diff --git a/.github/PULL_REQUEST_TEMPLATE/release-pr.md b/.github/PULL_REQUEST_TEMPLATE/release-pr.md index 6f86114060..8fcc3bd4af 100644 --- a/.github/PULL_REQUEST_TEMPLATE/release-pr.md +++ b/.github/PULL_REQUEST_TEMPLATE/release-pr.md @@ -10,7 +10,7 @@ ### Checklist after release -- [ ] Based on the merged commits write release notes and open a PR into `website` repo ([example](https://github.com/neondatabase/website/pull/120/files)) +- [ ] Based on the merged commits write release notes and open a PR into `website` repo ([example](https://github.com/neondatabase/website/pull/219/files)) - [ ] Check [#dev-production-stream](https://neondb.slack.com/archives/C03F5SM1N02) Slack channel - [ ] Check [stuck projects page](https://console.neon.tech/admin/projects?sort=last_active&order=desc&stuck=true) - [ ] Check [recent operation failures](https://console.neon.tech/admin/operations?action=create_timeline%2Cstart_compute%2Cstop_compute%2Csuspend_compute%2Capply_config%2Cdelete_timeline%2Cdelete_tenant%2Ccreate_branch%2Ccheck_availability&sort=updated_at&order=desc&had_retries=some) diff --git a/.github/actions/allure-report/action.yml b/.github/actions/allure-report/action.yml index ec751f51fc..dfb314571b 100644 --- a/.github/actions/allure-report/action.yml +++ b/.github/actions/allure-report/action.yml @@ -47,7 +47,7 @@ runs: else key=branch-$(echo ${GITHUB_REF#refs/heads/} | tr -c "[:alnum:]._-" "-") fi - echo "::set-output name=KEY::${key}" + echo "KEY=${key}" >> $GITHUB_OUTPUT - uses: actions/setup-java@v3 if: ${{ inputs.action == 'generate' }} @@ -186,7 +186,7 @@ runs: aws s3 cp --only-show-errors ./index.html "s3://${BUCKET}/${REPORT_PREFIX}/latest/index.html" echo "[Allure Report](${REPORT_URL})" >> ${GITHUB_STEP_SUMMARY} - echo "::set-output name=report-url::${REPORT_URL}" + echo "report-url=${REPORT_URL}" >> $GITHUB_OUTPUT - name: Release Allure lock if: ${{ inputs.action == 'generate' && always() }} diff --git a/.github/actions/download/action.yml b/.github/actions/download/action.yml index 731ef6639d..eb34d4206a 100644 --- a/.github/actions/download/action.yml +++ b/.github/actions/download/action.yml @@ -34,7 +34,7 @@ runs: S3_KEY=$(aws s3api list-objects-v2 --bucket ${BUCKET} --prefix ${PREFIX%$GITHUB_RUN_ATTEMPT} | jq -r '.Contents[].Key' | grep ${FILENAME} | sort --version-sort | tail -1 || true) if [ -z "${S3_KEY}" ]; then if [ "${SKIP_IF_DOES_NOT_EXIST}" = "true" ]; then - echo '::set-output name=SKIPPED::true' + echo 'SKIPPED=true' >> $GITHUB_OUTPUT exit 0 else echo 2>&1 "Neither s3://${BUCKET}/${PREFIX}/${FILENAME} nor its version from previous attempts exist" @@ -42,7 +42,7 @@ runs: fi fi - echo '::set-output name=SKIPPED::false' + echo 'SKIPPED=false' >> $GITHUB_OUTPUT mkdir -p $(dirname $ARCHIVE) time aws s3 cp --only-show-errors s3://${BUCKET}/${S3_KEY} ${ARCHIVE} diff --git a/.github/actions/neon-project-create/action.yml b/.github/actions/neon-project-create/action.yml index 2f58ae77ad..b4fd151582 100644 --- a/.github/actions/neon-project-create/action.yml +++ b/.github/actions/neon-project-create/action.yml @@ -41,8 +41,8 @@ runs: ;; esac - echo "::set-output name=api_host::${API_HOST}" - echo "::set-output name=region_id::${REGION_ID}" + echo "api_host=${API_HOST}" >> $GITHUB_OUTPUT + echo "region_id=${REGION_ID}" >> $GITHUB_OUTPUT env: ENVIRONMENT: ${{ inputs.environment }} REGION_ID: ${{ inputs.region_id }} @@ -72,10 +72,10 @@ runs: dsn=$(echo $project | jq --raw-output '.roles[] | select(.name != "web_access") | .dsn')/main echo "::add-mask::${dsn}" - echo "::set-output name=dsn::${dsn}" + echo "dsn=${dsn}" >> $GITHUB_OUTPUT project_id=$(echo $project | jq --raw-output '.id') - echo "::set-output name=project_id::${project_id}" + echo "project_id=${project_id}" >> $GITHUB_OUTPUT env: API_KEY: ${{ inputs.api_key }} API_HOST: ${{ steps.parse-input.outputs.api_host }} diff --git a/.github/actions/neon-project-delete/action.yml b/.github/actions/neon-project-delete/action.yml index e7c6f58901..d417c489ef 100644 --- a/.github/actions/neon-project-delete/action.yml +++ b/.github/actions/neon-project-delete/action.yml @@ -32,7 +32,7 @@ runs: ;; esac - echo "::set-output name=api_host::${API_HOST}" + echo "api_host=${API_HOST}" >> $GITHUB_OUTPUT env: ENVIRONMENT: ${{ inputs.environment }} diff --git a/.github/ansible/.gitignore b/.github/ansible/.gitignore index 441d9a8b82..e3454fd43c 100644 --- a/.github/ansible/.gitignore +++ b/.github/ansible/.gitignore @@ -2,3 +2,6 @@ zenith_install.tar.gz .zenith_current_version neon_install.tar.gz .neon_current_version + +collections/* +!collections/.keep diff --git a/.github/ansible/ansible.cfg b/.github/ansible/ansible.cfg index 5818a64455..0497ee401d 100644 --- a/.github/ansible/ansible.cfg +++ b/.github/ansible/ansible.cfg @@ -3,6 +3,7 @@ localhost_warning = False host_key_checking = False timeout = 30 +collections_paths = ./collections [ssh_connection] ssh_args = -F ./ansible.ssh.cfg diff --git a/.github/ansible/collections/.keep b/.github/ansible/collections/.keep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/.github/ansible/deploy.yaml b/.github/ansible/deploy.yaml index e206f9d5ba..4adc685684 100644 --- a/.github/ansible/deploy.yaml +++ b/.github/ansible/deploy.yaml @@ -1,7 +1,7 @@ - name: Upload Neon binaries hosts: storage gather_facts: False - remote_user: admin + remote_user: "{{ remote_user }}" tasks: @@ -14,7 +14,8 @@ - safekeeper - name: inform about versions - debug: msg="Version to deploy - {{ current_version }}" + debug: + msg: "Version to deploy - {{ current_version }}" tags: - pageserver - safekeeper @@ -35,7 +36,7 @@ - name: Deploy pageserver hosts: pageservers gather_facts: False - remote_user: admin + remote_user: "{{ remote_user }}" tasks: @@ -63,15 +64,29 @@ tags: - pageserver - - name: update remote storage (s3) config - lineinfile: - path: /storage/pageserver/data/pageserver.toml - line: "{{ item }}" - loop: - - "[remote_storage]" - - "bucket_name = '{{ bucket_name }}'" - - "bucket_region = '{{ bucket_region }}'" - - "prefix_in_bucket = '{{ inventory_hostname }}'" + - name: read the existing remote pageserver config + ansible.builtin.slurp: + src: /storage/pageserver/data/pageserver.toml + register: _remote_ps_config + tags: + - pageserver + + - name: parse the existing pageserver configuration + ansible.builtin.set_fact: + _existing_ps_config: "{{ _remote_ps_config['content'] | b64decode | sivel.toiletwater.from_toml }}" + tags: + - pageserver + + - name: construct the final pageserver configuration dict + ansible.builtin.set_fact: + pageserver_config: "{{ pageserver_config_stub | combine({'id': _existing_ps_config.id }) }}" + tags: + - pageserver + + - name: template the pageserver config + template: + src: templates/pageserver.toml.j2 + dest: /storage/pageserver/data/pageserver.toml become: true tags: - pageserver @@ -109,7 +124,7 @@ - name: Deploy safekeeper hosts: safekeepers gather_facts: False - remote_user: admin + remote_user: "{{ remote_user }}" tasks: diff --git a/.github/ansible/get_binaries.sh b/.github/ansible/get_binaries.sh index a484bfb0a0..9d2d0926f5 100755 --- a/.github/ansible/get_binaries.sh +++ b/.github/ansible/get_binaries.sh @@ -23,6 +23,7 @@ docker cp ${ID}:/data/postgres_install.tar.gz . tar -xzf postgres_install.tar.gz -C neon_install mkdir neon_install/bin/ docker cp ${ID}:/usr/local/bin/pageserver neon_install/bin/ +docker cp ${ID}:/usr/local/bin/pageserver_binutils neon_install/bin/ docker cp ${ID}:/usr/local/bin/safekeeper neon_install/bin/ docker cp ${ID}:/usr/local/bin/proxy neon_install/bin/ docker cp ${ID}:/usr/local/v14/bin/ neon_install/v14/bin/ diff --git a/.github/ansible/neon-stress.hosts b/.github/ansible/neon-stress.hosts deleted file mode 100644 index 750fd8106a..0000000000 --- a/.github/ansible/neon-stress.hosts +++ /dev/null @@ -1,20 +0,0 @@ -[pageservers] -neon-stress-ps-1 console_region_id=1 -neon-stress-ps-2 console_region_id=1 - -[safekeepers] -neon-stress-sk-1 console_region_id=1 -neon-stress-sk-2 console_region_id=1 -neon-stress-sk-3 console_region_id=1 - -[storage:children] -pageservers -safekeepers - -[storage:vars] -env_name = neon-stress -console_mgmt_base_url = http://neon-stress-console.local -bucket_name = neon-storage-ireland -bucket_region = eu-west-1 -etcd_endpoints = etcd-stress.local:2379 -safekeeper_enable_s3_offload = false diff --git a/.github/ansible/neon-stress.hosts.yaml b/.github/ansible/neon-stress.hosts.yaml new file mode 100644 index 0000000000..8afc9a5be8 --- /dev/null +++ b/.github/ansible/neon-stress.hosts.yaml @@ -0,0 +1,31 @@ +storage: + vars: + bucket_name: neon-storage-ireland + bucket_region: eu-west-1 + console_mgmt_base_url: http://neon-stress-console.local + env_name: neon-stress + etcd_endpoints: neon-stress-etcd.local:2379 + safekeeper_enable_s3_offload: 'false' + pageserver_config_stub: + pg_distrib_dir: /usr/local + remote_storage: + bucket_name: "{{ bucket_name }}" + bucket_region: "{{ bucket_region }}" + prefix_in_bucket: "{{ inventory_hostname }}" + hostname_suffix: ".local" + remote_user: admin + children: + pageservers: + hosts: + neon-stress-ps-1: + console_region_id: aws-eu-west-1 + neon-stress-ps-2: + console_region_id: aws-eu-west-1 + safekeepers: + hosts: + neon-stress-sk-1: + console_region_id: aws-eu-west-1 + neon-stress-sk-2: + console_region_id: aws-eu-west-1 + neon-stress-sk-3: + console_region_id: aws-eu-west-1 diff --git a/.github/ansible/production.hosts b/.github/ansible/production.hosts deleted file mode 100644 index 364e8ed50e..0000000000 --- a/.github/ansible/production.hosts +++ /dev/null @@ -1,20 +0,0 @@ -[pageservers] -#zenith-1-ps-1 console_region_id=1 -zenith-1-ps-2 console_region_id=1 -zenith-1-ps-3 console_region_id=1 - -[safekeepers] -zenith-1-sk-1 console_region_id=1 -zenith-1-sk-2 console_region_id=1 -zenith-1-sk-3 console_region_id=1 - -[storage:children] -pageservers -safekeepers - -[storage:vars] -env_name = prod-1 -console_mgmt_base_url = http://console-release.local -bucket_name = zenith-storage-oregon -bucket_region = us-west-2 -etcd_endpoints = zenith-1-etcd.local:2379 diff --git a/.github/ansible/production.hosts.yaml b/.github/ansible/production.hosts.yaml new file mode 100644 index 0000000000..9f9b12d25d --- /dev/null +++ b/.github/ansible/production.hosts.yaml @@ -0,0 +1,33 @@ +--- +storage: + vars: + env_name: prod-1 + console_mgmt_base_url: http://console-release.local + bucket_name: zenith-storage-oregon + bucket_region: us-west-2 + etcd_endpoints: zenith-1-etcd.local:2379 + pageserver_config_stub: + pg_distrib_dir: /usr/local + remote_storage: + bucket_name: "{{ bucket_name }}" + bucket_region: "{{ bucket_region }}" + prefix_in_bucket: "{{ inventory_hostname }}" + hostname_suffix: ".local" + remote_user: admin + + children: + pageservers: + hosts: + zenith-1-ps-2: + console_region_id: aws-us-west-2 + zenith-1-ps-3: + console_region_id: aws-us-west-2 + + safekeepers: + hosts: + zenith-1-sk-1: + console_region_id: aws-us-west-2 + zenith-1-sk-2: + console_region_id: aws-us-west-2 + zenith-1-sk-3: + console_region_id: aws-us-west-2 diff --git a/.github/ansible/scripts/init_pageserver.sh b/.github/ansible/scripts/init_pageserver.sh index 1cbdd0db94..426925a837 100644 --- a/.github/ansible/scripts/init_pageserver.sh +++ b/.github/ansible/scripts/init_pageserver.sh @@ -12,18 +12,19 @@ cat <> $GITHUB_PATH - name: Create Neon Project - if: matrix.platform != 'neon-captest-reuse' + if: contains(fromJson('["neon-captest-new", "neon-captest-prefetch"]'), matrix.platform) id: create-neon-project uses: ./.github/actions/neon-project-create with: @@ -204,11 +213,9 @@ jobs: ;; esac - echo "::set-output name=connstr::${CONNSTR}" + echo "connstr=${CONNSTR}" >> $GITHUB_OUTPUT psql ${CONNSTR} -c "SELECT version();" - env: - PLATFORM: ${{ matrix.platform }} - name: Set database options if: matrix.platform == 'neon-captest-prefetch' @@ -227,7 +234,6 @@ jobs: save_perf_report: ${{ env.SAVE_PERF_REPORT }} extra_params: -m remote_cluster --timeout 21600 -k test_pgbench_remote_init env: - PLATFORM: ${{ matrix.platform }} BENCHMARK_CONNSTR: ${{ steps.set-up-connstr.outputs.connstr }} VIP_VAP_ACCESS_TOKEN: "${{ secrets.VIP_VAP_ACCESS_TOKEN }}" PERF_TEST_RESULT_CONNSTR: "${{ secrets.PERF_TEST_RESULT_CONNSTR }}" @@ -241,7 +247,6 @@ jobs: save_perf_report: ${{ env.SAVE_PERF_REPORT }} extra_params: -m remote_cluster --timeout 21600 -k test_pgbench_remote_simple_update env: - PLATFORM: ${{ matrix.platform }} BENCHMARK_CONNSTR: ${{ steps.set-up-connstr.outputs.connstr }} VIP_VAP_ACCESS_TOKEN: "${{ secrets.VIP_VAP_ACCESS_TOKEN }}" PERF_TEST_RESULT_CONNSTR: "${{ secrets.PERF_TEST_RESULT_CONNSTR }}" @@ -255,7 +260,6 @@ jobs: save_perf_report: ${{ env.SAVE_PERF_REPORT }} extra_params: -m remote_cluster --timeout 21600 -k test_pgbench_remote_select_only env: - PLATFORM: ${{ matrix.platform }} BENCHMARK_CONNSTR: ${{ steps.set-up-connstr.outputs.connstr }} VIP_VAP_ACCESS_TOKEN: "${{ secrets.VIP_VAP_ACCESS_TOKEN }}" PERF_TEST_RESULT_CONNSTR: "${{ secrets.PERF_TEST_RESULT_CONNSTR }}" @@ -268,7 +272,7 @@ jobs: build_type: ${{ env.BUILD_TYPE }} - name: Delete Neon Project - if: ${{ matrix.platform != 'neon-captest-reuse' && always() }} + if: ${{ steps.create-neon-project.outputs.project_id && always() }} uses: ./.github/actions/neon-project-delete with: environment: dev diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index 7cc8715526..14ee61c5b9 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -35,12 +35,12 @@ jobs: echo ref:$GITHUB_REF_NAME echo rev:$(git rev-list --count HEAD) if [[ "$GITHUB_REF_NAME" == "main" ]]; then - echo "::set-output name=tag::$(git rev-list --count HEAD)" + echo "tag=$(git rev-list --count HEAD)" >> $GITHUB_OUTPUT elif [[ "$GITHUB_REF_NAME" == "release" ]]; then - echo "::set-output name=tag::release-$(git rev-list --count HEAD)" + echo "tag=release-$(git rev-list --count HEAD)" >> $GITHUB_OUTPUT else echo "GITHUB_REF_NAME (value '$GITHUB_REF_NAME') is not set to either 'main' or 'release'" - echo "::set-output name=tag::$GITHUB_RUN_ID" + echo "tag=$GITHUB_RUN_ID" >> $GITHUB_OUTPUT fi shell: bash id: build-tag @@ -78,12 +78,12 @@ jobs: - name: Set pg 14 revision for caching id: pg_v14_rev - run: echo ::set-output name=pg_rev::$(git rev-parse HEAD:vendor/postgres-v14) + run: echo pg_rev=$(git rev-parse HEAD:vendor/postgres-v14) >> $GITHUB_OUTPUT shell: bash -euxo pipefail {0} - name: Set pg 15 revision for caching id: pg_v15_rev - run: echo ::set-output name=pg_rev::$(git rev-parse HEAD:vendor/postgres-v15) + run: echo pg_rev=$(git rev-parse HEAD:vendor/postgres-v15) >> $GITHUB_OUTPUT shell: bash -euxo pipefail {0} # Set some environment variables used by all the steps. @@ -481,6 +481,7 @@ jobs: neon-image: runs-on: dev + needs: [ tag ] container: gcr.io/kaniko-project/executor:v1.9.0-debug steps: @@ -494,10 +495,11 @@ jobs: run: echo "{\"credsStore\":\"ecr-login\"}" > /kaniko/.docker/config.json - name: Kaniko build neon - run: /kaniko/executor --snapshotMode=redo --cache=true --cache-repo 369495373322.dkr.ecr.eu-central-1.amazonaws.com/cache --snapshotMode=redo --context . --build-arg GIT_VERSION=${{ github.sha }} --destination 369495373322.dkr.ecr.eu-central-1.amazonaws.com/neon:$GITHUB_RUN_ID + run: /kaniko/executor --snapshotMode=redo --cache=true --cache-repo 369495373322.dkr.ecr.eu-central-1.amazonaws.com/cache --snapshotMode=redo --context . --build-arg GIT_VERSION=${{ github.sha }} --destination 369495373322.dkr.ecr.eu-central-1.amazonaws.com/neon:${{needs.tag.outputs.build-tag}} compute-tools-image: runs-on: dev + needs: [ tag ] container: gcr.io/kaniko-project/executor:v1.9.0-debug steps: @@ -508,11 +510,12 @@ jobs: run: echo "{\"credsStore\":\"ecr-login\"}" > /kaniko/.docker/config.json - name: Kaniko build compute tools - run: /kaniko/executor --snapshotMode=redo --cache=true --cache-repo 369495373322.dkr.ecr.eu-central-1.amazonaws.com/cache --snapshotMode=redo --context . --build-arg GIT_VERSION=${{ github.sha }} --dockerfile Dockerfile.compute-tools --destination 369495373322.dkr.ecr.eu-central-1.amazonaws.com/compute-tools:$GITHUB_RUN_ID + run: /kaniko/executor --snapshotMode=redo --cache=true --cache-repo 369495373322.dkr.ecr.eu-central-1.amazonaws.com/cache --snapshotMode=redo --context . --build-arg GIT_VERSION=${{ github.sha }} --dockerfile Dockerfile.compute-tools --destination 369495373322.dkr.ecr.eu-central-1.amazonaws.com/compute-tools:${{needs.tag.outputs.build-tag}} compute-node-image: runs-on: dev container: gcr.io/kaniko-project/executor:v1.9.0-debug + needs: [ tag ] steps: - name: Checkout uses: actions/checkout@v1 # v3 won't work with kaniko @@ -527,11 +530,12 @@ jobs: # cloud repo depends on this image name, thus duplicating it # remove compute-node when cloud repo is updated - name: Kaniko build compute node with extensions v14 (compatibility) - run: /kaniko/executor --skip-unused-stages --snapshotMode=redo --cache=true --cache-repo 369495373322.dkr.ecr.eu-central-1.amazonaws.com/cache --snapshotMode=redo --context . --build-arg GIT_VERSION=${{ github.sha }} --dockerfile Dockerfile.compute-node-v14 --destination 369495373322.dkr.ecr.eu-central-1.amazonaws.com/compute-node:$GITHUB_RUN_ID + run: /kaniko/executor --skip-unused-stages --snapshotMode=redo --cache=true --cache-repo 369495373322.dkr.ecr.eu-central-1.amazonaws.com/cache --snapshotMode=redo --context . --build-arg GIT_VERSION=${{ github.sha }} --dockerfile Dockerfile.compute-node-v14 --destination 369495373322.dkr.ecr.eu-central-1.amazonaws.com/compute-node:${{needs.tag.outputs.build-tag}} compute-node-image-v14: runs-on: dev container: gcr.io/kaniko-project/executor:v1.9.0-debug + needs: [ tag ] steps: - name: Checkout uses: actions/checkout@v1 # v3 won't work with kaniko @@ -543,12 +547,13 @@ jobs: run: echo "{\"credsStore\":\"ecr-login\"}" > /kaniko/.docker/config.json - name: Kaniko build compute node with extensions v14 - run: /kaniko/executor --skip-unused-stages --snapshotMode=redo --cache=true --cache-repo 369495373322.dkr.ecr.eu-central-1.amazonaws.com/cache --context . --build-arg GIT_VERSION=${{ github.sha }} --dockerfile Dockerfile.compute-node-v14 --destination 369495373322.dkr.ecr.eu-central-1.amazonaws.com/compute-node-v14:$GITHUB_RUN_ID + run: /kaniko/executor --skip-unused-stages --snapshotMode=redo --cache=true --cache-repo 369495373322.dkr.ecr.eu-central-1.amazonaws.com/cache --context . --build-arg GIT_VERSION=${{ github.sha }} --dockerfile Dockerfile.compute-node-v14 --destination 369495373322.dkr.ecr.eu-central-1.amazonaws.com/compute-node-v14:${{needs.tag.outputs.build-tag}} compute-node-image-v15: runs-on: dev container: gcr.io/kaniko-project/executor:v1.9.0-debug + needs: [ tag ] steps: - name: Checkout uses: actions/checkout@v1 # v3 won't work with kaniko @@ -560,11 +565,11 @@ jobs: run: echo "{\"credsStore\":\"ecr-login\"}" > /kaniko/.docker/config.json - name: Kaniko build compute node with extensions v15 - run: /kaniko/executor --skip-unused-stages --snapshotMode=redo --cache=true --cache-repo 369495373322.dkr.ecr.eu-central-1.amazonaws.com/cache --context . --build-arg GIT_VERSION=${{ github.sha }} --dockerfile Dockerfile.compute-node-v15 --destination 369495373322.dkr.ecr.eu-central-1.amazonaws.com/compute-node-v15:$GITHUB_RUN_ID + run: /kaniko/executor --skip-unused-stages --snapshotMode=redo --cache=true --cache-repo 369495373322.dkr.ecr.eu-central-1.amazonaws.com/cache --context . --build-arg GIT_VERSION=${{ github.sha }} --dockerfile Dockerfile.compute-node-v15 --destination 369495373322.dkr.ecr.eu-central-1.amazonaws.com/compute-node-v15:${{needs.tag.outputs.build-tag}} promote-images: runs-on: dev - needs: [ neon-image, compute-node-image, compute-node-image-v14, compute-node-image-v15, compute-tools-image ] + needs: [ tag, neon-image, compute-node-image, compute-node-image-v14, compute-node-image-v15, compute-tools-image ] if: github.event_name != 'workflow_dispatch' container: amazon/aws-cli strategy: @@ -577,8 +582,9 @@ jobs: steps: - name: Promote image to latest - run: - MANIFEST=$(aws ecr batch-get-image --repository-name ${{ matrix.name }} --image-ids imageTag=$GITHUB_RUN_ID --query 'images[].imageManifest' --output text) && aws ecr put-image --repository-name ${{ matrix.name }} --image-tag latest --image-manifest "$MANIFEST" + run: | + export MANIFEST=$(aws ecr batch-get-image --repository-name ${{ matrix.name }} --image-ids imageTag=${{needs.tag.outputs.build-tag}} --query 'images[].imageManifest' --output text) + aws ecr put-image --repository-name ${{ matrix.name }} --image-tag latest --image-manifest "$MANIFEST" push-docker-hub: runs-on: dev @@ -597,19 +603,19 @@ jobs: echo "{\"credsStore\":\"ecr-login\"}" > /github/home/.docker/config.json - name: Pull neon image from ECR - run: crane pull 369495373322.dkr.ecr.eu-central-1.amazonaws.com/neon:latest neon + run: crane pull 369495373322.dkr.ecr.eu-central-1.amazonaws.com/neon:${{needs.tag.outputs.build-tag}} neon - name: Pull compute tools image from ECR - run: crane pull 369495373322.dkr.ecr.eu-central-1.amazonaws.com/compute-tools:latest compute-tools + run: crane pull 369495373322.dkr.ecr.eu-central-1.amazonaws.com/compute-tools:${{needs.tag.outputs.build-tag}} compute-tools - name: Pull compute node image from ECR - run: crane pull 369495373322.dkr.ecr.eu-central-1.amazonaws.com/compute-node:latest compute-node + run: crane pull 369495373322.dkr.ecr.eu-central-1.amazonaws.com/compute-node:${{needs.tag.outputs.build-tag}} compute-node - name: Pull compute node v14 image from ECR - run: crane pull 369495373322.dkr.ecr.eu-central-1.amazonaws.com/compute-node-v14:latest compute-node-v14 + run: crane pull 369495373322.dkr.ecr.eu-central-1.amazonaws.com/compute-node-v14:${{needs.tag.outputs.build-tag}} compute-node-v14 - name: Pull compute node v15 image from ECR - run: crane pull 369495373322.dkr.ecr.eu-central-1.amazonaws.com/compute-node-v15:latest compute-node-v15 + run: crane pull 369495373322.dkr.ecr.eu-central-1.amazonaws.com/compute-node-v15:${{needs.tag.outputs.build-tag}} compute-node-v15 - name: Pull rust image from ECR run: crane pull 369495373322.dkr.ecr.eu-central-1.amazonaws.com/rust:pinned rust @@ -619,9 +625,11 @@ jobs: (github.ref_name == 'main' || github.ref_name == 'release') && github.event_name != 'workflow_dispatch' run: | - crane copy 369495373322.dkr.ecr.eu-central-1.amazonaws.com/neon:$GITHUB_RUN_ID 093970136003.dkr.ecr.us-east-2.amazonaws.com/neon:latest - crane copy 369495373322.dkr.ecr.eu-central-1.amazonaws.com/compute-tools:$GITHUB_RUN_ID 093970136003.dkr.ecr.us-east-2.amazonaws.com/compute-tools:latest - crane copy 369495373322.dkr.ecr.eu-central-1.amazonaws.com/compute-node:$GITHUB_RUN_ID 093970136003.dkr.ecr.us-east-2.amazonaws.com/compute-node:latest + crane copy 369495373322.dkr.ecr.eu-central-1.amazonaws.com/neon:${{needs.tag.outputs.build-tag}} 093970136003.dkr.ecr.us-east-2.amazonaws.com/neon:latest + crane copy 369495373322.dkr.ecr.eu-central-1.amazonaws.com/compute-tools:${{needs.tag.outputs.build-tag}} 093970136003.dkr.ecr.us-east-2.amazonaws.com/compute-tools:latest + crane copy 369495373322.dkr.ecr.eu-central-1.amazonaws.com/compute-node:${{needs.tag.outputs.build-tag}} 093970136003.dkr.ecr.us-east-2.amazonaws.com/compute-node:latest + crane copy 369495373322.dkr.ecr.eu-central-1.amazonaws.com/compute-node-v14:${{needs.tag.outputs.build-tag}} 093970136003.dkr.ecr.us-east-2.amazonaws.com/compute-node-v14:latest + crane copy 369495373322.dkr.ecr.eu-central-1.amazonaws.com/compute-node-v15:${{needs.tag.outputs.build-tag}} 093970136003.dkr.ecr.us-east-2.amazonaws.com/compute-node-v15:latest - name: Configure Docker Hub login run: | @@ -669,12 +677,12 @@ jobs: - id: set-matrix run: | if [[ "$GITHUB_REF_NAME" == "main" ]]; then - STAGING='{"env_name": "staging", "proxy_job": "neon-proxy", "proxy_config": "staging.proxy", "kubeconfig_secret": "STAGING_KUBECONFIG_DATA"}' - NEON_STRESS='{"env_name": "neon-stress", "proxy_job": "neon-stress-proxy", "proxy_config": "neon-stress.proxy", "kubeconfig_secret": "NEON_STRESS_KUBECONFIG_DATA"}' - echo "::set-output name=include::[$STAGING, $NEON_STRESS]" + STAGING='{"env_name": "staging", "proxy_job": "neon-proxy", "proxy_config": "staging.proxy", "kubeconfig_secret": "STAGING_KUBECONFIG_DATA", "console_api_key_secret": "NEON_STAGING_API_KEY"}' + NEON_STRESS='{"env_name": "neon-stress", "proxy_job": "neon-stress-proxy", "proxy_config": "neon-stress.proxy", "kubeconfig_secret": "NEON_STRESS_KUBECONFIG_DATA", "console_api_key_secret": "NEON_CAPTEST_API_KEY"}' + echo "include=[$STAGING, $NEON_STRESS]" >> $GITHUB_OUTPUT elif [[ "$GITHUB_REF_NAME" == "release" ]]; then - PRODUCTION='{"env_name": "production", "proxy_job": "neon-proxy", "proxy_config": "production.proxy", "kubeconfig_secret": "PRODUCTION_KUBECONFIG_DATA"}' - echo "::set-output name=include::[$PRODUCTION]" + PRODUCTION='{"env_name": "production", "proxy_job": "neon-proxy", "proxy_config": "production.proxy", "kubeconfig_secret": "PRODUCTION_KUBECONFIG_DATA", "console_api_key_secret": "NEON_PRODUCTION_API_KEY"}' + echo "include=[$PRODUCTION]" >> $GITHUB_OUTPUT else echo "GITHUB_REF_NAME (value '$GITHUB_REF_NAME') is not set to either 'main' or 'release'" exit 1 @@ -710,7 +718,7 @@ jobs: - name: Setup ansible run: | export PATH="/root/.local/bin:$PATH" - pip install --progress-bar off --user ansible boto3 + pip install --progress-bar off --user ansible boto3 toml - name: Redeploy run: | @@ -732,8 +740,48 @@ jobs: chmod 0600 ssh-key ssh-add ssh-key rm -f ssh-key ssh-key-cert.pub + ansible-galaxy collection install sivel.toiletwater + ansible-playbook deploy.yaml -i ${{ matrix.env_name }}.hosts.yaml -e CONSOLE_API_TOKEN=${{ secrets[matrix.console_api_key_secret] }} + rm -f neon_install.tar.gz .neon_current_version - ansible-playbook deploy.yaml -i ${{ matrix.env_name }}.hosts + deploy-new: + runs-on: dev + container: 369495373322.dkr.ecr.eu-central-1.amazonaws.com/ansible:pinned + # We need both storage **and** compute images for deploy, because control plane picks the compute version based on the storage version. + # If it notices a fresh storage it may bump the compute version. And if compute image failed to build it may break things badly + needs: [ push-docker-hub, calculate-deploy-targets, tag, regress-tests ] + if: | + (github.ref_name == 'main') && + github.event_name != 'workflow_dispatch' + defaults: + run: + shell: bash + env: + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_DEV }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_KEY_DEV }} + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + submodules: true + fetch-depth: 0 + + - name: Redeploy + run: | + export DOCKER_TAG=${{needs.tag.outputs.build-tag}} + cd "$(pwd)/.github/ansible" + + if [[ "$GITHUB_REF_NAME" == "main" ]]; then + ./get_binaries.sh + elif [[ "$GITHUB_REF_NAME" == "release" ]]; then + RELEASE=true ./get_binaries.sh + else + echo "GITHUB_REF_NAME (value '$GITHUB_REF_NAME') is not set to either 'main' or 'release'" + exit 1 + fi + + ansible-galaxy collection install sivel.toiletwater + ansible-playbook deploy.yaml -i staging.us-east-2.hosts.yaml -e @ssm_config -e CONSOLE_API_TOKEN=${{secrets.NEON_STAGING_API_KEY}} rm -f neon_install.tar.gz .neon_current_version deploy-proxy: @@ -777,3 +825,31 @@ jobs: DOCKER_TAG=${{needs.tag.outputs.build-tag}} helm upgrade ${{ matrix.proxy_job }} neondatabase/neon-proxy --namespace neon-proxy --install -f .github/helm-values/${{ matrix.proxy_config }}.yaml --set image.tag=${DOCKER_TAG} --wait --timeout 15m0s helm upgrade ${{ matrix.proxy_job }}-scram neondatabase/neon-proxy --namespace neon-proxy --install -f .github/helm-values/${{ matrix.proxy_config }}-scram.yaml --set image.tag=${DOCKER_TAG} --wait --timeout 15m0s + + deploy-proxy-new: + runs-on: dev + container: 369495373322.dkr.ecr.eu-central-1.amazonaws.com/ansible:pinned + # Compute image isn't strictly required for proxy deploy, but let's still wait for it to run all deploy jobs consistently. + needs: [ push-docker-hub, calculate-deploy-targets, tag, regress-tests ] + if: | + (github.ref_name == 'main' || github.ref_name == 'release') && + github.event_name != 'workflow_dispatch' + defaults: + run: + shell: bash + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + submodules: true + fetch-depth: 0 + + - name: Configure environment + run: | + helm repo add neondatabase https://neondatabase.github.io/helm-charts + aws --region us-east-2 eks update-kubeconfig --name dev-us-east-2-beta --role-arn arn:aws:iam::369495373322:role/github-runner + + - name: Re-deploy proxy + run: | + DOCKER_TAG=${{needs.tag.outputs.build-tag}} + helm upgrade neon-proxy-scram neondatabase/neon-proxy --namespace neon-proxy --create-namespace --install -f .github/helm-values/dev-us-east-2-beta.neon-proxy-scram.yaml --set image.tag=${DOCKER_TAG} --wait --timeout 15m0s diff --git a/.github/workflows/codestyle.yml b/.github/workflows/codestyle.yml index 6d39958bab..66f9f33256 100644 --- a/.github/workflows/codestyle.yml +++ b/.github/workflows/codestyle.yml @@ -36,7 +36,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: submodules: true fetch-depth: 2 @@ -56,12 +56,12 @@ jobs: - name: Set pg 14 revision for caching id: pg_v14_rev - run: echo ::set-output name=pg_rev::$(git rev-parse HEAD:vendor/postgres-v14) + run: echo pg_rev=$(git rev-parse HEAD:vendor/postgres-v14) >> $GITHUB_OUTPUT shell: bash -euxo pipefail {0} - name: Set pg 15 revision for caching id: pg_v15_rev - run: echo ::set-output name=pg_rev::$(git rev-parse HEAD:vendor/postgres-v15) + run: echo pg_rev=$(git rev-parse HEAD:vendor/postgres-v15) >> $GITHUB_OUTPUT shell: bash -euxo pipefail {0} - name: Cache postgres v14 build diff --git a/Cargo.lock b/Cargo.lock index 8488fc4f9d..657baf5d80 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -30,9 +30,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "0.7.18" +version = "0.7.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +checksum = "b4f55bd91a0978cbfd91c457a164bab8b4001c833b7f323132c0a4e1922dd44e" dependencies = [ "memchr", ] @@ -40,41 +40,43 @@ dependencies = [ [[package]] name = "amplify_num" version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f27d3d00d3d115395a7a8a4dc045feb7aa82b641e485f7e15f4e67ac16f4f56d" +source = "git+https://github.com/hlinnaka/rust-amplify.git?branch=unsigned-int-perf#bd49b737c2e6e623ab8e9ba5ceaed5712d3a3940" [[package]] -name = "ansi_term" -version = "0.12.1" +name = "android_system_properties" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" dependencies = [ - "winapi", + "libc", ] [[package]] -name = "anyhow" -version = "1.0.59" +name = "anes" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c91f1f46651137be86f3a2b9a8359f9ab421d04d941c62b5982e1ca21113adf9" +checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" + +[[package]] +name = "anyhow" +version = "1.0.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98161a4e3e2184da77bb14f02184cdd111e83bbbcc9979dfee3c44b9a85f5602" dependencies = [ "backtrace", ] [[package]] name = "arrayvec" -version = "0.4.12" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd9fd44efafa8690358b7408d253adf110036b88f55672a933f01d616ad9b1b9" -dependencies = [ - "nodrop", -] +checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" [[package]] name = "asn1-rs" -version = "0.3.1" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30ff05a702273012438132f449575dbc804e27b2f3cbe3069aa237d26c98fa33" +checksum = "cf6690c370453db30743b373a60ba498fc0d6d83b11f4abfd87a84a075db5dd4" dependencies = [ "asn1-rs-derive", "asn1-rs-impl", @@ -83,14 +85,14 @@ dependencies = [ "num-traits", "rusticata-macros", "thiserror", - "time 0.3.12", + "time 0.3.15", ] [[package]] name = "asn1-rs-derive" -version = "0.1.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db8b7511298d5b7784b40b092d9e9dcd3a627a5707e4b5e507931ab0d44eeebf" +checksum = "726535892e8eae7e70657b4c8ea93d26b8553afb1ce617caee529ef96d7dee6c" dependencies = [ "proc-macro2", "quote", @@ -169,9 +171,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "axum" -version = "0.5.13" +version = "0.5.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b9496f0c1d1afb7a2af4338bbe1d969cddfead41d87a9fb3aaa6d0bbc7af648" +checksum = "c9e3356844c4d6a6d6467b8da2cffb4a2820be256f50a3a386c9d152bab31043" dependencies = [ "async-trait", "axum-core", @@ -181,7 +183,7 @@ dependencies = [ "http", "http-body", "hyper", - "itoa 1.0.3", + "itoa", "matchit", "memchr", "mime", @@ -259,15 +261,13 @@ dependencies = [ [[package]] name = "bindgen" -version = "0.60.1" +version = "0.61.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "062dddbc1ba4aca46de6338e2bf87771414c335f7b2f2036e8f3e9befebf88e6" +checksum = "8a022e58a142a46fea340d68012b9201c094e93ec3d033a944a24f8fd4a4f09a" dependencies = [ "bitflags", "cexpr", "clang-sys", - "clap 3.2.16", - "env_logger", "lazy_static", "lazycell", "log", @@ -277,6 +277,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", + "syn", "which", ] @@ -309,9 +310,9 @@ dependencies = [ [[package]] name = "block-buffer" -version = "0.10.2" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf7fe51849ea569fd452f37822f606a5cabb684dc918707a0193fd4664ff324" +checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e" dependencies = [ "generic-array", ] @@ -324,27 +325,27 @@ checksum = "5988cb1d626264ac94100be357308f29ff7cbdd3b36bda27f450a4ee3f713426" [[package]] name = "bstr" -version = "0.2.17" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223" +checksum = "fca0852af221f458706eb0725c03e4ed6c46af9ac98e6a689d5e634215d594dd" dependencies = [ - "lazy_static", "memchr", + "once_cell", "regex-automata", "serde", ] [[package]] name = "bumpalo" -version = "3.10.0" +version = "3.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37ccbd214614c6783386c1af30caf03192f17891059cecc394b4fb119e363de3" +checksum = "c1ad822118d20d2c234f427000d5acc36eabe1e29a348c89b63dd60b13f28e5d" [[package]] name = "bytemuck" -version = "1.11.0" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5377c8865e74a160d21f29c2d40669f53286db6eab59b88540cbb12ffc8b835" +checksum = "2f5715e491b5a1598fc2bef5a606847b5dc1d48ea625bd3c02c00de8285591da" [[package]] name = "byteorder" @@ -390,23 +391,52 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.19" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" +checksum = "bfd4d1b31faaa3a89d7934dbded3111da0d2ef28e3ebccdb4f0179f5929d1ef1" dependencies = [ - "libc", + "iana-time-zone", + "js-sys", "num-integer", "num-traits", "serde", "time 0.1.44", + "wasm-bindgen", "winapi", ] [[package]] -name = "clang-sys" -version = "1.3.3" +name = "ciborium" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a050e2153c5be08febd6734e29298e844fdb0fa21aeddd63b4eb7baa106c69b" +checksum = "b0c137568cc60b904a7724001b35ce2630fd00d5d84805fbb608ab89509d788f" +dependencies = [ + "ciborium-io", + "ciborium-ll", + "serde", +] + +[[package]] +name = "ciborium-io" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "346de753af073cc87b52b2083a506b38ac176a44cfb05497b622e27be899b369" + +[[package]] +name = "ciborium-ll" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "213030a2b5a4e0c0892b6652260cf6ccac84827b83a85a534e178e3906c4cf1b" +dependencies = [ + "ciborium-io", + "half", +] + +[[package]] +name = "clang-sys" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa2e27ae6ab525c3d369ded447057bca5438d86dc3a68f6faafb8269ba82ebf3" dependencies = [ "glob", "libc", @@ -415,28 +445,27 @@ dependencies = [ [[package]] name = "clap" -version = "2.34.0" +version = "3.2.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" +checksum = "86447ad904c7fb335a790c9d7fe3d0d971dc523b8ccd1561a520de9a85302750" dependencies = [ "bitflags", - "textwrap 0.11.0", - "unicode-width", + "clap_lex 0.2.4", + "indexmap", + "textwrap", ] [[package]] name = "clap" -version = "3.2.16" +version = "4.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3dbbb6653e7c55cc8595ad3e1f7be8f32aba4eb7ff7f0fd1163d4f3d137c0a9" +checksum = "6bf8832993da70a4c6d13c581f4463c2bdda27b9bf1c5498dc4365543abe6d6f" dependencies = [ "atty", "bitflags", - "clap_lex", - "indexmap", + "clap_lex 0.3.0", "strsim", "termcolor", - "textwrap 0.15.0", ] [[package]] @@ -448,6 +477,15 @@ dependencies = [ "os_str_bytes", ] +[[package]] +name = "clap_lex" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d4198f73e42b4936b35b5bb248d81d2b595ecb170da0bac7655c54eedfa8da8" +dependencies = [ + "os_str_bytes", +] + [[package]] name = "close_fds" version = "0.3.2" @@ -468,10 +506,20 @@ dependencies = [ ] [[package]] -name = "combine" -version = "4.6.4" +name = "codespan-reporting" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a604e93b79d1808327a6fca85a6f2d69de66461e7620f5a4cbf5fb4d1d7c948" +checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +dependencies = [ + "termcolor", + "unicode-width", +] + +[[package]] +name = "combine" +version = "4.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35ed6e9d84f0b51a7f52daf1c7d71dd136fd7a3f41a8462b8cdb8c78d920fad4" dependencies = [ "bytes", "memchr", @@ -479,9 +527,9 @@ dependencies = [ [[package]] name = "comfy-table" -version = "5.0.1" +version = "6.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b103d85ca6e209388771bfb7aa6b68a7aeec4afbf6f0a0264bfbf50360e5212e" +checksum = "85914173c2f558d61613bfbbf1911f14e630895087a7ed2fafc0f5319e1536e7" dependencies = [ "crossterm", "strum", @@ -495,7 +543,7 @@ version = "0.1.0" dependencies = [ "anyhow", "chrono", - "clap 3.2.16", + "clap 4.0.15", "env_logger", "futures", "hyper", @@ -514,18 +562,18 @@ dependencies = [ [[package]] name = "const_format" -version = "0.2.26" +version = "0.2.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "939dc9e2eb9077e0679d2ce32de1ded8531779360b003b4a972a7a39ec263495" +checksum = "7309d9b4d3d2c0641e018d449232f2e28f1b22933c137f157d3dbc14228b8c0e" dependencies = [ "const_format_proc_macros", ] [[package]] name = "const_format_proc_macros" -version = "0.2.22" +version = "0.2.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef196d5d972878a48da7decb7686eded338b4858fbabeed513d63a7c98b2b82d" +checksum = "d897f47bf7270cf70d370f8f98c1abb6d2d4cf60a6845d30e05bfb90c6568650" dependencies = [ "proc-macro2", "quote", @@ -537,10 +585,10 @@ name = "control_plane" version = "0.1.0" dependencies = [ "anyhow", - "clap 3.2.16", + "clap 4.0.15", "comfy-table", "git-version", - "nix", + "nix 0.25.0", "once_cell", "pageserver_api", "postgres", @@ -595,9 +643,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.2" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b" +checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" dependencies = [ "libc", ] @@ -622,15 +670,16 @@ dependencies = [ [[package]] name = "criterion" -version = "0.3.6" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b01d6de93b2b6c65e17c634a26653a29d107b3c98c607c765bf38d041531cd8f" +checksum = "e7c76e09c1aae2bc52b3d2f29e13c6572553b30c4aa1b8a49fd70de6412654cb" dependencies = [ + "anes", "atty", "cast", - "clap 2.34.0", + "ciborium", + "clap 3.2.22", "criterion-plot", - "csv", "itertools", "lazy_static", "num-traits", @@ -639,7 +688,6 @@ dependencies = [ "rayon", "regex", "serde", - "serde_cbor", "serde_derive", "serde_json", "tinytemplate", @@ -648,9 +696,9 @@ dependencies = [ [[package]] name = "criterion-plot" -version = "0.4.5" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2673cc8207403546f45f5fd319a974b1e6983ad1a3ee7e6041650013be041876" +checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1" dependencies = [ "cast", "itertools", @@ -691,15 +739,14 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.10" +version = "0.9.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "045ebe27666471bb549370b4b0b3e51b07f56325befa4284db65fc89c02511b1" +checksum = "f916dfc5d356b0ed9dae65f1db9fc9770aa2851d2662b988ccf4fe3516e86348" dependencies = [ "autocfg", "cfg-if", "crossbeam-utils", - "memoffset", - "once_cell", + "memoffset 0.6.5", "scopeguard", ] @@ -715,9 +762,9 @@ dependencies = [ [[package]] name = "crossterm" -version = "0.23.2" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2102ea4f781910f8a5b98dd061f4c2023f479ce7bb1236330099ceb5a93cf17" +checksum = "e64e6c0fbe2c17357405f7c758c1ef960fce08bdfb2c03d88d2a18d7e09c4b67" dependencies = [ "bitflags", "crossterm_winapi", @@ -759,25 +806,47 @@ dependencies = [ ] [[package]] -name = "csv" -version = "1.1.6" +name = "cxx" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22813a6dc45b335f9bade10bf7271dc477e81113e89eb251a0bc2a8a81c536e1" +checksum = "3f83d0ebf42c6eafb8d7c52f7e5f2d3003b89c7aa4fd2b79229209459a849af8" dependencies = [ - "bstr", - "csv-core", - "itoa 0.4.8", - "ryu", - "serde", + "cc", + "cxxbridge-flags", + "cxxbridge-macro", + "link-cplusplus", ] [[package]] -name = "csv-core" -version = "0.1.10" +name = "cxx-build" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90" +checksum = "07d050484b55975889284352b0ffc2ecbda25c0c55978017c132b29ba0818a86" dependencies = [ - "memchr", + "cc", + "codespan-reporting", + "once_cell", + "proc-macro2", + "quote", + "scratch", + "syn", +] + +[[package]] +name = "cxxbridge-flags" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d2199b00553eda8012dfec8d3b1c75fce747cf27c169a270b3b99e3448ab78" + +[[package]] +name = "cxxbridge-macro" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcb67a6de1f602736dd7eaead0080cf3435df806c61b24b13328db128c58868f" +dependencies = [ + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -792,9 +861,9 @@ dependencies = [ [[package]] name = "darling" -version = "0.13.4" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a01d95850c592940db9b8194bc39f4bc0e89dee5c4265e4b1807c34a9aba453c" +checksum = "4529658bdda7fd6769b8614be250cdcfc3aeb0ee72fe66f9e41e5e5eb73eac02" dependencies = [ "darling_core", "darling_macro", @@ -802,9 +871,9 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.13.4" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "859d65a907b6852c9361e3185c862aae7fafd2887876799fa55f5f99dc40d610" +checksum = "649c91bc01e8b1eac09fb91e8dbc7d517684ca6be8ebc75bb9cafc894f9fdb6f" dependencies = [ "fnv", "ident_case", @@ -816,9 +885,9 @@ dependencies = [ [[package]] name = "darling_macro" -version = "0.13.4" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835" +checksum = "ddfc69c5bfcbd2fc09a0f38451d2daf0e372e367986a83906d1b0dbc88134fb5" dependencies = [ "darling_core", "quote", @@ -837,14 +906,14 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6ee87af31d84ef885378aebca32be3d682b0e0dc119d5b4860a2c5bb5046730" dependencies = [ - "uuid", + "uuid 0.8.2", ] [[package]] name = "der-parser" -version = "7.0.0" +version = "8.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe398ac75057914d7d07307bf67dc7f3f574a26783b4fc7805a20ffa9f506e82" +checksum = "42d4bc9b0db0a0df9ae64634ac5bdefb7afcb534e182275ca0beadbe486701c1" dependencies = [ "asn1-rs", "displaydoc", @@ -865,11 +934,11 @@ dependencies = [ [[package]] name = "digest" -version = "0.10.3" +version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506" +checksum = "adfbc57365a37acbd2ebf2b64d7e69bb766e2fea813521ed536f5d0520dcf86c" dependencies = [ - "block-buffer 0.10.2", + "block-buffer 0.10.3", "crypto-common", "subtle", ] @@ -908,9 +977,9 @@ dependencies = [ [[package]] name = "either" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f107b87b6afc2a64fd13cac55fe06d6c8859f12d4b14cbcdd2c67d0976781be" +checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" [[package]] name = "embedded-hal" @@ -933,9 +1002,9 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b2cf0344971ee6c64c31be0d530793fba457d322dfec2810c453d0ef228f9c3" +checksum = "c90bf5f19754d10198ccb95b70664fc925bd1fc090a0fd9a6ebc54acc8cd6272" dependencies = [ "atty", "humantime", @@ -979,12 +1048,12 @@ dependencies = [ [[package]] name = "fail" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec3245a0ca564e7f3c797d20d833a6870f57a728ac967d5225b3ffdef4465011" +checksum = "fe5e43d0f78a42ad591453aedb1d7ae631ce7ee445c7643691055a9ed8d3b01c" dependencies = [ - "lazy_static", "log", + "once_cell", "rand", ] @@ -1056,11 +1125,10 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "form_urlencoded" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" +checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8" dependencies = [ - "matches", "percent-encoding", ] @@ -1085,9 +1153,9 @@ dependencies = [ [[package]] name = "futures" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f73fe65f54d1e12b726f517d3e2135ca3125a437b6d998caf1962961f7172d9e" +checksum = "7f21eda599937fba36daeb58a22e8f5cee2d14c4a17b5b7739c7c8e5e3b8230c" dependencies = [ "futures-channel", "futures-core", @@ -1100,9 +1168,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010" +checksum = "30bdd20c28fadd505d0fd6712cdfcb0d4b5648baf45faef7f852afb2399bb050" dependencies = [ "futures-core", "futures-sink", @@ -1110,15 +1178,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" +checksum = "4e5aa3de05362c3fb88de6531e6296e85cde7739cccad4b9dfeeb7f6ebce56bf" [[package]] name = "futures-executor" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9420b90cfa29e327d0429f19be13e7ddb68fa1cccb09d65e5706b8c7a749b8a6" +checksum = "9ff63c23854bee61b6e9cd331d523909f238fc7636290b96826e9cfa5faa00ab" dependencies = [ "futures-core", "futures-task", @@ -1127,15 +1195,15 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b" +checksum = "bbf4d2a7a308fd4578637c0b17c7e1c7ba127b8f6ba00b29f717e9655d85eb68" [[package]] name = "futures-macro" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33c1e13800337f4d4d7a316bf45a567dbcb6ffe087f16424852d97e97a91f512" +checksum = "42cd15d1c7456c04dbdf7e88bcd69760d74f3a798d6444e16974b505b0e62f17" dependencies = [ "proc-macro2", "quote", @@ -1144,21 +1212,27 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868" +checksum = "21b20ba5a92e727ba30e72834706623d94ac93a725410b6a6b6fbc1b07f7ba56" [[package]] name = "futures-task" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a" +checksum = "a6508c467c73851293f390476d4491cf4d227dbabcd4170f3bb6044959b294f1" + +[[package]] +name = "futures-timer" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c" [[package]] name = "futures-util" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" +checksum = "44fb6cb1be61cc1d2e43b262516aafcf63b241cffdb1d3fa115f91d9c7b09c90" dependencies = [ "futures-channel", "futures-core", @@ -1229,9 +1303,9 @@ checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" [[package]] name = "h2" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37a82c6d637fc9515a4694bbf1cb2457b79d81ce52b3108bdeea58b07dd34a57" +checksum = "5ca32592cf21ac7ccab1825cd87f6c9b3d9022c44d086172ed0966bec8af30be" dependencies = [ "bytes", "fnv", @@ -1283,15 +1357,6 @@ dependencies = [ "stable_deref_trait", ] -[[package]] -name = "heck" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" -dependencies = [ - "unicode-segmentation", -] - [[package]] name = "heck" version = "0.4.0" @@ -1338,7 +1403,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "digest 0.10.3", + "digest 0.10.5", ] [[package]] @@ -1349,7 +1414,7 @@ checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399" dependencies = [ "bytes", "fnv", - "itoa 1.0.3", + "itoa", ] [[package]] @@ -1371,9 +1436,9 @@ checksum = "0bfe8eed0a9285ef776bb792479ea3834e8b94e13d615c2f66d03dd50a435a29" [[package]] name = "httparse" -version = "1.7.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "496ce29bb5a52785b44e0f7ca2847ae0bb839c9bd28f69acac9b99d461c0c04c" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" [[package]] name = "httpdate" @@ -1412,7 +1477,7 @@ dependencies = [ "http-body", "httparse", "httpdate", - "itoa 1.0.3", + "itoa", "pin-project-lite", "socket2", "tokio", @@ -1459,6 +1524,30 @@ dependencies = [ "tokio-native-tls", ] +[[package]] +name = "iana-time-zone" +version = "0.1.51" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5a6ef98976b22b3b7f2f3a806f858cb862044cfa66805aa3ad84cb3d3b785ed" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "winapi", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca" +dependencies = [ + "cxx", + "cxx-build", +] + [[package]] name = "ident_case" version = "1.0.1" @@ -1467,11 +1556,10 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "idna" -version = "0.2.3" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" +checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" dependencies = [ - "matches", "unicode-bidi", "unicode-normalization", ] @@ -1484,6 +1572,7 @@ checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" dependencies = [ "autocfg", "hashbrown", + "serde", ] [[package]] @@ -1495,7 +1584,7 @@ dependencies = [ "ahash", "atty", "indexmap", - "itoa 1.0.3", + "itoa", "lazy_static", "log", "num-format", @@ -1541,30 +1630,24 @@ checksum = "879d54834c8c76457ef4293a689b2a8c59b076067ad77b15efafbb05f92a592b" [[package]] name = "itertools" -version = "0.10.3" +version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" dependencies = [ "either", ] [[package]] name = "itoa" -version = "0.4.8" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" - -[[package]] -name = "itoa" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754" +checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" [[package]] name = "js-sys" -version = "0.3.59" +version = "0.3.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "258451ab10b34f8af53416d1fdab72c22e805f0c92a1136d59470ec0b11138b2" +checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" dependencies = [ "wasm-bindgen", ] @@ -1585,9 +1668,9 @@ dependencies = [ [[package]] name = "kqueue" -version = "1.0.6" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d6112e8f37b59803ac47a42d14f1f3a59bbf72fc6857ffc5be455e28a691f8e" +checksum = "2c8fc60ba15bf51257aa9807a48a61013db043fcf3a78cb0d916e8e396dcad98" dependencies = [ "kqueue-sys", "libc", @@ -1603,15 +1686,6 @@ dependencies = [ "libc", ] -[[package]] -name = "kstring" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b310ccceade8121d7d77fee406160e457c2f4e7c7982d589da3499bc7ea4526" -dependencies = [ - "serde", -] - [[package]] name = "lazy_static" version = "1.4.0" @@ -1626,9 +1700,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.127" +version = "0.2.135" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "505e71a4706fa491e9b1b55f51b95d4037d0821ee40131190475f692b35b009b" +checksum = "68783febc7782c6c5cb401fbda4de5a9898be1762314da0bb2c10ced61f18b0c" [[package]] name = "libloading" @@ -1647,10 +1721,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "292a948cd991e376cf75541fe5b97a1081d713c618b4f1b9500f8844e49eb565" [[package]] -name = "lock_api" -version = "0.4.7" +name = "link-cplusplus" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53" +checksum = "9272ab7b96c9046fbc5bc56c06c117cb639fe2d509df0c421cad82d2915cf369" +dependencies = [ + "cc", +] + +[[package]] +name = "lock_api" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" dependencies = [ "autocfg", "scopeguard", @@ -1675,12 +1758,6 @@ dependencies = [ "regex-automata", ] -[[package]] -name = "matches" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" - [[package]] name = "matchit" version = "0.5.0" @@ -1700,11 +1777,11 @@ dependencies = [ [[package]] name = "md-5" -version = "0.10.1" +version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "658646b21e0b72f7866c7038ab086d3d5e1cd6271f060fd37defb241949d0582" +checksum = "6365506850d44bff6e2fbcb5176cf63650e48bd45ef2fe2665ae1570e0f4b9ca" dependencies = [ - "digest 0.10.3", + "digest 0.10.5", ] [[package]] @@ -1721,9 +1798,9 @@ checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "memmap2" -version = "0.5.5" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a79b39c93a7a5a27eeaf9a23b5ff43f1b9e0ad6b1cdd441140ae53c35613fc7" +checksum = "95af15f345b17af2efc8ead6080fb8bc376f8cec1b35277b935637595fe77498" dependencies = [ "libc", ] @@ -1737,6 +1814,15 @@ dependencies = [ "autocfg", ] +[[package]] +name = "memoffset" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +dependencies = [ + "autocfg", +] + [[package]] name = "metrics" version = "0.1.0" @@ -1761,9 +1847,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.5.3" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f5c75688da582b8ffc1f1799e9db273f32133c49e048f614d22ec3256773ccc" +checksum = "96590ba8f175222643a85693f33d26e9c8a015f599c216509b1a6894af675d34" dependencies = [ "adler", ] @@ -1829,14 +1915,22 @@ dependencies = [ "cc", "cfg-if", "libc", - "memoffset", + "memoffset 0.6.5", ] [[package]] -name = "nodrop" -version = "0.1.14" +name = "nix" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" +checksum = "e322c04a9e3440c327fca7b6c8a63e6890a32fa2ad689db972425f07e0d22abb" +dependencies = [ + "autocfg", + "bitflags", + "cfg-if", + "libc", + "memoffset 0.6.5", + "pin-utils", +] [[package]] name = "nom" @@ -1866,6 +1960,16 @@ dependencies = [ "winapi", ] +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + [[package]] name = "num-bigint" version = "0.4.3" @@ -1879,12 +1983,12 @@ dependencies = [ [[package]] name = "num-format" -version = "0.4.0" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bafe4179722c2894288ee77a9f044f02811c86af699344c498b0840c698a2465" +checksum = "54b862ff8df690cf089058c98b183676a7ed0f974cc08b426800093227cbff3b" dependencies = [ "arrayvec", - "itoa 0.4.8", + "itoa", ] [[package]] @@ -1937,18 +2041,18 @@ dependencies = [ [[package]] name = "oid-registry" -version = "0.4.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38e20717fa0541f39bd146692035c37bedfa532b3e5071b35761082407546b2a" +checksum = "7d4bda43fd1b844cbc6e6e54b5444e2b1bc7838bce59ad205902cccbb26d6761" dependencies = [ "asn1-rs", ] [[package]] name = "once_cell" -version = "1.13.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1" +checksum = "e82dad04139b71a90c080c8463fe0dc7902db5192d939bd0950f074d014339e1" [[package]] name = "oorandom" @@ -1964,9 +2068,9 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "openssl" -version = "0.10.41" +version = "0.10.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "618febf65336490dfcf20b73f885f5651a0c89c64c2d4a8c3662585a70bf5bd0" +checksum = "12fc0523e3bd51a692c8850d075d74dc062ccf251c0110668cbd921917118a13" dependencies = [ "bitflags", "cfg-if", @@ -1996,9 +2100,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.75" +version = "0.9.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5f9bd0c2710541a3cda73d6f9ac4f1b240de4ae261065d309dbe73d9dceb42f" +checksum = "5230151e44c0f05157effb743e8d517472843121cf9243e8b81393edb5acd9ce" dependencies = [ "autocfg", "cc", @@ -2009,9 +2113,15 @@ dependencies = [ [[package]] name = "os_str_bytes" -version = "6.2.0" +version = "6.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "648001efe5d5c0102d8cea768e348da85d90af8ba91f0bea908f157951493cd4" +checksum = "9ff7415e9ae3fff1225851df9e0d9e4e5479f947619774677a63572e55e80eff" + +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" [[package]] name = "pageserver" @@ -2024,10 +2134,11 @@ dependencies = [ "byteorder", "bytes", "chrono", - "clap 3.2.16", + "clap 4.0.15", "close_fds", "const_format", "crc32c", + "criterion", "crossbeam-utils", "daemonize", "etcd_broker", @@ -2041,7 +2152,7 @@ dependencies = [ "hyper", "itertools", "metrics", - "nix", + "nix 0.25.0", "num-traits", "once_cell", "pageserver_api", @@ -2149,9 +2260,9 @@ dependencies = [ [[package]] name = "percent-encoding" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" +checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" [[package]] name = "petgraph" @@ -2183,18 +2294,18 @@ dependencies = [ [[package]] name = "pin-project" -version = "1.0.11" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78203e83c48cffbe01e4a2d35d566ca4de445d79a85372fc64e378bfc812a260" +checksum = "ad29a609b6bcd67fee905812e544992d216af9d755757c05ed2d0e15a74c6ecc" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.0.11" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "710faf75e1b33345361201d36d04e98ac1ed8909151a017ed384700836104c74" +checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55" dependencies = [ "proc-macro2", "quote", @@ -2221,9 +2332,9 @@ checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae" [[package]] name = "plotters" -version = "0.3.2" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9428003b84df1496fb9d6eeee9c5f8145cb41ca375eb0dad204328888832811f" +checksum = "2538b639e642295546c50fcd545198c9d64ee2a38620a628724a3b266d5fbf97" dependencies = [ "num-traits", "plotters-backend", @@ -2240,9 +2351,9 @@ checksum = "193228616381fecdc1224c62e96946dfbc73ff4384fba576e052ff8c1bea8142" [[package]] name = "plotters-svg" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0918736323d1baff32ee0eade54984f6f201ad7e97d5cfb5d6ab4a358529615" +checksum = "f9a81d2759aae1dae668f783c308bc5c8ebd191ff4184aaa1b37f65a6ae5a56f" dependencies = [ "plotters-backend", ] @@ -2271,10 +2382,10 @@ dependencies = [ "fallible-iterator", "hmac 0.12.1", "lazy_static", - "md-5 0.10.1", + "md-5 0.10.5", "memchr", "rand", - "sha2 0.10.2", + "sha2 0.10.6", "stringprep", ] @@ -2300,7 +2411,7 @@ dependencies = [ "env_logger", "hex", "log", - "memoffset", + "memoffset 0.7.1", "once_cell", "postgres", "rand", @@ -2324,7 +2435,7 @@ dependencies = [ "lazy_static", "libc", "log", - "nix", + "nix 0.23.1", "parking_lot 0.11.2", "symbolic-demangle", "tempfile", @@ -2339,9 +2450,9 @@ checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" [[package]] name = "prettyplease" -version = "0.1.18" +version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "697ae720ee02011f439e0701db107ffe2916d83f718342d65d7f8bf7b8a5fee9" +checksum = "c142c0e46b57171fe0c528bee8c5b7569e80f0c17e377cd0e30ea57dbc11bb51" dependencies = [ "proc-macro2", "syn", @@ -2355,9 +2466,9 @@ checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" [[package]] name = "proc-macro2" -version = "1.0.43" +version = "1.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab" +checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" dependencies = [ "unicode-ident", ] @@ -2377,9 +2488,9 @@ dependencies = [ [[package]] name = "prometheus" -version = "0.13.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cface98dfa6d645ea4c789839f176e4b072265d085bfcc48eaa8d137f58d3c39" +checksum = "45c8babc29389186697fe5a2a4859d697825496b83db5d0b65271cdc0488e88c" dependencies = [ "cfg-if", "fnv", @@ -2410,7 +2521,7 @@ dependencies = [ "bytes", "cfg-if", "cmake", - "heck 0.4.0", + "heck", "itertools", "lazy_static", "log", @@ -2456,7 +2567,7 @@ dependencies = [ "base64", "bstr", "bytes", - "clap 3.2.16", + "clap 4.0.15", "futures", "git-version", "hashbrown", @@ -2479,7 +2590,7 @@ dependencies = [ "scopeguard", "serde", "serde_json", - "sha2 0.10.2", + "sha2 0.10.6", "socket2", "thiserror", "tokio", @@ -2490,7 +2601,7 @@ dependencies = [ "tracing-subscriber", "url", "utils", - "uuid", + "uuid 1.2.1", "workspace_hack", "x509-parser", ] @@ -2537,9 +2648,9 @@ dependencies = [ [[package]] name = "rand_core" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ "getrandom", ] @@ -2579,13 +2690,13 @@ dependencies = [ [[package]] name = "rcgen" -version = "0.8.14" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5911d1403f4143c9d56a702069d593e8d0f3fab880a85e103604d0893ea31ba7" +checksum = "ffbe84efe2f38dea12e9bfc1f65377fdf03e53a18cb3b995faedf7934c7e785b" dependencies = [ - "chrono", "pem", "ring", + "time 0.3.15", "yasna", ] @@ -2667,9 +2778,9 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.11.11" +version = "0.11.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b75aa69a3f06bbcc66ede33af2af253c6f7a86b1ca0033f60c580a27074fbf92" +checksum = "431949c384f4e2ae07605ccaa56d1d9d2ecdb5cadd4f9577ccfab29f2e5149fc" dependencies = [ "base64", "bytes", @@ -2683,9 +2794,9 @@ dependencies = [ "hyper-rustls", "ipnet", "js-sys", - "lazy_static", "log", "mime", + "once_cell", "percent-encoding", "pin-project-lite", "rustls", @@ -2706,9 +2817,9 @@ dependencies = [ [[package]] name = "rgb" -version = "0.8.33" +version = "0.8.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3b221de559e4a29df3b957eec92bc0de6bc8eaf6ca9cfed43e5e1d67ff65a34" +checksum = "3603b7d71ca82644f79b5a06d1220e9a58ede60bd32255f698cb1af8838b8db3" dependencies = [ "bytemuck", ] @@ -2775,9 +2886,21 @@ dependencies = [ [[package]] name = "rstest" -version = "0.12.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d912f35156a3f99a66ee3e11ac2e0b3f34ac85a07e05263d05a7e2c8810d616f" +checksum = "e9c9dc66cc29792b663ffb5269be669f1613664e69ad56441fdb895c2347b930" +dependencies = [ + "futures", + "futures-timer", + "rstest_macros", + "rustc_version 0.4.0", +] + +[[package]] +name = "rstest_macros" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5015e68a0685a95ade3eee617ff7101ab6a3fc689203101ca16ebc16f2b89c66" dependencies = [ "cfg-if", "proc-macro2", @@ -2895,7 +3018,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver 1.0.13", + "semver 1.0.14", ] [[package]] @@ -2957,7 +3080,7 @@ dependencies = [ "async-trait", "byteorder", "bytes", - "clap 3.2.16", + "clap 4.0.15", "const_format", "crc32c", "daemonize", @@ -3027,6 +3150,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +[[package]] +name = "scratch" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8132065adcfd6e02db789d9285a0deb2f3fcb04002865ab67d5fb103533898" + [[package]] name = "sct" version = "0.7.0" @@ -3039,9 +3168,9 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.6.1" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dc14f172faf8a0194a3aded622712b0de276821addc574fa54fc0a1167e10dc" +checksum = "2bc1bb97804af6631813c55739f771071e0f2ed33ee20b68c86ec505d906356c" dependencies = [ "bitflags", "core-foundation", @@ -3071,9 +3200,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93f6841e709003d68bb2deee8c343572bf446003ec20a583e76f7b15cebf3711" +checksum = "e25dfac463d778e353db5be2449d1cce89bd6fd23c9f1ea21310ce6e5a1b29c4" [[package]] name = "semver-parser" @@ -3083,28 +3212,18 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" -version = "1.0.142" +version = "1.0.145" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e590c437916fb6b221e1d00df6e3294f3fccd70ca7e92541c475d6ed6ef5fee2" +checksum = "728eb6351430bccb993660dfffc5a72f91ccc1295abaa8ce19b27ebe4f75568b" dependencies = [ "serde_derive", ] -[[package]] -name = "serde_cbor" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5" -dependencies = [ - "half", - "serde", -] - [[package]] name = "serde_derive" -version = "1.0.142" +version = "1.0.145" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34b5b8d809babe02f538c2cfec6f2c1ed10804c0e5a6a041a049a4f5588ccc2e" +checksum = "81fa1584d3d1bcacd84c277a0dfe21f5b0f6accf4a23d04d4c6d61f1af522b4c" dependencies = [ "proc-macro2", "quote", @@ -3113,11 +3232,11 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.83" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38dd04e3c8279e75b31ef29dbdceebfe5ad89f4d0937213c53f7d49d01b3d5a7" +checksum = "41feea4228a6f1cd09ec7a3593a682276702cd67b5273544757dae23c096f074" dependencies = [ - "itoa 1.0.3", + "itoa", "ryu", "serde", ] @@ -3129,26 +3248,32 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" dependencies = [ "form_urlencoded", - "itoa 1.0.3", + "itoa", "ryu", "serde", ] [[package]] name = "serde_with" -version = "1.14.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "678b5a069e50bf00ecd22d0cd8ddf7c236f68581b03db652061ed5eb13a312ff" +checksum = "368f2d60d049ea019a84dcd6687b0d1e0030fe663ae105039bdf967ed5e6a9a7" dependencies = [ + "base64", + "chrono", + "hex", + "indexmap", "serde", + "serde_json", "serde_with_macros", + "time 0.3.15", ] [[package]] name = "serde_with_macros" -version = "1.5.2" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e182d6ec6f05393cc0e5ed1bf81ad6db3a8feedf8ee515ecdd369809bcce8082" +checksum = "1ccadfacf6cf10faad22bbadf55986bdd0856edfb5d9210aa1dcf1f516e84e93" dependencies = [ "darling", "proc-macro2", @@ -3171,13 +3296,13 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.2" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55deaec60f81eefe3cce0dc50bda92d6d8e88f2a27df7c5033b42afeb1ed2676" +checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.10.3", + "digest 0.10.5", ] [[package]] @@ -3234,7 +3359,7 @@ dependencies = [ "num-bigint", "num-traits", "thiserror", - "time 0.3.12", + "time 0.3.15", ] [[package]] @@ -3254,15 +3379,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fd0db749597d91ff862fd1d55ea87f7855a744a8425a64695b6fca237d1dad1" +checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" [[package]] name = "socket2" -version = "0.4.4" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0" +checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd" dependencies = [ "libc", "winapi", @@ -3313,17 +3438,17 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "strum" -version = "0.23.0" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cae14b91c7d11c9a851d3fbc80a963198998c2a64eec840477fa92d8ce9b70bb" +checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f" [[package]] name = "strum_macros" -version = "0.23.1" +version = "0.24.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bb0dc7ee9c15cea6199cde9a127fa16a4c5819af85395457ad72d68edc85a38" +checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" dependencies = [ - "heck 0.3.3", + "heck", "proc-macro2", "quote", "rustversion", @@ -3345,7 +3470,7 @@ dependencies = [ "debugid", "memmap2", "stable_deref_trait", - "uuid", + "uuid 0.8.2", ] [[package]] @@ -3361,9 +3486,9 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.99" +version = "1.0.102" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58dbef6ec655055e20b86b15a8cc6d439cca19b667537ac6a1369572d151ab13" +checksum = "3fcd952facd492f9be3ef0d0b7032a6e442ee9b361d4acc2b1d0c4aaa5f613a1" dependencies = [ "proc-macro2", "quote", @@ -3424,33 +3549,24 @@ dependencies = [ [[package]] name = "textwrap" -version = "0.11.0" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" -dependencies = [ - "unicode-width", -] - -[[package]] -name = "textwrap" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" +checksum = "949517c0cf1bf4ee812e2e07e08ab448e3ae0d23472aee8a06c985f0c8815b16" [[package]] name = "thiserror" -version = "1.0.32" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5f6586b7f764adc0231f4c79be7b920e766bb2f3e51b3661cdb263828f19994" +checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.32" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12bafc5b54507e0149cdf1b145a5d80ab80a90bcd9275df43d4fff68460f6c21" +checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" dependencies = [ "proc-macro2", "quote", @@ -3479,14 +3595,14 @@ dependencies = [ [[package]] name = "time" -version = "0.3.12" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74b7cc93fc23ba97fde84f7eea56c55d1ba183f495c6715defdfc7b9cb8c870f" +checksum = "d634a985c4d4238ec39cacaed2e7ae552fbd3c476b552c1deac3021b7d7eaf0c" dependencies = [ - "itoa 1.0.3", - "js-sys", + "itoa", "libc", "num_threads", + "serde", "time-macros", ] @@ -3523,9 +3639,9 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tokio" -version = "1.20.1" +version = "1.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a8325f63a7d4774dd041e363b2409ed1c5cbbd0f867795e661df066b2b0a581" +checksum = "0020c875007ad96677dcc890298f4b942882c5d4eb7cc8f439fc3bf813dc9c95" dependencies = [ "autocfg", "bytes", @@ -3621,9 +3737,9 @@ dependencies = [ [[package]] name = "tokio-stream" -version = "0.1.9" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df54d54117d6fdc4e4fea40fe1e4e566b3505700e148a6827e59b34b0d2600d9" +checksum = "d660770404473ccd7bc9f8b28494a811bc18542b915c0855c51e8f419d5223ce" dependencies = [ "futures-core", "pin-project-lite", @@ -3632,9 +3748,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc463cd8deddc3770d20f9852143d50bf6094e640b485cb2e189a2099085ff45" +checksum = "0bb2e075f03b3d66d8d8785356224ba688d2906a371015e225beeb65ca92c740" dependencies = [ "bytes", "futures-core", @@ -3655,14 +3771,13 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.13.4" +version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "744e9ed5b352340aa47ce033716991b5589e23781acb97cad37d4ea70560f55b" +checksum = "5376256e44f2443f8896ac012507c19a012df0fe8758b55246ae51a2279db51f" dependencies = [ "combine", "indexmap", "itertools", - "kstring", "serde", ] @@ -3752,9 +3867,9 @@ dependencies = [ [[package]] name = "tower-layer" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "343bc9466d3fe6b0f960ef45960509f84480bf4fd96f92901afe7ff3df9d3a62" +checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" [[package]] name = "tower-service" @@ -3764,9 +3879,9 @@ checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" [[package]] name = "tracing" -version = "0.1.36" +version = "0.1.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fce9567bd60a67d08a16488756721ba392f24f29006402881e43b19aac64307" +checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" dependencies = [ "cfg-if", "log", @@ -3777,9 +3892,9 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.22" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11c75893af559bc8e10716548bdef5cb2b983f8e637db9d0e15126b61b484ee2" +checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" dependencies = [ "proc-macro2", "quote", @@ -3788,9 +3903,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.29" +version = "0.1.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aeea4303076558a00714b823f9ad67d58a3bbda1df83d8827d21193156e22f7" +checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" dependencies = [ "once_cell", "valuable", @@ -3819,13 +3934,13 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.11" +version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bc28f93baff38037f64e6f43d34cfa1605f27a49c34e8a04c5e78b0babf2596" +checksum = "a6176eae26dd70d0c919749377897b54a9276bd7061339665dd68777926b5a70" dependencies = [ - "ansi_term", - "lazy_static", "matchers", + "nu-ansi-term", + "once_cell", "regex", "sharded-slab", "smallvec", @@ -3855,36 +3970,30 @@ checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" [[package]] name = "unicode-ident" -version = "1.0.3" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4f5b37a154999a8f3f98cc23a628d850e154479cd94decf3414696e12e31aaf" +checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" [[package]] name = "unicode-normalization" -version = "0.1.21" +version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "854cbdc4f7bc6ae19c820d44abdc3277ac3e1b2b93db20a636825d9322fb60e6" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" dependencies = [ "tinyvec", ] -[[package]] -name = "unicode-segmentation" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e8820f5d777f6224dc4be3632222971ac30164d4a258d595640799554ebfd99" - [[package]] name = "unicode-width" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" +checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" [[package]] name = "unicode-xid" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "957e51f3646910546462e67d5f7599b9e4fb8acdd304b087a6494730f9eebf04" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" [[package]] name = "untrusted" @@ -3894,13 +4003,12 @@ checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" [[package]] name = "url" -version = "2.2.2" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" +checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643" dependencies = [ "form_urlencoded", "idna", - "matches", "percent-encoding", ] @@ -3920,7 +4028,7 @@ dependencies = [ "hyper", "jsonwebtoken", "metrics", - "nix", + "nix 0.25.0", "once_cell", "pin-project-lite", "postgres", @@ -3948,6 +4056,12 @@ name = "uuid" version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" + +[[package]] +name = "uuid" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "feb41e78f93363bb2df8b0e86a2ca30eed7806ea16ea0c790d757cf93f79be83" dependencies = [ "getrandom", "serde", @@ -3997,7 +4111,7 @@ name = "wal_craft" version = "0.1.0" dependencies = [ "anyhow", - "clap 3.2.16", + "clap 4.0.15", "env_logger", "log", "once_cell", @@ -4042,9 +4156,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.82" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7652e3f6c4706c8d9cd54832c4a4ccb9b5336e2c3bd154d5cccfbf1c1f5f7d" +checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -4052,9 +4166,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.82" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "662cd44805586bd52971b9586b1df85cdbbd9112e4ef4d8f41559c334dc6ac3f" +checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" dependencies = [ "bumpalo", "log", @@ -4067,9 +4181,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.32" +version = "0.4.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa76fb221a1f8acddf5b54ace85912606980ad661ac7a503b4570ffd3a624dad" +checksum = "23639446165ca5a5de86ae1d8896b737ae80319560fbaa4c2887b7da6e7ebd7d" dependencies = [ "cfg-if", "js-sys", @@ -4079,9 +4193,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.82" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b260f13d3012071dfb1512849c033b1925038373aea48ced3012c09df952c602" +checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -4089,9 +4203,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.82" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5be8e654bdd9b79216c2929ab90721aa82faf65c48cdf08bdc4e7f51357b80da" +checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" dependencies = [ "proc-macro2", "quote", @@ -4102,15 +4216,15 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.82" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6598dd0bd3c7d51095ff6531a5b23e02acdc81804e30d8f07afb77b7215a140a" +checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" [[package]] name = "web-sys" -version = "0.3.59" +version = "0.3.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed055ab27f941423197eb86b2035720b1a3ce40504df082cac2ecc6ed73335a1" +checksum = "bcda906d8be16e728fd5adc5b729afad4e444e106ab28cd1c7256e54fa61510f" dependencies = [ "js-sys", "wasm-bindgen", @@ -4128,22 +4242,22 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.22.4" +version = "0.22.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1c760f0d366a6c24a02ed7816e23e691f5d92291f94d15e836006fd11b04daf" +checksum = "368bfe657969fb01238bb756d351dcade285e0f6fcbd36dcb23359a5169975be" dependencies = [ "webpki", ] [[package]] name = "which" -version = "4.2.5" +version = "4.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c4fb54e6113b6a8772ee41c3404fb0301ac79604489467e0a9ce1f3e97c24ae" +checksum = "1c831fbbee9e129a8cf93e7747a82da9d95ba8e16621cae60ec2cdc849bacb7b" dependencies = [ "either", - "lazy_static", "libc", + "once_cell", ] [[package]] @@ -4235,15 +4349,14 @@ version = "0.1.0" dependencies = [ "ahash", "anyhow", - "bstr", "bytes", "chrono", + "clap 4.0.15", "crossbeam-utils", "either", "fail", "hashbrown", "indexmap", - "itoa 0.4.8", "libc", "log", "memchr", @@ -4254,25 +4367,23 @@ dependencies = [ "prost", "rand", "regex", - "regex-automata", "regex-syntax", "scopeguard", "serde", "stable_deref_trait", "syn", - "time 0.3.12", + "time 0.3.15", "tokio", "tokio-util", "tracing", "tracing-core", - "uuid", ] [[package]] name = "x509-parser" -version = "0.13.2" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb9bace5b5589ffead1afb76e43e34cff39cd0f3ce7e170ae0c29e53b88eb1c" +checksum = "e0ecbeb7b67ce215e40e3cc7f2ff902f94a223acf44995934763467e7b1febc8" dependencies = [ "asn1-rs", "base64", @@ -4283,7 +4394,7 @@ dependencies = [ "oid-registry", "rusticata-macros", "thiserror", - "time 0.3.12", + "time 0.3.15", ] [[package]] @@ -4303,11 +4414,11 @@ checksum = "d2d7d3948613f75c98fd9328cfdcc45acc4d360655289d0a7d4ec931392200a3" [[package]] name = "yasna" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e262a29d0e61ccf2b6190d7050d4b237535fc76ce4c1210d9caa316f71dffa75" +checksum = "346d34a236c9d3e5f3b9b74563f238f955bbd05fa0b8b4efa53c130c43982f4c" dependencies = [ - "chrono", + "time 0.3.15", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index bc2a705558..32c243bf44 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,3 +1,14 @@ +# 'named-profiles' feature was stabilized in cargo 1.57. This line makes the +# build work with older cargo versions. +# +# We have this because as of this writing, the latest cargo Debian package +# that's available is 1.56. (Confusingly, the Debian package version number +# is 0.57, whereas 'cargo --version' says 1.56.) +# +# See https://tracker.debian.org/pkg/cargo for the current status of the +# package. When that gets updated, we can remove this. +cargo-features = ["named-profiles"] + [workspace] members = [ "compute_tools", diff --git a/Dockerfile b/Dockerfile index 69402919ec..cb4e213687 100644 --- a/Dockerfile +++ b/Dockerfile @@ -44,7 +44,7 @@ COPY . . # Show build caching stats to check if it was used in the end. # Has to be the part of the same RUN since cachepot daemon is killed in the end of this RUN, losing the compilation stats. RUN set -e \ -&& mold -run cargo build --bin pageserver --bin safekeeper --bin proxy --locked --release \ +&& mold -run cargo build --bin pageserver --bin pageserver_binutils --bin safekeeper --bin proxy --locked --release \ && cachepot -s # Build final image @@ -63,9 +63,10 @@ RUN set -e \ && useradd -d /data neon \ && chown -R neon:neon /data -COPY --from=build --chown=neon:neon /home/nonroot/target/release/pageserver /usr/local/bin -COPY --from=build --chown=neon:neon /home/nonroot/target/release/safekeeper /usr/local/bin -COPY --from=build --chown=neon:neon /home/nonroot/target/release/proxy /usr/local/bin +COPY --from=build --chown=neon:neon /home/nonroot/target/release/pageserver /usr/local/bin +COPY --from=build --chown=neon:neon /home/nonroot/target/release/pageserver_binutils /usr/local/bin +COPY --from=build --chown=neon:neon /home/nonroot/target/release/safekeeper /usr/local/bin +COPY --from=build --chown=neon:neon /home/nonroot/target/release/proxy /usr/local/bin COPY --from=pg-build /home/nonroot/pg_install/v14 /usr/local/v14/ COPY --from=pg-build /home/nonroot/pg_install/v15 /usr/local/v15/ @@ -85,4 +86,3 @@ VOLUME ["/data"] USER neon EXPOSE 6400 EXPOSE 9898 -CMD ["/bin/bash"] diff --git a/Dockerfile.compute-node-v14 b/Dockerfile.compute-node-v14 index ed57b29009..f5ccdf7e99 100644 --- a/Dockerfile.compute-node-v14 +++ b/Dockerfile.compute-node-v14 @@ -71,10 +71,12 @@ RUN apt update && \ RUN apt update && \ apt install -y --no-install-recommends -t testing binutils +# Sed is used to patch for https://github.com/plv8/plv8/issues/503 RUN wget https://github.com/plv8/plv8/archive/refs/tags/v3.1.4.tar.gz && \ tar xvzf v3.1.4.tar.gz && \ cd plv8-3.1.4 && \ export PATH="/usr/local/pgsql/bin:$PATH" && \ + sed -i 's/MemoryContextAlloc(/MemoryContextAllocZero(/' plv8.cc && \ make -j $(getconf _NPROCESSORS_ONLN) && \ make -j $(getconf _NPROCESSORS_ONLN) install && \ rm -rf /plv8-* && \ @@ -116,8 +118,7 @@ RUN wget https://github.com/zachasme/h3-pg/archive/refs/tags/v4.0.1.tar.gz -O h3 # FROM build-deps AS neon-pg-ext-build COPY --from=postgis-build /usr/local/pgsql/ /usr/local/pgsql/ -# plv8 still sometimes crashes during the creation -# COPY --from=plv8-build /usr/local/pgsql/ /usr/local/pgsql/ +COPY --from=plv8-build /usr/local/pgsql/ /usr/local/pgsql/ COPY --from=h3-pg-build /usr/local/pgsql/ /usr/local/pgsql/ COPY --from=h3-pg-build /h3/usr / COPY pgxn/ pgxn/ diff --git a/Dockerfile.compute-node-v15 b/Dockerfile.compute-node-v15 index bdb4330c4f..ec555ad932 100644 --- a/Dockerfile.compute-node-v15 +++ b/Dockerfile.compute-node-v15 @@ -76,10 +76,12 @@ RUN apt update && \ RUN apt update && \ apt install -y --no-install-recommends -t testing binutils +# Sed is used to patch for https://github.com/plv8/plv8/issues/503 RUN wget https://github.com/plv8/plv8/archive/refs/tags/v3.1.4.tar.gz && \ tar xvzf v3.1.4.tar.gz && \ cd plv8-3.1.4 && \ export PATH="/usr/local/pgsql/bin:$PATH" && \ + sed -i 's/MemoryContextAlloc(/MemoryContextAllocZero(/' plv8.cc && \ make -j $(getconf _NPROCESSORS_ONLN) && \ make -j $(getconf _NPROCESSORS_ONLN) install && \ rm -rf /plv8-* && \ @@ -121,8 +123,7 @@ RUN wget https://github.com/zachasme/h3-pg/archive/refs/tags/v4.0.1.tar.gz -O h3 # FROM build-deps AS neon-pg-ext-build COPY --from=postgis-build /usr/local/pgsql/ /usr/local/pgsql/ -# plv8 still sometimes crashes during the creation -# COPY --from=plv8-build /usr/local/pgsql/ /usr/local/pgsql/ +COPY --from=plv8-build /usr/local/pgsql/ /usr/local/pgsql/ COPY --from=h3-pg-build /usr/local/pgsql/ /usr/local/pgsql/ COPY --from=h3-pg-build /h3/usr / COPY pgxn/ pgxn/ diff --git a/compute_tools/Cargo.toml b/compute_tools/Cargo.toml index 43cf7ae2dd..d6f8fae34c 100644 --- a/compute_tools/Cargo.toml +++ b/compute_tools/Cargo.toml @@ -6,7 +6,7 @@ edition = "2021" [dependencies] anyhow = "1.0" chrono = "0.4" -clap = "3.0" +clap = "4.0" env_logger = "0.9" futures = "0.3.13" hyper = { version = "0.14", features = ["full"] } diff --git a/compute_tools/src/bin/compute_ctl.rs b/compute_tools/src/bin/compute_ctl.rs index fc5bbc5fd2..7786d7af9c 100644 --- a/compute_tools/src/bin/compute_ctl.rs +++ b/compute_tools/src/bin/compute_ctl.rs @@ -51,53 +51,19 @@ fn main() -> Result<()> { // TODO: re-use `utils::logging` later init_logger(DEFAULT_LOG_LEVEL)?; - // Env variable is set by `cargo` - let version: Option<&str> = option_env!("CARGO_PKG_VERSION"); - let matches = clap::App::new("compute_ctl") - .version(version.unwrap_or("unknown")) - .arg( - Arg::new("connstr") - .short('C') - .long("connstr") - .value_name("DATABASE_URL") - .required(true), - ) - .arg( - Arg::new("pgdata") - .short('D') - .long("pgdata") - .value_name("DATADIR") - .required(true), - ) - .arg( - Arg::new("pgbin") - .short('b') - .long("pgbin") - .value_name("POSTGRES_PATH"), - ) - .arg( - Arg::new("spec") - .short('s') - .long("spec") - .value_name("SPEC_JSON"), - ) - .arg( - Arg::new("spec-path") - .short('S') - .long("spec-path") - .value_name("SPEC_PATH"), - ) - .get_matches(); + let matches = cli().get_matches(); - let pgdata = matches.value_of("pgdata").expect("PGDATA path is required"); + let pgdata = matches + .get_one::("pgdata") + .expect("PGDATA path is required"); let connstr = matches - .value_of("connstr") + .get_one::("connstr") .expect("Postgres connection string is required"); - let spec = matches.value_of("spec"); - let spec_path = matches.value_of("spec-path"); + let spec = matches.get_one::("spec"); + let spec_path = matches.get_one::("spec-path"); // Try to use just 'postgres' if no path is provided - let pgbin = matches.value_of("pgbin").unwrap_or("postgres"); + let pgbin = matches.get_one::("pgbin").unwrap(); let spec: ComputeSpec = match spec { // First, try to get cluster spec from the cli argument @@ -173,3 +139,48 @@ fn main() -> Result<()> { } } } + +fn cli() -> clap::Command { + // Env variable is set by `cargo` + let version = option_env!("CARGO_PKG_VERSION").unwrap_or("unknown"); + clap::Command::new("compute_ctl") + .version(version) + .arg( + Arg::new("connstr") + .short('C') + .long("connstr") + .value_name("DATABASE_URL") + .required(true), + ) + .arg( + Arg::new("pgdata") + .short('D') + .long("pgdata") + .value_name("DATADIR") + .required(true), + ) + .arg( + Arg::new("pgbin") + .short('b') + .long("pgbin") + .default_value("postgres") + .value_name("POSTGRES_PATH"), + ) + .arg( + Arg::new("spec") + .short('s') + .long("spec") + .value_name("SPEC_JSON"), + ) + .arg( + Arg::new("spec-path") + .short('S') + .long("spec-path") + .value_name("SPEC_PATH"), + ) +} + +#[test] +fn verify_cli() { + cli().debug_assert() +} diff --git a/compute_tools/src/pg_helpers.rs b/compute_tools/src/pg_helpers.rs index ad7ea0abc8..42aa00af01 100644 --- a/compute_tools/src/pg_helpers.rs +++ b/compute_tools/src/pg_helpers.rs @@ -8,11 +8,10 @@ use std::process::Child; use std::time::{Duration, Instant}; use anyhow::{bail, Result}; +use notify::{RecursiveMode, Watcher}; use postgres::{Client, Transaction}; use serde::Deserialize; -use notify::{RecursiveMode, Watcher}; - const POSTGRES_WAIT_TIMEOUT: Duration = Duration::from_millis(60 * 1000); // milliseconds /// Rust representation of Postgres role info with only those fields @@ -169,7 +168,7 @@ impl Database { /// it may require a proper quoting too. pub fn to_pg_options(&self) -> String { let mut params: String = self.options.as_pg_options(); - write!(params, " OWNER {}", &self.owner.quote()) + write!(params, " OWNER {}", &self.owner.pg_quote()) .expect("String is documented to not to error during write operations"); params @@ -180,18 +179,17 @@ impl Database { /// intended to be used for DB / role names. pub type PgIdent = String; -/// Generic trait used to provide quoting for strings used in the -/// Postgres SQL queries. Currently used only to implement quoting -/// of identifiers, but could be used for literals in the future. -pub trait PgQuote { - fn quote(&self) -> String; +/// Generic trait used to provide quoting / encoding for strings used in the +/// Postgres SQL queries and DATABASE_URL. +pub trait Escaping { + fn pg_quote(&self) -> String; } -impl PgQuote for PgIdent { +impl Escaping for PgIdent { /// This is intended to mimic Postgres quote_ident(), but for simplicity it - /// always quotes provided string with `""` and escapes every `"`. Not idempotent, - /// i.e. if string is already escaped it will be escaped again. - fn quote(&self) -> String { + /// always quotes provided string with `""` and escapes every `"`. + /// **Not idempotent**, i.e. if string is already escaped it will be escaped again. + fn pg_quote(&self) -> String { let result = format!("\"{}\"", self.replace('"', "\"\"")); result } diff --git a/compute_tools/src/spec.rs b/compute_tools/src/spec.rs index bd47614386..e0c0e9404b 100644 --- a/compute_tools/src/spec.rs +++ b/compute_tools/src/spec.rs @@ -1,7 +1,9 @@ use std::path::Path; +use std::str::FromStr; use anyhow::Result; use log::{info, log_enabled, warn, Level}; +use postgres::config::Config; use postgres::{Client, NoTls}; use serde::Deserialize; @@ -115,8 +117,8 @@ pub fn handle_roles(spec: &ComputeSpec, client: &mut Client) -> Result<()> { if existing_roles.iter().any(|r| r.name == op.name) { let query: String = format!( "ALTER ROLE {} RENAME TO {}", - op.name.quote(), - new_name.quote() + op.name.pg_quote(), + new_name.pg_quote() ); warn!("renaming role '{}' to '{}'", op.name, new_name); @@ -162,7 +164,7 @@ pub fn handle_roles(spec: &ComputeSpec, client: &mut Client) -> Result<()> { } if update_role { - let mut query: String = format!("ALTER ROLE {} ", name.quote()); + let mut query: String = format!("ALTER ROLE {} ", name.pg_quote()); info_print!(" -> update"); query.push_str(&role.to_pg_options()); @@ -170,7 +172,7 @@ pub fn handle_roles(spec: &ComputeSpec, client: &mut Client) -> Result<()> { } } else { info!("role name: '{}'", &name); - let mut query: String = format!("CREATE ROLE {} ", name.quote()); + let mut query: String = format!("CREATE ROLE {} ", name.pg_quote()); info!("role create query: '{}'", &query); info_print!(" -> create"); @@ -179,7 +181,7 @@ pub fn handle_roles(spec: &ComputeSpec, client: &mut Client) -> Result<()> { let grant_query = format!( "GRANT pg_read_all_data, pg_write_all_data TO {}", - name.quote() + name.pg_quote() ); xact.execute(grant_query.as_str(), &[])?; info!("role grant query: '{}'", &grant_query); @@ -215,7 +217,7 @@ pub fn handle_role_deletions(node: &ComputeNode, client: &mut Client) -> Result< // We do not check either role exists or not, // Postgres will take care of it for us if op.action == "delete_role" { - let query: String = format!("DROP ROLE IF EXISTS {}", &op.name.quote()); + let query: String = format!("DROP ROLE IF EXISTS {}", &op.name.pg_quote()); warn!("deleting role '{}'", &op.name); xact.execute(query.as_str(), &[])?; @@ -230,17 +232,16 @@ pub fn handle_role_deletions(node: &ComputeNode, client: &mut Client) -> Result< fn reassign_owned_objects(node: &ComputeNode, role_name: &PgIdent) -> Result<()> { for db in &node.spec.cluster.databases { if db.owner != *role_name { - let mut connstr = node.connstr.clone(); - // database name is always the last and the only component of the path - connstr.set_path(&db.name); + let mut conf = Config::from_str(node.connstr.as_str())?; + conf.dbname(&db.name); - let mut client = Client::connect(connstr.as_str(), NoTls)?; + let mut client = conf.connect(NoTls)?; // This will reassign all dependent objects to the db owner let reassign_query = format!( "REASSIGN OWNED BY {} TO {}", - role_name.quote(), - db.owner.quote() + role_name.pg_quote(), + db.owner.pg_quote() ); info!( "reassigning objects owned by '{}' in db '{}' to '{}'", @@ -249,7 +250,7 @@ fn reassign_owned_objects(node: &ComputeNode, role_name: &PgIdent) -> Result<()> client.simple_query(&reassign_query)?; // This now will only drop privileges of the role - let drop_query = format!("DROP OWNED BY {}", role_name.quote()); + let drop_query = format!("DROP OWNED BY {}", role_name.pg_quote()); client.simple_query(&drop_query)?; } } @@ -279,7 +280,7 @@ pub fn handle_databases(spec: &ComputeSpec, client: &mut Client) -> Result<()> { // We do not check either DB exists or not, // Postgres will take care of it for us "delete_db" => { - let query: String = format!("DROP DATABASE IF EXISTS {}", &op.name.quote()); + let query: String = format!("DROP DATABASE IF EXISTS {}", &op.name.pg_quote()); warn!("deleting database '{}'", &op.name); client.execute(query.as_str(), &[])?; @@ -291,8 +292,8 @@ pub fn handle_databases(spec: &ComputeSpec, client: &mut Client) -> Result<()> { if existing_dbs.iter().any(|r| r.name == op.name) { let query: String = format!( "ALTER DATABASE {} RENAME TO {}", - op.name.quote(), - new_name.quote() + op.name.pg_quote(), + new_name.pg_quote() ); warn!("renaming database '{}' to '{}'", op.name, new_name); @@ -320,7 +321,7 @@ pub fn handle_databases(spec: &ComputeSpec, client: &mut Client) -> Result<()> { // XXX: db owner name is returned as quoted string from Postgres, // when quoting is needed. let new_owner = if r.owner.starts_with('"') { - db.owner.quote() + db.owner.pg_quote() } else { db.owner.clone() }; @@ -328,15 +329,15 @@ pub fn handle_databases(spec: &ComputeSpec, client: &mut Client) -> Result<()> { if new_owner != r.owner { let query: String = format!( "ALTER DATABASE {} OWNER TO {}", - name.quote(), - db.owner.quote() + name.pg_quote(), + db.owner.pg_quote() ); info_print!(" -> update"); client.execute(query.as_str(), &[])?; } } else { - let mut query: String = format!("CREATE DATABASE {} ", name.quote()); + let mut query: String = format!("CREATE DATABASE {} ", name.pg_quote()); info_print!(" -> create"); query.push_str(&db.to_pg_options()); @@ -366,7 +367,7 @@ pub fn handle_grants(node: &ComputeNode, client: &mut Client) -> Result<()> { .cluster .roles .iter() - .map(|r| r.name.quote()) + .map(|r| r.name.pg_quote()) .collect::>(); for db in &spec.cluster.databases { @@ -374,7 +375,7 @@ pub fn handle_grants(node: &ComputeNode, client: &mut Client) -> Result<()> { let query: String = format!( "GRANT CREATE ON DATABASE {} TO {}", - dbname.quote(), + dbname.pg_quote(), roles.join(", ") ); info!("grant query {}", &query); @@ -385,12 +386,11 @@ pub fn handle_grants(node: &ComputeNode, client: &mut Client) -> Result<()> { // Do some per-database access adjustments. We'd better do this at db creation time, // but CREATE DATABASE isn't transactional. So we cannot create db + do some grants // atomically. - let mut db_connstr = node.connstr.clone(); for db in &node.spec.cluster.databases { - // database name is always the last and the only component of the path - db_connstr.set_path(&db.name); + let mut conf = Config::from_str(node.connstr.as_str())?; + conf.dbname(&db.name); - let mut db_client = Client::connect(db_connstr.as_str(), NoTls)?; + let mut db_client = conf.connect(NoTls)?; // This will only change ownership on the schema itself, not the objects // inside it. Without it owner of the `public` schema will be `cloud_admin` @@ -419,9 +419,15 @@ pub fn handle_grants(node: &ComputeNode, client: &mut Client) -> Result<()> { END IF;\n\ END\n\ $$;", - db.owner.quote() + db.owner.pg_quote() ); db_client.simple_query(&alter_query)?; + + // Explicitly grant CREATE ON SCHEMA PUBLIC to the web_access user. + // This is needed since postgres 15, where this privilege is removed by default. + let grant_query: String = "GRANT CREATE ON SCHEMA public TO web_access".to_string(); + info!("grant query for db {} : {}", &db.name, &grant_query); + db_client.simple_query(&grant_query)?; } Ok(()) diff --git a/compute_tools/tests/pg_helpers_tests.rs b/compute_tools/tests/pg_helpers_tests.rs index bae944440e..24cad4663a 100644 --- a/compute_tools/tests/pg_helpers_tests.rs +++ b/compute_tools/tests/pg_helpers_tests.rs @@ -33,9 +33,9 @@ mod pg_helpers_tests { } #[test] - fn quote_ident() { + fn ident_pg_quote() { let ident: PgIdent = PgIdent::from("\"name\";\\n select 1;"); - assert_eq!(ident.quote(), "\"\"\"name\"\";\\n select 1;\""); + assert_eq!(ident.pg_quote(), "\"\"\"name\"\";\\n select 1;\""); } } diff --git a/control_plane/Cargo.toml b/control_plane/Cargo.toml index ee8481e141..287385c709 100644 --- a/control_plane/Cargo.toml +++ b/control_plane/Cargo.toml @@ -4,19 +4,19 @@ version = "0.1.0" edition = "2021" [dependencies] -clap = "3.0" -comfy-table = "5.0.1" +clap = "4.0" +comfy-table = "6.1" git-version = "0.3.5" tar = "0.4.38" -postgres = { git = "https://github.com/neondatabase/rust-postgres.git", rev="d052ee8b86fff9897c77b0fe89ea9daba0e1fa38" } +postgres = { git = "https://github.com/neondatabase/rust-postgres.git", rev = "d052ee8b86fff9897c77b0fe89ea9daba0e1fa38" } serde = { version = "1.0", features = ["derive"] } -serde_with = "1.12.0" +serde_with = "2.0" toml = "0.5" once_cell = "1.13.0" regex = "1" anyhow = "1.0" thiserror = "1" -nix = "0.23" +nix = "0.25" reqwest = { version = "0.11", default-features = false, features = ["blocking", "json", "rustls-tls"] } # Note: Do not directly depend on pageserver or safekeeper; use pageserver_api or safekeeper_api diff --git a/control_plane/src/bin/neon_local.rs b/control_plane/src/bin/neon_local.rs index 0c26842b34..70a2c97a9e 100644 --- a/control_plane/src/bin/neon_local.rs +++ b/control_plane/src/bin/neon_local.rs @@ -6,7 +6,7 @@ //! rely on `neon_local` to set up the environment for each test. //! use anyhow::{anyhow, bail, Context, Result}; -use clap::{App, AppSettings, Arg, ArgMatches}; +use clap::{value_parser, Arg, ArgAction, ArgMatches, Command}; use control_plane::compute::ComputeControlPlane; use control_plane::local_env::{EtcdBroker, LocalEnv}; use control_plane::safekeeper::SafekeeperNode; @@ -85,212 +85,7 @@ struct TimelineTreeEl { // * Providing CLI api to the pageserver // * TODO: export/import to/from usual postgres fn main() -> Result<()> { - let branch_name_arg = Arg::new("branch-name") - .long("branch-name") - .takes_value(true) - .help("Name of the branch to be created or used as an alias for other services") - .required(false); - - let pg_node_arg = Arg::new("node").help("Postgres node name").required(false); - - let safekeeper_id_arg = Arg::new("id").help("safekeeper id").required(false); - - let tenant_id_arg = Arg::new("tenant-id") - .long("tenant-id") - .help("Tenant id. Represented as a hexadecimal string 32 symbols length") - .takes_value(true) - .required(false); - - let timeline_id_arg = Arg::new("timeline-id") - .long("timeline-id") - .help("Timeline id. Represented as a hexadecimal string 32 symbols length") - .takes_value(true) - .required(false); - - let pg_version_arg = Arg::new("pg-version") - .long("pg-version") - .help("Postgres version to use for the initial tenant") - .required(false) - .takes_value(true) - .default_value(DEFAULT_PG_VERSION); - - let port_arg = Arg::new("port") - .long("port") - .required(false) - .value_name("port"); - - let stop_mode_arg = Arg::new("stop-mode") - .short('m') - .takes_value(true) - .possible_values(&["fast", "immediate"]) - .help("If 'immediate', don't flush repository data at shutdown") - .required(false) - .value_name("stop-mode"); - - let pageserver_config_args = Arg::new("pageserver-config-override") - .long("pageserver-config-override") - .takes_value(true) - .number_of_values(1) - .multiple_occurrences(true) - .help("Additional pageserver's configuration options or overrides, refer to pageserver's 'config-override' CLI parameter docs for more") - .required(false); - - let lsn_arg = Arg::new("lsn") - .long("lsn") - .help("Specify Lsn on the timeline to start from. By default, end of the timeline would be used.") - .takes_value(true) - .required(false); - - let matches = App::new("Neon CLI") - .setting(AppSettings::ArgRequiredElseHelp) - .version(GIT_VERSION) - .subcommand( - App::new("init") - .about("Initialize a new Neon repository") - .arg(pageserver_config_args.clone()) - .arg(timeline_id_arg.clone().help("Use a specific timeline id when creating a tenant and its initial timeline")) - .arg( - Arg::new("config") - .long("config") - .required(false) - .value_name("config"), - ) - .arg(pg_version_arg.clone()) - ) - .subcommand( - App::new("timeline") - .about("Manage timelines") - .subcommand(App::new("list") - .about("List all timelines, available to this pageserver") - .arg(tenant_id_arg.clone())) - .subcommand(App::new("branch") - .about("Create a new timeline, using another timeline as a base, copying its data") - .arg(tenant_id_arg.clone()) - .arg(branch_name_arg.clone()) - .arg(Arg::new("ancestor-branch-name").long("ancestor-branch-name").takes_value(true) - .help("Use last Lsn of another timeline (and its data) as base when creating the new timeline. The timeline gets resolved by its branch name.").required(false)) - .arg(Arg::new("ancestor-start-lsn").long("ancestor-start-lsn").takes_value(true) - .help("When using another timeline as base, use a specific Lsn in it instead of the latest one").required(false))) - .subcommand(App::new("create") - .about("Create a new blank timeline") - .arg(tenant_id_arg.clone()) - .arg(branch_name_arg.clone()) - .arg(pg_version_arg.clone()) - ) - .subcommand(App::new("import") - .about("Import timeline from basebackup directory") - .arg(tenant_id_arg.clone()) - .arg(timeline_id_arg.clone()) - .arg(Arg::new("node-name").long("node-name").takes_value(true) - .help("Name to assign to the imported timeline")) - .arg(Arg::new("base-tarfile").long("base-tarfile").takes_value(true) - .help("Basebackup tarfile to import")) - .arg(Arg::new("base-lsn").long("base-lsn").takes_value(true) - .help("Lsn the basebackup starts at")) - .arg(Arg::new("wal-tarfile").long("wal-tarfile").takes_value(true) - .help("Wal to add after base")) - .arg(Arg::new("end-lsn").long("end-lsn").takes_value(true) - .help("Lsn the basebackup ends at")) - .arg(pg_version_arg.clone()) - ) - ).subcommand( - App::new("tenant") - .setting(AppSettings::ArgRequiredElseHelp) - .about("Manage tenants") - .subcommand(App::new("list")) - .subcommand(App::new("create") - .arg(tenant_id_arg.clone()) - .arg(timeline_id_arg.clone().help("Use a specific timeline id when creating a tenant and its initial timeline")) - .arg(Arg::new("config").short('c').takes_value(true).multiple_occurrences(true).required(false)) - .arg(pg_version_arg.clone()) - ) - .subcommand(App::new("config") - .arg(tenant_id_arg.clone()) - .arg(Arg::new("config").short('c').takes_value(true).multiple_occurrences(true).required(false)) - ) - ) - .subcommand( - App::new("pageserver") - .setting(AppSettings::ArgRequiredElseHelp) - .about("Manage pageserver") - .subcommand(App::new("status")) - .subcommand(App::new("start").about("Start local pageserver").arg(pageserver_config_args.clone())) - .subcommand(App::new("stop").about("Stop local pageserver") - .arg(stop_mode_arg.clone())) - .subcommand(App::new("restart").about("Restart local pageserver").arg(pageserver_config_args.clone())) - ) - .subcommand( - App::new("safekeeper") - .setting(AppSettings::ArgRequiredElseHelp) - .about("Manage safekeepers") - .subcommand(App::new("start") - .about("Start local safekeeper") - .arg(safekeeper_id_arg.clone()) - ) - .subcommand(App::new("stop") - .about("Stop local safekeeper") - .arg(safekeeper_id_arg.clone()) - .arg(stop_mode_arg.clone()) - ) - .subcommand(App::new("restart") - .about("Restart local safekeeper") - .arg(safekeeper_id_arg.clone()) - .arg(stop_mode_arg.clone()) - ) - ) - .subcommand( - App::new("pg") - .setting(AppSettings::ArgRequiredElseHelp) - .about("Manage postgres instances") - .subcommand(App::new("list").arg(tenant_id_arg.clone())) - .subcommand(App::new("create") - .about("Create a postgres compute node") - .arg(pg_node_arg.clone()) - .arg(branch_name_arg.clone()) - .arg(tenant_id_arg.clone()) - .arg(lsn_arg.clone()) - .arg(port_arg.clone()) - .arg( - Arg::new("config-only") - .help("Don't do basebackup, create compute node with only config files") - .long("config-only") - .required(false)) - .arg(pg_version_arg.clone()) - ) - .subcommand(App::new("start") - .about("Start a postgres compute node.\n This command actually creates new node from scratch, but preserves existing config files") - .arg(pg_node_arg.clone()) - .arg(tenant_id_arg.clone()) - .arg(branch_name_arg.clone()) - .arg(timeline_id_arg.clone()) - .arg(lsn_arg.clone()) - .arg(port_arg.clone()) - .arg(pg_version_arg.clone()) - ) - .subcommand( - App::new("stop") - .arg(pg_node_arg.clone()) - .arg(tenant_id_arg.clone()) - .arg( - Arg::new("destroy") - .help("Also delete data directory (now optional, should be default in future)") - .long("destroy") - .required(false) - ) - ) - - ) - .subcommand( - App::new("start") - .about("Start page server and safekeepers") - .arg(pageserver_config_args) - ) - .subcommand( - App::new("stop") - .about("Stop page server and safekeepers") - .arg(stop_mode_arg.clone()) - ) - .get_matches(); + let matches = cli().get_matches(); let (sub_name, sub_args) = match matches.subcommand() { Some(subcommand_data) => subcommand_data, @@ -358,9 +153,7 @@ fn print_timelines_tree( // Memorize all direct children of each timeline. for timeline in timelines.iter() { - if let Some(ancestor_timeline_id) = - timeline.local.as_ref().and_then(|l| l.ancestor_timeline_id) - { + if let Some(ancestor_timeline_id) = timeline.ancestor_timeline_id { timelines_hash .get_mut(&ancestor_timeline_id) .context("missing timeline info in the HashMap")? @@ -371,13 +164,7 @@ fn print_timelines_tree( for timeline in timelines_hash.values() { // Start with root local timelines (no ancestors) first. - if timeline - .info - .local - .as_ref() - .and_then(|l| l.ancestor_timeline_id) - .is_none() - { + if timeline.info.ancestor_timeline_id.is_none() { print_timeline(0, &Vec::from([true]), timeline, &timelines_hash)?; } } @@ -394,17 +181,8 @@ fn print_timeline( timeline: &TimelineTreeEl, timelines: &HashMap, ) -> Result<()> { - let local_remote = match (timeline.info.local.as_ref(), timeline.info.remote.as_ref()) { - (None, None) => unreachable!("in this case no info for a timeline is found"), - (None, Some(_)) => "(R)", - (Some(_), None) => "(L)", - (Some(_), Some(_)) => "(L+R)", - }; - // Draw main padding - print!("{} ", local_remote); - if nesting_level > 0 { - let ancestor_lsn = match timeline.info.local.as_ref().and_then(|i| i.ancestor_lsn) { + let ancestor_lsn = match timeline.info.ancestor_lsn { Some(lsn) => lsn.to_string(), None => "Unknown Lsn".to_string(), }; @@ -492,16 +270,16 @@ fn get_tenant_id(sub_match: &ArgMatches, env: &local_env::LocalEnv) -> anyhow::R fn parse_tenant_id(sub_match: &ArgMatches) -> anyhow::Result> { sub_match - .value_of("tenant-id") - .map(TenantId::from_str) + .get_one::("tenant-id") + .map(|tenant_id| TenantId::from_str(tenant_id)) .transpose() .context("Failed to parse tenant id from the argument string") } fn parse_timeline_id(sub_match: &ArgMatches) -> anyhow::Result> { sub_match - .value_of("timeline-id") - .map(TimelineId::from_str) + .get_one::("timeline-id") + .map(|timeline_id| TimelineId::from_str(timeline_id)) .transpose() .context("Failed to parse timeline id from the argument string") } @@ -510,19 +288,22 @@ fn handle_init(init_match: &ArgMatches) -> anyhow::Result { let initial_timeline_id_arg = parse_timeline_id(init_match)?; // Create config file - let toml_file: String = if let Some(config_path) = init_match.value_of("config") { + let toml_file: String = if let Some(config_path) = init_match.get_one::("config") { // load and parse the file - std::fs::read_to_string(std::path::Path::new(config_path)) - .with_context(|| format!("Could not read configuration file '{config_path}'"))? + std::fs::read_to_string(config_path).with_context(|| { + format!( + "Could not read configuration file '{}'", + config_path.display() + ) + })? } else { // Built-in default config default_conf(&EtcdBroker::locate_etcd()?) }; let pg_version = init_match - .value_of("pg-version") - .unwrap() - .parse::() + .get_one::("pg-version") + .copied() .context("Failed to parse postgres version from the argument string")?; let mut env = @@ -558,9 +339,10 @@ fn handle_init(init_match: &ArgMatches) -> anyhow::Result { fn pageserver_config_overrides(init_match: &ArgMatches) -> Vec<&str> { init_match - .values_of("pageserver-config-override") + .get_many::("pageserver-config-override") .into_iter() .flatten() + .map(|s| s.as_str()) .collect() } @@ -575,7 +357,7 @@ fn handle_tenant(tenant_match: &ArgMatches, env: &mut local_env::LocalEnv) -> an Some(("create", create_match)) => { let initial_tenant_id = parse_tenant_id(create_match)?; let tenant_conf: HashMap<_, _> = create_match - .values_of("config") + .get_many::("config") .map(|vals| vals.flat_map(|c| c.split_once(':')).collect()) .unwrap_or_default(); let new_tenant_id = pageserver.tenant_create(initial_tenant_id, tenant_conf)?; @@ -584,9 +366,8 @@ fn handle_tenant(tenant_match: &ArgMatches, env: &mut local_env::LocalEnv) -> an // Create an initial timeline for the new tenant let new_timeline_id = parse_timeline_id(create_match)?; let pg_version = create_match - .value_of("pg-version") - .unwrap() - .parse::() + .get_one::("pg-version") + .copied() .context("Failed to parse postgres version from the argument string")?; let timeline_info = pageserver.timeline_create( @@ -597,10 +378,7 @@ fn handle_tenant(tenant_match: &ArgMatches, env: &mut local_env::LocalEnv) -> an Some(pg_version), )?; let new_timeline_id = timeline_info.timeline_id; - let last_record_lsn = timeline_info - .local - .context(format!("Failed to get last record LSN: no local timeline info for timeline {new_timeline_id}"))? - .last_record_lsn; + let last_record_lsn = timeline_info.last_record_lsn; env.register_branch_mapping( DEFAULT_BRANCH_NAME.to_string(), @@ -615,7 +393,7 @@ fn handle_tenant(tenant_match: &ArgMatches, env: &mut local_env::LocalEnv) -> an Some(("config", create_match)) => { let tenant_id = get_tenant_id(create_match, env)?; let tenant_conf: HashMap<_, _> = create_match - .values_of("config") + .get_many::("config") .map(|vals| vals.flat_map(|c| c.split_once(':')).collect()) .unwrap_or_default(); @@ -642,23 +420,19 @@ fn handle_timeline(timeline_match: &ArgMatches, env: &mut local_env::LocalEnv) - Some(("create", create_match)) => { let tenant_id = get_tenant_id(create_match, env)?; let new_branch_name = create_match - .value_of("branch-name") + .get_one::("branch-name") .ok_or_else(|| anyhow!("No branch name provided"))?; let pg_version = create_match - .value_of("pg-version") - .unwrap() - .parse::() + .get_one::("pg-version") + .copied() .context("Failed to parse postgres version from the argument string")?; let timeline_info = pageserver.timeline_create(tenant_id, None, None, None, Some(pg_version))?; let new_timeline_id = timeline_info.timeline_id; - let last_record_lsn = timeline_info - .local - .expect("no local timeline info") - .last_record_lsn; + let last_record_lsn = timeline_info.last_record_lsn; env.register_branch_mapping(new_branch_name.to_string(), tenant_id, new_timeline_id)?; println!( @@ -670,35 +444,32 @@ fn handle_timeline(timeline_match: &ArgMatches, env: &mut local_env::LocalEnv) - let tenant_id = get_tenant_id(import_match, env)?; let timeline_id = parse_timeline_id(import_match)?.expect("No timeline id provided"); let name = import_match - .value_of("node-name") + .get_one::("node-name") .ok_or_else(|| anyhow!("No node name provided"))?; // Parse base inputs let base_tarfile = import_match - .value_of("base-tarfile") - .map(|s| PathBuf::from_str(s).unwrap()) - .ok_or_else(|| anyhow!("No base-tarfile provided"))?; + .get_one::("base-tarfile") + .ok_or_else(|| anyhow!("No base-tarfile provided"))? + .to_owned(); let base_lsn = Lsn::from_str( import_match - .value_of("base-lsn") + .get_one::("base-lsn") .ok_or_else(|| anyhow!("No base-lsn provided"))?, )?; let base = (base_lsn, base_tarfile); // Parse pg_wal inputs - let wal_tarfile = import_match - .value_of("wal-tarfile") - .map(|s| PathBuf::from_str(s).unwrap()); + let wal_tarfile = import_match.get_one::("wal-tarfile").cloned(); let end_lsn = import_match - .value_of("end-lsn") + .get_one::("end-lsn") .map(|s| Lsn::from_str(s).unwrap()); // TODO validate both or none are provided let pg_wal = end_lsn.zip(wal_tarfile); let pg_version = import_match - .value_of("pg-version") - .unwrap() - .parse::() + .get_one::("pg-version") + .copied() .context("Failed to parse postgres version from the argument string")?; let mut cplane = ComputeControlPlane::load(env.clone())?; @@ -713,10 +484,11 @@ fn handle_timeline(timeline_match: &ArgMatches, env: &mut local_env::LocalEnv) - Some(("branch", branch_match)) => { let tenant_id = get_tenant_id(branch_match, env)?; let new_branch_name = branch_match - .value_of("branch-name") + .get_one::("branch-name") .ok_or_else(|| anyhow!("No branch name provided"))?; let ancestor_branch_name = branch_match - .value_of("ancestor-branch-name") + .get_one::("ancestor-branch-name") + .map(|s| s.as_str()) .unwrap_or(DEFAULT_BRANCH_NAME); let ancestor_timeline_id = env .get_branch_timeline_id(ancestor_branch_name, tenant_id) @@ -725,8 +497,8 @@ fn handle_timeline(timeline_match: &ArgMatches, env: &mut local_env::LocalEnv) - })?; let start_lsn = branch_match - .value_of("ancestor-start-lsn") - .map(Lsn::from_str) + .get_one::("ancestor-start-lsn") + .map(|lsn_str| Lsn::from_str(lsn_str)) .transpose() .context("Failed to parse ancestor start Lsn from the request")?; let timeline_info = pageserver.timeline_create( @@ -738,10 +510,7 @@ fn handle_timeline(timeline_match: &ArgMatches, env: &mut local_env::LocalEnv) - )?; let new_timeline_id = timeline_info.timeline_id; - let last_record_lsn = timeline_info - .local - .expect("no local timeline info") - .last_record_lsn; + let last_record_lsn = timeline_info.last_record_lsn; env.register_branch_mapping(new_branch_name.to_string(), tenant_id, new_timeline_id)?; @@ -801,7 +570,7 @@ fn handle_pg(pg_match: &ArgMatches, env: &local_env::LocalEnv) -> Result<()> { // Use the LSN at the end of the timeline. timeline_infos .get(&node.timeline_id) - .and_then(|bi| bi.local.as_ref().map(|l| l.last_record_lsn.to_string())) + .map(|bi| bi.last_record_lsn.to_string()) .unwrap_or_else(|| "?".to_string()) } Some(lsn) => { @@ -830,45 +599,39 @@ fn handle_pg(pg_match: &ArgMatches, env: &local_env::LocalEnv) -> Result<()> { } "create" => { let branch_name = sub_args - .value_of("branch-name") + .get_one::("branch-name") + .map(|s| s.as_str()) .unwrap_or(DEFAULT_BRANCH_NAME); let node_name = sub_args - .value_of("node") - .map(ToString::to_string) - .unwrap_or_else(|| format!("{}_node", branch_name)); + .get_one::("node") + .map(|node_name| node_name.to_string()) + .unwrap_or_else(|| format!("{branch_name}_node")); let lsn = sub_args - .value_of("lsn") - .map(Lsn::from_str) + .get_one::("lsn") + .map(|lsn_str| Lsn::from_str(lsn_str)) .transpose() .context("Failed to parse Lsn from the request")?; let timeline_id = env .get_branch_timeline_id(branch_name, tenant_id) - .ok_or_else(|| anyhow!("Found no timeline id for branch name '{}'", branch_name))?; + .ok_or_else(|| anyhow!("Found no timeline id for branch name '{branch_name}'"))?; - let port: Option = match sub_args.value_of("port") { - Some(p) => Some(p.parse()?), - None => None, - }; + let port: Option = sub_args.get_one::("port").copied(); let pg_version = sub_args - .value_of("pg-version") - .unwrap() - .parse::() + .get_one::("pg-version") + .copied() .context("Failed to parse postgres version from the argument string")?; cplane.new_node(tenant_id, &node_name, timeline_id, lsn, port, pg_version)?; } "start" => { - let port: Option = match sub_args.value_of("port") { - Some(p) => Some(p.parse()?), - None => None, - }; + let port: Option = sub_args.get_one::("port").copied(); let node_name = sub_args - .value_of("node") + .get_one::("node") .ok_or_else(|| anyhow!("No node name was provided to start"))?; - let node = cplane.nodes.get(&(tenant_id, node_name.to_owned())); + let node = cplane.nodes.get(&(tenant_id, node_name.to_string())); let auth_token = if matches!(env.pageserver.auth_type, AuthType::NeonJWT) { let claims = Claims::new(Some(tenant_id), Scope::Tenant); @@ -879,36 +642,33 @@ fn handle_pg(pg_match: &ArgMatches, env: &local_env::LocalEnv) -> Result<()> { }; if let Some(node) = node { - println!("Starting existing postgres {}...", node_name); + println!("Starting existing postgres {node_name}..."); node.start(&auth_token)?; } else { let branch_name = sub_args - .value_of("branch-name") + .get_one::("branch-name") + .map(|s| s.as_str()) .unwrap_or(DEFAULT_BRANCH_NAME); let timeline_id = env .get_branch_timeline_id(branch_name, tenant_id) .ok_or_else(|| { - anyhow!("Found no timeline id for branch name '{}'", branch_name) + anyhow!("Found no timeline id for branch name '{branch_name}'") })?; let lsn = sub_args - .value_of("lsn") - .map(Lsn::from_str) + .get_one::("lsn") + .map(|lsn_str| Lsn::from_str(lsn_str)) .transpose() .context("Failed to parse Lsn from the request")?; let pg_version = sub_args - .value_of("pg-version") - .unwrap() - .parse::() - .context("Failed to parse postgres version from the argument string")?; + .get_one::("pg-version") + .copied() + .context("Failed to `pg-version` from the argument string")?; // when used with custom port this results in non obvious behaviour // port is remembered from first start command, i e // start --port X // stop // start <-- will also use port X even without explicit port argument - println!( - "Starting new postgres (v{}) {} on timeline {} ...", - pg_version, node_name, timeline_id - ); + println!("Starting new postgres (v{pg_version}) {node_name} on timeline {timeline_id} ..."); let node = cplane.new_node(tenant_id, node_name, timeline_id, lsn, port, pg_version)?; @@ -917,18 +677,18 @@ fn handle_pg(pg_match: &ArgMatches, env: &local_env::LocalEnv) -> Result<()> { } "stop" => { let node_name = sub_args - .value_of("node") + .get_one::("node") .ok_or_else(|| anyhow!("No node name was provided to stop"))?; - let destroy = sub_args.is_present("destroy"); + let destroy = sub_args.get_flag("destroy"); let node = cplane .nodes - .get(&(tenant_id, node_name.to_owned())) - .with_context(|| format!("postgres {} is not found", node_name))?; + .get(&(tenant_id, node_name.to_string())) + .with_context(|| format!("postgres {node_name} is not found"))?; node.stop(destroy)?; } - _ => bail!("Unexpected pg subcommand '{}'", sub_name), + _ => bail!("Unexpected pg subcommand '{sub_name}'"), } Ok(()) @@ -946,7 +706,10 @@ fn handle_pageserver(sub_match: &ArgMatches, env: &local_env::LocalEnv) -> Resul } Some(("stop", stop_match)) => { - let immediate = stop_match.value_of("stop-mode") == Some("immediate"); + let immediate = stop_match + .get_one::("stop-mode") + .map(|s| s.as_str()) + == Some("immediate"); if let Err(e) = pageserver.stop(immediate) { eprintln!("pageserver stop failed: {}", e); @@ -996,7 +759,7 @@ fn handle_safekeeper(sub_match: &ArgMatches, env: &local_env::LocalEnv) -> Resul }; // All the commands take an optional safekeeper name argument - let sk_id = if let Some(id_str) = sub_args.value_of("id") { + let sk_id = if let Some(id_str) = sub_args.get_one::("id") { NodeId(id_str.parse().context("while parsing safekeeper id")?) } else { DEFAULT_SAFEKEEPER_ID @@ -1012,7 +775,8 @@ fn handle_safekeeper(sub_match: &ArgMatches, env: &local_env::LocalEnv) -> Resul } "stop" => { - let immediate = sub_args.value_of("stop-mode") == Some("immediate"); + let immediate = + sub_args.get_one::("stop-mode").map(|s| s.as_str()) == Some("immediate"); if let Err(e) = safekeeper.stop(immediate) { eprintln!("safekeeper stop failed: {}", e); @@ -1021,7 +785,8 @@ fn handle_safekeeper(sub_match: &ArgMatches, env: &local_env::LocalEnv) -> Resul } "restart" => { - let immediate = sub_args.value_of("stop-mode") == Some("immediate"); + let immediate = + sub_args.get_one::("stop-mode").map(|s| s.as_str()) == Some("immediate"); if let Err(e) = safekeeper.stop(immediate) { eprintln!("safekeeper stop failed: {}", e); @@ -1065,7 +830,8 @@ fn handle_start_all(sub_match: &ArgMatches, env: &local_env::LocalEnv) -> anyhow } fn handle_stop_all(sub_match: &ArgMatches, env: &local_env::LocalEnv) -> Result<()> { - let immediate = sub_match.value_of("stop-mode") == Some("immediate"); + let immediate = + sub_match.get_one::("stop-mode").map(|s| s.as_str()) == Some("immediate"); let pageserver = PageServerNode::from_env(env); @@ -1098,3 +864,219 @@ fn try_stop_etcd_process(env: &local_env::LocalEnv) { eprintln!("etcd stop failed: {e}"); } } + +fn cli() -> Command { + let branch_name_arg = Arg::new("branch-name") + .long("branch-name") + .help("Name of the branch to be created or used as an alias for other services") + .required(false); + + let pg_node_arg = Arg::new("node").help("Postgres node name").required(false); + + let safekeeper_id_arg = Arg::new("id").help("safekeeper id").required(false); + + let tenant_id_arg = Arg::new("tenant-id") + .long("tenant-id") + .help("Tenant id. Represented as a hexadecimal string 32 symbols length") + .required(false); + + let timeline_id_arg = Arg::new("timeline-id") + .long("timeline-id") + .help("Timeline id. Represented as a hexadecimal string 32 symbols length") + .required(false); + + let pg_version_arg = Arg::new("pg-version") + .long("pg-version") + .help("Postgres version to use for the initial tenant") + .required(false) + .value_parser(value_parser!(u32)) + .default_value(DEFAULT_PG_VERSION); + + let port_arg = Arg::new("port") + .long("port") + .required(false) + .value_parser(value_parser!(u16)) + .value_name("port"); + + let stop_mode_arg = Arg::new("stop-mode") + .short('m') + .value_parser(["fast", "immediate"]) + .help("If 'immediate', don't flush repository data at shutdown") + .required(false) + .value_name("stop-mode"); + + let pageserver_config_args = Arg::new("pageserver-config-override") + .long("pageserver-config-override") + .num_args(1) + .action(ArgAction::Append) + .help("Additional pageserver's configuration options or overrides, refer to pageserver's 'config-override' CLI parameter docs for more") + .required(false); + + let lsn_arg = Arg::new("lsn") + .long("lsn") + .help("Specify Lsn on the timeline to start from. By default, end of the timeline would be used.") + .required(false); + + Command::new("Neon CLI") + .arg_required_else_help(true) + .version(GIT_VERSION) + .subcommand( + Command::new("init") + .about("Initialize a new Neon repository") + .arg(pageserver_config_args.clone()) + .arg(timeline_id_arg.clone().help("Use a specific timeline id when creating a tenant and its initial timeline")) + .arg( + Arg::new("config") + .long("config") + .required(false) + .value_parser(value_parser!(PathBuf)) + .value_name("config"), + ) + .arg(pg_version_arg.clone()) + ) + .subcommand( + Command::new("timeline") + .about("Manage timelines") + .subcommand(Command::new("list") + .about("List all timelines, available to this pageserver") + .arg(tenant_id_arg.clone())) + .subcommand(Command::new("branch") + .about("Create a new timeline, using another timeline as a base, copying its data") + .arg(tenant_id_arg.clone()) + .arg(branch_name_arg.clone()) + .arg(Arg::new("ancestor-branch-name").long("ancestor-branch-name") + .help("Use last Lsn of another timeline (and its data) as base when creating the new timeline. The timeline gets resolved by its branch name.").required(false)) + .arg(Arg::new("ancestor-start-lsn").long("ancestor-start-lsn") + .help("When using another timeline as base, use a specific Lsn in it instead of the latest one").required(false))) + .subcommand(Command::new("create") + .about("Create a new blank timeline") + .arg(tenant_id_arg.clone()) + .arg(branch_name_arg.clone()) + .arg(pg_version_arg.clone()) + ) + .subcommand(Command::new("import") + .about("Import timeline from basebackup directory") + .arg(tenant_id_arg.clone()) + .arg(timeline_id_arg.clone()) + .arg(Arg::new("node-name").long("node-name") + .help("Name to assign to the imported timeline")) + .arg(Arg::new("base-tarfile") + .long("base-tarfile") + .value_parser(value_parser!(PathBuf)) + .help("Basebackup tarfile to import") + ) + .arg(Arg::new("base-lsn").long("base-lsn") + .help("Lsn the basebackup starts at")) + .arg(Arg::new("wal-tarfile") + .long("wal-tarfile") + .value_parser(value_parser!(PathBuf)) + .help("Wal to add after base") + ) + .arg(Arg::new("end-lsn").long("end-lsn") + .help("Lsn the basebackup ends at")) + .arg(pg_version_arg.clone()) + ) + ).subcommand( + Command::new("tenant") + .arg_required_else_help(true) + .about("Manage tenants") + .subcommand(Command::new("list")) + .subcommand(Command::new("create") + .arg(tenant_id_arg.clone()) + .arg(timeline_id_arg.clone().help("Use a specific timeline id when creating a tenant and its initial timeline")) + .arg(Arg::new("config").short('c').num_args(1).action(ArgAction::Append).required(false)) + .arg(pg_version_arg.clone()) + ) + .subcommand(Command::new("config") + .arg(tenant_id_arg.clone()) + .arg(Arg::new("config").short('c').num_args(1).action(ArgAction::Append).required(false)) + ) + ) + .subcommand( + Command::new("pageserver") + .arg_required_else_help(true) + .about("Manage pageserver") + .subcommand(Command::new("status")) + .subcommand(Command::new("start").about("Start local pageserver").arg(pageserver_config_args.clone())) + .subcommand(Command::new("stop").about("Stop local pageserver") + .arg(stop_mode_arg.clone())) + .subcommand(Command::new("restart").about("Restart local pageserver").arg(pageserver_config_args.clone())) + ) + .subcommand( + Command::new("safekeeper") + .arg_required_else_help(true) + .about("Manage safekeepers") + .subcommand(Command::new("start") + .about("Start local safekeeper") + .arg(safekeeper_id_arg.clone()) + ) + .subcommand(Command::new("stop") + .about("Stop local safekeeper") + .arg(safekeeper_id_arg.clone()) + .arg(stop_mode_arg.clone()) + ) + .subcommand(Command::new("restart") + .about("Restart local safekeeper") + .arg(safekeeper_id_arg) + .arg(stop_mode_arg.clone()) + ) + ) + .subcommand( + Command::new("pg") + .arg_required_else_help(true) + .about("Manage postgres instances") + .subcommand(Command::new("list").arg(tenant_id_arg.clone())) + .subcommand(Command::new("create") + .about("Create a postgres compute node") + .arg(pg_node_arg.clone()) + .arg(branch_name_arg.clone()) + .arg(tenant_id_arg.clone()) + .arg(lsn_arg.clone()) + .arg(port_arg.clone()) + .arg( + Arg::new("config-only") + .help("Don't do basebackup, create compute node with only config files") + .long("config-only") + .required(false)) + .arg(pg_version_arg.clone()) + ) + .subcommand(Command::new("start") + .about("Start a postgres compute node.\n This command actually creates new node from scratch, but preserves existing config files") + .arg(pg_node_arg.clone()) + .arg(tenant_id_arg.clone()) + .arg(branch_name_arg) + .arg(timeline_id_arg) + .arg(lsn_arg) + .arg(port_arg) + .arg(pg_version_arg) + ) + .subcommand( + Command::new("stop") + .arg(pg_node_arg) + .arg(tenant_id_arg) + .arg( + Arg::new("destroy") + .help("Also delete data directory (now optional, should be default in future)") + .long("destroy") + .action(ArgAction::SetTrue) + .required(false) + ) + ) + + ) + .subcommand( + Command::new("start") + .about("Start page server and safekeepers") + .arg(pageserver_config_args) + ) + .subcommand( + Command::new("stop") + .about("Stop page server and safekeepers") + .arg(stop_mode_arg) + ) +} + +#[test] +fn verify_cli() { + cli().debug_assert(); +} diff --git a/control_plane/src/compute.rs b/control_plane/src/compute.rs index 89994c5647..9f32ad31c1 100644 --- a/control_plane/src/compute.rs +++ b/control_plane/src/compute.rs @@ -183,18 +183,18 @@ impl PostgresNode { } fn sync_safekeepers(&self, auth_token: &Option, pg_version: u32) -> Result { - let pg_path = self.env.pg_bin_dir(pg_version).join("postgres"); + let pg_path = self.env.pg_bin_dir(pg_version)?.join("postgres"); let mut cmd = Command::new(&pg_path); cmd.arg("--sync-safekeepers") .env_clear() .env( "LD_LIBRARY_PATH", - self.env.pg_lib_dir(pg_version).to_str().unwrap(), + self.env.pg_lib_dir(pg_version)?.to_str().unwrap(), ) .env( "DYLD_LIBRARY_PATH", - self.env.pg_lib_dir(pg_version).to_str().unwrap(), + self.env.pg_lib_dir(pg_version)?.to_str().unwrap(), ) .env("PGDATA", self.pgdata().to_str().unwrap()) .stdout(Stdio::piped()) @@ -422,7 +422,7 @@ impl PostgresNode { } fn pg_ctl(&self, args: &[&str], auth_token: &Option) -> Result<()> { - let pg_ctl_path = self.env.pg_bin_dir(self.pg_version).join("pg_ctl"); + let pg_ctl_path = self.env.pg_bin_dir(self.pg_version)?.join("pg_ctl"); let mut cmd = Command::new(pg_ctl_path); cmd.args( [ @@ -440,11 +440,11 @@ impl PostgresNode { .env_clear() .env( "LD_LIBRARY_PATH", - self.env.pg_lib_dir(self.pg_version).to_str().unwrap(), + self.env.pg_lib_dir(self.pg_version)?.to_str().unwrap(), ) .env( "DYLD_LIBRARY_PATH", - self.env.pg_lib_dir(self.pg_version).to_str().unwrap(), + self.env.pg_lib_dir(self.pg_version)?.to_str().unwrap(), ); if let Some(token) = auth_token { cmd.env("ZENITH_AUTH_TOKEN", token); diff --git a/control_plane/src/local_env.rs b/control_plane/src/local_env.rs index f4fbc99420..10b2db6396 100644 --- a/control_plane/src/local_env.rs +++ b/control_plane/src/local_env.rs @@ -201,28 +201,28 @@ impl LocalEnv { self.pg_distrib_dir.clone() } - pub fn pg_distrib_dir(&self, pg_version: u32) -> PathBuf { + pub fn pg_distrib_dir(&self, pg_version: u32) -> anyhow::Result { let path = self.pg_distrib_dir.clone(); match pg_version { - 14 => path.join(format!("v{pg_version}")), - 15 => path.join(format!("v{pg_version}")), - _ => panic!("Unsupported postgres version: {}", pg_version), + 14 => Ok(path.join(format!("v{pg_version}"))), + 15 => Ok(path.join(format!("v{pg_version}"))), + _ => bail!("Unsupported postgres version: {}", pg_version), } } - pub fn pg_bin_dir(&self, pg_version: u32) -> PathBuf { + pub fn pg_bin_dir(&self, pg_version: u32) -> anyhow::Result { match pg_version { - 14 => self.pg_distrib_dir(pg_version).join("bin"), - 15 => self.pg_distrib_dir(pg_version).join("bin"), - _ => panic!("Unsupported postgres version: {}", pg_version), + 14 => Ok(self.pg_distrib_dir(pg_version)?.join("bin")), + 15 => Ok(self.pg_distrib_dir(pg_version)?.join("bin")), + _ => bail!("Unsupported postgres version: {}", pg_version), } } - pub fn pg_lib_dir(&self, pg_version: u32) -> PathBuf { + pub fn pg_lib_dir(&self, pg_version: u32) -> anyhow::Result { match pg_version { - 14 => self.pg_distrib_dir(pg_version).join("lib"), - 15 => self.pg_distrib_dir(pg_version).join("lib"), - _ => panic!("Unsupported postgres version: {}", pg_version), + 14 => Ok(self.pg_distrib_dir(pg_version)?.join("lib")), + 15 => Ok(self.pg_distrib_dir(pg_version)?.join("lib")), + _ => bail!("Unsupported postgres version: {}", pg_version), } } @@ -422,10 +422,10 @@ impl LocalEnv { "directory '{}' already exists. Perhaps already initialized?", base_path.display() ); - if !self.pg_bin_dir(pg_version).join("postgres").exists() { + if !self.pg_bin_dir(pg_version)?.join("postgres").exists() { bail!( "Can't find postgres binary at {}", - self.pg_bin_dir(pg_version).display() + self.pg_bin_dir(pg_version)?.display() ); } for binary in ["pageserver", "safekeeper"] { diff --git a/control_plane/src/safekeeper.rs b/control_plane/src/safekeeper.rs index 34b2f3000a..64a89124d2 100644 --- a/control_plane/src/safekeeper.rs +++ b/control_plane/src/safekeeper.rs @@ -12,13 +12,8 @@ use nix::unistd::Pid; use postgres::Config; use reqwest::blocking::{Client, RequestBuilder, Response}; use reqwest::{IntoUrl, Method}; -use safekeeper_api::models::TimelineCreateRequest; use thiserror::Error; -use utils::{ - connstring::connection_address, - http::error::HttpErrorBody, - id::{NodeId, TenantId, TimelineId}, -}; +use utils::{connstring::connection_address, http::error::HttpErrorBody, id::NodeId}; use crate::local_env::{LocalEnv, SafekeeperConf}; use crate::storage::PageServerNode; @@ -281,24 +276,4 @@ impl SafekeeperNode { .error_from_body()?; Ok(()) } - - pub fn timeline_create( - &self, - tenant_id: TenantId, - timeline_id: TimelineId, - peer_ids: Vec, - ) -> Result<()> { - Ok(self - .http_request( - Method::POST, - format!("{}/tenant/{}/timeline", self.http_base_url, tenant_id), - ) - .json(&TimelineCreateRequest { - timeline_id, - peer_ids, - }) - .send()? - .error_from_body()? - .json()?) - } } diff --git a/docs/SUMMARY.md b/docs/SUMMARY.md index fb6467ffd5..faf2b2336f 100644 --- a/docs/SUMMARY.md +++ b/docs/SUMMARY.md @@ -80,4 +80,6 @@ - [015-storage-messaging](rfcs/015-storage-messaging.md) - [016-connection-routing](rfcs/016-connection-routing.md) - [017-timeline-data-management](rfcs/017-timeline-data-management.md) +- [018-storage-messaging-2](rfcs/018-storage-messaging-2.md) +- [019-tenant-timeline-lifecycles](rfcs/019-tenant-timeline-lifecycles.md) - [cluster-size-limits](rfcs/cluster-size-limits.md) diff --git a/docs/rfcs/018-storage-messaging-2.md b/docs/rfcs/018-storage-messaging-2.md new file mode 100644 index 0000000000..364f62dd2e --- /dev/null +++ b/docs/rfcs/018-storage-messaging-2.md @@ -0,0 +1,163 @@ +# Storage messaging + +Safekeepers need to communicate to each other to +* Trim WAL on safekeepers; +* Decide on which SK should push WAL to the S3; +* Decide on when to shut down SK<->pageserver connection; +* Understand state of each other to perform peer recovery; + +Pageservers need to communicate to safekeepers to decide which SK should provide +WAL to the pageserver. + +This is an iteration on [015-storage-messaging](https://github.com/neondatabase/neon/blob/main/docs/rfcs/015-storage-messaging.md) describing current situation, +potential performance issue and ways to address it. + +## Background + +What we have currently is very close to etcd variant described in +015-storage-messaging. Basically, we have single `SkTimelineInfo` message +periodically sent by all safekeepers to etcd for each timeline. +* Safekeepers subscribe to it to learn status of peers (currently they subscribe to + 'everything', but they can and should fetch data only for timelines they hold). +* Pageserver subscribes to it (separate watch per timeline) to learn safekeepers + positions; based on that, it decides from which safekeepers to pull WAL. + +Also, safekeepers use etcd elections API to make sure only single safekeeper +offloads WAL. + +It works, and callmemaybe is gone. However, this has a performance +hazard. Currently deployed etcd can do about 6k puts per second (using its own +`benchmark` tool); on my 6 core laptop, while running on tmpfs, this gets to +35k. Making benchmark closer to our usage [etcd watch bench](https://github.com/arssher/etcd-client/blob/watch-bench/examples/watch_bench.rs), +I get ~10k received messages per second with various number of publisher-subscribers +(laptop, tmpfs). Diving this by 12 (3 sks generate msg, 1 ps + 3 sk consume them) we +get about 800 active timelines, if message is sent each second. Not extremely +low, but quite reachable. + +A lot of idle watches seem to be ok though -- which is good, as pageserver +subscribes to all its timelines regardless of their activity. + +Also, running etcd with fsyncs disabled is messy -- data dir must be wiped on +each restart or there is a risk of corruption errors. + +The reason is etcd making much more than what we need; it is a fault tolerant +store with strong consistency, but I claim all we need here is just simplest pub +sub with best effort delivery, because +* We already have centralized source of truth for long running data, like which + tlis are on which nodes -- the console. +* Momentary data (safekeeper/pageserver progress) doesn't make sense to persist. + Instead of putting each change to broker, expecting it to reliably deliver it + is better to just have constant flow of data for active timelines: 1) they + serve as natural heartbeats -- if node can't send, we shouldn't pull WAL from + it 2) it is simpler -- no need to track delivery to/from the broker. + Moreover, latency here is important: the faster we obtain fresh data, the + faster we can switch to proper safekeeper after failure. +* As for WAL offloading leader election, it is trivial to achieve through these + heartbeats -- just take suitable node through deterministic rule (min node + id). Once network is stable, this is a converging process (well, except + complicated failure topology, but even then making it converge is not + hard). Such elections bear some risk of several offloaders running + concurrently for a short period of time, but that's harmless. + + Generally, if one needs strong consistency, electing leader per se is not + enough; it must be accompanied with number (logical clock ts), checked at + every action to track causality. s3 doesn't provide CAS, so it can't + differentiate old/new leader, this must be solved differently. + + We could use etcd CAS (its most powerful/useful primitive actually) to issue + these leader numbers (and e.g. prefix files in s3), but currently I don't see + need for that. + + +Obviously best effort pub sub is much more simpler and performant; the one proposed is + +## gRPC broker + +I took tonic and [prototyped](https://github.com/neondatabase/neon/blob/asher/neon-broker/broker/src/broker.rs) the replacement of functionality we currently use +with grpc streams and tokio mpsc channels. The implementation description is at the file header. + +It is just 500 lines of code and core functionality is complete. 1-1 pub sub +gives about 120k received messages per second; having multiple subscribers in +different connecitons quickly scales to 1 million received messages per second. +I had concerns about many concurrent streams in singe connection, but 2^20 +subscribers still work (though eat memory, with 10 publishers 20GB are consumed; +in this implementation each publisher holds full copy of all subscribers). There +is `bench.rs` nearby which I used for testing. + +`SkTimelineInfo` is wired here, but another message can be added (e.g. if +pageservers want to communicate with each other) with templating. + +### Fault tolerance + +Since such broker is stateless, we can run it under k8s. Or add proxying to +other members, with best-effort this is simple. + +### Security implications + +Communication happens in a private network that is not exposed to users; +additionaly we can add auth to the broker. + +## Alternative: get existing pub-sub + +We could take some existing pub sub solution, e.g. RabbitMQ, Redis. But in this +case IMV simplicity of our own outweights external dependency costs (RabbitMQ is +much more complicated and needs VM; Redis Rust client maintenance is not +ideal...). Also note that projects like CockroachDB and TiDB are based on gRPC +as well. + +## Alternative: direct communication + +Apart from being transport, broker solves one more task: discovery, i.e. letting +safekeepers and pageservers find each other. We can let safekeepers know, for +each timeline, both other safekeepers for this timeline and pageservers serving +it. In this case direct communication is possible: + - each safekeeper pushes to each other safekeeper status of timelines residing + on both of them, letting remove WAL, decide who offloads, decide on peer + recovery; + - each safekeeper pushes to each pageserver status of timelines residing on + both of them, letting pageserver choose from which sk to pull WAL; + +It was mostly described in [014-safekeeper-gossip](https://github.com/neondatabase/neon/blob/main/docs/rfcs/014-safekeepers-gossip.md), but I want to recap on that. + +The main pro is less one dependency: less moving parts, easier to run Neon +locally/manually, less places to monitor. Fault tolerance for broker disappears, +no kuber or something. To me this is a big thing. + +Also (though not a big thing) idle watches for inactive timelines disappear: +naturally safekeepers learn about compute connection first and start pushing +status to pageserver(s), notifying it should pull. + +Importantly, I think that eventually knowing and persisting peers and +pageservers on safekeepers is inevitable: +- Knowing peer safekeepers for the timeline is required for correct + automatic membership change -- new member set must be hardened on old + majority before proceeding. It is required to get rid of sync-safekeepers + as well (peer recovery up to flush_lsn). +- Knowing pageservers where the timeline is attached is needed to + 1. Understand when to shut down activity on the timeline, i.e. push data to + the broker. We can have a lot of timelines sleeping quietly which + shouldn't occupy resources. + 2. Preserve WAL for these (currently we offload to s3 and take it from there, + but serving locally is better, and we get one less condition on which WAL + can be removed from s3). + +I suppose this membership data should be passed to safekeepers directly from the +console because +1. Console is the original source of this data, conceptually this is the + simplest way (rather than passing it through compute or something). +2. We already have similar code for deleting timeline on safekeepers + (and attaching/detaching timeline on pageserver), this is a typical + action -- queue operation against storage node and execute it until it + completes (or timeline is dropped). + +Cons of direct communication are +- It is more complicated: each safekeeper should maintain set of peers it talks + to, and set of timelines for each such peer -- they ought to be multiplexed + into single connection. +- Totally, we have O(n^2) connections instead of O(n) with broker schema + (still O(n) on each node). However, these are relatively stable, async and + thus not very expensive, I don't think this is a big problem. Up to 10k + storage nodes I doubt connection overhead would be noticeable. + +I'd use gRPC for direct communication, and in this sense gRPC based broker is a +step towards it. diff --git a/docs/rfcs/019-tenant-timeline-lifecycles.md b/docs/rfcs/019-tenant-timeline-lifecycles.md new file mode 100644 index 0000000000..2734bf17b9 --- /dev/null +++ b/docs/rfcs/019-tenant-timeline-lifecycles.md @@ -0,0 +1,91 @@ +# Managing Tenant and Timeline lifecycles + +## Summary + +The pageserver has a Tenant object in memory for each tenant it manages, and a +Timeline for each timeline. There are a lot of tasks that operate on the tenants +and timelines with references to those objects. We have some mechanisms to track +which tasks are operating on each Tenant and Timeline, and to request them to +shutdown when a tenant or timeline is deleted, but it does not cover all uses, +and as a result we have many race conditions around tenant/timeline shutdown. + +## Motivation + +We have a bunch of race conditions that can produce weird errors and can be hard +to track down. + +## Non Goals + +This RFC only covers the problem of ensuring that a task/thread isn't operating +on a Tenant or Timeline. It does not cover what states, aside from Active and +non-Active, each Tenant and Timeline should have, or when exactly the transitions +should happen. + +## Impacted components (e.g. pageserver, safekeeper, console, etc) + +Pageserver. Although I wonder if the safekeeper should have a similar mechanism. + +## Current situation + +Most pageserver tasks of are managed by task_mgr.rs: + +- LibpqEndpointListener +- HttpEndPointListener +- WalReceiverManager and -Connection +- GarbageCollector and Compaction +- InitialLogicalSizeCalculation + +In addition to those tasks, the walreceiver performs some direct tokio::spawn +calls to spawn tasks that are not registered with 'task_mgr'. And all of these +tasks can spawn extra operations with tokio spawn_blocking. + +Whenever a tenant or timeline is removed from the system, by pageserver +shutdown, delete_timeline or tenant-detach operation, we rely on the task +registry in 'task_mgr.rs' to wait until there are no tasks operating on the +tenant or timeline, before its Tenant/Timeline object is removed. That relies on +each task to register itself with the tenant/timeline ID in +'task_mgr.rs'. However, there are many gaps in that. For example, +GarbageCollection and Compaction tasks are registered with the tenant, but when +they proceed to operate on a particular timeline of the tenant, they don't +register with timeline ID. Because of that, the timeline can be deleted while GC +or compaction is running on it, causing failures in the GC or compaction (see +https://github.com/neondatabase/neon/issues/2442). + +Another problem is that the task registry only works for tokio Tasks. There is +no way to register a piece of code that runs inside spawn_blocking(), for +example. + +## Proposed implementation + +This "voluntary" registration of tasks is fragile. Let's use Rust language features +to enforce that a tenant/timeline cannot be removed from the system when there is +still some code operating on it. + +Let's introduce new Guard objects for Tenant and Timeline, and do all actions through +the Guard object. Something like: + +TenantActiveGuard: Guard object over Arc. When you acquire the guard, +the code checks that the tenant is in Active state. If it's not, you get an +error. You can change the state of the tenant to Stopping while there are +ActiveTenantGuard objects still on it, to prevent new ActiveTenantGuards from +being acquired, but the Tenant cannot be removed until all the guards are gone. + +TenantMaintenanceGuard: Like ActiveTenantGuard, but can be held even when the +tenant is not in Active state. Used for operations like attach/detach. Perhaps +allow only one such guard on a Tenant at a time. + +Similarly for Timelines. We don't currentl have a "state" on Timeline, but I think +we need at least two states: Active and Stopping. The Stopping state is used at +deletion, to prevent new TimelineActiveGuards from appearing, while you wait for +existing TimelineActiveGuards to die out. + +The shutdown-signaling, using shutdown_watcher() and is_shutdown_requested(), +probably also needs changes to deal with the new Guards. The rule is that if you +have a TenantActiveGuard, and the tenant's state changes from Active to +Stopping, the is_shutdown_requested() function should return true, and +shutdown_watcher() future should return. + +This signaling doesn't neessarily need to cover all cases. For example, if you +have a block of code in spawn_blocking(), it might be acceptable if +is_shutdown_requested() doesn't return true even though the tenant is in +Stopping state, as long as the code finishes reasonably fast. diff --git a/libs/etcd_broker/Cargo.toml b/libs/etcd_broker/Cargo.toml index f7bfbad4ba..b18dcbe5a3 100644 --- a/libs/etcd_broker/Cargo.toml +++ b/libs/etcd_broker/Cargo.toml @@ -8,7 +8,7 @@ regex = "1.4.5" serde = { version = "1.0", features = ["derive"] } serde_json = "1" - serde_with = "1.12.0" + serde_with = "2.0" once_cell = "1.13.0" utils = { path = "../utils" } diff --git a/libs/metrics/src/lib.rs b/libs/metrics/src/lib.rs index e290828d37..880ab0e83c 100644 --- a/libs/metrics/src/lib.rs +++ b/libs/metrics/src/lib.rs @@ -77,6 +77,16 @@ pub const DISK_WRITE_SECONDS_BUCKETS: &[f64] = &[ 0.000_050, 0.000_100, 0.000_500, 0.001, 0.003, 0.005, 0.01, 0.05, 0.1, 0.3, 0.5, ]; +pub fn set_build_info_metric(revision: &str) { + let metric = register_int_gauge_vec!( + "libmetrics_build_info", + "Build/version information", + &["revision"] + ) + .expect("Failed to register build info metric"); + metric.with_label_values(&[revision]).set(1); +} + // Records I/O stats in a "cross-platform" way. // Compiles both on macOS and Linux, but current macOS implementation always returns 0 as values for I/O stats. // An alternative is to read procfs (`/proc/[pid]/io`) which does not work under macOS at all, hence abandoned. diff --git a/libs/pageserver_api/Cargo.toml b/libs/pageserver_api/Cargo.toml index be8762100c..5995325a2f 100644 --- a/libs/pageserver_api/Cargo.toml +++ b/libs/pageserver_api/Cargo.toml @@ -5,7 +5,7 @@ edition = "2021" [dependencies] serde = { version = "1.0", features = ["derive"] } -serde_with = "1.12.0" +serde_with = "2.0" const_format = "0.2.21" utils = { path = "../utils" } diff --git a/libs/pageserver_api/src/models.rs b/libs/pageserver_api/src/models.rs index 43059ead84..a153f1a01e 100644 --- a/libs/pageserver_api/src/models.rs +++ b/libs/pageserver_api/src/models.rs @@ -123,9 +123,15 @@ pub struct TenantInfo { pub has_in_progress_downloads: Option, } +/// This represents the output of the "timeline_detail" and "timeline_list" API calls. #[serde_as] #[derive(Debug, Serialize, Deserialize, Clone)] -pub struct LocalTimelineInfo { +pub struct TimelineInfo { + #[serde_as(as = "DisplayFromStr")] + pub tenant_id: TenantId, + #[serde_as(as = "DisplayFromStr")] + pub timeline_id: TimelineId, + #[serde_as(as = "Option")] pub ancestor_timeline_id: Option, #[serde_as(as = "Option")] @@ -149,28 +155,33 @@ pub struct LocalTimelineInfo { /// the timestamp (in microseconds) of the last received message pub last_received_msg_ts: Option, pub pg_version: u32, + + #[serde_as(as = "Option")] + pub remote_consistent_lsn: Option, + pub awaits_download: bool, + + // Some of the above fields are duplicated in 'local' and 'remote', for backwards- + // compatility with older clients. + pub local: LocalTimelineInfo, + pub remote: RemoteTimelineInfo, +} + +#[serde_as] +#[derive(Debug, Serialize, Deserialize, Clone)] +pub struct LocalTimelineInfo { + #[serde_as(as = "Option")] + pub ancestor_timeline_id: Option, + #[serde_as(as = "Option")] + pub ancestor_lsn: Option, + pub current_logical_size: Option, // is None when timeline is Unloaded + pub current_physical_size: Option, // is None when timeline is Unloaded } #[serde_as] #[derive(Debug, Serialize, Deserialize, Clone)] pub struct RemoteTimelineInfo { - #[serde_as(as = "DisplayFromStr")] - pub remote_consistent_lsn: Lsn, - pub awaits_download: bool, -} - -/// -/// This represents the output of the "timeline_detail" API call. -/// -#[serde_as] -#[derive(Debug, Serialize, Deserialize, Clone)] -pub struct TimelineInfo { - #[serde_as(as = "DisplayFromStr")] - pub tenant_id: TenantId, - #[serde_as(as = "DisplayFromStr")] - pub timeline_id: TimelineId, - pub local: Option, - pub remote: Option, + #[serde_as(as = "Option")] + pub remote_consistent_lsn: Option, } pub type ConfigureFailpointsRequest = Vec; diff --git a/libs/postgres_ffi/Cargo.toml b/libs/postgres_ffi/Cargo.toml index 60caca76b8..01ff6ab60e 100644 --- a/libs/postgres_ffi/Cargo.toml +++ b/libs/postgres_ffi/Cargo.toml @@ -13,7 +13,7 @@ crc32c = "0.6.0" hex = "0.4.3" once_cell = "1.13.0" log = "0.4.14" -memoffset = "0.6.2" +memoffset = "0.7" thiserror = "1.0" serde = { version = "1.0", features = ["derive"] } utils = { path = "../utils" } @@ -26,4 +26,4 @@ wal_craft = { path = "wal_craft" } [build-dependencies] anyhow = "1.0" -bindgen = "0.60.1" +bindgen = "0.61" diff --git a/libs/postgres_ffi/wal_craft/Cargo.toml b/libs/postgres_ffi/wal_craft/Cargo.toml index 88466737ed..4c35c5a650 100644 --- a/libs/postgres_ffi/wal_craft/Cargo.toml +++ b/libs/postgres_ffi/wal_craft/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" [dependencies] anyhow = "1.0" -clap = "3.0" +clap = "4.0" env_logger = "0.9" log = "0.4" once_cell = "1.13.0" diff --git a/libs/postgres_ffi/wal_craft/src/bin/wal_craft.rs b/libs/postgres_ffi/wal_craft/src/bin/wal_craft.rs index 9563298cd8..e87ca27e90 100644 --- a/libs/postgres_ffi/wal_craft/src/bin/wal_craft.rs +++ b/libs/postgres_ffi/wal_craft/src/bin/wal_craft.rs @@ -1,68 +1,19 @@ use anyhow::*; -use clap::{App, Arg, ArgMatches}; -use std::str::FromStr; +use clap::{value_parser, Arg, ArgMatches, Command}; +use std::{path::PathBuf, str::FromStr}; use wal_craft::*; fn main() -> Result<()> { env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("wal_craft=info")) .init(); - let type_arg = &Arg::new("type") - .takes_value(true) - .help("Type of WAL to craft") - .possible_values([ - Simple::NAME, - LastWalRecordXlogSwitch::NAME, - LastWalRecordXlogSwitchEndsOnPageBoundary::NAME, - WalRecordCrossingSegmentFollowedBySmallOne::NAME, - LastWalRecordCrossingSegment::NAME, - ]) - .required(true); - let arg_matches = App::new("Postgres WAL crafter") - .about("Crafts Postgres databases with specific WAL properties") - .subcommand( - App::new("print-postgres-config") - .about("Print the configuration required for PostgreSQL server before running this script") - ) - .subcommand( - App::new("with-initdb") - .about("Craft WAL in a new data directory first initialized with initdb") - .arg(type_arg) - .arg( - Arg::new("datadir") - .takes_value(true) - .help("Data directory for the Postgres server") - .required(true) - ) - .arg( - Arg::new("pg-distrib-dir") - .long("pg-distrib-dir") - .takes_value(true) - .help("Directory with Postgres distributions (bin and lib directories, e.g. pg_install containing subpath `v14/bin/postgresql`)") - .default_value("/usr/local") - ) - .arg( - Arg::new("pg-version") - .long("pg-version") - .help("Postgres version to use for the initial tenant") - .required(true) - .takes_value(true) - ) - ) - .subcommand( - App::new("in-existing") - .about("Craft WAL at an existing recently created Postgres database. Note that server may append new WAL entries on shutdown.") - .arg(type_arg) - .arg( - Arg::new("connection") - .takes_value(true) - .help("Connection string to the Postgres database to populate") - .required(true) - ) - ) - .get_matches(); + let arg_matches = cli().get_matches(); let wal_craft = |arg_matches: &ArgMatches, client| { - let (intermediate_lsns, end_of_wal_lsn) = match arg_matches.value_of("type").unwrap() { + let (intermediate_lsns, end_of_wal_lsn) = match arg_matches + .get_one::("type") + .map(|s| s.as_str()) + .context("'type' is required")? + { Simple::NAME => Simple::craft(client)?, LastWalRecordXlogSwitch::NAME => LastWalRecordXlogSwitch::craft(client)?, LastWalRecordXlogSwitchEndsOnPageBoundary::NAME => { @@ -72,12 +23,12 @@ fn main() -> Result<()> { WalRecordCrossingSegmentFollowedBySmallOne::craft(client)? } LastWalRecordCrossingSegment::NAME => LastWalRecordCrossingSegment::craft(client)?, - a => panic!("Unknown --type argument: {}", a), + a => panic!("Unknown --type argument: {a}"), }; for lsn in intermediate_lsns { - println!("intermediate_lsn = {}", lsn); + println!("intermediate_lsn = {lsn}"); } - println!("end_of_wal = {}", end_of_wal_lsn); + println!("end_of_wal = {end_of_wal_lsn}"); Ok(()) }; @@ -85,20 +36,24 @@ fn main() -> Result<()> { None => panic!("No subcommand provided"), Some(("print-postgres-config", _)) => { for cfg in REQUIRED_POSTGRES_CONFIG.iter() { - println!("{}", cfg); + println!("{cfg}"); } Ok(()) } Some(("with-initdb", arg_matches)) => { let cfg = Conf { - pg_version: arg_matches - .value_of("pg-version") - .unwrap() - .parse::() - .context("Failed to parse postgres version from the argument string")?, - pg_distrib_dir: arg_matches.value_of("pg-distrib-dir").unwrap().into(), - datadir: arg_matches.value_of("datadir").unwrap().into(), + pg_version: *arg_matches + .get_one::("pg-version") + .context("'pg-version' is required")?, + pg_distrib_dir: arg_matches + .get_one::("pg-distrib-dir") + .context("'pg-distrib-dir' is required")? + .to_owned(), + datadir: arg_matches + .get_one::("datadir") + .context("'datadir' is required")? + .to_owned(), }; cfg.initdb()?; let srv = cfg.start_server()?; @@ -108,9 +63,77 @@ fn main() -> Result<()> { } Some(("in-existing", arg_matches)) => wal_craft( arg_matches, - &mut postgres::Config::from_str(arg_matches.value_of("connection").unwrap())? - .connect(postgres::NoTls)?, + &mut postgres::Config::from_str( + arg_matches + .get_one::("connection") + .context("'connection' is required")?, + ) + .context( + "'connection' argument value could not be parsed as a postgres connection string", + )? + .connect(postgres::NoTls)?, ), Some(_) => panic!("Unknown subcommand"), } } + +fn cli() -> Command { + let type_arg = &Arg::new("type") + .help("Type of WAL to craft") + .value_parser([ + Simple::NAME, + LastWalRecordXlogSwitch::NAME, + LastWalRecordXlogSwitchEndsOnPageBoundary::NAME, + WalRecordCrossingSegmentFollowedBySmallOne::NAME, + LastWalRecordCrossingSegment::NAME, + ]) + .required(true); + + Command::new("Postgres WAL crafter") + .about("Crafts Postgres databases with specific WAL properties") + .subcommand( + Command::new("print-postgres-config") + .about("Print the configuration required for PostgreSQL server before running this script") + ) + .subcommand( + Command::new("with-initdb") + .about("Craft WAL in a new data directory first initialized with initdb") + .arg(type_arg) + .arg( + Arg::new("datadir") + .help("Data directory for the Postgres server") + .value_parser(value_parser!(PathBuf)) + .required(true) + ) + .arg( + Arg::new("pg-distrib-dir") + .long("pg-distrib-dir") + .value_parser(value_parser!(PathBuf)) + .help("Directory with Postgres distributions (bin and lib directories, e.g. pg_install containing subpath `v14/bin/postgresql`)") + .default_value("/usr/local") + ) + .arg( + Arg::new("pg-version") + .long("pg-version") + .help("Postgres version to use for the initial tenant") + .value_parser(value_parser!(u32)) + .required(true) + + ) + ) + .subcommand( + Command::new("in-existing") + .about("Craft WAL at an existing recently created Postgres database. Note that server may append new WAL entries on shutdown.") + .arg(type_arg) + .arg( + Arg::new("connection") + .help("Connection string to the Postgres database to populate") + .required(true) + ) + ) +} + +#[test] +fn verify_cli() { + cli().debug_assert(); +} diff --git a/libs/postgres_ffi/wal_craft/src/lib.rs b/libs/postgres_ffi/wal_craft/src/lib.rs index 7ffe19e209..c4404b37ba 100644 --- a/libs/postgres_ffi/wal_craft/src/lib.rs +++ b/libs/postgres_ffi/wal_craft/src/lib.rs @@ -37,22 +37,22 @@ pub static REQUIRED_POSTGRES_CONFIG: Lazy> = Lazy::new(|| { }); impl Conf { - pub fn pg_distrib_dir(&self) -> PathBuf { + pub fn pg_distrib_dir(&self) -> anyhow::Result { let path = self.pg_distrib_dir.clone(); match self.pg_version { - 14 => path.join(format!("v{}", self.pg_version)), - 15 => path.join(format!("v{}", self.pg_version)), - _ => panic!("Unsupported postgres version: {}", self.pg_version), + 14 => Ok(path.join(format!("v{}", self.pg_version))), + 15 => Ok(path.join(format!("v{}", self.pg_version))), + _ => bail!("Unsupported postgres version: {}", self.pg_version), } } - fn pg_bin_dir(&self) -> PathBuf { - self.pg_distrib_dir().join("bin") + fn pg_bin_dir(&self) -> anyhow::Result { + Ok(self.pg_distrib_dir()?.join("bin")) } - fn pg_lib_dir(&self) -> PathBuf { - self.pg_distrib_dir().join("lib") + fn pg_lib_dir(&self) -> anyhow::Result { + Ok(self.pg_distrib_dir()?.join("lib")) } pub fn wal_dir(&self) -> PathBuf { @@ -60,12 +60,12 @@ impl Conf { } fn new_pg_command(&self, command: impl AsRef) -> Result { - let path = self.pg_bin_dir().join(command); + let path = self.pg_bin_dir()?.join(command); ensure!(path.exists(), "Command {:?} does not exist", path); let mut cmd = Command::new(path); cmd.env_clear() - .env("LD_LIBRARY_PATH", self.pg_lib_dir()) - .env("DYLD_LIBRARY_PATH", self.pg_lib_dir()); + .env("LD_LIBRARY_PATH", self.pg_lib_dir()?) + .env("DYLD_LIBRARY_PATH", self.pg_lib_dir()?); Ok(cmd) } diff --git a/libs/remote_storage/Cargo.toml b/libs/remote_storage/Cargo.toml index cec344a4ad..f54d91905c 100644 --- a/libs/remote_storage/Cargo.toml +++ b/libs/remote_storage/Cargo.toml @@ -15,7 +15,7 @@ serde = { version = "1.0", features = ["derive"] } serde_json = "1" tokio = { version = "1.17", features = ["sync", "macros", "fs", "io-util"] } tokio-util = { version = "0.7", features = ["io"] } -toml_edit = { version = "0.13", features = ["easy"] } +toml_edit = { version = "0.14", features = ["easy"] } tracing = "0.1.27" workspace_hack = { version = "0.1", path = "../../workspace_hack" } diff --git a/libs/remote_storage/src/local_fs.rs b/libs/remote_storage/src/local_fs.rs index 5723a512f6..2f824cc453 100644 --- a/libs/remote_storage/src/local_fs.rs +++ b/libs/remote_storage/src/local_fs.rs @@ -16,7 +16,7 @@ use tokio::{ io::{self, AsyncReadExt, AsyncSeekExt, AsyncWriteExt}, }; use tracing::*; -use utils::crashsafe_dir::path_with_suffix_extension; +use utils::crashsafe::path_with_suffix_extension; use crate::{Download, DownloadError, RemoteObjectId}; diff --git a/libs/safekeeper_api/Cargo.toml b/libs/safekeeper_api/Cargo.toml index 852d643f30..15bdecd71d 100644 --- a/libs/safekeeper_api/Cargo.toml +++ b/libs/safekeeper_api/Cargo.toml @@ -5,7 +5,7 @@ edition = "2021" [dependencies] serde = { version = "1.0", features = ["derive"] } -serde_with = "1.12.0" +serde_with = "2.0" const_format = "0.2.21" utils = { path = "../utils" } diff --git a/libs/safekeeper_api/src/models.rs b/libs/safekeeper_api/src/models.rs index e13ea50eaf..85c6439367 100644 --- a/libs/safekeeper_api/src/models.rs +++ b/libs/safekeeper_api/src/models.rs @@ -1,8 +1,24 @@ use serde::{Deserialize, Serialize}; -use utils::id::{NodeId, TimelineId}; +use serde_with::{serde_as, DisplayFromStr}; +use utils::{ + id::{NodeId, TenantId, TimelineId}, + lsn::Lsn, +}; + +#[serde_as] #[derive(Serialize, Deserialize)] pub struct TimelineCreateRequest { + #[serde_as(as = "DisplayFromStr")] + pub tenant_id: TenantId, + #[serde_as(as = "DisplayFromStr")] pub timeline_id: TimelineId, - pub peer_ids: Vec, + pub peer_ids: Option>, + pub pg_version: u32, + pub system_id: Option, + pub wal_seg_size: Option, + #[serde_as(as = "DisplayFromStr")] + pub commit_lsn: Lsn, + // If not passed, it is assigned to the beginning of commit_lsn segment. + pub local_start_lsn: Option, } diff --git a/libs/utils/Cargo.toml b/libs/utils/Cargo.toml index ef2aa8b305..a7baddada4 100644 --- a/libs/utils/Cargo.toml +++ b/libs/utils/Cargo.toml @@ -20,7 +20,7 @@ tokio = { version = "1.17", features = ["macros"]} tokio-rustls = "0.23" tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } -nix = "0.23.0" +nix = "0.25" signal-hook = "0.3.10" rand = "0.8.3" jsonwebtoken = "8" @@ -28,7 +28,7 @@ hex = { version = "0.4.3", features = ["serde"] } rustls = "0.20.2" rustls-split = "0.3.0" git-version = "0.3.5" -serde_with = "1.12.0" +serde_with = "2.0" once_cell = "1.13.0" @@ -40,7 +40,7 @@ byteorder = "1.4.3" bytes = "1.0.1" hex-literal = "0.3" tempfile = "3.2" -criterion = "0.3" +criterion = "0.4" rustls-pemfile = "1" [[bench]] diff --git a/libs/utils/src/crashsafe_dir.rs b/libs/utils/src/crashsafe.rs similarity index 84% rename from libs/utils/src/crashsafe_dir.rs rename to libs/utils/src/crashsafe.rs index 032ab0a916..3726779cb2 100644 --- a/libs/utils/src/crashsafe_dir.rs +++ b/libs/utils/src/crashsafe.rs @@ -12,16 +12,8 @@ pub fn create_dir(path: impl AsRef) -> io::Result<()> { let path = path.as_ref(); fs::create_dir(path)?; - File::open(path)?.sync_all()?; - - if let Some(parent) = path.parent() { - File::open(parent)?.sync_all() - } else { - Err(io::Error::new( - io::ErrorKind::InvalidInput, - "can't find parent", - )) - } + fsync_file_and_parent(path)?; + Ok(()) } /// Similar to [`std::fs::create_dir_all`], except we fsync all @@ -65,12 +57,12 @@ pub fn create_dir_all(path: impl AsRef) -> io::Result<()> { // Fsync the created directories from child to parent. for &path in dirs_to_create.iter() { - File::open(path)?.sync_all()?; + fsync(path)?; } // If we created any new directories, fsync the parent. if !dirs_to_create.is_empty() { - File::open(path)?.sync_all()?; + fsync(path)?; } Ok(()) @@ -92,6 +84,33 @@ pub fn path_with_suffix_extension(original_path: impl AsRef, suffix: &str) .with_extension(new_extension.as_ref()) } +pub fn fsync_file_and_parent(file_path: &Path) -> io::Result<()> { + let parent = file_path.parent().ok_or_else(|| { + io::Error::new( + io::ErrorKind::Other, + format!("File {file_path:?} has no parent"), + ) + })?; + + fsync(file_path)?; + fsync(parent)?; + Ok(()) +} + +pub fn fsync(path: &Path) -> io::Result<()> { + File::open(path) + .map_err(|e| io::Error::new(e.kind(), format!("Failed to open the file {path:?}: {e}"))) + .and_then(|file| { + file.sync_all().map_err(|e| { + io::Error::new( + e.kind(), + format!("Failed to sync file {path:?} data and metadata: {e}"), + ) + }) + }) + .map_err(|e| io::Error::new(e.kind(), format!("Failed to fsync file {path:?}: {e}"))) +} + #[cfg(test)] mod tests { use tempfile::tempdir; diff --git a/libs/utils/src/lib.rs b/libs/utils/src/lib.rs index 2c80556446..f1f48f5a90 100644 --- a/libs/utils/src/lib.rs +++ b/libs/utils/src/lib.rs @@ -22,8 +22,8 @@ pub mod pq_proto; // dealing with connstring parsing and handy access to it's parts pub mod connstring; -// helper functions for creating and fsyncing directories/trees -pub mod crashsafe_dir; +// helper functions for creating and fsyncing +pub mod crashsafe; // common authentication routines pub mod auth; diff --git a/libs/utils/src/lsn.rs b/libs/utils/src/lsn.rs index 1090f4c679..289cec12a8 100644 --- a/libs/utils/src/lsn.rs +++ b/libs/utils/src/lsn.rs @@ -66,6 +66,11 @@ impl Lsn { (self.0 % seg_sz as u64) as usize } + /// Compute LSN of the segment start. + pub fn segment_lsn(self, seg_sz: usize) -> Lsn { + Lsn(self.0 - (self.0 % seg_sz as u64)) + } + /// Compute the segment number pub fn segment_number(self, seg_sz: usize) -> u64 { self.0 / seg_sz as u64 diff --git a/libs/utils/src/postgres_backend_async.rs b/libs/utils/src/postgres_backend_async.rs index 87e4478a99..53f6759d62 100644 --- a/libs/utils/src/postgres_backend_async.rs +++ b/libs/utils/src/postgres_backend_async.rs @@ -15,7 +15,7 @@ use std::sync::Arc; use std::task::Poll; use tracing::{debug, error, trace}; -use tokio::io::{AsyncRead, AsyncWrite, AsyncWriteExt}; +use tokio::io::{AsyncRead, AsyncWrite, AsyncWriteExt, BufReader}; use tokio_rustls::TlsAcceptor; #[async_trait::async_trait] @@ -66,8 +66,8 @@ pub enum ProcessMsgResult { /// Always-writeable sock_split stream. /// May not be readable. See [`PostgresBackend::take_stream_in`] pub enum Stream { - Unencrypted(tokio::net::TcpStream), - Tls(Box>), + Unencrypted(BufReader), + Tls(Box>>), Broken, } @@ -157,7 +157,7 @@ impl PostgresBackend { let peer_addr = socket.peer_addr()?; Ok(Self { - stream: Stream::Unencrypted(socket), + stream: Stream::Unencrypted(BufReader::new(socket)), buf_out: BytesMut::with_capacity(10 * 1024), state: ProtoState::Initialization, md5_salt: [0u8; 4], diff --git a/pageserver/Cargo.toml b/pageserver/Cargo.toml index 88430f3a86..2139e24ee2 100644 --- a/pageserver/Cargo.toml +++ b/pageserver/Cargo.toml @@ -23,7 +23,7 @@ futures = "0.3.13" hex = "0.4.3" hyper = "0.14" itertools = "0.10.3" -clap = "3.0" +clap = { version = "4.0", features = ["string"] } daemonize = "0.4.1" tokio = { version = "1.17", features = ["process", "sync", "macros", "fs", "rt", "io-util", "time"] } tokio-util = { version = "0.7.3", features = ["io", "io-util"] } @@ -38,25 +38,25 @@ tar = "0.4.33" humantime = "2.1.0" serde = { version = "1.0", features = ["derive"] } serde_json = "1" -serde_with = "1.12.0" +serde_with = "2.0" humantime-serde = "1.1.1" pprof = { git = "https://github.com/neondatabase/pprof-rs.git", branch = "wallclock-profiling", features = ["flamegraph"], optional = true } -toml_edit = { version = "0.13", features = ["easy"] } +toml_edit = { version = "0.14", features = ["easy"] } scopeguard = "1.1.0" const_format = "0.2.21" tracing = "0.1.36" signal-hook = "0.3.10" url = "2" -nix = "0.23" +nix = "0.25" once_cell = "1.13.0" crossbeam-utils = "0.8.5" fail = "0.5.0" git-version = "0.3.5" rstar = "0.9.3" num-traits = "0.2.15" -amplify_num = "0.4.1" +amplify_num = { git = "https://github.com/hlinnaka/rust-amplify.git", branch = "unsigned-int-perf" } pageserver_api = { path = "../libs/pageserver_api" } postgres_ffi = { path = "../libs/postgres_ffi" } @@ -69,5 +69,10 @@ close_fds = "0.3.2" walkdir = "2.3.2" [dev-dependencies] +criterion = "0.4" hex-literal = "0.3" tempfile = "3.2" + +[[bench]] +name = "bench_layer_map" +harness = false diff --git a/pageserver/benches/bench_layer_map.rs b/pageserver/benches/bench_layer_map.rs new file mode 100644 index 0000000000..25d5ecd643 --- /dev/null +++ b/pageserver/benches/bench_layer_map.rs @@ -0,0 +1,5866 @@ +use anyhow::Result; +use pageserver::repository::{Key, Value}; +use pageserver::tenant::filename::{DeltaFileName, ImageFileName}; +use pageserver::tenant::layer_map::LayerMap; +use pageserver::tenant::storage_layer::Layer; +use pageserver::tenant::storage_layer::ValueReconstructResult; +use pageserver::tenant::storage_layer::ValueReconstructState; +use std::cmp::{max, min}; +use std::ops::Range; +use std::path::PathBuf; +use std::str::FromStr; +use std::sync::Arc; +use utils::id::{TenantId, TimelineId}; +use utils::lsn::Lsn; + +use criterion::{criterion_group, criterion_main, Criterion}; + +struct DummyDelta { + key_range: Range, + lsn_range: Range, +} + +impl Layer for DummyDelta { + fn get_tenant_id(&self) -> TenantId { + TenantId::from_str("00000000000000000000000000000000").unwrap() + } + + fn get_timeline_id(&self) -> TimelineId { + TimelineId::from_str("00000000000000000000000000000000").unwrap() + } + + fn get_key_range(&self) -> Range { + self.key_range.clone() + } + + fn get_lsn_range(&self) -> Range { + self.lsn_range.clone() + } + + fn filename(&self) -> PathBuf { + todo!() + } + + fn local_path(&self) -> Option { + todo!() + } + + fn get_value_reconstruct_data( + &self, + _key: Key, + _lsn_range: Range, + _reconstruct_data: &mut ValueReconstructState, + ) -> Result { + panic!() + } + + fn is_incremental(&self) -> bool { + true + } + + fn is_in_memory(&self) -> bool { + false + } + + fn iter(&self) -> Box> + '_> { + panic!() + } + + fn key_iter(&self) -> Box + '_> { + panic!("Not implemented") + } + + fn delete(&self) -> Result<()> { + panic!() + } + + fn dump(&self, _verbose: bool) -> Result<()> { + todo!() + } +} + +struct DummyImage { + key_range: Range, + lsn: Lsn, +} + +impl Layer for DummyImage { + fn get_tenant_id(&self) -> TenantId { + TenantId::from_str("00000000000000000000000000000000").unwrap() + } + + fn get_timeline_id(&self) -> TimelineId { + TimelineId::from_str("00000000000000000000000000000000").unwrap() + } + + fn get_key_range(&self) -> Range { + self.key_range.clone() + } + + fn get_lsn_range(&self) -> Range { + // End-bound is exclusive + self.lsn..(self.lsn + 1) + } + + fn filename(&self) -> PathBuf { + todo!() + } + + fn local_path(&self) -> Option { + todo!() + } + + fn get_value_reconstruct_data( + &self, + _key: Key, + _lsn_range: Range, + _reconstruct_data: &mut ValueReconstructState, + ) -> Result { + panic!() + } + + fn is_incremental(&self) -> bool { + false + } + + fn is_in_memory(&self) -> bool { + false + } + + fn iter(&self) -> Box> + '_> { + panic!() + } + + fn key_iter(&self) -> Box + '_> { + panic!("Not implemented") + } + + fn delete(&self) -> Result<()> { + panic!() + } + + fn dump(&self, _verbose: bool) -> Result<()> { + todo!() + } +} + +fn build_layer_map() -> LayerMap { + let mut layer_map = LayerMap::default(); + + let mut min_lsn = Lsn(u64::MAX); + let mut max_lsn = Lsn(0); + + for fname in TEST_LAYER_FILENAMES { + if let Some(imgfilename) = ImageFileName::parse_str(fname) { + let layer = DummyImage { + key_range: imgfilename.key_range, + lsn: imgfilename.lsn, + }; + layer_map.insert_historic(Arc::new(layer)); + min_lsn = min(min_lsn, imgfilename.lsn); + max_lsn = max(max_lsn, imgfilename.lsn); + } else if let Some(deltafilename) = DeltaFileName::parse_str(fname) { + let layer = DummyDelta { + key_range: deltafilename.key_range, + lsn_range: deltafilename.lsn_range.clone(), + }; + layer_map.insert_historic(Arc::new(layer)); + min_lsn = min(min_lsn, deltafilename.lsn_range.start); + max_lsn = max(max_lsn, deltafilename.lsn_range.end); + } else { + panic!("unexpected filename {fname}"); + } + } + + println!("min: {min_lsn}, max: {max_lsn}"); + + layer_map +} + +fn large_layer_map(c: &mut Criterion) { + let layer_map = build_layer_map(); + + c.bench_function("search", |b| { + b.iter(|| { + let result = layer_map.search( + // Just an arbitrary point + Key::from_hex("000000067F000080000009E014000001B011").unwrap(), + // This LSN is higher than any of the LSNs in the tree + Lsn::from_str("D0/80208AE1").unwrap(), + ); + result.unwrap(); + }); + }); + + // test with a key that corresponds to the RelDir entry. See pgdatadir_mapping.rs. + c.bench_function("search_rel_dir", |b| { + b.iter(|| { + let result = layer_map.search( + Key::from_hex("000000067F00008000000000000000000001").unwrap(), + // This LSN is higher than any of the LSNs in the tree + Lsn::from_str("D0/80208AE1").unwrap(), + ); + result.unwrap(); + }); + }); +} + +criterion_group!(benches, large_layer_map); +criterion_main!(benches); + +// A list of layer filenames, extracted from our performance test environment, from +// a project where we have run pgbench many timmes. The pgbench database was initialized +// between each test run. +const TEST_LAYER_FILENAMES: &[&str] = &[ +"000000000000000000000000000000000000-000000067F00008000000032090100000000__0000006CF69CD8B0", +"000000000000000000000000000000000000-000000067F00008000000032090100000000__0000006F949B7C08", +"000000000000000000000000000000000000-000000067F00008000000032090100000000__00000071F15CF6B0", +"000000000000000000000000000000000000-000000067F00008000000032090100000000__00000072AEE2BFE0", +"000000000000000000000000000000000000-000000067F00008000000032090100000000__000000756884A510", +"000000000000000000000000000000000000-000000067F00008000000032090100000000__00000077B1836CA0", +"000000000000000000000000000000000000-000000067F00008000000032090100000000__0000007D41715570", +"000000000000000000000000000000000000-000000067F00008000000032090100000000__0000007F12B83FE8", +"000000000000000000000000000000000000-000000067F00008000000032090100000000__00000083D5DE3FD0", +"000000000000000000000000000000000000-000000067F00008000000032090100000000__000000873B520940", +"000000000000000000000000000000000000-000000067F00008000000032090100000000__000000890CF51FE0", +"000000000000000000000000000000000000-000000067F00008000000032090100000000__0000008C71903720", +"000000000000000000000000000000000000-000000067F00008000000032090100000000__0000008E43487FF0", +"000000000000000000000000000000000000-000000067F00008000000032090100000000__0000009445A06DC8", +"000000000000000000000000000000000000-000000067F00008000000032090100000000__00000096187D1FC8", +"000000000000000000000000000000000000-000000067F00008000000032090100000000__00000096E85806C0", +"000000000000000000000000000000000000-000000067F00008000000032090100000000__0000009921F3B4A8", +"000000000000000000000000000000000000-000000067F00008000000032090100000000__0000009B5229DFE8", +"000000000000000000000000000000000000-000000067F00008000000032090100000000__0000009EBB11FFC0", +"000000000000000000000000000000000000-000000067F00008000000032090100000000__000000A93DDE5FE0", +"000000000000000000000000000000000000-000000067F00008000000032090100000000__000000AD3698E000", +"000000000000000000000000000000000000-000000067F00008000000032090100000000__000000B3AC039FE8", +"000000000000000000000000000000000000-000000067F00008000000032090100000000__000000B8606C92A0", +"000000000000000000000000000000000000-000000067F00008000000032090100000000__000000BC59629F98", +"000000000000000000000000000000000000-000000067F00008000000032090100000000__000000BD25E66810", +"000000000000000000000000000000000000-000000067F00008000000032090100000000__000000BEF683BFD0", +"000000000000000000000000000000000000-000000067F00008000000032090100000000__000000C14270A078", +"000000000000000000000000000000000000-000000067F00008000000032090100000000__000000C3687EDFE8", +"000000000000000000000000000000000000-000000067F00008000000032090100000000__000000C6C7BD8140", +"000000000000000000000000000000000000-000000067F00008000000032090100000000__000000C896B8DFD8", +"000000000000000000000000000000000000-000000067F00008000000032090100000000__000000CB82C2FF68", +"000000000000000000000000000000000000-000000067F00008000000032090100000000__000000CD51009FE8", +"000000000000000000000000000000000000-000000067F00008000000032090100000000__000000CF7E08BFD0", +"000000000000000000000000000000000000-000000067F00008000000540090100000000__0000006AEF261AF8", +"000000000000000000000000000000000000-000000067F00008000000560090100000000__0000006DA30DA180", +"000000000000000000000000000000000000-000000067F00008000000580090100000000__0000006FAFE25518", +"000000000000000000000000000000000000-000000067F000080000005E0090100000000__00000073AF75E930", +"000000000000000000000000000000000000-000000067F00008000000620090100000000__00000078B2CB1C68", +"000000000000000000000000000000000000-000000067F00008000000640090100000000__0000007B9877EF40", +"000000000000000000000000000000000000-000000067F00008000000680090100000000__00000080E477E868", +"000000000000000000000000000000000000-000000067F000080000006C0090100000000__00000085BE169568", +"000000000000000000000000000000000000-000000067F00008000000700090100000000__0000008AF15FEF50", +"000000000000000000000000000000000000-000000067F00008000000740090100000000__000000902186B1D0", +"000000000000000000000000000000000000-000000067F00008000000760090100000000__00000092CA5E4EA8", +"000000000000000000000000000000000000-000000067F000080000007E0090100000000__0000009D34F8D4D8", +"000000000000000000000000000000000000-000000067F00008000000820090100000000__000000A29F1D8950", +"000000000000000000000000000000000000-000000067F00008000000860090100000000__000000A434813A68", +"000000000000000000000000000000000000-000000067F000080000008C0090100000000__000000AAEBE534F8", +"000000000000000000000000000000000000-000000067F00008000000960090100000000__000000B6C2E92A88", +"000000000000000000000000000000000000-000000067F00008000000A20090100000000__000000C5745579F0", +"000000000000000000000000000000000000-000000067F00008000000A60090100000000__000000CA2C877DC8", +"000000000000000000000000000000000000-030000000000000000000000000000000002__000000AFB4666000", +"000000000000000000000000000000000000-FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF__000000CF7DC97FD1-000000CF801FC221", +"000000000000000000000000000000000000-FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF__000000CF801FC221-000000CF801FDB61", +"000000000000000000000000000000000000-FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF__000000CF801FDB61-000000CF80201FA1", +"000000000000000000000000000000000000-FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF__000000CF80201FA1-000000CF80203CC1", +"000000000000000000000000000000000000-FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF__000000CF80203CC1-000000CF802067C1", +"000000000000000000000000000000000000-FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF__000000CF802067C1-000000CF80208AE1", +"000000067F000032AC000040040000000000-000000067F000080000005400C0000007DD8__0000006A5C770149-0000006ACEF98449", +"000000067F000032AC000040040000000000-000000067F000080000005600C0000008077__0000006CF7781D19-0000006D69B48989", +"000000067F000032AC000040040000000000-000000067F000080000005800C0000007A49__0000006F95E72491-0000006FA8EDF3B9", +"000000067F000032AC000040040000000000-000000067F000080000005A00C0000007614__000000723877FF21-00000072A0D7CEA1", +"000000067F000032AC000040040000000000-000000067F000080000005C00C0000016516__00000072A0D7CEA1-0000007318DDE691", +"000000067F000032AC000040040000000000-000000067F000080000006000C0000008FB7__00000075687C3009-00000075E915EBC9", +"000000067F000032AC000040040000000000-000000067F000080000006200C0000009441__0000007805801C41-00000078859FEA11", +"000000067F000032AC000040040000000000-000000067F000080000006400C0000007987__0000007AA1DF6639-0000007B14D5C521", +"000000067F000032AC000040040000000000-000000067F000080000006600C0000009381__0000007D41EA8D51-0000007DC21DE569", +"000000067F000032AC000040040000000000-000000067F000080000006800C0000007D6A__0000007FDCDCE659-000000804F6BFFC1", +"000000067F000032AC000040040000000000-000000067F000080000006801400000044E4__00000081AFAF5FD1-0000008215AFE5A9", +"000000067F000032AC000040040000000000-000000067F000080000006C00C00000090F5__00000084A325AA01-00000085239DFB81", +"000000067F000032AC000040040000000000-000000067F000080000006E00C00000096C8__000000873C9A2551-00000087BC75E5B1", +"000000067F000032AC000040040000000000-000000067F000080000007000C000000955C__00000089D6B8EE99-0000008A56BBF739", +"000000067F000032AC000040040000000000-000000067F000080000007200C000000933D__0000008C72843D41-0000008CF2BFFC89", +"000000067F000032AC000040040000000000-000000067F000080000007400C00000090E9__0000008F10E3E189-0000008F915DE591", +"000000067F000032AC000040040000000000-000000067F000080000007600C0000008180__00000091A6DD7A79-0000009228F7FA79", +"000000067F000032AC000040040000000000-000000067F000080000007800C000000974C__0000009446B52FD1-00000094D67DF4F9", +"000000067F000032AC000040040000000000-000000067F000080000007A00C000000974B__00000096E85829C9-00000098A7ADFC91", +"000000067F000032AC000040040000000000-000000067F000080000007C00C0000007EA5__000000997F5D23C9-00000099F1C9FC71", +"000000067F000032AC000040040000000000-000000067F000080000007E00C00000092CD__0000009C1E8CC879-0000009C9ED3F059", +"000000067F000032AC000040040000000000-000000067F000080000008000C00000081F6__0000009EBBC72771-000000A154401909", +"000000067F000032AC000040040000000000-000000067F000080000008200C000000974D__000000A154401909-000000A1E407F839", +"000000067F000032AC000040040000000000-000000067F0000800000082014000000393C__000000A323C9E001-000000A37A60B1A9", +"000000067F000032AC000040040000000000-000000067F000080000008600C0000009747__000000A37A60B1A9-000000A3CA47ECA9", +"000000067F000032AC000040040000000000-000000067F000080000008801C0000009703__000000A5A081B661-000000A6503DE919", +"000000067F000032AC000040040000000000-000000067F000080000008801C00000CF6B0__000000A6F001F909-000000A91D97FD49", +"000000067F000032AC000040040000000000-000000067F000080000008C00C0000002330__000000A98AB7EE49-000000AA2597E9A1", +"000000067F000032AC000040040000000000-000000067F000080000008E00C00000077B3__000000AB6533BFD9-000000ABF63DF511", +"000000067F000032AC000040040000000000-000000067F000080000008E02A000000529F__000000AF5D587FE1-000000AFB4666001", +"000000067F000032AC000040040000000000-000000067F000080000009004000000047E0__000000B18495C001-000000B1FA75F501", +"000000067F000032AC000040040000000000-000000067F00008000000920140000005289__000000B3AB3B7FC9-000000B4208FF3D1", +"000000067F000032AC000040040000000000-000000067F000080000009400C000008DEA4__000000B4E047E5A9-000000B5CED8CF79", +"000000067F000032AC000040040000000000-000000067F000080000009600C000000974F__000000B5CED8CF79-000000B63EADE5B9", +"000000067F000032AC000040040000000000-000000067F000080000009600C0000055A74__000000B808718889-000000B8606C92A1", +"000000067F000032AC000040040000000000-000000067F000080000009800C0000009748__000000B8606C92A1-000000B8E03BF0B9", +"000000067F000032AC000040040000000000-000000067F000080000009800C000010EC71__000000BA1FC3FB39-000000BA9685E7C1", +"000000067F000032AC000040040000000000-000000067F000080000009A00C0000071F6F__000000BCEF79BE91-000000BD263A5849", +"000000067F000032AC000040040000000000-000000067F000080000009C00C0000009749__000000BD263A5849-000000BDA607F261", +"000000067F000032AC000040040000000000-000000067F000080000009E00C0000004916__000000BEF5F47FD1-000000BF48FFEB11", +"000000067F000032AC000040040000000000-000000067F00008000000A000C0000008EF9__000000C19744E959-000000C217F3F379", +"000000067F000032AC000040040000000000-000000067F00008000000A200C0000009748__000000C430961E71-000000C4C05DDB29", +"000000067F000032AC000040040000000000-000000067F00008000000A400C0000009743__000000C6C87B6329-000000C74849FAE1", +"000000067F000032AC000040040000000000-000000067F00008000000A600C0000009746__000000C90726D0D9-000000C986F5F0D9", +"000000067F000032AC000040040000000000-000000067F00008000000A600C000007A149__000000CB40C16489-000000CB82C37859", +"000000067F000032AC000040040000000000-000000067F00008000000A800C0000009748__000000CB82C37859-000000CC11F5EDC9", +"000000067F000032AC000040040000000000-000000067F00008000000A800F0100000003__000000CD51344F89-000000CDCC7BF889", +"000000067F00008000000000000000000001-000000067F000080000005400C000004B479__0000006C98B77D29-0000006CF7781D19", +"000000067F00008000000000000000000001-000000067F000080000005400C0000104BE4__0000006C1E7C73C1-0000006C98B77D29", +"000000067F00008000000000000000000001-000000067F000080000005600C0000048643__0000006F3370DD59-0000006F95E72491", +"000000067F00008000000000000000000001-000000067F000080000005600C0000100001__0000006EB935F989-0000006F3370DD59", +"000000067F00008000000000000000000001-000000067F000080000005800C000005CF06__00000071F21624D1-000000723877FF21", +"000000067F00008000000000000000000001-000000067F000080000005800C000009D78D__000000716A103FC9-00000071F21624D1", +"000000067F00008000000000000000000001-000000067F000080000005800C00000CDE2D__00000070E8761431-000000716A103FC9", +"000000067F00008000000000000000000001-000000067F000080000005E00C00000385D9__0000007318DDE691-0000007497B01FF9", +"000000067F00008000000000000000000001-000000067F000080000005E00C0000050175__000000751253A4C1-00000075687C3009", +"000000067F00008000000000000000000001-000000067F000080000005E00C00000AF576__0000007497B01FF9-000000751253A4C1", +"000000067F00008000000000000000000001-000000067F000080000006000C0000051A02__00000077B2AD0F91-0000007805801C41", +"000000067F00008000000000000000000001-000000067F000080000006000C00000C3C38__00000077391A8001-00000077B2AD0F91", +"000000067F00008000000000000000000001-000000067F000080000006000C00000C56C1__00000076A8CDE8F9-00000077391A8001", +"000000067F00008000000000000000000001-000000067F000080000006200C000004811C__0000007A3F679FA1-0000007AA1DF6639", +"000000067F00008000000000000000000001-000000067F000080000006200C0000107883__00000079C527F0D9-0000007A3F679FA1", +"000000067F00008000000000000000000001-000000067F000080000006400C000004B4C9__0000007B14D5C521-0000007C73B53FC9", +"000000067F00008000000000000000000001-000000067F000080000006400C000005258F__0000007CEE5A0B91-0000007D41EA8D51", +"000000067F00008000000000000000000001-000000067F000080000006400C00000A887C__0000007C73B53FC9-0000007CEE5A0B91", +"000000067F00008000000000000000000001-000000067F000080000006600C0000049742__0000007F7BE4E6F1-0000007FDCDCE659", +"000000067F00008000000000000000000001-000000067F000080000006600C00000BC29F__0000007E71DBF8F9-0000007F11E4BFE9", +"000000067F00008000000000000000000001-000000067F000080000006600C0000111C82__0000007F11E4BFE9-0000007F7BE4E6F1", +"000000067F00008000000000000000000001-000000067F000080000006800C00000A8D4C__00000080EF2FF5B9-00000081AFAF5FD1", +"000000067F00008000000000000000000001-000000067F000080000006A00C0000051984__000000844F1A6789-00000084A325AA01", +"000000067F00008000000000000000000001-000000067F000080000006A00C00000703EC__00000082B573F579-00000083D5901FD9", +"000000067F00008000000000000000000001-000000067F000080000006A00C00000C4CC8__00000083D5901FD9-000000844F1A6789", +"000000067F00008000000000000000000001-000000067F000080000006C00C0000055EA3__00000086ED29E361-000000873C9A2551", +"000000067F00008000000000000000000001-000000067F000080000006C00C00000BC102__00000085D35BF439-0000008673817FC9", +"000000067F00008000000000000000000001-000000067F000080000006C00C00000BFB6E__0000008673817FC9-00000086ED29E361", +"000000067F00008000000000000000000001-000000067F000080000006E00C0000054244__0000008985FD3611-00000089D6B8EE99", +"000000067F00008000000000000000000001-000000067F000080000006E00C00000B6F42__000000890C5B6001-0000008985FD3611", +"000000067F00008000000000000000000001-000000067F000080000006E00C00000C5883__000000887C2DFE59-000000890C5B6001", +"000000067F00008000000000000000000001-000000067F000080000007000C0000053C20__0000008C2045B721-0000008C72843D41", +"000000067F00008000000000000000000001-000000067F000080000007000C00000B2B06__0000008AF67FEC19-0000008BA6803FC9", +"000000067F00008000000000000000000001-000000067F000080000007000C00000BF157__0000008BA6803FC9-0000008C2045B721", +"000000067F00008000000000000000000001-000000067F000080000007200C0000051312__0000008EBC4827C1-0000008F10E3E189", +"000000067F00008000000000000000000001-000000067F000080000007200C00000BA086__0000008E42A19FD1-0000008EBC4827C1", +"000000067F00008000000000000000000001-000000067F000080000007200C00000C58B0__0000008DB277FA49-0000008E42A19FD1", +"000000067F00008000000000000000000001-000000067F000080000007400C000004DF08__000000914B2393B1-00000091A6DD7A79", +"000000067F00008000000000000000000001-000000067F000080000007400C00000FCCA8__00000090D0E5EA29-000000914B2393B1", +"000000067F00008000000000000000000001-000000067F000080000007600C00000544BA__0000009228F7FA79-00000093786F8001", +"000000067F00008000000000000000000001-000000067F000080000007600C0000061028__0000009402435A49-0000009446B52FD1", +"000000067F00008000000000000000000001-000000067F000080000007600C000008C52F__00000093786F8001-0000009402435A49", +"000000067F00008000000000000000000001-000000067F000080000007800C000006D445__00000096AEF27399-00000096E85829C9", +"000000067F00008000000000000000000001-000000067F000080000007800C000007B8BC__00000096193A8001-00000096AEF27399", +"000000067F00008000000000000000000001-000000067F000080000007800C00000CD6B6__000000959635F2A9-00000096193A8001", +"000000067F00008000000000000000000001-000000067F000080000007A00C000004B9A5__0000009921E47AA1-000000997F5D23C9", +"000000067F00008000000000000000000001-000000067F000080000007A00C00000F720F__00000098A7ADFC91-0000009921E47AA1", +"000000067F00008000000000000000000001-000000067F000080000007C00C0000052A9D__0000009BCB4E4461-0000009C1E8CC879", +"000000067F00008000000000000000000001-000000067F000080000007C00C00000A9244__0000009A918DF181-0000009B51A8BBB9", +"000000067F00008000000000000000000001-000000067F000080000007C00C00000BA258__0000009B51A8BBB9-0000009BCB4E4461", +"000000067F00008000000000000000000001-000000067F000080000007E00C0000061ADC__0000009E781A9731-0000009EBBC72771", +"000000067F00008000000000000000000001-000000067F000080000007E00C0000093E3A__0000009DEEE6BFF9-0000009E781A9731", +"000000067F00008000000000000000000001-000000067F000080000007E00C00000B2704__0000009D3E97E549-0000009DEEE6BFF9", +"000000067F00008000000000000000000001-000000067F000080000008200C000005D8FE__000000A1E407F839-000000A323C9E001", +"000000067F00008000000000000000000001-000000067F000080000008600C000010ECC4__000000A539BDE561-000000A5A081B661", +"000000067F00008000000000000000000001-000000067F000080000008A00C0000104A0C__000000A91D97FD49-000000A98AB7EE49", +"000000067F00008000000000000000000001-000000067F000080000008C00C000005DA8C__000000AA2597E9A1-000000AB6533BFD9", +"000000067F00008000000000000000000001-000000067F000080000008E00C00000BC018__000000AC9601EA19-000000AD36393FE9", +"000000067F00008000000000000000000001-000000067F000080000008E0140000003E33__000000AD36393FE9-000000ADB047EAB9", +"000000067F00008000000000000000000001-000000067F000080000008E022000008E3D1__000000AE6FFFE799-000000AF5D587FE1", +"000000067F00008000000000000000000001-000000067F000080000009003800000C5213__000000B0F3EDEAC9-000000B18495C001", +"000000067F00008000000000000000000001-000000067F000080000009200C000009567A__000000B2CA27F641-000000B3AB3B7FC9", +"000000067F00008000000000000000000001-000000067F000080000009600C00000A93FD__000000B6DE71F5F9-000000B79E68FFF9", +"000000067F00008000000000000000000001-000000067F000080000009600C020000000B__000000B79E68FFF9-000000B808718889", +"000000067F00008000000000000000000001-000000067F000080000009A00C00000794DC__000000BC596B5D59-000000BCEF79BE91", +"000000067F00008000000000000000000001-000000067F000080000009A00C00000D6C06__000000BBE607E8F1-000000BC596B5D59", +"000000067F00008000000000000000000001-000000067F000080000009C00C00000B2921__000000BE45CBFBB9-000000BEF5F47FD1", +"000000067F00008000000000000000000001-000000067F000080000009E00C0000050E55__000000C1426D92E1-000000C19744E959", +"000000067F00008000000000000000000001-000000067F000080000009E00C000009FB21__000000BFF8BDFEE9-000000C0C8CA5FF1", +"000000067F00008000000000000000000001-000000067F000080000009E00C00000C0C74__000000C0C8CA5FF1-000000C1426D92E1", +"000000067F00008000000000000000000001-000000067F00008000000A000C000005635B__000000C3E17E01A1-000000C430961E71", +"000000067F00008000000000000000000001-000000067F00008000000A000C00000B8B52__000000C367E48001-000000C3E17E01A1", +"000000067F00008000000000000000000001-000000067F00008000000A000C00000BC072__000000C2C7B1ECC1-000000C367E48001", +"000000067F00008000000000000000000001-000000067F00008000000A200C00000677D8__000000C689AF4AC1-000000C6C87B6329", +"000000067F00008000000000000000000001-000000067F00008000000A200C00000933F0__000000C600A8FFF9-000000C689AF4AC1", +"000000067F00008000000000000000000001-000000067F00008000000A200C00000BBC1F__000000C56021EB29-000000C600A8FFF9", +"000000067F00008000000000000000000001-000000067F00008000000A400C00000C4AE6__000000C80801E859-000000C8993EBFF9", +"000000067F00008000000000000000000001-000000067F00008000000A400C0000107F8F__000000C8993EBFF9-000000C90726D0D9", +"000000067F00008000000000000000000001-000000067F00008000000A600C0000054BFB__000000C986F5F0D9-000000CAD5D7FFF1", +"000000067F00008000000000000000000001-000000067F00008000000A600C00001117CB__000000CAD5D7FFF1-000000CB40C16489", +"000000067F00008000000000000000000001-000000067F00008000000A800C00000BCB46__000000CCB1B9E181-000000CD51344F89", +"000000067F00008000000000000000000001-000000067F00008000000AA00C0000078E97__000000CE6C3FED31-000000CF7DC97FD1", +"000000067F00008000000004E10100000002-000000067F000080000005400C000004BA9C__0000006ACEF98449-0000006C1E7C73C1", +"000000067F00008000000004E10100000002-000000067F000080000005800C0000071854__0000007048B1EC09-00000070E8761431", +"000000067F00008000000004E10200000000-000000067F000080000005600C000004BA9D__0000006D69B48989-0000006EB935F989", +"000000067F00008000000004EB0100000002-000000067F00008000000A400C00000551FC__000000C74849FAE1-000000C80801E859", +"000000067F000080000005200C000006C000-030000000000000000000000000000000002__000000687B67FC58", +"000000067F00008000000520140000028A69-030000000000000000000000000000000002__0000006981B5FDC9-00000069FBEEB099", +"000000067F0000800000052014000002C260-030000000000000000000000000000000002__00000069FBEEB099-0000006A5C770149", +"000000067F000080000005400C0000000000-000000067F000080000005400C0000004000__0000006CF69CD8B0", +"000000067F000080000005400C0000004000-000000067F000080000005400C0000008000__0000006CF69CD8B0", +"000000067F000080000005400C0000008000-000000067F000080000005400C000000C000__0000006CF69CD8B0", +"000000067F000080000005400C000000C000-000000067F000080000005400C0000010000__0000006CF69CD8B0", +"000000067F000080000005400C0000010000-000000067F000080000005400C0000014000__0000006CF69CD8B0", +"000000067F000080000005400C0000014000-000000067F000080000005400C0000018000__0000006CF69CD8B0", +"000000067F000080000005400C0000018000-000000067F000080000005400C000001C000__0000006CF69CD8B0", +"000000067F000080000005400C000001C000-000000067F000080000005400C0000020000__0000006CF69CD8B0", +"000000067F000080000005400C0000020000-000000067F000080000005400C0000024000__0000006CF69CD8B0", +"000000067F000080000005400C0000024000-000000067F000080000005400C0000028000__0000006CF69CD8B0", +"000000067F000080000005400C0000028000-000000067F000080000005400C000002C000__0000006CF69CD8B0", +"000000067F000080000005400C000002C000-000000067F000080000005400C0000030000__0000006CF69CD8B0", +"000000067F000080000005400C0000030000-000000067F000080000005400C0000034000__0000006CF69CD8B0", +"000000067F000080000005400C0000034000-000000067F000080000005400C0000038000__0000006CF69CD8B0", +"000000067F000080000005400C0000038000-000000067F000080000005400C000003C000__0000006CF69CD8B0", +"000000067F000080000005400C000003C000-000000067F000080000005400C0000040000__0000006CF69CD8B0", +"000000067F000080000005400C0000040000-000000067F000080000005400C0000044000__0000006CF69CD8B0", +"000000067F000080000005400C0000044000-000000067F000080000005400C0000048000__0000006CF69CD8B0", +"000000067F000080000005400C0000048000-000000067F000080000005400C000004C000__0000006CF69CD8B0", +"000000067F000080000005400C000004B483-000000067F000080000005400C00000967AD__0000006C98B77D29-0000006CF7781D19", +"000000067F000080000005400C000004C000-000000067F000080000005400C0000050000__0000006CF69CD8B0", +"000000067F000080000005400C0000050000-000000067F000080000005400C0000054000__0000006CF69CD8B0", +"000000067F000080000005400C0000054000-000000067F000080000005400C0000058000__0000006CF69CD8B0", +"000000067F000080000005400C0000054000-030000000000000000000000000000000002__0000006AEF261AF8", +"000000067F000080000005400C0000058000-000000067F000080000005400C000005C000__0000006CF69CD8B0", +"000000067F000080000005400C000005C000-000000067F000080000005400C0000060000__0000006CF69CD8B0", +"000000067F000080000005400C0000060000-000000067F000080000005400C0000064000__0000006CF69CD8B0", +"000000067F000080000005400C0000064000-000000067F000080000005400C0000068000__0000006CF69CD8B0", +"000000067F000080000005400C0000068000-000000067F000080000005400C000006C000__0000006CF69CD8B0", +"000000067F000080000005400C000006C000-000000067F000080000005400C0000070000__0000006CF69CD8B0", +"000000067F000080000005400C0000070000-000000067F000080000005400C0000074000__0000006CF69CD8B0", +"000000067F000080000005400C0000074000-000000067F000080000005400C0000078000__0000006CF69CD8B0", +"000000067F000080000005400C0000078000-000000067F000080000005400C000007C000__0000006CF69CD8B0", +"000000067F000080000005400C000007C000-000000067F000080000005400C0000080000__0000006CF69CD8B0", +"000000067F000080000005400C0000080000-000000067F000080000005400C0000084000__0000006CF69CD8B0", +"000000067F000080000005400C0000084000-000000067F000080000005400C0000088000__0000006CF69CD8B0", +"000000067F000080000005400C0000088000-000000067F000080000005400C000008C000__0000006CF69CD8B0", +"000000067F000080000005400C000008C000-000000067F000080000005400C0000090000__0000006CF69CD8B0", +"000000067F000080000005400C0000090000-000000067F000080000005400C0000094000__0000006CF69CD8B0", +"000000067F000080000005400C0000094000-000000067F000080000005400C0000098000__0000006CF69CD8B0", +"000000067F000080000005400C00000967BA-000000067F000080000005400C00000E2771__0000006C98B77D29-0000006CF7781D19", +"000000067F000080000005400C0000098000-000000067F000080000005400C000009C000__0000006CF69CD8B0", +"000000067F000080000005400C000009C000-000000067F000080000005400C00000A0000__0000006CF69CD8B0", +"000000067F000080000005400C00000A0000-000000067F000080000005400C00000A4000__0000006CF69CD8B0", +"000000067F000080000005400C00000A4000-000000067F000080000005400C00000A8000__0000006CF69CD8B0", +"000000067F000080000005400C00000A8000-000000067F000080000005400C00000AC000__0000006CF69CD8B0", +"000000067F000080000005400C00000AC000-000000067F000080000005400C00000B0000__0000006CF69CD8B0", +"000000067F000080000005400C00000B0000-000000067F000080000005400C00000B4000__0000006CF69CD8B0", +"000000067F000080000005400C00000B4000-000000067F000080000005400C00000B8000__0000006CF69CD8B0", +"000000067F000080000005400C00000B8000-000000067F000080000005400C00000BC000__0000006CF69CD8B0", +"000000067F000080000005400C00000BC000-000000067F000080000005400C00000C0000__0000006CF69CD8B0", +"000000067F000080000005400C00000C0000-000000067F000080000005400C00000C4000__0000006CF69CD8B0", +"000000067F000080000005400C00000C4000-000000067F000080000005400C00000C8000__0000006CF69CD8B0", +"000000067F000080000005400C00000C8000-000000067F000080000005400C00000CC000__0000006CF69CD8B0", +"000000067F000080000005400C00000CC000-000000067F000080000005400C00000D0000__0000006CF69CD8B0", +"000000067F000080000005400C00000D0000-000000067F000080000005400C00000D4000__0000006CF69CD8B0", +"000000067F000080000005400C00000D4000-000000067F000080000005400C00000D8000__0000006CF69CD8B0", +"000000067F000080000005400C00000D8000-000000067F000080000005400C00000DC000__0000006CF69CD8B0", +"000000067F000080000005400C00000DC000-000000067F000080000005400C00000E0000__0000006CF69CD8B0", +"000000067F000080000005400C00000E0000-000000067F000080000005400C00000E4000__0000006CF69CD8B0", +"000000067F000080000005400C00000E277B-000000067F00008000000540140000005B2E__0000006C98B77D29-0000006CF7781D19", +"000000067F000080000005400C00000E4000-000000067F000080000005400C00000E8000__0000006CF69CD8B0", +"000000067F000080000005400C00000E8000-000000067F000080000005400C00000EC000__0000006CF69CD8B0", +"000000067F000080000005400C00000EC000-000000067F000080000005400C00000F0000__0000006CF69CD8B0", +"000000067F000080000005400C00000F0000-000000067F000080000005400C00000F4000__0000006CF69CD8B0", +"000000067F000080000005400C00000F4000-000000067F000080000005400C00000F8000__0000006CF69CD8B0", +"000000067F000080000005400C00000F8000-000000067F000080000005400C00000FC000__0000006CF69CD8B0", +"000000067F000080000005400C00000FC000-000000067F000080000005400C0000100000__0000006CF69CD8B0", +"000000067F000080000005400C0000100000-000000067F000080000005400C0000104000__0000006CF69CD8B0", +"000000067F000080000005400C0000104000-000000067F000080000005400C0000108000__0000006CF69CD8B0", +"000000067F000080000005400C0000108000-000000067F000080000005400C000010C000__0000006CF69CD8B0", +"000000067F000080000005400C000010C000-000000067F000080000005400C0000110000__0000006CF69CD8B0", +"000000067F000080000005400C0000110000-000000067F00008000000540120100000000__0000006CF69CD8B0", +"000000067F000080000005400C0100000000-000000067F00008000000540140000004760__0000006C1E7C73C1-0000006C98B77D29", +"000000067F00008000000540140000004760-000000067F0000800000054014000000BB51__0000006C1E7C73C1-0000006C98B77D29", +"000000067F00008000000540140000005B2F-000000067F0000800000054014000001A04C__0000006C98B77D29-0000006CF7781D19", +"000000067F0000800000054014000000BB51-000000067F00008000000540140000012EFA__0000006C1E7C73C1-0000006C98B77D29", +"000000067F00008000000540140000012EFA-000000067F0000800000054014000001A2E5__0000006C1E7C73C1-0000006C98B77D29", +"000000067F0000800000054014000001A04E-000000067F0000800000054016000000022B__0000006C98B77D29-0000006CF7781D19", +"000000067F0000800000054014000001A2E5-000000067F000080000005401400000216D5__0000006C1E7C73C1-0000006C98B77D29", +"000000067F000080000005401400000216D5-000000067F00008000000540140000028AD9__0000006C1E7C73C1-0000006C98B77D29", +"000000067F00008000000540140000028AD9-030000000000000000000000000000000002__0000006C1E7C73C1-0000006C98B77D29", +"000000067F0000800000054016000000022B-030000000000000000000000000000000002__0000006C98B77D29-0000006CF7781D19", +"000000067F000080000005600C0000000000-000000067F000080000005600C0000004000__0000006DA30DA180", +"000000067F000080000005600C0000000000-000000067F000080000005600C0000004000__0000006F949B7C08", +"000000067F000080000005600C0000004000-000000067F000080000005600C0000008000__0000006DA30DA180", +"000000067F000080000005600C0000004000-000000067F000080000005600C0000008000__0000006F949B7C08", +"000000067F000080000005600C0000008000-000000067F000080000005600C000000C000__0000006DA30DA180", +"000000067F000080000005600C0000008000-000000067F000080000005600C000000C000__0000006F949B7C08", +"000000067F000080000005600C0000008077-000000067F000080000005600C00000117CE__0000006CF7781D19-0000006D69B48989", +"000000067F000080000005600C000000C000-000000067F000080000005600C0000010000__0000006DA30DA180", +"000000067F000080000005600C000000C000-000000067F000080000005600C0000010000__0000006F949B7C08", +"000000067F000080000005600C0000010000-000000067F000080000005600C0000014000__0000006DA30DA180", +"000000067F000080000005600C0000010000-000000067F000080000005600C0000014000__0000006F949B7C08", +"000000067F000080000005600C00000117CE-000000067F000080000005600C000001AF0A__0000006CF7781D19-0000006D69B48989", +"000000067F000080000005600C0000014000-000000067F000080000005600C0000018000__0000006DA30DA180", +"000000067F000080000005600C0000014000-000000067F000080000005600C0000018000__0000006F949B7C08", +"000000067F000080000005600C0000018000-000000067F000080000005600C000001C000__0000006DA30DA180", +"000000067F000080000005600C0000018000-000000067F000080000005600C000001C000__0000006F949B7C08", +"000000067F000080000005600C000001AF0A-000000067F000080000005600C0000024670__0000006CF7781D19-0000006D69B48989", +"000000067F000080000005600C000001C000-000000067F000080000005600C0000020000__0000006DA30DA180", +"000000067F000080000005600C000001C000-000000067F000080000005600C0000020000__0000006F949B7C08", +"000000067F000080000005600C0000020000-000000067F000080000005600C0000024000__0000006DA30DA180", +"000000067F000080000005600C0000020000-000000067F000080000005600C0000024000__0000006F949B7C08", +"000000067F000080000005600C0000024000-000000067F000080000005600C0000028000__0000006DA30DA180", +"000000067F000080000005600C0000024000-000000067F000080000005600C0000028000__0000006F949B7C08", +"000000067F000080000005600C0000024670-000000067F000080000005600C000002DDD6__0000006CF7781D19-0000006D69B48989", +"000000067F000080000005600C0000028000-000000067F000080000005600C000002C000__0000006DA30DA180", +"000000067F000080000005600C0000028000-000000067F000080000005600C000002C000__0000006F949B7C08", +"000000067F000080000005600C000002C000-000000067F000080000005600C0000030000__0000006DA30DA180", +"000000067F000080000005600C000002C000-000000067F000080000005600C0000030000__0000006F949B7C08", +"000000067F000080000005600C000002DDD6-000000067F000080000005600C000003752A__0000006CF7781D19-0000006D69B48989", +"000000067F000080000005600C0000030000-000000067F000080000005600C0000034000__0000006DA30DA180", +"000000067F000080000005600C0000030000-000000067F000080000005600C0000034000__0000006F949B7C08", +"000000067F000080000005600C0000034000-000000067F000080000005600C0000038000__0000006DA30DA180", +"000000067F000080000005600C0000034000-000000067F000080000005600C0000038000__0000006F949B7C08", +"000000067F000080000005600C000003752A-000000067F000080000005600C0000040C90__0000006CF7781D19-0000006D69B48989", +"000000067F000080000005600C0000038000-000000067F000080000005600C000003C000__0000006DA30DA180", +"000000067F000080000005600C0000038000-000000067F000080000005600C000003C000__0000006F949B7C08", +"000000067F000080000005600C000003C000-000000067F000080000005600C0000040000__0000006DA30DA180", +"000000067F000080000005600C000003C000-000000067F000080000005600C0000040000__0000006F949B7C08", +"000000067F000080000005600C0000040000-000000067F000080000005600C0000044000__0000006DA30DA180", +"000000067F000080000005600C0000040000-000000067F000080000005600C0000044000__0000006F949B7C08", +"000000067F000080000005600C0000040C90-030000000000000000000000000000000002__0000006CF7781D19-0000006D69B48989", +"000000067F000080000005600C0000044000-000000067F000080000005600C0000048000__0000006DA30DA180", +"000000067F000080000005600C0000044000-000000067F000080000005600C0000048000__0000006F949B7C08", +"000000067F000080000005600C0000048000-000000067F000080000005600C000004C000__0000006DA30DA180", +"000000067F000080000005600C0000048000-000000067F000080000005600C000004C000__0000006F949B7C08", +"000000067F000080000005600C0000048643-000000067F000080000005600C00000907F3__0000006F3370DD59-0000006F95E72491", +"000000067F000080000005600C000004BA9D-000000067F000080000005600C00000551D2__0000006D69B48989-0000006EB935F989", +"000000067F000080000005600C000004C000-000000067F000080000005600C0000050000__0000006DA30DA180", +"000000067F000080000005600C000004C000-000000067F000080000005600C0000050000__0000006F949B7C08", +"000000067F000080000005600C0000050000-000000067F000080000005600C0000054000__0000006DA30DA180", +"000000067F000080000005600C0000050000-000000067F000080000005600C0000054000__0000006F949B7C08", +"000000067F000080000005600C0000054000-000000067F000080000005600C0000058000__0000006DA30DA180", +"000000067F000080000005600C0000054000-000000067F000080000005600C0000058000__0000006F949B7C08", +"000000067F000080000005600C00000551D2-000000067F000080000005600C000005E90B__0000006D69B48989-0000006EB935F989", +"000000067F000080000005600C0000058000-000000067F000080000005600C000005C000__0000006DA30DA180", +"000000067F000080000005600C0000058000-000000067F000080000005600C000005C000__0000006F949B7C08", +"000000067F000080000005600C000005C000-000000067F000080000005600C0000060000__0000006DA30DA180", +"000000067F000080000005600C000005C000-000000067F000080000005600C0000060000__0000006F949B7C08", +"000000067F000080000005600C000005E90B-000000067F000080000005600C000006802B__0000006D69B48989-0000006EB935F989", +"000000067F000080000005600C0000060000-000000067F000080000005600C0000064000__0000006DA30DA180", +"000000067F000080000005600C0000060000-000000067F000080000005600C0000064000__0000006F949B7C08", +"000000067F000080000005600C0000064000-000000067F000080000005600C0000068000__0000006F949B7C08", +"000000067F000080000005600C0000064000-030000000000000000000000000000000002__0000006DA30DA180", +"000000067F000080000005600C0000068000-000000067F000080000005600C000006C000__0000006F949B7C08", +"000000067F000080000005600C000006802B-000000067F000080000005600C0000071782__0000006D69B48989-0000006EB935F989", +"000000067F000080000005600C000006C000-000000067F000080000005600C0000070000__0000006F949B7C08", +"000000067F000080000005600C0000070000-000000067F000080000005600C0000074000__0000006F949B7C08", +"000000067F000080000005600C0000071782-000000067F000080000005600C000007AEE8__0000006D69B48989-0000006EB935F989", +"000000067F000080000005600C0000074000-000000067F000080000005600C0000078000__0000006F949B7C08", +"000000067F000080000005600C0000078000-000000067F000080000005600C000007C000__0000006F949B7C08", +"000000067F000080000005600C000007AEE8-000000067F000080000005600C000008460B__0000006D69B48989-0000006EB935F989", +"000000067F000080000005600C000007C000-000000067F000080000005600C0000080000__0000006F949B7C08", +"000000067F000080000005600C0000080000-000000067F000080000005600C0000084000__0000006F949B7C08", +"000000067F000080000005600C0000084000-000000067F000080000005600C0000088000__0000006F949B7C08", +"000000067F000080000005600C000008460B-000000067F000080000005600C000008DD71__0000006D69B48989-0000006EB935F989", +"000000067F000080000005600C0000088000-000000067F000080000005600C000008C000__0000006F949B7C08", +"000000067F000080000005600C000008C000-000000067F000080000005600C0000090000__0000006F949B7C08", +"000000067F000080000005600C000008DD71-000000067F000080000005600C00000974D7__0000006D69B48989-0000006EB935F989", +"000000067F000080000005600C0000090000-000000067F000080000005600C0000094000__0000006F949B7C08", +"000000067F000080000005600C00000907F5-000000067F000080000005600C00000D90E0__0000006F3370DD59-0000006F95E72491", +"000000067F000080000005600C0000094000-000000067F000080000005600C0000098000__0000006F949B7C08", +"000000067F000080000005600C00000974D7-000000067F000080000005600C00000A0C0B__0000006D69B48989-0000006EB935F989", +"000000067F000080000005600C0000098000-000000067F000080000005600C000009C000__0000006F949B7C08", +"000000067F000080000005600C000009C000-000000067F000080000005600C00000A0000__0000006F949B7C08", +"000000067F000080000005600C00000A0000-000000067F000080000005600C00000A4000__0000006F949B7C08", +"000000067F000080000005600C00000A0C0B-000000067F000080000005600C00000AA371__0000006D69B48989-0000006EB935F989", +"000000067F000080000005600C00000A4000-000000067F000080000005600C00000A8000__0000006F949B7C08", +"000000067F000080000005600C00000A8000-000000067F000080000005600C00000AC000__0000006F949B7C08", +"000000067F000080000005600C00000AA371-000000067F000080000005600C00000B3AD7__0000006D69B48989-0000006EB935F989", +"000000067F000080000005600C00000AC000-000000067F000080000005600C00000B0000__0000006F949B7C08", +"000000067F000080000005600C00000B0000-000000067F000080000005600C00000B4000__0000006F949B7C08", +"000000067F000080000005600C00000B3AD7-000000067F000080000005600C00000BD20B__0000006D69B48989-0000006EB935F989", +"000000067F000080000005600C00000B4000-000000067F000080000005600C00000B8000__0000006F949B7C08", +"000000067F000080000005600C00000B8000-000000067F000080000005600C00000BC000__0000006F949B7C08", +"000000067F000080000005600C00000BC000-000000067F000080000005600C00000C0000__0000006F949B7C08", +"000000067F000080000005600C00000BD20B-000000067F000080000005600C00000C6932__0000006D69B48989-0000006EB935F989", +"000000067F000080000005600C00000C0000-000000067F000080000005600C00000C4000__0000006F949B7C08", +"000000067F000080000005600C00000C4000-000000067F000080000005600C00000C8000__0000006F949B7C08", +"000000067F000080000005600C00000C6932-000000067F000080000005600C00000D0098__0000006D69B48989-0000006EB935F989", +"000000067F000080000005600C00000C8000-000000067F000080000005600C00000CC000__0000006F949B7C08", +"000000067F000080000005600C00000CC000-000000067F000080000005600C00000D0000__0000006F949B7C08", +"000000067F000080000005600C00000D0000-000000067F000080000005600C00000D4000__0000006F949B7C08", +"000000067F000080000005600C00000D0098-000000067F000080000005600C00000D97FE__0000006D69B48989-0000006EB935F989", +"000000067F000080000005600C00000D4000-000000067F000080000005600C00000D8000__0000006F949B7C08", +"000000067F000080000005600C00000D8000-000000067F000080000005600C00000DC000__0000006F949B7C08", +"000000067F000080000005600C00000D90F8-000000067F00008000000560140000002A9A__0000006F3370DD59-0000006F95E72491", +"000000067F000080000005600C00000D97FE-000000067F000080000005600C00000E2F0B__0000006D69B48989-0000006EB935F989", +"000000067F000080000005600C00000DC000-000000067F000080000005600C00000E0000__0000006F949B7C08", +"000000067F000080000005600C00000E0000-000000067F000080000005600C00000E4000__0000006F949B7C08", +"000000067F000080000005600C00000E2F0B-000000067F000080000005600C00000EC671__0000006D69B48989-0000006EB935F989", +"000000067F000080000005600C00000E4000-000000067F000080000005600C00000E8000__0000006F949B7C08", +"000000067F000080000005600C00000E8000-000000067F000080000005600C00000EC000__0000006F949B7C08", +"000000067F000080000005600C00000EC000-000000067F000080000005600C00000F0000__0000006F949B7C08", +"000000067F000080000005600C00000EC671-000000067F000080000005600C00000F5D9F__0000006D69B48989-0000006EB935F989", +"000000067F000080000005600C00000F0000-000000067F000080000005600C00000F4000__0000006F949B7C08", +"000000067F000080000005600C00000F4000-000000067F000080000005600C00000F8000__0000006F949B7C08", +"000000067F000080000005600C00000F5D9F-000000067F000080000005600C00000FF505__0000006D69B48989-0000006EB935F989", +"000000067F000080000005600C00000F8000-000000067F000080000005600C00000FC000__0000006F949B7C08", +"000000067F000080000005600C00000FC000-000000067F000080000005600C0000100000__0000006F949B7C08", +"000000067F000080000005600C00000FF505-000000067F000080000005600C0000108C10__0000006D69B48989-0000006EB935F989", +"000000067F000080000005600C0000100000-000000067F000080000005600C0000104000__0000006F949B7C08", +"000000067F000080000005600C0000100001-000000067F000080000005600C0000111BF7__0000006EB935F989-0000006F3370DD59", +"000000067F000080000005600C0000104000-000000067F000080000005600C0000108000__0000006F949B7C08", +"000000067F000080000005600C0000108000-000000067F000080000005600C000010C000__0000006F949B7C08", +"000000067F000080000005600C0000108C10-000000067F000080000005600C0100000000__0000006D69B48989-0000006EB935F989", +"000000067F000080000005600C000010C000-000000067F000080000005600C0000110000__0000006F949B7C08", +"000000067F000080000005600C0000110000-000000067F00008000000560120100000000__0000006F949B7C08", +"000000067F000080000005600C0000111BF7-000000067F0000800000056014000000451D__0000006EB935F989-0000006F3370DD59", +"000000067F00008000000560140000002A9A-000000067F00008000000560140000016143__0000006F3370DD59-0000006F95E72491", +"000000067F0000800000056014000000451D-000000067F0000800000056014000000B9A7__0000006EB935F989-0000006F3370DD59", +"000000067F0000800000056014000000B9A7-000000067F00008000000560140000012DE3__0000006EB935F989-0000006F3370DD59", +"000000067F00008000000560140000012DE3-000000067F0000800000056014000001A213__0000006EB935F989-0000006F3370DD59", +"000000067F00008000000560140000016143-000000067F00008000000560140000029CE0__0000006F3370DD59-0000006F95E72491", +"000000067F0000800000056014000001A213-000000067F00008000000560140000021666__0000006EB935F989-0000006F3370DD59", +"000000067F00008000000560140000021666-000000067F00008000000560140000028A7C__0000006EB935F989-0000006F3370DD59", +"000000067F00008000000560140000028A7C-030000000000000000000000000000000002__0000006EB935F989-0000006F3370DD59", +"000000067F00008000000560140000029CE2-030000000000000000000000000000000002__0000006F3370DD59-0000006F95E72491", +"000000067F000080000005800C0000000000-000000067F000080000005800C0000004000__0000006FAFE25518", +"000000067F000080000005800C0000000000-000000067F000080000005800C0000004000__00000071F15CF6B0", +"000000067F000080000005800C0000004000-000000067F000080000005800C0000008000__0000006FAFE25518", +"000000067F000080000005800C0000004000-000000067F000080000005800C0000008000__00000071F15CF6B0", +"000000067F000080000005800C0000007A49-030000000000000000000000000000000002__0000006F95E72491-0000006FA8EDF3B9", +"000000067F000080000005800C0000008000-000000067F000080000005800C000000C000__0000006FAFE25518", +"000000067F000080000005800C0000008000-000000067F000080000005800C000000C000__0000007168C9DFF8", +"000000067F000080000005800C0000008000-000000067F000080000005800C000000C000__00000072377CDB60", +"000000067F000080000005800C00000096DE-000000067F000080000005800C0000012E0C__0000006FA8EDF3B9-0000007048B1EC09", +"000000067F000080000005800C000000C000-000000067F000080000005800C0000010000__0000007168C9DFF8", +"000000067F000080000005800C000000C000-000000067F000080000005800C0000010000__00000072377CDB60", +"000000067F000080000005800C000000C000-030000000000000000000000000000000002__0000006FAFE25518", +"000000067F000080000005800C0000010000-000000067F000080000005800C0000014000__0000007168C9DFF8", +"000000067F000080000005800C0000010000-000000067F000080000005800C0000014000__00000072377CDB60", +"000000067F000080000005800C0000012E0C-000000067F000080000005800C000001C572__0000006FA8EDF3B9-0000007048B1EC09", +"000000067F000080000005800C0000014000-000000067F000080000005800C0000018000__0000007168C9DFF8", +"000000067F000080000005800C0000014000-000000067F000080000005800C0000018000__00000072377CDB60", +"000000067F000080000005800C0000018000-000000067F000080000005800C000001C000__0000007168C9DFF8", +"000000067F000080000005800C0000018000-000000067F000080000005800C000001C000__00000072377CDB60", +"000000067F000080000005800C000001C000-000000067F000080000005800C0000020000__0000007168C9DFF8", +"000000067F000080000005800C000001C000-000000067F000080000005800C0000020000__00000072377CDB60", +"000000067F000080000005800C000001C572-000000067F000080000005800C0000025CD8__0000006FA8EDF3B9-0000007048B1EC09", +"000000067F000080000005800C0000020000-000000067F000080000005800C0000024000__0000007168C9DFF8", +"000000067F000080000005800C0000020000-000000067F000080000005800C0000024000__00000072377CDB60", +"000000067F000080000005800C0000024000-000000067F000080000005800C0000028000__0000007168C9DFF8", +"000000067F000080000005800C0000024000-000000067F000080000005800C0000028000__00000072377CDB60", +"000000067F000080000005800C0000025CD8-000000067F000080000005800C000002F40B__0000006FA8EDF3B9-0000007048B1EC09", +"000000067F000080000005800C0000028000-000000067F000080000005800C000002C000__0000007168C9DFF8", +"000000067F000080000005800C0000028000-000000067F000080000005800C000002C000__00000072377CDB60", +"000000067F000080000005800C000002C000-000000067F000080000005800C0000030000__0000007168C9DFF8", +"000000067F000080000005800C000002C000-000000067F000080000005800C0000030000__00000072377CDB60", +"000000067F000080000005800C000002F40B-000000067F000080000005800C0000038B1E__0000006FA8EDF3B9-0000007048B1EC09", +"000000067F000080000005800C0000030000-000000067F000080000005800C0000034000__0000007168C9DFF8", +"000000067F000080000005800C0000030000-000000067F000080000005800C0000034000__00000072377CDB60", +"000000067F000080000005800C0000034000-000000067F000080000005800C0000038000__0000007168C9DFF8", +"000000067F000080000005800C0000034000-000000067F000080000005800C0000038000__00000072377CDB60", +"000000067F000080000005800C0000038000-000000067F000080000005800C000003C000__0000007168C9DFF8", +"000000067F000080000005800C0000038000-000000067F000080000005800C000003C000__00000072377CDB60", +"000000067F000080000005800C0000038B1E-000000067F000080000005800C0000042284__0000006FA8EDF3B9-0000007048B1EC09", +"000000067F000080000005800C000003C000-000000067F000080000005800C0000040000__0000007168C9DFF8", +"000000067F000080000005800C000003C000-000000067F000080000005800C0000040000__00000072377CDB60", +"000000067F000080000005800C0000040000-000000067F000080000005800C0000044000__0000007168C9DFF8", +"000000067F000080000005800C0000040000-000000067F000080000005800C0000044000__00000072377CDB60", +"000000067F000080000005800C0000042284-000000067F000080000005800C000004B9EA__0000006FA8EDF3B9-0000007048B1EC09", +"000000067F000080000005800C0000044000-000000067F000080000005800C0000048000__0000007168C9DFF8", +"000000067F000080000005800C0000044000-000000067F000080000005800C0000048000__00000072377CDB60", +"000000067F000080000005800C0000048000-000000067F000080000005800C000004C000__0000007168C9DFF8", +"000000067F000080000005800C0000048000-000000067F000080000005800C000004C000__00000072377CDB60", +"000000067F000080000005800C000004B9EA-000000067F000080000005800C000005510B__0000006FA8EDF3B9-0000007048B1EC09", +"000000067F000080000005800C000004C000-000000067F000080000005800C0000050000__0000007168C9DFF8", +"000000067F000080000005800C000004C000-000000067F000080000005800C0000050000__00000072377CDB60", +"000000067F000080000005800C0000050000-000000067F000080000005800C0000054000__0000007168C9DFF8", +"000000067F000080000005800C0000050000-000000067F000080000005800C0000054000__00000072377CDB60", +"000000067F000080000005800C0000054000-000000067F000080000005800C0000058000__0000007168C9DFF8", +"000000067F000080000005800C0000054000-000000067F000080000005800C0000058000__00000072377CDB60", +"000000067F000080000005800C000005510B-000000067F000080000005800C000005E871__0000006FA8EDF3B9-0000007048B1EC09", +"000000067F000080000005800C0000058000-000000067F000080000005800C000005C000__0000007168C9DFF8", +"000000067F000080000005800C0000058000-000000067F000080000005800C000005C000__00000072377CDB60", +"000000067F000080000005800C000005C000-000000067F000080000005800C0000060000__0000007168C9DFF8", +"000000067F000080000005800C000005C000-000000067F000080000005800C0000060000__00000072377CDB60", +"000000067F000080000005800C000005CF08-000000067F000080000005800C00000BAF56__00000071F21624D1-000000723877FF21", +"000000067F000080000005800C000005E871-000000067F000080000005800C0000067F8B__0000006FA8EDF3B9-0000007048B1EC09", +"000000067F000080000005800C0000060000-000000067F000080000005800C0000064000__0000007168C9DFF8", +"000000067F000080000005800C0000060000-000000067F000080000005800C0000064000__00000072377CDB60", +"000000067F000080000005800C0000064000-000000067F000080000005800C0000068000__0000007168C9DFF8", +"000000067F000080000005800C0000064000-000000067F000080000005800C0000068000__00000072377CDB60", +"000000067F000080000005800C0000067F8B-000000067F000080000005800C0100000000__0000006FA8EDF3B9-0000007048B1EC09", +"000000067F000080000005800C0000068000-000000067F000080000005800C000006C000__0000007168C9DFF8", +"000000067F000080000005800C0000068000-000000067F000080000005800C000006C000__00000072377CDB60", +"000000067F000080000005800C000006C000-000000067F000080000005800C0000070000__0000007168C9DFF8", +"000000067F000080000005800C000006C000-000000067F000080000005800C0000070000__00000072377CDB60", +"000000067F000080000005800C0000070000-000000067F000080000005800C0000074000__0000007168C9DFF8", +"000000067F000080000005800C0000070000-000000067F000080000005800C0000074000__00000072377CDB60", +"000000067F000080000005800C0000071854-000000067F000080000005800C000007AFBA__0000007048B1EC09-00000070E8761431", +"000000067F000080000005800C0000074000-000000067F000080000005800C0000078000__0000007168C9DFF8", +"000000067F000080000005800C0000074000-000000067F000080000005800C0000078000__00000072377CDB60", +"000000067F000080000005800C0000078000-000000067F000080000005800C000007C000__0000007168C9DFF8", +"000000067F000080000005800C0000078000-000000067F000080000005800C000007C000__00000072377CDB60", +"000000067F000080000005800C000007AFBA-000000067F000080000005800C0000084720__0000007048B1EC09-00000070E8761431", +"000000067F000080000005800C000007C000-000000067F000080000005800C0000080000__0000007168C9DFF8", +"000000067F000080000005800C000007C000-000000067F000080000005800C0000080000__00000072377CDB60", +"000000067F000080000005800C0000080000-000000067F000080000005800C0000084000__0000007168C9DFF8", +"000000067F000080000005800C0000080000-000000067F000080000005800C0000084000__00000072377CDB60", +"000000067F000080000005800C0000084000-000000067F000080000005800C0000088000__0000007168C9DFF8", +"000000067F000080000005800C0000084000-000000067F000080000005800C0000088000__00000072377CDB60", +"000000067F000080000005800C0000084720-000000067F000080000005800C000008DE86__0000007048B1EC09-00000070E8761431", +"000000067F000080000005800C0000088000-000000067F000080000005800C000008C000__0000007168C9DFF8", +"000000067F000080000005800C0000088000-000000067F000080000005800C000008C000__00000072377CDB60", +"000000067F000080000005800C000008C000-000000067F000080000005800C0000090000__0000007168C9DFF8", +"000000067F000080000005800C000008C000-000000067F000080000005800C0000090000__00000072377CDB60", +"000000067F000080000005800C000008DE86-000000067F000080000005800C00000975A6__0000007048B1EC09-00000070E8761431", +"000000067F000080000005800C0000090000-000000067F000080000005800C0000094000__0000007168C9DFF8", +"000000067F000080000005800C0000090000-000000067F000080000005800C0000094000__00000072377CDB60", +"000000067F000080000005800C0000094000-000000067F000080000005800C0000098000__0000007168C9DFF8", +"000000067F000080000005800C0000094000-000000067F000080000005800C0000098000__00000072377CDB60", +"000000067F000080000005800C00000975A6-000000067F000080000005800C00000A0D0C__0000007048B1EC09-00000070E8761431", +"000000067F000080000005800C0000098000-000000067F000080000005800C000009C000__0000007168C9DFF8", +"000000067F000080000005800C0000098000-000000067F000080000005800C000009C000__00000072377CDB60", +"000000067F000080000005800C000009C000-000000067F000080000005800C00000A0000__0000007168C9DFF8", +"000000067F000080000005800C000009C000-000000067F000080000005800C00000A0000__00000072377CDB60", +"000000067F000080000005800C000009D78D-000000067F000080000005800C0200000018__000000716A103FC9-00000071F21624D1", +"000000067F000080000005800C00000A0000-000000067F000080000005800C00000A4000__0000007168C9DFF8", +"000000067F000080000005800C00000A0000-000000067F000080000005800C00000A4000__00000072377CDB60", +"000000067F000080000005800C00000A0D0C-000000067F000080000005800C00000AA472__0000007048B1EC09-00000070E8761431", +"000000067F000080000005800C00000A4000-000000067F000080000005800C00000A8000__0000007168C9DFF8", +"000000067F000080000005800C00000A4000-000000067F000080000005800C00000A8000__00000072377CDB60", +"000000067F000080000005800C00000A8000-000000067F000080000005800C00000AC000__0000007168C9DFF8", +"000000067F000080000005800C00000A8000-000000067F000080000005800C00000AC000__00000072377CDB60", +"000000067F000080000005800C00000AA472-000000067F000080000005800C00000B3BB4__0000007048B1EC09-00000070E8761431", +"000000067F000080000005800C00000AC000-000000067F000080000005800C00000B0000__0000007168C9DFF8", +"000000067F000080000005800C00000AC000-000000067F000080000005800C00000B0000__00000072377CDB60", +"000000067F000080000005800C00000B0000-000000067F000080000005800C00000B4000__0000007168C9DFF8", +"000000067F000080000005800C00000B0000-000000067F000080000005800C00000B4000__00000072377CDB60", +"000000067F000080000005800C00000B3BB4-000000067F000080000005800C00000BD30B__0000007048B1EC09-00000070E8761431", +"000000067F000080000005800C00000B4000-000000067F000080000005800C00000B8000__0000007168C9DFF8", +"000000067F000080000005800C00000B4000-000000067F000080000005800C00000B8000__00000072377CDB60", +"000000067F000080000005800C00000B8000-000000067F000080000005800C00000BC000__0000007168C9DFF8", +"000000067F000080000005800C00000B8000-000000067F000080000005800C00000BC000__00000072377CDB60", +"000000067F000080000005800C00000BAF5F-000000067F000080000005801400000007C1__00000071F21624D1-000000723877FF21", +"000000067F000080000005800C00000BC000-000000067F000080000005800C00000C0000__0000007168C9DFF8", +"000000067F000080000005800C00000BC000-000000067F000080000005800C00000C0000__00000072377CDB60", +"000000067F000080000005800C00000BD30B-000000067F000080000005800C00000C6A32__0000007048B1EC09-00000070E8761431", +"000000067F000080000005800C00000C0000-000000067F000080000005800C00000C4000__0000007168C9DFF8", +"000000067F000080000005800C00000C0000-000000067F000080000005800C00000C4000__00000072377CDB60", +"000000067F000080000005800C00000C4000-000000067F000080000005800C00000C8000__0000007168C9DFF8", +"000000067F000080000005800C00000C4000-000000067F000080000005800C00000C8000__00000072377CDB60", +"000000067F000080000005800C00000C6A32-000000067F000080000005800C0100000000__0000007048B1EC09-00000070E8761431", +"000000067F000080000005800C00000C8000-000000067F000080000005800C00000CC000__0000007168C9DFF8", +"000000067F000080000005800C00000C8000-000000067F000080000005800C00000CC000__00000072377CDB60", +"000000067F000080000005800C00000CC000-000000067F000080000005800C00000D0000__0000007168C9DFF8", +"000000067F000080000005800C00000CC000-000000067F000080000005800C00000D0000__00000072377CDB60", +"000000067F000080000005800C00000CDE2D-000000067F000080000005800C00000D754D__00000070E8761431-000000716A103FC9", +"000000067F000080000005800C00000D0000-000000067F000080000005800C00000D4000__0000007168C9DFF8", +"000000067F000080000005800C00000D0000-000000067F000080000005800C00000D4000__00000072377CDB60", +"000000067F000080000005800C00000D4000-000000067F000080000005800C00000D8000__0000007168C9DFF8", +"000000067F000080000005800C00000D4000-000000067F000080000005800C00000D8000__00000072377CDB60", +"000000067F000080000005800C00000D754D-000000067F000080000005800C00000E0CB3__00000070E8761431-000000716A103FC9", +"000000067F000080000005800C00000D8000-000000067F000080000005800C00000DC000__0000007168C9DFF8", +"000000067F000080000005800C00000D8000-000000067F000080000005800C00000DC000__00000072377CDB60", +"000000067F000080000005800C00000DC000-000000067F000080000005800C00000E0000__0000007168C9DFF8", +"000000067F000080000005800C00000DC000-000000067F000080000005800C00000E0000__00000072377CDB60", +"000000067F000080000005800C00000E0000-000000067F000080000005800C00000E4000__0000007168C9DFF8", +"000000067F000080000005800C00000E0000-000000067F000080000005800C00000E4000__00000072377CDB60", +"000000067F000080000005800C00000E0CB3-000000067F000080000005800C00000EA409__00000070E8761431-000000716A103FC9", +"000000067F000080000005800C00000E4000-000000067F000080000005800C00000E8000__0000007168C9DFF8", +"000000067F000080000005800C00000E4000-000000067F000080000005800C00000E8000__00000072377CDB60", +"000000067F000080000005800C00000E8000-000000067F000080000005800C00000EC000__0000007168C9DFF8", +"000000067F000080000005800C00000E8000-000000067F000080000005800C00000EC000__00000072377CDB60", +"000000067F000080000005800C00000EA409-000000067F000080000005800C00000F3B4B__00000070E8761431-000000716A103FC9", +"000000067F000080000005800C00000EC000-000000067F000080000005800C00000F0000__0000007168C9DFF8", +"000000067F000080000005800C00000EC000-000000067F000080000005800C00000F0000__00000072377CDB60", +"000000067F000080000005800C00000F0000-000000067F000080000005800C00000F4000__0000007168C9DFF8", +"000000067F000080000005800C00000F0000-000000067F000080000005800C00000F4000__00000072377CDB60", +"000000067F000080000005800C00000F3B4B-000000067F000080000005800C00000FD2B1__00000070E8761431-000000716A103FC9", +"000000067F000080000005800C00000F4000-000000067F000080000005800C00000F8000__0000007168C9DFF8", +"000000067F000080000005800C00000F4000-000000067F000080000005800C00000F8000__00000072377CDB60", +"000000067F000080000005800C00000F8000-000000067F000080000005800C00000FC000__0000007168C9DFF8", +"000000067F000080000005800C00000F8000-000000067F000080000005800C00000FC000__00000072377CDB60", +"000000067F000080000005800C00000FC000-000000067F000080000005800C0000100000__0000007168C9DFF8", +"000000067F000080000005800C00000FC000-000000067F000080000005800C0000100000__00000072377CDB60", +"000000067F000080000005800C00000FD2B1-000000067F000080000005800C00001069D8__00000070E8761431-000000716A103FC9", +"000000067F000080000005800C0000100000-000000067F000080000005800C0000104000__0000007168C9DFF8", +"000000067F000080000005800C0000100000-000000067F000080000005800C0000104000__00000072377CDB60", +"000000067F000080000005800C0000104000-000000067F000080000005800C0000108000__0000007168C9DFF8", +"000000067F000080000005800C0000104000-000000067F000080000005800C0000108000__00000072377CDB60", +"000000067F000080000005800C00001069D8-000000067F000080000005800C000011010C__00000070E8761431-000000716A103FC9", +"000000067F000080000005800C0000108000-000000067F000080000005800C000010C000__0000007168C9DFF8", +"000000067F000080000005800C0000108000-000000067F000080000005800C000010C000__00000072377CDB60", +"000000067F000080000005800C000010C000-000000067F000080000005800C0000110000__0000007168C9DFF8", +"000000067F000080000005800C000010C000-000000067F000080000005800C0000110000__00000072377CDB60", +"000000067F000080000005800C0000110000-000000067F00008000000580120100000000__00000072377CDB60", +"000000067F000080000005800C0000110000-030000000000000000000000000000000002__0000007168C9DFF8", +"000000067F000080000005800C000011010C-01000000000000000100000002000000001E__00000070E8761431-000000716A103FC9", +"000000067F000080000005800C0200000018-000000067F000080000005801400000059BE__000000716A103FC9-00000071F21624D1", +"000000067F00008000000580140000000000-000000067F00008000000580140000004000__00000072377CDB60", +"000000067F000080000005801400000007C3-000000067F00008000000580140000020462__00000071F21624D1-000000723877FF21", +"000000067F00008000000580140000004000-000000067F00008000000580140000008000__00000072377CDB60", +"000000067F000080000005801400000059BE-000000067F0000800000058014000000BF38__000000716A103FC9-00000071F21624D1", +"000000067F00008000000580140000008000-000000067F0000800000058014000000C000__00000072377CDB60", +"000000067F0000800000058014000000BF38-000000067F00008000000580140000012530__000000716A103FC9-00000071F21624D1", +"000000067F0000800000058014000000C000-000000067F00008000000580140000010000__00000072377CDB60", +"000000067F00008000000580140000010000-000000067F00008000000580140000014000__00000072377CDB60", +"000000067F00008000000580140000012530-000000067F00008000000580140000018B50__000000716A103FC9-00000071F21624D1", +"000000067F00008000000580140000014000-000000067F00008000000580140000018000__00000072377CDB60", +"000000067F00008000000580140000018000-000000067F0000800000058014000001C000__00000072377CDB60", +"000000067F00008000000580140000018B50-000000067F0000800000058014000001F0D3__000000716A103FC9-00000071F21624D1", +"000000067F0000800000058014000001C000-000000067F00008000000580140000020000__00000072377CDB60", +"000000067F0000800000058014000001F0D3-000000067F0000800000058014000002562B__000000716A103FC9-00000071F21624D1", +"000000067F00008000000580140000020000-000000067F00008000000580140000024000__00000072377CDB60", +"000000067F00008000000580140000020464-030000000000000000000000000000000002__00000071F21624D1-000000723877FF21", +"000000067F00008000000580140000024000-000000067F00008000000580140000028000__00000072377CDB60", +"000000067F0000800000058014000002562B-000000067F0000800000058014000002BC37__000000716A103FC9-00000071F21624D1", +"000000067F00008000000580140000028000-000000067F0000800000058014000002C000__00000072377CDB60", +"000000067F0000800000058014000002BC37-030000000000000000000000000000000002__000000716A103FC9-00000071F21624D1", +"000000067F0000800000058014000002C000-030000000000000000000000000000000002__00000072377CDB60", +"000000067F000080000005A00C0000007614-000000067F000080000005A00C000000ED44__000000723877FF21-00000072A0D7CEA1", +"000000067F000080000005A00C000000ED44-000000067F000080000005A00C0000016337__000000723877FF21-00000072A0D7CEA1", +"000000067F000080000005A00C0000016337-000000067F000080000005A014000000148C__000000723877FF21-00000072A0D7CEA1", +"000000067F000080000005A014000000148C-000000067F000080000005C00C0000003207__000000723877FF21-00000072A0D7CEA1", +"000000067F000080000005C00C0000003207-000000067F000080000005C00C000000C96D__000000723877FF21-00000072A0D7CEA1", +"000000067F000080000005C00C000000C96D-030000000000000000000000000000000002__000000723877FF21-00000072A0D7CEA1", +"000000067F000080000005C00C0000016516-000000067F000080000005C0140000001694__00000072A0D7CEA1-0000007318DDE691", +"000000067F000080000005C0140000001694-000000067F000080000005E00C000000360C__00000072A0D7CEA1-0000007318DDE691", +"000000067F000080000005E00C0000000000-000000067F000080000005E00C0000004000__00000073AF75E930", +"000000067F000080000005E00C0000000000-000000067F000080000005E00C0000004000__000000756884A510", +"000000067F000080000005E00C000000360C-000000067F000080000005E00C000000CD72__00000072A0D7CEA1-0000007318DDE691", +"000000067F000080000005E00C0000004000-000000067F000080000005E00C0000008000__00000073AF75E930", +"000000067F000080000005E00C0000004000-000000067F000080000005E00C0000008000__000000756884A510", +"000000067F000080000005E00C0000008000-000000067F000080000005E00C000000C000__00000073AF75E930", +"000000067F000080000005E00C0000008000-000000067F000080000005E00C000000C000__000000756884A510", +"000000067F000080000005E00C000000C000-000000067F000080000005E00C0000010000__00000073AF75E930", +"000000067F000080000005E00C000000C000-000000067F000080000005E00C0000010000__000000756884A510", +"000000067F000080000005E00C000000CD72-000000067F000080000005E00C00000164D8__00000072A0D7CEA1-0000007318DDE691", +"000000067F000080000005E00C0000010000-000000067F000080000005E00C0000014000__00000073AF75E930", +"000000067F000080000005E00C0000010000-000000067F000080000005E00C0000014000__000000756884A510", +"000000067F000080000005E00C0000014000-000000067F000080000005E00C0000018000__00000073AF75E930", +"000000067F000080000005E00C0000014000-000000067F000080000005E00C0000018000__000000756884A510", +"000000067F000080000005E00C00000164D8-000000067F000080000005E00C000001FC0B__00000072A0D7CEA1-0000007318DDE691", +"000000067F000080000005E00C0000018000-000000067F000080000005E00C000001C000__00000073AF75E930", +"000000067F000080000005E00C0000018000-000000067F000080000005E00C000001C000__000000756884A510", +"000000067F000080000005E00C000001C000-000000067F000080000005E00C0000020000__00000073AF75E930", +"000000067F000080000005E00C000001C000-000000067F000080000005E00C0000020000__000000756884A510", +"000000067F000080000005E00C000001FC0B-000000067F000080000005E00C0000029319__00000072A0D7CEA1-0000007318DDE691", +"000000067F000080000005E00C0000020000-000000067F000080000005E00C0000024000__00000073AF75E930", +"000000067F000080000005E00C0000020000-000000067F000080000005E00C0000024000__000000756884A510", +"000000067F000080000005E00C0000024000-000000067F000080000005E00C0000028000__00000073AF75E930", +"000000067F000080000005E00C0000024000-000000067F000080000005E00C0000028000__000000756884A510", +"000000067F000080000005E00C0000028000-000000067F000080000005E00C000002C000__00000073AF75E930", +"000000067F000080000005E00C0000028000-000000067F000080000005E00C000002C000__000000756884A510", +"000000067F000080000005E00C0000029319-030000000000000000000000000000000002__00000072A0D7CEA1-0000007318DDE691", +"000000067F000080000005E00C000002C000-000000067F000080000005E00C0000030000__00000073AF75E930", +"000000067F000080000005E00C000002C000-000000067F000080000005E00C0000030000__000000756884A510", +"000000067F000080000005E00C0000030000-000000067F000080000005E00C0000034000__00000073AF75E930", +"000000067F000080000005E00C0000030000-000000067F000080000005E00C0000034000__000000756884A510", +"000000067F000080000005E00C0000034000-000000067F000080000005E00C0000038000__00000073AF75E930", +"000000067F000080000005E00C0000034000-000000067F000080000005E00C0000038000__000000756884A510", +"000000067F000080000005E00C0000038000-000000067F000080000005E00C000003C000__00000073AF75E930", +"000000067F000080000005E00C0000038000-000000067F000080000005E00C000003C000__000000756884A510", +"000000067F000080000005E00C00000385D9-000000067F000080000005E00C0000041D0A__0000007318DDE691-0000007497B01FF9", +"000000067F000080000005E00C000003C000-000000067F000080000005E00C0000040000__00000073AF75E930", +"000000067F000080000005E00C000003C000-000000067F000080000005E00C0000040000__000000756884A510", +"000000067F000080000005E00C0000040000-000000067F000080000005E00C0000044000__00000073AF75E930", +"000000067F000080000005E00C0000040000-000000067F000080000005E00C0000044000__000000756884A510", +"000000067F000080000005E00C0000041D0A-000000067F000080000005E00C000004B470__0000007318DDE691-0000007497B01FF9", +"000000067F000080000005E00C0000044000-000000067F000080000005E00C0000048000__00000073AF75E930", +"000000067F000080000005E00C0000044000-000000067F000080000005E00C0000048000__000000756884A510", +"000000067F000080000005E00C0000048000-000000067F000080000005E00C000004C000__00000073AF75E930", +"000000067F000080000005E00C0000048000-000000067F000080000005E00C000004C000__000000756884A510", +"000000067F000080000005E00C000004B470-000000067F000080000005E00C0000054BA9__0000007318DDE691-0000007497B01FF9", +"000000067F000080000005E00C000004C000-000000067F000080000005E00C0000050000__00000073AF75E930", +"000000067F000080000005E00C000004C000-000000067F000080000005E00C0000050000__000000756884A510", +"000000067F000080000005E00C0000050000-000000067F000080000005E00C0000054000__00000073AF75E930", +"000000067F000080000005E00C0000050000-000000067F000080000005E00C0000054000__000000756884A510", +"000000067F000080000005E00C000005017A-000000067F000080000005E00C000009FEAD__000000751253A4C1-00000075687C3009", +"000000067F000080000005E00C0000054000-000000067F000080000005E00C0000058000__00000073AF75E930", +"000000067F000080000005E00C0000054000-000000067F000080000005E00C0000058000__000000756884A510", +"000000067F000080000005E00C0000054BA9-000000067F000080000005E00C000005E30B__0000007318DDE691-0000007497B01FF9", +"000000067F000080000005E00C0000058000-000000067F000080000005E00C000005C000__00000073AF75E930", +"000000067F000080000005E00C0000058000-000000067F000080000005E00C000005C000__000000756884A510", +"000000067F000080000005E00C000005C000-000000067F000080000005E00C0000060000__00000073AF75E930", +"000000067F000080000005E00C000005C000-000000067F000080000005E00C0000060000__000000756884A510", +"000000067F000080000005E00C000005E30B-000000067F000080000005E00C0000067A2C__0000007318DDE691-0000007497B01FF9", +"000000067F000080000005E00C0000060000-000000067F000080000005E00C0000064000__00000073AF75E930", +"000000067F000080000005E00C0000060000-000000067F000080000005E00C0000064000__000000756884A510", +"000000067F000080000005E00C0000064000-000000067F000080000005E00C0000068000__00000073AF75E930", +"000000067F000080000005E00C0000064000-000000067F000080000005E00C0000068000__000000756884A510", +"000000067F000080000005E00C0000067A2C-000000067F000080000005E00C0000071187__0000007318DDE691-0000007497B01FF9", +"000000067F000080000005E00C0000068000-000000067F000080000005E00C000006C000__00000073AF75E930", +"000000067F000080000005E00C0000068000-000000067F000080000005E00C000006C000__000000756884A510", +"000000067F000080000005E00C000006C000-000000067F000080000005E00C0000070000__00000073AF75E930", +"000000067F000080000005E00C000006C000-000000067F000080000005E00C0000070000__000000756884A510", +"000000067F000080000005E00C0000070000-000000067F000080000005E00C0000074000__00000073AF75E930", +"000000067F000080000005E00C0000070000-000000067F000080000005E00C0000074000__000000756884A510", +"000000067F000080000005E00C0000071187-000000067F000080000005E00C000007A8ED__0000007318DDE691-0000007497B01FF9", +"000000067F000080000005E00C0000074000-000000067F000080000005E00C0000078000__00000073AF75E930", +"000000067F000080000005E00C0000074000-000000067F000080000005E00C0000078000__000000756884A510", +"000000067F000080000005E00C0000078000-000000067F000080000005E00C000007C000__00000073AF75E930", +"000000067F000080000005E00C0000078000-000000067F000080000005E00C000007C000__000000756884A510", +"000000067F000080000005E00C000007A8ED-000000067F000080000005E00C000008400B__0000007318DDE691-0000007497B01FF9", +"000000067F000080000005E00C000007C000-000000067F000080000005E00C0000080000__00000073AF75E930", +"000000067F000080000005E00C000007C000-000000067F000080000005E00C0000080000__000000756884A510", +"000000067F000080000005E00C0000080000-000000067F000080000005E00C0000084000__00000073AF75E930", +"000000067F000080000005E00C0000080000-000000067F000080000005E00C0000084000__000000756884A510", +"000000067F000080000005E00C0000084000-000000067F000080000005E00C0000088000__00000073AF75E930", +"000000067F000080000005E00C0000084000-000000067F000080000005E00C0000088000__000000756884A510", +"000000067F000080000005E00C000008400B-000000067F000080000005E00C000008D771__0000007318DDE691-0000007497B01FF9", +"000000067F000080000005E00C0000088000-000000067F000080000005E00C000008C000__000000756884A510", +"000000067F000080000005E00C0000088000-030000000000000000000000000000000002__00000073AF75E930", +"000000067F000080000005E00C000008C000-000000067F000080000005E00C0000090000__000000756884A510", +"000000067F000080000005E00C000008D771-000000067F000080000005E00C0000096ED7__0000007318DDE691-0000007497B01FF9", +"000000067F000080000005E00C0000090000-000000067F000080000005E00C0000094000__000000756884A510", +"000000067F000080000005E00C0000094000-000000067F000080000005E00C0000098000__000000756884A510", +"000000067F000080000005E00C0000096ED7-000000067F000080000005E00C00000A060B__0000007318DDE691-0000007497B01FF9", +"000000067F000080000005E00C0000098000-000000067F000080000005E00C000009C000__000000756884A510", +"000000067F000080000005E00C000009C000-000000067F000080000005E00C00000A0000__000000756884A510", +"000000067F000080000005E00C000009FEB2-000000067F000080000005E00C00000EF4ED__000000751253A4C1-00000075687C3009", +"000000067F000080000005E00C00000A0000-000000067F000080000005E00C00000A4000__000000756884A510", +"000000067F000080000005E00C00000A060B-000000067F000080000005E00C00000A9D71__0000007318DDE691-0000007497B01FF9", +"000000067F000080000005E00C00000A4000-000000067F000080000005E00C00000A8000__000000756884A510", +"000000067F000080000005E00C00000A8000-000000067F000080000005E00C00000AC000__000000756884A510", +"000000067F000080000005E00C00000A9D71-000000067F000080000005E00C00000B34D7__0000007318DDE691-0000007497B01FF9", +"000000067F000080000005E00C00000AC000-000000067F000080000005E00C00000B0000__000000756884A510", +"000000067F000080000005E00C00000AF576-000000067F000080000005E00C0200000023__0000007497B01FF9-000000751253A4C1", +"000000067F000080000005E00C00000B0000-000000067F000080000005E00C00000B4000__000000756884A510", +"000000067F000080000005E00C00000B34D7-000000067F000080000005E00C00000BCC0C__0000007318DDE691-0000007497B01FF9", +"000000067F000080000005E00C00000B4000-000000067F000080000005E00C00000B8000__000000756884A510", +"000000067F000080000005E00C00000B8000-000000067F000080000005E00C00000BC000__000000756884A510", +"000000067F000080000005E00C00000BC000-000000067F000080000005E00C00000C0000__000000756884A510", +"000000067F000080000005E00C00000BCC0C-000000067F000080000005E00C00000C6336__0000007318DDE691-0000007497B01FF9", +"000000067F000080000005E00C00000C0000-000000067F000080000005E00C00000C4000__000000756884A510", +"000000067F000080000005E00C00000C4000-000000067F000080000005E00C00000C8000__000000756884A510", +"000000067F000080000005E00C00000C6336-000000067F000080000005E00C00000CFA9C__0000007318DDE691-0000007497B01FF9", +"000000067F000080000005E00C00000C8000-000000067F000080000005E00C00000CC000__000000756884A510", +"000000067F000080000005E00C00000CC000-000000067F000080000005E00C00000D0000__000000756884A510", +"000000067F000080000005E00C00000CFA9C-000000067F000080000005E00C00000D91AB__0000007318DDE691-0000007497B01FF9", +"000000067F000080000005E00C00000D0000-000000067F000080000005E00C00000D4000__000000756884A510", +"000000067F000080000005E00C00000D4000-000000067F000080000005E00C00000D8000__000000756884A510", +"000000067F000080000005E00C00000D8000-000000067F000080000005E00C00000DC000__000000756884A510", +"000000067F000080000005E00C00000D91AB-000000067F000080000005E00C00000E2911__0000007318DDE691-0000007497B01FF9", +"000000067F000080000005E00C00000DC000-000000067F000080000005E00C00000E0000__000000756884A510", +"000000067F000080000005E00C00000E0000-000000067F000080000005E00C00000E4000__000000756884A510", +"000000067F000080000005E00C00000E2911-000000067F000080000005E00C00000EC077__0000007318DDE691-0000007497B01FF9", +"000000067F000080000005E00C00000E4000-000000067F000080000005E00C00000E8000__000000756884A510", +"000000067F000080000005E00C00000E8000-000000067F000080000005E00C00000EC000__000000756884A510", +"000000067F000080000005E00C00000EC000-000000067F000080000005E00C00000F0000__000000756884A510", +"000000067F000080000005E00C00000EC077-000000067F000080000005E00C00000F57A8__0000007318DDE691-0000007497B01FF9", +"000000067F000080000005E00C00000EF4F1-000000067F000080000005E014000000BDDE__000000751253A4C1-00000075687C3009", +"000000067F000080000005E00C00000F0000-000000067F000080000005E00C00000F4000__000000756884A510", +"000000067F000080000005E00C00000F4000-000000067F000080000005E00C00000F8000__000000756884A510", +"000000067F000080000005E00C00000F57A8-000000067F000080000005E00C00000FEF0A__0000007318DDE691-0000007497B01FF9", +"000000067F000080000005E00C00000F8000-000000067F000080000005E00C00000FC000__000000756884A510", +"000000067F000080000005E00C00000FC000-000000067F000080000005E00C0000100000__000000756884A510", +"000000067F000080000005E00C00000FEF0A-000000067F000080000005E00C000010862B__0000007318DDE691-0000007497B01FF9", +"000000067F000080000005E00C0000100000-000000067F000080000005E00C0000104000__000000756884A510", +"000000067F000080000005E00C0000104000-000000067F000080000005E00C0000108000__000000756884A510", +"000000067F000080000005E00C0000108000-000000067F000080000005E00C000010C000__000000756884A510", +"000000067F000080000005E00C000010862B-000000067F000080000005E00C0000111C20__0000007318DDE691-0000007497B01FF9", +"000000067F000080000005E00C000010C000-000000067F000080000005E00C0000110000__000000756884A510", +"000000067F000080000005E00C0000110000-000000067F000080000005E0120100000000__000000756884A510", +"000000067F000080000005E00C00FFFFFFFF-010000000000000001000000030000000002__0000007318DDE691-0000007497B01FF9", +"000000067F000080000005E00C02FFFFFFFF-000000067F000080000005E0140000006C41__0000007497B01FF9-000000751253A4C1", +"000000067F000080000005E0140000000000-000000067F000080000005E0140000004000__000000756884A510", +"000000067F000080000005E0140000004000-000000067F000080000005E0140000008000__000000756884A510", +"000000067F000080000005E0140000006C41-000000067F000080000005E014000000D890__0000007497B01FF9-000000751253A4C1", +"000000067F000080000005E0140000008000-000000067F000080000005E014000000C000__000000756884A510", +"000000067F000080000005E014000000BDDE-000000067F000080000005E0140000023A18__000000751253A4C1-00000075687C3009", +"000000067F000080000005E014000000C000-000000067F000080000005E0140000010000__000000756884A510", +"000000067F000080000005E014000000D890-000000067F000080000005E01400000144C8__0000007497B01FF9-000000751253A4C1", +"000000067F000080000005E0140000010000-000000067F000080000005E0140000014000__000000756884A510", +"000000067F000080000005E0140000014000-000000067F000080000005E0140000018000__000000756884A510", +"000000067F000080000005E01400000144C8-000000067F000080000005E014000001B1AC__0000007497B01FF9-000000751253A4C1", +"000000067F000080000005E0140000018000-000000067F000080000005E014000001C000__000000756884A510", +"000000067F000080000005E014000001B1AC-000000067F000080000005E0140000021E03__0000007497B01FF9-000000751253A4C1", +"000000067F000080000005E014000001C000-000000067F000080000005E0140000020000__000000756884A510", +"000000067F000080000005E0140000020000-000000067F000080000005E0140000024000__000000756884A510", +"000000067F000080000005E0140000021E03-000000067F000080000005E0140000028A36__0000007497B01FF9-000000751253A4C1", +"000000067F000080000005E0140000023A18-030000000000000000000000000000000002__000000751253A4C1-00000075687C3009", +"000000067F000080000005E0140000024000-000000067F000080000005E0140000028000__000000756884A510", +"000000067F000080000005E0140000028000-000000067F000080000005E014000002C000__000000756884A510", +"000000067F000080000005E0140000028A36-030000000000000000000000000000000002__0000007497B01FF9-000000751253A4C1", +"000000067F000080000005E014000002C000-030000000000000000000000000000000002__000000756884A510", +"000000067F000080000006000C0000000000-000000067F000080000006000C0000004000__00000077B1836CA0", +"000000067F000080000006000C0000004000-000000067F000080000006000C0000008000__00000077B1836CA0", +"000000067F000080000006000C0000008000-000000067F000080000006000C000000C000__00000077B1836CA0", +"000000067F000080000006000C0000008FB7-000000067F000080000006000C000001271D__00000075687C3009-00000075E915EBC9", +"000000067F000080000006000C000000C000-000000067F000080000006000C0000010000__00000077B1836CA0", +"000000067F000080000006000C0000010000-000000067F000080000006000C0000014000__00000077B1836CA0", +"000000067F000080000006000C000001271D-000000067F000080000006000C000001BE83__00000075687C3009-00000075E915EBC9", +"000000067F000080000006000C0000014000-000000067F000080000006000C0000018000__00000077B1836CA0", +"000000067F000080000006000C0000018000-000000067F000080000006000C000001C000__00000077B1836CA0", +"000000067F000080000006000C000001BE83-000000067F000080000006000C00000255B6__00000075687C3009-00000075E915EBC9", +"000000067F000080000006000C000001C000-000000067F000080000006000C0000020000__00000077B1836CA0", +"000000067F000080000006000C0000020000-000000067F000080000006000C0000024000__00000077B1836CA0", +"000000067F000080000006000C0000024000-000000067F000080000006000C0000028000__00000077B1836CA0", +"000000067F000080000006000C00000255B6-000000067F000080000006000C000002ED0B__00000075687C3009-00000075E915EBC9", +"000000067F000080000006000C0000028000-000000067F000080000006000C000002C000__00000077B1836CA0", +"000000067F000080000006000C000002C000-000000067F000080000006000C0000030000__00000077B1836CA0", +"000000067F000080000006000C000002ED0B-000000067F000080000006000C000003842B__00000075687C3009-00000075E915EBC9", +"000000067F000080000006000C0000030000-000000067F000080000006000C0000034000__00000077B1836CA0", +"000000067F000080000006000C0000034000-000000067F000080000006000C0000038000__00000077B1836CA0", +"000000067F000080000006000C0000038000-000000067F000080000006000C000003C000__00000077B1836CA0", +"000000067F000080000006000C000003842B-000000067F000080000006000C0000041B80__00000075687C3009-00000075E915EBC9", +"000000067F000080000006000C000003C000-000000067F000080000006000C0000040000__00000077B1836CA0", +"000000067F000080000006000C0000040000-000000067F000080000006000C0000044000__00000077B1836CA0", +"000000067F000080000006000C0000041B80-000000067F000080000006000C000004B2E6__00000075687C3009-00000075E915EBC9", +"000000067F000080000006000C0000044000-000000067F000080000006000C0000048000__00000077B1836CA0", +"000000067F000080000006000C0000048000-000000067F000080000006000C000004C000__0000007739203FF0", +"000000067F000080000006000C000004B2E6-030000000000000000000000000000000002__00000075687C3009-00000075E915EBC9", +"000000067F000080000006000C000004BAC2-000000067F000080000006000C00000551F7__00000075E915EBC9-00000076A8CDE8F9", +"000000067F000080000006000C000004C000-000000067F000080000006000C0000050000__0000007739203FF0", +"000000067F000080000006000C0000050000-000000067F000080000006000C0000054000__0000007739203FF0", +"000000067F000080000006000C0000051A05-000000067F000080000006000C00000A4D93__00000077B2AD0F91-0000007805801C41", +"000000067F000080000006000C0000054000-000000067F000080000006000C0000058000__0000007739203FF0", +"000000067F000080000006000C00000551F7-000000067F000080000006000C000005E90B__00000075E915EBC9-00000076A8CDE8F9", +"000000067F000080000006000C0000058000-000000067F000080000006000C000005C000__0000007739203FF0", +"000000067F000080000006000C000005C000-000000067F000080000006000C0000060000__0000007739203FF0", +"000000067F000080000006000C000005E90B-000000067F000080000006000C000006802B__00000075E915EBC9-00000076A8CDE8F9", +"000000067F000080000006000C0000060000-000000067F000080000006000C0000064000__0000007739203FF0", +"000000067F000080000006000C0000064000-000000067F000080000006000C0000068000__0000007739203FF0", +"000000067F000080000006000C0000068000-000000067F000080000006000C000006C000__0000007739203FF0", +"000000067F000080000006000C000006802B-000000067F000080000006000C0000071782__00000075E915EBC9-00000076A8CDE8F9", +"000000067F000080000006000C000006C000-000000067F000080000006000C0000070000__0000007739203FF0", +"000000067F000080000006000C0000070000-000000067F000080000006000C0000074000__0000007739203FF0", +"000000067F000080000006000C0000071782-000000067F000080000006000C000007AEE8__00000075E915EBC9-00000076A8CDE8F9", +"000000067F000080000006000C0000074000-000000067F000080000006000C0000078000__0000007739203FF0", +"000000067F000080000006000C0000078000-000000067F000080000006000C000007C000__0000007739203FF0", +"000000067F000080000006000C000007AEE8-000000067F000080000006000C000008460B__00000075E915EBC9-00000076A8CDE8F9", +"000000067F000080000006000C000007C000-000000067F000080000006000C0000080000__0000007739203FF0", +"000000067F000080000006000C0000080000-000000067F000080000006000C0000084000__0000007739203FF0", +"000000067F000080000006000C0000084000-000000067F000080000006000C0000088000__0000007739203FF0", +"000000067F000080000006000C000008460B-000000067F000080000006000C000008DD71__00000075E915EBC9-00000076A8CDE8F9", +"000000067F000080000006000C0000088000-000000067F000080000006000C000008C000__0000007739203FF0", +"000000067F000080000006000C000008C000-000000067F000080000006000C0000090000__0000007739203FF0", +"000000067F000080000006000C000008DD71-000000067F000080000006000C00000974D7__00000075E915EBC9-00000076A8CDE8F9", +"000000067F000080000006000C0000090000-000000067F000080000006000C0000094000__0000007739203FF0", +"000000067F000080000006000C0000094000-000000067F000080000006000C0000098000__0000007739203FF0", +"000000067F000080000006000C00000974D7-000000067F000080000006000C00000A0C0B__00000075E915EBC9-00000076A8CDE8F9", +"000000067F000080000006000C0000098000-000000067F000080000006000C000009C000__0000007739203FF0", +"000000067F000080000006000C000009C000-000000067F000080000006000C00000A0000__0000007739203FF0", +"000000067F000080000006000C00000A0000-000000067F000080000006000C00000A4000__0000007739203FF0", +"000000067F000080000006000C00000A0C0B-000000067F000080000006000C00000AA371__00000075E915EBC9-00000076A8CDE8F9", +"000000067F000080000006000C00000A4000-000000067F000080000006000C00000A8000__0000007739203FF0", +"000000067F000080000006000C00000A4D95-000000067F000080000006000C00000F7C7B__00000077B2AD0F91-0000007805801C41", +"000000067F000080000006000C00000A8000-000000067F000080000006000C00000AC000__0000007739203FF0", +"000000067F000080000006000C00000AA371-000000067F000080000006000C00000B3AD7__00000075E915EBC9-00000076A8CDE8F9", +"000000067F000080000006000C00000AC000-000000067F000080000006000C00000B0000__0000007739203FF0", +"000000067F000080000006000C00000B0000-000000067F000080000006000C00000B4000__0000007739203FF0", +"000000067F000080000006000C00000B3AD7-000000067F000080000006000C00000BD20B__00000075E915EBC9-00000076A8CDE8F9", +"000000067F000080000006000C00000B4000-000000067F000080000006000C00000B8000__0000007739203FF0", +"000000067F000080000006000C00000B8000-000000067F000080000006000C00000BC000__0000007739203FF0", +"000000067F000080000006000C00000BC000-000000067F000080000006000C00000C0000__0000007739203FF0", +"000000067F000080000006000C00000BD20B-000000067F000080000006000C0100000000__00000075E915EBC9-00000076A8CDE8F9", +"000000067F000080000006000C00000C0000-000000067F000080000006000C00000C4000__0000007739203FF0", +"000000067F000080000006000C00000C3C38-000000067F00008000000600140000001B38__00000077391A8001-00000077B2AD0F91", +"000000067F000080000006000C00000C4000-000000067F000080000006000C00000C8000__0000007739203FF0", +"000000067F000080000006000C00000C56C1-000000067F000080000006000C00000CEE0A__00000076A8CDE8F9-00000077391A8001", +"000000067F000080000006000C00000C8000-000000067F000080000006000C00000CC000__0000007739203FF0", +"000000067F000080000006000C00000CC000-000000067F000080000006000C00000D0000__0000007739203FF0", +"000000067F000080000006000C00000CEE0A-000000067F000080000006000C00000D8520__00000076A8CDE8F9-00000077391A8001", +"000000067F000080000006000C00000D0000-000000067F000080000006000C00000D4000__0000007739203FF0", +"000000067F000080000006000C00000D4000-000000067F000080000006000C00000D8000__0000007739203FF0", +"000000067F000080000006000C00000D8000-000000067F000080000006000C00000DC000__0000007739203FF0", +"000000067F000080000006000C00000D8520-000000067F000080000006000C00000E1C86__00000076A8CDE8F9-00000077391A8001", +"000000067F000080000006000C00000DC000-000000067F000080000006000C00000E0000__0000007739203FF0", +"000000067F000080000006000C00000E0000-000000067F000080000006000C00000E4000__0000007739203FF0", +"000000067F000080000006000C00000E1C86-000000067F000080000006000C00000EB3EC__00000076A8CDE8F9-00000077391A8001", +"000000067F000080000006000C00000E4000-000000067F000080000006000C00000E8000__0000007739203FF0", +"000000067F000080000006000C00000E8000-000000067F000080000006000C00000EC000__0000007739203FF0", +"000000067F000080000006000C00000EB3EC-000000067F000080000006000C00000F4B0C__00000076A8CDE8F9-00000077391A8001", +"000000067F000080000006000C00000EC000-000000067F000080000006000C00000F0000__0000007739203FF0", +"000000067F000080000006000C00000F0000-000000067F000080000006000C00000F4000__0000007739203FF0", +"000000067F000080000006000C00000F4000-000000067F000080000006000C00000F8000__0000007739203FF0", +"000000067F000080000006000C00000F4B0C-000000067F000080000006000C00000FE272__00000076A8CDE8F9-00000077391A8001", +"000000067F000080000006000C00000F7C96-000000067F0000800000060014000000F3A9__00000077B2AD0F91-0000007805801C41", +"000000067F000080000006000C00000F8000-000000067F000080000006000C00000FC000__0000007739203FF0", +"000000067F000080000006000C00000FC000-000000067F000080000006000C0000100000__0000007739203FF0", +"000000067F000080000006000C00000FE272-000000067F000080000006000C000010798F__00000076A8CDE8F9-00000077391A8001", +"000000067F000080000006000C0000100000-000000067F000080000006000C0000104000__0000007739203FF0", +"000000067F000080000006000C0000104000-000000067F000080000006000C0000108000__0000007739203FF0", +"000000067F000080000006000C000010798F-000000067F000080000006000C00001110F5__00000076A8CDE8F9-00000077391A8001", +"000000067F000080000006000C0000108000-000000067F000080000006000C000010C000__0000007739203FF0", +"000000067F000080000006000C000010C000-000000067F000080000006000C0000110000__0000007739203FF0", +"000000067F000080000006000C0000110000-030000000000000000000000000000000002__0000007739203FF0", +"000000067F000080000006000C00001110F5-010000000000000001000000030000000006__00000076A8CDE8F9-00000077391A8001", +"000000067F00008000000600140000001B38-000000067F00008000000600140000008758__00000077391A8001-00000077B2AD0F91", +"000000067F00008000000600140000008758-000000067F0000800000060014000000F32F__00000077391A8001-00000077B2AD0F91", +"000000067F0000800000060014000000F32F-000000067F00008000000600140000015EDC__00000077391A8001-00000077B2AD0F91", +"000000067F0000800000060014000000F3A9-000000067F00008000000600140000028656__00000077B2AD0F91-0000007805801C41", +"000000067F00008000000600140000015EDC-000000067F0000800000060014000001CB12__00000077391A8001-00000077B2AD0F91", +"000000067F0000800000060014000001CB12-000000067F000080000006001400000236BC__00000077391A8001-00000077B2AD0F91", +"000000067F000080000006001400000236BC-000000067F0000800000060014000002A294__00000077391A8001-00000077B2AD0F91", +"000000067F00008000000600140000028657-030000000000000000000000000000000002__00000077B2AD0F91-0000007805801C41", +"000000067F0000800000060014000002A294-030000000000000000000000000000000002__00000077391A8001-00000077B2AD0F91", +"000000067F000080000006200C0000000000-000000067F000080000006200C0000004000__00000078B2CB1C68", +"000000067F000080000006200C0000004000-000000067F000080000006200C0000008000__00000078B2CB1C68", +"000000067F000080000006200C0000008000-000000067F000080000006200C000000C000__00000078B2CB1C68", +"000000067F000080000006200C0000009441-000000067F000080000006200C0000012B8D__0000007805801C41-00000078859FEA11", +"000000067F000080000006200C000000C000-000000067F000080000006200C0000010000__00000078B2CB1C68", +"000000067F000080000006200C0000010000-000000067F000080000006200C0000014000__00000078B2CB1C68", +"000000067F000080000006200C0000012B8D-000000067F000080000006200C000001C2F3__0000007805801C41-00000078859FEA11", +"000000067F000080000006200C0000014000-000000067F000080000006200C0000018000__00000078B2CB1C68", +"000000067F000080000006200C0000018000-000000067F000080000006200C000001C000__00000078B2CB1C68", +"000000067F000080000006200C000001C000-000000067F000080000006200C0000020000__00000078B2CB1C68", +"000000067F000080000006200C000001C2F3-000000067F000080000006200C0000025A0C__0000007805801C41-00000078859FEA11", +"000000067F000080000006200C0000020000-000000067F000080000006200C0000024000__00000078B2CB1C68", +"000000067F000080000006200C0000024000-000000067F000080000006200C0000028000__00000078B2CB1C68", +"000000067F000080000006200C0000025A0C-000000067F000080000006200C000002F172__0000007805801C41-00000078859FEA11", +"000000067F000080000006200C0000028000-000000067F000080000006200C000002C000__00000078B2CB1C68", +"000000067F000080000006200C000002C000-000000067F000080000006200C0000030000__00000078B2CB1C68", +"000000067F000080000006200C000002F172-000000067F000080000006200C00000388D8__0000007805801C41-00000078859FEA11", +"000000067F000080000006200C0000030000-000000067F000080000006200C0000034000__00000078B2CB1C68", +"000000067F000080000006200C0000034000-000000067F000080000006200C0000038000__00000078B2CB1C68", +"000000067F000080000006200C0000038000-000000067F000080000006200C000003C000__00000078B2CB1C68", +"000000067F000080000006200C00000388D8-000000067F000080000006200C0000042009__0000007805801C41-00000078859FEA11", +"000000067F000080000006200C000003C000-000000067F000080000006200C0000040000__00000078B2CB1C68", +"000000067F000080000006200C0000040000-000000067F000080000006200C0000044000__00000078B2CB1C68", +"000000067F000080000006200C0000042009-000000067F000080000006200C000004B76F__0000007805801C41-00000078859FEA11", +"000000067F000080000006200C0000044000-000000067F000080000006200C0000048000__00000078B2CB1C68", +"000000067F000080000006200C0000048000-000000067F000080000006200C000004C000__00000078B2CB1C68", +"000000067F000080000006200C0000048000-000000067F000080000006200C000004C000__0000007AA0A6FB48", +"000000067F000080000006200C0000048121-000000067F000080000006200C0000090C08__0000007A3F679FA1-0000007AA1DF6639", +"000000067F000080000006200C000004B76F-030000000000000000000000000000000002__0000007805801C41-00000078859FEA11", +"000000067F000080000006200C000004BAC9-000000067F000080000006200C00000551FE__00000078859FEA11-00000079C527F0D9", +"000000067F000080000006200C000004C000-000000067F000080000006200C0000050000__00000078B2CB1C68", +"000000067F000080000006200C000004C000-000000067F000080000006200C0000050000__0000007AA0A6FB48", +"000000067F000080000006200C0000050000-000000067F000080000006200C0000054000__00000078B2CB1C68", +"000000067F000080000006200C0000050000-000000067F000080000006200C0000054000__0000007AA0A6FB48", +"000000067F000080000006200C0000054000-000000067F000080000006200C0000058000__00000078B2CB1C68", +"000000067F000080000006200C0000054000-000000067F000080000006200C0000058000__0000007AA0A6FB48", +"000000067F000080000006200C00000551FE-000000067F000080000006200C000005E90C__00000078859FEA11-00000079C527F0D9", +"000000067F000080000006200C0000058000-000000067F000080000006200C000005C000__00000078B2CB1C68", +"000000067F000080000006200C0000058000-000000067F000080000006200C000005C000__0000007AA0A6FB48", +"000000067F000080000006200C000005C000-000000067F000080000006200C0000060000__00000078B2CB1C68", +"000000067F000080000006200C000005C000-000000067F000080000006200C0000060000__0000007AA0A6FB48", +"000000067F000080000006200C000005E90C-000000067F000080000006200C000006802C__00000078859FEA11-00000079C527F0D9", +"000000067F000080000006200C0000060000-000000067F000080000006200C0000064000__00000078B2CB1C68", +"000000067F000080000006200C0000060000-000000067F000080000006200C0000064000__0000007AA0A6FB48", +"000000067F000080000006200C0000064000-000000067F000080000006200C0000068000__0000007AA0A6FB48", +"000000067F000080000006200C0000064000-030000000000000000000000000000000002__00000078B2CB1C68", +"000000067F000080000006200C0000068000-000000067F000080000006200C000006C000__0000007AA0A6FB48", +"000000067F000080000006200C000006802C-000000067F000080000006200C0000071783__00000078859FEA11-00000079C527F0D9", +"000000067F000080000006200C000006C000-000000067F000080000006200C0000070000__0000007AA0A6FB48", +"000000067F000080000006200C0000070000-000000067F000080000006200C0000074000__0000007AA0A6FB48", +"000000067F000080000006200C0000071783-000000067F000080000006200C000007AEE9__00000078859FEA11-00000079C527F0D9", +"000000067F000080000006200C0000074000-000000067F000080000006200C0000078000__0000007AA0A6FB48", +"000000067F000080000006200C0000078000-000000067F000080000006200C000007C000__0000007AA0A6FB48", +"000000067F000080000006200C000007AEE9-000000067F000080000006200C000008460B__00000078859FEA11-00000079C527F0D9", +"000000067F000080000006200C000007C000-000000067F000080000006200C0000080000__0000007AA0A6FB48", +"000000067F000080000006200C0000080000-000000067F000080000006200C0000084000__0000007AA0A6FB48", +"000000067F000080000006200C0000084000-000000067F000080000006200C0000088000__0000007AA0A6FB48", +"000000067F000080000006200C000008460B-000000067F000080000006200C000008DD71__00000078859FEA11-00000079C527F0D9", +"000000067F000080000006200C0000088000-000000067F000080000006200C000008C000__0000007AA0A6FB48", +"000000067F000080000006200C000008C000-000000067F000080000006200C0000090000__0000007AA0A6FB48", +"000000067F000080000006200C000008DD71-000000067F000080000006200C00000974D7__00000078859FEA11-00000079C527F0D9", +"000000067F000080000006200C0000090000-000000067F000080000006200C0000094000__0000007AA0A6FB48", +"000000067F000080000006200C0000090C11-000000067F000080000006200C00000DA35B__0000007A3F679FA1-0000007AA1DF6639", +"000000067F000080000006200C0000094000-000000067F000080000006200C0000098000__0000007AA0A6FB48", +"000000067F000080000006200C00000974D7-000000067F000080000006200C00000A0C0B__00000078859FEA11-00000079C527F0D9", +"000000067F000080000006200C0000098000-000000067F000080000006200C000009C000__0000007AA0A6FB48", +"000000067F000080000006200C000009C000-000000067F000080000006200C00000A0000__0000007AA0A6FB48", +"000000067F000080000006200C00000A0000-000000067F000080000006200C00000A4000__0000007AA0A6FB48", +"000000067F000080000006200C00000A0C0B-000000067F000080000006200C00000AA371__00000078859FEA11-00000079C527F0D9", +"000000067F000080000006200C00000A4000-000000067F000080000006200C00000A8000__0000007AA0A6FB48", +"000000067F000080000006200C00000A8000-000000067F000080000006200C00000AC000__0000007AA0A6FB48", +"000000067F000080000006200C00000AA371-000000067F000080000006200C00000B3AD7__00000078859FEA11-00000079C527F0D9", +"000000067F000080000006200C00000AC000-000000067F000080000006200C00000B0000__0000007AA0A6FB48", +"000000067F000080000006200C00000B0000-000000067F000080000006200C00000B4000__0000007AA0A6FB48", +"000000067F000080000006200C00000B3AD7-000000067F000080000006200C00000BD20B__00000078859FEA11-00000079C527F0D9", +"000000067F000080000006200C00000B4000-000000067F000080000006200C00000B8000__0000007AA0A6FB48", +"000000067F000080000006200C00000B8000-000000067F000080000006200C00000BC000__0000007AA0A6FB48", +"000000067F000080000006200C00000BC000-000000067F000080000006200C00000C0000__0000007AA0A6FB48", +"000000067F000080000006200C00000BD20B-000000067F000080000006200C00000C6932__00000078859FEA11-00000079C527F0D9", +"000000067F000080000006200C00000C0000-000000067F000080000006200C00000C4000__0000007AA0A6FB48", +"000000067F000080000006200C00000C4000-000000067F000080000006200C00000C8000__0000007AA0A6FB48", +"000000067F000080000006200C00000C6932-000000067F000080000006200C00000D0098__00000078859FEA11-00000079C527F0D9", +"000000067F000080000006200C00000C8000-000000067F000080000006200C00000CC000__0000007AA0A6FB48", +"000000067F000080000006200C00000CC000-000000067F000080000006200C00000D0000__0000007AA0A6FB48", +"000000067F000080000006200C00000D0000-000000067F000080000006200C00000D4000__0000007AA0A6FB48", +"000000067F000080000006200C00000D0098-000000067F000080000006200C00000D97FE__00000078859FEA11-00000079C527F0D9", +"000000067F000080000006200C00000D4000-000000067F000080000006200C00000D8000__0000007AA0A6FB48", +"000000067F000080000006200C00000D8000-000000067F000080000006200C00000DC000__0000007AA0A6FB48", +"000000067F000080000006200C00000D97FE-000000067F000080000006200C00000E2F0B__00000078859FEA11-00000079C527F0D9", +"000000067F000080000006200C00000DA36C-000000067F00008000000620140000002D07__0000007A3F679FA1-0000007AA1DF6639", +"000000067F000080000006200C00000DC000-000000067F000080000006200C00000E0000__0000007AA0A6FB48", +"000000067F000080000006200C00000E0000-000000067F000080000006200C00000E4000__0000007AA0A6FB48", +"000000067F000080000006200C00000E2F0B-000000067F000080000006200C00000EC671__00000078859FEA11-00000079C527F0D9", +"000000067F000080000006200C00000E4000-000000067F000080000006200C00000E8000__0000007AA0A6FB48", +"000000067F000080000006200C00000E8000-000000067F000080000006200C00000EC000__0000007AA0A6FB48", +"000000067F000080000006200C00000EC000-000000067F000080000006200C00000F0000__0000007AA0A6FB48", +"000000067F000080000006200C00000EC671-000000067F000080000006200C00000F5D9F__00000078859FEA11-00000079C527F0D9", +"000000067F000080000006200C00000F0000-000000067F000080000006200C00000F4000__0000007AA0A6FB48", +"000000067F000080000006200C00000F4000-000000067F000080000006200C00000F8000__0000007AA0A6FB48", +"000000067F000080000006200C00000F5D9F-000000067F000080000006200C00000FF505__00000078859FEA11-00000079C527F0D9", +"000000067F000080000006200C00000F8000-000000067F000080000006200C00000FC000__0000007AA0A6FB48", +"000000067F000080000006200C00000FC000-000000067F000080000006200C0000100000__0000007AA0A6FB48", +"000000067F000080000006200C00000FF505-000000067F000080000006200C0000108C10__00000078859FEA11-00000079C527F0D9", +"000000067F000080000006200C0000100000-000000067F000080000006200C0000104000__0000007AA0A6FB48", +"000000067F000080000006200C0000104000-000000067F000080000006200C0000108000__0000007AA0A6FB48", +"000000067F000080000006200C0000107883-000000067F000080000006200C01000000AF__00000079C527F0D9-0000007A3F679FA1", +"000000067F000080000006200C0000108000-000000067F000080000006200C000010C000__0000007AA0A6FB48", +"000000067F000080000006200C0000108C10-000000067F000080000006200C0100000000__00000078859FEA11-00000079C527F0D9", +"000000067F000080000006200C000010C000-000000067F000080000006200C0000110000__0000007AA0A6FB48", +"000000067F000080000006200C0000110000-000000067F00008000000620120100000000__0000007AA0A6FB48", +"000000067F000080000006200C01000000AF-000000067F00008000000620140000004888__00000079C527F0D9-0000007A3F679FA1", +"000000067F00008000000620140000002D0A-000000067F00008000000620140000016355__0000007A3F679FA1-0000007AA1DF6639", +"000000067F00008000000620140000004888-000000067F0000800000062014000000BC11__00000079C527F0D9-0000007A3F679FA1", +"000000067F0000800000062014000000BC11-000000067F00008000000620140000012FA7__00000079C527F0D9-0000007A3F679FA1", +"000000067F00008000000620140000012FA7-000000067F0000800000062014000001A33D__00000079C527F0D9-0000007A3F679FA1", +"000000067F00008000000620140000016357-000000067F00008000000620140000029C35__0000007A3F679FA1-0000007AA1DF6639", +"000000067F0000800000062014000001A33D-000000067F000080000006201400000216B4__00000079C527F0D9-0000007A3F679FA1", +"000000067F000080000006201400000216B4-000000067F00008000000620140000028A65__00000079C527F0D9-0000007A3F679FA1", +"000000067F00008000000620140000028A65-030000000000000000000000000000000002__00000079C527F0D9-0000007A3F679FA1", +"000000067F00008000000620140000029C38-030000000000000000000000000000000002__0000007A3F679FA1-0000007AA1DF6639", +"000000067F000080000006400C0000000000-000000067F000080000006400C0000004000__0000007B9877EF40", +"000000067F000080000006400C0000000000-000000067F000080000006400C0000004000__0000007D41715570", +"000000067F000080000006400C0000004000-000000067F000080000006400C0000008000__0000007B9877EF40", +"000000067F000080000006400C0000004000-000000067F000080000006400C0000008000__0000007D41715570", +"000000067F000080000006400C0000007987-000000067F000080000006400C00000110ED__0000007AA1DF6639-0000007B14D5C521", +"000000067F000080000006400C0000008000-000000067F000080000006400C000000C000__0000007B9877EF40", +"000000067F000080000006400C0000008000-000000067F000080000006400C000000C000__0000007D41715570", +"000000067F000080000006400C000000C000-000000067F000080000006400C0000010000__0000007B9877EF40", +"000000067F000080000006400C000000C000-000000067F000080000006400C0000010000__0000007D41715570", +"000000067F000080000006400C0000010000-000000067F000080000006400C0000014000__0000007B9877EF40", +"000000067F000080000006400C0000010000-000000067F000080000006400C0000014000__0000007D41715570", +"000000067F000080000006400C00000110ED-000000067F000080000006400C000001A80A__0000007AA1DF6639-0000007B14D5C521", +"000000067F000080000006400C0000014000-000000067F000080000006400C0000018000__0000007B9877EF40", +"000000067F000080000006400C0000014000-000000067F000080000006400C0000018000__0000007D41715570", +"000000067F000080000006400C0000018000-000000067F000080000006400C000001C000__0000007B9877EF40", +"000000067F000080000006400C0000018000-000000067F000080000006400C000001C000__0000007D41715570", +"000000067F000080000006400C000001A80A-000000067F000080000006400C0000023F4A__0000007AA1DF6639-0000007B14D5C521", +"000000067F000080000006400C000001C000-000000067F000080000006400C0000020000__0000007B9877EF40", +"000000067F000080000006400C000001C000-000000067F000080000006400C0000020000__0000007D41715570", +"000000067F000080000006400C0000020000-000000067F000080000006400C0000024000__0000007B9877EF40", +"000000067F000080000006400C0000020000-000000067F000080000006400C0000024000__0000007D41715570", +"000000067F000080000006400C0000023F4A-000000067F000080000006400C000002D6B0__0000007AA1DF6639-0000007B14D5C521", +"000000067F000080000006400C0000024000-000000067F000080000006400C0000028000__0000007B9877EF40", +"000000067F000080000006400C0000024000-000000067F000080000006400C0000028000__0000007D41715570", +"000000067F000080000006400C0000028000-000000067F000080000006400C000002C000__0000007B9877EF40", +"000000067F000080000006400C0000028000-000000067F000080000006400C000002C000__0000007D41715570", +"000000067F000080000006400C000002C000-000000067F000080000006400C0000030000__0000007B9877EF40", +"000000067F000080000006400C000002C000-000000067F000080000006400C0000030000__0000007D41715570", +"000000067F000080000006400C000002D6B0-000000067F000080000006400C0000036DD4__0000007AA1DF6639-0000007B14D5C521", +"000000067F000080000006400C0000030000-000000067F000080000006400C0000034000__0000007B9877EF40", +"000000067F000080000006400C0000030000-000000067F000080000006400C0000034000__0000007D41715570", +"000000067F000080000006400C0000034000-000000067F000080000006400C0000038000__0000007B9877EF40", +"000000067F000080000006400C0000034000-000000067F000080000006400C0000038000__0000007D41715570", +"000000067F000080000006400C0000036DD4-000000067F000080000006400C000004050A__0000007AA1DF6639-0000007B14D5C521", +"000000067F000080000006400C0000038000-000000067F000080000006400C000003C000__0000007B9877EF40", +"000000067F000080000006400C0000038000-000000067F000080000006400C000003C000__0000007D41715570", +"000000067F000080000006400C000003C000-000000067F000080000006400C0000040000__0000007B9877EF40", +"000000067F000080000006400C000003C000-000000067F000080000006400C0000040000__0000007D41715570", +"000000067F000080000006400C0000040000-000000067F000080000006400C0000044000__0000007B9877EF40", +"000000067F000080000006400C0000040000-000000067F000080000006400C0000044000__0000007D41715570", +"000000067F000080000006400C000004050A-030000000000000000000000000000000002__0000007AA1DF6639-0000007B14D5C521", +"000000067F000080000006400C0000044000-000000067F000080000006400C0000048000__0000007B9877EF40", +"000000067F000080000006400C0000044000-000000067F000080000006400C0000048000__0000007D41715570", +"000000067F000080000006400C0000048000-000000067F000080000006400C000004C000__0000007B9877EF40", +"000000067F000080000006400C0000048000-000000067F000080000006400C000004C000__0000007D41715570", +"000000067F000080000006400C000004B4C9-000000067F000080000006400C0000054C01__0000007B14D5C521-0000007C73B53FC9", +"000000067F000080000006400C000004C000-000000067F000080000006400C0000050000__0000007B9877EF40", +"000000067F000080000006400C000004C000-000000067F000080000006400C0000050000__0000007D41715570", +"000000067F000080000006400C0000050000-000000067F000080000006400C0000054000__0000007B9877EF40", +"000000067F000080000006400C0000050000-000000067F000080000006400C0000054000__0000007D41715570", +"000000067F000080000006400C00000525C4-000000067F000080000006400C00000A47A7__0000007CEE5A0B91-0000007D41EA8D51", +"000000067F000080000006400C0000054000-000000067F000080000006400C0000058000__0000007B9877EF40", +"000000067F000080000006400C0000054000-000000067F000080000006400C0000058000__0000007D41715570", +"000000067F000080000006400C0000054C01-000000067F000080000006400C000005E30C__0000007B14D5C521-0000007C73B53FC9", +"000000067F000080000006400C0000058000-000000067F000080000006400C000005C000__0000007B9877EF40", +"000000067F000080000006400C0000058000-000000067F000080000006400C000005C000__0000007D41715570", +"000000067F000080000006400C000005C000-000000067F000080000006400C0000060000__0000007B9877EF40", +"000000067F000080000006400C000005C000-000000067F000080000006400C0000060000__0000007D41715570", +"000000067F000080000006400C000005E30C-000000067F000080000006400C0000067A2C__0000007B14D5C521-0000007C73B53FC9", +"000000067F000080000006400C0000060000-000000067F000080000006400C0000064000__0000007B9877EF40", +"000000067F000080000006400C0000060000-000000067F000080000006400C0000064000__0000007D41715570", +"000000067F000080000006400C0000064000-000000067F000080000006400C0000068000__0000007B9877EF40", +"000000067F000080000006400C0000064000-000000067F000080000006400C0000068000__0000007D41715570", +"000000067F000080000006400C0000067A2C-000000067F000080000006400C0000071187__0000007B14D5C521-0000007C73B53FC9", +"000000067F000080000006400C0000068000-000000067F000080000006400C000006C000__0000007B9877EF40", +"000000067F000080000006400C0000068000-000000067F000080000006400C000006C000__0000007D41715570", +"000000067F000080000006400C000006C000-000000067F000080000006400C0000070000__0000007B9877EF40", +"000000067F000080000006400C000006C000-000000067F000080000006400C0000070000__0000007D41715570", +"000000067F000080000006400C0000070000-000000067F000080000006400C0000074000__0000007B9877EF40", +"000000067F000080000006400C0000070000-000000067F000080000006400C0000074000__0000007D41715570", +"000000067F000080000006400C0000071187-000000067F000080000006400C000007A8ED__0000007B14D5C521-0000007C73B53FC9", +"000000067F000080000006400C0000074000-000000067F000080000006400C0000078000__0000007B9877EF40", +"000000067F000080000006400C0000074000-000000067F000080000006400C0000078000__0000007D41715570", +"000000067F000080000006400C0000078000-000000067F000080000006400C000007C000__0000007B9877EF40", +"000000067F000080000006400C0000078000-000000067F000080000006400C000007C000__0000007D41715570", +"000000067F000080000006400C000007A8ED-000000067F000080000006400C000008400B__0000007B14D5C521-0000007C73B53FC9", +"000000067F000080000006400C000007C000-000000067F000080000006400C0000080000__0000007B9877EF40", +"000000067F000080000006400C000007C000-000000067F000080000006400C0000080000__0000007D41715570", +"000000067F000080000006400C0000080000-000000067F000080000006400C0000084000__0000007B9877EF40", +"000000067F000080000006400C0000080000-000000067F000080000006400C0000084000__0000007D41715570", +"000000067F000080000006400C0000084000-000000067F000080000006400C0000088000__0000007B9877EF40", +"000000067F000080000006400C0000084000-000000067F000080000006400C0000088000__0000007D41715570", +"000000067F000080000006400C000008400B-000000067F000080000006400C000008D771__0000007B14D5C521-0000007C73B53FC9", +"000000067F000080000006400C0000088000-000000067F000080000006400C000008C000__0000007B9877EF40", +"000000067F000080000006400C0000088000-000000067F000080000006400C000008C000__0000007D41715570", +"000000067F000080000006400C000008C000-000000067F000080000006400C0000090000__0000007B9877EF40", +"000000067F000080000006400C000008C000-000000067F000080000006400C0000090000__0000007D41715570", +"000000067F000080000006400C000008D771-000000067F000080000006400C0000096ED7__0000007B14D5C521-0000007C73B53FC9", +"000000067F000080000006400C0000090000-000000067F000080000006400C0000094000__0000007D41715570", +"000000067F000080000006400C0000090000-030000000000000000000000000000000002__0000007B9877EF40", +"000000067F000080000006400C0000094000-000000067F000080000006400C0000098000__0000007D41715570", +"000000067F000080000006400C0000096ED7-000000067F000080000006400C00000A060B__0000007B14D5C521-0000007C73B53FC9", +"000000067F000080000006400C0000098000-000000067F000080000006400C000009C000__0000007D41715570", +"000000067F000080000006400C000009C000-000000067F000080000006400C00000A0000__0000007D41715570", +"000000067F000080000006400C00000A0000-000000067F000080000006400C00000A4000__0000007D41715570", +"000000067F000080000006400C00000A060B-000000067F000080000006400C00000A9D71__0000007B14D5C521-0000007C73B53FC9", +"000000067F000080000006400C00000A4000-000000067F000080000006400C00000A8000__0000007D41715570", +"000000067F000080000006400C00000A47B1-000000067F000080000006400C00000F593E__0000007CEE5A0B91-0000007D41EA8D51", +"000000067F000080000006400C00000A8000-000000067F000080000006400C00000AC000__0000007D41715570", +"000000067F000080000006400C00000A887C-000000067F000080000006400C020000001F__0000007C73B53FC9-0000007CEE5A0B91", +"000000067F000080000006400C00000A9D71-000000067F000080000006400C00000B34D7__0000007B14D5C521-0000007C73B53FC9", +"000000067F000080000006400C00000AC000-000000067F000080000006400C00000B0000__0000007D41715570", +"000000067F000080000006400C00000B0000-000000067F000080000006400C00000B4000__0000007D41715570", +"000000067F000080000006400C00000B34D7-000000067F000080000006400C00000BCC0C__0000007B14D5C521-0000007C73B53FC9", +"000000067F000080000006400C00000B4000-000000067F000080000006400C00000B8000__0000007D41715570", +"000000067F000080000006400C00000B8000-000000067F000080000006400C00000BC000__0000007D41715570", +"000000067F000080000006400C00000BC000-000000067F000080000006400C00000C0000__0000007D41715570", +"000000067F000080000006400C00000BCC0C-000000067F000080000006400C00000C6336__0000007B14D5C521-0000007C73B53FC9", +"000000067F000080000006400C00000C0000-000000067F000080000006400C00000C4000__0000007D41715570", +"000000067F000080000006400C00000C4000-000000067F000080000006400C00000C8000__0000007D41715570", +"000000067F000080000006400C00000C6336-000000067F000080000006400C00000CFA9C__0000007B14D5C521-0000007C73B53FC9", +"000000067F000080000006400C00000C8000-000000067F000080000006400C00000CC000__0000007D41715570", +"000000067F000080000006400C00000CC000-000000067F000080000006400C00000D0000__0000007D41715570", +"000000067F000080000006400C00000CFA9C-000000067F000080000006400C00000D91AB__0000007B14D5C521-0000007C73B53FC9", +"000000067F000080000006400C00000D0000-000000067F000080000006400C00000D4000__0000007D41715570", +"000000067F000080000006400C00000D4000-000000067F000080000006400C00000D8000__0000007D41715570", +"000000067F000080000006400C00000D8000-000000067F000080000006400C00000DC000__0000007D41715570", +"000000067F000080000006400C00000D91AB-000000067F000080000006400C00000E2911__0000007B14D5C521-0000007C73B53FC9", +"000000067F000080000006400C00000DC000-000000067F000080000006400C00000E0000__0000007D41715570", +"000000067F000080000006400C00000E0000-000000067F000080000006400C00000E4000__0000007D41715570", +"000000067F000080000006400C00000E2911-000000067F000080000006400C00000EC077__0000007B14D5C521-0000007C73B53FC9", +"000000067F000080000006400C00000E4000-000000067F000080000006400C00000E8000__0000007D41715570", +"000000067F000080000006400C00000E8000-000000067F000080000006400C00000EC000__0000007D41715570", +"000000067F000080000006400C00000EC000-000000067F000080000006400C00000F0000__0000007D41715570", +"000000067F000080000006400C00000EC077-000000067F000080000006400C00000F57A8__0000007B14D5C521-0000007C73B53FC9", +"000000067F000080000006400C00000F0000-000000067F000080000006400C00000F4000__0000007D41715570", +"000000067F000080000006400C00000F4000-000000067F000080000006400C00000F8000__0000007D41715570", +"000000067F000080000006400C00000F57A8-000000067F000080000006400C00000FEF0A__0000007B14D5C521-0000007C73B53FC9", +"000000067F000080000006400C00000F5940-000000067F0000800000064014000000E7FF__0000007CEE5A0B91-0000007D41EA8D51", +"000000067F000080000006400C00000F8000-000000067F000080000006400C00000FC000__0000007D41715570", +"000000067F000080000006400C00000FC000-000000067F000080000006400C0000100000__0000007D41715570", +"000000067F000080000006400C00000FEF0A-000000067F000080000006400C000010862B__0000007B14D5C521-0000007C73B53FC9", +"000000067F000080000006400C0000100000-000000067F000080000006400C0000104000__0000007D41715570", +"000000067F000080000006400C0000104000-000000067F000080000006400C0000108000__0000007D41715570", +"000000067F000080000006400C0000108000-000000067F000080000006400C000010C000__0000007D41715570", +"000000067F000080000006400C000010862B-000000067F000080000006400C0000111C20__0000007B14D5C521-0000007C73B53FC9", +"000000067F000080000006400C000010C000-000000067F000080000006400C0000110000__0000007D41715570", +"000000067F000080000006400C0000110000-000000067F00008000000640120100000000__0000007D41715570", +"000000067F000080000006400C00FFFFFFFF-01000000000000000100000003000000000D__0000007B14D5C521-0000007C73B53FC9", +"000000067F000080000006400C020000001F-000000067F0000800000064014000000691F__0000007C73B53FC9-0000007CEE5A0B91", +"000000067F00008000000640140000000000-000000067F00008000000640140000004000__0000007D41715570", +"000000067F00008000000640140000004000-000000067F00008000000640140000008000__0000007D41715570", +"000000067F0000800000064014000000691F-000000067F0000800000064014000000D68F__0000007C73B53FC9-0000007CEE5A0B91", +"000000067F00008000000640140000008000-000000067F0000800000064014000000C000__0000007D41715570", +"000000067F0000800000064014000000C000-000000067F00008000000640140000010000__0000007D41715570", +"000000067F0000800000064014000000D68F-000000067F00008000000640140000014406__0000007C73B53FC9-0000007CEE5A0B91", +"000000067F0000800000064014000000E803-000000067F000080000006401400000274BB__0000007CEE5A0B91-0000007D41EA8D51", +"000000067F00008000000640140000010000-000000067F00008000000640140000014000__0000007D41715570", +"000000067F00008000000640140000014000-000000067F00008000000640140000018000__0000007D41715570", +"000000067F00008000000640140000014406-000000067F0000800000064014000001B192__0000007C73B53FC9-0000007CEE5A0B91", +"000000067F00008000000640140000018000-000000067F0000800000064014000001C000__0000007D41715570", +"000000067F0000800000064014000001B192-000000067F00008000000640140000021F03__0000007C73B53FC9-0000007CEE5A0B91", +"000000067F0000800000064014000001C000-000000067F00008000000640140000020000__0000007D41715570", +"000000067F00008000000640140000020000-000000067F00008000000640140000024000__0000007D41715570", +"000000067F00008000000640140000021F03-000000067F00008000000640140000028C6A__0000007C73B53FC9-0000007CEE5A0B91", +"000000067F00008000000640140000024000-000000067F00008000000640140000028000__0000007D41715570", +"000000067F000080000006401400000274BF-030000000000000000000000000000000002__0000007CEE5A0B91-0000007D41EA8D51", +"000000067F00008000000640140000028000-000000067F0000800000064014000002C000__0000007D41715570", +"000000067F00008000000640140000028C6A-030000000000000000000000000000000002__0000007C73B53FC9-0000007CEE5A0B91", +"000000067F0000800000064014000002C000-030000000000000000000000000000000002__0000007D41715570", +"000000067F000080000006600C0000000000-000000067F000080000006600C0000004000__0000007F12B83FE8", +"000000067F000080000006600C0000004000-000000067F000080000006600C0000008000__0000007F12B83FE8", +"000000067F000080000006600C0000008000-000000067F000080000006600C000000C000__0000007F12B83FE8", +"000000067F000080000006600C0000009381-000000067F000080000006600C0000012AE7__0000007D41EA8D51-0000007DC21DE569", +"000000067F000080000006600C000000C000-000000067F000080000006600C0000010000__0000007F12B83FE8", +"000000067F000080000006600C0000010000-000000067F000080000006600C0000014000__0000007F12B83FE8", +"000000067F000080000006600C0000012AE7-000000067F000080000006600C000001C20B__0000007D41EA8D51-0000007DC21DE569", +"000000067F000080000006600C0000014000-000000067F000080000006600C0000018000__0000007F12B83FE8", +"000000067F000080000006600C0000018000-000000067F000080000006600C000001C000__0000007F12B83FE8", +"000000067F000080000006600C000001C000-000000067F000080000006600C0000020000__0000007F12B83FE8", +"000000067F000080000006600C000001C20B-000000067F000080000006600C000002593B__0000007D41EA8D51-0000007DC21DE569", +"000000067F000080000006600C0000020000-000000067F000080000006600C0000024000__0000007F12B83FE8", +"000000067F000080000006600C0000024000-000000067F000080000006600C0000028000__0000007F12B83FE8", +"000000067F000080000006600C000002593B-000000067F000080000006600C000002F0A1__0000007D41EA8D51-0000007DC21DE569", +"000000067F000080000006600C0000028000-000000067F000080000006600C000002C000__0000007F12B83FE8", +"000000067F000080000006600C000002C000-000000067F000080000006600C0000030000__0000007F12B83FE8", +"000000067F000080000006600C000002F0A1-000000067F000080000006600C00000387B6__0000007D41EA8D51-0000007DC21DE569", +"000000067F000080000006600C0000030000-000000067F000080000006600C0000034000__0000007F12B83FE8", +"000000067F000080000006600C0000034000-000000067F000080000006600C0000038000__0000007F12B83FE8", +"000000067F000080000006600C0000038000-000000067F000080000006600C000003C000__0000007F12B83FE8", +"000000067F000080000006600C00000387B6-000000067F000080000006600C0000041F1C__0000007D41EA8D51-0000007DC21DE569", +"000000067F000080000006600C000003C000-000000067F000080000006600C0000040000__0000007F12B83FE8", +"000000067F000080000006600C0000040000-000000067F000080000006600C0000044000__0000007F12B83FE8", +"000000067F000080000006600C0000041F1C-000000067F000080000006600C000004B682__0000007D41EA8D51-0000007DC21DE569", +"000000067F000080000006600C0000044000-000000067F000080000006600C0000048000__0000007F12B83FE8", +"000000067F000080000006600C0000048000-000000067F000080000006600C000004C000__0000007F108C1FD8", +"000000067F000080000006600C0000048000-000000067F000080000006600C000004C000__0000007FDCA75700", +"000000067F000080000006600C0000049743-000000067F000080000006600C0000093532__0000007F7BE4E6F1-0000007FDCDCE659", +"000000067F000080000006600C000004B682-030000000000000000000000000000000002__0000007D41EA8D51-0000007DC21DE569", +"000000067F000080000006600C000004BAC3-000000067F000080000006600C00000551F8__0000007DC21DE569-0000007E71DBF8F9", +"000000067F000080000006600C000004C000-000000067F000080000006600C0000050000__0000007F108C1FD8", +"000000067F000080000006600C000004C000-000000067F000080000006600C0000050000__0000007FDCA75700", +"000000067F000080000006600C0000050000-000000067F000080000006600C0000054000__0000007F108C1FD8", +"000000067F000080000006600C0000050000-000000067F000080000006600C0000054000__0000007FDCA75700", +"000000067F000080000006600C0000054000-000000067F000080000006600C0000058000__0000007F108C1FD8", +"000000067F000080000006600C0000054000-000000067F000080000006600C0000058000__0000007FDCA75700", +"000000067F000080000006600C00000551F8-000000067F000080000006600C000005E90C__0000007DC21DE569-0000007E71DBF8F9", +"000000067F000080000006600C0000058000-000000067F000080000006600C000005C000__0000007F108C1FD8", +"000000067F000080000006600C0000058000-000000067F000080000006600C000005C000__0000007FDCA75700", +"000000067F000080000006600C000005C000-000000067F000080000006600C0000060000__0000007F108C1FD8", +"000000067F000080000006600C000005C000-000000067F000080000006600C0000060000__0000007FDCA75700", +"000000067F000080000006600C000005E90C-000000067F000080000006600C000006802C__0000007DC21DE569-0000007E71DBF8F9", +"000000067F000080000006600C0000060000-000000067F000080000006600C0000064000__0000007F108C1FD8", +"000000067F000080000006600C0000060000-000000067F000080000006600C0000064000__0000007FDCA75700", +"000000067F000080000006600C0000064000-000000067F000080000006600C0000068000__0000007F108C1FD8", +"000000067F000080000006600C0000064000-000000067F000080000006600C0000068000__0000007FDCA75700", +"000000067F000080000006600C0000068000-000000067F000080000006600C000006C000__0000007F108C1FD8", +"000000067F000080000006600C0000068000-000000067F000080000006600C000006C000__0000007FDCA75700", +"000000067F000080000006600C000006802C-000000067F000080000006600C0000071783__0000007DC21DE569-0000007E71DBF8F9", +"000000067F000080000006600C000006C000-000000067F000080000006600C0000070000__0000007F108C1FD8", +"000000067F000080000006600C000006C000-000000067F000080000006600C0000070000__0000007FDCA75700", +"000000067F000080000006600C0000070000-000000067F000080000006600C0000074000__0000007F108C1FD8", +"000000067F000080000006600C0000070000-000000067F000080000006600C0000074000__0000007FDCA75700", +"000000067F000080000006600C0000071783-000000067F000080000006600C000007AEE9__0000007DC21DE569-0000007E71DBF8F9", +"000000067F000080000006600C0000074000-000000067F000080000006600C0000078000__0000007F108C1FD8", +"000000067F000080000006600C0000074000-000000067F000080000006600C0000078000__0000007FDCA75700", +"000000067F000080000006600C0000078000-000000067F000080000006600C000007C000__0000007F108C1FD8", +"000000067F000080000006600C0000078000-000000067F000080000006600C000007C000__0000007FDCA75700", +"000000067F000080000006600C000007AEE9-000000067F000080000006600C000008460B__0000007DC21DE569-0000007E71DBF8F9", +"000000067F000080000006600C000007C000-000000067F000080000006600C0000080000__0000007F108C1FD8", +"000000067F000080000006600C000007C000-000000067F000080000006600C0000080000__0000007FDCA75700", +"000000067F000080000006600C0000080000-000000067F000080000006600C0000084000__0000007F108C1FD8", +"000000067F000080000006600C0000080000-000000067F000080000006600C0000084000__0000007FDCA75700", +"000000067F000080000006600C0000084000-000000067F000080000006600C0000088000__0000007F108C1FD8", +"000000067F000080000006600C0000084000-000000067F000080000006600C0000088000__0000007FDCA75700", +"000000067F000080000006600C000008460B-000000067F000080000006600C000008DD71__0000007DC21DE569-0000007E71DBF8F9", +"000000067F000080000006600C0000088000-000000067F000080000006600C000008C000__0000007F108C1FD8", +"000000067F000080000006600C0000088000-000000067F000080000006600C000008C000__0000007FDCA75700", +"000000067F000080000006600C000008C000-000000067F000080000006600C0000090000__0000007F108C1FD8", +"000000067F000080000006600C000008C000-000000067F000080000006600C0000090000__0000007FDCA75700", +"000000067F000080000006600C000008DD71-000000067F000080000006600C00000974D7__0000007DC21DE569-0000007E71DBF8F9", +"000000067F000080000006600C0000090000-000000067F000080000006600C0000094000__0000007F108C1FD8", +"000000067F000080000006600C0000090000-000000067F000080000006600C0000094000__0000007FDCA75700", +"000000067F000080000006600C0000093532-000000067F000080000006600C00000DD150__0000007F7BE4E6F1-0000007FDCDCE659", +"000000067F000080000006600C0000094000-000000067F000080000006600C0000098000__0000007F108C1FD8", +"000000067F000080000006600C0000094000-000000067F000080000006600C0000098000__0000007FDCA75700", +"000000067F000080000006600C00000974D7-000000067F000080000006600C00000A0C0B__0000007DC21DE569-0000007E71DBF8F9", +"000000067F000080000006600C0000098000-000000067F000080000006600C000009C000__0000007F108C1FD8", +"000000067F000080000006600C0000098000-000000067F000080000006600C000009C000__0000007FDCA75700", +"000000067F000080000006600C000009C000-000000067F000080000006600C00000A0000__0000007F108C1FD8", +"000000067F000080000006600C000009C000-000000067F000080000006600C00000A0000__0000007FDCA75700", +"000000067F000080000006600C00000A0000-000000067F000080000006600C00000A4000__0000007F108C1FD8", +"000000067F000080000006600C00000A0000-000000067F000080000006600C00000A4000__0000007FDCA75700", +"000000067F000080000006600C00000A0C0B-000000067F000080000006600C00000AA371__0000007DC21DE569-0000007E71DBF8F9", +"000000067F000080000006600C00000A4000-000000067F000080000006600C00000A8000__0000007F108C1FD8", +"000000067F000080000006600C00000A4000-000000067F000080000006600C00000A8000__0000007FDCA75700", +"000000067F000080000006600C00000A8000-000000067F000080000006600C00000AC000__0000007F108C1FD8", +"000000067F000080000006600C00000A8000-000000067F000080000006600C00000AC000__0000007FDCA75700", +"000000067F000080000006600C00000AA371-000000067F000080000006600C00000B3AD7__0000007DC21DE569-0000007E71DBF8F9", +"000000067F000080000006600C00000AC000-000000067F000080000006600C00000B0000__0000007F108C1FD8", +"000000067F000080000006600C00000AC000-000000067F000080000006600C00000B0000__0000007FDCA75700", +"000000067F000080000006600C00000B0000-000000067F000080000006600C00000B4000__0000007F108C1FD8", +"000000067F000080000006600C00000B0000-000000067F000080000006600C00000B4000__0000007FDCA75700", +"000000067F000080000006600C00000B3AD7-000000067F000080000006600C0100000000__0000007DC21DE569-0000007E71DBF8F9", +"000000067F000080000006600C00000B4000-000000067F000080000006600C00000B8000__0000007F108C1FD8", +"000000067F000080000006600C00000B4000-000000067F000080000006600C00000B8000__0000007FDCA75700", +"000000067F000080000006600C00000B8000-000000067F000080000006600C00000BC000__0000007F108C1FD8", +"000000067F000080000006600C00000B8000-000000067F000080000006600C00000BC000__0000007FDCA75700", +"000000067F000080000006600C00000BC000-000000067F000080000006600C00000C0000__0000007F108C1FD8", +"000000067F000080000006600C00000BC000-000000067F000080000006600C00000C0000__0000007FDCA75700", +"000000067F000080000006600C00000BC29F-000000067F000080000006600C00000C59CF__0000007E71DBF8F9-0000007F11E4BFE9", +"000000067F000080000006600C00000C0000-000000067F000080000006600C00000C4000__0000007F108C1FD8", +"000000067F000080000006600C00000C0000-000000067F000080000006600C00000C4000__0000007FDCA75700", +"000000067F000080000006600C00000C4000-000000067F000080000006600C00000C8000__0000007F108C1FD8", +"000000067F000080000006600C00000C4000-000000067F000080000006600C00000C8000__0000007FDCA75700", +"000000067F000080000006600C00000C59CF-000000067F000080000006600C00000CF10B__0000007E71DBF8F9-0000007F11E4BFE9", +"000000067F000080000006600C00000C8000-000000067F000080000006600C00000CC000__0000007F108C1FD8", +"000000067F000080000006600C00000C8000-000000067F000080000006600C00000CC000__0000007FDCA75700", +"000000067F000080000006600C00000CC000-000000067F000080000006600C00000D0000__0000007F108C1FD8", +"000000067F000080000006600C00000CC000-000000067F000080000006600C00000D0000__0000007FDCA75700", +"000000067F000080000006600C00000CF10B-000000067F000080000006600C00000D882C__0000007E71DBF8F9-0000007F11E4BFE9", +"000000067F000080000006600C00000D0000-000000067F000080000006600C00000D4000__0000007F108C1FD8", +"000000067F000080000006600C00000D0000-000000067F000080000006600C00000D4000__0000007FDCA75700", +"000000067F000080000006600C00000D4000-000000067F000080000006600C00000D8000__0000007F108C1FD8", +"000000067F000080000006600C00000D4000-000000067F000080000006600C00000D8000__0000007FDCA75700", +"000000067F000080000006600C00000D8000-000000067F000080000006600C00000DC000__0000007F108C1FD8", +"000000067F000080000006600C00000D8000-000000067F000080000006600C00000DC000__0000007FDCA75700", +"000000067F000080000006600C00000D882C-000000067F000080000006600C00000E1F7F__0000007E71DBF8F9-0000007F11E4BFE9", +"000000067F000080000006600C00000DC000-000000067F000080000006600C00000E0000__0000007F108C1FD8", +"000000067F000080000006600C00000DC000-000000067F000080000006600C00000E0000__0000007FDCA75700", +"000000067F000080000006600C00000DD152-000000067F00008000000660140000003DA8__0000007F7BE4E6F1-0000007FDCDCE659", +"000000067F000080000006600C00000E0000-000000067F000080000006600C00000E4000__0000007F108C1FD8", +"000000067F000080000006600C00000E0000-000000067F000080000006600C00000E4000__0000007FDCA75700", +"000000067F000080000006600C00000E1F7F-000000067F000080000006600C00000EB6E5__0000007E71DBF8F9-0000007F11E4BFE9", +"000000067F000080000006600C00000E4000-000000067F000080000006600C00000E8000__0000007F108C1FD8", +"000000067F000080000006600C00000E4000-000000067F000080000006600C00000E8000__0000007FDCA75700", +"000000067F000080000006600C00000E8000-000000067F000080000006600C00000EC000__0000007F108C1FD8", +"000000067F000080000006600C00000E8000-000000067F000080000006600C00000EC000__0000007FDCA75700", +"000000067F000080000006600C00000EB6E5-000000067F000080000006600C00000F4E0C__0000007E71DBF8F9-0000007F11E4BFE9", +"000000067F000080000006600C00000EC000-000000067F000080000006600C00000F0000__0000007F108C1FD8", +"000000067F000080000006600C00000EC000-000000067F000080000006600C00000F0000__0000007FDCA75700", +"000000067F000080000006600C00000F0000-000000067F000080000006600C00000F4000__0000007F108C1FD8", +"000000067F000080000006600C00000F0000-000000067F000080000006600C00000F4000__0000007FDCA75700", +"000000067F000080000006600C00000F4000-000000067F000080000006600C00000F8000__0000007F108C1FD8", +"000000067F000080000006600C00000F4000-000000067F000080000006600C00000F8000__0000007FDCA75700", +"000000067F000080000006600C00000F4E0C-000000067F000080000006600C00000FE572__0000007E71DBF8F9-0000007F11E4BFE9", +"000000067F000080000006600C00000F8000-000000067F000080000006600C00000FC000__0000007F108C1FD8", +"000000067F000080000006600C00000F8000-000000067F000080000006600C00000FC000__0000007FDCA75700", +"000000067F000080000006600C00000FC000-000000067F000080000006600C0000100000__0000007F108C1FD8", +"000000067F000080000006600C00000FC000-000000067F000080000006600C0000100000__0000007FDCA75700", +"000000067F000080000006600C00000FE572-000000067F000080000006600C0000107CD8__0000007E71DBF8F9-0000007F11E4BFE9", +"000000067F000080000006600C0000100000-000000067F000080000006600C0000104000__0000007F108C1FD8", +"000000067F000080000006600C0000100000-000000067F000080000006600C0000104000__0000007FDCA75700", +"000000067F000080000006600C0000104000-000000067F000080000006600C0000108000__0000007F108C1FD8", +"000000067F000080000006600C0000104000-000000067F000080000006600C0000108000__0000007FDCA75700", +"000000067F000080000006600C0000107CD8-000000067F000080000006600C000011140B__0000007E71DBF8F9-0000007F11E4BFE9", +"000000067F000080000006600C0000108000-000000067F000080000006600C000010C000__0000007F108C1FD8", +"000000067F000080000006600C0000108000-000000067F000080000006600C000010C000__0000007FDCA75700", +"000000067F000080000006600C000010C000-000000067F000080000006600C0000110000__0000007F108C1FD8", +"000000067F000080000006600C000010C000-000000067F000080000006600C0000110000__0000007FDCA75700", +"000000067F000080000006600C0000110000-000000067F00008000000660120100000000__0000007FDCA75700", +"000000067F000080000006600C0000110000-030000000000000000000000000000000002__0000007F108C1FD8", +"000000067F000080000006600C000011140B-010000000000000001000000030000000010__0000007E71DBF8F9-0000007F11E4BFE9", +"000000067F000080000006600C0000111C82-000000067F0000800000066014000000535B__0000007F11E4BFE9-0000007F7BE4E6F1", +"000000067F00008000000660140000000000-000000067F00008000000660140000004000__0000007FDCA75700", +"000000067F00008000000660140000003DAA-000000067F00008000000660140000017C4D__0000007F7BE4E6F1-0000007FDCDCE659", +"000000067F00008000000660140000004000-000000067F00008000000660140000008000__0000007FDCA75700", +"000000067F0000800000066014000000535B-000000067F0000800000066014000000C839__0000007F11E4BFE9-0000007F7BE4E6F1", +"000000067F00008000000660140000008000-000000067F0000800000066014000000C000__0000007FDCA75700", +"000000067F0000800000066014000000C000-000000067F00008000000660140000010000__0000007FDCA75700", +"000000067F0000800000066014000000C839-000000067F00008000000660140000013D42__0000007F11E4BFE9-0000007F7BE4E6F1", +"000000067F00008000000660140000010000-000000067F00008000000660140000014000__0000007FDCA75700", +"000000067F00008000000660140000013D42-000000067F0000800000066014000001B222__0000007F11E4BFE9-0000007F7BE4E6F1", +"000000067F00008000000660140000014000-000000067F00008000000660140000018000__0000007FDCA75700", +"000000067F00008000000660140000017C51-000000067F0000800000066014000002B9D0__0000007F7BE4E6F1-0000007FDCDCE659", +"000000067F00008000000660140000018000-000000067F0000800000066014000001C000__0000007FDCA75700", +"000000067F0000800000066014000001B222-000000067F00008000000660140000022704__0000007F11E4BFE9-0000007F7BE4E6F1", +"000000067F0000800000066014000001C000-000000067F00008000000660140000020000__0000007FDCA75700", +"000000067F00008000000660140000020000-000000067F00008000000660140000024000__0000007FDCA75700", +"000000067F00008000000660140000022704-000000067F00008000000660140000029C2D__0000007F11E4BFE9-0000007F7BE4E6F1", +"000000067F00008000000660140000024000-000000067F00008000000660140000028000__0000007FDCA75700", +"000000067F00008000000660140000028000-000000067F0000800000066014000002C000__0000007FDCA75700", +"000000067F00008000000660140000029C2D-030000000000000000000000000000000002__0000007F11E4BFE9-0000007F7BE4E6F1", +"000000067F0000800000066014000002B9D1-030000000000000000000000000000000002__0000007F7BE4E6F1-0000007FDCDCE659", +"000000067F0000800000066014000002C000-030000000000000000000000000000000002__0000007FDCA75700", +"000000067F000080000006800C0000000000-000000067F000080000006800C0000004000__00000081AFEDBFE0", +"000000067F000080000006800C0000004000-000000067F000080000006800C0000008000__00000081AFEDBFE0", +"000000067F000080000006800C0000007D6A-000000067F000080000006800C00000114D0__0000007FDCDCE659-000000804F6BFFC1", +"000000067F000080000006800C0000008000-000000067F000080000006800C000000C000__00000081AFEDBFE0", +"000000067F000080000006800C000000C000-000000067F000080000006800C0000010000__00000081AFEDBFE0", +"000000067F000080000006800C0000010000-000000067F000080000006800C0000014000__00000081AFEDBFE0", +"000000067F000080000006800C00000114D0-000000067F000080000006800C000001AC0B__0000007FDCDCE659-000000804F6BFFC1", +"000000067F000080000006800C0000014000-000000067F000080000006800C0000018000__00000081AFEDBFE0", +"000000067F000080000006800C0000018000-000000067F000080000006800C000001C000__00000081AFEDBFE0", +"000000067F000080000006800C000001AC0B-000000067F000080000006800C0000024348__0000007FDCDCE659-000000804F6BFFC1", +"000000067F000080000006800C000001C000-000000067F000080000006800C0000020000__00000081AFEDBFE0", +"000000067F000080000006800C0000020000-000000067F000080000006800C0000024000__00000081AFEDBFE0", +"000000067F000080000006800C0000024000-000000067F000080000006800C0000028000__00000081AFEDBFE0", +"000000067F000080000006800C0000024348-000000067F000080000006800C000002DAAE__0000007FDCDCE659-000000804F6BFFC1", +"000000067F000080000006800C0000028000-000000067F000080000006800C000002C000__00000081AFEDBFE0", +"000000067F000080000006800C000002C000-000000067F000080000006800C0000030000__00000081AFEDBFE0", +"000000067F000080000006800C000002DAAE-000000067F000080000006800C00000371D0__0000007FDCDCE659-000000804F6BFFC1", +"000000067F000080000006800C0000030000-000000067F000080000006800C0000034000__00000081AFEDBFE0", +"000000067F000080000006800C0000034000-000000067F000080000006800C0000038000__00000081AFEDBFE0", +"000000067F000080000006800C00000371D0-000000067F000080000006800C000004090B__0000007FDCDCE659-000000804F6BFFC1", +"000000067F000080000006800C0000038000-000000067F000080000006800C000003C000__00000081AFEDBFE0", +"000000067F000080000006800C000003C000-000000067F000080000006800C0000040000__00000081AFEDBFE0", +"000000067F000080000006800C0000040000-000000067F000080000006800C0000044000__00000081A164D628", +"000000067F000080000006800C000004090B-030000000000000000000000000000000002__0000007FDCDCE659-000000804F6BFFC1", +"000000067F000080000006800C0000042368-000000067F000080000006800C000004BACE__000000804F6BFFC1-00000080EF2FF5B9", +"000000067F000080000006800C0000044000-000000067F000080000006800C0000048000__00000081A164D628", +"000000067F000080000006800C0000048000-000000067F000080000006800C000004C000__00000081A164D628", +"000000067F000080000006800C000004BACE-000000067F000080000006800C0000055202__000000804F6BFFC1-00000080EF2FF5B9", +"000000067F000080000006800C000004C000-000000067F000080000006800C0000050000__00000081A164D628", +"000000067F000080000006800C0000050000-000000067F000080000006800C0000054000__00000081A164D628", +"000000067F000080000006800C0000054000-000000067F000080000006800C0000058000__00000081A164D628", +"000000067F000080000006800C0000055202-000000067F000080000006800C000005E90D__000000804F6BFFC1-00000080EF2FF5B9", +"000000067F000080000006800C0000058000-000000067F000080000006800C000005C000__00000081A164D628", +"000000067F000080000006800C000005C000-000000067F000080000006800C0000060000__00000081A164D628", +"000000067F000080000006800C000005E90D-000000067F000080000006800C000006802B__000000804F6BFFC1-00000080EF2FF5B9", +"000000067F000080000006800C0000060000-000000067F000080000006800C0000064000__00000081A164D628", +"000000067F000080000006800C0000064000-000000067F000080000006800C0000068000__00000081A164D628", +"000000067F000080000006800C0000068000-000000067F000080000006800C000006C000__00000081A164D628", +"000000067F000080000006800C000006802B-000000067F000080000006800C0000071782__000000804F6BFFC1-00000080EF2FF5B9", +"000000067F000080000006800C000006C000-000000067F000080000006800C0000070000__00000081A164D628", +"000000067F000080000006800C0000070000-000000067F000080000006800C0000074000__00000081A164D628", +"000000067F000080000006800C0000071782-000000067F000080000006800C000007AEE8__000000804F6BFFC1-00000080EF2FF5B9", +"000000067F000080000006800C0000074000-000000067F000080000006800C0000078000__00000081A164D628", +"000000067F000080000006800C0000078000-000000067F000080000006800C000007C000__00000081A164D628", +"000000067F000080000006800C000007AEE8-000000067F000080000006800C000008460B__000000804F6BFFC1-00000080EF2FF5B9", +"000000067F000080000006800C000007C000-000000067F000080000006800C0000080000__00000081A164D628", +"000000067F000080000006800C0000080000-000000067F000080000006800C0000084000__00000081A164D628", +"000000067F000080000006800C0000084000-000000067F000080000006800C0000088000__00000081A164D628", +"000000067F000080000006800C000008460B-000000067F000080000006800C000008DD71__000000804F6BFFC1-00000080EF2FF5B9", +"000000067F000080000006800C0000088000-000000067F000080000006800C000008C000__00000081A164D628", +"000000067F000080000006800C000008C000-000000067F000080000006800C0000090000__00000081A164D628", +"000000067F000080000006800C000008DD71-000000067F000080000006800C00000974D7__000000804F6BFFC1-00000080EF2FF5B9", +"000000067F000080000006800C0000090000-000000067F000080000006800C0000094000__00000081A164D628", +"000000067F000080000006800C0000094000-000000067F000080000006800C0000098000__00000081A164D628", +"000000067F000080000006800C00000974D7-000000067F000080000006800C00000A0C0B__000000804F6BFFC1-00000080EF2FF5B9", +"000000067F000080000006800C0000098000-000000067F000080000006800C000009C000__00000081A164D628", +"000000067F000080000006800C000009C000-000000067F000080000006800C00000A0000__00000081A164D628", +"000000067F000080000006800C00000A0000-000000067F000080000006800C00000A4000__00000081A164D628", +"000000067F000080000006800C00000A0C0B-000000067F000080000006800C0100000000__000000804F6BFFC1-00000080EF2FF5B9", +"000000067F000080000006800C00000A4000-000000067F000080000006800C00000A8000__00000081A164D628", +"000000067F000080000006800C00000A8000-000000067F000080000006800C00000AC000__00000081A164D628", +"000000067F000080000006800C00000A8D4C-000000067F000080000006800C00000B24B2__00000080EF2FF5B9-00000081AFAF5FD1", +"000000067F000080000006800C00000AC000-000000067F000080000006800C00000B0000__00000081A164D628", +"000000067F000080000006800C00000B0000-000000067F000080000006800C00000B4000__00000081A164D628", +"000000067F000080000006800C00000B24B2-000000067F000080000006800C00000BBC0B__00000080EF2FF5B9-00000081AFAF5FD1", +"000000067F000080000006800C00000B4000-000000067F000080000006800C00000B8000__00000081A164D628", +"000000067F000080000006800C00000B8000-000000067F000080000006800C00000BC000__00000081A164D628", +"000000067F000080000006800C00000BBC0B-000000067F000080000006800C00000C533F__00000080EF2FF5B9-00000081AFAF5FD1", +"000000067F000080000006800C00000BC000-000000067F000080000006800C00000C0000__00000081A164D628", +"000000067F000080000006800C00000C0000-000000067F000080000006800C00000C4000__00000081A164D628", +"000000067F000080000006800C00000C4000-000000067F000080000006800C00000C8000__00000081A164D628", +"000000067F000080000006800C00000C533F-000000067F000080000006800C00000CEAA5__00000080EF2FF5B9-00000081AFAF5FD1", +"000000067F000080000006800C00000C8000-000000067F000080000006800C00000CC000__00000081A164D628", +"000000067F000080000006800C00000CC000-000000067F000080000006800C00000D0000__00000081A164D628", +"000000067F000080000006800C00000CEAA5-000000067F000080000006800C00000D81BE__00000080EF2FF5B9-00000081AFAF5FD1", +"000000067F000080000006800C00000D0000-000000067F000080000006800C00000D4000__00000081A164D628", +"000000067F000080000006800C00000D4000-000000067F000080000006800C00000D8000__00000081A164D628", +"000000067F000080000006800C00000D8000-000000067F000080000006800C00000DC000__00000081A164D628", +"000000067F000080000006800C00000D81BE-000000067F000080000006800C00000E190B__00000080EF2FF5B9-00000081AFAF5FD1", +"000000067F000080000006800C00000DC000-000000067F000080000006800C00000E0000__00000081A164D628", +"000000067F000080000006800C00000E0000-000000067F000080000006800C00000E4000__00000081A164D628", +"000000067F000080000006800C00000E190B-000000067F000080000006800C00000EB071__00000080EF2FF5B9-00000081AFAF5FD1", +"000000067F000080000006800C00000E4000-000000067F000080000006800C00000E8000__00000081A164D628", +"000000067F000080000006800C00000E8000-000000067F000080000006800C00000EC000__00000081A164D628", +"000000067F000080000006800C00000EB071-000000067F000080000006800C00000F47AC__00000080EF2FF5B9-00000081AFAF5FD1", +"000000067F000080000006800C00000EC000-000000067F000080000006800C00000F0000__00000081A164D628", +"000000067F000080000006800C00000F0000-000000067F000080000006800C00000F4000__00000081A164D628", +"000000067F000080000006800C00000F4000-000000067F000080000006800C00000F8000__00000081A164D628", +"000000067F000080000006800C00000F47AC-000000067F000080000006800C00000FDF0A__00000080EF2FF5B9-00000081AFAF5FD1", +"000000067F000080000006800C00000F8000-000000067F000080000006800C00000FC000__00000081A164D628", +"000000067F000080000006800C00000FC000-000000067F000080000006800C0000100000__00000081A164D628", +"000000067F000080000006800C00000FDF0A-000000067F000080000006800C000010762B__00000080EF2FF5B9-00000081AFAF5FD1", +"000000067F000080000006800C0000100000-000000067F000080000006800C0000104000__00000081A164D628", +"000000067F000080000006800C0000104000-000000067F000080000006800C0000108000__00000081A164D628", +"000000067F000080000006800C000010762B-000000067F000080000006800C0000110D88__00000080EF2FF5B9-00000081AFAF5FD1", +"000000067F000080000006800C0000108000-030000000000000000000000000000000002__00000081A164D628", +"000000067F000080000006800C0000110D88-010000000000000001000000030000000014__00000080EF2FF5B9-00000081AFAF5FD1", +"000000067F000080000006801400000044E4-000000067F0000800000068014000000C3F5__00000081AFAF5FD1-0000008215AFE5A9", +"000000067F0000800000068014000000C3F5-000000067F00008000000680140000014303__00000081AFAF5FD1-0000008215AFE5A9", +"000000067F00008000000680140000014303-000000067F0000800000068014000001C214__00000081AFAF5FD1-0000008215AFE5A9", +"000000067F0000800000068014000001C214-000000067F00008000000680140000024125__00000081AFAF5FD1-0000008215AFE5A9", +"000000067F00008000000680140000024125-000000067F0000800000068014000002C035__00000081AFAF5FD1-0000008215AFE5A9", +"000000067F0000800000068014000002C035-000000067F000080000006A00C00000072CA__00000081AFAF5FD1-0000008215AFE5A9", +"000000067F000080000006A00C0000000000-000000067F000080000006A00C0000004000__00000083D5DE3FD0", +"000000067F000080000006A00C0000004000-000000067F000080000006A00C0000008000__00000083D5DE3FD0", +"000000067F000080000006A00C00000072CA-030000000000000000000000000000000002__00000081AFAF5FD1-0000008215AFE5A9", +"000000067F000080000006A00C0000008000-000000067F000080000006A00C000000C000__00000083865C64B8", +"000000067F000080000006A00C0000008000-000000067F000080000006A00C000000C000__00000084A1F03030", +"000000067F000080000006A00C00000096E3-000000067F000080000006A00C0000012E0B__0000008215AFE5A9-00000082B573F579", +"000000067F000080000006A00C000000C000-000000067F000080000006A00C0000010000__00000083865C64B8", +"000000067F000080000006A00C000000C000-000000067F000080000006A00C0000010000__00000084A1F03030", +"000000067F000080000006A00C0000010000-000000067F000080000006A00C0000014000__00000083865C64B8", +"000000067F000080000006A00C0000010000-000000067F000080000006A00C0000014000__00000084A1F03030", +"000000067F000080000006A00C0000012E0B-000000067F000080000006A00C000001C571__0000008215AFE5A9-00000082B573F579", +"000000067F000080000006A00C0000014000-000000067F000080000006A00C0000018000__00000083865C64B8", +"000000067F000080000006A00C0000014000-000000067F000080000006A00C0000018000__00000084A1F03030", +"000000067F000080000006A00C0000018000-000000067F000080000006A00C000001C000__00000083865C64B8", +"000000067F000080000006A00C0000018000-000000067F000080000006A00C000001C000__00000084A1F03030", +"000000067F000080000006A00C000001C000-000000067F000080000006A00C0000020000__00000083865C64B8", +"000000067F000080000006A00C000001C000-000000067F000080000006A00C0000020000__00000084A1F03030", +"000000067F000080000006A00C000001C571-000000067F000080000006A00C0000025CD7__0000008215AFE5A9-00000082B573F579", +"000000067F000080000006A00C0000020000-000000067F000080000006A00C0000024000__00000083865C64B8", +"000000067F000080000006A00C0000020000-000000067F000080000006A00C0000024000__00000084A1F03030", +"000000067F000080000006A00C0000024000-000000067F000080000006A00C0000028000__00000083865C64B8", +"000000067F000080000006A00C0000024000-000000067F000080000006A00C0000028000__00000084A1F03030", +"000000067F000080000006A00C0000025CD7-000000067F000080000006A00C000002F40B__0000008215AFE5A9-00000082B573F579", +"000000067F000080000006A00C0000028000-000000067F000080000006A00C000002C000__00000083865C64B8", +"000000067F000080000006A00C0000028000-000000067F000080000006A00C000002C000__00000084A1F03030", +"000000067F000080000006A00C000002C000-000000067F000080000006A00C0000030000__00000083865C64B8", +"000000067F000080000006A00C000002C000-000000067F000080000006A00C0000030000__00000084A1F03030", +"000000067F000080000006A00C000002F40B-000000067F000080000006A00C0000038B1E__0000008215AFE5A9-00000082B573F579", +"000000067F000080000006A00C0000030000-000000067F000080000006A00C0000034000__00000083865C64B8", +"000000067F000080000006A00C0000030000-000000067F000080000006A00C0000034000__00000084A1F03030", +"000000067F000080000006A00C0000034000-000000067F000080000006A00C0000038000__00000083865C64B8", +"000000067F000080000006A00C0000034000-000000067F000080000006A00C0000038000__00000084A1F03030", +"000000067F000080000006A00C0000038000-000000067F000080000006A00C000003C000__00000083865C64B8", +"000000067F000080000006A00C0000038000-000000067F000080000006A00C000003C000__00000084A1F03030", +"000000067F000080000006A00C0000038B1E-000000067F000080000006A00C0000042284__0000008215AFE5A9-00000082B573F579", +"000000067F000080000006A00C000003C000-000000067F000080000006A00C0000040000__00000083865C64B8", +"000000067F000080000006A00C000003C000-000000067F000080000006A00C0000040000__00000084A1F03030", +"000000067F000080000006A00C0000040000-000000067F000080000006A00C0000044000__00000083865C64B8", +"000000067F000080000006A00C0000040000-000000067F000080000006A00C0000044000__00000084A1F03030", +"000000067F000080000006A00C0000042284-000000067F000080000006A00C000004B9EA__0000008215AFE5A9-00000082B573F579", +"000000067F000080000006A00C0000044000-000000067F000080000006A00C0000048000__00000083865C64B8", +"000000067F000080000006A00C0000044000-000000067F000080000006A00C0000048000__00000084A1F03030", +"000000067F000080000006A00C0000048000-000000067F000080000006A00C000004C000__00000083865C64B8", +"000000067F000080000006A00C0000048000-000000067F000080000006A00C000004C000__00000084A1F03030", +"000000067F000080000006A00C000004B9EA-000000067F000080000006A00C000005510B__0000008215AFE5A9-00000082B573F579", +"000000067F000080000006A00C000004C000-000000067F000080000006A00C0000050000__00000083865C64B8", +"000000067F000080000006A00C000004C000-000000067F000080000006A00C0000050000__00000084A1F03030", +"000000067F000080000006A00C0000050000-000000067F000080000006A00C0000054000__00000083865C64B8", +"000000067F000080000006A00C0000050000-000000067F000080000006A00C0000054000__00000084A1F03030", +"000000067F000080000006A00C000005198B-000000067F000080000006A00C00000A31A6__000000844F1A6789-00000084A325AA01", +"000000067F000080000006A00C0000054000-000000067F000080000006A00C0000058000__00000083865C64B8", +"000000067F000080000006A00C0000054000-000000067F000080000006A00C0000058000__00000084A1F03030", +"000000067F000080000006A00C000005510B-000000067F000080000006A00C000005E871__0000008215AFE5A9-00000082B573F579", +"000000067F000080000006A00C0000058000-000000067F000080000006A00C000005C000__00000083865C64B8", +"000000067F000080000006A00C0000058000-000000067F000080000006A00C000005C000__00000084A1F03030", +"000000067F000080000006A00C000005C000-000000067F000080000006A00C0000060000__00000083865C64B8", +"000000067F000080000006A00C000005C000-000000067F000080000006A00C0000060000__00000084A1F03030", +"000000067F000080000006A00C000005E871-000000067F000080000006A00C0000067F8B__0000008215AFE5A9-00000082B573F579", +"000000067F000080000006A00C0000060000-000000067F000080000006A00C0000064000__00000083865C64B8", +"000000067F000080000006A00C0000060000-000000067F000080000006A00C0000064000__00000084A1F03030", +"000000067F000080000006A00C0000064000-000000067F000080000006A00C0000068000__00000083865C64B8", +"000000067F000080000006A00C0000064000-000000067F000080000006A00C0000068000__00000084A1F03030", +"000000067F000080000006A00C0000067F8B-000000067F000080000006A00C0100000000__0000008215AFE5A9-00000082B573F579", +"000000067F000080000006A00C0000068000-000000067F000080000006A00C000006C000__00000083865C64B8", +"000000067F000080000006A00C0000068000-000000067F000080000006A00C000006C000__00000084A1F03030", +"000000067F000080000006A00C000006C000-000000067F000080000006A00C0000070000__00000083865C64B8", +"000000067F000080000006A00C000006C000-000000067F000080000006A00C0000070000__00000084A1F03030", +"000000067F000080000006A00C0000070000-000000067F000080000006A00C0000074000__00000083865C64B8", +"000000067F000080000006A00C0000070000-000000067F000080000006A00C0000074000__00000084A1F03030", +"000000067F000080000006A00C00000703EC-000000067F000080000006A00C0000079B0C__00000082B573F579-00000083D5901FD9", +"000000067F000080000006A00C0000074000-000000067F000080000006A00C0000078000__00000083865C64B8", +"000000067F000080000006A00C0000074000-000000067F000080000006A00C0000078000__00000084A1F03030", +"000000067F000080000006A00C0000078000-000000067F000080000006A00C000007C000__00000083865C64B8", +"000000067F000080000006A00C0000078000-000000067F000080000006A00C000007C000__00000084A1F03030", +"000000067F000080000006A00C0000079B0C-000000067F000080000006A00C0000083272__00000082B573F579-00000083D5901FD9", +"000000067F000080000006A00C000007C000-000000067F000080000006A00C0000080000__00000083865C64B8", +"000000067F000080000006A00C000007C000-000000067F000080000006A00C0000080000__00000084A1F03030", +"000000067F000080000006A00C0000080000-000000067F000080000006A00C0000084000__00000083865C64B8", +"000000067F000080000006A00C0000080000-000000067F000080000006A00C0000084000__00000084A1F03030", +"000000067F000080000006A00C0000083272-000000067F000080000006A00C000008C9D8__00000082B573F579-00000083D5901FD9", +"000000067F000080000006A00C0000084000-000000067F000080000006A00C0000088000__00000083865C64B8", +"000000067F000080000006A00C0000084000-000000067F000080000006A00C0000088000__00000084A1F03030", +"000000067F000080000006A00C0000088000-000000067F000080000006A00C000008C000__00000083865C64B8", +"000000067F000080000006A00C0000088000-000000067F000080000006A00C000008C000__00000084A1F03030", +"000000067F000080000006A00C000008C000-000000067F000080000006A00C0000090000__00000083865C64B8", +"000000067F000080000006A00C000008C000-000000067F000080000006A00C0000090000__00000084A1F03030", +"000000067F000080000006A00C000008C9D8-000000067F000080000006A00C0000096129__00000082B573F579-00000083D5901FD9", +"000000067F000080000006A00C0000090000-000000067F000080000006A00C0000094000__00000083865C64B8", +"000000067F000080000006A00C0000090000-000000067F000080000006A00C0000094000__00000084A1F03030", +"000000067F000080000006A00C0000094000-000000067F000080000006A00C0000098000__00000083865C64B8", +"000000067F000080000006A00C0000094000-000000067F000080000006A00C0000098000__00000084A1F03030", +"000000067F000080000006A00C0000096129-000000067F000080000006A00C000009F88F__00000082B573F579-00000083D5901FD9", +"000000067F000080000006A00C0000098000-000000067F000080000006A00C000009C000__00000083865C64B8", +"000000067F000080000006A00C0000098000-000000067F000080000006A00C000009C000__00000084A1F03030", +"000000067F000080000006A00C000009C000-000000067F000080000006A00C00000A0000__00000083865C64B8", +"000000067F000080000006A00C000009C000-000000067F000080000006A00C00000A0000__00000084A1F03030", +"000000067F000080000006A00C000009F88F-000000067F000080000006A00C00000A8F9F__00000082B573F579-00000083D5901FD9", +"000000067F000080000006A00C00000A0000-000000067F000080000006A00C00000A4000__00000083865C64B8", +"000000067F000080000006A00C00000A0000-000000067F000080000006A00C00000A4000__00000084A1F03030", +"000000067F000080000006A00C00000A31B0-000000067F000080000006A00C00000F4C19__000000844F1A6789-00000084A325AA01", +"000000067F000080000006A00C00000A4000-000000067F000080000006A00C00000A8000__00000083865C64B8", +"000000067F000080000006A00C00000A4000-000000067F000080000006A00C00000A8000__00000084A1F03030", +"000000067F000080000006A00C00000A8000-000000067F000080000006A00C00000AC000__00000083865C64B8", +"000000067F000080000006A00C00000A8000-000000067F000080000006A00C00000AC000__00000084A1F03030", +"000000067F000080000006A00C00000A8F9F-000000067F000080000006A00C00000B2705__00000082B573F579-00000083D5901FD9", +"000000067F000080000006A00C00000AC000-000000067F000080000006A00C00000B0000__00000083865C64B8", +"000000067F000080000006A00C00000AC000-000000067F000080000006A00C00000B0000__00000084A1F03030", +"000000067F000080000006A00C00000B0000-000000067F000080000006A00C00000B4000__00000083865C64B8", +"000000067F000080000006A00C00000B0000-000000067F000080000006A00C00000B4000__00000084A1F03030", +"000000067F000080000006A00C00000B2705-000000067F000080000006A00C00000BBE10__00000082B573F579-00000083D5901FD9", +"000000067F000080000006A00C00000B4000-000000067F000080000006A00C00000B8000__00000083865C64B8", +"000000067F000080000006A00C00000B4000-000000067F000080000006A00C00000B8000__00000084A1F03030", +"000000067F000080000006A00C00000B8000-000000067F000080000006A00C00000BC000__00000083865C64B8", +"000000067F000080000006A00C00000B8000-000000067F000080000006A00C00000BC000__00000084A1F03030", +"000000067F000080000006A00C00000BBE10-000000067F000080000006A00C00000C5543__00000082B573F579-00000083D5901FD9", +"000000067F000080000006A00C00000BC000-000000067F000080000006A00C00000C0000__00000083865C64B8", +"000000067F000080000006A00C00000BC000-000000067F000080000006A00C00000C0000__00000084A1F03030", +"000000067F000080000006A00C00000C0000-000000067F000080000006A00C00000C4000__00000083865C64B8", +"000000067F000080000006A00C00000C0000-000000067F000080000006A00C00000C4000__00000084A1F03030", +"000000067F000080000006A00C00000C4000-000000067F000080000006A00C00000C8000__00000083865C64B8", +"000000067F000080000006A00C00000C4000-000000067F000080000006A00C00000C8000__00000084A1F03030", +"000000067F000080000006A00C00000C4CC8-000000067F000080000006A0140000001CBC__00000083D5901FD9-000000844F1A6789", +"000000067F000080000006A00C00000C5543-000000067F000080000006A00C00000CECA9__00000082B573F579-00000083D5901FD9", +"000000067F000080000006A00C00000C8000-000000067F000080000006A00C00000CC000__00000083865C64B8", +"000000067F000080000006A00C00000C8000-000000067F000080000006A00C00000CC000__00000084A1F03030", +"000000067F000080000006A00C00000CC000-000000067F000080000006A00C00000D0000__00000083865C64B8", +"000000067F000080000006A00C00000CC000-000000067F000080000006A00C00000D0000__00000084A1F03030", +"000000067F000080000006A00C00000CECA9-000000067F000080000006A00C00000D83C0__00000082B573F579-00000083D5901FD9", +"000000067F000080000006A00C00000D0000-000000067F000080000006A00C00000D4000__00000083865C64B8", +"000000067F000080000006A00C00000D0000-000000067F000080000006A00C00000D4000__00000084A1F03030", +"000000067F000080000006A00C00000D4000-000000067F000080000006A00C00000D8000__00000083865C64B8", +"000000067F000080000006A00C00000D4000-000000067F000080000006A00C00000D8000__00000084A1F03030", +"000000067F000080000006A00C00000D8000-000000067F000080000006A00C00000DC000__00000083865C64B8", +"000000067F000080000006A00C00000D8000-000000067F000080000006A00C00000DC000__00000084A1F03030", +"000000067F000080000006A00C00000D83C0-000000067F000080000006A00C00000E1B0A__00000082B573F579-00000083D5901FD9", +"000000067F000080000006A00C00000DC000-000000067F000080000006A00C00000E0000__00000083865C64B8", +"000000067F000080000006A00C00000DC000-000000067F000080000006A00C00000E0000__00000084A1F03030", +"000000067F000080000006A00C00000E0000-000000067F000080000006A00C00000E4000__00000084A1F03030", +"000000067F000080000006A00C00000E0000-030000000000000000000000000000000002__00000083865C64B8", +"000000067F000080000006A00C00000E1B0A-000000067F000080000006A00C00000EB270__00000082B573F579-00000083D5901FD9", +"000000067F000080000006A00C00000E4000-000000067F000080000006A00C00000E8000__00000084A1F03030", +"000000067F000080000006A00C00000E8000-000000067F000080000006A00C00000EC000__00000084A1F03030", +"000000067F000080000006A00C00000EB270-000000067F000080000006A00C00000F49AA__00000082B573F579-00000083D5901FD9", +"000000067F000080000006A00C00000EC000-000000067F000080000006A00C00000F0000__00000084A1F03030", +"000000067F000080000006A00C00000F0000-000000067F000080000006A00C00000F4000__00000084A1F03030", +"000000067F000080000006A00C00000F4000-000000067F000080000006A00C00000F8000__00000084A1F03030", +"000000067F000080000006A00C00000F49AA-000000067F000080000006A00C00000FE10A__00000082B573F579-00000083D5901FD9", +"000000067F000080000006A00C00000F4C23-000000067F000080000006A014000000E1C2__000000844F1A6789-00000084A325AA01", +"000000067F000080000006A00C00000F8000-000000067F000080000006A00C00000FC000__00000084A1F03030", +"000000067F000080000006A00C00000FC000-000000067F000080000006A00C0000100000__00000084A1F03030", +"000000067F000080000006A00C00000FE10A-000000067F000080000006A00C000010782C__00000082B573F579-00000083D5901FD9", +"000000067F000080000006A00C0000100000-000000067F000080000006A00C0000104000__00000084A1F03030", +"000000067F000080000006A00C0000104000-000000067F000080000006A00C0000108000__00000084A1F03030", +"000000067F000080000006A00C000010782C-000000067F000080000006A00C0000110F88__00000082B573F579-00000083D5901FD9", +"000000067F000080000006A00C0000108000-000000067F000080000006A00C000010C000__00000084A1F03030", +"000000067F000080000006A00C000010C000-000000067F000080000006A00C0000110000__00000084A1F03030", +"000000067F000080000006A00C0000110000-000000067F000080000006A0120100000000__00000084A1F03030", +"000000067F000080000006A00C0000110F88-010000000000000001000000030000000014__00000082B573F579-00000083D5901FD9", +"000000067F000080000006A0140000000000-000000067F000080000006A0140000004000__00000084A1F03030", +"000000067F000080000006A0140000001CBC-000000067F000080000006A01400000088E1__00000083D5901FD9-000000844F1A6789", +"000000067F000080000006A0140000004000-000000067F000080000006A0140000008000__00000084A1F03030", +"000000067F000080000006A0140000008000-000000067F000080000006A014000000C000__00000084A1F03030", +"000000067F000080000006A01400000088E1-000000067F000080000006A014000000F459__00000083D5901FD9-000000844F1A6789", +"000000067F000080000006A014000000C000-000000067F000080000006A0140000010000__00000084A1F03030", +"000000067F000080000006A014000000E1C2-000000067F000080000006A014000002682C__000000844F1A6789-00000084A325AA01", +"000000067F000080000006A014000000F459-000000067F000080000006A0140000016068__00000083D5901FD9-000000844F1A6789", +"000000067F000080000006A0140000010000-000000067F000080000006A0140000014000__00000084A1F03030", +"000000067F000080000006A0140000014000-000000067F000080000006A0140000018000__00000084A1F03030", +"000000067F000080000006A0140000016068-000000067F000080000006A014000001CC14__00000083D5901FD9-000000844F1A6789", +"000000067F000080000006A0140000018000-000000067F000080000006A014000001C000__00000084A1F03030", +"000000067F000080000006A014000001C000-000000067F000080000006A0140000020000__00000084A1F03030", +"000000067F000080000006A014000001CC14-000000067F000080000006A014000002384E__00000083D5901FD9-000000844F1A6789", +"000000067F000080000006A0140000020000-000000067F000080000006A0140000024000__00000084A1F03030", +"000000067F000080000006A014000002384E-000000067F000080000006A014000002A467__00000083D5901FD9-000000844F1A6789", +"000000067F000080000006A0140000024000-000000067F000080000006A0140000028000__00000084A1F03030", +"000000067F000080000006A0140000026831-030000000000000000000000000000000002__000000844F1A6789-00000084A325AA01", +"000000067F000080000006A0140000028000-000000067F000080000006A014000002C000__00000084A1F03030", +"000000067F000080000006A014000002A467-030000000000000000000000000000000002__00000083D5901FD9-000000844F1A6789", +"000000067F000080000006A014000002C000-030000000000000000000000000000000002__00000084A1F03030", +"000000067F000080000006C00C0000000000-000000067F000080000006C00C0000004000__00000086746BDFE0", +"000000067F000080000006C00C0000004000-000000067F000080000006C00C0000008000__00000086746BDFE0", +"000000067F000080000006C00C0000008000-000000067F000080000006C00C000000C000__00000086746BDFE0", +"000000067F000080000006C00C00000090F5-000000067F000080000006C00C000001280C__00000084A325AA01-00000085239DFB81", +"000000067F000080000006C00C000000C000-000000067F000080000006C00C0000010000__00000086746BDFE0", +"000000067F000080000006C00C0000010000-000000067F000080000006C00C0000014000__00000086746BDFE0", +"000000067F000080000006C00C000001280C-000000067F000080000006C00C000001BF72__00000084A325AA01-00000085239DFB81", +"000000067F000080000006C00C0000014000-000000067F000080000006C00C0000018000__00000086746BDFE0", +"000000067F000080000006C00C0000018000-000000067F000080000006C00C000001C000__00000086746BDFE0", +"000000067F000080000006C00C000001BF72-000000067F000080000006C00C00000256D8__00000084A325AA01-00000085239DFB81", +"000000067F000080000006C00C000001C000-000000067F000080000006C00C0000020000__00000086746BDFE0", +"000000067F000080000006C00C0000020000-000000067F000080000006C00C0000024000__00000086746BDFE0", +"000000067F000080000006C00C0000024000-000000067F000080000006C00C0000028000__00000086746BDFE0", +"000000067F000080000006C00C00000256D8-000000067F000080000006C00C000002EE0B__00000084A325AA01-00000085239DFB81", +"000000067F000080000006C00C0000028000-000000067F000080000006C00C000002C000__00000086746BDFE0", +"000000067F000080000006C00C000002C000-000000067F000080000006C00C0000030000__00000086746BDFE0", +"000000067F000080000006C00C000002EE0B-000000067F000080000006C00C0000038521__00000084A325AA01-00000085239DFB81", +"000000067F000080000006C00C0000030000-000000067F000080000006C00C0000034000__00000086746BDFE0", +"000000067F000080000006C00C0000034000-000000067F000080000006C00C0000038000__00000086746BDFE0", +"000000067F000080000006C00C0000038000-000000067F000080000006C00C000003C000__00000086746BDFE0", +"000000067F000080000006C00C0000038521-000000067F000080000006C00C0000041C87__00000084A325AA01-00000085239DFB81", +"000000067F000080000006C00C000003C000-000000067F000080000006C00C0000040000__00000086746BDFE0", +"000000067F000080000006C00C0000040000-000000067F000080000006C00C0000044000__00000086746BDFE0", +"000000067F000080000006C00C0000041C87-000000067F000080000006C00C000004B3ED__00000084A325AA01-00000085239DFB81", +"000000067F000080000006C00C0000044000-000000067F000080000006C00C0000048000__00000086746BDFE0", +"000000067F000080000006C00C0000048000-000000067F000080000006C00C000004C000__00000086720CFFF0", +"000000067F000080000006C00C0000048000-000000067F000080000006C00C000004C000__000000873B520940", +"000000067F000080000006C00C000004B3ED-030000000000000000000000000000000002__00000084A325AA01-00000085239DFB81", +"000000067F000080000006C00C000004BAC4-000000067F000080000006C00C00000551F9__00000085239DFB81-00000085D35BF439", +"000000067F000080000006C00C000004C000-000000067F000080000006C00C0000050000__00000086720CFFF0", +"000000067F000080000006C00C000004C000-000000067F000080000006C00C0000050000__000000873B520940", +"000000067F000080000006C00C0000050000-000000067F000080000006C00C0000054000__00000086720CFFF0", +"000000067F000080000006C00C0000050000-000000067F000080000006C00C0000054000__000000873B520940", +"000000067F000080000006C00C0000054000-000000067F000080000006C00C0000058000__00000086720CFFF0", +"000000067F000080000006C00C0000054000-000000067F000080000006C00C0000058000__000000873B520940", +"000000067F000080000006C00C00000551F9-000000067F000080000006C00C000005E90C__00000085239DFB81-00000085D35BF439", +"000000067F000080000006C00C0000055EB3-000000067F000080000006C00C00000AB316__00000086ED29E361-000000873C9A2551", +"000000067F000080000006C00C0000058000-000000067F000080000006C00C000005C000__00000086720CFFF0", +"000000067F000080000006C00C0000058000-000000067F000080000006C00C000005C000__000000873B520940", +"000000067F000080000006C00C000005C000-000000067F000080000006C00C0000060000__00000086720CFFF0", +"000000067F000080000006C00C000005C000-000000067F000080000006C00C0000060000__000000873B520940", +"000000067F000080000006C00C000005E90C-000000067F000080000006C00C000006802C__00000085239DFB81-00000085D35BF439", +"000000067F000080000006C00C0000060000-000000067F000080000006C00C0000064000__00000086720CFFF0", +"000000067F000080000006C00C0000060000-000000067F000080000006C00C0000064000__000000873B520940", +"000000067F000080000006C00C0000064000-000000067F000080000006C00C0000068000__00000086720CFFF0", +"000000067F000080000006C00C0000064000-000000067F000080000006C00C0000068000__000000873B520940", +"000000067F000080000006C00C0000068000-000000067F000080000006C00C000006C000__00000086720CFFF0", +"000000067F000080000006C00C0000068000-000000067F000080000006C00C000006C000__000000873B520940", +"000000067F000080000006C00C000006802C-000000067F000080000006C00C0000071783__00000085239DFB81-00000085D35BF439", +"000000067F000080000006C00C000006C000-000000067F000080000006C00C0000070000__00000086720CFFF0", +"000000067F000080000006C00C000006C000-000000067F000080000006C00C0000070000__000000873B520940", +"000000067F000080000006C00C0000070000-000000067F000080000006C00C0000074000__00000086720CFFF0", +"000000067F000080000006C00C0000070000-000000067F000080000006C00C0000074000__000000873B520940", +"000000067F000080000006C00C0000071783-000000067F000080000006C00C000007AEE9__00000085239DFB81-00000085D35BF439", +"000000067F000080000006C00C0000074000-000000067F000080000006C00C0000078000__00000086720CFFF0", +"000000067F000080000006C00C0000074000-000000067F000080000006C00C0000078000__000000873B520940", +"000000067F000080000006C00C0000078000-000000067F000080000006C00C000007C000__00000086720CFFF0", +"000000067F000080000006C00C0000078000-000000067F000080000006C00C000007C000__000000873B520940", +"000000067F000080000006C00C000007AEE9-000000067F000080000006C00C000008460B__00000085239DFB81-00000085D35BF439", +"000000067F000080000006C00C000007C000-000000067F000080000006C00C0000080000__00000086720CFFF0", +"000000067F000080000006C00C000007C000-000000067F000080000006C00C0000080000__000000873B520940", +"000000067F000080000006C00C0000080000-000000067F000080000006C00C0000084000__00000086720CFFF0", +"000000067F000080000006C00C0000080000-000000067F000080000006C00C0000084000__000000873B520940", +"000000067F000080000006C00C0000084000-000000067F000080000006C00C0000088000__00000086720CFFF0", +"000000067F000080000006C00C0000084000-000000067F000080000006C00C0000088000__000000873B520940", +"000000067F000080000006C00C000008460B-000000067F000080000006C00C000008DD71__00000085239DFB81-00000085D35BF439", +"000000067F000080000006C00C0000088000-000000067F000080000006C00C000008C000__00000086720CFFF0", +"000000067F000080000006C00C0000088000-000000067F000080000006C00C000008C000__000000873B520940", +"000000067F000080000006C00C000008C000-000000067F000080000006C00C0000090000__00000086720CFFF0", +"000000067F000080000006C00C000008C000-000000067F000080000006C00C0000090000__000000873B520940", +"000000067F000080000006C00C000008DD71-000000067F000080000006C00C00000974D7__00000085239DFB81-00000085D35BF439", +"000000067F000080000006C00C0000090000-000000067F000080000006C00C0000094000__00000086720CFFF0", +"000000067F000080000006C00C0000090000-000000067F000080000006C00C0000094000__000000873B520940", +"000000067F000080000006C00C0000094000-000000067F000080000006C00C0000098000__00000086720CFFF0", +"000000067F000080000006C00C0000094000-000000067F000080000006C00C0000098000__000000873B520940", +"000000067F000080000006C00C00000974D7-000000067F000080000006C00C00000A0C0B__00000085239DFB81-00000085D35BF439", +"000000067F000080000006C00C0000098000-000000067F000080000006C00C000009C000__00000086720CFFF0", +"000000067F000080000006C00C0000098000-000000067F000080000006C00C000009C000__000000873B520940", +"000000067F000080000006C00C000009C000-000000067F000080000006C00C00000A0000__00000086720CFFF0", +"000000067F000080000006C00C000009C000-000000067F000080000006C00C00000A0000__000000873B520940", +"000000067F000080000006C00C00000A0000-000000067F000080000006C00C00000A4000__00000086720CFFF0", +"000000067F000080000006C00C00000A0000-000000067F000080000006C00C00000A4000__000000873B520940", +"000000067F000080000006C00C00000A0C0B-000000067F000080000006C00C00000AA371__00000085239DFB81-00000085D35BF439", +"000000067F000080000006C00C00000A4000-000000067F000080000006C00C00000A8000__00000086720CFFF0", +"000000067F000080000006C00C00000A4000-000000067F000080000006C00C00000A8000__000000873B520940", +"000000067F000080000006C00C00000A8000-000000067F000080000006C00C00000AC000__00000086720CFFF0", +"000000067F000080000006C00C00000A8000-000000067F000080000006C00C00000AC000__000000873B520940", +"000000067F000080000006C00C00000AA371-000000067F000080000006C00C00000B3AD7__00000085239DFB81-00000085D35BF439", +"000000067F000080000006C00C00000AB316-000000067F000080000006C00C00001015F1__00000086ED29E361-000000873C9A2551", +"000000067F000080000006C00C00000AC000-000000067F000080000006C00C00000B0000__00000086720CFFF0", +"000000067F000080000006C00C00000AC000-000000067F000080000006C00C00000B0000__000000873B520940", +"000000067F000080000006C00C00000B0000-000000067F000080000006C00C00000B4000__00000086720CFFF0", +"000000067F000080000006C00C00000B0000-000000067F000080000006C00C00000B4000__000000873B520940", +"000000067F000080000006C00C00000B3AD7-000000067F000080000006C00C0100000000__00000085239DFB81-00000085D35BF439", +"000000067F000080000006C00C00000B4000-000000067F000080000006C00C00000B8000__00000086720CFFF0", +"000000067F000080000006C00C00000B4000-000000067F000080000006C00C00000B8000__000000873B520940", +"000000067F000080000006C00C00000B8000-000000067F000080000006C00C00000BC000__00000086720CFFF0", +"000000067F000080000006C00C00000B8000-000000067F000080000006C00C00000BC000__000000873B520940", +"000000067F000080000006C00C00000BC000-000000067F000080000006C00C00000C0000__00000086720CFFF0", +"000000067F000080000006C00C00000BC000-000000067F000080000006C00C00000C0000__000000873B520940", +"000000067F000080000006C00C00000BC102-000000067F000080000006C00C00000C580D__00000085D35BF439-0000008673817FC9", +"000000067F000080000006C00C00000BFB6E-000000067F000080000006C01400000016BC__0000008673817FC9-00000086ED29E361", +"000000067F000080000006C00C00000C0000-000000067F000080000006C00C00000C4000__00000086720CFFF0", +"000000067F000080000006C00C00000C0000-000000067F000080000006C00C00000C4000__000000873B520940", +"000000067F000080000006C00C00000C4000-000000067F000080000006C00C00000C8000__00000086720CFFF0", +"000000067F000080000006C00C00000C4000-000000067F000080000006C00C00000C8000__000000873B520940", +"000000067F000080000006C00C00000C580D-000000067F000080000006C00C00000CEF73__00000085D35BF439-0000008673817FC9", +"000000067F000080000006C00C00000C8000-000000067F000080000006C00C00000CC000__00000086720CFFF0", +"000000067F000080000006C00C00000C8000-000000067F000080000006C00C00000CC000__000000873B520940", +"000000067F000080000006C00C00000CC000-000000067F000080000006C00C00000D0000__00000086720CFFF0", +"000000067F000080000006C00C00000CC000-000000067F000080000006C00C00000D0000__000000873B520940", +"000000067F000080000006C00C00000CEF73-000000067F000080000006C00C00000D86D9__00000085D35BF439-0000008673817FC9", +"000000067F000080000006C00C00000D0000-000000067F000080000006C00C00000D4000__00000086720CFFF0", +"000000067F000080000006C00C00000D0000-000000067F000080000006C00C00000D4000__000000873B520940", +"000000067F000080000006C00C00000D4000-000000067F000080000006C00C00000D8000__00000086720CFFF0", +"000000067F000080000006C00C00000D4000-000000067F000080000006C00C00000D8000__000000873B520940", +"000000067F000080000006C00C00000D8000-000000067F000080000006C00C00000DC000__00000086720CFFF0", +"000000067F000080000006C00C00000D8000-000000067F000080000006C00C00000DC000__000000873B520940", +"000000067F000080000006C00C00000D86D9-000000067F000080000006C00C00000E1E0C__00000085D35BF439-0000008673817FC9", +"000000067F000080000006C00C00000DC000-000000067F000080000006C00C00000E0000__00000086720CFFF0", +"000000067F000080000006C00C00000DC000-000000067F000080000006C00C00000E0000__000000873B520940", +"000000067F000080000006C00C00000E0000-000000067F000080000006C00C00000E4000__00000086720CFFF0", +"000000067F000080000006C00C00000E0000-000000067F000080000006C00C00000E4000__000000873B520940", +"000000067F000080000006C00C00000E1E0C-000000067F000080000006C00C00000EB572__00000085D35BF439-0000008673817FC9", +"000000067F000080000006C00C00000E4000-000000067F000080000006C00C00000E8000__00000086720CFFF0", +"000000067F000080000006C00C00000E4000-000000067F000080000006C00C00000E8000__000000873B520940", +"000000067F000080000006C00C00000E8000-000000067F000080000006C00C00000EC000__00000086720CFFF0", +"000000067F000080000006C00C00000E8000-000000067F000080000006C00C00000EC000__000000873B520940", +"000000067F000080000006C00C00000EB572-000000067F000080000006C00C00000F4CD8__00000085D35BF439-0000008673817FC9", +"000000067F000080000006C00C00000EC000-000000067F000080000006C00C00000F0000__00000086720CFFF0", +"000000067F000080000006C00C00000EC000-000000067F000080000006C00C00000F0000__000000873B520940", +"000000067F000080000006C00C00000F0000-000000067F000080000006C00C00000F4000__00000086720CFFF0", +"000000067F000080000006C00C00000F0000-000000067F000080000006C00C00000F4000__000000873B520940", +"000000067F000080000006C00C00000F4000-000000067F000080000006C00C00000F8000__00000086720CFFF0", +"000000067F000080000006C00C00000F4000-000000067F000080000006C00C00000F8000__000000873B520940", +"000000067F000080000006C00C00000F4CD8-000000067F000080000006C00C00000FE40B__00000085D35BF439-0000008673817FC9", +"000000067F000080000006C00C00000F8000-000000067F000080000006C00C00000FC000__00000086720CFFF0", +"000000067F000080000006C00C00000F8000-000000067F000080000006C00C00000FC000__000000873B520940", +"000000067F000080000006C00C00000FC000-000000067F000080000006C00C0000100000__00000086720CFFF0", +"000000067F000080000006C00C00000FC000-000000067F000080000006C00C0000100000__000000873B520940", +"000000067F000080000006C00C00000FE40B-000000067F000080000006C00C0000107B27__00000085D35BF439-0000008673817FC9", +"000000067F000080000006C00C0000100000-000000067F000080000006C00C0000104000__00000086720CFFF0", +"000000067F000080000006C00C0000100000-000000067F000080000006C00C0000104000__000000873B520940", +"000000067F000080000006C00C00001015F3-000000067F000080000006C0140000013635__00000086ED29E361-000000873C9A2551", +"000000067F000080000006C00C0000104000-000000067F000080000006C00C0000108000__00000086720CFFF0", +"000000067F000080000006C00C0000104000-000000067F000080000006C00C0000108000__000000873B520940", +"000000067F000080000006C00C0000107B27-000000067F000080000006C00C000011128D__00000085D35BF439-0000008673817FC9", +"000000067F000080000006C00C0000108000-000000067F000080000006C00C000010C000__00000086720CFFF0", +"000000067F000080000006C00C0000108000-000000067F000080000006C00C000010C000__000000873B520940", +"000000067F000080000006C00C000010C000-000000067F000080000006C00C0000110000__00000086720CFFF0", +"000000067F000080000006C00C000010C000-000000067F000080000006C00C0000110000__000000873B520940", +"000000067F000080000006C00C0000110000-000000067F000080000006C0120100000000__000000873B520940", +"000000067F000080000006C00C0000110000-030000000000000000000000000000000002__00000086720CFFF0", +"000000067F000080000006C00C000011128D-010000000000000001000000030000000017__00000085D35BF439-0000008673817FC9", +"000000067F000080000006C0140000000000-000000067F000080000006C0140000004000__000000873B520940", +"000000067F000080000006C01400000016BC-000000067F000080000006C014000000830F__0000008673817FC9-00000086ED29E361", +"000000067F000080000006C0140000004000-000000067F000080000006C0140000008000__000000873B520940", +"000000067F000080000006C0140000008000-000000067F000080000006C014000000C000__000000873B520940", +"000000067F000080000006C014000000830F-000000067F000080000006C014000000EF5B__0000008673817FC9-00000086ED29E361", +"000000067F000080000006C014000000C000-000000067F000080000006C0140000010000__000000873B520940", +"000000067F000080000006C014000000EF5B-000000067F000080000006C0140000015BA7__0000008673817FC9-00000086ED29E361", +"000000067F000080000006C0140000010000-000000067F000080000006C0140000014000__000000873B520940", +"000000067F000080000006C0140000013636-000000067F000080000006C014000002DB5F__00000086ED29E361-000000873C9A2551", +"000000067F000080000006C0140000014000-000000067F000080000006C0140000018000__000000873B520940", +"000000067F000080000006C0140000015BA7-000000067F000080000006C014000001C7F0__0000008673817FC9-00000086ED29E361", +"000000067F000080000006C0140000018000-000000067F000080000006C014000001C000__000000873B520940", +"000000067F000080000006C014000001C000-000000067F000080000006C0140000020000__000000873B520940", +"000000067F000080000006C014000001C7F0-000000067F000080000006C0140000023430__0000008673817FC9-00000086ED29E361", +"000000067F000080000006C0140000020000-000000067F000080000006C0140000024000__000000873B520940", +"000000067F000080000006C0140000023430-000000067F000080000006C014000002A049__0000008673817FC9-00000086ED29E361", +"000000067F000080000006C0140000024000-000000067F000080000006C0140000028000__000000873B520940", +"000000067F000080000006C0140000028000-000000067F000080000006C014000002C000__000000873B520940", +"000000067F000080000006C014000002A049-030000000000000000000000000000000002__0000008673817FC9-00000086ED29E361", +"000000067F000080000006C014000002C000-030000000000000000000000000000000002__000000873B520940", +"000000067F000080000006C014000002DB60-030000000000000000000000000000000002__00000086ED29E361-000000873C9A2551", +"000000067F000080000006E00C0000000000-000000067F000080000006E00C0000004000__000000890CF51FE0", +"000000067F000080000006E00C0000004000-000000067F000080000006E00C0000008000__000000890CF51FE0", +"000000067F000080000006E00C0000008000-000000067F000080000006E00C000000C000__000000890CF51FE0", +"000000067F000080000006E00C00000096C8-000000067F000080000006E00C0000012E0A__000000873C9A2551-00000087BC75E5B1", +"000000067F000080000006E00C000000C000-000000067F000080000006E00C0000010000__000000890CF51FE0", +"000000067F000080000006E00C0000010000-000000067F000080000006E00C0000014000__000000890CF51FE0", +"000000067F000080000006E00C0000012E0A-000000067F000080000006E00C000001C570__000000873C9A2551-00000087BC75E5B1", +"000000067F000080000006E00C0000014000-000000067F000080000006E00C0000018000__000000890CF51FE0", +"000000067F000080000006E00C0000018000-000000067F000080000006E00C000001C000__000000890CF51FE0", +"000000067F000080000006E00C000001C000-000000067F000080000006E00C0000020000__000000890CF51FE0", +"000000067F000080000006E00C000001C570-000000067F000080000006E00C0000025CD6__000000873C9A2551-00000087BC75E5B1", +"000000067F000080000006E00C0000020000-000000067F000080000006E00C0000024000__000000890CF51FE0", +"000000067F000080000006E00C0000024000-000000067F000080000006E00C0000028000__000000890CF51FE0", +"000000067F000080000006E00C0000025CD6-000000067F000080000006E00C000002F40A__000000873C9A2551-00000087BC75E5B1", +"000000067F000080000006E00C0000028000-000000067F000080000006E00C000002C000__000000890CF51FE0", +"000000067F000080000006E00C000002C000-000000067F000080000006E00C0000030000__000000890CF51FE0", +"000000067F000080000006E00C000002F40A-000000067F000080000006E00C0000038B1D__000000873C9A2551-00000087BC75E5B1", +"000000067F000080000006E00C0000030000-000000067F000080000006E00C0000034000__000000890CF51FE0", +"000000067F000080000006E00C0000034000-000000067F000080000006E00C0000038000__000000890CF51FE0", +"000000067F000080000006E00C0000038000-000000067F000080000006E00C000003C000__000000890CF51FE0", +"000000067F000080000006E00C0000038B1D-000000067F000080000006E00C0000042283__000000873C9A2551-00000087BC75E5B1", +"000000067F000080000006E00C000003C000-000000067F000080000006E00C0000040000__000000890CF51FE0", +"000000067F000080000006E00C0000040000-000000067F000080000006E00C0000044000__000000890CF51FE0", +"000000067F000080000006E00C0000042283-000000067F000080000006E00C000004B9E9__000000873C9A2551-00000087BC75E5B1", +"000000067F000080000006E00C0000044000-000000067F000080000006E00C0000048000__000000890CF51FE0", +"000000067F000080000006E00C0000048000-000000067F000080000006E00C000004C000__000000890AE2DFC8", +"000000067F000080000006E00C0000048000-000000067F000080000006E00C000004C000__00000089D5AEF6E8", +"000000067F000080000006E00C000004B9E9-030000000000000000000000000000000002__000000873C9A2551-00000087BC75E5B1", +"000000067F000080000006E00C000004BACB-000000067F000080000006E00C0000055200__00000087BC75E5B1-000000887C2DFE59", +"000000067F000080000006E00C000004C000-000000067F000080000006E00C0000050000__000000890AE2DFC8", +"000000067F000080000006E00C000004C000-000000067F000080000006E00C0000050000__00000089D5AEF6E8", +"000000067F000080000006E00C0000050000-000000067F000080000006E00C0000054000__000000890AE2DFC8", +"000000067F000080000006E00C0000050000-000000067F000080000006E00C0000054000__00000089D5AEF6E8", +"000000067F000080000006E00C0000054000-000000067F000080000006E00C0000058000__000000890AE2DFC8", +"000000067F000080000006E00C0000054000-000000067F000080000006E00C0000058000__00000089D5AEF6E8", +"000000067F000080000006E00C0000054246-000000067F000080000006E00C00000A83ED__0000008985FD3611-00000089D6B8EE99", +"000000067F000080000006E00C0000055200-000000067F000080000006E00C000005E90B__00000087BC75E5B1-000000887C2DFE59", +"000000067F000080000006E00C0000058000-000000067F000080000006E00C000005C000__000000890AE2DFC8", +"000000067F000080000006E00C0000058000-000000067F000080000006E00C000005C000__00000089D5AEF6E8", +"000000067F000080000006E00C000005C000-000000067F000080000006E00C0000060000__000000890AE2DFC8", +"000000067F000080000006E00C000005C000-000000067F000080000006E00C0000060000__00000089D5AEF6E8", +"000000067F000080000006E00C000005E90B-000000067F000080000006E00C000006802B__00000087BC75E5B1-000000887C2DFE59", +"000000067F000080000006E00C0000060000-000000067F000080000006E00C0000064000__000000890AE2DFC8", +"000000067F000080000006E00C0000060000-000000067F000080000006E00C0000064000__00000089D5AEF6E8", +"000000067F000080000006E00C0000064000-000000067F000080000006E00C0000068000__000000890AE2DFC8", +"000000067F000080000006E00C0000064000-000000067F000080000006E00C0000068000__00000089D5AEF6E8", +"000000067F000080000006E00C0000068000-000000067F000080000006E00C000006C000__000000890AE2DFC8", +"000000067F000080000006E00C0000068000-000000067F000080000006E00C000006C000__00000089D5AEF6E8", +"000000067F000080000006E00C000006802B-000000067F000080000006E00C0000071782__00000087BC75E5B1-000000887C2DFE59", +"000000067F000080000006E00C000006C000-000000067F000080000006E00C0000070000__000000890AE2DFC8", +"000000067F000080000006E00C000006C000-000000067F000080000006E00C0000070000__00000089D5AEF6E8", +"000000067F000080000006E00C0000070000-000000067F000080000006E00C0000074000__000000890AE2DFC8", +"000000067F000080000006E00C0000070000-000000067F000080000006E00C0000074000__00000089D5AEF6E8", +"000000067F000080000006E00C0000071782-000000067F000080000006E00C000007AEE8__00000087BC75E5B1-000000887C2DFE59", +"000000067F000080000006E00C0000074000-000000067F000080000006E00C0000078000__000000890AE2DFC8", +"000000067F000080000006E00C0000074000-000000067F000080000006E00C0000078000__00000089D5AEF6E8", +"000000067F000080000006E00C0000078000-000000067F000080000006E00C000007C000__000000890AE2DFC8", +"000000067F000080000006E00C0000078000-000000067F000080000006E00C000007C000__00000089D5AEF6E8", +"000000067F000080000006E00C000007AEE8-000000067F000080000006E00C000008460B__00000087BC75E5B1-000000887C2DFE59", +"000000067F000080000006E00C000007C000-000000067F000080000006E00C0000080000__000000890AE2DFC8", +"000000067F000080000006E00C000007C000-000000067F000080000006E00C0000080000__00000089D5AEF6E8", +"000000067F000080000006E00C0000080000-000000067F000080000006E00C0000084000__000000890AE2DFC8", +"000000067F000080000006E00C0000080000-000000067F000080000006E00C0000084000__00000089D5AEF6E8", +"000000067F000080000006E00C0000084000-000000067F000080000006E00C0000088000__000000890AE2DFC8", +"000000067F000080000006E00C0000084000-000000067F000080000006E00C0000088000__00000089D5AEF6E8", +"000000067F000080000006E00C000008460B-000000067F000080000006E00C000008DD71__00000087BC75E5B1-000000887C2DFE59", +"000000067F000080000006E00C0000088000-000000067F000080000006E00C000008C000__000000890AE2DFC8", +"000000067F000080000006E00C0000088000-000000067F000080000006E00C000008C000__00000089D5AEF6E8", +"000000067F000080000006E00C000008C000-000000067F000080000006E00C0000090000__000000890AE2DFC8", +"000000067F000080000006E00C000008C000-000000067F000080000006E00C0000090000__00000089D5AEF6E8", +"000000067F000080000006E00C000008DD71-000000067F000080000006E00C00000974D7__00000087BC75E5B1-000000887C2DFE59", +"000000067F000080000006E00C0000090000-000000067F000080000006E00C0000094000__000000890AE2DFC8", +"000000067F000080000006E00C0000090000-000000067F000080000006E00C0000094000__00000089D5AEF6E8", +"000000067F000080000006E00C0000094000-000000067F000080000006E00C0000098000__000000890AE2DFC8", +"000000067F000080000006E00C0000094000-000000067F000080000006E00C0000098000__00000089D5AEF6E8", +"000000067F000080000006E00C00000974D7-000000067F000080000006E00C00000A0C0B__00000087BC75E5B1-000000887C2DFE59", +"000000067F000080000006E00C0000098000-000000067F000080000006E00C000009C000__000000890AE2DFC8", +"000000067F000080000006E00C0000098000-000000067F000080000006E00C000009C000__00000089D5AEF6E8", +"000000067F000080000006E00C000009C000-000000067F000080000006E00C00000A0000__000000890AE2DFC8", +"000000067F000080000006E00C000009C000-000000067F000080000006E00C00000A0000__00000089D5AEF6E8", +"000000067F000080000006E00C00000A0000-000000067F000080000006E00C00000A4000__000000890AE2DFC8", +"000000067F000080000006E00C00000A0000-000000067F000080000006E00C00000A4000__00000089D5AEF6E8", +"000000067F000080000006E00C00000A0C0B-000000067F000080000006E00C00000AA371__00000087BC75E5B1-000000887C2DFE59", +"000000067F000080000006E00C00000A4000-000000067F000080000006E00C00000A8000__000000890AE2DFC8", +"000000067F000080000006E00C00000A4000-000000067F000080000006E00C00000A8000__00000089D5AEF6E8", +"000000067F000080000006E00C00000A8000-000000067F000080000006E00C00000AC000__000000890AE2DFC8", +"000000067F000080000006E00C00000A8000-000000067F000080000006E00C00000AC000__00000089D5AEF6E8", +"000000067F000080000006E00C00000A8407-000000067F000080000006E00C00000FD787__0000008985FD3611-00000089D6B8EE99", +"000000067F000080000006E00C00000AA371-000000067F000080000006E00C00000B3AD7__00000087BC75E5B1-000000887C2DFE59", +"000000067F000080000006E00C00000AC000-000000067F000080000006E00C00000B0000__000000890AE2DFC8", +"000000067F000080000006E00C00000AC000-000000067F000080000006E00C00000B0000__00000089D5AEF6E8", +"000000067F000080000006E00C00000B0000-000000067F000080000006E00C00000B4000__000000890AE2DFC8", +"000000067F000080000006E00C00000B0000-000000067F000080000006E00C00000B4000__00000089D5AEF6E8", +"000000067F000080000006E00C00000B3AD7-000000067F000080000006E00C00000BD20B__00000087BC75E5B1-000000887C2DFE59", +"000000067F000080000006E00C00000B4000-000000067F000080000006E00C00000B8000__000000890AE2DFC8", +"000000067F000080000006E00C00000B4000-000000067F000080000006E00C00000B8000__00000089D5AEF6E8", +"000000067F000080000006E00C00000B6F42-000000067F000080000006E0140000000EEF__000000890C5B6001-0000008985FD3611", +"000000067F000080000006E00C00000B8000-000000067F000080000006E00C00000BC000__000000890AE2DFC8", +"000000067F000080000006E00C00000B8000-000000067F000080000006E00C00000BC000__00000089D5AEF6E8", +"000000067F000080000006E00C00000BC000-000000067F000080000006E00C00000C0000__000000890AE2DFC8", +"000000067F000080000006E00C00000BC000-000000067F000080000006E00C00000C0000__00000089D5AEF6E8", +"000000067F000080000006E00C00000BD20B-000000067F000080000006E00C0100000000__00000087BC75E5B1-000000887C2DFE59", +"000000067F000080000006E00C00000C0000-000000067F000080000006E00C00000C4000__000000890AE2DFC8", +"000000067F000080000006E00C00000C0000-000000067F000080000006E00C00000C4000__00000089D5AEF6E8", +"000000067F000080000006E00C00000C4000-000000067F000080000006E00C00000C8000__000000890AE2DFC8", +"000000067F000080000006E00C00000C4000-000000067F000080000006E00C00000C8000__00000089D5AEF6E8", +"000000067F000080000006E00C00000C5883-000000067F000080000006E00C00000CEFE9__000000887C2DFE59-000000890C5B6001", +"000000067F000080000006E00C00000C8000-000000067F000080000006E00C00000CC000__000000890AE2DFC8", +"000000067F000080000006E00C00000C8000-000000067F000080000006E00C00000CC000__00000089D5AEF6E8", +"000000067F000080000006E00C00000CC000-000000067F000080000006E00C00000D0000__000000890AE2DFC8", +"000000067F000080000006E00C00000CC000-000000067F000080000006E00C00000D0000__00000089D5AEF6E8", +"000000067F000080000006E00C00000CEFE9-000000067F000080000006E00C00000D872B__000000887C2DFE59-000000890C5B6001", +"000000067F000080000006E00C00000D0000-000000067F000080000006E00C00000D4000__000000890AE2DFC8", +"000000067F000080000006E00C00000D0000-000000067F000080000006E00C00000D4000__00000089D5AEF6E8", +"000000067F000080000006E00C00000D4000-000000067F000080000006E00C00000D8000__000000890AE2DFC8", +"000000067F000080000006E00C00000D4000-000000067F000080000006E00C00000D8000__00000089D5AEF6E8", +"000000067F000080000006E00C00000D8000-000000067F000080000006E00C00000DC000__000000890AE2DFC8", +"000000067F000080000006E00C00000D8000-000000067F000080000006E00C00000DC000__00000089D5AEF6E8", +"000000067F000080000006E00C00000D872B-000000067F000080000006E00C00000E1E91__000000887C2DFE59-000000890C5B6001", +"000000067F000080000006E00C00000DC000-000000067F000080000006E00C00000E0000__000000890AE2DFC8", +"000000067F000080000006E00C00000DC000-000000067F000080000006E00C00000E0000__00000089D5AEF6E8", +"000000067F000080000006E00C00000E0000-000000067F000080000006E00C00000E4000__000000890AE2DFC8", +"000000067F000080000006E00C00000E0000-000000067F000080000006E00C00000E4000__00000089D5AEF6E8", +"000000067F000080000006E00C00000E1E91-000000067F000080000006E00C00000EB5F7__000000887C2DFE59-000000890C5B6001", +"000000067F000080000006E00C00000E4000-000000067F000080000006E00C00000E8000__000000890AE2DFC8", +"000000067F000080000006E00C00000E4000-000000067F000080000006E00C00000E8000__00000089D5AEF6E8", +"000000067F000080000006E00C00000E8000-000000067F000080000006E00C00000EC000__000000890AE2DFC8", +"000000067F000080000006E00C00000E8000-000000067F000080000006E00C00000EC000__00000089D5AEF6E8", +"000000067F000080000006E00C00000EB5F7-000000067F000080000006E00C00000F4D0C__000000887C2DFE59-000000890C5B6001", +"000000067F000080000006E00C00000EC000-000000067F000080000006E00C00000F0000__000000890AE2DFC8", +"000000067F000080000006E00C00000EC000-000000067F000080000006E00C00000F0000__00000089D5AEF6E8", +"000000067F000080000006E00C00000F0000-000000067F000080000006E00C00000F4000__000000890AE2DFC8", +"000000067F000080000006E00C00000F0000-000000067F000080000006E00C00000F4000__00000089D5AEF6E8", +"000000067F000080000006E00C00000F4000-000000067F000080000006E00C00000F8000__000000890AE2DFC8", +"000000067F000080000006E00C00000F4000-000000067F000080000006E00C00000F8000__00000089D5AEF6E8", +"000000067F000080000006E00C00000F4D0C-000000067F000080000006E00C00000FE472__000000887C2DFE59-000000890C5B6001", +"000000067F000080000006E00C00000F8000-000000067F000080000006E00C00000FC000__000000890AE2DFC8", +"000000067F000080000006E00C00000F8000-000000067F000080000006E00C00000FC000__00000089D5AEF6E8", +"000000067F000080000006E00C00000FC000-000000067F000080000006E00C0000100000__000000890AE2DFC8", +"000000067F000080000006E00C00000FC000-000000067F000080000006E00C0000100000__00000089D5AEF6E8", +"000000067F000080000006E00C00000FD78D-000000067F000080000006E0140000011DB5__0000008985FD3611-00000089D6B8EE99", +"000000067F000080000006E00C00000FE472-000000067F000080000006E00C0000107B8E__000000887C2DFE59-000000890C5B6001", +"000000067F000080000006E00C0000100000-000000067F000080000006E00C0000104000__000000890AE2DFC8", +"000000067F000080000006E00C0000100000-000000067F000080000006E00C0000104000__00000089D5AEF6E8", +"000000067F000080000006E00C0000104000-000000067F000080000006E00C0000108000__000000890AE2DFC8", +"000000067F000080000006E00C0000104000-000000067F000080000006E00C0000108000__00000089D5AEF6E8", +"000000067F000080000006E00C0000107B8E-000000067F000080000006E00C00001112F4__000000887C2DFE59-000000890C5B6001", +"000000067F000080000006E00C0000108000-000000067F000080000006E00C000010C000__000000890AE2DFC8", +"000000067F000080000006E00C0000108000-000000067F000080000006E00C000010C000__00000089D5AEF6E8", +"000000067F000080000006E00C000010C000-000000067F000080000006E00C0000110000__000000890AE2DFC8", +"000000067F000080000006E00C000010C000-000000067F000080000006E00C0000110000__00000089D5AEF6E8", +"000000067F000080000006E00C0000110000-000000067F000080000006E0120100000000__00000089D5AEF6E8", +"000000067F000080000006E00C0000110000-030000000000000000000000000000000002__000000890AE2DFC8", +"000000067F000080000006E00C00001112F4-01000000000000000100000003000000001A__000000887C2DFE59-000000890C5B6001", +"000000067F000080000006E0140000000000-000000067F000080000006E0140000004000__00000089D5AEF6E8", +"000000067F000080000006E0140000000EEF-000000067F000080000006E0140000007C4F__000000890C5B6001-0000008985FD3611", +"000000067F000080000006E0140000004000-000000067F000080000006E0140000008000__00000089D5AEF6E8", +"000000067F000080000006E0140000007C4F-000000067F000080000006E014000000E97E__000000890C5B6001-0000008985FD3611", +"000000067F000080000006E0140000008000-000000067F000080000006E014000000C000__00000089D5AEF6E8", +"000000067F000080000006E014000000C000-000000067F000080000006E0140000010000__00000089D5AEF6E8", +"000000067F000080000006E014000000E97E-000000067F000080000006E01400000156DC__000000890C5B6001-0000008985FD3611", +"000000067F000080000006E0140000010000-000000067F000080000006E0140000014000__00000089D5AEF6E8", +"000000067F000080000006E0140000011DB5-000000067F000080000006E014000002B9CE__0000008985FD3611-00000089D6B8EE99", +"000000067F000080000006E0140000014000-000000067F000080000006E0140000018000__00000089D5AEF6E8", +"000000067F000080000006E01400000156DC-000000067F000080000006E014000001C468__000000890C5B6001-0000008985FD3611", +"000000067F000080000006E0140000018000-000000067F000080000006E014000001C000__00000089D5AEF6E8", +"000000067F000080000006E014000001C000-000000067F000080000006E0140000020000__00000089D5AEF6E8", +"000000067F000080000006E014000001C468-000000067F000080000006E01400000231D5__000000890C5B6001-0000008985FD3611", +"000000067F000080000006E0140000020000-000000067F000080000006E0140000024000__00000089D5AEF6E8", +"000000067F000080000006E01400000231D5-000000067F000080000006E0140000029F96__000000890C5B6001-0000008985FD3611", +"000000067F000080000006E0140000024000-000000067F000080000006E0140000028000__00000089D5AEF6E8", +"000000067F000080000006E0140000028000-000000067F000080000006E014000002C000__00000089D5AEF6E8", +"000000067F000080000006E0140000029F96-030000000000000000000000000000000002__000000890C5B6001-0000008985FD3611", +"000000067F000080000006E014000002B9D0-030000000000000000000000000000000002__0000008985FD3611-00000089D6B8EE99", +"000000067F000080000006E014000002C000-030000000000000000000000000000000002__00000089D5AEF6E8", +"000000067F000080000007000C0000000000-000000067F000080000007000C0000004000__0000008BA730BFE8", +"000000067F000080000007000C0000004000-000000067F000080000007000C0000008000__0000008BA730BFE8", +"000000067F000080000007000C0000008000-000000067F000080000007000C000000C000__0000008BA730BFE8", +"000000067F000080000007000C000000955C-000000067F000080000007000C0000012CC2__00000089D6B8EE99-0000008A56BBF739", +"000000067F000080000007000C000000C000-000000067F000080000007000C0000010000__0000008BA730BFE8", +"000000067F000080000007000C0000010000-000000067F000080000007000C0000014000__0000008BA730BFE8", +"000000067F000080000007000C0000012CC2-000000067F000080000007000C000001C40A__00000089D6B8EE99-0000008A56BBF739", +"000000067F000080000007000C0000014000-000000067F000080000007000C0000018000__0000008BA730BFE8", +"000000067F000080000007000C0000018000-000000067F000080000007000C000001C000__0000008BA730BFE8", +"000000067F000080000007000C000001C000-000000067F000080000007000C0000020000__0000008BA730BFE8", +"000000067F000080000007000C000001C40A-000000067F000080000007000C0000025B39__00000089D6B8EE99-0000008A56BBF739", +"000000067F000080000007000C0000020000-000000067F000080000007000C0000024000__0000008BA730BFE8", +"000000067F000080000007000C0000024000-000000067F000080000007000C0000028000__0000008BA730BFE8", +"000000067F000080000007000C0000025B39-000000067F000080000007000C000002F29F__00000089D6B8EE99-0000008A56BBF739", +"000000067F000080000007000C0000028000-000000067F000080000007000C000002C000__0000008BA730BFE8", +"000000067F000080000007000C000002C000-000000067F000080000007000C0000030000__0000008BA730BFE8", +"000000067F000080000007000C000002F29F-000000067F000080000007000C00000389B3__00000089D6B8EE99-0000008A56BBF739", +"000000067F000080000007000C0000030000-000000067F000080000007000C0000034000__0000008BA730BFE8", +"000000067F000080000007000C0000034000-000000067F000080000007000C0000038000__0000008BA730BFE8", +"000000067F000080000007000C0000038000-000000067F000080000007000C000003C000__0000008BA730BFE8", +"000000067F000080000007000C00000389B3-000000067F000080000007000C0000042119__00000089D6B8EE99-0000008A56BBF739", +"000000067F000080000007000C000003C000-000000067F000080000007000C0000040000__0000008BA730BFE8", +"000000067F000080000007000C0000040000-000000067F000080000007000C0000044000__0000008BA730BFE8", +"000000067F000080000007000C0000042119-000000067F000080000007000C000004B87F__00000089D6B8EE99-0000008A56BBF739", +"000000067F000080000007000C0000044000-000000067F000080000007000C0000048000__0000008BA730BFE8", +"000000067F000080000007000C0000048000-000000067F000080000007000C000004C000__0000008B9669EDB0", +"000000067F000080000007000C0000048000-000000067F000080000007000C000004C000__0000008C71903720", +"000000067F000080000007000C000004B87F-030000000000000000000000000000000002__00000089D6B8EE99-0000008A56BBF739", +"000000067F000080000007000C000004BAD3-000000067F000080000007000C0000055207__0000008A56BBF739-0000008AF67FEC19", +"000000067F000080000007000C000004C000-000000067F000080000007000C0000050000__0000008B9669EDB0", +"000000067F000080000007000C000004C000-000000067F000080000007000C0000050000__0000008C71903720", +"000000067F000080000007000C0000050000-000000067F000080000007000C0000054000__0000008B9669EDB0", +"000000067F000080000007000C0000050000-000000067F000080000007000C0000054000__0000008C71903720", +"000000067F000080000007000C0000053C23-000000067F000080000007000C00000A6F76__0000008C2045B721-0000008C72843D41", +"000000067F000080000007000C0000054000-000000067F000080000007000C0000058000__0000008B9669EDB0", +"000000067F000080000007000C0000054000-000000067F000080000007000C0000058000__0000008C71903720", +"000000067F000080000007000C0000055207-000000067F000080000007000C000005E912__0000008A56BBF739-0000008AF67FEC19", +"000000067F000080000007000C0000058000-000000067F000080000007000C000005C000__0000008B9669EDB0", +"000000067F000080000007000C0000058000-000000067F000080000007000C000005C000__0000008C71903720", +"000000067F000080000007000C000005C000-000000067F000080000007000C0000060000__0000008B9669EDB0", +"000000067F000080000007000C000005C000-000000067F000080000007000C0000060000__0000008C71903720", +"000000067F000080000007000C000005E912-000000067F000080000007000C000006802C__0000008A56BBF739-0000008AF67FEC19", +"000000067F000080000007000C0000060000-000000067F000080000007000C0000064000__0000008B9669EDB0", +"000000067F000080000007000C0000060000-000000067F000080000007000C0000064000__0000008C71903720", +"000000067F000080000007000C0000064000-000000067F000080000007000C0000068000__0000008B9669EDB0", +"000000067F000080000007000C0000064000-000000067F000080000007000C0000068000__0000008C71903720", +"000000067F000080000007000C0000068000-000000067F000080000007000C000006C000__0000008B9669EDB0", +"000000067F000080000007000C0000068000-000000067F000080000007000C000006C000__0000008C71903720", +"000000067F000080000007000C000006802C-000000067F000080000007000C0000071783__0000008A56BBF739-0000008AF67FEC19", +"000000067F000080000007000C000006C000-000000067F000080000007000C0000070000__0000008B9669EDB0", +"000000067F000080000007000C000006C000-000000067F000080000007000C0000070000__0000008C71903720", +"000000067F000080000007000C0000070000-000000067F000080000007000C0000074000__0000008B9669EDB0", +"000000067F000080000007000C0000070000-000000067F000080000007000C0000074000__0000008C71903720", +"000000067F000080000007000C0000071783-000000067F000080000007000C000007AEE9__0000008A56BBF739-0000008AF67FEC19", +"000000067F000080000007000C0000074000-000000067F000080000007000C0000078000__0000008B9669EDB0", +"000000067F000080000007000C0000074000-000000067F000080000007000C0000078000__0000008C71903720", +"000000067F000080000007000C0000078000-000000067F000080000007000C000007C000__0000008B9669EDB0", +"000000067F000080000007000C0000078000-000000067F000080000007000C000007C000__0000008C71903720", +"000000067F000080000007000C000007AEE9-000000067F000080000007000C000008460B__0000008A56BBF739-0000008AF67FEC19", +"000000067F000080000007000C000007C000-000000067F000080000007000C0000080000__0000008B9669EDB0", +"000000067F000080000007000C000007C000-000000067F000080000007000C0000080000__0000008C71903720", +"000000067F000080000007000C0000080000-000000067F000080000007000C0000084000__0000008B9669EDB0", +"000000067F000080000007000C0000080000-000000067F000080000007000C0000084000__0000008C71903720", +"000000067F000080000007000C0000084000-000000067F000080000007000C0000088000__0000008B9669EDB0", +"000000067F000080000007000C0000084000-000000067F000080000007000C0000088000__0000008C71903720", +"000000067F000080000007000C000008460B-000000067F000080000007000C000008DD71__0000008A56BBF739-0000008AF67FEC19", +"000000067F000080000007000C0000088000-000000067F000080000007000C000008C000__0000008B9669EDB0", +"000000067F000080000007000C0000088000-000000067F000080000007000C000008C000__0000008C71903720", +"000000067F000080000007000C000008C000-000000067F000080000007000C0000090000__0000008B9669EDB0", +"000000067F000080000007000C000008C000-000000067F000080000007000C0000090000__0000008C71903720", +"000000067F000080000007000C000008DD71-000000067F000080000007000C00000974D7__0000008A56BBF739-0000008AF67FEC19", +"000000067F000080000007000C0000090000-000000067F000080000007000C0000094000__0000008B9669EDB0", +"000000067F000080000007000C0000090000-000000067F000080000007000C0000094000__0000008C71903720", +"000000067F000080000007000C0000094000-000000067F000080000007000C0000098000__0000008B9669EDB0", +"000000067F000080000007000C0000094000-000000067F000080000007000C0000098000__0000008C71903720", +"000000067F000080000007000C00000974D7-000000067F000080000007000C00000A0C0B__0000008A56BBF739-0000008AF67FEC19", +"000000067F000080000007000C0000098000-000000067F000080000007000C000009C000__0000008B9669EDB0", +"000000067F000080000007000C0000098000-000000067F000080000007000C000009C000__0000008C71903720", +"000000067F000080000007000C000009C000-000000067F000080000007000C00000A0000__0000008B9669EDB0", +"000000067F000080000007000C000009C000-000000067F000080000007000C00000A0000__0000008C71903720", +"000000067F000080000007000C00000A0000-000000067F000080000007000C00000A4000__0000008B9669EDB0", +"000000067F000080000007000C00000A0000-000000067F000080000007000C00000A4000__0000008C71903720", +"000000067F000080000007000C00000A0C0B-000000067F000080000007000C00000AA371__0000008A56BBF739-0000008AF67FEC19", +"000000067F000080000007000C00000A4000-000000067F000080000007000C00000A8000__0000008B9669EDB0", +"000000067F000080000007000C00000A4000-000000067F000080000007000C00000A8000__0000008C71903720", +"000000067F000080000007000C00000A6F77-000000067F000080000007000C00000FA170__0000008C2045B721-0000008C72843D41", +"000000067F000080000007000C00000A8000-000000067F000080000007000C00000AC000__0000008B9669EDB0", +"000000067F000080000007000C00000A8000-000000067F000080000007000C00000AC000__0000008C71903720", +"000000067F000080000007000C00000AA371-000000067F000080000007000C0100000000__0000008A56BBF739-0000008AF67FEC19", +"000000067F000080000007000C00000AC000-000000067F000080000007000C00000B0000__0000008B9669EDB0", +"000000067F000080000007000C00000AC000-000000067F000080000007000C00000B0000__0000008C71903720", +"000000067F000080000007000C00000B0000-000000067F000080000007000C00000B4000__0000008B9669EDB0", +"000000067F000080000007000C00000B0000-000000067F000080000007000C00000B4000__0000008C71903720", +"000000067F000080000007000C00000B2B06-000000067F000080000007000C00000BC211__0000008AF67FEC19-0000008BA6803FC9", +"000000067F000080000007000C00000B4000-000000067F000080000007000C00000B8000__0000008B9669EDB0", +"000000067F000080000007000C00000B4000-000000067F000080000007000C00000B8000__0000008C71903720", +"000000067F000080000007000C00000B8000-000000067F000080000007000C00000BC000__0000008B9669EDB0", +"000000067F000080000007000C00000B8000-000000067F000080000007000C00000BC000__0000008C71903720", +"000000067F000080000007000C00000BC000-000000067F000080000007000C00000C0000__0000008B9669EDB0", +"000000067F000080000007000C00000BC000-000000067F000080000007000C00000C0000__0000008C71903720", +"000000067F000080000007000C00000BC211-000000067F000080000007000C00000C5941__0000008AF67FEC19-0000008BA6803FC9", +"000000067F000080000007000C00000BF157-000000067F000080000007001400000016B2__0000008BA6803FC9-0000008C2045B721", +"000000067F000080000007000C00000C0000-000000067F000080000007000C00000C4000__0000008B9669EDB0", +"000000067F000080000007000C00000C0000-000000067F000080000007000C00000C4000__0000008C71903720", +"000000067F000080000007000C00000C4000-000000067F000080000007000C00000C8000__0000008B9669EDB0", +"000000067F000080000007000C00000C4000-000000067F000080000007000C00000C8000__0000008C71903720", +"000000067F000080000007000C00000C5941-000000067F000080000007000C00000CF0A7__0000008AF67FEC19-0000008BA6803FC9", +"000000067F000080000007000C00000C8000-000000067F000080000007000C00000CC000__0000008B9669EDB0", +"000000067F000080000007000C00000C8000-000000067F000080000007000C00000CC000__0000008C71903720", +"000000067F000080000007000C00000CC000-000000067F000080000007000C00000D0000__0000008B9669EDB0", +"000000067F000080000007000C00000CC000-000000067F000080000007000C00000D0000__0000008C71903720", +"000000067F000080000007000C00000CF0A7-000000067F000080000007000C00000D87BC__0000008AF67FEC19-0000008BA6803FC9", +"000000067F000080000007000C00000D0000-000000067F000080000007000C00000D4000__0000008B9669EDB0", +"000000067F000080000007000C00000D0000-000000067F000080000007000C00000D4000__0000008C71903720", +"000000067F000080000007000C00000D4000-000000067F000080000007000C00000D8000__0000008B9669EDB0", +"000000067F000080000007000C00000D4000-000000067F000080000007000C00000D8000__0000008C71903720", +"000000067F000080000007000C00000D8000-000000067F000080000007000C00000DC000__0000008B9669EDB0", +"000000067F000080000007000C00000D8000-000000067F000080000007000C00000DC000__0000008C71903720", +"000000067F000080000007000C00000D87BC-000000067F000080000007000C00000E1F0A__0000008AF67FEC19-0000008BA6803FC9", +"000000067F000080000007000C00000DC000-000000067F000080000007000C00000E0000__0000008B9669EDB0", +"000000067F000080000007000C00000DC000-000000067F000080000007000C00000E0000__0000008C71903720", +"000000067F000080000007000C00000E0000-000000067F000080000007000C00000E4000__0000008B9669EDB0", +"000000067F000080000007000C00000E0000-000000067F000080000007000C00000E4000__0000008C71903720", +"000000067F000080000007000C00000E1F0A-000000067F000080000007000C00000EB670__0000008AF67FEC19-0000008BA6803FC9", +"000000067F000080000007000C00000E4000-000000067F000080000007000C00000E8000__0000008B9669EDB0", +"000000067F000080000007000C00000E4000-000000067F000080000007000C00000E8000__0000008C71903720", +"000000067F000080000007000C00000E8000-000000067F000080000007000C00000EC000__0000008B9669EDB0", +"000000067F000080000007000C00000E8000-000000067F000080000007000C00000EC000__0000008C71903720", +"000000067F000080000007000C00000EB670-000000067F000080000007000C00000F4DA7__0000008AF67FEC19-0000008BA6803FC9", +"000000067F000080000007000C00000EC000-000000067F000080000007000C00000F0000__0000008B9669EDB0", +"000000067F000080000007000C00000EC000-000000067F000080000007000C00000F0000__0000008C71903720", +"000000067F000080000007000C00000F0000-000000067F000080000007000C00000F4000__0000008B9669EDB0", +"000000067F000080000007000C00000F0000-000000067F000080000007000C00000F4000__0000008C71903720", +"000000067F000080000007000C00000F4000-000000067F000080000007000C00000F8000__0000008B9669EDB0", +"000000067F000080000007000C00000F4000-000000067F000080000007000C00000F8000__0000008C71903720", +"000000067F000080000007000C00000F4DA7-000000067F000080000007000C00000FE509__0000008AF67FEC19-0000008BA6803FC9", +"000000067F000080000007000C00000F8000-000000067F000080000007000C00000FC000__0000008B9669EDB0", +"000000067F000080000007000C00000F8000-000000067F000080000007000C00000FC000__0000008C71903720", +"000000067F000080000007000C00000FA175-000000067F00008000000700140000010412__0000008C2045B721-0000008C72843D41", +"000000067F000080000007000C00000FC000-000000067F000080000007000C0000100000__0000008B9669EDB0", +"000000067F000080000007000C00000FC000-000000067F000080000007000C0000100000__0000008C71903720", +"000000067F000080000007000C00000FE509-000000067F000080000007000C0000107C2B__0000008AF67FEC19-0000008BA6803FC9", +"000000067F000080000007000C0000100000-000000067F000080000007000C0000104000__0000008B9669EDB0", +"000000067F000080000007000C0000100000-000000067F000080000007000C0000104000__0000008C71903720", +"000000067F000080000007000C0000104000-000000067F000080000007000C0000108000__0000008B9669EDB0", +"000000067F000080000007000C0000104000-000000067F000080000007000C0000108000__0000008C71903720", +"000000067F000080000007000C0000107C2B-000000067F000080000007000C0000111385__0000008AF67FEC19-0000008BA6803FC9", +"000000067F000080000007000C0000108000-000000067F000080000007000C000010C000__0000008C71903720", +"000000067F000080000007000C0000108000-030000000000000000000000000000000002__0000008B9669EDB0", +"000000067F000080000007000C000010C000-000000067F000080000007000C0000110000__0000008C71903720", +"000000067F000080000007000C0000110000-000000067F00008000000700120100000000__0000008C71903720", +"000000067F000080000007000C0000111385-01000000000000000100000003000000001E__0000008AF67FEC19-0000008BA6803FC9", +"000000067F00008000000700140000000000-000000067F00008000000700140000004000__0000008C71903720", +"000000067F000080000007001400000016B2-000000067F000080000007001400000082A6__0000008BA6803FC9-0000008C2045B721", +"000000067F00008000000700140000004000-000000067F00008000000700140000008000__0000008C71903720", +"000000067F00008000000700140000008000-000000067F0000800000070014000000C000__0000008C71903720", +"000000067F000080000007001400000082A6-000000067F0000800000070014000000EED0__0000008BA6803FC9-0000008C2045B721", +"000000067F0000800000070014000000C000-000000067F00008000000700140000010000__0000008C71903720", +"000000067F0000800000070014000000EED0-000000067F00008000000700140000015ADC__0000008BA6803FC9-0000008C2045B721", +"000000067F00008000000700140000010000-000000067F00008000000700140000014000__0000008C71903720", +"000000067F0000800000070014000001041E-000000067F000080000007001400000294B8__0000008C2045B721-0000008C72843D41", +"000000067F00008000000700140000014000-000000067F00008000000700140000018000__0000008C71903720", +"000000067F00008000000700140000015ADC-000000067F0000800000070014000001C6D6__0000008BA6803FC9-0000008C2045B721", +"000000067F00008000000700140000018000-000000067F0000800000070014000001C000__0000008C71903720", +"000000067F0000800000070014000001C000-000000067F00008000000700140000020000__0000008C71903720", +"000000067F0000800000070014000001C6D6-000000067F000080000007001400000232FD__0000008BA6803FC9-0000008C2045B721", +"000000067F00008000000700140000020000-000000067F00008000000700140000024000__0000008C71903720", +"000000067F000080000007001400000232FD-000000067F00008000000700140000029F07__0000008BA6803FC9-0000008C2045B721", +"000000067F00008000000700140000024000-000000067F00008000000700140000028000__0000008C71903720", +"000000067F00008000000700140000028000-000000067F0000800000070014000002C000__0000008C71903720", +"000000067F000080000007001400000294BA-030000000000000000000000000000000002__0000008C2045B721-0000008C72843D41", +"000000067F00008000000700140000029F07-030000000000000000000000000000000002__0000008BA6803FC9-0000008C2045B721", +"000000067F0000800000070014000002C000-030000000000000000000000000000000002__0000008C71903720", +"000000067F000080000007200C0000000000-000000067F000080000007200C0000004000__0000008E43487FF0", +"000000067F000080000007200C0000004000-000000067F000080000007200C0000008000__0000008E43487FF0", +"000000067F000080000007200C0000008000-000000067F000080000007200C000000C000__0000008E43487FF0", +"000000067F000080000007200C000000933D-000000067F000080000007200C0000012AA3__0000008C72843D41-0000008CF2BFFC89", +"000000067F000080000007200C000000C000-000000067F000080000007200C0000010000__0000008E43487FF0", +"000000067F000080000007200C0000010000-000000067F000080000007200C0000014000__0000008E43487FF0", +"000000067F000080000007200C0000012AA3-000000067F000080000007200C000001C209__0000008C72843D41-0000008CF2BFFC89", +"000000067F000080000007200C0000014000-000000067F000080000007200C0000018000__0000008E43487FF0", +"000000067F000080000007200C0000018000-000000067F000080000007200C000001C000__0000008E43487FF0", +"000000067F000080000007200C000001C000-000000067F000080000007200C0000020000__0000008E43487FF0", +"000000067F000080000007200C000001C209-000000067F000080000007200C0000025939__0000008C72843D41-0000008CF2BFFC89", +"000000067F000080000007200C0000020000-000000067F000080000007200C0000024000__0000008E43487FF0", +"000000067F000080000007200C0000024000-000000067F000080000007200C0000028000__0000008E43487FF0", +"000000067F000080000007200C0000025939-000000067F000080000007200C000002F09F__0000008C72843D41-0000008CF2BFFC89", +"000000067F000080000007200C0000028000-000000067F000080000007200C000002C000__0000008E43487FF0", +"000000067F000080000007200C000002C000-000000067F000080000007200C0000030000__0000008E43487FF0", +"000000067F000080000007200C000002F09F-000000067F000080000007200C00000387B4__0000008C72843D41-0000008CF2BFFC89", +"000000067F000080000007200C0000030000-000000067F000080000007200C0000034000__0000008E43487FF0", +"000000067F000080000007200C0000034000-000000067F000080000007200C0000038000__0000008E43487FF0", +"000000067F000080000007200C0000038000-000000067F000080000007200C000003C000__0000008E43487FF0", +"000000067F000080000007200C00000387B4-000000067F000080000007200C0000041F1A__0000008C72843D41-0000008CF2BFFC89", +"000000067F000080000007200C000003C000-000000067F000080000007200C0000040000__0000008E43487FF0", +"000000067F000080000007200C0000040000-000000067F000080000007200C0000044000__0000008E43487FF0", +"000000067F000080000007200C0000041F1A-000000067F000080000007200C000004B680__0000008C72843D41-0000008CF2BFFC89", +"000000067F000080000007200C0000044000-000000067F000080000007200C0000048000__0000008E43487FF0", +"000000067F000080000007200C0000048000-000000067F000080000007200C000004C000__0000008E3CDF59C0", +"000000067F000080000007200C0000048000-000000067F000080000007200C000004C000__0000008F10EA21C8", +"000000067F000080000007200C000004B680-030000000000000000000000000000000002__0000008C72843D41-0000008CF2BFFC89", +"000000067F000080000007200C000004BACE-000000067F000080000007200C0000055202__0000008CF2BFFC89-0000008DB277FA49", +"000000067F000080000007200C000004C000-000000067F000080000007200C0000050000__0000008E3CDF59C0", +"000000067F000080000007200C000004C000-000000067F000080000007200C0000050000__0000008F10EA21C8", +"000000067F000080000007200C0000050000-000000067F000080000007200C0000054000__0000008E3CDF59C0", +"000000067F000080000007200C0000050000-000000067F000080000007200C0000054000__0000008F10EA21C8", +"000000067F000080000007200C000005131D-000000067F000080000007200C00000A2138__0000008EBC4827C1-0000008F10E3E189", +"000000067F000080000007200C0000054000-000000067F000080000007200C0000058000__0000008E3CDF59C0", +"000000067F000080000007200C0000054000-000000067F000080000007200C0000058000__0000008F10EA21C8", +"000000067F000080000007200C0000055202-000000067F000080000007200C000005E90D__0000008CF2BFFC89-0000008DB277FA49", +"000000067F000080000007200C0000058000-000000067F000080000007200C000005C000__0000008E3CDF59C0", +"000000067F000080000007200C0000058000-000000067F000080000007200C000005C000__0000008F10EA21C8", +"000000067F000080000007200C000005C000-000000067F000080000007200C0000060000__0000008E3CDF59C0", +"000000067F000080000007200C000005C000-000000067F000080000007200C0000060000__0000008F10EA21C8", +"000000067F000080000007200C000005E90D-000000067F000080000007200C000006802B__0000008CF2BFFC89-0000008DB277FA49", +"000000067F000080000007200C0000060000-000000067F000080000007200C0000064000__0000008E3CDF59C0", +"000000067F000080000007200C0000060000-000000067F000080000007200C0000064000__0000008F10EA21C8", +"000000067F000080000007200C0000064000-000000067F000080000007200C0000068000__0000008E3CDF59C0", +"000000067F000080000007200C0000064000-000000067F000080000007200C0000068000__0000008F10EA21C8", +"000000067F000080000007200C0000068000-000000067F000080000007200C000006C000__0000008E3CDF59C0", +"000000067F000080000007200C0000068000-000000067F000080000007200C000006C000__0000008F10EA21C8", +"000000067F000080000007200C000006802B-000000067F000080000007200C0000071782__0000008CF2BFFC89-0000008DB277FA49", +"000000067F000080000007200C000006C000-000000067F000080000007200C0000070000__0000008E3CDF59C0", +"000000067F000080000007200C000006C000-000000067F000080000007200C0000070000__0000008F10EA21C8", +"000000067F000080000007200C0000070000-000000067F000080000007200C0000074000__0000008E3CDF59C0", +"000000067F000080000007200C0000070000-000000067F000080000007200C0000074000__0000008F10EA21C8", +"000000067F000080000007200C0000071782-000000067F000080000007200C000007AEE8__0000008CF2BFFC89-0000008DB277FA49", +"000000067F000080000007200C0000074000-000000067F000080000007200C0000078000__0000008E3CDF59C0", +"000000067F000080000007200C0000074000-000000067F000080000007200C0000078000__0000008F10EA21C8", +"000000067F000080000007200C0000078000-000000067F000080000007200C000007C000__0000008E3CDF59C0", +"000000067F000080000007200C0000078000-000000067F000080000007200C000007C000__0000008F10EA21C8", +"000000067F000080000007200C000007AEE8-000000067F000080000007200C000008460B__0000008CF2BFFC89-0000008DB277FA49", +"000000067F000080000007200C000007C000-000000067F000080000007200C0000080000__0000008E3CDF59C0", +"000000067F000080000007200C000007C000-000000067F000080000007200C0000080000__0000008F10EA21C8", +"000000067F000080000007200C0000080000-000000067F000080000007200C0000084000__0000008E3CDF59C0", +"000000067F000080000007200C0000080000-000000067F000080000007200C0000084000__0000008F10EA21C8", +"000000067F000080000007200C0000084000-000000067F000080000007200C0000088000__0000008E3CDF59C0", +"000000067F000080000007200C0000084000-000000067F000080000007200C0000088000__0000008F10EA21C8", +"000000067F000080000007200C000008460B-000000067F000080000007200C000008DD71__0000008CF2BFFC89-0000008DB277FA49", +"000000067F000080000007200C0000088000-000000067F000080000007200C000008C000__0000008E3CDF59C0", +"000000067F000080000007200C0000088000-000000067F000080000007200C000008C000__0000008F10EA21C8", +"000000067F000080000007200C000008C000-000000067F000080000007200C0000090000__0000008E3CDF59C0", +"000000067F000080000007200C000008C000-000000067F000080000007200C0000090000__0000008F10EA21C8", +"000000067F000080000007200C000008DD71-000000067F000080000007200C00000974D7__0000008CF2BFFC89-0000008DB277FA49", +"000000067F000080000007200C0000090000-000000067F000080000007200C0000094000__0000008E3CDF59C0", +"000000067F000080000007200C0000090000-000000067F000080000007200C0000094000__0000008F10EA21C8", +"000000067F000080000007200C0000094000-000000067F000080000007200C0000098000__0000008E3CDF59C0", +"000000067F000080000007200C0000094000-000000067F000080000007200C0000098000__0000008F10EA21C8", +"000000067F000080000007200C00000974D7-000000067F000080000007200C00000A0C0B__0000008CF2BFFC89-0000008DB277FA49", +"000000067F000080000007200C0000098000-000000067F000080000007200C000009C000__0000008E3CDF59C0", +"000000067F000080000007200C0000098000-000000067F000080000007200C000009C000__0000008F10EA21C8", +"000000067F000080000007200C000009C000-000000067F000080000007200C00000A0000__0000008E3CDF59C0", +"000000067F000080000007200C000009C000-000000067F000080000007200C00000A0000__0000008F10EA21C8", +"000000067F000080000007200C00000A0000-000000067F000080000007200C00000A4000__0000008E3CDF59C0", +"000000067F000080000007200C00000A0000-000000067F000080000007200C00000A4000__0000008F10EA21C8", +"000000067F000080000007200C00000A0C0B-000000067F000080000007200C00000AA371__0000008CF2BFFC89-0000008DB277FA49", +"000000067F000080000007200C00000A2138-000000067F000080000007200C00000F342E__0000008EBC4827C1-0000008F10E3E189", +"000000067F000080000007200C00000A4000-000000067F000080000007200C00000A8000__0000008E3CDF59C0", +"000000067F000080000007200C00000A4000-000000067F000080000007200C00000A8000__0000008F10EA21C8", +"000000067F000080000007200C00000A8000-000000067F000080000007200C00000AC000__0000008E3CDF59C0", +"000000067F000080000007200C00000A8000-000000067F000080000007200C00000AC000__0000008F10EA21C8", +"000000067F000080000007200C00000AA371-000000067F000080000007200C00000B3AD7__0000008CF2BFFC89-0000008DB277FA49", +"000000067F000080000007200C00000AC000-000000067F000080000007200C00000B0000__0000008E3CDF59C0", +"000000067F000080000007200C00000AC000-000000067F000080000007200C00000B0000__0000008F10EA21C8", +"000000067F000080000007200C00000B0000-000000067F000080000007200C00000B4000__0000008E3CDF59C0", +"000000067F000080000007200C00000B0000-000000067F000080000007200C00000B4000__0000008F10EA21C8", +"000000067F000080000007200C00000B3AD7-000000067F000080000007200C00000BD20B__0000008CF2BFFC89-0000008DB277FA49", +"000000067F000080000007200C00000B4000-000000067F000080000007200C00000B8000__0000008E3CDF59C0", +"000000067F000080000007200C00000B4000-000000067F000080000007200C00000B8000__0000008F10EA21C8", +"000000067F000080000007200C00000B8000-000000067F000080000007200C00000BC000__0000008E3CDF59C0", +"000000067F000080000007200C00000B8000-000000067F000080000007200C00000BC000__0000008F10EA21C8", +"000000067F000080000007200C00000BA086-000000067F00008000000720140000001101__0000008E42A19FD1-0000008EBC4827C1", +"000000067F000080000007200C00000BC000-000000067F000080000007200C00000C0000__0000008E3CDF59C0", +"000000067F000080000007200C00000BC000-000000067F000080000007200C00000C0000__0000008F10EA21C8", +"000000067F000080000007200C00000BD20B-000000067F000080000007200C0100000000__0000008CF2BFFC89-0000008DB277FA49", +"000000067F000080000007200C00000C0000-000000067F000080000007200C00000C4000__0000008E3CDF59C0", +"000000067F000080000007200C00000C0000-000000067F000080000007200C00000C4000__0000008F10EA21C8", +"000000067F000080000007200C00000C4000-000000067F000080000007200C00000C8000__0000008E3CDF59C0", +"000000067F000080000007200C00000C4000-000000067F000080000007200C00000C8000__0000008F10EA21C8", +"000000067F000080000007200C00000C58B0-000000067F000080000007200C00000CF00A__0000008DB277FA49-0000008E42A19FD1", +"000000067F000080000007200C00000C8000-000000067F000080000007200C00000CC000__0000008E3CDF59C0", +"000000067F000080000007200C00000C8000-000000067F000080000007200C00000CC000__0000008F10EA21C8", +"000000067F000080000007200C00000CC000-000000067F000080000007200C00000D0000__0000008E3CDF59C0", +"000000067F000080000007200C00000CC000-000000067F000080000007200C00000D0000__0000008F10EA21C8", +"000000067F000080000007200C00000CF00A-000000067F000080000007200C00000D871F__0000008DB277FA49-0000008E42A19FD1", +"000000067F000080000007200C00000D0000-000000067F000080000007200C00000D4000__0000008E3CDF59C0", +"000000067F000080000007200C00000D0000-000000067F000080000007200C00000D4000__0000008F10EA21C8", +"000000067F000080000007200C00000D4000-000000067F000080000007200C00000D8000__0000008E3CDF59C0", +"000000067F000080000007200C00000D4000-000000067F000080000007200C00000D8000__0000008F10EA21C8", +"000000067F000080000007200C00000D8000-000000067F000080000007200C00000DC000__0000008E3CDF59C0", +"000000067F000080000007200C00000D8000-000000067F000080000007200C00000DC000__0000008F10EA21C8", +"000000067F000080000007200C00000D871F-000000067F000080000007200C00000E1E85__0000008DB277FA49-0000008E42A19FD1", +"000000067F000080000007200C00000DC000-000000067F000080000007200C00000E0000__0000008E3CDF59C0", +"000000067F000080000007200C00000DC000-000000067F000080000007200C00000E0000__0000008F10EA21C8", +"000000067F000080000007200C00000E0000-000000067F000080000007200C00000E4000__0000008E3CDF59C0", +"000000067F000080000007200C00000E0000-000000067F000080000007200C00000E4000__0000008F10EA21C8", +"000000067F000080000007200C00000E1E85-000000067F000080000007200C00000EB5EB__0000008DB277FA49-0000008E42A19FD1", +"000000067F000080000007200C00000E4000-000000067F000080000007200C00000E8000__0000008E3CDF59C0", +"000000067F000080000007200C00000E4000-000000067F000080000007200C00000E8000__0000008F10EA21C8", +"000000067F000080000007200C00000E8000-000000067F000080000007200C00000EC000__0000008E3CDF59C0", +"000000067F000080000007200C00000E8000-000000067F000080000007200C00000EC000__0000008F10EA21C8", +"000000067F000080000007200C00000EB5EB-000000067F000080000007200C00000F4D0C__0000008DB277FA49-0000008E42A19FD1", +"000000067F000080000007200C00000EC000-000000067F000080000007200C00000F0000__0000008E3CDF59C0", +"000000067F000080000007200C00000EC000-000000067F000080000007200C00000F0000__0000008F10EA21C8", +"000000067F000080000007200C00000F0000-000000067F000080000007200C00000F4000__0000008E3CDF59C0", +"000000067F000080000007200C00000F0000-000000067F000080000007200C00000F4000__0000008F10EA21C8", +"000000067F000080000007200C00000F342F-000000067F0000800000072014000000D54C__0000008EBC4827C1-0000008F10E3E189", +"000000067F000080000007200C00000F4000-000000067F000080000007200C00000F8000__0000008E3CDF59C0", +"000000067F000080000007200C00000F4000-000000067F000080000007200C00000F8000__0000008F10EA21C8", +"000000067F000080000007200C00000F4D0C-000000067F000080000007200C00000FE472__0000008DB277FA49-0000008E42A19FD1", +"000000067F000080000007200C00000F8000-000000067F000080000007200C00000FC000__0000008E3CDF59C0", +"000000067F000080000007200C00000F8000-000000067F000080000007200C00000FC000__0000008F10EA21C8", +"000000067F000080000007200C00000FC000-000000067F000080000007200C0000100000__0000008E3CDF59C0", +"000000067F000080000007200C00000FC000-000000067F000080000007200C0000100000__0000008F10EA21C8", +"000000067F000080000007200C00000FE472-000000067F000080000007200C0000107B8E__0000008DB277FA49-0000008E42A19FD1", +"000000067F000080000007200C0000100000-000000067F000080000007200C0000104000__0000008E3CDF59C0", +"000000067F000080000007200C0000100000-000000067F000080000007200C0000104000__0000008F10EA21C8", +"000000067F000080000007200C0000104000-000000067F000080000007200C0000108000__0000008E3CDF59C0", +"000000067F000080000007200C0000104000-000000067F000080000007200C0000108000__0000008F10EA21C8", +"000000067F000080000007200C0000107B8E-000000067F000080000007200C00001112F4__0000008DB277FA49-0000008E42A19FD1", +"000000067F000080000007200C0000108000-000000067F000080000007200C000010C000__0000008E3CDF59C0", +"000000067F000080000007200C0000108000-000000067F000080000007200C000010C000__0000008F10EA21C8", +"000000067F000080000007200C000010C000-000000067F000080000007200C0000110000__0000008F10EA21C8", +"000000067F000080000007200C000010C000-030000000000000000000000000000000002__0000008E3CDF59C0", +"000000067F000080000007200C0000110000-000000067F00008000000720120100000000__0000008F10EA21C8", +"000000067F000080000007200C00001112F4-010000000000000001000000040000000001__0000008DB277FA49-0000008E42A19FD1", +"000000067F00008000000720140000000000-000000067F00008000000720140000004000__0000008F10EA21C8", +"000000067F00008000000720140000001101-000000067F00008000000720140000007E82__0000008E42A19FD1-0000008EBC4827C1", +"000000067F00008000000720140000004000-000000067F00008000000720140000008000__0000008F10EA21C8", +"000000067F00008000000720140000007E82-000000067F0000800000072014000000EB9D__0000008E42A19FD1-0000008EBC4827C1", +"000000067F00008000000720140000008000-000000067F0000800000072014000000C000__0000008F10EA21C8", +"000000067F0000800000072014000000C000-000000067F00008000000720140000010000__0000008F10EA21C8", +"000000067F0000800000072014000000D54D-000000067F00008000000720140000025E6D__0000008EBC4827C1-0000008F10E3E189", +"000000067F0000800000072014000000EB9D-000000067F00008000000720140000015866__0000008E42A19FD1-0000008EBC4827C1", +"000000067F00008000000720140000010000-000000067F00008000000720140000014000__0000008F10EA21C8", +"000000067F00008000000720140000014000-000000067F00008000000720140000018000__0000008F10EA21C8", +"000000067F00008000000720140000015866-000000067F0000800000072014000001C591__0000008E42A19FD1-0000008EBC4827C1", +"000000067F00008000000720140000018000-000000067F0000800000072014000001C000__0000008F10EA21C8", +"000000067F0000800000072014000001C000-000000067F00008000000720140000020000__0000008F10EA21C8", +"000000067F0000800000072014000001C591-000000067F0000800000072014000002326E__0000008E42A19FD1-0000008EBC4827C1", +"000000067F00008000000720140000020000-000000067F00008000000720140000024000__0000008F10EA21C8", +"000000067F0000800000072014000002326E-000000067F00008000000720140000029F59__0000008E42A19FD1-0000008EBC4827C1", +"000000067F00008000000720140000024000-000000067F00008000000720140000028000__0000008F10EA21C8", +"000000067F00008000000720140000025E75-030000000000000000000000000000000002__0000008EBC4827C1-0000008F10E3E189", +"000000067F00008000000720140000028000-000000067F0000800000072014000002C000__0000008F10EA21C8", +"000000067F00008000000720140000029F59-030000000000000000000000000000000002__0000008E42A19FD1-0000008EBC4827C1", +"000000067F0000800000072014000002C000-030000000000000000000000000000000002__0000008F10EA21C8", +"000000067F000080000007400C0000000000-000000067F000080000007400C0000004000__00000091A67E3E18", +"000000067F000080000007400C0000004000-000000067F000080000007400C0000008000__00000091A67E3E18", +"000000067F000080000007400C0000008000-000000067F000080000007400C000000C000__00000091A67E3E18", +"000000067F000080000007400C00000090E9-000000067F000080000007400C000001280C__0000008F10E3E189-0000008F915DE591", +"000000067F000080000007400C000000C000-000000067F000080000007400C0000010000__00000091A67E3E18", +"000000067F000080000007400C0000010000-000000067F000080000007400C0000014000__00000091A67E3E18", +"000000067F000080000007400C000001280C-000000067F000080000007400C000001BF72__0000008F10E3E189-0000008F915DE591", +"000000067F000080000007400C0000014000-000000067F000080000007400C0000018000__00000091A67E3E18", +"000000067F000080000007400C0000018000-000000067F000080000007400C000001C000__00000091A67E3E18", +"000000067F000080000007400C000001BF72-000000067F000080000007400C00000256D8__0000008F10E3E189-0000008F915DE591", +"000000067F000080000007400C000001C000-000000067F000080000007400C0000020000__00000091A67E3E18", +"000000067F000080000007400C0000020000-000000067F000080000007400C0000024000__00000091A67E3E18", +"000000067F000080000007400C0000024000-000000067F000080000007400C0000028000__00000091A67E3E18", +"000000067F000080000007400C00000256D8-000000067F000080000007400C000002EE0B__0000008F10E3E189-0000008F915DE591", +"000000067F000080000007400C0000028000-000000067F000080000007400C000002C000__00000091A67E3E18", +"000000067F000080000007400C000002C000-000000067F000080000007400C0000030000__00000091A67E3E18", +"000000067F000080000007400C000002EE0B-000000067F000080000007400C0000038521__0000008F10E3E189-0000008F915DE591", +"000000067F000080000007400C0000030000-000000067F000080000007400C0000034000__00000091A67E3E18", +"000000067F000080000007400C0000034000-000000067F000080000007400C0000038000__00000091A67E3E18", +"000000067F000080000007400C0000038000-000000067F000080000007400C000003C000__00000091A67E3E18", +"000000067F000080000007400C0000038521-000000067F000080000007400C0000041C87__0000008F10E3E189-0000008F915DE591", +"000000067F000080000007400C000003C000-000000067F000080000007400C0000040000__00000091A67E3E18", +"000000067F000080000007400C0000040000-000000067F000080000007400C0000044000__00000091A67E3E18", +"000000067F000080000007400C0000041C87-000000067F000080000007400C000004B3ED__0000008F10E3E189-0000008F915DE591", +"000000067F000080000007400C0000044000-000000067F000080000007400C0000048000__00000091A67E3E18", +"000000067F000080000007400C0000048000-000000067F000080000007400C000004C000__000000914B20A810", +"000000067F000080000007400C000004B3ED-030000000000000000000000000000000002__0000008F10E3E189-0000008F915DE591", +"000000067F000080000007400C000004BAC9-000000067F000080000007400C00000551FE__0000008F915DE591-000000903121F569", +"000000067F000080000007400C000004C000-000000067F000080000007400C0000050000__000000914B20A810", +"000000067F000080000007400C000004DF0B-000000067F000080000007400C000009B41F__000000914B2393B1-00000091A6DD7A79", +"000000067F000080000007400C0000050000-000000067F000080000007400C0000054000__000000914B20A810", +"000000067F000080000007400C0000054000-000000067F000080000007400C0000058000__000000914B20A810", +"000000067F000080000007400C00000551FE-000000067F000080000007400C000005E90C__0000008F915DE591-000000903121F569", +"000000067F000080000007400C0000058000-000000067F000080000007400C000005C000__000000914B20A810", +"000000067F000080000007400C000005C000-000000067F000080000007400C0000060000__000000914B20A810", +"000000067F000080000007400C000005E90C-000000067F000080000007400C000006802C__0000008F915DE591-000000903121F569", +"000000067F000080000007400C0000060000-000000067F000080000007400C0000064000__000000914B20A810", +"000000067F000080000007400C0000064000-000000067F000080000007400C0000068000__000000914B20A810", +"000000067F000080000007400C0000068000-000000067F000080000007400C000006C000__000000914B20A810", +"000000067F000080000007400C000006802C-000000067F000080000007400C0000071783__0000008F915DE591-000000903121F569", +"000000067F000080000007400C000006C000-000000067F000080000007400C0000070000__000000914B20A810", +"000000067F000080000007400C0000070000-000000067F000080000007400C0000074000__000000914B20A810", +"000000067F000080000007400C0000071783-000000067F000080000007400C000007AEE9__0000008F915DE591-000000903121F569", +"000000067F000080000007400C0000074000-000000067F000080000007400C0000078000__000000914B20A810", +"000000067F000080000007400C0000078000-000000067F000080000007400C000007C000__000000914B20A810", +"000000067F000080000007400C000007AEE9-000000067F000080000007400C000008460B__0000008F915DE591-000000903121F569", +"000000067F000080000007400C000007C000-000000067F000080000007400C0000080000__000000914B20A810", +"000000067F000080000007400C0000080000-000000067F000080000007400C0000084000__000000914B20A810", +"000000067F000080000007400C0000084000-000000067F000080000007400C0000088000__000000914B20A810", +"000000067F000080000007400C000008460B-000000067F000080000007400C000008DD71__0000008F915DE591-000000903121F569", +"000000067F000080000007400C0000088000-000000067F000080000007400C000008C000__000000914B20A810", +"000000067F000080000007400C000008C000-000000067F000080000007400C0000090000__000000914B20A810", +"000000067F000080000007400C000008DD71-000000067F000080000007400C00000974D7__0000008F915DE591-000000903121F569", +"000000067F000080000007400C0000090000-000000067F000080000007400C0000094000__000000914B20A810", +"000000067F000080000007400C0000094000-000000067F000080000007400C0000098000__000000914B20A810", +"000000067F000080000007400C00000974D7-000000067F000080000007400C00000A0C0B__0000008F915DE591-000000903121F569", +"000000067F000080000007400C0000098000-000000067F000080000007400C000009C000__000000914B20A810", +"000000067F000080000007400C000009B420-000000067F000080000007400C00000E830A__000000914B2393B1-00000091A6DD7A79", +"000000067F000080000007400C000009C000-000000067F000080000007400C00000A0000__000000914B20A810", +"000000067F000080000007400C00000A0000-000000067F000080000007400C00000A4000__000000914B20A810", +"000000067F000080000007400C00000A0C0B-000000067F000080000007400C00000AA371__0000008F915DE591-000000903121F569", +"000000067F000080000007400C00000A4000-000000067F000080000007400C00000A8000__000000914B20A810", +"000000067F000080000007400C00000A8000-000000067F000080000007400C00000AC000__00000090DFD64240", +"000000067F000080000007400C00000AA371-000000067F000080000007400C0100000000__0000008F915DE591-000000903121F569", +"000000067F000080000007400C00000AA4EC-000000067F000080000007400C00000B3C0C__000000903121F569-00000090D0E5EA29", +"000000067F000080000007400C00000AC000-000000067F000080000007400C00000B0000__00000090DFD64240", +"000000067F000080000007400C00000B0000-000000067F000080000007400C00000B4000__00000090DFD64240", +"000000067F000080000007400C00000B3C0C-000000067F000080000007400C00000BD372__000000903121F569-00000090D0E5EA29", +"000000067F000080000007400C00000B4000-000000067F000080000007400C00000B8000__00000090DFD64240", +"000000067F000080000007400C00000B8000-000000067F000080000007400C00000BC000__00000090DFD64240", +"000000067F000080000007400C00000BC000-000000067F000080000007400C00000C0000__00000090DFD64240", +"000000067F000080000007400C00000BD372-000000067F000080000007400C00000C6AD8__000000903121F569-00000090D0E5EA29", +"000000067F000080000007400C00000C0000-000000067F000080000007400C00000C4000__00000090DFD64240", +"000000067F000080000007400C00000C4000-000000067F000080000007400C00000C8000__00000090DFD64240", +"000000067F000080000007400C00000C6AD8-000000067F000080000007400C00000D020B__000000903121F569-00000090D0E5EA29", +"000000067F000080000007400C00000C8000-000000067F000080000007400C00000CC000__00000090DFD64240", +"000000067F000080000007400C00000CC000-000000067F000080000007400C00000D0000__00000090DFD64240", +"000000067F000080000007400C00000D0000-000000067F000080000007400C00000D4000__00000090DFD64240", +"000000067F000080000007400C00000D020B-000000067F000080000007400C00000D9971__000000903121F569-00000090D0E5EA29", +"000000067F000080000007400C00000D4000-000000067F000080000007400C00000D8000__00000090DFD64240", +"000000067F000080000007400C00000D8000-000000067F000080000007400C00000DC000__00000090DFD64240", +"000000067F000080000007400C00000D9971-000000067F000080000007400C00000E30D7__000000903121F569-00000090D0E5EA29", +"000000067F000080000007400C00000DC000-000000067F000080000007400C00000E0000__00000090DFD64240", +"000000067F000080000007400C00000E0000-000000067F000080000007400C00000E4000__00000090DFD64240", +"000000067F000080000007400C00000E30D7-000000067F000080000007400C00000EC80B__000000903121F569-00000090D0E5EA29", +"000000067F000080000007400C00000E4000-000000067F000080000007400C00000E8000__00000090DFD64240", +"000000067F000080000007400C00000E8000-000000067F000080000007400C00000EC000__00000090DFD64240", +"000000067F000080000007400C00000E8314-000000067F00008000000740140000008178__000000914B2393B1-00000091A6DD7A79", +"000000067F000080000007400C00000EC000-000000067F000080000007400C00000F0000__00000090DFD64240", +"000000067F000080000007400C00000EC80B-000000067F000080000007400C00000F5F38__000000903121F569-00000090D0E5EA29", +"000000067F000080000007400C00000F0000-000000067F000080000007400C00000F4000__00000090DFD64240", +"000000067F000080000007400C00000F4000-000000067F000080000007400C00000F8000__00000090DFD64240", +"000000067F000080000007400C00000F5F38-000000067F000080000007400C00000FF69E__000000903121F569-00000090D0E5EA29", +"000000067F000080000007400C00000F8000-000000067F000080000007400C00000FC000__00000090DFD64240", +"000000067F000080000007400C00000FC000-000000067F000080000007400C0000100000__00000090DFD64240", +"000000067F000080000007400C00000FCCA8-000000067F000080000007400C00001119BA__00000090D0E5EA29-000000914B2393B1", +"000000067F000080000007400C00000FF69E-000000067F000080000007400C0000108DAF__000000903121F569-00000090D0E5EA29", +"000000067F000080000007400C0000100000-000000067F000080000007400C0000104000__00000090DFD64240", +"000000067F000080000007400C0000104000-000000067F000080000007400C0000108000__00000090DFD64240", +"000000067F000080000007400C0000108000-000000067F000080000007400C000010C000__00000090DFD64240", +"000000067F000080000007400C0000108DAF-000000067F000080000007400C0100000000__000000903121F569-00000090D0E5EA29", +"000000067F000080000007400C000010C000-000000067F000080000007400C0000110000__00000090DFD64240", +"000000067F000080000007400C0000110000-030000000000000000000000000000000002__00000090DFD64240", +"000000067F000080000007400C00001119BA-000000067F00008000000740140000004326__00000090D0E5EA29-000000914B2393B1", +"000000067F00008000000740140000004326-000000067F0000800000074014000000B7EE__00000090D0E5EA29-000000914B2393B1", +"000000067F00008000000740140000008179-000000067F0000800000074014000001D4B7__000000914B2393B1-00000091A6DD7A79", +"000000067F0000800000074014000000B7EE-000000067F00008000000740140000012CCD__00000090D0E5EA29-000000914B2393B1", +"000000067F00008000000740140000012CCD-000000067F0000800000074014000001A16B__00000090D0E5EA29-000000914B2393B1", +"000000067F0000800000074014000001A16B-000000067F000080000007401400000215C9__00000090D0E5EA29-000000914B2393B1", +"000000067F0000800000074014000001D4BA-030000000000000000000000000000000002__000000914B2393B1-00000091A6DD7A79", +"000000067F000080000007401400000215C9-000000067F00008000000740140000028A4A__00000090D0E5EA29-000000914B2393B1", +"000000067F00008000000740140000028A4A-030000000000000000000000000000000002__00000090D0E5EA29-000000914B2393B1", +"000000067F000080000007600C0000000000-000000067F000080000007600C0000004000__00000092CA5E4EA8", +"000000067F000080000007600C0000000000-000000067F000080000007600C0000004000__0000009445A06DC8", +"000000067F000080000007600C0000004000-000000067F000080000007600C0000008000__00000092CA5E4EA8", +"000000067F000080000007600C0000004000-000000067F000080000007600C0000008000__0000009445A06DC8", +"000000067F000080000007600C0000008000-000000067F000080000007600C000000C000__00000092CA5E4EA8", +"000000067F000080000007600C0000008000-000000067F000080000007600C000000C000__0000009445A06DC8", +"000000067F000080000007600C0000008180-000000067F000080000007600C00000118E6__00000091A6DD7A79-0000009228F7FA79", +"000000067F000080000007600C000000C000-000000067F000080000007600C0000010000__00000092CA5E4EA8", +"000000067F000080000007600C000000C000-000000067F000080000007600C0000010000__0000009445A06DC8", +"000000067F000080000007600C0000010000-000000067F000080000007600C0000014000__00000092CA5E4EA8", +"000000067F000080000007600C0000010000-000000067F000080000007600C0000014000__0000009445A06DC8", +"000000067F000080000007600C00000118E6-000000067F000080000007600C000001B00A__00000091A6DD7A79-0000009228F7FA79", +"000000067F000080000007600C0000014000-000000067F000080000007600C0000018000__00000092CA5E4EA8", +"000000067F000080000007600C0000014000-000000067F000080000007600C0000018000__0000009445A06DC8", +"000000067F000080000007600C0000018000-000000067F000080000007600C000001C000__00000092CA5E4EA8", +"000000067F000080000007600C0000018000-000000067F000080000007600C000001C000__0000009445A06DC8", +"000000067F000080000007600C000001B00A-000000067F000080000007600C0000024745__00000091A6DD7A79-0000009228F7FA79", +"000000067F000080000007600C000001C000-000000067F000080000007600C0000020000__00000092CA5E4EA8", +"000000067F000080000007600C000001C000-000000067F000080000007600C0000020000__0000009445A06DC8", +"000000067F000080000007600C0000020000-000000067F000080000007600C0000024000__00000092CA5E4EA8", +"000000067F000080000007600C0000020000-000000067F000080000007600C0000024000__0000009445A06DC8", +"000000067F000080000007600C0000024000-000000067F000080000007600C0000028000__00000092CA5E4EA8", +"000000067F000080000007600C0000024000-000000067F000080000007600C0000028000__0000009445A06DC8", +"000000067F000080000007600C0000024745-000000067F000080000007600C000002DEAB__00000091A6DD7A79-0000009228F7FA79", +"000000067F000080000007600C0000028000-000000067F000080000007600C000002C000__00000092CA5E4EA8", +"000000067F000080000007600C0000028000-000000067F000080000007600C000002C000__0000009445A06DC8", +"000000067F000080000007600C000002C000-000000067F000080000007600C0000030000__00000092CA5E4EA8", +"000000067F000080000007600C000002C000-000000067F000080000007600C0000030000__0000009445A06DC8", +"000000067F000080000007600C000002DEAB-000000067F000080000007600C00000375CB__00000091A6DD7A79-0000009228F7FA79", +"000000067F000080000007600C0000030000-000000067F000080000007600C0000034000__00000092CA5E4EA8", +"000000067F000080000007600C0000030000-000000067F000080000007600C0000034000__0000009445A06DC8", +"000000067F000080000007600C0000034000-000000067F000080000007600C0000038000__00000092CA5E4EA8", +"000000067F000080000007600C0000034000-000000067F000080000007600C0000038000__0000009445A06DC8", +"000000067F000080000007600C00000375CB-000000067F000080000007600C0000040D0B__00000091A6DD7A79-0000009228F7FA79", +"000000067F000080000007600C0000038000-000000067F000080000007600C000003C000__00000092CA5E4EA8", +"000000067F000080000007600C0000038000-000000067F000080000007600C000003C000__0000009445A06DC8", +"000000067F000080000007600C000003C000-000000067F000080000007600C0000040000__00000092CA5E4EA8", +"000000067F000080000007600C000003C000-000000067F000080000007600C0000040000__0000009445A06DC8", +"000000067F000080000007600C0000040000-000000067F000080000007600C0000044000__00000092CA5E4EA8", +"000000067F000080000007600C0000040000-000000067F000080000007600C0000044000__0000009445A06DC8", +"000000067F000080000007600C0000040D0B-000000067F000080000007600C000004A471__00000091A6DD7A79-0000009228F7FA79", +"000000067F000080000007600C0000044000-000000067F000080000007600C0000048000__00000092CA5E4EA8", +"000000067F000080000007600C0000044000-000000067F000080000007600C0000048000__0000009445A06DC8", +"000000067F000080000007600C0000048000-000000067F000080000007600C000004C000__00000092CA5E4EA8", +"000000067F000080000007600C0000048000-000000067F000080000007600C000004C000__0000009445A06DC8", +"000000067F000080000007600C000004A471-030000000000000000000000000000000002__00000091A6DD7A79-0000009228F7FA79", +"000000067F000080000007600C000004C000-000000067F000080000007600C0000050000__00000092CA5E4EA8", +"000000067F000080000007600C000004C000-000000067F000080000007600C0000050000__0000009445A06DC8", +"000000067F000080000007600C0000050000-000000067F000080000007600C0000054000__00000092CA5E4EA8", +"000000067F000080000007600C0000050000-000000067F000080000007600C0000054000__0000009445A06DC8", +"000000067F000080000007600C0000054000-000000067F000080000007600C0000058000__00000092CA5E4EA8", +"000000067F000080000007600C0000054000-000000067F000080000007600C0000058000__0000009445A06DC8", +"000000067F000080000007600C00000544BA-000000067F000080000007600C000005DC0A__0000009228F7FA79-00000093786F8001", +"000000067F000080000007600C0000058000-000000067F000080000007600C000005C000__00000092CA5E4EA8", +"000000067F000080000007600C0000058000-000000067F000080000007600C000005C000__0000009445A06DC8", +"000000067F000080000007600C000005C000-000000067F000080000007600C0000060000__00000092CA5E4EA8", +"000000067F000080000007600C000005C000-000000067F000080000007600C0000060000__0000009445A06DC8", +"000000067F000080000007600C000005DC0A-000000067F000080000007600C000006732B__0000009228F7FA79-00000093786F8001", +"000000067F000080000007600C0000060000-000000067F000080000007600C0000064000__00000092CA5E4EA8", +"000000067F000080000007600C0000060000-000000067F000080000007600C0000064000__0000009445A06DC8", +"000000067F000080000007600C0000061031-000000067F000080000007600C00000C1159__0000009402435A49-0000009446B52FD1", +"000000067F000080000007600C0000064000-000000067F000080000007600C0000068000__00000092CA5E4EA8", +"000000067F000080000007600C0000064000-000000067F000080000007600C0000068000__0000009445A06DC8", +"000000067F000080000007600C000006732B-000000067F000080000007600C0000070A91__0000009228F7FA79-00000093786F8001", +"000000067F000080000007600C0000068000-000000067F000080000007600C000006C000__00000092CA5E4EA8", +"000000067F000080000007600C0000068000-000000067F000080000007600C000006C000__0000009445A06DC8", +"000000067F000080000007600C000006C000-000000067F000080000007600C0000070000__00000092CA5E4EA8", +"000000067F000080000007600C000006C000-000000067F000080000007600C0000070000__0000009445A06DC8", +"000000067F000080000007600C0000070000-000000067F000080000007600C0000074000__00000092CA5E4EA8", +"000000067F000080000007600C0000070000-000000067F000080000007600C0000074000__0000009445A06DC8", +"000000067F000080000007600C0000070A91-000000067F000080000007600C000007A1F7__0000009228F7FA79-00000093786F8001", +"000000067F000080000007600C0000074000-000000067F000080000007600C0000078000__00000092CA5E4EA8", +"000000067F000080000007600C0000074000-000000067F000080000007600C0000078000__0000009445A06DC8", +"000000067F000080000007600C0000078000-000000067F000080000007600C000007C000__00000092CA5E4EA8", +"000000067F000080000007600C0000078000-000000067F000080000007600C000007C000__0000009445A06DC8", +"000000067F000080000007600C000007A1F7-000000067F000080000007600C000008390C__0000009228F7FA79-00000093786F8001", +"000000067F000080000007600C000007C000-000000067F000080000007600C0000080000__00000092CA5E4EA8", +"000000067F000080000007600C000007C000-000000067F000080000007600C0000080000__0000009445A06DC8", +"000000067F000080000007600C0000080000-000000067F000080000007600C0000084000__00000092CA5E4EA8", +"000000067F000080000007600C0000080000-000000067F000080000007600C0000084000__0000009445A06DC8", +"000000067F000080000007600C000008390C-000000067F000080000007600C000008D072__0000009228F7FA79-00000093786F8001", +"000000067F000080000007600C0000084000-000000067F000080000007600C0000088000__00000092CA5E4EA8", +"000000067F000080000007600C0000084000-000000067F000080000007600C0000088000__0000009445A06DC8", +"000000067F000080000007600C0000088000-000000067F000080000007600C000008C000__00000092CA5E4EA8", +"000000067F000080000007600C0000088000-000000067F000080000007600C000008C000__0000009445A06DC8", +"000000067F000080000007600C000008C000-000000067F000080000007600C0000090000__00000092CA5E4EA8", +"000000067F000080000007600C000008C000-000000067F000080000007600C0000090000__0000009445A06DC8", +"000000067F000080000007600C000008C52F-000000067F000080000007600C000010B57A__00000093786F8001-0000009402435A49", +"000000067F000080000007600C000008D072-000000067F000080000007600C000009679A__0000009228F7FA79-00000093786F8001", +"000000067F000080000007600C0000090000-000000067F000080000007600C0000094000__00000092CA5E4EA8", +"000000067F000080000007600C0000090000-000000067F000080000007600C0000094000__0000009445A06DC8", +"000000067F000080000007600C0000094000-000000067F000080000007600C0000098000__00000092CA5E4EA8", +"000000067F000080000007600C0000094000-000000067F000080000007600C0000098000__0000009445A06DC8", +"000000067F000080000007600C000009679A-000000067F000080000007600C000009FF00__0000009228F7FA79-00000093786F8001", +"000000067F000080000007600C0000098000-000000067F000080000007600C000009C000__00000092CA5E4EA8", +"000000067F000080000007600C0000098000-000000067F000080000007600C000009C000__0000009445A06DC8", +"000000067F000080000007600C000009C000-000000067F000080000007600C00000A0000__00000092CA5E4EA8", +"000000067F000080000007600C000009C000-000000067F000080000007600C00000A0000__0000009445A06DC8", +"000000067F000080000007600C000009FF00-000000067F000080000007600C00000A960B__0000009228F7FA79-00000093786F8001", +"000000067F000080000007600C00000A0000-000000067F000080000007600C00000A4000__00000092CA5E4EA8", +"000000067F000080000007600C00000A0000-000000067F000080000007600C00000A4000__0000009445A06DC8", +"000000067F000080000007600C00000A4000-000000067F000080000007600C00000A8000__00000092CA5E4EA8", +"000000067F000080000007600C00000A4000-000000067F000080000007600C00000A8000__0000009445A06DC8", +"000000067F000080000007600C00000A8000-000000067F000080000007600C00000AC000__0000009445A06DC8", +"000000067F000080000007600C00000A8000-030000000000000000000000000000000002__00000092CA5E4EA8", +"000000067F000080000007600C00000A960B-000000067F000080000007600C00000B2D55__0000009228F7FA79-00000093786F8001", +"000000067F000080000007600C00000AC000-000000067F000080000007600C00000B0000__0000009445A06DC8", +"000000067F000080000007600C00000B0000-000000067F000080000007600C00000B4000__0000009445A06DC8", +"000000067F000080000007600C00000B2D55-000000067F000080000007600C00000BC4BB__0000009228F7FA79-00000093786F8001", +"000000067F000080000007600C00000B4000-000000067F000080000007600C00000B8000__0000009445A06DC8", +"000000067F000080000007600C00000B8000-000000067F000080000007600C00000BC000__0000009445A06DC8", +"000000067F000080000007600C00000BC000-000000067F000080000007600C00000C0000__0000009445A06DC8", +"000000067F000080000007600C00000BC4BB-000000067F000080000007600C00000C5BEA__0000009228F7FA79-00000093786F8001", +"000000067F000080000007600C00000C0000-000000067F000080000007600C00000C4000__0000009445A06DC8", +"000000067F000080000007600C00000C115D-000000067F0000800000076014000000333A__0000009402435A49-0000009446B52FD1", +"000000067F000080000007600C00000C4000-000000067F000080000007600C00000C8000__0000009445A06DC8", +"000000067F000080000007600C00000C5BEA-000000067F000080000007600C00000CF30B__0000009228F7FA79-00000093786F8001", +"000000067F000080000007600C00000C8000-000000067F000080000007600C00000CC000__0000009445A06DC8", +"000000067F000080000007600C00000CC000-000000067F000080000007600C00000D0000__0000009445A06DC8", +"000000067F000080000007600C00000CF30B-000000067F000080000007600C00000D8A2B__0000009228F7FA79-00000093786F8001", +"000000067F000080000007600C00000D0000-000000067F000080000007600C00000D4000__0000009445A06DC8", +"000000067F000080000007600C00000D4000-000000067F000080000007600C00000D8000__0000009445A06DC8", +"000000067F000080000007600C00000D8000-000000067F000080000007600C00000DC000__0000009445A06DC8", +"000000067F000080000007600C00000D8A2B-000000067F000080000007600C00000E217C__0000009228F7FA79-00000093786F8001", +"000000067F000080000007600C00000DC000-000000067F000080000007600C00000E0000__0000009445A06DC8", +"000000067F000080000007600C00000E0000-000000067F000080000007600C00000E4000__0000009445A06DC8", +"000000067F000080000007600C00000E217C-000000067F000080000007600C00000EB8E2__0000009228F7FA79-00000093786F8001", +"000000067F000080000007600C00000E4000-000000067F000080000007600C00000E8000__0000009445A06DC8", +"000000067F000080000007600C00000E8000-000000067F000080000007600C00000EC000__0000009445A06DC8", +"000000067F000080000007600C00000EB8E2-000000067F000080000007600C00000F500B__0000009228F7FA79-00000093786F8001", +"000000067F000080000007600C00000EC000-000000067F000080000007600C00000F0000__0000009445A06DC8", +"000000067F000080000007600C00000F0000-000000067F000080000007600C00000F4000__0000009445A06DC8", +"000000067F000080000007600C00000F4000-000000067F000080000007600C00000F8000__0000009445A06DC8", +"000000067F000080000007600C00000F500B-000000067F000080000007600C00000FE771__0000009228F7FA79-00000093786F8001", +"000000067F000080000007600C00000F8000-000000067F000080000007600C00000FC000__0000009445A06DC8", +"000000067F000080000007600C00000FC000-000000067F000080000007600C0000100000__0000009445A06DC8", +"000000067F000080000007600C00000FE771-000000067F000080000007600C0000107ED7__0000009228F7FA79-00000093786F8001", +"000000067F000080000007600C0000100000-000000067F000080000007600C0000104000__0000009445A06DC8", +"000000067F000080000007600C0000104000-000000067F000080000007600C0000108000__0000009445A06DC8", +"000000067F000080000007600C0000107ED7-000000067F000080000007600C000011160C__0000009228F7FA79-00000093786F8001", +"000000067F000080000007600C0000108000-000000067F000080000007600C000010C000__0000009445A06DC8", +"000000067F000080000007600C000010B57A-000000067F00008000000760140000003D14__00000093786F8001-0000009402435A49", +"000000067F000080000007600C000010C000-000000067F000080000007600C0000110000__0000009445A06DC8", +"000000067F000080000007600C0000110000-000000067F00008000000760120100000000__0000009445A06DC8", +"000000067F000080000007600C000011160C-010000000000000001000000040000000008__0000009228F7FA79-00000093786F8001", +"000000067F00008000000760140000000000-000000067F00008000000760140000004000__0000009445A06DC8", +"000000067F00008000000760140000003354-000000067F00008000000760140000023CAB__0000009402435A49-0000009446B52FD1", +"000000067F00008000000760140000003D14-000000067F0000800000076014000000A251__00000093786F8001-0000009402435A49", +"000000067F00008000000760140000004000-000000067F00008000000760140000008000__0000009445A06DC8", +"000000067F00008000000760140000008000-000000067F0000800000076014000000C000__0000009445A06DC8", +"000000067F0000800000076014000000A251-000000067F000080000007601400000107AC__00000093786F8001-0000009402435A49", +"000000067F0000800000076014000000C000-000000067F00008000000760140000010000__0000009445A06DC8", +"000000067F00008000000760140000010000-000000067F00008000000760140000014000__0000009445A06DC8", +"000000067F000080000007601400000107AC-000000067F00008000000760140000016CC4__00000093786F8001-0000009402435A49", +"000000067F00008000000760140000014000-000000067F00008000000760140000018000__0000009445A06DC8", +"000000067F00008000000760140000016CC4-000000067F0000800000076014000001D272__00000093786F8001-0000009402435A49", +"000000067F00008000000760140000018000-000000067F0000800000076014000001C000__0000009445A06DC8", +"000000067F0000800000076014000001C000-000000067F00008000000760140000020000__0000009445A06DC8", +"000000067F0000800000076014000001D272-000000067F000080000007601400000237C3__00000093786F8001-0000009402435A49", +"000000067F00008000000760140000020000-000000067F00008000000760140000024000__0000009445A06DC8", +"000000067F000080000007601400000237C3-000000067F00008000000760140000029CC5__00000093786F8001-0000009402435A49", +"000000067F00008000000760140000023CB3-030000000000000000000000000000000002__0000009402435A49-0000009446B52FD1", +"000000067F00008000000760140000024000-000000067F00008000000760140000028000__0000009445A06DC8", +"000000067F00008000000760140000028000-000000067F0000800000076014000002C000__0000009445A06DC8", +"000000067F00008000000760140000029CC5-030000000000000000000000000000000002__00000093786F8001-0000009402435A49", +"000000067F0000800000076014000002C000-030000000000000000000000000000000002__0000009445A06DC8", +"000000067F000080000007800C0000000000-000000067F000080000007800C0000004000__00000096187D1FC8", +"000000067F000080000007800C0000000000-000000067F000080000007800C0000004000__00000096E85806C0", +"000000067F000080000007800C0000004000-000000067F000080000007800C0000008000__00000096187D1FC8", +"000000067F000080000007800C0000004000-000000067F000080000007800C0000008000__00000096E85806C0", +"000000067F000080000007800C0000008000-000000067F000080000007800C000000C000__00000096187D1FC8", +"000000067F000080000007800C0000008000-000000067F000080000007800C000000C000__00000096E85806C0", +"000000067F000080000007800C000000974C-000000067F000080000007800C0000012EB2__0000009446B52FD1-00000094D67DF4F9", +"000000067F000080000007800C000000C000-000000067F000080000007800C0000010000__00000096187D1FC8", +"000000067F000080000007800C000000C000-000000067F000080000007800C0000010000__00000096E85806C0", +"000000067F000080000007800C0000010000-000000067F000080000007800C0000014000__00000096187D1FC8", +"000000067F000080000007800C0000010000-000000067F000080000007800C0000014000__00000096E85806C0", +"000000067F000080000007800C0000012EB2-000000067F000080000007800C000001C60B__0000009446B52FD1-00000094D67DF4F9", +"000000067F000080000007800C0000014000-000000067F000080000007800C0000018000__00000096187D1FC8", +"000000067F000080000007800C0000014000-000000067F000080000007800C0000018000__00000096E85806C0", +"000000067F000080000007800C0000018000-000000067F000080000007800C000001C000__00000096187D1FC8", +"000000067F000080000007800C0000018000-000000067F000080000007800C000001C000__00000096E85806C0", +"000000067F000080000007800C000001C000-000000067F000080000007800C0000020000__00000096187D1FC8", +"000000067F000080000007800C000001C000-000000067F000080000007800C0000020000__00000096E85806C0", +"000000067F000080000007800C000001C60B-000000067F000080000007800C0000025D39__0000009446B52FD1-00000094D67DF4F9", +"000000067F000080000007800C0000020000-000000067F000080000007800C0000024000__00000096187D1FC8", +"000000067F000080000007800C0000020000-000000067F000080000007800C0000024000__00000096E85806C0", +"000000067F000080000007800C0000024000-000000067F000080000007800C0000028000__00000096187D1FC8", +"000000067F000080000007800C0000024000-000000067F000080000007800C0000028000__00000096E85806C0", +"000000067F000080000007800C0000025D39-000000067F000080000007800C000002F49F__0000009446B52FD1-00000094D67DF4F9", +"000000067F000080000007800C0000028000-000000067F000080000007800C000002C000__00000096187D1FC8", +"000000067F000080000007800C0000028000-000000067F000080000007800C000002C000__00000096E85806C0", +"000000067F000080000007800C000002C000-000000067F000080000007800C0000030000__00000096187D1FC8", +"000000067F000080000007800C000002C000-000000067F000080000007800C0000030000__00000096E85806C0", +"000000067F000080000007800C000002F49F-000000067F000080000007800C0000038BB2__0000009446B52FD1-00000094D67DF4F9", +"000000067F000080000007800C0000030000-000000067F000080000007800C0000034000__00000096187D1FC8", +"000000067F000080000007800C0000030000-000000067F000080000007800C0000034000__00000096E85806C0", +"000000067F000080000007800C0000034000-000000067F000080000007800C0000038000__00000096187D1FC8", +"000000067F000080000007800C0000034000-000000067F000080000007800C0000038000__00000096E85806C0", +"000000067F000080000007800C0000038000-000000067F000080000007800C000003C000__00000096187D1FC8", +"000000067F000080000007800C0000038000-000000067F000080000007800C000003C000__00000096E85806C0", +"000000067F000080000007800C0000038BB2-000000067F000080000007800C0000042318__0000009446B52FD1-00000094D67DF4F9", +"000000067F000080000007800C000003C000-000000067F000080000007800C0000040000__00000096187D1FC8", +"000000067F000080000007800C000003C000-000000067F000080000007800C0000040000__00000096E85806C0", +"000000067F000080000007800C0000040000-000000067F000080000007800C0000044000__00000096187D1FC8", +"000000067F000080000007800C0000040000-000000067F000080000007800C0000044000__00000096E85806C0", +"000000067F000080000007800C0000042318-000000067F000080000007800C000004BA7E__0000009446B52FD1-00000094D67DF4F9", +"000000067F000080000007800C0000044000-000000067F000080000007800C0000048000__00000096187D1FC8", +"000000067F000080000007800C0000044000-000000067F000080000007800C0000048000__00000096E85806C0", +"000000067F000080000007800C0000048000-000000067F000080000007800C000004C000__00000096187D1FC8", +"000000067F000080000007800C0000048000-000000067F000080000007800C000004C000__00000096E85806C0", +"000000067F000080000007800C000004BA7E-000000067F000080000007800C00000551B3__0000009446B52FD1-00000094D67DF4F9", +"000000067F000080000007800C000004C000-000000067F000080000007800C0000050000__00000096187D1FC8", +"000000067F000080000007800C000004C000-000000067F000080000007800C0000050000__00000096E85806C0", +"000000067F000080000007800C0000050000-000000067F000080000007800C0000054000__00000096187D1FC8", +"000000067F000080000007800C0000050000-000000067F000080000007800C0000054000__00000096E85806C0", +"000000067F000080000007800C0000054000-000000067F000080000007800C0000058000__0000009614F1FFE8", +"000000067F000080000007800C0000054000-000000067F000080000007800C0000058000__00000096E85806C0", +"000000067F000080000007800C00000551B3-030000000000000000000000000000000002__0000009446B52FD1-00000094D67DF4F9", +"000000067F000080000007800C000005523E-000000067F000080000007800C000005E9A4__00000094D67DF4F9-000000959635F2A9", +"000000067F000080000007800C0000058000-000000067F000080000007800C000005C000__0000009614F1FFE8", +"000000067F000080000007800C0000058000-000000067F000080000007800C000005C000__00000096E85806C0", +"000000067F000080000007800C000005C000-000000067F000080000007800C0000060000__0000009614F1FFE8", +"000000067F000080000007800C000005C000-000000067F000080000007800C0000060000__00000096E85806C0", +"000000067F000080000007800C000005E9A4-000000067F000080000007800C000006810A__00000094D67DF4F9-000000959635F2A9", +"000000067F000080000007800C0000060000-000000067F000080000007800C0000064000__0000009614F1FFE8", +"000000067F000080000007800C0000060000-000000067F000080000007800C0000064000__00000096E85806C0", +"000000067F000080000007800C0000064000-000000067F000080000007800C0000068000__0000009614F1FFE8", +"000000067F000080000007800C0000064000-000000067F000080000007800C0000068000__00000096E85806C0", +"000000067F000080000007800C0000068000-000000067F000080000007800C000006C000__0000009614F1FFE8", +"000000067F000080000007800C0000068000-000000067F000080000007800C000006C000__00000096E85806C0", +"000000067F000080000007800C000006810A-000000067F000080000007800C0000071870__00000094D67DF4F9-000000959635F2A9", +"000000067F000080000007800C000006C000-000000067F000080000007800C0000070000__0000009614F1FFE8", +"000000067F000080000007800C000006C000-000000067F000080000007800C0000070000__00000096E85806C0", +"000000067F000080000007800C000006D446-000000067F000080000007800C00000D9B82__00000096AEF27399-00000096E85829C9", +"000000067F000080000007800C0000070000-000000067F000080000007800C0000074000__0000009614F1FFE8", +"000000067F000080000007800C0000070000-000000067F000080000007800C0000074000__00000096E85806C0", +"000000067F000080000007800C0000071870-000000067F000080000007800C000007AFD6__00000094D67DF4F9-000000959635F2A9", +"000000067F000080000007800C0000074000-000000067F000080000007800C0000078000__0000009614F1FFE8", +"000000067F000080000007800C0000074000-000000067F000080000007800C0000078000__00000096E85806C0", +"000000067F000080000007800C0000078000-000000067F000080000007800C000007C000__0000009614F1FFE8", +"000000067F000080000007800C0000078000-000000067F000080000007800C000007C000__00000096E85806C0", +"000000067F000080000007800C000007AFD6-000000067F000080000007800C000008470B__00000094D67DF4F9-000000959635F2A9", +"000000067F000080000007800C000007B8DE-000000067F000080000007800C00000F73DA__00000096193A8001-00000096AEF27399", +"000000067F000080000007800C000007C000-000000067F000080000007800C0000080000__0000009614F1FFE8", +"000000067F000080000007800C000007C000-000000067F000080000007800C0000080000__00000096E85806C0", +"000000067F000080000007800C0000080000-000000067F000080000007800C0000084000__0000009614F1FFE8", +"000000067F000080000007800C0000080000-000000067F000080000007800C0000084000__00000096E85806C0", +"000000067F000080000007800C0000084000-000000067F000080000007800C0000088000__0000009614F1FFE8", +"000000067F000080000007800C0000084000-000000067F000080000007800C0000088000__00000096E85806C0", +"000000067F000080000007800C000008470B-000000067F000080000007800C000008DE71__00000094D67DF4F9-000000959635F2A9", +"000000067F000080000007800C0000088000-000000067F000080000007800C000008C000__0000009614F1FFE8", +"000000067F000080000007800C0000088000-000000067F000080000007800C000008C000__00000096E85806C0", +"000000067F000080000007800C000008C000-000000067F000080000007800C0000090000__0000009614F1FFE8", +"000000067F000080000007800C000008C000-000000067F000080000007800C0000090000__00000096E85806C0", +"000000067F000080000007800C000008DE71-000000067F000080000007800C0000097591__00000094D67DF4F9-000000959635F2A9", +"000000067F000080000007800C0000090000-000000067F000080000007800C0000094000__0000009614F1FFE8", +"000000067F000080000007800C0000090000-000000067F000080000007800C0000094000__00000096E85806C0", +"000000067F000080000007800C0000094000-000000067F000080000007800C0000098000__0000009614F1FFE8", +"000000067F000080000007800C0000094000-000000067F000080000007800C0000098000__00000096E85806C0", +"000000067F000080000007800C0000097591-000000067F000080000007800C00000A0CF7__00000094D67DF4F9-000000959635F2A9", +"000000067F000080000007800C0000098000-000000067F000080000007800C000009C000__0000009614F1FFE8", +"000000067F000080000007800C0000098000-000000067F000080000007800C000009C000__00000096E85806C0", +"000000067F000080000007800C000009C000-000000067F000080000007800C00000A0000__0000009614F1FFE8", +"000000067F000080000007800C000009C000-000000067F000080000007800C00000A0000__00000096E85806C0", +"000000067F000080000007800C00000A0000-000000067F000080000007800C00000A4000__0000009614F1FFE8", +"000000067F000080000007800C00000A0000-000000067F000080000007800C00000A4000__00000096E85806C0", +"000000067F000080000007800C00000A0CF7-000000067F000080000007800C00000AA40B__00000094D67DF4F9-000000959635F2A9", +"000000067F000080000007800C00000A4000-000000067F000080000007800C00000A8000__0000009614F1FFE8", +"000000067F000080000007800C00000A4000-000000067F000080000007800C00000A8000__00000096E85806C0", +"000000067F000080000007800C00000A8000-000000067F000080000007800C00000AC000__0000009614F1FFE8", +"000000067F000080000007800C00000A8000-000000067F000080000007800C00000AC000__00000096E85806C0", +"000000067F000080000007800C00000AA40B-000000067F000080000007800C00000B3B4D__00000094D67DF4F9-000000959635F2A9", +"000000067F000080000007800C00000AC000-000000067F000080000007800C00000B0000__0000009614F1FFE8", +"000000067F000080000007800C00000AC000-000000067F000080000007800C00000B0000__00000096E85806C0", +"000000067F000080000007800C00000B0000-000000067F000080000007800C00000B4000__0000009614F1FFE8", +"000000067F000080000007800C00000B0000-000000067F000080000007800C00000B4000__00000096E85806C0", +"000000067F000080000007800C00000B3B4D-000000067F000080000007800C00000BD2B3__00000094D67DF4F9-000000959635F2A9", +"000000067F000080000007800C00000B4000-000000067F000080000007800C00000B8000__0000009614F1FFE8", +"000000067F000080000007800C00000B4000-000000067F000080000007800C00000B8000__00000096E85806C0", +"000000067F000080000007800C00000B8000-000000067F000080000007800C00000BC000__0000009614F1FFE8", +"000000067F000080000007800C00000B8000-000000067F000080000007800C00000BC000__00000096E85806C0", +"000000067F000080000007800C00000BC000-000000067F000080000007800C00000C0000__0000009614F1FFE8", +"000000067F000080000007800C00000BC000-000000067F000080000007800C00000C0000__00000096E85806C0", +"000000067F000080000007800C00000BD2B3-000000067F000080000007800C00000C69DA__00000094D67DF4F9-000000959635F2A9", +"000000067F000080000007800C00000C0000-000000067F000080000007800C00000C4000__0000009614F1FFE8", +"000000067F000080000007800C00000C0000-000000067F000080000007800C00000C4000__00000096E85806C0", +"000000067F000080000007800C00000C4000-000000067F000080000007800C00000C8000__0000009614F1FFE8", +"000000067F000080000007800C00000C4000-000000067F000080000007800C00000C8000__00000096E85806C0", +"000000067F000080000007800C00000C69DA-000000067F000080000007800C0100000000__00000094D67DF4F9-000000959635F2A9", +"000000067F000080000007800C00000C8000-000000067F000080000007800C00000CC000__0000009614F1FFE8", +"000000067F000080000007800C00000C8000-000000067F000080000007800C00000CC000__00000096E85806C0", +"000000067F000080000007800C00000CC000-000000067F000080000007800C00000D0000__0000009614F1FFE8", +"000000067F000080000007800C00000CC000-000000067F000080000007800C00000D0000__00000096E85806C0", +"000000067F000080000007800C00000CD6B6-000000067F000080000007800C00000D6C18__000000959635F2A9-00000096193A8001", +"000000067F000080000007800C00000D0000-000000067F000080000007800C00000D4000__0000009614F1FFE8", +"000000067F000080000007800C00000D0000-000000067F000080000007800C00000D4000__00000096E85806C0", +"000000067F000080000007800C00000D4000-000000067F000080000007800C00000D8000__0000009614F1FFE8", +"000000067F000080000007800C00000D4000-000000067F000080000007800C00000D8000__00000096E85806C0", +"000000067F000080000007800C00000D6C18-000000067F000080000007800C00000E0179__000000959635F2A9-00000096193A8001", +"000000067F000080000007800C00000D8000-000000067F000080000007800C00000DC000__0000009614F1FFE8", +"000000067F000080000007800C00000D8000-000000067F000080000007800C00000DC000__00000096E85806C0", +"000000067F000080000007800C00000D9BA3-000000067F00008000000780140000013481__00000096AEF27399-00000096E85829C9", +"000000067F000080000007800C00000DC000-000000067F000080000007800C00000E0000__0000009614F1FFE8", +"000000067F000080000007800C00000DC000-000000067F000080000007800C00000E0000__00000096E85806C0", +"000000067F000080000007800C00000E0000-000000067F000080000007800C00000E4000__0000009614F1FFE8", +"000000067F000080000007800C00000E0000-000000067F000080000007800C00000E4000__00000096E85806C0", +"000000067F000080000007800C00000E0179-000000067F000080000007800C00000E96DC__000000959635F2A9-00000096193A8001", +"000000067F000080000007800C00000E4000-000000067F000080000007800C00000E8000__0000009614F1FFE8", +"000000067F000080000007800C00000E4000-000000067F000080000007800C00000E8000__00000096E85806C0", +"000000067F000080000007800C00000E8000-000000067F000080000007800C00000EC000__0000009614F1FFE8", +"000000067F000080000007800C00000E8000-000000067F000080000007800C00000EC000__00000096E85806C0", +"000000067F000080000007800C00000E96DC-000000067F000080000007800C00000F2C3E__000000959635F2A9-00000096193A8001", +"000000067F000080000007800C00000EC000-000000067F000080000007800C00000F0000__0000009614F1FFE8", +"000000067F000080000007800C00000EC000-000000067F000080000007800C00000F0000__00000096E85806C0", +"000000067F000080000007800C00000F0000-000000067F000080000007800C00000F4000__0000009614F1FFE8", +"000000067F000080000007800C00000F0000-000000067F000080000007800C00000F4000__00000096E85806C0", +"000000067F000080000007800C00000F2C3E-000000067F000080000007800C00000FC1A0__000000959635F2A9-00000096193A8001", +"000000067F000080000007800C00000F4000-000000067F000080000007800C00000F8000__0000009614F1FFE8", +"000000067F000080000007800C00000F4000-000000067F000080000007800C00000F8000__00000096E85806C0", +"000000067F000080000007800C00000F73E3-000000067F00008000000780140000003F18__00000096193A8001-00000096AEF27399", +"000000067F000080000007800C00000F8000-000000067F000080000007800C00000FC000__0000009614F1FFE8", +"000000067F000080000007800C00000F8000-000000067F000080000007800C00000FC000__00000096E85806C0", +"000000067F000080000007800C00000FC000-000000067F000080000007800C0000100000__0000009614F1FFE8", +"000000067F000080000007800C00000FC000-000000067F000080000007800C0000100000__00000096E85806C0", +"000000067F000080000007800C00000FC1A0-000000067F000080000007800C00001057C1__000000959635F2A9-00000096193A8001", +"000000067F000080000007800C0000100000-000000067F000080000007800C0000104000__0000009614F1FFE8", +"000000067F000080000007800C0000100000-000000067F000080000007800C0000104000__00000096E85806C0", +"000000067F000080000007800C0000104000-000000067F000080000007800C0000108000__0000009614F1FFE8", +"000000067F000080000007800C0000104000-000000067F000080000007800C0000108000__00000096E85806C0", +"000000067F000080000007800C00001057C1-000000067F000080000007800C000010EF0B__000000959635F2A9-00000096193A8001", +"000000067F000080000007800C0000108000-000000067F000080000007800C000010C000__0000009614F1FFE8", +"000000067F000080000007800C0000108000-000000067F000080000007800C000010C000__00000096E85806C0", +"000000067F000080000007800C000010C000-000000067F000080000007800C0000110000__0000009614F1FFE8", +"000000067F000080000007800C000010C000-000000067F000080000007800C0000110000__00000096E85806C0", +"000000067F000080000007800C000010EF0B-01000000000000000100000004000000000B__000000959635F2A9-00000096193A8001", +"000000067F000080000007800C0000110000-000000067F00008000000780120100000000__00000096E85806C0", +"000000067F000080000007800C0000110000-030000000000000000000000000000000002__0000009614F1FFE8", +"000000067F00008000000780140000000000-000000067F00008000000780140000004000__00000096E85806C0", +"000000067F00008000000780140000003F18-000000067F00008000000780140000009ED4__00000096193A8001-00000096AEF27399", +"000000067F00008000000780140000004000-000000067F00008000000780140000008000__00000096E85806C0", +"000000067F00008000000780140000008000-000000067F0000800000078014000000C000__00000096E85806C0", +"000000067F00008000000780140000009ED4-000000067F0000800000078014000000FE9A__00000096193A8001-00000096AEF27399", +"000000067F0000800000078014000000C000-000000067F00008000000780140000010000__00000096E85806C0", +"000000067F0000800000078014000000FE9A-000000067F00008000000780140000015DD1__00000096193A8001-00000096AEF27399", +"000000067F00008000000780140000010000-000000067F00008000000780140000014000__00000096E85806C0", +"000000067F00008000000780140000013481-030000000000000000000000000000000002__00000096AEF27399-00000096E85829C9", +"000000067F00008000000780140000014000-000000067F00008000000780140000018000__00000096E85806C0", +"000000067F00008000000780140000015DD1-000000067F0000800000078014000001BD7E__00000096193A8001-00000096AEF27399", +"000000067F00008000000780140000018000-000000067F0000800000078014000001C000__00000096E85806C0", +"000000067F0000800000078014000001BD7E-000000067F00008000000780140000021CF0__00000096193A8001-00000096AEF27399", +"000000067F0000800000078014000001C000-000000067F00008000000780140000020000__00000096E85806C0", +"000000067F00008000000780140000020000-000000067F00008000000780140000024000__00000096E85806C0", +"000000067F00008000000780140000021CF0-000000067F00008000000780140000027CF8__00000096193A8001-00000096AEF27399", +"000000067F00008000000780140000024000-000000067F00008000000780140000028000__00000096E85806C0", +"000000067F00008000000780140000027CF8-000000067F0000800000078014000002DC88__00000096193A8001-00000096AEF27399", +"000000067F00008000000780140000028000-000000067F0000800000078014000002C000__00000096E85806C0", +"000000067F0000800000078014000002C000-030000000000000000000000000000000002__00000096E85806C0", +"000000067F0000800000078014000002DC88-030000000000000000000000000000000002__00000096193A8001-00000096AEF27399", +"000000067F000080000007A00C0000000000-000000067F000080000007A00C0000004000__0000009921F3B4A8", +"000000067F000080000007A00C0000004000-000000067F000080000007A00C0000008000__0000009921F3B4A8", +"000000067F000080000007A00C0000008000-000000067F000080000007A00C000000C000__0000009921F3B4A8", +"000000067F000080000007A00C000000974B-000000067F000080000007A00C0000012EB1__00000096E85829C9-00000098A7ADFC91", +"000000067F000080000007A00C000000C000-000000067F000080000007A00C0000010000__0000009921F3B4A8", +"000000067F000080000007A00C0000010000-000000067F000080000007A00C0000014000__0000009921F3B4A8", +"000000067F000080000007A00C0000012EB1-000000067F000080000007A00C000001C60B__00000096E85829C9-00000098A7ADFC91", +"000000067F000080000007A00C0000014000-000000067F000080000007A00C0000018000__0000009921F3B4A8", +"000000067F000080000007A00C0000018000-000000067F000080000007A00C000001C000__0000009921F3B4A8", +"000000067F000080000007A00C000001C000-000000067F000080000007A00C0000020000__0000009921F3B4A8", +"000000067F000080000007A00C000001C60B-000000067F000080000007A00C0000025D39__00000096E85829C9-00000098A7ADFC91", +"000000067F000080000007A00C0000020000-000000067F000080000007A00C0000024000__0000009921F3B4A8", +"000000067F000080000007A00C0000024000-000000067F000080000007A00C0000028000__0000009921F3B4A8", +"000000067F000080000007A00C0000025D39-000000067F000080000007A00C000002F49F__00000096E85829C9-00000098A7ADFC91", +"000000067F000080000007A00C0000028000-000000067F000080000007A00C000002C000__0000009921F3B4A8", +"000000067F000080000007A00C000002C000-000000067F000080000007A00C0000030000__0000009921F3B4A8", +"000000067F000080000007A00C000002F49F-000000067F000080000007A00C0000038BB2__00000096E85829C9-00000098A7ADFC91", +"000000067F000080000007A00C0000030000-000000067F000080000007A00C0000034000__0000009921F3B4A8", +"000000067F000080000007A00C0000034000-000000067F000080000007A00C0000038000__0000009921F3B4A8", +"000000067F000080000007A00C0000038000-000000067F000080000007A00C000003C000__0000009921F3B4A8", +"000000067F000080000007A00C0000038BB2-000000067F000080000007A00C0000042318__00000096E85829C9-00000098A7ADFC91", +"000000067F000080000007A00C000003C000-000000067F000080000007A00C0000040000__0000009921F3B4A8", +"000000067F000080000007A00C0000040000-000000067F000080000007A00C0000044000__0000009921F3B4A8", +"000000067F000080000007A00C0000042318-000000067F000080000007A00C000004BA7E__00000096E85829C9-00000098A7ADFC91", +"000000067F000080000007A00C0000044000-000000067F000080000007A00C0000048000__0000009921F3B4A8", +"000000067F000080000007A00C0000048000-000000067F000080000007A00C000004C000__0000009921F3B4A8", +"000000067F000080000007A00C000004B9B2-000000067F000080000007A00C0000097B6D__0000009921E47AA1-000000997F5D23C9", +"000000067F000080000007A00C000004BA7E-000000067F000080000007A00C00000551B3__00000096E85829C9-00000098A7ADFC91", +"000000067F000080000007A00C000004C000-000000067F000080000007A00C0000050000__0000009921F3B4A8", +"000000067F000080000007A00C0000050000-000000067F000080000007A00C0000054000__0000009921F3B4A8", +"000000067F000080000007A00C0000054000-000000067F000080000007A00C0000058000__0000009921F3B4A8", +"000000067F000080000007A00C00000551B3-000000067F000080000007A00C000005E90A__00000096E85829C9-00000098A7ADFC91", +"000000067F000080000007A00C0000058000-000000067F000080000007A00C000005C000__0000009921F3B4A8", +"000000067F000080000007A00C000005C000-000000067F000080000007A00C0000060000__0000009921F3B4A8", +"000000067F000080000007A00C000005E90A-000000067F000080000007A00C000006802C__00000096E85829C9-00000098A7ADFC91", +"000000067F000080000007A00C0000060000-000000067F000080000007A00C0000064000__0000009921F3B4A8", +"000000067F000080000007A00C0000064000-000000067F000080000007A00C0000068000__0000009921F3B4A8", +"000000067F000080000007A00C0000068000-000000067F000080000007A00C000006C000__0000009921F3B4A8", +"000000067F000080000007A00C000006802C-000000067F000080000007A00C0000071783__00000096E85829C9-00000098A7ADFC91", +"000000067F000080000007A00C000006C000-000000067F000080000007A00C0000070000__0000009921F3B4A8", +"000000067F000080000007A00C0000070000-000000067F000080000007A00C0000074000__0000009921F3B4A8", +"000000067F000080000007A00C0000071783-000000067F000080000007A00C000007AEE8__00000096E85829C9-00000098A7ADFC91", +"000000067F000080000007A00C0000074000-000000067F000080000007A00C0000078000__0000009921F3B4A8", +"000000067F000080000007A00C0000078000-000000067F000080000007A00C000007C000__0000009921F3B4A8", +"000000067F000080000007A00C000007AEE8-000000067F000080000007A00C000008460B__00000096E85829C9-00000098A7ADFC91", +"000000067F000080000007A00C000007C000-000000067F000080000007A00C0000080000__0000009921F3B4A8", +"000000067F000080000007A00C0000080000-000000067F000080000007A00C0000084000__0000009921F3B4A8", +"000000067F000080000007A00C0000084000-000000067F000080000007A00C0000088000__0000009921F3B4A8", +"000000067F000080000007A00C000008460B-000000067F000080000007A00C000008DD71__00000096E85829C9-00000098A7ADFC91", +"000000067F000080000007A00C0000088000-000000067F000080000007A00C000008C000__0000009921F3B4A8", +"000000067F000080000007A00C000008C000-000000067F000080000007A00C0000090000__0000009921F3B4A8", +"000000067F000080000007A00C000008DD71-000000067F000080000007A00C00000974D7__00000096E85829C9-00000098A7ADFC91", +"000000067F000080000007A00C0000090000-000000067F000080000007A00C0000094000__0000009921F3B4A8", +"000000067F000080000007A00C0000094000-000000067F000080000007A00C0000098000__0000009921F3B4A8", +"000000067F000080000007A00C00000974D7-000000067F000080000007A00C00000A0C0B__00000096E85829C9-00000098A7ADFC91", +"000000067F000080000007A00C0000097B7A-000000067F000080000007A00C00000E3627__0000009921E47AA1-000000997F5D23C9", +"000000067F000080000007A00C0000098000-000000067F000080000007A00C000009C000__0000009921F3B4A8", +"000000067F000080000007A00C000009C000-000000067F000080000007A00C00000A0000__0000009921F3B4A8", +"000000067F000080000007A00C00000A0000-000000067F000080000007A00C00000A4000__0000009921F3B4A8", +"000000067F000080000007A00C00000A0C0B-000000067F000080000007A00C00000AA371__00000096E85829C9-00000098A7ADFC91", +"000000067F000080000007A00C00000A4000-000000067F000080000007A00C00000A8000__0000009921F3B4A8", +"000000067F000080000007A00C00000A8000-000000067F000080000007A00C00000AC000__0000009921F3B4A8", +"000000067F000080000007A00C00000AA371-000000067F000080000007A00C00000B3AD7__00000096E85829C9-00000098A7ADFC91", +"000000067F000080000007A00C00000AC000-000000067F000080000007A00C00000B0000__0000009921F3B4A8", +"000000067F000080000007A00C00000B0000-000000067F000080000007A00C00000B4000__0000009921F3B4A8", +"000000067F000080000007A00C00000B3AD7-000000067F000080000007A00C00000BD20B__00000096E85829C9-00000098A7ADFC91", +"000000067F000080000007A00C00000B4000-000000067F000080000007A00C00000B8000__0000009921F3B4A8", +"000000067F000080000007A00C00000B8000-000000067F000080000007A00C00000BC000__0000009921F3B4A8", +"000000067F000080000007A00C00000BC000-000000067F000080000007A00C00000C0000__0000009921F3B4A8", +"000000067F000080000007A00C00000BD20B-000000067F000080000007A00C00000C6932__00000096E85829C9-00000098A7ADFC91", +"000000067F000080000007A00C00000C0000-000000067F000080000007A00C00000C4000__0000009921F3B4A8", +"000000067F000080000007A00C00000C4000-000000067F000080000007A00C00000C8000__0000009921F3B4A8", +"000000067F000080000007A00C00000C6932-000000067F000080000007A00C00000D0098__00000096E85829C9-00000098A7ADFC91", +"000000067F000080000007A00C00000C8000-000000067F000080000007A00C00000CC000__0000009921F3B4A8", +"000000067F000080000007A00C00000CC000-000000067F000080000007A00C00000D0000__0000009921F3B4A8", +"000000067F000080000007A00C00000D0000-000000067F000080000007A00C00000D4000__0000009921F3B4A8", +"000000067F000080000007A00C00000D0098-000000067F000080000007A00C00000D97FE__00000096E85829C9-00000098A7ADFC91", +"000000067F000080000007A00C00000D4000-000000067F000080000007A00C00000D8000__0000009921F3B4A8", +"000000067F000080000007A00C00000D8000-000000067F000080000007A00C00000DC000__0000009921F3B4A8", +"000000067F000080000007A00C00000D97FE-000000067F000080000007A00C00000E2F0B__00000096E85829C9-00000098A7ADFC91", +"000000067F000080000007A00C00000DC000-000000067F000080000007A00C00000E0000__0000009921F3B4A8", +"000000067F000080000007A00C00000E0000-000000067F000080000007A00C00000E4000__0000009921F3B4A8", +"000000067F000080000007A00C00000E2F0B-000000067F000080000007A00C00000EC671__00000096E85829C9-00000098A7ADFC91", +"000000067F000080000007A00C00000E364A-000000067F000080000007A01400000065FE__0000009921E47AA1-000000997F5D23C9", +"000000067F000080000007A00C00000E4000-000000067F000080000007A00C00000E8000__0000009921F3B4A8", +"000000067F000080000007A00C00000E8000-000000067F000080000007A00C00000EC000__0000009921F3B4A8", +"000000067F000080000007A00C00000EC000-000000067F000080000007A00C00000F0000__0000009921F3B4A8", +"000000067F000080000007A00C00000EC671-000000067F000080000007A00C00000F5D9F__00000096E85829C9-00000098A7ADFC91", +"000000067F000080000007A00C00000F0000-000000067F000080000007A00C00000F4000__0000009921F3B4A8", +"000000067F000080000007A00C00000F4000-000000067F000080000007A00C00000F8000__0000009921F3B4A8", +"000000067F000080000007A00C00000F5D9F-000000067F000080000007A00C00000FF505__00000096E85829C9-00000098A7ADFC91", +"000000067F000080000007A00C00000F720F-000000067F000080000007A00C0000111692__00000098A7ADFC91-0000009921E47AA1", +"000000067F000080000007A00C00000F8000-000000067F000080000007A00C00000FC000__0000009921F3B4A8", +"000000067F000080000007A00C00000FC000-000000067F000080000007A00C0000100000__0000009921F3B4A8", +"000000067F000080000007A00C00000FF505-000000067F000080000007A00C0000108C10__00000096E85829C9-00000098A7ADFC91", +"000000067F000080000007A00C0000100000-000000067F000080000007A00C0000104000__0000009921F3B4A8", +"000000067F000080000007A00C0000104000-000000067F000080000007A00C0000108000__0000009921F3B4A8", +"000000067F000080000007A00C0000108000-000000067F000080000007A00C000010C000__0000009921F3B4A8", +"000000067F000080000007A00C0000108C10-030000000000000000000000000000000002__00000096E85829C9-00000098A7ADFC91", +"000000067F000080000007A00C000010C000-000000067F000080000007A00C0000110000__0000009921F3B4A8", +"000000067F000080000007A00C0000110000-000000067F000080000007A0120100000000__0000009921F3B4A8", +"000000067F000080000007A00C0000111692-000000067F000080000007A01400000040E7__00000098A7ADFC91-0000009921E47AA1", +"000000067F000080000007A0140000000000-000000067F000080000007A0140000004000__0000009921F3B4A8", +"000000067F000080000007A0140000004000-000000067F000080000007A0140000008000__0000009921F3B4A8", +"000000067F000080000007A01400000040E7-000000067F000080000007A014000000B5F6__00000098A7ADFC91-0000009921E47AA1", +"000000067F000080000007A0140000006601-000000067F000080000007A014000001B4CB__0000009921E47AA1-000000997F5D23C9", +"000000067F000080000007A0140000008000-000000067F000080000007A014000000C000__0000009921F3B4A8", +"000000067F000080000007A014000000B5F6-000000067F000080000007A0140000012AFC__00000098A7ADFC91-0000009921E47AA1", +"000000067F000080000007A014000000C000-000000067F000080000007A0140000010000__0000009921F3B4A8", +"000000067F000080000007A0140000010000-000000067F000080000007A0140000014000__0000009921F3B4A8", +"000000067F000080000007A0140000012AFC-000000067F000080000007A0140000019F9B__00000098A7ADFC91-0000009921E47AA1", +"000000067F000080000007A0140000014000-000000067F000080000007A0140000018000__0000009921F3B4A8", +"000000067F000080000007A0140000018000-000000067F000080000007A014000001C000__0000009921F3B4A8", +"000000067F000080000007A0140000019F9B-000000067F000080000007A01400000214BE__00000098A7ADFC91-0000009921E47AA1", +"000000067F000080000007A014000001B4CB-030000000000000000000000000000000002__0000009921E47AA1-000000997F5D23C9", +"000000067F000080000007A014000001C000-000000067F000080000007A0140000020000__0000009921F3B4A8", +"000000067F000080000007A0140000020000-000000067F000080000007A0140000024000__0000009921F3B4A8", +"000000067F000080000007A01400000214BE-000000067F000080000007A01400000289C9__00000098A7ADFC91-0000009921E47AA1", +"000000067F000080000007A0140000024000-000000067F000080000007A0140000028000__0000009921F3B4A8", +"000000067F000080000007A0140000028000-000000067F000080000007A014000002C000__0000009921F3B4A8", +"000000067F000080000007A01400000289C9-030000000000000000000000000000000002__00000098A7ADFC91-0000009921E47AA1", +"000000067F000080000007A014000002C000-030000000000000000000000000000000002__0000009921F3B4A8", +"000000067F000080000007C00C0000000000-000000067F000080000007C00C0000004000__0000009B5229DFE8", +"000000067F000080000007C00C0000004000-000000067F000080000007C00C0000008000__0000009B5229DFE8", +"000000067F000080000007C00C0000007EA5-000000067F000080000007C00C00000115FE__000000997F5D23C9-00000099F1C9FC71", +"000000067F000080000007C00C0000008000-000000067F000080000007C00C000000C000__0000009B5229DFE8", +"000000067F000080000007C00C000000C000-000000067F000080000007C00C0000010000__0000009B5229DFE8", +"000000067F000080000007C00C0000010000-000000067F000080000007C00C0000014000__0000009B5229DFE8", +"000000067F000080000007C00C00000115FE-000000067F000080000007C00C000001AD0C__000000997F5D23C9-00000099F1C9FC71", +"000000067F000080000007C00C0000014000-000000067F000080000007C00C0000018000__0000009B5229DFE8", +"000000067F000080000007C00C0000018000-000000067F000080000007C00C000001C000__0000009B5229DFE8", +"000000067F000080000007C00C000001AD0C-000000067F000080000007C00C0000024472__000000997F5D23C9-00000099F1C9FC71", +"000000067F000080000007C00C000001C000-000000067F000080000007C00C0000020000__0000009B5229DFE8", +"000000067F000080000007C00C0000020000-000000067F000080000007C00C0000024000__0000009B5229DFE8", +"000000067F000080000007C00C0000024000-000000067F000080000007C00C0000028000__0000009B5229DFE8", +"000000067F000080000007C00C0000024472-000000067F000080000007C00C000002DBD8__000000997F5D23C9-00000099F1C9FC71", +"000000067F000080000007C00C0000028000-000000067F000080000007C00C000002C000__0000009B5229DFE8", +"000000067F000080000007C00C000002C000-000000067F000080000007C00C0000030000__0000009B5229DFE8", +"000000067F000080000007C00C000002DBD8-000000067F000080000007C00C000003732B__000000997F5D23C9-00000099F1C9FC71", +"000000067F000080000007C00C0000030000-000000067F000080000007C00C0000034000__0000009B5229DFE8", +"000000067F000080000007C00C0000034000-000000067F000080000007C00C0000038000__0000009B5229DFE8", +"000000067F000080000007C00C000003732B-000000067F000080000007C00C0000040A91__000000997F5D23C9-00000099F1C9FC71", +"000000067F000080000007C00C0000038000-000000067F000080000007C00C000003C000__0000009B5229DFE8", +"000000067F000080000007C00C000003C000-000000067F000080000007C00C0000040000__0000009B5229DFE8", +"000000067F000080000007C00C0000040000-000000067F000080000007C00C0000044000__0000009B40525F80", +"000000067F000080000007C00C0000040000-000000067F000080000007C00C0000044000__0000009C1E3799F0", +"000000067F000080000007C00C0000040A91-030000000000000000000000000000000002__000000997F5D23C9-00000099F1C9FC71", +"000000067F000080000007C00C0000042360-000000067F000080000007C00C000004BAC6__00000099F1C9FC71-0000009A918DF181", +"000000067F000080000007C00C0000044000-000000067F000080000007C00C0000048000__0000009B40525F80", +"000000067F000080000007C00C0000044000-000000067F000080000007C00C0000048000__0000009C1E3799F0", +"000000067F000080000007C00C0000048000-000000067F000080000007C00C000004C000__0000009B40525F80", +"000000067F000080000007C00C0000048000-000000067F000080000007C00C000004C000__0000009C1E3799F0", +"000000067F000080000007C00C000004BAC6-000000067F000080000007C00C00000551FB__00000099F1C9FC71-0000009A918DF181", +"000000067F000080000007C00C000004C000-000000067F000080000007C00C0000050000__0000009B40525F80", +"000000067F000080000007C00C000004C000-000000067F000080000007C00C0000050000__0000009C1E3799F0", +"000000067F000080000007C00C0000050000-000000067F000080000007C00C0000054000__0000009B40525F80", +"000000067F000080000007C00C0000050000-000000067F000080000007C00C0000054000__0000009C1E3799F0", +"000000067F000080000007C00C0000052AA4-000000067F000080000007C00C00000A4244__0000009BCB4E4461-0000009C1E8CC879", +"000000067F000080000007C00C0000054000-000000067F000080000007C00C0000058000__0000009B40525F80", +"000000067F000080000007C00C0000054000-000000067F000080000007C00C0000058000__0000009C1E3799F0", +"000000067F000080000007C00C00000551FB-000000067F000080000007C00C000005E90B__00000099F1C9FC71-0000009A918DF181", +"000000067F000080000007C00C0000058000-000000067F000080000007C00C000005C000__0000009B40525F80", +"000000067F000080000007C00C0000058000-000000067F000080000007C00C000005C000__0000009C1E3799F0", +"000000067F000080000007C00C000005C000-000000067F000080000007C00C0000060000__0000009B40525F80", +"000000067F000080000007C00C000005C000-000000067F000080000007C00C0000060000__0000009C1E3799F0", +"000000067F000080000007C00C000005E90B-000000067F000080000007C00C000006802B__00000099F1C9FC71-0000009A918DF181", +"000000067F000080000007C00C0000060000-000000067F000080000007C00C0000064000__0000009B40525F80", +"000000067F000080000007C00C0000060000-000000067F000080000007C00C0000064000__0000009C1E3799F0", +"000000067F000080000007C00C0000064000-000000067F000080000007C00C0000068000__0000009B40525F80", +"000000067F000080000007C00C0000064000-000000067F000080000007C00C0000068000__0000009C1E3799F0", +"000000067F000080000007C00C0000068000-000000067F000080000007C00C000006C000__0000009B40525F80", +"000000067F000080000007C00C0000068000-000000067F000080000007C00C000006C000__0000009C1E3799F0", +"000000067F000080000007C00C000006802B-000000067F000080000007C00C0000071782__00000099F1C9FC71-0000009A918DF181", +"000000067F000080000007C00C000006C000-000000067F000080000007C00C0000070000__0000009B40525F80", +"000000067F000080000007C00C000006C000-000000067F000080000007C00C0000070000__0000009C1E3799F0", +"000000067F000080000007C00C0000070000-000000067F000080000007C00C0000074000__0000009B40525F80", +"000000067F000080000007C00C0000070000-000000067F000080000007C00C0000074000__0000009C1E3799F0", +"000000067F000080000007C00C0000071782-000000067F000080000007C00C000007AEE8__00000099F1C9FC71-0000009A918DF181", +"000000067F000080000007C00C0000074000-000000067F000080000007C00C0000078000__0000009B40525F80", +"000000067F000080000007C00C0000074000-000000067F000080000007C00C0000078000__0000009C1E3799F0", +"000000067F000080000007C00C0000078000-000000067F000080000007C00C000007C000__0000009B40525F80", +"000000067F000080000007C00C0000078000-000000067F000080000007C00C000007C000__0000009C1E3799F0", +"000000067F000080000007C00C000007AEE8-000000067F000080000007C00C000008460B__00000099F1C9FC71-0000009A918DF181", +"000000067F000080000007C00C000007C000-000000067F000080000007C00C0000080000__0000009B40525F80", +"000000067F000080000007C00C000007C000-000000067F000080000007C00C0000080000__0000009C1E3799F0", +"000000067F000080000007C00C0000080000-000000067F000080000007C00C0000084000__0000009B40525F80", +"000000067F000080000007C00C0000080000-000000067F000080000007C00C0000084000__0000009C1E3799F0", +"000000067F000080000007C00C0000084000-000000067F000080000007C00C0000088000__0000009B40525F80", +"000000067F000080000007C00C0000084000-000000067F000080000007C00C0000088000__0000009C1E3799F0", +"000000067F000080000007C00C000008460B-000000067F000080000007C00C000008DD71__00000099F1C9FC71-0000009A918DF181", +"000000067F000080000007C00C0000088000-000000067F000080000007C00C000008C000__0000009B40525F80", +"000000067F000080000007C00C0000088000-000000067F000080000007C00C000008C000__0000009C1E3799F0", +"000000067F000080000007C00C000008C000-000000067F000080000007C00C0000090000__0000009B40525F80", +"000000067F000080000007C00C000008C000-000000067F000080000007C00C0000090000__0000009C1E3799F0", +"000000067F000080000007C00C000008DD71-000000067F000080000007C00C00000974D7__00000099F1C9FC71-0000009A918DF181", +"000000067F000080000007C00C0000090000-000000067F000080000007C00C0000094000__0000009B40525F80", +"000000067F000080000007C00C0000090000-000000067F000080000007C00C0000094000__0000009C1E3799F0", +"000000067F000080000007C00C0000094000-000000067F000080000007C00C0000098000__0000009B40525F80", +"000000067F000080000007C00C0000094000-000000067F000080000007C00C0000098000__0000009C1E3799F0", +"000000067F000080000007C00C00000974D7-000000067F000080000007C00C00000A0C0B__00000099F1C9FC71-0000009A918DF181", +"000000067F000080000007C00C0000098000-000000067F000080000007C00C000009C000__0000009B40525F80", +"000000067F000080000007C00C0000098000-000000067F000080000007C00C000009C000__0000009C1E3799F0", +"000000067F000080000007C00C000009C000-000000067F000080000007C00C00000A0000__0000009B40525F80", +"000000067F000080000007C00C000009C000-000000067F000080000007C00C00000A0000__0000009C1E3799F0", +"000000067F000080000007C00C00000A0000-000000067F000080000007C00C00000A4000__0000009B40525F80", +"000000067F000080000007C00C00000A0000-000000067F000080000007C00C00000A4000__0000009C1E3799F0", +"000000067F000080000007C00C00000A0C0B-000000067F000080000007C00C0100000000__00000099F1C9FC71-0000009A918DF181", +"000000067F000080000007C00C00000A4000-000000067F000080000007C00C00000A8000__0000009B40525F80", +"000000067F000080000007C00C00000A4000-000000067F000080000007C00C00000A8000__0000009C1E3799F0", +"000000067F000080000007C00C00000A424C-000000067F000080000007C00C00000F5B43__0000009BCB4E4461-0000009C1E8CC879", +"000000067F000080000007C00C00000A8000-000000067F000080000007C00C00000AC000__0000009B40525F80", +"000000067F000080000007C00C00000A8000-000000067F000080000007C00C00000AC000__0000009C1E3799F0", +"000000067F000080000007C00C00000A9244-000000067F000080000007C00C00000B2991__0000009A918DF181-0000009B51A8BBB9", +"000000067F000080000007C00C00000AC000-000000067F000080000007C00C00000B0000__0000009B40525F80", +"000000067F000080000007C00C00000AC000-000000067F000080000007C00C00000B0000__0000009C1E3799F0", +"000000067F000080000007C00C00000B0000-000000067F000080000007C00C00000B4000__0000009B40525F80", +"000000067F000080000007C00C00000B0000-000000067F000080000007C00C00000B4000__0000009C1E3799F0", +"000000067F000080000007C00C00000B2991-000000067F000080000007C00C00000BC0F7__0000009A918DF181-0000009B51A8BBB9", +"000000067F000080000007C00C00000B4000-000000067F000080000007C00C00000B8000__0000009B40525F80", +"000000067F000080000007C00C00000B4000-000000067F000080000007C00C00000B8000__0000009C1E3799F0", +"000000067F000080000007C00C00000B8000-000000067F000080000007C00C00000BC000__0000009B40525F80", +"000000067F000080000007C00C00000B8000-000000067F000080000007C00C00000BC000__0000009C1E3799F0", +"000000067F000080000007C00C00000BA258-000000067F000080000007C01400000011E2__0000009B51A8BBB9-0000009BCB4E4461", +"000000067F000080000007C00C00000BC000-000000067F000080000007C00C00000C0000__0000009B40525F80", +"000000067F000080000007C00C00000BC000-000000067F000080000007C00C00000C0000__0000009C1E3799F0", +"000000067F000080000007C00C00000BC0F7-000000067F000080000007C00C00000C580C__0000009A918DF181-0000009B51A8BBB9", +"000000067F000080000007C00C00000C0000-000000067F000080000007C00C00000C4000__0000009B40525F80", +"000000067F000080000007C00C00000C0000-000000067F000080000007C00C00000C4000__0000009C1E3799F0", +"000000067F000080000007C00C00000C4000-000000067F000080000007C00C00000C8000__0000009B40525F80", +"000000067F000080000007C00C00000C4000-000000067F000080000007C00C00000C8000__0000009C1E3799F0", +"000000067F000080000007C00C00000C580C-000000067F000080000007C00C00000CEF72__0000009A918DF181-0000009B51A8BBB9", +"000000067F000080000007C00C00000C8000-000000067F000080000007C00C00000CC000__0000009B40525F80", +"000000067F000080000007C00C00000C8000-000000067F000080000007C00C00000CC000__0000009C1E3799F0", +"000000067F000080000007C00C00000CC000-000000067F000080000007C00C00000D0000__0000009B40525F80", +"000000067F000080000007C00C00000CC000-000000067F000080000007C00C00000D0000__0000009C1E3799F0", +"000000067F000080000007C00C00000CEF72-000000067F000080000007C00C00000D86D8__0000009A918DF181-0000009B51A8BBB9", +"000000067F000080000007C00C00000D0000-000000067F000080000007C00C00000D4000__0000009B40525F80", +"000000067F000080000007C00C00000D0000-000000067F000080000007C00C00000D4000__0000009C1E3799F0", +"000000067F000080000007C00C00000D4000-000000067F000080000007C00C00000D8000__0000009B40525F80", +"000000067F000080000007C00C00000D4000-000000067F000080000007C00C00000D8000__0000009C1E3799F0", +"000000067F000080000007C00C00000D8000-000000067F000080000007C00C00000DC000__0000009B40525F80", +"000000067F000080000007C00C00000D8000-000000067F000080000007C00C00000DC000__0000009C1E3799F0", +"000000067F000080000007C00C00000D86D8-000000067F000080000007C00C00000E1E0B__0000009A918DF181-0000009B51A8BBB9", +"000000067F000080000007C00C00000DC000-000000067F000080000007C00C00000E0000__0000009B40525F80", +"000000067F000080000007C00C00000DC000-000000067F000080000007C00C00000E0000__0000009C1E3799F0", +"000000067F000080000007C00C00000E0000-000000067F000080000007C00C00000E4000__0000009B40525F80", +"000000067F000080000007C00C00000E0000-000000067F000080000007C00C00000E4000__0000009C1E3799F0", +"000000067F000080000007C00C00000E1E0B-000000067F000080000007C00C00000EB571__0000009A918DF181-0000009B51A8BBB9", +"000000067F000080000007C00C00000E4000-000000067F000080000007C00C00000E8000__0000009B40525F80", +"000000067F000080000007C00C00000E4000-000000067F000080000007C00C00000E8000__0000009C1E3799F0", +"000000067F000080000007C00C00000E8000-000000067F000080000007C00C00000EC000__0000009B40525F80", +"000000067F000080000007C00C00000E8000-000000067F000080000007C00C00000EC000__0000009C1E3799F0", +"000000067F000080000007C00C00000EB571-000000067F000080000007C00C00000F4CD7__0000009A918DF181-0000009B51A8BBB9", +"000000067F000080000007C00C00000EC000-000000067F000080000007C00C00000F0000__0000009B40525F80", +"000000067F000080000007C00C00000EC000-000000067F000080000007C00C00000F0000__0000009C1E3799F0", +"000000067F000080000007C00C00000F0000-000000067F000080000007C00C00000F4000__0000009B40525F80", +"000000067F000080000007C00C00000F0000-000000067F000080000007C00C00000F4000__0000009C1E3799F0", +"000000067F000080000007C00C00000F4000-000000067F000080000007C00C00000F8000__0000009B40525F80", +"000000067F000080000007C00C00000F4000-000000067F000080000007C00C00000F8000__0000009C1E3799F0", +"000000067F000080000007C00C00000F4CD7-000000067F000080000007C00C00000FE40B__0000009A918DF181-0000009B51A8BBB9", +"000000067F000080000007C00C00000F5B56-000000067F000080000007C014000000EB5A__0000009BCB4E4461-0000009C1E8CC879", +"000000067F000080000007C00C00000F8000-000000067F000080000007C00C00000FC000__0000009B40525F80", +"000000067F000080000007C00C00000F8000-000000067F000080000007C00C00000FC000__0000009C1E3799F0", +"000000067F000080000007C00C00000FC000-000000067F000080000007C00C0000100000__0000009B40525F80", +"000000067F000080000007C00C00000FC000-000000067F000080000007C00C0000100000__0000009C1E3799F0", +"000000067F000080000007C00C00000FE40B-000000067F000080000007C00C0000107B27__0000009A918DF181-0000009B51A8BBB9", +"000000067F000080000007C00C0000100000-000000067F000080000007C00C0000104000__0000009B40525F80", +"000000067F000080000007C00C0000100000-000000067F000080000007C00C0000104000__0000009C1E3799F0", +"000000067F000080000007C00C0000104000-000000067F000080000007C00C0000108000__0000009B40525F80", +"000000067F000080000007C00C0000104000-000000067F000080000007C00C0000108000__0000009C1E3799F0", +"000000067F000080000007C00C0000107B27-000000067F000080000007C00C000011128D__0000009A918DF181-0000009B51A8BBB9", +"000000067F000080000007C00C0000108000-000000067F000080000007C00C000010C000__0000009C1E3799F0", +"000000067F000080000007C00C0000108000-030000000000000000000000000000000002__0000009B40525F80", +"000000067F000080000007C00C000010C000-000000067F000080000007C00C0000110000__0000009C1E3799F0", +"000000067F000080000007C00C0000110000-000000067F000080000007C0120100000000__0000009C1E3799F0", +"000000067F000080000007C00C000011128D-010000000000000001000000040000000012__0000009A918DF181-0000009B51A8BBB9", +"000000067F000080000007C0140000000000-000000067F000080000007C0140000004000__0000009C1E3799F0", +"000000067F000080000007C01400000011E2-000000067F000080000007C0140000007F04__0000009B51A8BBB9-0000009BCB4E4461", +"000000067F000080000007C0140000004000-000000067F000080000007C0140000008000__0000009C1E3799F0", +"000000067F000080000007C0140000007F04-000000067F000080000007C014000000EC12__0000009B51A8BBB9-0000009BCB4E4461", +"000000067F000080000007C0140000008000-000000067F000080000007C014000000C000__0000009C1E3799F0", +"000000067F000080000007C014000000C000-000000067F000080000007C0140000010000__0000009C1E3799F0", +"000000067F000080000007C014000000EB5A-000000067F000080000007C0140000027B5C__0000009BCB4E4461-0000009C1E8CC879", +"000000067F000080000007C014000000EC12-000000067F000080000007C0140000015910__0000009B51A8BBB9-0000009BCB4E4461", +"000000067F000080000007C0140000010000-000000067F000080000007C0140000014000__0000009C1E3799F0", +"000000067F000080000007C0140000014000-000000067F000080000007C0140000018000__0000009C1E3799F0", +"000000067F000080000007C0140000015910-000000067F000080000007C014000001C5BB__0000009B51A8BBB9-0000009BCB4E4461", +"000000067F000080000007C0140000018000-000000067F000080000007C014000001C000__0000009C1E3799F0", +"000000067F000080000007C014000001C000-000000067F000080000007C0140000020000__0000009C1E3799F0", +"000000067F000080000007C014000001C5BB-000000067F000080000007C0140000023298__0000009B51A8BBB9-0000009BCB4E4461", +"000000067F000080000007C0140000020000-000000067F000080000007C0140000024000__0000009C1E3799F0", +"000000067F000080000007C0140000023298-000000067F000080000007C0140000029F9A__0000009B51A8BBB9-0000009BCB4E4461", +"000000067F000080000007C0140000024000-000000067F000080000007C0140000028000__0000009C1E3799F0", +"000000067F000080000007C0140000027B5E-030000000000000000000000000000000002__0000009BCB4E4461-0000009C1E8CC879", +"000000067F000080000007C0140000028000-000000067F000080000007C014000002C000__0000009C1E3799F0", +"000000067F000080000007C0140000029F9A-030000000000000000000000000000000002__0000009B51A8BBB9-0000009BCB4E4461", +"000000067F000080000007C014000002C000-030000000000000000000000000000000002__0000009C1E3799F0", +"000000067F000080000007E00C0000000000-000000067F000080000007E00C0000004000__0000009DEF760000", +"000000067F000080000007E00C0000004000-000000067F000080000007E00C0000008000__0000009DEF760000", +"000000067F000080000007E00C0000008000-000000067F000080000007E00C000000C000__0000009DEF760000", +"000000067F000080000007E00C00000092CD-000000067F000080000007E00C0000012A0A__0000009C1E8CC879-0000009C9ED3F059", +"000000067F000080000007E00C000000C000-000000067F000080000007E00C0000010000__0000009DEF760000", +"000000067F000080000007E00C0000010000-000000067F000080000007E00C0000014000__0000009DEF760000", +"000000067F000080000007E00C0000012A0A-000000067F000080000007E00C000001C170__0000009C1E8CC879-0000009C9ED3F059", +"000000067F000080000007E00C0000014000-000000067F000080000007E00C0000018000__0000009DEF760000", +"000000067F000080000007E00C0000018000-000000067F000080000007E00C000001C000__0000009DEF760000", +"000000067F000080000007E00C000001C000-000000067F000080000007E00C0000020000__0000009DEF760000", +"000000067F000080000007E00C000001C170-000000067F000080000007E00C00000258D6__0000009C1E8CC879-0000009C9ED3F059", +"000000067F000080000007E00C0000020000-000000067F000080000007E00C0000024000__0000009DEF760000", +"000000067F000080000007E00C0000024000-000000067F000080000007E00C0000028000__0000009DEF760000", +"000000067F000080000007E00C00000258D6-000000067F000080000007E00C000002F00B__0000009C1E8CC879-0000009C9ED3F059", +"000000067F000080000007E00C0000028000-000000067F000080000007E00C000002C000__0000009DEF760000", +"000000067F000080000007E00C000002C000-000000067F000080000007E00C0000030000__0000009DEF760000", +"000000067F000080000007E00C000002F00B-000000067F000080000007E00C0000038720__0000009C1E8CC879-0000009C9ED3F059", +"000000067F000080000007E00C0000030000-000000067F000080000007E00C0000034000__0000009DEF760000", +"000000067F000080000007E00C0000034000-000000067F000080000007E00C0000038000__0000009DEF760000", +"000000067F000080000007E00C0000038000-000000067F000080000007E00C000003C000__0000009DEF760000", +"000000067F000080000007E00C0000038720-000000067F000080000007E00C0000041E86__0000009C1E8CC879-0000009C9ED3F059", +"000000067F000080000007E00C000003C000-000000067F000080000007E00C0000040000__0000009DEF760000", +"000000067F000080000007E00C0000040000-000000067F000080000007E00C0000044000__0000009DEF760000", +"000000067F000080000007E00C0000041E86-000000067F000080000007E00C000004B5EC__0000009C1E8CC879-0000009C9ED3F059", +"000000067F000080000007E00C0000044000-000000067F000080000007E00C0000048000__0000009DEF760000", +"000000067F000080000007E00C0000048000-000000067F000080000007E00C000004C000__0000009DDBE10620", +"000000067F000080000007E00C0000048000-000000067F000080000007E00C000004C000__0000009EBB11FFC0", +"000000067F000080000007E00C000004B5EC-030000000000000000000000000000000002__0000009C1E8CC879-0000009C9ED3F059", +"000000067F000080000007E00C000004BACA-000000067F000080000007E00C00000551FF__0000009C9ED3F059-0000009D3E97E549", +"000000067F000080000007E00C000004C000-000000067F000080000007E00C0000050000__0000009DDBE10620", +"000000067F000080000007E00C000004C000-000000067F000080000007E00C0000050000__0000009EBB11FFC0", +"000000067F000080000007E00C0000050000-000000067F000080000007E00C0000054000__0000009DDBE10620", +"000000067F000080000007E00C0000050000-000000067F000080000007E00C0000054000__0000009EBB11FFC0", +"000000067F000080000007E00C0000054000-000000067F000080000007E00C0000058000__0000009DDBE10620", +"000000067F000080000007E00C0000054000-000000067F000080000007E00C0000058000__0000009EBB11FFC0", +"000000067F000080000007E00C00000551FF-000000067F000080000007E00C000005E90C__0000009C9ED3F059-0000009D3E97E549", +"000000067F000080000007E00C0000058000-000000067F000080000007E00C000005C000__0000009DDBE10620", +"000000067F000080000007E00C0000058000-000000067F000080000007E00C000005C000__0000009EBB11FFC0", +"000000067F000080000007E00C000005C000-000000067F000080000007E00C0000060000__0000009DDBE10620", +"000000067F000080000007E00C000005C000-000000067F000080000007E00C0000060000__0000009EBB11FFC0", +"000000067F000080000007E00C000005E90C-000000067F000080000007E00C000006802C__0000009C9ED3F059-0000009D3E97E549", +"000000067F000080000007E00C0000060000-000000067F000080000007E00C0000064000__0000009DDBE10620", +"000000067F000080000007E00C0000060000-000000067F000080000007E00C0000064000__0000009EBB11FFC0", +"000000067F000080000007E00C0000061AE1-000000067F000080000007E00C00000C2A6C__0000009E781A9731-0000009EBBC72771", +"000000067F000080000007E00C0000064000-000000067F000080000007E00C0000068000__0000009DDBE10620", +"000000067F000080000007E00C0000064000-000000067F000080000007E00C0000068000__0000009EBB11FFC0", +"000000067F000080000007E00C0000068000-000000067F000080000007E00C000006C000__0000009DDBE10620", +"000000067F000080000007E00C0000068000-000000067F000080000007E00C000006C000__0000009EBB11FFC0", +"000000067F000080000007E00C000006802C-000000067F000080000007E00C0000071783__0000009C9ED3F059-0000009D3E97E549", +"000000067F000080000007E00C000006C000-000000067F000080000007E00C0000070000__0000009DDBE10620", +"000000067F000080000007E00C000006C000-000000067F000080000007E00C0000070000__0000009EBB11FFC0", +"000000067F000080000007E00C0000070000-000000067F000080000007E00C0000074000__0000009DDBE10620", +"000000067F000080000007E00C0000070000-000000067F000080000007E00C0000074000__0000009EBB11FFC0", +"000000067F000080000007E00C0000071783-000000067F000080000007E00C000007AEE9__0000009C9ED3F059-0000009D3E97E549", +"000000067F000080000007E00C0000074000-000000067F000080000007E00C0000078000__0000009DDBE10620", +"000000067F000080000007E00C0000074000-000000067F000080000007E00C0000078000__0000009EBB11FFC0", +"000000067F000080000007E00C0000078000-000000067F000080000007E00C000007C000__0000009DDBE10620", +"000000067F000080000007E00C0000078000-000000067F000080000007E00C000007C000__0000009EBB11FFC0", +"000000067F000080000007E00C000007AEE9-000000067F000080000007E00C000008460B__0000009C9ED3F059-0000009D3E97E549", +"000000067F000080000007E00C000007C000-000000067F000080000007E00C0000080000__0000009DDBE10620", +"000000067F000080000007E00C000007C000-000000067F000080000007E00C0000080000__0000009EBB11FFC0", +"000000067F000080000007E00C0000080000-000000067F000080000007E00C0000084000__0000009DDBE10620", +"000000067F000080000007E00C0000080000-000000067F000080000007E00C0000084000__0000009EBB11FFC0", +"000000067F000080000007E00C0000084000-000000067F000080000007E00C0000088000__0000009DDBE10620", +"000000067F000080000007E00C0000084000-000000067F000080000007E00C0000088000__0000009EBB11FFC0", +"000000067F000080000007E00C000008460B-000000067F000080000007E00C000008DD71__0000009C9ED3F059-0000009D3E97E549", +"000000067F000080000007E00C0000088000-000000067F000080000007E00C000008C000__0000009DDBE10620", +"000000067F000080000007E00C0000088000-000000067F000080000007E00C000008C000__0000009EBB11FFC0", +"000000067F000080000007E00C000008C000-000000067F000080000007E00C0000090000__0000009DDBE10620", +"000000067F000080000007E00C000008C000-000000067F000080000007E00C0000090000__0000009EBB11FFC0", +"000000067F000080000007E00C000008DD71-000000067F000080000007E00C00000974D7__0000009C9ED3F059-0000009D3E97E549", +"000000067F000080000007E00C0000090000-000000067F000080000007E00C0000094000__0000009DDBE10620", +"000000067F000080000007E00C0000090000-000000067F000080000007E00C0000094000__0000009EBB11FFC0", +"000000067F000080000007E00C0000093E3A-000000067F000080000007E00C0000111CED__0000009DEEE6BFF9-0000009E781A9731", +"000000067F000080000007E00C0000094000-000000067F000080000007E00C0000098000__0000009DDBE10620", +"000000067F000080000007E00C0000094000-000000067F000080000007E00C0000098000__0000009EBB11FFC0", +"000000067F000080000007E00C00000974D7-000000067F000080000007E00C00000A0C0B__0000009C9ED3F059-0000009D3E97E549", +"000000067F000080000007E00C0000098000-000000067F000080000007E00C000009C000__0000009DDBE10620", +"000000067F000080000007E00C0000098000-000000067F000080000007E00C000009C000__0000009EBB11FFC0", +"000000067F000080000007E00C000009C000-000000067F000080000007E00C00000A0000__0000009DDBE10620", +"000000067F000080000007E00C000009C000-000000067F000080000007E00C00000A0000__0000009EBB11FFC0", +"000000067F000080000007E00C00000A0000-000000067F000080000007E00C00000A4000__0000009DDBE10620", +"000000067F000080000007E00C00000A0000-000000067F000080000007E00C00000A4000__0000009EBB11FFC0", +"000000067F000080000007E00C00000A0C0B-000000067F000080000007E00C00000AA371__0000009C9ED3F059-0000009D3E97E549", +"000000067F000080000007E00C00000A4000-000000067F000080000007E00C00000A8000__0000009DDBE10620", +"000000067F000080000007E00C00000A4000-000000067F000080000007E00C00000A8000__0000009EBB11FFC0", +"000000067F000080000007E00C00000A8000-000000067F000080000007E00C00000AC000__0000009DDBE10620", +"000000067F000080000007E00C00000A8000-000000067F000080000007E00C00000AC000__0000009EBB11FFC0", +"000000067F000080000007E00C00000AA371-000000067F000080000007E00C0100000000__0000009C9ED3F059-0000009D3E97E549", +"000000067F000080000007E00C00000AC000-000000067F000080000007E00C00000B0000__0000009DDBE10620", +"000000067F000080000007E00C00000AC000-000000067F000080000007E00C00000B0000__0000009EBB11FFC0", +"000000067F000080000007E00C00000B0000-000000067F000080000007E00C00000B4000__0000009DDBE10620", +"000000067F000080000007E00C00000B0000-000000067F000080000007E00C00000B4000__0000009EBB11FFC0", +"000000067F000080000007E00C00000B2704-000000067F000080000007E00C00000BBE0F__0000009D3E97E549-0000009DEEE6BFF9", +"000000067F000080000007E00C00000B4000-000000067F000080000007E00C00000B8000__0000009DDBE10620", +"000000067F000080000007E00C00000B4000-000000067F000080000007E00C00000B8000__0000009EBB11FFC0", +"000000067F000080000007E00C00000B8000-000000067F000080000007E00C00000BC000__0000009DDBE10620", +"000000067F000080000007E00C00000B8000-000000067F000080000007E00C00000BC000__0000009EBB11FFC0", +"000000067F000080000007E00C00000BBE0F-000000067F000080000007E00C00000C5542__0000009D3E97E549-0000009DEEE6BFF9", +"000000067F000080000007E00C00000BC000-000000067F000080000007E00C00000C0000__0000009DDBE10620", +"000000067F000080000007E00C00000BC000-000000067F000080000007E00C00000C0000__0000009EBB11FFC0", +"000000067F000080000007E00C00000C0000-000000067F000080000007E00C00000C4000__0000009DDBE10620", +"000000067F000080000007E00C00000C0000-000000067F000080000007E00C00000C4000__0000009EBB11FFC0", +"000000067F000080000007E00C00000C2A75-000000067F000080000007E0140000004415__0000009E781A9731-0000009EBBC72771", +"000000067F000080000007E00C00000C4000-000000067F000080000007E00C00000C8000__0000009DDBE10620", +"000000067F000080000007E00C00000C4000-000000067F000080000007E00C00000C8000__0000009EBB11FFC0", +"000000067F000080000007E00C00000C5542-000000067F000080000007E00C00000CECA8__0000009D3E97E549-0000009DEEE6BFF9", +"000000067F000080000007E00C00000C8000-000000067F000080000007E00C00000CC000__0000009DDBE10620", +"000000067F000080000007E00C00000C8000-000000067F000080000007E00C00000CC000__0000009EBB11FFC0", +"000000067F000080000007E00C00000CC000-000000067F000080000007E00C00000D0000__0000009DDBE10620", +"000000067F000080000007E00C00000CC000-000000067F000080000007E00C00000D0000__0000009EBB11FFC0", +"000000067F000080000007E00C00000CECA8-000000067F000080000007E00C00000D83BF__0000009D3E97E549-0000009DEEE6BFF9", +"000000067F000080000007E00C00000D0000-000000067F000080000007E00C00000D4000__0000009DDBE10620", +"000000067F000080000007E00C00000D0000-000000067F000080000007E00C00000D4000__0000009EBB11FFC0", +"000000067F000080000007E00C00000D4000-000000067F000080000007E00C00000D8000__0000009DDBE10620", +"000000067F000080000007E00C00000D4000-000000067F000080000007E00C00000D8000__0000009EBB11FFC0", +"000000067F000080000007E00C00000D8000-000000067F000080000007E00C00000DC000__0000009DDBE10620", +"000000067F000080000007E00C00000D8000-000000067F000080000007E00C00000DC000__0000009EBB11FFC0", +"000000067F000080000007E00C00000D83BF-000000067F000080000007E00C00000E1B0A__0000009D3E97E549-0000009DEEE6BFF9", +"000000067F000080000007E00C00000DC000-000000067F000080000007E00C00000E0000__0000009DDBE10620", +"000000067F000080000007E00C00000DC000-000000067F000080000007E00C00000E0000__0000009EBB11FFC0", +"000000067F000080000007E00C00000E0000-000000067F000080000007E00C00000E4000__0000009DDBE10620", +"000000067F000080000007E00C00000E0000-000000067F000080000007E00C00000E4000__0000009EBB11FFC0", +"000000067F000080000007E00C00000E1B0A-000000067F000080000007E00C00000EB270__0000009D3E97E549-0000009DEEE6BFF9", +"000000067F000080000007E00C00000E4000-000000067F000080000007E00C00000E8000__0000009DDBE10620", +"000000067F000080000007E00C00000E4000-000000067F000080000007E00C00000E8000__0000009EBB11FFC0", +"000000067F000080000007E00C00000E8000-000000067F000080000007E00C00000EC000__0000009DDBE10620", +"000000067F000080000007E00C00000E8000-000000067F000080000007E00C00000EC000__0000009EBB11FFC0", +"000000067F000080000007E00C00000EB270-000000067F000080000007E00C00000F49AA__0000009D3E97E549-0000009DEEE6BFF9", +"000000067F000080000007E00C00000EC000-000000067F000080000007E00C00000F0000__0000009DDBE10620", +"000000067F000080000007E00C00000EC000-000000067F000080000007E00C00000F0000__0000009EBB11FFC0", +"000000067F000080000007E00C00000F0000-000000067F000080000007E00C00000F4000__0000009DDBE10620", +"000000067F000080000007E00C00000F0000-000000067F000080000007E00C00000F4000__0000009EBB11FFC0", +"000000067F000080000007E00C00000F4000-000000067F000080000007E00C00000F8000__0000009DDBE10620", +"000000067F000080000007E00C00000F4000-000000067F000080000007E00C00000F8000__0000009EBB11FFC0", +"000000067F000080000007E00C00000F49AA-000000067F000080000007E00C00000FE10A__0000009D3E97E549-0000009DEEE6BFF9", +"000000067F000080000007E00C00000F8000-000000067F000080000007E00C00000FC000__0000009DDBE10620", +"000000067F000080000007E00C00000F8000-000000067F000080000007E00C00000FC000__0000009EBB11FFC0", +"000000067F000080000007E00C00000FC000-000000067F000080000007E00C0000100000__0000009DDBE10620", +"000000067F000080000007E00C00000FC000-000000067F000080000007E00C0000100000__0000009EBB11FFC0", +"000000067F000080000007E00C00000FE10A-000000067F000080000007E00C000010782C__0000009D3E97E549-0000009DEEE6BFF9", +"000000067F000080000007E00C0000100000-000000067F000080000007E00C0000104000__0000009DDBE10620", +"000000067F000080000007E00C0000100000-000000067F000080000007E00C0000104000__0000009EBB11FFC0", +"000000067F000080000007E00C0000104000-000000067F000080000007E00C0000108000__0000009EBB11FFC0", +"000000067F000080000007E00C0000104000-030000000000000000000000000000000002__0000009DDBE10620", +"000000067F000080000007E00C000010782C-000000067F000080000007E00C0000110F88__0000009D3E97E549-0000009DEEE6BFF9", +"000000067F000080000007E00C0000108000-000000067F000080000007E00C000010C000__0000009EBB11FFC0", +"000000067F000080000007E00C000010C000-000000067F000080000007E00C0000110000__0000009EBB11FFC0", +"000000067F000080000007E00C0000110000-000000067F000080000007E0120100000000__0000009EBB11FFC0", +"000000067F000080000007E00C0000110F88-010000000000000001000000040000000015__0000009D3E97E549-0000009DEEE6BFF9", +"000000067F000080000007E00C0000111CED-000000067F000080000007E0140000004818__0000009DEEE6BFF9-0000009E781A9731", +"000000067F000080000007E0140000000000-000000067F000080000007E0140000004000__0000009EBB11FFC0", +"000000067F000080000007E0140000004000-000000067F000080000007E0140000008000__0000009EBB11FFC0", +"000000067F000080000007E0140000004418-000000067F000080000007E0140000025351__0000009E781A9731-0000009EBBC72771", +"000000067F000080000007E0140000004818-000000067F000080000007E014000000AD57__0000009DEEE6BFF9-0000009E781A9731", +"000000067F000080000007E0140000008000-000000067F000080000007E014000000C000__0000009EBB11FFC0", +"000000067F000080000007E014000000AD57-000000067F000080000007E0140000011291__0000009DEEE6BFF9-0000009E781A9731", +"000000067F000080000007E014000000C000-000000067F000080000007E0140000010000__0000009EBB11FFC0", +"000000067F000080000007E0140000010000-000000067F000080000007E0140000014000__0000009EBB11FFC0", +"000000067F000080000007E0140000011291-000000067F000080000007E0140000017809__0000009DEEE6BFF9-0000009E781A9731", +"000000067F000080000007E0140000014000-000000067F000080000007E0140000018000__0000009EBB11FFC0", +"000000067F000080000007E0140000017809-000000067F000080000007E014000001DD22__0000009DEEE6BFF9-0000009E781A9731", +"000000067F000080000007E0140000018000-000000067F000080000007E014000001C000__0000009EBB11FFC0", +"000000067F000080000007E014000001C000-000000067F000080000007E0140000020000__0000009EBB11FFC0", +"000000067F000080000007E014000001DD22-000000067F000080000007E0140000024244__0000009DEEE6BFF9-0000009E781A9731", +"000000067F000080000007E0140000020000-000000067F000080000007E0140000024000__0000009EBB11FFC0", +"000000067F000080000007E0140000024000-000000067F000080000007E0140000028000__0000009EBB11FFC0", +"000000067F000080000007E0140000024244-000000067F000080000007E014000002A798__0000009DEEE6BFF9-0000009E781A9731", +"000000067F000080000007E0140000025355-030000000000000000000000000000000002__0000009E781A9731-0000009EBBC72771", +"000000067F000080000007E0140000028000-000000067F000080000007E014000002C000__0000009EBB11FFC0", +"000000067F000080000007E014000002A798-030000000000000000000000000000000002__0000009DEEE6BFF9-0000009E781A9731", +"000000067F000080000007E014000002C000-030000000000000000000000000000000002__0000009EBB11FFC0", +"000000067F000080000008000C00000081F6-000000067F000080000008000C0000010448__0000009EBBC72771-000000A154401909", +"000000067F000080000008000C0000010448-000000067F000080000008000C000001870A__0000009EBBC72771-000000A154401909", +"000000067F000080000008000C000001870A-000000067F000080000008000C0000020905__0000009EBBC72771-000000A154401909", +"000000067F000080000008000C0000020905-000000067F000080000008000C0000028AF3__0000009EBBC72771-000000A154401909", +"000000067F000080000008000C0000028AF3-000000067F000080000008000C0000030CEA__0000009EBBC72771-000000A154401909", +"000000067F000080000008000C0000030CEA-000000067F000080000008000C0000038EB6__0000009EBBC72771-000000A154401909", +"000000067F000080000008000C0000038EB6-000000067F000080000008000C00000410B5__0000009EBBC72771-000000A154401909", +"000000067F000080000008000C00000410B5-000000067F000080000008000C00000492CB__0000009EBBC72771-000000A154401909", +"000000067F000080000008000C00000492CB-000000067F000080000008000C00000514F8__0000009EBBC72771-000000A154401909", +"000000067F000080000008000C00000514F8-000000067F000080000008000C000005977B__0000009EBBC72771-000000A154401909", +"000000067F000080000008000C000005977B-000000067F000080000008000C00000619C6__0000009EBBC72771-000000A154401909", +"000000067F000080000008000C00000619C6-000000067F000080000008000C0000069B6B__0000009EBBC72771-000000A154401909", +"000000067F000080000008000C0000069B6B-000000067F000080000008000C0000071DBE__0000009EBBC72771-000000A154401909", +"000000067F000080000008000C0000071DBE-000000067F000080000008000C0000079F8E__0000009EBBC72771-000000A154401909", +"000000067F000080000008000C0000079F8E-000000067F000080000008000C00000821D7__0000009EBBC72771-000000A154401909", +"000000067F000080000008000C00000821D7-000000067F000080000008000C000008A3AB__0000009EBBC72771-000000A154401909", +"000000067F000080000008000C000008A3AB-000000067F000080000008000C0000092556__0000009EBBC72771-000000A154401909", +"000000067F000080000008000C0000092556-000000067F000080000008000C000009A744__0000009EBBC72771-000000A154401909", +"000000067F000080000008000C000009A744-000000067F000080000008000C00000A29B0__0000009EBBC72771-000000A154401909", +"000000067F000080000008000C00000A29B0-000000067F000080000008000C00000AAC4B__0000009EBBC72771-000000A154401909", +"000000067F000080000008000C00000AAC4B-000000067F000080000008000C00000B2E21__0000009EBBC72771-000000A154401909", +"000000067F000080000008000C00000B2E21-000000067F000080000008000C00000BB0DB__0000009EBBC72771-000000A154401909", +"000000067F000080000008000C00000BB0DB-000000067F000080000008000C00000C331B__0000009EBBC72771-000000A154401909", +"000000067F000080000008000C00000C331B-000000067F000080000008000C00000CB4D2__0000009EBBC72771-000000A154401909", +"000000067F000080000008000C00000CB4D2-000000067F000080000008000C00000D3754__0000009EBBC72771-000000A154401909", +"000000067F000080000008000C00000D3754-000000067F000080000008000C00000DB9C6__0000009EBBC72771-000000A154401909", +"000000067F000080000008000C00000DB9C6-000000067F000080000008000C00000E3BC1__0000009EBBC72771-000000A154401909", +"000000067F000080000008000C00000E3BC1-000000067F000080000008000C00000EBE00__0000009EBBC72771-000000A154401909", +"000000067F000080000008000C00000EBE00-000000067F000080000008000C00000F3F63__0000009EBBC72771-000000A154401909", +"000000067F000080000008000C00000F3F63-000000067F000080000008000C00000FC160__0000009EBBC72771-000000A154401909", +"000000067F000080000008000C00000FC160-000000067F000080000008000C0000104448__0000009EBBC72771-000000A154401909", +"000000067F000080000008000C0000104448-000000067F000080000008000C000010C675__0000009EBBC72771-000000A154401909", +"000000067F000080000008000C000010C675-000000067F000080000008000C020000000B__0000009EBBC72771-000000A154401909", +"000000067F000080000008000C020000000B-000000067F00008000000800140000003ED1__0000009EBBC72771-000000A154401909", +"000000067F00008000000800140000003ED1-000000067F00008000000800140000009486__0000009EBBC72771-000000A154401909", +"000000067F00008000000800140000009486-000000067F0000800000080014000000EA73__0000009EBBC72771-000000A154401909", +"000000067F0000800000080014000000EA73-000000067F0000800000080014000001404D__0000009EBBC72771-000000A154401909", +"000000067F0000800000080014000001404D-000000067F000080000008001400000195A4__0000009EBBC72771-000000A154401909", +"000000067F000080000008001400000195A4-000000067F0000800000080014000001EBB4__0000009EBBC72771-000000A154401909", +"000000067F0000800000080014000001EBB4-000000067F000080000008001400000241E2__0000009EBBC72771-000000A154401909", +"000000067F000080000008001400000241E2-000000067F00008000000800140000029762__0000009EBBC72771-000000A154401909", +"000000067F00008000000800140000029762-030000000000000000000000000000000002__0000009EBBC72771-000000A154401909", +"000000067F000080000008200C0000000000-000000067F000080000008200C0000004000__000000A29F1D8950", +"000000067F000080000008200C0000004000-000000067F000080000008200C0000008000__000000A29F1D8950", +"000000067F000080000008200C0000008000-000000067F000080000008200C000000C000__000000A29F1D8950", +"000000067F000080000008200C000000974D-000000067F000080000008200C0000012EB3__000000A154401909-000000A1E407F839", +"000000067F000080000008200C000000C000-000000067F000080000008200C0000010000__000000A29F1D8950", +"000000067F000080000008200C0000010000-000000067F000080000008200C0000014000__000000A29F1D8950", +"000000067F000080000008200C0000012EB3-000000067F000080000008200C000001C60A__000000A154401909-000000A1E407F839", +"000000067F000080000008200C0000014000-000000067F000080000008200C0000018000__000000A29F1D8950", +"000000067F000080000008200C0000018000-000000067F000080000008200C000001C000__000000A29F1D8950", +"000000067F000080000008200C000001C000-000000067F000080000008200C0000020000__000000A29F1D8950", +"000000067F000080000008200C000001C60A-000000067F000080000008200C0000025D38__000000A154401909-000000A1E407F839", +"000000067F000080000008200C0000020000-000000067F000080000008200C0000024000__000000A29F1D8950", +"000000067F000080000008200C0000024000-000000067F000080000008200C0000028000__000000A29F1D8950", +"000000067F000080000008200C0000025D38-000000067F000080000008200C000002F49E__000000A154401909-000000A1E407F839", +"000000067F000080000008200C0000028000-000000067F000080000008200C000002C000__000000A29F1D8950", +"000000067F000080000008200C000002C000-000000067F000080000008200C0000030000__000000A29F1D8950", +"000000067F000080000008200C000002F49E-000000067F000080000008200C0000038BB1__000000A154401909-000000A1E407F839", +"000000067F000080000008200C0000030000-000000067F000080000008200C0000034000__000000A29F1D8950", +"000000067F000080000008200C0000034000-000000067F000080000008200C0000038000__000000A29F1D8950", +"000000067F000080000008200C0000038000-000000067F000080000008200C000003C000__000000A29F1D8950", +"000000067F000080000008200C0000038BB1-000000067F000080000008200C0000042317__000000A154401909-000000A1E407F839", +"000000067F000080000008200C000003C000-000000067F000080000008200C0000040000__000000A29F1D8950", +"000000067F000080000008200C0000040000-000000067F000080000008200C0000044000__000000A29F1D8950", +"000000067F000080000008200C0000042317-000000067F000080000008200C000004BA7D__000000A154401909-000000A1E407F839", +"000000067F000080000008200C0000044000-000000067F000080000008200C0000048000__000000A29F1D8950", +"000000067F000080000008200C0000048000-000000067F000080000008200C000004C000__000000A29F1D8950", +"000000067F000080000008200C000004BA7D-000000067F000080000008200C00000551B2__000000A154401909-000000A1E407F839", +"000000067F000080000008200C000004C000-000000067F000080000008200C0000050000__000000A29F1D8950", +"000000067F000080000008200C0000050000-000000067F000080000008200C0000054000__000000A29F1D8950", +"000000067F000080000008200C0000054000-000000067F000080000008200C0000058000__000000A29F1D8950", +"000000067F000080000008200C00000551B2-030000000000000000000000000000000002__000000A154401909-000000A1E407F839", +"000000067F000080000008200C0000058000-000000067F000080000008200C000005C000__000000A29F1D8950", +"000000067F000080000008200C000005C000-000000067F000080000008200C0000060000__000000A29F1D8950", +"000000067F000080000008200C000005D8FE-000000067F000080000008200C000006700C__000000A1E407F839-000000A323C9E001", +"000000067F000080000008200C0000060000-000000067F000080000008200C0000064000__000000A29F1D8950", +"000000067F000080000008200C0000064000-000000067F000080000008200C0000068000__000000A29F1D8950", +"000000067F000080000008200C000006700C-000000067F000080000008200C000007076D__000000A1E407F839-000000A323C9E001", +"000000067F000080000008200C0000068000-000000067F000080000008200C000006C000__000000A29F1D8950", +"000000067F000080000008200C000006C000-000000067F000080000008200C0000070000__000000A29F1D8950", +"000000067F000080000008200C0000070000-000000067F000080000008200C0000074000__000000A29F1D8950", +"000000067F000080000008200C000007076D-000000067F000080000008200C0000079ED3__000000A1E407F839-000000A323C9E001", +"000000067F000080000008200C0000074000-000000067F000080000008200C0000078000__000000A29F1D8950", +"000000067F000080000008200C0000078000-000000067F000080000008200C000007C000__000000A29F1D8950", +"000000067F000080000008200C0000079ED3-000000067F000080000008200C000008360A__000000A1E407F839-000000A323C9E001", +"000000067F000080000008200C000007C000-000000067F000080000008200C0000080000__000000A29F1D8950", +"000000067F000080000008200C0000080000-000000067F000080000008200C0000084000__000000A29F1D8950", +"000000067F000080000008200C000008360A-000000067F000080000008200C000008CD70__000000A1E407F839-000000A323C9E001", +"000000067F000080000008200C0000084000-000000067F000080000008200C0000088000__000000A29F1D8950", +"000000067F000080000008200C0000088000-000000067F000080000008200C000008C000__000000A29F1D8950", +"000000067F000080000008200C000008C000-000000067F000080000008200C0000090000__000000A29F1D8950", +"000000067F000080000008200C000008CD70-000000067F000080000008200C00000964D6__000000A1E407F839-000000A323C9E001", +"000000067F000080000008200C0000090000-000000067F000080000008200C0000094000__000000A29F1D8950", +"000000067F000080000008200C0000094000-000000067F000080000008200C0000098000__000000A29F1D8950", +"000000067F000080000008200C00000964D6-000000067F000080000008200C000009FC0B__000000A1E407F839-000000A323C9E001", +"000000067F000080000008200C0000098000-000000067F000080000008200C000009C000__000000A29F1D8950", +"000000067F000080000008200C000009C000-000000067F000080000008200C00000A0000__000000A29F1D8950", +"000000067F000080000008200C000009FC0B-000000067F000080000008200C00000A9319__000000A1E407F839-000000A323C9E001", +"000000067F000080000008200C00000A0000-000000067F000080000008200C00000A4000__000000A29F1D8950", +"000000067F000080000008200C00000A4000-000000067F000080000008200C00000A8000__000000A29F1D8950", +"000000067F000080000008200C00000A8000-000000067F000080000008200C00000AC000__000000A29F1D8950", +"000000067F000080000008200C00000A9319-000000067F000080000008200C00000B2A7F__000000A1E407F839-000000A323C9E001", +"000000067F000080000008200C00000AC000-000000067F000080000008200C00000B0000__000000A29F1D8950", +"000000067F000080000008200C00000B0000-000000067F000080000008200C00000B4000__000000A29F1D8950", +"000000067F000080000008200C00000B2A7F-000000067F000080000008200C00000BC1E5__000000A1E407F839-000000A323C9E001", +"000000067F000080000008200C00000B4000-000000067F000080000008200C00000B8000__000000A29F1D8950", +"000000067F000080000008200C00000B8000-000000067F000080000008200C00000BC000__000000A29F1D8950", +"000000067F000080000008200C00000BC000-000000067F000080000008200C00000C0000__000000A29F1D8950", +"000000067F000080000008200C00000BC1E5-000000067F000080000008200C00000C590C__000000A1E407F839-000000A323C9E001", +"000000067F000080000008200C00000C0000-010000000000000000000000000000000001__000000A29F1D8950", +"000000067F000080000008200C00000C590C-000000067F000080000008200C00000CF071__000000A1E407F839-000000A323C9E001", +"000000067F000080000008200C00000CF071-000000067F000080000008200C00000D8786__000000A1E407F839-000000A323C9E001", +"000000067F000080000008200C00000D8786-000000067F000080000008200C00000E1EEC__000000A1E407F839-000000A323C9E001", +"000000067F000080000008200C00000E1EEC-000000067F000080000008200C00000EB60C__000000A1E407F839-000000A323C9E001", +"000000067F000080000008200C00000EB60C-000000067F000080000008200C00000F4D43__000000A1E407F839-000000A323C9E001", +"000000067F000080000008200C00000F4D43-000000067F000080000008200C00000FE4A9__000000A1E407F839-000000A323C9E001", +"000000067F000080000008200C00000FE4A9-000000067F000080000008200C0000107BC5__000000A1E407F839-000000A323C9E001", +"000000067F000080000008200C0000107BC5-000000067F000080000008200C000011130B__000000A1E407F839-000000A323C9E001", +"000000067F000080000008200C000011130B-01000000000000000100000004000000001C__000000A1E407F839-000000A323C9E001", +"000000067F0000800000082014000000393C-000000067F0000800000082014000000B84D__000000A323C9E001-000000A37A60B1A9", +"000000067F0000800000082014000000B84D-000000067F0000800000082014000001375E__000000A323C9E001-000000A37A60B1A9", +"000000067F0000800000082014000001375E-000000067F0000800000082014000001B66D__000000A323C9E001-000000A37A60B1A9", +"000000067F0000800000082014000001B66D-000000067F0000800000082014000002357E__000000A323C9E001-000000A37A60B1A9", +"000000067F0000800000082014000002357E-000000067F0000800000082014000002B48D__000000A323C9E001-000000A37A60B1A9", +"000000067F0000800000082014000002B48D-030000000000000000000000000000000002__000000A323C9E001-000000A37A60B1A9", +"000000067F000080000008600C0000000000-000000067F000080000008600C0000004000__000000A434813A68", +"000000067F000080000008600C0000004000-000000067F000080000008600C0000008000__000000A434813A68", +"000000067F000080000008600C0000008000-000000067F000080000008600C000000C000__000000A434813A68", +"000000067F000080000008600C0000009747-000000067F000080000008600C0000012EAD__000000A37A60B1A9-000000A3CA47ECA9", +"000000067F000080000008600C000000C000-000000067F000080000008600C0000010000__000000A434813A68", +"000000067F000080000008600C0000010000-000000067F000080000008600C0000014000__000000A434813A68", +"000000067F000080000008600C0000012EAD-000000067F000080000008600C000001C60A__000000A37A60B1A9-000000A3CA47ECA9", +"000000067F000080000008600C0000014000-000000067F000080000008600C0000018000__000000A434813A68", +"000000067F000080000008600C0000018000-000000067F000080000008600C000001C000__000000A434813A68", +"000000067F000080000008600C000001C000-000000067F000080000008600C0000020000__000000A434813A68", +"000000067F000080000008600C000001C60A-000000067F000080000008600C0000025D38__000000A37A60B1A9-000000A3CA47ECA9", +"000000067F000080000008600C0000020000-000000067F000080000008600C0000024000__000000A434813A68", +"000000067F000080000008600C0000024000-000000067F000080000008600C0000028000__000000A434813A68", +"000000067F000080000008600C0000025D38-000000067F000080000008600C000002F49E__000000A37A60B1A9-000000A3CA47ECA9", +"000000067F000080000008600C0000028000-000000067F000080000008600C000002C000__000000A434813A68", +"000000067F000080000008600C000002C000-000000067F000080000008600C0000030000__000000A434813A68", +"000000067F000080000008600C000002F49E-030000000000000000000000000000000002__000000A37A60B1A9-000000A3CA47ECA9", +"000000067F000080000008600C000002F4CA-000000067F000080000008600C0000038BDD__000000A3CA47ECA9-000000A539BDE561", +"000000067F000080000008600C0000030000-000000067F000080000008600C0000034000__000000A434813A68", +"000000067F000080000008600C0000034000-000000067F000080000008600C0000038000__000000A434813A68", +"000000067F000080000008600C0000038000-000000067F000080000008600C000003C000__000000A434813A68", +"000000067F000080000008600C0000038BDD-000000067F000080000008600C000004230B__000000A3CA47ECA9-000000A539BDE561", +"000000067F000080000008600C000003C000-000000067F000080000008600C0000040000__000000A434813A68", +"000000067F000080000008600C0000040000-000000067F000080000008600C0000044000__000000A434813A68", +"000000067F000080000008600C000004230B-000000067F000080000008600C000004BA71__000000A3CA47ECA9-000000A539BDE561", +"000000067F000080000008600C0000044000-000000067F000080000008600C0000048000__000000A434813A68", +"000000067F000080000008600C0000048000-000000067F000080000008600C000004C000__000000A434813A68", +"000000067F000080000008600C000004BA71-000000067F000080000008600C00000551A6__000000A3CA47ECA9-000000A539BDE561", +"000000067F000080000008600C000004C000-000000067F000080000008600C0000050000__000000A434813A68", +"000000067F000080000008600C0000050000-000000067F000080000008600C0000054000__000000A434813A68", +"000000067F000080000008600C0000054000-000000067F000080000008600C0000058000__000000A434813A68", +"000000067F000080000008600C00000551A6-000000067F000080000008600C000005E90A__000000A3CA47ECA9-000000A539BDE561", +"000000067F000080000008600C0000058000-000000067F000080000008600C000005C000__000000A434813A68", +"000000067F000080000008600C000005C000-000000067F000080000008600C0000060000__000000A434813A68", +"000000067F000080000008600C000005E90A-000000067F000080000008600C000006802C__000000A3CA47ECA9-000000A539BDE561", +"000000067F000080000008600C0000060000-000000067F000080000008600C0000064000__000000A434813A68", +"000000067F000080000008600C0000064000-000000067F000080000008600C0000068000__000000A434813A68", +"000000067F000080000008600C0000068000-000000067F000080000008600C000006C000__000000A434813A68", +"000000067F000080000008600C000006802C-000000067F000080000008600C0000071783__000000A3CA47ECA9-000000A539BDE561", +"000000067F000080000008600C000006C000-030000000000000000000000000000000002__000000A434813A68", +"000000067F000080000008600C0000071783-000000067F000080000008600C000007AEE9__000000A3CA47ECA9-000000A539BDE561", +"000000067F000080000008600C000007AEE9-000000067F000080000008600C000008460B__000000A3CA47ECA9-000000A539BDE561", +"000000067F000080000008600C000008460B-000000067F000080000008600C000008DD71__000000A3CA47ECA9-000000A539BDE561", +"000000067F000080000008600C000008DD71-000000067F000080000008600C00000974D7__000000A3CA47ECA9-000000A539BDE561", +"000000067F000080000008600C00000974D7-000000067F000080000008600C00000A0C0B__000000A3CA47ECA9-000000A539BDE561", +"000000067F000080000008600C00000A0C0B-000000067F000080000008600C00000AA371__000000A3CA47ECA9-000000A539BDE561", +"000000067F000080000008600C00000AA371-000000067F000080000008600C00000B3AD7__000000A3CA47ECA9-000000A539BDE561", +"000000067F000080000008600C00000B3AD7-000000067F000080000008600C00000BD20B__000000A3CA47ECA9-000000A539BDE561", +"000000067F000080000008600C00000BD20B-000000067F000080000008600C00000C6932__000000A3CA47ECA9-000000A539BDE561", +"000000067F000080000008600C00000C6932-000000067F000080000008600C00000D0098__000000A3CA47ECA9-000000A539BDE561", +"000000067F000080000008600C00000D0098-000000067F000080000008600C00000D97FE__000000A3CA47ECA9-000000A539BDE561", +"000000067F000080000008600C00000D97FE-000000067F000080000008600C00000E2F0B__000000A3CA47ECA9-000000A539BDE561", +"000000067F000080000008600C00000E2F0B-000000067F000080000008600C00000EC671__000000A3CA47ECA9-000000A539BDE561", +"000000067F000080000008600C00000EC671-000000067F000080000008600C00000F5D9F__000000A3CA47ECA9-000000A539BDE561", +"000000067F000080000008600C00000F5D9F-000000067F000080000008600C00000FF505__000000A3CA47ECA9-000000A539BDE561", +"000000067F000080000008600C00000FF505-000000067F000080000008600C0000108C10__000000A3CA47ECA9-000000A539BDE561", +"000000067F000080000008600C0000108C10-000000067F000080000008600C0100000000__000000A3CA47ECA9-000000A539BDE561", +"000000067F000080000008600C000010ECC4-000000067F00008000000860140000002607__000000A539BDE561-000000A5A081B661", +"000000067F00008000000860140000002607-000000067F0000800000086014000000A518__000000A539BDE561-000000A5A081B661", +"000000067F0000800000086014000000A518-000000067F00008000000860140000012429__000000A539BDE561-000000A5A081B661", +"000000067F00008000000860140000012429-000000067F0000800000086014000001A338__000000A539BDE561-000000A5A081B661", +"000000067F0000800000086014000001A338-000000067F00008000000860140000022249__000000A539BDE561-000000A5A081B661", +"000000067F00008000000860140000022249-000000067F0000800000086014000002A159__000000A539BDE561-000000A5A081B661", +"000000067F0000800000086014000002A159-030000000000000000000000000000000002__000000A539BDE561-000000A5A081B661", +"000000067F000080000008801C0000009703-000000067F000080000008801C0000012E0E__000000A5A081B661-000000A6503DE919", +"000000067F000080000008801C0000012E0E-000000067F000080000008801C000001C574__000000A5A081B661-000000A6503DE919", +"000000067F000080000008801C000001C574-000000067F000080000008801C0000025CDA__000000A5A081B661-000000A6503DE919", +"000000067F000080000008801C0000025CDA-000000067F000080000008801C000002F40A__000000A5A081B661-000000A6503DE919", +"000000067F000080000008801C000002F40A-000000067F000080000008801C0000038B1D__000000A5A081B661-000000A6503DE919", +"000000067F000080000008801C0000038B1D-000000067F000080000008801C0000042283__000000A5A081B661-000000A6503DE919", +"000000067F000080000008801C0000042283-000000067F000080000008801C000004B9E9__000000A5A081B661-000000A6503DE919", +"000000067F000080000008801C000004B9E9-000000067F000080000008801C000005510B__000000A5A081B661-000000A6503DE919", +"000000067F000080000008801C000005510B-000000067F000080000008801C000005E871__000000A5A081B661-000000A6503DE919", +"000000067F000080000008801C000005E871-000000067F000080000008801C0000067F8B__000000A5A081B661-000000A6503DE919", +"000000067F000080000008801C0000067F8B-030000000000000000000000000000000002__000000A5A081B661-000000A6503DE919", +"000000067F000080000008801C0000068000-000000067F000080000008801C000006C000__000000A76EC5DFE8", +"000000067F000080000008801C00000680F7-000000067F000080000008801C000007180C__000000A6503DE919-000000A6F001F909", +"000000067F000080000008801C000006C000-000000067F000080000008801C0000070000__000000A76EC5DFE8", +"000000067F000080000008801C0000070000-000000067F000080000008801C0000074000__000000A76EC5DFE8", +"000000067F000080000008801C000007180C-000000067F000080000008801C000007AF72__000000A6503DE919-000000A6F001F909", +"000000067F000080000008801C0000074000-000000067F000080000008801C0000078000__000000A76EC5DFE8", +"000000067F000080000008801C0000078000-000000067F000080000008801C000007C000__000000A76F097A80", +"000000067F000080000008801C000007AF72-000000067F000080000008801C00000846D8__000000A6503DE919-000000A6F001F909", +"000000067F000080000008801C000007C000-000000067F000080000008801C0000080000__000000A76F097A80", +"000000067F000080000008801C0000080000-000000067F000080000008801C0000084000__000000A76F097A80", +"000000067F000080000008801C0000084000-000000067F000080000008801C0000088000__000000A76F097A80", +"000000067F000080000008801C00000846D8-000000067F000080000008801C000008DE0B__000000A6503DE919-000000A6F001F909", +"000000067F000080000008801C0000088000-000000067F000080000008801C000008C000__000000A76F097A80", +"000000067F000080000008801C000008C000-000000067F000080000008801C0000090000__000000A76F097A80", +"000000067F000080000008801C000008DE0B-000000067F000080000008801C000009752B__000000A6503DE919-000000A6F001F909", +"000000067F000080000008801C0000090000-000000067F000080000008801C0000094000__000000A76F097A80", +"000000067F000080000008801C0000094000-000000067F000080000008801C0000098000__000000A76F097A80", +"000000067F000080000008801C000009752B-000000067F000080000008801C00000A0C91__000000A6503DE919-000000A6F001F909", +"000000067F000080000008801C0000098000-000000067F000080000008801C000009C000__000000A76F097A80", +"000000067F000080000008801C000009C000-000000067F000080000008801C00000A0000__000000A76F097A80", +"000000067F000080000008801C00000A0000-000000067F000080000008801C00000A4000__000000A76F097A80", +"000000067F000080000008801C00000A0C91-000000067F000080000008801C00000AA3F7__000000A6503DE919-000000A6F001F909", +"000000067F000080000008801C00000A4000-000000067F000080000008801C00000A8000__000000A76F097A80", +"000000067F000080000008801C00000A8000-000000067F000080000008801C00000AC000__000000A76F097A80", +"000000067F000080000008801C00000AA3F7-000000067F000080000008801C00000B3B0C__000000A6503DE919-000000A6F001F909", +"000000067F000080000008801C00000AC000-000000067F000080000008801C00000B0000__000000A76F097A80", +"000000067F000080000008801C00000B0000-000000067F000080000008801C00000B4000__000000A76F097A80", +"000000067F000080000008801C00000B3B0C-000000067F000080000008801C00000BD272__000000A6503DE919-000000A6F001F909", +"000000067F000080000008801C00000B4000-000000067F000080000008801C00000B8000__000000A76F097A80", +"000000067F000080000008801C00000B8000-000000067F000080000008801C00000BC000__000000A76F097A80", +"000000067F000080000008801C00000BC000-000000067F000080000008801C00000C0000__000000A76F097A80", +"000000067F000080000008801C00000BD272-000000067F000080000008801C00000C6999__000000A6503DE919-000000A6F001F909", +"000000067F000080000008801C00000C0000-000000067F000080000008801C00000C4000__000000A76F097A80", +"000000067F000080000008801C00000C4000-000000067F000080000008801C00000C8000__000000A76F097A80", +"000000067F000080000008801C00000C6999-000000067F000080000008801C0100000000__000000A6503DE919-000000A6F001F909", +"000000067F000080000008801C00000C8000-000000067F000080000008801C00000CC000__000000A76F097A80", +"000000067F000080000008801C00000CC000-000000067F000080000008801C00000D0000__000000A76F097A80", +"000000067F000080000008801C00000CF6B0-000000067F000080000008801C00000D8DC1__000000A6F001F909-000000A91D97FD49", +"000000067F000080000008801C00000D0000-000000067F000080000008801C00000D4000__000000A76F097A80", +"000000067F000080000008801C00000D4000-000000067F000080000008801C00000D8000__000000A76F097A80", +"000000067F000080000008801C00000D8000-000000067F000080000008801C00000DC000__000000A76F097A80", +"000000067F000080000008801C00000D8DC1-000000067F000080000008801C00000E250B__000000A6F001F909-000000A91D97FD49", +"000000067F000080000008801C00000DC000-000000067F000080000008801C00000E0000__000000A76F097A80", +"000000067F000080000008801C00000E0000-000000067F000080000008801C00000E4000__000000A76F097A80", +"000000067F000080000008801C00000E250B-000000067F000080000008801C00000EBC71__000000A6F001F909-000000A91D97FD49", +"000000067F000080000008801C00000E4000-000000067F000080000008801C00000E8000__000000A76F097A80", +"000000067F000080000008801C00000E8000-000000067F000080000008801C00000EC000__000000A76F097A80", +"000000067F000080000008801C00000EBC71-000000067F000080000008801C00000F53A5__000000A6F001F909-000000A91D97FD49", +"000000067F000080000008801C00000EC000-000000067F000080000008801C00000F0000__000000A76F097A80", +"000000067F000080000008801C00000F0000-000000067F000080000008801C00000F4000__000000A76F097A80", +"000000067F000080000008801C00000F4000-000000067F000080000008801C00000F8000__000000A76F097A80", +"000000067F000080000008801C00000F53A5-000000067F000080000008801C00000FEB0B__000000A6F001F909-000000A91D97FD49", +"000000067F000080000008801C00000F8000-000000067F000080000008801C00000FC000__000000A76F097A80", +"000000067F000080000008801C00000FC000-000000067F000080000008801C0000100000__000000A76F097A80", +"000000067F000080000008801C00000FEB0B-000000067F000080000008801C000010822C__000000A6F001F909-000000A91D97FD49", +"000000067F000080000008801C0000100000-000000067F000080000008801C0000104000__000000A76F097A80", +"000000067F000080000008801C0000104000-000000067F000080000008801C0000108000__000000A76F097A80", +"000000067F000080000008801C0000108000-000000067F000080000008801C000010C000__000000A76F097A80", +"000000067F000080000008801C000010822C-000000067F000080000008801C0000111982__000000A6F001F909-000000A91D97FD49", +"000000067F000080000008801C000010C000-000000067F000080000008801C0000110000__000000A76F097A80", +"000000067F000080000008801C0000110000-030000000000000000000000000000000002__000000A76F097A80", +"000000067F000080000008801C0000111982-000000067F000080000008A00C00000084EA__000000A6F001F909-000000A91D97FD49", +"000000067F000080000008A00C00000084EA-000000067F000080000008A00C0000011C0C__000000A6F001F909-000000A91D97FD49", +"000000067F000080000008A00C0000011C0C-000000067F000080000008A00C000001B372__000000A6F001F909-000000A91D97FD49", +"000000067F000080000008A00C000001B372-000000067F000080000008A00C0000024AD8__000000A6F001F909-000000A91D97FD49", +"000000067F000080000008A00C0000024AD8-000000067F000080000008A00C000002E20B__000000A6F001F909-000000A91D97FD49", +"000000067F000080000008A00C000002E20B-000000067F000080000008A00C0000037928__000000A6F001F909-000000A91D97FD49", +"000000067F000080000008A00C0000037928-000000067F000080000008A00C000004108E__000000A6F001F909-000000A91D97FD49", +"000000067F000080000008A00C000004108E-000000067F000080000008A00C000004A7F4__000000A6F001F909-000000A91D97FD49", +"000000067F000080000008A00C000004A7F4-000000067F000080000008A00C0000053F0B__000000A6F001F909-000000A91D97FD49", +"000000067F000080000008A00C0000053F0B-000000067F000080000008A00C000005D671__000000A6F001F909-000000A91D97FD49", +"000000067F000080000008A00C000005D671-000000067F000080000008A00C0000066D95__000000A6F001F909-000000A91D97FD49", +"000000067F000080000008A00C0000066D95-000000067F000080000008A00C00000704FB__000000A6F001F909-000000A91D97FD49", +"000000067F000080000008A00C00000704FB-000000067F000080000008A00C0000079C0B__000000A6F001F909-000000A91D97FD49", +"000000067F000080000008A00C0000079C0B-000000067F000080000008A00C0000083351__000000A6F001F909-000000A91D97FD49", +"000000067F000080000008A00C0000083351-000000067F000080000008A00C000008CAB7__000000A6F001F909-000000A91D97FD49", +"000000067F000080000008A00C000008CAB7-000000067F000080000008A00C00000961E2__000000A6F001F909-000000A91D97FD49", +"000000067F000080000008A00C00000961E2-000000067F000080000008A00C000009F90B__000000A6F001F909-000000A91D97FD49", +"000000067F000080000008A00C000009F90B-000000067F000080000008A00C00000A902B__000000A6F001F909-000000A91D97FD49", +"000000067F000080000008A00C00000A902B-000000067F000080000008A00C00000B2779__000000A6F001F909-000000A91D97FD49", +"000000067F000080000008A00C00000B2779-000000067F000080000008A00C00000BBEDF__000000A6F001F909-000000A91D97FD49", +"000000067F000080000008A00C00000BBEDF-000000067F000080000008A00C00000C560A__000000A6F001F909-000000A91D97FD49", +"000000067F000080000008A00C00000C560A-000000067F000080000008A00C00000CED70__000000A6F001F909-000000A91D97FD49", +"000000067F000080000008A00C00000CED70-000000067F000080000008A00C00000D84D6__000000A6F001F909-000000A91D97FD49", +"000000067F000080000008A00C00000D84D6-000000067F000080000008A00C00000E1C0A__000000A6F001F909-000000A91D97FD49", +"000000067F000080000008A00C00000E1C0A-000000067F000080000008A00C00000EB370__000000A6F001F909-000000A91D97FD49", +"000000067F000080000008A00C00000EB370-000000067F000080000008A00C00000F4AD6__000000A6F001F909-000000A91D97FD49", +"000000067F000080000008A00C00000F4AD6-000000067F000080000008A00C00000FE20B__000000A6F001F909-000000A91D97FD49", +"000000067F000080000008A00C00000FE20B-030000000000000000000000000000000002__000000A6F001F909-000000A91D97FD49", +"000000067F000080000008A00C0000104A0C-000000067F000080000008A00C000010DF6E__000000A91D97FD49-000000A98AB7EE49", +"000000067F000080000008A00C000010DF6E-000000067F000080000008A0140000001A21__000000A91D97FD49-000000A98AB7EE49", +"000000067F000080000008A0140000001A21-000000067F000080000008A0140000009932__000000A91D97FD49-000000A98AB7EE49", +"000000067F000080000008A0140000009932-000000067F000080000008A0140000011843__000000A91D97FD49-000000A98AB7EE49", +"000000067F000080000008A0140000011843-000000067F000080000008A0140000019753__000000A91D97FD49-000000A98AB7EE49", +"000000067F000080000008A0140000019753-000000067F000080000008A0140000021664__000000A91D97FD49-000000A98AB7EE49", +"000000067F000080000008A0140000021664-01000000000000000100000004000000001C__000000A91D97FD49-000000A98AB7EE49", +"000000067F000080000008C00C0000000000-000000067F000080000008C00C0000004000__000000AAEBE534F8", +"000000067F000080000008C00C0000002330-000000067F000080000008C00C000000BA96__000000A98AB7EE49-000000AA2597E9A1", +"000000067F000080000008C00C0000004000-000000067F000080000008C00C0000008000__000000AAEBE534F8", +"000000067F000080000008C00C0000008000-000000067F000080000008C00C000000C000__000000AAEBE534F8", +"000000067F000080000008C00C000000BA96-000000067F000080000008C00C00000151CB__000000A98AB7EE49-000000AA2597E9A1", +"000000067F000080000008C00C000000C000-000000067F000080000008C00C0000010000__000000AAEBE534F8", +"000000067F000080000008C00C0000010000-000000067F000080000008C00C0000014000__000000AAEBE534F8", +"000000067F000080000008C00C0000014000-000000067F000080000008C00C0000018000__000000AAEBE534F8", +"000000067F000080000008C00C00000151CB-000000067F000080000008C00C000001E90B__000000A98AB7EE49-000000AA2597E9A1", +"000000067F000080000008C00C0000018000-000000067F000080000008C00C000001C000__000000AAEBE534F8", +"000000067F000080000008C00C000001C000-000000067F000080000008C00C0000020000__000000AAEBE534F8", +"000000067F000080000008C00C000001E90B-000000067F000080000008C00C000002802C__000000A98AB7EE49-000000AA2597E9A1", +"000000067F000080000008C00C0000020000-000000067F000080000008C00C0000024000__000000AAEBE534F8", +"000000067F000080000008C00C0000024000-000000067F000080000008C00C0000028000__000000AAEBE534F8", +"000000067F000080000008C00C0000028000-000000067F000080000008C00C000002C000__000000AAEBE534F8", +"000000067F000080000008C00C000002802C-000000067F000080000008C00C0000031783__000000A98AB7EE49-000000AA2597E9A1", +"000000067F000080000008C00C000002C000-000000067F000080000008C00C0000030000__000000AAEBE534F8", +"000000067F000080000008C00C0000030000-000000067F000080000008C00C0000034000__000000AAEBE534F8", +"000000067F000080000008C00C0000031783-000000067F000080000008C00C000003AEE9__000000A98AB7EE49-000000AA2597E9A1", +"000000067F000080000008C00C0000034000-000000067F000080000008C00C0000038000__000000AAEBE534F8", +"000000067F000080000008C00C0000038000-000000067F000080000008C00C000003C000__000000AAEBE534F8", +"000000067F000080000008C00C000003AEE9-000000067F000080000008C00C000004460B__000000A98AB7EE49-000000AA2597E9A1", +"000000067F000080000008C00C000003C000-000000067F000080000008C00C0000040000__000000AAEBE534F8", +"000000067F000080000008C00C0000040000-000000067F000080000008C00C0000044000__000000AAEBE534F8", +"000000067F000080000008C00C0000044000-000000067F000080000008C00C0000048000__000000AAEBE534F8", +"000000067F000080000008C00C000004460B-000000067F000080000008C00C000004DD71__000000A98AB7EE49-000000AA2597E9A1", +"000000067F000080000008C00C0000048000-000000067F000080000008C00C000004C000__000000AAEBE534F8", +"000000067F000080000008C00C000004C000-000000067F000080000008C00C0000050000__000000AAEBE534F8", +"000000067F000080000008C00C000004DD71-030000000000000000000000000000000002__000000A98AB7EE49-000000AA2597E9A1", +"000000067F000080000008C00C0000050000-000000067F000080000008C00C0000054000__000000AAEBE534F8", +"000000067F000080000008C00C0000054000-000000067F000080000008C00C0000058000__000000AAEBE534F8", +"000000067F000080000008C00C0000058000-000000067F000080000008C00C000005C000__000000AAEBE534F8", +"000000067F000080000008C00C000005C000-000000067F000080000008C00C0000060000__000000AAEBE534F8", +"000000067F000080000008C00C000005DA8C-000000067F000080000008C00C00000671AE__000000AA2597E9A1-000000AB6533BFD9", +"000000067F000080000008C00C0000060000-000000067F000080000008C00C0000064000__000000AAEBE534F8", +"000000067F000080000008C00C0000064000-000000067F000080000008C00C0000068000__000000AAEBE534F8", +"000000067F000080000008C00C00000671AE-000000067F000080000008C00C000007090A__000000AA2597E9A1-000000AB6533BFD9", +"000000067F000080000008C00C0000068000-000000067F000080000008C00C000006C000__000000AAEBE534F8", +"000000067F000080000008C00C000006C000-000000067F000080000008C00C0000070000__000000AAEBE534F8", +"000000067F000080000008C00C0000070000-000000067F000080000008C00C0000074000__000000AAEBE534F8", +"000000067F000080000008C00C000007090A-000000067F000080000008C00C000007A070__000000AA2597E9A1-000000AB6533BFD9", +"000000067F000080000008C00C0000074000-000000067F000080000008C00C0000078000__000000AAEBE534F8", +"000000067F000080000008C00C0000078000-000000067F000080000008C00C000007C000__000000AAEBE534F8", +"000000067F000080000008C00C000007A070-000000067F000080000008C00C00000837B4__000000AA2597E9A1-000000AB6533BFD9", +"000000067F000080000008C00C000007C000-000000067F000080000008C00C0000080000__000000AAEBE534F8", +"000000067F000080000008C00C0000080000-000000067F000080000008C00C0000084000__000000AAEBE534F8", +"000000067F000080000008C00C00000837B4-000000067F000080000008C00C000008CF0A__000000AA2597E9A1-000000AB6533BFD9", +"000000067F000080000008C00C0000084000-000000067F000080000008C00C0000088000__000000AAEBE534F8", +"000000067F000080000008C00C0000088000-000000067F000080000008C00C000008C000__000000AAEBE534F8", +"000000067F000080000008C00C000008C000-000000067F000080000008C00C0000090000__000000AAEBE534F8", +"000000067F000080000008C00C000008CF0A-000000067F000080000008C00C0000096670__000000AA2597E9A1-000000AB6533BFD9", +"000000067F000080000008C00C0000090000-000000067F000080000008C00C0000094000__000000AAEBE534F8", +"000000067F000080000008C00C0000094000-000000067F000080000008C00C0000098000__000000AAEBE534F8", +"000000067F000080000008C00C0000096670-000000067F000080000008C00C000009FDD6__000000AA2597E9A1-000000AB6533BFD9", +"000000067F000080000008C00C0000098000-000000067F000080000008C00C000009C000__000000AAEBE534F8", +"000000067F000080000008C00C000009C000-000000067F000080000008C00C00000A0000__000000AAEBE534F8", +"000000067F000080000008C00C000009FDD6-000000067F000080000008C00C00000A952A__000000AA2597E9A1-000000AB6533BFD9", +"000000067F000080000008C00C00000A0000-000000067F000080000008C00C00000A4000__000000AAEBE534F8", +"000000067F000080000008C00C00000A4000-000000067F000080000008C00C00000A8000__000000AAEBE534F8", +"000000067F000080000008C00C00000A8000-000000067F000080000008C00C00000AC000__000000AAEBE534F8", +"000000067F000080000008C00C00000A952A-000000067F000080000008C00C00000B2C90__000000AA2597E9A1-000000AB6533BFD9", +"000000067F000080000008C00C00000AC000-000000067F000080000008C00C00000B0000__000000AAEBE534F8", +"000000067F000080000008C00C00000B0000-000000067F000080000008C00C00000B4000__000000AAEBE534F8", +"000000067F000080000008C00C00000B2C90-000000067F000080000008C00C00000BC3F6__000000AA2597E9A1-000000AB6533BFD9", +"000000067F000080000008C00C00000B4000-000000067F000080000008C00C00000B8000__000000AAEBE534F8", +"000000067F000080000008C00C00000B8000-000000067F000080000008C00C00000BC000__000000AAEBE534F8", +"000000067F000080000008C00C00000BC000-000000067F000080000008C00C00000C0000__000000AAEBE534F8", +"000000067F000080000008C00C00000BC3F6-000000067F000080000008C00C00000C5B0C__000000AA2597E9A1-000000AB6533BFD9", +"000000067F000080000008C00C00000C0000-000000067F000080000008C00C00000C4000__000000AAEBE534F8", +"000000067F000080000008C00C00000C4000-000000067F000080000008C00C00000C8000__000000AAEBE534F8", +"000000067F000080000008C00C00000C5B0C-000000067F000080000008C00C00000CF272__000000AA2597E9A1-000000AB6533BFD9", +"000000067F000080000008C00C00000C8000-030000000000000000000000000000000002__000000AAEBE534F8", +"000000067F000080000008C00C00000CF272-000000067F000080000008C00C00000D8986__000000AA2597E9A1-000000AB6533BFD9", +"000000067F000080000008C00C00000D8986-000000067F000080000008C00C00000E20EC__000000AA2597E9A1-000000AB6533BFD9", +"000000067F000080000008C00C00000E20EC-000000067F000080000008C00C00000EB80A__000000AA2597E9A1-000000AB6533BFD9", +"000000067F000080000008C00C00000EB80A-000000067F000080000008C00C00000F4F40__000000AA2597E9A1-000000AB6533BFD9", +"000000067F000080000008C00C00000F4F40-000000067F000080000008C00C00000FE6A6__000000AA2597E9A1-000000AB6533BFD9", +"000000067F000080000008C00C00000FE6A6-000000067F000080000008C00C0000107DC1__000000AA2597E9A1-000000AB6533BFD9", +"000000067F000080000008C00C0000107DC1-000000067F000080000008C00C000011150A__000000AA2597E9A1-000000AB6533BFD9", +"000000067F000080000008C00C000011150A-01000000000000000100000004000000001C__000000AA2597E9A1-000000AB6533BFD9", +"000000067F000080000008E00C0000000000-000000067F000080000008E00C0000004000__000000AD3698E000", +"000000067F000080000008E00C0000004000-000000067F000080000008E00C0000008000__000000AD3698E000", +"000000067F000080000008E00C00000077B3-000000067F000080000008E00C0000010F0A__000000AB6533BFD9-000000ABF63DF511", +"000000067F000080000008E00C0000008000-000000067F000080000008E00C000000C000__000000AD3698E000", +"000000067F000080000008E00C000000C000-000000067F000080000008E00C0000010000__000000AD3698E000", +"000000067F000080000008E00C0000010000-000000067F000080000008E00C0000014000__000000AD3698E000", +"000000067F000080000008E00C0000010F0A-000000067F000080000008E00C000001A670__000000AB6533BFD9-000000ABF63DF511", +"000000067F000080000008E00C0000014000-000000067F000080000008E00C0000018000__000000AD3698E000", +"000000067F000080000008E00C0000018000-000000067F000080000008E00C000001C000__000000AD3698E000", +"000000067F000080000008E00C000001A670-000000067F000080000008E00C0000023DB1__000000AB6533BFD9-000000ABF63DF511", +"000000067F000080000008E00C000001C000-000000067F000080000008E00C0000020000__000000AD3698E000", +"000000067F000080000008E00C0000020000-000000067F000080000008E00C0000024000__000000AD3698E000", +"000000067F000080000008E00C0000023DB1-000000067F000080000008E00C000002D50A__000000AB6533BFD9-000000ABF63DF511", +"000000067F000080000008E00C0000024000-000000067F000080000008E00C0000028000__000000AD3698E000", +"000000067F000080000008E00C0000028000-000000067F000080000008E00C000002C000__000000AD3698E000", +"000000067F000080000008E00C000002C000-000000067F000080000008E00C0000030000__000000AD3698E000", +"000000067F000080000008E00C000002D50A-000000067F000080000008E00C0000036C30__000000AB6533BFD9-000000ABF63DF511", +"000000067F000080000008E00C0000030000-000000067F000080000008E00C0000034000__000000AD3698E000", +"000000067F000080000008E00C0000034000-000000067F000080000008E00C0000038000__000000AD3698E000", +"000000067F000080000008E00C0000036C30-000000067F000080000008E00C0000040393__000000AB6533BFD9-000000ABF63DF511", +"000000067F000080000008E00C0000038000-000000067F000080000008E00C000003C000__000000AD3698E000", +"000000067F000080000008E00C000003C000-000000067F000080000008E00C0000040000__000000AD3698E000", +"000000067F000080000008E00C0000040000-000000067F000080000008E00C0000044000__000000AD3698E000", +"000000067F000080000008E00C0000040393-000000067F000080000008E00C0000049AF9__000000AB6533BFD9-000000ABF63DF511", +"000000067F000080000008E00C0000044000-000000067F000080000008E00C0000048000__000000AD3698E000", +"000000067F000080000008E00C0000048000-000000067F000080000008E00C000004C000__000000AD3698E000", +"000000067F000080000008E00C0000049AF9-000000067F000080000008E00C000005320C__000000AB6533BFD9-000000ABF63DF511", +"000000067F000080000008E00C000004C000-000000067F000080000008E00C0000050000__000000AD3698E000", +"000000067F000080000008E00C0000050000-000000067F000080000008E00C0000054000__000000AD3698E000", +"000000067F000080000008E00C000005320C-030000000000000000000000000000000002__000000AB6533BFD9-000000ABF63DF511", +"000000067F000080000008E00C0000054000-000000067F000080000008E00C0000058000__000000AD34AF7FD8", +"000000067F000080000008E00C000005523E-000000067F000080000008E00C000005E9A4__000000ABF63DF511-000000AC9601EA19", +"000000067F000080000008E00C0000058000-000000067F000080000008E00C000005C000__000000AD34AF7FD8", +"000000067F000080000008E00C000005C000-000000067F000080000008E00C0000060000__000000AD34AF7FD8", +"000000067F000080000008E00C000005E9A4-000000067F000080000008E00C000006810A__000000ABF63DF511-000000AC9601EA19", +"000000067F000080000008E00C0000060000-000000067F000080000008E00C0000064000__000000AD34AF7FD8", +"000000067F000080000008E00C0000064000-000000067F000080000008E00C0000068000__000000AD34AF7FD8", +"000000067F000080000008E00C0000068000-000000067F000080000008E00C000006C000__000000AD34AF7FD8", +"000000067F000080000008E00C000006810A-000000067F000080000008E00C0000071870__000000ABF63DF511-000000AC9601EA19", +"000000067F000080000008E00C000006C000-000000067F000080000008E00C0000070000__000000AD34AF7FD8", +"000000067F000080000008E00C0000070000-000000067F000080000008E00C0000074000__000000AD34AF7FD8", +"000000067F000080000008E00C0000071870-000000067F000080000008E00C000007AFD6__000000ABF63DF511-000000AC9601EA19", +"000000067F000080000008E00C0000074000-000000067F000080000008E00C0000078000__000000AD34AF7FD8", +"000000067F000080000008E00C0000078000-000000067F000080000008E00C000007C000__000000AD34AF7FD8", +"000000067F000080000008E00C000007AFD6-000000067F000080000008E00C000008470B__000000ABF63DF511-000000AC9601EA19", +"000000067F000080000008E00C000007C000-000000067F000080000008E00C0000080000__000000AD34AF7FD8", +"000000067F000080000008E00C0000080000-000000067F000080000008E00C0000084000__000000AD34AF7FD8", +"000000067F000080000008E00C0000084000-000000067F000080000008E00C0000088000__000000AD34AF7FD8", +"000000067F000080000008E00C000008470B-000000067F000080000008E00C000008DE71__000000ABF63DF511-000000AC9601EA19", +"000000067F000080000008E00C0000088000-000000067F000080000008E00C000008C000__000000AD34AF7FD8", +"000000067F000080000008E00C000008C000-000000067F000080000008E00C0000090000__000000AD34AF7FD8", +"000000067F000080000008E00C000008DE71-000000067F000080000008E00C0000097591__000000ABF63DF511-000000AC9601EA19", +"000000067F000080000008E00C0000090000-000000067F000080000008E00C0000094000__000000AD34AF7FD8", +"000000067F000080000008E00C0000094000-000000067F000080000008E00C0000098000__000000AD34AF7FD8", +"000000067F000080000008E00C0000097591-000000067F000080000008E00C00000A0CF7__000000ABF63DF511-000000AC9601EA19", +"000000067F000080000008E00C0000098000-000000067F000080000008E00C000009C000__000000AD34AF7FD8", +"000000067F000080000008E00C000009C000-000000067F000080000008E00C00000A0000__000000AD34AF7FD8", +"000000067F000080000008E00C00000A0000-000000067F000080000008E00C00000A4000__000000AD34AF7FD8", +"000000067F000080000008E00C00000A0CF7-000000067F000080000008E00C00000AA40B__000000ABF63DF511-000000AC9601EA19", +"000000067F000080000008E00C00000A4000-000000067F000080000008E00C00000A8000__000000AD34AF7FD8", +"000000067F000080000008E00C00000A8000-000000067F000080000008E00C00000AC000__000000AD34AF7FD8", +"000000067F000080000008E00C00000AA40B-000000067F000080000008E00C00000B3B4D__000000ABF63DF511-000000AC9601EA19", +"000000067F000080000008E00C00000AC000-000000067F000080000008E00C00000B0000__000000AD34AF7FD8", +"000000067F000080000008E00C00000B0000-000000067F000080000008E00C00000B4000__000000AD34AF7FD8", +"000000067F000080000008E00C00000B3B4D-000000067F000080000008E00C0100000000__000000ABF63DF511-000000AC9601EA19", +"000000067F000080000008E00C00000B4000-000000067F000080000008E00C00000B8000__000000AD34AF7FD8", +"000000067F000080000008E00C00000B8000-000000067F000080000008E00C00000BC000__000000AD34AF7FD8", +"000000067F000080000008E00C00000BC000-000000067F000080000008E00C00000C0000__000000AD34AF7FD8", +"000000067F000080000008E00C00000BC018-000000067F000080000008E00C00000C5749__000000AC9601EA19-000000AD36393FE9", +"000000067F000080000008E00C00000C0000-000000067F000080000008E00C00000C4000__000000AD34AF7FD8", +"000000067F000080000008E00C00000C4000-000000067F000080000008E00C00000C8000__000000AD34AF7FD8", +"000000067F000080000008E00C00000C5749-000000067F000080000008E00C00000CEEAF__000000AC9601EA19-000000AD36393FE9", +"000000067F000080000008E00C00000C8000-000000067F000080000008E00C00000CC000__000000AD34AF7FD8", +"000000067F000080000008E00C00000CC000-000000067F000080000008E00C00000D0000__000000AD34AF7FD8", +"000000067F000080000008E00C00000CEEAF-000000067F000080000008E00C00000D85C5__000000AC9601EA19-000000AD36393FE9", +"000000067F000080000008E00C00000D0000-000000067F000080000008E00C00000D4000__000000AD34AF7FD8", +"000000067F000080000008E00C00000D4000-000000067F000080000008E00C00000D8000__000000AD34AF7FD8", +"000000067F000080000008E00C00000D8000-000000067F000080000008E00C00000DC000__000000AD34AF7FD8", +"000000067F000080000008E00C00000D85C5-000000067F000080000008E00C00000E1D0B__000000AC9601EA19-000000AD36393FE9", +"000000067F000080000008E00C00000DC000-000000067F000080000008E00C00000E0000__000000AD34AF7FD8", +"000000067F000080000008E00C00000E0000-000000067F000080000008E00C00000E4000__000000AD34AF7FD8", +"000000067F000080000008E00C00000E1D0B-000000067F000080000008E00C00000EB471__000000AC9601EA19-000000AD36393FE9", +"000000067F000080000008E00C00000E4000-000000067F000080000008E00C00000E8000__000000AD34AF7FD8", +"000000067F000080000008E00C00000E8000-000000067F000080000008E00C00000EC000__000000AD34AF7FD8", +"000000067F000080000008E00C00000EB471-000000067F000080000008E00C00000F4BAA__000000AC9601EA19-000000AD36393FE9", +"000000067F000080000008E00C00000EC000-000000067F000080000008E00C00000F0000__000000AD34AF7FD8", +"000000067F000080000008E00C00000F0000-000000067F000080000008E00C00000F4000__000000AD34AF7FD8", +"000000067F000080000008E00C00000F4000-000000067F000080000008E00C00000F8000__000000AD34AF7FD8", +"000000067F000080000008E00C00000F4BAA-000000067F000080000008E00C00000FE30A__000000AC9601EA19-000000AD36393FE9", +"000000067F000080000008E00C00000F8000-000000067F000080000008E00C00000FC000__000000AD34AF7FD8", +"000000067F000080000008E00C00000FC000-000000067F000080000008E00C0000100000__000000AD34AF7FD8", +"000000067F000080000008E00C00000FE30A-000000067F000080000008E00C0000107A2C__000000AC9601EA19-000000AD36393FE9", +"000000067F000080000008E00C0000100000-000000067F000080000008E00C0000104000__000000AD34AF7FD8", +"000000067F000080000008E00C0000104000-000000067F000080000008E00C0000108000__000000AD34AF7FD8", +"000000067F000080000008E00C0000107A2C-000000067F000080000008E00C0000111187__000000AC9601EA19-000000AD36393FE9", +"000000067F000080000008E00C0000108000-000000067F000080000008E00C000010C000__000000AD34AF7FD8", +"000000067F000080000008E00C000010C000-000000067F000080000008E00C0000110000__000000AD34AF7FD8", +"000000067F000080000008E00C0000110000-030000000000000000000000000000000002__000000AD34AF7FD8", +"000000067F000080000008E00C0000111187-01000000000000000100000004000000001C__000000AC9601EA19-000000AD36393FE9", +"000000067F000080000008E0140000003E33-000000067F000080000008E014000000BD44__000000AD36393FE9-000000ADB047EAB9", +"000000067F000080000008E014000000BD44-000000067F000080000008E0140000013C54__000000AD36393FE9-000000ADB047EAB9", +"000000067F000080000008E0140000013C54-000000067F000080000008E014000001BB63__000000AD36393FE9-000000ADB047EAB9", +"000000067F000080000008E014000001BB63-000000067F000080000008E0140000023A74__000000AD36393FE9-000000ADB047EAB9", +"000000067F000080000008E0140000023A74-000000067F000080000008E014000002B984__000000AD36393FE9-000000ADB047EAB9", +"000000067F000080000008E014000002B984-000000067F000080000008E0220000006AD0__000000AD36393FE9-000000ADB047EAB9", +"000000067F000080000008E0220000000000-000000067F000080000008E0220000004000__000000AF5D7D4000", +"000000067F000080000008E0220000004000-000000067F000080000008E0220000008000__000000AF5D7D4000", +"000000067F000080000008E0220000006AD0-000000067F000080000008E022000001020C__000000AD36393FE9-000000ADB047EAB9", +"000000067F000080000008E0220000008000-000000067F000080000008E022000000C000__000000AF5D7D4000", +"000000067F000080000008E022000000C000-000000067F000080000008E0220000010000__000000AF5D7D4000", +"000000067F000080000008E0220000010000-000000067F000080000008E0220000014000__000000AF5D7D4000", +"000000067F000080000008E022000001020C-01000000000000000100000004000000001C__000000AD36393FE9-000000ADB047EAB9", +"000000067F000080000008E0220000014000-000000067F000080000008E0220000018000__000000AF56604248", +"000000067F000080000008E02200000151DD-000000067F000080000008E022000001E90B__000000ADB047EAB9-000000AE6FFFE799", +"000000067F000080000008E0220000018000-000000067F000080000008E022000001C000__000000AF56604248", +"000000067F000080000008E022000001C000-000000067F000080000008E0220000020000__000000AF56604248", +"000000067F000080000008E022000001E90B-000000067F000080000008E022000002802C__000000ADB047EAB9-000000AE6FFFE799", +"000000067F000080000008E0220000020000-000000067F000080000008E0220000024000__000000AF56604248", +"000000067F000080000008E0220000024000-000000067F000080000008E0220000028000__000000AF56604248", +"000000067F000080000008E0220000028000-000000067F000080000008E022000002C000__000000AF56604248", +"000000067F000080000008E022000002802C-000000067F000080000008E0220000031783__000000ADB047EAB9-000000AE6FFFE799", +"000000067F000080000008E022000002C000-000000067F000080000008E0220000030000__000000AF56604248", +"000000067F000080000008E0220000030000-000000067F000080000008E0220000034000__000000AF56604248", +"000000067F000080000008E0220000031783-000000067F000080000008E022000003AEE9__000000ADB047EAB9-000000AE6FFFE799", +"000000067F000080000008E0220000034000-000000067F000080000008E0220000038000__000000AF56604248", +"000000067F000080000008E0220000038000-000000067F000080000008E022000003C000__000000AF56604248", +"000000067F000080000008E022000003AEE9-000000067F000080000008E022000004460B__000000ADB047EAB9-000000AE6FFFE799", +"000000067F000080000008E022000003C000-000000067F000080000008E0220000040000__000000AF56604248", +"000000067F000080000008E0220000040000-000000067F000080000008E0220000044000__000000AF56604248", +"000000067F000080000008E0220000044000-000000067F000080000008E0220000048000__000000AF56604248", +"000000067F000080000008E022000004460B-000000067F000080000008E022000004DD71__000000ADB047EAB9-000000AE6FFFE799", +"000000067F000080000008E0220000048000-000000067F000080000008E022000004C000__000000AF56604248", +"000000067F000080000008E022000004C000-000000067F000080000008E0220000050000__000000AF56604248", +"000000067F000080000008E022000004DD71-000000067F000080000008E02200000574D7__000000ADB047EAB9-000000AE6FFFE799", +"000000067F000080000008E0220000050000-000000067F000080000008E0220000054000__000000AF56604248", +"000000067F000080000008E0220000054000-000000067F000080000008E0220000058000__000000AF56604248", +"000000067F000080000008E02200000574D7-000000067F000080000008E0220000060C0B__000000ADB047EAB9-000000AE6FFFE799", +"000000067F000080000008E0220000058000-000000067F000080000008E022000005C000__000000AF56604248", +"000000067F000080000008E022000005C000-000000067F000080000008E0220000060000__000000AF56604248", +"000000067F000080000008E0220000060000-000000067F000080000008E0220000064000__000000AF56604248", +"000000067F000080000008E0220000060C0B-000000067F000080000008E022000006A371__000000ADB047EAB9-000000AE6FFFE799", +"000000067F000080000008E0220000064000-000000067F000080000008E0220000068000__000000AF56604248", +"000000067F000080000008E0220000068000-000000067F000080000008E022000006C000__000000AF56604248", +"000000067F000080000008E022000006A371-000000067F000080000008E0220000073AD7__000000ADB047EAB9-000000AE6FFFE799", +"000000067F000080000008E022000006C000-000000067F000080000008E0220000070000__000000AF56604248", +"000000067F000080000008E0220000070000-000000067F000080000008E0220000074000__000000AF56604248", +"000000067F000080000008E0220000073AD7-000000067F000080000008E022000007D20B__000000ADB047EAB9-000000AE6FFFE799", +"000000067F000080000008E0220000074000-000000067F000080000008E0220000078000__000000AF56604248", +"000000067F000080000008E0220000078000-000000067F000080000008E022000007C000__000000AF56604248", +"000000067F000080000008E022000007C000-000000067F000080000008E0220000080000__000000AF56604248", +"000000067F000080000008E022000007D20B-000000067F000080000008E0220000086932__000000ADB047EAB9-000000AE6FFFE799", +"000000067F000080000008E0220000080000-000000067F000080000008E0220000084000__000000AF56604248", +"000000067F000080000008E0220000084000-000000067F000080000008E0220000088000__000000AF56604248", +"000000067F000080000008E0220000086932-000000067F000080000008E0220100000000__000000ADB047EAB9-000000AE6FFFE799", +"000000067F000080000008E0220000088000-000000067F000080000008E022000008C000__000000AF56604248", +"000000067F000080000008E022000008C000-000000067F000080000008E0220000090000__000000AF56604248", +"000000067F000080000008E022000008E3D1-000000067F000080000008E022000009797E__000000AE6FFFE799-000000AF5D587FE1", +"000000067F000080000008E0220000090000-000000067F000080000008E0220000094000__000000AF56604248", +"000000067F000080000008E0220000094000-000000067F000080000008E0220000098000__000000AF56604248", +"000000067F000080000008E022000009797E-000000067F000080000008E02200000A10E4__000000AE6FFFE799-000000AF5D587FE1", +"000000067F000080000008E0220000098000-000000067F000080000008E022000009C000__000000AF56604248", +"000000067F000080000008E022000009C000-000000067F000080000008E02200000A0000__000000AF56604248", +"000000067F000080000008E02200000A0000-000000067F000080000008E02200000A4000__000000AF56604248", +"000000067F000080000008E02200000A10E4-000000067F000080000008E02200000AA80B__000000AE6FFFE799-000000AF5D587FE1", +"000000067F000080000008E02200000A4000-000000067F000080000008E02200000A8000__000000AF56604248", +"000000067F000080000008E02200000A8000-000000067F000080000008E02200000AC000__000000AF56604248", +"000000067F000080000008E02200000AA80B-000000067F000080000008E02200000B3F4B__000000AE6FFFE799-000000AF5D587FE1", +"000000067F000080000008E02200000AC000-000000067F000080000008E02200000B0000__000000AF56604248", +"000000067F000080000008E02200000B0000-000000067F000080000008E02200000B4000__000000AF56604248", +"000000067F000080000008E02200000B3F4B-000000067F000080000008E02200000BD6B1__000000AE6FFFE799-000000AF5D587FE1", +"000000067F000080000008E02200000B4000-000000067F000080000008E02200000B8000__000000AF56604248", +"000000067F000080000008E02200000B8000-000000067F000080000008E02200000BC000__000000AF56604248", +"000000067F000080000008E02200000BC000-000000067F000080000008E02200000C0000__000000AF56604248", +"000000067F000080000008E02200000BD6B1-000000067F000080000008E02200000C6DD5__000000AE6FFFE799-000000AF5D587FE1", +"000000067F000080000008E02200000C0000-000000067F000080000008E02200000C4000__000000AF56604248", +"000000067F000080000008E02200000C4000-000000067F000080000008E02200000C8000__000000AF56604248", +"000000067F000080000008E02200000C6DD5-000000067F000080000008E02200000D050B__000000AE6FFFE799-000000AF5D587FE1", +"000000067F000080000008E02200000C8000-000000067F000080000008E02200000CC000__000000AF56604248", +"000000067F000080000008E02200000CC000-000000067F000080000008E02200000D0000__000000AF56604248", +"000000067F000080000008E02200000D0000-000000067F000080000008E02200000D4000__000000AF56604248", +"000000067F000080000008E02200000D050B-000000067F000080000008E02200000D9C71__000000AE6FFFE799-000000AF5D587FE1", +"000000067F000080000008E02200000D4000-000000067F000080000008E02200000D8000__000000AF56604248", +"000000067F000080000008E02200000D8000-000000067F000080000008E02200000DC000__000000AF56604248", +"000000067F000080000008E02200000D9C71-000000067F000080000008E02200000E33B8__000000AE6FFFE799-000000AF5D587FE1", +"000000067F000080000008E02200000DC000-000000067F000080000008E02200000E0000__000000AF56604248", +"000000067F000080000008E02200000E0000-000000067F000080000008E02200000E4000__000000AF56604248", +"000000067F000080000008E02200000E33B8-000000067F000080000008E02200000ECB09__000000AE6FFFE799-000000AF5D587FE1", +"000000067F000080000008E02200000E4000-000000067F000080000008E02200000E8000__000000AF56604248", +"000000067F000080000008E02200000E8000-000000067F000080000008E02200000EC000__000000AF56604248", +"000000067F000080000008E02200000EC000-000000067F000080000008E02200000F0000__000000AF56604248", +"000000067F000080000008E02200000ECB09-000000067F000080000008E02200000F626F__000000AE6FFFE799-000000AF5D587FE1", +"000000067F000080000008E02200000F0000-000000067F000080000008E02200000F4000__000000AF56604248", +"000000067F000080000008E02200000F4000-000000067F000080000008E02200000F8000__000000AF56604248", +"000000067F000080000008E02200000F626F-000000067F000080000008E02200000FF9D5__000000AE6FFFE799-000000AF5D587FE1", +"000000067F000080000008E02200000F8000-000000067F000080000008E02200000FC000__000000AF56604248", +"000000067F000080000008E02200000FC000-000000067F000080000008E0220000100000__000000AF56604248", +"000000067F000080000008E02200000FF9D5-000000067F000080000008E022000010912A__000000AE6FFFE799-000000AF5D587FE1", +"000000067F000080000008E0220000100000-000000067F000080000008E0220000104000__000000AF56604248", +"000000067F000080000008E0220000104000-000000067F000080000008E0220000108000__000000AF56604248", +"000000067F000080000008E0220000108000-000000067F000080000008E022000010C000__000000AF56604248", +"000000067F000080000008E022000010912A-000000067F000080000008E0220000111C20__000000AE6FFFE799-000000AF5D587FE1", +"000000067F000080000008E022000010C000-030000000000000000000000000000000002__000000AF56604248", +"000000067F000080000008E02200FFFFFFFF-01000000000000000100000004000000001C__000000AE6FFFE799-000000AF5D587FE1", +"000000067F000080000008E02A000000529F-000000067F000080000008E02A000000D1B0__000000AF5D587FE1-000000AFB4666001", +"000000067F000080000008E02A000000D1B0-000000067F000080000008E02A00000150BF__000000AF5D587FE1-000000AFB4666001", +"000000067F000080000008E02A00000150BF-000000067F000080000008E02A000001CFD0__000000AF5D587FE1-000000AFB4666001", +"000000067F000080000008E02A000001CFD0-000000067F000080000008E02A0000024EE1__000000AF5D587FE1-000000AFB4666001", +"000000067F000080000008E02A0000024EE1-000000067F000080000008E02A000002CDF1__000000AF5D587FE1-000000AFB4666001", +"000000067F000080000008E02A000002CDF1-030000000000000000000000000000000002__000000AF5D587FE1-000000AFB4666001", +"000000067F00008000000900380000000000-000000067F0000800000090038000000970B__000000AFB4666001-000000B05429F579", +"000000067F0000800000090038000000970B-000000067F00008000000900380000012E71__000000AFB4666001-000000B05429F579", +"000000067F00008000000900380000012E71-000000067F0000800000090038000001C5D7__000000AFB4666001-000000B05429F579", +"000000067F0000800000090038000001C5D7-000000067F00008000000900380000025D2B__000000AFB4666001-000000B05429F579", +"000000067F00008000000900380000025D2B-000000067F0000800000090038000002F491__000000AFB4666001-000000B05429F579", +"000000067F0000800000090038000002F491-000000067F00008000000900380000038BA4__000000AFB4666001-000000B05429F579", +"000000067F00008000000900380000038BA4-000000067F0000800000090038000004230A__000000AFB4666001-000000B05429F579", +"000000067F0000800000090038000004230A-000000067F0000800000090038000004BA70__000000AFB4666001-000000B05429F579", +"000000067F0000800000090038000004BA70-000000067F000080000009003800000551A5__000000AFB4666001-000000B05429F579", +"000000067F000080000009003800000551A5-000000067F0000800000090038000005E909__000000AFB4666001-000000B05429F579", +"000000067F0000800000090038000005C000-000000067F00008000000900380000060000__000000B18434BFD0", +"000000067F0000800000090038000005E909-000000067F000080000009003B0100000000__000000AFB4666001-000000B05429F579", +"000000067F0000800000090038000005EA0C-000000067F00008000000900380000068125__000000B05429F579-000000B0F3EDEAC9", +"000000067F00008000000900380000060000-000000067F00008000000900380000064000__000000B18434BFD0", +"000000067F00008000000900380000064000-000000067F00008000000900380000068000__000000B18434BFD0", +"000000067F00008000000900380000068000-000000067F0000800000090038000006C000__000000B18434BFD0", +"000000067F00008000000900380000068125-000000067F0000800000090038000007188B__000000B05429F579-000000B0F3EDEAC9", +"000000067F0000800000090038000006C000-000000067F00008000000900380000070000__000000B18434BFD0", +"000000067F00008000000900380000070000-000000067F00008000000900380000074000__000000B18434BFD0", +"000000067F0000800000090038000007188B-000000067F0000800000090038000007AFF1__000000B05429F579-000000B0F3EDEAC9", +"000000067F00008000000900380000074000-000000067F00008000000900380000078000__000000B18434BFD0", +"000000067F00008000000900380000078000-000000067F0000800000090038000007C000__000000B18434BFD0", +"000000067F0000800000090038000007AFF1-000000067F0000800000090038000008470C__000000B05429F579-000000B0F3EDEAC9", +"000000067F0000800000090038000007C000-000000067F00008000000900380000080000__000000B18434BFD0", +"000000067F00008000000900380000080000-000000067F00008000000900380000084000__000000B18434BFD0", +"000000067F00008000000900380000084000-000000067F00008000000900380000088000__000000B18434BFD0", +"000000067F0000800000090038000008470C-000000067F0000800000090038000008DE72__000000B05429F579-000000B0F3EDEAC9", +"000000067F00008000000900380000088000-000000067F0000800000090038000008C000__000000B18434BFD0", +"000000067F0000800000090038000008C000-000000067F00008000000900380000090000__000000B18434BFD0", +"000000067F0000800000090038000008DE72-000000067F00008000000900380000097592__000000B05429F579-000000B0F3EDEAC9", +"000000067F00008000000900380000090000-000000067F00008000000900380000094000__000000B18434BFD0", +"000000067F00008000000900380000094000-000000067F00008000000900380000098000__000000B18434BFD0", +"000000067F00008000000900380000097592-000000067F000080000009003800000A0CF8__000000B05429F579-000000B0F3EDEAC9", +"000000067F00008000000900380000098000-000000067F0000800000090038000009C000__000000B18434BFD0", +"000000067F0000800000090038000009C000-000000067F000080000009003800000A0000__000000B18434BFD0", +"000000067F000080000009003800000A0000-000000067F000080000009003800000A4000__000000B18434BFD0", +"000000067F000080000009003800000A0CF8-000000067F000080000009003800000AA40C__000000B05429F579-000000B0F3EDEAC9", +"000000067F000080000009003800000A4000-000000067F000080000009003800000A8000__000000B18434BFD0", +"000000067F000080000009003800000A8000-000000067F000080000009003800000AC000__000000B18434BFD0", +"000000067F000080000009003800000AA40C-000000067F000080000009003800000B3B4E__000000B05429F579-000000B0F3EDEAC9", +"000000067F000080000009003800000AC000-000000067F000080000009003800000B0000__000000B18434BFD0", +"000000067F000080000009003800000B0000-000000067F000080000009003800000B4000__000000B18434BFD0", +"000000067F000080000009003800000B3B4E-000000067F000080000009003800000BD2B4__000000B05429F579-000000B0F3EDEAC9", +"000000067F000080000009003800000B4000-000000067F000080000009003800000B8000__000000B18434BFD0", +"000000067F000080000009003800000B8000-000000067F000080000009003800000BC000__000000B18434BFD0", +"000000067F000080000009003800000BC000-000000067F000080000009003800000C0000__000000B18434BFD0", +"000000067F000080000009003800000BD2B4-000000067F00008000000900380100000000__000000B05429F579-000000B0F3EDEAC9", +"000000067F000080000009003800000C0000-000000067F000080000009003800000C4000__000000B18434BFD0", +"000000067F000080000009003800000C4000-000000067F000080000009003800000C8000__000000B18434BFD0", +"000000067F000080000009003800000C5213-000000067F000080000009003800000CE979__000000B0F3EDEAC9-000000B18495C001", +"000000067F000080000009003800000C8000-000000067F000080000009003800000CC000__000000B18434BFD0", +"000000067F000080000009003800000CC000-000000067F000080000009003800000D0000__000000B18434BFD0", +"000000067F000080000009003800000CE979-000000067F000080000009003800000D80DF__000000B0F3EDEAC9-000000B18495C001", +"000000067F000080000009003800000D0000-000000067F000080000009003800000D4000__000000B18434BFD0", +"000000067F000080000009003800000D4000-000000067F000080000009003800000D8000__000000B18434BFD0", +"000000067F000080000009003800000D8000-000000067F000080000009003800000DC000__000000B18434BFD0", +"000000067F000080000009003800000D80DF-000000067F000080000009003800000E180A__000000B0F3EDEAC9-000000B18495C001", +"000000067F000080000009003800000DC000-000000067F000080000009003800000E0000__000000B18434BFD0", +"000000067F000080000009003800000E0000-000000067F000080000009003800000E4000__000000B18434BFD0", +"000000067F000080000009003800000E180A-000000067F000080000009003800000EAF70__000000B0F3EDEAC9-000000B18495C001", +"000000067F000080000009003800000E4000-000000067F000080000009003800000E8000__000000B18434BFD0", +"000000067F000080000009003800000E8000-000000067F000080000009003800000EC000__000000B18434BFD0", +"000000067F000080000009003800000EAF70-000000067F000080000009003800000F46D6__000000B0F3EDEAC9-000000B18495C001", +"000000067F000080000009003800000EC000-000000067F000080000009003800000F0000__000000B18434BFD0", +"000000067F000080000009003800000F0000-000000067F000080000009003800000F4000__000000B18434BFD0", +"000000067F000080000009003800000F4000-000000067F000080000009003800000F8000__000000B18434BFD0", +"000000067F000080000009003800000F46D6-000000067F000080000009003800000FDE0B__000000B0F3EDEAC9-000000B18495C001", +"000000067F000080000009003800000F8000-000000067F000080000009003800000FC000__000000B18434BFD0", +"000000067F000080000009003800000FC000-000000067F00008000000900380000100000__000000B18434BFD0", +"000000067F000080000009003800000FDE0B-000000067F0000800000090038000010752B__000000B0F3EDEAC9-000000B18495C001", +"000000067F00008000000900380000100000-000000067F00008000000900380000104000__000000B18434BFD0", +"000000067F00008000000900380000104000-000000067F00008000000900380000108000__000000B18434BFD0", +"000000067F0000800000090038000010752B-000000067F00008000000900380000110C91__000000B0F3EDEAC9-000000B18495C001", +"000000067F00008000000900380000108000-000000067F0000800000090038000010C000__000000B18434BFD0", +"000000067F0000800000090038000010C000-000000067F00008000000900380000110000__000000B18434BFD0", +"000000067F00008000000900380000110000-030000000000000000000000000000000002__000000B18434BFD0", +"000000067F00008000000900380000110C91-01000000000000000100000004000000001C__000000B0F3EDEAC9-000000B18495C001", +"000000067F000080000009004000000047E0-000000067F0000800000090040000000C6F1__000000B18495C001-000000B1FA75F501", +"000000067F0000800000090040000000C6F1-000000067F00008000000900400000014600__000000B18495C001-000000B1FA75F501", +"000000067F00008000000900400000014600-000000067F0000800000090040000001C511__000000B18495C001-000000B1FA75F501", +"000000067F0000800000090040000001C511-000000067F00008000000900400000024421__000000B18495C001-000000B1FA75F501", +"000000067F00008000000900400000024421-000000067F0000800000090040000002C331__000000B18495C001-000000B1FA75F501", +"000000067F0000800000090040000002C331-000000067F000080000009200C0000007658__000000B18495C001-000000B1FA75F501", +"000000067F000080000009200C0000000000-000000067F000080000009200C0000004000__000000B3AC039FE8", +"000000067F000080000009200C0000004000-000000067F000080000009200C0000008000__000000B3AC039FE8", +"000000067F000080000009200C0000007658-000000067F000080000009200C0000010DB5__000000B18495C001-000000B1FA75F501", +"000000067F000080000009200C0000008000-000000067F000080000009200C000000C000__000000B3AC039FE8", +"000000067F000080000009200C000000C000-000000067F000080000009200C0000010000__000000B3AC039FE8", +"000000067F000080000009200C0000010000-000000067F000080000009200C0000014000__000000B3A3EC82C8", +"000000067F000080000009200C0000010DB5-030000000000000000000000000000000002__000000B18495C001-000000B1FA75F501", +"000000067F000080000009200C0000012E97-000000067F000080000009200C000001C5FD__000000B1FA75F501-000000B2CA27F641", +"000000067F000080000009200C0000014000-000000067F000080000009200C0000018000__000000B3A3EC82C8", +"000000067F000080000009200C0000018000-000000067F000080000009200C000001C000__000000B3A3EC82C8", +"000000067F000080000009200C000001C000-000000067F000080000009200C0000020000__000000B3A3EC82C8", +"000000067F000080000009200C000001C5FD-000000067F000080000009200C0000025D0C__000000B1FA75F501-000000B2CA27F641", +"000000067F000080000009200C0000020000-000000067F000080000009200C0000024000__000000B3A3EC82C8", +"000000067F000080000009200C0000024000-000000067F000080000009200C0000028000__000000B3A3EC82C8", +"000000067F000080000009200C0000025D0C-000000067F000080000009200C000002F472__000000B1FA75F501-000000B2CA27F641", +"000000067F000080000009200C0000028000-000000067F000080000009200C000002C000__000000B3A3EC82C8", +"000000067F000080000009200C000002C000-000000067F000080000009200C0000030000__000000B3A3EC82C8", +"000000067F000080000009200C000002F472-000000067F000080000009200C0000038B85__000000B1FA75F501-000000B2CA27F641", +"000000067F000080000009200C0000030000-000000067F000080000009200C0000034000__000000B3A3EC82C8", +"000000067F000080000009200C0000034000-000000067F000080000009200C0000038000__000000B3A3EC82C8", +"000000067F000080000009200C0000038000-000000067F000080000009200C000003C000__000000B3A3EC82C8", +"000000067F000080000009200C0000038B85-000000067F000080000009200C00000422EB__000000B1FA75F501-000000B2CA27F641", +"000000067F000080000009200C000003C000-000000067F000080000009200C0000040000__000000B3A3EC82C8", +"000000067F000080000009200C0000040000-000000067F000080000009200C0000044000__000000B3A3EC82C8", +"000000067F000080000009200C00000422EB-000000067F000080000009200C000004BA0C__000000B1FA75F501-000000B2CA27F641", +"000000067F000080000009200C0000044000-000000067F000080000009200C0000048000__000000B3A3EC82C8", +"000000067F000080000009200C0000048000-000000067F000080000009200C000004C000__000000B3A3EC82C8", +"000000067F000080000009200C000004BA0C-000000067F000080000009200C0000055141__000000B1FA75F501-000000B2CA27F641", +"000000067F000080000009200C000004C000-000000067F000080000009200C0000050000__000000B3A3EC82C8", +"000000067F000080000009200C0000050000-000000067F000080000009200C0000054000__000000B3A3EC82C8", +"000000067F000080000009200C0000054000-000000067F000080000009200C0000058000__000000B3A3EC82C8", +"000000067F000080000009200C0000055141-000000067F000080000009200C000005E8A7__000000B1FA75F501-000000B2CA27F641", +"000000067F000080000009200C0000058000-000000067F000080000009200C000005C000__000000B3A3EC82C8", +"000000067F000080000009200C000005C000-000000067F000080000009200C0000060000__000000B3A3EC82C8", +"000000067F000080000009200C000005E8A7-000000067F000080000009200C0000067FC1__000000B1FA75F501-000000B2CA27F641", +"000000067F000080000009200C0000060000-000000067F000080000009200C0000064000__000000B3A3EC82C8", +"000000067F000080000009200C0000064000-000000067F000080000009200C0000068000__000000B3A3EC82C8", +"000000067F000080000009200C0000067FC1-000000067F000080000009200C0000071709__000000B1FA75F501-000000B2CA27F641", +"000000067F000080000009200C0000068000-000000067F000080000009200C000006C000__000000B3A3EC82C8", +"000000067F000080000009200C000006C000-000000067F000080000009200C0000070000__000000B3A3EC82C8", +"000000067F000080000009200C0000070000-000000067F000080000009200C0000074000__000000B3A3EC82C8", +"000000067F000080000009200C0000071709-000000067F000080000009200C000007AE6F__000000B1FA75F501-000000B2CA27F641", +"000000067F000080000009200C0000074000-000000067F000080000009200C0000078000__000000B3A3EC82C8", +"000000067F000080000009200C0000078000-000000067F000080000009200C000007C000__000000B3A3EC82C8", +"000000067F000080000009200C000007AE6F-000000067F000080000009200C00000845AB__000000B1FA75F501-000000B2CA27F641", +"000000067F000080000009200C000007C000-000000067F000080000009200C0000080000__000000B3A3EC82C8", +"000000067F000080000009200C0000080000-000000067F000080000009200C0000084000__000000B3A3EC82C8", +"000000067F000080000009200C0000084000-000000067F000080000009200C0000088000__000000B3A3EC82C8", +"000000067F000080000009200C00000845AB-000000067F000080000009200C000008DD09__000000B1FA75F501-000000B2CA27F641", +"000000067F000080000009200C0000088000-000000067F000080000009200C000008C000__000000B3A3EC82C8", +"000000067F000080000009200C000008C000-000000067F000080000009200C0000090000__000000B3A3EC82C8", +"000000067F000080000009200C000008DD09-000000067F000080000009200C0100000000__000000B1FA75F501-000000B2CA27F641", +"000000067F000080000009200C0000090000-000000067F000080000009200C0000094000__000000B3A3EC82C8", +"000000067F000080000009200C0000094000-000000067F000080000009200C0000098000__000000B3A3EC82C8", +"000000067F000080000009200C000009567A-000000067F000080000009200C000009EDE0__000000B2CA27F641-000000B3AB3B7FC9", +"000000067F000080000009200C0000098000-000000067F000080000009200C000009C000__000000B3A3EC82C8", +"000000067F000080000009200C000009C000-000000067F000080000009200C00000A0000__000000B3A3EC82C8", +"000000067F000080000009200C000009EDE0-000000067F000080000009200C00000A852B__000000B2CA27F641-000000B3AB3B7FC9", +"000000067F000080000009200C00000A0000-000000067F000080000009200C00000A4000__000000B3A3EC82C8", +"000000067F000080000009200C00000A4000-000000067F000080000009200C00000A8000__000000B3A3EC82C8", +"000000067F000080000009200C00000A8000-000000067F000080000009200C00000AC000__000000B3A3EC82C8", +"000000067F000080000009200C00000A852B-000000067F000080000009200C00000B1C91__000000B2CA27F641-000000B3AB3B7FC9", +"000000067F000080000009200C00000AC000-000000067F000080000009200C00000B0000__000000B3A3EC82C8", +"000000067F000080000009200C00000B0000-000000067F000080000009200C00000B4000__000000B3A3EC82C8", +"000000067F000080000009200C00000B1C91-000000067F000080000009200C00000BB3F7__000000B2CA27F641-000000B3AB3B7FC9", +"000000067F000080000009200C00000B4000-000000067F000080000009200C00000B8000__000000B3A3EC82C8", +"000000067F000080000009200C00000B8000-000000067F000080000009200C00000BC000__000000B3A3EC82C8", +"000000067F000080000009200C00000BB3F7-000000067F000080000009200C00000C4B0C__000000B2CA27F641-000000B3AB3B7FC9", +"000000067F000080000009200C00000BC000-000000067F000080000009200C00000C0000__000000B3A3EC82C8", +"000000067F000080000009200C00000C0000-000000067F000080000009200C00000C4000__000000B3A3EC82C8", +"000000067F000080000009200C00000C4000-000000067F000080000009200C00000C8000__000000B3A3EC82C8", +"000000067F000080000009200C00000C4B0C-000000067F000080000009200C00000CE272__000000B2CA27F641-000000B3AB3B7FC9", +"000000067F000080000009200C00000C8000-000000067F000080000009200C00000CC000__000000B3A3EC82C8", +"000000067F000080000009200C00000CC000-000000067F000080000009200C00000D0000__000000B3A3EC82C8", +"000000067F000080000009200C00000CE272-000000067F000080000009200C00000D798F__000000B2CA27F641-000000B3AB3B7FC9", +"000000067F000080000009200C00000D0000-000000067F000080000009200C00000D4000__000000B3A3EC82C8", +"000000067F000080000009200C00000D4000-000000067F000080000009200C00000D8000__000000B3A3EC82C8", +"000000067F000080000009200C00000D798F-000000067F000080000009200C00000E10F5__000000B2CA27F641-000000B3AB3B7FC9", +"000000067F000080000009200C00000D8000-000000067F000080000009200C00000DC000__000000B3A3EC82C8", +"000000067F000080000009200C00000DC000-000000067F000080000009200C00000E0000__000000B3A3EC82C8", +"000000067F000080000009200C00000E0000-000000067F000080000009200C00000E4000__000000B3A3EC82C8", +"000000067F000080000009200C00000E10F5-000000067F000080000009200C00000EA80B__000000B2CA27F641-000000B3AB3B7FC9", +"000000067F000080000009200C00000E4000-000000067F000080000009200C00000E8000__000000B3A3EC82C8", +"000000067F000080000009200C00000E8000-000000067F000080000009200C00000EC000__000000B3A3EC82C8", +"000000067F000080000009200C00000EA80B-000000067F000080000009200C00000F3F4B__000000B2CA27F641-000000B3AB3B7FC9", +"000000067F000080000009200C00000EC000-000000067F000080000009200C00000F0000__000000B3A3EC82C8", +"000000067F000080000009200C00000F0000-000000067F000080000009200C00000F4000__000000B3A3EC82C8", +"000000067F000080000009200C00000F3F4B-000000067F000080000009200C00000FD6B1__000000B2CA27F641-000000B3AB3B7FC9", +"000000067F000080000009200C00000F4000-000000067F000080000009200C00000F8000__000000B3A3EC82C8", +"000000067F000080000009200C00000F8000-000000067F000080000009200C00000FC000__000000B3A3EC82C8", +"000000067F000080000009200C00000FC000-000000067F000080000009200C0000100000__000000B3A3EC82C8", +"000000067F000080000009200C00000FD6B1-000000067F000080000009200C0000106DD5__000000B2CA27F641-000000B3AB3B7FC9", +"000000067F000080000009200C0000100000-000000067F000080000009200C0000104000__000000B3A3EC82C8", +"000000067F000080000009200C0000104000-000000067F000080000009200C0000108000__000000B3A3EC82C8", +"000000067F000080000009200C0000106DD5-000000067F000080000009200C000011050B__000000B2CA27F641-000000B3AB3B7FC9", +"000000067F000080000009200C0000108000-000000067F000080000009200C000010C000__000000B3A3EC82C8", +"000000067F000080000009200C000010C000-030000000000000000000000000000000002__000000B3A3EC82C8", +"000000067F000080000009200C000011050B-01000000000000000100000004000000001C__000000B2CA27F641-000000B3AB3B7FC9", +"000000067F00008000000920140000005289-000000067F0000800000092014000000D19A__000000B3AB3B7FC9-000000B4208FF3D1", +"000000067F0000800000092014000000D19A-000000067F000080000009201400000150A9__000000B3AB3B7FC9-000000B4208FF3D1", +"000000067F000080000009201400000150A9-000000067F0000800000092014000001CFBA__000000B3AB3B7FC9-000000B4208FF3D1", +"000000067F0000800000092014000001CFBA-000000067F00008000000920140000024ECB__000000B3AB3B7FC9-000000B4208FF3D1", +"000000067F00008000000920140000024ECB-000000067F0000800000092014000002CDDB__000000B3AB3B7FC9-000000B4208FF3D1", +"000000067F0000800000092014000002CDDB-000000067F000080000009400C000000830C__000000B3AB3B7FC9-000000B4208FF3D1", +"000000067F000080000009400C0000000000-000000067F000080000009400C0000004000__000000B5CED8CF78", +"000000067F000080000009400C0000004000-000000067F000080000009400C0000008000__000000B5CED8CF78", +"000000067F000080000009400C0000008000-000000067F000080000009400C000000C000__000000B5CED8CF78", +"000000067F000080000009400C000000830C-000000067F000080000009400C0000011A72__000000B3AB3B7FC9-000000B4208FF3D1", +"000000067F000080000009400C000000C000-000000067F000080000009400C0000010000__000000B5CED8CF78", +"000000067F000080000009400C0000010000-000000067F000080000009400C0000014000__000000B568835548", +"000000067F000080000009400C0000011A72-030000000000000000000000000000000002__000000B3AB3B7FC9-000000B4208FF3D1", +"000000067F000080000009400C0000012E51-000000067F000080000009400C000001C5B7__000000B4208FF3D1-000000B43089EC11", +"000000067F000080000009400C0000012E51-000000067F000080000009400C000001C5B7__000000B4208FF3D1-000000B4E047E5A9", +"000000067F000080000009400C0000014000-000000067F000080000009400C0000018000__000000B568835548", +"000000067F000080000009400C0000018000-000000067F000080000009400C000001C000__000000B568835548", +"000000067F000080000009400C000001C000-000000067F000080000009400C0000020000__000000B568835548", +"000000067F000080000009400C000001C5B7-000000067F000080000009400C0000025D1D__000000B4208FF3D1-000000B4E047E5A9", +"000000067F000080000009400C000001C5B7-000000067F000080000009400C0100000000__000000B4208FF3D1-000000B43089EC11", +"000000067F000080000009400C0000020000-000000067F000080000009400C0000024000__000000B568835548", +"000000067F000080000009400C0000024000-000000067F000080000009400C0000028000__000000B568835548", +"000000067F000080000009400C0000025D1D-000000067F000080000009400C000002F483__000000B4208FF3D1-000000B4E047E5A9", +"000000067F000080000009400C0000028000-000000067F000080000009400C000002C000__000000B568835548", +"000000067F000080000009400C000002C000-000000067F000080000009400C0000030000__000000B568835548", +"000000067F000080000009400C000002F483-000000067F000080000009400C0000038B96__000000B4208FF3D1-000000B4E047E5A9", +"000000067F000080000009400C0000030000-000000067F000080000009400C0000034000__000000B568835548", +"000000067F000080000009400C0000034000-000000067F000080000009400C0000038000__000000B568835548", +"000000067F000080000009400C0000038000-000000067F000080000009400C000003C000__000000B568835548", +"000000067F000080000009400C0000038B96-000000067F000080000009400C00000422FC__000000B4208FF3D1-000000B4E047E5A9", +"000000067F000080000009400C000003C000-000000067F000080000009400C0000040000__000000B568835548", +"000000067F000080000009400C0000040000-000000067F000080000009400C0000044000__000000B568835548", +"000000067F000080000009400C00000422FC-000000067F000080000009400C000004BA0C__000000B4208FF3D1-000000B4E047E5A9", +"000000067F000080000009400C0000044000-000000067F000080000009400C0000048000__000000B568835548", +"000000067F000080000009400C0000048000-000000067F000080000009400C000004C000__000000B568835548", +"000000067F000080000009400C000004BA0C-000000067F000080000009400C0000055141__000000B4208FF3D1-000000B4E047E5A9", +"000000067F000080000009400C000004C000-000000067F000080000009400C0000050000__000000B568835548", +"000000067F000080000009400C0000050000-000000067F000080000009400C0000054000__000000B568835548", +"000000067F000080000009400C0000054000-000000067F000080000009400C0000058000__000000B568835548", +"000000067F000080000009400C0000055141-000000067F000080000009400C000005E8A7__000000B4208FF3D1-000000B4E047E5A9", +"000000067F000080000009400C0000058000-000000067F000080000009400C000005C000__000000B568835548", +"000000067F000080000009400C000005C000-000000067F000080000009400C0000060000__000000B568835548", +"000000067F000080000009400C000005E8A7-000000067F000080000009400C0000067FC1__000000B4208FF3D1-000000B4E047E5A9", +"000000067F000080000009400C0000060000-000000067F000080000009400C0000064000__000000B568835548", +"000000067F000080000009400C0000064000-000000067F000080000009400C0000068000__000000B568835548", +"000000067F000080000009400C0000067FC1-000000067F000080000009400C0000071709__000000B4208FF3D1-000000B4E047E5A9", +"000000067F000080000009400C0000068000-000000067F000080000009400C000006C000__000000B568835548", +"000000067F000080000009400C000006C000-000000067F000080000009400C0000070000__000000B568835548", +"000000067F000080000009400C0000070000-000000067F000080000009400C0000074000__000000B568835548", +"000000067F000080000009400C0000071709-000000067F000080000009400C000007AE6F__000000B4208FF3D1-000000B4E047E5A9", +"000000067F000080000009400C0000074000-000000067F000080000009400C0000078000__000000B568835548", +"000000067F000080000009400C0000078000-000000067F000080000009400C000007C000__000000B568835548", +"000000067F000080000009400C000007AE6F-000000067F000080000009400C00000845AB__000000B4208FF3D1-000000B4E047E5A9", +"000000067F000080000009400C000007C000-000000067F000080000009400C0000080000__000000B568835548", +"000000067F000080000009400C0000080000-000000067F000080000009400C0000084000__000000B568835548", +"000000067F000080000009400C0000084000-000000067F000080000009400C0000088000__000000B568835548", +"000000067F000080000009400C00000845AB-000000067F000080000009400C0100000000__000000B4208FF3D1-000000B4E047E5A9", +"000000067F000080000009400C0000088000-000000067F000080000009400C000008C000__000000B568835548", +"000000067F000080000009400C000008C000-000000067F000080000009400C0000090000__000000B568835548", +"000000067F000080000009400C000008DEA4-000000067F000080000009400C00000975C4__000000B4E047E5A9-000000B5CED8CF79", +"000000067F000080000009400C0000090000-000000067F000080000009400C0000094000__000000B568835548", +"000000067F000080000009400C0000094000-000000067F000080000009400C0000098000__000000B568835548", +"000000067F000080000009400C00000975C4-000000067F000080000009400C00000A0D0A__000000B4E047E5A9-000000B5CED8CF79", +"000000067F000080000009400C0000098000-000000067F000080000009400C000009C000__000000B568835548", +"000000067F000080000009400C000009C000-000000067F000080000009400C00000A0000__000000B568835548", +"000000067F000080000009400C00000A0000-000000067F000080000009400C00000A4000__000000B568835548", +"000000067F000080000009400C00000A0D0A-000000067F000080000009400C00000AA470__000000B4E047E5A9-000000B5CED8CF79", +"000000067F000080000009400C00000A4000-000000067F000080000009400C00000A8000__000000B568835548", +"000000067F000080000009400C00000A8000-000000067F000080000009400C00000AC000__000000B568835548", +"000000067F000080000009400C00000AA470-000000067F000080000009400C00000B3BB2__000000B4E047E5A9-000000B5CED8CF79", +"000000067F000080000009400C00000AC000-000000067F000080000009400C00000B0000__000000B568835548", +"000000067F000080000009400C00000B0000-000000067F000080000009400C00000B4000__000000B568835548", +"000000067F000080000009400C00000B3BB2-000000067F000080000009400C00000BD30A__000000B4E047E5A9-000000B5CED8CF79", +"000000067F000080000009400C00000B4000-000000067F000080000009400C00000B8000__000000B568835548", +"000000067F000080000009400C00000B8000-000000067F000080000009400C00000BC000__000000B568835548", +"000000067F000080000009400C00000BC000-000000067F000080000009400C00000C0000__000000B568835548", +"000000067F000080000009400C00000BD30A-000000067F000080000009400C00000C6A30__000000B4E047E5A9-000000B5CED8CF79", +"000000067F000080000009400C00000C0000-000000067F000080000009400C00000C4000__000000B568835548", +"000000067F000080000009400C00000C4000-000000067F000080000009400C00000C8000__000000B568835548", +"000000067F000080000009400C00000C6A30-000000067F000080000009400C00000D0194__000000B4E047E5A9-000000B5CED8CF79", +"000000067F000080000009400C00000C8000-000000067F000080000009400C00000CC000__000000B568835548", +"000000067F000080000009400C00000CC000-000000067F000080000009400C00000D0000__000000B568835548", +"000000067F000080000009400C00000D0000-000000067F000080000009400C00000D4000__000000B568835548", +"000000067F000080000009400C00000D0194-000000067F000080000009400C00000D98FA__000000B4E047E5A9-000000B5CED8CF79", +"000000067F000080000009400C00000D4000-030000000000000000000000000000000002__000000B568835548", +"000000067F000080000009400C00000D98FA-000000067F000080000009400C00000E300D__000000B4E047E5A9-000000B5CED8CF79", +"000000067F000080000009400C00000E300D-000000067F000080000009400C00000EC773__000000B4E047E5A9-000000B5CED8CF79", +"000000067F000080000009400C00000EC773-000000067F000080000009400C00000F5ED9__000000B4E047E5A9-000000B5CED8CF79", +"000000067F000080000009400C00000F5ED9-000000067F000080000009400C00000FF60C__000000B4E047E5A9-000000B5CED8CF79", +"000000067F000080000009400C00000FF60C-000000067F000080000009400C0000108D1D__000000B4E047E5A9-000000B5CED8CF79", +"000000067F000080000009400C0000108D1D-000000067F000080000009400C0000111C20__000000B4E047E5A9-000000B5CED8CF79", +"000000067F000080000009400C00FFFFFFFF-030000000000000000000000000000000002__000000B4E047E5A9-000000B5CED8CF79", +"000000067F000080000009600C0000000000-000000067F000080000009600C0000004000__000000B79F439FE0", +"000000067F000080000009600C0000004000-000000067F000080000009600C0000008000__000000B79F439FE0", +"000000067F000080000009600C0000008000-000000067F000080000009600C000000C000__000000B79F439FE0", +"000000067F000080000009600C000000974F-000000067F000080000009600C0000012EB5__000000B5CED8CF79-000000B63EADE5B9", +"000000067F000080000009600C000000C000-000000067F000080000009600C0000010000__000000B79F439FE0", +"000000067F000080000009600C0000010000-000000067F000080000009600C0000014000__000000B79F439FE0", +"000000067F000080000009600C0000012EB5-000000067F000080000009600C000001C60A__000000B5CED8CF79-000000B63EADE5B9", +"000000067F000080000009600C0000014000-000000067F000080000009600C0000018000__000000B79F439FE0", +"000000067F000080000009600C0000018000-000000067F000080000009600C000001C000__000000B79F439FE0", +"000000067F000080000009600C000001C000-000000067F000080000009600C0000020000__000000B79F439FE0", +"000000067F000080000009600C000001C60A-000000067F000080000009600C0000025D38__000000B5CED8CF79-000000B63EADE5B9", +"000000067F000080000009600C0000020000-000000067F000080000009600C0000024000__000000B79F439FE0", +"000000067F000080000009600C0000024000-000000067F000080000009600C0000028000__000000B79F439FE0", +"000000067F000080000009600C0000025D38-000000067F000080000009600C000002F49E__000000B5CED8CF79-000000B63EADE5B9", +"000000067F000080000009600C0000028000-000000067F000080000009600C000002C000__000000B79F439FE0", +"000000067F000080000009600C000002C000-000000067F000080000009600C0000030000__000000B79F439FE0", +"000000067F000080000009600C000002F49E-000000067F000080000009600C0000038BB1__000000B5CED8CF79-000000B63EADE5B9", +"000000067F000080000009600C0000030000-000000067F000080000009600C0000034000__000000B79F439FE0", +"000000067F000080000009600C0000034000-000000067F000080000009600C0000038000__000000B79F439FE0", +"000000067F000080000009600C0000038000-000000067F000080000009600C000003C000__000000B79F439FE0", +"000000067F000080000009600C0000038BB1-000000067F000080000009600C0000042317__000000B5CED8CF79-000000B63EADE5B9", +"000000067F000080000009600C000003C000-000000067F000080000009600C0000040000__000000B79F439FE0", +"000000067F000080000009600C0000040000-000000067F000080000009600C0000044000__000000B79D17BFD0", +"000000067F000080000009600C0000040000-000000067F000080000009600C0000044000__000000B8606C92A0", +"000000067F000080000009600C0000042317-030000000000000000000000000000000002__000000B5CED8CF79-000000B63EADE5B9", +"000000067F000080000009600C000004236E-000000067F000080000009600C000004BAD4__000000B63EADE5B9-000000B6DE71F5F9", +"000000067F000080000009600C0000044000-000000067F000080000009600C0000048000__000000B79D17BFD0", +"000000067F000080000009600C0000044000-000000067F000080000009600C0000048000__000000B8606C92A0", +"000000067F000080000009600C0000048000-000000067F000080000009600C000004C000__000000B79D17BFD0", +"000000067F000080000009600C0000048000-000000067F000080000009600C000004C000__000000B8606C92A0", +"000000067F000080000009600C000004BAD4-000000067F000080000009600C0000055208__000000B63EADE5B9-000000B6DE71F5F9", +"000000067F000080000009600C000004C000-000000067F000080000009600C0000050000__000000B79D17BFD0", +"000000067F000080000009600C000004C000-000000067F000080000009600C0000050000__000000B8606C92A0", +"000000067F000080000009600C0000050000-000000067F000080000009600C0000054000__000000B79D17BFD0", +"000000067F000080000009600C0000050000-000000067F000080000009600C0000054000__000000B8606C92A0", +"000000067F000080000009600C0000054000-000000067F000080000009600C0000058000__000000B79D17BFD0", +"000000067F000080000009600C0000054000-000000067F000080000009600C0000058000__000000B8606C92A0", +"000000067F000080000009600C0000055208-000000067F000080000009600C000005E96E__000000B63EADE5B9-000000B6DE71F5F9", +"000000067F000080000009600C0000055A77-000000067F000080000009600C00000AAEA5__000000B808718889-000000B8606C92A1", +"000000067F000080000009600C0000058000-000000067F000080000009600C000005C000__000000B79D17BFD0", +"000000067F000080000009600C0000058000-000000067F000080000009600C000005C000__000000B8606C92A0", +"000000067F000080000009600C000005C000-000000067F000080000009600C0000060000__000000B79D17BFD0", +"000000067F000080000009600C000005C000-000000067F000080000009600C0000060000__000000B8606C92A0", +"000000067F000080000009600C000005E96E-000000067F000080000009600C00000680D4__000000B63EADE5B9-000000B6DE71F5F9", +"000000067F000080000009600C0000060000-000000067F000080000009600C0000064000__000000B79D17BFD0", +"000000067F000080000009600C0000060000-000000067F000080000009600C0000064000__000000B8606C92A0", +"000000067F000080000009600C0000064000-000000067F000080000009600C0000068000__000000B79D17BFD0", +"000000067F000080000009600C0000064000-000000067F000080000009600C0000068000__000000B8606C92A0", +"000000067F000080000009600C0000068000-000000067F000080000009600C000006C000__000000B79D17BFD0", +"000000067F000080000009600C0000068000-000000067F000080000009600C000006C000__000000B8606C92A0", +"000000067F000080000009600C00000680D4-000000067F000080000009600C000007180B__000000B63EADE5B9-000000B6DE71F5F9", +"000000067F000080000009600C000006C000-000000067F000080000009600C0000070000__000000B79D17BFD0", +"000000067F000080000009600C000006C000-000000067F000080000009600C0000070000__000000B8606C92A0", +"000000067F000080000009600C0000070000-000000067F000080000009600C0000074000__000000B79D17BFD0", +"000000067F000080000009600C0000070000-000000067F000080000009600C0000074000__000000B8606C92A0", +"000000067F000080000009600C000007180B-000000067F000080000009600C000007AF71__000000B63EADE5B9-000000B6DE71F5F9", +"000000067F000080000009600C0000074000-000000067F000080000009600C0000078000__000000B79D17BFD0", +"000000067F000080000009600C0000074000-000000067F000080000009600C0000078000__000000B8606C92A0", +"000000067F000080000009600C0000078000-000000067F000080000009600C000007C000__000000B79D17BFD0", +"000000067F000080000009600C0000078000-000000067F000080000009600C000007C000__000000B8606C92A0", +"000000067F000080000009600C000007AF71-000000067F000080000009600C00000846D7__000000B63EADE5B9-000000B6DE71F5F9", +"000000067F000080000009600C000007C000-000000067F000080000009600C0000080000__000000B79D17BFD0", +"000000067F000080000009600C000007C000-000000067F000080000009600C0000080000__000000B8606C92A0", +"000000067F000080000009600C0000080000-000000067F000080000009600C0000084000__000000B79D17BFD0", +"000000067F000080000009600C0000080000-000000067F000080000009600C0000084000__000000B8606C92A0", +"000000067F000080000009600C0000084000-000000067F000080000009600C0000088000__000000B79D17BFD0", +"000000067F000080000009600C0000084000-000000067F000080000009600C0000088000__000000B8606C92A0", +"000000067F000080000009600C00000846D7-000000067F000080000009600C000008DE0C__000000B63EADE5B9-000000B6DE71F5F9", +"000000067F000080000009600C0000088000-000000067F000080000009600C000008C000__000000B79D17BFD0", +"000000067F000080000009600C0000088000-000000067F000080000009600C000008C000__000000B8606C92A0", +"000000067F000080000009600C000008C000-000000067F000080000009600C0000090000__000000B79D17BFD0", +"000000067F000080000009600C000008C000-000000067F000080000009600C0000090000__000000B8606C92A0", +"000000067F000080000009600C000008DE0C-000000067F000080000009600C000009752C__000000B63EADE5B9-000000B6DE71F5F9", +"000000067F000080000009600C0000090000-000000067F000080000009600C0000094000__000000B79D17BFD0", +"000000067F000080000009600C0000090000-000000067F000080000009600C0000094000__000000B8606C92A0", +"000000067F000080000009600C0000094000-000000067F000080000009600C0000098000__000000B79D17BFD0", +"000000067F000080000009600C0000094000-000000067F000080000009600C0000098000__000000B8606C92A0", +"000000067F000080000009600C000009752C-000000067F000080000009600C00000A0C92__000000B63EADE5B9-000000B6DE71F5F9", +"000000067F000080000009600C0000098000-000000067F000080000009600C000009C000__000000B79D17BFD0", +"000000067F000080000009600C0000098000-000000067F000080000009600C000009C000__000000B8606C92A0", +"000000067F000080000009600C000009C000-000000067F000080000009600C00000A0000__000000B79D17BFD0", +"000000067F000080000009600C000009C000-000000067F000080000009600C00000A0000__000000B8606C92A0", +"000000067F000080000009600C00000A0000-000000067F000080000009600C00000A4000__000000B79D17BFD0", +"000000067F000080000009600C00000A0000-000000067F000080000009600C00000A4000__000000B8606C92A0", +"000000067F000080000009600C00000A0C92-000000067F000080000009600C0100000000__000000B63EADE5B9-000000B6DE71F5F9", +"000000067F000080000009600C00000A4000-000000067F000080000009600C00000A8000__000000B79D17BFD0", +"000000067F000080000009600C00000A4000-000000067F000080000009600C00000A8000__000000B8606C92A0", +"000000067F000080000009600C00000A8000-000000067F000080000009600C00000AC000__000000B79D17BFD0", +"000000067F000080000009600C00000A8000-000000067F000080000009600C00000AC000__000000B8606C92A0", +"000000067F000080000009600C00000A93FD-000000067F000080000009600C00000B2B0C__000000B6DE71F5F9-000000B79E68FFF9", +"000000067F000080000009600C00000AAEA5-000000067F000080000009600C0000101445__000000B808718889-000000B8606C92A1", +"000000067F000080000009600C00000AC000-000000067F000080000009600C00000B0000__000000B79D17BFD0", +"000000067F000080000009600C00000AC000-000000067F000080000009600C00000B0000__000000B8606C92A0", +"000000067F000080000009600C00000B0000-000000067F000080000009600C00000B4000__000000B79D17BFD0", +"000000067F000080000009600C00000B0000-000000067F000080000009600C00000B4000__000000B8606C92A0", +"000000067F000080000009600C00000B2B0C-000000067F000080000009600C00000BC272__000000B6DE71F5F9-000000B79E68FFF9", +"000000067F000080000009600C00000B4000-000000067F000080000009600C00000B8000__000000B79D17BFD0", +"000000067F000080000009600C00000B4000-000000067F000080000009600C00000B8000__000000B8606C92A0", +"000000067F000080000009600C00000B8000-000000067F000080000009600C00000BC000__000000B79D17BFD0", +"000000067F000080000009600C00000B8000-000000067F000080000009600C00000BC000__000000B8606C92A0", +"000000067F000080000009600C00000BC000-000000067F000080000009600C00000C0000__000000B79D17BFD0", +"000000067F000080000009600C00000BC000-000000067F000080000009600C00000C0000__000000B8606C92A0", +"000000067F000080000009600C00000BC272-000000067F000080000009600C00000C59A2__000000B6DE71F5F9-000000B79E68FFF9", +"000000067F000080000009600C00000C0000-000000067F000080000009600C00000C4000__000000B79D17BFD0", +"000000067F000080000009600C00000C0000-000000067F000080000009600C00000C4000__000000B8606C92A0", +"000000067F000080000009600C00000C4000-000000067F000080000009600C00000C8000__000000B79D17BFD0", +"000000067F000080000009600C00000C4000-000000067F000080000009600C00000C8000__000000B8606C92A0", +"000000067F000080000009600C00000C59A2-000000067F000080000009600C00000CF108__000000B6DE71F5F9-000000B79E68FFF9", +"000000067F000080000009600C00000C8000-000000067F000080000009600C00000CC000__000000B79D17BFD0", +"000000067F000080000009600C00000C8000-000000067F000080000009600C00000CC000__000000B8606C92A0", +"000000067F000080000009600C00000CC000-000000067F000080000009600C00000D0000__000000B79D17BFD0", +"000000067F000080000009600C00000CC000-000000067F000080000009600C00000D0000__000000B8606C92A0", +"000000067F000080000009600C00000CF108-000000067F000080000009600C00000D882B__000000B6DE71F5F9-000000B79E68FFF9", +"000000067F000080000009600C00000D0000-000000067F000080000009600C00000D4000__000000B79D17BFD0", +"000000067F000080000009600C00000D0000-000000067F000080000009600C00000D4000__000000B8606C92A0", +"000000067F000080000009600C00000D4000-000000067F000080000009600C00000D8000__000000B79D17BFD0", +"000000067F000080000009600C00000D4000-000000067F000080000009600C00000D8000__000000B8606C92A0", +"000000067F000080000009600C00000D8000-000000067F000080000009600C00000DC000__000000B79D17BFD0", +"000000067F000080000009600C00000D8000-000000067F000080000009600C00000DC000__000000B8606C92A0", +"000000067F000080000009600C00000D882B-000000067F000080000009600C00000E1F7E__000000B6DE71F5F9-000000B79E68FFF9", +"000000067F000080000009600C00000DC000-000000067F000080000009600C00000E0000__000000B79D17BFD0", +"000000067F000080000009600C00000DC000-000000067F000080000009600C00000E0000__000000B8606C92A0", +"000000067F000080000009600C00000E0000-000000067F000080000009600C00000E4000__000000B79D17BFD0", +"000000067F000080000009600C00000E0000-000000067F000080000009600C00000E4000__000000B8606C92A0", +"000000067F000080000009600C00000E1F7E-000000067F000080000009600C00000EB6E4__000000B6DE71F5F9-000000B79E68FFF9", +"000000067F000080000009600C00000E4000-000000067F000080000009600C00000E8000__000000B79D17BFD0", +"000000067F000080000009600C00000E4000-000000067F000080000009600C00000E8000__000000B8606C92A0", +"000000067F000080000009600C00000E8000-000000067F000080000009600C00000EC000__000000B79D17BFD0", +"000000067F000080000009600C00000E8000-000000067F000080000009600C00000EC000__000000B8606C92A0", +"000000067F000080000009600C00000EB6E4-000000067F000080000009600C00000F4E0B__000000B6DE71F5F9-000000B79E68FFF9", +"000000067F000080000009600C00000EC000-000000067F000080000009600C00000F0000__000000B79D17BFD0", +"000000067F000080000009600C00000EC000-000000067F000080000009600C00000F0000__000000B8606C92A0", +"000000067F000080000009600C00000F0000-000000067F000080000009600C00000F4000__000000B79D17BFD0", +"000000067F000080000009600C00000F0000-000000067F000080000009600C00000F4000__000000B8606C92A0", +"000000067F000080000009600C00000F4000-000000067F000080000009600C00000F8000__000000B79D17BFD0", +"000000067F000080000009600C00000F4000-000000067F000080000009600C00000F8000__000000B8606C92A0", +"000000067F000080000009600C00000F4E0B-000000067F000080000009600C00000FE571__000000B6DE71F5F9-000000B79E68FFF9", +"000000067F000080000009600C00000F8000-000000067F000080000009600C00000FC000__000000B79D17BFD0", +"000000067F000080000009600C00000F8000-000000067F000080000009600C00000FC000__000000B8606C92A0", +"000000067F000080000009600C00000FC000-000000067F000080000009600C0000100000__000000B79D17BFD0", +"000000067F000080000009600C00000FC000-000000067F000080000009600C0000100000__000000B8606C92A0", +"000000067F000080000009600C00000FE571-000000067F000080000009600C0000107CD7__000000B6DE71F5F9-000000B79E68FFF9", +"000000067F000080000009600C0000100000-000000067F000080000009600C0000104000__000000B79D17BFD0", +"000000067F000080000009600C0000100000-000000067F000080000009600C0000104000__000000B8606C92A0", +"000000067F000080000009600C000010144D-000000067F0000800000096014000000E7D9__000000B808718889-000000B8606C92A1", +"000000067F000080000009600C0000104000-000000067F000080000009600C0000108000__000000B79D17BFD0", +"000000067F000080000009600C0000104000-000000067F000080000009600C0000108000__000000B8606C92A0", +"000000067F000080000009600C0000107CD7-000000067F000080000009600C000011140C__000000B6DE71F5F9-000000B79E68FFF9", +"000000067F000080000009600C0000108000-000000067F000080000009600C000010C000__000000B79D17BFD0", +"000000067F000080000009600C0000108000-000000067F000080000009600C000010C000__000000B8606C92A0", +"000000067F000080000009600C000010C000-000000067F000080000009600C0000110000__000000B79D17BFD0", +"000000067F000080000009600C000010C000-000000067F000080000009600C0000110000__000000B8606C92A0", +"000000067F000080000009600C0000110000-000000067F00008000000960120100000000__000000B8606C92A0", +"000000067F000080000009600C0000110000-030000000000000000000000000000000002__000000B79D17BFD0", +"000000067F000080000009600C000011140C-01000000000000000100000004000000001C__000000B6DE71F5F9-000000B79E68FFF9", +"000000067F000080000009600C020000000B-000000067F0000800000096014000000571F__000000B79E68FFF9-000000B808718889", +"000000067F00008000000960140000000000-000000067F00008000000960140000004000__000000B8606C92A0", +"000000067F00008000000960140000004000-000000067F00008000000960140000008000__000000B8606C92A0", +"000000067F0000800000096014000000571F-000000067F0000800000096014000000CB61__000000B79E68FFF9-000000B808718889", +"000000067F00008000000960140000008000-000000067F0000800000096014000000C000__000000B8606C92A0", +"000000067F0000800000096014000000C000-000000067F00008000000960140000010000__000000B8606C92A0", +"000000067F0000800000096014000000CB61-000000067F00008000000960140000013F98__000000B79E68FFF9-000000B808718889", +"000000067F0000800000096014000000E7DB-000000067F00008000000960140000022A8D__000000B808718889-000000B8606C92A1", +"000000067F00008000000960140000010000-000000067F00008000000960140000014000__000000B8606C92A0", +"000000067F00008000000960140000013F98-000000067F0000800000096014000001B3C2__000000B79E68FFF9-000000B808718889", +"000000067F00008000000960140000014000-000000067F00008000000960140000018000__000000B8606C92A0", +"000000067F00008000000960140000018000-000000067F0000800000096014000001C000__000000B8606C92A0", +"000000067F0000800000096014000001B3C2-000000067F000080000009601400000227FC__000000B79E68FFF9-000000B808718889", +"000000067F0000800000096014000001C000-000000067F00008000000960140000020000__000000B8606C92A0", +"000000067F00008000000960140000020000-000000067F00008000000960140000024000__000000B8606C92A0", +"000000067F000080000009601400000227FC-000000067F00008000000960140000029BD8__000000B79E68FFF9-000000B808718889", +"000000067F00008000000960140000022A8D-030000000000000000000000000000000002__000000B808718889-000000B8606C92A1", +"000000067F00008000000960140000024000-000000067F00008000000960140000028000__000000B8606C92A0", +"000000067F00008000000960140000028000-000000067F0000800000096014000002C000__000000B8606C92A0", +"000000067F00008000000960140000029BD8-030000000000000000000000000000000002__000000B79E68FFF9-000000B808718889", +"000000067F0000800000096014000002C000-030000000000000000000000000000000002__000000B8606C92A0", +"000000067F000080000009800C0000009748-000000067F000080000009800C0000012EAE__000000B8606C92A1-000000B8E03BF0B9", +"000000067F000080000009800C0000012EAE-000000067F000080000009800C000001C60A__000000B8606C92A1-000000B8E03BF0B9", +"000000067F000080000009800C000001C60A-000000067F000080000009800C0000025D38__000000B8606C92A1-000000B8E03BF0B9", +"000000067F000080000009800C0000025D38-000000067F000080000009800C000002F49E__000000B8606C92A1-000000B8E03BF0B9", +"000000067F000080000009800C000002F49E-000000067F000080000009800C0000038BB1__000000B8606C92A1-000000B8E03BF0B9", +"000000067F000080000009800C0000038BB1-000000067F000080000009800C0000042317__000000B8606C92A1-000000B8E03BF0B9", +"000000067F000080000009800C0000042317-000000067F000080000009800C000004BA7D__000000B8606C92A1-000000B8E03BF0B9", +"000000067F000080000009800C000004BA7D-030000000000000000000000000000000002__000000B8606C92A1-000000B8E03BF0B9", +"000000067F000080000009800C000004BAD2-000000067F000080000009800C0000055206__000000B8E03BF0B9-000000B97FFFFFE9", +"000000067F000080000009800C0000055206-000000067F000080000009800C000005E911__000000B8E03BF0B9-000000B97FFFFFE9", +"000000067F000080000009800C000005E911-000000067F000080000009800C000006802B__000000B8E03BF0B9-000000B97FFFFFE9", +"000000067F000080000009800C000006802B-000000067F000080000009800C0000071782__000000B8E03BF0B9-000000B97FFFFFE9", +"000000067F000080000009800C0000071782-000000067F000080000009800C000007AEE8__000000B8E03BF0B9-000000B97FFFFFE9", +"000000067F000080000009800C000007AEE8-000000067F000080000009800C000008460B__000000B8E03BF0B9-000000B97FFFFFE9", +"000000067F000080000009800C000008460B-000000067F000080000009800C000008DD71__000000B8E03BF0B9-000000B97FFFFFE9", +"000000067F000080000009800C000008DD71-000000067F000080000009800C00000974D7__000000B8E03BF0B9-000000B97FFFFFE9", +"000000067F000080000009800C00000974D7-000000067F000080000009800C00000A0C0B__000000B8E03BF0B9-000000B97FFFFFE9", +"000000067F000080000009800C00000A0C0B-000000067F000080000009800C00000AA371__000000B8E03BF0B9-000000B97FFFFFE9", +"000000067F000080000009800C00000A8000-000000067F000080000009800C00000AC000__000000BA2E67EA20", +"000000067F000080000009800C00000AA371-000000067F000080000009800C0100000000__000000B8E03BF0B9-000000B97FFFFFE9", +"000000067F000080000009800C00000AA4F5-000000067F000080000009800C00000B3C0B__000000B97FFFFFE9-000000BA1FC3FB39", +"000000067F000080000009800C00000AC000-000000067F000080000009800C00000B0000__000000BA2E67EA20", +"000000067F000080000009800C00000B0000-000000067F000080000009800C00000B4000__000000BA2E67EA20", +"000000067F000080000009800C00000B3C0B-000000067F000080000009800C00000BD371__000000B97FFFFFE9-000000BA1FC3FB39", +"000000067F000080000009800C00000B4000-000000067F000080000009800C00000B8000__000000BA2E67EA20", +"000000067F000080000009800C00000B8000-000000067F000080000009800C00000BC000__000000BA2E67EA20", +"000000067F000080000009800C00000BC000-000000067F000080000009800C00000C0000__000000BA2E67EA20", +"000000067F000080000009800C00000BD371-000000067F000080000009800C00000C6AD7__000000B97FFFFFE9-000000BA1FC3FB39", +"000000067F000080000009800C00000C0000-000000067F000080000009800C00000C4000__000000BA2E67EA20", +"000000067F000080000009800C00000C4000-000000067F000080000009800C00000C8000__000000BA2E67EA20", +"000000067F000080000009800C00000C6AD7-000000067F000080000009800C00000D020B__000000B97FFFFFE9-000000BA1FC3FB39", +"000000067F000080000009800C00000C8000-000000067F000080000009800C00000CC000__000000BA2E67EA20", +"000000067F000080000009800C00000CC000-000000067F000080000009800C00000D0000__000000BA2E67EA20", +"000000067F000080000009800C00000D0000-000000067F000080000009800C00000D4000__000000BA2E67EA20", +"000000067F000080000009800C00000D020B-000000067F000080000009800C00000D9971__000000B97FFFFFE9-000000BA1FC3FB39", +"000000067F000080000009800C00000D4000-000000067F000080000009800C00000D8000__000000BA2E67EA20", +"000000067F000080000009800C00000D8000-000000067F000080000009800C00000DC000__000000BA2E67EA20", +"000000067F000080000009800C00000D9971-000000067F000080000009800C00000E30D7__000000B97FFFFFE9-000000BA1FC3FB39", +"000000067F000080000009800C00000DC000-000000067F000080000009800C00000E0000__000000BA2E67EA20", +"000000067F000080000009800C00000E0000-000000067F000080000009800C00000E4000__000000BA2E67EA20", +"000000067F000080000009800C00000E30D7-000000067F000080000009800C00000EC80B__000000B97FFFFFE9-000000BA1FC3FB39", +"000000067F000080000009800C00000E4000-000000067F000080000009800C00000E8000__000000BA2E67EA20", +"000000067F000080000009800C00000E8000-000000067F000080000009800C00000EC000__000000BA2E67EA20", +"000000067F000080000009800C00000EC000-000000067F000080000009800C00000F0000__000000BA2E67EA20", +"000000067F000080000009800C00000EC80B-000000067F000080000009800C00000F5F38__000000B97FFFFFE9-000000BA1FC3FB39", +"000000067F000080000009800C00000F0000-000000067F000080000009800C00000F4000__000000BA2E67EA20", +"000000067F000080000009800C00000F4000-000000067F000080000009800C00000F8000__000000BA2E67EA20", +"000000067F000080000009800C00000F5F38-000000067F000080000009800C00000FF69E__000000B97FFFFFE9-000000BA1FC3FB39", +"000000067F000080000009800C00000F8000-000000067F000080000009800C00000FC000__000000BA2E67EA20", +"000000067F000080000009800C00000FC000-000000067F000080000009800C0000100000__000000BA2E67EA20", +"000000067F000080000009800C00000FF69E-000000067F000080000009800C0000108DAF__000000B97FFFFFE9-000000BA1FC3FB39", +"000000067F000080000009800C0000100000-000000067F000080000009800C0000104000__000000BA2E67EA20", +"000000067F000080000009800C0000104000-000000067F000080000009800C0000108000__000000BA2E67EA20", +"000000067F000080000009800C0000108000-000000067F000080000009800C000010C000__000000BA2E67EA20", +"000000067F000080000009800C0000108DAF-000000067F000080000009800F0100000003__000000B97FFFFFE9-000000BA1FC3FB39", +"000000067F000080000009800C000010C000-000000067F000080000009800C0000110000__000000BA2E67EA20", +"000000067F000080000009800C000010EC71-000000067F000080000009801400000025C3__000000BA1FC3FB39-000000BA9685E7C1", +"000000067F000080000009800C0000110000-030000000000000000000000000000000002__000000BA2E67EA20", +"000000067F000080000009801400000025C3-000000067F0000800000098014000000A4D3__000000BA1FC3FB39-000000BA9685E7C1", +"000000067F0000800000098014000000A4D3-000000067F000080000009801400000123E4__000000BA1FC3FB39-000000BA9685E7C1", +"000000067F000080000009801400000123E4-000000067F0000800000098014000001A2F3__000000BA1FC3FB39-000000BA9685E7C1", +"000000067F0000800000098014000001A2F3-000000067F00008000000980140000022204__000000BA1FC3FB39-000000BA9685E7C1", +"000000067F00008000000980140000022204-000000067F0000800000098014000002A114__000000BA1FC3FB39-000000BA9685E7C1", +"000000067F0000800000098014000002A114-000000067F000080000009A00C0000004DB3__000000BA1FC3FB39-000000BA9685E7C1", +"000000067F000080000009A00C0000000000-000000067F000080000009A00C0000004000__000000BCEF79BE90", +"000000067F000080000009A00C0000004000-000000067F000080000009A00C0000008000__000000BCEF79BE90", +"000000067F000080000009A00C0000004DB3-030000000000000000000000000000000002__000000BA1FC3FB39-000000BA9685E7C1", +"000000067F000080000009A00C0000008000-000000067F000080000009A00C000000C000__000000BC59629F98", +"000000067F000080000009A00C0000008000-000000067F000080000009A00C000000C000__000000BD25E66810", +"000000067F000080000009A00C00000096E8-000000067F000080000009A00C0000012E0B__000000BA9685E7C1-000000BB4643FBD1", +"000000067F000080000009A00C000000C000-000000067F000080000009A00C0000010000__000000BC59629F98", +"000000067F000080000009A00C000000C000-000000067F000080000009A00C0000010000__000000BD25E66810", +"000000067F000080000009A00C0000010000-000000067F000080000009A00C0000014000__000000BC59629F98", +"000000067F000080000009A00C0000010000-000000067F000080000009A00C0000014000__000000BD25E66810", +"000000067F000080000009A00C0000012E0B-000000067F000080000009A00C000001C571__000000BA9685E7C1-000000BB4643FBD1", +"000000067F000080000009A00C0000014000-000000067F000080000009A00C0000018000__000000BC59629F98", +"000000067F000080000009A00C0000014000-000000067F000080000009A00C0000018000__000000BD25E66810", +"000000067F000080000009A00C0000018000-000000067F000080000009A00C000001C000__000000BC59629F98", +"000000067F000080000009A00C0000018000-000000067F000080000009A00C000001C000__000000BD25E66810", +"000000067F000080000009A00C000001C000-000000067F000080000009A00C0000020000__000000BC59629F98", +"000000067F000080000009A00C000001C000-000000067F000080000009A00C0000020000__000000BD25E66810", +"000000067F000080000009A00C000001C571-000000067F000080000009A00C0000025CD7__000000BA9685E7C1-000000BB4643FBD1", +"000000067F000080000009A00C0000020000-000000067F000080000009A00C0000024000__000000BC59629F98", +"000000067F000080000009A00C0000020000-000000067F000080000009A00C0000024000__000000BD25E66810", +"000000067F000080000009A00C0000024000-000000067F000080000009A00C0000028000__000000BC59629F98", +"000000067F000080000009A00C0000024000-000000067F000080000009A00C0000028000__000000BD25E66810", +"000000067F000080000009A00C0000025CD7-000000067F000080000009A00C000002F40B__000000BA9685E7C1-000000BB4643FBD1", +"000000067F000080000009A00C0000028000-000000067F000080000009A00C000002C000__000000BC59629F98", +"000000067F000080000009A00C0000028000-000000067F000080000009A00C000002C000__000000BD25E66810", +"000000067F000080000009A00C000002C000-000000067F000080000009A00C0000030000__000000BC59629F98", +"000000067F000080000009A00C000002C000-000000067F000080000009A00C0000030000__000000BD25E66810", +"000000067F000080000009A00C000002F40B-000000067F000080000009A00C0000038B1E__000000BA9685E7C1-000000BB4643FBD1", +"000000067F000080000009A00C0000030000-000000067F000080000009A00C0000034000__000000BC59629F98", +"000000067F000080000009A00C0000030000-000000067F000080000009A00C0000034000__000000BD25E66810", +"000000067F000080000009A00C0000034000-000000067F000080000009A00C0000038000__000000BC59629F98", +"000000067F000080000009A00C0000034000-000000067F000080000009A00C0000038000__000000BD25E66810", +"000000067F000080000009A00C0000038000-000000067F000080000009A00C000003C000__000000BC59629F98", +"000000067F000080000009A00C0000038000-000000067F000080000009A00C000003C000__000000BD25E66810", +"000000067F000080000009A00C0000038B1E-000000067F000080000009A00C0000042284__000000BA9685E7C1-000000BB4643FBD1", +"000000067F000080000009A00C000003C000-000000067F000080000009A00C0000040000__000000BC59629F98", +"000000067F000080000009A00C000003C000-000000067F000080000009A00C0000040000__000000BD25E66810", +"000000067F000080000009A00C0000040000-000000067F000080000009A00C0000044000__000000BC59629F98", +"000000067F000080000009A00C0000040000-000000067F000080000009A00C0000044000__000000BD25E66810", +"000000067F000080000009A00C0000042284-000000067F000080000009A00C000004B9EA__000000BA9685E7C1-000000BB4643FBD1", +"000000067F000080000009A00C0000044000-000000067F000080000009A00C0000048000__000000BC59629F98", +"000000067F000080000009A00C0000044000-000000067F000080000009A00C0000048000__000000BD25E66810", +"000000067F000080000009A00C0000048000-000000067F000080000009A00C000004C000__000000BC59629F98", +"000000067F000080000009A00C0000048000-000000067F000080000009A00C000004C000__000000BD25E66810", +"000000067F000080000009A00C000004B9EA-000000067F000080000009A00C000005510B__000000BA9685E7C1-000000BB4643FBD1", +"000000067F000080000009A00C000004C000-000000067F000080000009A00C0000050000__000000BC59629F98", +"000000067F000080000009A00C000004C000-000000067F000080000009A00C0000050000__000000BD25E66810", +"000000067F000080000009A00C0000050000-000000067F000080000009A00C0000054000__000000BC59629F98", +"000000067F000080000009A00C0000050000-000000067F000080000009A00C0000054000__000000BD25E66810", +"000000067F000080000009A00C0000054000-000000067F000080000009A00C0000058000__000000BC59629F98", +"000000067F000080000009A00C0000054000-000000067F000080000009A00C0000058000__000000BD25E66810", +"000000067F000080000009A00C000005510B-000000067F000080000009A00C000005E871__000000BA9685E7C1-000000BB4643FBD1", +"000000067F000080000009A00C0000058000-000000067F000080000009A00C000005C000__000000BC59629F98", +"000000067F000080000009A00C0000058000-000000067F000080000009A00C000005C000__000000BD25E66810", +"000000067F000080000009A00C000005C000-000000067F000080000009A00C0000060000__000000BC59629F98", +"000000067F000080000009A00C000005C000-000000067F000080000009A00C0000060000__000000BD25E66810", +"000000067F000080000009A00C000005E871-000000067F000080000009A00C0000067F8B__000000BA9685E7C1-000000BB4643FBD1", +"000000067F000080000009A00C0000060000-000000067F000080000009A00C0000064000__000000BC59629F98", +"000000067F000080000009A00C0000060000-000000067F000080000009A00C0000064000__000000BD25E66810", +"000000067F000080000009A00C0000064000-000000067F000080000009A00C0000068000__000000BC59629F98", +"000000067F000080000009A00C0000064000-000000067F000080000009A00C0000068000__000000BD25E66810", +"000000067F000080000009A00C0000067F8B-000000067F000080000009A00C00000716F1__000000BA9685E7C1-000000BB4643FBD1", +"000000067F000080000009A00C0000068000-000000067F000080000009A00C000006C000__000000BC59629F98", +"000000067F000080000009A00C0000068000-000000067F000080000009A00C000006C000__000000BD25E66810", +"000000067F000080000009A00C000006C000-000000067F000080000009A00C0000070000__000000BC59629F98", +"000000067F000080000009A00C000006C000-000000067F000080000009A00C0000070000__000000BD25E66810", +"000000067F000080000009A00C0000070000-000000067F000080000009A00C0000074000__000000BC53F74828", +"000000067F000080000009A00C0000070000-000000067F000080000009A00C0000074000__000000BD25E66810", +"000000067F000080000009A00C00000716F1-000000067F000080000009A00C0100000000__000000BA9685E7C1-000000BB4643FBD1", +"000000067F000080000009A00C0000071875-000000067F000080000009A00C000007AFDB__000000BB4643FBD1-000000BBE607E8F1", +"000000067F000080000009A00C0000071F8D-000000067F000080000009A00C00000E4F8F__000000BCEF79BE91-000000BD263A5849", +"000000067F000080000009A00C0000074000-000000067F000080000009A00C0000078000__000000BC53F74828", +"000000067F000080000009A00C0000074000-000000067F000080000009A00C0000078000__000000BD25E66810", +"000000067F000080000009A00C0000078000-000000067F000080000009A00C000007C000__000000BC53F74828", +"000000067F000080000009A00C0000078000-000000067F000080000009A00C000007C000__000000BD25E66810", +"000000067F000080000009A00C00000794E0-000000067F000080000009A00C00000F2480__000000BC596B5D59-000000BCEF79BE91", +"000000067F000080000009A00C000007AFDB-000000067F000080000009A00C000008470A__000000BB4643FBD1-000000BBE607E8F1", +"000000067F000080000009A00C000007C000-000000067F000080000009A00C0000080000__000000BC53F74828", +"000000067F000080000009A00C000007C000-000000067F000080000009A00C0000080000__000000BD25E66810", +"000000067F000080000009A00C0000080000-000000067F000080000009A00C0000084000__000000BC53F74828", +"000000067F000080000009A00C0000080000-000000067F000080000009A00C0000084000__000000BD25E66810", +"000000067F000080000009A00C0000084000-000000067F000080000009A00C0000088000__000000BC53F74828", +"000000067F000080000009A00C0000084000-000000067F000080000009A00C0000088000__000000BD25E66810", +"000000067F000080000009A00C000008470A-000000067F000080000009A00C000008DE70__000000BB4643FBD1-000000BBE607E8F1", +"000000067F000080000009A00C0000088000-000000067F000080000009A00C000008C000__000000BC53F74828", +"000000067F000080000009A00C0000088000-000000067F000080000009A00C000008C000__000000BD25E66810", +"000000067F000080000009A00C000008C000-000000067F000080000009A00C0000090000__000000BC53F74828", +"000000067F000080000009A00C000008C000-000000067F000080000009A00C0000090000__000000BD25E66810", +"000000067F000080000009A00C000008DE70-000000067F000080000009A00C0000097590__000000BB4643FBD1-000000BBE607E8F1", +"000000067F000080000009A00C0000090000-000000067F000080000009A00C0000094000__000000BC53F74828", +"000000067F000080000009A00C0000090000-000000067F000080000009A00C0000094000__000000BD25E66810", +"000000067F000080000009A00C0000094000-000000067F000080000009A00C0000098000__000000BC53F74828", +"000000067F000080000009A00C0000094000-000000067F000080000009A00C0000098000__000000BD25E66810", +"000000067F000080000009A00C0000097590-000000067F000080000009A00C00000A0CF6__000000BB4643FBD1-000000BBE607E8F1", +"000000067F000080000009A00C0000098000-000000067F000080000009A00C000009C000__000000BC53F74828", +"000000067F000080000009A00C0000098000-000000067F000080000009A00C000009C000__000000BD25E66810", +"000000067F000080000009A00C000009C000-000000067F000080000009A00C00000A0000__000000BC53F74828", +"000000067F000080000009A00C000009C000-000000067F000080000009A00C00000A0000__000000BD25E66810", +"000000067F000080000009A00C00000A0000-000000067F000080000009A00C00000A4000__000000BC53F74828", +"000000067F000080000009A00C00000A0000-000000067F000080000009A00C00000A4000__000000BD25E66810", +"000000067F000080000009A00C00000A0CF6-000000067F000080000009A00C00000AA40B__000000BB4643FBD1-000000BBE607E8F1", +"000000067F000080000009A00C00000A4000-000000067F000080000009A00C00000A8000__000000BC53F74828", +"000000067F000080000009A00C00000A4000-000000067F000080000009A00C00000A8000__000000BD25E66810", +"000000067F000080000009A00C00000A8000-000000067F000080000009A00C00000AC000__000000BC53F74828", +"000000067F000080000009A00C00000A8000-000000067F000080000009A00C00000AC000__000000BD25E66810", +"000000067F000080000009A00C00000AA40B-000000067F000080000009A00C00000B3B4D__000000BB4643FBD1-000000BBE607E8F1", +"000000067F000080000009A00C00000AC000-000000067F000080000009A00C00000B0000__000000BC53F74828", +"000000067F000080000009A00C00000AC000-000000067F000080000009A00C00000B0000__000000BD25E66810", +"000000067F000080000009A00C00000B0000-000000067F000080000009A00C00000B4000__000000BC53F74828", +"000000067F000080000009A00C00000B0000-000000067F000080000009A00C00000B4000__000000BD25E66810", +"000000067F000080000009A00C00000B3B4D-000000067F000080000009A00C00000BD2B3__000000BB4643FBD1-000000BBE607E8F1", +"000000067F000080000009A00C00000B4000-000000067F000080000009A00C00000B8000__000000BC53F74828", +"000000067F000080000009A00C00000B4000-000000067F000080000009A00C00000B8000__000000BD25E66810", +"000000067F000080000009A00C00000B8000-000000067F000080000009A00C00000BC000__000000BC53F74828", +"000000067F000080000009A00C00000B8000-000000067F000080000009A00C00000BC000__000000BD25E66810", +"000000067F000080000009A00C00000BC000-000000067F000080000009A00C00000C0000__000000BC53F74828", +"000000067F000080000009A00C00000BC000-000000067F000080000009A00C00000C0000__000000BD25E66810", +"000000067F000080000009A00C00000BD2B3-000000067F000080000009A00C00000C69D9__000000BB4643FBD1-000000BBE607E8F1", +"000000067F000080000009A00C00000C0000-000000067F000080000009A00C00000C4000__000000BC53F74828", +"000000067F000080000009A00C00000C0000-000000067F000080000009A00C00000C4000__000000BD25E66810", +"000000067F000080000009A00C00000C4000-000000067F000080000009A00C00000C8000__000000BC53F74828", +"000000067F000080000009A00C00000C4000-000000067F000080000009A00C00000C8000__000000BD25E66810", +"000000067F000080000009A00C00000C69D9-000000067F000080000009A00C00000D010C__000000BB4643FBD1-000000BBE607E8F1", +"000000067F000080000009A00C00000C8000-000000067F000080000009A00C00000CC000__000000BC53F74828", +"000000067F000080000009A00C00000C8000-000000067F000080000009A00C00000CC000__000000BD25E66810", +"000000067F000080000009A00C00000CC000-000000067F000080000009A00C00000D0000__000000BC53F74828", +"000000067F000080000009A00C00000CC000-000000067F000080000009A00C00000D0000__000000BD25E66810", +"000000067F000080000009A00C00000D0000-000000067F000080000009A00C00000D4000__000000BC53F74828", +"000000067F000080000009A00C00000D0000-000000067F000080000009A00C00000D4000__000000BD25E66810", +"000000067F000080000009A00C00000D010C-000000067F000080000009A00C0100000000__000000BB4643FBD1-000000BBE607E8F1", +"000000067F000080000009A00C00000D4000-000000067F000080000009A00C00000D8000__000000BC53F74828", +"000000067F000080000009A00C00000D4000-000000067F000080000009A00C00000D8000__000000BD25E66810", +"000000067F000080000009A00C00000D6C06-000000067F000080000009A00C00000E0166__000000BBE607E8F1-000000BC596B5D59", +"000000067F000080000009A00C00000D8000-000000067F000080000009A00C00000DC000__000000BC53F74828", +"000000067F000080000009A00C00000D8000-000000067F000080000009A00C00000DC000__000000BD25E66810", +"000000067F000080000009A00C00000DC000-000000067F000080000009A00C00000E0000__000000BC53F74828", +"000000067F000080000009A00C00000DC000-000000067F000080000009A00C00000E0000__000000BD25E66810", +"000000067F000080000009A00C00000E0000-000000067F000080000009A00C00000E4000__000000BC53F74828", +"000000067F000080000009A00C00000E0000-000000067F000080000009A00C00000E4000__000000BD25E66810", +"000000067F000080000009A00C00000E0166-000000067F000080000009A00C00000E96C9__000000BBE607E8F1-000000BC596B5D59", +"000000067F000080000009A00C00000E4000-000000067F000080000009A00C00000E8000__000000BC53F74828", +"000000067F000080000009A00C00000E4000-000000067F000080000009A00C00000E8000__000000BD25E66810", +"000000067F000080000009A00C00000E4F97-000000067F000080000009A0140000019842__000000BCEF79BE91-000000BD263A5849", +"000000067F000080000009A00C00000E8000-000000067F000080000009A00C00000EC000__000000BC53F74828", +"000000067F000080000009A00C00000E8000-000000067F000080000009A00C00000EC000__000000BD25E66810", +"000000067F000080000009A00C00000E96C9-000000067F000080000009A00C00000F2C2B__000000BBE607E8F1-000000BC596B5D59", +"000000067F000080000009A00C00000EC000-000000067F000080000009A00C00000F0000__000000BC53F74828", +"000000067F000080000009A00C00000EC000-000000067F000080000009A00C00000F0000__000000BD25E66810", +"000000067F000080000009A00C00000F0000-000000067F000080000009A00C00000F4000__000000BC53F74828", +"000000067F000080000009A00C00000F0000-000000067F000080000009A00C00000F4000__000000BD25E66810", +"000000067F000080000009A00C00000F248B-000000067F000080000009A0140000004031__000000BC596B5D59-000000BCEF79BE91", +"000000067F000080000009A00C00000F2C2B-000000067F000080000009A00C00000FC18E__000000BBE607E8F1-000000BC596B5D59", +"000000067F000080000009A00C00000F4000-000000067F000080000009A00C00000F8000__000000BC53F74828", +"000000067F000080000009A00C00000F4000-000000067F000080000009A00C00000F8000__000000BD25E66810", +"000000067F000080000009A00C00000F8000-000000067F000080000009A00C00000FC000__000000BC53F74828", +"000000067F000080000009A00C00000F8000-000000067F000080000009A00C00000FC000__000000BD25E66810", +"000000067F000080000009A00C00000FC000-000000067F000080000009A00C0000100000__000000BC53F74828", +"000000067F000080000009A00C00000FC000-000000067F000080000009A00C0000100000__000000BD25E66810", +"000000067F000080000009A00C00000FC18E-000000067F000080000009A00C00001056F2__000000BBE607E8F1-000000BC596B5D59", +"000000067F000080000009A00C0000100000-000000067F000080000009A00C0000104000__000000BC53F74828", +"000000067F000080000009A00C0000100000-000000067F000080000009A00C0000104000__000000BD25E66810", +"000000067F000080000009A00C0000104000-000000067F000080000009A00C0000108000__000000BC53F74828", +"000000067F000080000009A00C0000104000-000000067F000080000009A00C0000108000__000000BD25E66810", +"000000067F000080000009A00C00001056F2-000000067F000080000009A00C000010EC54__000000BBE607E8F1-000000BC596B5D59", +"000000067F000080000009A00C0000108000-000000067F000080000009A00C000010C000__000000BC53F74828", +"000000067F000080000009A00C0000108000-000000067F000080000009A00C000010C000__000000BD25E66810", +"000000067F000080000009A00C000010C000-000000067F000080000009A00C0000110000__000000BC53F74828", +"000000067F000080000009A00C000010C000-000000067F000080000009A00C0000110000__000000BD25E66810", +"000000067F000080000009A00C000010EC54-010000000000000001000000040000000020__000000BBE607E8F1-000000BC596B5D59", +"000000067F000080000009A00C0000110000-000000067F000080000009A0120100000000__000000BD25E66810", +"000000067F000080000009A00C0000110000-030000000000000000000000000000000002__000000BC53F74828", +"000000067F000080000009A0140000000000-000000067F000080000009A0140000004000__000000BD25E66810", +"000000067F000080000009A0140000004000-000000067F000080000009A0140000008000__000000BD25E66810", +"000000067F000080000009A0140000004031-000000067F000080000009A0140000009FC7__000000BC596B5D59-000000BCEF79BE91", +"000000067F000080000009A0140000008000-000000067F000080000009A014000000C000__000000BD25E66810", +"000000067F000080000009A0140000009FC7-000000067F000080000009A014000000FF53__000000BC596B5D59-000000BCEF79BE91", +"000000067F000080000009A014000000C000-000000067F000080000009A0140000010000__000000BD25E66810", +"000000067F000080000009A014000000FF53-000000067F000080000009A0140000015F1C__000000BC596B5D59-000000BCEF79BE91", +"000000067F000080000009A0140000010000-000000067F000080000009A0140000014000__000000BD25E66810", +"000000067F000080000009A0140000014000-000000067F000080000009A0140000018000__000000BD25E66810", +"000000067F000080000009A0140000015F1C-000000067F000080000009A014000001BED0__000000BC596B5D59-000000BCEF79BE91", +"000000067F000080000009A0140000018000-000000067F000080000009A014000001C000__000000BD25E66810", +"000000067F000080000009A0140000019844-030000000000000000000000000000000002__000000BCEF79BE91-000000BD263A5849", +"000000067F000080000009A014000001BED0-000000067F000080000009A0140000021E6C__000000BC596B5D59-000000BCEF79BE91", +"000000067F000080000009A014000001C000-000000067F000080000009A0140000020000__000000BD25E66810", +"000000067F000080000009A0140000020000-000000067F000080000009A0140000024000__000000BD25E66810", +"000000067F000080000009A0140000021E6C-000000067F000080000009A0140000027DB1__000000BC596B5D59-000000BCEF79BE91", +"000000067F000080000009A0140000024000-000000067F000080000009A0140000028000__000000BD25E66810", +"000000067F000080000009A0140000027DB1-000000067F000080000009A014000002DC9E__000000BC596B5D59-000000BCEF79BE91", +"000000067F000080000009A0140000028000-000000067F000080000009A014000002C000__000000BD25E66810", +"000000067F000080000009A014000002C000-030000000000000000000000000000000002__000000BD25E66810", +"000000067F000080000009A01400FFFFFFFF-030000000000000000000000000000000002__000000BC596B5D59-000000BCEF79BE91", +"000000067F000080000009C00C0000000000-000000067F000080000009C00C0000004000__000000BEF683BFD0", +"000000067F000080000009C00C0000004000-000000067F000080000009C00C0000008000__000000BEF683BFD0", +"000000067F000080000009C00C0000008000-000000067F000080000009C00C000000C000__000000BEF683BFD0", +"000000067F000080000009C00C0000009749-000000067F000080000009C00C0000012EAF__000000BD263A5849-000000BDA607F261", +"000000067F000080000009C00C000000C000-000000067F000080000009C00C0000010000__000000BEF683BFD0", +"000000067F000080000009C00C0000010000-000000067F000080000009C00C0000014000__000000BEF683BFD0", +"000000067F000080000009C00C0000012EAF-000000067F000080000009C00C000001C60B__000000BD263A5849-000000BDA607F261", +"000000067F000080000009C00C0000014000-000000067F000080000009C00C0000018000__000000BEF683BFD0", +"000000067F000080000009C00C0000018000-000000067F000080000009C00C000001C000__000000BEF683BFD0", +"000000067F000080000009C00C000001C000-000000067F000080000009C00C0000020000__000000BEF683BFD0", +"000000067F000080000009C00C000001C60B-000000067F000080000009C00C0000025D39__000000BD263A5849-000000BDA607F261", +"000000067F000080000009C00C0000020000-000000067F000080000009C00C0000024000__000000BEF683BFD0", +"000000067F000080000009C00C0000024000-000000067F000080000009C00C0000028000__000000BEF683BFD0", +"000000067F000080000009C00C0000025D39-000000067F000080000009C00C000002F49F__000000BD263A5849-000000BDA607F261", +"000000067F000080000009C00C0000028000-000000067F000080000009C00C000002C000__000000BEF683BFD0", +"000000067F000080000009C00C000002C000-000000067F000080000009C00C0000030000__000000BEF683BFD0", +"000000067F000080000009C00C000002F49F-000000067F000080000009C00C0000038BB2__000000BD263A5849-000000BDA607F261", +"000000067F000080000009C00C0000030000-000000067F000080000009C00C0000034000__000000BEF683BFD0", +"000000067F000080000009C00C0000034000-000000067F000080000009C00C0000038000__000000BEF683BFD0", +"000000067F000080000009C00C0000038000-000000067F000080000009C00C000003C000__000000BEF683BFD0", +"000000067F000080000009C00C0000038BB2-000000067F000080000009C00C0000042318__000000BD263A5849-000000BDA607F261", +"000000067F000080000009C00C000003C000-000000067F000080000009C00C0000040000__000000BEF683BFD0", +"000000067F000080000009C00C0000040000-000000067F000080000009C00C0000044000__000000BEF683BFD0", +"000000067F000080000009C00C0000042318-000000067F000080000009C00C000004BA7E__000000BD263A5849-000000BDA607F261", +"000000067F000080000009C00C0000044000-000000067F000080000009C00C0000048000__000000BEF683BFD0", +"000000067F000080000009C00C0000048000-000000067F000080000009C00C000004C000__000000BEF06884C8", +"000000067F000080000009C00C000004BA7E-030000000000000000000000000000000002__000000BD263A5849-000000BDA607F261", +"000000067F000080000009C00C000004BAC3-000000067F000080000009C00C00000551F8__000000BDA607F261-000000BE45CBFBB9", +"000000067F000080000009C00C000004C000-000000067F000080000009C00C0000050000__000000BEF06884C8", +"000000067F000080000009C00C0000050000-000000067F000080000009C00C0000054000__000000BEF06884C8", +"000000067F000080000009C00C0000054000-000000067F000080000009C00C0000058000__000000BEF06884C8", +"000000067F000080000009C00C00000551F8-000000067F000080000009C00C000005E90C__000000BDA607F261-000000BE45CBFBB9", +"000000067F000080000009C00C0000058000-000000067F000080000009C00C000005C000__000000BEF06884C8", +"000000067F000080000009C00C000005C000-000000067F000080000009C00C0000060000__000000BEF06884C8", +"000000067F000080000009C00C000005E90C-000000067F000080000009C00C000006802C__000000BDA607F261-000000BE45CBFBB9", +"000000067F000080000009C00C0000060000-000000067F000080000009C00C0000064000__000000BEF06884C8", +"000000067F000080000009C00C0000064000-000000067F000080000009C00C0000068000__000000BEF06884C8", +"000000067F000080000009C00C0000068000-000000067F000080000009C00C000006C000__000000BEF06884C8", +"000000067F000080000009C00C000006802C-000000067F000080000009C00C0000071783__000000BDA607F261-000000BE45CBFBB9", +"000000067F000080000009C00C000006C000-000000067F000080000009C00C0000070000__000000BEF06884C8", +"000000067F000080000009C00C0000070000-000000067F000080000009C00C0000074000__000000BEF06884C8", +"000000067F000080000009C00C0000071783-000000067F000080000009C00C000007AEE9__000000BDA607F261-000000BE45CBFBB9", +"000000067F000080000009C00C0000074000-000000067F000080000009C00C0000078000__000000BEF06884C8", +"000000067F000080000009C00C0000078000-000000067F000080000009C00C000007C000__000000BEF06884C8", +"000000067F000080000009C00C000007AEE9-000000067F000080000009C00C000008460B__000000BDA607F261-000000BE45CBFBB9", +"000000067F000080000009C00C000007C000-000000067F000080000009C00C0000080000__000000BEF06884C8", +"000000067F000080000009C00C0000080000-000000067F000080000009C00C0000084000__000000BEF06884C8", +"000000067F000080000009C00C0000084000-000000067F000080000009C00C0000088000__000000BEF06884C8", +"000000067F000080000009C00C000008460B-000000067F000080000009C00C000008DD71__000000BDA607F261-000000BE45CBFBB9", +"000000067F000080000009C00C0000088000-000000067F000080000009C00C000008C000__000000BEF06884C8", +"000000067F000080000009C00C000008C000-000000067F000080000009C00C0000090000__000000BEF06884C8", +"000000067F000080000009C00C000008DD71-000000067F000080000009C00C00000974D7__000000BDA607F261-000000BE45CBFBB9", +"000000067F000080000009C00C0000090000-000000067F000080000009C00C0000094000__000000BEF06884C8", +"000000067F000080000009C00C0000094000-000000067F000080000009C00C0000098000__000000BEF06884C8", +"000000067F000080000009C00C00000974D7-000000067F000080000009C00C00000A0C0B__000000BDA607F261-000000BE45CBFBB9", +"000000067F000080000009C00C0000098000-000000067F000080000009C00C000009C000__000000BEF06884C8", +"000000067F000080000009C00C000009C000-000000067F000080000009C00C00000A0000__000000BEF06884C8", +"000000067F000080000009C00C00000A0000-000000067F000080000009C00C00000A4000__000000BEF06884C8", +"000000067F000080000009C00C00000A0C0B-000000067F000080000009C00C00000AA371__000000BDA607F261-000000BE45CBFBB9", +"000000067F000080000009C00C00000A4000-000000067F000080000009C00C00000A8000__000000BEF06884C8", +"000000067F000080000009C00C00000A8000-000000067F000080000009C00C00000AC000__000000BEF06884C8", +"000000067F000080000009C00C00000AA371-000000067F000080000009C00C0100000000__000000BDA607F261-000000BE45CBFBB9", +"000000067F000080000009C00C00000AC000-000000067F000080000009C00C00000B0000__000000BEF06884C8", +"000000067F000080000009C00C00000B0000-000000067F000080000009C00C00000B4000__000000BEF06884C8", +"000000067F000080000009C00C00000B2921-000000067F000080000009C00C00000BC087__000000BE45CBFBB9-000000BEF5F47FD1", +"000000067F000080000009C00C00000B4000-000000067F000080000009C00C00000B8000__000000BEF06884C8", +"000000067F000080000009C00C00000B8000-000000067F000080000009C00C00000BC000__000000BEF06884C8", +"000000067F000080000009C00C00000BC000-000000067F000080000009C00C00000C0000__000000BEF06884C8", +"000000067F000080000009C00C00000BC087-000000067F000080000009C00C00000C57B8__000000BE45CBFBB9-000000BEF5F47FD1", +"000000067F000080000009C00C00000C0000-000000067F000080000009C00C00000C4000__000000BEF06884C8", +"000000067F000080000009C00C00000C4000-000000067F000080000009C00C00000C8000__000000BEF06884C8", +"000000067F000080000009C00C00000C57B8-000000067F000080000009C00C00000CEF09__000000BE45CBFBB9-000000BEF5F47FD1", +"000000067F000080000009C00C00000C8000-000000067F000080000009C00C00000CC000__000000BEF06884C8", +"000000067F000080000009C00C00000CC000-000000067F000080000009C00C00000D0000__000000BEF06884C8", +"000000067F000080000009C00C00000CEF09-000000067F000080000009C00C00000D862B__000000BE45CBFBB9-000000BEF5F47FD1", +"000000067F000080000009C00C00000D0000-000000067F000080000009C00C00000D4000__000000BEF06884C8", +"000000067F000080000009C00C00000D4000-000000067F000080000009C00C00000D8000__000000BEF06884C8", +"000000067F000080000009C00C00000D8000-000000067F000080000009C00C00000DC000__000000BEF06884C8", +"000000067F000080000009C00C00000D862B-000000067F000080000009C00C00000E1D7F__000000BE45CBFBB9-000000BEF5F47FD1", +"000000067F000080000009C00C00000DC000-000000067F000080000009C00C00000E0000__000000BEF06884C8", +"000000067F000080000009C00C00000E0000-000000067F000080000009C00C00000E4000__000000BEF06884C8", +"000000067F000080000009C00C00000E1D7F-000000067F000080000009C00C00000EB4E5__000000BE45CBFBB9-000000BEF5F47FD1", +"000000067F000080000009C00C00000E4000-000000067F000080000009C00C00000E8000__000000BEF06884C8", +"000000067F000080000009C00C00000E8000-000000067F000080000009C00C00000EC000__000000BEF06884C8", +"000000067F000080000009C00C00000EB4E5-000000067F000080000009C00C00000F4C0B__000000BE45CBFBB9-000000BEF5F47FD1", +"000000067F000080000009C00C00000EC000-000000067F000080000009C00C00000F0000__000000BEF06884C8", +"000000067F000080000009C00C00000F0000-000000067F000080000009C00C00000F4000__000000BEF06884C8", +"000000067F000080000009C00C00000F4000-000000067F000080000009C00C00000F8000__000000BEF06884C8", +"000000067F000080000009C00C00000F4C0B-000000067F000080000009C00C00000FE371__000000BE45CBFBB9-000000BEF5F47FD1", +"000000067F000080000009C00C00000F8000-000000067F000080000009C00C00000FC000__000000BEF06884C8", +"000000067F000080000009C00C00000FC000-000000067F000080000009C00C0000100000__000000BEF06884C8", +"000000067F000080000009C00C00000FE371-000000067F000080000009C00C0000107AD7__000000BE45CBFBB9-000000BEF5F47FD1", +"000000067F000080000009C00C0000100000-000000067F000080000009C00C0000104000__000000BEF06884C8", +"000000067F000080000009C00C0000104000-000000067F000080000009C00C0000108000__000000BEF06884C8", +"000000067F000080000009C00C0000107AD7-000000067F000080000009C00C000011120B__000000BE45CBFBB9-000000BEF5F47FD1", +"000000067F000080000009C00C0000108000-000000067F000080000009C00C000010C000__000000BEF06884C8", +"000000067F000080000009C00C000010C000-030000000000000000000000000000000002__000000BEF06884C8", +"000000067F000080000009C00C000011120B-010000000000000001000000050000000003__000000BE45CBFBB9-000000BEF5F47FD1", +"000000067F000080000009E00C0000000000-000000067F000080000009E00C0000004000__000000C0C9769FD8", +"000000067F000080000009E00C0000004000-000000067F000080000009E00C0000008000__000000C0C9769FD8", +"000000067F000080000009E00C0000004916-000000067F000080000009E00C000000E07C__000000BEF5F47FD1-000000BF48FFEB11", +"000000067F000080000009E00C0000008000-000000067F000080000009E00C000000C000__000000C0C9769FD8", +"000000067F000080000009E00C000000C000-000000067F000080000009E00C0000010000__000000C0C9769FD8", +"000000067F000080000009E00C000000E07C-000000067F000080000009E00C000001779A__000000BEF5F47FD1-000000BF48FFEB11", +"000000067F000080000009E00C0000010000-000000067F000080000009E00C0000014000__000000C0C9769FD8", +"000000067F000080000009E00C0000014000-000000067F000080000009E00C0000018000__000000C0C9769FD8", +"000000067F000080000009E00C000001779A-000000067F000080000009E00C0000020F00__000000BEF5F47FD1-000000BF48FFEB11", +"000000067F000080000009E00C0000018000-000000067F000080000009E00C000001C000__000000C0C9769FD8", +"000000067F000080000009E00C000001C000-000000067F000080000009E00C0000020000__000000C0C9769FD8", +"000000067F000080000009E00C0000020000-000000067F000080000009E00C0000024000__000000C0C9769FD8", +"000000067F000080000009E00C0000020F00-000000067F000080000009E00C000002A60B__000000BEF5F47FD1-000000BF48FFEB11", +"000000067F000080000009E00C0000024000-000000067F000080000009E00C0000028000__000000C0C9769FD8", +"000000067F000080000009E00C0000028000-000000067F000080000009E00C000002C000__000000C0C9769FD8", +"000000067F000080000009E00C000002A60B-030000000000000000000000000000000002__000000BEF5F47FD1-000000BF48FFEB11", +"000000067F000080000009E00C000002C000-000000067F000080000009E00C0000030000__000000C0B597E900", +"000000067F000080000009E00C000002C000-000000067F000080000009E00C0000030000__000000C1972392A8", +"000000067F000080000009E00C000002F506-000000067F000080000009E00C0000038C11__000000BF48FFEB11-000000BFF8BDFEE9", +"000000067F000080000009E00C0000030000-000000067F000080000009E00C0000034000__000000C0B597E900", +"000000067F000080000009E00C0000030000-000000067F000080000009E00C0000034000__000000C1972392A8", +"000000067F000080000009E00C0000034000-000000067F000080000009E00C0000038000__000000C0B597E900", +"000000067F000080000009E00C0000034000-000000067F000080000009E00C0000038000__000000C1972392A8", +"000000067F000080000009E00C0000038000-000000067F000080000009E00C000003C000__000000C0B597E900", +"000000067F000080000009E00C0000038000-000000067F000080000009E00C000003C000__000000C1972392A8", +"000000067F000080000009E00C0000038C11-000000067F000080000009E00C0000042361__000000BF48FFEB11-000000BFF8BDFEE9", +"000000067F000080000009E00C000003C000-000000067F000080000009E00C0000040000__000000C0B597E900", +"000000067F000080000009E00C000003C000-000000067F000080000009E00C0000040000__000000C1972392A8", +"000000067F000080000009E00C0000040000-000000067F000080000009E00C0000044000__000000C0B597E900", +"000000067F000080000009E00C0000040000-000000067F000080000009E00C0000044000__000000C1972392A8", +"000000067F000080000009E00C0000042361-000000067F000080000009E00C000004BAC7__000000BF48FFEB11-000000BFF8BDFEE9", +"000000067F000080000009E00C0000044000-000000067F000080000009E00C0000048000__000000C0B597E900", +"000000067F000080000009E00C0000044000-000000067F000080000009E00C0000048000__000000C1972392A8", +"000000067F000080000009E00C0000048000-000000067F000080000009E00C000004C000__000000C0B597E900", +"000000067F000080000009E00C0000048000-000000067F000080000009E00C000004C000__000000C1972392A8", +"000000067F000080000009E00C000004BAC7-000000067F000080000009E00C00000551FC__000000BF48FFEB11-000000BFF8BDFEE9", +"000000067F000080000009E00C000004C000-000000067F000080000009E00C0000050000__000000C0B597E900", +"000000067F000080000009E00C000004C000-000000067F000080000009E00C0000050000__000000C1972392A8", +"000000067F000080000009E00C0000050000-000000067F000080000009E00C0000054000__000000C0B597E900", +"000000067F000080000009E00C0000050000-000000067F000080000009E00C0000054000__000000C1972392A8", +"000000067F000080000009E00C0000050E89-000000067F000080000009E00C00000A18A0__000000C1426D92E1-000000C19744E959", +"000000067F000080000009E00C0000054000-000000067F000080000009E00C0000058000__000000C0B597E900", +"000000067F000080000009E00C0000054000-000000067F000080000009E00C0000058000__000000C1972392A8", +"000000067F000080000009E00C00000551FC-000000067F000080000009E00C000005E90B__000000BF48FFEB11-000000BFF8BDFEE9", +"000000067F000080000009E00C0000058000-000000067F000080000009E00C000005C000__000000C0B597E900", +"000000067F000080000009E00C0000058000-000000067F000080000009E00C000005C000__000000C1972392A8", +"000000067F000080000009E00C000005C000-000000067F000080000009E00C0000060000__000000C0B597E900", +"000000067F000080000009E00C000005C000-000000067F000080000009E00C0000060000__000000C1972392A8", +"000000067F000080000009E00C000005E90B-000000067F000080000009E00C000006802B__000000BF48FFEB11-000000BFF8BDFEE9", +"000000067F000080000009E00C0000060000-000000067F000080000009E00C0000064000__000000C0B597E900", +"000000067F000080000009E00C0000060000-000000067F000080000009E00C0000064000__000000C1972392A8", +"000000067F000080000009E00C0000064000-000000067F000080000009E00C0000068000__000000C0B597E900", +"000000067F000080000009E00C0000064000-000000067F000080000009E00C0000068000__000000C1972392A8", +"000000067F000080000009E00C0000068000-000000067F000080000009E00C000006C000__000000C0B597E900", +"000000067F000080000009E00C0000068000-000000067F000080000009E00C000006C000__000000C1972392A8", +"000000067F000080000009E00C000006802B-000000067F000080000009E00C0000071782__000000BF48FFEB11-000000BFF8BDFEE9", +"000000067F000080000009E00C000006C000-000000067F000080000009E00C0000070000__000000C0B597E900", +"000000067F000080000009E00C000006C000-000000067F000080000009E00C0000070000__000000C1972392A8", +"000000067F000080000009E00C0000070000-000000067F000080000009E00C0000074000__000000C0B597E900", +"000000067F000080000009E00C0000070000-000000067F000080000009E00C0000074000__000000C1972392A8", +"000000067F000080000009E00C0000071782-000000067F000080000009E00C000007AEE8__000000BF48FFEB11-000000BFF8BDFEE9", +"000000067F000080000009E00C0000074000-000000067F000080000009E00C0000078000__000000C0B597E900", +"000000067F000080000009E00C0000074000-000000067F000080000009E00C0000078000__000000C1972392A8", +"000000067F000080000009E00C0000078000-000000067F000080000009E00C000007C000__000000C0B597E900", +"000000067F000080000009E00C0000078000-000000067F000080000009E00C000007C000__000000C1972392A8", +"000000067F000080000009E00C000007AEE8-000000067F000080000009E00C000008460B__000000BF48FFEB11-000000BFF8BDFEE9", +"000000067F000080000009E00C000007C000-000000067F000080000009E00C0000080000__000000C0B597E900", +"000000067F000080000009E00C000007C000-000000067F000080000009E00C0000080000__000000C1972392A8", +"000000067F000080000009E00C0000080000-000000067F000080000009E00C0000084000__000000C0B597E900", +"000000067F000080000009E00C0000080000-000000067F000080000009E00C0000084000__000000C1972392A8", +"000000067F000080000009E00C0000084000-000000067F000080000009E00C0000088000__000000C0B597E900", +"000000067F000080000009E00C0000084000-000000067F000080000009E00C0000088000__000000C1972392A8", +"000000067F000080000009E00C000008460B-000000067F000080000009E00C000008DD71__000000BF48FFEB11-000000BFF8BDFEE9", +"000000067F000080000009E00C0000088000-000000067F000080000009E00C000008C000__000000C0B597E900", +"000000067F000080000009E00C0000088000-000000067F000080000009E00C000008C000__000000C1972392A8", +"000000067F000080000009E00C000008C000-000000067F000080000009E00C0000090000__000000C0B597E900", +"000000067F000080000009E00C000008C000-000000067F000080000009E00C0000090000__000000C1972392A8", +"000000067F000080000009E00C000008DD71-000000067F000080000009E00C00000974D7__000000BF48FFEB11-000000BFF8BDFEE9", +"000000067F000080000009E00C0000090000-000000067F000080000009E00C0000094000__000000C0B597E900", +"000000067F000080000009E00C0000090000-000000067F000080000009E00C0000094000__000000C1972392A8", +"000000067F000080000009E00C0000094000-000000067F000080000009E00C0000098000__000000C0B597E900", +"000000067F000080000009E00C0000094000-000000067F000080000009E00C0000098000__000000C1972392A8", +"000000067F000080000009E00C00000974D7-000000067F000080000009E00C0100000000__000000BF48FFEB11-000000BFF8BDFEE9", +"000000067F000080000009E00C0000098000-000000067F000080000009E00C000009C000__000000C0B597E900", +"000000067F000080000009E00C0000098000-000000067F000080000009E00C000009C000__000000C1972392A8", +"000000067F000080000009E00C000009C000-000000067F000080000009E00C00000A0000__000000C0B597E900", +"000000067F000080000009E00C000009C000-000000067F000080000009E00C00000A0000__000000C1972392A8", +"000000067F000080000009E00C000009FB21-000000067F000080000009E00C00000A9230__000000BFF8BDFEE9-000000C0C8CA5FF1", +"000000067F000080000009E00C00000A0000-000000067F000080000009E00C00000A4000__000000C0B597E900", +"000000067F000080000009E00C00000A0000-000000067F000080000009E00C00000A4000__000000C1972392A8", +"000000067F000080000009E00C00000A18A4-000000067F000080000009E00C00000F2B76__000000C1426D92E1-000000C19744E959", +"000000067F000080000009E00C00000A4000-000000067F000080000009E00C00000A8000__000000C0B597E900", +"000000067F000080000009E00C00000A4000-000000067F000080000009E00C00000A8000__000000C1972392A8", +"000000067F000080000009E00C00000A8000-000000067F000080000009E00C00000AC000__000000C0B597E900", +"000000067F000080000009E00C00000A8000-000000067F000080000009E00C00000AC000__000000C1972392A8", +"000000067F000080000009E00C00000A9230-000000067F000080000009E00C00000B297D__000000BFF8BDFEE9-000000C0C8CA5FF1", +"000000067F000080000009E00C00000AC000-000000067F000080000009E00C00000B0000__000000C0B597E900", +"000000067F000080000009E00C00000AC000-000000067F000080000009E00C00000B0000__000000C1972392A8", +"000000067F000080000009E00C00000B0000-000000067F000080000009E00C00000B4000__000000C0B597E900", +"000000067F000080000009E00C00000B0000-000000067F000080000009E00C00000B4000__000000C1972392A8", +"000000067F000080000009E00C00000B297D-000000067F000080000009E00C00000BC0E3__000000BFF8BDFEE9-000000C0C8CA5FF1", +"000000067F000080000009E00C00000B4000-000000067F000080000009E00C00000B8000__000000C0B597E900", +"000000067F000080000009E00C00000B4000-000000067F000080000009E00C00000B8000__000000C1972392A8", +"000000067F000080000009E00C00000B8000-000000067F000080000009E00C00000BC000__000000C0B597E900", +"000000067F000080000009E00C00000B8000-000000067F000080000009E00C00000BC000__000000C1972392A8", +"000000067F000080000009E00C00000BC000-000000067F000080000009E00C00000C0000__000000C0B597E900", +"000000067F000080000009E00C00000BC000-000000067F000080000009E00C00000C0000__000000C1972392A8", +"000000067F000080000009E00C00000BC0E3-000000067F000080000009E00C00000C580C__000000BFF8BDFEE9-000000C0C8CA5FF1", +"000000067F000080000009E00C00000C0000-000000067F000080000009E00C00000C4000__000000C0B597E900", +"000000067F000080000009E00C00000C0000-000000067F000080000009E00C00000C4000__000000C1972392A8", +"000000067F000080000009E00C00000C0C74-000000067F000080000009E0140000001880__000000C0C8CA5FF1-000000C1426D92E1", +"000000067F000080000009E00C00000C4000-000000067F000080000009E00C00000C8000__000000C0B597E900", +"000000067F000080000009E00C00000C4000-000000067F000080000009E00C00000C8000__000000C1972392A8", +"000000067F000080000009E00C00000C580C-000000067F000080000009E00C00000CEF71__000000BFF8BDFEE9-000000C0C8CA5FF1", +"000000067F000080000009E00C00000C8000-000000067F000080000009E00C00000CC000__000000C0B597E900", +"000000067F000080000009E00C00000C8000-000000067F000080000009E00C00000CC000__000000C1972392A8", +"000000067F000080000009E00C00000CC000-000000067F000080000009E00C00000D0000__000000C0B597E900", +"000000067F000080000009E00C00000CC000-000000067F000080000009E00C00000D0000__000000C1972392A8", +"000000067F000080000009E00C00000CEF71-000000067F000080000009E00C00000D86D7__000000BFF8BDFEE9-000000C0C8CA5FF1", +"000000067F000080000009E00C00000D0000-000000067F000080000009E00C00000D4000__000000C0B597E900", +"000000067F000080000009E00C00000D0000-000000067F000080000009E00C00000D4000__000000C1972392A8", +"000000067F000080000009E00C00000D4000-000000067F000080000009E00C00000D8000__000000C0B597E900", +"000000067F000080000009E00C00000D4000-000000067F000080000009E00C00000D8000__000000C1972392A8", +"000000067F000080000009E00C00000D8000-000000067F000080000009E00C00000DC000__000000C0B597E900", +"000000067F000080000009E00C00000D8000-000000067F000080000009E00C00000DC000__000000C1972392A8", +"000000067F000080000009E00C00000D86D7-000000067F000080000009E00C00000E1E0C__000000BFF8BDFEE9-000000C0C8CA5FF1", +"000000067F000080000009E00C00000DC000-000000067F000080000009E00C00000E0000__000000C0B597E900", +"000000067F000080000009E00C00000DC000-000000067F000080000009E00C00000E0000__000000C1972392A8", +"000000067F000080000009E00C00000E0000-000000067F000080000009E00C00000E4000__000000C0B597E900", +"000000067F000080000009E00C00000E0000-000000067F000080000009E00C00000E4000__000000C1972392A8", +"000000067F000080000009E00C00000E1E0C-000000067F000080000009E00C00000EB572__000000BFF8BDFEE9-000000C0C8CA5FF1", +"000000067F000080000009E00C00000E4000-000000067F000080000009E00C00000E8000__000000C0B597E900", +"000000067F000080000009E00C00000E4000-000000067F000080000009E00C00000E8000__000000C1972392A8", +"000000067F000080000009E00C00000E8000-000000067F000080000009E00C00000EC000__000000C0B597E900", +"000000067F000080000009E00C00000E8000-000000067F000080000009E00C00000EC000__000000C1972392A8", +"000000067F000080000009E00C00000EB572-000000067F000080000009E00C00000F4CD8__000000BFF8BDFEE9-000000C0C8CA5FF1", +"000000067F000080000009E00C00000EC000-000000067F000080000009E00C00000F0000__000000C0B597E900", +"000000067F000080000009E00C00000EC000-000000067F000080000009E00C00000F0000__000000C1972392A8", +"000000067F000080000009E00C00000F0000-000000067F000080000009E00C00000F4000__000000C0B597E900", +"000000067F000080000009E00C00000F0000-000000067F000080000009E00C00000F4000__000000C1972392A8", +"000000067F000080000009E00C00000F2B77-000000067F000080000009E014000000D3EB__000000C1426D92E1-000000C19744E959", +"000000067F000080000009E00C00000F4000-000000067F000080000009E00C00000F8000__000000C0B597E900", +"000000067F000080000009E00C00000F4000-000000067F000080000009E00C00000F8000__000000C1972392A8", +"000000067F000080000009E00C00000F4CD8-000000067F000080000009E00C00000FE40B__000000BFF8BDFEE9-000000C0C8CA5FF1", +"000000067F000080000009E00C00000F8000-000000067F000080000009E00C00000FC000__000000C0B597E900", +"000000067F000080000009E00C00000F8000-000000067F000080000009E00C00000FC000__000000C1972392A8", +"000000067F000080000009E00C00000FC000-000000067F000080000009E00C0000100000__000000C0B597E900", +"000000067F000080000009E00C00000FC000-000000067F000080000009E00C0000100000__000000C1972392A8", +"000000067F000080000009E00C00000FE40B-000000067F000080000009E00C0000107B27__000000BFF8BDFEE9-000000C0C8CA5FF1", +"000000067F000080000009E00C0000100000-000000067F000080000009E00C0000104000__000000C0B597E900", +"000000067F000080000009E00C0000100000-000000067F000080000009E00C0000104000__000000C1972392A8", +"000000067F000080000009E00C0000104000-000000067F000080000009E00C0000108000__000000C1972392A8", +"000000067F000080000009E00C0000104000-030000000000000000000000000000000002__000000C0B597E900", +"000000067F000080000009E00C0000107B27-000000067F000080000009E00C000011128D__000000BFF8BDFEE9-000000C0C8CA5FF1", +"000000067F000080000009E00C0000108000-000000067F000080000009E00C000010C000__000000C1972392A8", +"000000067F000080000009E00C000010C000-000000067F000080000009E00C0000110000__000000C1972392A8", +"000000067F000080000009E00C0000110000-000000067F000080000009E0120100000000__000000C1972392A8", +"000000067F000080000009E00C000011128D-010000000000000001000000050000000003__000000BFF8BDFEE9-000000C0C8CA5FF1", +"000000067F000080000009E0140000000000-000000067F000080000009E0140000004000__000000C1972392A8", +"000000067F000080000009E0140000001880-000000067F000080000009E014000000842E__000000C0C8CA5FF1-000000C1426D92E1", +"000000067F000080000009E0140000004000-000000067F000080000009E0140000008000__000000C1972392A8", +"000000067F000080000009E0140000008000-000000067F000080000009E014000000C000__000000C1972392A8", +"000000067F000080000009E014000000842E-000000067F000080000009E014000000F011__000000C0C8CA5FF1-000000C1426D92E1", +"000000067F000080000009E014000000C000-000000067F000080000009E0140000010000__000000C1972392A8", +"000000067F000080000009E014000000D3EB-000000067F000080000009E014000002578F__000000C1426D92E1-000000C19744E959", +"000000067F000080000009E014000000F011-000000067F000080000009E0140000015BD8__000000C0C8CA5FF1-000000C1426D92E1", +"000000067F000080000009E0140000010000-000000067F000080000009E0140000014000__000000C1972392A8", +"000000067F000080000009E0140000014000-000000067F000080000009E0140000018000__000000C1972392A8", +"000000067F000080000009E0140000015BD8-000000067F000080000009E014000001C7C5__000000C0C8CA5FF1-000000C1426D92E1", +"000000067F000080000009E0140000018000-000000067F000080000009E014000001C000__000000C1972392A8", +"000000067F000080000009E014000001C000-000000067F000080000009E0140000020000__000000C1972392A8", +"000000067F000080000009E014000001C7C5-000000067F000080000009E014000002337F__000000C0C8CA5FF1-000000C1426D92E1", +"000000067F000080000009E0140000020000-000000067F000080000009E0140000024000__000000C1972392A8", +"000000067F000080000009E014000002337F-000000067F000080000009E0140000029F4A__000000C0C8CA5FF1-000000C1426D92E1", +"000000067F000080000009E0140000024000-000000067F000080000009E0140000028000__000000C1972392A8", +"000000067F000080000009E0140000025790-030000000000000000000000000000000002__000000C1426D92E1-000000C19744E959", +"000000067F000080000009E0140000028000-000000067F000080000009E014000002C000__000000C1972392A8", +"000000067F000080000009E0140000029F4A-030000000000000000000000000000000002__000000C0C8CA5FF1-000000C1426D92E1", +"000000067F000080000009E014000002C000-030000000000000000000000000000000002__000000C1972392A8", +"000000067F00008000000A000C0000000000-000000067F00008000000A000C0000004000__000000C3687EDFE8", +"000000067F00008000000A000C0000004000-000000067F00008000000A000C0000008000__000000C3687EDFE8", +"000000067F00008000000A000C0000008000-000000067F00008000000A000C000000C000__000000C3687EDFE8", +"000000067F00008000000A000C0000008EF9-000000067F00008000000A000C000001260C__000000C19744E959-000000C217F3F379", +"000000067F00008000000A000C000000C000-000000067F00008000000A000C0000010000__000000C3687EDFE8", +"000000067F00008000000A000C0000010000-000000067F00008000000A000C0000014000__000000C3687EDFE8", +"000000067F00008000000A000C000001260C-000000067F00008000000A000C000001BD72__000000C19744E959-000000C217F3F379", +"000000067F00008000000A000C0000014000-000000067F00008000000A000C0000018000__000000C3687EDFE8", +"000000067F00008000000A000C0000018000-000000067F00008000000A000C000001C000__000000C3687EDFE8", +"000000067F00008000000A000C000001BD72-000000067F00008000000A000C00000254D8__000000C19744E959-000000C217F3F379", +"000000067F00008000000A000C000001C000-000000067F00008000000A000C0000020000__000000C3687EDFE8", +"000000067F00008000000A000C0000020000-000000067F00008000000A000C0000024000__000000C3687EDFE8", +"000000067F00008000000A000C0000024000-000000067F00008000000A000C0000028000__000000C3687EDFE8", +"000000067F00008000000A000C00000254D8-000000067F00008000000A000C000002EC0B__000000C19744E959-000000C217F3F379", +"000000067F00008000000A000C0000028000-000000067F00008000000A000C000002C000__000000C3687EDFE8", +"000000067F00008000000A000C000002C000-000000067F00008000000A000C0000030000__000000C3687EDFE8", +"000000067F00008000000A000C000002EC0B-000000067F00008000000A000C0000038322__000000C19744E959-000000C217F3F379", +"000000067F00008000000A000C0000030000-000000067F00008000000A000C0000034000__000000C3687EDFE8", +"000000067F00008000000A000C0000034000-000000067F00008000000A000C0000038000__000000C3687EDFE8", +"000000067F00008000000A000C0000038000-000000067F00008000000A000C000003C000__000000C3687EDFE8", +"000000067F00008000000A000C0000038322-000000067F00008000000A000C0000041A88__000000C19744E959-000000C217F3F379", +"000000067F00008000000A000C000003C000-000000067F00008000000A000C0000040000__000000C3687EDFE8", +"000000067F00008000000A000C0000040000-000000067F00008000000A000C0000044000__000000C3687EDFE8", +"000000067F00008000000A000C0000041A88-000000067F00008000000A000C000004B1EE__000000C19744E959-000000C217F3F379", +"000000067F00008000000A000C0000044000-000000067F00008000000A000C0000048000__000000C3687EDFE8", +"000000067F00008000000A000C0000048000-000000067F00008000000A000C000004C000__000000C366619FD8", +"000000067F00008000000A000C0000048000-000000067F00008000000A000C000004C000__000000C42FE73810", +"000000067F00008000000A000C000004B1EE-030000000000000000000000000000000002__000000C19744E959-000000C217F3F379", +"000000067F00008000000A000C000004BACE-000000067F00008000000A000C0000055202__000000C217F3F379-000000C2C7B1ECC1", +"000000067F00008000000A000C000004C000-000000067F00008000000A000C0000050000__000000C366619FD8", +"000000067F00008000000A000C000004C000-000000067F00008000000A000C0000050000__000000C42FE73810", +"000000067F00008000000A000C0000050000-000000067F00008000000A000C0000054000__000000C366619FD8", +"000000067F00008000000A000C0000050000-000000067F00008000000A000C0000054000__000000C42FE73810", +"000000067F00008000000A000C0000054000-000000067F00008000000A000C0000058000__000000C366619FD8", +"000000067F00008000000A000C0000054000-000000067F00008000000A000C0000058000__000000C42FE73810", +"000000067F00008000000A000C0000055202-000000067F00008000000A000C000005E90D__000000C217F3F379-000000C2C7B1ECC1", +"000000067F00008000000A000C0000056365-000000067F00008000000A000C00000ACA1A__000000C3E17E01A1-000000C430961E71", +"000000067F00008000000A000C0000058000-000000067F00008000000A000C000005C000__000000C366619FD8", +"000000067F00008000000A000C0000058000-000000067F00008000000A000C000005C000__000000C42FE73810", +"000000067F00008000000A000C000005C000-000000067F00008000000A000C0000060000__000000C366619FD8", +"000000067F00008000000A000C000005C000-000000067F00008000000A000C0000060000__000000C42FE73810", +"000000067F00008000000A000C000005E90D-000000067F00008000000A000C000006802B__000000C217F3F379-000000C2C7B1ECC1", +"000000067F00008000000A000C0000060000-000000067F00008000000A000C0000064000__000000C366619FD8", +"000000067F00008000000A000C0000060000-000000067F00008000000A000C0000064000__000000C42FE73810", +"000000067F00008000000A000C0000064000-000000067F00008000000A000C0000068000__000000C366619FD8", +"000000067F00008000000A000C0000064000-000000067F00008000000A000C0000068000__000000C42FE73810", +"000000067F00008000000A000C0000068000-000000067F00008000000A000C000006C000__000000C366619FD8", +"000000067F00008000000A000C0000068000-000000067F00008000000A000C000006C000__000000C42FE73810", +"000000067F00008000000A000C000006802B-000000067F00008000000A000C0000071782__000000C217F3F379-000000C2C7B1ECC1", +"000000067F00008000000A000C000006C000-000000067F00008000000A000C0000070000__000000C366619FD8", +"000000067F00008000000A000C000006C000-000000067F00008000000A000C0000070000__000000C42FE73810", +"000000067F00008000000A000C0000070000-000000067F00008000000A000C0000074000__000000C366619FD8", +"000000067F00008000000A000C0000070000-000000067F00008000000A000C0000074000__000000C42FE73810", +"000000067F00008000000A000C0000071782-000000067F00008000000A000C000007AEE8__000000C217F3F379-000000C2C7B1ECC1", +"000000067F00008000000A000C0000074000-000000067F00008000000A000C0000078000__000000C366619FD8", +"000000067F00008000000A000C0000074000-000000067F00008000000A000C0000078000__000000C42FE73810", +"000000067F00008000000A000C0000078000-000000067F00008000000A000C000007C000__000000C366619FD8", +"000000067F00008000000A000C0000078000-000000067F00008000000A000C000007C000__000000C42FE73810", +"000000067F00008000000A000C000007AEE8-000000067F00008000000A000C000008460B__000000C217F3F379-000000C2C7B1ECC1", +"000000067F00008000000A000C000007C000-000000067F00008000000A000C0000080000__000000C366619FD8", +"000000067F00008000000A000C000007C000-000000067F00008000000A000C0000080000__000000C42FE73810", +"000000067F00008000000A000C0000080000-000000067F00008000000A000C0000084000__000000C366619FD8", +"000000067F00008000000A000C0000080000-000000067F00008000000A000C0000084000__000000C42FE73810", +"000000067F00008000000A000C0000084000-000000067F00008000000A000C0000088000__000000C366619FD8", +"000000067F00008000000A000C0000084000-000000067F00008000000A000C0000088000__000000C42FE73810", +"000000067F00008000000A000C000008460B-000000067F00008000000A000C000008DD71__000000C217F3F379-000000C2C7B1ECC1", +"000000067F00008000000A000C0000088000-000000067F00008000000A000C000008C000__000000C366619FD8", +"000000067F00008000000A000C0000088000-000000067F00008000000A000C000008C000__000000C42FE73810", +"000000067F00008000000A000C000008C000-000000067F00008000000A000C0000090000__000000C366619FD8", +"000000067F00008000000A000C000008C000-000000067F00008000000A000C0000090000__000000C42FE73810", +"000000067F00008000000A000C000008DD71-000000067F00008000000A000C00000974D7__000000C217F3F379-000000C2C7B1ECC1", +"000000067F00008000000A000C0000090000-000000067F00008000000A000C0000094000__000000C366619FD8", +"000000067F00008000000A000C0000090000-000000067F00008000000A000C0000094000__000000C42FE73810", +"000000067F00008000000A000C0000094000-000000067F00008000000A000C0000098000__000000C366619FD8", +"000000067F00008000000A000C0000094000-000000067F00008000000A000C0000098000__000000C42FE73810", +"000000067F00008000000A000C00000974D7-000000067F00008000000A000C00000A0C0B__000000C217F3F379-000000C2C7B1ECC1", +"000000067F00008000000A000C0000098000-000000067F00008000000A000C000009C000__000000C366619FD8", +"000000067F00008000000A000C0000098000-000000067F00008000000A000C000009C000__000000C42FE73810", +"000000067F00008000000A000C000009C000-000000067F00008000000A000C00000A0000__000000C366619FD8", +"000000067F00008000000A000C000009C000-000000067F00008000000A000C00000A0000__000000C42FE73810", +"000000067F00008000000A000C00000A0000-000000067F00008000000A000C00000A4000__000000C366619FD8", +"000000067F00008000000A000C00000A0000-000000067F00008000000A000C00000A4000__000000C42FE73810", +"000000067F00008000000A000C00000A0C0B-000000067F00008000000A000C00000AA371__000000C217F3F379-000000C2C7B1ECC1", +"000000067F00008000000A000C00000A4000-000000067F00008000000A000C00000A8000__000000C366619FD8", +"000000067F00008000000A000C00000A4000-000000067F00008000000A000C00000A8000__000000C42FE73810", +"000000067F00008000000A000C00000A8000-000000067F00008000000A000C00000AC000__000000C366619FD8", +"000000067F00008000000A000C00000A8000-000000067F00008000000A000C00000AC000__000000C42FE73810", +"000000067F00008000000A000C00000AA371-000000067F00008000000A000C00000B3AD7__000000C217F3F379-000000C2C7B1ECC1", +"000000067F00008000000A000C00000AC000-000000067F00008000000A000C00000B0000__000000C366619FD8", +"000000067F00008000000A000C00000AC000-000000067F00008000000A000C00000B0000__000000C42FE73810", +"000000067F00008000000A000C00000ACA25-000000067F00008000000A000C0000102D7C__000000C3E17E01A1-000000C430961E71", +"000000067F00008000000A000C00000B0000-000000067F00008000000A000C00000B4000__000000C366619FD8", +"000000067F00008000000A000C00000B0000-000000067F00008000000A000C00000B4000__000000C42FE73810", +"000000067F00008000000A000C00000B3AD7-000000067F00008000000A000C0100000000__000000C217F3F379-000000C2C7B1ECC1", +"000000067F00008000000A000C00000B4000-000000067F00008000000A000C00000B8000__000000C366619FD8", +"000000067F00008000000A000C00000B4000-000000067F00008000000A000C00000B8000__000000C42FE73810", +"000000067F00008000000A000C00000B8000-000000067F00008000000A000C00000BC000__000000C366619FD8", +"000000067F00008000000A000C00000B8000-000000067F00008000000A000C00000BC000__000000C42FE73810", +"000000067F00008000000A000C00000B8B52-000000067F00008000000A00140000001132__000000C367E48001-000000C3E17E01A1", +"000000067F00008000000A000C00000BC000-000000067F00008000000A000C00000C0000__000000C366619FD8", +"000000067F00008000000A000C00000BC000-000000067F00008000000A000C00000C0000__000000C42FE73810", +"000000067F00008000000A000C00000BC072-000000067F00008000000A000C00000C57A3__000000C2C7B1ECC1-000000C367E48001", +"000000067F00008000000A000C00000C0000-000000067F00008000000A000C00000C4000__000000C366619FD8", +"000000067F00008000000A000C00000C0000-000000067F00008000000A000C00000C4000__000000C42FE73810", +"000000067F00008000000A000C00000C4000-000000067F00008000000A000C00000C8000__000000C366619FD8", +"000000067F00008000000A000C00000C4000-000000067F00008000000A000C00000C8000__000000C42FE73810", +"000000067F00008000000A000C00000C57A3-000000067F00008000000A000C00000CEF09__000000C2C7B1ECC1-000000C367E48001", +"000000067F00008000000A000C00000C8000-000000067F00008000000A000C00000CC000__000000C366619FD8", +"000000067F00008000000A000C00000C8000-000000067F00008000000A000C00000CC000__000000C42FE73810", +"000000067F00008000000A000C00000CC000-000000067F00008000000A000C00000D0000__000000C366619FD8", +"000000067F00008000000A000C00000CC000-000000067F00008000000A000C00000D0000__000000C42FE73810", +"000000067F00008000000A000C00000CEF09-000000067F00008000000A000C00000D862B__000000C2C7B1ECC1-000000C367E48001", +"000000067F00008000000A000C00000D0000-000000067F00008000000A000C00000D4000__000000C366619FD8", +"000000067F00008000000A000C00000D0000-000000067F00008000000A000C00000D4000__000000C42FE73810", +"000000067F00008000000A000C00000D4000-000000067F00008000000A000C00000D8000__000000C366619FD8", +"000000067F00008000000A000C00000D4000-000000067F00008000000A000C00000D8000__000000C42FE73810", +"000000067F00008000000A000C00000D8000-000000067F00008000000A000C00000DC000__000000C366619FD8", +"000000067F00008000000A000C00000D8000-000000067F00008000000A000C00000DC000__000000C42FE73810", +"000000067F00008000000A000C00000D862B-000000067F00008000000A000C00000E1D7F__000000C2C7B1ECC1-000000C367E48001", +"000000067F00008000000A000C00000DC000-000000067F00008000000A000C00000E0000__000000C366619FD8", +"000000067F00008000000A000C00000DC000-000000067F00008000000A000C00000E0000__000000C42FE73810", +"000000067F00008000000A000C00000E0000-000000067F00008000000A000C00000E4000__000000C366619FD8", +"000000067F00008000000A000C00000E0000-000000067F00008000000A000C00000E4000__000000C42FE73810", +"000000067F00008000000A000C00000E1D7F-000000067F00008000000A000C00000EB4E5__000000C2C7B1ECC1-000000C367E48001", +"000000067F00008000000A000C00000E4000-000000067F00008000000A000C00000E8000__000000C366619FD8", +"000000067F00008000000A000C00000E4000-000000067F00008000000A000C00000E8000__000000C42FE73810", +"000000067F00008000000A000C00000E8000-000000067F00008000000A000C00000EC000__000000C366619FD8", +"000000067F00008000000A000C00000E8000-000000067F00008000000A000C00000EC000__000000C42FE73810", +"000000067F00008000000A000C00000EB4E5-000000067F00008000000A000C00000F4C0B__000000C2C7B1ECC1-000000C367E48001", +"000000067F00008000000A000C00000EC000-000000067F00008000000A000C00000F0000__000000C366619FD8", +"000000067F00008000000A000C00000EC000-000000067F00008000000A000C00000F0000__000000C42FE73810", +"000000067F00008000000A000C00000F0000-000000067F00008000000A000C00000F4000__000000C366619FD8", +"000000067F00008000000A000C00000F0000-000000067F00008000000A000C00000F4000__000000C42FE73810", +"000000067F00008000000A000C00000F4000-000000067F00008000000A000C00000F8000__000000C366619FD8", +"000000067F00008000000A000C00000F4000-000000067F00008000000A000C00000F8000__000000C42FE73810", +"000000067F00008000000A000C00000F4C0B-000000067F00008000000A000C00000FE371__000000C2C7B1ECC1-000000C367E48001", +"000000067F00008000000A000C00000F8000-000000067F00008000000A000C00000FC000__000000C366619FD8", +"000000067F00008000000A000C00000F8000-000000067F00008000000A000C00000FC000__000000C42FE73810", +"000000067F00008000000A000C00000FC000-000000067F00008000000A000C0000100000__000000C366619FD8", +"000000067F00008000000A000C00000FC000-000000067F00008000000A000C0000100000__000000C42FE73810", +"000000067F00008000000A000C00000FE371-000000067F00008000000A000C0000107AD7__000000C2C7B1ECC1-000000C367E48001", +"000000067F00008000000A000C0000100000-000000067F00008000000A000C0000104000__000000C366619FD8", +"000000067F00008000000A000C0000100000-000000067F00008000000A000C0000104000__000000C42FE73810", +"000000067F00008000000A000C0000102D7F-000000067F00008000000A0014000001409C__000000C3E17E01A1-000000C430961E71", +"000000067F00008000000A000C0000104000-000000067F00008000000A000C0000108000__000000C366619FD8", +"000000067F00008000000A000C0000104000-000000067F00008000000A000C0000108000__000000C42FE73810", +"000000067F00008000000A000C0000107AD7-000000067F00008000000A000C000011120B__000000C2C7B1ECC1-000000C367E48001", +"000000067F00008000000A000C0000108000-000000067F00008000000A000C000010C000__000000C366619FD8", +"000000067F00008000000A000C0000108000-000000067F00008000000A000C000010C000__000000C42FE73810", +"000000067F00008000000A000C000010C000-000000067F00008000000A000C0000110000__000000C366619FD8", +"000000067F00008000000A000C000010C000-000000067F00008000000A000C0000110000__000000C42FE73810", +"000000067F00008000000A000C0000110000-000000067F00008000000A00120100000000__000000C42FE73810", +"000000067F00008000000A000C0000110000-030000000000000000000000000000000002__000000C366619FD8", +"000000067F00008000000A000C000011120B-010000000000000001000000050000000007__000000C2C7B1ECC1-000000C367E48001", +"000000067F00008000000A00140000000000-000000067F00008000000A00140000004000__000000C42FE73810", +"000000067F00008000000A00140000001132-000000067F00008000000A00140000007E49__000000C367E48001-000000C3E17E01A1", +"000000067F00008000000A00140000004000-000000067F00008000000A00140000008000__000000C42FE73810", +"000000067F00008000000A00140000007E49-000000067F00008000000A0014000000EBBC__000000C367E48001-000000C3E17E01A1", +"000000067F00008000000A00140000008000-000000067F00008000000A0014000000C000__000000C42FE73810", +"000000067F00008000000A0014000000C000-000000067F00008000000A00140000010000__000000C42FE73810", +"000000067F00008000000A0014000000EBBC-000000067F00008000000A00140000015925__000000C367E48001-000000C3E17E01A1", +"000000067F00008000000A00140000010000-000000067F00008000000A00140000014000__000000C42FE73810", +"000000067F00008000000A00140000014000-000000067F00008000000A00140000018000__000000C42FE73810", +"000000067F00008000000A0014000001409F-000000067F00008000000A0016000000020E__000000C3E17E01A1-000000C430961E71", +"000000067F00008000000A00140000015925-000000067F00008000000A0014000001C612__000000C367E48001-000000C3E17E01A1", +"000000067F00008000000A00140000018000-000000067F00008000000A0014000001C000__000000C42FE73810", +"000000067F00008000000A0014000001C000-000000067F00008000000A00140000020000__000000C42FE73810", +"000000067F00008000000A0014000001C612-000000067F00008000000A00140000023364__000000C367E48001-000000C3E17E01A1", +"000000067F00008000000A00140000020000-000000067F00008000000A00140000024000__000000C42FE73810", +"000000067F00008000000A00140000023364-000000067F00008000000A0014000002A070__000000C367E48001-000000C3E17E01A1", +"000000067F00008000000A00140000024000-000000067F00008000000A00140000028000__000000C42FE73810", +"000000067F00008000000A00140000028000-000000067F00008000000A0014000002C000__000000C42FE73810", +"000000067F00008000000A0014000002A070-030000000000000000000000000000000002__000000C367E48001-000000C3E17E01A1", +"000000067F00008000000A0014000002C000-030000000000000000000000000000000002__000000C42FE73810", +"000000067F00008000000A0016000000020E-030000000000000000000000000000000002__000000C3E17E01A1-000000C430961E71", +"000000067F00008000000A200C0000000000-000000067F00008000000A200C0000004000__000000C601294000", +"000000067F00008000000A200C0000004000-000000067F00008000000A200C0000008000__000000C601294000", +"000000067F00008000000A200C0000008000-000000067F00008000000A200C000000C000__000000C601294000", +"000000067F00008000000A200C0000009748-000000067F00008000000A200C0000012EAE__000000C430961E71-000000C4C05DDB29", +"000000067F00008000000A200C000000C000-000000067F00008000000A200C0000010000__000000C601294000", +"000000067F00008000000A200C0000010000-000000067F00008000000A200C0000014000__000000C601294000", +"000000067F00008000000A200C0000012EAE-000000067F00008000000A200C000001C60A__000000C430961E71-000000C4C05DDB29", +"000000067F00008000000A200C0000014000-000000067F00008000000A200C0000018000__000000C601294000", +"000000067F00008000000A200C0000018000-000000067F00008000000A200C000001C000__000000C601294000", +"000000067F00008000000A200C000001C000-000000067F00008000000A200C0000020000__000000C601294000", +"000000067F00008000000A200C000001C60A-000000067F00008000000A200C0000025D38__000000C430961E71-000000C4C05DDB29", +"000000067F00008000000A200C0000020000-000000067F00008000000A200C0000024000__000000C601294000", +"000000067F00008000000A200C0000024000-000000067F00008000000A200C0000028000__000000C601294000", +"000000067F00008000000A200C0000025D38-000000067F00008000000A200C000002F49E__000000C430961E71-000000C4C05DDB29", +"000000067F00008000000A200C0000028000-000000067F00008000000A200C000002C000__000000C601294000", +"000000067F00008000000A200C000002C000-000000067F00008000000A200C0000030000__000000C601294000", +"000000067F00008000000A200C000002F49E-000000067F00008000000A200C0000038BB1__000000C430961E71-000000C4C05DDB29", +"000000067F00008000000A200C0000030000-000000067F00008000000A200C0000034000__000000C601294000", +"000000067F00008000000A200C0000034000-000000067F00008000000A200C0000038000__000000C601294000", +"000000067F00008000000A200C0000038000-000000067F00008000000A200C000003C000__000000C601294000", +"000000067F00008000000A200C0000038BB1-000000067F00008000000A200C0000042317__000000C430961E71-000000C4C05DDB29", +"000000067F00008000000A200C000003C000-000000067F00008000000A200C0000040000__000000C601294000", +"000000067F00008000000A200C0000040000-000000067F00008000000A200C0000044000__000000C601294000", +"000000067F00008000000A200C0000042317-000000067F00008000000A200C000004BA7D__000000C430961E71-000000C4C05DDB29", +"000000067F00008000000A200C0000044000-000000067F00008000000A200C0000048000__000000C601294000", +"000000067F00008000000A200C0000048000-000000067F00008000000A200C000004C000__000000C601294000", +"000000067F00008000000A200C000004BA7D-000000067F00008000000A200C00000551B2__000000C430961E71-000000C4C05DDB29", +"000000067F00008000000A200C000004C000-000000067F00008000000A200C0000050000__000000C601294000", +"000000067F00008000000A200C0000050000-000000067F00008000000A200C0000054000__000000C601294000", +"000000067F00008000000A200C0000054000-000000067F00008000000A200C0000058000__000000C5FED35FC8", +"000000067F00008000000A200C0000054000-000000067F00008000000A200C0000058000__000000C6C7BD8140", +"000000067F00008000000A200C00000551B2-030000000000000000000000000000000002__000000C430961E71-000000C4C05DDB29", +"000000067F00008000000A200C0000055230-000000067F00008000000A200C000005E996__000000C4C05DDB29-000000C56021EB29", +"000000067F00008000000A200C0000058000-000000067F00008000000A200C000005C000__000000C5FED35FC8", +"000000067F00008000000A200C0000058000-000000067F00008000000A200C000005C000__000000C6C7BD8140", +"000000067F00008000000A200C000005C000-000000067F00008000000A200C0000060000__000000C5FED35FC8", +"000000067F00008000000A200C000005C000-000000067F00008000000A200C0000060000__000000C6C7BD8140", +"000000067F00008000000A200C000005E996-000000067F00008000000A200C00000680FC__000000C4C05DDB29-000000C56021EB29", +"000000067F00008000000A200C0000060000-000000067F00008000000A200C0000064000__000000C5FED35FC8", +"000000067F00008000000A200C0000060000-000000067F00008000000A200C0000064000__000000C6C7BD8140", +"000000067F00008000000A200C0000064000-000000067F00008000000A200C0000068000__000000C5FED35FC8", +"000000067F00008000000A200C0000064000-000000067F00008000000A200C0000068000__000000C6C7BD8140", +"000000067F00008000000A200C00000677DB-000000067F00008000000A200C00000CF739__000000C689AF4AC1-000000C6C87B6329", +"000000067F00008000000A200C0000068000-000000067F00008000000A200C000006C000__000000C5FED35FC8", +"000000067F00008000000A200C0000068000-000000067F00008000000A200C000006C000__000000C6C7BD8140", +"000000067F00008000000A200C00000680FC-000000067F00008000000A200C000007180C__000000C4C05DDB29-000000C56021EB29", +"000000067F00008000000A200C000006C000-000000067F00008000000A200C0000070000__000000C5FED35FC8", +"000000067F00008000000A200C000006C000-000000067F00008000000A200C0000070000__000000C6C7BD8140", +"000000067F00008000000A200C0000070000-000000067F00008000000A200C0000074000__000000C5FED35FC8", +"000000067F00008000000A200C0000070000-000000067F00008000000A200C0000074000__000000C6C7BD8140", +"000000067F00008000000A200C000007180C-000000067F00008000000A200C000007AF72__000000C4C05DDB29-000000C56021EB29", +"000000067F00008000000A200C0000074000-000000067F00008000000A200C0000078000__000000C5FED35FC8", +"000000067F00008000000A200C0000074000-000000067F00008000000A200C0000078000__000000C6C7BD8140", +"000000067F00008000000A200C0000078000-000000067F00008000000A200C000007C000__000000C5FED35FC8", +"000000067F00008000000A200C0000078000-000000067F00008000000A200C000007C000__000000C6C7BD8140", +"000000067F00008000000A200C000007AF72-000000067F00008000000A200C00000846D8__000000C4C05DDB29-000000C56021EB29", +"000000067F00008000000A200C000007C000-000000067F00008000000A200C0000080000__000000C5FED35FC8", +"000000067F00008000000A200C000007C000-000000067F00008000000A200C0000080000__000000C6C7BD8140", +"000000067F00008000000A200C0000080000-000000067F00008000000A200C0000084000__000000C5FED35FC8", +"000000067F00008000000A200C0000080000-000000067F00008000000A200C0000084000__000000C6C7BD8140", +"000000067F00008000000A200C0000084000-000000067F00008000000A200C0000088000__000000C5FED35FC8", +"000000067F00008000000A200C0000084000-000000067F00008000000A200C0000088000__000000C6C7BD8140", +"000000067F00008000000A200C00000846D8-000000067F00008000000A200C000008DE0B__000000C4C05DDB29-000000C56021EB29", +"000000067F00008000000A200C0000088000-000000067F00008000000A200C000008C000__000000C5FED35FC8", +"000000067F00008000000A200C0000088000-000000067F00008000000A200C000008C000__000000C6C7BD8140", +"000000067F00008000000A200C000008C000-000000067F00008000000A200C0000090000__000000C5FED35FC8", +"000000067F00008000000A200C000008C000-000000067F00008000000A200C0000090000__000000C6C7BD8140", +"000000067F00008000000A200C000008DE0B-000000067F00008000000A200C000009752B__000000C4C05DDB29-000000C56021EB29", +"000000067F00008000000A200C0000090000-000000067F00008000000A200C0000094000__000000C5FED35FC8", +"000000067F00008000000A200C0000090000-000000067F00008000000A200C0000094000__000000C6C7BD8140", +"000000067F00008000000A200C00000933F0-000000067F00008000000A200C0000110901__000000C600A8FFF9-000000C689AF4AC1", +"000000067F00008000000A200C0000094000-000000067F00008000000A200C0000098000__000000C5FED35FC8", +"000000067F00008000000A200C0000094000-000000067F00008000000A200C0000098000__000000C6C7BD8140", +"000000067F00008000000A200C000009752B-000000067F00008000000A200C00000A0C91__000000C4C05DDB29-000000C56021EB29", +"000000067F00008000000A200C0000098000-000000067F00008000000A200C000009C000__000000C5FED35FC8", +"000000067F00008000000A200C0000098000-000000067F00008000000A200C000009C000__000000C6C7BD8140", +"000000067F00008000000A200C000009C000-000000067F00008000000A200C00000A0000__000000C5FED35FC8", +"000000067F00008000000A200C000009C000-000000067F00008000000A200C00000A0000__000000C6C7BD8140", +"000000067F00008000000A200C00000A0000-000000067F00008000000A200C00000A4000__000000C5FED35FC8", +"000000067F00008000000A200C00000A0000-000000067F00008000000A200C00000A4000__000000C6C7BD8140", +"000000067F00008000000A200C00000A0C91-000000067F00008000000A200C00000AA3F7__000000C4C05DDB29-000000C56021EB29", +"000000067F00008000000A200C00000A4000-000000067F00008000000A200C00000A8000__000000C5FED35FC8", +"000000067F00008000000A200C00000A4000-000000067F00008000000A200C00000A8000__000000C6C7BD8140", +"000000067F00008000000A200C00000A8000-000000067F00008000000A200C00000AC000__000000C5FED35FC8", +"000000067F00008000000A200C00000A8000-000000067F00008000000A200C00000AC000__000000C6C7BD8140", +"000000067F00008000000A200C00000AA3F7-000000067F00008000000A200C00000B3B0C__000000C4C05DDB29-000000C56021EB29", +"000000067F00008000000A200C00000AC000-000000067F00008000000A200C00000B0000__000000C5FED35FC8", +"000000067F00008000000A200C00000AC000-000000067F00008000000A200C00000B0000__000000C6C7BD8140", +"000000067F00008000000A200C00000B0000-000000067F00008000000A200C00000B4000__000000C5FED35FC8", +"000000067F00008000000A200C00000B0000-000000067F00008000000A200C00000B4000__000000C6C7BD8140", +"000000067F00008000000A200C00000B3B0C-000000067F00008000000A200C0100000000__000000C4C05DDB29-000000C56021EB29", +"000000067F00008000000A200C00000B4000-000000067F00008000000A200C00000B8000__000000C5FED35FC8", +"000000067F00008000000A200C00000B4000-000000067F00008000000A200C00000B8000__000000C6C7BD8140", +"000000067F00008000000A200C00000B8000-000000067F00008000000A200C00000BC000__000000C5FED35FC8", +"000000067F00008000000A200C00000B8000-000000067F00008000000A200C00000BC000__000000C6C7BD8140", +"000000067F00008000000A200C00000BBC1F-000000067F00008000000A200C00000C5353__000000C56021EB29-000000C600A8FFF9", +"000000067F00008000000A200C00000BC000-000000067F00008000000A200C00000C0000__000000C5FED35FC8", +"000000067F00008000000A200C00000BC000-000000067F00008000000A200C00000C0000__000000C6C7BD8140", +"000000067F00008000000A200C00000C0000-000000067F00008000000A200C00000C4000__000000C5FED35FC8", +"000000067F00008000000A200C00000C0000-000000067F00008000000A200C00000C4000__000000C6C7BD8140", +"000000067F00008000000A200C00000C4000-000000067F00008000000A200C00000C8000__000000C5FED35FC8", +"000000067F00008000000A200C00000C4000-000000067F00008000000A200C00000C8000__000000C6C7BD8140", +"000000067F00008000000A200C00000C5353-000000067F00008000000A200C00000CEAB9__000000C56021EB29-000000C600A8FFF9", +"000000067F00008000000A200C00000C8000-000000067F00008000000A200C00000CC000__000000C5FED35FC8", +"000000067F00008000000A200C00000C8000-000000067F00008000000A200C00000CC000__000000C6C7BD8140", +"000000067F00008000000A200C00000CC000-000000067F00008000000A200C00000D0000__000000C5FED35FC8", +"000000067F00008000000A200C00000CC000-000000067F00008000000A200C00000D0000__000000C6C7BD8140", +"000000067F00008000000A200C00000CEAB9-000000067F00008000000A200C00000D81D2__000000C56021EB29-000000C600A8FFF9", +"000000067F00008000000A200C00000CF742-000000067F00008000000A2014000000B47B__000000C689AF4AC1-000000C6C87B6329", +"000000067F00008000000A200C00000D0000-000000067F00008000000A200C00000D4000__000000C5FED35FC8", +"000000067F00008000000A200C00000D0000-000000067F00008000000A200C00000D4000__000000C6C7BD8140", +"000000067F00008000000A200C00000D4000-000000067F00008000000A200C00000D8000__000000C5FED35FC8", +"000000067F00008000000A200C00000D4000-000000067F00008000000A200C00000D8000__000000C6C7BD8140", +"000000067F00008000000A200C00000D8000-000000067F00008000000A200C00000DC000__000000C5FED35FC8", +"000000067F00008000000A200C00000D8000-000000067F00008000000A200C00000DC000__000000C6C7BD8140", +"000000067F00008000000A200C00000D81D2-000000067F00008000000A200C00000E190B__000000C56021EB29-000000C600A8FFF9", +"000000067F00008000000A200C00000DC000-000000067F00008000000A200C00000E0000__000000C5FED35FC8", +"000000067F00008000000A200C00000DC000-000000067F00008000000A200C00000E0000__000000C6C7BD8140", +"000000067F00008000000A200C00000E0000-000000067F00008000000A200C00000E4000__000000C5FED35FC8", +"000000067F00008000000A200C00000E0000-000000067F00008000000A200C00000E4000__000000C6C7BD8140", +"000000067F00008000000A200C00000E190B-000000067F00008000000A200C00000EB071__000000C56021EB29-000000C600A8FFF9", +"000000067F00008000000A200C00000E4000-000000067F00008000000A200C00000E8000__000000C5FED35FC8", +"000000067F00008000000A200C00000E4000-000000067F00008000000A200C00000E8000__000000C6C7BD8140", +"000000067F00008000000A200C00000E8000-000000067F00008000000A200C00000EC000__000000C5FED35FC8", +"000000067F00008000000A200C00000E8000-000000067F00008000000A200C00000EC000__000000C6C7BD8140", +"000000067F00008000000A200C00000EB071-000000067F00008000000A200C00000F47AC__000000C56021EB29-000000C600A8FFF9", +"000000067F00008000000A200C00000EC000-000000067F00008000000A200C00000F0000__000000C5FED35FC8", +"000000067F00008000000A200C00000EC000-000000067F00008000000A200C00000F0000__000000C6C7BD8140", +"000000067F00008000000A200C00000F0000-000000067F00008000000A200C00000F4000__000000C5FED35FC8", +"000000067F00008000000A200C00000F0000-000000067F00008000000A200C00000F4000__000000C6C7BD8140", +"000000067F00008000000A200C00000F4000-000000067F00008000000A200C00000F8000__000000C5FED35FC8", +"000000067F00008000000A200C00000F4000-000000067F00008000000A200C00000F8000__000000C6C7BD8140", +"000000067F00008000000A200C00000F47AC-000000067F00008000000A200C00000FDF0A__000000C56021EB29-000000C600A8FFF9", +"000000067F00008000000A200C00000F8000-000000067F00008000000A200C00000FC000__000000C5FED35FC8", +"000000067F00008000000A200C00000F8000-000000067F00008000000A200C00000FC000__000000C6C7BD8140", +"000000067F00008000000A200C00000FC000-000000067F00008000000A200C0000100000__000000C5FED35FC8", +"000000067F00008000000A200C00000FC000-000000067F00008000000A200C0000100000__000000C6C7BD8140", +"000000067F00008000000A200C00000FDF0A-000000067F00008000000A200C000010762B__000000C56021EB29-000000C600A8FFF9", +"000000067F00008000000A200C0000100000-000000067F00008000000A200C0000104000__000000C5FED35FC8", +"000000067F00008000000A200C0000100000-000000067F00008000000A200C0000104000__000000C6C7BD8140", +"000000067F00008000000A200C0000104000-000000067F00008000000A200C0000108000__000000C5FED35FC8", +"000000067F00008000000A200C0000104000-000000067F00008000000A200C0000108000__000000C6C7BD8140", +"000000067F00008000000A200C000010762B-000000067F00008000000A200C0000110D88__000000C56021EB29-000000C600A8FFF9", +"000000067F00008000000A200C0000108000-000000067F00008000000A200C000010C000__000000C5FED35FC8", +"000000067F00008000000A200C0000108000-000000067F00008000000A200C000010C000__000000C6C7BD8140", +"000000067F00008000000A200C000010C000-000000067F00008000000A200C0000110000__000000C5FED35FC8", +"000000067F00008000000A200C000010C000-000000067F00008000000A200C0000110000__000000C6C7BD8140", +"000000067F00008000000A200C0000110000-000000067F00008000000A20120100000000__000000C6C7BD8140", +"000000067F00008000000A200C0000110000-030000000000000000000000000000000002__000000C5FED35FC8", +"000000067F00008000000A200C0000110901-000000067F00008000000A201400000047CD__000000C600A8FFF9-000000C689AF4AC1", +"000000067F00008000000A200C0000110D88-01000000000000000100000005000000000A__000000C56021EB29-000000C600A8FFF9", +"000000067F00008000000A20140000000000-000000067F00008000000A20140000004000__000000C6C7BD8140", +"000000067F00008000000A20140000004000-000000067F00008000000A20140000008000__000000C6C7BD8140", +"000000067F00008000000A201400000047CD-000000067F00008000000A2014000000ADA8__000000C600A8FFF9-000000C689AF4AC1", +"000000067F00008000000A20140000008000-000000067F00008000000A2014000000C000__000000C6C7BD8140", +"000000067F00008000000A2014000000ADA8-000000067F00008000000A201400000113B8__000000C600A8FFF9-000000C689AF4AC1", +"000000067F00008000000A2014000000B47C-010000000000000001000000050100000000__000000C689AF4AC1-000000C6C87B6329", +"000000067F00008000000A2014000000C000-000000067F00008000000A20140000010000__000000C6C7BD8140", +"000000067F00008000000A20140000010000-000000067F00008000000A20140000014000__000000C6C7BD8140", +"000000067F00008000000A201400000113B8-000000067F00008000000A20140000017969__000000C600A8FFF9-000000C689AF4AC1", +"000000067F00008000000A20140000014000-000000067F00008000000A20140000018000__000000C6C7BD8140", +"000000067F00008000000A20140000017969-000000067F00008000000A2014000001DF7E__000000C600A8FFF9-000000C689AF4AC1", +"000000067F00008000000A20140000018000-000000067F00008000000A2014000001C000__000000C6C7BD8140", +"000000067F00008000000A2014000001C000-000000067F00008000000A20140000020000__000000C6C7BD8140", +"000000067F00008000000A2014000001DF7E-000000067F00008000000A2014000002457D__000000C600A8FFF9-000000C689AF4AC1", +"000000067F00008000000A20140000020000-000000067F00008000000A20140000024000__000000C6C7BD8140", +"000000067F00008000000A20140000024000-000000067F00008000000A20140000028000__000000C6C7BD8140", +"000000067F00008000000A2014000002457D-000000067F00008000000A2014000002AB1D__000000C600A8FFF9-000000C689AF4AC1", +"000000067F00008000000A20140000028000-000000067F00008000000A2014000002C000__000000C6C7BD8140", +"000000067F00008000000A2014000002AB1D-030000000000000000000000000000000002__000000C600A8FFF9-000000C689AF4AC1", +"000000067F00008000000A2014000002C000-030000000000000000000000000000000002__000000C6C7BD8140", +"000000067F00008000000A400C0000000000-000000067F00008000000A400C0000004000__000000C896B8DFD8", +"000000067F00008000000A400C0000004000-000000067F00008000000A400C0000008000__000000C896B8DFD8", +"000000067F00008000000A400C0000008000-000000067F00008000000A400C000000C000__000000C896B8DFD8", +"000000067F00008000000A400C0000009743-000000067F00008000000A400C0000012EA9__000000C6C87B6329-000000C74849FAE1", +"000000067F00008000000A400C000000C000-000000067F00008000000A400C0000010000__000000C896B8DFD8", +"000000067F00008000000A400C0000010000-000000067F00008000000A400C0000014000__000000C896B8DFD8", +"000000067F00008000000A400C0000012EA9-000000067F00008000000A400C000001C60A__000000C6C87B6329-000000C74849FAE1", +"000000067F00008000000A400C0000014000-000000067F00008000000A400C0000018000__000000C896B8DFD8", +"000000067F00008000000A400C0000018000-000000067F00008000000A400C000001C000__000000C896B8DFD8", +"000000067F00008000000A400C000001C000-000000067F00008000000A400C0000020000__000000C896B8DFD8", +"000000067F00008000000A400C000001C60A-000000067F00008000000A400C0000025D38__000000C6C87B6329-000000C74849FAE1", +"000000067F00008000000A400C0000020000-000000067F00008000000A400C0000024000__000000C896B8DFD8", +"000000067F00008000000A400C0000024000-000000067F00008000000A400C0000028000__000000C896B8DFD8", +"000000067F00008000000A400C0000025D38-000000067F00008000000A400C000002F49E__000000C6C87B6329-000000C74849FAE1", +"000000067F00008000000A400C0000028000-000000067F00008000000A400C000002C000__000000C896B8DFD8", +"000000067F00008000000A400C000002C000-000000067F00008000000A400C0000030000__000000C896B8DFD8", +"000000067F00008000000A400C000002F49E-000000067F00008000000A400C0000038BB1__000000C6C87B6329-000000C74849FAE1", +"000000067F00008000000A400C0000030000-000000067F00008000000A400C0000034000__000000C896B8DFD8", +"000000067F00008000000A400C0000034000-000000067F00008000000A400C0000038000__000000C896B8DFD8", +"000000067F00008000000A400C0000038000-000000067F00008000000A400C000003C000__000000C896B8DFD8", +"000000067F00008000000A400C0000038BB1-000000067F00008000000A400C0000042317__000000C6C87B6329-000000C74849FAE1", +"000000067F00008000000A400C000003C000-000000067F00008000000A400C0000040000__000000C896B8DFD8", +"000000067F00008000000A400C0000040000-000000067F00008000000A400C0000044000__000000C896B8DFD8", +"000000067F00008000000A400C0000042317-000000067F00008000000A400C000004BA7D__000000C6C87B6329-000000C74849FAE1", +"000000067F00008000000A400C0000044000-000000067F00008000000A400C0000048000__000000C896B8DFD8", +"000000067F00008000000A400C0000048000-000000067F00008000000A400C000004C000__000000C896B8DFD8", +"000000067F00008000000A400C000004BA7D-030000000000000000000000000000000002__000000C6C87B6329-000000C74849FAE1", +"000000067F00008000000A400C000004C000-000000067F00008000000A400C0000050000__000000C896B8DFD8", +"000000067F00008000000A400C0000050000-000000067F00008000000A400C0000054000__000000C896B8DFD8", +"000000067F00008000000A400C0000054000-000000067F00008000000A400C0000058000__000000C896B8DFD8", +"000000067F00008000000A400C00000551FC-000000067F00008000000A400C000005E90B__000000C74849FAE1-000000C80801E859", +"000000067F00008000000A400C0000058000-000000067F00008000000A400C000005C000__000000C896B8DFD8", +"000000067F00008000000A400C000005C000-000000067F00008000000A400C0000060000__000000C896B8DFD8", +"000000067F00008000000A400C000005E90B-000000067F00008000000A400C000006802B__000000C74849FAE1-000000C80801E859", +"000000067F00008000000A400C0000060000-000000067F00008000000A400C0000064000__000000C896B8DFD8", +"000000067F00008000000A400C0000064000-000000067F00008000000A400C0000068000__000000C896B8DFD8", +"000000067F00008000000A400C0000068000-000000067F00008000000A400C000006C000__000000C896B8DFD8", +"000000067F00008000000A400C000006802B-000000067F00008000000A400C0000071782__000000C74849FAE1-000000C80801E859", +"000000067F00008000000A400C000006C000-000000067F00008000000A400C0000070000__000000C896B8DFD8", +"000000067F00008000000A400C0000070000-000000067F00008000000A400C0000074000__000000C896B8DFD8", +"000000067F00008000000A400C0000071782-000000067F00008000000A400C000007AEE8__000000C74849FAE1-000000C80801E859", +"000000067F00008000000A400C0000074000-000000067F00008000000A400C0000078000__000000C896B8DFD8", +"000000067F00008000000A400C0000078000-000000067F00008000000A400C000007C000__000000C896B8DFD8", +"000000067F00008000000A400C000007AEE8-000000067F00008000000A400C000008460B__000000C74849FAE1-000000C80801E859", +"000000067F00008000000A400C000007C000-000000067F00008000000A400C0000080000__000000C896B8DFD8", +"000000067F00008000000A400C0000080000-000000067F00008000000A400C0000084000__000000C896B8DFD8", +"000000067F00008000000A400C0000084000-000000067F00008000000A400C0000088000__000000C896B8DFD8", +"000000067F00008000000A400C000008460B-000000067F00008000000A400C000008DD71__000000C74849FAE1-000000C80801E859", +"000000067F00008000000A400C0000088000-000000067F00008000000A400C000008C000__000000C896B8DFD8", +"000000067F00008000000A400C000008C000-000000067F00008000000A400C0000090000__000000C896B8DFD8", +"000000067F00008000000A400C000008DD71-000000067F00008000000A400C00000974D7__000000C74849FAE1-000000C80801E859", +"000000067F00008000000A400C0000090000-000000067F00008000000A400C0000094000__000000C896B8DFD8", +"000000067F00008000000A400C0000094000-000000067F00008000000A400C0000098000__000000C896B8DFD8", +"000000067F00008000000A400C00000974D7-000000067F00008000000A400C00000A0C0B__000000C74849FAE1-000000C80801E859", +"000000067F00008000000A400C0000098000-000000067F00008000000A400C000009C000__000000C896B8DFD8", +"000000067F00008000000A400C000009C000-000000067F00008000000A400C00000A0000__000000C896B8DFD8", +"000000067F00008000000A400C00000A0000-000000067F00008000000A400C00000A4000__000000C896B8DFD8", +"000000067F00008000000A400C00000A0C0B-000000067F00008000000A400C00000AA371__000000C74849FAE1-000000C80801E859", +"000000067F00008000000A400C00000A4000-000000067F00008000000A400C00000A8000__000000C896B8DFD8", +"000000067F00008000000A400C00000A8000-000000067F00008000000A400C00000AC000__000000C896B8DFD8", +"000000067F00008000000A400C00000AA371-000000067F00008000000A400C00000B3AD7__000000C74849FAE1-000000C80801E859", +"000000067F00008000000A400C00000AC000-000000067F00008000000A400C00000B0000__000000C896B8DFD8", +"000000067F00008000000A400C00000B0000-000000067F00008000000A400C00000B4000__000000C896B8DFD8", +"000000067F00008000000A400C00000B3AD7-000000067F00008000000A400C00000BD20B__000000C74849FAE1-000000C80801E859", +"000000067F00008000000A400C00000B4000-000000067F00008000000A400C00000B8000__000000C896B8DFD8", +"000000067F00008000000A400C00000B8000-000000067F00008000000A400C00000BC000__000000C896B8DFD8", +"000000067F00008000000A400C00000BC000-000000067F00008000000A400C00000C0000__000000C896B8DFD8", +"000000067F00008000000A400C00000BD20B-000000067F00008000000A400C0100000000__000000C74849FAE1-000000C80801E859", +"000000067F00008000000A400C00000C0000-000000067F00008000000A400C00000C4000__000000C896B8DFD8", +"000000067F00008000000A400C00000C4000-000000067F00008000000A400C00000C8000__000000C896B8DFD8", +"000000067F00008000000A400C00000C4AE6-000000067F00008000000A400C00000CE20C__000000C80801E859-000000C8993EBFF9", +"000000067F00008000000A400C00000C8000-000000067F00008000000A400C00000CC000__000000C896B8DFD8", +"000000067F00008000000A400C00000CC000-000000067F00008000000A400C00000D0000__000000C896B8DFD8", +"000000067F00008000000A400C00000CE20C-000000067F00008000000A400C00000D7929__000000C80801E859-000000C8993EBFF9", +"000000067F00008000000A400C00000D0000-000000067F00008000000A400C00000D4000__000000C896B8DFD8", +"000000067F00008000000A400C00000D4000-000000067F00008000000A400C00000D8000__000000C896B8DFD8", +"000000067F00008000000A400C00000D7929-000000067F00008000000A400C00000E108F__000000C80801E859-000000C8993EBFF9", +"000000067F00008000000A400C00000D8000-000000067F00008000000A400C00000DC000__000000C896B8DFD8", +"000000067F00008000000A400C00000DC000-000000067F00008000000A400C00000E0000__000000C896B8DFD8", +"000000067F00008000000A400C00000E0000-000000067F00008000000A400C00000E4000__000000C896B8DFD8", +"000000067F00008000000A400C00000E108F-000000067F00008000000A400C00000EA7F5__000000C80801E859-000000C8993EBFF9", +"000000067F00008000000A400C00000E4000-000000067F00008000000A400C00000E8000__000000C896B8DFD8", +"000000067F00008000000A400C00000E8000-000000067F00008000000A400C00000EC000__000000C896B8DFD8", +"000000067F00008000000A400C00000EA7F5-000000067F00008000000A400C00000F3F0B__000000C80801E859-000000C8993EBFF9", +"000000067F00008000000A400C00000EC000-000000067F00008000000A400C00000F0000__000000C896B8DFD8", +"000000067F00008000000A400C00000F0000-000000067F00008000000A400C00000F4000__000000C896B8DFD8", +"000000067F00008000000A400C00000F3F0B-000000067F00008000000A400C00000FD671__000000C80801E859-000000C8993EBFF9", +"000000067F00008000000A400C00000F4000-000000067F00008000000A400C00000F8000__000000C896B8DFD8", +"000000067F00008000000A400C00000F8000-000000067F00008000000A400C00000FC000__000000C896B8DFD8", +"000000067F00008000000A400C00000FC000-000000067F00008000000A400C0000100000__000000C896B8DFD8", +"000000067F00008000000A400C00000FD671-000000067F00008000000A400C0000106D95__000000C80801E859-000000C8993EBFF9", +"000000067F00008000000A400C0000100000-000000067F00008000000A400C0000104000__000000C896B8DFD8", +"000000067F00008000000A400C0000104000-000000067F00008000000A400C0000108000__000000C896B8DFD8", +"000000067F00008000000A400C0000106D95-000000067F00008000000A400C00001104FB__000000C80801E859-000000C8993EBFF9", +"000000067F00008000000A400C0000107F8F-000000067F00008000000A40140000005626__000000C8993EBFF9-000000C90726D0D9", +"000000067F00008000000A400C0000108000-000000067F00008000000A400C000010C000__000000C896B8DFD8", +"000000067F00008000000A400C000010C000-000000067F00008000000A400C0000110000__000000C896B8DFD8", +"000000067F00008000000A400C0000110000-030000000000000000000000000000000002__000000C896B8DFD8", +"000000067F00008000000A400C00001104FB-01000000000000000100000005000000000D__000000C80801E859-000000C8993EBFF9", +"000000067F00008000000A40140000005626-000000067F00008000000A4014000000C7F9__000000C8993EBFF9-000000C90726D0D9", +"000000067F00008000000A4014000000C7F9-000000067F00008000000A401400000139F8__000000C8993EBFF9-000000C90726D0D9", +"000000067F00008000000A401400000139F8-000000067F00008000000A4014000001ABE9__000000C8993EBFF9-000000C90726D0D9", +"000000067F00008000000A4014000001ABE9-000000067F00008000000A40140000021DF4__000000C8993EBFF9-000000C90726D0D9", +"000000067F00008000000A40140000021DF4-000000067F00008000000A40140000028FA9__000000C8993EBFF9-000000C90726D0D9", +"000000067F00008000000A40140000028FA9-030000000000000000000000000000000002__000000C8993EBFF9-000000C90726D0D9", +"000000067F00008000000A600C0000000000-000000067F00008000000A600C0000004000__000000CA2C877DC8", +"000000067F00008000000A600C0000000000-000000067F00008000000A600C0000004000__000000CB82C2FF68", +"000000067F00008000000A600C0000004000-000000067F00008000000A600C0000008000__000000CA2C877DC8", +"000000067F00008000000A600C0000004000-000000067F00008000000A600C0000008000__000000CB82C2FF68", +"000000067F00008000000A600C0000008000-000000067F00008000000A600C000000C000__000000CA2C877DC8", +"000000067F00008000000A600C0000008000-000000067F00008000000A600C000000C000__000000CB82C2FF68", +"000000067F00008000000A600C0000009746-000000067F00008000000A600C0000012EAC__000000C90726D0D9-000000C986F5F0D9", +"000000067F00008000000A600C000000C000-000000067F00008000000A600C0000010000__000000CA2C877DC8", +"000000067F00008000000A600C000000C000-000000067F00008000000A600C0000010000__000000CB82C2FF68", +"000000067F00008000000A600C0000010000-000000067F00008000000A600C0000014000__000000CA2C877DC8", +"000000067F00008000000A600C0000010000-000000067F00008000000A600C0000014000__000000CB82C2FF68", +"000000067F00008000000A600C0000012EAC-000000067F00008000000A600C000001C60A__000000C90726D0D9-000000C986F5F0D9", +"000000067F00008000000A600C0000014000-000000067F00008000000A600C0000018000__000000CA2C877DC8", +"000000067F00008000000A600C0000014000-000000067F00008000000A600C0000018000__000000CB82C2FF68", +"000000067F00008000000A600C0000018000-000000067F00008000000A600C000001C000__000000CA2C877DC8", +"000000067F00008000000A600C0000018000-000000067F00008000000A600C000001C000__000000CB82C2FF68", +"000000067F00008000000A600C000001C000-000000067F00008000000A600C0000020000__000000CA2C877DC8", +"000000067F00008000000A600C000001C000-000000067F00008000000A600C0000020000__000000CB82C2FF68", +"000000067F00008000000A600C000001C60A-000000067F00008000000A600C0000025D38__000000C90726D0D9-000000C986F5F0D9", +"000000067F00008000000A600C0000020000-000000067F00008000000A600C0000024000__000000CA2C877DC8", +"000000067F00008000000A600C0000020000-000000067F00008000000A600C0000024000__000000CB82C2FF68", +"000000067F00008000000A600C0000024000-000000067F00008000000A600C0000028000__000000CA2C877DC8", +"000000067F00008000000A600C0000024000-000000067F00008000000A600C0000028000__000000CB82C2FF68", +"000000067F00008000000A600C0000025D38-000000067F00008000000A600C000002F49E__000000C90726D0D9-000000C986F5F0D9", +"000000067F00008000000A600C0000028000-000000067F00008000000A600C000002C000__000000CA2C877DC8", +"000000067F00008000000A600C0000028000-000000067F00008000000A600C000002C000__000000CB82C2FF68", +"000000067F00008000000A600C000002C000-000000067F00008000000A600C0000030000__000000CA2C877DC8", +"000000067F00008000000A600C000002C000-000000067F00008000000A600C0000030000__000000CB82C2FF68", +"000000067F00008000000A600C000002F49E-000000067F00008000000A600C0000038BB1__000000C90726D0D9-000000C986F5F0D9", +"000000067F00008000000A600C0000030000-000000067F00008000000A600C0000034000__000000CA2C877DC8", +"000000067F00008000000A600C0000030000-000000067F00008000000A600C0000034000__000000CB82C2FF68", +"000000067F00008000000A600C0000034000-000000067F00008000000A600C0000038000__000000CA2C877DC8", +"000000067F00008000000A600C0000034000-000000067F00008000000A600C0000038000__000000CB82C2FF68", +"000000067F00008000000A600C0000038000-000000067F00008000000A600C000003C000__000000CA2C877DC8", +"000000067F00008000000A600C0000038000-000000067F00008000000A600C000003C000__000000CB82C2FF68", +"000000067F00008000000A600C0000038BB1-000000067F00008000000A600C0000042317__000000C90726D0D9-000000C986F5F0D9", +"000000067F00008000000A600C000003C000-000000067F00008000000A600C0000040000__000000CA2C877DC8", +"000000067F00008000000A600C000003C000-000000067F00008000000A600C0000040000__000000CB82C2FF68", +"000000067F00008000000A600C0000040000-000000067F00008000000A600C0000044000__000000CA2C877DC8", +"000000067F00008000000A600C0000040000-000000067F00008000000A600C0000044000__000000CB82C2FF68", +"000000067F00008000000A600C0000042317-000000067F00008000000A600C000004BA7D__000000C90726D0D9-000000C986F5F0D9", +"000000067F00008000000A600C0000044000-000000067F00008000000A600C0000048000__000000CA2C877DC8", +"000000067F00008000000A600C0000044000-000000067F00008000000A600C0000048000__000000CB82C2FF68", +"000000067F00008000000A600C0000048000-000000067F00008000000A600C000004C000__000000CA2C877DC8", +"000000067F00008000000A600C0000048000-000000067F00008000000A600C000004C000__000000CB82C2FF68", +"000000067F00008000000A600C000004BA7D-030000000000000000000000000000000002__000000C90726D0D9-000000C986F5F0D9", +"000000067F00008000000A600C000004C000-000000067F00008000000A600C0000050000__000000CA2C877DC8", +"000000067F00008000000A600C000004C000-000000067F00008000000A600C0000050000__000000CB82C2FF68", +"000000067F00008000000A600C0000050000-000000067F00008000000A600C0000054000__000000CA2C877DC8", +"000000067F00008000000A600C0000050000-000000067F00008000000A600C0000054000__000000CB82C2FF68", +"000000067F00008000000A600C0000054000-000000067F00008000000A600C0000058000__000000CA2C877DC8", +"000000067F00008000000A600C0000054000-000000067F00008000000A600C0000058000__000000CB82C2FF68", +"000000067F00008000000A600C0000054BFB-000000067F00008000000A600C000005E30C__000000C986F5F0D9-000000CAD5D7FFF1", +"000000067F00008000000A600C0000058000-000000067F00008000000A600C000005C000__000000CA2C877DC8", +"000000067F00008000000A600C0000058000-000000067F00008000000A600C000005C000__000000CB82C2FF68", +"000000067F00008000000A600C000005C000-000000067F00008000000A600C0000060000__000000CA2C877DC8", +"000000067F00008000000A600C000005C000-000000067F00008000000A600C0000060000__000000CB82C2FF68", +"000000067F00008000000A600C000005E30C-000000067F00008000000A600C0000067A2B__000000C986F5F0D9-000000CAD5D7FFF1", +"000000067F00008000000A600C0000060000-000000067F00008000000A600C0000064000__000000CA2C877DC8", +"000000067F00008000000A600C0000060000-000000067F00008000000A600C0000064000__000000CB82C2FF68", +"000000067F00008000000A600C0000064000-000000067F00008000000A600C0000068000__000000CA2C877DC8", +"000000067F00008000000A600C0000064000-000000067F00008000000A600C0000068000__000000CB82C2FF68", +"000000067F00008000000A600C0000067A2B-000000067F00008000000A600C0000071186__000000C986F5F0D9-000000CAD5D7FFF1", +"000000067F00008000000A600C0000068000-000000067F00008000000A600C000006C000__000000CA2C877DC8", +"000000067F00008000000A600C0000068000-000000067F00008000000A600C000006C000__000000CB82C2FF68", +"000000067F00008000000A600C000006C000-000000067F00008000000A600C0000070000__000000CA2C877DC8", +"000000067F00008000000A600C000006C000-000000067F00008000000A600C0000070000__000000CB82C2FF68", +"000000067F00008000000A600C0000070000-000000067F00008000000A600C0000074000__000000CA2C877DC8", +"000000067F00008000000A600C0000070000-000000067F00008000000A600C0000074000__000000CB82C2FF68", +"000000067F00008000000A600C0000071186-000000067F00008000000A600C000007A8EC__000000C986F5F0D9-000000CAD5D7FFF1", +"000000067F00008000000A600C0000074000-000000067F00008000000A600C0000078000__000000CA2C877DC8", +"000000067F00008000000A600C0000074000-000000067F00008000000A600C0000078000__000000CB82C2FF68", +"000000067F00008000000A600C0000078000-000000067F00008000000A600C000007C000__000000CA2C877DC8", +"000000067F00008000000A600C0000078000-000000067F00008000000A600C000007C000__000000CB82C2FF68", +"000000067F00008000000A600C000007A149-000000067F00008000000A600C00000F5F42__000000CB40C16489-000000CB82C37859", +"000000067F00008000000A600C000007A8EC-000000067F00008000000A600C000008400A__000000C986F5F0D9-000000CAD5D7FFF1", +"000000067F00008000000A600C000007C000-000000067F00008000000A600C0000080000__000000CA2C877DC8", +"000000067F00008000000A600C000007C000-000000067F00008000000A600C0000080000__000000CB82C2FF68", +"000000067F00008000000A600C0000080000-000000067F00008000000A600C0000084000__000000CA2C877DC8", +"000000067F00008000000A600C0000080000-000000067F00008000000A600C0000084000__000000CB82C2FF68", +"000000067F00008000000A600C0000084000-000000067F00008000000A600C0000088000__000000CA2C877DC8", +"000000067F00008000000A600C0000084000-000000067F00008000000A600C0000088000__000000CB82C2FF68", +"000000067F00008000000A600C000008400A-000000067F00008000000A600C000008D770__000000C986F5F0D9-000000CAD5D7FFF1", +"000000067F00008000000A600C0000088000-000000067F00008000000A600C000008C000__000000CA2C877DC8", +"000000067F00008000000A600C0000088000-000000067F00008000000A600C000008C000__000000CB82C2FF68", +"000000067F00008000000A600C000008C000-000000067F00008000000A600C0000090000__000000CA2C877DC8", +"000000067F00008000000A600C000008C000-000000067F00008000000A600C0000090000__000000CB82C2FF68", +"000000067F00008000000A600C000008D770-000000067F00008000000A600C0000096ED6__000000C986F5F0D9-000000CAD5D7FFF1", +"000000067F00008000000A600C0000090000-000000067F00008000000A600C0000094000__000000CA2C877DC8", +"000000067F00008000000A600C0000090000-000000067F00008000000A600C0000094000__000000CB82C2FF68", +"000000067F00008000000A600C0000094000-000000067F00008000000A600C0000098000__000000CA2C877DC8", +"000000067F00008000000A600C0000094000-000000067F00008000000A600C0000098000__000000CB82C2FF68", +"000000067F00008000000A600C0000096ED6-000000067F00008000000A600C00000A060B__000000C986F5F0D9-000000CAD5D7FFF1", +"000000067F00008000000A600C0000098000-000000067F00008000000A600C000009C000__000000CA2C877DC8", +"000000067F00008000000A600C0000098000-000000067F00008000000A600C000009C000__000000CB82C2FF68", +"000000067F00008000000A600C000009C000-000000067F00008000000A600C00000A0000__000000CA2C877DC8", +"000000067F00008000000A600C000009C000-000000067F00008000000A600C00000A0000__000000CB82C2FF68", +"000000067F00008000000A600C00000A0000-000000067F00008000000A600C00000A4000__000000CA2C877DC8", +"000000067F00008000000A600C00000A0000-000000067F00008000000A600C00000A4000__000000CB82C2FF68", +"000000067F00008000000A600C00000A060B-000000067F00008000000A600C00000A9D71__000000C986F5F0D9-000000CAD5D7FFF1", +"000000067F00008000000A600C00000A4000-000000067F00008000000A600C00000A8000__000000CA2C877DC8", +"000000067F00008000000A600C00000A4000-000000067F00008000000A600C00000A8000__000000CB82C2FF68", +"000000067F00008000000A600C00000A8000-000000067F00008000000A600C00000AC000__000000CA2C877DC8", +"000000067F00008000000A600C00000A8000-000000067F00008000000A600C00000AC000__000000CB82C2FF68", +"000000067F00008000000A600C00000A9D71-000000067F00008000000A600C00000B34D7__000000C986F5F0D9-000000CAD5D7FFF1", +"000000067F00008000000A600C00000AC000-000000067F00008000000A600C00000B0000__000000CB82C2FF68", +"000000067F00008000000A600C00000AC000-030000000000000000000000000000000002__000000CA2C877DC8", +"000000067F00008000000A600C00000B0000-000000067F00008000000A600C00000B4000__000000CB82C2FF68", +"000000067F00008000000A600C00000B34D7-000000067F00008000000A600C00000BCC0C__000000C986F5F0D9-000000CAD5D7FFF1", +"000000067F00008000000A600C00000B4000-000000067F00008000000A600C00000B8000__000000CB82C2FF68", +"000000067F00008000000A600C00000B8000-000000067F00008000000A600C00000BC000__000000CB82C2FF68", +"000000067F00008000000A600C00000BC000-000000067F00008000000A600C00000C0000__000000CB82C2FF68", +"000000067F00008000000A600C00000BCC0C-000000067F00008000000A600C00000C6336__000000C986F5F0D9-000000CAD5D7FFF1", +"000000067F00008000000A600C00000C0000-000000067F00008000000A600C00000C4000__000000CB82C2FF68", +"000000067F00008000000A600C00000C4000-000000067F00008000000A600C00000C8000__000000CB82C2FF68", +"000000067F00008000000A600C00000C6336-000000067F00008000000A600C00000CFA9C__000000C986F5F0D9-000000CAD5D7FFF1", +"000000067F00008000000A600C00000C8000-000000067F00008000000A600C00000CC000__000000CB82C2FF68", +"000000067F00008000000A600C00000CC000-000000067F00008000000A600C00000D0000__000000CB82C2FF68", +"000000067F00008000000A600C00000CFA9C-000000067F00008000000A600C00000D91AB__000000C986F5F0D9-000000CAD5D7FFF1", +"000000067F00008000000A600C00000D0000-000000067F00008000000A600C00000D4000__000000CB82C2FF68", +"000000067F00008000000A600C00000D4000-000000067F00008000000A600C00000D8000__000000CB82C2FF68", +"000000067F00008000000A600C00000D8000-000000067F00008000000A600C00000DC000__000000CB82C2FF68", +"000000067F00008000000A600C00000D91AB-000000067F00008000000A600C00000E2911__000000C986F5F0D9-000000CAD5D7FFF1", +"000000067F00008000000A600C00000DC000-000000067F00008000000A600C00000E0000__000000CB82C2FF68", +"000000067F00008000000A600C00000E0000-000000067F00008000000A600C00000E4000__000000CB82C2FF68", +"000000067F00008000000A600C00000E2911-000000067F00008000000A600C00000EC077__000000C986F5F0D9-000000CAD5D7FFF1", +"000000067F00008000000A600C00000E4000-000000067F00008000000A600C00000E8000__000000CB82C2FF68", +"000000067F00008000000A600C00000E8000-000000067F00008000000A600C00000EC000__000000CB82C2FF68", +"000000067F00008000000A600C00000EC000-000000067F00008000000A600C00000F0000__000000CB82C2FF68", +"000000067F00008000000A600C00000EC077-000000067F00008000000A600C00000F57A8__000000C986F5F0D9-000000CAD5D7FFF1", +"000000067F00008000000A600C00000F0000-000000067F00008000000A600C00000F4000__000000CB82C2FF68", +"000000067F00008000000A600C00000F4000-000000067F00008000000A600C00000F8000__000000CB82C2FF68", +"000000067F00008000000A600C00000F57A8-000000067F00008000000A600C00000FEF0A__000000C986F5F0D9-000000CAD5D7FFF1", +"000000067F00008000000A600C00000F5F4F-000000067F00008000000A60140000011158__000000CB40C16489-000000CB82C37859", +"000000067F00008000000A600C00000F8000-000000067F00008000000A600C00000FC000__000000CB82C2FF68", +"000000067F00008000000A600C00000FC000-000000067F00008000000A600C0000100000__000000CB82C2FF68", +"000000067F00008000000A600C00000FEF0A-000000067F00008000000A600C000010862B__000000C986F5F0D9-000000CAD5D7FFF1", +"000000067F00008000000A600C0000100000-000000067F00008000000A600C0000104000__000000CB82C2FF68", +"000000067F00008000000A600C0000104000-000000067F00008000000A600C0000108000__000000CB82C2FF68", +"000000067F00008000000A600C0000108000-000000067F00008000000A600C000010C000__000000CB82C2FF68", +"000000067F00008000000A600C000010862B-000000067F00008000000A600C0000111C20__000000C986F5F0D9-000000CAD5D7FFF1", +"000000067F00008000000A600C000010C000-000000067F00008000000A600C0000110000__000000CB82C2FF68", +"000000067F00008000000A600C0000110000-000000067F00008000000A60120100000000__000000CB82C2FF68", +"000000067F00008000000A600C00001117CB-000000067F00008000000A6014000000499B__000000CAD5D7FFF1-000000CB40C16489", +"000000067F00008000000A600C00FFFFFFFF-01000000000000000100000005000000000E__000000C986F5F0D9-000000CAD5D7FFF1", +"000000067F00008000000A60140000000000-000000067F00008000000A60140000004000__000000CB82C2FF68", +"000000067F00008000000A60140000004000-000000067F00008000000A60140000008000__000000CB82C2FF68", +"000000067F00008000000A6014000000499B-000000067F00008000000A6014000000BD4E__000000CAD5D7FFF1-000000CB40C16489", +"000000067F00008000000A60140000008000-000000067F00008000000A6014000000C000__000000CB82C2FF68", +"000000067F00008000000A6014000000BD4E-000000067F00008000000A601400000130ED__000000CAD5D7FFF1-000000CB40C16489", +"000000067F00008000000A6014000000C000-000000067F00008000000A60140000010000__000000CB82C2FF68", +"000000067F00008000000A60140000010000-000000067F00008000000A60140000014000__000000CB82C2FF68", +"000000067F00008000000A60140000011159-000000067F00008000000A60140000029BB2__000000CB40C16489-000000CB82C37859", +"000000067F00008000000A601400000130ED-000000067F00008000000A6014000001A4BD__000000CAD5D7FFF1-000000CB40C16489", +"000000067F00008000000A60140000014000-000000067F00008000000A60140000018000__000000CB82C2FF68", +"000000067F00008000000A60140000018000-000000067F00008000000A6014000001C000__000000CB82C2FF68", +"000000067F00008000000A6014000001A4BD-000000067F00008000000A60140000021886__000000CAD5D7FFF1-000000CB40C16489", +"000000067F00008000000A6014000001C000-000000067F00008000000A60140000020000__000000CB82C2FF68", +"000000067F00008000000A60140000020000-000000067F00008000000A60140000024000__000000CB82C2FF68", +"000000067F00008000000A60140000021886-000000067F00008000000A60140000028C0A__000000CAD5D7FFF1-000000CB40C16489", +"000000067F00008000000A60140000024000-000000067F00008000000A60140000028000__000000CB82C2FF68", +"000000067F00008000000A60140000028000-000000067F00008000000A6014000002C000__000000CB82C2FF68", +"000000067F00008000000A60140000028C0A-030000000000000000000000000000000002__000000CAD5D7FFF1-000000CB40C16489", +"000000067F00008000000A60140000029BB2-030000000000000000000000000000000002__000000CB40C16489-000000CB82C37859", +"000000067F00008000000A6014000002C000-030000000000000000000000000000000002__000000CB82C2FF68", +"000000067F00008000000A800C0000000000-000000067F00008000000A800C0000004000__000000CD51009FE8", +"000000067F00008000000A800C0000004000-000000067F00008000000A800C0000008000__000000CD51009FE8", +"000000067F00008000000A800C0000008000-000000067F00008000000A800C000000C000__000000CD51009FE8", +"000000067F00008000000A800C0000009748-000000067F00008000000A800C0000012EAE__000000CB82C37859-000000CC11F5EDC9", +"000000067F00008000000A800C000000C000-000000067F00008000000A800C0000010000__000000CD51009FE8", +"000000067F00008000000A800C0000010000-000000067F00008000000A800C0000014000__000000CD51009FE8", +"000000067F00008000000A800C0000012EAE-000000067F00008000000A800C000001C60A__000000CB82C37859-000000CC11F5EDC9", +"000000067F00008000000A800C0000014000-000000067F00008000000A800C0000018000__000000CD51009FE8", +"000000067F00008000000A800C0000018000-000000067F00008000000A800C000001C000__000000CD51009FE8", +"000000067F00008000000A800C000001C000-000000067F00008000000A800C0000020000__000000CD51009FE8", +"000000067F00008000000A800C000001C60A-000000067F00008000000A800C0000025D38__000000CB82C37859-000000CC11F5EDC9", +"000000067F00008000000A800C0000020000-000000067F00008000000A800C0000024000__000000CD51009FE8", +"000000067F00008000000A800C0000024000-000000067F00008000000A800C0000028000__000000CD51009FE8", +"000000067F00008000000A800C0000025D38-000000067F00008000000A800C000002F49E__000000CB82C37859-000000CC11F5EDC9", +"000000067F00008000000A800C0000028000-000000067F00008000000A800C000002C000__000000CD51009FE8", +"000000067F00008000000A800C000002C000-000000067F00008000000A800C0000030000__000000CD51009FE8", +"000000067F00008000000A800C000002F49E-000000067F00008000000A800C0000038BB1__000000CB82C37859-000000CC11F5EDC9", +"000000067F00008000000A800C0000030000-000000067F00008000000A800C0000034000__000000CD51009FE8", +"000000067F00008000000A800C0000034000-000000067F00008000000A800C0000038000__000000CD51009FE8", +"000000067F00008000000A800C0000038000-000000067F00008000000A800C000003C000__000000CD51009FE8", +"000000067F00008000000A800C0000038BB1-000000067F00008000000A800C0000042317__000000CB82C37859-000000CC11F5EDC9", +"000000067F00008000000A800C000003C000-000000067F00008000000A800C0000040000__000000CD51009FE8", +"000000067F00008000000A800C0000040000-000000067F00008000000A800C0000044000__000000CD51009FE8", +"000000067F00008000000A800C0000042317-000000067F00008000000A800C000004BA7D__000000CB82C37859-000000CC11F5EDC9", +"000000067F00008000000A800C0000044000-000000067F00008000000A800C0000048000__000000CD51009FE8", +"000000067F00008000000A800C0000048000-000000067F00008000000A800C000004C000__000000CD51009FE8", +"000000067F00008000000A800C000004BA7D-000000067F00008000000A800C0000054CA0__000000CB82C37859-000000CC11F5EDC9", +"000000067F00008000000A800C000004C000-000000067F00008000000A800C0000050000__000000CD51009FE8", +"000000067F00008000000A800C0000050000-000000067F00008000000A800C0000054000__000000CD51009FE8", +"000000067F00008000000A800C0000054000-000000067F00008000000A800C0000058000__000000CD51009FE8", +"000000067F00008000000A800C0000054C9F-000000067F00008000000A800C000005E405__000000CC11F5EDC9-000000CCB1B9E181", +"000000067F00008000000A800C0000058000-000000067F00008000000A800C000005C000__000000CD51009FE8", +"000000067F00008000000A800C000005C000-000000067F00008000000A800C0000060000__000000CD51009FE8", +"000000067F00008000000A800C000005E405-000000067F00008000000A800C0000067B10__000000CC11F5EDC9-000000CCB1B9E181", +"000000067F00008000000A800C0000060000-000000067F00008000000A800C0000064000__000000CD51009FE8", +"000000067F00008000000A800C0000064000-000000067F00008000000A800C0000068000__000000CD51009FE8", +"000000067F00008000000A800C0000067B10-000000067F00008000000A800C0000071276__000000CC11F5EDC9-000000CCB1B9E181", +"000000067F00008000000A800C0000068000-000000067F00008000000A800C000006C000__000000CD51009FE8", +"000000067F00008000000A800C000006C000-000000067F00008000000A800C0000070000__000000CD51009FE8", +"000000067F00008000000A800C0000070000-000000067F00008000000A800C0000074000__000000CD51009FE8", +"000000067F00008000000A800C0000071276-000000067F00008000000A800C000007A9DC__000000CC11F5EDC9-000000CCB1B9E181", +"000000067F00008000000A800C0000074000-000000067F00008000000A800C0000078000__000000CD51009FE8", +"000000067F00008000000A800C0000078000-000000067F00008000000A800C000007C000__000000CD51009FE8", +"000000067F00008000000A800C000007A9DC-000000067F00008000000A800C000008410B__000000CC11F5EDC9-000000CCB1B9E181", +"000000067F00008000000A800C000007C000-000000067F00008000000A800C0000080000__000000CD51009FE8", +"000000067F00008000000A800C0000080000-000000067F00008000000A800C0000084000__000000CD51009FE8", +"000000067F00008000000A800C0000084000-000000067F00008000000A800C0000088000__000000CD51009FE8", +"000000067F00008000000A800C000008410B-000000067F00008000000A800C000008D871__000000CC11F5EDC9-000000CCB1B9E181", +"000000067F00008000000A800C0000088000-000000067F00008000000A800C000008C000__000000CD51009FE8", +"000000067F00008000000A800C000008C000-000000067F00008000000A800C0000090000__000000CD51009FE8", +"000000067F00008000000A800C000008D871-000000067F00008000000A800C0000096F94__000000CC11F5EDC9-000000CCB1B9E181", +"000000067F00008000000A800C0000090000-000000067F00008000000A800C0000094000__000000CD51009FE8", +"000000067F00008000000A800C0000094000-000000067F00008000000A800C0000098000__000000CD51009FE8", +"000000067F00008000000A800C0000096F94-000000067F00008000000A800C00000A06FA__000000CC11F5EDC9-000000CCB1B9E181", +"000000067F00008000000A800C0000098000-000000067F00008000000A800C000009C000__000000CD51009FE8", +"000000067F00008000000A800C000009C000-000000067F00008000000A800C00000A0000__000000CD51009FE8", +"000000067F00008000000A800C00000A0000-000000067F00008000000A800C00000A4000__000000CD51009FE8", +"000000067F00008000000A800C00000A06FA-000000067F00008000000A800C00000A9E0D__000000CC11F5EDC9-000000CCB1B9E181", +"000000067F00008000000A800C00000A4000-000000067F00008000000A800C00000A8000__000000CD51009FE8", +"000000067F00008000000A800C00000A8000-000000067F00008000000A800C00000AC000__000000CD51009FE8", +"000000067F00008000000A800C00000A9E0D-000000067F00008000000A800C00000B3553__000000CC11F5EDC9-000000CCB1B9E181", +"000000067F00008000000A800C00000AC000-000000067F00008000000A800C00000B0000__000000CD51009FE8", +"000000067F00008000000A800C00000B0000-000000067F00008000000A800C00000B4000__000000CD51009FE8", +"000000067F00008000000A800C00000B3553-000000067F00008000000A800C0100000000__000000CC11F5EDC9-000000CCB1B9E181", +"000000067F00008000000A800C00000B4000-000000067F00008000000A800C00000B8000__000000CD51009FE8", +"000000067F00008000000A800C00000B8000-000000067F00008000000A800C00000BC000__000000CD51009FE8", +"000000067F00008000000A800C00000BC000-000000067F00008000000A800C00000C0000__000000CD51009FE8", +"000000067F00008000000A800C00000BCB46-000000067F00008000000A800C00000C62AC__000000CCB1B9E181-000000CD51344F89", +"000000067F00008000000A800C00000C0000-000000067F00008000000A800C00000C4000__000000CD51009FE8", +"000000067F00008000000A800C00000C4000-000000067F00008000000A800C00000C8000__000000CD51009FE8", +"000000067F00008000000A800C00000C62AC-000000067F00008000000A800C00000CFA09__000000CCB1B9E181-000000CD51344F89", +"000000067F00008000000A800C00000C8000-000000067F00008000000A800C00000CC000__000000CD51009FE8", +"000000067F00008000000A800C00000CC000-000000067F00008000000A800C00000D0000__000000CD51009FE8", +"000000067F00008000000A800C00000CFA09-000000067F00008000000A800C00000D9118__000000CCB1B9E181-000000CD51344F89", +"000000067F00008000000A800C00000D0000-000000067F00008000000A800C00000D4000__000000CD51009FE8", +"000000067F00008000000A800C00000D4000-000000067F00008000000A800C00000D8000__000000CD51009FE8", +"000000067F00008000000A800C00000D8000-000000067F00008000000A800C00000DC000__000000CD51009FE8", +"000000067F00008000000A800C00000D9118-000000067F00008000000A800C00000E287E__000000CCB1B9E181-000000CD51344F89", +"000000067F00008000000A800C00000DC000-000000067F00008000000A800C00000E0000__000000CD51009FE8", +"000000067F00008000000A800C00000E0000-000000067F00008000000A800C00000E4000__000000CD51009FE8", +"000000067F00008000000A800C00000E287E-000000067F00008000000A800C00000EBFE4__000000CCB1B9E181-000000CD51344F89", +"000000067F00008000000A800C00000E4000-000000067F00008000000A800C00000E8000__000000CD51009FE8", +"000000067F00008000000A800C00000E8000-000000067F00008000000A800C00000EC000__000000CD51009FE8", +"000000067F00008000000A800C00000EBFE4-000000067F00008000000A800C00000F570B__000000CCB1B9E181-000000CD51344F89", +"000000067F00008000000A800C00000EC000-000000067F00008000000A800C00000F0000__000000CD51009FE8", +"000000067F00008000000A800C00000F0000-000000067F00008000000A800C00000F4000__000000CD51009FE8", +"000000067F00008000000A800C00000F4000-000000067F00008000000A800C00000F8000__000000CD51009FE8", +"000000067F00008000000A800C00000F570B-000000067F00008000000A800C00000FEE71__000000CCB1B9E181-000000CD51344F89", +"000000067F00008000000A800C00000F8000-000000067F00008000000A800C00000FC000__000000CD51009FE8", +"000000067F00008000000A800C00000FC000-000000067F00008000000A800C0000100000__000000CD51009FE8", +"000000067F00008000000A800C00000FEE71-000000067F00008000000A800C0000108587__000000CCB1B9E181-000000CD51344F89", +"000000067F00008000000A800C0000100000-000000067F00008000000A800C0000104000__000000CD51009FE8", +"000000067F00008000000A800C0000104000-000000067F00008000000A800C0000108000__000000CD51009FE8", +"000000067F00008000000A800C0000108000-000000067F00008000000A800C000010C000__000000CD51009FE8", +"000000067F00008000000A800C0000108587-000000067F00008000000A800C0000111C20__000000CCB1B9E181-000000CD51344F89", +"000000067F00008000000A800C000010C000-000000067F00008000000A800C0000110000__000000CD51009FE8", +"000000067F00008000000A800C0000110000-030000000000000000000000000000000002__000000CD51009FE8", +"000000067F00008000000A800C00FFFFFFFF-010000000000000001000000050000000011__000000CCB1B9E181-000000CD51344F89", +"000000067F00008000000A800C00FFFFFFFF-030000000000000000000000000000000002__000000CB82C37859-000000CC11F5EDC9", +"000000067F00008000000A800F0200000000-000000067F00008000000A80140000007ADF__000000CD51344F89-000000CDCC7BF889", +"000000067F00008000000A80140000007ADF-000000067F00008000000A8014000000F7D0__000000CD51344F89-000000CDCC7BF889", +"000000067F00008000000A8014000000F7D0-000000067F00008000000A801400000176D0__000000CD51344F89-000000CDCC7BF889", +"000000067F00008000000A801400000176D0-000000067F00008000000A8014000001F5D2__000000CD51344F89-000000CDCC7BF889", +"000000067F00008000000A8014000001F5D2-000000067F00008000000A801400000274D5__000000CD51344F89-000000CDCC7BF889", +"000000067F00008000000A801400000274D5-000000067F00008000000AA00C0000001863__000000CD51344F89-000000CDCC7BF889", +"000000067F00008000000AA00C0000000000-000000067F00008000000AA00C0000004000__000000CF7E08BFD0", +"000000067F00008000000AA00C0000001863-000000067F00008000000AA00C000000AFC9__000000CD51344F89-000000CDCC7BF889", +"000000067F00008000000AA00C0000004000-000000067F00008000000AA00C0000008000__000000CF7E08BFD0", +"000000067F00008000000AA00C0000008000-000000067F00008000000AA00C000000C000__000000CF7E08BFD0", +"000000067F00008000000AA00C000000AFC9-030000000000000000000000000000000002__000000CD51344F89-000000CDCC7BF889", +"000000067F00008000000AA00C000000C000-000000067F00008000000AA00C0000010000__000000CF7E08BFD0", +"000000067F00008000000AA00C0000010000-000000067F00008000000AA00C0000014000__000000CF7B8D3FD0", +"000000067F00008000000AA00C00000126EC-000000067F00008000000AA00C000001BE0C__000000CDCC7BF889-000000CE6C3FED31", +"000000067F00008000000AA00C0000014000-000000067F00008000000AA00C0000018000__000000CF7B8D3FD0", +"000000067F00008000000AA00C0000018000-000000067F00008000000AA00C000001C000__000000CF7B8D3FD0", +"000000067F00008000000AA00C000001BE0C-000000067F00008000000AA00C000002553F__000000CDCC7BF889-000000CE6C3FED31", +"000000067F00008000000AA00C000001C000-000000067F00008000000AA00C0000020000__000000CF7B8D3FD0", +"000000067F00008000000AA00C0000020000-000000067F00008000000AA00C0000024000__000000CF7B8D3FD0", +"000000067F00008000000AA00C0000024000-000000067F00008000000AA00C0000028000__000000CF7B8D3FD0", +"000000067F00008000000AA00C000002553F-000000067F00008000000AA00C000002ECA5__000000CDCC7BF889-000000CE6C3FED31", +"000000067F00008000000AA00C0000028000-000000067F00008000000AA00C000002C000__000000CF7B8D3FD0", +"000000067F00008000000AA00C000002C000-000000067F00008000000AA00C0000030000__000000CF7B8D3FD0", +"000000067F00008000000AA00C000002ECA5-000000067F00008000000AA00C00000383BC__000000CDCC7BF889-000000CE6C3FED31", +"000000067F00008000000AA00C0000030000-000000067F00008000000AA00C0000034000__000000CF7B8D3FD0", +"000000067F00008000000AA00C0000034000-000000067F00008000000AA00C0000038000__000000CF7B8D3FD0", +"000000067F00008000000AA00C0000038000-000000067F00008000000AA00C000003C000__000000CF7B8D3FD0", +"000000067F00008000000AA00C00000383BC-000000067F00008000000AA00C0000041B0A__000000CDCC7BF889-000000CE6C3FED31", +"000000067F00008000000AA00C000003C000-000000067F00008000000AA00C0000040000__000000CF7B8D3FD0", +"000000067F00008000000AA00C0000040000-000000067F00008000000AA00C0000044000__000000CF7B8D3FD0", +"000000067F00008000000AA00C0000041B0A-000000067F00008000000AA00C000004B270__000000CDCC7BF889-000000CE6C3FED31", +"000000067F00008000000AA00C0000044000-000000067F00008000000AA00C0000048000__000000CF7B8D3FD0", +"000000067F00008000000AA00C0000048000-000000067F00008000000AA00C000004C000__000000CF7B8D3FD0", +"000000067F00008000000AA00C000004B270-000000067F00008000000AA00C00000549AA__000000CDCC7BF889-000000CE6C3FED31", +"000000067F00008000000AA00C000004C000-000000067F00008000000AA00C0000050000__000000CF7B8D3FD0", +"000000067F00008000000AA00C0000050000-000000067F00008000000AA00C0000054000__000000CF7B8D3FD0", +"000000067F00008000000AA00C0000054000-000000067F00008000000AA00C0000058000__000000CF7B8D3FD0", +"000000067F00008000000AA00C00000549AA-000000067F00008000000AA00C000005E10B__000000CDCC7BF889-000000CE6C3FED31", +"000000067F00008000000AA00C0000058000-000000067F00008000000AA00C000005C000__000000CF7B8D3FD0", +"000000067F00008000000AA00C000005C000-000000067F00008000000AA00C0000060000__000000CF7B8D3FD0", +"000000067F00008000000AA00C000005E10B-000000067F00008000000AA00C000006782C__000000CDCC7BF889-000000CE6C3FED31", +"000000067F00008000000AA00C0000060000-000000067F00008000000AA00C0000064000__000000CF7B8D3FD0", +"000000067F00008000000AA00C0000064000-000000067F00008000000AA00C0000068000__000000CF7B8D3FD0", +"000000067F00008000000AA00C000006782C-000000067F00008000000AA00C0000070F88__000000CDCC7BF889-000000CE6C3FED31", +"000000067F00008000000AA00C0000068000-000000067F00008000000AA00C000006C000__000000CF7B8D3FD0", +"000000067F00008000000AA00C000006C000-000000067F00008000000AA00C0000070000__000000CF7B8D3FD0", +"000000067F00008000000AA00C0000070000-000000067F00008000000AA00C0000074000__000000CF7B8D3FD0", +"000000067F00008000000AA00C0000070F88-000000067F00008000000AA00C0100000000__000000CDCC7BF889-000000CE6C3FED31", +"000000067F00008000000AA00C0000074000-000000067F00008000000AA00C0000078000__000000CF7B8D3FD0", +"000000067F00008000000AA00C0000078000-000000067F00008000000AA00C000007C000__000000CF7B8D3FD0", +"000000067F00008000000AA00C0000078E97-000000067F00008000000AA00C00000823F9__000000CE6C3FED31-000000CF7DC97FD1", +"000000067F00008000000AA00C000007C000-000000067F00008000000AA00C0000080000__000000CF7B8D3FD0", +"000000067F00008000000AA00C0000080000-000000067F00008000000AA00C0000084000__000000CF7B8D3FD0", +"000000067F00008000000AA00C00000823F9-000000067F00008000000AA00C000008BA8A__000000CE6C3FED31-000000CF7DC97FD1", +"000000067F00008000000AA00C0000084000-000000067F00008000000AA00C0000088000__000000CF7B8D3FD0", +"000000067F00008000000AA00C0000088000-000000067F00008000000AA00C000008C000__000000CF7B8D3FD0", +"000000067F00008000000AA00C000008BA8A-000000067F00008000000AA00C00000951BF__000000CE6C3FED31-000000CF7DC97FD1", +"000000067F00008000000AA00C000008C000-000000067F00008000000AA00C0000090000__000000CF7B8D3FD0", +"000000067F00008000000AA00C0000090000-000000067F00008000000AA00C0000094000__000000CF7B8D3FD0", +"000000067F00008000000AA00C0000094000-000000067F00008000000AA00C0000098000__000000CF7B8D3FD0", +"000000067F00008000000AA00C00000951BF-000000067F00008000000AA00C000009E90A__000000CE6C3FED31-000000CF7DC97FD1", +"000000067F00008000000AA00C0000098000-000000067F00008000000AA00C000009C000__000000CF7B8D3FD0", +"000000067F00008000000AA00C000009C000-000000067F00008000000AA00C00000A0000__000000CF7B8D3FD0", +"000000067F00008000000AA00C000009E90A-000000067F00008000000AA00C00000A802B__000000CE6C3FED31-000000CF7DC97FD1", +"000000067F00008000000AA00C00000A0000-000000067F00008000000AA00C00000A4000__000000CF7B8D3FD0", +"000000067F00008000000AA00C00000A4000-000000067F00008000000AA00C00000A8000__000000CF7B8D3FD0", +"000000067F00008000000AA00C00000A8000-000000067F00008000000AA00C00000AC000__000000CF7B8D3FD0", +"000000067F00008000000AA00C00000A802B-000000067F00008000000AA00C00000B1782__000000CE6C3FED31-000000CF7DC97FD1", +"000000067F00008000000AA00C00000AC000-000000067F00008000000AA00C00000B0000__000000CF7B8D3FD0", +"000000067F00008000000AA00C00000B0000-000000067F00008000000AA00C00000B4000__000000CF7B8D3FD0", +"000000067F00008000000AA00C00000B1782-000000067F00008000000AA00C00000BAEE8__000000CE6C3FED31-000000CF7DC97FD1", +"000000067F00008000000AA00C00000B4000-000000067F00008000000AA00C00000B8000__000000CF7B8D3FD0", +"000000067F00008000000AA00C00000B8000-000000067F00008000000AA00C00000BC000__000000CF7B8D3FD0", +"000000067F00008000000AA00C00000BAEE8-000000067F00008000000AA00C00000C460C__000000CE6C3FED31-000000CF7DC97FD1", +"000000067F00008000000AA00C00000BC000-000000067F00008000000AA00C00000C0000__000000CF7B8D3FD0", +"000000067F00008000000AA00C00000C0000-000000067F00008000000AA00C00000C4000__000000CF7B8D3FD0", +"000000067F00008000000AA00C00000C4000-000000067F00008000000AA00C00000C8000__000000CF7B8D3FD0", +"000000067F00008000000AA00C00000C460C-000000067F00008000000AA00C00000CDD72__000000CE6C3FED31-000000CF7DC97FD1", +"000000067F00008000000AA00C00000C8000-000000067F00008000000AA00C00000CC000__000000CF7B8D3FD0", +"000000067F00008000000AA00C00000CC000-000000067F00008000000AA00C00000D0000__000000CF7B8D3FD0", +"000000067F00008000000AA00C00000CDD72-000000067F00008000000AA00C00000D74D8__000000CE6C3FED31-000000CF7DC97FD1", +"000000067F00008000000AA00C00000D0000-000000067F00008000000AA00C00000D4000__000000CF7B8D3FD0", +"000000067F00008000000AA00C00000D4000-000000067F00008000000AA00C00000D8000__000000CF7B8D3FD0", +"000000067F00008000000AA00C00000D74D8-000000067F00008000000AA00C00000E0C0B__000000CE6C3FED31-000000CF7DC97FD1", +"000000067F00008000000AA00C00000D8000-000000067F00008000000AA00C00000DC000__000000CF7B8D3FD0", +"000000067F00008000000AA00C00000DC000-000000067F00008000000AA00C00000E0000__000000CF7B8D3FD0", +"000000067F00008000000AA00C00000E0000-000000067F00008000000AA00C00000E4000__000000CF7B8D3FD0", +"000000067F00008000000AA00C00000E0C0B-000000067F00008000000AA00C00000EA371__000000CE6C3FED31-000000CF7DC97FD1", +"000000067F00008000000AA00C00000E4000-000000067F00008000000AA00C00000E8000__000000CF7B8D3FD0", +"000000067F00008000000AA00C00000E8000-000000067F00008000000AA00C00000EC000__000000CF7B8D3FD0", +"000000067F00008000000AA00C00000EA371-000000067F00008000000AA00C00000F3AD7__000000CE6C3FED31-000000CF7DC97FD1", +"000000067F00008000000AA00C00000EC000-000000067F00008000000AA00C00000F0000__000000CF7B8D3FD0", +"000000067F00008000000AA00C00000F0000-000000067F00008000000AA00C00000F4000__000000CF7B8D3FD0", +"000000067F00008000000AA00C00000F3AD7-000000067F00008000000AA00C00000FD20B__000000CE6C3FED31-000000CF7DC97FD1", +"000000067F00008000000AA00C00000F4000-000000067F00008000000AA00C00000F8000__000000CF7B8D3FD0", +"000000067F00008000000AA00C00000F8000-000000067F00008000000AA00C00000FC000__000000CF7B8D3FD0", +"000000067F00008000000AA00C00000FC000-000000067F00008000000AA00C0000100000__000000CF7B8D3FD0", +"000000067F00008000000AA00C00000FD20B-000000067F00008000000AA00C0000106932__000000CE6C3FED31-000000CF7DC97FD1", +"000000067F00008000000AA00C0000100000-000000067F00008000000AA00C0000104000__000000CF7B8D3FD0", +"000000067F00008000000AA00C0000104000-000000067F00008000000AA00C0000108000__000000CF7B8D3FD0", +"000000067F00008000000AA00C0000106932-000000067F00008000000AA00C0000110098__000000CE6C3FED31-000000CF7DC97FD1", +"000000067F00008000000AA00C0000108000-000000067F00008000000AA00C000010C000__000000CF7B8D3FD0", +"000000067F00008000000AA00C000010C000-000000067F00008000000AA00C0000110000__000000CF7B8D3FD0", +"000000067F00008000000AA00C0000110000-030000000000000000000000000000000002__000000CF7B8D3FD0", +"000000067F00008000000AA00C0000110098-010000000000000001000000050000000012__000000CE6C3FED31-000000CF7DC97FD1", +"010000000000000001000000000000000000-030000000000000000000000000000000002__000000A29F1D8950", +"030000000000000000000000000000000001-030000000000000000000000000000000002__000000C689AF4AC1-000000C6C87B6329", +]; diff --git a/pageserver/src/bin/dump_layerfile.rs b/pageserver/src/bin/dump_layerfile.rs deleted file mode 100644 index f5247ee609..0000000000 --- a/pageserver/src/bin/dump_layerfile.rs +++ /dev/null @@ -1,35 +0,0 @@ -//! Main entry point for the dump_layerfile executable -//! -//! A handy tool for debugging, that's all. -use anyhow::Result; -use clap::{App, Arg}; -use pageserver::page_cache; -use pageserver::tenant::dump_layerfile_from_path; -use pageserver::virtual_file; -use std::path::PathBuf; -use utils::project_git_version; - -project_git_version!(GIT_VERSION); - -fn main() -> Result<()> { - let arg_matches = App::new("Neon dump_layerfile utility") - .about("Dump contents of one layer file, for debugging") - .version(GIT_VERSION) - .arg( - Arg::new("path") - .help("Path to file to dump") - .required(true) - .index(1), - ) - .get_matches(); - - let path = PathBuf::from(arg_matches.value_of("path").unwrap()); - - // Basic initialization of things that don't change after startup - virtual_file::init(10); - page_cache::init(100); - - dump_layerfile_from_path(&path, true)?; - - Ok(()) -} diff --git a/pageserver/src/bin/pageserver.rs b/pageserver/src/bin/pageserver.rs index fb79ad3945..9317dd5dd7 100644 --- a/pageserver/src/bin/pageserver.rs +++ b/pageserver/src/bin/pageserver.rs @@ -6,10 +6,12 @@ use tracing::*; use anyhow::{anyhow, bail, Context, Result}; -use clap::{App, Arg}; +use clap::{Arg, ArgAction, Command}; use daemonize::Daemonize; use fail::FailScenario; +use metrics::set_build_info_metric; + use pageserver::{ config::{defaults::*, PageServerConf}, http, page_cache, page_service, profiling, task_mgr, @@ -31,72 +33,35 @@ use utils::{ project_git_version!(GIT_VERSION); +const FEATURES: &[&str] = &[ + #[cfg(feature = "testing")] + "testing", + #[cfg(feature = "fail/failpoints")] + "fail/failpoints", + #[cfg(feature = "profiling")] + "profiling", +]; + fn version() -> String { format!( - "{GIT_VERSION} profiling:{} failpoints:{}", - cfg!(feature = "profiling"), - fail::has_failpoints() + "{GIT_VERSION} failpoints: {}, features: {:?}", + fail::has_failpoints(), + FEATURES, ) } fn main() -> anyhow::Result<()> { - let arg_matches = App::new("Neon page server") - .about("Materializes WAL stream to pages and serves them to the postgres") - .version(&*version()) - .arg( + let arg_matches = cli().get_matches(); - Arg::new("daemonize") - .short('d') - .long("daemonize") - .takes_value(false) - .help("Run in the background"), - ) - .arg( - Arg::new("init") - .long("init") - .takes_value(false) - .help("Initialize pageserver with all given config overrides"), - ) - .arg( - Arg::new("workdir") - .short('D') - .long("workdir") - .takes_value(true) - .help("Working directory for the pageserver"), - ) - // See `settings.md` for more details on the extra configuration patameters pageserver can process - .arg( - Arg::new("config-override") - .short('c') - .takes_value(true) - .number_of_values(1) - .multiple_occurrences(true) - .help("Additional configuration overrides of the ones from the toml config file (or new ones to add there). - Any option has to be a valid toml document, example: `-c=\"foo='hey'\"` `-c=\"foo={value=1}\"`"), - ) - .arg(Arg::new("update-config").long("update-config").takes_value(false).help( - "Update the config file when started", - )) - .arg( - Arg::new("enabled-features") - .long("enabled-features") - .takes_value(false) - .help("Show enabled compile time features"), - ) - .get_matches(); - - if arg_matches.is_present("enabled-features") { - let features: &[&str] = &[ - #[cfg(feature = "testing")] - "testing", - #[cfg(feature = "profiling")] - "profiling", - ]; - println!("{{\"features\": {features:?} }}"); + if arg_matches.get_flag("enabled-features") { + println!("{{\"features\": {FEATURES:?} }}"); return Ok(()); } - let workdir = Path::new(arg_matches.value_of("workdir").unwrap_or(".neon")); + let workdir = arg_matches + .get_one::("workdir") + .map(Path::new) + .unwrap_or_else(|| Path::new(".neon")); let workdir = workdir .canonicalize() .with_context(|| format!("Error opening workdir '{}'", workdir.display()))?; @@ -110,7 +75,7 @@ fn main() -> anyhow::Result<()> { ) })?; - let daemonize = arg_matches.is_present("daemonize"); + let daemonize = arg_matches.get_flag("daemonize"); let conf = match initialize_config(&cfg_file_path, arg_matches, &workdir)? { ControlFlow::Continue(conf) => conf, @@ -122,7 +87,7 @@ fn main() -> anyhow::Result<()> { let tenants_path = conf.tenants_path(); if !tenants_path.exists() { - utils::crashsafe_dir::create_dir_all(conf.tenants_path()).with_context(|| { + utils::crashsafe::create_dir_all(conf.tenants_path()).with_context(|| { format!( "Failed to create tenants root dir at '{}'", tenants_path.display() @@ -148,8 +113,8 @@ fn initialize_config( arg_matches: clap::ArgMatches, workdir: &Path, ) -> anyhow::Result> { - let init = arg_matches.is_present("init"); - let update_config = init || arg_matches.is_present("update-config"); + let init = arg_matches.get_flag("init"); + let update_config = init || arg_matches.get_flag("update-config"); let (mut toml, config_file_exists) = if cfg_file_path.is_file() { if init { @@ -191,13 +156,10 @@ fn initialize_config( ) }; - if let Some(values) = arg_matches.values_of("config-override") { + if let Some(values) = arg_matches.get_many::("config-override") { for option_line in values { let doc = toml_edit::Document::from_str(option_line).with_context(|| { - format!( - "Option '{}' could not be parsed as a toml document", - option_line - ) + format!("Option '{option_line}' could not be parsed as a toml document") })?; for (key, item) in doc.iter() { @@ -239,7 +201,7 @@ fn start_pageserver(conf: &'static PageServerConf, daemonize: bool) -> Result<() // Initialize logger let log_file = logging::init(LOG_FILE_NAME, daemonize)?; - info!("version: {GIT_VERSION}"); + info!("version: {}", version()); // TODO: Check that it looks like a valid repository before going further @@ -356,6 +318,8 @@ fn start_pageserver(conf: &'static PageServerConf, daemonize: bool) -> Result<() }, ); + set_build_info_metric(GIT_VERSION); + // All started up! Now just sit and wait for shutdown signal. signals.handle(|signal| match signal { Signal::Quit => { @@ -378,3 +342,55 @@ fn start_pageserver(conf: &'static PageServerConf, daemonize: bool) -> Result<() } }) } + +fn cli() -> Command { + Command::new("Neon page server") + .about("Materializes WAL stream to pages and serves them to the postgres") + .version(version()) + .arg( + + Arg::new("daemonize") + .short('d') + .long("daemonize") + .action(ArgAction::SetTrue) + .help("Run in the background"), + ) + .arg( + Arg::new("init") + .long("init") + .action(ArgAction::SetTrue) + .help("Initialize pageserver with all given config overrides"), + ) + .arg( + Arg::new("workdir") + .short('D') + .long("workdir") + .help("Working directory for the pageserver"), + ) + // See `settings.md` for more details on the extra configuration patameters pageserver can process + .arg( + Arg::new("config-override") + .short('c') + .num_args(1) + .action(ArgAction::Append) + .help("Additional configuration overrides of the ones from the toml config file (or new ones to add there). \ + Any option has to be a valid toml document, example: `-c=\"foo='hey'\"` `-c=\"foo={value=1}\"`"), + ) + .arg( + Arg::new("update-config") + .long("update-config") + .action(ArgAction::SetTrue) + .help("Update the config file when started"), + ) + .arg( + Arg::new("enabled-features") + .long("enabled-features") + .action(ArgAction::SetTrue) + .help("Show enabled compile time features"), + ) +} + +#[test] +fn verify_cli() { + cli().debug_assert(); +} diff --git a/pageserver/src/bin/pageserver_binutils.rs b/pageserver/src/bin/pageserver_binutils.rs new file mode 100644 index 0000000000..b1484ac45a --- /dev/null +++ b/pageserver/src/bin/pageserver_binutils.rs @@ -0,0 +1,154 @@ +//! A helper tool to manage pageserver binary files. +//! Accepts a file as an argument, attempts to parse it with all ways possible +//! and prints its interpreted context. +//! +//! Separate, `metadata` subcommand allows to print and update pageserver's metadata file. +use std::{ + path::{Path, PathBuf}, + str::FromStr, +}; + +use anyhow::Context; +use clap::{value_parser, Arg, Command}; + +use pageserver::{ + page_cache, + tenant::{dump_layerfile_from_path, metadata::TimelineMetadata}, + virtual_file, +}; +use postgres_ffi::ControlFileData; +use utils::{lsn::Lsn, project_git_version}; + +project_git_version!(GIT_VERSION); + +const METADATA_SUBCOMMAND: &str = "metadata"; + +fn main() -> anyhow::Result<()> { + let arg_matches = cli().get_matches(); + + match arg_matches.subcommand() { + Some((subcommand_name, subcommand_matches)) => { + let path = subcommand_matches + .get_one::("metadata_path") + .context("'metadata_path' argument is missing")? + .to_path_buf(); + anyhow::ensure!( + subcommand_name == METADATA_SUBCOMMAND, + "Unknown subcommand {subcommand_name}" + ); + handle_metadata(&path, subcommand_matches)?; + } + None => { + let path = arg_matches + .get_one::("path") + .context("'path' argument is missing")? + .to_path_buf(); + println!( + "No subcommand specified, attempting to guess the format for file {}", + path.display() + ); + if let Err(e) = read_pg_control_file(&path) { + println!( + "Failed to read input file as a pg control one: {e:#}\n\ + Attempting to read it as layer file" + ); + print_layerfile(&path)?; + } + } + }; + Ok(()) +} + +fn read_pg_control_file(control_file_path: &Path) -> anyhow::Result<()> { + let control_file = ControlFileData::decode(&std::fs::read(&control_file_path)?)?; + println!("{control_file:?}"); + let control_file_initdb = Lsn(control_file.checkPoint); + println!( + "pg_initdb_lsn: {}, aligned: {}", + control_file_initdb, + control_file_initdb.align() + ); + Ok(()) +} + +fn print_layerfile(path: &Path) -> anyhow::Result<()> { + // Basic initialization of things that don't change after startup + virtual_file::init(10); + page_cache::init(100); + dump_layerfile_from_path(path, true) +} + +fn handle_metadata(path: &Path, arg_matches: &clap::ArgMatches) -> Result<(), anyhow::Error> { + let metadata_bytes = std::fs::read(&path)?; + let mut meta = TimelineMetadata::from_bytes(&metadata_bytes)?; + println!("Current metadata:\n{meta:?}"); + let mut update_meta = false; + if let Some(disk_consistent_lsn) = arg_matches.get_one::("disk_consistent_lsn") { + meta = TimelineMetadata::new( + Lsn::from_str(disk_consistent_lsn)?, + meta.prev_record_lsn(), + meta.ancestor_timeline(), + meta.ancestor_lsn(), + meta.latest_gc_cutoff_lsn(), + meta.initdb_lsn(), + meta.pg_version(), + ); + update_meta = true; + } + if let Some(prev_record_lsn) = arg_matches.get_one::("prev_record_lsn") { + meta = TimelineMetadata::new( + meta.disk_consistent_lsn(), + Some(Lsn::from_str(prev_record_lsn)?), + meta.ancestor_timeline(), + meta.ancestor_lsn(), + meta.latest_gc_cutoff_lsn(), + meta.initdb_lsn(), + meta.pg_version(), + ); + update_meta = true; + } + + if update_meta { + let metadata_bytes = meta.to_bytes()?; + std::fs::write(&path, &metadata_bytes)?; + } + + Ok(()) +} + +fn cli() -> Command { + Command::new("Neon Pageserver binutils") + .about("Reads pageserver (and related) binary files management utility") + .version(GIT_VERSION) + .arg( + Arg::new("path") + .help("Input file path") + .value_parser(value_parser!(PathBuf)) + .required(false), + ) + .subcommand( + Command::new(METADATA_SUBCOMMAND) + .about("Read and update pageserver metadata file") + .arg( + Arg::new("metadata_path") + .help("Input metadata file path") + .value_parser(value_parser!(PathBuf)) + .required(false), + ) + .arg( + Arg::new("disk_consistent_lsn") + .long("disk_consistent_lsn") + .help("Replace disk consistent Lsn"), + ) + .arg( + Arg::new("prev_record_lsn") + .long("prev_record_lsn") + .help("Replace previous record Lsn"), + ), + ) +} + +#[test] +fn verify_cli() { + cli().debug_assert(); +} diff --git a/pageserver/src/bin/update_metadata.rs b/pageserver/src/bin/update_metadata.rs deleted file mode 100644 index e66049c457..0000000000 --- a/pageserver/src/bin/update_metadata.rs +++ /dev/null @@ -1,75 +0,0 @@ -//! Main entry point for the edit_metadata executable -//! -//! A handy tool for debugging, that's all. -use anyhow::Result; -use clap::{App, Arg}; -use pageserver::tenant::metadata::TimelineMetadata; -use std::path::PathBuf; -use std::str::FromStr; -use utils::{lsn::Lsn, project_git_version}; - -project_git_version!(GIT_VERSION); - -fn main() -> Result<()> { - let arg_matches = App::new("Neon update metadata utility") - .about("Dump or update metadata file") - .version(GIT_VERSION) - .arg( - Arg::new("path") - .help("Path to metadata file") - .required(true), - ) - .arg( - Arg::new("disk_lsn") - .short('d') - .long("disk_lsn") - .takes_value(true) - .help("Replace disk constistent lsn"), - ) - .arg( - Arg::new("prev_lsn") - .short('p') - .long("prev_lsn") - .takes_value(true) - .help("Previous record LSN"), - ) - .get_matches(); - - let path = PathBuf::from(arg_matches.value_of("path").unwrap()); - let metadata_bytes = std::fs::read(&path)?; - let mut meta = TimelineMetadata::from_bytes(&metadata_bytes)?; - println!("Current metadata:\n{:?}", &meta); - - let mut update_meta = false; - - if let Some(disk_lsn) = arg_matches.value_of("disk_lsn") { - meta = TimelineMetadata::new( - Lsn::from_str(disk_lsn)?, - meta.prev_record_lsn(), - meta.ancestor_timeline(), - meta.ancestor_lsn(), - meta.latest_gc_cutoff_lsn(), - meta.initdb_lsn(), - meta.pg_version(), - ); - update_meta = true; - } - - if let Some(prev_lsn) = arg_matches.value_of("prev_lsn") { - meta = TimelineMetadata::new( - meta.disk_consistent_lsn(), - Some(Lsn::from_str(prev_lsn)?), - meta.ancestor_timeline(), - meta.ancestor_lsn(), - meta.latest_gc_cutoff_lsn(), - meta.initdb_lsn(), - meta.pg_version(), - ); - update_meta = true; - } - if update_meta { - let metadata_bytes = meta.to_bytes()?; - std::fs::write(&path, &metadata_bytes)?; - } - Ok(()) -} diff --git a/pageserver/src/config.rs b/pageserver/src/config.rs index 6e3c7baad8..4f80fc96b5 100644 --- a/pageserver/src/config.rs +++ b/pageserver/src/config.rs @@ -7,6 +7,7 @@ use anyhow::{anyhow, bail, ensure, Context, Result}; use remote_storage::RemoteStorageConfig; use std::env; +use utils::crashsafe::path_with_suffix_extension; use std::path::{Path, PathBuf}; use std::str::FromStr; @@ -24,6 +25,7 @@ use crate::tenant_config::{TenantConf, TenantConfOpt}; /// The name of the metadata file pageserver creates per timeline. pub const METADATA_FILE_NAME: &str = "metadata"; +pub const TIMELINE_UNINIT_MARK_SUFFIX: &str = "___uninit"; const TENANT_CONFIG_NAME: &str = "config"; pub mod defaults { @@ -364,6 +366,17 @@ impl PageServerConf { self.timelines_path(tenant_id).join(timeline_id.to_string()) } + pub fn timeline_uninit_mark_file_path( + &self, + tenant_id: TenantId, + timeline_id: TimelineId, + ) -> PathBuf { + path_with_suffix_extension( + self.timeline_path(&timeline_id, &tenant_id), + TIMELINE_UNINIT_MARK_SUFFIX, + ) + } + /// Points to a place in pageserver's local directory, /// where certain timeline's metadata file should be located. pub fn metadata_path(&self, timeline_id: TimelineId, tenant_id: TenantId) -> PathBuf { @@ -374,28 +387,28 @@ impl PageServerConf { // // Postgres distribution paths // - pub fn pg_distrib_dir(&self, pg_version: u32) -> PathBuf { + pub fn pg_distrib_dir(&self, pg_version: u32) -> anyhow::Result { let path = self.pg_distrib_dir.clone(); match pg_version { - 14 => path.join(format!("v{pg_version}")), - 15 => path.join(format!("v{pg_version}")), - _ => panic!("Unsupported postgres version: {}", pg_version), + 14 => Ok(path.join(format!("v{pg_version}"))), + 15 => Ok(path.join(format!("v{pg_version}"))), + _ => bail!("Unsupported postgres version: {}", pg_version), } } - pub fn pg_bin_dir(&self, pg_version: u32) -> PathBuf { + pub fn pg_bin_dir(&self, pg_version: u32) -> anyhow::Result { match pg_version { - 14 => self.pg_distrib_dir(pg_version).join("bin"), - 15 => self.pg_distrib_dir(pg_version).join("bin"), - _ => panic!("Unsupported postgres version: {}", pg_version), + 14 => Ok(self.pg_distrib_dir(pg_version)?.join("bin")), + 15 => Ok(self.pg_distrib_dir(pg_version)?.join("bin")), + _ => bail!("Unsupported postgres version: {}", pg_version), } } - pub fn pg_lib_dir(&self, pg_version: u32) -> PathBuf { + pub fn pg_lib_dir(&self, pg_version: u32) -> anyhow::Result { match pg_version { - 14 => self.pg_distrib_dir(pg_version).join("lib"), - 15 => self.pg_distrib_dir(pg_version).join("lib"), - _ => panic!("Unsupported postgres version: {}", pg_version), + 14 => Ok(self.pg_distrib_dir(pg_version)?.join("lib")), + 15 => Ok(self.pg_distrib_dir(pg_version)?.join("lib")), + _ => bail!("Unsupported postgres version: {}", pg_version), } } diff --git a/pageserver/src/http/openapi_spec.yml b/pageserver/src/http/openapi_spec.yml index 97fdcd7bbd..626cc07429 100644 --- a/pageserver/src/http/openapi_spec.yml +++ b/pageserver/src/http/openapi_spec.yml @@ -1,7 +1,11 @@ openapi: "3.0.2" info: title: Page Server API + description: Neon Pageserver API version: "1.0" + license: + name: "Apache" + url: https://github.com/neondatabase/neon/blob/main/LICENSE servers: - url: "" paths: @@ -207,7 +211,6 @@ paths: schema: $ref: "#/components/schemas/Error" - /v1/tenant/{tenant_id}/timeline/{timeline_id}/get_lsn_by_timestamp: parameters: - name: tenant_id @@ -612,6 +615,9 @@ components: required: - timeline_id - tenant_id + - last_record_lsn + - disk_consistent_lsn + - awaits_download properties: timeline_id: type: string @@ -619,33 +625,15 @@ components: tenant_id: type: string format: hex - local: - $ref: "#/components/schemas/LocalTimelineInfo" - remote: - $ref: "#/components/schemas/RemoteTimelineInfo" - RemoteTimelineInfo: - type: object - required: - - awaits_download - - remote_consistent_lsn - properties: - awaits_download: - type: boolean - remote_consistent_lsn: - type: string - format: hex - LocalTimelineInfo: - type: object - required: - - last_record_lsn - - disk_consistent_lsn - properties: last_record_lsn: type: string format: hex disk_consistent_lsn: type: string format: hex + remote_consistent_lsn: + type: string + format: hex ancestor_timeline_id: type: string format: hex @@ -670,7 +658,39 @@ components: format: hex last_received_msg_ts: type: integer + awaits_download: + type: boolean + # These 'local' and 'remote' fields just duplicate some of the fields + # above. They are kept for backwards-compatibility. They can be removed, + # when the control plane has been updated to look at the above fields + # directly. + local: + $ref: "#/components/schemas/LocalTimelineInfo" + remote: + $ref: "#/components/schemas/RemoteTimelineInfo" + + LocalTimelineInfo: + type: object + properties: + ancestor_timeline_id: + type: string + format: hex + ancestor_lsn: + type: string + format: hex + current_logical_size: + type: integer + current_physical_size: + type: integer + RemoteTimelineInfo: + type: object + required: + - remote_consistent_lsn + properties: + remote_consistent_lsn: + type: string + format: hex Error: type: object required: diff --git a/pageserver/src/http/routes.rs b/pageserver/src/http/routes.rs index e743f27aff..489adbb2cf 100644 --- a/pageserver/src/http/routes.rs +++ b/pageserver/src/http/routes.rs @@ -79,13 +79,13 @@ fn get_config(request: &Request) -> &'static PageServerConf { get_state(request).conf } -// Helper functions to construct a LocalTimelineInfo struct for a timeline - -fn local_timeline_info_from_timeline( +// Helper function to construct a TimelineInfo struct for a timeline +async fn build_timeline_info( + state: &State, timeline: &Arc, include_non_incremental_logical_size: bool, include_non_incremental_physical_size: bool, -) -> anyhow::Result { +) -> anyhow::Result { let last_record_lsn = timeline.get_last_record_lsn(); let (wal_source_connstr, last_received_msg_lsn, last_received_msg_ts) = { let guard = timeline.last_received_wal.lock().unwrap(); @@ -100,24 +100,47 @@ fn local_timeline_info_from_timeline( } }; - let info = LocalTimelineInfo { - ancestor_timeline_id: timeline.get_ancestor_timeline_id(), - ancestor_lsn: { - match timeline.get_ancestor_lsn() { - Lsn(0) => None, - lsn @ Lsn(_) => Some(lsn), - } - }, + let (remote_consistent_lsn, awaits_download) = if let Some(remote_entry) = state + .remote_index + .read() + .await + .timeline_entry(&TenantTimelineId { + tenant_id: timeline.tenant_id, + timeline_id: timeline.timeline_id, + }) { + ( + Some(remote_entry.metadata.disk_consistent_lsn()), + remote_entry.awaits_download, + ) + } else { + (None, false) + }; + + let ancestor_timeline_id = timeline.get_ancestor_timeline_id(); + let ancestor_lsn = match timeline.get_ancestor_lsn() { + Lsn(0) => None, + lsn @ Lsn(_) => Some(lsn), + }; + let current_logical_size = match timeline.get_current_logical_size() { + Ok(size) => Some(size), + Err(err) => { + error!("Timeline info creation failed to get current logical size: {err:?}"); + None + } + }; + let current_physical_size = Some(timeline.get_physical_size()); + + let info = TimelineInfo { + tenant_id: timeline.tenant_id, + timeline_id: timeline.timeline_id, + ancestor_timeline_id, + ancestor_lsn, disk_consistent_lsn: timeline.get_disk_consistent_lsn(), last_record_lsn, prev_record_lsn: Some(timeline.get_prev_record_lsn()), latest_gc_cutoff_lsn: *timeline.get_latest_gc_cutoff_lsn(), - current_logical_size: Some( - timeline - .get_current_logical_size() - .context("Timeline info creation failed to get current logical size")?, - ), - current_physical_size: Some(timeline.get_physical_size()), + current_logical_size, + current_physical_size, current_logical_size_non_incremental: if include_non_incremental_logical_size { Some(timeline.get_current_logical_size_non_incremental(last_record_lsn)?) } else { @@ -132,32 +155,25 @@ fn local_timeline_info_from_timeline( last_received_msg_lsn, last_received_msg_ts, pg_version: timeline.pg_version, + + remote_consistent_lsn, + awaits_download, + + // Duplicate some fields in 'local' and 'remote' fields, for backwards-compatility + // with the control plane. + local: LocalTimelineInfo { + ancestor_timeline_id, + ancestor_lsn, + current_logical_size, + current_physical_size, + }, + remote: RemoteTimelineInfo { + remote_consistent_lsn, + }, }; Ok(info) } -fn list_local_timelines( - tenant_id: TenantId, - include_non_incremental_logical_size: bool, - include_non_incremental_physical_size: bool, -) -> Result> { - let tenant = tenant_mgr::get_tenant(tenant_id, true)?; - let timelines = tenant.list_timelines(); - - let mut local_timeline_info = Vec::with_capacity(timelines.len()); - for (timeline_id, repository_timeline) in timelines { - local_timeline_info.push(( - timeline_id, - local_timeline_info_from_timeline( - &repository_timeline, - include_non_incremental_logical_size, - include_non_incremental_physical_size, - )?, - )) - } - Ok(local_timeline_info) -} - // healthcheck handler async fn status_handler(request: Request) -> Result, ApiError> { let config = get_config(&request); @@ -169,6 +185,8 @@ async fn timeline_create_handler(mut request: Request) -> Result) -> Result { // Created. Construct a TimelineInfo for it. - let local_info = local_timeline_info_from_timeline(&new_timeline, false, false) + let timeline_info = build_timeline_info(state, &new_timeline, false, false) + .await .map_err(ApiError::InternalServerError)?; - Ok(Some(TimelineInfo { - tenant_id, - timeline_id: new_timeline.timeline_id, - local: Some(local_info), - remote: None, - })) + Ok(Some(timeline_info)) } Ok(None) => Ok(None), // timeline already exists Err(err) => Err(ApiError::InternalServerError(err)), @@ -209,6 +223,8 @@ async fn timeline_list_handler(request: Request) -> Result, query_param_present(&request, "include-non-incremental-physical-size"); check_permission(&request, Some(tenant_id))?; + let state = get_state(&request); + let timelines = tokio::task::spawn_blocking(move || { let _enter = info_span!("timeline_list", tenant = %tenant_id).entered(); let tenant = tenant_mgr::get_tenant(tenant_id, true).map_err(ApiError::NotFound)?; @@ -218,36 +234,18 @@ async fn timeline_list_handler(request: Request) -> Result, .map_err(|e: JoinError| ApiError::InternalServerError(e.into()))??; let mut response_data = Vec::with_capacity(timelines.len()); - for (timeline_id, timeline) in timelines { - let local = match local_timeline_info_from_timeline( + for timeline in timelines { + let timeline_info = build_timeline_info( + state, &timeline, include_non_incremental_logical_size, include_non_incremental_physical_size, - ) { - Ok(local) => Some(local), - Err(e) => { - error!("Failed to convert tenant timeline {timeline_id} into the local one: {e:?}"); - None - } - }; + ) + .await + .context("Failed to convert tenant timeline {timeline_id} into the local one: {e:?}") + .map_err(ApiError::InternalServerError)?; - response_data.push(TimelineInfo { - tenant_id, - timeline_id, - local, - remote: get_state(&request) - .remote_index - .read() - .await - .timeline_entry(&TenantTimelineId { - tenant_id, - timeline_id, - }) - .map(|remote_entry| RemoteTimelineInfo { - remote_consistent_lsn: remote_entry.metadata.disk_consistent_lsn(), - awaits_download: remote_entry.awaits_download, - }), - }) + response_data.push(timeline_info); } json_response(StatusCode::OK, response_data) @@ -292,59 +290,33 @@ async fn timeline_detail_handler(request: Request) -> Result Some(local_info), - Err(e) => { - error!("Failed to get local timeline info: {e:#}"); - None - } - }; + let timeline = timeline.map_err(ApiError::NotFound)?; - let remote_timeline_info = { - let remote_index_read = get_state(&request).remote_index.read().await; - remote_index_read - .timeline_entry(&TenantTimelineId { - tenant_id, - timeline_id, - }) - .map(|remote_entry| RemoteTimelineInfo { - remote_consistent_lsn: remote_entry.metadata.disk_consistent_lsn(), - awaits_download: remote_entry.awaits_download, - }) - }; - Ok::<_, ApiError>((local_timeline_info, remote_timeline_info)) + let timeline_info = build_timeline_info( + state, + &timeline, + include_non_incremental_logical_size, + include_non_incremental_physical_size, + ) + .await + .context("Failed to get local timeline info: {e:#}") + .map_err(ApiError::InternalServerError)?; + + Ok::<_, ApiError>(timeline_info) } .instrument(info_span!("timeline_detail", tenant = %tenant_id, timeline = %timeline_id)) .await?; - if local_timeline_info.is_none() && remote_timeline_info.is_none() { - Err(ApiError::NotFound(anyhow!( - "Timeline {tenant_id}/{timeline_id} is not found neither locally nor remotely" - ))) - } else { - json_response( - StatusCode::OK, - TimelineInfo { - tenant_id, - timeline_id, - local: local_timeline_info, - remote: remote_timeline_info, - }, - ) - } + json_response(StatusCode::OK, timeline_info) } async fn get_lsn_by_timestamp_handler(request: Request) -> Result, ApiError> { @@ -414,7 +386,7 @@ async fn tenant_attach_handler(request: Request) -> Result, } return json_response(StatusCode::ACCEPTED, ()); } - // no tenant in the index, release the lock to make the potentially lengthy download opetation + // no tenant in the index, release the lock to make the potentially lengthy download operation drop(index_accessor); // download index parts for every tenant timeline @@ -566,36 +538,27 @@ async fn tenant_status(request: Request) -> Result, ApiErro false }); - let tenant_state = match tenant { - Ok(tenant) => tenant.current_state(), + let (tenant_state, current_physical_size) = match tenant { + Ok(tenant) => { + let timelines = tenant.list_timelines(); + // Calculate total physical size of all timelines + let mut current_physical_size = 0; + for timeline in timelines { + current_physical_size += timeline.get_physical_size(); + } + + (tenant.current_state(), Some(current_physical_size)) + } Err(e) => { error!("Failed to get local tenant state: {e:#}"); if has_in_progress_downloads { - TenantState::Paused + (TenantState::Paused, None) } else { - TenantState::Broken + (TenantState::Broken, None) } } }; - let current_physical_size = - match tokio::task::spawn_blocking(move || list_local_timelines(tenant_id, false, false)) - .await - .map_err(|e: JoinError| ApiError::InternalServerError(e.into()))? - { - Err(err) => { - // Getting local timelines can fail when no local tenant directory is on disk (e.g, when tenant data is being downloaded). - // In that case, put a warning message into log and operate normally. - warn!("Failed to get local timelines for tenant {tenant_id}: {err}"); - None - } - Ok(local_timeline_infos) => Some( - local_timeline_infos - .into_iter() - .fold(0, |acc, x| acc + x.1.current_physical_size.unwrap()), - ), - }; - json_response( StatusCode::OK, TenantInfo { @@ -784,7 +747,7 @@ async fn tenant_config_handler(mut request: Request) -> Result) -> Result, ApiError> { if !fail::has_failpoints() { return Err(ApiError::BadRequest(anyhow!( @@ -818,11 +781,6 @@ async fn failpoints_handler(mut request: Request) -> Result } // Run GC immediately on given timeline. -// FIXME: This is just for tests. See test_runner/regress/test_gc.py. -// This probably should require special authentication or a global flag to -// enable, I don't think we want to or need to allow regular clients to invoke -// GC. -// @hllinnaka in commits ec44f4b29, 3aca717f3 #[cfg(feature = "testing")] async fn timeline_gc_handler(mut request: Request) -> Result, ApiError> { let tenant_id: TenantId = parse_request_param(&request, "tenant_id")?; @@ -848,9 +806,6 @@ async fn timeline_gc_handler(mut request: Request) -> Result) -> Result, ApiError> { let tenant_id: TenantId = parse_request_param(&request, "tenant_id")?; diff --git a/pageserver/src/import_datadir.rs b/pageserver/src/import_datadir.rs index 23c4351b4e..ee3dc684e3 100644 --- a/pageserver/src/import_datadir.rs +++ b/pageserver/src/import_datadir.rs @@ -43,19 +43,19 @@ pub fn get_lsn_from_controlfile(path: &Path) -> Result { /// The code that deals with the checkpoint would not work right if the /// cluster was not shut down cleanly. pub fn import_timeline_from_postgres_datadir( - path: &Path, tline: &Timeline, - lsn: Lsn, + pgdata_path: &Path, + pgdata_lsn: Lsn, ) -> Result<()> { let mut pg_control: Option = None; // TODO this shoud be start_lsn, which is not necessarily equal to end_lsn (aka lsn) // Then fishing out pg_control would be unnecessary - let mut modification = tline.begin_modification(lsn); + let mut modification = tline.begin_modification(pgdata_lsn); modification.init_empty()?; // Import all but pg_wal - let all_but_wal = WalkDir::new(path) + let all_but_wal = WalkDir::new(pgdata_path) .into_iter() .filter_entry(|entry| !entry.path().ends_with("pg_wal")); for entry in all_but_wal { @@ -63,7 +63,7 @@ pub fn import_timeline_from_postgres_datadir( let metadata = entry.metadata().expect("error getting dir entry metadata"); if metadata.is_file() { let absolute_path = entry.path(); - let relative_path = absolute_path.strip_prefix(path)?; + let relative_path = absolute_path.strip_prefix(pgdata_path)?; let file = File::open(absolute_path)?; let len = metadata.len() as usize; @@ -84,7 +84,7 @@ pub fn import_timeline_from_postgres_datadir( "Postgres cluster was not shut down cleanly" ); ensure!( - pg_control.checkPointCopy.redo == lsn.0, + pg_control.checkPointCopy.redo == pgdata_lsn.0, "unexpected checkpoint REDO pointer" ); @@ -92,10 +92,10 @@ pub fn import_timeline_from_postgres_datadir( // this reads the checkpoint record itself, advancing the tip of the timeline to // *after* the checkpoint record. And crucially, it initializes the 'prev_lsn'. import_wal( - &path.join("pg_wal"), + &pgdata_path.join("pg_wal"), tline, Lsn(pg_control.checkPointCopy.redo), - lsn, + pgdata_lsn, )?; Ok(()) diff --git a/pageserver/src/lib.rs b/pageserver/src/lib.rs index 7937f72de7..c75f940386 100644 --- a/pageserver/src/lib.rs +++ b/pageserver/src/lib.rs @@ -46,6 +46,8 @@ pub const DELTA_FILE_MAGIC: u16 = 0x5A61; pub const LOG_FILE_NAME: &str = "pageserver.log"; +static ZERO_PAGE: bytes::Bytes = bytes::Bytes::from_static(&[0u8; 8192]); + /// Config for the Repository checkpointer #[derive(Debug, Clone, Copy)] pub enum CheckpointConfig { @@ -119,32 +121,6 @@ impl TenantTimelineValues { fn new() -> Self { Self(HashMap::new()) } - - fn with_capacity(capacity: usize) -> Self { - Self(HashMap::with_capacity(capacity)) - } - - /// A convenience method to map certain values and omit some of them, if needed. - /// Tenants that won't have any timeline entries due to the filtering, will still be preserved - /// in the structure. - fn filter_map(self, map: F) -> TenantTimelineValues - where - F: Fn(T) -> Option, - { - let capacity = self.0.len(); - self.0.into_iter().fold( - TenantTimelineValues::::with_capacity(capacity), - |mut new_values, (tenant_id, old_values)| { - let new_timeline_values = new_values.0.entry(tenant_id).or_default(); - for (timeline_id, old_value) in old_values { - if let Some(new_value) = map(old_value) { - new_timeline_values.insert(timeline_id, new_value); - } - } - new_values - }, - ) - } } /// A suffix to be used during file sync from the remote storage, @@ -181,35 +157,3 @@ mod backoff_defaults_tests { ); } } - -#[cfg(test)] -mod tests { - use crate::tenant::harness::TIMELINE_ID; - - use super::*; - - #[test] - fn tenant_timeline_value_mapping() { - let first_tenant = TenantId::generate(); - let second_tenant = TenantId::generate(); - assert_ne!(first_tenant, second_tenant); - - let mut initial = TenantTimelineValues::new(); - initial - .0 - .entry(first_tenant) - .or_default() - .insert(TIMELINE_ID, "test_value"); - let _ = initial.0.entry(second_tenant).or_default(); - assert_eq!(initial.0.len(), 2, "Should have entries for both tenants"); - - let filtered = initial.filter_map(|_| None::<&str>).0; - assert_eq!( - filtered.len(), - 2, - "Should have entries for both tenants even after filtering away all entries" - ); - assert!(filtered.contains_key(&first_tenant)); - assert!(filtered.contains_key(&second_tenant)); - } -} diff --git a/pageserver/src/metrics.rs b/pageserver/src/metrics.rs index 5c2f81d731..7ae2d0f14c 100644 --- a/pageserver/src/metrics.rs +++ b/pageserver/src/metrics.rs @@ -107,18 +107,20 @@ static CURRENT_LOGICAL_SIZE: Lazy = Lazy::new(|| { // Metrics for cloud upload. These metrics reflect data uploaded to cloud storage, // or in testing they estimate how much we would upload if we did. -static NUM_PERSISTENT_FILES_CREATED: Lazy = Lazy::new(|| { - register_int_counter!( +static NUM_PERSISTENT_FILES_CREATED: Lazy = Lazy::new(|| { + register_int_counter_vec!( "pageserver_created_persistent_files_total", "Number of files created that are meant to be uploaded to cloud storage", + &["tenant_id", "timeline_id"] ) .expect("failed to define a metric") }); -static PERSISTENT_BYTES_WRITTEN: Lazy = Lazy::new(|| { - register_int_counter!( +static PERSISTENT_BYTES_WRITTEN: Lazy = Lazy::new(|| { + register_int_counter_vec!( "pageserver_written_persistent_bytes_total", "Total bytes written that are meant to be uploaded to cloud storage", + &["tenant_id", "timeline_id"] ) .expect("failed to define a metric") }); @@ -275,11 +277,15 @@ pub static TENANT_TASK_EVENTS: Lazy = Lazy::new(|| { /// smallest redo processing times. These buckets allow us to measure down /// to 5us, which equates to 200'000 pages/sec, which equates to 1.6GB/sec. /// This is much better than the previous 5ms aka 200 pages/sec aka 1.6MB/sec. +/// +/// Values up to 1s are recorded because metrics show that we have redo +/// durations and lock times larger than 0.250s. macro_rules! redo_histogram_time_buckets { () => { vec![ 0.000_005, 0.000_010, 0.000_025, 0.000_050, 0.000_100, 0.000_250, 0.000_500, 0.001_000, - 0.002_500, 0.005_000, 0.010_000, 0.025_000, 0.050_000, 0.100_000, 0.250_000, + 0.002_500, 0.005_000, 0.010_000, 0.025_000, 0.050_000, 0.100_000, 0.250_000, 0.500_000, + 1.000_000, ] }; } @@ -294,6 +300,17 @@ macro_rules! redo_histogram_count_buckets { }; } +macro_rules! redo_bytes_histogram_count_buckets { + () => { + // powers of (2^.5), from 2^4.5 to 2^15 (22 buckets) + // rounded up to the next multiple of 8 to capture any MAXALIGNed record of that size, too. + vec![ + 24.0, 32.0, 48.0, 64.0, 96.0, 128.0, 184.0, 256.0, 368.0, 512.0, 728.0, 1024.0, 1456.0, + 2048.0, 2904.0, 4096.0, 5800.0, 8192.0, 11592.0, 16384.0, 23176.0, 32768.0, + ] + }; +} + pub static WAL_REDO_TIME: Lazy = Lazy::new(|| { register_histogram!( "pageserver_wal_redo_seconds", @@ -321,6 +338,15 @@ pub static WAL_REDO_RECORDS_HISTOGRAM: Lazy = Lazy::new(|| { .expect("failed to define a metric") }); +pub static WAL_REDO_BYTES_HISTOGRAM: Lazy = Lazy::new(|| { + register_histogram!( + "pageserver_wal_redo_bytes_histogram", + "Histogram of number of records replayed per redo", + redo_bytes_histogram_count_buckets!(), + ) + .expect("failed to define a metric") +}); + pub static WAL_REDO_RECORD_COUNTER: Lazy = Lazy::new(|| { register_int_counter!( "pageserver_replayed_wal_records_total", @@ -386,8 +412,12 @@ impl TimelineMetrics { let current_logical_size_gauge = CURRENT_LOGICAL_SIZE .get_metric_with_label_values(&[&tenant_id, &timeline_id]) .unwrap(); - let num_persistent_files_created = NUM_PERSISTENT_FILES_CREATED.clone(); - let persistent_bytes_written = PERSISTENT_BYTES_WRITTEN.clone(); + let num_persistent_files_created = NUM_PERSISTENT_FILES_CREATED + .get_metric_with_label_values(&[&tenant_id, &timeline_id]) + .unwrap(); + let persistent_bytes_written = PERSISTENT_BYTES_WRITTEN + .get_metric_with_label_values(&[&tenant_id, &timeline_id]) + .unwrap(); TimelineMetrics { tenant_id, @@ -419,6 +449,8 @@ impl Drop for TimelineMetrics { let _ = WAIT_LSN_TIME.remove_label_values(&[tenant_id, timeline_id]); let _ = CURRENT_PHYSICAL_SIZE.remove_label_values(&[tenant_id, timeline_id]); let _ = CURRENT_LOGICAL_SIZE.remove_label_values(&[tenant_id, timeline_id]); + let _ = NUM_PERSISTENT_FILES_CREATED.remove_label_values(&[tenant_id, timeline_id]); + let _ = PERSISTENT_BYTES_WRITTEN.remove_label_values(&[tenant_id, timeline_id]); for op in STORAGE_TIME_OPERATIONS { let _ = STORAGE_TIME.remove_label_values(&[op, tenant_id, timeline_id]); diff --git a/pageserver/src/page_service.rs b/pageserver/src/page_service.rs index 795a99058d..9b2bb3114d 100644 --- a/pageserver/src/page_service.rs +++ b/pageserver/src/page_service.rs @@ -32,7 +32,7 @@ use utils::{ use crate::basebackup; use crate::config::{PageServerConf, ProfilingConfig}; -use crate::import_datadir::{import_basebackup_from_tar, import_wal_from_tar}; +use crate::import_datadir::import_wal_from_tar; use crate::metrics::{LIVE_CONNECTIONS_COUNT, SMGR_QUERY_TIME}; use crate::profiling::profpoint_start; use crate::reltag::RelTag; @@ -500,11 +500,8 @@ impl PageServerHandler { task_mgr::associate_with(Some(tenant_id), Some(timeline_id)); // Create empty timeline info!("creating new timeline"); - let timeline = tenant_mgr::get_tenant(tenant_id, true)?.create_empty_timeline( - timeline_id, - base_lsn, - pg_version, - )?; + let tenant = tenant_mgr::get_tenant(tenant_id, true)?; + let timeline = tenant.create_empty_timeline(timeline_id, base_lsn, pg_version)?; // TODO mark timeline as not ready until it reaches end_lsn. // We might have some wal to import as well, and we should prevent compute @@ -527,7 +524,8 @@ impl PageServerHandler { // - use block_in_place() let mut copyin_stream = Box::pin(copyin_stream(pgb)); let reader = SyncIoBridge::new(StreamReader::new(&mut copyin_stream)); - tokio::task::block_in_place(|| import_basebackup_from_tar(&timeline, reader, base_lsn))?; + tokio::task::block_in_place(|| timeline.import_basebackup_from_tar(reader, base_lsn))?; + timeline.initialize()?; // Drain the rest of the Copy data let mut bytes_after_tar = 0; @@ -544,12 +542,6 @@ impl PageServerHandler { // It wouldn't work if base came from vanilla postgres though, // since we discard some log files. - // Flush data to disk, then upload to s3 - info!("flushing layers"); - timeline.checkpoint(CheckpointConfig::Flush)?; - - timeline.launch_wal_receiver()?; - info!("done"); Ok(()) } diff --git a/pageserver/src/pgdatadir_mapping.rs b/pageserver/src/pgdatadir_mapping.rs index fc9867dc05..ca931ed37d 100644 --- a/pageserver/src/pgdatadir_mapping.rs +++ b/pageserver/src/pgdatadir_mapping.rs @@ -1373,6 +1373,17 @@ fn is_rel_block_key(key: Key) -> bool { key.field1 == 0x00 && key.field4 != 0 } +pub fn is_rel_fsm_block_key(key: Key) -> bool { + key.field1 == 0x00 && key.field4 != 0 && key.field5 == FSM_FORKNUM && key.field6 != 0xffffffff +} + +pub fn is_rel_vm_block_key(key: Key) -> bool { + key.field1 == 0x00 + && key.field4 != 0 + && key.field5 == VISIBILITYMAP_FORKNUM + && key.field6 != 0xffffffff +} + pub fn key_to_slru_block(key: Key) -> Result<(SlruKind, u32, BlockNumber)> { Ok(match key.field1 { 0x01 => { @@ -1403,7 +1414,9 @@ pub fn create_test_timeline( timeline_id: utils::id::TimelineId, pg_version: u32, ) -> Result> { - let tline = tenant.create_empty_timeline(timeline_id, Lsn(8), pg_version)?; + let tline = tenant + .create_empty_timeline(timeline_id, Lsn(8), pg_version)? + .initialize()?; let mut m = tline.begin_modification(Lsn(8)); m.init_empty()?; m.commit()?; diff --git a/pageserver/src/storage_sync.rs b/pageserver/src/storage_sync.rs index bee460d173..037fe76d7f 100644 --- a/pageserver/src/storage_sync.rs +++ b/pageserver/src/storage_sync.rs @@ -169,9 +169,14 @@ use self::{ upload::{upload_index_part, upload_timeline_layers, UploadedTimeline}, }; use crate::{ - config::PageServerConf, exponential_backoff, storage_sync::index::RemoteIndex, task_mgr, - task_mgr::TaskKind, task_mgr::BACKGROUND_RUNTIME, tenant::metadata::TimelineMetadata, - tenant_mgr::attach_local_tenants, + config::PageServerConf, + exponential_backoff, + storage_sync::index::{LayerFileMetadata, RemoteIndex}, + task_mgr, + task_mgr::TaskKind, + task_mgr::BACKGROUND_RUNTIME, + tenant::metadata::TimelineMetadata, + tenant_mgr::{attach_local_tenants, TenantAttachData}, }; use crate::{ metrics::{IMAGE_SYNC_TIME, REMAINING_SYNC_ITEMS, REMOTE_INDEX_UPLOAD}, @@ -188,7 +193,7 @@ static SYNC_QUEUE: OnceCell = OnceCell::new(); /// A timeline status to share with pageserver's sync counterpart, /// after comparing local and remote timeline state. -#[derive(Clone)] +#[derive(Clone, PartialEq, Eq)] pub enum LocalTimelineInitStatus { /// The timeline has every remote layer present locally. /// There could be some layers requiring uploading, @@ -311,7 +316,7 @@ impl SyncQueue { /// A task to run in the async download/upload loop. /// Limited by the number of retries, after certain threshold the failing task gets evicted and the timeline disabled. -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] enum SyncTask { /// A checkpoint outcome with possible local file updates that need actualization in the remote storage. /// Not necessary more fresh than the one already uploaded. @@ -422,7 +427,7 @@ impl SyncTaskBatch { .extend(new_delete.data.deleted_layers.iter().cloned()); } if let Some(batch_upload) = &mut self.upload { - let not_deleted = |layer: &PathBuf| { + let not_deleted = |layer: &PathBuf, _: &mut LayerFileMetadata| { !new_delete.data.layers_to_delete.contains(layer) && !new_delete.data.deleted_layers.contains(layer) }; @@ -450,21 +455,35 @@ impl SyncTaskBatch { #[derive(Debug, Clone, PartialEq, Eq)] struct LayersUpload { /// Layer file path in the pageserver workdir, that were added for the corresponding checkpoint. - layers_to_upload: HashSet, + layers_to_upload: HashMap, /// Already uploaded layers. Used to store the data about the uploads between task retries /// and to record the data into the remote index after the task got completed or evicted. - uploaded_layers: HashSet, + uploaded_layers: HashMap, metadata: Option, } /// A timeline download task. /// Does not contain the file list to download, to allow other /// parts of the pageserer code to schedule the task -/// without using the remote index or any other ways to list the remote timleine files. +/// without using the remote index or any other ways to list the remote timeline files. /// Skips the files that are already downloaded. #[derive(Debug, Clone, PartialEq, Eq)] struct LayersDownload { layers_to_skip: HashSet, + + /// Paths which have been downloaded, and had their metadata verified or generated. + /// + /// Metadata generation happens when upgrading from past version of `IndexPart`. + gathered_metadata: HashMap, +} + +impl LayersDownload { + fn from_skipped_layers(layers_to_skip: HashSet) -> Self { + LayersDownload { + layers_to_skip, + gathered_metadata: HashMap::default(), + } + } } #[derive(Debug, Clone, PartialEq, Eq)] @@ -486,7 +505,7 @@ struct LayersDeletion { pub fn schedule_layer_upload( tenant_id: TenantId, timeline_id: TimelineId, - layers_to_upload: HashSet, + layers_to_upload: HashMap, metadata: Option, ) { let sync_queue = match SYNC_QUEUE.get() { @@ -503,7 +522,7 @@ pub fn schedule_layer_upload( }, SyncTask::upload(LayersUpload { layers_to_upload, - uploaded_layers: HashSet::new(), + uploaded_layers: HashMap::new(), metadata, }), ); @@ -561,18 +580,44 @@ pub fn schedule_layer_download(tenant_id: TenantId, timeline_id: TimelineId) { tenant_id, timeline_id, }, - SyncTask::download(LayersDownload { - layers_to_skip: HashSet::new(), - }), + SyncTask::download(LayersDownload::from_skipped_layers(HashSet::new())), ); debug!("Download task for tenant {tenant_id}, timeline {timeline_id} sent") } +/// Local existing timeline files +/// +/// Values of this type serve different meanings in different contexts. On startup, collected +/// timelines come with the full collected information and when signalling readyness to attach +/// after completed download. After the download the file information is no longer carried, because +/// it is already merged into [`RemoteTimeline`]. +#[derive(Debug)] +pub struct TimelineLocalFiles(TimelineMetadata, HashMap); + +impl TimelineLocalFiles { + pub fn metadata(&self) -> &TimelineMetadata { + &self.0 + } + + /// Called during startup, for all of the local files with full metadata. + pub(crate) fn collected( + metadata: TimelineMetadata, + timeline_files: HashMap, + ) -> TimelineLocalFiles { + TimelineLocalFiles(metadata, timeline_files) + } + + /// Called near the end of tenant initialization, to signal readyness to attach tenants. + pub(crate) fn ready(metadata: TimelineMetadata) -> Self { + TimelineLocalFiles(metadata, HashMap::new()) + } +} + /// Launch a thread to perform remote storage sync tasks. /// See module docs for loop step description. pub fn spawn_storage_sync_task( conf: &'static PageServerConf, - local_timeline_files: TenantTimelineValues<(TimelineMetadata, HashSet)>, + local_timeline_files: HashMap>, storage: GenericRemoteStorage, max_concurrent_timelines_sync: NonZeroUsize, max_sync_errors: NonZeroU32, @@ -595,7 +640,7 @@ pub fn spawn_storage_sync_task( let mut keys_for_index_part_downloads = HashSet::new(); let mut timelines_to_sync = HashMap::new(); - for (tenant_id, timeline_data) in local_timeline_files.0 { + for (tenant_id, timeline_data) in local_timeline_files { if timeline_data.is_empty() { info!("got empty tenant {}", tenant_id); let _ = empty_tenants.0.entry(tenant_id).or_default(); @@ -698,7 +743,7 @@ async fn storage_sync_loop( "Sync loop step completed, {} new tenant state update(s)", updated_tenants.len() ); - let mut timelines_to_attach = TenantTimelineValues::new(); + let mut timelines_to_attach = HashMap::new(); let index_accessor = index.read().await; for tenant_id in updated_tenants { let tenant_entry = match index_accessor.tenant_entry(&tenant_id) { @@ -724,12 +769,16 @@ async fn storage_sync_loop( // and register them all at once in a tenant for download // to be submitted in a single operation to tenant // so it can apply them at once to internal timeline map. - timelines_to_attach.0.insert( + timelines_to_attach.insert( tenant_id, - tenant_entry - .iter() - .map(|(&id, entry)| (id, entry.metadata.clone())) - .collect(), + TenantAttachData::Ready( + tenant_entry + .iter() + .map(|(&id, entry)| { + (id, TimelineLocalFiles::ready(entry.metadata.clone())) + }) + .collect(), + ), ); } } @@ -971,15 +1020,27 @@ async fn download_timeline_data( } DownloadedTimeline::Successful(mut download_data) => { match update_local_metadata(conf, sync_id, current_remote_timeline).await { - Ok(()) => match index.write().await.set_awaits_download(&sync_id, false) { - Ok(()) => { - register_sync_status(sync_id, sync_start, TASK_NAME, Some(true)); - return DownloadStatus::Downloaded; - } - Err(e) => { - error!("Timeline {sync_id} was expected to be in the remote index after a successful download, but it's absent: {e:?}"); - } - }, + Ok(()) => { + let mut g = index.write().await; + + match g.set_awaits_download(&sync_id, false) { + Ok(()) => { + let timeline = g + .timeline_entry_mut(&sync_id) + .expect("set_awaits_download verified existence"); + + timeline.merge_metadata_from_downloaded( + &download_data.data.gathered_metadata, + ); + + register_sync_status(sync_id, sync_start, TASK_NAME, Some(true)); + return DownloadStatus::Downloaded; + } + Err(e) => { + error!("Timeline {sync_id} was expected to be in the remote index after a successful download, but it's absent: {e:?}"); + } + }; + } Err(e) => { error!("Failed to update local timeline metadata: {e:?}"); download_data.retries += 1; @@ -1182,11 +1243,18 @@ async fn update_remote_data( } if upload_failed { existing_entry.add_upload_failures( - uploaded_data.layers_to_upload.iter().cloned(), + uploaded_data + .layers_to_upload + .iter() + .map(|(k, v)| (k.to_owned(), v.to_owned())), ); } else { - existing_entry - .add_timeline_layers(uploaded_data.uploaded_layers.iter().cloned()); + existing_entry.add_timeline_layers( + uploaded_data + .uploaded_layers + .iter() + .map(|(k, v)| (k.to_owned(), v.to_owned())), + ); } } RemoteDataUpdate::Delete(layers_to_remove) => { @@ -1206,11 +1274,19 @@ async fn update_remote_data( }; let mut new_remote_timeline = RemoteTimeline::new(new_metadata.clone()); if upload_failed { - new_remote_timeline - .add_upload_failures(uploaded_data.layers_to_upload.iter().cloned()); + new_remote_timeline.add_upload_failures( + uploaded_data + .layers_to_upload + .iter() + .map(|(k, v)| (k.to_owned(), v.to_owned())), + ); } else { - new_remote_timeline - .add_timeline_layers(uploaded_data.uploaded_layers.iter().cloned()); + new_remote_timeline.add_timeline_layers( + uploaded_data + .uploaded_layers + .iter() + .map(|(k, v)| (k.to_owned(), v.to_owned())), + ); } index_accessor.add_timeline_entry(sync_id, new_remote_timeline.clone()); @@ -1258,13 +1334,14 @@ async fn validate_task_retries( fn schedule_first_sync_tasks( index: &mut RemoteTimelineIndex, sync_queue: &SyncQueue, - local_timeline_files: HashMap)>, + local_timeline_files: HashMap, ) -> TenantTimelineValues { let mut local_timeline_init_statuses = TenantTimelineValues::new(); let mut new_sync_tasks = VecDeque::with_capacity(local_timeline_files.len()); - for (sync_id, (local_metadata, local_files)) in local_timeline_files { + for (sync_id, local_timeline) in local_timeline_files { + let TimelineLocalFiles(local_metadata, local_files) = local_timeline; match index.timeline_entry_mut(&sync_id) { Some(remote_timeline) => { let (timeline_status, awaits_download) = compare_local_and_remote_timeline( @@ -1308,7 +1385,7 @@ fn schedule_first_sync_tasks( sync_id, SyncTask::upload(LayersUpload { layers_to_upload: local_files, - uploaded_layers: HashSet::new(), + uploaded_layers: HashMap::new(), metadata: Some(local_metadata.clone()), }), )); @@ -1335,20 +1412,46 @@ fn compare_local_and_remote_timeline( new_sync_tasks: &mut VecDeque<(TenantTimelineId, SyncTask)>, sync_id: TenantTimelineId, local_metadata: TimelineMetadata, - local_files: HashSet, + local_files: HashMap, remote_entry: &RemoteTimeline, ) -> (LocalTimelineInitStatus, bool) { let _entered = info_span!("compare_local_and_remote_timeline", sync_id = %sync_id).entered(); - let remote_files = remote_entry.stored_files(); + let needed_to_download_files = remote_entry + .stored_files() + .iter() + .filter_map(|(layer_file, remote_metadata)| { + if let Some(local_metadata) = local_files.get(layer_file) { + match (remote_metadata.file_size(), local_metadata.file_size()) { + (Some(x), Some(y)) if x == y => { None }, + (None, Some(_)) => { + // upgrading from an earlier IndexPart without metadata + None + }, + _ => { + // having to deal with other than (Some(x), Some(y)) where x != y here is a + // bummer, but see #2582 and #2610 for attempts and discussion. + warn!("Redownloading locally existing {layer_file:?} due to size mismatch, size on index: {:?}, on disk: {:?}", remote_metadata.file_size(), local_metadata.file_size()); + Some(layer_file) + }, + } + } else { + // doesn't exist locally + Some(layer_file) + } + }) + .collect::>(); - let number_of_layers_to_download = remote_files.difference(&local_files).count(); - let (initial_timeline_status, awaits_download) = if number_of_layers_to_download > 0 { + let (initial_timeline_status, awaits_download) = if !needed_to_download_files.is_empty() { new_sync_tasks.push_back(( sync_id, - SyncTask::download(LayersDownload { - layers_to_skip: local_files.clone(), - }), + SyncTask::download(LayersDownload::from_skipped_layers( + local_files + .keys() + .filter(|path| !needed_to_download_files.contains(path)) + .cloned() + .collect(), + )), )); info!("NeedsSync"); (LocalTimelineInitStatus::NeedsSync, true) @@ -1363,15 +1466,22 @@ fn compare_local_and_remote_timeline( }; let layers_to_upload = local_files - .difference(remote_files) - .cloned() - .collect::>(); + .iter() + .filter_map(|(local_file, metadata)| { + if !remote_entry.stored_files().contains_key(local_file) { + Some((local_file.to_owned(), metadata.to_owned())) + } else { + None + } + }) + .collect::>(); + if !layers_to_upload.is_empty() { new_sync_tasks.push_back(( sync_id, SyncTask::upload(LayersUpload { layers_to_upload, - uploaded_layers: HashSet::new(), + uploaded_layers: HashMap::new(), metadata: Some(local_metadata), }), )); @@ -1427,11 +1537,12 @@ mod test_utils { let timeline_path = harness.timeline_path(&timeline_id); fs::create_dir_all(&timeline_path).await?; - let mut layers_to_upload = HashSet::with_capacity(filenames.len()); + let mut layers_to_upload = HashMap::with_capacity(filenames.len()); for &file in filenames { let file_path = timeline_path.join(file); fs::write(&file_path, dummy_contents(file).into_bytes()).await?; - layers_to_upload.insert(file_path); + let metadata = LayerFileMetadata::new(file_path.metadata()?.len()); + layers_to_upload.insert(file_path, metadata); } fs::write( @@ -1442,7 +1553,7 @@ mod test_utils { Ok(LayersUpload { layers_to_upload, - uploaded_layers: HashSet::new(), + uploaded_layers: HashMap::new(), metadata: Some(metadata), }) } @@ -1497,12 +1608,13 @@ mod tests { assert!(sync_id_2 != sync_id_3); assert!(sync_id_3 != TEST_SYNC_ID); - let download_task = SyncTask::download(LayersDownload { - layers_to_skip: HashSet::from([PathBuf::from("sk")]), - }); + let download_task = + SyncTask::download(LayersDownload::from_skipped_layers(HashSet::from([ + PathBuf::from("sk"), + ]))); let upload_task = SyncTask::upload(LayersUpload { - layers_to_upload: HashSet::from([PathBuf::from("up")]), - uploaded_layers: HashSet::from([PathBuf::from("upl")]), + layers_to_upload: HashMap::from([(PathBuf::from("up"), LayerFileMetadata::new(123))]), + uploaded_layers: HashMap::from([(PathBuf::from("upl"), LayerFileMetadata::new(123))]), metadata: Some(dummy_metadata(Lsn(2))), }); let delete_task = SyncTask::delete(LayersDeletion { @@ -1546,12 +1658,10 @@ mod tests { let sync_queue = SyncQueue::new(NonZeroUsize::new(100).unwrap()); assert_eq!(sync_queue.len(), 0); - let download = LayersDownload { - layers_to_skip: HashSet::from([PathBuf::from("sk")]), - }; + let download = LayersDownload::from_skipped_layers(HashSet::from([PathBuf::from("sk")])); let upload = LayersUpload { - layers_to_upload: HashSet::from([PathBuf::from("up")]), - uploaded_layers: HashSet::from([PathBuf::from("upl")]), + layers_to_upload: HashMap::from([(PathBuf::from("up"), LayerFileMetadata::new(123))]), + uploaded_layers: HashMap::from([(PathBuf::from("upl"), LayerFileMetadata::new(123))]), metadata: Some(dummy_metadata(Lsn(2))), }; let delete = LayersDeletion { @@ -1599,18 +1709,10 @@ mod tests { #[tokio::test] async fn same_task_id_same_tasks_batch() { let sync_queue = SyncQueue::new(NonZeroUsize::new(1).unwrap()); - let download_1 = LayersDownload { - layers_to_skip: HashSet::from([PathBuf::from("sk1")]), - }; - let download_2 = LayersDownload { - layers_to_skip: HashSet::from([PathBuf::from("sk2")]), - }; - let download_3 = LayersDownload { - layers_to_skip: HashSet::from([PathBuf::from("sk3")]), - }; - let download_4 = LayersDownload { - layers_to_skip: HashSet::from([PathBuf::from("sk4")]), - }; + let download_1 = LayersDownload::from_skipped_layers(HashSet::from([PathBuf::from("sk1")])); + let download_2 = LayersDownload::from_skipped_layers(HashSet::from([PathBuf::from("sk2")])); + let download_3 = LayersDownload::from_skipped_layers(HashSet::from([PathBuf::from("sk3")])); + let download_4 = LayersDownload::from_skipped_layers(HashSet::from([PathBuf::from("sk4")])); let sync_id_2 = TenantTimelineId { tenant_id: TenantId::from_array(hex!("22223344556677881122334455667788")), @@ -1634,15 +1736,15 @@ mod tests { Some(SyncTaskBatch { download: Some(SyncData { retries: 0, - data: LayersDownload { - layers_to_skip: { + data: LayersDownload::from_skipped_layers( + { let mut set = HashSet::new(); set.extend(download_1.layers_to_skip.into_iter()); set.extend(download_2.layers_to_skip.into_iter()); set.extend(download_4.layers_to_skip.into_iter()); set }, - } + ) }), upload: None, delete: None, @@ -1658,4 +1760,148 @@ mod tests { "Should have one task left out of the batch" ); } + + mod local_and_remote_comparisons { + use super::*; + + #[test] + fn ready() { + let mut new_sync_tasks = VecDeque::default(); + let sync_id = TenantTimelineId::generate(); + let local_metadata = dummy_metadata(0x02.into()); + let local_files = + HashMap::from([(PathBuf::from("first_file"), LayerFileMetadata::new(123))]); + let mut remote_entry = RemoteTimeline::new(local_metadata.clone()); + remote_entry + .add_timeline_layers([(PathBuf::from("first_file"), LayerFileMetadata::new(123))]); + + let (status, sync_needed) = compare_local_and_remote_timeline( + &mut new_sync_tasks, + sync_id, + local_metadata.clone(), + local_files, + &remote_entry, + ); + + assert_eq!( + status, + LocalTimelineInitStatus::LocallyComplete(local_metadata) + ); + assert!(!sync_needed); + + assert!(new_sync_tasks.is_empty(), "{:?}", new_sync_tasks); + } + + #[test] + fn needs_download() { + let mut new_sync_tasks = VecDeque::default(); + let sync_id = TenantTimelineId::generate(); + let local_metadata = dummy_metadata(0x02.into()); + let local_files = HashMap::default(); + let mut remote_entry = RemoteTimeline::new(local_metadata.clone()); + remote_entry + .add_timeline_layers([(PathBuf::from("first_file"), LayerFileMetadata::new(123))]); + + let (status, sync_needed) = compare_local_and_remote_timeline( + &mut new_sync_tasks, + sync_id, + local_metadata, + local_files.clone(), + &remote_entry, + ); + + assert_eq!(status, LocalTimelineInitStatus::NeedsSync); + assert!(sync_needed); + + let new_sync_tasks = new_sync_tasks.into_iter().collect::>(); + + assert_eq!( + &new_sync_tasks, + &[( + sync_id, + SyncTask::download(LayersDownload::from_skipped_layers( + local_files.keys().cloned().collect() + )) + )] + ); + } + + #[test] + fn redownload_is_not_needed_on_upgrade() { + // originally the implementation missed the `(None, Some(_))` case in the match, and + // proceeded to always redownload if the remote metadata was not available. + + let mut new_sync_tasks = VecDeque::default(); + let sync_id = TenantTimelineId::generate(); + + let local_metadata = dummy_metadata(0x02.into()); + + // type system would in general allow that LayerFileMetadata would be created with + // file_size: None, however `LayerFileMetadata::default` is only allowed from tests, + // and so everywhere within the system valid LayerFileMetadata is being created, it is + // created through `::new`. + let local_files = + HashMap::from([(PathBuf::from("first_file"), LayerFileMetadata::new(123))]); + + let mut remote_entry = RemoteTimeline::new(local_metadata.clone()); + + // RemoteTimeline is constructed out of an older version IndexPart, which didn't carry + // any metadata. + remote_entry + .add_timeline_layers([(PathBuf::from("first_file"), LayerFileMetadata::default())]); + + let (status, sync_needed) = compare_local_and_remote_timeline( + &mut new_sync_tasks, + sync_id, + local_metadata.clone(), + local_files, + &remote_entry, + ); + + assert_eq!( + status, + LocalTimelineInitStatus::LocallyComplete(local_metadata) + ); + assert!(!sync_needed); + } + + #[test] + fn needs_upload() { + let mut new_sync_tasks = VecDeque::default(); + let sync_id = TenantTimelineId::generate(); + let local_metadata = dummy_metadata(0x02.into()); + let local_files = + HashMap::from([(PathBuf::from("first_file"), LayerFileMetadata::new(123))]); + let mut remote_entry = RemoteTimeline::new(local_metadata.clone()); + remote_entry.add_timeline_layers([]); + + let (status, sync_needed) = compare_local_and_remote_timeline( + &mut new_sync_tasks, + sync_id, + local_metadata.clone(), + local_files.clone(), + &remote_entry, + ); + + assert_eq!( + status, + LocalTimelineInitStatus::LocallyComplete(local_metadata.clone()) + ); + assert!(!sync_needed); + + let new_sync_tasks = new_sync_tasks.into_iter().collect::>(); + + assert_eq!( + &new_sync_tasks, + &[( + sync_id, + SyncTask::upload(LayersUpload { + layers_to_upload: local_files, + uploaded_layers: HashMap::default(), + metadata: Some(local_metadata), + }) + )] + ); + } + } } diff --git a/pageserver/src/storage_sync/delete.rs b/pageserver/src/storage_sync/delete.rs index 21a3372e70..39846f0da3 100644 --- a/pageserver/src/storage_sync/delete.rs +++ b/pageserver/src/storage_sync/delete.rs @@ -171,7 +171,7 @@ mod tests { let local_timeline_path = harness.timeline_path(&TIMELINE_ID); let timeline_upload = create_local_timeline(&harness, TIMELINE_ID, &layer_files, metadata.clone()).await?; - for local_path in timeline_upload.layers_to_upload { + for (local_path, _metadata) in timeline_upload.layers_to_upload { let remote_path = local_storage.resolve_in_storage(&local_storage.remote_object_id(&local_path)?)?; let remote_parent_dir = remote_path.parent().unwrap(); diff --git a/pageserver/src/storage_sync/download.rs b/pageserver/src/storage_sync/download.rs index 3e850443d8..6f9b2e2071 100644 --- a/pageserver/src/storage_sync/download.rs +++ b/pageserver/src/storage_sync/download.rs @@ -16,9 +16,13 @@ use tokio::{ }; use tracing::{debug, error, info, warn}; -use crate::{config::PageServerConf, storage_sync::SyncTask, TEMP_FILE_SUFFIX}; +use crate::{ + config::PageServerConf, + storage_sync::{index::LayerFileMetadata, SyncTask}, + TEMP_FILE_SUFFIX, +}; use utils::{ - crashsafe_dir::path_with_suffix_extension, + crashsafe::path_with_suffix_extension, id::{TenantId, TenantTimelineId, TimelineId}, }; @@ -219,8 +223,14 @@ pub(super) async fn download_timeline_layers<'a>( let layers_to_download = remote_timeline .stored_files() - .difference(&download.layers_to_skip) - .cloned() + .iter() + .filter_map(|(layer_path, metadata)| { + if !download.layers_to_skip.contains(layer_path) { + Some((layer_path.to_owned(), metadata.to_owned())) + } else { + None + } + }) .collect::>(); debug!("Layers to download: {layers_to_download:?}"); @@ -233,89 +243,129 @@ pub(super) async fn download_timeline_layers<'a>( let mut download_tasks = layers_to_download .into_iter() - .map(|layer_destination_path| async move { - if layer_destination_path.exists() { - debug!( - "Layer already exists locally, skipping download: {}", - layer_destination_path.display() - ); - } else { - // Perform a rename inspired by durable_rename from file_utils.c. - // The sequence: - // write(tmp) - // fsync(tmp) - // rename(tmp, new) - // fsync(new) - // fsync(parent) - // For more context about durable_rename check this email from postgres mailing list: - // https://www.postgresql.org/message-id/56583BDD.9060302@2ndquadrant.com - // If pageserver crashes the temp file will be deleted on startup and re-downloaded. - let temp_file_path = - path_with_suffix_extension(&layer_destination_path, TEMP_FILE_SUFFIX); + .map(|(layer_destination_path, metadata)| async move { - let mut destination_file = - fs::File::create(&temp_file_path).await.with_context(|| { - format!( - "Failed to create a destination file for layer '{}'", - temp_file_path.display() - ) - })?; + match layer_destination_path.metadata() { + Ok(m) if m.is_file() => { + // the file exists from earlier round when we failed after renaming it as + // layer_destination_path + let verified = if let Some(expected) = metadata.file_size() { + m.len() == expected + } else { + // behaviour before recording metadata was to accept any existing + true + }; - let mut layer_download = storage.download_storage_object(None, &layer_destination_path) - .await - .with_context(|| { - format!( - "Failed to initiate the download the layer for {sync_id} into file '{}'", - temp_file_path.display() - ) - })?; - io::copy(&mut layer_download.download_stream, &mut destination_file) - .await - .with_context(|| { - format!( - "Failed to download the layer for {sync_id} into file '{}'", - temp_file_path.display() - ) - })?; - - // Tokio doc here: https://docs.rs/tokio/1.17.0/tokio/fs/struct.File.html states that: - // A file will not be closed immediately when it goes out of scope if there are any IO operations - // that have not yet completed. To ensure that a file is closed immediately when it is dropped, - // you should call flush before dropping it. - // - // From the tokio code I see that it waits for pending operations to complete. There shouldn't be any because - // we assume that `destination_file` file is fully written. I.e there is no pending .write(...).await operations. - // But for additional safety let's check/wait for any pending operations. - destination_file.flush().await.with_context(|| { - format!( - "failed to flush source file at {}", - temp_file_path.display() - ) - })?; - - // not using sync_data because it can lose file size update - destination_file.sync_all().await.with_context(|| { - format!( - "failed to fsync source file at {}", - temp_file_path.display() - ) - })?; - drop(destination_file); - - fail::fail_point!("remote-storage-download-pre-rename", |_| { - anyhow::bail!("remote-storage-download-pre-rename failpoint triggered") - }); - - fs::rename(&temp_file_path, &layer_destination_path).await?; - - fsync_path(&layer_destination_path).await.with_context(|| { - format!( - "Cannot fsync layer destination path {}", - layer_destination_path.display(), - ) - })?; + if verified { + debug!( + "Layer already exists locally, skipping download: {}", + layer_destination_path.display() + ); + return Ok((layer_destination_path, LayerFileMetadata::new(m.len()))) + } else { + // no need to remove it, it will be overwritten by fs::rename + // after successful download + warn!("Downloaded layer exists already but layer file metadata mismatches: {}, metadata {:?}", layer_destination_path.display(), metadata); + } + } + Ok(m) => { + return Err(anyhow::anyhow!("Downloaded layer destination exists but is not a file: {m:?}, target needs to be removed/archived manually: {layer_destination_path:?}")); + } + Err(_) => { + // behave as the file didn't exist + } } - Ok::<_, anyhow::Error>(layer_destination_path) + + // Perform a rename inspired by durable_rename from file_utils.c. + // The sequence: + // write(tmp) + // fsync(tmp) + // rename(tmp, new) + // fsync(new) + // fsync(parent) + // For more context about durable_rename check this email from postgres mailing list: + // https://www.postgresql.org/message-id/56583BDD.9060302@2ndquadrant.com + // If pageserver crashes the temp file will be deleted on startup and re-downloaded. + let temp_file_path = + path_with_suffix_extension(&layer_destination_path, TEMP_FILE_SUFFIX); + + // TODO: this doesn't use the cached fd for some reason? + let mut destination_file = + fs::File::create(&temp_file_path).await.with_context(|| { + format!( + "Failed to create a destination file for layer '{}'", + temp_file_path.display() + ) + })?; + + let mut layer_download = storage.download_storage_object(None, &layer_destination_path) + .await + .with_context(|| { + format!( + "Failed to initiate the download the layer for {sync_id} into file '{}'", + temp_file_path.display() + ) + })?; + + let bytes_amount = io::copy(&mut layer_download.download_stream, &mut destination_file) + .await + .with_context(|| { + format!( + "Failed to download the layer for {sync_id} into file '{}'", + temp_file_path.display() + ) + })?; + + // Tokio doc here: https://docs.rs/tokio/1.17.0/tokio/fs/struct.File.html states that: + // A file will not be closed immediately when it goes out of scope if there are any IO operations + // that have not yet completed. To ensure that a file is closed immediately when it is dropped, + // you should call flush before dropping it. + // + // From the tokio code I see that it waits for pending operations to complete. There shouldn't be any because + // we assume that `destination_file` file is fully written. I.e there is no pending .write(...).await operations. + // But for additional safety let's check/wait for any pending operations. + destination_file.flush().await.with_context(|| { + format!( + "failed to flush source file at {}", + temp_file_path.display() + ) + })?; + + match metadata.file_size() { + Some(expected) if expected != bytes_amount => { + anyhow::bail!( + "According to layer file metadata should had downloaded {expected} bytes but downloaded {bytes_amount} bytes into file '{}'", + temp_file_path.display() + ); + }, + Some(_) | None => { + // matches, or upgrading from an earlier IndexPart version + } + } + + // not using sync_data because it can lose file size update + destination_file.sync_all().await.with_context(|| { + format!( + "failed to fsync source file at {}", + temp_file_path.display() + ) + })?; + drop(destination_file); + + fail::fail_point!("remote-storage-download-pre-rename", |_| { + anyhow::bail!("remote-storage-download-pre-rename failpoint triggered") + }); + + fs::rename(&temp_file_path, &layer_destination_path).await?; + + fsync_path(&layer_destination_path).await.with_context(|| { + format!( + "Cannot fsync layer destination path {}", + layer_destination_path.display(), + ) + })?; + + Ok::<_, anyhow::Error>((layer_destination_path, LayerFileMetadata::new(bytes_amount))) }) .collect::>(); @@ -324,9 +374,12 @@ pub(super) async fn download_timeline_layers<'a>( let mut undo = HashSet::new(); while let Some(download_result) = download_tasks.next().await { match download_result { - Ok(downloaded_path) => { + Ok((downloaded_path, metadata)) => { undo.insert(downloaded_path.clone()); - download.layers_to_skip.insert(downloaded_path); + download.layers_to_skip.insert(downloaded_path.clone()); + // what if the key existed already? ignore, because then we would had + // downloaded a partial file, and had to retry + download.gathered_metadata.insert(downloaded_path, metadata); } Err(e) => { errors_happened = true; @@ -349,6 +402,8 @@ pub(super) async fn download_timeline_layers<'a>( ); for item in undo { download.layers_to_skip.remove(&item); + // intentionally don't clear the gathered_metadata because it exists for fsync_path + // failure on parent directory } errors_happened = true; } @@ -453,9 +508,9 @@ mod tests { let timeline_upload = create_local_timeline(&harness, TIMELINE_ID, &layer_files, metadata.clone()).await?; - for local_path in timeline_upload.layers_to_upload { + for local_path in timeline_upload.layers_to_upload.keys() { let remote_path = - local_storage.resolve_in_storage(&storage.remote_object_id(&local_path)?)?; + local_storage.resolve_in_storage(&storage.remote_object_id(local_path)?)?; let remote_parent_dir = remote_path.parent().unwrap(); if !remote_parent_dir.exists() { fs::create_dir_all(&remote_parent_dir).await?; @@ -473,11 +528,19 @@ mod tests { let mut remote_timeline = RemoteTimeline::new(metadata.clone()); remote_timeline.awaits_download = true; - remote_timeline.add_timeline_layers( - layer_files - .iter() - .map(|layer| local_timeline_path.join(layer)), - ); + remote_timeline.add_timeline_layers(layer_files.iter().map(|layer| { + let layer_path = local_timeline_path.join(layer); + + // this could had also been LayerFileMetadata::default(), but since in this test we + // don't do the merge operation done by storage_sync::download_timeline_data, it would + // not be merged back to timeline. + let metadata_from_upload = timeline_upload + .layers_to_upload + .get(&layer_path) + .expect("layer must exist in previously uploaded paths") + .to_owned(); + (layer_path, metadata_from_upload) + })); let download_data = match download_timeline_layers( harness.conf, @@ -487,9 +550,9 @@ mod tests { sync_id, SyncData::new( current_retries, - LayersDownload { - layers_to_skip: HashSet::from([local_timeline_path.join("layer_to_skip")]), - }, + LayersDownload::from_skipped_layers(HashSet::from([ + local_timeline_path.join("layer_to_skip") + ])), ), ) .await @@ -552,12 +615,7 @@ mod tests { &sync_queue, None, sync_id, - SyncData::new( - 0, - LayersDownload { - layers_to_skip: HashSet::new(), - }, - ), + SyncData::new(0, LayersDownload::from_skipped_layers(HashSet::new())), ) .await; assert!( @@ -576,12 +634,7 @@ mod tests { &sync_queue, Some(¬_expecting_download_remote_timeline), sync_id, - SyncData::new( - 0, - LayersDownload { - layers_to_skip: HashSet::new(), - }, - ), + SyncData::new(0, LayersDownload::from_skipped_layers(HashSet::new())), ) .await; assert!( diff --git a/pageserver/src/storage_sync/index.rs b/pageserver/src/storage_sync/index.rs index db37c7b411..0779d95e8e 100644 --- a/pageserver/src/storage_sync/index.rs +++ b/pageserver/src/storage_sync/index.rs @@ -212,8 +212,8 @@ impl RemoteTimelineIndex { /// Restored index part data about the timeline, stored in the remote index. #[derive(Debug, Clone)] pub struct RemoteTimeline { - timeline_layers: HashSet, - missing_layers: HashSet, + timeline_layers: HashMap, + missing_layers: HashMap, pub metadata: TimelineMetadata, pub awaits_download: bool, @@ -222,62 +222,161 @@ pub struct RemoteTimeline { impl RemoteTimeline { pub fn new(metadata: TimelineMetadata) -> Self { Self { - timeline_layers: HashSet::new(), - missing_layers: HashSet::new(), + timeline_layers: HashMap::default(), + missing_layers: HashMap::default(), metadata, awaits_download: false, } } - pub fn add_timeline_layers(&mut self, new_layers: impl IntoIterator) { - self.timeline_layers.extend(new_layers.into_iter()); + pub fn add_timeline_layers( + &mut self, + new_layers: impl IntoIterator, + ) { + self.timeline_layers.extend(new_layers); } - pub fn add_upload_failures(&mut self, upload_failures: impl IntoIterator) { - self.missing_layers.extend(upload_failures.into_iter()); + pub fn add_upload_failures( + &mut self, + upload_failures: impl IntoIterator, + ) { + self.missing_layers.extend(upload_failures); } pub fn remove_layers(&mut self, layers_to_remove: &HashSet) { self.timeline_layers - .retain(|layer| !layers_to_remove.contains(layer)); + .retain(|layer, _| !layers_to_remove.contains(layer)); self.missing_layers - .retain(|layer| !layers_to_remove.contains(layer)); + .retain(|layer, _| !layers_to_remove.contains(layer)); } /// Lists all layer files in the given remote timeline. Omits the metadata file. - pub fn stored_files(&self) -> &HashSet { + pub fn stored_files(&self) -> &HashMap { &self.timeline_layers } + /// Combines metadata gathered or verified during downloading needed layer files to metadata on + /// the [`RemoteIndex`], so it can be uploaded later. + pub fn merge_metadata_from_downloaded( + &mut self, + downloaded: &HashMap, + ) { + downloaded.iter().for_each(|(path, metadata)| { + if let Some(upgraded) = self.timeline_layers.get_mut(path) { + upgraded.merge(metadata); + } + }); + } + pub fn from_index_part(timeline_path: &Path, index_part: IndexPart) -> anyhow::Result { let metadata = TimelineMetadata::from_bytes(&index_part.metadata_bytes)?; + let default_metadata = &IndexLayerMetadata::default(); + + let find_metadata = |key: &RelativePath| -> LayerFileMetadata { + index_part + .layer_metadata + .get(key) + .unwrap_or(default_metadata) + .into() + }; + Ok(Self { - timeline_layers: to_local_paths(timeline_path, index_part.timeline_layers), - missing_layers: to_local_paths(timeline_path, index_part.missing_layers), + timeline_layers: index_part + .timeline_layers + .iter() + .map(|layer_path| (layer_path.as_path(timeline_path), find_metadata(layer_path))) + .collect(), + missing_layers: index_part + .missing_layers + .iter() + .map(|layer_path| (layer_path.as_path(timeline_path), find_metadata(layer_path))) + .collect(), metadata, awaits_download: false, }) } } +/// Metadata gathered for each of the layer files. +/// +/// Fields have to be `Option`s because remote [`IndexPart`]'s can be from different version, which +/// might have less or more metadata depending if upgrading or rolling back an upgrade. +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(test, derive(Default))] +pub struct LayerFileMetadata { + file_size: Option, +} + +impl From<&'_ IndexLayerMetadata> for LayerFileMetadata { + fn from(other: &IndexLayerMetadata) -> Self { + LayerFileMetadata { + file_size: other.file_size, + } + } +} + +impl LayerFileMetadata { + pub fn new(file_size: u64) -> Self { + LayerFileMetadata { + file_size: Some(file_size), + } + } + + pub fn file_size(&self) -> Option { + self.file_size + } + + /// Metadata has holes due to version upgrades. This method is called to upgrade self with the + /// other value. + /// + /// This is called on the possibly outdated version. + pub fn merge(&mut self, other: &Self) { + self.file_size = other.file_size.or(self.file_size); + } +} + /// Part of the remote index, corresponding to a certain timeline. /// Contains the data about all files in the timeline, present remotely and its metadata. +/// +/// This type needs to be backwards and forwards compatible. When changing the fields, +/// remember to add a test case for the changed version. #[serde_as] #[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)] pub struct IndexPart { + /// Debugging aid describing the version of this type. + #[serde(default)] + version: usize, + + /// Each of the layers present on remote storage. + /// + /// Additional metadata can might exist in `layer_metadata`. timeline_layers: HashSet, + /// Currently is not really used in pageserver, /// present to manually keep track of the layer files that pageserver might never retrieve. /// /// Such "holes" might appear if any upload task was evicted on an error threshold: /// the this layer will only be rescheduled for upload on pageserver restart. missing_layers: HashSet, + + /// Per layer file metadata, which can be present for a present or missing layer file. + /// + /// Older versions of `IndexPart` will not have this property or have only a part of metadata + /// that latest version stores. + #[serde(default)] + layer_metadata: HashMap, + #[serde_as(as = "DisplayFromStr")] disk_consistent_lsn: Lsn, metadata_bytes: Vec, } impl IndexPart { + /// When adding or modifying any parts of `IndexPart`, increment the version so that it can be + /// used to understand later versions. + /// + /// Version is currently informative only. + const LATEST_VERSION: usize = 1; pub const FILE_NAME: &'static str = "index_part.json"; #[cfg(test)] @@ -288,8 +387,10 @@ impl IndexPart { metadata_bytes: Vec, ) -> Self { Self { + version: Self::LATEST_VERSION, timeline_layers, missing_layers, + layer_metadata: HashMap::default(), disk_consistent_lsn, metadata_bytes, } @@ -304,35 +405,68 @@ impl IndexPart { remote_timeline: RemoteTimeline, ) -> anyhow::Result { let metadata_bytes = remote_timeline.metadata.to_bytes()?; + + let mut layer_metadata = HashMap::new(); + + let mut missing_layers = HashSet::new(); + + separate_paths_and_metadata( + timeline_path, + &remote_timeline.missing_layers, + &mut missing_layers, + &mut layer_metadata, + ) + .context("Failed to convert missing layers' paths to relative ones")?; + + let mut timeline_layers = HashSet::new(); + + separate_paths_and_metadata( + timeline_path, + &remote_timeline.timeline_layers, + &mut timeline_layers, + &mut layer_metadata, + ) + .context("Failed to convert timeline layers' paths to relative ones")?; + Ok(Self { - timeline_layers: to_relative_paths(timeline_path, remote_timeline.timeline_layers) - .context("Failed to convert timeline layers' paths to relative ones")?, - missing_layers: to_relative_paths(timeline_path, remote_timeline.missing_layers) - .context("Failed to convert missing layers' paths to relative ones")?, + version: Self::LATEST_VERSION, + timeline_layers, + missing_layers, + layer_metadata, disk_consistent_lsn: remote_timeline.metadata.disk_consistent_lsn(), metadata_bytes, }) } } -fn to_local_paths( - timeline_path: &Path, - paths: impl IntoIterator, -) -> HashSet { - paths - .into_iter() - .map(|path| path.as_path(timeline_path)) - .collect() +/// Serialized form of [`LayerFileMetadata`]. +#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize, Default)] +pub struct IndexLayerMetadata { + file_size: Option, } -fn to_relative_paths( +impl From<&'_ LayerFileMetadata> for IndexLayerMetadata { + fn from(other: &'_ LayerFileMetadata) -> Self { + IndexLayerMetadata { + file_size: other.file_size, + } + } +} + +fn separate_paths_and_metadata( timeline_path: &Path, - paths: impl IntoIterator, -) -> anyhow::Result> { - paths - .into_iter() - .map(|path| RelativePath::new(timeline_path, path)) - .collect() + input: &HashMap, + output: &mut HashSet, + layer_metadata: &mut HashMap, +) -> anyhow::Result<()> { + for (path, metadata) in input { + let rel_path = RelativePath::new(timeline_path, path)?; + let metadata = IndexLayerMetadata::from(metadata); + + layer_metadata.insert(rel_path.clone(), metadata); + output.insert(rel_path); + } + Ok(()) } #[cfg(test)] @@ -357,13 +491,13 @@ mod tests { DEFAULT_PG_VERSION, ); let remote_timeline = RemoteTimeline { - timeline_layers: HashSet::from([ - timeline_path.join("layer_1"), - timeline_path.join("layer_2"), + timeline_layers: HashMap::from([ + (timeline_path.join("layer_1"), LayerFileMetadata::new(1)), + (timeline_path.join("layer_2"), LayerFileMetadata::new(2)), ]), - missing_layers: HashSet::from([ - timeline_path.join("missing_1"), - timeline_path.join("missing_2"), + missing_layers: HashMap::from([ + (timeline_path.join("missing_1"), LayerFileMetadata::new(3)), + (timeline_path.join("missing_2"), LayerFileMetadata::new(4)), ]), metadata: metadata.clone(), awaits_download: false, @@ -485,13 +619,13 @@ mod tests { let conversion_result = IndexPart::from_remote_timeline( &timeline_path, RemoteTimeline { - timeline_layers: HashSet::from([ - PathBuf::from("bad_path"), - timeline_path.join("layer_2"), + timeline_layers: HashMap::from([ + (PathBuf::from("bad_path"), LayerFileMetadata::new(1)), + (timeline_path.join("layer_2"), LayerFileMetadata::new(2)), ]), - missing_layers: HashSet::from([ - timeline_path.join("missing_1"), - timeline_path.join("missing_2"), + missing_layers: HashMap::from([ + (timeline_path.join("missing_1"), LayerFileMetadata::new(3)), + (timeline_path.join("missing_2"), LayerFileMetadata::new(4)), ]), metadata: metadata.clone(), awaits_download: false, @@ -502,13 +636,13 @@ mod tests { let conversion_result = IndexPart::from_remote_timeline( &timeline_path, RemoteTimeline { - timeline_layers: HashSet::from([ - timeline_path.join("layer_1"), - timeline_path.join("layer_2"), + timeline_layers: HashMap::from([ + (timeline_path.join("layer_1"), LayerFileMetadata::new(1)), + (timeline_path.join("layer_2"), LayerFileMetadata::new(2)), ]), - missing_layers: HashSet::from([ - PathBuf::from("bad_path"), - timeline_path.join("missing_2"), + missing_layers: HashMap::from([ + (PathBuf::from("bad_path"), LayerFileMetadata::new(3)), + (timeline_path.join("missing_2"), LayerFileMetadata::new(4)), ]), metadata, awaits_download: false, @@ -516,4 +650,63 @@ mod tests { ); assert!(conversion_result.is_err(), "Should not be able to convert metadata with missing layer paths that are not in the timeline directory"); } + + #[test] + fn v0_indexpart_is_parsed() { + let example = r#"{ + "timeline_layers":["000000000000000000000000000000000000-FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF__0000000001696070-00000000016960E9"], + "missing_layers":["not_a_real_layer_but_adding_coverage"], + "disk_consistent_lsn":"0/16960E8", + "metadata_bytes":[113,11,159,210,0,54,0,4,0,0,0,0,1,105,96,232,1,0,0,0,0,1,105,96,112,0,0,0,0,0,0,0,0,0,0,0,0,0,1,105,96,112,0,0,0,0,1,105,96,112,0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] + }"#; + + let expected = IndexPart { + version: 0, + timeline_layers: [RelativePath("000000000000000000000000000000000000-FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF__0000000001696070-00000000016960E9".to_owned())].into_iter().collect(), + missing_layers: [RelativePath("not_a_real_layer_but_adding_coverage".to_owned())].into_iter().collect(), + layer_metadata: HashMap::default(), + disk_consistent_lsn: "0/16960E8".parse::().unwrap(), + metadata_bytes: [113,11,159,210,0,54,0,4,0,0,0,0,1,105,96,232,1,0,0,0,0,1,105,96,112,0,0,0,0,0,0,0,0,0,0,0,0,0,1,105,96,112,0,0,0,0,1,105,96,112,0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0].to_vec(), + }; + + let part = serde_json::from_str::(example).unwrap(); + assert_eq!(part, expected); + } + + #[test] + fn v1_indexpart_is_parsed() { + let example = r#"{ + "version":1, + "timeline_layers":["000000000000000000000000000000000000-FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF__0000000001696070-00000000016960E9"], + "missing_layers":["not_a_real_layer_but_adding_coverage"], + "layer_metadata":{ + "000000000000000000000000000000000000-FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF__0000000001696070-00000000016960E9": { "file_size": 25600000 }, + "not_a_real_layer_but_adding_coverage": { "file_size": 9007199254741001 } + }, + "disk_consistent_lsn":"0/16960E8", + "metadata_bytes":[113,11,159,210,0,54,0,4,0,0,0,0,1,105,96,232,1,0,0,0,0,1,105,96,112,0,0,0,0,0,0,0,0,0,0,0,0,0,1,105,96,112,0,0,0,0,1,105,96,112,0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] + }"#; + + let expected = IndexPart { + // note this is not verified, could be anything, but exists for humans debugging.. could be the git version instead? + version: 1, + timeline_layers: [RelativePath("000000000000000000000000000000000000-FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF__0000000001696070-00000000016960E9".to_owned())].into_iter().collect(), + missing_layers: [RelativePath("not_a_real_layer_but_adding_coverage".to_owned())].into_iter().collect(), + layer_metadata: HashMap::from([ + (RelativePath("000000000000000000000000000000000000-FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF__0000000001696070-00000000016960E9".to_owned()), IndexLayerMetadata { + file_size: Some(25600000), + }), + (RelativePath("not_a_real_layer_but_adding_coverage".to_owned()), IndexLayerMetadata { + // serde_json should always parse this but this might be a double with jq for + // example. + file_size: Some(9007199254741001), + }) + ]), + disk_consistent_lsn: "0/16960E8".parse::().unwrap(), + metadata_bytes: [113,11,159,210,0,54,0,4,0,0,0,0,1,105,96,232,1,0,0,0,0,1,105,96,112,0,0,0,0,0,0,0,0,0,0,0,0,0,1,105,96,112,0,0,0,0,1,105,96,112,0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0].to_vec(), + }; + + let part = serde_json::from_str::(example).unwrap(); + assert_eq!(part, expected); + } } diff --git a/pageserver/src/storage_sync/upload.rs b/pageserver/src/storage_sync/upload.rs index 75657915c0..f91105052b 100644 --- a/pageserver/src/storage_sync/upload.rs +++ b/pageserver/src/storage_sync/upload.rs @@ -69,14 +69,25 @@ pub(super) async fn upload_timeline_layers<'a>( .map(|meta| meta.disk_consistent_lsn()); let already_uploaded_layers = remote_timeline - .map(|timeline| timeline.stored_files()) - .cloned() + .map(|timeline| { + timeline + .stored_files() + .keys() + .cloned() + .collect::>() + }) .unwrap_or_default(); let layers_to_upload = upload .layers_to_upload - .difference(&already_uploaded_layers) - .cloned() + .iter() + .filter_map(|(k, v)| { + if !already_uploaded_layers.contains(k) { + Some((k.to_owned(), v.to_owned())) + } else { + None + } + }) .collect::>(); if layers_to_upload.is_empty() { @@ -98,7 +109,7 @@ pub(super) async fn upload_timeline_layers<'a>( let mut upload_tasks = layers_to_upload .into_iter() - .map(|source_path| async move { + .map(|(source_path, known_metadata)| async move { let source_file = match fs::File::open(&source_path).await.with_context(|| { format!( "Failed to upen a source file for layer '{}'", @@ -109,7 +120,7 @@ pub(super) async fn upload_timeline_layers<'a>( Err(e) => return Err(UploadError::MissingLocalFile(source_path, e)), }; - let source_size = source_file + let fs_size = source_file .metadata() .await .with_context(|| { @@ -119,10 +130,24 @@ pub(super) async fn upload_timeline_layers<'a>( ) }) .map_err(UploadError::Other)? - .len() as usize; + .len(); + + // FIXME: this looks bad + if let Some(metadata_size) = known_metadata.file_size() { + if metadata_size != fs_size { + return Err(UploadError::Other(anyhow::anyhow!( + "File {source_path:?} has its current FS size {fs_size} diferent from initially determined {metadata_size}" + ))); + } + } else { + // this is a silly state we would like to avoid + } + + let fs_size = usize::try_from(fs_size).with_context(|| format!("File {source_path:?} size {fs_size} could not be converted to usize")) + .map_err(UploadError::Other)?; match storage - .upload_storage_object(Box::new(source_file), source_size, &source_path) + .upload_storage_object(Box::new(source_file), fs_size, &source_path) .await .with_context(|| format!("Failed to upload layer file for {sync_id}")) { @@ -136,8 +161,11 @@ pub(super) async fn upload_timeline_layers<'a>( while let Some(upload_result) = upload_tasks.next().await { match upload_result { Ok(uploaded_path) => { - upload.layers_to_upload.remove(&uploaded_path); - upload.uploaded_layers.insert(uploaded_path); + let metadata = upload + .layers_to_upload + .remove(&uploaded_path) + .expect("metadata should always exist, assuming no double uploads"); + upload.uploaded_layers.insert(uploaded_path, metadata); } Err(e) => match e { UploadError::Other(e) => { @@ -262,7 +290,7 @@ mod tests { assert_eq!( upload .uploaded_layers - .iter() + .keys() .cloned() .collect::>(), layer_files @@ -357,7 +385,7 @@ mod tests { assert_eq!( upload .uploaded_layers - .iter() + .keys() .cloned() .collect::>(), layer_files diff --git a/pageserver/src/tenant.rs b/pageserver/src/tenant.rs index c2fb9ef242..69c89a80b4 100644 --- a/pageserver/src/tenant.rs +++ b/pageserver/src/tenant.rs @@ -11,10 +11,10 @@ //! parent timeline, and the last LSN that has been written to disk. //! -use anyhow::{bail, ensure, Context, Result}; +use anyhow::{bail, ensure, Context}; use tokio::sync::watch; use tracing::*; -use utils::crashsafe_dir::path_with_suffix_extension; +use utils::crashsafe::path_with_suffix_extension; use std::cmp::min; use std::collections::hash_map::Entry; @@ -23,10 +23,11 @@ use std::collections::HashMap; use std::fs; use std::fs::File; use std::fs::OpenOptions; +use std::io; use std::io::Write; -use std::num::NonZeroU64; use std::ops::Bound::Included; use std::path::Path; +use std::path::PathBuf; use std::process::Command; use std::process::Stdio; use std::sync::Arc; @@ -49,7 +50,7 @@ pub use pageserver_api::models::TenantState; use toml_edit; use utils::{ - crashsafe_dir, + crashsafe, id::{TenantId, TimelineId}, lsn::{Lsn, RecordLsn}, }; @@ -59,13 +60,14 @@ pub mod block_io; mod delta_layer; mod disk_btree; pub(crate) mod ephemeral_file; -mod filename; +pub mod filename; mod image_layer; mod inmemory_layer; -mod layer_map; +pub mod layer_map; + pub mod metadata; mod par_fsync; -mod storage_layer; +pub mod storage_layer; mod timeline; @@ -119,6 +121,214 @@ pub struct Tenant { upload_layers: bool, } +/// A timeline with some of its files on disk, being initialized. +/// This struct ensures the atomicity of the timeline init: it's either properly created and inserted into pageserver's memory, or +/// its local files are removed. In the worst case of a crash, an uninit mark file is left behind, which causes the directory +/// to be removed on next restart. +/// +/// The caller is responsible for proper timeline data filling before the final init. +#[must_use] +pub struct UninitializedTimeline<'t> { + owning_tenant: &'t Tenant, + timeline_id: TimelineId, + raw_timeline: Option<(Timeline, TimelineUninitMark)>, +} + +/// An uninit mark file, created along the timeline dir to ensure the timeline either gets fully initialized and loaded into pageserver's memory, +/// or gets removed eventually. +/// +/// XXX: it's important to create it near the timeline dir, not inside it to ensure timeline dir gets removed first. +#[must_use] +struct TimelineUninitMark { + uninit_mark_deleted: bool, + uninit_mark_path: PathBuf, + timeline_path: PathBuf, +} + +impl UninitializedTimeline<'_> { + /// Ensures timeline data is valid, loads it into pageserver's memory and removes uninit mark file on success. + pub fn initialize(self) -> anyhow::Result> { + let mut timelines = self.owning_tenant.timelines.lock().unwrap(); + self.initialize_with_lock(&mut timelines, true) + } + + fn initialize_with_lock( + mut self, + timelines: &mut HashMap>, + load_layer_map: bool, + ) -> anyhow::Result> { + let timeline_id = self.timeline_id; + let tenant_id = self.owning_tenant.tenant_id; + + let (new_timeline, uninit_mark) = self.raw_timeline.take().with_context(|| { + format!("No timeline for initalization found for {tenant_id}/{timeline_id}") + })?; + let new_timeline = Arc::new(new_timeline); + + let new_disk_consistent_lsn = new_timeline.get_disk_consistent_lsn(); + // TODO it would be good to ensure that, but apparently a lot of our testing is dependend on that at least + // ensure!(new_disk_consistent_lsn.is_valid(), + // "Timeline {tenant_id}/{timeline_id} has invalid disk_consistent_lsn and cannot be initialized"); + + match timelines.entry(timeline_id) { + Entry::Occupied(_) => anyhow::bail!( + "Found freshly initialized timeline {tenant_id}/{timeline_id} in the tenant map" + ), + Entry::Vacant(v) => { + if load_layer_map { + new_timeline + .load_layer_map(new_disk_consistent_lsn) + .with_context(|| { + format!( + "Failed to load layermap for timeline {tenant_id}/{timeline_id}" + ) + })?; + } + uninit_mark.remove_uninit_mark().with_context(|| { + format!( + "Failed to remove uninit mark file for timeline {tenant_id}/{timeline_id}" + ) + })?; + v.insert(Arc::clone(&new_timeline)); + new_timeline.launch_wal_receiver(); + } + } + + Ok(new_timeline) + } + + /// Prepares timeline data by loading it from the basebackup archive. + pub fn import_basebackup_from_tar( + &self, + reader: impl std::io::Read, + base_lsn: Lsn, + ) -> anyhow::Result<()> { + let raw_timeline = self.raw_timeline()?; + import_datadir::import_basebackup_from_tar(raw_timeline, reader, base_lsn).with_context( + || { + format!( + "Failed to import basebackup for timeline {}/{}", + self.owning_tenant.tenant_id, self.timeline_id + ) + }, + )?; + + fail::fail_point!("before-checkpoint-new-timeline", |_| { + bail!("failpoint before-checkpoint-new-timeline"); + }); + + raw_timeline + .checkpoint(CheckpointConfig::Flush) + .with_context(|| { + format!( + "Failed to checkpoint after basebackup import for timeline {}/{}", + self.owning_tenant.tenant_id, self.timeline_id + ) + })?; + Ok(()) + } + + fn raw_timeline(&self) -> anyhow::Result<&Timeline> { + Ok(&self + .raw_timeline + .as_ref() + .with_context(|| { + format!( + "No raw timeline {}/{} found", + self.owning_tenant.tenant_id, self.timeline_id + ) + })? + .0) + } +} + +impl Drop for UninitializedTimeline<'_> { + fn drop(&mut self) { + if let Some((_, uninit_mark)) = self.raw_timeline.take() { + let _entered = info_span!("drop_uninitialized_timeline", tenant = %self.owning_tenant.tenant_id, timeline = %self.timeline_id).entered(); + error!("Timeline got dropped without initializing, cleaning its files"); + cleanup_timeline_directory(uninit_mark); + } + } +} + +fn cleanup_timeline_directory(uninit_mark: TimelineUninitMark) { + let timeline_path = &uninit_mark.timeline_path; + match ignore_absent_files(|| fs::remove_dir_all(timeline_path)) { + Ok(()) => { + info!("Timeline dir {timeline_path:?} removed successfully, removing the uninit mark") + } + Err(e) => { + error!("Failed to clean up uninitialized timeline directory {timeline_path:?}: {e:?}") + } + } + drop(uninit_mark); // mark handles its deletion on drop, gets retained if timeline dir exists +} + +impl TimelineUninitMark { + /// Useful for initializing timelines, existing on disk after the restart. + pub fn dummy() -> Self { + Self { + uninit_mark_deleted: true, + uninit_mark_path: PathBuf::new(), + timeline_path: PathBuf::new(), + } + } + + fn new(uninit_mark_path: PathBuf, timeline_path: PathBuf) -> Self { + Self { + uninit_mark_deleted: false, + uninit_mark_path, + timeline_path, + } + } + + fn remove_uninit_mark(mut self) -> anyhow::Result<()> { + if !self.uninit_mark_deleted { + self.delete_mark_file_if_present()?; + } + + Ok(()) + } + + fn delete_mark_file_if_present(&mut self) -> anyhow::Result<()> { + let uninit_mark_file = &self.uninit_mark_path; + let uninit_mark_parent = uninit_mark_file + .parent() + .with_context(|| format!("Uninit mark file {uninit_mark_file:?} has no parent"))?; + ignore_absent_files(|| fs::remove_file(&uninit_mark_file)).with_context(|| { + format!("Failed to remove uninit mark file at path {uninit_mark_file:?}") + })?; + crashsafe::fsync(uninit_mark_parent).context("Failed to fsync uninit mark parent")?; + self.uninit_mark_deleted = true; + + Ok(()) + } +} + +impl Drop for TimelineUninitMark { + fn drop(&mut self) { + if !self.uninit_mark_deleted { + if self.timeline_path.exists() { + error!( + "Uninit mark {} is not removed, timeline {} stays uninitialized", + self.uninit_mark_path.display(), + self.timeline_path.display() + ) + } else { + // unblock later timeline creation attempts + warn!( + "Removing intermediate uninit mark file {}", + self.uninit_mark_path.display() + ); + if let Err(e) = self.delete_mark_file_if_present() { + error!("Failed to remove the uninit mark file: {e}") + } + } + } + } +} + /// A repository corresponds to one .neon directory. One repository holds multiple /// timelines, forked off from the same initial call to 'initdb'. impl Tenant { @@ -144,35 +354,27 @@ impl Tenant { /// Lists timelines the tenant contains. /// Up to tenant's implementation to omit certain timelines that ar not considered ready for use. - pub fn list_timelines(&self) -> Vec<(TimelineId, Arc)> { + pub fn list_timelines(&self) -> Vec> { self.timelines .lock() .unwrap() - .iter() - .map(|(timeline_id, timeline_entry)| (*timeline_id, Arc::clone(timeline_entry))) + .values() + .map(Arc::clone) .collect() } - /// Create a new, empty timeline. The caller is responsible for loading data into it - /// Initdb lsn is provided for timeline impl to be able to perform checks for some operations against it. + /// This is used to create the initial 'main' timeline during bootstrapping, + /// or when importing a new base backup. The caller is expected to load an + /// initial image of the datadir to the new timeline after this. pub fn create_empty_timeline( &self, new_timeline_id: TimelineId, initdb_lsn: Lsn, pg_version: u32, - ) -> Result> { - // XXX: keep the lock to avoid races during timeline creation - let mut timelines = self.timelines.lock().unwrap(); - - anyhow::ensure!( - timelines.get(&new_timeline_id).is_none(), - "Timeline {new_timeline_id} already exists" - ); - - let timeline_path = self.conf.timeline_path(&new_timeline_id, &self.tenant_id); - if timeline_path.exists() { - bail!("Timeline directory already exists, but timeline is missing in repository map. This is a bug.") - } + ) -> anyhow::Result { + let timelines = self.timelines.lock().unwrap(); + let timeline_uninit_mark = self.create_timeline_uninit_mark(new_timeline_id, &timelines)?; + drop(timelines); let new_metadata = TimelineMetadata::new( Lsn(0), @@ -183,11 +385,13 @@ impl Tenant { initdb_lsn, pg_version, ); - let new_timeline = - self.create_initialized_timeline(new_timeline_id, new_metadata, &mut timelines)?; - new_timeline.layers.write().unwrap().next_open_layer_at = Some(initdb_lsn); - - Ok(new_timeline) + self.prepare_timeline( + new_timeline_id, + new_metadata, + timeline_uninit_mark, + true, + None, + ) } /// Create a new timeline. @@ -203,14 +407,10 @@ impl Tenant { ancestor_timeline_id: Option, mut ancestor_start_lsn: Option, pg_version: u32, - ) -> Result>> { + ) -> anyhow::Result>> { let new_timeline_id = new_timeline_id.unwrap_or_else(TimelineId::generate); - if self - .conf - .timeline_path(&new_timeline_id, &self.tenant_id) - .exists() - { + if self.get_timeline(new_timeline_id).is_ok() { debug!("timeline {new_timeline_id} already exists"); return Ok(None); } @@ -269,7 +469,7 @@ impl Tenant { horizon: u64, pitr: Duration, checkpoint_before_gc: bool, - ) -> Result { + ) -> anyhow::Result { let timeline_str = target_timeline_id .map(|x| x.to_string()) .unwrap_or_else(|| "-".to_string()); @@ -285,7 +485,7 @@ impl Tenant { /// This function is periodically called by compactor task. /// Also it can be explicitly requested per timeline through page server /// api's 'compact' command. - pub fn compaction_iteration(&self) -> Result<()> { + pub fn compaction_iteration(&self) -> anyhow::Result<()> { // Scan through the hashmap and collect a list of all the timelines, // while holding the lock. Then drop the lock and actually perform the // compactions. We don't want to block everything else while the @@ -309,7 +509,7 @@ impl Tenant { /// /// Used at graceful shutdown. /// - pub fn checkpoint(&self) -> Result<()> { + pub fn checkpoint(&self) -> anyhow::Result<()> { // Scan through the hashmap and collect a list of all the timelines, // while holding the lock. Then drop the lock and actually perform the // checkpoints. We don't want to block everything else while the @@ -345,7 +545,7 @@ impl Tenant { ensure!( !children_exist, - "Cannot detach timeline which has child timelines" + "Cannot delete timeline which has child timelines" ); let timeline_entry = match timelines.entry(timeline_id) { Entry::Occupied(e) => e, @@ -389,21 +589,32 @@ impl Tenant { timeline_id, metadata.pg_version() ); - let ancestor = metadata - .ancestor_timeline() - .and_then(|ancestor_timeline_id| timelines_accessor.get(&ancestor_timeline_id)) - .cloned(); - match timelines_accessor.entry(timeline_id) { - Entry::Occupied(_) => warn!( + + if timelines_accessor.contains_key(&timeline_id) { + warn!( "Timeline {}/{} already exists in the tenant map, skipping its initialization", self.tenant_id, timeline_id - ), - Entry::Vacant(v) => { - let timeline = self - .initialize_new_timeline(timeline_id, metadata, ancestor) - .with_context(|| format!("Failed to initialize timeline {timeline_id}"))?; - v.insert(timeline); - } + ); + continue; + } else { + let ancestor = metadata + .ancestor_timeline() + .and_then(|ancestor_timeline_id| timelines_accessor.get(&ancestor_timeline_id)) + .cloned(); + let timeline = UninitializedTimeline { + owning_tenant: self, + timeline_id, + raw_timeline: Some(( + self.create_timeline_data(timeline_id, metadata, ancestor) + .with_context(|| { + format!("Failed to initialize timeline {timeline_id}") + })?, + TimelineUninitMark::dummy(), + )), + }; + let initialized_timeline = + timeline.initialize_with_lock(&mut timelines_accessor, true)?; + timelines_accessor.insert(timeline_id, initialized_timeline); } } @@ -469,7 +680,7 @@ impl Tenant { /// before the children. fn tree_sort_timelines( timelines: HashMap, -) -> Result> { +) -> anyhow::Result> { let mut result = Vec::with_capacity(timelines.len()); let mut now = Vec::with_capacity(timelines.len()); @@ -572,37 +783,16 @@ impl Tenant { .unwrap_or(self.conf.default_tenant_conf.pitr_interval) } - pub fn get_wal_receiver_connect_timeout(&self) -> Duration { - let tenant_conf = self.tenant_conf.read().unwrap(); - tenant_conf - .walreceiver_connect_timeout - .unwrap_or(self.conf.default_tenant_conf.walreceiver_connect_timeout) - } - - pub fn get_lagging_wal_timeout(&self) -> Duration { - let tenant_conf = self.tenant_conf.read().unwrap(); - tenant_conf - .lagging_wal_timeout - .unwrap_or(self.conf.default_tenant_conf.lagging_wal_timeout) - } - - pub fn get_max_lsn_wal_lag(&self) -> NonZeroU64 { - let tenant_conf = self.tenant_conf.read().unwrap(); - tenant_conf - .max_lsn_wal_lag - .unwrap_or(self.conf.default_tenant_conf.max_lsn_wal_lag) - } - pub fn update_tenant_config(&self, new_tenant_conf: TenantConfOpt) { self.tenant_conf.write().unwrap().update(&new_tenant_conf); } - fn initialize_new_timeline( + fn create_timeline_data( &self, new_timeline_id: TimelineId, new_metadata: TimelineMetadata, ancestor: Option>, - ) -> anyhow::Result> { + ) -> anyhow::Result { if let Some(ancestor_timeline_id) = new_metadata.ancestor_timeline() { anyhow::ensure!( ancestor.is_some(), @@ -610,9 +800,8 @@ impl Tenant { ) } - let new_disk_consistent_lsn = new_metadata.disk_consistent_lsn(); let pg_version = new_metadata.pg_version(); - let new_timeline = Arc::new(Timeline::new( + Ok(Timeline::new( self.conf, Arc::clone(&self.tenant_conf), new_metadata, @@ -622,18 +811,10 @@ impl Tenant { Arc::clone(&self.walredo_mgr), self.upload_layers, pg_version, - )); - - new_timeline - .load_layer_map(new_disk_consistent_lsn) - .context("failed to load layermap")?; - - new_timeline.launch_wal_receiver()?; - - Ok(new_timeline) + )) } - pub fn new( + pub(super) fn new( conf: &'static PageServerConf, tenant_conf: TenantConfOpt, walredo_mgr: Arc, @@ -656,7 +837,7 @@ impl Tenant { } /// Locate and load config - pub fn load_tenant_config( + pub(super) fn load_tenant_config( conf: &'static PageServerConf, tenant_id: TenantId, ) -> anyhow::Result { @@ -698,7 +879,7 @@ impl Tenant { Ok(tenant_conf) } - pub fn persist_tenant_config( + pub(super) fn persist_tenant_config( target_config_path: &Path, tenant_conf: TenantConfOpt, first_save: bool, @@ -791,7 +972,7 @@ impl Tenant { horizon: u64, pitr: Duration, checkpoint_before_gc: bool, - ) -> Result { + ) -> anyhow::Result { let mut totals: GcResult = Default::default(); let now = Instant::now(); @@ -906,16 +1087,20 @@ impl Tenant { Ok(totals) } + /// Branch an existing timeline fn branch_timeline( &self, src: TimelineId, dst: TimelineId, start_lsn: Option, - ) -> Result> { + ) -> anyhow::Result> { // We need to hold this lock to prevent GC from starting at the same time. GC scans the directory to learn // about timelines, so otherwise a race condition is possible, where we create new timeline and GC // concurrently removes data that is needed by the new timeline. let _gc_cs = self.gc_cs.lock().unwrap(); + let timelines = self.timelines.lock().unwrap(); + let timeline_uninit_mark = self.create_timeline_uninit_mark(dst, &timelines)?; + drop(timelines); // In order for the branch creation task to not wait for GC/compaction, // we need to make sure that the starting LSN of the child branch is not out of scope midway by @@ -926,12 +1111,12 @@ impl Tenant { // Step 2 is to avoid initializing the new branch using data removed by past GC iterations // or in-queue GC iterations. - // XXX: keep the lock to avoid races during timeline creation - let mut timelines = self.timelines.lock().unwrap(); - let src_timeline = timelines - .get(&src) - // message about timeline being remote is one .context up in the stack - .ok_or_else(|| anyhow::anyhow!("unknown timeline id: {src}"))?; + let src_timeline = self.get_timeline(src).with_context(|| { + format!( + "No ancestor {} found for timeline {}/{}", + src, self.tenant_id, dst + ) + })?; let latest_gc_cutoff_lsn = src_timeline.get_latest_gc_cutoff_lsn(); @@ -981,11 +1166,21 @@ impl Tenant { dst_prev, Some(src), start_lsn, - *src_timeline.latest_gc_cutoff_lsn.read(), + *src_timeline.latest_gc_cutoff_lsn.read(), // FIXME: should we hold onto this guard longer? src_timeline.initdb_lsn, src_timeline.pg_version, ); - let new_timeline = self.create_initialized_timeline(dst, metadata, &mut timelines)?; + let mut timelines = self.timelines.lock().unwrap(); + let new_timeline = self + .prepare_timeline( + dst, + metadata, + timeline_uninit_mark, + false, + Some(src_timeline), + )? + .initialize_with_lock(&mut timelines, true)?; + drop(timelines); info!("branched timeline {dst} from {src} at {start_lsn}"); Ok(new_timeline) @@ -997,7 +1192,10 @@ impl Tenant { &self, timeline_id: TimelineId, pg_version: u32, - ) -> Result> { + ) -> anyhow::Result> { + let timelines = self.timelines.lock().unwrap(); + let timeline_uninit_mark = self.create_timeline_uninit_mark(timeline_id, &timelines)?; + drop(timelines); // create a `tenant/{tenant_id}/timelines/basebackup-{timeline_id}.{TEMP_FILE_SUFFIX}/` // temporary directory for basebackup files for the given timeline. let initdb_path = path_with_suffix_extension( @@ -1007,24 +1205,65 @@ impl Tenant { TEMP_FILE_SUFFIX, ); - // Init temporarily repo to get bootstrap data + // an uninit mark was placed before, nothing else can access this timeline files + // current initdb was not run yet, so remove whatever was left from the previous runs + if initdb_path.exists() { + fs::remove_dir_all(&initdb_path).with_context(|| { + format!( + "Failed to remove already existing initdb directory: {}", + initdb_path.display() + ) + })?; + } + // Init temporarily repo to get bootstrap data, this creates a directory in the `initdb_path` path run_initdb(self.conf, &initdb_path, pg_version)?; - let pgdata_path = initdb_path; - - let lsn = import_datadir::get_lsn_from_controlfile(&pgdata_path)?.align(); + // this new directory is very temporary, set to remove it immediately after bootstrap, we don't need it + scopeguard::defer! { + if let Err(e) = fs::remove_dir_all(&initdb_path) { + // this is unlikely, but we will remove the directory on pageserver restart or another bootstrap call + error!("Failed to remove temporary initdb directory '{}': {}", initdb_path.display(), e); + } + } + let pgdata_path = &initdb_path; + let pgdata_lsn = import_datadir::get_lsn_from_controlfile(pgdata_path)?.align(); // Import the contents of the data directory at the initial checkpoint // LSN, and any WAL after that. // Initdb lsn will be equal to last_record_lsn which will be set after import. - // Because we know it upfront avoid having an option or dummy zero value by passing it to create_empty_timeline. - let timeline = self.create_empty_timeline(timeline_id, lsn, pg_version)?; - import_datadir::import_timeline_from_postgres_datadir(&pgdata_path, &*timeline, lsn)?; + // Because we know it upfront avoid having an option or dummy zero value by passing it to the metadata. + let new_metadata = TimelineMetadata::new( + Lsn(0), + None, + None, + Lsn(0), + pgdata_lsn, + pgdata_lsn, + pg_version, + ); + let raw_timeline = + self.prepare_timeline(timeline_id, new_metadata, timeline_uninit_mark, true, None)?; + + let tenant_id = raw_timeline.owning_tenant.tenant_id; + let unfinished_timeline = raw_timeline.raw_timeline()?; + import_datadir::import_timeline_from_postgres_datadir( + unfinished_timeline, + pgdata_path, + pgdata_lsn, + ) + .with_context(|| { + format!("Failed to import pgdatadir for timeline {tenant_id}/{timeline_id}") + })?; fail::fail_point!("before-checkpoint-new-timeline", |_| { - bail!("failpoint before-checkpoint-new-timeline"); + anyhow::bail!("failpoint before-checkpoint-new-timeline"); }); + unfinished_timeline + .checkpoint(CheckpointConfig::Forced) + .with_context(|| format!("Failed to checkpoint after pgdatadir import for timeline {tenant_id}/{timeline_id}"))?; - timeline.checkpoint(CheckpointConfig::Forced)?; + let mut timelines = self.timelines.lock().unwrap(); + let timeline = raw_timeline.initialize_with_lock(&mut timelines, false)?; + drop(timelines); info!( "created root timeline {} timeline.lsn {}", @@ -1032,25 +1271,65 @@ impl Tenant { timeline.get_last_record_lsn() ); - // Remove temp dir. We don't need it anymore - fs::remove_dir_all(pgdata_path)?; - Ok(timeline) } - fn create_initialized_timeline( + /// Creates intermediate timeline structure and its files, without loading it into memory. + /// It's up to the caller to import the necesary data and import the timeline into memory. + fn prepare_timeline( &self, new_timeline_id: TimelineId, new_metadata: TimelineMetadata, - timelines: &mut MutexGuard>>, - ) -> Result> { - crashsafe_dir::create_dir_all(self.conf.timeline_path(&new_timeline_id, &self.tenant_id)) - .with_context(|| { - format!( - "Failed to create timeline {}/{} directory", - new_timeline_id, self.tenant_id - ) - })?; + uninit_mark: TimelineUninitMark, + init_layers: bool, + ancestor: Option>, + ) -> anyhow::Result { + let tenant_id = self.tenant_id; + + match self.create_timeline_files( + &uninit_mark.timeline_path, + new_timeline_id, + new_metadata, + ancestor, + ) { + Ok(new_timeline) => { + if init_layers { + new_timeline.layers.write().unwrap().next_open_layer_at = + Some(new_timeline.initdb_lsn); + } + debug!( + "Successfully created initial files for timeline {tenant_id}/{new_timeline_id}" + ); + Ok(UninitializedTimeline { + owning_tenant: self, + timeline_id: new_timeline_id, + raw_timeline: Some((new_timeline, uninit_mark)), + }) + } + Err(e) => { + error!("Failed to create initial files for timeline {tenant_id}/{new_timeline_id}, cleaning up: {e:?}"); + cleanup_timeline_directory(uninit_mark); + Err(e) + } + } + } + + fn create_timeline_files( + &self, + timeline_path: &Path, + new_timeline_id: TimelineId, + new_metadata: TimelineMetadata, + ancestor: Option>, + ) -> anyhow::Result { + let timeline_data = self + .create_timeline_data(new_timeline_id, new_metadata.clone(), ancestor) + .context("Failed to create timeline data structure")?; + crashsafe::create_dir_all(timeline_path).context("Failed to create timeline directory")?; + + fail::fail_point!("after-timeline-uninit-mark-creation", |_| { + anyhow::bail!("failpoint after-timeline-uninit-mark-creation"); + }); + save_metadata( self.conf, new_timeline_id, @@ -1058,48 +1337,70 @@ impl Tenant { &new_metadata, true, ) - .with_context(|| { - format!( - "Failed to create timeline {}/{} metadata", - new_timeline_id, self.tenant_id - ) - })?; + .context("Failed to create timeline metadata")?; - let ancestor = new_metadata - .ancestor_timeline() - .and_then(|ancestor_timeline_id| timelines.get(&ancestor_timeline_id)) - .cloned(); - let new_timeline = self - .initialize_new_timeline(new_timeline_id, new_metadata, ancestor) + Ok(timeline_data) + } + + /// Attempts to create an uninit mark file for the timeline initialization. + /// Bails, if the timeline is already loaded into the memory (i.e. initialized before), or the uninit mark file already exists. + /// + /// This way, we need to hold the timelines lock only for small amount of time during the mark check/creation per timeline init. + fn create_timeline_uninit_mark( + &self, + timeline_id: TimelineId, + timelines: &MutexGuard>>, + ) -> anyhow::Result { + let tenant_id = self.tenant_id; + + anyhow::ensure!( + timelines.get(&timeline_id).is_none(), + "Timeline {tenant_id}/{timeline_id} already exists in pageserver's memory" + ); + let timeline_path = self.conf.timeline_path(&timeline_id, &tenant_id); + anyhow::ensure!( + !timeline_path.exists(), + "Timeline {} already exists, cannot create its uninit mark file", + timeline_path.display() + ); + + let uninit_mark_path = self + .conf + .timeline_uninit_mark_file_path(tenant_id, timeline_id); + fs::File::create(&uninit_mark_path) + .context("Failed to create uninit mark file") + .and_then(|_| { + crashsafe::fsync_file_and_parent(&uninit_mark_path) + .context("Failed to fsync uninit mark file") + }) .with_context(|| { - format!( - "Failed to initialize timeline {}/{}", - new_timeline_id, self.tenant_id - ) + format!("Failed to crate uninit mark for timeline {tenant_id}/{timeline_id}") })?; - match timelines.entry(new_timeline_id) { - Entry::Occupied(_) => bail!( - "Found freshly initialized timeline {} in the tenant map", - new_timeline_id - ), - Entry::Vacant(v) => { - v.insert(Arc::clone(&new_timeline)); - } - } + let uninit_mark = TimelineUninitMark::new(uninit_mark_path, timeline_path); - Ok(new_timeline) + Ok(uninit_mark) } } /// Create the cluster temporarily in 'initdbpath' directory inside the repository /// to get bootstrap data for timeline initialization. -fn run_initdb(conf: &'static PageServerConf, initdbpath: &Path, pg_version: u32) -> Result<()> { - info!("running initdb in {}... ", initdbpath.display()); +fn run_initdb( + conf: &'static PageServerConf, + initdb_target_dir: &Path, + pg_version: u32, +) -> anyhow::Result<()> { + let initdb_bin_path = conf.pg_bin_dir(pg_version)?.join("initdb"); + let initdb_lib_dir = conf.pg_lib_dir(pg_version)?; + info!( + "running {} in {}, libdir: {}", + initdb_bin_path.display(), + initdb_target_dir.display(), + initdb_lib_dir.display(), + ); - let initdb_path = conf.pg_bin_dir(pg_version).join("initdb"); - let initdb_output = Command::new(initdb_path) - .args(&["-D", &initdbpath.to_string_lossy()]) + let initdb_output = Command::new(&initdb_bin_path) + .args(&["-D", &initdb_target_dir.to_string_lossy()]) .args(&["-U", &conf.superuser]) .args(&["-E", "utf8"]) .arg("--no-instructions") @@ -1107,11 +1408,17 @@ fn run_initdb(conf: &'static PageServerConf, initdbpath: &Path, pg_version: u32) // so no need to fsync it .arg("--no-sync") .env_clear() - .env("LD_LIBRARY_PATH", conf.pg_lib_dir(pg_version)) - .env("DYLD_LIBRARY_PATH", conf.pg_lib_dir(pg_version)) + .env("LD_LIBRARY_PATH", &initdb_lib_dir) + .env("DYLD_LIBRARY_PATH", &initdb_lib_dir) .stdout(Stdio::null()) .output() - .context("failed to execute initdb")?; + .with_context(|| { + format!( + "failed to execute {} at target dir {}", + initdb_bin_path.display(), + initdb_target_dir.display() + ) + })?; if !initdb_output.status.success() { bail!( "initdb failed: '{}'", @@ -1128,7 +1435,7 @@ impl Drop for Tenant { } } /// Dump contents of a layer file to stdout. -pub fn dump_layerfile_from_path(path: &Path, verbose: bool) -> Result<()> { +pub fn dump_layerfile_from_path(path: &Path, verbose: bool) -> anyhow::Result<()> { use std::os::unix::fs::FileExt; // All layer files start with a two-byte "magic" value, to identify the kind of @@ -1150,6 +1457,19 @@ pub fn dump_layerfile_from_path(path: &Path, verbose: bool) -> Result<()> { Ok(()) } +fn ignore_absent_files(fs_operation: F) -> io::Result<()> +where + F: Fn() -> io::Result<()>, +{ + fs_operation().or_else(|e| { + if e.kind() == io::ErrorKind::NotFound { + Ok(()) + } else { + Err(e) + } + }) +} + #[cfg(test)] pub mod harness { use bytes::{Bytes, BytesMut}; @@ -1220,13 +1540,13 @@ pub mod harness { } impl<'a> TenantHarness<'a> { - pub fn create(test_name: &'static str) -> Result { + pub fn create(test_name: &'static str) -> anyhow::Result { Self::create_internal(test_name, false) } - pub fn create_exclusive(test_name: &'static str) -> Result { + pub fn create_exclusive(test_name: &'static str) -> anyhow::Result { Self::create_internal(test_name, true) } - fn create_internal(test_name: &'static str, exclusive: bool) -> Result { + fn create_internal(test_name: &'static str, exclusive: bool) -> anyhow::Result { let lock_guard = if exclusive { (None, Some(LOCK.write().unwrap())) } else { @@ -1260,7 +1580,7 @@ pub mod harness { self.try_load().expect("failed to load test tenant") } - pub fn try_load(&self) -> Result { + pub fn try_load(&self) -> anyhow::Result { let walredo_mgr = Arc::new(TestRedoManager); let tenant = Tenant::new( @@ -1340,7 +1660,7 @@ pub mod harness { }, records.len() ); - println!("{}", s); + println!("{s}"); Ok(TEST_IMG(&s)) } @@ -1364,9 +1684,11 @@ mod tests { Lazy::new(|| Key::from_slice(&hex!("112222222233333333444444445500000001"))); #[test] - fn test_basic() -> Result<()> { + fn test_basic() -> anyhow::Result<()> { let tenant = TenantHarness::create("test_basic")?.load(); - let tline = tenant.create_empty_timeline(TIMELINE_ID, Lsn(0), DEFAULT_PG_VERSION)?; + let tline = tenant + .create_empty_timeline(TIMELINE_ID, Lsn(0), DEFAULT_PG_VERSION)? + .initialize()?; let writer = tline.writer(); writer.put(*TEST_KEY, Lsn(0x10), &Value::Image(TEST_IMG("foo at 0x10")))?; @@ -1386,15 +1708,20 @@ mod tests { } #[test] - fn no_duplicate_timelines() -> Result<()> { + fn no_duplicate_timelines() -> anyhow::Result<()> { let tenant = TenantHarness::create("no_duplicate_timelines")?.load(); - let _ = tenant.create_empty_timeline(TIMELINE_ID, Lsn(0), DEFAULT_PG_VERSION)?; + let _ = tenant + .create_empty_timeline(TIMELINE_ID, Lsn(0), DEFAULT_PG_VERSION)? + .initialize()?; match tenant.create_empty_timeline(TIMELINE_ID, Lsn(0), DEFAULT_PG_VERSION) { Ok(_) => panic!("duplicate timeline creation should fail"), Err(e) => assert_eq!( e.to_string(), - format!("Timeline {TIMELINE_ID} already exists") + format!( + "Timeline {}/{} already exists in pageserver's memory", + tenant.tenant_id, TIMELINE_ID + ) ), } @@ -1412,9 +1739,11 @@ mod tests { /// Test branch creation /// #[test] - fn test_branch() -> Result<()> { + fn test_branch() -> anyhow::Result<()> { let tenant = TenantHarness::create("test_branch")?.load(); - let tline = tenant.create_empty_timeline(TIMELINE_ID, Lsn(0), DEFAULT_PG_VERSION)?; + let tline = tenant + .create_empty_timeline(TIMELINE_ID, Lsn(0), DEFAULT_PG_VERSION)? + .initialize()?; let writer = tline.writer(); use std::str::from_utf8; @@ -1463,7 +1792,7 @@ mod tests { Ok(()) } - fn make_some_layers(tline: &Timeline, start_lsn: Lsn) -> Result<()> { + fn make_some_layers(tline: &Timeline, start_lsn: Lsn) -> anyhow::Result<()> { let mut lsn = start_lsn; #[allow(non_snake_case)] { @@ -1505,11 +1834,13 @@ mod tests { } #[test] - fn test_prohibit_branch_creation_on_garbage_collected_data() -> Result<()> { + fn test_prohibit_branch_creation_on_garbage_collected_data() -> anyhow::Result<()> { let tenant = TenantHarness::create("test_prohibit_branch_creation_on_garbage_collected_data")? .load(); - let tline = tenant.create_empty_timeline(TIMELINE_ID, Lsn(0), DEFAULT_PG_VERSION)?; + let tline = tenant + .create_empty_timeline(TIMELINE_ID, Lsn(0), DEFAULT_PG_VERSION)? + .initialize()?; make_some_layers(tline.as_ref(), Lsn(0x20))?; // this removes layers before lsn 40 (50 minus 10), so there are two remaining layers, image and delta for 31-50 @@ -1535,11 +1866,13 @@ mod tests { } #[test] - fn test_prohibit_branch_creation_on_pre_initdb_lsn() -> Result<()> { + fn test_prohibit_branch_creation_on_pre_initdb_lsn() -> anyhow::Result<()> { let tenant = TenantHarness::create("test_prohibit_branch_creation_on_pre_initdb_lsn")?.load(); - tenant.create_empty_timeline(TIMELINE_ID, Lsn(0x50), DEFAULT_PG_VERSION)?; + tenant + .create_empty_timeline(TIMELINE_ID, Lsn(0x50), DEFAULT_PG_VERSION)? + .initialize()?; // try to branch at lsn 0x25, should fail because initdb lsn is 0x50 match tenant.branch_timeline(TIMELINE_ID, NEW_TIMELINE_ID, Some(Lsn(0x25))) { Ok(_) => panic!("branching should have failed"), @@ -1560,7 +1893,7 @@ mod tests { // FIXME: This currently fails to error out. Calling GC doesn't currently // remove the old value, we'd need to work a little harder #[test] - fn test_prohibit_get_for_garbage_collected_data() -> Result<()> { + fn test_prohibit_get_for_garbage_collected_data() -> anyhow::Result<()> { let repo = RepoHarness::create("test_prohibit_get_for_garbage_collected_data")? .load(); @@ -1580,10 +1913,12 @@ mod tests { */ #[test] - fn test_retain_data_in_parent_which_is_needed_for_child() -> Result<()> { + fn test_retain_data_in_parent_which_is_needed_for_child() -> anyhow::Result<()> { let tenant = TenantHarness::create("test_retain_data_in_parent_which_is_needed_for_child")?.load(); - let tline = tenant.create_empty_timeline(TIMELINE_ID, Lsn(0), DEFAULT_PG_VERSION)?; + let tline = tenant + .create_empty_timeline(TIMELINE_ID, Lsn(0), DEFAULT_PG_VERSION)? + .initialize()?; make_some_layers(tline.as_ref(), Lsn(0x20))?; tenant.branch_timeline(TIMELINE_ID, NEW_TIMELINE_ID, Some(Lsn(0x40)))?; @@ -1597,10 +1932,12 @@ mod tests { Ok(()) } #[test] - fn test_parent_keeps_data_forever_after_branching() -> Result<()> { + fn test_parent_keeps_data_forever_after_branching() -> anyhow::Result<()> { let tenant = TenantHarness::create("test_parent_keeps_data_forever_after_branching")?.load(); - let tline = tenant.create_empty_timeline(TIMELINE_ID, Lsn(0), DEFAULT_PG_VERSION)?; + let tline = tenant + .create_empty_timeline(TIMELINE_ID, Lsn(0), DEFAULT_PG_VERSION)? + .initialize()?; make_some_layers(tline.as_ref(), Lsn(0x20))?; tenant.branch_timeline(TIMELINE_ID, NEW_TIMELINE_ID, Some(Lsn(0x40)))?; @@ -1623,13 +1960,14 @@ mod tests { } #[test] - fn timeline_load() -> Result<()> { + fn timeline_load() -> anyhow::Result<()> { const TEST_NAME: &str = "timeline_load"; let harness = TenantHarness::create(TEST_NAME)?; { let tenant = harness.load(); - let tline = - tenant.create_empty_timeline(TIMELINE_ID, Lsn(0x8000), DEFAULT_PG_VERSION)?; + let tline = tenant + .create_empty_timeline(TIMELINE_ID, Lsn(0x8000), DEFAULT_PG_VERSION)? + .initialize()?; make_some_layers(tline.as_ref(), Lsn(0x8000))?; tline.checkpoint(CheckpointConfig::Forced)?; } @@ -1643,13 +1981,15 @@ mod tests { } #[test] - fn timeline_load_with_ancestor() -> Result<()> { + fn timeline_load_with_ancestor() -> anyhow::Result<()> { const TEST_NAME: &str = "timeline_load_with_ancestor"; let harness = TenantHarness::create(TEST_NAME)?; // create two timelines { let tenant = harness.load(); - let tline = tenant.create_empty_timeline(TIMELINE_ID, Lsn(0), DEFAULT_PG_VERSION)?; + let tline = tenant + .create_empty_timeline(TIMELINE_ID, Lsn(0), DEFAULT_PG_VERSION)? + .initialize()?; make_some_layers(tline.as_ref(), Lsn(0x20))?; tline.checkpoint(CheckpointConfig::Forced)?; @@ -1680,12 +2020,14 @@ mod tests { } #[test] - fn corrupt_metadata() -> Result<()> { + fn corrupt_metadata() -> anyhow::Result<()> { const TEST_NAME: &str = "corrupt_metadata"; let harness = TenantHarness::create(TEST_NAME)?; let tenant = harness.load(); - tenant.create_empty_timeline(TIMELINE_ID, Lsn(0), DEFAULT_PG_VERSION)?; + tenant + .create_empty_timeline(TIMELINE_ID, Lsn(0), DEFAULT_PG_VERSION)? + .initialize()?; drop(tenant); let metadata_path = harness.timeline_path(&TIMELINE_ID).join(METADATA_FILE_NAME); @@ -1720,9 +2062,11 @@ mod tests { } #[test] - fn test_images() -> Result<()> { + fn test_images() -> anyhow::Result<()> { let tenant = TenantHarness::create("test_images")?.load(); - let tline = tenant.create_empty_timeline(TIMELINE_ID, Lsn(0), DEFAULT_PG_VERSION)?; + let tline = tenant + .create_empty_timeline(TIMELINE_ID, Lsn(0), DEFAULT_PG_VERSION)? + .initialize()?; let writer = tline.writer(); writer.put(*TEST_KEY, Lsn(0x10), &Value::Image(TEST_IMG("foo at 0x10")))?; @@ -1770,9 +2114,11 @@ mod tests { // repeat 50 times. // #[test] - fn test_bulk_insert() -> Result<()> { + fn test_bulk_insert() -> anyhow::Result<()> { let tenant = TenantHarness::create("test_bulk_insert")?.load(); - let tline = tenant.create_empty_timeline(TIMELINE_ID, Lsn(0), DEFAULT_PG_VERSION)?; + let tline = tenant + .create_empty_timeline(TIMELINE_ID, Lsn(0), DEFAULT_PG_VERSION)? + .initialize()?; let mut lsn = Lsn(0x10); @@ -1810,9 +2156,11 @@ mod tests { } #[test] - fn test_random_updates() -> Result<()> { + fn test_random_updates() -> anyhow::Result<()> { let tenant = TenantHarness::create("test_random_updates")?.load(); - let tline = tenant.create_empty_timeline(TIMELINE_ID, Lsn(0), DEFAULT_PG_VERSION)?; + let tline = tenant + .create_empty_timeline(TIMELINE_ID, Lsn(0), DEFAULT_PG_VERSION)? + .initialize()?; const NUM_KEYS: usize = 1000; @@ -1880,9 +2228,11 @@ mod tests { } #[test] - fn test_traverse_branches() -> Result<()> { + fn test_traverse_branches() -> anyhow::Result<()> { let tenant = TenantHarness::create("test_traverse_branches")?.load(); - let mut tline = tenant.create_empty_timeline(TIMELINE_ID, Lsn(0), DEFAULT_PG_VERSION)?; + let mut tline = tenant + .create_empty_timeline(TIMELINE_ID, Lsn(0), DEFAULT_PG_VERSION)? + .initialize()?; const NUM_KEYS: usize = 1000; @@ -1959,9 +2309,11 @@ mod tests { } #[test] - fn test_traverse_ancestors() -> Result<()> { + fn test_traverse_ancestors() -> anyhow::Result<()> { let tenant = TenantHarness::create("test_traverse_ancestors")?.load(); - let mut tline = tenant.create_empty_timeline(TIMELINE_ID, Lsn(0), DEFAULT_PG_VERSION)?; + let mut tline = tenant + .create_empty_timeline(TIMELINE_ID, Lsn(0), DEFAULT_PG_VERSION)? + .initialize()?; const NUM_KEYS: usize = 100; const NUM_TLINES: usize = 50; diff --git a/pageserver/src/tenant/delta_layer.rs b/pageserver/src/tenant/delta_layer.rs index 57c5be91a4..41715ab0a4 100644 --- a/pageserver/src/tenant/delta_layer.rs +++ b/pageserver/src/tenant/delta_layer.rs @@ -556,7 +556,7 @@ impl DeltaLayer { /// Create a DeltaLayer struct representing an existing file on disk. /// - /// This variant is only used for debugging purposes, by the 'dump_layerfile' binary. + /// This variant is only used for debugging purposes, by the 'pageserver_binutils' binary. pub fn new_for_path(path: &Path, file: F) -> Result where F: FileExt, diff --git a/pageserver/src/tenant/filename.rs b/pageserver/src/tenant/filename.rs index 5ebac2332d..0ebf2d479b 100644 --- a/pageserver/src/tenant/filename.rs +++ b/pageserver/src/tenant/filename.rs @@ -177,7 +177,7 @@ impl fmt::Display for ImageFileName { /// /// This is used by DeltaLayer and ImageLayer. Normally, this holds a reference to the /// global config, and paths to layer files are constructed using the tenant/timeline -/// path from the config. But in the 'dump_layerfile' binary, we need to construct a Layer +/// path from the config. But in the 'pageserver_binutils' binary, we need to construct a Layer /// struct for a file on disk, without having a page server running, so that we have no /// config. In that case, we use the Path variant to hold the full path to the file on /// disk. diff --git a/pageserver/src/tenant/image_layer.rs b/pageserver/src/tenant/image_layer.rs index 92bf022fee..cbfa0134b0 100644 --- a/pageserver/src/tenant/image_layer.rs +++ b/pageserver/src/tenant/image_layer.rs @@ -357,7 +357,7 @@ impl ImageLayer { /// Create an ImageLayer struct representing an existing file on disk. /// - /// This variant is only used for debugging purposes, by the 'dump_layerfile' binary. + /// This variant is only used for debugging purposes, by the 'pageserver_binutils' binary. pub fn new_for_path(path: &Path, file: F) -> Result where F: std::os::unix::prelude::FileExt, diff --git a/pageserver/src/tenant/layer_map.rs b/pageserver/src/tenant/layer_map.rs index 495833e3ae..9d914c1839 100644 --- a/pageserver/src/tenant/layer_map.rs +++ b/pageserver/src/tenant/layer_map.rs @@ -62,6 +62,8 @@ pub struct LayerMap { struct LayerRTreeObject { layer: Arc, + + envelope: AABB<[IntKey; 2]>, } // Representation of Key as numeric type. @@ -197,9 +199,16 @@ impl PartialEq for LayerRTreeObject { impl RTreeObject for LayerRTreeObject { type Envelope = AABB<[IntKey; 2]>; fn envelope(&self) -> Self::Envelope { - let key_range = self.layer.get_key_range(); - let lsn_range = self.layer.get_lsn_range(); - AABB::from_corners( + self.envelope + } +} + +impl LayerRTreeObject { + fn new(layer: Arc) -> Self { + let key_range = layer.get_key_range(); + let lsn_range = layer.get_lsn_range(); + + let envelope = AABB::from_corners( [ IntKey::from(key_range.start.to_i128()), IntKey::from(lsn_range.start.0 as i128), @@ -208,7 +217,8 @@ impl RTreeObject for LayerRTreeObject { IntKey::from(key_range.end.to_i128() - 1), IntKey::from(lsn_range.end.0 as i128 - 1), ], // AABB::upper is inclusive, while `key_range.end` and `lsn_range.end` are exclusive - ) + ); + LayerRTreeObject { layer, envelope } } } @@ -338,7 +348,7 @@ impl LayerMap { if layer.get_key_range() == (Key::MIN..Key::MAX) { self.l0_delta_layers.push(layer.clone()); } - self.historic_layers.insert(LayerRTreeObject { layer }); + self.historic_layers.insert(LayerRTreeObject::new(layer)); NUM_ONDISK_LAYERS.inc(); } @@ -362,7 +372,7 @@ impl LayerMap { } assert!(self .historic_layers - .remove(&LayerRTreeObject { layer }) + .remove(&LayerRTreeObject::new(layer)) .is_some()); NUM_ONDISK_LAYERS.dec(); } diff --git a/pageserver/src/tenant/timeline.rs b/pageserver/src/tenant/timeline.rs index 247e076230..ccd094b65a 100644 --- a/pageserver/src/tenant/timeline.rs +++ b/pageserver/src/tenant/timeline.rs @@ -1,6 +1,6 @@ //! -use anyhow::{anyhow, bail, ensure, Context, Result}; +use anyhow::{anyhow, bail, ensure, Context}; use bytes::Bytes; use fail::fail_point; use itertools::Itertools; @@ -34,6 +34,7 @@ use crate::keyspace::{KeyPartitioning, KeySpace}; use crate::metrics::TimelineMetrics; use crate::pgdatadir_mapping::BlockNumber; use crate::pgdatadir_mapping::LsnForTimestamp; +use crate::pgdatadir_mapping::{is_rel_fsm_block_key, is_rel_vm_block_key}; use crate::reltag::RelTag; use crate::tenant_config::TenantConfOpt; @@ -52,7 +53,11 @@ use crate::task_mgr::TaskKind; use crate::walreceiver::{is_etcd_client_initialized, spawn_connection_manager_task}; use crate::walredo::WalRedoManager; use crate::CheckpointConfig; -use crate::{page_cache, storage_sync}; +use crate::ZERO_PAGE; +use crate::{ + page_cache, + storage_sync::{self, index::LayerFileMetadata}, +}; pub struct Timeline { conf: &'static PageServerConf, @@ -302,10 +307,6 @@ pub struct GcInfo { /// Public interface functions impl Timeline { - //------------------------------------------------------------------------------ - // Public GET functions - //------------------------------------------------------------------------------ - /// Get the LSN where this branch was created pub fn get_ancestor_lsn(&self) -> Lsn { self.ancestor_lsn @@ -440,7 +441,7 @@ impl Timeline { &self, lsn: Lsn, latest_gc_cutoff_lsn: &RcuReadGuard, - ) -> Result<()> { + ) -> anyhow::Result<()> { ensure!( lsn >= **latest_gc_cutoff_lsn, "LSN {} is earlier than latest GC horizon {} (we might've already garbage collected needed data)", @@ -450,12 +451,6 @@ impl Timeline { Ok(()) } - //------------------------------------------------------------------------------ - // Public PUT functions, to update the repository with new page versions. - // - // These are called by the WAL receiver to digest WAL records. - //------------------------------------------------------------------------------ - /// Flush to disk all data that was written with the put_* functions /// /// NOTE: This has nothing to do with checkpoint in PostgreSQL. We don't @@ -474,17 +469,172 @@ impl Timeline { } } + pub fn compact(&self) -> anyhow::Result<()> { + let last_record_lsn = self.get_last_record_lsn(); + + // Last record Lsn could be zero in case the timelie was just created + if !last_record_lsn.is_valid() { + warn!("Skipping compaction for potentially just initialized timeline, it has invalid last record lsn: {last_record_lsn}"); + return Ok(()); + } + + // + // High level strategy for compaction / image creation: + // + // 1. First, calculate the desired "partitioning" of the + // currently in-use key space. The goal is to partition the + // key space into roughly fixed-size chunks, but also take into + // account any existing image layers, and try to align the + // chunk boundaries with the existing image layers to avoid + // too much churn. Also try to align chunk boundaries with + // relation boundaries. In principle, we don't know about + // relation boundaries here, we just deal with key-value + // pairs, and the code in pgdatadir_mapping.rs knows how to + // map relations into key-value pairs. But in practice we know + // that 'field6' is the block number, and the fields 1-5 + // identify a relation. This is just an optimization, + // though. + // + // 2. Once we know the partitioning, for each partition, + // decide if it's time to create a new image layer. The + // criteria is: there has been too much "churn" since the last + // image layer? The "churn" is fuzzy concept, it's a + // combination of too many delta files, or too much WAL in + // total in the delta file. Or perhaps: if creating an image + // file would allow to delete some older files. + // + // 3. After that, we compact all level0 delta files if there + // are too many of them. While compacting, we also garbage + // collect any page versions that are no longer needed because + // of the new image layers we created in step 2. + // + // TODO: This high level strategy hasn't been implemented yet. + // Below are functions compact_level0() and create_image_layers() + // but they are a bit ad hoc and don't quite work like it's explained + // above. Rewrite it. + let _layer_removal_cs = self.layer_removal_cs.lock().unwrap(); + + let target_file_size = self.get_checkpoint_distance(); + + // Define partitioning schema if needed + + match self.repartition( + self.get_last_record_lsn(), + self.get_compaction_target_size(), + ) { + Ok((partitioning, lsn)) => { + // 2. Create new image layers for partitions that have been modified + // "enough". + let layer_paths_to_upload = self.create_image_layers(&partitioning, lsn, false)?; + if !layer_paths_to_upload.is_empty() + && self.upload_layers.load(atomic::Ordering::Relaxed) + { + storage_sync::schedule_layer_upload( + self.tenant_id, + self.timeline_id, + layer_paths_to_upload, + None, + ); + } + + // 3. Compact + let timer = self.metrics.compact_time_histo.start_timer(); + self.compact_level0(target_file_size)?; + timer.stop_and_record(); + } + Err(err) => { + // no partitioning? This is normal, if the timeline was just created + // as an empty timeline. Also in unit tests, when we use the timeline + // as a simple key-value store, ignoring the datadir layout. Log the + // error but continue. + error!("could not compact, repartitioning keyspace failed: {err:?}"); + } + }; + + Ok(()) + } + /// Mutate the timeline with a [`TimelineWriter`]. - /// - /// FIXME: This ought to return &'a TimelineWriter, where TimelineWriter - /// is a generic type in this trait. But that doesn't currently work in - /// Rust: https://rust-lang.github.io/rfcs/1598-generic_associated_types.html pub fn writer(&self) -> TimelineWriter<'_> { TimelineWriter { tl: self, _write_guard: self.write_lock.lock().unwrap(), } } + + /// Retrieve current logical size of the timeline. + /// + /// The size could be lagging behind the actual number, in case + /// the initial size calculation has not been run (gets triggered on the first size access). + pub fn get_current_logical_size(self: &Arc) -> anyhow::Result { + let current_size = self.current_logical_size.current_size()?; + debug!("Current size: {current_size:?}"); + + let size = current_size.size(); + if let (CurrentLogicalSize::Approximate(_), Some(init_lsn)) = + (current_size, self.current_logical_size.initial_part_end) + { + self.try_spawn_size_init_task(init_lsn); + } + + Ok(size) + } + + /// Check if more than 'checkpoint_distance' of WAL has been accumulated in + /// the in-memory layer, and initiate flushing it if so. + /// + /// Also flush after a period of time without new data -- it helps + /// safekeepers to regard pageserver as caught up and suspend activity. + pub fn check_checkpoint_distance(self: &Arc) -> anyhow::Result<()> { + let last_lsn = self.get_last_record_lsn(); + let layers = self.layers.read().unwrap(); + if let Some(open_layer) = &layers.open_layer { + let open_layer_size = open_layer.size()?; + drop(layers); + let last_freeze_at = self.last_freeze_at.load(); + let last_freeze_ts = *(self.last_freeze_ts.read().unwrap()); + let distance = last_lsn.widening_sub(last_freeze_at); + // Checkpointing the open layer can be triggered by layer size or LSN range. + // S3 has a 5 GB limit on the size of one upload (without multi-part upload), and + // we want to stay below that with a big margin. The LSN distance determines how + // much WAL the safekeepers need to store. + if distance >= self.get_checkpoint_distance().into() + || open_layer_size > self.get_checkpoint_distance() + || (distance > 0 && last_freeze_ts.elapsed() >= self.get_checkpoint_timeout()) + { + info!( + "check_checkpoint_distance {}, layer size {}, elapsed since last flush {:?}", + distance, + open_layer_size, + last_freeze_ts.elapsed() + ); + + self.freeze_inmem_layer(true); + self.last_freeze_at.store(last_lsn); + *(self.last_freeze_ts.write().unwrap()) = Instant::now(); + + // Launch a task to flush the frozen layer to disk, unless + // a task was already running. (If the task was running + // at the time that we froze the layer, it must've seen the + // the layer we just froze before it exited; see comments + // in flush_frozen_layers()) + if let Ok(guard) = self.layer_flush_lock.try_lock() { + drop(guard); + let self_clone = Arc::clone(self); + task_mgr::spawn( + task_mgr::BACKGROUND_RUNTIME.handle(), + task_mgr::TaskKind::LayerFlushTask, + Some(self.tenant_id), + Some(self.timeline_id), + "layer flush task", + false, + async move { self_clone.flush_frozen_layers(false) }, + ); + } + } + } + Ok(()) + } } // Private functions @@ -528,7 +678,7 @@ impl Timeline { /// /// Loads the metadata for the timeline into memory, but not the layer map. #[allow(clippy::too_many_arguments)] - pub fn new( + pub(super) fn new( conf: &'static PageServerConf, tenant_conf: Arc>, metadata: TimelineMetadata, @@ -601,11 +751,11 @@ impl Timeline { result } - pub fn launch_wal_receiver(self: &Arc) -> anyhow::Result<()> { + pub(super) fn launch_wal_receiver(self: &Arc) { if !is_etcd_client_initialized() { if cfg!(test) { info!("not launching WAL receiver because etcd client hasn't been initialized"); - return Ok(()); + return; } else { panic!("etcd client not initialized"); } @@ -633,16 +783,14 @@ impl Timeline { walreceiver_connect_timeout, lagging_wal_timeout, max_lsn_wal_lag, - )?; - - Ok(()) + ); } /// /// Scan the timeline directory to populate the layer map. /// Returns all timeline-related files that were found and loaded. /// - pub fn load_layer_map(&self, disk_consistent_lsn: Lsn) -> anyhow::Result<()> { + pub(super) fn load_layer_map(&self, disk_consistent_lsn: Lsn) -> anyhow::Result<()> { let mut layers = self.layers.write().unwrap(); let mut num_layers = 0; @@ -728,30 +876,12 @@ impl Timeline { Ok(()) } - pub fn layer_removal_guard(&self) -> anyhow::Result> { + pub(super) fn layer_removal_guard(&self) -> anyhow::Result> { self.layer_removal_cs .try_lock() .map_err(|e| anyhow!("cannot lock compaction critical section {e}")) } - /// Retrieve current logical size of the timeline. - /// - /// The size could be lagging behind the actual number, in case - /// the initial size calculation has not been run (gets triggered on the first size access). - pub fn get_current_logical_size(self: &Arc) -> anyhow::Result { - let current_size = self.current_logical_size.current_size()?; - debug!("Current size: {current_size:?}"); - - let size = current_size.size(); - if let (CurrentLogicalSize::Approximate(_), Some(init_lsn)) = - (current_size, self.current_logical_size.initial_part_end) - { - self.try_spawn_size_init_task(init_lsn); - } - - Ok(size) - } - fn try_spawn_size_init_task(self: &Arc, init_lsn: Lsn) { let timeline_id = self.timeline_id; @@ -972,7 +1102,7 @@ impl Timeline { Some((lsn, img)) } - fn get_ancestor_timeline(&self) -> Result> { + fn get_ancestor_timeline(&self) -> anyhow::Result> { let ancestor = self.ancestor_timeline.as_ref().with_context(|| { format!( "Ancestor is missing. Timeline id: {} Ancestor id {:?}", @@ -1031,14 +1161,14 @@ impl Timeline { Ok(layer) } - fn put_value(&self, key: Key, lsn: Lsn, val: &Value) -> Result<()> { + fn put_value(&self, key: Key, lsn: Lsn, val: &Value) -> anyhow::Result<()> { //info!("PUT: key {} at {}", key, lsn); let layer = self.get_layer_for_write(lsn)?; layer.put_value(key, lsn, val)?; Ok(()) } - fn put_tombstone(&self, key_range: Range, lsn: Lsn) -> Result<()> { + fn put_tombstone(&self, key_range: Range, lsn: Lsn) -> anyhow::Result<()> { let layer = self.get_layer_for_write(lsn)?; layer.put_tombstone(key_range, lsn)?; @@ -1077,64 +1207,6 @@ impl Timeline { drop(layers); } - /// - /// Check if more than 'checkpoint_distance' of WAL has been accumulated in - /// the in-memory layer, and initiate flushing it if so. - /// - /// Also flush after a period of time without new data -- it helps - /// safekeepers to regard pageserver as caught up and suspend activity. - /// - pub fn check_checkpoint_distance(self: &Arc) -> Result<()> { - let last_lsn = self.get_last_record_lsn(); - let layers = self.layers.read().unwrap(); - if let Some(open_layer) = &layers.open_layer { - let open_layer_size = open_layer.size()?; - drop(layers); - let last_freeze_at = self.last_freeze_at.load(); - let last_freeze_ts = *(self.last_freeze_ts.read().unwrap()); - let distance = last_lsn.widening_sub(last_freeze_at); - // Checkpointing the open layer can be triggered by layer size or LSN range. - // S3 has a 5 GB limit on the size of one upload (without multi-part upload), and - // we want to stay below that with a big margin. The LSN distance determines how - // much WAL the safekeepers need to store. - if distance >= self.get_checkpoint_distance().into() - || open_layer_size > self.get_checkpoint_distance() - || (distance > 0 && last_freeze_ts.elapsed() >= self.get_checkpoint_timeout()) - { - info!( - "check_checkpoint_distance {}, layer size {}, elapsed since last flush {:?}", - distance, - open_layer_size, - last_freeze_ts.elapsed() - ); - - self.freeze_inmem_layer(true); - self.last_freeze_at.store(last_lsn); - *(self.last_freeze_ts.write().unwrap()) = Instant::now(); - - // Launch a task to flush the frozen layer to disk, unless - // a task was already running. (If the task was running - // at the time that we froze the layer, it must've seen the - // the layer we just froze before it exited; see comments - // in flush_frozen_layers()) - if let Ok(guard) = self.layer_flush_lock.try_lock() { - drop(guard); - let self_clone = Arc::clone(self); - task_mgr::spawn( - task_mgr::BACKGROUND_RUNTIME.handle(), - task_mgr::TaskKind::LayerFlushTask, - Some(self.tenant_id), - Some(self.timeline_id), - "layer flush task", - false, - async move { self_clone.flush_frozen_layers(false) }, - ); - } - } - } - Ok(()) - } - /// Flush all frozen layers to disk. /// /// Only one task at a time can be doing layer-flushing for a @@ -1142,7 +1214,7 @@ impl Timeline { /// currently doing the flushing, this function will wait for it /// to finish. If 'wait' is false, this function will return /// immediately instead. - fn flush_frozen_layers(&self, wait: bool) -> Result<()> { + fn flush_frozen_layers(&self, wait: bool) -> anyhow::Result<()> { let flush_lock_guard = if wait { self.layer_flush_lock.lock().unwrap() } else { @@ -1181,7 +1253,7 @@ impl Timeline { } /// Flush one frozen in-memory layer to disk, as a new delta layer. - fn flush_frozen_layer(&self, frozen_layer: Arc) -> Result<()> { + fn flush_frozen_layer(&self, frozen_layer: Arc) -> anyhow::Result<()> { // As a special case, when we have just imported an image into the repository, // instead of writing out a L0 delta layer, we directly write out image layer // files instead. This is possible as long as *all* the data imported into the @@ -1194,8 +1266,8 @@ impl Timeline { self.create_image_layers(&partitioning, self.initdb_lsn, true)? } else { // normal case, write out a L0 delta layer file. - let delta_path = self.create_delta_layer(&frozen_layer)?; - HashSet::from([delta_path]) + let (delta_path, metadata) = self.create_delta_layer(&frozen_layer)?; + HashMap::from([(delta_path, metadata)]) }; fail_point!("flush-frozen-before-sync"); @@ -1221,85 +1293,86 @@ impl Timeline { // TODO: This perhaps should be done in 'flush_frozen_layers', after flushing // *all* the layers, to avoid fsyncing the file multiple times. let disk_consistent_lsn = Lsn(lsn_range.end.0 - 1); - self.update_disk_consistent_lsn(disk_consistent_lsn, layer_paths_to_upload)?; + let old_disk_consistent_lsn = self.disk_consistent_lsn.load(); + // If we were able to advance 'disk_consistent_lsn', save it the metadata file. + // After crash, we will restart WAL streaming and processing from that point. + if disk_consistent_lsn != old_disk_consistent_lsn { + assert!(disk_consistent_lsn > old_disk_consistent_lsn); + self.update_metadata_file(disk_consistent_lsn, layer_paths_to_upload)?; + // Also update the in-memory copy + self.disk_consistent_lsn.store(disk_consistent_lsn); + } Ok(()) } /// Update metadata file - fn update_disk_consistent_lsn( + fn update_metadata_file( &self, disk_consistent_lsn: Lsn, - layer_paths_to_upload: HashSet, - ) -> Result<()> { - // If we were able to advance 'disk_consistent_lsn', save it the metadata file. - // After crash, we will restart WAL streaming and processing from that point. - let old_disk_consistent_lsn = self.disk_consistent_lsn.load(); - if disk_consistent_lsn != old_disk_consistent_lsn { - assert!(disk_consistent_lsn > old_disk_consistent_lsn); + layer_paths_to_upload: HashMap, + ) -> anyhow::Result<()> { + // We can only save a valid 'prev_record_lsn' value on disk if we + // flushed *all* in-memory changes to disk. We only track + // 'prev_record_lsn' in memory for the latest processed record, so we + // don't remember what the correct value that corresponds to some old + // LSN is. But if we flush everything, then the value corresponding + // current 'last_record_lsn' is correct and we can store it on disk. + let RecordLsn { + last: last_record_lsn, + prev: prev_record_lsn, + } = self.last_record_lsn.load(); + let ondisk_prev_record_lsn = if disk_consistent_lsn == last_record_lsn { + Some(prev_record_lsn) + } else { + None + }; - // We can only save a valid 'prev_record_lsn' value on disk if we - // flushed *all* in-memory changes to disk. We only track - // 'prev_record_lsn' in memory for the latest processed record, so we - // don't remember what the correct value that corresponds to some old - // LSN is. But if we flush everything, then the value corresponding - // current 'last_record_lsn' is correct and we can store it on disk. - let RecordLsn { - last: last_record_lsn, - prev: prev_record_lsn, - } = self.last_record_lsn.load(); - let ondisk_prev_record_lsn = if disk_consistent_lsn == last_record_lsn { - Some(prev_record_lsn) - } else { - None - }; + let ancestor_timeline_id = self + .ancestor_timeline + .as_ref() + .map(|ancestor| ancestor.timeline_id); - let ancestor_timeline_id = self - .ancestor_timeline - .as_ref() - .map(|ancestor| ancestor.timeline_id); + let metadata = TimelineMetadata::new( + disk_consistent_lsn, + ondisk_prev_record_lsn, + ancestor_timeline_id, + self.ancestor_lsn, + *self.latest_gc_cutoff_lsn.read(), + self.initdb_lsn, + self.pg_version, + ); - let metadata = TimelineMetadata::new( - disk_consistent_lsn, - ondisk_prev_record_lsn, - ancestor_timeline_id, - self.ancestor_lsn, - *self.latest_gc_cutoff_lsn.read(), - self.initdb_lsn, - self.pg_version, - ); + fail_point!("checkpoint-before-saving-metadata", |x| bail!( + "{}", + x.unwrap() + )); - fail_point!("checkpoint-before-saving-metadata", |x| bail!( - "{}", - x.unwrap() - )); + save_metadata( + self.conf, + self.timeline_id, + self.tenant_id, + &metadata, + false, + )?; - save_metadata( - self.conf, - self.timeline_id, + if self.upload_layers.load(atomic::Ordering::Relaxed) { + storage_sync::schedule_layer_upload( self.tenant_id, - &metadata, - false, - )?; - - if self.upload_layers.load(atomic::Ordering::Relaxed) { - storage_sync::schedule_layer_upload( - self.tenant_id, - self.timeline_id, - layer_paths_to_upload, - Some(metadata), - ); - } - - // Also update the in-memory copy - self.disk_consistent_lsn.store(disk_consistent_lsn); + self.timeline_id, + layer_paths_to_upload, + Some(metadata), + ); } Ok(()) } // Write out the given frozen in-memory layer as a new L0 delta file - fn create_delta_layer(&self, frozen_layer: &InMemoryLayer) -> Result { + fn create_delta_layer( + &self, + frozen_layer: &InMemoryLayer, + ) -> anyhow::Result<(PathBuf, LayerFileMetadata)> { // Write it out let new_delta = frozen_layer.write_to_disk()?; let new_delta_path = new_delta.path(); @@ -1325,100 +1398,16 @@ impl Timeline { // update the timeline's physical size let sz = new_delta_path.metadata()?.len(); + self.metrics.current_physical_size_gauge.add(sz); // update metrics self.metrics.num_persistent_files_created.inc_by(1); self.metrics.persistent_bytes_written.inc_by(sz); - Ok(new_delta_path) + Ok((new_delta_path, LayerFileMetadata::new(sz))) } - pub fn compact(&self) -> anyhow::Result<()> { - let last_record_lsn = self.get_last_record_lsn(); - - // Last record Lsn could be zero in case the timelie was just created - if !last_record_lsn.is_valid() { - warn!("Skipping compaction for potentially just initialized timeline, it has invalid last record lsn: {last_record_lsn}"); - return Ok(()); - } - - // - // High level strategy for compaction / image creation: - // - // 1. First, calculate the desired "partitioning" of the - // currently in-use key space. The goal is to partition the - // key space into roughly fixed-size chunks, but also take into - // account any existing image layers, and try to align the - // chunk boundaries with the existing image layers to avoid - // too much churn. Also try to align chunk boundaries with - // relation boundaries. In principle, we don't know about - // relation boundaries here, we just deal with key-value - // pairs, and the code in pgdatadir_mapping.rs knows how to - // map relations into key-value pairs. But in practice we know - // that 'field6' is the block number, and the fields 1-5 - // identify a relation. This is just an optimization, - // though. - // - // 2. Once we know the partitioning, for each partition, - // decide if it's time to create a new image layer. The - // criteria is: there has been too much "churn" since the last - // image layer? The "churn" is fuzzy concept, it's a - // combination of too many delta files, or too much WAL in - // total in the delta file. Or perhaps: if creating an image - // file would allow to delete some older files. - // - // 3. After that, we compact all level0 delta files if there - // are too many of them. While compacting, we also garbage - // collect any page versions that are no longer needed because - // of the new image layers we created in step 2. - // - // TODO: This high level strategy hasn't been implemented yet. - // Below are functions compact_level0() and create_image_layers() - // but they are a bit ad hoc and don't quite work like it's explained - // above. Rewrite it. - let _layer_removal_cs = self.layer_removal_cs.lock().unwrap(); - - let target_file_size = self.get_checkpoint_distance(); - - // Define partitioning schema if needed - - match self.repartition( - self.get_last_record_lsn(), - self.get_compaction_target_size(), - ) { - Ok((partitioning, lsn)) => { - // 2. Create new image layers for partitions that have been modified - // "enough". - let layer_paths_to_upload = self.create_image_layers(&partitioning, lsn, false)?; - if !layer_paths_to_upload.is_empty() - && self.upload_layers.load(atomic::Ordering::Relaxed) - { - storage_sync::schedule_layer_upload( - self.tenant_id, - self.timeline_id, - HashSet::from_iter(layer_paths_to_upload), - None, - ); - } - - // 3. Compact - let timer = self.metrics.compact_time_histo.start_timer(); - self.compact_level0(target_file_size)?; - timer.stop_and_record(); - } - Err(err) => { - // no partitioning? This is normal, if the timeline was just created - // as an empty timeline. Also in unit tests, when we use the timeline - // as a simple key-value store, ignoring the datadir layout. Log the - // error but continue. - error!("could not compact, repartitioning keyspace failed: {err:?}"); - } - }; - - Ok(()) - } - - fn repartition(&self, lsn: Lsn, partition_size: u64) -> Result<(KeyPartitioning, Lsn)> { + fn repartition(&self, lsn: Lsn, partition_size: u64) -> anyhow::Result<(KeyPartitioning, Lsn)> { let mut partitioning_guard = self.partitioning.lock().unwrap(); if partitioning_guard.1 == Lsn(0) || lsn.0 - partitioning_guard.1 .0 > self.repartition_threshold @@ -1432,7 +1421,7 @@ impl Timeline { } // Is it time to create a new image layer for the given partition? - fn time_for_new_image_layer(&self, partition: &KeySpace, lsn: Lsn) -> Result { + fn time_for_new_image_layer(&self, partition: &KeySpace, lsn: Lsn) -> anyhow::Result { let layers = self.layers.read().unwrap(); for part_range in &partition.ranges { @@ -1477,10 +1466,9 @@ impl Timeline { partitioning: &KeyPartitioning, lsn: Lsn, force: bool, - ) -> Result> { + ) -> anyhow::Result> { let timer = self.metrics.create_images_time_histo.start_timer(); let mut image_layers: Vec = Vec::new(); - let mut layer_paths_to_upload = HashSet::new(); for partition in partitioning.parts.iter() { if force || self.time_for_new_image_layer(partition, lsn)? { let img_range = @@ -1496,13 +1484,37 @@ impl Timeline { for range in &partition.ranges { let mut key = range.start; while key < range.end { - let img = self.get(key, lsn)?; + let img = match self.get(key, lsn) { + Ok(img) => img, + Err(err) => { + // If we fail to reconstruct a VM or FSM page, we can zero the + // page without losing any actual user data. That seems better + // than failing repeatedly and getting stuck. + // + // We had a bug at one point, where we truncated the FSM and VM + // in the pageserver, but the Postgres didn't know about that + // and continued to generate incremental WAL records for pages + // that didn't exist in the pageserver. Trying to replay those + // WAL records failed to find the previous image of the page. + // This special case allows us to recover from that situation. + // See https://github.com/neondatabase/neon/issues/2601. + // + // Unfortunately we cannot do this for the main fork, or for + // any metadata keys, keys, as that would lead to actual data + // loss. + if is_rel_fsm_block_key(key) || is_rel_vm_block_key(key) { + warn!("could not reconstruct FSM or VM key {key}, filling with zeros: {err:?}"); + ZERO_PAGE.clone() + } else { + return Err(err); + } + } + }; image_layer_writer.put_image(key, &img)?; key = key.next(); } } let image_layer = image_layer_writer.finish()?; - layer_paths_to_upload.insert(image_layer.path()); image_layers.push(image_layer); } } @@ -1516,15 +1528,25 @@ impl Timeline { // // Compaction creates multiple image layers. It would be better to create them all // and fsync them all in parallel. - let mut all_paths = Vec::from_iter(layer_paths_to_upload.clone()); - all_paths.push(self.conf.timeline_path(&self.timeline_id, &self.tenant_id)); + let all_paths = image_layers + .iter() + .map(|layer| layer.path()) + .chain(std::iter::once( + self.conf.timeline_path(&self.timeline_id, &self.tenant_id), + )) + .collect::>(); par_fsync::par_fsync(&all_paths)?; + let mut layer_paths_to_upload = HashMap::with_capacity(image_layers.len()); + let mut layers = self.layers.write().unwrap(); for l in image_layers { - self.metrics - .current_physical_size_gauge - .add(l.path().metadata()?.len()); + let path = l.path(); + let metadata = path.metadata()?; + + layer_paths_to_upload.insert(path, LayerFileMetadata::new(metadata.len())); + + self.metrics.current_physical_size_gauge.add(metadata.len()); layers.insert_historic(Arc::new(l)); } drop(layers); @@ -1537,7 +1559,7 @@ impl Timeline { /// Collect a bunch of Level 0 layer files, and compact and reshuffle them as /// as Level 1 files. /// - fn compact_level0(&self, target_file_size: u64) -> Result<()> { + fn compact_level0(&self, target_file_size: u64) -> anyhow::Result<()> { let layers = self.layers.read().unwrap(); let mut level0_deltas = layers.get_level0_deltas()?; drop(layers); @@ -1775,16 +1797,16 @@ impl Timeline { } let mut layers = self.layers.write().unwrap(); - let mut new_layer_paths = HashSet::with_capacity(new_layers.len()); + let mut new_layer_paths = HashMap::with_capacity(new_layers.len()); for l in new_layers { let new_delta_path = l.path(); - // update the timeline's physical size - self.metrics - .current_physical_size_gauge - .add(new_delta_path.metadata()?.len()); + let metadata = new_delta_path.metadata()?; - new_layer_paths.insert(new_delta_path); + // update the timeline's physical size + self.metrics.current_physical_size_gauge.add(metadata.len()); + + new_layer_paths.insert(new_delta_path, LayerFileMetadata::new(metadata.len())); layers.insert_historic(Arc::new(l)); } @@ -1847,12 +1869,12 @@ impl Timeline { /// /// The 'pitr' duration is used to calculate a 'pitr_cutoff', which can be used to determine /// whether a record is needed for PITR. - pub fn update_gc_info( + pub(super) fn update_gc_info( &self, retain_lsns: Vec, cutoff_horizon: Lsn, pitr: Duration, - ) -> Result<()> { + ) -> anyhow::Result<()> { let mut gc_info = self.gc_info.write().unwrap(); gc_info.horizon_cutoff = cutoff_horizon; @@ -1907,7 +1929,7 @@ impl Timeline { /// within a layer file. We can only remove the whole file if it's fully /// obsolete. /// - pub fn gc(&self) -> Result { + pub(super) fn gc(&self) -> anyhow::Result { let mut result: GcResult = Default::default(); let now = SystemTime::now(); @@ -1951,6 +1973,9 @@ impl Timeline { ); write_guard.store_and_unlock(new_gc_cutoff).wait(); } + // Persist the new GC cutoff value in the metadata file, before + // we actually remove anything. + self.update_metadata_file(self.disk_consistent_lsn.load(), HashMap::new())?; info!("GC starting"); @@ -2076,6 +2101,15 @@ impl Timeline { result.layers_removed += 1; } + info!( + "GC completed removing {} layers, cutoff {}", + result.layers_removed, new_gc_cutoff + ); + + if result.layers_removed != 0 { + fail_point!("after-timeline-gc-removed-layers"); + } + if self.upload_layers.load(atomic::Ordering::Relaxed) { storage_sync::schedule_layer_delete( self.tenant_id, @@ -2215,11 +2249,11 @@ impl<'a> TimelineWriter<'a> { /// /// This will implicitly extend the relation, if the page is beyond the /// current end-of-file. - pub fn put(&self, key: Key, lsn: Lsn, value: &Value) -> Result<()> { + pub fn put(&self, key: Key, lsn: Lsn, value: &Value) -> anyhow::Result<()> { self.tl.put_value(key, lsn, value) } - pub fn delete(&self, key_range: Range, lsn: Lsn) -> Result<()> { + pub fn delete(&self, key_range: Range, lsn: Lsn) -> anyhow::Result<()> { self.tl.put_tombstone(key_range, lsn) } diff --git a/pageserver/src/tenant_mgr.rs b/pageserver/src/tenant_mgr.rs index 0e8ee8c067..f1db50bf7f 100644 --- a/pageserver/src/tenant_mgr.rs +++ b/pageserver/src/tenant_mgr.rs @@ -1,7 +1,7 @@ //! This module acts as a switchboard to access different repositories managed by this //! page server. -use std::collections::{hash_map, HashMap, HashSet}; +use std::collections::{hash_map, HashMap}; use std::ffi::OsStr; use std::fs; use std::path::{Path, PathBuf}; @@ -12,19 +12,19 @@ use tracing::*; use remote_storage::GenericRemoteStorage; -use crate::config::{PageServerConf, METADATA_FILE_NAME}; +use crate::config::{PageServerConf, METADATA_FILE_NAME, TIMELINE_UNINIT_MARK_SUFFIX}; use crate::http::models::TenantInfo; -use crate::storage_sync::index::{RemoteIndex, RemoteTimelineIndex}; -use crate::storage_sync::{self, LocalTimelineInitStatus, SyncStartupData}; +use crate::storage_sync::index::{LayerFileMetadata, RemoteIndex, RemoteTimelineIndex}; +use crate::storage_sync::{self, LocalTimelineInitStatus, SyncStartupData, TimelineLocalFiles}; use crate::task_mgr::{self, TaskKind}; use crate::tenant::{ ephemeral_file::is_ephemeral_file, metadata::TimelineMetadata, Tenant, TenantState, }; use crate::tenant_config::TenantConfOpt; use crate::walredo::PostgresRedoManager; -use crate::{TenantTimelineValues, TEMP_FILE_SUFFIX}; +use crate::TEMP_FILE_SUFFIX; -use utils::crashsafe_dir::{self, path_with_suffix_extension}; +use utils::crashsafe::{self, path_with_suffix_extension}; use utils::id::{TenantId, TimelineId}; mod tenants_state { @@ -70,34 +70,54 @@ pub fn init_tenant_mgr( .remote_storage_config .as_ref() .expect("remote storage without config"); - + let mut broken_tenants = HashMap::new(); + let mut ready_tenants = HashMap::new(); + for (tenant_id, tenant_attach_data) in local_tenant_files.into_iter() { + match tenant_attach_data { + TenantAttachData::Ready(t) => { + ready_tenants.insert(tenant_id, t); + } + TenantAttachData::Broken(e) => { + broken_tenants.insert(tenant_id, TenantAttachData::Broken(e)); + } + } + } let SyncStartupData { remote_index, local_timeline_init_statuses, } = storage_sync::spawn_storage_sync_task( conf, - local_tenant_files, + ready_tenants, storage, storage_config.max_concurrent_syncs, storage_config.max_sync_errors, ) .context("Failed to spawn the storage sync thread")?; - ( - remote_index, - local_timeline_init_statuses.filter_map(|init_status| match init_status { - LocalTimelineInitStatus::LocallyComplete(metadata) => Some(metadata), - LocalTimelineInitStatus::NeedsSync => None, - }), - ) + let n = local_timeline_init_statuses.0.len(); + let mut synced_timelines = local_timeline_init_statuses.0.into_iter().fold( + HashMap::::with_capacity(n), + |mut new_values, (tenant_id, old_values)| { + let new_timeline_values = new_values + .entry(tenant_id) + .or_insert_with(|| TenantAttachData::Ready(HashMap::new())); + if let TenantAttachData::Ready(t) = new_timeline_values { + for (timeline_id, old_value) in old_values { + if let LocalTimelineInitStatus::LocallyComplete(metadata) = old_value { + t.insert(timeline_id, TimelineLocalFiles::ready(metadata)); + } + } + } + new_values + }, + ); + synced_timelines.extend(broken_tenants); + + (remote_index, synced_timelines) } else { info!("No remote storage configured, skipping storage sync, considering all local timelines with correct metadata files enabled"); - ( - RemoteIndex::default(), - local_tenant_files.filter_map(|(metadata, _)| Some(metadata)), - ) + (RemoteIndex::default(), local_tenant_files) }; - attach_local_tenants(conf, &remote_index, tenants_to_attach); Ok(remote_index) @@ -117,18 +137,12 @@ pub fn init_tenant_mgr( pub fn attach_local_tenants( conf: &'static PageServerConf, remote_index: &RemoteIndex, - tenants_to_attach: TenantTimelineValues, + tenants_to_attach: HashMap, ) { let _entered = info_span!("attach_local_tenants").entered(); - let number_of_tenants = tenants_to_attach.0.len(); - - for (tenant_id, local_timelines) in tenants_to_attach.0 { - info!( - "Attaching {} timelines for {tenant_id}", - local_timelines.len() - ); - debug!("Timelines to attach: {local_timelines:?}"); + let number_of_tenants = tenants_to_attach.len(); + for (tenant_id, local_timelines) in tenants_to_attach { let mut tenants_accessor = tenants_state::write_tenants(); let tenant = match tenants_accessor.entry(tenant_id) { hash_map::Entry::Occupied(o) => { @@ -137,25 +151,55 @@ pub fn attach_local_tenants( } hash_map::Entry::Vacant(v) => { info!("Tenant {tenant_id} was not found in pageserver's memory, loading it"); - let tenant = load_local_tenant(conf, tenant_id, remote_index); + let tenant = Arc::new(Tenant::new( + conf, + TenantConfOpt::default(), + Arc::new(PostgresRedoManager::new(conf, tenant_id)), + tenant_id, + remote_index.clone(), + conf.remote_storage_config.is_some(), + )); + match local_timelines { + TenantAttachData::Broken(_) => { + tenant.set_state(TenantState::Broken); + } + TenantAttachData::Ready(_) => { + match Tenant::load_tenant_config(conf, tenant_id) { + Ok(tenant_conf) => { + tenant.update_tenant_config(tenant_conf); + tenant.activate(false); + } + Err(e) => { + error!("Failed to read config for tenant {tenant_id}, disabling tenant: {e:?}"); + tenant.set_state(TenantState::Broken); + } + }; + } + } v.insert(Arc::clone(&tenant)); tenant } }; drop(tenants_accessor); - - if tenant.current_state() == TenantState::Broken { - warn!("Skipping timeline load for broken tenant {tenant_id}") - } else { - let has_timelines = !local_timelines.is_empty(); - match tenant.init_attach_timelines(local_timelines) { - Ok(()) => { - info!("successfully loaded local timelines for tenant {tenant_id}"); - tenant.activate(has_timelines); - } - Err(e) => { - error!("Failed to attach tenant timelines: {e:?}"); - tenant.set_state(TenantState::Broken); + match local_timelines { + TenantAttachData::Broken(e) => warn!("{}", e), + TenantAttachData::Ready(ref timelines) => { + info!("Attaching {} timelines for {tenant_id}", timelines.len()); + debug!("Timelines to attach: {local_timelines:?}"); + let has_timelines = !timelines.is_empty(); + let timelines_to_attach = timelines + .iter() + .map(|(&k, v)| (k, v.metadata().to_owned())) + .collect(); + match tenant.init_attach_timelines(timelines_to_attach) { + Ok(()) => { + info!("successfully loaded local timelines for tenant {tenant_id}"); + tenant.activate(has_timelines); + } + Err(e) => { + error!("Failed to attach tenant timelines: {e:?}"); + tenant.set_state(TenantState::Broken); + } } } } @@ -164,44 +208,6 @@ pub fn attach_local_tenants( info!("Processed {number_of_tenants} local tenants during attach") } -fn load_local_tenant( - conf: &'static PageServerConf, - tenant_id: TenantId, - remote_index: &RemoteIndex, -) -> Arc { - let tenant = Arc::new(Tenant::new( - conf, - TenantConfOpt::default(), - Arc::new(PostgresRedoManager::new(conf, tenant_id)), - tenant_id, - remote_index.clone(), - conf.remote_storage_config.is_some(), - )); - - let tenant_timelines_dir = conf.timelines_path(&tenant_id); - if !tenant_timelines_dir.is_dir() { - error!( - "Tenant {} has no timelines directory at {}", - tenant_id, - tenant_timelines_dir.display() - ); - tenant.set_state(TenantState::Broken); - } else { - match Tenant::load_tenant_config(conf, tenant_id) { - Ok(tenant_conf) => { - tenant.update_tenant_config(tenant_conf); - tenant.activate(false); - } - Err(e) => { - error!("Failed to read config for tenant {tenant_id}, disabling tenant: {e:?}"); - tenant.set_state(TenantState::Broken); - } - } - } - - tenant -} - /// /// Shut down all tenants. This runs as part of pageserver shutdown. /// @@ -259,58 +265,98 @@ fn create_tenant_files( temporary_tenant_dir.display() ); - let temporary_tenant_timelines_dir = rebase_directory( - &conf.timelines_path(&tenant_id), - &target_tenant_directory, - &temporary_tenant_dir, - )?; - let temporary_tenant_config_path = rebase_directory( - &conf.tenant_config_path(tenant_id), - &target_tenant_directory, - &temporary_tenant_dir, - )?; - // top-level dir may exist if we are creating it through CLI - crashsafe_dir::create_dir_all(&temporary_tenant_dir).with_context(|| { + crashsafe::create_dir_all(&temporary_tenant_dir).with_context(|| { format!( "could not create temporary tenant directory {}", temporary_tenant_dir.display() ) })?; - // first, create a config in the top-level temp directory, fsync the file - Tenant::persist_tenant_config(&temporary_tenant_config_path, tenant_conf, true)?; - // then, create a subdirectory in the top-level temp directory, fsynced - crashsafe_dir::create_dir(&temporary_tenant_timelines_dir).with_context(|| { + + let creation_result = try_create_target_tenant_dir( + conf, + tenant_conf, + tenant_id, + &temporary_tenant_dir, + &target_tenant_directory, + ); + + if creation_result.is_err() { + error!("Failed to create directory structure for tenant {tenant_id}, cleaning tmp data"); + if let Err(e) = fs::remove_dir_all(&temporary_tenant_dir) { + error!("Failed to remove temporary tenant directory {temporary_tenant_dir:?}: {e}") + } else if let Err(e) = crashsafe::fsync(&temporary_tenant_dir) { + error!( + "Failed to fsync removed temporary tenant directory {temporary_tenant_dir:?}: {e}" + ) + } + } + + creation_result +} + +fn try_create_target_tenant_dir( + conf: &'static PageServerConf, + tenant_conf: TenantConfOpt, + tenant_id: TenantId, + temporary_tenant_dir: &Path, + target_tenant_directory: &Path, +) -> Result<(), anyhow::Error> { + let temporary_tenant_timelines_dir = rebase_directory( + &conf.timelines_path(&tenant_id), + target_tenant_directory, + temporary_tenant_dir, + ) + .with_context(|| format!("Failed to resolve tenant {tenant_id} temporary timelines dir"))?; + let temporary_tenant_config_path = rebase_directory( + &conf.tenant_config_path(tenant_id), + target_tenant_directory, + temporary_tenant_dir, + ) + .with_context(|| format!("Failed to resolve tenant {tenant_id} temporary config path"))?; + + Tenant::persist_tenant_config(&temporary_tenant_config_path, tenant_conf, true).with_context( + || { + format!( + "Failed to write tenant {} config to {}", + tenant_id, + temporary_tenant_config_path.display() + ) + }, + )?; + crashsafe::create_dir(&temporary_tenant_timelines_dir).with_context(|| { format!( - "could not create temporary tenant timelines directory {}", + "could not create tenant {} temporary timelines directory {}", + tenant_id, temporary_tenant_timelines_dir.display() ) })?; - fail::fail_point!("tenant-creation-before-tmp-rename", |_| { anyhow::bail!("failpoint tenant-creation-before-tmp-rename"); }); - // move-rename tmp directory with all files synced into a permanent directory, fsync its parent - fs::rename(&temporary_tenant_dir, &target_tenant_directory).with_context(|| { + fs::rename(&temporary_tenant_dir, target_tenant_directory).with_context(|| { format!( - "failed to move temporary tenant directory {} into the permanent one {}", + "failed to move tenant {} temporary directory {} into the permanent one {}", + tenant_id, temporary_tenant_dir.display(), target_tenant_directory.display() ) })?; let target_dir_parent = target_tenant_directory.parent().with_context(|| { format!( - "Failed to get tenant dir parent for {}", + "Failed to get tenant {} dir parent for {}", + tenant_id, target_tenant_directory.display() ) })?; - fs::File::open(target_dir_parent)?.sync_all()?; - - info!( - "created tenant directory structure in {}", - target_tenant_directory.display() - ); + crashsafe::fsync(target_dir_parent).with_context(|| { + format!( + "Failed to fsync renamed directory's parent {} for tenant {}", + target_dir_parent.display(), + tenant_id, + ) + })?; Ok(()) } @@ -475,16 +521,21 @@ pub fn list_tenant_info(remote_index: &RemoteTimelineIndex) -> Vec { .collect() } +#[derive(Debug)] +pub enum TenantAttachData { + Ready(HashMap), + Broken(anyhow::Error), +} /// Attempts to collect information about all tenant and timelines, existing on the local FS. /// If finds any, deletes all temporary files and directories, created before. Also removes empty directories, /// that may appear due to such removals. /// Does not fail on particular timeline or tenant collection errors, rather logging them and ignoring the entities. fn local_tenant_timeline_files( config: &'static PageServerConf, -) -> anyhow::Result)>> { +) -> anyhow::Result> { let _entered = info_span!("local_tenant_timeline_files").entered(); - let mut local_tenant_timeline_files = TenantTimelineValues::new(); + let mut local_tenant_timeline_files = HashMap::new(); let tenants_dir = config.tenants_path(); for tenants_dir_entry in fs::read_dir(&tenants_dir) .with_context(|| format!("Failed to list tenants dir {}", tenants_dir.display()))? @@ -506,19 +557,31 @@ fn local_tenant_timeline_files( } } else { match collect_timelines_for_tenant(config, &tenant_dir_path) { - Ok((tenant_id, collected_files)) => { + Ok((tenant_id, TenantAttachData::Broken(e))) => { + local_tenant_timeline_files.entry(tenant_id).or_insert(TenantAttachData::Broken(e)); + }, + Ok((tenant_id, TenantAttachData::Ready(collected_files))) => { if collected_files.is_empty() { match remove_if_empty(&tenant_dir_path) { Ok(true) => info!("Removed empty tenant directory {}", tenant_dir_path.display()), Ok(false) => { // insert empty timeline entry: it has some non-temporary files inside that we cannot remove // so make obvious for HTTP API callers, that something exists there and try to load the tenant - let _ = local_tenant_timeline_files.0.entry(tenant_id).or_default(); + let _ = local_tenant_timeline_files.entry(tenant_id).or_insert_with(|| TenantAttachData::Ready(HashMap::new())); }, Err(e) => error!("Failed to remove empty tenant directory: {e:?}"), } } else { - local_tenant_timeline_files.0.entry(tenant_id).or_default().extend(collected_files.into_iter()) + match local_tenant_timeline_files.entry(tenant_id) { + hash_map::Entry::Vacant(entry) => { + entry.insert(TenantAttachData::Ready(collected_files)); + } + hash_map::Entry::Occupied(entry) =>{ + if let TenantAttachData::Ready(old_timelines) = entry.into_mut() { + old_timelines.extend(collected_files); + } + }, + } } }, Err(e) => error!( @@ -541,7 +604,7 @@ fn local_tenant_timeline_files( info!( "Collected files for {} tenants", - local_tenant_timeline_files.0.len() + local_tenant_timeline_files.len(), ); Ok(local_tenant_timeline_files) } @@ -579,14 +642,19 @@ fn is_temporary(path: &Path) -> bool { } } -#[allow(clippy::type_complexity)] +fn is_uninit_mark(path: &Path) -> bool { + match path.file_name() { + Some(name) => name + .to_string_lossy() + .ends_with(TIMELINE_UNINIT_MARK_SUFFIX), + None => false, + } +} + fn collect_timelines_for_tenant( config: &'static PageServerConf, tenant_path: &Path, -) -> anyhow::Result<( - TenantId, - HashMap)>, -)> { +) -> anyhow::Result<(TenantId, TenantAttachData)> { let tenant_id = tenant_path .file_name() .and_then(OsStr::to_str) @@ -595,6 +663,17 @@ fn collect_timelines_for_tenant( .context("Could not parse tenant id out of the tenant dir name")?; let timelines_dir = config.timelines_path(&tenant_id); + if !timelines_dir.as_path().is_dir() { + return Ok(( + tenant_id, + TenantAttachData::Broken(anyhow::anyhow!( + "Tenant {} has no timelines directory at {}", + tenant_id, + timelines_dir.display() + )), + )); + } + let mut tenant_timelines = HashMap::new(); for timelines_dir_entry in fs::read_dir(&timelines_dir) .with_context(|| format!("Failed to list timelines dir entry for tenant {tenant_id}"))? @@ -614,25 +693,74 @@ fn collect_timelines_for_tenant( e ); } + } else if is_uninit_mark(&timeline_dir) { + let timeline_uninit_mark_file = &timeline_dir; + info!( + "Found an uninit mark file {}, removing the timeline and its uninit mark", + timeline_uninit_mark_file.display() + ); + let timeline_id = timeline_uninit_mark_file + .file_stem() + .and_then(OsStr::to_str) + .unwrap_or_default() + .parse::() + .with_context(|| { + format!( + "Could not parse timeline id out of the timeline uninit mark name {}", + timeline_uninit_mark_file.display() + ) + })?; + let timeline_dir = config.timeline_path(&timeline_id, &tenant_id); + if let Err(e) = + remove_timeline_and_uninit_mark(&timeline_dir, timeline_uninit_mark_file) + { + error!("Failed to clean up uninit marked timeline: {e:?}"); + } } else { - match collect_timeline_files(&timeline_dir) { - Ok((timeline_id, metadata, timeline_files)) => { - tenant_timelines.insert(timeline_id, (metadata, timeline_files)); + let timeline_id = timeline_dir + .file_name() + .and_then(OsStr::to_str) + .unwrap_or_default() + .parse::() + .with_context(|| { + format!( + "Could not parse timeline id out of the timeline dir name {}", + timeline_dir.display() + ) + })?; + let timeline_uninit_mark_file = + config.timeline_uninit_mark_file_path(tenant_id, timeline_id); + if timeline_uninit_mark_file.exists() { + info!("Found an uninit mark file for timeline {tenant_id}/{timeline_id}, removing the timeline and its uninit mark"); + if let Err(e) = remove_timeline_and_uninit_mark( + &timeline_dir, + &timeline_uninit_mark_file, + ) { + error!("Failed to clean up uninit marked timeline: {e:?}"); } - Err(e) => { - error!( - "Failed to process timeline dir contents at '{}', reason: {:?}", - timeline_dir.display(), - e - ); - match remove_if_empty(&timeline_dir) { - Ok(true) => info!( - "Removed empty timeline directory {}", - timeline_dir.display() - ), - Ok(false) => (), - Err(e) => { - error!("Failed to remove empty timeline directory: {e:?}") + } else { + match collect_timeline_files(&timeline_dir) { + Ok((metadata, timeline_files)) => { + tenant_timelines.insert( + timeline_id, + TimelineLocalFiles::collected(metadata, timeline_files), + ); + } + Err(e) => { + error!( + "Failed to process timeline dir contents at '{}', reason: {:?}", + timeline_dir.display(), + e + ); + match remove_if_empty(&timeline_dir) { + Ok(true) => info!( + "Removed empty timeline directory {}", + timeline_dir.display() + ), + Ok(false) => (), + Err(e) => { + error!("Failed to remove empty timeline directory: {e:?}") + } } } } @@ -652,28 +780,51 @@ fn collect_timelines_for_tenant( debug!("Tenant {tenant_id} has no timelines loaded"); } - Ok((tenant_id, tenant_timelines)) + Ok((tenant_id, TenantAttachData::Ready(tenant_timelines))) +} + +fn remove_timeline_and_uninit_mark(timeline_dir: &Path, uninit_mark: &Path) -> anyhow::Result<()> { + fs::remove_dir_all(&timeline_dir) + .or_else(|e| { + if e.kind() == std::io::ErrorKind::NotFound { + // we can leave the uninit mark without a timeline dir, + // just remove the mark then + Ok(()) + } else { + Err(e) + } + }) + .with_context(|| { + format!( + "Failed to remove unit marked timeline directory {}", + timeline_dir.display() + ) + })?; + fs::remove_file(&uninit_mark).with_context(|| { + format!( + "Failed to remove timeline uninit mark file {}", + uninit_mark.display() + ) + })?; + + Ok(()) } // discover timeline files and extract timeline metadata // NOTE: ephemeral files are excluded from the list fn collect_timeline_files( timeline_dir: &Path, -) -> anyhow::Result<(TimelineId, TimelineMetadata, HashSet)> { - let mut timeline_files = HashSet::new(); +) -> anyhow::Result<(TimelineMetadata, HashMap)> { + let mut timeline_files = HashMap::new(); let mut timeline_metadata_path = None; - let timeline_id = timeline_dir - .file_name() - .and_then(OsStr::to_str) - .unwrap_or_default() - .parse::() - .context("Could not parse timeline id out of the timeline dir name")?; let timeline_dir_entries = fs::read_dir(&timeline_dir).context("Failed to list timeline dir contents")?; for entry in timeline_dir_entries { let entry_path = entry.context("Failed to list timeline dir entry")?.path(); - if entry_path.is_file() { + let metadata = entry_path.metadata()?; + + if metadata.is_file() { if entry_path.file_name().and_then(OsStr::to_str) == Some(METADATA_FILE_NAME) { timeline_metadata_path = Some(entry_path); } else if is_ephemeral_file(&entry_path.file_name().unwrap().to_string_lossy()) { @@ -688,7 +839,8 @@ fn collect_timeline_files( ) })?; } else { - timeline_files.insert(entry_path); + let layer_metadata = LayerFileMetadata::new(metadata.len()); + timeline_files.insert(entry_path, layer_metadata); } } } @@ -714,5 +866,5 @@ fn collect_timeline_files( "Timeline has no ancestor and no layer files" ); - Ok((timeline_id, metadata, timeline_files)) + Ok((metadata, timeline_files)) } diff --git a/pageserver/src/tenant_tasks.rs b/pageserver/src/tenant_tasks.rs index 8329b15c08..030055df6d 100644 --- a/pageserver/src/tenant_tasks.rs +++ b/pageserver/src/tenant_tasks.rs @@ -70,8 +70,10 @@ async fn compaction_loop(tenant_id: TenantId) { // Run compaction let mut sleep_duration = tenant.get_compaction_period(); if let Err(e) = tenant.compaction_iteration() { - error!("Compaction failed, retrying: {e:#}"); sleep_duration = wait_duration; + error!("Compaction failed, retrying in {:?}: {e:#}", sleep_duration); + #[cfg(feature = "testing")] + std::process::abort(); } // Sleep @@ -119,8 +121,10 @@ async fn gc_loop(tenant_id: TenantId) { if gc_horizon > 0 { if let Err(e) = tenant.gc_iteration(None, gc_horizon, tenant.get_pitr_interval(), false) { - error!("Gc failed, retrying: {e:#}"); sleep_duration = wait_duration; + error!("Gc failed, retrying in {:?}: {e:#}", sleep_duration); + #[cfg(feature = "testing")] + std::process::abort(); } } diff --git a/pageserver/src/walingest.rs b/pageserver/src/walingest.rs index d3d2c6d9b2..9a6b99d991 100644 --- a/pageserver/src/walingest.rs +++ b/pageserver/src/walingest.rs @@ -34,6 +34,7 @@ use crate::pgdatadir_mapping::*; use crate::reltag::{RelTag, SlruKind}; use crate::tenant::Timeline; use crate::walrecord::*; +use crate::ZERO_PAGE; use postgres_ffi::pg_constants; use postgres_ffi::relfile_utils::{FSM_FORKNUM, MAIN_FORKNUM, VISIBILITYMAP_FORKNUM}; use postgres_ffi::v14::nonrelfile_utils::mx_offset_to_member_segment; @@ -43,8 +44,6 @@ use postgres_ffi::TransactionId; use postgres_ffi::BLCKSZ; use utils::lsn::Lsn; -static ZERO_PAGE: Bytes = Bytes::from_static(&[0u8; 8192]); - pub struct WalIngest<'a> { timeline: &'a Timeline, diff --git a/pageserver/src/walreceiver/connection_manager.rs b/pageserver/src/walreceiver/connection_manager.rs index 29179e9871..3a5d1c7ad6 100644 --- a/pageserver/src/walreceiver/connection_manager.rs +++ b/pageserver/src/walreceiver/connection_manager.rs @@ -47,7 +47,7 @@ pub fn spawn_connection_manager_task( wal_connect_timeout: Duration, lagging_wal_timeout: Duration, max_lsn_wal_lag: NonZeroU64, -) -> anyhow::Result<()> { +) { let mut etcd_client = get_etcd_client().clone(); let tenant_id = timeline.tenant_id; @@ -95,7 +95,6 @@ pub fn spawn_connection_manager_task( info_span!("wal_connection_manager", tenant = %tenant_id, timeline = %timeline_id), ), ); - Ok(()) } /// Attempts to subscribe for timeline updates, pushed by safekeepers into the broker. @@ -1374,7 +1373,9 @@ mod tests { timeline: harness .load() .create_empty_timeline(TIMELINE_ID, Lsn(0), crate::DEFAULT_PG_VERSION) - .expect("Failed to create an empty timeline for dummy wal connection manager"), + .expect("Failed to create an empty timeline for dummy wal connection manager") + .initialize() + .unwrap(), wal_connect_timeout: Duration::from_secs(1), lagging_wal_timeout: Duration::from_secs(1), max_lsn_wal_lag: NonZeroU64::new(1024 * 1024).unwrap(), diff --git a/pageserver/src/walredo.rs b/pageserver/src/walredo.rs index 15a9408dc9..e683c301d8 100644 --- a/pageserver/src/walredo.rs +++ b/pageserver/src/walredo.rs @@ -35,11 +35,12 @@ use std::sync::Mutex; use std::time::Duration; use std::time::Instant; use tracing::*; -use utils::crashsafe_dir::path_with_suffix_extension; +use utils::crashsafe::path_with_suffix_extension; use utils::{bin_ser::BeSer, id::TenantId, lsn::Lsn, nonblock::set_nonblock}; use crate::metrics::{ - WAL_REDO_RECORDS_HISTOGRAM, WAL_REDO_RECORD_COUNTER, WAL_REDO_TIME, WAL_REDO_WAIT_TIME, + WAL_REDO_BYTES_HISTOGRAM, WAL_REDO_RECORDS_HISTOGRAM, WAL_REDO_RECORD_COUNTER, WAL_REDO_TIME, + WAL_REDO_WAIT_TIME, }; use crate::pgdatadir_mapping::{key_to_rel_block, key_to_slru_block}; use crate::reltag::{RelTag, SlruKind}; @@ -244,12 +245,23 @@ impl PostgresRedoManager { let end_time = Instant::now(); let duration = end_time.duration_since(lock_time); + let len = records.len(); + let nbytes = records.iter().fold(0, |acumulator, record| { + acumulator + + match &record.1 { + NeonWalRecord::Postgres { rec, .. } => rec.len(), + _ => unreachable!("Only PostgreSQL records are accepted in this batch"), + } + }); + WAL_REDO_TIME.observe(duration.as_secs_f64()); - WAL_REDO_RECORDS_HISTOGRAM.observe(records.len() as f64); + WAL_REDO_RECORDS_HISTOGRAM.observe(len as f64); + WAL_REDO_BYTES_HISTOGRAM.observe(nbytes as f64); debug!( - "postgres applied {} WAL records in {} us to reconstruct page image at LSN {}", - records.len(), + "postgres applied {} WAL records ({} bytes) in {} us to reconstruct page image at LSN {}", + len, + nbytes, duration.as_micros(), lsn ); @@ -258,8 +270,9 @@ impl PostgresRedoManager { // next request will launch a new one. if result.is_err() { error!( - "error applying {} WAL records to reconstruct page image at LSN {}", + "error applying {} WAL records ({} bytes) to reconstruct page image at LSN {}", records.len(), + nbytes, lsn ); let process = process_guard.take().unwrap(); @@ -597,13 +610,26 @@ impl PostgresRedoProcess { ); fs::remove_dir_all(&datadir)?; } + let pg_bin_dir_path = conf.pg_bin_dir(pg_version).map_err(|e| { + Error::new( + ErrorKind::Other, + format!("incorrect pg_bin_dir path: {}", e), + ) + })?; + let pg_lib_dir_path = conf.pg_lib_dir(pg_version).map_err(|e| { + Error::new( + ErrorKind::Other, + format!("incorrect pg_lib_dir path: {}", e), + ) + })?; + info!("running initdb in {}", datadir.display()); - let initdb = Command::new(conf.pg_bin_dir(pg_version).join("initdb")) + let initdb = Command::new(pg_bin_dir_path.join("initdb")) .args(&["-D", &datadir.to_string_lossy()]) .arg("-N") .env_clear() - .env("LD_LIBRARY_PATH", conf.pg_lib_dir(pg_version)) - .env("DYLD_LIBRARY_PATH", conf.pg_lib_dir(pg_version)) + .env("LD_LIBRARY_PATH", &pg_lib_dir_path) + .env("DYLD_LIBRARY_PATH", &pg_lib_dir_path) // macOS .close_fds() .output() .map_err(|e| Error::new(e.kind(), format!("failed to execute initdb: {e}")))?; @@ -629,14 +655,14 @@ impl PostgresRedoProcess { } // Start postgres itself - let mut child = Command::new(conf.pg_bin_dir(pg_version).join("postgres")) + let mut child = Command::new(pg_bin_dir_path.join("postgres")) .arg("--wal-redo") .stdin(Stdio::piped()) .stderr(Stdio::piped()) .stdout(Stdio::piped()) .env_clear() - .env("LD_LIBRARY_PATH", conf.pg_lib_dir(pg_version)) - .env("DYLD_LIBRARY_PATH", conf.pg_lib_dir(pg_version)) + .env("LD_LIBRARY_PATH", &pg_lib_dir_path) + .env("DYLD_LIBRARY_PATH", &pg_lib_dir_path) .env("PGDATA", &datadir) // The redo process is not trusted, so it runs in seccomp mode // (see seccomp in zenith_wal_redo.c). We have to make sure it doesn't diff --git a/pgxn/neon/libpqwalproposer.c b/pgxn/neon/libpqwalproposer.c index 1f739f3722..6b1e6a8bcc 100644 --- a/pgxn/neon/libpqwalproposer.c +++ b/pgxn/neon/libpqwalproposer.c @@ -10,51 +10,12 @@ struct WalProposerConn PGconn *pg_conn; bool is_nonblocking; /* whether the connection is non-blocking */ char *recvbuf; /* last received data from - * libpqprop_async_read */ + * walprop_async_read */ }; -/* Prototypes for exported functions */ -static char *libpqprop_error_message(WalProposerConn * conn); -static WalProposerConnStatusType libpqprop_status(WalProposerConn * conn); -static WalProposerConn * libpqprop_connect_start(char *conninfo); -static WalProposerConnectPollStatusType libpqprop_connect_poll(WalProposerConn * conn); -static bool libpqprop_send_query(WalProposerConn * conn, char *query); -static WalProposerExecStatusType libpqprop_get_query_result(WalProposerConn * conn); -static pgsocket libpqprop_socket(WalProposerConn * conn); -static int libpqprop_flush(WalProposerConn * conn); -static void libpqprop_finish(WalProposerConn * conn); -static PGAsyncReadResult libpqprop_async_read(WalProposerConn * conn, char **buf, int *amount); -static PGAsyncWriteResult libpqprop_async_write(WalProposerConn * conn, void const *buf, size_t size); -static bool libpqprop_blocking_write(WalProposerConn * conn, void const *buf, size_t size); - -static WalProposerFunctionsType PQWalProposerFunctions = -{ - libpqprop_error_message, - libpqprop_status, - libpqprop_connect_start, - libpqprop_connect_poll, - libpqprop_send_query, - libpqprop_get_query_result, - libpqprop_socket, - libpqprop_flush, - libpqprop_finish, - libpqprop_async_read, - libpqprop_async_write, - libpqprop_blocking_write, -}; - -/* Module initialization */ -void -pg_init_libpqwalproposer(void) -{ - if (WalProposerFunctions != NULL) - elog(ERROR, "libpqwalproposer already loaded"); - WalProposerFunctions = &PQWalProposerFunctions; -} - /* Helper function */ static bool -ensure_nonblocking_status(WalProposerConn * conn, bool is_nonblocking) +ensure_nonblocking_status(WalProposerConn *conn, bool is_nonblocking) { /* If we're already correctly blocking or nonblocking, all good */ if (is_nonblocking == conn->is_nonblocking) @@ -69,14 +30,14 @@ ensure_nonblocking_status(WalProposerConn * conn, bool is_nonblocking) } /* Exported function definitions */ -static char * -libpqprop_error_message(WalProposerConn * conn) +char * +walprop_error_message(WalProposerConn *conn) { return PQerrorMessage(conn->pg_conn); } -static WalProposerConnStatusType -libpqprop_status(WalProposerConn * conn) +WalProposerConnStatusType +walprop_status(WalProposerConn *conn) { switch (PQstatus(conn->pg_conn)) { @@ -89,8 +50,8 @@ libpqprop_status(WalProposerConn * conn) } } -static WalProposerConn * -libpqprop_connect_start(char *conninfo) +WalProposerConn * +walprop_connect_start(char *conninfo) { WalProposerConn *conn; PGconn *pg_conn; @@ -119,8 +80,8 @@ libpqprop_connect_start(char *conninfo) return conn; } -static WalProposerConnectPollStatusType -libpqprop_connect_poll(WalProposerConn * conn) +WalProposerConnectPollStatusType +walprop_connect_poll(WalProposerConn *conn) { WalProposerConnectPollStatusType return_val; @@ -160,8 +121,8 @@ libpqprop_connect_poll(WalProposerConn * conn) return return_val; } -static bool -libpqprop_send_query(WalProposerConn * conn, char *query) +bool +walprop_send_query(WalProposerConn *conn, char *query) { /* * We need to be in blocking mode for sending the query to run without @@ -177,8 +138,8 @@ libpqprop_send_query(WalProposerConn * conn, char *query) return true; } -static WalProposerExecStatusType -libpqprop_get_query_result(WalProposerConn * conn) +WalProposerExecStatusType +walprop_get_query_result(WalProposerConn *conn) { PGresult *result; WalProposerExecStatusType return_val; @@ -255,20 +216,20 @@ libpqprop_get_query_result(WalProposerConn * conn) return return_val; } -static pgsocket -libpqprop_socket(WalProposerConn * conn) +pgsocket +walprop_socket(WalProposerConn *conn) { return PQsocket(conn->pg_conn); } -static int -libpqprop_flush(WalProposerConn * conn) +int +walprop_flush(WalProposerConn *conn) { return (PQflush(conn->pg_conn)); } -static void -libpqprop_finish(WalProposerConn * conn) +void +walprop_finish(WalProposerConn *conn) { if (conn->recvbuf != NULL) PQfreemem(conn->recvbuf); @@ -282,8 +243,8 @@ libpqprop_finish(WalProposerConn * conn) * On success, the data is placed in *buf. It is valid until the next call * to this function. */ -static PGAsyncReadResult -libpqprop_async_read(WalProposerConn * conn, char **buf, int *amount) +PGAsyncReadResult +walprop_async_read(WalProposerConn *conn, char **buf, int *amount) { int result; @@ -353,8 +314,8 @@ libpqprop_async_read(WalProposerConn * conn, char **buf, int *amount) } } -static PGAsyncWriteResult -libpqprop_async_write(WalProposerConn * conn, void const *buf, size_t size) +PGAsyncWriteResult +walprop_async_write(WalProposerConn *conn, void const *buf, size_t size) { int result; @@ -408,8 +369,12 @@ libpqprop_async_write(WalProposerConn * conn, void const *buf, size_t size) } } -static bool -libpqprop_blocking_write(WalProposerConn * conn, void const *buf, size_t size) +/* + * This function is very similar to walprop_async_write. For more + * information, refer to the comments there. + */ +bool +walprop_blocking_write(WalProposerConn *conn, void const *buf, size_t size) { int result; @@ -417,10 +382,6 @@ libpqprop_blocking_write(WalProposerConn * conn, void const *buf, size_t size) if (!ensure_nonblocking_status(conn, false)) return false; - /* - * Ths function is very similar to libpqprop_async_write. For more - * information, refer to the comments there - */ if ((result = PQputCopyData(conn->pg_conn, buf, size)) == -1) return false; diff --git a/pgxn/neon/neon.c b/pgxn/neon/neon.c index 2a2a163ee8..5c98902554 100644 --- a/pgxn/neon/neon.c +++ b/pgxn/neon/neon.c @@ -32,7 +32,6 @@ void _PG_init(void) { pg_init_libpagestore(); - pg_init_libpqwalproposer(); pg_init_walproposer(); EmitWarningsOnPlaceholders("neon"); diff --git a/pgxn/neon/neon.h b/pgxn/neon/neon.h index dad9c1b508..6b9ba372fb 100644 --- a/pgxn/neon/neon.h +++ b/pgxn/neon/neon.h @@ -13,7 +13,6 @@ #define NEON_H extern void pg_init_libpagestore(void); -extern void pg_init_libpqwalproposer(void); extern void pg_init_walproposer(void); #endif /* NEON_H */ diff --git a/pgxn/neon/walproposer.c b/pgxn/neon/walproposer.c index fc0b660a64..29290fa736 100644 --- a/pgxn/neon/walproposer.c +++ b/pgxn/neon/walproposer.c @@ -79,9 +79,6 @@ bool am_wal_proposer; char *neon_timeline_walproposer = NULL; char *neon_tenant_walproposer = NULL; -/* Declared in walproposer.h, defined here, initialized in libpqwalproposer.c */ -WalProposerFunctionsType *WalProposerFunctions = NULL; - #define WAL_PROPOSER_SLOT_NAME "wal_proposer_slot" static int n_safekeepers = 0; @@ -438,10 +435,6 @@ WalProposerInitImpl(XLogRecPtr flushRecPtr, uint64 systemId) char *sep; char *port; - /* Load the libpq-specific functions */ - if (WalProposerFunctions == NULL) - elog(ERROR, "libpqwalproposer didn't initialize correctly"); - load_file("libpqwalreceiver", false); if (WalReceiverFunctions == NULL) elog(ERROR, "libpqwalreceiver didn't initialize correctly"); @@ -1471,12 +1464,6 @@ SendProposerElected(Safekeeper *sk) */ th = &sk->voteResponse.termHistory; - /* - * If any WAL is present on the sk, it must be authorized by some term. - * OTOH, without any WAL there are no term swiches in the log. - */ - Assert((th->n_entries == 0) == - (sk->voteResponse.flushLsn == InvalidXLogRecPtr)); /* We must start somewhere. */ Assert(propTermHistory.n_entries >= 1); diff --git a/pgxn/neon/walproposer.h b/pgxn/neon/walproposer.h index 051c7c02a6..e237947441 100644 --- a/pgxn/neon/walproposer.h +++ b/pgxn/neon/walproposer.h @@ -446,31 +446,31 @@ typedef enum } WalProposerConnStatusType; /* Re-exported PQerrorMessage */ -typedef char *(*walprop_error_message_fn) (WalProposerConn * conn); +extern char *walprop_error_message(WalProposerConn *conn); /* Re-exported PQstatus */ -typedef WalProposerConnStatusType(*walprop_status_fn) (WalProposerConn * conn); +extern WalProposerConnStatusType walprop_status(WalProposerConn *conn); /* Re-exported PQconnectStart */ -typedef WalProposerConn * (*walprop_connect_start_fn) (char *conninfo); +extern WalProposerConn * walprop_connect_start(char *conninfo); /* Re-exported PQconectPoll */ -typedef WalProposerConnectPollStatusType(*walprop_connect_poll_fn) (WalProposerConn * conn); +extern WalProposerConnectPollStatusType walprop_connect_poll(WalProposerConn *conn); /* Blocking wrapper around PQsendQuery */ -typedef bool (*walprop_send_query_fn) (WalProposerConn * conn, char *query); +extern bool walprop_send_query(WalProposerConn *conn, char *query); /* Wrapper around PQconsumeInput + PQisBusy + PQgetResult */ -typedef WalProposerExecStatusType(*walprop_get_query_result_fn) (WalProposerConn * conn); +extern WalProposerExecStatusType walprop_get_query_result(WalProposerConn *conn); /* Re-exported PQsocket */ -typedef pgsocket (*walprop_socket_fn) (WalProposerConn * conn); +extern pgsocket walprop_socket(WalProposerConn *conn); /* Wrapper around PQconsumeInput (if socket's read-ready) + PQflush */ -typedef int (*walprop_flush_fn) (WalProposerConn * conn); +extern int walprop_flush(WalProposerConn *conn); /* Re-exported PQfinish */ -typedef void (*walprop_finish_fn) (WalProposerConn * conn); +extern void walprop_finish(WalProposerConn *conn); /* * Ergonomic wrapper around PGgetCopyData @@ -486,9 +486,7 @@ typedef void (*walprop_finish_fn) (WalProposerConn * conn); * performs a bit of extra checking work that's always required and is normally * somewhat verbose. */ -typedef PGAsyncReadResult(*walprop_async_read_fn) (WalProposerConn * conn, - char **buf, - int *amount); +extern PGAsyncReadResult walprop_async_read(WalProposerConn *conn, char **buf, int *amount); /* * Ergonomic wrapper around PQputCopyData + PQflush @@ -497,69 +495,14 @@ typedef PGAsyncReadResult(*walprop_async_read_fn) (WalProposerConn * conn, * * For information on the meaning of return codes, refer to PGAsyncWriteResult. */ -typedef PGAsyncWriteResult(*walprop_async_write_fn) (WalProposerConn * conn, - void const *buf, - size_t size); +extern PGAsyncWriteResult walprop_async_write(WalProposerConn *conn, void const *buf, size_t size); /* * Blocking equivalent to walprop_async_write_fn * * Returns 'true' if successful, 'false' on failure. */ -typedef bool (*walprop_blocking_write_fn) (WalProposerConn * conn, void const *buf, size_t size); - -/* All libpqwalproposer exported functions collected together. */ -typedef struct WalProposerFunctionsType -{ - walprop_error_message_fn walprop_error_message; - walprop_status_fn walprop_status; - walprop_connect_start_fn walprop_connect_start; - walprop_connect_poll_fn walprop_connect_poll; - walprop_send_query_fn walprop_send_query; - walprop_get_query_result_fn walprop_get_query_result; - walprop_socket_fn walprop_socket; - walprop_flush_fn walprop_flush; - walprop_finish_fn walprop_finish; - walprop_async_read_fn walprop_async_read; - walprop_async_write_fn walprop_async_write; - walprop_blocking_write_fn walprop_blocking_write; -} WalProposerFunctionsType; - -/* Allow the above functions to be "called" with normal syntax */ -#define walprop_error_message(conn) \ - WalProposerFunctions->walprop_error_message(conn) -#define walprop_status(conn) \ - WalProposerFunctions->walprop_status(conn) -#define walprop_connect_start(conninfo) \ - WalProposerFunctions->walprop_connect_start(conninfo) -#define walprop_connect_poll(conn) \ - WalProposerFunctions->walprop_connect_poll(conn) -#define walprop_send_query(conn, query) \ - WalProposerFunctions->walprop_send_query(conn, query) -#define walprop_get_query_result(conn) \ - WalProposerFunctions->walprop_get_query_result(conn) -#define walprop_set_nonblocking(conn, arg) \ - WalProposerFunctions->walprop_set_nonblocking(conn, arg) -#define walprop_socket(conn) \ - WalProposerFunctions->walprop_socket(conn) -#define walprop_flush(conn) \ - WalProposerFunctions->walprop_flush(conn) -#define walprop_finish(conn) \ - WalProposerFunctions->walprop_finish(conn) -#define walprop_async_read(conn, buf, amount) \ - WalProposerFunctions->walprop_async_read(conn, buf, amount) -#define walprop_async_write(conn, buf, size) \ - WalProposerFunctions->walprop_async_write(conn, buf, size) -#define walprop_blocking_write(conn, buf, size) \ - WalProposerFunctions->walprop_blocking_write(conn, buf, size) - -/* - * The runtime location of the libpqwalproposer functions. - * - * This pointer is set by the initializer in libpqwalproposer, so that we - * can use it later. - */ -extern PGDLLIMPORT WalProposerFunctionsType * WalProposerFunctions; +extern bool walprop_blocking_write(WalProposerConn *conn, void const *buf, size_t size); extern uint64 BackpressureThrottlingTime(void); diff --git a/proxy/Cargo.toml b/proxy/Cargo.toml index 8049737989..395c22b8bc 100644 --- a/proxy/Cargo.toml +++ b/proxy/Cargo.toml @@ -7,9 +7,9 @@ edition = "2021" anyhow = "1.0" atty = "0.2.14" base64 = "0.13.0" -bstr = "0.2.17" +bstr = "1.0" bytes = { version = "1.0.1", features = ['serde'] } -clap = "3.0" +clap = "4.0" futures = "0.3.13" git-version = "0.3.5" hashbrown = "0.12" @@ -22,7 +22,11 @@ once_cell = "1.13.0" parking_lot = "0.12" pin-project-lite = "0.2.7" rand = "0.8.3" -reqwest = { version = "0.11", default-features = false, features = ["blocking", "json", "rustls-tls"] } +reqwest = { version = "0.11", default-features = false, features = [ + "blocking", + "json", + "rustls-tls", +] } routerify = "3" rustls = "0.20.0" rustls-pemfile = "1" @@ -33,13 +37,13 @@ sha2 = "0.10.2" socket2 = "0.4.4" thiserror = "1.0.30" tokio = { version = "1.17", features = ["macros"] } -tokio-postgres = { git = "https://github.com/neondatabase/rust-postgres.git", rev="d052ee8b86fff9897c77b0fe89ea9daba0e1fa38" } +tokio-postgres = { git = "https://github.com/neondatabase/rust-postgres.git", rev = "d052ee8b86fff9897c77b0fe89ea9daba0e1fa38" } tokio-rustls = "0.23.0" tracing = "0.1.36" tracing-subscriber = { version = "0.3", features = ["env-filter"] } url = "2.2.2" -uuid = { version = "0.8.2", features = ["v4", "serde"]} -x509-parser = "0.13.2" +uuid = { version = "1.2", features = ["v4", "serde"] } +x509-parser = "0.14" utils = { path = "../libs/utils" } metrics = { path = "../libs/metrics" } @@ -47,6 +51,6 @@ workspace_hack = { version = "0.1", path = "../workspace_hack" } [dev-dependencies] async-trait = "0.1" -rcgen = "0.8.14" -rstest = "0.12" +rcgen = "0.10" +rstest = "0.15" tokio-postgres-rustls = "0.9.0" diff --git a/proxy/src/auth/backend/console.rs b/proxy/src/auth/backend/console.rs index 7dbb173b88..cf99aa08ef 100644 --- a/proxy/src/auth/backend/console.rs +++ b/proxy/src/auth/backend/console.rs @@ -8,36 +8,20 @@ use crate::{ http, scram, stream::PqStream, }; +use futures::TryFutureExt; use serde::{Deserialize, Serialize}; use std::future::Future; use thiserror::Error; use tokio::io::{AsyncRead, AsyncWrite}; -use tracing::info; +use tracing::{error, info, info_span}; const REQUEST_FAILED: &str = "Console request failed"; #[derive(Debug, Error)] -pub enum TransportError { - #[error("Console responded with a malformed JSON: {0}")] - BadResponse(#[from] serde_json::Error), +#[error("{}", REQUEST_FAILED)] +pub struct TransportError(#[from] std::io::Error); - /// HTTP status (other than 200) returned by the console. - #[error("Console responded with an HTTP status: {0}")] - HttpStatus(reqwest::StatusCode), - - #[error(transparent)] - Io(#[from] std::io::Error), -} - -impl UserFacingError for TransportError { - fn to_string_client(&self) -> String { - use TransportError::*; - match self { - HttpStatus(_) => self.to_string(), - _ => REQUEST_FAILED.to_owned(), - } - } -} +impl UserFacingError for TransportError {} // Helps eliminate graceless `.map_err` calls without introducing another ctor. impl From for TransportError { @@ -162,15 +146,19 @@ impl<'a> Api<'a> { ]) .build()?; - info!(id = request_id, url = req.url().as_str(), "request"); - let resp = self.endpoint.execute(req).await?; - if !resp.status().is_success() { - return Err(TransportError::HttpStatus(resp.status()).into()); - } + let span = info_span!("http", id = request_id, url = req.url().as_str()); + info!(parent: &span, "request auth info"); + let msg = self + .endpoint + .checked_execute(req) + .and_then(|r| r.json::()) + .await + .map_err(|e| { + error!(parent: &span, "{e}"); + e + })?; - let response: GetRoleSecretResponse = serde_json::from_str(&resp.text().await?)?; - - scram::ServerSecret::parse(&response.role_secret) + scram::ServerSecret::parse(&msg.role_secret) .map(AuthInfo::Scram) .ok_or(GetAuthInfoError::BadSecret) } @@ -189,17 +177,21 @@ impl<'a> Api<'a> { ]) .build()?; - info!(id = request_id, url = req.url().as_str(), "request"); - let resp = self.endpoint.execute(req).await?; - if !resp.status().is_success() { - return Err(TransportError::HttpStatus(resp.status()).into()); - } - - let response: GetWakeComputeResponse = serde_json::from_str(&resp.text().await?)?; + let span = info_span!("http", id = request_id, url = req.url().as_str()); + info!(parent: &span, "request wake-up"); + let msg = self + .endpoint + .checked_execute(req) + .and_then(|r| r.json::()) + .await + .map_err(|e| { + error!(parent: &span, "{e}"); + e + })?; // Unfortunately, ownership won't let us use `Option::ok_or` here. - let (host, port) = match parse_host_port(&response.address) { - None => return Err(WakeComputeError::BadComputeAddress(response.address)), + let (host, port) = match parse_host_port(&msg.address) { + None => return Err(WakeComputeError::BadComputeAddress(msg.address)), Some(x) => x, }; diff --git a/proxy/src/auth/backend/link.rs b/proxy/src/auth/backend/link.rs index 863ed53645..c8ca418144 100644 --- a/proxy/src/auth/backend/link.rs +++ b/proxy/src/auth/backend/link.rs @@ -1,7 +1,7 @@ use crate::{auth, compute, error::UserFacingError, stream::PqStream, waiters}; use thiserror::Error; use tokio::io::{AsyncRead, AsyncWrite}; -use tracing::info; +use tracing::{info, info_span}; use utils::pq_proto::{BeMessage as Be, BeParameterStatusMessage}; #[derive(Debug, Error)] @@ -51,11 +51,12 @@ pub async fn handle_user( client: &mut PqStream, ) -> auth::Result { let psql_session_id = new_psql_session_id(); + let span = info_span!("link", psql_session_id = &psql_session_id); let greeting = hello_message(link_uri, &psql_session_id); let db_info = super::with_waiter(psql_session_id, |waiter| async { // Give user a URL to spawn a new database. - info!("sending the auth URL to the user"); + info!(parent: &span, "sending the auth URL to the user"); client .write_message_noflush(&Be::AuthenticationOk)? .write_message_noflush(&BeParameterStatusMessage::encoding())? @@ -63,7 +64,7 @@ pub async fn handle_user( .await?; // Wait for web console response (see `mgmt`). - info!("waiting for console's reply..."); + info!(parent: &span, "waiting for console's reply..."); waiter.await?.map_err(LinkAuthError::AuthFailed) }) .await?; diff --git a/proxy/src/http.rs b/proxy/src/http.rs index dbeb3dc784..6f9145678b 100644 --- a/proxy/src/http.rs +++ b/proxy/src/http.rs @@ -17,6 +17,7 @@ impl Endpoint { Self { endpoint, client } } + #[inline(always)] pub fn url(&self) -> &ApiUrl { &self.endpoint } @@ -36,6 +37,16 @@ impl Endpoint { ) -> Result { self.client.execute(request).await } + + /// Execute a [request](reqwest::Request) and raise an error if status != 200. + pub async fn checked_execute( + &self, + request: reqwest::Request, + ) -> Result { + self.execute(request) + .await + .and_then(|r| r.error_for_status()) + } } #[cfg(test)] diff --git a/proxy/src/main.rs b/proxy/src/main.rs index 2e6c365d32..2055616a6e 100644 --- a/proxy/src/main.rs +++ b/proxy/src/main.rs @@ -23,6 +23,7 @@ use anyhow::{bail, Context}; use clap::{self, Arg}; use config::ProxyConfig; use futures::FutureExt; +use metrics::set_build_info_metric; use std::{borrow::Cow, future::Future, net::SocketAddr}; use tokio::{net::TcpListener, task::JoinError}; use tracing::info; @@ -44,98 +45,43 @@ async fn main() -> anyhow::Result<()> { .with_target(false) .init(); - let arg_matches = clap::App::new("Neon proxy/router") - .version(GIT_VERSION) - .arg( - Arg::new("proxy") - .short('p') - .long("proxy") - .takes_value(true) - .help("listen for incoming client connections on ip:port") - .default_value("127.0.0.1:4432"), - ) - .arg( - Arg::new("auth-backend") - .long("auth-backend") - .takes_value(true) - .possible_values(["console", "postgres", "link"]) - .default_value("link"), - ) - .arg( - Arg::new("mgmt") - .short('m') - .long("mgmt") - .takes_value(true) - .help("listen for management callback connection on ip:port") - .default_value("127.0.0.1:7000"), - ) - .arg( - Arg::new("http") - .short('h') - .long("http") - .takes_value(true) - .help("listen for incoming http connections (metrics, etc) on ip:port") - .default_value("127.0.0.1:7001"), - ) - .arg( - Arg::new("uri") - .short('u') - .long("uri") - .takes_value(true) - .help("redirect unauthenticated users to the given uri in case of link auth") - .default_value("http://localhost:3000/psql_session/"), - ) - .arg( - Arg::new("auth-endpoint") - .short('a') - .long("auth-endpoint") - .takes_value(true) - .help("cloud API endpoint for authenticating users") - .default_value("http://localhost:3000/authenticate_proxy_request/"), - ) - .arg( - Arg::new("tls-key") - .short('k') - .long("tls-key") - .alias("ssl-key") // backwards compatibility - .takes_value(true) - .help("path to TLS key for client postgres connections"), - ) - .arg( - Arg::new("tls-cert") - .short('c') - .long("tls-cert") - .alias("ssl-cert") // backwards compatibility - .takes_value(true) - .help("path to TLS cert for client postgres connections"), - ) - .get_matches(); + let arg_matches = cli().get_matches(); let tls_config = match ( - arg_matches.value_of("tls-key"), - arg_matches.value_of("tls-cert"), + arg_matches.get_one::("tls-key"), + arg_matches.get_one::("tls-cert"), ) { (Some(key_path), Some(cert_path)) => Some(config::configure_tls(key_path, cert_path)?), (None, None) => None, _ => bail!("either both or neither tls-key and tls-cert must be specified"), }; - let proxy_address: SocketAddr = arg_matches.value_of("proxy").unwrap().parse()?; - let mgmt_address: SocketAddr = arg_matches.value_of("mgmt").unwrap().parse()?; - let http_address: SocketAddr = arg_matches.value_of("http").unwrap().parse()?; + let proxy_address: SocketAddr = arg_matches.get_one::("proxy").unwrap().parse()?; + let mgmt_address: SocketAddr = arg_matches.get_one::("mgmt").unwrap().parse()?; + let http_address: SocketAddr = arg_matches.get_one::("http").unwrap().parse()?; - let auth_backend = match arg_matches.value_of("auth-backend").unwrap() { + let auth_backend = match arg_matches + .get_one::("auth-backend") + .unwrap() + .as_str() + { "console" => { - let url = arg_matches.value_of("auth-endpoint").unwrap().parse()?; + let url = arg_matches + .get_one::("auth-endpoint") + .unwrap() + .parse()?; let endpoint = http::Endpoint::new(url, reqwest::Client::new()); auth::BackendType::Console(Cow::Owned(endpoint), ()) } "postgres" => { - let url = arg_matches.value_of("auth-endpoint").unwrap().parse()?; + let url = arg_matches + .get_one::("auth-endpoint") + .unwrap() + .parse()?; auth::BackendType::Postgres(Cow::Owned(url), ()) } "link" => { - let url = arg_matches.value_of("uri").unwrap().parse()?; + let url = arg_matches.get_one::("uri").unwrap().parse()?; auth::BackendType::Link(Cow::Owned(url)) } other => bail!("unsupported auth backend: {other}"), @@ -166,9 +112,75 @@ async fn main() -> anyhow::Result<()> { ] .map(flatten_err); + set_build_info_metric(GIT_VERSION); // This will block until all tasks have completed. // Furthermore, the first one to fail will cancel the rest. let _: Vec<()> = futures::future::try_join_all(tasks).await?; Ok(()) } + +fn cli() -> clap::Command { + clap::Command::new("Neon proxy/router") + .disable_help_flag(true) + .version(GIT_VERSION) + .arg( + Arg::new("proxy") + .short('p') + .long("proxy") + .help("listen for incoming client connections on ip:port") + .default_value("127.0.0.1:4432"), + ) + .arg( + Arg::new("auth-backend") + .long("auth-backend") + .value_parser(["console", "postgres", "link"]) + .default_value("link"), + ) + .arg( + Arg::new("mgmt") + .short('m') + .long("mgmt") + .help("listen for management callback connection on ip:port") + .default_value("127.0.0.1:7000"), + ) + .arg( + Arg::new("http") + .long("http") + .help("listen for incoming http connections (metrics, etc) on ip:port") + .default_value("127.0.0.1:7001"), + ) + .arg( + Arg::new("uri") + .short('u') + .long("uri") + .help("redirect unauthenticated users to the given uri in case of link auth") + .default_value("http://localhost:3000/psql_session/"), + ) + .arg( + Arg::new("auth-endpoint") + .short('a') + .long("auth-endpoint") + .help("cloud API endpoint for authenticating users") + .default_value("http://localhost:3000/authenticate_proxy_request/"), + ) + .arg( + Arg::new("tls-key") + .short('k') + .long("tls-key") + .alias("ssl-key") // backwards compatibility + .help("path to TLS key for client postgres connections"), + ) + .arg( + Arg::new("tls-cert") + .short('c') + .long("tls-cert") + .alias("ssl-cert") // backwards compatibility + .help("path to TLS cert for client postgres connections"), + ) +} + +#[test] +fn verify_cli() { + cli().debug_assert(); +} diff --git a/proxy/src/proxy.rs b/proxy/src/proxy.rs index 5dcaa000cf..889445239a 100644 --- a/proxy/src/proxy.rs +++ b/proxy/src/proxy.rs @@ -1,7 +1,7 @@ use crate::auth; use crate::cancellation::{self, CancelMap}; use crate::config::{ProxyConfig, TlsConfig}; -use crate::stream::{MetricsStream, PqStream, Stream}; +use crate::stream::{MeasuredStream, PqStream, Stream}; use anyhow::{bail, Context}; use futures::TryFutureExt; use metrics::{register_int_counter, IntCounter}; @@ -64,7 +64,7 @@ pub async fn task_main( let cancel_map = Arc::new(CancelMap::default()); loop { let (socket, peer_addr) = listener.accept().await?; - info!("accepted connection from {peer_addr}"); + info!("accepted postgres client connection from {peer_addr}"); let session_id = uuid::Uuid::new_v4(); let cancel_map = Arc::clone(&cancel_map); @@ -270,8 +270,8 @@ impl Client<'_, S> { // Starting from here we only proxy the client's traffic. info!("performing the proxy pass..."); - let mut db = MetricsStream::new(db.stream, inc_proxied); - let mut client = MetricsStream::new(stream.into_inner(), inc_proxied); + let mut db = MeasuredStream::new(db.stream, inc_proxied); + let mut client = MeasuredStream::new(stream.into_inner(), inc_proxied); let _ = tokio::io::copy_bidirectional(&mut client, &mut db).await?; Ok(()) diff --git a/proxy/src/stream.rs b/proxy/src/stream.rs index 54ff8bcc07..2a224944e2 100644 --- a/proxy/src/stream.rs +++ b/proxy/src/stream.rs @@ -231,7 +231,7 @@ impl AsyncWrite for Stream { pin_project! { /// This stream tracks all writes and calls user provided /// callback when the underlying stream is flushed. - pub struct MetricsStream { + pub struct MeasuredStream { #[pin] stream: S, write_count: usize, @@ -239,7 +239,7 @@ pin_project! { } } -impl MetricsStream { +impl MeasuredStream { pub fn new(stream: S, inc_write_count: W) -> Self { Self { stream, @@ -249,7 +249,7 @@ impl MetricsStream { } } -impl AsyncRead for MetricsStream { +impl AsyncRead for MeasuredStream { fn poll_read( self: Pin<&mut Self>, context: &mut task::Context<'_>, @@ -259,7 +259,7 @@ impl AsyncRead for MetricsStream { } } -impl AsyncWrite for MetricsStream { +impl AsyncWrite for MeasuredStream { fn poll_write( self: Pin<&mut Self>, context: &mut task::Context<'_>, diff --git a/run_clippy.sh b/run_clippy.sh index 9feb8de4ea..bf770432d0 100755 --- a/run_clippy.sh +++ b/run_clippy.sh @@ -13,7 +13,7 @@ # avoid running regular linting script that checks every feature. if [[ "$OSTYPE" == "darwin"* ]]; then # no extra features to test currently, add more here when needed - cargo clippy --locked --all --all-targets -- -A unknown_lints -D warnings + cargo clippy --locked --all --all-targets --features testing -- -A unknown_lints -D warnings else # * `-A unknown_lints` – do not warn about unknown lint suppressions # that people with newer toolchains might use diff --git a/safekeeper/Cargo.toml b/safekeeper/Cargo.toml index cb1cecade9..64c541ddef 100644 --- a/safekeeper/Cargo.toml +++ b/safekeeper/Cargo.toml @@ -11,7 +11,7 @@ hyper = "0.14" fs2 = "0.4.3" serde_json = "1" tracing = "0.1.27" -clap = "3.0" +clap = "4.0" daemonize = "0.4.1" tokio = { version = "1.17", features = ["macros", "fs"] } postgres-protocol = { git = "https://github.com/neondatabase/rust-postgres.git", rev="d052ee8b86fff9897c77b0fe89ea9daba0e1fa38" } @@ -22,14 +22,14 @@ humantime = "2.1.0" url = "2.2.2" signal-hook = "0.3.10" serde = { version = "1.0", features = ["derive"] } -serde_with = "1.12.0" +serde_with = "2.0" hex = "0.4.3" const_format = "0.2.21" tokio-postgres = { git = "https://github.com/neondatabase/rust-postgres.git", rev="d052ee8b86fff9897c77b0fe89ea9daba0e1fa38" } git-version = "0.3.5" async-trait = "0.1" once_cell = "1.13.0" -toml_edit = { version = "0.13", features = ["easy"] } +toml_edit = { version = "0.14", features = ["easy"] } thiserror = "1" parking_lot = "0.12.1" diff --git a/safekeeper/src/bin/safekeeper.rs b/safekeeper/src/bin/safekeeper.rs index e4545dad87..9422b55d60 100644 --- a/safekeeper/src/bin/safekeeper.rs +++ b/safekeeper/src/bin/safekeeper.rs @@ -2,7 +2,7 @@ // Main entry point for the safekeeper executable // use anyhow::{bail, Context, Result}; -use clap::{App, Arg}; +use clap::{value_parser, Arg, ArgAction, Command}; use const_format::formatcp; use daemonize::Daemonize; use fs2::FileExt; @@ -17,6 +17,7 @@ use toml_edit::Document; use tracing::*; use url::{ParseError, Url}; +use metrics::set_build_info_metric; use safekeeper::broker; use safekeeper::control_file; use safekeeper::defaults::{ @@ -39,145 +40,44 @@ const ID_FILE_NAME: &str = "safekeeper.id"; project_git_version!(GIT_VERSION); fn main() -> anyhow::Result<()> { - let arg_matches = App::new("Neon safekeeper") - .about("Store WAL stream to local file system and push it to WAL receivers") - .version(GIT_VERSION) - .arg( - Arg::new("datadir") - .short('D') - .long("dir") - .takes_value(true) - .help("Path to the safekeeper data directory"), - ) - .arg( - Arg::new("init") - .long("init") - .takes_value(false) - .help("Initialize safekeeper with ID"), - ) - .arg( - Arg::new("listen-pg") - .short('l') - .long("listen-pg") - .alias("listen") // for compatibility - .takes_value(true) - .help(formatcp!("listen for incoming WAL data connections on ip:port (default: {DEFAULT_PG_LISTEN_ADDR})")), - ) - .arg( - Arg::new("listen-http") - .long("listen-http") - .takes_value(true) - .help(formatcp!("http endpoint address for metrics on ip:port (default: {DEFAULT_HTTP_LISTEN_ADDR})")), - ) - // FIXME this argument is no longer needed since pageserver address is forwarded from compute. - // However because this argument is in use by console's e2e tests let's keep it for now and remove separately. - // So currently it is a noop. - .arg( - Arg::new("pageserver") - .short('p') - .long("pageserver") - .takes_value(true), - ) - .arg( - Arg::new("recall") - .long("recall") - .takes_value(true) - .help("Period for requestion pageserver to call for replication"), - ) - .arg( - Arg::new("daemonize") - .short('d') - .long("daemonize") - .takes_value(false) - .help("Run in the background"), - ) - .arg( - Arg::new("no-sync") - .short('n') - .long("no-sync") - .takes_value(false) - .help("Do not wait for changes to be written safely to disk"), - ) - .arg( - Arg::new("dump-control-file") - .long("dump-control-file") - .takes_value(true) - .help("Dump control file at path specified by this argument and exit"), - ) - .arg( - Arg::new("id").long("id").takes_value(true).help("safekeeper node id: integer") - ).arg( - Arg::new("broker-endpoints") - .long("broker-endpoints") - .takes_value(true) - .help("a comma separated broker (etcd) endpoints for storage nodes coordination, e.g. 'http://127.0.0.1:2379'"), - ) - .arg( - Arg::new("broker-etcd-prefix") - .long("broker-etcd-prefix") - .takes_value(true) - .help("a prefix to always use when polling/pusing data in etcd from this safekeeper"), - ) - .arg( - Arg::new("wal-backup-threads").long("backup-threads").takes_value(true).help(formatcp!("number of threads for wal backup (default {DEFAULT_WAL_BACKUP_RUNTIME_THREADS}")), - ).arg( - Arg::new("remote-storage") - .long("remote-storage") - .takes_value(true) - .help("Remote storage configuration for WAL backup (offloading to s3) as TOML inline table, e.g. {\"max_concurrent_syncs\" = 17, \"max_sync_errors\": 13, \"bucket_name\": \"\", \"bucket_region\":\"\", \"concurrency_limit\": 119}.\nSafekeeper offloads WAL to [prefix_in_bucket/]//, mirroring structure on the file system.") - ) - .arg( - Arg::new("enable-wal-backup") - .long("enable-wal-backup") - .takes_value(true) - .default_value("true") - .default_missing_value("true") - .help("Enable/disable WAL backup to s3. When disabled, safekeeper removes WAL ignoring WAL backup horizon."), - ) - .arg( - Arg::new("auth-validation-public-key-path") - .long("auth-validation-public-key-path") - .takes_value(true) - .help("Path to an RSA .pem public key which is used to check JWT tokens") - ) - .get_matches(); + let arg_matches = cli().get_matches(); - if let Some(addr) = arg_matches.value_of("dump-control-file") { + if let Some(addr) = arg_matches.get_one::("dump-control-file") { let state = control_file::FileStorage::load_control_file(Path::new(addr))?; let json = serde_json::to_string(&state)?; - print!("{}", json); + print!("{json}"); return Ok(()); } let mut conf = SafeKeeperConf::default(); - if let Some(dir) = arg_matches.value_of("datadir") { + if let Some(dir) = arg_matches.get_one::("datadir") { // change into the data directory. - std::env::set_current_dir(PathBuf::from(dir))?; + std::env::set_current_dir(dir)?; } - if arg_matches.is_present("no-sync") { + if arg_matches.get_flag("no-sync") { conf.no_sync = true; } - if arg_matches.is_present("daemonize") { + if arg_matches.get_flag("daemonize") { conf.daemonize = true; } - if let Some(addr) = arg_matches.value_of("listen-pg") { - conf.listen_pg_addr = addr.to_owned(); + if let Some(addr) = arg_matches.get_one::("listen-pg") { + conf.listen_pg_addr = addr.to_string(); } - if let Some(addr) = arg_matches.value_of("listen-http") { - conf.listen_http_addr = addr.to_owned(); + if let Some(addr) = arg_matches.get_one::("listen-http") { + conf.listen_http_addr = addr.to_string(); } - if let Some(recall) = arg_matches.value_of("recall") { + if let Some(recall) = arg_matches.get_one::("recall") { conf.recall_period = humantime::parse_duration(recall)?; } let mut given_id = None; - if let Some(given_id_str) = arg_matches.value_of("id") { + if let Some(given_id_str) = arg_matches.get_one::("id") { given_id = Some(NodeId( given_id_str .parse() @@ -185,20 +85,20 @@ fn main() -> anyhow::Result<()> { )); } - if let Some(addr) = arg_matches.value_of("broker-endpoints") { + if let Some(addr) = arg_matches.get_one::("broker-endpoints") { let collected_ep: Result, ParseError> = addr.split(',').map(Url::parse).collect(); conf.broker_endpoints = collected_ep.context("Failed to parse broker endpoint urls")?; } - if let Some(prefix) = arg_matches.value_of("broker-etcd-prefix") { + if let Some(prefix) = arg_matches.get_one::("broker-etcd-prefix") { conf.broker_etcd_prefix = prefix.to_string(); } - if let Some(backup_threads) = arg_matches.value_of("wal-backup-threads") { + if let Some(backup_threads) = arg_matches.get_one::("wal-backup-threads") { conf.backup_runtime_threads = backup_threads .parse() .with_context(|| format!("Failed to parse backup threads {}", backup_threads))?; } - if let Some(storage_conf) = arg_matches.value_of("remote-storage") { + if let Some(storage_conf) = arg_matches.get_one::("remote-storage") { // funny toml doesn't consider plain inline table as valid document, so wrap in a key to parse let storage_conf_toml = format!("remote_storage = {}", storage_conf); let parsed_toml = storage_conf_toml.parse::()?; // parse @@ -207,16 +107,16 @@ fn main() -> anyhow::Result<()> { } // Seems like there is no better way to accept bool values explicitly in clap. conf.wal_backup_enabled = arg_matches - .value_of("enable-wal-backup") + .get_one::("enable-wal-backup") .unwrap() .parse() .context("failed to parse bool enable-s3-offload bool")?; conf.auth_validation_public_key_path = arg_matches - .value_of("auth-validation-public-key-path") + .get_one::("auth-validation-public-key-path") .map(PathBuf::from); - start_safekeeper(conf, given_id, arg_matches.is_present("init")) + start_safekeeper(conf, given_id, arg_matches.get_flag("init")) } fn start_safekeeper(mut conf: SafeKeeperConf, given_id: Option, init: bool) -> Result<()> { @@ -363,6 +263,7 @@ fn start_safekeeper(mut conf: SafeKeeperConf, given_id: Option, init: bo })?, ); + set_build_info_metric(GIT_VERSION); // TODO: put more thoughts into handling of failed threads // We probably should restart them. @@ -422,3 +323,102 @@ fn set_id(conf: &mut SafeKeeperConf, given_id: Option) -> Result<()> { conf.my_id = my_id; Ok(()) } + +fn cli() -> Command { + Command::new("Neon safekeeper") + .about("Store WAL stream to local file system and push it to WAL receivers") + .version(GIT_VERSION) + .arg( + Arg::new("datadir") + .short('D') + .long("dir") + .value_parser(value_parser!(PathBuf)) + .help("Path to the safekeeper data directory"), + ) + .arg( + Arg::new("init") + .long("init") + .action(ArgAction::SetTrue) + .help("Initialize safekeeper with ID"), + ) + .arg( + Arg::new("listen-pg") + .short('l') + .long("listen-pg") + .alias("listen") // for compatibility + .help(formatcp!("listen for incoming WAL data connections on ip:port (default: {DEFAULT_PG_LISTEN_ADDR})")), + ) + .arg( + Arg::new("listen-http") + .long("listen-http") + .help(formatcp!("http endpoint address for metrics on ip:port (default: {DEFAULT_HTTP_LISTEN_ADDR})")), + ) + // FIXME this argument is no longer needed since pageserver address is forwarded from compute. + // However because this argument is in use by console's e2e tests let's keep it for now and remove separately. + // So currently it is a noop. + .arg( + Arg::new("pageserver") + .short('p') + .long("pageserver"), + ) + .arg( + Arg::new("recall") + .long("recall") + .help("Period for requestion pageserver to call for replication"), + ) + .arg( + Arg::new("daemonize") + .short('d') + .long("daemonize") + .action(ArgAction::SetTrue) + .help("Run in the background"), + ) + .arg( + Arg::new("no-sync") + .short('n') + .long("no-sync") + .action(ArgAction::SetTrue) + .help("Do not wait for changes to be written safely to disk"), + ) + .arg( + Arg::new("dump-control-file") + .long("dump-control-file") + .help("Dump control file at path specified by this argument and exit"), + ) + .arg( + Arg::new("id").long("id").help("safekeeper node id: integer") + ).arg( + Arg::new("broker-endpoints") + .long("broker-endpoints") + .help("a comma separated broker (etcd) endpoints for storage nodes coordination, e.g. 'http://127.0.0.1:2379'"), + ) + .arg( + Arg::new("broker-etcd-prefix") + .long("broker-etcd-prefix") + .help("a prefix to always use when polling/pusing data in etcd from this safekeeper"), + ) + .arg( + Arg::new("wal-backup-threads").long("backup-threads").help(formatcp!("number of threads for wal backup (default {DEFAULT_WAL_BACKUP_RUNTIME_THREADS}")), + ).arg( + Arg::new("remote-storage") + .long("remote-storage") + .help("Remote storage configuration for WAL backup (offloading to s3) as TOML inline table, e.g. {\"max_concurrent_syncs\" = 17, \"max_sync_errors\": 13, \"bucket_name\": \"\", \"bucket_region\":\"\", \"concurrency_limit\": 119}.\nSafekeeper offloads WAL to [prefix_in_bucket/]//, mirroring structure on the file system.") + ) + .arg( + Arg::new("enable-wal-backup") + .long("enable-wal-backup") + .default_value("true") + .default_missing_value("true") + .help("Enable/disable WAL backup to s3. When disabled, safekeeper removes WAL ignoring WAL backup horizon."), + ) + .arg( + Arg::new("auth-validation-public-key-path") + .long("auth-validation-public-key-path") + .help("Path to an RSA .pem public key which is used to check JWT tokens") + ) +} + +#[test] +fn verify_cli() { + cli().debug_assert(); +} diff --git a/safekeeper/src/http/routes.rs b/safekeeper/src/http/routes.rs index 43c0a17f84..6efd09c7e2 100644 --- a/safekeeper/src/http/routes.rs +++ b/safekeeper/src/http/routes.rs @@ -1,8 +1,8 @@ -use anyhow::anyhow; use hyper::{Body, Request, Response, StatusCode, Uri}; use anyhow::Context; use once_cell::sync::Lazy; +use postgres_ffi::WAL_SEGMENT_SIZE; use serde::Serialize; use serde::Serializer; use std::collections::{HashMap, HashSet}; @@ -10,6 +10,7 @@ use std::fmt::Display; use std::sync::Arc; use tokio::task::JoinError; +use crate::safekeeper::ServerInfo; use crate::safekeeper::Term; use crate::safekeeper::TermHistory; @@ -77,6 +78,7 @@ struct TimelineStatus { #[serde(serialize_with = "display_serialize")] timeline_id: TimelineId, acceptor_state: AcceptorStateStatus, + pg_info: ServerInfo, #[serde(serialize_with = "display_serialize")] flush_lsn: Lsn, #[serde(serialize_with = "display_serialize")] @@ -121,6 +123,7 @@ async fn timeline_status_handler(request: Request) -> Result) -> Result Result ReceiveWalConn<'pg> { system_id: greeting.system_id, wal_seg_size: greeting.wal_seg_size, }; - GlobalTimelines::create(spg.ttid, server_info)? + GlobalTimelines::create(spg.ttid, server_info, Lsn::INVALID, Lsn::INVALID)? } _ => bail!("unexpected message {:?} instead of greeting", next_msg), }; diff --git a/safekeeper/src/safekeeper.rs b/safekeeper/src/safekeeper.rs index 7869aa8b3a..7b11aaf92a 100644 --- a/safekeeper/src/safekeeper.rs +++ b/safekeeper/src/safekeeper.rs @@ -222,6 +222,8 @@ impl SafeKeeperState { ttid: &TenantTimelineId, server_info: ServerInfo, peers: Vec, + commit_lsn: Lsn, + local_start_lsn: Lsn, ) -> SafeKeeperState { SafeKeeperState { tenant_id: ttid.tenant_id, @@ -233,10 +235,10 @@ impl SafeKeeperState { server: server_info, proposer_uuid: [0; 16], timeline_start_lsn: Lsn(0), - local_start_lsn: Lsn(0), - commit_lsn: Lsn(0), - backup_lsn: Lsn::INVALID, - peer_horizon_lsn: Lsn(0), + local_start_lsn, + commit_lsn, + backup_lsn: local_start_lsn, + peer_horizon_lsn: local_start_lsn, remote_consistent_lsn: Lsn(0), peers: Peers(peers.iter().map(|p| (*p, PeerInfo::new())).collect()), } @@ -252,6 +254,8 @@ impl SafeKeeperState { wal_seg_size: 0, }, vec![], + Lsn::INVALID, + Lsn::INVALID, ) } } @@ -740,7 +744,8 @@ where "setting timeline_start_lsn to {:?}", state.timeline_start_lsn ); - + } + if state.local_start_lsn == Lsn(0) { state.local_start_lsn = msg.start_streaming_at; info!("setting local_start_lsn to {:?}", state.local_start_lsn); } diff --git a/safekeeper/src/timeline.rs b/safekeeper/src/timeline.rs index dc7503af65..3fb77bf582 100644 --- a/safekeeper/src/timeline.rs +++ b/safekeeper/src/timeline.rs @@ -107,6 +107,14 @@ impl SharedState { bail!(TimelineError::UninitialinzedPgVersion(*ttid)); } + if state.commit_lsn < state.local_start_lsn { + bail!( + "commit_lsn {} is higher than local_start_lsn {}", + state.commit_lsn, + state.local_start_lsn + ); + } + // We don't want to write anything to disk, because we may have existing timeline there. // These functions should not change anything on disk. let control_store = control_file::FileStorage::create_new(ttid, conf, state)?; @@ -286,7 +294,7 @@ pub struct Timeline { /// Sending here asks for wal backup launcher attention (start/stop /// offloading). Sending ttid instead of concrete command allows to do /// sending without timeline lock. - wal_backup_launcher_tx: Sender, + pub wal_backup_launcher_tx: Sender, /// Used to broadcast commit_lsn updates to all background jobs. commit_lsn_watch_tx: watch::Sender, @@ -339,10 +347,12 @@ impl Timeline { ttid: TenantTimelineId, wal_backup_launcher_tx: Sender, server_info: ServerInfo, + commit_lsn: Lsn, + local_start_lsn: Lsn, ) -> Result { let (commit_lsn_watch_tx, commit_lsn_watch_rx) = watch::channel(Lsn::INVALID); let (cancellation_tx, cancellation_rx) = watch::channel(false); - let state = SafeKeeperState::new(&ttid, server_info, vec![]); + let state = SafeKeeperState::new(&ttid, server_info, vec![], commit_lsn, local_start_lsn); Ok(Timeline { ttid, @@ -381,6 +391,7 @@ impl Timeline { match || -> Result<()> { shared_state.sk.persist()?; // TODO: add more initialization steps here + shared_state.update_status(self.ttid); Ok(()) }() { Ok(_) => Ok(()), diff --git a/safekeeper/src/timelines_global_map.rs b/safekeeper/src/timelines_global_map.rs index cf99a243d7..a5d373a1da 100644 --- a/safekeeper/src/timelines_global_map.rs +++ b/safekeeper/src/timelines_global_map.rs @@ -15,6 +15,7 @@ use std::sync::{Arc, Mutex, MutexGuard}; use tokio::sync::mpsc::Sender; use tracing::*; use utils::id::{TenantId, TenantTimelineId, TimelineId}; +use utils::lsn::Lsn; struct GlobalTimelinesState { timelines: HashMap>, @@ -153,7 +154,12 @@ impl GlobalTimelines { /// Create a new timeline with the given id. If the timeline already exists, returns /// an existing timeline. - pub fn create(ttid: TenantTimelineId, server_info: ServerInfo) -> Result> { + pub fn create( + ttid: TenantTimelineId, + server_info: ServerInfo, + commit_lsn: Lsn, + local_start_lsn: Lsn, + ) -> Result> { let (conf, wal_backup_launcher_tx) = { let state = TIMELINES_STATE.lock().unwrap(); if let Ok(timeline) = state.get(&ttid) { @@ -170,6 +176,8 @@ impl GlobalTimelines { ttid, wal_backup_launcher_tx, server_info, + commit_lsn, + local_start_lsn, )?); // Take a lock and finish the initialization holding this mutex. No other threads @@ -190,6 +198,9 @@ impl GlobalTimelines { Ok(_) => { // We are done with bootstrap, release the lock, return the timeline. drop(shared_state); + timeline + .wal_backup_launcher_tx + .blocking_send(timeline.ttid)?; Ok(timeline) } Err(e) => { diff --git a/scripts/export_import_between_pageservers.py b/scripts/export_import_between_pageservers.py index 6f6c3864dd..152ce40cea 100755 --- a/scripts/export_import_between_pageservers.py +++ b/scripts/export_import_between_pageservers.py @@ -317,13 +317,13 @@ def remote_consistent_lsn( ) -> int: detail = pageserver_http_client.timeline_detail(tenant, timeline) - if detail["remote"] is None: + lsn_str = detail["remote_consistent_lsn"] + if lsn_str is None: # No remote information at all. This happens right after creating # a timeline, before any part of it has been uploaded to remote # storage yet. return 0 else: - lsn_str = detail["remote"]["remote_consistent_lsn"] assert isinstance(lsn_str, str) return lsn_from_hex(lsn_str) @@ -577,7 +577,7 @@ def main(args: argparse.Namespace): args.work_dir, f"{timeline['tenant_id']}_{timeline['timeline_id']}.tar" ) - pg_version = timeline["local"]["pg_version"] + pg_version = timeline["pg_version"] # Export timeline from old pageserver if args.only_import is False: diff --git a/scripts/reformat b/scripts/reformat new file mode 100755 index 0000000000..67140a705a --- /dev/null +++ b/scripts/reformat @@ -0,0 +1,11 @@ +#!/usr/bin/env bash + +set -euox pipefail + +# Runs all formatting tools to ensure the project is up to date +echo 'Reformatting Rust code' +cargo fmt +echo 'Reformatting Python code' +poetry run isort test_runner +poetry run flake8 test_runner +poetry run black test_runner diff --git a/test_runner/fixtures/compare_fixtures.py b/test_runner/fixtures/compare_fixtures.py index 78a12c6c45..2d36d90bd6 100644 --- a/test_runner/fixtures/compare_fixtures.py +++ b/test_runner/fixtures/compare_fixtures.py @@ -130,11 +130,12 @@ class NeonCompare(PgCompare): "size", timeline_size / (1024 * 1024), "MB", report=MetricReport.LOWER_IS_BETTER ) + params = f'{{tenant_id="{self.env.initial_tenant}",timeline_id="{self.timeline}"}}' total_files = self.zenbenchmark.get_int_counter_value( - self.env.pageserver, "pageserver_created_persistent_files_total" + self.env.pageserver, "pageserver_created_persistent_files_total" + params ) total_bytes = self.zenbenchmark.get_int_counter_value( - self.env.pageserver, "pageserver_written_persistent_bytes_total" + self.env.pageserver, "pageserver_written_persistent_bytes_total" + params ) self.zenbenchmark.record( "data_uploaded", total_bytes / (1024 * 1024), "MB", report=MetricReport.LOWER_IS_BETTER diff --git a/test_runner/fixtures/metrics.py b/test_runner/fixtures/metrics.py index 4d680aa641..62e3cbbe99 100644 --- a/test_runner/fixtures/metrics.py +++ b/test_runner/fixtures/metrics.py @@ -60,4 +60,6 @@ PAGESERVER_PER_TENANT_METRICS = [ "pageserver_wait_lsn_seconds_bucket", "pageserver_wait_lsn_seconds_count", "pageserver_wait_lsn_seconds_sum", + "pageserver_created_persistent_files_total", + "pageserver_written_persistent_bytes_total", ] diff --git a/test_runner/fixtures/neon_fixtures.py b/test_runner/fixtures/neon_fixtures.py index 28c65223ba..a77b3958c9 100644 --- a/test_runner/fixtures/neon_fixtures.py +++ b/test_runner/fixtures/neon_fixtures.py @@ -149,19 +149,6 @@ def pytest_configure(config): raise Exception('neon binaries not found at "{}"'.format(neon_binpath)) -def profiling_supported(): - """Return True if the pageserver was compiled with the 'profiling' feature""" - bin_pageserver = os.path.join(str(neon_binpath), "pageserver") - res = subprocess.run( - [bin_pageserver, "--version"], - check=True, - universal_newlines=True, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - ) - return "profiling:true" in res.stdout - - def shareable_scope(fixture_name, config) -> Literal["session", "function"]: """Return either session of function scope, depending on TEST_SHARED_FIXTURES envvar. @@ -874,6 +861,17 @@ class NeonEnv: """Get a timeline directory's path based on the repo directory of the test environment""" return self.repo_dir / "tenants" / str(tenant_id) / "timelines" / str(timeline_id) + def get_pageserver_version(self) -> str: + bin_pageserver = os.path.join(str(neon_binpath), "pageserver") + res = subprocess.run( + [bin_pageserver, "--version"], + check=True, + universal_newlines=True, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + ) + return res.stdout + @cached_property def auth_keys(self) -> AuthKeys: pub = (Path(self.repo_dir) / "auth_public_key.pem").read_bytes() @@ -972,10 +970,11 @@ class NeonPageserverApiException(Exception): class NeonPageserverHttpClient(requests.Session): - def __init__(self, port: int, auth_token: Optional[str] = None): + def __init__(self, port: int, is_testing_enabled_or_skip, auth_token: Optional[str] = None): super().__init__() self.port = port self.auth_token = auth_token + self.is_testing_enabled_or_skip = is_testing_enabled_or_skip if auth_token is not None: self.headers["Authorization"] = f"Bearer {auth_token}" @@ -994,6 +993,8 @@ class NeonPageserverHttpClient(requests.Session): self.get(f"http://localhost:{self.port}/v1/status").raise_for_status() def configure_failpoints(self, config_strings: tuple[str, str] | list[tuple[str, str]]) -> None: + self.is_testing_enabled_or_skip() + if isinstance(config_strings, tuple): pairs = [config_strings] else: @@ -1111,6 +1112,8 @@ class NeonPageserverHttpClient(requests.Session): def timeline_gc( self, tenant_id: TenantId, timeline_id: TimelineId, gc_horizon: Optional[int] ) -> dict[str, Any]: + self.is_testing_enabled_or_skip() + log.info( f"Requesting GC: tenant {tenant_id}, timeline {timeline_id}, gc_horizon {repr(gc_horizon)}" ) @@ -1126,6 +1129,8 @@ class NeonPageserverHttpClient(requests.Session): return res_json def timeline_compact(self, tenant_id: TenantId, timeline_id: TimelineId): + self.is_testing_enabled_or_skip() + log.info(f"Requesting compact: tenant {tenant_id}, timeline {timeline_id}") res = self.put( f"http://localhost:{self.port}/v1/tenant/{tenant_id}/timeline/{timeline_id}/compact" @@ -1150,6 +1155,8 @@ class NeonPageserverHttpClient(requests.Session): return res_json def timeline_checkpoint(self, tenant_id: TenantId, timeline_id: TimelineId): + self.is_testing_enabled_or_skip() + log.info(f"Requesting checkpoint: tenant {tenant_id}, timeline {timeline_id}") res = self.put( f"http://localhost:{self.port}/v1/tenant/{tenant_id}/timeline/{timeline_id}/checkpoint" @@ -1179,7 +1186,7 @@ CREATE_TIMELINE_ID_EXTRACTOR = re.compile( r"^Created timeline '(?P[^']+)'", re.MULTILINE ) TIMELINE_DATA_EXTRACTOR = re.compile( - r"\s(?P[^\s]+)\s\[(?P[^\]]+)\]", re.MULTILINE + r"\s?(?P[^\s]+)\s\[(?P[^\]]+)\]", re.MULTILINE ) @@ -1430,8 +1437,8 @@ class NeonCli(AbstractNeonCli): Returns a list of (branch_name, timeline_id) tuples out of parsed `neon timeline list` CLI output. """ - # (L) main [b49f7954224a0ad25cc0013ea107b54b] - # (L) ┣━ @0/16B5A50: test_cli_branch_list_main [20f98c79111b9015d84452258b7d5540] + # main [b49f7954224a0ad25cc0013ea107b54b] + # ┣━ @0/16B5A50: test_cli_branch_list_main [20f98c79111b9015d84452258b7d5540] res = self.raw_cli( ["timeline", "list", "--tenant-id", str(tenant_id or self.env.initial_tenant)] ) @@ -1469,21 +1476,6 @@ class NeonCli(AbstractNeonCli): res.check_returncode() return res - def pageserver_enabled_features(self) -> Any: - bin_pageserver = os.path.join(str(neon_binpath), "pageserver") - args = [bin_pageserver, "--enabled-features"] - log.info('Running command "{}"'.format(" ".join(args))) - - res = subprocess.run( - args, - check=True, - universal_newlines=True, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - ) - log.info(f"pageserver_enabled_features success: {res.stdout}") - return json.loads(res.stdout) - def pageserver_start( self, overrides=(), @@ -1642,6 +1634,7 @@ class NeonPageserver(PgProtocol): self.running = False self.service_port = port self.config_override = config_override + self.version = env.get_pageserver_version() def start(self, overrides=()) -> "NeonPageserver": """ @@ -1671,10 +1664,19 @@ class NeonPageserver(PgProtocol): def __exit__(self, exc_type, exc, tb): self.stop(immediate=True) + def is_testing_enabled_or_skip(self): + if '"testing"' not in self.version: + pytest.skip("pageserver was built without 'testing' feature") + + def is_profiling_enabled_or_skip(self): + if '"profiling"' not in self.version: + pytest.skip("pageserver was built without 'profiling' feature") + def http_client(self, auth_token: Optional[str] = None) -> NeonPageserverHttpClient: return NeonPageserverHttpClient( port=self.service_port.http, auth_token=auth_token, + is_testing_enabled_or_skip=self.is_testing_enabled_or_skip, ) @@ -1961,6 +1963,11 @@ class NeonProxy(PgProtocol): def _wait_until_ready(self): requests.get(f"http://{self.host}:{self.http_port}/v1/status") + def get_metrics(self) -> str: + request_result = requests.get(f"http://{self.host}:{self.http_port}/metrics") + request_result.raise_for_status() + return request_result.text + def __enter__(self): return self @@ -2334,6 +2341,7 @@ class Safekeeper: @dataclass class SafekeeperTimelineStatus: acceptor_epoch: int + pg_version: int flush_lsn: Lsn timeline_start_lsn: Lsn backup_lsn: Lsn @@ -2362,6 +2370,18 @@ class SafekeeperHttpClient(requests.Session): def check_status(self): self.get(f"http://localhost:{self.port}/v1/status").raise_for_status() + def timeline_create( + self, tenant_id: TenantId, timeline_id: TimelineId, pg_version: int, commit_lsn: Lsn + ): + body = { + "tenant_id": str(tenant_id), + "timeline_id": str(timeline_id), + "pg_version": pg_version, + "commit_lsn": str(commit_lsn), + } + res = self.post(f"http://localhost:{self.port}/v1/tenant/timeline", json=body) + res.raise_for_status() + def timeline_status( self, tenant_id: TenantId, timeline_id: TimelineId ) -> SafekeeperTimelineStatus: @@ -2370,6 +2390,7 @@ class SafekeeperHttpClient(requests.Session): resj = res.json() return SafekeeperTimelineStatus( acceptor_epoch=resj["acceptor_state"]["epoch"], + pg_version=resj["pg_info"]["pg_version"], flush_lsn=Lsn(resj["flush_lsn"]), timeline_start_lsn=Lsn(resj["timeline_start_lsn"]), backup_lsn=Lsn(resj["backup_lsn"]), @@ -2683,19 +2704,6 @@ def wait_until(number_of_iterations: int, interval: float, func): raise Exception("timed out while waiting for %s" % func) from last_exception -def assert_timeline_local( - pageserver_http_client: NeonPageserverHttpClient, tenant: TenantId, timeline: TimelineId -): - timeline_detail = pageserver_http_client.timeline_detail( - tenant, - timeline, - include_non_incremental_logical_size=True, - include_non_incremental_physical_size=True, - ) - assert timeline_detail.get("local", {}).get("disk_consistent_lsn"), timeline_detail - return timeline_detail - - def assert_no_in_progress_downloads_for_tenant( pageserver_http_client: NeonPageserverHttpClient, tenant: TenantId, @@ -2709,15 +2717,14 @@ def remote_consistent_lsn( ) -> Lsn: detail = pageserver_http_client.timeline_detail(tenant, timeline) - if detail["remote"] is None: + lsn_str = detail["remote_consistent_lsn"] + if lsn_str is None: # No remote information at all. This happens right after creating # a timeline, before any part of it has been uploaded to remote # storage yet. return Lsn(0) - else: - lsn_str = detail["remote"]["remote_consistent_lsn"] - assert isinstance(lsn_str, str) - return Lsn(lsn_str) + assert isinstance(lsn_str, str) + return Lsn(lsn_str) def wait_for_upload( @@ -2749,7 +2756,7 @@ def last_record_lsn( ) -> Lsn: detail = pageserver_http_client.timeline_detail(tenant, timeline) - lsn_str = detail["local"]["last_record_lsn"] + lsn_str = detail["last_record_lsn"] assert isinstance(lsn_str, str) return Lsn(lsn_str) diff --git a/test_runner/performance/test_branch_creation.py b/test_runner/performance/test_branch_creation.py index 9cb346de47..4b109c150f 100644 --- a/test_runner/performance/test_branch_creation.py +++ b/test_runner/performance/test_branch_creation.py @@ -3,12 +3,15 @@ import statistics import threading import time import timeit +from contextlib import closing from typing import List import pytest from fixtures.benchmark_fixture import MetricReport from fixtures.compare_fixtures import NeonCompare from fixtures.log_helper import log +from fixtures.neon_fixtures import wait_for_last_record_lsn +from fixtures.types import Lsn def _record_branch_creation_durations(neon_compare: NeonCompare, durs: List[float]): @@ -107,3 +110,43 @@ def test_branch_creation_many(neon_compare: NeonCompare, n_branches: int): branch_creation_durations.append(dur) _record_branch_creation_durations(neon_compare, branch_creation_durations) + + +# Test measures the branch creation time when branching from a timeline with a lot of relations. +# +# This test measures the latency of branch creation under two scenarios +# 1. The ancestor branch is not under any workloads +# 2. The ancestor branch is under a workload (busy) +# +# To simulate the workload, the test runs a concurrent insertion on the ancestor branch right before branching. +def test_branch_creation_many_relations(neon_compare: NeonCompare): + env = neon_compare.env + + timeline_id = env.neon_cli.create_branch("root") + + pg = env.postgres.create_start("root") + with closing(pg.connect()) as conn: + with conn.cursor() as cur: + for i in range(10000): + cur.execute(f"CREATE TABLE t{i} as SELECT g FROM generate_series(1, 1000) g") + + # Wait for the pageserver to finish processing all the pending WALs, + # as we don't want the LSN wait time to be included during the branch creation + flush_lsn = Lsn(pg.safe_psql("SELECT pg_current_wal_flush_lsn()")[0][0]) + wait_for_last_record_lsn( + env.pageserver.http_client(), env.initial_tenant, timeline_id, flush_lsn + ) + + with neon_compare.record_duration("create_branch_time_not_busy_root"): + env.neon_cli.create_branch("child_not_busy", "root") + + # run a concurrent insertion to make the ancestor "busy" during the branch creation + thread = threading.Thread( + target=pg.safe_psql, args=("INSERT INTO t0 VALUES (generate_series(1, 100000))",) + ) + thread.start() + + with neon_compare.record_duration("create_branch_time_busy_root"): + env.neon_cli.create_branch("child_busy", "root") + + thread.join() diff --git a/test_runner/performance/test_branching.py b/test_runner/performance/test_branching.py new file mode 100644 index 0000000000..562e751458 --- /dev/null +++ b/test_runner/performance/test_branching.py @@ -0,0 +1,94 @@ +import timeit +from pathlib import Path +from typing import List + +from fixtures.benchmark_fixture import PgBenchRunResult +from fixtures.compare_fixtures import NeonCompare +from performance.test_perf_pgbench import utc_now_timestamp + +# ----------------------------------------------------------------------- +# Start of `test_compare_child_and_root_*` tests +# ----------------------------------------------------------------------- + +# `test_compare_child_and_root_*` tests compare the performance of a branch and its child branch(s). +# A common pattern in those tests is initializing a root branch then creating a child branch(s) from the root. +# Each test then runs a similar workload for both child branch and root branch. Each measures and reports +# some latencies/metrics during the workload for performance comparison between a branch and its ancestor. + + +def test_compare_child_and_root_pgbench_perf(neon_compare: NeonCompare): + env = neon_compare.env + pg_bin = neon_compare.pg_bin + + def run_pgbench_on_branch(branch: str, cmd: List[str]): + run_start_timestamp = utc_now_timestamp() + t0 = timeit.default_timer() + out = pg_bin.run_capture( + cmd, + ) + run_duration = timeit.default_timer() - t0 + run_end_timestamp = utc_now_timestamp() + + stdout = Path(f"{out}.stdout").read_text() + + res = PgBenchRunResult.parse_from_stdout( + stdout=stdout, + run_duration=run_duration, + run_start_timestamp=run_start_timestamp, + run_end_timestamp=run_end_timestamp, + ) + neon_compare.zenbenchmark.record_pg_bench_result(branch, res) + + env.neon_cli.create_branch("root") + pg_root = env.postgres.create_start("root") + pg_bin.run_capture(["pgbench", "-i", pg_root.connstr(), "-s10"]) + + env.neon_cli.create_branch("child", "root") + pg_child = env.postgres.create_start("child") + + run_pgbench_on_branch("root", ["pgbench", "-c10", "-T10", pg_root.connstr()]) + run_pgbench_on_branch("child", ["pgbench", "-c10", "-T10", pg_child.connstr()]) + + +def test_compare_child_and_root_write_perf(neon_compare: NeonCompare): + env = neon_compare.env + env.neon_cli.create_branch("root") + pg_root = env.postgres.create_start("root") + + pg_root.safe_psql( + "CREATE TABLE foo(key serial primary key, t text default 'foooooooooooooooooooooooooooooooooooooooooooooooooooo')", + ) + + env.neon_cli.create_branch("child", "root") + pg_child = env.postgres.create_start("child") + + with neon_compare.record_duration("root_run_duration"): + pg_root.safe_psql("INSERT INTO foo SELECT FROM generate_series(1,1000000)") + with neon_compare.record_duration("child_run_duration"): + pg_child.safe_psql("INSERT INTO foo SELECT FROM generate_series(1,1000000)") + + +def test_compare_child_and_root_read_perf(neon_compare: NeonCompare): + env = neon_compare.env + env.neon_cli.create_branch("root") + pg_root = env.postgres.create_start("root") + + pg_root.safe_psql_many( + [ + "CREATE TABLE foo(key serial primary key, t text default 'foooooooooooooooooooooooooooooooooooooooooooooooooooo')", + "INSERT INTO foo SELECT FROM generate_series(1,1000000)", + ] + ) + + env.neon_cli.create_branch("child", "root") + pg_child = env.postgres.create_start("child") + + with neon_compare.record_duration("root_run_duration"): + pg_root.safe_psql("SELECT count(*) from foo") + with neon_compare.record_duration("child_run_duration"): + pg_child.safe_psql("SELECT count(*) from foo") + + +# ----------------------------------------------------------------------- +# End of `test_compare_child_and_root_*` tests +# ----------------------------------------------------------------------- diff --git a/test_runner/performance/test_perf_pgbench.py b/test_runner/performance/test_perf_pgbench.py index 656826d6a3..0ed3e45971 100644 --- a/test_runner/performance/test_perf_pgbench.py +++ b/test_runner/performance/test_perf_pgbench.py @@ -9,7 +9,6 @@ from typing import Dict, List import pytest from fixtures.benchmark_fixture import MetricReport, PgBenchInitResult, PgBenchRunResult from fixtures.compare_fixtures import NeonCompare, PgCompare -from fixtures.neon_fixtures import profiling_supported from fixtures.utils import get_scale_for_db @@ -187,10 +186,8 @@ def test_pgbench_flamegraph(zenbenchmark, pg_bin, neon_env_builder, scale: int, neon_env_builder.pageserver_config_override = """ profiling="page_requests" """ - if not profiling_supported(): - pytest.skip("pageserver was built without 'profiling' feature") - env = neon_env_builder.init_start() + env.pageserver.is_profiling_enabled_or_skip() env.neon_cli.create_branch("empty", "main") neon_compare = NeonCompare(zenbenchmark, env, pg_bin, "pgbench") diff --git a/test_runner/regress/test_broken_timeline.py b/test_runner/regress/test_broken_timeline.py index 7baa67935d..101cce9ffc 100644 --- a/test_runner/regress/test_broken_timeline.py +++ b/test_runner/regress/test_broken_timeline.py @@ -111,18 +111,20 @@ def test_create_multiple_timelines_parallel(neon_simple_env: NeonEnv): future.result() -def test_fix_broken_timelines_on_startup(neon_simple_env: NeonEnv): +def test_timeline_init_break_before_checkpoint(neon_simple_env: NeonEnv): env = neon_simple_env pageserver_http = env.pageserver.http_client() tenant_id, _ = env.neon_cli.create_tenant() + timelines_dir = env.repo_dir / "tenants" / str(tenant_id) / "timelines" old_tenant_timelines = env.neon_cli.list_timelines(tenant_id) + initial_timeline_dirs = [d for d in timelines_dir.iterdir()] - # Introduce failpoint when creating a new timeline + # Introduce failpoint during timeline init (some intermediate files are on disk), before it's checkpointed. pageserver_http.configure_failpoints(("before-checkpoint-new-timeline", "return")) with pytest.raises(Exception, match="before-checkpoint-new-timeline"): - _ = env.neon_cli.create_timeline("test_fix_broken_timelines", tenant_id) + _ = env.neon_cli.create_timeline("test_timeline_init_break_before_checkpoint", tenant_id) # Restart the page server env.neon_cli.pageserver_stop(immediate=True) @@ -133,3 +135,36 @@ def test_fix_broken_timelines_on_startup(neon_simple_env: NeonEnv): assert ( new_tenant_timelines == old_tenant_timelines ), f"Pageserver after restart should ignore non-initialized timelines for tenant {tenant_id}" + + timeline_dirs = [d for d in timelines_dir.iterdir()] + assert ( + timeline_dirs == initial_timeline_dirs + ), "pageserver should clean its temp timeline files on timeline creation failure" + + +def test_timeline_create_break_after_uninit_mark(neon_simple_env: NeonEnv): + env = neon_simple_env + pageserver_http = env.pageserver.http_client() + + tenant_id, _ = env.neon_cli.create_tenant() + + timelines_dir = env.repo_dir / "tenants" / str(tenant_id) / "timelines" + old_tenant_timelines = env.neon_cli.list_timelines(tenant_id) + initial_timeline_dirs = [d for d in timelines_dir.iterdir()] + + # Introduce failpoint when creating a new timeline uninit mark, before any other files were created + pageserver_http.configure_failpoints(("after-timeline-uninit-mark-creation", "return")) + with pytest.raises(Exception, match="after-timeline-uninit-mark-creation"): + _ = env.neon_cli.create_timeline("test_timeline_create_break_after_uninit_mark", tenant_id) + + # Creating the timeline didn't finish. The other timelines on tenant should still be present and work normally. + # "New" timeline is not present in the list, allowing pageserver to retry the same request + new_tenant_timelines = env.neon_cli.list_timelines(tenant_id) + assert ( + new_tenant_timelines == old_tenant_timelines + ), f"Pageserver after restart should ignore non-initialized timelines for tenant {tenant_id}" + + timeline_dirs = [d for d in timelines_dir.iterdir()] + assert ( + timeline_dirs == initial_timeline_dirs + ), "pageserver should clean its temp timeline files on timeline creation failure" diff --git a/test_runner/regress/test_build_info_metric.py b/test_runner/regress/test_build_info_metric.py new file mode 100644 index 0000000000..b75b5bd775 --- /dev/null +++ b/test_runner/regress/test_build_info_metric.py @@ -0,0 +1,19 @@ +from fixtures.metrics import parse_metrics +from fixtures.neon_fixtures import NeonEnvBuilder, NeonProxy + + +def test_build_info_metric(neon_env_builder: NeonEnvBuilder, link_proxy: NeonProxy): + neon_env_builder.num_safekeepers = 1 + env = neon_env_builder.init_start() + + parsed_metrics = {} + + parsed_metrics["pageserver"] = parse_metrics(env.pageserver.http_client().get_metrics()) + parsed_metrics["safekeeper"] = parse_metrics(env.safekeepers[0].http_client().get_metrics_str()) + parsed_metrics["proxy"] = parse_metrics(link_proxy.get_metrics()) + + for component, metrics in parsed_metrics.items(): + sample = metrics.query_one("libmetrics_build_info") + + assert "revision" in sample.labels + assert len(sample.labels["revision"]) > 0 diff --git a/test_runner/regress/test_gc_cutoff.py b/test_runner/regress/test_gc_cutoff.py new file mode 100644 index 0000000000..22b77d2cf1 --- /dev/null +++ b/test_runner/regress/test_gc_cutoff.py @@ -0,0 +1,39 @@ +from fixtures.neon_fixtures import NeonEnvBuilder, PgBin + + +# Test gc_cutoff +# +# This test sets fail point at the end of GC, and checks that pageserver +# normally restarts after it. Also, there should be GC ERRORs in the log, +# but the fixture checks the log for any unexpected ERRORs after every +# test anyway, so it doesn't need any special attention here. +def test_gc_cutoff(neon_env_builder: NeonEnvBuilder, pg_bin: PgBin): + env = neon_env_builder.init_start() + pageserver_http = env.pageserver.http_client() + + # Use aggressive GC and checkpoint settings, so that we also exercise GC during the test + tenant_id, _ = env.neon_cli.create_tenant( + conf={ + "gc_period": "10 s", + "gc_horizon": f"{1024 ** 2}", + "checkpoint_distance": f"{1024 ** 2}", + "compaction_period": "5 s", + # set PITR interval to be small, so we can do GC + "pitr_interval": "1 s", + "compaction_threshold": "3", + "image_creation_threshold": "2", + } + ) + pg = env.postgres.create_start("main", tenant_id=tenant_id) + connstr = pg.connstr(options="-csynchronous_commit=off") + pg_bin.run_capture(["pgbench", "-i", "-s10", connstr]) + + pageserver_http.configure_failpoints(("after-timeline-gc-removed-layers", "exit")) + + for i in range(5): + try: + pg_bin.run_capture(["pgbench", "-N", "-c5", "-T100", "-Mprepared", connstr]) + except Exception: + env.pageserver.stop() + env.pageserver.start() + pageserver_http.configure_failpoints(("after-timeline-gc-removed-layers", "exit")) diff --git a/test_runner/regress/test_import.py b/test_runner/regress/test_import.py index c84d282a4d..c888c6f7ee 100644 --- a/test_runner/regress/test_import.py +++ b/test_runner/regress/test_import.py @@ -105,15 +105,11 @@ def test_import_from_vanilla(test_output_dir, pg_bin, vanilla_pg, neon_env_build with pytest.raises(Exception): import_tar(corrupt_base_tar, wal_tar) - # Clean up - # TODO it should clean itself - client = env.pageserver.http_client() - client.timeline_delete(tenant, timeline) - # Importing correct backup works import_tar(base_tar, wal_tar) # Wait for data to land in s3 + client = env.pageserver.http_client() wait_for_last_record_lsn(client, tenant, timeline, Lsn(end_lsn)) wait_for_upload(client, tenant, timeline, Lsn(end_lsn)) @@ -155,8 +151,8 @@ def test_import_from_pageserver_multisegment(pg_bin: PgBin, neon_env_builder: Ne lsn = _generate_data(num_rows, pg) logical_size = env.pageserver.http_client().timeline_detail(env.initial_tenant, timeline)[ - "local" - ]["current_logical_size"] + "current_logical_size" + ] log.info(f"timeline logical size = {logical_size / (1024 ** 2)}MB") assert logical_size > 1024**3 # = 1GB diff --git a/test_runner/regress/test_normal_work.py b/test_runner/regress/test_normal_work.py index 002d697288..73918ee476 100644 --- a/test_runner/regress/test_normal_work.py +++ b/test_runner/regress/test_normal_work.py @@ -39,7 +39,7 @@ def test_normal_work(neon_env_builder: NeonEnvBuilder, num_timelines: int, num_s * restart compute * check that the data is there * stop compute - * detach timeline + * detach tenant Repeat check for several tenants/timelines. """ diff --git a/test_runner/regress/test_pageserver_api.py b/test_runner/regress/test_pageserver_api.py index def6bd5b33..bab96cff4f 100644 --- a/test_runner/regress/test_pageserver_api.py +++ b/test_runner/regress/test_pageserver_api.py @@ -93,7 +93,6 @@ def check_client(client: NeonPageserverHttpClient, initial_tenant: TenantId): assert TenantId(timeline_details["tenant_id"]) == tenant_id assert TimelineId(timeline_details["timeline_id"]) == timeline_id - assert timeline_details.get("local") is not None def test_pageserver_http_get_wal_receiver_not_found(neon_simple_env: NeonEnv): @@ -125,16 +124,15 @@ def expect_updated_msg_lsn( timeline_details = client.timeline_detail(tenant_id, timeline_id=timeline_id) # a successful `timeline_details` response must contain the below fields - local_timeline_details = timeline_details["local"] - assert "wal_source_connstr" in local_timeline_details.keys() - assert "last_received_msg_lsn" in local_timeline_details.keys() - assert "last_received_msg_ts" in local_timeline_details.keys() + assert "wal_source_connstr" in timeline_details.keys() + assert "last_received_msg_lsn" in timeline_details.keys() + assert "last_received_msg_ts" in timeline_details.keys() assert ( - local_timeline_details["last_received_msg_lsn"] is not None + timeline_details["last_received_msg_lsn"] is not None ), "the last received message's LSN is empty" - last_msg_lsn = Lsn(local_timeline_details["last_received_msg_lsn"]) + last_msg_lsn = Lsn(timeline_details["last_received_msg_lsn"]) assert ( prev_msg_lsn is None or prev_msg_lsn < last_msg_lsn ), f"the last received message's LSN {last_msg_lsn} hasn't been updated \ diff --git a/test_runner/regress/test_recovery.py b/test_runner/regress/test_recovery.py index d0ba96e8e0..e70b1351ba 100644 --- a/test_runner/regress/test_recovery.py +++ b/test_runner/regress/test_recovery.py @@ -13,13 +13,8 @@ def test_pageserver_recovery(neon_env_builder: NeonEnvBuilder): neon_env_builder.pageserver_config_override = "tenant_config={checkpoint_distance = 1048576}" env = neon_env_builder.init() + env.pageserver.is_testing_enabled_or_skip() - # Check if failpoints enables. Otherwise the test doesn't make sense - f = env.neon_cli.pageserver_enabled_features() - - assert ( - "testing" in f["features"] - ), "Build pageserver with --features=testing option to run this test" neon_env_builder.start() # Create a branch for us diff --git a/test_runner/regress/test_remote_storage.py b/test_runner/regress/test_remote_storage.py index 3e775b10b0..56b14dc42b 100644 --- a/test_runner/regress/test_remote_storage.py +++ b/test_runner/regress/test_remote_storage.py @@ -11,7 +11,7 @@ from fixtures.log_helper import log from fixtures.neon_fixtures import ( NeonEnvBuilder, RemoteStorageKind, - assert_timeline_local, + assert_no_in_progress_downloads_for_tenant, available_remote_storages, wait_for_last_record_lsn, wait_for_upload, @@ -111,10 +111,9 @@ def test_remote_storage_backup_and_restore( with pytest.raises(Exception, match="Conflict: Tenant download is already in progress"): client.tenant_attach(tenant_id) - detail = client.timeline_detail(tenant_id, timeline_id) - log.info("Timeline detail with active failpoint: %s", detail) - assert detail["local"] is None - assert detail["remote"]["awaits_download"] + tenant_status = client.tenant_status(tenant_id) + log.info("Tenant status with active failpoint: %s", tenant_status) + assert tenant_status["has_in_progress_downloads"] is True # trigger temporary download files removal env.pageserver.stop() @@ -126,16 +125,15 @@ def test_remote_storage_backup_and_restore( wait_until( number_of_iterations=20, interval=1, - func=lambda: assert_timeline_local(client, tenant_id, timeline_id), + func=lambda: assert_no_in_progress_downloads_for_tenant(client, tenant_id), ) detail = client.timeline_detail(tenant_id, timeline_id) - assert detail["local"] is not None log.info("Timeline detail after attach completed: %s", detail) assert ( - Lsn(detail["local"]["last_record_lsn"]) >= current_lsn + Lsn(detail["last_record_lsn"]) >= current_lsn ), "current db Lsn should should not be less than the one stored on remote storage" - assert not detail["remote"]["awaits_download"] + assert not detail["awaits_download"] pg = env.postgres.create_start("main") with pg.cursor() as cur: diff --git a/test_runner/regress/test_tenant_detach.py b/test_runner/regress/test_tenant_detach.py index f18e6867a9..a310eac1f7 100644 --- a/test_runner/regress/test_tenant_detach.py +++ b/test_runner/regress/test_tenant_detach.py @@ -70,7 +70,7 @@ def test_tenant_detach_smoke(neon_env_builder: NeonEnvBuilder): break # else is called if the loop finished without reaching "break" else: - pytest.fail(f"could not detach timeline: {last_error}") + pytest.fail(f"could not detach tenant: {last_error}") gc_thread.join(timeout=10) diff --git a/test_runner/regress/test_tenant_relocation.py b/test_runner/regress/test_tenant_relocation.py index 2b01546198..e14434ffdc 100644 --- a/test_runner/regress/test_tenant_relocation.py +++ b/test_runner/regress/test_tenant_relocation.py @@ -16,7 +16,6 @@ from fixtures.neon_fixtures import ( PortDistributor, Postgres, assert_no_in_progress_downloads_for_tenant, - assert_timeline_local, base_dir, neon_binpath, pg_distrib_dir, @@ -167,18 +166,18 @@ def check_timeline_attached( old_current_lsn: Lsn, ): # new pageserver should be in sync (modulo wal tail or vacuum activity) with the old one because there was no new writes since checkpoint - new_timeline_detail = assert_timeline_local(new_pageserver_http_client, tenant_id, timeline_id) + new_timeline_detail = new_pageserver_http_client.timeline_detail(tenant_id, timeline_id) # when load is active these checks can break because lsns are not static # so let's check with some margin assert_abs_margin_ratio( - int(Lsn(new_timeline_detail["local"]["disk_consistent_lsn"])), - int(Lsn(old_timeline_detail["local"]["disk_consistent_lsn"])), + int(Lsn(new_timeline_detail["disk_consistent_lsn"])), + int(Lsn(old_timeline_detail["disk_consistent_lsn"])), 0.03, ) assert_abs_margin_ratio( - int(Lsn(new_timeline_detail["local"]["disk_consistent_lsn"])), int(old_current_lsn), 0.03 + int(Lsn(new_timeline_detail["disk_consistent_lsn"])), int(old_current_lsn), 0.03 ) @@ -301,10 +300,10 @@ def test_tenant_relocation( # wait until pageserver receives that data wait_for_last_record_lsn(pageserver_http, tenant_id, timeline_id_main, current_lsn_main) - timeline_detail_main = assert_timeline_local(pageserver_http, tenant_id, timeline_id_main) + timeline_detail_main = pageserver_http.timeline_detail(tenant_id, timeline_id_main) wait_for_last_record_lsn(pageserver_http, tenant_id, timeline_id_second, current_lsn_second) - timeline_detail_second = assert_timeline_local(pageserver_http, tenant_id, timeline_id_second) + timeline_detail_second = pageserver_http.timeline_detail(tenant_id, timeline_id_second) if with_load == "with_load": # create load table @@ -347,7 +346,11 @@ def test_tenant_relocation( log.info("new pageserver ports pg %s http %s", new_pageserver_pg_port, new_pageserver_http_port) pageserver_bin = pathlib.Path(neon_binpath) / "pageserver" - new_pageserver_http = NeonPageserverHttpClient(port=new_pageserver_http_port, auth_token=None) + new_pageserver_http = NeonPageserverHttpClient( + port=new_pageserver_http_port, + auth_token=None, + is_testing_enabled_or_skip=env.pageserver.is_testing_enabled_or_skip, + ) with new_pageserver_helper( new_pageserver_dir, diff --git a/test_runner/regress/test_tenants.py b/test_runner/regress/test_tenants.py index f49b6fccb9..4ffea60950 100644 --- a/test_runner/regress/test_tenants.py +++ b/test_runner/regress/test_tenants.py @@ -23,7 +23,7 @@ def test_tenant_creation_fails(neon_simple_env: NeonEnv): initial_tenants = sorted( map(lambda t: t.split()[0], neon_simple_env.neon_cli.list_tenants().stdout.splitlines()) ) - initial_tenant_dirs = set([d for d in tenants_dir.iterdir()]) + initial_tenant_dirs = [d for d in tenants_dir.iterdir()] pageserver_http = neon_simple_env.pageserver.http_client() pageserver_http.configure_failpoints(("tenant-creation-before-tmp-rename", "return")) @@ -35,26 +35,10 @@ def test_tenant_creation_fails(neon_simple_env: NeonEnv): ) assert initial_tenants == new_tenants, "should not create new tenants" - new_tenant_dirs = list(set([d for d in tenants_dir.iterdir()]) - initial_tenant_dirs) - assert len(new_tenant_dirs) == 1, "should have new tenant directory created" - tmp_tenant_dir = new_tenant_dirs[0] - assert str(tmp_tenant_dir).endswith( - ".___temp" - ), "new tenant directory created should be a temporary one" - - neon_simple_env.pageserver.stop() - neon_simple_env.pageserver.start() - - tenants_after_restart = sorted( - map(lambda t: t.split()[0], neon_simple_env.neon_cli.list_tenants().stdout.splitlines()) - ) - dirs_after_restart = set([d for d in tenants_dir.iterdir()]) + new_tenant_dirs = [d for d in tenants_dir.iterdir()] assert ( - tenants_after_restart == initial_tenants - ), "should load all non-corrupt tenants after restart" - assert ( - dirs_after_restart == initial_tenant_dirs - ), "pageserver should clean its temp tenant dirs on restart" + new_tenant_dirs == initial_tenant_dirs + ), "pageserver should clean its temp tenant dirs on tenant creation failure" def test_tenants_normal_work(neon_env_builder: NeonEnvBuilder): @@ -258,11 +242,20 @@ def test_pageserver_with_empty_tenants( tenants = client.tenant_list() assert ( - len(tenants) == 1 - ), "Pageserver should attach only tenants with empty timelines/ dir on restart" - loaded_tenant = tenants[0] - assert loaded_tenant["id"] == str( - tenant_with_empty_timelines_dir + len(tenants) == 2 + ), "Pageserver should attach only tenants with empty or not existing timelines/ dir on restart" + + [broken_tenant] = [t for t in tenants if t["id"] == str(tenant_without_timelines_dir)] + assert ( + broken_tenant + ), f"A broken tenant {tenant_without_timelines_dir} should exists in the tenant list" + assert ( + broken_tenant["state"] == "Broken" + ), f"Tenant {tenant_without_timelines_dir} without timelines dir should be broken" + + [loaded_tenant] = [t for t in tenants if t["id"] == str(tenant_with_empty_timelines_dir)] + assert ( + loaded_tenant ), f"Tenant {tenant_with_empty_timelines_dir} should be loaded as the only one with tenants/ directory" assert loaded_tenant["state"] == { "Active": {"background_jobs_running": False} diff --git a/test_runner/regress/test_tenants_with_remote_storage.py b/test_runner/regress/test_tenants_with_remote_storage.py index d8424e22c8..96c1fc25db 100644 --- a/test_runner/regress/test_tenants_with_remote_storage.py +++ b/test_runner/regress/test_tenants_with_remote_storage.py @@ -7,18 +7,21 @@ # import asyncio +import json import os +import shutil from pathlib import Path from typing import List, Tuple import pytest from fixtures.log_helper import log from fixtures.neon_fixtures import ( + LocalFsStorage, NeonEnv, NeonEnvBuilder, - NeonPageserverHttpClient, Postgres, RemoteStorageKind, + assert_no_in_progress_downloads_for_tenant, available_remote_storages, wait_for_last_record_lsn, wait_for_upload, @@ -165,7 +168,7 @@ def test_tenants_attached_after_download( wait_until( number_of_iterations=5, interval=1, - func=lambda: expect_tenant_to_download_timeline(client, tenant_id), + func=lambda: assert_no_in_progress_downloads_for_tenant(client, tenant_id), ) restored_timelines = client.timeline_list(tenant_id) @@ -178,14 +181,244 @@ def test_tenants_attached_after_download( ), f"Tenant {tenant_id} should have its old timeline {timeline_id} restored from the remote storage" -def expect_tenant_to_download_timeline( - client: NeonPageserverHttpClient, - tenant_id: TenantId, +@pytest.mark.parametrize("remote_storage_kind", [RemoteStorageKind.LOCAL_FS]) +def test_tenant_upgrades_index_json_from_v0( + neon_env_builder: NeonEnvBuilder, remote_storage_kind: RemoteStorageKind ): - for tenant in client.tenant_list(): - if tenant["id"] == str(tenant_id): - assert not tenant.get( - "has_in_progress_downloads", True - ), f"Tenant {tenant_id} should have no downloads in progress" - return - assert False, f"Tenant {tenant_id} is missing on pageserver" + # the "image" for the v0 index_part.json. the fields themselves are + # replaced with values read from the later version because of #2592 (initdb + # lsn not reproducible). + v0_skeleton = json.loads( + """{ + "timeline_layers":[ + "000000000000000000000000000000000000-FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF__0000000001696070-00000000016960E9" + ], + "missing_layers":[], + "disk_consistent_lsn":"0/16960E8", + "metadata_bytes":[] + }""" + ) + + # getting a too eager compaction happening for this test would not play + # well with the strict assertions. + neon_env_builder.pageserver_config_override = "tenant_config.compaction_period='1h'" + + neon_env_builder.enable_remote_storage( + remote_storage_kind, "test_tenant_upgrades_index_json_from_v0" + ) + + # launch pageserver, populate the default tenants timeline, wait for it to be uploaded, + # then go ahead and modify the "remote" version as if it was downgraded, needing upgrade + env = neon_env_builder.init_start() + pageserver_http = env.pageserver.http_client() + pg = env.postgres.create_start("main") + + tenant_id = TenantId(pg.safe_psql("show neon.tenant_id")[0][0]) + timeline_id = TimelineId(pg.safe_psql("show neon.timeline_id")[0][0]) + + with pg.cursor() as cur: + cur.execute("CREATE TABLE t0 AS VALUES (123, 'second column as text');") + current_lsn = Lsn(query_scalar(cur, "SELECT pg_current_wal_flush_lsn()")) + + # flush, wait until in remote storage + wait_for_last_record_lsn(pageserver_http, tenant_id, timeline_id, current_lsn) + pageserver_http.timeline_checkpoint(tenant_id, timeline_id) + wait_for_upload(pageserver_http, tenant_id, timeline_id, current_lsn) + + env.postgres.stop_all() + env.pageserver.stop() + + # remove all local data for the tenant to force redownloading and subsequent upgrade + shutil.rmtree(Path(env.repo_dir) / "tenants" / str(tenant_id)) + + # downgrade the remote file + timeline_path = local_fs_index_part_path(env, tenant_id, timeline_id) + with open(timeline_path, "r+") as timeline_file: + # keep the deserialized for later inspection + orig_index_part = json.load(timeline_file) + + v0_index_part = {key: orig_index_part[key] for key in v0_skeleton} + + timeline_file.seek(0) + json.dump(v0_index_part, timeline_file) + + env.pageserver.start() + pageserver_http = env.pageserver.http_client() + pageserver_http.tenant_attach(tenant_id) + + wait_until( + number_of_iterations=5, + interval=1, + func=lambda: assert_no_in_progress_downloads_for_tenant(pageserver_http, tenant_id), + ) + + pg = env.postgres.create_start("main") + + with pg.cursor() as cur: + cur.execute("INSERT INTO t0 VALUES (234, 'test data');") + current_lsn = Lsn(query_scalar(cur, "SELECT pg_current_wal_flush_lsn()")) + + wait_for_last_record_lsn(pageserver_http, tenant_id, timeline_id, current_lsn) + pageserver_http.timeline_checkpoint(tenant_id, timeline_id) + wait_for_upload(pageserver_http, tenant_id, timeline_id, current_lsn) + + # not needed anymore + env.postgres.stop_all() + env.pageserver.stop() + + # make sure the file has been upgraded back to how it started + index_part = local_fs_index_part(env, tenant_id, timeline_id) + assert index_part["version"] == orig_index_part["version"] + assert index_part["missing_layers"] == orig_index_part["missing_layers"] + + # expect one more layer because of the forced checkpoint + assert len(index_part["timeline_layers"]) == len(orig_index_part["timeline_layers"]) + 1 + + # all of the same layer files are there, but they might be shuffled around + orig_layers = set(orig_index_part["timeline_layers"]) + later_layers = set(index_part["timeline_layers"]) + assert later_layers.issuperset(orig_layers) + + added_layers = later_layers - orig_layers + assert len(added_layers) == 1 + + # all of metadata has been regenerated (currently just layer file size) + all_metadata_keys = set() + for layer in orig_layers: + orig_metadata = orig_index_part["layer_metadata"][layer] + new_metadata = index_part["layer_metadata"][layer] + assert ( + orig_metadata == new_metadata + ), f"metadata for layer {layer} should not have changed {orig_metadata} vs. {new_metadata}" + all_metadata_keys |= set(orig_metadata.keys()) + + one_new_layer = next(iter(added_layers)) + assert one_new_layer in index_part["layer_metadata"], "new layer should have metadata" + + only_new_metadata = index_part["layer_metadata"][one_new_layer] + + assert ( + set(only_new_metadata.keys()).symmetric_difference(all_metadata_keys) == set() + ), "new layer metadata has same metadata as others" + + +# FIXME: test index_part.json getting downgraded from imaginary new version + + +@pytest.mark.parametrize("remote_storage_kind", [RemoteStorageKind.LOCAL_FS]) +def test_tenant_redownloads_truncated_file_on_startup( + neon_env_builder: NeonEnvBuilder, remote_storage_kind: RemoteStorageKind +): + # since we now store the layer file length metadata, we notice on startup that a layer file is of wrong size, and proceed to redownload it. + neon_env_builder.enable_remote_storage( + remote_storage_kind=remote_storage_kind, + test_name="test_tenant_redownloads_truncated_file_on_startup", + ) + + env = neon_env_builder.init_start() + pageserver_http = env.pageserver.http_client() + pg = env.postgres.create_start("main") + + tenant_id = TenantId(pg.safe_psql("show neon.tenant_id")[0][0]) + timeline_id = TimelineId(pg.safe_psql("show neon.timeline_id")[0][0]) + + with pg.cursor() as cur: + cur.execute("CREATE TABLE t1 AS VALUES (123, 'foobar');") + current_lsn = Lsn(query_scalar(cur, "SELECT pg_current_wal_flush_lsn()")) + + wait_for_last_record_lsn(pageserver_http, tenant_id, timeline_id, current_lsn) + pageserver_http.timeline_checkpoint(tenant_id, timeline_id) + wait_for_upload(pageserver_http, tenant_id, timeline_id, current_lsn) + + env.postgres.stop_all() + env.pageserver.stop() + + timeline_dir = Path(env.repo_dir) / "tenants" / str(tenant_id) / "timelines" / str(timeline_id) + local_layer_truncated = None + for path in Path.iterdir(timeline_dir): + if path.name.startswith("00000"): + correct_size = os.stat(path).st_size + os.truncate(path, 0) + local_layer_truncated = (path, correct_size) + break + assert ( + local_layer_truncated is not None + ), f"Found no local layer files to delete in directory {timeline_dir}" + + (path, expected_size) = local_layer_truncated + + # ensure the same size is found from the index_part.json + index_part = local_fs_index_part(env, tenant_id, timeline_id) + assert index_part["layer_metadata"][path.name]["file_size"] == expected_size + + ##### Start the pageserver, forcing it to download the layer file and load the timeline into memory + env.pageserver.start() + client = env.pageserver.http_client() + + wait_until( + number_of_iterations=5, + interval=1, + func=lambda: assert_no_in_progress_downloads_for_tenant(client, tenant_id), + ) + + restored_timelines = client.timeline_list(tenant_id) + assert ( + len(restored_timelines) == 1 + ), f"Tenant {tenant_id} should have its timeline reattached after its layer is downloaded from the remote storage" + retored_timeline = restored_timelines[0] + assert retored_timeline["timeline_id"] == str( + timeline_id + ), f"Tenant {tenant_id} should have its old timeline {timeline_id} restored from the remote storage" + + assert os.stat(path).st_size == expected_size, "truncated layer should had been re-downloaded" + + # the remote side of local_layer_truncated + remote_layer_path = local_fs_index_part_path(env, tenant_id, timeline_id).parent / path.name + + # if the upload ever was ongoing, this check would be racy, but at least one + # extra http request has been made in between so assume it's enough delay + assert ( + os.stat(remote_layer_path).st_size == expected_size + ), "truncated file should not had been uploaded around re-download" + + pg = env.postgres.create_start("main") + + with pg.cursor() as cur: + cur.execute("INSERT INTO t1 VALUES (234, 'test data');") + current_lsn = Lsn(query_scalar(cur, "SELECT pg_current_wal_flush_lsn()")) + + wait_for_last_record_lsn(pageserver_http, tenant_id, timeline_id, current_lsn) + pageserver_http.timeline_checkpoint(tenant_id, timeline_id) + wait_for_upload(pageserver_http, tenant_id, timeline_id, current_lsn) + + # now that the upload is complete, make sure the file hasn't been + # re-uploaded truncated. this is a rather bogus check given the current + # implementation, but it's critical it doesn't happen so wasting a few + # lines of python to do this. + assert ( + os.stat(remote_layer_path).st_size == expected_size + ), "truncated file should not had been uploaded after next checkpoint" + + +def local_fs_index_part(env, tenant_id, timeline_id): + """ + Return json.load parsed index_part.json of tenant and timeline from LOCAL_FS + """ + timeline_path = local_fs_index_part_path(env, tenant_id, timeline_id) + with open(timeline_path, "r") as timeline_file: + return json.load(timeline_file) + + +def local_fs_index_part_path(env, tenant_id, timeline_id): + """ + Return path to the LOCAL_FS index_part.json of the tenant and timeline. + """ + assert isinstance(env.remote_storage, LocalFsStorage) + return ( + env.remote_storage.root + / "tenants" + / str(tenant_id) + / "timelines" + / str(timeline_id) + / "index_part.json" + ) diff --git a/test_runner/regress/test_timeline_delete.py b/test_runner/regress/test_timeline_delete.py index 2eea8dd3cc..de05d445ed 100644 --- a/test_runner/regress/test_timeline_delete.py +++ b/test_runner/regress/test_timeline_delete.py @@ -32,7 +32,7 @@ def test_timeline_delete(neon_simple_env: NeonEnv): ps_http = env.pageserver.http_client() with pytest.raises( - NeonPageserverApiException, match="Cannot detach timeline which has child timelines" + NeonPageserverApiException, match="Cannot delete timeline which has child timelines" ): timeline_path = ( @@ -65,7 +65,7 @@ def test_timeline_delete(neon_simple_env: NeonEnv): # check 404 with pytest.raises( NeonPageserverApiException, - match=f"Timeline {env.initial_tenant}/{leaf_timeline_id} is not found neither locally nor remotely", + match=f"Timeline {leaf_timeline_id} was not found for tenant {env.initial_tenant}", ): ps_http.timeline_detail(env.initial_tenant, leaf_timeline_id) diff --git a/test_runner/regress/test_timeline_size.py b/test_runner/regress/test_timeline_size.py index 3a482be5db..d783f897f9 100644 --- a/test_runner/regress/test_timeline_size.py +++ b/test_runner/regress/test_timeline_size.py @@ -16,7 +16,6 @@ from fixtures.neon_fixtures import ( PortDistributor, Postgres, VanillaPostgres, - assert_timeline_local, wait_for_last_flush_lsn, ) from fixtures.types import TenantId, TimelineId @@ -44,20 +43,16 @@ def test_timeline_size(neon_simple_env: NeonEnv): """ ) - res = assert_timeline_local(client, env.initial_tenant, new_timeline_id) - local_details = res["local"] - assert ( - local_details["current_logical_size"] - == local_details["current_logical_size_non_incremental"] + res = client.timeline_detail( + env.initial_tenant, new_timeline_id, include_non_incremental_logical_size=True ) + assert res["current_logical_size"] == res["current_logical_size_non_incremental"] cur.execute("TRUNCATE foo") - res = assert_timeline_local(client, env.initial_tenant, new_timeline_id) - local_details = res["local"] - assert ( - local_details["current_logical_size"] - == local_details["current_logical_size_non_incremental"] + res = client.timeline_detail( + env.initial_tenant, new_timeline_id, include_non_incremental_logical_size=True ) + assert res["current_logical_size"] == res["current_logical_size_non_incremental"] def test_timeline_size_createdropdb(neon_simple_env: NeonEnv): @@ -66,22 +61,22 @@ def test_timeline_size_createdropdb(neon_simple_env: NeonEnv): client = env.pageserver.http_client() wait_for_timeline_size_init(client, tenant=env.initial_tenant, timeline=new_timeline_id) - timeline_details = assert_timeline_local(client, env.initial_tenant, new_timeline_id) + timeline_details = client.timeline_detail( + env.initial_tenant, new_timeline_id, include_non_incremental_logical_size=True + ) pgmain = env.postgres.create_start("test_timeline_size_createdropdb") log.info("postgres is running on 'test_timeline_size_createdropdb' branch") with closing(pgmain.connect()) as conn: with conn.cursor() as cur: - res = assert_timeline_local(client, env.initial_tenant, new_timeline_id) - local_details = res["local"] - assert ( - local_details["current_logical_size"] - == local_details["current_logical_size_non_incremental"] + res = client.timeline_detail( + env.initial_tenant, new_timeline_id, include_non_incremental_logical_size=True ) + assert res["current_logical_size"] == res["current_logical_size_non_incremental"] assert ( - timeline_details["local"]["current_logical_size_non_incremental"] - == local_details["current_logical_size_non_incremental"] + timeline_details["current_logical_size_non_incremental"] + == res["current_logical_size_non_incremental"] ), "no writes should not change the incremental logical size" cur.execute("CREATE DATABASE foodb") @@ -97,21 +92,21 @@ def test_timeline_size_createdropdb(neon_simple_env: NeonEnv): """ ) - res = assert_timeline_local(client, env.initial_tenant, new_timeline_id) - local_details = res["local"] + res = client.timeline_detail( + env.initial_tenant, + new_timeline_id, + include_non_incremental_logical_size=True, + ) assert ( - local_details["current_logical_size"] - == local_details["current_logical_size_non_incremental"] + res["current_logical_size"] == res["current_logical_size_non_incremental"] ) cur.execute("DROP DATABASE foodb") - res = assert_timeline_local(client, env.initial_tenant, new_timeline_id) - local_details = res["local"] - assert ( - local_details["current_logical_size"] - == local_details["current_logical_size_non_incremental"] + res = client.timeline_detail( + env.initial_tenant, new_timeline_id, include_non_incremental_logical_size=True ) + assert res["current_logical_size"] == res["current_logical_size_non_incremental"] # wait until received_lsn_lag is 0 @@ -210,10 +205,11 @@ def test_timeline_size_quota(neon_env_builder: NeonEnvBuilder): pg_cluster_size = cur.fetchone() log.info(f"pg_cluster_size = {pg_cluster_size}") - new_res = assert_timeline_local(client, env.initial_tenant, new_timeline_id) + new_res = client.timeline_detail( + env.initial_tenant, new_timeline_id, include_non_incremental_logical_size=True + ) assert ( - new_res["local"]["current_logical_size"] - == new_res["local"]["current_logical_size_non_incremental"] + new_res["current_logical_size"] == new_res["current_logical_size_non_incremental"] ), "after the WAL is streamed, current_logical_size is expected to be calculated and to be equal its non-incremental value" @@ -274,9 +270,15 @@ def test_timeline_physical_size_post_compaction(neon_env_builder: NeonEnvBuilder new_timeline_id = env.neon_cli.create_branch("test_timeline_physical_size_post_compaction") pg = env.postgres.create_start("test_timeline_physical_size_post_compaction") + # We don't want autovacuum to run on the table, while we are calculating the + # physical size, because that could cause a new layer to be created and a + # mismatch between the incremental and non-incremental size. (If that still + # happens, because of some other background activity or autovacuum on other + # tables, we could simply retry the size calculations. It's unlikely that + # that would happen more than once.) pg.safe_psql_many( [ - "CREATE TABLE foo (t text)", + "CREATE TABLE foo (t text) WITH (autovacuum_enabled = off)", """INSERT INTO foo SELECT 'long string to consume some space' || g FROM generate_series(1, 100000) g""", @@ -301,9 +303,10 @@ def test_timeline_physical_size_post_gc(neon_env_builder: NeonEnvBuilder): new_timeline_id = env.neon_cli.create_branch("test_timeline_physical_size_post_gc") pg = env.postgres.create_start("test_timeline_physical_size_post_gc") + # Like in test_timeline_physical_size_post_compaction, disable autovacuum pg.safe_psql_many( [ - "CREATE TABLE foo (t text)", + "CREATE TABLE foo (t text) WITH (autovacuum_enabled = off)", """INSERT INTO foo SELECT 'long string to consume some space' || g FROM generate_series(1, 100000) g""", @@ -419,7 +422,7 @@ def test_tenant_physical_size(neon_simple_env: NeonEnv): def get_timeline_physical_size(timeline: TimelineId): res = client.timeline_detail(tenant, timeline, include_non_incremental_physical_size=True) - return res["local"]["current_physical_size_non_incremental"] + return res["current_physical_size_non_incremental"] timeline_total_size = get_timeline_physical_size(timeline) for i in range(10): @@ -450,13 +453,10 @@ def assert_physical_size(env: NeonEnv, tenant_id: TenantId, timeline_id: Timelin """Check the current physical size returned from timeline API matches the total physical size of the timeline on disk""" client = env.pageserver.http_client() - res = assert_timeline_local(client, tenant_id, timeline_id) + res = client.timeline_detail(tenant_id, timeline_id, include_non_incremental_physical_size=True) timeline_path = env.timeline_dir(tenant_id, timeline_id) - assert ( - res["local"]["current_physical_size"] - == res["local"]["current_physical_size_non_incremental"] - ) - assert res["local"]["current_physical_size"] == get_timeline_dir_size(timeline_path) + assert res["current_physical_size"] == res["current_physical_size_non_incremental"] + assert res["current_physical_size"] == get_timeline_dir_size(timeline_path) # Timeline logical size initialization is an asynchronous background task that runs once, @@ -465,13 +465,16 @@ def wait_for_timeline_size_init( client: NeonPageserverHttpClient, tenant: TenantId, timeline: TimelineId ): for i in range(10): - timeline_details = assert_timeline_local(client, tenant, timeline) - if ( - timeline_details["local"]["current_logical_size"] - == timeline_details["local"]["current_logical_size_non_incremental"] - ): + timeline_details = client.timeline_detail( + tenant, timeline, include_non_incremental_logical_size=True + ) + current_logical_size = timeline_details["current_logical_size"] + non_incremental = timeline_details["current_logical_size_non_incremental"] + if current_logical_size == non_incremental: return - log.info(f"waiting for current_logical_size of a timeline to be calculated, iteration {i}") + log.info( + f"waiting for current_logical_size of a timeline to be calculated, iteration {i}: {current_logical_size} vs {non_incremental}" + ) time.sleep(1) raise Exception( f"timed out while waiting for current_logical_size of a timeline to reach its non-incremental value, details: {timeline_details}" diff --git a/test_runner/regress/test_wal_acceptor.py b/test_runner/regress/test_wal_acceptor.py index d5a5ec2f36..79adfb7b68 100644 --- a/test_runner/regress/test_wal_acceptor.py +++ b/test_runner/regress/test_wal_acceptor.py @@ -9,6 +9,7 @@ import threading import time from contextlib import closing from dataclasses import dataclass, field +from functools import partial from pathlib import Path from typing import Any, List, Optional @@ -126,14 +127,9 @@ def test_many_timelines(neon_env_builder: NeonEnvBuilder): for timeline_detail in timeline_details: timeline_id = TimelineId(timeline_detail["timeline_id"]) - local_timeline_detail = timeline_detail.get("local") - if local_timeline_detail is None: - log.debug(f"Timeline {timeline_id} is not present locally, skipping") - continue - m = TimelineMetrics( timeline_id=timeline_id, - last_record_lsn=Lsn(local_timeline_detail["last_record_lsn"]), + last_record_lsn=Lsn(timeline_detail["last_record_lsn"]), ) for sk_m in sk_metrics: m.flush_lsns.append(Lsn(sk_m.flush_lsn_inexact[(tenant_id, timeline_id)])) @@ -372,51 +368,48 @@ def test_wal_removal(neon_env_builder: NeonEnvBuilder, auth_enabled: bool): ) # wait till first segment is removed on all safekeepers + wait( + lambda first_segments=first_segments: all(not os.path.exists(p) for p in first_segments), + "first segment get removed", + ) + + +# Wait for something, defined as f() returning True, raising error if this +# doesn't happen without timeout seconds. +def wait(f, desc, timeout=30): started_at = time.time() while True: - if all(not os.path.exists(p) for p in first_segments): + if f(): break elapsed = time.time() - started_at - if elapsed > 20: - raise RuntimeError(f"timed out waiting {elapsed:.0f}s for first segment get removed") + if elapsed > timeout: + raise RuntimeError(f"timed out waiting {elapsed:.0f}s for {desc}") time.sleep(0.5) -def wait_segment_offload(tenant_id, timeline_id, live_sk, seg_end: Lsn): - started_at = time.time() - http_cli = live_sk.http_client() - while True: - tli_status = http_cli.timeline_status(tenant_id, timeline_id) - log.info(f"live sk status is {tli_status}") - - if tli_status.backup_lsn >= seg_end: - break - elapsed = time.time() - started_at - if elapsed > 30: - raise RuntimeError( - f"timed out waiting {elapsed:.0f}s for segment ending at {seg_end} get offloaded" - ) - time.sleep(0.5) - - -def wait_wal_trim(tenant_id, timeline_id, sk, target_size_mb): - started_at = time.time() +def is_segment_offloaded( + sk: Safekeeper, tenant_id: TenantId, timeline_id: TimelineId, seg_end: Lsn +): http_cli = sk.http_client() - while True: - tli_status = http_cli.timeline_status(tenant_id, timeline_id) - sk_wal_size = get_dir_size(os.path.join(sk.data_dir(), str(tenant_id), str(timeline_id))) - sk_wal_size_mb = sk_wal_size / 1024 / 1024 - log.info(f"Safekeeper id={sk.id} wal_size={sk_wal_size_mb:.2f}MB status={tli_status}") + tli_status = http_cli.timeline_status(tenant_id, timeline_id) + log.info(f"sk status is {tli_status}") + return tli_status.backup_lsn >= seg_end - if sk_wal_size_mb <= target_size_mb: - break - elapsed = time.time() - started_at - if elapsed > 20: - raise RuntimeError( - f"timed out waiting {elapsed:.0f}s for sk_id={sk.id} to trim WAL to {target_size_mb:.2f}MB, current size is {sk_wal_size_mb:.2f}MB" - ) - time.sleep(0.5) +def is_flush_lsn_caught_up(sk: Safekeeper, tenant_id: TenantId, timeline_id: TimelineId, lsn: Lsn): + http_cli = sk.http_client() + tli_status = http_cli.timeline_status(tenant_id, timeline_id) + log.info(f"sk status is {tli_status}") + return tli_status.flush_lsn >= lsn + + +def is_wal_trimmed(sk: Safekeeper, tenant_id: TenantId, timeline_id: TimelineId, target_size_mb): + http_cli = sk.http_client() + tli_status = http_cli.timeline_status(tenant_id, timeline_id) + sk_wal_size = get_dir_size(os.path.join(sk.data_dir(), str(tenant_id), str(timeline_id))) + sk_wal_size_mb = sk_wal_size / 1024 / 1024 + log.info(f"Safekeeper id={sk.id} wal_size={sk_wal_size_mb:.2f}MB status={tli_status}") + return sk_wal_size_mb <= target_size_mb @pytest.mark.parametrize("remote_storage_kind", available_remote_storages()) @@ -452,7 +445,10 @@ def test_wal_backup(neon_env_builder: NeonEnvBuilder, remote_storage_kind: Remot cur.execute("insert into t select generate_series(1,250000), 'payload'") live_sk = [sk for sk in env.safekeepers if sk != victim][0] - wait_segment_offload(tenant_id, timeline_id, live_sk, seg_end) + wait( + partial(is_segment_offloaded, live_sk, tenant_id, timeline_id, seg_end), + f"segment ending at {seg_end} get offloaded", + ) victim.start() @@ -464,7 +460,11 @@ def test_wal_backup(neon_env_builder: NeonEnvBuilder, remote_storage_kind: Remot with closing(pg.connect()) as conn: with conn.cursor() as cur: cur.execute("insert into t select generate_series(1,250000), 'payload'") - wait_segment_offload(tenant_id, timeline_id, env.safekeepers[1], Lsn("0/5000000")) + seg_end = Lsn("0/5000000") + wait( + partial(is_segment_offloaded, env.safekeepers[1], tenant_id, timeline_id, seg_end), + f"segment ending at {seg_end} get offloaded", + ) @pytest.mark.parametrize("remote_storage_kind", available_remote_storages()) @@ -481,13 +481,6 @@ def test_s3_wal_replay(neon_env_builder: NeonEnvBuilder, remote_storage_kind: Re env = neon_env_builder.init_start() env.neon_cli.create_branch("test_s3_wal_replay") - env.pageserver.stop() - pageserver_tenants_dir = os.path.join(env.repo_dir, "tenants") - pageserver_fresh_copy = os.path.join(env.repo_dir, "tenants_fresh") - log.info(f"Creating a copy of pageserver in a fresh state at {pageserver_fresh_copy}") - shutil.copytree(pageserver_tenants_dir, pageserver_fresh_copy) - env.pageserver.start() - pg = env.postgres.create_start("test_s3_wal_replay") # learn neon timeline from compute @@ -502,48 +495,76 @@ def test_s3_wal_replay(neon_env_builder: NeonEnvBuilder, remote_storage_kind: Re cur.execute("insert into t values (1, 'payload')") expected_sum += 1 - offloaded_seg_end = [Lsn("0/3000000")] - for seg_end in offloaded_seg_end: - # roughly fills two segments - cur.execute("insert into t select generate_series(1,500000), 'payload'") - expected_sum += 500000 * 500001 // 2 + offloaded_seg_end = Lsn("0/3000000") + # roughly fills two segments + cur.execute("insert into t select generate_series(1,500000), 'payload'") + expected_sum += 500000 * 500001 // 2 - assert query_scalar(cur, "select sum(key) from t") == expected_sum + assert query_scalar(cur, "select sum(key) from t") == expected_sum - for sk in env.safekeepers: - wait_segment_offload(tenant_id, timeline_id, sk, seg_end) + for sk in env.safekeepers: + wait( + partial(is_segment_offloaded, sk, tenant_id, timeline_id, offloaded_seg_end), + f"segment ending at {offloaded_seg_end} get offloaded", + ) # advance remote_consistent_lsn to trigger WAL trimming # this LSN should be less than commit_lsn, so timeline will be active=true in safekeepers, to push etcd updates env.safekeepers[0].http_client().record_safekeeper_info( - tenant_id, timeline_id, {"remote_consistent_lsn": str(offloaded_seg_end[-1])} + tenant_id, timeline_id, {"remote_consistent_lsn": str(offloaded_seg_end)} ) + last_lsn = Lsn(query_scalar(cur, "SELECT pg_current_wal_flush_lsn()")) + for sk in env.safekeepers: # require WAL to be trimmed, so no more than one segment is left on disk - wait_wal_trim(tenant_id, timeline_id, sk, 16 * 1.5) + target_size_mb = 16 * 1.5 + wait( + partial(is_wal_trimmed, sk, tenant_id, timeline_id, target_size_mb), + f"sk_id={sk.id} to trim WAL to {target_size_mb:.2f}MB", + ) + # wait till everyone puts data up to last_lsn on disk, we are + # going to recreate state on safekeepers claiming they have data till last_lsn. + wait( + partial(is_flush_lsn_caught_up, sk, tenant_id, timeline_id, last_lsn), + f"sk_id={sk.id} to flush {last_lsn}", + ) - last_lsn = query_scalar(cur, "SELECT pg_current_wal_flush_lsn()") - - pageserver_lsn = env.pageserver.http_client().timeline_detail(tenant_id, timeline_id)["local"][ - "last_record_lsn" - ] - lag = Lsn(last_lsn) - Lsn(pageserver_lsn) + ps_cli = env.pageserver.http_client() + pageserver_lsn = Lsn(ps_cli.timeline_detail(tenant_id, timeline_id)["last_record_lsn"]) + lag = last_lsn - pageserver_lsn log.info( f"Pageserver last_record_lsn={pageserver_lsn}; flush_lsn={last_lsn}; lag before replay is {lag / 1024}kb" ) - # replace pageserver with a fresh copy pg.stop_and_destroy() - env.pageserver.stop() - log.info(f"Removing current pageserver state at {pageserver_tenants_dir}") - shutil.rmtree(pageserver_tenants_dir) - log.info(f"Copying fresh pageserver state from {pageserver_fresh_copy}") - shutil.move(pageserver_fresh_copy, pageserver_tenants_dir) + # Also delete and manually create timeline on safekeepers -- this tests + # scenario of manual recovery on different set of safekeepers. + + # save the last (partial) file to put it back after recreation; others will be fetched from s3 + sk = env.safekeepers[0] + tli_dir = Path(sk.data_dir()) / str(tenant_id) / str(timeline_id) + f_partial = Path([f for f in os.listdir(tli_dir) if f.endswith(".partial")][0]) + f_partial_path = tli_dir / f_partial + f_partial_saved = Path(sk.data_dir()) / f_partial.name + f_partial_path.rename(f_partial_saved) + + pg_version = sk.http_client().timeline_status(tenant_id, timeline_id).pg_version + + for sk in env.safekeepers: + cli = sk.http_client() + cli.timeline_delete_force(tenant_id, timeline_id) + cli.timeline_create(tenant_id, timeline_id, pg_version, last_lsn) + f_partial_path = ( + Path(sk.data_dir()) / str(tenant_id) / str(timeline_id) / f_partial_saved.name + ) + shutil.copy(f_partial_saved, f_partial_path) + + # recreate timeline on pageserver from scratch + ps_cli.timeline_delete(tenant_id, timeline_id) + ps_cli.timeline_create(tenant_id, timeline_id) - # start pageserver and wait for replay - env.pageserver.start() wait_lsn_timeout = 60 * 3 started_at = time.time() last_debug_print = 0.0 @@ -553,10 +574,10 @@ def test_s3_wal_replay(neon_env_builder: NeonEnvBuilder, remote_storage_kind: Re if elapsed > wait_lsn_timeout: raise RuntimeError("Timed out waiting for WAL redo") - pageserver_lsn = env.pageserver.http_client().timeline_detail(tenant_id, timeline_id)[ - "local" - ]["last_record_lsn"] - lag = Lsn(last_lsn) - Lsn(pageserver_lsn) + pageserver_lsn = Lsn( + env.pageserver.http_client().timeline_detail(tenant_id, timeline_id)["last_record_lsn"] + ) + lag = last_lsn - pageserver_lsn if time.time() > last_debug_print + 10 or lag <= 0: last_debug_print = time.time() @@ -1093,10 +1114,7 @@ def test_delete_force(neon_env_builder: NeonEnvBuilder, auth_enabled: bool): cur.execute("INSERT INTO t (key) VALUES (1)") # Remove initial tenant's br1 (active) - assert sk_http.timeline_delete_force(tenant_id, timeline_id_1) == { - "dir_existed": True, - "was_active": True, - } + assert sk_http.timeline_delete_force(tenant_id, timeline_id_1)["dir_existed"] assert not (sk_data_dir / str(tenant_id) / str(timeline_id_1)).exists() assert (sk_data_dir / str(tenant_id) / str(timeline_id_2)).is_dir() assert (sk_data_dir / str(tenant_id) / str(timeline_id_3)).is_dir() @@ -1104,10 +1122,7 @@ def test_delete_force(neon_env_builder: NeonEnvBuilder, auth_enabled: bool): assert (sk_data_dir / str(tenant_id_other) / str(timeline_id_other)).is_dir() # Ensure repeated deletion succeeds - assert sk_http.timeline_delete_force(tenant_id, timeline_id_1) == { - "dir_existed": False, - "was_active": False, - } + assert not sk_http.timeline_delete_force(tenant_id, timeline_id_1)["dir_existed"] assert not (sk_data_dir / str(tenant_id) / str(timeline_id_1)).exists() assert (sk_data_dir / str(tenant_id) / str(timeline_id_2)).is_dir() assert (sk_data_dir / str(tenant_id) / str(timeline_id_3)).is_dir() @@ -1124,10 +1139,7 @@ def test_delete_force(neon_env_builder: NeonEnvBuilder, auth_enabled: bool): assert (sk_data_dir / str(tenant_id_other) / str(timeline_id_other)).is_dir() # Remove initial tenant's br2 (inactive) - assert sk_http.timeline_delete_force(tenant_id, timeline_id_2) == { - "dir_existed": True, - "was_active": False, - } + assert sk_http.timeline_delete_force(tenant_id, timeline_id_2)["dir_existed"] assert not (sk_data_dir / str(tenant_id) / str(timeline_id_1)).exists() assert not (sk_data_dir / str(tenant_id) / str(timeline_id_2)).exists() assert (sk_data_dir / str(tenant_id) / str(timeline_id_3)).is_dir() @@ -1135,10 +1147,7 @@ def test_delete_force(neon_env_builder: NeonEnvBuilder, auth_enabled: bool): assert (sk_data_dir / str(tenant_id_other) / str(timeline_id_other)).is_dir() # Remove non-existing branch, should succeed - assert sk_http.timeline_delete_force(tenant_id, TimelineId("00" * 16)) == { - "dir_existed": False, - "was_active": False, - } + assert not sk_http.timeline_delete_force(tenant_id, TimelineId("00" * 16))["dir_existed"] assert not (sk_data_dir / str(tenant_id) / str(timeline_id_1)).exists() assert not (sk_data_dir / str(tenant_id) / str(timeline_id_2)).exists() assert (sk_data_dir / str(tenant_id) / str(timeline_id_3)).exists() @@ -1147,10 +1156,7 @@ def test_delete_force(neon_env_builder: NeonEnvBuilder, auth_enabled: bool): # Remove initial tenant fully (two branches are active) response = sk_http.tenant_delete_force(tenant_id) - assert response[str(timeline_id_3)] == { - "dir_existed": True, - "was_active": True, - } + assert response[str(timeline_id_3)]["dir_existed"] assert not (sk_data_dir / str(tenant_id)).exists() assert (sk_data_dir / str(tenant_id_other) / str(timeline_id_other)).is_dir() diff --git a/test_runner/regress/test_wal_acceptor_async.py b/test_runner/regress/test_wal_acceptor_async.py index 9d2008296a..70ae6bae18 100644 --- a/test_runner/regress/test_wal_acceptor_async.py +++ b/test_runner/regress/test_wal_acceptor_async.py @@ -179,9 +179,7 @@ async def run_restarts_under_load( log.info(f"Postgres flush_lsn {flush_lsn}") pageserver_lsn = Lsn( - env.pageserver.http_client().timeline_detail(tenant_id, timeline_id)["local"][ - "last_record_lsn" - ] + env.pageserver.http_client().timeline_detail(tenant_id, timeline_id)["last_record_lsn"] ) sk_ps_lag = flush_lsn - pageserver_lsn log.info(f"Pageserver last_record_lsn={pageserver_lsn} lag={sk_ps_lag / 1024}kb") diff --git a/vendor/postgres-v14 b/vendor/postgres-v14 index 19d948fd47..bdd502a8da 160000 --- a/vendor/postgres-v14 +++ b/vendor/postgres-v14 @@ -1 +1 @@ -Subproject commit 19d948fd47f45d83367062d9a54709cf2d9c8921 +Subproject commit bdd502a8da5de9e0ac709caabc0401455c97d235 diff --git a/vendor/postgres-v15 b/vendor/postgres-v15 index ff18cec1ee..f7c5269e9c 160000 --- a/vendor/postgres-v15 +++ b/vendor/postgres-v15 @@ -1 +1 @@ -Subproject commit ff18cec1ee9b80055accd9c76b040875329b11ed +Subproject commit f7c5269e9c7e818653ad6fe95ba072d1901c4497 diff --git a/workspace_hack/Cargo.toml b/workspace_hack/Cargo.toml index 6977665c7d..f4468d85f0 100644 --- a/workspace_hack/Cargo.toml +++ b/workspace_hack/Cargo.toml @@ -8,7 +8,6 @@ version = "0.1.0" description = "workspace-hack package, managed by hakari" # You can choose to publish this crate: see https://docs.rs/cargo-hakari/latest/cargo_hakari/publishing. publish = false - # The parts of the file between the BEGIN HAKARI SECTION and END HAKARI SECTION comments # are managed by hakari. @@ -16,18 +15,17 @@ publish = false [dependencies] ahash = { version = "0.7", features = ["std"] } anyhow = { version = "1", features = ["backtrace", "std"] } -bstr = { version = "0.2", features = ["lazy_static", "regex-automata", "serde", "serde1", "serde1-nostd", "std", "unicode"] } bytes = { version = "1", features = ["serde", "std"] } -chrono = { version = "0.4", features = ["clock", "libc", "oldtime", "serde", "std", "time", "winapi"] } +chrono = { version = "0.4", features = ["clock", "iana-time-zone", "js-sys", "oldtime", "serde", "std", "time", "wasm-bindgen", "wasmbind", "winapi"] } +clap = { version = "4", features = ["color", "error-context", "help", "std", "string", "suggestions", "usage"] } crossbeam-utils = { version = "0.8", features = ["once_cell", "std"] } either = { version = "1", features = ["use_std"] } fail = { version = "0.5", default-features = false, features = ["failpoints"] } hashbrown = { version = "0.12", features = ["ahash", "inline-more", "raw"] } indexmap = { version = "1", default-features = false, features = ["std"] } -itoa = { version = "0.4", features = ["i128", "std"] } libc = { version = "0.2", features = ["extra_traits", "std"] } log = { version = "0.4", default-features = false, features = ["serde", "std"] } -memchr = { version = "2", features = ["std", "use_std"] } +memchr = { version = "2", features = ["std"] } nom = { version = "7", features = ["alloc", "std"] } num-bigint = { version = "0.4", features = ["std"] } num-integer = { version = "0.1", default-features = false, features = ["i128", "std"] } @@ -35,7 +33,6 @@ num-traits = { version = "0.2", features = ["i128", "libm", "std"] } prost = { version = "0.10", features = ["prost-derive", "std"] } rand = { version = "0.8", features = ["alloc", "getrandom", "libc", "rand_chacha", "rand_hc", "small_rng", "std", "std_rng"] } regex = { version = "1", features = ["aho-corasick", "memchr", "perf", "perf-cache", "perf-dfa", "perf-inline", "perf-literal", "std", "unicode", "unicode-age", "unicode-bool", "unicode-case", "unicode-gencat", "unicode-perl", "unicode-script", "unicode-segment"] } -regex-automata = { version = "0.1", features = ["regex-syntax", "std"] } regex-syntax = { version = "0.6", features = ["unicode", "unicode-age", "unicode-bool", "unicode-case", "unicode-gencat", "unicode-perl", "unicode-script", "unicode-segment"] } scopeguard = { version = "1", features = ["use_std"] } serde = { version = "1", features = ["alloc", "derive", "serde_derive", "std"] } @@ -45,7 +42,6 @@ tokio = { version = "1", features = ["bytes", "fs", "io-std", "io-util", "libc", tokio-util = { version = "0.7", features = ["codec", "io", "io-util", "tracing"] } tracing = { version = "0.1", features = ["attributes", "log", "std", "tracing-attributes"] } tracing-core = { version = "0.1", features = ["once_cell", "std"] } -uuid = { version = "0.8", features = ["getrandom", "serde", "std", "v4"] } [build-dependencies] ahash = { version = "0.7", features = ["std"] } @@ -56,7 +52,7 @@ hashbrown = { version = "0.12", features = ["ahash", "inline-more", "raw"] } indexmap = { version = "1", default-features = false, features = ["std"] } libc = { version = "0.2", features = ["extra_traits", "std"] } log = { version = "0.4", default-features = false, features = ["serde", "std"] } -memchr = { version = "2", features = ["std", "use_std"] } +memchr = { version = "2", features = ["std"] } nom = { version = "7", features = ["alloc", "std"] } prost = { version = "0.10", features = ["prost-derive", "std"] } regex = { version = "1", features = ["aho-corasick", "memchr", "perf", "perf-cache", "perf-dfa", "perf-inline", "perf-literal", "std", "unicode", "unicode-age", "unicode-bool", "unicode-case", "unicode-gencat", "unicode-perl", "unicode-script", "unicode-segment"] }