pax_global_header00006660000000000000000000000064144020434470014514gustar00rootroot0000000000000052 comment=6ee6fa1a88df6ea098f6b7dddde29e33f09d5331 stargz-snapshotter-0.14.3/000077500000000000000000000000001440204344700154635ustar00rootroot00000000000000stargz-snapshotter-0.14.3/.dockerignore000066400000000000000000000000041440204344700201310ustar00rootroot00000000000000/outstargz-snapshotter-0.14.3/.github/000077500000000000000000000000001440204344700170235ustar00rootroot00000000000000stargz-snapshotter-0.14.3/.github/dependabot.yml000066400000000000000000000020271440204344700216540ustar00rootroot00000000000000version: 2 updates: # Automatic upgrade for go modules. - package-ecosystem: "gomod" directory: "/" schedule: interval: "daily" ignore: # We upgrade this manually on each release - dependency-name: "github.com/containerd/stargz-snapshotter/estargz" # Automatic upgrade for go modules of estargz package. - package-ecosystem: "gomod" directory: "/estargz" schedule: interval: "daily" # Automatic upgrade for go modules of ipfs package. - package-ecosystem: "gomod" directory: "/ipfs" schedule: interval: "daily" # Automatic upgrade for go modules of cmd package. - package-ecosystem: "gomod" directory: "/cmd" schedule: interval: "daily" # Automatic upgrade for base images used in the Dockerfile - package-ecosystem: "docker" directory: "/" schedule: interval: "daily" # Automatic upgrade for Github Actions - package-ecosystem: "github-actions" directory: "/" # means ".github/workflows" schedule: interval: "daily" stargz-snapshotter-0.14.3/.github/workflows/000077500000000000000000000000001440204344700210605ustar00rootroot00000000000000stargz-snapshotter-0.14.3/.github/workflows/benchmark.yml000066400000000000000000000030441440204344700235360ustar00rootroot00000000000000name: Benchmark on: push: branches: - main pull_request: env: DOCKER_BUILDKIT: 1 jobs: hello-bench: runs-on: ubuntu-22.04 name: HelloBench env: BENCHMARK_LOG_DIR: ${{ github.workspace }}/log/ BENCHMARK_RESULT_DIR: ${{ github.workspace }}/benchmark/ BENCHMARK_REGISTRY: ghcr.io BENCHMARK_USER: stargz-containers BENCHMARK_TARGETS: python:3.10 gcc:11.2.0 postgres:14.2 tomcat:10.1.0-jdk17-openjdk-bullseye BENCHMARK_SAMPLES_NUM: 5 BENCHMARK_PERCENTILE: 95 BENCHMARK_PERCENTILES_GRANULARITY: 25 strategy: fail-fast: false max-parallel: 1 matrix: runtime: ["podman", "containerd"] steps: - name: Install tools run: | sudo apt-get update && sudo apt-get --no-install-recommends install -y gnuplot pip install numpy - uses: actions/checkout@v3 - name: Prepare directories run: mkdir "${BENCHMARK_RESULT_DIR}" "${BENCHMARK_LOG_DIR}" - name: Get instance information run: | curl -H "Metadata:true" "http://169.254.169.254/metadata/instance?api-version=2019-11-01" | \ jq '{ location : .compute.location, vmSize : .compute.vmSize }' | \ tee ${{ env.BENCHMARK_RESULT_DIR }}/instance.json - name: Run benchmark env: BENCHMARK_RUNTIME_MODE: ${{ matrix.runtime }} run: make benchmark - uses: actions/upload-artifact@v3 if: ${{ always() }} with: name: benchmarking-result-${{ matrix.runtime }} path: ${{ env.BENCHMARK_RESULT_DIR }} stargz-snapshotter-0.14.3/.github/workflows/kind-image.yml000066400000000000000000000017521440204344700236150ustar00rootroot00000000000000name: Kind image on: push: tags: - 'v*' env: REGISTRY: ghcr.io IMAGE_NAME: ${{ github.repository }} jobs: kind-image: runs-on: ubuntu-22.04 name: Kind image steps: - name: Checkout uses: actions/checkout@v3 - name: Docker meta id: meta uses: docker/metadata-action@v4 with: images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} tags: | type=semver,pattern={{version}}-kind - name: Login to GHCR if: github.event_name != 'pull_request' uses: docker/login-action@v2 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Build and push uses: docker/build-push-action@v4.0.0 with: context: . push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} stargz-snapshotter-0.14.3/.github/workflows/nightly.yml000066400000000000000000000064431440204344700232700ustar00rootroot00000000000000name: Nightly on: schedule: - cron: '0 0 * * *' # Every day at midnight pull_request: paths: - '.github/workflows/nightly.yml' # This nightly test helps us to track changes on containerd on daily basis # and enable us to quickly fix snapshotter when some of recent changes on # containerd cause incompatibility with this snapshotter. # # TODO1(ktock): Output binaries if needed. # TODO2(ktock): Ideally, this test should be invoked in containerd/containerd's CI on each PR. # This will make sure that each commit merged into containerd/containerd safely # works with stargz snapshotter. env: DOCKER_BUILDKIT: 1 DOCKER_BUILD_ARGS: --build-arg=CONTAINERD_VERSION=main # do tests with the latest containerd jobs: integration: runs-on: ubuntu-22.04 name: Integration steps: - name: Install htpasswd for setting up private registry run: sudo apt-get update -y && sudo apt-get --no-install-recommends install -y apache2-utils - uses: actions/checkout@v3 - name: Run integration test run: make integration test-optimize: runs-on: ubuntu-22.04 name: Optimize steps: - name: Install htpasswd for setting up private registry run: sudo apt-get update -y && sudo apt-get --no-install-recommends install -y apache2-utils - uses: actions/checkout@v3 - name: Run test for optimize subcommand of ctr-remote run: make test-optimize test-kind: runs-on: ubuntu-22.04 name: Kind steps: - name: Install htpasswd for setting up private registry run: sudo apt-get update -y && sudo apt-get --no-install-recommends install -y apache2-utils - uses: actions/checkout@v3 - name: Run test for pulling image from private registry on Kubernetes run: make test-kind test-criauth: runs-on: ubuntu-22.04 name: CRIAuth steps: - name: Install htpasswd for setting up private registry run: sudo apt-get update -y && sudo apt-get --no-install-recommends install -y apache2-utils - uses: actions/checkout@v3 - name: Run test for pulling image from private registry on Kubernetes run: make test-criauth test-cri-containerd: runs-on: ubuntu-22.04 name: CRIValidationContainerd steps: - uses: actions/checkout@v3 - name: Varidate the runtime through CRI with containerd run: make test-cri-containerd test-cri-o: runs-on: ubuntu-18.04 name: CRIValidationCRIO steps: - uses: actions/checkout@v3 - name: Varidate the runtime through CRI with CRI-O env: DOCKER_BUILD_ARGS: "--build-arg=RUNC_VERSION=v1.0.3" run: make test-cri-o test-k3s: runs-on: ubuntu-22.04 name: K3S steps: - uses: actions/setup-go@v3 with: go-version: '1.19.x' - name: Install k3d run: | wget -q -O - https://raw.githubusercontent.com/rancher/k3d/v5.0.0/install.sh | bash - name: Install htpasswd for setting up private registry run: sudo apt-get update -y && sudo apt-get --no-install-recommends install -y apache2-utils - name: Install yq run: | sudo wget -O /usr/local/bin/yq https://github.com/mikefarah/yq/releases/download/v4.9.3/yq_linux_amd64 sudo chmod +x /usr/local/bin/yq - uses: actions/checkout@v3 - name: Run test with k3s run: make test-k3s stargz-snapshotter-0.14.3/.github/workflows/release.yml000066400000000000000000000040311440204344700232210ustar00rootroot00000000000000name: Release on: push: tags: - 'v*' env: DOCKER_BUILDKIT: 1 jobs: build: runs-on: ubuntu-22.04 name: Build strategy: matrix: arch: ["amd64", "arm-v7", "arm64", "ppc64le", "s390x"] env: OUTPUT_DIR: ${{ github.workspace }}/out steps: - uses: actions/checkout@v3 - name: Build Binary env: DOCKER_BUILDKIT: 1 run: | mkdir ${OUTPUT_DIR} RELEASE_TAG="${GITHUB_REF##*/}" ARCH_ID="${{ matrix.arch }}" BUILD_ARGS=--build-arg=TARGETARCH=${ARCH_ID} if [ "${ARCH_ID}" == "arm-v7" ] ; then BUILD_ARGS="--build-arg=TARGETARCH=arm --build-arg=GOARM=7" fi TAR_FILE_NAME="stargz-snapshotter-${RELEASE_TAG}-linux-${ARCH_ID}.tar.gz" SHA256SUM_FILE_NAME="${TAR_FILE_NAME}.sha256sum" docker build ${BUILD_ARGS} --target release-binaries -o - . | gzip > "${OUTPUT_DIR}/${TAR_FILE_NAME}" ( cd ${OUTPUT_DIR}; sha256sum ${TAR_FILE_NAME} ) > "${OUTPUT_DIR}/${SHA256SUM_FILE_NAME}" - name: Save Binary uses: actions/upload-artifact@v3 with: name: builds-${{ matrix.arch }} path: ${{ env.OUTPUT_DIR }}/* release: runs-on: ubuntu-22.04 name: Release needs: [build] env: OUTPUT_DIR: ${{ github.workspace }}/builds steps: - uses: actions/checkout@v3 - name: Download Builds uses: actions/download-artifact@v3 with: path: ${{ env.OUTPUT_DIR }} - name: Create Release env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | RELEASE_TAG="${GITHUB_REF##*/}" cat < ${GITHUB_WORKSPACE}/release-note.txt ${RELEASE_TAG} (TBD) EOF ASSET_FLAGS=() ls -al ${OUTPUT_DIR}/ for A in "amd64" "arm-v7" "arm64" "ppc64le" "s390x" ; do for F in ${OUTPUT_DIR}/builds-${A}/* ; do ASSET_FLAGS+=("-a" "$F") done done hub release create "${ASSET_FLAGS[@]}" -F ${GITHUB_WORKSPACE}/release-note.txt --draft "${RELEASE_TAG}" stargz-snapshotter-0.14.3/.github/workflows/tests.yml000066400000000000000000000176401440204344700227550ustar00rootroot00000000000000name: Tests on: push: branches: - main pull_request: env: DOCKER_BUILDKIT: 1 jobs: build: runs-on: ubuntu-22.04 name: Build steps: - uses: actions/checkout@v3 - name: Build all run: ./script/util/make.sh build -j2 test: runs-on: ubuntu-22.04 name: Test steps: - uses: actions/checkout@v3 - name: Test all run: ./script/util/make.sh test-all -j2 linter: runs-on: ubuntu-22.04 name: Linter steps: - uses: actions/checkout@v3 with: fetch-depth: '0' - uses: actions/setup-go@v3 with: go-version: '1.19.x' - name: golangci-lint uses: golangci/golangci-lint-action@v3.4.0 with: version: v1.49.0 args: --verbose integration: runs-on: ubuntu-22.04 name: Integration strategy: fail-fast: false matrix: buildargs: ["", "--build-arg=CONTAINERD_VERSION=main"] # released version & main version builtin: ["true", "false"] metadata-store: ["memory", "db"] exclude: - buildargs: "" builtin: "true" - metadata-store: "db" builtin: "true" - metadata-store: "db" buildargs: "--build-arg=CONTAINERD_VERSION=main" steps: - name: Install htpasswd for setting up private registry run: sudo apt-get update -y && sudo apt-get --no-install-recommends install -y apache2-utils - uses: actions/checkout@v3 - name: Run integration test env: DOCKER_BUILD_ARGS: ${{ matrix.buildargs }} BUILTIN_SNAPSHOTTER: ${{ matrix.builtin }} METADATA_STORE: ${{ matrix.metadata-store }} run: make integration test-optimize: runs-on: ubuntu-22.04 name: Optimize strategy: fail-fast: false matrix: buildargs: ["", "--build-arg=CONTAINERD_VERSION=main"] # released version & main version steps: - name: Install htpasswd for setting up private registry run: sudo apt-get update -y && sudo apt-get --no-install-recommends install -y apache2-utils - uses: actions/checkout@v3 - name: Run test for optimize subcommand of ctr-remote env: DOCKER_BUILD_ARGS: ${{ matrix.buildargs }} run: make test-optimize test-kind: runs-on: ubuntu-22.04 name: Kind strategy: fail-fast: false matrix: buildargs: ["", "--build-arg=CONTAINERD_VERSION=main"] # released version & main version builtin: ["true", "false"] exclude: - buildargs: "" builtin: "true" steps: - name: Install htpasswd for setting up private registry run: sudo apt-get update -y && sudo apt-get --no-install-recommends install -y apache2-utils - uses: actions/checkout@v3 - name: Run test for pulling image from private registry on Kubernetes env: DOCKER_BUILD_ARGS: ${{ matrix.buildargs }} BUILTIN_SNAPSHOTTER: ${{ matrix.builtin }} run: make test-kind test-criauth: runs-on: ubuntu-22.04 name: CRIAuth strategy: fail-fast: false matrix: buildargs: ["", "--build-arg=CONTAINERD_VERSION=main"] # released version & main version builtin: ["true", "false"] exclude: - buildargs: "" builtin: "true" steps: - name: Install htpasswd for setting up private registry run: sudo apt-get update -y && sudo apt-get --no-install-recommends install -y apache2-utils - uses: actions/checkout@v3 - name: Run test for pulling image from private registry on Kubernetes with CRI keychain mode env: DOCKER_BUILD_ARGS: ${{ matrix.buildargs }} BUILTIN_SNAPSHOTTER: ${{ matrix.builtin }} run: make test-criauth test-cri-containerd: runs-on: ubuntu-22.04 name: CRIValidationContainerd strategy: fail-fast: false matrix: buildargs: ["", "--build-arg=CONTAINERD_VERSION=main"] # released version & main version builtin: ["true", "false"] metadata-store: ["memory", "db"] exclude: - buildargs: "" builtin: "true" - metadata-store: "db" builtin: "true" - metadata-store: "db" buildargs: "--build-arg=CONTAINERD_VERSION=main" steps: - uses: actions/checkout@v3 - name: Validate containerd through CRI env: DOCKER_BUILD_ARGS: ${{ matrix.buildargs }} BUILTIN_SNAPSHOTTER: ${{ matrix.builtin }} METADATA_STORE: ${{ matrix.metadata-store }} run: make test-cri-containerd test-cri-cri-o: runs-on: ubuntu-18.04 name: CRIValidationCRIO strategy: fail-fast: false matrix: metadata-store: ["memory", "db"] steps: - uses: actions/checkout@v3 - name: Validate CRI-O through CRI env: DOCKER_BUILD_ARGS: "--build-arg=RUNC_VERSION=v1.0.3" METADATA_STORE: ${{ matrix.metadata-store }} run: make test-cri-o test-podman: runs-on: ubuntu-22.04 name: PodmanRootless steps: - uses: actions/checkout@v3 - name: Test Podman (rootless) run: make test-podman test-k3s: runs-on: ubuntu-22.04 name: K3S steps: - uses: actions/setup-go@v3 with: go-version: '1.19.x' - name: Install k3d run: | wget -q -O - https://raw.githubusercontent.com/rancher/k3d/v5.0.0/install.sh | bash - name: Install htpasswd for setting up private registry run: sudo apt-get update -y && sudo apt-get --no-install-recommends install -y apache2-utils - name: Install yq run: | sudo wget -O /usr/local/bin/yq https://github.com/mikefarah/yq/releases/download/v4.9.3/yq_linux_amd64 sudo chmod +x /usr/local/bin/yq - uses: actions/checkout@v3 - name: Run test with k3s run: make test-k3s test-ipfs: runs-on: ubuntu-22.04 name: IPFS steps: - uses: actions/checkout@v3 - name: Run test run: make test-ipfs test-k3s-argo-workflow: runs-on: ubuntu-22.04 name: K3SArgoWorkflow env: RESULT_DIR: ${{ github.workspace }}/argo-workflow/ steps: - uses: actions/setup-go@v3 with: go-version: '1.19.x' - name: Install k3d run: | wget -q -O - https://raw.githubusercontent.com/rancher/k3d/v5.0.0/install.sh | bash - name: Install argo worklflow run: | wget -q https://github.com/argoproj/argo-workflows/releases/download/v3.0.10/argo-linux-amd64.gz gunzip argo-linux-amd64.gz sudo mv argo-linux-amd64 /usr/local/bin/argo sudo chmod +x /usr/local/bin/argo - uses: actions/checkout@v3 - name: Prepare directories run: mkdir "${RESULT_DIR}" - name: Get instance information run: | curl -H "Metadata:true" "http://169.254.169.254/metadata/instance?api-version=2019-11-01" | \ jq '{ location : .compute.location, vmSize : .compute.vmSize }' | \ tee ${{ env.RESULT_DIR }}/instance.json - name: Run argo workflow env: RESULT: ${{ env.RESULT_DIR }}/result.json run: make test-k3s-argo-workflow - uses: actions/upload-artifact@v3 with: name: k3s-argo-workflow path: ${{ env.RESULT_DIR }} # # Project checks # NOTE: Jobs for project checks commonly used in containerd projects # See https://github.com/containerd/project-checks # project: name: Project Checks runs-on: ubuntu-22.04 timeout-minutes: 5 steps: - uses: actions/setup-go@v3 with: go-version: '1.19.x' - uses: actions/checkout@v3 with: path: src/github.com/containerd/stargz-snapshotter fetch-depth: 25 - uses: containerd/project-checks@v1 with: working-directory: src/github.com/containerd/stargz-snapshotter - name: Check proto generated code run: make validate-generated working-directory: src/github.com/containerd/stargz-snapshotter - run: ./script/util/verify-no-patent.sh working-directory: src/github.com/containerd/stargz-snapshotter stargz-snapshotter-0.14.3/.gitignore000066400000000000000000000000041440204344700174450ustar00rootroot00000000000000/outstargz-snapshotter-0.14.3/.golangci.yml000066400000000000000000000006211440204344700200460ustar00rootroot00000000000000# This is applied to `estargz` submodule as well. # https://golangci-lint.run/usage/configuration#config-file linters: enable: - structcheck - varcheck - staticcheck - unconvert - gofmt - goimports - revive - ineffassign - vet - unused - misspell disable: - errcheck run: deadline: 4m skip-dirs: - docs - images - out - script stargz-snapshotter-0.14.3/Dockerfile000066400000000000000000000347171440204344700174710ustar00rootroot00000000000000# Copyright The containerd Authors. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. ARG CONTAINERD_VERSION=v1.7.0-rc.2 ARG RUNC_VERSION=v1.1.4 ARG CNI_PLUGINS_VERSION=v1.1.1 ARG NERDCTL_VERSION=1.1.0 ARG PODMAN_VERSION=v4.3.1 ARG CRIO_VERSION=v1.26.1 ARG CONMON_VERSION=v2.1.5 ARG COMMON_VERSION=v0.49.2 ARG CRIO_TEST_PAUSE_IMAGE_NAME=registry.k8s.io/pause:3.6 ARG CONTAINERIZED_SYSTEMD_VERSION=v0.1.1 ARG SLIRP4NETNS_VERSION=v1.1.12 # Used in CI ARG CRI_TOOLS_VERSION=v1.26.0 # Legacy builder that doesn't support TARGETARCH should set this explicitly using --build-arg. # If TARGETARCH isn't supported by the builder, the default value is "amd64". FROM golang:1.20.1-bullseye AS golang-base # Build containerd FROM golang-base AS containerd-dev ARG CONTAINERD_VERSION RUN apt-get update -y && apt-get install -y libbtrfs-dev libseccomp-dev && \ git clone -b ${CONTAINERD_VERSION} --depth 1 \ https://github.com/containerd/containerd $GOPATH/src/github.com/containerd/containerd && \ cd $GOPATH/src/github.com/containerd/containerd && \ make && DESTDIR=/out/ PREFIX= make install # Build containerd with builtin stargz snapshotter FROM golang-base AS containerd-snapshotter-dev ARG CONTAINERD_VERSION COPY . $GOPATH/src/github.com/containerd/stargz-snapshotter RUN apt-get update -y && apt-get install -y libbtrfs-dev libseccomp-dev && \ git clone -b ${CONTAINERD_VERSION} --depth 1 \ https://github.com/containerd/containerd $GOPATH/src/github.com/containerd/containerd && \ cd $GOPATH/src/github.com/containerd/containerd && \ echo 'require github.com/containerd/stargz-snapshotter v0.0.0' >> go.mod && \ echo 'replace github.com/containerd/stargz-snapshotter => '$GOPATH'/src/github.com/containerd/stargz-snapshotter' >> go.mod && \ echo 'replace github.com/containerd/stargz-snapshotter/estargz => '$GOPATH'/src/github.com/containerd/stargz-snapshotter/estargz' >> go.mod && \ # recent containerd requires to update api/go.mod and integration/client/go.mod as well. if [ -f api/go.mod ] ; then \ echo 'replace github.com/containerd/stargz-snapshotter => '$GOPATH'/src/github.com/containerd/stargz-snapshotter' >> api/go.mod && \ echo 'replace github.com/containerd/stargz-snapshotter/estargz => '$GOPATH'/src/github.com/containerd/stargz-snapshotter/estargz' >> api/go.mod ; \ fi && \ if [ -f integration/client/go.mod ] ; then \ echo 'replace github.com/containerd/stargz-snapshotter => '$GOPATH'/src/github.com/containerd/stargz-snapshotter' >> integration/client/go.mod && \ echo 'replace github.com/containerd/stargz-snapshotter/estargz => '$GOPATH'/src/github.com/containerd/stargz-snapshotter/estargz' >> integration/client/go.mod ; \ fi && \ echo 'package main \nimport _ "github.com/containerd/stargz-snapshotter/service/plugin"' > cmd/containerd/builtins_stargz_snapshotter.go && \ make vendor && make && DESTDIR=/out/ PREFIX= make install # Build runc FROM golang-base AS runc-dev ARG RUNC_VERSION RUN apt-get update -y && apt-get install -y libseccomp-dev && \ git clone -b ${RUNC_VERSION} --depth 1 \ https://github.com/opencontainers/runc $GOPATH/src/github.com/opencontainers/runc && \ cd $GOPATH/src/github.com/opencontainers/runc && \ make && make install PREFIX=/out/ # Build stargz snapshotter FROM golang-base AS snapshotter-dev ARG TARGETARCH ARG GOARM ARG SNAPSHOTTER_BUILD_FLAGS ARG CTR_REMOTE_BUILD_FLAGS COPY . $GOPATH/src/github.com/containerd/stargz-snapshotter RUN cd $GOPATH/src/github.com/containerd/stargz-snapshotter && \ PREFIX=/out/ GOARCH=${TARGETARCH:-amd64} GO_BUILD_FLAGS=${SNAPSHOTTER_BUILD_FLAGS} make containerd-stargz-grpc && \ PREFIX=/out/ GOARCH=${TARGETARCH:-amd64} GO_BUILD_FLAGS=${CTR_REMOTE_BUILD_FLAGS} make ctr-remote # Build stargz store FROM golang-base AS stargz-store-dev ARG TARGETARCH ARG GOARM ARG SNAPSHOTTER_BUILD_FLAGS ARG CTR_REMOTE_BUILD_FLAGS COPY . $GOPATH/src/github.com/containerd/stargz-snapshotter RUN cd $GOPATH/src/github.com/containerd/stargz-snapshotter && \ PREFIX=/out/ GOARCH=${TARGETARCH:-amd64} GO_BUILD_FLAGS=${SNAPSHOTTER_BUILD_FLAGS} make stargz-store # Build podman FROM golang-base AS podman-dev ARG PODMAN_VERSION RUN apt-get update -y && apt-get install -y libseccomp-dev libgpgme-dev && \ git clone https://github.com/containers/podman $GOPATH/src/github.com/containers/podman && \ cd $GOPATH/src/github.com/containers/podman && \ git checkout ${PODMAN_VERSION} && \ make && make install PREFIX=/out/ # Build CRI-O FROM golang-base AS cri-o-dev ARG CRIO_VERSION RUN apt-get update -y && apt-get install -y libseccomp-dev libgpgme-dev && \ git clone https://github.com/cri-o/cri-o $GOPATH/src/github.com/cri-o/cri-o && \ cd $GOPATH/src/github.com/cri-o/cri-o && \ git checkout ${CRIO_VERSION} && \ make && make install PREFIX=/out/ && \ curl -sSL --output /out/crio.service https://raw.githubusercontent.com/cri-o/cri-o/${CRIO_VERSION}/contrib/systemd/crio.service # Build conmon FROM golang-base AS conmon-dev ARG CONMON_VERSION RUN apt-get update -y && apt-get install -y gcc git libc6-dev libglib2.0-dev pkg-config make libseccomp-dev && \ git clone -b ${CONMON_VERSION} --depth 1 \ https://github.com/containers/conmon $GOPATH/src/github.com/containers/conmon && \ cd $GOPATH/src/github.com/containers/conmon && \ mkdir /out/ && make && make install PREFIX=/out/ # Get seccomp.json for Podman/CRI-O FROM golang-base AS containers-common-dev ARG COMMON_VERSION RUN git clone https://github.com/containers/common $GOPATH/src/github.com/containers/common && \ cd $GOPATH/src/github.com/containers/common && \ git checkout ${COMMON_VERSION} && mkdir /out/ && cp pkg/seccomp/seccomp.json /out/ # Binaries for release FROM scratch AS release-binaries COPY --from=snapshotter-dev /out/* / COPY --from=stargz-store-dev /out/* / # Base image which contains containerd with default snapshotter FROM golang-base AS containerd-base ARG TARGETARCH ARG NERDCTL_VERSION RUN apt-get update -y && apt-get --no-install-recommends install -y fuse3 && \ curl -sSL --output /tmp/nerdctl.tgz https://github.com/containerd/nerdctl/releases/download/v${NERDCTL_VERSION}/nerdctl-${NERDCTL_VERSION}-linux-${TARGETARCH:-amd64}.tar.gz && \ tar zxvf /tmp/nerdctl.tgz -C /usr/local/bin && \ rm -f /tmp/nerdctl.tgz COPY --from=containerd-dev /out/bin/containerd /out/bin/containerd-shim-runc-v2 /usr/local/bin/ COPY --from=runc-dev /out/sbin/* /usr/local/sbin/ # Base image which contains containerd with stargz snapshotter FROM containerd-base AS snapshotter-base COPY --from=snapshotter-dev /out/* /usr/local/bin/ RUN ln -s /usr/local/bin/ctr-remote /usr/local/bin/ctr # Base image which contains containerd with builtin stargz snapshotter FROM golang-base AS containerd-snapshotter-base ARG TARGETARCH ARG NERDCTL_VERSION RUN apt-get update -y && apt-get --no-install-recommends install -y fuse3 && \ curl -sSL --output /tmp/nerdctl.tgz https://github.com/containerd/nerdctl/releases/download/v${NERDCTL_VERSION}/nerdctl-${NERDCTL_VERSION}-linux-${TARGETARCH:-amd64}.tar.gz && \ tar zxvf /tmp/nerdctl.tgz -C /usr/local/bin && \ rm -f /tmp/nerdctl.tgz COPY --from=containerd-snapshotter-dev /out/bin/containerd /out/bin/containerd-shim-runc-v2 /usr/local/bin/ COPY --from=runc-dev /out/sbin/* /usr/local/sbin/ COPY --from=snapshotter-dev /out/ctr-remote /usr/local/bin/ RUN ln -s /usr/local/bin/ctr-remote /usr/local/bin/ctr # Base image which contains podman with stargz-store FROM golang-base AS podman-base ARG TARGETARCH ARG CNI_PLUGINS_VERSION ARG PODMAN_VERSION RUN apt-get update -y && apt-get --no-install-recommends install -y fuse3 libgpgme-dev \ iptables libyajl-dev && \ # Make CNI plugins manipulate iptables instead of nftables # as this test runs in a Docker container that network is configured with iptables. # c.f. https://github.com/moby/moby/issues/26824 update-alternatives --set iptables /usr/sbin/iptables-legacy && \ mkdir -p /etc/containers /etc/cni/net.d /opt/cni/bin && \ curl -qsSL https://raw.githubusercontent.com/containers/podman/${PODMAN_VERSION}/cni/87-podman-bridge.conflist | tee /etc/cni/net.d/87-podman-bridge.conflist && \ curl -Ls https://github.com/containernetworking/plugins/releases/download/${CNI_PLUGINS_VERSION}/cni-plugins-linux-${TARGETARCH:-amd64}-${CNI_PLUGINS_VERSION}.tgz | tar xzv -C /opt/cni/bin COPY --from=podman-dev /out/bin/* /usr/local/bin/ COPY --from=runc-dev /out/sbin/* /usr/local/sbin/ COPY --from=conmon-dev /out/bin/* /usr/local/bin/ COPY --from=containers-common-dev /out/seccomp.json /usr/share/containers/ COPY --from=stargz-store-dev /out/* /usr/local/bin/ # Image for testing rootless Podman with Stargz Store. # This takes the same approach as nerdctl CI: https://github.com/containerd/nerdctl/blob/6341c8320984f7148b92dd33472d8eaca6dba756/Dockerfile#L302-L326 FROM podman-base AS podman-rootless ARG CONTAINERIZED_SYSTEMD_VERSION ARG SLIRP4NETNS_VERSION RUN apt-get update -y && apt-get install -y \ systemd systemd-sysv dbus dbus-user-session \ openssh-server openssh-client uidmap RUN curl -o /usr/local/bin/slirp4netns --fail -L https://github.com/rootless-containers/slirp4netns/releases/download/${SLIRP4NETNS_VERSION}/slirp4netns-$(uname -m) && \ chmod +x /usr/local/bin/slirp4netns && \ curl -L -o /docker-entrypoint.sh https://raw.githubusercontent.com/AkihiroSuda/containerized-systemd/${CONTAINERIZED_SYSTEMD_VERSION}/docker-entrypoint.sh && \ chmod +x /docker-entrypoint.sh && \ curl -L -o /etc/containers/policy.json https://raw.githubusercontent.com/containers/skopeo/master/default-policy.json # storage.conf plugs Stargz Store into Podman as an Additional Layer Store COPY ./script/podman/config/storage.conf /home/rootless/.config/containers/storage.conf # Stargz Store systemd service for rootless Podman COPY ./script/podman/config/podman-rootless-stargz-store.service /home/rootless/.config/systemd/user/ # test-podman-rootless.sh logins to the user via SSH COPY ./script/podman/config/test-podman-rootless.sh /test-podman-rootless.sh RUN ssh-keygen -q -t rsa -f /root/.ssh/id_rsa -N '' && \ useradd -m -s /bin/bash rootless && \ mkdir -p -m 0700 /home/rootless/.ssh && \ cp -a /root/.ssh/id_rsa.pub /home/rootless/.ssh/authorized_keys && \ mkdir -p /home/rootless/.local/share /home/rootless/.local/share/stargz-store/store && \ chown -R rootless:rootless /home/rootless VOLUME /home/rootless/.local/share ENTRYPOINT ["/docker-entrypoint.sh", "/test-podman-rootless.sh"] CMD ["/bin/bash", "--login", "-i"] # Image which can be used for interactive demo environment FROM containerd-base AS demo ARG CNI_PLUGINS_VERSION ARG TARGETARCH RUN apt-get update && apt-get install -y iptables && \ # Make CNI plugins manipulate iptables instead of nftables # as this test runs in a Docker container that network is configured with iptables. # c.f. https://github.com/moby/moby/issues/26824 update-alternatives --set iptables /usr/sbin/iptables-legacy && \ mkdir -p /opt/cni/bin && \ curl -Ls https://github.com/containernetworking/plugins/releases/download/${CNI_PLUGINS_VERSION}/cni-plugins-linux-${TARGETARCH:-amd64}-${CNI_PLUGINS_VERSION}.tgz | tar xzv -C /opt/cni/bin # Image which can be used as a node image for KinD (containerd with builtin snapshotter) FROM kindest/node:v1.26.0 AS kind-builtin-snapshotter COPY --from=containerd-snapshotter-dev /out/bin/containerd /out/bin/containerd-shim-runc-v2 /usr/local/bin/ COPY --from=snapshotter-dev /out/ctr-remote /usr/local/bin/ COPY ./script/config/ / RUN apt-get update -y && apt-get install --no-install-recommends -y fuse3 ENTRYPOINT [ "/usr/local/bin/kind-entrypoint.sh", "/usr/local/bin/entrypoint", "/sbin/init" ] # Image for testing CRI-O with Stargz Store. # NOTE: This cannot be used for the node image of KinD. FROM ubuntu:23.04 AS crio-stargz-store ARG CNI_PLUGINS_VERSION ARG CRIO_TEST_PAUSE_IMAGE_NAME ENV container docker RUN apt-get update -y && apt-get install --no-install-recommends -y \ ca-certificates fuse3 libgpgme-dev libglib2.0-dev curl \ iptables conntrack systemd systemd-sysv && \ DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y tzdata && \ # Make CNI plugins manipulate iptables instead of nftables # as this test runs in a Docker container that network is configured with iptables. # c.f. https://github.com/moby/moby/issues/26824 update-alternatives --set iptables /usr/sbin/iptables-legacy && \ mkdir -p /opt/cni/bin && \ curl -sSL https://github.com/containernetworking/plugins/releases/download/${CNI_PLUGINS_VERSION}/cni-plugins-linux-${TARGETARCH:-amd64}-${CNI_PLUGINS_VERSION}.tgz | tar xzv -C /opt/cni/bin && \ echo ${CRIO_TEST_PAUSE_IMAGE_NAME} > /pause_name && \ mkdir -p /etc/sysconfig && \ echo CRIO_RUNTIME_OPTIONS=--pause-image=${CRIO_TEST_PAUSE_IMAGE_NAME} > /etc/sysconfig/crio && \ # Necessary to pass CRI tests: https://github.com/kubernetes-sigs/cri-tools/pull/905 mkdir -p /etc/crio/crio.conf.d && \ printf '[crio.runtime]\nseccomp_use_default_when_empty = false\n' > /etc/crio/crio.conf.d/02-seccomp.conf COPY --from=stargz-store-dev /out/* /usr/local/bin/ COPY --from=cri-o-dev /out/bin/* /usr/local/bin/ COPY --from=cri-o-dev /out/crio.service /etc/systemd/system/ COPY --from=runc-dev /out/sbin/* /usr/local/sbin/ COPY --from=conmon-dev /out/bin/* /usr/local/bin/ COPY --from=containers-common-dev /out/seccomp.json /usr/share/containers/ COPY ./script/config-cri-o/ / ENTRYPOINT [ "/usr/local/bin/entrypoint" ] # Image which can be used as a node image for KinD FROM kindest/node:v1.26.0 COPY --from=containerd-dev /out/bin/containerd /out/bin/containerd-shim-runc-v2 /usr/local/bin/ COPY --from=snapshotter-dev /out/* /usr/local/bin/ COPY ./script/config/ / RUN apt-get update -y && apt-get install --no-install-recommends -y fuse3 && \ systemctl enable stargz-snapshotter ENTRYPOINT [ "/usr/local/bin/kind-entrypoint.sh", "/usr/local/bin/entrypoint", "/sbin/init" ] stargz-snapshotter-0.14.3/LICENSE000066400000000000000000000261361440204344700165000ustar00rootroot00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. stargz-snapshotter-0.14.3/MAINTAINERS000066400000000000000000000005641440204344700171650ustar00rootroot00000000000000# stargz-snapshotter maintainers # # As a containerd sub-project, containerd maintainers are also included from https://github.com/containerd/project/blob/main/MAINTAINERS. # See https://github.com/containerd/project/blob/main/GOVERNANCE.md for description of maintainer role # # COMMITTERS # GitHub ID, Name, Email address ktock, Kohei Tokunaga, ktokunaga.mail@gmail.com stargz-snapshotter-0.14.3/Makefile000066400000000000000000000073051440204344700171300ustar00rootroot00000000000000# Copyright The containerd Authors. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Base path used to install. CMD_DESTDIR ?= /usr/local GO111MODULE_VALUE=auto PREFIX ?= $(CURDIR)/out/ PKG=github.com/containerd/stargz-snapshotter VERSION=$(shell git describe --match 'v[0-9]*' --dirty='.m' --always --tags) REVISION=$(shell git rev-parse HEAD)$(shell if ! git diff --no-ext-diff --quiet --exit-code; then echo .m; fi) GO_BUILD_LDFLAGS ?= -s -w GO_LD_FLAGS=-ldflags '$(GO_BUILD_LDFLAGS) -X $(PKG)/version.Version=$(VERSION) -X $(PKG)/version.Revision=$(REVISION) $(GO_EXTRA_LDFLAGS)' CMD=containerd-stargz-grpc ctr-remote stargz-store CMD_BINARIES=$(addprefix $(PREFIX),$(CMD)) .PHONY: all build check install uninstall clean test test-root test-all integration test-optimize benchmark test-kind test-cri-containerd test-cri-o test-criauth generate validate-generated test-k3s test-k3s-argo-workflow vendor all: build build: $(CMD) FORCE: containerd-stargz-grpc: FORCE cd cmd/ ; GO111MODULE=$(GO111MODULE_VALUE) go build -o $(PREFIX)$@ $(GO_BUILD_FLAGS) $(GO_LD_FLAGS) -v ./containerd-stargz-grpc ctr-remote: FORCE cd cmd/ ; GO111MODULE=$(GO111MODULE_VALUE) go build -o $(PREFIX)$@ $(GO_BUILD_FLAGS) $(GO_LD_FLAGS) -v ./ctr-remote stargz-store: FORCE cd cmd/ ; GO111MODULE=$(GO111MODULE_VALUE) go build -o $(PREFIX)$@ $(GO_BUILD_FLAGS) $(GO_LD_FLAGS) -v ./stargz-store check: @echo "$@" @GO111MODULE=$(GO111MODULE_VALUE) $(shell go env GOPATH)/bin/golangci-lint run @cd ./estargz ; GO111MODULE=$(GO111MODULE_VALUE) $(shell go env GOPATH)/bin/golangci-lint run @cd ./cmd ; GO111MODULE=$(GO111MODULE_VALUE) $(shell go env GOPATH)/bin/golangci-lint run @cd ./ipfs ; GO111MODULE=$(GO111MODULE_VALUE) $(shell go env GOPATH)/bin/golangci-lint run install: @echo "$@" @mkdir -p $(CMD_DESTDIR)/bin @install $(CMD_BINARIES) $(CMD_DESTDIR)/bin uninstall: @echo "$@" @rm -f $(addprefix $(CMD_DESTDIR)/bin/,$(notdir $(CMD_BINARIES))) clean: @echo "$@" @rm -f $(CMD_BINARIES) generate: @./script/generated-files/generate.sh update validate-generated: @./script/generated-files/generate.sh validate vendor: @cd ./estargz ; GO111MODULE=$(GO111MODULE_VALUE) go mod tidy @cd ./ipfs ; GO111MODULE=$(GO111MODULE_VALUE) go mod tidy @GO111MODULE=$(GO111MODULE_VALUE) go mod tidy @cd ./cmd ; GO111MODULE=$(GO111MODULE_VALUE) go mod tidy test: @echo "$@" @GO111MODULE=$(GO111MODULE_VALUE) go test -race ./... @cd ./estargz ; GO111MODULE=$(GO111MODULE_VALUE) go test -timeout 30m -race ./... @cd ./cmd ; GO111MODULE=$(GO111MODULE_VALUE) go test -timeout 20m -race ./... @cd ./ipfs ; GO111MODULE=$(GO111MODULE_VALUE) go test -timeout 20m -race ./... test-root: @echo "$@" @GO111MODULE=$(GO111MODULE_VALUE) go test -race ./snapshot -test.root test-all: test-root test integration: @./script/integration/test.sh test-optimize: @./script/optimize/test.sh benchmark: @./script/benchmark/test.sh test-kind: @./script/kind/test.sh test-cri-containerd: @./script/cri-containerd/test.sh test-cri-o: @./script/cri-o/test.sh test-podman: @./script/podman/test.sh test-criauth: @./script/criauth/test.sh test-k3s: @./script/k3s/test.sh test-k3s-argo-workflow: @./script/k3s-argo-workflow/run.sh test-ipfs: @./script/ipfs/test.sh stargz-snapshotter-0.14.3/NOTICE.md000066400000000000000000000072661440204344700170010ustar00rootroot00000000000000The source code developed under the Stargz Snapshotter Project is licensed under Apache License 2.0. However, the Stargz Snapshotter project contains modified subcomponents from Container Registry Filesystem Project with separate copyright notices and license terms. Your use of the source code for the subcomponent is subject to the terms and conditions as defined by the source project. Files in these subcomponents contain following file header. ``` Copyright 2019 The Go Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the NOTICE.md file. ``` These source code is governed by a 3-Clause BSD license. The copyright notice, list of conditions and disclaimer are the following. ``` Copyright (c) 2019 Google LLC. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ``` The Stargz Snapshotter project also contains modified benchmarking code from HelloBench Project with separate copyright notices and license terms. Your use of the source code for the benchmarking code is subject to the terms and conditions as defined by the source project. These source code is governed by a MIT license. The copyright notice, condition and disclaimer are the following. The file in the benchmarking code contains it as the file header. ``` The MIT License (MIT) Copyright (c) 2015 Tintri Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ``` stargz-snapshotter-0.14.3/README.md000066400000000000000000000364621440204344700167550ustar00rootroot00000000000000[[â¬‡ï¸ **Download**]](https://github.com/containerd/stargz-snapshotter/releases) [[📔**Browse images**]](./docs/pre-converted-images.md) [[☸**Quick Start (Kubernetes)**]](#quick-start-with-kubernetes) [[🤓**Quick Start (nerdctl)**]](https://github.com/containerd/nerdctl/blob/master/docs/stargz.md) [[🔆**Install**]](./docs/INSTALL.md) # Stargz Snapshotter [![Tests Status](https://github.com/containerd/stargz-snapshotter/workflows/Tests/badge.svg)](https://github.com/containerd/stargz-snapshotter/actions?query=workflow%3ATests+branch%3Amain) [![Benchmarking](https://github.com/containerd/stargz-snapshotter/workflows/Benchmark/badge.svg)](https://github.com/containerd/stargz-snapshotter/actions?query=workflow%3ABenchmark+branch%3Amain) [![Nightly](https://github.com/containerd/stargz-snapshotter/workflows/Nightly/badge.svg)](https://github.com/containerd/stargz-snapshotter/actions?query=workflow%3ANightly+branch%3Amain) Read also introductory blog: [Startup Containers in Lightning Speed with Lazy Image Distribution on Containerd](https://medium.com/nttlabs/startup-containers-in-lightning-speed-with-lazy-image-distribution-on-containerd-243d94522361) Pulling image is one of the time-consuming steps in the container lifecycle. Research shows that time to take for pull operation accounts for 76% of container startup time[[FAST '16]](https://www.usenix.org/node/194431). *Stargz Snapshotter* is an implementation of snapshotter which aims to solve this problem by *lazy pulling*. *Lazy pulling* here means a container can run without waiting for the pull completion of the image and necessary chunks of the image are fetched *on-demand*. [*eStargz*](/docs/stargz-estargz.md) is a lazily-pullable image format proposed by this project. This is compatible to [OCI](https://github.com/opencontainers/image-spec/)/[Docker](https://github.com/moby/moby/blob/master/image/spec/v1.2.md) images so this can be pushed to standard container registries (e.g. ghcr.io) as well as this is *still runnable* even on eStargz-agnostic runtimes including Docker. eStargz format is based on [stargz image format by CRFS](https://github.com/google/crfs) but comes with additional features like runtime optimization and content verification. The following histogram is the benchmarking result for startup time of several containers measured on Github Actions, using GitHub Container Registry. The benchmarking result on ecdb227 `legacy` shows the startup performance when we use containerd's default snapshotter (`overlayfs`) with images copied from `docker.io/library` without optimization. For this configuration, containerd pulls entire image contents and `pull` operation takes accordingly. When we use stargz snapshotter with eStargz-converted images but without any optimization (`estargz-noopt`) we are seeing performance improvement on the `pull` operation because containerd can start the container without waiting for the `pull` completion and fetch necessary chunks of the image on-demand. But at the same time, we see the performance drawback for `run` operation because each access to files takes extra time for fetching them from the registry. When we use [eStargz with optimization](/docs/ctr-remote.md) (`estargz`), we can mitigate the performance drawback observed in `estargz-noopt` images. This is because [stargz snapshotter prefetches and caches *likely accessed files* during running the container](/docs/stargz-estargz.md). On the first container creation, stargz snapshotter waits for the prefetch completion so `create` sometimes takes longer than other types of image. But it's still shorter than waiting for downloading all files of all layers. The above histogram is [the benchmarking result on the commit `ecdb227`](https://github.com/containerd/stargz-snapshotter/actions/runs/398606060). We are constantly measuring the performance of this snapshotter so you can get the latest one through the badge shown top of this doc. Please note that we sometimes see dispersion among the results because of the NW condition on the internet and the location of the instance in the Github Actions, etc. Our benchmarking method is based on [HelloBench](https://github.com/Tintri/hello-bench). :nerd_face: You can also run containers on IPFS with lazy pulling. This is an experimental feature. See [`./docs/ipfs.md`](./docs/ipfs.md) for more details. Stargz Snapshotter is a **non-core** sub-project of containerd. ## Quick Start with Kubernetes - For more details about stargz snapshotter plugin and its configuration, refer to [Containerd Stargz Snapshotter Plugin Overview](/docs/overview.md). - For more details about setup lazy pulling of eStargz with containerd, CRI-O, Podman, systemd, etc., refer to [Install Stargz Snapshotter and Stargz Store](./docs/INSTALL.md). - For more details about integration status of eStargz with tools in commuinty, refer to [Integration of eStargz with other tools](./docs/integration.md) For using stargz snapshotter on kubernetes nodes, you need the following configuration to containerd as well as run stargz snapshotter daemon on the node. We assume that you are using containerd (> v1.4.2) as a CRI runtime. ```toml version = 2 # Plug stargz snapshotter into containerd # Containerd recognizes stargz snapshotter through specified socket address. # The specified address below is the default which stargz snapshotter listen to. [proxy_plugins] [proxy_plugins.stargz] type = "snapshot" address = "/run/containerd-stargz-grpc/containerd-stargz-grpc.sock" # Use stargz snapshotter through CRI [plugins."io.containerd.grpc.v1.cri".containerd] snapshotter = "stargz" disable_snapshot_annotations = false ``` **Note that `disable_snapshot_annotations = false` is required since containerd > v1.4.2** You can try our [prebuilt](/Dockerfile) [KinD](https://github.com/kubernetes-sigs/kind) node image that contains the above configuration. ```console $ kind create cluster --name stargz-demo --image ghcr.io/containerd/stargz-snapshotter:0.12.1-kind ``` :information_source: kind binary v0.16.x or newer is recommended for `ghcr.io/containerd/stargz-snapshotter:0.12.1-kind`. :information_source: You can get latest node images from [`ghcr.io/containerd/stargz-snapshotter:${VERSION}-kind`](https://github.com/orgs/containerd/packages/container/package/stargz-snapshotter) namespace. Then you can create eStargz pods on the cluster. In this example, we create a stargz-converted Node.js pod (`ghcr.io/stargz-containers/node:17.8.0-esgz`) as a demo. ```yaml apiVersion: v1 kind: Pod metadata: name: nodejs spec: containers: - name: nodejs-stargz image: ghcr.io/stargz-containers/node:17.8.0-esgz command: ["node"] args: - -e - var http = require('http'); http.createServer(function(req, res) { res.writeHead(200); res.end('Hello World!\n'); }).listen(80); ports: - containerPort: 80 ``` The following command lazily pulls `ghcr.io/stargz-containers/node:17.8.0-esgz` from Github Container Registry and creates the pod so the time to take for it is shorter than the original image `library/node:13.13`. ```console $ kubectl --context kind-stargz-demo apply -f stargz-pod.yaml && kubectl --context kind-stargz-demo get po nodejs -w $ kubectl --context kind-stargz-demo port-forward nodejs 8080:80 & $ curl 127.0.0.1:8080 Hello World! ``` Stargz snapshotter also supports [further configuration](/docs/overview.md) including private registry authentication, mirror registries, etc. ## Getting eStargz images - For more examples and details about the image converter `ctr-remote`, refer to [Optimize Images with `ctr-remote image optimize`](/docs/ctr-remote.md). - For more details about eStargz format, refer to [eStargz: Standard-Compatible Extensions to Tar.gz Layers for Lazy Pulling Container Images](/docs/stargz-estargz.md) For lazy pulling images, you need to prepare eStargz images first. There are several ways to achieve that. This section describes some of them. ### Trying pre-built eStargz images You can try our pre-converted eStargz images on ghcr.io listed in [Trying pre-converted images](/docs/pre-converted-images.md). ### Building eStargz images using BuildKit BuildKit supports building eStargz image since v0.10. You can try it using [Docker Buildx](https://docs.docker.com/buildx/working-with-buildx/). The following command builds an eStargz image and push it to `ghcr.io/ktock/hello:esgz`. Flags `oci-mediatypes=true,compression=estargz` enable to build eStargz. ``` $ docker buildx build -t ghcr.io/ktock/hello:esgz \ -o type=registry,oci-mediatypes=true,compression=estargz,force-compression=true \ /tmp/buildctx/ ``` > NOTE1: `force-compression=true` isn't needed if the base image is already eStargz. > NOTE2: Docker still does not support lazy pulling of eStargz. eStargz-enaled BuildKit (v0.10) will be [included to Docker v22.XX](https://github.com/moby/moby/blob/v22.06.0-beta.0/vendor.mod#L51) however you can build eStargz images with the prior version using Buildx [driver](https://github.com/docker/buildx/blob/master/docs/reference/buildx_create.md#-set-the-builder-driver-to-use---driver) feature. You can enable the specific version of BuildKit using [`docker buildx create`](https://docs.docker.com/engine/reference/commandline/buildx_create/) (this example specifies `v0.10.3`). ``` $ docker buildx create --use --name v0.10.3 --driver docker-container --driver-opt image=moby/buildkit:v0.10.3 $ docker buildx inspect --bootstrap v0.10.3 ``` ### Building eStargz images using Kaniko [Kaniko](https://github.com/GoogleContainerTools/kaniko) is an image builder runnable in containers and Kubernetes. Since v1.5.0, it experimentally supports building eStargz. `GGCR_EXPERIMENT_ESTARGZ=1` is needed. ```console $ docker run --rm -e GGCR_EXPERIMENT_ESTARGZ=1 \ -v /tmp/buildctx:/workspace -v ~/.docker/config.json:/kaniko/.docker/config.json:ro \ gcr.io/kaniko-project/executor:v1.8.1 --destination ghcr.io/ktock/hello:esgz ``` ### Building eStargz images using nerdctl [nerdctl](https://github.com/containerd/nerdctl), Docker-compatible CLI of containerd, supports building eStargz images. ```console $ nerdctl build -t ghcr.io/ktock/hello:1 /tmp/buildctx $ nerdctl image convert --estargz --oci ghcr.io/ktock/hello:1 ghcr.io/ktock/hello:esgz $ nerdctl push ghcr.io/ktock/hello:esgz ``` > NOTE: `--estargz` should be specified in conjunction with `--oci` Please refer to nerdctl document for details for further information (e.g. lazy pulling): https://github.com/containerd/nerdctl/blob/master/docs/stargz.md ### Creating eStargz images using `ctr-remote` [`ctr-remote`](/docs/ctr-remote.md) allows converting an image into eStargz with optimizing it. As shown in the above benchmarking result, on-demand lazy pulling improves the performance of pull but causes runtime performance penalty because reading files induce remotely downloading contents. For solving this, `ctr-remote` has *workload-based* optimization for images. For trying the examples described in this section, you can also use the docker-compose-based demo environment. You can setup this environment as the following commands (put this repo on `${GOPATH}/src/github.com/containerd/stargz-snapshotter`). *Note that this runs privileged containers on your host.* ```console $ cd ${GOPATH}/src/github.com/containerd/stargz-snapshotter/script/demo $ docker-compose build containerd_demo $ docker-compose up -d $ docker exec -it containerd_demo /bin/bash (inside container) # ./script/demo/run.sh ``` Generally, container images are built with purpose and the *workloads* are defined in the Dockerfile with some parameters (e.g. entrypoint, envvars and user). By default, `ctr-remote` optimizes the performance of reading files that are most likely accessed in the workload defined in the Dockerfile. [You can also specify the custom workload using options if needed](/docs/ctr-remote.md). The following example converts the legacy `library/ubuntu:20.04` image into eStargz. The command also optimizes the image for the workload of executing `ls` on `/bin/bash`. The thing actually done is it runs the specified workload in a temporary container and profiles all file accesses with marking them as *likely accessed* also during runtime. The converted image is still **docker-compatible** so you can run it with eStargz-agnostic runtimes (e.g. Docker). ```console # ctr-remote image pull docker.io/library/ubuntu:20.04 # ctr-remote image optimize --oci --entrypoint='[ "/bin/bash", "-c" ]' --args='[ "ls" ]' docker.io/library/ubuntu:20.04 registry2:5000/ubuntu:20.04 # ctr-remote image push --plain-http registry2:5000/ubuntu:20.04 ``` Finally, the following commands clear the local cache then pull the eStargz image lazily. Stargz snapshotter prefetches files that are most likely accessed in the optimized workload, which hopefully increases the cache hit rate for that workload and mitigates runtime overheads as shown in the benchmarking result shown top of this doc. ```console # ctr-remote image rm --sync registry2:5000/ubuntu:20.04 # ctr-remote images rpull --plain-http registry2:5000/ubuntu:20.04 fetching sha256:610399d1... application/vnd.oci.image.index.v1+json fetching sha256:0b4a26b4... application/vnd.oci.image.manifest.v1+json fetching sha256:8d8d9dbe... application/vnd.oci.image.config.v1+json # ctr-remote run --rm -t --snapshotter=stargz registry2:5000/ubuntu:20.04 test /bin/bash root@8eabb871a9bd:/# ls bin boot dev etc home lib lib32 lib64 libx32 media mnt opt proc root run sbin srv sys tmp usr var ``` > NOTE: You can perform lazy pulling from any OCI-compatible registries (e.g. docker.io, ghcr.io, etc) as long as the image is formatted as eStargz. ### Registry-side conversion with `estargz.kontain.me` You can convert arbitrary images into eStargz on the registry-side, using [`estargz.kontain.me`](https://estargz.kontain.me). `estargz.kontain.me/[image]` serves eStargz-converted version of an arbitrary public image. For example, the following Kubernetes manifest performs lazy pulling of eStargz-formatted version of `docker.io/library/nginx:1.21.1` that is converted by `estargz.kontain.me`. ```yaml apiVersion: v1 kind: Pod metadata: name: nginx spec: containers: - name: nginx image: estargz.kontain.me/docker.io/library/nginx:1.21.1 ports: - containerPort: 80 ``` > WARNING: Before trying this method, read [caveats from kontain.me](https://github.com/imjasonh/kontain.me#caveats). If you rely on it in production, you should copy the image to your own registry or build eStargz by your own using `ctr-remote` as described in the following. ## Importing Stargz Snapshotter as go module Currently, Stargz Snapshotter repository contains two Go modules as the following and both of them need to be imported. - `github.com/containerd/stargz-snapshotter` - `github.com/containerd/stargz-snapshotter/estargz` Please make sure you import the both of them and they point to *the same commit version*. ## Project details Stargz Snapshotter is a containerd **non-core** sub-project, licensed under the [Apache 2.0 license](./LICENSE). As a containerd non-core sub-project, you will find the: * [Project governance](https://github.com/containerd/project/blob/main/GOVERNANCE.md), * [Maintainers](./MAINTAINERS), * and [Contributing guidelines](https://github.com/containerd/project/blob/main/CONTRIBUTING.md) information in our [`containerd/project`](https://github.com/containerd/project) repository. stargz-snapshotter-0.14.3/analyzer/000077500000000000000000000000001440204344700173105ustar00rootroot00000000000000stargz-snapshotter-0.14.3/analyzer/analyzer.go000066400000000000000000000311351440204344700214670ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package analyzer import ( "bufio" "context" "fmt" "io" "os" "os/signal" "strings" "sync" "sync/atomic" "syscall" "time" "github.com/containerd/console" "github.com/containerd/containerd" "github.com/containerd/containerd/cio" "github.com/containerd/containerd/cmd/ctr/commands" "github.com/containerd/containerd/cmd/ctr/commands/tasks" "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/log" "github.com/containerd/containerd/mount" "github.com/containerd/containerd/oci" "github.com/containerd/containerd/platforms" "github.com/containerd/containerd/snapshots" "github.com/containerd/stargz-snapshotter/analyzer/fanotify" "github.com/containerd/stargz-snapshotter/analyzer/recorder" "github.com/opencontainers/go-digest" "github.com/opencontainers/image-spec/identity" runtimespec "github.com/opencontainers/runtime-spec/specs-go" "github.com/rs/xid" ) var defaultPeriod = 10 * time.Second // Analyze analyzes the passed image then store the record of prioritized files into // containerd's content store. This function returns the digest of that record file. // This digest can be used to read record from the content store. func Analyze(ctx context.Context, client *containerd.Client, ref string, opts ...Option) (digest.Digest, error) { var aOpts analyzerOpts for _, o := range opts { o(&aOpts) } if aOpts.terminal && aOpts.waitOnSignal { return "", fmt.Errorf("wait-on-signal option cannot be used with terminal option") } target, err := os.MkdirTemp("", "target") if err != nil { return "", err } defer os.RemoveAll(target) cs := client.ContentStore() is := client.ImageService() ss := client.SnapshotService(aOpts.snapshotter) img, err := is.Get(ctx, ref) if err != nil { return "", err } platformImg := containerd.NewImageWithPlatform(client, img, platforms.Default()) // Mount the target image // NOTE: We cannot let containerd prepare the rootfs. We create mount namespace *before* // creating the container so containerd's bundle preparation (mounting snapshots to // the bundle directory, etc.) is invisible inside the pre-unshared mount namespace. // This leads to runc using empty directory as the rootfs. if unpacked, err := platformImg.IsUnpacked(ctx, aOpts.snapshotter); err != nil { return "", err } else if !unpacked { if err := platformImg.Unpack(ctx, aOpts.snapshotter); err != nil { return "", err } } cleanup, err := mountImage(ctx, ss, platformImg, target) if err != nil { return "", err } defer cleanup() // Spawn a fanotifier process in a new mount namespace and setup recorder. fanotifier, err := fanotify.SpawnFanotifier("/proc/self/exe") if err != nil { return "", fmt.Errorf("failed to spawn fanotifier: %w", err) } defer func() { if err := fanotifier.Close(); err != nil { log.G(ctx).WithError(err).Warnf("failed to close fanotifier") } }() // Prepare the spec based on the specified image and runtime options. var sOpts []oci.SpecOpts if aOpts.specOpts != nil { gotOpts, done, err := aOpts.specOpts(platformImg, target) if err != nil { return "", err } defer func() { if err := done(); err != nil { log.G(ctx).WithError(err).Warnf("failed to cleanup container") return } }() sOpts = append(sOpts, gotOpts...) } else { sOpts = append(sOpts, oci.WithDefaultSpec(), oci.WithDefaultUnixDevices, oci.WithRootFSPath(target), oci.WithImageConfig(platformImg), ) } sOpts = append(sOpts, oci.WithLinuxNamespace(runtimespec.LinuxNamespace{ Type: runtimespec.MountNamespace, Path: fanotifier.MountNamespacePath(), // use mount namespace that the fanotifier created })) // Create the container and the task var container containerd.Container for i := 0; i < 3; i++ { id := xid.New().String() var s runtimespec.Spec container, err = client.NewContainer(ctx, id, containerd.WithImage(platformImg), containerd.WithSnapshotter(aOpts.snapshotter), containerd.WithImageStopSignal(platformImg, "SIGKILL"), // WithImageConfig depends on WithImage and WithSnapshotter for resolving // username (accesses to /etc/{passwd,group} files on the rootfs) containerd.WithSpec(&s, sOpts...), ) if err != nil { if errdefs.IsAlreadyExists(err) { log.G(ctx).WithError(err).Warnf("failed to create container") continue } return "", err } break } if container == nil { return "", fmt.Errorf("failed to create container") } defer container.Delete(ctx, containerd.WithSnapshotCleanup) var ioCreator cio.Creator var con console.Console waitLine := newLineWaiter(aOpts.waitLineOut) stdinC := newLazyReadCloser(os.Stdin) if aOpts.terminal { if !aOpts.stdin { return "", fmt.Errorf("terminal cannot be used if stdin isn't enabled") } con = console.Current() defer con.Reset() if err := con.SetRaw(); err != nil { return "", err } // On terminal mode, the "stderr" field is unused. ioCreator = cio.NewCreator(cio.WithStreams(con, waitLine.registerWriter(con), nil), cio.WithTerminal) } else if aOpts.stdin { ioCreator = cio.NewCreator(cio.WithStreams(stdinC, waitLine.registerWriter(os.Stdout), os.Stderr)) } else { ioCreator = cio.NewCreator(cio.WithStreams(nil, waitLine.registerWriter(os.Stdout), os.Stderr)) } task, err := container.NewTask(ctx, ioCreator) if err != nil { return "", err } stdinC.registerCloser(func() { // Ensure to close IO when stdin get EOF task.CloseIO(ctx, containerd.WithStdinCloser) }) // Start to monitor "/" and run the task. rc, err := recorder.NewImageRecorder(ctx, cs, img, platforms.Default()) if err != nil { return "", err } defer rc.Close() if err := fanotifier.Start(); err != nil { return "", fmt.Errorf("failed to start fanotifier: %w", err) } var fanotifierClosed bool var fanotifierClosedMu sync.Mutex go func() { var successCount int defer func() { log.G(ctx).Debugf("success record %d path", successCount) }() for { path, err := fanotifier.GetPath() if err != nil { if err == io.EOF { fanotifierClosedMu.Lock() isFanotifierClosed := fanotifierClosed fanotifierClosedMu.Unlock() if isFanotifierClosed { break } } log.G(ctx).WithError(err).Error("failed to get notified path") break } if err := rc.Record(path); err != nil { log.G(ctx).WithError(err).Debugf("failed to record %q", path) } successCount++ } }() if aOpts.terminal { if err := tasks.HandleConsoleResize(ctx, task, con); err != nil { log.G(ctx).WithError(err).Error("failed to resize console") } } else { sigc := commands.ForwardAllSignals(ctx, task) defer commands.StopCatch(sigc) } if err := task.Start(ctx); err != nil { return "", err } // Wait until the task exit var status containerd.ExitStatus var killOk bool if aOpts.waitOnSignal { // NOTE: not functional with `terminal` option log.G(ctx).Infof("press Ctrl+C to terminate the container") status, killOk, err = waitOnSignal(ctx, container, task) if err != nil { return "", err } } else { if aOpts.period <= 0 { aOpts.period = defaultPeriod } log.G(ctx).Infof("waiting for %v ...", aOpts.period) status, killOk, err = waitOnTimeout(ctx, container, task, aOpts.period, waitLine) if err != nil { return "", err } } if !killOk { log.G(ctx).Warnf("failed to exit task %v; manually kill it", task.ID()) } else { code, _, err := status.Result() if err != nil { return "", err } log.G(ctx).Infof("container exit with code %v", code) if _, err := task.Delete(ctx); err != nil { return "", err } } // ensure no record comes in fanotifierClosedMu.Lock() fanotifierClosed = true fanotifierClosedMu.Unlock() if err := fanotifier.Close(); err != nil { log.G(ctx).WithError(err).Warnf("failed to cleanup fanotifier") } // Finish recording return rc.Commit(ctx) } func mountImage(ctx context.Context, ss snapshots.Snapshotter, image containerd.Image, mountpoint string) (func(), error) { diffIDs, err := image.RootFS(ctx) if err != nil { return nil, err } mounts, err := ss.Prepare(ctx, mountpoint, identity.ChainID(diffIDs).String()) if err != nil { return nil, err } if err := mount.All(mounts, mountpoint); err != nil { if err := ss.Remove(ctx, mountpoint); err != nil && !errdefs.IsNotFound(err) { log.G(ctx).WithError(err).Warnf("failed to cleanup snapshot after mount error") } return nil, fmt.Errorf("failed to mount rootfs at %q: %w", mountpoint, err) } return func() { if err := mount.UnmountAll(mountpoint, 0); err != nil { log.G(ctx).WithError(err).Warnf("failed to unmount snapshot") } if err := ss.Remove(ctx, mountpoint); err != nil && !errdefs.IsNotFound(err) { log.G(ctx).WithError(err).Warnf("failed to cleanup snapshot") } }, nil } func waitOnSignal(ctx context.Context, container containerd.Container, task containerd.Task) (containerd.ExitStatus, bool, error) { statusC, err := task.Wait(ctx) if err != nil { return containerd.ExitStatus{}, false, err } sc := make(chan os.Signal, 1) signal.Notify(sc, syscall.SIGINT) defer signal.Stop(sc) select { case status := <-statusC: return status, true, nil case <-sc: log.G(ctx).Info("signal detected") status, err := killTask(ctx, container, task, statusC) if err != nil { log.G(ctx).WithError(err).Warnf("failed to kill container") return containerd.ExitStatus{}, false, nil } return status, true, nil } } func waitOnTimeout(ctx context.Context, container containerd.Container, task containerd.Task, period time.Duration, line *lineWaiter) (containerd.ExitStatus, bool, error) { statusC, err := task.Wait(ctx) if err != nil { return containerd.ExitStatus{}, false, err } select { case status := <-statusC: return status, true, nil case l := <-line.waitCh: log.G(ctx).Infof("Waiting line detected %q; killing task", l) case <-time.After(period): log.G(ctx).Warnf("killing task. the time period to monitor access log (%s) has timed out", period.String()) } status, err := killTask(ctx, container, task, statusC) if err != nil { log.G(ctx).WithError(err).Warnf("failed to kill container") return containerd.ExitStatus{}, false, nil } return status, true, nil } func killTask(ctx context.Context, container containerd.Container, task containerd.Task, statusC <-chan containerd.ExitStatus) (containerd.ExitStatus, error) { sig, err := containerd.GetStopSignal(ctx, container, syscall.SIGKILL) if err != nil { return containerd.ExitStatus{}, err } if err := task.Kill(ctx, sig, containerd.WithKillAll); err != nil && !errdefs.IsNotFound(err) { return containerd.ExitStatus{}, fmt.Errorf("forward SIGKILL: %w", err) } select { case status := <-statusC: return status, nil case <-time.After(5 * time.Second): return containerd.ExitStatus{}, fmt.Errorf("timeout") } } type lazyReadCloser struct { reader io.Reader closer func() closerMu sync.Mutex initCond *sync.Cond initialized int64 } func newLazyReadCloser(r io.Reader) *lazyReadCloser { rc := &lazyReadCloser{reader: r, initCond: sync.NewCond(&sync.Mutex{})} return rc } func (s *lazyReadCloser) registerCloser(closer func()) { s.closerMu.Lock() s.closer = closer s.closerMu.Unlock() atomic.AddInt64(&s.initialized, 1) s.initCond.Broadcast() } func (s *lazyReadCloser) Read(p []byte) (int, error) { if atomic.LoadInt64(&s.initialized) <= 0 { // wait until initialized s.initCond.L.Lock() if atomic.LoadInt64(&s.initialized) <= 0 { s.initCond.Wait() } s.initCond.L.Unlock() } n, err := s.reader.Read(p) if err == io.EOF { s.closerMu.Lock() s.closer() s.closerMu.Unlock() } return n, err } func newLineWaiter(s string) *lineWaiter { return &lineWaiter{ waitCh: make(chan string), waitLine: s, } } type lineWaiter struct { waitCh chan string waitLine string } func (lw *lineWaiter) registerWriter(w io.Writer) io.Writer { if lw.waitLine == "" { return w } pr, pw := io.Pipe() go func() { scanner := bufio.NewScanner(pr) for scanner.Scan() { if strings.Contains(scanner.Text(), lw.waitLine) { lw.waitCh <- lw.waitLine } } if _, err := io.Copy(io.Discard, pr); err != nil { pr.CloseWithError(err) return } }() return io.MultiWriter(w, pw) } stargz-snapshotter-0.14.3/analyzer/fanotify/000077500000000000000000000000001440204344700211275ustar00rootroot00000000000000stargz-snapshotter-0.14.3/analyzer/fanotify/conn/000077500000000000000000000000001440204344700220645ustar00rootroot00000000000000stargz-snapshotter-0.14.3/analyzer/fanotify/conn/conn.go000066400000000000000000000075661440204344700233660ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package conn import ( "bufio" "fmt" "io" "os" "strconv" "strings" "time" ) const ( mesStart = "start" mesStarted = "started" mesAck = "ack" mesFdPrefix = "fd:" ) // Client is the client to talk to the fanotifier. type Client struct { r io.Reader w io.Writer notification *bufio.Scanner servicePid int timeout time.Duration } // NewClient returns the client to talk to the fanotifier. func NewClient(r io.Reader, w io.Writer, servicePid int, timeout time.Duration) *Client { return &Client{r, w, bufio.NewScanner(r), servicePid, timeout} } // Start lets the notirier start to monitor the filesystem. func (nc *Client) Start() error { if err := writeMessage(nc.w, mesStart); err != nil { return err } if mes, err := scanWithTimeout(nc.notification, nc.timeout); err != nil { return err } else if mes != mesStarted { return fmt.Errorf("non-started message got from fanotifier service: %q", mes) } return nil } // GetPath returns notified path from the fanotifier. This blocks until new path is notified // from the service func (nc *Client) GetPath() (string, error) { if !nc.notification.Scan() { // NOTE: no timeout return "", io.EOF } mes := nc.notification.Text() if !strings.HasPrefix(mes, mesFdPrefix) { return "", fmt.Errorf("unexpected prefix for message %q", mes) } fd, err := strconv.ParseInt(mes[len(mesFdPrefix):], 10, 32) if err != nil { return "", fmt.Errorf("invalid fd %q: %w", mes, err) } path, err := os.Readlink(fmt.Sprintf("/proc/%d/fd/%d", nc.servicePid, fd)) if err != nil { return "", fmt.Errorf("failed to get link from fd %q: %w", mes, err) } return path, writeMessage(nc.w, mesAck) } // Service is the service end of the fanotifier. type Service struct { r io.Reader w io.Writer client *bufio.Scanner timeout time.Duration } // NewService is the service end of the fanotifier. func NewService(r io.Reader, w io.Writer, timeout time.Duration) *Service { return &Service{r, w, bufio.NewScanner(r), timeout} } // WaitStart waits "start" message from the client. func (ns *Service) WaitStart() error { if !ns.client.Scan() { // NOTE: no timeout return io.EOF } if mes := ns.client.Text(); mes != mesStart { return fmt.Errorf("non-start message got from fanotifier client: %q", mes) } return nil } // SendStarted tells client that the service has been started. func (ns *Service) SendStarted() error { return writeMessage(ns.w, mesStarted) } // SendFd send file descriptor to the client. func (ns *Service) SendFd(fd int) error { if err := writeMessage(ns.w, fmt.Sprintf("%s%d", mesFdPrefix, fd)); err != nil { return err } if mes, err := scanWithTimeout(ns.client, ns.timeout); err != nil { return err } else if mes != mesAck { return fmt.Errorf("non-ack message got from fanotifier client: %q", mes) } return nil } func scanWithTimeout(sc *bufio.Scanner, timeout time.Duration) (string, error) { notifyCh := make(chan string) errCh := make(chan error) go func() { if !sc.Scan() { errCh <- io.EOF } notifyCh <- sc.Text() }() select { case mes := <-notifyCh: return mes, nil case err := <-errCh: return "", err case <-time.After(timeout): return "", fmt.Errorf("timeout") } } func writeMessage(w io.Writer, mes string) error { _, err := io.WriteString(w, mes+"\n") return err } stargz-snapshotter-0.14.3/analyzer/fanotify/fanotify.go000066400000000000000000000047551440204344700233100ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package fanotify import ( "fmt" "os/exec" "sync" "syscall" "time" "github.com/containerd/stargz-snapshotter/analyzer/fanotify/conn" "github.com/hashicorp/go-multierror" ) // Fanotifier monitors "/" mountpoint of a new mount namespace and notifies all // accessed files. type Fanotifier struct { cmd *exec.Cmd conn *conn.Client closeOnce sync.Once closeFunc func() error } func SpawnFanotifier(fanotifierBin string) (*Fanotifier, error) { // Run fanotifier that monitor "/" in a new mount namespace cmd := exec.Command(fanotifierBin, "fanotify", "/") cmd.SysProcAttr = &syscall.SysProcAttr{ Cloneflags: syscall.CLONE_NEWNS, } notifyR, err := cmd.StdoutPipe() if err != nil { return nil, err } notifyW, err := cmd.StdinPipe() if err != nil { return nil, err } if err := cmd.Start(); err != nil { return nil, err } return &Fanotifier{ cmd: cmd, // Connect to the spawned fanotifier over stdio conn: conn.NewClient(notifyR, notifyW, cmd.Process.Pid, 5*time.Second), closeFunc: func() (allErr error) { if err := notifyR.Close(); err != nil { allErr = multierror.Append(allErr, err) } if err := notifyW.Close(); err != nil { allErr = multierror.Append(allErr, err) } return }, }, nil } // Start starts fanotifier in the new mount namespace func (n *Fanotifier) Start() error { return n.conn.Start() } // GetPath gets path notified by the fanotifier. func (n *Fanotifier) GetPath() (string, error) { return n.conn.GetPath() } // MountNamespacePath returns the path to the mount namespace where // the fanotifier is monitoring. func (n *Fanotifier) MountNamespacePath() string { return fmt.Sprintf("/proc/%d/ns/mnt", n.cmd.Process.Pid) } // Close kills fanotifier process and closes the connection. func (n *Fanotifier) Close() (err error) { n.closeOnce.Do(func() { if err = n.cmd.Process.Kill(); err != nil { return } err = n.closeFunc() }) return } stargz-snapshotter-0.14.3/analyzer/fanotify/service/000077500000000000000000000000001440204344700225675ustar00rootroot00000000000000stargz-snapshotter-0.14.3/analyzer/fanotify/service/service.go000066400000000000000000000054671440204344700245720ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package service import ( "bufio" "encoding/binary" "fmt" "io" "os" "time" "github.com/containerd/stargz-snapshotter/analyzer/fanotify/conn" "golang.org/x/sys/unix" ) // Serve starts fanotify at target directory and notifies all accessed files. // Passed io.Reader an io.Writer are used for communicating with the client. func Serve(target string, r io.Reader, w io.Writer) error { sConn := conn.NewService(r, w, 5*time.Second) fd, err := unix.FanotifyInit(unix.FAN_CLASS_NOTIF, unix.O_RDONLY) if err != nil { return fmt.Errorf("fanotify_init: %w", err) } // This blocks until the client tells us to start monitoring the target mountpoint. if err := sConn.WaitStart(); err != nil { return fmt.Errorf("waiting for start inst: %w", err) } // Start monitoring the target mountpoint. if err := unix.FanotifyMark(fd, unix.FAN_MARK_ADD|unix.FAN_MARK_MOUNT, unix.FAN_ACCESS|unix.FAN_OPEN, unix.AT_FDCWD, target, ); err != nil { return fmt.Errorf("fanotify_mark: %w", err) } // Notify "started" state to the client. if err := sConn.SendStarted(); err != nil { return fmt.Errorf("failed to send started message: %w", err) } nr := bufio.NewReader(os.NewFile(uintptr(fd), "")) for { event := &unix.FanotifyEventMetadata{} if err := binary.Read(nr, binary.LittleEndian, event); err != nil { if err == io.EOF { break } return fmt.Errorf("read fanotify fd: %w", err) } if event.Vers != unix.FANOTIFY_METADATA_VERSION { return fmt.Errorf("Fanotify version mismatch %d(got) != %d(want)", event.Vers, unix.FANOTIFY_METADATA_VERSION) } if event.Fd < 0 { // queue overflow // TODO: do we need something special? fmt.Fprintf(os.Stderr, "Warn: queue overflow") continue } // Notify file descriptor. // NOTE: There is no guarantee that we have /proc in this mount namespace // (the target container's rootfs is mounted on "/") so we send file // descriptor and let the client resolve the path of this file using /proc of // this process. if err := sConn.SendFd(int(event.Fd)); err != nil { return fmt.Errorf("failed to send fd %d to client: %w", fd, err) } if err := unix.Close(int(event.Fd)); err != nil { return fmt.Errorf("Close(fd): %w", err) } continue } return nil } stargz-snapshotter-0.14.3/analyzer/option.go000066400000000000000000000044631440204344700211560ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package analyzer import ( "time" "github.com/containerd/containerd" "github.com/containerd/containerd/oci" ) type analyzerOpts struct { period time.Duration waitOnSignal bool snapshotter string specOpts SpecOpts terminal bool stdin bool waitLineOut string } // Option is runtime configuration of analyzer container type Option func(opts *analyzerOpts) // SpecOpts returns runtime configuration based on the passed image and rootfs path. type SpecOpts func(image containerd.Image, rootfs string) (opts []oci.SpecOpts, done func() error, err error) // WithSpecOpts is the runtime configuration func WithSpecOpts(specOpts SpecOpts) Option { return func(opts *analyzerOpts) { opts.specOpts = specOpts } } // WithTerminal enable terminal for the container. This must be specified with WithStdin(). func WithTerminal() Option { return func(opts *analyzerOpts) { opts.terminal = true } } // WithStdin attaches stdin to the container func WithStdin() Option { return func(opts *analyzerOpts) { opts.stdin = true } } // WithPeriod is the period to run runtime func WithPeriod(period time.Duration) Option { return func(opts *analyzerOpts) { opts.period = period } } // WithWaitOnSignal disables timeout func WithWaitOnSignal() Option { return func(opts *analyzerOpts) { opts.waitOnSignal = true } } // WithSnapshotter is the snapshotter to use func WithSnapshotter(snapshotter string) Option { return func(opts *analyzerOpts) { opts.snapshotter = snapshotter } } // WithWaitLineOut specifies a substring of a stdout line to be waited. // When this line is detected, the container will be killed. func WithWaitLineOut(s string) Option { return func(opts *analyzerOpts) { opts.waitLineOut = s } } stargz-snapshotter-0.14.3/analyzer/recorder/000077500000000000000000000000001440204344700211155ustar00rootroot00000000000000stargz-snapshotter-0.14.3/analyzer/recorder/recorder.go000066400000000000000000000127601440204344700232570ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package recorder import ( "archive/tar" "context" "encoding/json" "fmt" "io" "path" "strings" "sync" "github.com/containerd/containerd/archive/compression" "github.com/containerd/containerd/content" "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/images" "github.com/containerd/containerd/images/converter/uncompress" "github.com/containerd/containerd/log" "github.com/containerd/containerd/platforms" "github.com/containerd/stargz-snapshotter/recorder" "github.com/containerd/stargz-snapshotter/util/containerdutil" "github.com/opencontainers/go-digest" ocispec "github.com/opencontainers/image-spec/specs-go/v1" "github.com/rs/xid" "golang.org/x/sync/errgroup" ) const ( whiteoutPrefix = ".wh." whiteoutOpaqueDir = whiteoutPrefix + whiteoutPrefix + ".opq" ) // ImageRecorder is a wrapper of recorder.Recroder. This holds the relationship // between files and layer index in the specified image. So the client can record // files without knowing about which layer this file belongs to. type ImageRecorder struct { r *recorder.Recorder index []map[string]struct{} manifestDigest digest.Digest recordW content.Writer recordWMu sync.Mutex } func NewImageRecorder(ctx context.Context, cs content.Store, img images.Image, platformMC platforms.MatchComparer) (*ImageRecorder, error) { manifestDesc, err := containerdutil.ManifestDesc(ctx, cs, img.Target, platformMC) if err != nil { return nil, err } p, err := content.ReadBlob(ctx, cs, manifestDesc) if err != nil { return nil, err } var manifest ocispec.Manifest if err := json.Unmarshal(p, &manifest); err != nil { return nil, err } return imageRecorderFromManifest(ctx, cs, manifestDesc, manifest) } func imageRecorderFromManifest(ctx context.Context, cs content.Store, manifestDesc ocispec.Descriptor, manifest ocispec.Manifest) (*ImageRecorder, error) { var eg errgroup.Group filesMap := make([]map[string]struct{}, len(manifest.Layers)) for i, desc := range manifest.Layers { i, desc := i, desc filesMap[i] = make(map[string]struct{}) // Create the index from the layer blob. // TODO: During optimization, we uncompress the blob several times (here and during // creating eStargz layer). We should unify this process for better optimization // performance. log.G(ctx).Infof("analyzing blob %q", desc.Digest) readerAt, err := cs.ReaderAt(ctx, desc) if err != nil { return nil, fmt.Errorf("failed to get reader blob %v: %w", desc.Digest, err) } defer readerAt.Close() r := io.Reader(io.NewSectionReader(readerAt, 0, desc.Size)) if !uncompress.IsUncompressedType(desc.MediaType) { r, err = compression.DecompressStream(r) if err != nil { return nil, fmt.Errorf("cannot decompress layer %v: %w", desc.Digest, err) } } eg.Go(func() error { tr := tar.NewReader(r) for { h, err := tr.Next() if err != nil { if err == io.EOF { break } return err } filesMap[i][cleanEntryName(h.Name)] = struct{}{} } return nil }) } if err := eg.Wait(); err != nil { return nil, err } recordW, err := content.OpenWriter(ctx, cs, content.WithRef(fmt.Sprintf("recorder-%v", xid.New().String()))) if err != nil { return nil, fmt.Errorf("failed to open writer for recorder: %w", err) } return &ImageRecorder{ r: recorder.New(recordW), index: filesMap, recordW: recordW, manifestDigest: manifestDesc.Digest, }, nil } func (r *ImageRecorder) Record(name string) error { if name == "" { return nil } r.recordWMu.Lock() defer r.recordWMu.Unlock() name = cleanEntryName(name) index := -1 for i := len(r.index) - 1; i >= 0; i-- { if _, ok := r.index[i][name]; ok { index = i break } // If this is deleted by a whiteout file or directory, return error. wh := cleanEntryName(path.Join(path.Dir("/"+name), whiteoutPrefix+path.Base("/"+name))) if _, ok := r.index[i][wh]; ok { return fmt.Errorf("%q is a deleted file", name) } whDir := cleanEntryName(path.Join(path.Dir("/"+name), whiteoutOpaqueDir)) if _, ok := r.index[i][whDir]; ok { return fmt.Errorf("Parent dir of %q is a deleted directory", name) } } if index < 0 { return fmt.Errorf("file %q not found in index", name) } return r.r.Record(&recorder.Entry{ Path: name, ManifestDigest: r.manifestDigest.String(), LayerIndex: &index, }) } func (r *ImageRecorder) Commit(ctx context.Context) (digest.Digest, error) { r.recordWMu.Lock() defer r.recordWMu.Unlock() if err := r.recordW.Commit(ctx, 0, ""); err != nil && !errdefs.IsAlreadyExists(err) { return "", err } return r.recordW.Digest(), nil } func (r *ImageRecorder) Close() error { r.recordWMu.Lock() defer r.recordWMu.Unlock() return r.recordW.Close() } func cleanEntryName(name string) string { // Use path.Clean to consistently deal with path separators across platforms. return strings.TrimPrefix(path.Clean("/"+name), "/") } stargz-snapshotter-0.14.3/analyzer/recorder/recorder_test.go000066400000000000000000000206051440204344700243130ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package recorder import ( "compress/gzip" "context" "encoding/json" "fmt" "io" "os" "path" "testing" "github.com/containerd/containerd/content" "github.com/containerd/containerd/content/local" "github.com/containerd/containerd/errdefs" "github.com/containerd/stargz-snapshotter/recorder" "github.com/containerd/stargz-snapshotter/util/testutil" ocispec "github.com/opencontainers/image-spec/specs-go/v1" "github.com/rs/xid" ) var allowedPrefix = [4]string{"", "./", "/", "../"} func TestNodeIndex(t *testing.T) { type recordEntry struct { name string index int } tests := []struct { name string in [][]testutil.TarEntry record []string want []recordEntry wantFail bool }{ { name: "single layer", in: [][]testutil.TarEntry{ { testutil.File("foo", "foo"), testutil.File("bar", "bar"), }, }, record: []string{"bar", "foo"}, want: []recordEntry{ {"bar", 0}, {"foo", 0}, }, }, { name: "overlay", in: [][]testutil.TarEntry{ { testutil.File("foo", "foo"), testutil.Dir("bar/"), testutil.Dir("bar/barbar/"), testutil.File("bar/barbar/bar2", "bar2"), testutil.File("bar/barbar/foo2", "foo2"), testutil.File("x", "x"), testutil.File("y", "y"), }, { testutil.File("foo", "foo2"), testutil.File("baz", "baz"), testutil.Dir("bar/"), testutil.Dir("bar/barbar/"), testutil.File("bar/barbar/foo2", "foo2-upper"), }, { testutil.File("foo", "foo3"), testutil.Dir("a/"), testutil.File("a/aaaaaa", "a"), testutil.File("y", "y"), }, }, record: []string{ "baz", "foo", "bar/barbar/foo2", "a/aaaaaa", "bar/barbar/bar2", "y"}, want: []recordEntry{ {"baz", 1}, {"foo", 2}, {"bar/barbar/foo2", 1}, {"a/aaaaaa", 2}, {"bar/barbar/bar2", 0}, {"y", 2}, }, }, { name: "various files", in: [][]testutil.TarEntry{ // All file path should be interpreted as the path relative to root. { testutil.File("foo", "foo"), testutil.Dir("bar/"), testutil.Symlink("bar/foosym", "foo"), testutil.Dir("bar/barbar/"), testutil.File("./bar/barbar/bar2", "bar2"), testutil.File("../bar/barbar/foo2", "foo2"), testutil.File("/x", "x"), testutil.Chardev("chardev", 1, 10), testutil.Fifo("bar/fifo1"), }, { testutil.File("./foo", "foo2"), testutil.File("baz", "baz"), testutil.Dir("bar/"), testutil.Dir("./bar/barbar/"), testutil.File("bar/barbar/bazlink", "baz"), testutil.File("../bar/barbar/foo2", "foo2-upper"), testutil.Chardev("chardev", 10, 100), testutil.Chardev("./blockdev", 100, 1), }, }, record: []string{ // All file path should be interpreted as the path relative to root. "./bar/foosym", "bar/barbar/bazlink", "/bar/barbar/foo2", "chardev", "../blockdev", "bar/fifo1", "./bar/barbar/bar2", }, want: []recordEntry{ {"bar/foosym", 0}, {"bar/barbar/bazlink", 1}, {"bar/barbar/foo2", 1}, {"chardev", 1}, {"blockdev", 1}, {"bar/fifo1", 0}, {"bar/barbar/bar2", 0}, }, }, { name: "whiteout file", in: [][]testutil.TarEntry{ { testutil.Dir("bar/"), testutil.File("bar/barfile", "bar"), }, { testutil.Dir("bar/"), testutil.File(path.Join("bar", whiteoutPrefix+"barfile"), "bar"), }, }, record: []string{"bar/barfile"}, want: []recordEntry{}, wantFail: true, }, { name: "whiteout dir", in: [][]testutil.TarEntry{ { testutil.Dir("bar/"), testutil.File("bar/barfile", "bar"), }, { testutil.Dir("bar/"), testutil.Dir(path.Join("bar", whiteoutOpaqueDir) + "/"), }, }, record: []string{"bar/barfile"}, want: []recordEntry{}, wantFail: true, }, { name: "whiteout dir", in: [][]testutil.TarEntry{ { testutil.Dir("bar/"), testutil.File("bar/barfile", "bar"), }, { testutil.Dir("bar/"), testutil.Dir(path.Join("bar", whiteoutOpaqueDir) + "/"), }, }, record: []string{"bar/barfile"}, want: []recordEntry{}, wantFail: true, }, } tempDir, err := os.MkdirTemp("", "test-recorder") if err != nil { t.Fatalf("failed to prepare content store dir: %v", err) } defer os.RemoveAll(tempDir) cs, err := local.NewStore(tempDir) if err != nil { t.Fatalf("failed to prepare content store: %v", err) } compressWrappers := map[string]func(r io.Reader) io.Reader{ ocispec.MediaTypeImageLayer: func(r io.Reader) io.Reader { return r }, // nop (uncompressed) ocispec.MediaTypeImageLayerGzip: gzipCompress, // gzip compression } ctx := context.Background() for _, tt := range tests { for _, prefix := range allowedPrefix { prefix := prefix for mediatype, cWrapper := range compressWrappers { t.Run(tt.name+":"+mediatype+",prefix="+prefix, func(t *testing.T) { var layers []ocispec.Descriptor for _, es := range tt.in { ref := fmt.Sprintf("recorder-test-%v", xid.New().String()) lw, err := content.OpenWriter(ctx, cs, content.WithRef(ref)) if err != nil { t.Errorf("failed to open writer: %v", err) return } tarR := testutil.BuildTar(es, testutil.WithPrefix(prefix)) if _, err := io.Copy(lw, cWrapper(tarR)); err != nil { t.Errorf("failed to copy layer: %v", err) return } if err := lw.Commit(ctx, 0, ""); err != nil && !errdefs.IsAlreadyExists(err) { t.Errorf("failed to commit layer: %v", err) return } info, err := cs.Info(ctx, lw.Digest()) if err != nil { t.Errorf("failed to get layer info: %v", err) return } // TODO: check compressed version as well layers = append(layers, ocispec.Descriptor{ Digest: info.Digest, Size: info.Size, MediaType: mediatype, }) } ir, err := imageRecorderFromManifest(ctx, cs, ocispec.Descriptor{}, ocispec.Manifest{Layers: layers}) if err != nil { t.Errorf("failed to get recorder: %v", err) return } defer ir.Close() fail := false for _, name := range tt.record { if err := ir.Record(name); err != nil { fail = true t.Logf("failed to record: %q: %v", name, err) break } } if tt.wantFail != fail { t.Errorf("unexpected record result: fail = %v; wantFail = %v", fail, tt.wantFail) return } if tt.wantFail { return // no need to check the record out } recordOut, err := ir.Commit(ctx) if err != nil { t.Errorf("failed to commit record: %v", err) return } ra, err := cs.ReaderAt(ctx, ocispec.Descriptor{Digest: recordOut}) if err != nil { t.Errorf("failed to get record out: %v", err) return } defer ra.Close() dec := json.NewDecoder(io.NewSectionReader(ra, 0, ra.Size())) i := 0 for dec.More() { var e recorder.Entry if err := dec.Decode(&e); err != nil { t.Errorf("failed to decord record: %v", err) return } if len(tt.want) <= i { t.Errorf("too many records: %d th but want %d", i, len(tt.want)) return } if e.Path != tt.want[i].name || *e.LayerIndex != tt.want[i].index { t.Errorf("unexpected entry { name = %q, index = %d }; want { name = %q, index = %d }", e.Path, *e.LayerIndex, tt.want[i].name, tt.want[i].index) return } i++ } if i < len(tt.want) { t.Errorf("record is too short: %d; but want %d", i, len(tt.want)) return } }) } } } } func gzipCompress(r io.Reader) io.Reader { pr, pw := io.Pipe() go func() { gw := gzip.NewWriter(pw) if _, err := io.Copy(gw, r); err != nil { gw.Close() pw.CloseWithError(err) return } gw.Close() pw.Close() }() return pr } stargz-snapshotter-0.14.3/cache/000077500000000000000000000000001440204344700165265ustar00rootroot00000000000000stargz-snapshotter-0.14.3/cache/cache.go000066400000000000000000000246531440204344700201320ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package cache import ( "bytes" "fmt" "io" "os" "path/filepath" "sync" "github.com/containerd/stargz-snapshotter/util/cacheutil" "github.com/containerd/stargz-snapshotter/util/namedmutex" "github.com/hashicorp/go-multierror" ) const ( defaultMaxLRUCacheEntry = 10 defaultMaxCacheFds = 10 ) type DirectoryCacheConfig struct { // Number of entries of LRU cache (default: 10). // This won't be used when DataCache is specified. MaxLRUCacheEntry int // Number of file descriptors to cache (default: 10). // This won't be used when FdCache is specified. MaxCacheFds int // On Add, wait until the data is fully written to the cache directory. SyncAdd bool // DataCache is an on-memory cache of the data. // OnEvicted will be overridden and replaced for internal use. DataCache *cacheutil.LRUCache // FdCache is a cache for opened file descriptors. // OnEvicted will be overridden and replaced for internal use. FdCache *cacheutil.LRUCache // BufPool will be used for pooling bytes.Buffer. BufPool *sync.Pool // Direct forcefully enables direct mode for all operation in cache. // Thus operation won't use on-memory caches. Direct bool } // TODO: contents validation. // BlobCache represents a cache for bytes data type BlobCache interface { // Add returns a writer to add contents to cache Add(key string, opts ...Option) (Writer, error) // Get returns a reader to read the specified contents // from cache Get(key string, opts ...Option) (Reader, error) // Close closes the cache Close() error } // Reader provides the data cached. type Reader interface { io.ReaderAt Close() error } // Writer enables the client to cache byte data. Commit() must be // called after data is fully written to Write(). To abort the written // data, Abort() must be called. type Writer interface { io.WriteCloser Commit() error Abort() error } type cacheOpt struct { direct bool } type Option func(o *cacheOpt) *cacheOpt // Direct option lets FetchAt and Add methods not to use on-memory caches. When // you know that the targeting value won't be used immediately, you can prevent // the limited space of on-memory caches from being polluted by these unimportant // values. func Direct() Option { return func(o *cacheOpt) *cacheOpt { o.direct = true return o } } func NewDirectoryCache(directory string, config DirectoryCacheConfig) (BlobCache, error) { if !filepath.IsAbs(directory) { return nil, fmt.Errorf("dir cache path must be an absolute path; got %q", directory) } bufPool := config.BufPool if bufPool == nil { bufPool = &sync.Pool{ New: func() interface{} { return new(bytes.Buffer) }, } } dataCache := config.DataCache if dataCache == nil { maxEntry := config.MaxLRUCacheEntry if maxEntry == 0 { maxEntry = defaultMaxLRUCacheEntry } dataCache = cacheutil.NewLRUCache(maxEntry) dataCache.OnEvicted = func(key string, value interface{}) { value.(*bytes.Buffer).Reset() bufPool.Put(value) } } fdCache := config.FdCache if fdCache == nil { maxEntry := config.MaxCacheFds if maxEntry == 0 { maxEntry = defaultMaxCacheFds } fdCache = cacheutil.NewLRUCache(maxEntry) fdCache.OnEvicted = func(key string, value interface{}) { value.(*os.File).Close() } } if err := os.MkdirAll(directory, 0700); err != nil { return nil, err } wipdir := filepath.Join(directory, "wip") if err := os.MkdirAll(wipdir, 0700); err != nil { return nil, err } dc := &directoryCache{ cache: dataCache, fileCache: fdCache, wipLock: new(namedmutex.NamedMutex), directory: directory, wipDirectory: wipdir, bufPool: bufPool, direct: config.Direct, } dc.syncAdd = config.SyncAdd return dc, nil } // directoryCache is a cache implementation which backend is a directory. type directoryCache struct { cache *cacheutil.LRUCache fileCache *cacheutil.LRUCache wipDirectory string directory string wipLock *namedmutex.NamedMutex bufPool *sync.Pool syncAdd bool direct bool closed bool closedMu sync.Mutex } func (dc *directoryCache) Get(key string, opts ...Option) (Reader, error) { if dc.isClosed() { return nil, fmt.Errorf("cache is already closed") } opt := &cacheOpt{} for _, o := range opts { opt = o(opt) } if !dc.direct && !opt.direct { // Get data from memory if b, done, ok := dc.cache.Get(key); ok { return &reader{ ReaderAt: bytes.NewReader(b.(*bytes.Buffer).Bytes()), closeFunc: func() error { done() return nil }, }, nil } // Get data from disk. If the file is already opened, use it. if f, done, ok := dc.fileCache.Get(key); ok { return &reader{ ReaderAt: f.(*os.File), closeFunc: func() error { done() // file will be closed when it's evicted from the cache return nil }, }, nil } } // Open the cache file and read the target region // TODO: If the target cache is write-in-progress, should we wait for the completion // or simply report the cache miss? file, err := os.Open(dc.cachePath(key)) if err != nil { return nil, fmt.Errorf("failed to open blob file for %q: %w", key, err) } // If "direct" option is specified, do not cache the file on memory. // This option is useful for preventing memory cache from being polluted by data // that won't be accessed immediately. if dc.direct || opt.direct { return &reader{ ReaderAt: file, closeFunc: func() error { return file.Close() }, }, nil } // TODO: should we cache the entire file data on memory? // but making I/O (possibly huge) on every fetching // might be costly. return &reader{ ReaderAt: file, closeFunc: func() error { _, done, added := dc.fileCache.Add(key, file) defer done() // Release it immediately. Cleaned up on eviction. if !added { return file.Close() // file already exists in the cache. close it. } return nil }, }, nil } func (dc *directoryCache) Add(key string, opts ...Option) (Writer, error) { if dc.isClosed() { return nil, fmt.Errorf("cache is already closed") } opt := &cacheOpt{} for _, o := range opts { opt = o(opt) } wip, err := dc.wipFile(key) if err != nil { return nil, err } w := &writer{ WriteCloser: wip, commitFunc: func() error { if dc.isClosed() { return fmt.Errorf("cache is already closed") } // Commit the cache contents c := dc.cachePath(key) if err := os.MkdirAll(filepath.Dir(c), os.ModePerm); err != nil { var allErr error if err := os.Remove(wip.Name()); err != nil { allErr = multierror.Append(allErr, err) } return multierror.Append(allErr, fmt.Errorf("failed to create cache directory %q: %w", c, err)) } return os.Rename(wip.Name(), c) }, abortFunc: func() error { return os.Remove(wip.Name()) }, } // If "direct" option is specified, do not cache the passed data on memory. // This option is useful for preventing memory cache from being polluted by data // that won't be accessed immediately. if dc.direct || opt.direct { return w, nil } b := dc.bufPool.Get().(*bytes.Buffer) memW := &writer{ WriteCloser: nopWriteCloser(io.Writer(b)), commitFunc: func() error { if dc.isClosed() { w.Close() return fmt.Errorf("cache is already closed") } cached, done, added := dc.cache.Add(key, b) if !added { dc.putBuffer(b) // already exists in the cache. abort it. } commit := func() error { defer done() defer w.Close() n, err := w.Write(cached.(*bytes.Buffer).Bytes()) if err != nil || n != cached.(*bytes.Buffer).Len() { w.Abort() return err } return w.Commit() } if dc.syncAdd { return commit() } go func() { if err := commit(); err != nil { fmt.Println("failed to commit to file:", err) } }() return nil }, abortFunc: func() error { defer w.Close() defer w.Abort() dc.putBuffer(b) // abort it. return nil }, } return memW, nil } func (dc *directoryCache) putBuffer(b *bytes.Buffer) { b.Reset() dc.bufPool.Put(b) } func (dc *directoryCache) Close() error { dc.closedMu.Lock() defer dc.closedMu.Unlock() if dc.closed { return nil } dc.closed = true return os.RemoveAll(dc.directory) } func (dc *directoryCache) isClosed() bool { dc.closedMu.Lock() closed := dc.closed dc.closedMu.Unlock() return closed } func (dc *directoryCache) cachePath(key string) string { return filepath.Join(dc.directory, key[:2], key) } func (dc *directoryCache) wipFile(key string) (*os.File, error) { return os.CreateTemp(dc.wipDirectory, key+"-*") } func NewMemoryCache() BlobCache { return &MemoryCache{ Membuf: map[string]*bytes.Buffer{}, } } // MemoryCache is a cache implementation which backend is a memory. type MemoryCache struct { Membuf map[string]*bytes.Buffer mu sync.Mutex } func (mc *MemoryCache) Get(key string, opts ...Option) (Reader, error) { mc.mu.Lock() defer mc.mu.Unlock() b, ok := mc.Membuf[key] if !ok { return nil, fmt.Errorf("Missed cache: %q", key) } return &reader{bytes.NewReader(b.Bytes()), func() error { return nil }}, nil } func (mc *MemoryCache) Add(key string, opts ...Option) (Writer, error) { b := new(bytes.Buffer) return &writer{ WriteCloser: nopWriteCloser(io.Writer(b)), commitFunc: func() error { mc.mu.Lock() defer mc.mu.Unlock() mc.Membuf[key] = b return nil }, abortFunc: func() error { return nil }, }, nil } func (mc *MemoryCache) Close() error { return nil } type reader struct { io.ReaderAt closeFunc func() error } func (r *reader) Close() error { return r.closeFunc() } type writer struct { io.WriteCloser commitFunc func() error abortFunc func() error } func (w *writer) Commit() error { return w.commitFunc() } func (w *writer) Abort() error { return w.abortFunc() } type writeCloser struct { io.Writer closeFunc func() error } func (w *writeCloser) Close() error { return w.closeFunc() } func nopWriteCloser(w io.Writer) io.WriteCloser { return &writeCloser{w, func() error { return nil }} } stargz-snapshotter-0.14.3/cache/cache_test.go000066400000000000000000000106751440204344700211700ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /* Copyright 2019 The Go Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the NOTICE.md file. */ package cache import ( "crypto/sha256" "fmt" "io" "os" "testing" ) const ( sampleData = "0123456789" ) func TestDirectoryCache(t *testing.T) { // with enough memory cache newCache := func() (BlobCache, cleanFunc) { tmp, err := os.MkdirTemp("", "testcache") if err != nil { t.Fatalf("failed to make tempdir: %v", err) } c, err := NewDirectoryCache(tmp, DirectoryCacheConfig{ MaxLRUCacheEntry: 10, SyncAdd: true, }) if err != nil { t.Fatalf("failed to make cache: %v", err) } return c, func() { os.RemoveAll(tmp) } } testCache(t, "dir-with-enough-mem", newCache) // with smaller memory cache newCache = func() (BlobCache, cleanFunc) { tmp, err := os.MkdirTemp("", "testcache") if err != nil { t.Fatalf("failed to make tempdir: %v", err) } c, err := NewDirectoryCache(tmp, DirectoryCacheConfig{ MaxLRUCacheEntry: 1, SyncAdd: true, }) if err != nil { t.Fatalf("failed to make cache: %v", err) } return c, func() { os.RemoveAll(tmp) } } testCache(t, "dir-with-small-mem", newCache) } func TestMemoryCache(t *testing.T) { testCache(t, "memory", func() (BlobCache, cleanFunc) { return NewMemoryCache(), func() {} }) } type cleanFunc func() func testCache(t *testing.T, name string, newCache func() (BlobCache, cleanFunc)) { tests := []struct { name string blobs []string checks []check }{ { name: "empty_data", blobs: []string{ "", }, checks: []check{ hit(""), miss(sampleData), }, }, { name: "data", blobs: []string{ sampleData, }, checks: []check{ hit(sampleData), miss("dummy"), }, }, { name: "manydata", blobs: []string{ sampleData, "test", }, checks: []check{ hit(sampleData), miss("dummy"), }, }, { name: "dup_data", blobs: []string{ sampleData, sampleData, }, checks: []check{ hit(sampleData), }, }, } for _, tt := range tests { t.Run(fmt.Sprintf("%s-%s", name, tt.name), func(t *testing.T) { c, clean := newCache() defer clean() for _, blob := range tt.blobs { d := digestFor(blob) w, err := c.Add(d) if err != nil { t.Fatalf("failed to add %v: %v", d, err) } if n, err := w.Write([]byte(blob)); err != nil || n != len(blob) { w.Close() t.Fatalf("failed to write %v (len:%d): %v", d, len(blob), err) } if err := w.Commit(); err != nil { w.Close() t.Fatalf("failed to commit %v (len:%d): %v", d, len(blob), err) } w.Close() } for _, check := range tt.checks { check(t, c) } }) } } type check func(*testing.T, BlobCache) func digestFor(content string) string { sum := sha256.Sum256([]byte(content)) return fmt.Sprintf("%x", sum) } func hit(sample string) check { return func(t *testing.T, c BlobCache) { // test whole blob key := digestFor(sample) testChunk(t, c, key, 0, sample) // test a chunk chunk := len(sample) / 3 testChunk(t, c, key, int64(chunk), sample[chunk:2*chunk]) } } func testChunk(t *testing.T, c BlobCache, key string, offset int64, sample string) { p := make([]byte, len(sample)) r, err := c.Get(key) if err != nil { t.Errorf("missed %v", key) return } if n, err := r.ReadAt(p, offset); err != nil && err != io.EOF { t.Errorf("failed to fetch blob %q: %v", key, err) return } else if n != len(sample) { t.Errorf("fetched size %d; want %d", len(p), len(sample)) return } if digestFor(sample) != digestFor(string(p)) { t.Errorf("fetched %q; want %q", string(p), sample) } } func miss(sample string) check { return func(t *testing.T, c BlobCache) { d := digestFor(sample) if _, err := c.Get(d); err == nil { t.Errorf("hit blob %q but must be missed: %v", d, err) return } } } stargz-snapshotter-0.14.3/cmd/000077500000000000000000000000001440204344700162265ustar00rootroot00000000000000stargz-snapshotter-0.14.3/cmd/containerd-stargz-grpc/000077500000000000000000000000001440204344700226155ustar00rootroot00000000000000stargz-snapshotter-0.14.3/cmd/containerd-stargz-grpc/db/000077500000000000000000000000001440204344700232025ustar00rootroot00000000000000stargz-snapshotter-0.14.3/cmd/containerd-stargz-grpc/db/db.go000066400000000000000000000372651440204344700241330ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package db import ( "encoding/binary" "fmt" "os" "sort" "github.com/containerd/stargz-snapshotter/metadata" bolt "go.etcd.io/bbolt" ) // Metadata package stores filesystem metadata in the following schema. // // - filesystems // - *filesystem id* : bucket for each filesystem keyed by a unique string. // - nodes // - *node id* : bucket for each node keyed by a uniqe uint64. // - size : : size of the regular node. // - modtime : : modification time of the node. // - linkName : : link target of symlink // - mode : : permission and mode bits (os.FileMode). // - uid : : uid of the owner. // - gid : : gid of the owner. // - devMajor : : the major device number for device // - devMinor : : the minor device number for device // - xattrKey : : key of the first extended attribute. // - xattrValue : : value of the first extended attribute // - xattrsExtra : 2nd and the following extended attribute. // - *key* : : map of key to value string // - numLink : : the number of links pointing to this node. // - metadata // - *node id* : bucket for each node keyed by a uniqe uint64. // - childName : : base name of the first child // - childID : : id of the first child // - childrenExtra : 2nd and following child nodes of directory. // - *basename* : : map of basename string to the child node id // - chunk : : information of the first chunkn // - chunksExtra : 2nd and following chunks (this is rarely used so we can avoid the cost of creating the bucket) // - *chunk offset* : : keyed by chunk offset (varint) in the estargz file to the chunk. // - nextOffset : : the offset of the next node with a non-zero offset. // - stream // - *offset* : bucket for each chunk stream that have multiple inner chunks. // - *innerOffset* : node id : node id that has the contents at the keyed innerOffset. var ( bucketKeyFilesystems = []byte("filesystems") bucketKeyNodes = []byte("nodes") bucketKeySize = []byte("size") bucketKeyModTime = []byte("modtime") bucketKeyLinkName = []byte("linkName") bucketKeyMode = []byte("mode") bucketKeyUID = []byte("uid") bucketKeyGID = []byte("gid") bucketKeyDevMajor = []byte("devMajor") bucketKeyDevMinor = []byte("devMinor") bucketKeyXattrKey = []byte("xattrKey") bucketKeyXattrValue = []byte("xattrValue") bucketKeyXattrsExtra = []byte("xattrsExtra") bucketKeyNumLink = []byte("numLink") bucketKeyMetadata = []byte("metadata") bucketKeyChildName = []byte("childName") bucketKeyChildID = []byte("childID") bucketKeyChildrenExtra = []byte("childrenExtra") bucketKeyChunk = []byte("chunk") bucketKeyChunksExtra = []byte("chunksExtra") bucketKeyNextOffset = []byte("nextOffset") bucketKeyStream = []byte("stream") ) type childEntry struct { base string id uint32 } type chunkEntry struct { offset int64 chunkOffset int64 chunkSize int64 chunkDigest string innerOffset int64 // -1 indicates that no following chunks in the stream. } type metadataEntry struct { children map[string]childEntry chunks []chunkEntry nextOffset int64 } func getNodes(tx *bolt.Tx, fsID string) (*bolt.Bucket, error) { filesystems := tx.Bucket(bucketKeyFilesystems) if filesystems == nil { return nil, fmt.Errorf("fs %q not found: no fs is registered", fsID) } lbkt := filesystems.Bucket([]byte(fsID)) if lbkt == nil { return nil, fmt.Errorf("fs bucket for %q not found", fsID) } nodes := lbkt.Bucket(bucketKeyNodes) if nodes == nil { return nil, fmt.Errorf("nodes bucket for %q not found", fsID) } return nodes, nil } func getMetadata(tx *bolt.Tx, fsID string) (*bolt.Bucket, error) { filesystems := tx.Bucket(bucketKeyFilesystems) if filesystems == nil { return nil, fmt.Errorf("fs %q not found: no fs is registered", fsID) } lbkt := filesystems.Bucket([]byte(fsID)) if lbkt == nil { return nil, fmt.Errorf("fs bucket for %q not found", fsID) } md := lbkt.Bucket(bucketKeyMetadata) if md == nil { return nil, fmt.Errorf("metadata bucket for fs %q not found", fsID) } return md, nil } func getStream(tx *bolt.Tx, fsID string) (*bolt.Bucket, error) { filesystems := tx.Bucket(bucketKeyFilesystems) if filesystems == nil { return nil, fmt.Errorf("fs %q not found: no fs is registered", fsID) } lbkt := filesystems.Bucket([]byte(fsID)) if lbkt == nil { return nil, fmt.Errorf("fs bucket for %q not found", fsID) } st := lbkt.Bucket(bucketKeyStream) if st == nil { return nil, fmt.Errorf("stream bucket for fs %q not found", fsID) } return st, nil } func getNodeBucketByID(nodes *bolt.Bucket, id uint32) (*bolt.Bucket, error) { b := nodes.Bucket(encodeID(id)) if b == nil { return nil, fmt.Errorf("node bucket for %d not found", id) } return b, nil } func getMetadataBucketByID(md *bolt.Bucket, id uint32) (*bolt.Bucket, error) { b := md.Bucket(encodeID(id)) if b == nil { return nil, fmt.Errorf("metadata bucket for %d not found", id) } return b, nil } func writeAttr(b *bolt.Bucket, attr *metadata.Attr) error { for _, v := range []struct { key []byte val int64 }{ {bucketKeySize, attr.Size}, {bucketKeyUID, int64(attr.UID)}, {bucketKeyGID, int64(attr.GID)}, {bucketKeyDevMajor, int64(attr.DevMajor)}, {bucketKeyDevMinor, int64(attr.DevMinor)}, {bucketKeyNumLink, int64(attr.NumLink - 1)}, // numLink = 0 means num link = 1 in DB } { if v.val != 0 { val, err := encodeInt(v.val) if err != nil { return err } if err := b.Put(v.key, val); err != nil { return err } } } if !attr.ModTime.IsZero() { te, err := attr.ModTime.GobEncode() if err != nil { return err } if err := b.Put(bucketKeyModTime, te); err != nil { return err } } if len(attr.LinkName) > 0 { if err := b.Put(bucketKeyLinkName, []byte(attr.LinkName)); err != nil { return err } } if attr.Mode != 0 { val, err := encodeUint(uint64(attr.Mode)) if err != nil { return err } if err := b.Put(bucketKeyMode, val); err != nil { return err } } if len(attr.Xattrs) > 0 { var firstK string var firstV []byte for k, v := range attr.Xattrs { firstK, firstV = k, v break } if err := b.Put(bucketKeyXattrKey, []byte(firstK)); err != nil { return err } if err := b.Put(bucketKeyXattrValue, firstV); err != nil { return err } var xbkt *bolt.Bucket for k, v := range attr.Xattrs { if k == firstK || len(v) == 0 { continue } if xbkt == nil { if xbkt := b.Bucket(bucketKeyXattrsExtra); xbkt != nil { // Reset if err := b.DeleteBucket(bucketKeyXattrsExtra); err != nil { return err } } var err error xbkt, err = b.CreateBucket(bucketKeyXattrsExtra) if err != nil { return err } } if err := xbkt.Put([]byte(k), v); err != nil { return fmt.Errorf("failed to set xattr %q=%q: %w", k, string(v), err) } } } return nil } func readAttr(b *bolt.Bucket, attr *metadata.Attr) error { return b.ForEach(func(k, v []byte) error { switch string(k) { case string(bucketKeySize): attr.Size, _ = binary.Varint(v) case string(bucketKeyModTime): if err := (&attr.ModTime).GobDecode(v); err != nil { return err } case string(bucketKeyLinkName): attr.LinkName = string(v) case string(bucketKeyMode): mode, _ := binary.Uvarint(v) attr.Mode = os.FileMode(uint32(mode)) case string(bucketKeyUID): i, _ := binary.Varint(v) attr.UID = int(i) case string(bucketKeyGID): i, _ := binary.Varint(v) attr.GID = int(i) case string(bucketKeyDevMajor): i, _ := binary.Varint(v) attr.DevMajor = int(i) case string(bucketKeyDevMinor): i, _ := binary.Varint(v) attr.DevMinor = int(i) case string(bucketKeyNumLink): i, _ := binary.Varint(v) attr.NumLink = int(i) + 1 // numLink = 0 means num link = 1 in DB case string(bucketKeyXattrKey): if attr.Xattrs == nil { attr.Xattrs = make(map[string][]byte) } attr.Xattrs[string(v)] = b.Get(bucketKeyXattrValue) case string(bucketKeyXattrsExtra): if err := b.Bucket(k).ForEach(func(k, v []byte) error { if attr.Xattrs == nil { attr.Xattrs = make(map[string][]byte) } attr.Xattrs[string(k)] = v return nil }); err != nil { return err } } return nil }) } func readNumLink(b *bolt.Bucket) int { // numLink = 0 means num link = 1 in BD numLink, _ := binary.Varint(b.Get(bucketKeyNumLink)) return int(numLink) + 1 } func readChunks(b *bolt.Bucket, size int64) (chunks []chunkEntry, err error) { if chunk := b.Get(bucketKeyChunk); len(chunk) > 0 { e, err := decodeChunkEntry(chunk) if err != nil { return nil, err } chunks = append(chunks, e) } if chbkt := b.Bucket(bucketKeyChunksExtra); chbkt != nil { if err := chbkt.ForEach(func(_, v []byte) error { e, err := decodeChunkEntry(v) if err != nil { return err } chunks = append(chunks, e) return nil }); err != nil { return nil, err } sort.Slice(chunks, func(i, j int) bool { return chunks[i].chunkOffset < chunks[j].chunkOffset }) } nextOffset := size for i := len(chunks) - 1; i >= 0; i-- { chunks[i].chunkSize = nextOffset - chunks[i].chunkOffset nextOffset = chunks[i].chunkOffset } return } type chunkEntryWithID struct { chunkEntry id uint32 } func readInnerChunks(tx *bolt.Tx, fsID string, off int64) (chunks []chunkEntryWithID, err error) { sb, err := getStream(tx, fsID) if err != nil { return nil, err } offEncoded, err := encodeInt(off) if err != nil { return nil, err } ob := sb.Bucket(offEncoded) if ob == nil { return nil, fmt.Errorf("inner chunk bucket for %d not found", off) } nodes, err := getNodes(tx, fsID) if err != nil { return nil, fmt.Errorf("nodes bucket of %q not found: %w", fsID, err) } metadataEntries, err := getMetadata(tx, fsID) if err != nil { return nil, fmt.Errorf("metadata bucket of %q not found: %w", fsID, err) } if err := ob.ForEach(func(_, v []byte) error { nodeid := decodeID(v) b, err := getNodeBucketByID(nodes, nodeid) if err != nil { return fmt.Errorf("failed to get file bucket %d: %w", nodeid, err) } size, _ := binary.Varint(b.Get(bucketKeySize)) if md, err := getMetadataBucketByID(metadataEntries, nodeid); err == nil { nodeChunks, err := readChunks(md, size) if err != nil { return fmt.Errorf("failed to get chunks: %w", err) } for _, e := range nodeChunks { if e.offset == off { chunks = append(chunks, chunkEntryWithID{e, nodeid}) } } } return nil }); err != nil { return nil, err } sort.Slice(chunks, func(i, j int) bool { return chunks[i].innerOffset < chunks[j].innerOffset }) return chunks, nil } func readChild(md *bolt.Bucket, base string) (uint32, error) { if base == string(md.Get(bucketKeyChildName)) { return decodeID(md.Get(bucketKeyChildID)), nil } cbkt := md.Bucket(bucketKeyChildrenExtra) if cbkt == nil { return 0, fmt.Errorf("extra children not found") } eid := cbkt.Get([]byte(base)) if len(eid) == 0 { return 0, fmt.Errorf("children %q not found", base) } return decodeID(eid), nil } func writeMetadataEntry(md *bolt.Bucket, m *metadataEntry) error { if len(m.children) > 0 { var firstChildName string var firstChild childEntry for name, child := range m.children { firstChildName, firstChild = name, child break } if err := md.Put(bucketKeyChildID, encodeID(firstChild.id)); err != nil { return fmt.Errorf("failed to put id of first child %q: %w", firstChildName, err) } if err := md.Put(bucketKeyChildName, []byte(firstChildName)); err != nil { return fmt.Errorf("failed to put name first child %q: %w", firstChildName, err) } if len(m.children) > 1 { var cbkt *bolt.Bucket for k, c := range m.children { if k == firstChildName { continue } if cbkt == nil { if cbkt := md.Bucket(bucketKeyChildrenExtra); cbkt != nil { // Reset if err := md.DeleteBucket(bucketKeyChildrenExtra); err != nil { return err } } var err error cbkt, err = md.CreateBucket(bucketKeyChildrenExtra) if err != nil { return err } } if err := cbkt.Put([]byte(c.base), encodeID(c.id)); err != nil { return fmt.Errorf("failed to add child ID %q: %w", c.id, err) } } } } if len(m.chunks) > 0 { first := m.chunks[0] if err := md.Put(bucketKeyChunk, encodeChunkEntry(first)); err != nil { return fmt.Errorf("failed to set chunk %q: %w", first.offset, err) } var cbkt *bolt.Bucket for _, e := range m.chunks[1:] { if cbkt == nil { if cbkt := md.Bucket(bucketKeyChunksExtra); cbkt != nil { // Reset if err := md.DeleteBucket(bucketKeyChunksExtra); err != nil { return err } } var err error cbkt, err = md.CreateBucket(bucketKeyChunksExtra) if err != nil { return err } } ecoff, err := encodeInt(e.chunkOffset) if err != nil { return err } if err := cbkt.Put(ecoff, encodeChunkEntry(e)); err != nil { return err } } } if m.nextOffset > 0 { if err := putInt(md, bucketKeyNextOffset, m.nextOffset); err != nil { return fmt.Errorf("failed to set next offset value %d: %w", m.nextOffset, err) } } return nil } func encodeChunkEntry(e chunkEntry) []byte { eb := make([]byte, 24+len([]byte(e.chunkDigest))) binary.BigEndian.PutUint64(eb[0:8], uint64(e.chunkOffset)) binary.BigEndian.PutUint64(eb[8:16], uint64(e.offset)) binary.BigEndian.PutUint64(eb[16:24], uint64(e.innerOffset)) copy(eb[24:], []byte(e.chunkDigest)) return eb } func decodeChunkEntry(d []byte) (e chunkEntry, _ error) { if len(d) < 24 { return e, fmt.Errorf("mulformed chunk entry (len:%d)", len(d)) } e.chunkOffset = int64(binary.BigEndian.Uint64(d[0:8])) e.offset = int64(binary.BigEndian.Uint64(d[8:16])) e.innerOffset = int64(binary.BigEndian.Uint64(d[16:24])) if len(d) > 24 { e.chunkDigest = string(d[24:]) } return e, nil } func putInt(b *bolt.Bucket, k []byte, v int64) error { i, err := encodeInt(v) if err != nil { return err } return b.Put(k, i) } func encodeID(id uint32) []byte { b := [4]byte{} binary.BigEndian.PutUint32(b[:], id) return b[:] } func decodeID(b []byte) uint32 { return binary.BigEndian.Uint32(b) } func encodeInt(i int64) ([]byte, error) { var ( buf [binary.MaxVarintLen64]byte iEncoded = buf[:] ) iEncoded = iEncoded[:binary.PutVarint(iEncoded, i)] if len(iEncoded) == 0 { return nil, fmt.Errorf("failed encoding integer = %v", i) } return iEncoded, nil } func encodeUint(i uint64) ([]byte, error) { var ( buf [binary.MaxVarintLen64]byte iEncoded = buf[:] ) iEncoded = iEncoded[:binary.PutUvarint(iEncoded, i)] if len(iEncoded) == 0 { return nil, fmt.Errorf("failed encoding integer = %v", i) } return iEncoded, nil } stargz-snapshotter-0.14.3/cmd/containerd-stargz-grpc/db/reader.go000066400000000000000000000756611440204344700250120ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package db import ( "bufio" "bytes" "encoding/binary" "errors" "fmt" "io" "math" "os" "path" "path/filepath" "sort" "strings" "sync" "time" "github.com/containerd/stargz-snapshotter/estargz" "github.com/containerd/stargz-snapshotter/metadata" "github.com/goccy/go-json" "github.com/hashicorp/go-multierror" digest "github.com/opencontainers/go-digest" "github.com/rs/xid" bolt "go.etcd.io/bbolt" "golang.org/x/sync/errgroup" ) // reader stores filesystem metadata parsed from eStargz to metadata DB // and provides methods to read them. type reader struct { db *bolt.DB fsID string rootID uint32 tocDigest digest.Digest sr *io.SectionReader curID uint32 curIDMu sync.Mutex initG *errgroup.Group decompressor metadata.Decompressor } func (r *reader) nextID() (uint32, error) { r.curIDMu.Lock() defer r.curIDMu.Unlock() if r.curID == math.MaxUint32 { return 0, fmt.Errorf("sequence id too large") } r.curID++ return r.curID, nil } // NewReader parses an eStargz and stores filesystem metadata to // the provided DB. func NewReader(db *bolt.DB, sr *io.SectionReader, opts ...metadata.Option) (metadata.Reader, error) { var rOpts metadata.Options for _, o := range opts { if err := o(&rOpts); err != nil { return nil, fmt.Errorf("failed to apply option: %w", err) } } gzipCompressors := []metadata.Decompressor{new(estargz.GzipDecompressor), new(estargz.LegacyGzipDecompressor)} decompressors := append(gzipCompressors, rOpts.Decompressors...) // Determine the size to fetch. Try to fetch as many bytes as possible. fetchSize := maxFooterSize(sr.Size(), decompressors...) if maybeTocOffset := rOpts.TOCOffset; maybeTocOffset > fetchSize { if maybeTocOffset > sr.Size() { return nil, fmt.Errorf("blob size %d is smaller than the toc offset", sr.Size()) } fetchSize = sr.Size() - maybeTocOffset } start := time.Now() // before getting layer footer footer := make([]byte, fetchSize) if _, err := sr.ReadAt(footer, sr.Size()-fetchSize); err != nil { return nil, fmt.Errorf("error reading footer: %v", err) } if rOpts.Telemetry != nil && rOpts.Telemetry.GetFooterLatency != nil { rOpts.Telemetry.GetFooterLatency(start) } var allErr error var tocR io.ReadCloser var decompressor metadata.Decompressor for _, d := range decompressors { fSize := d.FooterSize() fOffset := positive(int64(len(footer)) - fSize) maybeTocBytes := footer[:fOffset] _, tocOffset, tocSize, err := d.ParseFooter(footer[fOffset:]) if err != nil { allErr = multierror.Append(allErr, err) continue } if tocOffset >= 0 && tocSize <= 0 { tocSize = sr.Size() - tocOffset - fSize } if tocOffset >= 0 && tocSize < int64(len(maybeTocBytes)) { maybeTocBytes = maybeTocBytes[:tocSize] } tocR, err = decompressTOC(d, sr, tocOffset, tocSize, maybeTocBytes, rOpts) if err != nil { allErr = multierror.Append(allErr, err) continue } decompressor = d break } if tocR == nil { if allErr == nil { return nil, fmt.Errorf("failed to get the reader of TOC: unknown") } return nil, fmt.Errorf("failed to get the reader of TOC: %w", allErr) } defer tocR.Close() r := &reader{sr: sr, db: db, initG: new(errgroup.Group), decompressor: decompressor} if err := r.init(tocR, rOpts); err != nil { return nil, fmt.Errorf("failed to initialize matadata: %w", err) } return r, nil } func maxFooterSize(blobSize int64, decompressors ...metadata.Decompressor) (res int64) { for _, d := range decompressors { if s := d.FooterSize(); res < s && s <= blobSize { res = s } } return } func decompressTOC(d metadata.Decompressor, sr *io.SectionReader, tocOff, tocSize int64, tocBytes []byte, opts metadata.Options) (io.ReadCloser, error) { if tocOff < 0 { // This means that TOC isn't contained in the blob. // We pass nil reader to DecompressTOC and expect that it acquires TOC from // the external location. start := time.Now() tocR, err := d.DecompressTOC(nil) if err != nil { return nil, err } if opts.Telemetry != nil && opts.Telemetry.GetTocLatency != nil { opts.Telemetry.GetTocLatency(start) } return tocR, nil } if len(tocBytes) > 0 { start := time.Now() // before getting TOC tocR, err := d.DecompressTOC(bytes.NewReader(tocBytes)) if err == nil { if opts.Telemetry != nil && opts.Telemetry.GetTocLatency != nil { opts.Telemetry.GetTocLatency(start) } return tocR, nil } } start := time.Now() // before getting TOC tocBytes = make([]byte, tocSize) if _, err := sr.ReadAt(tocBytes, tocOff); err != nil { return nil, fmt.Errorf("error reading %d byte TOC targz: %v", len(tocBytes), err) } r, err := d.DecompressTOC(bytes.NewReader(tocBytes)) if err != nil { return nil, err } if opts.Telemetry != nil && opts.Telemetry.GetTocLatency != nil { opts.Telemetry.GetTocLatency(start) } return r, nil } // RootID returns ID of the root node. func (r *reader) RootID() uint32 { return r.rootID } func (r *reader) TOCDigest() digest.Digest { return r.tocDigest } // Clone returns a new reader identical to the current reader // but uses the provided section reader for retrieving file paylaods. func (r *reader) Clone(sr *io.SectionReader) (metadata.Reader, error) { if err := r.waitInit(); err != nil { return nil, err } return &reader{ db: r.db, fsID: r.fsID, rootID: r.rootID, sr: sr, initG: new(errgroup.Group), decompressor: r.decompressor, }, nil } func (r *reader) init(decompressedR io.Reader, rOpts metadata.Options) (retErr error) { start := time.Now() // before parsing TOC JSON // Initialize root node var ok bool for i := 0; i < 100; i++ { fsID := xid.New().String() if err := r.initRootNode(fsID); err != nil { if errors.Is(err, bolt.ErrBucketExists) { continue // try with another id } return fmt.Errorf("failed to initialize root node %q: %w", fsID, err) } ok = true break } if !ok { return fmt.Errorf("failed to get a unique id for metadata reader") } f, err := os.CreateTemp("", "") if err != nil { return err } closeFunc := func() (closeErr error) { name := f.Name() if err := f.Close(); err != nil { closeErr = multierror.Append(closeErr, err) } if err := os.Remove(name); err != nil { closeErr = multierror.Append(closeErr, err) } return } defer func() { if retErr != nil { if err := closeFunc(); err != nil { retErr = multierror.Append(retErr, err) } } }() if err := f.Chmod(0600); err != nil { return err } dgstr := digest.Canonical.Digester() if _, err := io.Copy(f, io.TeeReader(decompressedR, dgstr.Hash())); err != nil { return fmt.Errorf("failed to read TOC: %w", err) } r.tocDigest = dgstr.Digest() // Initialize file metadata in background. All operations refer to these metadata must wait // until this initialization ends. r.initG.Go(func() error { defer closeFunc() if _, err := f.Seek(0, io.SeekStart); err != nil { return err } if err := r.initNodes(f); err != nil { return err } if rOpts.Telemetry != nil && rOpts.Telemetry.DeserializeTocLatency != nil { rOpts.Telemetry.DeserializeTocLatency(start) } return nil }) return nil } func (r *reader) initRootNode(fsID string) error { return r.db.Batch(func(tx *bolt.Tx) (err error) { filesystems, err := tx.CreateBucketIfNotExists(bucketKeyFilesystems) if err != nil { return err } lbkt, err := filesystems.CreateBucket([]byte(fsID)) if err != nil { return err } r.fsID = fsID if _, err := lbkt.CreateBucket(bucketKeyMetadata); err != nil { return err } if _, err := lbkt.CreateBucket(bucketKeyStream); err != nil { return err } nodes, err := lbkt.CreateBucket(bucketKeyNodes) if err != nil { return err } rootID, err := r.nextID() if err != nil { return err } rootBucket, err := nodes.CreateBucket(encodeID(rootID)) if err != nil { return err } if err := writeAttr(rootBucket, &metadata.Attr{ Mode: os.ModeDir | 0755, NumLink: 2, // The directory itself(.) and the parent link to this directory. }); err != nil { return err } r.rootID = rootID return err }) } func (r *reader) initNodes(tr io.Reader) error { dec := json.NewDecoder(tr) for { t, err := dec.Token() if err != nil { return fmt.Errorf("failed to get JSON token: %w", err) } if ele, ok := t.(string); ok { if ele == "version" { continue } if ele == "entries" { continue } } if de, ok := t.(json.Delim); ok { if de.String() == "[" { break } } } md := make(map[uint32]*metadataEntry) st := make(map[int64]map[int64]uint32) if err := r.db.Batch(func(tx *bolt.Tx) (err error) { nodes, err := getNodes(tx, r.fsID) if err != nil { return err } nodes.FillPercent = 1.0 // we only do sequential write to this bucket var wantNextOffsetID []uint32 var lastEntBucketID uint32 var lastEntSize int64 var attr metadata.Attr var ent estargz.TOCEntry for dec.More() { resetEnt(&ent) if err := dec.Decode(&ent); err != nil { return err } ent.Name = cleanEntryName(ent.Name) if ent.Type == "chunk" { if lastEntBucketID == 0 { return fmt.Errorf("chunk entry must not be the topmost") } if ent.ChunkSize == 0 { // last chunk in this file ent.ChunkSize = lastEntSize - ent.ChunkOffset } } if ent.ChunkSize == 0 && ent.Size != 0 { ent.ChunkSize = ent.Size } if ent.Type != "chunk" { var id uint32 var b *bolt.Bucket if ent.Type == "hardlink" { id, err = getIDByName(md, ent.LinkName, r.rootID) if err != nil { return fmt.Errorf("%q is a hardlink but cannot get link destination %q: %w", ent.Name, ent.LinkName, err) } b, err = getNodeBucketByID(nodes, id) if err != nil { return fmt.Errorf("cannot get hardlink destination %q ==> %q (%d): %w", ent.Name, ent.LinkName, id, err) } numLink, _ := binary.Varint(b.Get(bucketKeyNumLink)) if err := putInt(b, bucketKeyNumLink, numLink+1); err != nil { return fmt.Errorf("cannot put NumLink of %q ==> %q: %w", ent.Name, ent.LinkName, err) } } else { // Write node bucket var found bool if ent.Type == "dir" { // Check if this directory is already created, if so overwrite it. id, err = getIDByName(md, ent.Name, r.rootID) if err == nil { b, err = getNodeBucketByID(nodes, id) if err != nil { return fmt.Errorf("failed to get directory bucket %d: %w", id, err) } found = true ent.NumLink = readNumLink(b) } } if !found { // No existing node. Create a new one. id, err = r.nextID() if err != nil { return err } b, err = nodes.CreateBucket(encodeID(id)) if err != nil { return err } ent.NumLink = 1 // at least the parent dir references this directory. if ent.Type == "dir" { ent.NumLink++ // at least "." references this directory. } } if err := writeAttr(b, attrFromTOCEntry(&ent, &attr)); err != nil { return fmt.Errorf("failed to set attr to %d(%q): %w", id, ent.Name, err) } } pdirName := parentDir(ent.Name) pid, pb, err := r.getOrCreateDir(nodes, md, pdirName, r.rootID) if err != nil { return fmt.Errorf("failed to create parent directory %q of %q: %w", pdirName, ent.Name, err) } if err := setChild(md, pb, pid, path.Base(ent.Name), id, ent.Type == "dir"); err != nil { return err } if ent.Offset > 0 && ent.InnerOffset == 0 && len(wantNextOffsetID) > 0 { for _, i := range wantNextOffsetID { if md[i] == nil { md[i] = &metadataEntry{} } md[i].nextOffset = ent.Offset } wantNextOffsetID = nil } if ent.Type == "reg" && ent.Size > 0 { wantNextOffsetID = append(wantNextOffsetID, id) } lastEntSize = ent.Size lastEntBucketID = id } if (ent.Type == "reg" && ent.Size > 0) || (ent.Type == "chunk" && ent.ChunkSize > 0) { if md[lastEntBucketID] == nil { md[lastEntBucketID] = &metadataEntry{} } ce := chunkEntry{ent.Offset, ent.ChunkOffset, ent.ChunkSize, ent.ChunkDigest, ent.InnerOffset} md[lastEntBucketID].chunks = append(md[lastEntBucketID].chunks, ce) if _, ok := st[ent.Offset]; !ok { st[ent.Offset] = make(map[int64]uint32) } st[ent.Offset][ent.InnerOffset] = lastEntBucketID } } if len(wantNextOffsetID) > 0 { for _, i := range wantNextOffsetID { if md[i] == nil { md[i] = &metadataEntry{} } md[i].nextOffset = r.sr.Size() } } return nil }); err != nil { return err } for mdK, d := range md { for cK, ce := range d.chunks { if len(st[ce.offset]) == 1 { for ioff := range st[ce.offset] { if ioff == 0 { // This stream contains only 1 chunk with innerOffset=0. No need to record innerOffsets. md[mdK].chunks[cK].innerOffset = -1 // indicates no following chunks in this stream. } break } } } } addendum := make([]struct { id []byte md *metadataEntry }, len(md)) i := 0 for id, d := range md { addendum[i].id, addendum[i].md = encodeID(id), d i++ } sort.Slice(addendum, func(i, j int) bool { return bytes.Compare(addendum[i].id, addendum[j].id) < 0 }) if err := r.db.Batch(func(tx *bolt.Tx) (err error) { meta, err := getMetadata(tx, r.fsID) if err != nil { return err } meta.FillPercent = 1.0 // we only do sequential write to this bucket for _, m := range addendum { md, err := meta.CreateBucket(m.id) if err != nil { return err } if err := writeMetadataEntry(md, m.md); err != nil { return err } } return nil }); err != nil { return err } addendumStream := make([]struct { offset []byte st map[int64]uint32 }, len(st)) i = 0 for off, s := range st { singleStream := false if len(s) == 1 { for ioff := range s { if ioff == 0 { singleStream = true } break } } if singleStream { continue // This stream contains only 1 chunk with innerOffset=0. No need to record. } offKey, err := encodeInt(off) if err != nil { return err } addendumStream[i].offset, addendumStream[i].st = offKey, s i++ } addendumStream = addendumStream[:i] if len(addendumStream) > 0 { sort.Slice(addendumStream, func(i, j int) bool { return bytes.Compare(addendumStream[i].offset, addendumStream[j].offset) < 0 }) if err := r.db.Batch(func(tx *bolt.Tx) (err error) { stream, err := getStream(tx, r.fsID) if err != nil { return err } stream.FillPercent = 1.0 // we only do sequential write to this bucket for _, s := range addendumStream { stbkt, err := stream.CreateBucket(s.offset) if err != nil { return err } for innerOffset, nodeid := range s.st { iOffKey, err := encodeInt(innerOffset) if err != nil { return err } if err := stbkt.Put(iOffKey, encodeID(nodeid)); err != nil { return fmt.Errorf("failed to put inner offset info of %d: %w", nodeid, err) } } } return nil }); err != nil { return err } } return nil } func (r *reader) getOrCreateDir(nodes *bolt.Bucket, md map[uint32]*metadataEntry, d string, rootID uint32) (id uint32, b *bolt.Bucket, err error) { id, err = getIDByName(md, d, rootID) if err != nil { id, err = r.nextID() if err != nil { return 0, nil, err } b, err = nodes.CreateBucket(encodeID(id)) if err != nil { return 0, nil, err } attr := &metadata.Attr{ Mode: os.ModeDir | 0755, NumLink: 2, // The directory itself(.) and the parent link to this directory. } if err := writeAttr(b, attr); err != nil { return 0, nil, err } if d != "" { pid, pb, err := r.getOrCreateDir(nodes, md, parentDir(d), rootID) if err != nil { return 0, nil, err } if err := setChild(md, pb, pid, path.Base(d), id, true); err != nil { return 0, nil, err } } } else { b, err = getNodeBucketByID(nodes, id) if err != nil { return 0, nil, fmt.Errorf("failed to get dir bucket %d: %w", id, err) } } return id, b, nil } func (r *reader) waitInit() error { // TODO: add timeout if err := r.initG.Wait(); err != nil { return fmt.Errorf("initialization failed: %w", err) } return nil } func (r *reader) view(fn func(tx *bolt.Tx) error) error { if err := r.waitInit(); err != nil { return err } return r.db.View(func(tx *bolt.Tx) error { return fn(tx) }) } func (r *reader) update(fn func(tx *bolt.Tx) error) error { if err := r.waitInit(); err != nil { return err } return r.db.Batch(func(tx *bolt.Tx) error { return fn(tx) }) } // Close closes this reader. This removes underlying filesystem metadata as well. func (r *reader) Close() error { return r.update(func(tx *bolt.Tx) (err error) { filesystems := tx.Bucket(bucketKeyFilesystems) if filesystems == nil { return nil } return filesystems.DeleteBucket([]byte(r.fsID)) }) } // GetOffset returns an offset of a node. func (r *reader) GetOffset(id uint32) (offset int64, _ error) { if err := r.view(func(tx *bolt.Tx) error { metadataEntries, err := getMetadata(tx, r.fsID) if err != nil { return fmt.Errorf("metadata bucket of %q not found for searching offset of %d: %w", r.fsID, id, err) } nodes, err := getNodes(tx, r.fsID) if err != nil { return err } b, err := getNodeBucketByID(nodes, id) if err != nil { return err } size, _ := binary.Varint(b.Get(bucketKeySize)) if md, err := getMetadataBucketByID(metadataEntries, id); err == nil { chunks, err := readChunks(md, size) if err != nil { return err } if len(chunks) > 0 { offset = chunks[0].offset } } return nil }); err != nil { return 0, err } return } // GetAttr returns file attribute of specified node. func (r *reader) GetAttr(id uint32) (attr metadata.Attr, _ error) { if r.rootID == id { // no need to wait for root dir if err := r.db.View(func(tx *bolt.Tx) error { nodes, err := getNodes(tx, r.fsID) if err != nil { return fmt.Errorf("nodes bucket of %q not found for sarching attr %d: %w", r.fsID, id, err) } b, err := getNodeBucketByID(nodes, id) if err != nil { return fmt.Errorf("failed to get attr bucket %d: %w", id, err) } return readAttr(b, &attr) }); err != nil { return metadata.Attr{}, err } return attr, nil } if err := r.view(func(tx *bolt.Tx) error { nodes, err := getNodes(tx, r.fsID) if err != nil { return fmt.Errorf("nodes bucket of %q not found for sarching attr %d: %w", r.fsID, id, err) } b, err := getNodeBucketByID(nodes, id) if err != nil { return fmt.Errorf("failed to get attr bucket %d: %w", id, err) } return readAttr(b, &attr) }); err != nil { return metadata.Attr{}, err } return } // GetChild returns a child node that has the specified base name. func (r *reader) GetChild(pid uint32, base string) (id uint32, attr metadata.Attr, _ error) { if err := r.view(func(tx *bolt.Tx) error { metadataEntries, err := getMetadata(tx, r.fsID) if err != nil { return fmt.Errorf("metadata bucket of %q not found for getting child of %d: %w", r.fsID, pid, err) } md, err := getMetadataBucketByID(metadataEntries, pid) if err != nil { return fmt.Errorf("failed to get parent metadata %d: %w", pid, err) } id, err = readChild(md, base) if err != nil { return fmt.Errorf("failed to read child %q of %d: %w", base, pid, err) } nodes, err := getNodes(tx, r.fsID) if err != nil { return fmt.Errorf("nodes bucket of %q not found for getting child of %d: %w", r.fsID, pid, err) } child, err := getNodeBucketByID(nodes, id) if err != nil { return fmt.Errorf("failed to get child bucket %d: %w", id, err) } return readAttr(child, &attr) }); err != nil { return 0, metadata.Attr{}, err } return } // ForeachChild calls the specified callback function for each child node. // When the callback returns non-nil error, this stops the iteration. func (r *reader) ForeachChild(id uint32, f func(name string, id uint32, mode os.FileMode) bool) error { type childInfo struct { id uint32 mode os.FileMode } children := make(map[string]childInfo) if err := r.view(func(tx *bolt.Tx) error { metadataEntries, err := getMetadata(tx, r.fsID) if err != nil { return fmt.Errorf("nodes bucket of %q not found for getting child of %d: %w", r.fsID, id, err) } md, err := getMetadataBucketByID(metadataEntries, id) if err != nil { return nil // no child } var nodes *bolt.Bucket firstName := md.Get(bucketKeyChildName) if len(firstName) != 0 { firstID := decodeID(md.Get(bucketKeyChildID)) if nodes == nil { nodes, err = getNodes(tx, r.fsID) if err != nil { return fmt.Errorf("nodes bucket of %q not found for getting children of %d: %w", r.fsID, id, err) } } firstChild, err := getNodeBucketByID(nodes, firstID) if err != nil { return fmt.Errorf("failed to get first child bucket %d: %w", firstID, err) } mode, _ := binary.Uvarint(firstChild.Get(bucketKeyMode)) children[string(firstName)] = childInfo{firstID, os.FileMode(uint32(mode))} } cbkt := md.Bucket(bucketKeyChildrenExtra) if cbkt == nil { return nil // no child } if nodes == nil { nodes, err = getNodes(tx, r.fsID) if err != nil { return fmt.Errorf("nodes bucket of %q not found for getting children of %d: %w", r.fsID, id, err) } } return cbkt.ForEach(func(k, v []byte) error { id := decodeID(v) child, err := getNodeBucketByID(nodes, id) if err != nil { return fmt.Errorf("failed to get child bucket %d: %w", id, err) } mode, _ := binary.Uvarint(child.Get(bucketKeyMode)) children[string(k)] = childInfo{id, os.FileMode(uint32(mode))} return nil }) }); err != nil { return err } for k, e := range children { if !f(k, e.id, e.mode) { break } } return nil } // OpenFileWithPreReader returns a section reader of the specified node. // When it reads other ranges than required by the returned reader (e.g. when the target range is located in // a large chunk with innerOffset), these chunks are passed to the callback so that it can be cached for futural use. func (r *reader) OpenFileWithPreReader(id uint32, preRead func(nid uint32, chunkOffset, chunkSize int64, chunkDigest string, r io.Reader) error) (metadata.File, error) { return r.openFile(id, preRead) } // OpenFile returns a section reader of the specified node. func (r *reader) OpenFile(id uint32) (metadata.File, error) { return r.openFile(id, nil) } func (r *reader) openFile(id uint32, preRead func(id uint32, chunkOffset, chunkSize int64, chunkDigest string, r io.Reader) error) (metadata.File, error) { var chunks []chunkEntry var size int64 var nextOffset int64 if err := r.view(func(tx *bolt.Tx) error { nodes, err := getNodes(tx, r.fsID) if err != nil { return fmt.Errorf("nodes bucket of %q not found for opening %d: %w", r.fsID, id, err) } b, err := getNodeBucketByID(nodes, id) if err != nil { return fmt.Errorf("failed to get file bucket %d: %w", id, err) } size, _ = binary.Varint(b.Get(bucketKeySize)) m, _ := binary.Uvarint(b.Get(bucketKeyMode)) if !os.FileMode(uint32(m)).IsRegular() { return fmt.Errorf("%q is not a regular file", id) } metadataEntries, err := getMetadata(tx, r.fsID) if err != nil { return fmt.Errorf("metadata bucket of %q not found for opening %d: %w", r.fsID, id, err) } if md, err := getMetadataBucketByID(metadataEntries, id); err == nil { chunks, err = readChunks(md, size) if err != nil { return fmt.Errorf("failed to get chunks: %w", err) } nextOffset, _ = binary.Varint(md.Get(bucketKeyNextOffset)) } return nil }); err != nil { return nil, err } fr := &fileReader{ r: r, size: size, ents: chunks, nextOffset: nextOffset, preRead: preRead, } return &file{io.NewSectionReader(fr, 0, size), chunks}, nil } type file struct { io.ReaderAt ents []chunkEntry } func (fr *file) ChunkEntryForOffset(offset int64) (off int64, size int64, dgst string, ok bool) { i := sort.Search(len(fr.ents), func(i int) bool { e := fr.ents[i] return e.chunkOffset >= offset || (offset > e.chunkOffset && offset < e.chunkOffset+e.chunkSize) }) if i == len(fr.ents) { return 0, 0, "", false } ci := fr.ents[i] return ci.chunkOffset, ci.chunkSize, ci.chunkDigest, true } type fileReader struct { r *reader size int64 ents []chunkEntry nextOffset int64 preRead func(id uint32, chunkOffset, chunkSize int64, chunkDigest string, r io.Reader) error } // ReadAt reads file payload of this file. func (fr *fileReader) ReadAt(p []byte, off int64) (n int, err error) { if off >= fr.size { return 0, io.EOF } if off < 0 { return 0, errors.New("invalid offset") } var ent chunkEntry switch len(fr.ents) { case 0: return 0, errors.New("no chunk is registered") case 1: ent = fr.ents[0] if ent.chunkOffset > off { return 0, fmt.Errorf("no chunk coveres offset %d", off) } default: i := sort.Search(len(fr.ents), func(i int) bool { return fr.ents[i].chunkOffset > off }) if i == 0 { return 0, fmt.Errorf("no chunk coveres offset %d", off) } ent = fr.ents[i-1] } compressedBytesRemain := fr.nextOffset - ent.offset bufSize := int(2 << 20) if bufSize > int(compressedBytesRemain) { bufSize = int(compressedBytesRemain) } br := bufio.NewReaderSize(io.NewSectionReader(fr.r.sr, ent.offset, compressedBytesRemain), bufSize) if _, err := br.Peek(bufSize); err != nil { return 0, fmt.Errorf("failed to peek read file payload: %v", err) } dr, err := fr.r.decompressor.Reader(br) if err != nil { return 0, fmt.Errorf("fileReader.ReadAt.decompressor.Reader: %v", err) } defer dr.Close() // Stream that doesn't contain multiple chunks is indicated as ent.innerOffset < 0. if fr.preRead == nil || ent.innerOffset < 0 { base := off - ent.chunkOffset if ent.innerOffset > 0 { base += ent.innerOffset } if n, err := io.CopyN(io.Discard, dr, base); n != base || err != nil { return 0, fmt.Errorf("discard of %d bytes = %v, %v", base, n, err) } return io.ReadFull(dr, p) } var innerChunks []chunkEntryWithID if err := fr.r.view(func(tx *bolt.Tx) error { innerChunks, err = readInnerChunks(tx, fr.r.fsID, ent.offset) return err }); err != nil { return 0, err } var found bool var nr int64 var retN int var retErr error for _, e := range innerChunks { // Fully read the previous chunk reader so that the seek position goes at the current chunk offset if in, err := io.CopyN(io.Discard, dr, e.innerOffset-nr); err != nil || in != e.innerOffset-nr { return 0, fmt.Errorf("discard of remaining %d bytes != %v, %v", e.innerOffset-nr, in, err) } nr += e.innerOffset - nr if e.innerOffset == ent.innerOffset { found = true base := off - ent.chunkOffset if n, err := io.CopyN(io.Discard, dr, base); n != base || err != nil { return 0, fmt.Errorf("discard of offset %d bytes != %v, %v", off, n, err) } retN, retErr = io.ReadFull(dr, p) nr += base + int64(retN) continue } cr := &countReader{r: io.LimitReader(dr, e.chunkSize)} if err := fr.preRead(e.id, e.chunkOffset, e.chunkSize, e.chunkDigest, cr); err != nil { return 0, fmt.Errorf("failed to pre read: %w", err) } nr += cr.n } if !found { return 0, fmt.Errorf("fileReader.ReadAt: target entry not found") } return retN, retErr } // TODO: share it with memory pkg func attrFromTOCEntry(src *estargz.TOCEntry, dst *metadata.Attr) *metadata.Attr { dst.Size = src.Size dst.ModTime, _ = time.Parse(time.RFC3339, src.ModTime3339) dst.LinkName = src.LinkName dst.Mode = src.Stat().Mode() dst.UID = src.UID dst.GID = src.GID dst.DevMajor = src.DevMajor dst.DevMinor = src.DevMinor dst.Xattrs = src.Xattrs dst.NumLink = src.NumLink return dst } func getIDByName(md map[uint32]*metadataEntry, name string, rootID uint32) (uint32, error) { name = cleanEntryName(name) if name == "" { return rootID, nil } dir, base := filepath.Split(name) pid, err := getIDByName(md, dir, rootID) if err != nil { return 0, err } if md[pid] == nil { return 0, fmt.Errorf("not found metadata of %d", pid) } if md[pid].children == nil { return 0, fmt.Errorf("not found children of %q", pid) } c, ok := md[pid].children[base] if !ok { return 0, fmt.Errorf("not found child %q in %d", base, pid) } return c.id, nil } func setChild(md map[uint32]*metadataEntry, pb *bolt.Bucket, pid uint32, base string, id uint32, isDir bool) error { if md[pid] == nil { md[pid] = &metadataEntry{} } if md[pid].children == nil { md[pid].children = make(map[string]childEntry) } md[pid].children[base] = childEntry{base, id} if isDir { numLink, _ := binary.Varint(pb.Get(bucketKeyNumLink)) if err := putInt(pb, bucketKeyNumLink, numLink+1); err != nil { return fmt.Errorf("cannot add numlink for children: %w", err) } } return nil } func parentDir(p string) string { dir, _ := path.Split(p) return strings.TrimSuffix(dir, "/") } func cleanEntryName(name string) string { // Use path.Clean to consistently deal with path separators across platforms. return strings.TrimPrefix(path.Clean("/"+name), "/") } func resetEnt(ent *estargz.TOCEntry) { ent.Name = "" ent.Type = "" ent.Size = 0 ent.ModTime3339 = "" ent.LinkName = "" ent.Mode = 0 ent.UID = 0 ent.GID = 0 ent.Uname = "" ent.Gname = "" ent.Offset = 0 ent.DevMajor = 0 ent.DevMinor = 0 ent.NumLink = 0 ent.Xattrs = nil ent.Digest = "" ent.ChunkOffset = 0 ent.ChunkSize = 0 ent.ChunkDigest = "" ent.InnerOffset = 0 } func positive(n int64) int64 { if n < 0 { return 0 } return n } func (r *reader) NumOfNodes() (i int, _ error) { if err := r.view(func(tx *bolt.Tx) error { nodes, err := getNodes(tx, r.fsID) if err != nil { return err } return nodes.ForEach(func(k, v []byte) error { b := nodes.Bucket(k) if b == nil { return fmt.Errorf("entry bucket for %q not found", string(k)) } var attr metadata.Attr if err := readAttr(b, &attr); err != nil { return err } i++ return nil }) }); err != nil { return 0, err } return } func (r *reader) NumOfChunks(id uint32) (i int, _ error) { if err := r.view(func(tx *bolt.Tx) error { metadataEntries, err := getMetadata(tx, r.fsID) if err != nil { return err } md, err := getMetadataBucketByID(metadataEntries, id) if err != nil { return err } nodes, err := getNodes(tx, r.fsID) if err != nil { return err } b, err := getNodeBucketByID(nodes, id) if err != nil { return err } size, _ := binary.Varint(b.Get(bucketKeySize)) chunks, err := readChunks(md, size) if err != nil { return err } i = len(chunks) return nil }); err != nil { return 0, err } return } type countReader struct { r io.Reader n int64 } func (cr *countReader) Read(p []byte) (n int, err error) { n, err = cr.r.Read(p) cr.n += int64(n) return } stargz-snapshotter-0.14.3/cmd/containerd-stargz-grpc/db/reader_test.go000066400000000000000000000046161440204344700260410ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package db import ( "io" "os" "testing" "github.com/containerd/stargz-snapshotter/fs/layer" fsreader "github.com/containerd/stargz-snapshotter/fs/reader" "github.com/containerd/stargz-snapshotter/metadata" "github.com/containerd/stargz-snapshotter/metadata/testutil" bolt "go.etcd.io/bbolt" ) func TestReader(t *testing.T) { testutil.TestReader(t, newTestableReader) } func TestFSReader(t *testing.T) { fsreader.TestSuiteReader(t, newStore) } func TestFSLayer(t *testing.T) { layer.TestSuiteLayer(t, newStore) } func newTestableReader(sr *io.SectionReader, opts ...metadata.Option) (testutil.TestableReader, error) { f, err := os.CreateTemp("", "readertestdb") if err != nil { return nil, err } defer f.Close() defer os.Remove(f.Name()) db, err := bolt.Open(f.Name(), 0600, nil) if err != nil { return nil, err } r, err := NewReader(db, sr, opts...) if err != nil { return nil, err } return &testableReadCloser{ TestableReader: r.(*reader), closeFn: func() error { db.Close() return os.Remove(f.Name()) }, }, nil } func newStore(sr *io.SectionReader, opts ...metadata.Option) (metadata.Reader, error) { f, err := os.CreateTemp("", "readertestdb") if err != nil { return nil, err } defer f.Close() db, err := bolt.Open(f.Name(), 0600, nil) if err != nil { return nil, err } r, err := NewReader(db, sr, opts...) if err != nil { return nil, err } return &readCloser{ Reader: r, closeFn: func() error { db.Close() return os.Remove(f.Name()) }, }, nil } type readCloser struct { metadata.Reader closeFn func() error } func (r *readCloser) Close() error { r.closeFn() return r.Reader.Close() } type testableReadCloser struct { testutil.TestableReader closeFn func() error } func (r *testableReadCloser) Close() error { r.closeFn() return r.TestableReader.Close() } stargz-snapshotter-0.14.3/cmd/containerd-stargz-grpc/ipfs/000077500000000000000000000000001440204344700235565ustar00rootroot00000000000000stargz-snapshotter-0.14.3/cmd/containerd-stargz-grpc/ipfs/resolvehandler.go000066400000000000000000000045011440204344700271220ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package ipfs import ( "context" "crypto/sha256" "fmt" "io" "os" "github.com/containerd/stargz-snapshotter/fs/remote" "github.com/containerd/stargz-snapshotter/ipfs" ipfsclient "github.com/containerd/stargz-snapshotter/ipfs/client" ocispec "github.com/opencontainers/image-spec/specs-go/v1" ) type ResolveHandler struct{} func (r *ResolveHandler) Handle(ctx context.Context, desc ocispec.Descriptor) (remote.Fetcher, int64, error) { cid, err := ipfs.GetCID(desc) if err != nil { return nil, 0, err } var ipath string if idir := os.Getenv("IPFS_PATH"); idir != "" { ipath = idir } // HTTP is only supported as of now. We can add https support here if needed (e.g. for connecting to it via proxy, etc) iurl, err := ipfsclient.GetIPFSAPIAddress(ipath, "http") if err != nil { return nil, 0, err } client := ipfsclient.New(iurl) info, err := client.StatCID(cid) if err != nil { return nil, 0, err } return &fetcher{cid: cid, size: int64(info.Size), client: client}, int64(info.Size), nil } type fetcher struct { cid string size int64 client *ipfsclient.Client } func (f *fetcher) Fetch(ctx context.Context, off int64, size int64) (io.ReadCloser, error) { if off > f.size { return nil, fmt.Errorf("offset is larger than the size of the blob %d(offset) > %d(blob size)", off, f.size) } o, s := int(off), int(size) return f.client.Get("/ipfs/"+f.cid, &o, &s) } func (f *fetcher) Check() error { _, err := f.client.StatCID(f.cid) return err } func (f *fetcher) GenID(off int64, size int64) string { sum := sha256.Sum256([]byte(fmt.Sprintf("%s-%d-%d", f.cid, off, size))) return fmt.Sprintf("%x", sum) } type readCloser struct { io.Reader closeFunc func() error } func (r *readCloser) Close() error { return r.closeFunc() } stargz-snapshotter-0.14.3/cmd/containerd-stargz-grpc/main.go000066400000000000000000000264331440204344700241000ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package main import ( "context" "flag" "fmt" "io" golog "log" "math/rand" "net" "net/http" "os" "os/signal" "path/filepath" "time" snapshotsapi "github.com/containerd/containerd/api/services/snapshots/v1" "github.com/containerd/containerd/contrib/snapshotservice" "github.com/containerd/containerd/defaults" "github.com/containerd/containerd/log" "github.com/containerd/containerd/pkg/dialer" "github.com/containerd/containerd/snapshots" "github.com/containerd/containerd/sys" runtime_alpha "github.com/containerd/containerd/third_party/k8s.io/cri-api/pkg/apis/runtime/v1alpha2" dbmetadata "github.com/containerd/stargz-snapshotter/cmd/containerd-stargz-grpc/db" ipfs "github.com/containerd/stargz-snapshotter/cmd/containerd-stargz-grpc/ipfs" "github.com/containerd/stargz-snapshotter/fs" "github.com/containerd/stargz-snapshotter/metadata" memorymetadata "github.com/containerd/stargz-snapshotter/metadata/memory" "github.com/containerd/stargz-snapshotter/service" "github.com/containerd/stargz-snapshotter/service/keychain/cri" "github.com/containerd/stargz-snapshotter/service/keychain/crialpha" "github.com/containerd/stargz-snapshotter/service/keychain/dockerconfig" "github.com/containerd/stargz-snapshotter/service/keychain/kubeconfig" "github.com/containerd/stargz-snapshotter/service/resolver" "github.com/containerd/stargz-snapshotter/version" sddaemon "github.com/coreos/go-systemd/v22/daemon" metrics "github.com/docker/go-metrics" "github.com/pelletier/go-toml" "github.com/sirupsen/logrus" bolt "go.etcd.io/bbolt" "golang.org/x/sys/unix" "google.golang.org/grpc" "google.golang.org/grpc/backoff" "google.golang.org/grpc/credentials/insecure" runtime "k8s.io/cri-api/pkg/apis/runtime/v1" ) const ( defaultAddress = "/run/containerd-stargz-grpc/containerd-stargz-grpc.sock" defaultConfigPath = "/etc/containerd-stargz-grpc/config.toml" defaultLogLevel = logrus.InfoLevel defaultRootDir = "/var/lib/containerd-stargz-grpc" defaultImageServiceAddress = "/run/containerd/containerd.sock" ) var ( address = flag.String("address", defaultAddress, "address for the snapshotter's GRPC server") configPath = flag.String("config", defaultConfigPath, "path to the configuration file") logLevel = flag.String("log-level", defaultLogLevel.String(), "set the logging level [trace, debug, info, warn, error, fatal, panic]") rootDir = flag.String("root", defaultRootDir, "path to the root directory for this snapshotter") printVersion = flag.Bool("version", false, "print the version") ) type snapshotterConfig struct { service.Config // MetricsAddress is address for the metrics API MetricsAddress string `toml:"metrics_address"` // NoPrometheus is a flag to disable the emission of the metrics NoPrometheus bool `toml:"no_prometheus"` // DebugAddress is a Unix domain socket address where the snapshotter exposes /debug/ endpoints. DebugAddress string `toml:"debug_address"` // IPFS is a flag to enbale lazy pulling from IPFS. IPFS bool `toml:"ipfs"` // MetadataStore is the type of the metadata store to use. MetadataStore string `toml:"metadata_store" default:"memory"` } func main() { rand.Seed(time.Now().UnixNano()) flag.Parse() lvl, err := logrus.ParseLevel(*logLevel) if err != nil { log.L.WithError(err).Fatal("failed to prepare logger") } if *printVersion { fmt.Println("containerd-stargz-grpc", version.Version, version.Revision) return } logrus.SetLevel(lvl) logrus.SetFormatter(&logrus.JSONFormatter{ TimestampFormat: log.RFC3339NanoFixed, }) var ( ctx = log.WithLogger(context.Background(), log.L) config snapshotterConfig ) // Streams log of standard lib (go-fuse uses this) into debug log // Snapshotter should use "github.com/containerd/containerd/log" otherwize // logs are always printed as "debug" mode. golog.SetOutput(log.G(ctx).WriterLevel(logrus.DebugLevel)) // Get configuration from specified file tree, err := toml.LoadFile(*configPath) if err != nil && !(os.IsNotExist(err) && *configPath == defaultConfigPath) { log.G(ctx).WithError(err).Fatalf("failed to load config file %q", *configPath) } if err := tree.Unmarshal(&config); err != nil { log.G(ctx).WithError(err).Fatalf("failed to unmarshal config file %q", *configPath) } if err := service.Supported(*rootDir); err != nil { log.G(ctx).WithError(err).Fatalf("snapshotter is not supported") } // Create a gRPC server rpc := grpc.NewServer() // Configure keychain credsFuncs := []resolver.Credential{dockerconfig.NewDockerconfigKeychain(ctx)} if config.Config.KubeconfigKeychainConfig.EnableKeychain { var opts []kubeconfig.Option if kcp := config.Config.KubeconfigKeychainConfig.KubeconfigPath; kcp != "" { opts = append(opts, kubeconfig.WithKubeconfigPath(kcp)) } credsFuncs = append(credsFuncs, kubeconfig.NewKubeconfigKeychain(ctx, opts...)) } if config.Config.CRIKeychainConfig.EnableKeychain { // connects to the backend CRI service (defaults to containerd socket) criAddr := defaultImageServiceAddress if cp := config.CRIKeychainConfig.ImageServicePath; cp != "" { criAddr = cp } connectCRI := func() (runtime.ImageServiceClient, error) { conn, err := newCRIConn(criAddr) if err != nil { return nil, err } return runtime.NewImageServiceClient(conn), nil } connectAlphaCRI := func() (runtime_alpha.ImageServiceClient, error) { conn, err := newCRIConn(criAddr) if err != nil { return nil, err } return runtime_alpha.NewImageServiceClient(conn), nil } f, criServer := cri.NewCRIKeychain(ctx, connectCRI) fAlpha, criAlphaServer := crialpha.NewCRIAlphaKeychain(ctx, connectAlphaCRI) runtime.RegisterImageServiceServer(rpc, criServer) runtime_alpha.RegisterImageServiceServer(rpc, criAlphaServer) credsFuncs = append(credsFuncs, f, fAlpha) } fsOpts := []fs.Option{fs.WithMetricsLogLevel(logrus.InfoLevel)} if config.IPFS { fsOpts = append(fsOpts, fs.WithResolveHandler("ipfs", new(ipfs.ResolveHandler))) } mt, err := getMetadataStore(*rootDir, config) if err != nil { log.G(ctx).WithError(err).Fatalf("failed to configure metadata store") } fsOpts = append(fsOpts, fs.WithMetadataStore(mt)) rs, err := service.NewStargzSnapshotterService(ctx, *rootDir, &config.Config, service.WithCredsFuncs(credsFuncs...), service.WithFilesystemOptions(fsOpts...)) if err != nil { log.G(ctx).WithError(err).Fatalf("failed to configure snapshotter") } cleanup, err := serve(ctx, rpc, *address, rs, config) if err != nil { log.G(ctx).WithError(err).Fatalf("failed to serve snapshotter") } if cleanup { log.G(ctx).Debug("Closing the snapshotter") rs.Close() } log.G(ctx).Info("Exiting") } func serve(ctx context.Context, rpc *grpc.Server, addr string, rs snapshots.Snapshotter, config snapshotterConfig) (bool, error) { // Convert the snapshotter to a gRPC service, snsvc := snapshotservice.FromSnapshotter(rs) // Register the service with the gRPC server snapshotsapi.RegisterSnapshotsServer(rpc, snsvc) // Prepare the directory for the socket if err := os.MkdirAll(filepath.Dir(addr), 0700); err != nil { return false, fmt.Errorf("failed to create directory %q: %w", filepath.Dir(addr), err) } // Try to remove the socket file to avoid EADDRINUSE if err := os.RemoveAll(addr); err != nil { return false, fmt.Errorf("failed to remove %q: %w", addr, err) } errCh := make(chan error, 1) // We need to consider both the existence of MetricsAddress as well as NoPrometheus flag not set if config.MetricsAddress != "" && !config.NoPrometheus { l, err := net.Listen("tcp", config.MetricsAddress) if err != nil { return false, fmt.Errorf("failed to get listener for metrics endpoint: %w", err) } m := http.NewServeMux() m.Handle("/metrics", metrics.Handler()) go func() { if err := http.Serve(l, m); err != nil { errCh <- fmt.Errorf("error on serving metrics via socket %q: %w", addr, err) } }() } if config.DebugAddress != "" { log.G(ctx).Infof("listen %q for debugging", config.DebugAddress) l, err := sys.GetLocalListener(config.DebugAddress, 0, 0) if err != nil { return false, fmt.Errorf("failed to listen %q: %w", config.DebugAddress, err) } go func() { if err := http.Serve(l, debugServerMux()); err != nil { errCh <- fmt.Errorf("error on serving a debug endpoint via socket %q: %w", addr, err) } }() } // Listen and serve l, err := net.Listen("unix", addr) if err != nil { return false, fmt.Errorf("error on listen socket %q: %w", addr, err) } go func() { if err := rpc.Serve(l); err != nil { errCh <- fmt.Errorf("error on serving via socket %q: %w", addr, err) } }() if os.Getenv("NOTIFY_SOCKET") != "" { notified, notifyErr := sddaemon.SdNotify(false, sddaemon.SdNotifyReady) log.G(ctx).Debugf("SdNotifyReady notified=%v, err=%v", notified, notifyErr) } defer func() { if os.Getenv("NOTIFY_SOCKET") != "" { notified, notifyErr := sddaemon.SdNotify(false, sddaemon.SdNotifyStopping) log.G(ctx).Debugf("SdNotifyStopping notified=%v, err=%v", notified, notifyErr) } }() var s os.Signal sigCh := make(chan os.Signal, 1) signal.Notify(sigCh, unix.SIGINT, unix.SIGTERM) select { case s = <-sigCh: log.G(ctx).Infof("Got %v", s) case err := <-errCh: return false, err } if s == unix.SIGINT { return true, nil // do cleanup on SIGINT } return false, nil } const ( memoryMetadataType = "memory" dbMetadataType = "db" ) func getMetadataStore(rootDir string, config snapshotterConfig) (metadata.Store, error) { switch config.MetadataStore { case "", memoryMetadataType: return memorymetadata.NewReader, nil case dbMetadataType: bOpts := bolt.Options{ NoFreelistSync: true, InitialMmapSize: 64 * 1024 * 1024, FreelistType: bolt.FreelistMapType, } db, err := bolt.Open(filepath.Join(rootDir, "metadata.db"), 0600, &bOpts) if err != nil { return nil, err } return func(sr *io.SectionReader, opts ...metadata.Option) (metadata.Reader, error) { return dbmetadata.NewReader(db, sr, opts...) }, nil default: return nil, fmt.Errorf("unknown metadata store type: %v; must be %v or %v", config.MetadataStore, memoryMetadataType, dbMetadataType) } } func newCRIConn(criAddr string) (*grpc.ClientConn, error) { // TODO: make gRPC options configurable from config.toml backoffConfig := backoff.DefaultConfig backoffConfig.MaxDelay = 3 * time.Second connParams := grpc.ConnectParams{ Backoff: backoffConfig, } gopts := []grpc.DialOption{ grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithConnectParams(connParams), grpc.WithContextDialer(dialer.ContextDialer), grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(defaults.DefaultMaxRecvMsgSize)), grpc.WithDefaultCallOptions(grpc.MaxCallSendMsgSize(defaults.DefaultMaxSendMsgSize)), } return grpc.Dial(dialer.DialAddress(criAddr), gopts...) } stargz-snapshotter-0.14.3/cmd/containerd-stargz-grpc/server.go000066400000000000000000000021151440204344700244510ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package main import ( "expvar" "net/http" "net/http/pprof" ) func debugServerMux() *http.ServeMux { m := http.NewServeMux() m.Handle("/debug/vars", expvar.Handler()) m.Handle("/debug/pprof/", http.HandlerFunc(pprof.Index)) m.Handle("/debug/pprof/cmdline", http.HandlerFunc(pprof.Cmdline)) m.Handle("/debug/pprof/profile", http.HandlerFunc(pprof.Profile)) m.Handle("/debug/pprof/symbol", http.HandlerFunc(pprof.Symbol)) m.Handle("/debug/pprof/trace", http.HandlerFunc(pprof.Trace)) return m } stargz-snapshotter-0.14.3/cmd/ctr-remote/000077500000000000000000000000001440204344700203075ustar00rootroot00000000000000stargz-snapshotter-0.14.3/cmd/ctr-remote/commands/000077500000000000000000000000001440204344700221105ustar00rootroot00000000000000stargz-snapshotter-0.14.3/cmd/ctr-remote/commands/convert.go000066400000000000000000000243461440204344700241300ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package commands import ( "compress/gzip" gocontext "context" "encoding/json" "errors" "fmt" "os" "os/signal" "github.com/containerd/containerd/cmd/ctr/commands" "github.com/containerd/containerd/content" "github.com/containerd/containerd/images" "github.com/containerd/containerd/images/converter" "github.com/containerd/containerd/images/converter/uncompress" "github.com/containerd/containerd/platforms" "github.com/containerd/stargz-snapshotter/estargz" estargzconvert "github.com/containerd/stargz-snapshotter/nativeconverter/estargz" esgzexternaltocconvert "github.com/containerd/stargz-snapshotter/nativeconverter/estargz/externaltoc" zstdchunkedconvert "github.com/containerd/stargz-snapshotter/nativeconverter/zstdchunked" "github.com/containerd/stargz-snapshotter/recorder" "github.com/klauspost/compress/zstd" ocispec "github.com/opencontainers/image-spec/specs-go/v1" "github.com/sirupsen/logrus" "github.com/urfave/cli" ) // ConvertCommand converts an image var ConvertCommand = cli.Command{ Name: "convert", Usage: "convert an image", ArgsUsage: "[flags] ...", Description: `Convert an image format. e.g., 'ctr-remote convert --estargz --oci example.com/foo:orig example.com/foo:esgz' Use '--platform' to define the output platform. When '--all-platforms' is given all images in a manifest list must be available. `, Flags: []cli.Flag{ // estargz flags cli.BoolFlag{ Name: "estargz", Usage: "convert legacy tar(.gz) layers to eStargz for lazy pulling. Should be used in conjunction with '--oci'", }, cli.StringFlag{ Name: "estargz-record-in", Usage: "Read 'ctr-remote optimize --record-out=' record file", }, cli.IntFlag{ Name: "estargz-compression-level", Usage: "eStargz compression level", Value: gzip.BestCompression, }, cli.IntFlag{ Name: "estargz-chunk-size", Usage: "eStargz chunk size", Value: 0, }, cli.IntFlag{ Name: "estargz-min-chunk-size", Usage: "The minimal number of bytes of data must be written in one gzip stream. Note that this adds a TOC property that old reader doesn't understand.", Value: 0, }, cli.BoolFlag{ Name: "estargz-external-toc", Usage: "Separate TOC JSON into another image (called \"TOC image\"). The name of TOC image is the original + \"-esgztoc\" suffix. Both eStargz and the TOC image should be pushed to the same registry. stargz-snapshotter refers to the TOC image when it pulls the result eStargz image.", }, cli.BoolFlag{ Name: "estargz-keep-diff-id", Usage: "convert to esgz without changing diffID (cannot be used in conjunction with '--estargz-record-in'. must be specified with '--estargz-external-toc')", }, // zstd:chunked flags cli.BoolFlag{ Name: "zstdchunked", Usage: "use zstd compression instead of gzip (a.k.a zstd:chunked). Must be used in conjunction with '--oci'.", }, cli.StringFlag{ Name: "zstdchunked-record-in", Usage: "Read 'ctr-remote optimize --record-out=' record file", }, cli.IntFlag{ Name: "zstdchunked-compression-level", Usage: "zstd:chunked compression level", Value: 3, // SpeedDefault; see also https://pkg.go.dev/github.com/klauspost/compress/zstd#EncoderLevel }, cli.IntFlag{ Name: "zstdchunked-chunk-size", Usage: "zstd:chunked chunk size", Value: 0, }, // generic flags cli.BoolFlag{ Name: "uncompress", Usage: "convert tar.gz layers to uncompressed tar layers", }, cli.BoolFlag{ Name: "oci", Usage: "convert Docker media types to OCI media types", }, // platform flags cli.StringSliceFlag{ Name: "platform", Usage: "Convert content for a specific platform", Value: &cli.StringSlice{}, }, cli.BoolFlag{ Name: "all-platforms", Usage: "Convert content for all platforms", }, }, Action: func(context *cli.Context) error { var ( convertOpts = []converter.Opt{} ) srcRef := context.Args().Get(0) targetRef := context.Args().Get(1) if srcRef == "" || targetRef == "" { return errors.New("src and target image need to be specified") } var platformMC platforms.MatchComparer if context.Bool("all-platforms") { platformMC = platforms.All } else { if pss := context.StringSlice("platform"); len(pss) > 0 { var all []ocispec.Platform for _, ps := range pss { p, err := platforms.Parse(ps) if err != nil { return fmt.Errorf("invalid platform %q: %w", ps, err) } all = append(all, p) } platformMC = platforms.Ordered(all...) } else { platformMC = platforms.DefaultStrict() } } convertOpts = append(convertOpts, converter.WithPlatform(platformMC)) var layerConvertFunc converter.ConvertFunc var finalize func(ctx gocontext.Context, cs content.Store, ref string, desc *ocispec.Descriptor) (*images.Image, error) if context.Bool("estargz") { esgzOpts, err := getESGZConvertOpts(context) if err != nil { return err } if context.Bool("estargz-external-toc") { if !context.Bool("estargz-keep-diff-id") { layerConvertFunc, finalize = esgzexternaltocconvert.LayerConvertFunc(esgzOpts, context.Int("estargz-compression-level")) } else { if context.String("estargz-record-in") != "" { return fmt.Errorf("option --estargz-keep-diff-id conflicts with --estargz-record-in") } layerConvertFunc, finalize = esgzexternaltocconvert.LayerConvertLossLessFunc(esgzexternaltocconvert.LayerConvertLossLessConfig{ CompressionLevel: context.Int("estargz-compression-level"), ChunkSize: context.Int("estargz-chunk-size"), MinChunkSize: context.Int("estargz-min-chunk-size"), }) } } else { if context.Bool("estargz-keep-diff-id") { return fmt.Errorf("option --estargz-keep-diff-id must be used with --estargz-external-toc") } layerConvertFunc = estargzconvert.LayerConvertFunc(esgzOpts...) } if !context.Bool("oci") { logrus.Warn("option --estargz should be used in conjunction with --oci") } if context.Bool("uncompress") { return errors.New("option --estargz conflicts with --uncompress") } if context.Bool("zstdchunked") { return errors.New("option --estargz conflicts with --zstdchunked") } } if context.Bool("zstdchunked") { esgzOpts, err := getZstdchunkedConvertOpts(context) if err != nil { return err } layerConvertFunc = zstdchunkedconvert.LayerConvertFuncWithCompressionLevel( zstd.EncoderLevelFromZstd(context.Int("zstdchunked-compression-level")), esgzOpts...) if !context.Bool("oci") { return errors.New("option --zstdchunked must be used in conjunction with --oci") } if context.Bool("uncompress") { return errors.New("option --zstdchunked conflicts with --uncompress") } } if context.Bool("uncompress") { layerConvertFunc = uncompress.LayerConvertFunc } if layerConvertFunc == nil { return errors.New("specify layer converter") } convertOpts = append(convertOpts, converter.WithLayerConvertFunc(layerConvertFunc)) if context.Bool("oci") { convertOpts = append(convertOpts, converter.WithDockerToOCI(true)) } client, ctx, cancel, err := commands.NewClient(context) if err != nil { return err } defer cancel() ctx, done, err := client.WithLease(ctx) if err != nil { return err } defer done(ctx) sigCh := make(chan os.Signal, 1) signal.Notify(sigCh, os.Interrupt) go func() { // Cleanly cancel conversion select { case s := <-sigCh: logrus.Infof("Got %v", s) cancel() case <-ctx.Done(): } }() newImg, err := converter.Convert(ctx, client, targetRef, srcRef, convertOpts...) if err != nil { return err } if finalize != nil { newI, err := finalize(ctx, client.ContentStore(), targetRef, &newImg.Target) if err != nil { return err } is := client.ImageService() _ = is.Delete(ctx, newI.Name) finimg, err := is.Create(ctx, *newI) if err != nil { return err } fmt.Fprintln(context.App.Writer, "extra image:", finimg.Name) } fmt.Fprintln(context.App.Writer, newImg.Target.Digest.String()) return nil }, } func getESGZConvertOpts(context *cli.Context) ([]estargz.Option, error) { esgzOpts := []estargz.Option{ estargz.WithCompressionLevel(context.Int("estargz-compression-level")), estargz.WithChunkSize(context.Int("estargz-chunk-size")), estargz.WithMinChunkSize(context.Int("estargz-min-chunk-size")), } if estargzRecordIn := context.String("estargz-record-in"); estargzRecordIn != "" { paths, err := readPathsFromRecordFile(estargzRecordIn) if err != nil { return nil, err } esgzOpts = append(esgzOpts, estargz.WithPrioritizedFiles(paths)) var ignored []string esgzOpts = append(esgzOpts, estargz.WithAllowPrioritizeNotFound(&ignored)) } return esgzOpts, nil } func getZstdchunkedConvertOpts(context *cli.Context) ([]estargz.Option, error) { esgzOpts := []estargz.Option{ estargz.WithChunkSize(context.Int("zstdchunked-chunk-size")), } if zstdchunkedRecordIn := context.String("zstdchunked-record-in"); zstdchunkedRecordIn != "" { paths, err := readPathsFromRecordFile(zstdchunkedRecordIn) if err != nil { return nil, err } esgzOpts = append(esgzOpts, estargz.WithPrioritizedFiles(paths)) var ignored []string esgzOpts = append(esgzOpts, estargz.WithAllowPrioritizeNotFound(&ignored)) } return esgzOpts, nil } func readPathsFromRecordFile(filename string) ([]string, error) { r, err := os.Open(filename) if err != nil { return nil, err } defer r.Close() dec := json.NewDecoder(r) var paths []string added := make(map[string]struct{}) for dec.More() { var e recorder.Entry if err := dec.Decode(&e); err != nil { return nil, err } if _, ok := added[e.Path]; !ok { paths = append(paths, e.Path) added[e.Path] = struct{}{} } } return paths, nil } stargz-snapshotter-0.14.3/cmd/ctr-remote/commands/flags.go000066400000000000000000000342601440204344700235400ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package commands import ( "bytes" gocontext "context" "encoding/csv" "encoding/json" "fmt" "os" "path/filepath" "runtime" "strings" "github.com/containerd/containerd" "github.com/containerd/containerd/containers" "github.com/containerd/containerd/content" "github.com/containerd/containerd/contrib/nvidia" "github.com/containerd/containerd/images" "github.com/containerd/containerd/oci" "github.com/containerd/containerd/pkg/netns" gocni "github.com/containerd/go-cni" "github.com/hashicorp/go-multierror" imagespec "github.com/opencontainers/image-spec/specs-go/v1" runtimespec "github.com/opencontainers/runtime-spec/specs-go" "github.com/rs/xid" "github.com/sirupsen/logrus" "github.com/urfave/cli" ) const netnsMountDir = "/var/run/netns" var samplerFlags = []cli.Flag{ cli.BoolFlag{ Name: "terminal,t", Usage: "enable terminal for sample container. must be specified with i option", }, cli.BoolFlag{ Name: "i", Usage: "attach stdin to the container", }, cli.IntFlag{ Name: "period", Usage: "time period to monitor access log", Value: defaultPeriod, }, cli.StringFlag{ Name: "user", Usage: "user/group name to override image's default config(user[:group])", }, cli.StringFlag{ Name: "cwd", Usage: "working dir to override image's default config", }, cli.StringFlag{ Name: "args", Usage: "command arguments to override image's default config(in JSON array)", }, cli.StringFlag{ Name: "entrypoint", Usage: "entrypoint to override image's default config(in JSON array)", }, cli.StringSliceFlag{ Name: "env", Usage: "environment valulable to add or override to the image's default config", }, cli.StringFlag{ Name: "env-file", Usage: "specify additional container environment variables in a file(i.e. FOO=bar, one per line)", }, cli.StringSliceFlag{ Name: "mount", Usage: "additional mounts for the container (e.g. type=foo,source=/path,destination=/target,options=bind)", }, cli.StringFlag{ Name: "dns-nameservers", Usage: "comma-separated nameservers added to the container's /etc/resolv.conf", Value: "8.8.8.8", }, cli.StringFlag{ Name: "dns-search-domains", Usage: "comma-separated search domains added to the container's /etc/resolv.conf", }, cli.StringFlag{ Name: "dns-options", Usage: "comma-separated options added to the container's /etc/resolv.conf", }, cli.StringFlag{ Name: "add-hosts", Usage: "comma-separated hosts configuration (host:IP) added to container's /etc/hosts", }, cli.BoolFlag{ Name: "cni", Usage: "enable CNI-based networking", }, cli.StringFlag{ Name: "cni-plugin-conf-dir", Usage: "path to the CNI plugins configuration directory", }, cli.StringFlag{ Name: "cni-plugin-dir", Usage: "path to the CNI plugins binary directory", }, cli.IntSliceFlag{ Name: "gpus", Usage: "add gpus to the container", }, cli.BoolFlag{ Name: "net-host", Usage: "enable host networking in the container", }, } func getSpecOpts(clicontext *cli.Context) func(image containerd.Image, rootfs string) (opts []oci.SpecOpts, done func() error, rErr error) { return func(image containerd.Image, rootfs string) (opts []oci.SpecOpts, done func() error, rErr error) { var cleanups []func() error done = func() (allErr error) { for i := len(cleanups) - 1; i >= 0; i-- { if err := cleanups[i](); err != nil { allErr = multierror.Append(allErr, err) } } return } defer func() { if rErr != nil { if err := done(); err != nil { rErr = fmt.Errorf("failed to cleanup: %w", rErr) } } }() entrypointOpt, err := withEntrypointArgs(clicontext, image) if err != nil { rErr = fmt.Errorf("failed to parse entrypoint and arg flags: %w", err) return } resolverOpt, cleanup, err := withResolveConfig(clicontext) if err != nil { rErr = fmt.Errorf("failed to parse DNS-related flags: %w", err) return } cleanups = append(cleanups, cleanup) var mounts []runtimespec.Mount for _, mount := range clicontext.StringSlice("mount") { m, err := parseMountFlag(mount) if err != nil { rErr = fmt.Errorf("failed to parse mount flag %q: %w", mount, err) return } mounts = append(mounts, m) } opts = append(opts, oci.WithDefaultSpec(), oci.WithDefaultUnixDevices, oci.WithRootFSPath(rootfs), oci.WithImageConfig(image), oci.WithEnv(clicontext.StringSlice("env")), oci.WithMounts(mounts), resolverOpt, entrypointOpt, ) if envFile := clicontext.String("env-file"); envFile != "" { opts = append(opts, oci.WithEnvFile(envFile)) } if username := clicontext.String("user"); username != "" { opts = append(opts, oci.WithUser(username)) } if cwd := clicontext.String("cwd"); cwd != "" { opts = append(opts, oci.WithProcessCwd(cwd)) } if clicontext.Bool("terminal") { if !clicontext.Bool("i") { rErr = fmt.Errorf("terminal flag must be specified with \"-i\"") return } opts = append(opts, oci.WithTTY) } if clicontext.Bool("cni") { var nOpt oci.SpecOpts nOpt, cleanup, err = withCNI(clicontext) if err != nil { rErr = fmt.Errorf("failed to parse CNI-related flags: %w", err) return } cleanups = append(cleanups, cleanup) opts = append(opts, nOpt) } if clicontext.Bool("net-host") { if runtime.GOOS == "windows" { logrus.Warn("option --net-host is not supported on Windows") } else { opts = append(opts, oci.WithHostNamespace(runtimespec.NetworkNamespace), oci.WithHostHostsFile, oci.WithHostResolvconf) } } if clicontext.IsSet("gpus") { if runtime.GOOS == "windows" { logrus.Warn("option --gpus is not supported on Windows") } else { opts = append(opts, nvidia.WithGPUs(nvidia.WithDevices(clicontext.IntSlice("gpus")...), nvidia.WithAllCapabilities)) } } return } } func withEntrypointArgs(clicontext *cli.Context, image containerd.Image) (oci.SpecOpts, error) { var eFlag []string if eStr := clicontext.String("entrypoint"); eStr != "" { if err := json.Unmarshal([]byte(eStr), &eFlag); err != nil { return nil, fmt.Errorf("invalid option \"entrypoint\": %w", err) } } var aFlag []string if aStr := clicontext.String("args"); aStr != "" { if err := json.Unmarshal([]byte(aStr), &aFlag); err != nil { return nil, fmt.Errorf("invalid option \"args\": %w", err) } } return func(ctx gocontext.Context, client oci.Client, container *containers.Container, s *runtimespec.Spec) error { configDesc, err := image.Config(ctx) if err != nil { return err } var ociimage imagespec.Image switch configDesc.MediaType { case imagespec.MediaTypeImageConfig, images.MediaTypeDockerSchema2Config: p, err := content.ReadBlob(ctx, image.ContentStore(), configDesc) if err != nil { return err } if err := json.Unmarshal(p, &ociimage); err != nil { return err } default: return fmt.Errorf("unknown image config media type %s", configDesc.MediaType) } entrypoint := ociimage.Config.Entrypoint if len(eFlag) > 0 { entrypoint = eFlag } args := ociimage.Config.Cmd if len(aFlag) > 0 { args = aFlag } return oci.WithProcessArgs(append(entrypoint, args...)...)(ctx, client, container, s) }, nil } func withCNI(clicontext *cli.Context) (specOpt oci.SpecOpts, done func() error, rErr error) { var cleanups []func() error done = func() (allErr error) { for i := len(cleanups) - 1; i >= 0; i-- { if err := cleanups[i](); err != nil { allErr = multierror.Append(allErr, err) } } return } defer func() { if rErr != nil { if err := done(); err != nil { rErr = fmt.Errorf("failed to cleanup: %w", rErr) } } }() // Create a new network namespace for configuring it with CNI plugins ns, err := netns.NewNetNS(netnsMountDir) if err != nil { rErr = fmt.Errorf("failed to prepare netns: %w", err) return } cleanups = append(cleanups, ns.Remove) // Configure the namespace with CNI plugins var cniopts []gocni.Opt if cdir := clicontext.String("cni-plugin-conf-dir"); cdir != "" { cniopts = append(cniopts, gocni.WithPluginConfDir(cdir)) } if pdir := clicontext.String("cni-plugin-dir"); pdir != "" { cniopts = append(cniopts, gocni.WithPluginDir([]string{pdir})) } // The first-found configration file will be effective // TODO: Should we make the number of reading files configurable? cniopts = append(cniopts, gocni.WithDefaultConf) network, err := gocni.New(cniopts...) if err != nil { rErr = fmt.Errorf("failed to prepare CNI plugins: %w", err) return } id := xid.New().String() ctx := gocontext.Background() if _, err := network.Setup(ctx, id, ns.GetPath()); err != nil { rErr = fmt.Errorf("failed to setup netns with CNI plugins: %w", err) return } cleanups = append(cleanups, func() error { return network.Remove(ctx, id, ns.GetPath()) }) // Make the container use this network namespace return oci.WithLinuxNamespace(runtimespec.LinuxNamespace{ Type: runtimespec.NetworkNamespace, Path: ns.GetPath(), }), done, nil } func withResolveConfig(clicontext *cli.Context) (specOpt oci.SpecOpts, cleanup func() error, rErr error) { defer func() { if rErr != nil { if err := cleanup(); err != nil { rErr = fmt.Errorf("failed to cleanup: %w", rErr) } } }() extrahosts, nameservers, searches, dnsopts, err := parseResolveFlag(clicontext) if err != nil { return nil, nil, err } // Generate /etc/hosts and /etc/resolv.conf resolvDir, err := os.MkdirTemp("", "tmpetc") if err != nil { return nil, nil, err } cleanup = func() error { return os.RemoveAll(resolvDir) } var ( etcHostsPath = filepath.Join(resolvDir, "hosts") etcResolvConfPath = filepath.Join(resolvDir, "resolv.conf") buf = new(bytes.Buffer) ) for _, n := range nameservers { if _, err := fmt.Fprintf(buf, "nameserver %s\n", n); err != nil { rErr = fmt.Errorf("failed to prepare nameserver of /etc/resolv.conf: %w", err) return } } if len(searches) > 0 { _, err := fmt.Fprintf(buf, "search %s\n", strings.Join(searches, " ")) if err != nil { rErr = fmt.Errorf("failed to prepare search contents of /etc/resolv.conf: %w", err) return } } if len(dnsopts) > 0 { _, err := fmt.Fprintf(buf, "options %s\n", strings.Join(dnsopts, " ")) if err != nil { rErr = fmt.Errorf("failed to prepare options contents of /etc/resolv.conf: %w", err) return } } if err := os.WriteFile(etcResolvConfPath, buf.Bytes(), 0644); err != nil { rErr = fmt.Errorf("failed to write contents to /etc/resolv.conf: %w", err) return } buf.Reset() // Reusing for /etc/hosts for _, h := range []struct { host string ip string }{ // Configuration compatible to docker's config // https://github.com/moby/libnetwork/blob/535ef365dc1dd82a5135803a58bc6198a3b9aa27/etchosts/etchosts.go#L28-L36 {"localhost", "127.0.0.1"}, {"localhost ip6-localhost ip6-loopback", "::1"}, {"ip6-localnet", "fe00::0"}, {"ip6-mcastprefix", "ff00::0"}, {"ip6-allnodes", "ff02::1"}, {"ip6-allrouters", "ff02::2"}, } { if _, err := fmt.Fprintf(buf, "%s\t%s\n", h.ip, h.host); err != nil { rErr = fmt.Errorf("failed to write default hosts to /etc/hosts: %w", err) return } } for _, h := range extrahosts { parts := strings.SplitN(h, ":", 2) // host:IP if len(parts) != 2 { rErr = fmt.Errorf("cannot parse %q as extra host; must be \"host:IP\"", h) return } // TODO: Validate them if _, err := fmt.Fprintf(buf, "%s\t%s\n", parts[1], parts[0]); err != nil { rErr = fmt.Errorf("failed to write extra hosts to /etc/hosts: %w", err) return } } if err := os.WriteFile(etcHostsPath, buf.Bytes(), 0644); err != nil { rErr = fmt.Errorf("failed to write contents to /etc/hosts: %w", err) return } return oci.WithMounts([]runtimespec.Mount{ { Destination: "/etc/resolv.conf", Source: etcResolvConfPath, Options: []string{"bind"}, }, { Destination: "/etc/hosts", Source: etcHostsPath, Options: []string{"bind"}, }, }), cleanup, nil } // parseMountFlag parses a mount string in the form "type=foo,source=/path,destination=/target,options=rbind:rw" func parseMountFlag(m string) (runtimespec.Mount, error) { mount := runtimespec.Mount{} r := csv.NewReader(strings.NewReader(m)) fields, err := r.Read() if err != nil { return mount, err } for _, field := range fields { v := strings.Split(field, "=") if len(v) != 2 { return mount, fmt.Errorf("invalid mount specification: expected key=val") } key := v[0] val := v[1] switch key { case "type": mount.Type = val case "source", "src": mount.Source = val case "destination", "dst": mount.Destination = val case "options": mount.Options = strings.Split(val, ":") default: return mount, fmt.Errorf("mount option %q not supported", key) } } return mount, nil } func parseResolveFlag(clicontext *cli.Context) (hosts []string, nameservers []string, searches []string, dnsopts []string, _ error) { if nFlag := clicontext.String("dns-nameservers"); nFlag != "" { fields, err := csv.NewReader(strings.NewReader(nFlag)).Read() if err != nil { return nil, nil, nil, nil, err } nameservers = append(nameservers, fields...) } if sFlag := clicontext.String("dns-search-domains"); sFlag != "" { fields, err := csv.NewReader(strings.NewReader(sFlag)).Read() if err != nil { return nil, nil, nil, nil, err } searches = append(searches, fields...) } if oFlag := clicontext.String("dns-options"); oFlag != "" { fields, err := csv.NewReader(strings.NewReader(oFlag)).Read() if err != nil { return nil, nil, nil, nil, err } dnsopts = append(dnsopts, fields...) } if hFlag := clicontext.String("add-hosts"); hFlag != "" { fields, err := csv.NewReader(strings.NewReader(hFlag)).Read() if err != nil { return nil, nil, nil, nil, err } hosts = append(hosts, fields...) } return } stargz-snapshotter-0.14.3/cmd/ctr-remote/commands/get-toc-digest.go000066400000000000000000000061361440204344700252640ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package commands import ( "encoding/json" "errors" "fmt" "io" "github.com/containerd/containerd/cmd/ctr/commands" "github.com/containerd/stargz-snapshotter/estargz" "github.com/containerd/stargz-snapshotter/estargz/zstdchunked" digest "github.com/opencontainers/go-digest" ocispec "github.com/opencontainers/image-spec/specs-go/v1" "github.com/urfave/cli" ) // GetTOCDigestCommand outputs TOC info of a layer var GetTOCDigestCommand = cli.Command{ Name: "get-toc-digest", Usage: "get the digest of TOC of a layer", ArgsUsage: "", Flags: []cli.Flag{ // zstd:chunked flags cli.BoolFlag{ Name: "zstdchunked", Usage: "parse layer as zstd:chunked", }, // other flags for debugging cli.BoolFlag{ Name: "dump-toc", Usage: "dump TOC instead of digest. Note that the dumped TOC might be formatted with indents so may have different digest against the original in the layer", }, }, Action: func(clicontext *cli.Context) error { layerDgstStr := clicontext.Args().Get(0) if layerDgstStr == "" { return errors.New("layer digest need to be specified") } client, ctx, cancel, err := commands.NewClient(clicontext) if err != nil { return err } defer cancel() layerDgst, err := digest.Parse(layerDgstStr) if err != nil { return err } ra, err := client.ContentStore().ReaderAt(ctx, ocispec.Descriptor{Digest: layerDgst}) if err != nil { return err } defer ra.Close() footerSize := estargz.FooterSize if clicontext.Bool("zstdchunked") { footerSize = zstdchunked.FooterSize } footer := make([]byte, footerSize) if _, err := ra.ReadAt(footer, ra.Size()-int64(footerSize)); err != nil { return fmt.Errorf("error reading footer: %w", err) } var decompressor estargz.Decompressor decompressor = new(estargz.GzipDecompressor) if clicontext.Bool("zstdchunked") { decompressor = new(zstdchunked.Decompressor) } _, tocOff, tocSize, err := decompressor.ParseFooter(footer) if err != nil { return fmt.Errorf("error parsing footer: %w", err) } if tocSize <= 0 { tocSize = ra.Size() - tocOff - int64(footerSize) } toc, tocDgst, err := decompressor.ParseTOC(io.NewSectionReader(ra, tocOff, tocSize)) if err != nil { return fmt.Errorf("error parsing TOC: %w", err) } if clicontext.Bool("dump-toc") { tocJSON, err := json.MarshalIndent(toc, "", "\t") if err != nil { return fmt.Errorf("failed to marshal toc: %w", err) } fmt.Println(string(tocJSON)) return nil } fmt.Println(tocDgst.String()) return nil }, } stargz-snapshotter-0.14.3/cmd/ctr-remote/commands/ipfs-push.go000066400000000000000000000051541440204344700243620ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package commands import ( "errors" "fmt" "github.com/containerd/containerd/cmd/ctr/commands" "github.com/containerd/containerd/images/converter" "github.com/containerd/containerd/platforms" "github.com/containerd/stargz-snapshotter/ipfs" estargzconvert "github.com/containerd/stargz-snapshotter/nativeconverter/estargz" ocispec "github.com/opencontainers/image-spec/specs-go/v1" "github.com/sirupsen/logrus" "github.com/urfave/cli" ) // IPFSPushCommand pushes an image to IPFS var IPFSPushCommand = cli.Command{ Name: "ipfs-push", Usage: "push an image to IPFS (experimental)", ArgsUsage: "[flags] ", Flags: []cli.Flag{ // platform flags cli.StringSliceFlag{ Name: "platform", Usage: "Add content for a specific platform", Value: &cli.StringSlice{}, }, cli.BoolFlag{ Name: "all-platforms", Usage: "Add content for all platforms", }, cli.BoolTFlag{ Name: "estargz", Usage: "Convert the image into eStargz", }, }, Action: func(context *cli.Context) error { srcRef := context.Args().Get(0) if srcRef == "" { return errors.New("image need to be specified") } var platformMC platforms.MatchComparer if context.Bool("all-platforms") { platformMC = platforms.All } else { if pss := context.StringSlice("platform"); len(pss) > 0 { var all []ocispec.Platform for _, ps := range pss { p, err := platforms.Parse(ps) if err != nil { return fmt.Errorf("invalid platform %q: %w", ps, err) } all = append(all, p) } platformMC = platforms.Ordered(all...) } else { platformMC = platforms.DefaultStrict() } } client, ctx, cancel, err := commands.NewClient(context) if err != nil { return err } defer cancel() var layerConvert converter.ConvertFunc if context.Bool("estargz") { layerConvert = estargzconvert.LayerConvertFunc() } p, err := ipfs.Push(ctx, client, srcRef, layerConvert, platformMC) if err != nil { return err } logrus.WithField("CID", p).Infof("Pushed") fmt.Println(p) return nil }, } stargz-snapshotter-0.14.3/cmd/ctr-remote/commands/notify.go000066400000000000000000000021031440204344700237430ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package commands import ( "fmt" "os" "github.com/containerd/stargz-snapshotter/analyzer/fanotify/service" "github.com/urfave/cli" ) // FanotifyCommand notifies filesystem event under the specified directory. var FanotifyCommand = cli.Command{ Name: "fanotify", Hidden: true, Action: func(context *cli.Context) error { target := context.Args().Get(0) if target == "" { return fmt.Errorf("target must be specified") } return service.Serve(target, os.Stdin, os.Stdout) }, } stargz-snapshotter-0.14.3/cmd/ctr-remote/commands/optimize.go000066400000000000000000000327351440204344700243110ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package commands import ( "compress/gzip" "context" "encoding/json" "errors" "fmt" "io" "os" "os/signal" "time" "github.com/containerd/containerd" "github.com/containerd/containerd/cmd/ctr/commands" "github.com/containerd/containerd/content" "github.com/containerd/containerd/images" "github.com/containerd/containerd/images/converter" "github.com/containerd/containerd/platforms" "github.com/containerd/stargz-snapshotter/analyzer" "github.com/containerd/stargz-snapshotter/estargz" "github.com/containerd/stargz-snapshotter/estargz/zstdchunked" estargzconvert "github.com/containerd/stargz-snapshotter/nativeconverter/estargz" esgzexternaltocconvert "github.com/containerd/stargz-snapshotter/nativeconverter/estargz/externaltoc" zstdchunkedconvert "github.com/containerd/stargz-snapshotter/nativeconverter/zstdchunked" "github.com/containerd/stargz-snapshotter/recorder" "github.com/containerd/stargz-snapshotter/util/containerdutil" "github.com/klauspost/compress/zstd" "github.com/opencontainers/go-digest" ocispec "github.com/opencontainers/image-spec/specs-go/v1" "github.com/sirupsen/logrus" "github.com/urfave/cli" ) const defaultPeriod = 10 // OptimizeCommand converts and optimizes an image var OptimizeCommand = cli.Command{ Name: "optimize", Usage: "optimize an image with user-specified workload", ArgsUsage: "[flags] ...", Flags: append([]cli.Flag{ cli.BoolFlag{ Name: "reuse", Usage: "reuse eStargz (already optimized) layers without further conversion", }, cli.StringSliceFlag{ Name: "platform", Usage: "Pull content from a specific platform", Value: &cli.StringSlice{}, }, cli.BoolFlag{ Name: "all-platforms", Usage: "targeting all platform of the source image", }, cli.BoolFlag{ Name: "wait-on-signal", Usage: "ignore context cancel and keep the container running until it receives SIGINT (Ctrl + C) sent manually", }, cli.StringFlag{ Name: "wait-on-line", Usage: "Substring of a stdout line to be waited. When this string is detected, the container will be killed.", }, cli.BoolFlag{ Name: "no-optimize", Usage: "convert image without optimization", }, cli.StringFlag{ Name: "record-out", Usage: "record the monitor log to the specified file", }, cli.BoolFlag{ Name: "oci", Usage: "convert Docker media types to OCI media types", }, cli.IntFlag{ Name: "estargz-compression-level", Usage: "eStargz compression level", Value: gzip.BestCompression, }, cli.BoolFlag{ Name: "estargz-external-toc", Usage: "Separate TOC JSON into another image (called \"TOC image\"). The name of TOC image is the original + \"-esgztoc\" suffix. Both eStargz and the TOC image should be pushed to the same registry. stargz-snapshotter refers to the TOC image when it pulls the result eStargz image.", }, cli.IntFlag{ Name: "estargz-chunk-size", Usage: "eStargz chunk size (not applied to zstd:chunked)", Value: 0, }, cli.IntFlag{ Name: "estargz-min-chunk-size", Usage: "The minimal number of bytes of data must be written in one gzip stream. Note that this adds a TOC property that old reader doesn't understand (not applied to zstd:chunked)", Value: 0, }, cli.BoolFlag{ Name: "zstdchunked", Usage: "use zstd compression instead of gzip (a.k.a zstd:chunked)", }, cli.IntFlag{ Name: "zstdchunked-compression-level", Usage: "zstd:chunked compression level", Value: 3, // SpeedDefault; see also https://pkg.go.dev/github.com/klauspost/compress/zstd#EncoderLevel }, }, samplerFlags...), Action: func(clicontext *cli.Context) error { convertOpts := []converter.Opt{} srcRef := clicontext.Args().Get(0) targetRef := clicontext.Args().Get(1) if srcRef == "" || targetRef == "" { return errors.New("src and target image need to be specified") } var platformMC platforms.MatchComparer if clicontext.Bool("all-platforms") { platformMC = platforms.All } else { if pss := clicontext.StringSlice("platform"); len(pss) > 0 { var all []ocispec.Platform for _, ps := range pss { p, err := platforms.Parse(ps) if err != nil { return fmt.Errorf("invalid platform %q: %w", ps, err) } all = append(all, p) } platformMC = platforms.Ordered(all...) } else { platformMC = platforms.DefaultStrict() } } convertOpts = append(convertOpts, converter.WithPlatform(platformMC)) if clicontext.Bool("oci") { convertOpts = append(convertOpts, converter.WithDockerToOCI(true)) } else if clicontext.Bool("zstdchunked") { return errors.New("option --zstdchunked must be used in conjunction with --oci") } client, ctx, cancel, err := commands.NewClient(clicontext) if err != nil { return err } defer cancel() ctx, done, err := client.WithLease(ctx) if err != nil { return err } defer done(ctx) recordOut, esgzOptsPerLayer, wrapper, err := analyze(ctx, clicontext, client, srcRef) if err != nil { return err } if recordOutFile := clicontext.String("record-out"); recordOutFile != "" { if err := writeContentFile(ctx, client, recordOut, recordOutFile); err != nil { return fmt.Errorf("failed output record file: %w", err) } } var f converter.ConvertFunc var finalize func(ctx context.Context, cs content.Store, ref string, desc *ocispec.Descriptor) (*images.Image, error) if clicontext.Bool("zstdchunked") { f = zstdchunkedconvert.LayerConvertWithLayerOptsFuncWithCompressionLevel( zstd.EncoderLevelFromZstd(clicontext.Int("zstdchunked-compression-level")), esgzOptsPerLayer) } else if !clicontext.Bool("estargz-external-toc") { f = estargzconvert.LayerConvertWithLayerAndCommonOptsFunc(esgzOptsPerLayer, estargz.WithCompressionLevel(clicontext.Int("estargz-compression-level")), estargz.WithChunkSize(clicontext.Int("estargz-chunk-size")), estargz.WithMinChunkSize(clicontext.Int("estargz-min-chunk-size"))) } else { if clicontext.Bool("reuse") { // We require that the layer conversion is triggerd for each layer // to make sure that "finalize" function has the information of all layers. return fmt.Errorf("\"estargz-external-toc\" can't be used with \"reuse\" flag") } f, finalize = esgzexternaltocconvert.LayerConvertWithLayerAndCommonOptsFunc(esgzOptsPerLayer, []estargz.Option{ estargz.WithChunkSize(clicontext.Int("estargz-chunk-size")), estargz.WithMinChunkSize(clicontext.Int("estargz-min-chunk-size")), }, clicontext.Int("estargz-compression-level")) } if wrapper != nil { f = wrapper(f) } layerConvertFunc := logWrapper(f) sigCh := make(chan os.Signal, 1) signal.Notify(sigCh, os.Interrupt) go func() { // Cleanly cancel conversion select { case s := <-sigCh: logrus.Infof("Got %v", s) cancel() case <-ctx.Done(): } }() convertOpts = append(convertOpts, converter.WithLayerConvertFunc(layerConvertFunc)) newImg, err := converter.Convert(ctx, client, targetRef, srcRef, convertOpts...) if err != nil { return err } if finalize != nil { newI, err := finalize(ctx, client.ContentStore(), targetRef, &newImg.Target) if err != nil { return err } is := client.ImageService() _ = is.Delete(ctx, newI.Name) finimg, err := is.Create(ctx, *newI) if err != nil { return err } fmt.Fprintln(clicontext.App.Writer, "extra image:", finimg.Name) } fmt.Fprintln(clicontext.App.Writer, newImg.Target.Digest.String()) return nil }, } func writeContentFile(ctx context.Context, client *containerd.Client, dgst digest.Digest, targetFile string) error { fw, err := os.Create(targetFile) if err != nil { return err } defer fw.Close() ra, err := client.ContentStore().ReaderAt(ctx, ocispec.Descriptor{Digest: dgst}) if err != nil { return err } defer ra.Close() _, err = io.Copy(fw, io.NewSectionReader(ra, 0, ra.Size())) return err } func analyze(ctx context.Context, clicontext *cli.Context, client *containerd.Client, srcRef string) (digest.Digest, map[digest.Digest][]estargz.Option, func(converter.ConvertFunc) converter.ConvertFunc, error) { if clicontext.Bool("no-optimize") { return "", nil, nil, nil } // Do analysis only when the target platforms contain the current platform if !clicontext.Bool("all-platforms") { if pss := clicontext.StringSlice("platform"); len(pss) > 0 { containsDefault := false for _, ps := range pss { p, err := platforms.Parse(ps) if err != nil { return "", nil, nil, fmt.Errorf("invalid platform %q: %w", ps, err) } if platforms.DefaultStrict().Match(p) { containsDefault = true } } if !containsDefault { return "", nil, nil, nil // do not run analyzer } } } cs := client.ContentStore() is := client.ImageService() // Analyze layers and get prioritized files aOpts := []analyzer.Option{analyzer.WithSpecOpts(getSpecOpts(clicontext))} if clicontext.Bool("wait-on-signal") && clicontext.Bool("terminal") { return "", nil, nil, fmt.Errorf("wait-on-signal can't be used with terminal flag") } if clicontext.Bool("wait-on-signal") { aOpts = append(aOpts, analyzer.WithWaitOnSignal()) } else { aOpts = append(aOpts, analyzer.WithPeriod(time.Duration(clicontext.Int("period"))*time.Second), analyzer.WithWaitLineOut(clicontext.String("wait-on-line"))) } if clicontext.Bool("terminal") { if !clicontext.Bool("i") { return "", nil, nil, fmt.Errorf("terminal flag must be specified with \"-i\"") } aOpts = append(aOpts, analyzer.WithTerminal()) } if clicontext.Bool("i") { aOpts = append(aOpts, analyzer.WithStdin()) } recordOut, err := analyzer.Analyze(ctx, client, srcRef, aOpts...) if err != nil { return "", nil, nil, err } // Parse record file srcImg, err := is.Get(ctx, srcRef) if err != nil { return "", nil, nil, err } manifestDesc, err := containerdutil.ManifestDesc(ctx, cs, srcImg.Target, platforms.DefaultStrict()) if err != nil { return "", nil, nil, err } p, err := content.ReadBlob(ctx, cs, manifestDesc) if err != nil { return "", nil, nil, err } var manifest ocispec.Manifest if err := json.Unmarshal(p, &manifest); err != nil { return "", nil, nil, err } // TODO: this should be indexed by layer "index" (not "digest") layerLogs := make(map[digest.Digest][]string, len(manifest.Layers)) ra, err := cs.ReaderAt(ctx, ocispec.Descriptor{Digest: recordOut}) if err != nil { return "", nil, nil, err } defer ra.Close() dec := json.NewDecoder(io.NewSectionReader(ra, 0, ra.Size())) added := make(map[digest.Digest]map[string]struct{}, len(manifest.Layers)) for dec.More() { var e recorder.Entry if err := dec.Decode(&e); err != nil { return "", nil, nil, err } if *e.LayerIndex < len(manifest.Layers) && e.ManifestDigest == manifestDesc.Digest.String() { dgst := manifest.Layers[*e.LayerIndex].Digest if added[dgst] == nil { added[dgst] = map[string]struct{}{} } if _, ok := added[dgst][e.Path]; !ok { added[dgst][e.Path] = struct{}{} layerLogs[dgst] = append(layerLogs[dgst], e.Path) } } } // Create a converter wrapper for skipping layer conversion. This skip occurs // if "reuse" option is specified, the source layer is already valid estargz // and no access occur to that layer. var excludes []digest.Digest layerOpts := make(map[digest.Digest][]estargz.Option, len(manifest.Layers)) for _, desc := range manifest.Layers { if layerLog, ok := layerLogs[desc.Digest]; ok && len(layerLog) > 0 { layerOpts[desc.Digest] = []estargz.Option{estargz.WithPrioritizedFiles(layerLog)} } else if clicontext.Bool("reuse") && isReusableESGZLayer(ctx, desc, cs) { excludes = append(excludes, desc.Digest) // reuse layer without conversion } } return recordOut, layerOpts, excludeWrapper(excludes), nil } func isReusableESGZLayer(ctx context.Context, desc ocispec.Descriptor, cs content.Store) bool { dgstStr, ok := desc.Annotations[estargz.TOCJSONDigestAnnotation] if !ok { return false } tocdgst, err := digest.Parse(dgstStr) if err != nil { return false } ra, err := cs.ReaderAt(ctx, desc) if err != nil { return false } defer ra.Close() r, err := estargz.Open(io.NewSectionReader(ra, 0, desc.Size), estargz.WithDecompressors(new(zstdchunked.Decompressor))) if err != nil { return false } if _, err := r.VerifyTOC(tocdgst); err != nil { return false } return true } func excludeWrapper(excludes []digest.Digest) func(converter.ConvertFunc) converter.ConvertFunc { return func(convertFunc converter.ConvertFunc) converter.ConvertFunc { return func(ctx context.Context, cs content.Store, desc ocispec.Descriptor) (*ocispec.Descriptor, error) { for _, e := range excludes { if e == desc.Digest { logrus.Warnf("reusing %q without conversion", e) return nil, nil } } return convertFunc(ctx, cs, desc) } } } func logWrapper(convertFunc converter.ConvertFunc) converter.ConvertFunc { return func(ctx context.Context, cs content.Store, desc ocispec.Descriptor) (*ocispec.Descriptor, error) { logrus.WithField("digest", desc.Digest).Infof("converting...") return convertFunc(ctx, cs, desc) } } stargz-snapshotter-0.14.3/cmd/ctr-remote/commands/rpull.go000066400000000000000000000113501440204344700235750ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package commands import ( "context" "fmt" "github.com/containerd/containerd" "github.com/containerd/containerd/cmd/ctr/commands" "github.com/containerd/containerd/cmd/ctr/commands/content" "github.com/containerd/containerd/images" "github.com/containerd/containerd/log" ctdsnapshotters "github.com/containerd/containerd/pkg/snapshotters" "github.com/containerd/containerd/snapshots" fsconfig "github.com/containerd/stargz-snapshotter/fs/config" "github.com/containerd/stargz-snapshotter/fs/source" "github.com/containerd/stargz-snapshotter/ipfs" ocispec "github.com/opencontainers/image-spec/specs-go/v1" "github.com/urfave/cli" ) const ( remoteSnapshotterName = "stargz" skipContentVerifyOpt = "skip-content-verify" ) // RpullCommand is a subcommand to pull an image from a registry levaraging stargz snapshotter var RpullCommand = cli.Command{ Name: "rpull", Usage: "pull an image from a registry levaraging stargz snapshotter", ArgsUsage: "[flags] ", Description: `Fetch and prepare an image for use in containerd levaraging stargz snapshotter. After pulling an image, it should be ready to use the same reference in a run command. `, Flags: append(append(commands.RegistryFlags, commands.LabelFlag, cli.BoolFlag{ Name: skipContentVerifyOpt, Usage: "Skip content verification for layers contained in this image.", }, cli.BoolFlag{ Name: "ipfs", Usage: "Pull image from IPFS. Specify an IPFS CID as a reference. (experimental)", }, cli.BoolFlag{ Name: "use-containerd-labels", Usage: "Use labels defined in containerd project", }, ), commands.SnapshotterFlags...), Action: func(context *cli.Context) error { var ( ref = context.Args().First() config = &rPullConfig{} ) if ref == "" { return fmt.Errorf("please provide an image reference to pull") } client, ctx, cancel, err := commands.NewClient(context) if err != nil { return err } defer cancel() ctx, done, err := client.WithLease(ctx) if err != nil { return err } defer done(ctx) fc, err := content.NewFetchConfig(ctx, context) if err != nil { return err } config.FetchConfig = fc config.containerdLabels = context.Bool("use-containerd-labels") if context.Bool(skipContentVerifyOpt) { config.skipVerify = true } if context.Bool("ipfs") { r, err := ipfs.NewResolver(ipfs.ResolverOptions{ Scheme: "ipfs", }) if err != nil { return err } config.Resolver = r } config.snapshotter = remoteSnapshotterName if sn := context.String("snapshotter"); sn != "" { config.snapshotter = sn } return pull(ctx, client, ref, config) }, } type rPullConfig struct { *content.FetchConfig skipVerify bool snapshotter string containerdLabels bool } func pull(ctx context.Context, client *containerd.Client, ref string, config *rPullConfig) error { pCtx := ctx h := images.HandlerFunc(func(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) { if desc.MediaType != images.MediaTypeDockerSchema1Manifest { fmt.Printf("fetching %v... %v\n", desc.Digest.String()[:15], desc.MediaType) } return nil, nil }) var snOpts []snapshots.Opt if config.skipVerify { log.G(pCtx).WithField("image", ref).Warn("content verification disabled") snOpts = append(snOpts, snapshots.WithLabels(map[string]string{ fsconfig.TargetSkipVerifyLabel: "true", })) } var labelHandler func(h images.Handler) images.Handler prefetchSize := int64(10*1024*1024) if config.containerdLabels { labelHandler = source.AppendExtraLabelsHandler(prefetchSize, ctdsnapshotters.AppendInfoHandlerWrapper(ref)) } else { labelHandler = source.AppendDefaultLabelsHandlerWrapper(ref, prefetchSize) } log.G(pCtx).WithField("image", ref).Debug("fetching") labels := commands.LabelArgs(config.Labels) if _, err := client.Pull(pCtx, ref, []containerd.RemoteOpt{ containerd.WithPullLabels(labels), containerd.WithResolver(config.Resolver), containerd.WithImageHandler(h), containerd.WithSchema1Conversion, containerd.WithPullUnpack, containerd.WithPullSnapshotter(config.snapshotter, snOpts...), containerd.WithImageHandlerWrapper(labelHandler), }...); err != nil { return err } return nil } stargz-snapshotter-0.14.3/cmd/ctr-remote/main.go000066400000000000000000000035131440204344700215640ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package main import ( "fmt" "os" "github.com/containerd/containerd/cmd/ctr/app" "github.com/containerd/containerd/pkg/seed" "github.com/containerd/stargz-snapshotter/cmd/ctr-remote/commands" "github.com/urfave/cli" ) func init() { seed.WithTimeAndRand() } func main() { customCommands := []cli.Command{ commands.RpullCommand, commands.OptimizeCommand, commands.ConvertCommand, commands.GetTOCDigestCommand, commands.IPFSPushCommand, } app := app.New() for i := range app.Commands { if app.Commands[i].Name == "images" { sc := map[string]cli.Command{} for _, subcmd := range customCommands { sc[subcmd.Name] = subcmd } // First, replace duplicated subcommands for j := range app.Commands[i].Subcommands { for name, subcmd := range sc { if name == app.Commands[i].Subcommands[j].Name { app.Commands[i].Subcommands[j] = subcmd delete(sc, name) } } } // Next, append all new sub commands for _, subcmd := range sc { app.Commands[i].Subcommands = append(app.Commands[i].Subcommands, subcmd) } break } } app.Commands = append(app.Commands, commands.FanotifyCommand) if err := app.Run(os.Args); err != nil { fmt.Fprintf(os.Stderr, "ctr-remote: %v\n", err) os.Exit(1) } } stargz-snapshotter-0.14.3/cmd/go.mod000066400000000000000000000150311440204344700173340ustar00rootroot00000000000000module github.com/containerd/stargz-snapshotter/cmd go 1.19 require ( github.com/containerd/containerd v1.7.0-rc.2 github.com/containerd/go-cni v1.1.9 github.com/containerd/stargz-snapshotter v0.14.3 github.com/containerd/stargz-snapshotter/estargz v0.14.3 github.com/containerd/stargz-snapshotter/ipfs v0.14.3 github.com/coreos/go-systemd/v22 v22.5.0 github.com/docker/go-metrics v0.0.1 github.com/goccy/go-json v0.10.0 github.com/hashicorp/go-multierror v1.1.1 github.com/klauspost/compress v1.16.0 github.com/opencontainers/go-digest v1.0.0 github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b github.com/opencontainers/runtime-spec v1.1.0-rc.1 github.com/pelletier/go-toml v1.9.5 github.com/rs/xid v1.4.0 github.com/sirupsen/logrus v1.9.0 github.com/urfave/cli v1.22.12 go.etcd.io/bbolt v1.3.7 golang.org/x/sync v0.1.0 golang.org/x/sys v0.6.0 google.golang.org/grpc v1.53.0 k8s.io/cri-api v0.27.0-alpha.3 ) require ( github.com/AdaLogics/go-fuzz-headers v0.0.0-20230106234847-43070de90fa1 // indirect github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20221215162035-5330a85ea652 // indirect github.com/Microsoft/go-winio v0.6.0 // indirect github.com/Microsoft/hcsshim v0.10.0-rc.7 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/cilium/ebpf v0.9.1 // indirect github.com/containerd/cgroups v1.1.0 // indirect github.com/containerd/cgroups/v3 v3.0.1 // indirect github.com/containerd/console v1.0.3 // indirect github.com/containerd/continuity v0.3.0 // indirect github.com/containerd/fifo v1.1.0 // indirect github.com/containerd/go-runc v1.0.0 // indirect github.com/containerd/ttrpc v1.2.0 // indirect github.com/containerd/typeurl/v2 v2.1.0 // indirect github.com/containernetworking/cni v1.1.2 // indirect github.com/containernetworking/plugins v1.2.0 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect github.com/cyphar/filepath-securejoin v0.2.3 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/docker/cli v23.0.1+incompatible // indirect github.com/docker/docker v20.10.20+incompatible // indirect github.com/docker/docker-credential-helpers v0.7.0 // indirect github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c // indirect github.com/docker/go-units v0.5.0 // indirect github.com/emicklei/go-restful/v3 v3.10.1 // indirect github.com/go-logr/logr v1.2.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-openapi/jsonpointer v0.19.5 // indirect github.com/go-openapi/jsonreference v0.20.0 // indirect github.com/go-openapi/swag v0.19.14 // indirect github.com/godbus/dbus/v5 v5.1.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.2 // indirect github.com/google/gnostic v0.5.7-v3refs // indirect github.com/google/go-cmp v0.5.9 // indirect github.com/google/gofuzz v1.2.0 // indirect github.com/google/uuid v1.3.0 // indirect github.com/hanwen/go-fuse/v2 v2.2.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-retryablehttp v0.7.2 // indirect github.com/imdario/mergo v0.3.13 // indirect github.com/intel/goresctrl v0.3.0 // indirect github.com/ipfs/go-cid v0.1.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/cpuid/v2 v2.0.9 // indirect github.com/mailru/easyjson v0.7.6 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 // indirect github.com/minio/sha256-simd v1.0.0 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/moby/locker v1.0.1 // indirect github.com/moby/sys/mountinfo v0.6.2 // indirect github.com/moby/sys/sequential v0.5.0 // indirect github.com/moby/sys/signal v0.7.0 // indirect github.com/moby/sys/symlink v0.2.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/mr-tron/base58 v1.2.0 // indirect github.com/multiformats/go-base32 v0.0.3 // indirect github.com/multiformats/go-base36 v0.1.0 // indirect github.com/multiformats/go-multiaddr v0.8.0 // indirect github.com/multiformats/go-multibase v0.0.3 // indirect github.com/multiformats/go-multihash v0.1.0 // indirect github.com/multiformats/go-varint v0.0.6 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/opencontainers/runc v1.1.4 // indirect github.com/opencontainers/selinux v1.11.0 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/prometheus/client_golang v1.14.0 // indirect github.com/prometheus/client_model v0.3.0 // indirect github.com/prometheus/common v0.37.0 // indirect github.com/prometheus/procfs v0.8.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/vbatts/tar-split v0.11.2 // indirect go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/otel v1.12.0 // indirect go.opentelemetry.io/otel/trace v1.12.0 // indirect golang.org/x/crypto v0.1.0 // indirect golang.org/x/mod v0.7.0 // indirect golang.org/x/net v0.7.0 // indirect golang.org/x/oauth2 v0.4.0 // indirect golang.org/x/term v0.5.0 // indirect golang.org/x/text v0.7.0 // indirect golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 // indirect golang.org/x/tools v0.5.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // indirect google.golang.org/protobuf v1.28.1 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/api v0.26.2 // indirect k8s.io/apimachinery v0.26.2 // indirect k8s.io/client-go v0.26.2 // indirect k8s.io/klog/v2 v2.90.1 // indirect k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 // indirect k8s.io/utils v0.0.0-20230220204549-a5ecb0141aa5 // indirect lukechampine.com/blake3 v1.1.6 // indirect sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect sigs.k8s.io/yaml v1.3.0 // indirect ) replace ( // Import local packages. github.com/containerd/stargz-snapshotter => ../ github.com/containerd/stargz-snapshotter/estargz => ../estargz github.com/containerd/stargz-snapshotter/ipfs => ../ipfs ) stargz-snapshotter-0.14.3/cmd/go.sum000066400000000000000000002363201440204344700173670ustar00rootroot00000000000000cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/AdaLogics/go-fuzz-headers v0.0.0-20230106234847-43070de90fa1 h1:EKPd1INOIyr5hWOWhvpmQpY6tKjeG0hT1s3AMC/9fic= github.com/AdaLogics/go-fuzz-headers v0.0.0-20230106234847-43070de90fa1/go.mod h1:VzwV+t+dZ9j/H867F1M2ziD+yLHtB46oM35FxxMJ4d0= github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20221215162035-5330a85ea652 h1:+vTEFqeoeur6XSq06bs+roX3YiT49gUniJK7Zky7Xjg= github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20221215162035-5330a85ea652/go.mod h1:OahwfttHWG6eJ0clwcfBAHoDI6X/LV/15hx/wlMZSrU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg= github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE= github.com/Microsoft/hcsshim v0.10.0-rc.7 h1:HBytQPxcv8Oy4244zbQbe6hnOnx544eL5QPUqhJldz8= github.com/Microsoft/hcsshim v0.10.0-rc.7/go.mod h1:ILuwjA+kNW+MrN/w5un7n3mTqkwsFu4Bp05/okFUZlE= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/cilium/ebpf v0.7.0/go.mod h1:/oI2+1shJiTGAMgl6/RgJr36Eo1jzrRcAWbcXO2usCA= github.com/cilium/ebpf v0.9.1 h1:64sn2K3UKw8NbP/blsixRpF3nXuyhz/VjRlRzvlBRu4= github.com/cilium/ebpf v0.9.1/go.mod h1:+OhNOIXx/Fnu1IE8bJz2dzOA+VSfyTfdNUVdlQnxUFY= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM= github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw= github.com/containerd/cgroups/v3 v3.0.1 h1:4hfGvu8rfGIwVIDd+nLzn/B9ZXx4BcCjzt5ToenJRaE= github.com/containerd/cgroups/v3 v3.0.1/go.mod h1:/vtwk1VXrtoa5AaZLkypuOJgA/6DyPMZHJPGQNtlHnw= github.com/containerd/console v1.0.1/go.mod h1:XUsP6YE/mKtz6bxc+I8UiKKTP04qjQL4qcS3XoQ5xkw= github.com/containerd/console v1.0.3 h1:lIr7SlA5PxZyMV30bDW0MGbiOPXwc63yRuCP0ARubLw= github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U= github.com/containerd/containerd v1.7.0-rc.2 h1:Me1LnvqNQPl56LrVpVkNiQPPLomEKgZi2wKbe6ixx6w= github.com/containerd/containerd v1.7.0-rc.2/go.mod h1:N8hwWslQgbkbPIQulOL9Qgsw5x7VWZppXQLZburjSso= github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg= github.com/containerd/continuity v0.3.0/go.mod h1:wJEAIwKOm/pBZuBd0JmeTvnLquTB1Ag8espWhkykbPM= github.com/containerd/fifo v1.1.0 h1:4I2mbh5stb1u6ycIABlBw9zgtlK8viPI9QkQNRQEEmY= github.com/containerd/fifo v1.1.0/go.mod h1:bmC4NWMbXlt2EZ0Hc7Fx7QzTFxgPID13eH0Qu+MAb2o= github.com/containerd/go-cni v1.1.9 h1:ORi7P1dYzCwVM6XPN4n3CbkuOx/NZ2DOqy+SHRdo9rU= github.com/containerd/go-cni v1.1.9/go.mod h1:XYrZJ1d5W6E2VOvjffL3IZq0Dz6bsVlERHbekNK90PM= github.com/containerd/go-runc v1.0.0 h1:oU+lLv1ULm5taqgV/CJivypVODI4SUz1znWjv3nNYS0= github.com/containerd/go-runc v1.0.0/go.mod h1:cNU0ZbCgCQVZK4lgG3P+9tn9/PaJNmoDXPpoJhDR+Ok= github.com/containerd/ttrpc v1.2.0 h1:we4O9wzVsBA1HUVRGU8CWFsbjy2P/U2g9raVu5XXNI0= github.com/containerd/ttrpc v1.2.0/go.mod h1:YYyNVhZrTMiaf51Vj6WhAJqJw+vl/nzABhj8pWrzle4= github.com/containerd/typeurl/v2 v2.1.0 h1:yNAhJvbNEANt7ck48IlEGOxP7YAp6LLpGn5jZACDNIE= github.com/containerd/typeurl/v2 v2.1.0/go.mod h1:IDp2JFvbwZ31H8dQbEIY7sDl2L3o3HZj1hsSQlywkQ0= github.com/containernetworking/cni v1.1.2 h1:wtRGZVv7olUHMOqouPpn3cXJWpJgM6+EUl31EQbXALQ= github.com/containernetworking/cni v1.1.2/go.mod h1:sDpYKmGVENF3s6uvMvGgldDWeG8dMxakj/u+i9ht9vw= github.com/containernetworking/plugins v1.2.0 h1:SWgg3dQG1yzUo4d9iD8cwSVh1VqI+bP7mkPDoSfP9VU= github.com/containernetworking/plugins v1.2.0/go.mod h1:/VjX4uHecW5vVimFa1wkG4s+r/s9qIfPdqlLF4TW8c4= github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cyphar/filepath-securejoin v0.2.3 h1:YX6ebbZCZP7VkM3scTTokDgBL2TY741X51MTk3ycuNI= github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/docker/cli v23.0.1+incompatible h1:LRyWITpGzl2C9e9uGxzisptnxAn1zfZKXy13Ul2Q5oM= github.com/docker/cli v23.0.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/docker v20.10.20+incompatible h1:kH9tx6XO+359d+iAkumyKDc5Q1kOwPuAUaeri48nD6E= github.com/docker/docker v20.10.20+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A= github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0= github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c h1:+pKlWGMw7gf6bQ+oDZB4KHQFypsfjYlq/C4rfL7D3g8= github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA= github.com/docker/go-metrics v0.0.1 h1:AgB/0SvBxihN0X8OR4SjsblXkbMvalQ8cjmtKQ2rQV8= github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= github.com/emicklei/go-restful/v3 v3.10.1 h1:rc42Y5YTp7Am7CS630D7JmhRjq4UlEUuEKfrDac4bSQ= github.com/emicklei/go-restful/v3 v3.10.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/frankban/quicktest v1.14.0 h1:+cqqvzZV87b4adx/5ayVOaYZ2CrvM4ejQvUdBzPPUss= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonreference v0.20.0 h1:MYlu0sBgChmCfJxxUKZ8g1cPWFOB37YSZqewK7OKeyA= github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.19.14 h1:gm3vOOXfiuw5i9p5N9xJvfjvuofpyvLA9Wr6QfK5Fng= github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/goccy/go-json v0.10.0 h1:mXKd9Qw4NuzShiRlOXKews24ufknHO7gx30lsDyokKA= github.com/goccy/go-json v0.10.0/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/gnostic v0.5.7-v3refs h1:FhTMOKj2VhjpouxvWJAV1TL304uMlb9zcDqkl6cEI54= github.com/google/gnostic v0.5.7-v3refs/go.mod h1:73MKFl6jIHelAJNaBGFzt3SPtZULs9dYrGFt8OiIsHQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/hanwen/go-fuse/v2 v2.2.0 h1:jo5QZYmBLNcl9ovypWaQ5yXMSSV+Ch68xoC3rtZvvBM= github.com/hanwen/go-fuse/v2 v2.2.0/go.mod h1:B1nGE/6RBFyBRC1RRnf23UpwCdyJ31eukw34oAKukAc= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= github.com/hashicorp/go-hclog v0.9.2 h1:CG6TE5H9/JXsFWJCfoIVpKFIkFe6ysEuHirp4DxCsHI= github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/go-retryablehttp v0.7.2 h1:AcYqCvkpalPnPF2pn0KamgwamS42TqUDDYFRKq/RAd0= github.com/hashicorp/go-retryablehttp v0.7.2/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk= github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg= github.com/intel/goresctrl v0.3.0 h1:K2D3GOzihV7xSBedGxONSlaw/un1LZgWsc9IfqipN4c= github.com/intel/goresctrl v0.3.0/go.mod h1:fdz3mD85cmP9sHD8JUlrNWAxvwM86CrbmVXltEKd7zk= github.com/ipfs/go-cid v0.1.0 h1:YN33LQulcRHjfom/i25yoOZR4Telp1Hr/2RU3d0PnC0= github.com/ipfs/go-cid v0.1.0/go.mod h1:rH5/Xv83Rfy8Rw6xG+id3DYAMUVmem1MowoKwdXmN2o= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.16.0 h1:iULayQNOReoYUe+1qtKOqw9CwJv3aNQu8ivo7lw1HU4= github.com/klauspost/compress v1.16.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348 h1:MtvEpTB6LX3vkb4ax0b5D2DHbNAUsen0Gx5wZoq3lV4= github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA= github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g= github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg= github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc= github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU= github.com/moby/sys/mountinfo v0.6.2 h1:BzJjoreD5BMFNmD9Rus6gdd1pLuecOFPt8wC+Vygl78= github.com/moby/sys/mountinfo v0.6.2/go.mod h1:IJb6JQeOklcdMU9F5xQ8ZALD+CUr5VlGpwtX+VE0rpI= github.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5lXtc= github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo= github.com/moby/sys/signal v0.7.0 h1:25RW3d5TnQEoKvRbEKUGay6DCQ46IxAVTT9CUMgmsSI= github.com/moby/sys/signal v0.7.0/go.mod h1:GQ6ObYZfqacOwTtlXvcmh9A26dVRul/hbOZn88Kg8Tg= github.com/moby/sys/symlink v0.2.0 h1:tk1rOM+Ljp0nFmfOIBtlV3rTDlWOwFRhjEeAhZB0nZc= github.com/moby/sys/symlink v0.2.0/go.mod h1:7uZVF2dqJjG/NsClqul95CqKOBRQyYSNnJ6BMgR/gFs= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ= github.com/multiformats/go-base32 v0.0.3 h1:tw5+NhuwaOjJCC5Pp82QuXbrmLzWg7uxlMFp8Nq/kkI= github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= github.com/multiformats/go-base36 v0.1.0 h1:JR6TyF7JjGd3m6FbLU2cOxhC0Li8z8dLNGQ89tUg4F4= github.com/multiformats/go-base36 v0.1.0/go.mod h1:kFGE83c6s80PklsHO9sRn2NCoffoRdUUOENyW/Vv6sM= github.com/multiformats/go-multiaddr v0.8.0 h1:aqjksEcqK+iD/Foe1RRFsGZh8+XFiGo7FgUCZlpv3LU= github.com/multiformats/go-multiaddr v0.8.0/go.mod h1:Fs50eBDWvZu+l3/9S6xAE7ZYj6yhxlvaVZjakWN7xRs= github.com/multiformats/go-multibase v0.0.3 h1:l/B6bJDQjvQ5G52jw4QGSYeOTZoAwIO77RblWplfIqk= github.com/multiformats/go-multibase v0.0.3/go.mod h1:5+1R4eQrT3PkYZ24C3W2Ue2tPwIdYQD509ZjSb5y9Oc= github.com/multiformats/go-multihash v0.0.15/go.mod h1:D6aZrWNLFTV/ynMpKsNtB40mJzmCl4jb1alC0OvHiHg= github.com/multiformats/go-multihash v0.1.0 h1:CgAgwqk3//SVEw3T+6DqI4mWMyRuDwZtOWcJT0q9+EA= github.com/multiformats/go-multihash v0.1.0/go.mod h1:RJlXsxt6vHGaia+S8We0ErjhojtKzPP2AH4+kYM7k84= github.com/multiformats/go-varint v0.0.6 h1:gk85QWKxh3TazbLxED/NlDVv8+q+ReFJk7Y2W/KhfNY= github.com/multiformats/go-varint v0.0.6/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= github.com/onsi/ginkgo/v2 v2.4.0 h1:+Ig9nvqgS5OBSACXNk15PLdp0U9XPYROt9CFzVdFGIs= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/onsi/gomega v1.24.2 h1:J/tulyYK6JwBldPViHJReihxxZ+22FHs0piGjQAvoUE= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b h1:YWuSjZCQAPM8UUBLkYUk1e+rZcvWHJmFb6i6rM44Xs8= github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b/go.mod h1:3OVijpioIKYWTqjiG0zfF6wvoJ4fAXGbjdZuI2NgsRQ= github.com/opencontainers/runc v1.1.4 h1:nRCz/8sKg6K6jgYAFLDlXzPeITBZJyX28DBVhWD+5dg= github.com/opencontainers/runc v1.1.4/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.1.0-rc.1 h1:wHa9jroFfKGQqFHj0I1fMRKLl0pfj+ynAqBxo3v6u9w= github.com/opencontainers/runtime-spec v1.1.0-rc.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI= github.com/opencontainers/selinux v1.11.0 h1:+5Zbo97w3Lbmb3PeqQtpmTkMwsW5nRI3YaLpt7tQ7oU= github.com/opencontainers/selinux v1.11.0/go.mod h1:E5dMC3VPuVvVHDYmi78qvhJp8+M586T4DlDRYpFkyec= github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw= github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE= github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo= github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/rs/xid v1.4.0 h1:qd7wPTDkN6KQx2VmMBLrpHkiyQwgFXRnkOLacUiaSNY= github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli v1.22.4/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli v1.22.12 h1:igJgVw1JdKH+trcLWLeLwZjU9fEfPesQ+9/e4MQ44S8= github.com/urfave/cli v1.22.12/go.mod h1:sSBEIC79qR6OvcmsD4U3KABeOTxDqQtdDnaFuUN30b8= github.com/vbatts/tar-split v0.11.2 h1:Via6XqJr0hceW4wff3QRzD5gAk/tatMw/4ZA7cTlIME= github.com/vbatts/tar-split v0.11.2/go.mod h1:vV3ZuO2yWSVsz+pfFzDG/upWH1JhjOiEaWq6kXyQ3VI= github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.etcd.io/bbolt v1.3.7 h1:j+zJOnnEjF/kyHlDDgGnVL/AIqIJPq8UoB2GSNfkUfQ= go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/otel v1.12.0 h1:IgfC7kqQrRccIKuB7Cl+SRUmsKbEwSGPr0Eu+/ht1SQ= go.opentelemetry.io/otel v1.12.0/go.mod h1:geaoz0L0r1BEOR81k7/n9W4TCXYCJ7bPO7K374jQHG0= go.opentelemetry.io/otel/trace v1.12.0 h1:p28in++7Kd0r2d8gSt931O57fdjUyWxkVbESuILAeUc= go.opentelemetry.io/otel/trace v1.12.0/go.mod h1:pHlgBynn6s25qJ2szD+Bv+iwKJttjHSI3lUAyf0GNuQ= go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210506145944-38f3c27a63bf/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU= golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.7.0 h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA= golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/oauth2 v0.4.0 h1:NF0gk8LVPg1Ml7SSbGyySuoxdsXitj7TvgvuRxIMc/M= golang.org/x/oauth2 v0.4.0/go.mod h1:RznEsdpjGAINPTOF0UH/t+xJ75L18YO3Ho6Pyn+uRec= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200916030750-2334cc1a136f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 h1:vVKdlvoWBphwdxWKrFZEuM0kGgGLxUOYcY4U/2Vjg44= golang.org/x/time v0.0.0-20220210224613-90d013bbcef8/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.5.0 h1:+bSpV5HIeWkuvgaMfI3UmKRThoTA5ODJTUd8T17NO+4= golang.org/x/tools v0.5.0/go.mod h1:N+Kgy78s5I24c24dU8OfWNEotWjutIs8SnJvn5IDq+k= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 h1:DdoeryqhaXp1LtT/emMP1BRJPHHKFi5akj/nbx/zNTA= google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.53.0 h1:LAv2ds7cmFV/XTS3XG1NneeENYrXGmorPxsBbptIjNc= google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools/v3 v3.4.0 h1:ZazjZUfuVeZGLAmlKKuyv3IKP5orXcwtOwDQH6YVr6o= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= k8s.io/api v0.26.2 h1:dM3cinp3PGB6asOySalOZxEG4CZ0IAdJsrYZXE/ovGQ= k8s.io/api v0.26.2/go.mod h1:1kjMQsFE+QHPfskEcVNgL3+Hp88B80uj0QtSOlj8itU= k8s.io/apimachinery v0.26.2 h1:da1u3D5wfR5u2RpLhE/ZtZS2P7QvDgLZTi9wrNZl/tQ= k8s.io/apimachinery v0.26.2/go.mod h1:ats7nN1LExKHvJ9TmwootT00Yz05MuYqPXEXaVeOy5I= k8s.io/client-go v0.26.2 h1:s1WkVujHX3kTp4Zn4yGNFK+dlDXy1bAAkIl+cFAiuYI= k8s.io/client-go v0.26.2/go.mod h1:u5EjOuSyBa09yqqyY7m3abZeovO/7D/WehVVlZ2qcqU= k8s.io/cri-api v0.27.0-alpha.3 h1:RT3W8OnLFpk9MUod99GwYeNPnzhEqVH0aQE8zBKZ9ds= k8s.io/cri-api v0.27.0-alpha.3/go.mod h1:dwMiSnrLiMmrAsTo/fObV8+efaoI9hHa1IlL++hdDIs= k8s.io/klog/v2 v2.90.1 h1:m4bYOKall2MmOiRaR1J+We67Do7vm9KiQVlT96lnHUw= k8s.io/klog/v2 v2.90.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 h1:+70TFaan3hfJzs+7VK2o+OGxg8HsuBr/5f6tVAjDu6E= k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280/go.mod h1:+Axhij7bCpeqhklhUTe3xmOn6bWxolyZEeyaFpjGtl4= k8s.io/utils v0.0.0-20230220204549-a5ecb0141aa5 h1:kmDqav+P+/5e1i9tFfHq1qcF3sOrDp+YEkVDAHu7Jwk= k8s.io/utils v0.0.0-20230220204549-a5ecb0141aa5/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= lukechampine.com/blake3 v1.1.6 h1:H3cROdztr7RCfoaTpGZFQsrqvweFLrqS73j7L7cmR5c= lukechampine.com/blake3 v1.1.6/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k= sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= stargz-snapshotter-0.14.3/cmd/stargz-store/000077500000000000000000000000001440204344700206725ustar00rootroot00000000000000stargz-snapshotter-0.14.3/cmd/stargz-store/main.go000066400000000000000000000147271440204344700221600ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package main import ( "context" "flag" "fmt" "io" golog "log" "math/rand" "os" "os/signal" "path/filepath" "syscall" "time" "github.com/containerd/containerd/log" dbmetadata "github.com/containerd/stargz-snapshotter/cmd/containerd-stargz-grpc/db" "github.com/containerd/stargz-snapshotter/fs/config" "github.com/containerd/stargz-snapshotter/metadata" memorymetadata "github.com/containerd/stargz-snapshotter/metadata/memory" "github.com/containerd/stargz-snapshotter/service/keychain/dockerconfig" "github.com/containerd/stargz-snapshotter/service/keychain/kubeconfig" "github.com/containerd/stargz-snapshotter/service/resolver" "github.com/containerd/stargz-snapshotter/store" sddaemon "github.com/coreos/go-systemd/v22/daemon" "github.com/pelletier/go-toml" "github.com/sirupsen/logrus" bolt "go.etcd.io/bbolt" ) const ( defaultLogLevel = logrus.InfoLevel defaultConfigPath = "/etc/stargz-store/config.toml" defaultRootDir = "/var/lib/stargz-store" ) var ( configPath = flag.String("config", defaultConfigPath, "path to the configuration file") logLevel = flag.String("log-level", defaultLogLevel.String(), "set the logging level [trace, debug, info, warn, error, fatal, panic]") rootDir = flag.String("root", defaultRootDir, "path to the root directory for this snapshotter") ) type Config struct { config.Config // KubeconfigKeychainConfig is config for kubeconfig-based keychain. KubeconfigKeychainConfig `toml:"kubeconfig_keychain"` // ResolverConfig is config for resolving registries. ResolverConfig `toml:"resolver"` // MetadataStore is the type of the metadata store to use. MetadataStore string `toml:"metadata_store" default:"memory"` } type KubeconfigKeychainConfig struct { EnableKeychain bool `toml:"enable_keychain"` KubeconfigPath string `toml:"kubeconfig_path"` } type ResolverConfig resolver.Config func main() { rand.Seed(time.Now().UnixNano()) flag.Parse() mountPoint := flag.Arg(0) lvl, err := logrus.ParseLevel(*logLevel) if err != nil { log.L.WithError(err).Fatal("failed to prepare logger") } logrus.SetLevel(lvl) logrus.SetFormatter(&logrus.JSONFormatter{ TimestampFormat: log.RFC3339NanoFixed, }) var ( ctx = log.WithLogger(context.Background(), log.L) config Config ) // Streams log of standard lib (go-fuse uses this) into debug log // Snapshotter should use "github.com/containerd/containerd/log" otherwise // logs are always printed as "debug" mode. golog.SetOutput(log.G(ctx).WriterLevel(logrus.DebugLevel)) if mountPoint == "" { log.G(ctx).Fatalf("mount point must be specified") } // Get configuration from specified file if *configPath != "" { tree, err := toml.LoadFile(*configPath) if err != nil && !(os.IsNotExist(err) && *configPath == defaultConfigPath) { log.G(ctx).WithError(err).Fatalf("failed to load config file %q", *configPath) } if err := tree.Unmarshal(&config); err != nil { log.G(ctx).WithError(err).Fatalf("failed to unmarshal config file %q", *configPath) } } // Prepare kubeconfig-based keychain if required credsFuncs := []resolver.Credential{dockerconfig.NewDockerconfigKeychain(ctx)} if config.KubeconfigKeychainConfig.EnableKeychain { var opts []kubeconfig.Option if kcp := config.KubeconfigKeychainConfig.KubeconfigPath; kcp != "" { opts = append(opts, kubeconfig.WithKubeconfigPath(kcp)) } credsFuncs = append(credsFuncs, kubeconfig.NewKubeconfigKeychain(ctx, opts...)) } // Use RegistryHosts based on ResolverConfig and keychain hosts := resolver.RegistryHostsFromConfig(resolver.Config(config.ResolverConfig), credsFuncs...) // Configure and mount filesystem if _, err := os.Stat(mountPoint); err != nil { if err2 := os.MkdirAll(mountPoint, 0755); err2 != nil && !os.IsExist(err2) { log.G(ctx).WithError(err).WithError(err2). Fatalf("failed to prepare mountpoint %q", mountPoint) } } if !config.Config.DisableVerification { log.G(ctx).Warnf("content verification is not supported; switching to non-verification mode") config.Config.DisableVerification = true } mt, err := getMetadataStore(*rootDir, config) if err != nil { log.G(ctx).WithError(err).Fatalf("failed to configure metadata store") } layerManager, err := store.NewLayerManager(ctx, *rootDir, hosts, mt, config.Config) if err != nil { log.G(ctx).WithError(err).Fatalf("failed to prepare pool") } if err := store.Mount(ctx, mountPoint, layerManager, config.Config.Debug); err != nil { log.G(ctx).WithError(err).Fatalf("failed to mount fs at %q", mountPoint) } defer func() { syscall.Unmount(mountPoint, 0) log.G(ctx).Info("Exiting") }() if os.Getenv("NOTIFY_SOCKET") != "" { notified, notifyErr := sddaemon.SdNotify(false, sddaemon.SdNotifyReady) log.G(ctx).Debugf("SdNotifyReady notified=%v, err=%v", notified, notifyErr) } defer func() { if os.Getenv("NOTIFY_SOCKET") != "" { notified, notifyErr := sddaemon.SdNotify(false, sddaemon.SdNotifyStopping) log.G(ctx).Debugf("SdNotifyStopping notified=%v, err=%v", notified, notifyErr) } }() waitForSIGINT() log.G(ctx).Info("Got SIGINT") } func waitForSIGINT() { c := make(chan os.Signal, 1) signal.Notify(c, os.Interrupt) <-c } const ( memoryMetadataType = "memory" dbMetadataType = "db" ) func getMetadataStore(rootDir string, config Config) (metadata.Store, error) { switch config.MetadataStore { case "", memoryMetadataType: return memorymetadata.NewReader, nil case dbMetadataType: bOpts := bolt.Options{ NoFreelistSync: true, InitialMmapSize: 64 * 1024 * 1024, FreelistType: bolt.FreelistMapType, } db, err := bolt.Open(filepath.Join(rootDir, "metadata.db"), 0600, &bOpts) if err != nil { return nil, err } return func(sr *io.SectionReader, opts ...metadata.Option) (metadata.Reader, error) { return dbmetadata.NewReader(db, sr, opts...) }, nil default: return nil, fmt.Errorf("unknown metadata store type: %v; must be %v or %v", config.MetadataStore, memoryMetadataType, dbMetadataType) } } stargz-snapshotter-0.14.3/docs/000077500000000000000000000000001440204344700164135ustar00rootroot00000000000000stargz-snapshotter-0.14.3/docs/INSTALL.md000066400000000000000000000137521440204344700200530ustar00rootroot00000000000000# Install Stargz Snapshotter and Stargz Store ## What's Stargz Snapshotter and Stargz Store? *Stargz Snapshotter* is a plugin for containerd, which enables it to perform lazy pulling of eStargz. This is an implementation of *remote snapshotter* plugin and provides remotely-mounted eStargz layers to containerd. Communication between containerd and Stargz Snapshotter is done with gRPC over unix socket. For more details about Stargz Snapshotter and the relationship with containerd, [please refer to the doc](./overview.md). If you are using CRI-O/Podman, you can't use Stargz Snapshotter for enabling lazy pulling of eStargz. Instead, use *Stargz Store* plugin. This is an implementation of *additional layer store* plugin of CRI-O/Podman. Stargz Store provides remotely-mounted eStargz layers to CRI-O/Podman. Stargz Store exposes mounted filesystem structured like the following. CRI-O/Podman access to this filesystem to acquire eStargz layers. ``` /base64(imageref)// - diff : exposes the extracted eStargz layer - info : contains JSON-formatted metadata of this layer - use : files to notify the use of this layer (used for GC) ``` ## Install Stargz Snapshotter for containerd with Systemd To enable lazy pulling of eStargz on containerd, you need to install *Stargz Snapshotter* plugin. This section shows the step to install Stargz Snapshotter with systemd. We assume that you are using containerd (> v1.4.2) as a CRI runtime. - Download release tarball from [the release page](https://github.com/containerd/stargz-snapshotter/releases). - Add the following configuration to containerd's configuration file (typically: /etc/containerd/config.toml). Please see also [an example configuration file](../script/config/etc/containerd/config.toml). ```toml version = 2 # Enable stargz snapshotter for CRI [plugins."io.containerd.grpc.v1.cri".containerd] snapshotter = "stargz" disable_snapshot_annotations = false # Plug stargz snapshotter into containerd [proxy_plugins] [proxy_plugins.stargz] type = "snapshot" address = "/run/containerd-stargz-grpc/containerd-stargz-grpc.sock" ``` - Install fuse ###### centos ``` # centos 7 yum install fuse # centos 8 dnf install fuse modprobe fuse ``` ###### ubuntu ``` apt-get install fuse modprobe fuse ``` - Start stargz-snapshotter and restart containerd ``` tar -C /usr/local/bin -xvf stargz-snapshotter-${version}-linux-${arch}.tar.gz containerd-stargz-grpc ctr-remote wget -O /etc/systemd/system/stargz-snapshotter.service https://raw.githubusercontent.com/containerd/stargz-snapshotter/main/script/config/etc/systemd/system/stargz-snapshotter.service systemctl enable --now stargz-snapshotter systemctl restart containerd ``` ## Install Stargz Store for CRI-O/Podman with Systemd To enable lazy pulling of eStargz on CRI-O/Podman, you need to install *Stargz Store* plugin. This section shows the step to install Stargz Store with systemd. We assume that you are using CRI-O newer than https://github.com/cri-o/cri-o/pull/4850 or Podman newer than https://github.com/containers/podman/pull/10214 . - Download release tarball from [the release page](https://github.com/containerd/stargz-snapshotter/releases). - Add the following configuration to the storage configuration file of CRI-O/Podman (typically: /etc/containers/storage.conf). Please see also [an example configuration file](../script/config-cri-o/etc/containers/storage.conf). ```toml [storage] driver = "overlay" graphroot = "/var/lib/containers/storage" runroot = "/run/containers/storage" [storage.options] additionallayerstores = ["/var/lib/stargz-store/store:ref"] ``` - Install fuse ###### centos ``` # centos 7 yum install fuse # centos 8 dnf install fuse modprobe fuse ``` ###### ubuntu ``` apt-get install fuse modprobe fuse ``` - Start stargz-store (CRI-O also needs to be restarted if you are using) ``` tar -C /usr/local/bin -xvf stargz-snapshotter-${version}-linux-${arch}.tar.gz stargz-store wget -O /etc/systemd/system/stargz-store.service https://raw.githubusercontent.com/containerd/stargz-snapshotter/main/script/config-cri-o/etc/systemd/system/stargz-store.service systemctl enable --now stargz-store systemctl restart cri-o # if you are using CRI-O ``` ## Install Stargz Snapshotter for Docker(Moby) with Systemd - Docker(Moby) newer than [`5c1d6c957b97321c8577e10ddbffe6e01981617a`](https://github.com/moby/moby/commit/5c1d6c957b97321c8577e10ddbffe6e01981617a) is needed on your host. The commit is expected to be included in Docker v24. - Download stargz-snapshotter release tarball from [the release page](https://github.com/containerd/stargz-snapshotter/releases). - Enable `containerd-snapshotter` feature and `stargz` snapshotter in Docker. Add the following to docker's configuration file (typically: /etc/docker/daemon.json). ```json { "features": { "containerd-snapshotter": true }, "storage-driver": "stargz" } ``` - Enable stargz snapshotter in containerd. Add the following configuration to containerd's configuration file (typically: /etc/containerd/config.toml). ```toml version = 2 # Plug stargz snapshotter into containerd [proxy_plugins] [proxy_plugins.stargz] type = "snapshot" address = "/run/containerd-stargz-grpc/containerd-stargz-grpc.sock" ``` - Install fuse ###### centos ``` # centos 7 yum install fuse # centos 8 dnf install fuse modprobe fuse ``` ###### ubuntu ``` apt-get install fuse modprobe fuse ``` - Start stargz-snapshotter and restart containerd and docker ``` tar -C /usr/local/bin -xvf stargz-snapshotter-${version}-linux-${arch}.tar.gz containerd-stargz-grpc ctr-remote wget -O /etc/systemd/system/stargz-snapshotter.service https://raw.githubusercontent.com/containerd/stargz-snapshotter/${version}/script/config/etc/systemd/system/stargz-snapshotter.service systemctl enable --now stargz-snapshotter systemctl restart containerd systemctl restart docker ``` stargz-snapshotter-0.14.3/docs/ctr-remote.md000066400000000000000000000336611440204344700210270ustar00rootroot00000000000000# Optimize Images with `ctr-remote image optimize` This doc describes example usages of `ctr-remote image optimize` command for converting images into eStargz. `ctr-remote images optimize` command (call `ctr-remote` in this doc) enables users to convert an image into eStargz. This command works on containerd so containerd needs to run on your environment. So this converts an image stored in containerd and stores the resulting image to containerd. Because the resulting image is stored to containerd, you can use `ctr-remote image pull` and `ctr-remote image push` commands for pulling/pushing images from/to regstries. [nerdctl](https://github.com/containerd/nerdctl), Docker-compatible CLI for containerd, allows you to pull/push images using `~/.docker/config.json`. Various other containerd-based commands like `ctr-remote content get`, `ctr-remote images export` and other `ctr-remote` and `nerdctl` commands can also be used for debugging and inspecting the resulting eStargz image. The converted eStargz image can be lazily pulled by Stargz Snapshotter which can speed up the container startup. Because this image is backward compatible to OCI/Docker image, this can be also run by other runtimes that don't support lazy pull (e.g. Docker). Though lazy pull speeds up the container's startup, it's possible, especially with slow network, that the runtime performance becomes lower because reading files can induce remotely downloading file contents. For mitigating this, `ctr-remote` also allows to *optimize* the image against the *workload* the image runs. Here, workload means the configuration of the container that runs from that image, including the entrypoint program, environment variables, user etc. This optimization is done by baking the information about files that are likely accessed during runtime (called *prioritized files*), to the image. On runtime, Stargz Snapshotter prefetches these prioritized files before mounting the layer for making sure these files are locally accessible. This can avoid downloading chunks on every file read and mitigate the runtime performance drawbacks. :information_source: For more details about eStargz and its optimization, refer also to [eStargz: Standard-Compatible Extensions to Tar.gz Layers for Lazy Pulling Container Images](/docs/stargz-estargz.md). :information_source: Please see also [Creating smaller eStargz images](/docs/smaller-estargz.md) if you're interested in creating a smaller size of eStargz images. ## Requirements - containerd: Release binaries are available on https://github.com/containerd/containerd/releases. - CNI plugins (if network connection is needed during optimization): Release binaries are available on https://github.com/containernetworking/plugins. `ctr-remote` requires CAP_SYS_ADMIN. Rootless execution of this command is still WIP. For trying the examples described in this doc, you can also use the docker-compose-based demo environment. You can setup this environment as the following commands. *Note that this runs privileged containers on your host.* ``` $ cd ${GOPATH}/src/github.com/containerd/stargz-snapshotter/script/demo $ docker-compose build containerd_demo $ docker-compose up -d $ docker exec -it containerd_demo /bin/bash (inside container) # ./script/demo/run.sh ``` ## Optimizing an image The following command optimizes an (non-eStargz) image `ghcr.io/stargz-containers/golang:1.15.3-buster-org` (this is a copy of `golang:1.15.3-buster`) and pushes the result eStargz image into `registry2:5000/golang:1.15.3-esgz`. This doesn't append workload-related configuration options (e.g. `--entrypoint`) so this optimizes the image against the default configurations baked to the image e.g. through Dockefile instructions (`ENTRYPOINT`, etc) when building the original image. ``` ctr-remote image pull ghcr.io/stargz-containers/golang:1.15.3-buster-org ctr-remote image optimize --oci ghcr.io/stargz-containers/golang:1.15.3-buster-org registry2:5000/golang:1.15.3-esgz ctr-remote image push --plain-http registry2:5000/golang:1.15.3-esgz ``` When you run `ctr-remote image optimize`, this runs the source image (`ghcr.io/stargz-containers/golang:1.15.3-buster-org`) as a container and profiles all file accesses during the execution. Then these accessed files are marked as "prioritized" files and will be prefetched on runtime. You can specify the GZIP compression level the converter should use using the `--estargz-compression-level` flag. The values range from 1-9. If the flag isn't provided, the compression level will default to 9. A value of 9 indicates the archive will be gzipped with max compression. This will reduce the bytes transferred over the network but increase the CPU cycles required to decompress the payload. Whereas gzip compression value 1 indicates archive will be gzipped with least compression. This will increase the bytes transferred over the network but decreases the CPU cycles required to decompress the payload. This value should be chosen based on the workload and host characteristics. The following example optimizes an image with a compression level of 1. ```console # ctr-remote image optimize --oci --estargz-compression-level 1 ghcr.io/stargz-containers/golang:1.15.3-buster-org registry2:5000/golang:1.15.3-esgz ``` You can enable host networking for the container using the `net-host` flag. ```console # ctr-remote i optimize -t -i --oci --entrypoint='[ "/bin/bash", "-c" ]' --net-host --args='[ "ip a && curl example.com" ]' ghcr.io/stargz-containers/centos:8-test registry2:5000/centos:8-test-esgz ``` You can optimize GPU-based images using the `gpu` flag. The flag expects a comma separated list of integers. ```console # ctr-remote i optimize --oci --gpus "0" ``` `--oci` option is highly recommended to add when you create eStargz image. If the source image is [Docker image](https://github.com/moby/moby/blob/master/image/spec/v1.2.md) that doesn't allow us [content verification of eStargz](/docs/verification.md), `ctr-remote` converts this image into the [OCI starndard compliant image](https://github.com/opencontainers/image-spec/). OCI image also can run on most of modern container runtimes. You can lazy-pull this image into other hosts with Stargz Snapshotter. The following example lazily pulls this image to containerd, using `ctr-remote image rpull` command. ```console # ctr-remote image rpull --plain-http registry2:5000/golang:1.15.3-esgz fetching sha256:9f9b5a43... application/vnd.oci.image.index.v1+json fetching sha256:16debc17... application/vnd.oci.image.manifest.v1+json fetching sha256:a610ec55... application/vnd.oci.image.config.v1+json # ctr-remote run --rm -t --snapshotter=stargz registry2:5000/golang:1.15.3-esgz test echo hello hello ``` In the following examples, we omit `ctr-remote image pull` and `ctr-remote image push` from the example. ## Optimizing an image with custom configuration You can also specify the custom workload configuration that the image is optimized against. The following example optimizes the image against the workload running `go version` on `/bin/bash`. ``` ctr-remote image optimize --oci \ --entrypoint='[ "/bin/bash", "-c" ]' --args='[ "go version" ]' \ ghcr.io/stargz-containers/golang:1.15.3-buster-org \ registry2:5000/golang:1.15.3-esgz-go-version ``` Other options are also available for configuring the workload. |Option|Description| ---|--- |`--entrypoint`|Entrypoint of the container (in JSON array)| |`--args`|Arguments for the entrypoint (in JSON array)| |`--env`|Environment variables in the container| |`--user`|User name to run the process in the container| |`--cwd`|Working directory| |`--period`|The time seconds during profiling the file accesses| |`-t`or`--terminal`|Attach terminal to the container. This flag must be specified with `-i`| |`-i`|Attach stdin to the container| ## Mounting files from the host There are several cases where sharing files from host to the container during optimization is useful. This includes when we want to optimize an image against building a binary using compilers. For these use-cases, you can mount files on the hosts to the container using `--mount` option. The following example optimizes the image against the workload where Go compiler compiles "hello world" program. First, create the following Go source file at `/tmp/hello.go`. ```golang package main import "fmt" func main() { fmt.Println("hello world") } ``` Then you can build it inside the container by bind-mounting the file `/tmp/hello.go` on the host to this container. ``` ctr-remote image optimize --oci \ --mount=type=bind,source=/tmp/hello.go,destination=/hello.go,options=bind:ro \ --entrypoint='[ "/bin/bash", "-c" ]' --args='[ "go build -o /hello /hello.go && /hello" ]' \ ghcr.io/stargz-containers/golang:1.15.3-buster-org \ registry2:5000/golang:1.15.3-esgz-hello-world ``` The syntax of the `--mount` option is compatible to containerd's `ctr` tool and [corresponds to the OCI Runtime Spec](https://github.com/opencontainers/runtime-spec/blob/v1.0.2/config.md#mounts). You need to specify the following key-value pairs with comma separators. |Field|Description| ---|--- |`type`|The type of the filesystem to be mounted| |`destination`|The absolute path to the destination mount point in the container| |`source`|The source of the mount| |`options`|Mount options (separated by `:`) of the filesystem| ## Enabling CNI-based Networking You can also gain network connection in the container during optimization, using CNI plugins. Once you configure CNI plugins on the host, CNI-based networking can be enabled using `--cni` option. The following example accesses to https://example.com from the container, using `bridge` CNI plugin installed in the demo environment. ``` ctr-remote image optimize --oci \ --cni \ --entrypoint='[ "/bin/bash", "-c" ]' \ --args='[ "curl example.com" ]' \ ghcr.io/stargz-containers/golang:1.15.3-buster-org \ registry2:5000/golang:1.15.3-esgz-curl ``` If CNI plugins and configurations are installed to locations other than well-known paths (/opt/cni/bin and /etc/cni/net.d), you can tell it to `ctr-remote` using the following options. |Option|Description| ---|--- |`--cni-plugin-config-dir`|Path to the directory where CNI plugins configurations are stored| |`--cni-plugin-dir`|Path to the directory where CNI plugins binaries are installed| By default, `/etc/hosts` and `/etc/resolv.conf` are configured as the following. /etc/hosts ``` 127.0.0.1 localhost ::1 localhost ip6-localhost ip6-loopback fe00::0 ip6-localnet ff00::0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters ``` /etc/resolv.conf ``` nameserver 8.8.8.8 ``` If you want to customize the configuration, the following options are useful. |Option|Description| ---|--- |`--add-hosts`|Commma-separated list of hosts configuration (formatted as `hostname:IP`) for `/etc/hosts`| |`--dns-nameservers`|Comma-separated `nameserver` configs added to the container's `/etc/resolv.conf`| |`--dns-search-domains`|Comma-separated `search` configs added to the container's `/etc/resolv.conf`| |`--dns-options`|Comma-separated `options` configs added to the container's `/etc/resolv.conf`| ## Other useful features ### Reusing already-converted layers If the source image is large, its conversion takes accordingly long time. But you can skip conversion for layers that are already converted to eStargz. For enabling this feature, add `--reuse` option to `ctr-remote`. The following example re-converts already converted eStargz image (`ghcr.io/stargz-containers/golang:1.15.3-buster-esgz`) with `--reuse` feature. ``` ctr-remote image optimize --oci \ --reuse \ ghcr.io/stargz-containers/golang:1.15.3-buster-esgz \ registry2:5000/golang:1.15.3-esgz ``` You will see `ctr-remote` skips converting some layers with printing `copying without conversion` log messages as the following. ``` (... omit ...) WARN[0036] reusing "sha256:4416ecf7e2787af750fe3b1988f36a2c47edc2d3162739c6eedd739d6d5a14d1" without conversion WARN[0036] reusing "sha256:976cc0da952505fede3abe08c0ff0c5277416828c4dff8bd01b306c5b4e5c6f5" without conversion WARN[0036] reusing "sha256:59cf7266511a915072804370a3083a1007c4fb757d800ceef848032ac4a5b605" without conversion WARN[0036] reusing "sha256:ca2a1da2dee341a3b87a14d56603e9c29c66721056a47bec156f9b04ee0b1e5e" without conversion WARN[0036] reusing "sha256:79d28aed10b15d548b63eea4cc59e518c4939f9c8fb8498100ec658fc7e0baca" without conversion WARN[0036] reusing "sha256:6aedf0c74720e30b9093dc0d2b39c2dd88f35ead14e2087bb49c1608bb151e61" without conversion (... omit ...) ``` When optimizing an image, `ctr-remote` tries to avoid layer conversion as much as possible. The layers that meet the following conditions are skipped to converting. - layers that are already formatted as eStargz - layers that no file access occurred during optimization ### Converting multi-platform images You can also convert multi-platform images. If you want to convert all images contained in a multi-platform image, use `--all-platform` option. If you want to convert an image corresponding to a specific platform, tell it using `--platform` option. The format of the `--platform` option is `||/[/]`, please refer to containerd's [godoc](https://godoc.org/github.com/containerd/containerd/platforms#hdr-Platform_Specifiers) for more details. The following example converts all images contained in `ghcr.io/stargz-containers/golang:1.15.3-buster-org`. ``` ctr-remote image optimize --oci \ --all-platforms \ ghcr.io/stargz-containers/golang:1.15.3-buster-org \ registry2:5000/golang:1.15.3-esgz-fat ``` By default, when the source image is a multi-platform image, `ctr-remote` converts the image corresponding to the platform where `ctr-remote` runs. Note that though the images specified by `--all-platform` and `--platform` are converted to eStargz, images that don't correspond to the current platform aren't *optimized*. That is, these images are lazily pulled but without prefetch. stargz-snapshotter-0.14.3/docs/estargz.md000066400000000000000000000476661440204344700204370ustar00rootroot00000000000000# eStargz: Standard-Compatible Extension to Container Image Layers for Lazy Pulling This doc describes the extension to gzip layers of container images (`application/vnd.oci.image.layer.v1.tar+gzip` of [OCI Image Specification](https://github.com/opencontainers/image-spec/) and `application/vnd.docker.image.rootfs.diff.tar.gzip` of [Docker Image Specification](https://github.com/moby/moby/blob/master/image/spec/v1.2.md)) for *lazy pulling*. The extension is called *eStargz*. eStargz is a *backward-compatible extension* which means that images can be pushed to the extension-agnostic registry and can run on extension-agnostic runtimes. This extension is based on stargz (stands for *seekable tar.gz*) proposed by [Google CRFS](https://github.com/google/crfs) project (initially [discussed in Go community](https://github.com/golang/go/issues/30829)). eStargz extends stargz for chunk-level verification and runtime performance optimization. Notational convention follows [OCI Image Specification](https://github.com/opencontainers/image-spec/blob/v1.0.1/spec.md#notational-conventions). ## Overview Lazy pulling is a technique of pulling container images aiming at the faster cold start. This allows a container to startup without waiting for the entire image layer contents to be locally available. Instead, necessary files (or chunks for large files) in the layer are fetched *on-demand* during running the container. For achieving this, runtimes need to fetch and extract each file in a layer independently. However, layer without eStargz extension doesn't allow this because of the following reasons, 1. The entire layer blob needs to be extracted even for getting a single file entry. 2. Digests aren't provided for each file so it cannot be verified independently. eStargz solves these issues and enables lazy pulling. Additionally, it supports prefetching of files. This can be used to mitigate runtime performance drawbacks caused by the on-demand fetching of each file. This extension is a backward-compatible so the eStargz-formatted image can be pushed to the registry and can run even on eStargz-agnostic runtimes. ## The structure ![The structure of eStargz](/docs/images/estargz-structure.png) eStargz is a gzip-compressed tar archive of files and a metadata component called *TOC* (described in the later section). In an eStargz-formatted blob, each non-empty regular file and each metadata component MUST be separately compressed as gzip. This structure is inherited from [stargz](https://github.com/google/crfs). Therefore, the gzip headers MUST locate at the following locations. - The top of the blob - The top of the payload of each non-empty regular file tar entry except *TOC* - The top of *TOC* tar header - The top of *footer* (described in the later section) Large regular files in an eStargz blob MAY be chunked into several smaller gzip members. Each chunked member is called *chunk* in this doc. Therefore, gzip headers MAY locate at the following locations. - Arbitrary location within the payload of non-empty regular file entry An eStargz-formatted blob is the concatenation of these gzip members, which is a still valid gzip blob. ## TOC, TOCEntries and Footer ### TOC and TOCEntries eStargz contains a regular file called *TOC* which records metadata (e.g. name, file type, owners, offset etc) of all file entries in eStargz, except TOC itself. Container runtimes MAY use TOC to mount the container's filesystem without downloading the entire layer contents. TOC MUST be a JSON file contained as the last tar entry and MUST be named `stargz.index.json`. The following fields contain the primary properties that constitute a TOC. - **`version`** *int* This REQUIRED property contains the version of the TOC. This value MUST be `1`. - **`entries`** *array of objects* This property MUST contain an array of *TOCEntry* of all tar entries and chunks in the blob, except `stargz.index.json`. *TOCEntry* consists of metadata of a file or chunk in eStargz. If metadata in a TOCEntry of a file differs from the corresponding tar entry, TOCEntry SHOULD be respected. The following fields contain the primary properties that constitute a TOCEntry. Properties other than `chunkDigest` are inherited from [stargz](https://github.com/google/crfs). - **`name`** *string* This REQUIRED property contains the name of the tar entry. This MUST be the complete path stored in the tar file. - **`type`** *string* This REQUIRED property contains the type of tar entry. This MUST be either of the following. - `dir`: directory - `reg`: regular file - `symlink`: symbolic link - `hardlink`: hard link - `char`: character device - `block`: block device - `fifo`: fifo - `chunk`: a chunk of regular file data As described in the above section, a regular file can be divided into several chunks. TOCEntry MUST be created for each chunk. TOCEntry of the first chunk of that file MUST be typed as `reg`. TOCEntry of each chunk after 2nd MUST be typed as `chunk`. `chunk` TOCEntry MUST set *offset*, *chunkOffset* and *chunkSize* properties. - **`size`** *uint64* This OPTIONAL property contains the uncompressed size of the regular file. Non-empty `reg` file MUST set this property. - **`modtime`** *string* This OPTIONAL property contains the modification time of the tar entry. Empty means zero or unknown. Otherwise, the value is in UTC RFC3339 format. - **`linkName`** *string* This OPTIONAL property contains the link target. `symlink` and `hardlink` MUST set this property. - **`mode`** *int64* This REQUIRED property contains the permission and mode bits. - **`uid`** *uint* This REQUIRED property contains the user ID of the owner of this file. - **`gid`** *uint* This REQUIRED property contains the group ID of the owner of this file. - **`userName`** *string* This OPTIONAL property contains the username of the owner. - **`groupName`** *string* This OPTIONAL property contains the groupname of the owner. - **`devMajor`** *int* This OPTIONAL property contains the major device number of device files. `char` and `block` files MUST set this property. - **`devMinor`** *int* This OPTIONAL property contains the minor device number of device files. `char` and `block` files MUST set this property. - **`xattrs`** *string-bytes map* This OPTIONAL property contains the extended attribute for the tar entry. - **`digest`** *string* This OPTIONAL property contains the digest of the regular file contents. - **`offset`** *int64* This OPTIONAL property contains the offset of the gzip header of the regular file or chunk in the blob. TOCEntries of non-empty `reg` and `chunk` MUST set this property. - **`chunkOffset`** *int64* This OPTIONAL property contains the offset of this chunk in the decompressed regular file payload. TOCEntries of `chunk` type MUST set this property. - **`chunkSize`** *int64* This OPTIONAL property contains the decompressed size of this chunk. The last `chunk` in a `reg` file or `reg` file that isn't chunked MUST set this property to zero. Other `reg` and `chunk` MUST set this property. - **`chunkDigest`** *string* This OPTIONAL property contains a digest of this chunk. TOCEntries of non-empty `reg` and `chunk` MUST set this property. This MAY be used for verifying the data of the chunk. - **`innerOffset`** *int64* This OPTIONAL property indicates the uncompressed offset of the "reg" or "chunk" entry payload in a stream starts from `offset` field. #### Details about `innerOffset` `innerOffset` enables to put multiple "reg" or "chunk" payloads in one gzip stream starts from `offset`. This field allows the following structure. ![The structure of eStargz with innerOffset](/docs/images/estargz-inneroffset.png) Use case of this field is `--estargz-min-chunk-size` flag of `ctr-remote`. The value of this flag is the minimal number of bytes of data must be written in one gzip stream. If it's > 0, multiple files and chunks can be written into one gzip stream. Smaller number of gzip header and smaller size of the result blob can be expected. ### Footer At the end of the blob, a *footer* MUST be appended. This MUST be an empty gzip member whose [Extra field](https://tools.ietf.org/html/rfc1952#section-2.3.1.1) contains the offset of TOC in the blob. The footer MUST be the following 51 bytes (1 byte = 8 bits in gzip). ``` - 10 bytes gzip header - 2 bytes XLEN (length of Extra field) = 26 (4 bytes header + 16 hex digits + len("STARGZ")) - 2 bytes Extra: SI1 = 'S', SI2 = 'G' - 2 bytes Extra: LEN = 22 (16 hex digits + len("STARGZ")) - 22 bytes Extra: subfield = fmt.Sprintf("%016xSTARGZ", offsetOfTOC) - 5 bytes flate header: BFINAL = 1(last block), BTYPE = 0(non-compressed block), LEN = 0 - 8 bytes gzip footer (End of eStargz) ``` Runtimes MAY first read and parse the footer to get the offset of TOC. Each file's metadata is recorded in the TOC so runtimes don't need to extract other parts of the archive as long as it only uses file metadata. If runtime needs to get a regular file's content, it can get the size and offset of that content from the TOC and extract that range without scanning the entire blob. By combining this with HTTP Range Request supported by [OCI Distribution Spec](https://github.com/opencontainers/distribution-spec/blob/ef28f81727c3b5e98ab941ae050098ea664c0960/detail.md#fetch-blob-part), runtimes can selectively download file entries from the registry. ### Notes on compatibility with stargz eStargz is designed aiming to compatibility with gzip layers. For achieving this, eStargz's footer structure is incompatible with [stargz's one](https://github.com/google/crfs/blob/71d77da419c90be7b05d12e59945ac7a8c94a543/stargz/stargz.go#L36-L49). eStargz adds SI1, SI2 and LEN fields to the footer to make it compliant to [Extra field definition in RFC1952](https://tools.ietf.org/html/rfc1952#section-2.3.1.1). TOC, TOCEntry and the position of gzip headers are still compatible with stargz. ## Prioritized Files and Landmark Files ![Prioritized files and landmark files](/docs/images/estargz-landmark.png) Lazy pulling can cause runtime performance overhead by on-demand fetching of each file. eStargz mitigates this by supporting prefetching of important files called *prioritized files*. eStargz encodes the information about prioritized files to the *order* of file entries with some *landmark* file entries. File entries in eStargz are grouped into the following groups, - A. *prioritized files* - B. non *prioritized files* If no files are belonging to A, a landmark file *no-prefetch landmark* MUST be contained in the archive. If one or more files are belonging to A, eStargz MUST consist of two separated areas corresponding to these groups and a landmark file *prefetch landmark* MUST be contained at the boundary between these two areas. The Landmark file MUST be a regular file entry with 4 bits contents 0xf in eStargz. It MUST be recorded to TOC as a TOCEntry. Prefetch landmark MUST be named `.prefetch.landmark`. No-prefetch landmark MUST be named `.no.prefetch.landmark`. ### Example use-case of prioritized files: workload-based image optimization in Stargz Snapshotter Stargz Snapshotter makes use of eStargz's prioritized files for *workload-based* optimization to mitigate the overhead of reading files. The *workload* of the image is the runtime configuration defined in the Dockerfile, including entrypoint command, environment variables and user. Stargz snapshotter provides an image converter command `ctr-remote images optimize` to create optimized eStargz images. When converting the image, this command runs the specified workload in a sandboxed environment and profiles all file accesses. This command treats all accessed files as prioritized files. Then it constructs eStargz by - putting prioritized files from the top of the archive, sorting them by the accessed order, - putting *prefetch landmark* file entry at the end of this range, and - putting all other files (non-prioritized files) after the prefetch landmark. Before running the container, stargz snapshotter prefetches and pre-caches the range where prioritized files are contained, by a single HTTP Range Request supported by the registry. This can increase the cache hit rate for the specified workload and can mitigate runtime overheads. ## Content Verification in eStargz The goal of the content verification in eStargz is to ensure the downloaded metadata and contents of all files are the expected ones, based on the calculated digests. The verification of other components in the image including image manifests is out-of-scope of eStargz. On the verification step of an eStargz layer, we assume that the manifest that references this eStargz layer is already verified (using digest tag, etc). ![the overview of the verification](/docs/images/estargz-verification.png) A non-eStargz layer can be verified by recalculating the digest and comparing it with the one written in the layer descriptor referencing that layer in the verified manifest. However, an eStargz layer is *lazily* pulled from the registry in file (or chunk if that file is large) granularity so each one needs to be independently verified every time fetched. The following describes how the verification of eStargz is done using the verified manifest. eStargz consists of the following components to be verified: - TOC (a set of metadata of all files contained in the layer) - chunks of contents of each regular file TOC contains metadata (name, type, mode, etc.) of all files and chunks in the blob. On mounting eStargz, filesystem fetches the TOC from the registry. For making the TOC verifiable using the verified manifest, we define an annotation `containerd.io/snapshot/stargz/toc.digest`. The value of this annotation is the digest of the TOC and this MUST be contained in the descriptor that references this eStargz layer. Using this annotation, filesystem can verify the TOC by recalculating the digest and comparing it to the annotation value. Each file's metadata is encoded to a TOCEntry in the TOC. TOCEntry is created also for each chunk of regular files. For making the contents of each file and chunk verifiable using the verified manifest, TOCEntry has a property *chunkDigest*. *chunkDigest* contains the digest of the content of the `reg` or `chunk` entry. As mentioned above, the TOC is verifiable using the special annotation. Using *chunkDigest* fields written in the verified TOC, each file and chunk can be independently verified by recalculating the digest and comparing it to the property. As the conclusion, eStargz MUST contain the following metadata: - `containerd.io/snapshot/stargz/toc.digest` annotation in the descriptor that references eStargz layer: The value is the digest of the TOC. - *chunkDigest* properties of non-empty `reg` or `chunk` TOCEntry: The value is the digest of the contents of the file or chunk. ### Example usecase: Content verification in Stargz Snapshotter Stargz Snapshotter verifies eStargz layers leveraging the above metadata. As mentioned above, the verification of other image components including the manifests is out-of-scope of the snapshotter. When this snapshotter mounts an eStargz layer, the manifest that references this layer must be verified in advance and the TOC digest annotation written in the verified manifest must be passed down to this snapshotter. On mounting a layer, stargz snapshotter fetches the TOC from the registry. Then it verifies the TOC by recalculating the digest and comparing it with the one written in the manifest. After the TOC is verified, the snapshotter mounts this layer using the metadata recorded in the TOC. During runtime of the container, this snapshotter fetches chunks of regular file contents lazily. Before providing a chunk to the filesystem user, snapshotter recalculates the digest and checks it matches the one recorded in the corresponding TOCEntry. ## eStargz image with an external TOC (OPTIONAL) This OPTIONAL feature allows separating TOC into another image called *TOC image*. This type of eStargz is the same as the normal eStargz but doesn't contain TOC JSON file (`stargz.index.json`) in the layer blob and has a special footer. This feature enables creating a smaller eStargz blob by avoiding including TOC JSON file in that blob. Footer has the following structure: ``` // The footer is an empty gzip stream with no compression and an Extra header. // // 46 comes from: // // 10 bytes gzip header // 2 bytes XLEN (length of Extra field) = 21 (4 bytes header + len("STARGZEXTERNALTOC")) // 2 bytes Extra: SI1 = 'S', SI2 = 'G' // 2 bytes Extra: LEN = 17 (len("STARGZEXTERNALTOC")) // 17 bytes Extra: subfield = "STARGZEXTERNALTOC" // 5 bytes flate header // 8 bytes gzip footer // (End of the eStargz blob) ``` TOC image is an OCI image containing TOC. Each layer contains a TOC JSON file (`stargz.index.json`) in the root directory. Layer descriptors in the manifest must contain an annotation `containerd.io/snapshot/stargz/layer.digest`. The value of this annotation is the digest of the eStargz layer blob corresponding to that TOC. The following is an example layer descriptor in the TOC image. This layer (`sha256:64dedefd539280a5578c8b94bae6f7b4ebdbd12cb7a7df0770c4887a53d9af70`) contains the TOC JSON file (`stargz.index.json`) in the root directory and can be used for eStargz layer blob that has the digest `sha256:5da5601c1f2024c07f580c11b2eccf490cd499473883a113c376d64b9b10558f`. ```json { "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip", "digest": "sha256:64dedefd539280a5578c8b94bae6f7b4ebdbd12cb7a7df0770c4887a53d9af70", "size": 154425, "annotations": { "containerd.io/snapshot/stargz/layer.digest": "sha256:5da5601c1f2024c07f580c11b2eccf490cd499473883a113c376d64b9b10558f" } } ``` ### Example usecase: lazy pulling with Stargz Snapshotter Stargz Snapshotter supports eStargz with external TOC. If an eStargz blob's footer indicates that it requires the TOC image, stargz snapshotter also pulls it from the registry. Stargz snapshotter assumes the TOC image has the reference name same as the eStargz with `-esgztoc` suffix. For example, if an eStargz image is named `ghcr.io/stargz-containers/ubuntu:22.04-esgz`, stargz snapshotter acquires the TOC image from `ghcr.io/stargz-containers/ubuntu:22.04-esgz-esgztoc`. Note that future versions of stargz snapshotter will support more ways to search the TOC image (e.g. allowing custom suffix, using OCI Reference Type, etc.) Once stargz snapshotter acquires TOC image, it tries to find the TOC corresponding to the mounting eStargz blob, by looking `containerd.io/snapshot/stargz/layer.digest` annotations. As describe in the above, the acquired TOC JSON is validated using `containerd.io/snapshot/stargz/toc.digest` annotation. ## Example of TOC Here is an example TOC JSON: ```json { "version": 1, "entries": [ { "name": "bin/", "type": "dir", "modtime": "2019-08-20T10:30:43Z", "mode": 16877, "NumLink": 0 }, { "name": "bin/busybox", "type": "reg", "size": 833104, "modtime": "2019-06-12T17:52:45Z", "mode": 33261, "offset": 126, "NumLink": 0, "digest": "sha256:8b7c559b8cccca0d30d01bc4b5dc944766208a53d18a03aa8afe97252207521f", "chunkDigest": "sha256:8b7c559b8cccca0d30d01bc4b5dc944766208a53d18a03aa8afe97252207521f" }, { "name": "lib/", "type": "dir", "modtime": "2019-08-20T10:30:43Z", "mode": 16877, "NumLink": 0 }, { "name": "lib/ld-musl-x86_64.so.1", "type": "reg", "size": 580144, "modtime": "2019-08-07T07:15:30Z", "mode": 33261, "offset": 512427, "NumLink": 0, "digest": "sha256:45c6ee3bd1862697eab8058ec0e462f5a760927331c709d7d233da8ffee40e9e", "chunkDigest": "sha256:45c6ee3bd1862697eab8058ec0e462f5a760927331c709d7d233da8ffee40e9e" }, { "name": ".prefetch.landmark", "type": "reg", "size": 1, "offset": 886633, "NumLink": 0, "digest": "sha256:dc0e9c3658a1a3ed1ec94274d8b19925c93e1abb7ddba294923ad9bde30f8cb8", "chunkDigest": "sha256:dc0e9c3658a1a3ed1ec94274d8b19925c93e1abb7ddba294923ad9bde30f8cb8" }, ... (omit) ... ``` stargz-snapshotter-0.14.3/docs/images/000077500000000000000000000000001440204344700176605ustar00rootroot00000000000000stargz-snapshotter-0.14.3/docs/images/benchmarking-result-ecdb227.png000066400000000000000000000340271440204344700254660ustar00rootroot00000000000000‰PNG  IHDRèî SÌ2PLTEÿÿÿ   ÿÀ€ÿÀÿîîÀ@ÈÈAiáÿÀ €@À€ÿ0`€‹@€ÿ€ÿÿÔ¥**ÿÿ@àÐ333MMMfff™™™³³³ÀÀÀÌÌÌåååÿÿÿð22î­ØæðUðàÿÿîÝ‚ÿ¶Á¯îîÿ×ÿdÿ"‹".‹Wÿ‹p€Í‡ÎëÿÿÿÿÎÑÿ“ÿPð€€ÿEú€ré–zðæŒ½·k¸† õõÜ € ÿ¥î‚î”ÓÝ ÝP@Uk/€€€@€@€€`À€`ÿ€€ÿ€@ÿ @ÿ `ÿ pÿÀÀÿÿ€ÿÿÀÍ·žðÿð ¶ÍÁÿÁÍÀ°|ÿ@ ÿ ¾¾¾ŸŸŸ¿¿¿ßßß___???eÏL¨ pHYsÄÄ•+ IDATxœí º£ …an_ûßÂ*jç% &éùçëõ>¤p‚Ç4رÆ~×<Þº-åIïäÞÓ6®À“Rž¤xb»Ð¦÷k‡ôoþ<à×ç=ç_¿ºCöÓuÖ¸qÖùxŒ!2ßž#<ùºÓmþæÏàφwáþÛg87úà2Ÿó¯_Ý!ûéB(×™Övg^þ6:AÁŸÁ›Ï9<Ælôéhsí”à›~˜óYLlfÎSÝü›fÿ›~Xöñ¿îüË‚FMlãÚÑοï¦?ŒíÏ0ý}þUÉÔlìë×Ä×Ó¡FÿÍ4ÒauÂÚçÖÕÜ:<Ýaˆñyc›0¬eD³¹úðêÆ÷r0àÖåÜ4Žõ#˜û_¬Ï»¹‹p|ÆÐfÐÚ)<ÌfôéHkìØM_¦Ã¯±>±­¦]S]î3N¦ Éoúmïÿrhä3zlãVÿ»¶SÏàÿ>ëHüóM?Œ®Ÿ\âv-g N;wë+‘5ïºZ[Ç!n‰ãt³åæ…— ßyÚáô±Ëµ»ñÏŒþqrX”îEÆÇg<nm“½\@šÍè£ÏgƒÿÒ­®ró>ã°¦ºÆn¿ÙÚ»&øçØhÚnmܺºžügÍÎèþ‡ÉÑsó?Œ>îF²œW>ºò»ÅV;Å¿ÄqΚ»]$Öç鯸 fëòpîûÏèû6ñy"c„ã3úý×mmðÚ<Ëft°ùãØmsbkw¶ž³›MÇà¢q4æ£ÑtÜnm¶•€)­v<Ã`vFŸ_Ì.ÅZ3zc–¼·ö¹ÞÚzëa\ŸwgèvÑìв]xÉÑo¯Ö.»Ãyê}ßfyÞÃb„£ˆé›Ý€Ö6ÇÓwùfô™ÍÖ³±Ö=ç¾ø kÌÓÆ…?îMÝÚl–è—rôã“iôe$ë™ç£«Õ臶ç]Ç~³ŽhIÖS‹¡]óéúÍÚeL´ýÐf}ޣȃїñnZÛ,¯,xŠTF_Ù2z»³~¶Bª;;˜FƒÛµ9X¢–"w÷ ÙFÿ3£·ýØÁ1£/²·íÆ+änoôóŒ~h³<ï‡Èï}dtð0ÝÊß5z7óÜþ×èX£-1ýþ¿gøßè5ú¼¦þ_>?óGW‹ÑÄ¿ÄqnÚ~5G¢íVÁf×ËV£ïW#ÿ3ú¡Íò¼"£Ñ5ú!}Û5:xš/Foœ¿øµT›¡ËÚñ8ëJS.Ç%Å®?6Š«î¶ÙY¢›~³¬E>ÃÜÍÎè«îSÓ+Û¿VÝý¥½cW¡õøÑAüKg¸.¸Žh~étøÑ6ÔÛ˸«î¾»u¬ÁÕ«µmÖçý~Xu_Ç‚Uwð0_Œ®ì®×ª;÷q}þMëì8U­.4¯[íßÄ‹Û1÷M¿ñW˜þx†ùW{£ûëèíìÃUõ`_Gïžðx}míŸîÐAüKçz {ÑœD~šÌ¹½)`×åÒÝ:ÖƒÑmÖç=ŠÜ^º/ϯ£ýÖ×ÑÁÑ{çýÈÿ]ß'ñ&Á“.¡³ä3â•;ø!¦—îsñ¤”Ñî:±åSï| ¡ƒ"¾yôH)£' ãç»L>#þ÷à6}øR”{õÄ0„¤àýÅh¦uáMÎÅÞB xŸÞv0:Úñ·pæx¯^€.üL‚Ñ÷êh¢;Þ¡«Å­=PÈú‰¢Ëköý]F, õÝ2ú÷ê¥ „+ÐõV+üu½dôãý}éáߊt½ÕŠ]oeôýzéáߊt½ÕŠ]/ýoø‹Æsè’ÕªüEãÀ¹tÉjUþ¢qàܺdµ*Ñ8pî]9­âG[Uè«lþ6: 6þb3˜£ Û Ö¿¿$¼qtat4²~Š;Œ€bœÿ´ÇÆ~5ú­w¶³ñ›ðÁÓ­í¿}qÉÕí6þb3Þ!xº³ÝW£_È4º˜ÿ—À N3úüåJ6‡ÑàÊZ£o»/FFInat¸²®º®ï›oFGF‡Ñl\38ÿ™&½¿ojóƒ«îaµ1ûe\¢è]‘ÙØ!eôœõÆÃ9ÀèÈèà€ÑI6Êx6v@F`¥}ü£MØØ5:+Ãoh£™ï‚ìÚÑÆL?ÌߌÖÚ.þöØØ5:ø!×™v2³“Œi¬ÿÁ|ìÃoÍ8ì~ûl쀌~ˆÕÀám¯ó›ÛÝò'ÿÑ£ÞèÇßš_xà jt ‹Î§mwõüC»°ãlôßš,5:2:ÐEüxQí¼[²pjtkW£¯¿]ÉòÁ'lì€ü[Fov?ôvªÑ}OÆñ/ÔèÈè@ë'‡‡wí{ðvo×ýsî2:jt  ¿êÞMVFo¦úa0þ–Ý8Ž~ù}ûm5:2:Æz½Y¦Wí­³c×Yg:·\G¶ýVÝQ£p 6v@F l쀀r°±2:å`cÔ蔃Ñ(; F¿Nø?«ÛÇ7´ o•{6v@F¿Nø?«›Ñ]cz÷Ô(ØØ5:øuvÿgu\~ò߬èà 2:øBú>|òšiÜögýFG~ù¸ü°Ñ‘ÑÁ/ðóF'=Ø(àóǨî?KõÇŒŽŒ~7ß%n÷Yª?ftÔèàÖ>|–ê€{°±jtÊÁÆÈ蔃P£P6v@F l쀀r°±2:å¨o‡Þ9¿ùüLXÔ蔣¾ëÌ|wúnÿYÈ蔣ºZÞìóÿÛ~¾7AÀMjÛ¡··÷ü rÝþ£"¿·AFà&µí0eroô6X|ÿ‘¨Ñ(Ge; £YŒîê/€{ÔµCx­NÈè¨Ñ¸E]; Ë¢kf‹·ûýÛÿ¯CF€NÂX…ÙVÝ·Ï÷¨Ñ¸É[F÷×Ñ[\G o=ïq¨Ñ¸; £P6v@@9ØØ€r°±jtÊÁÆÈ蔃P£P6v@F l쀀r°±2:å`cÔ蔃Ñ(; F l쀌@9ØØ5:å`cdtÊÁƨÑ(; £P6v@@9ØØ€r°±jtÊÁÆÈ蔃P£P6v@F lìðƒ5º¥ñö°DØ6?˜ÑatP 6‡ÍÖè0:¨›ÃFå`sØ F‡ÑA9Ø6Èè0:(›Ã5:ŒÊÁæ°AF‡ÑA9Ø6¨ÑatP6‡ 2:ŒÊÁæ°A®ÆèZu‰†Mx‘ÑÕB«.Ѱ /jt5†ÐªK4l‹Œ®ÆZu‰†MxQ£«1„Öù ›ð"£ë1ºÒù ›ð¢F×ctÒƒ¿.Ѱ /2º£+/Ѱ /jt=FW:_¢a^dt=FW:_¢a^ÔèzŒNzð×%6áEF×ct¥ó%6áE®ÇèJçK4l‹Œ®ÇèJçK4l‹]ÑIþºDÃ&¼ÈèzŒ®t¾DÃ&¼¨Ñõ]é|‰†Mx‘Ñõ]é|‰†Mx“F×j¥ºHþºDS9¼ýà¬k¦oÆpÌ—bç/Ödmù8jŽŒÎÊáuco:;9}>þrfô¸Cî–/jNÌé  •ÃÛõÓ—ÁMŽo®]˜Ñ‘ÑùñFx‡1ßèk>µF'=øëÍ ámm7õ;Œö`ö³U÷yŸŒ-ÿG­Ñ‘ÑùQ=¼£µ­ß S±î®.ÆQêsþŽZ£s:(È áÝüÝÚþÊ@Ñ…o„7ú»Ûýûa¬µæSktÒƒ¿.™¼rØôw¶7zpx³ë«îzŒŽŒÎÊFw¡4MoÃ7»Õ¸3£Çr·|QktbN©ÞðθÉ㦧oÚkAFftdt~° ï‰Ñ5Ö|jNzð×%6áŪ»£#£óƒMx“RŸ³Qö­µ¬V]¢aÞŸÌè:3ŸV]¢aÞ_¬ÑIèØ„÷ÄèyÙÜ BkæÓªK4lÂ{fô¸Cî–/ZkY­ºDÃ&¼Èèj2ŸV]¢a^ÔèÐÊÁ&¼)£ggs¿e£ì+Z3ŸV]¢aÞdF§Ôçl”}Ek-«U—hØ„]MæÓªK4l‹º@9Ø„÷ÄèyÙÜ BkæÓªK4lÂ{fô¸Cî–/ZkY­ºDÃ&¼Èèj2ŸV]¢a^ÔèÐÊÁ&¼)£ggs¿e£ì+Z3ŸV]¢aÞdF§Ôçl”}Ek-«U—hØ„]MæÓªK4l‹º@9Ø„÷ÄèyÙÜ BkæÓªK4lÂ{fô¸Cî–/ZkY­ºDÃ&¼Èèj2ŸV]¢a^ÔèÐÊÁ&¼)£ggs¿e£ì+Z3ŸV]¢aÞdF§Ôçl”}Ek-«U—hØ„]MæÓªK4l‹º@9Ø„÷ÄèyÙÜ BkæÓªK4lÂ{fô¸Cî–/ZkY­ºDÃ&¼Èèj2ŸV]¢a^ÔèÐÊÁ&¼)£ggs¿e£ì+Z3ŸV]¢aÞdF§Ôçl”}Ek-«U—hØ„]MæÓªK4l‹º@9Ø„÷ÄèyÙÜ BkæÓªK4lÂ{fô¸Cî–/ZkY­ºDÃ&¼Èèj2ŸV]¢a^ÔèztÑx{غaޔѳ³¹ß²Qö­™Oë|‰†Mx“RŸ³Qö­µ¬Öù ›ð"£#£ƒr° /jtèå`Þ£çecÄd>}þ¢n¾DÃ&¼gF;änù¢·Fß¾jš/Ѱ /2:2:(›ð¢F‡.P6áM]é*®ÚŒ®t¾DÃ&¼ÉŒN©÷Ø(ûŠÞ]ç|‰†Mx‘Ñ‘ÑA9Ø„5:trTo?8ëÿ]3}Ó^ˆ¿df þŽÚŒ>Q7_¢©^7ö¦³÷y7}³sú™Ñã¹[¾è­Ñ·¯šæK4•ÃÛõÓ—ÁMŽ÷i½q—¢5C £Qó%š7Â;ŒS2ï¦o:Û_ˆÖšºdéÍ ám'“·Áâ³ÝO¢uWmFW:_¢©ÞÑúʼ ýöÿ˜³åàè­ÑuΗh^oçdt2º¬ùÍá\>[¼Ý×èß例æƒ.YºdòÊ-ùúÆ;Ûû;¬ºûå÷8žï­ìü%3Kð?pÔfôù‹ºùMe£»¡Ÿ^ºóuô×ÑÎ}ûªi¾DS9¼áqƒOëxg2úaË_—hØ„÷Äèk>è’¥K4l›2ºÒU\µ]é|‰†Mx“Rï±Qö½5ºÎù ›ð"£#£ƒr° /jtèå`Þ£çecÄd>}þ¢n¾DÃ&¼gF;änù¢·Fß¾jš/Ѱ /2:2:(›ð¢F‡.P6áM]é*®ÚŒ®t¾DÃ&¼ÉŒN©÷Ø(ûŠÞ]ç|‰†Mx‘Ñ‘ÑA9Ø„5:tr° ï‰Ñó²ƒ1b2ŸÆŒ>Q7_¢aÞ3£Çr·|Ñ[£o_5Í—hØ„”ƒMxQ£C(›ð¦Œ®tWmFW:_¢aÞdF§Ô{l”}Eo®s¾DÃ&¼ÈèÈè l‹º@9Ø„÷ÄèyÙÁ1™OcFŸ¿¨›/Ѱ ï™Ñã¹[¾è­Ñ·¯šæK4l‹ŒŽŒÊÁ&¼¨Ñ¡ ”ƒMxSFWºŠ«6£+/Ѱ o2£Sê=6ʾ¢·F×9_¢a^dô«Fm]á]ó%6áE~U£ÓtUáÂ&¼'FÏËƈ©e5fôù‹ºù ›ðž=î»å ±F—at…ó%6áEFGFå`^ÔèWu‰0ºÆù ›ð¦Œ®tWmFW:_¢aÞdF§Ô{l”}Eo®s¾DÃ&¼ÈèÈè l‹ýª.þF§éª8„MxOŒž—Œ‘°ŠKMÎŒ®q¾DÃ&¼gF;änùBÔ%Ãè çK4lÂû‹}þ’«K†ÑΗhØ„5úU]"Œ®q¾DÃ&¼)£+]Å%êâot¥ó%6áMftJ½ÇFÙWˆºø]é|‰†Mx‘Ñ‘ÑA9Ø„5úU]üNÓUq„?›ðž=/;#a—¨K„Ñ5ΗhØ„÷Ìèq‡Ü-_ˆºd]á|‰†Mx‘Ñ‘ÑA9Ø„5úU]"Œ®q¾DÃ&¼)£+]ÅŪ»¬ù ›ð&3:¥Þc£ì+¸Ž.k¾DÃ&¼ÈèÈè •ÃÛκfúf Gßpi Zk>Ôè²æK4•Ã;޽éìäôqøøË‰Ñó²ƒ1Vq‰ºD]ã|‰¦rxÛ~ú28cBZ¿8{Ø!wË¢.FW8_¢y#¼$£+ÌÈèFÔ|‰æ…ðöÞävíÁì¨Ñ¯êató%šúáíÇÑø}*ÖÝÅÅ8¥«¸Xu—5_¢©ÞÞñûÖöW¢õº,®£Ëš/ÑÔo·¿¤Öíþý€Ôš!ÑeÍ—LŠí‘ÿwèíR—‡7»ÞQ£_ÕÅßè4]Gøƒ<ÞÓƒk½|ÞÛP£ïVãNŒž—ÂPè2*AÔ%ÂèçK4ýä¹û娛L>:ëÚä΢Ô}¼!ê’at…ó%šgÃë?€ŒŽŒÊñ|x»ðõúœ<­5jtYó%šÇÃÛ.'è\§§Œ®t«î²æK4‡w)¼;÷Ü@´^—ÅutYó%šÇÃû9‡ Dk†@F—5_¢y>£Ïïy6£ë¬ùˆºø¦«âÇÃÛ¸¶ë»æ¿ÿvc vþ’™%ø8D]"Œ®q¾Dó|x‡p\}ÞWâÎ@ìa‡Ü-_ˆºd]á|‰¦Dx»®Ëo„ŒŽŒÊQ$¼ýù.ÿýª.F×8_¢y>¼­óGÕkö”Ñ•®âbÕ]Ö|‰æñð6vðï™ùïæ7¢õº,®£Ëš/Ñ<^ÿ†ëï/ñÜ@´fdtYó%šÇû/¼ˆÖš¨‹¿Ñiº*Žðy>£wáI;÷Ü@ìü%3Kð?pˆºD]ã|‰æñð6¶él×>þ†™¸Cî–/D]2Œ®p¾Dó|x›p\åú¤DxK¼aFc͇]Ö|‰æùðú è]›ýž™”Ñ•®âbÕ]Ö|‰æñð¶Îß|ÂÚܤžÌè”zÿƒëè²æK4‡wlqƒiÇó]¯Dk†@F—5_¢y<¼vù\†Ü'F~U£ÓtUáRÂè#<ñ‰Ñó²ƒ1Vq‰ºD]ã|‰æù—îMø\†Î=7{Ø!wË¢.FW8_¢y<¼µþnR¸ÃÌ9ÈèFÔ|‰æÙð¶þK¸²Ö™Ì{»£F¿ªK„Ñ5Ηhž ¯MüDˆÖU\¬ºËš/ÑÔè²æK4%‹OS½Q—£kœ/Ѱ ï™Ñã¹[¾uÉ0ºÂùÍóáí»™ç¢5C £Qó%šÇÃÛ,ÔèWu‰0ºÆùÍãáuM?óÜ@´®âbÕ]Ö|‰æñðRŸ0™Ñ)õÿ×ÑeÍ—hï@Xq÷ £#£ƒr<Þ~ÚÀsÑZó¡F—5_¢y<¼ ñÈ:1z^v0FÂ*.Q—£kœ/Ñ<_£7”ÛNœ=î»å Q— £+œ/ÑÛýt Z32º5_¢y<¼§'è~ýÿZß^7ºÆš5º¬ùÍÃá;F÷eÞM>ÏÌèJWq±ê.k¾DópxÛÁŽ3_^ºwv˜7þïí¾Fÿ~@j½.‹ëè²æK&¥€1ù×~½tXu÷Ëïq<ßiÍÈè²æK4•Ã?{Ñ_Goq¢‹¿Ñiº*Žð©Þ~9êú¼wÆÍ_2³ÿ‡¨K„Ñ5ΗhØ„÷Ìèq‡Ü-_ˆºd]á|‰†Mx‘Ñ‘ÑA9Ø„5úU]"Œ®q¾DÃ&¼)£+]ÅŪ»¬ù ›ð&3:¥Þc£ì+¸Ž.k¾DÃ&¼ÈèÈè l‹ýª.þF§éª8„MxOŒž—Œ‘°ŠKÔ%ÂèçK4lÂ{fô¸Cî–/D]2Œ®p¾DÃ&¼ÈèÈè l‹ýª.F×8_¢aޔѕ®âbÕ]Ö|‰†Mx“Rï±Qö\G—5_¢a^dtdtP6áE~U£ÓtUáÂ&¼'FÏËÆHXÅ%êató%6á=3zÜ!wË¢.FW8_¢a^dtdtP6áE~U—£kœ/Ѱ oÊèJWq±ê.k¾DÃ&¼ÉŒN©÷Ø(û ®£Ëš/Ѱ /2:2:(›ð¢F¿ª‹¿Ñiº*ŽðaÞ£çec$¬âu‰0ºÆù ›ðž=î»å Q— £+œ/Ѱ /2:2:(›ð¢F¿ªK„Ñ5ΗhØ„7et¥«¸Xu—5_¢aÞdF§Ô{l”}×ÑeÍ—hØ„”ƒMxQ£_ÕÅßè4]Gøƒ° ï‰Ñó²ƒ1Vq‰ºD]ã|‰†MxÏŒwÈÝò…¨K†ÑΗhØ„”ƒMxQ£_Õ%ÂèçK4l›2ºÒU\¬ºËš/Ѱ o2£Sê=6ʾ‚ëè²æK4l‹ŒŽŒÊÁ&¼¨Ñ¯êâotš®Š#üAØ„÷ÄèyÙÁ «¸D]"Œ®q¾DÃ&¼gF;änùBÔ%Ãè çK4l‹ŒŽŒÊÁ&¼¨Ñ¯êató%6áM]é*.VÝeÍ—hØ„7™Ñ)õe_ÁutYó%6áEFGFå`^ÔèWuñ7:MWÅþ lÂ{bô¼ì`Œ„U\¢.F×8_¢aÞ3£Çr·|!ê’at…ó%6áEFGFå`^ÔèWu‰0ºÆù ›ð¦Œ®t«î²æK4ÕÃÛØÆoÆpô —¢õº,®£Ëš/ÑTo?®F>þ‚ŒŽŒÊQ9¼mgf£»æú@´Ö|¨ÑeÍ—hꇗfô¼ì`Œ„U\¢.F×8_¢yËèvíÁìgF;änùBÔ%Ãè çK4o}zÓ¹«‹qFe†@F7¢æK4o=ÐÚþÊ@´Ö|¨ÑeÍ—h^5z·7ú÷Rë*.VÝeÍ—L^8–ŽƒÑƒÃ›]ïÉŒN©÷ø8¸Ž.k¾Dó’Ñ{jôÝj\ÊèJ32º¬ùMåðÎoˆ›^±w£³®½6­5jtYó%6á=1z^v0FÂ*.Q—£kœ/Ѱ ï™Ñã¹[¾uÕ¤¦.R_à"l‹Œ^6£×6ºÂù ›ð¢F¿ªK„Ñ5ΗhØ„7et¥«¸UWÝk]é|‰†Mx“Rï±Qö•ª×Ñk]é|‰†Mx‘Ñ‘ÑA9Ø„5úU]üNÓEê \„MxOŒž—Œ‘°ŠKÔ%ÂèçK4lÂ{fô¸Cî–/D]2Œ®p¾DÃ&¼ÈèÈè l‹ýª.F×8_¢aޔѕ®âbÕ]Ö|‰†Mx“Rï±Qö\G—5_¢a^dtdtP6áE~U£Ót‘úaÞ£çec$¬âu‰0ºÆù ›ðž=î»å Q— £+œ/Ѱ /2:2:(›ð¢F¿ªK„Ñ5ΗhØ„7et¥«¸Xu—5_¢aÞdF§Ô{l”}×ÑeÍ—hØ„”ƒMxQ£_ÕÅßè4]¤¾ÀEØ„÷ÄèyÙÁ «¸D]"Œ®q¾DÃ&¼gF;änùBÔ%Ãè çK4l‹ŒŽŒÊÁ&¼¨Ñ¯êató%6áM]é*.VÝeÍ—hØ„7™Ñ)õe_ÁutYó%6áEFGFå`^ÔèWuñ7:M©/p6á=1z^v0FÂ*.Q—£kœ/Ѱ ï™Ñã¹[¾uÉ0ºÂù ›ð"£#£ƒr° /jô«ºD]ã|‰†MxSFWºŠ‹UwYó%6áMftJ½ÇFÙWp]Ö|‰†Mx‘Ñ‘ÑA9Ø„5úU]üNÓEê \„MxOŒž—Œ‘°ŠKÔ%ÂèçK4lÂ{fô¸Cî–/D]2Œ®p¾DÃ&¼ÈèÈè l‹ýª.F×8_¢aޔѕ®âbÕ]Ö|‰†Mx“Rï±Qö\G—5_¢a^dtdtP6áE~U£Ót‘úaÞ£çec$¬âu‰0ºÆù°·›ÂIDAT ›ðž=î»å Q— £+œ/Ѱ /2záŒnÿÑÕÀ&¼¨Ñ¯ê"çæZ1Ô:_¢aޔѕ®âÖ]u¯˜ÑÕÎõË€êÃhl3ouíµlgûœ-“' ê"ûœ–k«é"õUý:ý¸½qéìÎéÈèÈèÌѯÓvf6ºó_wi Zk>¢.òáV+†jç FÏêÑ[¼³]øÚ_ˆ¿df &N@ÔE=Þêetš.R_5ÑózôFoƒÅg»ŸÄvÈÝò…¨‹ìsZ®­¦‹ÔWM`ô¼g£ûoû £kÌódôY©¯šÔŒáãHÉè*k>ÒƒžWjÅóÅP×KFŸ-Þîkôï/tô®â’tñÏèšçK\FO«pÇÛªûàv¿N´ˆÌÙ¾àsˆºÈ>§å¤jºH}Õ¤f ç-£ûëè-®£#£oºH}ÕDfF_¨<Œq>èúÌwÆ ®u}^/†˜/†º˜ ãÔèyÙÁ6gÒD]ü3:M©¯š £?Á™Ñã¹[¾u‘}NËIÕt‘úªIÍ>“a £#£“úª 2úœ]lm”€¨‹èóz1Ä|1ÔÅdi£gg¿e£ì+Xu8_Èè7Iftû±Ó•-e_!ê"ûœ–“ªé"õU“š1|&Ã@F¿¼EF dô'HftÁµQ¢.¢ÏëÅóÅP“aœ=/;ÃæLš€¨‹F§é"õUdô'83zÜ!wË¢.²Ïi9©š.R_5©ÃÇa2 dtdtR_5AF‚£‹­u}^/†˜/†º˜ #môììà·l”}«îç ý&ÉŒn?vº²e£ì+D]dŸÓrR5]¤¾jR3†ÃdÈè—·ÈèoŒþÉŒ.¸6J@ÔEôy½b¾êb2ŒS£çecØœIuñÏè4]¤¾j‚ŒþgF;änùBÔEö9-'UÓEê«&5cø8L†ŒŽŒNê«&ÈèOpbt±µQ¢.¢ÏëÅóÅP“a¤žü–²¯`Õ]à|!£ß$™ÑíÇNW¶l”}…¨‹ìsZNª¦‹ÔWMjÆðq˜ ýòý-ÑŸ ™Ñ×F ˆºˆ>¯CÌC]L†qjô¼ì`n$¾zTÕU3£Ót‘úª 2úœ=îpy+ÃèÕtÑòQE]¤¾jR3†ÃdÈèÈ褾j‚Œþ'F'ÔF"Œ^S¡¯šºH}ÕD´.&ÃH=;;ø­£×ÔU3£Ót‘úª 2ú$3ºýØéÊV€Ñ«ê¢å£ŠºH}Õ¤f ‡É0ÑKëBF¿ 2ú$3:©6âoôʺ}ÕÔEê«&ü¨L†qjô¼ì`n$¾zTÕU3£Ót‘úª‰h]L†qnô¸Ãå­ £WÓE˳u‘úª‰h]L†ŒŽŒNê«&¢u1Æ©Ñó2Œ^S¡¯šºH}ÕD´.&ÃH=û,ê·Œ^SWÍŒNÓEê«&¢u1ÆIF·;]Ù 0zU]´|TQ©¯šˆÖÅdÈè¥u!£ßF´.&Ã8É蔇£WÖE諦.R_5­‹É0Nžw57_=ªêª™ÑiºH}ÕDôqÈ&¼gF;\Þòp‚ººhù¨¢.R_5}² /2:2:sD‡lÂ{bôü“'¨­‹ÐWM]¤¾j"ú8dÞ”Ñi«<œ«î]¤¾j"ú8dÞdF·;]Ù2 p‚ººhù¨¢.R_5}² /2:2:sD‡l›Ì蔓'¨­‹ÐWM]¤¾j"ú8dÞ£çEÍÄWªºjftš.R_5}² ï™Ñã—·<œ ®.Z>ª¨‹ÔWMD‡l‹ŒŽŒÎÑÇ!›ðž=ÿÁ$À jë"ô%BW-DëzËècP3\ˆèÕÎXuÇ|UÓõšÑ‡_$3ºýØéÊ–àŠÓRU1ñ×UѺÞ2ºk>~Á%£Wœdt†™O«.F'=ˆ®8-UuÑú¡«¢u½et;Œö`ö£çEMå„N7D=]¦^F¯©‹4B¢u½eôqèMç..Æv¸¼­ )Uuó]õ­ë-£ZÛÇïÙdt¥™O«.ÒiˆÖõªÑ»½Ñ¿ ¤å"z€ }‘äC×3ºj!S× ÚÞìzOeô쳨ß\3óA×}]¤Ò­ë%£÷6Ôè»Õ¸”Ñãs¶ÔÓÎÛ ë ]õ­ë­ŒÞκöÚ@ù ë»¬zˆ~?Ç[Fÿ“1æ?è¡"ôE– ]÷uÕ¢ª®§£!ÅèygQsãDjêe>躯‹4Buçëáhˆ1zÜáò–*Úy›.ºîéªGU]OGCŒÑ‘ù ëOYõ@F‚“1æ?è¡"ôE– ]÷uÕ¢ª®§£!ÂèÙgQ¿%Ǫ^惮ûºH#¤!z¾D=þ1gK/íÜM‘ ]÷uÕCô|‰0ºä3iJ2t= ‹ þºž/F'=臡/²d躩‹ æºh}¥Ï‚³1fŸMÉÇ@½Ì]袃¿®‡çKŒÑã—·äøÒÎÝTÉÐuK1ìu==_bŒ.õLz&º «†.)FÏPãKê‹,º «Š.FÏ>‹ú-1À53tAW-]"Œÿ˜³¥Ç—vî¦H†.誤K„Ñ%ŸIS’¡ ºjéatÒƒ_R_dÉÐ]UtI1zTqyKÅÔËÐ]µt‰1zÜáò–_Ú¹›*º «‚.1F¯v&¥M Y²Ô ]²tI1zþƒ~N¤ôE•Lè‹xܰ×EkGŽF5]<æK„ѳϢ~{㜘Ö¦I&ê"9õ2_M]Ùý˜ßœ/FÌÙÞ8pHýåSU×hTÒ•¹ÿ¾'…óuˆIÎãëà™ð|F'œégtþº0_ŸNÿ½ŒNyÐω”¾¨’ }‘Î\æ«ä|Ñ$àlŒùgíÌý—n¨ÙˆUñÈa¯+|Êçë3ú¶CÙ­%µ»qàûË=×KЕ¿ ëÆy™òHžgcD†¸Ÿ!˜ëÊŸòùúÅŒžÿ Ÿ)}Q%C—z]DŸ?¬‹&¹©1RÏÚ„v6»Ÿy€ ë't!£HŽÑ~ìtek3÷ß÷Dé/èú ]dŸÒãëà™#2tÉÕ…Œ~àdŒùú9‘ÒU2t©×Eôùúh’ p6Æü³væþK7ÔlDº~C2úžÓ1ÚËl-©ÝºnmeèÊÐ_$Ï€³1"C@—P]äŒþ¤.)F'œ‰íh}Q%CtUÑE“\€Ô©g7B;›ÝÏ<@ Ð]Õt‰0zücÎÖfî¿ï‰Ò_>Ð]ß¶ëatÉgÒÐ]Õt‰0:éa‰íh}Q%CtUÑE“\€³1æŸÝ2÷_º¡žµ @tUÓ%Æèq‡²[KjwãÀ®[[躨KŒÑ¥žI@tUÓ%ÅèùKlGë‹*º «Š.šä¤ÆH=»ÚÙì~æR€.誦K„Ñãs¶6sÿ}O”þò.èú¶}\—£K>“&€.誦K„ÑIKlGë‹*º «Š.šäœ1ÿì–¹ÿÒ õ¬Mº «š.1F;”ÝZR»tÝÚB×E]bŒ.õLšº «š®×ŒÞ8ëÚk±¤‡%¶£õEº «š.šäû4®3m/ Dôjgè‚®jºÞ2ºkŒwû¥lgªœ­ÍÜߥ¿|  º¾m×õ’Ñ;Û…¯ý•ˆ>“&€.誦ë%£·Áâ³ÝObIKlGë‹tAW5]4É·iC¿ýu£›ü³[æþK7Ô³6è‚®jº^3zfFßv(»µ¤v7躵…®‹º^2úlñv_£ÊñŽÑçU÷Á½Ô;  þ:z»¿ŽPÈç;ã E¯ô„]²Ðª‹ ½so¡Ð% ­º¸0Å·?ßKÐ% ­º¸@‹oßvç;=ÔŠtZA×íV²¡Å·µÖ¹ì`ÑZÑ€®=Ðu¿•l||óÏozÓåÎ ­ èÚ]÷[ÉÆÇ7ÿüÖÙùí:MV_´V4 ktÝo%_Âùmûq Ó8duFkEº@×ýV²™âK9¿ù÷ÙM—ù¾®û­$Óµþ„Þý;iwY¢k¶Êºþh ]·[ g§Bil2—"w­úŒ÷9ZÑ€®/­ «ª.6„B¥·¶5}{ýíZ¹ëï]¤µ¢]_ZAWU]|˜^Ä´£õïDÌùŸk«ÞÙa,ÜŠtýÕ ºè­¤ÓÍóÿ,¸¾Ù¯‘jMw½Ô¡µ¢]ÿ·‚®;­Äã¿>á¿Ë¹«ÏÔŠp¿^Z+ÐõÑ ºn¶N3š¥Vi†ëïnÆ5RY÷ µ¢]ÇVÐu·•|ÖÅÎÞd¼_h‰TÞ}ˆ­ˆ@×èºßJ:Qjc¯ŸÞš%Ry÷  µ"]; ë~+é´k¹’ý&Â}È­ò®ÿZB×íV’imxÕÔfœHg÷ ·"]@×ýV¢éÃýò‰´o®Ÿßv÷ (ÞŠt€®û­à…÷MÆùm߀îòš­Õ  km]·[i`ü*dÆÍ»÷ ¸+Z«;@× tÝo¥ÞÎå|nÆñ¾WcEkuèŠ  ën+é4c׎vÌüºÝ}ú®ܵ5Z+еºî·’Nãæ­É#Ü7 o†ÑZëÆáâüÐZÑ€®=Ðu¿ÕoâïÐÚ±i³Î†´V5®û­j¢U/h7Äç}èºßª&ZuñAk„¡ë~«šhÕŇ9VmæŒøGºþoÅ­ºøÐ„ÿ0.K˜y­8]ÿ·âŒV]ÜðÖx'.è’…V]|èýzF}ÿ—ºd¡Uü¸úVß»Œ KZuqa¹COãÞÈÃ@—,´êâÂz'®Á½<‡.YhÕņ%¾­UövBè’…V]lh–øYŸ¸Áè’…V]¼ðñm­uÚVB KZuqÁÇ·±C¯í¨¡KZuq¡ çÑù74}Þ tÉB«.>L/”Æù=Iƒª·&A—,´êâÄü‰½º»èB—,´êbCXþð×2•­yB—,´êbƒÿÄιNÛš'tÉB«.>4ÖÙ±×·æ ]²Ðª‹}Û©\ó„.YhÕÅ ­kžÐ% ­ºØ uͺd¡UâšgÎ]}]²Ðª‹ ëš§¶»ú@—,´êâüæîö1ŠÖ<¡KZuñÁ¯y†WMÊîê]²Ðª‹ë]}´½j‚.YhÕÅ…~ù”ÊpWŸNÏ 'è’…V]\˜âÞ¨ÐO7X5¯› KZuqaz½Ô4fyÝ4ê¹” ]²Ðª‹ áÍW7B|µ¼ßºd¡UüÕ u#Ä·3jâ ]²Ðª‹]Óš_e@—,´êb…ÖøB—,´êâB«4¾Ð% ­ºØÐYetÉB«.>4J¯h@—,´ê„K½&ëý›$v;$wþûiý{¤¯7« ß‘eEÔ~à= òiœuë±ûaú¡ùóOo’œþÏ·Bý·sïÜnï¿Þ"y8ÄšCÞ¥õïá>ÍaÒz;Ãi]Ê«ø[ĉчãñ§nä3M"\·]˜ÇÞtv;ä»é'NOÎhø/K©÷èÇS£A4“Ch¸btw˜´¹«ÿ¯9P~<:ýmâ:8ý@ïÏ}Ûô!‡#¯FëAtNˆcãÌk¬#÷ çs?ÖéTnÇ6n§¯óK÷õ÷¾E¸éÈBë6 mgvŽOë»X1V ÿìDÆ¿}›×ô݇2wøiÑÉá…&3æœ=EqÍ!Fó_››ûõÑ|¸uï½ß(Ž|[ɼq—?.ãZŒ7 ÜŽûéO £Ç.¦fë„zå­•‰0öé¬ëGåÃ?}´NÕÍÇ»ÂÚ·ú<ÀxÊ F_‡Œ¾ý‚¾›…%ýáõygzÍàð± {æ” 225 2 225 1 2999 1 1687 ø7“@IDATxì ¼ÔÓÿÿ²‡l‘5´‘$‰ì¤BˆT¤,YS$!—²äK¾%¤$kE!…¾Ù¥DEQ‘¥²•}çëó?Ï÷÷wîÿsçÎ̹ÍÜ;sçu¹3wæó9Ÿóy~ÎúÞÎj1Ÿœ’ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€D¬ù¬" " " " " " " " " " " "`¤@PE(C@ „2Hô…ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ@ÊFð×_¹ÿüç?îÏ?ÿtüñ‡[{íµÝ:ë¬ãÖ]wÝ2EÉäØ2'ë H@€ºÇë¿ÿý¯[¹r¥Õ»š5kºÕW/«KË䨗ÒW" yH€vÆ Æ¡01ŧLŽ?Wÿ‹€¤&À6ÆäÕV[Í­¿þú6'äs4erlô¼býÌöfÌsàF?Æ‹ïjÔ¨áÖXc ·ÖZkÙçxΩxeò 296Õ5‹ý78†öÁ;sU欌[é<»ðìÿþûï £¤ÎP_R%ÊæÕ|æEY97œŸhž*Ïð[È›{ ¿àžÈsÍ5×,©ËÍ;\£*ßi—Üü2M0à¥$" " " •A RLŽf͚宿þz7wî\÷ý÷ßÛDøŒ3ÎpÆ +u¿™[êDý# 0Aÿúë¯Ý¨Q£Ü}÷Ýç>ýôS›¬ï°Ãî™gžqõë×/9+“cKNÒ¼'ð믿ºçŸÞ :Ô½ùæ›îÇt[l±…ëÝ»·»âŠ+J•?“cK¨D@Ê%€ÀlöìÙ6&?ûì³î»ï¾³sÎ=÷\÷üÃm¾ùæ%ydrlÉIEüë’%K¬¯›1c†õuüvÓM7u{íµ—;î¸ã\«V­\íÚµM[®LžA&Ç–wÝbþuЫ¯¾êFŽiÏò›o¾1¡|¯^½Ê´‘dœæÌ™ãyä÷å—_&;¤ÜïÛ´iã:wîìjÕªUæXæË¿ÿþ»ã:O>ù¤›?¾{ï½÷l¾asëÖ­[»Ž;ºÝvÛ-mÅ"o”&¬Ÿzê)7oÞ<·páB‡M6ÙÄò>à€,ï&Mš˜ =¥J™›¨â/~þùg7qâD÷ôÓOgTîµC‡ölP *‰€ˆ€ˆ€ˆ@® Tš…Ëûï¿ïN8á÷ÕW_™…ÙÆol‹Ä:uꔺÏLŽ-ubþÂé·ß~³Éntá[…EÒ¥#~úé'Þxã¶Xfa³Ùf›™ b4erlô¼ªúp,´°ÂSID 4úè—_~Ùyæ™&¬Äã!ÄÖ[o]JXÉY™[ú*U÷–™rr_J"Ï8^sÍ5î…^°q á$Vĸ7Ø`ƒREÏäØR'VÑ?a>ÈØÌ\£<ëíl“~àÅ_tƒv(2b­€‘×·ß~ëžxâ 7eÊS ôïßßí¿ÿþåZ1gò 296›÷^Ѽªòy¥*3ʃÚóÄÊœ6³¤ßpà SZòÛ²eËÜsÏ=ç>ùä“’ïÂÖZÜ;ïäË+QbMsÔQG•Q 0Ö ˜À0gôèÑ&Ø§Ž‘ã+y#ðG©ðàƒº³Ï>ÛÆß-·Ü²\ï Ê´bÅ wï½÷šå‹/¾()#Þ¿üò‹)0J?~¼ëÑ£‡;å”SÜV[m•èòú;Æm”$(zB;M×£¢aÆƙóò1±.áþ(ßzë­gïùXN•ID@D@D =‰g‹é›ÑQXs>úè£6!dò‹ ÷Øc5!.‹¬hÊäØèyUõ™t}úô± .Š¥ü"€¥1 XC]yå•®E‹¶ˆ‰·XÊäØ|¸K,7±Hc!uùå—»ž={æC±TÈ+#°Äz±^½z&¼<üðÊìø1(“cóá&±`d|0`€C Àx¤$ùL€ñŠ×6ÛlãºwïîN?ýt·ýöÛ[‘ãÇäLŽÍ‡{ž:uªûç?ÿiÊË.»Ìô•Q.ŒXð°Dy€—%Æ9û;øàƒ]ãÆÍëòwÞq”ï•W^1Á2žÀx|yä‘)…{™<ƒLŽ­ .å]£ªžWªr1&Á/”ܧvš½¶Ûn;S´¥:7ú[Ó¦MÝ…^è~øá‡è×ö¥cÅG}ä=ôP›—9ȱÇ{Ø8ýò½ýöÛVÏ'Ožlu§Y³f–sk”Ÿ}ö™)±P`|üñǶî£ýúõ³ß£ùE?“÷¢E‹Ü 7Üà~øaSpP)ã~ûíçðF€òqÒ¤Iîƒ>pƒ ²{$o”…švß}w×¶mÛ´ŒP2ì³Ï>å*ÿª’Ñî¼óNwØa‡9”•Ô_%Â%Pi \q™@b™²Ë.»˜JÀ¿XÌäØGU¾c…³|ùr»?SJùEK&¬î´ãuÀBlï½÷NXÈLŽM˜A|‰ ¡ *ʯ$"P–Â5„jXFî¹çžîÄO,9(~ Ê䨒Lªð}šÜ_4[I—¤h_ŒÉ¼#,#¼IݺuŸÉ± 3¨‚/™bù7`¼r2WÅá:/½ô’7nœõ(ØuéÒ¥”|7bÄwÇwXXÞñÄL6/Êädrl®XdšoU<¯òʈÕ6Ênx"|%äT²6’*/ï¼¥™3gšgøçŸnÞ(_|q¢Ã~‡§î„ Üã?n뺮]»ºK/½´ÌøÓ©S' ¿„B À{î¹ÇêÚ\Pª^F/‚y£§^¦ã”!ÑtÐAYøžë®»Î ÷ß¿y `DS¨û „Á ÅjuH~ø¡E`]¯$" " "PøÊ{B°‰¥àXX¤J™›*ý&õ‰ÏåÕ¿LŽ%?% @8¼‹ý°óÎ;§,t&ǦÌH?Š€”!€pÁ( AÖÉR&Ç&Ë£¾GNX"B¡ h½öÚkBÝDá“P \@`ŒG0‚]ö†u¢”É3ÈäØD×Òwÿ#@ûσö‘OeŒ¦ð\ÀsA=ûØáÕ›Hy•ÔÅP/¨'5kÖ´ç–î±ñ¬ªúÇuCÛ¢ÎroÔÅhÛªì ãÙèÈ&úgê8õžöƒ‡âÇp,çÑWê‡vBÛ í„¾ž>„¾:Ýc¹n4Ñþƒ8Ÿ1ˆÊF_?fEÏ Ÿ)k°:M·ãZì@ŸÆ¹$Êî1(ôqá:zlˆÎ™Â¼‹1™¶Ä;í)>Ñ>xQ?y'Ñ6©¿´KΡ3®grlô:”%ÌSC;"_ò¤-R¶òæ„¡óÐׄ¹n¢öÌuÃñ\Ÿÿi‹´ÏÐ919ÛÂ`„®l˜L¸ö< ÷[^Úm·ÝÜÁ~öC@¨KÌ}½¡Ëädrl´\ùü¼¨+<óŠ>/Æ›0O£.D×䛨‘sh|&ñm#U=¯#T/ø°ßA2ï€ès¦Nxরboê ( ¢‰|§OŸn¬PNPËKp%ê2aŸXsÑfõAååU~¯Hý‹¿ÿЯ1¿ “B»ó¦øs¸.u–sy§? s°ÐRÿËkœCÔ®æR‰ÚM(ó0úýÐ×s>}0å§^ð}ªóC>zHL ´$ñ16ø#|yýõ×ÝøñãÝ{ï½g›c±I“6,˜ÚµkWf“-&X’`Å„˜ ·˜`é„û4‰ýÌ3Ï´•Ò=6X£0AüòË/Ý´iÓÜC=ä–.]ê¾þúkï¸ãŽV¦cŽ9ÆòN¶`bÃäbþüùîpï¾û®Å’ÆJ†X”ÜÛÑGpC+&ô´óaBbòîÉk]×—¸ J'À¤‹'6ScC9XóìÙKƒÅ –v|f‚MìyÀó¡Îq>‰zŒ+5J&¥œwî¹çÚþé®Q•õ¶År„,@XA [&íÄ£Eˆ@â‰óžÎ,Ü“ÞE  ÐÖè[iÿlšHÀÿ„vhÞ¼¹ 9ä³@Œ–Ÿ>š0 „è ?`ƒ{˜O?ý´í[ñäqòÉ'Û¹éË&Ž$ÆŒ'N´xâŒA$„ !4aûhÉ}Y>öØc&Ìc¿ ÆFYGq„kРA™>nÉ’%î–[n1åÂ… ­<´ÿ0ÑÇ!Ü9û쳓]Zß‹@F¨óŒ9œi/óæÍ³ñ§V­ZŽp"´Ãƒ½ vwqs5B“ÐfÞxã ».m“ñŒñ bæ[Ì»Ò=ö€()?óLæpŒ‹Ó½’qŸ¶Å¦ªÌU™’7ó»dÂEæä™·òbƒVòÅš±KgæÏ¢‰kq]Ú!s]æ´ÅQ£Fٸ̱´Eæ+ÙÞH”y0!ŒŒÑ2wM'Ñ?° +÷EŸÈ½Ò¯2·/ÖçÅ~Ì£Hžjlƒ 6ˆù‰Y¬víÚ1¿8ŒyIÌOb^£óBؘŸP–ÊË ob>ÆjÌo\ó ¶˜ŸüÆ|‘,¾ãåcQÇü2–ɱ\„r}òÉ'1?¹ù‰DÌ/<­L~‘gå󄘟ÔļkkÌ+J•+ú_,Åó“r+÷ä'U1?a‰‘÷æ±Ï>û,zš}ö F;ÎOfŒ ÷æ¥v_Ü›_„żb¥Ìyú"}^(ó §˜_,Ùsö‹ ãÊó»ŸÌZò“͘Ÿ¤–ÊØOvKžõ#<òàù‡Ú9™Ë U]ÿü$;võÕWÛ}ж¨ë´/Ô(¹g/pŒyK¯RLôoAf}ý…^hã u<ŒA¼‡ÿ} f«¢÷çì±=zX› §¿ˆo'Þ*2æ5±LŽ ×ð‹ÛØÍ7ßlcc#ã‡Zß®Çxrûí·Ç¼\8­Ô;ß?õÔS1/X±vL{f|åEÇýyáHÌ ]b~\ê\oÅi×âÆ*ú8oå\Òã—’d‹€ ņ Ûi§lNÇXZ§N—™#2'¤Îy!RÌ[‚–\Ö æc×_}ɘ孨KæƒÔsòñ ˆØ˜1cb™.@ÛðF ±]wÝÕÚ9ùÑö|ìxkG´OÚd¿~ýÎçȇëzAYì„N°û`Ƚ‘} yx£ƒ˜W Øœ5\›÷9sæÄ¼pÊîÌ—™{P^Ì7¼r!zZV>{㛘èÙµ†šQžÌ£O=õT{Ü·¸Ùù™<ƒLŽ …Ë×çÅ3Ïë”SN©Ðó mÄ2Y¡~3ßdM@Ý ø}¬À.$ÚKh#œC}£O§­ÐÇS.Úˆˆ†SVéÝ[ûÇ|+ËÿÆoL+/Æ«K.¹ÄÊår)×W‰2ô›(ÇX§ÁbäÈ‘¥!oopey³¶óŠùR¿W×X;ŸsÎ9vßô¬-W%¥[ÿ¼¢ÔÖ2‰®EûôF1oü`õuu˜þ~Ô+‡c~Cöu(~^Ây^‘iõ•:Ìœ‹õX{Q‘)xET©Ksß}úô±þšvB¡ïåšÌoèK9õ8óÂø„a¿ýö3ŽŒ^hí…ymŽ~›µ“’ˆ€ˆ€ˆ@Å ”6ð3Õø„åÕ„ lƒ,?i0k?©6ˬ´°2ðBw÷Ýw»o¿ý¶Ä„|¼àÃtÒIÎèfU0|øpGlʃ:ÈùÉ’]ÊO.̲—ÜtåD¬H±*ÀšÍO2l-¬­)#×À›K"¬Üü„Ä,ÃüÂÀ®þpoX|â!Ày:t0kt6à 7[ÊÌu°*}ðÁKYù ¾ó`³žÃíÖ ‰ÌÒ Öw›o¾y¸œÞ3$૵[¶l™=,Zx.XPŸüdÒ, ýbÙž÷i§æîºë.³ —¡^Œ=Ú\`±Ba“7žó Aƒ¬Îð|ÂÆt™KþU]ÿh/Ä9Æ¢ —`¬Ó¨³;wvÇ{¬! ma¨$…L Œ+^Poí‹Ð.]º˜E0–úx&ñºí¶Ûlœñ‚’ðô¿~Aî°\ó‹N³NÃSÿ/Hô XRb‘œî±œ‡µc M$,ÛðfbƒfÆ ¬—ñØÃkbذaÎ/‚mŒ±ƒÿïyë™1hÑ¢EfqÙ«W/³²£cyÊ„õŸW 8ú;â–‡„WcÖÎ\oܸqæ©pÝu×Ù!„LñJ„p¸ÞE`•‚¶æÖÖ°„îÖ­›yòa1¥*óEæL̯®¸âŠ’ Ëi_ŒM´ŽÅkKëV­Z9/¸6«P/42«ÑLŽ 7D;‹/#昴#¬´)‡îÛoXµ2W¥_èÝ»·Y+‡óyÇ ˆ¶Ê}ж¸7¼¼àËâ½ßwß}Vf6(&4›Çb‘K·oß¾6¥-Â6Ͻ1N“¼BüRíŸ,þÁJ—s\/dË(gú?^$<¶x‘2y™k™û?ùú¼[ð¤!1? ÞföE𶬴CaÞˆ§Zh#Xfÿãÿ°:OÖÌI£m„ãXËàÕC¹¼Ô,¸ñL«ªê×§®Å¯«Ê+W¨oX‰‡ºÎa.Kþ¤Šäò)äw¼»X[³þI–¨p§ÝŧLêžúx'z~|6æµyÕUW™ž ¬ûéOé÷—ÆÚjº÷òây1Á%”‡=)˜q/#FŒ°¨x,°Ÿ…WÄÚµðþ¦_ ‰¶€‡súTd¬ÉéWñva}G¿Ì܆qˆ¹VÈ+ä}Ç Œ¶Ã|òÓ†¡…\BID@D@D`¤Ò= áNJ̇á1+H,#ü¸Ô)~‚󎋯ɓ'—ú=üƒ%X\tÑEáë„ïé‹Å–X)$ÊÏ Tb °ßý$æ]ËK] r,­¼PÚ,È#Þ‚ÿ½‚ÁòÀÈ ƒJåþÁjÆO¦Ìêk)e‡–"×\sY¯À Üh¢~úEˆYçbuë…‚1/,ˆbŸ±êònáö|°ÈMeÝ“î±ùTÿ°"ò.ÅfD[TêB€öH»§ÝbµæCó”±äÇÚÎ+ÐÌò6/¼Kxû>´IÌ +ÍKÀ/n¾LçX¬Ý¼ÒÂú<h‡ÑDÙñŒbüÄzÙ/Ô£?ÛgÎÁ"šþˇ´ˆùð'eŽñJ +7c§D•¹NÀ“Î+F­¯Ä¢TIrAÀ‡-2¯J¬I½Ò>æ…õ¥.Ãøë 7¬ÎãCûÀ‹0>Q_Ï;ï/ŒˆÝcø=¼c ÍXÆuèãØCHI*›€¦[ìr¼-ikÌû¨›Ñ„×±­±öô‚d««aOžèq¹øìÃhØ~ÌýYác‹µ­7q§Ÿ~ºy0EËA¼mb³{ƒó:ÀK‰6MX¤·oßÞö`Xöo Wu‰ù7ž™¼2IÌ¡a†e.ób^•‘ªãóÂú›= Êk#ì£Añró2#¶|¡¤P×(oEêu zR|}#o^$æý™Öe;±Àÿ°®¡ßIõ –þñ·šiýcýË^3Áë#ä‡å>s ú6ÖWxäÐODõ—5}-7^Hý9£ÏxÉY^Œ!Ô“hâúôߌ=ìùöÌ3Ϙ§gô˜ègæŽì͈禙ýIŸE@D@D@V@Jƒ:å±(ôÖ‘%á^â¯Ç@ß½{wÛÄ•{rÍà-xl±ç-¦Lp„0'*8òpò×K„LÑĽáÖÎc„?œÿB‰@È ¸Ü²y˜Rî ¬@ðà­›l!'Q u“$„*@PIõ¯2(çÇ5Pf!ì@°ÄÿÓMK]¦o çÇŸ›Î1ñçËÿ„8`LÁÕÐe„K”ìÒ ›˜Òoä:Ñ÷¢„…-Š 6!%u$$Êò“P.ñ›Ò_‚‰²¢@`œ‰øAJn\þáá÷ô Ùë]*¡ÄðÐÆ¨Ëñõ9„/lhJx æL(É*#RÒ[œÚõ˜Û!œ¥ß~„n„\",óY”Ñ„Œí Åí;Q{$“ßgÁBvúý,S4ŸªøÌ|„~(å3-ó[î•ù.¯ÊHÕñyeÒF0jbBû Jb< ÂäŠÔ7ê/K‰Ö· 4‡EEò.†©Ê‰ðÜïcáwä'zaP/`'ÏLëë_¡œM̹˜k–ˆþ.úŒ¢Ç1çbî…Œ¾gV‘„B€pµÌ•™1v$ê{YÇ3î ´`D“%æTm 'PÈÒæUqù2ÉcAÅäa=öˆûõÿÿË$E‰ ±¦™Tä21ña¢Å9ñ‰Së7¨sÞÝÒ<°R ¯Då œLx˜Ä2iM&” Â=òà&9LL”rK Ô=že¬“%ê“\&±Ô½ÊHÅTÿh¿C[w1$CXf!ˆ¢n±Èò®Ó¶ Gêe*Ôa¬ °l¥¯Aȃ` o­Ò9&[ŒïÙY\–× DÈNâ¸'S6d‹#ã ‚D,âØ£Å»Ê›U6ÆCÊÆ  p‰^›6EÅo¼¨#ÉDZhæÞˆ¬$•M€¾ó%úÁTí Á(¿s|*!O6ï9ý+{+°GýnðL"Æ7 ¬ìé‡%úw^(ýxO6'¤ÏF¸E 1Ûy<$ºF®¾ qåa)oæµìIAß‚PŸWe¤êø¼B¡Ž±BÁœ,Ñ>h'«Z î›E% E6ûK%ØB‘ƒõ1e§O¯Œ~š> EÁM7ÝdõÄÇ ¶MšÙô¡ϹM›6¶¡+ mÆÑh迌•# …Âå%ç…$l*ï~ô{á@¨Ž€Š¾ŒWª1™þÁ6™ ´+J/D6F¦ÀÈÇÔ¶ðg(ûi§l¬Üºukçãv›’~<$úbî¶…÷á;¢m5}g@fZÕ)(è÷2åMŸÏ‹DZYÛêø¼¨C´ÚGT0ž¨~Ð>h'Ìs3}f‰ò«¬ïB]ãzAɵC}£žQߢ‰¼Cý£-—è}TÕçLëó ú æL!±†fÎÅw̹R)x~ôƒ¤ø|B~é¼3¢/Ż͑Ëë{ÉeCÔÛ3þ:=†ºÿ›þ¨8¤ T æ Ð, É¢—e’ÁD‚óúTFb‚N|F<Æg?,…‰¡IÜl¿é±Yr°¿Ç„{÷†…1åFЃ€ª¼Äõä}P¥ìüÎ$–ÅC:uÉ& ¶Ê¬{Üe±Ô?B¬G”û½øâ‹«½€ßàÑÃÔC»( PRªÓ‹/¾h ¿É·ÅY }K¨ýô~ÓNs?÷›zÚ¢ÁU4”Z:Ç„ü*ã0 (Sì°oLU'ë„~B™HOµ ýÇðÌRY¦eó¾xî(ªyÆ,\b¹ŒðƒÐÄÃFHÔÝ+ŽðPˆÆâ徦Pv,Uã÷xITN„ž©¼£ïD hS¼¨ƒx!¤J´C^ÔñTBžTyTä7Ú†ßPØr=ö˜C©‡0Œ01o¼ñ†)øðJð´š"!((#ý1JTæxôÕ©–¡l\/”­A¨Ëü—¾îáÞBY“½3¾‡oÜs:÷,¯L¿¯nÏ+´ÚGyüC¡îñ¼ %Qß©oŒ[A`nÙ›Ù…9V¢ºê1ys ¯ty‡:°MGnÞ…r\¦õzÊ: v!‘ʾ+#uœ9J[΋æòKçym€ò°·B*ƒÅõ0U_E™”D@D@D@²O é* 2fYT¥ŠýàA ~6¶­¬Ä$q§v² ž™¼° ‚bG¾ýöÛ&¼C¹K#)ÜQ,WûõëgãUV™uò 0ùÃb!"!d¨c<·D‰cxîL>+³îQ–b¨áYÐðªÎ‰E B'¬ÊYõèÑÃ6ÝŒ†*ÂÒ +s<Ÿð0`…‚2šè—xËB, :vìèØ‡%>¥sLü9¹úŸöÅÞ5Ý’í7’«k'Ë—zÇ„¥‚É}?ãB@ž[ªÐÉòX•ï±Äãó¢o¾ù¦)™ØèÏwÜq‡ öFŒQöŠÅ9 %ÊË¢¥•’ä+Ú"s&,î©ã©Æd~çµ(®¬ûÂã€Mjy!à o2”{(igÜÃÀKB#Ò¹?ÞQ0À6­¬2¯êu˜w‡g²hÑ" ¹Š¦Ê›ã‰wξ1ô·„Oá™UfªNÏ‹öA=¢î¯Žd,CaŽPÙÌ“•)ï©oÜ+žßàÝÃü»¼Ä\žúƪ~ýúVߢç02ïG8L»%”ÍÁ~¿’ò”1ä2ã¹çž³µ(Êx”õŦDÈ´þ¡¼b®÷häCÀœ+(eÂïÑw”ÔcÖ`ñùD+ï3ó ú^ò¸úê«Þ+‰€ˆ€ˆ€ä'ÕS+dQ Ê(YŠþÎD/kþdyeú}ÔâÉ"‹¨:¸[o½Õ„a 4°‰ü½÷Þ[*kÊI_†¸Ù§J,²XprŸJ•C Ô=žoy®Ì<,Ã+»îA¢ê™S¦L1ž|.çª.ñBL´ù3Ï<Ó”‹Qå×e‹›5¿ãzýÀ”±xgA…0›ÅXÔê•'Ü3‚A¥U#ÀóÙa‡l1˳f‘’(1‰Äš‰p1ÔWF•‘òµþåBÉ×&Mš˜µf|/øÃ"+øa)‹ãTB&ÚmŽ>…Ï$Ú‹ÜÖyy&{žœÇµÃµ°øKÕ>i—‰ÊJÿE¢,,pŸxâ [ØbMžÌª%¡0Xü³pî6$ÊD>0 ,üÏ}ð?צ éc™ýßÎçÞà„éô1Ô8rŒÂõ£yó™¼`žÿS^^|W• a<ýåçÙ$ë§ñ@ÂÊ«9Ñ(’sà‹+Ì ¼ˆ¿&c!c tøG• ,˜YtSÇȇñ%Y¢M Ä›:ujI¸‘dÇò}:õ#ÕùúMâ Ð×!|§auL¸œD‰zμŒMÁ9žW®õa8m‘ya¢qáú¾ûîk›ž‡¾4Z.ÊI¿™{K”ÇӯϘ1Ã=üðÃvlª¶ÆxÈ+׉¾dÿý÷·M¤é‹˜/ñ R]›û@ÙÀ܉ùòá‡náØr]Vò¯®Ï+ÚF¨C´“D‰6òî»ïZý©¬6’¨ýŽÐSÔ7ƵW^yÅý©æ^ÌyPÌÑnðvA©wÄG$Ü(˜¼8ೂ'ïgŸ}Öæ"©ÊŠœãÙ¸8ôÇÑã²ý¥4{ƒ°GueM|¢Ü´ʈákH,º‰µÞ¬Y3«›ôq‰ž)ãíŠP{XR5*dQòN}$oê ypM%È&rÍ›77*B1oŠW0Ò6Qôñ;u‘ú¡F®B,úB±¹=ýAü@‚2•¶B{Œ&Úáž{îi ú¼ñóJþÇ"ƒ<‹è_¹v|"o^ôü*#Qöƒ>Ø„<ƉdÊ”0‡!ãÏBe({`Q]Ÿm„çÀÜ®<‡x¥7ý9ÊâÐFvc¨UH 3B~îæ6Ï?ÿ¼)Éãïƒ6Ãó9r¤ywÒ.Ó {”(á5ĘڲeK[‘7ÊsƵø6ÍÿÌù…ó:ænœ[Œ)Óúkú ÑD_€PŸ93óYæ¸ñìéK™¿3×`szŒ‹˜‡Ä'úZ¾z+ÄC{Ákãæ(‚âçyœC ±ŸÔE]dk€ø¼ô¿ˆ€ˆ€ˆ@n ¤ ZÉä‚X’Ä#Dxsà 7˜•“]&ñ˜`0³Pa"̦ƹN\›8£ ##ln—XK#Q\YʃðšIV»,>,r &Ï$M¬¢åÑç²°HÁA/0·Ýv›;ûì³Kâu"œåù2Ä<_XгF®S¾Õ?ê;õú>sæÌ‹ ÊI½Ke”+&í-±ðB¡Ã$ŸÄŸÍ)¢Â…Ïu×]g“üÐZ#@çÙ…ó8—Å ¬Òh³(X¨ÐVÈ—¶Ç¹´Köˆ&„,¾ÙÀ˜2‘/÷H»£œ arH,â9–ï»û mY° ôe!Ü­[7;Œ>ƒD„²ˆï/B>Ñwú úƒp¿±ÐBŒ""x°æÞ¨›<'ZåS×{O!xBÏ}Ò‡Á†gúÈ#X¹”!P޾,èî¾ûncN™T³øcM8%ž‚6¸Ãa >ó¢½-ñý: }„xZTU£MŠD"¤±H¦¿‡Ïå6Œ¨KÄ=O´ßD.ÊOÛ‚+Ïå V•'žx¢=ÆE(¹PPñ™0Œ/ÑD=<ùä“MáFýå¹uíÚÕžüc¹o„£(Ÿ¨—ñûmÏ’ü)P:!¤á{ÊHýÑ%¯Ï!€‡¾ÅkèOBüsæ:(éƒéó÷ÙgÛ`¾2³ÐÇÑÆP¸Ò×ÒÏ!d¢ÿm¥5í‚q’¾˜>6š8‡¾†1”òóÿYges^Æ3òGXʽcáOÄ=FÇ™cF*xa ücîH9hÓäÅ+Û ƒÚ<ý!Êyú ÆYæP(»¹>c+}&óy¼ÀƒñŽ>…¹pe¥|~^Ôê4ã*Ï‹¾œ±&ÝÚ†GŒÕÔ#âðcBP”áôçíÚµ+¸F° ìŒ…=FwXÿQy¾0c>Á #æ<(Ùi ŒÓ´Íd‰y&ó<8PH2ocü;î¸ãÌR¼×hÓž Ðc¿”•ìuWh ™d*ò}&õ#:ú0žW4¡P¤ ÐÝwß}ÖWROéÓè癟³Oý$shæÿÔóD‰þŸ¶Äs$?<hSamæ%Ì{X‹3Og¯(ÊDˆ+ŽåY3Ïf><Ý+åøŸºWÑÝ“¾b&Pî*†ÅÅ@/hcbÈ„ Âqn„mLÞ"²@Á Y®“G1½{÷6á1G¼˜¤ãþÊ$‡ïˆMÎD§qãÆî´ÓN+S,Ü M„f„š8餓\½zõlဒB&´Lb%&8Ü? I„Iã˜ø"\dÁ@¾pTÊŒB/&­Ø0_{íµ6Ád‚ÌB˜g†ÐÅ8VG,ö+#å[ýcrNýD¨u$J´Ú)Ù¹L, ûCx•ð ͳ=z´)ø¶Ÿ°^uÕUö<û÷ïo–c(†X(° :UÚ6uĶ…2“6NÀ~XNrïx0 x`‘ƒb‰E{4Ñq¦o Ü Ÿ` ‡ÀE(<ÓzQ&®KÿÀâ™w„J¹±Ng/¬òè;©ÇäËó þ”w õ›ûá8]ý©ãÜ?J3îŸùn»ífÏ:Ü#ý48 Ð½òÊ+Ͳ‹{£/cÑGphäÇ=°˜çY±p£/¤¾\ýõ¶ÀCVÕ‰þøâ‹/¶{ÁÓƒçß¾}{ëSñž`A oXœqÆi=»lÜz\ õ˜±„:‹õ#¿!¼ƒ+–¨( ¨ÇÔhBIŠÀƒ¾ŒçÃæ­,Ê©“üF¾llÍËbš¾eJ|B¹ÄD½…ÏA×ã7„:ä§$«BÁ;ûà B©Ïœ¡;ßÅ /æBÌéc*#ÑOÑŽ¨ó(óPb Œâú´„æôÅ(˜¯á©ÈXŸèû–xå)›žÓG2Vp,÷ƒ ”öða=©ÉÆVÚ;ý6}ãJ]æ¡MñtÈ•€“{êÓ§ n¹W·ð@¹O_ÀøyŒ1ýº{…ú©§žj‚Àx¹ú?ŸŸ×}^`Ê<…0}f¦Ï Î'œp‚Õ#ÚŠ~”n´,ñy.x2w`®TYm$ÛÏ’6@½anA{cŒâ^1 ¡¾ñŒQ.àñI߀ œ0‡O•˜—`ØÐåkM Řó0þ1°…5ið¢S÷aŠâ§XS&õù/sõD©gÏž6f>É3c.à ¯3ê5F2p&ñsí'uõ/Êeæ7Ì…1¢á;”IÁûçÊŽ>êÑGµçŠ'ótúo®Ï\~‹5µæ4°ÞE@D@D ’ xT¹É Ýb~²óݘWÄü¤:æ­b~‚hÿ{IÌ/RRæã'1/üˆùEUÌO"²r¬·f‰yXÌOÌc^óS+—Ÿ¨ÆüB-æ=b~²óVVI¯ç'#1/ˆŒùÉˆÝ çq~Èà ‚b^aó Á¤yðeñaW,¸À‡—~»”'ëÇ”¼@9æ-Œc~Ñó“M{ÎáùPŸ¼#æ÷Ióð‚ݘ_´Åü‚-æ'©1/$ÎʱùRÿ¼°Üê§X;ð ;«{^˜;ýôÓ“Þkº?øEoÌ[ƒY{òÖ”%§ÁÕOè jóVá1¿Èˆñ¬BZºtiÌ/.ì7/\ _Û»_ôżð%æ•?1ú¯ˆ,ù6é…=1îÃ+Fb^ Sò›·8‹y¡ºõ=^ð£oŠ&/ty‹ª˜_üÇü"§ä'¿Èy¥•Õ ðc^@[¦M{Áõ%^`󂨒sS} ^y­Ýƒ—ê½£b^èmùyKÝ’ï£RCݺóÎ;­¯õBýèi1oeó®˜_´‹è^m÷ï…U¥˜r çùÅ}Œzá­RK±£Áœvå•­Ñ,óâ³_´ÚC} ÓÇRVÆ"úyúïTý<7á1/\ˆÁÆ[禼¯tõ Û˜WÜÅüBØê9å¡\¼(#¬©O>ÔIÌ C’^Ó ¬b^Aó‹ùR}yж{½00FÛH–¨^ad|¢c¡ÖÄ¢í6Ùùú^Ò%à+b^‘ó‚u›kÑWS矩oÞú:æAI³óá/bÞ Ãê¶ Zß”ìàLŽõÂñ˜jƘ·ÑÃXHÙ¼À*æ÷1Ž2æ›É.ó‚ɘTÆ|xk¿¡¯ ÷ÇØÂ¼Ó+’æAå­ÌízÑ>s‡r¼'æ×1/L´9ýãsRæÊÌã½07æÃ?¦ì—B93y™[Ï˯ ½‡6k˜ó ¨CŒ ôçÔƒTm„9-m„ñîŠ+®ˆ1÷Év¢Œ¬ow˜WU$Ñ^¼ÑFÉH{¡®ñ c õùPªv—èÚŒ™^óF%k«7Ö¿`ÌxDÛ a=‡µe¨É®Ç÷ï$æƒXP“èsðhã™}™£?p£¿#LsZú/Ð5ï]æíô åõ™¡h™<ƒLŽ%ÿ|}^Œ‰x¿1–VôyÑF°gÌÂkþôçXl3I•œ7´Ê’íÐWÌÑh‡Œ«´AêuEõ‹ñyíŽ6D?@]ã…WãQE够ñBqëk˜ûЦaKæô?…šÂ³¦Ž°>æYW”U”ÁªÔ¿íïê0ónæ Ìw mL–Ìó œÏ;yà=Š×B˜—°vÃkŒ”ñ‰úȵè{©Ÿ¬×¨?x,Ч+XÃs>ëC<ÇÊëë㯭ÿE@D@D@RH[:ý*"P] ”§@À•˜Pí£ Á ñÿ á“L€0—ðT, ¢ Áçñ{T˜Ïâ…y_}õÕ¶@ˆž‡ð‚E,!P.àZO Â5àMžÞz-zª-VÈ›Ånó,VR% „Åàþ9Wï°°I¥y–wLÑÄ;ŠP”,”£8@QuÕg±H¸ 6,Ìâ$\ALXì{‹Ë÷… @ œJ" " " " " " " " •K Få^NWŠÀò ËPàì,aé‡" >¡4@¯<à8¬œ°XÂÚŠÍ2ËKäÇXXŠåAyç¥û;VhlÌ&îX‘â‘ÀµØÿ 6Äb0Xª6X¡ã‰€ÅW²„åÞJ" " " " " " " " "Š€©èè7¼$€K<›jG-ð£%¼!œ¥d¡'|l]s¹›â₟,òEOx‚p^¢k­Êw(|œX σç›/âÂ[7›$ûøÕæiGEHxà~Ê)§Øæ¦áûøw<ØtPID@D@D@D@D@D@D@D@R!ý&"WðÀÚá:ñ¬Å…Gðw@ª}.Ý1uÙOƒðF„&"œ‘ß /Ñ¡ò‡8¿S§NµX¼(4r‘Pªˆ¸Û¼øŸ}#ü†‡nôèѶÏ1š‰ó<(PzàIU,„²q>±ö9&Ûáz¨>V¯>·¢;¨î°œg³?âýã)ŸØ|˜Íר ˜PG™$6áÛgŸ}ÌâŸÍš'L˜`Âöø<³7Õ²9%!‘Ú·oØ*ýÏ^l6÷ᇖ 5„÷²). < Â}â ÁFs„2‚ïñ‰K(=ØèEB|âÞPÀ(‰€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ¤@P=(XÖ³i1ß{ï½&Èo„îôÙ\ùâ‹/vwÝuWÆ÷µí¶ÛºO<ѱÀ˜1clŸþÙ­\¹Ò¬ÿñlX±b……4hcŸ<P>d3±›R·mÛÖ< Øá>‰ûüí·ßÌ‹ F%{=à•Áþ»í¶›)7Ø!ìÁ¹„\â»ÓO?Ý]rÉ%nÉ’%–PLž \›ü•D@D@D@D@D@D@D@D@D@!ŒTD@ †‚ú<ÐÂMŸ>Ý 8ÐõêÕËÂ÷Úσ§žzÊ~?þøã3¾/6WîСƒ… ºóÎ;]Ïž=MAЪU+ÛSañâÅ&„衇,´ÐÑGí;ì°Œ¯SÞ ›nº©Ý'ûŒ5ÊB5í·ß~®fÍšîóÏ?·0K(6ºvíj!?<ºwïîú÷ïo0ã‘Ñ¢E S̘1ÃÝqÇ–á4hN³w®‰7ÅÇì¦L™â¸›6תUËÞK¬D@D@D@D@D@D@D@D@Š‚€Eñ˜u“"PqX§#¸GL¬ýh"Ž>¡tŸŸ8/ ã'òIJ?>Oò ¿#ÿÁ7›ãi0~üxSÚè›o¾1+zöF¸òÊ+Í?”)UYÂ1á}°Ðg¯…[o½Õ >Ü 2Ä,ÿ±ÒÇÒ¿nݺîÜsÏuݺu³k†sÃ;–üÜ3 $J©Ža?ƒC9Ä7Üpƒ»ôÒKí:ìùðý÷ß[˜¡Ö­[›‚ƒ{ ¦(@à£sÎ9Ç”+xi p`ƒe”}ûö §”¼×®]Û”!ì¯pÞyç™Ò¢Q£F–ïJ" " " " " " " " ÅG`5Úâq1ŠïÞuÇ" i άY³,Ö>áƒÂÆÅtÄÔÇâ—]v1K÷hv­—.]ê^~ùe×°aC·×^{•üL8âðÿúë¯ë~íÑÄïsæÌ1Ëùƒ>Ø”ÑßùÌ>,2å@IDAT/¾ø¢{ë­·Ì*à 74 zʈ <šBYØ·€0?Í›7þœð3{`?oÞ<7þ|»B5mÚÔî¥~ýú Ïã˰ÁG}d\vÜqÇ2Ǧs ŠÎ;×ö|`ïlöÌæÉ(N%žÙûï¿ïð:`?î…½PJðâ•2!B7Á}Ú´iʈ{$ä×T(>R ß3׋€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ@¹´‰r¹ˆt€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€)Šï™ëŽE@D@D@D@D@D@D@D@D@D@D \R ”‹Hˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ@ñ¡øž¹îXD@D@D@D@D@D@D@D@D@D@Ê% B¹ˆt€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€)Šï™ëŽE@D@D@D@D@D@D@D@D@D@D \R ”‹Hˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ@ñ¡øž¹îXD@D@D@D@D@D@D@D@D@D@Ê% B¹ˆt€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€'¿þúËñR(N5Šó¶u×" " " " " " " åX´h‘ûý÷ßÝŽ;îèjÕªåV_]vˆå1Óï" " "PôÈÄÒ¥KÝgŸ}Vž‰î¥€¨ÐÃRQE@D@ª%üÑæƒ?üðCµ¼¿B¾)=›B~z*»üÀÊ•+ÝÈ‘#]»víܸqãÜO?ý$4" " " EF  (êÖ­ëößÿ"{lºÝ|! :˜/OBå(VÆ ³ù ïJùE@Ï&¿ž‡J#!€÷Á¬Y³,„ÑÎ;ïì6Ø`ƒŠd£sD@D@D@ ˜@A+ ˜»Š." " " " " " yKoë‡~Ø}úé§î¨£Žrõë×wk¬±FÞ–WÈ )rÃU¹Š€ˆ€ÿüç?:eùòåEp·ºEb"ðÅ_¸iÓ¦¹ß~û͵oßÞÕ©S§˜n_÷*" " "ð¤@PU ˜3gŽ…NéÒ¥KsÐi" " " "b±˜›4i’ûä“O\«V­\“&MÜÚk¯U‰D@D@D@rN@ „œ#ÖD@D@D@D@D@D@D p°1ý“O>éx?æ˜cÜV[mU8…WIE@D@D@²J@ „¬âTf" Ù aaþþûo÷Çdãvr–G>pÊÙÍ)c*#0eÊ÷Á¸¦M›º–-[ºš5kVYYtaª% BÕò×ÕE@¨ê°0(–,Yâ{ì1·bÅŠ%̯ªšS~PP)D@D@D@D@²Ià÷ßw(¾úê+שS'·õÖ[g3{å%" " "P`¤@(°¦âŠ€äžÀçŸîn¿ýv׫W/7dÈG X¥Ü€3^lÔ÷çŸfÄsÿûßÿº_ýµäüø§sLü9ú_D@D@D@Š'¿ýöÛ¦88à€ÜÆo\lt¿" " " 5"ŸõQD@ŠžÀ/¿üâž}öY7zôh·ÓN;¹6mÚ¸ÕV[­R¸àù€Å×[sÍ5íU)®â‹ 4øî»ïÌÊmñâÅîÛo¿uÛm·«_¿¾«U«–Ûpà ÝZk­•´”+W®tË—/w ,°þ`×¼ys×¢E‹’sÒ9¦ä`}"%€Çã?î¾üòK×»wo›“) ݶˆ€ˆ€ˆÀÿAUAD@þBæyóæ™×Bë®]»š¡²áù0qâD·þú뻽öÚËí¾ûî•ué*¹?ýô“{饗ÜàÁƒ=Âÿ5ÖXüø¼ß~û¹¾}ûº½÷ÞÛ­³Î:eÊI~ø¡»üòËÝÔ©S->ï–[néºwï^¢@Hç˜2çð ê÷Í}n´ÑF9¼’²Ì¼ñÆŽ0™ë­·žkݺµÛ|óÍ3Ë@G‹€ˆ€ˆ€T;R T»Gª¨„ÌX¿1Â-[¶ÌuìØÑsÎ9ɪBçp}6ª»ð Í]¼ÿþÕ^€§Áý÷ßïnºé&‡÷ÅhŠ‚­¶ÚÊ}úé§¶x}ñÅMApÍ5׸víÚ•Q"îhöìÙîÉ'Ÿ4^çž{®mö]ì¦sL…ZOâ9_ýõ®aÆîÊ+¯¬`.:MD@D@D@²K௿þ2c–Ï>ûÌuéÒżqW_]Q³KY¹‰€ˆ€ˆ@á¡ðž™J,"³Ù4ù‰'ž0ëÿ~ýú¹ 6Ø WJž%az°ž¯]»¶Y}%?²ða¿‚¹sçšòÏ‚=z¸‹.º¨T¨" >Üö£ÀÄ£>ºÔͳç^›¥Ï)§œRêwþIç˜2'åè E„ ®üñ9ºŠ²Ì |òÉ'æŠ"áÈ#´yiæ¹è êF@ „êöDu?" øã?ÜÌ™3ݰaÃ\ݺuÍó`×]wÍ8ŸU9}š5kf Œ5j¸:uê¬Jvy.B¼¨Ÿyæ™… ÷M(Sð(`„‘#GºxÀ\é×]wÝ’ÃXàâa@اí·ß¾äûè‡tމ¯Ï" " " "Plð}øá‡Í÷ðÃw5*šý¸ŠíYë~E@D@D SòGÌ”˜Ž¨VX,½ýöÛ¶ï‚æöíÛW™e8BðÝvÛÍí¼óÎn‹-¶(Å™²±Á2–û$ÊÍ&w¤ð›ý÷=x”$|&qÞÏ?ÿl›óòŒ;µä_ÎãÚ?üðƒmvLüþpí’ƒ"ByB¾”!?ž$Êòú믛²„’ñˆW„ìP"{ì±nÓM7µM’§OŸn?Q&ò!_ÊÂÿ\ÿ)+eHç˜pÞ9Ÿ{cCçï¿ÿ¾$Ÿè1É>³¯çÁ(\?þXʃð,øŸòòâ;%¨*_ýµ{î¹çl.Ä|˜’J" " " "Òæžb"" ED3±öï»ï>ÛÀk+ö H&ÌÎ5šüÑÜÆø·mÛ¶dƒ]ÍÁ¥<(Ø8øå—_¶"±ùòƒ>h®æ(ðf)ä‰ý°Ã3ÅÁ›o¾é^yå·téRW¯^=³êßc=\Ô²?œPãðÐà<„äýÙä™W­ZµJ]eÞlŒÜ¤IS†¼ÿþû®ÉI'dÂy6«æzûÛn»íÂåʼs/;ì°ƒëÔ©“»çž{la{ÄGX3fÌpï¾û®• Á?û% À'œ›/³vyÇàqB=€JçŸÞ}ñÅV66nnÑ¢…㘚5k–)[T‰óÑGY&î–œ 'ÂR‘x†ü±{úé§m¯ ì¹Á=q[o½µ)JÊ\D_ˆ€ˆ€,Æ^Œ¼GSø5ÖpĘŽÝÑãôY*‹ÀäÉ“óæfÉæ…•U]GD@D@D ¿H_ÏC¥¨DXß?óÌ3J§qãÆ®oß¾Uë•ØøÄüGHß´iÓÂÿ×^{Í]z饮k×®&˜¿îºëì8p¡\ ìÐo»í6 Œ!Ïo¾ùÆ„Ù(žzê)‹øñãÇ»AƒÙá<Þ¹îœ9s¿úê«–ïÚk¯íž}öY7jÔ(;þ²Ë.+Å åÇò}÷îÝM90pà@ 1Ô­[7Ë }6çÛd“MLнf¢Ï(vÙe³ìç<ÒŠ+Ü]wÝeŠŸàu0iÒ$»·vÚÉ<8Ê—w ʼ äsŸìÇ€bÎ#‹€ˆ@@9ÀxŠÂåpxçsðÞ ži|Ç‹sxg¬A¿Ùf›ÙÞG00&ðÎ %4c6±-ÊPÀÅÄcêÔ©Žù"s8æPJ" " " "HHè]D ¨°ÀÇ þ¦›n2A6at:è ¼fðË/¿XØxX¸c¹ÿ¯ýËÞÙgÍše‹?¬üãeW]u• 9ú÷ïïZ¶li.êΟ|òIw÷Ýw›t‚ð>øÀÝpà îwÞq½{÷¶ýØàù­·Þr7Þx£Cñ€dÈ!%–öáºFPz°oAƒ lŸƒÀ?^Eš”—(×å™±°å}Çw4eɲeËL„çÀùçŸïÚµkgùâv`…Jªcúp?‡2¡?–wÜÿ”)SìþQBàùq衇–•PD(bà@ÂSïî Åõ …ψ#,?î”/(XÎ;ï<צMwýõ×›Õ)ÏOID@D ÿ e¡çxáÁ†"/3¼y¡¼Ç› ƒƉ< ‚Çùñy½õÖ³p}Œ‹¼ãÙ ¼ Qn£P`·üqs=Ot2‚m„x´jÕÊ¡y¦M›f‚y¬úÃFÄxgL÷û êè¸ãŽs×^{­ ä9±yóæîÊ+¯4/Ž!ô‹ÍhúöÛo-ŒÑþûïïFm Òð;„+ÍÓQ (!, ¬8É›{F‰À=‘¿¡@ÐMåƒR†PB€ˆ÷Ë+¤Ž;š²‚ò³¨Ž*!Å÷†H‡þðÂK¶<£±cÇš²'X™n´ÑFVçøŸ}âË®­wü!€Rœñ‡1xùòå¶wÒܹs-„ z~C¸ÏxŸZ§N ó·í¶ÛÚgÂÛÑïó;ïá3ù¢dÀ£1˜w^ .t³g϶‹PØ|óÍm¼@™Ý¬Y3×°aC3~ _®+eBþÔ•B, óKæÔ=Œ¨·J" " " "% B”†>‹€6‰›8q¢Y+¿_¿~ª&ßoa9û4j¡AH„?Ø}÷Ý!|n$J„õA蔃СD£FÌ3!z.¬år†‹|!aáâ zŽ‹W pÜ6ÛlcÂtöˆ&¬-Q" LOWèAYQPÎÏV"O=ä‰<ÈP¾3Ï<ÓömˆòFiÀ±¡l‰òáXxpÿ(W»3Ù*·òÈ- 4@ÑLŸO˜À^x¡dúz×]ºt±1˜±Á+ãêšk®¹J…cLbF‘0þ|{-Z´ÈÂæ1=s (ÒQ`K™°JØ‹ödŒE0JÁXƒy"õKID@D@D@¢¤@ˆÒÐgjO+A6ø%d BubÛcÉW Bé¨0›r#¨@è*!èfÃäøÎÅ2šðX „ì,.£ ákð$LC|"_,%O8á„øŸ,ü!‰P"`íÆþ©Ây”ê¹ÎÍV¢œlÒL"„ý„jÂó… LaP&š¾çy°‘3±ƒ£ŒPl°Á¶¿|¤@ˆÔgÈ_„É Þi„ªãµdÉSº3o8í´ÓLxÏ8Ah!ÜÙNx(ƒžáïHŒ·„J" Š ÂjåÆ(ØøcW.Ê•íûT~UOEÙ£>js¹3Î8ÔbéwT}éUÊ" Be‘ÖuD@ªœBoâÝö‡…5¡y:tèPååÊÇ ÜGðÍÃÕ“%¡HˆOXï#\á=>¿™Dï¿ÿ¾YXÆÿÿ?ùã5‚2a Bÿl&+xuP/P.˜kí¼óζ§Â±ÇkJ)¤ÀÂûDtîÜÙ>GÿB‰ðHJ" " ùMË~úë·ß~Û=ôÐCî¹çž³ñ±€=vÚ¶mk{0†UEˆ…;¯îÝ»›wÛŒ3l3gºÇ{ÌöM@ ~ôÑG›â¥;Ê%HF€(£¯uÄGdÕH#Ù5õ½ˆ€ˆ€ˆ@á¡ðž™J,"PX±/]ºÔ6 F‰pä‘Gº>}úha]Ë&MšØþÉ,±RK¶A2 6„ „yÀ]ž°ì,Ї@+ÿp^9EÎøg„‚ÀrsÁ‚AÌœ9s,¶5›$îŠÍ•±î ‰ú„•'¡#Ø<™0Pƒ?—¼c©äG}¨Rôå(©ñÂ#,Ý<`{0.°ï {í½÷Þæ‰W¥»8ã+ãèI'äºuëfƒÏ?ÿ¼Y’>Ü7ÎuÔQæQ‡—%Š„l+ß㊤ †5(ËðšDé„A…Nø Ud¨R Td]BD ê bæÉ'Ÿ´E5Bñ /¼ÐÀU_²ü,–Xû#DiÙ²eÂx¸þ¼djIŒÝ=÷ÜÓ6FàA8öTH”îJiêÔ©›—g—‹ÄuI´ï¾ûÚ‹ÿ—-[f¡®Ø,™v›6mla<(Pzà©@"^p¼‚kVŽ‘Ð&OLyŠ€ˆ@Å ÐÇŽï6<ÏP`\À¾?„ÞC0ÏxSÂT” Ûm·;ýôÓmo"îg̘1n„ ¶7Rë֭݉'žh^„Ö+„{ªø“Õ™™øüóÏmo<+Û·oo{Ber¾Ž(ÙÚY<ìt§" BAîìÙ³ÝСCÍ55‚b¥ä°œ'Öó?ü`žñG#šÍyä‘„{ Äý› cñÿÁ˜ƒgŸð`ÊÞlIH$¸ÙLXß±Ç~X*Ôö-@„ˆ°×žkXpó}¢„P ¥±ª“Ý %Ê%€âï·{î¹ÇuíÚÕõë×ÏÂõ¦ˆ0@„³c¼)DA;žíÚµs÷ß¿?~¼mˆ‹¢åžt„ÛCqÂøªTܨì}°ÄïïÁÆÉ7Î;O›â~Bº{È/R ä×óPiD@²L!-Âg6MþöÛomaMì`¥ÔØ£€X¸_~ù¥»÷Þ{MÞÝazõÕW»‹/¾ØÝu×]©3Kð+¡°ˆd,%‰5Í&ÉlæÇ¢ÏŠ+,|РAƒÌ­Åʇl¦åË—»ë¯¿Þb[ãiÀ&•A°Â}"hÁ‹€ØÀ”‰„W1±Ù$ÅC4q.!—¸6—\r‰-ÎÃ1(&È‹<¹6ù+‰€ˆ€äžcJq6EîÕ«—…ç£?¿öÚkMqpÙe—ÙX“û’äþ Ü¡ùFŽitˆñ¤c“ܱcÇ:,Ï)·s_2]!_°ÇmwözJæ š/åU9D@D@D@ª–€BU-]]D ÇB³hÆï ƒr]t‘ÅÒÏñe >{õx …/š>}º8p  \ßCh<XxÞèøãÏø~Ù\™ ¬ÉëÎ;ït={ö´PF9ØSañâÅ&„çÙZˆØ¼‡vXÆ×)ïÂUpŸìs0jÔ( E´ß~ûY¼h,ZPl`¥ŠGFHx  ˆÂ ÅÊB-¡`SË;î¸Ãò ¬Qƒ ÂiöÎ5±nýøãÝ”)S×#R­ZµJB"•:Aÿˆ€ˆ€¬úhú\,ó¿;‡â sçÎ Cô­ÒÅòèdÖ„ ¼å–[ܳÏ>ëFŒaãù3Ï<ãzôèaÞ€x- ÔV*.Ì?˜ká Ú¢E ›³Ý­ˆ€ˆ€ˆ@&¤@È„–Ž((s§M›fxld{Þyç•çÛÍ.Á=VøÑÐ X­3ásâSªß“åò¿’(zM~GðÍ&Âx ¡ ¡¾ùæ³¢Gypå•Wš5~È/UYÂ1ák7,ôÙkáÖ[oulü8dȇå?B,(ëÖ­ëÎ=÷\Û$’ïâB˜ ûdr ‘C9ÄõïßßÝpà îÒK/µk#\Â*‹UâG£ààÞBâ9¡ÁÛà‚ .póçÏ7EÇ£p`ƒe”}ûö §”¼×®]Û”!xÅP'¹›0Úw%ì O¦Ÿf.€ðüý÷ß·ýjz÷îm^dÑ~=;WÌÏ\»³öÚk/Û ŠM–ñÂèÒ¥‹)ï Ù§ýzòóÙå¢T¿þú«{â‰',„#¡»¶Ùf›\\FyŠ€ˆ€ˆ€T#e¥1Õèæt+" ÅK!ôo¼a±Œ,c%{>'éX²°Ã ?$Êß¼ys³lذaøºäß±0è½âO–g89ü޲Áv4!œ'L¡}^|ñEÛ`«ü 7ÜÐ,è q„ <šBY PJ±=&úk|„èÄlž7ož âÙk€GM›65aÊŸd Åû"»7ÙËåÃpÇ[`îܹVos¸²y2—øD¾xx^ÇsŒ…„@ƒRAM¼R†cáŒÒ B-Bq”CID@D ;ا†0s„á›4i’õéìpÜqÇÙ8–«V.[o½µíù€b¥=ìE„B+ôDF …u‡*m:˜{àAÉ\ë€0ÈtÎÓ1" " " ÅK@ „â}öºs¨¶ˆCÿÉ'ŸXl~¬ ì"¤ÎwKCÒmÛ¶-ó\äï°Ãö*ó£ÿ"ÕïÉò ùð{y¡°ïر£½ÂyÉÞS•%Ù9(°¼çuÒI'%;,á÷x äç•,¥s –—õêÕ³{3dš8‚t!#àðRȰ×{ѰJ °¸O¦hÎÞÕó?'ÆiŒðøc"Â÷±Ÿ|PÈNc”ª'¼\üq3^@qDHF%(€åÒï" G€Ð3Äv}øá‡ÍŠ}‚+‰€ˆ€ˆ€T_x²×Bqö¶ÁâžðtzNéÿ`^Dˆ@Â:ÔÂâÀFËxÒ% øÿÏÖ§B%ðÑG¹W_}Õ<+1 ‰z¼ê=©Ü" " " ¹' Bîë " •H€gÏžm‹á:uê¸3Ï<3¥uz%M—Èöòyçw̲žÍìñ:@@¾Ë.»ä芅Ÿ-Þw„d¿!ö""¤ öïiÖ¬YÒ½… ÿ΋óðÎaŽL8J¼-ñn•·IqÖݵˆ€ˆ€dJ@þ©™Óñ" yK€…Ñ»ï¾ë† æ~ùåwä‘Gº“O>9oË«‚‰€ˆ€ˆ€¬:?ÿüÓ¬ª¯¹æ÷Ê+¯XØÂk¯½Vʃ4Ñ¢d4h»ð m 8Κ5Ëa”¡T}°çÒœ9sóeGìõ¤$" " " é!J:FD  °ùîøñãÝK/½dÔÓ—øúJ" " " Õ“›%¿ð ‚ç½÷Þs—^z©ÅóWèÂÌž÷¦›nj—_~¹[¶l™CÃf»ðU*|ì†÷¯#Ž8Âí¼óÎ%H‡€B¥CILj€ä=_ýÕÄ=f3Þ>}úhc¸¼j* ˆ€ˆ€TœÀo¿ýf{áyˆÂUW]åŽ;î8·öÚkW<Ó">suÖqݺusë®»®»é¦›Üu×]ç˜_áÑÉwJ…KàÇ4ïƒÅ‹»þýû;Â|*‰€ˆ€ˆ€ˆ@º¤@H—”ŽÈ[+W®t¯¿þº-vkÖ¬iq]?üð¼-¯ &" " "°jˆN˜0Á1Âm´ÑFîŠ+®0Ëê5ÖXcÕ2.ò³±JïÔ©“) n¼ñFÇë÷ß7ÅÌúë¯_ät ÷öÙ8™ð^õë×·ý-¤*Üg©’‹€ˆ€ˆ@UP£ª ®kŠ€d.Ù}ô‘»ãŽ;Ü’%K\«V­\Ïž=³–¿2ÈŒûß|óÃãpèСnÛm·µøýXÉKyçG6¡8p )g† â&NœhŠ„ì\A¹T&në­·®ÌËëZ" " " Õ€€<ªÁCÔ-ˆ@1øî»ïÜc=æ}ôQ·×^{9ö=ÀQID@D@D ú@y0|øp7fÌ·ï¾ûڸ߬Y³êw£U|G«­¶škÓ¦í%ÅË(l6Ø`wÔQGi©*~6™^~Á‚îå—_vìsѲeK{Ž™æ¡ãE@D@D@Š›€<ŠûùëîE   °±ßÌ™3Ý-·ÜâêÖ­ëÎ>ûl×´iÓ‚¾'^D@D@D 1ŸþÙÝÿýîÁtmÛ¶u °p,‰Ö·Ù pຠ.¸À¡PÀÛó¥—^rÿýﳑµò¨<«9sæ¸ùóç›Â ¥›’ˆ€ˆ€ˆ€dJ@ „L‰éx¼ ð÷ß›+öÍ7ßìþóŸÿ˜«}—.]ò¢l*„ˆ€ˆ€ˆ@v `4€·áرcÍãð¼óÎs 4ÈîE”[(PÖôîÝÛ­X±ÂÝ~ûíî7ÞpýõW™cõEþX´h‘í}Às$|Q½zõò¯*‘ˆ€ˆ€ˆ@Þ!ï‘ (ùO€Eä?üà–/_šëDüãÏ>ûÌ7ÎbºbMÕ·o_ÇÆJ" " " Õ‹VÔÏ=÷œ»ûî»]:uÜ9çœãš4iR½n2ï¦F®C‡¥Í»ï¾k!¤Þÿ}‡1‡Rþ`~>kÖ,7wî\S0_^}u-ÿó÷‰©d" " "¿4ƒÈßg£’‰@Áøúë¯m#C6Ü#&ñ—_~éþüóÏœ•ÿ—_~)$ì²Ë.¦<Іp9íŒE@D@D Ê }íµ×,?‡={ötûï¿••§X/¼öÚk;<= ‰PzĈîóÏ?/VqßÛ¾#ö>hܸqA”[…È?R äß3Q‰D àà€uàÇìúõëçN=õT÷üóÏ»ï¿ÿ>ë.î+W®4KªÁƒ»Zµj¹nݺ¹V­Z3XD@D@D 5,ܱt'ö>s ”íÚµ³xü©ÏÔ¯¹ À&ÊÌñP$<óÌ3n„ î×_ÍÅ¥”ç* í¼òÊ+nöìÙ®E‹n¿ýös(”D@D@D@D "¤@¨5#"PŠá.½ôRwÓM7¹F™µÓÉ'Ÿlß½õÖ[” «šÈãƒ>0«·/¾øÂbòöèÑcU³Õù" " " yH w”X¼ŸqÆ®sçÎ WXÅÏi³Í63ã½÷ÞÛö¤xúé§ÆJùEàÛo¿µ0ŸŸ~ú©ãY5kÖ,¿ ¨Òˆ€ˆ€ˆ€) êq©°"¿ð8í´ÓÜĉ]Ÿ>}܆nèxà×±cG‹•»lÙ2÷ûï¿¯Ò *‰ ÿýï»=öØÃ]tÑE®fÍš«”§NÈ?ß}÷íy0uêT³xÇ0Ac~~<'ÂGvíÚÕâé?Þ-\¸0+†"ùqw…_ n]ôòË/[Ø"¼ðQЍQÑužˆ€ÄXmµÕÜöÛo﮺ê*wÌ1Ǹ[n¹Åa™vÝu׹ɓ'Û^mÚ´1åB¦ÿñÇ^2eÄ;ìàzõêåXÀ*.¸sx—(‰€ˆ€//¿üÒMš4ÉÆ 6M&d¡R~`¬O<Ñ6¸&ÄdÆ Ý!‡¢M®«ðqa¤Aø¢7ß|Óæàì $" " " «J |ÓßU½‚Î(z„¸à‚ lÿxÜzë­î¸ãŽ3Å‚?ÿü3!§ŸþÙ”cÆŒq»îº«»ð ]1ZR%„“ç_òL¿ÿþ{÷É'Ÿ¸§žzÊ6Õ&„U·nÝL€AÀÌû nݺy~G*žˆ€ˆ@. 0nL™2Åa{ÔQG9Æ Â#*å/ž¦„˜DD¨J” 4(šûÏ—e? ¼ðäiÙ²¥í!’/eS9D@D@D@ ›€…ýüTú;•<Šf›m¶É£NQJ/ÿ—_~qÄ?®Q£† Óù·ÝvsãÆsÛm·]áÜP’’"LA°ÎÂå–[n1O‹k®¹ÆMž<Ù6˜&~ðFmd÷Ÿ$‹*ù¥JžÇ§Ÿ~jÖ¡S§NµXÇX‡âiаaC[Œ±á%o|§$" "P|ØûfäÈ‘ŽýmP’§“˜Lš4É<ØÎ?ÿ|GÒ9OÇä]wÝÕ nºé&3”`ÇÜF)·˜?ã}ÀÞb{챇í5%ŽÜ2Wî" " "Pl¤@(¶'®ûÍ ”ÄìUJŸ@°ÆÇê}¤#dgñ‰;ˆõÖ[¯Zyvp¸•5ʬ÷Q$`½Ï¾l*Ü»wo»wðUºgÃ~ X‘~ñÅnÚ´iæiðꫯ:~#ìÒŽ;îhôáiÀF}µjÕJÿáëHjIAæŠ+,$ïå%ÆÂ¾KYÑŒ•J…I€¹ X¿üòËöL e¨”[ìA…áã?v={öÔþ!¹Å­ÜE@D@D ( HP”]7-UGá±8 S„5>û°ðA ÍFÉì ðÞ{êJ™Û+£ èØ±£Yˆ;Öâÿûßÿv/½ô’ëÞ½»½PJ¡@©¬Äsa#dö5Àý²P&¬ÙØŒ²l»í¶–èè£6ƒÍ6Û¬²Š§ëˆ€ˆ€­·ÞÚñúè£Ìk­¼"v…½ðä<öØc-n~yçè÷ü&ÀüÃÚlèËÞ(å†ó7ö=`¾Æ¾b„Úxãss1å*" " "P´¤@(ÚG¯Ê'@ld„ÓÏ=÷œ»í¶Û¡êÔ©ãºvíêúôécÖ÷” B1$b<_xá…æîâ?6ÌM™2żÚ·oï6Ùd“œm>Ì¢O”_}õ•->¹6›=óŠŽ-¶ØÂ,ÙP‚Iq©‹¡fêE@D bP,#@Æcý¡R%Æ ¬ÔçÍ›ç;ì04§:^¿Â² „×_Ýxà…Sø+)Æ(kÞyç×­[7ót-°[PqE@D@D@ €€ðTD(tìs€—‹ÈáÇ›µ!ÂiÒlLø¬‹1q߻첋:t¨ëÔ©“»ùæ›m!xÑEYLè¾}ûšÕ?›Qfƒ<@Ø×à믿6!žÓ§O·½(°ÄrgC(‰C=Ô<ŠñÙèžE@D@2#À†¹aß"Œ9ÉÒ7ß|cæµÖZˬ¦7ÜpÃd‡êû#°Ã;Ø3eNƒ’ˆð묳NÝEawþüùf‚ònŸ}öq[mµUa\¥((R ÔãRaE ° 8À’}ñâÅî¾ûîs„ëÁ }Î8ã ³”’ÀàÏ”ÍîÖ³ùÝĉm_,÷°Ììܹ³í“P¯^= €€&“Äs€;!ûí·î7Þ0/ö6@€ƒÒ€= öÞ{oS´iÓÆBJer +" " À±ýÓO?M „q «iB¯`­Ž€9YâX ˆ¯_•û%+Ÿ¾OL€çú /˜p›ù s ¥ì`nÇ~Ìë0ÆA $" " " ¹ B.¨*O óù矛 úöÛo·PˆqÜ«W/‡ušRYXÿŸyæ™!þwÞé|ðA7fÌÛt™ñN8áW»ví´,ùØ»Î÷ßïÞ|óMÛÓ€Í*‰9‚krÈ!B‰ð 4p™*'ÊÞ¾(fì—ÃxŸJðÓO?™eúÊ•+ÍR=Ùž:(}È|‚‡ä­T˜SŸD` ¡ ²³ûì Û5j˜ò`§vÊî”›ˆ€ˆ€ˆ€ü)TD@²J€Å>¡qØÌíÖ[oµ…Íæ›oþùçÛb2«¬†™!į[·®8p )\n¹åS \}õÕnòäɶ_DëÖ­‚—ø„5JBF±°dO”lZ§V¡,èÛµkg1§ Ÿ”ÐHñåÐÿ" " ÅI ú Çœ Qb,§ñ[r({ì±fàÀ‚¯Êþ+-¬¾úêbÿꫯŠe­Uþ(¶K_|ñ…(0^Úm·ÝL¯^½ÚÐ:BE@PE@h(ª@h(üJ¼àeAnW,ä<¸ñÆE(°ß~û™m¶Ù¦P\ý'žxÂlºé¦™Ê]¹ L!yäÝwßmHFÐËÎ]vÙŬ²Ê*¼É1±çž{ší·ß^0C¹ EPE@h쉺wï. o”à® D&GÊn¼Pˆ»òý÷ß›|Pr|óÍ7æä“Oá(ÆZZö,k¬±†x•Àò^h¬þüüä~ÂCEʼԫ#?žz¥" (Š€" ¤C@épÒZŠ€"PØ#GŽ”Ojz*xuà]À "I”yY\l±ÅÌ;ì I”I–‡¢…²òÊ+‹À%CóZUPE@( EYÄ,½ôÒâ‘HÎ ‚O¾blqðÁ›•VZ©ƒ>^Œ„å#מscÆŒ1„ß# ’–ÖF%¹—~õ«_IHª¿þõ¯bøÐÚ£j\ï¹WؾýöÛÚ oS-Š€" (Š€Oس…<|¶­mµ.º+o]ÞiÏE   ®-/‡Ä ¾ôÒKÍ]wÝ%qmQ :Ôì´ÓN’ã  ‡®CRE@hxéÄ ‚N aWÞxã Q†ã€:/¨ÿýßÿmn¸ásÙe—*wÜqfóÍ7××6™ ƒ¿x!¼òÊ+/„-¶Ø¢FWíP^xáóÔSOIØT¼0âÑ¢(Š€" øB€è|^xaÙǪ[‹"ÿ¤0(Š€" 4„(„o 2±Ÿû÷ïoî¼óN³ì²Ëb@c™¹Ç{¨ò ñ¬Ò(Š€" ¤@€Ð5|\yë­·D™@ø=¼xîñ‚zÉ%—ˆ§ÇÆ'Âeµzs¨µÇ÷¢‹.*a«Pa ïµdG€°–x€!!ÀÖ_ýì芀" 4ï¾ûN¼ë Ç;þüN9’Ð%%Y‹/¾XÂ"xà¯A-Š€C@=ú­(Š@ƒ 1ò§Ÿ~j~øaI†Œ䓃 2Ç—· êš’UE@Pr!à<¸1 ¼vÜqG±š&,/©7Ýt“ùÝï~gŽ>úh±RÏEL/jz·ˆµüìÙ³E RAK6PÚ’\W$£^f™e²5 µE@h=ô¹òÊ+åå'r¿ùÍoÔ%[""PÜw½ºz®k!  „®Åo­" 4ä9À˜Ð$HFðÿñb}yøá‡›¾}ûJFÝDCÕ®(Š€" t1P„ó¡üÏÿüxØ‘ìuÅW!ò\`î¾ûnQ(Gi¹å–ëbu­á"(«rΜ9òQB6þÿýï7þóŸÍŒ3DáFø"-Š€" ´ Ÿ}ö™yíµ×ÌG}d~ùË_Šç}«ô]û©(ÿ‹€*t&(Š€"P1Xb’TrÖ¬YfòäÉæÆo4(ˆ }À˜„,ZE@PVEàç?ÿyGØ=¼K„™çÝi§f{ì1yÞ 6ÌtïÞ½U‡©ýN‰@·nÝÄÚ8JMþ›¸T{çwÌÓO?mðZÅû œ„<[KZ[Pê`O€¡Ü7ß|#ï¹ÿïÿ©(²z.(EE z×ÃO¯VE įýøãÍ=÷Ü#^sçΕÑ;ï¼³9ôÐCM=2µ§•E@PfG€äÉ -´ù÷ÿwsÕUW™_|ÑrÈ!fÈ!F-Ñ›{~úGÒl¼P$½÷Þ{cZ’@é†÷ÁsÏ='yð>Ф–ɸi E@È^O?ýô“ùÙÏ~f|û]Ø"¼ï.¾øâù;§W*Š@CPBC`W¢Š€"Ð \Ñ£>*É"I‚G,àvØÁŒ1Âl¸á†]³" (Š@@àÃ?ù~xöqÄfß}÷…B¾ñà‚ÐÂY¸W P}¸oØ7Λ7Ïì·ß~â±Zÿ =«(Š@>P¯E/yùÖ^{m³êª«Š"!_‹ÿ{Õj«­føhQÖE@­Ë;í¹" ´XpL›6ÍxàÒkÜχjð<À¥S‹" (Š€"ÐÎðD€|ÔQG™=öØÃüë¿þk;WǃV§|áˆpJ1 Eö’ÐE|ÖZk-ƒ÷Á¿üË¿DjéOE@PÒ#€Wž?þø£„Eà Oƒþç6„K;þøãÍSO=%!Ï<óLY·9ÿÝw߉WëRRYxá…P:p 4QPà‘}ÿ ŸçZú‚ç>Ÿï¿ÿ^¼×è{ÖÀ"laZ$¥‡áá1Ì9Oûœ£/ޏqžzüÏqÆwe/ ®a,| ‡G´˜8:qØÂ+°ÀûŒº\K_O¸†vî ´¾þúkÁqAPÉYö`ìßàm0nðIë çÆÍ8HÎLiÃñ:nÌîy´ÀŽ~s}à}úÅ/~!x¸ºú].ª@(_m]PA€ Á"‹,búôé#/ƒ+L…GPE@hwxÙìÝ»·9æ˜c$i2¿µt=WE²lÂñà… ‰€“çÀ—_~)x¡pÙn»íÄ8ù*­¡(Š@<œQâÞrË-¢˜üàƒD0K.¾å—_ÞÜu×]¯A¼=¬Â¯§´$ï³Ï>›*ò>ûì#¹núSB_vÙe¢ ˆž‹žÇàn±Å3S§N5?þ¸y饗Dè¼Ê*«˜M7ÝÔl»í¶f饗N-¼–„þ„ûB8EŒ^yåsÓM7‰â„u—¼=;í´“<~¡5Ê•[o½Õ<òÈ#æ“O>a}¯^½$ã:ë¬ÓSˆTÇ¿ÎYÇï¼óNÁ}öìÙ¢0Xyå•Ízë­'{#ð¯µ?â¹ùÐCɸ1@D ?øà)È-DHd¾Áý¯ý«yðÁ¥Ïðœk+ `ø«_ýJŒù!ýôéÓÍÃ?,Ø0næž)»ï¾»Y}õÕëŽexÞÿý‰áÕW_…m0ç¶ß~{é/J˜¸ý?üáâsì±Ç _˜W^y¥xæuÖY¦oß¾Rqmé±âü?ŒV-ùË_¤ëÜ­<ŽVÅ_ûmŒÎÁrf®Ú´íto/µÔRæ‚ .±±y+:¶vÅIj‘?ʃa”v³­ <嫯¾*¼®¶5P œãÍ +¬`PœóÂIî-],±¼|ýõ×K¿_±LijU Ö¢ä=Àû€¤É(\“E ]@Žƒ€á,k,««*’y'sVÝi­©}ô¯´Áøi§&9ùXO”ÄõwÜq‡¼ã%xê©§ŠB!Ì·÷ÝwŸ€ã0à™ÏúŽl°A¸îоûî»EÍ^á±;G[áóì^xáÔÓ7„㬇àéãÀ Âd„ïyx¦…ðáø%—\"w¬ûzÏœ9Ó̘1üüòËæ”SN1üÇŽ+ßôã@B=½öÚkæÉ'ŸåÊ8¼þÓŸþ$×óìÃúŸØ>ñÄ"\Ÿ2eŠ=z´¬óÜÑ‚‚ã†n=F‰ü],ò¡‰EþÍ7ß,cá¹Ã¨Q£ í:kúŸù0¦‘#GÖ % N((Î8ã oé3mÁ›Ç{ÌÜvÛmæÂ /4›o¾yM%òŽ1cÆH]ú‰Çm ¥È5×\#óqÏ=÷”ç[x¾ž ×]wùè£ÌÞ{ï-´ ƒ öðù½&Šþö‹þGúQ tèÐ9 s@ç€Î:tèÐ9 s -æ€ZX™Sëî#°BžÀ†‰¬Ui`•o­;˜Š{þ»ßý.v[ÁYÅ=i,¹fÆÁ* k9Lœ81°ùàký|þùç•f¢µŠŽ<òH¹Ï¬€6°ÖJè7ж&@IDATÖŠ?°‚×`¯½ö ³øV`X+ó`›m¶ ¬8°‚ðÀ Îåx·ß~;°Ö÷µjïô±Š iÙ¢ì6R`…»—3f«•ûÒz"VàÝqŽÂç­€<°Êß`Ë-· Î=÷ÜÀ ¬+,—uÐzFVx 0 °BýÚHû#LËFlnžÀZæ'œpBFÖK °–ñvV8ØÜ3õž ¬Å~`­÷Æj•ÀV#uößÿàý÷ßíØZKýÀ*ƒk¯½VêZáz`…ýÁÆo,çl® áC7× 8tïÞ=Xc5ë}!}±^iÁäÉ“›c1?~|`sLI_¬E~`Ã%Öª?°É«ƒ‹/¾8°ŠŠàª«® ¬GI`•.Á/ùËÀ*Ià‘£Åsdž ’zôl>øàÀz­Ö#$°õ–>€UÈûlÁ€¹a•Á„ «Xè4O£mèo Šˆ}¸êqÅEç€Î:tèÐ9 s@ç€Î:Zq´ºÙ[l!‚+kéOÐZjfÁy•ð736LN€ða0답F¬Uu€Ð±ì‚€!(Âh·¶Ù.Á[o½U6iØ6‚6c¶¡D!¹õÖ[‹ò&:Xõ6׊¡­E~'!´¾ûAö2Ë,#Bk^¦Óµa¡}’¹`-Òƒwß}בo@”=ÊîÛpKDz–p_¦[O‰åbXd=–¨c~@¼õví Ǹ‚[¯Á ¥K´Øüõ˜þ¢ ±!|: ¼¡…r…¾ØP±Êb§@`¾¢T>ñÄNhr(1PQ¡¼õ$éÔ–õ(l8A©ƒ"Äz,Ð?œvPZX¡x¡È@Á2dÈÀ†Kâð¥ JBÖû¤-”ˆÃ† lPÐØQ° +˜_Ök&8ù䓎k©²“B‹" (Š€" (Š€" (Š€" 4„šxæ™g$|Ɔn(á@š [ÚEÀ„V!¼ áb(ÌùiÓ¦ë…àF­†[ýÏ>û¬£ á`>þøãŽþtœðüO£h“À˜Xù|ÿþ÷¿7K.¹d§‘Zˆ<„†!Þ?ÉwÓÂýˆøø„Új«­$¯BškãêУ>Zâõ‡ÏòÈ ÉÍŠ+®(¡mˆ«Í"…œ„è!äR8üõ0V`-a–HLbir„cõЇÐrä÷™7ož„Šöåü£¬åô}øðáv)rZ„ð!ï¹)¬'ƒ„lжÅo‡¹?.ä Å*µØïTÇzuHòcê€áÃjæÁé§Ÿ.c cC}ÚßqÇ…Þí·ß.mYqvGS„²J }DÎ Â;Y¥FÇyþ!üÔqÇ'8žŠðXܵ áíç‰9ꨣŒõ ¨UM—ˆ€*JW›VE@PE@PE@P² @|hW" ²¡($ùt–ëµ®"Ðì ˆe~»‚P•ßÄ–/» ¸´!ZˆŸp3*Ø-£¢‚ÆÆÆÞçÁ,Bjð†¯ × ÿo-Á%É-kVïÞ½ ÿó?ÿ3\%óÿĺ'¡p?H¾‹ðš~’£€½E B}ÖXÆ-äà¸õayœÐÚÕ±±Br(Xé3Ê æ7u£òX/I`M¼ÿZØ“´ø€ˆÅ˜ë™_”(‰¢¢`€ÿô£žò€6¬7Š(ƒÈ}WÈmÅ} ÈAþJWP‚0” ð“6¢cæ7J—€šœä]¨Uà=ÊÍT ¡òÿߊ]>-¥ (Š€" (Š€" (Š€" (5@¨‚ åù矫X<¢B —êaE e@`j㹋ð/žï´ÓN,¦ËÂÌ~ýú"G„œ‰û÷ï/Šº²¢mCɘÅ[Lâx"t×Y«;ŒñNÀ+ëqêb^¯ ä¾âŠ+$0má5€CÑõ ~Ôã‚x’ñ~úé§ ­ëõµÖ¹zÊ”,Œ„Z ,óë«y¬êÁrΜ9âׄïÎ‚ßæ»D-ö¹®^Ã^öka§,‰ë}®76ç­ÂµŒ“g—+Œ•„Ú`‡§ ÝäNuú†—ôÕ†5“k:UøÇ›·Ã0µ4XZ«¢ZÃ2†Ä„dbFK³ö7ÚOýÝÔš‡ŒNç¢óeCÀC3êšç‡B{´¢85Žû¸è¼CE)þ°qhŪ+®ej¡‡L5ÇjñFùR þ¾¨`5 /£…{ ^æ-XÒ.B Úª' HC£V?Ó\ÛŒuà¡@@˜‡e¬MzÙŒÝÔ>)…@@•4!^¾ýö[Chæz-Am!b1  m¬ØWZi%ã,Àcªz?ÔÚ¬³„"4šM/ÊI,ùü£ÀAi@ø›XYBùÒëúZ…kl¢dsýõ×¼Ž=öX³É&›$*jµ—å¸MÜ+tÁC¿›µ€Êžy„ù±yŸw(˜À“wÍf/¼ó¾ Á4(PTí¾ûî‰ãf¬x½„•Ññ£L-C V€ò†7[a3Õú­DK³ö7ÚOýÝÔš‡ŒNç¢?ñÄfS'—¦©S§úi´ [QœÇT‡}\tÞÆ¡¢ÇÿŒ;ÖŒ3&¶á‘#GÖ<{ôŠ@-Þ(_¼Â\zcÜ_ð2ZàãèÑ££‡SÿF8~Î9瘞={J8¬‹”Zý,Òf£®EàôôÓO‹°Ä×[•6ª_JW(ÂÔðiDá¾Ú~ûíåS5ýFÑ&ôͳÏ>+J›#<Ò 4È ”EXýÈ#ˆbeŽM¾+áˆêYª#0>묳ÌìÙ³Íf›m&±éQ UQ°ŒÇpa3^¬›µ¬í«èO-(7øÐ¿•W^Ydià„)Jòþ¨E³êã<¿QN1NçAAkĸ™ëxû¤yÎ"*ê<×ÒXbí’RWE@PE@PE@hG°2?~¼„6h!IU| , ’¹"ÄëÕ«WU¤•Ž" ´9(0xă +÷óÎ;O”¹~ñü ÜÌ®»îjŽ9æ˜XÃ]ÂâóÏ?ß<÷Üs-€¸ô„ªª¸ü xH¸xþUÑÎB¡9¡„|ƒë°aÃ$4T–6š¹.óæ‹/¾EÎRK-µ€÷¹ 7Ç™gÝ»woæ¡hßR"  „”@i5E@PE@PE@Pb Pá£eAÆ^±áñ>@ §EP¢0wÒ¤IJkøýöÛO,Æßyç±ÞG±Ð§O³âŠ+JáZô°ú¿ï¾ûÌwÜ!Vç§œrŠ$Áõé)…åz½âò ”NcÑ_¯­²Ï&‹>’P˜\õ Þàȧhh¿ztÒžKâ oBòì"RL8üØÒK/-ã@θ©SkLxÀ@+)çBÚ~k½òPByØjËŠ€" (Š€" (Š€" (Š@"ÄŠFyðöÛo›!C†H¼òÄ‹´‚" ()xï½÷Ì”)SÌ×_mN8á³ÕV[‰…xŠK¨‚Âá‚ .8‰§wØaï9§æÍ›'Ê ¼ ¢!;¹ðBXýõS…Ɖ¶Qåo—ðù¥—^2Œ Áz\¸%¼:ÈMA(ÂJ‘,¸–À½ªþ“«ˆçÒ¯ýëØ¾ÜsÏ=’¿Ïa%Òo~óá cž>}ºx¾ÔRö˜< „°æ: UT‡³Óù§ì—芀" (Š€" (Š€" (Š€"à ^xAò @Áû¡E@P| à¬ßIèûä“Oš7ÞxCß"à%œÂb„ó$¾­U&“÷€DË$ž>ì°ÃÌ2Ë,S«zîã—_~¹™6mš(Âۯ¿þº& 4I|›¹l»í¶‚Ñ«¯¾jxàQ"`.xu<ú裂- ‡ñðpü ׫ú”—^zilŸñ>¸á†D!Eþ?aÁÿrË-'IµQàù‚‚ :nÆÃœ:ãŒ3ÌСCÍÑG-¹ª§ÒK€z ¤ÇJk*Š€" (Š€" (Š€" (^@¨‡÷B¦ÝvÛM,k½ÐÆE K#@b^rª¼ûî»"°½è¢‹Ä*œÐE‹/¾¸X¾cOx#¬æIhK®–!7ã?ýéO’tùÀ”ëQ<Ä•Ÿÿüçº'=Âé1cÆHH’ÉÚ†7(YO;í4IÜŒò/ úÙÌeÍ5×4›o¾¹yÿý÷ÍUW]%˜m·Ýv‚-w6x‡ dÿàƒÄóŒ1§I:\ö¸þãmB>ƒwÞY°Æ{žŸtÒIæùçŸ7x ø'E´zè¡â}0sæL3qâDC®Œnݺ‰§üDauî¹ç _ñ^0`€ä´ˆ¶£¿›º ˜êÜV¸ññ‹_H¼ÊF¯ýAsE,ÍFõ­è²/®xÙ xÕšOµæ!Çç™­‚3ýv}%Ϊ»çóç!È:ÁCžv¾ùæšmt–ãŸ~ú©\G¬FÜiǵM9îÚ/û¸täc€6›'7.ÎA¿QÇ]?ˆȽ ÆUãS6þµÚwØg™W®­¢ó“vöô#ZšaÞº±v•ùo˜U®á>´]ðä%ÐÝk¹Xùnôñ0¯£ÿÓGž%ÍØoÖ f±Œþ7®0îÏ>û¬)æOtÜI°Žã9Ï9'®ãáYÛÕŽsÅøÈ§Yð©Õϸ¾7ë1O?ý´Ì;ÂW ÈÓ¢(Š€/xß?þøã%éí#<"atH€Ë‡}+Ï>,üùðþðûßÿÞ|ðÁ’߀µžþ×_½¼sò||üñÇEáY«[l±…Áúž}XÖ²öÚk =ÊÓ³w€&ýEáp«÷V(ô•\x Œ9R¼ Ö]w]ºÏž=ÛÜvÛm¢`@PÏy¬÷›¡À?BVòjòäÉbˆyijêµ×^“=xÌ¡HˆBLá¥BÂí+¯¼ÒàÑ@›ðwiB ŽŠkh¶Ür˺ù7¢íëïÆ €ÿÌ›);°±À B;åœ]$«³ûê Óq»¹ ìbØ›¦P;еZ»úéú·oYÇÒêõ~V0Œ7.€7>x‡Ëé§ŸX!z`_Þ Í!Ú‰›‹ÖuNÚgnÙlö…çVµæ®ÃÑÍ¿ð7Øú˜ëqý‰Ã9Ë=I߬Æ^xn]È‚ãŽ;.°ÂŸ°³/ȹŽ[Á™´c_vûp¬ö<°ŽÀ> ä¸um ®¾úêÔǦ\·ß~û-Ð8Ì™3§”ãW\q…àóâ‹/ƒ lÜÅÆ0vìXáo‘ã`d7o}H þaŒ²¶ï°/‡q™øÀêÛçyd-d«H ¬»j¡yå0ŠÎOxrÉ%—vƒ”ºý0ön¾ºïªçm#øâ°¬z>$ѵVéÀ ÙÐöÛo/×^{íµ²ÿí8iÿáyâž%¼—Ñë1!ýµ y/§ïV¡Üyçµ^_žéÿp_lÞšm!/±ÞÁðáÃä'q…ý+˜Y`ÆŒqUä˜ {ì±Á +¬ cBž` |d46 S`…íÁÝwß]³/È)zöìì¸ãŽÁ[o½K^­ºêª‚q­þraß¾}ë ï!q8þáq#×yöÙgå™O}úJŸ­R(°ÊŽóŽžTîºë.á%Ï8d· -´ð“vØw3øÄæó•yÇ~Ì*¸âªé±Šˆõ@ÀŠW’Ã?Ü>só´—/¿ü²¸¶à*¥¥9@Ûwã7š­·ÞÚ¬¸âŠÞ;߉‹g@Ñç%€¥IÚ ÏE´ãÄPCSKg­ž—NÜuyç.ýyæ™gâšlø1úFÌ@âÚEÛØ ¥ô•¤5®`]õ¸}Y4·ß~»¸‚.‡XÐZæçž{Î5Ÿé8Ö¼|ª,¸ Ú¡™;w®Xb`fn Œ M:±óÇUõËŽm¶ÙFbOæioxŠ€}^T S¥´xÝqÇò,ÁZ¡è¼¢óÑù O°¢Àµ7Kû•¡ÄàÙ@LÔk®¹Fêb½c_T¸^ãnK˜î÷2 4èGRû$±³By±øŠö3©_¬µvC-Õܺ›tM‘ó³fÍ’¤žö…£H35¯å¹Á¾Á¾¨Ö¬£'ÚîW¸ðØ,«dWUï9ÊwíZcc@bE‰¤[ïu¼Š1—Iƒ5–$“XKšØâZE@ð…ïÈ÷zè!y×±âš{.ö•V1,ïÄo¾ù¦ìÏV[m5±Š'|ïfiŠ5úY ¼ò«Ô•èVÈ-ájµC˜bâïµ×^"¯ tátØ'"{ÀR¿È3;ÜƆGm\9à€$L‰kå¤A6`•1Ѝžç¡–&L˜`,˜âuÆ>¹Âk¬!|©މ°GÈî×tïÞ=®»†±š A­þr¡5Ò>Ð^ÜØ­"Û¬µÖZ>áíAòm«éH^m• "¡ßáÄɱ²wÚi'I Í^Ÿ5o;k%2IæJ\biÚCfB%d˜¼«»ZµhéñrˆU °™ÇEᓆZm“|èÌMsœ›ŠÄ,lŽò´Ã5õ ýquÒö­«ÖG\„ø¬·Þzòâ–†—YñBÈ`­#¥}êYç±øx!ÁÍ Á^t.¿Å—¹Ê "!ú˜µŸµê'ÍÝZó‘v(7¸ž[­öqáÊ>ðÃjz;âñÑ><@pAsqúÒ·Ö„òP@‰ß–_~yiËZʃwC޳øÓ^Òqðƒ§¸Fò°¶–Ò_רóà(ã89kñ ìE|ÐAI#7†%—\Rr<œIl”÷8eâÛ2ÇÙÌemŒí„âû×Z0t`\&>ð°êöÙ=öØcò'ÄÞdã0K;¯’ê[«RÙ“´í 1ÊšŸÀ¿ŠûÎ׸pi?~¼(4a ó… kx­ î&k *Q¦Âoßcd<¸%#ªÕ>ý@ù¢ÝzKtêg&¼ø°ég-§ÿ¬»ßse/7Ök£#l/.¼L@›qð›Rä8ÏtøE›ÖZ-SûB<æÏ_ýÓv²ó›¹ã”\aö°?â÷+BR°¥™?µø“e^Ñ'ž(äùŸ9žÛÐ`~vµãð0NXÄÚÆ¾/Zu<ÚVúÍþœw%Þexof^D0ÖJc×¾*Š@5°—sk Øj  é r"Â!$¼Ïd¼o²·Í[X×M”¥ `æÓ¿ÿ,—%ÖMÛå|êÞÅY·Óöéì}ødr>õ <â6©$ñÁáîÚὄ}:Ÿ¼¹2¬ÆHð*-¾yû¦×eC@\Ní%ßÖ¢5°Ú¤Šœ Ò“±V-} ÷×nèÓ7Ò…kZë ×X›À¥©‘€×„v±B’¦›‹µæ!s×*ëXÅGÓá ÿqãÓŒ÷· ×bwÛ‡”;\É÷“O>ÙQ¿~ý*¡™‡H#1ÊÓß"×4+OÂK4|ö·•Ú‚¯öE@¬[pIJSªàG \¡p™¢Ÿ>4Žq4|Ï]ðÄ*Ëòf,ðß¾HI×ð¨UªÀ «rz +4Ò¬)gAËÿXVY‘ã0ª7©ÔGÒµiÏÇÑh$Fiûí«^žÄaåæ•¯þ8nþújWÛ)޼fÍ`­Ãú&kX Z=p<ç|t½ªuMÒqîaSU¼!¬¢cp|¾hDûg¸‹ãq… y«3¬ÔœÕ9VPð¢–Kr´i‡i8Zi¯Õz­‰@˜çeÍ+áÞcǼעT€}—d”OÛ„”X„’<Ùy¾TA_i(Š@×@€çšÍ_`Id…óâíÏÞŽH!î™G˜#<ñH°lsqIHßvØAÇ…¹éÈé(E Œ@¬ôá"áa¢å nO¸[¦²É)ÿTA#eWÚ®/]6i¤Œ‹Ð?õ„ÈnðUð#ŽBlb£í»ï¾±sÑõ/íw ßs—¾ðà%´Œ ¥•¶UÔƒßqŠÁ(í*°bípîu¸kÆÃ…1 ,Ç¥—^*ݪ»/Úo¿™i0r´êÃÕ)úG£‘OÖë³ð$+7¯²Ò­U?L£V=Þœ²‰µŽuÁ·æyt½ÊÛ>÷0ñÛÕ¶š0ÏËšWŒ.!¬•fó‚¡=k+ñkTÊ;J擄m5xŒ" TŠ9%ÙËÝrË-’ ÷o›WŒoÈ©GŒyBaÃq›pÙœtÒI’û ŠŽÒd(¾ Oªè»ÒPº ± ¬!Ò ˜» Pí0N,õÆ'C!VÛ)§œÒ´Ãâ‚ÉÄZi.¢<8äC$iÍÅ_ÜTøºûšNoR#€Ò Q^(®Ø¯C4jÑn÷ãâá+…DpQþÆ¿ ~ÄÑ „á‹fΜ;ãúZïXzõóž#±.IåÀ·ÙJZRX&À­%áðE`†Òˆ…0U¾LÙüæÂ /Ú6î·6l˜ü_ëO½qÔº&ëñ8Ä(kÿ‹ÖÏ“8¬ŠÒ^ïhüôÓOâþ=¯¿‡Ê¦×^{Í\sÍ5Ò‰4÷pšÞ:žS7º^¥¹>®Nt^cuZkMŒ»>ϱ<ãÀkÁíX‹I¼W¯àéèÆQFø"h‡i`)ÇÞFK{#æyYó à Â|‘ÔÒ¡½‘ÕÑ5ÞXcßxã 3hÐ ³îºë6²;J[Pº„‰æÓl¯›§³Ùº¥ýQ± ^ÆÈº0£4`£CAÈXFx‘*h„Æß%ÿŲ?­õyüˆ£ññÇ›)S¦Ò*;ê13ŽF½úyϹÐEhÍ›­¤U UÊ!·– ÔÂוY³fI®~³¹;v¬;Uú7ᛜ°Ì&KT Ô‡¯ÎÆÑxûí·†‘¯q¥m' Oâ°JK'm=Gƒù‹k¯–æA¡üøñãE‰K¯ÒÜÃizïxNÝèz•æú¸:Ñy=dÈškbÜõyŽåû=ö iârÛD bÙFÿðþ(Ã$LcÒ¤IfâĉyàÐkZ0ÏËšW()^yåsüñÇèéúÞB¤E»úâ‹/Š÷ûn¼øÖ¢(Š€" (Š@³"«@¨Þ„—È2âÆ‡Á©‚F˜^Wú¾bUEœå´ñ]«àG-j°@O«ì¨ÇËZ4ê]“çܯ~õ+Cè"\›­ÀgÍ_Ó*°Â²ÖZòùçŸ/ ¬GÆî0J#øª7_ýŽ£ÑHŒ|+m;Yx‡UZ:ië9e(ÐÓöAëÅ#€P0Ö:„Ýiîáø–<êx¾àÑâ¿Âý,‹F¸—yiô°á\ð<`ïTx¶Ô{¾$]Ÿæ|˜FÙ´ÒôGë”@˜çeQÃÈKp>$²Õ¢”‰^ŒþóŸÍË/¿lÈ}&I}™ýѶE@PE@HB V€{p–D¢µˆÛñÛo¿•/ʸcᣥ1ÀW¼JV_}u‰µ‰ë¿o~øâ9!Œ°>Çb«œpñE#Üfôÿ¼4P4*~t Ñß🸇ŸB°b.}ÿý÷’ô pAÌ[P¡ˆ¡8a~Þ¶²^‡ Œ{·ò¥–Z*ëå‰õI²M¼ó¢X5£ÄAz®OFmþö·¿IlNŸÍûâ‡Ï>i[ùpÊ&Ö:„Ýe¢¥ ž§¡Á=L¬Ù>}ú˜~ýúE»™ø; ÄF*@ƒpi({‰…Û»wï„+²Ÿæ¾fMD˜&(}Pthi_à9a‚Êäyžy…Ñ {#Ö _Ô¾ó¯YFöú믛§Ÿ~Z¼Ú6Ø`ïû›f§öCPE@PÚXèÁƒ%Êâ˜Ý|óͲßyç%Áaᆵ\ ,ØqÇÍ7ÞhÆXArüðÅs^þæÌ™cöÝwßNsÑz æ¥À…DÊ.”Q=UŸã¾ö¡Œö¬Î?ÿ|óÀH(¢=÷ÜSb¹Fë¥ý½âŠ+šK.¹DªWmå lï½÷6wÞy§ð0mŸÓÖ#!é•W^Y«Fb”v¬¾êÁžG|ðéÙ³§¯f¥_üðÚ)m,7(›x¶±Ö­¿þú’.ÚXùä±Ðó–†þúâGYc×v³!€²iøðábÑΕX¶GçK/ .çù4[á¾F8N‰bZ¤¯`E¨©MmÌqæÖòË/_¤93kÖ,3fÌi«,÷¡FS^LVÖ>J 6„d>°j$F)¡ôV ž\vÙeÒÞgŸ}ÖI \„/~éƒ^ë„òãÇ_ {TáTÏÓÐ`^»õøw¿û]æy†FQd¡A¨¥Ç{LÖvÖwß…ö<òH {‡0™NZÚxλÁ AƒDiTÏóÌ+žý„]íÞ½»„Ík”'d{s_GGh8”sçΕ™xviQE@PE ˆU `Qì#¼ k®¹¦|ZŒvï#|]|ñЊ­¶Úª¾øä9–ˆÎŠ,ÌŸ4Âí†ÿÏK žX×5[ÿΚßÇýíÆVXQññQ°rÅ‹ƒÂ\­²¸$¬ÐŒ†>ñÑæ…¬‰‘²´Q&O|ñ#Ëx´ny ”¿ýöÛ%DÂî¸{¸ ž§¥Áš\«ŸI(¥¥‘ÔN½óÐ \Z›[bë­·.e=¦ýª×ùzcÖså#PÏóÐÀK¯W>„•Ñ¢øF€P¢þóŸÅœNn¸a)Æ*¾û­í)Š€" (Š€"± ¬ÀFŒÑ ¡h u^α¸öYª á³¿­Ô|Å’Ÿ£´ù(ªàG „ÒXŸ÷îÝ»#Nt¬ãhøž»ôK³Z­ÁÿÑ£G ŒõU`E¨BPƒ›ãJ#1§ðüAPæ0"žzR©7ޤkÓž£ÑHŒÒöÛW½,<‰ÃÊÍ+_ýq4ÜüõÕ®¶S§lb­C(½ýöÛoÔ¶àxNcÑõ*/îáe—]Öl¼ñƦ_¿~¥Ðˆö-Ï8ð0[mµÕÄR6MbYò&àAHÁ ŠŸ%LÃÑòÙ¾¶Õ|„y^Ö¼r÷6!4™÷UBÛ¸û0ž]¬¾ïŸªÇ¥ôþ Oâ°J³Îeé“£µ»–æBÀ)›à9Šrß>Šã9mE׫¼ísŸþù²‡ðŽ$Ww9|шö-Ï8¶ÜrK³ÒJ+‰÷"Âú¤0FS§N5=ôÞd“MÌ6Ûlã]¦Aòe-í@˜çeÍ+r8m»í¶fSŽqóÍ7/Tr}ÿý÷†ÜYÜ[ä` Y9ßì £Ø­[71¤@i‚bÃ-þW¥Béì)…ÀóÏ?/ ”Çm´Q‡±L)Ä´QE@PE@P<#«@pÈQÁK8†:1B<ð@ï „*hxưešC0|ê©§Jn5*±ïUð#ކ í€Å$ç£s1±ã‘ q4ÊP  <8ôÐC%ìC³%Qv÷5Ѐo-L«À*ÿ{ýõ×7{î¹gGP4Ê‹#j¡%<µê#\¯Èÿq4*4 £"cÉsmžÄaUkžçé ׄiämC¯+”M‡~x‡w^"I÷pšž„y]¯Ò\Wa%$ ý,ƒF”n„K{â‰'äC#>õ }—ÛgÎf›mæ]¦Q¯/z®}ó¼¬yÅ\ÇÐÏ%”‘eú޲àË/¿+t#>ú¨„MbïÅùpa¯†‡&yˈ·Òzë­g]tQQ0à­«¥5@Y„÷Á«¯¾*9@x–hQE@PE •ˆU h>ï¼ó: ˜ÙȺ—q¾ùí»TAÃwŸ[¥=^N&Mš$ÝÅÂ1¡ ~ÄÑÀÒŠ0Kl´ãæbVÌãhdm#M},Ɉ߾ͦ@H«@ª+B¸µ„—chº‚UÞW_}%?q߯2ŒºŽoË-·œ9ì°Ã\·b¿ë#ö‚ãh4£C(tIžÄaUˆxÌÅŽŠ ZšxòÚk¯™k¯½V:•æNÓ{ÇsêF׫4×ÇÕ‰ÎkòEÕZã®Ïs,Ï8ܺ}ʸ$ÖÑn<ÇÃk{ž>Ç]¦ñÓO?>ZÚ0ÏËšW ˆpþüùâqã;Œó#“‡~Ø\~ùåfÆŒ†ÐLÑÂ=ÃV ß~û­yçwäsóÍ7<–¶Ûn;³Ûn»I˜Ï²ÞÇ¢ýÒßÅxå•W$÷\ä>Xj©¥Š5¨WçFàÓO?5|ðAîë[í¸u¦ÕÆ ýUE@hbš¯ºêªNf,s>ø`é9B=Ük}—*høîs«µG‚´V¹Uð#Žä)S¦´i•õøG£^ý¼ç\è¢f _ÄxÒ*ªÀj‰%–èXKàoøEذcÆŒÃý/Jþƒ…®–C=IPo¾ºG£‘ùWÚv²ð$«´tÒÖs4è×-·Ü’ö2­Wå'L˜°@ö¤{8M·Ï©]¯Ò\W':¯ õãöW¾hDéæŠö Iá‹ ·öÚkwŒ!‚_ß%LÃ%$õMCÛk.ÂÐÆ`‚c()ñ,@AàÅ(Ê—â½÷Þ3\p¹ï¾ûÄ|ï½÷6x…—q¯5×,hÝÞ`ô2öÅ_”ðX𤻱¼ÄëY‹" (Š€" dG V€åKœ€¡èÙgŸJ†+ª ‘¡;mU¾.¾øâ’\r«­¶J5¶*øG‚{¡Š›‹©:ªG#tÚÛ¿$ÿÅ‚Àf+ðßYó×ô ¬° ®µ–F/ Bü* /ï#gE[~½qÔ».˹8Ä(Kß}ÔÍ“8¬|ô!܆£AXU „‘iüÿåY;Xëv§¹‡ÓôÚñ}Ìꫯ.ÇØ¡P`màZ¼ZÉ‹ðöÛoâçóyã7̼yó̇~(aIŸ~úiÉÝDŸÃÆEû®×ûCþMŸ>]¼JHFO^-Š€" (Š€" ´± bÃ1ÂËXHÆ&˜Í0ÖÙ¯Ó ¬¹¯§œrŠá……p ð¦ ~øà9ýÂú¼wïÞ±/r>h$˜‡ŠƒfMÿG-î§@HÂ%î|+¾XÒå-\‹"†â„ùyÛÊz‚2î,±èó]G€%š[óbÕHŒ|c’Ôà€ …Íò믿.–3¼,cýÖ«W¯Âíjùà%¤ÿþföìÙæþûï/…¾xN;Xí»ï¾æ¢/õPÌKƒ—;bܺPFõhT}Žûúˆ#ŽðN¬^zé%á–u›VYe•Üt¸þ’K.‘ëI¨\e! ë!‡bÞ}÷ÝR”k„$ F;s»VĨJ~@ ž††\$ŽôY|ñÃgŸ´­ü8ek!"V[mµNUÁó44¸‡Ï?ÿ|Y+f-ihdm3Z„="y+Ï5,©}+ñh—5‹j?Xb—¡¼ŽM7xŽ5v™<Ï3¯0®9úè£%a1BÞ"¥y Î9çñT#äë–[n)¡‘X›Èã§°·Ä¸fܸqfðàÁÒöM7ÝdÞ|óMsúé§‹’‚Üe„˜ÍÓ_½ÆÈº‰—¹5¿Õ³gO…EPE@P–E °=_àc_BÆŸ+6ik0räHiÛZÙGuT¡­%Ïýtý¶ñ‚ µÛU.¶›×`èСµê|ð#7_<·É­n)8묳:ÍE_4âúïŽÕ£Qk2­B`-5g×V³|[åFÀ¸øø¸¿Ý¸ho¿ýö“{³[·n}‰u§ZîÛ¾ô6q·¬[§žzª÷þ3wÚ+ïàÔhžX¥gðÐC_ýuZùáÇÔ©ScŸG¬Öú=_‡ôªÂ0_Ü:7_Šð´žK™ÚÒÊ~¨Åø]„çizYt^¥¡Q¯Ž Y#Ïzk¸Xq`“&V ^ï’\ç¬u{0mÚ´`çw e7‚n¸!°†¹Ú‹»ˆûȽoµâ7ó°QþXoá û‚Ç{¬Q]é’tÁ¼çlU}fÔ¢(Š€" dA ÖÁ¾|›óÎ;¯Seû@Ë\°–Áû€ºlf†ÏëXð^|ñÅÒ&nÓeñÃϱÎZk­µÌÌ™3cç¢Iàæ¡A¼Zbp““\ÍT¸¯­P\ºDœÝQ£Fyë®öÜã|WV°fÈA¡Í*ÃY™Ì·W^y%ÖzÙ`>°j$F>0ÈÒ’â†éûàG¸=ý¿q*kvÂ…PðzŒ›/Uð<‰óÚ=#jõ3 É$I×§9OøIö|Ƚâ»Ð~xüÖÒÞ¸¦nÏPÏóÌ+«p4ß|óì;Ø# c„§/9 ¬SK4|ö·•ÚÂ¥{àÀÒeÂÙ¤"WÁ86œ™3gŽXíÄÍŬ¸ÇÑð=wé“MTlþú׿J¬Ûf c¿<òÈDèªÀŠjÂÑPxi_l±ÅdMá÷Š+®Ø‘«ã׿þ5‡*+( Ò`ä:To®NÑï8Ĩèx²^Ÿ…'qXñ¬òY 7}¶­mCÀ)›XëP”¯¾úêÅüÇÕŽçüŒ®Wy pŸ{î¹"œ'¬Y4¢}ËCƒP,ô•5š3IaŒÈ_ƒ%7…=Êœ¢yq¢ãÓp´¢uôw{!æyYójùå——=' 3¾¾Ê3Ϭÿ7ÖZøþòË/KîƒõÖ[¯½QÒŠ€" (Š€" øA VúOÜÆ83Ê^Ð)XT°9òm¥[ @üËöøñãeä·O>ùäDªàG B;`†0;n.&v„1Úzë­ë’F)2fÌ©/ø%‚Ϧá³]m«yó¼¬yE¨)3ÇÝ»ŽDæÍ›'ïK´_FA‰Ç•*Ê@7_›¯¿þºä>@áŠç–†–ʇ£^¥(Š€" (Í…@¬Aóù矟JÀÜ\ÃÑÞÔCAüĉ¥ KiõÚ+󮨄/"m+ÍÅï¾ûNâ÷ƒo³)ò(Êäq­¶qóÇÚ‚—H•aŒÞ·IX/¾øb¡½Ürˉ2H~4ÙŸFbT5­Â“ªqQz@ÙôÚk¯‰µ/g›ùŽÎk¬ž›±ÃÛí°üNR 4ã´OŠ@Zð²™?¾ä óÆ(-}­×ú°?CYûüóÏKVíhQE@PE ÕˆU h¾òÊ+; ˜±ÈÅó€²ÄKt„ñ B4|ö·ÛÂ"¦–õytþøcIÇ<‹›‹©:ªG#tÚÛ¿$ÿÅó€dÊÍVà¿{­‡iX­µÖZk B-Ây¸‚PöÖ[o•ŸñGíN•þÍ|s¥ }Ro¾:GƒPÂÈ׸Ҷ“…'qX¥¥“¶ž£Á³p÷ÝwO{™Ö«„òܬu»ÓÜÃiºåxNÝèz•æúZuÂý,‹F˜v^=lèJ±'r¹ðjàï‹aºa“&MêPú†ëèÿí…@˜çeÍ+›;w®|ȰÛn»yò!‡"ž I ²&àyÉsÅ¿ ?‰0zæÌ™æ‘G‘ü`áv¨£¥9 ÚÓO?mž}öYCÞƒ6ÚÈ{®Àæ©öBPE@Pº"± ¬Æ?üðNx°¡-#n|˜P4ÂôºÒÿðuÔ¨Qb³öÚk§züˆ£Á‹Ó*«¬"aŒ6ÜpÃT}­W)ŽF½úyÏ¡8p“¼m”uü?å”S¤ùz „*°"DU­µ„—g1'Ì—üAPæ0ªÕ¿p7ê#\¯Èÿq4‰Q‘±ä¹6 Oâ°ÊC³Þ5ŽF ôztõ\2¬]¬¬u»ûõë—|QŠŽç)ª¦®Â=L\l•Ûm·(ÌÓ¬9© ÄTÌ3¸^iÀ€Ë;¦Ùñl©÷|Y rÎaeÓÊÙE½Ì3až{nº£9”ƒÐañ¾ˆ$ä|Ò„Ðxáâ]óöÛo›ûï¿ßÜ{ï½æwÞ1œsÅõŸfôzuýìJߟ}ö™Ç|úé§²f®¹æš]iø:VE@PE@hsbl ±ö)Z°šùöÛo僅 rܵ4°G€ô'Ÿ|"–¾ùá‹çûÛßÄÊjß}÷í4}ѨDž¼4x¹#‘² eTFÕ縯<òHïdÁŠ],ä7J”…^87^´]‚ª…´ðFŽ)aʰêc~0µ(VÄ(7cs^OŽ8âÚ€€ÇgñÅŸ}Ò¶ò#à”M¬u¿ýíoÍꫯީ±*xž†÷0‰aΓ5kIC#k›ÑúÐG”`ê+)u˜÷5í²/A©‚u9Š-í‹<ÿòË/Kåyžy…a {$ž9Ìûª }æ‰ý9‰Ëo»í6±dg.Ü'ì³XïP’8Ь¼òÊá*ú`/LÎ<zöì)ÞÍèÜh”¤" (Š€" ´ ± 6AĔ共Ha#|ÕUW™›o¾Y”;ï¼³>|x‘&õÚDëjŸð‚r衇zç‡/ž#¼%I1£sÑzPæ¥ò€˜Û¾›-‰²»¯7ø½¿~`E¢ëx@Bí¹çžfРAîtæo°k”ómöìÙ2,™œ¹ÿõ.˜7ožä—)ŠU#1ª7¾2ÎÁBšñYc5¼†DñÅ2Æ­mfGÁ߈#D ÍÕqï*xž†aÛúôé#ƒŒëgÒèÓÐHj#é<4®¸â IŠWqá÷ßÿ¤Ë2'é59·^|ñE³Â +ˆÁÀ&›l’© ­ÜZÀó“O>¹Tžç™W„éâSu ùN @IDATAy†’€>£4¸ï¾û̇~Ø©xæbœÁ}Âûû$Åki¾úê+ñ>ÀS„÷«uÖY§9:ÖÅ{7È?þ((  foŽç.ïÅì1»òñ.>=tøŠ€" (ø§¸úúè£Røá‹çX ¯ùÕW_í4}Ѩe^$¸#7.çÍV¸¯Ç'÷·X!tç>G„ ·H!A Š>¼UYX¯Î:ë,sÓM7I2Eß´y‰ñU#1òIR{ðäŒ3Î0çwž¹îºë’ªg:ï‹™ˆjåÒ`-BçÖ¹¸ùRÏÓÐ`^×ëgHih$µ‘tä• Œ 1½ËØÃ±/Á¨ç1ÞçÏŸŸÔ-=ßâTÁó<4âc\C&¼Ë,tp¡¤{ôÑGŘg—]v1]tQ'劎ÄÔ?õÔSÍ]wÝeN8áU”É móž‹÷ÁòË/o½Îí•£9½Ä5á­Ãç裖gMß~ûíB0éø{ï½' ¾ë¯¿^øšTŸgf–ö©ñÆo,­}úsË-·ˆW ýÇÓÊõS:«E@P”Äz °ñÆ" ¡"+gÜ7‰gŽÕL‘°&Eú¡×.ˆ/#„“*ƒ¾xNü×)S¦HÇ—Yf™æ¢/ ¢²à¯¼4\è¢fŒGË}=qâÄXL}¶_`Å\â>ç…©hìàY³f‰`^|Ðå$ÈÖ«|µÙP³öQÊp=g~øÀª‘åC6ÿUðä’K.‘°$ÃÃÇWñÅ_ýÑvŠ!€Pþ´ÓN[ Áxt¾TÁó44˜×n=&_C´ŸIH¤¡‘ÔFÒyh°_pß¾CˆAKP¼áx~àåP¤qêùjp!xÊäyžyuõÕW›É“'KÈ.iÔ^¼_pÁ¥Ÿkõ5íqøÏË(%ŠiÚ6âê¹*6ÝtS ;…õU‘Â&K ‚µ*. +´yéð]˜>°j$F¾1Ij¯LžøâGÒô|5 ”ÇŒµŽxq÷pÖ„½C°Ê*«Ôë’žkà9ïeò<ϼB¨ÿÊ+¯ÈkŸ ò‰ ÀäÙýÄOˆâsÔÓ5½/F(ë®»®ì¶Øb‹Ž½[°¿-‡À¼Áû#ÖJ³ZšýöÛÏ,¹ä’âåÆ3Í ÌÙ8>Õ;Î9”yxîc¤€—\½úYÛ§>ïf=¬gr’2Ú‡‹.º¨Yzé¥EyùÖ[o™sÎ9ÇŒ;VB¢5§´Š€" (­€@¬—8¹ °\[sÍ5åÓ `´{á+ÂX6·$‹+£øâ9í HÀò WàpñE#Üfôÿ¼4°Zßc=¢Í5Åoø?jÔ(é‹OXñ¢ËÇGa3Íæœâ>ÚMÓx‡‘{±Hs]Ú:ÌX5£´cõU¯Lžøâ‡¯±j;ÅpÊ&Ö:âè“`4ZªàyÜà ȃ€eqÖ’†FÖ6£õ¡À5 !ÿFm­Rø7F (еtªàyìeþíßþMŒFø*.VÌ„U›1c†!ar¸°v¡ôDÈÇ}¶Ï>ûHx•2<…ÃtõÿâÀKÂsË-·”w¬â­j ¾@§ Ìzœçô™gžÙ©[YÛ©UŸ÷ó8ƒ©Zõ³?ðÀ%ÇÆ^(1 §J^#rªhQE@PÒ"«@@¸8dÈNmD“°¢½ÇµÝg©‚†Ïþ¶R[¼¹ä¶„³I#D®‚q4ØÏ™3G¬¯âæbVÜãhøž»ô +3\Ci»ÙÂÁ:*º*°"V9 Ì(¼8#¨rüÀr8À„U”i0r}ª7W§èwFbTt r ¼~Üoî=îAß%L³Ùh pï§2hQE@P² ûäpĨ€Ù%a…–Á#GŽ—ó,“êVA#©ízl'L˜ ÃcópÒI'%µ ~ÄÑ@à€›¼´ÊŽzƒ‰£•ªï‚òà°ÃÁ7¡Œš©¸ûš>oôþv}­+Ü€IèM!ÇÅàÁƒ;úƒÒ Q^Q[\‡ßõÆ®Wäÿ8ĨÈXò\›…'qXÕšçyúÂ5Žár´4(›Ø—8åßI÷pš8žS7º^¥¹>®¡.ð’ ÐÏÏ>û¬æšw}žcyÆÁ3í©§ž’ÏV[meøÔ+Äs衇¤ ãÛf›m çÅ‰Ò Ó@8«¥ýó¼¬y…b¯iù>à’(yîܹBKö_ÐB·òÊ+›]wÝÕì´ÓN¦‡õ€dŸFÁ%Kñ­(ÏB»+×eB(*(“÷iåEs͈k®¹F¬íéÕ°aÃ$¿Ö÷<}Pú¤‡i6 Œòœw&ÊR-Š€" (Š@b~FÌr±˜£tïÞ]\á| a« ‘ vª ¶Ä<¤ ‰ò7n¬Uð#Ž1`ÉÓ0sæÌع××zÇâhøž»Ð'‘ñûÁ·ÙÜ×iHU`…ðÕ­%¼tí¹çž „¿ÿýïæ«¯¾v²©¯2Œ6—°w¹å–3‡zh½ieê£î…NÆÑÀ¢©Qe躗ªYx‡•oB˜†—j#Þ@˜C¼þ믿^ÚLs§!æyt½Js}\è¼&7Q­51îú<ÇòŒá˜Û7 ŒIR Ðwã@ºÙf›yW „iäÁA¯i=ÂN™¾6îöK,±D¥{¥¸~tÅc¬©ä> Ê_^o]˲Æ|ûí·KÈÚGQþýÛßþVÂåúV 43vØ¡,¨µ]E@P.€@¬âW\ÑIÀŒÕŒ³æã›ß¾K4|÷¹ÕÚ#¤@Z¡Züˆ£AX‚)S¦´i•õøG£^ý¼ç°<»ù‡æm§Œë¸¯ ¨¦U`E·–ðò MWfÍšeÆ'?ªÅÅuu}ó2è0".w’¡Þ8|õ-ŽF#1ò5®´ídáIVi餭çh ¬Ž&ÀLÛ†Ö+„ò§Ÿ~úIØ“îá4=q<§nt½Js}\è¼&ÄI­51îú<ÇòŽƒëØ7$…/¢OXV»q`^Ûóô9îš0 ®|´´7až—5¯@pÚ´i†ò ƒŠ›îeBt¾ùæ›æÔSO•œK( ˜ÃY½\_16zôh³÷Þ{»Cú]ð åÊ-òÊ¡@`nji.x9C$že(Ý3 ÅAϨf¦ñõ×_‹‚.¹œ/ÍÅ1í" (Š@3#«@àa'`æAC ã2’{UA£™Rfßàëâ‹/.aúö훊Tüˆ£u5q6{qs1UçC•âh„N{û—ä¿x dj¶ÿÝ&º¦U`…µœ[KPf„-ý>ÿüó€U*˜o#÷‚QõÆQïº,çâh4£,}÷Q7 Oâ°òчpŽ`¼´4Ž'¬u»ÓÜÃizïxNÝèz•æúZuÂý,‹F˜v^Œ™°..äR¸ÍèÿÒÜÚŽ@ Á¯ï¦‡B<-í@˜çeÍ+$Ô“¤´¬òí·ß>> ”ZªE€ðn(>øà³óÎ;‹×tµ=PjiØo¿ý É­)=l˜0,ðW[m5ù½ì²ËÊ{¦üðø§™i` úÎ;ïÈh<òHÍÙá‘ïÚ”" (]Xî´Ã‡ï4~¬ªÏ>ûìNÇ}¨‚†Ïþ¶R[ðõä“O–ä’¼Œ¥)Uð#Ž¡€VYeÓ«W/±êIÓ×zuâhÔ«Ÿ÷ŠƒFÅïOê3ü5j”T«§@¨+B‹ÔZK°BCqÂ|ùQÁ^.FÄSO*õÆ‘tmÚóq4‰QÚ~ûª—…'qXùê‡kÇÑxâ‰'Tà@i’o§lb­CØíâüížãyÑvÂ×s¸OŸ>fÛm·5eÐÓãÿ<4Pî–ƒp+n“Jš< Im$Ó;v¬*’kƒóaž—5’©b@Á½6j(‹ž¶Ûº^ê¹çž“µa4kc½}u뎴õ{UúðJLB¥™iÜ{ï½!«I¿“¸©çE@PÂÄ*Ø‘dÇGÁ2†PXÚÞ… º–Æ À‹ÑÀ%®*ñ:±Î,ƒ>xNsæÌ1ûî»oì\ôA#‰ yhàÒŒU’ e”D£ÊóÜ×GuT)$ÃX!ÄãŠjÿý÷7ë®»n³tMûA^±ç¦ðÞ›õùµ<£x:92 Ÿ¥Jx÷cœÅм«ù¿¶¥(Š€"Ð:ÄJùxH²Ñ-jMPñõ×_7o¿ý¶<¤°~â\Kc ‰.1Wá-› ¡C‡zç‡/ž³±á¥‹MUt.ú¢Q yi <8ì°Ã ‚ïfK¢ìîkÆ ¾Eïo‡X½ôÒK¢ð!l‚1¼Gò°k”óð@~ø¡Ì?ú,àHòŠr¬VÄÈ'iÚ‚'óçÏ—å1}…¥¶/~¤‡Ö)”M#GŽ4 (|GçK}z©<Ï3¯ÊòrØb‹-DÀÌ^©Œ‚@´joÍ2ÆÑJm¾øâ‹¢@à™C¸+ÂÃjiN®¹æC‚rʰaÃÄ/KOy@–AÈ1”u½{÷O¥,m$Õ­’Iâ‰BÀXò/$EÏ+Š€" ´7± Í?O:é¤B£' ͵×^+Vv¼ÄW… -t1‚øI“&Ið²o~øâ9lÒfΜÙi.ú¢Q̼4¸Ž¸èÄŒn6÷õ„ dØ„)*z;üó%—\bؤce7bĈB ,}ÈAÁ:¦Êã÷mÖ3Ï<Ó¼üòË#õꫯvÃôòrÂVÄÈ ''N%ai|º†ûâG†áhÕ@Ù„0úúë¯*-DçKÇ¢m)Š€" ´7± Í$Ùñ!`ÄÒÍ8þ×Ò`^?|ðü‡~0S¦L°ÆGç¢IœÈCƒkÎói¶Â}}Î9çÔÄ´H±€ãç Š”Y³f‰@‰6V]uUSee’°²öQÊ à«Fb$àTøž\|ñÅBñ“O>é$.Úü(Ú½Þ¼àŸ~úé¹)¿U @© ž'Ñ`^»õ¸V?“PI¢‘t}šóì(ŽVšk²Ô¡}×6ߎ^–6´nk!àöŸnÏPÏóÌ+ &Ož, ,ÂÒDc§·ÊÚÛ²@IÍ /,¡òÔŠ»,¤ý´‹2Ð"ñŒÉZx§ ?£²^Ÿ¦~•4 …w!FeàÂ:¬EPE@H‹@ìSƒ·ð&úÈ|úé§r޽F?([\’ûˆcxGª2!ŒfuÿKï±6É÷U]¯»6¥Ýwß½Ûm·áSf©’Ʀ›n* rí³Ï>ª@(“±Ú¶" (mˆ@¬áâ!CÚp¸]{H¼ 4H@à…ŧÙ7²$›#Ñ,–#­4±#y/wÍÆ~uÔQ¾Yå½=¬P/¼ðBiw±ÅóÞ~½Q(Fõªþ\«ð¤zd”b§lb­CñLBÞf-¬sçž{®äZYvÙe›µ›b¹‰çk1^xvhQÚuÖYÇyä‘Â(j¸âk¼(¸æÏŸož|òIsÝu×É·Kü^‹Æ)«­¶šÙe—]D˜Éš"/&-Õ Àþïƒçž{Îà¡ÂAÙ¤¥¹àÞ«‡‚Cƒ®\¸÷S¿]y&èØE@ȇ@ì· nœ€™02ÀX§ù~øTA#T­ñO;í4›‡O<1qPUð#Ž/EX€q.n.&vêfáIVn^ùè m8nþújWÛ)ŽÊ¦‘#GvÜÃÜËI÷pªŽçÔ®Wi®«ƒ—^ú‰õ³›S¾hDéæÏ4†òéÛ·¯Ùj«­¢Í.ðû«¯¾’ØÊDP7ˆoké0 ö5ZÚ0ÏËšW„aÄ;ÏÇ2ö‡ìÁ¾øâ óðÛ«®ºJî)” i aG\óáZr»°OZ|ñŽß_iúÓëòåé§Ÿ–uzàÀ†¤ïZšk¯½Öà9B9ì°Ã$$ÏB ^=¼kúVÄñ,oVx`‡G^ZVC€g©ï{¶0`Ü”®8öVàOWë#³q,&L°ótÁbvÔëÞ½{`]m¬àáW=ásá>ÛXþ(·aüÒb¾¦JžÛÍW`Ã:Ö!v.få–Ïq„Û ÏÃðÿiñÍ:Ž"õ­ (8úè£åw»¶Ãã+‹çS§NíXKìK{`_ÌùÀzŸö%[>V8Ôq¼ŠìKFF6qo"ÉzãH¼8e…8Ä(e·½UË“8¬¼uä …i„ïùðÿ6w‡o²Ú^ l|êÀÆ0Ït§h6ó<º^¥¹>®Nt^—A#J7 j¦c­=zt´ÉN¿ÃõGŒظòê=¦¾ï¢ÿ§éoѾèõµ¨Å§<| ·Uæ¼²Bù`ÆŒÁwß}W{`9ÎXëõà³Ï> N>ùäÀðtÜSÑ9›ö7ïiC‡ Þ}÷ݽÉv üJÛ¯f¬ÇÜ)Zàßí·ßôìÙ3°¡‹«*Ú¤^_ìÇܼäþ}óÍ76¡°÷ž´ ïÀhƒŠ@Al”‡à­·Þ Þ{ï½À*à ¶ÖZ—³‡xóÍ7EþjC ¶Vçµ·m…@¬ß—_~y* uûPÖÒb‚ –õy³ «¬)S¦Hw¬0¾eæ¢ ]äÜC›OúÁ}}öÙg7=¦ï¼óŽäꠣė­2‰2ñ‡Fö@¬ü°&ûÓHŒª†¢UxR5.J¯3|ðxÙ…“°c©ÛŒ%:¯ÇŽیݔ>áÅþAÃ5-‹´cž˜6mšx’tÐAf×]wõÔª¯<®¸â C²æpÁÛ$>ÜkÎkξm’öòaOŒ7ž+ìçþë¿þK<Á­B¥é÷ô®ß­ú§^X콬âÆîJKk €¢Ë§æî­Öèy9½üúë¯eM¡u¼¹Êð¶*§çÚªOx¾´¢%û7ÞhÎ<óLƒlè²Ë.kêP¥>ùE[È'®¼òJñ&¢ÈrË-盄¶§¤B VÀ‚'`æÁk-’¥á%–X¢c“›ŠRÊJUÐHÙ•¶«_qw&l–[n™j|Uð#Ž/J?ÿùÏeŽÅÍÅTUŠ£:ííßEYDB¯¶Ù üw›èz˜V!:ÜZB8hº2oÞ8Å óݹ²¿”9Œx™O*õÆ‘tmÚóq4‰QÚ~ûª—…'qXùê‡kÇÑàY¸ûî»»ÃúÝ8ek]Ÿ>}ÌöÛoï¥WŽç4]¯òà&þðÆo,ñˆË í[¼\’Œš˜ßU“ ñ•û÷ï/ÕŽúRâ„é†iLš4ÉLœ81|ZÿoCÂkˆçþÐC‰—²ÍÜu×]ƆÖ1+­´Rr¾ñCBaÃóþµ×^3{ï½·YwÝuß)íAj¢û4ž´#?ï<Ó}—f¦qÏ=÷˜'žxB†¼Ç{¨Á7ó›¼½Y³f™ã?Þàmwß}÷¥2 iò!i÷E bbllqß^ÎIRXf©‚F™ýoæ¶y1ÚgŸ}¤‹¼ŒÔ"»qTÁ8hÈçÌ™c°‰›‹®i¿ãh¤½6K=´Â6>Ÿ$µk¶0FðÛæ@HNXá]Rk-ÁÂë /”~bí[eAi#×§zãpuŠ~ÇÑh$FEÇ“õú,<‰Ã*+½¤úŽF ô$Úz¾>NÙ„âáÜk¬Qÿ‚”gÏSVOU{øÜsÏ5«­¶šYvÙeåšZkbªSTÊ3,7—_~yñ¼ ŒJR#ž3iö)º[³J˜FÙ´jvBOTŠ@˜çeưæÈ#Ëa†+®Ÿ/¿ü²y饗:¬%Ë!‡"Ö¿x§)\CsÖ4Ö‹K.¹D2sí믿nÞxã U ¤2Gø‡÷Á¢‹.*Me¯Ó9º¨—ÔAKkþ åc{·f¦YP4|Q‰Ó¦§ð\³¹ÍóÓ¦#Ôa)Š@ÙÄ*°jI+`®×AÚùöÛoåƒÅ =±µ4ÄL£°y8üðýóÃÏÝ|aÓ‹¾hÔãB^Xšá½Ã‹Æ\PDåçXRœœNЮs«'ÄB -dŠ„pBiÐ(/7߈9Œ"%ìá+L¼Ì`ÑV«Fbä‡,mÀæعY®¯W×?êÑÐsÕ!€² —|î1 ßQ ø*xž†^V.$P\?“PKC#©¤óÐøôÓO%ö7ñ¿`ÊÈgÁX€ñ aüBÑ¡¥}p!ÊäyžyÅÜö=¿á¢MøhlâCa(ÏýwÜÑ 2DBŠfår·nÝÌðáÃ噈¡{@ñC7¼±´´·Ýv[GÈ„çYï½Ç{LdŸ|ò‰x ´œw<Ÿ¥jx@í´ÓN•¾_ùÄKÛRE@h± 6º¼40²™}ߺI;«2âïji@"Àð]|ñœP S¦L‘î±Q ÏE_4ê=/ ^2Î7[ø"ÆV E1­‡EÒ9°Âº‡ûë8b)$÷7nœ4¿Ê$Ê$auB=¬#}—üÑ VÄÈ7&IíÁ§Œ#¬YT œt}½ó¾øQ†ž«žixÙ‘H™Böè|©‚çih0¯B?®ŸI¨¥¡‘ÔFÒyh8Á'϶2„“´Oøž<÷ñâÓÒÞTÁó<4HrÌÁüàÁƒ½$Qf¯Í}Ä7ïTáM£Ãm“ˆ MÒÞ3¨šÑ±·EyðüóÏKH<¼Xµ´Èœ!RžgØçŸ.!Ègpñœò]ª¦AhBÂíb aŒ|s³9ÛC9γ‚g#k…gÏ ‘ â¼kðD%Ü^2xdu€‚G8ó‡°–õÖEžÜ3Ü{D( .ía|H[ÈKÈ?T¤ð¾ÚeŒŽ÷~½¾9šôñÑØpO¸ñÑ7°I*ô1¹6¨ïÚ×4÷xÐý¡=úN?0fH íãqc‚‡ÐÇ8ž%á }>ÔƒgŒŸùãÂ^±Iƒk´Oú»}ˆU ø oB;L<\õ™°|´4øÁæ‡o³2øá“ç,t<ð”Ÿ4Âí†ÿÏKë2„e`î_žÿ“ÛDG1ÍÓž»†v/÷9ã/jµ‡Õ+^kU*˜o`Ĥè8>áo¸>°j$FáñTñ¿ã  6ƒ>‹/~øì“¶•„ò(X“ØlÇÍ—*xž–F½~&¡–FR;õÎCƒ>=zô0K/½t½ê¹ÎñRÃóˆçû^–´´7ðܽ”Åó<ó A ñîùàí¶ë®»f„»‡èÂ'è(Ú0B'báã;EÛÖëÿž'„/ƒ„œ:$“×ÒzK9…çXÖ»(BN„­qÖ¬íÅÕ¯’Æ_þòó§?ýÉÌ;לp šD9Ž!mxìšk®c aðžwªË.»¬ÃÔ¹=tèÐŽœ\@€0œúx¡â%óÞ{ýõŠ+®h¶ÜrK³ýöÛBañŒ‹+Ï=÷œyðÁE1ß¿<“¼Ï ®9ãŒ3$Xܵiޱ>?ûì³âeDbhæ7a~ñ–%é=ž­µú(T¸øðìLj#ò m³Í6âuÄþ”gl\á¹K„žwÜq‡DÎ@!H}rÑÎ^{íeȱÄ;I­v;2ôÖ[o5S§N5 ²÷îÕ«—Ù|óÍ%„(ýM*Ôa/sÿý÷›G}Ô¼úꫲv±öṿð‚¬'"É:F¼«®ºª0`€\O¿káW\áÅ"i,z¾yˆ½ÛÙÐǽhAÇbA(n^µWÑb×Ã×Q£FÉK:‚Þ2øá‹ç,šXŸ³pFcŽú¢Qͼ47*~½ñpþ6€RïÁ!2ü+6è›Ú˜šl*Šºx³Vð°¦8…G†îªŠgÆqÇ'›ß.ÊtŒqùÀª‘8ÇÅð—/lX}_üðÙ'm+?NÙÄZ‡'åh©‚çih¸=ÑÆol¶Ûn»h7§¡‘ØHBh¬¹æšby4pà@yYL¸$óiîi×ö¾ñÜ×ÒÞÀsÞ ÊäyžyžÓY ²¯ñQP ÌÀb(ü±Á“ŽçY^e‚„:J\A™ÕBÑ]«ß@ƒ÷žQk¯½¶Ùh£ró«sëz¤Jvß}÷Bäx0a‚X#L›ø< Ñ*i}ôÑ¡.ÞG°6²°bÙÌþ Å2ßU”°XZ³¦²†ò©%àõݧªi#æãò±Æ!pç¹Gá9… Ûê¡4àý /Q°AÆÁ7˜MŸ>ÝüñAóYg%‚ržwÑB¨Bв—Dxà 7ˆ¡ʉõ×_?Z=õoú þÆo4×]wÌ!úÆqžµÌo xú"Äã+ŠÎÓ'úƒ€Ÿ½9aŒé7ms¿ì¿ÿþf‰%–ˆµº§cÆŒ17Ýt“àÂÞÁÍcžõ(%P–°† Ð`Ÿ-(!ô#£{üñÇ¥¯´ž÷Üs\OØ1žùŒ¯^aL't’\oác‚‡(9®±Š$<µ‘UÑ—8\xöMž<Ùl»í¶òìÃ%÷fÑ(õú®çZXÂŃ:¨ð(˜¸,|´4^Œ8àé †O!²/žóàbáes‹¾h¸>Ç}ç¥ÁÂŽ[(‹~³…1‚ß<}°B›ÍÇGa3ëBÖ°¡©²„•ÍRY…M…¬‰QYØÔjž Ô)£øâG}Ó6³#€² %)ŠG,Fyiˆ–*xž†÷ð¤I“Ī•YKYیևÆ{ì!J|°D¡à»ÎO3-]*xž‡‚b’°c}ˆÀØWqBG„)x9çE¡aV%B' <òˆX‘ÒG >¼?}·Úùâ‹/„Gx!à‰‚àKKk"@è ç­ƒ€0«€Ë]>e–*i\tÑEk‚ÅF¬ÇŸzê)TÃî5Œx¯,»0'°òÆÒšð—챨GÙ[vimžm‚¼ù曪—ðwÇsL‡õ?ø‡ _yåÙOó¼Yi¥•$)Výv¢ðA(λ:Ï¢;ï¼SìõÞÙQsÎ9òücoI>’~ýú™îÝ»ç‚ÏÛÈŠç·Ûn»Éû5÷;¡é^|ó•É ÁûåÏaôäj<ÈÍ…ÅýøñãEéBöèøÊ¢&ÐãÁp‰=-Ïdr²1æ‡~XrùñažE…öÜ„nÆcC”ž`ðÿ¥—^á=9e[=OC7&<±/}¦Ox¿oÈW‰÷s¥¡¡Q«°_A"‰=c£=ä‰Zº6±O&'7fTÀ쎓ŸÅ&NÛXÒ*hé_+_ûÿÙ;à;ª*ÿ÷üëoÕÖX2…ãÔ”N±ýA6YCX¾)!$™ !JBÂŽ,B°‚8&!²†¨ Bd€CBX"[ $J …R¢¼®sŸþÝî¾Ý}º_¿÷ΩzÉï½î¾çÞï¹}—³Ý"‡èÖ!úƒ(“¬«/敃‹‡tߥN„¾q05 ê&Qƒøûm뿯Š÷¹2BÖëÄÊ#îaëUÇÿñzÑö4ŠßϢȶ#í¹<×\<:‰QžºKÜošLâ÷V)Û%Ú¨eÈ À&…±• ÿ§õ_®Uô+”ñVqN=QÚzÇÇDßzfÝW¤„B£ìä³×^{e¢Ì†ƒM ĦŒy<¾YʪgÖõ(Ë+ë½ÞÝDe^U¿FQr€7^Œ’ó8ž‹%ðD„PjðN ¼Á¡€y*K‘Ç»Knd”%(Q°VƒPîðQ’A\ñ\eÌÛ|óÍÍáɪ0‘Á¶¥àÌ9m)Z0èñ>A¼{U(«™Ë›ÊcüøñF Hû«ÈD@¹>„ÃçmâHqâ¼¾×1žá©ƒ"žôÔ…óïðº>ì°Ã*IaŤ¼9B?g=sÞäÌy.Â@€‘]Jdpá}ð\Ÿú¨Ió†’ÙŽƒí‹ÂØÈ›orRú0þWqÞS´úä­GÒßÌQ(–™WÈݳK\ÙÒ™(:Rìš{Óˆ{0ÞM:Õ¬#˦ÜÑ€ÔB§Ÿ~º‰@ˆòfþ¦î(À930®tÇñe:ëp ¬kã{Ey00Ñ'I+Dº& [ñfÌíôÕ)S¦¬eİõ! õAŸÅ¾œ¢ŒD:€kR Yã-cý0Šèj m¤VrQ´Mè.pˆ°Æ{?mÂØBDóŽ´1) |¨û•W^iæAéqÒÖKÿï>œ3&Šf¬Âq#¿Ó‰ : +i%l<ºOL²5fÐŽ”Iꇋ&&XÈר‘Ô~wñî»ðaA9·ts­ÓV”†iX1‰Ú±„É— ÓöIBJñN€Øx“°.bCo1bÁ”e@Hk‡T]x¢˜ uŽ|¸NR)ðÞ’“™ïQB³é¦›E”=J2<õÔS&ÍJDdi^µ2µ”*@Yg‘˜Ëx­At"ì3¤cMæÂÃ$6Òm÷•%² ²‡ÿ­…g’7´o¹¾÷1.GÛ_¾Wm¸ ~äíƒX XƹRKóA?cÛ½‘‘ª`Òˆ2Qø3¦ú¬%ÓÊâs&呾ÈE¤¢?QWæÓ(±‡Æ(O{<ð@3Æs_œPäã}Òž,£R{â,JÛÁ‚~Œ±‚÷Ë~ø~ŽÁƒŒ¸1ƒzpŽüIDÄ¢‹¶Ûn»€3ÓX ¸(Ú&ÎZÀÂÕ&ÊÇ(DT†rŒ¨IdFT7팾+.þú[!à4 Ða\J~·V3þç»4ÕÁCºÎÝRØ2ða]'ÏŸÕ!$ üLL®¾èS÷è=I<¢÷HüÍ„Åd’4Kð(ZØEt¦u`…\íX‚W<-á-@„¿Nõ²ÙúÙz¹þOk‡ëþ"¿¹xt£"m(óL™¸°*ÃÛõ¬åÁÂ,ËãÆõ¼þV(åÉEÊxÂÅçö©•9÷ÆÇ+Ÿç“î‰Ö³*QÞEy`p&}k‡,b“dq¯JåÁÆ-kãšUg½Þ|¢2¯ª_›p>(9¤ ”Ëœƒ£‰ ·ttcÓ©;øøJ.ÖóDÍ»©$ƒ^œ«FÌJÝ ²¡C‡šF¬zò¢X³sJ±èþCª¥Mæ‘G-å Þþ 0BaŠB”µcõ,JkGÖ³¾×]<:‰‘o½¥îË#VRõ°åX,ÖH'¡ÔP3f0Öá©Ã_deNYññªhù¼Ãälå°VrœVÁ#^·"<›ñÈFQés°,ÑÚ±µ›"iŠòÀƒŠ4KJ½@TæUõ+¬x7£k)d‡ fÎ9!â…E‘ó;¬Ñ¯KuÂØwV!²èRݦ-#RßX÷‚‘Å Œ²‰× X£÷À9¢(EÛÄ!ÌIÆ“hùÈ4ê̽ÆßD_°Ÿò)+þ¬~ïmœ£$ÊE»Œ6ë¡Mïý]òï:xHÖ·›ÊbctÔQG™*ãñ”¦D¶íªC.ä‰%¼Šúºú¢­Ÿïÿ.¾Ïæ¹ ‚™ÉžM"äÍ¡}YTVx˜$%,f¿óï˜jJy*dµÙ^Çhàƒ‘½?­öž²ÿ»xt£²íÉû|™¸°ÊË/ë~˃ ˜²Ðª÷º56¡PCùƒw™Y™K”eËàæ6”ó(1 ¤1Ñ>Söÿ"í`COjÆb69YE<̲ÎI(ÛŽ(óÏ?_ eí‚ç£2¯ªº)ðÈE¡åc,Ë[†È{øÝï~7Xž‚b÷*mÖ”5xy'ÇŽk4¬Â@—·]½r?^¤$Ÿ|òIm%á¼Ô+Øts;PÚ÷ ÃDZÃ,<šÌ P Bu(ËÓ°B£‡”³G/×5Ö6|:AäÕ^ÞÎéÁézÖÔDca¼§ÞD¿©AÚPœîP^gQ†º,žI×Ñ‘¾ˆþOšM]XçF[.Ñ`DÊ2ô?¤wgÞ4hI­F`EÊa w.Âa–¹‡wÁÇá*ƒß¢m"²ÇÇÉ}ë’$j’̒꨿w§뙯‚9«Ú6_Ö+^ ^¥Î ÀF…üЃƩ§žZ‰<$dNa³Ä$æê‹<²¤P„!l'œp‚ÉaÛ´C”í{M»Á×Ç€”…‘½ÅŠ §Ì¢”‰¼SQô7Ð+Ú€ÑM’(—…|AQ¬:‰‘$>eY™X¼ØüH‘”<¤ê£å”CcÓÉ'Ÿl¼Š( ÅA¼¿Ô!slDHÑ–TOs!å){]‚qRzð!UŠtº6]Œ‰üÏ‘1Q7-^âéÚ›5ž|UʼH¿"B€O•DG ³õÖ[Eõí·ßn”Ö¤Mæ;ê±ბ€ñ‚¨*ÖF<«{)y)qè-ÑL¬g‘QÐJÝÔö@ãã?Þðò´Šw’9ŠùÐê1XJR\ñLƒæ¾ûî+.)™3°:E8q¼/JñHC²( Éß'lÓ qRÙ÷ÛâV.DÄ“à&›lRjãÅBˆÍ3o]„7ÅÌ™3â/‹ÓO?]”5‹útY¬:‰‘( …!¼5églè¿úÕ¯z<åw‹”<ü¸é]U#Àf†5Çܹs +<ûãý¥™ûð __}õÕ‰õÌÂʇGVY×áq×]w™÷{ñT’6 ` `LÄ“ ¯H"2tã“%™î¾ŽÌIS¥Ì‹ô+œ0:²îÀðXE#+9ÖJø0·ÙqBa­Ž ÏERñ>PŸ¸R–¥ÿ—G€¹ãÁOM£¨)Ži™º‚ÕUW]Üæÿc"œ2eJ)5î¡0®óe¤ð–6 °8Àª“pjü™Ì˜1ÃpD&q…p™ªHÉ£LôY9PÊeÇAÊ«¿Ô!sôkkÐwÕ3 Yed]‡Ç‹/¾hncn«B¡Fùßüæ7M:Ö#lVÕ€%™î¾^‡Ì‹ð¸þúë>(ídž)‚$QN“œx-òQê xÜ’¾ˆÃ'IÊùkJ½Æ7ëˆTd#]%^Ê«W¯öÙg£Ó _¿$Õ̓´3xLÿçþ§1˜J¶EËê’ 6/?©6‰RI2°æFñm# »¥åÌñŒ ïIY‡Qð_ÿõ_ÕǨ̞›‡›nºi[¹±ßˆX‹§7²…qH3ó ¹p²uA‘ÿÈ#˜TQ®50ºA1\¸È–C›pÐà{’ã FË!C†ù]uÐßúg< X*½ ›N†µÜõÄÍi)reÀÄâˆLª’‡”Ì™°ðxtõE)iÒ)ƒ ˆüý,6›FVþô¦eêËäCŸâÿ²ý ¯D¢8ø<øàƒeª•ûYê6ô½ªÂ2%°ê$F¹A-ù€• ›@>Ò$!é:iyÅ@)ñ€±Ž…sR©Cæ><²ê™…‚¬2²®SG>x7a –&ÊŽ¶ƒïJ½@2/ƒþ²eË‚»ï¾ÛDÅ4E x ¢xÀk0IáÓ”ºvc=ðÔÄx@š6I(ƒ’/ÝØ¾~¯ó˜1cR°ðY¿€‘Ž=MtŽªÏ:y06>ðÀÁ…^h¢¡«h–Ù\èËôÑ(¶qØŒû_î! •y'îùγ¤7Â!#Jë4/ûxùþŽáŒsŽpöÄi€(X×ÜJD"mœ4iRpÊ)§´S¡QÞY«ïÀàRìó;‘ÆÌ-àh=ÿ£ígL"…ºÎÕãàjæû(ñ×ЉP¦‹¢mÂA\n<‡3é%—\ÎTæ¬{”¼8##çTò²Ä …§óöÛoocü­Ô9+Õ¤”º\…<¤dÎä…÷9^@ñƒÌ¤x¤I¢(Âý:•¿?­=\Cþx@’°ÂC÷ <Ц2„!ÂZò™Pë$Þ Âñ6°›JòÇ0!U'1’Äç,dÂÁÖx^l³Í6>xß#%o†zc¥01f0Ö‘Äu0_2÷áÁ;ÌXÀ&f¿ýöˋ܅ƀ‡M£Â<Œ÷•4‘ ‚¹žM,ÞnI^`Ò|µ¼Î!€ÌÙìV)ó"ýŠu'ÏñnV©@FQ7!ÿ³ft9+°ñGiÀ¼‡Ã)Žx†*¬±XÃa MJuÐ9évg(V®\iö¾xš*õÇ/Õ˜õÖ[Ï–0 yPÅØP'" —,Yb>W˜w•úúk;Ou"?ÙgÙ”6¬£IáË\È^¯xÎÝcmÆ\ż‰ìP¢3—alàžï9rdðØc™÷€4¹8¬ò.ÐFæ_ÚsÝu×™èX¾|ðÁké7ÐS0&0/X°Àž9<lÁã$hé¥@IDATà af†k¯½Ö(ýÁÉbÇçðÃ7uyú駃Ë/¿Ü8úRkŒ  ˆÄç°j ;IdÛÄ|vÅW£u¤MÔ‰h²ÂuÁo£FOÇ–T7ý½·pX˜’n¨,±¸½úÅÐÒ¥KÍùœße½R{µ½ýØ.y(6!ö+yœø‹ùó`]'+PC((•ú  Ð쫞{î¹`Þ¼yFgÁ<ÂXȼÂÚt×]w5œ®™«I)Í5öäxÈ¥Ç|†; ãÁa £7Šøn TÇo”ê?þñMºNR”1ÐæßE‹™±ãÐC5ç@DÑ£‘æ# ¹qãÆ»ï¾{€âŸy£g§0§€‡-[Œâøà€‰ó)lŽ=öX#æzŒ ÌQp0ìYD¶MÈ%ç®F90ÞyçÆPуµg¡XcRR™ú»"àBÀ9s0ˆâR…‚ÙU ý­˜È ¡ÜŽž+PO ü¹00“j‰E_7õErâa4ÃÂÿíoÛ¿Á5ÜißkXUe@’h-VôNýIb“Áf£‰ÔIŒêÆ£[dR7.Êo lŠN>ùäö;Ì»ÜÔwï%6dP“ë‰"Óz+r€²ô!ÊýGh(øTE¤‹ ÁìÙ³ÒEQuq‘·ÜrK0}útãq­ó!ùúIÕÆ9ø;ì°ÆŽsѺ7ño=žŒ … ©$”z œí Òv1Ø÷"(:­A„(H¥þB?Šsæ£åË—wÝu—Q,ãøÈ¹\äÎ'Š÷¬³Î2º¼ôñXgȾÝ Êlœu<ð@s Å8Þí8Ɖ(;Ö»”)a°ò-µ?ºø& džgá0€n ,ˆ  èH¨+ÏÒFæY×»‚A"ˆ°é—QЃÓÞ{ïmÎõb~ÁðÂüá%NÔìè]‰† ëwÜaŒ:”ƒÑCΊ+Ì‚ûÒÚD½q†ÄØ€.Š6q?¢9ôùŒ3ÎHtt;ŒLèJŠ@§Eó¬Y³(˜éø¼ ï4‰Á Z©:xDùõÓßEÑ­C.XDñÃBîê‹yåæâ!Ýw©(}»ðø™;w®aêóûÔÎÊœ{ãã•Ïó®{âýobÛ§¤xÄùiÊ5{Ø3Ï,ãs DÔ#é H”‡åo«~ï-¢2¯²_aÌ#´’©J(£ï ˆ1àÕW_5¹“íz”1Œ<Ç7ß|s{¿•$ÉgŸ}Ö”G=‰Bé¡”gžyÆXƒröAÙœù¸ëÝu pë­· tÐA&ms!„’Œ÷GúÝa.o*C9Ä´]ÿé_ðJg}¼(ô°Gqξ¥ô;ìО÷Hm„û£>j”ßôiœt0zs½9ï Ψ¥0̹¢0Va,Gî:8¯ly艨O‘ˆttÒø²¦Eßd•ü©+·8ùPwÖ.¢(þ÷Øc%–ì9‰,&ª`ýÐóŸgmº#öîI‘¼¬“Á‘¨¢ø@6•7Š"BvÛm7£øgÎJ"Þqæ3Œ|Èè¼à=lØ0££J[—c`Öſt”­ðÇŸPöóµiõêÕíû—±ZÈÖ¾Aà[èµh]u¨JÏañ ÆV˜ÚÁ«}öð®SæQ¾ò–W¶Ѳ¢ý¿Ã¹N­prõ·Λ¢õNÃ4z_Y¬’Ú.ZÚcI8ɶÂp»ö­¡W]+Œ@0Ÿ .¸ ý{DëNÒ™,£÷ÇÛ‘ù°ç .ÄȳÚb·EÛŸ%“è½uÈ#þþÛïYõG Z páß1bD{l‘’Cý*Z&õŒ~¯£ïúò½žZᆨnÂZ¡—ÖZx»¾p¿}Ât0­0‚Áu[©ß¢<,/×ÿçw^)>úp9’äTD.ѲªìW¬y v+LiP®ñ‘§Cï?S^¸!o¿ôWÞ«0Eg+T ´ï´ZÇwÜZ÷±® 3fmz~¶XÃÛþε05i+Tî´ËþyY~Ýø?}ÇEaZ¨V˜oÚàF´Â¼Þ®Ûô·.G`ÿý÷o…Ê3ó •¡-æ[ÛÃHžV…"ÞÂ&óS§™y™¹™±IIPE@ȃ€3‹¢¦/ —=FÈ•Éu‡µ´é„eKn7õEÂúˆ<ÀâÝ4BþÖ›¿É˜âG.Â+Ëï’ýÍbÔÔÔ'Ô»“¹p«ò·n‘I•hÙ~öKjÆ:<ˆšüÓ¢n©ghp6^Q¬”^F?>œ¡Bj ÂûtÖ£Ï?Öˆ¤DÀk“ï–ð\¶l™ýj®áeI†Ç«yáÂ…æCz1Ò!ÏœC9äQÉR@ÑÈ›ÜßJ½‡Àý×™Üä´lýÐ#¸ß ¯rÇ…ðžÖ~ßï=BÛ¯(Š@>œ” ®üø„Õ‡^k†¡3|—¦:xH×¹[ÊC®—^z© Kr.éjGòpñ _‡ÅpøÌÿÍíªŸïo.¾Ïæ¹Ma§ò÷gÕùÛTiе:°"$ÎŽ%„úEà '&dJ OÌjo‘ëlæ-F„ fQZ;²žõ½îâÑIŒ|ë-u_™¸°’ª‡-ÇòàLJÍA£3!º9N*Ÿ¹•9-WE[Ï;Lx5aÆ„PWÁ#^·"<½¦ŽÇsL{ÌŽ—ýzp·ïCYƒPš¢xâ‰'L*Ë㹨njÓÞs‘Â!ôœfΜiÒfb à£ä†ÒÚ`xÁQ…²Qê=HÇ¥Í6Û,øàƒÌOì‹¢¼è}eþn2ùóç·S: >\ e­Ï*Š€"Ї8 (9 Ÿÿüç}1«Þñë.ñ{$¾“G"Mälñ^spRÕJ8;–`°°^ÿÔ …1›cHro Ìø£F¶˜´vØ{ÊþïâÑIŒÊ¶'ïóydâÂ*/¿¬û-Ç\ÌC5‹§^÷CeÛ9çœc”ñLú¹Ï}ÎïÁŒ»¬Ì¹->^e<šx™wø’K.1›wŒa:Ä11±œŠ´C/Ñaä%}t¬v±SHp€¹„A½Šh¼(3f´ç W}ô·Þ@ *óªú¹9„µ1KƒX Qwš¬3Ö]wݵX¬\¹2à\ ŠMhˆfܱÄûH®j"ˆXà|Îáü„* v–o/ýÏÙœïšè©¹¢—0ê•¶DÏ#À@8mÚ43ßÒ>æ³è»%Õæ&ó`M"RSIPE@ȃ€Ó€À"Ô¥`faÊä[%ÕÁ£Êú7¹l6,j ³œ:ŸEuÈÃŃ*¼D\}1«Þñë.ñ{$¾ÿáN=õTs(0a¢M"û^S'ðH2 Õ ö¤±„¾I¸~'¯4»ÑÇ›™”_i”ÖŽ´çò\sñè$Fyê.qo™¸°’¨C´ Ë£ z”þ6ÆxêÚw˜ÿ³Þa.Væ>÷úÞƒAצ°õL}Ë̺¯H;P¾<ôÐCæÃ¸œ56Ó.>UR”GÕ¼ªl‡–í@TæþOå»sèСI"Å„·ß~Û‹áãDÜxÀÅ—^z)óð·Ù3Ç`%â"NŒu|0 °¶Ã¸‡!!ËÀ/§¿c4À`éÒ¥FDXÙC¬û^o3’Û÷ê´ÓN«ÅXTÇú°(¢ ­‘ßz½hûE@PäpP4ë£`N« g6Ÿo½õ–ñ¤Aé ×M{V¯É#ÀæâÚk¯5æ3Ÿ N8áqyHÉoG¼2Yà³1ŠöE)iåÆ,X°ÀœpŸV~'®1 ùÔ¬0ò`hVš–×êy·Þz«9—çšûî»O0t¤ ±Ê~bøÄ‰sH_„!" B’²“”Q:B0LT‘.Ì0è¡pxY²d‰1 4Èœ³¶Î:ëôP µ)qˆì#½!Ÿ"ŠÿÇ{ÌìG˜£H™ÇÜ-Muó¸ñƃ^x¡}„t{´óc®äÜ$]W-OdÎAÀUʼH¿bŸ‚é‹,Z¤ á=€@*IŒœðáðÞV«e¢nˆƹÀŠí­·Þz­C‘¹×p² "–|\©Žlyú`°ÆHCú"¢„{Ë®W׿#€¡¨ ±ž ¿°¾ÀùªŠH¼:yàä…Ážº5 ”éú¬" (ý‡€Ó€ÀîÈ#, øC=Ô,‚ÙˆâEªÔ9Ǿûîk”³xjn¿ýöâ•‘’9‡œá©Ew¼/JñHk|QÔ{ÅŠæ,€¦¥1â½?~|Z³ ]«‘#G»í¶›Y`—U2qÈ Qä&Þ§qxûüñÆ;1KšØ¬J`ÕIŒ¤1É*™|ík_3žÊ®ƒ'³žO».%4z­>{0’½†Âeœê¹ÞaR÷p² ‹×5í»´ç}®Áƒ8Ý¢õÌâ³ñÆ%˜ä—¥ÞF™=Ú¤à©JæEúkbŒÕDÚH«YÇM@Z%"6Qb3N±FÄ(@$žñ–XSÁ?š›ÃÐ>úhpÓM7ïa{?ï§uº°¿éÿC¢èQ£ÌÊïÒ_z  m6j yh»í¶3éõH/†¡ƒ 4ÕÉ㢋. H™a,URE@Pò àÔÙô-eÓœ €cáÌG©óàùté¥—šŠ ˜=ꨣÄ+%%s¼ÚQ~ðÁæ€Þh_”â‘Öø¢Ò„‡ï{ìÑNCù¬3øÄ‰µ‘8dD_¾|¹Y¿sÆ”U†ò,ãÈÎ;ïl ¦ñ²ôûÚpÆ¢Aˆ>Z¯ÍE¿5 ›o¾9 êÂ@èr,H«3ý¤ê¾R'ÖÑvM]E¤u–zMPE ûpP4Ïœ93¸øâ‹×j! H¼Â!¹XòQJR<$ëÛMe‘–Ãa!<5ãòuµ¥y¸xÓ•:.]ºÔäDö©««þö7é¾ /Û\#„ÿ /4×ñ©½¬‘ |–!­Rõuñ@ÑÑ)Œ¤Úå[N™¸°ŠzqúòL»Ïò°ÊÞ´{õZ½ ”Ÿ>}ºÉ1gŸwا†VæÜ¯|žwÝï×(æ“ÆD×óE~+Ú¢±x|Þ¥E‹óçÏ7ÕCQqÈ!‡ˆîåa_.‚‡>Ó=De^U¿ºå–[‚k®¹ÆœÅ1a„`Ĉb‘R‰uÆ;î¸ÃH©CÚK DÊŒ”¤~E©%R{Í2ôÃ?4÷4(7nœñ¦Þ«D€´EpNÂèÂ8®Ô` ´i™Ën¸á†vDé1IwH¿¤&ó`íA "jSÓIJ^ËRE ÷pð–q)@Q@2)B\ç°Qi%l^eÀ;Œç#¹¸÷ÜsOã…œ4&å®H;h/J·áÇ{,ËÜbÛÁ¹Ò©!hS”o>J½@TæUõ+"H‰®fü ßWA”ÏûÎ'/q6{3ÖÆ(Á1*(e#@dÚ믿¼ÿþûf¼Õsù²1ë¥;ößÿµšƒ£—£pR«bŽj2ûï¿¿m@!‚I kuý¢(Š€"€Ó€ÀB}äÈ‘e±:eÊó; x:xH×¹[ÊCaa#~ýë_{yö×!wÞyÇœ·ÁBßÕóbîâ‘· Ÿû G_±bE;•‘Ï3uÝÃûzÜqÇe²«+" ìXÂß묳N»^„êÅUµ‰o3‹ýÑÀ#ûXZ;ì=eÿwñè$FeÛ“÷ù<2qa•—_Öý–Çk¯½Ìž=;ëv½^#֨ò-ïa‰IUµ2ç:GÇ«¤g²~çæŒ¥(Qp%‰Yeù^/Ҍ뭷žñÐ$" åj¡aÛ±í¶ÛVâåñàƒ<ð@Z•ôZ •yUý EÚ±Ç:‘47M#"ø(åC€sq ÁƒËFläïÛïæÀ`{Q‰_ùÊWÚg`ùSÅyxMæÁšzƒ 60bÕôEÝÞ»µþŠ€" ÔÀ?…,œäõ™Ï|&X¼x±—‚¹Î*ãEBøaœPr¬”ŽiOÎ:ë,sŠÙ‹.º(ý^%Ç;ù«QærèЦPR?¤~iÈÏK„ŽÍ¥ß”zs82†#ˆ(ƒ&aÚŒØd°Ù€ØdJ¥@iJûº±M• g´$¥¹`ì"g·Rý4µ¿Ä‘è–z’jÁ‚¦ú¤1Ê:D9ÞΪ¿Ÿþùí³¹â¼Î;ï¼Äkñ{õ»<I²Q¹Èc]e‰S§N e·ë]ÆÆ°yÚi§iäF· ²`½qH"]„ü¥ V§ã`÷9ìWuŸÓq‘hE@è*œ¢:kÖ¬Ò æV«eêa£Lˆ áó(X•:ƒaþÖcÇo|ãâò’9ù(©ã“O>¼ûî»kõE)iR(ÊãÏþ³ÉßQ«iÄ{m$–4 í&¥ ©ˆxÏËxµP$ˆñ¢Î4F‡f̘axã|Ê)§˜¿¥þùè£Ì˜X«Nb$……o9UÊDJ¾mÑûªE€µÞ¦sçÎ5Œ\ïp2÷áQ¶_ûð(‹6<–,YÒ^7à¹(m@ jùEs‡t>ê²8èó² kÖ£UʼH¿úÍo~ckÖy@*’¶¾ýöÛíƒK‹¢i÷QD“¢ç]‰¦,Zn¯?‡ó ‘¤‹#:M©¿ààq> ÒòX¯3G1­@¢ô{W'"¸Ø[±W«"}Sõ.m­" (ý‡€Ó€ÀbwÞ¼yk)m‹@ÃÁUöÌ3Ϙ !y÷9ÀW©ó hA9/-)™S?»àC–â‘&…¢ iÂ’1ñ7Þ>õ©O¤ª!½“Rï"€ÌúÓŸV*ó"ýêÖ[o5‘£äG?~|0bÄ!<ûì³Æ¨IÚ»2„3Xcòް§"KédËÔ³iÏbâÌÒÚ)õxØãI_µråJcHÇ™,œ¯Ä{(Iuó =0û@>e¾$1вE@Pº§A*½ ^²wÜqGpå•Wšî„ ÄÖÝs3j‰\IOÅ"ÅÀwÞ).)™ã§ ›xª)iR)ʃƒ³P`51ÒùÛEtÓ4,²®Çn¸ÁLF˜x©¶îºë.ÖœÛu›‹ÿøÿ0Þ‘UÈCw%°ê$FuÊ^È„q -éPk)yÔ‰òs#€Rãc¹ú]ý¥™ûòH«§»…ÿøÕ—Ç?žÈÿûìcŒ¬K“î/òûc=\uÕU&Í,ŽìÑÙ§¹êS¤|Êyä‘G‚K/½Ô´•¹ãã7¿ùM=D¹ÿ^ m±" (¥ø?®§?ùÉO'Nt]Êý^kLÐL¶–ž>Ñë©§žjÂx«”‡„Ì­²ûÐCuöE YàáÒù ƒ2ç d•_÷uäöÙg›ÔûmÛŪìd`Hê>u¦/¢-xãœp Fy7ÌÙb‘ö?†1 ¬:‰QZûª¸†LN>ùäàè£F-ÊBJ¢•Ò #À¼†‘”tGy¤³¿Ô!s¼ÃDkѧ‹ôk…üßáÁxN]1âU¡€‹¦½#¹_©·¨CæEx<ü¥ÒU%IR4¡:ujÀ9%Dí*¹à x>Jý‰ÀþûïoGgc-ÉÙUDµãpÝwß}f½ôû%—\bú¬E~øáÔû“ÊIû‡>¢6Þxcc˜À0˜vžúÛr0JÐö‚DEÝvÛmí³ú³gh«E@PŠ àŒ@ väÈ‘EÊ[ëe›o¾ypðÁ#+u”xa¼÷Þ{&÷lò’9›#Rfï‹R<Ò$Q”õ^±b…Qº° mñ^s(µ4Š0"[X˜âÕR†ð#Šª{OŽïc=Ö,²És*MViX«Nb$IVyÈdܸqù©¥:RòÈjƒ^¯6ÇI‰^#]…«¿Ô!s¼Ã_|±1”ÚȰ<(ùðÈSžë^x`Œ!ú‡qïÒÄ'5Êö·2ÿ³ñ'Š£„)™PháÍ,Mäø–Àª“Ic’U2yçwŒò’PsB±¥HJRõÑrÊ!€±‰5ýrõ—:dîÃ.QVIõ4Rþñá‘ò¸×%xìµ×^fæÆFiB¡qî¹çJ«å5:d^„i‹$SY0.Qîl`Êý«Õ2ï!ÎxNó±QœgÆG nXÙOM¥Ôß°v䌌I8Xƒ¸Ïï̃‡v˜1.þéO*\N_ê…CÂ'>ñ‰€óRxÇ“î/ò;y”o£ü(ŸTJŠ€" (Š@œͳfÍZëàÚ<…ê½ÍD ªCt«h-žZx“r7¦è!ÊUð“* ùû©{Óˆ÷ÚHŒº©˜‚!Ñ' |ÂŽë"a1c†a‡rOúe©vt#©6ø–Ó-2ñmÞW(Ôžxâ s`)\šüwK¿~ê©§ÚË£EÉ¡¤ô"D¹at$í*JE©svÜqG“:´,f8¼õÖ[æjTë>üðC£h¤îTQ^e}¾W ŸOœô÷8"ú]PE@HFÀi@@ÑÌAŸq#›óÅ‹›ÒÈUK8œ´—n<’áèý+l.ð8ðõ>¯C.üF~We|¼/æ•”‹‡tߥN䋯ËÌß¼í(s¿¯©¬]¶l™iéFðœcLV­ZeÒð7¿[£ß«&ËÃö߬ûõz} ”'ý)C>ï°Oí¬Ì¹7>^ù<ïº'Þ¯IÓeû”8ߢí`®dÝàã­ˆ V‡RB̃¤%*{.Ž),òO”‡å¹¬ö Q™WÕ¯È >gÎA:~üø`ĈBÏa<ˆGe 8Z€ k6Þm"v­Wu£*®•QE@PE@è œ©§ßýîwÁðð!ˆ<Æiïà:x˜ôá?È•š¥:t¨uÈÃÅCJ<Á\}Ñ«ò‘›\<¤û.ìðX»üò˹‰CþöPâ4LëÀ E™KÝ?¾Ùƒáïÿ{ÅÁßlŠë$e#ŸCÓÚ!UoNb$Õ.ßròÈÄ… IŠò,WË*JyŒŒu(»}Þa®Q™ÇÇ+Ÿç“î‰Ö³*QÞEy`Ä?à€¼Ò»Üpà æ`WøN™2ÅüÍÙ8’å!Y®–Õ\¢2¯ª_¥ùüóϪHe$….9Î$áœ- iU8$U R(k9Š€" (Š€" (qœ6{“&MŠß«ß»äzÖYg™È‚j2¡X!O%¹èñ"íbóÖ©üýY!ÿsÎ9ÇÜFþí¦Úƒ˜«0ò¤µE™ÅˆtM¥NbT7&Ý"“ºqQ~°Æ&ŒÌÆ xSC~áÞj«­Ì·çž{6¤V«QœÃe‡ JŠ€" (Š€" (Š@U8 , GŽ9€'© ð¾ƒðì“N A¹uð€O? ‹=öØÃ4|©i^èŸ:äáâas¼sè“«/Úúùþïâáûlžûþú׿¯¼òJ;•Qžg«¾—÷ú¸ãŽËdSVD—ر„4El†-m´ÑF&Šƒïläë$Œ>Ù:¥µÃÞSöNbT¶=yŸÏ#VyùeÝoy¼÷Þ{Á‹/¾˜u»^¯klb¬CÙÍAƒdeNYññªhù¼Ã_|±©#Æò§Ÿ~:qL,Ê#þ\‘vì°Ã‡)3/–•ƈèT;¶“¾giŠòøõ¯Ý>3Gš–×¢2¯²_qP*Ñ;ï¼ssï¨ QD×qX4†0a¯¤(Š€" (Š€" T…À?…·â…ãõ»dÉ’ f{€÷³)ÄCGzs˜ÆƒP]ÉqBi yp㨠üNÚ" ßCtÓä1C±_\<0pàAŠ2w̘1úb^N.EûnR?¤NlàöÚk/c`ã»&€+DÛ“ H’X%µÿ/ùKð‡?üÁ\F1…Rª¨<’xù\ÂkÖ¬1âÍœ•¥ŽvÔÁ£Vu=“G&u`ey<þøãÊ&1v-Z´ÈuI«<ýÅ·*VæÜ/5^ÅëI„XÕcb‘vÜ}÷Ýí3%Hc”uˆ2gíð>þñ›´gt”‡Þ“6ÐEçw^;’ëºþV-矾ÿ"r‰Ê¼Ê~Åú¤Äz‡ÒqJ”—Æ<ÎBz÷ÝwMªOR/blç eH’çÔ©SdÙ­DýésJŠ€" (Š€" (åpF tæÌ™®eA*O:^ý:xÄyöËw6`ö€XŒ.>×!<ÒñÊ|òÉ'Íɧ®irtñH»¿è5"'îºë.sðsÑ2ªzŽ÷zÚ´i¦ø4RX¡„KKlô Å Sg#ŒC(¤ M6Ù$óå´v˜Bþqñè$FMÊUD™¸°ÊÅÌãfË£é).<šÒs· ”_ºtipóÍ7›¶ù¼Ã> X™ûÜë{«_'‰¾efÝW¤O=õT{Ý€‚2Ë€€ò•O•åQ5¯*Û¡eû#•¹ÿSùîDÿæ›o…ü§?ýéRiŒpØy饗Lt%‘´DÿHN[o½u»HŒ¯¿þzðÚk¯Ci YË))Š€" (Š€" (R8 (šçÍ›ç¥`N«ÈG}p ë[o½eBlQZ&y=§•£×d`SAø³o£<Ü¥dŽ"èg?û™a7vHñHkWQàºÁ˜CÆÓÊïĵ"$Ÿz‚i$ðž¥ý¤»ÈòÜO+¯º³Ï>ÛÜBº /¼0ívÑkÂjlx‘ŸrÊ)¢åøá‡fL,‹U'1Ä£°*e"%fè-5 €R~úôémy×;\‡Ì}x”í×><ÊBæ ¼¨ÿùŸÿÙ|Ê–žƒ_Y'ƒ1ŠÛ¬4Iñ2ô{w!€Ì™Ãª”y‘~uÛm·sæÌ1ë—ñãÇ#FŒ( ì³Ï>k6ˆú!’vï½÷6k#éh*ÈÊË—/®»îºàÆŽLž<ÙDÿn€>¨(Š€" (Š€" ÄpP0K(úYÔbˆ¸å–[ÌÆððÃN:é¤Xôk] WœQ @?üáÅå!%sxl¡´ˆ÷E)i¸åW2隘‹ÖÊŸvÇ1MÃ"ëX±é&ò#á¨Q£‚£>:ë±ÄëxîQD˜~DÚ"¼l­bCš÷Ûo¿-‚U'1’Æ$«<²ÊȺŒ©äU'ï¼ä¼aySþÊ•+ÍüÁoum=ôÿú¨CæExÐÇq®`)›¢nã76k ÒqÞtÓMÁ·¾õ-Óljj õFñ¢i0ÅHÔÁÂ… ƒýèGÆÓ/}éKf®ä.Œ~JŠ€" (Š€" (Š€$Î&›Ä‘#G–æC¨.éLð*caÎßJC…aÔäH}õÕW+‘‡”ÌÙ ½ñƹcã}QŠGš$Šò Þ¯¼òJÛc3GÝ×x¯ ¥—&°ÂpÀ{Î;^vã½ÑFµÅ$¢¡N"úਣŽ2 „*”elê%°ê$FuÊ^Èä˜cŽ1)/,Ê^J¢•Ò #€± #)ï.}…1)NuÈ܇ïðÅ_lꈱÈjýõׯÄH!]g-¯Èœ~U¥Ì‹ô«í¶Û.8õÔSM-‰¹†t–'N4‘´î½÷^㜀cÌ¡‡j ¬qpî`Äûæ" x|ðA@„†³pr¸ýöÛƒ—_~Ù¼3Díœxâ‰&z‡5™’" (Š€" (Š€" €sµŠG±D~|ðv‘̸nobi°º½<6xAòŒçãÁ,Þ$)™³Bͦ)Þ¥x¤5¾(6wl@Q¶RÞ$²ï5u"ÂC*XaäÁãÏ=”xeˆ u§¢88{ÏER°¡—&ú´VÄH“¬ò ïžœkÖ¬q¦¥É*#麔<’Ê×ßëEÀé'«¿Ô!s96ÝtÓÄzš )ÿøðHyÜë<ðj&*ãéê¤ Om"^yÇ?ñ‰OV”zd>zôèJe^¤_‘¶¨lꢸä0bDàlÒ¹’"éž{î -Zd"-‰F í¾cH`¯Ä\ÇûFÚ>œRì:˜(O‰§ Ò’¦ãÛСCÎlØa‡*1òÅÛ¤ßE@PE@Pú§EóÌ™3K¢ÌBr>JGÅ(¹ê!”¼Vy!Y3)™³bãõä“Oï¾ûîZ}QŠGZ»‹òøóŸÿlò÷—U¢§Õ­è5ÞëiÓ¦™ÇQ@_tÑEE‹Zë9°Úb‹-Ìg­ ¿€!Ñ'Ɖ: Â:cÆ Ã› =rI¢=Xu#I<|ÊŠËDò`k)yø´C社M(Øn¾ùfÃŒw8Þ_ê¹²ýÚ‡GYÄáñÞ{ï÷ß¿)JÂ+;^'Œx~+õuȼœUH•ÇÙ[(ü)C‚p(!úó‹_ü¢9èøá‡6)‡~ñ‹_| Ö¼8-~ ã"N4ýÎ;ï˜wC‚%®í‰#)‘<ðÀJ"Š-?ý_PE@PE@§E3‡ÇŒx0[Å̤â@y(Iuð¬o·•…W_ïó:äáâ"èg?û™e|¼/æÅÝÅCºïR'Ê$lü¶M#ÞëÙ³g›j¥aZVÈ÷w¿û© ^tl°S U«VgŸ}¶ùû _øBpá…š¿ëø‡<Â#"*âÊÇxÒÚ¿·èwNbT´EŸË#V¶_åÎò°ý7~]¿w”òÓ§O7)S Ÿwا¶VæÜ¯|žwÝï×xáÛ>%Å#ηh;ˆ,#:€µC­€±"Ç;^ÕÒ)U¢<,¯¬zéõîF *óªúÕm·ÝfœlXàÑr^ŠXÍC„ „»ï¾;xá…Ì;O4çЗ“ú3ó†R?iµÇ{˜ú‘ªŠÔbRíÖrN#@äã„Þ‚ýFBæÛÕ«WÌ‹ýü{§å£üE@Pº §öŸ…ªKÁÌÂvêÔ©¦…ë®»®É5,å¡ca«ƒ‡åÕoÿ#Wº Ñ&äهꇋ"6‰,ò\}ѧîÑ{\<¤û.ü(ó²Ë.3žóQþMøùî¥aZV,Ú/¹äS— 7Ü0˜5²2çÞøxåó|Ò=ŒÉ¶žUñˆò.Ê…Ëà•Þ…Ô,óçÏ7l9ÌõC ÖYgh5JÿårH©÷ˆÊ¼ª~ÅÚ‡ô@t*#+!Ƥ#Ž8¤}饗‚x X¼x±Qf’ªCÿsîFŒ‰|0Äm¶ÙfæÐõí·ßÞDf2~()Š@:œ bÒÆŽœwÞyÁúáy;@ŽNǃ~þ==½ª(Š€" ¬€Ó€ÀBo¸8áÁ|à 7˜Ÿñ°>ùä“ÅB|-¯:xX^ýö?r=묳ÌÁmä\õ¡:äáâÁƥŎ;îh¼H}êšv‹GR>Tq¶DZÛ|¯!…ðdK¢:°BùjÇ6ÃxûYE/þ¿ÿ÷ÿLõêL_CúœÅ/¿,JkGÖ³¾×]<:‰‘o½¥îË#V¶_IÕ'ÊCªL-GklBæD 6L¤à¨ÌããUQ¼Ã¤ á@Õ=÷ÜÓ(“ÆÄ¢<âÏió$)††n¦Ž—ÿŽBß¶9ì·ß~â„(8ýÞ›De^U¿9ÖF¤x¬b}• Î1¼ÿ|ˆú$UØ[o½eÎ(ãÎ? .Ôƒú²ˆïmEQÿV² º€w¡Òß`¼yýõ×Mäc‘’" (Š€"à‹€Ó€À"•ƒ>ã„R—‰‹F:,rëàŸ~$„=Cñƒ‰“ð¨C.lž~õ«_™ó3\}1©¾I¿»x$Ý[æwòÔ¾òÊ+íTFeÊ’~–÷š<¼YTVxÔÙ±„…}t,!ÄŸ(ˆkuFŒlÒÚaï)û¿‹G'1*Ûž¼Ï瑉 «¼ü²î·<ðåàW¥æ `MŒuäë'½‡Y™SV|¼*Z>ï0©ù8‹ˆó~üñÄ1±(øsEÚÁå%Ï–e{;¶“ö¨ …g”o>J½@TæUö+ ûï¿¿w”®ꬹpðàc'$ÊÕ2E ƆQDßc„dM`æÌSœsF4B?ýŽ!å™gž1ç½ ®çTê[¢(Š€"§o—‚™”2S¦L1å³€gA/Muð®s·”Ç¢Áæ“G bÿN«òpñ@Qç¹)]}1­Î®k.®ûÊþ†Bñ´ÓN36›K¿l™RÏÛ÷šòذ&¥1ª+"˜ìXÂßÑôÍNEqÐßÖ¬Yc Ç›9+JZ;¤äæâÁØÛ)Œ¤Úå[N™¸°òåã{ŸåñÚk¯µÏËð}V頻MGuTûæ]Îz‡}jdeνü¯|žwÝÃ;l7îÔ³ q¾ExP·EaZ">¤1â“FìØ¾í¶ÛŒ£Òåñàƒš40Ò<´¼f!•y•ý ƒÞÎ;ïœi(k:ZE@HB`Ÿ}ö øÄ©_2dˆIéôꫯšLvÇG¿+Š€" (.þ)ü±¿ÀÆ–œä> æø³U~'O!žqÂëܾJéDñk:f¤Zà;ŒÃ3¤I}1ŠcâMÄ—¼ùöpb_RRûªüýÏþsû°v¢fêLc´bÅŠàŠ+®0ÍÛd“MÌâºÊ¶-»“­sÑçš*rê²s^¬(\•êEcÓÒ¥Kƒ¹sçÆM~‡›Ú¯ã;ÿüóMžh~'w49£›DÑúÅëÕÄúÆëØËß“dÓT¹à¬òæ›oåOúÓ•§1êÙóÎ#Ën%êOŸSêOØO²6€ˆ:¨Â¨ÝMÈÕ¿dÉSåyóæg•E@P_þ¯ëFÂÁo¹å–ÒJ[ã00&nÂØ G!¨Ô9ÃÇ?þq“†%¤´<¤dNŸ±‡^¡Œ¤x¤I¡(½Û`ƒ Œ7iZù¸Æ{}Í5×ÖqLËÔ¬èK¤t!ï¹ .RîªU«Úç|á _¦M›V¤˜BÏp«Å%0ç¼HÒG}dÆÄ²Xu#I<|ʪR&Ròði‡ÞS=wIfaw½ÃuÈ܇GÙ~íã,âð -ßÇ>ö±€È´*¢N)Ÿu"ÿÇÜ?¥ÞEY³©RæEúÕm·ÝÌ™3'Àx0nÜ8ãÄÒ»RЖ)ýgò¼üò˦±_ÿú×ÅRv+zÇ{lpàšê³_URE@Pò à4 ¤¥7ÉS8yìñ$×Â-¶Ø"Øe—]ò¡÷ "€\ɵŒ÷9 ä'Ÿ|R\R2ÇÐÂeB<ÕŽ4h‹ò í ,iÃLZ]}¯!ÿÏ~ö³æö8¦¾e¸î«ŸÿüçÁ‹/¾hR{|ñ‹_ ¶Ùf×­^¿)qçwš{ë>ô Ï$Ò  Ü¨B†ï¿ÿ~°xñâÒXu#/! Þ„LH½B?“HG­š”<¢eêßC¥<ÆÆ:rõ»úK2÷å‘VÏ,}yd•“vxoâtÀa¯DtHߌ‰o¼ñ†9koH·Pê]ùOúÓJe^¤_±ÞxþùçÍG÷*½Ûÿ´eý…ÀÂ… ÛicÃó¤ÎFêVíYˆÝZ­·" (Š@gp8Èkâĉ¥k†WòwÜ\y啯sm„ â ëÒ•ì£+¹‰ï¹çžàþûï6ÜpCqyHÉÜ;vÜqÇ/Ò(Iñˆ–ÿ»(”ÎMÍMüm #IOR°" /ƒéce `h¬3}}ÃÚ¤I“‚G}Ô¼ñ~Qö;gdH`ÕIŒÊb÷ydrÒI'™Ô䦖$)yHÖIË*ŽÆ&Œ¤vÝu×`ذa «Cæ>Q‰<¤dÎæ0ÎBˆ÷E)i’(ÊÍÓN;ͤΘ={v‹Ú¯Ù÷Æ(iʾ߶`EÚ¢wß}7 ÊÁFØëyÿÇhЩ(úÛÛo¿mÒgUa@Àˆ'U'1Ê+Öß@IDATϲ÷#ÒQüéO Ö¬YãLKS”‡”<Šò×çd°Æ&ú äê/uÈ܇F»qwÕ3 Yed]‡ÊÔ^xÁ`ÉØ(MŒe;í´“1R ÜŸRo#€Ì9ßÃTU2/Ò¯ˆvG¼ö¶$´uŠ@ï#`½ßR¿>øàƒí”N8•ÙuˆßÓz—" (Š@¿#ðO!­8ll'Ož¼ÖÁµñ{:ñÙlÄ ¯ÃÕ«WÇÖï1¢ø53ò.1"Xo½õŒiôåX³jÿÅ1‰yñ%o¾MaÄæºI˜Fq$%Ñ' ¬:Ó­X±ÂÙàM¾oéC”)W‚:‰‘Dýó”ÑT™pÈû!CœMA µhÑ"ç5ý±:06qîÒܹs “&¿ÃMí×qéœþùÁÔ©SÍϤ²ÇïëÔ÷hýâuhb}ãuìåïI²iª\pVÁXÃ)k£¿÷NÞydÙ­DýésJý‰ûIÖê~Oc4räÈ`É’%Rªrî’" (Š€"à‹ÀÿuÝÈ¢·ÜrKcŒ®:ëo~’Ïj)ïs?®ùïb±‡‚BßTew¼e6u‡¾6x¯¯¹æS­&cºjÕªàœsÎ1õÄKqÚ´iµAÉ!¬#”ÀM5 t£Ú„ñ¿ŒºE&uã¢ü"€q—ôg¤ 5ùî¦~Â…¨Å*¢²JQQ:ƒÀm·ÝÌ™3ÇÆgœX:Såª(Rp>)0¡¯ýëÎÔ†R¼º¡œcŽ9&8à€LU7Ø`ƒn¨²ÖQPE A8 IéMPê.^¼ØTŸ¼¥[o½µ¸%¿ ¿֪ ×7ÞØœéžh=«âå]”g4xàfí-Ïõ7FŠ!¨Ñ²çâÄùDyX^ñ{ô{o!•yUýŠõÆóÏ?o>»ì²Ko¨­Qú… ¶ÒƆç!¸ÎFê'höÜsÏ~j®¶UPE@§<æ'NÀŠ0@›²<Æéô"uðа>ù¹žyæ™ÁàÁƒƒAƒyµºy¸x XÁKžCSwÝuW¯º¦Ýäâ!Ýwáá SùûÓÚÏ5äoS‘¦,‰êÀ å«KŸ?~;÷5ÚsªQR»ù>g1"Ÿz¥µ#ëYßë.ÄÈ·ÞR÷呉 +éœêQRmÔrd°Æ&ŒÌÆ )8*óøxU”ïðV[meæ86ôUðˆ×­Œâ´yøðá^ËâíiÓM™2ÅüÍÜ#IQ’åjYÍE *óªú­gmDŸ¯#}Ñ|ðaÜbÌž=» …Ë´ï5á¿mÁu`E;–¾ècû˜eo6ŇrHû{ÐïÖ¬YcXâ©”•%­RõvñàýíFRíò-'L\Xùòñ½ÏòÀôÅ_ô}L頻M¤(°ï0ÿg½Ã>Õ²2çÞøxåó¼ëÊ´wêY8ß"<¨Û#äM¶¹“ãeÛïD§Ú±e s4Eyüú׿Þxã iZ^ÈʼÊ~µ÷Þ{_þò—Ÿļá`B½û[o½5xæ™gŒàÜsÏ5‘ÁIQ¸—5%}T¤‡z¨‰ Ú|óÍ+Ù‹åm›Þ¯4}÷Ý·©UëH½xà¶ÃÂqÇ×^‡t¤2ÊTPE ëpP4Ïš5«­l¶­b#NªˆMa!¾uð°íé·ÿ‹¢[‡<\<Þzë­€¼ËO>ù¤ Û¶†¢2sñ(ZVÚsúÓŸÌ;bÃeÓî­û𝩬PÂÙ±ƒEÔ«•P}«"j¦Î4FäY¾âŠ+Œh6Ùd“ÌC”ÓÚ!%_Nb$Õ.ßròÈÄ…•/ßû,Ç<8ì°Ã|Óûj@cÓÒ¥Kƒ¹sçn>ï°Oµ¬Ì¹7>^ù<ïº'Þ¯'Mš”8&ºž/ò[‘v<õÔSíƒåI‘e@1bDûžüãiŠò˜1cFpùå—K³Ðò†@TæUõ+Òžá°ÂC8HîqpàX±bEðÝï~7øÁ~`x1ç}­^½:x÷ÝwMšIì¬Ý‰VÀø@9ü}å•WšhדN:É4 ‰ 9ýMÒ²²6€˜Ãú=ÎcD@B:nôE@P8 ,Vo¹å–ŒÒù¤ãu­ƒGœg?}g³‚²6Éû<ŽEòpñ`±gS: Œ/k@pñˆ·Uâ;áä„–ã-×4ò5 ÕJ¸¤±äÕW_ «…ð®›6mZmP’Nàšk®1üvÛm·LBZ;¤*íâÑIŒ¤Úå[N™¸°òåã{Ÿå!©\òå­÷¥#ðú믛Cì9Hòy‡ÓKüûU+sŸ{}ïqõë¤1ѷ̬ûж… y×£†Þ$^¤âS%EyTÍ«ÊvhÙþDeîÿT¾;I4gγ67nœIe”¯„ä»y߯¾úê€ô!8X"º€t|’Î Á¡ƒ#ÆKDçÞyçQ ßøÆ7ŒÁ^ÓÿEàÜxãÆèÆ/gœqF£Sþ£ÖÕýuÌ1Ç´üMKµ[]«µdEà0ï~ôÑGæ,!ôbÝL¶yÛÐKäm{•÷Ûuº´^!úý…(Yû¾8 4ÚWÁœ ±üãMSÒnH”›ÆS¯%#€\Y,p@-y^%RŹIÉœJº¼#â}FŠG¼îÑïEy¬»îº&?yj›FÈÿ³Ÿý¬©VÓ2u+<ãþð‡?˜p|Ò7ÅP”Þ~ûí¶'.)¡ê$e`ÿ ÅÔ‡~hÆÄ²Xu£:å/d‚AŽI¹L¿rÕ[J®²õ·ú`NÃxÀX‡²ÛÕ_ê¹/´zf¡çË#«œ´ëðÀðÌÚm—]v  ”v{¡kï¿ÿ¾áCÄÙ§?ýi/CE!fúP#@æ«V­2}«*™éWDi>ÿüóæ³óÎ;‹a…C iC.\Ø6Xgú;g`H"öO¤-⬌¤¤c>äÒ‹QnZI´ORôwE [À0hÒ8ásŸû\·T½’zÚ³+)\ UºæQÖ èjˆÌ­b¿_% ùË_ŒÓÑ’D/²ž`~ÏWÿDûqFDoµå–[j*D±&{ì±Ç²‘°^cïdîÅw¬ˆ^xÁèŒÑŰÖÄYÚi@`ã=qâÄÒÀyóæ™h6 ‡~x@¸­Rg@®S¦L HIÀ¦ƒ‹´<¤dŽb…F_úÒ—‚!C†¬˜µ })ʃ»©¹é‘ÿYgeZŠqFŠÀ ¯=w –z}ôÑG.ž±‚Iª3}üès'œp‚IeC|ù]ŠPüK`ÕIŒ¤°ð-™œ|òÉØí°Ã¾yÝ'%/fzSå`lÂHÊX‡Â{Ÿ}öÀ³™ûðàÆÏ·×^{ ¨gÖ><²ÊȺoeŒG š”£=«œ´ë”g6é Qìpˆýî»ïžöˆ^ërù%—\R©Ì‹ô+Öoœ}€ãŠd„Ùê0EÑ}÷ݬ\¹ÒHŽ3Ÿ˜×8o”`[o½µY'‰•÷bêÔ©ÁØð|—Ûo¿ÝœŸÀ†Ž(œ,}ôÑ`=öŸ“ꣿ+Ý„‘}6­,k„~'-; ¦4Q¿÷ˆþk?úŠK/½ÔÌÜ-„¡[çRèRo £8jCì#¾õ­o/ÞâœÑgS·‘Î5n$!Ó )@Qt£«u9\u &M©'ŽPcÆŒ1Æ ˜5‘ßÝN¤‰åܮѣG'iŒNNÊE”€e‰NŽgò²eËLÇÝqÇ˩ϗ@€Í›ŒgŸ}6xî¹ç‚*ä!%s¬x„m“Â&Þ¥x¤AY”õ~å•WŒu®i¡¡¼×_ýêWÓš]èXaÍç=g¡þæ›o*Ç>„â~úôéæ+õ:‰Åô‘Güñ¬Ä ¯ ¬:‰Qò€2Áklùòå¤W(eKɃ²”:J9Œ¤Œuƒ6 éx­ê¹Þá‹.ºÈ(Í­r#^×´ï><Òž÷¹Ä0&M*M”b•ùbìUêmêyl¤O9å£Ìßf›mÄ„@Tkn6õÑ'žx¢I‘„±Ó‡ðø²ÏaP¸øâ‹ƒ'žx”i£&¤ ì>õÒ{¦#Àúqذa¦šë¯¿~Ó«[yýH£Æz"]ìç?ÿùÊy*E I9Á’—í÷¦ÿÁ€ùÿ¡‡ Èø€éqF²Î¡¬ÝYc`,„®¿þz³'Â9×’Å ÛÚoëßÄÿ£XFÿnb]óÔɶÅöžuPJ¤·aÓIçf±Ë¡gü­Ô9ؘcm$A¤ yHÉœrðÃzï‹R<Ò$Q”Þ`§Ÿ~ºÁëp“Ⱦ×Ô ù£˜• °ÂpÀ{NŸ*빇ѠSQô7 `E»¤ %€VÄH“¬òìÀ»EêI/ )ydµA¯×ƒcÑOôÈÕ_ê¹úvãîªgb><²ÊȺHe„Aßâšõ\žëDb5Âür'î%•§,½·;@æÌaUʼH¿âÌ>Ò„ñÄûtà_þò— 9)àÍF "8L™´K̤Ed“× áòÒøkyýÀ¾ûîÛßÄZO:5›Òé¸ãŽk¯Cb·éWE@h ¤ÈÁQ•¹þØc5ï¬ÑëØùÆŠ+ŒÃ"MÀ¡åoÔ€ÐÀ¦i•º§Eó¬Y³J\ËþÐC5Ö16¢u§#é"9ÔRÕ÷Þ{ÏX!a†¢åàƒç+%sâMZò»EQ–â‘Öø¢<²ÊȺ¼žï¹çž€õƒU‚f=—ç:åOš4É(@9¨y£6Êó¸ÞÛ… sB¡QzW%ó"ý gHéAŠOúYbÓNžbÖÆ2R—‘î±(áEÊ¢˜ž~úis®åãu¨)ZŠ¢ªÏõ*xì²6€pàé÷w„4m6B^Óõj¯×võ*dvA@>zœXëÄ CÙè^!¬q!~¯~WŠ ð÷ž{’"¹±Ê*é¸xØY/»ýÚ@™FÉËAÒ$%s{ÖC‚ºFû¢´¶åÁs,ÌØ›F¼×䚆☖©+mÞb‹-̧L9öYõ!¬"…Õ´iÓì¥ÊÿGð½ï}Ïð©ÂƒˆVĨr!Ä “k¯½¶-“¸B8v{®¯RòÈÅTo® ”ò¤?#¿)Ä;ï/uÈ܇ýÚŽÇ®zfäÃ#«Œ¬ëð@‰ŠÂE¯oº•¬r£×)ŸÔ1Jýƒ@2/Âã¶Ûn3g¡d7nœI1TV*6 ˜U`¢ü—ˆ²¡”‘ͧߕ£eå¥Ï÷7Þx£‰Ö¡egœq†‰|ê½Vú·¯e5$ø?­w*Õ#ÀÌgÌq¹Tùý̉& ‚¤µN¸§žzªÁl 4úàê_åp’Ò›Ða­g0÷°ÈFy(Iuð¬o7•…ÌDÈ#ÎY>T‡<\<˜,HñÀÄ!‘jÇÅCºï‚'‹ À²;Œëºùãý¥aZVl¦íÁ?xú“–†úAx¹ÅY¯=󥆨|[Œ|R夵Cªº.ÄHª]¾å䑉 +Û¯|ùeÝgyØþ›u¿^¯”ò9ÊnŸwاvVæÜ¯|žOº'ZϪxDyå'‡½r0uéFZˆ9œÜ¬Òéà¢<,¯¬zéõîF *óªú}Éž' uÞyÖƒŒ˜»%"yXEû>ëÙ*Ö´ÝÝk´öŠ@Ü{ï½m‡4ÎC uZ?)Д&"€á€Ô;/½ôR°jÕª`È!Á¿øE=èÛ!,ÖI†ÖUdqTCêSœÚ6Þ'N ‹Õ©S§šßQ”â%Œ—$ÕÁC²¾ÝTr=óÌ3MJ©-·ÜÒ«êuÈÃÅÅ J …a)K.Ò}—:²QìTþþ,Œ?ŒBlÀ“¨¬V¯^\rÉ%¦ XÑ'OžÜönÅë•Ô#Pé‹àgaåï4# ס´vüýŽòÿºxt£ò-ÊWB™¸°¢ßK’å¡ITeʲÆ&d޲{Ÿ}ö)ØÊœÂâãUQ¼Ã¤2aŽÛk¯½‚*xÄëV„óäöÛoo¼±}–]´hQÛL»˜¥ êQöðåx[õ{o!•yUý Äðè£ÏK­YËbÈäÌ œÌœ]€A¤èÜD4)eÊBY@„ô{f ×.GgG›ZU#t‚à·¿ým€¢"‘¦1êò^ ú¤†f¯a›tzÌ!¤Ú#…m¬s]ó Ïpsqús&ççã,Âs̃”E*x£“€ßsÏ=g2NpV§u$Ýl³ÍÚ}”g˜;©7s*Jt‘‘:R?Û>×}Y¿ýõ¯ Þzë-“n‘ºâ`I©«=ó‘ú»i'Ï‘‘gh;ï’©‚2X#dQ´‰úð,ÿ“2ûW¿ú•Á‚çY³°°2ÀɬóàoÏâåºN½é”_êŒÜq¢ eʆŸ­+û"Ê3ÚËÇ'°£m´Ãg çÜ6êK¹Œu¤’¤ŽÔ™õ:lWíØH_¦¹î¡¾Ô‰ò‘c(õ.B8“PGÞGÊ‚/ïÐfB&Ô…>B»yoè÷”Cã]É"ða}jåk×”¼;IëTg¯‡é¨Q£ð£r7ÜpƒùJ‘@j‘m™ÕÁÃòê·ÿéŒÖó€Žâ£ ­C.Ö ž6®¾˜Wv.Ò}—:1§—¯i¡¡¼×_ýêW3¡«+&U;– œ?~|{bár饗šz2€×I¼>Ù:¥µÃÞSöNbT¶=yŸÏ#VI“_ÞzØû£<ìoú3°Æ&ƺÁƒ‹¥é‹Ê<>^m9ï0©ùH%ˆrƒ”}IcbQñ犴ƒôB,"Y„²¸ÌzŸPèÛvpï~ûí罎×7é{”GÒ=ú{o!•yUý Ä0ê >Üõ¤DÉÆ—u7ñE¡‘ ¯JÞ Æª<Äæý¡‡ ~ò“Ÿ´#4)g‹$EFžòõ^E × ê`ذa¦Y뇇ö;‘¦uùòåA5Ítÿõˆ'žxÂ8z0oŒ3Ƥº¹ãŽ;̼‚2tÆŒ&…°E )B‰æyä‘G‚_|ѬQÆу£'ú%"øÓâ(L1À‹ó{Ö¬Yc”¯›l²‰qà»ÿþû2•õ;:”xôsçÂ… Í|wôÑG'¦‹~ðÁÊb}͹ƒÌ‘y ¥.ëÎ{üñDzžùå,ãÈN;íd"sY3¸È(™çÌ™c°ÂIœ–,Yüà?0ÿŸvÚiÁá‡nãYu«ýèG/ꄞ]Ó•W^Ù^CÐΡC‡%9å=üðÃÁÝwßmÎ;ᄼø¸ê‚{éÒ¥Áí·ßn"41Z€Mhû—¿ües&“¢ÚU~´®¤x>ì°Ã‚Ÿÿü禟ÑO1˜Ð¯0$tÐAÆ9,m‚‘‰çh;õfÝ…,uÞu×]M9èãk¦þð‡¦ÒoÒ0{ÎfÄHõÍo~ÓÜ’Œ ®6£è'5˜.^¼Ø8„ Sö‚ðÆI†L1èÀ’¢LPú­Ãz>ŠƒÚÄ{ɸÎZ–~ŠÁ$©Œ5¿øÅ/L¿¤ŸñžƒÕ AƒÌ³D²À+NN…KÁÌ `_B*—¬8ã¤ïuðHâÝ뿳ùÏ{ˆnòpñÀr‹‚Ÿ—ÞÕóÊÊÅ#o>÷3Ð’cëá5×\ãóHm÷Ø÷†à‘d@ª+&;– œŠŽ% ˜¾Þ ¢¿± °r3Î¥QZ;ÒžËsÍÅ£“婻ĽydâÂJ¢Ñ2,ALÖJÍA€1M…}‡ù?ëö©½•9÷ÆÇ+Ÿç]÷ 8dA QÏ*xÄùáÁ†ïÑG5Ÿý÷ßßl˜âåF¿ãácÇv<†’­ÑgòþåÁ¢›Ro#•y•ý ÅQ36•¡ª(i0n²ñgm‹á[ßú–ñŒÛ}÷ÝÍzÑ¥€ˆòf“‡Câ9ˆ2,QÌF^IP"°ï¾ûü±yàÚ)Ž;î¸FP¨±žfœC9È'º/¬Z\(áÏþ—5#k¥º¨¼_xác@`î@iûýïß(\i?éûâŠU NÌY(þ­G;óÞÝ(êQÖsÌ1ý %müy°DuóÍ7ßþö·Íš %<ó–uEáÍZî+_ùŠ9û£Bœ˜CQºRo×IçMÚûh ç}Ø5i¼¼¤ï ,X`êb,zöÔ—ß0*`LÁáG›x›Ù»þô§?5ÊpÆ Ò2q/ xÊ£ùöqæ~d†‡<ý”:€'eZü½÷ÞÛünÛ„R£Ã¶Ûnkœ4Y7å%ú&gâ^vÙe†/ë"0`C$cÉc=œ}öÙÆˆTô½±uE©ŽÁà ؠëàC»1 `<ºà‚ Œ‘Áå|AÿÁ@sþùç›û<÷²g§ÓϨ3újTD›B›ñãϹö0¤Ê…dˆ–áƒ1F4Î÷?úúN¢9é­·ÞjÞ³¯ýëÁèÑ£M„ƒ«ñÐ7b,c}ÌÞýrhï%}Žr\ xÏ;ï<ýC]¬±Œxþµ×^3}6nDp`F2—ЗÑ÷‘!%ï:‘wæÜsÏ5F\"ÑÉzÁúÃ%†©ë¯¿>¸óÎ;RŸñïk_ûÚZu¤­ès1’Ч³x'i/kcö§¤ãå}ºüòËq âã)Æ,k<À G9;yïˆF¸ï¾û"Öàç¢Vøã€OØ!CS³(v@=©{ëÚ,äþ^ð ;O+´rµÂ¼ËM¬b»NQY7M¾ÑºÅßÐò× _ÒÖ!CÚmiÊÑz7 Ó(Fá!†­p²6Ÿ0¼6z©ò¿ÃðÈöN\•ó+Ê “­sÑçš*“h½âã@“ûNQ9tÃsáb¿.r»âŽöŸ&÷—póÐ .­Ð3¥.H× ¨_üý³ßÃ…qãêÛOJ’MSå¦h…Þ˜­0|¼z—‰Š*ôÖk{ì±­Pa0 ¿†ÀV¸ñn…)Za:‰V˜î †Ï·Â”­Ð¸Ð #•Z¡cÇ€çÂm+Tø´B:ÑºÆ C^öêÆÿé‡Jý‹@¨0j…ÞÑæzìö/ÿÛòPyÖ ¾æ*Ú:Ž2Ùa‡Z¡âÑŒ3¡R°FYµB¥Uåu Ó·Xߨ±ý;{¬ª©“¼™ëBM+t i… ÇkÐPYØ èk5;ô:nÍ›7¯*:[¡Ò¶F í£Z¡³_+4´Båz+ôö^«îanƒûûÐ ¾Öu¾€y¨¬7ý 4j´B#€{˜‹óbè=àºý!<ï±zd·Âô+-öq²íGöì³ÏÆ/·ÂóB[¡B×´'ôâo…Êâµî—Ðë¾z¸·Â³ÁZ¡‚{­ë|¡þ¡òÚô+pož FîÍóC¨86u ­Ð£>ñÑPImÖ ¡A¨åzϳ®‡Æ¼VÁÑ £ ZašéVhˆÀ+ŒŠh…¿Vhè1m •ôîñùÁÖ…w0Œ.i…i}Z¡‘b­G‘Ó¾ðÓ?X…‘Ûk]ç k,ÖJ¡3H+4(¹ÑúahÄЦÐ8`ôwèòà*ûð£[Ì».¡‚¾Å3–ÂèÛv„Fžµ®qü㇥O„Æ·ï\hdj×q£6jqhL³,Ìÿ¡¡¥FO´+CC+Ì~²Öu¾POÞIêNÔ…w’þ^¼SaêÙýüµ×^k…Ñ3¦Pó(m„œXü\ÖÃðá\–o¬eXk°zÚâkmËÅHoöB¹†ÑXö°~âi%-)™Ó_ð„Çòï‹R<Ò@+ʃЬ›X›FÈ߆åÇ1-SW°¢/†å™÷ÖY¬Ä¡zužID<àùתìSÏpò0cbY¬:‰‘O;%ï±2¡ŸI¤£‰ÖMJÑ2õïÎ!€÷ž9Œu„ ºúK2÷å‘VÏ,}yd•“vá"ÓÌÁäÆKš(¯*þ掸W‘4O-¯³ kBÍ«”y‘~…×#ž[|ðZ“$" ‰_µj•ñ¢c_d /PÒðñ%ÖY䇞8q¢ñfô}NïSú òCã™ ‘ï½ß£uˆxj‘†µë ïf<‘ñ†zWQgö®ô Ò¦X"êf<ºËxSÛò’þï$o['Ú‰^ˆT(xAÇ£sð²&U ‘¤' +dº Ol¼²ñXÆ+šCQ|æû•+W¯mò»Í'¼×y7™™'y†u|ÝÄ^“úóžÞ‰µ@\W†Ž*4˜è ¢ ‘e¡Ëà¬G¼Í‰¬é ž5 Q[D‡JæÕ& +Ñ$¤ºé¦›L«"©’lÁÈ;4™(¤xJ(dADÁ/ùKãYO$B4¥,r#•©Äé§D2ÅË@nè?‰¦!Ò…ub”XW…@D ©ŽÐµ  â9KDŸ°fcMžñ%<ù¯# ˆD™0a‚9ë ®/C÷I?á="¥ïTèôk" ,ž!*†ÈÔO<Ñy¾}˜=0c+me\ÖœÀ÷Œ³ˆ0‰÷óõèäA=à%§üñÑû ýMe Al>‚Sê È•”,LÒ¼ L’Òò’9¡C¡W‚¢ˆIñˆ–ÿ»( ¼ÔM$äZÕMÕ ¤¬8ð†|l´ŸM-kQb#Ô ª3}üès Æ,^°¥‰I‡sÊbÕIŒ¤1É*™°P`âe‘$)yHÖIË*Ž›Œ¤Œuä>%T8NuÈ܇ï0‹Oæ86TyɇGÞ2ã÷ÃôàÊ{èÚôÅŸÉû ,c"T6()ØÐ*õ.ÈœÐø*e^¤_±~AéÁæ¬ ‚ÐËÓ(xŸÓ'¤žMobCŒ£ s!›LÆ8ÖËJŠ€"àF˜]ÏǤî'zûWží!;Þu²Å(¹¢J4”ö¬áêp$€üQ¬YL_{·•7sFµ¤´€ÌѤôéŽÔF`ƒ\œWènÖr¤›an‹Ð;Á Ýï`’a†t,܇‚5®Üó¬ê;u<âˆ#ÌY ÌÏÔC ÚN?áÚH»ø=H±¦çn1Ðô·´•3¡PÔ'ÉC éœH‡Ca¯Wܧa½Æº†:Iãô‘Gi΀B)ÎyùìØÜ0rqÓÇPŽ[Wœ6ø°¯A®(Ðé×q⼊™3g«ÃtB2™;,žÇPF™(ÜóêÒB~cœ„?ºBú»‹¶Þzk“*Šw'Fšè½à4}útÓ»¨uB^¶ôQö™à€4ÞVŒ8Í@f’Œµìɨ†›(9 BeËÁ“˜S©Öi…uÙ:öÓólް0s'W!)™3P11!Åû¢4ÙåA½±Ò1xÚ“i|ê¼Æ{M.5i«0Ä1ßږê2rÂÅqNDd¹ÈÉùwcïSO¼$°ê$F>피™0°X@),IRò¬“–U®Iëƒ6ÝtÓ…Õ!s¼ÃœíC­rc@eS~ðá‘ò¸×%xà5Æ!Ïxqrà˜´rŸòY¬/Z´ÈTðv‘æáÕX½©6êy(QÈå‹Â‘¿¥‰M(›NÆ)òãyË:—M›¾$b3Ì&å ï vÖ)Œ(7”E wx³C뇕ýNä´f= …ib;~ˆ2ëz>ìŸù xSÏ8=ž¥e‡¢^($qcíˆ25H’’[ªämÛ€ÓÆÐ[;É`Îü„✺r`o¡…\ùË^Žy §bœf¢ QžÃè‚%(΃(?;I(`q A‰Kß ÖÂx¥ó¡ôŸ98LOhœ›˜Ë»…†t<=ôP¢>ÌOÆ‹¬aÇ“ ‡²p±“¤”,Q¡HÌÜGšxn>¥„sÒïìÀKJQ v@YéÇÎypó@ãÆ5}ðˆC:  lä¡|å•WƱÈõ{w]ÔžëÛ ˆUÔÆµKò§Aµvq¸ù†×:‹Å FXU£$:ôÙð ç¡È" *-MZ~¾ô‘–¿Îó‹÷4¢O˜'PÔ|ÉCçIxð¢Ê¢­˜œö‹?’ð(qz¢¯àÁ³˜E&‹T^ð|ýóÒÀ:‘ßI^Æ|Ë þòE³NÈRçiæÕNC Ÿ, ¹ˆæ"]©ØžN±:žq.Âѽð^6‰äÅœíõ¤yÐu’¥–Ôw#!€Hô ¥\J'"v‰â­&qo#p€{/Æc"Ù…^é»dÒ1‘Z§q!¿ üƒ?ÎÚ<¨š¼é`˜ð˜±¿`@æÙ4bĈD:Á¨ëža®?Ö’8‰Øm:~üx›©'¼i‹±“àºBž{ƒ³¹yéÀÉüSŸ¢Úˆ¦à.gvYð,ÆžÉs9<Æàùá¿Yës~½:dMÂIeÄŽQtXаÙag,—RýE}Ç;s†èyœ;a^Ì#Rÿv §ã`>aÏAo|â‚C'».ðàLcäÒ±†cVî= £=2aÉ;—ß´áäœ 1nÒKêsØxðNI°¾›Ÿ`Uj¬è—~±WÆÉäíþŽt 0¨výÿ÷®]ªßÊX$ãÝåbãoQõà8fÌ+zúð¥sú!JkúôéöÆœ‹¾x”ÒDZ¾ãº>÷Üsë?ˆi%ýƒi‹ØrÈÚ¥JÛ'‹ŒU7ý<Óá=¿üòËmÔ­3î¥GÔyŒÇVÕÄ(j\YC'…¢Cva2§à½'BÔùÒ‡/yÔOeàlÂA^(h;â^ž/yè< æ5»¡(9í%~$áQâôD_Áƒ….k>,¤}/ä˜åe±m!:”yQc#€ÎÙ]š¥ÎÓÌ+^Ôp’ñ¾ÂË[±¨LÚá%]R|pÐáìä…Žu[ìq4ðbG4.¿]ÔÞêC4šX@<_¸ö𙏧¸òÜëjxß?øàƒ«" Ƴ®]»ÚOÞT“7csDcÓÀXÉ<Ùk¯½¥àÁèEZ Œºa …€ ©Žx&büïÿ»™0a‚5R³cˆpl Õ žÇÔRÃF‚-‚u)é›:wîlíR$ñ¥s&¶‹Àœ‹¾x”oZ,X˜Õbž;®kŒãPÓRXÄ}VÜŒ}¥Gâ¡|æ™gZ¶8¹(Γa@7nœe‡÷Ö7qS÷U51òI\èÄ9>1`† Âqç—úÞ—>JñÐwù!€QþüóÏ·3p%çxx¾ä¡ó$<˜×î~%gjIxÄõ÷=Ùþ& &Hƒ±ù4"a'Àƒw*ŒåìTJc0÷ Nvð›zwAüI[I–ì{î¹§9í´Ól€F° òÍg@)bþØÄ\`žr¿$õ‘«_¹Ë.»”¾~¬-‘£A™“q’î6<†Q£FY§×%︇rHäŽìsÅNø8{Üß‘3O™Ïô&qBèû|@¯lWã¢`ò×21áyÐðP©§¹È —üý\´µFèŸ.T˘rceDî< C™Ãˆ…S­R51Ê“zÑIÞ¸ˆ_k0ʳݖ{ÆîZ¾†‘¾^ä$ú†¹ï$­5¨#B z¶€´B|X'çED¤ñ2IúWÈ0î¼8²žä~‰ÌK>ñõŒõ{\@ÑÍÐ53‘:F$’ €­; †Tg¸å¹E8ˆê&J8]óÔºÂË:ò ƒ²]Ð/övÅá!|n¯`äyø{Œ®ÆTNåè$ +7¯ÊáYª­ãáæo©¶ú._œ³‰{/)D3ù §sú ߯ÒöÏ5¼é¦›Úg/ôYðË–†.[n¹¥9à€–å…pN!ÕD‹|ß†Ï ÇË2Ô†E ¨ó¬æàaü`ÎóÉ’0nöCé‹ à…’q"Âxñã…û ãå%’5 QclþPf)§úõŽ×ŒK+›Å{_½áÃ=#„á±HD!€‘ƒ,‘פÂ~Dz¿("_<glƒ¬y–:âù=iÒ$ƒ“hiê’¤y†9£­K­äúw¿y®"A´IC<±ƒðî‰ "êƒ:˜ð çï´ÎŠ4òåuvBRN¡wR;ò^åðÊÀÚ…´÷ïÑ£‡ ÜJëD`íÚˆ5N”aàRæs gSðÝ‚ó0t#k¥¨óÑ+ïîüæeXwcc÷ k/RmM›6Íàˆæ¾¹Ï>û,1·]û$¿YÇá˜bœ8<ȲeãýÄOX~´ ÎA þ8i±û7‡IÔX‘…Ý@ÈBÊ.ôÍÿab]Ê5v"D:LTz:qÆ\@Å™àÛÀ—08Íò?ÆmyÀ¤Jb ÍCQ<˜¨äžÃ°5ËÕYßs™(H‚·–›Z­m åºN’f(¬¸»{ Š*±È‡¸©±‹"Ï`žÄ5‘#'S©q¸6•þŽâQMŒ*O¹ç—£“(¬Ü¼*—o±öAÅÚèxupÎ&îuäß`ƒ ¼Ôyø~•–×ð9çœceĸA„d±{bZáóÒŒƒü§,æYÀâ€à%¢]{íµføðá¶ÉñÇoÿŽZ”–ê#î» ¸¶ú¾1ê<«yR8õößÿÅkeßèah`§"o»í6[·%ÎØÃq½õÖ3»ï¾»!?//{v¢^è}ˬþ„@=#À®®‡v³)A_|ñE Ãé§Ÿ^õ"ÊÍ®Z?ï_¬K)0}ã7š­·ÞÚ>ÂŽ8 ž¤ÿÃÈʵF*QžWŽxîá0ÀØ~ÿý÷Ûõ$;„éÇ}0„â4ÇVUÌáû õ‚0|b+r†bœîØ_H{ŒÑ£iBú$í3Ÿ úÈŒq—ñ"c WÓð­µsöÝw_[Œ˜ÂÖ¬Sȧϻ@P7`L¡iRê€ï2_¤q1~œ2—^z©9ãŒ3l_n}ƒ±ü¥—^27Ýt“­…£"½ïæ ï)èù”£;N®+¯¼Ò:~àWÊñCÚVl¦Ì)Š2S_ã?õŠíé³ñüáz"âŸR8Òp¸¹9̹8¥¸Ö˜[\ÈÀúÏïbÎqÂu‡Ý1|=’zê÷¿ÿ½M݇^˜³ag ²à$ÁÖJÝ@·Ë<è¬`­J:/(n7ƒ“#Ò³¤fב~×>\TYÑÍbäÜ4¸ qsª§¹Èö©!C†Ø;nRµDîºF&nVܘj‘pTkó O+Ä ¹VS T£¼çL½è$o\į5ÜÓÈïë®a~×ê5Œ“ƒ<í“·õˆª„è¢)S¦Ø L>"!Шæsï½÷ÎÄÐÈŒ3÷Üs}!9sfb#/¿DÂñ!o45x MKšöe½Qu¨q iDß ðàƒ.NéD¾ùöíÛó¥þ!úôéc{ì1[ŒÕÕíêСƒ5ôc”dHÖ‰qIýÂΖ ‘6 Ã)†Í«®ºÊO îâƒQšwZÖï^bØ$À“OÐpJ<Ÿ1ìRÓ„ô28Xãã˜àÙŠ±“g$m86še*ö7ër‚^àC[²ñÃ48äÚ'œc8ÿ?þøckÈu†Ýb}×Óq‚X ]sÍ5¶^69ÒŸDÄšƒ`qÉ%—ØñÓ–yQÉzÃ<…Ñ)ý1?°â,úÝï~gù¡›ãŽ;®U΂?˜&•-†w‚,0ˆc›Ã@=Ută8úĉàaý°ÛC?ó©BŸAÇDøœ¸ÿ©¯…ƒ g óèØcµÎìr`J`ÉE]dþ|G up^q½p`øÇ±Áv]p-0&l¦úÓŸ¬Ì¼gâÝNüð\,WQ<Êí#I{$l±rÛe“œ“W›¤¤<°â¦æî%܃^”ñ¼B,Øí”±¸áÆ q ` ËQjá¶iÿâQMŒÒŽ#íyåè$ «´|‹çxp?e ªp6±H$šJr '‘Þ霶áûU’ó£Ú„ç5‘ Åî‰Qç§9–fàéÖ ¬ûâܯÝ8x FÖ¤‘9êœ ž,¤E@PçYÍ+^š0Ì)"0@øLcÄš–]øÃÌu×]gwó¤Õò]|ñÅÖsÒI'Ù—öðË]Ú¾užh4ØUÍÚ …ѯ™ ã®Û!Ÿ6’¶™ñk¶±³“—"º~øaC±Z¢°™CÃàùä“OÚ¨lj°C޵fpžc|1c†5’òlÅØ‹‘’ô89y¯å½ {†êþýûÛß<‹±¶$b›5Qïô‡S1FYÖ›¤H¢_íiž‹ð ÑÝÇ1¢º¸DÁ³[˜HtŠ+³6ƈŽ…{LÐÐëd®çßÎ&ÿ?µ+~ýë_Ûõ?Î ôKd>©oЩ­ø¾ÒÝÆ¬í¸G³ ý±ã'Á8xaŽ¡ ÝŒ»víjSúLœ8Ñ 6ÌjÐYÑs—þ‡jN8á«_ž 8P‹9ºtébó.È‹bÊ¥jA$Ñ5»ãÉtÁܹõÖ[íÎ Rq=°¶CN‡qák‰9‚wv°3„”½î: 5:Ûo¿ýl?8÷'×`˜˜ë8‘q¼±;cöìÙCÆÈ»ŽI<3H ¤H“KØh‹âH5q‘ú\\;¡òàáx5ão&Þðw¸yè#ŠWô*©³£Ø8Å£Tû´ßñðà•§Ñ;©¬\×ÎT Ó<°Âçî%8,‚i1ÈÛvæ™gÚaáYe;b^„çÖa„A/ÎPj¾dŽâÁ"¦ZùWÒ~ÊÑIVIù$mçxL:Õ.ˆ“ž§vÙ#€Qž­ÓDŸ@I®á$R9Ó6|¿Jr~T›ð¼>æ˜cŠÞ£ÎOs,í80¸ð|‘+ÆŸZ ,²!¡•.¶£øy\xá…æ‚ .ˆj¦c „@PçYÍ+úÅ)L¤/h¿øÅ/¼!È ÜÕW_m›s‰ë‹è1&¸¿8'[Ó1Ð`Xágå\"Õ\êG =ËK䣿…@3"0nÜ8kaìýš½ˆ2F)÷ŒvŽ„fœÍ»5ŸÈ0ˆ5. Öb_–àoîYlQçŽ\¸¬xÁÄC4÷8¢-‰Êã{"9gGØâK~õ#ê¢g]@ÚÁÜôR{ˆšv °C—5a){@%ž‰<§œa–€ ž´‰Ç Ž ç|žJ1@ã¸:ûì³—¨䱘v8Å1þò,Þl³Í¬aÔµÛf›m¬až:<y–b(' žç'ëjÒ–‘N‡u†Ú0¹ñ#oTÀ'ý‘òÃ1 Þ¹±YÐ'Ï[ú…/ŽžÑ8*Âv°!¥5Ïk¢ÃKžÃò•úã0˜Ð1; ç“J £>²bO SÜ÷®=v-œ?w‚˜cìÆyÕ}®=p‘‚Qðì&i[p‚à@À8_ÊIÁx/»ì2C€óÝ0/ݹ`1 Â@/QsÖ¬"Œ›9L:#Œê¥ˆ5݈#ìNV®•R²²C€kŠy®NVj‡ ßRó…ï0üãÄ¢`8Ît€>px0/XCò½».q.DípüqMp½;ýƒx¢æ7ßs}¹yé@àÅ›h¸J ¯Þ rW! ‹b¼¢ê €^Éo…”/"¾õáKç<0Z°­g§Â6ž ùâì3üwZ\XÕÊßCøô÷Šz˜„Û'ý¬xÁåæÇÍ÷x_Ã@IDAT’LÔ;iÜ๩CQö¤ý¤iÇœÃkËXœ#!M?ÅÎaqÄ=±R¬ª‰Q±±eu°c‹+ ^ŸäK>eR_é`ÑÃu˽c7QaÊCçIxp ³ÐãÅ+Í }á±—û?<¸îxÁd¡,ŠWn_ÅÚ“2†{"‹y0áeý‰tND_–:O3¯X¿ñâÅ‹˜O1ÛßIñ€ÁÂðÀÚ†È=^"¹WÅñ+œDœá4 /Ö^DlmIZŒ"! –D€k# TÊ(³äYû«<×!ží>‹ZcŒwô4ïé.’›h–]<“1þ³Æ+Fs rÅ`ɳyÊs.L\Ót‹óº”c$Éø1¼ Χáh(Fر0"û&ìvIlwqíâ¾Êm‡õïA>îoÖb8&ø”KÊ»uëf?ÅÎÅ0ž„pf±vãݤW¯^±;ªÑ9k±¤Ä<惡? ±æ+µîÃÇ' á¤á•¦; Ÿ E:0.R «Râ¦A1 ò>…XâR‚TÊSçG€ r‡v°:¡ˆRúð¥s¼}l#åBx.úâQ)c·æ¥™»ÈM~@n¶\ˆµD\×l›òM胭ù¼Ôâ$$?9Ó[þØÅááΓx î¿ÿþ6÷^)ÏqZ™ˆbðU51J;ö´ç¡îs ¹“>ô“òò¥¤üÔ.[Xàà$å^G4RÔâ>'áÁ5ÌV]¶‘§yV$áQ)Úð o;‘Ù¤Kaa¾ûî»WÚíçó’Ht‘F`A>O «¢ÆE¥•¥ÎÓÌ+Œ"D>òBWŽ$NSþÉáë :bØ`-F^é¤kŒ8ñ¸F¸ÏeÇ3""O©IÛP?„@"À®ç¤Oó¬m4ÈÆŒc#^×é§Ÿ¹Nj´1k<ÕC€]D1ã y׃QüN2¢ÚÙ¡Gô8Qß’`°Æv%y à«O±¾"E*ï?¤ ŠÛQ‡|µÄ#Ò@/<Ô¥¼wIA?D&“3‹Å/žGQõà"À0Ë–,¢¿²Ð‡/³c…ˆ,òã…ç¢/¥4‘–[ÕØåÇÊåµDŒ ,!¼¤•^ßnlôK4×9/Þä2¬„x¡®Ö.æ3^Æ“zmË+ $XU£rÆë£-:!7& J¢6}êÅ—>|ŒS}TŽÎ&òû²ëâwx¾ä¡ó$°ª&FyéÂñA'×\sýCIØ ìÚ¥ùíKixëÿ`”g—…”!r—†çK:OƒyíîÇQrÆ¡“„G\qßÃÃã~˜Å=‘þ=öX[†þY›ˆtN>µ€²Òyšyuë­·šÑ£GÛÍ´…‰+Õ;4ÙÉÃoˆT|*% ¡|X ½É!v]øè»RÙt¾¨%ÆgBÈtòÉ'[£P-É—·,ìÒ¤˜-ä yË ~Í…v‚ãŽ;ÎîD ª›Â¯ìnÅ.±–uëM‚~X³Ô΃æ™#ì‚Úe—]¬þ«åàÅ>ÊÎæSØò°“ð!çAë¹é@ð•Þc*“BÛãZ_#è• ƒ5\¨T3÷M¾tÎ…LŠ¢#©v|ñ(5ö´D:ˆ@Ž201síµ×ZɈ >ñĽ;òà‘´µÇ%MÝ<ôѨ- üDLFÍÅrÑâ‘…-ð¿ùÍoìËÜ•W^Y®˜™¶w×5LˆÊ.æ@Ê+Œ¯î^‚Š ÷ÎЋӠZ»8˜oï¼óŽÕ/ãqiŒJ×2£xQU-Œ|+i?åè$ +7¯’ò‹kä×Vßç‹Î&òûºk˜ßq×p ƒ:߯’œÕ'5^ äÌ‚G˜oÈ6eÊû!ŸR„AßÝÛ¹ööØcï„ R²è»ÆA ¨ó¬æÁG1g}I‹H¡ð3fØ¢Ê=ö˜M7D0©’XóÄEó$uásÏ=g®¾új뀠è„2‹”¤3{4’fF î™ÕlØ<øàƒ‹S: 4H÷Žf›¯B B"šGµDáZø`tÄp‘r#¯oʃ‡o™ë¥¿4EtóÐGæѤӧO·Ev‚E”ÓàÅ#M?qçß–üýn»l\û<¿Oê@Ê+¢Yݽ¤M›6KÜKØžO¤Ä–ü<ÓQ„õ¢‹.²¼)æ.Àj¿ü(5Ž@³ŠþŒâQMŒ*LŠ“ËÑIV)X–<Åñ 4ï%Ó—ÖáÌ3ÃBOr 'Í霶áûU’ó£Ú„ç5éúŠÝ£ÎOs,Í8žzê©ÅÅžY÷Åcˆ¨vã 2:‹¼ìA8¼ùˆ Î³šW¬;Y'Ïž={qQG¨rÂQ@ñHœxþqÊÓ­[7³S!M'õÉØÁ5ʇ6_|ñ…M5‚óàµ×^3ýë_Í}÷ÝgåsΛo¾ùbg¤yÕ‡h$¸æ¸† žM;S‡à1W<9ÎqÙHó@cB@?D:X@ó6Ú1wüñÇ[Î,àËÝz›DäIÛ9™®ºêª¤§©]`”'ý…”¡$×p±œÎiËßÁûU’ó£Ú„çõ~ûíWôžu~šciÇÁ…5Ÿ8b‡†»·wéÒ%cM©`zè¡8±ô}#ÔyVóŠõ»(¤wøá‡›ý÷ßß j¼+í³Ï>æÅ_47Þx£-¢Œ€t—|®»î:› vÆR7ÂAÍ®  8X‰`ê¨àÔã\‘­7nœ!E tòÉ'7}eviº@Ÿ;­Z#¯#B@!ЈD:X”F˜1<ŸrÊ)™âLPãW¢œ¶Ûn;›{5‰¨yè#Š[É1d5“ÈlÅ#ø½¯¿Ùþ~Þyçy10ù’ÉõƒþÙJ•Â4¬xÙ-v/á…ùöÛo·rΟ?ßþÎë†2‡Q’Ô'¥ÆáKæ(ÕÄÈ׸’öSŽN¢°JÊ'i;ǧIQ˧FyœÜë¸%¹†“Hætž¤m9m‚rfÅ#(OZœ‡ÁüðqÄú‚O–äAd©Y¢]}už•Dì*Ã1Ì'É\/GŽõÖ[Ï:$pþO:uqD4}°ƒæ™gž±Ÿ¤}âì`=?`Àï²&•Aí„@= 0a„ÅiÔC åW3“«ÑÌhìB@!H/ÞG}tú^ÿw&6äøäÈw¶å’’DTÐë!ClaâöíÛÛ((ßúð¥s +-ˆ:c{w|ñöþ;-"S÷Ýwßpw5ñ?ú?õÔS­,8g|X‘R‡—oRpW²-–9¹Î:ëXñˆ˜Í“˜s\#Œ% Þ_}õ•½'VŠU51ÊSðrFO°#´Oò¥Ÿ2©¯ô8g÷: ŽÝ»woÕY:Oƒk˜èaR¥y¡O£ÕàË<äìСƒ ÞtÓMËì!¾ù¢E‹ì=‘ß<÷yv,³Ì2ñ'ªEÝ"€®1šg©ó4óŠõ)N˜ƒYÔÈbGk%îSÓ¦M3¤•dýTq°C#è!‡b>×såÈ¢¶B  ˆ9ëHˆk¯Ù‰ÔiØf ‚É*y_kv,5~! „@3"é@`1Š—¾R"ç“O>ifΜi_y õÕS©ŒÍt>/G»ì²‹yá…Ìõ×_o¾õáKç¼üÍ;×Pà)<}ñ(¥û´<›-é.•Q)yÇuíÃ1–¬( ȼbŽm¶Ùf6'o¸]ÒÿÛµkgwqОâ‚yEXû÷ïo#³xÑøøãmäJ±ª&Fyê^èdàÀ6û$_úð)“úJFœ¤ÜëÈ Ž£â¾‡ÇÝwßm(L Ž8È};p¸_vÙefÒ¤I†Æ “!N1uþ}:OÃÃ<Ÿ,‰µm§NlÑãgŸ}Ö<øàƒöúzóÍ7Í'Ÿ|bw?²VƒbÀé@`ëáÎ;›½öÚËÞ7p(ˆ„€ˆGÀåûoÙ-¸ç¸ƒéù~¦7Š¥B yˆ\bhþãÿh~ûÛßVŒ [ÑY³Ö¶ôŠá¬¨ŠèŽ=ÚöAQ·¬ôáCçôA”íØêž‹>xÄ™†/€äï§ðs­×õ¹çžkÅâe4Œi%ò±ªôŇ/Óé3²H%Tl¬aåÞ‡ξ‰HBXU#ߘÄõ‡NpBãœãïN8!î”ÄßûÒGb†j˜)8›0v³ÃZwÝu[Í—hìöÅ£Ô|H˃—â¶mÛæjô.5Žàw\×Ç¡0¦Ávåþ V¤-úðÃmn^Œv•E‡j»`Žž}öÙ•tWÖ¹¼ÀsöM8D|`UMŒ|c×:aË5DD´O‚/}ÄAßçƒFùóÏ?ߌ?Þ2$çxx¾ä¡ó$<˜×î~%gbIxÄõ÷=<0bbpYa…ì'îœr¿oÓ¦ÙvÛmmzžLE:g÷ )y²Òyšyuë­·Ú æ ióöß/ŠÀùÍõîòŽÓ?»¥œC€5kò<ƒ%¼ L:@`ìØ±6¢ž|òÉM_DùÐC5nW÷_‘B@rˆt øJoBÄ ùÄùˆªz%·0/ëÔBøå/é](_:çÅ .ÑáT;¾x”|Z¼ŸwÞy6Z¬TÿÕøý¯±Æ–uÓJä«£Ž:Ê~*éÇK”+»8 ùóç»Ã¹üÆPæ0 §>ñ!}úÀªšùÀ¡œ>²Ô‰/}”3µÍŒt8¸×á(º†óÐyR¥äŒC))¸~J} 7ÜÐîÄàà»f¼éß9ŒKÉ¢ïŸmêE'>Ǭ¾Ò!àœMÜë¶Ûn;Ó½{÷tåp×ð&›lb¶Új+SË/ô¤»ã9Ü·o_“EaÙ  !Öoì p…yï‹HÃ9gÎ[LJ> ŒhiiñÕ½úB ¤-b ±Fhv¢® Û E0™Ò5ûŒÐø…€å!é@À¸ˆ—>L¤•!’"o)…À|?ŒóàW³üÏËQ·nÝìpÃ…‰‹a‡>¢xP¬qîܹ†OQs±˜¼ÅŽGñð=wáÜïs©ŒŠÉSã\×Iƒy`E=†§Ÿ~Ú€\¤3àžµk×ÎîâàoÒgäI8 ’`äd*5צÒßQ<ª‰Q¥ã)÷ürt…•›Wåò-ÖÞñpó·X;ÏçlâžBnñöíÛ{ÂéœÎÂ÷«´ ¸†Ï9ç[À4YðË–†Ç[laHÃuDš:R•¢×^{ÍKiƒ˜±UZ'Ì/Èì¨ñê<«yÅŽ›=öØÃ:̲ØmÓøZÒ…@í!Я_?³ûî»Û:#o½õ–Ý€SgÆsj$ðÁ¨Þ ǯ¹æóÒK/YEvÚi*¢\{SV ! jÂ`–øRx´Rd–¤Âvq»Â¾å7ÞX²‡ÿJñ~”¹ÏÝçÆï¢õÔR0ŽÚÏgœ‘hÀAÌóÔy!—uK¡ÈSˈ#"çb"á|Ž#ØWpòwÁIÓRØÐrÄG¸×ÆŸ熽f¹n£®o'ep|Yé|Ò¤I‹ï%…èÖ–‚C˱¯êï ÄbŒ E ceÉcyðˆh”£“<° ò_ÿîÿBNû*"Öܬ˙/I‘ êÜ×ý*,g<ÂãKãþañºáž{î wÙêÿáÇ/¾·üñ-…´0­ÚTz ÈÃ]sQ¿‡ V)+_Åô”F/Á¾²œW h™={v£n}êÍ7ßÜRH©´øº2dH˧Ÿ~ÚºaA_Q×W½c@¡‚}¯dÞÓZ µÄ,(Ív¼Ž°¥àÔ·×4k‘B@rˆÜ@”Åý‚…k \Q#UÝ,`¡¨Ѥ3fÌ0lÿ®—¹øÉ'ŸØüý)®5âº>÷Üs­XlϯUL /ÖæÍ7ß´r’æƒhüˆ"¬_|±eG1èpÖ¼äˆãSMŒâdóý}½èÄ÷¸Õ_ù°{júôéæú믷'×ò5ž×W¯EzòÉ'{&BÛ_¬EY%“¨ ˜‚Áî´ñ™Æ¨R¹t¾BÀ;w6Ó¦M3ÔR ! „€(H†æqãÆµ20²…\¸Ð*«¬²8åH¹LKµÏƒG)þþʼnÉ´ˆnúˆâtòäÉVã+5vGñÈB×.uQžFï¤ãHê@Ê+Ò€¸{ é‹p9*D-.ª¹ÑF™³Ï>Û}•ùoаâ<… Q䱄Rãð%ljbäk\Iû)G'QX%å“´ãÁõô /$=Mír@£üùçŸo )Ã.É5œD,§sÚ†ïWIÎjž×;ì°CÑ{bÔùiŽ¥éþH]—¾™xö¹{;)"¨g䛂úUB ‘ Ÿ0éxý/„€B 8‘¡Q…DyÙ]mµÕŠ÷æá›™ 9Ýí}ÄGêC! „€B@D!é@À¸Èb´RúꫯÌ[o½eÞyç³ÔRK™6mÚ$2ÊUÊWçG#Àˆ j <õÔSVIŒ¤Ñ½Eõ¥óBÁ_S(ökØj.úâ=‚¯¦åܯ¼òŠq©ŒJñÈû;®ë(Ç`¥r€;FÞ{ï=;n¢~ÙÅ–Úµkgwqp>Quy×Ãa‡fsƒúz¹ÊÿÅ_Ø{b¥XU£àxòøŠ’›BÑYïÑ̾ô‘âÎ&œäÜë0v·oß¾ÕIyè< ®ásÎ9ÇÊHJ–r) rû ·‡;²:`Ý0oÞ<›î!Ü®’ÿ?þøc{O¤œ*¤“P$u%ˆÖþ¹è|Ö¬YvNe¥ó4ójóÍ7·i 1Èã4ËŠæÌ™cøø¢µÖZËìºë®¾ºS?B@! „€B H—_~i·ð–JsÙ[è eo¸á[З„>}ú˜_ýêW¡Vú7/(¢‹Á‚­Ó0ÊùÖ‡/ãp"Œ¢˜l'ÎE_Y¨¯C“ê‘@–¬tžf^1ï4÷jl²H! „€B@šA Ò€¡ãg¥ÅK1X™üôÓOÛ-íÛl³MÍ ¼¡èçUW]e‡Îvptã›|霢ºD“Θ1ÃIœ‹¾x”{ZÓo»í6›~©TÿÕøŽëš—vçLÓJä+Š—r¹‡sª¢€¶››8óLcÄ8.¹äëDØpà oÂçŸî«jbT‰nÓœ‹NFŽipÎQhöøãOÓMä9¾ôÙ¹æŽÎ¦éÓ§ÛÀ˜¯»îº­æK:OÂÃÝkŠÉ^q}Ä}ø/¿ü²mÊ®@ßÄÎvíñü€xN‰š–‡K]”§Ñ»Ô8‚ßq]5Ê clWîß`…ã€ëœ9UéK7¹‡ fÅØh£ÌYgU®H©Ûc@àÞe‘[›ùá«jb”Ü”'¢“Ñ£GÛ³)>éÓàK)‡¦Ó<#€Qž‚ºwÜq‡í™ú9áù’‡Î“ð`^»ûq”œqÐ$á×GÜ÷ð õ¡ûEAdœÄiæùѶmÛLî»qãÔ÷ù"€ÎÙE—¥ÎÓÌ+‚?ÆŒcÓhzè¡fÿý÷Ïæ9už”ñA¬)|§#õ!—úB@! „€h,"¾Ò›°€ïÝ»·éÔ©“}%—®¨z Wr¥b”%§qÏž=½ ãKç8:Hñ€³#œjÇRƒOËc¥•V²Qþ]jп»ØV"+Xxà¶Ø5ELqNTB¤ÍàEâï<Éa…g6œ+>°ª&Fyê^YêÄ—>òÆDü¢À(ó€{)w¢®á°ª&F`“'e©_úÈñ*Ž€s6aˆÞ~ûíM·nÝZ5ÎCçIxЦcÇŽCeš¨Ix´|™àÁ½,9æû<.³‹Øæ8)²,X+€äŽ@:OÃõÑün—nîÀˆ¡B@! „€¨a"ûõë×JlrSÈÂÀËBã¡Oʃ‡Oyë©/^ŽºwïnE&.6Ž<ôÅcÑ¢Ev®Q3j.“·Øñ(¾ç.¼‘›|ÎôÍ6õZ"®kŒ@q”V¤¨zë­·¬(Ë.»¬!ß0÷¨]»v‹k5æ OÂi#'S©q¸6•þŽâQMŒ*O¹ç—£“(¬Ü¼*—o±öއ›¿ÅÚéxþ8g÷º.]ºx ^p:gDáûUÚQr ŸsÎ9VFžYðË–†Æ}Œ±ŒûÃ?48gJ5 ,X`› ‡W\ÑæÎ'y8^>ûW_µ‡@PçYÍ+j¦|ðÁ6µ’j¶ÕÞDB@! „€ÕE Òú1ÊÀÌ‹ÚðáíĤj9ãŒ3*Îw~<Â<›å^ÀÊ-¢›‡>¢x`pÀhÁ#j.–«³(ôï›(ôJ”?©3(D^Kä®kd¨Z,QXÍ™3gñ\Ä6xð`›rÙpTkóíwÞA ›:'*Šýò?J#Ø®’¿£xT£JÆ’æÜrt…;o|’ã!‚OTýô…³ §³»†ùw 'áìtNÛðý*ÉùQm0‚º][ÈIú÷|öÅ#Ì7Í8¨;2uêTûÙc= ŸR4iÒ$3~üxÛd·Ýv3½zõ²uJSîwA.åL¹}¨}}!ÔyVóŠÔ™Ôe ½gÞÁ õ¥ I+„€B@!ÐŒD:04cü ®œ>úÈ\{íµ'R‹œxâ‰Þyð°hÂiŠèæ¡(—#štÆŒæã?n5ËU_,Ÿ|ò‰Íß_i€rÇ—¤}RRXa|u÷ÒTvØa‹Ÿ~ú©yóÍ7íH¡‘g#а^rÉ%–7шá¬aœK#Ü6íÿQ<ˆ®FiÇ‘ö¼rt…•oBGÚ1é¼lÀÙ4}útsà 7XI®á$’u¾_%9?ªMx^“V°Ø=1êü4ÇÒŒãÉ'Ÿ\\ì£jœƒ¾×í}× òHƒƒÎ©?‚:Ïr^ÁÞ&›lâýý¦þP—ÄB@! „€Bà"šÇŽÛÊhëÒq:)G|oK§ßìÌ Ë÷¸sÒ|ïRåiôN*gRRXa'Ô¦M›%î%¯¾úª6l˜ýŽ‚ßgu–ý;a5j”eµãŽ;Æ:J×¼Q<ª‰‘¯q%í§Da•”OÒvŽÇçŸn£Æ“ž§vÙ#€Qþ‚ .°…”á–äN"•Ó9mÃ÷«$çGµ ÏkR»'FŸæXÚqP[‚ÔEqé‹i¹å–[<Ú³æðMA8¼ùˆ Î³šW 8mÚ4›ZìðÃ7;öM\Y\¾åTB QÀ)HÄ3–wJêœàPgWï›Í|¼Qô¬q! „@>D:0 F˜Ùrï"rYÀ³ ÷Myðð-s½ô‡^‰¬Ún»íÌÎ;ïœHì<ôŃ4:g‘5 hÅ#ðµ·?Iíuî¹çz¸ô! ú_c5lW¥0Í+,î^ÂßÁÕwß}×îâ@PþΓ\Vx&I}Rj¾äŽâQMŒ|+i?åè$ «¤|’¶sï¼ó¬X8g|'«n¸Á\{íµvû?ù¯‰äKKô‡Áb‡LžiŒØõBT0Ñ9n¸¡÷Tï½÷ž¬ª‰QZ½¦=Œ1ÂP…û•˯ž¶¿ày¾ôìSWœM3f̰×R -<_òÐyÌkR)“Ó~QâG%NOô<î¹ç3iÒ$Û~½õÖóî@ òó²Ë.³ÓÕ¯¶$¹¨o(–<þ|»ã©¾GâOzvi²›°’Ýâþ¤QOB@!POD:04_wÝu^ Œ‚y@‘›XÛÒkcj°û€ô¬ôáCç‚È1aŒ»}ðˆÓF.uQžFï¸q¸ï¹®1Ô@Q˜ºvi~±ª´8 Åi1"AñúO#_Òsp\Œ;Ö6Ï¢H<מ¬ª‰QR,}µC'£G¶ÝQ<:l®„/}T"ƒÎõ‡FùóÏ?ß.Ð+õsÂó%'áÁ¼v÷ã(9ãPIÂ#®¸ïáÁn@ˆ5éé|S0íý+Õ‹o„k¯?tÎ:wƒ¬tžf^ü1fÌq衇š>}úÔx’H² ¸i„ 6¥¬¸q§N̾ûîkH¥(B@!P‘_éM0”m´ÑF¦gÏžöE¿EÕC½b8&¿+y³Ð‡/c¸ B£E8ÕŽ/¥4‘–¤‰"gt­ú_c5¬XaL+‘¬H[ÄÖàW\Ѭ»îº•tgÓyð"ù( ]Ž0®+ç„SŸ”ÓO±¶ì¨ð)Oª…Q±±euxð`û<Ž9¥ì¯Ùe6tèвÏÓ õ‹@:Oõ ,vF(}QýÎ/I.‚pMãP$ &µàDÆÖB¤Þ…Jc¤!„€å é@À¸ˆá_ÔXðrÔ£G;¨paâZé¢E‹l= bÖÓ\DnrïºTFµ„+×õ±Ç[K"EÊBd »8 XyNa”'âñ¼êE'ñ#Q‹¬pÎ&]ºt1µ\ûõV‘ÈûZ%pĘJªv™­H4"Ôn:ᄬQm‹-¶hÄ!jLB é0`€­ÃxçwÒ`ŠŒ­/xá…Úúbµ¼N’®„€B öˆt à¡20“—þñÇ·£àe’zDüù¤¸×äEa½ä’K,;Ò(… °†å(5ŽpÛ´ÿGñ Uµ0J;Ž´ç•£“(¬|çTòH;&— 8›f̘an¸áË É5œD’ ÎÃ÷«$çGµ ÏkÒ »'FŸæXšq<ñÄ‹‹=“"Î@ÁÊáÇ[ñ¸ò7µq|R‡Ï~ÕWí"Ôy–óŠk„t]›l²‰ÒÕîtdB 1¼ÓÌŸ?ß°C\ô5)P³OŽRÍ! „€(H†æë®»®¨±\&j_;Pœ˜ÈÇbÑçµ")† É“'[q0Æ3v׊¼N—º(O£·ã÷;)®Ï,¾Ÿ={¶6l˜íš<Æyê£üe—]fySÀ9ÎÅø“ôYMŒ’Èç³M½èÄç˜ÕW:0ÊŸþù¶2=Ôò5ž×YÕ%J‡ä’g±;§¥Ò-‰‹þk<p˜‘Zìˆ#Ž0}úôi¼jDB ÉÀù8aÂ[¡É†^t¸dèÝ»·!•¢H! „@9D:Š¥7á%’è;h•UVYœr¤†qmóà'C£~^Ù¢MQÄ®]»&fúˆâ±páB›*‚42>œQ<Pf#":ÈßO½‰Z#ôïv]”Â4¬ˆ~q÷Ò±ãÄé<ØÅaÌ“˜o£$©OJ×ÜQ<ª‰‘¯q%í§Da•”OÒv޹^x!éij—åï¸ã›¢ cw’k8‰XNç´ ß¯’œ_¬ ÷d'gV<‚¼Óò`7 ;X;ÄÎswo'}côMAè|îܹ¾Y¨¿C ¨ó¬æCþ÷¿ÿm?Ûo¿}! q„€HƒÀý÷ßo¦L™’æÔ†=ÇA¯^½¬-§a© ! „@&D:~ðƒØ\·D€óòGaB¢ÀÙ¾~ñÅÛü³?úè#ûð!·:‘ä( ¶Osœ0¿úÕ¯l?¼$ÀÓõ3mÚ´H\´:ÑßÈ1޲U‘ü~äÏ×ñ¯qÛƒ:ÈÖ® ¥ *§[‡qX‡ÕÒ9[N1ZtîÜÙ¬½öÚv7B%sËç8˜Sňëb³Í6³Ç{¬¦æ#ú§ õÊ+¯l‹a†¯o7¸n~ýë_Û¹ÁõDä)y¦Ãsõç8F^æ/ù\Ü0ì;ÎN˜Q£FÙö---6/ésÏ=gÛ³ÕCè #-s¶Ú"FALÈéû8<† bÇðÕW_ÙyWl _uÕUmú%ÆÌœ}æ™glÚ¥r°(Õ?ý`°¼é¦›,¦o¿ý¶ùç?ÿi·cƒÑ_|aïè2|²Æ?ªæÃ¡‡j ­q:)5¯|éÄé|êÔ©fß}÷¼0?óœ·Q¸5ê|(5.ŠüâÄ(Oñß6Ú(öN2/àɺ„k•ëŽçg’û\©k›yݱcGû¼Ø`ƒ ì5}Ê)§Øû(/÷ð|å•WJÞGKõ5®4×÷gpd‡éåH+Èz4xàÍýÿ½÷Þ³˜sü€0;ì°ƒ=ÎuðòË/ÖrÅÚ§9Ž3^ðÅÙìÎá‹Ù¸'ß9A=‡9…grãì×ñlqë(B/qó(…«–¡C‡Úc…sK!…Ha-ÝÒRÈ¡^õãaYƒÿ#÷èÑ£­¬…E~KÁèdÇ ãßàpÑEU]‡IæÔ믿ÞR0µŒ6-…|´u3 ž-‡rHMÎ;d+Ç[xàÅs`¹å–k9餓Z /ÃK\ßå/,Ð[ Ûþ[ NÅ–‚ó åØcµ¤9~ '´êØ>Ž;BAeÛWÁp×rË-·Øë»`XËìxá%Ãò)lïµ| E[FŽiùÜ-ƒ ªúñB¡n+ã\ÐRÈóž+>‘%þQý_}õÕKè$ͼò5?]?“&M²¸ŸAîoî]yÏÛ(Üò¸^j‰o!À¡åÒK/m)¤`lùë_ÿºø>„>8ïOÕ<ÎëÞ{ïmyä‘GjZÎ /¼ÐÞ »ì|ßj«­Zî»ï>‹eÁ‰ÖR(PYÕãîš+ö»[·n-È "Q[Ÿ¶:žÅôRkóyN>ùä–ÂÒ–k®¹¦…yïæ sÜÍ!æ~³/¦ËB­ªžÉ‡\KÁ ÙRpÀØk¬ZÇÃrê°Øë_?šž³l)OÙyžÍø!褥gÏž-…@—朵B@¤F rBáa*UE€â¹…—4óðÃWUŽr™ÁV«[e‰8¡ˆòUW]e †y;4¢hÙÙCáQvN8*÷8ÑxôóüóÏ›‚ÁÝuc£ôÊ=Nd!}P‹ `à³ó`q‡9üAÅ`îãÏ?ÿÜFÚ]Dí@Õ<¾ÔRK™‚ÚFW¥Üè„N\m Æês¾•;?]ûFǼÇÇ(® ˆ´6wÝuW̓T=zô¨ùô;Ô¡aÇEÁpZ³XJ0!àwÞÙœ¶+Òžˆ’!@±ú‚1ÒîÎzöÙgÍwÞifÍšeªu<™ÔjÕ,ðœ7ož™8q¢ÝíÜ,ã.5NÞ³ø°³²}ûö¥šê;! „€K é@ åÛuÉ?N:#þ†ª}ƒòã?¾Äø‡íÆ|ÇöâBŒýY×[o=;†f?ÔYð¨5݆塆‹¾±cÇZ}†¿¯æ\tsÌ úaã7ŸZ›w8¸~‚Ø!>r~üñÇ/ìZ°).¸yqDgPÚãœËÖZ Xô…qÐå4Ïú8¼IÝDÚäg›/v¤AžZ8n…*ü@VòŽç…OÖøëßé„q§W>ç§Ã?ü»˜ü:þc U–8vJN8øÜ}ˆë‚ûÔ¿Ž}Ÿ.…é[¸Ö:tè`ïïÜ9ñì¨öqºsФÊaíCš(ä„H[„£œ9 ãÙã@Z¿(Ý ôPKó(8¯™+Èææ sÜÍ¡f<ÎuE¤C—[l±…éÛ·¯]«Q„šTg¤ðËûø‹/¾hQ²êXó"À}ˆ”¤6}õ¸®Y‹‰„€B@”‹@«-}…aê- YžXxi%ka°-µ*o–X”Ó·ÃM8•ƒZñ¶Oæ^øSË;¹kYF‡ºKS0Ô»C¹ý®&ïrYO²–;¶`ûZ§“)|àÿjÌÛ ^Íü·Ó‹tг€ô$Q× Ç† Ö Ôè(‹éFz©Q… }E]cè·–¨^ä¬%ÌšA–#F´‚¯àœÇQs»Ñ±>"åcagF3LQ! <"¹¡ðà ! „€B@! „€B î¥ƒîÅ@IDAT ý^­¦–­˜k­µ–éÕ«—Ye•Uª%‚ø ! „@"°TÊ-±…€B@! „€B@!Ð ÒζiÓÆ,½ôÒ­¾kÖÔÄ#ýuûDB¾úê+!„€H„€v $‚I„€B@! „€B@z@ ÿþ¶ŽŽß}÷Ýz9sgΜiFŽiÎ=÷\QÎíÚe@­°7ÞxÃÖùðÃÍ·¾õ-³òÊ+›u×]×P‹R$„€ˆB@;¢PÑ1! „€B@! „€B .èÑ£‡)Ô@°N„º@B¿ú꫇ÊÛo¿Aïê²øòË/ÍÔ©SÍСC;ûîkºwïnºuëfN9åóúë¯×ü éÜk^F (ÈŸ}ö™™|¸6lX³ [ãýçwž¹çž{ Á}ô‘p) °ãŽ;šÞ½{›¾}ûªr“Έ›nºÉœvÚiÖ?dÈÓ¯_?Ó¶m[[+„TFµJgŸ}¶¹úê«Íž{îiN=õTóÓŸþ´VE•\B aˆÜа£ÕÀ„€B@! „€B@†Fà¾ûî3S¦Liè1–;8"·{õê%çA¹À5Pû7ß|Ó|úé§æ'?ù‰Ù{ï½Í:ë¬S£cÂû￯Eu¡- Ù¨¨B£jVãB@! „€B@!Є¬¶Új¦M›66²º ‡9dvbç~áÂ…‘ßë`ã#À B»víT¤ñÕ­ ¯ÈàNu&„€B@! „€B@TþýûÛh{rþ‹¾F`ÆŒæÂ /4³gÏ$MŽÀ2Ë,cj9eQ“«GÃ5‰€RÕ¤Z$”B@! „€B@!=z˜y󿙉'šwß}7M wΫ¯¾jøüêW¿2íÛ·o¸ñi@Ѱëà½÷Þ³é\añO>ùÄhÙe—µ'ýèG?2+¬°‚Yj©Ö1Ƥâü?üÐ|þùçæ{ßûžmË s'qDp×!}Á›s(ÚüÃþÐ?þØòýâ‹/Ì|`¾úê+óßÿþ×¼öÚk‹SQš>–^zéðéfÁ‚¶:çÀŸÂËÈKñèüà‘c¥“––C±iR=­ºêªæûßÿ¾=ÿ?ÿùíôOôų•: oSH§Þè³Ï>3?þ¸ùÎw¾c¶Új«z?wy…W¶× ¾õ"'Úb@Á3›nºi¶ õ^MÞ!Qbÿ­'YcS¢A-³–e+iÃ~%}4¬j ŒÊ9s星ýìg¶ `¢“Ô(3¤Ì UÇ à^ j^0:ció¢°äÈ1ž²#Cª¨y`çÉ­·ÞjÞ~ûíÅEÅ_~ùesñÅ[#>Hxàfçw^"­Ñ¢E‹lÊ+Š‘?úè£æ¥—^²Fùÿ÷ÿþŸÙ`ƒ L×®]Í®»îjV_}õ’Æt ùÓ§O7wß}·™9s¦uà0XwÝuMÇŽm-†Í6ÛÌêƒZyî¹çÌ7ÞhùÓ¦M³©·ž|òIsþùç/n»Ï>û˜=öØÃàHpDŠ&RuQå‘G1/¼ð‚µ/¬²Ê*fýõ×7;í´“•{Í5׌”» ›9oðàÁöøÿå/1ü>ùä“MŸ>}¬ÅñÔo!Ð |{Ò¤Iu7N^HÚ*œװåÏpá•-âõ‚o½È‰¶&Ožlì8ò¾Æ«É»Ü™ZO²–;¶`ûZg-ËİYþ–>šEÓÑã<묳ÌðáÃÍ€ìïèV:šÒG^H‹QŒ;Ö`øÄx)úÎ;›Þ½{Š)×YNd;‘ÞŽñ‰Š€ÏJV"ÓáO$9ÆeŸ¿`¿yòÆ™öüóÏ"è/v‚np” í¾ûîöxPF ø¤¼ºë®»¬Á~å•W¶Îô…3€Ï‘Gi=ôP[S!*"Ÿqâ¼  8ƒ3ÑûDùßB8'0ÊãŒÀÉåˆ ñçÎkw?p§ Çœ®¶ÜrËVr¿øâ‹æ¢‹.2wÜq‡»ÖXc ë€xðÁí}™?üp[DúÛß^21 „xÀ<öØc†LÈyÞyçÙ8ààçÌ3vBúèÿø‡­QŒ;$pFÊyP !o&”¨™´­± ! „€B@! „€hp(K„9FPÑ×`èŨ4ÜW œ;|ÐRÕéM:™¬‰ˆxx±bÖ¬YÖÉDÄ:Æâp„¼oYªÉ;éX0ijS‚y&ßÿþ÷‹žÚ®];›.ˆë-løwý¬¿þú%yÔæ`GäúISc~ìBc —"j<@8Jk1ÂIʦ<êr“AÇ…@­ B­hBr! „€B@! „€#0vìXsÏ=÷ØwÖ  Ne ¶Õ&òÑ6̦™Áð¼Í6Ûòßsèg)cŸ>}l‘]j€üq®äAÕäd|8V0ªÿèG?*ºkÀõCÝ ö¤úì³ÏÜa» €cè]Û}À àŽÃ#}¸ŸÅ&øÃÉaĈ‰æΫR5R6ÜpC»3&{5 € ¯b P! „€B@! „@ó @1ÕG}´yœ`¤Ê{÷îmÓ÷$hžy á|ðÁ™ó‰b€£¢k×®öõ}–ǪÉ;ɸp`Tg7F\ä=ÎÚaˆÖ.p©ƒ8×u p0À+ÜOy]ÈÍΉ½öÚ+QÚ!Rœ‘Ϊ!›H¯A3A! „€B@! „€hV[m5ù¼`Á‚’Æ 3àùè£Ì믿nsÚ×B£"«I Ž—N¨”ÆY°úê«/‘‹ÔÀYòî»ïÚ6ÅúÁðÏܤ€u¸ŸbçDwu5Ø91xð`³å–[F5Ó1! R" "Ê)ÓiB@! „€B@! „@í!@áSÒõ¬¸âе'\•$š1c†9r¤™={v•$Ûz@€z80êSp;˜š((?» Þxã [w€:áZ ®œV8 ŠÑk¯½¶øû5ÖX£U?ÅÎ wÎÔ?)•šˆ±9çG¸ý/„@4r D㢣B@! „€B@! „@"@ñSŠô’¢Dô5¯¾úª?~¼5 !P RKQ·€ô=¤à Eï¼óŽ™>}ºùàƒlý ŠtÉO~æ™gìÎÒEѤI“ìœdçÀO~ò“’õØíÀN…(‰Áî ÿûß‹Ê͹<òˆ=z´Î‘ñÈ‘Z! „€B@! „€u‚éWˆB.f´¬“ax/FV¥/ò kÃu†ûí··Åï¼óN3sæÌV»0ºóÝË/¿l(¤¼ãŽ;Z§CŒnݺ™¶mÛš7ß|ÓÜ}÷Ýv·BÐøÏœZ&L°×j=¬!ªîÂ2Ë,ck)¸A>îov ì´ÓNVŽo¼Ñ<õÔS­ä¦íþóë<:t¨ùÃþ`(¾,B Õ@ˆÇH-„€B@! „€B@:A`ܸqÖhI Ñ×tîÜÙ¦u¢˜²H”B OŸ>æ±Ç3S¦L1W\q…­eо}{»;€tDÓ¦M3—^z©­“0pà@³Å[´rLm´ÑFf÷Ýw·)³n¾ùfCJ#váp`—>ú€Ïª«®jH;F £(¢¦ uþñ˜§Ÿ~Ú¬°Â –5ØeäŠ;¹~øasùå—Û®:tè`Ó"á°`7ÅØ±cí¸H¹Ô³gO+WOB`Iä@Xý'„€B@! „€B@Ô1D5“~Eô 8z÷îm(6+¥Øxã Ž… š‰'Ú[mµ•Ý•0wî\k€Ç‘À±þýû5ÂrÈ!†TG·Ýv›ùÝï~g&OžlpDÐ/;žþyÛçá‡n6ÝtSÃNƒ(êÔ©“u2¼ð fĈæñÇ78HY´Ï>ûØï8oƒ 60ôEª#œ¯¼òŠÝMÁÜç÷„'Ÿ|Ò::è ³ë®»*ÍYà:&"!B@! „€B@! ꌋäqgB©bªõ9ºtR“v†‚¶D{+Q: ëý,t‘ýg?û™è/6ÒxàöºòÊ+Í¿þõ/ëHÀðÏÜYi¥• )‡Ž;î8ÃN· Üõ† f¨o€#ƒ>;–Zj)»+`“M61 0ûí3|¾û—]v±mØq€Câ/ù‹íc³Í6³µN—#úâÿQ£FYÅC=d‹4##²o¸á†¦{÷îfРA‘;h×®];[Û"ìÈ*BÀ94 „€B@! „€B@†Aààƒ6äü§h0©RDÆÌ˜1ÃŒ9ÒF‚.j>öÞ{oƒÑý{ßûžàC€:DÿÿóŸÿ4Dÿc¼Ç9·ÞzëÙIŠ”³KàŒ3ΰ‰_|Ñöµì²Ëvà@ .G±N>ä=ýôÓmƒgŸ}Ö¼÷Þ{öœ!Açk¿í¶ÛZÇ5Ç}Ðvë­·¶”bئ롪èkfΜiFŽiæÌ™#H„€B@”…€eÁ¥ÆB@! „€B@! „@-#°çž{ší¶ÛÎ,¿üòµ,f®²Íš5ËŒ?ÞÌ›7/W¾b&„€õ€j Ô¿5! „€B@! „€Bà¼õÖ[fþüùfÑ¢EÂä,·Ürf¥•V2ßýîw…‰B@²¡,¸ÔX! „€B@! „€¨eÆgî¾ûn³`Á‚Z3WÙ:uêd‹(·mÛ6W¾b&„€õ€õ¯C@! „€B@! „€ø&L0>ú¨ð Ю];ë@XuÕUGõ§B@xT!#µB@! „€B@! êŒämÚ´1K/½tHœ½˜}ô‘yýõ×ÍÂ… ³g&B@!ÐPÈÐPêÔ`„€B@! „€B@47ýúõ3={ö4+®¸bsýÌ™3ÍÈ‘#Íœ9sGõ§B@xä@ˆÇH-„€B@! „€B@:A`Ï=÷4Ûo¿½Y~ùåëDâìÅœ5k–?~¼™7o^öÌÄA!  Õ@h(uj0B@! „€B@! šŒäóçÏ7‹-jn £_n¹åÌJ+­d¾ûÝïŽêO! „€ñÈ‘Z! „€B@! „€u‚ÀرcÍ=÷Üc,XP'g/f§Nlå¶mÛfÏL„€B ¡¡¡Ô©Á! „€B@! „€hn&L˜`y䑿!4úvíÚY¦EB@! ÊA@5ÊAKm…€B@! „€B@šF#y›6mÌÒK/]Óræ)ÜG}d^ýu³páÂ<ÙŠ—B@4r 4€5! „€B@! „€BàkúõëgzöìiV\qEAò?fΜi.ºè"3gÎa"„€B ,”¨,¸ÔX! „€B@! „€¨eöÜsOóé§Ÿš3f˜>øÀS¦ˆðøC³Ì2Ë¢ñ©@‘åf8þÞ{ï™Ù³g›Y³f™ã?Þl°Áµ¬>É&„€5†€5¦‰#„€B@! „€B@T†À¦›njvÞyg3wî\óî»ïš:˜}÷Ý׬¼òÊfêÔ©æöÛoošã”~ðÁ͇~X¨:[! š9šRí´B@! „€B@ÆE`uÖ1ݺu3ÿþ÷¿Íþó³Ûn»™_þò—fµÕV3«¯¾º5¦7Óqv^0^vaˆ„€B@”ƒ€å ¥¶B@! „€B@! „@] °ûî»>aÒñ0"ú_! „@qšÂðå—_Úm‹ä9$ á;ßùNqDjø›¯¾úʼõÖ[6Wãšk®i–_~ù–V¢CÀÇ|üøãÍ«¯¾j~ô£Ùè™o}ë[ÅØ5ÅñÏ>ûÌF}ñŦmÛ¶fÙe—µã&§éÛo¿m£‹ˆ2Za…šbƒ,†S±ö¾Žsïzÿý÷ͼyóÌ*«¬b·ûê[ý! Ò"@ÖUßÿþ÷m4ê·¿ÝËâ²á"o6©?x†’öC8• ¡NB@! „€u@C¿)µ´´X£ÕÓO?mn¼ñF3gÎsÅW˜µ×^».•†Ñøšk®±¹ ûõëgvÚi'óÓŸþT/ru¢M_ó£ø /¼`l¶ÞzksÐA™õÖ[¯)J8c0jL›6ÍÜzë­¶Úˆ#ìuÁ´Àh}à 7˜¿þõ¯fÿý÷7»ì²‹Yc5lá´:™6^ÄŒÃÉ “|òÉ'ö¾Åý—mä={ö4k­µ–ùÞ÷¾Wâ¬ÆüªZNœzC“¢‡ä+f«=Î?笷qHÞÚDàóÏ?·ókâĉ†œÐ]ºt1Gy¤œ›EÔ5yòd3vìX³þúë›^½z™ 7ܰéòE Òa! „€B@!Ð4¬#ÍË/¿lî»ï>ë4 ™D YõJDñ"ÿ¬Y³¬ñ¸wïÞfàÀfã7ÖKo+Õç|ıpáBóßÿþ×üéO2ûÛßÌqÇgºvíÚT%v½ôÒKæÎ;ï´† ðØu×] †GGÎq¼áp2dˆéÑ£‡9ôÐCMÇŽ›æšI‚“Ã+«ßÜ»¸Þxã óûßÿÞLš4ÉqÄf«­¶²Q¿K-µTV¬k¦ßj;qjˆ„‚¼öÚkfذavÇ ¹Š7Ûl3óãÿ8áÙj&¢àù9þ|3sæLsýõ×›ûï¿ß,½ôÒf“M618DѸ€Cïá‡6>ú¨éß¿¿Í#Žs¯^wõFTG…€B@! „€ˆB á.ÍÏO‘»å–[šË.»Ì~ˆ¾?þøãmT %æ8)•HSD!4""ÇŒcž|òI;ß~û™AƒÙI7v ¤a¨^i¥• ×̽÷Þkw+àD Š’tG_N¯¬~“ö¼¹?]}õÕÖxÇý¸oß¾öCTk#§—ª'NVºÍª_î¤M™1c†™2eŠ9äC NóvíÚÙt3YñU¿‹³gÏ6wß}·}¼ù曦}ûö¦OŸ>öƒ1\kLÒf² ö±Ç3gžy¦ùûßÿn<ð@Ó¹sgûŒmGp4::*„€B@! †r `¤!Ò˜T&¼ä`€Ø~ûíÍ€ìËa#×Éyì±ÇÚhóK/½ÔFƒuÖY桇²ŽvYðÜì9ñkáÒÍr>’΃VDÒc7nœ™0a‚5´uÔQfï½÷n8‡‘£ ,0ÿøÇ?ÌM7Ýdn¹å›¾k·Ýv³×ø{ì™æ'˜p/¸òÊ+m*FŽ‚O‹SÖ× PÒHm±Åöþ<~üxëzä‘GlêFL/UKNœ¬õë»Ò²9Ò^³<ð€¹ð íΕÃ?Ül·Ývvç ‘ã"!‡»¨¿‚Áûºë®³pœÊ–°>Ü|óÍ• 2DíÝ»w· 7ß|³}þ²ûï©§ž2ìÂÁ ç^ ˆúZ! „€B@Ô1 á@àåúDã5Ê<ûì³6 ™t%ö³ŸÕ±ŠZ‹ŽÑÃñ%—\bîºë.»Ó‚:D_³­œœøë®»nSæÄoVþGòœ8”ˆä&};ØqsöÙg[#9ަFq(‘þ†¢ÑÔ2=z´"%3QíÔùÉO~RRÑìÚ Êyçg/_)N%Aôð%ª™N;í4³ãŽ;Ú{F½FK/U«N*üÿíÜ]óÇÿVi¨ª+všB(‰#EBŒ UjÏEµ|ª­­-jD©‘X±gP±GìÑAì´¡¨U­æûÔyÝÜ÷Þ¼ëîû}>Ÿ›÷ÍyÏ=ã{ÎùŸsžß3*¶š´’MuüñÇÏpÍ’m…Eä3ÑãSšŠ Iòĉ#°Ñ™’vˆ˜8½¹‡jí'À½–’‰ !˜ày²¸#îQjÌ&Ëíg꜀$  H@¨u- डÄÎsš»ñrHTÙ¦›neK¨‡ÞÈ)Õݺu GÊÀÓYgÕ"&àD¦Áî /›,×ÉØÛX­óA GÛ©§žÚr<ýôÓ!(ñBŸ5Y®GÆYä(eš¸Æ‰DÆ9‘•+‰ёk¼=QðD×›•šS¹÷ŸhVÆgú·ÍÚHå¥j]Ä)÷±-õò)›2bĈCÉ,¼æšk"㊀²hÊMct›,—š|}/~ˆÎ<=:=÷ÜsQÎ’û!âA¯^½ÌÔìä!F Œ"YB<ÒK⡇ŠàîÍ”„²Ér'áú5 H@€$  Ô(ºˆ$#™²$¤§ãD%2‘ZÉ Í`8O_|ñôË_þ2ÚvÚi‘RŽ€5YÆ£•Ÿ@µÏGœ²œÿ8Õÿð‡?DsáÜ&ËD~×›ÑüœÌ J4IJF‘Ç8(:yœÏøñàƒ¶DÁÕ\oVN•`ÐÞòR•Ø–®®£ÞDœ®îo%¿Ï5K&áá‡Â8×,}Ž8âˆ(kDï›,WòˆÔþºÈD=úè£Ó-·ÜM’š(WDæÁZ× ðœÃ}™{4½%x&GLÈš,#¨j€$  H@@ý¨;!k¬ú÷Þ{/ Ôû_f™eÒvÛmN¢¯›Ñà@Ä9Î^ä.½ôÒ(ëD™­<jõ|ÄIBD.Ž6z (!,Ôƒ‘ðá‡Ʀ¾øâ‹é¸ãŽ‹r”íB8 <YG¥0")Y&Ù#ãÆKcÇŽF¿,›cûÉ'ŸÔl“åJr*ë¶–A9ưË.»,JU1ŽgM–jÝêUÄ©u®¹Û7×\s…€Ð§OŸÈ8$s…*4RÏš,Ó(WkNûìøÓ›{î¹#Ûiذa!p®h¥'@é"DT2Ê(K÷üóÏÇO²„5 H@€$  H þ Ô€ðé§Ÿ†³ C“ÃÑxÐAe“ýù%×^{-z%¤<êå|Ä©‚£­ ñ Wä§Íù”Û 0~¾õÖ[iÙe—-÷*;µüjsêÔFwàKS¦LI£FJÏ>ûlâÇÑNýaš(ӘÞ:í½÷Þá§Ÿ@=á±Ç½Øš¨"Rg QeâĉÑh:·A3}T#‡Þ™ÅVí;åâTî":•,Êk1v!³/ðG<¨e6"â”û8—zùœ7œ+œ7æ½{÷N›m¶YŒy8‹µæ&0bĈxÌzAQoÛm·MLïÕ«WˆÓÍM¨ë{O 7² îºë®4zôèèMĘMSs®A®I2b5 H@€$  H þ Ôµ€@j:‘egžyfD­žþùé¾ûî‹ d#d WóSÚëÿ°ý2‡ñý÷ßc¢t3‡ñ>ûì“VXa…˜Q¡2G¼Zçc‰K­xœ%|ˆ¼Üpà ãE~óÍ7ˆî¬6teh”f-”œ2dH”±¹üòËÓ%—\’n¾ùæÈ@D A8eÚ[š‚29ˆ,Œçž{nzä‘Gâû8•pzМõî»ï.ÍÆWp)¥æTîM/–ýÁqØm·ÝÒÀ£„T¹·£”˯W§” ʽ¬ÜL;ê«“i7ÿüó§-·Ü2®ßu×]7®íro‡Ë¯}”ìC„$˜";WÖØwÚi§Èd[d‘Eâ^Yû{S[[È3Çûï¿YccÇŽM7Þxcl Ù°¥gÍ<óÌS[íÖH@€$  H@]"P×B¶ç”9áEçbÆSO=5²~üã‡3j±Å«;‡T¶ù?3‡ñ3Ï<Óâ0¦”cœoDaâÌÖªC ’ç#€¯¼òJœëœû”ó ºÇúî»ïÑôÕ¡PÚµ’€(F¦³Ï>;"O<ñÄpöSÖˆr7ÌCß‚BÆ5S¨L× Êäp Õ»u•S%ö?Ëþ¸á†±G‰‘þýûG¹‹‘#G¶êQ‰m*Å:êMÄ)Å>WrdÖ=ÿüó!Ð8™&­”I!ªœÌ!„M¹èE•£Ž:*îDÉ“ÉvÄGÄOšp¯²Ê*ÑW‹yµ¶ Ðk„`Ä;„~'Xe«­¶JŒßK.¹dÛ q H@€$  H î4Œ—Çá²Ë.›N8ᄈX5jTzüñÇ£œ/5 ¤S×{“å¬tÃí·ßžÎ:묇1˜8Œ›¥lS­_iå>s#qɼ7n\{„ÊÑû¢ÑŒzó8 O:é¤ )]Â5¾ï¾û†ógÐòË/ߪán½—Ééèqì,§Ž®§£ó·'û££Ë¬ÅùëAÄ©EnŶ)k®MÖ×<ä=§gQ"…¬¡•W^¹ØW. 0÷Üs'2ñ8Wè³B­~z­Æy„€Ì9ÕÞL¶fÄJÖM’ÉtE8 l(Ád"âwµ/Q3ruŸ%  H@€$P/F@È€EÌË ië8({‡²$d#ì¸ãŽ­ŒÙwký'Ñæ¼ð’]‘5IF8ÀaLÉ­ö”ã|$š~Ê”)Q3žºñÓ¦M‹ó~|½tuç)_F$òµ×^×:ý÷ß?j\g >ýôÓ¸fN;í´h’LŸŠz.“Ó‘3¼#œ:²ÜÎÌ‹˜ž»Y“dJS!ì6JöG.—Zqr·±ÖÏ2í¨]Ï9Ã}£< YC8„çšk®Zß ·¯†Ðdù ƒŠç%îôÌ¢/âB4»çTáFÏ‘1cÆDÖkn“äaÆuºQá59U€$  H@¨E ' ™TôîÝ»§C=4êÜž~úéñ‚ˆ‘()ÊeÔ£á(¦á+ŽÒÜ&ÉD×iµK Ôç#ÎXÊWq^ã'‰ÒEÍbdx,³Ì2QŠbРAÑd„ Ñ× _¿~©oß¾‚þW]uU\ÿ\3”:©ç29=¾íåÔÑåvt~Æ.mùËqÃé„xPëM’;ºŸùó×’ˆ“¿mµþj¬s¾i—Û$™hgÁš:Cq€ î—”Q£¯ÎÃ?œzôèlž[…©Ž?>]qÅ‘¥Á3GÖ$™{Œ& H@€$  4>†²Ã–5µ%êõºë®K“&Mªëú¬DÆ :4j½ï°Ã-M’³ýõgm(Õù8Ûl³¥å–[.ú]¬¹æšMÝó"·îû»$Ðqƒ JÜ7z÷îÝñ/û’ðx”© ”€$  H@@UÌòÅt«Êš]©$  H Î L˜0!ýèG?J«¯¾zºà‚ ê|oêó=õ Ý H@€$  H@¨- µu<Ü H@¨#S§NMãǨg¢mµêðxT—¿k—€$  H@€$ Æ# €ÐxÇÔ=’€$  H@€$  H@€$  t™À¬]^‚ €$  H@€$  H@€$  H á( 4Ü!u‡$  H@€$  H@€$  H@]' €Ðu†.A€$  H@€$  H@€$ÐpîºC€$  H@€$  H@€$ ®P@è:C—  H@€$  H@€$  H@h8  wHÝ! H@€$  H@€$  H@@× ( t¡K€$  H@€$  H@€$  4„†;¤î$  H@€$  H@€$  H ëºÎÐ%H@€$  H@€$  H@€Ž€BÃRwH€$  H@€$  H@€$Ðu ]gè$  H@€$  H@€$  H@ G@¡á©;$ H@€$  H@€$  H@è:„®3t €$  H@€$  H@€$ †# €Ðp‡Ô’€$  H@€$  H@€$  tÀì]_Dã/á³Ï>K>úhúË_þ’fŸ}öÔ«W¯´æšk6þŽ»‡%'à¹Tr¤é­·ÞJ·ÜrK,¸{÷îiÈ!©[·n¥_Q,Q–MpÝE H ª¾øâ‹ôøã§'žx"¶cÅWLýúõKsÎ9gU·Ë•K@€$  H@(F@¡™œéŸ|òIºñÆÓÅ_ŽÉ‘#G* äðñ×öð\j?«öÌùßÿþ7Mš4)ýú׿N8eVYe•Ô¿„öÀË›G–y@ü¯$ 2øÏþ“î¸ãŽtÆgÄ}kçwN+¬°‚BX»H H@€$  H 4ÚÁÇÚßÿþ÷ôæ›o†còý÷ßoÇ·œE­ x.µfÒÕ)ˆ2o¼ñF,f‘EIŸþyWÙ´ß—eãz³K÷غgõE±ûÃ?l¹oñL‰¨ I@€$  H@¨U í82sÌ1G”-¢4Ê׿þõÔ»wïv|ËY$К€çRk&]²à‚ FÙ"–óï|Çìƒ.•eàÕðWÍ.©áƒã¦5Yf™%-»ì²-÷-ž)-_Ôt§;, H@€$ º"0ËôH¨/êj‹«°±D4Ož<9M™2%Í6Ûl©GiÉ%—¬Â–¸Êz'à¹Tú#HvýIpÊ|ãß±ïk_ûZéWÔK”ecd„Ûn»- :4vpõÕWOW]uUZb‰%s‡Ý+ Ô0»_{íµÈjå¾Å3åâ‹/=¶jx³Ý4 H@€$  H ‰ ( 4ñÁw×%  H ñ дõg?ûYì,™:¿øÅ/'š$  H@€$  H@˜¦¨1ûꫯ¦'Ÿ|2½÷Þ{éŸÿüg¤/°ÀQ–§ %f Ù´iÓÒƒ>ó¯¶Újiî¹çŽÙpÌüíoKÏ<óL¡¯Í0ìj´³žBöïÿ;Mœ81½ôÒKiêÔ©Qwá…ŽÈ4¾3ï¼óúšÓª@Às©´Ð‰ÈäšäÚ¤Ÿ×FFÙ>+­´Râ:-dÔíçš¡Žô¢‹.¥!²ùÈø öû‹/¾˜M*ú“¬…Å[,-³Ì2çùøããú|ùå—c[‰åúìÙ³gZn¹åÒ<óÌSð{•žX.–}ôQzöÙg[ŽÍÌöë›ßüfêÛ·o”|ËŸk‡1ó©§žŠ¬.Ž5Ǚܥ—^:xæÇÿw€Ù%]gè$K€±ìõ×_OÏ=÷\zçw÷"žó¾õ­oESäå—_>ƶÜïd¿s¿{å•WÏ}Œ{ßþö·³?ÅrøÛÛo¿Ý2­Ø/<‹rÏâ^TÈx–|á…"‹öÿøG<ÃòJ %2æšk®B_sš$  H@€$ 4M^ìn¸á†4nܸÇugqL®¸âŠi£6JÛm·]+G=9ÊýêW¿ŠyO9å”xáƒ$JœžG}ô ` ý‡um¼ñÆ­–ÿÁÄö]ýõ å_ÿú×Äô…Z(¨ë¬³NúÁ~ÎBËvZåx.•–õgŸ}˜K.¹$=ôÐC! îqþ#š! ¬·Þzi«­¶ !!í8F/¿üòôÄO¤áÃ‡Ï p¬î¿ÿþtæ™gæ­Õÿqzo±Å­DBœCŒ7ß|sˆ8epq}â¼Ù`ƒ bûr@­VP åd 8"¶e½zõŠñA&×8&Lˆò9<òHŒ«kæE(9rd0`@ðÍý®¿wÀüóÏŸÖ^{í®-ÄoK@A€çÇ{î¹']sÍ5ñ Èøøé§Ÿ¶ˆ” ÛtÓM –¼œ4iR:ï¼óÂì.»ì2ƒ€À=åþéOj“6"À®»îÚJ@àÙ”Ò~×^{mº÷Þ{Cèà9“>^ˆ ô]6lXËúYŸ& H@€$  H =<Åæªóé8è‰PƉóÚÏ«®ºj¼Tñ†sÿw¿û]D?Ÿ}öÙiýõ×O}úôi×^ã$ëׯ_:ꨣZͳç#™ ÌÇ2yÉÌ5^æx=ýôÓÉF$ÙöÛoQÍ™ÀÁ‹Gd RìÈ#Ì]„¿W€çRiaãTƉ‚€G&ÐÁQ›Dò#Ôe”\—ÌC´ÿ¡‡Úî ÚAŽù†ã…1áÄOŒ¨L®c2 r çÑ›DŠb{î¹g1bD”ÙÁɃ8H¤(×&ó°Õ°r³D<Øwß}Ã!–¿”Æ€ó‘É‘_rбöÜsÏM÷Ýw_ŒÃ»í¶[¥8ÑFî¸ãŽp‰]j©¥òWÕ´ÿ/gvI³eê4íI䎗„Bò]wÝÏŒ¤ì·ß~1–‘ÅF ÙpÜn¹å–t饗¶ í]9Î|î3<‹æe“ÈL S•ùÖ]wÝ(—;Û@æ÷L2øvÚi§4dÈ’›cÆŒ áücd?«I@€$  H@(F )„̱†3‘—¨\'!ŽÅ=zD Ô2ÇiØ^#Úç8»ò g3/™8H‰¨Æù–!M$ÑÍ”H"Ýç(µÀ3£9¢ÄN8á„(ý±í¶ÛÆ i6?+GÀs©´¬q\qŽX€ÿûßÿ~ ƒq½Rº‹ÿS šk„(øŽˆn…J41õÕW‡ˆ@=hÚ\o¹F}ë‹/¾8¶o›m¶‰ ®ÇÌØfÑâPÂC™#®ãj8¾ËÍ’l=§÷{È7DPJO! p¬(Ù±õÖ[ÏÐO†ñ‹ˆ\j°9ðÀ#Ûƒ2P%ŒºwïÇœÒdƒÁò€È_]Óþ¿œÙ%Í–©Ó´'‘;^d ˆò<@P ™k|`”âÁ¸ˆèGðH~6V[Áü,#÷^“}ç?ϔܿx–å¾Ä3lf®ÁXKv,÷T2 j3C˜`{Èï¼óθÿ2k€$  H@€ h '?Ž*"·pØó3s\…&rD_1²ÅšXl/DÔŽ5*ÖGoê³³-™Sˆ Rß÷Øcăl>œkˆ82qh¡KʼVyžK¥ežñd©8[¸>3i869×úÓŸFé–BBóuÔ÷î¾ûî(™ƒ#…ëq1÷ú䦼" Qœô )äÐa™E”`b~œ7ժŒ1ŒÌ2¹p¦!Ää7ôÄQuûí·‡S QÖ¹c0ÇqAf“M6‰q“qŽee ë;zŒiþL¸4S§‘ŽªûR¯¸/ñÁ¸—ðɦ‘6hz¹JÆAæË¦™§3†h@fÁŸÿüçÈÆÛa‡"û ÷¾E Ïž”8â¾Äxš+°^æ'˜…m¤ô‚í‹/¾"ng¶ËïH@€$  H@O )"gW[mµhÞITÖ +¬Ö\sÍpòáœÇø¹å–[–äˆFï‚ÓN;-ÒÌiKMo2r %ièDçÒŒ•²J¹ýrçʼn†°3“4­:<—JË,œíˆ”¢A9Bç:×Nf3\¿¥2Dz1@‰1œ,ˆ¹ Ö…#†ì~’eÀ6»>qÐP^ § e‘ªaÕ`I$. ŽmêuÓb•UViµû”8¢Þ6ǹoß¾!ªbI† gl$ã‡Y5ĘV;På åÎ.ÁÉÙ,™:U>”®¾P:ˆLQÆ\žÉ‘É ƒ•1Žë‰]Ãt$IDAT{bi© Q•¬9²¼È$à™$×è‘Bv};1 µ|‡ÌÊ’áÇG“€$  H@€$PŒ@S8ßIó¦qÑVG}t¢n-å‹zN/ÉÁQ—­ü¨Øbàf6Aà /L·Þzk¤³S®çb¾á$£ +ÆwhÈWÌhöJ¤//…¯½öZ±Ùœ^fžK¥œ9Œ‰¤¤†>u™©M¦×%×$×&×j&öuu ÞyçÈæ¡):Îj2(;‘o8m¹æ02¿ùÍoògiù?™,—ïTËSi–ŒI”.¢Ö7-ØÍ6Û¬à DU²LˆžE˜)dde‘e…e,RðÍîMfê:sœ&Ê Á€gJú¾iJ) îUÜ·xÞãwDUD†R÷űcdžÐNÆ[DŠ|C@àƒ1>Sú²˜1Ó†q—Ÿš$  H@€$ bšB@ ü»ßýn4:¾ñÆÓ</{DÎI†ƒŠèâ¦6Ú(^‹kk:QbD¤Ñ,‡¹”ë(dˆ8&ÉXÈ"y Í—;m-•#5w¹þÞ>žKíãÔ‘¹ˆä¤Ö=N",iœŒÐ‡Ã”ÒA8b(·0xðฎó#.;²."ái@ISuœ/4—0`@ÁEà 'Cç ×)ãE[†QÍ’;•b ²§çA7ÜpÃërËOe¬˜—XÆ8„œZ8Þffô¤ :–líÿý@ûÍÔñl@õ 0Ž„BÏ*ž£qðsÿbüGðæ¾µúê«Çó¿óìÐYCȾòÊ+㹕{áöÛoË/´<Älzòð|I¶*÷®™™wtèЈúçÅŒ>^öpR^tÑEQÚ„HÏŸüä'>+H?çœs¢‰*%X(]T¨éj¶`œ}4mf»h¢Lv­>x.•þ8áð b“™DqRn‡èw–Ó‡v1C(¢~4Çšhøzº>ËÉ’†¡ˆ­—\rIôu!–rÅ ”’ô‰à'™^ˆ«ZÇT*»„­jôLŽ‘wn 'À=„à>”¢¤Â7¥Æ= ¸vX:bdo!œ#Ö”Â=ˆ2q}â³Új«E¦¢õĉãþÐQ±’¾?þxd;}Ðsz…™÷J>üq4¢g<-TZŽeð7ž=$Èle_4 H@€$  H@…4¼€À Î(wâð¢|F~ÃT^špúSŠƒˆ1œ1œjO>ùd:ýôÓ£ñ'ëØn»íÚtò# Pº…,²®¸âŠÈZ(´n"ÛÎ8ãŒØ6¢wqÜi•%à¹TzÞœ÷Dj’iЫW¯ˆ®Ìwbà”áo8PqæSã¹#†¸Gß“ .¸ –±ÕV[¥M7Ý´Íë“(~Æ+4¦Œ%É âÁïÿûؾ-¶Ø"JZš¯œÓ*Á’²6£GŽ>D·RR A¦-c|íß¿KójÆÇBb)N/²Á8Vk¯½vúáhɶ<¸åÌ.i¶L<´þWí"ðÊ+¯D?ÆÜuÖY'­ºêª­œïŒo”³C\`\#s«#Æsèõ×_={X™^ˆù÷Çüer¿Bx'ÛëÑG²}dG2þNo„qÊùP£I@€$  H@(D áÃØI'¥ü˜cŽI'tR”¡˜o8è逓’²%í5.DÕžy晉Úí¼Hî·ß~íJU'J™([ÄÖñÅG¹–üuS¯Æ¯^xaºöÚk#!ÿ_~žK¥güÞ{ïE„å±Ç›Fõ¢ó×B9êHåOfBGz€pÌ'ˆ˜GHÄ)Mã䙕€ÈÖÀGƒL«ã8§ŒÛ‘o”@Cd`ÞjX¹Y­zÓM7EIN8÷©ÞcþM6Ù$2 (I…ÓŠ1/×b‰Ô=û쳃#Bã«öñÉ,ËÔáÝÿý#³f4¸&S§£VªLbëå¦l ÷d®MMõH€EôÒ9î¸ãâ¹ó9ßÈå\GôFoÏ='[ßaücœäšA”æo+Ó‹ïÓÄ™}ôí¡ç"÷¾|cÛ®¾úêÈš½ï¾û"ˆ%ÿ/ H@€$  H #ÐðDQ†„´o^’ÆŒ/r¤™9KI#~8è‰Æ"j‹³í5"Ë(BvŽÔ¹¥v;ŸBÆKd®Óõ‘±ðàƒ†#•è\—¼â<åoˆ8*‰$>|x¡E;­Ì<—J˜Ò 4ÔÅ1M­gD¾aÆÅõJÔ:Nk¦SŒFd"´§Yo¶¥”gÀIBf®5²pœðÉ7";©gݯ_¿–?‘DÙ1llj'žMœiœ‰3§ýÝwß.½ôÒpôPßfýZ\†_Êɧ5â B LqNá£Ih!#JžìªLŒeœ¥·Ù1,‡±s½õÖ‹ì/œÉô¢ÁÙÏžÓÇkæYŠBëmÔi•È.i–LF=GܯÊàÙ‘ò“<3Rº’{ÏfLç¾@P ¥0([Ä=®PÆU±-f,$#•1—,8ÆZ~/$`ó\B³y‚Q2#…çXîsŒ©lÛÇüÜsùðœIè¾}ûf_÷§$  H@€$ V^@ ʧá!‡/Q8ãqòÂEZx& PcN+˜í5ÒÒ©«ÎO–CðBÆKŽÇ\Œœq‡~xdG d9š 8P)DdèàÁƒ£A°¬†•“%YPd ¤0Ž!RR­˜1¶î»ï¾-ó!Æì±Ç‘U@&Õ)§œ±Ùn Ê‚p¬{N8ÎðÔþO Ë.¹í¶ÛâåžÆ}#×J™©³ñÆw*S窫® f~9”ÜL„tz›h¨Gˆ£d`qÍ!Œž^ÖR|\—Ü3ËÈÊJæ!´×Èfå>H?’LG¨(d܇/sÄ÷#FDÄmgxöE@à>ˆ€Àö±M°á@ßM€$  H@@1 / °ã¼`á!Ò  ?ò8êqúó²E´åMˆÒÊwâ0ãåŠÌœš¹ðX6NÇö¼|ñâ†-߈XãŽhݬD5Õqžâh¡Ö8„u×]7ÿëþ¿‚<—J ›kgÌa‡™8Mpnà æ'ç?‘‘8#9ÿqæçN® ÑùNK¾OjÚmb^¡ˆw®ím·Ý6®]š¬³]ôD@4dù”‹ ¾?™DÙWËÊÉqçbO{Œq.¿Üc-ÇçÐC —q˜ãŒ³ öpÆ™µþúëGDl{ÆÔölK#ÌSÎìødNÊfÈÔi„óÁ}¨.ƲAÓ3ÈjãÙŒ±ŒLVJ‡1s½2Žq_ º¿wïÞ­6˜çLž7§M›Ù ¹3dãÙ¯-㙄ûP¾¬²Ûn»Å¸}ÿý÷Ç=‹r~ôrâ–g^î]C† ‰ñ8ÿûþ_€$  H@@.Y¦GH5M‘iv•—52¨ÁMY^¦pxñÂ…£¬ F:8/‡8ÒxiÃxÃÙÏrÛ2„ÖGƒ»BÆöQªç$Ë$º ç(õÃ)ÛÂ˪V<—JˆâŸ 1 LÂ'Y@IDATxì¼ÕÙÿO’7õM1&±DM°aAAQE©*Ø@ň ‚ "ö‚Ý€ ˆt¤‰TQ@¤‰DØkŒ-Ñäý'ÿû}’C†afv¶ÜËÞÝßù|–½ìΜò³»sžßyžç;ÿª(NED@D@D@D@D@D@D@D@D@D@D@JˆÀwKh,Šˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ š" " " " " " " " " " " %G@HÉ]R HD@D@D@D@D@D@D@D@D@D@D@ˆæ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ@ÉRr—T¢9 " " " " " " " " " " "Pr$€”Ü%Õ€D@D@D@D@D@D@D@D@D@D@D@$€hˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€” %wI5  š" " " " " " " " " " " %G •òí·ßºGyÄ5oÞÜõëׯä h@" "PÌV¯^í7nìzôèQÌÝTßD@D@D@D@D@D@D@D@D ¨üOšÞüóŸÿt7ntK—.u¿ûÝïÒœ¢cD@D@ DàóÏ?wK–,)PmªFD@D@D@D@D@D@D@D@ʃ@*ò@¡QŠ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€” TÈ¿þõ/‡Èw¾ó÷Ýï¦:¥Tøh" " " " " " " " " " " Õ@j5„‚¢"" " " " " " " " " " " ÅL@H1_õMD@D@D@D@D@D@D@D@D@D@D '©B`Q+'Î:ID@D@D@D@D@D@D@D@D@D@D  ¤@« ¯ŠšÈ‹@*ñƒù?”$/Þ:YD@D@D@D@D@D@D@D@D@D@D  ¤@è‡<@ªàj¨ ‚RŒªDD@D@D@D@D@D@D@D@D@D@D ˜üOÚÎ( zZR:ND@D@þKà믿v«W¯v«V­rþóŸÝ¯ýkרQ#·ß~ûý÷ jö×;ï¼ãÆç¶Ûn;שS'÷½ï}¯ÒFP•mUÚ B3üq÷þûï»–-[º½öÚ+tDiÿ—q/X°À}óÍ7®I“&n÷Ýw/íkt" " " " " " [€­†^ ‹€ˆ€”:?üÐ9Ò=øàƒîóÏ?·áÖ¬YÓí¹çžÕZùè£Ü<àöÞ{oסC‡J@ª²­ªš_|ñ… /¿ü²;à€ÊNùä“Oܼyóì3Á’RU3O툀ˆ€ˆ€ˆ€ˆ€ˆ@ùH-€”XD@D@r'ð÷¿ÿÝ­\¹ÒÝÿýîG?ú‘ëÖ­›«[·®ÛvÛmÝ®»îš{Å1g⩹qãF·téR÷óŸÿܵjÕ*æÈü_þÇ?þá>ûì³M¢Nþ5Æ×P•mÅ÷¢°ïp­¾úê+cÈ<)·òÿ÷îË/¿´ùÃõUÊ"J!:‹õï|ç;î»ßM6¤²ú¬zE@D@D è `àf‡?»ý[´háÎ;ï<÷‹_ü¢Ò¼%0*jë¶ÛnsÍš5«T¤è᫃" " " " " " " "PA •)D "ˆŠˆ€ˆ€ˆ@2¿ýíoî½÷Þ3o ïù‘|F~ïò;è²aÃÛ]Ÿ_m:[D@D@D@D@D@D@D@ª?¹sTÿk¨ˆ€ˆ€!ÿ÷ÿþŸûöÛoÝ÷¿ÿ}·Í6ÛaÕ%(m© 9”ï}ï{¥MD£À+ÏIyO¨ª,(V°t¨ˆ€ˆ@Õ@x'Ñö×_m‰Ãö³Ÿ9ò\¼ûî»–[ã›o¾qµjÕ²„â$+¾ž¿þõ¯VÏOúSËkõÑG¹—^zÉí°Ãnÿý÷<Í„±zíµ×Ü'Ÿ|bÇî½÷Þöµ!€¶>ÿüs÷ç?ÿÙ½ÿþû–ÿƒ:>øà÷æ›oZôuÇwŒÜP€`BÎ×_Ýýñ´~î³Ï>6FúUð2ùðÃ-üÏÔA|{ô“¤è¿úÕ¯¢N7/Úzã7lŒ¿þõ¯Ý{ìájÖ¬™•pãÛ%ï õÁ•¾ÿö·¿l·2^d®Ðþ;ï¼caÀw5l,üT˜O\§üà›ú̵£®U«VÙ<Üi§Ü¾ûî»éý¤ú˜«$¥_·nqýÝï~gçþò—¿L:ÍÞ‹›³Ô÷ÜsÏÙõ…ëà¶ß~ûÍêcî=ÿüóÖ6Ÿ®Á^{í•êZÒ.ó–ÏókJ;»í¶›Û}÷Ý7k'üŸ¿üå/Žynü?ýôS« öûí·Ÿ± Ÿ—ôÎç;€¹¿í¶Ûf}~RÝzOD@D@D@D@D@D <¤@XS´ƒµ<&…F)" Å@ÃçĉÝÂ… ÝùçŸoFØþýû›q?ÆZŒ­ˆ Ý»wwõë×춯gÑ¢EvÜ!‡âæÍ›ç† æ0zwìØq „ß=„Q£F¹9sæ˜(ÐðãÿØ ±Gq„Õ6î#^Lž<Ù9Ò„ ê¼vÏ=÷¸qãÆYÿ[îºë®MFbßir†<ùä“îþûïwo½õ–C°¡±wÝuWwÎ9ç¸ã?Þ}÷»›;o¾ýöÛîú믷s0@SÌN?ýt«FmÚ´±þú¶xþç?ÿi¢íÑî—_~éþþ÷¿›‘£z“&M¬M„L£ùèÑ£ÝO<á>þøc zQÎ=÷\ëw¦:òyácÉ’%ÖÄ*0?0ž#ZÀ¯iÓ¦±Í õêÕËÄ®\‡î˜7â©ëŸfLˆS¦LqãÇ·s™;?ùÉOÊ 'œàŽ>úèØ~ðFxÎxàV߃>h }ATèÒ¥‹;æ˜cŒ9}e^#~Á€ðk´yÊ)§¸N:Ù9Q 3Ïþô§?Ùx™;Œ—¹À}ßøC÷›ßüƵlÙÒ}öÙ&ÞEÕÁçäpgœq†Çõàs€x{®A6eÅŠÖD=úÞªU«lN×±" " " " " " "`R ‰¡„6¼Ø‹úGD@D@ L#/FÙ5kÖ¸gŸ}Ö À¯¾úªCÀ¨S§Žã} ÷>ú¨Ã›£wïÞf´wÃ׃gÞ#ˆ7ß|³Œ1ˆ³;>\0¢ßxã&¶`dƈ!ãþâŋݤI“l‡=m »xà=ѬY3>–-[fIÉk×®½é8<0L "ÉÃ?ìî¾ûn3´c°¦^ŒÏŒãò-·Übž:tØl'<»ë?üpÛ¡O¿ãÎ;ïl}  ïá1bÌ_½zµ»úê«ÍX~ÐA¹#<ÒÆóùóç»#F˜÷¨/ªpo€X3pà@·råJG²÷ãŽ;΄%Æþøã›ƒPT¯^½¨*ò~Äïð¹õÖ[y£FÜÁlB"s¶\;Xzè¡‘mR¬Ó /¼`õáýø!–ù1!.Ä ƒ="âxO ÚÑD¼BEâJpή]»Öæù¬Y³Ì›!‚÷™‡Ì}ƈÈõ4hå›Aüâ5ÆÁ1Ìy<€N;í´È&¹†Ì/ÄæùI'dŸ1<9‚¨¡ ‘ì†nØbþR)ãfNuÔQÖ·;ï¼Ó6¶ o¼[Z*£ *p].˜ˆU5*BvÁÆŒ‡ùµBlÀƒˆþÄêA˜€=aÅ0ôï²Ë.‘c¢®p!lׇy„C¸+Ú‡ ×9uòÉ'›'FR?|½xà¹B]xq|ñ‚Bð \s‘ŒkI´Å<ÃóÏX… ‚ý泀؀÷ s‰kÏ\bîkÏÄȤk ?¼²è7sƒÏ(×#M!w aÇòš7oî.¸àëWðó’¦#" " " " " " ž€OBÏ" " EIã>†T ÜûƒÃ(Þ‡ñÜ@a×TÁ(‹q›|"„—Â8.ˆìÐ'¬ù60^‡ FáFvÞǨŒwC>ãóÌ™3ͳaÅ{“ëDTÁÀM8!< 5”kÁ N® !Â6x\sÍ5–Ð<| ÿÇ¥gÏžÖ¯0Oú '®GcTý™^c> Üwß}Ö OpaŽ`€ç=Â\‘—%©0¦=zä4&*Œ÷ˆ&'žxâfÂm2wHïçsR?xƒy†h‚ˆ,ž/yp.¹äcðÞ£Ä0rz0þpALéÚµ«…ŒƒG°Ðã„-â ÞˆZxfðœTÒŽ),´á‚7^1ˆr5*ÄŸ¨Ã5©À>ÊcÀŸ“tÝü1…xFðÀ³ƒg„÷BÄ›fÞhÏûú3‰1¹Ž ®x1 ( Hdâ’†Mš¾p ¢J\}¼÷^=sŸ$ð$çÏ$Ä„?Ï9>?Bp!Š¥-T'N´ÐWÌK<O¿´uë8H%€€É/xY”ªˆ€ˆ€ˆ@1ÀèL(„ Ĉ¨Â1™r`0G`÷;ù’ Çì¦'¿Þ'™¼ ¢úÃk¾=6 ¤ pÄŽá7/8o˜¸sƒ¯Ó&†zŸ'"ø^uüOyóæ™k†ÀÅuÙc=lN0NÆŒ‘=˜;¥Ðc¥nD1æYØ#¥Ðm²>îïðî:t¨{üñÇQ ïæ5^@|®øÜàéDròL¯¨L™¯ƒÏÍÔ©SÝÚµkm^#œ `¢Í{uùcõ," " " " " " ¹H-€äR¹Îª €4»Æ“Œ¯I‚ýD`À€M2ïë®».2ôPx<ˆ„èÊ¥øöD,’]g*xfäc`‡cDÀAÈGLÉÔ×Ê~Ÿk¾lÙ2×§OۨѩS'KÖ  ñ„î"7 ÂÆ}< *«p]hÏ{œTV;…®&ýû÷wsæÌqõêÕ³äå$DÇû‰ñøðgˆL….xêàqE2w¸#`öë×ÏÍš5ËÕ®]Û^/t›ªOD@D@D@D@D@D ¼¤@|ÜhÅc.¯ ¢ÑŠ€ˆ@u €!œ|äJˆJ„v {3ð* ¤y*³øöøÅPwGeòFx¯<òS*»¯™ê'LÓ<`ɽ/½ôR×¾}ûÈ<*pÎ$~ej+Óû´Áœa.fJ´ž©®ªzì¹çž³Äã$½Çs,XU!©`Õ¬Y3?_#†Ô°aÃLÙ{ï½ÝÎ;ïìŠþ¬¤@½A©lBV½×Á"PB0DÞ{ï½n—]vq]»vÍkd|^‰?þ|÷Î;ï˜Q‰Xÿ;vLT–p<÷ÝwŸO^‰Ÿy]\‰ØqÿñÇ[X'v®GåÿHÛ<Þ(«V­2¯$„Ïm#\äZ|‚wò,ðYÅ“%.Ô$í!”ð~Ü1iúA›|°óž6ãÆHŸþò—¿˜1ùäHñƒvaç>¤g¡û¼–3ó‹Ý»æ«¯¾²ðS°iܸ±Cpˆš[ž.;B^rÊ)–÷Ñ…Ç 'œà^xá÷ØcÙëgžyf¥ˆ/…ƒê(_xÐñ}ŸMALæ78WÏÑlÚÒ±" " " " ÿ&JaÁK‘øñohÕé_vw.Z´Èœ¦iÓ¦[½ûðÖ¯_o»<1v`p!1m.¥uåÒ~¡Îá3†à0|øp A’‚qïÍ7ß´dÊÄUÇGL|Œœ;w¶.§áFòÛqãÆYø“=zH)ÔÅV=YÀA”9Þ ñcáÂ…f<%r>;ÕOŽ<òH tôÑGGÖÇç ‘äÎ;ï´0=:tÈé3‚°ˆ!¤N:nݺunùòåî°Ã‹d„H:iÒ$-3I6Uè;ëã clÔ¨‘»ë®»ÌÈÌ£Nr¡ÜsÏ=–×ôÀŒ«r«½Žgž?x Ä _° Ôsˆœ;•Q`H?¸–o¿ý¶…ܘ.|ÿb0{ñÅÃoUùÿáGμWà%~Ð)óì®æ:¨ˆÀÖ$À.uò70¯ñ¸’(?ýôÓnúô麇Hùă>ØÕªUË-^¼Øä¨ú0O˜0Á¾ËøÜæóÛH¾‘¶mÛº 6¸±cÇšÐn“Ï,s’Pãñ%!ü`PÆàÏ®Ô/¾ø"\ýŸW „kâ{"ê;ñgÊ”)füÎ'¬Xd' ô"":IºùÞCXÄB< 8ÐÕó½ËÊ*xðቂw óƒœÁÂoÛ믿n97ª·vñüéßðì—Þy¿Ðü›kCج0‡ øè£š'R°Oú[D@Šßñ/½ô’m"@¨­_¿~Æ5ŠÝûƒ{­'žxÂ3¦Ú„t,†ù >ˆ€ˆ€ˆ€/T tß/ŠÃ Õâšzn`1ªæÄ_íM;º1¶¯?ÊàÏ1ì %±-ÆÈvíÚEv;M]‘'–ð‹„Y´`Dºøâ‹ÍÐ6–Š[ O€{ò°Ó’ï’…ã9†ð€0ÂîKŒ²§žzjl8§´XøÛsÏ=-\Üí·ßînºé& ¯uÜqÇ™¸Àw*ß]#FŒ0q¡„÷òùmD´hÒ¤‰ 9Œ‘Ïn—.]\Íš5Íû!ƒÝ÷Œ“Ïw›6mÌk$<&<øNEØàû“ºZ·nm`þûŸ~r¡‡Î=÷\7`ÀûžíÞ½»…@"Ô¢'FgBàa g—*"C1–í·ßÞ{ì±&–#òŸwÞy–<›ÐSîñ ”^†Œ/8a¨ãƒýA,X°` ýô Þ\;'Ø"Pa(Ã{ikú‹Ñ^x<1÷IHŽƒ¶fÍ7qâDóXéPáå„GPeòó,0âBû$DÇûèøã÷oëYD@ŠŠ@Æ ÞÒiBbò;Ìou1¼ÇÙpÁfê Ø3KõMD@D@D 8H)ŽëPi½Àð}ú駛ѰX XìR&Ñ/¾Ÿüä'¶Ó: 7ßñ0ÈÄ•´uÅ_Нc …aE?üðØâi®A)òјª¾'K…±vðàÁ–°™¿ùŽ üß$À>ãŒ3R2À ã+† òò\{íµæ}Âw(B ¡¡_0ã]‡P‘OÁ‚žºh¯ ¼ä2è cÄ`ލ‰— Gr œvÚiÖ_dùä&ãß´á ß½„µ:ûì³­]Â]‘sÑ€Ýÿ„ :ꨣÌsáÂ1W^y¥‰4I÷ð!ü†¡\KR[Þ€¸³dÉóÀ@¿qERo¸c8Ç‹ˆ°^©£JR;Áã3‰dèxw0n8…X$jg'-ïÁžyI¾—(‘?Íœå79C(IÆW‰Î?ÿ|óRŠº–̧N:Y]x®`ôâš2Ç©†ˆ|¸æÌ#ïQl“Ïb!ŸÇL…ñ#äñ[Åg,ªÀ€pbô/iŽE«×D@D@D@D@D@D@DÀˆ¶ÚøwÏ~±‹aH¥úÀ@‚Ñ¥˜ sˆÝ¹<ò-…¬+ß¾Óù|^“>«âVLWK}IC€9‹!”ðBñR`žcØGh÷ÃõáA‚¡¹^½z›< ÂÇDýŸï(Ú"|9&È“@?ð¬£Íph¹pœžÝ“ô!SAHA(À`ØøÁN{Bbùqf²©c×]wµ°U-Z´03}Ƙ>—×ȵƈH@{Œ÷Âçø1ÐGB"Ñ^Ü1ËïO×®]cE"__Òs¦¶j×®m†t¿[•1 vÇÍ1ˆ Þ &Üf¦vüñiÆÄ|D<@tc®2wh!ÆÏæ›üÿ}ý<§™³pçZÊŒñÆ®ã)§œbs7êwqÁ‘¯&?ÏaǼó¼øüfŽyµË9ß`ÿ¨‹ùÉg8jüþXƇ¨ÇndßÿžžE@D@D@D@D@D@D T ToPeá«’¿  Œ3ìÖgÇíêÕ«í= mì´LZèûz¨‹z0PðF–+V˜…ÝÐ,mbxá‘T02lܸѭ[·Î¼`ˆCŒ¤˜¾4}¢}Œ>ì2¥` òóŠö /Cè v[S/³šÂqe0ˆøWïcÌóíøã£ž;c“bòbzã7,Ô ¡wàB(ø§-ìv¥6Ù‰ŒA.nyÚz½«:†VÏú=7ÆG?1:ù’ÄÍ“Ís¾|8íÚµ¾ C,×™Áì>N2îeÓG[ý `xeçr¦Q1ÿ1èg,¢êÁÈÌw5l íFœ“êá;ŽùÎw\ð{.éœð{´›MŸùþá·„GÚâÏÉt<×+›z£êKÓ׉ïï¤ïp„q%M;œ›vLþúÇ͸×i#íœe®dú~ôl¨7©POR²ûLõpß’tïlÖi~;i3ÍqÁºõ·ˆ€Twl€ØP‘ÑûxîçkTxS²^à7ί™2‘û|B>²æ`mÇw©_ÓÅm!Ç^”¬YCÑ6ë(Äo(÷&qçsÞ[o½e~+Y'q/Ÿô{Ç8Xr‘ßÖc|÷³fÂ;•> °û>d·Þ(©NT¬(|Ù½†ÑœdžÄd'Þ6aNH²KLr„nð¸¹c0ñìÙU‚õÞŠ„À„:éß¿¿%«#a­@ü±cÆŒ±¤¾„;‰+Üx6Ì=üðÖä”_nDMsÕUWE&Þ¥>ßcËÔ'Žçæš]Á\¦M›¶i7)7Î„Ø  7Ãܼ?ÿüó–Ç„ó¸ñf8!?|‰«‹9ËM?¡=2nÌÙE »p¡Äp¿ë®»¬_2¼ÆB‚ELÉ=€Á*®ÐòrÜyçîÙgŸµ±!Z°aAsÙe—e\ÄÕÍë0 7âó!„+䡰ÖÀ]t‘ýŸâ¸m: åùòaóÜsÏYüyBÅÀ6ÞˆKȘŽ;ZØ¡”]Òa" " " " "P­pÿ»|ùrǺ{cÖB¬!ØÀ÷a»ví,h&1ácêÔ©–3µk: Ö.„7侚ûëp! "kA’Ÿ³†¢?¬ÿü6n‘㊼eÁÂqsæÌqä‰Ba#“ßÀF·îÝ»;ÅÇmB@è`KÅsÎ9ǘ!C†¸¥K—š/uds°?ú[D@D@D@ÂR áõÿì pËŒéįç&c8¡G³Â"7½“'O6¯«¯¾ÚâLJ[òõà5B}O?ý´%Ïåf·qEH8`Ó)þXn, 7W¸ÑíÝ»· )x pƒMè ¼Sžzê©M}"¦9^*áâÛIÓ'ÎÅH¿fÍ»ÆËÃâˆs£Ë ;7߈ „æ póŽßW;¤ØEDܨâ½VHøŠ@@ÒðpÁ8ÿøã»>}ú˜`@rav!ဗ n‰=O_~¢vâÂfýúõî‚ .0Oø’·¯š_|Ñæ¢O’8îWøÿ´‹`†¨'ó‹>znìÔ¢Ý`‰ã<&ÓßÙð!‰nxÇ &æ&qã™käKàús9Xø<òÈ#¶ûŒÏ¢¡Šˆ€ˆ€ˆ€ˆ€”ç0`€ûøãM¨àžñOÇ{Ìõë×ÏÞcÍ€—~TaÃ"¹­ØÜ…bÊ¢E‹Üüùóí¾šMQ¬ƒ¸È9Æk¬)y œÐß›ôÂÞô{РA&ÚàÝLJµ-åÕW_µ~°Îask2Ö'áÂFÀ—_~Ù¼¹ÿ>|¸õ•Mbl‹:'\‡þ/" " " IR ÜÜPpIUÉ7 “&M²° ÜÈ⌡ƒ=±Ø0Ø]Ó·o_»ÄPU0àcðÆ3]1·Þz«yd6…þ ºÌ;×¼+h›0Üpcà&.‰wé+ĘŠ]IaC¶ï_¾}¢M¼¸áÆócâĉvÓŽwƒ/q»‡üûþžÄ5ÇÛ&ªà^~ÿý÷Û?Þ䯂0tÇwX,~¼7?üpc Žgï1ÂØŸxâ‰Á*ìoÚ5j”‰]ÇsŒ‰)ì⻆EÂÿøG{ÿ–[nÙâÜ´/°aÇŸS±Œ\R>TíáÕ ëH¯á°¡"Æì}÷Ýg1õ¯»î:‹ë§><ð|Àc…ù ,p-[¶ô‡löœoŸ¸!F â&Ý‹BðÉVÔñbÑ•+€Q„[‚/9&zöì¹Eœq¸"Àp~ÅWؘƒ"¡ÁðÜAdÀ•œÝVxÙaäµ 4»§ð á:ùϋĮ;»»ðÉ¥ÀÍÇÙçPXåÊ-M²åóàƒÚÂ+è%Ê_ph\±ãÌï0£}O„0ƒ#{niú§cª?æôyçgFÀ*" " " "PlðÆg]wŸÊz„µFœÂºs¼îO>ùd×¾}{ÛÄåÇÉÚ‚Rï¼óŽ…ãåX6aÅ ŽÅ/Ö>„çE4 ®  XÓ±¶a ‰8±×^{mR؜Ńþrk Öcqë B]=Ú}òÉ'Η|œï ÷qxo#Ö°aPÐ,lP‹*„ý‚¬Z·n½i-u¬^l¤@²©TÇ&ÀØM¨Ÿ&Mšl±«™gn21¨s“ˆû2qS¹ ¼3pÆSãpxPøø¨ÿ{Á‚PZšñôú„ ïwîÜÙ±c(N)DŸÂíúÿˆyŒ úKh%\ÃÃãâu< áEN ܾÉ;µ[ ., 8£}¯^½b›G bÀ3ù<‚…zxÍ/6‚ï…ÿö ˜ðëÅøÿ\øø…Yp<Ì]†÷'ųð#n1¹pêÖ­ëú(HL‹€ˆ€ˆ€ˆ€6ŠqO›$€$õ/h6^áÑ‘$$P?!bisÈ â×ÔÁÿÙP”´®à}ÚaB¾\ k%BV!løõd\]¯½öšË’ bŒ!\Ø…È“ëÆ¾p}ú¿ˆ€ˆ€ˆ€x@<‰"{æÆ÷à·ß~Û’áEuc’n’£Î ¿†Ñž›WêŠÊ•<Þ÷‰G~øa¤Rˆ>Û,äßìˆÂÅœ¤åxmú*JÄ¡M¸ >QÈuAžŠ¤‚ €±‘(XÈ]€•†oð¼bÿ;>ä> ‹M,ÎÏI…û&¬S‚aµ QGR»Qï±Nb]HÂuBý¦ñ€á~?Øï`½úÒÐß" " " …$ZQ¬BbÏ\;c>øà T™ù¸YæFûì³OlçènËx9pNu*¸g“P~îܹré´ÓNKÜaB1ï7Þ ¹êÁË„k‰çL8Ya.uÃ9…âãÇ‚¯œ]wÝÕx} †Ä‘Äðýû÷w=ô‰VG}´?MÏÕ”‹{Ä­#F¸Ž;VÓQ¨Û" [›Cò˜!¦b„«S§ÎÖî’Ú¬ °ŠÞxuÄ% §b6T!þÀ{ðz¸^‹+~cuDmNŠ;/ü:!šbX’w$iÓ^ø\ý_D@D@D@ª’ÀwÓ4†˜FJíÌHC,¿cð¶ñ ¸¹‘ŒÊÿ‘_ ÿ=C6¹?áD®‹¸‚°qãFK\‡øew^1¼Î.) $ 01âÊ+¯Ì:Ìøéÿúõë-¡`ÒXà罤‚Çy¾|ÉR*¥P|âx°£Œ|3µjÕrÇwœ…À"9äŠ+âNÑëÕ„ŸBÊ 2Äm·Ývî ƒª&=W7E@Š»4h`³ãÇß"W±õWý(>'^Ðl6‹+ˆ#lXã>œ„áA  ’ŒSk·¸Bl΢ŽL!ãêàu¿&$—›Í’ k%¿¡2é8½'" " " •A •BÃþ†EHþ—ÐVì~æ&6ªp9gÎ%XØon£ŽÏç5vÝ7kÖÌŒ3gÎŒu»ö}b·%¹ªª0ïà•Oá&ÿÖ[oµØºˆ{íµWÆê˜ç,Ž8â˲xñâØså3zôh×µkW÷üóÏov|›6mjc˜>}ºíìÚì€ÿü‡\O<ñDÔ[EùZ.|z÷î½Y.®-BßìٳݤI“Ì?j°ÄC&: §R #5ÖrxEòàÁƒíZvéÒ%£YŠLðÃ`û‡?üÁÝ|óÍnòäɉƊbçÀïÙc=æúöíëž{î¹JënUµSiˆ©˜d¶x¹áíF¢Ør+Ä‘;v¬6l˜ýæ¦?¿E{ï½·yv²‰ƒßXªˆ€ˆ@u"€>^âlY½zuìýÞn„ˆÝm·ÝÌã"8F<1¨vêX·n]ðíM³)‹:¸«Y³¦KŠ4@è㨠^¾2¼µñtç÷Ÿœ’Þ^àß÷ÏÔsÝu×¹K/½4qÃ?^Ï" " " "Ph@ M4E}Üx>ýôÓf(¨,üŸxÖcÆŒ±ÝÑ^xaðí‚ÿÍN{v`|ðÁÖî#<²Eô‰iŒ3¸7wèÐa‹c ý¡,¶Ùf[‚Ä€¹Œe°Dp">m‹-R'Ò¦ýÎ;[Ûƒ ЬØ]Ebõº¥K—náú _Ø›œÅÆ„ ¶X°(@ü¸ûî»sâV;'[>ˆCá$ñx× NÝsÏ=&úE cÖòåË-DÖ.»ìuˆ^«&í°`Áû>!ô†Ër+x¤ñ}ÄwËõ×_ïøn™8q¢} 0WׂHθKœÑ¥c«ªv Ñ×lê🠄0ır+ìzž7ož›5k–ÃÛ/›Âï,¡¹—™?¾[²dI6§ëXØêØôÆ}òÂ… Ý+¯¼²EŸøž$”/åÇsŒ;äC6;A˜œj‡z¨ý³y‹5F° P°åû– aMš4Ù,Œ–?O6àá%òÑGÅnR"‡}á8¾¿96ª ðþo¼[WÔyzMD@D@D@ E µâw`˜VɉßX¨cô¾æšk7¨ø1ôO™2Å]vÙev#Ù¾}ûœsO¤í!7ËÄ™½ä’K,'ÆM7ÝäFe®ÓÜ$s#Ë +»÷I"Þ­[7 ™•¶þ\£_ĵenÜìêÄ@D¡_q;Œ‚í!4‘?âþûï71 ñƒ0^,ÂnÈy/XØI… ¡#yÑŠEÆ\¼JؽJ’n‰ ã Ìç²`wïí·ßn¢ ž#kÖ¬1(»¦Y´T'h¶|Ú´ic×Óóñl‡à€„— Ÿ¾o‚»ä-Z´i¡æÏ×sõ"Àg–Úˆ€,º›7o^­æ{¡hcÜÅc ¡»nݺ&„9Ò¾ƒ ÕF°¾gž|òIãÎg«² ŸWÄ ~'òõÚKêcUµ“Ô‡Êxqáá?~»Ê­ ²aÐ-þ76„~Á‡Ç †=v6«ˆ€ˆ@u!@H+„ÜV­Z¹•+Wšw(B¿ ü¦®]»ÖÝ{ï½æ)‡·Çî*\Ø(tâ‰'Zh*Ö?„å·ŸïUî³ïºë.·aÃÛ†Xµ¶GXf Fasë$6}…×`Çz1†û;Ö3x©ðNá{5\¿~ýìoúæëµôˆ€ˆ€ˆ€TÔIÐYœS¢n’ª¨¯%Ó †ðzõêYÂqBŸîЬÜà²Û›Åž={Úan,+»`Èf7Ä7Þx£CÁ ‡Ac ŒÕìÔçÆ•¿«¢àa@ˆœÛn»ÍÝqÇ–ÄÜÇ»:tèÞá>V C»i1ª\qű}‡3¡½c°‡ñ‘ˆ61Ôó±z ß„1£_÷îÝÝùçŸo‰ƒçó7|1ö²ø`Ç7 ˜3f˜Gý¢Ÿpmݺµ1|~1ÿ?>,Âó™ØÁx9ñý2mÚ4»FÔ o^#| 6{ƒa©˜Ù¨o›@È$ÌÏ©|¿”cá{aa*3§"ö˜ /¸4¡.ÊñzhÌ¥Cà€p‡~¸øý0êžµt®¯F"¥Na€{bÖ «V­²ðRŒ›r¬ÇØ@wÁ¸:uêDâ`Éz†µáFÙ\„ANIÄu6lñ7íœvÚi[x®ûJ9Ÿ]x¯Ó6mŽ–µ*kúá7mF‹µ#›¼¸ÏcÓcaô™ûîÿÙ0vüñÇ›PíÛѳˆ€ˆ€ˆ€TÔHUu¨Úá¦gvïg‚>xàQ€Á.Ü 1En"‰¹Ên!¼’Š?–›Ô† ÆŠ1#=.ØÄog§Â7µŸ1*Ô®];ÒMšJ};iúÄñxw Hp¼¿æõ`Q§NlÞ2N¹ñ†7Õ¾ÄÕEŸX šd*ô#*7}#Î. D+’©ã= =ׇkÅŽ-’uc´*\oÄï_\ÛYÌàaÂ"‚0Yì\íÓ§Ol=QuG½F[7Üpƒ‰4Qïû×⸥}Ÿã²áƒ°.,Ô˜_W_}µÍ¿eË–ÙB‰]ë\˜³ÈcîÖ¨Q£Róá„û¦ÿ–‹nB7Fï¹r-ž§Ìm>÷•)~ÀØ<ýŽÌre¯q—6rnq¯‚ñ ïL~Ÿù¾QÊ"À€5ß=që™´mSk6U±¾cmÈšƒûÖܳi‚°SÁuP¸~îï¹ÏB°`ÍA^îÁ¸ß𡳸‰ò ÖEœCø*<@X§ò¾kƒâ2ý¦äø`MK{Ï1֕䚤ßûï¿¿­‡X… k°=zXŸYǨˆ€ˆ€ˆ€ˆ@¡ ¤@pwe767,ÁžBw¦Üêcz ` Ç8ÅM+ÞI7¶ ÄÍ"7¡I%›c© ƒ ô¼gý Ÿ$ÜàÆ•lÚ¡ŒýçœsŽU·``®qãܶm[ã„øÁ$„X°/quq ĤL…zCT¡;ì°ƒ¹Š³ÀÁC‡¾À†¶XâÆ¬ŽW\;®7!påFŸºøŒ‘ ®Áº’þ¦ 0e¡Åg‚‡Jõ%Àç…¼xóœuÖYÝÕw¤™{N >ûþû#ó:BD -î_¸7"'F8 iÉé8\°‰‰ï°(K]œÃ=5ÞÑlöbýBø_î¸f½¶6±qï@¿¦ã¾ÚßS³I,Sa=Ѹqc.Xû°Náža%,bÐï]wÝÕÖKGyä¦~ÓmÒ÷¤µëêIãõÇ-XOWÿ~ø9_>œ¢RzûDÒM>Lj¬å^ø=åûIED °¸wÁàçcÖ#¦ó»«"" •AA‚G! ÷l’à‘Ϻ€5&"\ }@I[üú4.ŠA\=¬x¨ˆ€ˆ€ˆ€ˆ@eH½*”RY—@õŠ€ˆ@i |áÍXÈò,Ÿ‚7É|` e¿(g‡$aåˆ3·m°øN|=,î½ðF˜ ê!Äa×¢Df~ i°´ÇŽHÚcçcœPK؈7šgá¯8‡Ð$…§` Åp%Œò>#œ÷Úk¯™ cÜ{ï½m¬Q;*©ŸŸOô‘q ‹°†¾M<ä`epà|0Æ ‰R)Œ6³ MAßIÀJø@8°;ŸÝ²QíZCþ2<è;XÙ‰Z£"œá“<ËØq ÎGö$¸ ë·õú#Íx0Æ3¼7Ôï~÷;cw݃(|˜7ô‡¹Æu¢>BœÐ/>äÁ‡c$·ØóÏ?oÇ2æ+×!éóáÛ¦]B§pýðàbþÓaZÃ’TðtäœÛÌIê‚ý~ûí—Š[° Îçº0~8„¹#ìï±ÇÆ€,ð!ˆŠˆ€ˆ€ˆ€ˆ€ˆ€ˆ@ùH-€°Ð¦°¸T´ 0¢âý‘ohŒš½zõ2î­·Þê}ôQ7bÄG²oŒÕˆ€[´háÎ?ÿüXQ‚zz÷îmF}w®_¿Þ 8Ðò`èʯ„@råûï¿ß½õÖ[&b`ƨŒ@@X?|†'ÈyDŒðˆÄö>ýôÓ ![íÛ··ð`A¦Ô¡}Ô¨QnΜ9&¼øÜÉ!D¬p/ùs¿úê+7{öl}Fø@!q©iã-·Übáçüy<Ó?â}Ãã1w ça4§ŸÇw\b( ŽG`zöÙgÝСC-¸ãA. c=Ö’¸†ûÍy…*Ì…%K–¸Ñ£G›pŒùFŒ†ëÕ´iÓÈ&1²Oœ8Ñ-\¸ÐúJøCrQ9Ò®=õ! ¤"Ä”)SÜøñãM˜â:²k˜D±'œp‚…kŒìÈ^ôý!¿לPŠÔ÷àƒÚg‹9ÅÜGT "qÞaÀñÆ 3á‹>#ÚÐæ)§œb9¶¢D>šdîýéOrÇ7Ì!¿3™q·lÙÒ}öÙ›Äpÿ™³<ð€;ãŒ3ì8®üHì {®A6eÅŠÖ>Gä#ZTAð D â—(JzMD@D€¼#Ü©D0`€åž‰~W¯Š€ˆ€ˆ@õ"Za1LI³c°z!¨ÚÞb|ÀøÞµXµ½Pk" "P5ØõÎîtDt<òý Á¸¿é‚ÑÝ@IDATfÍçüƒ ²z1øbè|õÕW-Ùú}÷Ýg‚AÏž=#=+|=x_¼ýöÛî¶Ûns?þ¸íj¯_¿þÞð~øaw÷Ýw›!2\†ísÏ=׌×xÔ,^¼ØMš4ÉD „œ 1™ßê£~ ׌‹þ“cã7…ç°E½cÇŽ5#3ã:ùä“Mô@4ÀË€°Bp¢®3Ï<3öZ–c”0ò# áåÀx¬0Š#!ÈDy°„9dûÚçz ÑWr/‘po „®%ãÅ.á‚ €€·ž0xmÀ¯™víÚ™'ŒϘ1cÇÜ@„@È¢ á=Á| /ˆ"Ô(W|ðfY»v­ q³fÍ2o„ÞgNÀ—1rŸAÿø|àµƒØÆkx¯p žoÄ\*ÌQæ3s夓N2#×‘Ï u "˜1G£®#ãÆ°D®3úvçwš† \6÷A/¾ø¢}ì³C˜Wi ó±ï«Ö­[›‡ cˆSa‹¸G?ÃTD@D@D@D@D@D@Ê›@ºÕg#…ÀÊ¢°Ø',F žUD@D Ô 6Ç P Q@0ÚÖ®]Û„vöc8FDÀ°Ú¸qc3z‹þ‚£ õ&‡ÐFgu–C>‡pòNv²nÃ0bJ“&ML$ÁŒaƒ8mâùAØ(ÂwócxæêÅOa÷;ÿçÁ{Ao ¼fØéO=„<"±3†]êâ™ÿ·iÓÆÂ`-]ºÔŒè~Œ†j|Ý´Åy´íÛ„WÐðM¨­qãÆ™QÑ€]ûA0eœˆöӜȓ‚hU9àŽaÑÃ8õ`¤'ç â s¡¢ÐQë͵¥-„#Ä&æ¿Á\/~ „4úW%" a—’ÆCµp+בkJð£}xÀ…ë‹€‡¸’Ô_/‚ ž+Ô…Bã`Õ©SÇ®lÉù(‡HB´ÅõGCA ÂÃ%ê³A¨,úxÈ\À{†ÏÂs‹ùG®æl¨'®p.è7Ÿ >¯i¿ ø|"ÊÍ;×5oÞÜ‘ѯ$ñ„¹Ïç ñDED@D@D@D@D@D ¼ ¤@XÄRâvÜ•7F^D@D Š;î1Bb°Ì&äMT]Á×ð²¸ð Ͱ|¿1~b´%”„͉*ôpAˆ„tÂU0ã@›ˆÞÓ"x,mbpÆ@ÎŽÿ|bJ#´,®ð  oxQD æüר0ìó>h¼.r-ü¾o¨HvÎn~ êxmDODvþã¹U0ì“ãë.¼ðBwÕUW¹Ù³g[¸ƒ,ªÐ¡" "P´õ„¸{ï½÷ºóÏ?ß ²>^~Ñvº;†ÈÁlFà_|±[úoÕ>‘8»þ3Lÿ{Ö–! €ð»õÎ;ïlÚ °å‘ÿÎ…Àn¿a ê˜4¯ùü%lÀS!©àIßò)Œq§v2c3»ÿ“’“c†CÒ1ùô%ßsIÐM®rnœ|òÉ‘âmxÏVžó½^q}΄Ø{ùꫯì~ .+rã 8„ÅÆäÇß…*„¼:å”S,ïí–ã„N°Dè=ö˜[°`yÔ$µ·aÃKx¿Ï>û¸í·ß>éP½'" " " " " "PR ÞØAH‡\ F¦7Ýt“ëÒ¥‹í0ä5vi¶k×.×južˆ€r ‚‡ÈO>ù¤}çuïÞ=•ñ®¨R Îx„$èË—//H­äõxúé§#ëâw#ýÂ… Í ‡ä¹~óˆ½nݺÄþã=çOïÞ½s…dê ÞÄžþøã- ¢JTaœ/¼ð‚;ûì³ÝÈ‘#E Žew}TÁPO2p¼tȽ°jÕª¨ÃLh9í–¨†ïÈsxÏïùǨB-Á.ù HQmðsñ¹ƒ÷!·¢ ÷W$U%FõÁ¿æsæà½¿8¯_ÚH¼ë¸§Œ*ˆZ\_ø ÍWþ†ëÖ.ô÷ ƒrˆ–sæÌ1^xSÁü |>ù|!2tèÐÁ>[QbY¡ÇA:¼@ð®#!:žuá‚È÷ÔSO™Øwøá‡[èºð1ú¿ˆ€ˆ€ˆ€ˆ€ˆ€ˆ@ù¨´$è-0ÐàíÑ…Ýìþ½òÊ+m»Mƒ!ʽF,"PêØ‘¿Í6Û¸Ã;ÌŒÐÄÔ7nœ›7oží¢ÇÀ{ÖYg¹æÍ››Á±”y`XÅLÿÉ“'ÛŽnØ‹ßAckÒÎrB a€½ï¾ûLA á7C?ùV`~Ùe—ÙïN°\þFÀ`~ÅW˜`è°lÙ2Kp'!—0`³{þâ‹/6ïFþΧP/_¯“KæÚk¯µDÐx,¼ÿþû6VŒÕô«fÍš‘ÍÁñ$Ä!úI~ŒŸýìg®uëÖîÄO´óׄ`wà 7¸Aƒ™á›b\#ÞC<Àhè¡‡Úæ…|žÈŽV¼ˆ‘9à êl ð0âÎ ¿Ž¡œÏÞ„KZ¹r¥žŒ9…w‚ï#T¦ÉwÞˆf pÓ§O·Ð[ˆjŒOŒú={ö4a°g[³0ß<ð@Ëц7â¢-Â9iø|qíñÐâX¼xù¼Áµ2ÃMÁ‘¹×ªU+›Ÿ\;r|ÀΗ5kÖ¸+VØqÌyú§"" " " " " " ß«ˆSß'vå²##É)ÙMW0Vp»aWøØ=zÞyç™‘Š¸æ,ž+s¡×7½." [ƒÆ; ž„ú#Q ´ìVÆ+Ž|Ûm·ûío¹‹ŸDØc*B:!cô¯ŽÁ‡M"„ x Çà±€!žp7ˆ0 ¿kCw¯^½\íÚµ+ç" w…œRxROÜo Çÿò—¿t 6´:‚mDý€ø@(/êEÀPσk‡Á•oô{ÆÕ¸B€<ãŒ3L|#4ó‘g8„Líøþð7 ¬˜¯ô £=Ç#àåsÒI'™`sDB¸à%Ë –p‚Ü‚Ç1~Ú:âˆ#¹3¢ u!€Ñs‹y,üŸsé/¢"÷uÔ˵@”;í´ÓìoÆëàü ÖC;\ú’)Ì)Çò Úá³.ô…±1g©‡ç„0ƒ¸Ìf¼¾è×^ED@D@âpoÍ=v¸t¨¸·ªQqÏ].EÊåJkœ" "PÞ¾S±°ýW&,x‰µNÜ磎:*òv>òÈ#¶s”p„•`§% =,ØY䪈€ˆ@¹à+—P-$›F §ß±ä{`w3Æ»ð¢kÉ’%f¼Åhލ\] cÇ@‰×±ú QAØŒô\1¨‡³ìØÇ‹¡ïBŽã·ç³Ï>3c=FYŒ»““ hÄŒÓ™Ž ÖÃèçú¾b˜Åxë½%‚LJÿÎ¥]<*i‹¼lHàwq‚öxNS˜gœO}°EU¸0F˜2FŽçºøö ¢Š÷Ü€ ׌ú£ ÇQ7ýáZÁ.Xxv)2p Þ7¤m‡1‹yA´Ãuf¼Ì ^Fô…þ†çYÚv2ÇúÏ?þXÏ•61ôÃB_˜ü?ìA”¶?ˆ[ÌÆw­<¸rŒçñŸnnz¢.„?ç`Çõð¬|=\'ú¼NT‚xæùú1nª<ôãæXæÇÆ z´éç0ý`žñ÷¦£F²°fˆŸ|6TD@D@þMïB¼8­½p,6Îî­¹Çîµ¹ç.—Âq(—«­qŠ€ˆ@ùH‹E)%¼Àå5Œ ìb&\aA6nÜh!ºvíêˆÃÌ˸Å,竈€ˆ@¹à;C¢ß}Ïw$Æ;Bº˜¯ÓO?Ýò1`l,¥ÂØÙiÏøXˆ#„ ‚xc%;¶³3ç`Ä3öÆñCø i>û´>Ž|$ˆÉ|§âý•Ïç$ªozMD@ª3Öðä^>|¸…ó$*98UD@D@D@D œä%€°#‘ݼćÆx·aÃ3\«ÏÂdc@)'ð«ˆ@yÀÇN¼Æ»®ˆcO%âé/]ºÔ‘(œ| *\ðKmã& á”HHá’°D*" "-¼|-Zdž4„„CäCÀSø77ß|ÓBT“Ÿ“ðÔ„dCr€T>wµ " " "P|R ¾ëè>üðCK`‹aÎ<@Ö¯_oÿšžE@D@r'À÷-¹2x”b z¦á³&OžlÆOò& ᣼¯¿F/"M€{GÂŒ>óÌ3¶Ù„x€°‘DED@D@r%0dÈ÷î»ïºK/½4§œš¹¶«óD _©­G¸ÍRص۴iSKþ:~üx7mÚ4÷·¿ýÍâ/·mÛÖB(¤I¾—Eç‹€”#o¿ýÖ½ôÒK– „g¾Kk×®íêÔ©c^wåÈ$ù¤yài˽Ó.»ìbb$°bÅ ÷ÁX䙆 *¤~1^¤ÿôéá‡v«W¯v:u’RÄ×I]Û’@jć)a×±êIØKâÞæÍ›»áÇ;«-\¸Ð}óÍ7®sçÎŽ/-ÌðôÀ£n„ núôé¶£‚¼ $õmݺµýŸ°ƒ*" " " " "D€Ä焾ڰaƒy̲YQH1½'"°µ Lš4ÉBê³ñzìØ±@¶öIhŸ|П~úé¦4 ‡ê-(*©p¯ =BÂÉvØÁ÷’ÿ!dêÔ©Ž¸õ-Z´pçž{®Ûm·Ý§êÿ" " ÿ!ðÙgŸ¹Ù³g;<êøîä¦ïÄOtíÛ·wûí·ŸûÍo~ã¾øâ ñD$>_°`›7ož­ÑY³/_¾Üýö·¿µMŒ‰'ëMØJðþxë­·¡õmUD@D ÐR x°C™xíáXË$£%D 1E=ôP‹Í>qâD7tèPó i×®;ãŒ3,ñZ¡;¯úD@D ºàÆîÙgŸu#GŽtO=õ”C9øàƒÍ•´Aƒ¶Pýþ÷¿_]‡§~‹€ˆ€ˆ€ˆ€T1^xÁ¼?0"î¿ÿþî£>²Í4¿ÿýïÝ~ðƒ*îštŽ>úh·í¶ÛÚfÀwÜ1ÝI:JD@² J¡> $\x/«Ã?ܶ…/¯1cƘ ‰ÑÙ…B|¸fÍš)ñZžþ/"PVX¾ñÆö9gÎ oEX‚‹.ºÈB Ö¨QÃr-• VD@D@D@D /l¦!ñ9¡©ÉÙ‰'ñ”)Sl£"›UD@D ˆ\@ˆüB" ^»ãvÛmWˆ*U‡ˆ€lF  ˆ¯‘/? y|aí³Ï>‹°XùÖ­[ç{ì1×¥KÛâÏѳˆ€” \{Yˆ>ôÐCîµ×^s„%èØ±£;õÔSÝÞ{ïmBr¹°Ð8E@D@D@D@ G€Ä笻Ù=}ÜqÇYnNrÌrÈ!J€^8̪IÊšB+aï‰d€íü¿;ï¼sÞL~õ«_å]‡*$©B`QÂ!°¢*ÿáhÆ<¾ëÖ­ëfÍše»If´råJצMסCÅ!‚§×D@JŽÀ—_~é.\h߃|~õÕW®I“&îœsÎqõêÕ³ïÂBíž)9xˆ€ˆ€ˆ€ˆ@"bç“øœè ¬³‰ÈÀÚûÃ?´°ªäQ4þñ¸µk×Ú÷ ëV"ì»ï¾î¯ý«»óÎ;ÍÓŒcN>ùäMÕá ²qãF^7½óÇÏ~ö3‡àÁf@_¾þúkK¬M¨¾_ÿú×›½Ç1þýýèG¶is?ÿüs÷ꫯº?þñö=Ç&lêMc³ôíF=û¶~üã[[¬Ó _½zõj÷æ›oZ8A<ìöØc‡íÓÐðÁó®N:©ÓpΟþô'‹ññÇ»vÚÉíµ×^©ll´¤à0¢lذÁrŒ"Zm¿ýö®~ýú[l¸$LâsÏ=g¿Cz~/²aȸá²fÍ36v(x}=£¸çO>ùÄÆÍoi7ù¤ƒ|£ÎÅι¿øÅ/Ü/ùKKÛðÍ7ߘ@Çuc̙ꈪW¯•&ÿ~ãd_R¬¨S ‹Å1íùÂlÔ¨‘%ù1c†}A-Y²Ä}öÙ&†øhT=zMD@ª+Qr#0jÔ(÷ÄOXf~ÌÙ)sÔQGÙ®ý W׫«~‹€ˆ€ˆ€ˆÀÖ'€ÑŒÓsçÎ5ãÞŒ‚£ÈÿñÓŸþtëwT=(zùGmdÖ²?ùÉO,1¹_³bìîÖ­›mtÆÀïÃU}ñÅîúë¯w/½ôRÆ1¶lÙÒuíÚÕ íþàU«V¹þýû›ÐrÁlöÇø÷:è wÖYg™·ÛÌ™3M0@˜á»n›m¶1ã)§œ²…¡ß·“æÙ·EŽc6,"0“·“Œˆ.ˆ-Dqà}`¸'òâÅ‹MÈÁ~JŸ¨£gÏž& $mxDøžÿí·ßÚùØT –ÉÓvôïî»ï6ñ”?ü°{ï½÷בëW«V-wË-·¸š5kZ®•qãÆ¹I“&CDŽÙa‡¬¿´™ÆNËõ¾ãŽ;Ü믿n9M#}FH¹îºëì÷'*‚¿„Ÿ»ˆi7Ýt“ \×ÓN;Í!Xpý_|ñEw÷îÝMXÞž3ŒFŒ›|ÔÌß>}ú8~ñ¼!ÒFÔ9ž™žË@*,Ù„ÀŠÂˆb‡Ñ/ >ˆóçÏwÆ ³øLT£Ø©ˆ€ˆ@u'ÀˆÞ½{›;)7$u;ãŒ3ì»›¤¨›–ê>fõ_D@D@D@D j Ú„<›$>?öØcÞlÄy÷ÝwÍIœ~¨nÞ~ûm3®2·1®³‘¬qãÆf ¯ì±°ù—]éäºxÿý÷]ƒ ÜÅ_kÀ.d¶VÛx’yaC{Û¶mM@ÀŽ¡šðR éx9àY†ÑÚ¼‰E=QC>ïaàoÖ¬ÙfçF÷©ÃðBa>ò‰ù`„·Åµ×^ë0îc¼§Þ˵àE@äÆFH&Ä Â.ýüç?7O¼(k|Ú&ïáuÁßW^y¥Í#ŒûQßÅûGŒážzê)mð*Aü ê`îá‚ÃùxǰÁ<ª`³EˆázñyAØvÛmÍ– ÷K.¹Ä—Áoùòåq†x°`Ÿ@˜Â[äÑGµñ&y"60Æ«¯¾Ú~k Ï 'œàn¿ývBî»ï>9x/\° O˜0ÁN Û s vŒƒþ’¿Š>Òï1çâì(|nÏFH/l(ƒ|xù‚BæK •UED@J.¤,HÙyÀ®n\øþþ÷¿_ ÃÓD@D@D@D@Š€À²eË,÷› }EÄ aOxqÄ‘F·"躺 ‰0,³“yÌîqBù¼‰'àM<¨0J³#ƒîºuë̘Œ¡8ƒzš®m­¶ñÀà¡™B|§xc3"kÙvíÚY^K¸ð}@¸Fx‹DÄ,¢"`Ø>ÿüóÍàäYU‡ 7¢y…?|ñ"Ä4€¬=ìŽÍs-x8 \têÔÉBXù0Ló?¢Éà<ð@×¥KóŒ ܉~Ch'Djò£ h„=ÈŠß=÷Üs“·íñŽèG¢u"¶DyT`ƒà:"Ä B &ø‚g Œ qƒÐRˆ\\CÏ¿Ai¹Ÿ$€ ® ÂÙ_OBWá™sÅW˜ÈBŸ;vìhžþúD(±{î¹ÇæD¯^½Ì6ìùò>cÄëƒs9o¦aOŽ*K—.µ<&xœ0臊„ |7üBÜÿóõ ÖËŒ0I¾¼øqÃÅNED@J7.ƒ¶›/n"¸ñ’øQ WVcâ @ˆUŸú„Îx€`\cc!F0Œa-Yw«ˆ@u#@Bë`‡Â£ã<̪¢Ð.k ÀþOÔBAUvÙZmó}BÂaà÷FñàxñªÀ¨ÎwNZ0Ä#¡€ììÇ»!ׂ ñ!(Ðøº§@ÈA&¼àð ȵ tèÐÁ„· qžújTä9Æàqá…šØ?8Q‘†ïexEyÇ`Ø'T#èw”°A[„C4ÀS$nó8ŸÄ<ƒâ}Ág Ï´Ež” øÁ1®?ÇІ·ÿû-ÿÅSï °áâu®ž9¤= A{° X ²´hÑ¢d„ùr,׳}ûö6_o†çM\!‘;b œ$~ÄQÒë[EñØù ì´ÓN/Ž›3(ÞÓ˜šÜø¨ˆ€ˆ€ˆ€ˆ€ˆ@¡`H#L †%b¦chòɈÙ1‚áM8QÆ©BõCõˆ@e ZHP¼Ã çaPè>ì»ï¾f,öFYŒÉ„?ªŠuÝÖj£1ãÅPO¥¨‚˜Á{xx6QÇ_#â ù20LcxÇ; ŸÂ÷†û(¡€zùÎÃÐX†ˆ%:¤mŸüIØ+£62"vðÝÊœÄK#nnøãàc`w !­h+ìâûÉXùž‡;9TâÄ'D+Ò D…›¢.úÂ1Yq"âíEõ×÷Ç?3î¸>3?ø #bÛÅ‹‰þ\^CÁK1Iãz†¼+$»+0<þøã·~âŽ×ëåI ÊC`•'fZD@D@D@D@D@D@ò'°jÕ*7kÖ, ©Ò²eK‹•î ‚äÿàш‡ŠTG„8Âxç¹dù¢r(TÆØíC"hvÃc¸Åk°Páþ¥Ô6 0æãiCÞ¾;üwŠ'»öñVÀhf—ýš5k,OÜ# ïäëÌö9Ê3%X¢Þ!Þ —…'\œ‘>x^ÔßñãÚó¯Ã(Ì)XÇùcƒ¯ó7 bb a»‚‚_øØ>øÀ<‘¸6aoŠà±Œ?®=ÿz” ãëH‹?Æ?ûúüÿÃÏx®ÀO¼¸‚#>ßxÀ¬X±"‘!×ñãÃ?Œõ™“ˆ ™úìƒþ.?©”JÜŸ˜LÙ| ʧF," " "/î;¸É%¶9»š7ožo•:_D@D@J‚¡Iˆ)O(’óbÆi÷ïU•Á¸$ÀjEE€ä_@àûž]ÿi½òv/0’ˆ{RvøW…qukµGÀYgåúõëgÉÐ-ð&ÀXŽ-ÄçC† 1¯B<Ç%âöì ×Dlò§öžˆUQð2AôøôÓOM$®Š6si1qAA$®p ð€©ªÏA\_Ò¾ÎAAÀ{á¥È¸Yïz-©Pâ‚ ¨3\øŒF½>Nÿ/o©yw­ªøÒ/ïK¢Ñ‹€ˆ€ˆ@yà^ƒN³gÏvS§Nu6l°„} 4KsyN ZD@D DÀ'>Ç(„øQÌ DÕ0ü‹Ð*"P] `Ôä±5 tB)m²5ÚÆxL^¾_¯G¨%Â9#ý’K.‰ÌwäÄq$ÿ&DßQˆXU¾Œ~ൃ¡ᬘÅ®3Ìù¿ì²ËÌ»!È1êoÂE–«:ÄæÞBáôˆaØ–ÉY²Ï>û¤/‡w=e§®3bë÷QÈֿꈀˆ€”5nŽY\ÎcÚ´i–h’cµk×¶äxI±aËœ/" "PVˆÏ&7ß|ÓvkûÄçâÉ£1Zb,Òï§'£g$Ü‹/\¸ÐrR Z °"¤’”(íÚµs$ 'E\Ž _?¡²&Nœhhx•N«* Ô„éB!ÏpU„-óãÎöÙ‡êúûßÿnß×xÜ”RaSž\ÿ°pˆÃkx/’÷1HE*›@j•Vî*»ƒª_D@D@D 4 xác1`_}õUGhW„= a"á;’bÕ–&JD@D@6'€w;³çÍ›g¡iN8á„-ÂÐV„¿ *" "†÷àÇwõë×·|„ #×B÷ሠxq„ ÙẠãD¨,Œß7ß|³«S§N•ÞÇùå—&Ó/Dœª »ææÿôA›„àI…pQˆHÕ)ÌÓK/½dó‡Prᵜ÷æ`ìä×I@ˆ’ÞOâ¦÷D H µ‚‘‚R•Êm°£ú[D@D@D 4pOA¼ðÁΧË/¿|“ðQ•îò¥AV£(U«W¯v<òˆ”‰Ïý˜}þ~O•ÿÃSѳˆ@&+W®t¯¿þº%|Ç0Ol "í°aà gŸ}¶¶ƒù‰²­/êx«¿÷Þ{æU%Ð6!tùDÄ)fû%zxÕ^lÉ’%®fÍš±!ß-Zäf̘á7nl¹¤¶vAÇ“ƒü8á‚x6sæLû½bŒaoDò;"”Mž<ÙB¯®,ªF«[·n–äŠ+®HLu¾^ TˆÄ 2ý-" " " î'>þøãM¡®>uU«V-×»wo»©'Þr&×ú\ÚÖ9" " "P] ð[IâsŒ{Mš4±¸úÄU~c Åãá_TD@D véc„ž0a‚ûì³ÏÜ~ûígß!!(Ââ=‚Ñ›N:t0#=bET¡®\ÃSÑOÂlÝ~ûí&ôqÄÖ7Ö´¿`ÁKÒŽÁ<Ø¿¨~Ãkˆ8;vtwß}·»öÚk]÷îÝMäæûä•W^q\“ùó细 :Æö¦Øã „U£F\ß¾}Ísa~=ö°ß r:Ž9Ò ¼7Èuªè/sŠèk×®u÷Üs…@†áH»€èøÁ{>gžy¦…aÛcU›¥C µâÕ¶ðÄ-‰ˆ€ˆ€ˆ@! pï€A†ÜIJ8aW> IZu‰€ˆ€”*¹°ö7Þ0#P8ñ¹÷»ï¾k±ï1R"€(w§'£gLØÑO¸!ŸsŸÎæ$„ þϽ<¢ëòåËížOB!Æb#|úé§Í˜ÍñC‡5O’¸6÷Úk/wà 7عqÇĽNh¿6mÚX’urŒx¡à‹/¾°ÐX-Z´p]t‘Û}÷Ý·0ºÇÕ¹5_'· æk `"ÈÀb7×>ò©ú ¯D†b°ÉÖ¨QÃ87΄'ž ]Læ ^Cˆ:ˆeáüž7áó-·ÜâFe¿sü~q<¡’ñè " ‚–ò€xrzΕ@jD ¹"Öy" " "P^¼ðÁáƒÝKûëÙóÿ³÷PWçþÿü“˜˜\½öhbV–¨X@±+bWl¨I4,‰ ¢ ö{È cW$ŠHÑØ@,+bÁ`oïJ{b”xcÊŸÏø›÷›½ÏÙeö>åý>k÷œ÷œ½ç™ùNÙ3O=ÑÆÆÂg¹å–ë\À¨µB@! 2 @L},šï»ï>’f¯½öJ +ƒp’ ›=ôKt©%#À:ƒ ƒ%,í¶“Û%*IÐIBMN^(Z±îgMÂdÀ€VØÍÿ„N°ðzÕÅ# šç¥÷ç;ß©y>@QCˆ-<'fÍšeÈ]òî»ïš 6ØÀzGà%ò£ˆ°ÜÕ¥VX^Â…y䑿ÓO?µX%µÙ…#Äs#©N„C©³úê«›Ù³g[ƒ1”xI h"4Ö¦›njðºH*£oß¾6ÔЉ$¢œsÎ9Ç–•¤”@b‹ü)Iù[Ž:ê(Û(¿è3Ê¥yÅógï½÷¶ ´ 7Ü0± êHèËaÆپ伈×ã¶î³Ï>¦gÏžV!—T—=z˜3Î8ÃðŽÂN$j! H-tô›B@!ZŠ6ȸGKñ‘N](„€þ"”Dðˆe3°$Ï,…IŒ Œg­H!Ï„©Åë`Çw4ägHò2à7B0‘¸û¹çž³¡Š°ö'é8 ò?Ô#”Ñ$Þ¼âî()!¶+Á9¼PtGO ê„ayJ’ÖHw½÷4uA9 CñZ¡¶ð€ õJR^PÊ@ØW^(VÀ‰û–_~ùºa¯ÈÃ×NW¿­($PZ€o’„1@{x'…ÚB1A?¡pàYƒ²„v¶ŠrQV ÔIÓ\CP¸áÝHœ'Á%™óðñÛáÆ#¦ßÂkÔ¥¾þ=úÜyH­é¼©åB@! „@=\¨«‰'š^xÁ°ë,¦°’ÇG=õ»B@/@„•5ù?°ÈÆû#IІ°Œp!¼cÁ‹K$„€Hƒ{ö¿üå/V©P/Ñ9n„Í®r;¡3Âò$yš:PŽ++Íõ(h´'y¤)#éš4u¡ýQ/–¸òP6ÔSè¸ûP:PfšrÝ=î½–âÃ]“¦Pl p©EÑüR(+ÈéÂ+/9œ²–o^"!T 4ph6™ä¼DB@! „€„º"Y"ŠbÿbFœZ,‘Ã!ŇƊB@l<öØcÖûëê=÷ÜÓ–%‰ðþ –¸X/'Y÷&ݯè¼`EÒ”5‡{ûí·_¬¹ ž×^{­µÔÇ꿞°¼ó¢ª– !Ðl¤R€Pi;(ÉÎþ¨?B@! „@§@ÅÇäɓ͸qã:x|wÜq:uŠ¡ F ! „@`ðæ ôÂFbò楖u4¹?xat ü;CÅ 6G¯±“O>Ù :Ô\vÙeÖ°‰Ü |e>y@ðyùå—ížo m‹ÇˆH!Ð ¤V€´BcTG! „€B \œâƒäæ$»ÃãÅÇ1Çcz÷îmC]IñQn¨t! „€h_þùϦN|îPp ÐIF+ˆCEïB@¤A€°G(3W‹ÈÌ™3mRêÏ>ûÌ,X°À*_Q„‚o=ö°¹*Pàá]•´Ë‡áÂo¥i—®B@ø¤V€ÌˆE‡—H! „€è\ ø ¹S|ð?á8l“Öqh’â£s µV! Â#àŸ#|ìÓ§OÍÄçpçœN¬÷Þ{Ï&’ýÎw¾¾R*Q¶FO’dwéÒÅì¾ûî6Ÿž(d‘VÏ%äf¿_µ\p‹-¶0#GŽ´9?VYe•¶î 5NrH­Q¬r:@¥ ! „€hfððpŠ9sæXb}ôÑÖZŒXãR|4sªnB@!Ð*|òÉ'‰Ï·Ýv[›û£^rÛùóçÛü$Æû#mÂÝVÁDõB :ò&á.»†œ5tÞ(e•/ÚT )?Ú{¨uB@! ¢ëÅ9>|ÅÇ Aƒl¨+)>¢ˆé! „€Å üÌÝwßm}{íµWÍÄ玹?Èò½ï}Ï*@ª Iãøë]! „€ÍŽ@*ø÷¿ÿmÛò•¯|¥ÙÛ¤ú ! „€9@ñ1eÊ”ÅÇûï¿oºvíjhC]Iñ‘XÝ&„€B äñp‰Ï>ø`³Ë.»˜o|ã5îøò'—g5á(EB@! „€‹"Z"/EÓB@! Ú ÷ß¿¹í¶Û¬Ç‡S|uÔQR|´SG«-B@!Ðtgÿ¡‡2“'O6Ý»w·¡¯ÒæòøóŸÿls€l·Ýv6HÓ5NB@! „@ƒH­‘Hƒ{Jì…€B@”€ÀÇÜáñAâU’›¯±ÆæÈ#ìP|¬°Â %pV‘B@! „j’ÐW$>'ñV[meÒD^àNø+ÎêòÐÔXB@! „@<© ò‰Pß ! „€hEœâcüøñæ¹çž³Š.]º,¢ø Ù b‰·bïªÎB@!Ð*¸Äç?ü°Ùf›m ¹?ê%>wmûÓŸþd…· пöµÔÇ{W„Þ…€B@!Ðö¤Þ!IÒöcA B@N€À_þò—ŽPWx|êjµÕV3 °ñÆ©`0¨‰B@!Ðpüq›ûc¹å–³ÊuÖY'uP~;„èÊÿ‘6](„€B@t2R)@P~ðB"H'!j®B@´(>xà3vìXã+>?üðÅ¡®ôœo‹îV#„€B p‰Ï_zé%“%ñ¹k ¼@vÛm7)@(zB@! „@T îQrúW! „@ €âãÁ´Šê /þýû[ Ÿ¥øhŽT…€B ­ø×¿þe¦NjŸwëÖÍì±Çæ»ßýnê6þïÿþ¯!úG}dï[yå•Sß« …€B@!ЙH¥ÁûãóÏ?7ï¾û®–|õ«_íL©­B mXi¥•̈#̪«®ºH›Hz|ÜqÇ™·ß~{‘ïC^ôÑG›÷Þ{o‘ò×]w]sþùç›èí•W^1çž{nÓ_¿HcJüç¯ý«-áõöÛo_"§Ö-z©¥–2Œ×¹sçÚF|ë[ß2½{÷6'tÒ"Z°`U >|‘ïÛñzÆÍ”)S̘1cÌ /¼`ç÷ßÿþwëáAØ+­n¼ñÆ‹x|t&|íÜÞW\цEYd ë! „€X~ýú^ —øüÓO?µuH›øÜÕ•};$¬÷äÿXrÉ%ÝOzB@! „€ðH¥áz,Tx=úè£Þíú(„@+!€âef”° ›5k–yóÍ7ù)äõO>ùäbÂ8„±ðŽÉ [áúh½ËþöŒ3ÊfÓ’å“,O†çŸÞÖ饗¶Â€hcx޽óÎ;‹áØN×3Nðø7nœyæ™glh žaÔ€°‹Ñh¸«Î€?&Ú¹½¬ß(“EB@!ŒÀ;ìüc‰¿üío3÷ÝwŸ™>}zGâóe–Y&G”¼ÈýÁH$„€B@!@jHüíúV! „€hPÞ~ûíæ¶Ûn³Š¼<ð®Â¢”"! „€B 9 ñùÝwßm–_~y³çž{¼¢³’K€Ž7§ gEO× ! „€ )@:So«­B@!ЖàÙõðÛ§žzʆŽCrÊ)§˜­·ÞÚzSIÒ–Ý®F ! „@ "€ââÞ{ï5$>?ðÀÍ®»îj¾ñodj ù9 5þ|Ú6KîLŒ:áÅ'œp‚ÉêÓÊ0bW$„€B Ý¤Ý{XíB@¶Gà‹/¾0äòYsÍ5ÍÉ'ŸlóuuéÒÅ T^{íµ¶o¿(„€B  ô¢K|Ž×Þy”xyΛ7Ïæý ü¡@EaB Ž*E! „@3! H3õ†ê"„€B K,±„éÕ«—¹ä’K Š¢’߃ã"! „€B 9 WÙ=÷ÜcÈ×õ“ŸüÄzj~õ«_Í\¹?ýéOO”'x}~å+_É\†nB@! „@gA d•UV1cÇŽm*¬pîÛ·ïbujƺ.VI}ÑV$E×ÈFŒÉ¯9[@IDATýëÖMÞÕÁ½¯´ÒJæ–[nY,AzÈëÉKà'b†7‰§ÉQ%,âZáúh½ËúK4Üñãhà 74#FŒˆû©S}‡ð`É%—4Ÿ}ö™m7ÿûÛß^ ƒo}ë[æ?øYguù­®G™ñÀ˜ñãÇÛºík_3]»v5ûí·ŸÙn»í k sÇOlÞÊí¥‘ªÿ—Ã4Ïø$œÊ‚ ¾, ÿ=z´á¥~ýú^¢Æ! ¾iö¡9·B_&Õ14µÊûôÓOmâóiÓ¦Ùü\xä µDòs (?¾ÿýï×b«ß„€B@!Ðé(¤ápÐ¥™è­·ÞŠ­N3Ö5¶¢ú²mH‹®Í4&Qtl±Å®jußó\ß³gÏºåº PŒ´òõ®U¼spn¶u¸Švçå ù;ßùŽ}¥)£®Gñ°ƒƒ§Ÿ~Ú¼ûî»VsÀ˜Ýwßݬ¾úêf…Vˆµþl†úû8«>>‹.ŸÅ9¶ÿ7Ó§Om$!c´vÆBSÙ—ê›Ê .Ϩ8ZmµÕšfž%Õ1®Þe}çŸ/·Ür6ôU÷îÝs³"ÿÇŸÿüg»_VôÜ0êF! „€B “ PØWK–áÇ›í·ßÞìµ×^æÎ;ï´Ð5êû¤~£>&Lè¨Û•W^iëŒå¾ßÞnÂãpÀ›¦Q}Ùê|“Æ¢¾o~ð¸`MãuÐA™|ÐVúwÞ1^xaåß×9éìוùzß}÷ÙºâD8$Úõ{îIò8iþÞkŸ¢ø LÆQGeN=õT›09}ƒ%ëàÁƒÍf›mfðàRè‹ôýîÏ™f˜ßiÖ7'Ó\[u›Ž=öX»Î{†Ð.Ð3Ïù䃡^~ßûÞ÷lØK÷›Þ…€B@! G ÅýóŸÿ4o¼ñ†™1c†YvÙeMŸ>},—´ß÷îÝÛÌš5ËZµ²)Ì[Žã»x¿ü†ú+âó›o¾iya=Môýÿá€âaÔ¨QæøƒéÑ£Gá>v}ã š`ý/ÂÔäCK-µT‡Û7–œ®<Ö^{móñÇÛ°N>úhá±åן±^oìÚA¥?-‰q™Y‹ ò) (…8pΜ9Óþ†Á¦›njÇÁçŸn^yåû½}‘ïj37Æx^k­µÌ‹/¾hëáÿñëŠü™ ð~õÕWm°tÞm·Ýìmþ÷\ŸUW]Õòp×ûåësõ°.b}ë­·Úg#Ê,b|üñf=öèÈñ!¥G¾¾ñçLÒ|e^0ï>üðCóÍo~3øüfÎa;ä/ù‹yä‘G×'žxÂz,ñL˲¦0ŽX¯&Ožl(#©­E¾gM|ì±ÇÌìÙ³ ʼÓ&„ž<{ ÕæP‘ïIøËºË¾-k9q#á¡óÔ¤ný×÷_>ËÂÎq„ ˜ãŠq¼Ã;˜õ×_?s¿§'YÇ• Û‰'á}lóŒÎøýþ󟸮´k'Þ‹`Ã> # öàGØÊ*¿wó=¶¢%Iâó‡zÈLš4Ɇªd_És /1?ÅxÄûƒuV”BȺçSö»ÛÿÂ슄€B@´ M±[bSÈ¡žwQãøÇ?þa^zé%óïÿ»#ž~èZqPB¡P´ß±|š8q¢™3gÎb.öÔŸœ¼Ê[»¡GFs”‡âá‡?ü¡µföõ|f\9ò?»ïB½S6s„1†Õ?BØ$B舰A –ªŒÒ×s ïÖ­› ¥Ä=(9ð8…IšrtMâäõ@ñA¨«5ÖXÃZyJñQ ï¤ùí—êæÏæWhrk‰{FÕZKXÒ"ðÊJn Éz_Úëi‡[#.ÞtÓM6Ízë­—¶ˆÔ×±ÒžZX¥.L65ô±Ëeä±2*u\}ôÑGeT£mËDÉ…çÊöüNaÔ¨ï4^.ñù!‡b¶Ùf»·Ë[—ÜÊÿ‘Ec÷»ùïÖB@! „@+!ðÿ-ZOGý¿þ뿬°O>ø ÐØòëÏ­7v}£s‡ÿ¹Ÿ9"j>8¤“Xëfú1Œ•Ýßÿþw»æ1^вn`yÇõô¥³ht×ù~‰%–°<áËxûýïo½%”gžy¦¹ùæ›Í]wÝes¹p-^JŒA¼È7C¦S§'Ÿ|Ò†ÇÂÓ Ø ûÂõ¬ÃÜ»âŠ+Úߢüôxxþa5ì{| ¤'ÇtR|„ÅA$„€B@!Œ@a›ýf¢$¡³„Íé{ AÌÙgŸmo@AñóŸÿ<ýÍ^I¸üàVÍA´Ùê™4D“ ½§A91Ç£„PaÞIfÐáj1690s½S€œ~úéI—ëû’@Á†@û†n°¡^&“Ðüˆ#ްkJ„sκ¤j¨Ø&Fàõ×_7—_~¹­a×®]͉'žØ”µ½îºë¬¥0ŠZBµ5 ±6²ÞÅBϤßâ®×waHê›fí—©S§æäV[me˜ˆ¾D€yD¶"Q÷2 § 2Ä*ô8_a¼…aK^úâ‹/왇ã™аîÆêrúœ×_½õ¬³_ÄüÁ*ÜY±~öÙg6†?–¸Ìò#!ÄÜh£Ì¾ûîs·¾*Š8ßÿý¡11îQ|‡áðÃ7?úѬwcDŠ¢HÇßr~;eÍs„dx™m½õÖv\0O¡2ÖÊÍÛ<ÇØ/ÿcÇw¤¨D—Ä:Ó³gÏàÂ;Ÿ‡ã­Êc^¢ö@Àïó²Æ9 ÉkÓ½{÷àc¶=zA­ˆ"€Á ¡¯È‚qî»îZHùAùxÌS.ÞpSIE]ÿ ! „€B`q‚+@Gà,€G>´¹ ‹CÕy¾ÁU›P,%8DÖ£*ú#ŽõrñÙ £V”âx„»Eë¨û«A`îܹ6¬ܰô,¢áêÖD’¦ãÅRBù7Þx£¢S_˜Ã‡¯)<'¾:!d æ;y@êð=–…]·Ýv[)@,Báþ8Å ªgŸ}Öö¡];ì0³Ï>ûHñêš%…œßŽQYóAÏc„\(Ê\KhKÞvGõ%BmÕ"¼Ù°\†0^ Œ_hžÏíuÑ:ІF¢ö@Àïó²Æ{Î_|Ñz1æ¥@k±SV+#S¦L1“'O6„¼Â¥EQÂø ã”ãÊÿQMÝ/„€B@t‚+@8£BÈ—"ÅHf¬«à‘¹RmtŠ\µ±â$ñ.ÉújQýÇÉæ›onÃFþƒzõ¬Õ~‹ãQïýÞž“ß­c(Š_Ößþö·àk"l¿ŽüÏNK¬Ñx ðòÉ/Óÿ^Ÿ³#@¿ãñA¨«§Ÿ~Úb@)>²ãYôN†ç~™!ç9ó%¡Òœ¹u)$ϼí`<² !4{¿Í6ÛÌ/v‘Ï($\;XwÊØ'ú<aîýÃ"´âÅ+^+FÀïó²ÆMBð|Ûm·™µÖZK Šû¸ÕØaèp÷Ýw[ƒòyaP³“1ˆå1J‘B@! „@}‚+@°þsaSHXXϰ~¿¢ ‹sí<ß  ÙëwÜa^xá…ºŠ…*ú#ŽÇ‚ ¬Õ:a¦M›V·žõz0ŽG½{ô{{"€÷Ú Aƒlãˆó]„VZi¥Ž5±Œ˜á~QVcšÐVäíá]K°GØ«—_~Ù*Y£©×Úk¯møþ½÷Þ³É4·Ùf›"ÍÖ½ @HýÀXÅÇSO=eXk:Åc…ºª~¨„œß®öeÎs”'N´ùzÜþªŒµ„¶ämJšI“&YkgÖ”Z rv¹vl°Á†„ó¡ÉçA¸?òÏçóðÃ[…¬ø}TZ÷³ßçe+ÐA)Éþo‘HB€çÿ½÷Þk×¢!ìµ×^æ›ßüfÒå©¿GaLGò ’kiÕUWM}¯.B@! „@gF ¸¥Çµ×^k1%\Ã2Ë,ß*x¯t‹è¬ÂÓX’WÑq<Ö:«õ4õ¬×q<êÝ£ßÛò1\tÑE¶qEURV¢nM¤¬ÐaÕ°¼&12Ö¯X¥R÷aÆYkì¤ÞÁrðÒK/µ ÂÇ‘wâøã·^PX€#,CyTŸvûÁǃ>hs± ø@XF?êêÇ?þ±í)>×ë!ç·kE™ó£Æy?Ê\KhKÞv°nðL†ÜsÙþó‡00.Oë Æ¡Éçñ‹_ü"Vòøã^R€„F¿1åù}^Ö¸"4ä9çœcÈg‘HB€¼l(@X·Q~°¶† ò-Í[èùÎ>}EçìõTB@! „€h6‚+@Pz H.“ªàQfý›½l´ÎúkòzTEÄñøú׿nÈ©€<–E)ŽGÑ2uk"€¢b¹å– RyÊ*sMüêW¿jÀβÐÕ½OÂþ8Æ=ÈZ×¢â<>ÈÉ‚â0Šþýû[ÅÇÊ+¯,&nŽ„¬JYó<ê­Rö<ÍÛŽUVYÅ*¾÷½ïÕôþsÖ*·^…ì¿,ŸG’‚ ~Yñû¨µög¿ÏËj ÆAXÜãeYÔ;´¬:ªÜÆ#€‘ ‰Ïñ<#ñù.»ìR8ñ¹ká¯x±ÖâQ"¤–+[ïB@! „€hg‚+@²‚…+9¹ùóçy„A`$jË.»¬Í‚‹uªÏÿñظ„Ò á¥O¡xøeF?WÁ#ÊSÿWƒcÿÎ;ï´Ì@º$èËH2Ž 8Ú¡ÃdåÁúyÝuי矾08´m„ ¶×.LMá‚Û¼$’Gññä“OZÅ‚‰SO=UŠ&ìû¤ùíªšuºû²¼§åB%?×6Ú( +ܯb½zóÍ7ÍìÙ³-¿½÷޻û#Sek\üÉ'ŸØu—w<§XsÓgÔ(Òþ„¿¼?ê¡Ô˜ßék„Ç¡ûÜoMžq5kÖ,zµ{÷îF~™ú,8¸Äço¼±M|ÎÙ69Ïöi"! „€B@t|%Ýeå]……ìÈ‘#m–¾}ûšÑ£G—ÇL%§BëpúdèС6Hª›2\²Ï"aÉuÉ#©iUðHâ­ïËE`îܹ欳β/„ÚŽÈqÅWØõª_¿~æöÛow?{ÏÊã­·Þ2W]uUe]pÁö¥µ¸~—²V¢(;øàƒÍ€ÌÔ©S­`öüóÏ·‰O>úh³úê«›¥–ZJVšõá¬ìФùí*uºû²¼§åAn[o½Õ*²†ÏKË#K½£×Âãì³Ï6·Ür‹5f!Qhïr‘ÁƒP}„ûCÉ‚zõêex‰š²úÜoiì9_|ñE3jÔ(C‘ˆ"€2ïB’£cë­·úüw Œ,x‰„€B@! Ò!ÐpÜÉ"‘t!–´¢Æ"@>‹/¾ØÐ7xY„¦P}ŽâcóÍ7·±po¾ùæE’ ‡âQ«íUð¨Å_¿•‡ñìäAþšD,~¬FY¯;€,4e嵡_Ç"õ¡Ý$\†X—Eñ€ Ê”cO<ñ„Xcž|òÉÖヘßÊñ]3|›4¿]ݲÎAw_–÷´<˜ß(Aî»ï>;¦œ7Z^iy¤)+éx°V2'PРœ u­$èIe%}ÿÅ_X¬»Ì-„Ð!ˆ=„ ¢<•²úܯa^xU‘o‹œÊâ#ªÏ¬ƒ“&M2äÿ ìyiB*„É…#{>¼“WZi%.„€B@!†+@"r 7^F|5.©8r¡)TŸ£œyä‘GÌÌ™3Í´iÓQ€„âQ«íUð¨Å_¿•‡@4î¾ãD˜>B¯°^qð$xhÊÊÁ{Ÿ>}Ìc=fŠÎWÚu 'Ø&­±Æ¡›Öòå!Ü`­AñAòd„„ãÁ*}¿ýö³ÂY)>š¿›“æ·«yÖ9èîËòž…Jɉ'Z%@HYêî_ ·â ‚·Êšk®T‚’¬O„ %PĂƌ ƒåwh“|¦Ïy¾†îs¿yyÇ T^¡q~ô¹µ@ñ÷ë‰Ï×Yg  ÂûO]ža„‹&D¢H! „€B  ß9a1ˆÀ$q”‰š2<@Bõ9Ÿþ¹}9…C.W^Ü{<âøê»òèÒ¥‹¹è¢‹,#ÿ€‰õñ9çœcN:é$Còp¼ÖBSV‚l-‹*@(ë¼óÎ[¬Ý¡ÛØj塸@°qà 7t(>@ ø O ŸI´Ì˜5?IóÛÕ<ët÷eyÏ£”mY=½²ðÈRwÿZx\}õÕÖktøðáÖŠÐ/!‰8úð@à¼ÄKXO“å£Ää¥< !Ð [}Îs6tŸûµÌ3®ðø`ÉûÃGSŸQN ü DÚa‡fvÝu×à x`]á¯4Þ„€B@!†+@Pz¿!šÃ!{StG(ì4È"Ñh´^¡úœ$Ô›nº©MÛ­[·EØ„â±H¡‘ªàa©+B¥ÇrË-·7¬ñR+ÓS-+®gÎ2Ší.³mEëWõý(>°wŠBž!ðEiLJU÷H~IóÛ•žuºû²¼§åÁsÏã®]»faaÒòÈThäbx¬¸âŠ6Š,öC†¿‚kwh¡ü@ ²Í6ÛØ³û^ïB@! „€õh¸¤~uEÕ uÖïÍlÑŒw ‡,°X5Lâׯc™äÖÈ,agª†…Ãðu×]$ :¹&L˜`›€‡¹Õ EÇô…„º"´˜S|wÜqVñ6òøhÝ‘ÑJóe aî¸n´ÑFM úûï¿o= <ð@³ãŽ;6m=ýŠaÁ/ï}®‡À¬Y³Ì£>jºwï®ü1õÀêD¿?÷ÜsÖûƒ½!IC'>J”,<»È…ľc Q8úöíkC*ç)±W¯^æµ×^³Ñ,xF:É«IÞ —cÏñ8ýôÓM™×;>YÞQìŽ1®qYîÓµB@! Zà ’²ñƒØœÝ~ûíÁ7iUðh…Î+«ŽlàÇŽkzöì™JàREÄñ ýXoÇ9ºÙ̃M0ò Ùú÷Ì;לuÖY¶!‹(@ÈQÃÁ B€yýõ×M\I<è«®ºªÃ’yöìÙÖËì$â íb.‡ f®½öZ{ÀÆë¢ÝMÂڇNJ„\` ÅX`Ý.ÅGÒ¨jïCÎo×ê²æ9JIòjž‹õ2×Ú’·¬)„ê"Œi½WxA„ŠÁ£*t>%ŸG4D¦e¼ðB+^¢ö@Àïó²Æ{NB5ÊŽw…Áj±S¤ì&Ožlóƒí¼óÎ6ñ9û„ÐôÎ;ï˜yóæÙóÎj«­¦Ñž?¾Í¯’§Xò^aŒD˜JžƒQúøã­Áï>•}½Ï+ígBû–þ:-]'„€B L‚+@8#ƒHÈÿ¡© ¡ëÜJå!2dˆµâÜ}÷ÝI.׎*ú#ŽŠÍ7ßÜn¾ùæºõŒ«»ÿ]ÿw}î<°v¹ƒJÖ¸ûQ”˜¸5q•UV ¾&2ný:rpA™—–¸Ÿ9ï"î>§qÿ·ó;ŠGyÄ*§|ÅDZÇÛáñ`·™=âÚ¹B·-äüvu+kž3?Q‚Üwß}6 T™k mÉÛ4„|AÈ\© …„kÇG}+0r¸æ}÷y$•Á‚—¨=ðû¼¬qR<_±æ^k­µ*ÉÂzEÈÕZF ®Ýs»ŒüdއÞE€5ïî»ï¶ëßž{îiÖ]wÝE/ôvƼDB@! „€Ù®ÉÆ^W7#X¯àb}Çw’*rÈ!ÍXMk¡‚ЋÕiÓ¦5m=›ÚbA¨+)>Ô9° 9¿]uËœç%0fáñë_ÿÚ²,c-¡à¼í@ L!öµˆðD½{÷¶—f² kuŸáŠxEéñÇ·9~¤‰"Óšÿû}^Ö¸Âëø¤“N²žCe+wÝu—¹òÊ+mn/žO„yEɸúê«'vÎ{ï½gæÌ™cÇô³Ï>k˜?üp›— ô¾#±èÖe§ bÝ$ñ9ûˆ²ˆü¼X;Ù£ˆÂ!Ày²L…f¸š–_^äœ aR>Þâ „€Õ"PL²SW¬“°vTTxèÊñß«àáóëlŸ—^zéë÷4‡¦*ú#Ž ¶M7ÝÔú¥8EËÔý­‰ëÖrË-¤òÌ'·&¦ c‘…1a1VXa……ü8Œ£ÐK"ÂÏÜsÏ=ög¦ý:ꉺ¶! Eåx|¶gРA6·‚íÖãñí 9¿‡²æ¹ï­Bœqž¦ ‰ãê—ö=o;XoH(¾êª«Úçr-~\ãòk±Ö”ZÎçqÿý÷ÇVáŽ<±Ð´ä—~Ÿ—5®ØwâŠ×eÞ¡óŒ=Ú*?æ-Ì÷€bÂòŸçv-–Û¯¼òн‡°˜(N.»ì2ÎsðàÁšÕ.ñ9ûˆ²Ÿ»*Òþg<0ÎÓœÍܽzB@! „€øà Š-Céí°*xDyv–ÿ—]vÙë÷´‚‰*ú#Ê+$'vኊöQ”GÑòtk"€•˜È"á P$”9®ˆ }Ýu×Ù møÕâÉoNÁÁ;óœï°00a‚-†Cv»$AGññØcÙPWx| °ÀÃ…uïˆÉãÞö9¿ZeÍsæå÷¿ÿ}³ÕV[YÅf­yíêRä=o;Þÿ}»¦tÐA6X­:”%œöyú<’ö1Xð—eÅï×EŸ«AÀïó²8>õÔSV‰¾Þzë•’?æÁ´Þ™üãÉãÂÕjׇ~h”;ÂCáƒ>0#GŽ´Š~” (pDÅ@¹äŸï´ÓNÖûƒ=DYD¨-ÆFxýºý[YüTî—¤ õÍo~Ó*Ó9?ǃÓO?ÝSŽ9éЬ2¯÷yÕú¬`µÐÑoB@!ÐN”¢É‚©ñãÇÛ$q£qímÖœYÚÕÊײ±'\ y¡û#dŸ£Ásƒð>…äá—뮂‡ÏOŸ«C`îܹæÌ3Ï´ <:sI/9èì¾ûîæ‡?üaЊeå𪫮 bÉŒÅéùçŸßÑîVW€0G sCŽXÅ®¸âŠæ¨£Ž²ŠËR|¾-QXÒüv•Ï:Ý}YÞÓò@)I~„^Y…õiyd©wôZx\sÍ5v‡7ìƒBÒK/½d×]ÞW[m5óãÿ8HŽ‘^½zYÅRȺª¬0Ð×C† 1¡ûܯ]žqÅñÅ­’afÖ9éó~~óÍ7mXJÊw‚Ò5ÖXÃÆã'¹ö&›l½e‘ÿwÞyg›€/GB\>ñÄæ_ÿú—U‚ Xa/C/Qq\âsöe&>w5ÅÐ…— ;Dªydz‘goQBÑ‘Åk§ìë£íá-B@!Ðh¸ä‹/¾°‡‰;ï¼Ó ¢\X„Î~³¶‘„«^x¡M¸Z†B*TŸ³aã0‡Ðö–[néÈa®¡xÔê£*xÔâ¯ßÊC€0ü±e€ÐܱígÏžmX¯ˆõLHšÐ”•¿ŽEêC»™ÿ^­J(>þ ø@PáGy¤­Ú©ë4¿‹¬sÐÝ—å=-æ7JbÍ“+Ã)cÓðJË#MYI×Àï*BïàU5}út³ÖZkÕ ƒ•T^Ü÷X¶Ã%&Iä† öü„@2|eõ¹_Ó¼<°ÆÇ2œX! <«PT°>Þ òÒò[ßúV]ï ®aO‚œPy—_~¹Ý“+C€GyÄ*QÊçãÚîŸYI|N¾òΔ™øÜaé ¬ô¯H! „€B ; W€PeÉlÐ íÀgQcÀòÌ%GØ[…ès¼?8ÐÍœ9ÓL›6muÁ£^Û«àQ¯ú=<~Ü}?Î÷þóŸŽq…%(‚ŠÐ”•‡a%8^xá…BÕ!ìÕñÇoË(C¹S¨r)nF äø@ûÉ'ŸX¡ì€lްBˆœ' ]Ò$Ío×´¬sÐÝ—å= ”’xžÞ&‹$ ,u÷¯…ÏbÖB’03Æ`µN~®PÄžìyG)‚P¨ð )ÄQ/•a¬D}îc›w\1Öy…ÌÃ^oN„ëÐf›mfPØ“k„<]i‰gX묳Žéß¿¿õ {zB(ñžÅ=-ßÎrc<'Mšd6ÜpCëýQfâspeœ1.0ÊáÙU+¿[géµS! „€yh¸„°W„!®)›ü 6Ø O;tOIp M¡úÁ ^NaãêЇ+/î½ q|õ]ùtéÒ¥#ŽsŸÄèÄÊ%4Ö–õBRä©iV¸çsÌ1Öc£¨„ð2.–ßî<í¨ò(BÉ…â+>N<ñDCN„º’åk•½Ò¼¼’æ·«qÖ9èîËòž…B7¼š²zzeá‘¥îþµð4hµNG0HMæcHB¡BÍàeÂú‚P–âY"H4ÖAŸï²Ë.ÁûܯežqÅX9ûì³m1!Ç Âmòu8åÞ–[ni¶Ûn»LÊ¿m<ëPBöìÙÓL:Õ*lP ò’ÄG*Ûç?üáæî»ï¶gŽ#Ž8Âl³Í6¥T ü@9öíoÛ†T—l}¦«…€B@!àh¸„ðlôÙ¨çM¾é£÷0,½ôÒIÅË8(…êsŒ”gݺu[¤ñ¡x,RhäŸ*xDXêߊ@ø`/JÌ „„`ÁÒ² %AV:¸'Ä¡˜öÛ¤UAë“O>iC]!äÁヘÜ(><ð@›w`åtÛm·Ù$Š$_¬GUôGê…õ&‡Ðe–Y¦^5ëþǃ1,ê|Ì;לyæ™¶á$\‰ßaqÊÁ9¤Õ ¡®¼òÊKæùóç[Å@-ëQ¬@_zé%['æ;a`FŒaÃ,Œ=Ú~O»›MB¸;Päø Y,!P|{ì±VðJ/y|ØîÓŸ„œßŽMYó¥$y5¾ÿýïBw9Ò²,c-¡à¼í@`‹ •ùWOYA¸:^{ Âô„&S®ÏÃñâ{Ÿzõê,¡º_®>7¿ÏËWì9_|ñEsÓM7ÙñJ†ç"áÝ ü½ßÿýŽïò ÊóòwÞéðú l'/QvPš£ü Ö¡‡ZIâsjÉšÊ3þã`˜"B@! „€ȇ@pV€\p­ ›µÝvÛ-¸¤ ùàl»H¸JöîÝÛöÕµ¨ŠþˆãÀdóÍ77óæÍ3·ÜrËbIÐkÕ9î·8R€Ä!Õþßa%éBEd»E…[±àÛ~ûíƒ*@<úuD€9|øpR0Z÷?‡j„#ЧŸ~jð¢Àª•vó¿ûÞ~h‚?ÔÕy|8Å!ÊÈ}Âú$ÅGtR U!äüvÍ.kž3¿€M™2Å ßðö‚ÊXK(7o;ðR!FýŒ3ÌRK-U3 ×\rÉ%°³Þ›x¶„V€ø<ÜZgzàš¯W¼>VŒ€ßçx—1®hÏØ±cÇš®]»ó B‘ÏüÁ+…9ÿꫯš×_½EÍœ9s:¼IxfÆ…ö¬¸›ZŽû%—øœ<•„ã«*9¡ËX“Q*³ÏÑ™¤å†*,„€B@4Á l CXâÖšªàºÎ­TøÏ›P8žê)@ªè8„ÀÂ%«¿iÓ¦Õ­g½>ˆãQïýÞž`]}ÔQGÙÆ­µÖZ…‰°Õ­‰(*B¯‰.9á ʼ´D}°8åqÀÆ"›C~£ ÁåSO=ÕêŠv9Å¡v°ˆ—ÇG£{©õø‡œß®õeÎsּȎ:egk mÉÛ”4÷Þ{¯UÔ&°Væµ[YwB¯‰´ÃçÁÿqôðÃ^¡¬øãxè»êðû¼¬qEk˜#¼Bæ!ÔÝÊ+¯l=zcpÍ5×XïæîÝ»g¡9^*7@<'IúŽaš(œƒH|Κտ»^”8Z3”mx‘ë½!EB@! „€ù®Á½šœ MeÄ˯‚G>8Ûç.'M#H­¢?âxº‡/¯4õ¬×;q<êÝ£ßÛÕW_Ý\|ñŶq&Ša-ÜšˆÅhh‹c,¯<òH«ÄŠ„§„¯ªÅ‡¹óòË/[ï)ÖhêµöÚkÛf²n£ü Ù{£ˆ9ýôÓO[ÅNñ1xð`ê ÅVæ„EB +!ç·ã]æúhëá%ÅGQ„u?„œßѲæ¹ï­‚âæð÷,ËXK(8o; ƒÒ óZÞð@ˆè¥£€e½ M>_üâ± ,øCZñ‡nƒÊˆ€ßçe+žA(!†õ¶Ž¼%{ï½·yå•W yŠœð/çõ×_ßòå”0„Ë«O0òCð"dxMâ­Àóâ:êZa­;þï'>GñE?TI.ÿF-R€T‰¼x ! „€íˆ@p³4Bó"`VÁ£HýZý^¿Îú¬ëQýǃX¸ùcIJ¼ç¢Ç£h™º¿5 qè]wÝe+²Ht•e®‰„GÀÚóµ×^³õuÂÝZ<±u Æ=H®ç°Mè;ÅbUIÐB:_ñ1hÐ «ø@ð+Û-úóÛU§¬yŽw±ß€‘Ó ´ÕÕß½çm › ÏBÈL§ÜpeF߉g_/Qzôž¬ÿû<’,„åý‘Ùæ½Þïó²j9{ölž E„{††âõõ¯Ýî5ðV"üÏE”(7˜_(BàÉå¹Í om’‹=1ÞW¼;Â@b÷Ýw7ûí·ŸÁØA”ž„õ#ñùOúSÓ§OŸJ=h>ùä{ÆÁc—Xx牄€B ó!Às}Ĉfþüù6ÿ%çb‘( ‹.ºÈî?.¼ðBktSŸF•\’µ!Ä«G€Ç„f£ŽUÖÌ¢Æ!Àf{̘1—k\æC{ñ„ìs£u É#©'ªà‘Ä[ß—‹ÀÿøGsÆgX&1™F ¬ÀEAHÊÊ%à•W^Ä’’óÎ;¯£Ýe+@hë³Ï>k®»î:k¹Jây„4R|„Q*+Š@Òüv×eƒî¾,ïiy ”tÏã¬Üiyd©wôZx¼ùæ›v£Œð¡lhå‚@Ö]Þ±fgÍ%Ô_Qbmç%j>èk¡ûÜoižqÅx§^ä×@ùuNúüã>#ä>âˆ#¬Ǹqã:BXáñœ5Ô+Šö.?ûÙÏÌzë­§üq€'|Gß’øüž{î±^U&>wUbíç|ÌzÇyŒµU$„€‹"0cÆ »V²nï²Ë.m)°¥m¾ñƦoß¾¦ „÷tÆRûì³ÝÏ/Ú“ú¯Y`ÿƒ|†ý#²®v£†ï¦¶9Ò†`aB=ºÝ0n¹öà:öÙg[¯ŠsÏ=7xýCõ9ŠÍ7ßÜ ^n¹å–EêŠÇ"…Fþ©‚G„¥þ­,*ÆórI‡aMrÒ+®¸Â®Wýúõ3ÄèMYy ˆ£Ž¾ÕgÞ:Ñnæ?/¼DÊ"„HX³â¹…eêøñãmòvr™o›õÇ)_•磬^è¼å&Ío‡HÖ9èîËòž–óA›Qç•––OZiË‹»Ì×±cÇÚz’,o®ô /X„ê;ñÄÍ“O>¤xö¼D͇@Y}î·4/„ÒŒ÷Ç{Ì/.Èg„Üäã2dˆaÿGÈâƒ|"—_~¹ùå/iðVá;QzH|Žòƒ½¡¯ð«ZA¨RÆ¡¯P€ˆ„€B`qvÚiæ”SN±9‹_aÌ«¯¾jzè!ƒü¦e¹¶V9!CÂÙC#ò¶"]uÕUæÔSOµ¯>ú¨›ÐiêŒ÷1cq׎Ôð1À"h{÷Ýwmˆ_ØØŽ€·B›XXô‰'ž^åP}ŽÀ—ø¼CHöHè G¡x¸òâÞ«àÇWß•€wßóÍÜÀj”õŠp/õ6Qyjš•‡ãÝvÛÍÐ÷Å_Ìòã, ;î8ûÿšk®Ùñ}¨lÞ!rýõ×[®óø0`€ 1°‡?Rz„B\åÄ!4¿ÝµYç »/Ë{W‡‚x—Ç·œD0O蹌˜ÚYy2ðØcµÊ˜¢ Õæ¸à‚ ,Ð~»‹" ˆ8Ú„ºš2eŠf‚ŠŸüä'f5Öâ£(Ⱥ?5IóÛuºû²¼gáÁA¡\V‘,<²ÔÝ¿„ía>s¸A)Œ"$$á¥Ö]\±C…ØÂ‚Ÿ—ò€„ì­0eÑ猩Ð}î×.ϸ"äÕYge‹ þʯÞÝ»wïn½@=ôPûÜ$|9APŠò\%gñboÂÜà>)>|4³}~ôÑG žl`ÛˆÄçÔAžËý‚2ì»ßýn¶Fèj! „@'A€…œ#Y71 Œ#ö¥ìQ1|@~T‹²\[«ý¶(t Ê™&º~Ñ+õŸ(†+@°X:á„lÌ[ʵ4²åB¡ÒžŽ:ê(ûo­DÊîú¬ï¡úœ X™r8àèS(~™ÑÏUðˆòÔÿÕ €ðŸÃo”°¨<çœsÌI'dÃ!”a˜•HÆ"ó¡(ÑîJh§øÀã‹,?œâ­®]»JñQ´Ótf’æ·+(ët÷eyO˃ëÜóØ÷FKÃ+-4e%]¬êȉ@Â`u!½?àK8x°žžõ.Q/Qó!@Ÿóœ Ýç~KóŒ+Î)„#"wL^’~ýøÌó}/”€yà8ëI%¬g¼ªÑ­k;üïŸã©êŸ³æTM(?æ-ÌÉÆ>#—PJߪÛ!~B@² <*ÊjHrİh£Tb‚0x$¬/j¢^*£ó!fDÀÃZ@i €øV6ÜÎú½ŒU¨>Ç;…¹ûÍ%àÃЇ_fôs<¢<õ5pvñöð¹$è#P„TD[”•!n¸áC<ó¢D®‰'ÚbP,æM‚ÎÜ|î¹çl½P|ºÇ)>9ä)>Šv”î/„@Òüv…fƒî¾,ïiy |ëÒ¥‹éÕ«—Ùpà ³°°ÂÓ*Ö«W\Ñ ªÙ/ ØÜqÇ3Õ³ÞÅ(wáš°à—÷GhTÔWVŸûµËëxtëÖ­òü1Ì/^Èû¸µëg¬‚I2‹"wýõ×7{î¹§ ¹×ˆöºüxö$Y47¢^â)„€h6PKI®W7û«_ýÊÌš5ˆÕÄð3„ÜCÊ©p}¤’Š!ÐpH±êëî2 „Ÿqãl‚qâ$63aH)К¹—Z¯n„™8ãŒ3lűôt flÉ[o½e~ýë_±dÆâð¼óÎëhwVŠB]áñA¨«>øÀ*>?üpkM)fA¯N­4¿QJ’à!X™!wŠŽ¬º°Jç€Ó*QÖv^"!öœ/½ô’õxB`Þˆ9 _öé„ÁÂ2“ýï’K.©\i;1á:r¬øOU,U·ß~û†yÕüéO²ù?ðnWô„Ó×B@”ŽÀûï¿oŸy¯¼òŠÝÛ­·Þzfíµ×®ëiA^Žùóç[ïE XxVʕܲø Å‚9ÑcåJ”—_~¹U.0†0%D1Êø±_DáƒWtÒ¬±÷¤nNYFÔ™ùˆ§ ¾K"úîÆo´¡ŒQ@‚/×ÓŸ¬%¿üå/íOR¦DûŠyÍ@‰„¡. †+@4ðüšªàºÎ­T“ˆ‰Â"Œ5w=ÅBýǃz¢ÑDóÉä¨WÏz}Ç£Þ=ú½=@ñ•7î~´ýnM\e•U‚¯‰X†ç¶Ûn³¬y° ÌKKŒ{65NñÁCž‡ €z/@(u ”acØ¿»©Å²AŠz(ê÷ª9¿]ÝËœçÌÍñãÇÛÉSv–±–Ж¼í@XGè5ljk)@PH¸5kkžå¡Éç‘T6û6 ƒ•„Pk}ï÷yYã D8Ûðb®”IóZZò\',åo¼aù9ÞÑ9Ã3ŸCá¤I“ÌW\a=SŽ8âû,wB2ëÚêeÖ Áê"HkaJßÓo(–Qn‰„@gG€=‚Xε„meà„ABF‡UM4‚7KÜ`1~â‰'ZoY¾G:jÔ(ë%À5(â Xx>"K⹌Âe øQçV„É¿ûÝffœ"c”G²lÖ`„¥¿ùÍoÌô… ­\pµrö±ãÅ^™3­#öú¸9›¢œ ö{x”8%B\„¹Y®uåóþôÓO[¡6Ƈ”wÛm7[GêN» §ÃÏþsëí7vÁ%ׂQ0dä¹>cÆ «aü±¯)J„§FˆOß\rÉ% „Ç”O¿^wÝufÝu×µøsÎð Ì0XJ2d‚0›zÓŸQ6Š/aРA¶}œc¸³`ô1×Åç Æ>Ïv”;Û/ôZ`î¼ø ü‹qŠp?ðe.°/Üÿý­'˜z£È£<ú ¼0ŒaOAtŽßÿþ÷¶-(¸ðªµG¤¨s„¼hÌꀌ˜}ßž\qå0ñ(ºãŽ;¬Bíøã·c›9‹"ˆýꡇjç>y|â~_±n0Á͸{âúÀÿîkþ?ú,,L 8&T³uüüóÏí«™ëÙ¬ø©^Éàrëòà87Ãä«û d,hœ¤hmxxc±ÂC-‰P|àþé<”Ùñã%ÅGrú¾h¥ù ^;±jfâàãêÈÞ¡7v^R€´Bo5OÌàùQ–÷–…X_byËaƒ/Ô‰C‚5Âßò+E 90ŠZZƕљ¿ã`н–¨à¦Jln 0C†€$NRe}ÄK4¬¦/»ì2+¼F‡ào÷Ýwï`—Y7ä éÌÊ@IDATX.# Dƒ ‘0Áì!˦FòF‘~÷Ýw[Ën¼8wã,ÅñÆÀÓa.¿Ú¡hÒ:…!,gCxp®îÓ§Uha¡þÛßþÖ>ç°^Ç3ÁåØâ¹†€3Ê”ú„ùIK²±§ü‡Q,`m2B¡E}²\ëøó̽úê«­‡ ãbŸ}ö±åRž.S_Ó£G6'Ÿ|r¬GNÓ*gy…ì6ã݀ Ì6#dÆ¿ˆBœ³û¥—^jÏï(¤|Eý‚b„ýaðñ¼àyè{Y0À“±GÌp>à€lè,7fâ®­õuC±rò0eÜað‰|â¿ø…8„Á&¿å%Œ¶xÞ¢4pýÇ^€}ïà~ÕUWÙðhðF Bn.öì˘ì±Pâé§áL„"…ð_Œ<§PRoúœ1I¿£ìc­Aa¤Ø' °½ùæ›íüC@ŸÒ”-Îë oöª(™£Ì;Æs’9޼&Néð¤MÈ„P\ ƒu 4î+²‰òÔÿB 4!ç·«[YóK ÷<æEH¨Œµ„r󶃺¡H@hGÌâZDx"â C´/n­©ušß|XBñŠH¼Dí€ßçe+hœmxÞò¼ MX#2V±vÅ­žâ#Ž?‡DÜÄZæPÍsEHžCb\ùíøëB<_YÃIcP‚ üà%ÎX,cÅ` a9‚/Bë–M(‘Yñz`-FPÍÚÜ¡ìõ´Q¼ …ÄùOŒ‹.ºÈ†¦á™çˆýBKB2!F¸‰Bˆ=`‘ïƒÐ=xbp¶tàG¨uŒ÷ðž ô ^ìý3$Bo,ó MÄÙ•µ:­çc'„G` oÚ‚@—OY®u÷aÕÎù,xv€Þ 9ûw/xr"œæ‡å XpG9ÛµÏÕ•ó5Ï®-B„OB‰Â³Ž½ŒõÆP‚~¢]xžàÑâ+@¸Æá­F‘(,û¢LHÑûâþG ƒ@ÏŸqÜÅ BwÈÿŠÈk{x} Aæéúñ‰A;!ë(ˆë~ÿqîACÓ?<³£žÔ# Âiqöñå3ô1|QŽ9J$¼:˜g®.>Fš±¿Îkþ\aO >ÌÉÇÜî#93úg,ÚÅxÅ# ¯aö‡µˆµ–yI»ýú0È•Kø¡p·ßvä´(`àI-”¥>vŒ?Æ!ëŠO<¦Pî$)ˆ4™0vðró¤Vý“~˯2K(‘ʰX9ò;Æ}Wô½ EëØÊ÷³ @…üšÔ¦*ú#ŽLÜÏX ‰ßW”âx-³êû±Âå!Ƀ‡§Jj4o¼€Ø â†X”Ød¡‡¤°iÉK,änMäáá?ò–éßÇa™î¬üx(ÖÚ|0oÐþCl ±f Ž<¼Ùø0ïùkˆ$Â6»¾âƒM›%çñQÆzo+Т˜!ÇeÉ›zbÅŠùÈÚÚLr~»v•5Ï™Ÿl<9p²Qt‡2ÖÚ’·ô5뇒ðÕ"Œ¬«÷¤ÙgÔ*/î7Ÿ^qT¦?}W.~Ÿ—5®HÞˆÀƒ±SƺÆ0Ïh¬V!˜@àÇ‹ä¡Ì,ßÜ:Ëüã‚óˆf?„'–‰<܉â`ÝŸíZx—±ÅsÿÅ/öq EB 3#€`Š]^Z±2¯‚6"psŠhêG ^yeŸ±Å¯X£Ÿ.ûʇ9ߑےs2Ê)¶IgN,¿àûÊWŠ$©XÍcièr{`žyx £ø`ÃÀ&‡U-^9 k‹[Ê—ii$o†(ÉHæ‡RŽ6®¿YÜÖÓ¶3ïu!ç·«CYó¥$îàX•rǵ÷¼í@@ÀÆœƒZ’…˜ãÃz·v¿‡x÷y$ñbãÐ)jü>/«EìwP‚Œ^΂ñrNR.îPÊÁÁ<‰G`‚ç­ÿ G Äõìްþ•ƒ…#¦X)Va5]öe–»ÝvÛY Þ¤ƒw™¼ý²Qh±æ#TC Ç/_Ÿ…@«!@ìz¬Œ±^‡0A Y!Ap‡Õ<†`ê1D©bhoöÇìã ÃÎÇáŽRA>äÞàyèΕîÞYÃÑÄíÃßð=xr]œ²…2øžëàÁ«á1ìÍñzˆ ½]ÁEm伎ŒÍW€¸ïð|ñ=ÜýîùF>îšzïÔ̱ÌgßGô%û òImŠÞ‡•?†!¯QxN× k„âŒØ‘EEÚºFëN9IÞ(9é?Æ/J¸$´—ëâÆ'x"[aïEÿÆÍêÄ÷Ì9úo§$Ï ®ã<4\Á$é,V«¾Q|«IífN2náéÖHÿ~ö Î»¶–˜¹O›žy晎PÊ~9î3×à‰ã{.¹ß²¾—¢ÉR ´†¸bõ8¸›OÔ8˜¬gžy¦]ÔéÜÌBR¨>g£¤ÁR 7â$: ÅÕ÷^8¾qßa!ƒûØÌ™3íCÃÚqeS#y3V±@A@ˆecƒ>óÚ¡Ñw„•%±8qSdcHZ,BRVý:© íSÅ®ˆhõ⃵ÅZ~6sR|Ä£]Ö¸Œç¶è·äMM8<ñÌÀÚ‰±É&Ž ¸÷6 %ÍoW¿¬sÐÝ—å=-0ä…s.‹7ZZYê½ä*`Fx‡—zÖ ƒ-§Öÿ°Ywy_m¡0‹#\ø‹{^¢æC€¾fOºÏý–æWx]b©†B!¤E¡Vœ` \ÖM<ª8 c±W ¢(aþN¡k0–x(û¤‰G¡&¯Fc‹},Â'iú¼Ñu!P&x¢sÖÀ3µ «æªBñî’k€p+œ1±ÐFîPž¡Q¼QÀÒVÖ ZBK„¢.ȲDÐw=BR®©Eõ~çÞ4×Ôâú7öå(3ÀÉ·|òBž€A˜ÃÖÿrÀA|~îÚíGi…"YçzäÑrñèAFè£4ãy!‰0¸%ÄSåd´N÷Θrž`Êž)IHïîIz1>kÕ% †3<Ûñâ©…)aþÀž{’ ´ƒ:×£Z×Ôªo´Üzײ³>£äq{WWJkÚWÞ:µêD›™Ì'Îyqò%”áµ”²Žoš÷†+@A‡f4:.,BšÊëšr@ó‹v!:Ð P}΂B¢âîaýï+@Bñ¨…p,"hR« Fò¦½ÿi/D]؈árWDÂ:äâîûø ¤`½ÂHhÊÊ·[1Ä{d--BlxÉ‚ðš‡J4,kƒâƒÃ‡õ.k\ÖçlìPÆœHÛkX—y~0!2„,h&Jšß®ŽYç »/Ë{ž0asœE’…G–ºû×ÂÁÄœ9sì׬¬#! ´x9r(Ãs#±àRˆ¢^*ÃØ±^FŸûØæW¬ï¼|¯K¿Ü<Ÿ1¨A!㬜12 oqÅk˜£¼84òŒÞu×]íO¬Ã„Ø@øÂÜd}N²Œ–Õ™þGÑРʧ!´DUBÞÎÔÏjkë!€×9†f(>X»×¤…n!‚]bàcÝM]ª\'Á›±È~4Ök+Ânú„g)Ï–ZüÐýÒèòP\€„72¡$B®FØ”ÚÑçï{ï½g÷iðN*?í÷(iH(OX#BGÖ‰1Æ|¢Ž’ ¹(ájòaÓ~Bd#¸®'0¯U^–ßP¾¡ô î¼™åþª®Å ý"s‰ópœ`ßÕ…> jʰ¼ WVUïµúÁµy⌊“êE¨g<<â¼hÜ=È£B­ý W€Ð( ÀaPÔZ@z¯·¸‡æ¢Ï™$ÔÊš(…à-3ú<¢<ãþGyÈA™ ›4Ü« FòfÀ5ï²õrYã2M-É›ú±ÂJãÍ7ß´Õå€DÈ‚f¢¤ùíê˜uºû²¼gáÁ¦iVO¯,<²ÔÝ¿|Y!ÞQŠ„$Úžõ¼‡:ì `wùBÖWeG ¬>÷k–‡Ê2<¤¡Š3”Æ()Üž‚Cðö c`gQ~ømã>Ö]B* aÎ hÁP†ç¼¨9@‹þ—¤9ûHµª_Iá\Ê® ‚ÈZÖýeòooäðÅÝ=’ÚȾ”g 玨`?éžvùÙ8‘ÓãüóÏ7k¬±Fݦ!£àlí“3*DŽUoÿ¾<ŸQNóbêÔ©VÙ¡,¡¬ßxïc$ò}ذaÖ[´–°™½?  &Ù!‹©§0ËSç¤{8±‡ãŒY«žI÷Wõ=ý îx‘]tÑE5ܹ:1—µæ¸:¤}¯Õ®í(Ûð°e¾Ô#Â%£Êµ†+@лäA4¸\ëuN»ÿŽÆ÷ˆ#ްV¼IÉzŠ`ªÏY XP8Ì_ѧP<ü2£Ÿ«àå™ô? %ኈÕÇ 7]„UP#y£œà xÓM7Ù:{ì±GaLÊû|G²&6 B§‘ÝÅ-õ•@®žzOF ¬q™Ìñÿ~i$ojçÕ©§žj-PJ²5›$i~;³ÎAw_–÷´<êy«Ôâ™–G­2êý,ʈ-LrPÖàÐë"Kx ä‡ëoB‰ÒŠ?DTÆ—Ð笡ûÜÇ7ϸ⠕á©Bz€rˆÄŠâ,„¥h/VÊ!Þ4ut"(XxI:ÍGsç6¸Eû¿ùZ¨ !Ðì¸ÐWÎ3¡–žKRÞìm Y?öæÈ°lG‚ñWâ>Ê!ôF>µðÎS¾J‹±cÇÚ!œÓÌ[˜7Œ~ÜvÛm­ –|X´­žL¯tÂq=Xª؃Ê·féBDa|Ây)ï8ñû±™>×ê×vŒâØæ5è)£½ W€ Ùhv$h+£›³•É%æ% KZÕP}Ž%(îUûî»ïbI¯Cñ¨…\ ¥å‘¥Ìèµð`}|þùç­pµÿþÁ½ÝÌž„ñ&! þVü!ê¤2¾D ¬>÷ñÍÃØÙx a5YÖ‹}‘¢û ö(fXƒQFcћՋÌÇKŸËEAgÖT„:ôH!P%(^9G#'ÇERN$(Ôl²f…´Î®²½yy¡ô¡ÝDÞàÙZ‹Ëð<޳€wx»äó~‚ôZeæù o äŠb“~¦nno;ƒ}M½¾Äß(ìÅÉBêÝ“§¾I÷à1 ^œ-QØÅáštoÕ߃ {0ê[Ïà Ù û¾2d¯eµ›°ð(î0 ŠžÍœrаôŒ³Z{f°©õ{èú×Ï¢šcLy4'›½*S}µxãÆ³nØ<ØÊ P}î& .SQ Å#Z®ÿ<|~µ>óða¡Àªz5š7íÅÊ‘5$ăƒÕé§Ÿn_×_}ì´“ 8—%ØÍʃMê¯ýëŽü•Íñ².¸à«ýío›£Ýâ CKWv½÷Fò¦nÌAÍêŸ4¿®Yç »/Ë{ZXÿîw¿³Ïc0ÍBiyd)3z-<8D±iç3k#ÿ‡$7”éÊ.*vuC‘-%¯C£¹ÞËês¿•yx°ç$WÇèÑ£mþ¿¼"Ÿ29Á‡Iæ=ƒE¡*g¥Ëbß"jN\þ¼?°œd= ! ªD€(Lž<Ù*dñˆ£)S¦XC9ŒHðÌmâùŠ·]ªu-ç;°‚À‚\Itï½÷šýöÛÏÜxã‹åB ZxOš4ɼöÚk‰a°Èu‹Ò©¡aoÁš½2Îiì?xG¾Qï¹ÃèÜsÏ5¯¿þºÍ%²þúëW@LŸ>Ýî]’ú‰0Ý`±ýBÃ×f7SNxøÞu×]6œqR’ƒ…\G&L°J…¤ëªüž:')øã„âãàèÙOÈ$Ù/»}h\ÝñÙ{ï½M¿~ýl¿Ç]ú»à tð¨Q£l=9¬ï¿ÿþV²âUðYßV+ K±óÆ3$ü‰ýäâqm©¢?âxðð!æ !ŸÆŒS·žqu÷¿‹ã‘Uàä—§Ï­‹q8]¦¢“xhð0ƒØäÒ#ä!‡_G¬QÚÔrG¥mq `ÄÂ1b„ÍÛÀü‡’xöGý-Œ@Èùí`(kž3¿ñƺÿþûm®+Pk åæm–>¸v“¨œçf­0XXÑó‚6Úh#ëÝÂó<$ù<¯hùð Í7ÊCÿW‡€ßçe+Zƒ úÖ[oµžY¡<ˆ@`QŠ`‚õ ‹9¬,R$Š(z±Nuk†BqÆByÊÖ=áp rT)ÿGx|U¢õXma^ÉwÞÙz pve=ІMäùD(%ö§|° ÙW¿äÆ^€ ure"ï©¥´I{-!±Qn`0ˆ0žý@Ô@ÅÈÍ7ßl¦M›f• Ä}Ârž{yÞ#(&4'/ŸÈÕAdžéE “I3À€„åx“ߓœì=x±‡¯g$É<`å»}úô©{½ßŽ´Ÿ_'t’•eàA᲋k¯½Öî“N<ñD«¸ñoÆÏxÛÜyç6Á|ïÞ½có«ÐôËœ9sÌYgµØ8jD»ËxúÐä„õÇ.sÿ—¿ü¥ }Ìoì¹£ ¬(A×ò"N®ŠÞàÉ'Ÿ´2çèü)«ÝÁ $ñÁ‚bÁD“ר" ª‚G‘úµú½h\±#¾ßsÏ=WW±PEÄñ`ò=òÈ#vÒЩž¢¦^¿Äñ=vëÕA¿7<òH[™µÖZ«P¥Pй5‘PltB*@°Ä’ËæðáÃkZq0DZlPt`YBX/Œyò ¨ vD äüvø”9ÏQXò<ÆÇY㕱–Ж¼íÀªŒƒ Š” µ 3f̰›jø 8Іö ­ˆðy¸µ~>±àJˆí—­ÏÕ#à÷yYãŠVñœäå !ZŠ7 1 H9r¤vtíÚ53 ¼GÊ`U *¡ ÂQs"ÀÊ‹=¢ ÍÙGª•hwxÊ”°¦—’èœó0–þ<óyƒ0žgÔqÇg6Þxãş͈¡dñ"~â‰'lÝyÖ¢ à<‘öZ”E„'ø±Çk…ö$Ç O rÆ&T,F»Q+y‡÷þðëuƒQ"sÒðÇâ7¿ù »‰’kù¼DÝ«®ºÊFÀˆBhMû<³O@!ƒbåÞ)¾Ð›öq‚k =ŽF’e?ŠöyÚðæY¦Ð1ÆFæ÷ÔSOÙ¥`E®b:Q¡{^lʼ9Ò)§œb† be•çœsŽAâdŒ¡^|ñÅ6¡<í"ÏaÜB·}Aòv¬#"7,Þ?¬ (53¬qÆ:Œmú{™Œ” Œ1Æ¡ÌÈáËoÈÅØ·We¤\ÂBâ,ˆiŒ;¬‡ì”*x„¬o+–E¿±È¢¨GUôGêˆ`ƒWšz6C;êÕA¿7,úh½¡¢!%nMÄS#ôšÈì'?ùI‡„MB–ùàæºÛTqðÆñ§?ýist†j!#r~»ª•9Ïyþqå娌µ„²ó¶ƒû\ýÜZâê}ç™íÖD® ½&ÂÏçåïþçÐâW ‡Hk¿û}^Ö¸¡=zØÐi¡Ç år G‚ï 2qЬG¨sEù¼ÜãŒ3ì9±–'E#êžÄCA”Ëx® ŒþÕ¯~eC7ñýÉ'Ÿló.¹{Ó^‹€÷Ç?þ±þ L~þóŸÛ¼"àe/rÀX!1çõ8âùŒ˜û§/Tx ¤AàöÕ„PBpŒgÄ«¯¾WDªï(á5Þ&³±Üç;Œžyñ š;w®Ý{`TÉ…‡óÂóÃíO\3ôFZqä©ÑG„"ÿÙÏ~fCnqrãïcŽ9¦7L*À]Ä8é·0¼í¢=ƒ ²Ê8þgŒ`äFÛhÊ„"^>ªl‹q >"ŠY„n(ÄØ§pE±3tèPëýAãeJ¼ZØÓ2‹¼-(®PˆÐ~Îä(UQ•¹ÅÕ!î»à &,I©!6p¾æ0®y¾«‚GžzµË=hÈ `›“f^EÄñ ¡ , 3Úê¢Ç£h™º¿5`f³‚xø»5KÎÐ:¸­ò š·0‡N6oµø°%4׳FS¯µ×^Û6—ú2ŸXDB 9¿>eÍs6ÈîyÌAÅ…»+c-¡-yÛÁ†vÛm·µÏãZÞð`}qkbY\>\æ]È?ø;BXÒŠß•«÷Æ à÷yYã +7<$=ôP«¬ÙRæÍ>ûìc<› ëK[Úƒ$ï<ï]¨ žå$Ÿ€Pƒ0O»ÁBqBH¬9E͉ž»X÷¢üÀj6j‘ÜœµV­„€hG8W]¡$vXþcÅͳ„½'¹ÓxÞb­”3…>ïì “dIœ3O;í4«$@é’Dì)goÜÙÖñâ¹g‰N¹x^à©Ñ«W/ö?eqoô¼›õZr Ä j /žÅ”A!–þ SHó=÷_yå•Ö€aÖ¬Y6ÜçzêËsQ 8qVIß#´F¡En-ì'h7ýÇÙ‚”ÈÖð¾ rŃ>hFx¤`Ô¾ÓN;YOU®©Gx´FqEÀMØ$ÚŠÌ-‰¨Ó:ë¬cn¹åëõ§6{Æò öJà™4ö’Êõ¿wuAöõÊq×!øwÉÞ ‹–D‡v˜Ý_ÑÏI|ðC‘µîºëZ/*Æ Ê&ÚD?ãQ.ðIj !¼‚’æõC©…b¢gÏž‰F3Ì5æ6ò¢¤péðâ7ö$'œp‚è„Ñ^8܇— c›ýJ-ãö2¬%D&é·P „Þeœ½6Ûl3»–PWκIå¤é«¤¾Iú>¸„N!6D£Ëpe©‚G`á{•aÆ٦¦Ù„WÑq<8, ­æÁˆÛTQŠãQ´LÝßš LÀzbQ.Š‘[y0:—ÇPÈpp¾ýöÛ;ÊEÛÎüe#˜Dÿó?ÿc.½ôRƒ…L¬KØô§’Í. x‚ˆ„@»!r~;lÊšçXɰAfƒÈ†+(¨Œµ„ró¶ƒÃ û…C9¤#1$åÅë©K‰¶ÖA(îþ4ßù<ØèÇ)@8ć¶âOS7]S~Ÿ—5®>ðÜäð'ˆ)Ò2„{xå•WÌÕW_my`=ÊsK9Ÿ\ÃÜg®ñÂ{Ê\p½S|PÒ(>ÈLjrSÔœ83…)kÎ>R­„@gB€ç Ï öH  C<ƒx¾& zFN …p?)LÏPñ®\woô7á›à§DHË2‘óà±Á^ç&Äþ“öD)ËµÔ +vÖoòç‚øÑn„ëõ°‚7íBÞÀýQ?î£n”ó3¿¬„ÀP\„2£?}EQt/Ão([ÈËà„ÕðéÎ!i¼¶iWï-ÓÖzmàž…(RP¼ œqx&§,˜¤© õÇ(ì£ù¼PʲŒkhwñ; ä4(C'ô1/ð­u/e¢$á ˜¤°árq Ô£¤qÇØFvJ»¢}D¼¨ýD½ñBFÁCt×Ôƒ2ê×0¦8s¡Ädÿ̢ʮÕÊNÓWõêý=¸°¶Lª‚G™õoö²±(#ñÞL¤zTE$ñ`ñ`ò„P´%ñ¨×~ýÞ~h «ˆ›¥¼Ä¨Ì5qÞBa 1=%3üPbÖâ‰e)óbܳäz/hé!Ú-ˆ…BÚ óÛASÖgÁA‹Í¡¸rx`G5Cñè(0æC±ë.ïlœYsCÄÈ-ë`U«-ú-ô5^;¡ûÜçžw\qf!$IÅC+@8˜úÐ!¼w…m¢ “à…w'–©N€‘¥][ (¶Ptã]„u,VÀ"! „€¡ÀzŸç a­0p&´nœƒ ÷qÌ;®P òb¼—AX»ñ,&É(㜽ø]wÝeCQüõ¯e‰¥"žN„·Øo¿ýLŸ>}lÜe¾Cˆ!j^PpÎ/\B~d±&mÞV©fB@!Ð, ³ ¯ɨ/ºè"{¦ Jru`HI~ ò¼öÚkVéAÒk"Á°' vB á#M#–Æ$#r°nå¶p¸ eYîãªÏ)w>^ÑCa(~½£Ÿ«àå©ÿ«A‹I—Çð£Äj”õ J°Ð”•Çj “g¡„¡.E ”E’8Èowè6ª÷k—‡„”‚B{øuCiÁ™«MÖ+ŒÃ˜$ÍÄ[OMŒ€ð Ât,5É3Æ»>¢Íû"^„¾R„æí'ÕL!Ъ° j Sžxâ ›ï#3fس†KxV£9ôÐCíþCŒ*òxª²!ü2‘( †+@àd¼góÎä㳨±pèêׯŸ ?"ÌD´5¡úœD¸ñ±XãîïS(~™ÑÏUðˆòÔÿÕ €ðŸ<Q"Ls‚õŠXÝBSV\φ!MÜÇzu¥ÝZƒë¡¤ß[¤ùíÚ•uºû²¼§åQÏ[¥Ï´wÂý}î×"ϸb¼£ áe^’ðcO΋9@Ø-7(!„¬g\ÇKÔzÆÈl ü­×}ª±B %@ÁÀ™‚ÜÛm·õdÅ›•ýûöìãÙc‡ÚggÏUöVx®–!_ÉR]ÛÞ4\‚àî„N0Gq„Õö¡5$BF0P†Y¨>ÇúƒÃ¾ûîk¸h¡x,RhäŸ*xDXêߊxçwÌ=÷Üc¹±Ypq÷ù|Î9瘓N:ÉÎ „¡)+r’à¦ZÔûƒv`YzÇwØ&aù¡$è¡{Wå5IóÛÕ-ët÷eyO˃ÃH×®]mN.” Y(-,eF¯…ÇÕW_m.¾øb3sæL¶§wïÞÑË ý¿ñÆ[ìIœ…X¡ÿßÍXðËû#’áË ÏyΆîs¿¦yÆc¯!òs„¶Œœ={¶yöÙg ÞÅ„BB‘ˆW‡#öã¼”ÏÃ!Òúïô5!°x!üaß%B@!Pì]Bï_BÔÅ/‘(†+@°¢_f™eì«ìƪütJg„ Ö»‚Ø¡)dŸs8fg ù’‡_®ÿ¹ >?}®’ŽžvÚi–áV[mÕ¡ÁB‰2½$²ò˜7ožÍKÂ\(J”…‚¢ÝR€ET÷7#IóÛÕ5ët÷eyOËçï~÷;+Ë*¬OË#K½£×ÂcÅW´ÖZN9Úr %÷1ÌÃç,ÉÙó›ßØ¢BŽ’“zkLr¬²Ê*‹(@üºës{ ðþûïÛü¬„¿ŠžeÚ£•j…B@! šeÆkŽ~hªZ[øÜsÏ5#FŒ°±›ªr^eP|Ï/bŠ„@(p %Þ6¯2òà„ª'åüë_ÿ²uÄ#ª(Ñnæ?/r3‰„@;"Ðjóëàûï¿¿Ã+­ûáI±Žæ™gš±Š‹Õ©Y­à«¨¾h*W4fÌ;ÖCVŒÜ9nßÁó—g»¨½@Á͆ð~äÁ°J$„€B@!PÁ læV[˜H—qÜ5šªàºÎ­TÖg$?~¼¹ä’KêV½ŠþˆãÀ÷‘G1#GŽLUÏz ‰ãQïýÞžÖeÀ€öåÂ_åm)!3ÜšˆG!‰ƒóþûïßQ$a46Ûl³žŽ·ÿŽÕ*^^õÁê”ßûöíkó‰ì´ÓNòþè@TÚ óÛaSæïÞ{ï5—]v™Á’½a\Ax 2Ä|òÉ'µ.Ïõ›ÏƒÏq„²†=„¨=ðû¼¬qR(P,X ü1í1lÚ —ÿå/‘B@! „@y…ÅÒ[o½ekÌ!¡ ¦*x”yk”L\Z¬Ñþú׿֭pýǃ:~þùçö•¦žõÇ£Þ=ú½= É)Jˆ£EˆnM$¤ã,$!DüéOjÆg‹E1ˆ2/-QçõÁ=Â÷Ùg[fÚ2th%BÎo×î2ç9F \y}ðÁ–ek çm‡ S{‡ZÄóÚ­‰}ôQGBçZ÷dýÍç‘t/ ^YC‹%•§ï‹€ßçe+ZØ£G:-dø«Æ"'îB€½Ex³“÷E$„€B@!PÅ${åÕK%7;cýù X¥XÖÄoÞtÓMÍw¿û]Ó­[·Økô¥ȃJå–[.Ï­•ßC þÉØ)$d!ˬ15h¥ùí¼UhŽŸ¼½Fóò ™m·ÝÖ>IÞÜ „²‡—HdAAõAd÷ŸYîÓµBÀG…6 ‘ü|¥•VòÖg! „€B@ÀW€pÆ¢B@]Ɔ® qn©âü:ë÷¯|¥~”´*ú#ŽÇüùómìÜ}÷Ý× 8°0Æq< ªZ_Ј²H¬6Ú¨cMD©°üòËÅ„ô¤I“Ìšk®iÞxã « $t]->´ï¦›n²÷qÝ`>ø`Üš>}º!œÍwÜ¡0XA{J…5 !ç·kSYóœ}T×®]MÏž= ž+óæÍ³,ËXK(8o;¥‡òôC1;­cÒŸÃ;ÌôîÝÛþÌúZ†²Õç1jÔ(Ã+JXðËû#ŠJëþï÷yYã t\ã9I‘È‹ž„Àb¬’C©¨·qÞzè>! „€B@t‚+@8l±Åø•±¡«‚GG:á‡Ï>ûÌLœ8Ñ`ʼn0¤UÑI<°Þä·e–Y¦^5ëþžÄ£îº íøãÿhN;í4Û®­¶Úªd饗îXIp‰0$!½æškl(8Ê…ó…^~æž{î±?/±Ä6'ëöc=f~ûÛÿŸ½ó—¢ÈþvaT@I » H•hT\T@ØU0€³®kVuÍŠ9 *†„1®`‰êŠÄHð/ (YÁÕ·øêÒ 3s§gºgzf~õ<}gn‡:Uou÷tŸS眧 †OúMž(4A^ߎMX×9ΧŸ~ÚÎFa_½zu+2Œ{ §Û„êÚe—]L¹rå–¸ŸÌvFéGá^“ÊD‹¸%Yé•Aùxž cL~®óŽyXçdæÍ›g¯Id„uþ,[¶Ì|øá‡æÇÁsE{×[~ž1¹mµ3€0.Êÿ‘Û±tâ ¸la=b‡#2beËÿ䏿škL—.]ÌQGe#—Ö÷lŒG¬ ÄÍå%bäÈ‘)µ3 ý(­ Úž{ij'ñ0eÍš55Eeì¹›Q…1£xŒm#ò’Édí¢ð‰BÄíï–AE ‘@×·ãÖuÎõ½hÑ"3aÂkèïÖ­›Êgºý@±Šqà *˜8 aûÂTN;¡^‰¾ÿüó6ºˆ~ÚîÝx 2﫯¾2o¼ñ†UÚ&3€xOå;Š`î»|ÖªUËôìÙÓ´jÕ*•C“†%¬YüI…kcRŒõ!Cs¯ÐtÏ+ ¨,aæ #?&5xG?·ß95Ê»žK<{©ˆ€ˆ€ˆ€ˆ€„K ç7šÙ³g›qãÆÙÐ .,B¸ÝVí¥øã?̺uë̪U«JÛÕ÷ö Æœ6®_¿Þ.±í JF²ÎeCF2ùÚbíßvÛmV€óŒà® Œ‚ܯ˜íLÞ ‹_(™Ù‰A…N&¥víÚæÆo´UxûI:V¢F ÑõíÚé÷tÇùùô#ƒI \ß±ž^¥Éó#£´ºmG¡ófÍše•ÂìǺ á€1iÒ$Ó¬Y3ž/ˆú1~0‰B h[GXcîme:28W.¿ür[Î/M}÷C€|k„"%|/!°¨"" " " ".œ@èŠdÙ(Üø®’[$$íß¿¿ùôÓOí,÷0ZĘ“¶eË–6–xãÆ·if2¶©4fE6dĈԿY À½h÷ÝwßFF77æÌÐd_Ðů rŠ·Ÿë!ÓB¿ñlQB&èúv}ö{ ºãü|¦*£4o•d2S•‘¬ŽÒ¶!oLî…Ü3ɤ÷ò1!ƒçD> D c–}íRá¹—m:ç¿·„¾j×®]( \û¸Gž-Qø6·ŸŸO…{óC+Ü}]ø+B_aQ‰&¾}û¦2î ƒ²xŽÿõ¯Ý&/åÍ7ßlFe1í-SÃÜß++Ùw r*" " "P rn!ì!dãB¬ÛæÍ›÷H÷%³ß™Ñ”¢ÁÛá ÆE3¨zõêeÎ:ë,¯N-ìó*¨~lÕpý ‹/6¯¾úªm Hv†kƒ¢¦M›šòåË[e_Ð ö+ƒ$ÉÇ·žt™¶…\„²¡’AIÐ3%ªã£H ÑõíÚê÷tÇùùLU†Í ˜¶mÛú~>JU†ŸvÇAƒY,\O=õTsä‘GÆî–Ñÿ(œ‘ѽ{wSµjU{ÿͨÂÿ03ø5‹?’Á×Á˜wîÜ9ð1÷¶4ójúôé6lZÆ SRŒzåùù~Øa‡™‹.ºÈ4iÒÄÏaI÷%7Œ Iem#ï¾ûÎÞÛ•ÿ#kØ} JÕ0€78cŠ—&†ÕØBKÆÛåtÛÃÞßÉѧˆ€ˆ€ˆÀf97€ð0ÎL*fò§›|Sƒ,µkך—^zÉ´hц›¶vc_À‚sŒ œC¸‘{K6ΫlÈðöIß³G`îܹæÒK/µ>øàž:t°!X˜™É,Í ‹_óçÏ7÷ÜsO ñÈçÍ›g®¾úê’~Ëô誾(Ht}»¶ù½Ýq~>S•ó©§ž²I¿ÊúTeøiwì¾È8æ˜cÌ'Ÿ|bÃ{î¹§)W®\ìnýLÈ`~P‰¡áIb•èk̽=MG^C„šä𤸽&½ò“}çâZ’w@2Jù»ü,Gq„ çï0ªå" " " yF xí]P$³¨Dƒ.º×^{­éÒ¥‹M®ÌŒ÷ KcN­[·¶³jF޹UtÚ„ŒÒú ¥µAÛƒ'@87SËw#-ž?a¿2P zÛ˜IÛè·sÑWÂÔLHêØ(Ht}»6û½Ýq~>S•ÁõgÖ„ ¬¡ßy£¥"+U©Ô•hd ¬­W¯žùúë¯ÍÔ©Sm½ Ã`aôÚ¨BôûhTs¿>¬1÷ö,]Ìô~öÙg ¹„Â2€xÛ©ï…E`ùòåÖ{O¢ì±Ç…ÕÁ<ìÍ€ì»$“€T6àÞV¥Já‚"¸dõêÕæñÇ·˜x 'ØøôARˆŒ Û›ouñP¾dÉóüóÏÛ„Ï¥@²1ñdàýAÓ3f˜·Þzkˆ_îñdp«f†Ë—R¿~ýŒ0ƒ{̘1¶ê%ŒK /yîØ±£yã7Ì?þhpÙôÑG á.Œ;.a:_$:t¨Yºt©M;‰i¬"…H ÈëÛñ ó:çzå÷øã?¶Fd†q/¡ÞtûÁlfÂŽ?Þzh$3€Fˆ…²ÿþûÛð^#‚,^NVlý$Ag‘;–L~þïó°Î+È`@eÁDEüà‹­fÍšÖÃ#²Jn ôìÙÓ>7˲eÈ祜€[x蛈€ˆ@aܲjÕ*sýõ×[:Ä?ꨣ7€dCFa oú½ ±éºuë ¬K+Ùx2h#IQYRigúQZ´=˜ÙIJ¦a®ÈSãúÃX¤¤V­Z6‰âsÏ=gÛËËõ]wÝeC Úqþ`ä亡àéE ³Í«W¯nN<ñD»Ä9T«D ï y};a^ç\¯¿üò‹ÍË潄¾¤Û´‘³C²2qâDsË-·Ø]ÈßE¸Í  ^î^Û&îyL¢$–L~þïó°Î+Èì·ß~öœÑy“ŸçI®[íò(z®Gb‹|rúᦲ…ùÇõ«"" " …D p/ê.„ J>”ÔA—lȺÍùTß®»îZ2û½råÊ¥6=ãOg(”™ Û¸qãRÛYÚñd”vŒ¶&Œ$÷ ¢ t÷DBU}Oä¥{-Æ Ÿ~ ‚ÎØé”–\ó(#¹¨ˆ@!òúv|ºνÞ*$ÇË‚ƽ„zÓíù Ú·oo“y ƒ„»'rß úž+ƒÿãfðk<2ù¹.çdöÙg;A€çOðK †4%@÷K/¼ý ¥œîï!9‰xœ.¿ürsÞyçm“ ðgaîŸ -rk* B&u¬ˆ€ˆ@ naE¯^½l_Q¤…/?2¢8XÙjŠ_7û=•ÙÙx2ÝóÝwßÙóÙ~™–x22­SÇç'¯¢¤Ÿ¸û±=®ZµjÉ=‘8ùAÏtÆããÅ_´/^(y¡"q{29\;sæÌ1ó7%PçM»4h`gpngæÌ™¶¾c=6¶;ú_òž@×·ƒÖuŽ¡Ÿk³mÛ¶6´”Ë…ƽ„¾¤ÛÂïaŒíׯŸ9üðÖ¸ŸLXpω͛7,©¹W˜Wáþ\È?ï>Ìà×,~/‘üþîó°Î+áéÄDƒd¿±ùMR­‹JržÙxV#|)†c•hs,x.÷“ë%ìý£A\­ìÜ‚Ñãᇶ=AyÎ ‚ K6dÝæ|ªåè /¼`ˆÿIhŠÒJ6Æ#ž ÚÉË/¡Aœgñd”Öwm/LsçÎ5—^z©íÆ„L äq÷Dfž=£ #Æc=V~¦víÚæÖ[o5ÕªUK88o¿ývk!W†Ž .¸À&0îÝ»· µóí·ßÚõ +ÑÈSA^ßAX×9ʲ§žzÊR”œjaÞKèKºý@!Œ%³Y‘Ʊ‰ý$’3’`€eòAÐÅ+ƒ ‰ ‡zhТU_ŽxÇ<¬óŠ®‘'à™gž±áa‚4  4ÈðûKá9A ˆ-Š‚úC®$ž¿04ãI„[ED@D@D@D ;7€`ô@‘fɆŒ0Ûõº™™tõÕW›.]ºØ.¥%AÏÆxÄ“á£uëÖöe×åÒÚY÷x2J;FÛ “a`ð„ j&“‚Ñ#Ì{"ŠGòx¸âÂû$“Éþnö*ç= HöÇ‚Q‘Å[§«[Ÿ"P‚¼¾°®s®ïE‹™ &XC&ÆX×ÖdŸéöeFWòjpI IiF’dmLe›WF" ÷@wL¥NímÞ1³¥„/zöÙg ¹„‚4€`ðpF%ÆssW7ÆÎB_á¢"" " " "=@ü6—{øá>h^¤UrG€YœK–,1Ï?ÿ¼ …“©a!¶'Aù† lÓ3fØ$ÎÞv%#¶íÞÿ³!Ã+Oß³GWøX„ŸqÅ…/ Ü 3÷H^³fM·9O¿2x‰ÆX9mÚ´¸³œý4ŠYægŸ}¶=„;*"Pˆ]ß®¯~¯AwœŸO?20Æò{üÓO?ùòFó#ÃOÛ½û"o1~‡ÉO2~üxÒ*™Ä{|*ßW¯^mÃÆð‰‡ ÷\?áDɘ2eŠ5Ø©ÄN$Këý`¬ñÚ z̽­H÷¼Â€Ê¹d‘Ñ#HšÑ¬ >Þyñ°ß{ï½£ÙHµJD@D@D@ ”@Î „1>|¸6l˜}±íß¿¿/°Ìå~ÅlMŒ`A¿2H¨™÷ÔT]¥qÒvÂso+Ò‘±ãŽ;¼#Ûµkg0¤ªˆ@ª0‹Pmx.Õvh?(V97€ DDáFBHù–ûS%Æ7ÞhFŒaA·(¨1'Ö‚ L¯^½ÌYgµU3ƒ’±U¥1ÿdCFŒHý›%„ä#œ ¤‹»±Ð+ܯHbI¬û ‹_Ì(Ä‹nöìÙ7…™‰/¾ø¢­‡pX$GWB#èúvýô{ ºãü|¦*ƒ 64mÛ¶5Í›7÷#†ÍÆýÊÝ y†ãžqä‘Gújgi;ÃÜw ;TþfðËû£4ú¹ÙΘóûô˜{{“ÎyE¨IF–î@IDATòܳqãÆÞêô]’àY ç49@x‡PÈœ@˜sá…šÚ‡A^ UrK€Yío¼ñ†éر£iÖ¬Yà rÌ1‚ð[±bÅ­Ú¤Œ­*öü“ qúšEÄ´ÿÇ?þa%¢$sf_sÍ5æâ‹/6$Ç[*èâWÆüùóÍ=÷ÜÈLæy󿙫®ºª¤ß2€=ºª/ ]ß®m~¯AwœŸÏTe 4{ê©§ I¿ÊúTeøiwì¾ÈxðÁÍÍ7ßló€`¬ Ê@ádáQ‚ ¼5˜ÏooåÐC5,*Ñ#À˜ó;ô˜{{šÎyE{æÌ™c¯IØ ƒå%ªïÉx +ÿG2RÚ&" " " áȹ„”×± ìpº«ZS!°råJsíµ×ÚÄÊÄÙîÓ§O*‡¥¼OPcŽá£uëÖ6¡ 9¼í JF²NeCF2ùڜօâ»Ï¬m¼ÔÂôTó+ãÿûßVmÌ„ ýæú§ÒFE ‘@¢ëÛõÕï5èŽóó™ª ®o<³Þ|óMûœäŒ±©ÈJUF*u%ÚUªT1ûí·ŸoO2t¼N‚ ƒEx?d]x†`Q‰°ÆÜÛÓte È~öÙgM:udñÕ÷¤.\hï‘tõIº³6Š€ˆ€ˆ€ˆ€N çÀ{¤ 3&@Lobm?ÿüófæÌ™[2®<À ðþ ‰) ”C^H€bTUÈ$î~¶qN¡sçÎfúôé'Ag–ùÙgŸm»@œs(Dùt}Ãc,Fþü±Ä-jã‚rï•W^±Þ£äX ÒV_§L™bÃùõ¬ «=ª7?`@eQþ˜ü¯(´’Üq„ìýå—_l¬0 ºQè§Ú " " " Q&°]Ð#\C­ZµìB’ÀÅ‹-ÂΠ [Fàγ Ið½nÝ:³jÕªR[ž«1§ëׯ·I©SigiÉF?Jkƒ¶GƒÉMo¿ýv»Äæ—ñÛB î~uÜqÇY%¦ß:’íOÝ={ö4ß|óÝ £e«V­Jd:ÙÞO~cÆŒ±û£T½õÖ[íþ‡v˜™8q¢ÙÿýmXÂdrµMò•@×·cæuΤg&L(¹®Ã¸—ЗtûB˜6ò[̳C²2tèÐ’~ 2Äþ†'Û?m^|W˜@Á¢R¼cÖy)¼x.Pø«Â8o²Ñ çýQ³fM›Ï9ìÜ„p Ìr¡ðBÌÿA—lȺÍùTy  `›\¹råR›žñˆ'ƒð-[¶4Ä oÔ¨Q©í,m‡x2J;FÛ “3˜wß}÷@:Ç,QwOdæ9çY…ir'áEác^ª…ööÊ…¾"Æ>ý#¿IªmÒ~"& ¯o×ΰ®s¯·Jlòö ï%ô%Ý~ÐÎöíÛ>KóþÀHâî‰Ë—/7x‚.^‰ê¦¯,*…AÀ;æaWÚgŸ}ÌI'dŸ? ƒœz6ÿû¿ÿ³ ÐI~΢"" " " "}@²ßI šŠ_f¿SHôÕ‚¢—X̽zõ²³ñ¢ÚNµ+ÿÄ*ýÄÝÏvo1v8oŽ dªáwÞ± =zQ¥êHȧë›øÛ´ic”¯¾új¤XºÆàI†1¶ÿþæðÃw«#ýÉ ~…¿ŠôE²qx:a|Tþ˜HO$å ãe+H$‡H(@˜ý7yòd‹ŽúU«V c6dÞè<ªpíÚµfìØ±vg‹-Jmy6Æ#ž ”XÌÞä%´bÅŠ¥¶³´âÉ(ím/Lß~û­ùÇ?þa;‡’,á¤Ü=¯ YæÏŸož|òÉ’*7nln¹å–¤rMøÄO˜×^{ÍîGþœO<Ñæü¹à‚ ¬AeÙ²eF¬úR@‚¼¾–°®s œ#FŒ°žŽÝ»wõ^B_Òí a<9ðF+W®œÃ÷ó´ÓN3:u²Ûðà ÃÛÌ+ãñÇ7,±åÐC5,*…AÀ;æaWâ7÷™gž±?…Á*Œs'Ì^ X‰ Å¢"" " " "}@PF3SÑBM]²!#è6çS}„¹ꪫL—.]L×®]KM.žñˆ'ƒu­[·6¸–“ 6Ó$èñdäÓ¸©­Áà…•ÄÔ5kÖdTñn»íVrO,S¦ŒUšdTaÌÁ(þùç’µÈC‰‰A/Q!ü ‹)„¼"‘:÷m Š.߀·ÎDõh½ä# ¯o×ÿ°®s®ïE‹™7ß|ÓT¨PÁuÔQVd÷*N·„ª^½º!±8íL  j ^¦axšzeŒ?ÞÊŠýÃo>‹JaðŽyX礘Íÿì³Ïš:uê(Haœ:¡ö‚û7Ï\x×ï½÷Þ¦lÙ²¡ÊSå" " " " ñ „ߣ‡[â‹Í|­«? Kæ­ËïP€.Y²Ä<ÿüóæŸÿügJÉÆxÄÊ  L{ì±”ÛYZgbe”¶¿¶&ŒÌ&e9úè£3ê$ŠJw^…‘øãíÄóÃ'/Ù'í¢ð‰²ˆ} Í0hÐ »ÈûÃÑÔg¡òúvl¼Î1Æbää‘GB½—ЗtûÁ gŒª„Ï$Y{²âî7ÜsÂ0~ ;kœw^²öj[~Hẽè TÂ`)L4 ¿&i±ð¬†D%?𛋇W­ZµÌe—]f½xhy±­ÏÑR+E@D@D 5Á»g¤&·d/^"Fm^ýu;+†°$TÉ-?þøÃ¬[·ÎT2èÔ˜ÓÆõë×Û%¶AÉHÖ÷lÈH&_ÛÂ#°ï¾ûš;î¸Ã @Iç ! È·1qâDS©R%ë!´¡À¯ ^Î[ŵðù矻¦¦õY»víc¢·ßiU¦ƒD ¢]ß®¹~¯AwœŸO?2œW–_o4?2ü´Ý»/2zè!ûÇo"…g‡ ÷5î»|r¿ëÙ³§iÕªUÆ"˜@Á¢< £ ¼ÆzÈ!¹·¡éœW(DQ†RþÊKSßp&Mš(ÿG"HXOèg ù”ãŽ;ÎzV‚/BÂâIÁ;:výüMañ>üðCóÕW_™Ÿ~ú©ÔýÕ“l=m›7ož!„í—_~i°Éö×ÎT÷§/|ðõæÄ+TED@D@ …ÀÍ^Žz´qãF3{öl3nÜ8;Ú…EÈQs$vâqc„úì³Ï¬ËvÐP‚srÌ´lÙÒ†ú!I¬·%Ã[gì÷lȈ•©ÿ³Cå?á b н™3gÚûá^êÖ­»KÆÿû•W !g¸2-ôÃŽŠ2D×·ë³ßkÐçç3UÎ[…º4hàG„5Ddã~…'Å_|a¾"_å2&Mšdš5k˜â™üšÅäHWWXcîma:2Y¯^=2’OHF€‰Z(®Y:wîl½@’í¯m¹#0|øpû;C üþ†MŸ>ݼúê«fùòå¡u£ Ï ”¯¿þ:ãð¼É:uêT;òý÷ß/Ɉ‡¸Šˆ€ˆ€ä;œ@ˆ"™ÙË(%ø®’[(~o¸áóÀ„¦bÌ E\Ý^½z™³Î:khAÈØ¦Ò˜Ù#RÿfÀ?ü`„# ¤ ƒÅˬsg„ºø•ÁK ~™Íši!V5ÆhJ5”=S :>’]ß®±~¯AwœŸÏTe£‚ðväèiÞ¼¹&U¾*Ùüs/ÄÛ­[7«è‹Ù-£ñ€Aω|º™¸Uºé`fðËû#SŠáÖ˜{[›ŽŒiÓ¦Ù°i#•?ÆKSßãÀÈÆ{ UÈ“obM¼ã´.ûð˜ &…ß3òJ’ “ß&ºÉAñÖóÛ„q‚{J‡ÌgœQ’ì>ÞþÈð»¾aÆ6Gmäù¼\¹rT㻞drñ2½óÎ;­‡Ë'Ÿ|b=Z-ضm[y/YÚú#" "ï2Ê‚âÙx(ß(«W¯¶.ë„(HuýСCíñ$…#¹ç1Ç“V=¸Ê#·´—YÚH‚oöE™ðÌ3Ï”´]ë7á5×\cŽ<òHà #F¤<–n J{Æš™PíÛ·7k×®µñTÓ=‡xX#Á)cé•Ë«w&ŽËwÎ9š¨_¥»¥‹öÄÓŸHøöÛoÍ%—\b—“O>ÙÞWÁÂË+ç.áWýB"TÖS¸rŒ»¥»Ÿ7¤›;wÂõžsñã?¶»¿ÇÅà'ôÂùçŸoÛÄõæŒÔ?kÖ,»?akpñ§à^å•WÚeذavþˆ@¡Ht}ÓO®c®'w½cü<üðû¾Ý}‚߇·ÞzËôíÛ×\{íµ¦~ýú ï÷ÝwŸ¹îºëÌ~ûíWr/rmMvÏñ##Y=ÉîiǼm÷EîUä)Á#“~1+–Â'ÿSO:ë¹×ºÜDžQ.ù©‡ñŒWhï=÷ÜcÛ…×+!?(x›0±‚öj}¸å`áÙó—P”œ[nœüŒ;ã—lÿtÎ+Î?fEŸzê©æÄO´ao8gèGïÞ½í9SÌëa¡²…÷{žÃPX“¤´ç¹-Gê[¶ öêÜsϵKÍš5­Ñƒ1ÃpU¹rekÄ¢MCb×óNÀ³3÷+ž¹ñw9ÿâퟨždë1Øó~Ž ~ñBO¶:ry÷çyô›wlÞ‚št`¬?" " "Cy€ðƒˆâ ¥2…™$ëd¶KÅŠSZÏLŽg ˜eÀ, ¿õ¸ýKcém#³9\Lm­_³Õ¢Te¦;c“é»±qç³æ<ð@Ó´iSÒ‚1Hç"ìÏ€lèØsŽ+È£ðÊ,~Šwœ]{Ò]_Ú¹kêO^à|áeÅž»ì²‹ûK,\Î]”•(Ë8w™5FaƘ›íÇÿé®'Ä/.®•*UªØï‰þÐ6^Æœ3²gŠ·M\(•(xÛ¹¸¾$ÝõÁŒ2¾ÎƵ?‘\­|%èú¦?\3ÜÛ9ÿIX‹çE‹- ÞQA\ßîšD1FýÌíß¿¿5°¼üòËöù‰v¸ëëå פ‹Oî¶¹ºøýóãÖ§*ÃퟨžÒÖ£˜iݺµÍ2cÆ Û”ÏÌŠ¥ð‰a–zÒYáù ƒ²÷, ·sæÌ1xñ¤Z?㙨°v¡°rá°¼íÕúÍã7†±ãÃo‘óÐÁ Åoqºç“áWÎÃtÏ+îÄù=—9'i#¡±¼2‹i}ì8ºÿݽÅ2v47‡Á‹«m[ü÷ Ës.^‡2~Ï8ȇnó?ÅÖIè²Z›Bæ1i Èòä“O–È‹¢ &ËáÁD!qº<˜‚}Õ%" "+@rÕpÉ(` dÇRGidâ·…‰Dλ˻ù0™tñÊ‹¢Œ§Ÿ~ÚLž<Ùv›ü¬:‡ƒ>TŸˆ€ˆ@.È’ ê’)" " " " " "Pp\þ)óch 1I<ÊòåË F ᳃öþ Þ:˜ªU«ò5’20иvxŒªˆ€ˆ€ˆ@!¤FQ}È)Æ„À"ì t•h0`@Iˆ`¯ÂŸp’a„/»øâ‹KäEQa¯Z¶liMço´Ï]µND@D u2€¤ÎJ{Š€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ@\K—.µ9ãÈ!E~‡òåËÇÝO+£CÀåûÊV‹*V¬º¨Ldôëׯ$Gc¶Ù„FD@D@Š–@™Mq-K lÉLˆï¿ÿ¾h!©ã"P(pãÞsÏ=mB_oŸ¸Æ™©F¢lo rÿÅ‹—¸Ý…ñð^ú." "°…@¥J•L&Êâ-5mþ6cÆ sýõמ{¯»î:Ó£GØ]ôÄŒ;Ö,Z´È¶ŠpX5jÔH¹…?þø£Õ“üúë¯ö<ª]»¶)[¶lÊǧ²c¡ÈH¥¯ÚGD@D@Â"’$,áªWD@D@D@D@D@D@ À˜1c¬EøàÁƒÍXÝ*è>tïÞÝL™2Åöñ•W^1|pÊý5j”¹ãŽ;lÒûÃ;ÌÜpà ¦nݺ)ŸÊŽÙ–Á¹K_˜DD8,…ÁJe”´ˆ€ˆ@Ô (VÔGHíˆ<¢&°´oßÞ†ÀŠ|ƒÕ@CÒï•+WZ±Þð¥áY·nùé§ŸÌ’%Kl±Þ륟ÊölËÀKzöìÙf»í¶3mÚ´‘$•AÒ>" " ‘' Hä‡H ˆ2”èÿ÷ÿgÃqþùÏÞ& g”Û^Ìm#ìUÓ¦M-?á¯8€p«„ÆpRµjÕm Á5Û2¹µfÍÛô0 :A0Q" " "à—€ ~‰iðX¸p¡M€Ž3èU¢O`À€%yý&ýîÖ­›9ôÐCmÞBr™OƑ˶ ¸aÈ£(ü•}Š€ˆ€ä;@ò}Õ~œ@i̲÷Þ{+üUNGŸp¿FoíåË—7,a–lËÀ äÝÖE£F²ç2 ìÓ§Â`:úùQÙ¯¿þjÆo¾ýö[Ó³gϼ4èÒ‡uëÖ™ßÿ=? ÔJ ÅÚ÷€ªš& H®º&" " " " " ".<ð©\¹²U­4·õÅ]ûÏ?ÿlH`OqŸ|ÿå—_ ÊÄ  ¡i,X`«¢Œ§Ÿ~Ú0{žÒ¦M@,‰âú³jÕ*ƒq‚Ž;楤¸FL½H…€ ©PÒ>" " " " " " "‡¹?ð!ô9@Tò‡À±Çkš4ibüâ‹/šbƒ…A8Åå±ÿèOÑÀkbÍš5Ö¨s h†]‚' HÁ±:(" " " " " "¼?Xš7o®ÙÒaA©Þšß~ûÍÖÎw¼2( 40;í´“ýäfÖ¯^½ÚVE'œp‚9ðÀmûç¦"" " …@@BEõAD@D@D@D@D@D ë“´páB»tëÖM!ƒ²>™ $é·+Íš5+ {Eð2eʸM}6nÜ8Ò2ú÷ï_âùáeU$" " 9 H K¤ˆ€ˆ€ˆ€ˆ€ˆ€ˆ@þ N>Þx «bÅŠùß©"ê7ìá°jÔ¨jï1¬„]2‘!£GØ£Ýú/^lßýøã6ø† ÌܹsM¹rål£Ë—/oöÚk/“(ÇÑœ9sÌçŸn ¸Ã;Ø}÷ß{_ÜqÇvœ°käÆáÜ«R¥Š=výúõfÚ´i†Ï¶mÛšÝwß=áñ©nظq£ùꫯ̌3¬qs¿ýö3$éW*…{ý_|aûÈýžc5jdvÛm·T·ûàýõÑG™o¾ùƲÞc=L:uÌr=„(c\fÍše³ºuëZ¯­t-Y²ÄÌž=Û0v*T00iذ¡)[¶lÒ>ÑdÓ~r_m·ÝvöœyçwìwrÇ”VGRÚ(!$¨ªRD@D@D@D@D@D ð  ìÃB¸ ò„á5Pøs×ÃÇ{ÌL™2Å6€f~ 'N4cÆŒ1(Œ9öä“Oöu|*½Î¶ Î_ (u ‡¥0X©ŒRaìsï½÷š^xÁ*æ—/_n=•Î9ç㌄F»í¶Ûìùáí1Êó¡C‡š·ÞzË‹‚Ï8 q(Õ{÷îmÎ;ïÜ@Ö®]kïÓrzõêeþñ$ ]Hˆ¼Q£F™xÀ0 q`¡O×\s9òÈ#“R¨cĈæñÇ·uüú믶êÞg_|±M:ï N®ýÞÏ+V˜»îºËÞwàD½´Ã;Ç÷èÑû{Â÷=øàƒféÒ¥†>aÄ€ ¿cwÞy§iݺuÉØÇVôöÛo›«¯¾ÚœrÊ)欳β†¡+¯¼Ò|öÙg¦gÏžÖh%H,5ýŸk2€äz$_D@D@D@D@D@D / `aAQŒˆJ~`öùÊ•+m£].T{€ák„ fÁ‚vö3Š¿ K¶eÐ~ª(fQ€FÅÂ81ëœÙæ‰<‚fïêË¥lÚ@ˆ=¼#0J¡¤« Äç†ñåøºuëL¿~ýJîkxT­Zu+ñx`@˜>}º=_¨ãC± y¼yäóä“OÚöŸyæ™ÛOeðDXµj•õD@Áÿßÿþ×´lÙÒuÔQy èÇ8óÔSOYCÊñÇo½LðTÁ AÛ0zž~úéöÜÚªs›þ! <Æö¥ÿ—_~¹9øàƒíõ1sæLó裚‹.ºÈ®Ç`X©R¥Ø* ¡;î¸Ã 6ÌŽßqÇg ;xsèÍ7ß´õ\qÅö³U«V¶þØŠàƒ‘ã¥—^²†—öýþûï †R¸q0~É }:ÿüóÍØ±c-“ .¸ÀÖÃ8¼ÿþûCÆÜ[o½ÕÖ1ž!ƒs¯5kÖ˜O?ýÔ\xá…v"F,Æ,Þ1ÉÚ¤m" 2€dƒ²dˆ€ˆ€ˆ€ˆ€ˆ€ˆ€gAY,Hþ /a¯š4ibîÇûƒP$¢4$L3¨™itɶ ÚO(ÈÎu)Êø'žx­3xð`6(ì¶åR6}ûòË/­âüÝwßµF©ë¯¿ÞtíÚÕì²Ë.¡tÅ~›6m¬1%;†A®ÂXQðTÀ8æ çÇC=d¦Nj:wîlPàׯ_ß*¿1ÔÚiß}÷5§všCö‰5 ¸ºø„÷}÷Ýgø-=ôPküÈD™Ž' ,—]v™éСƒ5Pж£>ÚT¯^ÝÜrË-Ö€¢ãZl?~¼ÝއM›6-Qîsß <× Aƒl=xNaü‰5Ráa6zôhƒ÷Æ….]ºXÏXb×ÜÃ?lÆgöÙg۶ضPç!¯n¾ùf6‹ð]yþö·¿Y¯ N„ù"4U¢‚—ã{ÄG˜k¯½Öz|`T„?}:è ƒLŸ>}¬Q‡~3†Dã޹îºëlزgžyÆz²àõ“ɘœ£u"@‚ ¨:D@D@D@D@D@D@ŠŠ¡T˜}Ë'3åQ¨©äÚ02´Úoþ f_£eÖuíÚµ“*wÓ¥’m(ÝQÌ¢‚÷ùôÁXƒ J`”׫ÂV²æR6ç ä¨Y¶l™U@ãÅ@¨$æaÆœ¥:Æù„cJdpA¡bCÞ\¸,ÚÇyD[i3a²È²Þ»·“&M²×âM7ÝdCJù½½u¹ïxCà}g‚·œ;œGx€à©‚—OlÁãã÷wŒäéð¶6xqà=2dÈ> ãD¬!•PUäD9ãŒ3LÇM<¯Îôcç69Fðªˆý-Á ˆ0\0¿ýöÛ­ cE3}ëß¿¿ý=bßDwß}·½v.½ôRS¯^½­ 6ÔƒÑãÜsϵ}"tÞ‰òœ¼þúë¶½„Ãcǵ)‘|­\$—ô%[D@D@D@D@D@D /  h"DÑž{îigÑ¢ÌRÉ/™(YQîbø`7c†B>Û2\.Û™° ê, D açBèŒ4(¬Ãàímw.eÓ”Ýô—Yö,$½ÆØ•B^¼Rð^ y¹×8àÚÈuAž ”ô@Ø7Þ~ì‘o¼(‚:÷.¹äëIâ5~¸¶Ñ.ÖcàˆþÏ Ú„qCG¼vÓ?¼G…õÊ+¯˜“N:ixÖ +‘!ïA *ü¦0æ±…<)óçÏ·lHTÏÐ@ýäP! ûÆ+„ÛÂàsê©§šZµjmeüpûÓ§¾}ûÚ< @µ•¨ÝŸ|ò‰¹ÿþûM‹-â¶ÉÕ©Oˆ@¢0 jƒˆ€ˆ€ˆ€ˆ€ˆ€ˆ@^ÀøÁ‚ò* ³åó ^DË ûE‹ÙÖî'vöv²f¢§MvŒßm…"Ão¿Ýþ„_BQKX¼ȱÀ õD Yw\Ÿ¹”Mû;ì0óÎ;ï˜yóæÙîš(^˜¦ úšN(Êã…ZBON<Ë’«U«f»äbÁ˜¨`&ïK<S¢c´^rE@\‘—\¼%@þB`1cyï½÷ÎÛ~sà qÃLoÊ×_mãïó\ „³AÉd3fŒ=g¢*ãùçŸ/iIsmØÃà¶Ûn³áuP¬“G‚|;ñfÀ9NÔ•KÙÈ'a7¡“8?ñ@ ¹tó 1.“'O¶ž3fÌ0ܱe> t–xFúé ^$÷ܶt?1p¤[÷vÚMè)ú—ì^€¡K—.µ†xÆî/´ÞݔǃäñäXÁóF|r‹qŽW0ÒRi¡ßJë«3F^íßÿþw‰(žLŒ.È$Ù9ÎÅØ‚‘.^â÷Øýô¿DÀ¶gpZ¥6ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ@D  °BA†rˆYÆ,*ùG€PJ(")Cœ’ƒJ¿dJÏtzKÎgp‰¢ òL ì¥`hȵ„v4hÐÀ\|ñÅVÎLú°½néJ.eÓ×=zXóúQª;×¾\~üñÇ6'ù;h¡Ž;î8«¨'áI¸ý¯ý«Ô¦Ò¿ ¯·R…&Ù£†<&Ü="ÑîÜÿ1Þм;¼#yl¸¿ð›Á}…k‹ëF,ôHÔž¨8à ƆLΫÓî9"€‚Ùͺ7n\I8,Bö$RúeÒT¯Á%Š2h3Ñ)ñBñdÒ÷tE)^¡B…tÏè¸\ʦá(˜Y¢XÈW1xð`óÞ{ïÙœäŠÀCe>†DØñùᇖ“õ£4ï…ddž±°NôᬳβžGÉBK9ù„f‹õþxâ‰'Ì=÷ÜcÃD‘€A~7¼Œ0°ð’(Üõ²?×&Œt õÀùŠ+®°¡äè_i…¶&2ºDmÌJë‹¶7@Š{üÕ{Ÿ˜ÉK¨fÈcQÉO§Ÿ~z‰B‘øùäš 0®©(ýöºC‡¦jÕª‘•AØ+ò P¢àýa¢?‘$€WÆÞ½{› .¸ aȸ|õpxK`€KLJ‘œ°räï ”[¢|0JfL '† ï´'Ý$ñ¨0¤à•B.‘l„’‹äÉ«F%@ŠrØÕit  ØÂR¯^½HÆåO·_ÅvœW‘x饗–C˜)hÖs&ŒåäfpGQFÿþýKûìcÛI»ð@Kf!ôW²í±mÔÿ"uÛE½jŸˆ€ˆ€ˆ€ˆ€ˆ€ˆ€D‰ ,̨bbâ(±Šr[{õÐCÙ…YÚ•+W¶K*ánÒéád¢,£mdI¤ÐN§ß:&ÿài›ÏÂÛ Ž)™!0Y$þ^¶l™U¸'«Ï[w¾qÄÖ jìØ±fþüù 7p4hùÛßþfæÌ™³Õ~0Â8£d÷’Ê}ã1"Ù8)¯½öšõRsFÔXNo½õ–MÄ»ÞýOÈ?<ÝÈEĘ$*xˆËå”SN1K–,I´›Ö‹@^$¯†KÈ%åË—Ûü(ªD(•ü$0lØ0så•WÚeÞ¼y¾:ÁÌî™3gšéÓ§[Å'ŠÐ K¶e£àöÛo7|bàS)>$ÚFYB~ñâÅÖp ÎÙ¥ÿêÕ«·Ù…s÷Æo4_|ñ…Ý–H¹¿ÍYaû裶„±‚E¼2fÌ3qâD»FC¯Œð"ùüóÏ&R'Iü¨Q£ÌO?ý”Ђ‡MÇŽ­qã^)±å¿ÿý¯ ³…—H¢BbsŒ ŒíÓO?mÖ¬YwW’¶Ï˜1ö‡Y*"Pt&Â(ª" " " " " " Y!€òˆðW„%!ÿ‡Wá••HH`¼IÉͪN$ìí·ß6wÜq‡=˜¡}à 7Ø<‰öOg}¶ex8­ZµRt-Ï!ì÷µ>øÀ Ü'lR“&MJ<‚Üý®{÷îæÝwß5÷ÝwŸ5’üñÖŽPW$F¿÷Þ{­'aÕP¶ã AØ¥|)3úõëgfÍšeÈw²bÅ sþù盦M›Ú0Rôà ιnèg¬7`óæÍíþxnp¯`Ÿƒ:ÈæðÀÀøÌ3Ϙ—_~ÙzZ`PÇXm9õÔSÍ'Ÿ|b^ýu›SäÌ3Ï4íÚµ³†ÆaĈ¦aÆö~„G¼B=çwžíÓСC­·ù[0°‡ã>IÛÙF¸.Àã ¦"…@@BEõAD@D@D@D@D@D +\þ”]J€žä¡ a64±ù)5jÔð%%#³¶ ³råʒܾ*)eçlËð6E¶JñÀÀ²/¼ð‚õnÀ“<5Ú·oo!:u² r ÿØF²nBÉ¡Hg;9o¸6ñ´téRC^‰|*xøÝu×]Ö³bôèÑæ?ÿù©^½ºMHN) áwÞy§éÒ¥‹õöðö¯|ùòæ’K.±2.&L˜``‰!FxÐàÆ}O²?þØz’` ‰M_·n]k˜¸âŠ+¬áiÚ´i†ú1Ü26ݺu³ÉèÉïñå—_z›±ÕwŒ9®ºê*óÜsÏÙ±¡Mä!“ºh—ë,s\;ËqŽ[¯Oˆ2y€DytÔ6È ÿ!°˜ñOl|”L*ùK`ܸqfÑ¢E¶„¡ñ‹ð3,a–B‘&#Õ”Ûx}”VP¼³$*Pö'*È)MážèØDëQâ§R’µ+öx×Ït¯yú˜¬Ÿ©þ–À“}íï§O®<ÍüŒ.ÎÀåç8í+¹$ H.éK¶ˆ€ˆ€ˆ€ˆ€ˆ€ˆ@Þpá¯!¢Ay3l :lØ03eÊ»p4~ +Íã ä9 93¥wïÞ:Çóx,Õt-¶ÛòUßD@D@D@D@D@D@D@p’Ÿ+z"Jù³þ矶IšIÔÜ«W/SkS<}–—_~Ù†… º'䈲Œ#F˜ë¯¿Þ.óçϺûªOD@D@rB@ 9Á.¡" " " " " " ùDà÷ß·³ã ƒE¸¤š5kæSóÕÖ8ÇÆÛ-„ÃZ°`ýNîbâ]~øá‡HËÀ ´jÕ*Ûmò¨ˆ€ˆ€ˆ@!¤FQ}•ÀÒ¥KmþbÀãý‘J|üP¤Ê3&0pà@CB_ʧŸ~Z’$ãŠó´Â^pÀ¶õ ñ–§ƒ¨f‹€ˆ€lC@mh…ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€lM€Ü$@ÇóãÏþ³!­J~ð±zè!³zõjÛ¡ $L2œIï»ï¾HË8ùä“óüØu×]3骎È$2C¡†ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€D•ù?0‚àýD%ÿ öjÑ¢E¶#Ý»w75²ß·ß~ûP \„Ûr¡µ¢(CFü?§Õm Ȳ-­­¸èíÚµSô­Èäï?=ö˜™2eŠí@³fÍB7laô»d"côèÑÖÈG ‡¥0Xa–êÈ@²AY2D@D@D@D@D@D@ò–¡‘0€¥p•*Uò¶/jøkÖ¬1+V¬°+\.-[“›8q¢3fŒùñÇMóæÍ á£jÔ¨‘ü Ÿ[³-ãý÷ß7Ë—/·­lÕª• >ÇK»‹€ˆ€D“€ ѵJD@D@D@D@D@D "“„7!°2™e‘.©›ôèÑÖŠâ×xA>˜ &˜ ˜uëÖ™ž={Úz‚ü“m6l0¿ÿþ»í‚ËdT—ˆ€ˆ€ä‚€ ¹ .™" " " " " " yCE4‹òäÍ¥ÔÐçùáMˆžÊÁ~ýõW³~ýzƒáÀåöHåØT÷ɶŒZµj™öíÛ›=öØCÞ©’öˆ<@"?Dj ˆ€ˆ€ˆ€ˆ€ˆ€ˆ@. ¸ü;v =OD.ûYl²ý=¼|uå•W£ծ]ÛT­ZÕ»9ïÙ–Ax·¶mÛšJ•*%DdU‰ˆ€ˆ@ÈAPD@D@D@D@D@D@¢I`ãÆ614¹þüç?›š5kF³¡j•oãÆ3„7£ËO¬úõë[Ã!£‰V¶lYßòK; W2Ê”)SZÓ´]D@D@ò†€ y3Tj¨ˆ€ˆ€ˆ€ˆ€ˆ€ˆ@¶ ,^¼Ø†¿Ú}÷Ý­$ Ew¶û$y› <öØcfÊ”)öŸfÍšù2€ì¸ãކ%Ì’m$uÿþûïm—zõê¥0Xa®êÈ@²†Z‚D@D@D@D@D@D@ò€ Ex r€¨5kÖ˜+VØ9Ò|ðÁö{×®]MݺuOvï50DQÆ“O>i&Ožl´lÙRÂ9ÕÕ(j2€õð«ó" " " " " " É`!zãÆ•ÿ#¨<ÜFØ+Æ•2~üx³téRûC Á mdÁÀàp¹­pàÀæ·ß~³øôÓOÍW_}e¿“÷…±º``X¹redeöjÿý÷·íÃãIED@D@ € …0Šêƒˆ€ˆ€ˆ€ˆ€ˆ€ˆ@à–/_n½?ð :y@T ‡Àn»íVÒ™#Ž8Âìµ×^ö”ÿA{Pq‡LÕªU#+ã”SN1Îóc×]wµíÔÈw)@H‚uÈ!‡ä{_Õ~ÈråÊÙ™3S§N5;í´“½~üñ­ä3«hÒ¤IfÀ€[­/Ôý×®]k^zé%sÅWlÕß]vÙÅüå/17ß|óVëµÿfâ³™ƒÎÞ„·ìÕªU3óæÍóâ×w(^x¡aIV\þ5jXH™2e’í®myF€÷“E‹ÙV÷íÛ×ð»GÁ0F‚ó‹/¾¸Äã$Š2dô°Ã¯?" " F %3,XP`]WwD <@jÖ¬i¯ õë×ßF.Õëם߿Ú*äýqù޽—ð½lÙ²¸|´¿1â³ùÔàzÑù óÁÝ(t>l&‘ûaAbïÛnô)" ùNÀå:HÖ&bÁûC Г‘ÊÏmÆ +ÉÉÁÄ£>}úX£XåÊ• ˇjC  cž!…¾¾B… ¦mÛ¶æ´ÓNSÈ·ü<­Õj)@bŽÑ¿" " " " " " "PðH~ÎÒ¢E %@/ÀÑ&¯Ë† ÌôéÓ­¡ƒ‰Y.'“o0€1 ÑzÎ ö)[¶¬ÍíQÚþ‰êI´~ñâÅ%*xª ƒ\¢ýÓY!p‡v°uÓWÁOž<Ù~øá2€à9¯.‰€ˆ@1¤G]}HJ`ݺuVÙ¼zõj«®^½zÒýµ1ÿób»í¶3sæÌ1Œ³ß‚ç?9=öØckDð{|iû† or“2‹¶]Ê—/oûP©R%›÷ƒ‹Ë´<Õ'" " Ù& H¶‰Kžˆ€ˆ€ˆ€ˆ€ˆ€ˆ@ä ,\¸Ð@0|þ*Œœ‘‡Pà $œdÿþýmNBþü_±bEÛkÂ^uêÔÉJ[aÂÏþð³? Ù{÷îmŽ<òȔړNý'œp‚éܹs‰ácÏ=÷´ôGD@D@ò€ ù>‚j¿ˆ€ˆ€ˆ€ˆ€ˆ€ˆ@à\tåÿm¤*ĸÁ[´>–ˆþü$PfS"Ñ?Jk:q kÕªµÍn$#6d” 179ä¸MŠb{ã6T+óž@™2eÌÎ;ïl“œÓ\£«U«¶M¿p«'Æjl)Äý¹Õ¬]»v›„ç°"á ®ÝÞ¢ý7ÓŸÍt>è|Ðý!7÷Ob‚oܸы_ßE $f‰-$fQÉù0–‰ÚxÝu×™Áƒ'„=bÄsýõ×›6mÚömРAÂ}µAD@D@D@D š2òÁ sŸ}ö‰fÏâ´*ßÚ§ ZU`0tø¹†òyù‰fQÅVíÊ–uâ³…E¼oâÊ–uâ³…E¼oâŠÖ‰@°ˆ5¯zÆÏ³Q¼:´.»\¸ X©ŒqTÆ2QcÛìýŸpHx€„š‰t5kÖônÖw餓Ì|`wŒÂúC=Ô´oßÞ¾CôíÛ×LŸ>ݶOþ§Íż>vDáFñ¼bÛû?^ÚD`ù?ðXVÈ?y€ÐÝßÿݬX±Â&‹Y>$Šã“Ð>“&M*Y¿fÍK'vÿtÖcÀxàâÖŸl8εíí·ß¶m+[¶¬yùå— Ûhsië“Õ¯m" " " " " éX¿~½ !Ê»Eݺuͯ¿þj+cý’%Kìó{¢õ;í´“™5k–a‚S*û'ª'ÑúŸþÙ¶eÙ²e¦víÚ%¡N‘õÃ?ضãúD•¿ùæ;9#ß?üðCˈDâLšËæúU«Vù>)ñþøî»ï¬÷9@ðTÈ?@b»ÌÃåC=d #î…%vŸLÿGÆ-·ÜRòB”j}G WŒ0®m¼°¼ñÆæÝwß-u=!´x!úÛßþ–ªHí'" " " " "óæÍ3sæÌ)1L-’I_*©˜?¾yòÉ' ¹„~ûí·’qÉÕúÔ[¾yOŒAðìÁ¢"" " " "Ÿ2J‚NL×¹sç xPl·ÝvfåÊ•vÖ8öÜsOóâ‹/š5jâ®V¨PÁ¼û§³ž—DŒ—^zÉ&¤£þD ÛíÎþ¡þK.¹Ä\pÁ¶/V§ÃE@D@D@D@D ( 0)‰¤Ò±å²Ë.3]t‘U–ã©Í»ŸLZâ‚ÏØõÔÅä( ÏéÔË>‰öOg=õ¿óÎ;¦C‡æ°Ã3íÚµÛªm¼1Á*¶mŰþî»ï6·ÞzkìPæÅÿœ+‰’ 9€s‹ÉoìWµjÕ¼è“)" " " "°5¶þ×ÿ=vß}w»ptµjÕÌäÉ“mE¸¡ã‚¾óÎ;—T»¿Ûàg=õ%“áêŒ÷Iéc=ÖœsÎ9ñ6—¬Ã½W¯^övyäkÈaö†` `@¨^½ú6•²ž%¶°îì³Ï6Ý»w·›öÚk/›³¯ƒDû§³žüUªT±r6l¸Õû õ1ñ+¶ËúxKÐåË/¿4$bÇÄ;¹+h9ª/H~N,"0.Œs*=U+D@D@D@D ð oØÄ, £GìP¤+ƒäu,¥»¤‡7Ýt“mÁ2€ÄŽˆþìËèáí žäyüñÇÍÿþ÷?kñn×÷Â"€÷ËÞ{ï­ü…5´êˆ€ˆ€ˆ@Åâ‡ã/¿übFm^ýuë¦Þ©S'sÒI'ù©"+û’8¾<@TD@D@D@DUÈæð@IDAT@D@‚%ðù矛!C†>Éù׳gOÓªU«@…P÷˜1c|Ë@!>jÔ(S¿~}@‘èUÆX㻩 Go|Ô"ðC ç7šÙ³g›qãÆ™]vÙ¥Ä}ÝO'²±/y?.¼ðB+Šœ'*" " " " " ÁX¶l™ 55iÒ$›KðàƒVÀ¦ÚÒ•ç“·Hv®R¸ðöÁòã?Zãa°TD@D@D@D@ò—@Î  Ã²~ýz–ŠïQ,x} <Ø6M1`£8Bj“ˆ€ˆ€ˆ€ˆ@¾Àë4ï|btº¤#£}ûöæšk®±Má»JáX´h‘5€øüOú“r¾îP«g" " " EB ç²eËš=z؇ËwÜÑ4oÞ<’è1zTªT)’mS£D@D@D@D@D ì»ï¾¦sçΦ{÷î¦jÕª¦iÓ¦w ƒ ò%ã?þ0$[Ç#¥^½z·IF‡Þ,„¾"ˆŠˆ€ˆ€ˆ€ˆ@~Ø.×ÍßyçM»víÌ™gži `Ú¶m›ë&Å•¿zõj3tèP»üPED@D@D@D@D X{íµ—9æ˜cì»AïÞ½m`%rׯŒ÷ßß¼üòË6' ï/*…KãÇwß}§è…;ÄI{Fž ä ºì²ËÌÂ… íþŶ>)$m<#sxñõ‰U«V™ë¯¿Þ/³N;í´<j5WD@D@D@D@¢M`ûí·7åÊ• µ‘éÈ ïy ™E-…Á uˆrV9ž>$?GéÝ­[7%@ÏÙHdOðرcKŒÇwœùùçŸí9€Œ|A. _±­ÏÞH’ˆ€ˆ€„O pžÎCb·Ýv3'œp‚á3È’‰ b ôÑGÖ“#Y›V¬XQ²™‡‘#GÚ_¬$ˆŠˆ€ˆ€ˆ€ˆ€ˆ@î LŸ>ݰPößëQÆä*ã̯_¿¾ ¹öPZðÓO?YïvÚÉ?*T¨ŠUÇ7S¦L± âþQì…{\™2e,†>}úÈXì'„ú/" B pˆ×S¢Fæ¨£Ž Ü’‰ Ó¦M33gÎL:„ÌìrƒËOdV«VÍì³Ï>~« }oÞ‘Š+†.OD@D@D@D@D Ø¬^½Ú|þùç†Oò “=öu£ìö+ƒcFeêׯ/H #Ê”ÿ#ãíV >ÜL™2ÅŠmÑ¢EÑ@¸Çq-P‡¥0X…þˆ€ˆ€ä9œ@p5æ¡cذaö%§ÿþfðàÁ‘úÛn»™ .¸À¶+è—°ÈuV ˜5k–¹úê«ÍÔ©SMÓ¦MÍßÿþwÓµk×@[‚Œ;î¸Ã·Œß~ûÍæ øõ×_mO¢Ê‡÷z*žÎ{]³·Ñ,}=.¿|°Ù{ï½K?@{®•+WÚ¾pÍ{yúé§ÍäÉ“-†¶mÛÊRì'„ú/" B ç\Èyè ¯ìkÖ¬‰$Zò€\wÝu¶m„ÃR–ÀÆÍŠ+ì»Á^{íesn+Á˜tdò à %ÌðW¼†é7Þ0¯¾úª9ì°ÃÌ AƒL²¼#ó¯ýË.(,{÷îmš5kJ2ø Ç"*õ¡øvQ ˜ñŽç‘Jq ìÆVJ±‡¿‚º™U«Vñµ$ˆýGD@D@D äܬ&Œ úÓŸ¬ߣX0zDµmQä¥6‰€ˆ€ˆ€ˆ€ˆ€_(ú+T¨`ß HBFndT­ZÕ— Œ ¼¯àP¯^=¿ÝJiûÌà)OèÝ… š:uê$¬céÒ¥æÓO?µa|>úè#CNƒ˜>,a#ò|á˜1|¸ G·[´hQôQ£Fîu”>}úȃ̒Ð|'¸„ËC9Är!qá /¼`ø ²d"—ðaÆ™1cÆ$mÒÿþ÷¿’íÄ„íÕ«—uwoÓ¦9âˆ#J¶é‹ˆ€ˆ€ˆ€ˆ€ˆ@î :Ô°PðÒ&¼.¹‚.ä `Á$È2qâDk¨ îí·ßÞtíÚÕ†Ûÿým.ŠÒ¼7ÈWQ·n]«¸ç]åî»ï6Ï>û¬Y¿~½™:uªyï½÷¬…ºU¶%€÷ ^6äyÁÓ÷Ýwßv'­)X$ýv].‚íl {úé§­1•]¹Ÿ(H д‹ˆ€ˆ@ä nÁp@œZ ^CBP42‘ÁƒíêÕ«í’j{‡„©£Ž:ʺ‘§z¬öù3ÜûÊlçE´ÄfÍšÙÐWAzlܸѶDç”V­Z™3Î8ÃN(#Jªe»í¶³ ã6lhN=õTƒGÃøñã lPîó¹Ç{¤Z]Qí{&ØÕ¬YÓ@`©R<{Õ´iSÛáb BÜ/(aèrlÅú#" " Y&¸$ËíϪ8÷bÆŒ²¬vDÂD@D@D@D@D@| 7Dß¾}MË–-}—lg•ªÊ)Ûµkg:tè`ü?¼õãåAûÚ¶mkÞ~ûm;! £‹ ^R[¾c,ÂH¤è[˜Ó·Øë„>+ÿÅæ°Wî'ïbºÔW(l@öÜsÏ—Iܵ«V­8ÁLd”+WÎ{ì±¥zq¸°W4ž>Üyç¶_¼¤[—™U*" " " " " ¹%@Ø«N:ÙFz7,%æ/¿üb ;ï¼s`ÆøÁBa’^™N¶¢}¼/aðXºt©áý…E%>ŒAðÀ¢R\º_ä+Å~ýú•dÅ&_GQí΄ÀC=d>ùäsþùçÛüZeʔɤº¬KøKò}ôÑGöùèé§ŸnCe¦Ú˜3f˜çž{Îz¥â%G¨M•Ì ÜtÓMÖë÷†n0Õ«WϼÂÔ@»×_Ýæ¬ëر£MfÅmBฉéÊ;.¢$G:2ðâàÅÈÛFW÷ӹѳCN­ZµÌ¹çžk8žc@¼´ô]D@D@D@D@rC£Ë9ȳ:KeîܹfĈ¶ê Â`ž×…ì 2|0uzëUnƒøgŠ"Â_a b¶»B ÅçTÈk_|ñE³hÑ"ÛE&Jû9 £G!Ÿíê[*&Ožl^}õUs 'XH*ÇDe~Ë.½ôR«&ôÿ.»ìb*V¬hs»6¢ëœ6mšÍgÖ¤IÓ¼yóm¼N™@ÞdŒ?ݺu“ÄÁËð“Ф¦£B1€Ìž=ÛŒ=Úì»ï¾6|k“„2ĽÍáÁ['6‰ÃèÛòtep³”v|ìv^¤¸P¸¨ˆ€ˆ€ˆ€ˆ€ˆ€äž@˜FoïP”9ÒÔ«WÏæñnK÷{•*UJ<æ×­[g=~üñÇ’uéÔ‹RñâÅ%^ÌÜÔìÍø$âBœ¥z,~íZ›{ì13eÊÛTÅn5j”5 ¤OŸ>J‚ž'±Ú(_ýÕð{ì&ZyÈ•áµ1aÂ{»öÚkí³ FÍjÕª•Hþì³Ï Û–-[fÎ;ïnÜ8ëžåÜ×£†­R¥Jæúë¯·Í Ë­>j}V{D@D@D@D@D ›˜‘ÈlìI“&™fÍš™ƒ>8pñéÈ8ôÐCÍUW]eÛÂ÷  ^ç„AÀB¾BosBSø-„¶ _á[o½e%üa Š}V{"ŽÎràÊ’R¯'ì•»ÖtƒAhÕªUvÔ1ʪˆ€ä¼ñ\áù‰çŠXã=iРܽvíZë!åEùC^-Í97€ #®@¼ð=Š£FpðâÎìDz! \:2P"" ƒLݺuíü`PÀãO^xÁÎÊ$ÿ`»ví¬—|iQZ¾÷Þ{†p>o¿ý¶=žc6lh!±á}K«¯X¶/\¸ÐÎ~íÑ£‡ Å2è1ý8p õìbµò_l{Õ²eKKIÞ1'‹þ ž ÐÑÅSðG¦‘9h^lp!ºN¢‰Û„¼ºð íoùŽÙWEŠ@Î \løàÊã…ý86H•À#ÇŠð`·¤üÎñ`äH¼Æ}kðýúõ+ Ÿ'6[³Ñ¹%ðÓO?™ÇܼóÎ;Ö³ñïÿ»©]»vn1é©„³Bïª|W85'+rná‚™MÌ2ÀzÕÙIÄûXD®©Tõ|ÔñÉ'ŸØßC<ëÕ«gð’\½zµÕǽñƶML ˆŒ0þ|ûÛI»Ë—/Û¼’ÿÙßYoÿJ6úüB»È»ñÍ7ߨÐqä ®S§Žm3§“•t9ÇÖ‰'#“"ðneÜød\îb®é=÷ÜÓð¬á ÛyÎ`Bˆw½Ûîç–LÄ ¹:F*Bl‚‹ ‰¼PüÔO[9/àÊ3!Ï><11…‰œ xæúy^üøã “N`Ç9Îsž¸œ«ñÚ «ï¾ûÎn#?]²ó™Ü*<»Ê4‹/¶é"h'5pÀ{ÇÏx¡Çæ’𨜫œplÕª•¯zËøÂÐj­[·¶×O¼û€Ÿ±Íö¾97€Ðan\±7¯lƒ(M7—YED@D@D@D@D X¼L9…K°5o©-]ä‹9r¤UÈi¡eU«V5„âá}ãùçŸ/ aEx`K’ãŃʥ—^jð ‘b?9/”`,*ÅI€°q䢠`*v÷³”N8AIÐ-‰âúCîÛ©S§š'Ÿ|Ò´hÑÂæ¥>|¸U?ûì³q½.PRß|óÍ6ÿŠV”Ô(¤QÖbX¼ä’K ŠãdeÚ´i6ê Ÿôn(öÝoÊäûî»Ï*oQÂÆëøÍûðÃÍsÏ=gÚ´iW¡³hËœ9s̈#ìDì¸;–²’þq<)sçεÚÉÂ3€‹/¾ØtìØ1á3M:œã5ë–[n) ¡‰‚çd;EùGaG;\!Ä& íwß}×*ÄÝz¿Ÿ_~ù¥Í†qŒ„êðE.ËI'dŸCPÞgRhëW_}eÛŠ"ÿŠ+®°'&~`¬@ç){PîÇ3`8ù>8O9Ç\x&BðÜÄùvÊ)§Øü(±Æ+úÅ3ϯ¾úªiÔ¨QÉyéêvŸwÞy§}Žc|?þxß!Æ0(1æ‘G±‰ê1þÐ'tæôú1Ö$3Âpp­<õÔSCŠ«ƒó“ãp@¸úê«íg²zèÓ+¯¼bn¸ákÂÄþ´…°´~ùR7€p³ã&@á¤áG3öäÉN&2x,´C‡MÚŒ+V”lÇòÌÌË ®ï*" " " " " ¹'Àì6 3Û¶mÊä*çqÁËiÐ…—[fM2ÄæíxôÑG­RÅ^JQºà©N1B —öbë§þBÝï~•â$À»¾›èÈ5^ì…ÙäÉ“-fùF%ã„Åw¶'ÏæR6Á,u”ýèÕ’)wƒ:wÑ…áÁ²%ê<`eãQÈLûØYß®ºê*3sæLÓ«W/sÔQGY#ÉÒ¥K­1⥗^²Šão¼Ñ4iÒ$nPL£Åó‘ÐVGy¤í3 å~øa«HF‡8^a–:Ç£óKV0пÒöKT“£ï¸ã3lØ0Û—ãŽ;ÎtêÔÉê Qª’’ßpõ|2ÛÞq¼uúåì=Öû½[·nö¹ûŠóù›<\þú׿ZïöÃcÇyƒ¸ã`+ûéòŽ]tÑEVÞé§Ÿn:n2öð[ЧÞ²è…i JróÌ3­1…ñ:üðÃ­Ž—´ x6 #¾ûî»-«“O>y+/"<ŠÈ©ößÿþ׿YØÏˈk†¦x`”ñ{¯âœ<ûì³ÍË/¿lÏ'¾sæÞ‡Q’ë ÿþæ®»î²ç\¼ú9?9÷0V’Ç.ôïÎ9 ÔsÁØk O­D…q¼é¦›ìõÒ·o_Ó¾}{Û§‰'Zƒã@xÖ|1‚na†–. ³'¸ùmÉD'Ö>nÎÉ '+œl\HÌFc6ÕYgå6éSD@D@D@D@D ‡xc$…çôt^:Si>ƳÜѳÚ°?Ù((\™Œ‚ÙïxÊÅêöPø>øàƒÖ£‚qaÆ;F*~ÏP¾ <Æç؉'žh v®Î3ÎQàzǃ“FqtS%§ýD@D@D@D@D \<×»÷^ÊÃxÿ (˜UI耰 ³{yQE!‹‚YˆÌØ#ij5é'(„”@qÏ‹>µ8N†#ƒ"Žq7[Ô_MÚ;_  Lrž\CÅ^ˆàAxJ¼?˜µÍLò>øÀ*ïP<}ôÑV‰Žb0Ì’KÙô £ W<P¤âƒ!{Ø…ßQ¤(: ×óƒ6Œ;Öz õèÑÃ.È1à”¾üžñ[…’”| ([Q̳ד…ðY„8BéËï+³Ö]¡.Œ.xŸ0sz8GsiÁ#E?ý ç5 ó[Â}ƒç*ùÐ%&2€¤ÊÙñˆ÷‰qÃ8Wž â)µãŸÎ:Î <ðPÀ›Âkp@gŠ cT0`2fpqç†_™(î1¦ ¥¿«‡q€?²Ü¤ $œGÞßuÆŒl(ÿ1¨aXp¬h üxîâú?~¼Uú3™Ä»ÞÜ1Xa ÞíÔóúë¯Û<,Küò§0ö\wÝu¶­®|Ò~Œ]i¸p=1é'öw ÃÏ‚Œ 0Z¸B=è³12â9Þ)ãµo"rÿÊ Ã&×­+Ü{©÷Ö[oµ)<§æC ÜhÜÞ(ÿ½3—jìãøõÚì{×R¶RŠh¡„’È–¬©×ÖB¶J*oR²T–()^’¥²¤¢¯(…H’íµ¶Èæ=ß'ç¾§ifîÜ{ÏÜÙ~Ïç3wæž9çY¾ç9sÎó_™©¸)•¦ .LìD×54j~<°ô½ÊO~¨$è‰èé;(„Äð×xB'fqzèÇ·ö Å9¶¸û²HeQË‹Å=–‰,Š1£°èf]Ã+z^ܶòy…¿Ê糿aìÑ£|'Bx„”L`Ãï.d¿O(¹ñŒÀS%²¦àùOgÛô¡¢¯ÔGPŽõz]Û}ôQw® ‹/Çshx!¢ Wd¹%-={ötŠ‹Xs c„ô(P”‘£#h¸Î|ó• (£b=7ñ<…Aß‘ëƒyÊ5àÎ7ã!$Ü+¯¼â1AÅŠŸ¡ b~÷÷ Ï æ7Q”xæó•~û¼óüI¸±§žzÊÆŽë¼Y¢§Ï8ã §€C‘ì_°dâŒw¹¢Ì7~Ïï ×6^$þ¯W?8qÍòP6”Ð (=põ¢$¨m HiÚ` ¡$¾n¢Â„÷ Lâ£qA}üñÇ.ư ‰èé;(X²n€Â‚³4 ìD=ÆJ«Gß© ƒ«}ÖT¼R¥Ø‰Õf¾l“$_ÎtüqbawËÚèð<ñÌÍo¢…ié%y ¼xûx F6ƒ¢;žà9Ìþ¦³mƵ÷«¯¾jÜ{(„4BV(÷Öx‚Xú€2†k‡ßQõ±¶ìÇ=ëzÎI¬Q`ª‹œŽ¼ ñrlÑ‚Zö ¥©¿¬ ÏÑÏ'Ð<P\‘ƒ>óLâ+ïbõ3αŽKç6£Øeþs'Ržp-!ggœ±”ü†GÿŽ3–o¿ýÖÍOÎßrOñA[ñƉñ?ó…¯,‰ÕwžKé ü³¡„®aà©þQ.M\„hb‹ê#~¡=N*„WYiÝýöõ." " " " "›Ïö¼R]0"d@õêÕËTâ A ‹]¯Xî±>a‘Oøà§÷ø°H奒¿ÏBL ‚õ|W€ƒá&ËÞt‡ÁBGüyB¹ ¬Ã›¤À:S]ÒÙ6cCØÊo=óOG,ÃQ6”Eá¾Ò¸qã˜Bc¿}„½Ü“¹Có Å½¿ÿŽpå@,î©x @æ{ÂE º±Žçx’£'jÇo¯,Þ꣠šáåhyÿý÷ݽ% ÞñŒá¼%*ÉpNt|:¾C‰…gÏD„›Jt-¾ Ù*Ç À,M)êY‡kƒë…߯X^ ´Í|ÅŽyóæ¹¹‹Œç¾V•ç­X…sä¶!¹>+û è©EzP1«žXÛPJÐo~sG¼Âw„çÂ8Ÿk¢ÀSÇÚŸ9‰G aÈP®àeEýŒ•sÁ³d¼q¢Àc<¯ŠR8u^â#ÛãS-£Þ0ɸpøÑäGn§vr?xeÔ|ÒÍ ­&Ã=¥$Ú¼¤ÒŽ" " " " "§04"ä,ï, N‡ýìMÝ,‹Û G^,–Ë¢°Fb¡Nì{ú‹`a} °è† Â-`-ÌçhÁQYô5[Û@”ÈÒ2[Ç¥~'O‚ Šm%tîíIlùÙ³g»¡hH·„Ž·ÿꫯvÂ:,ïËÒ.m3VBK¡ø@Éo•/l-‹™‡aA¢öP€ø¹u¹Ÿ&p#tExŒr#Z ŠBƒ<#½{÷vɬy'ç™ã,¾A;J¹`.‚²àÝŠ8òÒ <åÞŒškkyÂ+ñ¢¯×_}ô¡1ÿ/Šs̃Ҹá8¿•œß #^w8„IB±œêgdÉ´§C,¯lD"Ì9g$Pg>ù/~ÿ0t‰W˜»xF½óÎ;N‰‚‡Ϫ<¢Ta.ÔªUk“9¯¾àvžùàTª¿~öÇŠ§c *@PÂÜyç.ù<ŠG~Úz!èxžöç'û_xá…Á*7úŒr'Ù¾lt`†ÿ“v'gôèÑ.Á‡˜“}úôÉ8l¸Zúa³Ý2®ãꈀˆ€ˆ€ˆ€d bœcIJ’Iâ/“زeË–¡öž6† R¬6yÕ«W/×T‡¿Â p„ .Á%~,¬YˆòB˜,_H²Š€høðáÎ3…¤ÎR-lö#[?g“åb¶2Îô~#`ö­´óÝûƒs…BËuJ,!¢û¢Œÿð[–.«ÿt¶ fµ¼2± ¿ƒ÷ê¾}ûºpYEõ¡ytø2~‡ „™¤êä•À+A0÷8/êׯŸSö—¥,Öx|ðA'`füÆ sž2xd"T†ï(P`b)× çs†WÖ€’2RAqêkž‘b)ð@!­ž(Û.¸à†¹Ä /ç$æEÉ{¹gpÞyîj×®S€ \a®"Ï.é8ñ8ƒ+ÊÄèg½è9Äï4ÞŒ•9,ôœxÄÜqÇγ‘ºý¹É;Æ4‰®#?¬ ”¢úl;Ó?§]ÂIãäáºÃIaÒfbá"@ ¢"" " " " "Xú¡2pñO…·EIÚ`QŠug£F\H€TŒÃ0,GŽéB°F*JÉ \^-±ÈźñŸÿü§KŽÉ"VED >Ê¢\¤ È÷‚…}½zõ†LðþÈ÷ó‘ÉãçW ÷l”X¥—¤ äÞ÷öÛoÛ…žU:óa2–üXé_|ñÅN¹Ï=8ÝÊ ¼ÇýšÐl„äbìÑù!Ï ¹XüPSß}÷ ]VÒó6¢ ñÌ„—Q´pŸçª%K–Øå—_î"û0wcŸXÛ¢û¹÷Þ{»yIè3<%Ègóâ‹/ºç0y±æCt±þ÷C_ñWÔ³ž(lï~ùä“O /¶áâçEñ¿÷ß‹Rò` @\‡þýÑ?6›ßÿO*M£`‚¡Xàd3Q2UÉ€b·; O~˜UD@D@D@D@D@Â#@جçXટ am`MZœ6ˆ÷LX,Å9>ìÂZƒ,X°µøÕ>B$Bs÷yРA. Š…xŠEKÛD`)=6ž X0û¿?b³1ý·1îÑÈÆ,£°OT0<@èm­Î1(íxàkÕª•uèÐÁYµû^ìÏ=—WQB[êâ>˜¨`,àÏïDûÅû¯L_1Ãó@‹ùûøï(@hS§NuÊòw\{íµ%E½gœq†Ýu×]öØc9¦Ì±XŠB¤2‘IG_+Œ“¹_µjÕ¸ã¤-Î^Ãðˆ5Næ- IÎÆ97Ýt“Û—cƒ…~L›6Íß·gêç´+@Ãg*7aBgR°Ð p1¨ˆ€ˆ€ˆ€ˆ€ˆ€„K€…i<«·°Z*i,pYx’P2LŠ•gžyÆ…½ò¢(;œwÞyÎëÄ· d1Œbˆý|ËR»Ä·F‰òè£:¾G1BkÔ¨á”(añS="KÊΚ5Ë ‰˜öx†åsAø†åÜsÏuÖÍùÌCcOL€Ï>û¬S¸s_$'÷«`AQϽ OJrTE[­c”°ÝvÛ¹à€œG= /›6mêºG?_~ùe{õÕWÃì®êœ"€‡gQ^þ5˜S,æ`ðŽ#Ù4¯åžGšŠ$"€B [·nNAÀtÔ¨Q.D”/ýôÓÕG*ÛOgÛ©—êtà¹Þ_à]˜ŠõcÄ:°mÛ¶NøÖ˜Y8“ÌáëX<@Š£üö K¼FPÖ |¡^êg‘/án”>‹À;v,¼þÅôÏ^XõbüI‰%¬Îùâ€÷u`ùŽaÁ¾ûîkMš4±ƒ>Ø ©A.÷^’DÇ*þø¦G÷—ýñ¸Dð;}út'üÅ`švêׯïî½;ì°ƒ¢£ G Ê—XÅo'YαêˆÞK à¨À E^ ±Jƒ œÅ?Þ7±íÃï%F!3fÌpçœdö}ô‘SÁö¤“N2ކ«ŠÕV²Û˜gxÖ0Ÿð0™3gŽ s†>Š3Q±”Ôϱ×\s›ô÷ý÷ßw†2„=之ç;úÉóÞ$x¥Ðày ì{ôÑG'5΢¸3ß8'x© ÌC¹€7J”<Ìe‰îUx)¥Æ\7ÌÆ +??Þ0xU¡ÈˆWPø¶®©§ì÷ܹs®w^(Wàν‚6¸æ3¹„®ÉäÁ–¶o\LhÜÐráÃd0ÙâîSÚñëxƒXZøÂÜWyH.‹B›Xù®È©,él;•ãRÝ" "/°âDÁRRåD,NÔéZ± eO ëøXÛX¯ Œa‘Ë=ÎO–.H,ZÚ–ï ’ò‘ –оYlòq˜³gÝRœEܹw! ÆK…ò3ºÌ£XŠèâù²á,xPø%ú^‹àËxŒçX»ù÷NÞÀÒ>†ô:G°.„ÈÌñà¶`XÇ'?ãB WÁÉ'Ÿ·„Í­i'Öø‹j'اd?3öDcóëAaÀ~(bžEðn ïñ” [öãÜŸp ÷TxR'ÊkDæ+}Œ7ŽàØ8…óŒóëËüóÃsç”1Ç›~(À–{J6”…±Ânùûß‹âξô…ë% ¿¯ô‰qú} ÖüÌ~ôçì³ÏvÞTþuÀ±Ás‰ÂE±ãúEé·ß~û¹°W´d޲‹óäìO&}]BÂ>4U@òv)Mhõp©#¶Z¢‚— ˜Â°Væam*…ÅÏ=÷Üã´q¸ÐÅÓêºõGD@D VXÃ`]AÁê Ìp"… ÅøÀüã‘Á}Š6–©.él;ÕcSý" "N„½Â“‚{?îú©(Ë–-s¡XŒ†uß .dYP²Ð,jÑ]ÔØ¨‹M^(@â@ED`Sx¯\¹Ò}A8¬|WJé±éÉ·-܃JrâÞSÜc1ŠÃ0cƒÂÙXÌÙ‡0>ì_à)CâYèÕ‡¢ÆVÔñ~ߊ‡ÕŽß^2ïEµé×°:Qá\u>üã9/ÔWTþþ¥}§_%ýJæÜu^é?žÇȃ1¬DNTÜ%_q%Ó×DmŨ8õ'b^œ¹’¨¿eñ]âY_‚0Yp}ñK²¿2ï¥iƒþ°0 ö1V›A¯ÚC@FAKŠ›ÏC=äbÆ“Ì Íï¿þõ/§a‹U—¶‰€ˆ€üŸ Kâ³cŠ`¦e˖κáÿ{¤î÷,Œˆ­Iý÷ßßÅhÅÚ#Õ%m§zlª_D@ÒIE:!'(,Äy¥¢|þùç6aÂwïKBßýð,¤ÉuH¸*[IƵÆ\„=  $Š'(*Iý:Fr‰À<à,ÐÖ°ù®yì±ÇÜï<‡¥0XPI¬ñ¹æÈïǹB×Eäp„XBî†^±ö‹>Nÿ‹@Ø0*éׯŸ Ã…q=É*žÂî‹ê+Ð 4Ÿ ¥Gô°JÚ†¿ *êøèïqq#fA±îž}öY—«\ñˆ‰Ær²Ú¿è1éÈünЏ§XÑ¢d.ˇ„@®ˆÕI_hß¿7¤š:ÛNõØT¿ˆ€¤‹¿áeñ;Î=‹ †° ÞxFr/ª•{ê©§:—¨óÎ;/­iúh©e(>B#béùÚk¯¹çëc=¶ø•qDIÚÀë¡ ÊŒ Â,‡z¨À¢AðH˜­Õ«W[÷îÝ$•É p‰aï½÷^JÄÏùA²Ðš5k&UG˜cR]"-ªúžÉ\kÙ2®’ö“°WxR¤8-)EW» ¯î±¾·% 8dn¼Ø#2)>ŠC67öÅXž9‘ªünÉP:ðÀí¥—^rJa W˜‡ò@J†\fí“v8˜Ì(Bxù™…ÉÜ"dÈ!®[¸Ýñ ä´Ò¸?qaâ ‚EY·nÝœ{РAr‰òAé]D@D@D@D@@à²uï©°@.I¯¿þº ƒBW˜¥nݺFòeŒÂH´Ž2cÊ”)N DLô“N:É)HPÀà‚5äš5kœÇÈ_|a„¼"¯áxÙN(- ‹ó-Z„–°=Ì1«.ÈRzl|&HèëÿîŠÍÆlô_j  ä¨P¡BjQíYG ˜Ÿ9]÷•téj_í†C í ~àp;e!í ƒ gd!ׂû]ïÞ½]­XB lD]àÅ)>|¸³˜èÙ³§?sÑ¢E.VÜá‡rTˆ€ˆ€ˆ€ˆ€äÂ5!ðoÛ¶­ó´NEXYڸꪫŠÕÊâ>=Ú)fÂJ‚ÎÙcaݺuk[¼x±1Âå#@„§ÊìÙ³mîܹn­Õ¡o ‹€Ã1ÿ°5ôÑ/ìwüñÇ :É3¢""›À¤I“låÊ•îKäùKJØóD[E@D@²›@Ú Ü`<òHó,2±°¸ð“£ù11£ûÉBƒx½^x¡a­ÕµkWg‰…E âÄE'W®Cÿ‹€ˆ€ˆ€ˆ€ˆ@¾ ¶rË–- à ¤âÙ¹¤môrüøñ.§F˜ Î5kÂêbt…7¹ ¥¯xëXóf­Zµ²o¼ÑêÕ«kmø›Àý÷ßïÂXó/×K¾+@{ì1[±b…£C8,…Áú{¢èMD@D « ¤]=”™ªøðÏ.a¯®¹æ÷/ ”D¯– Ø“O>iýû÷w‰¯¿þzg½uË-·ØŽ;î˜èp}'" " " " yIƒ¢TÇø.ix\ð zZ„u’è¹Eèrvà B"ØâµjÕ²:9 wß}w_ öÍKxOù†Ž™Ž»,O Q,fΜéšlÔ¨‘ e _m‰€ˆ€¤Œ@è U«VÙÈ‘#]‡Q´oßÞx³”¦ pH8xðà„]ÂúÊ/ÄÒÅ‚„ç<Œ°¨Âk‰Ûn»Íy¸Üpà Îbìý÷ßw!±üÄbEÕ£ïE@D@D@D@D@â L/ ^å<¯oµÕVñ(Á7^¨ÛsÎ9ÇxÛûÃïëÖ—^z©|òÉöÜsÏ9ƒª 8Ï¿à;Š“m¶ÙÆêÔ©cXk>l§vrJ$¾SHL€°W‡z¨Û)ß½?€€¼Ä÷8ós$&¨oE@D@D ó ¤DÒ¯_?7r¬Žˆg› HIÛà†N‚Àùóç'<;Á›ýêÕ«íÎ;ï´Ê•+»¤ƒGuTÂcý/YtT©RÅ-Fj֬飣|!¦1 7äQ(×^{Íy]sô•W^éÂØ„­!$Ì/¿üb§vš‘´ryAðRQ|"@ž… º|„½Åúïï0 m`áÌ{²màñÁó;¥I“&avGu‰€¤‘a¯êÔ©ãz€÷U¾B~Ä ?H¾3ÑøE@D@²Ÿ@Ú k×®uIÁï¾ûn·¹ä’Kœ x¦¡Eéô «•+W¶SO=Õöß#/IÖÏ?ÿ|ëܹ³]sÍ5) !VßUˆ€ˆ€ˆ€ˆ€„Ià½÷޳뮻΅¤9äC¬gÏž.,TØm 8°Xm`Žñy÷Ýwß0»£ºD@ÒH S§N…^Wʱ!ìUƒ ÜQø«4NL5-" "*´+@ V$GÉà[„:Ê*[½zµ WEU•*U²Ž;†Pë†*xÐb7vìX»ãŽ;\¬[n¹ÅÞzë-:t¨K†ZcªHD@D@D@D@2”ŠÂѰ6øå—_ŒðPa—’´1{öl¦zõêV£F°»¤úD@ÒD@JÁ_xá…æ{~ˆÍÆlôŸˆ€ˆ@öH»¥95°.À½´ù5Ru*~úé'»ñÆ]õô5L•Âð_X¹몫®²çž{Ζ.]jƒÝò-UœT¯ˆ€ˆ€ˆ€ˆ€””¹ò=Ëóö.»ìb[o½uI«Š{mðÜ]œ6ÛK¨ÚÑ£G» a&AÛQ}!"r“&M²/¾øÂµC8¬|ƒ%¥GʧœH lÓаß$Þ×_½-Z´ÈHNاL,XA`Æ+•^*+V´O<ѦL™b-Z´°Å‹[‡¬W¯^Î .Ù¨O" " " " "Ã?Ü|ðA·6@0Ù¬Y³0ªÝ¨Ž’¶ñùçŸÛøñãíõ×_ߨ¾0ÿùöÛoÝšˆ°¸a½>þøãÂ?aöUu‰@.¸ÿþûí†np¯ƒ:È.¿ür—#ˆ±7ÎEj@)›OÛ õ×£GB¹pž5ü&vðc…Å+“ ŠšîÝ»».¦ÚK« ¾°0»÷Þ{ÈðáÃmÁ‚.D®÷*" " " " "k¶Øb «P¡BJ‡UÒ6Å oT•yóæ¹g~?ází\}õÕΘ*Ó×[aŒUuˆ@q àõÁú›0w«V­rF‡\çBu ;ß¶c„ÉoQË–-§\q™jÈ4¡É4(±úƒÕGÿþýÝW„«Ju¡vÚÉX°Ô«WϺuëfÓ¦M³Ö­[»$ñ§Ÿ~zª» úE@D@D@D@D@<M›6µ~ýú9Mš4I”+ä> ³¬_¿>ÌêT—är^°ö^¸p¡StäÔàJ8~‡xù¹@JXŒ!°™wS‹Õ›Ï>ûÌ 6Ù­Zµj¶|ùò¶¯X±Â¹‰²‘ø™íÃŽ£™¨x} vë§­¶Ú*¸i“Ï`ÁÚƒÂѶÛnëò“à{Ùe—m²*7ü×uÜPŸyæÛ~ûíµ>}ú¸~¥²mÕ-" " " " a@™Ð·oßMªåù6ÖöMv l _/ Ïé<¯W®\9°Gé?0ÀÞy纷nݺ†IXåæ›ovÊßê<¬zýzàÓTy€P·¯òÛÌ–wúΜSÉoxzêÞ \+xaåóvf20ëò{–iô" " é$P.ìÆyhÀE” 3 ýJ±»PÚ6ÈáQœ<´·fÍÃzjêÔ©V®\¹Ð“ '‚@{ûï¿¿=ðÀÖ°aCc‘4räH{÷Ýw]H,Âe©ˆ€ˆ€ˆ€ˆ€ˆ@>à¹Þ_à=‘ŠõI?üðƒ­[·.¥ÁòåË;l˜BÇ¢ ¿òqÎhÌ"$€ÒƒWtÑöh"ú_D@D@²“@è ìÄ\¯± yþùçmÉ’%eª¡wx¡ì°Ã.ùZíÚµ]H¬W_}Õ…ÄB!Ò®]»ä¡½D@D@D@D@D@ŠM`Ù²e6f̧`!$V*ÊñÇï¼LxÞ« I•÷GX}T=" " " " "*¡+@vÛm7{ï½÷\±`"EØ¥4mTñ¬³Îr¹5õëË/¿´N8ÁíÂn»í6»à‚ œHq¼GµQ’ï¶ÙfkÖ¬™Mž<Ùz÷îm&L°.]ºØœ9s\n’µ«ˆ€ˆ€ˆ€ˆ€ˆ@¾ 앟P±+VLÉÐ?ÿüs?~¼U¯^ÝåIE#x~Óÿ°Cx¥¢¯ªSD@D@D@D@²@è ”|páØ‰v)Mô‡…Q°±úGø.¿Ð^:u¬{÷înSÕªUý¯ÒòÎÂhß}÷µ»îºË4hà!X£-Z´È† æúš–Ž©Q(c;ó”¦Y¼¦y¥¢£ƒÉUD@D@D@D@D@²ƒ@è † ¥G4Î’¶á/ˆŠ:>ú{”ýû÷wÝðëˆîSYþOPä\rÉ%.é|×®]mÖ¬YvÚi§¹D~x«dB?Ë’‰ÚÈ?<ó¦ú¹—W~¢ï&MšädXD@D@D@D@²”@øîÅñóÏ?»äÞ't’µiÓÆÅÕ-fe²;‹*âçfZ Ý­·ÞÚ7nlO?ý´{î¹¶bÅ ÞëÒK/u‰ËŽ,\¸Ðzôèa¬ ó:wîÜjÝ¸Š’´Abõ=öØÃÎ>ûl÷ì½qúOD@D@D@D@D S ¤]òÇØ|`S§Nµ—_~Ù}ÎDX«W¯¶¡C‡º×¨Q£2ª‹„Ä*((°;î¸Ãî¾ûn×·GyÄ%HŸ?~FõUx~üñGãù•µÁo¼aß|óM¼]K¼½$mÌž=Ûüqûúë¯m‹-¶(qÛ:PD@D@D@D@D l ¤]Âp‰¥‹"„Ÿ3±üôÓOÖ«W/÷"!z¦ØY¹½ùæ›ÎÒíºë®³Ë/¿ÜÈ¢"" " " " ™B€gX¼ÂSYJÒ}ûöuÝⳊˆ€ˆ€ˆ€ˆ€ˆ@v]¾jÕ*9r¤=^íÛ·7ÞÃ,¥iã÷ß·yóæÙàÁƒv‰œ~Y³fÝsÏ=¶óÎ;[£F ½Uüï3ù7z¼k&NœèÆÌ¹¹é¦› eÈ!C 8ÈV$(çEá¹—çužÃ,+V¬páp1.ÊÔ½aŽWu‰€ˆ€ˆ€ˆ€ˆ@®ݧåD¿~ýÜkèС¶zõêÐY•¦  sæÌ)ì£ß×è÷;°ßŒÿÙ‡°R£F*ü.>:`÷Ýw·ýë_öðÃyBÈrÒI'Ù«¯¾š CPE@D@D@D@D &×^{­ðÙþÅ_,ÌÛsçnüôÓOÕ?þ˜ñžë%¢ðŒ;ÖjÕªå¢)tîÜÙÈýCÉ·ínÐú#" " 9B t`²p?ixجJÛÆüa¼ŠS ¯É“'ÛÂ… §ŽtïKH¬6mÚØèò™Ìš5ËÎ=÷\ëÖ­›{‘EED@D@D@D@²‰Ïõþºcýúõ)é:ëeË–Ù˜1c\…ÁJ fU*eN€\™óçÏ7¼¼öÛo?ûðÃmåÊ•†Ñ%Qî¾ûn§ aŸ|Ù~ÔQGYãÆ­råÊe~>Ô ˆ€ˆ€¤‚@è m¶ÙÆå ³Ûm·ó6»ã¥iƒ¼Õ«W·C=4a·~þùg{æ™gÜ>xLð0mÚ4cQõÛo¿%<6“¿ÜrË-­N:6~üxÃCçÎ;ï´:‹6¼\öØcLî¾ú&" " " " ÀZ›ÐT”zõê¥,‡ÒqãÆ9!© ý#YK`ôèÑ6sæLûóÏ?w×_ýåÖü è?ÿù½÷Þ{FÞ ¾÷¬¹¾}ÆŒNþqå•WZµjÕ²öܪã" " "à]²ýöÛ†ˆâA{Ø¥4mПæÍ›Û Aƒv‹ޝ©ZµªK€^³fMw ÿgs!$¹?n¼ñF«_¿¾óyöÙgí£>²Ûn»ÍZ´h‘ÍÃSßE@D@D@D@òˆ@ëÖ­­eË–nÄ;ñJEA0Ê A¨Šˆ@n D¶oà%‚k=ÖõžëÛßzë-{çwìä“O–$7¦¹F!" yO ôÕJ<&RYJÓDz(*ªÁĉCô¸añ.\ZO9å«Q£†]wÝu6}út»à‚ ìŠ+®pÿ§By• Ü4Ì!J¥‡?J<>úöíëþ•÷‡OEï"ýÎ:ë,Ûzë­íõ×_OIþÒl$ä+xý§"" " ¹@ tHq¡psýì³ÏìË/¿t.§(öÙgŸâV“òýQz•")o°Œ ïÇ!‡b<òˆ1† â¼@Þ~ûm"+ÏE¡Q3" " " " eL€¸ûäÛã°·{íµ—áýf¡n¼½‹Û}iÔ¨‘í»ï¾avGu‰€¤‘@‡œäûï¿/Èßç¡víÚ.–Â_¥qbªiP ljm%¨líÚµvß}÷Ù 'œ`§žzªƒ3ËêÕ«mذaî•©},)7ßÃåú믷ÇÜ-2ŸþyçòJh,( ÄÛÇ3™µ^ÉsæÌ ½Ù’´1kÖ,—Cï믿vF[¡wJŠ€¤…åË—7ÂD«l €dçÎþJBD@D gdÄ]ž¸›$_·n]aüÍL#üÓO?YÏž=ÝëÖ[oÍ´î…ÒŸŠ+Z«V­lÊ”)nѹdÉ»ä’K¬W¯^î܄҈*8ȱñ믿ºµÁ/¿übÑ1ùãV¬Í%i¯õ¥K—Ú˜1cŒÁ*" ¹A`„ 6uêTç–#*ý(¶Øb —Ë5WB—žˆjÈviW€pS%©8.å{î¹§ûœ‰P‰ÉbŒ—Ÿ$-ûYÚ>aýrÐA¹Dö7ß|³­Y³Æî¼óNkÓ¦K’^Úúu¼ˆ€ˆ€ˆ€ˆ€Ä#@:Bâ²6Øe—]\lþxû–t{IÛ lÖ¸qãlöìÙ%mZlj€d¢;<ù䓆Á£ÊxÉ›På*" " " Òž¤R¥JF襫®ºÊñÄ5 ýôûˆÂ&— J©vÚɺuëfuëÖuï$Hoݺµõïßß)Cryü›ˆ€ˆ€ˆ€ˆ@z~øáÎãÏBÒ ¬»Ðƃ>è¼KŠÓž#¼ðQÈ D£X¿~}n &¤Q¼ûî»¶hÑ"·þW ª´H»„ѳ°IÅâ&L²UªT±º*óÅtÛm·µæÍ›ÛäÉ“]¬ÿûßvÙe—Ùܹs­OŸ>FÈ,‹¡W*T¨Vu1ë)IMš4qÏ¿TÈgÜ pÖYg¹ßœ7ÞxCIÐÿ>¥(yyCED@D@r@F(@²$J­¶Ú*ºjË•+gûï¿¿KTß AëׯŸÝ{ï½¶`Á>|¸ —jƒªLD@D@D@D@2Œk,¡5jdûî»o†õNÝ():kÞÅ‹Kò7D’ }ôÑ.aI¹ê8È$¡ç!6.Þ¼>ø`ûâ‹/BoiÚX»v­Ýu×]…}ôûýÎMß/_~ù¥ô‡ â„æSaÁ·Ã;8ï§žzÊ-þ^{í5çûØcå UD@D@D@D à <¸ðÙ¾G)Ifl³Í6vÌ1ǸXmÛ¶µeË–Y×®]ÝÃQW>1ÑXE@D@D@D@Â#@‚q?É8ï't’[CðoûË/¿\øl?tèPgµœhÿxõ$ÚN8˜·ß~ÛÎ>ûl;å”S\HXF=cÆ kÙ²¥ëc>oo¨&([&L°©S§ºß²m9s[CÉKˆò| ý¹gB=‹@©B`ùÊ  þ÷?sÃ<âˆ#\ž¶ÿú믅þ>%ÝŽ°ú:ê(kÖ¬™‘«"X<8Ó´iS;ôÐCÝþ3gδÿüç?®®¢¶ã9‚÷Þ ~ÿ㵓ËÛqÞgŸ}\ø+BbõêÕËyÄ,\¸Ð† æØæòø56Ô ù9/ ï?ÿü³[Cð,o;k‚Ã;Ì0ÎB‰Á{¢ýãÕSÔöüÑ­wÖ­[·Q_h £ª|ÞoF`ANذ=÷ÜÓ>ûì3Ófåʕβ<ÛãõSÛó—ÑPdú×þ’øÿÈYÛ1ºté¢0XÿÇ¢O" " YL T Dã&_òÊ•+aêoÑ¢…ó>øå—_’ªž„Š­Zµ²N: )(@’ÝŽ’eÔ¨QIµ•Ë;a ²ýöÛÛÅ_l5kÖ´nݺ¹Åæé§Ÿn½{÷¶‹.ºHÖ"¹<46È 25nÜØÑŠpH* Æ[*Å#€ák”¯¼òŠS‚pŽÒµ½x½×Þù@à÷ß·õë×çÃP“#ù>Q‚´nÝZ ¤©iGL&°™÷ _ä“<Ö: â?¢ŒÀ»‚ªðŽð=$Òµ=p÷ô3º¯%Ù^©R¥xÍäÕö¿þúË)’ ä˜Wb ¥ZýúõÝBœ¸²„ý:XxÐ&d¡‚%W÷Ç‚sâĉNa/\gœq†ÝyçÁÍÎâSû›ópÓ|øûêÐõ²„~O6p(‹ù°óÎ;Û'Ÿ|²Ñï³þ0°^À¸(ºz…5^ÇXd³ïéÞγ®ß_úFé}c;ßçëvžiýõ_ôùÌ4&ÑýëÛ·¯õéÓ'z³þÏ#„óžúhyäûÅ¡ñ‹€ˆ@(Uôâ ¡ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€äŒÏÊ—/o›o.шÚk×®íB'Šâï«wȺËgÃYRE@D@D@D@D@D@D@B%@˜â©S§ÊÛ1@•ð~„ 'ĵŠˆ€ˆ€äPB`åAD@D@D@D@D@D@D Œ=ÚÈuA;• H€>bÄëÒ¥‹Â`åñ¤ ó‹/¾hóæÍ³ÿþ÷¿FžSæD5ò˜Š†."­¤ÉÖ3§~‹€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€”˜¹É3§ò ,0” ­[·–äÿXòêÓ?ü`W^y¥S€¬[·Î¶Ýv[«R¥ŠþùyÅAƒÈ›y‰D#E ‡]V¯^]Ônú^6!àÏÛo¿Ýî¹ç[õ¸ãŽ3þßu×]7Ù?—6”+W®Ð’ˆÏ$’.XÅJô™«û³Àˆ•ЛػX”Dí¿ˆølà ù ùüÐ|(›ù@ ’O«ˆ€ˆ@.Øj«­\¨Ÿ\›Æ”Ö¨“'O¶9sæHæ… Ϙ&MšDmÕ¿ù@àŽ;î°!C†8ØW\aÇsŒU¬XѶÞzkãÙ0˯¿þjÏ=÷œ}üñÇvöÙg[µjÕ2±›ê“ˆ@š$¥ISßÔlXµj•M™2Å®½öZûþûïíàƒv7ÔfÍšåÐ(5l!€AÅÃ?lýû÷·+VdK·SÚÏC9ÄŽ:ê(ëÞ½»í½÷Þ)mK•g&‹.ºÈ&Nœhƒ¶sÏ=תV­š™ ôê›o¾±¶mÛÞ+\ÓuëÖ |«" ùN@IÐó}”Ñø+W®lgžy¦S‚4lØÐÞ}÷]kß¾½ÝrË-ÆC§Šˆ€ˆ€ˆ€ˆ€ˆ€ˆ€”%<­Ë—/ï"”e»™ÜVíÚµ]®‡‚‚‚Lî¦ú–B_ýµóÆp•ÐWÙPˆ>‚l‰vIºÉ†!©" !$D˜ª*1.ëÔ©cãÆ³k®¹Æy‚ 8ÐÚµkgŸþyâƒõ­ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€„Hà‰'ž°iÓ¦ T6 ÄÑ–[ni›m¶™ä)Bu3Pjäé$аE ÇH’c'4Ó‡³ùæ›»Ü={ötŠJ•*Ù³Ï>k­Zµr ¶2½ÿꟈ€ˆ€ˆ€ˆ€ˆ€ˆ@n5j”Mš4É~úé§ÜP£ ú]wÝ¥`!°T" " ™A \ftC½È7„Ä:ùä“­zõê./ÈôéÓí /´Ë.»Ìn¸á%#Ì· ¡ñŠ€ˆ€ˆ€ˆ€ˆ€ˆ@ðCæ”q³ÝÜ‚ %ëõ½öÚ+£ûªÎ…G€¨«W¯¶¿þúËÖ®]ëÞ?ùäCvC! ú®»îWVCŽE‹Ùûï¿ï’¥“Kæ ƒ²m·Ý6éNþöÛo¶téRcþ÷¿ÿµ}öÙÇ;ì0×n¼äë_|ñ…óàbÿuëÖ¹0X$B' …Äí{ì±GÜ~ûí·®ßôϧš5kºƺ‰Êš5k쫯¾rãÛi§¬\¹röË/¿ØìÙ³]?È£³ÝvÛ%ªB߉€”!%A/CØjjSÄfäFu÷ÝwÛ­·ÞênRÇsŒ 6ÌÝì6=B[D@D@D@D@D@D@D ôî¹ç›}úØ«¯¾êÚGCÛ¼Î>ûl#ŠHµjÕ69®[·n.a;ÊúMÙj«­Üq|®_¿¾ >Ü)cøß/„ù;v¬Ý~ûíöÙgŸÿSè7Šž¸H%(Pb•_|Ñõ©Y³fvõÕW;¹VïÞ½íõ×_·N8Áú÷ï/™V,pÚ&i" 4W³Orçwv^ õêÕ³«®ºÊ^xá§õçFÙºuk¡Ð \rÉ%.ÏÂW¨*fXîc½žIÞXÛ“§eÇwŒkÉŸªs—ζžxQà‰AHñTr³6lØÐ)0H]¶l™]yå•¶ß~û¹&÷ÜsOÃÓ!XH8~íµ×ºðæ5jÔp=š6mê‘£T$”Ú¥—^j7ß|³µm۶Л$XŸgΜi×]w}ôÑG.G,!Ò÷Þ{o§˜=z´=õÔS†§2"³ó’´iÓÆåšýþûïa- œ:*Kè3 `A¹ƒBå‘G±}÷Ý×)APöQïÛo¿í”9]ºt1’Á·oßÞªV­<Ü}FaòóÏ?^+x½Ð7<§?}Úa‡69FD@ÒHÀ³ÀWŒ àYD/^ñ\m#Þ'âݨ"=zôˆx7•ŒèŸ:!" " " " " "[<ëõHAAAÄËèå18ï¼ó"~øaijÀOû‰¦#FŒˆxBˆx‚åˆ'$/“~¥³mè Õ#çœsŽ“‹xʇȣ>ñBS¥lìž@?‚L†×±ÇÙf›m"ž7Fá6OÙ±IÛ'NŒxŠÈqÇyë­·"ž2 â)Ü‹ÏóæÍ‹Ô­[7ây‚D<%‡Û] câ¼z ƒˆ§0‰xB"ôþ¼{НÈ5×\ñ g#ž§EÄS„lT…ßï+VD¥³mÆ6räH#Ì!à -E¸&¼ARU8ïÈdxùçžpPþ6>Ë?ü`xgðÞ½{w«]»¶ iŽ— /rpxÊó” Ϋäé§Ÿ6ò„D—ÇÜ`}ê©§Ú‰'žè¼|è }à\ž’Áy„°/yI<1ja5Á~Ó.ÇE÷ÛýôÓOöÀ8ÏÎ;»ÐXþ˜ÙÏxŸüóŸÿta»&Mšär}6õáå—_¶åË—ᯎ?þx«R¥Š«#j7ý+"fR€¤ù¨ù pÃÁEwCÏšÀvß}w{饗\(,þW0`|‡€¡¨Ê„ñ!t‘gQŸv$„âå ¼ ¹D’lŒ%S]ÒÙ6cózó™ñðÁF8®L)„­BáyJ¸0YÑ ú‰rÂóbq¹@P€Æ*ºL™2žûî;—oùO¬B86òˆxÞ.Gû—´ÐoBmµlÙÒõ›>FäR(cvÙe£$;W¨ëâ‹/¶#<²ÌóÅë“¶‹€lJ@ M™hK Æ%78,<°à!çòË/w–™tÓÏTꂈ€ˆ€ˆ€ˆ€ˆ€ˆ@ xán\¾_À^‚*rî ¸H Xµ§»vØaNHU>e»í¶3¶aeŸê’ζòò¥úå˜cŽqÞþÿé~'q890êÔ©“ð|¸|x±g'x­¡xÄÃ…(?ð‰UðìØÿý].”O?ý´0Ùy¬}‹Úæ÷»f͚λ$Þþä\ÁÄ iåOÁ~aŸ£>:fžà~ú,"^û°¥·/j]6"€79\?Ѧ÷ë×Ïî½÷^{÷ÝwíÎ;ïtɯ6:@ÿˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ@’Î<óLÛj«­Œ„ÍJ‚¾ ¢yÅø&‰6”Ý*T¨àR#øõ×_Õ>IÚ}…H(Ä©$mÓ%BG17gÏžmµjÕr ‘è$äqº^&›Qhpœ>ÑÏxåÉë‘ï ÏêBbÍ›7¯8Ui_<#pæ™g:h¥J•òläñ‡ûçŸ:A³¾ñésJ„–-[:ÅÀã?n_~ùå&X>úè#—¿…ÄùçŸoxoD—víÚ¹|3O<ñ„S4+$X8ö¾ûî³÷Þ{ÏÚ·ooµjÕŠ™0½jÕª.7Ʊ+W®tŠÍ`=þg”6'Ÿ|²›ã=ö˜SÎøßßÇïrÎâ±BΑ çJp?}ÈR€dÇyR/ãà&ÄŽ›) Ò¹’ýŒ3ÎpJÞTD@D@D@D@D@D@D š@ÇŽÝÚ1‘Eyô1¹þ?kêË/¿ÜöÚk¯\ªÆW $ˆ¿øâ‹í¨£Ž2 =zôp²òtS "t²œæÌ+ŒX£ F­W^y¥ËËq饗ڃ>èBfá™õñÇ[Ÿ>}œGrŸsÎ9ÇyD×Áÿx“¸z&L˜P¨LA‘Tæ!Cºð ­Y³f†â¦{÷î6þüB… ¡¸FŒatÛ.¹ägx«MmÈå²§«ê©Ä'@« Ø“O>iƒ r={öt7àÛn»ÍvÚi§øë¼#€ewùòå a®ÊuêÔ±®]»:a²˜ˆ@"äÓ _Ì7ÞhO=õ”=ýôÓ†7a¨P„ßE¹çžër€Äª‹kדּÎrß_ýõvÕUWïÈxÖ­[çê:î¸ã¬wïÞV·nÝ„×* MÂU*}êÔ©FÂó5kÖ¸|±„Úò0ȇPrà 2vìX{þùç]x.”($G_½zµU¯^݆ æBt·Çƒ¶‰€d>ÍùääÝwßu(d®¹æ«Q£Æ&'‹<„éòû,‰dí5²† :CÚråbÛ“×äí·ßvûàÝB‚wÌ% Hæžõ¬°8X¸p¡³˜3gŽí²Ë.î¦×¹sg‹w+Es:TD@D@D@D@D@D Ë4oÞÜf̘a_eºáäÕ«WÏY½_qÅ ƒ•eó9¬î¢HàzÀc"ÙÜã¿8e²—¢”Á>Ó¦_ï´Ï«82r†p=û¹Dè ñúA;Ã;í³?mâ–¨p /ÿDûê;ô$ýç@=HnF_}õ•K’~×]w9ü‰'žh„ÄÂUSED@D@D@D@D@D  4mÚÔ^{íµücä¾ÐyúôévôÑGÇØC›D@D@D »(Ðev/õ¶Ðð£èÀ}÷á‡v r„œ|òÉöÊ+¯£&í*" " " " " "kÚ´icx&Ge,áÿýwyÄhBˆ€ˆ€ä -<ápßœ"1öØc.9: î `çœsŽ­X±"Ô¶T™ˆ€ˆ€ˆ€ˆ€ˆ€ˆ@æ`H¬ÿxù2á÷us×®]­   üÊU£ˆ€ˆ€¤€ i€®&ÓC€‡Ú]wÝÕzôèaãÆ³*UªØ”)S¬U«Vö /¤§SjUD@D@D@D@D@D -&MšdÓ¦M³Õ«W§¥ýLl” $&¹³Šˆ€ˆ€ä…ÀÊ…³¨1‹!±öÛo?kÑ¢…-]ºÔæÎk$xûùçŸíÈ#´råÊ«>í," " " " " "}ºuëfÏ?ÿ¼­[·.û:Ÿ¢£ùᇬFV¹råµ¢jE@D@D ìȤìX«¥ "€«sÍš5]rô›nºÉÅ{:t¨µmÛÖ>ùä“ ê©º"" " " " " " $û&H$IEõYYç‚ lذa¶|ùò¬ì¿:-" " Ѥ‰&¢ÿó†.½;ï¼³uïÞÝ&L˜`;‘¼ ?ýôSÞpÐ@E@D@D@D@D@D  ì»yóæV©R¥|~Ì1ÿù矆bHJ¡˜x´QD@D (ÖOž4u9\+V´O<ѹø4Èy†ÈÕ7\ƪMD@D@D@D@D@2@§N\¾‹>ø@y@þ>9µjÕ²ÆÛ^{í•i§Ký¤DØtP®(_¾¼pÀvß}÷ÉÒ•ð-×ΰÆ#" " " " "  42kAÖ€*Ô©SÇÈRPP $" " "¤É‰Ó¨A„A¥G… ¨Juˆ€ˆ€ˆ€ˆ€ˆ€ˆ€d8I“&Ù´iÓäý8O$AßrË-e`¢" " ÙM@fÙ}þÔ{¸ÿþû %È?þX‚£só… ÚÈ‘#mÅŠ¹9@JD@D ïH’w§\ Ù÷úõë•ð;0,X`Æ ³åË—¶ê£ˆ€ˆ€d/…ÀÊÞs§ž‹€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€”@›6mŒ< o¾ù¦Â`ýÍðÏ?ÿ4^‘H¤„Tu˜ˆ€ˆ€d)@2ë|¨7" " " " " " " e@ S§N.ßŇ~(Èß¼kÕªe7¶½öÚ« ΀šÔP¬Ô3V " " " " " " " FïòåËÛæ›K4⟚:uêX·nݬ  ÀߤwÈjºËgõéSçE@D@D@D@D@D@D@JB€èÓ§O—÷GÞ[lá¼b6Ûl³ÀV}ì%°™×Q³÷ü©ç" " " " " " " % мys›1c†ýñÇÊyñ7¿=÷ÜÓN?ýt»úê««sJ‡ˆ€ˆ€dåɼs¢‰€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€¤˜IÐׯ_oóçÏ·ŸþÙüü•+W¶… ÚìÙ³mÕªUyµ}åÊ•6räH§QO@U/" "P&¤)ÌjDD@D@D@D@D@D@D “\xá…®;Ë–-s ò_tíÚÕªU«fcÇŽuJ ù¶ý÷ß—GL&MTõED@D T«Tøt°ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ@¶@Øÿ믿:?IÑ·ÜrK—=Ÿ·s.·Ýv[#ˆŠˆ€ˆ€d;)@²ý ªÿ" " " " " " " " " " " ›Ø|“-Ú " " " " " " " " " " " YN@ ,?꾈€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆÀ¦¤Ù”‰¶ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€d9)@²ü¦£û‘Hľùæ>|¸uîÜÙ.¾øb»ùæ›íÏ?ÿLGwBi“¤w“'OvcyöÙgC©3^%eÙV¼>¤bû_|açž{®õéÓ'Õg|K—.µN:Y¿~ý²úZÈxÐê ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€$I \’ûi7pPr,Z´ÈÚ¶mk+V¬pÛªV­jx ÝtÓMYKé?þ°>øÀ)A>øà”Ž£,ÛJé@•£[³f=õÔSV¿~ýÀ7ùóñûï¿·)S¦Ø`={ö´-¶Ø"¯‘Š€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ@$OJ&wiÕªUvûí·ÛÊ•+íôÓO·.]º8åÇæ›§Æ™è·ß~³7ÞxÃfÏžm§všÕ¬Y3exþúë/C9Qž,eÙVʀŨxýúõŽaŒ¯r~J Æ_ó'çaj€" " " " " " " " ")@B€˜OU¾iÞ¼yV©R%»êª«ìÐCM©¥ûÚµkmÔ¨Q6kÖ,kÔ¨Q>¡ÖXE@D@D@D@D@D@D@D@D@D@JA 5fû¥èÍlxHàý¤víÚ)U~ø$~ÿýwà {H†€ ÉPÒ>…PB )_¾¼{~¡" " " " " " " " " " "A¤É “¡®ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€„C «r€`ø“O>1nרQà áð§Ÿ~j¯¾úªý÷¿ÿµjÕªYýúõ ¿/ “ü;ï¼cË—/·½öÚËêÕ«gûì³k§¨ã‹û}¬1üüóÏöÖ[oÙþóÛ}÷Ýí°Ã³½÷ÞÛ6Ûl³¸Õûõl±ÅV½zu·¡¢¨cñâÅÖ¦M¦*VkÖ¬±wß}×Þÿ}[·nËãA8«ªU«ÆÚÝy|Àú¿üòKŠŠ\ .tûs>¶Ûn;Ûu×]cãÏ>ûÌ`¼lÙ2Ûc=\›ô›þG¼L~úé'j‹÷Õ«W»>p~ü6Ë•+çmµÕVч»þýøã¶`Á7FúM[Ì‹]vÙe“ýmðç9H¨³V­ZvÔQGY¬vÕSÒïH–þÕW_Ùk¯½æÞá^PP`p€›§‰êõçH˜× íÕóðË/¿XÆ íCIʈ¹¶bÅ ÇŽ1P˜‹o¾ù¦½÷Þ{Æ9%§ uçáϘӳgÏv¡Ð:è ;üðÃmÇwtuõ‡ùCK—.uçpûí··ý÷ßß…pcÞÆ+x:}÷Ýwnþí¼óÎV¹reã||þùç.ó¸Aƒñ¹sòõ×_»:©:TD@D@D@D@D@2ƒÀرcíÖ[ouÏüçwž]wÝu¶çž{Z¾mÏŒ³¡^ˆ€ˆ€ˆ@8²J‚‚ãä“Ov‚Èùóç;a|Ÿ>}ìÉ'Ÿ4³”FIÐÝ­[·„”Dþë_ÿr3;¼s|… œâÞ{ïuBö„•óËàèÒ÷믿ÞV­Zå„ü´¿Í6ÛØñÇo÷ÜsU©R%f ÔÓºukC˜;gÎ'ïÞ½»=ûì³N$º |9s¦]}õÕNpŸ1#lFù/¸!0–o¿ýÖ)TPb°? ~Ròm·ÝÖ.¹ä»ù曃‡¹Ï;xð`=z´;ÎgŒa÷È‘#7QV!ð~þùçí²Ë.síqnékçΜŠQd<ýôÓ†0øÀºvíê” þÜùÇ?þᔎwÞyg\˜ß¯E‹Ù¹çžkuêÔ±qãÆ¹yÛ»wo{ûí· ç>¹e¸Æ `;í´“k³ÿþ6eÊ7¨‹ðk();ʨxÅÇ3ÏÖ®]넘cÏ?ÿ|ûþûïíÒK/µ#Ž8Â=œLŸ>ÝFe·ß~»PŸxâ‰1O–ègu–-Y²Ä؇Ï5kÖtÏ=÷œ¡ü@‰À;Öæa ÔÿýïÛ 7Üà„¸-[¶t ¢|ðA'ÄÇûÅA,Ï ¿ ºì3öÆ[‹-6ñþàámâĉNøŠå9Ba,íQ|à™ wàÀΛfÈ!y8°¯^½œµ>¼oºé&§dB(LA }àºÏÁ?x‹´k×Îy›0¾‹/¾Øy.ð7uêTC‰ã»ï¾{#A6õÁœsÈù~ì±Çì£>²Ž;ºãi@´7Þ#FŒ°Aƒ9OÆA=Õßxã W‚uÚçax¬‚EÊ<|AõÇì”R<ä^{íµNy…×B*Ê7ß|c:t°3f8‹¶mÛZ“&Mœ‡O?ü°›'<3ÈGŽ0ÎÒ\/( ðÀ@á;”œ·Ï‹%Ñ‹/¾è®AT‰ ÷œOæ5ç¾(98OxBàYµËx*V¬híÛ·w æû¢8Áæ‰'žpŠ<#<òˆá]à2~üx7oQСL;öØcK ô™9Ï\A‰ˆÂ1ºÀ¹ÀþxÿpýÜxã¶Ã;¸ñ'R¾D×ÅB„syÍ5×ýAA‡GED@D@D@D@D }XoãíïÖ,¬Õ“)¬_8–õM²ÏwÖ¾$Þñ¬ }cO""ø xû·£lùâ‹/œ±Yp{¼Ïì×>kGÖHxÀaCED@D@²ž€'äËšâY/D³}ó¬N"ž°=rðÁ»ÿÙÆËó´ØèÏš%â)"ž‹cM¿¨ƒBO‰ñ¼"žÒȱ÷O99úè£Ý˜ü:›Â,ây+¹kÐSà^ þ>z({¬9<¡Î&¯1cÆDXùkNÖ“¬ƒ°~g»g¸ñŒÂܱÇw\ÄSˆ$ÜŸÑÛCæ@]”Xõ³µ9kúؼyóˆgÀÉæ¸ûS²L?þ¸[ Å«Ÿí^T†Â6¼ˆn=ÆšŸ5ŒŠˆ€ˆ€äce‰:Ç‚:—̇zÈåêÀúK|^X*œzê©ÎÅ“ÐEÑ ß’ vB`a‘ͱXÊb,Â=á«ó™4iRt5¥þŸ>cQW!·ðz }ÞqQÅâÿ±†Çj#Vñ& ³Lǯ ¼XðŒ î`ÁµOïÎy.àéB ?ÔcÇ˯ê‰K^ æý@Ñ”¨”öz!á=}!gL¼RÔ|G]^¨µà¦ÂÏÔ_æ"çÿ£K2ç€ó}}ùž5$Äãƒü?xšøVNÑíøÿãÄu‘h.ûûßÉ[ÃÂvÈÓ©S§¸×ið8}(Áut¬µGÙô"sZAB”d!A6™ÓCõDD@D@ŠO ¶¸øõ”ùñEu!òrÏáp<å„_7|,Ä ÙCòe,îý‚ Ú‹Áéÿ»É;®±=zôpÉÉ7ù2‰ ôÅÂ}¶ñ ÂÙX œýýýñâÆêå¬pþwÑï‚®sŒ¯PˆÞ'™ÿ9¡9aœ`Hé‚ðžý°Ò‡iI¬Lüþ%è÷ûÎ~‰JQs«¨ïÕ]œï8g$Çci†—@¥Û8O(>èS’QÆ”´Ï¾rÉŸ‰ú_œ6’Ù7Þ>ñ¶G÷ >(Öð Â£‰$…$Gg»Ï¹CH¸D ñúðòÔ$òÊïç^¢zÂë½ð î·… ¾ü}ô." " " " "^&L(\o'Zw§·—e×:J Öï‰Öðe×µ$" " áH, §ŒªÅW(`!+O°³ìƒ¥: ò (8®¸âŠàî}F GI mãÐôÛo¿MXM"Ë Æë%ÃvÞ<Ì @WšËKÌæÂÅÛ¯¨í~›þ~‰Úd,ë9Ey2øõE¿ûíÁ au¶ÎçŒiO>ù¤³¼©_¿¾ ɆBŽsƒ9IH¥TØ¢üKæzIe?Š[7J5/áŸËY‚”—0Ý…5#´üP~ªPzE]_\7E)Í‚ýãÜ‘fæÌ™æ%wÞ&óçÏ·G}Ôåü î«Ï" " " " " é#0zôh›5k–ë@QëÖôõ²ìZÆÑKŠî¼ñ‰4QŲë­Zääa&Ê‹¯¿þÚYƒãe¯`iOü„¿ä%}ûö nÚè3VêWÒBÛq©awI Ç3^ÂtÒI.ñt2uGà]Ÿß& ž’é?¼¢C>E×ïÎ) éP%JfïøLÛÎzõêå<ð2"_yG8'pb¼(IH®ê¹d®£!\T¢ë%Õ}I¶~<¶^|ñEÇ0tƒváßPú×%ï„ÂKÖ²‰ý“-(LñüèØ±£K~þú믻EÕ#úh)@41D@D@r‚@Þ)@üP>_|ñ…ñ"!s¼‚õ;ÖáUªTqVãÁýx (©À>XO¼Ï´’†þ–&Ç#<÷ë#dVª‹ß&BsrU”¦ÿÉôÕ?§Œ1Q2ëdêJ÷>„dB±çÇ¡‡j÷ß¿S@D àQöDoKEßQ€ DÀ«Wi¼šRÑ¿Xu¾m̘1މÙO=õÔ˜9]P$¥‚!^H矾KdO¢uÎ#ʲ>܆3·I¬±h›ˆ€ˆ€ˆ€ˆ€ˆ@êœuÖY.óo¼áòfú-‘Ã/^^H”'~ƒ—_~Ù?üð"Ÿó×®]ëîòfZbúž0‰ÂBD@D@D ä„ Ü8qs%Iq¼<˜É@΀Zµj+Nç©·ÞzË=txa{JZP ÀFЋ;+4~ãv8&Ñ>ñŽõ·s<}Æò+ûÃ;Ìÿj“wªh3YKüM*ð6øçåy28wîcÚ¢Op@Ü}bWVÛèßâÅ‹Ý9 i}¢^Œ“â¿§¢>[Â9ѯV­Z¥¢™Pë\½zµK<ÎäúŽ·¨`îq=ð&Ã5jØu×]g(?(„Ñ;í´ÓœWÊôéÿkï<À¥*Îÿ?ù›H÷@¸V‚hç¼dâF”ôü’FÈIK¸)Ûo¿ý¬ž /¼Ð¹#ŤóùçŸoB ;Zêáþ(^_[>ƒbý}ê©§LàH¶rŸ>ÞsÏ=VE–ÀÔ–ú“çð0ÀzA„Ã,üœsαyobÂÚ©§žš<½!ÿ/±ÄfõÄ{ñÅÍU¼!XWÍ™3ÇÖýC©t·V¼¼2Ÿ™ß[mµ•Ûyç­îË/¿Ü\d•9Wy„€B@! „€¨<óó<Ê&É™3gš›ljš4i’ëÓ§O®§‚Ûn»Íâeà†yë­·vGyd¡ûg\káé¡™ëÀ}/Ϥñg>k°þ! „€è ´fœ;hG*i6AqQ³Ï>ûX äwß}× 6Ìâ|·¡q‚4vìX÷õ¯½’âKå…° B0§Nê°B CLºï¾ûÌê¦LÙÕäa<ˆ/àʉèûÄ. þe—]¶&õcñÌ ÌGa‚ mÀº‚›Ú«¬‰'©^ínúBðgÄÜ[!¸z…V°x ÔÉMf¿~ýŒÐ‡´NK¸b× ! „@GE C ìDÇe¯¬~ÕUW™[¥¬<œÉÎuLPÙ½APtÈõM6ÙÄ~ì!R¹‰©Gↂvžxâ‰nÏ=÷t³gÏvÏ?ÿ¼™šb™ÑÛÇူßPÅÛÇ"~<ï3V'C† ±¾=ù䓎ÝûìˆÇÞ‰uB›° ÉJ|NÛŠØûâËp~饗¬O˜ÔâV ËDެ~R;c°2 f q3 þ‰ùO”¹}üñÇ›‚ ùw´p{…ðÏÎG(Ùi§ÌõCVâܽöÚËõìٳͻ÷‹êB°!úý÷ßï0«Æz…>`ùBû àŽèÀÍ:B ¢H~ñ9RízaNl±Åf-ñÄO˜{.,O8†Å .Ó°PAP Þ´Ô½{ws˜‡Y‰õ‡@GL‚‰§%„„,Ö'e&Xp±BÁj…›÷-·ÜÒÆyÌñ`À“W2+-Ä,‰ŠR¼Y× DF,¾X¬!Æ5¢:õ½B@! „€mGñ/ÈÏ}صÁyi¤r8§­ïÜPqƒ Žà±L½ÔO;¨ŸW™v—Å"ÙVðã\ê }¦¯yÂG¼ Î%•ic8º8úHÏœŸE‡óâï܈Qíçgµ<S>—Á•¶…1 ü¬T6_Öù/[ñ*hèý·-ŒaÖz(;G*Y/”Ê s5´)¯ú@{IYãÆw”M¢ì¬5~¼ø>o…¶’7ÞÖPnhSV9ñùúhKùÊ⫼þÅóåõ1¥ B@! „€B †ðŒÉ³‰MV¸Ã"±‰oàÀ¹.°°ÊgC#–縴fsò|ðAËÒŒu°q¯ lÜÂúŸ‹JB@! ::ÙfMÚ³­hžR@pÙ‹ǦyZ¨–! „€¨'€TÞE!„€B@! „€B@E˜9sf‹Û«®îþ dØ„W´oQõ_gB€X´Ï<óŒÅù\wÝu3½2t¤>céuÚi§¹·ß~Û=Ú­¹æš©ùU·•ñ$®.®ï÷ØcÜpUWæ X¸p¡ÅcÅí>®Óqÿ} 'Tãø¸ãŽs¯¿þºÅùžRõ<öØcæ¶×ðí1ªoqq xÍaMcÉ9a„L—ü”$¤OåB@! „€B@! :—_~y‹Û«û¢“u±¢îüå/± èË-·œ:t¨‚ W„^çÈL¼Xbå>Ü!€t†9:gÎ÷§?ýÉí³Ï>]NAø¹ûî»ÍÝø.»ìR×!}ï½÷±•ˆÌ5u饗¶¸§cÆŒi©awƒŸ}ö™ÅhÝh£ZYœ1^”1~üx‹Ür²>´¿ÿýï¶¶‰«[ïyÐæFVx"kûÎ;ï4wûcÇŽÍ=[H.<µÿ’¨ŸL8%! „€B@! „€B 1@ÐAÂ)}ñE]d»þ{õê%¤ NŒG“Ø•)ß“˜¥­_eƈ>3®!&k™sÚšç¼óÎsO?ý´ÛtÓMÝa‡æ6ß|s³([j©¥ZŠ|þùçݱÇkÖ!‡z¨[{íµ[ ŒUˆÛr¢>T…bA{̓ªZáÉ¡OEk[H…ÀV›}¥•V2sBÊ‘OÍjÑÔùB@! „€B@! Ú†n@V]uUÇÎXÜÄ,X°À ºí¶ÛÜÿøÇ܆|~ø¡ågGó¥—^ê°œÈKûÛßZ¾nÆ: È‚%L™ÔÒ}B@üO=õ”ûôÓOÝèúöíë–\rÉVØ Ä <“òZךVé@RPóŠ$2 JB@! „€B@! „@ã9r¤mL$>@?hÍM7Ýän¾ùæÜøxa‡2–\pÅÐÈëMšµÚµÁ8Y䢾B ÄäÅ[ÌõèÑ#Uüà<,>Ž:ê(‹B<Н~õ«YÅ鸨@j¥ B@! „€B@! : xeøò—¿lTãmŽ ñãYŸC*u/ÓŒuп 7ÜÐýêW¿rݺuËꮎ ! R@æšú•¯|%õ{þà?p«¯¾º}O^%!Po$€Ôa•/„€B@! „€B@43gδ@»ßùÎwÁ{?ùäkãÖ[oí8–GÌ0ü…^°sV^ye·ñÆ[Àß¼NÞwß}îÝwßmê:Ö_}÷­o}+×ú%¯úN!‡±‘_|ñ¼,úNÔ 5‡T ! „€B@! „€ÍŽÀå—_î|ðA³ î¬hó/ùK·ãŽ;æºf™>}º;ùä“MYwÝuíó÷¿ÿýÜ.ÿøÇ?n@š±üõ§ä’K.qC‡UôÜÑÔ—ÄÀ!æÃk¯½æþõ¯¹e—]Ö­±Æ®gÏž…b óì£>rßûÞ÷Z\%!B>úè£îÕW_5×ñm´‘Y$¥Å‘H¢Oü\Ñ=ûì³îí·ßv¬ÅÍ6ÛÌļdÞ´ÿiÏÇl–O¡¾¹sçºÇÜÖì*«¬âú÷ïoq~pmÒ;ï¼ã~øa‡ Jÿ úݽ{÷R1«Áìè'ÁÅ—_~y³º ¦Æ#Ž [‰Jß.\h±<°lÃìBŒ¤e–Y¦• üç?ÿÙÎÁ¤ÚøÈŸþ¹{å•WÜsÏ=gc…‹­M6ÙÄ­°Â …n ËàC[‰Yœ²…ß Äo°&Äu­µÖZ¹V/Ézˆ!õâ‹/º7ÞxÃæ?ó‹Àñ¼#%c;oÞ<ûŽ5†åLVzÿý÷ÝüùóÝ7¾ñ ·âŠ+¦–—unüø›o¾éXÿòË/Û|@ä§Ÿ•ˆWÿüç?m}ÐvæskÍ5×´uR¶Ö6m`m³€ëXU^"±x¯Ûñ3÷É'ŸtÿøÇ?Ü AƒÚ±fU%„€h ÜdðãÇ(ñªÆ´Hµ ! „€B@Îd]š+*¹%–X"W D–"ø±çœ¼ò“§ë€È$˜;Ï#Š’7’]û;`æ BÙ믿n¤9sw¬ˆŽ9æ ‚˜DìØcu<ð€»á†Ìzв.¾øbG ‰àNŽ5²ûî»»ã?Þ­¶ÚjÉ"ZþÿàƒÜ)§œâ®¿þzá aÊšD8úè£Ý{ìÑ’7ëíy衇¬ ˆîÓO?Ý]{íµ2™~±& n'Mšäúôécÿ_vÙeû'ÞfÈþÃ?Üí»ï¾&ˆ¤ÕW üŠÆŽkÆ©bœ8¾ýöÛÛT"€Ð¯óÏ?ßâs\qÅîÛßþvZÓSrÈ!î‰'ž°y€ˆ^»îºk ¯·{öÙg/"Èüâ¿0Bûw¿ûášZp‰ƒãô!‘‚º{^ÇwãÆ[¤ÞE¶ÊB[X¨ƒkäa‡æEøí`^ Fó„ù€ø¿Î' Cø`œà½58ŸùÊ9úÔuä‘G¶ÉWÄzcž"òdÕsê©§ºk®¹Ææ*ë§èw)ÙFxùsÎ9ÇwÞy&lR7‰ß<Ö!k‘3O„ã:ãŒ3ܯýkcXÓ´7Œ¢)óÜ¥!ŠŽ=ÚÝyç¶Ù€ó©—µMù;ì°C²ù™ÿ7• (:£F² ‘Ùj}!„€èDð㌹ýÕW_móÁƒw¢Þ©+B@! „€B 9€…ˆ!á‹Ý¸]9AtA¢©Y»ÝÙ=¼ÜrËU´û¸íodÝ´r²b=‹ð¬E?Ë–Á¸„ìEÜ1b„0`€îX@TBžBâN:ÕδvCþ‚-âàoû[‡ë¹1cÆØ8³9‘K+H×ý÷ßߎ'Ûɼ໻îºË¬O ±ÂÀ¢ãÞ{ïµ¶PBF^¢=÷o½õ–›Ö@àâ}|ík_[ätÚθTs™={¶=$9s ;,(°6@Lƒ_A0˜2eŠõ ±¡-)´K„6ê6l˜ûÑ~dV8ÌÑÛo¿Ýæ ó„8Jp<É„€‚0†ˆ2pà@kï6Ûlcb.X;X9rÌÀ±!†yÝÍÇhJbJ}Ìã{î¹Ç¬T¶Øb‹\?Ù>þg®Ó7Ö1VpSÌqÖÖ’Yün"–!>¤Yq0=ôP7cÆ ·ÒJ+Ùçí¶Ûέ³Î:¶Þoºé&+‡uû›ßüÆÖwÚØpm@HC$Û`ƒ _¬PÀ€õ~ÔQG¹ XŸKYùÉÖÉys«hË-·Œ¼)häAoŠv©B@ö@Àÿ Dþ‡9ò?j‘¿±j*U‡B@! „€èÒxò0ò„‘½¼ÅŒ¿½<‰iÇòÀ¹òÊ+#OBY~¿ã:ò._ò²Ûwž0kê:àÍË[@D^°‹¼;²–ca~ÄËñ6&Yë¹è{Æ–qbžÍš5+òbJä7Õ[ÔÇXpc,¼(Á·´5ÑƲ¼@y×c6?™ïô¶p|饗޼8yF­ª¢M^(´µÅ8PFœ÷æ{°ð.á¢ï~÷»6ß’…xaîÞ[ä]\%¿¶ÿC/\´j‡$"o٥̓PkÎ 0‘h¢×_ÝÚH?ÁÖ[ØØº }¬Ko“zðbPä…È `Ñc=fø„±¡,ÊáÚ^\+»´4aÂ[“ô÷ü£G9\cÀÜ‹E‘ÕyñÄÞY£y©µc±4 ¨Ž¡Æb¾…z9~üø\˜vhŽª(€ŸXfÊ„Y&o(™'tR‹¹b‰"š. &s(·ôÅÿHÔ­}íUOÝ:Q0>÷Þ{o33ÌÈÒ©û‹²ù >ñÄ+^þâo;0çÍ4ýM§ÆJB@! „€F€]£¸®â•¶K½ÑíkïúÙµîÉ1w 'Øãö®?Y;=mþßÙìIrsCÃ.çz§FÖMß°2À*×FX&M›6ͬAêÝï¢òÙÝÏÎó_ýêW΋æ¶'ìvg7k +\(“«Š¬äÉc۩ήzÜ6aå‚;\ÜP;ú±J`Ǽ'<[ƒu n¯˜¸Üš‹µL{( v°ÿìg?+åÒ‰yÏ…õV$œO[xy¢ÕʧïX\`q°ÓN;™•Ch3®†úõëg19°@Iks-ñ/¨˜Å–Ûn»­Å} =e–Xê€®Š²,ŠÊêŒ×þç=Ì¢r*ùžøMÄüðY(`%®áÔÇXqÄ·ƒ¾/…±mkòĽY|À}WƒùÉ|§ïÌêò€ñˆÄÄñDý"U±Ž‰É±Þzë™Eó:Žm&¶c@HbxPgø`#—ñ¼w8IÜ^%Ëb=Ð_ÖÆp[÷V¼É„ˈ]æhZ›k¼xÁ¶•MÄ €Ì‡Ed$¦C²ÏeËjD>AÚ‹;&„³´„ .D4Ʊ‡5UMBf|Ón«h ‚BmòÅ\†7ÅmBsÚõ•ë/œ*×»xb|q7G¬ÁäÚb,ÄhK¥ózàtY³;ï¼³+¢E¼ ´Í[ ZŒÆTÉ„èHL\£e‰0A\™çÝ•%ûIy÷ÝwŸñb´Å[›´(ñºÀ‘Å[æÄg~þræ7íøJ~æØùŒê›6Ú±9ªª(쌋ƒ€F¨ÿyAxJ™›…›~ÜyäSøPMë•PY(Ò~¬jYg{ÕSË6—)+ìâ(“·³åáÆ”þ·uîðÃ!7Eüh2çQØ•„€B@! „€¨=Røu'²¹öµtœ±BÇw>±6† b;€Ùúþð‡ö|ÉËs„&ÇÒˆçZ·³‘uÓ|æÏñ Ù M"ð6ãÒèéœ$Êá6Ø ·Ç;ä-–ˆ É]ìÉöçÅulåŽ0ˆ`ñó©x£6Ê%AQ ‹õ䵇~Ófú––È8Í´6×?ï2É6&—%i3»î}è ä œCš•Ö¿f8F {,*à ‰½’—ˆAßZÏWMŠ[™$ËảS)ŸVß3“ qO*X}Ð/æ4|R\øŸÿŠE‹wûeAÑãq@‚ex©4!.sEl²úÉu¶07óÚƤ W|ÈêqŽ£`OõAb·1e.J5ªZÅT•>,*ïãÐ~pêiùznN À£$:+Üp¡ê#€ðÃF «z®­ÎŠ£ú%„€B@! Š@ôàÙVé  ÀA ëØÏ.ÝF&Hf‚3CÈ1N<'A2& øz´±‘uÓˆNˆ?6âFAÄÇ©GWÛT¦ák»ÐÙ‰Nðm6É‚9¸e6®± - `9»ëóHÒJê(“·(OÑ÷ôµVø躒yñŒë DÆ w^¸ÎêH‰>p톀î­q’d{¼/qðÎýë_PWëϸÀ‚Óf£xX É:à6±´À"…µ Ñ@€`F¿87M<£,®?𱎈qÁR#¸¿úéOš =Ù–äÿàJ[°àÊãæ©K\ÜцnÞ“IZ~¼…¾2ß‚%}£¿\Ó³úÉxCÀ4ÙÖð™µò6…BxÌÕø1Sê0YÔøAl«ŸÀJ{Ê… K¬´,åÍŠp~@°†ÃÖ<ÐánHš[µK! „€B@ÄØ}÷Ý;„I>°=ãÆ¿ïjŸ!¥xî&eSí îO?üp#Ì :Ù×íhd݈<¸YÂ…â +!ûê…;¾±š2eŠíè†Ë£X"@Šòb<î•ÊìÊ®¦XÀ…Ø!Õ”Õ^çÖ?æEÙ5^#FŒ°ëcèP;\oÃÅbEÓQ6^ûN’ë„}^Âê¢W¯^æF©ÞýCˆ¢bi¤Í},4Ž>úh‹]‚"3ñiÂÚaã÷ÕW_Ù%ÊÇ-Ô3Ïa=vN±ÖøU"Šáe˦+®¸Â6\ÂɃåÔSOu—^z©Yä#Þß"x1×ð–k~æbQ"½çÖ&ˆÈA‰· —NXÞ`Ù0zôh¢hwX7\køŒ—¢1ѵdžYbȲþW°&á7­È-X¼]ñÏàJ;XOˆ`–•6è+qq’ùÖغwïnBØÇûŠp’wmÊåZRÔ–¬6&7TAù¼ûî»íÇLn’C£ÿ…€èªp‡:ÎÉÓO?mj~½¬»*Öê·B@! „@×E X@Æ-Òüšç¡Äù¼*IÍX퇬"Æg7o•®$âà"K)æúi§fqIÒÄ©"7^f5ŸCPrv‹ãN§­Äo5m¨äÜFãÇXALãm‚Øýû¨[o½ÕxÙ»îºËa—çJ¬’¾Ö3/\ ä9ãNŸâq0êYoQÙlÇ*IîŸþùæ^ðˆ#ŽptcÓkZ*³v§Ù0 ŸŽp,Ü_!bÒV<‚»)ÊL³`‰·"é. 7Šl*Àò±oÝu×m%PNQ?ñ6DùqkŸxýmùÜP5`(;e|æu 0þßP«ÈBbÀð_9{öl3ËÁ|±gÏž-ßç•?ÿÙgŸu\¨˜d›l²‰[}õÕ wv•Ö^ðøýïo¦L 6A·X8y#”ÃÄ@]#1é1‡ÂÇZVð°Ay¤o(‘LtLÞ(ƒ²Ò Œ)_‹Ü ò#ƒ¿GØ3–˜4¥%Âçž{Î| r³G}Ü\ek¢|T̰x_°`]L‹P'0J»HÓ^‚¥Q'󿘂¡çašÖö0—G`"|p²+&­Þ´ó«9†ªÊ…ýÁ´w0çft­µÖ²ù˜Wv˜µ\Ôÿ‡?üÁÆ›%*뇕q'¨¸…jæÅ“O>éðÈx2/(3>1çc>ã#‘ÏŒ#;¬0»+“˜;ÔÁŘñãÇS]æs6+1‡FÅùÜ\¡ˆ3\„ñ¹Èºá‡§’ĘðÃH™”Gi‰vq½a-3ß¹( ! „€B@!P; s‰aÀŽW¥/à9,ìÖ&B Ž>ÿáfx^ÇõNšøA~ž™ásÂ{¼ŒZ~†7âva]U–¨e*)«Ñøá†¨ÿþ-9¼Ì¸qã,ÞÌ„ Ó‹8ÈJú[¯¼Œ;;\&üP^‚¿„g‚«w‚Ï¥=p]I B84Ú²Ë.»dr ´/pQY >sàÀæ.¾›ú°BìÑ£‡ñÖq.-«Œ´ãpæ´•¶²¶Ò-ãäDC¬„¸®¬¶„~†÷d=¡-”G[ÒÈ'Ï)ú¿¡2ÕînüvÚÉÅßýîwFг‰/aKb’pA$h÷¡‡š‹ %€iÓ¦éÎś󙑨¦\Úšâí…Ô¥cÆŒi E]¨v¸¾Á·"¦}i‰r˜Xº?þ¸ä(ŠwÜq‡  É„?:L’°ÌD }câB>_tÑE©"çQ çp.œ`½ƒÙÕÈ‘#ÝI'´H•¾=ôùí$?œóYˆŒc’¼ 1?P18àËÏ8r.¾$ƒšŠ¨b !eÓÆc=ÖpàÂïã6ÛlãN<ñD#¿Ã9Yï´ý‰'žp`J*þ§,æ+?úçœsN*VYåUzœñ óŒp¢ \˜àįdùñyVíºû¹sçºQ£F™˜Æ‘›.Nçž{n¦øÚ…Ë»½÷ÞÛ.Ì3f̰9{üñÇ›•ãļÇäµ|Ê)§˜é už|òÉfÞÇœ#qQF ïQY ‘3Ï3Î8Ãæ*øQï´²{î¹gjˆ\pÕ=~üxÛárýõ×[Û˜ÌÛJ#vVp»Î>ûìLhßï Ü$€¤‘ ! „€B@6#pÙe—Ùýv’lš4i’ÝûçñyNÇý°aÃšÆ V›X'Öž¯áDà"'“VÁµ×^k›Édzw½d>1pÏ,’õ±SŽ¯Ñ©ÑøÁù%‰y6‰ƒ.°à>àŸØ¨Ù̉ë2p©„TȲzàZ÷ ˆøEê—é/‚9ÖqpŸÉ„wã7šÒ·oßVõ°7ð¼Iî3”ÅÆíY³f96ÇÂûe%â¶Àk3¶›@Ø4=dȪ¬ À‡˜0×]wñ°Yî¸ÀMýQR˜ Ÿ¬y0Êê'}bì(ƒ¹–ÖOÜ|…¶ì·ß~Ʀ•Çøƒ}™qm˜ ï¿ÿ¾u4Ëb k ÓŽfBA˜âòñ±ÆŽ¾¿÷Þ{íâˆ8¬DvØa‡´¢L”A}å•W,Ÿ±Pa×7“ñ!€wv¡·%…öòãqË-·X ˆÜ|ˆßøÿ‡ÜGagÁ¦áÊáBÙ)ýäŒ`YLØxâælðàÁfA]Ü€aI€¸Á„>}»ð [ËLLDvìƒí 'œ`‚Ä0‰ éÚk¯mŸÃ_„/çCD# |`}ƒ,t|ØÅÕCÊ_Æ‹±½æškL‰Ä§m&±ØAB„ ‚é`¶… ŸÉOßYÈ\çy+~”“í åðÎ! ñƒùÈjT{D)”VnrYpy?þñ2+ù<þ|ó Ž…Å{ìá~ô£ÙM(x]uÕU6G¸h0‡ÒnÎÃü¨v]°^Q^Û˜+ÌUæ Z",¹Xkü¨ä%DÆ’9Í|[ü#2ö¨Ã¨âÜÀÐÌW¹€#¸0ßÈ‹¢Í…}æÌ™&ª!Œ0žXg$¸0ÆÌY.¾iýúõ3,ƒõóÓ]Ä´8àÇ< ?ræòqÇg&†ô?O|I¶ñ†±Äß#íÁ×&"NVB Á „úé¿’B@! „€µE€{tžÉ“ "•MvñçÓd\Õ2‘û{‚φçÔdÞðœ¤kÆ:ØÙË&Pžógh»Þ…Ïìxoàù> ™àGØ4È3,룞kŽ1«”äæP<7À9áͤÑ"͆c‡à G?ÃfTxŽzp\ɹRÍÿð;̵ɓ'÷ɵ7Ià "ì¼ôÒKÆ£…ëu[ëe#9s.(N¸Ãs1ǘ‡ðÇxIÖÅz8f~7(#ùÛ_ Ÿ Eâ· >*+Á!´ ćß8ठ‘u~ÚqÚˆ°4uêTãá;“œ2›sáªáwáy'Ê`î°îàƒÓ6ós>cÇ÷YýÄóœ5î´àbá “nÃð’Æj®Eññˆ·g‘ÏІ$OêE~wäIÎÈèU·Á‹‘'A­<¿X#¿h#?ù"o5ù{yÅ7òÖ‘Ÿh‘Rëô“-òÄ~ä9òdnäÉ~;×_´#?©#OÜFþ† òàFÔCùmI¡½~bD~‚DÞ\äU¾È~D]¼{ë˜h¯½ö²¶ø‰—Z åxa$òúÈ‹‘_H‘'„#Oضj›W›#¿«>òÐúH°!Q§'¦#/žD~G~W»ýŸ¬”ü´Í»Š<áynö?Çxù3-§P¦7ŠüPä/‘wE1îàH¢,ƒy’;ò?D‘¿Ø¶œ>,üÅ 4håóæEê$OH>@Nä/„Ö¿ Sê!õúý‘¿hEž\Ž<™Nkyg¼=!nß{r:ò‡µ lBÿü"üE+ò"Žaï-oZÎ/û!ÔÖ'NlucÜ ^üˆgæZÀŽþø‹yäEÃÄý­Êà@˜g¬³jÖ¸zëžÈ_L£}öÙ'b€í¡]Œ("áühäE®Ôö<öØc¶N½èasŒ5æ/VVãÄ¥/ô›<þ¦;òþ)#/jY=aþywV‘·ˆˆüE1òÂXj]äñ!‘ßÅy±2bÜâó“ºX+`Ži‰~ù›[_ÞBËê1bDä-Œ¬=ñò8Ÿþyÿ‹‘·2²>…2i·¿8Gþ!ÊÖƒpZÖ^È“|Wãhåy'ùµþB@! „€B Jü†¨ÈoÖ³—''a›ìå7ÎÙóC^ñžÄ‰<lùyfñ1ó²Ûw<ß4s¡m¼ûÍ[…ýQ†Î‡€ß@jÏãpCq®…žòŒ Ã34üŒß lÏð|Ç32\ÚÆoùÍš‘'g#OXF>83_·JyõÄ3SÜÏÓiéõ×_vÜqÇÈ‹‘C"¿‰8òâ‹­G8ïå$ò;Èí™Þož²øÚC=yóÞoè5È{‹‰üÆÐ´æD^²:ý¦äÈol^$O-ñó›u¯‚Ÿñ|©'ùOÈ{àÿ’üžqö¤wäIõ¨wïޑߌ›ÌRúø?Æ‚ù—¼å‰qGp†i©è{Úì7ŠFp,ðT!1Žôn >Þ©­)´^ŽÐ{‰¼—«Þ‰ùÏ ¯ Wx»x}~3­­¸[¿¡Ú8´À§yË‘Èoþ޼%‹ñ•pÞÛIËÚŠ—ÿì7"[^l1~3kN†s¼kCÖ< Ÿ÷Úc|Üù¼àa<œ óȇ0LáŸá-“ Þ5 ïî-DlÝ2ïIpô~ƒ³ñbÞ3Š½ÃŸÁ}§%æ¸À¿ÃßΞ=Û0a]Á£Â÷Á×Q†wÇeügZ9áXÃ,@ü@;v¸7Hþ¶&É“²¶kúŠ+®0+v.„„ZÌh°H&Ú„bÇî~”l\`±“#$ÊBÝb§8Aƒˆ‰æbmMìÚgW=V | µ`2ìzÇ ;âÙ µdòƒiŠXe 8úE¾H6q0@ìxÇš%/® Ò7TC,.PRQIÙ=K«x *p\ÍŒŽçż+¿PÌŒ+š¸"KYXµÐ”;L pEÔKÊ¢]”O8—ÿ™3iub¶Œ !Š+;ìãª*ç2¼¨dV˜óJs-ÄwÀ¿OŸ>6ޏÑK&ÊÇR Üh3añ¹@~ê¢Ôwv ƒiZº ßÀì(ñZ»ÆÄÇ#íœpŒµG\mù ¿'ס°–B¾ä;sžö0v´MI! „€B@Ú"Às8÷ë$ž ±€èʉ]·ì¨ç¹™g.%!G€gÿcŽ9Æžµ‰9€'ˆàëðxXÀÍ=|n¸y.gÅŸçãeVû™y ‡¯á7%ï—' žÅá*ØßÈÔŒøÜ\ÜÍ7ßleðœâ7~.ÂÍ5·´ºi3C°ªñD½y·ó›‚?a>2ç5€§’8ï”V^™cxÓÁŠˆ9 /ø-âã>É{†r±¬€‡ÆšžÏ"´+¸¼æ]ÂýÁ½Q.žO˜¿y NÎ k+8¦8—šw^ÞwÝ<Îø|ðÁf ˆE <8ž\à¦ÀK!ê‹sÊ¡LÆk 0ǃ /úI_à8ùm;¼Q–Y^H1k—$ÇÿF[à¥ñtÄ5'`î7›ë3¬—àËáÚŠRÃH{™&Éú¢Fç}ï•›t˜%„#‹ƒ:¹'íá‚ yêÕìV¦IDAT4˜c`@^bõ“øµlR“¬yÀšgLpS…«;Ö8s‚¶²–¼£ëæyê¼ß6¤Ã_Ùú€õ ¯G?Á*Ì/D øé,×t` Ï |Ƽ½Å—µƒþÂçÂÝ6n0MˆkÃ:B§id-w73²çû´‹8ßA${×NFœçíègârCÀ;jçñ¹- âV&É2 z™ ¨fÔ••¸ø2q²&!mäG€ïóâТ;ëÛÚ7~HcÂÅ!Mà }á;o&i¾ëòúòg½—?êc|™ô7-q±?Üißs.cÁ]¯ÄØóŠ'úQõ*/Ú€°•—ª]¯§-ÄoÉJEs9~eå]äÀ–qb ÒÆ¨ þŒarmq½Aufg×v€ ~0_óD~x˜£yk'Þ¿ð™_.êÔC¼‚se­ÑpNxâýÈfB^½ ! „€B@!P9¸Š¢ºÈW-~Éq2™2³RÙ¼´½¨]Yu„ãeúNÞ¢|E߇úx˜WrNüüJ?ƒg٭ɲË̳2co‹ë7\?á> Á¢(•¡œ2m yÓÞ‹0ª¤|Æ6k|ËàEûÊ_IÒzSÅ1:ŠŠ!ˆ¥@3¤ 2ж¢×äá¦ÁsžzÝPà„o¸¼”7¹è›ˆÝrzÑÍ;ÝÁ È² ¥ÀćP"Y^}ϼ˜Rÿ‘‰âJý꤬"s»R60˜0^¸G»é¦›ìâŠ:Šë5Ä^Ì æ.•ê™À‘¯Ìº¨g;*-˜`rA¡GIïæw4€"'®áðÓX´¶˜ÃYÛ´v1v˜úÀXÎ%3kL‰OƒŸá2 a±†ue-S¦åB@! „€B žSËøO?»óÅ#†nk„âV[mU7ž£ó!§ ! ÚÜÀO7\XXàî ¾N)† Š X.€¸mÂ\íwÞ1âË‹¬Ä|vg3ɪ!í³ÊÇ©"7!áx¥ïœOß4‚?¹¢2/’.˜ŠÎ ߇ú8¿{,Î2©’9Yã‡ê‰X„{£éÆoÌõºÐˆöµwðaóbž…|{·Kõ ! º2O>ù¤›ÊîŒO+‡ú ÍYˆÄa' dsV¢>ÎÉË“un8ÆX ¯¾új&iÌø!*‘7RÍ–Àâå—_6< Ÿ·ûŸ¾Â{=úpÅí A­êQW­Ê\°`gγŽéCZb®37y¯%†Å:ꨣLü ^„vÙe³J!PÖ)jÊK ÌeTýŽ`u“×}'„€B@! š,ÄçÎkq/Øì›Ñn¾ùæ\‹ç6ü‘¸og³SÑól°®àœf¬O<»ì¿ÿþÆÐN%! „@WF±Þèë_ÿzÃ`X{íµÝ}÷ÝgÜ¿3p\Õp¶ ëH+Îf¤Û¡QAäŸ={v;Ô˜_Š$%îs®½öÚÌø¸¾ºá†Ì=Tµd0¾Û(+-AÊBÔsc„k§¾}û¦e+u ÅrРAæßô׿þu‹Ykòdêäæç£Fj¹¡Kæ+ó?Ä=î¯(ïÖ[oÍ<²E½{÷vs| ï¼DûŸ´úHyW]uU&¡puÜqǹ-·ÜÒÝ}÷ÝiE5ôVn<¹¨Ñ§¬D?P&õô[˺À‚báÂ…nÆŒæ’-­MÌeæj3$¬hX§ü(`‘–˜GEGðóøÃHZþJŽ!æÅëEdÕ!‡bâ)nè8²î¯›èÇ6ÛlSø •UŽŽ ! „€B@!n¯p]‹wž BâÙž‚第÷ê<‹‘C8'+o8ÞìuО] Ö´«8̽ !Е€—ƒ“mä5Ï,0´ƒöHü¨|F6Ô„Ä>Ä>Ä77i&£™¸D‡Œ:t¨1bDå½-8²t½õÖ³ãXJL›6ÍÌŠâ§qSóøã»ë¯¿Þ\davOÜ0`–D n˜È'Cãù‰©0nÜ8Ûá5L<ÇÉ'Ÿl$(îtÊÄ ˆŸÿ !‹K/v?ðÀŽXɶ“R+ì~kÎkk"æÈàfÍšåÎ:ë,‹}À±xâFñ•W^1"Ÿx!Y}D `npãH0i„•dâÀnù=z˜ )nfÃ8„¼Ü¤bâÌ\bW=æ½µNÕÎW0ÇE}}ê©§ì¦:y¡¥‚ÓÝsÏ=ÖüZ’÷I<º`>öØcîœsα9ob˜žzê©ÉÓò?â*H¬/\쿾¡1<ÌpÍa}Ñ?D˜õL¬' î¼óÎV÷å—_n.²Òê|ã7LeÎ# * ! „€B@!P{p[ÅsA°ä5ð\ÉóœEVÂÓÁ /¼àؼ´òÊ+Û&BÈ©¼Ä^\˜š±ˆ5Üf_vÙe÷`rƒ•7šúN! : mg·kÔCü¨aiQÏþ1cÆ´*™›\NŠþýû·ÊS«ø¼ÄuÍ>ûìcÁd¸96l˜ùUãF2Á‚4vìØT(ˆëœš†<×:ôðàÁ&F#`ûí·77\ÍìîÇUÂ;ǪIÄ oì,§í¬t ÀÜÀyæ™núôénà 7´ïª©"Kâ œqÆ&Z`é±é¦›:Li ÍgÚDœ’´„¸±Î:ë˜c€‚/HxÚ°0?~¼ d‡v˜ÅÙk¯½LˆÂ2’~„ &ìP_RI«»ÒcÕÎW„ n†Á ‚1G˜”ýì³ÏšÁxA¢#Ž×¥ž‰uÁÚD|DŒÄ2éàƒ¶¹Š tË-·¸;î¸ÃL¥fxAh8÷ÜsÝ1Ç㘠ˆˆÌû©S§º;ï¼ÓAÄ$D°º©wêæ]rí»ï¾ö…0ºí¶ÛÚZ‹×‹8àׄ¬5?GŸ…€B@! „€¨6’¥m„‚ü癓g³¬Äs3ϲ <«ñW¸y ÇAiÆ:èËý÷ßoÏ+¸–’7šúN! :  @Ø} Ù>`Às[4|øp·Â +´ÂË ˆn^ÁÌ´U¦€´Ç*`æÌ™FæžtÒIFÞ³ú×Xc 7yòd׫W¯ÌÉG ïY1a¿&7+Ü4±Ë„›0È}n:¨kÙe—Í*¢ôqÊe'<–ˆNˆÙàH3þ|ö_¿~F°C"W› Ÿ¹q:âˆ#Là¡ÏÔG¿q•5qâD#òãVñº± Ðæ& ˆcÿ0öÞ{ïá a…ö3~ÜP"r xP'D7ä2q?&MšävÛm·x5ý\Í|vaiÁ80{Ê”)&âà†Š~`©‰O¿°2ÂÒ ˇz$pF@¸îºëL\B¬ÄV˜« $<$4ƒÂœæZ2oÞy‹žÇBþf­ƒçX6Ýñª'ïb ëB@vB áýÄ  ‚ CžrÊ)‹tr—W¸ˆâ&ƒà/ÉÄu\7!`ðÊJ ć Ì¬Äù”ìh'ùÓO?mAÑ!Ü7Ùd> X¹ÉI&Èk\+AÔ“¨'ï&ˆü´éÄOt{î¹§ÅByþùçÍ–¸¿´ÍâýN¶%íÚL,ˆl, èßK/½dåãv 7GXm 8dÕI¹´œ¶%ÆwÈ!†ï±àÆ’ñ$ˆ°;ˆ>p‰À|ˆEX½ ЭµÖZ6·Ø±„P‚(’6^ñùQíº`|¶Øb ³–xâ‰'Ì=–'Ãb÷eÜ(#(PoZ‚ÔGÌaNd%Öb1E²vP±¦Y‡”™L`Áq®'ŒV+qÌ Ö7sŽ®;àÉ+™‚…âÏlüºÕÿñþ¥]8yˆeëõø<èóƒ>hkËæ·’B@! „€õA€MsaÓ"ÏA©OmÍ_*Ïtl(ä™EÖÍ?^j¡B@”CàK^Õÿ"jW¹üuËÅÎvv\œp æo’þñÄMIp%±ß9ò…] iÄvÈÃ{°®È#„C~ê$?õ‡z9/lç„:ÂÿiíáÆ 2"üµ×^3òŸ:¨‹:©‹W™6–íwhOx§Î 7|`J}Ô[&q.©LÉv“PoÀ‹„Î'HÊ ¼Ðæ¬6/Œyy1yãGÛ8/Œw¼îøç¼|á;òg•òd}êÂj…¾ò"/}¥!<ÓæyÊÎJÖe†r“mÊ+‡>Ð^RÖ˜ñ]˜[”5VàÇ‹ïÉ—•B[Éok(7´)«ÚKž0²êáx(‹Ïyý‹ç }¤}K‡z¨‰JXh剧ԡ$„€B@! „@mèí7²‰Ä†ÁæZ€L:Õ62buŽ+k6¦±É)/5{l2Ã}5ýà9=<3åõIß ! „€hv²M%Ú¹åì¨gç=Äq[Änkvw‡T†|Ì#C9¼gÅñ<á3äd¹ò%ß+©#œKÙù_i*Ûïd¹mí[(§Òz¹y—¶`êä½Á¤-},3×hG^¾¼ï8—T&ùŠæDQËŽS%ãB™Yåæ•ÃÈ:¾†T&OYüòÚJ}Emªdý•ú—–'‚ b‰uüñÇKü`é]! „€B@Ô ¸Û«®nýÄ—ùðïÿÛñª$5c¼TÈ:½’ÑT^! „€hfdÒÌ££¶ ! „€B@! „€uA`»í¶ssæÌqÿùÏœœc|ñ*«¬â ä?üp¹ÁªË¬S¡B@!ÐÞ,6Þ§ö®Tõ ! „€B@! „€B ‘|úé§f¹1þ|sgµþúë»]wÝÕMœ8Ñ­»îºnîܹnÁ‚Ž`é—]v™7nœûîw¿kî²8òï»ï¾n£6rùË_Jåïß¿¿åã7ÜG}”Y~Ÿ>}ÜÀïÄäxë­·mÎjÇwÜqG׫W/·Ì2˸wß}×ú•—ôèÑ®gÏžn‰%–°üï½÷žÅCÙyçÝj«­ÖÈáQÝB@! j‚€\`ÕF"„€B@! „€B@t$†n®ž^|ñE.zôèáFåºwïîþö·¿9bb–Zj)·òÊ+›A€ðp<ä'xøôéÓ[ŽåïÖ­›#öÈí·ßž[>Öx  ”ÿ裺÷ß?³=Ô;bÄË?mÚ4÷ /¸?ü07ÿ6Ûlc¢ÎòË/ß’Ÿø&²ˆ±¡Ñ! „€èÈV'DuA! „€B@! „€¨ÈþÏ>ûÌb_,¾øâ̼+EÄ” ôTŽªÎB@!Ð<Hiž±PK„€B@! „€B@! „€B@!ðÿjTŽŠB@! „€B@! „€B@! „@Ó ¤i†B B@! „€B@! „€B@! j…€Z!©r„€B@! „€B@! „€B@¦A@HÓ …"„€B@! „€B@! „€B@Ô  µBRå! „€B@! „€B@! „€Mƒ€¦ 5D! „€B@! „€B@! „€¨@j…¤ÊB@! „€B@! „€B@! šÿh‚Pr}~GIEND®B`‚stargz-snapshotter-0.14.3/docs/images/estargz-structure.png000066400000000000000000004002361440204344700241100ustar00rootroot00000000000000‰PNG  IHDR(é}V‰gAMA± üa cHRMz&€„ú€èu0ê`:˜pœºQ< pHYs"š"š¾Ýû*YiTXtXML:com.adobe.xmp 1 LÂ'Y@IDATxì˜Eþ÷ËSïb¨è‰s@DÀL¢¢¢`FQ˜Á€0‹  (ÁœÄ„#zzzæì½~ëó»·ößÛÛ3;³;;;³û­ç™Ù™îªêO…®þ¥Z,òÉ)‰€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ@ ü©ˆe©(0RP¨#ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€€EG®E@D@D@D@D@D@D@D@D@D@D@¤ P(:)(ŠŽ\Š€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€HA¡> " " " " " " " " " " "PtRP¹ ‚B}@D@D@D@D@D@D@D@D@D@D@D è¤ (:r(" " " " " " " " " " " …ú€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ@Ñ HAQtä*PD@D@D@D@D@D@D@D@D@D@D@ õ¢‚¢èÈU ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ê" " " " " " " " " " " E' EÑ‘«@)(ÔD@D@D@D@D@D@D@D@D@D@D@ŠN@ Š¢#W" " " " " " " " " " " RP¨ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€€EG®E@D@D@D@D@D@D@D@D@D@D@–(¿ÿþ»ãõßÿþ×-¶ØbnÉ%—tK,‘^ý|Ž-—ëW=ë—À¿þõ/ë{Q¹?ýéOn©¥–ÊX¡|ŽÍ˜‰~h´ècÿþ÷¿+úÛâ‹/îþò—¿¤òÈçØÔ ôe£#ðŸÿüÇýñÇ÷Ò?ÿùÏŽ>––ò96í|}'uA€þË:wÖƒ¬Y¦¥|ŽM;¿±}Ç=…uvXosýaÍÍÚ‡Ïù¦|Ú Ÿcó­Gc:ŽÌß´'/æùLÏLI.¡ð^ÓD_áU]¢¯…þÊã~D]s9?[þɼé»äÍ«¶yg+·X¿…ëË·¼\Û&ß|u¼ˆ€ˆ€ˆ€Ô–@º„¿¶¹øü~øÁ=õÔSnÆŒîïÿ»kÞ¼¹;蠃ܞ{îY¥¤|Ž­r²¾Ò?úè#7qâD÷þûﻟþÙ­¿þúî’K.©"ÔËçØD1úWŒÊ­·ÞzËM›6ÍúÝ?ÿùO·ýöÛ»Véoù+¼"€ðçË/¿t3gÎtO?ý´ûꫯܚk®é<ð@×®]»J€ò9¶Ò‰úGê˜ÀO?ýäž}öY[~öÙg&0?øàƒ]·nݪó9¶Ž«]Ù£ÿÇ?þa÷ ×^{ͽóÎ;&ä^k­µÜŽ;îè¶Ûn;·âŠ+šð8WEE>mϱe´*ÉÜÍ:uΜ9îÉ'ŸtŸ~ú©­˜ç÷ÝwßœLÜ'X‡|óÍ75¾‚7ÞØm²É&ËCB=?üðC÷úë¯;ú}oÙe—u›m¶™Ûyç]«V­Ì(_e‚û_~ùÅ-Z´È½ñÆîÕW_µ¼WZi%·ÑF¹m¶ÙÆÞ14Ê7暑Ÿ´S> E.í[%(5%¯ øöÛoÝyççFíš6mj‹×UW]Õí½÷ÞUXæsl•“ëé <èe²®§j©XO…Ë/¾èºwïîè[Mš4q<àüöÛoU„Åù[*p©3‰Xªe² .•º6†z0<òÈ#î„Np(Z™ïèoÍš5«Ò>ù[*ì‚5g°`,•z5–z ºà‚ Ü„ ÜÒK/í–Yf·á†¦ÞKó9¶ø!”Ca‡° Ka¥†Iàûï¿wW]u•9r¤µ7ÂLæíÛ·¯"hÌçØR EfŽ VÞÅœ"Ð…×øñãÝõ×_o‚Ýøº€µÜî0ÀÖDÜ—ªSRäÓù[jí«êX«Îp¼æšk¬Y'ÐNu1Fr­#Bý‹/¾ØÍ›7¯JµC?å=ÞG’žuÖYîœsΩ²vá8ú9Jƒ+¯¼Ò=ôÐCëPêògýÃÚ»ÿþ¦° ¬\y#´¿úê«ÍÐ¥ç2žÈ›¾¼ÜrË™‘[ß¾}í˜kÞ¹”_Ìcî¹çwá…V´C.í»üòË»!C†”´‚‚ç^\O&ϸbrVY" " " Å#ÛŠ¯xõ©T I,kn¾ùf·îºëÚÒî»ïn‚•Júò96yn}üÏBù‹/¾p·Ýv›-ÀÎ<óÌú¨†ÊÌB <0ÿøãîÈ#´s¬ÂÒR>Ǧ_ìïxpÅ#iöìÙîÐCu[n¹e±« ò°öc®cn@tÜqǹ¿þõ¯‰£þ÷o>ǦfPä/O<ñ„YäbÉ™i¹Z¦8”ªÏ?ÿ¼C õèСCÍB!P2åslòÜúøáê{ï½ç&MšäV[m57õQ•Y÷fÍšå|ðAóüA‘Û£G‡ÁJZÊçØ´ó‹ýÝÇlÂZl]»vµk,F¸ß¼ûî»&Ðe~@)~øá‡›@»uëÖ¶¶ÆºýÑG5Ï+¼ù°ÜæöÙ„¢ù´A>ǃKueÔW{UW/8>ðÀ®E‹|¶1’)/¼„YГ Ï»éÓ§;®=öpÛn»mòû¿M›6U”†ü€g¢W\q…)ÂðÝm·ÝÇÓŸÈïÇ{Ì7Δ (::uꔪìˆκ…Çe—]æÞ~ûm·ùæ›[ÞmÛ¶µgHÖ!Ï=÷œ›|¸#<Û‰'žh}h•UV©8¥ò2 h@!‰7÷.¼@2%m?þ¸»ôÒKMávôÑG»ÓO?ÝÖSñsÎ"˜ûÅ­·ÞjÞù(å_V® åΩ§žÚ`¼ hGŒu0ÔÙi§ÊµYTo¨~³dZ¨Spñd‹ÅGuÞù[¨ú)Ÿ†M€>Åž'<eSN@!Ÿc65]]M  äÂ:q…VȪœ ÿ|Ž­i}t^Ã!@AIh‹êæ²|Žm8„t%å@€Ðw(×Ù;o™l)Ÿc³åÓÃó0A¬°‡ fÊ˸r"\?ë ¼V¹Ê=êþûï·½á gJù´A>Çf*Oß; ÉÁƒ"›¯>X}ðÁæÝÁ§vš)âʉx¶ÞzkS6rÈ!æQסV3%¼J±ºgÏ8ƒ®¢œç†cPt²Oǽ÷ÞkÜÂïz¨%­ àÁ‡KÕÅ•ÎçØúA­RË@èSÄ@­Îu:Ÿc˃ê[ô!Rˆ—œ­Ô|ŽÍ–~kÂüÄÇÆÏkLŸñØ#”JI6GI‘-±Ю»îê»B6+'lN¦”Oäsl¦òô½³g&æyÚªº1RL^ìA_{ê©§,4(º²%B\ÖwuÖ1%á™è'É„y£l oâIWsƒ 60e«xJã­¯$" " " "P¿Šâ‰Å#‹S¬µx°DÙMH‚0éœÇ;)üp…óó96œÞ‰WJ½Â‚—z-µÔRy-ê¹&îr½6ÊæX®‰òÃgþà|VªØÒ>ð¥¯Ð¾Õ)B[„wjÿþâßÇŽ›¼’úèð ÿÑïáÁÿɱ•‹ð'y-úÿ`æØÒß²)B{p6íBâ»Ð‡˜ x!lÈçXË(ö‡séoäËgòd¾Ã;Ϲ&Îçúè3Œ#òàú2¥øüú[˜ÿ8'\[>uÈTVCÿ>´>üi'¸Ón|¼Ã=´_>Ç&YÓ¦ô/ÞCžÕÝç“y„>J|¦of›«9†:‡µù…k yg›Ã1z/.Ú7´íC;g»çЦ´3)¼ÇÛ™þF>¼ò96yÕäÖ üF~aþÎu~¢Orm¼øÆów¦D¹áz8‡Ï0 ÷€pm¹Ö!S9Éï)ƒ½fù= PLäâf­µÖ2%ÅÓO?m Š^x¡Rȸ|Ú Ÿc“õ/¥ö¢­âí•­½“בü?9¯‘W¸Ïfê¡‘LI|êÄyä“é|;¡Žÿ `*Æ!ÃØç"—´óÎ;›ÒáÎ;ï´þF˜'¼yâéÍ7ß4á S¶É&›ÄÎøÏ|nxt0”þ·þ¤ï„9:—þ—Æ-äA¤ßчyeꃡß'ßãc‹º0fJÔ™ãiË\Ö§!ާܸ}ˆ|¸„uH8Vï" " " uK ³d©å²P&d VZ,N?ùäs;fQˆõ ®½A8ŠcQC|SÎùõ×_mÃ4 üu ‰‡F6=ãÜ\e‘‚6¨fÓÐ… Úâ´Y³fV…Åïꫯî–^zépxê;×öõ×_[\o6ô­x5Ö°PTm´‘] ¤dbÁóâ‹/š;11ÁC>áÚX€Q>qX•jG7wú±‚±öcñºÅ[ØÆy¸xî$™h¬´Ø(–‡­<ô„ö¡Ïñ€Nçsl¼œúêô5BV1ÙÀ±ÉØzùå—+?Œ-6=L>Æë¯ÏU „~Â<@cÓ^¤èo›m¶™Í ÄìN&Úéôzë­gm–뱡êE_þÛßþfóñ£±xmÞ¼¹Ûpà m³D, ›4iNI}çŽAŒ#úÏçŸnã€ëc.'†sr.§oQ.s,ó4á“Ì?ÿü³•üKÕÍ·©•jD_Ÿ{Ö‚ ¬Ÿ07aU ;=ðçÞOÌwl8úþûïÛX'\"}ûÕòË/o‡òΦ٤\EÈ÷k1‚Júu¥Ï’/‚"ÊÈ&T Ò;Ô±Ã8àÚ6ÝtS[3¤ÍGÌ˯¾úªõgÆuáÃ\M=™çéçJõO€öa`¢™èµ•Í!„£áþ“LG¦?"†¾Áÿ¡¹38?ŸcC9äG_¢ÓŸØŒ{ûÊ+¯lu£2¾âý>œg§|Æ(/Æà¬åx§žÉ1Ê—þÎ}&ŒÆÐܹsm<’?ëV­Z™ ,^^m?sÿ§lêÍX­.ô[¼ý1þÌê^Ý;s'{;ÄÇ÷jú`x®H#Ü_iKî¹ô_ÆZrŒÐ‡2…Sª®^…økâÅx§¿e»'ÄË£ÿ£tÀC‚ñÉØ¢ïÅùrýäͱɵHüØøgî ×\sŸë9ñóÚçšö¿$ÖµÌÕÜ—Y3²¾dÌz€öäÿ¤¢‚oÏ\̹Ì÷ôa¡áþÖÒÉy”~Ïš(ÈX+±>b“tÆ"sy¶öeM˽‰°bŒ7êB_c\³Q<õN–™¼fý/" " "P ^8P'É/"ƒüfdQÓ¦M#ÿðù…Iä…ïÑŠ+®ùjäoþ‘8ªT¾`E~s¬È?Úq~!ù…Lä…{ößûEGä Q>džBüaäc™Fþ¡1ò «Óºë®kõòË‘_ÔD#GŽŒü")œRåÝ/â"¿ ‰?üðÈ/œ"/à‹üCIäã"[ý"'š5kVäP«œK½;vìhÇyá¾Ê‘ð­¸6|òÉUÎӹ𰑚E~÷Üsí˜d®^ðj}“~æÝÏ­}ü´¢}è^x¡–ϱ¡œúìôÇ»ï¾Û®…kóÐ6¶è‡\//ÿùÀP]½ç@À "/h‰.¿üòŠ9€¹€}ùåÊ+¯Œ¼à¡Jn^áyჱO›üƒQtýõ×Ûyù ò]‘ßÐ4òÂ'« ó‹ÛœÅ|Ç\ê7>µ¹4œ“|gŽö¡<"¿)mä…l6W2ß1—{Gä7½ŽæÍ›We.çzýæ«vm”Å<ÇXâsèo»í¶[ä É"õŒã–û‰P¶û ÷æ2Þ™Ïü†×}à UcgE‘@F~ÃPcͽΠ¶"/²6 ü;uêdÇåsl(„û WÆE>œ†•A`~¤o0¿Ð7Ž8âk_æä´ÄØñÂÙÈ ‰ì\®‡k£Ÿò™±sÉ%—Dß|óM”̃²½¡‚õkîì¸Æpm^  :4­X}Wd^Øy|tÜqÇY¿¥o0?r_fÞ£'Ožy}•šq÷JPkWÖ’¬™¼B³¢}H—èÑGµóò9–èS}ôQtöÙg[_£^¡Óÿ˜«ü†½‘W†T™ßâõ­hüøñ‘ßÐÕÖ•\}˜u/ãÂÇ»¼AJ‡xòÂä¨oß¾v-ôa/D³û2ã5ôãF¬5 ¼00òavŒ-uÏ'±ö4h9¿q¥v˧ ò9–ú•K{±ÎÏ7Ñ7˜Óâc„¹þáoù½RïÕ·ÜrK¥1Â\ÈX }È{ TŒ‘|ë•<Þ+òlÎgqÇw$Îø?ÏUÔ‡ëcÎÏ'ùµ#ïuy/Ÿè¡‡ªrê¨Q£ì~qÌ1ÇD^YSå÷†úÅùçŸoóá!CªÌ-ù^s®ý/9‡%Ëa®ºà‚ leý_ ÓŸo¼ñÆÈ+a«ÜÏ_zé¥ÈZa~§óÎZ"ôcÖªÉ{DXŸ²– ó-s/÷Ö«ûî»oª¬!^o¿™¼•Ã:×+:ln ãÎ{ýD¬u”D@D@D@ŠC N<(üC„y°¹™,8¿ u^¸e@X8²!Ÿ_¬º^½z9/Àr;w®°¦Àê—[¿à6 ÿÐjnè^`VZèe°¾ð vsáÌõXÎê+5¯p~ñúj³ŽÀ² +ܽrÄsÎ9f¥Ç&jI+® «êŽÅ†_Ûg¬“¸V¬ú°ÈéÝ»·å¿ÿþûW\uð¼Î ÇÍê«>cåá˜ülV~gŸõ§f°À¹á†lƒ=,nN9åó  ±òõ dçhÌªÛ Ž+ÅÁ¥}¼@Ìú†ô,3½Ø*ƒŽšÙç|Žå„úîX€î¸ãŽ6¶`¬Ñ¼Äú uÄ:Oý¹'ÿ@fcÝ+ÌzÏ œÌ“ *¬¿øž9«.ææ®°4>|¸YÛbýåìÌjœHI´Ö·¤|Žåx¬€)ß?ÄÚ¦²äMŽþݺu3ëÀE~SÐxÀù‡vûÝ+È€?V‡þáÜî»x9`팥 íÜ®];+Ð?üWX'æs,'cýL¿æžGÌïc=Ö<}°&Î8å±±)Ö”ÌÇi팵8s+s–¯Ì·X1r§ßq?f®¦¯Ñ©oH^ì¼²Ø,Ž™×YSpýôEýœ1£Tÿ°²¿øâ‹WdZÿíÙ³§ÍxTч'L˜`óÞ]¬YŸ…DLy/,²ù‡ÍlYî·ß~¶Á-Ç0‡/™|Žå\ú¦²ºqãÆ9/¶q„!^xNœ8Ñæ8êÎ<_œOâXÆ c>α^XfóÂã9“µó)s;߳Φ.iõuÀ£u,ë¼–}‡§¼'!½‹€ˆ€ˆ@Ô…ëu/$0ë³aÆEXIÆ–ž<òˆýîfÿ=|ö ÑèŒ3Î0‹4,„²¥\Žõ7fýŽEVÅÉ„u»_ÌXy^›jaEò©§žjXùÅq¥l°´ð!LÌzkôL–T‡µVÅXè)†\ñÌÁ’‹+/ô­’1>xöø‡žhĈU~_ø‡!³fô ÔðUÆ÷\Ž-¥þÇíÑ£‡Y9cªT3Xoù‡)³ f{åe¥Œ˜°TíÒ¥‹y.xaX¥ßãÿÌž=Û,À½Â6þuêç\ŽÅ’Ð?˜EÞÅÝ,/“yáTtÕUW™:ÞiXøuÔQ–‡WfT™ï˜Ë½€Ñ¬ä°äÇ?-a=Œ…s¢_’vˆ¾K!€w  x%Œ=ºÊ½O?¯ø±{}Œû`Zòá›"/ˆ¼²+š4iRÚ!ßåzì3Ï7°® cÄ+uÌ£.pK¾_tÑEæ=‘ËIž›Ëÿ5ñ à¹‰µBÔ/mÏV6^½xûàÕÄsW<±nñFHæ‰wsòy3~lCû<(˜;Y§áA’ö:þøãS=O|úß‘Gq_N&úèM7Ýdë܃>8òxÉCl^óB{~FÉÏOæKÞyVÉ”Xo²îöŠ<‹Œµ`̘1¶îñ†‘•šUð À[5 åâI¡$" " "P|™w›ª¡rÄ/RÌ*«1,¼ûw«\,‰!Šu_è˜õ\ ‹Ëë4¬Q‰m‰qÓ“ ¬H±^Æ $n©Á±\VÎXd`‰ŽgH°„ yaiA¬X¼4°0åX¥âð m³ÈÅ[6H³ó9æUA­hÎ)FRÿ+åâ–AÜ~ÿdÖ}X„o‡P æbàú‡G³ Ã²Ñ ¨ÂÏuúŽ5q±±v ^?ñ±FÇË`êμOX{·{ç$Í*k¸ä|Ç9l®ŠG^h^ÈÏBŸkA«Høûð5v¿ÄÒ:éÑǾ&Xuã¬Ñ‹‘˜Ë°ˆ¥Ž^ð\Å2“~‚õ/Öˆx`M™LôM¯°³±Ã1ä“L^yac‡ëfìk®NÖCÿל€Wd™E-ž1¬ùðHŒ'Ú p¼­ððÁë‹~UŒ„%//ÖqkÞP6s7ãOöYHÆ1ÇÚ—ñé¹vmôóä‰'Ó>ûìcB\–Ä¥KÔŸ9„:æ›°hÇžûY±îi µ½èx–g#ýüYkð<Oxã ‡žÌÉÄs·W4Ùzû9ž‘µI”Çžoxpâ‘æ!º•çu<=y~gí’–xfÄsï%¯„±{BÚqúND@D@D n \APŒ…6 PÂ%…üárXH \’‹‘x¸Ä=Á‰”L,„ DÝYHÇׯFm$D™\EY(¶Š…švq‚uÿ™‡ÐXh¦%öÉ…P!ÙŒ3Ò+øwêGZïòPæ­OmcLÂU¤%æ@”µ„°áAÒ[ê¦VðïxXc  ÄJšÐp"ýû÷·$ñ°*TaЬY³L…â6)œ ¦ ¿¯Ž ¬§OŸ¾Ö{- ÀÁ÷$„£IRÈÁ>÷+ú"ÂÒb$úõ"!ø œBR`A"Dý+MXp‚±ƒyçwN­6Â&ú( 3kì¤VF_æMÀÛܘÒ!lŽË<˜–v3?¢òž7¶™nÚq…þ.ÙY07³fK&„[ÞÙÂD&׳êJ’°'™B°É*›eRs)$ÚÆ[²Û á\¾‰óIÌ™®;ß<«;¾!¶W¾c„ùû9cª\ý,ÞßjRoΧŸ%ûZ!ò®I}Jéï±`!‘0&I{.‰cÒR¾ý{2ëÂÃÅ“`FyÞ›ÌæñLJ(Ö*ôaÖ*µQPÐî„efîâYŽuhZbŒs7Êòd½Ã9¬©á“JôpŒÞE@D@D@êžÀ….ë¬ÉX ` ”)ñPC i¼|(S¤Y?d:¿&ßSVzÄBgÿ  >,† Z¨/ågQ^¸6êΡL¦Ä±Ä#f†B¤®¯-S=Ó÷,Tix£€àa6S¢ PÅ«¦Iý¯”‹WÂ,ö¡áo½õÖËj…в!-\Ê‘ü…¦8ÀR͇23¥1V˜(‡Ã|—IÉJýPÈâÆÜE èlóÇs <Øû‚ü•jG€fú Š€L‚]J }ì"¸á~S þˆyŽR¥1 ñ‚÷ôп2 );ìñƒû$Ÿ3%ú!ÇÀƒ½L”ʇñóQ´1ç üá˜)ÑÆ¼‚•|¦ã ù=^>¬SÙë„ýÐ;Ä9g¾}8)—°‹ú¢dã¸ls$ ;„{X{³>Ì6÷ÆË¨«ÏÌ×¼°@ç•o‹v<ñ¸×#5Äö‚#ýˆ1Â<žíY¡>ÆH!Ú•~Æzœù€¾–oÿžô³ø>DÔ½Pȃ3¼úòÍ»×WßyÐ/˜·j2§äÛÿ˜Y—p_Ž'¾ãÍZ%/ÄŸY7ÐŽ(¢1ža P¯æQÚ;ìO”mî¥<Æëê˜)¡œ ~J" " " õG à ¬(yKÇ ÄÏviÃb€ ‡dx”lçÖä7oXb²1²1é.ðrù=2œßiÖ{Xq²¸bÆÃB2qm}ô‘-°qù϶d‘ÌBoŠ¿ÿýï&ÀLæ§ÿ K &}sÂ#©ÿƒrñÊSY+­´RÖ‚y8"„ʳÚXe-$ñ#1,ïÏ=÷\ÛœÐïçcážÈ1âË=sóT2q}( cÅæÞÌי„Î( QR hQªšô/„<¨û=+jWxg£”cÓ_ëܬ6ñ\#”!¿uƒE9ãaE²ï„¾E}±‚Ä=S¢OÂ`¥ò!€‰} mM¿˜¼˜s>#Ñ? áļ|ÿý÷»>}ú˜ñ eã9Á<É\FýÓ”®–¹>,sYÃfSfЇéËi¸K¨Ÿ‰cPPPÿš((‚Ð1Bâb¤†Ø^aŒ0>² váÆ}­&mVŒ6J+ƒë¢ °¦Þùöÿ  #¤‚nôå7sGZ¸¶´zé;gó}0×þÇZ6ÞÅùá?c4m®ŒKûð<ÄZ¥p6Åuü¼øgî¬#x¾fãí¤püXŽ ÊKKôÖÆÅšËÒê ïD@D@D@¼wv¡! ðåAŒ›}u‹mæXX²`Å’¢‰…ñÒ =+,ô¸Kó‚k ~çA5iIÁµ!|CØ‚5`¶‡Q®kR®O©8jÒ÷«ïAAý¯8}¡¥ð ÃƒóJÍl‰‡1æC—>„#üáœ9s,¬¡ß´Ú{챇…Çñ›ñVB„¾ÅØA ¼×& "$F‰¦þ•$SÚÿ3×!gÉfÎU `âþˆ0‰W±JZ V؇°#„/¡?ó™þ‰²%¡KÇ×Ç‹1Êɺ7S¢3ðÜ,…xæ+ìF¡Ã9(¥¹Ç$¹Ôåõ5´öb|ЇÕ vŒ“b‘Ú¶'÷ ú÷1żòQÐÅÏIžGÞÜCX_…ã’k™lõÇ–”mìf;¿ÜË·ÿ±–¥¿²–'ÖÂÜ×iãêži«x>ôë|kSÊc]@Dƒêà@²~H3Æ eW·Æ Çé]D@D@D î\AÁ ¬PTðЖ)!fAÉB…¼b%!,TN8á K€š=)žzê)Û¿€‡Ubc³W|1̵ñ?‹¢áǧnêY¬kP9U „¾‡Ëp°¸­zÔÿ¾ }‡›ê„c™ò¨é÷ê5%WZç&Œ‡nÔx8Ë–8†y&xRd;¶Ð¿1¿n´ÑFöbÆÆóÏ?oÊ ö b“ì_|Ñ´q…*×ÇÿDPf(.o¡[&{~ÉþE‡L)ô/ŽÉG8“)¿|¾GØÀ&À¼\¾óÎ;vÿÄ3‚M»ékxY>!¤Ð·8—ïÏ<óÌð“Þ„AÌxX!Ë–ð¦áÅœZL7u¢Žx”ñb,á5†%±ÕO>ùdwê©§Úz1.àâ3/”xÜb×;Ïê~#f;s:ŠÖë°‡C.‰}gx±ÖgM\@2—<ó9¦!µ×Bb|¤í‹çRŸc$^š|æÞDÃÒžWÚ¾Diù²V§¯1&ñr?“…ãCÞxCjˆP`¹$òÆŠ…Ï ¹öÿ\ò.—còíÌì{•T83÷q_g-Ì1Éßã‚>Bg°øZäÃXU—‚eNuÇé÷ˆ÷=Ü~³ñ§r mJX’úJêõE¾öåòÆC-BÙ°E¦\Ã1XŠÕgø#”c̵“¯¹æ7~üx k‡Ž㉺¢¼ãáVu)Ûx«î\ý^•@¼e‹¯ wW<ô#$HàTͽn¾¡ÎÄÂ0`€õ­óÎ;ÏFÄø[Ås\è[Õ­ꦦʵX[aÝLßä•mŽÇÐë³³&@xzøá‡»±cÇÚº5*h/¿ür%l!¼B9,z«KÙ®¿ºs ý;BF±ÑFÌÿÄ„Ï%a‚Bxƒ°ÿF}¦ro/Æm@ÿ¯Î“¥TÆHMÚ›ð9ô7¼Õ ‰¿dËÅÏc(pèki^tÛl³…é}õÕWM9Ž….‰PE„ëÝwß}mýSJã3—úâ˜|ûkYÖ°I¯ÖÂÜ×Y«pL¦„Rˆ¹’gŸÚ((X?Pë‡\ûR¦:é{Ò!Pp ¸`£|xã72>"ä÷ÝwÍbˆÐ Åp­dñ‰…^i),˜Ž:ê(s]§þñăV¸µ'‹Çg®ý*Êí¡5yåô? ÉX£aI•ͪ-äXïäjÉU[êµ%XZçÓw°Üc^@€ð SBð°`ÁsO{ÀÎt^m¾GÄC}¦z1çâöÞ£GsÙg>Ž'ÆÊ;ö“¿Åã3r Õ X8¶1 ¸î|SœÿÂ… 3rƒ=aZPºbMX¬{)÷xb‰óž–ºJ‘û;†(„C c‡9›~“Ír˜{)B°xÈ#í]}+Jý}‡‡ –úôÚ¾š–h7,Ÿ6q<¯b$ú}8S½˜ÛÛµkg{Qй†xBÀÆ+í·øq|f-ÈõeëëáœbôcÖ»Ák…ĹÔk;w®­£;uêd{u„z×õ{©¶Wm®;h1F`›©/Ò'Xײ֠Ï뿜Ï…x@ ØžåC¨ÑçªK´7žL¬Õé«ô·´p‡¬áÛ·ooŠž™3gZ¨ÁêÆ‚ròEцù2&[Ê·ÿ±¦d ›ô6a­Èš…µ sj¦Äýþ‹/¾°è im?/[Òÿ¹Oë Ú3S ^bÔ‹u±’ˆ€ˆ€ˆ@é(¸‚‚ Ö¹,ôî½÷ÞŒzÖ°ÞÅâsÿý÷/ !Ö·Þz«Ãª“M¦„ ‡„ð$ž¸6,maY—IùÀB KÌlÞò‹çÅgòa±„0Ûâ*yžþÏLËËîÝ»›@ë®»îJ]ŒÒï½÷ž=$ú†8êÅH¥ÖÿË@ÿËE¨\ >åVsUÄÙG@Ì&«i?X“¡œÀrpÓM7u›o¾y_jfŒ5Ê]}õÕ•uÇÜõ$Ãt Á³Œù‰¹ùú믛'<ÊœL÷ÊD!Ê}:JÈb=¤Õ¿>¿Ë·ÿáµ°Ã;˜2(^ï]wÝÕ ZXæåR2ñëd” Üû3ENkQÖŠ™žŸ©w·nÝÌÈlÚ´i#6Ðî¹ç›{ÇŒ“Ñ`'YWý/" " "P? ® `a—Bb€„vàá3,yg±‰»Ö»ì²‹­yQÒΘ1Ãî¡ÿ…{È£`îÇê—u_2ámB~xÞb@£ºNÔA!FEŒÕaÆÙ|µuàžÁ½/÷±‘#GÚújï½÷.в=Π¡¶c„~„¢‹ç"ÆH¸W3F¸ï2FèCx¥ÑfÅ#qþµýŒ†¾Æý€9å ‚°6¡¿ÑïX'p¡?âÁ„M™ä7ÅwÞé.ð{°na~a}˘„)cüÃ?t£Gv÷ÝwŸ)=ºtéR4¯­Lõ¯Ïïóé½{÷6C›ä:e|Ìq¬…1Ê Ï°§]Q°ñ|Í<ǽŸ~–X+Ò¿™w³)±0nd4uêTë/ô›0÷’/å¿ýöÛ¦äbþbýôüH+_߉€ˆ€ˆ€ÔÅý"î‚BÀ€Eâ¼yó*vƳøD8ÌeèСö°‡fšÐ:±¸`‘Š•–¤XeJ¹‹å "±Ì –b,zYÄ"Ü`ÑÊB›6mÌj3¹˜ ×FXÜWU"X± f“m6WÄ¢¼™,ÌX,Ïòk,œÌ °á;êÂ"/í!6Óõëûÿ€Â*Ú‰‡9ÚA< f»èsx¸`}3pàÀŒnÝ<ò0Žð¶_¿~Yçrl)õ¿ @D¸‰—múŠôåL}6+„Fø#ýŠþÆÜ†€XÞX¾Óy°b.Áƒ+ð<Ð>k¿´Ä1X§2vØai‡T|Wݱ”û<y<à3/1ß+]ú+Š”¬àØäõ„N¨²±!y`™Ïƒ%c e3ã‰y !VÑl Íï¬Ø„›~žL<4š‚1‰p›¹Žãð[Ú9É<ãÿðçÁŸ~Ø:‰¶$Ì ž|ܳxHÇË )@ Ìhï§Ÿ~Ú„Ÿ´5ž<™R.Ç2Wp/eEðL]X0ïr/FI€Wó'õg“a„SñÄñŒú$\êGžäA¿Xä•ö\߈#¬¿ 4Èö·ˆçÁgÎçž #Êen£R„"Ìeº—&©ïÆ6÷PÂ#Ñ'˜»‚B A!ÂÄÛo¿Ýú \ÖM´iZ¢°&DHK¸˜l©ºcé¬KYÌòë0”ËÌkôKîÌo¬¤2—zè¡fÅMÿŒ'úõemA$áÌe}ˆ`™q@9\BÔ4A+e3ŽX7Sò%ч©kÚ9v@-ÿÐ6(™Û™ÏáÆZ˜µ vŒ\JÖ ŒQö˜ÁP'¹>NV¥º6ˆ_ݱ¥Ü^Ô-Þ^´_>íÅżNaŒ`ÜÅÿôCÆëiô³c=Ö”ÙÆý…uuc$Î?×ÏŒ‹Ù³gÛsKG¯xdÏ¡\œ0òâzY0îxãÙ‰¾Æ^^ôæ}”a(/zsÿà—-Áƒ¼~Ógɇ±„W÷ú3ùÁ7<£áAtÚi§Yè¨L<³•Yß¿Á¶ ­i ú]MR>ýïœsÎqë­·^j1<÷£ žõÉ—ù’¹Ÿ¹ôüóÏ·ßyîbžç÷´Ä½›kcmÁ½‚9‡ïx±¦¥‘X‡ ðE‚—/ëp½¼³&€ e’s/ ÆU2áaA}Ùw¨¥WD+‰€ˆ€ˆ€Ô#ÿ0_'É "¿°Ž¼K{äî‘м "òn‘xEÞb%òBþ¬eûFä70‹ü¢3ò ô‚ëö"ï2ykáÈ?œF~±y¡Nä\‘_Ùgÿ y ¶ŒåqmÞÂ)êÓ§]›_ Ùù!/ìúöíù…qÆ<øÁ?ÀFS¦L‰8žzøEXä­€"¿à¸v¥šð;‘ȉ¼°7¢}è^plmN>|¸ñÏV‚WYðyÙ³ßr=¶”úŸ´ñƬ¼ÑØT{Á: ¯ä‰|È?ÜØ8†)ýŽ1íÃ1D^ù‡«Jç$ÿñŠëo‡rHò§*ÿçz¬ŠEþA?ò›KÚ`xa”Í9|ö{PD'tRä…ÁUÊ_x!Iä-;#/²9œyœó˜·ÈÃ{ÌEƒŽ(+[ò‘‘!]Qú›ß43ò^mÙNkô¿ù‡íÈ{á;ØÓ·˜Ë½«W¯^l³%¯мPÀxû Ùr=–~á‘÷–´û ÷vú¼RXý¨+s§·¦ÌZžŒFÞÓÇî}\—·ª´{>ŸY+øÐ‘WþU›cŒ{9\(›zx’È+IJž«‹CÀ £O<1òÊI›™yÑgXz%Uä…ôY+㕽6ïx¥UÖãø1×c½0>òʯŠ5 õa§R?/(ûe¦D½WÞ Þú¾÷¬³92äáÃÇD^À\m_ôB¶È[3[fÝL=èÃ>lJ¦¢ ö=ko8dk毼ÑÞ™ç‹^ÀyÁaÄœ”Kʵ È+×cK±½xv`Ρ½¼¢¾Æí#´A#Ì…a¬nŒø0‹6F¼w[.M”÷1ðçùƌٳTÞø¼AVä=Ž"¯¬«¸wxasä^‘0Ûœà•è‘÷°ˆ¼Ò&¯"è›^0y ýˆqÈ}‰¼C_¦­X»qÄ‘WääÜ—óªD‘¾üòË•÷¯vîÌ¥J¹ô?îûÙ÷[FÙÖœôaÆÌùÌ\êÒÕ>ßòŒ}ÑEÙ:€öã¾N›y“+$Ë÷867ÑÞÌß<ã…û Ÿ½'NÖ~tä‘GÚñ^A›ÌZÿ‹€ˆ€ˆ€™Àb”W—ú¬b° ÃÒ«,¬q‰ÁŽK)–.ÙVXáa@Ø(¬n3¥|Ž%¬Å°HÅÒ ,9üÃ…ÅvÅ{"—„×–\n¤$/t3«¥lªñ¼©7–Xõ`y‚ÕÖlX¨)ÕŽ€_äš«<¡ °Ö¢/Ɔø½IkÞ´’°€Ä +AbÔfKùK>¥Òÿ°f§ï1F±8òÂfMÖXãñfkãê~Ö¹Šþ†ESkèoX–U—°"$”sÉðrÉsó9–z`™‰…/s –¼Ì½XÁQN®X!r]a.g®òû™÷\’x•0ï2±ø'\E1öåÈ¥~¥z mÈødƒ?÷ ‹1—ñÂ’0[b~ÂBëWBakß´sò9–ó9žzaµK?c?s,¼^aVL¥ï¸r.ž‰ô1îɬZ·n]#¿Ò )ÿPB¤àÉ„Å;––Œ?BR(•Æ<ዘ#YÛ1aÍ”­O†ÚÓ‡9Ï+H3ZñÖäX,Õ™“wHˆ%êé…ò¶îd­ÊÚ0—ÄüFÄc0=\_XïÒŸ«KŒsÖ’x½QpÁëÉ èª;½Ö¿S÷0¼TÓÜg¼€ÐÆ2×Á<…r®©±´÷Vú%kNæ,Âò%CÚåÊŒû,ÏJŒú^t°ÇƒÜ {«Í&æÕf–rõ£ Ö°¬k2…éI9µÊWäÅý,Œ;`¬1oóâWS¯€p_Â+ˆúò?k+òg}KþÜ#Ê9ÑO¸6Ör´E!¼@jÛÿàÉ|J½h[ž-ð¢àžgë\Û”±Ä<„ ëÚŠç0ˆ€ˆ€ˆ€ˆ@9#‹/¾x9_†ê." " "PRP²Šr%0þ|׫W/wöÙg»~ýú•ôe|þùçnذa¦PyüñÇM¡k…Q, Pxá…ÜØ±cÝ‚ Üßÿþw÷—¿üÅ­¿þún«­¶rûì³Ûn»í\“&M2f‹âaâĉîºë®sß|ó[guÜ€Œ!'ñ°NÞÔóé§Ÿ6%JÛ¶mÝ„ ¬¬Œ×Ñ(dP˜p5QèÔQµ”­ˆ€ˆ€ˆ@™xûí·Íàc½õÖ3c ­3ʼAU}¨CNApèÓO?uXr´hÑ¢Ñ*kH' >˜ÎEߊ@}@9ñÕW_¹ñãǻ믿Þ5oÞÜí´ÓN®uëÖæÕðòË/»'žxÂ͘1à <ØuéÒÅ-½ôÒUªK¸¦7ÞxÃ]y啦Ô:t¨å±òÊ+2õES@IDATWûüà óæÍsýû÷w»ï¾»[i¥•êE9§ õE€Ð¹sg«GEEõA8<˜P(âÝ„“RéPÛ”N[¨&"PS?ÜxãnÒ¤IîÜsÏuGq„æÚšÂÔy" " "Ðäÿ¢Ì¡ œhÙ²¥k×®]™_‰ª_®Ô˵åTï†Jà—_~q>ø y5ì°ÃnêÔ©¦¨8î¸ãܱÇëFån¿ýv s5dÈ{Øa âL õÑGÙž½{÷v=zôpn¸¡[a…*C úú믛ââŒ3ÎpmÚ´1eFÅEü@]¦L™bÞ!U‹WQ"P¯FŒaëAÞ•J‹€Ú¦´ÚCµšxçwÜܹsm/.Ân.³Ì25ÉF爀ˆ€ˆ€4NAÑHÚU—)" "¼'.\èÆgŠk¼ËOxÜm»í¶î’K.1kë1cƸÏ>û,~ˆ}f „þxW$ós ž k®¹¦ûóŸÿ¾Ö»ˆ€ˆ€ˆ€4qà9Á¾`ݺusl°[b‰F¸¡A´¥.BD@D@ŠE@ Šb‘V9" "P¿?þøc÷Å_d- Á<Âr6‚f‚|çRçÖ([âØl)ÓïÉïC™”[]™Õ•ÏûÛo¿µðMÞw‡~¸ûä“Oܽ÷ÞkžñcÉ7ä͆×ñÿ9.þ?q˜Ãÿáœd^\+íC˜„\yÑžxs¤yyÄóc(;|ÿÇKûœk?K;W߉€ˆ€ˆ€4\ìáõÔSOÙÅꫯÞp/VW&" " "P2e(Fe"" ¥A€½ :vìè:tèàfÍšU¥R¢ çƒÀûï¿oÿk­µ–Y·U·o<ØGáÝwß5øÆolaRš6mZ©,”‡p}Ýu×­ôÿ DçwÞ“¿ÿú믶W{7,·Ür9—Y¥Ø¡î_ýµ…\ ûBðýðûµ×^Ûíµ×^±3ª~$N}ûöí=ö˜;þøã-dA¸V·qMï-ZdÞK-µ”[c5ŒŠ£?üÐR Žo½õ–mLM¾ááöùñÇíúñì@Ñ^„GXvÙe«ṼbáçŸvlN»~÷ÝwŽM)Qª¬¸âŠ•¼5û>øÀ6òF ÂgÊb³lê’¶ÇF¼àêúYüX}hXLž<ÙB^î²Ë.Ò’µ…’ˆ€ˆ€ˆ€d# E6:úMD@„ßÉÙOF$\î¨øôÓOw{챇#¤Q2!ÔfCån¸Á=ùä“&ÌF°½Új«¹3Ï<Ózè¡nÉ%—¬8 /¾ÿæ›oR%óÙ4Ïò‹Ÿûâ‹/:öp`¿B+9Òò@€ž­ÌŠÂ¸nö†¸öÚkÝìÙ³­\¼%H(C¨#  ´Hœ^é_&°BAƒ’‡=&Pr 6Ì=ôÐCÆÄ€ìš6ÝtSÛ4ûË/¿´k‚# ”Ï<óŒ)`>ø`wá…š’j ”;î¸Ã¬QHÄaªP:Q{Ó¦(“h#<\ìy䑊pNxHœuÖYÖzöìiõ»óÎ;­>(GZ·nÏ^ŸE@D@D@D '¬c0âØj«­ÌØA›cç„M‰€ˆ€ˆ@£' ŠFß@D 1 ÿÇÜ„è'Ÿ|²)¸öý÷ßßfèŒ3Îp&Lpçw^%$_}õ•Yû}ôÑî´ÓN«„U?Â}¼1ÈÁ{¡¡’ÐuÔQ¦TJçS& ”ßï¿ÿ~ó>À3#$<(arI„)@AÎåêF˜,Â/½ð &‰LIü^Í›7¯ò;Ö†($Ëtâ‰'VÔ %Š~ùå—ÝP‚‰ÐU¯¿þº).ðÄÀ &$<=PÈ À@AC¨…VXÁ”QlÒ÷ a½ð¬hÕªU•P[!½‹€ˆ€ˆ€ˆ@uðr}ðÁ^£¬3Yk(‰€ˆ€ˆ€ˆ@.äA‘ %#" eNA<{-4kÖÌBáù‚j,ÝÎ9ç³vÃ{!žk„áwPð;J ÎCùK!Â~Bd+}¦„r‚ÐM“&M²pI(:Ø3"~Ý( Ø·E®ñ‘aEˆ%¼PR2æ ¦a/‰ø&ׄj5j”y’Ä÷‡@yôÄOX8(Âs%Š“=zØ(|J=qÍ´]9$êo£ÚÖ¹6×͹IÏšd}ø½6e$óÓÿ" " "'À:£‰-Z¸víÚ™1Füw}LäA‘‰Œ¾D¡7!žxhÄB?™°¤Ç2?-!Ç# ¾OÇzÚ9µý.”‰B žâef¶ò=ž„¸êª«lÿ<’{k ”ÀsE‚þ\Çâ‘@¨'¼9 ™¨ËÎ;ïl{C\}õÕú õD)W…rÙC‚°\xdжìa‘L0ƒcZø®ä±õù?!®Øà›T…f[èëB)Çþ)ôùëXÆA@ ŠÆÑκJFN+{,¶pOž<¹"¹!5BuŽ#×LÑù÷äïì)‚bˆY(€¨c.e&ˈÿꎧ¡ºB8.ÆÙÃ?lŸŽ+[Z~ùåM †Åc=æŽ?þx—áZ©3õ¤¿>‰¶¤¿Ò?(ú žQ\ÞQ(*È7¾IÈäÉ¥"sžGð ?$ý%^;´+J0”€´ çŽ5(åu ^S´'lÈ[\™˜,Kÿ‹@c$xA±gÀo$ÌŒéxÈÂøqú,Å"Àš…{kº­·Þº ë‡bÕ]刀ˆ€ˆ€”)(J§-T¨S­Zµ²} .¼ðBÛ4ÏÙóçÏ7ëæ^½z¹>}úTª¿#ÔÌ$Dä÷ Ÿˆ ’ ~±'´°1öSîðáÃ-¤µÉTÓ2Ö ¼F9’Ú´hÑÂbõߟPNùƒðAŠ‡ë®»ÎøP·‘#Gš’¡7Â[„¿X½Ë?.à×òáòLK\‚Ù¤cÉOø`Çø'q„ »øâ‹Ý;ï¼cÞ4°á<”\§žzªõúuH\JF¼u؈žcQfqmŒo6qßm·Ý*”Œ7¼‚ØðeyÁ—w,mO;í4Ǽ¤$c e"cˆûLxç3óŠEÞ9†ïxqï̛ܗWZi%»—0·2¦xç…’{Q|ì66¾ºÞâàƒâ{[÷îÝMI^œ’UŠˆ€ˆ€ˆ@C# ECkQ]ˆ€d €°‹y„Ñ3f̰ tQ ÌÄ»/ƒ¤@¡ãàÁƒí¼´lùáîæ›o^ågwxë|,ÿò#€ßyçM€ÎÁ<Ìòp›R×´ÌæÍ›»ƒ:ÈòDHO\õ¹âŠ+ÌzáO\HŒB }ذ 6f#´E „€!?JŒ¸p;ž?ŸQbàÉ@¾™ö€Aß¾}uMKx¶Üzë­fñþüóÏ»·ß~ÛP´V÷™ò… йs纗^zÉ„ö´gÿþý-J“´„%ýo ÍiÊ“´s³}‡ …‚ ”&ÆšQå]z饦ázã áÛ«¯¾êP `CÐÏ5£X€Ëõ×_oŠ„ñ…J”‰ræ©§ž2!}MËIJe!µfΜiÂú œ^?üðƒy äRwúû°Ñ5JxHœþùîè£6¯\pÏàAA_˜>}ºõ_”0æÆ@¼ß¡¼âw (°|¥¿Ãš¶ã·[n¹¥Ò8!Lí7vìXóê@¡Ižï½÷žµ s IŒ)×\s'NTO<ñDó, ¹°Ð1"Pî‚2Å /æ”™xáµÇ ¯$æNÆÞMŒÙ¤²=üO~|f¾Æ €±Åkíµ×6%6s$ó Dæ^æî‹áürç©ú—Âb²NÁ3ãæu%¨ Êœšä sD@D@ÊŠB ƼªKÔ9䌇ñ;›7§%!K°ÄNKíÛ·OûÚ5)“ð4X§gJüž©ÌpÞ„)à•oB„„W¦„ ©[·n™~¶ï©'^^ù$x>äãý€ ¡7ûð*DB°†ÀÿñÇ7eÌÉ'Ÿ\!c/ ,ñD!ÔØyçW©HfXû#€Çº¦$¼'è±Á4yRAA¨$'Gu”)SjR& ”xç줓N2Å_¸8Á£cÇŽUêÚµ« 2ñ@Q„' (Êö°aî ,ZH(ºPD!XeŸÊ£S>/ÚŽ:ãÙƒ¢…ÐNJ"ÐÐ  üÄ O'æ<ÃS(ÁQÚócÅã…û)ó>cœÏŒøüÎ{øL¾Œ5¼¥˜Wxçõæ›oš¢ÃÊrÆ"( {ŒAò¥\)+ “þÔ÷&öæ¢ïsÌ1Öok˜•N'…:ˆ€ˆ€ˆ@Á 0Ãs¯ ¼dâB0mÊÎ9çX#hã»P² Ä@ø÷VA©ÁyxQ°çA!‚sö¡Ìx]âeâq“)!ì'¼{€– å {Fįe{0  @ñK¢.XGãÕ€ ¨‰º! Äª«m¥aßÞá¢"Þ(4Ù†¢‚ð\É„PµGæA‚ vÇwL¢ÿE ÁJ Æ;J<³P€ªßP´ôaùzöìiû⌱ƒ2!>Þjб‰"EáÕxá H(7Ç('P¾£Äf>ÅX9FÊŠšÐÖ9O?ý´  tGÉMÿRšø?©@MsÐy" " " "ðÿ ˜#L û~ ˆK&„bp@òkûá]ج;~‚;u‘B™qååÄËD ‘–øïö„`¯„4„0ÂÒ9žPJ ÄAÑ€ ?—ıXI£DÀƒ¤Ð mÂ:± 7ûšž ((x%…¥X’ Ú–}1’‰sh,j•D 1JHÂö†×"¿=JIöö9òÈ#M9°å–[šgß:1יּæšö"$ å#ã–(JˆÕ;ó0ceó Æ]Ô«ÐשüêŸÊ6B r¯gï,îõq¥|ý×P5(7RP”[‹©¾" " "Pˆ¯ŽA\COíD²ÏŠ,¦²¹yâÕÇïÃ>9³gÏ6/7ÂéÝwß}Š¥1áÙó‡pSI%k}Ô]e–. ¸yóæ™×!}\aûJ·­T3(RP”KK©ž" " "P3‚Ð.¶Ë Ê5®"Âzöj@¸‡PРAnÔ¨QîÊ+¯¬™2Ç:™„T‚J‹l‰ ËQvpÞ…NxŒ°ñûøñãMéÀÆÞœ£Å5â鬳Î2o ʦ] 7µí¶ÛÚæë™êƒ ‹q%h¨P4'ö”` =÷Üs¦œÛm·Ýl?ŸvØ!çpnÅâ„…;ÊÎ^½z¹Ã;Ì6æ~òÉ'Ý”)SÜÈ‘#-DÝÞ{ïmóûU ¨HzR«®*§t p/¸çž{¬ÿì·ß~Ž0eRh•n{©f" " "P.¤ (—–R=E@D@D    f/ Âü ÈK û€€ƒï‹¡Ä ¼ê"a¼ûî»»!C†8 Ä•g 6g‡øµâi›m¶1Kë—_~9ë „ÏøðÃm3ÝÎ;›'C]ÔŸj©_±ê'" " "Pg°ø':¡Œ¾þúë*åé­·Þ²pHXä"¡èHÛLšïØ¡Ðk‡:ceŒ×Š „”ûì³y;ÜxãŽÍÂãi5Ö°M¤ÙPûÎ;ïÌ !( BG­ºêªîˆ#ŽˆgSÏAÐ bçÇJ„N„zas]”I¤Ð®x€¤í£Až?þø£µ;‚«´Ä1¼”D ÜЧ ávûí·[ˆ3Æ=ã¥a’ðš"¬]9 òñ”èÒ¥‹;v¬»ûî»Ý®»îêð¬@y1lØ0G83»åÖk __úÀäÉ“m¼…PlÖOID@D@D@jK@ ŠÚÔù" " " p“=‚ Â…„Âa›jžrÊ)&ô ¿ÕôPEØBøe}òÉ'¾„Xëu‘PŒÄ…3xpm„fºí¶Û* ÿ9ëj6¦¥>( PžÄuƃMlyä·Ç{¸öíÛÇ)Èg„ áôÊ+¯T<"dÅjšã‚‚‚vŪúûï¿7!f¼]©ÂZ®yÀ€îí·ß®TO®×›¼æJê(1ŒIú<ãµ_¿~nèС֗yG1Áþ-ì×Òc´]»vî†n°ý4PT°¯ÆÑGmJÕÏ>û¬Ò|Þ®Y×o¿ýÖ=öØc6&ðDñ®$" " " …  O… ¨ð;‚k„çi‰ß›5kf{!Ä'´áI¤ZiêÔ©& GØO¹Ã‡7ëß÷ß?~š}®i™æš6mj^ɽZ´ház÷îmž „rÚj«­*6šÅ3ÅÃu×]g|¨›ÓrûNB¡=Ð3Î8#ãæØÁs™BÊpm(!¨g2ñÂ%<(Î9çÇF§›o¾¹•·hÑ"SNà¹qÒI'U:µeË–vÎå—_n{Sl½õÖ&¨E™_öØ ])7ž¨؈›kÆ}ƒ 60”J"PJPâ‘EE8¿páBשS'›Ë'É1_Ju/d]>ï¿ÿþ6W°·/¼HPB¢`& œ6Ñ.$ñÒ΋ðŒx÷qo8p …r,í«v" " " åD@ Šrj-ÕUD@D@Ê€ô-¶ØÂ,êg̘aÉ"Ô@pw^Ië[¬îlç¥]"¿³5ÂdBÁÆÎxg ä_}õÕÝÎ;ïì “ºwïnû#$…ù5-³yóæ¶±,{. ì'®‹úà•À„‡Yyå•+A¸¹ñƼ Ø0ûwÞ1 ùQbdü¡ÄÀ“|¦%ôíÛ×Q×´„Ò G®m۶^²mD»a%ݱcÇT ˜;w®C-Ú³ÿþ ¥IZ"È&›lâ¦OŸn! •I•v¾¾bøç?ÿiʶ1cƘ²“}`؇9$©x+F}J¡ öbÏ B¼¡PÅ£äÝwßµ1Ï\…ÇšRÃ'€—â›o¾i›«sÿÁ @ID@D@D@ E`1¿ÙU£Ú­ðã?vXò@• ’›€ú`±‰7®òfÏžm‚Å:¸Y³f5®‹×Õ€úYÑP« :"€wÏ>lÍùçŸoïuTŒ²­úh›°× 4ö`À#¨[·næ1€ÂQé؃`ܸq†ŽðzxTì³Ï>&¬N*ŬáÀÃý•0`ÿ¨O<ѱ/‘’ˆ€ˆ€ˆ€Š@e³¿Båª|D@D@D@D@D@D Ä àÍÃ^7Ýt“›Ü^¿ýö›)~–^zéÒ©¨j’3¼'†÷›¢o¹å–e”’ˆ€ˆ€ˆ€Ô)(ꂪò(¢ƒWa%Š|ùå—îõ×_7…J‰·ÞzË}ûí·ŽÍ;yÀFˆ²Î:ë8Î]l±ÅŠVW$" "P|Ìõß|ó»ýöÛÝm·ÝæZµjeaÚµk§{@š%›Œ%c,pÐAÙw*FÙ‰k)öžX°`ëÕ«—[sÍ5‹T²ŠhŒ¤ hŒ­®k2&@¨¦àÁ;!ˆ!ŽgÊŸ}ö™ÅIF!AØŽ¦M›ºõÖ[Ïm¾ùæfˆ%àÆo,ÁT÷U]D@r%ðõ×_»‘#GºqãÆ¹¶mÛºÓO?ÝmµÕV¹ž®ãr$€Â=ö0c6о馛ܲË.ëöÞ{oû.ÇltX xå•W›Ç¯´ÒJ®M›6ÖŽ%P-UAD@D@D ‚¢6¬.KD@?þøÃ¼#ðŒ@A¨&b!£Œ@Áû|à~ÿýwóŒ ”›l²‰Ûb‹-LµÙf›™õŸ¼%B¯Ð5ˆ€ˆ@î~úé'7vìX7a·çž{ºÓN;ÍBÖ䞃ŽÌ—@ûöíí~’âÆotË-·œëСƒ#”RéÀ+ï ”„@ÛqÇK¿Òª¡ˆ€ˆ€ˆ@Y‚¢¬›O•†C€Á3‚‡c62ýüóÏ+!TÓÏ?ÿl–˜xFðjÑ¢…[ýõ+”xIà-²BID@D ñ@¹=eÊwçwÚ¾C't’”Eè  úñÇÝ¥—^êFeøÛn»­öû(ÿÚWê³Ï>kž¨xOüõ¯­m–:_D@D@D@²‚"+ý(" uG€ØÌ<¼#@!BcÚHe^Á3ÅñÁÙ+EV{o¾ù¦ûâ‹/LÑ€²WóæÍݦ›njÊÂ4ñÚpà Í:³îZJ9‹€ˆ€”ÂNŸ>ÝöœX}õÕ]ß¾}]ëÖ­Ëí2ʶ¾K,±„Ûÿý,W^y¥…Ø:ûì³ÝFmäþô§?•íu5ôŠã¹úÜsϹ_|ÑB;MíÕÐ[]×'" " õO@ ŠúoÕ@D ‘ &6¡xà×»wowÀ¸W\Ѽ”(!ðŒàÅ{ï½gʈ°wÄ¢E‹lÓêàÁfÖxC @A¸&B5­¶Új ®GD@D €²¾ð ¶÷öœ`Cl¥âà~Þ³gO3Æ=z´ãuæ™gºµÖZ«¸Qi9øä“O,¼ë4B;±Sº& E]Vþ" "^QÌ<ØM›6Ízê©n§vrÍš5+Û0x† â…+!™Ø´Ï”¼.\hÞÁ3eĺë®k¡7‚2åDË–--Ä@„úZD@D@*àÄ=ö,4hëÒ¥‹ÓD•0íú¨»ì²ËÜ}÷Ýç à:uêä–_~ù¢ZÆC5á!ñË/¿˜õcPF¼þúëîÝwß5ŠàÁ;ž( ⡚¸¾Å_¼¤ÛA•Bˆ+óPè16ÃJ" uC¥ùĉíµûî»»£Ž:Ê­²Ê*uS˜r­ÝvÛÍÂZŽ1 2ÖXc µQHþ$öœxþùçÍè™m·Ý¶ð…”xŽ_|ñ…y—x5ë­zìÇZFID@D@ê‚€uAUyŠ€ˆ@ ,¹ä’æN?jÔ(ó @QAاþýû›‡ÅÉ'Ÿl¿Ï…B&,çâž¿ýö›ûÇ?þáPB„½#Þ~ûm÷ÝwßUxFð²úê«;B5eÖ믿¾yN²~ÊKJ™@š2O¢0v>úè#·ýöÛ»Ë/¿¼”/Cu²%À|öÙgݽ÷Þk òãŽ;Î,ôËö‚hÅY7ì¿ÿþîý÷ß7/Ö(’$ô¬ÿñÅm ±ÞÑË• ÝgÏž]ÿQ¢5˜5k–ëСC‰ÖNÕ(wRP”{ ªþ"  ŽÀÒK/íºuëæÚ´iã&L˜àn¹å7}út7gÎ ùtôÑGÛ&“WÓß7ïì@•Š b£4Ap@¸&ÊCù€"¼Ù «ðš¶‚Î+GiÊ<öX Ê<Æc‰P3ñ0gl ˹ gRŽ­®:—:Ï?ÿÜM:ÕÆÝ 'œ`aK½Îµ~6rÈ!¶ù”)Sûmí²Ë.šë±Cà}„÷a:8àS¨×cuT´ˆ€ˆ€ˆ@#$ E#lt]²ˆ@yÀz ï‰Î;;¼*¾°ñç#<âN<ñD×½{w·âŠ+Vkyøûï¿[&@QFüüóÏîƒ>¨PF Påÿ?þøÃ<‚BbÓM7u( PF°Qâf›mæÇ kyôÕ²0’ʼï¿ÿÞáMD¨³¸2o‰%–0…ã§iÓ¦æY´ùæ››wQØwEc§0m¢\D Nï¿|ÐaÝ‹uþ{ì¡ûTP ~&|ÐAä.½ôR÷ÐCÙUl¤­T?P°ã„‡.Æ1(Ô•D@D@D@D ˜¤ (&m•%" y ”Ól`¡a°j»æškÜ3Ï<ãÎ>ûl7mÚ4wÊ)§¸vÚɱÙv|„ª_}õ•íe)ŸaïˆwÞyÇ”AÁûZk­e{GÄC5áæ¸’4(éÂðaß•?üÐÆNC(óPú±<ãƒñÞ+IeÞšk®)!icé8ºÎz#€W¡xàóðÛo¿ý\óæÍë­>*87(kÙ'äå—_vO=õ”íwpðÁWZÇä–“Žª-îgóæÍsóçÏw;vtmÛ¶­m–:_D@D@D@ò& EÞÈt‚ˆ€ŸBÐöíÛ›7g=Ú/¸wïÞL¿~ýLÁ€p•ÄæÕ½zõr ,plú©„lBxƒ7ž($xbË9¥†GÏBx!P_n¹å$úÿMŒ`%/ÆÍ¯¿þêâʼª £0~‡løBáY„—qÔ¥ÌkxcGWTú¾þúkó.\´h‘4hÛf›mJ¿Òª¡`s}ú¸"04XÃ!”F€ŠB"(#ݴꪫ–3Õ=Gð¸Ap·ãŽ;:6ŽmÕª•í'Ҙ ¡Œ€Es†Râ›o¾©Øwå•W^qo¾ùf…2e/”yŒ—¤2E’ˆ@ý`L?úè£îÉ'Ÿt:u2a7^‡JåCÐ.]º¸1cƘ’‚ÐB(‚•ŠC€g¼'0xA9ÁæØqoÜâÔ¢ôKYmµÕU¿Ä°‰u’’ˆ€ˆ€“€Ť­²D FàÓO?u-[¶Œ}£"Ps(»ˆå¼ P`ðëÖ­-–0ññ•ó¤Ÿ~úÉ7Î=þøã¦¤8ôÐC{œ4iÒ¤ABAp<#xçúß{ï=Û3"ìÅ5|†ñ Ê<!ÔŠ=J" uG€„ŒQ<üÂ=,—ÒP*Þÿý¶Ó¾ûš ´;†{Pð¢xì±ÇÌ!ycR ×g“à5ˆ‚‚ ((X3*U%0qâDסC‡ª?4Ðoõ5{öìzuº,R% ‰U©¶ŒêÕà `¡D¨%¨ ¬Þ~øáÛK!+ýi…V°½(° ÇC‚ÐOJ›?4'MšäFŒa ŠaÆ9„± ›Éâ ÀqåšþûßÿV„jBÐIH¦Ï>û¬BBbáÂ…æ=<#PF°Ç áD‚2O#”ÆRæ•kOP½Ë•À[o½ån¸áóVêÛ·oN—ÁýoêÔ©æùtòÉ'+n~NÔJó Á]»vuW\q…yÄ0³¯–RÝ`í8gÎ{ Å÷F%¨RPÔu•)žÊ ,x•D cùåÛ[âæ›oþì¼ÕÙÿÏç}“|bIÞ* Ô°¡¨+ˆˆ¢"v± Ø¢Ñ$6„DcoDcAÑØÅ[4‚5X£€XPP‚ÁÔ5íŸýÏ÷y3÷;wvwvöÌÞݽ¿çó™»wggÎsÎsÎSÝÔ©S!-°úF°ƒU<Öˆ"!"€òØÞ¿úÕ¯ÜôéÓMQA~ÆË.»ìâîa5‰år½‡GA ‚¯B6aù‰%u˜açG}ÔâwÏÅk¬Ñ*TSê*ÄIŸB@´<×~ø¡…aã³1Ö‰ðN(`‡ ÒÐJÖrímöß™wH˜%?¹èSæ&Q¾›jÖ¬YnÁ‚ö m¶Ùfù2TéB@! „€(€%ÀÑOB@zAY”ZwÞy§»öÚkÉA±1b„…íYuÕUå’]/V‡õX~ùåݰaÃ1¿ ÷Æü&GÅa‡f ×W_}u·ì²ËÖMíQFÀšeVÓxC„ʈٳg»÷ßß+xG`ýIÈ-Xᆹ#Ö_}SRÔMÃT! ZèÖ­›ãxçwÜ¢E‹ZÎû‡°4Ó¦M3ÏA<É[ jl0ÚÙvÛmÝsÏ=gýÌSË-·\c7ªŽkÏš…ë­·ž­ ¾÷½ïÕqU5! „€B Ù‚¢Ù{XíB á@H‹Eøï~÷;wùå—[èââï·ß~îøã·5 ßH5 f¬¼òÊîÄO´¿üå/ݽ÷Þë.»ì2‹åŽ7ÅСC-¦;ÿZR4TÊ8<…È­*#^{í5÷Ö[o™E˜7‚Oø`ó²l°&¨ºB@! „@“! E“u¨š#„@ó €Àö³Ï>s¯¼òŠCLI¬Û·ß~{7vìX7xð`ÅËožî®iKÞ#Ô¿ð ͫ‚üÏ>û¬;ùä“-®;ù)¶Új+ËO‘‡ !cÔ3â믿¶/(!?…RbÞ¼yŽ¡gʼ„Ö^{íe$„WÜìš1^ !2!Ø ¼Šžƒ°y/3Ÿ:¢æ@Púô’K.1%Tß¾}õnÏ©kQ¡ècNÅ[¥k×®9qR±B@! „€H‡€épÒUB@š!€pë¶ùóç»o¼ÑÂñÞ¦gÏžŠçCqrůYw45#û;…D"á,y*PT`<|øpwÔQG™‡¡6"f¥hÞ¼#P<`¹‰2‚ʼn­É—"á# „ 6Ø@c?k'è>!PÇàõ„²¡Tˆ'æFB=ÿüó–v1âÚÿ÷ÿþŸ…«÷Ü:ÅÚÐÏãEñøãÛ<ÄÜ´å–[vDrm3Æx+a@þŒDB@! „€ho¤ hï! „@6ŽX>üðÃnÒ¤Iâ†ØÜl"ÇgÛÈåúWxA`…Vp£F²D¥$_¿õÖ[ݯýk‹óŽ’bÿý÷·äw(Gÿú׿, J5”ýë_-¶|¨Œà“XóQ„ ½£€@±é¦›º^½z™Ug5Š‘ruÕïB@Ôä¿AIQJAñ—¿üŬ¾yÇ`iOh¨$âݲdÉSzb!NÙ¢Æ@ GÖ·W\q…yÊOŵÈsçÎmñBB„W¢H! „€í€íÝâ/„€@ Bè ¬CÙ˜“¸¸S§Nn×]wµ<Äb– VC%O_$›?~|KاG}ÔMœ8ÑòT·b§vjR+åPr¼$°Å#"ÌñÆo˜’"TDð‰ÀÜaÞ”„÷¨uÞ‹<ñTÙB@¤G T$̘1ÃæÃ¤;±ú&±/žŬ¾Q^à}HØ:æSÂÖc_Ôàí‚Åc=fý·Ë.»˜²º1j_ÿµäùà9ÂKœ 蘆eý÷›j(„€B # EGèeµ±n@(].!dÝV^ó†¹&>øà7yòdwçwZx'¸Gq„ÛgŸ}Vëï¿ÿ~*~XBX®“`X$² °ÒJ+¹ÿøÇ–°”ü'4(ÌH¤ýùçŸ[±K—.µœxE À2“1ˆ¢E–¯xgà …áʾóïd©šîB  À›  æ®p‹6å'¹'x÷‹™O(¹9s渋/¾Ø”ü‡z¨Ûyç£Åèÿ@Oº-¶ØÂÝqÇ6¯à]'!ºŸŽ[¸p¡y!áÙˆ’¬EB@! „€¨¤ ¨‡^P:,('ºwïÞaÛ¯†G…ÄgœaGñ«Šÿ‚•©ÆVq|ôKå|ñŦ@CHاO+€<‡~xKm´‘)$BeÂ¥.]ºTÎPw!С@1ÿo|#QAAR_òãðîÙzë­Ûà‚¹)PN 0;v¬=z´)HÛ\¬uŠmæ‘ûï¿ßÍž=Û<ð¤Ð®¾Ë0†áÂà/$<(>«z\U‚B@!à)(üà¨R„@&þû¿ÿÛBªdºY75<l‰©Mˆ6ß$®–BëS¬×WYe•j‹ÓýÂ7aµÌÅ2 VÆ(ãŠd¶1àwÛm7·Æk˜gDïÞ½í†Q$„€¨<(õDš(1¯¡%|ùp%æÐ'Ÿ|Ò]xá…–Ãâ”SNqt—95ÊGÿ×¼îPn.ϼb!½jW£ÆçôñÇ›r]ž#ŒDB@! „€¨$A¨—žP=:$lÆq·uLþüç?»Ûn»Í=ñÄŽPƒ6ëÑjИ9s¦0`€mæ‰å-Y@à·xñb³`%Äÿó¾6l˜;æ˜c,|ØÍ7ßìÖ_}wýõ×ga¡{„€­àÓ­[7S†¢ !5–ßXÕã= ÷óõ×_»‡~ØrN¶æôÓO·Ðˆ(éE‹Þ4(¼ñŠ¡ÿ±ø'?…(Â9! ¼è¢‹ÜðáÃÝÝwßíºwïî~ô£™u2±ª.%>BÀ3„öáé7Þ°÷áäzöìiÊ ¼¼®ºê*óòâÜ„ Lx­ÍpˆZs|"D'Ê(’e3_‰*G€0h¿ÿýï CB¤m¹å–•¢;„€퀞ÝäÃÈŠýŠævè„”,ñ¾?úè£Ý 7ÜÐâ›òV]&ZE úG! „@ÇA€Ä×K–,qÓ§OwW\q…Y)“ –ä²Ç{¬Y®v4ÔR! êЃ‚º ˆ@AÅ{ìa!~þøÇ?º+¯¼Òò7m·Ývîä“OÖ»ª:.§:¬·ÞzÖïï¼óŽ…y’åå@ã‚÷Ä÷¾÷=ËáUV^šîB@Ôru>ú裶ØtÓM]ÿþýÝÿüÏÿÔ®â”ö”äÂ\e•UÜ¿þõ¯Ô÷éB!E@ Š(ú_! „@“#€5©/½ô’)&PP,¿üòÅÄÀÝÿ÷79 jžõˆJRˆPóæÍsßùÎw\=Bj”©÷݃}ºî@IDATwŸ),N8á·Î:ëÔc3T'O¬µÖZ–hÁ‚ŽC ŠÊ€Åܯ¼òŠÍñxPˆ„€‚@8ïc¬0zôhËM$E£ôžê)*G@ ŠÊ1ÓB@! ¬‘q“&I&î·ÄoGxÑ«W/wøá‡»<Ð}÷»ßm¸v©ÂB@4„“ CÊ! lqóQ¬žsÎ9îw¿û½«ÆçºuëÖ< WKÀ% u[l±Eâu:™ŒÀ[o½eÞä™"§Ôºë®›|¡Î ! êo|ãæ1±Â +¸e—]Ö‘‡J$„@ó" Eóö­Z&„€BÀ nëâÅ‹Ý<à&MšdÿJeÏ=÷tÇsŒ €•B ž 96 §“'Ov/¿ü²Å7>âˆ#dI_O•c]F¡ @Qõî»ï:íP¥¥ÞsÏ=çžþyË;±Í6ÛÈ;2tºJ:A¥*Þ’Ÿ~ú©#¡êDB@4/RP4oߪeB@! ,œVÇ—]v™ +‘1tèPwÜqÇ9"! „@="ðþû‚¸Æ+­´’;ñÄÝ¡‡*O¯zì¬ë„M—.]̃âÃ?l –#˦(£K—.µÜ½{÷nŠv©B@Ô'_}õ•yjýõ×®sçÎ6£\®†È™³ß~ûUS„îB ‚¢:KUB@!P „pzê©§,n+!žñ0fÌ·×^{µ„Q©¤<]+„€¨%ÿøÇ?,ÄÓI'äFŒá–Yf™Z²¯:@ {÷pExQ„9Jê ju[ž‰Fiw#Ô3ì6Ä£F²ó|ÐUWsB! ÖTò~^‰qŽð¤Q ëXBxP ÄB¡ƒ M$š ­Œu„»í!d -áË —óÀ¼=x#¿¸ôÒKݽ÷Þkùì-¨ž_~ù¥Yã†qìØ±m ¡~øa÷«_ýÊ¢/‰Ø³Rí>ú¨Ûn»íZõéÏþsË¡÷ÐC™<Þßü>mÚ4wÏ=÷X=~ö³Ÿ¹·ß~Û¬í#ýë_]×®]çwÙe—ªÞ‡ðBp«¬²Š;ÿüów¨|A™ÀžkâĉfXAØ+0ºí¶ÛL™AÝÙ‹!‹<úè£ÝñÇo‚ò$\8‡bæúë¯w×]w):˜ !„÷mœzê©nøðá†yÒXd.À•v7Δ6—_~¹[´hQK9^x¡Ã€íÌ3Ï´¹öñ?×P_êÊZ%mÛd“MJ*)ÀüOú“;÷ÜsÝ#X<Z± < AH¥Â!‡RX°`A«ßøx-A¼ñ ”-d°q ¼+ A?+ç¾ûîKÄ.ôzôèa冋…À›£(ØZxvn¸a!Pr†ñkïÅBÉú!Pδº?üÂ|(e —G!P‚凵#üÏ —T!ÝYŠ…bu¼ô ·À°ÀóxMD‹°ÿ/¹äãŘ B7µùA­B†¬(‹ ë­·^áꫯ. üÄku²~ø¯u*Z! „€B@! „€È,¬±rÅRuë­·6«ÛœYªx!PS^~ùew×]wYÈñ@¤fávˆ+Oè˜Z–ïXÄ‚†ÜwÞy§ÅôofÞ¼O«³Ûn»¹UW]µMS ÷zÂv aÔæ¢„ô¬„îÀ¼ $AÎBxb”›PEñ:b)¿ß~ûYþƒW^yÅÞÕŒúo…Ÿþô§–"j‰Oˆ@<ð&!Ã)§œbVûah¦°mÛn»­Ã ð•x7ĉpX7Ýt“åˆ=z´åšˆ_CΈ#<Ò¼¦NZrRÚ(Â0P™^!»ï¾»yWįÁ»‚\PàL ïUŒ¸7P ˜÷EܳдO’É“'Û3/‡XäìÀS,“¼£Ž:ê(ûçPÔ+‰O…Ç¡Ç<ðÀDO•¤ût®ý‚¢ý°g! „€B@! „€U#@¸âv¦c«­¶²0,Uª„@!€°2*°$oáž’„¼yTzTèŠàu-¨½x#grÙð™D]ºt±DÄä¨Kƒî»ï¾Û‘ĘÐQ„Dª†H|Lè©$"¤ ”„ú!·C5Dè%r1DÇBXáŒè«À;Âòi$…o¢\VÑãDkÂQçRÉœÉ×Aˆ3B7ËñAÙ„ÙÚk¯½Ú$ ç7ô+Šò4ü<‰èc®ãY+¦à¾À³Ä°I ÷Åïp€…v ‰ñôÓO›u+Þ„ä fC*I|QJ°&Ýa‡Z 8ón/a„À?ÿüó.ˆÙoÊÀjÞk•Ô·½x£»$Ù$u&r(G¾ ùÉ'Ÿ4 „ÍA>ˆ’ÍâÝKbm’“Lš0>Èæò&2S7¼'Òxyä]ŸRå#¿ÄSá–[n1ÜC¼“îÁÓ‚ùá>ÏÞõN¡r! *(K(HB?nܸ’ ¼#¸–þ,¦ ÞåÆd½ãÕ‘êçMAríU½l÷@§z­o¼žúÞ<h,6O_ÖcKfΜé P´jlVg̘Qôwý Ò Plœi|¥AO×ÔArM$ÁM¬Ê 'œPô·ÄtÒ+ÅúFýâæÜ ãù¢/ãD?žuÖYñÓ©¿?÷Üs.rm´‘;餓ª×P¬ž©+TGb5Kî <(¶ÜrKÈ„Ÿ:ª¦ª"¼ €Åø¨Q£¼”•¥þýû;Žö öà$bv¼‰÷•ý¡‡ê÷!߸ð ÝÛo¿mïer ”"<0Èã2•r Óƒ§A-EïE,ô‹ ´kQ4<}„²¥ †¥òû!ž‹F!ÂH¡t ½>Âz‡ÊÂdr*î­^~2ÞP˜•º®”r',GŸõƒ€7Eý4I5B@! „€B@fAkåŸýìg& “5dë^Ń"á0:è ³Hn}…¾ ! ²!€ð—¼cn¾ùfËP/„Å‹›ÅþÑGm¹,#r PI‹QpqÄ5À‚b‚œòë}ÁKÜI(½Ç{X²ìb¸6ây0xß „ˆ*ÓñÔÁ›¯šI“&U—¤±éèu–‚¢£µ_! „€B@!PÇ •CÔPè‡à¡ gÓÄ€o]о ! ’xíµ×ÜÏþs×£GK¢LNrp`™NTÂl‘S *hN*‰¼!x[,]ºÔ]rÉ%†®”g@RÕœƒ?J¢«Ô{$@Ô1 õD(ÝbÄPK‹Õ#íy<þí„‚">nÂïxæ Lu<¤ èx}® ! „€B@! „@ƒ#@^B;be̘1®OŸ> Þ"U_zAá7–ì¼gȱÙf›eªù(ç•W^±ð\Ûn»­w/'½“%´ãøƒ…wZk­µê^‰K—[n9÷Ö[o¹/¾ø¢h~4Ú…°eÑŠ+®X2gC¦ŽËp}]*„ ÀÉ5—!¬¢!˜ð¬¡((Pdñ½˜ò/ ú¯”òÅ®ËÐÝÒŽüW;òk! „€B@! „€B $ë%ž;±¸ñž(b%CñºEŒ`„Å$`&”Bcæ¡É'B qÍ£>êî¹çK²}À´ä°(wo%¿ß{ï½–\ ý8þî·¿ý­Õ¹_¿~uÿžÄ+…Ü >ø ›;wnQoú…0P„ö›7ožCaÑÞôØc¹×_=±ÎŒ™_ÿú×6ކÚ&—Ô7¿ùM·ÿþûÛøºõÖ[M1–ÔÆÔu×]çvÞygwß}÷Y¾Ž¤ët®ñ‚¢ñúL5B@! „€B@ŒÂC’cÏ™3Çm½õÖn‹-¶èÀh¨éB@øF+þí¶ÛάÓO>ùdwÜqǹ‹/¾ØÝrË-¦txñÅM)@ø$r< €ŽÓ»ï¾k!PjŒ;Ö­¾úêvׯ$åB¼¼bßï¿ÿ~~¿óÎ;&à¦,ÊÇÒžRÍÉç°ùæ›{÷Þ(V§¬çÉ“±×^{Y=èóŽ'ivH´Ó$ç7r9l¼¼£uÊ)§8Bƒ¡ÌB™Àñå—_º3fXÆÕ¸qã‰ËãDv”3( _ýë_[)^(ÿÕW_u7Ýt“ûì³Ï,ôŠ Qs à5Ä ƒ„ˆ«n;<(íyw´$ jb™ò?×ñóPSoÿ_xyû®^ú3íø¢Þi¯­Õ-5™Ð;âø# ÏÛòË/o®€`Ä$¤ó•ã€UKÂåR8k¼e}îŠ1Æ€F}~ÃvÑæѸˆƒó‰Î§Ç!Ä’„àGÜ\6àÊæª½Ï‡õKúäÝÈ»”zSOêÍ9>i‡Îç‹c$‰è,8Û{ì$eê„Ð%Ûl¶Ã±óé<ý•Dúè#S„¬¿þú&; ï×gƒ# –ŠháÂ…ø µ9‚—R!xP £F²ß‚—RaòäÉVv¥ç l!pSªºœ(ßxƒT!x@¬~p¸p '?oCØßÁ¦¼hË ÁÆÂ[?Gû‡ñòË_þ²é ôÖq¼  S¦LI¬#u6¸ÞÇVt¬§»ñ±(à AÌØ9þxoš{ƒX„…`Ñ`8è|6âc+ú=°~ÎoU?_Á¦ÂʈŽ-þç™mäç׎àÏüùó ÁæÊÚ,œ Á¦¦,† {u!°ºjuž{’®Ïr>ˆ^6l˜•¿öÚkn¿ývŠñV~´ž”Xcj.å‡c#pO/EkG°¡-Â3k_°A-É\«>¿ÓN;žxâ‰BD¯PIùãÇ·z„õŒò®¤\ˆÏØõ:_âýýžµÏéË4c„òÁK!Ø<‚° ©Æì¹çž[`lPOÆJtìtÔóÑ>‹þ„*<ðÀ…@qcøn³Í6†[{Ö-ú?ïˆF À2¸ A¼îB2¥$­m„j×uÃg6:øŸµOG"áБz»t[|aúôé…áÇ\¸þúë AX9›ëÁ¹É‡Ataûí·/ ³ È5µÉs(ÙÎn»íV<R×\sM!P·ªT ¤.tëÖÍžCÖäqÚ{ï½ ÐÞê„û)0·Àº Ûã„*<õÔS¶öß_ÉwêB;!yÑÛiõêÕËÞÏñVâu7Guò!C Ah¦Äk8ÉZ÷|ïÞ½­MAéûÚäo(ì²Ë.… Ä_ù ‰‚ÐZ¶– <_ ï¿ÿ~Ò%…@Ð_Øxã Aè«B`¤“x '‘WÞ/… „S"¿»ï¾»Ð³gOë§ Ï„í›À 9b`\@NäÖ0™ë¬r(4 ýû÷/Þ!Ö^Êe…Î;Ö[o½ÂW\aëµbå°ßàÞbí.vŸÎ·/Þ<(‚f˜çD0‰WE¸aá~ ¤ªÊÑÍ~ÀºÿÚk¯uÁ ßbœú-Ý™åÙ /¼`7$ËÉJxz`O”Whî‰Óš×ØÊ:v±ºÃ=[$„€µEË.<Ø!·%–Ãs"Nœ#®+Ièò"øcQ1'$yD±ÎÂR›ù8©žiëÆüH’B¬°ðÉ‹p9'nn°¹È…á^~ùeG"AQÇ@ ï>§|,CyFˆW]Žxn ±ƒ©¨<Ñ“»ñÆ c¼³ñŠÚë|ù×÷o¼ñ†Y’âýOx'Bbˆ„€>˜6mšY©ëÿÔSO-ê}€e;òŒ“N:É]}õÕf9O‚c¼+°†/æ!¯+Öð$<Ža¥öÛo?ýˆ0"¯9&ùpÀƒ 60É—«¥°.Ô³á5OBY©#‰Á½›8q¢ykó1Â[âÄO´pO„L"´ûÚÒ·o_ ë‡ì«mºé¦îüóÏwx´6*‰ˆsÙe—µxŽ']Ã9<8c*Û?$y¸0]y啞”yÇw¸Ù³g[Ž$¼È“„,Ï ¢e”#Ú5X¨(Ú[Y¹¡•ÃC™a©V±yAkw9þú½}ð¦ ÀM6ШZ™À’Ò\p‡¡1®GiÎóöéÓÇ8®¸Óg)8á‹+WñÄÿ<´Ôs:ß0"®8ñ¢ ¯Óögˆošëy™ï»ï¾V>ÉuÒŒ—hù¼Ü™üHÂÄË0Ê“ÿ·ÜrKh[MAáclEËgŒ–»ÅÆ"\”&L4ÄìHã> Ÿo&º@#ný®ó•ã€;d’P“g$JÂùqÂ!ѱý¿Qñ$¹Ü~ô# eÈœÃ;˜w1ÿób“Ä;Šxµ¬MX`‡çi?íŽ_Ÿå<|X°¿õÖ[®{÷î-†Ñò /C|]è,ȳò¥|\¥QP0f-§(Z8P¢„R6ˆ¼£À• +mª9O{V&ÎJÊ7æ ˜§)‡zA|R_ê­óùãÀš?3Ñî¡_ø­š>O3Ö(Ÿðl® QnL-^¼Ø‘”eõ …1áØ‰ÞSÍ~ž>L Ÿ„RbêÔ©Ñ®µÿÛë|›Š4Ð ”ëÏ>û¬Ã¸ ¡9öi"! „€O˜ã0äÙ}÷Ým\¬lÞ?¼‡¶Ýv[[§rÊ{dHÈ`ª!B5UB¤¯ ;*¹/͵iê‚áL9ãà•†Xó³vç@S E9=kòÀkªl±ìJ{(Ž(—ýGVB.xYÚQi„=5 •:p›@sÇ šÚæ3ØÀUZ\î׫o=Ö5w020„…`Ãe.Z—^zi†jwK´¯ë±£õ‹>?Á¤aaDzè¡Ú%NM‡@±Ð;áXÃ][$ªE Ø8kÔñoO=·#Z×z®'®íÔ/H„X—a1ß¾ãŸguVµˆî¯b}S¯ý­/ÿ‹þú+þl5Ò÷FèKö„U$lÆ9çœc!x5þªG€¹+i¬2ÿv$©·K·õð÷Ð<„s OŠ^(M-|ßþûï_èÑ£Gð<µ¢hˆ§¤Pµª‡ø!P=Þ<(Ðì…–ÐÁÄÞBXx`áʃÕ>©<|Ö·‘ÊÂ",Øh˜æ{³Í6KUõZôG°rhk“Æbø{ÚÏ$¾Ç.uÁr‹=‘B@ÔÖ%X1¢÷{Ü­ ‰…DB@!PP:ã%ØDŽ Ýÿ6pŸ·ùõXo”(äõzä‘G,7y"DB YàYÄZ”„˜"!7AðSNàA±á†ZÂQŒÉDB@<@ðä‘GZräéÓ§›çù—^ýuG´‰0ù2É£I\Lî…<"N”jëN’V/·Ür¥.ÓoB@4Þ,˜’,ìy©á9a˜‡v³< /s©" Š &XÙ$‰L£ ¨E$ñÀ»ã”SN1áMÒX¬ $•–‘æú¯¾úÊ’‚¯H! j‡›+¬¿pOgC†Oª¶„u ×>¾Â;¡ÄÆsbÞȃG¼ÝYx¼óÎ;-‰pñ®-§ @¸b•Gx'ÚåñÅ_XŸÇÛªïÍ…@´ÏóWx ±öä=òõ×_+ÌSs ¡ºl ûB;½ùæ›nÔ¨Qn‹-¶¨ËzªRB@4¬A8à;ê­e]tQ½UIõB #Þ²¯½öÚ6l”¸¡B|y¹ù¦Zðð]çF+¡MšðN´«ý‘ăEû’%KÌj“1—F™Rª’x”º>ëox~`}À!B@Ú!°páBwî¹çš{:JbÂ'vØaUW€PQáÚ!§Nª.“pÄ÷…MÅFÑ7x%³´ƒµk†Pá/3þ}ôèÑ"‡ó¬3Ò®5âå”úåWèÅ_\êrýÖDû<¯qÅ;ƒgpâĉn¿ýösÇoäÔ„zFàÅ_´ü«¯¾ºyO  ! „€B 𪠠yN\(ÌF5¸ýQðkÁ#ʯ#ýOL¿.]º˜Ð¦œdˆK-ú#‰Go°ÎIŸI<’®«ö\çÎ-´“¯ä¬ÕÖG÷ ! : ÄÍOòöðÍ#©³ò@1±Ï>û$©sB@!#(¢™Óþñ˜Å’¢øßÿþ·…°$„ o\ã;ÎmZ¬‹˜ã’êY¦´<Ê•Sêwx›˜D‰4EE©ë³üFÙxL†}ÆÚLDÍ‹}þé§ŸæÚçYÇažØ«pˆ„@žÌž=Û¼'˜¶Þzk×=ð¤ ! „€B Yø/_ !ÎðGQuq('°fÜsÏ=Í]zÊ”)U—©²#€àfذanÖ¬Y¹õ‡Ï>ÿö·¿mñ®ãcÑ'bhfå@‡DÙl¾EB@!P;ðœtÒInèСîðÃw#FŒhÃü£>r—_~¹­KFŽéî¹çž6×T{" B&‘„¼Iõ,W‡4<Ê•QîwxÌ™3ÇÍ;×Â~>ûì³ån©øwÊ?ýôÓ­?ðÚe}"jnjÑçYx°æ$ Ú~ô#7dÈæîµ®] O¹'^zé%óLCA!B@! „@3!à̓ÅñÇ_56$š[Ąƅ«8þ¢öC€°I—^z©{òÉ'MèGøês,[WYe43¦h¾x´*4ö%+”Ô—ü,¿üå/c¥ê«B@ä…!’Î:묒ÅVƒÄϬK˜c¶ÝvÛ’×gù1 uÖYÇwÞynÓM7u=zô¨˜M»$ç/!³Ò†‡ŒUô+å¿þúëÖûÛßÜÒ¥K‹^«šZôy»ì²‹ëÝ»·=“ä- ¼ œ _<Ç¡·þúëçÅJå ! „€B ]𦠠¼ .÷Õ†y"|¡ ˆË «ï0 í‚r3EAqþùç[ ð¦È£?|õ9J²SN9Åm²É&mÆ¢/¥º2+¯¾úÊÝu×]Žd‹RP”BX¿ ! ü"€bÁ$Ö©aRçxø$”ßÌ}¬KȯG(—4g0ä‘G1ËÊhÂv_+:+¬°‚¥Ê×oB@!à<6Ï=÷\G²l”ÄX¦Æ“d#?ôÐCÝ€!]¾ÿýïû­DPZ‹-r7Üpƒñ&4U¼žå*•†G¹2Êý,{ñºd —Gn¼G~øÃºƒ>ز$.×+ÿ;}ÎÞ Ï>Ï2®|ðA30ááÇÛÑøh«õ†ÀŸþô'SP|øá‡6)!{½õê#„€B@ø@À«‚â²Ë.«ZAåÝÆol‡ªŒêÀ+ K—.&´!L}ã›|õ9J² &Xõ4E¾x”j{Vtðœ¨Ô¶T]ô›B@”GÅy¯B"$Q\ðÏ»y‹-¶°#¼Î÷gï½÷^Ë·ÝvÛµ©g¹:¥áQ®Œr¿Ã£gÏž–Àuà 7´Xéåî©ôwσPcxÀBŒw‘ð ðžà ¼_¿~ýä©ãd•'„€B@ÔÞ²“Â;±°"|^ƒÅ¸OªŸõm¤²p¥?óÌ3MA‘6ÿD-ú#‰Gˆ+›Ic1ü=ígßc—º ÐÁòN$„€µE€0„/$®wFÆG EØK¼ç}̬£˜ã(//ÑögáññÇ;æÏ}öÙ'•"|„„‚ׄ— íôIQ!/Ÿå«¬úC Úçy+Zq ´"!àO?ýÔ”äA;v¬ëÓ§o*O! „€u€7ñÿGݦQŸ}öY‹Åלp æ’ßæÂ*NÔ‚GÕkè[ÜàR¥Í1R‹þHâAÜàé1pà@¾VEIøÀò¬½ôÒKnñâÅ%”:u2E+ka£$T&_Ï#^W(/Dƒ‰×ÇsæÌ1c1úS$„€B@fEÀÛJ•Å’…}Ö »ãÛmŸrkÁ>‘PP„Â6;iµè$ßýîwÝ)§œâ6Ùd“ıXiÿ%ñ¨´Œ4×õÕWÃ|¥ Hƒ˜®B@øAkd”Ñ÷ޅᓪ- æ0Ô ‚Aæ“j %öàÁƒ­æ(Ÿ}.-Zä¦L™bL©ë¶ÛnëG¼EYÚð“5C¨ð‰—ÿNLõ+Àæ’&ʃd³„L57Ñ>Ïk\aóæ›oº³Î:ËtÐA^ó‰¾ EÄO<ᮼòJTÓc<[+®¸¢='¬yÎXŸ£ŒøòË/-ü W”o¿ý¶½ã®ºê*«ß‘GiÞ(NEõ‹ýÏ^æ•W^1ås“¨ýÀ R$„€B@ä‹€W.úq {„®^xa®­¨\PÇ…cÉZ‚ ›Q‹þHâeK¥Þa“>“x$]Wí¹Î;›ç„6‹Õ"©û…€•!@£k¯½¶å¦7ÞxË‚‚pL¾×>Ñ9n»í¶³zúæÑÄþÉÒÂÌ LÃZ{ë­·ŽÙæû.»ìâ8ò¤(Ö RPä‰v}”íó¼j„áÅ_´â}寡0 ¯½öšûÕ¯~å~ó›ß˜ÇT(& G.<#XŸcü…†‚Zºt©Ã“‰º½ð VÞ(8ù>nÜ8·Ç{XH¨Ðû ПºAàõ×_wO?ý´) P°}ÿû߯›º©"B@! „€Èo Šh8œj+ŠÕîҔɫ Qû €+8–a›o¾¹Ûxã}“GøìóbÞ>yë,¼X‘:/„€9!€µ?Þr„üÁ9IQLK¬‘Ãu ÷p­OJ˃us\R=ËÕ'-rå”úx2òI\~¼<|S˜˜OÖˆô‡¨y ¯yFóìó¬ãŠ51R>¼¤èABE=öØcîüóÏw„øY}õÕ-´Ûàz÷îmϱžæyàÝÀA~™b÷Üs…7ožûñly Ž;î8ËU!%E1DÛç‰ù’þøè£,ž~¯^½\·nÝ|²PYu†}N,þ<û<˸ÂswÆ!Cì¨6r˰־øâ‹MÑwøá‡»Ã;Ì]W£„ãÄÃ}ÿý÷·òñ¤¸å–[LéÃûo­µÖ’’¯ÚÎóx?Þr((Èíˆro4‘B@! š¯ Šxx§,à±8¿ñÆᢈ©J\b)(² éçr‹`Å5sæLäѾú?ñ²‡êÆŒÓ _ÇêˆØ×>ú¨›5kV«±è‹G)t³ò`ÓMh'…w*…®~B@øG`áÂ…¦„'F{÷ Üñ¾GŽÙŠó!PX—tîÜÙuíÚµÕï>¾¤á±hÑ"óâ€u׳\=Òð(WF¹ßáÁ\Æg¨ð)wO¥¿z’[(AÖ]w]Kô[iº¾± Ï S”gŸgW÷10È%¶Ï>ûd–1ÒEI-Öƒ¼ËH–}È!‡xÏ©“„~#Æ~ì_ðžÀ3ï †ÖŠšûí·Wt½.B@! ü!àUAAX¦jÃ<±#i‡¨ý`£´òÊ+[ Ô¸±cÇz¯”¯>GI†ê@‘‹¾x”j|Vl'Mš”ɶT}ô›B@”Fàü£»öÚk[.zã7Úþ±¨<í´Óìh¹Ðó?ix—<œãH~[©‚" j›wÜÑ-]ºÔâ¦?Ý7N‡ð4¢Žƒ}>~üø\œe\‘3ïÎ;ï´zm°ÁU)(XowêÔ)×6Æ G‰Xkžñ:èûÿ!ðÅ_˜÷Ä›o¾éŽ8â ñô¿ê?! „€B@47Þ,¬Њš ¼&Î<óL³*íÓ§OC4ËÍF‹„éØwß}[UR!ÐLàù†åô?þñ³"Î6©–x°ÖbŽ«çz¢K`¬É1l fFà›ßü¦y|WÞ)Ž¡çþõ¯9>ó 9¸—ƒy¹áýøÙgŸÙ%¬90Œ`>ôIQ!/Ÿå«¬úC Úçy+ZM ”q$´öE„+}þùç[öO¾Ê Ëa/FȺÕW_=<¥ÏvF€ðe¿ÿýïÝk¯½fã‰÷¼H! „€ oš6”Ñ:!ˆ('@ݺu³Å×j«­fß}ý©_um´rHJè.ˆ$ÔI}oS-ú#‰UW]Õí±Çn̘1ñjUü=‰‡ï±K¥PNsÌ1f)E¨'‘B@ÔÞé&LðÎ AÊrAà}÷Ýgv"ã’ØžwÞy–<·gÏžnæÌ™ÞyÄ«–¥(QX’*4ˆ—ýÎcüøñvŠäÀüÏý>)ÊÃg¹*«~ˆöy^ãŠÖ÷èÑà 6ÌBšùBcþüùÆìw¿û¯"[•C®ž3)(ZÁÒ®_PL<óÌ3ƒ?Bãå‘ó¯](æB@! „€(ƒ€7îüi-ìËÔI?×X²‰âyìdýAròÉ'›ð¦‘ÆâW_}e1ŒÁW Š:PªŠMžr(â §‚‡B=‡O"ÔàÁƒ­O˜7ê•Þyç7uêT«¶PQS¯õU½„@5à!Åûã믿¶POÕ”¥{;&Œc¿üòËö¾Ì#wOÇDV­B@!  o 6ø×]w] {Bà9aÝ^mˆƒ$pkÁ#‰oG:‡Ð&m^‡ZôG”dŸ|ò‰›6mš›5kV›±Xi%ñ¨´Œ4ׇ¡VXa…4—ë! „€ð„ÀÂ… ÝùçŸï-ZdJx¼FŽYué-õŠæ“j ¯¾)S¦X1(´ñ¢ðÍ#^Ç,í ­¬B…O¼ÌøwÂï„íÈ#¼ü¢Úí×"qB@! „@6¼)(Xì&m*Ydå·?ÚÜZðˆòëHÿcuvæ™gš°¡OŸ>©š^‹þ(Å£oR *Å£Ô}•þ†b"ÎTz¯®B@ìðžÇÒúÿø‡YüûR3å±öa­EÙÔ3/Q4³ðøøã­æµÿÉÃ-3þ?a 8ò¤(¼yåÙ•hŸ§¿«ò+Q ,³Ì2^Ã;ñî¨Ôãßÿþ·½Çð"ÌÚ#<âî½÷^÷úë¯[*Zzf`€£ç ò¾ÎãŽ?ýéOæ…Ã{“ÐNm´QlT¦B@! êo ºX+UK„éÁ™ƒ8‹~„¢öAì±â ‹E4J(ßýá³Ï¦ 4hP+À|òhUpäKVl*I”†zŠ©…€B GºwïnžŸxNtéÒÅm¾ùæm¸ñŽ&¯1æyO£Xn¹åÚ\W͉4<.bYÝ·oß–\•ðLã’ò’®…Ç?ÿùOˆâYËZÎ7V”O„J%Ö%Ìý¢æE€>ÿôÓOsíó,ã O¼Œ† âvÛm·véêMNš>úÈÝwÝu—{úé§Ï_H(Qx×[o=·÷Þ{»áÇ+ sN;~²o 1ö³Ï>ë0ëׯ_‹÷K;VK¬…€B@!Ð.xSP`iElf'Ožìn¿ývSN 6Ì{ì±YŠÒ= N3ñ¹ÿð‡?¸÷ßßyä‘ÞûÃWŸ#8Â*l=öpcÆŒiÕz_?ýôÓ-‰p^}že\í¼óÎnà 74á2ëÏZ ºÏ?ÿÜÍ;×B8=ðÀîÝwßu( C"ÜFE½{÷vûï¿¿:t¨[e•UŸõÙÎ,]ºÔræ-X°À”\i=ÕÛ¹ÚMÏ~É’%f˜‡òùž–(ÅQú’«#ŸoúÎW…€B ]ø/_ܱaò®–˜ø±\ÃxœlrE퇋1„ ?ü°õKýá«ÏI&xòÉ'›ð&>}ñ(ÕYy`ùvçwº|°TñúM! <#À{ËlÂkðÉû8Nx2…u Bqòù¦4<È5xð`×µk×Äz–«SåÊ(÷;<ˆuOnbª#0õMN¶†þ˜={¶CÈ'jnjÑçYx¬¿þú–EVy{-ž1¨>ú¨;v¬Ã‹¼*(QN„aàx_ì¸ãŽîŠ+®pwß}·I9‘w¥/Ÿ¾|þùç̓ÏrO¤MŠžž‹®Ì‚FxWžxâ‰nÑ¢EVÄwÜa}ÄùSO=µetåáM7Ýdï†4×à ©œRço½õVó¸¡|ö¾YêYªüh}ÀÙ cV$„€B O¼yP°°Ç°Z/ Ö„O q0îȾCä f3—{8®ìyô‡¯>gáôÉ'Ÿ¸iÓ¦™ERt,úâQª³òC;­°Â ¥Š×oB@!à6Ýx ²¹_sÍ5-IéÈX’lÞÑÌ}¬KHMèIß”†Bÿ)S¦kê¯g¹:¥áQ®Œr¿Ãam˜°—OßD¨+ŠÒX·ÂOÔÜÐçáÞ ¯>Ï2®ðªš:uªOΈJóF¤í5Ö·ûÛßlK8 o¼Ñ=ùä“B-,ƒ5(ëtÖ’ä2Àsiûí·÷–mŽ+@IDAT5ä§Ïê@þÜsÏ™²•Pº$YÕ¯¼òŠ. ¨„‰‚ž|0yû]!F¼ò" Þxã 3ŽÈcý“W½U®B@4ÞXÚ_zé¥U+(˜øH¬¸é¦›Z2·µÖZ«ñPm¢³áYqÅ]=,qÛ^{íå½u¾úœ18~üx«›¨‚ÂRÏÊ! nl¾EB@!P;ú_sÍ5- ,Äÿ¼£=ôP7 Èo„ðûßÿ~Ëõ¾þIÃeJ8Çm·ÝvmêY®.ix”+£Üïð &?9«X7l¼ñÆån©øwÊýáha¶VcÅ.jnèsöróêó,ãŠðJXCŒCß <"ðÌÀ+iÆŒ¦ Äê/ŠP ò^Zi¥•ܶÛnë;ì0SP°&Õ/x㑯¼'j"¬~‘iÿš o ß qŽì‹™çûTì<÷²E†gf¹ë‹•Sê#x;ô]! :&Þ¸Û=º Џ%þ •Xûø¤ZððYßF* Á –£yâ‚ÿ¤¶Ô¢?’xP7,* ”TµŠÎ%ñð=v©QeS¶Â©<|Ö·‘ÊB¹Dè.(ì¿rõ¯E$ñ`s†%Ù{ìáÆŒS®šeOâá{ìR ”$:ÄzPO"! „€¨ „F˜8q¢wf ƒpL“&M²r±À5j”åM¨†B¬_üâ³gÏž–¸Û7xý²´% s%I|C£x¹Ñï„®yä‘GìTÿþýÍÀÀ§5:Gy\[ÔüDû<¯qÕ­[7¯ûï¿¿) |¡úÖ[o¹ßüæ7–Ÿ€2QØ¡¸cN\’ø8Дª¾xªœÚ ð¯ýËñ"GA¿~ýLAá[![›–4/—¨²eà” ÷Ó;ï¼c &·KïÞ½½‡9ªg`îÞ©yǽZ&„€¨¼)(°6gB[ØGÜ,äñ²'9_Ô‚‡¯º6Z9éCÕx^‡bm©E$ñ`ãvÒI'¹M6Ù$q,«o±óI<|]xãÆO cð•‚¢Xoè¼BÀ?XEò®GhÄÆ;kø¤xÍÍ*÷·ÜrK(âiZ :´Òÿøæ¯_–v È Óf¼Kº°¬%Iìë[AåQª.ú­yˆöy^ãê½÷Þs(ñØÿ+Â÷¸ {ƒõ-ù%=ƒÅ}Èçã?¶KhGZÂr¹å–S8¨´€y¼ŽñBî rÚiƒ 6ðXºŠòÀÍ7ßìÞ}÷]+ê裶ù,ô  ÏÈ7ã[PÏœY¯<?üð–ÈxŠ„€B@ä…€7üÉ“'[¨„heðNœCy‘‡•H-xDÛÔÿGhW>áý‘ăÍÙÒ¥K-^/I ÛQ %ñ¨¦¼b÷†¡Þ©B:/„€È„E\p%ÃDIŒ2! kX GÂ:…s&!!˜Oª%”7Þx£C]×Ygï<âuÌÒîaÍ*|âeÆ¿‡!k8Ï}>°*Ńøï¢æF ã Q„œyæ™öÞð$;ì¡®]»š÷Ä´iÓ܃>hã¥*ãøŸÿügË÷´JŠ 7ÜÐ9ÒÂÅ…<ô™?„ê"´Ó¬Y³,§y„ Ê¿%ÍÍáöÛooQ`€B0œÏ™×ò˜£ê™Ç°aÚ»ÃÕ:! „€¨¼)(°´¿ä’KÚ…Éa&q‹ßT ¾ëÜ(å±Ãj¡ Vi¨ý‘ă1HBoáMµ Š$iÚ_é5;w6Ï „X"! „€¨ý‰óÒ믿îEAA¸ÁpíÃ|Z<‡|²|¢L ç8’Dcâ›G¼^YÚA‚lÖ AÓ$íÓ§OK;Ø!XöMQ$§EH(jn¢}ž×¸Á ØAþš¼¼—8|Š Â¡Šj‹¹EPh}ðÁî€0ïÚÖ@ÜÒ €2™„Â}èС6ŸñP‹œóMõÌ1¢Øøöñ¥ÊB@ÆEÀ›‚Avh]…«ð /¼0zÊûÿµàá½Ò R !Î8ã s)g³—†jÑI<>ÿüs«^%Þ¥Ú“Ä£ÔõYC1OÈ–µ,Ý'„€é@Ѐ2›n_Šb¼òXû°ÖbŽ£žyñˆ¢—…ag¨ç¾ûî[6¼¼vÙe;¢|}ÿåqöÙgKAáà:,/ÚçyV x>”yÖSe·/x·„ÊÑ6ÚÈòOäa´×¾­lîtÃÂÀà?øAî ó‘;±\%³òÀbþüùV<ÆJ’]iý.„€Y𦠠Î01 }îÊÄ…fƒKø¹¿ú@5[nwAà¡Àb:þðÕçnXT4¨Mƒ}ñhSpäD¸|“(; õ)Nÿ ! „@Žtâ)³áž7ož[e•U\’"Áփấ†o Â4<à¹úê«›w®»îZ1*ixT\hìx„k7òdüío³ä¾±ËªúÊœIðɼIäaÑZU%u³Wèk”ˆyöy–qEâj’V2¤%?Œ†³–]i¥•Üj«­æ£¸6eà Qí 2 Š·ß~Ûyä‘Q}"@újˆµsóa(Ç`^ôIµäq÷Ýw»§žzʪ—˜>{Re ! „@o ,íO<ñÄhÙ™þGÀ;wî\÷æ›ošë=’‹ÚÔ„îB9ÁBë°ÃóÞ¾úœE á(öÜsO·ñÅ£T/dårbìØ±¶U’ìRë7! „€_Nœ8±d¡$¿3gŽ…qA Ù£GK’Yò¦ LÃÐçwž D{öìY!gI|kÑŽPYpÇwX\q]KÝÀœI;—ÂÚ³W¯^®[·n¥nÑo Ž}Nbá<û<˸Úyç-ô ŠMÖŸ¾ˆ}ëÁ¿ÿýハlUaÔÂ6­~ЗÜxá…Ìs‹÷ø6Ûlãï*ªOi„":D8§¥­íûï¿o² ¡ó^@‰‰ÁŸOª%Þxˆa èÛ8Ã'&*K! o „×LèIaž* ‹;’@^zé¥Vñ•¥ ¨A¿×¢˜ Dß²8ñݾúœÍÖI'dõ‹E_)Ê…EW]u•›2eŠyYàq±þúëG/©úÿ4<°z&a'ļQi8ª4<ªm<{ì17cÆ +j­µÖr¾ÄâŸ0a‚ñ`=B^)(ªí¹ú¾¿}ž…ïÖnJF_ažBŠúîÕ.-Œ òÞÌž=ÛBß‘£GT¿Ü|óÍîÝwßµ }ôÑ–w¢’ÚΜ9ÓöÎ ƒ¼Qxô#ÓÈbTPŠg­yà%†b ¯S‘B@¼ð¦ `ƒOŒÂjÓP,ápð¿¨>Ã6äQ}Ž’léÒ¥núôéîùçŸo3}ð(×ö,<¸‡|"! „€¨.¸à·hÑ"4"8"¬aœ° dMÂ'ïì<¨zcÀ!Mªg¹z•ãQîþ4¿³Và€‡o Ëûƒï¢æF€>×WŒ©<ú<˸z衇ÜÔ©S |BŸä•$»¹{·ù[÷ꫯZx'Öùy Õ'ª_n¿ýv‡Â(¯—JˆwUt®­äÞ´×ÖšG¿~ýÜG!ÏŸ´¤ë„€B ÞXÚ ¨Z:o„X"…–I™Z§›ªF€  jrŒtéÒ%—þðÕçŒA,)!ÆMt,úâQ Ь<:uêdžJ–W ]ý&„€ðBÿ«¯¾º¥`¬¨ã‚¬™ñ`]BXŽ®]»¶\ïëŸ4Ï2®I†2cL¶‡‚ãŽ0?G^ ÔÆ=í[s¿þþ÷¿w/¿ü²Ûa‡ÜV[mÕ¾÷²1 ÆÞ®RZqÅ-¬y­ðœðåY­G-y€›D'ŒDB@! ò@ÀÛ ƒ »ÚðN42Ž;î8;òh°Ê¬  „RØzë­“‡VVZòÕ¾ûI|,úæ‘Ô’¬:'„€¥@ø€`’¼lº“Â&!d8í´Óì(]Zö_Óò`­Å—TÏrÜÓò(WN©ßá±ñÆ›7ãøñãÝ€J]žé7ây+b&èö&úœñ”'eW„>E™‡2Þ^(æ„à›Ðt|ÿôÓOí“wkQrå„õ’Ò"Ždí¾¿õÖ[–?…¾c/E#Q}#pÐA9Œ ,†’„5ôÚ0ŽX-y\~ùånþüù.2ùŒ’dÇ{Cß…€BÀÞXØ~øá¾ê¥rê6;¡•f<¯CT±U5ܰ¨$æg£Vo$ c©0OÒkª§Í€@÷ ž2ÞvóæÍ³ü$»­WBBh<9vÝu×z­¦åªBhK‚_æe‘hFP Ø >{žÉP1A’ð§Ÿ~Ú=þøã&0ÄlÉ’%¦°ñ%6Þ&Ô‹õð~ðóÃ&‹5xX®>+G€GÏ=÷œ#Avß¾}ar¤,ªÇZß!£±ÖˆßsÏ=-!¯öÞ{o'Ek|ôM! ü!àMA¥ý‰'žØ¦f,ÎX@C,Œ±®óíX mÖAN[ä²Ë.³ÖâÖ ›T ‚ZôGý«®ºªÛsÏ=ݘ1cŠU/õù$¾Ç.•!oƸqã MÝ=ºP!P5«­¶š›8qbÕåÄ @0àB`H‚ëj…ƒ„K:÷ÜsÍ›‘°yððÑ„£¬ }ôQ³â-Qãe‡ß?ÿüsGˆF£îõ-Ä‹òy…üõÙœDû<¯qµÅ[XøSB÷0îó ð9'ùüõ×_ï^|ñEóø*Æ o0¬9îºë.³Gàºÿþû»õÖ[O ÃbÀåpžý/ɱY磜èÝ»w\T¤o0Ècá‘ôñÇÛ|Ë÷•VZɼ¥ðfôI¬xÖ¡zãÌËPû`+X„€B@xËôˆuzœXœa¡ÈAÜÍpÿ®šïµàQMýùÞ0¯q¯É1’†jÑIÚ„Ý( *¡÷Þ{Ï]pÁf`„çeŠòGïh¼'x‡n¶ÙfÞIÞdùãîƒÃ-·ÜâÎ9ç;x~Pð…ó9{µP‘àƒWXF=ó5j”…{æ= "!ÐH0g©‚µ%ïåŽD¬K>ù䇬©£µ½#õs³µÕ›=–=ä5,ª± ¨gBI†€‰ f2ÃÐN ïTÏ£KuB @øpþùç›§'±¦ ŸtÈ!‡ÔeSQšßtÓMV7êš%6v-†§k,-%«ââÑž €>óÌ3ÝÈ‘#áO|ù%Pðýüç?·Ñry¶ðÌⓃu$Ý ¸Å+Šþ‡8¢ƒï<Ÿ;ï¼³w/¥hýôÿÿzG£ X¸p¡Ûc=rËã'¬ý#pÛm·µ„4Ê3t›ÿšçSâ^{í•OÁ*UÔ—_~Ù]}õÕ–°žyšh.…‰Ýzë­/OÖ'’5u”žoìvzSP ¾øâ‹Û…YwëÖÍP"üNµ!’à®$¾á¬6Ú H™ì²ý‘ă1È&BpS­‚"‰G}Þ©S' íD|`‘B@ÔE‹ÙÆ%ä8wî\/ „‡áÚÇGx'ꇠ+œã›D¸'ßX­­¾úêæ0hÐ STøæo|–v °åÀZ‹ƒ2JëǼ­‹£<òæUª­ú­vDû 7}ú+s”6N”S‚øä¯²j}Žp$Ï>Ï2®vÚi'óFà™ìÚµ«7`ïôæ›oZyìƒ8àwðÁgzï°f?ì°Ã¡ÍH– ŽK–,±Ã[…UP (eñžCÁDî Â݉ æ¼ æ Ö*!Ö È1(ƒ¹‰g°Ò2Êñ«%æuÖ=4ZxŸr8êw! „€¨/¼)(Φµ°/úäÉ“Ýí·ßnʉaƹc=¶Ô-ú-G¢y8 œñݾúœx¡(É6Þxã6cÑRPgåÁ}Œw,y¯¸âŠR,ô›B@xDŠxbë²ù&tC<ÌÓG}ä®»î:÷ÐCY¨&Bò!,ôIixg~÷Ýw7¶ÄŽ×³\}Òð(WF¹ßáA8™ûï¿ß.E¸ã[A1gÎ묔×]w]G(BÞˆšúœp£yöy–qE~îÝ»ð }…y"f6žµŠI„ܱd%ª¬±|~á…L9ñá‡f-N÷•@€qôÌ3Ϙ2©_¿~N¹>J€U§?ÎæÝwßµÚÒ†g°úÝï~g²Œ?ýéO"/Möx>©–<>øà3þã¾ï|¶Ee ! „€ð¦ `ƒOŒÂj#,Àë6¶Ä?ÕpÞ{ï=ï•ñÕç(ÉP¨<þøãîÅ_l5}ñ(Õø¬<ÂÐN+¬°B©âõ›B@xF€9íüóÏ·¤²ã=JXľóÎ;¶.Á;`Ûm·þìåÿ4Þ’dc¸ÂáÌQ-‘$“÷ ‰÷{”„Ø"€¨±¸í¶ÛZBº­RÏ4È30îcžòMµæÖá‡n¹p|·EåÕ'È5ðžÁ»Oä,¼ãøñnc—ôŽãzÖƒ\Ë}È:ð¾!,bÒõQ¸—#,Ÿß(ƒçˆOÊ ¼j‰öá•zfRn%kVî£}Q§J=Œ¢eÐîÇP ƒ©´VÔ¼Á¯­Jîò û l¨GL¨÷pmØ7ô†Æåú=Zýß±ð¦ @0L|Ój ^¬I‡Åï0 »»+o=ýÁâŠO\Tóè_}õö`‹¾x”B0+®á9‘¶¥ê«ß„€E‹¹«¯¾º†¹sç¶ü³Øæý̺„÷µ/+é¦Á?ix ì8óÌ3í6¼*UP¤á­S–ÿáÁƈuÑnݺe)¦ä=là9I°>a%jnèópoWŸgWXËã ­·ÞzÞgÑ‹¾y$¡š•!!CDB@!P[Xü#@`qÎÿI hæ‡z¨0`€Ynå‘ 2-ÖZÌqIõ,‡\ZåÊ)õ;á ³Å…œ¨¹ ÏÙäÙçYǂ־ˆpnL- „' °È¯†Þÿ}Pkäø:¹š²u¯3‹_c#ÀëÛ·¯õW9!•p«O<ðÀ–°+%”S?ÿùÏÍ Šç˜Ã7Õ’%äÅÁõ„N¨‹$Ù@˜–šúÆ<,kñÐ+ ” ;¼Þçg-yßxãæ!ˆÂƒ6c$¾×¶Øb wÑEµZƒ¡Ì¸òÊ+÷¢À+ëzx!ò Ãb‘#PœtÒIn—]v±µÌãÇ7A>‚nBzfUP°Ö'TäyçgÊ Æí"L=r®Ÿþô§nÿý÷·µeR¿¡ÜÇCîg?û™)àAû(cûí·w?þñMŽÉZ=‰¨Šlê@YŒ!Öô|òkõ§^#GŽt»í¶[¦}KX¾>;Þaåjáã¡ Æ!‡¨ý@psÄGXExq污ñÙ缜±, E|ò(Ö+Yy°ØÀZ€I¥Ød]Œ§Î ! „@v>°YÂò‡ÉnãÄÆG^”†,ÏC5hÐ Š«’†GÅ…Æn€É‚9°àª&n~¬è–¯lL}çµh)\ÿÔ%µèó,<¼`íH_„@%„"{²®2`©‰BÃ!ò‡Ö§((ø<è ƒ´õmÍKB@Y uòÒpäIµä ëuhøðáíª @€‹E>–ùø±†CVQ+EVï(Ž©C¸Ö)&´õÝÿµæ¢n@`˜ƒÒáÜsÏ5…Û‰'žh^ ´9$ê%‹bâĉŽ.³<òH·óÎ;›'–þÓ¦M3¡<×Ðoó‘”"¾—]v™Íp€Ûk¯½2+'Ä?ùä“îŽ;î0Aûi§æ6ÙdSœÜyçîž{îqçœsŽÕ÷?øAÅŠ r¿ 8`Neï€àg¼) ÃÊyž™m¶Ù&±}ÌÙ0·#üGÁµÜ Œ™4i’»ë®»ÌS…Éj«­Ö""¿þõ¯­_P²„Xó,Æñ·¿ý­õ^<3Å(l²>ÖïgŸ}¶Ûa‡Œ'!p§L™ân¾ùf‡Š'òn•S ò®@ÙLŽré3žU‘H‹€7[œøh]¡PÀ]n`ÇË(÷½<ÊÕ¡Y§ï.¿ürknѰIÅÚ\‹þ(ƃñž{îéÆŒS¬z©Ï㑺€”?›ÄãrB¬Sު˄€B  ø³YòM¡5冞Õ®}p›fó´ùæ››ëu<â8dá‹7kÂéÓ§›å\9e›Æ0Ü ášúú6Dy„¼âmÕ÷æB Úçy+„'.$ ²"вÁï Æ+”£F2¡P1‹Ê8?î¾ûn³hEкCäö 80°c< ì5&X&3÷Aæ!\ ¿Ó¯å„ªYZåYo<À€9ª•0¾†/½ô’YÓ#h潎õ8 Á°~Åîóqžw1Âòk¯½Ö,ÖÞ_z饿È÷š%^ßöàðž¥+¡Pi#mN2䡾O=õ” ð/¬UYû…ãC¢E ó@ÙñÀ¸ 7ܰ•‚#Þfò0!gî»ð ÍH¨šgÏ õXô#Ðà‹‡"u£^xpº*®Äǘ”ú°¶À›C!Ö«†ÚDaOwÅu×]×îÈ.øÏ¼n¸áóŠ$Lë©§žÚ ƒ^½zÙždþüù¦HA)“´¶À«’uuk‡Ô» ¯ï“O>Ù<`P¦£°MÜ;yòdÃ8ì3”äèCG›®ºê*û,e(â†þ¥oùÄ“£Ú½O±ºë|ó"àMAÁâŒÉ5naÏC‹„€×@ß“H-x4ï(Ý2° c^£íN£ ¨E$ñ`|¡Ùgs4K·´í¯I<|]¸2ã> ¾RP´íB@ä…BñòØø°áõ!XZ„eÁ âÝŽ`1ÜÓ­·Þê^}õU7zôhSB‡Ê‰èu(aüq›»ù…ET©Â\A¸tÆ,õ@ø'¼9QTþ åsy<\!´ðˆd=Àš9¾¿@&FX&¼4ðú(Fa›ðx`]Ôg¼QÜð¬ÑvÊ×ñr|ðAS(]pÁ-ùCâ×è»(‡€7ü믿¾›ó,ª!¬ؾ'‘Zð(d³ÿ΋1®|*ÖæZôGÜÚxñ31ðRO£L)ÖÎ'ñð=váÃKmt)4׉„€BÀ/¸0c™…û2B?6A•&ŸNªØpíC™lT∤ûJ£LÜÇ!êÊá›Gœ–v°‰dÍÀF'¾©Š—Ïwa;0vaãæKÐò‹òÏé³¹ˆöyžã AKÞ{ï½·Ph Œ$ôÜ5×\c‚8XmòÀs¥ ï—[°nÅCÅ%ë`<$ ‰gëJBJ䱞 ùt´O 4]wÝuÍ7.üêhx4z{1 Cº …{ø}«­¶²¸ðI‚¼jÚ]Ï<|½×ªÁ'¼#’¨p¡3ŠŠZ}íwÞ§¼kfç­ hOÞi±e^!Äv´¸…9Ê >‘%1¿1Ÿ•ë7„S"QsµÊ êA¸)æÕbïgŒ/êE]£Dý QÅùvÚ©h˜)”ÌÍxøàQ‚Ç3‘!¡p9묳 (N¬Q(;<˜Ÿ©KˆSt-Í5¬o0TBqõ ùðÉú`È!nîܹÑÓ-ÿGÛT*Gëqúï%’^3Ï“ ²§B9'uÞ^E- Ñ?M‡€7Öæ,œãBag8ˆùÌc°Ö‚GÓõ|Ê-/>´Ê¸õ¥¡ZôGÆ`¥Þ¥Ú“Ä£ÔõYc¢Äs"ïÅMÖúé>! „@³"€unË!±÷¡ `3®}ðÈ`>©–ðfç8¼p¹öÍ#^Ç,í`NC)Cr?>Ë›°°lÂ|`çåA<ÞR1yã÷ê{c"íó¼ÆÈ` ʱÙf›ySPP.!K Û@¨<) }òÉ'ægD%ijL\p¡T›p»¾Í~-B"¼'æÌ™cÖ¬ì—DóVÂÏ ºpŽBPœÇUÏ<°tÇ3 ‡¨ÞNÖðWbì¿ùæ›&ÀEàÌ»²D¾!Þó(%°jÇú=Ì7ÿöä]IÛþ?{÷¬OQæ‹j«¼uK«ö–u×µ P@$ $¨dDr,I$ È ŠÅ•$AÉA$ ‚(ø#HPDA’ø[XA ·VÐU¯þŸþï‡9óæž÷¤ç©šsÞ÷™~º¿Ý3ÝýDBws¥ƒ°ßœE‘$„ì|g°C(ß„!ô>e€šƒÈYº]ÏzUiPå)”ú—9´§ñ¡¨èä‰á>ïø˜?`䣌€ yO c –uœðJ‰w†úT=4êuêö¾ª¶‰Qn·6ëʲ)ßu^¾3Ö°î·þ †E ›‚ƒVNÞÕÊx©p B&û6„°ãàQmÓ\úLƒ+‰Í -p?4ŽþhâÁ{Ùˆ6Å~ê^½¦‰Gõ|®Ïž‰Q²åªK”À\BÀ†Ä»žÀÚçáàgÓP®}X1åò°Ö2Ç©g[<ªý? VÜêÉk¤ÃñŒK¬¬5ÚØØTy&²všÝTû¼­qAÂÏw®g¼Ú+¼öÙgŸ$¨0n 4êŠêõMŸ \¼/X=JÞé¹ì&Ðh*#~ëŒÀ}÷Ý—Þ'„Rú«)^xç»ãÌtD@Ø”÷½ï}©jæoBp1Õ‘\PÖ ¹i:óV‰¢É™HÑ9U$œ÷¯%}âÝ^*“Ú®“÷æ±Ç›”„Ç’ ïÔMè«NSÉ»ß6˜›ºåy T·Î2nà­ Kay© èU.¹Ót‰.Á›ØüË#‘\¬Û^Áu¥ðß8©“ý†rx#Ì›7¯0‡”Êï8QXt Uzíðø°–ªmÚwß}»® „#§˜f²›‚Â{³)ôÕ°uŒûæ&Ù4¡b©ÕÉ‹Eø„6i<Ú¬ÿt.›à¦ìW/Ê~ÿãè&^Ô\븢JMOg—_~ùDˆ«-¶ØbJÀ·ÏwL Ë)64•¼ûi¯¹IñóÏ??)ÒÍ’Q ÷#ÌÑë_ÿú´6$WjÜ×y˜ÇÓÈiÔ™Q©vu#kgóvÝ0›p_èEм€ËRû '‡اŸ~z# æ2¹Q”¥Õ6áÝË8ˆ‘åd·ë¦SŸ5‚?β)(XÚüãÏÒhøjåÛF7hj  ÿêW¿š˜³PøèG?ÚUÃ:l-sô¹M—ìæ›o^4-ôrðèÕ¾axp$ —0’d÷B8Î@ »cŽ9¦k¬Âl*ÊuIiáÔõ¦OöÃå¦d¬Ê¸¾Jýð´Ìúõx° ¦lgAǪ<· R_øoÞ×£lÒêmˆïÓ}Íê°Í>f\‰EM°À[£)Ùe.$Y Ÿxâ‰I0vå•W&«K±žYjª·wSù,PdR ZKVºÍ6Û¤pkÓEГ “éPÅ6e'ìyOàÍ|äy¦Ð0B@÷š£Ì‡Æ9Fîçoœ<¼OJ/ï— @ Ž€ñ~ê©§ç,Hö.ÌͶua6ï c¨EÇT~/sB,² Iü¾ð…¡Öàê/±µóçÏ/8à€b·ÝvK zÛ(6:½3„Q…+,G WZmÓÉ'Ÿœ’—×ëß©@ Û,cî×¾[C xÅ€¦Uô£\vÙe»ÝçZD€–ö3ŸùLâ`³Ãu+wäês‹§<°x×»Þ5i,æâÑ êayp›“¦=ÝŽs@ äEÀ&Ÿ"ÞæŠÁ¢¿îºM(¾¸8ó,¦[l±$ðËY“~xÈ% ·¶^Ï^õé‡G¯2zÇãî»ï..»ì²t)áNn«/ýÁÕÜk©¥–*Þô¦7õªZœŸÁèóþð‡­öù0ãŠr‚Àûm„yJ…/øcOd}ëðÞb­JÈAH!µó,/)]ýôýPò‰ÿý! ('ÄÃs[¨Âè ™ÀE]T<ñÄ©!,À BO>ùd’eØßÙ;³$ïeq=Hù®'VÓÞ;,ÇË÷Ý õëg7ž~æx ÛÙô>d€Ð+¯D?=|á…¦°W ~wß}÷Ž ®»•å9T!š¼c†¥j›È°‚é‚@6… ¾…,ÁG!›îsÏ=·8餓’Õ‚¸Ä¹â£Ôo.ßkÄå,wäêsJ2ãðæ›o.~ò“Ÿ¼b,æâÑ­ÿ‡åagmạç@ È+d¡˜lö)‰Y| …R%9$ÒfFð'Ž»Ð9©6#\瑺ÖëÙ«>ýðèUF¯óx<ôÐCé2^ mlP•ÔQG%+rë›áPPôê™™}~}> áOЖ[n™5Iv·ól.´éµÑœ+Чžz*…w^–0Ž¢4hv @AqË-·¤Æ|ðƒXAá^¡)…c$ÓÆë±šãæ!$Í.»ìVÖÝ:e–Ÿ#géD„åBRÊuZû‘Ó†Sðv+¯Ÿ©ú]” !¶ä>±ÎUÿNž»Œ{m ÏH§ŠÅ/ùËd`ôÞ÷¾·ã³¤lX2œ*=±ªíVÇ<”B©ò®tNyMTm“h¼6psñÞ „êt]Ÿø-l¦FîÇ9ȃÌÈQ}¨s”e †€ÏšÚ6û#GŸ—Þ<>šÆb½Ð†‡—½0Z³A@ ãC€‰òáºë®KîégŸ}v#ss`[BwL{ñ ì0¿9:Õ³±ò•{ñ¨\:ôGëž(B=Ùðä&åWÛ¥ÜO¿òÆÑçÃðàÉÃÖásÐÜ@€à‡÷Ä]wÝ•Â{­¶Új“B™Ì $fg+ í}æšAÉ^°:G z?ד^òÞPƘÍ-ô?"4ïš©› ¼DËýŒl¹Þ{t¦õÿÆoœÂ' ³øë_ÿº±ê”ßüæ7‹Í6Û,n{fª¤Ý3”3îIæÆo,( ÊЖÕ2¬¯åZeØzÉ%—$EhSyö77ÝtSÊsZ½¿ü\m¥l½®åuêtÖYgë®»nqÕUWuåõñ?lö&ôQÉ„Î2»,WiŸƒ¦á=ôÐrëé§Ÿn¥?r÷¹X™õ±˜›GS ËCœÁí¶Û®©Èø-@ E¼·…^° ð¹),Š9å-oyKZ—üßÿû[±Zî—‡µ–k›êÙ ¦~yô*§Ûy@ Ð.„æ8ÉNm¨Õëä÷O}êS騟Ëõ½6âËs¡6bPê‡Ç eÖ¯ÇCýXÊ Ñésn"øáu4wÐçGqD« f\QĹ B(˜6¨îüâ¿H‚†e–Y&å^©ó¢øÍo~SÜpà Åõ×_Ÿ’q.Pì?´æšk&¡ Áf)P©—ß{#@ $Ï“äårOØ+Í((F!ïG›4N—BJ9¶ÝvÛPP´Ù±Ó°l‚rÂô{î¹§`i_æþbÔC(N ]¾ ?æ˜cÒ8!Ä'!¬÷;å£×ÓO?=…J%ÁóTÀ$ÄåÑG]|âŸHÊ„6Ú(…~"#ƒÏW¾ò•Â\-ùõŠ+®8É(€gÅí·ß^œqÆIiã»}/…yóæ¥0÷ÖB@ÉKúâ‹/6&Âæ¡,…ó¼ª)FxxÈUwï½÷×\sM’-Y—Pbt¢²Mr¸’ã|ðÁÅÚk¯ú˜|Jî¯/~ñ‹)ÿ—¾c¤ßƒ6Ȧ ð²¢Uš]ˆX hÆKeÅtl¥ —¸‡´Á{ï½÷t¬bc¸ð™ðlMlA@ ãA€Àßfj&k¬Ïþó)¤Èâ‹/>m«L jMø½ï}/YŠåN’=m›sØÈ{ "ÚÈA€sÿý÷§nÂJ,¿üòIQƒ_•~ö³Ÿ%AÂÕW_¼'Êó,^ðƒ’sî¼óÎÅ>ûìS°v !C‰Ð`ÿYSNBIrZï‹ÁJ‹«§#âÇ"Ö¹þ¬ÀÀœŽJkïô%þÌÜÍ%r0ì´ÓNI1QæÞ\k­µÒ¸ 4gQ’tSÜRnø|†E?kÿ[o½5ùÝÜUW˜»‡g¬ûë熼Z^·g™gCÉ·Óu ]Ê`âÌ3Ï,N9å”ôlð~`ÀДLÇÜÐâ”ÒF;yi„»’ÛŽ’€×Úzë­‹8 xöÙg‹Ë.»¬£Ey­gÓ¾@X)9|Õ[{)0Ž;î¸TŽ5„ë:a©M_ÿú׋C9$­!ì‰à`®S/õ“ë£î9“*½àar¬ª÷Ey.þƒ"MAÁ¢Ä„ ^bGä¡a]—{rj›æÒç2¯ƒ6—–¦½Ú?ŽþhâAâ¥Îº¬i,öªwý|ÜcO–¦, à Šz/Ä÷@ ÚCÀ{ž"ž•2·e ûºKö0Ü-êY3#e²jê´áé·|›M6Ù$]nc¨¼Ü<êu¦6±ßúÖ·RQÖ„½âÞZk R‚N©tѪ]yì² 96!&¢Ü š{ë$÷Ùw¿ûÝ”#rÁ¼*äO¹¶õN$ÇŸ‡ÿ3Ï<“Æ‹ùЇE)Üæ]ËÈoMă€p°ßó6*•åY[v+ÏûüK_úRR¾ð éDäLB }Ä0àÑGMaMÉqÖYgäé\bÒT/$¡ìÍïòM-Áw…VHë ÷j»¹¿ü7•ã7Ú§Â9ñäð÷²6XPV¿–JƦ²\oý@™¡,¡¦DÇyë[ßš<¶ÍsÊîD°³¾²*ǪŸø}n MAaƒÿo|c’…=åÄ"ÿ3™´FJNœõ‰eyAÖ•OÚ1Žþhâa¢¤íe)fbÕÛ£‰Gî± C‚‘#(@`|ˆ•{ '¤¤}6+¯¼r±ãŽ;Ž\kaˆX±6£9‰ÅRW›ÁÜ<êõ¦6WÖ 6]þ÷"–d¬ÑË2Ÿ»m¤Ò…þ©òðÖ¸|†"Píó6ÇA…J¼¶Øb‹lh=ðÀIX•rIÌ)\FÕê”r•×Äå—_>!àô ”Ï…& (‘½Y7!J¶†Ì¢‚XÈz'àðÖ6_Í>((„3B€¬‡Ëï’Ònºé¦I ™³å„–Ó•ÇV[m•³©QÖ EÀÖ<×äX—–kÓ¦k)öˆ¡›"¡Ó}~ï·ok\A§‚µr·ƒ"MQzÛm·¥˜žëo^Á Uï"Ê 1Á…v(iÙe—-?üðBòÎ2$Æn˜”Öó<¡ (QëýŸ÷ļILa½Þzë%%qï»âŠ™ˆ€ä³¼$PhëäYÏ‚P¹Ó™ÇÉ'Ÿœr¨ça‡–Þ%>@ ¹Ȧ  §±N”B ‹l{nÜuž)剳YÆ”°§Áÿ8ú£‰aO–c£RQËlºŸUŠø…,RÄú @ B%Iì'Þ*7pÊ„¤œríCÙ-GÒ¨D¢\æå6xÔë8 [k9(~(9º‘Є©ˆÂ¾ oÂ*Þ¾ÂzÍnª}ÞÖ¸šS8¡­s‘Ðs<#µ¨ä”;ì°Ã$#/ùÖÄŒ–—yGˆý¾÷½oB9áwÏ#o q®)(^|ñʼn¼/ÎõFà‘GIÞö²¼'"‡GoÌfêõ=¤ä¾<‘¹Üœž›¦3aæÊðSÞE<´‚@ 6Ȫ Øm·Ý&ÕÑBnԸ˓ ­ý05–sæ«Ü"åFÞFì3ŸùL϶£?šx”ní’ˆ~ä#éYÏ^4ñèuÏ0ç%.<øàƒÓ&ô¬³Î¦ˆ¸'@`ÄL=è ƒ†¸³û-¹×>âÕuÔQI1Q*³só¨·j˜vðî`¹-áiS\Ü*!#mR•GÛ¼ÚlG”Ý?Õ>ïÿ®Á®\k­µR¢O ¹HÈÒ2™»²åŒhŠ>öØc KñöŽàAQõ²(ëä]W¾/ª ÄËóñ¿3ßyç…ÙÄöA³çž{n"Ÿ‹çº ãÊ:rÓ™‡÷/4dN @ ÚB ›‚âÿý¿ÿWôkaß­1¿±î"€ %—iႦ Š/ùˉ¹Ñ”P¹û#WŸ³Ò¤˜°ˆªÅ\<ºõ°<„¦"ÈaÉ@ 0>$òÇoóH=Ìá”u e2E8O‹œÂH­í‡¡ã +¬Àyþùç'Õ³jýðèUF¯óx<ôÐCÅõ×_Ÿ.µn襠èUfýüK/½”úƒõ8Ëpž9ûìóŠ Pðn»æšk’rûí·O!W^qш_úáAHvÊ)§$N‹ÔëÙ« ýðèUF¯óx<üðÃɃÂÜ–+÷F•¯òO?ýôâž{î)ÞñŽw{íµW±æškV/‰Ï³ }~ì±Ç¶ÚçÃŒ«o¼±¸øâ‹ÚÛm·]áÈA„™¥¥r'e%†¤ÍÖ½È=B¯”ÞUõz®—Je ÅÔ{ ʉ»îº+åã[uÕU³ ›{×"®'ŒÆÊFrª „þk_ûZñôÓO«­¶Zò’Ï-Ø7}÷Ý·ØrË-½³ÆÙ7Á+@`v#UAqöÙg¿B(< t‚¬ï»ï¾äòo!4u°cIUöMîÚ”åŽÚçUoÞÕpT¹xtkû°<¸õ £UZ¶uãç@ ò!ðÌ3Ï$£ˆ²Dqßë‚V~7G uÀ227õÃCž¥Ò£qõÕWŸTÏ^uê‡G¯2zǃÔÚÂ'·§ þÊ—3D áj‚f7ãèóaxÈF˜‰Xç"!UyLyæ)&½X1—ÉyyOÿ6{æÅ„œ1MŠ×—<®-Ë÷9¨;ÂýÜqÇI‰½Í6Û¤<Ý3óÖB -”š1Œçïž„óçÏOkš¹iÜ<~ñ‹_¤wÈ;ßùÎ åiî6Ey@ @6…Íh? ”{Anñ-|«8Ií|š:l>ñ‰O¤Å97ò6ú#gŸ‹{Ͷ>sòèÔÃò ˜¨'dëÄ#~@ ȇáƒð <Y×Ã;áÄ€bºÄØF¬è~yXk5…¡ê‘~yôSV§kð ö†Õ©˜ø¹ÉœIx¤?X¥FN‰ÜO¿òô¹g³Í>v\ïÞ ¹Â;AŸ€Ô:–‡Áàw¾óâío{Rú9O±zÙe—wß}·¯IqAᨓ𣠿„]ûÙÏ~–N«kÓ»®~ï\ÿN±ó£ý(yPðNÞÉ#hv#°ãŽ;¦dóZ9Lø]!Ù( ­/(ê›òÇŒŠà8y0ʸùæ›Ó{䳟ýl$ɵóâþ@ ŽdSPX°í¹çžõ{ÂaóÍ7O‹l]ÖûAS‡€þtšÅ„9-ÄÊVåìs‹Á5ÖXc’À?'²ÞõÿÃòøË_þ’bï\óë¼â{ Àè>ˆ1Í"Ÿòr…yàµ`ŽF`Q/³þ½(ê'Iëºë®[/¢ç÷~xô,¤Çx,³Ì2…POS ä&‚Zá&XZ{ w4»Ðç;ì°C«}≯â‰ðÞ÷¾7åYYo½õ²u‚ºÈ'!Œ ëkÊJ ábÍ…1uðFiW‚Ö–rccwÉ%—¤PT¥wEAÝ€ŸðNòŸìºë®­ìº× ÎN£™£?üð”ë…"° OÂqòøØÇ>Vüô§?MÇG?úÑPPLÅ  ž@ ̲*($P•i ÃAS€ÍÏI'”*b#&övnÊÕçÊaáD¡"Yv•rñ¨–Yÿ<,B–ƒ>8-`Å9 @ ’ÜtÐA]™Q>/½ôÒéèzá'ûáAøxÔQG%%Å0Êì~xŒÐ„t+<'Xj?öØcI°—[J B84wGŸÃŽ"Áû!§Ò{IÙ·Ýv[ åd-΋ÂQ'JSJÊ ëÐ’„>»êª« áwï¿ÿþ‰¤Ø±®§¤ꎡ¬ðNŒå„ÎÙÇÝ9ÇÙ©D@X¯2,“>÷Œ B¼&mÒ8yH ÏË•¹qÚl[”@ 0wøûJvD ÄßçX­ãw1T‘ÐÂ$TÐ#²M·ƒGŽzÎÄ2ºåuèÔžqôGa/(&Xl6ÅNõíô{Üco Å0nÃ*·SÛâ÷@ " !„?!Œ°ñ6|RKåñ:DÂ;rXBB.®°Â © êš›G½~ôC¼|ádÁÞ>ðz±¯øNÊRi“v ™˜“ªok\ñ\BéÅ_LÏwÎ0O }èCJ^#öQÖ¤u²&å±Ä»d¹å–{ÅiÏ®DòB©#:wuÖ)Þÿþ÷gß‹½‚ù,øòòË/'ï‰|°Øb‹-B): ú´ß&œþùɳÝõ<,yêyžE¼Â9É\>]yì²Ë.Åú믟š{Õœ½e@ ÔȦ  È>ãŒ3^‘˜3Á#Ž8"ñeÿéO:{üæqðH ˜£:åuèÇ8ú£‰‡z–I¹¾W“dwªk·ß›x°°ËM6˜¬aÛ¶¶É]ï(/™Ž€ð'Gydô{¿ç=ï8ùtó$Ç<öØcÓ)ï÷ýöÛ¯3z’,÷”SNIEkDИ›G½~ôƒBF[K…O½Ìú÷yóæ%Ko¿ ]µÙf›5&ú­ß7È÷*2¹ö ÷ǵ3jŸ·5®.¿üòâ¼óÎKùvÚi§bÛm·Í¥æî»ïž” \pA2ö²×ºéU¯zUzÆx' =DxXW€2ãNáGBIÃ+ƒ·; îÈÿa/!ÇÍÊ+¯FDÝášUgÝrË-©MÂ;^qÅ…<Œhï½÷NÊ@Ï`N:çœs¦-R9‘³½QV @ Є@V7âºPX¼S“.²ùJ!·wûì3ñ}ج!˵ùs=öYAÁŠºœãäÃ"7z{‡iÞ²Ë.›¼=„EéEe;(66Ø`ƒì Š*^õ‰ó³jŸ·5®^xá…âÇ?þqÌsž›Ä¯§Pà9%ÂÃ?œB­0øZŠÂA¨¦&#¿QP¨å¦P”£å¶þÎÝî©.%;¼!Þ&ÙT÷ÊøøS.´ÐB‰¡ðN7Üpðž×RnÅtæaðÇ?þ1áAñažÆ7ƒS s l ‚ìzx'`úÝd†LøM‹ètr„?ãà1Bõfô­,¯>ùÉO¦ÄpýZ\£?šxPPØ@°k‹ƒvDAËèçz®Âòf@ Œ‡7¾ñIègÓM ˜ƒx”ka_r­}ÌKêÙjû‡á!¯Úh£ ajz‘ö”X ¥Ñ† °Êƒñ#hv#Píó¶Æ­á<ã9Ã;U{æÕ¯~uzŽúy–ª÷ùL‰±×^{%å¨$ÚB<õFà‰'žHùsx«PND¾ŽÞ˜Í¦+„L[{íµS“¼1$+ç(ë„6æ¨é̃AéArØa‡Åó0›{´%i†@6…Å? Á:ï¿ÿþégר0ä¦qðÈ]ç™Rž×zë­—ªÛo^‡qôG.ì„Mk®¹fŒŒŠqQËlºßèÑGMñ€‡I|ÚTfü@ Ї<° "ô畃xŒ–kŸ G%‚õc-¼S<êu†‡¶Z;È ±¦¹´±ð.±"D4!i·²ËsU7ÝtSñýï¿<ÿg)Õ>ok\ñdxßûÞ—ò¬#5ÝÈóë y;qà ¬üsƒÕ(®'u£±­¶Új"É¢‹.ÚÊx˜Î<ªÞ»,ÈG »qŽÆàÀÜB «‚B¬Ô:q«¦mo“ÆÁ£ÍúOç²Å»=ñÄSË"½ê;ŽþhâA²øâ‹'oɲG¥&£–Ùt?kÓC9$yyæ™M—Äo@ - ð†7¼¡8øàƒ³—¼ð g_û¼å-oIù2x3–Êì¶×Wôƒ¢‡…éu×]—BAôJ’ýÞ÷¾·p´IU·„‚¢M´§GÙÕ>o«F b–Xb‰ò…—xÐì@@n"ŠU^+¹”Ö³™¹ÑŠçž{n"aµçZжi:óà=²È"‹$"¼SÛ#!Ê@`n#MA!¼N¿öÝ ÿÛßþ–âÚ@Úà /À/hj  øÒ—¾”˜T|üãÏÞ¹úÜfB|]‹¨úXÌÅ£[/ ËãøCqÍ5×D¾nàÆ¹@ Z@ÀZã׿þuFØx›Gêažþú׿¦uÉŸþô§ªÉº$÷&½B.²èEÏ?ÿü¤zö‚§½ÊèuÞ(×_}ºTø¬^ Š^eÖÏó:Û!¯ôEîxàužñ}jÐ×ÂrµÙçÃŒ+ã›ÇÏï~÷»4s…yRkCÿG!¡åÔÏÑFXšQê6ïõ{×»Þ•¼'rx¿Mç¶FÝ&# )=Ïv$wæb‹-6ù¢.¿X+˜£Œ#Þ7ÆP®0%ÛqòØl³ÍRtk^§A@ @[dSPd³þþô§?=R]ÿüç?§„s?ýéOÓ†“¥ ÷é ©G€ çž{îÉÞ¹úœ’ŒÕ“ãŽ;îxÅXÌÅ£[/ ËÃâ•5l¸áwC7Î@ óÅÑG]<ýôÓé,Þø¿üË¿¼‚ÑK/½TÜu×]ÅC=” Ë-·\JZûŠ‹FüÒ‰nO=õÔÄémo{Û¤zöªB?9RyžAà, Å¸§P¡D eEwXÆ™ ¼ëƒæŒÆn¹å–ÔpÏõ  ŠÇ¼¸ûî» ²Fs­‹B“ÆÍC¨32™ÜÆ91‰²@ f>YguÖ+„ÂÃÀÃbèÊ+¯,N:餔¯Br·PP ƒdž{X'¾ùÍoN‹,‚‡«¯¾:{äêóª· ª²,n¨ËæñøãÏî™Ò­®q.@ (žy時µdI‚u…0|]tQ!Q$AŸ| +¬°ByK–ÿýð /=W_}õIõìU‘~xô*£×y<N¬(ÝÛ{£ü“O>¹˜7o^±ì²ËŸýìg‹PPôê™™}~}> ‰c 3Ñ»ßýîl óB:í´ÓŠ›o¾yä2)#äÿ7^œû-·Ü2 M)/‚š.vµÕVË.Tnæ¿N7Ì[öfò(Ýwß}iÞ·¯$œ§<œ?~òº´húýöÛoOÏ/ïLs5ï/{éN×óû­·ÞZ|ñ‹_Lu‘—ÊØÿ¦ú S¾räb9ꨣ}öÙ§ØeAþ !ÏBI1ÝFlÔ'ÙƒÀ?äjŠÍèë_ÿú,ű¸3ùqInÃú.K%çH!BJˆÏÍr¢ÍþÈÕç6b’±7Å\<ºuý0aY[}≯R^Þò¬ä42¡è³&´®…( …?-éÅ_,.¹ä’äÝ$§ÏŠ Éðþа«“q™+¿0ã ÈKï…^¸ÙŒì­x!Ïhý“xl½óï,®½öÚâ²Ë.+~ûÛßæ,>•…‡µïMÞ¦W]uURØðÆ @ Ú@ «‚b÷Ýw¹ŽIí¼óÎé¹°(`d,¨¸™#V%¹)WŸÛÌq˶°üÈG>òŠjæâñŠBk_†åa|È!‡¤Pò¸@ Œ7¼á ÉK°7ž{ï½w:º]7ʹ~x¼å-o)Ž<òÈzev?eÌk–¦Õ¼ísŒƒ»îºkZLΤ±(ww`ø@ Œi5f¹âŠ+&VÏ?ÿü´­'aÌõ×_ŸêÉ’”uyP 0`eï½!V=#a]r¥‡Øï£ u»í¶ÛŠ3Î8#å´°æ|ì±Ç’ç.AjP LF`ýõ×/uŠßëˆÄ÷@ @ ÙÙ¬¿ël›~–:H¬`î‚Âðä¤qðÈYß™Vë B›~•Oãè&”dÿþïÿžŽ;î¸cÒX÷&¹Ç®:ÙÔ²Œ wòA{(®@`4ÌG}t².öf1YO’= ‡2¹¦{ÍŸÂÓXBÂDœzê©©I¡·ß~û”ÀÓ¹xÔë7L;´“•¥ùR½z‘>˜¿ é(Ò‹,°X5/æ¤*’WÎò£¬é‡@µÏÛW7ÞxcqñŧÆo·Ýv)6ýtBB^ a¨x[Ë Ó"^ýï~÷»tL§ºF]@ @ æ6Ùv€guÖ$¡0—C‰¡ e…ØÄ9i Šù-<“ð @ @ ¦ Y»ï¾û¤vQJm€l:Û°0I ›#?Ýuâ‰'¦ÖŠc[Ï1ÒÃ8ú£‰‡LïxÇ;’7ÂG>ò‘¦ª ô[ èóbÖ¦|pŸ<.A@ ãA€÷„÷on¢”(×>”Ýr2ŒJrIœ«l¡ÿô§?eçQ¯ã0íxÝë^—<(®½öÚ”@¸W’ìm·Ýv¨à5¯yMáÈMUÖ4Â*Ínª}ÞÖ¸zÿûß_,ºè¢)œÙ¨!ÜÚî ʉwÜ1=k -´PÛ,£ü@ @ @ o²)(Äÿî¹ç’µÊR¢íEû8xTÛ4—>SP”1¯Yšö£ G4ñ°áÚm·Ý –rMcqÐ~kâ1hý\Ïóãšk®)à@ 0>þû¿ÿ;%Žõfõo!È•(%r¯}„\\i¥•RÕ^xá…TÏÜ<êí¦òx\ýõ©(VÚ½BV9Ú¤*¶yµÙŽ(»ª}Þÿ]ƒ]IiÈ‹‚§ge#¬?ÿùσ‰­…p&-'©§Ü0Uzùå—“§Ó«_ýê,JÔjÙñ9@ @ l ‚ì3Î8£/v· rAf ÿÛßþ6-Ò ÞøÆ7v»%ÎÂzÇÓO?½?rõ9%ÙüùóÓqÇw¼b,æâÑ êay”¡Âݾºq.üüû¿ÿ{qôÑG'%E¦ž$›àк„ðÐûš‡·œÔ§žzª8õÔS[õzöªO??öØc[íóaÆÕ#<’Þ }÷»ß=2ÀÖ‘=ôP!TéòË/Ÿ<4F.¸R€ÐpŒ®¼òÊâ›ßüf!Ìœ6A@ @ ÀT"MAA⼆,z¸g¯ºêªS‰Ïœç-¤ÄÇ?þñâºë®+îºë®Ô7¹AÉÙç\â…è¨Åœ<:µX›l²I§bã÷@ –`áO@Çßç¦ðNzÂY—©ôì³Ïf¯M¿<¬µ¬šêÙ«RýòèUN·óxüîw¿Kac„¿ióA_=þøã©?ÔE2î ÙÀ8ú|XÖpžÇQÂ;é=ž@”¾êU¯*¾öµ¯%‘vک炲ÏÚv”°O (þóŸ'Åï ý÷ß¿Xyå•g÷ŠÖ@ @ L{²)(Ä6ÝsÏ=Gn°Ø«Â'Hv,©ÏAS‡€×l„3Â'µÑ9ûœ€iÍ5לH¸Y"—“GYfýÿ°<þò—¿$‹Ó2ÔS½Üø@ ÐrÿtÐAÅO<‘â¾K ]'ïfŠ ësਂÈzù¾÷Ããÿïÿ],¹ä’Å{Þóž¡,žûáÑT·A~Ãaƒƒ"…B%7Y—Hð«?äœÂ'hv# Ïåeh³Ï‡WÆù{ßûÞbýõ×/Ö[o½‘;Áû…w%…°¹ŸùÌg’gÆ[l‘ž{I”~ý†N³¾¤x>Jˆ¬n¸¡¸êª«’Roã7.öÛo¿b¹å–¹ÞQ@ @ @ 0*Y»ï¾û¨õIanÄ^å*m£Ëj(hê6IÌk9AV\qÅbÓM7Í^›Â}n¼Ø¼òFà_¥\<ªeÖ?ËÃÆñàƒN^gžyf½Øø@ м'¼»…ć?üá§`R#7õÃGÂQGUP¢ÈA1(õÃcÐ2ë×ãAà)T‹oIÈsÓÛßþöbß}÷MBWÆ1Ã`‘»NQ^»èóvØ¡Õ>f\ÉÛ@i¸ôÒK'ˆ(x†vÙe—TÞ9çœSüøÇ?.n¿ýö”àZ(&‰®)è<_ÞGÖ¾¼+xIPJðdúÃþ¼½|ðÁâG?úQò‚¶–_xá…“„"d‰%–ÈQå(#@ @ l ámž{î¹I¡u­¡…ö;ßùÎt zo\Ÿ Н|å+©`B™Å_<;“\}n³Æ=žEe},æâÑ­ñÃò°‰Û¼ ¡W·úƹ@ æ:èòPxS2›Gêá“üNéh‹úáÁZ{¥•VJUxá…&Õ³WÝúáÑ«Œ^çñ€÷§?ýiºT}·Új«^· tž·Äa ãâ‹À8ú|ozÓ› žMÖÊ”ÊÈAoúЇ’2òÜsÏ-¾óï B­ZkR¬.ºè¢É£ËµÞ[¼x%ú–üZ˜5ïµ_ýêWÉ[Â=BŸòô è¡èpOP @ @ 0]Ȧ °8çŽüéOúm£¸Øqõ&ÁB9'ƒGÎúδ²:åuèÔŽqôG¿Í_†ÊqÇwL‹êÛé÷&¹Ç.ÞÊdk£@ 0>Xú}ôÑI˜ç,|Ҡɧ›jKññ›ßü&ú_ÿë%áà¨áŽžzê©äѨP^ò¹yÔÛ2L;´Wÿû‚Ê!A Š\OCØš“ªok\Ýxã)©µÖo·ÝvŶÛn› koÞöUB— Ítÿý÷§\pŒpäÅéFÖ–žCžÅ¼&„kÝrË-“÷E·ûâ\ 0×oÊûƒ"ñO% ?ësâ\þ}®h @»dÓPPœuÖY“„Â6‚GqDjÅk_ûÚt>—…Q Í8x”¼æÚ‚ ôV_}õ¾š?Žþhâñ_ÿõ_Å—¾ô¥TG ʺ²¬¯ÊW.jâ‘{ìb§Ìã?>YïVØÇÇ@ – t¸à‚ &¸@äPPP”{챩ܷ¾õ­)Öû¨ £{”sœùxíµ×ÎÎcˆÿù0L;䄆f…V(V]uÕz‘“¾Ï›7/ _XwÝu‹Í6Û¬xõ«_=éºQ~¨ò | šýTû¼­qõÈ#$Xh MÛñøà?˜ž y$~ðƒ¤O¥°ôüc éô׿þ5¼P ¨òóÊ‘áYäA1J’í6ÚeÓ8 D~›m¶)Ž9昴æÅ$Ä"Å ã€Ã?<)þæÚïÓ±¿¢N@ ³l ‚l‹ß:IÎ&†*b(en!ï8x¤ÌÁ?,?õ©O¥×2Ë,Óãè&*7¨·G·5ñÈ=vñ£ÜÝÚç@ Š$Èc é}_ õrೡ\ûðÊØc=’5ó¨e[kQ>¶Å£ZÇaxÈ«d.–„w•UV©×ø™Â ÄЇ¥wnE•Gc%âÇY‡@µÏÛW@³†ó<¶±>¬v ÞŽ=÷ܳxùå—S~¸çŸ>ý—w‚§ˆz8$ÜÎýUëŸÙŽ€P…ŒÕ‚@ @`<dSP°ð±`®“Í´°Nˆ#·Û¾rÇÁŸ¹H6^øÀRÓëy:á1Žþhâ!$Wø6Ú¨Sõúþ½‰Gß7p¡„†=öØD¨§nK@ F@€·É'žx¢ø§ú§ó}„â&neÅ\®}/s¬}ĺò…ÂC ù6xL4à> ÃúÁÁ³–gc¯0O.%VÖ’mXyWyPF9‚f7Õ>ok\y>x)l¾ùæÅzë­76@½O´Ï!DhP äCàõ¯}òŽà$ñ<2GQ¸{Þ[l±´ßœ+¿›ÃŸ~úéÂ>›A‡µHP @ ÐY»ï¾û¤:šÔößÿô» ‚ÅtnÜuž)å0œp ©ºeˆ®^uG4ñ aY¶É&›ùÈGzU³çù&=oâÖ¦‡rHRàÉã@ 0l¶>øàìÌxŒ–kŸsX2Œyä‘)Y·Ð‹BMäæQb˜v°Ü¦d¸öÚk“§4r¨—]~§p)Û±âŠ+N~Êó9þWyÜtÓMÅ÷¿ÿýÅFÓjŸ·5®–Zj©¤€ã-DÙ3vÚiBá¸È"‹¤m¸á†…£Nsá÷Ïþóù¯>ùÉO‹/¾x†ø@ dA ›‚‚V½Éž[õa‡–¥² N¼gûïeÌë~ó:Œ£?:ñ ˜°˜l‹ƒöU'ƒ–Óëú?üáÅÕW_›Û^@Åù@ 2# á¥<Þìþ)¦y<ŒJ’Òæ^û¹HèŠ^xá…dá™›G½Ýôƒâäúë¯OE½ñoœð¬—]~#ßÑ&UyèóPP´‰öô(»ÚçmÕhµÕVKÂ:á•›´æ©­vD¹@ ðwš?;÷>Ýxã)'‡–Ë¿ й7¢Å@ Œ l ‚ì3Ï<3å+¥òûÛß .•6,ð¸OMúAŽ”BœœµÉÕç”d#Ž;ï¼óc1ní–‡¸Â,cYª@ Œ‰f?÷¹Ï¥|¼)V^yåbï½÷~E$Ÿ-Ñ ­b]’;ÄA?<žzê©â´ÓNKuãAQ¯ç+*Ý𥠷 ôˆ·ì«^õªâ5¯yÍ@÷÷s±°ˆúáõ^A³}-,W›}≯"¸»ä’KðÛn»má ™À³Ï>›äZ!Ü“ðÁs™¬ÊPr¹×>s×h{ Àd¦‚B¬ÇÿøÇ…ÄT6œK/½tñ¾÷½orÍã—± `óÏ‚Rx.–÷ÜsOöþÈÕç”d'žxbÂ…·‡äÞ%åâQ–×ôX,îŽ?þøPÄ5¿@ Ð"¼'Î?ÿü uÁÿK/½TÜu×]ÅC=”B5-·ÜrÅ +¬0qOŽýðøÿø‰9nõÕWŸTÏ^õè‡G¯2zÇã?ÿó?S¼nóð[ßúÖ^· |žðHÀC8)^%6A³}þÝï~·Õ>f\=òÈ#ÉòÞ A@ 0ó8ï¼óŠG}45D^9'æ2íºë®Ål ¥ (@ h l ‚lI°G%úW^yeqÒI'% ¼½öÚ+»@|Ô:Î¥ûyMˆ ýï|§¸í¶ÛŠ%–X"{äìsÞBtÔÇbNúX¼S6ÝtÓNÅÆï@ -!À2RòK‚uŸ›Â; ÝrÑEçœsNºÖœ˜[AÑ/k-Þ MõìQ¿ùä“‹yóæË.»lñÙÏ~6¹Ažfå£Ï‡åa çyŒðNÓlÐDu!¸îºë&Bí°Ãs^A±Þzë ‰dÜ@  †@6 û=öØc0î®æ9Á…° Üö;€4¦Ÿm¼XM°ã=ÑVäêscf5Ö(6Úh£Iåâ1©àÊÃðVà±Ç+ÊPO•ââc @‹°ò?è ƒŠ'žx"Yã/¹ä’“¸Q|WßíÞÕ¹©ÖEê·ÒJ+묳ÎÀUè‡ÇÀ…ÖnÀƒR¢ÄHèÅÜT ³%ÜVJÜuŽòFC@ŸSž¶ú|˜qňGŠõ×_"©îh-»@`ªÖIôd_9׉§©°ŠH¸§ó4×GD´?öȶËÎ¥  °gQ^nÆÛk~”Ü a“N9å”âH9(š„7½Êèu>WŸÛ¼¾ãïHcG²ì*åâQ-³þyX,N¹óú8ãŒ3êÅÆ÷@ –°ÙöþíFõ·˜ $]tÑn—u®b@yä‘)ôå0!úá1Tå+7áa.ãåñòË/§dÞ•ÓY>²V'~ík_[,² ܘ Ù€>_j©¥ZíóaÆÕZk­•ö,ÂÑjÀÌG`§v*Ö]wÝÔF s¾ño?üp‚ᓟüd$Éžë"Ú@‹dSP°’{î¹ç&…Ö´î¯~õ«‹wÞ9ƒÞ×çG€@æ«_ýj*Ø"«knÊÕçB;QLXÔÇb.ÝÚ>,¡¡®¾úê"ÁÝÐs@ äGà¿ÿû¿ ÖÞÄëæ‚Ê*És /E=7EõšQ?÷ÃrD¾ô /Lªg¯:ôãW½ÎãÁPàâ‹/.~÷»ßO?ýt¯[>/Ôäá‡>ð}qÃÌE`}> 7½éMɘÊZ™‘J„yš¹c,j”l¸á†åÇø¿o¼q"äÕn»í Š@ ­!MAaq~æ™g¾"1qkµŽ‚ÇŠ€ MyÆZ‰>˜Q’=ùä“é¸óÎ;gÌXäùÁ2ÖF7(@`|HŠý¹Ï}®øÍo~“B¬¼òÊ­*"FiÙSO=UœvÚi©m*LF©§<ÿçÿüŸŠÇÚ!(˜­Ü]rÉ%©yÛn»má ™À³Ï>[0^@<£æz˜'^ŠŒÿP„wJ0ÄŸ@ –h]Aa‚¿ë®»RõmZßýîwgŸèÇÁ£%ü§}±b;„°Ú\}õÕûªï8ú£‰%Ù‰'ž˜êÈáSŸúT_õítQ6©,îŽ?þød½Û©.ñ{ @~xOœþùSXäüÿçþgqß}÷¥r é…§±…þã?þcbŽ3øÃÎΣ^¿aÚ!¼Ó2Ë,S¬¸âŠÅ*«¬R/rÒw˜ÏŸ??ýNQORæ°˜tñ?Ty”¼†,*n›!Tû¼­q%?X$ \P Ì|Î;ï¼âÑGM r±Å›ù¡¢”^%¥¢b„ââÖ@ @ #ÙÙâ׉U¢¤ÅȲâÍo~súžëÏ8xäªëL+GH ñ&—_~ù$pè§þãè&ê–ÓÛ£‰GΊȹ@ 0^(Y¾ôÒKÉx¢ÞiØÚPN”k þ«®º*K®k- õl‹GµÍÃðWIÂá7Þ¸XuÕU«Å5~>çœsŠ#Ž8"ÛÿýÓgkœT味Ü(kú"Píó¶Æ•Ö[ÃyÇÞéoû[ZëöBþ¯ýkáZÏ¢µqP ô‡Àu×]7ÒHhã¹® Xo½õú.® @ FD ›‚"W’ìÛ·gFÀÆkýõ×O¥Öó:df•¥8Â&B¡6Ú(Kyã(ä/ùKñØc%‹Q¡ž‚@ ƃo»ƒ:¨xâ‰' ù–\rÉñ0‚‹Ð ê·ÒJ+묳Î%Œçë¯Æÿú¯ÿJ!"ÇÃ9¸ãG@ΡʤºmÔ@SÞLÖá¼{|ýÓ?ýSWVrÀüò—¿,(*^xá¤DÕ‹«+Ã8Ì„uòÌ 6<çgL öþøÇ?¦j3èˆ0O3­£¾@ ÌZWPX —IyX´±8™Ó¥ykZ ›ôÚ×¾¶¯°Iãè&þóŸSrNÞÜQG¥&£–Ùtÿ‹/¾Xzè¡I8vÆg4]¿@ ´€ÀÞð†B‡Ü$¬S¹öÞIÝQIh…#<2…‹zûÛß^Ü{ï½ÙyÔë8L;(zXl_{íµIÑËú’°µÄJy‰ä¦*_ÿú×…pYA³jŸ·9®Œï-¶Ø¢XtÑE[ôå—_Náfn¾ùæâ»ßýnÁ¨e¿ýöëéyûÐCÇsLÊËÆÐhƒ 6Hav­åƒ@ 3;í´Ó„‘Ã\§¯ýëÅÃ?œ`UañÅŸëDû@ ZB ›‚‚uO“…=¥„ÐȦ³ èqðh ÿi_lUAÑo^‡qôG!:vÙe—ÂF´i, vAËèçz›OÏH,‚ûA+® @ ¬‘塸Ãþ¬þ äs„y¢”(×>”Ý’FJ‹¥ ÿ…^HŠŠÜ<êu¦O>ùdqýõ×§¢ÞøÆ7½¬ÏK¯Ç×¼æ5…#7UyÈUu 'äfåM3ª}ÞÖ¸2¶—]vÙÂHh³Ü{^·Ýv[qê©§7ÝtSÁ‡ç„üÝB=9'?ƃ>X<õÔSe…„Þûì³OR¦Xß@3e¾…æ³sïWïŽ[n¹%5|·Ýv ÅÜÑâ@ Ɔ@6Aö™gž9ÉžR‚;`›4mÖº—=h^‡qôGDV‘Ž;ï¼sÒXç&ƒ–ÑÏõ’ íÄÚ/(@`|¦}ôÑ…¼)V^yå,I²)%r¯}O;í´ÎÛÞö¶TÏÜ<êÈÓŽR!ã?…O/’SÃÑ&Uy´Í«ÍvDÙý#PíóþïìJkÍK.¹$ÝD!²Í6Û V@—«)O ¿øÅ/&o©òRŠï­ßÿþ÷Ÿ/†/ÂÖy¯•ôóŸÿ¼8î¸ãR¨–wÞ¹OŠ™ø¼gŸ}6…Ró«pOs=Ì“uã?á ñ'@ %ZWP Zo±R-¨ûÛߦÄn,YàM „ô%¬û—^zéâé§ŸÎÞ¹ú¼›·G.ÝzaX6‰6¯~õ«»ç@ 2#`N;ÿüó'Je™¼÷Þ{O|÷Õ²u Á …²F¹-ûáAùÎú­¾úê“ê™NtùÓ.·÷u D"äÍK,Ñ×}ƒ\Ä[RÐÊuA€”ÃCe:ĵãE@ŸË§ÐfŸ3®„=)½˜xRä$eS~冬Ç%7Þ)þºåwáF¨¸Ê*«óçÏOÏËŸþô§âW¿úUqá…¦ç“×R$ÏÎÙcQÖlAÀšàÑGMÍ9øàƒç|’la“K¯’RQ1[ú:Úôƒ€ùÖº“‚ÎÜš#lk?|s^ccã?²n¶Ÿ±¯é‡äÁ²gr þáþ¡ŸÛâšXÛÊñcÏİk69¾Ãz•œsбÒ߈ì) çvV?]tQZ@Ûxn½õÖÅØG â’6ð:à€ŠŸüä'Å=÷ÜS\zé¥Ùû#gŸwòöÈÉ£ÎÃò ˜Øl³Í:¿@ ´„ËH m vŸ›Â;=ÿüóÅYgU\sÍ5éüöÛo_ìºë®YkÔ/k-–áMõìU¡~yô*§Ûy<î¸ãŽ$Üá‘Ò†µ%Áíé§ŸžÖ$ïµ×^Åšk®Ù­Zqn†# Ï=öØVû|Øqe¯âyÌÞ‰"æ†n(n½õÖÔsxÈ;#„c™e–IÊŠNÝ* TÎéºë®+.¾øâ´Ž'dyàR¸–UW]u¨÷H'žñ{ 0[?© id¾_l±ÅfKÓ†jG¯0C73ûï¿¿8ùä“Sx³=÷Ü3y\Ï ê'åʼyóÒ{!£Ú7Þ8y}Z/ åÒȈ`Ù~£J?úÑŠ/ùËÅÚk¯ÖÝá\EgøÏÖ¶ÖŸÖio~ó›‡/hÝiýJѿ˂Ðû›o¾y2&¤zÙÿøÿXì¾ûîƒðn¼V˜ ï»ï¾´ ·€š:Ï?ð\ÃmjÚèœ}NÀ´ÆkLXz”ÈåäQ–Yÿ?, {챤Áê)(@`<,¼ðÂÅA”¬³-Òy Ö‰å±*Ö%”Â?ä¦~xö/¹ä’ÅŠ+®8‘ÀszôÃcòš®Åƒp•Âf¹Iù?þxêe³ê šÝŒ£Ï‡áÁ£aµÕV+$¡^wÝu³u‚5¡ðQrÍðÎ`ÉM9ѯÒŚСöfÞ_øÂR’m¡£¸„b/[—EA³Â9k4×Ã;Á€å8 _d Ôï;(ÝY€À‹/¾˜¼ÍÇå³0Sše]~î¹çÿöoÿ–dMÞm¼0½Ûª–í Ä­Û)/?üðIa ­ç))ȪȮ‚ò `-Æœçël!ÿwß}wÊAH>:(eUPÐ(ŽJîF¬â$µó9hê6é”SN™x)·Ñ¹úœ‹šq³é¦›ÜQ«”‹GµÌúçay˜ô=ôÐ4ÖÏ8ãŒz±ñ=@ %„<äCº–nn±)7¿˜sZJ—Œûá!´Â‘G™’c³¦”úá1h™õëñ`ØÀý]‚_Y¹‰5ùB -”ú&aÅ•áéWž>§@ô ¶ÕçÃŒ+þw¾óÅ»Þõ®äÊž 9Ágžy&Ç;c«­¶H9Q­‡µ©Ü:¬Ø±žT6A@ 0wܱXguÒ !Žç:}ýë_O¾pøä'?I²çú€ˆöÏ((®¼òÊäAÞ$:=µA•.¿üòd!‰è)‘§ªŠN|'Ù´#Ï=÷ÜÈažl,¢ßýîw'-ßlqug§æäEAñÕ¯~5ICøŸ›rõ9m0W"›×úXÌÅ£[Û‡åÁÒT ãXwC7Î@ ÖÄ„u,W¼ÃÍ#õðIþð‡SÞGm¼«ûáa³ðž÷¼'À²º^Ï^èôãW½ÎãAyòï|§ÔÛ\œ›”¿ï¾û¦Xº¼w廚ÝèóvØ¡Õ>f\Ù£xoX+SÊÿ9ˆ¥bé}D²ÜrËdµÌês©¥–J9a(((ÇÀdäg ú;7ÞxãDÈ«ÝvÛ-‡&>ÓÇ<R×Ö)·¯ßßúÖ·¦ö06 ¦ l£Ïâ\ŒfšõQÈa1îš”y¸Š/¾øâÙ+•«ÏËKB„Ýu×]¯‹¹xtkü°<ÜÇ]¾A@ ãC€eÑÑGÂ6Yœ¯´ÒJ“’O@ ýÔþ)WMûáÁeö´ÓNK,m"êɼ{Õ¥½Êèu–YòWIöFá“›õSÐÜA`}> ï}ï{)‘µžØvÛmS<ç½B˜`_…šNÈý2דd ›¼á†&êþòÙnâ=Èo‚¹«áZ Š=÷ÜsÒ 4™! îò!˜tá?ŒƒÇ՛ѷÈ_úÒ—RxÀô6iýÑÄÃKÃFуÏuTjâ1j™M÷KTø‰O|¢xÝë^W|ík_kº$~ @ hy'ÁG a@IDAT9äì%[Ø—kŸn›‘AÛ8qÄió$¡¯ÍGnõú Ós™ù˜ª…o/ëK›Û²Ö’õ @½NÃ|¯ò°ñpÍnª}Þæ¸Z~ùå“×OÎmÞK6Æ6›,ô.¿üò´¡µÏ²yìWhÊbÏfý‚ .(¾õ­o¥qïùRלõÝ#)Z7רqÇ B$dð\§o|ã…pvè_ÿõ_§Í»ƒðš‘¡`ò¥^ýNiãÝK(Ø«œaΛ7¡è§>õ©´ž#Œ$Ì?ñÄ“ò{Ë-·œdÊ}ÞïX2$Jvj†+”gŸ}v±ÔRKûì³O2*ídÄBpLzòÉ'wÜqG²ð&è§0S6Å;¡­5ü^{í•ä(u, Ü?üðâø@šS;)((9ä£Ó<† Sœzê©I `l’›j£ßýîw ÏÑ.»ìRì¼óΓ”9e½å™ûÁ~Êжã?¾¸þúëÓºX˜µ~×Çø _é £ ŠƒRˆNÙä(ŸBëý÷ß?åÒ"ôVAa¬ðdQo}kýE¡koÆê[mµUñ†7¼a‚wÙþ~ÿ—ueïY8é¤“ÒØÂO½õ§¶î´ÓNžûî›äƒäzMôÐC¥ð¹7ÞxcZ[ßÊ!ȧT0^?ö±¼é¬+«Dapàk®¹fj3¥F÷p@௽öÚ/¹A®»îº^{+ë@JÏãìüã…õh§~#Ó½âŠ+Н|å+IÁ  ûScJ9Ú©Ï `'¼ð;÷Üs‹û·Ku(Ãò^|ñÅIä~kÏQ(›‚ƒØda¯ƒ vd€Ö;v”Ê—÷ŽƒGÉk®ý7˜Ë˜×ýæuGtâ᥿È!NÓX´ï:ñ´œ^×{ˆ¯¼òÊX÷*Î@ Â?›'Ö-6OÞûl£‹ríãó0›zlvV^yåô³Åj<ê<‡áÁâËÆÙ€ôRPð0)±âÒ¯ðµ^×nß«—®)¸„ᥠ•°žÁƒ2°©ï("èüã'ïcOª”§œrJñÍo~3ÍyxN%i׿øÅ$ϱöâô½ï}oÁ˜ˆ@™g„ó”-¬þaÖÍ{Äzâ /L†H<XñS”Ê„^me°K™h¼˜ÿõ×J+­””Œˆ‹÷Üc–A„¼=žMáZy—RFY—<ðÀ EöØÛ׌Bóx>yä‘IƬ<ë&sž”$ò ‘e ¹k]UWð‰RHŸx÷ MëB©ã÷£Ž:ª8æ˜c’7Ï’ªB²ôt¡áUP üëm²'Ò0é¤$«ßS~'cÆLÈ8ák/èCu饗—\rIq衇_þò—Óû¨ZDzÊJFkFÆ.† áï;E–¾±ÎÔ}Ç:Ycðe,ã™4®(½<§ðòÜ[Ÿ 5,eSPèü³Î:k’…=íÌa‡6lýúºo<úªÈ,½ÈÃLhãAè‡ÆÑMŽþ/ëPýO8k<åxr—ÂÏ ï û ?c•§F'âLÈÏ3d»í¶Øø€¸ÌgM`¾·^ À÷¿ "Ö<(äÝãuÀ8½$^”;ì°CR.„äõñS^ßÏ8içqÇW¼ímo›P@Ø»›x]vÙeÅ?øÁäS_ÖI:Æb©Ä°¶bB  ß„Ç¢$ª¶É¾Q¼‹xùxOÖ×VÖ‰ £üƒúù^íB‰BÀøf4N9Qb¦Ÿ…$S'ˆÄBæ÷*©ƒ:2ŠöÜRPT(x?ûÙÏ&ÏŠ1JÅ&Ï)Ê2aüŒ'Ï9Zn¹åÒ³ÊàŒ×/žÃRVÅgœ1²P˜M£…¢Ñƒvä°`Ä}“ðr%ÃÍa°åî\}ÞÍÛ#Éýý—ayØXz™ä°°ý{mâS @/(´YØ”Ä*®®  ø³.adóc]R_ä–÷û¿,KFñèëõìÅ»½ÊèuØXìÚ°6ÊMÜåõ‡ÿÖ(ø•.ë¹yEyÓ}-4@›}≯ö„,²NÎI6£›o¾yÀØ„³¾CÖº¬Ôƒµ;¥†8Ö„A@ ÐŒ€5¡b­Êây.Ó®»îšrCÁ€nªIXú¾ˆQ"Á!w?F£Ö_˜ `²*Á%ô8SÉn$„¹„c€‡ƒñS*J^Z‡ÆEo‡ú3^lÈ¡B©Q/CYúUÿRÙÖ‰·ÌÕW_ò¡3_—“ò¡H£È&¬å„ý% %@©œ(ëáûn»í–”êÁ«‰¬:7F;¢á4…ªR–¾±64÷‰,:/Fr””0'.•e]ô9¯(Xy.‡¥l 4½<­í-¤‰Æ†ÓC®Cƒ¦V4m„ZZÆÜý‘³ÏÕ±ÉÛ#'N=1,Š ›Ð @ ñ"ÀªË×âÍg3urΘ5³÷µbnÁ{¿<¬µX½4Õ³^ïú÷~yÔïä;pb±e!Þ†¥‹IýÁ£Ä‚šõ$Ë© Ù‹€>guØfŸ;®lF=£l²;õœwM©ˆ¤°1´„l ÎGXÍÙŒ7 •)3® f3„¦eH#œ¹® ¿:‘u˜÷®=?ã@ò"Š[‚ÝqÙHÕ(‚U²0,ã ©ä­}¼ôÄõg„Ò4èVéέ¶ÚjçEëmç â­ç|®zH”¼”C¨\¶Vq&ð7Çñ$‡™*b4D>VÇ„@[½ü7^·>.=´šêˇŸÕÿ0ký¦2Çñ[Jò£ýh£õ}Y^ÚEAEÐ=ÊÚ‰Ò¬.H/ym¼ñÆÅç?ÿùâöÛoOáÅȪõCI0ö~«÷›þÑoe»‡A[ÓsNÁëHm«òÈ7EÆ  4ü=#ê ­Œ™yúYÛ ¿4oA6žU k@ž^ÖÕ¶jOµ­d¨Î—m­âê:^"ž7á°:Õ…¦3ÃR6 íͨ¤Y#IvX®M¹â£Öq.Ýoðq›“‰kyý‘³ÏMx& – UÊÉ£Znõó°f\±¤¦€P³-²©–WM<äï}ï{Éuž`ƦÙFÔ¡þöM0"<"H$´£œðî þ·\XDø=×IxáìøúMùƉ‘¹@þ-^a„ÓJãZ ”!_„ޱ“hv¡¥`<•¼ñ·þì¦*• BÄ06.µî­á-¡g“@•w¬œK<šŒ9aC­-‘~‡¿Sæ:F*S©Ld‰N€K@­N½Ö¿”0ê¬næhr5‚ændÍ©ÎÝsóOèG9 „ÒŽND@¼]ûª’7å¡òK¯€r 9·zë3‡Ðdê†ì/ô›vo݈w„ðVÆ«¨(帾Œ2Ãé^ †¦ò­ó`Êó£×û­l§qHÁP'ÊãÒò'?ùIRîyáQî©<¿M÷*K˜)u±ÖíU—:ïA¿gSPè`™QÃ<ÉC)†—E¶ÏAS‡€©ÄSˆ6¼þÈÕç^t;ï¼s±È‚X},æâÑ­'†åAÛÎk(ÁÝÐs@ äGÀ¢ÓFÊ"ÍšÃdõCX˜›úáÁGÌOd]¯g¯:õãW½ÎãÁ²®%š‹s“v³Z‡‡ùÞæ4hv# ÏYͶÙçÃŒ+–yƼwƒ5à(¡ zõ  !eˆƒÐÃÆÞf’‘‹Ðj6àö`ž/S)¬éÕ–8LgX©ýž[eÈ+€S­ P3ïZ Û©"ùSASÉ›°¶›à™”Ó\ÍÛ¢)Ñn3kZ‰¥›„ñ<…}—xÙú|ë­·NóËn‚Û³Î:+ÍB‘Oµ-«uò2Êc“ÒŠg #(kâÒâ|Çwì)ì†eÆL#^#Ö&úÝÆ ïgdœ´M 6àiŸ§~U¢ðž—%'uu³–²Ž*÷Y¢Ét#÷ (\íǓ‚ŽGL©´èVNýœõ:»·žî³u ¹bÝûðÒK/MqÊ>’ŒìQ[Oí1çÌ3ϬW#}ça¡\kÞ^ui,`€³)(,ÎÏ>ûì¤Y€ÿ¤Ku!³#hz `ô^þ¬JrS®>§$#hrHÌÂÊ£¤\<ÊòšþËæ’ë– :(@`|¢îsŸKɽƒY䉟Z%‹6qàËXðÕs¹>÷Ã0R²4ÄŶ^Ï^ué‡G¯2zÇÃâž@ƒE޵Cn²ù9üðÃsåMcÆÑçÃð`‰fÓ‡#ã _›JGP äE€€©´˜e-:ו}”ž‹üAqP Ð ‚Yk?kÁƒ:hde–d¿æÙ26A3a8áñÇ>ö±d±.7ÇTáïgœ‘šòp9øàƒÓ:˜ÑB•ù”ï–ê¹ÙðYŸ3¤ ÃåÕ¤­Ót‘ÚãUëDÜqÇ¥äÖ[n¹eò¦çUW™ê¿ÕÛeÌó’Cù‡?üa’빇âƒgƒq<Ì3 ,¬ËxõÝjoÎê6WQJÈ7Æ:]dŠ y ÜCè+a¬9oT"pUŸaH¢)g(e¬}›ÚeùåÿaxMç{¼(„LâåSUÔëMÞ„QýºQ¿[1î‚9×j䥠üb$ü™Ï|&yP4Dz¿Êÿê$œ¦°ø¼&(ìÙÌ#¼fš<„:•Sý]nŠ.{Užݨ Á¤=Õvº‡ã®NÊ ×•m,ÿû­$ÏšºàC)×&eSPx94YòÐzÁ Ú%.OÝ´3Ã4v<†©×l¸‡Fš ß˶ßÍ×8ú£‰¼½XXl6ÅAû£‰GN4˜âÕ@ ŒïtÖB¤ø\ºóŽZ nî÷Ýw_*Æœ$<5Шd­E žmñ¨Öq,Ûlð™ÜQ÷1"`$òˆ ShðNk_BWQ/x)•ñó˪RÈ}"—Ùn»í–ä‡å¹Aþ“ 9ÌæÏ&2§ò¦Vèj­a>&ãäEÐIðÎòQ”!MõŸ.¿Ùçð°b­/LžõHéו‰›®ëç7û òºN$ÿƒþ1ÆÊ0[åµ?þx]MÊ ×ÇeâèòÞ¦ÿÂo2ΖŒ2€¢B[?øÁm„lL;¬,€Å+uô ótÎ9çGqDb½ÿþû§Ï½â×ëÙë{•G¯kãüì@ Úçm+H½ãï(>ô¡¥g²-äl, jxxÝ~ûíé P±Nµ¶±,‰2‚«U¼ŸWYe•”·‚"¶“ ¨¼7þ@‘„YÖ¨ ô™†±÷LùŽñ‰0O3­ÇW_F4ŒS$áýÖ·¾•æ!‘8êÂ_Öàßüæ7“e·ð©ÕuŸó’LtJ4Ì0‡âÝØ3y.Íuõrë-uù eH“â÷¿ÿ}ZŸ_sÍ5IÑ_¿¿Ÿï„„¹žŸ›ˆ ·6k~í4§Ï6’3Dˆ$^¥Ûm·]òp©[òk3a9¯,ùü„ÆòN–䯱&"÷«¿—ôí¹çž›Œ:Ȩ…*•}`\Ô…ñåuÆÐº¢´P¾uê_׋ƾdÛäÝ×_}RnS\ k$b¬ *W†¶P–7a?ôÐCżyóRø_ë¾ú¼¥­êW槨?7”ñ‰¤u&-(@`<äzè¡ãa6"—E¸O±@O‰bP&­±Øì·—VJ’Ú0P¦³Ï"kÁ¶ÇRò•¡|XÒ±íDα´sØ Û@Ú¼S¢»0l¨Nüâ÷@`¶! ßâÚk¯š%dð\'Ê^áìÐa‡ÖÚ»n®ã<[ÚϰÕÜóýï?y)Ãò»ÒòX«Ÿ‚‚p˜ƒaK•¹(‡‚âØcMÂlk`–ð<­3ýç)hNó;FUXª<ùÚ(î¿ÿþdÔC¸ËhÆä™pG}tzn{µ«Ûùl Z“…½Æ³D:Ì÷Ü4¹ëÁ/Áè{ì‘„§d.uÚ~ûí“••=«m‚SQ'¬ÛB)Y¯SPfÞŠÙ_µÚg¸*a³¼2_úÒ—R~#Le-®\²#‚ÚaÃ*ouÖI!©ðP&+vÂwó/e¶òÖVI”Õ6O99±íSô¡è Öõ¼=ýNqe/ÓäÕ0(&úŽPœw¹FÆaüÙgŸúÀºÇ°zËÞlýõ×/.½ôÒâÈ#L†ùƱpõÕW'EÅQGUì¹çžIÁÔÍ8DÝ­;y­RŒ(ǸèR©ß¶ÚGrÈ!)_-±¨+Æ—õ§z^~ù婽žN¡µôƒ5¤Æ¢ç‘犽¯w»\‰4ŒÑõU“bC^&¹s?ýéO'ŵP¾öŠ”óxqØ«R>ñø–²)(² „º…=¥„ÐÈà̽xWî8xà3W‰&ÑÀƒs?4Žþhâa 49hCëc±ŸºW¯iâQ=Ÿë³˜§—ZP Àø LÿÜç>—B¥x[ôåH>má[®}l¼,úF%Bu®ÆÈ†ŒEPnõ:ÓŽ²½þ[;ô¢m·Ý6 M]gÁíÈMU'žxbq 'äfåM3ª}ÞÖ¸²ÁãoLáÇÒ-Ù8²dxï½÷NkMN™J1ÂßgÏšßmž…Æp¯51²a·.f¹h³l›Ci:Q©øÌ"ž}öÙ "ëÐz¸ŒYÔÔ¾šâ=gŸŠ¼o‚æÖrBòð:îgî ´äUpÒI'%<%—çÈüD Lè*¡4‹l×Õ‰ÒßüwÇw$Ï¿M6Ù$ñ7§°:¬‰%!¦8øàƒSYd?”%¯”%æF õ1WZ“ã»ï¾û¦õçwÞ™Ê/­ÁËûËÿeûíÌ·U"ß,£ÈPFP¨œþùi®uN¸8‚eû Ê F´ê`^® ÍÕ]xÆœë`Þ”(žãn}ÊG}£ÞuêuÞõ®¡,0NÎySh£ò„\âí¢/y®S\ÔÛ_çÙë;œï­é¡ºx?X)_ßo¹å–Jò7LüŸ·@°n}¤ÃôqgîjÕáw aáiêBaâh“ÆÁ£ÍúOç²aëÁaÝèë‡ÆÑM<ŒÁã?>U‘7B},öS÷ê5M<ªçs}¦i´Íáæ–«NQN s®×,¹Jã=‡‚Âb-÷Ú‡õX9DZSÏÜ–÷‹½Ðp#„Õ<`ÒMQR–Óï ž+BaŠ[yOáE9Dž×‰œ×f *÷[+é›2”nYO^ŒP¬·ªc«©\ÞHûûQ4QÖ©÷nÄ3ãœáöŒaÏ“ºZ“b©¬k§2ÔŸ<ךÒ^—ÜÑs ­ås`]I&I‘ÔM.i>Xn¹åÒXç­b¼xž”eíí9£ú £ÔΦ Ðù:mTò¢‘ŒÉƒí¥å%࡚¼¤i½d„9¹û#gŸ{ix(êc1'N=1,/pP Àx°f1Å*‹0¾ÉË“å•u‰E¯ù¥×BrÐVôËÃZË⯩ž½xöË£W9ÝÎãÁ+…EBP yýÁË¢Xÿ5m(»Õ3ÎÍ,ô9!G›}>ì¸2=Ã<“zÁûˆõ(‹Oä½Ãš`ƒ5 AA/E‹<‚–r,}^Bx›HóÈGÑ©â÷¹Œ€XßeH#–¥s]A! JÐÜF`Ø9Ž€–àÒ1™ÿ„a’ ¦.Ó©–CVH] KÍ”ñu psùÓÑDxtãÓOû ˆ €Ë¥M|Έ€87Ù¯ô³gé…A¯óÕz“Çi§cïû7ëÇ ä^F_ŽNDaÔÒˆüZ¾ʘµÖZ«QÑSçaìöK”1”{ŽaÈ:Òщ<¯ÝÆoõ>JCG™¯©zާÑ(‘a²)(<ø»ï¾{µnC}öb‘Xä /LÊD̶ ©A€ðÜÆš„öµþÈÙç„M^0V)'j¹ÕÏÃò°a|üñÇÓdêE@ 0鸙{ÿì ¼UãúÇßë^c×X†Š¤Q%M”’26' •2uÑq‰‹º÷š‡J—¿¹Bº2&E2•P$"„’R)CЍd8ÿý}XÇjŸ½ÏÙÃZûìá÷~>ûœ½×^ë¾ï»Ö^ë¹ùŽus‹5 n±¸c4A,Oâ0Yi+^N–•×!Vßi#ÖqÉl£ ¡XŸâ‚ÌMz¼ÂdêõïKý„ºÂR Ë8\뉧ª’¿˜se†9穬+qg§rNÆ›1b8cŠGúx2ãž°´4«6}\/ðê࡚ã C…GŠVbsŽ¢DTØ’Â<,?)IvÿþýݱÇk ÛñR –@` Ù±Âÿ åÄêÂ>h¼äY2ÑFýÍ¥ºëtÙe—™G Éö)™˜XmÐ7ÏÛ#ÖZL¤ïþ}bµôÚ¥=Â` "" "Y÷ÜsOs%G(ÈÃPÅ E]Ô‹f5ÔWý « ÿøSiƒÐ4¸6ãqIá² 9$Ö­[g»á­Iâá ]£ýmxm•Õ/}ŸÛüsÖº‚J9ÎÇ ®ÔÉ5‰ÏOK—.µD¡‡v˜Ýãò}²…d£„ÂàEáâ…ÊH¶.í/ùNà©§ž*i„÷$–±…\Ž9æ˜B¾Æ." "Ai pµ:ãŒ3JtÁáÇÛv,Å/¿üò@oâ©8mØ ðÂsâR¢ó:ÄщùˆÕýAØ„FµcÇŽñº—ðöXmùêuK6"¢üeŠGEÿE@D |Xû2Ä®Á(¶ñ”¢ T$)/ÄóÎ;Ïò8¥S7¡pg>øàƒÍí=Œ6¢û—JÜ7 ´]¿~½Åæ/+ÌÓŒ3ܤI“¬iÜù»uë¸G¡¿ /¹vôXõ9¿øç<¬u1„—^(Š ¢œðbiãå5wî\ g@î q’-ܿϞ=Û®s˵.Cždû¡ýE pîq®Q ´jÕÊê$ŒRmXå¾?©´Aâñ§Ÿ~ÚjAÐZ–‚‚ßnÞ¸©Xˆûºó­¿ Œx©ä7ÿœ‡µ®HΈó‘W×f…ó†sýÅ_tü±ûâ‹/Ü=÷ÜãP%mqÍâåE'òJ`é¼yófó.ÿè£ì\œ:uª#‡ …jt)Vlƒþˆ€lA@ñî·Àá¦M›VòŠçì •±[¶¤O" " …N 0‚lnž£-ìyØúh³Z¾í¶Ûù40¼;v¬…C#=×*ÎO((xäâ1Á¾ ,psæÌ±Ï^§8'Û´icuóL¦""P’çÆ Œ+ÃøM*ÙjönÁ€ã?ŠÂ;ý‰@  ÂÓD+(xHÅ0Ì’‰6Âì6ׂôx¨I¤db>bµAò¿o¼Ñºˆ7BôZL¤ïþ}bµáÿ>¨÷XÅ^ýõ°‚ê“êB €Bû¾ûî+ê’%KQP†%è{, ½ß8r-¡H ºb¿¿Ie(%C…µeË–ÑU–øÜºukÇ+ÌâoÁ“aÒÎŽºýsVP¼õÖ[V=J ‚Q¼%¸&‘´÷‡~°êQB°~“]ÃY5jäúôécçf}U]"OxàS<2¦ /¼°à“d÷ïßßy‰²åíŸO+]cì#˜‚Av ×pQÆ=™H,÷±öÁ…Y¥|xBú8ÀÕ«WÏya0‚ìMsÏÛ#È6â=Õ6°ÀëÑ£G¼jµ]D@D $íHHK¨=î7b…hùõ×_‹Ã¦¦’ý‚¶"L´ îµPÄêgYˆm£¬zJûž6°>å÷𨣎2+ïÒöO廟þÙæƒÿð`.µ£’¿˜kÂr…9ç©®+žQ8S9'Ëš±&Mš˜"’ó饗^r_ýµãK¦pnfåÄYgå:uêda©’©CûŠ@!@!HŽ'ÊÉ'Ÿ\ð O9QHk@c()(p>ãŒ3ÒñSçÎëÞ~ûm{àlذ¡;ì°ÃÒ®W¤Fá9næï½÷ž{ðÁ]óäœ#l²´cÇŽ[ 8È6¶¨Ø÷!Õ6x(^¼x±=0z.´¾jõVD@D $x\pÁî“O>1# ~㢠–Ë„JùàƒÌÓ ¡!1܃,‰´ ¾~ýúKí²ò:Äê["mÄ:.™m´Aœ|”0Ûo¿ýWM<~ê&ä†1xxÖ¬Y3™njß#Àœ?û쳡Îy*ëŠÐJäŠà>ÙKª$ZpÜÓV©RÅ’\Ã`éÒ¥–ïc.± Æ:Ü£˜¨S§Žõ¯[·n–w"Œ\€±ú m"«ð^ÚgŸ}¬ûœG…^øMçzC!ÜSÐ…ÎWãøƒ@  ŠþQsŠï°Ðâ‰'ܨQ£ÌJ:¥ Hf‡‘[䦛nr¯½öšÅ c>‚šsböò ÆCØi§¶Åèƒjc‹J£>¤Úîú—\r‰ Z¼øâQU룈€ˆ@üqý-­üv„ nܸqöpN¾„ ‰´{ذaf M’ÜdK"m$[gôþ´Â‹ðÂ;%脚Ôë­·º3f¸Æ)(¢g"¿>gbÎSi£]»v¶¾ñNð½‡A¾víÚî²Ë.s={ö´ÐN(è8Çð*Á8†Š„©+T¨`÷”(O0Øáü@i¡""P6 qĶ£B9û-ÿ裌a%ëÖ­[6Dí!" " )LAA‚b’²æ wdn°¹Ñ–Û~ ³à!((Fm5V"¬ùbÎIjÝ?'!N¬µDe¡M¥ B‹<þøãN7ÁeÑÕ÷" ",ÂIbˆ‚™P-üŽD‡jA°ç¿¶£ º$ÒùŠ=ôPkE@t?ËêS"m”UGYßÓ‚R¸’€OŠ ‹?Ìá¶°2WÉoÌ9çÏaÍy*ë +k”( R9'“™5Ö9¡Vy{î¹î /"Œ\ð\‚O¥J•LQ‚¸¬œ“¡«}Eà]ºtùãƒÞ¹iÓ¦‡¼â9[ - °ö” ûÞ{ïM;a#B€ ¸®]»ÚÍ5ïUÊ—„6•+W¶¹ º7AÍ9J2M¼Þxã-ÖbPm”6öTÛࡲzD©RµjÕÒª×w" " @ˆ~Í5׸U«VÙ5¸yóæ.ÚÅa¸Ï!¤ ÖÌA—DÚ@yçwZÓ5jÔ(Ñϲú”HeÕQÖ÷´W ù«$cØt!l Š6üv†i¹tßU_j˜sr¡…9穬+UOœ8Ñuâ‰'º^½z¥6À¨£Pð­_¿ÞªpÎùä?—P¦ „à¥"",뜃αBóÄo,¿µ)> ƒþˆ€ˆ€„D PáipýK§óàÔSOµW:õèØ``±… ¡M›6mn¯A— æáÑ 7Ü`ÝÃÁ¿ƒj£´±§ÚÜ×_½Å6/­~}'" ",Ï?ÿÜÂxµ’‹"ZAgèÙgŸm/o¿ ÿ'ÒÆòåË‹ãˆKÝϲú”HeÕQÖ÷´ÁýÂÒHœüfÍš¹–-[–uHÒß“‡ãÊ+¯Lú8»21ç©´±páBó€…ì`Îõ©S§º?þØ<»Ž;î8wøá‡V¿*ˆO`üøñvî±Ç!C >I6^^¢lyûÇ_7úFD@D })(dó`ª’_°ÚºôÒKMÐ@¬çl/ž·G.­E=zôÈv´êŸˆ€ä,#É“@ˆÞ'6)Ó@¸×Â’:›ûI¨úI>(/$U¦9©=ȼ†8ƒ<'QœNž<Ù½øâ‹n§v2ï.)(25£j§Ð pîÍœ9Ó0œtÒI¯ ð”…¾.4~ð ¦ àúôÓO/Ñc\$IæFÁÝ¿iÓ¦»Jf¢+ ÏI°G‰•×!†LÌG¬6è &<=¼>Çê_¢Ûbµ†›ïÏ?ÿlIE½PO‰öOû‰€ˆ€¤G Zµjî‚ .pxN¿½aÆéUøûÑß~û­›?¾}"D"ái¸J§Z+otyä‘.Œ6¢û—JÜ7 ´%D ±ùý¡i¢ëç3É~—F<.(„:$”¿‡A^[AÖ¯º²€ÎÃZWŒºN:Ú©C‡ÙA=HšaP8z¿„8Âs€ß`ÂóÂ3b!m'Œ1F‹{ï½·Â<%½¢t€ˆ€ˆ@Š’,‘å¢Hå%^‘î˜5ù÷< EÜ–cî—ÎÆÒÚðçïw¼þ¦Ó|<6b YtñÅÛëÚk¯Mhˆ~晜óH|‹}Q$JBý,k§ Çá¯Ï¿#œ¢ˆEQ$\GY]Ò÷"—ÀŒ3J\—ýë,&î±úB%oi}mIÐÏ©E‹E‘[`¤èÑG-Z´h‘FÑÝJ¥1cÆEBÒýío+š>}zt•%>>¼øÚ5xðà¢HÒßû¤»Á߆ÿºý~ذaé6¥ãÓ ožR™]a®«ž={-X° Q—<4b½]ñ˜°ó"bV4bĈ’;eñæ+úÜʥϬ•Â%ðä“OEÂMEòÒØ:Ž„8*úôÓO ÈØ±c‹!°ž i{­ZµŠ¸Ö}øá‡…»04rÐ f¢F‚âD-ì#?ê*9B ´¼Ù6¬T#7‹f}™KkqÆ Ã8rÛmHÕÈkXAb¹qãF³úçw$ÈP-AÂ#_‘2‰0JÙZH<þôÓO[÷Ÿ…·‡Šä+_ýÕ­Y³ÆqNfëµ#_Ùk\".]ºØùQÐÛ¹F¹VçâÅ‹ÍÛРA®nݺ¹Ö}õWD@D G¦ @±\ß"11 i±4¸L¦â ×L´«ÝBÙ–l^‡LÌG¬6P’!hâõÆo”X‹ÉÎW¬6’­#‘ý½ÐN„ PÈ„é×\s‹x8Xx!<'›|:VoQtx÷>„w"¦2~; Áÿ²Â;Ñ¿}+Â;‘¿"èâocåÊ•–*ùMÀ?ça­+Λ7ÏE<ŒÝi§f¡žò›ªF'…A€ðM‡rˆ½!'¼¥·3~~ÛUD@D@D ,*(î¸ãŽBa”“&M²þóІuQ&Úk²½^æ ABr;$R21±Ú@àpà 7XñF:th"Ý»O¬6âîœÆXÅ^wÝuޏÝ*" " ™#@2ÚqãÆ7H.Š (%¼{O`_ÜHŠo"!2‹ã"!µÜ€o#ºk©Œ¥¹<š5kæZ¶l]e‰Ï½{÷v:u²í*Tp¼‚.þ6n¾ùfwÓM7Ý„êË2þ9k]1dr]ðJd­§‚(âKïð´ Òk ÃòÄ¡8MeL:F²‰¡c%‡ÖölŸ9õOD@D — ¦ @½ûî»—`Áv¬ Â,™h#ÌþgsÝXJ\zé¥&hhܸqB]ÍÄ|Äk#YoÒ¯ÒŽIå;Ç|*‡ê4l»í¶Ž0D?üðƒã}PF(%¸÷áw ý « ?ÎTÚ@J?»uëV’Ê_gô{Æ“ˆ§EôqÉ|ö·v[ÉôKû†GÀ?çáµâLÐÏùÔµ#º¯?ýô“›3gN èUªT±sÏÈ)("IÜÜé§Ÿžö˜ˆåJˆrlµÕV.’ Êq#­R>žG’]ºuëÖ™{åÊ•Ÿ çž;vÜXmlQ±ïCªmüüóÏ×Ó õä«RoE@D@B$P­Z5wþùç»%K–¸J•*™åts¹/AðÎuc <ì‚,‰´Aˆ‰zõêYh§Tò:$ÒFºc¢ ¬½7mÚdVå_~ùeà¬P&1ßÿ½ ‡Q0)ìDº3—ÝÇ3çx7…9穬«]vÙŵjÕÊò¬tèÐ!ˆœKS¦L±WP º†ëAU=" " " " éTAñ·¿ý-ÝþØƒí„ ܃>hž'œp‚»à‚ Ò®W¤F€Ü"7Þx£[°`#Ægœø| ÌbÎÕ®]ÛuïÞÝbûGTþ:£ß§ÚÆÚµk-B¯Ûo¿=ºZ}‰e…üúë¯Ý=÷Üã&OžlF§œrŠ…W ²K‰´0qذaoÆZµj%Ý|"m$]iÔ´ ™7£Fr„§éß¿Ô^é}üðÃ!Eß|óMKÖIH®öíÛ§W©ŽÎjÌ9¡0ÜóTÖU»víÜþûïï5jŠÇTVOŠ:'" " " " LAA‚b¼b…yJ¦¿ÔCÃùóç›Ë?–I*åGÅÈ‘#­¸Ë37A— æœdžBâD¯Å Ú(mì©¶bã±ÇsäÍPÈüѬñ7nÜhFüŽD‡jÙ¼y³#™6÷%„múâ‹/ï`"m¯¨uëÖÖ6ÞÑý,«S‰´QVe}OkÖ¬1¦x9,]º´¬C’þ+úÅ‹Û|pð·ß~›t: ·dbÎSicŸ}ö±œ)›Ê9™è,àQNÓ JÐõÕ/Õ#" " " "P¸SP È3fŒ»ä’KÒ¢ÉM3JŽºuëÚMº ´:£ƒ‹ ZáHóÔœ£ œÄôéÓÝܹs·X‹AµQ $Æ›TÛðB;U­Z5F­Ú$" "×^{­ Ô aØ¢E wÖYgmÑ×hÜ—ð˜¬b`‹Êâ|H¤+V¸»îºËj¨Q£F‰~Æ©ºxs"mïœâÚ@ÉCxHð’ˆ7èB†™ ”S"hÂÙWsNH¢0ç<•uõüóÏ»‡~Ø€õêÕËñ ºpNá¼ß~ûV5^„ÐUl!¨‚‚ð4é*(x@ DOÓ¦M-ÖóÞ{ï-¬ ²$ºä¡ˆ‡ÂJtíÚ5pAÍ9J²ë¯¿Þú‡7‚-ÕFiƒOµ ?„.@ £"" "9„.;vlqƒ„'ŠVP 8ùä“]Û¶m-‘vÞn‰´±|ùòâß8úÝÏâAÄy“HqMx3mpÀæ9Á=C³fÍ>6Ñ o5hÐ ³X'ÿYÍš5=Tûå(æ¼OŸ>¡Îy*ëjáÂ…æ Ö† †B—{Ã3Ï<3ððª¡tV•Š€ˆ€ˆ€ˆ€ˆ@ŠSP ȺK!’@òR)$ž¼ì²ËÜAd Š0zäœãõfôZ ²x Rmƒ‡Ïã?>^µÚ." "m·ÝÖ‘d™¹¼GÀ]P>#| KI{‰¶Á½±úÝïèω¶}\2ŸiÃãxÚi§¹v‘ýAÆÞ¼yó «U}YL ùá­@IDATsžj¬yŽå¥"" " " " "ÀX±ñ0]»CX Ö„I@dÉDAö7—êBxÞ©S'ërt^‡xãÈÄ|Äjƒþ iÓ¦;î¸ãâu/áí±ÚzíÒ™ŸþÙâiS7á*TD@D@2C ZµjnðàÁnÉ’%¦ØÆú?ˆâå¶ ®m¶ÙÆí±Çv”NÝ„ZÄxãàƒv:tpa´Ý¿TÚ@`ËkýúõŽØüe…`"‡Äºuë¬i vÙeGÈÄ ‹¿ ¯­ ëW]ÙGÀ?ça­+ÎI<…:wîlçdöQPD@D@D@D@D 7¦)@AqöÙg—5‚Ƿ턲¹üòË·2ÊD%V ›4jÔ¨âùó‡MЇ ó« üÄé%DX,eY¼þÆÛ«0,äÖ®]ë†jÂ1¤©ˆ€ˆ€d†@•*UÜ¥—^xcK#É¡ ÝG!_ÄyççðHL§ À6l˜ D GóÑGÞFtÿRŒ(ž~úiST L)­Ì˜1ÃMš4Év9òÈ#]·nÝyèoƒdç*ùOÀ?ça­+”i-[¶4/Ø:uêä?TPD@D@D@D@B"˜‚kóXöXÏ7κOà!C†® ÈD!ñÏújKËë¯ó™˜Xm $ëß¿¿y!ÄZ‹ñúo{¬6ÂPPlذÁb‡×<ÞØ´]D@DÀ{!lܸфéXZq_½zuñ½‰·‰!Ÿ®‚#Ö­[Û´}óÍ7–ØÛ»¿ ªè5‘Ê8H<Žr‚Bø¬²( ¼qÀÈ s2ùÛˆ£>ç'ÿœ‡µ®8?Pâ­ZµÊ’xqíÈÏÙШD@D@D@D@D t)(d3f‹ÄÄ4í…uâ=!‚vÛÏT´S¨%^^‡x<ÊkÎQ’}ùå—núôénîܹ%Öb¼þÆÛž‰qжÚ žŠˆ€ˆ@æ L¿öÚkMØ_¹re‡ ?ÙäÓ±zKX'BZR*V¬Ƚá2ïºë.«¯ rb݆Uîû“Ê8¶ÞzkSÆplYáhŠ}¼q`hÀ=GÐÅ߯¼Tò›€ÎÃZWœ7ož%¯Ç@¦W¯^ù U£ €r“qÜ` DAÂÙ»÷á}×÷åË—ÿƵmÛÖÝÿý·Q â÷7©ŒƒßN”'Íš5s‡rHt•%>£òXq¯0(èâoã…^pÏ?ÿ|ÐM¨¾,#àŸó°ÖCFhÉ‹ö‚*x|pýôÓOvíKPdU”MàüóÏw3gδÁ\p#WÕĉÝèÑ£ÝÊ•+݉'žèþþ÷¿»½÷Þ»`¶ “]ÈTD@D@D ,)(øÁ"îptá&›øúa–L´fÿ³¹níAdq¯é«wL"û¦ºO¬6PP$ëíQZû±Ú(mÿT¿CpÕ³gÏT×q" " )@N¢~øÁãA…hA ƽ÷ZzÐϰÚð£L¥ ÂOÑOrIx!©üuF¿gŸDö‹>.™Ïþ6Hü-E2ôrs_ÿœ‡9ÂchÔµƒ¾¢œÀàæ×_µûZžwêÔÉmÞ¼Ù,ÄÓô|9ç›ðô †µ¿Ù†¿^ÿûTÛøùçŸÝâÅ‹‹C=ùëÔ{ð €ÇzÉ’%fd…`tAHÈ} ¿ƒ„©ä¾d»í¶‹Þ-­Ï‰´A›õêÕ3Ʋò:ÄêL"mÄ:.™m´r‚ך5k,LÊþ ¿™Ìÿi.„•RÉ_Ì5a¹ÂœóTÖI²[µjåHÂ}ÄG6\gÂð$ ¬ƒªHò˜F âQHLž<¹ÄH?þøcÇ+ºäóöW^yÅ5mÚÔî?‚¾ÿ‰æ¨Ï" " …K PÅÙgŸ6IܙɀuœXvØai׫ R#@n‘‘#GÚMø¾}û>AÍ9fµk×6—ÜheYPm”F1Õ6ðüÀu¤ÿû¿ÿ+­ }'" " *UªØõ·´*ñ®˜3gŽûàƒ,ÜJ“&M^…A–DÚ tá°aÃÌ›±V­ZI7ŸHIWumpœ×Ã?l÷q]ºt‰Ú+½_|ñ…Í99øÝ$´NÍš5Ó«TGg5æüÙgŸuaÎy*ëŠPkuëÖµsÒË£’Õ Õ92 ôë×Ï<Ÿ|òIS´—y@ì€\yÀ5×\ãößÿ±†(" "PSPàùÕW_Å ó”ÌÀx¨}â‰'Š]'¸@<™þú¾((n¸áÀ++ž2A+Œ‚šsú×?’¤°zõê%ÖbPm”¶RmcÆ îÑGµDl¥Õ¯ïD@D@‚%@¸ŸÕ«W›E>VäOˆÕBÈ¢ &¸qãÆY2g<.‚VP$ÒýòB!±t?Ë"“HeÕQÖ÷´ñÚk¯¹Ù³gÛ  xÞzë­Ž76¥eÍLnŸ‰9O¥ <°¸÷Ä»#•s2·gE½ü$бcG{Ž|ñÅ¥ ø}ŠÉÏÅ‹û)(òsÝkT" " SP È3fLÚ‰‰‚ç‚ܛ嶟 ËÄY \B)„5AÌ9¡%¾üòK7}útó‰N’DeÍF*màùREIË¢«ïE@D X$žÆ"%EåÊ•Íÿ¬³ÎÚ¢ÂMú¯íaăO¤ ¬Çïºë.ë[5’NæH[ <…´Axîà· ‹?Ìá¶hK%¿ 0ç¬'ž šóTÖ ×ñ¢ôêÕËp ù=¼©QHØ7•ß ˆ%׎Â;iEˆ€ˆ€„I PÅí·ßž¶‚‚‡Ù ¸®]»Ú ïUÊþ„• ÷ɱ˜ æ%I)ôÙ¯ ªÒf"Õ6¸á»öÚk-tHiõë;` ¬\¹Ò;¶¸R,£ä]"¬¿1Äœ'”`Ð%‘6P¦x¿q„–‰îgY}J¤²ê(ë{Úà~×Ê=±Á=ôP– ÜWh²f%÷¿gÎÉÃýRXsžÊº"ì°”XùkrŸ¼F …GàþûïwS§N-NŠ]xJŽ˜üݺu³ëoÉoµED@D@‚!˜‚A6±€Ó-$e>õÔSí•n]:>}$·üç?ÿiI±¥F rαÞÄÊ#z-ÙF<©¶Áq={öŒW­¶‹€ˆ€„DOMb’;÷±Â&ñ{BŽ­ òlÅF¢m`å+ U¼zýÛmÃL²ïiƒð«V­rC‡uíÚµK¶Š2÷¯_¿¾»òÊ+ËÜO;äLÌyªm ”CqëÚ‘?3 ‘ˆ@á@91sæÌÂp#Åk³Gv¿”ÀîÚED@D@R"˜‚‚æèÄÄ)õHe„ç;w¶>‘c$ìÁ!`jÓ¦#~h®\ˆ‰}ì…zÊ•~«Ÿ" "ëöÙg‹©¼dɇ5VÿÙZ­€•üGyd¶vÓ!°åµ~ýz‹ÍÑ€Šä#<ªZµjeçãG‘CÔ˜D à`´ÀýÀºuë96Uœý–öÙg¦ P˜'­°¦ ÀÒ>–u! (çÌ™cý'n,.‚‘ƒ,™h#ÈþæR]n¹åë2bþ°IñÆ‘‰ùˆÕ~Bo`ᄲ,VA¯]®]»Ö]z饿õñÿ÷ñ°j»ˆ€ˆ@ÀÈýÃõ7èòí·ßºùóç[µpþ…{ t ¡ ‡ f‰¡kÕªåÂh#º©´^µÏ<óŒ)*:tè]ퟗ-[æ–.]jÛ˜Bøð{dñ·áµdýª+ûøç<¬uÅZň‡°´¼WÈ}ýúõs*Tp“'OV’ìß§óí·ßv#GŽ´œ]J’ûk\#l%Ø ±,ìI<é¹øó€€²‚\A–L´ds©.„×]wu9:¯C¼qdb>bµ¨ÿþök-Æëo¼í±ÚzíÒö† ,†1|UD@D@2GE4×úM›6YÞ«TÃ'E÷å„wïÓ¢E 7iÒ¤´s%B¦uëÖÖÔ7ß|ã,XxAŒ+KBdPÈEQ–‚bܸqnøðá¶ÿàÁƒí=AAÖ«º²—€ÎÃZWœçï¾û®) wÚi'…yÊÞå ž‰@ÂðÂç9ò¥—^’‚âwjäçâŵT Š„—’vH’ÀVIîww,íÇŒ÷{}‘»Èë€Ð«Èl.EEEvCùÜsÏåÔZÄRkXYßeóêRßD@ò‘‰§ÿõ¯¹!C†¸«®ºª8ám6Ž•„Þx4òòófc?·Þzk‡°–{…wÊÆRŸ‚$ðÖ[oYòú^x!ÈjU—ˆ@9øâ‹/L1A^•ßð[Ž‘žÂ;iEˆ€ˆ€„I 0 ,ío¿ýö!€i€õ KºtCÄ‚‘‰6bµ[ÛÓ@b,b^·mÛ6¡!gb>bµ‘Š·GiŠÕFiû§úɯ½öZG¾Ì@è?vìØâ-ZäÎ:ë¬âÏ©¾A©ïÝûÞ ¡}ºÏÏ£‘ßã#FÞFtSÇ˃ž‡rHt•%>ã]ë±BQÏ}GÐÅßs¾bÅŠ ›P}YFÀ?ça­+†LÈ0^ÞÎ2 ꎈ@’î¿ÿ~ó$…Êoš4iâºwï.c:-P ¦  —„Jxå•WìÇ -;–xV\pÁöÀY³fMK:ÅvbÃò€Èƒ(Þþ©l瘋.ºÈê!L–{¸!R?¡bú:sæL‹sŒ¾råÊÖ_e®ZµJÛç@ø¡SN9Å„ •*U*1¿±æ‹07ß|³ñGÈ¿qãF›‚ ç=Öºò‚b­ÅX}-­O±Ú(mÿ²ê·aÄýõÕWM!T(ëKÎ?,m ±Âù‡[µ¶'ÏÁ‹wëzçß&ÎZoéœ_þµäϺúàƒrîüýî»ï,é#×{®ï(º EÉ}É^{íe×%®í\¿ÉA”èö5kÖ¸¡C‡ÚþÕªU³c?ú裤ëñ· o<¹o¢Ÿßÿ½»ãŽ;¬Ÿ¿þú«Ãêó½÷ÞKªŸþúc·J•*žŠùýüóÏ-œ °Kã@ø©Ÿ~úÉzþ“kû¶ <ùOî2¶÷îÝÛBW±}óæÍnñâÅn¿ýö‹»¼zJÛ~Ì1Ç8¢Ó.Þ'ñЯBÚÎy£"¹J€…ÈTþ € ‡$WÐDn¨“*‘‡‡¢Hgâ¾"œE‘$JVgäµèüóÏ·}Ëk{i}å»ÈCEѽ÷Þký¿f̘auD¯µˆ‘ANž¿£F*ºæškŠzõêUÔ A°Xñª°óåÓO?-êß¿VlŸ={vQDp_køgk?¹Œ(Ý‹"Êgë'מH,oãÉÿHnŽrݽv£?}ôÑE°¦L›6­(âbýÕöÌpˆž>gÛòúÃZoÓ¦MÑå—_^tõÕW¯•ˆr¤x E’ÅìöXsɶˆR§(¢-Š(Š"Ï¢ˆò×αòÚÝÏHN;ÿõ§0 p?P±bÅ¢ˆ1€­ËèõQˆŸy>›5kVQÄè°0…F-" "zPD~°UD Ü`L8‰7ß|³ÜúJÃX¦ây¤"" "Y„‰BŽÅšÖM6­!oíòŸ…5â­•† ¯!Â=ÚvΛX%+çXóæÍíZÆ=ßo¼a¡` ˜éí .”b)ÖDø¶Ž;Z¸ÊˆÇŸ¿¯B/òŠq4}N…ñr±æŒWP0FÂóÄûZÛE !ñÖY.­/o ¹Ôç„&G;%DO™H—˜û6,îw1ÐÆ@ Ä›ÍK ˜C¯Œó‹¹Œ.lg.³¥äJ?³…W¡ôƒ|NãÇw‘Yí­˜ÉùÀè%1ù›Z´h‘ɦՖˆ€ˆ@̃¢€˜i¨" " " " " " " yDàp$Ê^·n]*½¡àÖ½{÷˜FªéÕ¬£E@D@DàRPüÁBïD@D@D@D@D@D@D@ À”)Sž–* dw=\$©ýõND@D@& EÀ@Uˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ@n@_±bEó øå—_r«ó!õöûï¿wË—/7¹¹T —À?üà¾ùæÇÊÎ;ïlùÜÈë©"" éЕ$]‚:^D@D@D@D@D@D@D § ôíÛ×í°Ãî©§žR’ìßgrþüùnĈîšk®Q’ìœ^Ýéu~õêÕ–Ï#rkþú믮sçÎîÄOt•*UJ¯r-" )(~üñǬt‡äB«dkcõµ<¶yÜÄ)8úÓèÅ8šˆ>§B€‡‡ÒÊ·ß~›•×èÒú¬ï²@¼u–KëËC.õ9ûVBîöhéÒ¥q;Ï·B{ÄÅúñæFó:ú@`¾bæ7›Î¯xýŒÕwm+:ur_ýµ b׬YS8/e¤‹/v¼,E)œòù«Í›7»ûî»Ï=Úá-Q­Z5·ãŽ;ºm·ÝÖmµÕVY;t<=8IôŽ·ÇŸÿüç¬í«:&"àÜŸŠ"%ÜÌU¯^=™C´¯ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€d5áÇ»aÆeuÕ¹ð|ñÅnüøñnÔ¨QnÅŠá5”C5#ÜÝe—]Ü£>êZ´h‘C=WWƒ"€‚ªOŸ>nÉ’%îŸÿü§;á„Ü^{í•ÕÊ ÆŽR|âĉ®mÛ¶îØcu;í´SPHTˆ@ó ¡oªRD@D@D@D@D@D@D@B'ðÀ¸©S§ZŠÐË‘š4iâºwï.#Õ™¯0º‰‚ÏãF¹£Ž:ÊU©R%Œf¯söìÙî‰'ž0Ÿ~ú)ðúU¡ˆ@°¤ –§jÈ1S¦LɪPdÙ€¯fÍš®G–$;ú£>dž‰± óT£F W¡B…Ìw@-Š€ì Wø5Hò&°çž{ºŠ+*V½o"¾ÿþ{·|ùr·iÓ&ßV½-$D…çEþ‰lÎ9QHs¢±Š@>‚"gUcH˜@ß¾}]çÎ-çBÂåùŽóçÏw#GŽt$ºW)¿üò‹Û°aƒ#Ñô?þh Â$ñÙ{±O¼ò믿Ú~«W¯vŸ}ö™%Ÿ÷ê‰wL¬íxnàÁ’ìóÏ?wß}÷£îx…>mܸÑÚ¦¿ìK^ŸùÿóÏ?Ç;ÜÆÉ>䣡ß_}õ•)çIÝ‹cýýƒáªU«Œe"uÄ혾 tˆ§m·ÝÖ’Ìä.†sæÌqôÿCɵîg¼¿âr~4ù‘Z¹É«\¹²ÃmVE‚"@|P$vÞyg׸qã ªU="`òa}åôƒ#°lÙ2û=Þwß}_;8¬)פùH ˆ×•Â%ЩS'¤Î˜1íY³¦pAøFNþ^çwžÛÿý}ßèm>@@O‡uëÖ¹×_ÝáIÃ:˜rï¾û®ûðÃMÁPµjUW¯^=wÀX¨¨í¶Û®T|óQHð\»páB÷É'Ÿ˜,¯N:¶6lhÞNÑm£Ì˜5k–[»v­µÒ€~‹‚„ï”Ö­[› A±A¿ßyçûr‚|ô»Aƒ®víÚ®´~¿úê«…L‡Ü{ìa do¾ù¦;ùä“Ý(ï,?p½([ž‘Q_Æú¸×^{9~°s­ðÀS½zu—«ýÏ4oñ 8?î·ß~»û÷¿ÿíN:é$wà 7„טj.83gÎtíÚµ3åÄK/½äþô§? 8<þõ•‹÷ɇ1„7Ã…Wó¿þõ/7|øp׿û_x²kÄšìšõF BY¥YX„º»ì²K©‚ÙL3Áà9Úzë­KÇ3ф޷£ÜùÔ6ò qãÆ™bãÏÀO¸SöÞ{o{ù•(4žþyóºAX¿ÓN;¹í·ßÞÍ;×d M›65e×a‡7Ÿʉ>øÀÝsÏ=î©§ž²9F)‚g´iÓÌaàÀ&KAAòç?ÿ¹=† ÷ß¿ûøãí\FYòòË/» ï·ãŽ;º}öÙg‹ùc|<ÛŒ1ÂŒIÙ‡~£¬¸÷Þ{M±rî¹çÚs6ßÅ*ÈxxþF‰³~ýzwã7ºgžyÆžÇ;vì¨çòXдM|’VPøŽÕ[ xnþó«Òa" " " " " " ixàÜÔ©SÍj<ͪòæð&Mš¸nݺ™±g6 ù¢E‹Lø¼ß~û™e;‚äL„ÝŸ~ú©Y×ï°Ãf†¥¼_@V?2ÝvݺuÝ¥—^j!‹^|ñESV4oÞÜxâ‰n÷Ýw·aF{ 8B¡pÕUW9ø <Øúx! ¬˜4i’›0a‚„`‚Q],” ,¼öÚkîè£vÝ»ww(6¨oˆ1cƸ[o½ÕÎSÚ@Qâ—\r‰y|Lœ8Ñ=þøã®K—.îØc5e ûáAd¯xŠúM.¸à×¾}{«…%ׄ±cÇ÷‰ÒÖ^>ø y àeÒ²eKW¿~ýrQ¦ycÔÈRPäÂ,©" " " " " " " ¡˜2eŠyZ†Ö@VL8âã?Þ‘@¼¼ Vî£GvãÇ·-Z´°ÏÍš5ˈð—ÐA×^{­…<‹àŸÿü§;ãŒ3\¥J•BG“é¶ñXhÕª•ëË/¿4<Š€6mÚl¡ðœÖã"^a^yå•î˜cŽ)äÃÅõ^ýõ&ð¯U«–ãå/äx衇Œ1^(Iˆ„â<ö4ÈÚb šÍStæ…eÞ¼y¦ˆ  ”!+VôªÙâ?¹&ð’Øf›mL¹Â¾ž¢sÎ9ÇÖ?cBQA¨§ÒÂqA‰æyyx!±¶hTD@JتÄm€<(BG¬D@D@D@D@D@D aábfÂ">áN•óŽ„'Æk°Få]Þÿ} ñƒ5>a€ˆïÿöÛo›•&ú†5þ[o½eI£áB(¬ý3QʳíDÇ÷¿ÿýÏB3¡Ð:ôÐC‹•ÞñœW½zõ²\ „Bb>É}ê/„–b¬(€¿+/ž3'œp‚å” ·¹*Ò)(DÈsAøíƒ>¸X9á¯% òr¼÷Þ{qÏBâªsçήwïÞÅù:üu齈@lRPÄæ¢­"n¦x‘@ùBìŠE@D@D@D@D@D a}úô1Á"9T~#@’â‘#G:¬ãË»6ˆÐ:Þ34Bìï¾û.c9C°Î÷ò/ÀbÆ v(\ʳíDƇ`þ•W^1…ù%ây+àIѶm[Ëÿ@Ri’Yû ¹Q8àÅ@h(o®ýûðþ¸ã޳ïQ;&ÕB¿ÉQ×J•xÞxTð=ž(Æ¢ûíµ" BJÅcàí«ÿ" [Pˆ§-yè“d„ J¼ÜŒtBˆ€ˆ€ˆ€ˆ€ˆ€ˆ€¬ž‰9O²\þ«8·xñb{wÞy¥†µÉ«8À×$ Þ¼y³Y×·nݺ8·@Ø}`}`õOç *X>†Ê•+‡Ý¬Õ_žm'2À¯¿þÚi£T(+/aÃàGh%”<þ‚·ÎÆm­‘`;^¡ ”„q"17ù)Rñ|"_Ê+W®´¤ØñÚ$ ŠŒ+VXã퇷TD@’# Er¼´·B@!žÁ¨JD@D@D@D@D@D Xb£˜ÀªZå7Äàǣċñ_ž\þò—¿¸¡C‡:’5ˆ;ÕªUKI0Ê8È¿€‰šÉk@âæwÜ1•ª’>¦<ÛN¤³÷Q,à5@.‡Ò I¶YOœoѡÒ­rd°ð°I¶xÊBu5ªÔ:è+Š1ÆI®ŒXÔ dLi«Ú&¹J@ Š\9õ;§ ȃ"§§OÈ3$_&Á-Ù*¿hÒ¤‰ëÖ­Û‰ŠË“ –î={ö,·.£€Wy”òl»¬ñj ¡=Ї²<ðž`þx>øKPõøë,í=‰×é÷®»îjÉ·Ë ïvÈ!‡¸ªU«–ª€ÀËBED yRP$ÏLGˆ@Ú¤ H¡*À<õÔSnæÌ™Õ—އ¤Ç$Wxðã9^¥€(ªW¯^Â3'ºžÒ‹€C@ Š`8ª%ЧOG2â²Â¼äèðRêöüùóÝ-·Üâ–.]šÒñ:¨0à‰€°ŸIË–-‹«Ð"¤Ó;ï¼ã~øá‡w9Nü¥N:–×cÁ‚¥†Zûøã-‡E5J ·DÝ^þO;Þ{ú¢„$ß(âJóþøüóÏÝ›o¾iû)OGPÿE 8RPÇR5‰@Â<í;^*" " " " " " åKåDÛ¶m3–ø¸|G›Xë‹/v>ú¨ ƒ;B{"’UwêÔÉr9<þøã¦¤ðd~¬§—_~Ùáõ@²óè$ã­[·¶0K³gÏ6EžÑ'žxÂ<(Ž=öX·×^{EïbŸéò–ÒÂNá-ÕµkWS”°Î?ûì3«ß(.~øa7`ÀG(8<‹TD@‚% E°}º{ì±Ç,Y5û’ƒ"Va;ëvÞ¼y¥z= ähÙ²¥{þùçÝ”)Sl_rdx¯×^{ÍŒÏvØÁûZÿE@" $ÙT5" " " " " " " ¹I`üøñ& $ù®Êo7nìºuëæªG«ˆ@iH4}öÙg[îˆ#FXX°víÚ¹wÞÙ Ï”‡rˆëÒ¥‹å{‰UJBŠq>^}õÕ¶þêׯï~üñG÷Þ{ïÙv >i«víÚæ%«ž† šƒcþ÷¿ÿ¹µkךÇ!ÜöÛo¿âü(C¨ Ï (Ÿ~ú©kß¾½%†'<Ô»ï¾ëî¿ÿ~óØ8óÌ3]Ó¦MSÎy«ŸÚ&"ð)(´D xq•$»à«Iˆ"€uæÌ™Q[ ûc­Zµ\Ïž=MX[Ø$ wôôÉ A(%Â&•V?üp ó„ Ÿs‰s eÂ_þò £Ô£G7pà@SÄ«‡ö†j^O>ù¤»õÖ[Í{¯Z£,C¡Ð¡CW¡B…xÕ¸F¹Þ½{» &8ÂN=ýôÓù Ç]tÑEnß}÷->öÐCµ°S£Fr¯¾úª›6mšÛvÛm-'Þ$2dˆëÕ«—íW| ïÍ>ûìãP¤”Ö'ßîz+"E@ Š( ú(aàŽñƒÈAÁþêիݪU«,1É©T²›®¡X… ¨Âe«’l.ÄÜd}áR[µjÕ¸n´Ù<†Bë[®­±B›WD@D@D ûkjBºx!y³¯—™í±öI¼çž{*ÌSfÑgMk|°ûÏþcЇ]wݵÌ~5iÒÄ=Ú‘Èúƒ>p_~ù¥­„÷õêÕK(<ŠˆAƒY~ˆ… º?üмð| ~ÎÕèðPÑCÖ‚"ƒþ“ìnÛl³kÖ¬™çÑû×­[×ÝtÓMî“O>q´Éó:J ä+­Zµ²ÿ¥˜â]2¯ä HA‘<3!i@AAIGAAŒßÿ}÷È#XÌÄsÏ=×~ÈÓî *•7ùW\q…)–úõëç°4Áâ‚ l*<˜}ýõ×î­·Þ²˜›Ü`r£Ø·oßlê¦úƒ@®¬±]×&(ÜãbýŒÕ7‰uUœ v±†G@½ÿþû I@À+™²ÓN;¹ƒ:È^Éçß޼ȑJA¡@2n^‰Îÿ<Ð^‰ìïßŒŠˆ@ê”$;uv:RR&®‚â‡~pï¼óŽ»÷Þ{Ýi§æÆŽë¸ ÀR%û à‹uÖ²eËÜ%—\â.¾øbKöµråʬ°Öb}b96wî\÷ßÿþ×,Ožxâ [c¬3•ì'ík,û ª‡" " " …F sçήmÛ¶§¾ÐÆo¼$6~ôÑGÍú<Þ>Ú." " éEºu¼¤@ Õ?ÿü³ µ_{í5SNð‹\ Ï8ã ׺uëz£C2M×T¬HÜ5qâD7kÖ,7{öl‹‘y '˜u Œò(›6m²Ä`/½ô’»ï¾ûÜ‚ \5lýû÷7—Øòè—ÚLŽ@6¯±äF¢½E@D@D@D 3Eƒ‡:Ï\*¿øë_ÿjFpÛm·ˆ€ˆ€ˆ@h¤  ­*ø’õ @¡ñÕW_™‹íøñãgÍN‚'BuëÖM1AããÎÊoˆãzÎ9ç¸#<Ò<`¦NêÆçž{î97`Àsc%qW¦’lñ F.“×_ݱÆ^xá‹3Ú©S' étÔQGe]ª¬œØ,êT¶­±,B£®ˆ€ˆ€ˆ€ˆ@ <ð€›2eŠ[·n]‰ï uCãÆíY£8‹€a‘U½"P D=(Pd˜ŒØÿ“'O66Ÿ±¼G) ;Ùx¥tK_e˜q5‰å:|øpSHÜsÏ=îÕW_5ïŠgžyÆ~úéÅ ¹ÙFa-òöî»ïºÇÜrM ¬ f(Þ½zõr+V £iÕ™Ù°Æ20L5!" " " i ÷ÄÌ™3Ó®'Ÿ*¨U«–yëcø¢"" " a‚",²ªWâHÔ{âÇtK–,q3fÌpwß}·[¸p¡«Y³¦ëÑ£‡;묳LI§ mÎ1Ûo¿½k×®ÃB E ( Î;ï< ­tÊ)§Ø|ï¾ûîi%VÆB.“E‹¹gŸ}Öa1FNŒ:uê¸cŽ9Æç(òZc9ŠKÝ(@~f•\l¿üòK(9dŒã–/_îPP(ÌSI>Ú"" " )(‚á¨ZD )¥))¸þüóÏ-A1!¦OŸn7„;v´„ØG}´Ã*Z%ÿä¼OŸ>–œÏ å5iÒ$G>/”ù vÞyç´¿yóf{ÐÀ[ãþûïwä2©Zµª;þøãÍ+‡\&Zci!ÎÚƒ3µÆ²€:&" " " qôíÛ׫âI±fÍš8{Öæùóç»[n¹Å<¼ñüV0HAUÕ)eð,rüB`”k×®uï½÷ž…Ù™0a‚Ûj«­\Ë–-݉'žèN>ùd·ÓN;•Q³¾ÎuÌ9¹'þñ˜'aŸÈ1jÔ(7mÚ4K†Þ¾}{·Ï>û$‚uÇÃÖ¼yóÜC=äxøÚvÛmõ±¾ºvíêH„§’ßÂ\cùMN£Èg;w¶{e<Ø¥ øm¦/^ìx 4ÈBÓæóükl" " åG@ Šòc¯–E ˜€jo‰»îºË’jçØcµ<XÍ«m¶ÙÆ5kÖÌf Þ4o¾ù¦»øâ‹M¡@þ‘¦M›º½öÚ«Lo”_ß}÷… #ñÞähРAq)*…E È5VXä4Z|$ðå—_ºo¾ùÆ‘Må7/á«ðNZ" " a‚"Lºª[âð’dóÿ“O>qsæÌ±<„Ú©^½º%";ãŒ3¡vT ›x6´hÑÂ=òÈ#nâĉnÖ¬YnöìÙ®wïÞ–ÈwkâåÆ*›6mrŸ~ú©%ü;v¬[°`Cá……XÿþýM ë8m+é®±Â!¥‘Š€ˆ€ˆ€ä3r²ã!Êoȑ׭[7óð‹€a‘U½"‡Öì¼°Ìùàƒ,×Äc=æ6nÜèvÝuWwøá‡["lÂñÌœ93N-Ú\ˆêׯïˆKÞ”Z·Þz«{î¹ç,7 ‰­ 啟~úÉ­X±Â½ñÆæ1Ax(¯“k‚<&ìOÒ;­1˜þC ¬5†·—Šˆ€ˆ€ˆ€ä#ŸêÞxË™­U«–Ïáµ­"" " a‚",²ªWÊ °aóˆÇØ+ä ¸óÎ;íåmÓˆGœ÷ßß >ÜÂ?]~ùåÅ»ÒéñÇw7Ýt“)*¼/PZŒ1Â^Þ6ýx¢×Øa‡oWmœ&°Ç{˜Wò·ß~뼜9= :AÓòåËÝž{î©0OðT" " ± HA›‹¶Š@¨úýå/q{ï½·%%^¹r¥Ý³­ZµjfåN"[ðÀ󆇄eË–Yâ¾?ýéO¶~°zçµÃ;ï¾õÖ[Û:Â-›õöÅ_Ø#~,kŒ‡ ­±b\zó;dÖ˜ ‰€ˆ€ˆ€ˆ@>èÓ§«P¡‚ÓBI²›Ùùóç»[n¹Å]uÕU–/Ÿæ[cÈRPdÏ\¨'D17¿ýúõs;í´“#Þé‡~haŸŽ:ê(wÊ)§8ò TªT©€¨h¨¥ <ÓÒ¥KÝË/¿l ³yX@ÑЮ];Ë%Ѽys‡Âå…uÕ£GתU+÷ÐC™·Î¢E‹ÜöÛoïºtéb®Ú$b'¬˜Š@ ‘5ÆúS|$À=2Þí3fÌ‚â÷ ^¼x±ã5hÐ )(òqÑkL" "%¤ È’‰P7 ‹VÊ”wÞÙò ”¸÷Þ{Ý“O>é&L˜à¦OŸîH’M"ãýöÛÏ”…EH£õ«ï‡yóæç’`ÝG‚|ä’@é« °¨R¥Š;ï¼ókŒ$Ù䢸ûî»-wÅ€¬rWÄ«#V½Ú–_ÒYcùEB£(d_~ù¥)(¸7RùÀ_ÿúW·Ë.»(¼“„ˆ€ˆ@¨¤ ¯*Øð  b‡â+®¸ÂuìØÑÝ~ûíî•W^17Ú©S§ººC=Ôí³Ï>ް=*…A€5B‰ ¸I“&™ĦM›\“&MÌ3¢wïÞ¦)„;à€ÜþóSh  #Éö°aÃLaqÚi§¹-Z˜2ƒ}U ƒ@k¬0ˆi”" " " ùL`üøñÞiݺuù<̤ÆF¸ØnݺÙójRjgH‚€$QIÀÒ®"Ï{ëvAù€¸aÆnÊ”)fíþî»ïºsÎ9Ç<)°vç;rDë¯GïsŸ Ô?ùä÷üóÏ[8'Þ×®]ÛuèÐÁÂ95hÐ ¥A’£âÈ#tM›65¥Þ:o½õ–½xð8ùä“-—¡Å´ÆRBœ3…µÆr€:*" " " Q&OžìfΜµµ°?ÖªUËBÃîµ×^… B£•€¡âUå"›@<%{#D>á„\Û¶m-7ÅÃ?lVî/½ô’;õÔSí;n ó£’_~úé'·bÅ ÷ú믛bbÖ¬Yއ”Ì}ûöí-¹zº£®X±¢CáEþ òŸZì‘Gq/¾ø¢åEéÚµ«…ÛqÇÓmJÇgL­±,¶º#" " " eØc=÷¿ßÿ½óž×Ê<(Ïw '9î0’Ûn»íò|´žˆ€ˆ@y‚¢¼È«Ý‚&àñ ÖëÜ^pÁîØcuwÞy§YÓßvÛmîé§ŸvgŸ}¶;üðÃ]õêÕݶÛn« mË!¿üò‹Å»}çw,”!þüç?»Ã;ÌÊ©{÷î+¤-V³fMw饗‡}"!àÍ7ßìž}öYËBû„Ûf›mrˆ¦º‹@y¬±XýÐ6ÈW³V®\é8תV­ø5;¹£1 ¥råÊå7¿]*" "«úôéãÖ¯_ï0úá‡ù0 ÃÓëüÚµkí:_HÛ =L¹á†”$;W¶ú-" 9@@ Š$'‰ÏÕ«W»U«VY¼vÐfCÙ¼y³ûàƒì扤ÊXá«d/Ï"§¬0:<èÎçÆo4wã»îºËÍ;×]tÑEæaqæ™gºƒ:È„!œUr‹ë€‡… ºgžyƼHÎW¿~}ËGBl”Pa\‡rˆµIröûî»ÏB>]xá…R Ï ò^ 0Ó s&©;ÖX8#S­"~üñG»'|ùå—MÁÌ5ã‚6mÚdGCìy’î¾ûnóò<î¸ã,eݺuÍú¸¬û›»¥ªE@D e]ºtq‹/v ¡  ÿžÅ„?EPÑš5k n;¡¯† "EÊ+KŠ€ˆ€”E@ вýþ=BÜßÿ} …BløsÏ=× 4(ÁÂÝí‹/¾0‹g\RÏ8ã תU+³|VÂÛp¹§Z{¢ ¯~Gu”kÞ¼¹­?Âò¼ùæ›–è {rì¿ÿþvóì£ÿÙM¡ÖÒ¥KÍBkìØ±nþüù®Zµjî”SN±pNä#ɤ€g§vrǼ];zè![g/¼ð‚{íµ×ÜI'dßÕ©SÇíºë®Ù V½+&mk¬¸cz#y@ƒ•¯¿þÚ½ýöÛ¦˜˜6mš ¯Çí·ß>FXöPZï¶Ûn¦h=z´ã7Å:žxß ‡²Ii\"€¡JfŒ9æ‡W!WyaXTˆÛ™?…Î¥U¬¾Š€ˆ@î‚"9ÃzbÑ¢Eëb,ع)Áª}—]vIàèÌì‚"÷úyóæYø¬?ú÷ïï8à»™ÊL/ÔJ"PNâ ás²鬹ÓO?Ýß{ï½–;àÁ´<t'žx¢Ûwß}é†ö)G\S°ÂbjqÃôÑGÛPy ·X“x…wÞy¶ÆPœÐ?®{\ÿÎ:ë,³"#|‰Jvk{¯%JÌîùWïÂ%ðí·ßº>úÈaQJž¨¯¾úÊŒ¸÷âw¸Fáv KjçžONNø¤=zX® Â(¥[‚ £ðlذ¡»êª«ìm̘1–¸{äÈ‘&hB ¥’ÝÂZc\{þõ¯Yȯì& Þ‰@ð6nÜè–/_n9¡Æo¡51Ák [®çÄ)/¤‚ç.y’ðð|â‰'Ü£>ê^zé%÷ÆoØoßa,ƒ2#Y£ŒBâ¨±Š€ˆ€ˆ€ˆ€ˆ@!‚"ÆìcÝŽ5!Wxå á~‡\¿~ý\·nÝBÀl*X>£¤ 7q€IªŒ«ý¨Q£ÜSO=UœTëz%U.ÿ™++Iv"=DBî€<Ðgcé^¯^½DÕ>åL€ëIûöíͺ”ðIo‚*~rº!¢ÈeCh±fÍšÙuä­·Þ²ÄÚAõUõ„G ¬5†ßA($¬J &XN(Ây䑦œàzŽ ¾ žuçœsŽåÇ›‚{”Û3f̰ЅXóûDbYð‚ÂGÃK&J²iÜöÇgq&±$F)1`À·Ç{øŽÈ¾·$U¦¿7ß|³yPÜsÏ=–T™¤V(X„°‘0.²d+¿ù BAáõ!2^=¼TrƒÀÞ{ïíþùφÒÙ0È+V´q„SÉ a®±Ü  ^Š@úüùÇð xòÉ'݆ Ì0€ß\î ¹ŸRù÷•܃>Üî9É—5kÖ,wõÕW›× ^&‡v˜ÔÈXF«FD@D@D@D@DÀ# Åï$H&ºdɳô"TÒÂ… ÍR˜Ð+Ä]ç+— ~IJÇžøÈx‚Ìž=ÛâÞ˜Wݺu‚G•ÌH6IvÐ=ܼy³C™Å+Û –«(t¶Ùf›”»êåý@x’®WAÊ( áͼÁ[k¬€&^C<"@"Tî ŸyæóšXºt©å–àþ A;‹2ôˆ=áxcCÈ«)S¦¸‰':<ðkȽiïÞ½]ãÆí4~#bR[E@D@D@D@D@‚"Pð Š_~ùÅ}þùçæe€Ç‰`±@îØ±£#‰ksùái×]wµ†„! ž!÷ß¿¹Þ£xaœ$7Ä _%sÊSAõçsÏ=çÈKR¿~ýÌ :…–è+MаºLæ\äÜþúë¯ÝÊ•+ÝúõëÍê•$¤&ÞP±êã8"¹"\Okè‡À}îܹ®N:®V­Z¡·—N屯8ÿYgÖ™„œéÌ Ž`  Àç¾ðå—_6ã®eÜKa°B®‰V­Ze]˜Ï` WF0§žzª;ôÐCMIÁ=(aSÉ›E2ñÎ;›± á±d<wÕ$" " " " ¹F `ˆÖ®]ëÞ{ï=ó0 ¦0B¢–-[ÚCrù’TšqÕ¨QÃ\îQHxI•ItŠeÛÀí{Ÿ}öq$ÇU —kãåñ@N~bÈÿãÿÈz}½í¶ÛÜâŋݳÏ>›°"mÓ¦Mîý÷ßw“&M²\,(8Ã}·ÝvsmÚ´qǼ…éð'4Å“ê“O>±öPT¶hÑ"Üŧµ£Tâºr饗f½‚"ÓkŒ)_·n%çzÛ AG’]ò%Àoy&Þ~ûm÷ÐC™!=B¸Ž0ü^ò:MmŽPT_rÉ%îˆ#Žp„}"GÚèÑ£-)Þ(‡~¸ã#Â#PÒè~øÁ-Z´È¼%îºë.·zõj³ôÅíœ óó± ˆÅò¯Q£F–ðvìØ±nÁ‚–@»k×®fåF(+³*á@PN)E¸#+ÿÚ -ôî»ïº«®ºÊ xµnÝÚí²Ë.æQñÚk¯Yq¬b¯½öZwÐAw¥%Âr¸p= Þ¸ŠDHgQ×G}d9°¾þúë]÷îÝ£›Ðg @ŽBåŠËý÷ßßuéÒÅ”ùz_˜IÄ(d ;ŠRöùçŸ7ï”×_Ý]qŦ°À0£€Ÿ~ú)“ÝR[" " " " " Y@ à7n4«jòL ¨¬^½º%>ãŒ3Lˆ™sz*T¨`ÜíÚµs÷ÝwŸ{ä‘GÌ“âÅ_4¡²tâý‡>€[IDAT<*TÂ# ŠðØ®Y³ÆÍ™3Ǽ¢N8á„-”´Jè6rË|øá‡¶æ 鄊‚° ! ò%Ä› L%Σ#5kÖt#GŽ´µ‰BLED |¬X±¢X î·Ü'Ì/•Ì@1ñßÿþ7s ª%¬!P âÊ¿õÖ[Á°g-G8—;ï¼Ó^Y3#åÜB—¼óÎ;ö*ç®äuóa((PÄ‘ð—õ¾ÝvÛ™uv¢!¤èy¨ƒ„éþ¼ þ‰`?öñ{$$ú=J@¬%½>ñ™þRJ²TóŸPÅëù'°p'ŒDcK©®1êåÜgÁ–ùñÎ ¾S(I€óÄË{ÀµŒç%!ɉ€!K¢×¸’µkKi¸V­\¹Ò}ùå—Ö‰y¨V­š]Ã>ûì³ÒÕw" " " " " yF   yØô B„@qxªZµjL¡¢·>ÿG¸~ýz·dÉ÷í·ßÚƒ8–ã0!DŽJð<,BXÂìd[D˜Â>óõé§Ÿšp{½zõ\ݺu·XûÑus,[¶Ì! À£á>Ç4mÚ´D.¬K.\è¾ùæ×.,º ´¦”mÛ¶ÝB¨ƒ âÕW_5Ëqι¥K—'£†}%¤F¥J•¢«ûa?ýƶzDÉÀ‹‚ðŸð«V­2.(#¢ ˜:uêØ+ú;Ƈ’Ž˜ãûî»oñ×lã7,ÑvñFßÚ%,”?4|™¸17ß}÷ ½° 'i(9r¡0·Ÿþ¹Í/sǵENýúõmNKó6AhÎ<1~b¼—6ß(¬XC¬µX ÊYGäo ÎæÍ›o±Æ˜¼Ààºûî»Ûº¦¯eµYÿ°Öã _Œ/6O‘Ê£ÿ(¸†Ã†yBqT»vm[‹œoA\gJã¤ïD W ì½÷ÞvM¦ÿü†üõ¯µë×ñSN9żíx]%üžŒœø {饗ìšE~ ˜¿òÊ+nĈÁ4¦ZD@D@D@D@D@r‚@A(("p¥ ¸9øàƒMÆCÒQGeD$CLF8š³[F'òÞ†‡C’…üñÇ&Ü#ì!pˆÕ¯’ÝPN ˜7nœ{üñÇM"JÖ=^§žzjL‹}„À„°3fŒ{óÍ7MØ‹€á)aÐ.ºè¢-„2(²KÃzAð]ðÀ ŸÃÔ©Sm-ù½Ò÷ìÙÓ]vÙe®}ûöîž{î±¶V.‡}Ï>ûlwÖYg[³F×ïÿ̹ûþûï»Ñ£G› —z=EÅŠM¸MLkÆvÒI'™²…s?‘Bâø~ýú¹K/½ÔsÎ9Ň Èù÷¿ÿmÞÅ#ob#Æ*~ذaÅ úÈÜçeÚ´iö=Â/ÂÍñŸy9î¸ãL™â¯/ÛÞ³N`Í#±)Ê^”»¬®™Ìaòüóí<¹~ÆïàZÖ|Ãñꫯ¶51cÆ ¯šâÿ«W¯v7Ýt“…d¡/~Oêïß¿¿ûÇ?þa ¯ûï¿ß”veµY\yÔ›0×ç8”Ï>û¬­ šOvq ç%1ÜÇŽkëÐSÆÃ¾I“&v^á­!%´TD >BvèÐÁ=ðÀnÖ¬Yv-zá…\Ÿ>}Ü¡‡ê*W®ó:¿F}ã'Àµ˜ß Œ)È÷A®(”« 6´ß~G0ŽAѬ"" " " " "PX BAáŸR,kyø¼÷Þ{Ý“O>é&L˜à¦OŸn‚ÜÎ;›p1ß-å°êÆ­ë5¸ú°†fü§Ÿ~º= c•®Ô)醎@Ø}ÇwØZ>ÿüó-y˜[´7Üpƒ=ü·lÙr‹Á |õ¬ú aàÏ Ž»í¶Û,ìÙ‘GéZµjµÅqé|ð¾8ÉwºC„‚ Aþa‡V¬LŒ×ëekk{)Ç{lñîxLœxâ‰&G¨Î¾|e=Ê „ê(’-x p½ðDX­70ý÷ Bhúˆrâïÿ» `ð4@‚å LP†d³ð˜¸à(žPb!üG©‚2Öã`í ÷ ¬'öRoe½ÇˆD«¼°ŒF ”Ïk åc…-ëåÞHp §ç2‰âQ,®FED >”ûüî5nÜØí=ô›7ož›?¾l Àà:‡‡žçõ¿6}ã'àyyq¿Í=8Fx(b@pòÉ'»8 «ýcÑ{à œ‚A EW\q…=p"xÃüª«®²Òš¥Â¿unðè3_£g½†Àðá‡6a+clݺµ=$öêÕK‰34-Ù)é9n3—<òˆYIcíï)<”æ >ž„Nð¾£]˜œ±~2dH±Uè^{íeÙý.©  M„Úxg\pÁÅm¢0 y=J Æãy;ÑÏè‚BÁгƒ6Á¿?˜"D5j”)Z8¿y¡¸¡n`# Ap¢$Ñ‚GŠç¥áC¿Q¸ðŸk J ^µžyæÇy…âÏ+„Žâ:Ã1x Ãj4 Þ4„µbÞP² LñÖ^Vx‚à5‚Ð ¡ž÷cAy†ŒuÉø½ëi2ó,ò 1xãœvÚi)µ™+k 6„1ÃS–Ë/¿ÜÂm±Ö¬+Æ‚‚KåóÎ;¯TD@Ê ÀïÞXxM ¤xê©§ì<ãw¤wïÞ®S§NB}þk^Õäמ‡¡§Ð澂ßâ®]»º¾}ûc/HAÒ E@D@D@D@D@Œ@Á)(¼yG€CŒs\˧L™bá1l!LÓ`À€öBÞ|xÅz Kr¬¹±Þƺ›ü„qB-xõ8éö`N'OžlJ„&þuÊ{qW^y¥ …BL¯ l'”×…^X,Äå;¶ŸýöY°º'wmúû‚°…ÖàähˆW¶âùƒõ%!mÎ=÷\ùÇí‹"«~,ËñXÀK !­^|ñE³€E@‚ò€øâ©(ŠÞ#°"TE—.]̳ÀkŸ°U„¡o„ ‰.(Gr]rÉ%féŽi6®^X'úëg 3®ŸC‡5æÇÏo®/„‹7ßä²² 0Ä[†6ý}ÉÇ57¼[˜ŸcŽ9¦X9áñä\&´×yÂHýío+V zû迈@|äqáúvÄGØï¿x#qÎ!\ç7å²ì%ò{@¨I~s1ˆyúé§-Ä÷ÝxMà‰‡²ZED@D@D@D@D@ ð‡Ä²@yê·}’ú"øäA !>qö ÂwXE#àÊÅ‚•=Éi‰OX«9sæ˜@–|X²i!Ÿ‹|Ê«Ï<¼SÒ íƒe"9vÇR0‘s+± :Žñ¬Ú½}èÃÞÛÔ¯M¿°šºùì%YöB_E·Év’jâ-r÷Ýw[(%”2~!tô1|¦MÎ_^Xñ£¬@È„b Úb˜'¼¢ ÂþKcäóˆÞ·¼>£#/á’byy OŠX¡žh~.ìçŸïXÇ¥³Ík3z]øÛÌ—5†B5D® B—Å[cŒ…ûr­PHœ¿!Ü'¡DG1NRgÎ5<–ȧDRg”ú„Œ¾Ö%ÞJ~í‰âyÑ¢Eæy‚ ¿Ý  È'ü"¿™~ew~^£H…@Á+(€Æƒž„ÁúöÎ;ï4 9âwcõE¸,åèb•š 8ÖÏX¯FfÒ¤I¦d!슬Çse,¹À;™>" åźKç!åÂcâûç{!\kž!(ÝPº*Ñâ)+Ž ¸¹îºë,¬^äVH¦Z‡ÐY„i¢Bcù á¬ÊxIŸýßyï0J$›…ZŒá6Ìó½äâ#i8I² ±EȳèÂueŠ"öSHJôã?Þùä{8$ ÎG}d¡mçD2dB¨dOàK€žhÀãùƒ•>Bäè°6ÔCx!å™°ZD˜í+Ñ1$º rà 4Èa¥ÉyÈ' ç£7vxWú ψXa‰h&$x&4 O¡PV¨ÿ­·Þ2ëP®þ¤ÑþcÎ 8†‰V½þù÷á=ß§³¢ë ú3ã ¼ÞX±ÖÜ`Â2á ¢5öÇ 37œÿpǃ‡äï±J¶¯±X}Ö6Èf\ïP>“߯Tîg͚宺ê*óª  ŒÝvÛ-›‡H߸þ/X°À”5x–ßÞ=zØ+Þop «¼!°UÞŒ$„‹Ÿ¸õ¸ª8Ðâ°c†sĘϖ‚ЖpT_|±2dˆ#0Imoºé&Kê(åD¶ÌÔoý@ÐJAPžj!é4VÓÊGV$†ž9s¦ÃÂ1ÝB_Ì ðŒNfÍ6bÜöÙgé6óx,RQ²¡<ä¼$)0¡qãÆ™2Â;eJ hãP=V¡¿R® @Id˜3<9þ÷¿ÿY•´Ï*”dÍ5jÔp„à‰Å„~¡X",ܲµ0Ø3BwDÖ‚9Æuô1¥}öÖ땹ô¶±ÖáFɵ5ÆùOx7ònî,Ο?ß<êXó*" ÁàÜØeĈnذafÔBXÍÿþ÷¿^3¸–²·&î5¹/æ>™ßf”3·Ür‹ýK9‘½ó¦ž‰€ˆ€ˆ€ˆ€ˆ@¶‚¢ŒA [=’{âÊ+¯´¤ºÄfÛÍ7ßì&NœXÆÑ™ûÁ¡dræ²Ë.³¤Ø$°g½¹Þ©¥hA((!ѱcG«šè~¥ÂH¼†j‚XéÖ=ä%˜={¶yP'my‚ûyóæ¥ÛLÌãi¬WÑ„¢á>ÊB˜QP´hÑÂÂk<úè£îÝwßu(jüÅS XGA'D"…Ï<óŒc(.±W*UªdykàŽð&:þ?¹+Q…GÖ§ÙZð!<cçzçW 0@wÉ%—¸Q£FÙºHwxú ä¢=êöÎæiáÂ…æÑF\ó0J®­1[‚¾ä €_I3B® <Ø=:%eÜU§ä:®“ 0ÅÄùçŸïÚE¼'ðn*„‚Ñ¿…xr_Œ¢æÀÌjÏÀB˜QD@D@D@D@r€B<%8cÎHÈ˃ž Ó¦MsõêÕKðèðwÛa‡,Á7äþýû›R%üVÕBª6ßž(:ù41ïQ@wÜqÖ=J: íé1¨"G­¬6©O%òø DZ¶ñÚˆ®“¸ûä¢À¢öÿ·w'@RÔgÇ@‘SV`EnD9\”[@9E@¯HD<0RÁQc*•Š!jÅ”÷E&$ QA„U\‘ ÈÀr,‡¨€Ä—ßóVofggö¾zæû¯ÚZv¦§§ûÓÃnw?ÿçyz÷îí9µÝÆ ó²“&M²{ï½×o¬ëFŠ2öîÝëYÚ—1cÆäjRk[”9°fÍpèßÚ×è¡ß }ûöõrpzNå-”!¡ „ï â膿n+p¤ÞwÞygÜã½þòúYÇEYºþ—¿üÅ“>ÃëÖ­ó •Jz :4ÇæÅ2Œ\ Þóú<+¨3þ|?¦ÊÔÑûëøwìØÑîºë.›Vj+úóoÁûÆ{¾<>c±Þ³(Ÿ1°QÆœŽÍÿøG/E¨Œ"õ RÀGŸq € € € €@E @Q Û”ð%¤ÐMZݨ¿ÿþû-##Ã˼({¢K—.>ë]3ô£³4t_%ËÔè=ÖÐóãÆ³6mÚäzZÁ•óQöJH)  LÝ•žŠ Ü(ƒE7Ý•a²}ûvo\¯,•bSv@ErÖqQPFjäÝïXÝUÎ#–aä~ÏGo-£Ï‚!*§¥`—>sú<}tTfOŸ‡èÏu°ÎÈãV÷,ÏX¬÷,êgLA¯ø1RfΆ < £¬"}Æbý?Žtáß € € € €@y T:v£ôÿ»õ–çV”Á{«¡µfâê¢fß2òÀ+oŸâ<«Ùóšq¾~ýzÏ8ÐLz €@Ù¨\˜lÊxRf#¹ä¾çX9@õOÐwFù p<ÊןwG@@ <Š^¿<¶–÷D@@@@@„ @‘‡‘›@I4ÉÛ>³½ € € € € €@¤ŠH þ@¨ªš¾Ô?"ºÑo¼=o € € € €Tâ0° € € € € €$—Šä:Þìm ÄS9l € € € €”›Šr£ç“Y€E2}ö@ ¢Ô¨QÃRSS­fÍše“’z;8I}øÙy@@$8.Yöûøã·víÚY£F’e—‹µŸx‹/ß È—ˆ@(u!C†X‹-,--­Ôß‹7È_€ã‘¿K € € hI HII±»ï¾Û43‹‘¿^ùg 5ÉÖ Ivqy- €ÅP`‚àDñ KòÕ’Ôd] € €„C i L\yå•á8*`+ñ*½ƒ@p¢ôlY3 € € € €„G€á9Vli Pâ)&»‚ € € € €E @Q$6^„@ñPÏW#€ € € € €@øP„ÿ² € € € € €„N€EèœdP$ÂQd@@@@@ 8(Š£Çk(‚€šdë«R¥JþU„Uð@@@@@ ô(BÙ0 (@¡¡ @@@@HFÉxÔÙçr @Q @@@@@r @Q΀·ONzP$çqg¯@@@@@à(þgÁ¿(3eFÍ!€ € € € €@ @QA ›… € € € € €@"  Hä£Ë¾UHõŸÐ—dÓ$»B"6 @@@@Ê@€E óD Pâ)Z„Ÿ@@@@@ ÙŽK¶f¨Ê Ð(É Šï¿ÿÞ–/_î_gŸ}¶uéÒ¥"ì*Û€K`×®]öî»ïZíÚµ­gÏž–ššZ¬õñb@@@¨8(*α`K’H $Gµ7ÚÛo¿m³fͲիWÛm·ÝF€"‰>Oì*‰,™™i?þ¸—Æ4h]tÑEÖ­[7«^½z"ï6û† € € €@R HŠÃÌNV4’(ñ¤ Çž={ì½÷ÞóàÄܹsMÁŠÁƒœ¨hœíA" (cBA‰éÓ§Û„ lÉ’%þ³‚iiiV¥J•"¯›"€ € € €@ù  (_Þ= XÐWqšd:tÈæÏŸï7ìfÏžm[¶l±^½zeß´kÛ¶mʲË ˆ7ö¬°öíÛÛ;ï¼céééöðÃÛâÅ‹mÈ!vÞyçY“&Mq×Ù'@@@^€E)bÍÏÊÊòǚݩ›' 4(¥wcµa(j€âÈ‘#¶jÕ*›1c†ß¨SωV­ZÙwÜá™]»vµªU«†ƒíEâ (˜«,Š+®¸Â³ÃÔcG¿çÌ™cË–-ó@…2ÇÎ=÷\«S§NÜõðaP/–mÛ¶™Î/5jd Ü1@@@D @QJGQ ‹?þøc{î¹ç¬V­Z6räH»ä’KJéÝXmØ  Ð ÕaŸ9s¦ß˜›7ožÕ¬YÓFŒáYýúõãÆ\Ø>l/Jà¸ã޳ÓN;Ín¼ñFS0VA õÝy饗lÑ¢EžMqá…Z‡ÔJ–…à °páB›8q¢}ж"^• 8T®\Ù¿òÛÁØûï¿ïŸ%õ›Ø·oŸ—4QMvÕ`oÖ¬Y~«ày@ aªU«æM²[·níßß~ûmϦP#m•}R6ÅÀíôÓOO˜}fGؼy³©¤£Î ºwï € € 0(JéPª¬“n0À3(š6mZJïÄjÃ(  •.‰7”…³téRo€­Ì‰Õ«W[§N즛n²`–°‚ @ ü×ïBõ¦Ê>eddØ'Ÿ|â´ÕŸ¢wïÞ^*}ØçÄÐy¤²%•Aqê©§&Öα7 € € Ô(Jéð«@=¼ï„ÊR0˽” CºÚ¼AöÍôéÓ½¤“J…rÊ)öóŸÿÜg÷ìÙÓjÔ¨Ò=g³@’PV=žTî.R¨‘ök¯½æA 0”mÖ­[7«^½zɽ1kB Œ”5ѰaCÓ9“^ÊŸ·C@@R @QJ¼ºi¢†41,%à¯VÁ‰X=(ôØž={LeœT²dîܹ~#B½K4øüóÏ·“O>9Ä{Φ#€¥# IíÚµ³-Zd—}z÷Ýwí™gžÉΦPI¼3Î8£t6€µ"PÊjŒ­/ € € h( pD5[mëÖ­¶{÷nûæ›oLõ¯ëׯï)öÇ|Ü5¨ÏÀÞ½{ýùÔÔÔË9r$û¹ODý @j†¬¯xC¥€vìØa»ví2ý[°šeÇlÑxbåÿ¸>A‰¦C‡Ùüùó³›¾nÙ²Åzõêå3uS­mÛ¶å¿Ñl PÁô·R=ŸÒÒÒ²i«‡ÏC=”ÝH;ø½[Áw…ÍKPÿé|Mçm*פ’ :GÔ„–ZµjÅÝk½Nç :Ðr ÊC´.}å7tÞýúÈ×h]ês±sçNïy¥s^WÖ«WÏò:ç\ÿF@@ #@€"-]nÛ¶ÍÞzë-Ÿ© JÝHÖE¡f²wìØÑ.¸à;묳b®å«¯¾²GyÄTâéÞ{ïõïZ0Xïƒ>óu‘*È4üŒ|\ÿJ½þúëöŸÿüÇ/xøá¿T}b͸×Mî¼úD¯“ŸËF@74t W¬Xá •%Y´h‘}÷ÝwÒçDA±W_}µl6ŠwAH@õ»V_úû=mÚ4[¶l™5oÞ<ö’] “€&¤§§ÛÂ… ýü2PèœRA5MHèСCŽàC° h¨ô£^sñÅ瘸 ó†Y³fyf°|¼ïj¯×·iÓ&×" €¨¬¤¶qãÆ Ðy¨‚'Ú.õUkÙ²%畹äx@@Š#@€"Ž^pCãñÇ÷ ÂV­Zyù]¨é"ñóÏ?÷ ¸O?ýÔî¼óN¿p‹^•.ô^|ñEϸ¸ûî»s<­'ûöíËñXäz­Jüh–Û9çœù”ÿ[3é–/_nO=õ”iv¨‚%­[·ö¬‰ÌÌL›:uª-X°Àn¾ùf/¤ £â G}†ž{î9Û´iSöêÄìÙ³ý+ûAþ Pdý¾]·ny%¼" hÂËË/¿lšT¢ï*IV»vmÛ¿¿O2Ñ5x¿å–[|rIôy[VV–i"ƒ–ïÔ©SŽ…Î)4&Þy¥&<¬]»ÖV¯^íç„ýû÷ϵÊøUyI·*ƒBåДÐÿ½NA}5j”OÌ!)! € € €@¸kN¥’TrgòäÉÖ·o_»ãŽ;|v›š+@ñÙgŸÙ /¼à32O8á{òÉ' ܸ8èO´6åÛo¿õ‹Ä>úÈÔ9V€B½ ÆïA’Ÿýìgö“ŸüÄg…*_Û§>ºé­²š™kÁûñ½ìt³@CŸeàŒ=Ú³(tƒBŸ=}ÎtìÕô•’ e|xG¿€n¬jÆú¼yóì‹/¾ð,Fõ¨Ð—þF2(KSjòˆ24y¤K—.> EAeÁ¾ôÒK€8ñÄ=V“N :t.1pà@_g¬×hijÏ>ë%¢z÷îí%J#—Ó9IFF†Ÿ7*KøÖ[oõ É)§œbšP³fÍÏæTf…' ¢(S— € €”„Š8Š (@ #FŒ°îÝ»g/Ù¤IkР_X*P €CpS9{¡|þ¡ÐJç*ù³råJOÕ×û(0¢ï‘ãðáÃÙ³ë‡ fcÇŽµºuëf/¢‹Æ‘#Gz]ãßýîwöüóÏûEkd½âì…ùG¹ >Ù/ Fhö¢»ê¦šJsésFŠr9D¼)„T@¿_5\7S·oßî¿K¨ïׯŸ—¶ÑïV!=¸!ÝlÝäWö‚šTrÞyçe—ýT@ëu.©s@eê*¢0C¯Õzô=TntΜ9^²IAŒK/½Ô38"—S9'•3U©¨1cÆø¤§£G~žùå—_úù§Î[š5kæç™Á2|G@@Š*@€"Žœf“©Ì’ndÄêá Ë]»vµ?üá~Ѧ Ê’ x<ýôÓ^‚â®»îòlÑëÕŦ‚jª™÷‘Á‰`Ymnl«œ€nÒhö[ûö탧ù^ŽAp"òs¥ê¢r ݺuól ÝPPŠÅ‹{³l=¯›l @Ø*§ß™3fÌð`¯fŽëoõ!C|†¹&h¦8²Ðß}Ýü×dýíW@!rè1MR¨S§Ž÷LQ–EI <”¹ñ¯ý˃Ç÷ Žèu«$¨&å(€¡òO‘Á‰`ÙÓN;Í+*õ¤>ZNͳ € € €@qPÄT¶nèOœ8ѦL™â©ìªÇ[¥J•ìW¨œR¿c32KjhÆœj¿ùæ›~CZ™‘ï§÷ÑE®f°©ÿ„JÅʶGeÔ$û¯ý«7ù&@È”ÿ÷ ÄSäM Ý HMMµ«®ºÊo¨é¦šêM¿ñÆ~ütÓM ÓuLK* Vþl P|ÝøU &fΜé#›6mê¥tô{S_~oß™5M@“ZÔhZßUr¬sçΞ=Фõ–(É¡~i“&M2MlQY&A"Ï;ô^ÊîX¿~½7ßÖ9e¬, -§óQõcSæÄ† ¼l É0@@@ ¸(âêF†f‡) Ö¬Y>óM)í§Ÿ~º_œi&™n&—ÔÐâÒ¥Km„ ÖâX}l•mª_¿~®Õk6œJV¨•¾”!oh¶ž– êpÇ[ŽÇË^ V€"ØŠà&€Ê,èfBpÃMŸ )4ø‚ .ðl‹è Á:øŽ$ƒ€~—}—T"OÙúª¾L]t‘õéÓ§DÿV'ƒ)ûXòš€ I%úÛ­Å}÷ÝçA3ÝðoÞ¼¹ç”ѱ‹³%ÊÈ}íµ×üÜòâ‹/ö  ‚D/TMçŠ*1š×y¥þ¯i’Œ&ËÄkȽ~~F@@ò @GH7~uá8nÜ8¿À[¶l™ýýï÷¦Æê ¡æ…ʨРdÍ„+Îb]èeffzÓ묬,ol­`H¬¡@†š}*P±uëVÏðˆµœÓzÕ¯B-Ϩ8:6ºio¨éå¹çžkíÚµóŒ eSÌž=Û|ðAS3í d‰f32@d8pà€—¥Q`B%ñvïÞífʘP©ÝôÍëwl²y±¿å+ ¿åjŽ­€„J$©ì’†2+ôYmÛ¶­÷;;묳¼„gq¶VEsçÎõ L¯^yå•þ>±Ö©@Ãþýû½ï…Ê7)›"ÞPC硚@œÇÄ[–Ç@@@‚  ÈCJ©ø* ¡‹»Ï>ûÌ”*¯´öÍ›7ûÅ¥J1)  ?Õõ.ǔǪs<¥^¯¼òнÿþûvíµ×Úe—]÷¦Š.uá©m;óÌ3mèС9Öëm—J]0*Ž@pa_›gªI­¦–*ùdT|ðÁ>+rÉ’%vá…z©1-Ç@]@Ùƒšé­ ­¾Ô|¸M›6vÍ5×ø uý]V™FI@çm]ºtñê¦Þ` èœRe;PPy²aÆyöOqzN©Õ?ÿùO?—¼úê«MAxçšÀ¢ÀC½zõü\"Þ™HËZµjù$ÈÇø7 € € PTùÈé‚N²Þ½{û—úD(sAÁ 5Tm_]\ªôS÷îÝóY[î§U†I7›_|ñE/Ù£Ùuºð‹7”þ¯úÀÊØhذ¡92Þ¢<^AœÐ—>[ñnDoºŽ·2wn¸á†ìl •~R)Íx i+€¡› @ ÑtU„º‰«ßúÝ—’’b×]w—¯QÆÚD;ꉷ?:§Ôù¢¾”åªRœk×®õϳzN=ù䓦b—_~y‘²s·mÛæÙZ§‚*UªŒÌxCï¥/õUÓ¤õÁb € € €e)@€¢Újh¨™šú:çœsüâòùçŸ÷>… P¨v¶22þüç?û ëÛo¿Ýym’ʆÐk7mÚ”}£;Þk43N7· z#<Þzx¼dòêA‘×;éøkv£²zŒPi“wß}מxâ o¤­šëªq­Ï'HtU#?==Ýú®»ê¥Úúýúõ#K0tîƒúi‚K0ÉEŸuõ›RG•)«]»v¡T<è<õNSÖ¥z±ä×/MA¾ºuëz™'ý? &PÄzc=<Ïye,!C@@¢ ˆ£¦Ì¥ß«É n~Ä*ߤgš±ùì³Ïšf¬v¨Ñàßþö7S‹;ï¼Ó/Fó[‡‚ ºØTÿ 7V­Z奞b½.ÈÎP Cº-[¶Œµ…P@²óÏ?ßÚ·oŸ]öI5Ø?ùä/1jÔ(oÂ]c“@šaþôÓO{pbãÆ~ã5èÁ“––óïsŽðå, €šÎÅ@8õÔS½‡Cô&©Ä’Ê¢U-[˜… lLž<Ù3‰”=¡¾ù It~¨ •KÛ¹s§gèÆz2˜Ô?CÛ¨I:Úf € € P\ÊÅ]A¢¾^³È{ì1»ÿþû-###ænª„J=)xQØZÁºX>}ºM:Õg^ýõ®™­òZ~×®]Q=îè¡ U•¢zôÑG½\ÀW_}½?—£@Q3("7Y³õ¹S½ê»ï¾Û~ûÛßZ§N¼Žµ‚^ @ ²²²¼×„þ®© â¸qãl̘1^W?ÖäDØgö!±233mâĉö§?ýɺkIôÐc:¯S_24¡0Cý,œÐ:ÔM„‚üÿй„–íܹ³Í›7Ï¿Ô;zhûÔ'ãÁôÌÍXçžÑ¯ág@@@  dPÄQÒEê]ôÑGöðÛJëhf›nëbNjj=mÚ4L³Ù :´^5Ý?~¼÷ P½_­sÇŽ¹V¡Ç5«M)øÁÐE«fª9è¿ÿýo;í´Ó¼V±zÛ­¢j¼½téR_–ì‰@¯b|/‰E°':æ­Zµòv*3¦, •v` €‰ ШQ#S DÍ&ïÕ«W¾%kaŸÙ‡ÄÐyœ&¦( s@ý¬2ʈUß(SΟ?߃꣢ìÈÂdO(#÷Í7ßô‚Ö«fÜꙦ¯è¡s­[™ÁPÙH•KS¹HõDÓs={öôlÊÜÕ¤õKSDÁ‹:=àñ@@Š-@€"¡êñÞzë­žb¯‹²{î¹Çëú«ÿƒ.î4CM‰uñwÓM7ycÁ8«Êõ°.RUX³ÜÕðZ=Þ{ï½\Ëé]¸êBPï -š5kf¿ùÍoì™gžñ Ê+VxÙ•Ò…ê§Ÿ~êÁ‰AƒÙm·Ýæ ƒ×ó½|`RóËúõë—膨 f=ü«DWÌÊ@rhР7Â.©MÐï^ýn×®]I­’õ §€‚lÇ÷ý~ø¡=ðÀžÔ¼yso`­,!M(QYÑ#Fx‰Fët¬[·Î{´¨Ü¨&Ò(Èïõ*ˤ`„²&‚¡ó/êœvÒ¤Iž%¡‰7ö>f*³¦¦ôÊ¢¸öÚk}YY € € €@IT9vãýž’XQ¢­CAÝQ¯+4{LéóªÏ«غ˜Tá뮻Δ™áXh–œÊ,©FöàÁƒý"OÏiöÙÚµk=…_§ºàSª|¬/­C3ì¢pkû,Q}aÍnÛ½{·÷£POŠ-[¶xi5GT)(•ýaTªU«úgB³ [¬âì[‚„S@AbÍPïÖ­›ÿ}ç^°ÕaP°@R”ñª2š¨¢>b*ªà‚Îá4ñäŠ+®ðÆÖ:¿Œ:GT¦…ÎýôÙ<Ð9©ÎSõ˜20ò:¯ÔÄ—6mÚX‹-r¼…²*”)ܰaC½Î%•í«~lû÷ï7eY(xr饗š2v € € €@I T:VÓùÇ’ZY¢®G’ºˆTã@]곂º@‹¾À‹4PpAÁ tQÌf;zô¨g`¨ b~C¯U-bÍb‹5tøÔHQ U"JÙÊ¢PpE šÇ@@(e)èæ¿²tN©óÉwÌÙc@ Ð*!2gΛ2eŠ×R¿æšk¬ÿþ…^/@@@@@ ¨üƒï €ÄPÓÕµk×ÚŒ3,==Ý3)â-Ëã € € € €D€ Š‚(±  äjÜzúé§Û€<ƒBÍR € € € €G€&ÙÅÑãµ €@’üðö}ûvÛ¶m›U«VÍš5kf'Ÿ|r’ì=»‰ € € € P(JC•u"€ € € € € €@ž”xÊ“‡'@ÄP? eBìÙ³Ç×ë#_£uíÛ·Ïû\h)))Ö¨Q#;餓¬R¥J‘‹òo@@@@ Ä¿âbÓ@r (À°aÃotýÉ'ŸXVV–>|تW¯î}%Î>ûl;ÿüó­M›6¹_|ì5žzê)_ööÛo÷@E°àÞ½{mêÔ©¶råÊࡸß[µjez}åÊ•s-£õÌ™3ÇæÍ›g;vì°x`¢iÓ¦ÖµkWäzá±ùüóÏí‹/¾°Ë/¿<Ö"ž1ñ /ØôéÓíÇ´Ž;š‚ R¬X±ÂæÎëÛ:bÄkܸqÌuð  € € € €@xP„çX±¥ €@‘T*)==ÝfÏžm\p3ÆZ·nm*·¤ÅÒ¥KMÁÉ“'[íÚµmܸqžYQÐ7¬W¯ž)pp饗æz‰‚«V­²xÀZ¶liW]uU®ì 7Þyç{饗<0qà 7X§N<[BŠO?ýÔ&Nœh&Lðõ+CÛÎ@@@@¯Šð;¶(°€zG,^¼ØjÔ¨áÝüÆ©§žj 4ðþßÿ½÷yP9(•~*è¨Zµª÷°ˆµ¼J5-[¶Ì3!n¼ñF4hPŽÅ”ݱvíZ@h;~ýë_›ÊMý&ªU«fýû÷·O<Ñ6mÚdÓ¦MóRT;wα~@@@@—Šp/¶(’À‘#GìСC~Ó?¸ñ¹".úöíë ©$PP $†27Þ{ï={ë­·¬G6räHoʹneOÌŸ?ßÖ¯_ï™]ºtÉNË©1·ÊN :Ôî»ï>{ã7ŒE Ãw@@@@ œ¹;”†s?Øj@<T¶IͯwïÞm¯¿þºg,¨ôRäHIIñ …ʈ(îP†J3©t”ÞôèѦlè¡ìeX(C¢OŸ>9z[D.«çÕ7Cý)–/_nʼ` € € € €„W€ Šð;¶(°ÀI'dôÙÊ>Ø¿¿uèÐÁ{B´hÑÂuëÖ-ðú ² z[¼øâ‹¶eËûÕ¯~e½zõŠù25ÐÞºu«ó2O6l𬄹sçzŸˆ®]»ÚðáÃmÈ!y òÚàï¾û΃¯¼òŠ5oÞÜK;rÊ)q_¢RM*•ššê ¼Õ#¿¡l•b € € € €„W€Ex[ŽZ@ͦ•п;ï¼óì›o¾ñLkÖ¬±>øÀ³²²²<° P…ê¡Mê;qàÀ;v¬gn䵞N8Áƒꉡ2T±úTäõzžC@@@§Šp7¶(¶@¥J•< áÌ3Ï4eUtìØÑ³g϶?üÐ{TöMܘ2eŠ-^¼Ø³!.¹ä’|31ªW¯n76I¾øâ‹< €(ãB € € € €@¸ŠWd<ÜûÎÖ#€I# L‰%K–ØÇlÊTˆ V¨ÄRçÎM%švîܽH¾?«Éµ²0¦NjíÛ··Q£FY:uò}x«?†úV|ôÑG1·O+QpBM²Ço*I¥@@@@@ ¼(Â{ìØr@ @º±¿yóf{ä‘Gì±Ç³¥K—Æ| *ÏTµjU«W¯^Ìeâ=¨ ‡2 žþyo°=zôhkÛ¶m¼Ås<ž’’b½{÷ö÷T“ì•+Wæx>øA ?žxâ ´ó@@@@ œ(ÂyÜØj@ P*‰tèÐ!Sù&e ,Z´ÈöìÙãY `ìÛ·ÏŸÓóÍš5³sÎ9§PëWÆÅË/¿l+V¬ðÞiii¶cÇŽ˜_z_5ņ¶íŒ3ΰaÆYff¦ 222ìðáþˆ2%¶oß&Ožl 6ôí«\™?a!ß@@@@0 Ѓ"ŒGmF ! òMÍ›7·_üâöí·ßz bïÞ½ÖºukkÔ¨‘)Pß5¬¾îºë ÕB„õë×Û«¯¾êë_·n=ôÐCq·°iÓ¦výõ×[“&M²—QÆÆðáÃ=ˆòÖ[oÙ½÷Þkݺu³ºuëz0C™Ú¾jÕªÙÍ7ß\èJöñ@@@@ #@€¢Â 6(=5jXŸ>}¬V­Z6cÆ /£¤, eO((¡ÿêѿπPãêèQ¿~}»ì²ËL†Èì­£fÍšÖ·oßì—|ùå—ÙÿŽþ‡J:E÷ÐúZ¶li¿üå/=˜²`Á[¶l™,`Ñöۦﱶ/ú}ø@@@@ b T:vcéÇŠ½‰l €@I èWþ×_mÊrصk——QR€B *íÔ¸qã¸o¥’K[·nõ€†–Uà Zç¶mÛ‚óü®`ˆÊ4é{¬¡&ÝÚ6­/++ËTJ ¼ÀÐw € € € €@b HŒãÈ^ € € € € € *:Œ†êp±± € € € € €$†ŠÄ8Žì € € € € €¡ @ªÃÅÆ"€ € € € € (ã8² € € € € €„J€E¨‹ € € € € €@b HŒãÈ^ € € € € € *¡:\l, € € € € €‰!@€"1Ž#{ € € € € €@¨P„êp±± € € € € €$†ŠÄ8Žì € € € € €¡ @ªÃÅÆ"€ € € € € ÿ‹\Ž™±iûÅIEND®B`‚stargz-snapshotter-0.14.3/docs/images/estargz-verification.png000066400000000000000000005544551440204344700245470ustar00rootroot00000000000000‰PNG  IHDRÖùvE;¡gAMA± üa cHRMz&€„ú€èu0ê`:˜pœºQ< pHYs"š"š¾Ýû*YiTXtXML:com.adobe.xmp 1 LÂ'Y@IDATxì¸]U™¿7(ƒé½%$¡“Hh!ôÞ¥XËŠ ˆÎ8ãècyDZŒ£àØ 8*mAz‡ÐB‡$´Ð „Ž"ÑÞåÿ;®»sú½÷Üsî}×óœ»Ï=gïUÞµö:{}ë·¾µÈ_„  H@€$  H@€$  H@€$  H@€$  ô!°hŸÿüG€$  H@€$  H@€$  H@€$  H@HÖØ$  H@€$  H@€$  H@€$  H@€$P…À;ùŒÝ žyæ™*_û‘$  H@€$  H@€$  H@€zÀ +¬P,¶Øb½—qs, H@@WXd¨æ/¯¼òJ±ß~ûuUÆÌŒ$  H@€$  H@€$  H@€Ú%pÒI''Nl÷r¯“€$  H@‰€[AÙ$  H@€$  H@€$  H@€$  H@€$P…€Âš*PüH€$  H@€$  H@€$  H@€$  H@ kl€$  H@€$  H@€$  H@€$  H@¨B@aM(~$ H@€$  H@€$  H@€$  H@€$ wÖC°È"‹«¬²J½SüN€$  H@€$  H@€$  H@CFà…^(Þzë­!Kß„%  H@Þê k–\rÉâÌ3ÏÞ,$  H@€$  H@€$  H@@ÏøÌg>SÜ}÷Ý=›3. H@@wp+¨î®s' H@€$  H@€$  H@€$  H@€$0DÖ x“•€$  H@€$  H@€$  H@€$  H@èn kº»~Ì$  H@€$  H@€$  H@€$  H@ÀPX3DàMV€$  H@€$  H@€$  H@€$  H » (¬éîú1w€$  H@€$  H@€$  H@€$  H@CD@aÍ7Y H@€$  H@€$  H@€$  H@€$ î& °¦»ëÇÜI@€$  H@€$  H@€$  H@€$  …5CÞd%  H@€$  H@€$  H@€$  H@€º›€Âšî®s' H@€$  H@€$  H@€$  H@€$0DÖ x“•€$  H@€$  H@€$  H@€$  H@èn kº»~Ì$  H@€$  H@€$  H@€$  H@ÀPX3DàMV€$  H@€$  H@€$  H@€$  H » (¬éîú1w€$  H@€$  H@€$  H@€$  H@CD@aÍ7Y H@€$  H@€$  H@€$  H@€$ î& °¦»ëÇÜI@€$  H@€$  H@€$  H@€$  …5CÞd%  H@€$  H@€$  H@€$  H@€º›€Âšî®s' H@€$  H@€$  H@€$  H@€$0DÖ x“•€$  H@€$  H@€$  H@€$  H@èn kº»~Ì$  H@€$  H@€$  H@€$  H@ÀPX3DàMV€$  H@€$  H@€$  H@€$  H » (¬éîú1w€$  H@€$  H@€$  H@€$  H@CD@aÍ7Y H@€$  H@€$  H@€$  H@€$ î& °¦»ëÇÜI@€$  H@€$  H@€$  H@€$  …5CÞd%  H@€$  H@€$  H@€$  H@€º›€Âšî®s' H@€$  H@€$  H@€$  H@€$0DÖ x“•€$  H@€$  H@€$  H@€$  H@èn kº»~Ì$  H@€$  H@€$  H@€$  H@ÀPX3DàMV€$  H@€$  H@€$  H@€$  H » (¬éîú1w€$  H@€$  H@€$  H@€$  H@CD@aÍ7Y H@€$  H@€$  H@€$  H@€$ î& °¦»ëÇÜI@€$  H@€$  H@€$  H@€$  …5CÞd%  H@€$  H@€$  H@€$  H@€º›€Âšî®s' H@€$  H@€$  H@€$  H@€$0DÞ9D隬$  H@€$  2¿üå/ÅÛo¿]üùÏ.ÞñŽw‹.ºh±È"‹ rªF/ H@€$  H@€$  H`øPX3|êÒ’H@€$  H@HBšW^y¥xýõ× ŽÏ<óLñÚk¯Ë/¿|±ÒJ+Ë,³L±ä’K&¡¸$  H@€$  H@€$  H >…5õùø­$  H@€$ Ž({˜ÁËL³kÓ<øàƒÅyçW̘1£xá…’·âÀS ¢š©S§‡~x±Æk4µçI@€$  H@€$  H@±֌ت·à€$  H@#‘â‹7Þx£àH@lxãï|ç oÄvDo¾ùf%mÒ'íÅ[lÐÓ&­no½õV1þübîܹïñ.3zôèb饗n*ëx§¹êª«Š3Î8£xê©§º†:ÿÃþPÜ|óÍ)ÞC=t¡sü@€$  H@€$  H@€úPXÓ—‡ÿI@€$  H`Ø@Ô2gΜâÞ{ïM[!ªAÔ²òÊ+cÇŽMÇ¿û»¿ðò#èxõÕW‹Ç{,ySá=aÑEMiŽ?><áŠÑõòÍo~³"ŠAP³×^{Çw\bU¯8úÓŸŠY³fÿýßÿ]¼üòË•S.Q§°& ;o¿ývªÿÊI¾‘€$  H@€$  H@€$ šÖÔDã€$  H@>·°EЉ'žX<ûì³} †èbÔ¨QÅG>ò‘´MP+Ûõ‰¨Æ?=.¾øââôÓOO›ü´Å_¼ØqÇ‹Ï}îsÉ{MþÝHzØè¨ˆj(;Üî¹çžâ÷¿ÿ}±Â +ÔÅñüóÏ×_}QÍK,‘êu„ Éû Þjh/½ôR±âŠ+ÖÏ/%  H@€$  H@€$  Hà¯ÖØ$  H@€$0¼öÚkÅÃ?¼¨†¢ãÉäÑG-Î<óÌbܸqÅšk®9`Dˆ{öìÙ)îðT“GζTl}ôâ‹/&ñGþÝHzX”üª}žŸÇ9O<ñDÖÄçx©™›"±[cl ·­•‘Á>ñÒK/U¼ëâ  €† ú:ì«áU=¼~ç¶Y{½áRÛ–C€$  H@-À[ ^Mf̘‘ F\þ /7ß|s1eÊ”¦Dõ’|î¹çŠn¸¡r Ûm¶Ùf =°T.o!¨i%0àË=Ö°šnñÅqƾV˜y®$  H@€$  /¹‡™VE\ËVÖçž{nòºûÄOT&W¡D|믿~qÌ1Ç$;JÒí…@`ôo|£xðÁÓ¢¬•W^¹øüç?_l¸á†ý¶U+ÿpçY­Ì~6ü Ø®»¿ŽŸ~úéâÄO,{ì±”ÙUW]µøÊW¾RŒ3¦â±LaM÷×£9”€$  H@À @ıÒJ+[mµUqá…¦4^{íµböìÙÅܹs‹Ñ£G·.b"³fͪÄñe›m¶)fΜYùÌ7ý'ÀàœUuBXÿ{”€$  H@€$ î&ðÆo1ñÊX/¤¼2°0cu¼ÕV™ßVâb{à9sæ¤E',";vl±Â +¤mœš‰çþûï/N=õÔäu¯å@ݰmóE]”&Yñ\Cèoºåtºñ¶øÆF„½ˆ€Wâùóçë­·Þ€ kFÏn¬có4¸XxøÈ#üã“׫qãÆx§6t„5?þxÁï1÷xvÇ>^kÖtO}™ H@€$  tœ¹É“'—]vYe5†Œo¼1 ÚÍqLŸ>½'TÖ]wÝ´Âk …5¼0 þå/IÆAòËÊ1^Lú3HÅØH¼µâá;ÒÆÀÆ{ÒÊÓn—]£t«ÅË5yèO¹#ÊDÙ`†Å(#ÊTÆùí«¥Cܸר4ÚÍ›×I@€$  H@èk¯½6yaBq%Þe·Ûn»â]ïz×€$ϸë¶ÛnKk_}õÕ4Öš0aBòVËx½—‚¯ýë©lŒa ðÃóÀŠ+®Ø°hlstÒI'¥‰o8û"lb\Êx›x&Á.ÆßýM·aÆFØ òa>BŠKŸ×“x ÒwÐ÷âŠmæ ½E@aMoÕ—¹•€$  H@À€ÀH4jÔ¨bƒ 6¨x—a[¡;8à€ Vzµ0D¡è¿å–[*—bÌÚvÛmD(1 ƒ /ÒaåyÆk FGö>ç…7¶Ÿ¢ ­¬ôÃ`†0wLjj_ˆ<0¢½üòËiÛ,¼û°¢ÿã&”•'œ¿ÔRKU®©€¨ó†tq=ÍJ„,¬€ÃËOy Íyìù+(H&y€Í“O>™” ƒL­ŠA,ÄÀ¦¬¨!~ ‘'êruÖ)ÖXc´mU;†^ÚyfµéPä—­Èh“¤1zÁŠÒ þHƒºˆ¬È+ºâ³Ôe(3à{â¡nb…a\ãQ€$  H@ÀP`üræ™gsx\ ažQ«³E>j7Œ!ðƒlqÕø›o¾yÚJ8>ëÅãC=T<úè£}Æ„÷ÜsOòª²ÜrË5—_yå•iÜìáÍØž­¬ûR?ÔÍ}÷ÝW¬¶Új•øú›n/²Ì<Ës0é÷PÀnHÿD?aÆŒÉÆÄXñz| kŸ±)H@€$  H « àyë­·.0i9Ò Ä@x‹æk®¹&¹aFPQ+ Ð@ärÈ!‡$¯<4BSë>Ǹøío;¥Ãw£6*¾øÅ/«¯¾zñúë¯'±É\<ò )„0S¦L);ì°bíµ×NB‘ò9ÕþG ôï|'Õß# "Žƒ>¸ÏéôXÇÀ¼Z@`rë­·GqDŸ¯©Œ¦_þò—‹e—]¶ÏwüC½SwáÞš>‚¡j¡ûËï¹çžÅN;프*Íè \"ì_ñ¬Zˆv³óÎ;»ï¾{bÉgövÿêW¿šÚiµk]zé¥éUþžv°×^{Ÿüä'Ë_ù¿$  H@€$ Ž`œ³á†¦…±€‚#fÖ\sÍ´ ¡¿™".6ä¯ ­,Bɯí¦÷ŒÿB“ç‹ñ{µÏËç0vdaFÊ|þóŸO^orãe 5ýI7EàŸ>äÙ‡ÿÔ!@ÿÈ û¶(cµ³è«NöUÞ·ä‘FÿÔ¬--¿Ö÷CG@aÍб7e H@€$  t¼ºŒ?>‰-B(‚€åæ›oN‘ÜÔL†Ù›­¤" â@ÐÁ‘xÛ x£AˆqÖYg%ÁK3qàÍ„eˆU}àHžy]ËuapÄÇ` ÞdôÊX+0h¾úê«ÓJÀ~ô£Å¦›nÚ”±áPð'î•ÓÁØ”¯2,_ë„3ÄOÞËÂŒvÎ9眔wÒ®ø~Ö¬YéD.ï{ßûÒŠ>\–× ˆ~p{úé§·ß~{Ÿ;åëÈ/gÎ8ãŒ$6ú¾<…ñW;úAìƒxšÂƈ †Y»í¶[ÚF¯þ•ÿ–EsôOyÿ‹8þ)u>W¦Ø.úVÏvcõ: H@€$  H g°:‚Y“'O.®¸âŠ”oĸ+Å‹Êè[ò4(²}b‹lg´Í6ÛÄ¿-}Ìœ93 dr*¹ØÚƒ ƒQ^œ‹xáGˆC(Ë 7ÜþÿÜç>·¨¤Q†0°ah›6mZqöÙg±ý"V÷Eº|Û‘D='Ÿ|rqì±Ç¦m°¥Óì÷±U^_I/7R§œ—>«¶×R_?ûÙÏ’x)®¡\(` k®§|”¦\G}\|ñÅI¨rôÑG§}œW-OÚÓ¯ýë>éÀ|‘/ÊAÜ”iO¼GÔ„˜ˆvJ¾0’²•S‰›¼…•ô9¯šÐ‡ò`Ø0H@€$  H@èl;ÄD+ÛðÆ¸†1%cQ¶3b|Ón N<ÔÆ™xðÌŠWÖþÄÛn~ú:¶ËbRýÚk¯McUƈc(_­ñiäq5cÎÉ{n]c5ŠC=´âyClaì©#Œ¨”·¨/¶ê2H@€$  H@è,6`ûdÆgáÙ€±žfÖYg~y­Á[hŒ•¢¼Œ‰jŒqÕ‘±âQGU|ðƒLìðQ^hR+oŒ£Ë‹TšñtC|ýI·V~Fòçòɵ?|ËN»>î¸ã £±H¾¾Ú"°áK`x•LaÍðªOK# H@€$ ¶„fÝu×Mâ"aÛ *p@±ôÒK7ŒA®‰€+ßm·Ý¶("¾köÈ :òGðR‚H…Õˆ&ʃQò1’Õjì“~Úi§U ˆˆ~v°Še…Vh6ù$XAàA@à±þúë§m¥„äÆ:8]tQÚ**ö^ÇŠå®»îê—מ<³äý½ï}oå#„D§œrJEXƒ¨„Õ‡_úÒ—*çÔzƒ0A+g" n¡lGyd2àÆç©O;x úÕ¯~•V²ê‘ºôÑGßýöÛ¯j}³Ò²œÎN;íT|âŸè³UåãE:ˆ âPFŒÉ}øÃŽS›ýÖ·¾Ui»´„b'œpBåßH@€$  H@èflÅb—ÖW¶hÞwß}ÛÖ°è…8ò8YHÇÚá"¬‰:e¼Î«•€°&qlxµÚI·•øGÚ¹òi5>2Êk»õ¬°fxÔ£¥€$  H@@¿ fØzë­+âVm±ZîÎ;ï,¶ß~û†ñã-¯.¯¾új:žEÂô'`ìÃ-6B <Äl¸á†U…yˆp¦NšÊrÉ%—¤¯0(" em5„Xƒ•pxs)<µ øALsúé§WV½!è¹îºëLXSN·?ÿãi>á¡õõ™Ï|¦¦çVÛàÁ†Õ€ˆXAI œx²;+üÊvAzð¼Ã>Øõ Ÿ©öÜsϸģ$  H@€$ aK`“M6IFg…•ûï¿?ËÛÝ ïž³fͪŒù€ÇøšEŒíFz€O°†ã~¹ŒôVaù%  T'Ðþ¦ŒÕãóS H@€$  H G ÁÀ–{§aõ«Ûò\ÕŠ‡h$7ÝtSåkâÃ{L_åËÞ`Ôb»'¼´à‰¥Y#^Myäç# a‹«VâöYÇ»Êè*¢šˆ2sÞÊ+¯%W¯J1¬\С7]ØÂ ·àV[mµ´=åhÆìºë®¯=#-åm â@lD[ ÑŸãmˆm™ €$  H@€$ðWo),vÉ=¦0Žd1Cîq¦Vն«,Û%5Øo§ŒçØRŠ#ùáóþÆ‘”1¶“.Ç—§Ë6*õÒlW9nþÏE5üŸÛø¿™ÐNºµâLÖå4#-¶—æßXtS>·“ÿ·Ã³™k°KÐnó6Ü-v¸“7ê!î/ò;P>ÜK‘FÔ7ÿ÷—A¯³Ï'î…¸/`ĽR«Ê¯¯÷¾Nå뛹†vB~óvÍuƒàòoÁ`·!Ú.õA)k«éE¾£N‰£ÝûK5ƒÑ²ŒS€$  H@=H€-—V_}õä±+³gÏ.æÎ[WPÂàäž{îI[AEÑ^°eÐP<æ aÿb_„v„5paÛ)<Õ ýôÓiÒ—8°G0þÎÏ¡\¤I¹b’[F¼ç{Æ«ÄSžteÌÊXŸ1mšM7¿¦ü¾¬ó4©CP¯°e “åð¢NáË{ÄWe~y<ƒñ¾žõÚy¤¬Ôóƒ>˜lVxÛÅþ(ÊJ»ã}¾Õ÷`”­g"(3[ˆÓî( þØŸ°ÑpÏò*o…^ޝü?횺¦n±ÿ°}7÷0éÑα•q“¶@îa>kÅ>Ó)öä›rĽÊû<`s£/ÁNU´cê·V[†m$ì…Á ×qßÓŸ¬ºêª‰}U+ÂDò§èŸ¸6ú§r^óÿIŸEzˆB¨'æm”6M¾±Çq‹éû(+[ØÓ®iG­¶›<¼§"-˜?üðÃ)­ø- ]’7¶nçEûáÕJ¨WNú}¾¿ãŽ;Ò½Ëÿ,¢ŒßF¿‰ðáàþ¢¯‹vÄo ù…ehO^…59 ßK@€$  H`„`p±å–[7ÞxcEÁàŒÿëyja~à 7Tè1(a€RïšÊɃøc!É\XକÀ ‹-¨ÆŒÓÔe ’ðæƒ iòÒ-!Œ7‘¿”±‘5ÎçÈ ãbk0DÐÊcƒmÎe{1ƻ믿¾ÀÝ9£þöËiú¿$  H@€$ ^#À¢&D?Æ¢$0ŽbKãV&½«m…‡Õz“Ìðb"’‰Z>ŒÙ"Ôò€ÀdóN;íTxài²¸,<©Çÿ?øAZìÁ8’ñà׿þõ$úaü<}úôâ¿øEñøã÷I›Éñc=¶ØÿýûLnÿèG?*®ºêª$À!ͽöÚ+yœe<ßýîw“—Õ²p&Îaœü©O}*þ­±q|ç;ßIv޼šM·QéM§X“,퉉å+®¸¢¸ì²ËÛhcy¶¨Sø±-3cøN†vxÖjGä›ò²ý5efPµvŒ¸æÈ#,&L˜Ð²( 6ˆC¸7±£œþùÅ]wÝU±Y•ãÃ…'è}÷Ý7‰ hϵ"ùµ¸o¯¼òÊd«CQ­®ã„ØÙÞ<Í¤Ó öðú÷ÿ÷Ä©VM}ôÑQœ>Gêõ[ßúÖB¢ÚõðØcW_}uo ¾ñNŸHþÿ?l¡wÈ!‡$ïÍØOs¡Kµó㳓O>¹˜6mZ¥迎?þøºö7úª°ÍÒ?žtÒIÉ‹7ùÆNKÿ|ù嗧߆jyF|òÑ~4Ùܪ Ž"oõŽSø-8ï¼óR¿‰¯ZZÄ8k—]v)Þóž÷´ô[U«œy°3ŸvÚiI4•§KÛüô§?î‹j¶DÚ yåÞ‡÷~~}”™;MLæßU{Ïøî¬³Î*î½÷Þ4±Í›f½9`k lÆ–¤ÍxôÒK/M¢š<ï‘6cIÄ6åq=Íù¤; >òÿãz¼´”¯ïêc‚¹¼¥Ùt«ÅÝIÖpF|ðãÿ¸˜5kV]Ôéé§Ÿž¶ ;æ˜còÞS­,õY;<«µ#&å)ïOúÓ$`©Ö"Ïœ‡¨ "±Á\E=`‹ùùÏ^\{íµ!Xä¥|d‘‚ ˆ1?üðä±£žè…~ïÄgœqF$Ä=VŽ;ÿŸ<áu™ë:è dÿÃ3H½t¸¾ìé°O֫ü,å÷ÔoùZú‘‡z(õ3ô­åïËqÄÿ´ÏSO=5 qþþïÿ¾`ë¾fÄ„ôG¤ÞêQX\CŸ…MÁ¶WîcÄRñ}Ä›nxâ‰I`¸ýöÛ÷±ÝåçÕzOz¿ûÝïRÿ‹kËçx úÕ¯~•ò÷ñòü“Ÿü$ý¾~âŸhª¯SXôN9å”tÏ!,iV×7{ÄûõÀýí™káuÁÿ|Ç+òHžÏ=÷Ü$Ž8ì°ÃjŠ$¸'Åýïÿþo¶ÊNa¯"nÒÈë–>ç—¿üeòˆÂvèØ[±Ë {úÄNØ™¢í’缈òÁ®ð\¾o‰ Ñ õ8è·àÃùôu¤Ç‹~4î ÎG¬C=âEÕ­0ŠôZ=’þu×]Wü×ýW¥$ŸÑ7ÓFà’×'öÑoûÛ©]ãUŒúo&p÷ÏÅ_ܧr_D‘ÿÐn¢=ãéK_úRñÉO~2Ù›M3òE&) hÊÞU£œŒíó0‘ã9&mIo§^<ä°eÜx4Ák-"˜»ï¾;Mò2ÄnðÃþ0é8·<™iÕ:2Y͸±=± é³p‡ü1ögÌÏ8±ÕÒÁë‹>‚ ÛlÁ5&S™4fKœ²0ˆm¸«¶:I\-fMYñp¤('ùb›!¼Êbÿ Ü9OGÔ%ù,ŠÁó 6„^ Ø®XÀí/»ˆ6ß|óÔ–¸¯('“él—6"Ø ^™:uj±öÚk¸‚¶‹·“²Ç ¶wâžçž‰û†¶Žg&ÎÅVöîi¶"Ê=G½Dþó›ßô±!& ~Ç—¼^áu‰6ÈŠ÷2õ} ñÑpßµ*2 öÜëäcÆŒÑr/0ôk›m¶YÕûsòäÉ1Q°‚-í€À= O<ôpï5ª`;4îyWôwôsx ⾈öÂ"CLlMWî/"<"Ãfmû—:âþeû@òƒ¨6ä3í±ÕŽ;î˜ÊŸ×:r>åb¥hôåðÀV‡]v s„I°DC[…¼°ýmŽ<¶bÓ‹-ÒBÈ„˜”ßîIDCñ;PÍ£íštÉWÔùáÛh£+®ãž¢íÓ×ñžë°m#êlÔ×)¬¨A€$  H@¨`ЊÑaüøñÁ 7 Nx±=ztå\ ¬FˆAƒ%V€±Ân ƒ*>ì›~ÓM7õYY2Ði ÷øª k(3õ×Ê€·Ì #$ƒTÜÕV€p.b€c´+ƒdÚÕÿû¿ÿ+öÞ{ït>ñ „³ZžüL€$  H@@·`Q ž=c¢’IB<Å2QYmR½œ„ˆk"01Êv͵&€™ 0nc6lØX°Á¶:œ×J@ØÞ;2üÀ>P_’7¶œb¢¶V9¥Çä2¯x` œÁöÓŸþt²kÄ9}ì4k¼3ÎŽIrÊC9?ò‘$¯²e–ŒÓýë_'» m(ÆëÍa°â»fÁvFÚ0¶„(ûì³ÏB[<±PëG?úQ– & Ö@À€w^,vþùç'ÁO´qÒC0ð÷ ¶Úc=ª¶éyóæ¿ýío“ ÷a-› Âî½ÜÓeÀ>Ç}\" ˜# T@Œ€m/Ä |ŽÈh»í¶Ký@­49/ƒÅž¾€W¼‹ 2 –ô ÿò/ÿÒtÑæl`ÃB$rÀTÔ‘¢Â]vÙ¥Øyç“'î߈Oh+£ØI›e×¶z¼üòËÓ%¤ƒ¸¾&e/f´_¶A¢^C\‚p o7 Ù֏ޅ–Á–ôF/(ß 'œìĹ`’­ÿxáÝüÌ3ÏL¿ñ›Åb:¶sâ·qW³áœsΩ¤ÍoyÆK¿ Ú7"bå²°èjÜÏœÏuxRƒUùü9 &r±+0d+á||ÊçxŸèåÐiÖØBLåb êíÐCMb“²¨¶ªþñÿ1yªAìDýF»èöØ…X0ö‰O|"µ™jí›åúÿøŠ0Œò]zé¥i›ê¼íõ·ÜΈ7„kćhàSŸúT¯Ô²¡ á¼’à9{[µ²Ð®ÂpGà¼}÷Ý7ÝKõDn«¯¾zñÏÿüÏI\“oóŽÈáÈGQ5DÜõŽÝƾZ^ñ>E_Ê/5eÁEµkðˆƒ‡-ŠÂv… !÷L'ìU°Ås â?òS­ÅÞF»þú׿ާ½!–Á^W¯¬´£³Î:«âí ˆxØ6«Þ–Wô)õX"î ,}m/@¹­¶ßø,~ÿ}ôÑéú<Ï|Ž÷µr M~‡¢nøž|á5»V¹±oþóŸ/N;í´$&ÊŨåøã…5A£$  H@€$P!€¢ŸU œðRCÀ˜‚úŸ F¶X%À 2{ç«¿âóþ1Î1¸ÿÙÏ~VÉ VVö°Jn„ éˆKjŒùj Ü ²ò×¶†¿€_Ήo0´btbã`Ô¤÷þ÷¿? ’qU‹á—Õ‡ˆµXÙB`@°còñÇŸÄ5ÍÆ» Æ/ H@€$  H`°°haÓM7M•1QÈø…ó‰ÆrðlÁ+®ã{¼S0!Y-°Í2žaCCÜï{ßûÒdqµ‰ÛrlÓÂxŽE0Lè"`BžÉæð2P¾¦Öÿ=˜-‹jjßkŸwš5[ØðŠÉjx1ñލ lÈY"ô`¢œ­ÂñD—Ž^×`3`!ⶺª'x@¨…à ÑZˆhÇ´a.»ì²>[/â3Ä=µD5yÚxŽ!¯”¥Ú½-……Kqs-bD1õD5‘e…ö?ìgQ׈1ðL£z#žndyË0¤Ÿi5à=áIÞ·ÆVrÍði5½ü|ØRŸýìg“·–z¶1„™x’aû¬X,9gwÚG=Áç³­SÜ púЇ>T`ë­—^äö[ìzìÆ´¡cŽ9¦©vñGúD9ÕÚ{œ—Yš——ï°OÓ×U£ÅµÜäßUê6§Å9ùqÑüßK@€$  H@l锯`0†1…Á c[2Å€›ÁÈèj سR/>öØïCß¿øÅ´BŽ& YiƒÀ&^ʃÛfƒ™ÿnŒ‹iÙˆ†¡ ñT§†VÄ<gpÝ‹p+_íCû°Åê«ØKºÓy4= H@€$  H@&€¢ìQ„IËFã"¼½â!#cuÆÌå¸â{&ýsÏ8lÃdz­óãº82éŠ'\ Àä|.æˆsë«“O¶ì¨7ù[/Žnÿ®Ó¬Ùþ%o/ØGvØa‡¦ù"pbœfÛB7ð_f™eŠ#<2ÙˆÊö rþø{DÞÞ°}±Ø' åkZý›v´\ô‚=†ísZáŠ÷Z"¼„äÞ6 Ü)Û}êåqÍæ›oÞgÛúÄ ¹¤^ÝÆ¾^^Ûù#¯Ü®ˆˆd ÚJ½jy·‰ëÊG¿äñ³µ/ÛŠ´°A|àH^RZ¹®WÎ ÖóæÍ«xŸ€â‰Z[‚UãHbçiER-žN~6f̘TÆFä‘'¶Ö)Ÿ‹¡Õöñ•xíÀ–^@øž:È•¯iål>úhŸ{˜-¤8´jŸÃÃGn$­ÜËÝÆ¾ŽÍž‹ð0ï“Ùþ¨ö'úe26ãEŒ²°ýRùÜzy¥ºï¾ûúˆ`H¯ÜqBh™§;þü>q6ºžß<¶l5]äå‹n´ÑF}òR/mú:&˜,¬%ŒÀÛ×ä’,ÂÀãM.hT^Æù˜ aBä¹Ñµñ=â<䓲ñÝp8vš5uÊDz^·xjÅ‹I/roµýà ¤| í7çÖ,¶•Än&ðóóë½Ç.WÎ/‚‚V… ¤à§ÜWÐn›µ¯”9ÖË7ß 6ûFé7úÁ ý`ÞÊýnî%¥Q|ýù¾U¶ü~ä}2iÓ××ñ;C;Ê¿GDÄ5å2×+G¹ýеˆwÍn=ù ~ØÂ)Ïûøñãûx_Šsû{TXÓ_‚^/ H@€$ aLƒ"\IÇ@šÁ {ä² ®P1ø1èÈÀ¶l€@‚±Q`@Åà­c`£8‡Ó÷¸èŘ3sæÌT,Œ1¬NÁM+Æ”¡ €0ªR×!Þ¢.k­ÌdeI>x§ÎC04”å0m H@€$  H@ý!ÀvPlç“‹TØ’y³Í6«:ÙYöhÃ8i‹-¶è3^ÊóÃvÏå13cýóÎ;¯šüšjï¹&Ÿ< ¨,ÀivB¸Ùóª¥ß Ÿuš5¶¼¥ä“Íx¬îœ[m eQ×Ã.S´g~>Û¨—ãbÁXîá)?¿Õ÷ÕÚ¶¼vâǃghÚHä¹Zü­æ±ÖùƒÍ¾VºÕ>Çö„ˆ„E]ôe¼èÇrŒPOœçtñÛr糚g™9 <•ÿæ7¿i©Ïàšh;Ä;Ä5Ø ËBŸ<ýxßNÿD¹xå¡ìY(ÿ®?ïÖô‡ž×J@€$  H`˜À£ +š²°zÀ^ÓwÜqGEhÃgì»Ë¸XÁS^MÅà6ß/¾ZšŽÈç¬Y³Ò®Ú9#ý3 9xb;¯ô²éÊ+¯L.‰ËÜûËø13ˆÎ0µâ¤þ0îF¾8í¬Z`õ «q" £`ig•VÄãQ€$  H@ÀP`Õ=„ŒoC ÁÂÆ;,pÉßãY–‰áxü¬ç† o\Cü¼ú˜eLWŽ»?qöúµf #H;<„´#¸ˆë‡ãq°y0áŸÛ6`ˆ=¦A5þÕ„/ôí–+òy~öÙgßUËG;Ÿµ›ÇvÒªv eÄK ñ†·n<%Óß²°«™[ÝÚǵʶZÿÄï ¯þÚy.ºìO\µ®¥F{s°Ô=qrTX“Óð½$  H@€$ЇBÄ x­9ÿüó+ß寄x>7n\åûzƒ(bÍ5×ìD3xUaF97 H×^{mqæ™g.4îÖAo¹ƒý?«EX¹xÉ%—jXýˆëÕÉ“'§ý×­(a€ŒÑU;¡ð4S¾†xCŒE½!ÔB(S+`Ø@ð“¯ÊDèÃÞçÕ „PÓî½÷ÞTÆr~h#­"n€$  H@€:E€Å.ŒÛ˜ì ož,z™={v«ç[tà/¤¹w<ÞÔ[l€§ËËYÞö…ïªm!”_ãûötšõòË/¿×!<碉öJâU­¨&|A¼’ÛÖZ‰¯|.‹Ñ°‰ä¡Ýz¦mpmž7Ó•ãÏÓêµ÷”ñ´ÓNK[‡G9é'~ðƒ,BÕ³–EFõÎí%6Õ¶‰Èv:˜,ª k— †ˆpÑÁ,ˆqK@€$  H@ÝA€ƒ¿|À‡À ÙÁ1  &$ Q"®Ç“ â•fé—Wä‡zù Ñ£GúЇҖTÕVûDúœË`pÓM7MâøÃ}Ü–VK?®#qäåòÿq^­#ip ¯ÍÄQ>§üÄU>–ËÄueÆåkòÿa϶HÇ{l±÷Þ{'ï.0¬W'q=œXÁƒWÚ^eX…W rñŒCÂèÓÈ0iSÏluðÁ'a åª0î¶ÛnÅ–[nY×å8«p]$  H@€$  ô ¶Vb,“¼Æ–¾x°É·bœÆø«ÑØ‹Iÿ|üKüÏ=÷œâ‹ô½ï4kÚ@Ù6ÀVÎ k¨B›Œ¦šð…­«Ãóo“ÑÔ<­Z»Ê= ×¼°Êx&Ž>%¾î5­(X¤Ç¶yù}€䣎:ªý0Ê?R޵Úi+l‡Š‹=Ë¿cO>ùdØ@åM5EÒx$  H@€$ÐÅ0¦áù—¦xë@¸0nܸäÍ¥™l#jXsÍ5‹ý÷ß¿¸ùæ›Ó"¶éi6° „ó1ðá…n­«‰1ò8c…×^{íµi‹"ÜzR–ØK—22˜B$²ÓÏ%l°AÊ'F_4Ê/""8a´dõ 1cÆäÙ©û¶ H·Øb‹´m'“&ñÔ í¦K>1`DÅ0@<0h% Ρ~>úèbçw.¦M›–¶yb…Œ‰—Wˆ}(#uOØ d¢I»Z þðxÚ[=a°a»&ê¸i ý8—zdEæöÛoŸXV‹³üyZýõ‹N8¡¸ì²Ë*nЩ÷ˆÏ9ˆ´vÝu×òåþ/ H@€$  H k °53ÞFso2Œ«ð.Á8¬¼ že¯1Ö«X,Ãø 1ML â-–-€fŽ@§Y3¾¦n{‡g¼ц¨ÛFmƒ’s×3¦6´GOÏØ"ò€WÝ—_~9- k¦òkËïY…]ˆxâfwê™´[‰{MYXC¿ƒ½¥›eÊËvÁfòøÐCx7ÎÃŽ;î¸p1ÿ~$¼gý}„Ç<Ùí°Óus ¯ã÷»hÜ÷Þ{oÁö‰ô»Íú:Ä8q}­kÖÔ"ãç€$  H@F±Â É«¯¾šÅÍz% xaË öZGH^>˜sk1& Ü /ä1 €f餃8åC)öÝwß—¤¸¿FüÁwä ÇÄ‹èãk_ûZJ/òßW;âæöSŸúTE¨BžÉc³ñ û1“&ƒ:þ‡S£•‚í¦ËöK‡vXqÀ$L«ùÍËEåðBPÃj6SWW¢¾0ÎÀ™´›©;Ò€"'òIý1ÀÅ` #â¦R¿ÄÉ€¸¯<ßù{Vk~øáÉÓ ÆaòÁ !j^å•,ùõ¾—€$  H@€$Ðmwá%töìÙ•‰O&Îï¹çž4¾a1&‹{m»í¶U·é-—‹xY À*c@[øÎš5+ÏÚ—•Óñÿ";ÍšU?üp¥nS·,¬i4YÎ3"„óÎ;¯Òæ¬ÇÖ p!NÁ¾9sæ3fÌhé‹…e!¢‰œ`;vl—šèèn½õÖ;v°f‚Šk®¹&Ùûâ|ì3´Ùnë°ïä¶H†Q¦\|ŸaK¤ßlð2ŒÛkßÓNY0‡GŸÒqÿ#Òš2eJÓ¶¿¡*7‹+±1FÞ©gî1l„”­^ í :üíoÛ°~ÖÔ#éw€$  H@Ft"ºàÕn‘H-Ï$ÍÄK>ój7`ÀÄ«Qh'=„ˆ;Ú ¤‰‘ª‘¡ª»é2HDì2¼^àÝ…×@ò‹0'A dÑÖñÒÄË  H@€$  H × ¬9÷Üsûˆ¦OŸžB0‰Ép{4;Τ)ÛJ…°†IÆ‹.º(M²"`|ef½Óo¾yÝR <Բ芺­%&`r±ÕO~ò“$æŠÉê¡0òbÙa‡’H<í"dXguÞc,ºûè…-°Ëv=¼ò""`‹©x{Æ[4Þ® XìtÝu×~¢®¹ïI‹üÕj'‘V§åE^ô¼š±3²È°Ü§!Dj$ÌATC P.÷`§G;¥¿`1%&üæ°øJ7¶Ÿ¿á†úü>^uÕUÉ#9^ÅËue¡½ÓîøÃ>úhÃvÐX~1{”€$  H@€$  H@€$  H@€:N`Ô¨Q¯Ü'½L çÛ·° o+Û8±1ñæ“ïx)¸ôÒKÓD#ʰl×ÌÄdî=§Ñu#íûN³fÛh„yÝÞ~ûíÅùçŸßgû¯¼ðXKþà?HÛ87Sÿùõ¾_˜ÀÔ©SÓÖØy= „¹øâ‹“€©–P±^ªÎ8ãŒâ¤“N*~ó›ß$!]9¶Ò¦®s1uøë_ÿ:]_¯¹oèýêW¿JÞ~#n<ï¹çž ‰xâû¡<"¬ÉÅ>Ah×á(Ï[…â3¶(ÏëÏñî“oçÆOOÄòÉ'÷/ñ}#ANÄÑ Ç-·Ür!¡[6j§yÙà€ ÏgxT+óÏÏÈ÷ˆÈXX— hØÚìw¿û]ò˜]--ê^§œrJÊk­û0¿V59 ßK@€$  H@€$  H@€$  H Ë0a¸ÝvÛ%ÑCx¨a‹]&ÆcB c<Û4»ý EäÜ<0ybÀã£ÄÇD;“£ïyÏ{Ò¶¾xÉà\&gÂ/71Ø¢™IT&¨çÎ[|÷»ßMb|’³ËpIv:Íšºb;n¶ƒÊ½¥à…‚-…Ø2l¹å–+[l±$J`¢ùþûï/Î9眊àƒóhˆ·†“ˆ “ †ûì³OòŒÁ=Kàþ9묳’Ài¯½öJÛbs!á¾B,¤ÿ%—\’kœ·•ju€ØŽûô¾ûîK[ùÄ9x¡A–êx!xuáþ%~^ˆóÈ^["ÐÈ/[iç–ø~¨x¯ÎEDä‡6ˆí¯ø†°¦Œ›o¾yELÃ÷lCN?œ'Nœ81ÇýÀ} oÚ<}ÛwÜ‘DJxÎöG[Á{ å&pïÿüç?OÛÂtÐAÉó4çáåºü[@ÿÁu3o¹å–âÉ'Ÿ,~üãxŒì@^öØctåBÓ³Ï>»Àë:¢!<}s¯ Àâ¾@|væ™g¦ß>ÚçQï´™ZAaM-2~. H@€$  H@€$  H@€$ .!Àä “à!¬![!ªá=ál°AJð³aûí·/|ðÁ䙀Éè˜p¾é¦›’Ç <Ú0!Í‹‰g&.™˜d2ñ Â|2’ïˆCaÍÂ5ÐiÖˆgðH‚ǘpFXqúé§§ÏÇŽ›&œiSÔ%í <œ ä`{¶…BpSÍ#ÈÂ%ô“jðZƒ€ñÙ›o¾Y9åÊ+¯LŸ­±Æi{.O?ýt%pÌïo eo+Ñøñã“ðîòË/Ob»øüÎ;ïL¢7úîc<!†CX2oÞ¼ä%OÁ[ɱµŠn l¡…wDÑWÑnô­¿þú©¢oB˜„0ˆ¶ÛD!¬À^€è§Ô^KØ: Ï?pF˜"xmApÄ;pË™u#£vó´Ë.»<ð@ÁVeùï "-„[£lÏïí‰ßú}΃÷C=”úØE@lÓ©ßúV¶ƒÂTôUôe§žzjqýõ×cÆŒIâ4D†ä•WÔ#¢Dˆ|F9ãó(GÖ €$  H@€$  H@€$  H@èRLf2qŒg™˜8̳ºÍ6Û$¯ùgͼg²þýïšö±$.éÖ{Ï;{ï½wòN’{bÂC ¯<À+8Äç|pÞxã•z€b^Õ"<ßìºë®Å×¾öµÊuÝʨZšùŒ¶F;¥ÿGL“·£çž{.yXj&ÎÁ3ü;ňôN8á„ä%/Cù=†w^å@ÞKí¸ãŽ©ÜÔm½ °¦¿“€$  H@€$  H@€$  H@@—Àó+òËb&›·Új«–¶Ê‹ÄŠý£Ž:*y#¸úê«‹'žx"mTMÀ“_‡G¶NáúVX¡ LT6šLe»™üœòÿyÞ—¯-ÿ_ëúòyx ÉóTëºø¼|}ùÿ8¯|ì4ëµÖZ«8î¸ã’Ç <×à]å@ÙÉ)öÝwßïLŒ—ËÅä{+œÊéÔú¿œNùÿjוÏ)ÿ_íšü3Ú/åÉC«qä×Ö{7©üãi«-¶Nck¡Ü»GùZ<¤,¿üòɓͶy£Ö ÜÄÏý‡¸‘ ‚juqPv¶ÀAH…0oÿý÷Oß2§òÿ‘F­cØÓÏ D£ÌüùóÏ&ñ¯»îº mgEuä‘G¦mðNÂõᥩœWÎ… ‚¶I‚gÞ^êÕGÄU>§Ní\éq$”?å8óïò÷¬ãÑL›6­ÒŽj1ŠkIYü V¡MÖ å<5æ^|xdúô§?]üèG?JÛœá-D¢ùu´oʉ§(î-¼Õ—rúpÌï…59EßK@€$  H@€$  H@€$  H K Lž<¹`{Ÿ9sæT&ƒÙÞdܸqņn˜&‹ÛÍ:‹x`1eÊ”4¡ÊV*x¯aë6LÐ3ÉHzL¢2é̤< ¶Ùl³Í’—‚ò„nµü°å ÞSð*Àä%[Ù0©ÙNh7.¼ÿࡃ­LÈ3“ðˆš í¦KüdMzˆ˜,Ç#â¼Oृz¥>y1Ñ .HŸtᎠ‰íŽð’ÂýNÝ4(^†žàq/ˆððPפAÝq¯ñ£÷ç“·¨ófÒJö”óøã/ØJëŠ+®H÷0} e¤|Ü_x™A4Áûr ŽÿéŸþ)ÕÛgÁˆë£`Cÿ6zÁÖGˆ.؆6x¿¡½° þ£³ &¤|‘7Î¥¯ktÿ´sM^FøLš4)Ý·Ñ®×\s͆éF0{ï{ß›¶‚»æškR;â· Wû-`ë8Ú,íFˆjrQJÄû[Î<®xÏV^x®¹è¢‹ ¶BCH{^Ñ×…"ê–¶ù$ïxA¢Ð”E¢‹,há†Ýo¿ý"½Êè\pAåßH@€$  H@€$  H@€$  H ›|æ3ŸI«ÓËy:餓’P üy¯ÿÏä.b„LІÀ%&ª|¤ÃdêSO=•ÒC`CzLú3‡ÈÄ)Õ&®›ÉÞ˜¨e/ýÉ»q1GJ¹˜Hgb¸Ñ$y¹\í¦[Žg°YçéÁü±ÇKâò— <£ ¦Aµzà<Ä©hoÕÎÉÓh÷};<Û¹&Ïž8¸Ÿ8vùòtyÏýže¨Ø"¢a²Ÿ:i$À(ÇWþâ„#/¿ürºßhëÜoÄØ‚û¯ÝÐ ì©7ÊK/”mhÏÍ” Fˆ/!8C€¼™ð*·uD”;Ähå﫱D¬ÁýC~šIµsMž6\È'å£]sŸ·èŸøxúé§ûüöð[@Üü°]Y;‚´þ–³^™øœ³@„Šçîq×Q£F¥|W»6„5Õ˜)¬©FÌÏ$  H@€$  H@€$  H@€z‚ÀHÖôD¥˜I H@À0"Ðws­aT0‹" H@€$  H@€$  H@€$  H@€$ þPXÓz^+ H@€$  H@€$  H@€$  H@€$0l ¼sØ–Ì‚ kþóŸ‹™3gë2Z8 H@€$  H@€$  H@ÝF`ܸqÅRK-ÕmÙ2?€$  H@4 k ­&×^{­`ÏTƒ$  H@€$  H@€$  tŽÀI'TLœ8±s š’$  H@€†˜€[A q˜¼$  H@€$  H@€$  H@€$  H@@wÐcMwÖ‹¹jÀ¢‹.Zà~Ô  H@€$  H@€$  H@O`îܹ^Ä €$  H@‰ÖŒÄZfe^|ñÅ‹Ï~ö³Ã¬TG€$  H@€$  H@@wøÎw¾SÌž=»;2c.$  H@€$ÐanÕaà&' H@€$  H@€$  H@€$  H@€$ÐÖôF=™K H@€$  H@€$  H@€$  H@€$ PXÓaà&' H@€$  H@€$  H@€$  H@€$ÐÖôF=™K H@€$  H@€$  H@€$  H@€$ PXÓaà&' H@€$  H@€$  H@€$  H@€$ÐÖôF=™K H@€$  H@€$  H@€$  H@€$ PXÓaà&' H@€$  H@€$  H@€$  H@€$ÐÖôF=™K H@€$  H@€$  H@€$  H@€$ PXÓaà&' H@€$  H@€$  H@€$  H@€$ÐÖôF=™K H@€$  H@€$  H@€$  H@€$ PXÓaà&' H@€$  H@€$  H@€$  H@€$ÐÖôF=™K H@€$  H@€$  H@€$  H@€$ PXÓaà&' H@€$  H@€$  H@€$  H@€$ÐÖôF=™K H@€$  H@€$  H@€$  H@€$ PXÓaà&' H@€$  H@€$  H@€$  H@€$ÐÖôF=™K H@€$  H@€$  H@€$  H@€$ PXÓaà&' H@€$  H@€$  H@€$  H@€$ÐÖôF=™K H@€$  H@€$  H@€$  H@€$ xg‡Ó39 H@€$  H@€$  H@€$  H Io¼ñFñôÓO¯¿þzñŽw¼£Xa…Šå–[®Xd‘EšŒÁÓF¿üå/Å›o¾Y¼õÖ[Å;ßùÎb±ÅKíf$1°¬!ðÇ?þ±xî¹çR[£­²Ê*ÅRK-Õ™ÄME& °¦ÃÀMN€$  H@€$  H@€$  H@͸÷Þ{‹3Î8£xæ™g’Pâ ƒ*vÝu×â]ïzW³QxÞ0'€˜æÙgŸ-~ÿûß/¿ürñüóÏ/½ôR±ÄK+®¸bz­±ÆÅ’K.9ÌIX¼N˜1cFqÎ9ç/¾øbÔzè¡ÅÔ©S‹¿û»¿ëd6LK! °¦#˜MD€‚ÀŸÿüçôpÏCýÛo¿<Ø; B#ëH{` ÷Ê+¯T ¾è¢‹Ë/¿|O?|Wkç+­´R±øâ‹WÊ9ÒÞÀ„UUøÃ*EgÅ̲Ë.ÛÓu])ŒozšÀŸþô§dlb`VÙбÐÐìWº³^ÌÕð Às:Ïh¯¾új¥@ä—^zé4‘SùÐ7è~wig¬¦Ž@;{÷»ßÝïß_ž;™Tzíµ×RÔË,³LÁ‹ßwƒ$  H ×ð[yþùçwÝuWò —~ë ý&@;{ôÑG“]È~ûÛß›nºiò\ÓïÈ@]F@aM—UˆÙ‘€$0œ ` Ÿ?~1mÚ´â¾ûîKbŠÕV[­Øf›mŠÉ“'«–Ε_£lìaˆÀª‰}öÙ§Xk­µâ£ž:Öjç;î¸c1a„´J¤§ 4@™Åàsçw·ÞzkŠ#Ъ«®Zì¹çž kˆ±Ñ´O±'¿M¡"ðû´ÿþûë¾6€táÑ~¥ +Å, ¬6¼é¦›Š‡~8• á3ÆÑ­·ÞZaͰ©å¡/+î§OŸ^<ñÄ•Ìl¸á†i|ÈÖía¬ê¿ù曋Ǽ ý®¿þúŶÛn[Œ3ÆgÏvÁz$  &­gΜ™D5d‚m &Mš4¢p YetaÂxªÁÞöË_þ²x衇ÒbÖr6±WòÝ5×\“žë— ù»¶Øb‹‚y@ñþàƒ¦Åj¶³v©z]·PXÓ­5c¾$ A€‡^60ô ÷ýp)+ûm^pÁir=*c=bÊ¿ýöÛÇÇGÚ?ûC#´ŠÀ Õ]vÙ%þí©c½vާV‡ "i.1AÇÀŠ€;P¼Õ°rØ ¡&€È‰·¼/B´‘¯îê<UúÝú¬2œû•ne>TmÐt;O€6ÈäÍí·ßžžÓÉÏgãÇ0Ïžÿ‡û(Ô?5 €yì±Ç’á=Nâùð­·ÞŠ[>Ò¾ø=gµv.ØAÀƒv¿ýö+ÆŽÛr¼^ÐÝìWº»~Ì$Ð?ôq—\rIš´Ž˜¦L™’¶õñY*ˆŒì#Û?ýô§?MÏU<˘oÀÛ$ÞùŒç.<†ãÙ&ÎÙÔ,ý@`¬ˆ€}Þ¼y©Ñg]vÙeÅÆoœÄ5•ŽñH (¬é†Z0Àˆ!ÀC+¸£Ž‡Yެšã!w8ÊÍŠÄÜ3I”×_}±ÝvÛ¥‡þøÜ£z@½vްä¶Ûn+Pñ3¸IÉW¹7&M&NœØo7ÿ#‰£e•@'ð¬ÂJ6~›1ºñâÿuÖY§«¶mNý Ì)Ï„¼"ã½ ¯^îIÞ‰VoeÜ÷üfóì>`ôèÑm=ÃÐÆ0Æ(Ú8«]Á„=Ú«±sQMÄýÈ#¤ï;TzóH¿‚šßMêœE ünºgoÖ§¹–€ê`K¼‘ÄÖÅl3¾Ã; {[r}*~øM¼üòË Ä5¼'°õ:Þú°»­¹æšiLÿä“O³gÏNcŸÁƒžÇ"À‚iÄ4<›n¹å–bîܹiA¥[¬eãé kº¡̃$0b01ÅŠxÜáqd¢™Ï>ûÙÏûÁ‚„ñ€ŸW:ŸaÃàþ®w½+ÿÊ÷è)õÚ9÷:«d™<Å2’åž5kVeõ1ªUVY¥Ø`ƒ FË*ž Ào1ž*î¿ÿþdáY…í8Ž9昮úNý "¼y1Ìó!žüØó¯ kzâ¶v™ 1,Ï.Ú!¢š5ÖX£­²r¿â¥’vNǨ¿ÕV[¥íö4ê·…Ô‹ê‘bµSBˆG:Û^5B½ó“‡<ð@zfÁë^P8∴-Š“7½SæThŽÀÕW_ÝǦŠ`ïkˆ' } 0¶úýïŸlÌü°¨‹ñìpÔ"Šg{'„¦Ö^{íâøãOâšüw‘çrû ÷¾ÁÁcç \§ozî¹ç’ý—çnú.>Çs’AÃ…€¿¼Ã¥&-‡$Ðx àA—½Þ#ôgïøˆ£Ž<´³å L„yà;:#Ml3ðýð P¯cðài“¤LʱâIú ¨pŠGƒ$Ð]0B^uÕUÅÝwß]ÉX·=« ·~… ÁK/½4¹í®@÷†ˆÏéˆëro«¯¾zÖ´û¬NgûŽ 6j,µÔRiÒÑ{øŽçP'"s*½ù~ÆŒiU4 t €†3lÉxùæíÓF¾Ç›nº)Mæ3®ÅþÆö4xà°æ…W^x!yÉ»í¶[z~ÏE5|çvìAÈã@@¼¶óÎ;wÞygeîç†n(9äôl>œÅmÍÒøº›ÀÈÚ‡ »ëÂÜI@Öàzr½õÖëcÈ䡊‡úI“& ëÕúr-\…@½v¾ÒJ+›nºéˆkç/¿ürZMʪ÷<,Æ_áæ H@­°_i…–çJ 5l5À6P±âcüºë®›¶ƒk-&Ï–ÀÐ@83z‡%¶ãÙ<bÚ2+¸5ì€$ÐíX¤„W®‹"tƶԮà¹ÛËÛßüMŸ>½¸ýöÛÓâ.D˜×^{må¹¶¿qwëõˆjÂÓdäq„ ¶‘€á±chw¹x ƒl?V^dݱ ™€kªQJ@ÀÂ0^²rU\pAÚ÷•‡~VXl´ÑFioà…¯ò ôzíñ[{Œ¤À6o ðgΜY)6+…™Ô`+(ƒ$ V د´JÌó%Ð<&lÕ°]Sd5qâDïù ßH@­°_i…–çJ 5l©Â6P/¾øbåBİ<¿#L0H W° cêÔ©i^˜x>_c5ŠVX¡WŠ`>%  H@Åo¼QÜu×]é8°§8A4 dÁ?‘ùb;`D{¤<Ëç·ò? 3ð‰Tâ&Зm¾ùæÚƒ[é¹]K@ëH×V“@ç ðãÎÃ4*g~\y(ãÅçü¸ÆÃuü ÷×¥ ñòãÊC Öxç3¸I“4x8•3?î­†ˆŸ‡.!ñ@—ÇE9ÉeçᅼŹQ^òÑ(piOµ€ùwä‘Õ×ÍŠàBxµH'šâ!æä™ÌaL>xˆâ¡­:&.ÒapÖl€5|[-S§ë:O»ÞûàñÇ?þ±òðO{‹6¬´ñfÛ@9=Ò mÅ`žÄUÍÅ"i“—h‹p‹gòÒŸ|”óEZÑxPçÒ‹²Ó¾È;Ÿ÷Zˆzm¥sïÒÎáõmy¹½û‹>>¿¿¢m—Û7ìÉCÜkµòí‡cµ@zÜSyà§_i¶~ãwF H@ÝF€þ5·©¿ 6Ø ýF´›WúÍçŸ>3ž~úéôüÇøß¾ãY‹ß ÄÕ«¯¾zÁVÞ+­´RËöa¼S°%8¿…ô÷yâ¡$ 1(Ny`Á¥2ØË.»lKéFø硈¤É9?À<ÈóƒÎÃòÈ#iàf¯¡LŒzˆ¾ÖÑ—ÒŸñ+÷u«ù¥½Qÿ÷Þ{oåRÊ!„>¦¿ró›AÛ¡Ìô« Þ¹¿bò†þž¶£Ük´7ŒCôçÍäƒøn»í¶Ôo’g~(CôUôäƒÁâƒ>˜î+úZòÀ=´âŠ+¦ß Øo´ÑF)ýV¥”•û‡IIê–ºæý8÷uM{ MÊÅ‹²r?Ó¿páÙP­Ü Šq9MˆßîmÚ†,ê›vGÝÃ;DTô'ô-ýioªïj|¢?¦Ìô™ôiƒ9ÇFßþèWèKx6 ceþ{ͤ>uIÂ}MÜ”•ßþoÅMam‹>‰üÒ§F _ü¦Qvî3î7òýý)FYXsl§_¡QünðûÁo xÑÏ’e㞦/mÔgsÏåü¶”}Ïg¿i´úƒ$ n#Ào'}¿3xNi÷ù$~«°Ac+çy$;Òˆ#ý5Ïë;ï¼szfçw¬Ùþõ”SN)î¹çžJüï}ï{‹|ä#M÷·ôñßøÆ7*c~+þíßþ­˜4iRŸò“ÿï}ï{I€T«,ü>ýë¿þk«Ï‘±;é0~È0جO=õÔâ–[n©,Z(ç1¼Ê›Öþç¦ú쯀›çÆvØý.¼ðÂ4Öã™·Z ]žmvÙe—bÊ”)éy·ÚyùgŒÛx®` yÕUW¥t¸'ªž¯x® ­ò»Î³t£¶:Øu”çó¿øEqýõ×Wì´'Ÿ|r²Á‹¶Ž­åºë®K﫵cîÅí¶Û®8à€Òø¬ºãÙÛã/îþ§«îõ­¶ÚªØwß}ÓØ»q7ϳôUñ¬†“çÓþØÊªåÕÏ$0Ö uÓ”@—àÇC)<ìâ’¹fB¸wÜqÇb=öhæ’tE<ÜaÔD|BºÓÊC ?¶  ðÀ€hÛm·­LN62Hg´y` `<âa éòðƒè 7ÜŒ?é¤ÿÿ‡‡5 T0Œ#TÀÀ\ë‚ò11Á ¥Ù@À¾Ù€AŠªFÂêcÚå—_ž l°¬õ€KÚ:£¼üÏil½õÖIhAšÍøÂµ<`3Q“ÕͤS>§Óu]N?ÿŸ¶oþáÈÃj9À;Ú8m‹6ÅCëÔ©SÓ V+ÇÃÿ¤Ç=Ìg yã7¦‡ç0jG\Dà Í$®»îš«Ôy3÷YÄCÝÓþ™8ÄÊ{½6×U;Öz¸¯vîP|ÖN;!Ñ@kHŸI~Œç°f’Ïʺf°ý<í ¡÷5÷7õÝJ—ã¯õ?}ycÒˆ@ ž0Êô'D¿F{§ïæÞif2&&rI› a&å0ì7 ü°BŒß*“]üŽÐW18œ³`ñæ›oNâ›,Fœ0ˆté·)ûN;í”NÍNdP^ú¾ÜOÄWí73Ò$¿L^E ]=“'ONƒa&1š år3ÙÀï0e œôñލƒjüùŒ>n ¦wÛm·”f&góüuº¾ó´yO_†ŒŽ”—Ï(y ¼Q×”cFU­=;qoÓ†èóã7#/K­÷<»Qöf¿!8iöšFçus¿Â=Ædm­6N›áy–þºÙ@¿Í«Ù€Q8„ïõ®áY•þ„çpúR~Kªý~DÔ=÷súrŒ•›m¶YJ¯ÙÉH~‹î¾ûîô{E\ôOü.þ?öîüW¾¤®ÿxƒøAˆ@$q«ì;  Ë°ï »h5b4ÑüÄL¢bÐöUvaÙD–aG2 HT•@„(|ïãð}¬OÍéîÓ}»ïíÛ÷UIßîÛ}Nªg½ë]ïz×ûÔX£Ll"NYåbGôöƒ…[¤‹Œ£æ êìúSÇ1í`®Ã>c{Ó—cö†:OeoQV_ ¬Ñ×°^¥¯çyïú•€ó‘M¦²ßJ§Ó®A¦¦¤’qcâÔ´ªŒ³[”gj`9–¹ö¦¿\¬õ‰na¯°•²àêׯ0cÿº©d›LúÓŸÆEò5%±Ⱥ¹v€6åÜã:†ý@_°°46Ž1_V¾±~9vyek¦˜šæé³› ¬)Iöµqõ¡¾<µxÓ?ö?Ù#ïæÇ‹Nt¸y€Åvi¯;¯LÕÇù=ä}þùçòåËžÆÊ@¿ÉS+}ÞXÒÏ=+?ºÛÂͼÀåþÄ'>qvžZç-z7ÖÖÍ&‹Ž«ßԣƒú.ï!!°+ÌAû¹§ÀÛUç˜êCgó¿å-oÆç)c-_Ä¥ þÆ8öÈ#ùÈÁ›²¨o|jmãà¼qbŒ7ûŒ-WÉøfÌmóô›ïÙ÷«ä]yzçÛ0l2kví:u&Oæ@lÌ)í¸ˆ ›ïe/{Ù #óÆú:ßuÉ‘ù ù¤¹ä"9Ö&æ~¯xÅ+†óZY¨<Ûw6¨ùõÁ;O~ò“YgãEµåcÓ”ìª ¾ÃãÕ¯~õp#Æ¢öÔßüæ7þÁ§<å)ƒí²Jûi«·¾õ­³·¿ýís–ÛòšC9Ö\ö‰O|â°ŽfŽ4uÞ-¯^W©·þæûy¶_[†|]&Àš]n”-¶H€mçh|Ï{Þ³’³B±œÏ(žˆã„™3‡aÞO3/1.T&¬.ºè¢á®ÙUty+7£ÛË¢/£‚‘°,1è89œ­»žÔդÂì:I9*qºûÝï>L ãX^§ ‡9ç¸ÚšlY¨b€Î»C™ñÛÌ«õ QV‹áËœ©óø¨»ü½›ÜhÇw¾óÂÁ¼sê{ýZ¿ ëyÌc&-&¸yÑ?郾~•ÞOk“"t‹´}@Ç¢+8–<¸£Vp»98´WÕ¥‹®A,Pµ‹z,N¹+õ0‰sÅâ9 X;LÞSÎU7}¼íWä~Yr¼Ecà£ýèa¼ì¿7Mø×]”u]Ž .Pè–y ÿ‹Ê£dÇËb}bL^–èúð oxÃà3~O *’÷q··~¡¿Uçí6ÒràÐÄH‡jk‹îSÓ®÷í©õØÆqû¬W¶ÁkQžú%°JPw›ýÎŽ×/èýz•`àÊ‹^©—þ" †~@³()?ûг^ñ]îr—I×çȸÃ.Ö—[;E_çÜãÜõ==¯l§%©+û“mP‰ãT6Ç÷ILæ™æxï{ßû† \úujäE¿p‘qÈ«&×4W–€½J"³ìåÙõDG+'ÛÍ"HÉwûžŒù‰èDmÕÖÙB›Ç;BÚßËF^lDwpÓl¦>Í9G‡šK¸¡C`µE‹[}¾ò`ÿ¾ãïò"«I!!›'À1†´©_¬n›÷ÙeñÞ®"­/Þ8!ØÀ ’ñÄøæ¸·øÞô¦7 ö÷¯ýÚ¯ ~y óʰ­ïÙð‚e•±ìwŸ[[_YÕsÌïu˜€ÆêtT¬ÉùPÙ¸|5­¬¨«ví댗›`V Ê«§5¥×¾öµƒ­]2eNÈ¿hí€<ռʱæxÚűìDë*‹lóÕç?ÿùƒÑ¶¥k¸±¢üZê-_rK^+€Œíþ+¿ò+£;$Uq«ï¬×°á&•oS›˜ƒ•¬²¯´qÛ®Ö ôOýPàý”vHõÒ—¾t¸^•Ü䢭°$~Ó>ʃ)žæüv×yÒ“ž4{ØÃ6ʳòëßùû667·r½¤8ÉXs’[/e5  àØÇz' ƒ“ÄXñ2ØÄ'uƒl;O)†k2¢,†Z .c×¹®'€€aT nò÷2{Ur} Ê,À…Á¶JRˆ`‘׿þõC¤¬óš Œ2¨«zr€–‘ê\Æ…:¸ÓÍñ}’ó'cI½{~ÎYe×mSž±k,úŽÁU“rú_ûª›zâK6”±R1·]4çò2ã§XÎÛáÆµÈ“ël3m»­ÇÊŽ!#‘lµ‹d\3XÉ6(Îä‘¡¬¼äÃãU¯zÕ°XeÁhБޣvUg|´»„—'mÍ™@ÿ-Kò9ª¾M^•i^¿W~ú¢mCc‘vžÚ‡ñ™Rïe\êweÙU½BÞ—q)ûkó³K†Ô¿rª‡EïlØUû¶ü”]?¦Wè”Ò+ÊL.•Œ{ù\É¢¬¹ýn÷ƒUíy«¯ ÎO¥·”ÁXæ¥|®KŸ’˲Uôçp¤Û‰mQr-A—,~·Aʬüt#ýd Õžt–k¶Q[g×Ð.Ž«újSüÆ’²kÃyí>vN}§žÊRLê{m¼N;×ùcïÆök9usæÀ»L¶+?z—yuÅQ}jLt™óšz ù“eɵèîK.¹dh÷’×ÑVò1fkCå¡_”Í«mïÒɾ€@§&²mÈ%ؤէʡ É’ú—®tŽk9–¬·ú`êuë8}E‘y~íV¨,5ÞèØWû©Ù¦W¼W­Z~é¾yóNí;ÖV½ÎØñê`·‹"mßQOå”F·hcs=ÇÐ+ì:©MdÒqxIêT:¦=®ý,?-¨[_^Æk̽û ïìç’qm¦(“mþÍõ§öEù°ÇíYù)›kV]´MÕ«OÈ·6oËÜÖ«ýì|ö9KòQ·V~\ßµ§ÖE¿.îc×Èw!!pœúÀ6ƒ±¥ô딲ÑÁo|㇛ÿZÝkŒ`C ¤æŸ°›nÎuÅ_Ï;»¹ÕÁïÿû‡ù­Ý@V±‹¦”sÝc°pC‹@Œ“ÌQÚ Ùûv”5ÖöÉM›ªËQ²äÀV/“MB^ÊÖf\pÁƒÍÛÖ ç­"CíùõÙ<Œ T2E6Ýðð =hðù˜hv¡y†ãÙ ‚<Ø ‹Æis1Nâÿ«ú¸®Ý§µ™=s0W1~³cøjÜ@á½üë䛾m²ŠÕØû¥óR>:ó0Éî·ú |jGøæÍ%ZŸ½ï^þò—Ï~ï÷~oéMêk§×c7Iì$2Àß_;‚²·°Ôo+›y:û͵9Ö.ÖSe‡mÙ÷¹^§ ÊŸ8Xs-EÃàt`ô0hlÿXFgåÉà0€×öÈvßq fa p¤3°91¦¦®i_Fx›^s[Ê»«›‰aÄQd7 [ÀdL”ŠQà.+Î;jôƒt›ÿYÊ/ÐÀ§Ä `œ‰ôõxe`l8Ž£Šc¶ E')£Æn}ÂC^œScI¾ƒLR*)¿€“š)IyMz¦&ÇË›“‰“oŽ>ÿ{©¯ÄPbð2t íöøÚšÁÌp]¶xázޱEèXÒ~‚NzY;ö0ßm»­û²é[ú‡Åö6¨†YŸ2‰#ãú”ï0e´’Žh²^"}cúV·ºÕJm]eª~nçè2Ôõ7*0±¸mBåZú‚‰§~]ýŒÌ3¤MŒLzæ%Ç+»ë´õ6I"oµÝº;!ýO>\Ó™ë1ªM~ü’ÒqÉ9NÚÅ«Mô´É¥Iý _“º“.ÅZßæoÛØ®eäÀ.`äcI?oM€±2¡:Ì#°”Y=è6¨†lª7™Ö¿ÔÅwœô-9ærŽþ&zz•q£eB‘YŽ ªÁMWMmáºÆ Î ÇÖVw>@£©I}J_s¤£9*J·û #z\=µ5'˜±”Hô;½â\ãÀ*I[Ò¿¯øÿã—v5–è*år-¿[ÀvýÒ=%‹&èÚɹ‹Ò®´·þcÑ©‚jèî²´·~ÆŽÒÖœê]mM0ðšò˜Ã£ìÛê¡æÙ*ÊÒ?zAßâx!ßS’~qتÚëì²^Ñ7Œ­¸ÎKñ9ÉÈÏX’Û²]ÖO鉩º™3lêî"Æhº’îpžàeó™^ñ¢'É7öú½BŸé×¥WÈ<»–mãµJÒÏÙšìKò¦ï˜¸6½Î.7žÑt8gi1ªëë{ÊPÇÍ»¾¾Lÿè•puž€ ómT‰æzçIgëÏ•ÔÓõ}bÞ£‰È„þ¯ÿ¬’ÔþV_6V%ùéW«²®ó罳߼´‰¤íÉßØã­æåywÎ<g·L“§È8væpÆ»¶½É–v`ÿÒß8*3¹#Æt²äÕÊ8Ù³; s=JxQ?/68ÊOP¹dqõ»ñÏøm,VöûXr]snm—þ²ïrÒ_ôa;Õ´6š²“ýY]Ù ÚM¡®¸ëÃô û¬ÆÏUê*?Ò´‹§6Ю›NÊÎ.mõ6} ,A Þ­¼( Y¢‹È(›²]D¾èd‰Œ,oéæKHÌõJ?‘cýÄ.£Óå·2º¦ù+ÎJ@IDAT߆²è+~c¿˜»c¹hÎWeUnºQÿ*_’1…,³ƒénŸ][#ÿÚ–=^ò­½µ?Ù_äOR&;.š;Ž%zÚØD+Ñçx.³5ëxeRï:>ï!!p”Øg¥k]—͹ªÎ2?g“´ºÒxÁí‘2e‡T½Ê×ͯð¢½h»ZtÙÏtþ®Ø(êâUÉc¬) ·_9ؽdê\©òYõý(Yk§j+åüÓ?ýÓÁïgl—ŒÁÏxÆ36>o2?øÓËÛã7ó7 Ža)™ñÜZ‚­ÐÚHu¼wö‰õ*>Ų•Øæ&äU>cóc¶7{T¿ÑOœ×§£l£þÚíÿæÀ’>„/¼ðÂ+Íüà»ÍXkàï«ÄöVO¶Ò"[Ê1®Uýßõ̿Ȇyjk/aìeG¾|7ý²µ ÛÝÎü~g§NIÚɼUÛ”\*Oµë”È臕ôgmkâ#8¦_¼£×- qfs¾›PY¤«‰Œö3!Ó¯§,þ×uç½Ë—¾œWIð‰Û:r\yè_^Úþe±U™XöΠ癨×EßÿÈî:ÉÔêE‹êfÜÔ—ÛDŸâÊ)€}%‹Ô1èÚyú¸Žõ;~Æ:ÜËbî¼ó,Z9Æâ¦v­;‘å§ÎÆnz†îY%÷Õ›N°uêÑ:EŒ©p¿+kÁÇ;=!ŸžU_–]ioýƘ-q̰9<úFÛ¶m@¾èQwµmƒvàdjïë{Ô}ÛØ¤ 浃q@[U@‘òÒ3-ÇúZ_ŸMÿ¿z…=ƦôKú%×.в£8K±ßdb«Ò#÷¼ç=‡~Lvód”M«ÜÆl ¹úuÙtƒrë'«{°3ôº‰~0®Z„·«YkÇ3AÊI§+ƒ±K²Øj^£9f,¹»V ¾òJê*?ŽJ:«¯»þn\å4dŸ±…ê\v‹ödSµºoìÚúšëx­’Ô˼©]LÖnêˆÏ¼¾»Ê5êX Þæ%¥ß}/znYý*ï˜-’qAB½ŒkovbÕm~ë~VíÝÕ-òiÁEŸêô5c™€Á—dGb7 ÎpÜ<9kËK>P¹ÊÃï/Û»žÿç%ÎozX»l{h^¦|¯~l>så6¨†Þb£Yü ÿó|ú?ý×ߘ0åÚŽÑ–óôªß- ÒO›¬¡ôQ²Q6%9£'ò‡ ce¯W0a/Ò+µëaK÷ÓËl«y¬Ô§’>K¾Za.'ÿ^¶äWþ mA‡ÚQÏ\ÑõÙ¶ô:Ù>sàÿXvý²%K+ÛÀ‚›˜}Þ':“©¼sýžS{.fóæ¡ŽÓßµm-ùŽN§¿ÇÊá÷¤8)èH¾•²A•Û|ßx35™Wói·c4ûƒÞ./‹l0¶ÓsžóœÁ´û,+±—¬)wø*’~Là4±f;ð”_± ^6øS¼%¶[¥ÛÙÏzÖ³†9â¼ù ;êiO{Ú`òÁ™ö>È]k#6»åW‚¾Ø;cuSab+òçV?TœÜÀ8¯;ÖM°½á·~ë·Ÿà<› õð‡?|8ï5¯yÍÙ]«Ü¸ÀïÌ>3Ï’µÑY¥Çøëó”ósLì*ݾõeW©¥\!pB 0Ê9Â-v•C\UÊÙ"¸ä±}ì Ç9g,¨‰R_”\“1ÄYÃ8ªdf4<þñ_¸Hèà•Ü/rÂs~2&ÖIŒÎ”âDê‡Sÿ¾÷½ïa]¿3Ô¥5 ë·]zW~ŽXÏÝ¼à‚ gÙ"ÇU•s(£¸5”Ô›¤MOZÚv[s*[,oƒÇ°æ€Üãw¥ š–ŸþdC_p|%Ó6@¡~›òN>•I982‚‘õ±ÅeàLµÕ&}« dhóÙ5,’´ô‰ ö/ÿò/úAÞó’²ù]QŸ¦ÈjÎ>ÿ¯ßq†(l'E,JÑßí"dÏcíKÇkŸ6‘‹ÿdî°‰“]€™€I;rþÐ)‡IÆ‹mR_ dë,ôoB¾L^¼Øk¬_é &÷Ú§]<Ó¯8£¦L&åaîéOúП,HL)»ëYܱpÞöA×6~­£ÇëœÒ§œq.Æ&ÿÆc§ ®6‘5»øT^íoíç]kïâÉùhQªoƒ²£´µÅ£JSÚú¤ôíªÓq¼Ÿ&½r|麓ÝQÁ#½L•C¿¦S8CÉ|%íc^±¬_×ñõîxc…þÎÞ¤ë8ê?Œgt®…zǵI ˜E‡yÉ5دí"°E:Ò"ö¢ºŸ9˜˜¯´wåÑc‚yÚŠy×^ç{zƒýǶjïJ,þ‚•yÕk[-Ò—“–|¨÷ظ¶jÞG}<™b— ¬i8tß>¨¦-#{Âqæ@x·I¾‚u–Ý~ˆ%h¬Kåcl0ïd‡±É[» ½N}ö»¾f,]50«ò8Šw2*0¦‚P]SÙÕ‘}$À¸Õ}™È2»¢‚ؤŒ÷×ÜÄÿô€ 'ýµ’H2Fv•ßM/ìâÖ^ £èúpYÒWnµ:ˆ~ôèy/’-ºOàO¿ÚX¿™W:£/§ëÒ§};ÎË£¾_Ä©ŽÉ{„@œVô}ÙgÅ€¾_Ewòç3Ú|øØ-šËkYb“?ó™Ï#Ûë¾ï}ï;gw”eùœ†ßOkó*7´ó?vM+#ë¶9¿:Ÿg›÷kl—1ßSs·?øƒ?Çz›h×ÚÈ Ï~ö³çúÕªnæ/O}êSßj}çÝZ[Ϫý]}Sýßœ[ßçW\dŸWlKömµ«¹`žvŽSÇÎ{ç‹n¯¥,­ý<ï¼|»NàÿM—ö+«•p6Ü•MGXЪDþ,ª¬üRyxW‹mR‡)õnÏÙÔgN‹²šúÅ·öÊhüê‚éŒ6Àµ=§ÿ¼®ÇF`K[>×µ³îDÖØ Ow%s,J®+˜«•5 l ¼šwþ.µwq@hËy©Úz,˜Ói^: }{^Ùâ{ãÐiÑ+GÁ³®±®^©ZÝ«_Óglãu»ƒŽ4–q„¶¶~Ÿ' àÐÖ¶5†-rî;ÚyºÖÚ\ýµü_eëƒLäÙ.j»Îwì) Ü íŽQx۩ƸÓêÔu®ÑžãzWÕ´ö+»• Ç.=i‰®Ü«N•èpre¸O;­3~•½À× ce¥sŒíøI§X€oedìÜ]iou„K‡¶ºy¬Ì¾›×Ö‹xŸ„¾=¯¾GñýiÑ+GÁrS×`+´º=@Ÿµ¶þÔkq²Ñ'Œgì¶E‰N3hm5‹‚¾éœ¾*ÿÔyˆãúc­SßEuÃÑÎ;–Û› Œ9ÍíÖ—cQ~S~cÓ_q,R|´Ç™ƒ š>@pJ^»pŒºôÎeXæôóÔd̶-{{ƒsÙä^‹’26Ñž•È›6<©\«ý{f·c:;Ó®JûV×¾îúj¯wÈËT9cSôÇê‡Ë(Ù¼UÖÀ°Í÷¦ø5ª|*[]êO|7­ìÖñí»ë±ÓÚ$®]wÎÚæ•Ï!!?&ÀÞìõ*[xYgñ£ÏùgÚEpº_pg»P^Ç/z·£dë+t,›¨]_Xtþ¾ÿvÚX³aÈRkXoª7—ÙóäÌ÷>>þþËeóÄyyÖ÷»ÖFl1¾ÒÖ«²Î{gïõöã¼~¨ß÷ó"¾àÞ¯:ïZõ½›ËZöó®WÇ÷ï®×Öø];¯+#}þù?Ž‹@kŽ‹|®GLÀ€eàâèk“Ζ×ýÀܳîg×äpêŸiîŽ&ÎáU“(e;o´‰¡ÀèZe@6°0Ø?¥Í·ýlÒÒ;²Mn,†ísb8µ 'êªÞ›^HØ&ãhkIåö1 c†?ñ\TW†¦IIû8(rÍÁ¹Î¼¼ÍvÔ˜Ú¿•¡-³ë ¸ë_úžHõÖì:î ^ÕP_Ä%¿ÍþÚ¡ÝK[Yø±¹jržvj“ÅkwÊŽµu{ܼÏΣÛu8kèÙ>ˆg^‹¾ç@êƒ9,@ÜüÒ—¾48ó×-û¢ëŽýf1Ä£í^ÒžG—¶»;øÍˆˆm'º¨¿6¥½WM…bñ{•GRÐýñê¾L§íJ{[$óHV//â6¯­çÕ—Ìîzß^TßmÿvšôʶYn2v‚>Ú&¶@k´¿-ú,H‡m/è uÌ.:‡^kæ®=o `·ö¶«ó§.(8®?–=¼é…zŸ«S£t êˆ~ \ÄhÊox aËU2^ˆèJê÷]~Wwm¶;Åàwæ PÈãNWIl,ÜûÙ3,ºÁ@»™<¯$/ r§Êx»ëïXàÝö‹,Øõ}f×ë²jùØ íB¥óéE27%Ñ£ý±ägž«<É`ÿ*75°ÑúüꜱwrÉŽmçˆô(=Ô¶çØ¹tQ?صÀ [éã±üò]„@„À8ökXcü Ã§$s~>š6;òµ>¿)ù8†-Óë~>ÐecÆÔüOúq§‘µuÖ÷Ë&|á _8{ë[ß:t½evMßîæ%ý¼mÊ.£}>cÿïZM kë¢ÿö66Ûp¬êŸ~kû?_0?¤¹ÊÔ—ëµ:G»öÁåmûÏôF_×± Áþ¼ü»NàÜÛ v½´)_„ÀÚ8j<æÃàUÉÀhPµø¾Ä€2àºû©‡gL{{ý¶ì3’³Î€\†ãSýZ'û¢¼ä35¨F>8µÆ¢ïÔmCÂ9»š°ôê ^L[ãiWË¿¨\GÑÖ8µ‹Ê㺫:ñG¶û`&2Îàµø´Jb¼Úâ±ÏoQú;t9g+Í».g²»_Ú¤Þû~‡j[ߣúLLˆ¼*™ÜÐ¥SvѨsêlp·º”¼G´ãª‰<|ýë_éê\²c±tGÛ¿süÓÛä¹Rè-}ïU¯zÕ°K’ #wëZì'›}~‡ù¿©A5®£þ½óJÙ1ßT: =Žk¿kܲòk·~Ç:S0É¢´+í]}eQYÛßæµõ<{á$ôí¶~Gýù4é•£f;åzä“mØÛ‡¾ß”}ÈQÊA¨¯MMÆ=¶JéeéàÛ¼Œiý¸f>äü>ð°=¯>;®®Uß‹V±¯ê¼y?õ©O [Ÿ·s5cÇkÚqeÓÉu®8¬iÃÂj“Þù¹éko#? z´ü´/[i‘|Ì+ {‚=L¾ªúÀ˜mÃ>aKµã{gëÌ}ç•mW¾/‡|[Ìøö=±3û~ÂN×öSlP²ÚÊ ^ì%ò²(ñçôÁÑc.‹ò¨ßô^7òÝ(Wÿ}ã^RVA4l:Iÿ»ä’K†›ì\* Ù<€ýÛsNÈŸ¥ØeƒÔÁ«Ö”¯¼ÎõnŒ³aÚcÆ>ŸŒ­i,ÿ±sOÃwc,öµœÝXçÆ€²iØ7/zÑ‹fï{ßû†Ç7yŒ-XÐþ”5ëG|[mZ5x¸=·ý¼md~ÒÛUìñž™zÕ×ÍšozÓ›VÒÎiƒÉµ5›—ýÙ—¥å]ŸÍó{ßùZ¯Ûêø¼‡ÀI!°úÊÉI©YÊ!pN[ô¶‰Ã„S¤àÚcóÙ59ÛÁ’ß.Ú¯’¿rM$Z§©+ÿ¯²ýñª×Ý£UÊqØcµcˆÓ—!ä3Ç0~tå«ë8¦u¶×÷ûü®WmkÜÜ9Ø'†mxÒÓÿ¯-ZƒÕïÚH?êw}èÏíÿW)ŽÝö<å§?ýéíWÃç1&ÊÕëFõ¶úá• uо &¨­.5)ô´ v¢G9GÊ9/o×qwÈ:‹…š>÷¹Ï•_ºÞÚã6‘äÇI/XÌ$½Ê­Ÿéœù&ô¶5¶)pÈB™^µl¢¼mëè•öüösµ“;ŠéhúÇ«ô¸~Ù&Î8íãJÚ¬µIyûEêöwŸOj{¯ÚÖ'¡o÷ms”ÿG¯ mz”NÕ/Ù ¥W|GF{G›gÞ.L«–Ø\D_%Ù2{l·¶1[E¾‚ãûù °@<ï<çÒ¹¼íM¾7þnÊÞÁÛ£ŸŒa­Ýí÷¸Ç=&="K™VMvü¼â °¦Æ c噃Ý]¦îеêõ¶}<ù­ÀÛº–ÝN½ÖIdÓøÅÞ2ÞJXéþïÇ6¿ J ·ÚÄYÇ®jóØÕÏêÚ×—16»Z‡uËÅŸÑ/ 0gGÓ7ËôŠEŠþŽlúhY!A/·‰]O/÷mÑ3öYŸi玩€ŸEýÆüáüóÏUÔ£ÆýâÓŸþôð˜`óV»Ð)t›\žS`ÆÊšïB Bà4(ýºnÝÇÖ8¬j{×õ}ôx•‹†›4İï¬íO}êS‡ù#_`ëãñä/ó%·n`ðÓõöS+?ÖvJ¾êû’»úÝ÷}è˜÷¶Û­æs-›1;Ï^‡I®¯ß÷6ä*yæÜU®“cC`›X³MºÉ;vˆÃ¤w‚3¦9p¶• ”ý5 ÀëÖ(§2;¿ ¬qwI%(>8ü>ÿùÏŽ_ÎgÇ ×ñœ~üm  séàÑN üÊénûËu&¬½³Tß]ÕQzn Wûo‘#¸ÍI¹úz«ïºÁmÞù|.“¤VçùÕdô0 5Î×Vdµ’6íå¯~[ô®|ýÉTÉ„OË"Ç|;õ½ÝaâÞŽ/ÊNÇ}à˜}èCvò±£ÀwR`eqk>9µ|Ûñ‰O ã½3î´3:lýÇäœLöA'ë^G^»ØfÊÕN˜Ô‘œéë¶åºçiÿ^ÇÑßë&“1TßJd¹]<ªï—½“õ¯|å+gL=ªã6·¹Í²SWþÝ.k{ØÃ†üÝiÁ©ß3x ôñúèG?:ÖxÔˆ—ETÜÆ&ñ+æˆNà¬ÒN_øÂ†»Kܼ‹:a ‡1»ß1hLžÇÎõݾ·÷‹]êÛóÚå(¾?IzE0‚±ï$éŽp¶ôg>ó™áÅVìoGÑÎGq ó;™±… ’qÃÖ场w¸Ã†÷Ö9ˆG°q£v ¬i†e àSê&PÔ8E¿㳠лÝín[›§¹cS`MÙqê®Në<ÆtJ=âce¿¸£_¦‰x‘…JÚ ‚úÞ;ª·£ØýŽIí9'ùsÏœa¾èNä“\ß¶ìî¸ö8m:¥|,Æ- Gì¿‘vñ‚ܰ[/½ôÒá‘IeË;è(‹ýbI{MŸé¢:¯~Ó«/×wë¾ËÛoYRæ{ÞóžÃ\âÃþð˜)P¨ôXo¬© ó5?p×:?To#Öyyøñ®‹ýübl‘z+:¹×鯢þ»yç÷ß÷ç²o¢ÇLé4³f=ç9ÏæLl7/ba?—¬±ÍyüöØÇ>vö‡Vò7Ïî®ß§¾ïC±Óz`>ÛÚ›‹xð[ð±q^t^ýÆÎ¿ûÝï¾Òc_Ù¨½}(°fj™ëÚy]#Àš]k‘”'¶D€1Ó; ÆÅm¦M@mÇßÞ°h?­Ÿ.JÞøÆ7ŽnõÇéY/FUÏÌp†õ‹Ö§•ç¼zãÖ³s¬ æØ÷óò™÷ýaæå{ØïÉW»x _n[Ÿ¶Ì'õ|}±w¢¶.óävU™U6wë~ö³Ÿ=[$r`ÂæN†M'å㈿袋†@Î|&µÃB?æøßã., ÿíßþí°­”mÙâŦ˾N~Uþ·¼å-ÃÂk›ê@×xÓãú)=Þ. ·ylû³ë÷mBWLÈï{{ïrßÞ¶l,Êÿ¤é•?øÁÃ]8¦Êö¢úoû7ú€Î~×»ÞuN ºëêŸeÒ+þïÇó ²~^±ír¯›¿ò T±#Œ@–*·€Åw¾óø…^NIíGgS0XÓîhaXÀ‹Ýz.«–n6.¹FéhyÞøÆ7¬Ïºl#ÑË‚jŒ•È®ëapR“zym2i±vûÎuÙj½½¦íc  =­¯´õ-ݱÉ6ØÕ¼È€À}ÉnX%{>Ó~c ×½Cÿ°[-*UŸW? ^xá$»yL&q§«7‘¢MÍ‹lßþö·êiׂ‡èLõ##mxSÁŠççQwŠ–=:«Í#ŸC Bà4¨1¤­3û±Æœöû±Ïc èÆ¢©ç÷yÒñí¸?% ´Í£ÚßNúç]c}Ô<Ù"wºÓ†ØBì‚O~ò“Ãî˜íN1äï%/yɘû€<àJ>d¾¾~>írwX{zÚˆÕúáµ³›{f¾Ó÷»ßýf~ô£GwÞtÎ6Õ÷ýØ~Û <š@kŽšx®ÇD€¦¿caÂ@ÙVrMwjµ‰ßÞõ×þ6å³ó[·s8 IÿG€Ñ‚³hq¬JÕ&ŒUwÜz¬–;)ñó[›kõœôöû|>—ùëoÆà·;†˜Ã&‹æYv-©·þ]wi’¹º{¦—¥]+ûI+IR¯¿-f´[ȯZ'þ~W%×éuö²|µ¹EÛÀWÒl…¿M9ÐÇ8ãÏ,º[˜3ߣLª—É[-ž*ùtÉ%— ‹«}èC‡…€m–±x¬ûn¼³«€»ŸÕ¯Ryµ«Q;Á hêëƒ=îùÖÇ‘ÈéØ˜½ªœík{ïrß>y©kž4½"€™¼ï}ï;,Œöý°êµ ïú$]ùÁ~𜠠¤ô9ÝÂ~ñ¿¾××G@ ½B?”Äy§^ÞÛyýÄVþÈG>2ØrìavùQï´t.‡±…äUuXÏÉøäѬœÎí\ÌcR,6³!{î}ëþ¯þdTyð¸–m]³®³Íw²êÕ¦ÃîäAõ;°Ë½Æ’~äÕ&öˆ×¾%²RÌ«¯ëÖöÚ·:÷õÑ_-ÒxŒ^(C7¾á oôcpÒÏÙíí‚$†t­E}°—þzþüÖg§©U7ÇòöÛzÕ%”ÉâÝÅÞ´C vú•Zóú&ÆÜœ'Xñ0»pV¾y}#0¶øÌ.é©çÕ›íÛ/¸ÓÍíX4ïÜþ{ç8· ÊáSîóoÏã·hÓ>ÛÇͺå|œŸµ¹ÇCyÙiš/Ë\‹mP¶»ñ•¯|åLm?ÿ ~ÐÕÊݺõÛ‡6bOöýwŒFl«¾ò‰öç¯Ësêy½è¼±5¨©ù叨çÎúw¥T)G„ÀÆ L{'0IJ­ÄYÔ;fÊ_÷šÊ̘oCÞ„#éÿ0Tm]ÿ|àì—ÚÃ" §×]îr—¥Û½ss 2€Û$Ÿ¤ÿ# oõ5‚ ~é—~i¸ƒýÿŽÜ¯OêÍÜÖX´ë6ö«æG_¬ûÀN wÄ®›´S¾vëljeù[ £kʹ#Þð†ÃÁ²s7ñ»Å×óºÏ}î3ûæ7¿9Ü9lá˜þ2ñlÅpóØ*õ|ž°‘à·MÔc,}Ë]>ÿøÇÏþLÜ‘BÛy‡3kQrwÿ>°æ¨ôø˜œj³uƒa÷­½w¹o/’«mÿvÒôоjç‹‹Æþuå{Û\å/QI«ô+NMzÅÎ-½MÓ—Ën 3úÀš£Ò+}y–ýo|²;‹@– ªÑ÷”·‹½í£Û<¿Òo}ë[[_sÊ&™ËXPÖí£mÉÍï|çáNÏ~Ì?Ìõús]Û«Æm×=s¤zØzõ×9êÿÉqo6°ÆùœÁ•ÈŒ¶™XãúýoæSe+W>ûònžïU5lKŸõ«E mûPý˜NaSÖBT÷ê[Ú}^Ûó]èsú¼×T_†¹W/çô6Ø<ÿ8“õ^Àg¼ ç¾›w”ÎUN6ú{ßûÞ!8I0a_¯ã¬K®!»@Àkli“qÅ4%YpïÏÿÆ7¾q¥e§äÅNnm"ç, êd3±j\tþÔ²O)Ó*ÇTV9g•c›õ*e=ªcÝöÈG>r˜Û¼à/˜}âŸ8€ÍoÇgÇ×ÚÎcÁ/æ¯lÌæ}h#s¸žÅØ.?XÕ—°µÅËtÊù‚¬Û~¯½½vÕw0¥N9&8wt“½%ÀÌÓ&ƒ©Au[É5û-Å ¦"d×I aÎv1¸êÕð¬“ÿq³ ß„ÅóK[ƒ‰áâY˜¶ý‹³¹Öæ8î¡pç@ÜçT}Ï„¨’þm¡ï÷õ{ÿNö±ÚÇ;yûºæÎÞY.`¡2œzj§ÖÙ_×Xe1O´»@kœ¹ímo{,Îq:Îâ°×ùçŸ?,¤ZìþÒ—¾4,&—>´èc{ZwËZˆØÕdQB«ÜÊiÑBÝøÀž=>&§ÚÉ܇MûÐÞÕïZcÌÚß}ÞTß»Æ6l•±ëœT½Â6õè úçV·ºÕXÕVþn̯8ØaLP Y©$@NÙöNcu½£~·KG®p‰ý‰ËÙkN±0ÎI‰‹~I¿xor“›Ìîz×»Înv³›ãø]·æ^£<ÕÆ”ݵé:Sm¨u®oÕEÙíB`zG*‡½¶€Ù~>¨m×µ1É;©]D"Æáy®ß—3¹µ·[Ï]:¿êÛî ÈÆòš¨­ýõ?眤džwéÁØå×0¤#èö¹#CÆ4u$3¥Sps'÷½îu¯Ù npƒ•‚è‡^þ”a×øÑ¯w¸Ã†—Aø—]vÙ è¡ê÷ô¡»ŒC€6•*ÿMå—|B Bà87j׉²ÝéÍú¼¬L|HµëMéEóã¿Í*~á}ìcçØD®mgíE´löÆÎÖ·±¨üÊ+ bêñ}^®Û^Û˜\ úc7ñÿq³ÞD¶•‡¹Ô3ŸùÌÁ×®AU9¯D.{R{ã¶M뜩ï»ÖF5G`ÛM©—~僚 è®z pë‡lLöæ%û‚ÍK¶9߬rÕ{ÿ9e:®yg•)ï!° Çã=ÙDÉ“G„ÀJ ²ýãd¨8ƒ9c}ÓÉ@ÉAÂùé$1ñë\SœÁ­aí¶Nžb„lº~ëä§œ½ÁÃÀé £uò®s*¿þÎ[†ÓE]tbXU}výÝ$ÚDF{þíïûðY½{c¼úwÿý¼úâd2%ðaI_àØ¶(âs-ˆœ}QL”›ŒÑw’wºTýVÝÁ9&T­.5y5F¬ÂÆBŠ»uK‘ :ß]§ÇLÎmgoo"þÖ·¾uöÕ¯~õl±L&¯8X`ÞÕÀòªŒ­ãAÛXxX³J;­ô¨þ×ïjÁ¹g!w“餶÷®ömòÕÛ*ôûQ,Üd½Âù»nP-ýéÕ&z¾t~ûýºŸµ¡ßvÜ5ív°ÍG­[ÞMœGÙ1ÁXUòËF¹à‚ †Ýݵk,0e®aLüçÅ!ÉY9u7‰eev ˜kn¤ Ìe¿ßèF7Z–Å¡~7ö³»êÚ5ÚöuzÛ2n.ËQë:d]²€OæÙ)ôí*‰LèÏd¨[¬·ùë7ï®ßÛÀl.딡Í{Ÿµ;&úÏöÃe]›Âù} ‘úzõ‹"óÊ/HœFž”D&jÇ©²¥é we»Ó𽩝‘=}ž’ÅycQ?†×yý»ë]zLʆ¨d<$ÚEÔoõ®Œôt•nÊâß0.°×%céÛÞö¶Á¦Xtܼߨóíø`þ³Í±á¸YÏã°+ßßô¦7cØ×e[³K6ªœä…_’¬Ô|… @×Î,‹ä­òðÎîv~–ùn×ÚÈú–~å1õì»e ;qåu¼>6/HK}ÔέuŽ~õ¹Ï}n%–Ëʵèw×íäè4sФ8é"Å'½Sþ˜HÀ U†sÝyǘáˆaT_pà`nΉÙ.¢ÝްEÌY·ÙÆUÖþí'Àج^ìía‡-AÈÊl³j<ÓÐèkìCy.KæªìQ;JµóVçf°ìº‡ýÜâHv+Ù©ŒüÑ©vŸòÚFr·µ¶k“fÌÉ&ÙÛÕd¬yЃ4,ðàWm\Áoþ_µ°Uú:ËOßïesW¹¤\!!°ˆ;ÍN‡5§÷n¬µûb¯ÿÆò¹ð û³ `}ÿûß?ì2Ì.Y6þóG|ðƒl¢ò¥ÐÕ÷¿ÿý{z‘/…Á‡_e7n~èC|ßólO6˜@€¿ø‹¿ãËž«Û¢ïŒÉmÝØAìo~ˆUÇšE×i;NÖm9Žâ3¹ÐVÆÚ)<µcÉO•_aL†Ýüæ¦óÖJïz×»†AÌá–]OÿpÛ’œ¶öÀ.µ‘~ñò—¿|˜‡Y“c'Í«›ºN®9NqqÞ"™6Ǥ?ÌG$¶¼›jV½±²®¹Ê;µõi:—NëƒÄWÉ3džÀ®Xº+¥L9B MÀàÌpíƒP pøÀÎq8úbMK ­mrMÆuëTnû\ÎàvÇF2C`S[î]wÓß)s¿ ¨nʹtØk2V{cKû÷‹dó®£ÚHô4lÒb&’ à¶]M0´)¶Ÿ<,Îíäüjäçv"mb ‚¾]´«> ì¿ú«¿:ç1BcÇ®óü-†¼æ5¯™½îu¯&ïîó›ß<{ÙË^6LÒ6ÕßÖ)ß:çpԻˣM&šèZÇ~ûûØçêÛìèÁµ¸2vÎØwQ¹ãI¢c8/¶µ0V†©ß‡,Úµ ÇÚŸîõÚŤµ»J(£ñcžª¯ƒúcéqºè¨“ë[ä!Ÿ-c B&ñ­ÞØtÙNZ{ïZßÖtB¿ÐMwÐÛÛÔ']¯{ô]ï«&rÐÛil9z~SÌýâµ¶nuã¢r«—ÀL¶xéþEÇïÂoô ]ÚÚbcÛ.«ë3ÍÚ éÄ»ÝínÃâÆ˜cy“åâdfÕü‹>sàØä >ŠD¾Éy›È· M%»…j“: ².‡rûÛ¼Ïú97ŽUR~óh7ŒÌKÆi¿÷Á7òbûyçoë{×õ¸W½êU³w¼ãÃã‚/=¸C–ìAÛëè7+ÚEy ÞjûÜX½Œ)î˜õèbzå$¥Ú1²eF>¶Ý‡1Ò‡ÈÝ]‰¼j_Û2Õï»ôNf°jí@²bì\§ìä¯e¡®l•~¬Û%)K„@¬B€­Ö/|9í{Q~w¾óg·¾õ­ÏÑ•nŽzÅ+^1ØG‹òaC§-þ·6 [K d°0V;•ÑùmzßûÞwÎN’íot·Ý¬_øÂ7/ó+¶çöŸù¦Ú±†Ý!˜×{Ÿ–Ù,ýñóþ?NÖóÊ´­ïÙµü¹v%‹ÆpsH8ïçµü›c÷¾÷½‡›5ÙÕ•ÜœÀft5o®-xŠÍÿÊW¾rvñÅÏ^ÿú×_ÉWºkmDæÿüÏÿ|vqãé˜,šÃH{Ó›Þ4ÜtSLô»p‘ðŽw¼ãàëmYj;A:|…‹ú]GÛÒާ;*P®~_ônNÐ_cL§-Ê#¿…À®ØÝÛv•XÊ'˜Gò]îr—ÁP-ÕÉiøîw¿{ˆäиóªëp×»Þuö–·¼åì ä¿þë¿î„´Ð;ýÎxB?˜Y`pGjɉþ©o»3wÞc%ȘE¥÷¾÷½ƒØtõɧ‰Ý%—\2,bµù—î¡Ï˜ïŽÛcwí³I‡ˆ@…Z¢M,Ýé{§;Ýiá„J}è`mC÷–.µB'Ñ?‹tCËc‹ &·•œKÎâquÍ©ï&r&‚5î9sŠsWû¥òõ ÊoÒ˜±¨ÜÚÖ⊠ó{ÞóžÑðmêñGLºÉ[%㟻’n{ÛÛÖW[y?ií½K}»„|qF¶IÐ Ûàö·¿ý•v+k[÷ó>è¶û«w~OaÂîía‹ƒXÆ«^Lɳ?Fùz=/؆~Ôo•›Þ1v ¶Óeë\¯ëlS¯Ô5V}§{gž;v[X ðRï60`Õk,;—b×Þ  -ô'ÞM´ï¢rÐËêÜÌÓ=vìûú¢|óÛ"çX_äžz]7\è/vèv'ã_ü⇛1ìÓ÷6omE¶?ùÉO %ÓæVÎeÛŽ-´yTRýw©æzæÙÚœžh{ÚóÛÏ®oìwì¢þÙžÓV‹æ$m ãÌUÔ•=LVmõQ_2¥¼Ó[lV oc}Ëuµ‰¹¹ðƒÝÇ.¬ù&{…,ñ!¸Ñë%/yÉY[Qyø ;fß’E2ÆFÔ>y ‹lÙ‹.ºhãÙ[d|ö(?0›Ìñ싲å‡LþìRa¤|½øÅ/Óí¨Ã~V7¶®`!Á7} ºÝh0\Ôµ‡G• |7v=ù –3/¥êzŽÕ´~¸êú¯5+>A}üÇ<ô¡1¿8×{¯«”ÕÜ¡×iu|ÞCà$H`ÍIj­”5IÀÀe÷Î>¶Jœ}åëžÍ5ˆ;¾(k6°3n¼ È‹v(àT2H3R ÂeÔ0zDȰ-s|ô(Ǻ–Á^㺒²1Ð]»ŽÝ¥wFç%C‘ñ$aÈØ`˜â_[ˆ÷åÆ/Æ?VóÃ~«<_×0‰bhÞæ6·¹Ò¹Œ&CË"½;jýŸ4€¶ ãúQkì >%Ï8®Å‹EF¯«igíAöõMòÒöÃi%ÚþQÊdâmAÈ•È +·ÀQýZ½æ&U&ñdLò»þß:‡+¯uÞõ'm@ÖÇ’ßMÆØbô¤$:Ï›ßüæCÙñ”ȘmQõuwÕcÉÚz©³v±ˆáXÁ8•èzã‚£©‰\šPµ»ÞصÉbѶdÕ˜¡ÝLö¼”{lÞÖ¡•9w'•3Ç1η}ò®&í]ã"} icýÇøMzÇßËq!Ëbn›Jø™TÓw^}[ã­ ]ß"žÿ%Ǫ}AF—¥ÓÔÞ»Ô·«]ô-c~R2¤ýÙaô·@<}~¬’Çj{¿÷rZ×èß÷A¯qÜÖIXW°½m±kö.Çs©í5èxÌé ¼ÇÚÅñÆåZpuޤ}ÙÙÆ€1禲˜8FP¦ÅÜ*ßÁŽÿÁU½Ù^UgÁ%n( O9ö´Y1sœå…·>Z²ì}¬ a°Î>ä,}.à±[]VjL_”ÏØo½;ÆwìÐÚ¨gP¼¦æ1/ï©ßɸ1K®60?±€2f'k;r‡SµÇØuÙ¥¸ lƒˆì$Ƀ¬—L´yhs[;Ðs-+}[ù¦< Ï¢‚1Z_i»@ÞØ`ÆQ7˜«±gJöª,¥C±QýÏâú6 ÛÛC=J´®Sï5×öû*Ër¾¶"Ct³þêÇÎÖ¶Õ¦»›ØÂ™ÇP\ñÿƒj*¨œž„DNµ]›Ì+°&_ô YÔÏK—”^ñ^z¥d™Þ^¥–¾&t¿D¶*)Yå³ÕÚ2û¬o9ÇX ”iQYÈ'¹v^ÙãÊ_mÜç_ÿk{íËÏP ;õÙ¦ÖIÚ¸†iéW\ÜÙ­\äS[ŒÕÉñ5žaµ¬ë”/ç„@„Àa Ðçt»¤ìE6Nͳ§äoq¯{Ýk°Ù•øHاlbü2ÿàçá£.}_ÇÓ•vŒÀ0IoÓÍ‚ z›ˆ]öGôGƒŽäBóQñsÔ¸¦Î®c.Ä^(_eYö.š}¯sÍeÿäOþd«Ù'Æ 6 ®Ïþó{kY¾Ë~?.ÖËʵéßKþ0}Á ^0Ø©|âle¶°1{mgÙÊ/{ã1yÌàšW.»Ö°­#ÕXíX»äøŽíÀ?ê:Ö:Ô¶AíŽ5Ç"ƒ}Ú•62÷×§ø9ñ„ÙÕ'}gþ ²ÕÚ¤þúgY:ÿüó‡>ÈoOæKðÉ Úѵ›¿ƒ¹›¯™@—Oȵü&1Ûª/K¯«ôkò›«'•ÿO"ÖœÄVK™Cà8üàd»mÀÎñfÁ5Tƒ<‡_-’0²9ÞŸ m ©Œ’E‰£D`•¡S‰AÿÖ·¾u0,¶`ëzÊc0wç&c¢’Á›³NžcFR·‹ïÊΈLdѱœüŒ$F£6ád¯Àõs ^ SYNµ±äŒ+F&#¶’¶ÃÛµœÏq&ÿ3ŒLv,†–ãU>ÚÎyS“²Ê«mçþ\õ°ðÚ&ç1&•a,) §™Iå.&F!£Ý6Œ7TF¯ œ>åñCœèÚ]û3þõ+/iµ±~æ¥o˜ÄzÄ#q%çí®0Ð_sÝ’uf| (ò<[“²¦?ÓŽõ.áf²k‘Öv›HXêG5YËSÉÛºi]9'ûÚužœã—‰ÆX²°cRdÒXåWOyÚ-‰žÔúJÉyÒ6õжoº]ïN‡Ut©É˜„rPc}ÓbÖ6’:ª³»*”×$Ó«dK=”¡ê }”ÍäÏyœ1ƬJŽw¾;¨v5)£vTÎvüÓî&Äú“‰¯v¦éãƒÅ,²ß壟¶áuëlb-ÔØãÚµ èdÛ5”-áUòázôžmhÝI½,ÆöÞ•¾]m£Mk!Ù"˜>%“8³è㇤~祽½8¾èz‡“FPé”tÒõŠq΢´1m„ᙃ@öçUaÛ‚UÙfœlµ€¨ßk—ê{lCßÑÃ쑱äÆö½þ\‰Þ Kì¼Wö§ßèã }O‡j©^['çðÃþÁK›/0’°­àPLغô™zK¼ûÞ;ý)̼ô küÁ|Q¢›9ÒË­–¯v°½ÙaQ^íoÊ«të”d>åU}Ùùú§1æ¨Ò<·BÆÍ úªöRé²È!/ýlžŒ;G`s“qA’|p¦gŒCŽ1WÒ’~d 5v±|®¤o°ËÐË™ÐWÕ‡Í[7R8Ï)¨K—'þ5/ð»r”½â`§oÊÏÜ}ÝÀó2¯EI—3ï|å¢çÙ™lN wÎzÿ[dáP:D •þ -$¿±\__Y%aն󨹮SrP¿×œDKä.Ô÷Ç’¾G¯°1å%‘1ÁE^Î/ùrzùž ûߣôŠüè×›W¦¶˜Ypb뱫_ë#æúä†?¡‚kjN úœÕxm¬&—Æóö¦ˆöšõÙùæÚ‹üjå§GÕMùõ“ê+®C´ƒ>h1¬í_ÎãK¢S×I®GÆ´…úW2n¹&ÆÕÒñXÕØIîÕ][Ð=¸&…@„À® çÌ¿ùÐÊöfGÐÃÆ‘)Éüä'?y8ßøÜ9È“-ÖÞ|5–'=-póYÏzÖ`‡ÉsJâëçÃúÀ>0èÜšã”MÐî‚,?ù²óìNÿ¤'=iÆZ'Ñéì'ã]_×eŸõþhcQý¾ÎµÚsŽ“u[ŽmfûY?(™ÄÙkYb븡XÛà>/ùíiO{Ú¿1½ì-Ç“/öÎXb°Qf±¹ú´+mä¦wAèn:/;šíR7¡öåö?ûJÝžñŒg ¶‹º.KŽyâŸ8Ø~æ&æ÷­íØÚOËòbë[Sú¿y0]Uóy³·jþµìZù=vÀøLr×Kò…@¬M€QnðöTº”þàpÁÝ«M¥—Rr¢OMênQ½]t=NñmNŒ*ȤÚÙ‚”¶ÔæÞÕKÂÃd»¯wé6 kw9Ydtf£Æ^üMNq¨;JÔYÿâ *Ý¡^Æpmkò+8â°‰N3Vs ­Z"—löyk“vÒF‚ps¦¤ÓÖ޻зûvѾî,Æs¾T"cäÀ([Eÿ×÷j#Ž!w{ØÃ&Ùj']¯Tû Ù¨ë&6—<ؾí£þ-¨CoÜ[]‡9;ŠÓ÷eAýÙÞåäb£øŸ^gûÉß8®Ýõër˜ª]«œô Ú]Ot€:S e‡(»zâ×ë®yõ†CИ'8ƒý¢-æ%öµ ¤vîãXü<âÖkd¡XÿL»,雂¼Û9‡±Á<Šìeª ²eŒ®„»†³—Œ{¯É&V«È¸ñI?b#isçWb¿˜‹‹ØØú‹±RYô»v.ävR~8vjR~v†üŒ¿­|Ñwîõ*[ÆœO}Ù‰Êë˜Júäa’6^ÖÎ,;f^èíJ³rÔÓal^ósu¥OZÆÎÕV:Ö±S´±`ccÒ¢Teªcô…7¼á €º^@IDATõï•Þéqýk^0°º(3S½[)3ºµÕáWº@÷…ëY¬ôb›²›\cQ²c»Ï¸Ð.¨+Ù2ÓÈY§»$e3F“Iü¼cƒöeÉyò¯]Šô'×ÒžÞÙúýêZÚ\kÌ©üG— ŒqÞºI;Ø%e/Ë«(• ‡ÛèeRwedkŸ9lM`ͺ-óB ¶M€/”Ÿ§Æ¾rs46ÂÔñÛÜîÙÏ~öpޱÙXÈþ¡ç%6®1É8ÅoÄíó²1ªÍ®Œc,2Ÿá/míœ:Vžô´qˆïÀØÀF©ëyW¦ú¿Î÷n.k|° ˆëÖx×Ïþ2öºÎ¦Òq±& -ãsûÿ¦ê'>Iã¬àöñ¾cõ×Ò¶å;~ž0Øúý1ýÿæpdöµ¯}í°ÎÀVoÇùþx¶93Ïqƒ*ÿü<ÿÓqµQ[fm#Ȉü½îu¯lJs¢1ŽäÔü¿˜ßx^ÝÚkÔgçþê¯þêàC4ÿ47f«ö¶Y_ﮫ;¿üCôι"Ú¬íwt™ü’B`lnÔØ©CœŒ †ÁÌ–Ô }bì26‘ øPÇ©|ÛÜ÷õEN(F¢…xŽ,ÆÇIM FÁMqÅ)×N,°0ÁiΫÖoŽ*FnäáZuçêX¾œO&3v ½J`ü”Ñälìš¾k­þÌÖɳÏgÛÿ›t2rõ1ÜÉs[/Ÿ9#½®Xó΋m×aÕüÉ YÖ§MZÛ~­¾ô‹W›LZÝéIÆÈ©…§M%m†¾>6Oi'*‡IÛs}³•—±ò);§†dª×ú GKÝ™?–ÝoBÆÑ`‡‚U’EŽtgÉ„ kþ£Lø[|jÌ–]¿ÆüŠá²sŽów~‹¦úUË\™ŒÙ°Æ’6á„"ã\pÁpÈ: Vcyû{ íâØØ±xs¼UPM-ꌻì»ÓÐÞÇÝ·û6 K9¥8Í,ŽÒ)í8ìsgý¹«þÒõŠ€v©øÃ¤²Ý8ÔôY\Ú13ݸ6ol›rmMAÆe¶`9è»È'ú°PŽ<»zÐM'!ÑCʬ~l³Öæ^µüÚÄ"¾ÇM?9ý1e§Ž%Îß±9ÖØ±ÛúÎÂIÛÖÚòÌÁ"²þ}Ô©•qAší¢¾²lBÆåcþbüÓ.vGéíq×dã5–œg æÐ—À‘U“9«Ù\üéÐ^öÖÛV-‡±…]¬>cã6›Üï«õe ûÌÏÙd˜¶zËwý]ðìå2 ; k§U~®ÕŽMSòpÞ¢säÙÖa,O}ÈøH¶,ÈsÝdÑÁ"½oNÅOƒÏ¢E ¿a§?×i«Ï•§lµ6¨nÝ2.:Ïu½ØS’²[ ¤ènòÃȞ뙋ºã›>qãÛ¶‡9‹W¿CÁ”²æ˜Ø|ô&;´ô›Ö<Ûœ{jb <å)Oü@nʪàoö*?ž± $O/úÙ<‡ßH`½1gÄ?j÷~æK/½tê¡«]³®'’]Àvâ«ò½$è”7Îȇ}U¿-+‹úþú¯ÿú0ÞÔiòªë²K]W c7™Žƒµ¶Â‹œ`$ˆ³m$mù;¿ó;ƒë&K¶ž5 l‹/r}œkÌ_UŽï:l bßòÊŽ%—ü_|̶Ìj×eé8Úh¬Lú1»ÒMîæG|ú¤úµ}Ñn—|à»}jh¯§ùÈG6»ÀlóY>¶º6c³Ñ0•¿9 {Ôœ‘¿W9ù~§^›ŽÒN•Økt™r$…À>H`Í>´bêk0q¬sÛ)ÄðŒ 22ei`7¸VÄñ¢cÛß\“Z±A\Ä8ƒo‘ÃÙ n07‰ÅË çä<é QP7"‡Œ™š(Õ±xhƒe‰Ñân;ïv‘áÐmšöüÊWÛÔĉñÄÑ—4Žî^~ô£=LÅ2üEÖ·W`¤’²a1hÝÉk›ç6?+/ãúñü°•mK;æ°f ›à˜(s›è‘÷)ò<µÕ»¶N^¿ÕÂàIÖ#ô¯EBw ¸s‰Ãœ3y‘Œi'º D&›«™Ø™äÑ'•LFåwX§xå7ï½d‡ó“¯±sµ¹I¶z›h[¬0)ôýIH¸rô¨ƒ»¢É³qb,U;GY\œ·EîX‹¾ÃL;Xœ7NÑWäL?ãlP˹³j?­í}\}{^»+9ÒÏíüàÎ&ºf‘ È‹,r¢Mi÷}Ð+ÙL›Ð+¸²Ç8£8»Ø8Íëw˜ë3˜O±Øyò3~ÐcÎÓ©òÕþÊeÞÀ¡FŸöÛ¶+î&c#Ýé½eH¾½È«ï‹q}ö?YwžwÿW2_Ò'ȸö2ïbÒ®Wr›gTb[ž9pÞÒÓÇ‘JÆÙËvé¬ÝÖ0ž—ô-²Í>ž"ãò¬ÁùÌF´Á/ý5ï:äÝxk5v™·š+¯›œ« ôƒàöZÍ}[yêó'“æÊb?L[©“Å ú[@Ù­D~-P ˜;L=µ ý Ê.u¶¿¹¦ßÙúK-|`ÅÔv­²÷;½,¨¦µÉÔ\«£ºWýõÃúLÎÖmÏU¾‹*ÚžŸ@>‹’¶\£OYl@§L|+‹ä«òT^2àzÆ/ß-Kä‘î,ÝXu[v91žè“OÙäxm"™Ó¸;;ö˜¯,ãPõW®)õÞD9“G„@¬C€ÞÄ*xµÆ¶8=G¯®šøÖ½ŒOüòt&I~ÆþwsóycÃ&Ûæ‚ƒ`e…ºâÀ6uMc–ë¹ß ñ¥×ÇøµÕÛØ³llìËʾëº|âz7†²Gø&Wͳ¿Æ¢ÿ’µz²]JàŠç6í+öƒÀj/vY2çbëjoíJvÙz÷m»ˆ[û$;^æÆìi6yUsS¶¶ë¹îªé(Ûh^ÙØC×DÖÍÏõv–6T?ýcSrj.øØÇ>vö˜Ç"›ê-hÕ1„,çèÍJúå*ü”§¶š8‹–%ç zÜã7ô+ò¬o)WéqõªTc¥1¶dœÜ·×&cdmÕD†0$œ®·¤œ^ÅÛÙœ¢¿úrW{w[‡ãèÛuí±wc >d<£k8^jQh3í¯ïéd›Ü.·]ï4ê•1Îíwl7Á:ú2æKceÒye;àNvÙ©ú‡â²äxz[ 80fW›–¢G÷Ò'ÊÂ6)½¢Œ­^ñ›ã%²íšm"#ËÎk_õ³úXd½ä’K†›è,uÀÉÂ5»—žr\û¢_ñ6Ö°e°ãpÂ_"»‚%j7ÍbÓ–QÿQç±ßÚãVý,‚N^–”ýŠƒÅ ’rœ9˜¿™Çg*¼BÆÝåŠ5î5¶+kɹ6ZEÆ«nÚ™ÍG~ÙJ‚¿1Ѷ5Ï-½EæÕ×äÂØ¯6i':”ýi—';jØ©±d‰ÜIê« ^äFŸª¶Ò“ØA,FèkÊ€±º±OâsXUfyélzË"‹6•7;…P'sïÕ÷ýÞÏcè†e6›óqjuÑa8Õ¹ä†=3/‘uÃ.•È‘²¸ ¨æéd¬Õ+>ÓådNñª;…Ëžâ ðÈXyT>óÊá{ìÈûŒ®óâϑ땜;Nk¬ö®_é‹ô‰y'9qÌ¢$Ÿjgå·€F²Á]K=ê½®I¦µ½kOô{vð²k-*ÇØox©ƒÇTÑ+5/*{Å9®©\ê¯LÚš/Æç¤Øet¯±Ç¸*Õâ;=¶®>¥ +¨à¨êîšÆ¯)‰ÎÞD¦±ˆ­áué¨Xóý”¯õ(ëéšGqó"›å0Áà‹˜U-*Žì¤£HúûÏkÓÉ<Ǽ«ô•üëÉ›¾Vò ã"p•ƒ‰ÏLxEÄõIgö ê¤Ø5­Ìš_|ñÅ»VÄ[NΑºÛ‰#¢œ!tÞë,”ÍÂùâzÚÕbÄ9çzŒÞÓäèàˆÂ3ŒÓMÂÛ‹cÖbãg„5G §2ÇžÅUy2¤ÖYh]§§ñìÉ6$î>30õ-ܽ´1¹·p°nï[uU·º+—Ñ—Mø9TMVŽ*Ñgä]ðž2qÒÓ)'™ïkWzƒloj|Ög^óš×œ³;‘ÅÆç<ç9[c”k—œ)ƒ~îµé>®Î§µ½Éí¶ûö:}Ãb…hº¦lú†LѳÑ+Óéëk˜³Ïé;ýŒf#[Æ ó±+–íI§Èßÿò¥?ÝË·ÇòÜ•ïìÒÁŸa§}I¢/[€&«S+ˆÆ¶ù‚"È®„¹øúЇž ˜’ßQ£Œ`̵Vå€1™'‹^ú™úzéóUÿUóÍñ³Ùóž÷¼!ˆ ¾XÁrI!°KžûÜçv}™N²¼ ðþÝßýÝÁ'C¿I¿ñ¿1¬çѵI!»Mà÷ÿ÷‡ù$;Mr“Çþán$pl×jnÎÌV0ï’Øþ|uÒç»Æ:å9>û³Òp| såØ+8ކ©ŽæÃVžs…“åÌÁ]kI?¾ëŸ“ÇkÓ k.Ž?¯¤£#€=CrʇGWªí\I]9”Ïì@Ÿ¦Ï8ñ½ö=©«Å ¯m$NrwÀ^qpç{%‹Pv=XÇé_y¬ó®® §Ü­¿Nþ»|Žº3½Ü~É‚Äaïž_¥Ü§¹½qÚvß^¥-êX ¾×{÷`ôJ]þ^‹¡Ûè{tø¶lÏå5ÛÞQí°d‡ ªÑŸìÎ!(t•¹Yˆc‘Ú.ª% •9 -ïR²ÐmÌvóB%v(û ‡]Je; ÀöÚV¢»ô¡mô£UÊl=ûÔ<ÐŽ^ÛLäkcÄ6˸nÞC>ö± A1•zŸûÜgØ5lJPóȼ;®Ýàh±ÔŽJt–ä]¿¥gØ{«&r~Ts}²L÷íšþìæßæàÛ¸{ÕvÉñ!!pôß‹ÀɲC-^_p°#]kC6ç†@l’;–n2o®$×®»6­òå=Ö!°[•ujsB B B B ¶JÀ¢¡Ç÷Y—,"X8Ší^·Z±d!pl¢WŽ ý©¸°2ì´f§‚J‚i–¬XQÁ}P§q±î<¬ëìÂû×¾öµ!°¦ë+èù¸‚2wIʇ%àÑOv²#K%AR¹NŒÅPA)}@Žü«ïÖuò!!pº <øÁvØ+ _øÂ†Çif¼("y8nv¿þìg?{ÖVfã>ð\首ã®C®S$°f ¥!!!§”G;g¿ô¥/%`gwý¯³ˆp6“|8µ¢WNmÓYÅ=êÇ«M±½ìd°j²;M=V¥=×îmÛÚ-®½Î*Ÿ-ÊÛ­F@%5ég÷£¤õ­ óÊA°À»u’Ý´¶‹¢ô“›ÒW×!šsB B` ÜêV·šÝâ·8;æìîw†ØßÚ§f!'ÀûßÿþsqzÞyç »m­k+Ÿ„:§Œ§“@kNg»§Ö!!!!0‰€ÇI|õ«_(m/_Û¾ßæ6·™t~ ž@ôJO$ÿoš€Åé>€F`Ìw¾ós±§^×Nv!»•騭b•ÇJÕ¹Û|ÿ×ý×áñŒÛî´£ÆÏýÜÏmó²É;öžÀ˜^lóßÿýßg97‚`=Áoßüæ7ÏÞÕë\úD`M¿‹ÍÔ|s\„@„À~°kðE]tN@÷G?úÑᱤƔ¤8NæÚþð‡»X9è,;mõ;¾gsíØ«m*£ä!!!!°ÜEëY¸·¿ýí‡Ê™9x”†GA%…@„À:¢WÖ¡–sV!`'™ŸþéŸÆ/»BHv†¸üòˇ[n|ã ×}ðMïÿû³oûÛ³|ä#Ã#Û… p1.Ë£ÏsÛÿÛ±æÚ×¾öÙqÛ½]æ0I XŸÀÏüÌÏ\i·Æÿ÷Ÿ}þóŸ ô¡›É,¹„@„À蕈Á¶ \ýêW,PÛ¥¦Òg>ó™á.º»Þõ®³ŸýÙŸ9ÎB„R£‚p,Tx ªù§ú§™s¾üå/9•ólÉo|×’2íb¹vSÊ«¸Öµ®5è•üÇûÙÏÎ<IrÝ¿øÅÙW¾ò•ÁÑwÃÞpØÉÅB…&ü.Çî6v”ð`Ó&A5·»Ýífw¾óg“B N;8~ýë_^µ–]¢l}ÿñ|XP¨E6ôŠ­ñ=FŽnùçþç!§îæ-rv”º×½î5»Å-n‘;{ JÞC B ®Dà>÷¹ÏÎF~Þyç W:0_„@ì {ÞóžC5Ç`ãvâ>¥óÏ?ÐMì^sä›ßüæ{WÇ}j¯ÔåpXs8~9;B B B B B B B`ÇÜä&7™q𠪱CÄ÷¾÷½Y=ÊÉ¢ö·¾õ­á5µØî¼óx©_üÅ_œÝûÞ÷žyœTR„Àé"`Wšÿøÿi¾ùÍožxG×TÐÍT*‚úìrs·»ÝmXdI°ÞTr9.B N'»]ÂL 89.¼ð™×>'ód7ž$…Ài ÀšÓÐÊ©c„@„@„@„@„@„@œ"¶×ö¸& ÕûØÇf÷w7ûö·¿=ìaËü ²Y„ÄÀv¨±]·GGÝñŽwœÝæ6·¶¸^t^~ ØOôŠÝ®ýëzÅc¡<ŽCà^¿ Í<‚ôè»ÔгS¶òyÄò}„@„@„@„@„@ìÖìF;¤!!!!!°<¶àz×»ÞÌn•npƒ Ï‚®ÿó!'…€…kA1v—ð¨+®¸âì#žØxœ‹—@‹æ‚i,|Ó…×¼æ5g7ºÑ†GJýüÏÿ|jNJ£§œ!°EôÄ-oyËáñvÃúû¿ÿûA¯xÔ“]k¼J¯(âe—;Ô\ûÚ×jþy]j¶ØXÉ:B B B B B 6H 5„™¬B B B B Bà¤põƒô so`ÙÝÕI!!p XÐ`Soòìws±ÓÄ÷¿ÿýÙ~ðƒ!°F@EnúÎâ·Ýnœ›!=¶ÑÍo~óá%0ï»ßýî°+–:¥vÆ¢S{k\cvÝë^wÐ/m’B B B B B B NÖœ¬öJiC B B B B`«,,_ç:×Ùê5’y„@'3^v²I ð‹GÆy%…@„@„@„@„@„@ì'Ü"±ŸíšZ…@„@„@„@„@„@„@„@„@„@„@„@„@„@„@„@’@k 0§‡@„@„@„@„@„@„@„@„@„@„@„@„@„@„@„@ì'Öìg»¦V!!!!!!!!!!!!!!!!‡$ÀšCÌé!!!!!!!!!!!!!!!!ûI 5ûÙ®©U„@„@„@„@„@„@„@„@„@„@„@„@„@„@„@„À! $°æsz„@„@„@„@„@„@„@„@„@„@„@„@„@„@„@„À~H`Í~¶kj!!!!!!!!!!!!!!!!pH ¬9$Àœ!!!!!!!!!!!!!!!!°ŸX³ŸíšZ…@„@„@„@„@„@„@„@„@„@„@„@„@„@„@„@’@k 0§‡@„@„@„@„@„@„@„@„@„@„@„@„@„@„@„@ì'«ígµR«ÓDà‡?üáì+_ùÊiªrê!!!!!!!!!GFà{ßûÞ‘]+ ]#Àš]k‘”geßÿþ÷gÏ{ÞóV>/'„@„@„@„@„@„@„@„@„@„@„@„@„@„@„@„À"yÔ":ù-B B B B B B B B B B B B B B B BàÔÈŽ5§¶éOvůzÕ«Înw»ÛìJ¤ô!!!!{Ià»ßýîìòË/_»n׸Æ5fçwÞÚççÄØ&öjR„@„@„@„@œ& ¬9M­½Gu½úÕ¯>»øâ‹÷¨F©J„@„@„@„À¾¸ì²ËfÏ}îs׮ޠšØºkãˉ!!!!!!!!!!°QyÔFq&³}!Àš}iÉÔ#B B B B B B B B B B B B B B B B`£X³QœÉ,B B B B B B B B B B B B B B B B`_$°f_Z2õØ(Ölg2 Ø ¬Ù—–L=B B B B B B B B B B B B B B B B 6J 5Å™ÌB B B B B B B B B B B B B B B B ö…@kö¥%SH`ÍFq&³}!Àš}iÉÔ#B B B B B B B B B B B B B B B B`£X³QœÉ,B B B B B B B B B B B B B B B B`_$°f_Z2õØ(«-Êí‡?üáì²Ë.[tH~ h\~ùåÍ«üîw¿›yØêØrF„@„@„@„@„À)&`•!!!Û"p•$ÇÃö°m]#ù†@„@„@„@„@„@„@„@„@„@„@„@„À‘¸øâ‹g·»ÝíŽôš¹X„@„@„ÀþÈ£ ö¯MS£ H`Í &‹ý#ÀšýkÓÔ(B B B B B B B B B B B B B B B B`X³ˆÉ"B B B B B B B B B B B B B B B B`ÿ\M•®zÕ«Înw»Ûí_íR£8bßýîwg—_~ùÚW½Æ5®1;ï¼óÖ>?'†@„@„@„@„@„@ü˜€ùUR„@„@„@–ÀU~t›IÎø1Ë.»löÜç>wmnz¸øâ‹×>?'†@„@„@„@„@„@„@„@„@„@lŽ@µ9–É)B B B B B B B B B B B B B B B B`$°f3U ØÖlŽer Ø# ¬Ù£ÆLUB B B B B B B B B B B B B B B B 6G 5›c™œB B B B B B B B B B B B B B B B öˆ@kö¨1S•ÍH`ÍæX&§="Àš=jÌT%B B B B B B B B B B B B B B B B`sX³9–É)B B B B B B B B B B B B B B B B`$°f3U ØÖlŽer Ø# ¬Ù£ÆLUB B B B B B B B B B B B B B B B 6G 5›c™œB B B B B B B B B B B B B B B B öˆ@kö¨1S•ÍH`ÍæX&§="Àš=jÌT%B B B B B B B B B B B B B B B B`sX³9–É)B B B B B B B B B B B B B B B B`$°f3U ØÖlŽer Ø# ¬Ù£ÆLUB B B B B B B B B B B B B B B B 6G 5›c™œB B B B B B B B B B B B B B B B öˆ@kö¨1S•ÍH`ÍæX&§="Àš=jÌT%B B B B B B B B B B B B B B B B`sX³9–É)B B B B B B B B B B B B B B B B`$°f3U ØÖlŽer Ø# ¬Ù£ÆLUB B B B B B B B B B B B B B B B 6Gàj›Ë*9…@„@„@„@„@„@„À~øßÿýßÙ~ðƒÙøÃÙOþäOήvµ«Í®zÕÜ£²_­œÚ¬KàG?úÑÐ7œÿ?ñëf“óB B B B B B B B`§ $°f§›'… 8jßÿþ÷gÿò/ÿ2ûÎw¾3û¯ÿú¯Ù¿ýÛ¿Í|w­k]kv½ë]ovÝë^wvýë_´9ê²åz!°+þó?ÿsöo|cæ]ºÎu®3»Ñn4û©Ÿú©])â‰*‡ ¾o}ë[ƒ¾ùŸÿùŸ!P©ôM‚ùNTS¦°!!!!!!{H 5{ب©R„@„@„@„@„@„ÀêìJ#æ²Ë.›]rÉ%³/ùËCЀï+]óš×œÝõ®w=ùÉOžÝô¦7­¯ó§ŽÀ'>ñ‰Ù‹_üâÙ×¾öµÙU®r•Ù-oyËÙ3žñŒ¡œ:¨°@¾·½ím³7¿ùÍÿ½3 –«ºî÷¶™Ì,@ !@³4š˜1ƒùä“(PºòÊ+Ãu×]E}µnñÅ_^سjÕ:×ã€$  H@€$  ô€Âš¾qó* H@€$  H@d>øàƒpß}÷ÅÀö®]»ªöŽà÷ÚµkÃĉÖT%äÁ¡B`Ïž=FI(ÖFú>T4³ŸˆiÞyçJ ÷ß?~ÿøã« k`N6­M›6Å [øBÆ  &„aÆ5Ó5Û’€$  H@€$  y k†ü€$  H@€$  |þùçaݺuañâÅ1[D"BJÛpÀ1+ħŸ~È`Ãùš$ "@yº¥K—Æ= QFé¨o¼1|ûÛß–¨‘ñ¾€$  H@€$0 (¬Œ£jŸ$  H@€$  H !»wï+V¬¨ˆj(mCÙ§)S¦„3Î8#uÔQ1#Çk¯½3Jœx≠µïÉ€šI€l5¯¾újÜ—R»dÚb"Ë û—& H@€$  H@@s(¬iG[‘€$  H@€$ .%ðÕW_…íÛ·‡U«VUzð­o}+Ìš5+üõ_ÿu8æ˜c*Ç9—r7d²Ñ$  ö"^E#£/­y*Q*ð³Ï> ûí·_-Qn‹Ïš$  H@€$   k†Æ8ÛK H@€$  H@¨A€`éo¼3éÄ4 .ì!ªá7©Gyd:Íw H@B€Œ4LjÙÃ0ÊÖqìàƒŸëMŸ{î¹°lÙ²°cÇŽ°ÿþû‡™3g†+¯¼rŸçÃ`í¿ý’€$  H@€$ Ö8 $  H@€$  H`Høâ‹/b6‚ÂG&Nœ˜ò³$ Ž!@Æ”9sæÄ½ëí·ß”¯;õÔSÃÙgŸmF­&ÒÚµkÃêÕ«c‰-š&ƒÍyç§°¦ÉœmN€$  H@@'PXÓÉ££o€$  H@€$ÐrŸþyøðÃ{܇ROˆk4 H@H!ÍôéÓÔ)S{FöŽk€$  H@€$  4—€Âšæò´5 H@€$  H@è2d¬É…5ßüæ7ÃAK~tYWtWb(Ogé§!6èvW€$  H@€ÚNà›m¿£7”€$  H@€$  t¯¾ú*|òÉ'Ö±F“€$  H@€$  H@€$`Æç€$  H@€$  ô›ÀÿøÇðå—_ÆvÈ €8%7Ä+¿ÿýïcÉJ•æC p@~ZÝÏ_ýuøôÓOÃþð‡x/î¹ÿþûG íõU C;´[3Ê©À)ÓÂgÚÄ_|íOF|¥=úè+|öìÙS9‡l¼8·¬ ”ïøG!„NpclRF˜5Ò‡Þú §Ï>û,Þû$Aåt™—µîÓ*†ÅûÁ‹¾¤u#X5«Åû5úÿàÌ+qÆ?æ$ë¡7Kë3­Q®)ÎùÞÚH¿çmѬúÚVj³·÷Ôÿ´pOö*úߌyöW¬¯làBiÑfZŒU3üÌ9åLrß—f­óÔ¯4ÿò~ñü)3ÿr¿ý, H@€$  H@C—@ïÿ‚1tÙØs H@€$  H@(A€ å+¯¼vîÜÏ>î¸ãÂ)§œƒÇMß}÷ݰuëÖðòË/Çϲ?þø0qâÄpú駇Ã;¬æ]ŒÒþŽ;ÂîÝ»Ã믿víÚ…#I ŽuÔQᤓN #GŽ Ã‡GydÍöøö^{íµðñÇÇóh!J2îùÁ„gŸ}6ŠïøMÛcÆŒ©)ðÀ§>ú(úøÎ;ï„7ß|3¼÷Þ{ñ^ªéë1ÇFFŒý¥eíý÷ßÛ¶m‹þì¦úN€˜ 8cgÆ!Aq~?ãŒ3¸qã¢Ø¢Ö½Òw|b Ò3>p#衇FV£GŽý=úè£kò¯Õ·tœö[æÐ[o½_Ið……±a\ÒØqÄ Ý«Õ S?í0oú7>#HbÌY¬‡N8!{ì±áðÃo¨é>ýyÇüzã7âzÃOø#(Á¿4ž|†}-£_ÌyÚc 1F\ËØ4bìE¬IüAðÆúamðê«(¯ÞýÙ_Øû¶oß÷->ÓîKŸY¬_>ä/Æ\f­0ØŸkÚd¼ËãÁ:cœxgŒàˆ1aoe¯®·G6,®—ÞúÀÚ`­Áµî |gã?ó6­¿FöƼ¿i}°·s¿´N¸WµõÁ\bn%ã9Ó$ú þ'cþ¼ôÒK±?éXz‡ó³ÞœNçú. H@€$  H@ÝC@aM÷Œ•žJ@€$  H@èHHÿã?þ#lÚ´)ú‡Xæþáâ÷Ýw_X¶lYœä ü³Ÿý,Ì;7?\ùLÐ÷í·ßÏ?ÿ|X¾|yl?‰a*'ýùÁê±cdž „… Æ{×Êz@Ðô_þå_b°»Øß ¦¾ð áïþîïzüLàuêÔ©áÿñ⎢´¥í§Ÿ~:<ùä“1àØ¥šD†Ó…^Î>ûì@p:ìV»†c«W¯7ß|säB0úª«® ?ùÉObwݺuáî»ïŽ‚ ¿¹Á˜ó3U³ô 6oú–ƹè?>Üñ½ä’KâX7"†@,õᇆ7†'žx"Þ‹`y œçL˜KÆa6kÖ¬x/Æ«7kC|@œ€PmÅŠáñÇ¢ˆj¾!¶Bvþùç‡yóæÅ>ÕZÕ®ïë1D ˆ¦1ž6lˆâ‰b{XOŒç™gž…Ås3<òÈ#á–[n‰b~g߸ñÆãÚa ”5„¿ùÍoâÁGÖ÷¾é¦›¢x¤l;½Çœbn=óÌ3ÑwÌ¢1§¦L™û1}úôÂâ¹µ¾§ý¡ ÆúþéOfÏž]ë’x®¬‡-[¶„G}4¬\¹2 IX'üg̘ïI_jû6‚¦U«VÅ9Ë>YvoDÜSvœñac™õ‘ÖùyçæÏŸ× s6¿øÅ/âúB`TÍx.ýÛ¿ý[µŸ¢`êïÿþïÄ ªþîA H@€$  H@èN kºsÜôZ€$  H@@Ç H ^Fü'ÉâÅ‹c€²ZÀ6e¢©Ö‚®¤ûÛ߆§žz*fº¨v^:†góæÍ1ÙZ®½öÚpòÉ'WÍ2»¤k˾p%hK–…¢°†þ"¨¹óÎ;cƘj‚ü>ð"ðN€™€32gì­g0Ki˜òùúõëí·Þ™UcMf Ϋfé;< R#BŒÄ÷ZwÎC„Ãø"L*“‚qãš|0,Y²$Þ¯Ö=8Î\"0ϳ·á×E]¦M›VUèUëzŽÃ$qá;žj"~ËÌ==ôP\ðì«1ÿX—©j è'LȦÕèÞ›O<±×½‘ûs/Ä\eÖGZçìÁÌÅ´>ð9YKTS«Ÿé8lÙ—5 H@€$  H@\Ö ®ñ´7€$  H@€œBĈȆŒl”á àŸ‚–Õ²´ðB²T…%8´ OeG` &×ñ™{rÿÿøÇ1ãHñÒ±P&Ã_Ä*yÀ—{îâ)CS,5EP–¬dà H› ÉDC9Ú¢}ü%øË p¹Ž`ìw¿ûÝpê©§–ÎÎÀ}hƒŒ ˆ- $#› ¼ s¾WËú0¾Ã‚q&óÊš5k"Æ ^Œ1þ"@(@?0ÞÉ8õdà©—%#±€ñwÜxàâ"Ƙ1â^šh; ˜KˆpÜsÏ=qÜÉ*RÍÚÅŸo!P@¼1ÆÌ1^ô~©ˆZÔ0þdPA\EöV÷Ið?ð¿R)*ÎÁ'8'QÂDaü¶`oF¢¢¸e“èÆzEôD6¬ZcRì#ms>¥Ù’±—Ðnq=§ßûòÎ:FÔ±téÒâ æó,•6bþ2oSÊ01¦’Ø¿Zmì=ˆjØwøŒ±Ò2gò’HœK_Ó”ýˆrcµ2ÖÕöF8© Á{cÊýŠ{#ÂJöòïÿû1Lµ= Ÿ0öp2âäëƒ~qÆš~q=sù—Öó”1Hëƒ~‘m>¥gms^2æ5Ï²Ä ç|4 H@€$  H@\Ö ®ñ´7€$  H@€œÁÔÇ{, p†@,JÊëàD(¨…àê±ÇÛÃ_‚íR ¨&Q ÁP‚Ò“'Oçž{n»·äÁK‚š”@!ÈNæ &K œà¿ýöÛÃøñãã½ó›à YH^}õÕx˜`îÚµk+BîwüñÇïS¢Š -íчd„)UE¹«$ª!èŠç¬³Î 3gÎŒþÒO‚³ô ?Éà@ ”áÅ9õ‚Ôéžù;ýG8’D501bD9rdd °'ÀœÛ@ûŽÐl=¼ã ‚ JvÚi1Ûã/Æ’LŒóƒý¥ÔÐ)§œR7ˆ„V”"ƒE2XPª!l0oáɸð" c_^Õ¬ ™_ˆÆÒ¼eþ3-ZçãÎ18‘…Ñs“ëX?ÌßV ²1ŸÓx2Ï8ãŒ8NøÀx0žÏ=÷\ô‘µŠ!"ÛbJW1öÉÆŠk’¸>±îVU7¤kÓ;ã·\¸‚`‡W³ ‘ ¥¹ŠÁ Yškd¤}C€Ãœ†ó ¿"&±Qº¶ÙïðCĆÌ Á ëˆrH”ubïÃ`–Ä‘°N}bŒ(ÝŸ`ˆ“¸¾hÌJꑽ(߇÷EÚ»w/g߃k/툭’È !]Ú‹{X~Ïâú`¾ãÛ\³Ñ/ޱÎXñ|Á?®cßä9…±§,9ø€1÷˜£iþ±WsÎ9q߈'dÿS홓ýìG H@€$  H@èR­ýW•.…¢Û€$  H@€$ÐwŠŠð×þd# °~Í5×Är:/ ¸„G\“‚³én2 xÐMF0ñÀõ×_5é8ïybFHC`Ÿ 5÷&вAyðk.»ì²J3VÉX2Ø$ÁÂßüÍßTΩõ2(«W¯ŽB Î!hŽè窫®ŠåŠBõ âõë_ÿ:öñe‚·fÏžƒ»µî™'0%!×roÊ$Ñ„ ¬áð"·ö=e]sJ}ûÛߎÁö|¼ðÑY@˜7‚$‚ðü'Mš”w«Çgæs /Uƒè‰ù'„E#ðÎüCŒƒ8…9œ‚îÅsÛÉpÓ¦MW2DXÌmʈå¼`É‹l._|qÌrƒ „¥6šùž„O ‚c<¯äþ!t@,ñ«_ý*–ocîbÌx³–ó¬5r+0“@ƒyÀØÃŸ¾öfˆ·’ ‰sOü5jTo—–þÿjä.2²,Ø›…!_q¯ã<v÷ߨ$~¥o؇ˬ\¹2²ãrÖÞĉcv/¸çã„ïc÷ _`ÿË_þ2Š´þ°W¥=ŽsjYµµA¦°+¯¼²êÞÈ8²/²žo»í¶ÊÞÈþˆðqêÔ©ñ‚ÏÕ¬Úú€{q}i†ùÉú`ÏgÿfŽåëÑ ¯dÿùŸÿE~IXÃò½ï}¯ª (]ã»$  H@€$  . k×xÚ H@€$  H@N€à+B‚×Ioºé¦@¶†d)£ ÁÉܸŽLˆcÞbdS óË_üÅ_IJ!ùùés³D%˜‹#øN 2` Bh¶ÑGÄ0¼Ræ D;ˆ §’*Åû¼&HL S¶²¤ÐB$2¨”±$J 0³^ÈèBf—dd‘áÕ›±WåâFƉW-+® ®eo,Û?ööF²ù$«·7V[ìûd@ë”õ‘úá»$  H@€$  t'}ÿe¨;û¡×€$  H@€$Ð!#áòË/ï!¨çA_2O†P…@,Aõ²F€uøðá•ÓÉd€`§Ù†¿d© 3C2² Pb&?¤ßj½°æ• õÖé¼ôŽØ‚Ìd¬©&þHçåï)“Ï@ûÎ8Q®%¯ÜÏâgÅYd!©&¬!³ ýËKà `"Xß›ˆ§xßjßÛÍ5E˜¼ÿ¬••+WÆòHy¦Žjþ¶ããˆ@¤L6 äY]Še’X¼Š††ñËç9™hxÕ2æ«\\7jÔ¨(xa¯h–1Ïò¹–ö®²,è"£²§úâ7s–ÌGù\ao-³¿²§åûû¯jF)öÆ]»vU~nÆÞȾXm^pÖó/ !¦zòÉ';f}T`øA€$  H@€º’€9Q»rØtZ€$  H@h‚Žüe|­ò2½Ý·¿"Ád¢è‹‘Õƒl yˆ¾´Óßk(ׂ ¦^iŸâ=è7™'ÈB‘Œ€/™ŠÙ+ÒïÕÞ¹>˜3ž~øaÏ<0\íÚFŽá/cM :ÁtÆ ñ p2D"ô x. H¿ß[ ȳIÏ)~'@Ý ¾ÃŠWYcn§2_éšZkXÃô1_ǰjdN¦{T{†P^q„ùññLJ|0Š ÈX„ðá e–ÂO|Dˆ–glâb)úV4Æ 0ô‘ñÅÌ ¬9çœsªö¿§uŠpâÕ,C`‚¿y©)úuâ‰'–ZÃÍò£·vØÿØ'XC‰o«ô–½§(b j=gØ¿Õ$æøÅ3öî¹è'Í‹Z{#ëcìÞçëƒ1Á´>.ºè¢øë?>ôÆÌß%  H@€$  H@‰Àÿýë]:â»$  H@€$ !L€ Ü=÷ÜÓ#ÃA#8ò¬\—Î}ûí·Ãÿ÷§¯ ½0¥lAö¶2¢ÜÇj™eÌ®]»6À¤¬qÍ믿^9+â Ä5ÍUÐ8þ³'0w(eµnݺÊý{ûÀ5¹ !a‚ÈeÄ2}3¤`zîÛ@øžß¿ÌgHEq'^EC8Äé7‚û¼šaÁ2V”Z¢¼ Âæ6óäá‡Ï?ÿ|8ûì³Ã¬Y³¢€€ìôµÑuØ 6´QmL询1×ÉXƒ¸& kXïg#æeÂÒµÅ2PˆßÕä%†Ò¹}}gþ1×òL0ô‹{uš!†á•ÖÂ#Ø‘9ª¸¶’ïô’cyÉ-öÒZÂöEÖGnÍÚ_h—ý¼[ÖÇyçŸÝÉ×´>^xá…pÖYgUÖ"-öWæ”& H@€$  H@(C@aMJž# H@€$  ü…<ë+VôÈvÑ.s–/_Þ§ÛX^°`AŸ®è‹”ƒéh}ôѦ¸–g.iFƒ´Wt xàÕ#ÐKF^­2DAÝè;lÊ EªõáY³„5ÕÚoõø“‰†²_ìdâ@\óå—_ÆiB&%K–Äõ‚H‚ó&OžÈDB©±NЧb†DŽ ­²’ ®Ap—„,ˆg¶nݺ°†1â·<{$œZ"’tŸFÞñ1\nÌ5^f#FŒˆ™tÈôÃsŽ9ûÔSOE±l‹\Ø'^~ùå°jÕªJ¶Ö ¤Ze®¸ö¹5kmàs­½<­ž<ð@,—ÎE¼X\S¦L‰,:y}ä ý, H@€$  H@K@aÍÀò÷î€$  H@@‡ ÄÅìÙ³Ã#<Òç¬5Ñ%‚¸'N Ó¦MˆÛ÷ûž@‹ÁX%ÐÛQB J%1®Í4üMýÔn~ôÕ_®;òÈ#£¢ZF†tŸþ¾ãw·ú^¶ïÕúH))^Ͱjí·cü3\wÝuQÔ°lÙ²°mÛ¶˜9) ÈæAöšõëׇ±{Ëâ½ ‘ å–:±YˆDÀцX¨8?Ó˜‘ea ¥–È¢‚‘u bœ\8E¦+ø¤}…½a \šiÕ„@ÕCͼg_ÛBTtæ™g†M›6EóÑ þ.Z´(rMó„¹cD*™’‘ ‰ç ¥®ªY+Öbž#Ž8"Þ³ÞÞˆàçšk®‰ëcéÒ¥áµ×^«»>(5gΜ€à(/;U­_“€$  H@€$ ¡M@aÍÐ{/ H@€$  à%ËÃüùóí·ÞZó¯ã — øWÍ .ìÈày_á "ŒØ¤/F !cÙŽ )åQÈú÷ñé/%KŠ™#i§/çv³ïÕúK žµœ[«3µ‹!6.»ì²0iÒ¤ðä“O†5kÖĬ,”ÛI"dq![ " Ä8ï²t’!¦á• kz¥PÊ qMÖ ä ¯”€£P2Ä6¼’±°¾§fó* ›R»|OÙ„Ò±Nx‡-즲…dx¹ÿþû£x†lGgðŸrJ[¶léQнrKsçÎÝ'ÓP½þQz‰{öuodÞN˜0¡ÔÞˆç’K.‰ëƒÒ|Ï=÷\ÌÌC‹ëñÕÆõ×^N?ýô¶ï»õ˜ù›$  H@€$  tÎú•Îb£7€$  H@À%@–¿b§ %3:ÝR¶šéÓ§wº«5ýCHR,B0ö†nˆcQóÂúSf‡äAéŸþô§÷N6üîVßËr%«ÙMr#£I­Cùye>4C„Cd^3fLÌJƒx`õêÕQA‰¨ÔO²ŽPÖŽùúãÿ8 ¿Š‚£2ýmÕ9ð1/}ƸÇ.¿?ÂG2”0âZŒÌ4¯¼òJÑ¿Ï>û,ŠjÈf“ A×5»ÿˆEŠ‚îŸDéþðμ@„”¸06ÁŸg]­çó‡ç"Ùn.¸à‚X ªVj­›nº©m{#þ²6:’µ‰Œ;Ï<óLؼys,•æ <Òú@°Æ5š$  H@€$  H …5Õ¨xL€$  H@Ò6vSÖšÁ­†ŒÅà4™(RV…N›©„MîAZÊÂtºUËÒ-¾—e[MœÑÌ>v CD"”¿!CǼyó† ÂC=ž}öÙðî»ïFÁÙG(÷ƒ¨„½ß;Å^¹UEå¿“Ù‰¬+ˆ ^~ùåøb"„5}ôQ,„@±ÍçŸg½"¬AhÑl«&¬A¸‘Ä;__ÛC@C‰°åË—x¥çeòvïÞ>üðÃ(HJ"'˜!’¡”J¢¤Ù¿˜Cõ¬ÚÚ¨V.«^ÍúõA´´>èÿÃ?³<Ñg˜äëƒ~E‡ÍòÅv$  H@€$  H » (¬éîñÓ{ H@€$  H Eº%kÍ`ÈVÃ̤D P‚AqÊÛt¢á/âÜß={öt…°&‰NºÑ÷²sìŬ'ˆ.x5Ã:‘!{eÄÐÜwß}áÎ;ïŒ úK¹„'ˆmN<ñÄf hJçŠk<±­wƒTŠ2WAxÑ?Ä4S¦L‰ï|N†ø.Ì‹fÛ·¾õ­€(_OðæÕIFçŸ>–>Â/J&]qÅA¿Qþ) øRz”pš6mZ&!ÆéÍ¿"g„5ìi¬³Ï>;вî½÷Þp×]wõX” ClSf}¤gÔ@öÇ{K@€$  H@@{ (¬i/oï& H@€$  t ô×üü…þ­·Þÿª½] ÙjàJ–2  NXÊ©¼ýöÛQ`ÓiYðwøðáÑoüÄ \øòË/Ù:Õ˜w«ïe™&±ãÀx`dé`>5c|:™áQG.¾øâØW6I€€å½÷Þ+%(Ë9?! 2M‘U¦7ï×^{-¼þúë=N-#¬¡LBI˜C[ˆk8ŽH‚±N†‡W+Œ²Cì[7’(eçα_0)³wÁ‚Œ1Í~Uë'¢„3)# YÙÆ3Ðð¡ÄÙ[È´ƒHˆL5¼7jˆjä°G¦rXìÜŸöá5–Öå°òõÁÚ`.UÖÀ!gA?Çì‹÷–€$  H@€$ öèýOMÚç‹w’€$  H@€$ÐQRÖšÞJ_ ”Óƒ%[Mâ‡X@o2¼/½ôR –§côμ F2D5/¾øb ^§cøN€¸[}/Ë“>"¾ ÌM2çÌ'êe b‰TR(]×é é;cœ \Z]žáÄ3Ï<¶lÙRJˆ×­[·†·Þz+abü.f<©œðç)…ˆ&ãK{ëÖ­ Ûöf«I‚*ˆjFŽ™Nmú;B5Ä$É” ÊÅ=é·â;¢D_+V¬ˆ¥¼Š¿7ë;|x%ã¾DxO†èaSÊÀ“Ž7òÎØ ’ì佑ñbžåÈzë¡^.Bü™æW#lûì>"µ2íõvó ë͹¼ æjQTÄÚ`T3z¹H-•¶¢ M€$  H@€†ÎÍM=4øÛK H@€$  H Ã ¤¬5>úhؾ}{Çx;زՖ æÌ™3Ã’%K‚Œ ïÊ•+c`ü¬³ÎŠYHr¡D<©ð?W)«BY‚îcÇŽíð.œÞ篣F §Ÿ~zxî¹çâýhˆ <òH8úè£ÃäÉ“cö‡Þü% L@û÷¿ÿ}@\Dæ‹Þ®é³Ó¾°›}/ÛwDOÓ§OæFv„2ŒÏÔ©ScfŽb{ˆ È BöJÅ |¸é¦›¢p"?· ñûå—_Ž™\ ý¹_ˆÞxãXf)¥ƒL6­42û<öØcQàpÕUWEfd?É ¡˜{ï½7Š:Òod–aÍп2FV3 †`”ƒbŸNåäXGÌ^­´#FÄ5O?ýte/` ËÀÁ`.ÌÀX‘=é>ø`œg­öqôèÑQøÇÀèî»ïŽûë©§žK Qþ‰ÒUù‹g ¬ù qR äÈ¢ßdB ÅÞȾ†1‡ÉÊÃä·Z"–Ôó˜µH–žìyœtïì»i}0'Xß¹à*?—v™/” ƒC2üb¬ª}ÎÇ¿$1æø•b›\À”ÿæg H@€$  H@è^ kºwìô\€$  H@h£ 4g\9!ˆ@À˜0>ˆ ø­hídÈÜøùÏ…sæÌ ³gÏŽk…¹Å:À²Ÿà?s¡þ'£¼ÏI'ÔÒŒ5ð†/¢Ä5øÁ|†1" Ö7b’;vDÁÒ“O>Ùc?Eü‚Ø _Ë" ^IXC&‘Ü[ÚE|ÓJc¢ŸTXÿpÀ˜{¬}ævøÌ8±W1ÏÈÆEÖÊbÁy¿jó­¿þ#ÆBàÃ\"›÷ÁDŒIÈXëÌ1Ä*dÿAüD;ôÁI5 ý`í‘¥&ßW¯^çÅe—]g¬Ó^νéwÚÃ!”b½"š¹ä’KÂøÃ—ä/}ºå–[âüb}ðb¾³váÚßõAi+æRnˆm¹ãÎó¿yþ XbpoM€$  H@€…5ƒg,í‰$  H@€$Ð"–µf0f«ICGðaͶmÛb€šà/FF—ßýîw1M@—@9ÁN‚²Ó@ýaëÖ­1cE Là ±A+„5øEPÿ /ŒéÍ›7Çà*Çñÿæ›o=ôP {þ¦L4øKà/QRI³ˆ·ÚºÙ÷²lUœsÎ9±Aè‘›6mŠA{æãÃ' Žˆ áG.Ð @^KìÑ.† xѲŒÔ?í´Óâüc^!°aÞ„RW'øŽ1—Î>ûì(†@`Ð*#3ë ÖE(ƒDfÄrŒ¿‘E k5þ ¼!#å”1„ ŒÁªU«â:/^K†2à´²ßéžôŸ¹F‰%„*ô1C8úÆ|ãkŸ1" †påŒ3Έb Ä(Œs³ a‚,öÆ_þò—qï){öa‹I´H¹-„.ÉÖSÍÒÚ ûcžöd„„ˆ`ÈæÃÜàz²Å NbÿCPÃ:„à…¥½1Ï“îË9¼Òú@‡¸…±g}°~3áq}Àž¹‡H²V¦Úa.1né™Ä8ÿÏÿüO¼™nØ?ØW¸Ï?ÿó?ÇñLþù. H@€$  H@ÝO uÿ¢Òýlì$  H@€$ H Ó²Ö ÒlÙjò©†ÐáG?úQÌ„@”€*FF²<ð*c`ê ¾i•‘­ ,ÁV„?ƒò`ˆ ´ò*cdD¨Wâ§LœÓ;—í's€ìˆ—(¹“ê3‚㼪|D)é«Y»¦25ˆ~ $CL«ž%ÁÆ¥—^ËÖÔ;·¿¿‘¹aÉ#{K¡Q Y õÖüÕ°Ÿ!PCàÔˆ!J¢Ä¹±o#è»WðÒCÜDÔÜu×]Qä”D!µ²ÂÐDS¦L ßùÎwb ²b?šé{…0/’qʱVð= ‚ðÁ‚Æ‘ß9ÎLV1Ä[ø],‡DÛð?óÌ3ãÞxçwVD'ü†p ¯2[æF5Q ׳Ï# 3þ!Î!;¯zÊR‘A‡yTË…1GÉ ³m¯h2+¢!^¹ñ¼IBÉü¸Ÿ%  H@€$  H » (¬éîñÓ{ H@€$  H M:%k A;2Pf£SŒjž¢ø½Q?É@6ŽŸýìg1@Mi‚—Uz XâAXdC M±„GÑ‚ÛyÀÿóïÅó‹ß ÎΟ??w—,Y3u‰‚Ì)[¼†ïé¾dDÁ_2V5!z¯ƒMžU¡ø½x~oß»ÉwÆ…ÜþceúÜqÇ…«¯¾: } ƒÀ~­¹ÄbL°!Ê¹à‚ b œZ,ÛÁp„ aÁ‚Ñg²n 6K@ªù…Oˆq!ª¡tÜšiŒEš‹´ÍgD d‘áÞ”zB”Äù½9±c3wîÜè#ëµ/†x†=‘ìO9;dMApÑ.c#Ò€ÿ=÷Ü3œ$¡]îýg/Ç7ÄH\3nܸ˜á*1åü4çókóÏÅù_üžŸË8°—.^¼¸"öƒÑyç÷/žqðCÀ˜^\ƒH…LHð%Û Y‡0Þ)e…’,cÕŒ>¦½ñþûïeó¹Á$­áj×ÁÑ{9¢öFŒµ2y1ÏYøO6¤²ëƒyCæ2ëƒû#¬![ï0*ãE¹,æ¶& H@€$  H@ƒ‹€ÂšÁ5žöF€$  H@hfŒ Þzë­5ƒò-º}¥YÊftZ¶2L›6-A’Pƒ`wŒÀ*¼ÿò/ÿ2ö—Òv æìEÁ‹qAA@ AXî=yòä@ |ëÍÞ" K›\ƒ°§ãþˆÈz°nݺ˜±ƒL(dí «í†óð7 € š cuÑõŒñç\ÄÂÊËôǺÅw‚êc÷fa®1{êˆ`z3„×]w]˜:ujxüñÇciæcC0žùƘ ˆ@ìÀÜ¡l÷ãxoÖj†ˆ®ºêª8ödƒy饗bö8àG¤€Ÿ0âÅÚA°‚P‹k[aXgd áÞ°bþRªŒSˆ!{챘( ™ÒzeqþùçŸǤ?BÆ‹õ‹hH2Ö{cÛN£oMX—ˆ0¶íÍpBÿ“èÑ{þ{î¹±ÿiŸâ˜2fÌ)Öw=a cÀœf? Ÿô—=¥š±Þwß}Q Ìáÿýï?Š«]“Ž1¿I‘‰ ¥ì0îK™+D„µö®|m¼ð 1‹ ”´7&.Ì ÎeþÒgúÁ~Êzg®Ôj?àuå•WöXIÀCûùú`³ÂžŒ:ˆ‹Ê¼~øÃFŸ(c…€PØà7mQ«Ö”¹çH@€$  H@@gøÆÞÿsù§?óêLÿôJ€$  H@@Ç@±aÆð¯ÿú¯1ëE»#°¸`ï_åÿíßþmÍ¿Üo·Oé~/“0…$b•f"¹){ Á\‚™Ü‹€&â J‚œmÔ¾üæÉÿþä |EÀ‘ëŒ!þF€(„€r#F¿iÿh‹@q³­S}g Ìæ…@þ—¾ùìÙ³'Š0¾Ã’1`1&ˆêñ‹mÕúÞ*†ÜAë±ëŽà>â Dm¬úÒ.µúRí8ÿœ”æ"s1Dqí±žðÁ §àÌÜ'«¾ϯvŸ2ÇÈŽsË-·TD#ô,E7Þxc¼_™6ZqãÂ8±ùclv0תeÆJL“§·qLç×Û‡Ûn»-f«a0„€7ÝtSCÙÏÄÜ|óÍᑽ™Ÿ’!"¢Ä\eŒyÃúc/'³WÊDÆ^ÎN{#œúº³>Rù­”½†½‚góŽ}·7®õúÂóq÷ ø‰¨“ì=ô¡¯~×»§¿I@€$  H@ÀÀèýÏ®Ö?ï. H@€$  H c&p6PYk:1[M‚”[iïÉ\À«ÙF€Ÿ@n3öšÝ&þ!úh†ð£^_;ÕwÖ r^ý1‚ßd»i¥µŠ!>#B@ÈPVÌЊ~"@„Æ«–±fG_µÎéïqDV›6mŠåyR[(Èö‚Hc q ""^e­Ñõ]æ|ÄMd–I¢Öe]ˆ¶xå–„nù±zŸ™7[Êdšª×N½ßX<«yµÂx^0Çxi€$  H@€$044ögqCƒ‰½”€$  H@€$P“ZJÄô·üNÍÔøà)AP² h€$ð'o¼ñFÖ•%¢^ÚŸ=‰W2„!ˆËꉢҹù;ÙxåÆ3qذaù!?K@€$  H@€…5ƒnHí$  H@€$ÐJ)kÍ‚½%™šUƤŒ¿d«Y´hQÇ•€*ã»çH@hJò­fëÖ­•æÉV2nܸ0jԨʱ¡þ,1yy"J÷Q¢.Ûôƈ²Vp¦T22òPZIaM"â»$  H@€$  V këÈÚ/ H@€$  H eÚµÆl5-J–€º˜â„5»víªô"ÙjÍÆRi`~@ürì±ÇVzöÇ?þ1lذ!<ýôÓáƒ>”jÙ×_>úè£xþÒ¥KÃæÍ›ã©u(E†ˆ‰R€š$  H@€$  H`0ðÿùæÑµo€$  H@@KäYkn½õÖºAÉf8`¶šfP´ H`°زeKÖ Á{œ|òÉ–* ôÑG3øPþiÏž=ñ×7†Å‹‡íÛ·‡©S§†£Ž:*‘ ÉPóùçŸÇÒO/¾øbX±bEÕ$YjÈÜ6mÚ´ÂÝü* H@€$  H@|Ö ¾1µG€$  H@@¤ âÚµkAÇVÙGfÍšfΜ٪[Ø®$ ®#@#ößW_}µâ;ûò¤I“b&•ÊA?DÁÌÂ… çŸ~î¿ÿþ°{÷îHeÛ¶m×!‡Ë9!¼!Cƹüq,õÉ'Ÿ2×`ˆnN8á„pÅW„K/½Ô2P‘Šÿ# H@€$  H@ƒ€ÂšÁ>ÂöO€$  H@h ‚‹d’á/ö)Á_÷7۸lj'žïa©fÓµ= H › ¼öÚkqï%«J²1cÆ„SN9%ì·ß~éï&€æ’K.‰%²(… q†p†W=ãy„Ðó´ÓN ³gÏsæÌ dÂÑ$  H@€$  H@C€Âš¡0ÊöQ€$  H@h C=4LŸ>=L˜0¡%Yk?üðØþøñã[â¿J@èV}ôQøì³Ïb†„‡ÇsLÌî5vìØníRËýF¨yùå—‡ÓO?=P Qè[o½>øàƒX" (/ÊÂô ƒŠb4\;nܸpÆgÄr[)³MËö€$  H@€$   °¦A$  H@€$ î$Ðʬ5f«éÎ9¡×@{  ¹úê«Ã»ï¾<ðÀ(¬9õÔS£¤=tß]x®yä‘Q°‰@fçÎ=„5dÿùòË/c¹§8 kx"Z"ã ïfOë¾q×c H@€$  H@è?…5ýgh €$  H@À&Ъ¬5f«“ʮK@½ ƒ /­o#92¾úÖ‚WI@€$  H@€†o®ÚS H@€$  H@Í'g­á/ü›af«iEÛ€$  H@€$  H@€$Ð kúÏÐ$  H@€$ !N ÏZÓ f«iEÛ€$  H@€$  H@€$Ð kúÏÐ$  H@€$ !N ™YkÌV3Ä'“Ý—€$  H@€$  H@€:Š€ÂšŽ‘€$  H@€º•@³²Ö˜­¦[g€~K@€$  H@€$  H@ƒ‘€ÂšÁ8ªöI€$  H@h;fd­1[MÛ‡ÍJ@€$  H@€$  H@¨K@aM]<þ( H@€$  H <þf­1[MyÖž) H@€$  H@€$  H Ö´ƒ²÷€$  H@€†þd­1[͘"vR€$  H@€$  H@è2 kºlÀtW€$  H@èl}ÍZc¶šÎW½“€$  H@€$  H@€†&…5CsÜíµ$  H@€$Ð"dž9á„‚ ÂPê.y¦›ý÷ß¿Ô5ž$ H@€$  H@€$  H@­' °¦õŒ½ƒ$  H@€$0ÄvØaaúôéa„ ¥zN¶š3f„ñãÇ—:ß“$  H@€$  H@€$  H =Ö´‡³w‘€$  H@€†F²Ö˜­fM »* H@€$  H@€$  t…5]7d:, H@€$  t²YkÌVÓ £©€$  H@€$  H@ÀP% °f¨Ž¼ý–€$  H@€ZJ LÖ³Õ´tl\€$  H@€$  H@@¿ (¬é7B€$  H@€$P@oYkÌVS›G%  H@€$  H@€$  t …52ú! H@€$  :õ²Ö˜­fÐ ·’€$  H@€$  H@€!…5ƒpPí’$  H@€$Ð9je­1[M猑žH@€$  H@€$  H@¨E@aM-2—€$  H@€$ÐÕ²Ö˜­¦ `mB€$  H@€$  H@@(¬ido! H@€$  mŬ5f«ÚóÁÞK@€$  H@€$  H@ÝC`\ýâ‹/Âÿûÿ¯{¼ÖS H@€$  H@]F`Ïž=ñÿ{áö×_¶oßþ÷ÿ·Ëz¡»€$  H@€º‡À¥—^Ž?þøîqXO%  H@èHßøã^ûøãÃW\Ñ‘ê”$  H@€$  H@€$  H@€%ðïÿþïaÚ´i^æù€$  H KAõÀá H@€$  H@€$  H@€$  H@€$  ü‰€Âg‚$  H@€$  H@€$  H@€$  H@€ªPXSЇ$  H@€$  H@€$  H@€$  H@€$ °Æ9  H@€$  H@€$  H@€$  H@€$ *ö¯r¬rè€7ÜpCå»$  H@€$  H@€$  H@€$ÐI–,YvìØÑI.é‹$  H@ƒˆ@]aÍ~úÓŸ¢îÚ H@€$  H@€$  H@€$ ÁD`íÚµ kÓ€Ú H@@‡°T‡ ˆîH@€$  H@€$  H@€$  H@€$  t…51z! H@€$  H@€$  H@€$  H@€$ÐaÖtØ€èŽ$  H@€$  H@€$  H@€$  H@@gPXÓã €$  H@€$  H@€$  H@€$  H@F@aM‡ ˆîH@€$  H@€$  H@€$  H@€$  t…51z! H@€$  H@€$  H@€$  H@€$ÐaÖtØ€èŽ$  H@€$  H@€$  H@€$  H@@gPXÓã €$  H@€$  H@€$  H@€$  H@F@aM‡ ˆîH@€$  H@€$  H@€$  H@€$  t…51z! H@€$  H@€$  H@€$  H@€$ÐaÖtØ€èŽ$  H@€$  H@€$  H@€$  H@@gPXÓã €$  H@€$  H@€$  H@€$  H@F@aM‡ ˆîH@€$  H@€$  H@€$  H@€$  t…51z! H@€$  H@€$  H@€$  H@€$ÐaÖtØ€èŽ$  H@€$  H@€$  H@€$  H@@gPXÓã €$  H@€$  H@€$  H@€$  H@F@aM‡ ˆîH@€$  H@€$  H@€$  H@€$  t…51z! H@€$  H@€$  H@€$  H@€$ÐaÖtØ€èŽ$  H@€$  H@€$  H@€$  H@@gPXÓã €$  H@€$  H@€$  H@€$  H@F@aM‡ ˆîH@€$  H@€$  H@€$  H@€$  t…51z! H@€$  H@€$  H@€$  H@€$Ðaöï0tG€$  H@_~ùexçw‹/¾ø|øá‡‡ÓN;-{챕sü  H ¯>ÿüó°gÏžðÅ_„ƒ>8zè¡a¿ýöëksvÝ×_÷Èo|ãÑÿo~³÷¿¡éË5ÍìàÿøÇðÙgŸ…?þ8ðùC‰cPÆ÷2~ tÿÊøØìs~ÿû߇͛7‡;vÄy0zôè0nܸð­o}«Ù·²= H@€$  H@€$0¤(¬RÃmg%  H@@wøàƒÂ’%KÂÃ?ƒÆ'žxb¸á†Öt×0¸·_}õUxûí·ÃÓO?>ýôÓ°ÿþû‡“N:)œuÖY1?àê@[ >X¿~}ؾ}{øðÃßî!ì8úè£Ã)§œ¦L™Ò5sãõ×_kÖ¬ »ví kØ'gΜFŒQ“k_®©ÙX?  a-nܸ1Š&á° ;ì°ÃâÞ>iÒ¤pòÉ'‡<°–{ž:PýëéEû¿!¨yðÁÃsÏ=…5Ó§OßùÎwÂĉÛïŒw”€$  H@€$  H@ƒˆ€ÂšA4˜vE€$  &ˆ!Þ|óͰlÙ²€¥oÆ ‹¯ÁÔOûÒzd%AHqË-·Da IN¼G`£ ˆgØS–/_V®\)[J"@fÉ“'Gñâ”n°—_~9Ü~ûíá­·ÞŠîžzê©á¨£Žª+¬éË5ýeAvî‹PòùçŸ;wî øÃb¶ÚFDV²yóæ…k¯½6fZI÷üä“Obf¾#À!»P=ˆþÕó§]¿!C¼´{÷îøŽ˜püøñq¯;à€Úå†÷‘€$  H@€$  H@ƒŽ€ÂšA7¤vH€$ À#€J€©UFpž’DË¥)ÈÂBô½÷Þ‹~â+eH(AP—m’m€öûóWûeü§>ú(úôþûïW|"ȉ/)‹ÃñÇŽ8âˆ2M6å|Z»vm,iAƒRÉ$1vìØ¦´o#C‡‚ ²’0§0¾3×S¦Œ¡Cbh÷”L)‹/O=õTœÕh°¿òÊ+aÓ¦M1ëKµs:í>óJFV&^õ¬/×Ôk¯·ßx¿ð Q„È­šœÃ:%› ÏHJqŒïŒy°‘#G†Y³fE±H­û¶»µüh÷qžÓ«žy晸DZÏQJñì³ÏcÆŒi·;ÞO€$  H@€$   kÍPÚ H@€²S<ûì³áþûïˆFZe^Èhpå•Wöz øj·nÝ?IXCp‘¿ØÇg„:Y:è (`AXCI„$gœqF8î¸ãz½O#'xÄü¢l>!úÁ'~KšC=4f?À—Q£F… &Ä€&~¶Ê¦¾óÎ;á‰'ž¨ˆ£ÈÀ@0µÕB£VõÉv% #@ÆÊã<úè£qÏÅö8ö·N8! Ù÷Èô±iÍ#WösÄ’I1ĤìëHɦÂsñLΞc\÷›ßü¦"ÆAàɵl|ô#ÊÜQö‰l\”ÃÈÞóÒK/Åç7Ü4 H@€$  H@€$ Æ (¬iœ™WH@€$Ðá©PzüñÇ[ê),D(õ„5”3zõÕWÃc=ƒºÛ¶m«dͨæÜ‡~X9Ì_õ4DÐ2}úôøç”(éoÖ²u¼ñÆaÕªUñ¯Ú× ¨Éƒ™'²äŽ<òÈ´›6mZ8묳b‰ ‚ÓÍ6‚àü•=¼0XD¥|& H Q;vì<òHETÃ~†xñ‚ .ˆbA6k8ÌFˆµæàÙ²aưnÝºŠ¨†=Æçž{n=zt|Ö!¢Aà‰È†ýã™H¦¡<à Ym'Ž)¬ÙwŒã’µ†ÿ†@¸KÉ-øÏ˜1#ÑF“€$  H@€$  H@hœ€ÂšÆ™y…$  H@]@ ýE|+]%XˆH¥–!ðyúé§Ã<ÿJÿã?®ujÍã´¸dûöíQh²páÂpá…†áÇ׼¦ÞŽ)ÇA6ŸçŸ>–Ѝw~þÙ(+AIþú}Ë–-áòË/oI¹²<ù䓾”ÆBÌsôÑGç.ù¹¶’¥ˆriÌaÄZd8 s„60“Öqçy€˜ÌÉ;ì°pÞyç…믿¾G9?ö9öI„Zs ”ܼys|Ž¥5]|ñÅaÑ¢E±Ì_:ÎX±'!®ÁnV˲±jÇS;Cùç%Âóß|yf3 k†ò̰ï€$  H@€$  ô‡€ÿZØz^+ H@@G Ç_ÂS⨷,,œø ùü¯á ¨"2èÍøKyþ¼š˜%KÍí·ßýÈÏ!ˆ@d̘11Ì!‡ƒˆˆhß=ÑÃ{ï½W¹Œ`#A1„-øŠ ¥ÑÁÍgžy&–Ô s@‘ ÈŽCiŽƒ>8ãÈ @Æ^Ü;]Ãw2Ñ—I“&ÅòUgûù *‚ÉàE†­9˜[wÞygÌ Á8æ˜c¢`«^ö¥æÜÙVjpLj‘éÿqöcJËåû<{ ÙR!äÆžÆž¬5Ï Ä’<ã’rÊ)1ÏšÜx~'Q LJ Ÿ•¼ólÄ(ÝÅó³xmüÑÿ‰àË a Æ31,ÏQJNj€$  H@€$  H@PXÓ/Ï–€$  H   x9çœsb@Žìõ áȯýë@9¤dd2¸é¦›ÒךïpFµÏïW®\/^Ë@¥øË{‚¹³gϧŸ~z,A°0 kÈXø Á°7ÆòQ”¼ÀµìÚµ+Ü{ï½a¿ýö ßýîwKi›L5·ÞzkÌ|“|âl%S§NJräÂJ¢Pvƒ ÿ+¯¼¯EôƒÐ‡6 Öñ{33pO2KÀƒ3""|ÓšCó‹±ÄX?¾9ÛJŸ8&}ÂVê"ö+Ĺ!$Dœ¡µž{yÚÏÓÝxf”yn0NsçÎÏIžŸ(E3³ %šû¾wÜq‘ÓAŸÕ<¯ùï Êj7nß <" H@€$  H@€$P—€ÂšºxüQ€$ n$ XzóAÁ’%KzœF Š@^_ !b…Ûn»­‡¨†` eÿío;\pÁ ~V3‚½]vîÜ&L˜–/_Ö¯__9‘ËÃ?ÆŽæÍ›W9^ë>!€¹ãŽ;zˆjð‰ 5—\rI˜5kV ¶Õ TÒ÷ݰaC,kµjÕª˜é'e°©uï¾'N™ªdVùË{ÿÊ>ñ]h„š”í„ëØ{ÙçÙ[´Ö@T“—BLYƒ2†„ç㈑ѦÖó³L{CáÆ'tR/ñüÇ^{íµøRX3f€}”€$  H@€$  H ÙÖ4›¨íI@€$0¤ <$£ W’$³Íw¾ó°páÂXþ)ýVë= q.»ì²˜å†,8”¶Â³ðWçK—. 'Nìµ$e„8k×®­ÜŸÕ\ýõQèC–žz†?ÇBÊlQ*kÍš51ÛMo×Ök·øe (ÙòꫯV~"£Îi§Vùî H@@Af­dìgˆ:Èü¥µžÂš¼ N„ŒCYã™Å5Zykx%a ÏVÄ5d¯)+j*7Ï”€$  H@€$  H@ƒ›@ùÉÜì$  H@è7D!›7oŽ"–<“ Âïÿûᢋ.*%ªÉ9øàƒÃÙgŸ®¼òÊ×"´á^ˆ[ê>Qæ a ×$£ÜÓ¥—^ZJT“®áà&å;ÈrC¹,2ðàc³ŒÒ\ˆ’xǸߑG3÷4ë¶# -dÜúì³Ï*f_©•«r’šFaSÊ6C£šÕ4Í‘!ÖâY^ÌwŒ5€°&•—b8ì®$  H@€$  H@è3Öô ŸK@€$ ÿ#@ÐjÅŠ=2#P²bÒ¤I1SM_KQ®dÆŒaÊ”)áñǯÜL4Ï>ûlX´hQÍ2Idi@|Ã_ª'ã¯þñé / }Í6C­('¿yÙ+þªž¿¸?ú裓û½¾D'CÁD˜WËJAöJm‘aˆóဠOµó‹7M×#âzÄEÆ ‹~63`Œ0êÝwß }ôQÌø€` &Ì î×èø%ÁWz/ö«Öñ˜-ž_ü ˜07aDf °ÅWüfM4ËàC‰2ʇq/üç>ÌƲÙÖŠþ%æé½ès­ã:&EÿË~‡-óüý÷ß„€i rÈ!qLñ%v´>'h»xŒßÊrMí4úΜe¾ÒWö©¯¾ú*fbIk„¾–Ùƒ½ï@œŸø6ƒ?ÜXãŒÏŸv £ØÏØkxfð¬OY?üð¸÷õùž ¼¸óƒg!k€~rcŽ9&>Ï™Ÿ\Çó“÷”±é7Þˆå*GßÚÏ€$  H@€$  H@½PXÓ –€$  H@eCñÔSOõ8@ð‚ j _zœ\ç ffÍšÛ'Àˆdܶm[|U+•„O”Œ*úD€nþüù½–ªãNË~"ø÷Ê+¯TÚ'Èzýõ×ã5!¶€í¯[·.lܸ1–Ç HÊq0æ^“'OŽïÅàvºáYu(¯ÁõÆgÄãÇS§Ní—èˆ 4Ü 6ÄìŒaQXC(Í…¿Œý˜1c*̪}`n>òÈ#•à*œ¸G2¸/½ôR¸ùæ›Ó¡Ê;BJŽy晕cùú¿k×®˜iûöí1í'a Apüå…x€1A$F&…¾Üñ—¬MŒh‚ÝŒAd²*M˜0! ȸ_¬UýlcÒÆŒs›õD&·Þz«"ÊbN&ñë“19rd\cˆúê ´Ò>°{÷îèóƒu”Œ5ÆÞYœïÜyÉþȼm–±WÓ7JÜñލ½( ke¤5‚`ŽR{”ÜcOêF#K¥“˜ƒý˜1IFöšÕ«WÇý3ã=—ý“=8Î0VœÏ>ƒ°„5Í~Ôߵ߻Úgžµì/<ýôÓá…^ˆAx‚òÕŒ±$hJÿ.¸à‚(V©& €JþóŸ÷`›· {Ä ¼Š†°Å9ƒ8@ó3Ï<E@[¶l‰™‘R¯b;|O^Úš3gN ¢4.kˆ\&00bLÙ 6»a3oÞ¼(Æ(žÓÛ÷Vöo0IokýŽ˜€ù†ð±ûT¾ö‹×1¦ˆO=õÔ0sæÌpÎ9çÔV øÅ/~…ÅvøÎØ"”`MäÆ&›ÂŽFö¼ü3ëŠ9Jf1Dk‡Ð÷Z†`¡ýc:å”SšZn¯Ö}›yœ½«Þ~Ã~ʾÁ+7Æøê«¯ŽýÏEEÌ“ßþö·•Ìk0a¯m¥°†qbÜØïñ!Òb<«{$ÏUį ¥_×/@IDAT. c÷ saPµk8Æ>€‘½ŒûÐÏZk6ˆ)™Ÿ”•d TÛï‹÷‚cÎ’g }a6šªØ¶ß%  H@€$  H@ÀP" °f(¶}•€$  H eYE ˆBŽæA­¾:@À— "\XCŒq5Cà@FÄÉÈŠ€‡¬f2æþÂDYãÚ\ˆB—@%‚›;î¸#J« 1hŸ`;ç=öØcQ0óóÎ;/¶G–š»ï¾;–Õª%!HÊõ>úh¼'bÆ¿¬‘¡€{ßwß}Q,•s¨Ö¿“…1b“‹/¾8Ì;·êØ®åwµ¶óc0,^K_¹ç¯ýëFÈPÆ`LÆ„|0 ÄA€tùå——*}“Ä·ß~{xâ‰'b–šZ÷„ s‰à8ëƒ $̯²ÖŽþ †1)˳xóiåÊ•q®#ZÈ×lñÜô1EÈŘ²×2®ÌDEcÎÖZçÅsóïŒ;‚ƒz—üüzŸ™¯ˆäØ7xg}—1ækƒµMæ—믿>Š(镹W«Î_™1-ÞŸ1f,<_s!#m÷¥ýâýj}GˆøÐC…åË—Ç}„±¬gøÂX177öb²r‘i©ž±‡²ß/]º4>;˜µ 6쳈bÈäFV#„•½%ñòç=}á9Ås£•¤Þüòw H@€$  H@€$ÐmÖtÛˆé¯$  H@I Csçø+öfd«Im’Ùƒ ,¹„$GпhÏÀr.Âá7}”+êD£/E‘šã?¾Ïîð${ÂsÏ=_p"“"%‚’ˆg†¬L[Æ’Ò÷Þ{oÌZÁo·Ýv[¼ž do×Ó21p¬É²Ñ›1VO>ùd¼O΀*mP^„ øûÁÄ+c‹@>’ñƒ@)m=ù\à«dÐ! ŠÑGÚA€€qÙ Â9Sœw°‚™ঠʢ¹ûqkñe`ÈH‚0ãþˆ¾xà˜¤Ø~Ѿã;"‚Ý0NgÆÙ>ÈâĘòÂO2…0†ŒyYkuÿ˘”噟—Ïu$É`Â|gœx!dî¤õÉux1žˆ˜G?þñ÷ß±W’uÆýôÓc‰‘ü:>#@7n\ÃI¨À¼Oóœû""øŒ¯ˆh7†Éè@ÐyíÚµÑ_|¦¤™!Æî-Âܬeð$K ¥¼rQ sƒ’R”–b­á kˆ©R¦Ägô¹¬µ£Ý>&eYæç1æÌqʵ墯ž9KÆ%„tEa cGfJæ ,ÀžPFŠùöÝï~7ŠÃÒ½¢ýð‡?¬Œ9¢Ö¥˜0Ö†k®¹&]ßÙs¸3„ÌSæ"{IZC¬1Ös5‰ÏÑDì#¬iüd¿âZÖ9¢8úÄ3 ŒrEŒiÚÙK‘¤ý†uJɼbF/ö D%ðcݳo ÞcÎ`øŠHhÁÞrxd{c/æ9̹ìÅì¿ÌCæ&bÆŒç {s¬Ö ŒDt•˜À d»á~Ìæ#ÏÅtæmã"´2Æ>Ì0wð Kš2×{Ž$  H@€$  H@ÀŸ(¬q&H@€$ ~ J`!Kn²r±Kþ[_>€%«/¶É–|Ëï…àÝäFà²Ùò6›õ™@4‘Ÿ _ÉöBp±¯—m{OÒ p^zé¥aáÂ…ñ/õá‰ì§l÷CÜ‚ˆ#AîŒ$ËÄe—]¶ÏõŒÿÔ©Sc0øÎ;ï¬dp!K ÁVÊIÕ ‚2Fd¶ ƒ †_øú½ï}/^[/Ú"Ób‚¯dÓ!8K?&æ·<Op•@v2D ©äÇ#P¸ä’KÒ)ußi(qïÓ þW/²Ø•Ñ\S&%Ö bü5jTÍ{X&£O Ôs"âØþà?ˆ>äϘ1#ŽÉ#<Ì+ø”µvô¯ÛǤ,Ëü<æúêÕ«£è,g>#Œºêª«¢`¹X4D ¬c˜!`cÞ`Ì%Ä ˆÝ1$£MÄoÉó ˜È…5ÌŲó=µÓÈ;¾âëŽrU¬ÄCìÓìG¹±nÆî—±FX WlØÿx1nÿØ£˜¯ô—ç "˜j{"óaa2ÆóùÁ=xñ;¾°wW˶”Ú)¾ÓV¨²b<›xi€$  H@€$  H@å ìû¯–å¯õL H@€$ ½ØèE`‘Œ`A8ÄÍ4’Ùra "š<‹÷ãXÑ'ŽãA¶N4²Ÿä |ÍÅB}õ¡ Aôk¯½6\xá…û´ÉX!d!SÀúõëc›{1žˆl¸Q ÁÕ‹.ºh~é÷ .¸ –d"³FÈf@–, ÕŒq"ÀJ@–`,Ƽ9÷Üsã½QU3îIV˜ùóçG1ÒwÜOCL…€áJ™òJÕÚ.sŒ±!{ÃM7ÝÙÁŸêgÄ7 öf~Hš$JƒQ-a \@S^+m´fL jusæ:<ïºë®˜Å¦x^­ïíì_-=Þé>3×Gæ:Ÿ1LÌS²Ë0ŸjÍ!ƱØõ×_÷[Êô`ùú!#S5CƧ½ZÆB„Ö¨!lâ•„5ü·AúïƒÞæd£÷ò| H@€$  H@€$0X ÔþW›ÁÚcû% H@€šL ‰òf Ž!|h¶ˆ&øšAÀT%GŒ@¶–Ü:sí@•ÙÈ})~¦6S@“ßaXKXR¼¾Þw2'\qÅQ8SK¨Cp‘Ìd…(Zºžl7µDIéú³Î:«ÇåžR€¼Çþ‚ˆ2"y (²»Ì-ÓwæXžÉ‚¹H “^x¡Úíšz –d†AtT68Ké&ÌãdŒ;AæZ#D5©4 ç1d«!H=#ÛY ®¼òʘM§Þ¹ÅßÚÕ¿â}ûó½“}fÉ.ƒØ,ãxþùçÇ2d½Í!ö/Ĭ<‹Yp“!jè$£?¬eÄdô³·þ%ßa 2ËEB0rF:×÷æ`¦t_Úgs‘eˆ=®–¨&¿;¢D4©t!Ï22$åYiÒùü†h3‰)9Îç”-׬wöۼܟ{åÏÛfÝËv$  H@€$  H@À`% °f°Ž¬ý’€$  H mÈ(P̃(¤X6¢l- .Sd|/úDpÀ{Ùo3ü-Ûþòô¹Ñ×þŠ€R–Ä)à™ß#ÿÌx…ý½žàež…'¿ŸÉ €h„1ĸ™VÆ¿÷ö?¶äÙ^Y‘-¡uA&|,0§L Õ|†墒1)3sæÌt¨î;s~Þ¼y¡(zª{QìKÿúx«¦]Ö.ŸcÊ줒\Ü—L.³gÏ.Ýö„'”ÄI–2ºùi0kšõ‘ïód(˳” †~vZ¶nÝx¥½˜}ƒÒ]dã*cŒûpžUˆrKd*"ž7ì÷ÉàÉ+Û¤ßúûγ?3Ò‚ÆTö°¿í{½$  H@€$  H@ Ö …Q¶€$  ´Á¹VÈ"Û%@] šUÛ´B7DXS̰C¿òÀcÍUNåzñy°³òcám2úäÙÏõÿË^O@œv’ÕÖ$AÀ[o½•Nå:(+’g«¨üXãþæç“ïeßiä¢BúWÌJV¶-Ïëû4åèÂ$#SYÌx•5ö™|o«•iˆ6Ù¿ò¬vd\z衇¢Ð²(2-{ÿZçñŒ(þ7sJaM-b—€$  H@€$  H@ûø¿õß÷7H@€$  ” @<Ê%ˆ&êe*)ÑlÕSÕÛ­–ņc¹@„Æ’ÈÑM§e­¡_Å ;ô¡Èµ*”^6ÒW˜­—A¥Þí¸žŒ,iŒª †Òõ6wîÜÙ£ß\a±iÓ¦tZ¯ïƒ¹O2>S‡öû+LJmöçþ H>"¢ÉƒÕÌGÖK5ã7®¥?ÉdKå¤ßâ½?ý¹g»}æ~¬‰\Â8R*)Ÿ ex°' –CÀF»T§Ltsœ½™õšÖŸó}‹ãœ§µ†û {~.4áùÜmd/F˜ÆOGö;Æ·(l™0aB,‹Ç¼es.ÙËð…ò~“'OŽ™Ëòì^}í=÷.þ÷}ÍûÛ×¶½N€$  H@€$   k†ÊHÛO H@€ZF€ÀpQBp-‰+šyct¹È€¶k kòR"œ‡° Áíâoü>¯¢°®Å``«}äžý£}®'!¨Y,Âø<þøãaݺu¥»J;d[HÆ= Ò2OÉê’®ïë;Áá;vJšpo2”0×Ò{ 8Óç<3D½û1gÉú€ 6¬Þe-ù­ýk‰£Y£â3ã÷î»ïö‡0ŽyÆŽÌíº“\Z?Ì÷nÖ°Ç‘™„,U¬uÖÇxч$ža 5;kI]¨CüGXy³§.Y²$f+‹‡6ò½˜=cŒoQX3zôè°`Á‚86oÞÇžu²~ýú¸‡®Y³& o&NœXÉìij¾/†­x-ÿ-ÁK“€$  H@€$  H@(G@aM9Nž% H@€j Л—àD¤)XÚ¡Fñ¦_‹@Ú/Þ¿šØ†¶¸ÁO§ kð­øƒaÊrÂïí²"šë«@ŠùMÙ¶$¬A ÀgÖTqé/Ïþ^¸QQ¾FÖ cýÃToVkôv¿÷N€}†qÈ 6}Í\–ÚAhÉ~UmN2‡g̘ï{ÿý÷‡—_~¹’щ¹±víÚø,1bD8ýôÓc›©S§ÆÒ„´Ûˆ1‹ó‡çD#Ï«Fîç¹€$  H@€$  H`0PX3GÕ>I@€$ÐV¹(k‚XaD2‚¥ÍÌB{Üò¿2'8}ôÑGï“1'ž êåç@$Xx '$7;âÀcµ¬?y阎p´‰Nì,ŠNt2fN“[\Xl«Å'jK,]º4¬^½:lÛ¶­éYš˜»ÌùÜ`ÓŽLFíè_Þ¯f|îTŸ«cµ5_–׿‚Eú]FœR¶ýfǧ”ÐÃ?žþùðæ›oî#¦kÖ½l§ï˜;ÅùÃ>Ã^ÜWñ sQÌ)§œRSÈŠ8ìüóÏÇsLxòÉ'+s$‰|x> T|ã7ÂsÏ=fΜæÏŸE6”,k¬¿ü¿¸Ž=´ûhY=O€$  H@€$  t:…5>Bú' H@@W@TCí•W^©øK Ž€X³ÊññBnÜwÔ¨Qû1 ´ãÞdGHFÀ®K¦„,fÑ!ûD 0&ÿÓ;[úÛ‘GÎ=÷Ü0räÈüpéÏiÜÏ8ãŒ}Ú.ÝHÉ™G÷ÜsO|åYeHá?ë1å•pÉ,²jÕªR"ѧÜÚ5/ÚÑ¿¼_ÍøÜ©>3†ˆýrëÏ8¯¥m„dÅõ”߯ݟû¥æŽ;îO<ñDLc¬sömiä|Øç7lØ §MƒÆü,î3cÆŒ gžyf£¾¸Á\DÀJ¶™bÛy{Œ?‚JCMŸ>=ŽûÆ믾…¹Ì#Z”Ù[¶lYg]sÍ5aΜ9ûˆQóvóψjŠ"N…59!?K@€$  H@€$ Þ ôü×ÍÞÏ÷ H@€$ *øËöqãÆõÖmåé§ŸŽA³*—4|ˆr"Ï<óLëÈ”C°šQjìØ±=„5{öì‰ÁÞyóæU»dÀŽÕÖ æŒ5ÕúL‚Y³fÅ,6%nL91‚¼÷Ýw_¥TÚ“O>9Ìž=;fi8þøãý!pœg~غukœƒ´Ñ›q"„ÜU0[iíê_3ûÐÉ>37Ȭ•ÂC2zõÅ äb.²× >¼/Mµìš×_=Ü{ï½aåÊ•Q {òäÉ“c Ö Âš”íŒý eG! âšb©¸–9;Ä®&29î¸ã¢E‹¢0¦ÕxwD°¼È6†¨†LGëׯå È2‡Àq ‚«´ž87Í™z>𱦓€$  H@€$  H@å(¬)Çɳ$  H@@]&L˜ÅéD‚`Ï>ûl uÔQépŸÞÉÜB6œ-[¶T®' F»§žzjåXþQÃøñãc‰‰tA OPº¿>¥6›ñ^MdÂ_é祵šqŸNjƒ Ús#JF—N6¼dbBTƒØ £/”<¹á†¢ 1M-ã·b‡ZÁájÂõUQ˧üx;û—ß·?Ÿ;Ýg„EáK_Ç‘¾"8ÉE'´ß¬Ì`ý‡t-â/J÷PÞ'•2#“¢9²ð¬ÀçZÆoe×H­6<^žcS,EH†¸|Ž•o­g"$$s YÇȘƒ˜öÑGBæÏÅ_|1þ·Ï÷â3¤ÚÝ« k£±¿j€$  H@€$  H@åôÌ«^îÏ’€$  H@( :iÒ¤˜} ýDlçÎaÍš5éPŸßÂÐN.4A @€–rÕŒ€Ûĉc‰”ô;92)I§“Œ 2M6ÉÈhAps°MÄy1V«´»ßÊY„Ȧ±}ûöÊ锣„Âz¢šÊ%? ØA –€Yo¾ùfÌàP²™xZ'ö¯7ÿ»Ñçj}b6lX¹Žháµ×^«vzÝc\ÇÜc/K–ÖRú>ÐïˆãÈ:B¦‘d”G›?~8í´ÓêŠjÒù¾·û‚–\à‡5‰¢ÚçÉÿ݉5ƒpæŠ+®W_}uÌ–~eDÜXöYÁžgc_­&ÞJíû. H@€$  H@€$°/…5û2ñˆ$  H@h˜‚“N:)þ•y~1°+Vôjå¿—ùŒØ‚ò9E¥U2$«fˆ(Eé‘Üöòðæúkˆ‡ša4Ö|O6"“äC+ß²x䙃’Ø Õ¥Žà‹˜)À»Œ1§ß~ûí˜9!O`zÊ”)5çb:¯/ïurFÜAF^ ¨^»ˆS8—Ò*e¬ÝýK>uÓ˜$ŸË¾#Cè—g×@4ǘìÞ½»l3ñ<ÆrõêÕ=®¡œûo§>¦ò=ɧQ£FÅý8_wé7ß–{ "Ç|~"Zyë­·úõìnF¯R^²OùÜaŽñ*c„ògÊá‡ûš ‰Ê´ã9€$  H@€$  H`(PX3”Gß¾K@€$ÐTw,XÐC\@ † 6„ǼG†…²7Fð€¨æÞ{ïí€F„B©^õ ñÍܹs{dÁ§—^z)Ü}÷Ýa×®]õ.¯úB22 Z²dIÓþªŸàfÇO‚ÓQŽ£jÇ[pAJ^Ê q %¿Ö­[ׂ»ý_“ˆ±˜¯ÉÈ”^ÓñjïŒ?c“[Ê,“«ö!ã‰x¥¬&óR²” Šr(eŒùƒ>Kª”9¿ÝýK>uÓ˜$Ÿyg®çãÈÞ†paíÚµ¥›©¶>Ø7XCùÞQºÁHßxåÆžMfÞ,eê*+të­=ï“O<1ŒñÿÙ»ÓgÙª:ÍãÛ*KY¼Ì£ 2Ïó B¡¢VwEtt½ìèˆ~ÕG÷ûŽŽ0¢ÛR‹*Ke”AæDæá"¨€ €¨Õöýìîu\gßÌ<;óäÉ“yî³"òdžÌ½×^ë»Æ½~Ïþ­Ý–&FÑÇðð¶ÞAÛ!:­…5úÁ>ÂVÛH¯ë>×¼À+!B B B B B B B B ?kú³Ê‘!!!!0’€­Ž:ê¨æˆ#ŽXv£Ö¿üË¿4wÜqGoñ‚Ä}ôÑæª«®jE þï{íµWsþùç·ÛW´_ùÃèìI÷cŽ9fÙo¿ývsË-·4ßþö·Ûm}JÜËðãÑÇ7¾ñæk_ûZóÝï~·ÝîjÀ¡c%­¶K)Ašˆ0ÆõhQÎ_„wžX”Mm0%vR6“ˆžúæ™·œÚ;€:Qo]3,®î¹ŽSWW*'F`[øÜ|óͽ=-ˆ›ø¸ãŽ[¶”tvñœ3,¨?¶b#J#{çw†ºìûYç¯\¼{Ýy.“’æqÞyg:õÔS—‰ü”ã­·ÞÚË›Á ‘á7Þ¸LÌg+¼³Î:k™·‘qÒµÇò2R ×\Cý[ik!y|ì±ÇZïd}…nk‘þm1Î}öÙ§Ùo¿ý–mWF€Ê;Rß¾£/7ã(Á_ß­õ¯Î©ÅZúïÚ“×°kK»¾½áèSwÜqÇa§äû"¬%_…@„@„@„À$<õn;‰/|á í?%­çž{®ùßÿû·BlFêÞ}÷ÝæÙgŸm®»îºæý¯ÿÕz»©=„0Š1$w·x*׫ߥ‰áù¢‹.j·!©cØs éºé¦›Z ^7øîµ×^kî¿ÿþæ›ßüæ’ †g^¦åQ¦ë±F:°%žè¦uÑþg€çuˆA·Ô‡~¸T=ýôÓË ¢å˜î;-ï ×^{móƒü`™¶{¬ÿ‰8vØa‡¥ŸŠÅvcµñÖêoí=£”S½ˆ-IÔabç?õÔSmý!R®u%ìâéƒGÛš•€ƒ7ÑÌ 1öb›¡ú§jQ×û†Y篤k‘ʤ¤yœwBÛ…ú• oá±F9=þøãCëºãN¾õ­o-ó<¤ýyä‘Í¡‡Z¢œ‹w}´WÝFô—„ݺ_¬íÜ{ï½m1©û|ÇŒj#%޼ONÀØmL5^– oÑŸ'‰W*¿;çÁlE§Ãêô‹/¾ØŠm n3j ÕÿêÛ½ê¾Yzûˆc{½êà<õ3!B B B B B B B B ?÷÷?4G†@„@„@„@¬D€qœáø²Ë.kE4ÅèÏHJ\Ã/{ï½w»íÄöÛoßzpà…†X€@‚§ž¼ZêÀë‘ a 9}‚ãž/¿üòæŸÿùŸ›W^yeé47#|÷ßÿÖcŒ'በ{‰€÷ÒK/5 ‚ÒY‚üÚªg¡4&#ô«¯¾:èç2†w^z.¸à‚¶¬‹T½¹úê«[cîñÇßì¼óέ‡[‚(OBÆXžðyùå—Û-¤”ѧ?ý鿨céÁƒÈaÓ¦M­§œb¬%>!Tá5ƒqYÙúNüŒ°çž{nËÐ÷ÒcëÆfA½½ë®»Z <ð8_y*?u˜¨æî»ïnEÄmDþ`äz'Ÿ|r[ÿJz±²ÅÑŽ6'¶Sò=?üáÛëIf¼;¸6f£Â¬óWÒ²HeRÒ<î»z¡ï"(Þ[JÝQnŸûÜçZq"Ñ€¾Ñ1á„ZqÁ¤[8Hq„øn¿ýöÖˆMQA†A¯aaîàƒnE5¼ˆPL+0*2:3j “„5ŒÏ}žÎŸV:fCçç?ÿùÖ¨~ëB í‚zÂc‡WŸ€Ñ¾ûF]†\Þ>_ˆQÆ[Æa¯o‹¡¸|§œx‘Î;ï¼³­ÛÄ5„Ä@ƒQ§Ÿ~z[®µ°†zT†}öÙ§ùÊW¾Ò„]S݈w¼ºñ›ø‹ M½Uïû„YçOš­LúptŒºþ·û·­¨„è„hAP”)oµW­nê/ú2‚¼y „?ÒHpA0D¸¦Ðy <‰wÜqíKHTQÂJm¤—÷É `lü±#¡›í픟 Ÿéö£®Dœ¨%”êß«Ĉú\sÇ"rì_þןsÕ+â¿•‚4å”<8Þy^©O+ÑËï!!!!!!!!°œ@„5Ëyä¿mŒãƒ{ ÝÿË÷“¼°\xá…­G[|؇!¹<}>,^O“{z~¯½öj½}ôÑ­`‚‡ƒÕy%l Rð¤¼íGWøŠPaPüŒÙŒqŒ ¼1ì·ß~Kžm3Éw â.š",±½1ÏJCZKð?iß0óëëõ½~U\qÅ­GÞ;Ô¢—®÷¢:/꫺›‘- <ðÀF]éã@]8í´ÓÚr'Tá1£lÁU®!~ÆþC9¤|Õ¾û^}¸òÊ+[ï6ÒKØ2h uVú¤‹Gý!¾ÁFùöeD@!_þò—Û6Ës >âè#õÓ5O9å”fÓ–m¯ˆºucÑ[\ë‘?×]´2‘æqƒòÖ¯©;ê,/ Ï<óL+T–âWúSýQ ñ‰:9¬üºiêÖ1u²n§Ýã§ñ¿6MH&íÚ—­ÉjåQ½Ä„ç*ý3ñ¤ö/bù•W¿Õ£•Ž—¿IΙ”K7=ú'ßõ “¤u’s¤G[3©oÆIåFðB„:jÜVVú2NªŸ¶Å«Ë¥äW=&¼Õ·Ú†Q½5þÔð0f«*uŸ§1õj¥@)îz QÏ\?!B B B B B B B B`<«³ÌŒw­!!!sG€qõ¼óÎkvß}÷ÖøÄà7M££šm=lðOXÃÐE\ã)uÆ4b‚ÆU/Æ9Û„0:{IÛ4ÀÒÄ`(M„D+Eð#Mžr—&†IiqmÛìxÊžQŽá°pc’Â&, ¼ð^¼æð¦ÂÈÜGXÃÆe—]Öæ‰AšáÒ–}ƒ|^~ùåKç3ps¾ëóv@¬4îõJ]ÏV$ òÅàJô„ã¨Q@©+„H®I„5n]aV·ˆyx¹±å3®¥^º/G›¶ˆRˆ»A:ˆWxf(éåÁö&ÊN~”#Qø•Ÿ:„‹ú÷Õ¯~µmŒÆ¶Ìé$œK\CdC Äxl+u¶¤Ùu´;u‰\ÀÖÖA¾Ê–Tí?þ¬Gþ±L [ñ+ùT/”!ö­_$”R–êŸz¢ŸÑÿ¨‡Åˇ2UïÇ ŽçåC}'ŽÐ¯uÅbãÄ×÷Xi×v´MùT_y*+mL}–6é"œP§ÕSi<öØcÛ¶®Íû]½œÇ qE»ÃŠøbT˜äœQñú͘ª¬‰¢ŒuòH¼Ò7L’ÖIÎ)éQ?õ{úUÞâž}öÙÖ[ ¾ú6eB e,UGÕ'uT_¬¬Œ“Æðaâ!^Þ”¯kˆÛ¬Ÿ×ÿƒKÝ×wyi+úOe:އ8ãºW ÎUÒ™!!!!!!!!0÷mYØú3×ú—\rÉVgZ ºúê«·ú>_„@„@„@„ÀF#À[D Œ¡}žŸ”á ²Ï®+±ã±Á 'Ý'½æJç12ö±ÃnÖH—41Ï" ý÷ÿþß›²Uëóâð_ÿëm=8¬”FIl‹qr\ÐzŸ_çX¤â‹à‰à£]‰W‚WÄÏh¬nú¬ü “þû”½´ªC„5î/´!÷ŒèEÜRÒȸîxבmnÜ ×yóÍ7—„5â‘^FîAFíR¶®¥^¹vß0ëüI×¢•I_–ƒŽ“We©L}VVʰô‡úÄÕÔsñ‰W9ê[•ÿZöóÝ<ª¯®¯xù¬]É—vÖm%½úfÕçúòe“'ýCŸñc’sêkŽóÙ˜Rʵ¤oþ“¤u’s†åÉØ¨/ÖG–|è?Êø¨';`£Nˆ_*sñêÛÅësŸ>¸N»úöï|§ùÚ×¾ÖÆë7ÇÿðþCëÅ«>6ŸC B B B`£ø/ÿå¿4>úèVÙùoÿí¿µ‚é­~È!!!!0þ+ÉcDšCC B B B`Ñ0\yÍ"0*òò1OÑŽq×k½Q/EXÈùÊ+¯´žIúpc|gœ4¬÷ùuºÇy>ðZë ^zñÚ3IVçö9ŸA½X`T:Ä¡œÇ)ëÕ”í¬ó'ï‹V&£Êk¥ßä•·µ Êžð¡+`Y«ëuãU_Ë8Ó·'­ê§×8a’sƉ¿>–e![}®Ï“¤u’sº×-ÿ¯eÝÁ…ÑkZÀ‘·‚x«™¦G¾oÞC B B B B B B B`[ °úG[·JÉc„@„@„@„ÀÌJØ®§x9ñäý¯~õ«æñÇŸYr¡XT¶#ܼÅûÏGÏO›¶l=ÕGÔµ¨yNºC B B B B B B B`- DX³–tw„@„@„@„ÀØ<½¿çž{.sÕLXóàƒ¶Û¸ŒaNm„€­¤ž}öÙæ…^XÊ1Q Á*ÏP !!!!!!!!㈰f|f9#B B B B` ì´ÓNÍÉ'Ÿ¼´mËïÿûÖHøÒK/­ñ•}„@„@,._üâÍ3Ï<Ó¼õÖ[m&l»wØa‡5ûï¿ÿâf*)u&aÍ:@.!!!!°5}èCÍØ>a_~e,¼ÿþûË¿yèxî¹çZaMÙŠ8švØ¡sdþ èK š¾¤r\„@„@„@„ÀL ì¼óÎÍ©§žÚ|àh¯ûÎ;ï4?þxóöÛoÏ4¹X„@„@,ßýîw­¨æ§?ýi›Ü¿þë¿nE5¶zßûÞ·YHC B B B B B B B`. DX3—Å’D…@„@„@„@|ä#i=ôÐfß}÷maüéOj Ÿ~úéÀ è0F¾ð ͻï¾Ûþ²Ûn»µãèŽ;îØ92ÿ†@„@„@„@„@„@„@„@ŒCàýãœcC B B B B`V<]¿ûî»7W\qEsçw6øÃšvÚ©Ùn»íf•„\'B B †Àûßÿþfï½÷nþíßþ­ñÙP‡~xóW•gª¦“й$aÍ\K!!!!€ÀöÛoßœrÊ)Í~ûí×¼÷Þ{͇?üáÆQ !!!Ë ì±ÇÍE]ÔØ:Ñ6PĨ;ì°Ãòƒò_„@„@„@„@„@„@„@„ÀØ"¬YN˜%bOà'„@„@„@ 'ðÁ~°±ý“WB„@„@„@„@„@„@„@„ÀôÄðôX&¦ D š T˜ÉJ„@„@„@„@„@„@„@„@„@„@„@„@„@„@„@„ÀôDX3=–‰)B B B B B B B B B B B B B B B B`ˆ°ff²!!!!!!!!!!!!!!!!0=ÖLeb Ø@"¬Ù@…™¬„@„@„@„@„@„@„@„@„@„@„@„@„@„@„@„@L@„5Óc™˜B B B B B B B B B B B B B B B B 6k6Pa&+!!!!!!!!!!!!!!!!Ó#ðþéE•˜B B B B B B B B B B B B B B`± üÛ¿ý[óÛßþ¶ùÝï~×|ðƒl¶ß~ûö}±s•Ô‡@„@LJ šIÉå¼ A€˜æ‰'žh6oÞÜüò—¿lÞ~ûí%aÍÇ?þñf=öhŽ;î¸æ“Ÿüdó¾÷½oCä¹O&Œî¼óÎæ7Þhþüç?·"£SO=u›ãЇUŽ ظ"¬Ù¸e›œ…@„@„@„@„@„@„@„@„@„@„@„@„À†'@ðñÖ[o5ï¾ûn³ÝvÛ5ŸøÄ'š¿ú«¿êo"š{î¹§¹å–[šçŸ¾ëÿüŸÿ³t¾¸vÞyçæøCsþùç7úЇÚßV{Ý¥ Ìñ‡×^{­ùæ7¿Ù¼òÊ+ &¼÷ì¾ûîÍ;ìмÿý15ÏqÑ%i!S$0³ÞÎ@óõ¯}ŠIOT!!!°8Ül|ñ‹_œZ‚ó›ß4W]uÕÔâKD!!!°HvÝu׿‚ .˜Z’_}õÕæú믟Z|‰(B B ‰€1ÕØš!!°¾ˆxùãÿØŠvÙe—¶G²R^ýõÆýÏ{ï½×üõ_ÿuS®áó"b›nº©yúé§Ûí›lÝtÐA5guÖ’fTþxª¹úê«›k¯½¶åS jÊy¾ÃîÑGmÎ<óÌ6ÞÕ^·Ä=ïïÖ¢‰–ÔMéwÞiE6óžö¤/B ¦E`fÂí×¾öµi¥;ñ„@„@„ÀBp“:Ma ÷›Wª $±!!S$pÄGLUXã黌«S, D!!°PŽ:ê¨kªÄ’ØH€×“oûÛÍ /¼ÐŠ]öÜsÏæ?þÇÿØì¸ãŽSɲà]ã™gžYÖ|ö³Ÿm¾úÕ¯6ýèG§rõŠ„`èŸþéŸZ~Eóàƒ6‡vXóéOzÅm›ž{î¹æšk®i…3ÊBøÀ>Ð lûä»7ß|³q:¬öºu\ù!!0ßf&¬™o I]„@„@„@„@„@„@„@„@„@„@„@„@¬Û=þøã ï)ÂO<Ñœzê©SÛnçå—_nn¾ùææ¿øÅR?õ©O-]oéËüðóŸÿ¼õöSD5²à;b˜=öØ£õÎ3,[ιᆚ_ýêW­€Æq¶y:ûì³uì´ÓN­g–_þò—ÍæÍ››M›6µ[M9n5×u~B„@„ÀâXaýö.¼ðÂÅ¡””†@„@„À~ÿûß·.H'8u¬S>üá7çœsÎXçäàX4Dï¾ûî5O¶§AO:é¤5¿N.!!ëIÀ˜jlM˜ï{ßûš#<²yöÙg›ßýîwm¢þô§?5÷ßëuÅ6ó« <ðÀRÜ%®£>zI$R¾[Ôw »¡ÏWÆÃ‡z¨õâSÎ?ôÐC›+¯¼²õToÅõî»ï¶‡l·ÝvåÐÞpú\w)‚|U°• gú(Þ¶öÞ{ïæ3ŸùÌÀþi•—Ú¦O_a½ä’K¶iðÉ|„@„ÀÆ'à¦ÌÞ¾k>ò‘d\]kȉ?B B`Ý pW>+aMîW×½¸“€5&ðôÓOGX³ÆŒ}„@ŒKàÄOl·#*ÂçÃ|éK_jV+¬ùãÿØØé½÷Þ[JO,|póÁ~pé»Eý`Û,žd~ýë_7IÄ0tPÃ#ÏJ"—W_}µ=¯l…Áé§ŸÞnU‹j|Ï“MVsÝ:ž|Õ¸å–[šÛo¿½OêÓ?þøæþá6Dÿ¾.Ó>w]„5ÓÎDâ E%P< ¼õÖ[­8D>~ö³Ÿ5/¾øb»‘‡Ö' ?ùÉO/¢“xÈùä'?¹!<Ðð0sÔQG-–9ä†GÒ•‚‡#Ëö[åØ<°õúPþö¾šë‹3߇@„À¸ž|òÉv¬(ÛácvûµqãÌñ[ˆ°fk&ù&B B B B B B B B B B B B fF€—c=¶yê©§–0Œ¤÷Þ{osøá‡÷z K,o5µ'Û&Ù·ëeØù‹ðý 'œÐòãË®·™ayøå/Ùc´cÞÿþ÷·‚úž?éu‡¥'߇@„@Ì'¿šÏd%U!!!!!!!!!!!!!°í°}ÇÇ>ö±e~衇š·ß~{Ùwãü3h¨]wݵ9à€V%Ö' ³:Ö¶OÄB}E1ÒÅCPíÙÁùÄ5ã„I®;Nü96B B`ý DX³þe„@„@„@„@„@„@„@„@„@„@„@„@lã>ýéO7ûì³Ï2aÇÏþóæùçŸod& ¯¼òJóÒK/-yÁÇ1ÇÓ|üãßÛ@M¤>ç÷¿ÿ}óç?ÿyé+[nñè“!!5ñ$—õ™ù!!!!!!!!!!!!!0<ŸØZè±Çk~ó›ß´q}Üwß}ÍQG5‘‡™x`Ù6På}·rý_ýêW­×ÛIøŸ|øÃn>ñ‰O4ó73‘E¼D-¼Ål·ÝvíöM5DÛ3ñ(ó§?ý©½Þ.»ì2Rôî»ï.¥OœÃ2õÖOµ¨Æõýï÷úß‹kX|}¯+žQa­X»&¶ÊV¹bŒÙ'?ùÉf§vËëϰø§ù½4Ú¶Ë;ÞXIoIój„bâUåÃ1o¼ñÆR;àIøÔ§>Õz™V7¦É ¤c¥´jS¯¿þz›Ö÷Þ{¯ùÈG>Òno¦\µÝ•B÷|[«m¿ýö OW}Î_)þú÷µ*Wå%îÒ¿¨'ãmkC}çJ¡\Wÿ¡ÄË1¿øÅ/–ê’xÅ_êÒJ×(¿wû¨ò½w×Ôùm^ŽOø kþÂ"ŸB B B B B B B B B B B B B`Ý}ôÑÍ;ìÐüö·¿m£b;¨wÞy§5ncÀ'‚!¬a\/aÏ=÷l½â 2ø–c¼/<ñÄÍ‹/¾ØðzSEXÃhLX³×^{µÛJ|ðÁÈuœõç»îº«¿þ/¼ðÂÖpÏèû³Ÿý¬M·ëSa ÃþÙgŸÝxà˼úˆ÷î»ïnãc—·Ï~ö³Í±Ç»•`ç¶Ûnk~ò“Ÿ,yðùñ¼ôY<ò}ÕUWµ†nÿ—@\ ]!Qßë–x½¯5ëúšŒíÏ=÷\óôÓO·e‹¯ºV+Ó½÷Þ»9ôÐCÛrw[¬úZ«ý¬®Ik©ƒÄ"Ê/ù –P‰vÛm·fÓ¦MzH2NU 3ž}öÙ–ÏQÚ^êiCàe7•qÚç8i,ÇŽJ+^O=õTÛ6oÞÜŠÒ°úèG?Ú¾´}|9ä­ê·øÕr>æ„WÎW÷ —œ¯]y­Ô”ôzŸE¹^{íµKí\ú•Ïá‡Þ[T"ï×\sM[Þò N]|ñÅ+–±þåÉ'ŸlYâ~饗.£.áûÌ3Ï´^È\C]"¬q,a e'žxbÛÏ bW¾“?âœ"®yùå——Æ Çøíë_ÿúVý¤ßvß}÷¶]϶-‹"¬YÄRKšC B B B B B B B B B B B 68 õ8Á-0Æî¼óÎc´ bj‰¸Ž;î¸ÖÆÏÂkÝ{ï½­ ‡÷…}ìcÍ~ûíלuÖYÍ©§žÚŠ‚×ýîæ›onˆä‘Há ƒj Ë/¼ðBó½ï}¯¹óÎ;[£v÷º Є ]£ðM7ÝÔÆ÷‡?ü¡½Ô«¯¾ÚvØa[ kþõ_ÿµùÑ~Ôz²è¦Éÿ„„5ÝÀ8OÐsä‘G.»vßëvã+ÿÏ‚u¹Ö¯ýëæž{îiÙÑR—¯c•©ò8å”SšÓO?}hÙ—x×âÝöeDa>ø`£N¼ùæ›K"‚Aדf[©qÄÍI'Ô¦¿[Gç»au‘˜ ¯;K¼ýöÛYDH#¡YÏ&ÃÒ²Ò÷ÃÒJð£=i7„ÅãU!’¾åä“On.¸à‚emÕùÎõR7¯ ¨—\rI[7xì7̪\¿õ­o5µØD='(’‡>·¬üÇl…/ŽW¦„9;î¸ãHñÔõ×_ßÖ[‚ýšþÂ9D4تKDmêÖ  ÇcB¦AB-}Ñ â ö+Þ"¬t uT_Ý·} Šc[ý.šmµä“ï¹"ÀJÀKMÖ0žºsÌ1c kxD(Q™°fض(®óÈ#4ßùÎwZã°­TV Ä?üá›×^{­ÝºéüóÏo Œʣ‚¸‹Q˜šç" o~ó›Íí·ßÞL7Vx~èù,Þü6L $½õqÝx†ý/=¼¥”4—ãú^·_ÞgÉÚ5ñæåâꫯn ò£`¤î(zž`F_ò4­w^„ˆ«Ôy„.óAבf‚nx˜¹üòËz,tî ºHXqà 74·ÜrK+l•Œ°U7¯¼òÊ5õô3(­?ýéO›ïÿû ‘—íª†ñÒÆˆÊ2x§ÁˆPÍù¼³íÈ˰óµÛÔaíuÑEµƒ1ôÝ,ËU»¬ó1¬?”NߨÕýŒÏƒÚ÷üº¿Ug0ÇW}þÁ~Ð ÄêtuÏ'¢Ôÿ–º´ï¾ûnåeG¼}ÛE7~ÿˆ%LF šɸ嬘:^loÃx]Œ°Ä+¼Ø’dƒn"ˆrxû`Ø-á3ŸùLã5ÌSO¼4¸û@ ÃCŒm˜lucûF].ˆòzëyƒ‘Æø‡hÓ_®Ûç]œÿò/ÿÒzu(¢^"l‹%~,·¥½Oþ‡]Ó66ØÑ’ëÖbù•Ϯׄ]vÙe«ï‡]g¥ïgÍšhâÛßþv+)uJmmµÇ{´^jˆ x†!ÀšXŠ‘Ÿ—¿Í".÷ßÿR¹.Q˜´ò£mHŸ´‚¨sþÔõ^™òbÃKɰúÞž0àºL`FTS„ê½-t¤AµmÌ@IDATÜ®M¡n ÚA˜-’þÓúOí6i¢žúWÒúð÷¢ élç%­Ò¬*ÇZh"íÚªrÅR½P?úžÏ‹0<8‰£ÛVerÊuPºÖú;^ÃxªÁ·ôÅúmN߆¹:\ šçxué?ÿçÿÜt=Fòžc»¯RÿqJüò¤½(ÛA}eß2[k6‹„5‹XjIs„@„@„@„@„@„@„@„@„@„@„@„À†$@ØÁøÉkF1–2¼ÚB„¸£Ïv& º¶) xÂaÔ\‡ˆâÑG]:çCúP{Îi§Öê‰y‰\ìŸzê©ÖÌ…ë03}ôÑíV1}ÒYÒR¶H)Žý÷ß¿õÐCÐCÂpLðAÃ।q^ʵ¤g–ïúÃ矾íÕ%õB]"VT/ ž”…:O€S꽺ä[B ê~‡XæË_þr+˜*åAèd;²Rÿµ“¯|å+Ç ýØjúÐYò›·kEX3o%’ô„@„@„@„@„@„@„@„@„@„@„@„@lÓN9唿ž{îYÖ€Áho+§>‚Fÿâmù# ºÃ¶â¥ÆöSÅ[ ë­^.½ôÒVœPvÅAüChÀóÂÿüŸÿ³Ù«#q#ì¼óÎ.Ý+ðRŒÄ®{üñÇ·^7D ]ŒùŒÑ}ò?ì¢ûí·_ãUÂ3Ï<Ó<þøãKmqŸ~úé­€£3í÷Y³&€àÙ¤ð•ŸC=´ù»¿û»ÖÐß5²ãOؤ‰§jqÖ´YÔñu¹øM:ˆ Î:ë¬VüS_Ê‘×!õ‘çu¤ˆ ´—3Ï<³štóXÇÓýÌ“ ž£]xá…­ ‹Ð¬|p{Œ-˜Ô{Á–C¶ü9à€Z9õñkñ¹NëgœÑŽIW-ê‘6|þÇÿø˶""æÐ®ð’Wõ^›W7†ORøªWDD<ƒ<£”ü®U¹žp Ë'åzóôN )¾xé»õ±”Xýµþ©çÝ>ÀЫuŽ'¡R6úɳÏ>{+o7åø¼OF`ô‡“Å™³B B B B B B B B B B B B B &$ÀhÊë@-h!>©½r ‹š×šbìwã,Ì m[¾ûÝï¶[<•8¿ð…/´^Bê4”ß½‹ësŸû\kŒg\/i-"òý¨÷"ú°½ O „Euœ Ë<-ØÞg”Ô5æá·Y³æYèÖ[o]òª‚Án»íÖ\yå•E5~·ÝÑ9çœÓüýßÿ}+¨E~_‹@DpÍ5×,«ƒ;î¸cë=èüóÏßJTS§w!â›+®¸b™÷"â ·ß~»>¼×g„ÿïÿ}[Ç»¢‘ð†£Õu’ §x±éu±U¤mœwÞy­Pª+Š5QaÁT-èÐ?b8ÿÜsÏmÏ×ïtË»œ¯­×çkmÞ²Ñ(áÕZ–kÙºj•øÖütÌjÔ%…j†åâ<ÿðB£íÕ¡öbSŸÏëC šõáž«†@„@„@„@„@„@„@„@„@„@„@„@„À@Ķ ©=¼ùæ›­‘²]ÈÀ·|iË—®Á›ç ^kžjlSâeH'Tàå¢ :×wâ&2(¢‚ž²­Ó°óºß3*ñ‹_j|ÿÏšµr°…Oñ‚™òêŠ$º,•%ïHDN¼Æ”²í7­ÿyO©=‰—Ç"^IÔÇ•ñ‚í¢ê´>üðà ¯.£Äݸ ÉN=õÔVè@ðPÇ×=ÖïÄ(u;%~#ú(ÞCºçLóÿ’VB©=÷Üs™¯¾14Ý> >ÔVgÄ6¶ãêžo»ºQlײ\m±Tyu^çé3¾DMÚ‘òÕŸòvøá‡/«oúüEÍ÷µJK„5kE6ñ†@„@„@„@„@„@„@„@„@„@„@„@„À„ ºž2úxÃènÅË O à ·ß~û2ã-0ϵX`Tl;Â#N퉘c”Á½ñÏ$„}¯ÛcþŸ5kBžZà„-ÆÝz5ŒqÍ,¶”±­P- øèG?ÚnãÔr K§ïÕó®‡WÛñŒã=‰Gžhxx"Œ%x‚©ÛAÍ[o½5ÑGI«÷•ÒÊ U·mí¾ûîm^½¯t¾íŠºçÕ¢­.«µ,×'Ÿ|räµ»iYÿÕ!¢§]vÙe¤¨FÚÔ¥cŽ9f™Ç u‰×©Yˆ´ÖƒÏ¢]sto°h¹IzC B B B B B B B B B B B B`°-R×àýØc5¼ 3´³ðQouÐA5»îºë@Ã91Ë/¾¸LÃsÂ8‚¨m‡S{öxýõ×Ç2zØŽ† b£†õ`m»žZøÀ+ /+Ýí~†1gì籦M ;vÒï¥ï'?ùɲ:¸÷Þ{7êaßt–kŸxâ‰[ÕÝW_}uƒrì°w"í®®ÏÃŽõý c‰!fáMEZµ>i%<Ò®k¯)ÚmßóyÑê ²k†ås­ËUÝÖŽ*¯Yþ†­úQ3uýA^múlÿ7*Îü6=ïŸ^T‰)B B B B B B B B B B B B B`ˆLlÙCøòûßÿ¾’Áž§žj/åz¯¼òJóÒK/-)œ|òÉ[‰ ÊñD¿ùÍo–¨‰(^xá…¡ç”sëw^Qj#÷Ûo¿Ýüö·¿í½ÿ'?ùÉÞèúÚ‹òyÖ¬‰¬”C-¬!VézYo~ê߯ýëeõgÒtÚ Ê¶PÄg%Œ+òê+‚(ño¿ýö[‰ÖÞyç–ûZ ’\œ´òHCã½Ô‰qÎ'ÞÁÖùEL£—Ï…Gy_ër}íµ×†^»¤a½ßÇá+­ÄOÝs´aŒWò(´ÞyÝ®aͶPÊÉc„@„@„@„@„@„@„@„@„@„@„@„ÀÂàãºë®[ÖÈ€í N9å”Â[ÿ0v—`›¦A[À”ß Š‘½|G¸óÆoôò‚QÎq|½ÝŽ8‹A¸7®1¹Ä»‘ÞgÍšX¥² Ç¿ù›¿«\Ëykù>È£ÌN;í4‘€‡›"t)‚šq¶%7¯Ä3Ýú[{Œ7¾µ<žÇ™:­õç>×ížßí;ê8Öº\Å_ʸ¾î"^¤º´Èœ'M{„5“’Ëy!!!!!!!!!!!!!°†öÝwßf¯½öjÞzë­%Ì~ô£VøÂûDm/Û@ñSÂá‡>ÒkÌ <äx­&8 2¯&ÎE?wÖ¬‰ºÂ^æÍóÏ#ÝtÖôd ªEºyæ™g–<Ñðóøã7{î¹ç2¯5?ûÙϚ͛7/yç`?餓FnéÔÝ L[9w#z]Î?è ƒš]vÙeîDu:gýyÖ¬‰±Š¸¤äµ”mùÞmoÖÖðŒ2HdÐ'½ƒ¼ªDœÐ‡ÜtYër]K/DÓ%‘Ø6 k6JI&!!!!!!!!!!!!ŽÀ 'œÐ|ï{ß[ÖÈà=÷ÜÓœ~úéË„5<ðÀ²cxý8äCZÏ1àð,ÓÐsÌ1ÍÁ<ò¼añùžxc¿ýökxÔIø Y³äñÅÖPó&2$ö!BꊂþBrô'y¬ÏÝa‡&®Ë£¯”_GXërµÍ6•³"Ú6+Ò¹N„@„@„@„@„@„@„@„@„@„@„@„@ŒIà3ŸùL³iÓ¦æÍ7ß\òFóä“O6¶¸!^áÙcÐ6PGuTÃøÜÎÔ—ÿèG?ºÕïx`sÅW4ùÈGêCóy•fÍZÙwÅ5ï¼óÎ2ÑÉ*³4•ÓwÞyç­Ò9ÈÛNß‹i'µ°†ç¤0úÒ›Þqk]®»í¶[o¯Fu}˜^Ó¶F š Tâ:…Ÿüä'Í/ùË¥\0¹Ûã*0am˜¬>öØcK‘› šÈÚ÷t[¸¼ôÒKÍ+¯¼Ò¼÷Þ{=-1±gB„@,ý˜qÕM\ Töp@ûÔMù.ïÓ%àæþ¹çž[ŠÔM¯±ƒkãm9xJǸúóŸÿ¼](óÄ™5 $ !!°¸ªç–Þ“ƒ%XdÛu×]³ÀY€¬Á;毾úêRÌÖ0ßqÇ—¾Û?˜ß™ç1DY7Ád¯½öŠáh[¬ És„@„@,ë#Ç|óãÿ¸ùÍo~Ó¦ÚÊ~ô£æÓŸþtcë›î6PÄ6¶òÛ¨À›GwË7Þxc™0aÔùù­?Y³¶~Ô-[÷fó&2øÔ§>µ•°†­s’t²Gýú׿^v.FW`Ô¿Ôrä¤Öº\÷Øc­D%­]!Õþð‡òSÞC`bÖLŒnþN´ÿàÃ?Üî«YRgÑŒ’9šBdúï髯¾z)b“”ý÷ß›Öüñlëám·ÝÖüô§?m…5 \Nž}öÙÁ4!B æ€ÉöC=Ôxú§ÂI‹6 Ó'À ­…›z\ýð‡?ÜqÄÛ´°æw¿û]óè£6wÝuWk5ÎZ9üðÛSO=5¢ÕéWÅÄ!°ˆ;n¿ýöæµ×^[Ša€À£»àµt@>¬Š€qõé§Ÿnî¸ãŽ¥x<ðpÚi§mÓÂsûï¿¿ùáØÎ;<³ûî»7¶W8òÈ#›í·ß~‰W>„@„@„@„À<8öØc›þç^ÖH›í Î:ë¬V<óàƒ.ÛŠxØvLøÀFfƒ7® Éœ‰Í)aºfÍš‡kkuxñÅ›qEk½u”u®îzëóÏ?ߦSÆ Lc·«îÖÔDfóy­ËU׎•œéÓÜ땺KlU>—cF½sì¨xÖë·IDië•ÖEºn„5‹TZ+¤U#ÿÕ¯~Õ Ê¡”È™ükóŽ;ñH :ñmÙ+K©‡7ÜpCc‚V‚tOšÄ]vÙeåë¼oÊœ‘—AdØ$fd3YØ ˜|z2¢îãûÛß.{ÚaIJæYvc_3çr˜g–m5¨‡¼ÔÜtÓM­¸ÂG87„Î9çœòuÞ7enþnÁ'ãê(Ðda‰O5¼ƒÔ}¼ûsÉ„µ#`¬¨™[`&ØÜV„O<ñD+6ª½ý>ûì³í¢½'ˆ?ûÙÏn«x6d¾©ÆV÷«£¶ÀØ™O¦B B 6b`^á_ýõv=VŸzê©ö!ë<ð@Ããm „8æ7+âkpóõbOzá…Úm§ç¬÷1ÚHÝW×cÁz§m#]?šTšÉË6CÀ¤ÀÓu£‚Ô‹ÊׄÁ»ÉµIÔZî‹jrfb_‹jJ:Ky䑿¢‹.Ê$¦@YÀ÷"¤ñÔ‚½JÝp¤O9å”v’»€YJ’C ¶q »Œl£‚1ÕZS«ûØÇÚ­˜ºOþŒŠgÜß,^ÖXHèÆRé>ãŒ3âí¡ gþ7®G©ÆV/uí¸ãދׄ*Ç$5BàÿЧ³^~ùå‘HŒ«þÊýª‡‚,˜3üøn­‘´´Õ¢šr-['ØЧÕqîËùyŸ 1¶Ç¨ÇUO²|ðÁ+nƒ19H*B B B`8÷жvb°^ ÷{ì±vþbM¾މJyˆ\i(qˆ—W\BŠ ÀáÞ{ïml¡³–뮿-…õ`Íô3Ï<³$°'±ûÅ>ûì³bÙš[ñáä“OnÅEXãb ÷¦ ÑÃŒ×}âÎ1Ë ÌšµmÄí0P{®¼õÖ[[O‡vØÐ‡µ¬G¶|ó›ßl=Þ¬õúÓÙgŸÝйõKݶ­íÐ ÊVà{pî{ßû^û€ZI«z{á…¶ëvµè`y‰ä¿µ$°–åêÞqXØÿý›;ï¼sÉë A± ¡Ö°û÷ŠÎùú׿Þxð¢ÔÃaט§ï±¨ë8a ûG õ÷ó”æELK¿us–4‡À&`Ràé«IƒEËwÞ¹uiUÌ´6:p âz"/­&1=+M€&ÍWΛ “ Æ?{ö–ÀmdB„@,*F´IÇU7&nP<ÁåÆÌ˜ê}Z‚FFcw½¸…µñôSŸúT¼À-jÅûÿ鶰Žì£>º”åš!‹J@¿6é¸êžÑ½)a ·ÞÑ÷ÜsÏ¡ Ÿã22f»w1†v…«Dá1§¯ñiÜkçøÙ°xlLõ´s²˜\ÓÈçE&`]Ÿ‡=bÒ2Ÿ!löFñô!ãzAe' ¢á¤Äk<ýÆ7¾Ñœ{î¹m¥Vò\ãá [=÷Üsí|ð‚ .h½ý.2ïµHû¬YoÚ² ’:£Ž”²%BþÖ·¾Õ®_ñèÒN(ßu×]­PÅÖQe©µàQâ´¦Æ#Ów¿ûÝ¥50"Âé&Vջ뮻®¹þúë—ÎïØÆ¹ÝvÛ•Ëä}ÆÖ²\Gݻ鯺êªe÷¦D3Ú±O·.©ówß}wó¯ÿú¯:¿H¢Ej-±¾çaÇóÀËßýÝß-»Ÿ–/"£aâ¢W…»\„5 WdIp¬žÃœI1ØO>ùd«L>á„ÚÅËÕÆnfroÐ2•}7 nˆjlTw^Îõ$àf„Ô¢‘±ÕÞæ¢,8÷Vk<òÈæ¡‡ZZqãèé³£>:ãêj!çü¹!`Áž‡/‹ý\Öë¸'zYm°xè‰kÛ$»ËV ¾gl°Èš!!!óN€ø€—š"’ l¶ÅI1X—ÇpJx|Ùe—µk¶„òp¯ø¢_ýõ6~žzyîõò`­ëóðžCèc+kó¬gŸ}¶qð®ã8¶„¿˜5k6›³Î:«×x[&I‹-Ãvß}÷öÁ1¶#åÍ[=o5Äê›:AœS¼Áü%GÓù¤žð.ã^õ¨\ÇZ±ƒ52v°=É;{”ºXáÄ¥—^Ú›T¡2û÷µ,×Q¹!(s/yóÍ7/ ÃÔ•üÇlëŒ=Ô#÷„ê9q¾:ïu^÷öÛo7<¿,Bp/«ï/ã‚4ßtÓMKâ9™hìÂŽùÒ—¾”‡5'(Øk&€–SB`Þ˜x2žò³¿Î‘±ÏÄÚ»IQ™Œ8Îg“]7y§vÚ²8J\ã¾›°˜¨™4S ›à˜l[ÀäZ0!B B 晀>O³»+Á¸j±È˜êåFÄøV«ž°e‘Á×¾u%®qß¡ž¤`P|õÕWÛ>[|ðÁí“üãÆ—ãC B B`–ˆAyv«½qДqÕ˜jluÿj¼-ÁwÑ«3=¼QÇQŽçݽ³±ÙS×Òä^Øw Ä;¾Ky'`Þb]À©ÌŸÊ»´ó¤ëaœ®’•òu衇6—_~yë!„§²æAìÌŽàšÖ(¬™Xû·Âæ`>GŒQ{Ñq­ÚÀ»Òµ·µßgÍÚC`D+¶Bg ”ïm·ÝÖ ¡<Æ®S„5Ê»”¿¹òßþíß6„8Ö»Ê÷kQfÄ—\rI[Õ§R¯ m¬¹©ê¡WÖ”u¸r¬tñFyþùç·÷ñV³%5^œëQ®Öw/¾øâV0£*õÃO¼5¹·¬…5l™åéýÊW¾Òz¼±Í^ù~¼\ÏöhÂýÊ<°$$ÒŽ ‰Òja±Ò ㈰f<^9:æ’€…@*]Ž:˜XXŒ$ªñ*\Ê^î‘K0Áµ¹c tV»˜hÀ2 wÞy­ÒS:¸óîîñW®Ÿ÷˜'Æ1ÛNÔãª(ãY-Xµ€å&Ÿ§7ñ%oï¿ÿþvÉ œ§zV$¥Ç8ê:®,by™$„@„@„À<ð¬>˜,Æ[´¯ïW-ð[ä´`n¼Œ¿ÆÚ;ýŸû÷Õnc\¼ÓxÑ5¥¶]œÖ6ŽmBó'B B B Ö€õ°2×Û?•KòNψ:n0/òÀ,£ë5×\ÓŠœ­AŒË^+ñ0òAdÝb0­Y³6×%Ž17ÿÞ÷¾·ä‰FêÌÁ½ºA=0'J?óÌ3›'žx¢{ÈšüÎ9ç´ñ^{íµ­˲ •wžE¼F¢ˆÓO?½U¨ƒ óA`=ÊÕC‰2¶c-÷¡Ös½ê Î.^tÑEÍgœÑžWÿ>ÏŸ ÈŠ×1f–¼ºç-bº’þÕÞS—x¶Å÷k¶ÅROž7$‹ƒT‡£—f ræ=öXóøã/)ýæ{{î™`M2ñ®¯mb¨#_)Mõ9ù!!ó@Àf\i #L%T5~>òÈ#í>åfß–q–¡ŽÐ´»oï¸ù,iZíø<îus|„@„@¬–@ñ7j\µègìdâÆÝ¸Z?1hk(.á«Üy3¬&HOpÓØ^j5éȹ!!!!0)Þç=ÔSPÅåáÛ@Mꥃ×\ó.ó/[>3DCí 4{(ˆˆxyÓ¶ZéA[kÖ;Jà§þ¿|ß÷}ÒøºÛU›ŽI¯;KÖ*S†w×e"’òY7xÀ‹x‹¸€ÐÀüÛÚ–y´à]<«)¯îuËÿD@¼ëðJ£Z_ãAiPZË9ê;¯;„ê¿×8âI˰\ŸçºÍá‚OáUŽ›ÆûjÓºÚóK{)k }ÛËz”«rñÐ#1"± º4HŒXê¼~KW÷}§Î+K}_ß:Gúò)çhk^ú\ÁõK:Ê1ÃÞ¥ÿßý»×Üzë­í=uÙú¸>^_ý¹Ï}®ñž0>PŸYÎ…% £4±6¡51Ò›|×} „?üá[W‘'žxâÂæ3 Yp“ÃHÈKoon˜ W˸Ês pÜ/»±IL ,z²y×]wmѹ¥ß\=UÈhôÐCµ¿ï½÷Þƒ#Ê·!!!!° øêW¿Úz!80ŸbD¶a®Ä(Äk!^XmZy ÒN'mw¶Øâh’óg]®ÊF½VwÕeBÁ—_~¹­G„+~+õǽ¨-Óôe%ð\ã{Çé_Wê׈Â6m²·ª£â§hƒ_þò—Ûm‹­1BtÐA½ê4¾®¯}ö³Ÿmûl×y„Õ·é—Ýoój&ï ㈰f|fS9Cƒõ„3÷K ŒâMEöRù5†ïÓ :u“ ƒÆT ÊKçâ5Nv{ÔÔJ0pi¼}§8 àÜ<— ƒ¢JõY÷ÚÎ19À®\Š›K;>î8—|S,p×#H Åm7`g€§ÓíÆ1è¨ÀZ<Ø”ãÔͻᄏ5š :tûiÚ“¾oP' JXO;Hú'?êµÏòbÀ+íIY¯tC!&‡ã¸tm7Ú&Ú”6­Ü œÚ°6¥~b: ù“g¯ÒŸøÎK^Ô!y. þÒ£ †Õ+ùÁ°n‹uÚÔ׺­ûÍõÜ`¤ûiÃdTÛîOŽ Œõ¸ZÚ ïµíÐËØ`LѦ\øjLÕfŒcÆ×u=ýŽkŽÓ§H›>Dÿª-– ÿ0ñÖvËqå]ºôIú‡¤KÛ5·è^["ýuß-ßúýž|Wõe\•wýý¸ù.é\Íû¨>ÌM­§Wú2ì›õËM–€yíFÀC9¤å3,Nüœk<éäg¼§JÝ1®¨Ó^Ú¶¥ŒÕ!}ù¨ }êÀ¸}=¸©[ÆmÚwêbY°Ó®¼¤gš¡ÔåPÆtm×—'/éЗx•¶îûAÁ¹ÆÍa®Š]«nëâоŒ«}ëƒkkÛúœ„X-Ò‡Ô]íB;(sK}žþ´Œ Ól‡Æ}ŽqÕõõ=‚6§­éO´} KãmL¿¢?)Á¸&ÚvŸ€ƒ8¤¯éÐK߰н6^Ωç#ò­¿“o×0®úgùöZiüvýÕ~¯“&}b7`(/+ÝóVúßCŠ9Þecã1ö¹çžkÍÍk†e-ÝÝþuØñ¾WŽ8ã>Í -øyÉ—~ÞÚ…kê»»Oº¾cñ·þ»–1Èš6åõ«ŒgÚ•õå9Šé 4úÎ5Ôem¹´ÒŸøMÛóÒ§È›r÷ÂcÔ‚ë:8ʶã¤cÒëÖù\kÖõµÌ'Öy­0W3?5oSܧ¸ç4o"@b¬W^ÊÊñkÌS½Ü H«ù½´*+s5é(i·þÕi_mj—_~y›6÷PkÉgµi­ÏW†Ò>N}·=ï1dz´>I»U¹–2–?uW[/¶lõÈ=‘úc͇nà½K¨þi7ÃÖþêóˆx­­¨£ƒÚR}|÷³t\yå•Kk±Îç¾DßÌËa—{&}·v#íújí»O>ºéÊÿÿÀàÕßÐY,wa~Ae.™ÆÌ¯ƒ¡üÜgŸ}&JWYär}×}ôÑG—ÔeQECÕ J£²ˆE×·±(<‘M9Z‚|üýßÿ}ï8¤«ç믿¾DÑòÐISô Ýk<¥hDÐá‰×ä Yäwi,ù¶€V:ßÏ*HËí·ßÞîWZ_S™È7•íZõ‚qÑž©ø”G<ÕjeͰ`Pxþùç›;ï¼sØ![}kq÷Õ~¡ÞHûSO=Õ¾Lî eÁÒïê±r69-íaØåÆI#VÚñüã–!nì´çb|0èyiËTÓî}÷ÝwÅt KŸïå  ƒ^DYåÝ„ÒËïÚ‚—üË—ÅIýŠº®ÜMmFœ7ÜpàŸ[ã"czä™ûȾmGýæéÈ#¬£Éç‹€6XÆU}{Wµ2®ªÿ^å&K[ô2¦RÖOJ?âúe|¡t/ã‹ë«ãÚ\1T¨ëžòé;iÕ‡Ýwß}Íæ-Oi— Í~þóŸï‡t˜sK– =žöðÔɰн¶›ã‘›ÁøiÿY}Ÿ¾BËô;8Ë·þVŸg9à€z§yXšú~_n²ïºë®eìœo0¿Ö÷õ½Æ°ã”­:uÒI'µ‚#7g‚rÀIYªÃ®öª&Âéäɸjþ2€Ÿ›-cªy@ÖW•±ñ§ÌG¼JZÆMŸ±S;rýR·Ê¸ZÆ5cj™#W‰…K»,×ç]¾ôe\5žW±P~ÒU®¯œëqO×iWæìƒ‚óÍ™î¸ãŽA?·×ÐŽê€ýM7ÝÔ^«þ~Øgmθêɬ„˜”€vî~I¥NZ´ÔþK;°e®ç¥-SŒ©Ú€ù-ƒÿ¸AœeÏøcÜrO©ÐKßãzê¹kº76.¹—é»pjîzï½÷. 4¤Ó˜`1¹oî9ÜóÚþ¯ý¾8ŒyÃB÷Ú±Œ©e,ÆXŸ+^ùÆ]Ÿ¤O6ëg\K¯ïë›æaiêû½¹Î /¼Ðz9-â–r®ñÔÂú$å^âõnNa¡O6—QõD­ÿW÷†}ø<ЦØ1Ýï•£¾Ô¸2`ìЖlm¥mI“ô+selì’O㥲.maصÇMŸöcΦ]™³Z@VÍ9”­¶l\W¿ŒaæÇÖR´ë•Ò2,¾7®†êK¼´ÿË·1QY:F=.ãjßñÄÈÚ§6?(ȃ­Âp\Ç8Zuû¾mGýÒNù !°–Ê=¥v¢mtéïõý!$¡“‡E `õZë`.î5í0íôOŸy‘פaÒëºÞZ±î^Ë|pÔ½L÷xÿO3Ÿƒâö¹sc ;fµß¯6oÒh>;‹°Ú´®÷ù…Ñ,ʵ\˻빗g}x’y™û»Õéœäºõ5Å1«¾¤¾îFÿaÍŒJØ ¼‹„̺7ùÃ’Áh¥ñXÜ™TXcp´xAXbaIœeQª\×ÿé³è⦎q¨Ï@`ÑÏ‚W½°a¨{r½AïVOê8,bPÕ Ýk[()iv}B"ùf¬Â¡~W6Œ8Ž,vYl’ïa‹8õù«ýÌèFTsóÍ7·y/ñ™ÀQ ¯¥+=×Â×"¸—úQ‚…6‹Æ£„5¸[ô­Ë«œ?ì]˜´ŠÓB%C•2f„Soù)å<è÷ú;iÄ}TPWÕÌl¥]‹P°`jQû°ãæ- ‹ÅjuÜ€»vÂð*ßJ]cPÀ§e1Üuù‡MÊ5Æ)ÛRõõF}6qe`un~ 2^”¶ÏXÀPÑ'èëõïŒà,Ç ÎgЯ×íó«ÿéŽw~×Vµý2®ú_ÛSÿW â3&ÕíP[ïŽc£â±ˆééä:7 +‰0º×6Ñ_îò­ÒÿvûùVúc¿+Œiel•æÕü&}®uë–=dï¹çž%Á¨8õ{ŒĪ} *“¤EÙz‰A®+{ó¯Qý–æ uy­” ïÅ0»Ò±+ý®~1ìÛ¤½+ô(ç—º]þõ.}œϨã”qÔµÕ/mš1pP0wblW·0ÕN<%Ã7IÓNÔ›>{v+#ù/Ay Ú™9Ó0akHó8e«ÆýîJÁ½®óä³ ÈÝë”ß½kÿ®[·eó‚Qˆ§{mc*ñ‚¾O|%ßî¿»éÑè?ôu.ÆW÷ªú~Ì×2¸'ÀŒx^[ú?y&jÒï )¿µ Æ]s)¬JPŽDH£„5Ø9®.¯rþ°ws •æIÃÎí~ïÐxjl5WU·Û'Hߨ{ô‡º¥>¹¶ù2Îí߃æm8;öè£nïÛ'1,™«ºGU¯­Á+»óÅ’Žz^[3°NaÎ4lMÆyÚÂ8e+þú% ÃÞÕ½:}ÃŽË÷!°ú)÷-^ú4uNÝÓÎÏ<ó̶[Ë>v5iïsnò·ûšŽ‘}Ê Ç„@„@„@„@L—@„5Óå¹UlÅÈëÇý÷ßß.XluÐ _0,Œ³PGgÑËËSï?øÁÚµú÷AŸ¥™ñßžEJn«)H¿›Q òm!ÐBíJÁyg¾ÿýï·F·âñf¥ó&ýÝQô1¸•`qÚB–} ‡ ʱÓx· ËàiÑ­ _ꀅ¶> Õå¼Y¾K£…Þ«¯¾º]dî.ÖÉW®à[‚W›FõD\žxU~êL7hs¸u¯)Œ,=Ý:j1¸¯k[˜¸í¶ÛZOAu½é›ÿC`£`äцŒ«Äƪq‚vd\í+píÆ­}KƒÅOm±6òt-ÿ3’1†éŠp²ü¶ïòk\ÅÌã^ö´©óc aHb°Ñ'7õ1Óú¬\¥I™èŸ=É\‚±ÀµÏ8㌡‡rì4Þ= à)çZXcÌ/‹åóøä³ºi|⩌1¬6ìªóCD+êñ ãܤì”ñL›R· z̺×5&ÚÙ9úÂUOÙ÷ ®­^›#›§Éö/Ç…À"ÐŽÓyúò>LÔ6,oæ·Ú°~n’@XCàú„u}„²®G€£O0矦p’<Œ{Ž>7bž¬ä»<ä2*.}‘„>[¾§%¬tMý½¹‹{Uâˆr_cLpzÚi§µ¢Æa‡AqNòëÙ^š0¶žsYÑïc¹–‚ÙIÒìuÔ<Õý¢‡ð,Az©æ„ê°9K÷^¶;É»±ÍœÃ\™¸eP›2¦ ÝëšW«æNŒûã<•îÚÖ<8Dô¢IL@{±fùo|£¶Õóï2á _hŒƒc˜ïo“¿ß5‹\~ó]»’ºX?Ö¬!{7&®»îºÖcJYŒ*—´ Âå®—)F ’Ž+bšA‹ åü>ïp,¦‹Ô†ŠâJÚSèÒɨÀR¢,îY賘2ÉÓ‡}Ò·VÇH»T¢bü³(çi^‹ròmI¾-hÖ È>[ØåU`ؓǫM·&×°àT—±."— .¸ } pµ×és>ߦÿÿ”iYøR'Ô‹€\ Œ\ê…§-uÏâo½:è¸I¾·ÅT[$Xp(Aš”q©³Œ©ò¢>X°·¸×5Âk‡< ”§ÜG•»ÅOOµ»vñãúÊGOojÏ\½¹®EUÇY`´P"=Å£‚öþÅ/~±·‹I†m(íRÜ%ȃn¯²H+=8éOÊ‚­´¨oÚ¨€£x†yíª›m«¯ÁØBò8‹´£Ò›ß¶ê4#ŠqÕØÖWÕûz\UÏôk^e\ÕV´CƼºЦÞòb,Ðö±ÕßÉ·sý¾šØ…@¿ÜÃL’Žaçèë¥ïÖ-ãO5uKŸox +ubX<ÓúÞ8¢>`Rê(ú_ufØ=E“Jé¦GØ®vn8(^÷]±¨qmÓ–ûE/y’>iÐŽ<0‚y½.!^íO}p¬`\0¶Ž êŒ9‘¹W©[Ž7W5F»_.óÐ2ŽS±0§Ò/h[~3¾yè§ïX$cjWŒ¥žª;æb8È{NùW>꘲4¯PÆÍQAzÔ‰aãª|›S”y˜¸ÔÜWŠ»\WÿÓ7ß圼‡À8Ôu÷”Ú¿¾½ڂ߬ê±.&‹]~u}Ìç¿è·Rû—ãói -ò3òto’,fØ3Ú†|7JÜø;ÏË 7¼Œe!eŒË·‡Z¤¨E5nƈ¸Ë·Ý‹'¥,ìYÔd|oÓÂ#Å¢ ŒNò]D5 "„2ò] ŸqܬZôRFu¾-yâýÒK/z¶-1NÞxãË ReÑ k‹D³ Í-D[äòd[ --° Ö¨K²ÔÝA¡,v¯…°F;Á!  dê´í]¸ï®™‹!¡S¯óé@[ÖþµAý©~M]/ãªú¯?ÒŽ´‹I~úñ꿽ë#õ…Ę>kâ/ížÁ¾´{íнœö5j«½’¯yy7—.žgäA¾Í_Ì'ä¥ôç^ʘjNQòí{÷î}û»qò­Y[éc•· ú}¢ýó°þlœkõ=VÝ*u°ÌCœk<ð¿ßý¨þÜÀ à|c€:5Í@Xm ÅZJ „,Ê—ØwÓaz]‚1Å<‰§÷‹u¿î3I‚¶9j\-scdÛŒÅÊÎØ¬M»,ãº:åzúBãô˜_™³H5«ak%Þ§Îxi³‚±ÛüØviú–r¿ªN•ûUé–^eâ%£Dåþ{˜·*ù1·©çL¸ã_Ä¿mGü‘†ÂiÄaù)&& ÷Òómý‰>lÒ1vP¼³ú.ù[ìò›U=ÉuB B B B`ÑDX³F%f±Þ"„…šÚøgQÃbÙqÇ×.XŠÑ"‹Ï“烇E×µF`P§²Xòï|gé'i·ÀÂƒŠ…E cJÀøÄOly $u`€oåÒÍ7×Í„ÓÌ·& í NcÇ€ÊÀU‚…/ÛgY°ì–YIëÉ'ŸÜ.b^uÕUK Óâ°è)ÃeË5”Ÿ…m %X˜Ó¦ÄÝ«X0UÇ´/†iTöe¡‘1Â`yj°ÄÛ}WU¼JPo¶‰±¯Í{ ]£ò¨>/ñ ŠS\Ò­«ƒ´ÈGÄ25•|ž&}Jñ,Q«êÃÉEûQ àŒEŒïŒsêù$ÁµË"½ñEßM,RÆÐ'Ã#†¶víµ×–¯Ûë3à—º}ÕÒAsöAžË˜%Íú5 yïö-ú:ýÖú·pgü$Ô˜V¾Ëx@`L¨E‡úsiT6Ý4–4­å{éÿË̵,šñÈ k[0—ÖaéepªãǸß)'†3sžÒ®”99 Cu·¼Ì”3¶ÚRŒ¼‚ñÍÜAú]•™ñ¤´)q+Ï<ó̶~uç\^Æ[i`t#˜Õ?®mžež;Ê çXi5¦ÖcºþƒÁXÞ/ïe\íŽù£ÆUçé¼…b¼¬3¿`HVêcó9&! ?aÈïŠjÔ¹Ã;¬5Â3D×€îu´=íNß6©°«"õ' øÆ ã¹¾ e.MP !Œéîa̺ýU}þ<}Öÿ”ûýCy8÷nßIl‰áA7ßòN(1­|ëÇô‹DÌÄ¥o¿yNÕ êך¯ûlÊ|ÄõÔ"t}ýµ¹Ø°àA‰z;äaÇ󽱞·—çŸ~I¬f|7žKvç‹âÖÆô÷æ•Î×.‹¡Ýº†²WÿûBÔ õ¤Ü‡+;LWÕ¯îú“²ôÒ~½<Äá|÷ÈæÄw¼éŒ¿£‚´e‹–PÏ|uïÃÕÅQõ3e;¬|ñëò2§ÐO¬Gý-<ò5ã€v6*˜ŸšcŽ:w½KþþŸ—¹E-¿õ®?¹~„@„@„@Ì+ɬJóš›9I—I3C©òT™¤Y`x&Ö`„ï.jt“ïx‹GžNðÔÞj‚…™®¨¦ÄkáÉ“Ýõ¢¨¼xúÜbÎ"‹)G V,ð Ê·E»²˜8¼»©dìáI§^l*¢¢®ðg×퇅ì®ñJÙ×õ·O<³8¦µkñ”ú]Úɨ8¬-(ÖO´£¢EÀQÁu <}X‚…pmÚBe×ÀVŽñޝÅÈÓN;­]ü.¿‰sóïÄ+‹ƒDvuÐf=Í?LSÛý<ŠS÷ØüëM@;Õ'óJR÷ËÚ oM_|qûê(Qo˜`Å1Äú¦z\a ÑoCâjÓnŒ*u‚¨¦Ä[D5úÜõ%oº}³>ÞæSê!Ãb-J2?5ïÔ¶FŽ3¦2— ~+öV ŽeÀ嵡ãš1Ú<¹®?å÷ò®í3¦1À‡KP¿3kãsù­û®/©½ øÝ¼[ž&1ºbÕ½vþõ& ýñx ŠÏ%è? UmúsìQ¡·µ†ÿIƒöëÅ9çœÓŽ›]QxáÆïú>ÚýŠ1 ÜOšŽYŸ'O¼’tE5%ߨtóm<Ñw×å·šôWÝYÃàa®Ì·”Íz‹jäË}}wž'ïó6Ÿ"ô1®Öã½õC óHWÊ0Y[ªTáX½~PŽï¾k Ú´ûËÌEF‰ÕêvS~/ïÆ_¢]êëk[ÆÔúœrN÷]»é4V«ãƒD5Ýóëÿ3¦Ö4òy£0nê÷ƒ‚viÐû"†äo±Ëoë\Ò!!!³ 0xö>‹+oàk0ZŒêÁ-dX,œõÓtžòTù¹çž»Ì¸×-‹nêj‰cŠA³{ü¼ÿϨeaÈBe÷ ¨:í%ßµaÆïÓÌ7Cíˆjê§Õ¥‘¨‡ài5‹Ñu~&ùìF¾»Øeqµ^œ$Þµ8Ç¢y×`gQß"$CÛ¨ ¬å³»E„8ë'ÖÅ¡ ‰jÍJ`xc¸íOËïõ»kë kÖâíz©Ï+Ÿ‡ ´ï„ØèN<9Ýmûúv}¼{mlVÁâ¦ñå¬-ÛŸ ó@!-úVid¬ƒüÔB†ú·yþÌЩ“÷QÂ}1.]ÁÑ´ò]D5<•ð X -ñ–F¢ÚQe³Öœ1è.‚›Wèóç)çyK©ƒ²5Wí3¦ÿ´¿:ˆ³ö@SÿVVn¼ÀÕÞ·Vª_%mžpŠx­fÍÈ;ÒJaÐIœ+å{¥xó{,m”°¦î?Õ}Â6÷&Úâ,ÇÕ"ÜènçÚeiÎۿ!H÷œyý_¼¸— f¬ïºi–oÆÕn¾ )¦q¿f\%t¼õÖ[[.åá iT6µÄ£Æþnš§ý¿ûf¯:˜WÌ› Ê˜V·+éUv83ž—<ùݱ^u_7Îú÷òYÿJù‰Ï½Rý*ç;Þšˆ~ ¾Ç$ªéÎÁË9õ»òè Äé•!°5¢;óÞAbrý/¡«õÙnß·uLóùMò·Øå7Ÿµ*© õ';Ü5(‹; ð¨J°Pé)¡Õzž)ñõ}·ˆáº¼¡ zò¯ãk5~—Z Ò=gÿ—OËõYt|íQ ä»QLšO LêQMŸ›c[ÕÔO…MzÕžW¥ÄÅ8…ÚÕ¦«{¾öÕ}Â\ûêËpбòÚ}º®¾®ß-fÚ*£uÆ¢'Ï}ƒJOœÖ"*†=õB=¤»ëyÁÂ%÷å‹fH•Ïüƒè‹´¿z\ed2¾­ÖóÌ ëúNßí©ò•D›%m·;¾h﵇•rì<¿0Ø^©ûÄø t+Ÿî¼C¾û†ÅW¾S°#¨!¬©ãs=Lˆj-P—8fñn1ƒ:èïçMX#=]ŒtwÇ›:õçAÇö©ßXx¢Ÿ`®m‹áÑ–©}C4áZÝÆ\ß¼u%cë :j[FÉyœÿôe’ãB øîvÃæ§ÆÕzžÚ'®Õc¯ï¶kwë–Aq»·ëzÞ $X´ù°|‚ZèÞ‡ Ê·<ÊwQ :§ÏwÆU‰[ˆjlÍEDlÞÓ瞺Ïõ&=Æ}”9Uô÷^óÌQ깉´yx©/¿AǪÛ+•3/¼ð²‡»Ì×eºBQ¼Ì¥¾¤£×–/c÷¨0¨Žºoç iÞÊiT>ò[ÌŠ€~MûùÏ~ɳ“u¦rOó…/|aæcò4óžü-vùM³.$®ØHâê`Ê¥iaÊBŠÅÊ:X$tÃ4ë' \©¯è@š»Þ]JžêüÌûgùw ˆAù^­G HÅSÍo¼±„1‡¨†›õÚ´tÀŒ?0v*gœ„Þ—S¹Äîyèç»QmÓ""6µ!ÜñŒyÊrœ`qx­ÞzŠaSÜ£ ™ÎënãFXc) ŸŒÒc6—”@IDAT!&!6Â6Oÿv]Ðó”¡Ÿ×6fŒç¶AêÛwë_º^­üð)ªð~×+‡åÁ˜Ò5"É÷J†¡añù^ÿ¯¯$¨ñª=HìWWÐ3*εúM¹/¸j|룓Ã8 :Ö8´R»4~1¶Õí@Û"¬5Jƒ4/åizõ„0FÜ£êQNw[ç<øàƒ­çÆn[Xd\D=ß-2óNžªê>T=ç©ÊöO³î»þÇÙ‚M›ïzwÑæMÇ ~¦XU}”oeé5iÐ_QmùÊ=–¾Ý}ÅgœÑŠ­º‚žI¯·šóÔÑEèo^Ý0h¼ìSþï«M®Ô.ͺ[P™¹ï\éÜr]ï®mþæU<1W0ÓÆFÕcnWج¯!†O8îw»ù«¯ŸÏ!°­ |#¬1&¼ê?ÜoºZÿw^F‰ºé^‹|ÕÜÿý­§‹\%bx:‘7qÒXÎ_«w‹]uƤ>f=>KW÷iVi÷Ä}×@6(} »Ý§ó-62ž ÎéŠå 'iÓ„»FvéWGFÕi”?ÆO#–`õ–[ni6oÞÜ.Vòˆã¸î5ÊñyE# ý1˜×ãªvÄ>ªÝ®U>]{T[í^×ñÝ'ѲíÉ]‹º}E5賺ÂÃÕäÛ¹ú»»ï¾»Õck© ET3N»–¡;®ª kyý>qKSwÞ§­ñøÒG”íØÚŸkªï+KÌCXSéç©úr®ñ¸+â2o•‡QÂõ“‡Ñ¢lߪžoºé¦æÅ_l…ŒËÒÕ½F¹~ÞC`ÑxD»5¾– ýñT³}(aÉ(c}Icy7uÅ{úÛnŸ[ŽŸ×wùî+ª‘‡iç[g~uÛm·µÛÒÖ¢÷güQÍ8i\KÖÖY¤¹ƒ˜Ô¿¯ÇgiòªѦvúÜŸ9®ûpóVj›æEõÜÈõ£ÆÁ:õgýAwn ^£ÚªqRÝyâ‰'–æÚåóÏ?ß ùÜú—5®üt¯Q§!ŸC`[" zpC?'˜Ÿo¤üm¤ÒL^B B B B "¬™r°ØÓ5ô1øO9)G'½Ûb˜f¾-T{âù†nX&â`l*¢†Ày nà»Oyº™Ÿ—…Ôš“…ô®1ÍÖ ¼¶ŒZ„Ð>å³ÞzB܃⬯iA°GùM[,‹Ðõñ£>3¦¿úê«Ë×0¹ì€-ÿ¨Ÿ$l?c±µN'åIz ½õ;XõYÄí^/ÿ‡À¼Ð><íZ¢YoUQ_ÜÏÓ_ƽöz?­|ë»sx€»ýöÛ—¶§?á²…hšyêëÔÛZ ¦ÔÛ®0t=Ëǵµº"ãÚsÏ=׊JVS‰žyæ™eÙç²¶üS„/õ÷x=ýôÓ+އõ9>ë1ÑwÆÚ®Ñ÷u7c¥úsýõ×/Õ+õM¾yä‘–­±´Œ«ÆÖˆlj’ù¼hîy?¬·~™÷Û-„[°d,Oäû?‹–…VÞ…À öaá^š°mPy!)A=ðd4Áê<‰j¤O?߬Jï¼ kŒ›6mjÓU¶„2ÞS:è v¼-¼»ïÆ-cªr)xˆpx%o‰ø”1¼œklã‘hÜEwã`íyC|þïÆ_®S¿Ëÿ‘GÙûÀ´Í2®z—&Â]‚b@cª±ÕËܡ둪Ž?ŸC` ±u…D5ŒÍci­Mšô‘ú5ÛÕ÷ îjæMTƒ‚û=÷_u ª™·>Øøg¬À·ˆJŒ«Æ b’AÁ˜ã8KÔÞU•‰8W¾aÓm×D:„§£Ä<ƒÒbÞUÒ^~Ôo”ßêwi=á„ÚyíÅêy›±ßöØ^òé¼Ü¯–q•WH󥄘G¹cr©Xéà-d¬d`˜r2Ý:`X²µ÷Ú¦J°@õÒK/µF§q¸Jkñn‘«û´·ôÍã;¶ŒZ a p‚vç 8‚Òˆkê',•'ö~øáöœÚØi‘ò¤“Niìw¡Òwu<«-ñõ O<ñĶyÑSõ‚¥8Ä¥âqÀŠ Î+¹Þ&Ìaˆž§ú×'ß9fÛ%PêsM€á}œí˜êsóy1 ¤0À«Ê¸ªnèó=Ù­Ÿ›§~«Û7¿ê±iJ‚QÒ˜à sc¤€¯ùË7ÞØòÝÿý—‘Å0Æ3Ÿ-/Ëøˆ¿ùîÑG½¢ˆÓ5ºR߭Ǹªîðx$팀<ð˜3ÔAÚ<½ïEÀÊ{€y¡¯9‡yÉ<Õ¿:íù]Ú^·ý雿QPßM{þŸcªù”~­Ü‡x7vñøeܧ~mG÷Eóæ±F;:ðÀ۱–‚‚5Û#yH‚èÄ}Yn푇m8®ˆE•û7ñu·—êÖç”óÊoƒ¾+¿û^êHŸóŒ‰¼ñDS¸]±«´™Óy¹Ÿ5Wå•°—Hwžê_Ÿ|ç˜O š5(ãqÖàò‰r X"H9ï¼óZq÷Ú‚záé3Û X<ôÐC×9¥¹¼Å¾®ËiÀQ^\þröì?Yèå¡ Þ2‚¡¯Ãl‰dqN90†1•'ë­!,hèüñ#3¡LëÅOûÎÂ)N« òÓטáºåiR‹ûî»o+ÖòD¢WwÑR½“/B^nŽ:ê¨öï5«-¹œ? SgAy¾¯QÆ£cŽ9¦áUEß/0Ê0Zñ§f|š—@ R?q.]Òhlš·À¸zÜqÇµÛ ò^ ËxšÜ˜ÉÈÅÀeœ2ÖúΜA9Ô¿ÕqÄ+f‘±°k$TÎÆÃiŒ«„/}ELÆU"ÛÏ}îs­QÏXI\dûŽâɧd †g/âUÇ:×¼nÞ<'”4ç=jWkÛægý¯¾]Ÿ¥¿w!èï{ì±öû3Î8cnîËýLw{"}÷Jž\f]ÂÆ”½÷Þ»Œ!åÞÌøÊ3!‰ß½ø›/ømóïoîaë1‡wã3ìJÁØÙõôbÞá~OšVˆP»÷ÃÃâ4ÆÕ¸_ß´Å+ž{ôW^y¥}ñVÓõ†CX¤š[˜×™óÉww®0ìšù>B B B B B B fA š)S¶hÑ5V[âM#aÛ! ئä /lÓŠP]`€¹îºëÚ…)O¯w` R?kÁ‰ô[<ó´Ù¼iìˆh,ÈÙ2„qްÆ1aËõ%?~÷”¹§é|,TZü¬ƒ…Pžn,®6XÝ´eÑqœ`Á’¡S1-@2–ücÐõž…År¿1H{BÇ„˜gêz×X­­w½Ìs’¶Õ`Xa`9ûì³[#ïocŒ1–±Ç1‡ëŒŽj zl™GÁjºcªqgã ‘Š—9ƒí‘joÎ7Þmò¨Ö*eEüR‡âAÎØ¶Ú {íµ×XÑë1Íß”#`=®Ùð ÀÓ•~‰°¨ðëâ98fH@ûëàÿ‹`†IÉ¥Ö‘€ûž,•ûm·ÝÖ >$GÿÐCµs¯âÍk“Ù^ZݯÖu´ˆU?ñ‰O¬wòz__úy¤áù̘Z„MîÙŒ¹%˜3‹x·!ÚÔfW eœ®ãǶ^Óá<î6¬òGôln¦üʸê^Ô=«ïêù„yˆñ”h—ØÈÚ<Ã%„@„@„@„@„@„@„À¼ˆ°f J¢ëyÂ'“¶-Ä,"]pÁí“g5‚úà çk¯½¶¹üòË{=¶–ä,fÙ󱬋í R+ NÊñ³|ÇÏ‚ïí·ß¾dXgÄ’VOøùÝËÂe½øZÒÈpÆ8k‘òðÃo÷u/¿ {/ÑúwŒ,2$®g6‹¥DBÜf[„´Xé©?‹—ž|d ,ý‘tõsÓ˜‚žOÞC`V´oÆ‚:A`ý]>o| 4p@+´õŸ¾N 4Ž1²ñ·Ûn»­+ caõ¸JèA¬ÚGt2Ëăî½÷Þ%ï3Ƭ=EoÌpÌ -8¤ÓqÆÆY¯¾bSchWXƒ Á±ñl=CÓBÙ"‹ð¸Œ«ær›·x œ*A9àÜu×]­0‡!3!æ™#}×óÃ~W=ÏyHÚ¦CÀ=A {&[ìºlK¤žLv0˜ÎÕûÇ¢ÖÏ“J ô0æô”sfñnL œáõ­Ü‹–öVD$¸µÇ·:]n!&!ˆ1ù¿O0WîÞ»gÝï®÷¸¤ŒW½ÌjJ™S­æN%˜×ñ§ÞÛNCp[âÎ{„@„@„@„@„@„@¬†@„5«¡7à\ÀwÜqÙ/ õü²7Ð?ƒžÐ­Ÿ¼ê“ÕÚÕçøy?†qŠ›m†¾ï|ç;K+uÂbÏ5—]vÙº¥Ã¢Þ#<² ¥Å?éžÇ`AòÑGmÊ[êE·3Ï<³]¤#(±(Ì hQ®OÞ,LZ€µHiÁ’A°OGwAO]ínóÑ'®µ<¦¤SZ‰lxô`Ü}òÉ'Û2ÆDPîÒîiTÑi Ýõb÷4âL!€@©×5 íÏ¢üFÝqUgœt¼ö¾‘£#°- Š·5ÂJcƒñëÜsÏ]·-—”9Ÿ'ÒëÀ£‹­æ-àh<-éÕÞvß}÷æØcmç, _æ Æã/AŒ¼xS‰˜Œ©Æ’b8ì“GF¶®°FüóÖ®å×ú^ò©lL ¹03ÏÌw‰Y}?-fÆÕ>5)ÇLB`g‹mAXÓS±3FŽ3NnÄqÕ}ƒmq‰@lUTVî#î¹çž¶o·Q_Ç$urÔ9D(¶"¬©ƒ{ºyôçžÌx{ŒwÆ4¸ÿò;Æx›3¸5¦9=Üâx"cPß0¨]«ÆÎS(Bcbcºð\c«(^U‰lÊú‘yñÖ=m÷>|Òüd\”\Î (úß©—3ò>’€§\-†X¸sã.x÷4°Eƒõ~ŠzdâWñ£üvŸ’ïò”VŸ¨[¶Lêsü¢£Nyä‘íÚ5×\³´5„Eܲ‡ý%—\2¶kåi䟡ÌÓˆ g%(K‹Wó°MUISyW§,ÞqÇKÆ,‹•žè³=ˆ:DXc ‹qò‡Y¬ô.oÞÇ âè.èYôÃMš-ÔÿZË8ºÓN;µéæYÇ¢-/5%”Eêòÿ8ïòÛ5 âPâlj+džÀJ´q†jõN=ôŸÅ81F••òÔçwýNWüÇSr+ÅA#ÅF úpÂ}¾~­ô=Þ|ðÁ–›mþÖc{Ì¥¡T+KÂŒMS2N«<µ'óS†Ôò=Ü9‹íŒ·æ® sX7ä…ñ¯Œ«ÆF猌!]a ‘ŠôÌë¸ÊÀÉÐilåùNßtÿý÷/eݼãÿ²w&°zTçýž³$,l ؃Y Æ&,o8¬†„$”¬*IÕ6R)‘ª.jÕJm¥ªªÔ(©"µJÛ„TmHBBIÀÄa5 ûblÌŽ1f36`³„%Ä,ÿûœþß›s‡ï»ß¾ÞçHsç»ß73çœçl3çýÍ{Â:úe³¹^hï\Ó v@Nÿ˜«´q þÜC÷J@Ñî|–¯G+·3úµèÿÊÇ—ÿ§MÒ'ÒO [ o;å”SR_H5DƒÜkÝtÓMé¾Ï6eϼæÀx€7„ŒùòŠÜqoØèÒDN/u„—˜Óà34rÏÂÒ½ˆ©?Œ«ÜÏQÿš0¦²1.Ò6Ë÷õ¤›±¸\>0㾤_yGtŒ —ûùk®¹&ñ‹ô"¶mVp˘Í=Khëõ¶÷ü\H##ã*FÇz—”ŠtwsOÚë÷­Q÷hŸ1ÙsL#åöî£ñr`@; `€ç>Ÿ{þoQoñ¦9sæÌ$®cì¶ÀK åABˆ_+¯ôéUy!{ÿa U.\˜úb„,Ô ùå~‹qqH™a§XÀœñæ,m›úE<™”…$ù1½øÌ8žÞ"~DKxgâ‘N Â)Ä9<§…¨‡ûfŸ°bÌí×€/=´1¶¨{ðdþ„ü”E2µò²ð!×ëÇyŽZùñw H@€$  H@èÃ7cÖ\™`Ò)L`hVW%a †û'žx"ÇPñ3†Ä%,é“»ð/™¼f²’·sƒ GLò†F¹N&)áÌ2@×^{íñV,‘„ˆ2í·@;BX“…‘¾N§ãÆFÞPGŒ‘+W®}«3~ë·=|˜xÎëi$_Ͱ£ž”ߥ?öØccŒÉýÆÁô &ê(“ãèò€1£6ocÀÐN¿“ µ zôM÷W˜„˜.¿Î0|¦^`Y°`A­ä IˆuaDét€9qœ7ûËoÕcРL3ým'ÓN¿«Ûc*y¢¼í`lŒ@:0RoC¬¿õÛžôc°Ëëi,ÿ_oº1¸–=ãQwQ¿ h'îÿh{eOªÝ£Gøq/Á–Äk±¤`þ}þ™6È2Dôïˆè;‡1P/ðÂó*ByþÀRwxˆCpÓþ™yîwˆ¯ùcs-ýº¼"è¼ßîÖØÏ}#¢|,á% ©·!V‰2í·=ã ó%y½ƒ]l¦7¼åç!&fËË'ÿÝÏ€$  H@€$ Z~;[RëH¯›“êÊoÈ šX±bE26bèbò®^Ï/u'²Í2áQ~ó “³¹©-“d¾~þóŸz"(3Lÿ3ÁÃò x„É'Ù¨¼qýõ×™8lgÞ™@b"#4"˜c°‰@z˜¨ä ÿ~~£-çFÚa‡1—Û´“NM”…'Ÿ<~x"˜cnˆ¢¢¬ÝÓ1`”@?…—©²Ø&~oÏ„'Kaä~ŠIÛÇ<ÿÚÏh «ô›¹AŒ¶N›§/c¬©×ÐÃyÔ×ð~Ó–và"HÊ}1ý }oÛV ä ÏQÿX2¯Ÿû¥Jéoô;ú"Þ_²dIqä‘GŽWáÀö,ÕÓÈ=W#i€7â‡|0y£Ã3aîQ-ÒÇ=aY$ÕH<<6Óˆ‡{6Æ4îøL;¸ç`)Ç< Ôm„¿ˆæº!Šj6oÔ)Œ¾y¿m¶™q•sËžÉ?ã*mƒÚM€¥‹OP÷"`x§?cü@äV¯!õ5?Ä5ûiϳyùù1ÏCù=ržæxQ„þGµãòsù3ýÞ?×Ä2œä‡±O"¼PÐIq¼:­Zµ*Í›ðŒ— Ÿ"}ˆ­y6ëÇi¤¶Äó"{ÚI§ÆUâ¥]ç/‚?u<ÆõNÝO«ûrîÝráí•ù“\lSo<¼TRöh„¨†úK< H@€$  H@@3óSÞL ðü™ˆ:á„Ò[V1yÂDk00IŽ11 åÉ&˜Dâ8&î™8ZºtißÒd"‡¼`ˆÉ/òÍDb&çò·§ø ã”LÞÆÚÙO1R³¾Íp“ ƒŒÎ8ãŒdðÄÉhÞÊ£¬/^œÜEÇoõì£Îı0ä;x2‰ÇDo "|`Ë'Ö¨x ATƒæ~ ˆAtPO"ýä@òÀÆïËä+yãslüm´½z'e1<À#žY"`¸Æ°O]§M—q\¾§lH?ˆœ?cÆŒqßrçx&òñìDý‰ ‘Ayò¶×Ç}:á¹WòÓì²Y0Å ëx«™4âÁñ ^™fÍš5F銼.ÞL, â8÷È Ð–qû?oÞ¼$B¤0ú1AN}b¼<ꨣÒXCÏÛÇG‰acóæÍIèÀØÔ¯<3®²ú„Y¹¹žøè§ãž†ã¹£Îñ=uŽëS—ècaŸ‹,(?}ˆ€ÈÏ£ôwôGôKâq}ÇÒ¯ÀöÌâøaÙÓçÓ÷’_žãyÆ!PæñLÁxʽþxýl™GÔ™ò¸ÊøÃsž^èÿy€x¨[¹¸‹þg—“O>9‰jË×ï‡ÿy¶KŒ<+!xÆ“/õ,Úc)}Œ©œÃÿ1ž²g\©5þåùæÙ FFDP°$ÀýÑGM÷‚´iê9é¨Uv¤ŸvÍXm‡´V ´â%¿Œ§Œgô3µî ¸G¥¿áyñxÞ®H'[3úB{§LhËîðàCšx¦à^¡Ò½!õŽúOÚ(ÏFÊ ™´zŽ$  H@€$  ñg©'}—RÐyƒš !&â"0QÀä#L<ð°Ï„ü<à3±ÄC<“}Lb0±„цI~Ö‡O<1Ö#¿LJ¬1j1Q†Q”¼2¹ƒQq†‰˜è`òˆóyÃ<&¢â:ôg2–7ìÏ9çœTÖe‘KbÁ‚IÃZ^Á…zÅäÙ•W^_™¨¤>a¨¡N•ÙF+ Ìsçέkâˆk„0j4ÂÒÊ9sŸŸ©ÁËiˆSIËÔ©S‹cŽ9&¾³çw&טdò-“^LıÑöhKL€Ášsø“—üÆ$%Œ©³ÔË#Â&"sƒA\;öœÑ‹vÈä, ä“vN=gÂ*¦1J|ä—¼3™GyPçi´~ûÝßýÝŠ"”ˆ›=›”oˆjÂÈõÙÂðIþéGØ8‡ÉpÞÄe‚:yÁMy7àC–`¹âŠ+Ò¤#×!÷Ýw_2D3ÙNZ9Ž´QF¤‰ºH¾a‰åQ ¨‡“ú‹GD ŒŸ´õ´!ÚßSÏc\¥îÑ6¨kÔ;ÆVŒ9Œ«ô‡L¨÷³°&ú;Œ[9#Ð÷`è¢bòIû"OˆJ`@~i§ôk¼½Ì›ÒÕúݸî ïé÷è{×ÐÇrŸE æ OôCÇw\Ýã*¼¨+1®2βÁš8¨O”}y™-qa\¦ä­úz 2ôˆ(#«âÎ=ÍqiA¤K:*ÒÂ8ÇrTå7Æ\Øá¥"yãÒÂ1\#ÆÑKcl¥Qó0>÷ÔÆS‰‹kP‡O=õÔÄ9dŒ%”!|7ŒÜ+3Fsÿã*é9<¢}3Þq>ã cû'>ñ‰še÷Mù¸Jb\%ïl¤3Êx¸·¡Ï¡¼"p餽6`…p÷0 Жi¿¤•:EúàMyÄ}åE¾ a4MÿøG5 šA´Å})÷²øŸûl^îà~‘6B»¢ ÒP/é{èw{é+È×èÇ=í”<ÓOåË3Óž¯¾úêÔ¦yΠ¡oáAù£¦/à|ÆÆZöÃ(kÆLú—ü%ú˜DÿêD=~”ç„r׋¾œ>œßègËlxn@¼O_[Oœ\‡r.?æi%”o¸WDL•?;å¿ÓóœÃøYÜ«"°äY?®K^Èé¦~±ñ™-ÆWöl\#ÆUÆRÆTê, jÊÁm—{GÚ*öʽ3÷DÌ= (!Ú5ñQ·W©ç1®Ò¾ÙàÁØûñ¸“Oxã…7žSI?qij*é#ïåÎõ)#x3îGàeˆA) ŽÕâ$]y`òC]nÏg²p<âöy€/ùå¸AQ~nþ™2â%DrÑ—ñ;q†û òÏFÙEš"ïÜËQ÷ €$  H@€$ 0þSyå¾)L$ð† ¼µƒçšü-œ¸(“ñFP|7ˆ{&#˜hbÂqåˆÁ/ÜFG^˜Ü*#â&ðÀD¼Â8çãžú቉«Ÿüä'ɸùd2Š7'™„bÂNí Lf!¨ˆ·ß˜¨köM°z&ØÊ馾Ǥ}ù7®Wëš1  M»š Ä…ñ M&õxs>&ü*]£u• ?&™‘0 ¼1‘É†Ýø­Ý{âÍã®u}ÒΖ¼ ¿Vu’~íôÓOOõOy»…ÿçßµŸçJ´M b1®bØÁ0^´íaWÉïŒ&ú›ü‚<"¨ OÁ€sð0€1#†¾+-âøaÚÓ/c@a\EHl0 aÅã*u¨ã*}+F§|\ÅÖL¨5Vºæxã*y¯6ær-x .E £0¢UЧÖwŒÇ¼uÎý߆#5:ê`-# c âjD3,c†q;ÛaRé²VzýN¤™þ£V ‘f]ÜDzo%p_H=ÂóŸa˜_á÷­Äã¹È ðæ¾þóî»ïNõŽzVŒ!Ã0Ž`@ç˜ñÃzÞÖ¹§ÎÇÙ`žéC¤Èý=B›FîÁãZƒ¶G¤1þüÔ÷°ÔdÔ ú&„ÜÑgqßÑ®@ߊ˜QϨLRW ô뎫1fƾ'׫öÇ"HBÌJÞˆ8·ÿó… /nÜÏ1ÏB]¤þU ðCdÉ‹(pDtNÍ9Ä3dˆ¥ª]«Õº’eã]“±:Ge\åeV÷”÷…ÜGÃ0o·Ük ÃóB+Œž 0ŒÔsÃye¢‘|ÂߘôÄHÈgöÔE&(™DÌë%ÇÑ&1Ä2Š'–jÉJ&ة缙Ž÷Ú5§\w¼‰Ö¸&í·ÓÄÅ„a-£#çÑ.h/Ô•rú㺕öÔ1Úñ0)Íä"}ùh5n„Y0gr2¡ƒq>y[އ¼&Þ’4H QÔ;„Xh´? ñ´a&Ϋê|Œ«ˆ ›]²¥Úõ;õ=F–bÑ“þÃ9ÐÖ1FÐ&WÑ!šà>¤ž>¦|½AýŸ~%ÞÔfiÉ÷1àñãšk®I<àÔH þäc*Ÿéû¨Saüc\¥ooGÿÚHÚZ9–±£í(Õ0>Í+È'ß³1¾ÅxÊžs1²b”Êë$ý?Æ+DÖÔÛZ÷°ð¢=c´æ¾—q•²ÂȘWϸŠq7ÆÕZFÇàEù‘Ç0ªåyˆc*íÃH/†dú"ÆUÆØv”;¼¹çƒ^ˆýÒ¿Áz¼q•¶Nþ© 4J€öŽaW´?DþxJ¯]Шw´[„…œ?öŠ„vÌ’Wä•>­hWÜ/ÐÆWióä™ñ–m¢Ê•ûÆSÄHQ'èÿñ|Bÿ»xÄóY£åϽ ŒËc+å¸Êó*Ï­ƒö¼€¨—¾›q0úmîŘÓ!_ä›ïclå3õ ÆÜ˲åuæ´MXÑÏ×z)†ø8†c©ïÌÉ  åe’¸/¯þ2ž1FÒ7ðÌF9ÔªóœÃÜí„qµœ‡jñqõ –/åþŒ{ØV<Àåq‘~Q¦yœùï|æ®KYä“•L®Q—˜n%V&ëÆKC3×çºÔ›j‰GÞ„Gp„#®0DCž™ˆd¢Œ ËøÌÃŒ1Й\‹7/9žv‰!–ÉsŽàËÛéö1t#¬áü0BЮ‰“2dãx¸³§þ3ɇ1‚¾ö>^ -ä Þ´§×°'¶È+{âa£ž‰´3&VaÜÎ@Þbâc&\aJ߯>ÞP$=K}ŒIZØ$Ð úEú2™yž>ó;uQ m‘&ã*c6qp=®Í30í/Úv>®PÜSÑÆë)êm'VeìŠ1•ü²‘6âa¬¦ß íRNä‹ÏãÕ›r>ëùŸ8XÒ‰zL½„/ec+i"Î`@¨?´uÊÛ  H@€$  H@ïy~—Iq&–ËÊ+¯¼²üuSÿçq0aòõ¯½©ë ÓILœ°1AÎd L.0±Ä¾‘ Æ~æBþBXÃÄ ùcrƒÉ ƒ!Àä×òåËÓrÔ%m…‰ÊeË–¥zUÏõ˜ÆTê^RðŽT¯¨†øûðèÀøùÀ$/3‘.ŒVxy6ºÙ¦»W£8> ý”K3ñxŽrˆfmûË%ŸyÙú¹ý€âeO¦àá”%ëÕp^úè8Œ§,W\ާ‘k{¬$  H@€$  H@ÍPXÓ<;Ï”€ºHÑËÔ©SÇx¨Á˜‡°æúë¯/6mÚ”Ö¯•$ÞÒê©§Š_üâiã˜3gŽËV÷€$0”0ʱŒb·ãŸ|òÉ⦛nJ›||¬7ôׯ__ÜxãÅwÞ9ffé‹#Ž8Â1µ<¿—€$ ¡!°ûî»'Ñ Ï¬#xàbÕªUéeŽZã*¿³¤Ôý÷ß_Üpà IX×b¿ÿþûp@þ•Ÿ%  H@€$  H@è"æüÒv1F% Hx¬aÂrÚ´iźuëF¡0aÂ~ãíxŒyˆdx#Ÿ¥(x 5l¼5ˆpÆ c¼Õpìá‡^wÜq£×öƒ$  H` `øÛk¯½’`•·â#àyæÚk¯-žyæ™d¼ /nŒ©a,Œ1Ï6ˆ[üñ$ÈɽÕì¼óÎÅ‘G™¶¸¶{ H@À°`œœ2eJ×ð¼1’çUö,7ŒÇ¼°òìɆwžQ9QͳÏ>[<öØcÅÆÓ3l\‡ñø˜cŽQX@ÜK@€$  H@€z@@aM ¥$ÐI“&‹-JKNä–÷îºë®bÍš5ÅÞ{ï„5¼…φ°†‰J6&-_|ñÅ1“”¤„‰Ð£Ž:ª8ýôÓÓºõͥγ$  H@ƒCãÞÉ'ŸœD¦ŒÞ–ùå—‹Ûn»­`ÌŇ0Īc*c/Bœòì±Ç .,>øÁrŠA€$0ô>øà$~¹ýöÛG—*F8ƒXÁ ã#c/âÓWñã*Â6–;ŽÀ³,c1ã5žU9×  H@€$  H@@o(¬é wc•€š À$oê!aÂ’%+XÚ)Ÿ™´d«'àgŸ}öI×<þøã‹3fÔsšÇH@€ž¾¹sç¦qq*†¿Ü˜‡¡ïê ¼yÏÛøˆjðþærõ’ó8 H@=©<ãiÎ  H@€$  H@@ï(¬é{c–€š Àô¼±·ï¾û=ôPÁÏ=÷\òD—ã]–·þX*ŠóY:jæÌ™Åa‡–¾ï<“€$  –X<õÔSÓò?üp¬2¦¾òÊ+ÉX+¿±LãäɓӘzÈ!‡lˆv €$ ‰D€çÌý÷ß¿Xºti—²|1UÆU¼¼á®VàE’=öØ# UyéãÐCMãëN;íTëT—€$  H@€$  H ÃÖt°——€ÚO€ ÇÃ?¼ÀÝöÓO?]lÞ¼¹Øºukz ðµ×^KËRàV› N–„âMzÞúÈÈ6eÊ”4ñ¹Ûn»µ?^Q€$0 vÙe—böìÙIh@ÆÔW_}5-e78<Ù ^EHÃxʸÊyŒ§S§Nš¾l›L H@@Û ðì‰g™O<1½¼±qãÆä¹†¥Wñ¼ÊŠŒ©lïÿûÓ¸Êó-Ï¥,¡ÈÒOŒ©xÀQPÓö"ò‚€$  H@€$ ¦ (¬i'J@½$À¤%xœaCDÃDek0òF@&,™¬ÄÛ “•üo€$  Hàÿ0¦âefÖ¬Yic åízÆÕ7ß|3§1¦"¬aLE¬ŠÐ1ÕZ$ H@K€gP6lxªA¤Ê¸ÊÆ‚UÆPĪlŒ©Œ­œk€$  H@€$  H ÿ(¬é¿21E@˜”d2’Í  H@@óÏ De3H@€$Ð<Ä«RÙðòf€$  H@€$  H`0 ø*Ì`–›©–€$  H@€$  H@€$  H@€$  H@è0…5ìå%  H@€$  H@€$  H@€$  H@€“€ÂšÁ,7S- H@€$  H@€$  H@€$  H@€$Ða k: ØËK@€$  H@€$  H@€$  H@€$  &…5ƒYn¦Z€$  H@€$  H@€$  H@€$  H ÃÖt°——€$  H@€$  H@€$  H@€$  H@L k³ÜLµ$  H@€$  H@€$  H@€$  H@@‡ (¬é0`// H@€$  H@€$  H@€$  H@€$0˜Ö f¹™j H@€$  H@€$  H@€$  H@€$ PXÓaÀ^^€$  H@€$  H@€$  H@€$  H`0 lß‹doÛ¶­¸âŠ+zµqJ@€ºFà7ÞèJ\¯¿þºãjWH‰$  ô’À–-[º=ñø¼ÚÔF" H@=$Эqµ‡Y4j H@€$  H@m#ÐaÍ[o½U\yå•mË„’€$  LdxW'r 0ï€$ÐNWÛIÔkI@€$  H@€$  H`° ¸Ô`—Ÿ©—€$  H@€$  H@€$  H@€$  H@è®y¬ÙqÇ‹/|á ʆ—•€^}õÕâG?úQÓ vÛm·â‚ .hú|O”€Æ'°ë®»Ž@ƒ¿ÒfW„æáh€À¦M›Š+V4pÆØC§L™RœuÖYc¿ô? H m&OžÜ¶kq!Ú¬ãj[‘z1 Œ!°zõê‚­Ù0gΜ‚Í  t†ã A€$  H@€ªèš°f‡v(.ºè¢ê)ñ H %›7onIXƒÑß6ÚRx²ºJÀ6ÛUÜF6 ¬Y³¦%a FÇÕ XqÌòÀ°ÍlÑ™ð!ðî»ï¶,¬q\Â6™€$  H@€$ !$àRPCX¨fI€$  H@€$  H@€$  H@€$  H u kZgè$  H@€$  H@€$  H@€$  H@€†€Âš!,T³$ H@€$  H@€$  H@€$  H@€$Ð:…5­3ô €$  H@€$  H@€$  H@€$  H@CH@aͪY’€$  H@€$  H@€$  H@€$  H@h€ÂšÖz H@€$  H@€$  H@€$  H@€$ !$ °f Õ,I@€$  H@€$  H@€$  H@€$  ´N@aMë ½‚$  H@€$  H@€$  H@€$  H@ÀPX3„…j–$  H@€$  H@€$  H@€$  H@€Z' °¦u†^A€$  H@€$  H@€$  H@€$  H` (¬ÂB5K€$  H@€$  H@€$  H@€$  H@­PXÓ:C¯  H@€$  H@€$  H@€$  H@€$0„¶/Oo¼ñFñÕ¯~u¼CüMèÛ¶mk)%[·nµ½·DГ%  H`˜¼öÚk-egݺuŽ«-ôd H@&›6mj);+V¬(î¹çž–®áÉ€$  7žÃ €$  H SÆÖ¼óÎ;Åš5k:·×•€úˆÂÛ{ˆI‘€$ &€0Çqu ‹ÐÄK@@@˜Óª8§²cR$  H@€$  H@0.5`fr%  H@€$  H@€$  H@€$  H@€ºC@aMw8‹$  H@€$  H@€$  H@€$  H@À€PX3`fr%  H@}Ù`@IDAT€$  H@€$  H@€$  H@€ºC@aMw8‹$  H@€$  H@€$  H@€$  H@À€xß»#áwÞ)Ö®];`I7¹@N`ëÖ­ÅßýÝßå_5ôy¯½ö*þæoþ¦¡súèÑßü ‰FàÁ,Ö¬YS¼öÚk)ëˆ?.\¨°¦ÉŠð /·ß~{ñðÃüvØa‡‚>fúôéU…5·e˖⥗^*&MšTLž<¹@h€$  H@˜8ÖLœ²6§€$  H@€$  H@è)4x©¹ä’KŠ7&å±Þk6oÞœ Ùåßý_‰Ë@åÂ3þGèahŽKjýú׿e Oþ§ß©`饗·Ýv[7á5ï6Ÿýìg“g­Jçø$  H@ÀðPX3|ejŽ$  H@€$  H@€$Зž~úéâÎ;ï,؇8S¦L)f̘‘–}ÚºukòdÃ÷ïÿûû2&J˜âaëþûïí³žyæ™bþüùÅ>ûìSÕËÍÄ c.%  H@ÀÄ! °f┵9•€$  H@€$  H@@Ï ¤¹ï¾ûеk׎¨wÚi§âÔSO-Î>ûì$®AHƒ·Ä5ØÆ  H WXþ‰åëBH:X–ë•W^I·$  H@€†Ÿ€w}Ã_ÆæP€$  H@€$  H@='€!zýúõÅ–-[FÓrÐA‹/.Ž=öØ1ž<ðÀdÈÖcÍ(*?H@= €ø¯R?4iÒ¤Šß÷ ‰Cåã?^¬Zµªxá…Òxpä‘G¦±a—]vš<š H@€—€ÂšÁ-;S. H@€$  H@€$ !€×‡—_~yŒç„5³fÍ#ª!CÛm·]Ú&s&TJˆüfÏž]lÞ¼¹xõÕW“˜fîܹŴiÓŠvØa(óÜ«LÝ|óÍÅÕW_]¼øâ‹‰ó#}z¯’d¼€$  H`”€ÂšQ~€$  H@€$  H@€:Eàõ×_OK¨ä×ßsÏ=‹=öØ#ÿÊÏ€ú†ÀÎ;ï\|êSŸ*–,Y’–„ÚqNjɓ'§¥ëú&‘C’–Ýb@–Ú"à¹fÛ¶mC’;³! H@À PX3è%hú%  H@€$  H@€$0Ö°E`y–SÁPm€$Я¦L™’Ä4ï¼óNò¤õ¾÷½¯_“jº$  H@€:D@aM‡ÀzY H@€$  H@€$  Hà·Þxã‚-˨(ª î% ~&€˜1 A€$  H`bØnbfÛ\K@€$  H@€$  H@Ý$ðÖ[oo¿ýöh”Ûm·]¡ç‡Q~€$  H@€$ >% Çš>-“% H@€$  H@€$ œÀ»ï¾[üú׿N^_¶ß~ûb×]wãAeJž{î¹bÆ Å+¯¼Rì´ÓNÅþûwÞ9¿TÕÏÄÁ¹7n,¶nÝZ¼öÚkié“ÝvÛ­øÐ‡>TL:5Å[õ¥H×$Ä>á~ÏÅ6ü†ØÑM­Ðî´æñqíW_}µøÍo~“–«Úe—]ƈ€HóOøÀÒ5öÛo¿‚ÿ› µÒÎ59æÙgŸMñܽØ{kzòPOÚSQ—žþùâW¿úU*kâ!êR½õ²Z\ä˜Ç¹mÛ¶TN/¼ðB*3ÊŸ´³DeEýèu .=óÌ3©Ý’êÒ>ûì“Ú?}A­@žð(õæ›o¦ºWî_jŸÿεè;à'¶N‹è¨c›6mJù'Q>Ó¦MK}až¾f>“®[©ï­÷zpyùå—S:·lÙ’Nc9<Êiòäɉ{%Nõö‰y:¥mÀ¤Z ü^é½U£æ÷€$  tŠ@í§¼NÅìu%  H@€$  H@€$ º ¬ZµªX¾|y2ì#W ço¿ýöâ®»î*žzê©$Þ¡¬àLy‘wDˆ5Ž?þøbáÂ…Åî»ï^éRU¿/íÄsÏ=÷¤¼QÎ!âbä“úrðÁ§|Ìš5«i øÝ{ï½I@„`‘ VäqÏ=÷,Ž8∔G=ä½ÞÐ Ž¤qÙõ×__Ü}÷Ý©M lc#D”mbñH{<à€ÊGºP ¦Ýÿý©í?ú裣í–KF]B\7þüâä“ONb›JÑQ/.¾øâT^ÑwsÌ1ÅÇ?þñ$ú¨tNµï¨Sÿõ_ÿU<ôÐC©Ì©WŸøÄ'ŠN8!Õ¯jç5ó=é¦þò—¿Lý¢@ú-¸DþprÊ)‰b£fý.õQ í”¶I[§?¬' z¢ÑH#uˆt"‰ö@›àsµ°dÉ’‚íƒü`µCÒ÷ƒÔ6¾ÿýï§þˆ>€0,_.~äk_ûZÅzƒ`ê3Ÿù̸ãZº¨$  H@@›Ôÿ´Ò¦½Œ$  H@€$  H@€$Ð8ŒŒ‘ñšƒ<°xýõדpå§?ýiñ‹_ü" 0*çc2†`Ä•†7?ÿùÏ‹;î¸#‰ ¸fùq^Zyä‘d4ǰ!DˆkÄž8ðf– ×!,Á“C:•Ö<>#:¹ï¾û_Xã™æÈ#LùþÁ~ ä°1Œçá ƒJ¬+ kV¯^„Q>ø`*3ŒÉåóãZpF˜ððÃ'QÞpàRO¨–vDn¾ùæÄv¥øŸ|òÉέ©7ˆmê ˆ®»îº$"àˆ©BPS¾"êb®|ä#ÅgœQì±ÇåÃÞó78"Ø@HA»@°‚W¾«ÈÌßüÞïý^1{ö쮈ký ð"ÔÏJõ‘ôRžp¦ÿ Íîµ×^ïÉy@Ô@ÝDXCàÚ7Ç'ø(_ ñâ1âpÚi§U¬kñ{3{êVˆÈHkµü#`#ÿÔ› .¸ j9Ž—êù¢o$ øCäRKXÃñˆ~h=öXjÕúÖñâç7D\sçÎWX3Hmƒþ!B¿jLè£(»Jþaiµq­Ò9~' H@€Z! °¦zž+ H@€$  H@€$ .À°Æ}#1(#L¸æšk’÷”JIAìÆòüw®—šË.»,8Yª§’Ð"?‘" ¢,½ÂrB˜+ "j]+¿nþ9Œ¬¹¤ÓiÍãç3ùŒt7Ü1ðþð‡?,ðÓJCpœ¿ó?Æu8sjB£8ž=×Ç ÑÊ•+“æÂ /,æÌ™“Œëùq•>WJ;FhÄWˆ§ð˜QNc~0fë[ßJu ¯9•„Bù9|FDð¿ÿû¿ÅÕW_Ò\MPçÁ±u ÎguVU=ÝäH›ºôÒKSyUj;‘ö‘ÚB¨C9¤ªg˜ü¼V>#Fƒ5éD`3^yR—h§?ùÉO’7¼Ç”k¤å°Ã+Ö¬Y“®ÇÿW—‘ŸF¼&Ñ>b™#®Ã¹xòAÒ®k¼à†¸jå1é³ðàU«n–ÓIÈã(ÿ_>žÿ©—_~yê›>5gùšœ_­OĶAÿNºs®å<×ú¿Ò²YµÎñw H@€$Ð,…5Í’ó< H@€$  H@€$  ôK®Üpà É †fž%X*d—]vI ŽaI”JËìàQ†¥˜0Î#¦ `ìÄ^7ð’‚Ïæá°ì ×ä;<0üøÇ?NËúà9 ìÕƒ<Ë¿à)ƒÀyxÛ Q qá £ìA),”/ÛÒé´¦Žóã=‚„‘~˜â±ã.Â3x²ÈA\’óà„70®Ã 8ˆàŒ0 !‚ Ž'¿Äƒ¼!ZùÊW¾R~øá)¾q’úžŸXº A e7Êzè¡Ë‘n¼zà%'D?ˆ Æá8¶ñ¼§°QWrc9Œ¨S,÷„¸–ÂHWÔ;êiDôPMÄÑ-ŽxZ¡] ‚ Q u”¥”Ž:ê¨âCúPÊå…` ì)/øÂ®“qÈw¿ûÝÔ®¢ÝÓf¨pfé%Ä6”7\£,Âà u%žÈG>üá×^{í¨°†ßð³hÑ¢ªe’ŸÏgâÃ{OÔ3¾£žOž<ù=í‚ßš ”}ñåb“}÷Ý7µ)â£nÑž;‘6ÚßÁ¢Ó¥ðH#õ)Êæ,KE»ç3íôÄRVQßHÛ”)S’7Ê“>æÔSOM˧UJ÷ ¶ òÅø›èæÂ?–Ç‚ûr€!ËÉ$  H@@·(¬éiã‘€$  H@€$  H@@ `8'àñƒ€@ãôÓOO¢ ‘+1êbtÇàžDÍo»í¶Q£&ç`èd¹Dˆ/Š`øÄŒçD8W]uU] @DÁ²/9gΜ™G‘ êEá0þâ5Qk³D KåÃ?S~'t#­yü•>¯ñç0ã=ï*Ó¦MK‚DC X aSŽg9!D!ªAôãÅ‹'áÒ®»îšÄÕáŒÆå12s×f 'x6jLæ<ÒGØ"^aé%ê iáúÄKùàC>ˆXne<¯5ˆKe ¢ #òHùr>õïHñm£Gêaª‰RºÉ^𑢚/~ñ‹iY,D?ˆƒÈ#Ü>Ñæh‹xD¡ÝTÏvì&!®! ð<ñÄ‹¥K—|p*#D0F¤À²e”M´Aê0Þ­hçÔ£\†WÚ0‚*ʇÀHüÏo•Äyåü„˜'»°œX£u¶|Ýüú4úœ²¨†vsöÙg§´Rð¡^!à¢=QC$˜_¯ŸñÃ2U¹¨¡!ž§Ž9æ˜ÔGP¢í!j£ú¼?ö±¥vJ9!¾£¯(‡Anô ôGÑîñBýùD”wÑE¥~¶œoú£²8¬|ŒÿK@€$ vPXÓNš^K€$  H@€$  H@]"€‘< Øxxa‰ æxzÁ¸ŽayÖ¬Yi¨!=ð¨€pƒ€Ã4†_Ä"xȆj#ˆ 0òbÆpO¬W¯^D¹ñÑ[5¹è€ë`- râøØw#­Wµ=†ò`Àx‰åm0 #."ÿy"á©&„ ˆ…>÷¹Ï%!Þ€raçRNÐ9aÇ7Þ˜Ä\ 勸#?¯Zšãû^‘V=³€„p)Ž#=”û%—\R_iÀØ?wîܪÂ޹îºë’Ç›0#àY¶lYqÞyç%a@^/"¾©S§¦ú‰!$xÉÙÅqì»É1Iˆˆ{þüùITƒ¨)ùc#½´ <¤ ¶B@u"Žm÷1x’ ðš1"’*—'i¢>!.ÁÛTœ‡ %Úkîˆó)g¼2…—)6,EÿRˆÞ›"%y?¿5»¿å–[’؇¾'⢠.¸ µÁrß…¨‹úŽh \^¶q~»÷=ôP±áÿ{1âÚÔ“~ô£©.åâÒʆHäw~çw’èÞäþaõ*/§rZ¹mÐvØ"”û6¸! ­5FÄùî%  H@@' (¬é$]¯- H@€$  H@€œFHÄ!*h4;±TI£çÅñÄNâ»z÷ˆKƒŒçi£ÞkõãqQ&xI £mnÀF|QÔ¼lÜu×]ÉØ×Àp¹`Á‚äq¥šh#x²$Ë«`ø% ÜÀPì±Ç&#zú²Mú%­Á áÁ'?ùÉ$4È øˆ,Êõ ‚“à¼w Ô@DÏJï¹ ˜@b< á=$7FWºFù;Db v ½å€ kñˆ‡„ xE !e¬ò9üˆ€cðœ!êf¥¸8£9KQ±ŒËQwñPQÝäH>É;_"à &_–,¾Ï÷”}¹üóßÛý™ºwþùç'¡‚ŸJŒùQ˧>õ©âßþíßÒr_¤Ñb –* 6Ž;î¸$rÊ…dxÂÃQ-a çàá(¯xg¡.W«ërÁSK†…XŒógŒˆŠº!lËÛd\›zF=üüç?Ÿ~dzR«ãR\»ÚžeÕ¢ÝrÌÑG¶\T“Ÿ ˆh8—üQñ"…¯\Nq®m#H¸—€$  H@' °¦óŒA€$  H@€$  , æ,iÁ’?ͼ#´X^%–ˆ:‚!¿¡ŸÒŠ1C5~9߈`{ì±Ñ%…9±düêàmÁ ‚Ä xƒb·F„5,ðƒ€…61^SŸh/¤ ¸‰“ø+ 8^ıÁ€úˆ§‰JÇÇ1±'N„+ÕÒÕMŽxÖÉ=¡Fú0<UED>ºµ‡¢+DRÔ¥jÜHüƒá±…öb)0”1Â&„'¨WÔ¹ #ÞV³ ^S{Pžù±qNìËË@‘.êR;—BTC_ž‘ˆ›e”èw*‰j"m´7ex…¡ßà SôqL;÷,Ÿ• ŒÊKÄUŠ‹²B4G?Â!D¥ã¥Ó¶Q‰¤ßI@€$ ÎPXÓ®^UMˆÖfNÎß‚hæ|Þ¼j%~Pûe‚¡™ü{Ž$  &Zó‰ÌFs×ʹÄEü­Œ«LªVz»¼Ñ|x¼$  H 0Äc°D`Ó‹€Q»qÏ©‚Iÿ°îð€²dÉ’ä™§Þ|†¡<ŽÇ†ßZ^9âxê^(X²(‚Ãǵcß/iEpH ñÑxâ‚<Ïr&ÔÇZâ„ü|âAøÀ’?qŠ÷–çi$à O4µDqM¼1ÇeË÷xø`É'ê\¸ï]·nݘ{_ÒŒ‡ŽF<¸Œ'é&GX#.¡Ž“_K¦tÒIÉkH9ÿ9‹n}¦YvŒ¾‚@ß·žS*yÖ„¢—¨ïˆA7˜3lW`î2<'Å5úôZèi‰=åó(¼ã… DvkñÀCWœÃõ UËŸm#ˆ»—€$  H@Ý! °¦;œE5 0‚ûæÃ?¼i¯55#éÀ¼áÁd%Ë H@@¿àܹsç+W®lÈpÑëô39Ï$6÷ H@@?ÀûË y­™Þjš­wËK ᑃ}ñ‑Ã| ê\—­lÀcÝRZËyC bøQ â„F1ð,s‘K#×)§o¼ÿ¹nYXSÍÛF¥|âe£]‚¶J×ï4G<Öà=’e6Q·©ïˆÉའïCÌã|òÉÉ+V™×x|{ñb™r™?òU)œp Åõ×_?*¬¡üW¯^ž±ÊÂÄGåe 9ä´ìY#}J¥täß!´+÷]ÔµvÆ‘Ç×ÊçXÂ-D2ðAP·÷Þ{WM/u ƹç/<•yGºlA½$  H@è…5Ýál,¨‹o-œþùÅ?þã?Öu|?Ä[çž{nÕ‡¼~H£i€$ ‰G€‰m&Ä/^œ–Z¼qɲÕÞJ”|˜N H@>ƒäµf¢x«i¶–á}#_žˆë `ak% ÆÀxßÎû˜AJk™<Ë„l­D,GUI´rÍò¹Õ<¢„7’üxòYÝŒ·|M~n=Ÿ{Á‘º|ÒI'¥¹®þð‡Å<0*@A(Á†—G}´¸á†’ÀæôÓOOÞEª±«'¯<Y€B],×ÑHÏR3gÎL¢è/ðâó /ó|âÑHÇ5xÉåÀÚXÆŠ>!ý*¬ApõË_þ2‰³áùç²Ë.KuŠ¥¶ÊË;=óÌ3Å~ðƒ$¼‹ö„ †¥þª-?gÛÈk‚Ÿ%  H@@ç (¬éþñÇw\[ÅeeÍþO}¡}S.Q/ù®Z9!ü˜3gNZkóæÍ)Z¼õ<üðÃÅA”Dt‘7pˆë"°;ú裫 Bâ¼F÷xr)÷]\£Z½~;ÇcÍ¢E‹’+–ÈÂÓÑ7¿ùÍ$:bù_–Lc¹8D5xªaé-þð‘|$y3­Ö§Ú6‚”{ H@€$Ð kºÃÙX$P7¼Ö,[¶¬øú׿^÷9½:Po5½"o¼€$PAóZ£·šzJÕc$  H —Ák V^Á ÜI½,‡VãFôPfƒ…³Ï>;-oÓÌõ¹ïbŽ€eNÚ)­å|c / •0´ãQ±šŠò5Êÿ#„ÀCG»9—ãiäÿJK !¨æ ¥‘ksl/9".ÁkË>ûìS|øÃ.|ðÁ$²a)*–á! *bI%„m¾ô¥/%áu·ŸÞd(“¿6<ÊŒ—ND\Ë—//ž{î¹t^,ù„7Ê€Ð0ˆpÄG$ï=íáÁ¥Ü¦*ym‰tôrOÞY¶*QëׯO{ÍQb&¶©S§&ÑÌSO=UÜtÓMÅ­·ÞZ°<ünYéÒK/Mb¼ºôS`Ù§r™ðr_¹/ÈÓŒGD2O<ñD·Â}÷ÝWàÁˆ\ð¶Âïù2PrÚ½ q#H+ HW»D\ÄÑ®€ŸÛo¿}T€E=†â$D4!Ì*ÇG.\Xœyæ™É£y¹É·mä4ü, H@€:O@aMçƒ&À›GýîµFo5 «'H@@0Ù;mÚ´ôfðÅ_܃Ô¥ÞjêãäQ€$Ð{ýìµFo5õÕŒ±ˆz󀇑| ’ü·^~¤´–9U 8aù–a kÊKÕ´SXÓO™ c›áÝ5<¯RÇyœ>}z1þü$f‚ãx¢˜Ú6ÚU³¼Ž$  H@¨€Âšú8y”ºJ€·EúÙkÞjºZŒL€Z$Ðï^kôVÓb{º$  t@¿z­Ñ[M}Uã4Þ$0è" `,Ãy}WéÎQƒ”Ö2ê#÷y¾bù-[¶¼GÜP>oÐþ§.•…57nLËÛ´#/ýÈ‘y1„§œrJ*ßoûÛy&à•äÉ'ŸLùŸ4iR;´åˆ}Ê^RÖ”=À”#Ã[5e@þ‚P—ï¾ûîbÁ‚i9(„5ù2PG}tòÈDÿÒîOÚTÞw!^A\ÓHˆ~¯‘s9>Ô–‚"vØai)18"Æ¢^ýõÔç’'–Õ¢ !Úª%vÊÓ1Úõ-úÏ<ï~–€$  H@½ Ðþ;Ü^äÂ8%0d˜t ¯5ý˜5½Õôc©˜& H@¨F€‰×ðZSí˜^~¯·š^Ò7n H@h†@x­™={v3§wä½ÕÔC:Kám"ÂsÏ=—¼+ô›×šAJk°Œ=s–ËÉE'ëׯ/XF¨¼$Oœ3ˆ{ò‡ç ú…ˆX¨ì!%~odßÏñDòá8y°É…$Ï>ûlÛ„E•XQ‡6Œ,;•/¿T鏸AÌ=÷ÜS¼üòËñUò†B?ßñ/)sÌ1©Œã¸‡~8-E}~úé§GË™~¸SË@7×gyª¼Máù%±D«í©“7ß|sÈ­S²É…Š`˜KE´ÿþû'>lN>ùäôbå‘G™< qÜxKs•Ó;Œmƒ~$oKo¼ñFt•óîÿ€$  H Öô‚ºqJ ¹×š:ïÚ!Ljñ¶Ê±ÇÛµ8H€$Ð*ðZ3cÆŒV/ÕÖóõVÓVœ^L€ºH Ï…ìû!Ž9sæ$w?¤§ŸÓ€qúÀL[¤ýý÷ߟ–(‰ïúa?Hi-ó"íÌŸä&¼TtÚ¨_NG7þgéî·#` ¿õÖ[‹­[·ÆW5÷Ï?ÿ|±nݺ÷RúcxÉ3ˆà¦Ö2>ùñ~ÆãÉ÷¾÷½bíÚµu‰´àŠø$âÌš5«8à€Æ¢ª¥ñžT"P¾ô¿øÅ/Æ”1¢‘ƒ>¸¦X'®ÓÌA ž¬" Z½zõ¯9ñ[yϱ˗//V®\ùï=åc[ù:¹x¡õ;÷”C½fŽ5‘4ç0¶ ú‘\¤‡@©ß–új´œ<^€$ á! °fxÊÒœ ŽúÑk ÀsÏ=·`’À  H@ý굆·DO;í´ŽN>J™N H@,ýäµ&Œ‹}rƒÜ`ínjgΜYzè¡cŒÿ,sË-·x€è§0Hi-sc™o¼RG#Ü~ûíŪU«ÒR0ñÝ ï.\˜¼óäù¼ãŽ;Š»îº«¨å ±ÇþË¿üKñï|§À{R9t“#¼íÄ2>å´”ÿñÅ“w’\4À¤“ófÄõøãÿùŸÿYÜyç㦕üüèG?Jžeò´Sfó2ËÏ?tÐAÅŒ‘rO1”Ù7Þ8Æ âFæ2ë¹f~ýF>Ï;÷=‚n»í¶$äʽĔ¯‰¨è§?ýiqùå—›6m#r)Ûêÿåò§>Q¿¿ño$a}À½÷Þ[<øàƒEx±¢ÞÓVòzTO:†­m DDp1"^‘êmqž{ H@€$Ð ¿õÑÙ‰«{M H %¹×&¸zx°a­d½Õôº$Œ_€š!^kxC÷ܽˆUq«Î¾ H@À ¯5xMÀPÙ«ÞjØê#À}Fð5kÖ$/!œ…óºë®KÆÝóÎ;¯8ì°ÃÆõ¦€ ‚%o‰°4 ž$ ·â¡Rê)­åô#2`¹—gžyfÔ³ËñüÏÿüObg„Öã ðրǑ»ï¾;‰)>ýéO§ecÆ;§œŽNÿ¿ß~ûóçÏ/6nÜX 4!D>ñÞqöÙg{î¹ç{’Á=ùõ×_ŸDˆðD‚7”rè&GÄ"xB±téÒ‚ezrAIž6–ºâŠ+ƈV¨ÿx‚á^¿“öÇ\á¿ÿû¿çœsNJ+ŒózÇ K.¹$ —r®x•á9o;õæ'ißôõ!|Âi`# j¤OɽÉÔsíF!ˆk¨;/½ôR:ºöãÿ8y‡¢½•EMôSˆjð°³yóæÑ47w½Ç#DŒD¼z¨'´aúD5ð¤žÀŒò»{þ§¿£O`¹N8!yO0:lmƒúŸ(7Æ#Ä]Q¿ù¶ÛIïP‘÷€$  H k¬èc<,°v0ȼÕÐëÀ¤À²eËÞó€Úët¿$  H L^²ìÁ¢E‹ÒDl=çtò&L—,Y¢·šNBöÚ€$ÐQûxñ‚e8z%¬á¹9–+ÏøØQxqî‹0¬s_„‡š0P#ŠÀˆùÔSO%ñ/÷N–BüGŽÅƒË›°ç|–¦ùà?˜Äí RZËUƒïG>ò‘dTÇPx]@€rå•W¦ï9ä$â@œ‚h! <áŒW8Ó¾àŒø‰2›>}ú¯åx»ý?ù\¼xq rÀèýî»ï¦t_vÙe© ÍN&Mš”DFÔÄìñ4Â9!0(§¿›a`å‘GIË!B¡Ÿ£- b@dCzi#xJÁ+⡈>8¶“ý¢D3ˆe$ýð‡?Lé@DÜô‹HαdSÙ“K%C‘þjûyóæW]uÕ¨°±Hà4mÚ´1¢ˆü÷v}&oˆgXjŒºF=#Ц¾ýío§<³ÌKWÑ^àƒwÚíŠãaD¿BYçËcµ+»îºkñùÏ>ÕgÚ=é ^ölãê:uŒvrà 7$Ñ™gž™Ú¿•ðµ <©Ñ"Bв¥ÿÇüG³hƒŒCˆ9Ùá _(fôÙrÏå2ò H@€†‡€Âšá)Ks2¤x˜b-c,zéµ&¼Õðö‰A€$0¨0ø0)Ì›¨zèµ&¼ÕqăŠÒtK@€ðsß}÷õD\ñë­¦ñ É}f0N_}õգ⌕=ôPºWâžoxì@ô±mÛ¶dÐÇXŸ¥F`ôîD¤´–ó(é /Lõ{î¹g”¼ý° 6àŒ÷8ÂáFx8óŒÍâq4³Ÿr£ø–-[’H(ò‰€¼! AhÆsâD$GYW ÝâHYFÄ2ùÉOæøü, H@€:J@aMGñzq ´N€‡„~ðZùÞjZ/O¯  H@½%ÀD8o(öÚk “Ÿz«ém]0v H@h^z­áyYo5­•#‚$ “,¿±bÅŠdÌäŠã1\²Õ ”ÃŒ#2F÷àÔ:§™ß)­åüá•æþàŠË/¿< ¼Ãà 6ĵBxîÁ[I%ϵÎïôï¤é¤“NJÑüà?(Ö¯_?ºäbñê¢îÏ?ö±%¯0ÕÒÚ Žõcy3Òð"–?ª–.¾G°ñ™Ï|&y·É—²ïœfÛwß}Ó³m‚:…wÚ,¢¶J¡ ‚š .¸`ÔcK¥ãª}GùüñÅwÞùa 凬j¢¨j×lö{ò‚‡ýw¿ûÝ$¸¢ŸJÂÒ§›sÏ=7¥õh6úºÎCD‡`1Ä!œ„ÐföìÙI@‡8„¶Ïž´#ÐâX„KxÒá{}Ìwß}÷$¢ì+…ai”ÏɈhÈ7Œìéåe³è €$  H [Öt‹´ñH LLõÒk ªG}tZ+¹…lxª$  H /0áÛK¯5z«é‹j`"$  H 0îâÝ´Û^k"^ö%àÕ„-m¶fFI<ð"Íᇞ ™x{`Y•0hVº6ÆO–ZÁ».†bæ ð"QËÈÉ}PžÞFÒßí´î¶Ûnc–óÁˆËüH3^ˆ>÷¹Ï¥ù›nº)-„¡ñFµ@|”^.°¥~ªÃ÷­¦y(Êæxú`Ïò6µ–7â˜ùóç'-¿üå/ –ÁÁÛFˆÊiFlNÝ9å”S –1âÿñâèGb_þò—Ó2O,õ´aÄkÍxmAÍâ‘e°zðí”Ep¡NÐÐïuÖYiù%ˆB°•ÇÏñ3gÎLK’1·8uêÔÑkåÇÕó™¶Î2KÏ?ÿüO/0#=‘Æz®Õê10`‰®?üÃ?LKTÑoåKCÅõIýË_!l¡ýÀ$o#Ô+ú&öÕB~<ÇŒ×Pg~ô£¥%¨¢îPG1Æ2TáA‡ö‡!Ú4D?,¡žŸðîÄ}K—.]–¯œÎaj,‹‡‘1…ºg¡r  JuËKR9~ÿ—€$  H`bxßÈÛÿ-D:1óo®%00xs·Ç¾ñot=ͼñçþçé¥ë‘¡$  H x““·;yÃ±Û Â¯|å+ÅqÇ×í¨O€$Ð1,ÛÀ¸zíµ×v,ŽüÂxIÁÈxÑEp@þÓP,„Ü[`äm5`ÔÅ0ØÃ9ââÃû¿aÈF4À^0h/Þnø¾–¨†ôa4~òÉ'“ Ëœ‹à‘N#¡ie –Xöã<žb¦M›–¼M4’Öò±áyûQâ`C^60ðÃ6˜á0œÿ)ʽVh5íûñ8ÃuðœA¼ˆ(óñÄ‘.Ê–üa§Ñ?P·XÒÑyBˆÈƒ¥_(¾o$t’#ùgù Úé§ÍñSé”,Øh ˆŸh õ´FòÇ"° ÝÀº†Ô…à@)3Ò‹ƒ2ãú8“Fέ§þD¼•öFðH”‹~ÿ÷¿8ï¼óºæ±&O}ý^^´.Ú‹=÷Ü3 Yh»Ô·¼ŸÂËÇÓî¨{0åøjeXo›¢~|ë[ß*–/_žê iE‡PaR=â#úÉk®¹¦øþ÷¿?Æ[ÒŸþ韦åû(ÛñBÔ‰Nô1Ýjpdü¡îS¾lÔmê/íz=cdì ýÕÃt<^þ& H@€ê% °¦^R'à‚Ɉ¿ýÛ¿-}ôÑ®¥†QÞèø«¿ú«1o•u-F$ H@è&ûï¿ÿþâk_ûZšPí@/‰¡#àýÑ¥ÉîŠù¥$  H` `ÜüùÏ^ü÷ÿw2pv: ðþqæ™gN8£†M6 Œˆª‚[)Ê“|0Ðò™@<ÄÇ27¢›5frFú™çà­¦¿“iåÚ¤•|³µ*J(— |áËÁD™ŒÙšåÓjÚ)®AyQN¤©™yd,¹^X¨Kí`qt‚#i¦ŒX ¤—ôS6¤ŸÏÝyYTª¤á éä3ébNçv¥‘ë~ýë_/®»îº$Þ!߈þú¯ÿ:y-«”®n°!Žr9‘òõ¬R:¢À§žúÇs,[¥º‹êŸþ韒×Úáÿø“w!¼ÞÔJýýßÿ}ñÈ#ŒžòÙÏ~6-å…¨Þ0èm†´ëè'É7í®–‡¡zùxœ$  H@h„@wîüI‘ÇJ@ ð°Æ›0çœsNW½Öð ‚KhD €$ a!ÀD+n¸-ZTlyS±[·ÊY3¾Ö[†ÝJñH@€ÚEÃ$Ër¬^½ºãž:ê¨_» ÆíâÐë„Q·“qÁµ#p#iá>¬øN¦•kw²Ža fëDh5í´3„ ­†Næ1ÒÖÉ8hox:aëe¨UI'^sÚὪZ><öØcIäÇà…o8ílÓqíFöÍ”S£m¤žãñ°’/IÅsßÁÜpý!®²p‡¹YòÙHô¶ƒNæ¡–+ H@€¶$08x†õq¿ÛÀ k]Ï™3§Ñ‡$  H «p©?oÞ¼bƈ énĪÇsLrÞøŒC€$Ðm,µÁó#ûN†nÅÓÉ#€×Œ­«W¯.6mÚÔöÔá áñ$  H óÞyçâöÛo/¶lÙ2b¹sç{ì±Çèw~(ŠÝwß½X°`A±yóæbëÖ­ É /¼P\uÕUI,3}úôO?ÇÜëÛo¿]¼ôÒKi{öÙg‹gžy&-·¢.°dÉ’béÒ¥éK@€$  ôŽ€³½coÌhš@îµæÑGmú:ÕNÔ[M52~/ H@ÃH ¼ÖÜxãE'Ä5z«ÆZcž$  H`<áUæþûïo«¸&®Û)o8ãåÉß$  LTO=õTñÈ#$*Áà ƒ*<ðÀ1ËÅoyàèÌ3Ï,X:kùòå£K@½üòËé3,'Mš”Ä¡Dß}÷ÝbÛ¶mÅo~ó›âÍ7ßãц—@N8á„âüóÏO¬ùß  H@€$Ð; kzÇÞ˜%Ð4N{­Ñ[MÓE㉀$0€:íµFo5X)L²$  ´D S^kôVÓR±x²$ ¦¬Zµªxþùç“$.€·š½÷Þ;þuŸØk¯½’†¥›n¾ùæâÞ{ï-^{íµtâ¶ñâ<ÛœvÚiʼn'ž˜>ë¥m·$xPž3gNù'ÿ—€$  =ðZ³råÊâ‰'žh9¿ˆUgÏžÞ8lùb^@€$0€ÂËL«^kâ:z«ÀJ`’% 'À’O.ûÔ|1"šay(6ƒ$  H@ÀàØnp“nÊ% ðZ³lÙ²¶ÀÀxî¹ç¦·#ÚrA/" H@ áµ—Ýí¼ÅyÚi§¥7Ûq=¯! H@4ᵆ8Z z«i…žçJ@€$  H@€$Ð*…5­ô| ô˜@•¤è­¦zž+ H@ÃB ¼ÖLŸ>½¥,é­¦%|ž, H@CD Uo3­ž?D(ÍŠ$  H@€$  H@=" °¦GàVí"Ð.¯5z«iW‰x H@díòZ£·šA®¦]€ÚI U¯5z«igix- H@€$  H@€š! °¦jž#>#Ъ×½ÕôYš H@è)V½Öè­¦§Ågä€$Їšõ:Óìy}ˆÀ$I@€$  H@€$0ÀÖ pá™t V½Öè­&Hº—€$  E«^kôVc-’€$  Œ%Ь×½ÕŒåè€$  H@€$  ô†€ÂšÞp7V ´@³^kôVÓö¢ð‚€$0šõZ£·š!(|³  H@!Ш÷™FïH¢½¨$  H@€$  H@! °Æj !!Ь× €Ë–-+vÞyç!!a6$  H@­hÖk Þj–,YRLš4©õDx H@ÀhÔkÞj†¨ðÍŠ$  H@€$  H`À (¬ð4ùÈ 4êµ&¼ÕwÜqùeü, H@ÀF½Ö„·š#õ©O¾ú՝޾å[¾e¤__ëZ×Z<ÂÜ!°0SO=uô˜Ç„@„@„Àa!@¦’­ !!!!!!à ˜cÍ7ó7Î:ë¬á9Í•!!!°#>÷¹Ïm<§ßömß¹ºqêI0B Bà°ø®ïú®ÈÕÃZ¹)W„@ì92.!B B B B B B`>yÔ|¼ru„@„@„@„@„@„@„@„@„@„@„@„@„@„@„@„ÀžˆcÍžTtŠ!!!!!!!!!!!!!!!!08ÖÌÇ+W‡@„@„@„@„@„@„@„@„@„@„@„@„@„@„@„@ì 8ÖìIE§˜!!!!!!!!!!!!!!!!óˆcÍ|¼ru„@„@„@„@„@„@„@„@„@„@„@„@„@„@„@„ÀžˆcÍžTtŠ!!!!!!!!!!!!!!!!08ÖÌÇ+W‡@„@„@„@„@„@„@„@„@„@„@„@„@„@„@„@ì 8ÖìIE§˜!!!!!!!!!!!!!!!!óˆcÍ|¼ru„@„@„@„@„@„@„@„@„@„@„@„@„@„@„@„ÀžˆcÍžTtŠ!!!!!!!!!!!!!!!!08ÖÌÇ+W‡@„@„@„@„@„@„@„@„@„@„@„@„@„@„@„@ì 8ÖìIE§˜!!!!!!!!!!!!!!!!óˆcÍ|¼ru„@„@„@„@„@„@„@„@„@„@„@„@„@„@„@„ÀžˆcÍžTtŠ!!!!!!!!!!!!!!!!08ÖÌÇ+W‡@„@„@„@„@„@„@„@„@„@„@„@„@„@„@„@ì 8ÖìIE§˜!!!!!!!!!!!!!!!!óˆcÍ|¼ru„@„@„@„@„@„@„@„@„@„@„@„@„@„@„@„ÀžˆcÍžTtŠ!!!!!!!!!!!!!!!!08ÖÌÇ+W‡@„@„@„@„@„@„@„@„@„@„@„@„@„@„@„@ì 8ÖìIE§˜!!!!!!!!!!!!!!!!óˆcÍ|¼ru„@„@„@„@„@„@„@„@„@„@„@„@„@„@„@„ÀžˆcÍžTtŠ!!!!!!!!!!!!!!!!08ÖÌÇ+W‡@„@„@„@„@„@„@„@„@„@„@„@„@„@„@„@ì 8ÖìIE§˜!!!!!!!!!!!!!!!!óˆcÍ|¼ru„@„@„@„@„@„@„@„@„@„@„@„@„@„@„@„ÀžˆcÍžTtŠ!!!!!!!!!!!!!!!!08ÖÌÇ+W‡@„@„@„@„@„@„@„@„@„@„@„@„@„@„@„@ì 8ÖìIE§˜!!!!!!!!!!!!!!!!óˆcÍ|¼ru„@„@„@„@„@„@„@„@„@„@„@„@„@„@„@„ÀžˆcÍžTtŠ!!!!!!!!!!!!!!!!08ÖÌÇ+W‡@„@„@„@„@„@„@„@„@„@„@„@„@„@„@„@ì 8ÖìIE§˜!!!!!!!!!!!!!!!!óˆcÍ|¼ru„@„@„@„@„@„@„@„@„@„@„@„@„@„@„@„ÀžˆcÍžTtŠ!!!!!!!!!!!!!!!!08ÖÌÇ+W‡@„@„@„@„@„@„@„@„@„@„@„@„@„@„@„@ì 8ÖìIE§˜!!!!!!!!!!!!!!!!óˆcÍ|¼ru„@„@„@„@„@„@„@„@„@„@„@„@„@„@„@„ÀžˆcÍžTtŠ!!!!!!!!!!!!!!!!08ÖÌÇ+W‡@„@„@„@„@„@„@„@„@„@„@„@„@„@„@„@ì 8ÖìIE§˜!!!!!!!!!!!!!!!!óˆcÍ|¼ru„@„@„@„@„@„@„@„@„@„@„@„@„@„@„@„ÀžˆcÍžTtŠ!!!!!!!!!!!!!!!!08ÖÌÇ+W‡@„@„@„@„@„@„@„@„@„@„@„@„@„@„@„@ì 8ÖìIE§˜!!!!!!!!!!!!!!!!óˆcÍ|¼ru„@„@„@„@„@„@„@„@„@„@„@„@„@„@„@„ÀžˆcÍžTtŠ!!!!!!!!!!!!!!!!08ÖÌÇ+W‡@„@„@„@„@„@„@„@„@„@„@„@„@„@„@„@ì oÝ“r¦˜;HàÿüŸÿ3ú¾0ú–où–Ñ÷~ï÷Žþù?ÿç;XŠd9B B žÀ?þã?޾ú՝޾ô¥/uòôjW»ÚèŸý³vðKB B B` üýßÿýèÿïÿÝÉÖïüÎï}÷w÷è[¿5敬Êd9B B B B B B B ˆåg¦\´iŸûÜçF¿ñ¿1úë¿þëÑ7}Ó7N:é¤Ñ/ÿò/®~õ«o:+I/B B vš€Å¿}èC£g=ëYÝ" ‡Õ›Þô¦£‹.ºhô=ßó=;]¶d>B B 6MÀ׿þõÝëoÿöo;GÕóÏ?t×»Þuôßñ›ÎNÒ Ø8Öl²$þîïþ®;}åË_þr·›íû¾ïûVºSœqïÿþßÿÛíBßõè_ÿú×Go{ÛÛFï~÷»G'Ö|ó7oþÉe‡‰kr ÿ|ík_©sív×ÛîâM–BàÐ0>ñ‹_‘«N_!'V9†¦±éoþæo:¹úÞ÷¾·“«V·i¹êÔ\ÿáþ¡««oû¶o;´íó  ÆE>é†Àn0.“§65GlfàxÉsÁœŽÜÈŸUŻм-Ç'?ùÉÑ;ÞñŽÑŸüÉŸt2MyÎ<óÌËÕÃÆu‘ºX÷=æ©ì,t'zæ®·ÝuóJü!!!!pØÐÍ“œí¤JÀãLØjùp•'mvñúÌzðâìöéÎ8Ö¬±¶-½öµ¯}à}þóŸï“ j’áÓO?}ô€< [ \4vžóœçŒ,–1ˆêvËÝýîw_4Ê¿O™ÞøÆ7sªa¼²³ÞñÚ› ‡‘ë¦Ø Mç+_ùÊèâ‹/>ff¼·ËóÎw¾óÐ(¶ò:ýðÓŸþt×/)ÝŽ„¿Þõ®7zØÃ6úÿâ_lež“©Ø¹ðº×½®;}…\¥ì’«:Ȉ›ßüæ£ûÜç>KnvÇ&H­³êw}×wnxÃnÔà$ºK/½ttÅWtÍí׸F7æßþö·ß•æ·õù<¬Œõñ|ä#£¿øÅ#Nbúûi§6ºßýî——¶¾U&ƒÛL€ÎúÑ~´s¼ü³?û³ÎPÌ@àüò?ð£sÏ=wtÎ9ç,%/8Ÿ¼êU¯}æ3Ÿéœnt£usÕßøÆÛŒgjÞ®¼òÊ‘†™vë\§Ÿ¦Þ¸Â#×âYIT—_~ùè5¯yM7·ãXsê©§Žîq{Œ´á]NYzë[ßÚ½|f›ºãï8ºÃî0úöoÿö].Zò!!!+!ÀqÙe—uknŸýìgGt&s%v~s%úàýïÿѵ®u­;ׯ¤€ F¹è¹Ï}îèSŸúT7âdtá…Ž®}íkï‡ñ­õ¶´Ùåñ>ÿùÏýáþá±¾~äȑѽï}ï<òyy´‡.†8Ö¬¡Jíò³‹íyÏ{^'|ÿ×ÿú_ÇvèUr 3ŸøÄ'º…ö=èAõuçLòçþç°æhpòÉ'ûmÜæ{Þóžn‘Ñï„;ÃÞ®:Ö0N^uÕU£}ìcÇŠ«LŒº›ÜYظƒ¹E,ˆk»ËF<í}×kìÕ†ßüæ7Ûݨ¯+Wk¶¨&+;E@¿²èWÎxljç{„Œ0±³ËžsMŽ’ñÑÉU}ðš×¼fý4öý°Mœ|?þñwlªÀÝò–·Ü¨\UgÆ|õ(ÈÃ)§œ2ŠcMÕÊò±>iû-oyKw¤¾Î˜c02[¾Ý$†ý$àt ë6_ýêW;GÕ–†ù˜ïwÆgt?™çšÛrؾÿû¿f?äPcÈ_þå_v÷HÛé.»êXcüùÓ?ýÓî4Ú®@GÿÜà7ýàþ`ç8Tß­ûý°q]7¯EâÇøÿøk»gŸ}öÎ;ÖèÃïÿû»S—Ø=ld¢#sPcÍ"-%÷„@„@„@lëK6±‘ØXfÃÀ<§š·\rÉ%£w½ë]ÎÏ©¦ ÖõÌ¡lpÈCÒ¥á÷eÓmÓØÖÏ쫞4¯¹¡Ol3orín[ùT¾m³•ßmM×ÜÏæŠÚ@cŽdc…õé„h ¤E´4Vô™±ð OxB·+Û‚Ö¸@ðØukÁ½ÃåŸøÄN0[Däýzë[ßztÑEÕ%cß[á.ÞþbãØ›¶ôKå&œk·¤lÀnw»Ûm<LJ‰ëÆá HP[mûÇ®·Ý*r•£úa•³mÓumÞC †ø«¿ú«Ñ“žô¤Ñ‡?üá‰2ŽÒk±‹sM§F=å)Oéd-ùbB}ÛÛÞ¶;Aª®é¿WŸ­ï«O×ÿ»öN×xßûÞ×9$È;c‚ o-’nª<ø·ã újÿßT>s:‡•±¶B¦V{QÎöÿÃ\§)[¬ƒ€>Å©†³ª ÖÇýŒÁ”,ÈCó´W¾ò•™AÙÎD;¸nu«[‹¢ûŽƒk›†ÏíÿoÜÒÌßÒEc²“L®{Ýën4LJëFá LL;Ź®·Ý*‡¶k^eS.ÿW›®ëò!!!p0>ô¡u›¶éãž|@×äĽÊÅ]›žl`±%^ñ;…e•i=úÌÓŸþôΉ˜~£<žñˆG¯Å?Î3adW #æÚl7 cåììÞ‡ ìNú¨@ù¹Å-n‘“> HÞC B`ÏPbMh?øÁ“«ó<ú‰\µ[žì Wyè[àÈ`'b9å‚ÜÜgò{¯{Ýk/䊉í¾ð…n·uàè'|0*lòñŠ•vÞC B ž€9¨Ä<º´ ¢æ\œ.O9z’˜—æ Œí¾÷|g×ýÑ['{=òôf7»ÙR‹:x*Ãr€—Ój8ÖTpü»…ˆœôQDò!!!!°(ú泞õ¬cÄœâÉÇ?þñ3Ÿl04M6²ßú­ßêÒ°(/ '×=ö±]íjWÍV^Ç žÐ‚röðù‚ .è‰>ëTó§m:í¦‚õ;ÎMô~õãTCsöGvFaÙt+­¼‡À¼m³ó¦“ëC ¾A Ž5ß`±’O÷^ò’—[ü©E¿ŸýÙŸí0ƒ›Å>ÞÀŽNcÀúÏþóÇ9ÕøÞNsGõîƒc ÅäŠ+®èer=B§””ÿÿmþ†@„@ì 2ÐîørV%Lfõ¨Gu“bYN­f8‘”\õÿË©/²–\5AvÚat ÎE8T`q^äjÉ{„@ìrÐ/s/½ãï8ºç=ïÙmal¶‘#ë9Î_ùÊW:Z§\øŽó+¹êCÎaæëŒè­¡ý†7¼a§D®öÚOùB B B B`ýèâ^ì8e£ƒ~à}ß÷}ß±ÍdËäÄiÐlEôý ·¹ÍmÅ£|œxmÞbSîζhþ3ͱ†‘ýÑü¦‚Mi?ù“?9ò8PŸÅ[ëzìkßùßÙ]ºLº•VÞC`^Ë´ÙyÓÊõ!ß Çšo°Xúál cô*”cˆg öw±y{k€+A\÷z÷û¸ïÛkËgFZ§Õ‚²Äã* Ï”#&Ð×,¨x<Œ…»Î9çœîôI÷äû8ŒvÃÛ5_,½Óî4ú¡ú¡c§¾Õo·J®z·Èg=îûŠã0½{|‡ %W!ìQ8%„@¬ŽÃšç0;²Û¸Å©þ–·¼åˆ®ŸÛD€‘˜Leø­ 9rdtæ™g;ÆoäÃqÉU2Ä«8æŒû¾Ýaø;Ž5å”äTZ§Õ”Sïa(cÊÛ@À)”æªõèôë_ÿúÝIÆ×¸Æ5¶!{ÉC„@„@¬•€ÍPì¶6 tÏw½ë]Ý£ÍéÞˆ?üÃ?œ(¿ ·Ü»âX³ÂzáXÓ>nAÔ6Ö!±ò~áºn”¢(|òÉÇ<_‡Ä±«×0îÚUÿ¥/}éX((@B VK@3VÕÑ–&SíÎåÕ¦–ØB`qvåôÛ&Ù`Ò?+˜ô’¡¿ø‹¿ØÅ¡“«#U;Jfű˿sVýà?xÜã*S{«[Ýj—‹•¼‡ÀVpú›±ªäª9£B`Û8!« Åäì`W™ #Œ_v™ æ¯dí,#õ¬¸wá÷?ÿó?ïkZc;§$¯„Õ0V‘«õØ5Žõ¾K} ð/ÿå¿vÚiÝ£šj£™¹&Ï5¯yÍ¥e3›pÀˆ§Ç@±—†`CGÇß÷¾÷ít:§š!‹÷t– ì}'šqœ–Iw\|ù.†X¦Í‰•×È+;YiÆ¡vÃÏ*ÓJ\!°nq¬Y!a‚·}6¥¨ Ö!Á" ïÖSN9¥T†í!ñîÂ5ÔË.»ìØó/gí€Ä#!B B`? P°û‹ÓNªz’ ^d‰¸öI®âf’~1\åX”!!°Ÿ8Õ´Ž5ä$ù0tw*ƒ´™jîº5ÕR>þñ¼J®žtÒI“‘÷„X:úmo{ÛΦS‹ÐtÐw¾óÝ *Ë<ªÿ(úüíoûCu²ñu®sî´»yí€ìhî©€3û£yϰhºCâÎ5!0ŽÀ²mv\œù.B`6ož}I®J ¿;•Ðe¨*|+×ïÓânWáÚ”ß1}Ë(ŠWÞC B v“‡Õö$3þoÿöo\Q /ŽÎ÷üÚ Boq‹[ ^<­ûò!!px8Õ«‡¯y竌ýûäTÃéÊ+¯9µ¦‚SiÞƒEB„@„@„@„@¬’À9çœsÂ)+ï}ï{;Y9zÏ›ž“œ=1 } ”hCOe™7½ƒ¼~‘õ5öÇöÄöÇyuýEÒ=HNI{· ¬¢Íî6ä>†@kV̽ULD=¯ð]qvv":žÀ¼¥ÛÝ“’îxÇ;îDþ“Éõ`,ðˆ•6D®¶4ÆöˆŽ÷¿ÿýÇž mbk\ctöÙg¿!߆@„@ìó®¯ýëÇÊJ>쓃̱‚Ïù³ªgÀ׎aÌœwÊÑ“fB B B B B`Õò‘Ñ_þå_ç…K›=Õ˜Bì < j•VGÄÕ{%a<î{Æ8†ÌqÁ33<=îbÓŠ ¯ÜO~ò“£ÏþóÝó¬ Μ\ìt÷øÏø\u` üƒ?øƒcÑRZ(Žž¹HàÜtÕUWuùò—¿Ü97]ýêW}ÿ÷w à*ÇêöŸøÄè/þâ/F”[žÌXyôˆ÷E‚:—6à¸Á¡Ë-È‘«òaŒ7féÃ'Ÿ|òhðXÊ÷¼ç=Dz­Ì7½éM»1ãØ—?àgìQãùB¦ÿ=ÛÛx´J¹jl§‡5>ã0r2À":Ù%ÿÊ!®yÆLˆÜ§Ìä±P†œ*(]ãvɨq'ð)BÛXEYVéØË”S¼”S—ç±7/ø%óÓŸþô1S4êšLÕ¶ÖŒ)ú‡S'Ôz¥?Ð¥­_'††£ê½½Óqß»f¨\]u~ÛüåóþÐkçe½·¥÷]¿­š§Ö«½Ögs-}Çï›+úéÛ•÷ÙÏ~¶ëË•rŽ<2\DVôÓèÿÿ§ú§#¯ Æ(ó½ïùžï©¯¿ãíyòæÊB^M¥˜CN² N¤¹ì6ÖÖ3ìÕNæöóŒweÍ3c¸ÏšgÖ}õ®­©72Àø+?³ôˆ’Åd,Ýþ8ê<é+Æy\]G×òZ¤¬•çEÞéò«œõ~ž‰wÚ=ôL}C]cŒûÇ,j›˜–žßŒt¶Ö~„»yª—t‡¶}C= õÞýóOÿ«ü>iP÷¶ï«Ìoo>‡À2Œ‹ü໓ьdŒ æ[«”Ëäq™{S¾eèåÞ}& ÿ{D“Ç?*¼ë]ïê6#/bï?ŠŒöÈ©¡q‘ÏæÒd¿õ+z¡{­ Ð/é\³ôº*Gû.^zLéo}»qäcûX§ç`!='GšÇOJÏ|¿ô0óƒI㩸'ùò{ÿšiºÇÐt'¥Y߯‹uÅß77¡GªWúfê“-nÝ:l?/³þ×VÌo¼ãMG4§gö¤iíbVܳڢû]cÎQó9:·y¡52v¥ImrVÚCï·Çö¾EÚlÿþUöñEò*?ó¶9cûªy 6¡¿'´'rÍ_ˤÿcvëê/æzêŸ}Àœ~ÒXÓ'ÿï68Ö,Q„óSŸúÔcF6J®àŠÆ/þâ/ÖWÝ»Îe‚äûÖð'¾ßùßé< ŠÉùçŸ?º×½îuÜýëøç¯þê¯FoxúîËD€2üŠE˜zD“×*‚rÚý×*¥wäÈ‘¹„x<ó^<ú¢Œ”Ê€·ü3¦1,y†ø t‹|ÞúÖ·ŽÞò–·t‚Üÿpƒt ¦œƒ~äG~¤¨CÓÏûoÿ­s¤Ð~ Ê÷»ßýºç§‰C}Q4Ÿö´§uÊ­²›”?úÑîŒÍãâ°à¨Ý]qÅÝÏÎcó˜c×ûý²Ë.QÜ Öj”„RžÏ:ë¬Ñýïÿ¥˜ŽËÛ¸ï(M/zÑ‹FŽ¿Ä\ ´\tÑEÝÎÑq÷,óÝW¾ò•®®Md8¸T]«uÍpx£Ýht§;Ýi%§AhË8¿ãïÙI@H3Œª[åU§¸{iÓŒâ\pÁèÌ3ÏœXLÌžüä'w\s‘~qÕQ'© þ¿üòËO«ü®Œê÷ /¬Ë{_G~K ÿìÊïoÿöowrAÁµ{ÊjíÍÿ}¹j<2¾?ö±íúd]oüzö³ŸÝ*Ý«¿Þõ®wÝínw«KÖò^òÿo|ãèø@·ØÐŽä\É ãÇÿðwýl™aØ M2+w·ºÕ­æ’«â!Þüæ7wõQÆu‚7¹Š§Ië­o}ëÑmns›¥œ,é!ä*CÉ©ôÕ¹j¼3ÎKCÝ ]ÒVžùÌgvºÚÈ}îsŸÑ-oyËB3õ^FÖ<ÿùÏïÆ~åV_?þã?>U¶·/¾øâN·1f›\‘QÊ m(+®ôGÔ•UÛÀu™²N-ÈŒå÷e/{Y×OJoºÞõ®7zÈCÒé}3nŸûgåÛÛÞ6z÷»ß}¬üÒô “ßÓN;mt䨮æ}Ù@vj ô:b9mIÓ«ôíŒ1D;»ÉMn21iF”ßýÝßí/]dñ”ŽPÁÿÚ3·ôÆËûÞ÷¾ýŸºÿב߱ å˽  Ÿ½æ5¯éÆf(5ÆV0þèÿôÜ6ãé¶æ¢úecâ+_ùÊN?­ñíž÷¼gç¼Y׬ã]>É$cg®gŒ®1‹\-Yqó›ß¼[l0o]E–¹ª±«‚q1ƒ¡A<ŽÞ7/Ì1ôwrÁ8T㟸-¢˜Kö†¦%N㹪ìäC¬/Cùï|çN†›ç Æ5õon!Èã=îqnÜr?]ⵯ}m—/e×ÎÎ;ï¼nÌmí"ý¸p“.;VGŽÊ‡»ßýî-…® M(+‹#‘²ú^üÚ]Å=ÆÞE™öó4ééʇr’=¥7I+síUé±AUùÕuõ²MH“îãD`,– Ú®yªzÁ¾ÚWµçJ{ö êÙ¼uRз1«¶Å(îUAÿyÁ ^0zÝë^W_{W>léºãÂ:ò;.|‹0_}á _ØÙ´y}šçÆ7¾ñèGôG»¹·«!å»Ñ M»Z¿É÷ú XÃ`Ï!éwû­ñ¼y]”~Ô ”±†|&»§:]ÃýlÖìÔä¾1‹nV:g^:¹OØOÌ[ä‘Nüs?÷sǹjÿÒ—¾´›ËKWšÆEº#›½¹¯H“Î@çfWR6ëXæß}—½Ð @Ê"°£Ñ£*ÃþÃø]ùê;ïÊö¸Ç=®c×ÖÁÐtÛ¸úŸ×ͺMžŠ{Ù.èLʯ­UrJPŸã8·q­û³¶Á^Xú'Næ‚UwÚ„º®yŽuùž×IuZ[”žy3½õª£ë*Ú#^Ú€6(m}êAzPçØ®o¬:¬ºÍVþÖÑ[§ÄMÀ¬>ûŸ]íW~åWÆÊIsíG<âÇ­»§ôY6˜óšªmB”À\A{0÷µ§í³ýø¦ý¯¿X¯³NjžW›(´;ýÅøÂŽøc?öcÝzì¢éLËC~Û»«oCE3“üIAg¦ðôá¯ãÛA^Açd¬üð‡?Ü}¥óóö]§c2¼éMo½â¯èòS§åTžúï 'úЇ:ã"!aq`™ }§ Ì,Ò ”Š‹­vJ•²ÙƒQ”Q–2ÈäÜsÏí_2õñ2\Yd£x•ájÜM®3È>êQêÕÆ]ÓÿŠ_” ÈŒÃ?ôC?Ô¿tìÿ”K dï{ßûŽ)Ü v­ãBµÑ+¯¼²ûÙÎ2å²è»ßû½ß;f¤,e¥‡PVÂð'~â'F§¬ñHôªëW½êUÇõ;ÂUïBIJêZÖÏ)qã‚ëô íéÞ÷¾÷¸Kf~'= & Æ“$å”fEȨ©žô ÆÆŒ6h³òNèOŠË5úþ¸±ŠH¹ê;Ö¬+¿mÞóyÿ˜ôRˆµÇIâ:®­ãLð9>T0¾éOyÁ8a¢¿NÇš*ë_ýênáÌxnlŒŸ%—,YÀ\vÁGWæ¯)ø,ov³›Ë ßè'/~ñ‹» kízöý¸`ü±€db9ÓJÅ¥ŽìÐ|ÉK^ÒÉgù¯¼×5ÞMÀÈT²Æ$eÈÂöŒŒÁâÎPÇùÀB{«ò˯É9)»édƒàå¢û™ì)+]ÏwãÚÆ"e”—YßÓèPú]éÚeM@gÝ?Ïïx’YÈLý›~>Ú…‰/dzE¶â¡ãj£äjŠ&Å'm†;ù¤{qÄëëOäntÉqù·kô¯~ÀÖ«ïX³®üöÓÏÿûEÀÜ͉ì´Us¯6è tJúeÛ\g|3ž ú”ÅìvNÛÆ³ŠÏú±wã¹¾Wõqq“yd¾1–L²Ñ7´»oÚwÒ'«ÍÕñq~¡O î373‘¯š?–\iãÀ]þŒÏ9眧%Î~ózûÛßþöÑïÿþïwNþ¯¼·ñ(¹ªNéEÓäZÝG&Ò1jN!¿œ^‡æQ{Ñ&µ!Áýä¹ÅŽiŽ5æHä§1Õ= üÕèÊÊ‘HYµé~PNåÕ~ŒëCÊÚcÈÿꔼ1V‡ÕïŒùúƒë*žú7ç9\ÉñquMwÒ†q7Wæà2-t\å²™I|ô!y—fÅS}’.u—»ÜeäqœmÚ@?Ðî•eœ^äZòV9¼úÍÄ"Fß±fÙüZ¬£?/;†ôó›ÿC ¯8 ÃŒs­\ +üÿÓ?ýÓƒæ=ç6½§|»]ÛÔ–ö9/œglv¤¯•þEß!ÓÉóyœWÌqéB­®ÄY¢ïlÒçÍ‘àå/y§k˜SOš»¯ìãæÔœÍ#èn³û€ù?ÀõÊK¿´é¹Ï}n§'”^ÕÆEï"ÿû²Ú÷^âèœpûÁš›Vˤ½†^"oý@¿¡{Ú¼ÕêwCÓíÇWÿo‚u¥EΰÍHÓæ#ºõ¸@÷ÒvÌèF­¬wý:¾ÓÞÙu¬éiƒÚ´|¨uÁfc]•M©ßF&åsR[4ÿÅËœ/zæ¸`Þ¡üäOþd·¦g°Ê°ê6+oëhwø˜§™?Nª+mN¿pÔÞ&͇Æ%›¥Á¾:)ó$m;6s’yëŘdŽgLRÿ5÷ó^õÿS?õSÝüoÎUý4óÿÁXmÏ>˜2hª“:ì¬L1>ÂýÐvJqOSVú÷Îû¿´œüaê+V“â2(… )ìj^4„À 5FDÞ¤CãÚÓŸþôNL[ˆ­¸(Dî¡<p¥7Ó áÊÛ’Ò5N¡«t¼×‚ž|ýÌÏüL'LÛß'}në|Þ6àzelÛ%åp’J\[Цÿ]¯ž 'G0B¶íÒ5mp?– ¸ÊÊ‘hènϬÏxs:axhëšaôa{X§ÌΊcèïPó7³SÄ&)KE€q;PyÕÎ0ÔV¤mÕâæ8äÍ=Ú5åò~áŽSMH¼¦µYéô'AëÌלּä÷ÃO@ûZ$è·}…U\ËŒ©óæƒC¹jñ̤Kž¦ùs…6‹Æ>ð'8ÈM‹£ýM|Æ‹xæ÷1ê÷önbph’®ëÉÕi'hµñ×-¢<ïyÏët‹i²K“—ryøÃ>ó”2<úò­ý¿Í˸ÏÒÄD<|7k<í_ãÆ/úÇ\õܶˊ»Þ]?oYëÞyÞéBô9Nâò'ï-X>àXèÑa“ÒÇŒäÏxF7¡V×xËOõ zçöÛ¦¡Eº§<å)ÁkH[v¿´-Ê«6-|ä#3–•Lœ¶Øæ¥ÿ¹îo¿_g~Ûtòy? ´cØPuO¿½êËmÛ÷yÖ˜84Íþuò`îÅÑ“S¬|õ¯­ÿå‡<õ8Dã(º“w†Î-+žz×7ÉEÆÙ AN=õÔAްÆzEe0&ÍšS(Ÿ1ÈËí~zÁÐÓwÌÌí9÷š[L“y~3¾^zé¥ÛqúUæzÇw™údzm/Ê+>ßO mºîq½ò1ðs*¡sµñöã‘ìe 7ÏRÖ~Cþg°%WÍ£«®Ù|Ø7ì˜dwÿ:” RôNv™iå÷›¶A?Ô®ì$ŸeËè§§½HCÆëir¼½WÝé“êJŸTŒÙ­-Œþ^m¡½wžÏý±jùÕ†Éi¿ÿFöÕîê¡ ‚mý9åÛíú;èö“ô¿A€r³¤…ð#GOã›Ç±Æ˜ÒÊÏ8¥LŠƒ¾EÏ¢ÇÒ§é••[cGAƒôvÎų±Å]ã`é#~çè ûœtZý³ÒòÎ_÷µßÓýÚïûÿ×µí5õÝwù¡¿ôõƒ~:ýÿ'ŽIÖò`]Åz{ÝxuÊæÇ±š.Çk–î>©œ‹|ÏxÉ%—tŽ]CõOיеGïl†ld×Í㜣MÒ§ñÒ&]÷Ä'>±;q…Þ½J>-íi|ǵÙu¶;ýCš‹æ·ß·Ú²±ï±[›› ±½Ë‡6P/ó6‚v>ÒÆßÿÌ1lj՜€Ôÿ´àwŽ`¿þë¿>úWÿê_ucìÐt¦Å›ß¶@k–¨JO:‹`02!ªÅ ßñZíïà208z¹²„ë7W^ÿú×w†ƒJ½ß.< +ÄEióY`a$¤=þñŸ¨„U¼ãÞ j.*N×`Êè4$’5 U­bˆ/ƒ'¤2HG½Pè „‚A]™x*q¬Q· ªOxÂ: ÿKÇqŒgœqF÷Ž '†­ „±…!œMva •gʶúVf¬C'Ù(ƒ…´eÅ´‚ú 80&:öl•ee˜¤”SæûN5Ž…ÓfV©¤Ðbg”锣'òØg‘¯80¸ãdŽ7ô$oÛŠ§ÿ®âi,)£¨öe@û2^à/Må§Èê;Ú– míO½qp:rtrÕuÆ c"$HP|¥åô©q»M°(ÍmXw~Û´òy¿˜Ø3¶Wªñ»]×&û Lú&'O'³T¨qʨ?V°ûÇŽÿ’«òÊÓ3^-p(§ïo¯?Û™¸È˜F·¨ÓÊurjè -òÐ{Ze;óq·#‡q€ì&ïêñ7¾3Ú•?ı†ÌP~‹Ÿd ¹JP‡ÆXc’1ÕØØê Ú‚û\G¿Z¥¬©ò®ú]½ çʪŽº¬A-¼2”•ÞJЛ8MÓÛWË2Ѷ8PY$/9'NýY=rH¥sªsºyUý‚!eÞµ/:ŸôÄ#Ðe옣Ëh?äª4ÉUùsmé‰Ú#YëA§áQ'÷;¥®Ú¿ô´Sï‚´ì.Ô_ú,ïŸÌ¸ÎüöÓÏÿûE@ßÒ~µqA'#ª­jÏŽF&+Ú oxÛ¼NmmË~6xLƒ/¥ ¿ä½=O9ª“ëÓäc/Ý~¬ŒÊGÎr:0Î8‘Ÿ;o0Z=„<ïÏï'ÅK^™¿ÐÙÛ9®äª2+ĝޮ:*óJ†+‡SZÈð¾Þ3.=FñÓ¥d ½ /é—ŒSÒ ׸–QÒuÆ,×m{P/ÚCþ…*«ºÑNð$Kª¬Æõ¶¬Æq×­*T{­Çˆ—ŽÂ©ÆI{«žsÞáD¥>•­‚yŸ~¯>Õ/V”½dÅîV×½ÓÞµ/ýK9+½Ò9žàiÁs:"Û€ôýÔwì/úç´ 8ÑýŒUÕþ¥'Ï•O:‰ 5Ê׿°ý-«È¯~k!Ó¹®SŽúeÉÿûE€©ÍWŸê—žìs¾»ÈܰߦÿOùv»þ6Ý^’Þd½IG#Ûj¼ #ZPú8(ãÝÁ{ñ’ß“t?ë>ÈïJ—Ìv"$ÙO× —åƒ.N²ÖbþM¥³…üûÿïç^+]Sóyºþ§ËЭéùËèsÖÄAO¤Ë>@‡”—ÞŸG(·òû}aÓ¬Ùf¬hSm Sq„¢û¨Cö«šÇ”-N·s£öþUfG“Wó±jƒÒ ÷›K±_yi Ú©—ùNÍ»´mÓºœyã"³bcµÑ›\ñêwæÊúæ^¥·J—ÎÌ!Ýux®*¬²Í®³ÝÑ[ØÌŒUÅM]ª©Gk¸ãú‘ù>›D?¸×¸Ä~Îö^q¹Îú™~©Ïôgm˜] Ú9¢vå¹ãÒí§'ÏÖƒµÁª_ýßø©MéCæcê¿ÒPÿÒ´±ÒuóÚ3ûyÈÿÛI`~ëÒv–ã@rE ;Öî‚ .èÒ'„ða‘HÐíÿÍ¿ù7ÝÿõÇ÷—UîXª¸‡¾›¼*e¸pŸ¼:¦Œ‚$o 0œV,:6Í=†ßq<`±:o0qŠ1ظàÎYÁ½vX3¶N5”¡ù‘éGù÷2ÀºÆ¤”dp¤ø~¨"àZ©t}–Žc” F‚Jã ÁYåòÎa‚ͲÍ*ûºÇ £NÚ¯^òʪíRÄýn±‹Q³Êª(+¥cU§ÖˆS³ØKq® /œjŽu"Y¥€RÇ óÚy ~ijKFðR (ÕòF€2êÖãÔðóš'hSÒ’¶>Ç ÌsV{QNŠ„ñÆËuÚÕÖÜ'0bRöì8hBÔ!V•/“„'?ùÉÇ¥ÉØûèG?ú„l›`õwù®;¿'d"_ì }ÙQÆRÁû³žõ¬n—«ÿµGrbœ\5¯r,ÞРOpà´xVN5dZ;tÝ[rUœ%/, ¸Ç˜#}“±Ã¢»G+ÌŒŒ5&¯M*ÚÅ‹IqÃYCM@IDATº—\5öµÆeðèD {Ê@þ‰Ÿ\•_ãŸû®::‘ð}3“Ò©ïŸ&8îQv' (»…ã4L„8VJ£ÊEv“5&ªCÊViÔ»ñš33y± eÕ¯ð$/Ô» ½–S cø ì¢üÔ£ú¢3–¼—I¨¶¥Yú·v]ºŽÅ—߆æÁ„–¼Ôfô2ŽÎƨA®jǾ'ÿäI»e€QOŽª]Òý䃓k;¾èŽvU6‡C.#“ ~}Ɖzý@èËÕuç·Ÿ‡ü¿?èã LäŽP‹ñÆ_A[¥sö‘¨o‹õ“ƒÆã™TrE^–AÏx§^µZt‘'XóFκVºÆiúʲ ÉÏ:¯ÁK†Y²Cýz¤&ÃeÍ´ euÚ)ùCþ ʪì«,«ÅcN.æ¬Õ^õ¡rªQ«ìKNè{mÛT6é8GÝëúyc0ÛΩ»‹üÑÏ´cmF{Â}À¼Õÿúb•Q›Å\äÕ}âÐÎôm:‡ñ§‚øè¬ÕÞõv†Ê«z¥'Ž{<¤´Éö6¬"¿ôzy΀®NB`•´)cÙ´ }çv1¤|ÿñwWëoÛÜaÍ3™n­†~[óO:™Ê¹À81+8õ…TºŸëm4ž4ï¿Mc¥S»žlÌ}æ òE¥¯–.ξeÑÚwôë/Ö~<yH>¥#Ðßä·ìæôŽ Û }ݼÕ'ºçø#Nå).Âå·ôº:[¹ò¶A¹é̳ÆðöžIŸ7ÍÚ‚?°oc1Ç2w`›£Ó•DÛ¡“á­^k9©<«ú^þ´AsªªqÓûÙY8d¨ŸjW8Ò?µYñå³ôó*.Ìæur¡ ²}Ò-ɵ;ݸìÅ6­ÿhçÒ5ç´nªmVÐþÍ;èÌ¥'×o‹¾¯ªÍn¢Ý9yU›ªúó§XV¿Ö‡~îç~n¬ã¼ùEÍgZV6ݨ“Z·ô9ëÔmv ÷iêÞ¸äÅA æ¿æÌÕ6Ú¸Ç}f'”_׫sNé‹Ô¿>a\6w1~H¯[¿4ٹݛp¸ıf‰ú$<- x :%£ m÷LûûA|6àLZAÈÀÿK¿ôKBbðiƒ2y1V0(x ‚ƒÒ4Mkãj?Jà ,®LRêê:ïòàØêÖ1Æ`{ÑEÎ?ÿüžº—ÐepR~ƒ0CóЀ›€' O„q«Dd9( /xÁ ºwä—R¸ Ž5„‡+å¢Lq¶²À«\mY)eÀÒ*X¤³…ó²s†8 …º…¶œjú}®®Yô2Äëµ&+âÑ&À-V™+~JŒŠŽ¡#0ç Ú¾û9¨1²sŒÁž±e.^ £ïµ=eç[ýˆ’gqÙò§`´m]ý–â)NiˆkèXµîüÊSÂ~ÐVµ}/œèË$“æ¡muSkܰp!ÔøéÑl&nýÉÝ@?6žøÍ¬GÈÞóâ,0Ìc Ðÿ)üíT ³â‘®E¡vìS2“cy'®~ /,‚”\å¼:t’*M“unçòCúÐnႌmÇ=ã+ÝC?¡8YÀZd¡´‹dƒÈ2myʪ­2¢ØáaaNÀ›AÎI5êºß^—E%uÕN0µ}ÊdkÕo¥C®Ê¶%Ÿ 8ó2Ž<5éµãJ¢¯OÚöUñ–\Õ7õ“}nO®ê—m[s¶YA›lû™ºV®¡cÕºó[ùÌûþПÛ>MNµF=ýŽ?´­nŠ ®Åwc§@÷ e°”7s7ó–r°hÇ=c¬6aܲ #HÇüžñ×ïÛÈ2AYÙîw¿ûuc}^È੬ج«¬ õêʆ“Z P×åTClÛë*Ø’‹Nƒ)û„8É}ÎØBöÓ®:ê€-Xl0e oÛšºkë\ß® ®Í†ŽU«Ê¯ú•wºmþ*_yeóéÄäŒq¸è­úí¸~Ö¿vÿOùv»þ¶±Mísž8–²µ·¶jÎØø‡ŒœÕÛ{gيؤèÁ56‘ÿLØ ú6rß‹îEös2 §°ùÐ=è'æÏ­N:­>ÍÉ骂 íèO9zcéàòE6ËW}7-¾I¿ƒ½*ÐèqÌ+Ì!jí¯¾_åû¦Y[ã¸\|•åÈÑy–êôŶü~³ž`ÍÂÉ1Öjnã·u†7ÝLß¶Aiq°²Ó§¯_k{‚úÒ¾9q´N9æ9úŒ§h7CCJ`î&m¬Èæ¾£„6‚ÝsŸûÜnPüXé·ãúùš~ÿºUµÙM´;LÚ¾C—nÇc—~ÝöÁ~yÛÿñä´ofµ_ó6óAiµñ×½Æm†MÙýÚt¿×µý÷šoã~üǼÛÌcÓ¿¿Öˆ­ Ö=òküs v¿½ôÓÉÿ»Gà’b÷òž/@À Ã j)㛈3 C_³M€A2ØT!eÁdž@²hQ;¥ÝKâñ7+¸×#o®ú'ãŒë N„+e«é¸x”ÏÂAèV<¦ç ¬Ç<æ1â:n°6xû¾¿P$ÏvõóyÒ<ˆk«”fGÌ•phó¢=D­ÚWBƒ{Ù²R¾òcÁ¹uS¿|ä#GGŽ*2«6n©'íÙ„£‚vI¢`ŽôX1xÛÉæÙ‰„å¼AX>êQê<ðµQL}?)ø ·0ÙÜjq¿ý~•Ÿw-¿«,{â >cc(‡Í÷LÈUãå{RpųVö1BX0!3æ M-ŠÕ¢Ž{-hí³‚E2¹]h1®1ÞÔ)]ãâ ÈEN œ0ù—yðãÅç~ ˆÆ¾ÚõÔ÷è(§hõÇ|åÅ©˜Ëß6}· eÕ¶,T3ˆpÂðfôVëpªá˜Âb¹‚>Ag#¿´Ÿ~ÀЬg|“/ày½,½èŸ®é¯ýI|?N÷¸®í®ÁÍÄ}a×ò»N‰;lH0V™”ÁŒ¬p" y0Í(iL1–qf¨`¾i jçŽõÛ´w2‘Ók»a\‘—YÁbLJ:ÅÎõ °Æ2sœSkÈ[óF SÚâ¼A¿¿¶¥ÑZ¦ãâ³haŽì”¦ ˜s˜kwóÖo«|_e~éô™„X52‹ ³u2«4èè~£›Òw1¤|»]»Øæsž9Ð’½íxP\œe!Ã8{·²Œ“ì8[?†b9 ·›™Ù…83›§÷m6ÅÝ÷lÛÖZÚõ%úe£MÝ3é½t4º‡Es޵­ ìæó8HLJë ¿ß4kú>ç6Ž Ú–u²qN5®¡ï¹Æ#ëÍǦÍÅ*Îeß9þ°±¶mPû¿ð ;½rZ´ ú¿5šþz•S›ËQfž<ŠÓoë}6Z´ý°â!ó¬‘õ.èí-ïºþ ß7ÝîVUVszÎ÷Ö¾*˜ç9Ňþ¤±ÉœÃ•yõ`cJ;žT\“ÞõŸù™Ÿéô2N:æ{ýÀáPûè«lûåhÓ¿'ÿï6[Án—'¹ŸA@Gfü1€Và,À«oÈ€Bp0Ž0*VàHÑ.˜Ô÷ÓÞåî® $q2–Î OGs‚¨ ï&CvôdŸ8KÌcT2¢”ºq†»Ê‹ø æ®ke UÚß¶í3eÀÎu _­2Üϧz£4·,¡ü*'£ø¢AÝ:šðiO{ZgЮxÖéT# †sm«Í»z?rÔ‰G›™w튿èè"…sÞà~,[¥oVîÑgZ£&vvÖ­;ìZ~×Í#ñï/»¦ßð†7;ª¾d€cT‡ÈUrËDÀ䬂»õç &‡"+»ÚS5ê·þ»Å iå*§Æ“q 4ýû&¹Œ3³ÆÊö^2Ø ½B~'Mò-VW²¦]ð¬ß¶ñý ËJW³[ÿÙÏ~vwªFÚªz[—S4,*3Ü´õDï¤#sVuO²®ÆÈCÖÍ?5¦élý8¥©/¶:ì1¾ôãžõÿ®åwVyò{,J€±Œªôq†ScÅùqFÌ~:äžkÉ1ÁÜ„A¿uíß3îs¯ Æ,rÕ|dVà¨ïÞv¡Ã äd;¾LЧd¸¹Åй13­c°ÍE¦œÉvq30V0Ö‘«Þ·=˜ƒ*« ?CÊÊA“QaeÅÊŽ_»ëqEòµN§ùç¬ê„À¶žØQè’ÓæíÚ‡9¾RŸçÑפë~mÑ}CÚ°{ý†m„®X;¯u†Uæ—Ðò^g¾÷~0f°¹Y¬tÊ•>¬¯Ð_Í‘ØigéËÛL,åÛíúÛæ¶µy#{­ 6Ǧ3Ï’QtkkZ½”“lkKn™Z¯iel²`láxH ïÒ3Kö³Ýpš•Ï~ÜtúiýëwñÿM³ö˜+k‚帄g™IN5Å”^Ŧe­ˆýnˆ­³î]äŽÍ‰¼m³6(Øà0d>(tc§U;”«ŽnÒçè2O[”‡y:4™ŒÅ¤àwr½í§æ´ôÞ–ù¤û7õý¦ÛݪÊåqKe#¨8m.:¯Q?ì Úû´z¬¸½«'Õ9º68k d0¶¶mtóž6¿ù¼9ߘÝn.ͤt€(3PAGgˆ²ðV÷P¨áuB®=Q¤®›ôNôWAÈYÀ"˜ ?B°‚Éš2PÜæ î\kÇ!:mñ¯âÃÕõ¯~õ«ë«Ž“ÅË¡ÆÑc7nøƒ:`Œ>rT`LR²Û,1ÚR˜)=´3 ÃCêžzמ¿Ùç4‚R<ÖíT#}m‹¡²!Ëiò2$hÇŒæÚ‰‰Ë&þ7föëÞY¿L¹v-¿Ë”5÷î»~ú§\‘IãvŽ#B¾g8Ö1^óžÁYÕ½%—ÅAá7ám'‘¾Œ×í½Æ~På˜'Ì#W-êÙEÒŸtNJîaA³Õa”Û =~ÛæpÐeåLžz¬¢Å^r•|[·S:1‰l¦µ líîõiu§-ºÖ Œ ë¸HSÿ©GPÒ jÑtÝéÏÿ®åwÞòåúý$ÀˆÚ>~‰ž{ÊQ纡s(rqÍÜ¡ú.9ç540Ø»êt/÷95`ˆ1×ë4”ö^yqòÌPÝ@zú÷<Áî82Õ¼lÈœÚc’¼È‡ h¼Zcpý¶MïUV3Côœ*kë´¼LYéio:z<½S€KVoëvªQÒkÛ–ºÖ6[Ç¡iu¥-Úcλ‰Í¸pp¥«U¤´',NË聯_ãÈ< 0›ÎsÒÛmú‡S ôcöBóýŸeލMîrHùv»þv¹íƼ[°uâF=SëÑ6Óì÷ýÇ@Ñ­§ªçúötãÓ¤S:Æq–z §Ÿ:Y‚n\ŸÇÝÓÿŽ~醽]¤î_·ëÿošuß9[]Ñ_‡êþÚSYœ,J^­+ôOXbŸq¢ç´vÞÏ‹2¹G^KïÔÍ5å}Ú&„6.vHÎtè!ó3s1q›kT [¯2o©{Öù¾év·Š²à§.[Üú´ ˜CëR>æÕ«ŒA6Ôal5GlÇ;ú½nÞ´WÁ-q¬@kÖÇvëbfä³Û†2SA‡& æéØ„ˆE‘ !æYÈ7°xÖf«Zt¢ Î Ò²xØ,ïŒjó×YéôWfèÐ]ÏòdÀlCñjôjïÝägyWÖ¡ •ܶ=È«zÒÖ,ÚÍ0b,äTÛÐ(/ëzüS›¿¾S Ež|–Gj›ÜU¤¾ôŸ Ø·Ê[}¿-ï»–ßmá–|l'ý±½]à0QbxÐÖ‡“ã\…yNÈ0IsI/JfYT´CcVp½ õú7þ[<œgr2+þï8‘5CœUÝkRÜ[éÊ>ÏBe?›øe5ñ_¤¬Ú(§)N5É9ícN5ØöR´-Ó¡“RqÅóÈa÷,Èñ¶]bV}k™x×uï®åw]ïá  ¯™ ´s=cÿHåY¥­…üºnÞbæ›kÊ`¬Ÿ‘‹§ 8=ËX­ í‚„¹ÚuSÍ…mj*»]ÛŸÛšC˜£orÌ­:šçN@Ž -«rö7|(ç"e%×<ÎÀ–ÍEæ¯t¾M8Õ`da@{® mi—­Üªß&½“ÅíüqÒu«ú^=µu…aõ­U¥±Êxúù5.•]b•é$®(ÆovÂ:Á”®~˜BÊw˜j3e9HÆú(=¹m9J°GMrÄ#sNÜê¥Nl ëkè±}'ö­VŽa@w§?WàÌ;,•fÿ„žŠë°¼këwm=pa;œÇ~inÖÖíªëCÛvÒhµqñËç"Ž WÙÂʱF\æi-ßM æ^ãú˸ûèæ}>ì»lsۢݭ¢ÜÆ%'b·ÙÍó†ÖÍ"ù0çìÏ#§Å3®ªsÆ„ÃE Ž5‡«>§–Ffüi¾cPjw€Oäè[û¼x×PfŠÜ¬ ýö1P„ÝÈ}G”qñȯ“9ÚÁˆð߯Eµ¾cŠ<óP¤Ìø4ÏxÆ3:¥¿Ú馜jä‘ÑL;®ÀøÍ¾N]i }7)bL->ÚT«Tˆ§íCã]×u»–ßuqH¼‡“€Éå¾ú£RêÆ¿yäªëÛ1S¼µpÒ_ôGÒØÙ>Ê=&ž}G”q÷2°0r´ã†+»˜¶)õýE#ÜÛÅ¥mÊï2yWVº×¼eU§vãxü““þÄAžmÊ©FútÌ6ßÚCöÈUy,9U†›qF¶,S·ËÞ»kù]¶¼¹ÿÐÃé¶­±SßtÚ–¾:4˜ó¶Žæd¹JײƒCâÇ?þñcÉ™§ÚŒ2D&—LoÇ2È‹p >pZì/’`†Ña Ê©¼mPÎy˪]Ú dQB›4#³7åT#}ŽÐmÛfbƒi˾ÎϘ”ƒVÍQém~ÿÿuæiZÜCò»-yVŽüv8l‹~¼.š)ߺÈ&Þ}!@Ÿá(À™¦æ®t'Ü2ÁÉÖæŽ%“±òXæ¾m¥²oõõ#z4{“¹üÐÐO“.@ÏçÄ1d, ;OÊãÐ7¯cÍtÚk¬‘õÛ¸ùa˽½~ÓŸ7ÝîVU¾¾³•xÙ×¹qe‘¼÷׃ÅÁ¾Qío‘8sÏvˆcÍvÖËZr¥÷;g8¹0ÍÚE÷„ó,£Žë)¢*Ï;ï¼AÞ±ãÊ@X Y<¬ô6ñ.OãöÖH¼‰|l"U•Õ¤€ÂO/OzqS¤9^ 1d/S^uÓ7ä3”TÛ’ ¢Ž?¤ô•‘Þ"%V¥ù\ªò„°Þµü«¼‡À2Jöµq¿Þð†7ÌåX£ÿôåj9ÌûŒ™vÕ›U°ûèV·ºÕ ¹j iwoˆƒüš%Ï+­M½ÇM¤±;laUeeŒpTª6R Ò䪺åxÕwŠ]5Gm˜ìjëˆÑæ ÚúŠÓ,ŠÊ›¶O®ÊcÉU¼ÈÝ6„\ݵü¶¼ò9% ÿõ © u饗ÎeôÕú²M¼âŸåXØk¾ÊÉ®‚]³kŒ¡³B¥Ó^g>³î1·MoÈg2•¼iƒ±®ÆÂöû]ÿ}ßÚ¡êûUó™ß®åwVyò{„@„ÀþðØÏK.¹ä¸‡=ê‚ .ëˆòîw¿û8ÝÚÆd§½oš5]¬ìBÅÙšG>P¿Ôû8Ç—þ HCó¦lNñ^ºû¸ø‡Æ7ä:öÔþœ±Òrÿº¯Ùt»[UyÆåÛfümk¿Û^ÿ«ªÄstí$ö‡%¦¿pç;FÃÖp¸^ËCŽŒ¶€÷¶·½í8Aî>»¼†ùmWáè¶í¬—¯¾õüÆÐ/ë"å¤X;ÖR±(ˆ‡â÷’—¼dôèG?z.ïøy9Sr¾ð…/w›<µg9îÇ5ýcÀÄÇÄÅ ®ÉˆJl¶Iƒ`×ò»¦jK´{J€Q /“|gqa™`Lµ7ä¸Ic¤JÆÁ¸ÅXâ1vC‚1¥¿ˆiaè œ¦åy²fZüÛôÛ*ÊJ7s¬<£–Óí“Öïÿþï.¼ðµ.2ÚamØ´c =‚ŽK¦ÚewÕUWuzEÉUí›äê®å·­Û|UÐ7û_2ª/§æM‹l´{lÈÎWãÇšÈDN5Cq+ÿý2Hû œ¦±Z…¬™ÿ¶üÖ/gåkÞ9+üӋ8gÖc@µ“÷¾÷½ÞuäÈ‘µ.Ñ9ûöœM;Ö(/g7rõòË/ïND6ÔæÍUé£ór­úXÇû®åw g„@„Àá!à„Ž1æÙeúÈG>ÒÍñÙpÚEf²Ùc 8¼V°þBŸ™èlm`sòZ&”©Íß2ñ†{7ÍÚšGÍoŠŸ5ó¤m tì~>­û-šÏr¾¨8õ¶O¬ºì«šw¬:_ߦÛ]¥»ì;»flâ¶h»X6?“îWÿÛ47š”ï|??8ÖÌÏlgïЉûF>…a`\t2XØM—»ÜeÐ £è›ßüæc yñyfæÐ¯‡åš¡òÎw¾óè×~í׎-Lk3žcϘýà?x=‰UÛâ=ßãbÿšUýOÉõ(,»é-®SÑ[Ežw-¿«(sâ–À8¹j̰~Q¹Zc¡“Üf-ÂIßcœ,èT`$¹ùÍo>ø”/ !mP†I;˜Úëòy» hƒƒÞžúÔ§3†1нéMoêuhgÛºÃEp“2Uÿ°@þœç<§Ûa§Üí®¹u•{Ñxw-¿‹–3÷…À4ƾL2_ä(¸èøá~ãàYg5sÎH&rDlOW51–Î:é¦Ê¥ e¸­ïŒÇ‹êGÞž›Ãîp‡nžúŠW¼¢s\5vêSŸ½æ5¯ÙM«­+˜Ž“c‹öyó©]¿ãï½ìe/ëœÏìí÷×yã\çõ»–ßu²HÜ!!‡ƒ}Òã 8·ÖúÝÀ‰z?øƒ?xœ9–“B-FÓ¦= !ëFt›6ÐéÓ‹÷Kw› ½hYVyߦY[óè×í¦tÈy¸ÕÉFí=ÚߢyíßËæºL{n󵋟7ÝîVÅhœó~ÖƒWE7ñ,B`q©¸Hj¹ç@ @}ƒ …³‡<ä!Ý##ÍaĈ4KÀ1l8‰¤vwIϽ)†iôp(ã"†Æ™ë¶‡€öxæ™gŽúЇv‹€%4y3^:b{èéFó–JÛê/b›|ðäÝDàHóÌg>³s<ã…[ÁBÂé§Ÿ>ºÉMnÒµ}íŸ3\õ7;/¾øâU÷¯ë}×ò».‰w¿ è‡}¹j1†}öÙ Ãç¹j|²;©=!ÇnŒyÆIr¸ÿ¸)‹$›û†”еÏ#~Þóž×-€‘mN­yÕ«^Õ=¾‚#Ö:ƒEÿtmkÙ“'†ä•nhGý³Ÿýì‘£±Û4åD§SO=µ“«œÑô¹’«X½øÅ/>áqPCÒ]ôš]Ëï¢åÌ}!0‹™ÔwìÔ_ïu¯{uãÕ¬ûÇý®o“sC䪓HœVC¿®À©Ækh0žôuƒICãÌuÛCÀŽYÛÔVl"SÉ6Hp=ÌiqëŒÇýþÁ8>ÎÙfÕé³å8Uõ…/|agÓ©Å<ýËæý”šÓˆõ7sØ û8ôrÄÙTصünŠKÒ Ø}kØ[}•ã+}¹¿ë]ï:n̦~Ê)§Lu*hçÅEêž÷¼gçXÜÊöúmÈ;g úQßî4äÞÃ|ͦY³ •Í£¸Ž;½¤~;¨wö¶¤6hëå Ö~?äsßQ‡.oι¯aÓínUœWÝ.V•¯Ä³¿öwÙÃ:'<CÝßY`°p¿îÀàÄ R‚PÚžG~Úi§ Nš`åáÜ‹ýGø´¿ïúgF¡} &GŽ£mçßK_úÒ®èÚ̧?ýénQðZ׺Ö†õiµ-Š~¤» §-Š,#åe—]Öí|”J'£<àÝ#²(µØÐîxåàòò—¿¼Íö Šòq?®àŸ]Ëï Šœ(B`,ãFß!Ïwà6!W9:ڷ䪋97¸Á ÆæwÜ—îq|f,–,{Ôoß6}Þ7™Š=ÙÆ‰™3Íë_ÿú®:èdýèGG/zÑ‹:½Ê¢ØªƒÅ?²« ÒíŸbÓþ¾ªÏNrR¶Ö©†~á”D†Aú'Þ<’­­\õÆ×¾öµÇe¥o€:îÇü³kù]A‘EŒ%@&yµÁÿúì&ä*§c€ù¥`œàTÓŸ¶ùëvOá€ÓüatX¥«>‡Ãú?y`aʉo›ßÿþ÷wEåÀùö·¿½k+÷¿ÿýOØ ´ äX_ïä´µ‰SN9™›_qÅÇvÈ[˜8rtÞþÃ?üÃsü•\¥W0Ÿ¶àWaÝ2U:»–ßb“÷˜E€üµ–b-„ƒ­@‡e7g‹2·õý¸Ç@ÍzÜ8=£•áâöÝMozÓt¿%,N`Ó¬Ù…úuÛw:Y¼4«»Ó¼«µÏˆ™svÙ=çMɺIküøâŸ7Î]¾~ÓínU¬®qkœPoæb‹¶‹Uå+ñì/8ÖìQÝ3`ôÏÂó7AÏâ®`!ãö·¿ýqÞÔõÛ¤w @ñÇÚîÖŸtï®|Ïx\Æ1õSJò®äÙ|j§”½ûÝï~£O|â£÷½ï}]”” †¼g=ëY£Ç=îq'8‰-›.¥Íä¤ ÚÖº—«ÚáXwyqdýÏþìÏŽN9º› ¿3±Í£ß6aœ¬4w-¿•'À:I}‡÷¹Ïu U6F'å̳“ȵ}Ýà°8Ö‘%GéµÃº˜íûvjQÚ¶Ï|æ3,Uî:2úÒK/=â˜KÂ>cçz8Ö¬ÛaUßàœë$:©F^nq‹[tå¼îu¯;u‡ýt“ru×òÛÖg>‡Àª 0ôYœoý¸täöûU&+8ÕX”¨À±úÓtñº¶Þ-Xôkä¿=‘²®Ýµws/c¹`üªÏ»V–eòKNØAc¬'[öŽ×½îu#†ßóÏ?ÿ'±eÒt¯MRýRä\ɺeãŸt¿¾ÁÈãŠK§â8{×»Þµ›³[é/Ô´qi3› »–ßM²IZ!!»O€Ìõh%'É•\®¹½SYéÓEO©Eg²øv·»Ý §*öiŒs¾`ߢó%¬–À¦Y[óèëdÖ<ª¬¶t‹Ç6α¦ï34öšGZ˨`]‘.¿¯aÓínUœÍ¯úõ¶h»XUžÏ~øÆ6’ýæ°¥§xõOŠÖºƒOéÖIò¼óΛ+i ÒÖp£ ög6W<Ûz±òµ ¢Ê6ï‘É­²°­åœ•¯j«øÃs¤2Qp”¥EÀU+~Ø÷ù&(œyæMkžë-òÚY@¨àX¾sÏ=·Û!;!¿î_ä}hž·%¿‹”1÷„Àª Pê9,´Ê=ƒƒÇ¬;8 Õ"G{ü/™[Þò–s%mŒéO¬,Ð8Ýd×Y¡¢]¤åUßO{? 2Uù´Q»ÌøÀvC©2ãñÖ·¾uôš×¼fnYWqLzÇŸ\%Ó*8­ÆÂõP™S÷Ís½öK/lõ'mœñÑ"yÛ_+þU¿k7CÛÎ6äwÕåO|!°(¢dY;×3nÌ;v/’>çãSë¤À©ÆkžÀñcMë ç„¹Vן'¾mºÖøÙŽ¡XÕ†!ù:.‰ë ¯á椖#GOl©ÝßÊç±×¯~õ«»Í!«./\mç‡Òóš'-×Îs½5g­sØ)G7xԤʼn¶¿®«^æÉó6äw]o„@„@ à±”6±´ú¦ÓáJ/³±¹•ÛôYkB}ÇŠ>Mö­vþîwö­8ÖôI-ÿÿ¦Y×ɇm›±æQmfh‰æ±Í ³½Î\°]óÛ>ð…}ú‘|ä„ûöýÄšM·»¶nûŸçiKëÜÎCÅeCþ>nòèsÌÿC Ž5ÃýÀReôñìë #Çä®{Ð ÷¦£ªÀør£ݨ[à¨ï†¾3&1ºVPö³Ÿýl}µ³ï”›¶l¸)×PÖ"’Ú‡!–Ž|ç\Ó*Tvº{DÃ[Þò–•Sší‰H¸3²·;W§%ÊàÇpþÆ7¾qÚeÇý& uÜ7-+ûºŒ”ÚYk¥È´®ã2Øûç òÛËBþ ­! /Ù±ëuÊ!oݧÁÕc *]“d»“N>ùäújлq¦ë»:L°wý1‹ÆôöÔõ2D¦“9ÛvX™G!yDE9)'\}Ï{Þ³ò¢J³= Nÿ S- äÙ>BbÖ}œpÕs+WµzçºäªxÛI¾6Ö.ÎOËóAäwZ~ò[$c£Y;2s–[÷cä8º{U0vy Tÿä­ú}Ò»±Àœ»]”P;‡7á 4)_«ø^™Úr™—ÑGÚñvR:ÆE Äá°N›w»ÛݺàµP¥œûØÇ:¹ÊQk•Þ©m•#¸µ)§´µ˜¦¥É¾ð¡}¨«‹i×µ¿©çÖYÕoôM/yZGÀ³˜ŠŸþà5$D~‡ä+ׄ@„@„Àª°C9=¯æõâ½êª«º»‡¹}ë0á‰ýSïÆåÅšKóç¶ñyÁÇÅïŽ'°iÖt6k­~eŽ2sÛÅÞð†ÁkÇ—xØÚ4çš6ŸŸüä'GÚá¼NN’l×;ØmØ…Ú5‘a¹:üáwó !6Þ6ù« ÇšUPÜ¡8ún{ÛÛ—c»ç<†f]¡Í¢H=\:òa‡×"‚Œ`íïÈgÐ#؇y²°ÃèµMphE ‹O”‡Y±ëyÏ{Þèÿøg]º3¿šv˜{,TuGñ{þóŸßí*­ïWñ.=“60â;%gHPUå˜ìeC«(LŠ ijÿóq· âa€ô¾hXg~ÍSî M0nØ-TA?â¨ððõÕÊßebÙ.NYøó¨›vqhÂhœfRÁ¤„á¤}|cý6éÝb‡óÛHàz×»^·£¶òF¾˜G®sÞÆ¡”LmþN9z"‡Ý½­Q·ò4ëíE‰ ÊÀ™¡•ÛõÛ¤wÆæmrrí;u0†ZÄ17›ÌißûÞ÷Ž^ñŠW Þ°0-¾mùaX]_pÁÝâVåË¢Ç\ö‰U×ß npƒ‘¶Y[aEf×:EX=,{2¡²·†ñIica®:ÔÙ´â¡_·…³8Ø.ÖuCß×ß¡ùÈu!!!° äÚîp‡ãžé›Öl ¦›‘ûG§Ì‘­³‚xÙ·Ú ®æµ6¶ ³âÉï³ kkm;à¨bÍcˆŽÅöÀ6óö·¿}°³ól ã¯è?¶LÛ¶Áz}’ƒ»õvÀ guÖFŸPénÓûA´»*ß1†Ý­Æ©ºfÚ»úk Íáßtô ‡yÚ…9Íó¤;-Oùm ıfÏêž#Ë‘#GŽ„QXÅ¢Å8œ%¤ÛAŽwäïxÇq—ÏüNî{ßûžPÎA”ÇYq‡1é?ÿçÿÜ=RhÖõ›üÝ¢Ïgœq\’Œªv’S`&‹TÏ|æ3;ã]ËyÒõ»ô½E¹{Ýë^Ç9„aAAúÝßýÝvÏ-S6Êeb‚§þáT¤IÁ™Ýñ¿ýÛ¿=ºì²Ë)¤—Ÿö´ ßë3ŒÔÓ‚4-8þÖoýÖ GËÏZȳ@`‡eÊ„…DñÍ ‘ßYyÊï!pêQ­roÜ “æY@›§ êLÉ3ÁÄÈc9Ö,ÜëÑŒ­³+§[ÎAíîýIqÿ8¡üú¯ÿú\'vMŠoUßÛ‘å´600™O’©ÆO‹SÏ~ö³Go{ÛÛæÏÛt¶õ³¶Â÷÷¸ÇȤ´B-\¿ð…/\é‰ d¸SrZÃåõ¯ýÔÝòä’eõðÎw¾óX[¯üN{'Ë=—» ú$g©iA›°ãåâ‹/>açÿ,¹ªï´«ä¸>Ô.ÒOJû ò;)/ù>¶g–ßøÆÇ9´pªqry³ŽÀ)Ô˜S†Wº2ùÁ‰a‘p³›Ý¬›ÓµN9t†èYN(ÆÆ>óЧ<å)Sç ‹äm™{ìrmO÷4Vsòš4Níšfˆ7W/ÆËäc›î57Rßw½ë];מå4Ù!‹CˤMêÒ­ ˜ƒÚÌ4)ànáä/xA'ëÔËÐ@¾µ2Î}dœ×´ Üòe1Žá»Â¤¶R¿{g/òª@çÕw†œÌsù­|æ=B B 6EÀú[Ž9~sg Í­Ìi§ÖÙ†l4Ð}¹O§áè~Øô¸âvPï›fmó2MÛfèiÂÙ„&:Íܯ|å+ŸV9)®!ßÓ«Ù­Ú6k%ý!ë^ì0ÏyÎs:÷Ò;ÙllÜvξ‡M·»âm-ªsÚ3:/±™¡]ϯ¹† ³eØûØ!ÿËù/£ç>÷¹˪Rò¾08Ö,Œn7o$8í´€V€a„ùïÿý¿wjÈ`F ÚÉþä'?yôÿãœ:Qº(u  7¿ùÍ;対›çPõ¸‹Ö1Gx>á O8.­6^¬ÒÊI¸22 nS` ã•ëHÇ Êcd-¢ÖoêJ9žô¤'u+¼ÃÔ·Ÿ}èC{Œ™vEpZÒf‡pÑ6¥Õž>¡Ýò—Æ9»H›‘ø7~ã7:ãik4’¦:×'[ÅÂÈq…“¤©-kïv#Ì;±‘Vûhù¤Ì¼úÕ¯>!.ŠG[¦ƒÈï޹&Š€þd‘õ‚qƒs†>ÊÁfÖE†Y(`¬pÏ3žñŒ©÷XȰ㸂ÇÜ0–˜ /8¹¿uÌ1®ÛžúÔ§—V¿±Š“ÊŸøÄÑ‹^ô¢n¡f–óB{ÿº?3}öÙÇ=Šœ¤“p°íè6ÿ”™SM;ö­;¯›Œß8îøÛ<à#Ï—® ¼ q/ùË':ÕµCß9œ]ÿú×?ÎiX »ÐkƵ—Ò1ó7³Ó†NÚüpTá°ÚÊUÎ<&Ü“¥aÑ^Ýs¤ÕgÛô|VÎ~ÿ³(Í~\úV[¦ƒÈo?ÿù?¶‰@mÏÁ¦‚>ÃF7~Ì2œùÃøË^ö²Ñý¯ÿµÛ|0É¡Rö[GRÎ#k†™_ylßüÈÔÖ1‡Ìt‚ C^›V{Ý_ž9Ô(¯/“Æ­ö¾M}6gáÔÑ:Kšƒ“©l}ÆtœèilíÏe7•ïu§c§ÞéNw:n!J}Ú c±bV›šGm’ÎvÝë^÷Ø-Úik/NŒyÕ«^ÕmJ¡ÛõõŸcMø =›;¶‹0Ú¦yè$]I>èd½9ô¼åWζÿÑ•õ}‹zm\¾×®Ú2D~' Ë×!!!°6ì@Nôoõ2öë·¾õ­Ç9õZghUgeˆÀšK{r]âþÏÿ9ºÇœ—Ìæ(þ+¿ò+íÛ³òrØß4k':ßæ6·9®Í¨[—ÕWßv¿GŽZÿ3Gq#ÝkÝA>mkÛ­ÓM.½ôÒnhÚ Ã6Kýÿñ?º¹I«z‚Çé§Ÿ~܆Âu—c[ãßt»+æ­ŽNo-ÊæÑ6øÞ£ßÖÌEMæ^Ì9žö´§uó qí×uÚ»5[‚vnîߟ·V|y¡¾±Íeè¹nç PŒ~ìÇ~¬Û WG°ìŒãpbÁžg¨Ö‘Ï3‹Q&ìˆ2ùlðâø@ õêoßPiAçÈÑSsZ¯Óy¡@-q8©Å ¢€OúÓ»… Ʀ: „ã㪼Xè°h#ýv0Ÿ7븞±Š!ש)‹@ˆ`í òo1LÝp„`”U_¦”xßúgî8£Ú:ò¼‰8Õ“Ç”<üáï”#ÆCA»´­®j³ŠÀ€w—»Üå8om‚™àýµ_ûµnçý)GßÖ)”úß•)lÚ·þ#o¾›Ô9㟎â´e†C§?ÜínwÝä&7é®Qn ­…O;µiyG_Ù˜–®@ʤ÷R2õ |ùf07NhGÊg±ð_ÿëÝEyùV–üÛ@À"àƒüànŒÖG}S?6Iµð`\à¸gŒ7~èk&E®’ÇÆz×[Ìó{—xÉ<² uH0†p\F®’+w¾ó;™R _ÒzßûÞ×uòd¬uˆqƒ\e´±XbáÈwʵMr•LäÔ ^‚Û—ÈL“vuA‡0û”‡<¸Îu®Óýߟèu‘íðÆ7‹¾÷¿ÿý;#JéRÚ …_ú]mÁ.: Ží1¼d9fÑUýାèhäŽXŸäÈ#}‡®©¿Ì Ú 49a×iŒÚ´…MŽÈÚ¹z§ßÒ¥8Y“«œª´k2x^¹Ê¨Iv*ƒ< ÚŒUtý‡~@/=⢋.ê®;ˆüv çOl)ýS$ù¢ÿ‹‚wc99k^@&‘]e 3WÕïŒñäªwcš±ƒœvôykœ­â›3‘«í܉S~+/‹÷ÙHâd0ò½Æe0w©q@Èzc‘ñA™•Ïuô:ø2²}‘¼O»?»£—W\qEw©²ÑwÌÁ9(bG~ª;ß3db«QéhOô]:¦yý“ŽZë%µö§<µÞ!OÊã´šþf¨Uåw×âÙt»+>Ö¢ØÎÚù‡Íæ æ/lÛÆ/cŒú³ÕÖ™|[ÿ³ÒÇ}^êÝFíZ»0O`ÓÆý¦›ÃT6–ˈcÍ2ôvô^Ç)G ú?ýÓ?Ýy`‘Çf'<£Å« 1 û(K®(i“#‚–§t]ÏC©[&PÄ;9q*%Ožv‹1 zÊ Pâ¼Z¡j奻m!èîw¿{g°¤„ ÊÅ0L@XäT.e&Ô…à>ãûÜç>Ý©<Ý—‡è¶ÈË^{Uç.”*NGýñ‹]{çñÑÑ/é”Ð-£±ö¥Ík?úþu{)¡œ¾xåòCï /ìvÔš„Úª~È€èwõ[uÎ`I Ñ,ÖëOv T˜Ôëwy7hÿú§P,MÈ,vº¦&FŒšmØt~Û´ó9¶‘€þbòyÑÑqÃi3Õ÷ˉC¿¶UrÕõú³Wõ32J?Ü7)ÑNër¯ .Nv//8Åœyæ™üá PWc‘E c/¹j,–?ù•÷V¾L”¶)p°°ÐR‹;ò¦lôc©qVÙ•ƒ~Sã¹ÉžçE=rï°9ÖàÀ±äÜsÏí&˜/}éK}ÕÕ­E]Æ íÊâݲÌdð#¯_ò’—tmGœX—‘¦tImJ=h_‚6ÇÙØî"§< q¬q¹E;õ¡ê޼¶ÐÇ@¨ì&Úú‘ô´¿“ãœYg,„V˜%Wõ ÆE}¨N“ÒÎŒâÑžôUeö*絊Óù­tóÛJ@eô¥ïÒM«ë? môc2ÕøMGÖGõgc¹ñC&¿J®Öû¸ò^uÔPÌØVr¯ús_ÿwï´ï± »Æ…’íòÆ@Ì™ÇØgÜ‘÷’«•q3 2nS0Fš{Ê"Óè Æ<ã¶ñyï‚…sV‡v¼¶  *£#ÊÉ*zŸ Mš¿sta,vͲnèŒ?û€4´qú&9Ç9UßÐæÈUõàƒô½ï}ïî3ǘְÝ}9沩smÖ=êPzÊY'ò¨w×IGzò¢]t)²Áu³‚1€sWÿÄÇa–Nªï(Ÿ¼H³ÕW"¿³Ê“ßC B B`èeæítåÒ5Ût,VÛH4¯C gÚ‹ŽÚ·œÁa¶ôSkÂÙWZ]œ.벚l¦ ´ù"ûÛ|ïÓçM³f·ø©Ÿú©Î)ÞúÎËœHýZ'0?¡_Ñßè›~´·G=êQ]§6%­«®Ì¥~â'~¢³éÈ[µ'6Q›ÌÙuèƒ^5—ªùT›'ë|ä#;§ts”„ÿO`ÓíNªÒ´vÉælŽ"Ô|Æü¥Úù ûYÍ#» ÿé9:G=§Ïh ØxÙÙMÆihÆ¥6XB,C £É2ôvø^ƒÇ­o}ën ñŒD»éKHtjp›UDž#¸,¦ ”)‰¨@€qZ· ¿®úÎXÄ($Îßû½ß;Î(D R*ËÛ“p~àØ+×ÿí ÿ7ðST÷¸ÇuÞ–vdU ¼,µá‰qíž÷¼ç1áÑþ~X>kgŒ•ŒéÕ®(VþçóïþÝ¿›ØçaPéÄuõB»ÜoÕü1 Î3iцö°‡u卸)±ÕÚXiy·ˆà™˜<®)!­cM{ݤÏÊȸmåCP> ‡WåÐÏÛpùmÓÏçØFåÜhRg7­‰^ÉÕ~¿š–ÿ:}Æ8Òâãpi‘¡‚¾\^ÿõÝ¢ï[8#èóœL¢éšÐŒ›ÔøÝ8ÁÁ®¦ö1~;è`”ÞÁp@W0!”iœ¾C[°¢_œþùqX@Ê¥ÎÉ-N£í" …kN«?ÿó?ßÉ´Ú‚*2‡îvÉ%—trKtŒotš¾^ÓÖƒJôÉyä*ùÍÑU›TŽ’ãê\YÇrœ–çyk'­c͸ëûß1pŒ¶ˆ^ŽÑtý¨ú’{ÈP¯6D~Ûôó9¶‘€>õ =¨sFðNÆnãc½×¬`,á|oneüéqqàR±ÎNÌq××5CÞ¥-]³%‹œšUF=cÃ4Ý€æŒ` s:Ï6z‡9§À©¢Æ;,Õ^m0vã`óCꛎî<=¬…ƒ¹Ê±¤B0ñ¨& _ô‹eÛ–t,ŠTÛwÙoÊ^Ðg\õ }›U,Ši£CÃI'ÔÉGòÚ‚‹ö«?Në‹úNÈ#S˱fHšòk1P›Ñƪ¿³ó¡}ãø¦ó;¤L¹&B B VM€NÁù•.Û×Á¤eƒ 9¹Hp:ÞcûØÎŽâ„ˆÒcK×(Ûõ´¸És‹Ø‹8÷L‹÷°ý¶IÖl—Ú…ù Ç)ö‘rZ™¤×±_ØxFŸ77©§,¬»l\²>fí’Ô:‰@7ïèçÇ|ŠSa«M8žÀ&Û”éëÖ/9ëµ{Æ”šSV­›«ˆC[4¶\|ñÅÝš™ö ˜'°ý•ý¯âªw´a¯þZW]“÷Jàx«îлrÝX:» |ÿ[ \ß:œ ¹‘{*?)#vͽñoì¼=-ÒO ”6 hu¼5£NÀýŒkŽæýZ¡qý¿ì;¯SÆ!'ØÍh7`q¦ÒÀÊŽ? -œôÑ'V×y_†kÅCqõ*'?Cä€1ÅÓõ„<¢ Œeíý”†*‹@ Ox0âYª@PŒ[ ­ß ¢6_þŸÄ¥îiß±RNy®<ªç6íõõy‘t¥ÅÈþ‡<¤ó¢Ön‚Ó$‚ƒH[–JkÞwéèó]»*íŽ+®Ïï´#Gãô ““‹6êÀuÓ†ûÄéˆxŽCÕvÚû´#ýÏ‚ïyç×í~ä|¥?[ôƵGÚ{ÛÏêH~é—~©+ŸI’>Ûâ¡6ß~úù?hÏ­w|ZdœY䞪 ýÂxÀ1ìÐ?ÛEõº¶Þ7ÆËSŽž"eÒ¨_ZÐÓ×ûA<&Æù øk«Ò$'g²l,²k`Ҥĸ#¯ä•—±iÒØoÌie‘qqÒµãÊ¢^ð5ù/ƒŽôg­â2/É6ã¹ yÅQi©×q:6æ9Èõ˜·i Ió ÊºHºê\r6&»8[ äùUÿ¯½;f•¤Ø8míX“~šœÙ¤§ò´Ùžç]üµ«{çZÝkû¥Û`úLÏï”æ¡y­/íþgyØÜæ¶¼XêK{W½^Oô‹ãèNõlœ8Ÿk›í3ëw¬éÿÎ"Þ¶Qz姺c!@€K踹1æÿÞ:f^ï'ÏvÍàNã¬]yªïëzKwûh ÑX£ó\+¯§³¹~ã‰Æ‹×O×§Ÿ¶tŽ`}¬Þ1ùúëÓÖÝös·WœëéîÇÜtiWã°Æ«Éº{qçȶ·l W9þÏ­kw¬\óYÏgc±Æ–ënÛÊdÎ{եޥÞÿý“//VûضXÇöówØñOwM{ºIDATGõ¿ó”§qÇzãïzÞzoß:0ƹc™KcÉóð)¾Cêì±ë]ñVýÄSw­éZî¶²¬¼:/»ëx!Ï&×tlÒ¹¾®›Ž»/•ÆæR½­.ôEÐêFÇæ•϶esBO¾»>»mýq¼8&:ŽýeŸmlÛ®÷–'ð¯[áÿOé:§ØÚ9šø°¹ÔàvÙ«´DÙ%úfR'îkºHÞÉ‹)K'AõM×Nø´#6ù£×2gmÛêä^'ukÝžw‚±÷kd+¯N†ÔðOÏkhzÔÉn[ºhõÑG4’ý H×'Ÿ|r&'“ÖÓìM1w˺üš`ÑI«b(Ö:Án¥ÝÅŒòÐã´í,\;áÛÉ1à̪ÁdñL]ÊWy©^uq¶mµOÕI7#ÏòÔÉ´1P®îtÒ©uª“åµ „ãÿ7Óîóջʽç•uõ®íN]ª'MrwÊ»o&¶­]Ë!é¶n'&ë4ë¨*Ë:ºN¨–æ®XN{¿}¹“”=rêseP9VÃj½ *·â«.V—òh ¸« ÖÓoÝ.d–^uºÛØU¯ÛNyì¢wƒNdW§Z2¨®µ}ÚÉû~váÓO?=¹¸Xš3:Xüàƒö:PÜŒwÛë¼kŠ»þ¡zWÛ—Ïhÿ*‹Ú‰ò°yð¹¹Í¶W9Vžµg嵃 ÚΩKmS·{­îà½tëwlmn·~¹>µòh¬VŸZ\­_ÔvÖ÷µÝqà]9öÙò__S~Ksüÿf½¾¨¼’nëÖgUÞ=¯ŽÖÇ5†ê»Íbó½öú¬úœÊ¡4+Ï1^Ë÷ñ[À7Ë¡ÿ¯_mÆ“ÅVŸZ9Œ´+÷ѯŽ~®²oiŒTWßZ]lÿ+ÆêZ“ØŠµqEucj]-ÖêËèWÛS·êYíWcÒö™m˱ãÝÃßë.`€Ù\:YûñÇo¾½×ëóÜö^áÃÕÅú’êè£Ö×îMYÚwjË›4оØ~Ñ>´«>·Í9ëlÆRßÓ~YºµSí_=om¬P[PßTß²Þ/õº“«õÛ–&–öÙg'ÇYýmÀ;ï¼s2Ù°vð¬–Ú•ìkê‡êWߎ¥[ûÐqv¦µMµýß®åP×bc¬úº ë×kŸ¦´­ÅUžÊOísy*¦êUeѶª“t1Ê rë •gçªåû4ï1)e½Þµ^nS–bqf^ºµûÅxZ^I7‹öµ¶Q»Þq`¶wJsJ~Ö?Sýϲ²,½öŽ ÇX+ÛòZ¿Úþ0œ[gìË•MžÅ6þ=õ磯 Étô«¥™eû_é•×úêÆîÅR\¥—Eu¼ôNk7Fš¥×ø³õK³ôÚwÚNå_:ß7ìš„vH¼c"Oùé1åX~Ä}þÖ§Öÿm.õ©õ­¸}¤±UýdÇòëë“;޽Sß>%—ãÖ7~¨OnÜQß߸ªó$·»6†­O®nÜÑpJÿÙ¦ñdñ7žhœP?ÆSb\ÿÌÜí•ÇÎÿ”·Ü?uþgªáÜt×c?oëõ´ª;cLWj¬Ýù™Îu ¢rh,™Cïc“ÎË4®«¼*û¾ìÝøüÿzgõ¼ºÖ±Ô8j<رHÇ1Õ±ê\õ­˜;¶m¼YlûÆth66ï\Ru©cØö‹®Û¾±L±;´ÎŽ4ŽYïŸW–Õ£âïQÝk?« ilߣc‰;]¿­ôèÜbmSõwÔËÚ Ú‘Ú¤¶[½¸S›R;Ô£cÚ¢qþnjÙUþÝh¢˜zÞ~ÑuÙb±\-kΡ<Ûij8ÛñwM:9-Ù:µN>´£Oí¸ç¬³+†:¤ÓòP^j8ÊGù©£jp6e©c~ï½÷N]}¾mô-ø~‹ñ<—ÿ0)Ý,ëL÷-±}Êb=oum£¿Ãpýÿ§>¯>tB©F½r)ž÷:çžo[úì>é^T^IwìkÕÑö•Ó:ÛmFû¼—û¸¨ÜóʳGõjWŒ¼Í)ûÊ®ý°Ç(Ëʼ춃’êHqýuŸ¼õÙÖ/Åg鬜OÛæ±ã=-–%ü_퟉5gWc_¿ŒýjûFûÕz¿Z>ÚÇj;êSÛ·ï´dÐ0>üðÓƒÇ>ßâÛo¿}ò“pwZîÿ×6¬Ç_~нv­ö¡çS—Ö­j›#ÿSןm]¯ÛÆœv¿ÆX!×¶3Ú»míyq×.î“æEåõÐt³É$×,æøž@Mø§>§r}å(‡ö‰]åP|åqNÙWwF¿:Êsô«ÛöÁ†Eéí»´îèW{¾ž¿)åÇŽwßüûóç9ùå<·}l§)év¢¿íkÛö·Ó¶3§ž³Î®jê—Ú¿Ú·ÚvyhëQ2eŸmý&;w é¶×ÒDøwß}÷䜻Ò?ôýõø{>Žcê‡zìSgáZ mgÄ1¥}Z7¨Õ¦v²»¿£nŒPYlÛ^åVº£þmûÌz=o}¶õö퟊kx+ÝÒ+æÒýꔼnæ}ÊëÒýj¶-ÕªS§•Cñ͉­<µîz?WÞJkÛ>8>_œíŸsʯôƾßöÚNõl[¾i6Òß'ÞáX:çUn›qóµ‰5ÇÔ–Î_`W—R}×>cÊ}¢ë˜ºþ¸ôê›ë#GßÞ ±Çœ~sÄ_ÜmïÐeîöÊSc€Æ*¥ö]榻-ó²ÞL«<±|ñçߣëN»ÊbäsÎ5Íô÷yݘ®óHéF £¬ŠeÎdšÍôÇvçÖÅblý=†Ï¡uv3ÿǪwùŒ±y^•cãúÊpßc…Ú¤ân{ãx£ò«ï»_¶òß,?¯#px/uœ8/U*í´=æ.ûîì¥3g]ñur¢Ç!K~–©™Ìc©aì6]罜Eü#ÆC]HN9Ñ3ÒÛõ·Îdê7òÆ6öM÷¢òzHº‡îkÃjÊß’ûÎ.=$oÕqbrJ|cð1å³Û>Óúû¤·¹cÇ»™¾×W[àÐ}}ξ8gm¥Ð¾qýRߘ鶻}#c,Ͷ?«ŸÛÜü[ÛÐAMC—,u=´­+µçõ©SûÕâÞ·O½¨¼šn6»NœZþ›ëgºë¡y«îì³/Úî´þ>émú;ÞÍô½¾ºg±/í³ï&ym÷(‘Ú¨¾ùuèÒ7äú¨1©&—îÒ5õn³sÓ?«øKÿ,\mósÛ·=ŸÓ¾ÎYg½ŒŠsÎ6æ¬3Ò­|zc)}åÉ[žÕSƈãós-Æús÷ý±þ>ñ:f›Wë @€9Çê·Ædð91ž¶ÎYÇ?w{‡ŒÊßÜt·Ùœ—õfZåyêù±±îYæslsÊ߯tguŽrWz‡æ­÷=^ÞË”÷­³›i«ÞåtVií{´™çõ×—­ü×c÷üxÇ9Ê?^~¤´&Ö|ñÅ·£éDO·ìïvÐ @`?n‹Ù„Õ±t 9~p¼ç/ 0M I5Ýê},MVmRM·é¶ @€ @€Ø0±fSÄ냺W¿k÷Í7ßÜÞV3ý^|ñÅ£} úvž @€K.Ðí,û½ã~øávNú}ØçŸþ ;äÝÞ˜' @à$Ðo¯×§ö;ìci²êOûìê™gžÑ¯,k @€ @€«+`bÍÕ-Û ËYw¨yñÅO~ú©Ÿ«¸víšoÕ_XiH˜.»Àƒ>¸zíµ×V/½ôÒÉE¿&°Þ{ï½—=[â'@€"ðøã¯Þzë­Õ7NŽU›\ãn5R%@€ @€\k.MQ]®@;1éääå*3Ñ @€À2š¤zß}÷<–¡¨ @€Àå¸ë®»|ñãò—H  @€ @€‹¸¶ˆ(A€ @€ @€ @€ @`a&Ö,¬@„C€ @€ @€ @€ ° k–Q¢ @€ @€ @€ @€X˜€‰5 +á @€ @€ @€ @€,CÀÄše”ƒ( @€ @€ @€ @€&`bÍ D8 @€ @€ @€ @€Ë0±få  @€ @€ @€ @€… ˜X³° @€ @€ @€ @€À2L¬YF9ˆ‚ @€ @€ @€ @`a&Ö,¬@„C€ @€ @€ @€ ° k–Q¢ @€ @€ @€ @€X˜€‰5 +á @€ @€ @€ @€,CÀÄše”ƒ( @€ @€ @€ @€&`bÍ D8 @€ @€ @€ @€Ë0±få  @€ @€ @€ @€… ˜X³° @€ @€ @€ @€À2L¬YF9ˆ‚ @€ @€ @€ @`a&Ö,¬@„C€ @€ @€ @€ ° k–Q¢ @€ @€ @€ @€X˜€‰5 +á @€ @€ @€ @€,CÀÄše”ƒ( @€ @€ @€ @€&`bÍ D8 @€ @€ @€ @€Ë0±få  @€ @€ @€ @€… ˜X³° @€ @€ @€ @€À2L¬YF9ˆ‚ @€ @€ @€ @`a&Ö,¬@„C€ @€ @€ @€ ° k–Q¢ @€ @€ @€ @€X˜€‰5 +á @€ @€ @€ @€,CÀÄše”ƒ( @€ @€ @€ @€&`bÍ D8 @€ @€ @€ @€Ë0±få  @€ @€ @€ @€… ˜X³° @€ @€ @€ @€À2L¬YF9ˆ‚ @€ @€ @€ @`a&Ö,¬@„C€ @€ @€ @€ ° k–Q¢ @€ @€ @€ @€X˜€‰5 +á @€ @€ @€ @€,CÀÄše”ƒ( @€ @€ @€ @€&`bÍ D8 @€ @€ @€ @€Ë0±få  @€ @€ @€ @€… ˜X³° @€ @€ @€ @€À2L¬YF9ˆ‚ @€ @€ @€ @`aÿ¾¨xþüóÏÕ›o¾yQÉK—œ›ÀÍ›7ÏmÛ»6ü믿êWwáxŸ.µÀ7Žÿ÷߯_=ºº  @à¿ýöÛ1’‘ @€®”À…M¬ùûï¿W?ÿüó•” pQMæÑ¯^”¾t  @ઠ4™G¿zÕJU~ @€ @€ÌðSPóܬE€ @€ @€ @€ pÅL¬¹â,{ @€ @€ @€ @€óL¬™çf- @€ @€ @€ @€+.`bÍ/`Ù#@€ @€ @€ @€˜'ð¯¿o-óV¶V›ÿå—_¦}ا @€À¸víÚêúõëåðæÍ›«_ýõ mX™\»ï¾{õÐC”•7n¬~ûí·ƒ¶ae pêSë[- @€ ðßç>±æ¿“ô @€ @€ @€ @€å ø)¨å—‘  @€ @€ @€ @€.@àÿYÝÝœ­&ÝsIEND®B`‚stargz-snapshotter-0.14.3/docs/images/overview01.png000066400000000000000000017155651440204344700224210ustar00rootroot00000000000000‰PNG  IHDR[fUågAMA± üa cHRMz&€„ú€èu0ê`:˜pœºQ< pHYs"š"š¾Ýû*YiTXtXML:com.adobe.xmp 1 LÂ'Y@IDATxìÝw°Õ'ðCF(sÉ E‚Á ƒ‡uÀ6ìNXïÌÖVmÍûÏVMmín•kÿ™ÚñÖ†Úm–ñ“l‚ÉA„$²È!"‰dË·gš}zºÝ÷¾pŸ^øœªë÷^ßîÓç|:¨ÌïwÎÙèÓÏJQ @€ @€ @€ @€ƒ6ô·?  @€ @€ @€ @€•€¤7 @€ @€ @€ ÐQ@RAG  @€ @€ @€ @€Iî @€ @€ @€ @ £€¤‚Ž,6 @€ @€ @€ @€’ Ü @€ @€ @€ @€@GIYl$@€ @€ @€ @€$¸ @€ @€ @€ @€Ž’ :²ØH€ @€ @€ @€H*p @€ @€ @€ @€$td±‘ @€L=5kÖ”×^{­¬]»vêu^  @€ @€Ž’ :²ØH€ @€¦žÀW\Q¾õ­o•üT @€ @€Tà> @€ @€ @€ @€: H*èÈb# @€ @€ @€ ©À=@€ @€ @€ @€tTБÅF @€ @€ @€ @@R{€ @€ @€ @€è( © #‹ @€ @€ @€ @€€¤÷ @€ @€ @€ ÐQ@RAG  @€ @€ @€ @€Iî @€ @€ @€ @ £€¤‚Ž,6 @€ @€ @€ @€’ Ü @€ @€ @€ @€@GIYl$@€ @€ @€ @€$¸ @€ @€ @€ @€Ž’ :²ØH€ @€ @€ @€H*p @€ @€ @€ @€$td±‘ @€ @€ @€Tà @€ @€ @€ @€: H*èÈb# @€ @€ @€ ©À=@€ @€ @€ @€tTБÅF @€ @€ @€ @@R{€ @€ @€ @€è( © #‹ @€ @€ @€ @€€¤÷ @€ @€ @€ ÐQ@RAG  @€ @€ @€ @€Iî @€ @€ @€ @ £€¤‚Ž,6 @€ @€ @€ @€’ Ü @€ @€ @€ @€@GIYl$@€ @€ @€ @€$¸ @€ @€ @€ @€Ž’ :²ØH€ @€ @€ @€H*p @€ @€ @€ @€$td±‘ @€ @€ @€Tà @€ @€ @€ @€: H*èÈb# @€ @€ @€ ©À=@€ @€ @€ @€tTБÅF @€ @€ @€ @@R{€ @€ @€ @€è(°iÇ­6 @€ @€høío[>øàƒ’ŸŸ~úiõÉîo¼qÙtÓMËV[mU6Ûl³–|E€ @€A@RÁD¸JÚH€ @€øÝï~W>üðÃ’Ÿ â¥$€·ùæ›WŸü® @ ßï¿ÿ~Y¸pa¹ãŽ;ÊK/½TÖ¬YS%$™`›m¶){î¹g9ùä“ËQGU%ô»=ê'@€ @€þ H*蟭š  @€ 0jI HÐî±Ç+‹/.+V¬(«W¯®FÏœ9³pÀåˆ#Ž(»îºk•\0j'V:<õÔSåòË//<òH‡oKÉ÷yOm½õÖåÈ#ì¸ @€ 01$LŒë¤• @€F, t¦¨þøã‡UW=~“M6)m´QÉOeì’@pÙe—•«¯¾º¬]»v½ßpà å‹_übùþ÷¿_æÍ›WÍ^°ÞN6§Ÿ|òI5ûF§÷SÞ7yÿä3šï¼3ãÇà©ûsŽŒ¶Ï'çV: |ôÑGÕ¬)¿ýÇ­½ìÓv¼ï @€ @`|H*×A+ @€ôM ³L—¿råʲtéÒjäèPN–`^`ËúØÓ¦M+Ûo¿}õÉ”û[l±Eõ}t0”ºíÛ»À¢E‹Ê}÷Ý×1¡ ®å‰'ž( ,(tP™>}z½ÙOãZ Óè/[¶¬<ûì³å­·Þ*I0XòžÉý¼ÓN;•]v٥̘1cijq$yáõ×_/O>ùdyá…ªY@’`„‚m·Ý¶ì»ï¾åàƒ.Ûm·Ä‚Ãï @€ 0%$LÉË®Ó @€SI »Ûn»­üÍßüM°¾'É Á½¹sç–9sæ”<° ôeí|§Œ¾Àk¯½Ö5!$ $II°TRÁè_5޾@ÞO™eã¿øEÉ=ÞV6Ûl³j™óÏ?¿üñ%INÃ-yF.¹ä’ê܃“RgÎuÁ” /¼°š¾¸çq @€˜ þkßd¸Šú@€ @ E Aæ›nºiÔ rªŒè}ù嗫ϯýë²å–[–£Ž:ªüÁüA5º7kh+£' g– ‰ ðøãWIOÝ Ò—,SðØc•,òÁ”3Î8cØ3¼ùæ›UòM§„‚ú\™5aÍš5’ &¤ @€ ÐWI}åU9 @€ /¥Þxã¾6$¾ùóçWS‰ŸsÎ9åÌ3Ï,³fÍ2kÁ(©g‚NkÍwª>kÀ×uàÀͽ’OSRÒ·”zû$¤dº{ej$é©—„‚IhºñÆËÎ;ï\Ž8âˆq{¿l³ß  @€ @€ÀDT0‘¯ž¶ @€èA AÛ:€ÛÃî#ÚeÕªUåÒK/-‹/._|q9äCÊÆo<¢:ü÷iÓ¦U3Bt›­ KPdßñXV¬XQÍšq÷ÝwW£ÄÓ—$K$‰ ^Ç> )ÇsLÙb‹-Æc´i”’`’ħ¡–'žx¢ÜÿýeöìÙÕ½3ÔãíO€ @€ô.à¿îõneO @€zÈå‹-*?þñKF!+£#°Ã;”|ÚJÖÏèíÌ1Ë#}z5ŠÓM7­– ȲI&È ‡~x5Ê?£þÇcÉŒÝfÍèeŸñØ7m{矾<ôÐC%3¤( @€ @€@ÿ,Ð?[5 @€˜0m´QÉZöG¸gÙ„$|òÉ'Õ'ÁÞLSžO¶w+«W¯.óçÏ/‡vX ï¶¿ïÛ¶Ûn»òÝï~·|ñ‹_¬©™bÍš5U‚ÁÌ™3ËÁ\Ž?þø²Ë.»´Wä[“D ï¨ÌT0gΜrúé§[je’\WÝ @€ @€ñ' ©`ü]-"@€ 0æ[n¹e9í´ÓÊ_üÅ_¬sîí2Íx‚ׯ¼òJY¼xq¹ë®»Ê²eËÊÚµk×Ù·Ó¯¾új¹æškªÄ‚­¶ÚªÓ.¶ A`Ú´iå”SN©>C8Ì®&­@ÞEYáÐC•P3i¯²Ž @€ @€À†°üÁ†¾ÎO€ @` dƒÍ7ß¼šÁ £/¼ðÂòÃþ°|ûÛß. pw+™Ý`ÅŠÕRÝöõ=†#°hÑ¢òðÃ÷4ƒÊpêw  @€˜ê’ ¦ú ÿ @€†(0cÆŒrÎ9ç”ï|ç;eÓM»O~–Yž~úé!žÅî(Õ’oÜþŸ.^{íµjIÌZ  @€ @€£/Ðý¿Žþ9ÕH€ @€ÀØvÛmË1ÇSn¿ýöòÔSOµöæƒ>(+W®lݧ—/?þøãòÑG•?ü°‘œ¥>ùä“’Ÿ™Qa“M6©ItØb‹-Êf›mVmï¥î¡î“sf†, ‘OÚ‘O]M{Ò†º]õwM?Ó‡|ºPsžXä“’cRÒï[ÿ]mÂÿÔK]¤_©»þY÷+õ¦/ùdöŠ|ò{[Iu;³_êʶ¶R“ó.iC>ÝŒr\݇ԗOŽi3ʽ•{5?ë>×}Íò ¹–)©+m«û’¿ë6eÿ‘\ƒêŸýO§¶ô¯÷› ?gÍšU™¾ñÆŸ_—NýÎl=ôPÙ}÷ݻޗŽï÷¶Ü/¹oòþªïŸl˧¾¯ëû(÷iýŒõr¯´í¹ßÒ®Üûù½nWÎOÚÒïwj·>ä9KÛòŒÆo`;k¿´5Ï`žÕ´¹~f»Õí{ @€è. © »‘= @€è 0sæÌ2oÞ¼®I ­]»¶C Ý7%”`×»ï¾[^}õÕ’Àá“O>Y%)¬^½ºÚžú¿ð…/”$:d…½öÚ«Ì;·pÀÕßù®[ð»{Kþqº= p¾øâ‹U[^xá…òÖ[oU}L[¶Új«²õÖ[—í¶Û®ì¹çžÕ'KE$ðÕVòýöÛo_vÞyç* 6xßœ;ŽYNâ•W^)ï¼óNL -}ÜqÇËn»íVõ9µ^Kˆ Ôe´÷³Ï>[2Ú;¿ç<ù™¾¥mÛl³MÉ5OÐv¿ýö+tPÙc=ªe0pܿԹ|ùòòöÛožHºcÔVÒ¯ÌlÑéžÉuÜa‡ª¾6 ÓŸÔñÒK/U÷L]Ob´÷Þ{WËyÔ÷D‚“ÙñâÅåÎ;ï,O<ñDÕæ´q§v*YöãôÓO/‡zhÕö܇u¿ÒÇœ¯¾»îºkuÿå^ìÑÖçßå¾Î=«÷Þ{¯²ËõÌ=•{£6¯Û?ðØÉø{î¹\‡”¶ä¤7ß|³J*ÈõÚÿýÇEžÙêsÓ¾$`=þøãÕµÍ=—Y\ònË~¹¾yާOŸ^]ç<_x`õ{Þ¹‡{O5a$!*mÈûdáÂ…UÛòÜç™}ÿý÷«sæ=6{öìrì±ÇVÏ|’<Ò–±*u"Až‹çŸ¾zNŸyæ™Ê³þ7 ~þòÜåš÷Óa‡V½{óoBÚ›} @€¾€¤‚áÛ9’ @€À”H 9œn¥¬uÛoð÷I&HðþÞ{ï-×]w]ÄO·SI,Ÿ’¾öÚk«`÷qÇWÎ:ë¬*È” ÝHKu{î¹çžÏÛ“¾fIñâ‹/.i÷à’Úe—]V®¾úêŽ÷“Lñýï¿y䑃_ïï´=Añïºë®rÓM7UÁÎõvü§ 2¾þúëUÀÿÖ[o­Fï³Ï>åË_þr9餓ª`ÿÀ@÷üùóËO~ò“Ö:;ë±Ç+ù4•Ã?¼\tÑE%?;•$AüÝßý]u$h:°äúå+_)ßýîw«Œ$8,]º´\qÅ%íÍ5X’8’OÀ ì&(üÓŸþ´1¸{ì¼óÎ+\pA•Ü1°®^~O€÷¿øEù‡ø‡õÚ’ã“\pÚi§•oûÛUòB/uNô}rÔÎèý¶¤‚ôsÉ’%UbA‹†’X3ÚFy¶rïå^|ðÁËÍ7ß\=7I.h*I>È;,þ$äËó”Ĥ/}éKåÄO,»ì²K5cÀH“ òÍóüÈ#TÏI’µò.\ò<äÞî¹çª÷C‚õ_ÿú×ËñÇ_% Þ4ÿNsþ<·Ýv[¹ãŽ;ªëßôÎMûW­ZU%<ðÀÕs”$œ $à•‘µÝJF”gôm¯%A£²,XP~ùË_v ¡©ÞŒN üþûï¯ßçŸ~5ây`à»éØÛÜJ@?íI²BF²gôl?J’"Dë”T€~¾«GÞ>Ü2Â=ûtK*HŸ’L‘ù×_}yùå—?ŸM`p½M'hš2»A‚Ž Ôg¤~J|ꙚŽîöÔ›ö6%dDxfXœPó¥ßù.É*ýž”ŸÿüçU º)X™ãr?f†‚Øæ:4•~øá*¹##»‡Z’à„ŠÁÉ u= —¿  @€ 0$L…«¬ @€ú g[€µ>eF ÷2£AöOÀ+ߺìm ®Öu÷ò3 ×\sMˆþÁ~PüJbAS=ž…N£y{iC¯ûdôp’â08hØô®ëïuŸålËàNÁ÷º¾^~&˜ä‚$ÔI¹néK¾í’zÛF|÷r¾ø>ú裕A‚ÐÝJîõ$Çdé…ÌFДؑz’xàëQGU®ïVwý}®]’òi+™â=Ÿ©RÍÁ\-i’¤¶’Qþ¹¦U?–Óô§M¹ßóN¼êª«ªÙL’\0%ýÏ3û·û·Õý‘€~f0Ê{,íÈ}Ÿ¥;ònÍûl8Ï~Þ ög†Ì 1Ü„‰&—Ô—Dмs3;ÁhԻ̚’„¢:¹LbAÓ° @€,*×ÙÅV @€º$°›uß»•L9`l·’ÀY¦7ÏTô—\rɨ$ÔçLð,Æ¿þë¿®Fó×Û»ýÌq·ÜrK¹ýöÛûžPP·% þõ«$è™éõG#¡ ncî…öWûÕ‡Ô=’d…´+÷í¯ýëjùºm?ëk²Ûn»•Ýwß½m×*™"AÑŒ´JIòKfšH°¶©$šÄ:y£i¿É´½¾Þp@5D·DÜ‹yÖ“\0–¥¾¯~ö³ŸUI£•P0° èßxãÕ™!$÷åPJ¶®¼òÊê6œ„‚ú\9o’;²K·$˜ú˜^~æZ'A)Éy?FBA}ÞÌp‘™#’¬Ðmú?  @€ @àÿ H*øÿ~#@€ @ GМÎRÝJ‚€;î¸c·Ýª)æ³öxÞ½3rYþþïÿ¾u õº¡éc‚à nu f½÷º-™™að,uÝ~¦ž$aäg?J î»ï¾êÓ-¨˜QÐiKFæÇ8ýʶNÎ þ ¼fiÿPGQ÷ÚßÔ=Ÿ˜?~ωés>ûî»oõéd0°ý¹o2sÃPJFSçÓV¶Ùf›²Ï>ûô<óG[]å»<‡ùäùš;wn9ðÀ»6ý©§žª &ºt=h„;Ô QY¦`4fXijNžµ{î¹§šÍeÕªUM»­·=mÊ»,IR£Õ¾Ô3Zu%Qá•W^©ÞÿyGåš·•¼cóo@ÞM¹7zyß$)#³Œe’X[|G€ @€‰$ПÿR5‘´• @€! ÔÁŸ,Qài[I :Ótg*ò¶’w¦£OBA[0)¤‘f̘QÖκò ð&›€TFy'Ø4‚7A¥Gy¤ *gì¶àpvYÏ;£Ç›J‚ZÛm·]5z=ýL>£3z7íɨéný˜€°Ë.»”vÚ©ét#Þ§Œ0n[¶"Á¹/|á ÕuÛ{ï½ËÌ™3«„x$pšc3ª>Ë$Àë3°¹î©#>Ý’†Ú©ÖónÉï\÷¦{¤S½é_’“)ß³üÀ;ï¼Ói×j[fBHRÁqÇW%c4î8à‹,›ÐmÔw®G>m÷í€*'ů¹Nõµ:è ƒªÄ‚$µ³óÝÂ… «}9显{å9Ï’wÝu×:É5M ÏJ:IÊÉ2y^êþ6Ÿ}r®ÌšqÎ9çt½ÇR_-î¿ÿþÖûvðùêgzà5¼Ïhý÷v “PÐÖÿ<‡y·ä½”÷ÿÎ;ï\½‹òìdv<—y75•ü‘Ä‚›çS!@€ @€Þ$ôæd/ @€S^ žë².uFãfMîn%AØÓO?½ ¶·í›`w Þ~ûíÆÝ„Ë´ïguVõXN ;3d&‚7ß|³1¸—àxr§vZ™5kVÇó% Aª$4•$Ì›7¯ü³öÏÊ!‡²NP=«´%Óm'¹ SbAvõTöuP>#±?üð¦SŽx{’@Ú’$¬N°-k¶ŸrÊ)UðnðI“TÄŒŒôÏLqO/3Ô%ýɨþŒ*¸DFîŸ|:yÔÇÖ3P¤ŽN%åÖGRš‚–é‚–¹6I˜H;³oFBç“ï“T$™$g4•‡ckŸ™º•T“T„”¦’sïýY¿s}¦R‰}¿$¡(ÏGî¿%K–´2,]º´<øàƒ%÷ËôéÓ[÷É—i[î…ÌЖh’säæ9É{1÷Ež‘$ä~ËsõØcUË6äÕ-'ûdÆ‚, 1gΜÖ.$é! ©¿[Is¯çýš÷cžÇ<ã™­%÷iîíÑ.1|àª`ÚÚT’„‘뙄°$ä<°ä]óË_þòókÑôœg‰…ÜCGuTÕ¿uø @€: H*èìb+ @€)%àK‚X  ,u@/Ö•ˆI ¼-0]Ÿ€O^)ÜV2{@FÑ.^¼¸q·Ý2ÀÅ_\N>ùäŽûeôøÙgŸ]ôÿŸÿó®Ìx@ú”­ ,(_ûÚ×~õùï™"?£¡›F¼¦= j}ï{ßë8 CFÑ&ð•õ¥—^Z\H‹ÏE]Tõmð÷ýø;ýΧ©$9àŒ3Ψ> àu*;ì°Cùò—¿\N=õÔêº%˜š`ïà`w|rÍ,­ƒ{÷Þ{o•ŒÒ¶œÄþûï_¾ò•¯”ÝvÛm½ÓÇ3#“{YNc½ƒ[6ÔÔÔ›6'ð›v¿úê«Õ=Àof¤H©ƒÁ‹-jL\É~™© Ÿ$¤þ¶’`hkj§NûæþιëvtÚg2nËs2Ðåàƒ.GydIÒ@ÞM%ï¬ÌV€ûïýÞïu½MõtÛžD‚$/dŒ¶’wF®]fÈ'³­ .çw^É}•Ĩ´½[bA òžúâ¿Ø:ýîüc»%ä>Ý~ûíË—¾ô¥ræ™gVÏB¶%èñÇ/×]w]Õ×ü;‘ë2Z%†éwkšJžý$q]xá…%÷@§’ç4ÿF¤IRKrY§’Y!â‘÷rÞ'  @€tTÐÝÈ @€&½@‚WÅú£ýèó¾&—À\FOgÚûŒ¾Ïß½”Œ2Op¸—©¹¼í¶¾}‚ô_ýêW ê6%ž b’þöoÿ¶1蛾$˜àu‚}ƒK‚Þ Ö5•ŒàÍ(׌4n*1H`=Á«o¼±ãnõí{ì±Gß‚žõ‰sí2Ò8¦’„̞ДP0ð¸Œ`>ôÐC«ÏÀíõï &@ŸO]–/_Þudp®u‚¤¹Æ¢$hšd‚$SdŒ,A‘’û?÷}þ RÖÁÇiÓ¦UmË2éOSIBBf+ˆwF~·K4ëä: L*HK’ ²\ÊC=Ô|àgßÄ?ûd&‘~$c¤]yOdÆŽmܨÜc¹.¸à‚ê3pVûæ]tÄG|>[FÞQmïÜú=•1>gëLð?I±èV2£Ã׿þõ’ä†3Á$A,íÊ,™åŠ+®¨fáHp~¤¥6Œc›aÞµy>› êv$ù&I$éï-·ÜÒXg’@$Ôj~ @€ @ »€¤‚îFö @€ 0éJð4Ÿ‘–“þ£?ú£jMó¶úrÞfÛ¦’O -£Ö3z¶—’ R`UÛô͈Ý|—å:-ï“xÐTöþlôy‚\ ¶•«LL:ìÍ9Ҏ̈Ðhl«(ß%q¤ÛÈçL=žO‚{Ýú6”s×}ÓÇ$|ó›ß¬’VN§žï’8Ïà’åòiº¿²îí.“0e šJ’2KA–i*iKf)<DÓþ“mûà`s‚ÛyƈN¢LSÉ3—ÙU’h”÷G§¢¦c{Ù^àï°O"ÄïÿþïWAñ$ãt+iïþáV}ë¶ÌC=#FSRAfHûšFí×mIâKf É  êïó3ý¨¿Ïl Ï<óLÇ÷ÚÀcºýžwm¯Ò¦’S²ìE’Cz)ù÷"û&¡¤é=ž„Œ$ %y©—$ª^Îk @€Lfõ‡äLæÞê @€}HÀ.Á¨Œàÿó?ÿó® iH–ÈúÖMË dŸ:I £è{-Yž c[Ið¼iºíŒn›¢?mʈõn%³dß,+ÐTrž¶s57Ôíõ:émAÍÙ2ê:³StJ‚ê9Çûþ¹O²LEf¬˜PÐ­Ý à&© Û1Y&$ŸÁAñõg”yîöQßA¾÷g‰,`Ö5U~O8ï™ß“pÑV^zé¥*i)3¢Œv©¯]·d®än{ö·-K£dT~·Dˆô«­o™1£-ù¥>o5N<ñÄ®3:$ÀŸ™’ô03¬d9–\£6Ã,kDµ¼K{)1KÒWqÚJž»ü;  @€ @€@wIÝìA€ @€@‹@8 ö$pöýï¿üÅ_üEI@¬—’QÆ º¶•Œàêíï2~[I"CFˆw* ¨·¹Òç$ ŒFICÛç£qŽÔ‘àkL n* ~ßvÛmåÒK/­®KÖ¬Ÿ¬ÉI8í´ÓªO·å {åþÊýÞ4:¼Þ?³d¶‚¶Ñô ¨æÓV’PòÿfÏž]%ôh^´hQ5cÁhß˹¾m3L¤µ Â'`Ÿö¥$i)‰+fÊXOî­$5Ç3CA·Y ò>ÊLéÓÉ'Ÿ\;Ðö>ØÎ¦ß“‘d¦¶’„²$ ¥$‘«-™+uåýß–Ð6”óÙ— @€“]@RÁd¿ÂúG€ @  Tgúø /¼°üð‡?¬Ö ÊŒ ˆµM{¦'ø›€R|ïågÚÕ- ”¤¦4kštkÿh}ŸûãÈ#¬ †;ú?#¡(N]M%I¹¿_hHœ‰iFKg4ySIýC ø6Õ3Ù¶çÍl$™¿í¤ß©Ÿ%V&ä˜nÇ娶Y&ºÍãó~L’UÛû$ûu*¹î¹Ïº•$¬Zµªãn½$äÈyf̘ѱŽNó^Þû³D—ôo$%פ[RAGâ×Ë»¿Þ'³Yt›I$ïÿ¶ä±‘ô˱ @€˜l›N¶é @€c'€[çù$8“‘ÀõÚkIRA·©¹$Jà)ë—÷ZÒž¦ []G¦›oÝ›‘èm#p3ew¦>Ïä¶ Oи)0™ ffbÈZåcQvÞyç*˜Ñóm£¶ó]Ö9Ï'ÇwÜqÕÔè r&Y#Áº^²cѧáœ#æ FxàÃ9¼:&#È“T€g’LšJ ²¦}¦oül$™ £¥s¿6•$$x;”€oS]“m{îÇ$‡<úè£]Ÿ÷%K–”… V#ÿszM*h2Ëû.IÝ’‹rý†{íz¡Ÿ÷h§Ä¥<ÇißêÕ«›ºQmßm·ÝJ>c]ò^ì%é!3¦ä=Ú¶ÌÃà¶§ÏLî—÷Û²#÷õ; @€¦º€¤‚©~è? @€Hp¼^ó;Áž¤Ðo ˆ×p ô\rÉ%åñÇ/?øÁJÖ¿<­÷ø³ê·T³‚®ÿù?ÿ燎Êï9ÓÔ× œgäîƒ>Øñ\iÓ½÷Þ[MOž¥2jz`‰YZóçϯ¦]øÝÀßNÐ>Aî±( Â{ì±U²ÀÀQÛmçNÅUW]UÍZ×gœqF5í|fÈhà^®u[ýâ»ú^IbDŽMRAî“«›J’[’Ä‘ çààrtÒtl¶'¡ ×MY_ ÷^f+HÂÀ­·ÞÚš(“Ž,ƒý3º~¤IywäÓíý˜wI·YSÖïÙ?néu“$\uz&ñ!ùnó´o83)4µ»×íis/ý¼Góí’ë×Íf´Ï©> @€LTuÿË×Dí…v @€ 0"ų>üÑG]Õ“`T‚ΙE #]»MŸàPðÿãüòçþçUbA·ÕIÝöë×÷ &i¢SÉzæYž ^‚rJ’ RÎ=÷Ü*ðÃ*Ó¯·Þz«ÜrË-U ¾m´ì{ìQò«’ l’ 2r>K uö‡ŒOòH‚Ü_ýêW«Ù vÜqÇõ’*ƪ?úE‚y™ÿ”SN)7ÝtSÇÐ ˆÝ~ûíU@9å$$± É™žgSÒBΗ}3ò¿—5Ó·o$o·ÝvåË_þr5íx#’4Ñm´õÀóe‹ôïý¯ÿUÐ¿à‚ ª{§Ûúåë˜,¿'ùdÿý÷/I¬ÈHø¦’©ÛŸ{î¹rØa‡}>³Ão¼Q%4Í–‘º²ÖýÞŸÍTжGÓ9§Êö<ÇqÍ27ÜpCÇgµ¶¨g+ÈÒ9n$³lôšT`ýpöi_=[ASrSú–÷tÞ¿ƒK¶uÚ>x¿œc¬–`xî^ 3š¿çýŸû@!@€ @€î½/vÚ½.{ @€ 0É\Ÿ7o^ùwÿîß•¯|å+AøºÛ >üðÃåÎ;ïl îeÿ§TÚP%Að¬YÞTvÚi§rÎ9çTݦ}²=k‚?ðÀå—¿üe¹ì²ËÊwÜQ–-[ÖšP@ÖATÍ5×Ǻ$™áOþäOªY’d‡¡–Œ´ORÂûoÿ­ês[Ðs¨uO¤ý“P’eÚÊ;ï¼SÍT¥ê’DƒÌTÐVöþ,¡ ¥] KˆuÔQ=ÍòØcUË%$`?’¤‚^ö \çùª{œc{9¾SbP’šzI*Èr ùŒuéµ}ýjWÞÿS1ª_žê%@€ @`r H*˜Ü×Wï @€ŒŠ@ìçw^™;wnב©ÝuוÔNH`½—@VöK`n4?9œ™ˆl*9oöIŸG³¤Þ³N;í´Q¯{(íL ö{ßû^5;EFzg4|/ÁËÁçÈü«®ºªšV>‰"S­di‚$t NÆ)K ¤$œ„‚$Ÿ4•¼÷þ,¡ÀÒMBënÏ=œç¹Û;%ËMd¹Š$uÛwÝ3¬ûWŽíåø$Û 7y*÷IŽï–°“{¯Ó2 yg&1¬[ÙP3ôšØçÑ|ÿÇ$K>d)˜ ‘ÔÕízøž @€ãQ`èÃQÆc/´‰ @€¾ díòLuŸÀhrM%°î2bÿßøFcBE½L ¾Í6Û”C9¤kж©=ƒ·'p¾ë®»–N8¡šº~ð÷õß 'A"#ÊG«$0–™Î=÷Üjæ‡NÀÑ:W/õÄÿK_úR5Å‚ ª¥žy晲víÚjJõ^“²4Ff§Øk¯½Ê.»ìÒË©'Í>¹¦Y!Áÿ¥K—6ö+÷Qž¾ß~ûí*©`õêÕûç>ÙgŸ}ʶÛnÛ¸/þ¿@¼²Â’%KJîᦒ÷Sf+È’#™© ü^ö™½¥m‰‹¦vf{fȱm˨d¿´£S[ò|÷²¬A’†ÛÆœ¸%mî–Œ“º“•›á$=uj[ΙÙZN?ýô’_ @€è. © »‘= @€øL ŒÈ>õÔSË•W^Y¶n‚yë­·ª©ñ´i š¤‚^‚ê RÿÙŸýY5k@ÓùF{{+V¬(¿úկʳÏ>»^õ™m %ûõRb—àðœ9sÊÙgŸ]ÍPÐ)ØK]ýØgÚ´iU€í¤“N*O?ýt¹ýöÛËÂ… Ë믿^’îÔŒÃý÷ß_-é%#jŸ~´u<Ö¹ï¾ûVÏF‚ÙM÷Ä{ï½W2[AUV®\Ùuéƒ$$ªô.YE’´‘޶iÿ3KÄO<Ñx­z9c¯³Œ$© ÷L|º•¼G;ç³-#òóþi{†ÓÆn³!tkÃp¾Ï;0ŽÝJ’E.ºè¢*!«Û¾¾'@€ @€þH*è«Z  @€LJY³f•ã?¾ÜrË-%ëÄ7•ŒpÏl÷ÜsO9묳:î–¤‚Œ¢Mº)›?úè£j)…,E0VeÍš5宻qètÎ8dð»ï¾[MmžfúœOú• ^~æ“ÀY’1âpôÑG÷4;C§sŽÅ¶!“øO‚ßóçÏ/·Ýv[ Oà±í:eöŠ\ó'{=ý«sdy\ã$g´Í>¤‚$©$éæå—_nlž¥iZ¿HâN=[Áã?Þ¸ožÓ$ÏŒ¤äYé%)ª×Ä€NmIBA/IéwÓŒõlyW5•Ìœ‘ÏPKÛû —ºz© mÏ;9³Q( @€ °a$lwg%@€ 0!ìLpÿÄOl ¸×Kù¾ûî«FÀw ¾¥®a kKPÈzß«V­ª«íûÏÊð½öÚk;ŽîMÀ<³ ä“ ñC=TíŸQý <}úôjºîLÙO¦ÅÏg¢M³@ùùçŸ_2{Á5×\S®¿þú*ÞHL°<Ÿ‘$¤þ¶sôýÆ ’“%’XšJî«Å‹W‰(mKˆì°ÃÕÒížiê÷XnÏR)™­ Éyw4•6ÿ¦cnÏ=žwWãI|j*I´Y¶lY•ì0Ô<^}õÕ’O[IâRî—¦€{’ 2[A[RAÚ˜ÙŽ9昞gùøã«¢¶¾·µ;ße–‚¦I¾h*i{[û›Ž³ @€FO@RÁèYª‰ @€À”H𪞭 -h—Ñû™†|Ñ¢EåØcíh“`Ò^{íUZ;îðÙÆŒO06A¬Ðú]r¾$hëTvÛm·2{öì²ýöÛWŸâ&sÉÚó^xaeÙe—µN“žÑÎI*Øu×];’ôTÍLm÷UÇŠÇÁÆ,W¤‚$ ä^íTÒ¯»ï¾»kàÖÒôzÛ–zf+xôÑG[X?üðrÀ”LAž@fŽËÏÌæPוsäïó³þ½×öWÂÿ$˜ÃÌ‘k—eÌˬ ÝÚ’c3:9‰m%׳-›|ÚJ¦‰OÒÆa‡Vvß}÷Ê-†IÞ¨—EH›Û®Q[ýýü.³ $È›€ðpךÏs’唑 ä¹<ꨣªÀ|‚ôý(y~ržû5)I<7ÜpCÕ„o|ãÕûnðŒyO%ÐÙ]’@uÍ5×TK‰´µ;çϳûì2kÖ¬õöM`ìÄO,W\qEë(ÞÌVðWõWåK_úR9ï¼óª@Z¤ÏÏåòI)Á¹:– õc=Vþ¬NrAÖÿé?ý§’äˆÁ%ÁªŒîMÀ*õu*©#uæÓ©$HŸ ^Fæ'Èž>&°—Ãù™€Vü²¬Àààb§úFc[®Cf¸óÎ;«Ïõ×__Î8ãŒê¦-éwÚ’O¬KÿŒËrIFÈ4äM%Çd‹¶uã3 {·ÙRÚã´/ViGÚÑÊ9ÏïÿþïW£Ð›Ú²¡¶çz'© ÁÊL%?Ôû½?K*°ôÁPåÖß?ï„ÌV°dÉ’2þüÆgyý#{ß’çü ƒª‚Ü÷ß빟“,¤¤sÎ9§º¯ÓÆÔ‘‘óyÎ’ðô›ßü¦ºÿ»-’{%31äüm%û%I%÷d–`h+IÈ{! D§œrJ5BŽO >‰2wÝuר/C“þg¹Šô#‰m%ÆË–-«üN:é¤ê]’öÕŽ96ïþú“ć¸'ñ-ÿåøçŸ¾òþæ7¿YþèþhÌÞ¿mýò @€&‚€¤‚‰p•´‘ @€À8ÈèØ£>ºÛ66áË2š7ÁàÁ%õ$9!Ói·-;ã2âøÚk¯­êJ *Aú$dôj‚Íù>ŸŒDÍ9Ÿ~úé*•ƒ%»$tJ*Hà;II€È¨áᔵÌÊ'ÁüÌ V]Rw‚v_þò—«`_’ \ëgI[*¤ÿ›¿ù›*™#ý=âˆ#ª@g’’‘>$šDŒ›o¾¹ Hf[SI²@¦aï”8RÓëô &‰!ŸÁ%õçÚ' :Ë~ûíW%<ûì³CdgÆŽ€s?(#ˆef+H2Mž÷~”ÜósæÌ©ŒÖ¬YÓzм'3Ú>÷u’eòîJ"J‚öyó®hJdXqÞuI8þøã{J@IÀ>ÏK–aü.Xo~Ï;"3ä“óôÒžÁu õï\§´oÑ¢Eë¼£:Õ“ä²ÿøÇUòEx’¤•ç&ÿŽ$9#ï¬ú߀˜æß€¼Ç¿»²O®ÇÖ[oÝé4¶ @€ @€À Iƒ@üI€ @€@ošÕ =ôÐC­% —¤‚ÓO?}½éïLO öüóÏ/ÿ÷ÿþ߮ӯ'8”‘´ù ·$PÖ4}wÚ“ WF²^zé¥U o¸çi:.W^ye5‚:&gžyfëgbAÜ:Ȭg/H{3ò7³dß$"t:fp¿|Là2SÁç÷¦’ MЉ2C)IÒIRAF°+£'ħcŽ9¦Z‚dôj]·¦$Ê$ÈŸû:‰ ý*¹·2²þÔSO-§vÚf´˜;wn¸Ï,$£U’|”z»=÷½œ/÷þW¿úÕj’~Öm‰åpßAu~ @€ @`* H*˜JW[_  @€Œ²@FcrÈ!%Aån%K<ðÀ£C3ø·¿ýírøá‡÷5Ÿv&€Ûiéƒ}ÈhúL³ŸéµûY2*7£s³üC‚ùý*éOŠmÉÃ9÷ôéÓËgœQ%ô L2SÒwóojKF5ç3žKf*HRÁP¬sÿg†Œj•ÑHà8K{$±`¨ K¹Ÿó®è¥$YæßøF`êyz©?ýÈÒ,guVùÖ·¾U-ýÒËqõ>I”úÊW¾R%#ô’\T×égÚ’ä†,ßrá…V÷m§ý†º-×éþàªg§†u{ÒþXW?ê?ÄOÐ:ë÷Ú®¶F¤I&9ï¼óª¥+Ú<Ö“`a’ ò‰ÓPï»Ú{`ãí÷ps/÷’lS·}ï)ºôA/׿—}jÇN?wØa‡rÊ)§”9sæôüNI2AfPÉ{¨—’ý³ Ÿþ韖yóæUï„ÑxÎÒ÷Ã) Ðdp‚âiß6eþ‡~X2å[ .Á³?þã?®f ¸îºëÊ /¼P>øàƒ’%Úênj{”K3ªþ裮áM 9GÎùÓŸþ´Ü{ォͱ ÐetrÇi[>™u ?ÓÏwß}·êëªU«ÊêÕ««mmíùå—ËóÏ?_øÏ5\ŒO,çnšþ? M²8d‰‚¬ç~ýõ×—+VT®ÝÖ/ØŽÚ2Ž™öük_ûZ9ôÐC{ZVa`=p@¹ø³¥%´?~É,½´#.{íµWëì#uØÎ‘ü~ÐAU6YÖ¢[ßzé×HÚ2žÍýšû6ÏÈàç#÷[¤3Ò>vØaÕ3™wIž³>ú¨ãs”sæz$)$Ë4=OÚ“csž¼n½õÖrûí·—W_}µzΚžÙNõd[Þ×9wÞ•yÏd†‚ÌœÒéÝÐTG§íéWÞ¯;í´S¹å–[ªg/ÝJÞ;¹³gÏ® N8á„ê¹Ï³›g®Ó¿/µe¾ïµ¤žÚ0ÿ¦Üu×]Ÿv{ŽšÎ‘¶§ iú¥#N>ùä!'45Õo; @€¦‚Àúÿ¥j*ôZ  @€L!¸Î>ûìrà 7”·ß~ûó@Z>) ´$x–@ËpJ‚\™Òþÿð« Õ{ï½·N5õy’´tF w+UŸõµ3¢6£÷üzî¹çª€x L‚D‚u¢DΓàQ~&0•v%‘ A¹Ò22>ÁªnçóÍ7Ë7ÞØ˜Pú3½}–jÈÈä¶ _‰IP¸öÚkËwÞYðšúž}“€k”Ù—Ì0Я½öZI z`2mÊ, éc®eSÉúL/~üñÇWý»ï¾ûÊK/½ôyrAê¬]SGíXÿÌuI2A®M‚æC nS’~ðƒTË]\sÍ5U;4̧nGú•OŒ`Ýû³Ñü ®¶­á>NƒÛ:œ¿÷ÜsÏê™J²ÈSO=ÕZÅ®»îZÝS¹_§ZÉýšç|Á‚Õó]'äºçqì±ÇVK¬ŒÔ%÷pγûî»W P<òHÉ !ƒÕ¹§³tÅ™gžY=OÃ9o£²,@Þ©wß}w¹ÿþûËòåË«þ ¼¿ó¬Õ÷x~ÖÏYÚ÷T––I›c4š÷Fž‘ï}ï{Õ³ü›ßü¦šA&IPi[Ú”ç/íÉû4Ÿ<{I¢J[òÎËýZ—¼Sò^úé§«$ªúØ|Ÿ[òÎͳ0Ôô1K6$ñèž{îùÜ0‰[9OýþÏÏÚ1†uÛ㘶Ç2﫼?ó3mV @€ @`h}ö¾>Ú!ö&@€ @`" $“ÀQ–H`>Á¢í(N@z4JêÍÈÕŒÔOà'Á:¸Ÿ ànÉ,aœe XÏßéKFÞ§¤éO’2’>Ór'p¤Šôµ—’ Z’þãüeprD}|êK°+£ôÛ êýó3‰÷wW®ºêªÊeàwO°ÿ¢‹.j š××±Æ8×/²¡^Ç“ÈÓØ&Y!¦±Mß’Ü€\>éw‚‘Yæ WÏ}kû=£Ç_ýõjDrfPÈ'#×sžÌfó&1$×´×àêh:µµ½í»eË–•Ÿüä'URLÛ~™òýâÏfnØû³¤‰ ]ÒÞÌÒ‘öä^«’ç-×<÷Bî餇sO¥½õ¬"õÉys$Y¦ÓùóœåþNàýÅ_¬ÞyÆò ç>­Ÿßô7#é3“Gñ½ÞëÎÙë¶´í•W^)>úhõ3ïï$[äùÏ2y$ŸDž¼_›JÞù¹~éWœÄ‰$!äø¶’}Æ"ÈÙÖߎ@FlgdzF·•ÜO{6CÁHfñh«ßw @€ @€‘ H*© ã  @€˜4Y¾!Ë4•Lãi¸3eùPJ–UX¹reµ4DÛq™º;eâ dšöÌRÐí^IBAf*P @€ @€ãU@RÁx½2ÚE€ @€À˜ $ø¿fÍšÆóæû—^z©,_¾¼J.hÜqÀ9fÉ’%åá‡n]V¡ž"=Sˆ+[ ‰'™¥àÙgŸm툥Zy|I€ @€ŒMÇI;4ƒ @€\ Ël»í¶åÍ7ßllË‚ ÊÌ™3Ë9çœS¶ß~ûjÚú,kY òùôÓO«„ƒ$¼ÿþû%#Öÿáþ¡,\¸°±Î|±ÝvÛ•ýöۯ̘1£u?_ŽW_}µJ*X½zukc³–}f)È}§ @€ @€Æ«€ÿr1^¯Œv @€ 0æ[o½uÉ÷mI™Éફ®ª’æÍ›W9ä²óÎ;—›Ù’H%XÎìù¼ûî»­}IRÂܹs«ºZwôå„xê©§ª¥º56 {¶üB€ @€Ï’ ÆóÕÑ6 @€ÆT 3}ôÑåñÇ/üqã¹óÝsÏ=W}ê’PO¾Ël½–ÌnàòÉ'Ÿ,ÀÜ+Ú8ÞoíÚµÕ,Ë–-kmå–[nY]ï$¤( @€ @€ñ,°ñxnœ¶ @€ @`,²ôÁ1ÇSfÏž]% åÜŸ|òIÉ’CI(HÂ.»ìRÎ:묒Y”‰/d“¥K—¶&¥¤—{î¹§¥&þåÖ @€ 0%$L‰Ë¬“ @€ô"YöÝwßòýï¿ìºë®}]ë~‹-¶¨‚Ê^xa9óÌ3ËV[mÕKí3Ž’X’¥žyæ™®­´ôAW"; @€ @€ãDÀòãäBh @€ãC`óÍ7¯f+øÂ¾P~ö³Ÿ•'Ÿ|²|ðÁ%ã‘–$-l¶ÙfeÚ´iåÈ#,çž{n9è ƒÊ&›l2Òª?^{íµ*¡`õêÕ­­Ùzë­«¥vÚi§Öý|I€ @€’ ÆÃUÐ @€Æ•À¦›nZ;ì°ò—ù—媫®*÷ÜsOIÀø£>ª>üqÏË$a ‰ùLŸ>½J"8ãŒ3Êœ9sJ‚ËÊäX¹reÉ'É#MË`$iåàƒ.p€d’Éséõ„ @€LjI“úòê @€#ØvÛm«¥Î?ÿü²téÒ²hÑ¢êçŠ+Ê»ï¾[Í^PÏ`Ÿ &§l¼ñÆÕ'‰;î¸cµÌÁXæÎ[vÞyç껑´Ë±ãS ×:ÉI@ùðÃ?ŸÝ"÷E>[n¹e™={v9묳ª{a|öB« @€ @€ë H*X×Ã_ @€XO`›m¶)GqDõÉ—™© SÜ¿ùæ›å½÷Þ«șŠg‚|fΜY²ŒBl°^Å6L*]vÙ¥üéŸþiùæ7¿YV­ZUÞÿýjÆ‚ÌN{hÖ¬Yf§˜TW\g @€ @€ÀÔT05®³^ @€ 0ŠYÒ ù( d– ÷Æ@¿ @€ @€]`ã‰Þí'@€ @€ @€ @€ú# © ?®j%@€ @€ @€ @€^@RÁ„¿„:@€ @€ @€ @€ú# © ?®j%@€ @€ @€ @€^@RÁ„¿„:@€ @€ @€ @€ú# © ?®j%@€ @€ @€ @€^@RÁ„¿„:@€ @€ @€ @€ú# © ?®j%@€ @€ @€ @€^@RÁ„¿„:@€ @€ @€ @€ú# © ?®j%@€ @€ @€ @€^@RÁ„¿„:@€ @€ @€ @€ú# © ?®j%@€ @€ @€ @€^@RÁ„¿„:@€ @€ @€ @€ú# © ?®j%@€ @€ @€ @€^@RÁ„¿„:@€ @€ @€ @€ú# © ?®j%@€ @€ @€ @€^@RÁ„¿„:@€ @€ @€ @€ú# © ?®j%@€ @€ @€ @€^@RÁ„¿„:@€ @€ @€ @€ú# © ?®j%@€ @€ @€ @€^@RÁ„¿„:@€ @€ @€ @€ú# © ?®j%@€ @€ @€ @€^@RÁ„¿„:@€ @€ @€ @€ú# © ?®j%@€ @€ @€ @€^@RÁ„¿„:@€ @€ @€ @€ú# © ?®j%@€ @€ @€ @€^@RÁ„¿„:@€ @€ @€ @€ú# © ?®j%@€ @€ @€ @€^@RÁ„¿„:@€ @€ @€ @€ú# © ?®j%@€ @€ @€ @€^@RÁ„¿„:@€ @€ @€ @€ú# © ?®j%@€ @€ @€ @€^@RÁ„¿„:@€ @€ @€ @€ú# © ?®j%@€ @€ @€ @€^@RÁ„¿„:@€ @€ @€ @€ú# © ?®j%@€ @€ @€ @€^@RÁ„¿„:@€ @€ @€ @€ú# © ?®j%@€ @€ @€ @€^@RÁ„¿„:@€ @€ @€ @€ú# © ?®j%@€ @€ @€ @€^@RÁ„¿„:@€ @€ @€ @€ú# © ?®j%@€ @€ @€ @€^@RÁ„¿„:@€ @€ @€ @€ú# © ?®j%@€ @€ @€ @€^@RÁ„¿„:@€ @€ @€ @€ú# © ?®j%@€ @€ @€ @€^@RÁ„¿„:@€ @€ @€ @€ú# © ?®j%@€ @€ @€ @€^@RÁ„¿„:@€ @€ @€ @€ú# © ?®j%@€ @€ @€ @€^`Ó ß @€ @€LP^x¡¼øâ‹´õšM€ @€“MओN*›l²É:Ý’T°‡? @€ @€c'ð“Ÿü¤ü‡ÿðÆî„ÎD€ @€ZÞ~ûí2}úôuö°üÁ:þ @€ @€ @€ @€j3Ô~ @€ @€6 ÀÞ{ï]öÚk¯ ا&@€ @€©(p÷Ýw—?þ¸±ë’ i|A€ @€;‹/¾¸üå_þåØÐ™ @€ @€Àg3fÌ(ï¼óN£…åi|A€ @€ @€ @€¦¶€¤‚©}ýõž @€ @€ @€4 H*h¤ñ @€ @€ @€˜Ú’ ¦öõ×{ @€ @€ @€ Ð( © ‘Æ @€ @€ @€ @`j H*˜Ú×_ï  @€ @€ @€ @€@£€¤‚F_ @€ @€ @€ @€©- ©`j_½'@€ @€ @€ @€’ i|A€ @€ @€ @€¦¶€¤‚©}ýõž @€ @€ @€4 H*h¤ñ @€ @€ @€˜Ú’ ¦öõ×{ @€ @€ @€ Ð( © ‘Æ @€ @€ @€ @`j H*˜Ú×_ï  @€ @€ @€ @€@£€¤‚F_ @€ @€ @€ @€©- ©`j_½'@€ @€ @€ @€’ i|A€ @€ @€ @€¦¶€¤‚©}ýõž @€ @€ @€4 H*h¤ñ @€ @€ @€˜Ú›Níîë=ñ+ðÞ{ï•—_~¹|ðÁå“O>)o¼qÙzë­ËÎ;ï\¦M›6~®e @€ @€ @€LI“æRêÈdøÝï~W–,YR~ô£•×^{­äïM7Ý´ì¾ûî墋.*§žzêdꮾ @€ @€ @€ 0N&Ìò©ýñÇSFÍ"0º¿ýío˳Ï>[^yå•*¡ µ'±`ÅŠU²ÁèžMm @€ @€ @€è,0.g*x÷ÝwËš5kJ¦ÏÔï °~øá‡U¶ÜrËjÄö[lQ¶Ùf›j:øüÌÔð  @€ @€ @€ 0zã*©`õêÕeùòåeÑ¢EeéÒ¥åÅ_¬¦~OrA=KÁ&›lR¶ÝvÛ2kÖ¬²Ï>û”ýöۯ̞=»Zg~»í¶+[mµÕè騉 @€ @€ @€Laq‘TY ’Lðàƒ–o¼±¼ôÒK—$Éo½õVõÉôð7ß|s•Hpä‘G–N8¡zè¡e·Ýv+I>P @€ @€ @€ @€á lФ‚O?ý´J&¸ï¾ûÊ 7ÜPžyæ™aõäý÷ß/óçÏ/©gÞ¼yå;ßùN™3gΰêr @€ @€ @€ ð,© Ë–-+?ûÙϪÙFã‚dƒ ”µk×–ÿú_ÿkÙh£z®6íyóÍ7ËÛo¿]~÷»ßUÇmºé¦eúôéeûí·ï¹; @€ @€ @€ @€É"°Á’ ²„Á¥—^ÚšP°í¶ÛVKl¹å–eóÍ7/ üôÑGÕçƒ>(ï¾ûnI"ÁÀòÉ'Ÿ”矾üö·¿­Žø]ÛïÙÿŠ+®¨–`HRBÊ´iÓÊGQþäOþÄr mx¾#@€ @€ @€ @€I)°A’ 2ÀwÞYn¼ñÆŽ¨[o½uÙ}÷ÝË‘GYöØc²ÓN;U³$aà7Þ¨>¯½öZyâ‰'Ê«¯¾ZÍ0P'¤Â$ '©àÊ+¯,~øáçmJݯ¼òJùîw¿[¶Ùf›Ï·û… @€ @€ @€L1O*HÀåÊ•åòË/ïè›Ù N>ùärÞyç•ýöÛo½}öÙgŸÏ·e¶‚E‹•ùóç—%K–”+V”lÛd“MJ–.jIÒB§Ò´½Ó¾¶ @€ @€ @€ @€É"0ôÈû{žå î¿ÿþ²|ùòõjÚl³ÍÊ©§žZþÍ¿ù7=-7eŽ=öØ2oÞ¼òøã—_ÿú×åé§Ÿ.;ì°CÙb‹-Ö«ß @€ @€ @€ @ w1O*ÈÒ÷Ýwßz-Üh£Ên»íV.¼ðž V°ñÆ—C=´|ðÁå™gž)©K!@€ @€ @€ @€F&0æI¿ýíoË£>º^«³\Á‰'žXvÜqÇõ¾ëuC–=8ðÀ{ÝÝ~ @€ @€ @€ @€@‹ÀÆ-ßõå«wß}·¼÷Þ{ëÕÙöÝwßõ¶Û@€ @€ @€ @€l1©àÓO?-ï¼óNÇž&©`‡vèøÝdßøá‡–>ú¨diˆÌä§,á™6Ûl³²Å[TŸ åv­Y³¦¤)™Ub«­¶ª>Ã]j"u}ðÁå“O>©úëŸþ¦îô7ýVÆF`¼ßc£°îYb’OýLæÛúy¬ïÿܳªŒæ3™÷M½òøþÉ3˜Ožõô]!@€ @€ @€˜šcžT`X§’ÀV×cQV¯^]^}õÕ*x_Ÿïý÷ß_çïzûÇ\žy晲õÖ[×›Öû™€Û®»îZ¾ð…/¬÷]§ ©3ÉiGfnX±bEYµjUÕÿü`{ë æM›6­ì¼óÎe§v*Ó§O/³fÍ*Ûl³M§j{Þ¶víÚòòË/WçÉAiÿÌ™3Ëî»ï¾N ª¦m/¾øbeðöÛoWAÇm·Ý¶êof–ØsÏ=«v­s`éoåÊ•%õ¼öÚkÕï¹æéo¨MÓ×´'Ûº•´}»í¶«\ïçýüýPÿNE®I®u/mjýcµžÁܹ×úuÿ%Y$÷ô믿^«Ó·øå9Êýœë<%Áð׸¾FC=GÞ?yäÞ|ë­·ª÷CÚ^?£éOžï´;Ïaž•í·ß¾ú=7¹¦6ØÏdΙç0ýÍ3þÆoTÉy“L¾æ}“g<ÏãŒ3ª„ŸúªùI€ @€ @€˜Ý£¶£èÀ[pJÀO?ýt9þøã;}=jÛP½ë®»ÊÏþójr]q‚ŠÿáXÚF%'Pú/þÅ¿('tR]]ÇŸ Ö%¨¾|ùò²hÑ¢òÄO”矾 \v<àŸ6Æ-‰tPå3gΜ²Ç{ kö‚ŒD^¼xqù«¿ú«*è›`iÚì±Ç–ÿïÿýçýL°ùá‡.×]w]yä‘G> ×íL›Ìÿîw¿[Î=÷ÜzsÇŸ9G’ž|òÉrÓM7U?¼m*©;ÜnIÙ/ɧŸ~zùÞ÷¾·^u ÿõ_ÿuå½Þ—ÃØ†Xÿøÿ¸ì·ß~èaÃ’|L–-[VÝyÞúuÿå^ÿÕ¯~U®ºêª*Y&÷@‚ÑIÈøæ7¿YÎ<óÌcddýý÷ß_þÏÿù?U@<×çøçÿüŸ—SN9¥§säÉc=V.\XýŒS[IrÉP?üðrÌ1ÇTII¶Nëg2Nyå¹Î󘤩lk*¹ïwÛm·rÔQG•£>ºì¿ÿþSvV™&#Û  @€ @€ @€“Y`Ì“ 2ú5àò–ôï¾ûîrÖYgU#€~7š¿×I¯¼òJOÕ&Ù [€1£ÖçϟߘT€j‚x æ§ Öî[cÒ†ùxàêØÌðï|§yä‘e¨Ìô?ä}J°9ÕŒÔN‚AF.ßyçå§?ýi5r»SÛÒ¦$ÜsÏ=IÙ'#½´¼ùæ›Ëí·ßþùìꬷå¸Ì`ÐëÌ Œ~ë[ߪÊuégF°'H<š%}¾÷Þ{'TRA,ê rî¿Ü‡ý¾ÿrÎÌ’ë_—ÏsM®¹æš*àŸ{m$%÷GêJßê’sdÄ}ÎÝ­ä>˾Ið©“g²­—’g%Ç-Y²¤Üzë­åë_ÿz•ð“àûPËX=“é[îß$ÜxãÕû$ï¦n% _/½ôRõɳöµ¯}­zÿdö… @€ @€ @`ò ŒiRA8·ÜrË* ûøã¯£›€× /¼P.»ì²*@œi·ûUÍ’¶'˜Ù©$h— úßÿýß—;ôÄëTO½-¾¥K—–ýèGåÛßþv9ûì³+Óúû‘þLò 7ÜP.¹ä’® éw[p:u%X{å•W®“Ä0Ò6>>£¬ë)ÛëïÒ¶¶Ñ×õ~Cý™ë—~M”’€ufˆÈs•Ä—±ºÿ’84wîÜ*™$×¢.9f­xôÑG«þõö¡þ¬ëüI=yÇzè¡­Uæø$#\}õÕåÚk¯m½Û*J=I”øßÿûW‰9]tQÙk¯½F¼ÂÀsŽÖ3™z’„ñ‹_ü¢J xŽ^O"GfÏž]¾úÕ¯öz˜ý @€ @€ @€&°À˜'dTÿ 'œPMý?0ØÃ@3]z¦0?ÿüó«éõGÛ6Sæg逌Ö­’¥šF('°ÿÑß©äØÍ7ß¼š½!?óIâ@‚õu°<.o¾ùf•¨µã»-»0øØ¦¿sÎ̆p饗vM(¨ëˆg§’¶?øàƒUrÂà$Ž“Àof­È4ò @gÿœ?ë¼ÝÞ©îÛ25û;ìPͰ0x{Ö¼gê­’¶çž(%Aà$ˆ,X° c“ûuÿÅý°Ã+IZµjÕ:çÎýç!Ë ·$‰ä¡‡ZïÚÖSõgi‚¦’D€,wpùå——_ÿú×eð{(Çåžœ1cFuæzçL»sÞüœL“{,Iùù/ÿ忬–Éh:ÿP¶Ö3™vÅ+}îôpN㹌g‰ß˜3fd%1QBÿþý}¤…Ž;ú:Îùp¤S'$ýõð÷‚ß.÷Ôû¯~õ«‰ÏFÖ ól(Ö3ÉóÈs…XÑNhpâ÷ ÈÀ}@\Àó '¢J¬]»ÖÏï÷ ¯;ÌOË" " " " " " " " " " " " µG ÉE8q*_yå•î¿øE†Ûðâœ#\û²eËÜÅ_ìC™ãL¦mc §!¢œ†ô:6ÃQþ•¯|Å÷еmÌé±üOÿôOY=áÃ48hs/Žó-‡B θAÇç2„0ËG}h8 qrÒ FcŒÐè÷߆VDu5j”इçÄ©Šs5ILÁ¸í y°iÓ¦Œ"!è ùe—]æN?ýô,!‰ap¸ÿ ,Èè!”ã>ýéO×E  >åª4þùŸÿ9ãš2 ”c§7ë{î¹'Ãyʹ¸Ï„õ¯£ŽàœÆ(?õ!õûZÊú‡ƒŸ{IÝ Ÿž ê5Ï÷ĉ FÉ5áÐ_¿~}Ö±D¿à¹ÊeÔ_¢$Â?n<ë}ûöu—_~¹/7¼Bƒ†àdÞ¼yî‘GñÏd(~a™üqÒOž<9<¼àåb=“"æÌ™“õ<òÜ :Ô}á _ðÃä* Ï$ÏòË/¿ìkx>rEfÉ•‡¶‹€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€T/&€ çò¤I“|þÙ³gg8n %ŽCœ†?þñýp çœsŽ«œP÷8ÿc8 ‰ =xãNDöÓãAÎØ†ŽùÞ½{û¿”}øðáÞÙØµk×TÙáľâŠ+|ßûÞ÷²†ÀIúÚk¯5ZT€Ó7Ÿž{Ô¯_?wÍ5×ø0õp00`€?TÒ…†›ûöâ‹/†›=[8~ùË_Î;Þ=¼px#ð Wtåç(õ…á3ÌÁ›q’„¢,À?­áð¦W7Ã@Ä{cSïÆçºuë–6»²§CˆÑ³gOõþˆ@x–ö¤±ÆÔ?œÖ°ç\DÛÍœûgœq†ÆÂ}õ-s,÷'*p u‘{“ëþð›Â½}ಎåÞáà3ŸùŒç•¯ ¤E Á3|çwfELà·Q õaKC­XÏ$"€U«VeƒßÀë®».¯ €ƒx&QÎ:ë,·zõj7bĈ¬ü´AD@D@D@D@D@D@D@D@D@D@D@D 6 dz„›ð9æïÀ£Ç1ÃÄ„VœÔôÅqÎì8!qpá 'J7œº8æqfÒƒšPã…ÎRí82Ÿ|òÉŒÃá³{÷îŒm]Á‰ÈÐ7ÜpC^ç}’¸‡ï’%KêzÇ[Yèµ>a„¼‚KËg6=Æ×­[—Í‚ì>ú¨Õ Âc³Lïpz±‰!4˜tïÞÝGηWú2¢ êÏÏO.‡{¾ëhLýãü OàèFÄràÀÿ,ç;|N{Dqã÷€È¹ê…‰R`éq˜3d¿+iŒúÀ1ˆ¨+6,Ç"^`(ʈ¾Ö˜gñÏöíÛ3ŠÁ=å·PZ£ ÔŸ†Ô¡´çP:Ê#ð·îçM\6¢ÐÓ÷ë_ÿºÃ~ÜqÇå-NÈW^yÅýà?p?ýéO½ÐGYzpàÀ,\a,XÕ"+a°Á†> ž…ÆP œƒ!’ ±ËŠ+ü0$á~œëôØ'JC ±ÑÍ„†øeÓ¦MáDc­1Ï$õV<ƒ¡ñ íÛ·¯æ7ÃkÖ²ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ@ÔUT`EnÕª•ûâ¿è®½öZß;žõú §aöøÃºÛo¿Ý; ?øàƒú«êý¹zÃâí·ßnôµá<>|xAâ'ÅIxúÐ(7ÎÞ¸c3L“´Œ¨!EÜ8Ñbš…Æ_¾|yF¶8Å»téâ{úã¸nÎÖÐúG”†¾ˆßïD(D Â3ÎP(qã§žzj|sݺ‰ê6üuã‹ÄEñt¹Ö©:tH¿pέ[·æ:4ÕöÆ>“ܳ“N:)ëúx†=ìÚµ+U9”HD@D@D@D@D@D@D@D@D@D@D@D ù¨Qø ÓNùý×u—\r‰ë›ÞíõŽÉùóç»ÿøÿp/½ô’Û¿}‡Tí~˜­[·Î*?¢‚ƒfm/dߎ;úaYßËÕ+šr'…¿Os„qã<ÅÀoݺuîñǟʇԧ^vïÞ=k_sÛÐÐú‡c|ذa‰Q6¸<¿iŒûÄ'[¶lÉHNÝå¹à¹ŒaR6nܘµ¡H¯^½²¶²Ç}’Šß¦Æˆ ŠñLrü¶"Œ‰Û{ï½ç{챂Dñ<´." " " " " " " " " " " "Pû*FTjœhôª½úê«Ýw¿û]7uêT/.ÀaǾ\†“™žë?ÿùÏÝÃ?œâ<×qÕ¶§n’ßëÇiÚÃñ;`À׳gÏgÃ=B<@¸öÐIãöìÙfå—á?GV¢”`‡å‘GÉfàp³´ùË_2’â4:thÎ:Az†ax‹¸Qï –#ž¢‚$±çmŒÈ©Ï$eµ|âå†çsÏ=çî¼óN/ªAd 8ìnàñeXÇ IHñéÓ§»óÏ?ßÍ™3Ç÷f&L:N:ÁI†“Œž·Œc~ã7f…üN:¦·áL§—3!ÊC*×ŶRÌ“ …ž‹È;wv‡ª;”ëá¾>|ØwÜquÛë[@(±mÛ¶¬d¹œ¸Y Sl௾újVH}«ƒW^yeƒ£,¤8}E&)Eý£n1¬Y³2ê0ç"òSß¾}óò þ,Z´(+ BòÎe1 þ»auþÝwßuL 5†Î ¯¸ñì6&¢†•/žo¡ëð9í´Ó|=‹t¨ÿ³gÏv›7ovgu–þ„!GˆƒˆD&" " " " " " " " " " " " )*°Û‚S­]»vnÚ´i¾·8Ã0íܹ3§§;N2ëa^ÉŽ1œ‘ï¼óŽ2`"œ|lÇɉˆ€ífìãÚ+ÙLT°råÊŒb9rÄ-_¾Ü;73väXá>âh^¿~}F ê„ 5Ú8S‰nŠ7È÷ØcugŸ}¶ÞÐØóTâñ8Øá4Uý#êCŸ>}ü aõaG>Qõãâà ð|#@"ÊF.ãÞrIÆv"œ4ÆÈ?) Œ#*hL™ÂcáÀöÒK/u¿ùÍo²ÊdÏÁwÜážþy/Ð ò\‰ÀP ±QX-‹€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€TŠ„(O<ñDwñÅ»SO=Õýþ÷¿÷=Ëq2â‹Î÷{î¹Çõë×ÏuïÞ=¾»¬ë”—Pì ×€C{Íš5~LsD„§7v($(kaprœÇ80_|ñÅŒëàº}ôQ¿žÐù g,NÚ'Ÿ|2ËJþ8?þø|Y¤ÚG4…'žx"kˆ„\ÃE]”*ŸjJ„sž¨Ô?ôMYÿƒÐcþÞ{ïÍ@ÆóºdÉ?ìI.6ˆ… fE)!ý¨Q£C ä2œþˆZâF=ã¹KŠ~OÛuò‹U’O1Ž‘êÀ‘ß ¸ñÛDd&ž½áÇ»ñãÇ{1ÃÒe$ž·ÖE@D@D@D@D@D@D@D@D@D@D@D@ª—@Õˆ @L/õöíÛ»ÏþónìØ±îW¿ú•wŠÆwæ”Æyù/ÿò/Æ›2ãÙãø¦6"0Œ@¥¬/}éK>ÊÇsÏ=çÅ4~øabñàõòË/ûß©þýû»3Ï<Ó9ÒGš@t#h>ªÒ;DÈs†7øêW¿ê~ò“Ÿ8œ×8CÉMdzd#D(§Q6¢*<ûì³îé§Ÿ.‹ƒ³)¯Ÿé—]v™ûÑ~ä‡v°sæžÈDh¸ð ½°âœ›„ŠÇñýÌ3ϸ ØausÈ pn6Æpb3ŒÄƒ>˜M¼øâ‹¶©"çD$˜?¾ä* ‚DLõÙ±Çëzöì鮺êª,‡s}ÇÆ÷ãÅ‘:sæÌø.ï`FPÀ=©Ã9¼wï^wß}÷% ÊQÿºŽÓ=~²ò¬po„†£‡vÜÈc̘1ñÍYë#¿úze×—G©÷SÆÕ«W»‡zÈ…èUŽHgeZÃéà‚S¦Lñ’´Ç&¥£>Ñâá‡Î ÷޳{ôèÑn„ I‡Vå6zøSÿ’"dÐsŸÐüM]ÿpäGö /¼Á1  pV›˜ÃeÄ#‘P71Ä@}†øˆº7~/ˆA=­ôç*^öb®óÊýúõó<ñ›µmÛ6/"ˆŸ‹ßT„}ÎB&" " " " " " " " " " " "PÛª^T€ó‘0ûôºGe¹Œò̘1#+œ8Nξ}ûº/}éK®[·nå*^IÎKuzÆ37ÃÞkÆÁ;>øÀ­€)4œDi`êÑ£‡wzã€.†Ó—H8²×¬YžÒ÷¶îÒ¥‹»âŠ+¼H%cg¯àü}þùç³êŒ T¶údzŠ襗^ÊžPƒúÁÐX®¡Ècüøñ©îÏQ ’ŒaàDÏûænü–)åüóÏ÷âš¹sçºÇÜ‹ BÁË;wîtÏ>û¬û¾ÐܱéúE@D@D@D@D@D@D@D@D@D@D@D æ T½¨€;DOc¥qÃI†sº†ãÖLq£×þ 7ÜPs‚z•36;!ÔCÃAüùÏÞ÷*Ÿ8q¢eO/hœÇ‡r8v¹Wˆ¸_Ý»w÷Âä'…­óN»L…µk×z‘Gü©S§Nu]»vïªÚuîÅ–-[‡ÿÀÁ~ýõ×—­þe`À€®C‡Þ9B&rÀâÅ‹½˜„í }°lÙ²0‰¯+‰FŒ‘±=× ¿ D¼ Ž!4 ߢgHTRq~˜¢X0<Q`â¿c@Ö­[—yÖD@D@D@D@D@D@D@D@D@D@D@D@j’@¶'¾Ê.'!Žiœ‘qɈó1­‘>näCºPÃY¹~ýú¬Ã8ÌÁƒgí«ö ˆ-Z”q8»Eш€áHf(3œß8ŽI‡ØaA±{¸wï^?$ç ó 2ÄuÖYáæª_6GüBèµß¦MïÔïkÊuÄ" spÿý÷gœÖ"œsÎ9~8“ 6¸={öd¤±{–öÙ&Ê¢+D«g{ëÖ­Z#̳V–c ì¹úê«Ý­·Þš!Èà÷ûBÄ‘¤¡%j…®CD@D@D@D@D@D@D@D@D@D@D@DÀ¹£ªèŸd8ðqb§µ$‡6é¸#2M~·ÿþ¬¤8ué‰Ï¼Ö í®]»2.‹ë´Pö;þº‚˜‘E‹-J"(à4 1'#>©Ç;ÎæiÓ¦yACRùªuÏE8…]Žâ“O>¹ìõÉØ±cÝÑGmEósĈqÞzë-ß,X±ŸœØi‡>°ƒ9_¯^½lµnNÝ`H1²lü&öë×ÏüñY;€ Ö‘‰€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€Ô6&õlãhÇéÌæ,Ãè)»téÒĬp$2v|C€ÐªU«¬¤”“òjGÙâÆy:$N¼†âe(Õ:Žì#GŽddOfÆ_'Ä|9Ì"F06|ܸôˆÇiZkƽÀa7D R¢˜õèD¯HbOBL@]_¾|yÆ%˜H¥ÐHˆ’ŽAÄðÆo¸Õ«WgœG+#pÌ1Çøaþ¶å£%~ãà'¨mM**Ø·oŸ»ãŽ;^œxIC‚›žñ .t³gÏÎ: ç#=²»víšµ/iƒ9+ãûpÎîØ±#¾¹ÞuÄIaÁ-¿BE8X¹ÖU«VÕ{îr%€a¼G3÷èÍ7ßt<òˆ[³fgÉ}ÇAMïpœ’8þ 呿É“h>úhV¯}zì80c(†È{|Ý@IDAT4yVKîÎà¸Y4‰By—¢þQ>†@ˆucÞ¼yÞÙÿöÛogìF0zôèÄg+#alÅ"#$ zÿ̘1#KË¢jWyƸï 5žÓø} /êØ‰'žØÐluœˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ@•øXS•ÓzŒ#ÀáþüóÏ{‡.!Ð  'øíiËsøðaÇxë¿ùÍo¼ƒ:~ÎdzÏ>;už”‰0üq£Üôšž-„áú¡>+eýãÞ>Ü}ÖkàëÖ­KšPÆW_±³öS¯:uêä /½ôRÆþ?üÐG;a;¿GIÜ2ȳBC4Ã50ôJ!õ5O¶ ÞEyˆöÀïN·nÝüµñÌ¥5 /ÖÂu!(àw[&" " " " " " " " " " " "PÛšLT`ÎIp²ÌXÜwÞy§›u?aÂwÊ)§xGo‹-¼ƒ'sÜ!‡C5½fW¬Xážzê)ï ß"ˆ„UŸ8qb|WÎuŽIr&rN¢¬\¹Ò¥@÷ÐpHâD¤tØ3ÜÊ€s—}zYëÏ7Bž‘#Gº$G<*ÏBœ>}ú4)‚„FË–-Ër’ólÝ~ûínëÖ­îüóÏ÷NÒ:ßù ’ÃüñüV°í+_ùJÙî”ë¿þ뿼 Á׸€gˆç,Ÿq ·|ðÁ¬d;tèÐzóÈ:PD@D@D@D@D@D@D@D@D@D@D@D@ªŽ@¦‡¼„ÅÇwbáàÜ´i“ŸpÊ1‹p&ãô²줳ñÜéeMhtwIÆyÚµk箼òJïèOJ“´ÍD8ãã„ã˜ûÉO~â>÷¹Ïyç6åÂQ˘õ8ý ë?jÔ¨ŒÔä×½{w׳gO·~ýúŒSâÈÆ‰Š£'<× „ì£w1NN†]˜9s¦ÄãVÈ ×Ì×\sMìÙ³'Ë¡Ÿ¯¨\;\éMoz3s@#Îå¤È–žú²hÑ"l›ÍáL¯u¢j”ãØcõõ4‘šO©Ó#Ð@„Ñ-r 󌅛Y³f¹–-[–½þ™ÀcîܹYâ›°Ì,“öÔSOõ“ø¾4ë0AHBÔ‘Ç{Ì?gáqGŽq¿ÿýï½#(D`8žMê6¢«£üF0ñÛ@=gˆ"Àšß+ØnÛ¶Í 2$õ)ï0Gÿ-B4@½aø2D{à7ˆã(+¿A°CôCä ~x^ãF}åY.·!&àwÃDIˆ ^xá/0@pÂ5ò›É5"ìâº<èù¼ñÆY|øåwê‚ .ðÑeÊ}}:¿ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ@é 4™¨‘½öéÑ3/t–']&N0œ[LiŒü齎³ùâ‹/Î:!Mˆ8–1ÄãÑ 8'á–-[üæ‡QAÜpæ! œ:Îð¸“^Ä8/™ê3ò"ìû9çœãž{î¹TÇÔ—g©öãx´¡ è%mÆvz›#<€÷˜‰e ÑÏ:ËÌ“Œ´„™§§9N^îÎиq<ÔR÷zõêÕ/*€=û‰”AüJ­ˆ('C2ä2zÑy'xcºyà 7¸_ÿú×îõ×_Oü-‚¡ÿ™bÊ¥ÜF@°±}ûöŒ¢ žàwŽ©c‰3Ï<ÓM:µÃ”VD@D@D@D@D@D@D@D@D@D@D@D Š 4™¨F8¤gü¾ûîsô‚¥çy’3¾Pž8ïp8âè:í´Ó<Þ½‰ˆXÀi£à,Ïå@ÄJ(u†2`Œxz7b–wß¾}ý8UTª!ÆX±b…ûå/™vŸë 74=͉XSÇ-éYfnë„ç§G8ë ƒ3Ò„†(åÑGõ‘Î;L{n†ð˜b.S¶j0ž¹Ë.»ÌíÞ½Û×ixbMQÿš ¾yòÉ'söî' Ï6åi¬!@bh’¿ÿû¿w÷Üs[ºt©ÿ-Š×±†œ‡ßêù Aƒ¼È©!yó„Rgu–{ê©§ü5"Êiˆq]mÛ¶uôÛ V‰€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€4M**À!رcGïÌ#ZÁœ9s|O`ÂÑãÀÇ™œÖpjÞG×)§œâ.ºè"?ÎwÚãs¥£×û7¾ñ ÷À¸… ú!rõš·ëÜ8áþ€‰48–q&¶lÙÒ9Ò÷¢ÎWB®_}õÕîôÓOwO?ý´Ÿoyò’|À†|M¨'ÊaÆ>zûs œ`‚C§l#,{¯^½ÜðáÃ=kþ1s^¢áyÒäOƒCöÁÌ ©N†€àú9}_ÄL ™3óÞ{ïu3fÌȈlAÙ9'=͉Vœ`•^úÅ2Xq/‰fQJ+æ}‚'ôk¯½Ö3yæ™gÜÚµkëêsSÖ¿\Ìx¦/½ôRM!½„g ÑN\8’+¯B¶ãl?÷ÜsÝøñ㽈ʶmÛ¼è‡rðûc¿CäKYxæ˜3QGtëÖÍ 0À Y¨{…X1ïuÒyyþ.¹äÿ-^¼Ø?Ã3aB.~GˆÒ`/锟ß!&~‡ˆ!1AYm¨&´ÇÓF{m`´›Ê*‹À¾}ûÜm·Ýæ;/Ò6Kûä·¿ýmß>L»¬LD@D |þ.r$5,v ÊL/|Thô@§'5s{ü“Çéˆç(Ê4œàMa8Ü<è{Íã >pà€w*⨳²àX,Ô¸6†àŸ$s®'%"œ§8þs ©À?Sœéôæçzq§T`åDÄÀ9q(ã<„g¡yX^Ìy[²d‰ûîw¿ëŶò!ŒøÖ·¾•ºç¶Îatë­·ú¡Âí”yÊ”)îÆo 7×Ìr±ï`xä©ÔårÕ¿ø ¢L[¶lñQBâC4P¿¿ùÍozÇü¸R¬£‚¥,°áÃùÎ}ॕgß!æ­[·v:uòËÅ(G)îuR¹`Í5qü¦ñ[Ëuò»Âï×…p†9ìùý•‰€ˆ€ˆ€ˆ€4wÝu—»ûî»ÝôéÓÝu×]×|.¼ŒWzóÍ7»[n¹Å—€å›nº©Œ¥Ñ©E@D@D öÐF„]:8Ò.Нöw†TVÛWeÝo†Íæ}ß…Ùw¾óßY?†LD@D tðáÆðÕá# ­¢¼E8Ô™*É,@±{I#`âÅ¥P£·|cY¡ÄDQ,CüAxuD¡ñ‚†ÓŸyc Gî!C²D8By¬U+ö}‚ \~˜ÊUÿâ÷ •0¢”¸ €²òì1ÄISuÈù†4)EYJq¯“Ê S†0ày’‰€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ@­ SÍOúS=ØÚ¯{÷îíþýßÿ½(C*×:?]Ÿˆ€ˆ€@à(ab —5¡ããÆpÅp#¤HŠƒ”}²ê&À‹=¢”¸‰‚¡:’î}<­ÖE@D@D@D@D@D@D@D@D@D N€ˆDH6Aû7lØà£‡ÛâÇi]D@D@Dào**RÁߊ¥¥j#ÀËáôCÃáS˜!kŒk¿}ûö¬l;ŠDÖI´¡¤:cëÖ­nݺuYç!jÀøñã³¶kƒˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ@ù0œ&QG‰@J´_"c6¹ǽ§m™!âF»¤LD@D@D ‰ ÒqRªzðböá‡f¤âE—˃6ÊñO>Þ|óÍŒüYA°Ð³gϬíÚP=:cΜ9JaJÏH‡\¿~ýªçbTRh–/_îfÍšå{ûìcóÑF/¼ðB׺u늻ú¶mÛúá„F—át1:ªµjÕJQp+în©@" " •J@¢‚J½3UV.ƃ'D=/f¡}ðÁîÕW_u“'Ov¤)Ô JxöÙgÝÆ3'/~ƒÎØ®•ê!ÀýÝ¿¿[¸paV¡‰r1nÜ8÷ñêÅ'Ÿ|²£'ú'>ñ ?ljQÄ„ÉÚ³gÛ¶m›#ØñáAA¯^½ÜUW]åǾ ÷i¹züéOr[·nõ¢‘x©Q ?^cšÅÁh]D@D@D@D@D@D@D@D@D@D@D@D@š˜€DM ¼VO‡( M›6îºë®sÿû¿ÿë6oÞœ±À®›(6lð“m+dŽ¡gÏžîꫯvcÇŽ-äP¥­0ˆH^~ùe‡¸ 4êÃdŒ=:ܬe( ¢¤þáð“µUѱ‰ŽTt~9ꨣu^ò¤-Œ¶Q–9ù­“°œ‡6±†y1–<™’Œó3é‡~èwÓcŸkk칓ÎÕ˜mD³5V—²~üã÷Sc" ¤á/;eà~q¯rÕ†ñ5¶ÜGÊjlãù5vÝê)åâžS&˜X]mhþõ]'‘…¹FÎ "SwÓš•›úO+3íý©ûiϯt" " ' QAã*‡¿àebðàÁîë_ÿºûÝï~ç6nÜè8å4n0^Â-?C ,U/^:ä^{íµ¬‹à…ràÀ®mÛ¶Yû´AD@D@D@D@D@D@D@D@ŠEG'í—û÷ï÷QS÷íÛç‡e¥í §éI'ä:wîìÛ©Xf[Z(ÎW¢·ÒF¾»vírt Šs‡ìqÇç:vìè§V­Z¹Ö­[{gt!×·{÷n·}ûv–ò1dlË–-½³™ë  o¿ý¶Û²eK]¶k×®~â‰*›ïÚ8ׂÓ#O®Ñ !ÃÙâ|Ž×ɹr9¡q4¿ûî»~â^ÀŠs‘ç8ñÄ=ø°Ìðº,ÓÖvîÜé9qÏqúSžN:åa/×Ì„3k0`@]Ô]ØZÝ¡ü­·Þòe&oÒv‹†víÒ¥‹Ÿpœ7ƨ/p¡þáwïÞ½žׂ˜€ZíÛ·wD¦žÒŽžK‘TŽ|×ùþûï;Ø­\¹ÒQ×`Á=èÑ£‡;å”Süùò F”›úÇñÜgÊme¦¾ÚýÌ—OR¹µMD@D i ¤ÿ¯Û´åÒÙª”/¤}ûöußúÖ·Ü+¯¼â‡C`8^ÚÀÔŒõ]ù $àå–—D ¯@ïu^ÌdÕM€a^VùøÄ§vZ¸YË" " " " " " " " "P48ªqô¯^½ÚÍ;×½þúëç)Žâ¸ÑFÙ§Owúé§»áÇ{Gt}½åÉkÇŽnÁ‚nñâÅÞ¡jâù³Nû'ë3Î8Ãw¶ÁÉšÖaþÄO¸gŸ}Ö‹hSýÇüG7qâDïTÆL¤P†¬¥<´ÉÅ ÇúE]ä¯g4yÄ !ÈÈ+×uàT¿í¶Ûâ‡úõîÝ»»oûÛ^ð& <´õN8®)§E(ÓÚ2⇠&¸O~ò“~ˆ\ÖÓ8£)ÿœ9sêÊöÙg»¯~õ«Þ¹myÇç¿ýío=;®.·Þz«1b„çˆsÖ¬Y¾ '(°°|\vÙe¾]¡G>цŸã”ß´i“?ײe˼!©žr‚ÚÏ/¸àßžŽà åºNÚôy>Ò˜û^#×ò¹Ï}Î]rÉ%‰B˜Ñþ £W_}Õ EÂã­\”™¶à³Î:Ë l»æ" " •G@¢‚Ê»'5Q"Ô˜çwž›4i’éá}ëÖ­þ%‘—j^y‰°Y^Bx1câ…ù„Nð/è¼xÑk•eC^ºjf ^÷’—Ú~ýúùyê÷ɘ1cܨQ£jðªuI" " " " " " " " å&€ƒœvJ¥8Û‰Ïèè`ÕªU~8Ö«®ºÊ‹ r è•#vÆŒ¾W¹õìÏw¢ ÌŸ?ßá4ÆÁ:uêTï€OÓ¹ŠŽ\ÖÆÊ¹ÅOû+½ç~øa·fÍš:GzRˆ p×]wy‘Å”)S|ÏzÚéB#D¹aÚ¤e:Ñ;=4Ú‰lðä“Oúh¦\GãÚQ¬X±Â;Ï'OžìˆòPŸÁ8tjsŸÂõ¤ã9—¥-eÄÑN}¸ï¾û¼X$ßý¥žýÏÿü2pî¹çúù…´qãȧ=óÌ3>âDRÃmD3 -"„iÓ¦y ê;gÒuÂë©§žòÏIÒ½AØ@ä«{a9…P—r¬[·®.ºE˜Æ–)óã?îÞxã wÍ5×øh¹DvŒæ" " å! QAy¸7›³òâÛ¿?qѼ„ñBÂË/’¼ˆò’ÁK8á¯PþÊBt5PÍìBŽ êE4‹#u€ûOØ2>ê{Ñmf¸t¹" " " " " " " " E"@ö;ï¼Ó;=‰ªjF;&^hŸ¤ç;í–´_": Mç1=®é?}útï ¶cmNÈþßÿþ÷~bÙ '=lÈŸ60Ú¾+à¬åæ¸fù…^ð!⯻î:/^H±ÀÎEžDÅYO¯´äA'0® '0ç!—²àØåš¯½öÚ¬aI9žè¢t3':ìˆ0ãã‚ÊÅœ;4Ùô_¾|y]žK9i†mÆ”‘sQ^BçÛùq¸?øàƒ®C‡nüøñþÜaþ¥X¦Ìô¼à|HÎA-<u0™cœe®¶W_}µ¯iʆˆ§üK/½ä¯ßŽ¡ÝÜqnØp?‰hÀ}ä¼8òò“Ÿ80E¨w…yΜ9Ó=öØcž;ÇRg¹'äÏ~æ¹"DÐÁðöÛo÷‘ ¬Ž‘Ç#ràY£š†¼Büüç?÷Q(`%¨<TÞ=©éñ¢Ó8z´¦AèâüK'!Õ˜d" " " " " " " " "Pj8úyäßËǨs"j2N<`pzÒ“žØô¦Ç9ϱ8´%ààŽûpÄÒ³<àÐ%ü?ywíÚÕO8QÉ›žìäMTÖlÇ-ZäE „†§l…=ø ;oe ç&,Î}®›aj€apHc8ÞàÔSOõm·¡˜g?Ãp<Žk 1C˜°±¡÷Ê!n m¿†= óÜà͵"`îë8Ðq0s/`æV˜ÁœëkŠH·¯½öšçÆýÇÉN»f¯^½<ÛöíÛ{ ì‰dÀ½µ^ü°}î¹çÜ™gžé‡%ÈåŒ7n‡8eN4\ƒÕSî×È0 ?L]BäGêÒÂ… =ŠÆ=÷ÜãÓ<8Qìaç‹Ï© ÝaQ{ölï„§·u’SG=ép€›áôÅIO(zœÀœ/n¤¿ÿþû½§ª šaBq¬Ó#=­!*Àpm矾¯qAx~œóô„‡‡ pDãœFï„`€Éì¿ÿû¿ÑLT@þW\q…w²[š|s¢à¬îÒ¥‹?ÎòáÇû{–“<(Ã¥Ž;Ö÷€GÐ`½Ù ³O/w DJ(¥!*À`‹ƒÿSŸú” ¨ GùwÜᇞ0a÷™{Š#žkÏgˆ5¨«&ž ¾! zâБO9˜ˆ '¢(p_¨G8êýÔ£´F´ +7b¢\pÁu‚êˆ ™#üà~„ÂêÒg>óÿŒÅY@@At†ð¸´åU:¦! QAÓpÖYD@D@D@D@D@D@D@D@D@D@ÊD§îüùó3œþôª'$==Ès9zqˆ^zé¥>’Zœ×q'2Žu±»víª >8çœs¼`!ÞK?D€cýÓŸþ´?Ž}Œžà8–»E½öqDb8¡‰Ž@¾8ããC½ÝêÑb3à8?÷Üs³D…œ?MÚvíÚyG5Nfå„ô¯Ï¸¦É“'û^ð8£1Ø#èÀwX×—_CöÃvŸÿüç½£?tð[~ôÈÿìg?ë¾ÿýï{G¹mG˜rÑEå¬k¤#2ÁO<‘QO‡|ík_óâ€$A Çíá /ôÇ=ôÐC~h¶#d8ï¼ó|M*+iâf‚¢E\sÍ5>JEÈ–ºÈ!nˆ xÖÀŒgåòË/w'NL¼?\¬xÎnADáÀòÑ\D@D üŽ*T(Å‹û0ñ¡Ã’HôðÎ%(Kƒãûþá|Ôz凯0äo‚öáx&J@>AåA„ëåO/x3üôú¶^ù¶=ßœ^þôL¿þúë}Ïþ$Aß»wo_NœÄfô§‡»‰ l{±ç\'Ñ ¸iv~Dñ( û÷ï/ˆ‘åUè¶ wpã7úPþùœô„ù'm˜!„EÈun"H0ô@8ìbÄ,¹a^&±h8ú‰`Ñ(´ù–©Dbøä'?™(H:võêÕ~¸%fäÈ‘^¤Ö±ø±Dâ¸ä’K¼ø€çÅÊO§uò¨ ¼üuvÀA¾jÕª §?ÎvÔ…„…§7xÒPsçÎu{öì©»É8ÌééÖˆš@÷0 =¾×¬YS7¶}š¼pÐÓ3|ذa¾÷z¾cpì“.d€èâý÷߯ ŸïørìC£ÐYOŠB„ -7âÄ}úôñC ä˶ãÆËˆ[„'¡°%žÇÌ™33î7uh„ .ŸS>̃á  qïNÁ†©ÓæZƩϳATˆ|¢”øñDEE&I›Ã,0 IÚkŸ_ë" " ¥% QAiù*w2ÀÑÉÐaoí=zø! 4Æ,~? ùŽc·ÿþõÀ§ £Gv ‡½ð­×z¸=×r—.]üP i¹ô€;qß{bœÐ¹ÊRªí0BqGS•—:Ó¯_¿ AC¾kä^„âÒ2¬ÅŸÿüçÄÃpü¯_¿>ƒ=Ñ$Ž=öØÄô¹62´}3/¹ÎiiÂ9|¯¼òJǼã9£Ñ^á½Ê—e&rE¼>æ;FûD@D@šŽÀÇšîT:“ˆ€ˆ@5à£å4s›LI]ß>KÏõÚ²c Âí,‡iÃóØö´sË+)}Ò¶0=ûã–k®íñããë¹B¸åÚndz?L“´œ+¥­o¿…ѳt6§ ¶lóp›—´ÍÒ[æ¶œ´m2(&ô¾¿å;wî\P/ì\åA¨@ïóЙڳgOw 'ä:$çvœÖô†íÀõ·oî0|Ëñ^ÿ¤…U!=Ûóåߨ}Ü3â¡SçsØ~ûðÞ6öœ¹Ž/”-u ~ ¢k÷ŠŸ‡¡':”±‘ ¢‰°~Å‹¯#” ùpÎB„)ݺus;vÌ*{ü<á:×DĈðÚˆ˜fh‘0-‹€ˆ€T.‰ *÷Þ¨d" Í”A¼€Ûĺm³9ûâÛíãÊöÕwKŸÛ±ö—kN:öÙ~;Î>8ãÛMeÎvû€&­å.[Z¶…ÛYÆìx޵4l³í¶Ì>TõvÎ0-Ë–Žý¤ g?jtKcûY·åøœ}—tMlǬ,,³ÍÒÛ¼±û-ò—‰€ˆ€ˆ€ˆ€ˆ€ˆ€T?µq'9ß´=¨óÀéF@ m¼'}¾ãÃ}8ƒé•η²9‘ Tæ—f|‡FdÚ]šÚp|ã'ê÷ °=r䈟[û "‘r”¯Pqç>ÇsmÖþÏoïÞ½u÷Ýömß¾Ý=ù䓾mŶÕ7瘰¾ÓfÇ3@TŠø½NÊ+Mšøq\÷Éîû‰Tмâyk]D@D 2HTP÷A¥¨¼óâÏdNmæ¶lûHßfë–‡­Ç±&>¤X&/ÿñ9VL–>ižëx¶s^›“·¥µrUÉ-©èbÚ‡”Í+º°T8>8ó h\a¢áÃæ¶lëñyÚý|ð3™¸²˜H!œçÛž´ü’ޝ ì*Šˆ€ˆ€ˆ€ˆ€ˆ€Ô,œä椷‹$"ߊµ$§Ë–-3Æ´/äˆø¦µòÒû»^æ…œ‹´ö [èqÅJOû‘¸Î­[·ºåË—û9ë‡öûH“Ï*µÝ…¶€BŒë_ <˜cÜcêS<ïÆä?–ç€6ÅШ˅2ײˆ€ˆ@e¨ ²î‡J#"PD¼(óÑa/Í,órËIJ­“ζ1O:ÎÒ’ÎwTÒ|Ð1áð7ËL¤±mcËlÓ$­—ò¿ˆx••”Œ€=Ÿ<å2>¸ÐÀdB[fÎtôÑGû†ÛO£Û,mgÎv&–4|X‡bÎÉnCˆ@¾&HÓXZÛÆœt2L´ãð­ÚqÇç¿·Âm YNŠ‚Ð˜¼ Ïw e§-‰ö¢ZûæãžÐ«~þüù~Ú¸q£oC³konó¤zjßü eACÛ¶m]»víJêàGB»jh ­Qku6¼>-‹€ˆ@s#ð··“ævåº^Š&ÀK(ÎøÐ™oÎ †)):ÿqì³nã£Ìþñíæüg?ëä+¨}ü®ØïE©®Ö„ ¡èÀ¶…ö‡iL €8ÉÖ™›PÁ„ 4D±l„øv>î-M˜®T׬|E@D@D@D@D@D ’DØ´ñ£cßñ|¬½ª!×jí^vì1Çã¿ûjÍ9 ³;v¸ßüæ7nÑ¢EþÜ®™! ˆ$Á7/߬LáõïٳǓûZ·îÝ»»6mÚ4XñcǺV­Z•URÇÔôÄÊ\D@D ÉHTÐd¨u"h>Bç?/÷qqÛÌ韴Ÿô„¥3‡sÖ™Ba€ío7ùÈD@D R ðÁôÑÝÐòÒÀb¢˜è€F¨p›m§L|;ë4ØÐè¤YOj¬kè5é8(ª|/…öî»ï囌¼‚‡FÞ m—zçw|ÇË邏Nò¢[¯•ù[o½åî¹ç·xñâ:Aß®:urƒ òÎtBèÓã=üÖüÕ¯~åfÏží>øàƒZÁᯃot®3´I“&¹‹/¾ØÁ¦’ç ^ö÷Þ{/KpSÉ× ²‰€ˆ€ä' QA~>Ú+Íš^áœ"& ˆ 8†—z›BQ€‰lNš¸8«LD@D 0º, ãQ6Ô'õq&H°e"$­Ó›„ãh¬³È&D°9 ,ÛºÍ-}CË­ãD@D@D@D@D@D $Ç?Îûb½[·n%*à›¬!yÓÆÆ±¡ Ç:ßhµd\çŒ3ÜÂ… }'"® a=ê§M›æzöìé¿s]3iÃÈár®cªa;ÃfÄóIà Tâµ´lÙ2+šâîµLD@D 6HTP÷QW!õ01/r¡P€uö…ÛYÆ1eb€#GŽ8& „sØ~Ž‘( ÞÛ¡" "P±'˜Ø‹F¶BÍD ˆ„â¶1±}–ƶÛ&4ˆ‹Âíˆl½Ð2*½ˆ€ˆ€ˆ€ˆ€ˆ@ó"€¨ î˜?pà€ˆÙXIyïÝ»·®÷}!ùï߿߷Áñ]fV-‘ Â2[ÙsÍq”¯\¹Ò (, B‚+®¸ÂõéÓ'C0`û›Ã ß¹¡Q'h«­t#¢D<Ñ(ª¡ì•ÎVåJ!ùªRJ¥rˆ€ä%ÀK:Âäš[„œü>ìç&`ßf‚Ä/B„¢Š 1 â‚Ä&@ ×“‰X&2½TL`À<ß„¡Vz±ÂViE@D@D@D@D 9°ï¾Ìù½uëV‡ºcÇŽY½Ã aÅ÷ ùÓÃÜÚÒÖ­[çöíÛçCùó ’Ö^ýu_¦0}ûöí³áþr-Ã2ü¶¢}Ò®¿¾2íØ±#CP@úáÇ»víÚeäY_>µ¶Ÿ{}â‰':„VOwîÜé…&8í+Ùøž§ì{öì©«<´ Pö°®äºêÇKˆ‹¶‹€ˆ@y HTP^þ:»Ô°H&@K,€ÃAáÐln¢ Ø>Öéq*J'Àÿ@&Æ]Lk4Ü!2 ϦpÝølëôPÊ%< !„}Ìiü+¤0m™•ND@D@D@D@D i ð^Ã3mhØ®]»|où“O>Ùüñ© D{ß,ˆ›í[gi×®]ݪU«|ç2"ìûòåË}§1Úû,Xà°–gl¯^½¼ÐÚ¶UÊéÛ»+ù:U6h®$*h®w^×Ý$ì%7.0Ás^ ÙÏKŽæˆln›sœLD@D@DÀùö?4 ühü¢Ñ¡ÍÃe¶µhÑÂ7Ü!B0B(80ám£ñÇÓ”CiD@D@D@D@D@š–À¨Q£ÜŠ+êDœý•W^qôS}ïóô¸ÆAJÛݸqã\ëÖ­ë.€uD8E­‡ù¢E‹Ü!CܰaÃêuÿñt¤ß°aCݰ¢|»Œ?Þ‹ øî¨4£WzX.‹ˆJ{h},‚óM\i#ÍgäMïwœîµÚ>zê©§ºùóç×9æ©OÏ<óŒëß¿¿ëܹsªÿù–rß™gž™QvÎõòË/»¡C‡ú²Ó) ɸ¯ÜÓ_ÿú×nýúõŠTIÛD@D dþ简©"P B‘¢„ËlCaŒ21Ë&`Î6!¼t×¢º¶î¥Ê(" "мÐ Ãÿg&‘Ög4’!8@d`–Ðkˆ¹‰+˜ØÀ†d°uòab½¾¶úʤý" " " " " …9r¤›3gŽÿÀ‰á ž9s¦wú÷ìÙ3ÃIng ÝŽì³gÏvÏ?ÿ¼ïqÝ»wï QÁàÁƒcÈÓÖ‡!0xä‘Güûÿ Aƒ¼¸Ùò ç¤_¹r¥{ðÁýyl=ÓqÒ†âÛW s¾‡BQL]À&!.4 ç:Q#B[½zµÃ¡Î÷VR¨|¾áp8ÿö·¿uk×®Íp<›#̯Z—‚è´à £~P÷&Mšä£bÄñk…íÎðß¾DhŠ(tˆÚqèСº²/]ºÔ=õÔSîòË/wD£ˆß[¢VÝ€ûÊðññkÓºˆ€ˆ@ùHTP>ö:sÀ±Ñ€ âËìçeßÄÌM,`ÛL8 —  ¼É*’ˆ€ˆ€@€÷D˜ò #4ÒÐN4´±nsD?0‘‰âë4åêÅ‘¯Ú'" " " " "L'6NYœýôŠÆpÚ>ýôÓ~ÈÉ“'»Ž;zg7B`ë0„ðàÅ_to¾ù¦ß†c4Þ9ˆôçœsŽ[³fw|Ûþ%K–øÈS§NõŽbzèó=À~;ã ôÑGÝÎ;ë¢ð=€  {÷îY=ú“¯®é·¶k×ÎEžyîܹ>Ô=½êáÍ÷”uª"¬?ßC‚ 8âL& ¶lÙ2ß«eòF´!Vxçw¼`áñÇ÷÷Ïœí>Aýẩ/TÂ# ¾Ü{n¡>õ©Oy>ð%-ß”´AÃV8éù~E¤±xñb·cÇwÛm·ùúwèe™8q¢¿¯´“›=ñľÞÑÃ"\pßìð\=üðÃþ™ä:íù`8ßZ‹ ÍE@D š HTPÍwOe/ˆ/%| 0™` ¾ÌK‚^zxYeÎÄ6[GPPË/®AUbO€ÆpÞ~ûm?åÃrôÑG× hPApNl#*D¡Ø ¾,áA>ÊÚ'" " " " ÙFŒáN9å߃‡¦Ù‚ |oðöíÛ».]ºøwñýû÷»Ý»w»½{÷Ö9¾IߪU«ÄñáqšÓÓžaø.0‡(B†5hÛ¶­ïÅMOnÚ&wíÚå¾8ŽÍ±Nþ8féí‚sUªÑûkA Á·†XãŽ;îðC6  •è8ˆÿíßþÍ 0À§C„«­[·Ö‰)`pÿý÷{V„ËGàCîCK0‘|`‰ãœ|kÑN;í4ÏáÙgŸõmÒV—¨§ð$’A‡üÄ÷#`CÝCx€XÑŠûÈ£Ô¢·pàµ×^sD(°ûC}¿ûî»ýv"‚ ¼GlBYy6Ø!:9ýôÓ}=Bl>>þˆ€ˆ€”•€Deů““/¯¼h0…ⶳ·€p2ñ/¡ìE§˜åR^" " " "H#> J=4:ÔÄÌm¢!†žNˆ hXc²e 0—‰€ˆ€ˆ€ˆ€‰¡È£ö£¨qÉE<u vQCÝÝ]fÊEqî]ÔuØE/i.z‘sÑ‹œ‹¼Ï.òä©Ê¦±èÙ}ñÅûvÂE‹ù¹9lq¼Å€)Ép„ç’‡íE]äÛçDÃ, F°ŽI´W""`Â1œËpªöë×Ï}úÓŸöŽùJŽ^†š^éÛ¶móâ:taIBk¸ »vDˆëOÛ,÷NðÉÅ>ˆâ@ïvœÒXS8Ë­ÜM1§®M›6Í3#úÂãËLiá3ø¶l*FœïK_ú’»óÎ;=cVV¢~0Ų¹1Å5×\ã~ö³ŸÅ“h]D@D HTP7AE¨Ÿ/•&@  XGy‰@5&¢^D™l™} ÔÏY)D@D@D@*ƒ FôÜ`¢çO’™ð‘ èÉd¢–it#2S(8°u¶5UãRÒ5h›ˆ€ˆ€ˆ€Tè,ìžnØÎ­Xᢿ]Ô½ÖE/j è-  rÜEqÉëÖ͹hlqu9w®sgâ½»(Ž}U\n­’!®»î:ÿMojœÿ´š¸ ~ýˆwyǦçü¹çžë&L˜à#‹ÅÓ±Ž(øÚk¯õÒ—_~ÙG" ]’¶Ì\†±0‚")L™2%ª2£*Õ©`_¯/ ¾+âçJ›ÇÈ‘#½¨Ç7₤ë$V", \ åw†‰@pö®§ÅYMtŽáاžzª.Išïšxšøz]fÁB:‡ çÃòR?Ãõ<§Ö.Лl á*ëôxy´è6EDàåÃÄÌY·m4¸çzñO_ ¥ê! '3Éh ²h4Â!>`¢qÉ„48™È€9 t¶Nc¢o’Èj›ˆ€ˆ€ˆ@³ @x|„¯¾êÜŒÎÍ›ç¢Æ)5Be_>á» µW¹µk‹Â–{áÞ'Ovîœs> .Hé,Î>‰¶‹aûo¸á·lÙ2ß+~k†ŸöEÚ%q~âÄä]˜Þø8ć âúӛº¾÷cŽÁñ=jÔ(îýõH„Bï}„ 8ÝÉÇ/ùó¾Î»9!á ß·o_ÿ.^Èu2TžHôBVÊ=hÐ ß3=m”w "˜ÈCÏ÷áõù&¨Ï8öª«®òQ^xá_„&. /œÆD%`È‚¸±ísŸûœCœ0kÖ,/ÂàxÚ…á#¾W¸8ÇÇŒã…Ó aÛ¿/h¦ü !—ÏHC3÷Nƒöü‹}L˜Êï5¾ß`ŠÃëJcð›:uªS RYµj•ZÀõ[]¢>’Ÿ‰ àÀ9ˆèÀ¹«°/Ÿ5„M¾üØÇ³BÄ‚™3gú¡Æ‚ç‹rS^&¾UŽäÌ(òÏ$÷#ZÏ ufˆê» þˆ€ˆ€””ÀßEÿtÞ‚KzNeÞL ðR L4Àœ„n2Á€…rbðc2¦%ÀGI|²—ûøv{±·y|?%·mašp»í·mIél_}sò2‹/ÛºÍ-Í‹µÝò³y®·…lÓ²\ß:ç¶4IéÃýF/L—f[˜Þ–Ãã8‡©ÑãûI¦µý#hü®ÓCC&¢›#8`}4â™ÐÀæ4ìÐdÿš¦´:‹ˆ@S¸ë®»ü˜·Ó§O÷½8›âœÍý7ß|³»å–[<–oºé¦æŽD×/å'@÷Ý»‹œxQ oy?ê 1%‹fQ\oy›?Õ@V1h‡ÜÝsz‚ÓNiÎpœÙ¼óîÛPã›§?NU~•÷h¢ŠñÞÃçscŒ¶SÊH| }O§Œˆ*h¿E(Àdí2iËED%T?í¼´¯p}8¸qtçjo±ü9>8“a…óŸ^ëíÛ·÷¢îIh8§­Í˜kNsŒ?ß3ˆê+çkÈ1a9ajláÀ÷Ušó†yØ2í&ð¥>‘'âC|Ï• ÎÊŽÏ7oìuæË›{I$ Úù9õ‹º€{—ătø Ë,_¹´OD@D “‘™xÂøŸN»`h  sѲü•/s&@@À ëL¼èðRhâp™—s, ¦ˆÀG¡Êø(ग़AæLl³É¶…ÏLaZKgÛlÝò·õpÎ>ÎËËœƒ Öyñç…žå0-“ËLVVÒ²Ýòµ}–?ûÈßÔÊ|`ñ1Dz;Îò¥~„Ûm9LǶ¤í¦ˆfö!DZLfIëì³4ñ¹íc;¿{\ƽ°9>üÌl9œÛ2iâËá=†“ý¶’Öî9i8މqŒm¶Ýæùö“†c)?üv³spÏØgiÂy¸L&ÎCYmÝæäÍ2÷‚s0±Î=¡>°l×A¾ë,Ûöøºí³9û-;Û쾆ûíæá²?±þˆ@3 À³Â»SÒØ±ü†™À€ÆT&zº0§ÁŠÿ¤aâ7•ßV~3˜ó»!ª#}«Dƒ~;÷Ë_:÷À.ònçˆxðƒ|íàÆ;ë,½Tñ¡Yœü•K£Ø»n£2Éq0ïÅ:uòSŽ$ÞÌ{9SC2âHhŒ‘Gc8r<ßL}úô©·(|w¶CHÀTˆ5ä˜0Ú: -gx|¸L»¢¦b[c¯3_yøV$ G!Vè}*$o¥h‰ Æ­Y…“È„¡p'Ê”½(&™#`nêÒf N_3ÌaÍÇ/óÌÙfë¶Ÿ9Ï Ï Ë8ãÍQ¦![·¼pÎðqćËÌYoã8T¾0áì —qú›H€í,ÛþpÝÒÖkàÏÊJIØNv,Ϫ-s.&Ø<#Ø6òAÁ±˜=s¶ßæäOþ2¨ÔmƘeŠÿ3h¸$¬%B›Xçwœ'üoâ7Á‰ø–‰€ˆ€ˆ€ˆ@ň¾…Ü¢EÎÝzëGÎÿè]¿¨}ïºW^qnËç¾þu箼ÒEÝÔQÎõ4ÊLD@D@D@D@ŠM@¢‚b­¡ü¬',NQ[ÆqBX)–-•-Óô2¨$8<˜p^Ø2N?Ì”lÇÉÃ?LgÇ™pÀö™ƒÄæ8ãq–0Çqœ}·=ê‰ÀÄvƸ1bD]Êay7ËæàOËgnA†qéÒ¥þ¼8°Ï8㌴‡§J‡Sô­·Þòã¶qmLÅvø×Ò9pb3Æ…ž+¶¨_­ŸƒçÀžÓT•4G"¢àð|ðœp?xþF#uæfÄàm–™Lx@¾„ƒZ½zµÛ‰nx6[IhFŽa?iùjëlc™|L¸`ƒpnû˜[ƒÙoé-‚–e"Д¨s¬¸Ü»'éN—RçHljTaÅóÄD„‘|ÆÐ>üžØ}2dˆ6lX¾Cü>DüF0™ÐÀþ³Îv[ĠÃq¿mD\  ý϶tˆ˜øßΊâËñuÒÛ±”M&%@=âù`ÚBO¼Àxf¨ÃD×aBp`ËDṋÿßæã™–‰€ˆ€ˆ€ˆ@IDïÃnÙ2çn¹¥ô‚»€(Ú§ûñ]ôòãÜg>ã"%¦íÑ\D@D@D@D@*Ž€DwKJS P<@´8!èYf¢={öxñë8[q8ÈD ¡Ì©Ïç9ÿÃå¤m¶çÇâÜÇ9‹Í Ìq8˜X \¶4& $£~ÓÛ›zOœ Ši\K—.]¼cÒÎQÌüÉKçHO´©X1T=pqH—bŒ;ê¶Î‘î¾W2+œ£”‰ñù C^ ö³z•4ä¢þ¿ÛÿxæüÏ7Ñ-‡b[FLÈÄ1ü>’s&¤Y'-“LòïÝR#@IDAT .1tÓ:Æ+ŒÿéD2à÷“‰ÈüŽG70áÄ<-Š€ˆ€ˆ€4œÀ¶mÎýð‡.êPÚñ",øÏÿtÑ8ƒÎ]x¡‹@â)´." " " " A@¢‚Џ Å-Dè4°eÄD —#NT&ÄïD/ê‘X\þµ–ŽXœX8ÅmŽ€íL& °}¶ G þ˜Ûd=¸mÝáœeò)¥‘?"‚b Â2ë!ü˵ĊáŠ=äAHšÎɽÜÜXñ{Ì„¨¥1fQØ{„Ͱlóø2ë L `ÛlÇr¸ÌºL¨C;vìðSHƒ÷  4`b¸‘Pl`#ðüËD@D@D@D "rþò—ÎÍ›ç"EnªCŠšˆ¡þû¿ëÖ͹‘#é=PÔì•™ˆ€ˆ€ˆ€ˆ€ƒ€DÅ X¦è0.2Ë8«Ba€-3·´ÌÉ[&" "P}pÆ2ž¾!†¨€wÞI˜›ÁÖmŸ­3¼Û1ü¿hÜÚPl`¢ƒpβ­“Vï7 ¹KÕw uÃÞoÃÒSW 0@h@ælãÝÄD‹,“Vï'!=-‹€ˆ€ˆ€x¯¾êÜ“O: ùY6³2 ,ˆ¢5ÉD@D@D@D@D ÒHTPiw$GyGL£¼õd™! ß¾{÷nßÈÊœñáih—Õ>‹ L Î- éL`Ëñu°Ÿž~¿¸öë’®PD@ŠI€ÿ7L [Sˆ!0Áï9L0×Y61"˜à לshx†BîJå§åþóÌdÆ» GÄ:uò‚P/M‰à€‰÷&™ˆ€ˆ€ˆ@3%ðþûÎÝ}·s PNû¿ÿsîþû;ë,çZ·vQ²r–Fç,zCÍBRþ Ö[ÏÔi4G,@(XLW™h i «-&°žt¶Îœá:ÎŒÅms¶™X ÜNã9™ˆ€ˆ€T*DrücJkD)0!ïKá„ÁD ¶uš¡è€ðá:˶ ‚¬úP/xÞ¼y³Ÿì ¨c­£Fz„6!6hÕª•—â}‰w* Ÿ`Ä4f@€Ë–¹èå¡ü»u«s/¼àÜ€.RG–¿<*ˆ€ˆ€ˆ€ˆ€$*`”c1Œ<`½î @DÀœP¯¤“U'Ä&È7GH€g !§m9ÐÐÍ>Ä d" " "М Ð#ÿ‰LmÚ´©Îf¢?!2x?ê•fb›#Ø´}ìG„`ƒPl`Û˜3!>¡^üeOÀ=Ú·oŸŸ–/_îËCD'Þ­téÒÅuîÜÙOˆxï2¡uLC'”ýª" " "P\HŸ~ÚE oÅÍ·1¹=û¬s—]öÑÑ»®LD@D@D@D@*…€DMx'hÈ´^sôª£±š†ÍíÛ·GQÖ¶y»e•OÀ¢XTæIÛL@ƒµ‰½kb–ÐX­¡*ÿ¾«„" " ÕK€ÿ³òþ¤“Nª÷BðîÆ;‚"¼ûî»~ÙælGjذ I„zO¬MF€á0Þyç?­^½ÚŸ¡ïi œ|òÉ®{÷îîÄOôïk¼ÛñÞÆ»ie" " " UJ`ï^çVR$ÐU«œÛ°Á¹]ôâZ¥`UlZ$ QA ï*˜MHpèÐ!·5 e†€!‘Ø'«,4Ç¡X€eöÓØlB„L¬›`€9ÎêÕVY÷W¥´ˆ0dÿãë;Æ" 4@€`óø2ï~á „BÄ 8»eå!{î“ x÷#F×®]ýÔ­[·(*q{ÿî‡ÀÀ&êŒLD@D@D J (ˆ†uQ4«Š1¢'0Ùgj„й)*ˆˆ€ˆ€ˆ€ˆÔêU¤z@8]‰ ™‹€FH¢ "زe‹•@V^8øM@£/ ÄLá2Â8èf"–ÙÆ:Ë ”÷>êì" " "PiŽ>úhÇDØü|fâzÇ›ãše°LäÄ©¡øÀ–Cñ„ùHw]»vùiÁ‚>sÞ‰f`‘ ˆjЪU«ºhTìç½S‘¨Š{/”›ˆ€ˆ€Q*)J]åŠÚ#£mÑ\D@D@D@D@ÊN@¢‚Þqmü]æ4 ›€`óæÍ^D@c°¬i „"í‰:@c.=ËlL\Dád‚–-[zÑa‘ÓÃY Á+´mÛ¶èQ tŽ4wâ£4b%VÕú ò[õ6½c"Ã!‰CªØNtŽôχX‰US=ƒùļg"Våý’HW&@`n"„¬&2ནôkb"ÈJG€{´nÝ:?qDª¼s2TB=Ñ ÚµkçE u…È€ßy‰ JwO”³ˆ€ˆ€D Š$½ttH“$®Ôr5ÉÅë$" " " " •J@¢‚”wÆDô£ñàÁƒñÀÆݦM›|¯%œš²Ò –†X„˜lmˆ `ûªHÙÍçÀW\á:tèàÓ«„Ôƒ|ÐgÇPW]u•o4.Vþä£s¤§)VbU­Ï ‚û-áwjêÔ©Þñ”þŽÖŸR稟‘¥+#Qÿ\¬êgd) e…(’w &zÂ'™  <à}töìÙa Â$Þ‡øßH{¶!>°9Û,òѶdÅ!€ˆÁ)Óüùó½x€û@$ƒ^½z¹ž={ºŽ;ÖÝ[‰ ŠÃ]¹ˆ€ˆ€ˆ@ƒ ìÝ뢤^²+µ\%»`e," " " "P $*Ès—ˆ@€ˆ€ù¼ˆ`ýúõ~NøSë–' í*â ÄE K€@€‰Z¦p`Ö»×BszäO:餢 ¼,%¢…vÁ+f%zÎóN„áóp™ÈøÃêÄ&:`Žð@‘wËlóåјÍd‰EDLˆ ØÆû*"Þ…e" " " MD jï‹^xšèdœ¦RËUÀ%(©ˆ€ˆ€ˆ€ˆ@í¨ ¸§4 "" ñ•^_[¶lqˆ˜vìØá‰ €ÕÀEœþq±0<‘Ìd‚–ÐØš6\,ç¡ACŒ`bƒ;ñ0#KâF±JÄ’¸Q¬±$n¬V8ì÷ ŽÂb›Î‘ž¨X‰U-=ƒ¼_ŽŸ)É ð΋xÑsœà6çÑE;0±sŽ•À6‰jîmˆ à½bÅ ?ñ^Ëû.C%ôéÓÇG2àÿA‹-ü{o©Þas—P{D@D@D ™ˆ†r•µ©RËÕ̪‡.WD@D@D@D “ÀßE[Í6æ)—n"zjíÞ½Û­]»Ö‹Ö€SYáè‡S†É,Ó°0‘âQYnß¾}Ý6œ„Å0î-ã c4ØRŽb; tŽôwJ¬ÄJÏ`î:€SޱÐ1~§ø­,öï•Α›|Xʼnä^«Ülâ{ª•‚ëi¿ÿ~ÇÄPˆpŽóÛe¢„aÔ®YVÞƒÛµkçúöíë§îÝ»ûh[&2à}:­À¶°3+µd¸ë®»ÜÝwßí¦OŸî®»îºÌZ+ ›o¾ÙÝrË->o–oºé¦’œG™Š€ÄL™âÜóÏW^´‚(§{î9çÆX«" " " " "P:ønñ—c´ý]3´f©€ñcéue¡`‰B°fÍ÷æ›oú†ÒŽ–sÀáŠp‚1m€aÚ¶më…ôŒC8À:"ö5…ÑàJÙRšÎ‘ž®X‰UzéSÖJ½â÷´Ô¿W:Gúz%Vb•ž@ú”ÕZ¯„žŸ)nDðâ#Ä&:`ŽèàÈ‘#u"‹p€è€wqòl0EäÌ4{ölm‹¡ àúõëçïwˆ xç¦^ÉD@D@D@A ŠŠ…Ó¬ÒÍ#00‘Í9¦¹‚ ÄÑL³fÍòïè “0xð`×»woÿ¾N š{MÑõ‹€ˆ€D W/ýótÑËIA‡•<1åj¢HŸ%¿@D@D@D@D fÔ”¨€±\0öëöíÛÝŠ+Ü믿îCˆÖÌkä…„âÐøˆ`á„L¤—‰€ˆ€ˆ€ˆ€ˆ@1‹wM&âfùË_ü  öîÝë̉t€HØ¢„¢ƒæ,6à{gÁ‚~:þøãƒ¡C‡zl|"êy©VÃ4ÑÿÎH©ç¢FÄ„eÚDÊÅ2¨ U/* ×ŽE$ Áòå˽€èÍÙ>ö±ù±Vq€9 ‹ˆ:tèà'Ynݺu4„\4†œLD@D@D@D@Ê@ਣŽr8Ç™èyoöÿ÷^P€ØÀ&z볌ØÀDˆ˜7·aÞÿ}·dÉ?µhÑÂõë×Ï 6Ì  1‚ïE³Z¥¹ˆ€ˆ€ü•@ÿþÎuíꢱ†\ôQXœrŠ‹^Š*£<*…ˆ€ˆ€ˆ€ˆ€ü•@ÕŠ >\.•ˆK—.u›6mjvCÐ8hÂP<@癩;ºN:Õ‰(ò€ž}j!À».ÂØ=zøÉÊØ€ï¢ìÞ½Û °k×.¿Ž“Ý"„b;¶–çï½÷ž[´h‘Ÿx÷4h>|¸ëÙ³§B†èàãÿx-#剈ˆ€ˆ@zÑ;†›4ÉEÊ<½P¤?®”)O?ý#¡C4œ”LD@D@D@D@*‰@U‰ þô§?ù¡ ƒuM¤"&äçêÕ«}¤J‚Zª²Ðƒ á€M4°2tÑL@€ˆ€! èå%Z$€ØÀ"ôbÜá¿Q €hˆ ˜Xæûáƒ>ðÑ üñ¬iAòþýûÝœ9sܼyóü·ÂÈ‘#}ƒ“O>9ŠôÜÊ‹5ø¾‰€ˆ€ˆ@³&pî¹Î=òˆ‹”‰. wT^ˆ¦LqQC_yË¡³‹€ˆ€ˆ€ˆ€ˆ@ªÐHC ÃXÏÖkÙÿÔÄÌг¨sçÎ>ús„„4Í7t¦„Åè•DTƒb›Î‘ž¨X‰•žÁÜu VžUŒóËßÝbGˆ¡w.¬tŽÜuÉöˆ•‘¨.Võ3²be$ꟗ‹U›6mÓ!C|!)ßD40¡‰ Ž9’!6@hð—¿ü¥þ‹«¢-vìØá§™3gúaÆŒãèoŒ|ßUt©*ªˆ€ˆ€N 6Èwžsë×;·o_áÇóˆSOuŽé¸ãŠ™«ò¢¨hQã¤"X»v­ïaóúë¯;¢Ô¢át¢·•E°á ºFc»} K—.®uëÖ±AZƒBŒ­[·úã"0Æj1MçHOS¬ÄJÏ`î:PKÏCñà¬BP@oPBvÓpxé鈊U:N¤+±ªåß+D^t{÷îí'»ÛˆÀ>‡ûÎ;ý|Ïž=~XÄìGŒÀóQ+Æu-[¶Ì1|ßcÇŽõÃ#pÿ[Fc8—BüX+ìt" " 5Làê«{õUçfÍrQÏœò\h$ˆt×_ï¢Èòœ_gzTœ¨€žAˆ Sº$ÓlN²Çx-=hؤ“ëEPн{w7jÔ(‡ˆ€‰1P $ñ¡WW­Zå{qÞb‹ tŽ$òÉÛÄ*™KÒV±J¢’¼M¬’¹$mm*V øÝ5‘X±EDŸÑ9’îpö6±Êf’k‹Xå"“½]¬²™äÚR鬈Ö­[7?Ù5 $àýyûöí~Bl@„¶!0@Çû{µG3 ü½à…^ð‚ñãÇ;†’ Êâ¾Ud" " "Ð,Dmrîºë\ôÏÑEã­ºè}Ó^vôNâ¦MsîôÓ]ô!Ù´çÖÙD@D@D@D@D %ŠÐ°Åø§4n-X°À‹ jeˆKÇE¡ËÌÁDC®Š'œà 䯗ò¶¥KFC BÎËœ^³Å6#=Q±+=ƒ¹ë@-=Üg~wí·7÷U7l¬tŽtìÄ*'R‰•Xñ®Xl«Æz…Ð1˜ Â:o’ÇÜmÙ²Å?ƒHèôú·á’¦ZíwÞq/½ô’[¸p¡ÿ&9ãŒ3\ÿþýý0kðà>ÊD@D@D æ \r‰s68÷Ë_º(„‘sÑ;@“ï`§æÜ¾à¢0BMrJDD@D@D@D@B ì¢êLL0oÞ¼(ÒØ,÷î»ï6äZ*☣Ž:Ê ˆD€C‰1J‰€‰Ð¢ˆ¸n„X嘶mÛ½üD:`؉uŽüxÅ*?Ÿp¯X…4ò/‹U~>áÞZbÅï<ÿøím×®]x™EY&ºÎ‘¥X¥ãD*±+ý^%×ê KvzÔspذaþýž!É0ÄØæÍ›}T5„ >\7dïûÕd”aCÎ 8ÐMœ8Ñ‹ øNA\ š&€sÿ+_qQ#¥s÷Ýçܾ}¥ÐùgÄç¾ó)úPúÖ4b]œˆ€ˆ€ˆ€ˆ@uø»¨±«l­]ï½÷žo„{å•Wa7éµ_mf""01)âž={ú9NýRôN®6N*¯ˆ€ˆ€ˆ€ˆ€Ô"" ’&’Ó¦M›¼p˜oD8ë!”ñ³«AØ <ØMš4É‹ ˆ¶¦ïš¡¬ºƒîºë.w÷Ýw»éÓ§GÑÀ£pಒ¸ùæ›Ý-·ÜâÏÃòM7ÝTòsê" 9DÜ~äÜC¹h ¤Ò …€`AÏ;‘ "ñ¸LD@D@D@D@ÊI€Ž5ÖñŸÈ–t’­,‘ þð‡?D‘ÄvºE‹¹3fø1JÃBýöÎJ®âLÛ5£œsFÒHHB‰$@$a„%LÁ-ë¸{w½ÇçßÏÏbÖg×»ëÃúد›à€ L’ „$”Š(Ç‘4Š3=5S­;­·»o÷tx¿£V÷tß[á¹uëÞ[ß[_ógf+!èÒ¥‹{g¦áQðdC•1ãV&" " " " "Pþ¸÷ÇáÎkòäÉN<€XzݺufõêÕ.šÁ'Ö)ÁC"ƒÚÚZÃr Å.2¨««sÏk~ø¡™4i’œvÚiND­çòoת¡ˆ€T,þýùÿÏØPE‚•+9r$Z½{sþùÆüŸÿÓ(,ÈÃr¥ÑX©‰€ˆ€ˆ€ˆ€ˆ€10p¶uëV³xñbóä“Oš¥K—–Ä1`–Ë $@¥x`äÈ‘î%AIBRD@D@D@D@ BrÏž=Ý‹%xBdÀr +­c‚Hˆ Í€HÇŽ+HٲɄr¾øâ‹fÉ’%fÚ´in)ˆšš·ÔO6éi(z6 ©ùç6ÆŠéŒÞbÞyǘ;±Ñ‰r2»Lª]ËΘÏ~Ö˜¯Ý{=Õ’9ÕÎ" " " " $P0QÁÁƒÝLgŸ}Ö<ÿüóVä±Ê7Bh­[·vQ뀘€A3fåðbkÖÉ–‰€ˆ€ˆ€ˆ€ˆ€ˆ@:A‘Á„ L}}½Ù±c‡,_¾Ü=#mß¾Ý °TÛ›m³kKÿápâ‚3f˜‰'ºè <;ÉD@D@D ì0ö7{¶±ázŒùõ¯yî9cÃc¯Ù6äPfÕµc‹fÀcì}€]WƘ .0V—YÚZD@D@D@D@Z˜@ÞG€˜™Ã Ù›o¾iyä7+§…ëœ0{A¿~ýÌèѣ͘1c̈#œ° áNúRD@D@D@D@D@2 P]]múöíë^çwž¹K ¬_¿ÞìÚµ«(£·34—-[f6lØàÊ‹¸€(n™y)r$0l˜1·ßÞ(0xúic~ñ cCeµ`útcæÌ1æ’KŒ ƒZŽ”T' WQk…²–è¼yóÜ‹¿‹É:wîlˆFÀ’D#@D0nÜ83xð`£uB‹éH©," " " " "PžÚµkg†Y‡/œô V¯^í–Š[µj•!BÀž={Ìþýû‹&ÚK"<óÌ3N\ðY™¨ø h*ÞÅ*‚°Î)QÎ8ã '$èÕ«WÑ”Q¨<,•Às ¯)S¦–[»v­{®"’Á¦M›œÀ€eZz99–hà9ÑÃÆ­¯dº8p Ñr•×nUc¨(­Ze^]éG&" " " " ¥N /¢‚Ý»w›×^{ÍÜwß}n¦MKC""A=ÜàËœ}öÙfìØ±†ïe" " " " " "PŒXV€ç^ˆpÞ¿÷Þ{fÉ’%î3Q ˆÐ’ƒ­[·šßýîwfË–-æê«¯6Ç7D_‰€ˆ€ˆ@Ù°"ÀŒÍ.+R&©¨ ÁÞ ïܹÓüùÏ6¿ùÍoÜú -§}ûö.³|N³áÉúõëgN?ýt'$èß¿äËPwfaÌ0ÊG¬aºyóf—Ë3°kÔË4(‡7Ôb “ÛH¬ÄJýUò6pøða³}ûv·N"éDÝ·+äüã«x"Éÿ«älâ«x"Éÿ.VDà…)W®K´mÛÖ9ìqÚ_uÕUny„ùóç»wDÝÇŽ³‘˜¸÷ä„óóK]]yá…\¯½öZ3~üxÃó˜LD@D@ÊŽ@¶‘ $*(»¦  ‰€ˆ€ˆ€ˆ@¥ˆLT€S§Èã?n~ûÛßœˆ…6œ0>"Á©§žjÎ9ç•€>wß}·Y·n›5ó¥/}ÉtíÚ5Òâ1;èÑGuiâÊG ú<˜¼é¦›Üe”QáiŠ•XéLÞt~$gÿ ×Nß·0ÀÌš5Ë.µÙ)~³œþVáñ‰•XéLÞt~$gÿËÒ¥KÍ믿0a‚™:uj¤³÷:tÈ=s9ÒEd#³•+WšO>ùÄ 2`éžÑ e<ÿ½ùæ›NX~ýõ×›³Î:ËtèСPÙ+( ¢d© €×ãÂ@P." " " " •H 2QÁŽ;Ìc=æ…¼â !èÓ§‹0iÒ$3yòd3xðàØñdÆ“LD@D@D@D@D@ÊÂj¢ \@h€ ç>„ DL8zôhAªÍsà»ï¾kêëë]~,;§ˆA¯LD@D@ E º:sQ×E u„”ˆ€ˆ€ˆ€ˆ@žD"*سgyâ‰' *( |h÷îݘ`̘1æüóÏwË$Z¿“m™ý‰µiÓ&ò°Ò¤[ˆ<0ôõ@Huxlê¡< ÎÄ*'¶+±R•¼ 0ÛÔ÷í½{÷Î9­à{¾óàPÆ«²1Ìú‰ºÊ#xDS«Ô|‚¿ŠUFêÏb•šOð×raÅlNïä¡OGuß®<‚-'õg±JÍ'ø«Xi¤þ,V©ù-VD`y4¬uëÖΩÎý{”6à‹/vË1øè<·pͧq-;ï¼óÌç?ÿy3jÔ¨¼¢óYþJN{îܹæþûï7sæÌ1·ÜrK%£(XÝ¿ûÝïš;ï¼ÓåÇç;`y+# |ó›Æ<ø 1{÷†ßñ'?1æ‹_4ÆŠÿd" " " " "P¬˜Ì¿·é>—ñ$&¯-§H¬›ùÖ[o¹‡cÇŽÓü3ƒq}ûöuË $¸ð OªLªL£^Ÿ:Q^ù΃H呈üÉ߉ÕÉL’}#VÉÈœü½XÌ$Ù7b•ŒÌÉßãtÉwß®-l<^tÑEn‰¸+V˜ùóç»%6oÞl äȇ‘.ÏŠ<€Þ|óÍNž|”¦ˆ€ˆ€”€ì”±ÙñS™ˆ€ˆ€ˆ€ˆ€”:¬EÌlY»v­ùå/iöïߟ7D&@LPSSc.½ôR7Û…H2pˆrvæ™gšqãÆ™Õ«W›—_~Ù¼ûî»qÏsùˆ\@´†×^{Íôïßß\}õÕ¦K—.á «­D@D@D ˜ d}(Ï‚Š—Ê&" " " "P²ÔÖÖšG}Ô¬_¿>/$˜åÊÚÒÆ 3—]v™9ÿüóÄyA­DE@D@D@D@D@*„àFmFŒaV­Ze^zé%óÎ;ï˜-[¶Ä–Z‹aóþú׿š¡C‡š©S§ºå ¢L_i‰€ˆ€ˆ@A (RAAq+3â!•¨€exzñÅóR“Î;;1Á´iÓœ @3Zò‚Y‰Š€ˆ€ˆ€ˆ€ˆ€T(ÄcÆŒ1§žzª9÷ÜsÍ_þò³xñb³}ûvsôèÑH©|ôÑGæÕW_uÏxƒŽ4m%&" " 'i¤¢(RAÁ“2ˆ–@V¢‚]»v™‡~Ø .ˆÒXê`РAfÊ”)æsŸûœ0`@”É+-¶mÛš &˜‘#Gš7ÞxÉ V®\iöíÛÙ’,­°hÑ"!¡_¿~†lxamÚ´1:t³[FÛ"C‡™#Gޏr´}ûö•1ÌÆÊ# ¥ÆmÄJ¬t&o:?’³‰ÿ¥®®ÎÍêÄ1CßÞ®]»øMrú›ÒÖ»V©QŠUj>Á_Å*H#õg±JÍ'øk9±Â©Î³Ï+ôí<ƒDi¤Mß^,ytìØÑLŸ>Ýôïßß<ñÄfáÂ…n9„\ëL´‚+V"Ói©»\ij!€¨ S‹xùØL³×ö" " " " "ŒD,}ð /D‘¯©¶7á¬Û9gÎ7¨6Ñz»ÙúõëÍš5k\4ãÆ »{¨í •ǺuëÌÚµkÝàä)§œâÖ UÀq¼”G8XbŽ[‰•X©¿JÞ8?>úè#³iÓ&çtb¶'3=£4DoÊ#Q± lj­ÄJ¬Ô_%oœË–-3»ví2,pê©§š~ýú%ß!‹_öíÛç„ÛÅ”µñãÇ›nݺ™®]»š—^zÉìÞ½;‹Ú5ß:×1‰ šsÑ_" " %BÀ^­º;óÂj „Ì™i¢"‘¨€:‹-ʹ FŒa¾ño˜3Ï<3£ô˜ñ´e˳dÉçŒg°+jQA¡òؼy³«3x=:#é6f¦“òHG©ñw± lj­ÄJ¬Ô_%oœ ¸F1˳S§N‘‹ ˆp£<’ƒà/b¤‘ú³X¥æüU¬‚4R.'Vü±Ù°aƒéÓ§[º-jQÁL±æ1xð`sÝu×¹ç•gŸ}ÖìÙ³'õOóë'Ÿ|âDâñ´BXúYD@D ø„Œ²Ú¬àŠTÐ ‡þ(M¡EÌÞ':@®³S 4È|ýë_ÏXPàrg ℨÃJ2sÔƒwêµÁZy„£*Vá8±•X‰•ú«äm€óÃ_£|ÿž|ëì~Qṉ•Xqµ©]…'ZN¬X"‰~e×Â.Ùž”qÏ5ÅœQfΜé–n{î¹ç "ˆle‚Çñ\‰HC&" " %GÀ>÷elŠT12í " " " "P\B‹ ˜}ùá‡æ\zÂgÞ|óÍæì³ÏÎ*-„,yÀ %¯| D*fý0ØM~}ûöÍŠGªðT©øM¬N°H÷I¬Ò:ñ»X`‘îS9±"„8 èߣžÉ GÄtÊ#]‹jü]¬Âqb+±+õWÉÛç˶õïßß ºwïž|ã,aY…bσg°3f˜;wš ˜£GfY[c¶mÛæ^ùx–˺PÚQD@D@ÂÈ6RDaèj"&PeCý7„)k‰þ×ý—[K3Ìö‰¶!¼åôéÓÍw¾ó¼ÌðI”§¾ÈŽ/¿ü²yàÌÚµk³NpøðáfΜ9æÂ /Ì: í˜?sçÎ5÷ß¿;F·ÜrKþ2RÊ1ßýîwÍwÞéþæówÜûMD@ŠŒÀ÷¾gÌÝw£ _°Ûo7æ¶ÛŒQ~m)" " " " &ÀDš½{÷º\Yþ’@A«þ‘ê3˰þe.FaˆRÀŒT™ˆ€ˆ€ˆ€ˆ€ˆ€ˆ@é Rç&Mš”Óòmûöí3¼d" " "Prl´Q:5³bÛ1UnNWféjk( Тf¥ê2[#JÁ9çœc† ’mÚOD@D@D@D@D@D  7nœ[’.Ûb›¿[*ÄÍ­[·Ž¼>Ù0Ð>" " "Pp™ ( ?LÊPD@D@D@D zÑN—IQ>D4[·nM±•~(Vû÷ï7D]èÖ­[±Qåü òP¦ÂE*ÈßñPÊ" " " " #P°HÔa3töîÝ„b@Š™™X›6m"ùLºå’³‚<«Ž;æ…•ò Å„3± lj­ÄJ¬hQ[¹´«¶mÛÆúöÞ½{»kVÔ¬”Gx¢b%VQ‡¨‡¨ÚU嵫Î;Çúvœï<Em-‘àŽ;fÚ·ouu”žˆ€ˆ€”l–3²Ë™ÊD@D@D@D@D Ô T5X S ÂL_uÕUa6M¸ ¡œÿô§?™z«ÎýøãÝ ŽqŒ´½uèÐ!/•rȃCuðàA‡ŠIó¢øV¾%¦«ôŒübåI¤«ôŒüåŠëb]]«}:⻨ûvåá[Múw±JÏÈo!VžDúw±JÏÈoQ.¬Ž=jpÀc,€°$jaA¡óàºK”êÒ³gOsÿý÷›¹sçº:fóß-·ÜbæÌ™“Í®Ú'Ï8®_ŽÇI–ßýîwÍwÞé2âówÜ‘ÿL•ƒˆ@v~ö3c¾ÿ}c6l¿ÿ7¾aÌÿý¿Æ ~m)" " " " &н{w€l÷ìÙ à‹QÐHdŠ£¤¦¦ÆÞ{o0}ûö5 ¢^;ÚW.ø^y0™ïz(`«IýY¬Ró þ*VA©?‹Uj>Á_Ë…×Å|÷íÊ#ØrR«Ô|‚¿ŠUFêÏb•šOð×raE6^ù´Bæ€a÷îÝNøÆ¦LD@D@*–@«,¢ð)RAÅ6U\D@D@D@ʉ€]¬ðFÈêAƒ™;v4‹RPø’(Gd¼ C¾–rH–·¾¢$`'ýdláÅfœ¬vB(x¤_1¥ `6nÜhúôécXT&" " " " " "PXÂ,ဠ€H2üX»v­™?~~3Qê" Yè¿zµ©9|Ø´Ë …-›6™µ ˜Ãv9X™ˆ€ˆ€ˆ€ˆ€+ãi"lµ˜¨` †jxh&Œ5ësò¬e°¦÷Þ½{ÍÁƒÍaû€tìØ1ú¶2("šñ<СC':FxÌ3‚¬°x@PÀúyðïÙ³ga  ÜD ‚ Ì;×𒉀'[m±þÕ¾†fP¼§çÍ3ÿf_ë2ØG›Š€ˆ€ˆ€ˆ€ˆ@±hQQ0˜í2lØ0óÉ'Ÿ¸ÁÃvíÚå}méb;-Yž~ÙG[·n5«­ÚzùòåfÍš5fÛ¶mfÿþýn0±%˧¼E@D@D@D@*ƒ"cÄ̈g©´‘#GšÓN;ÍÔÔÔ˜^½z)²YšË 2>tè騱£éÚµkrV6" " "Pü˜zÓa1‰ó“Å‚ æ¢ÍE@D@D@D@D ¿Z\T@õ@dàðÀΙݿÃ,%ÍJÊïÁ‡7Q"^ýuó׿þÕ-E‘ß•ºˆ€ˆ€ˆ€ˆ€$&€Øg6¯Í›7›·ß~Û 83fŒ¹ä’KÌ„ Lß¾}õŒ_ÎßâŽHeD.ÈN (r9cU"Šâ©‹/¾8Ô¶ÚHD e ŒÚ²Å´_gcXñ]Xë߯Ÿ9מçCÛ·»‹¶²!Àò×ø xÞ8å”SœhßLD@ZŠÀúõëÍ:{?G”Æ!C†¸ˆúZîñ䣑¨¯. Q/j§NÜEe“]k¬½½ÑæÅl¥D÷ûè=s Øn߾ݼñÆæ±Çs'Oæ©hÈ/–äzï½÷\4-D³fÍ2cÇŽUÔ‚±ólg"°ÏdŠN!`%%!Ì™3Ç𒉀”4æŽ;ŒùøãÐ…qùåfÆwª5ô>ÚPD@Ê…À]wÝe¾÷½ï9ñò 7Ü`n¿ýv®\ê§zˆ€”üàæ_ÿõ_Ý8ýÒ¿ýÛ¿9téÕ¤ð%.*QÕ'jŠ5ÂnnذÁôéÓÇ}GèM¯aЋæ×\uDø_!ò`àŽµJ1¢2 ¢ˆÚâó –šxâ‰'Ì“O>Ë?ê|•žˆ€ˆ€ˆ€ˆ€DE€{Ú ¸çƒÙ³g› /¼Ð Dáç7žxŽà^—èQš ÀÌM-êü¤M= ™u n°«­­uìúÙ™”þ™+J†JKD@D@ʆ@6³kíu^&" " " " ¥N èD(ƒ\Ç7û÷ïwK" 0À ²áx'4Åš5kÜ€×À͸qãün‘¼ò¢y^ƒÐ? N"¤=zt$å÷‰¾4˜KL0ëè‘G1O?ý´DôÛê]D@D@D@D@Š™pDÇÚ‚€¯¸â ÓºukóÑG"!(:t¨{†ˆ²äµlÙ2³k×.Ó¥Ksê©§œïQÚ¾}ûÌêÕ« ’ÇÎ;]48XëÝ»·–:ˆò€*-ò&`…Œ›½‘‰€ˆ€ˆ€ˆ€ˆ@)(ZQ‡Ú¹sgÞ”Pœp‚>øÀ¬ZµÊÍBbFRÔ¢,·Ø5Ò–,Yâþùʃµbɯ¨EÌtòy0àÊ@(ì^{í5 |Ó»ˆ€ˆ€ˆ€ˆ@Iضm›y衇Üìz„ ¸§&²¡û&GiDû؆8öQÔúöí¹¨€çœ|çpañâÅîyN°›:uªfDÉKi‰€ˆ€ˆ@YP¤‚²>¼ªœˆ€ˆ€ˆ€ˆ@rE/*ðEg /"`DÀùŸðœˆhcéÒgFRÔ̇?≨²ûzµ€ÁÖ7ÞxC‚‚¨A+=‚ؽ{·yñÅM¯^½LÏž=Ý};Ï  ¢6¢ŠuëÖÍ-O@^Q/¯@yç+"-ð ÅÚ_D@D@D@D@Z’ââ­[·šW^yÅ|ñ‹_ŒÍ¸çþ=jCD0~üx·ìŸ¹Ú(w”yÀ!QüóQ÷îÝÍ”)S̘1cœ yðàÁQWC鉀ˆ€ˆ@ù°c‘‹ HTPþmC52'Pr¢œü555îűaÀ QvèÐ!7xÆÌ›\ɃYO¼òeäÁÚ¥¼òeˆ.HŸÁÏyóæ™={ö¤ÍŠ}X#–°±Djhß¾½V¤ÝQˆ€ˆ€ˆ€ˆ€ˆ@–¸§gé.–øä“OÜR{÷îM™óµkך5kÖ˜Y³f¥Ü6—™Í?hР\’H»/Ï/Qäá£pOÏó\y }ì”SNI[m " " "‚¢‚L­)RP¦»i{(&%'*ˆ‡Ç` 0DÞp 3¨FQã•j $²îì‚ Ò"`ÀqâĉæÜsÏu3±¼ Æ2È'D̮߼y³Y¶l™»]¹r¥sŒ'Ë—{þ·ß~ÛLŸ>=/ˉ%Ë·˜¾'bÜàç—3@T@„7ÿw1•We’&ÀY¦ãdZþ ¤¹ /" " " "ÐH äEÁ‰x€Žt?³‰Áµ;wºA6B~¶mÛ6¸KÙf×òå˃T•…Ëyçg®¹æSc#AÈD@D@D@D@D Ó ˜K‘=ë‰'žp÷²ÉÊqôèQ³iÓ&ÙàôÓOO¶YÙ}ï£: ¢æ>žç•~2<ÈfÙUE*ÈÓÁP²" " " " …$PV¢Ž™õ0ÜêêêbŸwìØáÜl«¢‚Å‹»ú'û™L¬©*AA2Bú^D@D@D@D ×?a‰ŒÈ^0œ¨ µµµfÅŠ¦ÜEA!Ƽ€h;vÔ’e‰‡¾¨ ¥€W&fÅöÂÉÚVD@D@D@D@ŠŽ@YŠ ‚”™ñDŒÐ ~ð-Á K—.±uFƒû–Ãgfo}üñÇ)«Â $Q j¡ %'ý(" " " "P8 ÆŽëį¾újÒŒ}ú¸¯0‰È ÞÞܳë¡C‡œ¸ œç¨ç¶mÛ‚NúÌ’Ì“‰€ˆ€ˆ€ˆ€ˆ@1à¾|ܸq&•¨€È\,wV.Æ3Éþýû]u¼€?K+"A¹eÕCD@D d (RAÉ:\D@D@D@D 7%*¢bP®W¯^î+DÌþñ†Ø€0ªlÓµk×’^&º8pÀW-á;õ4hPÂßô¥ˆ€ˆ€ˆ€ˆ€´œêýúõK™½ §Ü¨ˆôågÉ6–gãÞÜ[›6mLçε´¢whiÙF*Ðò-}䔿ˆ€ˆ€ˆ€ˆ@Ž*VTäFøÐîݻǾBT€ÅG1`F?³¥ª2];-–rË| lj*£þÔM&" " " " ÅD;‚TÆ=;ŽùR2D#โe{㾜åÙd" " " EHQA¦ã‚ë|ÖHEPZ\T@„€‡zÈ–™83gÎt³qB•>äF™æAXQ^| ú1X‰>|Ø 2pÉ ‘ 0þ^¸p¡ûÌàç™gž™vÔmœÁä½hÑ"·ƒ«„‚M7È6ùRJ„­—¶(mQß§îÛ·Ï,]ºÔAÁy?jÔ¨È#“mܸÑlذÁå1`À·Ëøg_'ž1øòLá¿ {´Þÿ}óÞ{ï¹ÍÇŒcÎ:ë¬ÈëQˆ<ÂÖWÛ‰€ˆ€ˆ@QÐòEqTÂhqQk Î;×ÕGþôéÓ#ä’ƒ|=zôˆÒòÞý,#Þ_zé%7Çì¢Ñ£GGæð÷™#*xýõ×ÝŸ €Ž92ò<|^zr$€¨ÀßSãð6lXäÎø5kÖ¸gž&Mšd.¾øâf('³¬A.† À?G]{íµfìØ±‘×£yäÂ@ûŠ€ˆ€ˆ@Á © S+±ˆJ™VOÛ‹€ˆ€ˆ€ˆ€T”fÖ9íÓ§O¬ØÌ8B\À¬£U«VÅ¢lÛ¶ÍE9`Ö™ˆ€ˆ€ˆ€ˆ€ˆ@ùàY€g–3à3‚žx6`YµššCD6–Q“‰€ˆ€ˆ€”8E*(ñ¨â‹€ˆ€ˆ€ˆ€dK ÅE °1³Ãaï—ȶB‰öËgD%àEƒsÎ9ǰôBòÄXzÁD¢ ð3’²]²>&Lpé’ËD@D@D@D@D@Âà~ÜßSïÛæ€˜øÀNH€x˜gàÒ hÎ=÷\—äøñãÝ6aÓ»Køç(–>ðÏa÷³]!òSm#•J€þD&"Pd쵿*Ã"5Ø¥UíÌ#cÕ‡î©ÍE@Љ@𞿘ʥ²ˆ€ˆ€ˆ@¡´¸¨Çøœ9sbõ͇¨ ¥ò`ñرcÍ–K ¢µµµnÙ>3ÉRanJØvêÔ©ìæL¢OBï" " " "  Ñõ@IDAT"Žü=5÷àéœñÜÏïÝ»×Ý×sÿÍ=9†³—têÔ)V€‰'š3Î8ÃýMúù¸oGHÀ’X)çá* ÿD Â xñ€¯pª¾7{ïf ¯Y%¬ Àß4â?D Ô$ºNÓdÜ'”ZÅU^h"Ðâ¢Ê‘ëz¢aŽfKåѺukÓ³gÏfE$ªAð&„¿™íDT%V%ƒ;gå ˜†>‹€ˆ€ˆ€ˆ€ˆ@¥`Ð/Ù=µBPWWç ð÷î¼™Œ%ˆrÌØ'B‚`~å’G°Nú,•F Ø·ëî¿~§Ï" ÅA Ó(”šH.ZDÅqU È‘@PDÀ5Û_·%0Ȭv(zE!*(zJȼ¼!&7" d"4``Ó\&÷Õgô¼€àСCncœôˆ ü  _20H€Þ½{§OP[ˆ€ˆ@:/¿lÌüùÆ@8cNJ6ØßéÒÓï" …'°aƒ1Û¶e”oÕúõÆÜ{¯1}ûf´Ÿ6(Ço»Í˜îÝcò‚ À?Gøßb냈€ˆ€” ‰ Šà@2PÍÀnR<C‚ÐààÁƒ.ôª³JݨÁATD@D@D@D@Š–Kìß¿ß>|ØÝ;#ð‘¸×ö÷ÓD# K$ÈD@D rˆ î¼3¥h@‚‚È©+AhqUVˆP…¨@&"P²ŽÜ|³±³]ùý³ãóþY‚ïxùq|¿MÉVX¯<'/[¶ÌlܸÑùœRUšöÎäWÿÌŒ?kРA.‚ŸÚ{*rúMÊ‹€DEz< µê×kõEL$4`éÄüFçÍ)Ë'øAR¿¯ÞE@D@D@D@D Ü 0ˆÇ}±øÅý1"oìýààCR-cPî¼T?ôˆrÖ`°Ï¼êíÒ&¼ãlõÿî·s;è?(RkÖ¬1?ü°ùè£RŠ |›O$*2dˆá5jÔ(·Ì9ÛÊD@Ê—€D%tl â—N : –Ñ€ÁÔíÛ·—P UTÈœ÷Ä»wïv‚ø½Ô@@Ð=®4~ý-" ù&àDMùÎDé‹€ˆ€ˆ€ä…ûìË;WyÇÁêE ø›wÿ‘ƒ5/‡C‰FDà­·Þ2‹/v¾¤L“DˆÀþ(™(-(‡2ÇíËG& " 2Àø›ßq¾bŒùcøø^&¥@`Ĉ泟ý¬éرc¬¸ˆex!*¨­­u>­+V˜eË–¹gXÚ¸·•+WšÇ{Ì-ƒÀ³³Ú¾'£w(%'*à¢üÎ;ï˜çŸÞ©¥Î=÷\sÝu×Ez4 •ÇÂ… ÍüùóMÛ¶mÍùçŸofΜi=èäéØe" " " " "PÎpÈ?úè£æâ‹/vë8FYWfb<óÌ3fõêÕfРAæŠ+®0§Ÿ~z”Y8AA9ä)%&" " " " EB€YØÇšDˆàHõ‚Døp òÙ›ž„ÞK…“_'L˜`ºté’´ÈœkÖ¬1ï¾û®yê©§Üà °àý÷ß7¯¾úª¹êª«Lûö퓦£D@J@ɉ èœ>ùäóÞ{﹋ö)§œ9õBåÁ3ÔƒO555‘׃E*ˆ«(28þ‰T0zôèÈK†PA÷í䃨9j#ÝrÈ#j.JOÊ€`å]sËሪ" " •H ®®Î³/¿Ä¡ß™¹ˆ€ßóÎw~8ùh•ÈLu._íÚµ3cÆŒ15Ö§Å„ÙxÀE0ð5&Ú¢ùK.¹D¢Eï"P&JNTÀŵaXPýâ4j+T½{÷võ æsÔÆMK÷îÝ£NV鉀ˆ€ˆ€ˆ€ˆ@Qð"Ý=zD^.f¡ÇÿàÁƒM§N"σò—C‘ƒQ‚"PF$*(£ƒ©ªˆ€ˆ€Tffµ‘ ðG ðKàGðb¾ç…yQaÅR…+ŠÏ±W^y¥yë­·Ì¢E‹ boëÖ­3{öìqË—sŽÈD@ʃ@ɉ ¸p~…µRéŒú÷ïù‘(T“&Mrƒ‡ä—z C1&r&ÀZ7Üpƒ8p`äÕìܹ³[ò€|FXµQ~–U(õ<¢æ¢ôD Ô Ä;$,(õ#ªò‹€ˆ€T*¢—±ÂÄîznýLèc\ŸhÁþÅß xšß'ø>‹@9@t?yòd· 7B|o ¶nÝj†[&Äÿ¦wÒ%Pr¢„56¬ ¯|Y¡ò>|¸á•/ãæ…O2(gݺusù¨#QÅN?ýô|$K“ò—C± 郈€ˆ€ˆ€ˆ€”¤D+À (àÅ÷ |”~ã%J"pê©§:ÁM|·lÙâ΢ÿ%3ÎÄ8˜(;`ÀÃsx¦Æ² ¤uðàA7!¹cÇŽn2o¼È'QºÛ¶m3{÷îuç/“ þ'ÚoÇŽfýúõn[ÊLÝ(+Ù€@”uú™”+ägs¹ÖXõpV" b†#Ñ ü»O†¿ƒÂ>+ü»§£÷r$Ð¥K—„ŽtΗ๨îkÖ¬1úÓŸÌöíÛÝ9…ƒž~Ó¦MËXX°páBóÊ+¯˜ÚÚZ—Q>ó™Ï˜qãÆ¥Œ–@Þ>ú¨$P^ö›={¶›ì7n4‹/6Ë—/7~i‡8áAûöí † â"‡_xá…¦k×®‰ª«ïD ä HTPò‡PÈD%ÀÁˆhÀ/wà^Ht òwHæ£LJSŠ…ÎuÚ{¼1k?Ñlÿàv«V­2/¼ðBLÀoœ_ 2VðÖ[o™ùóç›C‡Ų âù¨Q£RŠ 6oÞl^zé%³{÷îØ~,]ŽH€súÝwßué.Z´È‰‚çylûáƒ>0o¿ý¶'\yå•.J‚EABú\$*(‡£¨:ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€DN (Àáéÿ:ùïXå;9#?J°ÈlذÁ‰nâ‹Å2©–>`{Ä:ñ–è»ømý͹<'Ù†´â¿‹ß7Ñ6¤Å2 ˆž}öYƒø!L¹X~áü£(\sÍ5fèСÅ×ß%M@¢‚’>|*¼ä‡@]]yñÅ](Ÿ6mÚ˜ÓN;Í\tÑEùɬÈS‹"?@*žˆ@Þ ìڵ˅۴i“éСƒ?~¼A±-«j•s¬US“ x§$ŽF¿ô[yqÁÉ{è¨ D`&ÿáÇ›U¸gÏž†W©Fë@P0oÞ<÷Ú²eKL˜ÀùߣG·Ü/‰¯ûþýûH sæÌ1;wnÆFˆ@)¨ ”žÊ.y ÀÍñÊ•+ÍüÇT†¬ tÅWT¤¨@,òÐÀ”¤ˆ@I`ý;»qM kÄ]ýõ E…šQ¨|2=PÅZ®Lë¿}&m ~_ý-" "1»¶¬¹øbÓpÔ†t=RgꛪÖmMU»NÆT·Jž™Ý®íÙ¯ªÊT·ëhL›É··¿TlÇ™úÃûmÜÝcnfiUÇn–mꡳ»}ÃQ»Ævƒ sÝÖrmkùZÎIMyˆ•ÚUÒÓƒsOç ú’èûÝ£ÆüäcöîMÞöÒüâÅ„r÷ƒ`T¾óß§IJ?‹@YxõÕWÍâÅ‹ cA›fï[»víüª¤>¿öÚknÂ%¢ÎmÎý‘#Gš³Î:ËœrÊ)n| áÁŽ;œ/åÍ7ßl¶ìÂÑ£GÍË/¿l¦OŸî&l–ª¸¢¤š [©ŸŒ Re""PL˜™ÿüóÏ»5€(W§N*VM'ÅÔ2U– ÀÃëÊ}øá‡.û¶mÛšŽí@y“ñ´zõj§À¦ÏDt0yòd3qâD¿I$ï…Ê'ÓÂk¹2­GªíÓµTûê7ˆ *¸ãÓppiØ¿Ã4;jªÚw1­ºô±"vI3k8~Ô4Ôn7õ­3¥ª•©êÚÛTuê™t{~¨Ø<¬ð¢aÏæFQ…´îuJZFýÞ-ÆÔís"Ó¹—©¶¯T"Ê㸫Ôµ++‚Ò9¨¾$É•*ãóà ëªüuN¢_ < ½W:½V¤C„‚ßÿþ÷n¶~ÇÀÍ¥—^ê¢]¿/¥Ïï½÷^l9¢vÅ™×gœÑÌWBŸ°víZÓ«W/76Fôo;wî4ˆ† â|,þ{½‹@)¨ ”^…–(kQi=ªèÁÚÚZóôÓOÇÇyô™Ï|&öwK~ |þæ=ßê¾bbAÄ„O>ùÄìÙ³ÇÝŒ¡†$‚„LD@òI€~µàPV{ëÓ§Amîo .4ßÿþ÷ ¢‚~ýú™[o½5rQA¡òñõ û^¬å [þtÛ…iéÒÐï" " " " " "P.ü¸d¹ÔGõx´ñcÇŽÆ£ƒÆ˜~^Û·o7ï¿ÿ¾Ú¸qc³mYò`Ö¬Y¦¦¦ÆÍî¦QJŸ}$¢-Åù³Ÿý¬4hÐIË9à£6l˜™={¶‹úŒÐ~ÞS»òÊ+%*ð@ô^òZ\TÀ ¯‡zÈdíö™3g6SúDA¸\ò@å„ò ÃÑûéOº¬;#:n.PkÖ¬q¡föíÛg`ÀŒp3¬EË ÕСCâ«{÷î¡› 飨ûàƒ\º¡w lˆc÷ì³Ï6äË…–ÐФµQ_ÉcÇŽ:éféqÁ[±bE¬¬4bÄ3a„fÛêÂ&±ÃG}äÞiúŠÞ½{»cß¿B(“c¦üŇÕo¼a~ûÛ߯DS¦LqN;Ú…LD@òE€þ–,‰ƒqÍ;í´Ó̸qãbYÒWò@ɶï(±£¶Bå“i¹‹µ\™Ö#ÙöaÚ@²}‹ù{Ä2Ï<óŒ+"÷ŸúÔ§"ŸAÁ 3°1cƸ‰DúˆÒÊ%(™(-¨Um¬À¸cSeÃí›Ö6BAÓs ÌáƒÆ½ÛïªÛÚeìò¦ªÚE4¨nÕÆ}.}ÐÀöG:tU6tK#+⯀<ÙeÜml½íZ·,!agFWuênªlv¸™jˬÉ\¤[«îÐ¥‘½ýìöme÷³ƒðU¥\D;;Vyˆ•Ú•Îõ%Ëê°OÞûÄÃv–0ýq–²ýuøÛGsmËÅp´zAAðs.ij_(FøbyäӮ݉(X´yÆöïßoŸ'ä?³óñ» §;“/¿üò²˜G„êó¹Ï}Îù"RMre’ Ñ–/_îÆÉ<& 2CcùžŠÞK™@‹‹ pÎ;×1ÄQÎ#8Š£´rɃNÛ³b”™‚„¦/7ãb´lÙ2³`ÁçàÆ¡¼~ýzwÁBTpèÐ!§£P/*fa8Ý ¹ˆ€DL€þxÓ¦MNT@Ò\‡ àÖ‹8+%W¤ÔŠôÀ¨X" " " " " " "PðÇàHgÂßé§Ÿî&z2°Ì/ãVP@ÙÿKB£8àãŠ_N¢©•I ÅEt2ÌÞÁ˜½C´‚¨­\ò€g…Ú‹Yäåbt²„p½ï¾ûœ3™0ACÖ·o_ƒŸzãÀDZŠÃÙ+¿üF”@§ÍÌ-:ê[n¹%˜L³ÏüÎrA#´3y…5œî8Y0”f\dÂì£8h\€y%3Ò$„N>ˆBaœ(èPʈP€¨á‡?ü¡Ù¶m[,[œY>*œ˜9Œ.@e§°ÎQ.V ,|ùiWô:Ç2zôH<{&¶¡>ˆ€ˆ@èc‰ŠB”Œ>xüøñføðá9¤ª]K‰@9·î×ü=5¸ÿ‹Úˆ€àó8묳\”%å5¥'•K á˜"tä ï|¼q¶|Ó,{Â;W·ïjXºÀ†íoœIo9Ùe\ÈiösQì¸K›Æ¶D&¨îÜÓÁt¡û›ÂCWBUí2Ž¡eA4ÌÎnm8ܸ,‚_6ÂÿVåf½6^3|”vqËGبöSc¤‡Öv83;_yÄ":ˆ•Ú•‹„¢óè/áÚ•¿~·Úö»®?æZÈ26X}óqØÆ/õ¿ˆ@/BX0ÌF‘.§™øø¡Oå³IÄß‚¢|>rA¢}ô”ðÞÓ<Õ Çåœ9sb©çCTP.y $ð¬p²–‹¨Küô§?5/¼ðB¬Ã¥Ž„Z>ÿüóÊ­¦¦Æ-A½qú"(ؽ{·[»™µj˜©Žóq3»üñ”¢‚X£kú@Ûc¦û™gžÿSÒ¿¹hR>ŒrEZª‹åþùÏ[b€4®¹æCý’¢‚#F$û9’ﹸ=ýôÓ1Õ<>ýéO‡IDR›¢‚×_Ý 8þ\¼'L˜`Î8ã '€-r«V­rB¢`wÖr‚-Ž/ÖpÊÖŠ…/;íƒè ´)¢Ðœ{î¹®ùmô." Qؾ}»yùå—c×"£Æ.Œp.ê²(½–!PÎm!¿§æa?×G‰ŽB–åÂ8ó<µ•KQsQz"P ޲aõw5…îïlZu¶3Â\è~ûÞ±›u”7X víèjû²Ö€£¼®Ö.`£ßÙç©V,1t´Ÿ›&,Øg0œánŸ È£ªS“PÛÕ»ÑñÔpÜ.!qÀ.!HÀ^#Z;F£à ºC7ÇÆý˜PÈ:‹-ÛûLÊÕmŸO¸m»oLØ¡<6±R»Òùa»aõ%ך&‡~ûݦkš]¨Ê ¿d" é 0¹I†þ? “;ñÃ0”¥z½ïƒñø·ß~ÛM‚»á†Ì©§žZV‚ô´NÞ‚±üx! =³“÷Ð7"PZZ\T®B¬±Ryàd-D= Ù„™±ÿᇚ»îºË-yàóÆiÁÅëÆotk×032Ñ,2:cD +V¬p3*ßzë-ªç2ŽáLŒô™á~Ýu×e²[l[.´,½À+•Iሉ pÞßtÓMnêTûåó7npγìF[Ãô)»ŒD¡¼98ÎY·ž„Oâ‚ìò²ìÅÈ‘#ˆ¦hndþò—¿Äœ~Ÿ°ïÅÄ‚2ãè¸è¢‹Üì`n௠:ô¤›“°õÓv" "Ž€_veáÂ…nSœ®„ocÝyYe(÷6@›Î÷=5÷…~&_­¦\òÈ¥+eMÀ‰Ž[µ¯úUÅq˜ Ñ‡râ{÷ÉnÇölîöoú§N¢í+!ëøOh0u¬pBùhñ;¹í›öq€›6àx(æ´ÄÊžƒjW®Qèüh~nð—Îüž'×7"  0±_…fö¢&»1¡óµ×^3+W®4>smm­y¹iRÊ—¿üeq7Þ©ž ›²ý*Ñ8³%*(ÛC^q+ QAÅQW…ï¼½÷Þ{Í_ÿú×ÊÓ§Ow¯Ë.»,eDï€&ºŽgœÐS¦L1o¾ùfÞ— ˆ¸ >!ç‘_G6a‹\ÐÚá0Ÿ1c†s^M›6Í ­ÃÄ ®96Ê 7.?øÁb溺:',á·l¬Ð,¸©@ 0†6œh™ D6555ÙTGûˆ€”ú¯Õ«W;Q\¼˜ªÕ@ÀôÎ;ïfªc]ºtqQcür?…,‹òjj-Ã]¹Š€ˆ@Xnö{û.¦ÊF 0n&½`Ç·l ó\…œ0ãvIÆ¿]GÓ¸•ýŸ°ÓMFÔòÖ\8jÁ )t¹çq´Î9ñªìR¦mS˜l">tèÜÉÁ2¬>1l[Vmí­× v!ÝYúÀ 1ˆNà£=˜cvVl­£Pyˆ•Ú•Î×ÑÚÿÔ—ä»Ody ÛÞªmÔ˜v¶OF9gEÅîݽ‹€$%€o†ñiÆ‚âÉD#`ùb¢ ó7†Ÿ±ãõ‚“ãÓ(÷¿ñWñ’‰@¹8ñtT®5T½Š–Γ?ÿùÏn™¯Ôâ¢Å÷wgÎ9県ʎ£‡Ñ pH×­É(¡ ܘ¨O=õT¬æ\ø9…¾rü/¿ür' sób’%'î»ï¾˜ó‹ãþÑG¹›™lT‘…b˜`Ó¦MæÕW_u¯õë×›oûÛ E±£" eMÕ7}1"¯ .¸À½Xþ%KC¥É3/¾øblÖƒ#rM¡¯ ±èCÁ ¨ ¹2ÌX±@U§&'-‘ì³0æBH´¡ûÔYçv[Š¿—(ßÚ^ëMC;+BhÛýÍ šrl8|ІûßåþªîÔÝúÐ ÝoB+!¿„D»V{Ñ×:ª­Ê“u`Y„¦ˆ2š¬þÀ^»,‚"XkÕ½¿c‹“ªªmg+J°"kU‹¦Þõ,!q`·;.UÊ:b¥v¥óÞ êKìRyìëkwØ.Ü.GÓÞ† oÛ϶9Û÷ “‰€äL€‰ˆLèìÝ»·[’zéÒ¥±e3‰\ðÜsÏ–éã¥å3sÆ­D ( œx:*Êâ©PåJÀG)`ÖáÁpÖý[ßú–!ò@¶FHÛAƒe»{ÅíâØG˜:uj3lÇŒzœîÜpóУGÓ”ͶLþi aÿþý. D >”{á°"ZAXãX³LËcøµ´­;vD+a„ Á¼Â²î“égÄ0 :‚‚ 8,qâ$2Ï öܼ±t2NlËrD\À‰BÔ‹+ﲊ¨äEz¨N{öìévíÚ5Qöî;ŸîÇÛ5¶(K"åjÒ„?PÊ@y9~|¦Ü´‰îÝ»»öÕ«W/÷9°[è¤b–´wîÜéÚõG¼BúÔ;Ñ .¼ø=Œ#—ãIúp!jýa®¨l† ’pé–ЕÈ`CØÑ¶¨#Ç„üý±'Î ÊÉ6|¦ŽlƒÃ˜í³qs¾QoŽ!çõGØ Sµ­ø*¦ª‡o3«V­rÜ9¾”þ¨ÆFóö'ñé²-âBµQÿnݺ¹l¨¯3í+âÓ¦Î,!CÚûöísíŽ(+™¶ÊÈ1¡O¤úˆ /¼Ðœþù¦PâÊ@´„Å‹»jRúسÏ>;¾Ú¡ÿ昮[·Î ©8Ïi—ž?çH¢ó0tânÈ9‹xc­]&‰wÚßÑ·ÒN¹.Ñ·ñwT–úSnÖ2¤oÛµk—«e¦Ïäˆv<ÿ3©K>Ú@&ùk[ôœãº)î@³­íý¯±Q Ìñ£öÛÎÊ$”6†CÅ…ág¦fœæŸí1{MôVyPo^õVH; V!Aã—Mÿ{¶üiU¹°‰ØÚ4•‡XÑPÔ®üérâsNç‡Î|œôÕDòáE;c°=e" Ñ ZÁµ×^ëÆÂe¼ã3‚Q£F¹1–èrTJ" ÅB@¢‚b9VØçÏŸo–,Y«9¼Y³f¹ð±/õ!ïpL°î¡Ž1œÕÌÅáê Ç!NÃÿþïÿŽ j¬ï›ßüfhaŽNœd>ø sãØ½ä’K\d ŸO6ï ‚e% nd²q¦„a‘MÙ§NÇW^yÅ9 EDoÔ'o¼áÌ_¾|¹ùÙÏ~æØsžÀmöìÙñ›ºµ¬>üðCsÏ=÷8ŽÖ¯~õ«æ´ÓNsŽføsÞá,Ä…§'N(¶ÁqyñÅ7s¦Qnœ„µzï½÷œÃ§ w¾á¼Bô™Ï|&©Ð!¾ ^ذhÑ"ç¼ÄÑ‹C± Î,ï†>ÊE›Lå0ŽÏƒtÞ}÷]×¶qô’>Î7òÆñFÚÔ;‘3“c1räHsÛm·Å'û.”û™gžqÇg­uPâL†)éSVœzcÆŒqëП{î¹&ÑR±sü@}ßzë-óë_ÿÚ16l˜ùâ¿èœÁ”‰c‡eÙ²eNDŒSQ?†,;“¨ &*m€v ã5kÖ8ðå{Úlðâ4Æ1Î’*éœ÷©êAû ŽœC(¡Æp<É qÑØ±c]>(¦ƒë—± "„çŸÞ¼ÿþû®¬äCýi_”È8Ìħ_ÊÄH0?ü°û‰þ'4"”?ýéOîø¿ýöÛÍΟŽlÆ‹Ï}îs®=úßâß½ÈäÉ'Ÿtí'=í;Õ1¤ 0@x2sæÌ”é'«ÎÒÇÜÕ';ÛÅÎbf¾ô¥/™OúÓ®@èhêøƒslã,7œÿDà7ú>Äa §;B Úyà NfaÛ¢ÎYÄ´yú6fÓûÈœ£ÁÈ™ösÉÊç¿ç8r<©7¿ôÿ;ì;ç×–sxã7œè&~_Î5ꆓÿÖ[oMØÆï“Íß\¤ø~~.•!ìàá˜>‡¾™Z>êO…'/Ò½0¾lˆêè÷¯ºê*·¬‘ÂZ”m lžÚND@D 6¬~½]æÀ·ñv6¼sµ'³lNì]MU{ëPÁ‘ÂßÖì=ráZûÚoâÖyÞ±‡©êÐøaû«Ø×šs˜7…î7GUgyÏÞÿ8Ñ‘¬5XÇS½]²Ñ<ªZ[NVxUu´÷‰>úƒcÛ8ó•õÑ×H·á¶;v·NtŽôì~ÊÂ+µ+{ŽÝCç‡ú’Âô‰½lÇcûv®wM×´®—~ù:t™ˆ@Σ¾âŠ+ÜXã½Þ‹c¼lذa±‰3þ·Dï‰"§2þ˜j¬1Q:úND 0$*( gå à~Ìœõ†Ó ‡Yáà°Æ™ÃLR ç"bÖ=  f½O˜0Á9æø 1ÂÓO?JTÀMΜGÞpÆ/±à ûNºÌfÆ©7ꀓ>Ñ ‰ß&Ñ{X‰öMôàŠ ü Îxf“âøe&>,’-ÛAÙ‚ÿwð7òõæ¹Ï;×Üwß}nF9¿‘7N3Ž¡ßŽ8¹ñãX3k›Yø÷Þ{¯srÞ”ýØÖ+PÙ!ÃücöžÙýÉØãÜÇö?ÿó?N¼àˉSg;Î\D8gi/8Ž +O„¢:àĽýöÛ›ÍB÷iøwœ‡ˆ*~ò“ŸÄ–“ M0Ç eãF—˾~_ÿîëéÿ¾SÔ-p”S¶ÇiŒãŽYÂ8ú˜EO=p s#ÞeN1s=jãXsŒ¼ñ™Yá8ÙáA´ ŒcϹW_ÚÇð§?ý©cÌ4É–´à¸PÚ…` þ8·9†Ìô¦¿`;œáäÁ1ÁNXþ&ÂI²¨ ‰êÁ±BÄ`‚Ïû“'iû6 kÎ5ÚÇ~ ñï~õ+©&¾þ´a^ï\h3lC„ê”Êp¼ÿþ÷¿w,Ø—2Po¸ÑàÀ¹”i;àüò#è;¨7 ҂' ÎS~ó‘ N?ýôŒETÉê; DvÀ`L“Lf»Ã¶~ÿý÷›ßüæ71ì9Oø¾ãx{–äý•¯|ÅE.p?Fôíqç,ŽxÜIž¾¶Âñ¦Ír^`”è k×®uý&¢ °‘òUÚ7býèG1¦ôD{ o£.ôOðäÅrEÔ!O&¢‚(Ú€ƒ¨ÿD@D@òJÇ·9vØÎ¨·×.¶öšŠ9Á@u£@ yìï6ò@ƒ Å UûÏnÆ}«“‡†*#F_3Vˆ¬ À±ªnmª½ˆ¾Mâ‹fÛÛ?\T­f|öw’É—EPbuâÙMí*îŒÒ9¨¾$×~×>{žd4OúM_ˆ€dM€1#"0FêÇTHŒq+&1”nŒ1¾øm»aÌH&"P|N~r,¾26+‘€fÀ”ΆÁ`T£´BåÁ ;ƒÝ8"˜QœÉ o˜ú2°í>a¶/Ô6\pbgØá¸`ö¥¬°pȱΑŸõ‹³ñòË/O¸–<ÂnpR`8qXâ4K7‹“cÎRAÇ&ç-3As1œ¡8¿8—¼Ñ–²I7>¯DïœwÌ‚åf g2ï”ÑßáXc}r„´yÊŠÃ;†sˆYêœo8µ¹‘# ?aèq3“vÅŠ® p<);Îû»ï¾ÛýöË_þÒ9[qV1“›2#| ]ÄD7 ®Ô Ö<àÚõKd´3œ¾ìã9àøå”Ȉ È ç)ÎchÌ.¦\ôÌTgÖðE]”(yç,Ä K¹i—\#H—Ù÷„1G,A¾\?5Á§!F»AHAÈpÊ@âß´cf\ÿð‡?tõg?Ζ£€ }8}9å‡7eÇ LÙqÚ#ìàwfÒÇß,“V”† Èˆ†à³›ã~öÙg;C"fÀ þ˜°ï°HdÔ \[P$#Bbù ";Àg:u#–EàAcÈyЍ„vÏñcÁzpL¹æÓ†É“:ñéÓ®8><À0ÃÑùá'9lj}8ßè¯pв\ûQDœ§Ìdçx"LJf8œ_zé%·Ì Œó‰ýHŸâDà¸gӨ״iÓœs¨ô!¼/ÀŸçâ‚`äÚ.í8£O€ ýF{…#üÂû""¢õG(áÛì9Fô3êD?+ÚçâBŽs†“sÑ“Ãy]SSãD,AÁ}í×*Ú墜ˆRhÿüÏÿŠo>êÏùÉyJY|=8ß p> T¢^ˆO¨çý¿îdÂ2Š6I~QnËyÍõŽcšî¾$Ó|i·´ÎΘ‡j6/ÊO]êy„­¯¶ÈB€Ö¹Ê N Ý_oÖ¹]ÅìL̘·÷gnÖ¼ åû¾©Î!náX£À Q”Pyg »dŒZÙzÃÉÞ˜6í@£1rà çB©Àqg™ ¸Y±AC[{<¬ÓÊ9ˆI³3cü²ÊÃ!«êÆöÖÔv€¢v¥sÐv¾:?¢ìwÝ5­©]5Ešq}{Lòåpë?0Ùñ0ÆYÛñƳ-“d#K7VÅøbü8)ã9Œ%fjÙŒƒdš‡¶J'Pr¢v¬f@烩„§Ò •Y´t¾8¤ŽÒp°0h_lF¹ðšä~WèÏ\¨pÖpÑKg8 pqìJÕ¸È23óÙgŸU:%[΀Ú)Ž œðÂ9‹SrÖ¬Y±4}ð{3@Z8†É/#]FÞFZ8ä½”‰eÊ"QÚž‡À‡½¿™ÁYFˆy?»çcÔ‚¨ørá8~Ù:uq†pÜn¼ñFsõÕW;Ç2åá{œÎ8P¾£oÂ1…Cc…ЄöœÆô‘ˆp(ßsÏ=Î)˾ìÃÌðø‡ˆ/Šû›>Q¸qã\ßMzˆàÂoA£ì8Àïºë®˜sŒöÆlõd¢n8©Î7 Å-·Üâf?së²rËàßÿý߃٠þþïÿÞíÇ94Ž#Ë* X@P‘þÍ7ßìD8¬ƒÇiÖ1L¾¿þõ¯cÎ>–¡ÀaŸÊiL'ÛϜۨ‚qŒÒή½öZ'ø œ8Äø‡8Ž\•kŒãÊwDÎHtÓOŸGÙ96lƒ™òcâ!ý)jeD*^X€Ð€ôÊ ¨ŽsÚyІ éNº´aÚ Žiœ{"8¶8渶âÆ H?ÃrÌ6'_œÜÊB´fÔ“LøŽ>eΜ9ŽGü´Ú3ð½ çå¾ð—~üŒþ\Ú}}"Ä .ð‘ pÖÓ\°ÄG|äίDÇ.¾.ñâŒs§{²ó-~ÿ7u¦±?ç;}÷7œëœ3pFÈÁ½ç¼1Î_úO¢ \yå•>¹¬ßƒÇÊ;âáOŽ/ç'}ŸqoÂõŸü9'èÃaBÛ€3çmù¨?×8®'” ƒ#}Ø·¿ýí“Di”¾^ôG?Ö¢jaó‹z;ŽËÒp¾ñ#JÃÑOôÚíšû ú¾(ò—CQ2QZ" )´noª;µ:áÇam @}Ý>Šé ÛO¸þ*–7@`Ю‹ °¾´ý‡½É4 «;Øm:Z!NñJÈc¿]æ€Ømái—B@¤a{Õvy'€C ŠC=œlD¬U—Þ–iG÷¹Ê®ß]eya=?û¹þ˜ qÐå!VjW:?Ô—®OÜ¿ÇõáUí:˜êÎv){ ¬²‘gd" ù!À„1Æ?ã…Œ÷0žnŒŠ1ŽxQãÁñþ0%gƵC”‰€ä@É]Q$f°õ…|8å •õÀÁSSSùQ¦¥3-6á€sÐ •©f•qL¨gö2ŸSéq±ÂïLµÎ)¢8¢Ò º|AÒååï\˜i8È0œ… ' ñŒÃ',NDœ‚Î;ÀqÅ_üÝö?ŽNœÛÞpêõ £}Sv–`ðæëïØó¿'{Ï”E0œ0Ì–Žð=F?å×·§Í „¢mÊp”!(øêW¿jþæoþ¦Yè}x1»ùk_ûšsVá´ÂØ'3}kÌ®>è4§-Ð÷âHeýíáÏþ³!|~¢sh×_½cÀÌåTÑYȧÎSœðä8áPås|ú´3f飌pgö  €ßØ&×\sshr“KfŸQàœsÎa³fFÞ¤íÛ1ŽHÎ…üÇLxâwßs¬óÒ·S¸2‹– ßøÆ7š¥õð ¯Åÿå/ÙÌž=»Y»£]rÝÁÑŽsñûà8£_àú„Ø#Þà†§/ ©–rÀ™ã ± õæ¸qŒüçøcŸûzPVÚ0å¥ ÞhS“'Ovmq|Ðy1ãA ‚ýLJöA]ˆPÀ1Á¸f"H šD¢ò¡º¦ à°ÅxðÁÙüõ¯ý¤vÆïQ´òðÑp„ãXF`ÀyAßCÿJÄf¦ó=BÚp­ k<ü¡"çØcä‹ö™×úßöpÂz£íÑâôå<õÑ&øÝ;Uùþ)ãX!ðÇŠ¼8'ÿéŸþÉ 86A#?ÎÚíŠ{ö¥ r³|mžû•tuýiËôÉ” #2ǘòÆí–óñ çõkQ¶°yF¹ýýËèÑ££LÖ¥Eÿ €þ‘|8'£6Ò-‡<¢æ¢ôD@H¶díü­Ó»Î49ho¤ìlûúÎ àPiõ5ÁõÕÎÖo8rÀm×ÐÆÎskNW5E-H0dTNyXN.RƒÕ\Ø‹~#++Шj›äúÉò°eóúî'X±,¯xcP[yˆíBí*þì°b@Q_ýùÑpÔöÓDìie;wúöªÆ<à-ˆž}›cbþoŒ±2–á#Óúïãßñ Å]0>Áx‘ãÇoâ÷ço&6±•}•‰€ä@‚'ÄüeEÊ Ô2³Œ™Wt6t,Q[¡ò`àšz0èt’DU–s UY‚é0ÈÄ©. ¤r›PÖ ð§2Ž3<PÇÙÖpâ,â•Î8fÌÖ:ºDº|£üYþ¬3íÕ{8Q˜ÍËñHflW/*€³d‰Ä;n} ÄJÚÏê%}œ•8gr1n.X+Þϰæ¸Ó̱NÜLQÙ° Ópâá¸ÂÑG8u¾Ç¨'NLfsãüÁ‘Ê› ‹Tûâcx„8¢â~”™ç8‰½¨€mhãœ?8ÍqNƼé_XZ€ñ´#^g#‰of¸ó cˆƒàGZÜrîsÜù¼œñF^ÌH:3ƒyR~Òeæ1¢ÒÆác:^TÀo¤Ëò´ŒbÚZ*ayÀ–~Á7Ö´Ä 8[SõyÁ²fûÇ-eÄAžèØ“.×SÄ<òˆ;vž1‰D8šyPk´$‰àËqâò9ìõÉ× Üã Ž,¿Àìd/*`Ž/}~7ŽíƒHˆa(}íˆãL™ƒ¸üþ÷¿=$qü:$ëÿØ?ªv€Ð– d"ŠâÊìÅ>ràH#.@PÁõý)LS]܆ þã~‡¶GKdÔ‡¶D¤½ç9Âõ;‰ÒIôýðÚ&!€ ¥Ï ŸC°H0âÓá:GŸM_[ßfmàP­ êúó@Ì94Úc*£ÝÅ?”§Úžß¢léòÊÇï´©+‚IÖßå’'çý×7úuú¨ò—CQsQz" IXg‰òi%öwûÜo˜iû~7“(m¬3¥µuo™Î¸n¸eì³ Ûñ½ÿÍîëBùÛ X¡qç)÷<ŒZTY~Õ~éên—0 ²@£#ʲ D00mhmÑ f6B„ÛÏû}ÓŒd¶iP¶É‰•Ú•=¯t~4ö¿têKòÚïºehl_ŒãÎÁX§­" Q` ŠhÈ~ †ôý-ÆÇñÕ$3ÆPƒc\ËuðÎx-þƒDcÁ´˜,…¯‚±=Æ•d" ù%Ü{˜ß|³NREt6 ˜¦ÈÏ6“BåAfÉ/õÀ©œ™™-¨÷c°ß;þH›ú§š±Ì6\„pžÖ6ŒáŒÄqõ© DaÒ nã/ÁïJå3Ç€ÙÃ~V7ççÎÅT†c §Ž4.\àqBàTgz"Ã9Ç,ZïlgÐ'ïÙíÕøÃb7¤Ç¬úLy6,Ø'Þ~ô#W÷ ˜'N<¢pC…Ó,â§0ì8·˜±™LPàÓà¸Æ;ŠqÈÞvÛm){ÔÕßúsç3Ù?W£]â࣠¦ûxQ£uëÖÅÚeK4‹7X¦ø¾—sšöo¾àTÄpHÒwãœLg8žN;í4×pHSNøpÃË9—/ã˜r­ÄŸÊÁÄ.ÌÚ÷„@AáW.e„ç¼S”¨0#* ˆ<ˆ(ê!‚ߘU4û·›PPà·ãø 8àÝ—þ…ñ¢Ú6Ç‘F>|¸‹XáÓKöe;àúÆCçNĈ›͇²ó G{å7D-ôÏ©ÄÔm­uÂû6N»€_6³±}ÛK%(ðœ8n\S8ŸýÃ#åGd‹¨€cˆ0Á‹èKXê‚9©¾\´Y΄5(ë1ÊFTú“fP”FÈ5ú¿÷åÏæ=Ê6MþQì D>éî)³É‹þ€È+œ|æüˆÚ(9ä5¥'"˜k°×ªuÎïj»¤AUG{ïóGK¡G®Ÿ=ßpÜn¿ß4>àÆQª:ØmÚ7 («l/&pË"Øë&V yTw²âGDˆ2¼ÈŠ/ްBeÁÁ :Û(YM«;vo[ÈE~hdUo¹²ŒiµjoÍí2c8¹¢]0»~Ê”)Igèº ð\˜åÎÁâg`‹äcÁïâ?s^r. šðNï˜ÏdïøtƒÓϤŸì&1xsŠàçx*c› ‚•ý9®9Æ^@zkïˆN•¾ÿ_„¤Ñæ8÷ò-*งq8r¬ƒÂ—(EÔ^A‘ Ìö c”6œ®0Žß†<Ó9¦iÃô8µ}»òõÇ 4ÔÖZü9à…ëïa,êvêG[dö<Zˆ ¬µœà,OC¿ì²ËRFDâüeV¾ÕÀ§z6‚GÊ…Ã5]¿3ßG!~¢üçG¦×o·cà?Žç›ï`@O£/ =!¶ò¢ÊÅñOgù¨?ß”±‚IŽ)×Õÿýßÿu‘˜pžåbQ¶\ʑ˾ôßñ¹\Ò îËqåŸO£üåG>)m\ÈþÃV$p쨱.qÓ Õ¸ÈmO¾7á¾×-‹`… VlЪí wUëvö¢l_qVy´;9òLƒ}†5v9D VlPÝéD´·ªlÁƶ†ãa#HÔ[Bu¢û¡¯8Sb¥v¥ó#®[pª/Éo¿Û¸¼O"òúND WŒI06ÅDœ ¨€q&–²ÅGÅØL2ÃWÀä ?.ÅvŒ0¡ñžõGõcˆ›÷K„úqFžÝ r÷¾É2Ó÷" 9(9QANµÕÎEA€Áú ƒ dzwH&+ .L¬CŽS1ÞpòºhÞH7ñDfÂû§3êtt¦Û¾Ø~Ç!á×§l8,¨w±4BŠ?üðÃîXp¡&d<ëpÇ‹ø U¡ŸÍ…ŸYüa;ñܸ!@¤€3Ÿèeæ¦A³­3µlXжX¯Û;É“ºá»é¦›Ò:23-c¾·÷ÎtXfzÓ.À¦aüh'8t½³ŒA”©üFßào }š‰úøÀ¤¹lÙ2×F&$2nJ™Ýí4µ!/*ðÛQ.n^ó›ßø¯R¾#  nÞÈ—ïüÌzêCØ~Buñ[:#œ'8Ÿ™¡ïºpq RAºðû¾-ýŽã§,mÁ߈…-ûÆ;ê‚7ŽÉÒñìY?}éÒ¥Îñxç:7’~†²´øÞÚ2!à9¤ÍÍ(ËPÄ¿#x FÑ }&PÎoüͱ:oýo‰Þ©+"oü^PWÔ¸ÿùŸÿÙlí1¿}ü;â Ú^T¢Øoì9~”1áü]³fãL_à ^TàC–ÑñéÒÍæ÷(Û0}ﳂeá:ƒ#×õBÜ„¨*Œ¥kaÒH´ ¼y"J×À`[åØ" Š&âÓà8­^½Ú¥ÁoœÏDQÂI]£ï FáÜ *Ó³)C¼ab0G˜4¹Ö—Y¡\ˆH;x¾„I+Õ6aëªÿÖ[oulPâS¢Q äoDJgŸ}¶[N‚w¶ÃZK·°åÔv" " 'Tµioªì z7ãÝ:³½Ó¤Á†ìo`™ƒc6t¿ý¾š%ì¶öFßTµ³Ÿ[µµ‰T™ª¶'fŠÕ9èö!õj;s¿Šðýö¿ò¨?h…´VXPm#5¸%$XTUÓ2N`éÄì×Ùí-[¬Û4E|¨¶lX"çÞ66êC“óªq ¡Kyˆ•Ú•Îõ%MËê O¬³“:¬¨«šk¥]¨Q,†˜®IÜäzqý'"5&A1ÁØ™×%„¼ca $‘1Ã$FÆÙ68¶Ì¤^Œ[3JÚŒ‰1Ÿ«¯¾ÚE2fɉ ‚tôY¢%ø,Ž6¥&Ípñ.Ë€sëÖ­î•jœ GÐñL]&Ë#÷­´Ï8Ƙ‘êC}3ƒ“(Á™Ê©˜0°‚*pÚ81/¸ñÆcÂ.þ8<‚¸y³}¢üɃš„{öZÊκLk×MÏæøgË‚6ÌŒÐo~ó›fþüù.Œ74ðÀ9Çw~–Ô¨©©±ãr•ó𒪮´ nüqçÔ',ÌÂ8±µ ÿyÒ¾¶üà?p7ŸDÈøáèÚ!jYnnqÓßz롇ŠEÑ ³€õA”-8ë™4p óÊÔ('3‰ƒQ`B[äÆ(Oðæ<Ì>é¶¡ ZªcHþˆ pf"ÌÀ¡M4‚L)ÁüŠís¢úÃ<è즾8™³™UŸ¨dÊ„ˆghÓ>ÂÇu8b1W´ýdFùIà ¤¸Ðo%»Þ&K'Ûï1E´¯ è&›t9V~yöçá4ÓèB”+È€óžëçi”¢‚°õGÐã;ßùŽSé¿üòËNpEÿA»|á…Üq$bÇм‡)kK·lޱöJ'P…Û¾Nz°÷' „á?|Љ ¬ƒÛ‰prÛÐý Ã÷æÿ`ã}mƒÝ® !ƒ ÈÃÔí³ìí;™VÔÛbb '¬HÔÈlXրà Î@¤ÑÁþbI ·ÛØå)”‡X©]éüð}Bì]}I^ûÝ`VÌÕÐÁF3ìЕnÚöírÄÚŸ>ˆ@ L›6Í™ 8n‰€ÉTLRL5~æ™gšn¸Á7.Y²ä¤±bÆ?¼?ÃWñ/"|êSŸr>Æ7éùíõ.";]Qsg¨2$Àà¾ûíwÅ9ÂÌù™3gú¯ôž8E¸øÎ›7/–:óLgùã€ÅaÁ¬|f8rs€s‘âÞYÊwÌàõ3”9î8v³™½‡2ßsÏ=1'0Ž¢ÜvÛmY­û nN%þ­o}ËœwÞyn†°Ÿ±ÌMŠJœ¬ˆ KÍ‹ÈDw¨ä/(¸ûî»Ýò^ ŠR–Ï Zm’Öí‹v„@%!2¹ôÒKÍücçøc_o(d'Nœàläæ” N=”´_ùÊWNŠºàó¤½xc{Ö²?묳üW¡ß9¸I.B[¦Oœ={v³›îD‰Ò~>p.µ„áHgyÎÅ'Ÿ|2æÄFhC¹xqüè#ü1¤G<’£%ê˜*Ï`; Ž<!0ÊÔµƒ°iЇ#&ð‘ øp.Ñ/ZŽwÚš?ñyP3œ'ÞXF¥ iA®”¶¹éÑßx ¦ï¿K÷Î>ñBÎ}Ž]Ô,_ªúá×ÙI“&™7ÞxÉI¸æÐßqýáZŒÀ÷/|á æºë®K), ïbhQ3Uz" "Pölÿm]µÕtÊ‚&¨½WdF¦ À¿½5Û‡ï›~³Û°=ÖìY¥ÙöüZ†yØzW5Ø—aÙêØd,[à ŽÞª¬‚;4Û¾9[%Byx‚¶ÙÙŠ•£v¥sП!:?IäØïVÙsªñš×·{Îzˆ`âSp̈{A¾‹Ÿ|Û!Íƾ+còK0šc³L"IeL¦`<ŠI!øf¼+8fâ÷§ÌŒ#““%We&©0vãú0–’®>Œ)÷c&À¤ÛÏç|O´_¢ï‚ûè³”‰ JéhýöÎÓ¿ó¹Ý·çMO÷LÏLϨ§çœÒS÷t¿÷î»ß»¼×÷û=çäȵ² ‚Œ”W—1áCPAΔLȘf¥„m‡l ×<H¸wHΩÇATmذÁ…çæAŒñÞ{ïu§Â£ó±Ç‹ßø!‹ c4Õ›1$ÉO<áˆbÈLÌ?düáþárÖ}™æ3Å‚‡êq¹ƒp€PúÞc‚a¡û@îA±­]»vÊ8¤Y­¬Ý>ƒà¿üË¿Èþ纱O_€„&ê=)%xÈâAŽ>†¡0ýó?ÿó´DˆOð¸ö›œŸÖ={ö¸-8à<|~ñ‹_LÙ—¸–`Z2!õ¿óï$;償q,Ǿ~ìÌg<ü’Þe²hþa˜ç¹6p%úmøÓŸþÔy¶SÆÆF§f>ð¢ÚÐÿ(!Å÷¾÷½y/*`Þ †Ðç^Ej Ä(Sµdý`¢s€=â ¢ÐÇÙðF_÷b¢¤°1·ûY²ó3OïÝ»×E á{Ú Ow¶¹2~dzQe&â<ëàÁè Ì÷Ì%S1®+(f¢Íˆ†’ég”©ÖŸ6ET@T~lÓ'Øf"$ âó^ô®ùöÛoK€È†>¸{k†€!&‘¡>‘¾någ‡£‘Ôk^­­[¸¤Z"…ú7÷DÀðØÄ3V£ :«g>‘ °û–LjsR%ÄÈò…PF¨¬V±q©"| !rAO‡~>¤P‘ ACgçE§CŠ­ÉAMS&ıê×¶ШcúÌF*)Ò¨Šsˆ}¬Œy…Õ‘§åhS«v‡|÷<¹´¶B*J뢿߭ÍÅÆ‡óù1'Ö»ù8”¯s·( •îæqûÏ0ÜúkAž£a̓unÖU¦c÷©O}Ê­[pNÖ³à‚H³™N$EÖ·Xse픵ÒC‡¹´Ë¬s°Öε²–˺(çDTÀúÇaDœ¤|¢Ôâ(B}à=XÓ™ÈX“Æ)ƒãpRaÖÆ(oªÆ5q.œ«¨?õ&"èt1jù¶¿!0Û˜¨`¶¶óC€IžÉÏaÂðcǯ۷o·hãËÜ?þ¸» sVn¬ºS½ABlr‡¨ ·<ƹ!ÿ!g1Â1C|a´9dc²Üön‡ÿyOó¿ÿû¿wžÎìÆƒ>‚‚éxŠû¢2‰â‚­[·º‡.êH_fƒô£ c½¸€ëçaqèñו«¯<ÈA.ÿÇü‡{P¥žýë_ÿºKaL‰Ä ©©É‰7‚Ÿ%{iˆ7ü¿ýÛ¿¹ù„6!5øÓG9d›ï»Dšà”öBÌD¤‚T‰·bÅŠø×<\ò0KŸÎ”ñ€ÉÃp6ä'}úpXÒw¹fÚÁîÉ qÁTç˜dç9ߟÑFÁ6§OÓeúùñáÐÏ}ªÚ€¾ŒhÉ‹ |M&&ð×ÙÜÜìÄP´-ƽ™1‘Î=Ž™¾Rv0­e37ÌÄ8GPDS0w€7ú0?2™C2iÓ­¿Ÿ—˜Ç (xòÉ'@“ÝôÏýû÷Ëý÷ßïúBÎd– } ÙuÙg†€!`#ì—H¯.Tjx}Bõç!P4ù]Rô¡w'Ѝ÷kd [Ér R¢\ŸÏ|*º_Ã÷'ÚB(#Tª"C¨éÓEp.;FLT&ŒvQQKs Çê„ µ=ô‘!äÒOŒ_”·2ß,Åjû“Ë+»÷°ˆáž‰´HDM'êÖϼY›Ûø°q®ÃdžÍ‰!áÇd{5 GʳŽ7Ãk3Ð©Ž£ ë*ž ‡ƒ˜ÊzÊêÕ«Ýš#k9l¬Ãr\œk>ÉÖ)Q¬Ô"?5.ÄŸþô§¿Áz ¢‚©^³ïNê|Åú‘Ç4ÝkðÇÛ«!혨 Û[(G¯ÉŸ‰Ïnú†…íýו-[¶Œ!r‚9¯7R¼.!þ½¡ú#ütŒ÷V%Ò 5òròäZ‡ &D!•1nž^S!Š Z%üÝßý]\¸À 4 å§k™Æ‚ëðd5䂈9Ò¢)RAàáÍgàá£J?]pºu>ßÇQú„Ï*cýK_úÒ˜|êÓ½NÔ˜Op@´²øC$æ/*ð QHX¼wY"G9‰™'ïü>œ“¶äÁx¡ˆB¨;ãœ1îÕËÌãôsÒ6 âÈucÎ Õô9Ä*³Ñ˜£è¯ô]æA" 0ð££ß!`$ÒB%~N¦¼¶ר‰ùc›Žø+xNÞsíS1D> Çq¿H%PI÷¼‰¢pãÞD›¥óc’rðò^Çñ£p2›ëúÓnè¨èkjjÜ}\©/b.DÉ"ÍV˜ #ûÞ0 CÀ0 lD GŸÞÝÿ¾:rÄ=ÓòüÈoX<&S‰à³±vM†€!`†ÀT`v¦B‚ÄòXÛa›‰±ÞÁÚÛT ç¦TŽ‡ãˆ › › L3q]vC œwQDä}÷ÝçêÂb8 `ˆŠLZ®”Á¢øO~ò $ž¡ó•Èaqžp¹½§;íÄ{úÃïþîïNJôe²,„sAêâe ¹€qs#ŒÊÁéDëªU«)ûì³ÏºÝ>Š@Rx£Ÿ~üã÷NúŠ €PÎ ^~ùe·?ó?æ¿õ­o¹”“žd‚2E°(OðxqÞÃ>rÁ[o½åòIJéÁtd¤ „ ããsÑhSd¼ñ`‰@$Sk´)ÞÜ"˜!º„äó‚èCiÊëTˆWÎG_G€ÀyýyŽèB©DÖ¯_Ï.  Y}ê*ŒŠ—óõ>4ÕFóDµïô9æS6Ô™0ú¢;v¸ùÁ‹ Pdc”(†±ãÅÉSíÓœ‹öD¨€°ãÙ‹{B£*ªgbàrøðaGâO}ƒzáMÏ‚­7žoï?C\øõä:ý!ÑdÆó×ôúë¯Çwåi:ãý|ÖáÞG?úQ‘Èß;‰ÊsìØ±¤¢‚Ùêqвø ÷aÿœÂ˜Ú¶m[R/‡™Tg."H`ô¢+ez¡&Wʘ Îv¬!°P™ ´FBÍOOHv}æÅ"Ã"ý=ÑWý,LjR Š_#„ñ¸'tÁhd‚ûô¸ã]Ô‚"·!—V!×Ë %©!‘"m¦; :A¨¬ZBÚ÷¬Â£ár]¤0V —袳 ‡¯»q,‘"ôYÎE€Ðg6Œh.-‚•1/°j:Ù,=DÛÑ[qQ¡G4ªW·¦Ò*ÕHÖæ6>lœûá~“s"Ñch§‚BŸu®fNÖ9š{›™!`†€!`Ì ó.*€húáèjÁBòÍ7ßœqQA®”A¸c  x‰ÏW2b„Åïßþíßv ÷Ñu$<:†À2Ð,3@,<üðÃΫ–3ÒwH_é:]cÌ"@T€A±H¾O}Àù•¤Â{?ƒÌaAžç¤.„;‚‚mºð?S› ,¯‰> Eh}<òàLPO¢s<òÈ#+æ¾?ýÓ?uBÄsåÂßú>JõŸÉ«D8qâD<âÅD8Ï÷-„ý’~ùMyô£é}‚’ð]°,2á¡þ?ÿó?òÝï~×{:çoÇÐg}”®oùÉ2VHë`xûùVo½Ô²!‚ú‚æÕo~ó›éÜŸzê)ùþ÷¿ï¢B$Š ˜KˆÁ|I91¯mòÌ3ÏÄï ‹-r‚­™Ü87Ï\IEò;¿ó;cR‡ø²ye>}Ú…ì÷õdNX»ví´Ånþü@8O£Þ{8`Ì%ÜŸH;Ã÷ØŽÉGÛaÿ 6¤%H8ßõCž½1NSõ“Ùê¾ìl~¥ïùgjÆÏ-ÉB'Τ<Ëø2ˆÎEß›lΜjy¹RÆTëmû†€>K«¨À ÁÐt#¤EP¡ßG ÈUT‚,WQ‚Dsi:›ÝÇá²Z%ÅUp ÏÎ ¡ŒHW‹`„4ÅAB Å)„8@É,Ò£Øz¸"ØP’*\¬¢ak.…„•íƒó«ã纥·?*ñ-¹´¡^ÊBéj–é,æA=üµ_­ï’*ÆÆùB™¯FtÞE0†ø+„¸Î¥ýˆdž½7 CÀ0 ©!0=†ejeØÞ†@RX¤‡Ô†`ýÁ~àHVOÒRŸ°Ãx¼ã9™Y@ˆ_³ä€äó˜uÌ” §]®¿þzŒ‚œ€LÁkîÇ?þ±#u)‹Eú›nº)­°CÈ{öì‘ø‡p„¤D0éHyp뭷Θ¸›-,¨k2kHí[n¹Å‰ ˆHà#J¢ÖGx¸ûî»sVTà½ý=FôÈꟌð¢/€ä*^¶“D $⫯¾êÈJˆìï}ï{NT@ÄD4\ûQ}“4„Ñ‚„K%r  Ù‡T ò'âRY@‚>ôÐC®MG“‘QÌmòIíž© “á’ÉïïÁðÿx93^Sµ!ÞáxÜCªyr6“×3×ç¢4*I 9ø×ý×n¾#¥ ýÁ sáD÷*®w²~@ÈzÒ¦©£Lú(‘ 00&3î€4ÿ£Í Û½'>BÆ Äj& \î¿ÿ~wý_øÂ\XþÄó2ˆØ‚°Á›÷´§Î31Æ:óâÄú§r¸#jB‚XñcûXRQ&÷IÜÃ}ôÑø%ö€ç‘tSødºþÜ__yå'j™HLÂý²}D"*ÀÜ—,bÄl÷8xöÆ0 CÀ0 y‚©ôp@ÚŠ% ú[obAjp{o†€!`†€!`ä2ç]TÀÂ8 ôdžÏ™¶\)ld !Ê¿úÕ¯:¢íç?ÿ¹#ëXÔommu‹úxƒBz@à! iÃb8‹ç„(†œ„L ÚT½-9'åùüÒÁs¥zOß"ìuÐ+0Õ¾çós¼… £ Y‚Ažâñ =ëcrpC¦Aa´Éÿ÷ÇOG_…À™ÌhwµþçvdäƼ€‡(XãÁ›ŽÑ·è'¤KH'³…Åd×åû;ÂB/. ¢Âêëó¥Ov®ùø=}ŽvôF;0Ö÷.|®+p`üóÄÞã?îÈ[\ªWæGD<¤!º-þ›yy†ï½¨À èägüzB•ÐèÉ"À°ïm·Ýæ®Ò—ë„”ý«¿ú+7i±çÃ3ƒàC0BªB¼ÓΈ 'ñ4ŸoÆüL—Âü¬Fƒð¡ø}ê"ê0ß‘²‡è̯¹`ÝŒa¼ØL ~¡]ÿßÿûîþ ññŒh:ýìXÈôb‚Í›7;Qs,bún&Œ¹áÄ>Æøc¾¤ÏÔ¸vî Üo~ô£¹WÒ5úqõCINd"_¢næDwÉ„1®.>ñIJwï^×V¼"Zƒ¤'Š ÷@öãþCŸe¬2¾é·¼Ç˜[lݺÕý=Ù³Q®å/ÿò/èŒ>Ƶ3ƒâ$DˆqÈ÷tþJø<˜³Ù©‡¦7H®;ƹ xQ'97$î%—\2†LNU&$-Ä çáÞ íÞyç¹Â6Ù+ã"™è÷A›M,‚å¤zﯼ××]w]<-‘9‚^੎Ÿ¯Ÿ3CZB¬ ¢½‰&€Ç7Ñ-˜˜Ó ª!ð9bBF“ }"c?ˆú¯ýëòññpû^¤€Pa"£C&"`íç æÄ¿ök¿æÆu:ÍFýéG\÷BÆX"* Ÿ1.™çJ01Ñ'é«D(Ód„ùlötp:ßûÐÏü35ý/ÓcŒúÑNô3ŒçR¶\)#Ó¸Øù …€@d°Oñ·ÆB÷—K^¹ —”åék©¦þRÁœ2)ú™njˆòÞNMСŸ…%ÓqQA©¾W"Óg^·éÛ…PF¨,–æÀÕ;J7áîì±@6@€±¥k,ÔC f³¨€z Æâ¹÷ÊN·žíÇ"9D#çL S¾xõω2Ò?h>L~ð³tÞCèA^E³E:×å÷¡ÿáÕŽ¸/XÈ"ÈÚ\5OBú÷»ßuD<íA½! !é/´?„žÃDÁøÄ'>!„ç˜tŒþâ¹R Q"%Êcã=&ˆ8<|–âûÚ×¾6N¸éñúío[~ö³Ÿ¹HÌOœÃ‹j(ëà¼A mŽ0ŠzÍGc¬oܸQîU!àßþíß:sêˆÇ;ÒÌ…Œu„!xAS_ˆb¼Å!8!rsÁ˜[¨}†H»víríÍüçç@°‚žj?C"n na>˜ ¢ÓßSìa\+ãäÊ+¯ÌHó@tßsÏ=NÌ{¿þë¿îî1‰×>Û} ±¼lü›{Òl?SÓ·ÙfÓr¥ŒÙÄÈÎmä,N4 Blõ²' AÜô¦l¶ûÿ,þF÷cvwÇǾÀ‹3ʹÄ÷toBJü'50uXL€„RáFRsûÇŽqÇö¢=¬Œ±e)V§šÎJgWûê/˜g…E*.(RÑ[þ}ÍÒzD¯‹qn}×µ–Á@§½]È}w<ö‰!`†€!`L¬Lñšm÷D€p<ï÷~Ï…Ò†Ü#íd8„ ੌcñ $O2iðÚ‚€¤˜ÈXŒ‡Ì…Dd1~:æËžÊ±ÃSt r6£N ÎÀ#¢£Þ[·nMÛëÒ4ÁÔòå?øA<Ì9ŸÓ¦ˆ Ò1ø!Ô…@ÒÎÔÀ•ë Úlc,+Ý÷à„¸ •ç:ämÆ+D;¯•Él*û&ïÏK?á=}’k›Ìüq~?Ž Šuüç¼rNHCÊxòÉ']TÞCˆáEì㿤  _Öh$œÒ×dãr¢íûßÿ¾ë?x…ô*xÉ#"€Lô¯Ì)ˆ ˜_H“@ˆ~ÎOÔB¶#L"’DШ+äD„/BDP'OžŒ/êâÇ6Çr ã‚Rv&ÅB¦ \  )~ÂxJ†S²r÷Mü;x }õ“Ÿü¤Ã‘ÌÓAÀÓ‡±ç|8}Ù­:߀±oCÎOŸNf™¨×Ãy(ƒ×É,±¾Ì©®sQ?ïåL?@X@„Hj/Š‚Üõ¯?&~@r›M£ÓþZiSî…´Ùt ŒƒÄ)c5DY€˜衇œÀË߃|àéÏ8#iP&Â}:}ƒc{¿õ[¿åž~úÓŸº¶âüxAûƒÃå—_îæ*DMÌÙ\ÔÑÞïÿþïDZ$ª×Ï=Í 0¹F®…H´'ÂR¶$»_dºL„}g†€!0;8ï÷â iqžô±gžá!qi 4Ìsœ0üšÁ…ñ/*•è^úþh$"iÔB|î"ÄB÷çzƒêÈ [HSEHa,L6JÊc‘Ãðè²Y<´ÿb+S©üI9'D+äÊ´%$*m’ŽA†@¦ýñÿq<Ïw:Ç¥Ú‡k‚Xñ6WXøò2õ ÁIødR„ÐO!܃õ –3•}ƒÇñz<ð!«h <—!'3Æ¡àikÚñȱ©Œþï½÷ºèˆ‡H#ÁE:Ê…d\µj•0¶ü5øúC˜A BqÀ?þã?º9ƒó°é/ Õø;•!F@@À¼ÑJ?Aàðâ‹/Žøs@ ^{íµ®oóJú¢+@T"(àœ£ôAÆ‹Q^TÐØØ8†€õçœé+å!¦¢Î”O{Bê¦c\'ûþÁü#Â㤹p>ˆâ/ùË®<0CTAÒ?½˜‡\QL˜¯7lØ¿6úót2›I=À˜ˆ7ÍÍÍ®ß@ s=“}ê‹_ü¢óÔ§ýéÉrÐ'žܶnÝêÂЃ÷)p |+ô©¹î‰×˜ø7õcŒ?ûì³ñ¯¸Î$õA°ÍRо¤Â q_ ÙOŠÆÂîÌ„ð§pÏŸhœr±Ár¦ÚÇD…¡<ú:‚EÚË?SÐO˜Ë˜è»Ì¹\W2B>\ìMðºf«þÌ#ˆ¬.»ì2máàÁƒîú™7)“k@”Çõ3Ç Ô ®ÉúÿlôDLìoCÀ0 9@@Å!Çv*EB¤Øó® MÞ£¡ûz•ôÒ¼Òeuê(Ÿïö‰©¡0*Nv‚ƒØeFú{4Ü4UX¸¬Z9t%aø=½Êð)$Ô=/¿AI§°’PúüXBZ„X„D1én×´шŠyÕK¶ –âZ®¢%œÕB´E,‡÷i*ºÏEÓTX “µXoj•޾Ѩw´%¿ ŠFd¸#êô`mnãÃÆ¹Œy0'Žt6ë®N)Åešºd±N=:÷ 33 CÀ0 #0úëhƧ²™AAÄ)^ÆlÞó—Å„ ,”CèCPB\xâq*WÀ9X g›Kƒˆ"/;u …´€t› Ã+›Ó>¤;u†ü…äɤq^Ή×.õ‚\†äH×Sšk¡ÝiO°™ ›+,2}íô H.Ä` ¡*ÀTöM¼N°ÿÆ7¾áH6Ú‚~9ÉÇ9¸<×!ï«ü=Ùxä{B­Ñ D#búä„3ï½AÊç;߉“´A¯höaN@@wŒ~Çõ%c²:ÐO!ïºë.'*àxú èDÆy!Eï¾ûn'Dà„Ê\׆D7HGè4Qy“}&¤&`|Cfówºã !iJæV>›ÈhgÄ-`çÛ‚“r©3D}° ™hCúçNÕGfRú Â/n þ“µ?u$ÒÍg?ûY—jÂu¢ëKÄ„1Çb#Ç‚=}€>Íû¹î‰×—ø7s)Gìa\mCdéZ°ÍœÓ·/cÑý1ãœ>Æçàô“tÚˆk –3Õ>Îñ\õ„lÄCDkàzhGîÍž˜O÷š¯k6ëO¿dŒ3o2ÇpýŒ=®̹væOÆæDóÍlôp03 CÀ˜[q‹;0¦d}R Ã*4ÐߘJª8ƒPqaø“üî$Ì?ûcú;ÎÛ‚(ƒz³¨ì0° fÑcÿ{lùSË{ ¹ßóɰÕsZY-ìØq鉥àôíŠh¹´Xû†Öæ6>ÄÆ¹î5[çD®‹H>lÌíøéÜnf†€!`3G`”µ™ù¹ì †À¬ 1yÇ–+a1Ûy@Hx ²Ó³a´ät6Ú\c‘I ˆ ÔØ&³©ì›x.ˆµé´ý’pªFyÐlu‚èfKfôï;v8R—ï!߈rÀùÓ1®âßå qÿyªW9!ñÙΗqÔmªÌ S j!åÙ&2®-ÝsϤ´ÄêTÍ“ÊS=.¸¿¿nÄ lÙhDQ ÕD4æ£RL§Ïë7YÿaîbQv¦æ1žÉõræ«U‘"S6Wõçz¹~ÆÒt#ÍVÈ–vCÀ0 ô "hhýxè~Jà¼ãUHÖhš?NŽ«¸ ÂþŽUÒœ>t¿¦<kšÌ}»„…PF¨HÓ(ùäê­ÏÃΔ„Ц@`¡XiÚy€”>ÊC[Ý+2¨¿·G´M”¼ å)¶.ââõŒµ2Fûa–bÕÑÑ.Íu¨7ž¹x¦/«®—p(* ±6Wtl|Ø8ŸsbXç]w,еOËΘ†€!`†ÀŒ0QÁŒ!´Ù‰^³xÌ’»Þä-Ü Í ‹Ünq"~àîöÆ“7]CpBxvo sÁÄ—m¯†Àl!À8!ÝQ=0J‰ ’nšŒÙº.;ïÜ!`}`î°¶’ CÀ˜u4¬þˆ¦9a%Ä‹ˆ0V­é TX‰]R)¡b%T Rbˆ>Dú:uëRR\ÉóÒ •è¾D9Ǫ9Â<º_@¡r7;/VRHDÉ%žF4e¢ ðå+N*¼pø”ªxÕGpØFÉ*òŠGs‹k¸íÒj%ÑUhÏùô8+C‘Ër¬Né32¬øé ±=ܪzks—bÅÆ‡óù4'âô ã™û]ìžá~éÓÚøn¯†€!`†€!0eLT0eÈìC`~ €÷ö®]»äÈ‘#î‚!J ›¼fÍšùQ ^¥a‘A0³ðTx§~Þ"G}T¶lÙ2¡7/‹F¤,xä‘Gä©§žr‡C´âé~íµ×úÓÙ«!*÷îÝròäIW¢å¶fºï9Ê«„õÖàV]CÀÈi ¾e¨_=êÕ³Â6F†:Á@8* €’+¥ ¢B¢äkhè˜9ïë$áþFQ±€Ç½"PAÃ*œ/a/"Ð/½øbÌþú‡‹ê Ñ ÀŒ÷1¿X@ÄFÉØ1ÇXY…ÕÑcG5õAϘ&ºà‚ \tIkó1°D6>lœÇºEÖŽdQ+syB¯¶? CÀ0 C` Ì;Q$Й3gÜùS[[+<ìgÒæªŒS§NÉY ±FØ\BGã1˜IÃ#ó›-LðÜþÅ/~¡©£¡ú÷ü±},í𹄚a‘K­9¾.„BG@zD)@$ÀߤAX½zµ»Wø\ãô‡¶¶6G®¡€}Oœ8áN ÑzÏ=÷È¥—^:¾ ûĘÇð<ðÜsÏÅï ¤úð‡?¼ ï ó¸gté¹Þ˜Ûßyç—.«¡¡aFX%L8ä£G:/FÒO,^¼xZ©VÏü›ë?}úô¼/#X'{o³‡B€ˆ†u&¼þ¸Ðý±\Ò!¼3à1OÔ¼æ5luüóØå9BÜ¥EÐÝäÅ¢,„2†I!¡) Àˆzƒž­ÅúY8ú9©$ó™©Ö{Âýçª r€³À9Ä×wÞ9áuMõKr&¿ûî»S=ÌöÏÇ@®B‘/|Ó¦MŽ@Ê‘êM©†Å”àšw;hÎÒ«¯¾Z>÷¹ÏÉý× ‘) Üwß}ò /ÄE, !âêììÓÆ¡êêêLŸÖÎ7O $ü-·Ü2O®vv/Ó°˜]|³áìÜg}ûÛßvâˆÈ¥ÖÖV™€°Òl,úTUU¹¹‘WRè\vÙeÎk›hná(*d×`džn¿ýö ŸÕN7ŸÈõ>àEº55ê]šaCȼ|ùr'( 2)¥2m\.”‘i\ì|†€!%K„4ppú»_ðÀÔµçI‚%SòÕëÞ“(*.-‚ŠØÏýwz¬ 寧rb_ä(CThAšƒ°O}@ÝÉ»­‘¢D”bˆ< `)rÑ n„Úæ8×úy,ºûD¬ ý![±ÂÙa_ÐxfbÝ‘ˆxôùá#GäíwÞ•C‡HSS“ôötË F –‚¢B)-¯Ðç†r·æ·dÉbY±ü¹xíjYzÁ =Lˆ2AÖ¯l Ò7m.™Ú¼ëÒЩ 83G›†€!`†ÀŒ˜w¢ˆ£«®ºÊy×Aþ/Y²dÆ $ž`®Êؼy³[<¤¼Ù¨iðD43 C`! À\J”R ¨yï½÷Ü‹Dl==ꉤ ª•••cD^x¡‰ B±:†@N#@$†{î¹Çyfº¢D<"å x° ÓÆõçB™ÆÅÎgÉ ÏûH_§#¿ÃšÒ TZ%¿!'Iy@„Hoï=Öý»$Òß­ä”F!(Ñ}Š£Q BÂß‹ \ZDj ¡Œp™†Å†hB”áE*¾îÖÐÙÁÁ ÊÕ$†c¸T6[`ŽŽb5¢¸’F‚så©wºh RX¤š+#›±:zô¨ô&¤>@äÇýKÕæM§ŽËƒ?{@^|i‡´œ;§ABR–§Üyø‘Bâz¹xÍZÙ°ñ }®ø€‹¸—ª ëW6m.I=':o#¦ ¦£Q¥O|,ÚCÀ0 CÀ˜>óNTÀàÆÆF·M¿Ú9We\tÑEÂ6[ÁÆ!3CÀ0Ìáx‘^yå• ©ÚVWCÀ04DŸÙ²eˬ`@T±Ë/¿|VÎíOÊõçB¾>öj³‹€ Ù߯"¡AÊÌCD ™ °t\ák]Z"DTlW¨aÝcÊWP¶[e<Ötˆ*"*6—FÀ %ÁØØWhŒ¨!AÔ®C -¶³2²+DˆÏƒ¶råʸè3 CÀ0 CÀ0 CÀ0 C`A €¼’ÕøÉ‡Ô™À¥4 âˆ4*A÷†ç½ ·>çÆB.ê€bFD+ˆ×[±Š(V.zA ¾#-‚Ëq /.Åت±í¡©\{D?âê<Ø­ 9ŠJa5 é# *(-™)ÚüTÓYéíïwu"iõØ ÈÐàô¨`¡WNž:%íííc¢´¨aûöíÒÖÖ&¿þkŸ×”k„tK‰ýª½»WÞ×ô ‘‚“R½x¹,^²T*ÊË$Ú+­_ec¿²¹$æÄXDîcn×kò÷¶èLdÿ†€!`†À40QÁ4³Ã CÀ0 CÀ0 CÀ0 CÀ˜kBÅRzçñŽ'|Œ4‰hÈþi†4l¸~&Åî«1ø%TD4r¸kúƒBý,f#š"LÁÂê¹"|¿’ì ¡Œ‘žv—Î ¬‘\ ‰X„P,ÍТ$o¬á^Ý_±ÅòØ'ñ!¬ØFH‘€¨£@£>ÄÈ«h ÅVÅ VF4:F6aÕÞ7$­­­BoDü\¶lYšžÂÊÈ^¬N;+ÝÝݾ¹ÜkMM°¹¨|’¢Í¯Øx¥üKø`Ñ¢EBª$ ¡J¤ó¬ëW!úU剨ÀñÂÛo¿->ø ¼£©¢â”¡¡!yñ¥WdˆÕR³a]TØèWçºäб“ræÌw~„.G”¥¿~·¬XÚ`}7€•A×EFÿKÑwÂ|A¦b®HI…„J*– ä£ÑŒ"dï CÀ0 C`˜¨` Ù!†€!`†€!`†€!`†€!`œðˆ÷aø²  Ý…ñG@d„xÚ{s ŸÇ¾#*î9Ï|÷Nÿ³?æ`àÑMHûà+NÝGFÿGoáVÁÆì?[%ÂÊð&`{~±:z쨦'ˆŠDü^°|¹”••ù?µÛ'osRT¬YÝ/8ÎxŸÐ¯Wuuuò¡}PJ45Â?Ÿ;'‡Ž—Ѫ©:&ë5ú€úUÇ?§ÖÕÖHa!F¢Ñqy@£tiäWŽõÝ0Á1{~ûU° m.Ñæqã#Ö¯“ŒX×N˜f6ï†tÜFïY s{¼0{c†€!`ÓEÀDÓEÎŽ3 CÀ0 CÀ0 CÀ0 C`Žˆ õ©u·òUÃÑHê5ïÂôçåK¸¤Z"…ú7÷DÀðØÄkU£:¬ÔD.ÀBì[#pH•cÄB¡²ZÅfÄ¥Šð)$„È=úùP4j¡³I12Š­ÉAMÃÎDZê×¶èuB Â~K‘F-@ÜÁ>VFÖbuüä©q¢‚KiZhÔš9“mÒ~uåºUrñª•rúÔIéëF+ œãgÏI_HÇbB¿ZT^(E„mµ®®néÖ´ ‘ÒZ7þ§Úw{G¤¹ù¸ê¡²8OJtø;®×ú®9“mnsIÄ¥B˜û9±ÞÍÇ¡|»½0,–ºft$Ù;CÀ0 CÀ˜&*˜jvŒ!`†€!`†€!`†€!`çÈ`¿DzÛ\x}Bõç!PAAò»¤`Œ£,—QçÈ@· Í®;é?Ý⢠ݯáûm!”*U‘@‚!ÔˆôiZ.;FLT&ŒvQQKs ÇÂΆ µ=ÔQ6äÒOŒÔþP+Cñ=ÏX kªã'NIo¯ŠAvAC”FÈt›‡´_]tÁbÙYZ:FTЯ]'¢cY F˦_Õ•*éŸ *àÚ[{e¸°B³œ ŠZ:ýŠt O?þ¸¼ùæ›î ê²BY^W%×l\/KV¬•<ë»*̲qîû¯éô«àþ¼ÏÖ91ä#ü$^°ým†€!`i#`¢‚´¡² CÀ0 CÀ0 CÀ0 CÀ0 C`>#pNS´¶¶ $»·|Û,ÕH%Eã… ~ŸL¼–•”H~^ ¼»ž´D?#r@¢•ê畺ž ©˜À[KK‹ô÷÷Kq@Tà¿›èuß¾}òè£ÊÞ½{5H‡FéPL]M•ÔVUJý²‹H¦`f†€!`†€!`¤D་ å¾ûîsXPP wÞy§”—ÇÂÉ¥¼ì©}‘+etwwËO~òWùRU5ßqÇcs½M ÛÛ0 CÀ0 CÀXpœ9sF{ì1WïúúzÙ¶m›[ÌÏ$xîÞ½Ûrýúõ²iÓ¦19‘3QV®”‘ ,ì†ÀBC Dd‚Ò i.=FFF4t¿ô÷ˆ{ÕϤ6 ¡øÕ :ŒÇ=¡  F#DØ šWžˆ¡"Ò"hùP)!H Aˆì¡ß5eÑ BeÕV²¬ÂÑÔô±‘žv!=.Q¯rª^wãX"Eh¾{‚XòjD;pi¬Œ¬ÃêøÁ}ÒÝ¥í°šÚZ©[º\‡Ì¨÷ÿl´yïHX†F"’UT¯.4B† iJŽ@¿ÊÓ~µdÙr)Ú³_†tMÐ[ÓÉãÒÛzZ*ÞiöÝž®yüÈ‘#Gœ €sE´Ï†uŽ(ªnÐ>­ý8¾+êÉ? ùÒ?8$E}ƒzíÅNœ0XÙ´¹dZýŠè1ÌÇù#T¤s5ýZÇ’¾ñCÈ^ CÀ0 C`šœwQÁÀÀ€üð‡?t—Q~óÍ7g\T+eté  [·n5QÁ4;¾f†€!`†€!°08}útü™Âÿø@ÆE üsû§?ýi¹ôÒK3.*È•2f/´Z3CÂß‘þ‰§”Ò"¨P€ï#äJ† ËUT€° Ñ\Z„Îf÷q¸Ls´“ A ˜…PF¤«Å 0Bšâ ¡…âB ‚déQl½\l(I.V2VîÞͶ@IDATØÆšK!aeDû`–auäýýÒÛ3JÒÓr+W®”²Ú¥1ò1Ú–SisÒÈ€¦Í˜¤Í;ú†dph4ê%iÖ 3v5µIb¿jX¾ÒE$ÀÑÈ[ó™SÒ×zJFª4ÂAš}÷µ—^”7ví”àyˆŽpã7ÊêK¯‚ÒѰÿ‰}·«g@Ž:ã Dxଵæçç»uÉ ¦°¸,,Ëê«dq¦XÜ8®þÚýkbéÖÃÆ ÍW“Í»#:Œ!þ !®siFb¾Ú«!`†€!`Ló.*˜ú%Û†€!`†€!`†€!`†€!`†€!`Lc'OIOoï˜/¸àÁÙ)ëéé"A°³µµµ Ž@adQ’7¬) ¤¬¢ZÊë—IYe•Ô)Ñ^«‘ Ýq¤.ZµFl-(H¾D»xñb)JHÉp¶õœôD£fÏ“êýÙ–sòôK;¤I_ƒ¶víZç°T]]ü8þ¾·¯OÞÝsPÞØwH<ìD¤ŽpŠØ^ÊÊÊdq}\°¸AV­X*W^÷!Y»þr)šbz†xÁöÆ0 CÀ0 C +HþÄ:‡—Jʼw0®Ó}€ŸÊ%æJ`ã±"E9×Ì CÀ0 CÀ0 C }ˆøåŸ©—,Y2å|Äé”D_©ø=’iË•22‹ÏXD†”Ä#:Bè~õ–y*Þ9\\)RhØþ¨Ç³"¢i\~ŽsQ”8-ˆæ'2A¸\C®«¹Ðý±ðÐ ¡ŒP©¦9p*DsÀÔ»5ÒM‹@èuÝ!ö]Èy½FCã{orqžÓêa®ï¢‘4¼Ã™¶±2âëÙ‚Õðà€œjj–Þ>ÚlÔV,®•’È€ë¾?$ksÒ¼øâ/å½÷öKKK‹@²³õªH!K‰®m–”KIY‰’í•R®^ü xþ¨®ª”ýï½ç¼ü}ɳxE£”Ô.NŠÕ¢Šb).»|ÛÒÖ!ƒyÅn¼ûkMÕwürç¯dÏ#Zî¨!À-[o•õ•šzAS{¥$ÐwOµ÷Éó/¼,/ìØ%Sƒb“Ä8GG‡Ûö<";Þ,‘·—-×qQê«Ê$4ı6>|[%ëW@ks‰FðÈÀ¼Öy×õ7î…¤±ÁF4¥™!`†€!`̱O¥3>ÝÔO€àÞ{ï8¢‚\)!Ç*¤ &*ˆw{c†€!`†€!`¤…BÿLw]¢÷_Z'™d'„¤<Àð{$Ó–+ed;Ÿ!°ˆ öI¤«5º¿\òʉNè~}-­R¢œ|íš;:ËÇ QÞÛ©©4g»˜y¤˜Ž‹ Jõ}Ìa¼Ólj ¡ŒPY,Í«w”xЍ§ùHw4 ½è="ß 4¢‚ƒpI•ÃÆý§8zéS‚bRH„ËuÎ'ܶvX®lÀªýìY9×Ù;ÆÛ¾@Ãø/Qò»`XS hðäo°Íû”Tß½óyöÙgåÕW_uÑ |ð¯ì]*.`& rÒ%yÚgJKKT| ã×ÑèWUUU²hù…RT½DS/ÄÄ-ú•Ǫ¾$,…ù£ŸsTgW·ôF %R¤„}Lô’ªï:tHžåuiëèŒûóæÍrÍëTHÑ/Ã*ˆôÝgšå¡íÏÉö§žv‘ÆûÃÍÚ¯ƒuá«îž^yíõ]rèðQ9«XßqÓµ²´¦\1Á2l|Ä€´¹ÄÝËfoÞÝÓ4=öÖèöb†€!`ÓE་ ¸pÈòÙ¶\(!ÁlÕc„¿ÙÙn;¿!`†€!`†€!<§fÒÌÖ3µ¿ND³!$ðçç5WÊÖÉÞ†@š8BR=:ÕËž(qƒ¸FLåPâGßè~ìÏîBÓyq&Û!”¡ÄRS‡ÀH(Í ñ ·ìpl'$°2ÆÀ•X=~BH_´Úš*©®Ô\õn osžE^xá—òóŸÿ\#Œ4Àyü³Eee¥ ¹ó¹` àÝ?¬ç@ h¤](+W¥Fc1¬*5âAEY©[³óÏDˆZ4:ÂÀà°#&ò–Ðwû4}ÁöíÛåðáÃcDK—.•[n¹Eiô„Ð0"b}·¹Y?,?ñ¤´·kƒ€qáÒ5+5Í) %¤"¦Ááˆ;vLöïß/MMMñr8Ï/~ñ îéOßv£,ªÅ{œ (f)ÆÇˆÎ=mù od@E¬oŠøkô«øµß$´Gü+›KâPÄßÌVñÂì!`†€!`L„'ÖéžÆŽËfòUqÍšTÆò¹YäƒTÙ熀!`†€!`ç̓ òÉ®á-‹ùf†€!`,œ÷{q…„48Oú˜×üð¸´æÙy/Ê¢’pÒEJJ:€ôÿühêþ$"A-Äç.‚A(êaŸëe ª7¹Y!M!…±0ÙD|()ErÐ{KxtÙ,ž¬ 5…DŒÌ%…Ä'"ð¾öÑDC¾»ö°2² «c‡HO÷XrÄ~M},Àø6? aýyø!Ù³gOœ4gÌ°Ž¶qã²zõ—Þ ²´Xz5Š@O§ôôJgÿ ´hÄöÝ ÝÓ,_²HJB:v{Û“ö«Ââˆ,Z¼D ÷½/ˆ¼5<.ýmR\ÔàÆ¸‹V’ÐwõƲcÇéêÒh1cpÛ¶m²nÝ:)*Ñ>> ©Rb}wPןyæyúé§Ç xκúê«eóækäÊK.’åKiô„" WÔÊ€Š Nœ8!ï½ý†ìÚµ[^Ùù†ttFËëìì”§^xI.X¾X¶ÝðA©Hc|ìÛ·_^zn»k£Úšj¹øò«dÃÆ+]º\ƒ6_¥7ï’Hçã°F)Ò9¥û­LAçG†½†€!0Šk{÷î•3gÎÄy³Õ«WËŠ+lía&{·@}R^ äzµ‰>@ž´Duq°Þ,Öž¢÷Pî9Dý13*Öûs¼å 䢋.’¤¬)`¯¾úª\{íµî!<åŽö…!`†€!`†€!0G‹øÝwß•wÞygÂKKK…|Äf†€!`,ˆH@hýxè~Jàt?!Ì5Íæ>wïôÔ  ŒP‘¦9PòÉÕ;í*šBtÅJÓFx¯gRø(qlu¯È Ô#Š­’W¡ /ŸÐæ-]ÒÞÑ-âc>pÍ&Y\]&¡!mû4ÚüÄÑÃÒÕ©‘ 9cF´€úÅˤ ¼&Ê{-Á~µ¸®V#!è8ØÙ¶vQ¢4Iß=v┦1xz\Äë6_-W]¥©Ê¢žêÁ2ö½ûž õÌó—·B­×­¹Y®¸|ƒ‹ÄÎøX½æÙ¼å¬8|LÎjÊlppP~µû ¹zÓF.$ùø@xAªˆ ‰Ã3^‘ŠvîÜ)ÏoLvhz…&T…”A*Š7ß|SîýÒeýúK5à„Fi±14Y5çbN ë¼ëîÚ×¼˜™!`i"€€ ˆÃø»µµÕ½š¨ M m·œDÀD9Ù¬£•â‡ÎW\!O<ñÄè‡ ïxG üÀȧ>õ)$àc†€!`†€!`Ì-,hrðñÇwáo'*½¢¢B.¹ä’‰v±ï CÀÈ-4¬þˆ¦9a%Ä‹4¼s¸ZÓ(áVR)¡b%T RbˆþæôuêÖ¥¤¸zD—*Yñ­QαjŽ0…&—PFH‰Ü¨«b¢‚ ,¢ÄÓˆ¦,@´¡|ÅI…X¨´ÊUî‡mÔó•<ïÑ\ïn»TCÊçUFϧÇYŠVau¬µK½Û׌ڢú:©(P’»GSU$ió¼RöÄdì°2%°—Õ”KÁ ¶ýäõäm~ìà{ÒÓÝ5Z°¾#7sYýR WÔG?OUƒ–U¤ë{Akim—~Ñþ™Ðw‡úzdûÉû`hH=¶c9ó-·Ê¢†%úIBßU¢ä—Ï?#MMM~w÷zac£\¾é*â¥;>.½|£T>þd\TÀÉ< Ýí:¶–-K9>Nœ8!ÝÝcSSÔ××Ëk¯½¦‘^rbS£’ÏŽ>ú‘mrñÚµNTÀØMƒßÑÖªi*Z%_FTR(Ešú¢°DçM5çxöÏ÷9QS‚Â&Ž&ÂýÒ§µq-mÿ†Àl!@”Rm#ƒ|_¦ó>Ñnp~/†˜-…(pÑ©>ìbo œGÀD9ÞĈ Ö­[çB¢¤JeLò/¿ü²S±`õêÕƒ;eØ«žSlŸ†€!`†€!`3D€…ï®®.—û—¯¼òм÷Þ{ž•… )V­Z5á~ö¥!`¹„Äž&Wz%G!!cžÏN0KJ×êþ)Ó"Xç «ã'OKO¯¦ d{iA^Ê6Ñ~ ­8Bu&ڶሎ#ÆTšm~ìøI-{4 '¤ì²J¢ŒMmÀwÁ~USU) 8|¤ƒN}fêéëWýˆ®ÛéõÅúî;{öÊ+¯ï”öÎNN㌵AB6_²^I@ _FkÛ9ÙÿÞþq„>éê‘;ZIf,Íñ±bå…R^"D9ÛÒª©züŸIÇG0õßñðáÃ.5^£A‘„ÿ>øJd… Â@û`~ "$8qâ¸9rD8_K³Š'ú{$//$…*ª*ªª•†%Ë\š ÖC«ª4F‚Äcu¾ú®NöÁªFß§ÙÁD=bí¬·ë»c>°? C`6@àõãÿØEÍfîõ¿×ÿìÏþLjjTÌ9O쪫®rkmm*âBÀÆÆFK}à±×‹À¼ðð|æÌ·ñ€GþTÂ3isUÄgÏžu¤=¹XXͤàôéÓncÒ›HT@¹Lô :4FTø Ék´s†€!`†€!` @8A/*ày4ø>Bååå²Ró¿ÿþûîÇý¢E‹¤¡¡!ÕîÓúœ½,rsm„Ö]¼x±[lžÖÉR„WÏíó½ŒÕ³ C à ˆhXgB{ ÝË%íH@x1CŽá±«aÝãŸÇ®ÉL¤:P‹ bQ BÃJ’jÊ0ÊÓzƒNJð"ÐpŸ“J"f <1åp}‡Ø R¨í¡ŸpL=c#>-‚•á 9ßX=zXzzF‰m.jå TiôƇ/cÛ¼ ¤(ÜÕþ×­¤IkG † ¤˜H“´yŸFG8ª‚†^g˜’‚°F;ˆ^Sª~U¢^ô5ºn9ãS@°·6Ÿ•Á~)*Ö0ïÚg»ú‡å©_“§šââÊ»lÝ%rýæ+¥¢X—#*JJ軇NsÍ$šãxþyäá‡eñ’%Îñ¨®ºRjTÿPZX¬‘t~I1>Š T“à 4<¤SجŽ?>®}HƒÅú¦¿¶%‹dͪF'vÐç¼aIùJê„Å õBJ‰°Ïu­c°]£#¼ðÂK²s÷n9xð {ÞòRGŒuOÈ.Öe/¹øbÙpÙ¥²qÃ¥R]¿HûDtéü|÷]›K´HÝ“Ðw“λîž›Ûc‘fÜÜž ж¾ýo™D~iß¾}Žóòçmii‰ß»ügÙþzÓM7¹{ü÷ R.Ž-ñþ–íu±ë32À¼°ØH8«íÛ·«¢4O®»î:ùÌg>“Q\檌;vÈsÏ='(†?øÁÊwÞ™Ñz0áQÆ3Ï<ãe‰:ÀÄ>‘ñ Nx63CÀ0 CÀ0 C [`a}éÒ¥Îkí‡?ü¡ÿ7ß|sF/¢ÿ±ÇsÞË—/—Ûn»M.¿üòŒ–  ÊÈ((v2CÀH@~±„Ë”œó„8D¨‘Þ‘>¶Ÿ0Þ!Òàe\T¡„ ù¥ád¢ÂwŒzëFzÚÝñáݧ¢Â(£KC±[ Òp™zÏ!ÒPÂ*¬é!œxQFÀI#`y„«W iþîâåÞ#䈑¦#CêÅÞ£íaed V­MgÇ+V6JYÝ2 —h&ióúâÔUWÈ]ƒÒ5IŒˆ¿Üõ¶4^²A.¨Fàódm~üÔyù¥eÿÁÃt4JkšØ…#m@ ØDý bŸu½ !~öÔ õþïu¢úîëïÝ{ö‰ÆY~ë×É’J%d»4‚ih|ß=p¬I:{ÆFQàzXSüÕ¯ÞT½Vp†ª×­®ªBjkª¥^…œõêÝ_¯‘ ø®h°SBåë®sìúcqi‰fiÍqŸˆ•”T ¢¼\ƒÆ-FÝ7]ºV®»j“\ºîb©_±Z@Eº~yJöh„«7T4°zU£Ô.Òô±1ØröŒ¦ƒ}\~ìI9­jDuHfpÄbÛ³g¼¡ëÎ{®¾Bn»õY¹zµ Wun°qžt|dåœØ¥žÅˆ¼ŠJ$\®©ôèÅ!ÉÚß>3 ÙEÀ‹Âf·”Ìž}‰Þsï¾ûnÁÇ‹ ÊÊÊôöŽf¶8;›!0¯˜w¢&!ïÝú°HN–LG) õæª r…Q<ž3Þqxð¦ òØ€Õ…^èB}M.,ãb'4 CÀ0 CÀ02ˆ?æù¡à 7¸ç[ž©‰`FÚ¯L‹xÀQDÍ™6Λ ed;Ÿ!`$G UÊeÌ”ôîz=GÔÛ~$š#Ü*š7\dTL?³zëG¢9Ì#JÐEsNk~yÈô¡ß?—ÊPïp©7tï¡­PaT¤¯³C¨û˜GydDCÖ»üÜŠžêl‰:_Ë ¬: ¼ÚU¤2ÒÓÆ_ê ¯Û<ÆêÚMë5mÁ€œ<Ó"ÝñŲR×ÊJHAàYOuIoPU’/Wo¸XÞ?|DZÎE8|µcçR®¶nÝ*kÖ¬q^Œvɵùˆ’ëg››eßñÝn¿×^{m\ôPž[Øò5B:ýª¡a±ëõvÒœÕ0þ1ç¡Ó*˜xú¹¤YÓ xãyéú믗+Ö­•’°zûëXOÖw]…„´þ}]á”zj²yc“kGLàÄš>µVŵ•e*À¨)«•Þ‘BII©aœÄ™„ñÑѼY‰•h¤#çlÞ -oPç¬É«T1 ¡jkëäb¢ ¨à³²²Rªõš(ƒ5Ñ'ŸzZ|äÒt¶Å­õúóúëÇÛѱüZ)ÇÔ4 §Îœ–síÝòÅ{Ó­=çä8÷€ðšÐóyœGU¤£éhBy:a1_Ñåbâ»`•í½!`!€ÑoÌ C`,óNTÀ1¬<°£ê%Äi¦m®Ê¨×‡nêÚ–÷™6Žƒe\vÙeΛ뗿üe¦‹²ó†€!`†€!`s†?î·mÛ&øÀÔC¯Ï=S³<yç¡âŸp‡x(dÚXÜÎ…22‹Ï0R  d‰ºD+Y¢ßëï~õ­¤‰²&xc… @Éé9sB4ŠCo—#æF4ÚÂ@[“ k*(¯•’ek¤P½‹«51^{ÚéWó«m7~H.Ys‘4µvJûÀ°—”Iã…+%Ìø†|L^ë·l–Ý{ÊÎ7ߎG hooW/ø'\ŠB"#v,ÉÉ`w»œkk‘c'›å݇ää©ÓqÂ:Þgô NR„SN·_‘~‰õ൴´I¿¦V€'êÞ½{ã×Ç~8}øÃ–ºÅÆ_Å Xbߔ֖æ1DZß=¦@ŸÚÚ;¥[SFÙÔD!õEÃ&m‰Z°…y!Y¿ö¢ØŒBê†ç_|iŒ €g:òd“Þ`É¢zåšCŠ_Ÿ4)އvù³›U ž¤ªxþ—/Ê­½ÝE”#°É•qžãõp­#)‚ܘ¦ÃPg3CÀ0 CÀ˜1óNT€€@r¥z¥£p‚¹*cóæÍnñòøñ‘i#­B° ¤? Ü®]»2]œÏ0 CÀ0 CÀ˜u°@þÑ~Ô‰ðÀC¨Ë³/a„3mååån1›¼GXiƒ(`Á|¾—‘i\ì|†€!ˆzOôu:ò;¬) BJà9BÒ›”D(€ôöÞóJ†ôuI¤¿Û­£„4Ìx¨8ÅÀå‘÷$x€\_e„ËÔ£¢ Q†Y(¹<Ü­¡³•¸t‚ƒru‰á.Uo5Ę‹ü%/G׈¦‘à\yÅ"ê=ÀC ‹Tó1?Ê@Dж—ôž9,íÇö©¨ Múº5u.¾ŠÅ †Øê—|M£Q\Ó ÕR\©¤sq‰WÔ¨À`‘Õ-—’º¥RPV¥)$²«âšÅ²Z¯uµÓÐNZ¿aÂ¥OÐæKËê哟úŒ pŠå7Þˆ‡èïîîv)Z‰Êó Äúàà€z¸w¸õ7òoG<áýßt¡•+W:QA¸TÅŠiô«Å ‹\¤ŽõÖÜÖîDD;zᅜǽÿÂ-·Ü"k×®•Âbíã)Êèh:-]ícDœƒç«‹×¬•.`ÐÚÚ"Íͺ=+-gOKsk›K±¬O· ØŽŸjò—0浬H£ xb>Éø8~r§[¯ TSU)wÜq»|üãŸpëÀDbIUÄ1øÊ+¯È™3Mc0¿úê«åž{î‘Ë4rCQGbm>_.'›š]êƒW_}Õµ1bRêÇÚ3ÛHßüç`› óÕäõÐy1]8 *@üef†€!`3F`Þ‰ xklltÛŒkŸâsUÆE]$l³eˆËàG̾ð§n&üšï5[×`ç5 CÀ0 CÀ02Ïèx«}ä#Ñæ;â¢\B޲͖±(¹†ÔM#¬o.”1›Ù¹ C`²¿_ /õ0Æ÷2j\d‚Bõ|N0Gü‘A…ä‘×q|=v|œ¨àr%ÿo¹ùæ¸c™¤9#C%òî»ïJG˜¨"‹K/½T ÂéçÅu5ný”Ȉ0©>óÌ3v<£9QÁ<ç‡ù:ýõû×éÔ#š²ÆŸáü¾¾÷Þ{Îáç¿…`¯¿þú¸h(ÙPoæˆÓ§U(¥J˜¿ˆ€Ç¼ÍÜÌøÇ ÇV>›‰1/Rid(Ó—ÅÜ‚0žù asN¡DŸž®555¹ûe"ˆG¼žìú¹"ºpADE$~÷û‘ÂÓ¹ú0)düý‡úí%Ѹ.¿OâwDœè^ÜŸÔ„\û™3gÜu{,¹V|`ɵÓn3Å’{øÀŸÑNœÓE ^P’÷sÝI.!åGàGŸg£ÝéóÔ¶;îy´? ÓiÿdMVúæñãÇÝs øÒ_è«D¤_µj•{Ÿì¼³ùÙÛo¿-?úÑ\;Ïf9ÙpnæM›6Ɇ ¦ÝÆóNT ÀÏçkàqÅW!V™XQîžU¥±™!`†€!`†€!­°@€XvëÖ­n›(_ÙZw».CÀ0Æ!€—¯’ոɇXèÖÅ!guÎ8Æhî;ý^£ÁyÐó¹7¼—}Xh¼õ97¶ÊpžÛ1¬ˆV¯·bQ¬\ô‚ÀÂ>i\Ž}qÑb¸³í&ýD[pu!ã³·ŒsGÞ•c¿|PZ¼¡b¥Ä½7»#½ÿºÚ5²A»È‰ñ «ê¤´FEE*.X®"ƒ:'4()Q‹Fƒ(*«”¢üb别7Ål`Ö6gâcýš eÿ¾÷äý#GåØñ“ÒAÍøSËÏÏ‹.Ê_°BÖ¬]#7n’ŽösòÞþqQksG,à»tiô«2Á°Ø9ä ›ÎÎNyñŧ!Èouµ5rÛ­·º¨,OTÆÎ$±K÷‡»×òRMWÀui{±†È¶dQŒ¬Ô4´µ¢·HÚG ¥¹­Ó<-ÍMÉ 9*®h='͈,tPÁB½ŠB¯Ú¸A*5ò@Üm>¬pRS)@ˆ5ÕQRß}žæT‚ÄAþ|AææqíþÞæ;Äy~õ$ó£>*û÷ïÏy§?ˆælP@haæÐ!MQsò¤›ÃˆìÌ520ß1×3O“ª1ÒºuëÜçSé:œïwÞ¢É@à#*`n‚ÈeØ“ؘߗ.]êʤ,ÒXsS18žûï¿ßîô1ÈúÏ~ö³îw´'ˆ}ÝI—säÈ' êõö¤2‘tÖ¯_/7Üpƒ;Lt O=õ”q!®Ã ­Á2h\ËO~ò“è=/øEì="€Ïþóó$_;1×!Ä!®¹z,¹×±ffœ¹›{6Q¼áÀܽ0ÙÉS|–\3mæE8àÜ0Q»œ6HQ…13ßzë-7ß;vÌÕ‹vç¾Ë3¢ ê…¸Q}q"k0<³¤k“ÕŸ6#5;QŸ<èÆbú*m¶e˹óÎ;'Ä8Ýk™l?ÿÜÆ~ˆ3#NµŸLVF¶}O»ñs¦-é÷ˆlCÀ®gÚ0psÂÓ Å4?>öìÙ£áÌZ§}N;Ð0 CÀ0 CÀÈ4, °˜ÃÚk¯½Ö‰cQ±›†€!° {H=èÇ;žð1Ò$2< Ñˆ` ¡ûõó0)t_uC‘PÑ 6 å]8êí<¢!À9 +i"|¿.Ì.„2Fz”W=¬‘\ „Še(ºß-,*ñèm¸W÷‡ŒTËcŸXć°b!E̬’螼“–´ÙZFÓ¾rüõ§¤ýÐ[Ê%s}§û: 6¬UÓ*` JªðÀÌ“"fPX¡žëõË4eÂrÍQ¢p–Jn…eµ.W|³´=ðf_±´A®ÝrVŽ;.GOœ’6MwÀÂ|HÇ`‰v™šÊ*¹Pâ/Ù U5µò“ÿ¯’UѾxƒ:@—â”F¿BÔÀ‚;¤D‰óì³Ï:bÅ} ÿAݨDÐåW\'p&ê»ùå5*8í眇ë*Šè|Ò{N#q$e!)×¾¿ü¨f¸³Yz:Ú¤å\›´ö Ikbƒhô‚#l¼úJM•¡í#wƒã£­«W McˆU®aYã)!=DÌ&ªGp Ž Fþ8^!ºÜœÉ“ŒóZÆ·}h³ä•×J~Iô¹s¾Žsª› óÕ”êÑ«éT´æ^©)\ŸÓþ¤o8MVØ%—\âÖåÓ žxâ G’¦òäΊ‹Î‹€€†Ð„ Ù½{·s´ ‹‰UDxÀœK{‘Žûfœñï úÄýƒC€SÎŽ;äý÷ßÏÛÁ}ßsM ˆÂGyúЇœç6óa:N”•sçÎÅw‡T‡H¤ž¹Ï=÷œ‹’ù›ªîÏD— Àí·ßîY©ÈÖÇ{Ì‘±^ì/8ð†ržþùÀ'cß‚1åð;?±p0„ðÝ·oŸLTgF,‚Q_8¯|àrå•WN‰¨Ë'Ÿ|r –HÃ8‘¨à|´«lŠÿÀžöı˜6›É"—¿ùæ›Nà~`GÔ"D/éØDõGØ@aÎCìð’´5bD"SN„q:×1Õ}û°åªÑ~Û¶ms¢DË—/7Ö¦R÷±OS9Òö×0Aþæãÿ¸S¾yÕª/n*^57Ù$3¯A°‹7 CÀ0 CÀÈx>ED€Jp{,ذ¢ ž<»š†€!`(-­Û8zD="„áïW1%S"Jp;q$ž† Of]‰ïHO4${D÷ !D@x°ÊÞ ì )$ŠË$z+LxÍ;aE²Ž†`ƒ<ìj‚8‘F‰þ?Þ›ôÙXÆp‡† ~÷U9úÊ£Òuö¤roãûJfø¿ ÐÀŸ:OÅÅÕ *((“¢Òrí¶º‘Naq£”.Z!eú¾z‘ªÈÀE4ðòzÛ#¬m^¿l¥Û®ÖKàp^¸}RÐß©ðêÿO¿ªŒŠtV¬¼ÐyLB,᥇j|~ õàYÂÉ‹ €!ÑAÈEvÚv³–u|µ Ê(ª¨UpGc­§½U†;[TÀT™ÞøèР\P[&®ÖÅê’ §³$MFˆÇÇÑCÇÆÔ‰+Áª¶a©Nuô,Ô#8óT×%Ï–ž´@ôñ®’K«¢¡•'ç,˜ç…Tp›hçÛ8?Ÿãã|cA¦óZDû`¨D£ch†)e™!(¸çž{yŒwî#<âˆ×àøæ’ù=Ä÷üF¢OÏw»æškÎKˆq¸Ä?ü° ½ž®€!$+Ñ L¿ô¥/¹ß¥©Ú‚óîܹӕÃkb{NÖ~ÜK¼G9žÜwß}·ó*NÇ[ÇÏy¾îO\¤>„.õH‡ïAPðÓŸþÔ‘ê\CcccR1ø$–éËN÷ÑW²öàZxà‘‡{çT˸öÑ@áAsoHÇ’aé£1Lt|²ãf» R]å"&xðÁ]çt ¼_~ùe'ˆ!ÝѸ/§ê÷þ¼©ê €ë`ü‘.#•ÑW“õ…TûÏäs"YüÆoü†hÎä<Ùp,¸¿ª©¹xÎ âǼqÝu×91Q6ˆPŽ(j²:eßu²+¶ï3ŠökÖ¬q ø!‚¨Õ›ò|aÛ1“h(Ö>ó™Ï$~œòïL'±€Ù:¯/g¶Ïï˱WCÀ0 CÀ0²~ zQÞ{D( L­E&È–²ë0 ¬AxÑÐúÎW õLvæ¸õfói<ùàö×Ý«îÄçþ;ǤÇ<à‚á¡B'ÅÑa…ÐaDXvglù|â©#b˜ó9û;¼ü>®!t_þ¦=²§ŒŽãû¥åÍçäÄÎíÒÝ¢^bs$(¦d6¬ºÏ‘¨ßýè…•š>¡v‰Š TTPÕà„E*>(­]¨Ð ̳¤=X[#¼þˆ’ê‘¡^«08é/Ñ:mÒˆKU*08¡kn]rÑêÕnqÞ};…~E>g<:SYii‰¦=¸EVi4…1DþeÔ¨÷Çñæ ˆˆc'›dÃ%k¤¢l´Sœ3/¬ ø~æ®cüø8vòô¸Ô+4äxYbèï êƒ,¢³Ö‰§0ÄFüq'Zݬ¤fq‘'–ôzüÊŽi–ŸC©N–sª±°ëáû¬U<üíÀÉ®ÿÖ®]+N\ð‹_ü‘nÊ~MžqIHr!„Ò!—³«†c¯†ºL4Ý;3A¦B.CPã íç:vÄZ¦„͇8F€ñ 7â ²“Pÿx¼oݺ5%9 ±G 8}ús@h#C@|à .†èA2²‰ª@*{ï½×EžNÛsݾ_½ÃùÝÍon6xÊÖ—kæsæMðá’ý.§ÿ’B ëbM¬7Otíg’‰fˆªðì³ÏŽ»?Їh/^Ù¸ßó=× €)þïÿþÏÝXc˜ŒU#c/³Ý©.”þC_ä^È=Ð}~ˆ°‰ÈIàG§À ñ£oþìg?sýýSŸúÔ´"жoßî„S‰‚‚à³×ǵÌUû|ðƒt‚Ïà¸óͧWRè0¿%c!ÁÇ>ö1õ$“ÑLTˆöý›ÁÊ“- 5\2Q7éZ¦Î“XÞl×—3Ûç÷娫!`†€!`†€!`†ÀüB€°á‘Âê+Y­¡û]š¼05½AX=»5¸’dº(§ßaHïÍù>@ˆ{¢¨·£F.ÀBE¥QÒ÷¤JеlA”¡aß À¥ˆ.A²GúÔËuX,”( :›ïÕÜ{Å 9O·(V.ÅÁJü„ˆ`¶JL† ”¨Í¢2Z¿+Ç_|PZß{]ú;Û¦%((.¯RÝ4>ƒ ö÷é"õ ÈðàB¦’Q¥‹Ãh&ÿ thúÝ‚VXYëD^hŸÖpúJÌÔ-‘ü¶sRºd•iŠ…ˆzÌK–µGQa\rá¹ä‚úõ+© ˆKðý•—­“kÖ_$¥!õFÔ(éôÝâHŸ4TW*aP0&EÃû'NKhžoÆ@ÌË{¶ÆÇ‰3­Ò ï¨Ó‹ë´ôþ´ëló°ŽAÈB={QçÄëb©G‰²k7]*¥ÍEë–Kã<6b•­óÕLê‘§©Uœˆ€”?ˆDÔ"#=ĽËÎÿ xñ¢&Š žüÀ¹ä'$8kä8ÞvÛmn# K&¼M³Ì_×=ôÐ8A$9¸ƒ'+¼œ-ÁOyR x!‚HWHÒdïx Câ¾ýöÛcH\j„Wô¦M›dÕªUŽÈ÷¢ˆ|ˆ[ÊzñÅãeq â¢p_ûÚ×aÙT WêNÈ{cÎi Ùȵ\ â-DÞÔòQBoÔbŸÔ¤Hìw–àç½ø9šszãšqM&J`B±WThdŸ;räH\˜Áu7ªø†TÞˆÆÀAçdü * Ý/xçÓAÏ|Ò'¼ð r×]wM‹O¸´)ý9ÛmìbèO?þñÇ xŽ …}€÷ôy°EHCá>I Ž÷Bpeü’ƒ(’ì?#"ÊðF;ÒŸ5Pý¶ãoÚs.ŒˆQñ¨QsQ`†Ë`Þ E÷ î~ž¢]I!Aš60Í´™¨ ÓˆÚù CÀ0 CÀ0 CÀ0 CÀ˜%"Cýš² ]=¢£¡ú•¼†ô å!,¿( qѰá#z D¹[ ô¢ ã®±çÇ]é‚(£Tó»'šO‘M‹ Â 0 #"ˆ‰ \íÄýõo—T *HP)À^ùã9e4íÝ!Ç_{JÚ¾)C`:V^W/+Ö*»x‰Ö3,½]2¨â„A=_¿’ÃCÃÒÛÝ¥÷Ë€nÃC*6@h $F&l £U…­cNå#„ ¥¬~¹ðwaQ±«CJX…5%‹¥4 ¤Oˆ¥ôsþ8í1Ý~…‡%Þ™-‰žu‹ÉG>´EÊ ¢)MJ4¥Gš}÷âÆe²ëÍR9Û?yïCräl»Ô¯\#…1bv6°‚œ;ÑÔ¬²* ØòEÕR¢i (3ÝzÇ „É 7ÜàH’`Š˜w´·ÉɃWÈM[6ɲ¥ËÔc87ÆùtûU¶ÍW³Ra"ñff. tÓŒ¿…$%Ì8ä!«þóŸ;B²¢¡ ¤ï'>ñ ç-ÇûTIæŒ_t–ŸÐ{Zó¼„^¼¤ÝK$ËÙ’“9²÷îÝίýd˜C¢ÓF{÷@ƒ‡þæÍ›™ ‘ÏñÉŒyŠ9žñDÎñäNh÷©FyصkW¼Þx*ßxãrÓM7¹¨A’Ÿú>|ØÝcH“Iï ² |Dÿ9¯\›7<ÑI3‘(*øä'?éHl¿_:¯oPîW\!5ês;Ñ ÛËŸQÄ÷~ô#×v>jÄ5)F Ô3é±íËèu¶Û ±lÚŽ¨Aaû€"0H$ÓÕ`à¼bÅ —ú‚¾ïÅ"8Àm€ï‚ýÆ4Éô_Ä&ô1Ú !"„6ˆh#ú?ãþMä'³ÔоŒGRI¡!ó¸!¨$ª íŒp#Ù\•úÌéc¢‚ô±²= CÀ0 CÀ0 CÀ0 CÀ0 yÀð@Ÿ4|[¿ü˜t5›Vt*ºdÕYrÑ:©WËüR®(É\©Â‹!&€¸eD »H¸HE=Ò×Ý)ýlê >¤˜ý}Ý2 ‹É,Litƒ!}ˆ­ûßpmR¨‚’ªZ ÖQ Åš2¡°²^Š4šAqÍ)ÒïŠ5uBFô(Ðz„Tx0Ÿ Â3H–`˜j„B7Ýtƒ\zñÚ¤Þ³“Õñ*pðìË;¥¥­#Nd‘;ÏDÊÄ›p¢ÐÕ“¢ï!K!<ñþJÂ-%ÕCxñ‹_t$*äb¼äÿýßÿÝ‘¥x?C]{íµS&šg¿ÙS!àÉUHå»ï¾Û R 3 ã ³!Q!çx¿gÏGX'ó¤Ft@›Óp\uæÑ‰<¼ŒyÑæ„ñ÷ÂÎ yaˆb*D¡R0—3'Râ…DRžsEáž{îqä.ÞåÁy™h·ß~»KS0W­ vx]ÓÝá“Õ{â¼ë‰Ð•1~¸ç@ 'Ö6ë4×m@ú”;vŒé‹´?Ñ"”¤¶€ß]ýõîY’1·çŸÞˆd¢¾ì÷÷¯AÊ–-[ä _øÂ˜ˆ<Ó a3Kóó â¢pO`ŒÒ—¢!bŒƒñl=³ù«;ï¢ÂÜwß}îzè@¨ñ¦ªvñ•Iõš+eÇÆ§ Š^3i¹VFP—Iœré\¹Öæ´‰{¨µùÄø¿ ¬P £Æx°Ý¶m[ÆU³VF°U'~oXýöÞü9ŽëÌüjGö Hà.‰E-–µSûbµûÙ²Ý~ýÂí×~ï—ù±›þÞLDGLôÄÄtwt‡ß¸myymKÖBjE‰I‘qß@€@kµæœóe%˜(€B¡°î «•™7ï¹KUå9ßùfÆÇý®ÁÊÆÌ¯ V3ãã~·T°â=>Xî¾ûnµ—äob–R©£˜˜˜sV LSà)‡Í;"ã5úš($w5ÍÚž#Ê>ˆûˆÎö0ʸ¬ $+Ö!Ü4ö¸œ h¯‘ö8žÛ=<†û¬‚:¬r­g0ô„Õ ‚™VèžrD~‚$×× ¦’ŽÚVìØà-±ÎtúºB,`ë#„—Ø:vÛ ô­"ý–¨Žññ1é?yHº핱›× ø`AÛÔÖ.÷Þ'Íöbd3ÝHI€Ð3+¤ÛC.Æ}¾Ôø¨¤à`ƘL&R vÇ14‡!4 à gƒÑ©BìçÜtWPçñ_|tPøÐrå´>ùBa[`PQ-aŠ àRáTH¢ƒHm£øAÊ‘ª¢ ï;Qñ§„†‡ë×P”•0ÏKe½*j;˜ˆëRå!Š ð™¦Ÿ“Ë9‚kd^ò3ˆ‘íwÝu—FÇPèC‹z¾´sçó /¼ âFg/4‘tçU.ï-LB"ÔmçÏ+&¦$ÈIäÏVØü=G“$u.œ)š{ÿý÷•ÈvŸäýk¯½¦âùØ;0ÅE__Ÿ¦jq_7SaÐÒß–¹ë™í5ÏKÂñ‡?ü¡F†ÏDÌ3­­Óé¸àNsíÚ5%˜‰Ã\åÙ®m¦÷9þwìØQи¦cÓ*Ðrßý™I’œ"‘|úc¦k›ë{‹Õ$™é(àî;^+)t?™IPàn…»víÒTŽP¦¿¿_#ä‰_!œ$çÝOúS‹5†ÜmZɯéPEa?Ø¿ä+X˜z„s›Ÿt(6¯>fK.*à¢K… -¢ñ¥R r+~€ìÞ½»  <Ý`àöR¬c¦öš÷J³ÏÍü˜yd—â<_É}Î/´ÎÚÎ/XT¡óËf1‹©#4 V+3§f~LMö;´ tÖvÞHâ¨b‹ J¥ŽlìÌ߃Àìð'¡}=",=Ž´±¨Š,€´|'Y^V¡ì³SPé×ÍÞò:Æ´µE¥^‡5: 0óÀúܧ)$µâÉ›+-PÑ”À‹Å„•bA‚'‡›±¦X¢:†{.ʵ{¤÷øg21ØW  \U-Mk;dݶ»@ÄW€”RP¨Â4O¸*Š þó•AœÛz¿ß¡Þp¥TZ^ˆ &ÀÕ&ñŒôãQ%’m¡Á¨L •B7HcqØã¦îã#Ä‹&4 ÀaìÆe{ív_¯óšéôDâÒ-ø£°`®QêÎ9 yæµ*”á}UbOŽ»ÿ)Øàß¹Ü& ¹Æ|ŽYÌ> ËЉ'„AÖN¡Ã׆¹xÍäi9æQÏGa ÿžË¹xAè”ÀûÞ…ö)Ï³Ú 6("Ø»w¯:Öðžç$×"Š(& ¨€ŽùÌíbá·ä¢‚b5ÄœÇ `0 ƒ€AÀ `0 ƒ€AÀ °š¸~ôCé9ü¾ œþRp(¤TÔ7HûÖÒ´a“„@T[iæ¶Û_`ñ‚˜÷âµs’êJ¸¤‘BƒT”éebd¤L7¬“C„é¶3uÉ” jHèv“^’Gú>ÜÅ-4Ây"ýÊÛ¶‰¯¼J" k%T bbÅ,t Ø¿ÿч´¹¥íí\oðg_;#:éË ’”NzŸƒT8{îœt›6Ô¼yM1L3ÀÙ±›ÝšúbÃ)¸£@Xð"lxiÕ=Séê¹!щؔ]H3§rD1/ì~RÚ6l•O÷P‹rF\:Öâ´ÃæM{x?zþ1Ù¸¶¤ÇâöïÌDúñ,ŒÀæ¼§kÁ§Ÿ~ªî%¯¿þº:tH-ÏioÿÄOÜ‘3=Ç)K~S6¹Ês côû²Á«¯@IDAT\ˆùÙ€úúë¯'#‡}Ù_?þxAACLµ@×)·P®ʹ²Ï·ÌåÚÎ`¬|IGÃÏÚß»ë'Áé&è󽆥ÚmÎŽˆ'¦‹Ý†ÅìŽy'ŠÝÁ}Æ š¾# çýéž9³ç %çŠ륰…b•ìóMW÷jßNáL}óöÛo«h‰ßY(:¢°ˆ©o(&`ÍE´T,\ïóÅ:ßœÏCÕ U*,TÅŽÎäyK¥~¡v°r¾¸³}Å,¥Vs¶ÐÄ”é(µ>gKÍü˜¾¿ùŽéó™ñq¿»XQýë¬í¼9“¯•û:g{mê˜ ¡Ûï¬nc1Û+ƒÕlÝ~ß`u‹Ù^• Vt&pÖvæäï‘b—R©£Ø¸˜óVV"[ýq›äEô¥7wœŒ²GšË'¼V—Â4 ’ ?ˆ;šæ cÝïA„> X<<ÞgY uxàHàajDS+~l7ÒXñ1ØŸ3Dâ{ÃL‹`ß:ó åºD`?=&ã‘F àW»m¬š83¢ëàMÞ^ .¼÷ï2Ús¡ wö}3¢Ä[7n“† °Ò.G$'­R_xV"=3F0í”|¦ûF#”…Þn¶ÜNgu<V^Î^¤ ðó|U•N6Jc4Äùpž$ˆæ8"Ø£C7%‰T Ü`M@p—ƒXtÇ%Žm‹"4€ƒA¤îæZ™”7´ …!<ʪAX0µB-\Ê‘R¹œb\]ë»%ïà¦2oæ»$}©Æß‘Å»÷àûËO~ò%#™œ¶ÑN!ÉKþN¦ˆÞÇ%Q‡€eb<&Ã賑Ѩ~÷yägsÈ/:\ä˜É`¥\냘ýè.ëšê$—ˆôØ`Ñæ`óü×K[{§¬o_'{÷¼+ç.\a–ÔªIœQ´áOÅäçÿ寤µ׆e6ÏKe½ZÈv¨Û Ç[듎†®4îA¶‚_wBÜó‹_üB­ÉèU:\¸pAþùŸÿYS°‘À#áDgƒÕLâ1JݱÍnço(’òùìù •\õì+Ô5‚$ìÃ?¬nRŸk0EP$Ëó%ÙV’Úùîï´—ixîúɳ¸?ƒœ}—ë3Ý(²û™„»#([¬ë^Ì>àXt÷ÛØÑÑQÐý÷g¼ÓïÃÃÃHieƒll§Ã“FÔÏWü8ÝùKi;q¦…t¤Ù·oŸ®aÄšb¨W^yE]'(XZˆ{Lùb¹ä¢~°ýüç?Ÿ¼Þ…\¥R‰R+$~‰/v)µ:z{{¨`–ARj}Îæšù1s§›>Ÿ÷»‹o9k;¿°3Ò£ØÅÔ‘?¢«"b…/Ãã#ƒÒwñ¤ ^» cC·p£² ,Â5È“ºv³Ôµo–peÍ´•šþ˜š;Þ0XÝÉ´+æ ¤µ ‹,ľR©cÚŽ2o Ó"`%!ƒ½3Iæ‹ÎâJê’ÄFNu-2…d°…<á´'§m½§¢AÓ'pO¨Üè¤\lÚe5Ôá©pr)£Í¸Ç¢ÿVù*ÀIÄwóŒ¨À Òx²8ØbƒEQÁ°E‘§víL‹@œ™¢‚¯µ,lÑþ.é?yP®|ö°ø¿R ÀðKSëZéÜq¯T¶´£-TP$Ä”¨|+Œ3¤4€ ûa›—‘“QÛ†:¦2‡H ä2œT¨@ñ…—ž<ŒxùàP^&v|¸GÚa'£Õ@DƒZž $!ž˜€‹AŒî °c ’ˆÜŒMŒ©«Aé(8H‚$ÆzúùþBz›`8û•žŽ) eµÍ**Õ6âu‹„*ª¤¬ÛÒhG„ÂŒÂÇU Dýžw>Ð(579ÆïÏ<ý´lÛ¶M¿g¨Eþ<Ç®ýF‹õX%Ó-àÈ‘#šnîNá oþíÞæ¼ç~¦Ý2¯q¦ù1”!R©Û.üÞÔŒ”¡ä°X£+EžƒÌþò‹ÏKSE@Þxç=ùúäψˆïg‡ŽÊƒ>! ë6A›uû·ùLíX¬ynã»°kIÉÖAq]‘Ö÷8_ª×$ˆõK+z ˜…³gϪ[I) ^‚[›6a<ã~Ój*$Ž™–€i\Ü…î)ÅÄ‚õ\¼xñŽz˜ë|>6﹈`¶…â2FžÏU$àÆ Ÿ×äè²ë K‚C.çsŽÅÞ‡âJ·`€üîâ~ß½}9¾.¤8³Eÿ1uE!÷›øF ~礸…ßòGü>Pˆ°e9öÉB^AèšDAcƒƒƒZÝU(ÊàZN!iMë÷ÈB^Ð ç^rQ¯¤ÍB—R¨ƒx¡ÛQjuÌö#g¡ÇÝJ8©õùBbn°Ê]ƒUþXñKØB¯í¦Óù#ÿž3«8¢É®8(~ ÝgŽÈ­®K2kYÞàõ#Â+RS/uë6Ëšm»¤ã¡gdí]á†,#¦–™ê˜ºgá™:òÇÎ`•?V¼!ÎÇB–R©c!12ç6”, õT(€ÙJÎ:¼éäÓ©7PìkqÝç6gÿcÿUQÇ4íNƒŠ&VÞ,Ê%$˜2¶©Ÿ9ÆÂëɳ*Ö“Ý>„رŽá®sríó7¤÷øg21؇kçuÏ­„«ª¥©¥MÖnÝ,‘úFDøÞŽÐž" pŸíPÒÏײwA»s4ï#ü'Ž[báà”kî×@&Þ®VŽò&ø^™F …T ÏØ$ <ˆŽ"]œ &F† :ˆª“Ý xƒ=‰T IìïÜ·¯³ðÿÝB¹x\O¤®5M¢‚ƒšF à^7†Pe”…üâGätYU#¶È}ëT=˸:rü¤ìûü€ !:Ð]H&>î¶8'–EWÒ òQq´õftWW—æpw"Ý×’ýšb‚]»vÙ7¾g˜×®uKT#·ÏP__'5p®€÷újaæ`ãûáû¶KwÅ£Ñ 9uþƆ=o˜áó/ÈŽ{wÊšHùí ›¡9{ûcrŽÜ¾ûU‘ëxçw…ùšùŸ…Ïts¢F¼x7e=R‚D&E³$œœ +’We©Q8M$Ô…d)ÖÄiûÃF­¤þgÀ!s¥s¾1²)>øàíGŠ ( :pà€0%Â3Ï<#Œ>çýºÕPhžk½"¹éŒñbà@¢îÙdu}}ý¼êatw6©Ï륃Lv]ÅhGö9rý–e½Åú Í®/ß¿y ÝÝÝÒ××§â6ö1û€Ï\¿ÝÖüŒÚç8X©e®}À¾¹yóæ Øv¦4"a]ȸ§€ »Ï¹8r¾•Ú yÝt`*›?ýéO*c_sŠ1˜Ê†éK¸ÎS\°\Öïe!*XÈN1ç6 ƒ€AÀ `X<hQ{úã?É7{~-=§Ž@H€6W‰GGdÙ`÷%¹úõ~é>yX¶¿ôSÙòø÷$ÄH.S ƒ€AÀ `˜Úê[Hs@²ÇË4™(rÚŸ#d[mйM߃%½¤¥Œ€¢ËDlÑš>S,M‹`VÓ²Þè`î· ê°âQe´öÚdkD~&Í޸˸®ôÄ(þ³#5å„Ï1ݨoäi`ŽÈû acÁòøRø±Puôø\º¾-ý§€TÇõP*êd Ò´"ò1T‰q87°(¾ý |uð<^8+xý^ñ—aÜòšQG%EÑaISh€ï ñxB‰†ø\ pÓvÏq¤Nˆó}ܰe*…$œ²o˜£’ŠÃ)â2"ð»˜,ÁÊZ WÕAQQA­„êJ¨~ ­*¸-«¨QGÓm¸ÆUÏõ^y÷“ƒÒsbÈ™R Òýù'•¶Æ5‰àæbÝ$dû¦vÙÒÑ&×oɵîD:vÉM9#pŠ…KD. $Øÿ^̲ _óMkÚäáG’bžÔø´óãÊ…sèŸÛ.lǺuíユ‘à˜Z 9è WÉŽûݽƒÒÓ? ý bœrDÔP_¬A w,Õ<_Œµ„u¼óö[òõ7Ç•ÈÔ>E4¼>k˜w~8ãP\@²‹â øš‚¾&É]æµ$ôHyYX*ꚤ B¥J—ª++¤º¼Lª*Êa@ÁT1 µîÂÙó…î=šÖ‡ë³~N–.™N±ÀOúSaÚ5æÛþóŸÿ,Ÿ}ö™ÐÁ÷ßÿýß娱c”&ÌÃýè£.x`‹3—–ò™6÷îuÓ¹–éÈzçý¹>3 1W=LQ0Ò•–ù¹Ž'y¾¢Î}>–K!ñJÝ8( ¨€}L!ó ¸ ”Ê\û€n;¹D§N**,¹Ä.E­`•œŒ‚W¦”âzÍTqnó³•N4Nªƒûï¿?§Àh)a2¢‚¥DßÔm0 ƒ€A „˜@ºƒÓýQ¾xýÿ’+gqûF$Ä›‹¡€”!'o`Í6±*›düf·Œ\;/ã·nÈ¥#Ëè@/"Ì’²ýÙŸät,(!ˆLS ƒ€AÀ 0oh«ïcþz%ymËy¦C°@¨Z‰¨Ó¾öþÜÄD¹ ÕпõXüGb]S)ðFÓ¶ž7’WCc }M«Ä…>àrÚ‡èr CDð·M†ã±ÆaŸ  ?Š·ÙÆûxC ‚IŽévœƒ}‚ ÖÕÁ¨û¾“ûåòG¿“‘«§%Åœõ”†¶uÒ¶u¤Ú%XYKÏ\» 6™ 8I:ˆ @x{‚l£-:PŠCvg„zĉ"–2¦Qàþx ±Š ð]€:¼þ²0Ô¢_Y1ˆMÔQ‰t R@؇øbÑéšF䌊 tû¸ÞÌMà¦<ñLÁâ7QÄ3ϵÄGn —H] ¦ÈX¤ †+¥¬¹C"ë ˜Iï°ÿœ8{^bG8…$Ãwwm—›×¡}À˜‘ä 8vCÛí뤣s†@ZEc**@ „ñ ÅŒ×dö!òDry©6«;ƒöq}?Íü¸r邊>œ¶ñ¹½½]*!¶ð!"^Mžsðì•k‹ÊÆM›¥"œßôaŒÜs߃Rµ÷ã)¢‚ ˆCR£H1Ã4(ºÖ.Í<_ŒµÄ]:SǼ;Òw²o ö-ƒà§iTèÌH‚´b‚ªŠ2©…(¦BƒÆ5뤹u477Ie¤ U\$аîŽB B1—®Í¡Ö†ÕPî¾ûnÙ²e‹„Ú³g¼ùæ›òÍ7ßÈÉ“'•Œ%iEm:lß¾]É«RÅe:òc±˜¤(E¹H~FϧG¨£ë«ó9‹Î"q\¬Ï¦•Ð÷$É¿üòKuÍ¡ àܹsêP°š0È·Ÿ8æ—ÊÊJ˜ŸOj|ÛSÊûQóÖ[o©3Á'Ÿ|¢Â¶wëÖ­òòË/kªƒ§žzª ”‹›,ʦƒ€AÀ `0 %Ž@ ùk¯üR¾üÃÿ£‚/n.VG‚RW–*<‡qÓ´ìÁ§ÅÛùŒ÷÷È­KÇ寱}2pá¨ô_:%_ýñ_¤ªit>ðT‰#ešg0 y"@V–$bvÁMg $¹…hm’¾·m§AÒh”æm‚|òP’º?60$¥£eÔ¡" 1Òþ¤ø&oؓКæVHòI¬°ÿ$VÓ`Kü¢Žh_—ô{@®|ú_Hº¢ü›Z×Jû½HuÛzˆNèPA±@¦ÿ§ˆ\a|'M×ü ;à|ðÂÜcîcš:!9•þŽ$Ša[ltHS'$ð=7•H"*¿ˆB¤‹ãá.A¸DêZq½ˆ¯i–±cßH§oPj+-Ib8ACPÛÔ"Ï>úÔW•cÎbÃ$¾è‹»”WTê£É}áx꿬"%nöïÉq1ÍüH@¸Ñs£WbSÙjÚû†á˜a“ùٕ䞃‰TZÞÙó¾F±>òÈ#òôÓO £„ó™ƒ>]²‰?¦^ð[ŽÉÉ)1M;ò©#«*¸Yk‰ûº´*¦roßë ô-´ãvâ] ñI}cÍúX³f J:;;eŠm|ë®:«ð³-´×íÄÉžt_JI¾&Ù÷Øciú’x@#`™ áòåËê^@‘ÁáÇÕN›ä…<¹"âW:89Å1h”~Ö±qÓ/—Ð`.Õòúyîìó3Š™BƒÕPH’SCòõ\ ²û”k S®8º¥¸±aNz®?óí‹•‚uöXq®›B#¦ýÈþ¬sÞÏ÷™ønÚ´I׌ùž+ß:Km?¦Ú»w¯Š èNÀT,-H9õÜsÏ©˜€©øf9—i~)-çK6×f0 ƒ€AÀ °Ü½y]N¼÷[é»p6¬´ÕWâ?ìp±üÑáÅ΢°ëp3²Ö¦ kã‘þÓ‡¤ÇçWÒ²e'n$2BЃ€AÀ `0r! ‘ãIq$i=¯î$kíˆ`´}vF%‹ÉLŸîï80å] øÏ“¡ÐVEˆb%q¨íÆ÷%è‰-£¿‰UȶçÖ7mm[hã%oí›úšâÀ!wÉBXqä>E®c¸û¢Üøú¹~ôc¸n_¯^\þÿ‘°mjk—uÛî–òVägeÊ |wÓ¶ƒÄ`ñht8ÆšÈñD‡èv‡ÌÙh~ ¦Ç{hSŸ!:tü9ê—ƒÖ¡Øb×%¬Ã‹º}LÀ~ ê® í¨ÀaÚæHÅ“H‹“ñAÿL€øÄI¤±‰1ˆ >@Ú„$"F“°¯ŠÛ|ÿ‹@h€ùLéÀsCƒG†qYITÜ5 I ^–‹1\{„[p™¨GŒOŽÃe:vu½rÍ7 ë×wÈ•k×ÕÆšÎ$†Z[[$ñŠ51‚Öç7oöÞS'OÈ©oOk®íÍ¿~MÒKÌ<ÏÏ>%£p^p—ÆÆF8-Ô.Ù<ÏÆJ×òYÚ‘/V3®WŽËŠŒxM‚ohdT$ Y=NaÁ¤aa¤æ=÷ÜcW¬»êP@Q—; æ…³r-@“–å)‰)sqSXððÃËo¼!~ø¡p~0w7] 8 ûìÞ½ÛNWRBdu6Áìt‰fŽÁb )è(à&²Ýõ/´: ä²²///Ÿ79ì\ãr~fq¼þæ7¿±n¼¦¦FÉíÍ›7 _3í LÅâî‹/¾øBÞ{ï=ˆ›J+-ÂtýF ÜíwöcJÚéŸùÏuz¾ç™Ï5¬Ôc9Ÿ™’†î1o¿ý¶œ?^Ç4çóã?.ßûÞ÷4Ý?sõárk·,·1×c0 ƒ€A`…!ÀÔ7¯ž•ó_¼§W ú¤µ¦N·s6g7ɇØuï•d,*c½W5B÷·‡åú™cÆ­ ,ó·AÀ `0\²ÆAº) <^ؽÓVöξ0„ye SH 8Q˸1K‚NI:F^¤Eð„m+h/mÉiýÏB’7C(¬Š:*‚ i… @<¥Ç@êR„áA*ZfgðñE‚û³¸¬´Ó1ä„' ËA_wœÏ‹m]¤:nžøBº}$ƒWÎH Vú…8TÔ7Èš[¥uøHÁ^ž‡DJ‘¹ÎˆUü° G„?ÞÔqá:+üíìOÒ.‰4$±‰aé52cΣé$2XQ°á°y˸/ÚáEjÚ¨´o—–74Ah‹C)ˆÒæ$`ùìG ª£AœBìG^gæÇejŠ$ÜB܇L¡¥ÂoI…ûîm¢[z¾'CåUâ‡X7\Û,ò¼Ž@˜[‹,'âT@l°UB5*„Yê±›k~Âåòn¢oܲUzz®Ë0ˆ}Úä··­Á|’ôæà@o·ÄÞ‚…9äyÓ¾««KýîÃr×¶­ÒÖÒ*AXñO™ç°È?{þ‚|ôáû2pëvj ÞÌð;IC['æÇ½]kžçªØkÉ´u8ë ÓèE|f¾t>¾ýö[µ:§°€$Øw¼_êëm5ßu×™0ºöpCÁïU]ÃôÕõ_[[›üìg?“;w ÉEæï&ÙÊ9òË_þRŽ;¦“Ô¢ø€âžR($ër‘sŒ\'Ùψÿb”éêqÄ …ÖAñGvd>Ï5ß´ …^ÏbGg a¸¦»?O)$`D7…G7nœÑžb„ÕdÓO!M®qMá ±*•¹½Øcq>õq=zTÝ6(&`*$„¬íÚµK…/½ô’~Þ­¤±êþZ:|̱ƒ€AÀ `0 «8òÐÞ8w7XûÔ¥ ö²Õå·oÂM …5íÛ¤~ËýÒuàmS®~½ßˆ ¦Ìl7 ƒ ‰›ŠÙVüˆü$ºIìú3ʤ@î‚ µ˜œQãŒfv Ià ìlÒçUQGŽˆ-%Ê3Xy3ÿv £õs:@€%ÉO‡‡?W3I7Ç:hÉß w‚+Ÿ½!#×hÿKlj¹—«íÛî“úõë%Xñ‰: ¸Îƒë²pó“ãÉãC»U ÁÖ`LaØÜQð>Sfà‚@ܸp⎹ÚÍí+¬ê€ÈdóÝôSEc$G!$x ey!&HJQhñ±a¤LµÓ'ŒªÐ€Ñ–$¼“p6p#„£Ð‡¨„–[Ož&\×$!ä¦'anh—Ò)„jš$Rß áAµ”Ad¬¨™Ô…¨{ÉŽ]½°æGç†MÂo°Óæš7ÔËüpÍ‚ ׫<ç`S­…ËôwHãÒ‰¼té’F³’LY»v­’qŒ°–ë—ÎÊÁ#GåøÉ3š£Ü‘.;ï»_*ë`=Ì5Õ)3´#çxŸã<×j–º§­KüÜ××§îÌN'ƒW^yE üóí%n×RVOr¢‚mÛ¶©sm·)¾¡ˆƒ¢>:tH­·_}õUu‹XIW.lI ’dÍ.$ë¹.«°'BܽÆO' È·^GüàÞŸ}ÒÔÔT°ûû\Ëýõ§Ÿ~*W¯^ÒWŒ’ÿñ,Ì5o¢åïìAÎs:7ôôôLÁ-×Xºóh³¥Øð;Swp½}ÿý÷õ» ëèììÔϵ^xAž}öY¡0i¥•'*àẩA•mt™„ù¶ŠY«Žîîný’DeJ]]P9XÌB%Ìõë¶ØJ®Ã ÛtíÚ5ƒ•×ëRésÓW§ÎòÒ`5 @®· +®Qüñ@u(s 1G`1K›\ÛM³£j°š#gùb‹ŽÊœ XüÁT­Ù Á¶VçôúLû` ‘|Éî“S·Ç'¤ ?|XâzžsSÞŸËómG>u™:òAÉÞ§”°ºr劌‚$àM#æ»c„H1 Ï͵}¥×QLL̹ é õ¾ ¼0n˜gˆÛ¾‚ `áî¡àä.^‰…ý­Q{NêT¡y½3$µZúgˆó¹Ô‘è’ÔÀUØþÃN ^¦Q(r ÒFB“8÷!:ÝG±d; ¾`þxadºÂÂwGd`§L°™v0³hÑ ’ÂKÌ3²ÍëMlçQGôfô{@®|òuv*Ä€—ßÒ¹IÖnÛ!µëÖ#Ÿ×HAî”h³Å~ãõàaŠ HÀ@l Û3ïñ}ÏÆ×“ûcO'ß-Á:|#•ÀX…81æ+ FŠ„T,Ü ¢ã¥˜Û& @˜†³>ïãGé´% ü®Ka ¦@¨»‰(óÂþèEZŒ^ûà³Çô9XU/‘ºˆ *¨n’ž¡'9!eø;ÁA±Ç.ç,K>óÇ9X…4:†ˆÉç`Sóyö©'% ׈«W¯ S)°ð·9´xçïrÚÁ“dŽI/"X‡¦D“¤zä;ÊÚ&DÆÓµÃƒ¾C;–óZ’W;Š”ÆCÁ/ÂünÌÈΡ¡Aùñÿ“lÞr¦úeÆq±×+í¦9áþ™ÏIýcÿÇñ¿{÷n0-É.>8O>úè#P\ÀœÞŒž%‰»Rs§³­$àÉ#ñ~ Sø»ŽB¦bÞûkmmU Ýç¥Pƒ¿‡ % Ïœ9£î7îë¤è‰÷WbŸÌåsŽû2¢;;ý6yä#(pЬ×äI)ÈrcG¡–{dbþ,2¼_¿wï^Ù³g:Ã8nõpÝ¡ËÅt†áú¤ßŸ‹\ÿbœnʼn 8¾úê+͇B¢œ‹I±E‹UÇ?þXÂÇ{¬èD9m×J¡÷D`œÃ‡¬Ü ¸^—JŸ›v¸:u–—«Yr½½XX1GÒÁƒ¥7E¨ž-¶¨À‰º0u¸:wš—«i€É±y¾X¥y5>lGKù`ÃÙö¸”mÝ5YS":$7qc3uêø’ŸIÒ"ø@v°0ϳ„,)œ':d¿Ö süo¾íȧ:SG>(Ùû”V¼ÙÆçó&ÛŽ;ò"=iÍX uäÑT³‹AÀ PHÞ{iïŒÏP /Çi¶…Ï\ D! ü„1…ø|öàµ~úf„¼+>&Öø^•7\çù2—:R½ç%öÕqœOü-›Å׺Mümwƒ« “S”:¢šæä·—E mÇÃ[^kcK’ÜÁ¥Çíôxí«l´±¢Þ² ˆÍë:áõ°T4¶¢_ˆ‡M<p-l» !ð"ò½ÕnCæ»÷M€`Åx³ ð8yÊ1NÔ–Ý!"ݤ ÙUV‡øy†ŒG‚„µuR‰üžlAD¤sÁXŽ#š"!±AŒ9³G‡ð<* \‰8œŠ,4ˆß>ÜÅxq_5‚ô ÁÊ)«o“Hã:ËÂjzâÉîÃø^ŽóÃ=ËpýÏ¿ø²T54˧Ÿî“c_ "k!2(¼—H+í™ S/<úè£òâ“ß•*?"£}‹2ÏÝíX¨µ$ß: v™ ¢%y¤ì¾}Ÿ‰ëèÏÿëßʺŽN̈U¿K±^y™’¥s‘kæ'^,I–c¥ ÒüÑ~$>ø Ún3%9 Zöÿîw¿Ó{ïäH|ñ¾9+‘üêì씓'ON!TO:¥AžœóÅ"çé†BÇ·¨àôéÓšb‚ؑÚKa*Š¡¸v¹Ë]wÝ•Ó}Á½ÏR¿f[³Ç !8—¹&g¿—ëzÇ‘N(~ß}÷-ûöçjÏbnczˆ}ûöMð>‰î•:¿ùÔÅùÊÔ2\OùàÀ±ÏôÃÐu‡N0[¶l)ÚÚ3Ÿëϱ+NTÀŇþÌEAËÚW»,VT²Œxêèè(v3ô³êpCÁÛTìâœ×ôÇìȬfÇÈÙÃ`å 1ûs)aEÕ3×:ÐÐZ®Ø…_ÄMù¡j°Ê'î5_¬øE9GN]ZŽ&ƒ€A`Hì2ú;»àó˜‚+Ò˜¯CI›BÁ籺8ä±û8 ¸?Š…ˆN¹q–9ÔAËÿôÍ«’ê¿$ÉËGÄ×´‚»Ä¿†|Æyç[‡RAEn¼é5]Açõá;ˆ–Œ Âþ#ëëV<ƒU$ƒ-w®ÐSÜQTP`·ºÎI÷ן˭Ë'%6WŠ Šaæ"aZ\çYޏëš8æÙ¼¿àºupÓqq®cÞ9‡yž~7;~ü¸® a°!¿»ñ~(×г˜Â r:›”BÉñ+ty7‹A«ˆM›6©Ê‹6Å.‹UíjØ~Ѿ¦Ø…‹l)ÔáÆ…m2X¹™úºTúÜ´cj¿Îô—Áj&t¦¾·XXñ†×v*@),(vqnz˜:fGÖ`5;FÎÅÄ*\²7ŽïÃMHü`ÁÍÇñ[×åÚÁ=2Ü}A«ó”!BŽ7w2%Òcyh‹QŠÙŽé®ÇÔ12wn/%¬èPÀætHcTK± Ü—BÅÆÅœÏ `ÈÀdš°ÁjÑï%Y Ö„ò$¸p0 CüásWíè™EÉeç=ŠH,s»FrêK›ÄÖHó<ë°ƒëÁ0„G%Ùu\’Õ­loÝ:ñÕ´‰·±C¤ê6û¾äí€e=ÉQ\?‡@ÏkM/‘yîÎv?QExe“­$ïY¸Ouôß/׎~$CWÎÂF¿0±eMs«´oÛ.õmí°ºÏ¸0dš¡Êo滘Û]@ÐÝZŒ'CÛp‹lª¦Ô¸Ýl/¾ÔÙÄs98êþιÜd^ Õ1‚hhŠrÊV„јù`Åߥ^öÄŠ#%X^&å ’†À@0ÞRø^œÆÜKÀ¢?:2wƒÛÑ¢ƒÝR©’|à¦5f·vÙ|ÿs œs1eB0R…” 5®Eê„Høq푦uª¨ÕT e5MH­W”Eš3ÍAŒTÙÔ¹^Ö¯_¯è¹Ó§¤ëòEØŸ#ÅȾX¿;@V%àQ†æ¦FYÛòudSÞoN]‡âÙž,nñD±çùLí(ÖZ2ç:œùë €eô<‘LJ~Œ~zPïµÌÔºns­V!UfáˬÝ˨IËæR¸&ѱàž{î¦D e7ÓNÐ~Ÿn'NœPç¦C 1Æ(Û¹FÞ/UcIèq^;„¶sÌoN¡8× ¶¶BaË×p@!1KqÅ®]»¦çtào9Öà)§|ú駺?#ìùÛ8ŸÂ´$&Iˆ»K{{»”Ë”äõ9.nB¿««KEŸKpàn'_ó·1äèÜ÷ŽmÏsæ3þèPAqVSéèèÎÎNuquÄvüñ}âjJq`б}çwô™.I,œ¯LsÀ5“ÏäJ©ä·š-£sÑàIN€bÛJ³©‹UÕetZ`} Ñ.Ò¥P‡{øQiÅþ/v)¬L;ò+ƒÕB­»Œpàe~‘¦ò¹Ø…_ÎMù¡j°Ê'î5¬xCÙ®/ ËÖÁK'åìø¿J¸®Ñu7e¤ëlî‹Á1ñdJǦÚúåÞyö­óo‡©cvòߣ”úƒ7ÑhYÇ(“b§^#¢Œ(…:òfOƒ€A`^ÀVßš¡‰HL¦BˆT+yB±€¾NWà~ È_|,–…Ü£ˆ¼‘‰›çLs@KsO(ŽÙ¾5d“ë™›ës¬COæþ¤hjîxxBåâmh#‚CÖî@û½â­o·#I—²å ÛA4©ëCF$@ñ…5†4)Ü„¦à ¢~G[m&ÅþŠSÄ Ct"I+àê¾ÄÙ A5‡:’QéýöK¹øÙŸe´÷Š-ìpcšçë–ÎM²vë=Rƒûf>±Xé8ÄèãL˜5¯Ë¶Ç ]dŠ…ïp`©9` 0á>?¸ñ á‰7Há ¾¸©p 3F(V¡sØÎô«¥ŽôµÓ"=çìtLAQA9"øCx°Ÿ@Æc2Úxñï<°òAœÀtÁÜÅIè:R1’.i î_|й :2 ¡Á°¦Lˆ!‚-4W¢%ÁÅE 5Cé½*PL–HC+Duê\@QAí¥»A„Áòj û#ÄÚDR¾Xóƒ•ç;˜ƒ6l ë×ÁbTúûoª¨ žÄ1×B˜ÍõÕÒØÔŒÔkl!Öê(tžÏ¥‹]‡3y˱œ¿pAíäIŠù“ø<›nݭĺÍuÌÜ¡1!èÜ\Ž [&×D—Isò o¼ñ†|wÒ´ÑÁÀq-xöÙg'¹™erù9/ƒ‰$ô©ív+ Ãoû[ùË¿üËÉÀÕœ'ÀFÇÙà½÷ÞS£è)Àà}e§0d2ÝèPàº-ÿú׿V·ò³ è\GÇ éìǾa¤þJ „`E±†[TÀñC!‡7§}ÙÏäøû˜nå1Î}8þvîÜ)ÕÕøŒ¦°NâÇ4t¬q?Í!%µ™Ø=óÌ3òí·ßªÈÅiÇüþðuä¡0(_‘ §0ƒc™„9òéC§ÞR}&Ÿ|ò‰®“P4CñÇæ“O>)ßÿþ÷uÎ’û] sv®ý´âDìªÈøX¨²Xutvvªrh¡ÚA±B)ÔáÆ‡ ÛTìR*X™vä?2 V«üÈOŽ+:ð±P…î6¦ŽüÐ5Xå‡÷š?V¸EãºK“FTÝ0„|ÌTâ CnŽLÈÈxqÔãóoÇLWk¿gê˜#gRÂjûöíN³ä™7¢J¡ŽÇœÔ `¸’#X €õã7] 2»‘‚ÈÌ.$4 'Fðy탙íLÀÝlò˜ùÔ2ç:¦>å/^kêÚ)IõœÒ#$/lßš»ÅW‡t–å°²Å5/I; v¸£àf´¶U(™^ŽìLɉ-Þ³è&a¼ â'í¶!òPWçÎsŽ:øéÖ¹¯äêþ7d¬@A¤Có:Ügzàa©@仕„…;‰´4Ð ¸,ž'çzœgÚ…SX dnâwBñ€ˆ #PqvÕgˆ(4Í$¼&Ç }¯TëžéëçÅ:ó…Òz¹#(…Žájô9°Cäþ¤Ð  äðšH1qÊ+H 0_à¼Æ1a4Núu4@Ú0:DGG$‘ ¤Q‡=w®qR$WèjB¿¦i;åz§tæÜþˆö÷îâ¤O »AYuFhÁAl$RU/e-ÅW†õŠ~óé§9XVY+kñpÎïô`=Ï-Ì ¯2¥:òç˽ïÎE.Ãg’ƒŒ ew¥gîë.fà2lÕò»$ñõW¥ä-I`’ÜÌÑÎ÷$È;¦yÃiéÍ€ É—s!Ï4v—/_ž$¹¹62º˜ÎŒ"îèèPGƒH$¢ë$…ƒƒƒr)Tx,ó¤÷÷÷ëñÓYê?õÔSrèÐ!%´"›kîáÇ5¿=IÈ{ï½WÅÙù×éP°ÿ~Ýß)…O<ñIJO}à\3¬Èá88p;q s ×ÊJðð¹HÆÕ«W•¬¦«„›¬¦0,[@l¶nÝ*Äš¿Ÿõ»‡S)žoÞ¼©îì[ëf¸v+ù—qÎ2͇ƒÇ"Çç1EAÛP¤2¸€}CAÉò tQðÂ1üw÷wêÊ‘}Ƀši ñ$®o½õ–âI7 ®'þ÷W^yEƒEˆoö[þR5N¢¼Î_ýêW2 Ñ•SHx“x¥£‰™&i¤¹$?­ö)*`„¶;¥…¹ÈBé?øÁ”ˆe„½[ÄÅ|ë0€¤ëIuF”³. è¤ÀÈrÖç&ây­7n”ÿøÇ+ÂÂÁ–äê‡~8Å‚„ÿ믿®5…+$³IRS(D¼ÿþïÿ~Š“7-ÌMïD€óÜÜìFÛÓ8C’åf0eSHè¥HÁ/8×¶ž‰Ë~ô#ÅÄ‚…„8Ý( X†c¾¦¦Ft*áûtô p†xGŠ>ØG°p nEÚ Õ­¶Â9JW¦‡¡Kã~µÒ¬$ñÏ|úψ 惞9Ö Pâ¤AêÇÐa¨Û©¡7DJ¼Ñ¦yƒ€AÀ 0g†®_V VÄÒ¶{ Äz½q Gà —[×.¨¨ ™JKÿÈ8¢§ö CnÓÛ‘As®Ø`0 Õˆ€)`=Nò]#d¢dÜ4BQÀ^F#ºY p¼ö‘´açÁñ“öõ X¹ï)£u?Èâ¹Ôa=§ÿ-¤cHuýàú´¥^’]ÇÅ¿n‡øÛîAª„ÛŠœŽ Ø+ Cwÿl«yã)&`*/rÅëv’¼¨ß)Ö8Ò"0’ÅÁ>´ûçë R0]~/+¶n 0ê_ÓTÌPÇõc˵C uÔqÀH¡P@©@¤ÙºM[¥¹s³„*”×ìIÛñ*Af®‰§·øÛž×„b§,°ÇÓ±ÂßýŽ‚ûC(ªíæ¹0Ö<>Ž#´ÑëY5uX£"]§Åê½(°˜B)Óýçdö±üÀ$ºà>€”V (Þòz¼‡HYÌCö…öOýáÅ9½ ©ü ¤:-ôþ …f*ˆw“D$cQ™¡‹§ *°…IãH¥Y@"+‰T I8 ¸É°éš–Ïv·Ðà– eŠãhÀkUÖ†j)oZ'A¦NÀë²êzMpgÀ<Ô”, <u,›:l—’̺Oß.Õ>´á&Aæ bŽL·îŽCÈÎõ -¦Âze»I¨j©.}EÖKâ—)àè¨Fq 5>hóϨqFƒ3:Ÿ¤ýË/¿¬ÎÒËl¤€ntàµBdå.gΜ>X( ±ÊG®ÂÈnÚï»#êÝû‘Lg=´™'ñí¹Ü‡N |ÐÍ)õøìˆ Æ!˵îÒjþ‡?ü¡0ŠºˆrwýËå5¯—D«;Rž×F‚šØ$ûÝí¦0€8ðl;ÓÒƒ‚ §ðx’Ý$¶Iˆ»EŽ›÷eÏ À‰'´N·0Ä9W)?SèC1Êïÿ{r¸ÛÏù˱¦À…8/®¯Ž¨€œì1Éý9>*eüÜmãx£û׺=P ÃÂu€:êSTÄ9Ïñꔿþ뿞v­pöY©ÏFT°R{Î\·A`Á°d|dHº”ˆ*칄z0Gä‚UjNl0 +8"Ÿnu!¯,J 7&»ðR^Û8Ù¢ |®ÄaÉÊO¦äÆ­¨$˜¹TÈÀ¨­|Ö̃€AÀ `0L‹€‡Vô¹ìèAþ¦iÃòÐ1EAJ¨(î²ÀÏœ]mÀ£¶“Î @HÎ¥Ži/4Ÿ7@b¥‡{õ‘¼rL] |M›ÄSÛ&>>Ök¢Ö8LP–„%;È]jHä2‚ >€ÃAÄZ$Ÿ‘DeòRçóÂ-4pÎDººøÑîpM#„5x]!‘æõRÆ´ ÜV^-Þ(¢Œ‘Öƒe¾sp1æùJ«C‰x§S–ñ³3¬»i(œò†!>€Ž®ota1¥`H<¾úê«B~çL‰ðÁ(¹Fº@¦k­ÕI´-'â‘bFn“e=£°Ý„¿ #´s %èx@Û}Š+¦p;‰p öìÙ£®N„·s^þ½ÍyÏy¦µÿ®]»T¬1S}ÎþËí™D?Ç ÉWº/¸ m^+ÅîÂ~ÉMÐù‚B:I0*œ.ÉMÑ£çùÈUÚÚÚä±ÇÓ¼öÿðÿ n¹ö+åmÓPTA±ÉpºŒP¸á.ēⷃ‡û}÷kž‡–þtóÈåÔáÞ·T^/¦ìàzGw¦ f\ª««Õék…o¾ùæͦ¨cºµâŽWØ#*Xaf.× °¤qª÷ü 9ùáïåÒ¡O¤ÿò)XWçþBµ×aÎm0 +Äø˜\;qpÚ0Ø*A*çšò€´×•K8è—ýçú¦=Ƽa0 ƒ€ ~˜2Y9>Wº’É Nœ´ø¬Õ¢ûcg}Æ6nwÞ#ùÌýYÔ~Ý~iï;‡:2‡ÍçÉ‚ ‚ŽI8xËkÅWß!Þ–ÍX¿K|p1ðU4Ø×]¬v(Nh£bàj·F÷óoàäŠðW|¬xŒS¸¿^!žÜù”£ŽhßUé?u@®ìû£ŒÝ¸\ À‡›íÍë:¥éÊk &  -I³LÕö¥éÉ\¥û ¼v_cfÌ€ºsÝ7s Ü ¦–®„»uý‚È¥¯!èŸtw˜Úþ"þ÷‹÷)ô Ü Th²F|ø›ýR Ç’Dš …ºv÷•Ý8"ø@ ˆ7'{]‡‚4Hš4Ä¿é8/ˆ„Çû%>2Š›åpƒ!†ïøqA$âb¸O”L@4ãŒ{žj%>:ˆ`8 À?d²D×J顤0T©Âß ŠNH¸#(yé\KsPçëÏó•XÇ O=&;¶l@:¤€¨E3ÔW¦µKal$ñœ £^“cœL`ìðõDJÛl†ÓEzOvî|_̸îrfÎ3^:ãc¾õ®òãû7ó7Jx?üðÃJ¤ÑNº¿üå/ÕR“PæûŒü_.¥¹¹Y…L?Àk¤UþtâçšIî“ ¾çž{TPA¢Ÿ„ùL…ï?ÿüóÒÒÒ"‡V2—Œ¶ŸiÍ$QË´JÞR¼Áè¹8?ïì4„Bç:.×¶é° V\(â`J‚l‡ç8’®Ü—Xg Q1H;Ä“­0D61Ç¿»îºKÇÓ'0Ÿçu·¿¢¢bÊßÎñÙÏ…bYèqÙõóï\xçÚ–ëXnãX ?…þPX@bœ) r‰j²ÏCìx,Çdgg§<ôÐCÂ>™©³ý3Õ³ïQC¼Þzë-dÐ…®"cĄ㊸°/X²ÇíB^Ûr9·,—ž0×aXbRPËw}ó…|ùÛ”s_ì•T"¦‹"scW"ï?”ùÒÄH’1¨êÇÜ?õf¹xD<ø;gÙÉõ¶©ÃÆ,/ V³äz{±°éCD”ñùD¢øêÖæ»·`rJz9q挷|ž£}]‡ûîS°¢ZÂÕT5HîUÔåyµkj‘‘NukJÁN’k²Þ…žç+µŽ—^yKúk EX ÔÍ"5z ŽH‘‚À P.I,´É¦ø$†þ·Ei‰â5#7¯Ër¥ŒÈÈDR†GÇ墌Id9çùôÿLûÌ´îú*ëí9KW®‹(V„ÐL'4ïÍ ÚÛ3§=£èiÎHÞ“'O*iI²žd:#ö).  ~vúœ*+âÎÌ!Ïè÷­[·jÊÇJŸã’ÑÆ$‘Mb”ÈÐfH æK²½$ÊénÀgŠ º»»5rŸs„u‘p§£E¬¢‡µk×JGG‡lÚ´éq@>00%(– JR™×Î6͵°iM‡®ñ<Saðšó)Ü„6…(¼^#⇰6pýàûŒö¦øâÁ’ý¹ 1á> ;vlò<<%(J`:‰¦¦&%¾™6}æˆ1ž{î9Å–û²Î|ÛP(–…—«¬ëY0@IDATíóíž“c–˜lܸQÇâÅ‹5}-ý‰‰##^ÄÒP¤A\{ÿ|æq1ÛŸ “…ÞFÑ] ¸®Ñűpü®!P¨’ïz°Ð×¼ç¿ýëa)j7u Ëþ ê»xJöÿÏÿC.|ß¹aE]ß"=-Í›îÅëf8'–A¥œ–±Þkrëð›’¼ú”!²´¢ 9'ñ5Sñ–×IäûÿûL»Ly7»âÇß•ÄéO¦lŸéS‡Áj¦ñÁ÷m\ùI\ür¶Ë™|ß×´QÂÏþo“Ïö" R6ñÍ;¦ŽÙ€Âû«å7®’»Ö•# âs& ß¾ÉcDy h³‹AÀ `02X°ÿ¶@ìY†kºÚ¤ƒ÷ ß½øì¨™)`áwœâ;cH”ëVGT@ iµ‘žrÎ=Ç:¦^´¿,¤H^;)ÉžÓ’8Û÷‚vñÖ!r¯iƒø;î?R%,×sm,Öï( ž,X¬STAL½dxµÑ¾ãþ΀»¿ü]+Q1MäOMSqýè‡Òsø}8ý%!D( Tà†fû–{¤iÓ6)«qÆkËõs€E¡ÄzÓÓGÀþÞE!JÎÂÈ|¶:Z7Œ'þÖ§Ù¥Dë°F1·nœ«ë´Hô¶Ýrvó—ìï Œ7¤)ñVCP0Æé›"÷‡/\¡Ám’‡”T%‰åaܱö¤@ % Y‰F‘&×”€£S'LŒhŽB Ÿ€ÃAÌ$0¯n«æ]ýÇ\;?y¦OW×I@E-¬n’‘úVLã DJ¿=üÛœ/ 8Ï'/jÖ¡éPÐ÷l·à@ö ÿ¼Ñ¢¼îüÌ™¡¤†®Ëø­^ÅxMùe$á‘[CÃ200 _}õ•F³Og3?Ãi§¼•ïº;y…bEƒ“ç\å/HÐ2ÀÎ;'Å$⺺ºäã?V#|_|ñE wGŒ/|üL$ÁÊ U’Ý$ùšä¹CªRT@Ò{>Ä!‰r /ø Na Ǿ[Tàˆù̺çSx½¯½öšÖÁ¶PTÀóÒ†ŽŽðZ)ãµ±ÏçZˆó† ã\¢׳‘Õ|Ÿ¢ YØWt}à¹øÚP”AqAv[éXpï½÷ªˆÃ!ͳ÷ÉÕ¦B±,ô¸\×P¬>à¹ÙwtÜàƒ}ÊqÏ1ÏEümÀ}ø È…:ÇÎ\K1Û?׺ç³?SuìÝ»WÓ–P$E|8î9‡ˆ×>øw>ãg>ײŽ5¢‚•ÐKæ  ŒÀÄØ°ýÓ¿ÊÅ/?ÄïQŸÔ¶m”ûð ÙüÝñºSkB¤}oIï…ã2tã†$ÇŽ#§"¾Œµ×E¤&âäU¼ób½5Pq=ñêoL³…7¼Æã—eâ&¢ò,¦ƒÕlCe±ÆUtø¸ÄFNÍv9“ïûÛ×JÕæGz°_úΙ:&œþ…Á*ÿuwya…[ŽzÓgú¾5ï ËܨòñÆ|Å ëv3× ocßhß’ 2ëñ<Ѷ­ÈqO „3"âI«Ýa?‡*UÏ>a4}æáATö“C,æ:Ž™ÜßÃÏY0³õí\êÀ¾ ^PGzè†>w_m›¤zNIjݽâ[sÄëáºÀ2,$\ûNî— {þ§Œö\о(ä2›×µKËúièÜ&{tW˜Ç:\È5”ú1ÖÍ.;åÁ­ë‚pü¢EÜ·†µâ[¿S<ë!¢+IF,RÔJrŸÌKR9‚y†õ#Xá‘H¸Z*±À¥aoÁ+ŸBƒ8Æ; âH‘‹"}¢Ü!8˜´ÎObÿ$„ År4p§O9¦¬ª—„^¤|(WQAéÖJ9¸%A+)~~º‘˜Rt ËàN×TQ/^<ñ IªsçÎ)éYôJÍ —Fí’Èf´9-ûIÈÑòžî¿ÿýïÕµ€Öõt-ؽ{wN›û%¹pTÊñȨöÅ(´Mçc¡ ÉaÇ–}¾u‘„çc¾…Ü|й Ð¶98R¤’o!I^H)ËBËuÅê÷¹)a…*ÅlÿB]£s^ ,>ÿüsMåÂtgΜQqPHЙ€BÅ9N=¥öìÁ8ûWî,-£ò‡‹¡…J¡7ß|óŽÃ©„ùÕ¯~¥Û9I¾ÿýïOkwrÇÁyn(•:˜{æw¿û¶šx¾òÊ+ªÀʆ¼v[.uÜiýÓŸþôŽk¦êì׿þõÛ³78íà¸u0sï“ïyÜǸ_Ï÷úÜçÊõz¡Ïï®3Š{ü×”ëïü£D‡$R”ïîºW¶?û¸PhI4–”cg.ÉÉOß‘¡ë—'çý‹`Ð'›Zêåçÿ“4¬ß2ùžya0 |èºt^^ÿ—ÿ[w_Û±A~ò_ÿ{¾‡šý %B€9ù(´0b„S–Nßš>*Nß8w\˜‚À³oŸx>ý´ðÃFVž|Òvˆ!ZB,E„¾ºLwfÔF®v„kä9£ú5²ºý±] ò¬#ÕwA’—¾‚‚}†Ó÷-ØZ{«ÅײUü-[ÄÛ¸i÷:ÄWÓ ܸÇMl¼‡EÄJ…`0ÒÚŠ¨@ÃÞ^a“^ KÓ “Išò&¸‡„#É{m¢ùY¼ˆ—€Qh‘|F~yT"^º%húÔ¨î1Xèß<{T®~þ¦ŒÝ¸R Àâ³é:vî‚‹`ƒx)ž`z¶ÑÐLv3ånþc;¯ÅBJCn׈*ºdÈgu0P‘ vÕ홸äT¸0š—§Âùé|±ŠêHwÙà"i¤ÝàxYŽÅÓ† kï©i̸T,Ï>·àŠ¡6ú˜G)Fÿb홈"xtLX‹â¸W71: ÇQ‰a~&ádÄýáb rõߤÐ∠Ü8p")«m”pÛf¤ShD DÌBUçGŠ:xæ;Ï­×cgY˜µ¤Têxçí?Ë¿ýê7r£·/Wͺ–ú?ÿùÏ¥¹¶bÚuWÓqíc?†°VsMä:¹q³À‡~Ö:¦ÛáwÿãH 6쌚f4/‰9M$,ùàk'š›#ZIL‘`ÓÏ\‡®ÇÓUPÛO7 Fü’b’vÄižþyù‹¿ø Ü'†¦ ¥@€”ø7ß|£ëÔž={dÿþýêfÁk¡ø…®t( hŠ¥µ›k 9ÜR,KîTÀü1ÿöoÿ¦ØòøÙgŸ-º¨ Tê Aî`EKœÝP÷{`–b¥8q‹Ù¦qüûà·ÿ¯t¤4—æšê l Jâ³Þ.Iâ á™ë#rø\¿Ä‘[?¬Ê«¡4.¯Á ’.ýx¦oL"ƒyú?ÿ\¡;­š;ø~/ï˦…gøéÿ.eü—¼1u¬f,‹5®"/ÿ„v}¶Ë™|?yé° ÿË›ü{¶Þš5:?L³!…û¦«ÙAÊì±ÔX…ŽîÕآuMøøŸó¾v³£AÀ °4ඬl^7ºo})ã9˜C ɾ5}´0?ÞRøy­³"ãaŠÅ÷‚Ä…ƒâ«FTrc§à^àïxƒN[Dò”ÒÔB«ÿÑŸL!QŽ,ÐíDº7WZ­)'˜ê…d< +¼BÈoŸƒ¾ú­tíÿé?}–ð°Ñ/€¨WUKÓÚißqŸD[l²ßÝZ¬C¼ „æ¤í€àb:ሊ ªÐv°Í#(@È?îaòìRâuh¿tCPpTdض»Í†`Éÿ¦ ¦e£ø6W¬p¹-IFíñ âåÕç^¤!@D]ovd.ãDSp(HC€“N¦$£Á`&]„ 8ÀÝ©AâòÜ’Ø?Ïx¸Y»)ŽÔ |¸‹/"¸¦ Î Õ†¨À‡ùàG„}¨ªNÊÛ¶I°®9ó>r(c®g`-ðZRRup -`-ÌÆ}ºu—X¥Ñ¬ƒãСÃ5.“Æ&û<æïâ"@ñ­þ™ÃýþûïW+qFÿž={V'Ož”#GŽhJ„—_~Y6oÞ<«õ}q¯ÐœÍ `Xí\¹rE˜ª…  ˜Jƒ…¢0'ÕŸAØjÇ+Wû—\Të¢Ì6ƒ€A`ñ€~\jÒv>Ç Ï+›+%àò²@’¼“ÝÈYAV µÕÒ|ßcèxPn]:!W÷ÿ /Q9ƒÔÛ_üϲæ®ïâMMƒ€AÀ `0 ƒ€AÀ `@$tªÿ’¤n^‘d×qñC¸ëgZ„V<àbà«n¶E‹„Ôõ£JÏÁweàìü^+¨ÖŠºiß¶Cš6l©‰t$ÅÜ‚‚‚Îjr#` õŠÕý­X]p)€ÓF±Èkwó~]Ó,Þúuâí¸W¤ã WŒZ|BáƒÅª™_])UÅ@c ã; ǦM £&Ó†0eB 7û' @ Ð çŠ RØ/W $sÑsÍ翜Æn\ÆCä–ëDDêI°ª×Ù$ü‚ø Rß*òju5VØŒ®ÃÌKƒ€Aеá…^Pw'%£{{{Uh@7ƒ¨kÁsÏ='MMMêf`À3  …ÀÐÐ|ôÑGêNðÎ;ïȵk×ô{ÝgèHÀ4t( ÓL!Î uÝËñ¼K.* Ð~ô#ņÆb—R©ƒNV´á z¦Ø¥ÔêˆBåLE¤)Ó#àENÍJ-ñ¢ÆªÛs?¨Çãi¹9Ó{!,²kk¤¶jí{—êuÛd ézOì—ØØ°t8hDÓCmÞ1 ƒ€AÀ `0 …D€¶ÿ#}’ÀƒŽ`ÞúõâoÝ&ÞfDC¶"MBó&ñ„9èn <´,GÎu'ß·ÒÒŠCÂd¦WÓÊܾuFç3O&å“aøÓ1ìŸdúä–O‹ô=,öþ2Ús¡ wÂÓжNÚ¶n—F ü‘Jû<)8ÐÒÛ q: À%ׯkB»=™m6¼ÀnØŽíˆö‰!±|´uÇñÁÌí@“)tm€uÃüê@”*‹Vay×aÝê–4Óô_„Ìëå Ëç©îíÛáÀÑ!B à sþüû|ôSv„85u‡WÂ’–  ˜²ÅJ[¤TP Bƒ±MŸ@ƒ‰ KhÀEp îâ¤O à`Rh@Ay¦¤_"-Âå…ÚŸù®%\kÔm„–ùÄfÖ«¥¨ÃÃô0™qéÆv®¯Ýënv;Ôm†k%SºbgQWš¹VböŸ7ò“ŸüDvîÜ)?ü°’yŸ}ö™ôõõÉ믿.ÇŽ“/¾øB¾÷½ïÉHñD¾Ãƒ€AÀ PLèbO9BŠ ¸î0U ¹hŠžvà ž©ÒÉ!3] K,ž}Ÿ}!#CSÝŠy]+ù\™oøK×vs!9¥Øvþ#*` ÀÉ’!ªôŠ @Øã÷pÿÕsÒõå^¤ ¼j &Èï…74›×uʺí÷IuëZät‡èŸ×–Ç5Q¸€_îAlóf‚@Æz·…ØÙ®„üäÕŽXƒ#b]C4>ߦ¶à‘j±(0¨¬ù†ûK)œuˆl* ,š‚7´ ÒÌe-—:ÒÝgĺò5]J6:Wº¬ž‘îÀÛ LM‹=1šgŸ¯¤þ˜'|±ëÅ<ôú1–0vƒ¡: ƒ°¯„H& ñ€" «£A Nt6ˆÜÒ4 Ip4 „“Aû'q\±(r¥O"MB„∓ÊÛ$XY/¡Úf ×6ˆwbÓ-"A¬¡ÖÍH“b߆Ÿm-¡:ÉS^¹JRœsM·B€8Ÿ2jëÕ’ÕÁµ†éæY¬Ìº›w;4åÂä¢4ÏÚÍásE`ëÖ­²qãFM‰@Ëñ?ÿùÏrôèQ9}ú´œ?^S#¼øâ‹òꫯªäž)ƒ€A`¾œ:uJÞ~ûm}ìÛ·oR4À-/½ô’0 Ëã?®ÁÛt2àc"—½ï¢\Ø|ë/Õã—\T@`C…V uÔ]èv”Zcc…Ù –ê„ÏÝ.DS0 …â‰xJaûF€³MßÄ^ç‡Kf˜ÅáP ǦÙ`ŠAÀ `0 ƒ€AÀ `0– øÝj HââR#|÷‚vMàïx@|H‘à¯[gGIózIÆã‡1‰Kñòw²‹„r ¦4 DÿÈõ+Òs|¿ôþJÆû „«ª¥im‡´ï¸O" Ívt²CÆë¥ášp}0´¯SŸ“`œr5öl3¯í¹~I¬žs"Ý· ô²r86TƒÛÃmAX¸[Ì;Ž<ò á‡û\àĶãþž¥£¦”i® ûXFÐŽ¢Ô‘1}ý¼Xg¾îÃe¸úwÊõ/áˆJ÷PP°~‡Xe:çÚçEÁj™õ¹×€ÐÀ&ù?¤1ÐÌ@0@Áøˆ¤ù€(&KIt"¦i:':!‘A )H˜>AÅE H|x@ÌÀ¹£ú¬ŽµM:mB‘ ¤K¨’pË)kX+!Ì·²šFM¡€ É”Ûlœ™õ‡ód² œ¹®gwýÇñ[Àzå³$uLi°«-s}YVs­Ãì_Th1þÝï~W¶oß.>ø F 3jøâÅ‹êVpâÄ 9tèÐ$Ñ×ÑÑ¡9Í‹zædƒÀª@ §§GöîÝ«b>ß¼i;0ÕÊóÏ?¯&¦haºw¡C{Þ}[†ñ}Þ”Ü, QAîK3[ ÅF …#=ÃRÎOÊwCW¾]ìË4õ ƒ€AÀ `0 ƒ€A`ÎX ؤ_?#©g!28qR" -‚oí^à TϤ9`Ð…ãRÀŠÒ£d1µNÝÏKr” Ç¥ëÀÛøm|ZÓZ«oåý_E}ƒ¬Ù¸MZ;7 Ê™78IvSÔ`Gôjj?iTl÷a›CÌX£Í:·{( «ßÃk#»û.‰\DD>DSt¬8Rú¯ðØÂý ’“Vôp/ #‚UÚîóœ|â1â>¬ƒ NÅʹ&œÊN¥`+ T¸‰L.¨EªÃº!Vß8|#2rs* À2øx7vŠoÃ}À8ãÍœú¼HXÑcÚqµŒêP‘„¾€W,÷ĪW%Ó*8HÁ¹ Ç’Ü Æt¤®x¦ÃA, —¼O d¦SHB0eŽÌc8är4ð…öCLÐ$L¦¨óÊka[¤®UØ* ‰?T¡óÉÀ|ËÌ) éU¸v±_8ŸÔY„óópŽëS*`µ€8) w…¥«cðê¡3·Î..ùözÅö«Û2ùVoŽŸ ˜dºƒûï¿_­Çé0üÞ{ï)éGƒ¯¾úJ<¨û<û쳚ç\?cæQ§9Ô `XŒŽŽÊ§Ÿ~ªn(t( h‰ŸítÇ衇„kÊk¯½&tOñf¥âq Œ `ö±bD³cdö0¬©´œ¿1"íu)›b¡x'T€S…=ÚsñÎ7̓€AÀ `0 ƒ€AÀ `0,Wpƒ1}ëªÄñHœû\|M› ,ØÒ"´n_í:DéƒÄ'Ÿ)Ö8ò«'@V±x›AB&¤ïäçrùãßËÄö)…”†¶viÛº]êÖµK «óÈà I•¼ÇY½Í€ÌJ4â}þE·@¦Jƒìõé*à‹Qø7΋\9 AÁ­üÈRä°»ªBk°GÏdñâiÉs‚ñT2ÓÂ6©ªÇk<ó5Ó1øm›vû üOœTì€×ˆ¶/´$U=LAÁˆl^‡SæZÇúo´_-å- %HÒ2ÍÈÕeQ`›ïíÜ)Þ–ÍJ3“„í8€¶çÑçEÅjšqµRêðù¼âCê?Hz‰CøR])•Ò€Ôñ¦Í˜DGF„Á2#Ã2""6N±Á˜ TpWO¦ú,†Ø …¹5vã2"H°2Y4}D„0¯‚‘* àV²V•u¶«Ö!]à´¡‚Î7´Q 0ðq,ë¬Åš0Ãzåöóˆ¢Tb×OBÅ^Xt.XX+`÷°°u0m`æYflÇ("R)Àжf„—‹yVk/"­­­ò³ŸýLvíÚ¥â‚7ß|S º»»å—¿üåq" t›cNe0,!)|^>|X (Tâknóás‘î(O?ý´ìÞ½[vìØ!--HY”%(‹NÈ[ï¼'ï¾c òéF#*È%³A`•  NCãrªgHîi…jÚoߨÈn~?0.|#—?ù½¤ø#܃€AÀ `0 ƒ€AÀ `0¬@˜›;yõ˜$¯}#‰ê5÷‚mÈgÔp1ð–#jŸÄHr Ñÿ,cý]ró ¹²ïJâNÀó´tn’õ÷> Õ-mâ-+S wKÓ2ÍA†HçŽd˜ñï΂$Ü9Ø=t6—6pMÒ¾‚ÁUˆFçGˆf œz'¯õ^Š ‚Ò"ÉY—ƒ2¤T™›Æ5y2® …¶Ã®÷$H¨ç¸5á´›ûåS‡§ª× QDÞx\#µÙŸÖHÌ(bÑ¥4wB§Ò!^8gÐ-b²½yöy±±"Iíà댫•^‡—Që¸ø5b]T³TÒÍéR‰dFh•è@¯Ä£#p1Ç#¡Ïãp6`ÚÐÆ ÅC©$Ö‚)óÓF§ÿ™:ÁIŸà¯éêZThP†T$~¬ Á`HÂUuâ WH9Rc”á}¾g “\ŵ^ñZ'§¶ß%ÎÉ«iIp¯B¥´?)¾ÉöáÈbÖ¡"žÉ•$וç·m†v¨ËÅ ¤½6hã'Èïüf¯EC€„ß–-[äwß}W#Œ™ áøñãræÌ%iSNwƒ{î¹÷ª§ó‹vŦ"ƒ€A`9!pþüy0ʇ~(Ñ(¾Ë¡¬_¿^…O=õ”<òÈ#R†ÏRºžd;ŸPPðÇ?ýYþãÿˤ<ȳcÍ*œ'Pf7ƒÀjA ·‚ã]CPs‰¬­ Kjò‡„@ ?¸Î½›Ô«eP˜v ƒ€AÀ `0 RGÄ|úVÜ ºà^ð…ø7НºܥѻŒÚé¹ 7N%7¾ùLÆ®# Ö&óçO¸²Rê[dý}He \ åÁyyMëD»¢òµŽL=F)Èý¹\ TT€íéž³¶½?Dêb0—‹šË¾£·$Íxk;•¼}$] Â0M®Éâu…+ŪjÄv<‡«@N2ZÚ&gj‡6NÏ r®ÃÁNzl¡µù¤Ò"¬p œ=`C8Qx©Æ¶DÅ3> Á]"П±ˆ †ÅŠãÆ4¢×Á2ãŠ@„j›\ÿ#OHwPŽˆsÚÑgJ¾}¾ Xe«R­ƒÞ> þnc|ýŠÆˆ{¢*H¥,IÀ‘$:<$‰Ña˜[ÀÕN©XLÆñœÀsâ nBh±‹«hÚ8øàÜQÞrD‚Õ p4h”pu#2ø¡E©• æÓ(¨ØbÛòŸs…·ÿmR]Ó(0 Ç3ÝM˜§|û0õÞÓõ(Å©ã0‰`"]0™–ÃY£ ©C]Mrªe\­ýåLíP‡ŠÜépý6³ŸÛì±øƒAyòÉ'eçÎòàƒ ÉA>ºººäã?–cÇŽ©¸àÅ_”—^zIÖ®]{G¤ñâ_µ©Ñ `XJúûûeïÞ½²gÏ¡;A_\ºðÙÖØØ(Ï?ÿ¼¦XÙ½{÷Œ)TAÁë¿ý ÀÍ*óu¦vEð9Åw‚|öé<+ù=#*Xɽg®Ý °à'‚ŒÆ’òu×-¹12w¦,ÊÑxR._ÑîøQEÃ6X§ÁrŠmS ƒ€AÀ `0 ƒ€AÀ P ¨{A××p/8.‰šñ·@XдA†=Ò‘ý ÒÄFV AAE]½¬iï”æÎN ×ÕØw†íò¨­y†¼&©ç°`)¤V ±G"Ðê9äm"éé=FºëÜ!¦>à~‹]2®Sj.‹HZ… "+2¡u#„p7`ÉÕÞÌUg‚LÃI &‘J8“Ȥ;B&jº`¬²ë(¯‚˜"ƒ ú¨CÓ:À‘Ñ‚ÐÀ‚e½g¦J˜€È€B¦]@${¾B½§3 °×ø€¿xàöàiì_Ç 2nséóìv,V« Ä1>ç,è0ÆD ’£i¸0Â8"'¢H—06CQ¤Q˜æ@||\…Iä$é„Q¤¹>X.ÔgMqb$[T¡A}«”Õ¶ [I¹”U×K ¼÷íü“KIšé&0~Ñ—ÞÆç¢þ½¦{P‡×˹–qtàÜKA=Äô.¤[ ð‰ëŠ/RmïÏ?\éfªÃÂæ8Ÿg™©©ÈÐ:Ÿ2ui:–)«Ó<¯À¾TWWË~ðu-øÎw¾£®Œ<’?üá*,8xð ºÐΜûgG/Äu™s Ëq|Îîß¿_׊ Ξ= mmZÂá°<ú裺>ÐÙ„b¥™ÖGPð›×!(¸Õ—WÃ<öø“òá{ïèg|^•àNFTP‚jšd(šÊåR_TbÉ”\¹‰™Â¯Þ±DJz¡ÒGñAÍܸá.ÔËÅCè6óŸAÀ `0 ƒ€AÀ `0Joé[Ýp/è–[§ÉXHF£ã¸yY˜°¾¦¥UÚ·íZDC+I‰ ƒ»Æð€Ðc&‘LCTd¡AŽÔ >8…”Õ4iê„0œ ¤6Eš’¶E 8ðKJ ÀúCgwÿå'‡×Tˆëÿv ÝHr`¡óë$Sî¬crK®£óÛ6kY§q_wÖ[æÏå‡@{{»üíßþ­F;â‚C‡ÉåË—ÿöÞü»#Íü €ûNФ¨Ô¾P›µÛ²åò^¶«ºª«{z©î33¯{~™ßüsÎü0çÌ™3ýæt½êé®é¶Ý¯ì.[’]–%ÛÚ­ÅÚ%j'Å}ßID¾{#‘ H‚$‚{„”D"‘™q#Ȉï~÷“ßüæ7rýúu±ÉT6 ¬¹NÀÒF€Ä›7o*U†J¹pá‚"ñ9@ «®®–wÞyG)™ìß¿_ýÎÕÖÖNúLl ”BA' ¦O$>|D^>t@¾?óGM*˜²…sžÒÒÒ¢dnrsseåÊ•I-à\åÑÐРd9œ]ËËË“²²²¤Öc“®¦¦¦EŸG$(¬S}}½Æ*”ˆý™¶¹±÷ý‰4vK=$¦Z›¥"µ`Á|à1ŠÉGn~‘”®Y++7í‘N°EŸÂ31»[įÞDŠíZ½{ìÁ©Þ‘õŒ‰x´{Mv™Îƒ[ÒXÍ.VÄ7ž¾ìjŒk|PrUç[_×XÅþ½;ßXÄÖ¨ú,€F@# Ðh4sŒÀpО€Cš‡ yCV¢¾®%k*¥œ„‚r„; ó, ‘^ùJÔx„ŠC­¨p! JŠ`2Ö[!¬Ï ök†F@ý±ÀñËdB-@…eIB]§ÊC‘{øMÍz Ì “ª‡ÚÓ 4îܹS6mÚ‰pâÄ ©©©‘k×®ÉÝ»wÃ!Þ~ûmY¿~½¸ D'€F`é!PWW'ÿ$0äAo/~·‘hæøgX”×_]2^lº4ˆçù'¿–?ùHºc y0J(8(ii–ZÏtù,åÏÝ7-¦d£}ýõ×xw ™'É&ÌU?üðƒŠ D)ŽC‡%ÝPθ_K!È8„‡î«W¯j¬"A‰ØŸi›;c°äÿUò1¡iil¶æéF|b ’ŠÏÓ3Ò%£¿N ƒÝ’ꯓög5ªœžÿ(Cgþ!¢DÖ.Ui¯ýý„ã“019<ý!ê½&»Fç1wÕXæª_ùžÿýoÇf>Å;GNi|ã#DZÐyLjè#›|¡±ZøXùšZ¦/¤>C# Ðh4À#00âv¿S:‡2„*@ù;S\RTZ!k÷ìG¼öRÄ+ÇR½ïí»Ñ€n'†8P2Ý8@§2ÈaÆK‡íE¬¤ÃáóßX#æS Úë-C}…ôZ yÿ•[@(X C.Œ{pFp!ŸÎªwilD€zì€\£·aÇB6J–}†XÍZÊÍö£!šõð‰£·*}ʘ™‘Y€úÀ‹õKÖMlY˜þ"%ÄØæ³VU&ÖcÔø»(Ûc’z˜=ðBl~"fÓcEþðA zþ‚„/dùa7žÃ€’Ñf&Âx„(c0Z{8Ðwé©âJÇ·EV¶àŽ£ŠPÿ$á`j ƒ=]ŠXàóùÁñ!5:D? XÁ:\¸¬Ìlɇ<¹)¢€AS°¾×Y÷PŠ7ï—‚GÑ C‚ ‹’‹ƒý: ¤†F 9†á9б‡ÇB)8Ø"Õà´ÌBë; }Èõ “c˜ã–ت±Ž· #2<€Ã‰)½Øùòuª<‚ S ¼†Kɩ߱h?»GÞGï/|¨B@c!=‘÷íÛ§$ÏC½¹¹YmÕz)¿ñÆR\\¬Q~Ít 5é`è“ï¾ûN >ûì3ålÎßŬ¬,9pà€ó¿úÕ¯¤´Ï×!BàT÷Æoî™ÏOÊïÿߤ[)LÿdïE!K¡@ llGŸì# ü•†þ?þø£bŸ•——'½Äs•=îYÆûX½zuÒëa{õ/ö<"±ëy,ûö};V3®ØÄTàê*lx €åìD|8ȹ11`èÆ¡oÿA†.üNüð$vbÁ„‰ÏHOsTmG$ÖâP*0‡úDf£¨X™Mü«óˆÝû^c5»XùnŒ:&öZëˆsqŒ*øîÖyLhÄqUìJóU  ±iuÒh4€F@#°€è…:Aë°*NñC­`úelj…Ï€ºfAa‰”mÞ*E%0NÒÀ…óàA-)ã:æÞL†2Âs‡ŒÒ4L3Ðlz(fÍE‘žÖ¤­›'é/ ‰…+űj›XYy ©GdV$а¹tåb£ÊG1Ç\Âó‰=ЂÀ€Ñ€¶I#0±³ ™öE3É÷˜´=ìûó•yÀ žeV†j2 › I‰¸&¦68_å‘(V¸OÌõX"y[ž‰¼¸±3 ÚcŒô|Ï-_„0Ù_1Vé9 €À÷Yyèc ¸¡r`÷1¶i ýÊñàÀ}íExw¦W2óó Ðé‡q< ¯„IP¡â‡zR4€ÊÁðÖã rÀ #þ€E4[âÈÒO¿uusÄ”Á¾n¼gžîÉX±JÒKÖ ”Ç >Ã÷ 3NÔK%ÔQõ™hwˆcÉL „()x2T„ ú\£Â!øpòÄßǵ3U¨¿K¡‡y©ïÐèß¹qå©OžW ä—¿ü¥"Ø!Ξ=+mp†û裔ʼnpøðaetœ×ëÌ5„ð\GÇâãÇËÉ“'åÆ*ÔÃ÷PÁäÕW_•W^yEvìØ!+V¬ˆ™Pðõ7ßCíà¸ôt‚dÃo) »vï‘#y  F›Ó~ž=²À÷È8ÉÏÏ—ÊÊJ¥TPTT”ôÏUü1d=Üx -,£3ɉ2AK!HXX'U$"c÷g£Í]œø`³ þ:i4€F@# Ðh4€F`©"Ðu úðš¨OmvšKÊVäIÁªUâÉË·ŒÌ4nq“†.Û°FÃ$ÖºT¢%Î2¸1BÃÀ„1°¿KI¸+…‚Þö±Rëóÿ7^Íyåâ(ßogem£º*™U«®¬3ëÎêCBÕrë6yB4 Vý UÐ`Üݤ ¿×.à­¼¤GžÒöÊSe¢\}ByLÑI«‡ÎCAiý™¦ÍcÅ*ˆP% Ež\ä™cJp¬nHÁîæÑKЇèùn2”…ÝÇÒ3ap‡7<<ÿ…á1R(õo§©ëa@ ›Ã“çñâ™ ŸYf†" JAªC}}P2è’áÞnFa„J ¥ H#3 €,^áûÖ‘IL4€F@# Ð,!àÀ+] 4¹d¡ÔóOõ+ÌvKIŽ[rÜ>q6J°%ÙóbH„)¯_>{©ô¦ÔxÈ­×A/w%ÓLáTa'†r3;aà|qOLz^C¦|ŒÇµ}â|¿æ Ž¶:;dlW¥.€EcKRžÆLòÀÉyE¸P$‹PÝqžò„¦rVÒöL̺ÿP'ćiL{Áœ¤[ÉDÌxªÀ€Ë¹ªIň4h†áÑ @–=JSµG²ê¡ó@«ÅØæ±be÷‹ÙúáA®‹€|&ð¨^’àŸ¾N dõ#ûôä7Ñ߃ŸÀ¾fx-2 Ç4CzÄ0ιÞå¤<¨iHJî…~šcxp*ðÚ B­ ÅPoŸ4?­‘¦º§2„з%‘¥Šyß›W*%Û_7ÔD¨‡ ¹‚ü †ç‘L„C ™ PÇŒŒ|U.fâà fXù1DDH«€á?1ƒ†|(ž1Á6fû©Ñd ¬»Äüwª<ÌL”‘ß1û¡ED’&YNŒ9O}âÂA€¶†Bزe‹Ð¸Hã#½™I*¸xñ¢Ü¾}[®\¹¢â¬3Þúš5Å£ñqáÔR—D#°¼hjj’S§N©±LÂPk«¥ÆE%‚#GŽ„·ìl<ÛMf ŠÙLÛ·m¯'DŒ‹rïåzhÑ‘ ØaVåÍm¶Ò\åÁ4n³•øc¹òˆÄÇårÍ fK«¹¨Gd{Ìæ>'^®ªƒ’Z±S…«Ä@<7cšhÁÞØ˜fv¹ÅUÂ-ž¤óˆ­e‹UÙVqb‹'Å•Î#fxÙº=bƒ+&¬ÿÒäbVO–¸ÀÕ2,ÆÆñ@[iôY€F@# ÐhæzB!†$8P×ÌpKE¡^M¾⹩³ÏN-btÕ‹™Q  ^Œ»N¹~Îqiì¶“íÑk¿½ÒãÚ¡@:Âôq§ÌÿÛbmVn£x-ê4‰G%ÉIP?,IâUýhT¦¡|‚QR…€¿zÞ$V*üÃc1^™:üdäMn¼g{­ugeÆb4½¥A:<Çš ˜ð0§w¶ÁXðÙ ~Ð8L2Ä$í¡¤ÕgZ»®: ë5Z›ÛgÄ€•ôvBÍ㩘õP)€²ûØl¥!¸…î¯^Ã} ¤$¥làQ†÷,8Åq\¨ÏadWFøq‹2>èéïô¦« F!Z{º¤¿¯GüP,H´~Å+¥´ú5)yé-ñ”ÁoϨeÂ©Ü„Š‚"ÿ0$D(©qb¿‰x5ò P\Á%T3@¹iÑgûqœ'aî8U*ôHDyÔnH9aüaý~q#‘‘!$ P‘€Ž•”Jÿúë¯UHî_¿~]ìÇŽSŠÎzíbq·¹.ýÒC Š<çÏŸWã—ã–ä †øæø>tèã u“Ò^œ¿Ã/”¨B ·&Dëq‹ŽT­ú˜F@#°´00ywäVˆ§t‹8 T “F@# Ð,àUbÀ ÇY¸óX(ëƒçO¼@ÜX(ÓI# Ðh4À"E 7D&è 8Å4ÂFÂxªãMu‚P"¥ù^ñxá™é £¸ |›Ñ~xî:ÀHÏ'½˜•'//€g¯m¡dhH¸›`@Lz[ÂÄxê÷¹4Vˆ«r¯çï4دG ìÐx&Ø°ÒØTÝy ›úˆ¯À×ðÙ³ãöaô¸ ªãŒÀª®4z‹<‚AƒoZ–>Òöž,E00aÔ5` U@¹fP•oøÏ¸6Wõæ‡:Õöaœ¸35VfG#ÈP¯‘G¨V0›„‚1åŠx¥™Ëa¤Y!8Œ²õ"e"úúw,mËH2-ÊóÛ?B€¡E]"rŽy7¿r»”î8"yU{š¥Ä"РðÂÜŽ_^T+`²÷A°B“„ k~B_XŠ”À±ÊKàäf*•€ÐØUGñ‡y`KFš2S˜8_µÆ~!'£ú ’’ùË¿üË0¹€!.\¸ òÏÿüÏŠ\péÒ%yï½÷dÿþý’žŽïs4yE €0?7nÜPd*P]ÄU:S„„¡·ÞzKí IWW|DA NþN¾L ä&LÝ54©`j|ô§À<  ØÌùå–wÀ<䯳Ôh4é0±Xcø­Ø¾\ŒeìM4€F@# Ð,2:î uØ)}xMÔÜ•A)Bäg§Jª{¡`”f§Á3@õ ̾V1²àŸY;=üCFFxûšmµ0 ÿ¨$ÜçÅ@:®ìÞ"μQ¸Zœ[á‰]BÛ–ÊV4 2Y²ïÖò#=ˆ•ñ‘ÆKÛh‰s”òü‡1¤à ”AЀd:Ô è½Þ Ü,’íŽ|­ð ÝÈ#Äk`Á•G9¥í¡ZRI­"@é žkTëbȆïùXꊡî–ñ•ÙÌVË1䩽 Bˆ ñ,¨4Œ96’  ˜0¤HЊÓøðûd µ ‚O¤öÞ]éïA_ Îã­gIõQ©8üd—BY¤;ÜŠ ±2Ôc[6 ×pŒ2‚ã\gŽÉÈþ>ˆ°·H$M¨ð ÜOEÈ~—aœ¸—ÝßÕ8ó „¿Ô… þ™*sß%P„1¢å¶Ô F  f«/[à0BUU• üå—_*cå­[·äÎ;òðáC¹zõª¼ùæ›òî»ïÊÖ­[•ñrWIO#°$ C0tÉ™3g¤§¿?HkÖ¬Qc”„‚£GJV~‹H*ˆ' É7g¾—“'ŽKOW[L—zÓ³eÇŽ¢ ÓÃ¥IÓc¤ÏÐhæ<øÁìžLFm.‹¢óÒh4©PÄHaá5ãLפ‚©ÑÒŸj4€F@#°]» D‚Æ!— &î€õ)™ (3Ur²RaŸ5O[WzíÂó>€Íh¯³HŒ?NC_z®8zá‘),bðœ‡aŽ’â §-K"'ä#ÌØF1J7(åÛpÈ[1~¹°!JîË´çE$Õ‡ö†Ø¢q˜”)“U'®¶@Îþù-„1¨·dÕçÂ=ŠÇ¹E4©žç‚ô&Œ–a¢Av¡2žNU»º‘¯ÉÆ*òÞöþ’Î#¬æquêp6óñJvÉ:qVíAøs¸×Ï(Ë´ã‰Þ†:i¬¹#ÍÏŸÉ`? $Ðÿ½…å’¿f›¬zíÏ$cŋ܅" öª±kx €Dï3(rL¦J§B?$€Äs Á÷þ*¢„`lŒK*†QHÂ÷ØTy-r„à ¼RAA¨,¢Ó²@ 55UÅ^ß¾}»òp&¹€†Ëºº:ùþûïåæÍ›Ê#šÐÜV®\‰Ÿ¯8~»—Šº’ÙA ­­MNŸ>-T&àÖÔÔ$A<÷åææÊÁƒ•šÈûï¿/TIt\’PðégÇA*ú".BÁÞ—ö˦ kŪCL×úšT0Bús€F`nàä"4)™ÛŒun€F@#ôBóÃóFFãk&t}‘F@# Ðh49BÀig‡ß%-P(JPàtwà–ŠB¤yéŸxáMÌÍöZ 2ÔŒÕB#˜ô®Í†á>¥ŒôfoŒ‘}xî‚gý^‡aÌ›/¢A1¼œWn£ \yì‹c¼0ÞÛñÆ|¤â„€Šø@º&ò^¨· ÿðãÎ&Ø"-õƒÄ‘žá•“ œ•/!$X>È4\F©‡Êv’ºÛçóœH`yUWY">˜ +uâ$×,Ñ<Ìî1;êÄ|vcá«y¬Ý Jž"ž„ûÛ,¢i'´9ˆ9­OJã½›ÒÑÔ ÃCP'fGý(pK…t7Ÿ±2áOåx8«ÒÒnÌð CRÙß.p_†§?” àã£FÀ‰YÌèˆíq½fø¤…˜»ÃxHÏcð <“CGG ¤ÏmUctéÑò˜§4=eÑá ¦â®Ã³ç¨P\ÈUFHÔ & røÔÑÈ+CˆUP. §6ê• 0"êaáð ˆ Àf«å˜‡ÙÑ,Áç7EÚêæN½"ÞÁƒ1k@ÍÃQ²VD¡˜Çú‰a:¤éñyvóºô¶·ÈÈHb„šœuÛ¥âЇ’_µKR³ò@LâwÕÐWÝé–J(ÆœÁP s@c=Çn(< ‰<æ 0¤H†mµ0!L¼ÃUçÆß IO“å°!6¼.Ñ4UNà®Æ Oø}‚dÉ 2$Z\}Ý<"@%‚¿ýÛ¿•;wʾ}û”QóÒ¥KR[[+ÿøÿ¨È4v2$ š7tÒh’Unß¾­T ¨ráÂÆÏ€C6mÚ$/¿ü²"TWW+‚Ë5úÌoþ‘„‚î øÀt$‡aE*˜ú ý)H¼•4~€F`¶à\'€F@# X<èïíÅÓVº¤€F@# XÆôÒBA7Â\HJ‰ !ò³S%ÕDBÁ¸Â˜$ À ;ØÕ€T/ÈVñØY%⤑Òé¶È 4¾Óƒƒòå$ ¦¸Ù×!Áá!1¨¨ˆ±Í³é§l'Ëzƒ£Q…‚µÕ–ǵÀPÀ½alTe(¬…ÖÉŒ§-QqAɟàI_ –%ÉÈ 4y„<¹ò@o¸/æ‹ J€`±Ÿ5i¸ÌE[¬Þa©ØÜõC€EueȬ–cÁÆK í…’ëc°€vŒÒõ/+A¾Y¡BxŒ)ÚTãaåºÚ¥»¹UžÝ»%}ðª&‰;‘TR}Tʾ/¹k·ãë Gä÷Â,*"p(ª0 U2>Áoà|Ž[ $„H*´ÀøóñžÊ+“å¡Â„ ýQ.ùÐTy0dÊ„DRD ¦ ×éKþF‘T@#æîÝ»…!Ž?.<ëׯ˽{÷äêÕ«*c¹oذAfbÜ\ éJhfˆ‰;_ýµ ?rêÔ)¥Âç¹ŠŠ 9pà€¼òÊ+*äUEU&°‹˜(¡àÐa‹P–æ–žsuŠ M*ˆ &}’F@# Ðh4€F@# Ðh4ÀbD {: M>—ôø0‡'F((™ (3Ur²RÅ•2Æä>{°ÐSØVË_Ä@IDAT/HAìÙ^H¾÷4Šd‰*†‹±P2°k¤^a4éj ”†¯®Ã8êC,ö~a\ëïAy%G”|LøÛ0ª 8âÁíõŠ+#KŒ¢µâ\Qü,QwÊg#™õ|r}a{ ç!ÖoéŒKàïî¤IULDT©;,DRÅÄ¢Îþ;FÍE‘žÖ…I6±Õ<Öî• ÆíxÆ ¤ {[¥éÉci®«… Ælmïô¤IÑæ²ö¿–Œkà¬o‡(˜ý&Ò9h2T!8vì˜Ð+šª$`À¸î4zÞ¸qC._¾,ï¼ó޼ùæ›R\\¬<ªrtÙ4 îînùöÛo™€êuu Èâ·!FH$ q‡c°°°Q£fþûDBÁg8) yB">($èóN*ðAþëw¿û*u*¤’Þÿ}ÉÈȈ¯Óœ½Tòèëë“O>ùDÕ6==]ýÀñ5™i©åÑßI²N1#À¸Œƒ§ÿŸiϧ—„÷Õ¿—oX\—Ï‹<þB1•];pü½¨×Çr_^h`áµv_Ô{胀F@#°0bÑÚwëä´…s䔪ßñ'ºŸ=¹þ?¬ßk4€F@# ˜1~ؾ{FœÒ6ì’^¿‘¡À ãz~†[* =’æ…äýñ ÆW^…;èl`w³R.03 YŽ8íiy⤒@JHZÜ“!Žü  @ƒ7=£©|@r½ˆ{Û nÂß9t.éIÌ‚&΃7²“ÄHÐ:RQW76Üäóõ°7%Óy_HŒ«c (¯ü1U2jôpN Ѹ2Æ+¢U šî î ؽlƒ8Ê·ˆdZÛQêAÜ)¯¼¿YÇD°Â-‚­ÏEºZ$HÏëL´¯úX€7ÝiV¸„˜QÓ´GRꑤ<”zEÛs1ŸßBÿmOÈØ>~<%ý=d”¢u–šÂ¨ð%öœn|üÒYÿB^ܹ-ÍM2<”X\çÌò*ɯ¬–²êW$ ëëf‡R:‘KÒݱlrÌBýÀ+ö—™‰*¦ß 1±On¬ÍcÜø>P¤¥°ÊÆm(ñ}" Ñ‚äÀ:aLy üÂx2Sèvq½LY¨Ôw¿¯Ü(Ơᤠ$ôÝWNú䥈@~~¾üâ¿“ >ÿüs9{ö¬´µµÉÇ¬Ô H.`H„#FÏÊÂo¢NÀ”Ð{åÊEÖ!™àÖ­[â÷ûUXƒ={ö([æ[o½%Û¶m“æææ„ÃúDbhØ'_Ÿ>q›¡ ] "áŒyÞIìX¿ýíoUÓÒÒ[,Ù¤‚¥’ ä6VrôèQI6©`)æóhÐ'bQ¡wZRE(øOâ9ðâBÜÆ”vz'|ôqUlj,¢±©ëÿx7&„™’¡I1a¥OÒh4 ÊòNG³ÿIÜ;ߟPl÷gqL“ &£h4€F@#0#â áÚ± $F(ð¦:A(H‘Ò|¯xú dŸQ¹f|1Õ Þ €MíçsiJ­;¡``¤‚@ƒad‚l¹ÍDh )8`èTá``„‰Q2aL4aHtT4 V`¸`ÿñ!§|–”; æÊP>>P~$?Œ¤LÊKZ74fb›¶!ØôHäé ¨( œCÞÙî™ì¶zÕ~`Ðv¸ƒÈ|(ã¬2ÌÒ˜NCfX™=P£h¯y<`@¶ˆ*_ L`o¤ÃЕYdµ eéyŒÆãqe‹»=’TeìÍãȃ„‚àã+"ÍÏ@ŽA¨…Ø?Ð'ŒòMâ,ßVó° Ù‘ÄÚÓì##ÒôàŽ¼@¸ƒ®æFÄu¶ÆÎÄ+§>’³n»Tú™äWí§¡P8–p ¿#èÀƒ=E0¸;.™ˆ%Íï*cð{™‚ï’Ї HDKæÂ¬¤„s<Ÿß%3L$=LV êÁ<^„IŸ Æ:iÆ!PYY)kÖ¬‘]»vÉW_}%_|ñ…\»vM=z$OŸ>Uûo¼ñ†2†ò:Äê¤ÐŒE€¿É÷ïßWcˆê$è X¿ 9BÕª>|ª ¿&) ûræ»órü‹ÿîÎvÜ•¿xS'/Èû’—M(˜«©>wRÁT…ÓŸi4€F@# Ðh4€F@# ÐhâE€áÚ@&èö;…ä‚DR:HÅwP˜ã·g ÆU„Æ@Úõ„þ B"¬od@VÞíâ€q²êÓP¥|³Û˜c˜(á¼”zCÀ¢*&¿p Æ…«Ä¹¦„ à5Îh®LvTø‡§QÂ? \…ÉI)Ð#žäHÞK*È0¤JÂUPµ" û$~Ä#Áqÿ…°l¬zÅ]‘¨°¯/ÄT¼FÅ«Å(X B0µŒed U{&O®_–¾.jp%ÕG¥üàû’»v»8Ý^iˆÁ¼²ÁÔeÒÌ-”_g(„-[¶½©éa}òäIyüø±\ºtInß¾­¼¯éaMÃèÚµ”Éö¹­¥ÎM#0;466ªÐ!3$æPíƒ$ƒ¢¢"yùå—åÃ?sè VºJBQH(8uú;ŒÕãÒ¡`ûŽj9´o7È –zOв,o1車””%7CôÉöò"V[²ÓRɃLJó0QÍq€’–ZdE‘!¥ÓòA€„õá9²| ×5Õ$=†gçâpúáIæÀB– ‹I|ÕI# Ðh4ÀrB ˆ9! M>—ôø …; ^yP'(Éö@ö8URS õ?™a~¡€ c$=“G°;êY  àÌ*¶$Ðñlh…#-†Â° ôPÆK6²úÊK™²á?W²æ¸¿¥:`üèQ­Œ ¸/=CÏž±æav5IðéwP'Â0 œ ,´”]2ÁÈÚ¯…áÞ2ÏVÁ¦Çñ…†á˜[$fTTðBº^‘ ðJ¢q%„ŠP‘0ÓAD€'º©Ú{nÛ<®~@ÙzZ•ê…É: cnCŒ ï‘0%eŸX—¬ÇjM~D)SÄ8>Àèi­—®¦f©«¹+ýˆA¡À™ê–(¬9ò3ÉZ»ÍߨUF•j÷Sè]m•+ÈðTAŸàçJÑ„ãuTàá¯Î}7˜{`B‚j T'q°øÀ;&‡þhO¨›$øgªz(eÖذÌLJ!Á¼ôe˪A“8°sçNE2 jÁ7ß|#---Šhpýúu±C";vLŃO¦‘ty ¬k¹T`õsçÎ)uq¨ì1‚ß Ž#’s^}õU¥P0 aBÁ  ºÚb‚” $lߺ6UüvÇt•>i2æT@"Á¯ýëpù’-çÏ/•–†G·%ˆÅ ôœ\)ÛX-Ù%ŠÄBEGC­<º~NF`O…ŒgÙúmRZ¹e¹úÀ8°>8Øß-õ5w¤»ù… ôvÊ0¼]XòfæH~ùZ)߸NJÑ%+ÇÝM¿Õh4€F@#°¨ðÓP7â”¶a—ôú wàtwà–Ò<·d¦§*èb…! L_½0! Ì#ÈwfZêð´Wa ¸¤ŠÍ^Y¡ÑOc#@äçŽÓž+”HƒÐ4T+©ÿÎÅ1¤øBII­ãc+EÏ#ØQ/æ‹û‚ –Eh°O_@¯FÙq”n¡`B À±g¶°BhØ`3/+#úŒÈ0›½±HÀã81<ÃZШ “òön,¬“|ƒ²™ù~/”-è;Kmw¿¢„}I¥˜À¨¤(H*ê›a9zÑñ:×D’ ×(‰pL…Œ×áN2ÕøÀ8é@<éú;·¥½¡^†‡0^(¿· T Wo’²]›™-ó %ˆ#á.`"©`¨[©WéãÁ° *D¯â˜ uvOÌN‹Ìa€8„õ6›TPì G0Ãw=TÈ…Q|f˜½¾| #P\\,ñ¡Èû÷ï—Ï?ÿ\Ο?/MMMò/ÿò/Br Þ}÷]9xð`ÒCS/ahuÕ–82q ØŠW¯^ŸÏ'.—KvìØ!¯¼òŠ=zT¶nݪœ¢y<™i¦„¯G‡ÂIF{$·U, Ù³–B$Ìv=–ZýýxXÖiÉ#@Coëó9÷ñQº©ýÛòò;K’T„l!Ç)·¥–¬…ÖmáÖ,€Œ'7.ÈåÏþIüXpKÏÆâéФ‚(M6Üß+5W¾•üo`«€ÑJÙŪh¤êknÊyŽa,L¦×?ùM*ˆ‚kä!EÆh|!÷/üQ_;+Ý- ŠPT &X„gFÉêõ2øsÙtàõÈKõ¾F@# Ðh4%‡Ct"ÔAB #xS ¤Hi¾W<}°ç&15 •振Ü:^À›:_‚Ø „HP$7<ï# Ž4lÒ×¶7(40FÉ ŸóŸ:—M“\ƒ“h<5©LðÿÙ0#úØL“÷.äî¬Ú/’ ÃkH!2eNVf?B>´<“!zÛgPø„1fU(› ú€ƒÝ™`z@ I‡‡»Šôº§á\y–‡:À Ú\õ“xû½å½0–³,¡¤Jº0TæŽÆ`¯a$G—Aôsªg0LÄl ²1~Ê6 I'$jDë¬ïÄñüizpÑ>nIWs£XÞRfy•”¿ô¦ä—­Aä ŽcÞ$¢u#Æõ˜ÛsŒCÎÅÄÚûp¨eGÇú˜“yKÜ3t¾8 V0Ó<’õ¥šH=Æ×M¿×LÀæÍ›¥ªªJvïÞ-_~ù¥"0ÂÝ»wåáÇBc*• Þyçe@¥R¶N¥ŒC‚0Ä gΜ‘Þ^úäСCŠP@"ÆgÃv¡  §w>•-œ2é’h4¸à"Äð`¿"ðBÚº#)ùqÝnÁœLClOK£t4ÕA‰¡ÆÂ^ ÁiÀ£k®òBÎÈ)€'òj(bGâ²·³MÚ^<…9¼QâHœtºàåP¾~«8•Œ^ãT¶—LüΆZìëÂÜ^‡ûzÕC‡ËíÁ:FÈþŘ ¯ÂNQ|ÌâÙÄ­¯£Î]*—ALˆ{;[f1ÇÅ{ë,Žô£ öa‰c²¿»=j…H–ñq ÓÓ i$ûº¨èƒ >à{í«äþ¹?FÅ‹8¶AY£ññ]M*Ð}F# Ðh4%@?HíwÐpŠv¯SYÌõN‰ 83U sÜâö,BÁ¸š›~ûì3¥Z@rU K>7*/KúAb9÷†åS÷ÁÁA¹pá‚R&øâ‹/”BÃx½^9pà€êïìó Bµp f#  ËW§NˉãÇ¥§«-¦,¼éÙ²}GµlߺY4¡ &Èâ:I“ â‚KŸ¬ÐhfzðôtÈï¿’§?žC,ú;Ê{{|ŽAü€÷uµ«­µî‘Ô?¸)-Ïjdý¾c²åÐ1©P)àÎ÷'!—^?þö1½÷"^_'d×c%P޽³¡N^ûu»€2ßÂÚÌD…NSý˜û[¡ÒÐ$ÍÏàˆ©I1µŠ>i9!@å‡Ç×ÏÊ`¯¥‘êM“µ;Jõ?W¤.ܨï‰6¨~.'ht]5€F@# X&ø±vÙ3â”¶a—ôú w@¨ ³2*aº2ݰÉÑ ¹|’ŠOßÙR/È–Hý;•zA¡8oÝ €ó1¢‹Å†A¦€&Q ³Ïç™aƒ´º FÊ ,yxć÷àinÂcÞ ÑóAƒ Ó4ÔÒ㜤‚!ÈÚ÷c£‘”ç!#®]’d¼RÊÞQºQŒ¢ÕVœyÜ4¦zŒÉ<¬@<6>³æ":p«•ǘ{,€7l÷‚rq`‘ƒtX¡p†m>¦j1`5æüÚÃãE…ò!ú•‘¯u\à¨ARE0°H&ŒÐìh ô=¼°›ƒ4àJKG˜"åØá$© á2bŒ'æ4õ@{÷46Jý½à<‘!8‹$B(ðæIþÚ-Rqà]É(®P$rODhˆ1p £BAà ûqx˜*}’†Æ&U&”•Ę + N\c%\™Ì<™Â¾÷Ø2ÄõnŠz(e ´¹™°¾TåÃÄ•>Y#‰@yy¹üÍßüìÚµK(óNCë… åÅ‹ò›ßüF®]»&—/_–·ß~[}îñ€x§“F`‘!@rU8êà8 ù/^”ááaåÈX]]­”9ØÇ÷íÛ'n·[zz@¥DBÁçÇ¿’ßúi\„‚C‡ÈÚÕâqkó÷l4Fu6PÕ÷Ôh4 @ÏãGWÏÊ¥ÿø¯ŠC<”ÈnM²êœ»2\€o“ßPòcòû†zù3²reí®CöG“¾rÂ8Ô—à>Ë“âVqï'Í â† èyá§¿AÜ÷sohåKéLoV¶ä­À|zœVR¡dàÿ!Ú Î`É)QB_'€F`, ÁQÿfø`Fn¡l{í}YµeOøXV>uÒh4€F@#°ÒéwJ‡DJ„>€¹;îZ’@Ÿá–ŠB¤yap´Ýqßi \¢’‰‡±Õlõxg“\Ððö2²€a”'´5®Qªw0bŽhPz$$ÊŽ‡Ù &IÜÔ94lZ Vè²1wTrå*?6îÍ<(åUÄtƒžô$°¬8¦ŒÁ86Ñè ¯í¥,j çèFÁ*q¬Û-‚:SMÁN3ªG4¬Qæ–Z„<¸!Ò CvØpkç¸^þ¡`µ8Ê7Фe¡í-w«d³ÔæÑ°bÛ'³_Ùy0¼ÖW"û®ƒÊ’ Pe´I*IèÃìûvØ“Ê4TãÕ »¥ïÚy,¬¹˜_Ù\s_šß—öÆz8P$¦H‘ U‚òݯIÁºâÉ_jf±D• 5¦Ð)õo‘AÀ’üçxäò¿56UˆÖ…}Ê#Š0‚Ïx<û Öë=6q"éyPÁ.£Õ©ú;U=”BÉ ‘áئ å¤/ÒŒE€k´;vì7J^á ikë§OËC?þø£Ü»wO®\¹"o¾ù¦òäæy.¨è¤X 0´ÇÿøGæàÔ©SÒÝÝ­žUH¨9v옼ÿþûòÚk¯Iv6ž CÏ|³U/›PðÑGÿ&­~¤§ÉŒ ‘—”Žö–YSO˜¦Kþcý¶ä›XWP# X,ü>yq÷š"ð‡Ù Ér†4(Z½^2²óàÈJ,ÈôÃû¸³á¹<úñ¼ŠYÏúÑpßÝÚ WN~$«*%c¢ßÜ«¤jÏ‘˜ bÙ¼™9R´jÝ´çs‘¤¿§S®žüXÉ´„¤#ÝÞtY·ûˆ”Um—üòUª®.Lf%ôƒ0ÑÛÑ,]Í ÒÓÖ$•Óæ£OÐ,7ü` ÷uµ†«ž•'¥…¢“F@# Ðh4¥ŽÀàˆ!í tø]â£:S‘;Õ)…)Ršï…¬9ŒåÚÚî6”s7º%ÐÙxo–R/p¤å*/mGˆ6X4ÚÑKƒ&„©ˆ/òh6”t:Œ–LJbÝÚ•¨ÕÑJƒ¦ ß5¡Œ˜“BNçýÇçÓŒŒȲ[y¨æ"¡`À"Ã}  YŠ”¼§* ` b:‚yôP0U hëW\Ù… 3 Ü9³Ç<ÔÈYay C1A…j˜…z˜õV¸ƒÖZ”üÄ`¡%†(ƒZÊ*„€Š„ÝãÛc.Ú|Žó0¼P1`B¾.»m”"A¨âé»#ý½ÒòðŽ<¹ñ£ôÁi$Ñö.©>*%»ŽIAeµ¸@ˆPcMyé[e öw`L¡¿S@Ç’3 „»ÒÿA†@ÿ#éãZYÜÏ0”*D¯áxž¥<nÔaŒÒƒ*nܦ¬GFÈÜ¡¾{øƒ¤Ö¢à˜³J§ÿ.BšÛ¥µµ]ŠKŠa¸ ¨PÊ£û›o¾‘7nˆƒ’’týP\„õÕE^ÚtuuÉ·ß~«Bœ8qB©oP±€¡?¨ÊqôèQùùÏ.•••Põ")tvS$¡ „‚X~lBÁ+GJzš¤‚Ù-ãr¾»&,çÖ×u×hxÀt¹=R^µMVWòõÛ`¼¯RJvaùCÚÛÑ*ye«åê‰àÑߤ>A¾!ž^?/;^ÿ™}ú´¯L +ÖÉá_üÏÓžkŸÀØ}ŽÐB‹},Ú+Uî|û¶Ïêlx,FxÓ2eóÑwd×ë?—¼ÒU¸,ú Þd÷¨X4Q‚ˆ›éƒ·–o‹žHô@IMƒš ?tÒh4€F@#°”è 8¤„‚nl~3ú¤^±ÎBû?CØãG‘¢á;+y„sS´¸Þ$R¸2Ð'k&Gàimƒ|ôÑ'ræÔ—øéðKQQ‘dffJFF†X@ïîöövùä“OäúõëréÒ%yï½÷äÈ‘#ÊÃ{ò;ëO4s‹ÃPYƒ¡† à9Û}€P½rñÓßb’jMˆ7ùüîÕ¸H4ês±…ÉLALRÛëŸËµ¯>A(L°áI(€ÑsDZe×›"™ù%Sfç„Ü`6¤ÄtÒhÆ"Ĥu¨Þ%ôäB¢ÚC¤Ìg2àÉ4Ý÷<Ïáï?Ƨ@ãƒñ‡ô{€F@# Ðh4a([OBA“Ï%=>GBê¼YVZЬÈuK^V*L£Y±ÃY.«Î&‡±BhB9`Èi_¤>kbó¸  u‘þIqºÅéÉ‚²8Ô òÀéôâY4ÞÝxRã™ &ƒÒ‡ ©cÂ"@1Àdh~FohÜÛJ$° ¨ã¡Ïø9Ã*„欣çãL[ŸڡàÉít–A žÛy¸Ö/#"’ omSÅ?—ËOÌ/Öz`Nl~"fÍ%‘žVTÛz~Ç-N¢ñ„×Ú]"¹¥ðtGû°ÝCžÝ3jÜ)f¬ìþo›/¤<#ÒÓÒ,õ÷nHËó'2„uDÚÜ‹…›öʪ#¿”´’Uj¼¨ì? þƒ ªm 0@ŒéøAeK;)åŽÐ:‘ÎÀúŒë~&C#€¬ã@ø\¤.QíMCý,çA"ƒÊÃ.h‚¯SÖóedbaÅP*H +µ§ÿhf†@$¡`hh44­×ëUö  èõMRAoo¯<~üXž={&×®] ‡Dؽ{·2Úά$új@â𷉡:¾úê+9~ü¸œ;wN…ð } ªªJ H&سgx<ü±Ÿ×Ï3–+I(8uú¬|ü±&Ä‚×|³èH4š’áõõ×_+c<å7’M*˜«<(CY2:”tC9YEK!ÈÁ1¯Ì«W¯j¬"A‰ØŸi›Óà“öÚßGÜqâ.Yõ§?ÈЙ?búר“81<ÿQU,÷ _3G?RáüÐŽßëv’µ;öÇd d^—§>•„`"C¶«é…Š4ß²Z~Ä||õ{€esaq¢|Ó.Ùóί$=§€‡tÒh@€dT±î])\ü›¿äÈ)þ÷#D(ðßÿvBA}M-Žé€F@# ÐhˆÀpÐ :@(èõÃÀ=ê[3@xÞgy1É÷H.xãëd!à7LÄ£ä R(@¨Þ#á¡‘ÑN8>$Á ÕÚpÜ£]Jj†8`¨LIÁ+Œœ.+SœŒéî„L º"`NH¥<•”'¼•‘2h‚ OOk~ÃŽ…C³’e§‰†g;1Œ‚2|ã@*B)()ö'äüIùúYË#J= š`vB²÷Ù ‘Þö„ŒËvUgí5#WŒÂ5â¬Ø*’œ¬9Åì¶G¬’ÞæsœÕ0βéÉcizúXÚëñý3”Y^%+v•;_Oa9º6G:B`Ü(ƒO„šdp° AVœ™…ÖÁ@p€dr|)£;ÚÛV¤ðÍIð8á`L™±—LY¬Ã¥d€8Áï |/¨/‚±·Ñï4q!0¡ ò&Œ5o«tvvJ_¿twu+ÍÝ»wÕëÛo¿-ÜÖ­[§ì[‘×ë}Àl#@GçS§N©P´±¶µµ©g:<¿öÚk²wï^9|ø°äää(§îÙ.}ÿa_@Î~uJ>ýý諒µ eŠPß±O÷êIÏ–ƒ‡Žˆò`ÜÇúí,!°èHdѰãÿøã˜¸¸¤¼¼<éÐÌUô¸g=Èd[½zuÒëa{õ/ö<"±ëy,ûö};V3®G JœÌøžSž¦~x;1Qa‚‘k¤§9ªªñ §ó`¥çmO[£ v´Hßó‹2 ¶§ å¡g{fa±däÎè‡lˆîÖéFãR//3/_Ò³ Äž‰ ˜Uxÿri#04(ÝmM2ÐÝ9òAÁd’^ÞŒLlY’†ØÜŸ.g..¨ĚȴNÇÄ?·¤Õ_È+5-]2г K°({?ˆ,ëáƒ7DO{3úú#ˆ&¼%R<ˆ‹¾èÉ´ú£y%šTëí’®æzå-Ou 1éYy’³¢\<o1)àó©1ÜÓ†ïÔÑÿ½é’‘WÌVÌh"¶Ú„!† áÀ÷ ¿g{±¨‘ í>šð}‚…oVöœxeXœrlÍ>Ê^±y}÷NGýt’$¢\ªi4€F@#°L1¤¡:ü.ñÁ•¡À E‚¼4—!äAVÚ Nþ–` ;L釭m6·È*Å O 0$ÜdÔaÏ¡nIq1´H0€:A:paKÅ3£ÁØïEàÀ9.x]+CÉ$À³_9[§ØD&ÂPÙê|呌;0–4<8 O¯Ÿ—ºšPy¨“!Ì}ˆ)ER‹ÙÂò5R¾q—¬Ýy –ÛMz1!Oo\Dßy¬H$ÐXîHqAN*]ÒróU,C_)_¿]&½aÄ~™[_<•–§÷­þ’Ë ªÇœFÐÓÑ3°eKvÁ Õ+Öo“T·%q«Éw1ïïé’§?^úG·¤[‘ ºk $x'¥åäªqZ±y¬Ü’¼vÀãµö!Æði­Ã[ÕÒ«= eåJIå6Y½mä—®ž¼üQ>Y4m‚u®–z¹öåǶ& ¢³åE¸F$Mµ>¯‘sÿ—ð1îdäʦCoHAÙš1Çõ€F@# Ðh4‹†;h¡ ›ß ›Äâ*: +²ÝR”ã·Ç© è "Ì C°[&Û䀇47•ÚÔ‹+Jn›T†ù–Gœîtˬœ.üsbÞètD. £d4 ÚFHQ1°îKË(H*ñx8Á³M…9Àu.¯á®¡x èücÌ“›GëòâÂ@‰ ë ’PPP.ÎU;ÄÀ«Ð››=@ªç«¹hYÍ÷mÒöøÔ=¸/ý ~'ÒÞN¬m> + ÙåëA¸I1œšè¯L$¤¸ÉÀ "‡=lòGˆdÀpáϰža݇BäÞJ…€3 Û\g8¦¹Êƒ$!»üVÎ ýª bºÙy…0J(3}ѲG B VÙÊuòÖÛïÈK{¶É‹º:Ù¹³ZΜ9£” š››åw¿ûRã¾té’2æRÅ:==q ;_ýª@k† ¿qòäIê€ûT»Nâ)üõÖ[ŠL°k×.uìÅ‹Šl0þ>³õÞ&œ8~B:Û©Pz¶›"C;ªwÊÎêí’î|nœâ"ýQÒXt¤2ew¦¸¸Ï†zM¡ÍU/½ô’RZ`~¬O²Ã*,…<"qa ¶²ÓRÁj.ê‘Lìð6~pö ¹÷Íïåùõïa̵$üÇçÁ±î†ñaŽüÙÿ"9EˆóC¢±øÑ•ïä¼åŸß¹2A„ëDèz.,dÂðÖ •„­¯üTr‹Ë¦¼3Øú»ÛåÁ…opÏË·{%CÊvOþƒG÷ڻפrÏaÙ|à-É…7w²™{~IJ±r¹Ó25c±}q_i~qÿ&8Yåü×#kvR$‹$f£nÅ6éël“+'þ ë6õœ+õ†Ç>œ²¯ð:Þow\nžþi‡Q>Zª½}Eµ_oG3ú`bÄß`¿<¿}Uîž=!Ïn#|Ô&KÑ~e÷¯Ë–#ïȺ]‡§$GÐc¡ ê5 å°·>,ÚqëÉû#Û¢öÞ5YÿÒ+²~ïk’ e„éÕ ¨Æqû»Ïåî÷_J'ÈÑÒsÔíŃ›²½³EŠ*ÖG;%öc¨U7]ù^\:¥îK'$ôù§7.I{ícÙñÆÏ¤xUlù.¦6á8"‰ãúWŸÀ‘g¢T$ûA'žp‹L9Ee ó¬Ö¤‚HPô¾F@# Ðh4 ÚƒI(hB¸ƒŸ#!uV2+-EŠA&ÈËY„,8C¡ ¶IÀ;g)à[dr@öž¡œ0†:A2p8A4 ‚'„üLØÿ±Oe’ðjPúÄ$Œ¬–¤9ߌV„!‘¦D˜ÒÈ ã*.Â9ŠWódt0EN]ƒó”G7 ­8>“<ÌÁ^t^Ìdžú@nI€˜|n†ç<eî`»H~9J†¹…Šaó€Õ\´Ç¬æ>ÕÓÔ$Mo#äÁ#(öÆdßà^„8(Úø’Tù9F ¢‰qj…ªT@Ÿd_7ÓòóBýXp#3³ê¡ íA¯ü „°PýoÓà4̰²ã8à@2‡ûÐ?Ùæèïó‡ Iê@ þ™²™À}Ú1J* ÁB Á õeËD+׬—7ò–ìݳUܰÏ0ÌÁªU«dûöíB¥çoÞ¼©bÚ?zôH®\¹¢ »ôß¶m›2ì.[ÀuÅ“ŠûÕ1N@à»ï¾ª0­]»Võ¹wÞyG^~ùe¥VÔŒc¼Y˜P€òuB}5BÁö­›Åë ãbÌOŸ–©€3~ s›­4Wy¬Y³F¸ÍVâ¤k)ä‰C^ÌfK«©êáƒ7tGG‡ Û}œìGÆÆ™¯Äpu·/ɹßþïÒúô®*†}6³°L2àN9uªШH£ýP_·<»uYyÝNG*àÐP¯Ü>ó¹#•˜Xo*Ы—Fo&NÖzráÚ‰qMŸùÓ¿S êÃ(xÝÃKgä§¿‘þ.o™ ?vŸq|æ€loQfžÏüšßS^ð¾ÁAyùOÿ^o];³¿0 {ÖÁNTÈÊI uϤ”ê…‹àJI•² ÛÂC¯í†Çwäê¿“’™Hô`Ï$~Îë?‹šûH/䔨?n\úAJ'`Çòº0q†úR»€ÊÅÅÏþIÚëŸâ\»ÝÃWL¹ÓßÕ!wÏ)÷Î}Ê=µ¸D2‹ca=Üi*dAÈ*ì7”ö¯½sá@ZW«lyå=ÉÈÁ¤8Jìí‘ûç¿R„ Ž+Ya4²A…9@^Cð˜`Xî?Ç™ ¤¡²÷ÝÿaJE±;êŸËµ?~ ãþiæ#\`E Ç®!KØßëA*@+¶î–>Œ­D’j\{ã›Ï0Ž?—ŽÆZu*s¸áÅDû… ØïGèbìGÈoüBJ+§–á_ŒmÂTÏð`(ÆD¼œèË:i4€F@# X,øaçêqJÛ°KzýFB„†7Èò¦Hy¾Gr³Rñ¬:¿s£…„½ªnCX À6—„‚É0Â(:< ©q’­j@’ †A'<Ž2ÁØðކR Ò QÚ–²ç$`ž  °xUça^d\#²RÆUJsI® vÜèǶ÷èko’<8Ïs¯ÉÆœœ*4c¦H$ИK–i®=×K¿»j¿®$b`~8_X¡qf½=f%E „m­!÷¡ÎØÜˆfEh‚Ú4³¼JVìzMVTO~‰{[•ÑŸ¤qÛKõ]tôC#Z_DYL,˜+EúèŸ1-™‹ ÌWj F·Ñ ;űDê7ÅõG‰$J(ø³_ý¹l¨¬ÀïÔ(¡‘6 :JD;ŒÍ•ïˆ_݃Š|CãqÞŠ "$·´á<ØÓ@yq(‚KgsƒÔÞº$ÍP3`ìƒLcÍ¥odåæRV59áƒjwΔ;PtðAzŸ)j E«« FP%YP: G/ú{#ÈÍPïà¸b}ÙƦɱŠÝSYBíÓš¤MÕ€áRz*!Ê| 8`üwAå€!TøOŽÓŠaJ¹³<œD…'R,6ULN®ø ÌWÂkø:&å¢ÎçA|¦Îç>v¢å£®g;xê¡aézªÏã3æ:çÝXƒ0©€W°ÌqM8#fÜ” 2FÁJqP¡À&¨&©‡ªÀ,cµó@»@)²ùÅCy~ÿ®šs.šHÊY³UVz_ ªöH*Â7Ò9…a9Lå]êöIbQýƒk5l³Ðr¾½¯H4^†;(ÂÐáÂêS*ÌA¨oÏ{¨K2ÒÔõÀ¸E⺖§ÖuLÿÑÄŠÀLÇŽ”ÖÖµV5>¿¬¬,ùéO*”šß·oŸŠoOã/ÿð‡?„C"¼÷Þ{òÚk¯Inn®5îÇßH¿×DA`$7’TŽ?®555ªÚê߯¾úª=zT6lØ %%%óÖ·4¡ Jã-¢CšT°ˆKU#ü¹|ùr˜íHFÚøÉPŠósñ½B Í.ÁÔwN=Ÿ;ŸÊSHš3ÑZ¾y¯þõVFÑ@󨇻e|î•zHʵ×=Q1Û§+¤2˜Âóœ“-OF–l:ø†¬ß÷* §[•1”÷ìïj“’µä ¼Ûmãó0<­o÷…¬­>€Å‰èñxhÜËÎ_cj¥”nØ®bÓ¯ÞrAæ*c¿Ri¸^±fƒœÿý•ÆG·Õ$¡î|wB’A*àþOßžF;Ñë}í΃öÛ˜^IÂh­}$ç>ùåÉÎ÷¬'ïåEŒ"7$ø¼9*4D᪪)½Ú™!É,ð賆P°FkmK ŸŸžËI½Cü¾!¥.ðè‡ï”a*°BEä]£ì#Ÿ®–^Á&¤Cq`Âll~ùM),_7æ"*.¬Þö êr *4’“0Ru€5Û÷è0Jʰ/$‚dë6C b»¬Ü´SŠP~ú\ä²Ö¨TPX¾F~øâÿQ§ý1(4Ì?¼üí¤¤cµ„ D VmÝ#»ÞúS)ZY)i0ò£ ¨ñÑ-”÷ŒÔüp} Ság!žWbÑ ûNf~‘lÜ dŸW¥„T7” P®žvi|xW/ž‚¼ÃE8ªÔA…¡¾æ†Tî>21ËEÜ&T yé§©HQT…¸‚Ò(©À…°Urø—ÿÓh¿“æ;ÊhæKj~,®µÁ;¬'0$ýèGAŒ.Œ»1^r±P šÇ^¤›ÿ"ëh4€F`Ù ÀpmÃNé8…ä‚DRjŠCŠê „‚´tHÝî“…À ÂP0„)‚efŒ™T'B¦ºÄMÏKjo_Q¡;øËX ¢ C&TlÙ…#£Xy€ÿê­û@>JƉ}±0Æå«Þ¢iH¯~ãOdËá·0Ö°JôÌÏ€þšYÊ›ƒdU˜HztõœòÚ瘈L‹ºM€É9ÜH¢á÷æhâB(x1VuŠŽ€}¼ÒñÑÚ;@IDAT µ m†'Xd?‡ð]0G§×!^ ²±@W„è O¦”`qÚÌuÒh4€F`v —û`Ð)M>—tú ˜¨ûý%Àƒ0nL¦˜+ `7&Érô¸%_—c¢ùx„‚Ø7fî Ïš™n§x@(Pó`JªÜ1ÑöͼøÌEÂx‡xå±Ì GH@À1‹„`]ÃëfšA `|gêmT/vèÃpÁÆÊ0 qº¡Â‚¶ƒ+¤pàJã’(û¶Pzuƒˆ?ŒÃ9?uÄà9¸§ê¢ÆÛˆÓD(ôž3 ôC°B˃Æ}/B'âÓ`6íÈÀš4A°6† O‚R9€:"DôÃHLâÁŽH â‡M9€-ÈlPÎ 6ät1rJÄUºQ‚˜'(ÔQƒÝdÕ#¢³†ÕBÈ„”žæi©½éÉC8G }ìõŽˆòM·ëD(¿¢ÍdÕ‘‡ù-ÉláÜë&Êð?ѱB‘ >CëÁw›'#Ôu¡n€yK´D¢ŠI $ž³`ò`¨†q}8Zù§;6VAvH´pxªÂ Z¤ÓÅt7ן/kæ‚P`ÌuÕíÛ·+¯q~?ÿüs9}ú´<|øPnÞ¼)<«W¯Ê›o¾)ï¾û®lܸq^Áv¹õëÂBàùóçÊtòäIò »Û"½1|<É w@bJ&œ'[ËŸ«‘Pðùñ¯”’B<„‚]»÷ÈÖÍÄã»Î;WåÖùŒE@“ Æâ¡ßi=d¡={Vþõ_ÿUÅË™¶Bx€áÂM‡™%rëÖ-õ@3íu38A3 2Ѩ?]¯0Õù4*o{õ§0àþJ^£K‚½ú¯}ù1Œ¸õê” M𢟌T@vñšÍj‹vÏñÇœ©©Ê{œqà‡`ðf=}ý}©Ø£dþÇŸëûaxdßþö¸ ÀkøP†Ð;^û@)?Lw%=ñ§‘uªDñžNµQnòü–ø+²éÀO0/‹ð†ÝH©K |á„Évîqþßÿ_énµzŸ¡ïqÄ•p® $axЉüµt·4A.P$·¨LVmÛ;îLëí åw¾?^ q`ÝÎCP¨ Âg›c“…m¾ì€±ŸÆ÷+e@¢È” +6 ±q÷üI¥ÄÀs³ p±å•w¢ Â÷B;f!–âúý¯)B•HРa'ppŽSà Qa=bM ÝÀ0©èûìC$€ £øÐ7I:“ÐT–xÕ{Á„dÊGTÈ„¨X(“ì«ßø¹Z̽ùͧJbÌ}c|“ŵ­¯½¯ú4CbDK.wºa(6©€á šŸÝ“vô*Š„ÓRh“peôN< £Ÿ?…·Ê½~¨[`a-0î÷ÆÇïe,zwcA¯ăflÓód­7G)Ä“—>W# Ðh48À³¯ÆÕAŠ `> æ„Çc»!žõ|{|ÒÕ£¦)©)NqC½€Ã"p[NDƒ°rA¡+‰ h#/ˆ¹^©ÕÜ7 µ©ã†­9g†ðß—`HÉ€\œå`'c>ÉT7P$ìÏÑÀç=l‘ÉnWj:H£$xÑïÒ`ïÇ{w&æFŸÂ !:¬åˆKYßp…#Ž+}è}ès¾S熮±± _5É5×™„tðRueàœOÃðÖN¨²€5e(À\Îå¸Ì yHbnX qÀKÖáE=s vGô0È÷$H0EÖ]ëØøfPñ·Zôy€ðÑQ÷Lêï\‡Š_=æÑa1n>⤻™åU’_Y-+~ ÈO¶Š€Å]Æûbl¨DÒdßc¿48¢xÜ>ç†Ë‚ƒ‘Ž+êz»/ã;Í{,‹]»P ¼NY#û÷·qM +}ÉòA`. ‘¨º¡Üzøða©¨¨mÛ¶É·ß~«¶––E2 ú•+Wä­·ÞRƒÒÒRåy½¿üèìì”3gÎÉ'NœúúzµË sÀþÂ~åÅóÀ|“ Ø:6¡àãþMÚ[cú-õ@™gÿþƒ²³zl âéïòÑÑ5©`A4ƒ.„F 9Ð#£¶¶V>úè£ØÙš˜p´ôùåßÿýßeõêÕˆ?9ÎÀqîLwû,³ ,|› §µ×Ïɶ7~¥<“Ã$¸CCw~éÙýÖ/'%ðÖüA¥±²heU˜T@ z:Ìyâe\h!y!=¯P‘ xà PÖ~2CéÄ»Œ=Âp ÷oÀ`ýeøW×ï}ÞÙûÂǦÚIõ¦ÁXû3i|| ')XP7ƒ Þð@1qÿaféõOBAkícñsâlÊ`o§Ô\<ƒéÏÊ“UP.Ÿ8Áfè;ñ:­¹‘_¶JÅÏ,(<¨0Ø×‹ux›C–¿½þ™Ê‹Æÿ{ç¿Â2‡)oþÿ›òжï9þ5 r’{à=?²§¨ôØfXñ‰íÛ‡ÐÍOï‡?bÈ…õûŽªr„FÙ¡Ñ}ë‘w  ï²íJ*7ÊŽ£?vœxÒ3…¡+Hxì³ÈJƒ¢d_Š$,…6 ¤wbFÀ"\ëm‘6Ĭeô`6']$Š¢8tæÉ k»tµÕÈ`OƒÔcÑuýŸ’½ÒóµbAÌhë5€F@#'xntÂb:!OoІçã{œ7Âï9~·‡`w¢»¶X„e§#C8<·1ßpAÅ [$ÑÀ²A =ï±2ƹ¡ dç°‘<î,¬ üˆÝÿ½÷ ’ãJ¯D¿ò¦«½Ð  AZ ÍrH.gF䬑«ØY½÷Kÿú«Ÿ/⽈÷ ­f¤‘f‡£á8j‡´I € Hx¾ÑÞwuùª|çÜ̬ÎnT»êêFwã^ :³²2¯9÷fUÞûï|°33Ü"K•|xP a~X…?ÉÍSz”Q„çONÌhÒ„™²û¦ªº s=Ô sÆ[ˆ87gДîùÏbôôçÉ%H9ä—J ˆƒ·„ ˜­­jàFxHn¨(¢ ñnTHF`he YB5½ò1àP[ÕÑÜx¡ÍTGpQQŒõVרàC …Ò¡d@] 1Ø`k0y5[I+©2˜GY•YFí 5NñÀ*9„t(ÄØ€Ë ¿x £OEªË©ºP%ÁR$˜° 8Ìz;bæ@…:Á)i9û ֌ڠŠa3ìNšâ¶rÅ]²òÑ?‘Ú ;Åu0û1؉;ºk1ø«ösP¨†ø@Ù.¨k¸ ¢Æq䢌?ÃÐαÂ/-$E,Á¸FŒ<œ‡ï2Jý[cI탨Â4¯Ê`›œäUÃéÿ™+Bލ{PÝæ=È{ÃDyúeé+î Š!4¯X+¯¼òcybïƒ2•“!YYY) w@õ‚{î¹G ŽÒjo¯üö·¿•/¿üRÉÚSµà±Çž¯Ó‡JÞ€D¾N:…ß§ Æ`@xàE&à¡úÕ¬©\ ž©n#T Ô™ $tO“Pðè£â™ŠÍýê)î6¶Bm#0ò´jÑ[€F`Á"cšlƉBLÔ¸4¤ùÉ~äÓ“O>9Ñ©3ú̃ oݪ»@˜¯„¡tóÉÏ•#ÿöÿÉÝßyYê+à5Cw±‰±äËkëñZ2i<7R[—?1äi`-e¢Ñœ!ìD¥ª“xmg«’áW! Ö +ÖÓýc$ÑÇ/Áå„{žx qçÄ|„,d¸1™å¢IRz{§0¡îëE¸†3róìI¹~æKÕW$Eôµ]—£oÿ›T.i†gú²ÑaL‚3‘LЈ>_±e— K@bAyMƒ2psMÂAöí 9œùì=¹ ’  Þ×NAÙ' $°Û™å-û,#R‰É㉓î¡Þμ2‚9V¤aå]\5òÉÕKVà€Y¿‘OFï1ÄBÔQCaT54+…€Ñg~G‰ûHU]^ÙAå2ÄLI,ã…Jv¢±$’±‰á@VÀV‘ ¾•èëZ&MXP£±¿²žcÃI*˜ôJu˪¨[:*äÁxW*’B!0$dz'ÔiT^δúÄÙ½?94.tHp2Ú¥T=®‚£V¾ò«ñ•\†õ[®geCË$¶ä'ø^ûFÚ.ï—®›Ç¤‹y§¢=R²Ã!è¤Ðh4À, €ßêž9C0ÌÖ…=2ˆ¹HZîi hš©9™žðq:öZ$î9‰T. S}†s¿¤¼ bëw (õo:è/sT¦Ó <ç䊬¶N~Ÿ„ýÀˆ²áEæCÌ™F©à="Á›Dv5 ò0šfa¼Ï Â$©sNšÆ4Ÿë³”ˆÇxÈb.ÌùŸñ”ÁPå<³?T4«j'ÀðïƒzÛ —Àƒñä&áógÃR4`Û0xÐHl‰_cëNc1Ú¥¼=x*áy³`‚²€¡¤â©-é(rînJº[)O¥‡Ñ4—À5˜‹«2BøÄ*L ûôÑÛñʘ‹vÌç20β‰¸t~{k_ ¬_Ÿ—£Á›Ú»†;¤y;Â:nÙ#^DTrôŸ3®¤ŽsP ™€]¯Bo`Ýæ–„>7b8Ÿãߟn’,R’ý¿åÜ: ‰pËPa H–™ašv;pï¡õ3,U_¾X¸z£z¿•¾+‰Ä­ëc…ÚÝ„ð¥Ï}ÿyüÑÝ%!8Ëhnn–W_}U¶lÙ"÷ÝwŸ|òÉ'ŠPpùòeùÙÏ~¦öI6 áxÇŽʘì¼^ï/Nø,tæÌ¥L@u‚C‡)ÒóI  2I) w@u‚ù’fJ(¨ˆ”IΈ:Í4©`þô…®Éˆ"nÙÏþó)œiž2ÿæã?NJ*›g¡÷4“T`'ªZP®ŸFüR&†-p–ÿ¡ÞvùæÀ›S*†j IÆË´’I*èRÄ ûظ[”•¶ÆcyPž‘ã‘}Æ4€P©1¤Bã‘ã—¤;£Š:Ää, aŸSªíÈè™ZŽTw áÁ&°­Ãƒ£CT,†>™ú,Ù.ÅûÎ &pL”*üœ¬Ï¥d~ç:–c»²nˆ<+ñZ=Òuí3éÅÂ/C&4"¶iÀò²óÖ[€F@# ÐhJ€ž[?>#x¼«#!x×ÃK’Ät)ñ)L‚è½^¬‚ÁØZŽ"$ME¯‡u M„Ìh¶‰T/ð{M•øHàÆ³Â|$p†™–ƒ°=î€x•€r$¹‚MÓ}8 z¡÷˜‡»  Àó.(ð¶â ôÌ Þœ“pN“ƒ#•ÔrðÌOcÌd2I8ýƒ|ƒs¼Ù&Tf}âCâ© GÒ)¼ s æghä‡Ã„+\#‹ ‘ a ÍO0ÎÛZ¥¯åŠÜ8wsb„šÀ:Ñt“Š•uk·ÊêÝÏH¤qUÉצ[}¾F@#PE(øõïäÀGÓ#<óì÷dÏ®í%'صäz5 H, *Áû￯ŒÉ.\P¡h\>~ü¸ ‡ðì³ÏÊúõëgmß®“ÞÞ>ÚàÃ?TÊ T¯àZó’%K‰àÅ_T„‚ÚÚZ“Xxûª:ªd ÞÞ÷¼þëâ H(p˜Få­ßÜ>n;© … Âk¯½¦ðãaü…^Hnd%L‹¥ Â)uÃTVV¦¾(¸-ešïeÐàý/ÿò/3nr©ò[‘ÙÊ×.g¶óg9”˹rþ´t¼ÿS©ÇÎêÂ:ôÿ.^xc{¿8$ré-ņö®¸ÇŸ·«;jßÿ£ÞSzlSGzkÃÒÒ ƒ'V‰¸Xpéȇrýäç²dõåѾtÝVČ߬Œ™£2(Õ,’ø‚'´~Õâ…ý~¢-=öûÛ[¥ãÚyéFˆ†HÍNA[zU¦Ýme5¥ÏŽàÔ'oËéßÊ{ûÃÙÌú`¶’òMwmCöném½&Ý7.©¢¨FðíñÏäÿlô ~í}#½I`¨)àÁI«è}ãš»eÃî'äó7Ì{ƒP0 a}¦ÆöY´¯+_z¹—Q~°ÄÉôŠ)‡X];õ%œ›RIJ=ÀÁ¤LÕXõ‡±QY ·­EÇÞ–«ЯÆ#ï«ÂQdñ{ËÄ}'có±ßÓ#È©ÚÁ 10ÇS „uƒ€ãL‹¡Oœí™oû¹þ6I}³oÒj¹«–©ß±'®â{åÄß=\ô{ú6b\f Z¤`Y½¬Üò„Ô/Å‚ïØ\ñ=-­ÿ äy«¤¬nHK´ƒñÞrÒBBG*®Õ Æb¦ßk4€F` îpâ”dã0´&1‘œ²‹<~µaăà½@†lÌIaÈOÁ†—™ …|hú'Á û·¥"P†_EMP^¬¦ñÐI4ðpÎBAáüðܧ’AŠ$øð"ÑÀƒÅ7tÿoWø„ p^C†Q—b nÌãBh[uÊ &k¢´„® C‘L|aqH&€¤{ë,‹˜”s0÷`Né  ŸGù„Ÿ™Šð"ÇÜ0ywdbλyœkY²ôØG‡æhæÉëCÉŒ”EÅ •0ï·s5 °h@ÉÀd®‚B@~8‡cT3pEêÅCït´ÇEµ8?v2\•‚åt Î±H .zœcœ©Ä}^‡Äµ0ÆÍ¶à¢¼Ø­(]tN·ÁÁA9xð êwª\»v Ï:Ye?½ÿþû•SèÞ½{eûöíê˜ú-¸õuLeTȃßþæ7E…<Є'šókŸ¿¨·5QnÝ6‡Ãayâ‰'JN*X,e8 ÊuuuÂ/ŒR“ K·uP/‚ÂiŒ»þîO%XnNêM2 ?‘àžÿ$^xæûz8±~ è>ñ®ØVÐXDcSÿÿóœ3µÁCþΕ5ˆÑè“}Ã2ƒ—Ž¥âQÈ݇'üIÄ¡?,Ë7Ü+«ïÝ#«·= ”‘/ušî.ë8ÔÓ)çA€h¿|VÚ¯œ—þ¶ˆOt+^¥ªk *罯Â$b¦’±ØðÀã²ýÉ— zÿ—ªlæ£B,¬\'kî}0O* ×ÿ0 ôT—[2~8—ÒŒÎ~R ?$XL1ñÚU[È“ 8d„Ø`¯’ÄŸb6Oc©`'ª(P¦¿Ô‰õu–£B^'†û˜vÂ8ò=ñ %¶©¯ý†\<ö± Ñqí‚ ">ÕLÇ£Â|`Ä0Ï…@‹~ó0±nþðÉŽ˜àãL‹¡Oœí™oû¹þVK“Pð ÜûÂØ$ðÕA+© +C?”³)|ù¤¼~“4nþKsQiléCÇE.üDÅrŸTâgjס"Ç÷zk2ªIc1Óï5€F@#0OY\‚ËzaÌõHv($™2ÉÆ`lMOoÙ vyñ»rÛý¨ÄˆI h×MØâý\ X7þx¡\ൈ´†0Â#”‚¯€¥j0—Dƒ4Ü磰9'P—ÌÜF8Á¶+…‚ (øi|+¥í A•À­bÄ“H€çvûlƒ©ª–¹4çÓŠÀóÑ Vs!†ë»<_{5¢Â‡â¶©Š ãzy¤A6`HL d¨tP,Ñ€$E(ˆ'A(°iùj¨7ò¾8GïiUdƒ,T7Ä|ƒ$‚òzÉ‚T  þTd`;@<ð„At&ŒÅep® c6“‹„´EáOã2^·$ hdVf‘Uñhˆ.t0ÆOˆ¿PÒÒ~þ”Ü8ýÂv(’J('=TÞ¼^š÷ýôS2 ïºë.Ù³g"Pµ‚ÚÓu”œ‹“PðñÁC²Ä—Þî© ¶n»GöËa[*²A …ñ¥RÒ´@ÛáÜ \;‰~ÈÙû``bK ¸ ÌóL{ûÔ&º¤U$1gÂ3K pZ¥OV†;¨@̉ ÷b®4c{?¡T °ÐíÅú<ö]u ¼ªY;kíg+zSþ…bŸÄÀ>^vEhì'±™[ãœÆZ 0½ú-¼Xwž­ÇPÑ÷hØa J…I–fx²X_HÓóJ¨Z‘lÀ $ °táR¡"%IÛ3©{ÀA4 <;žU  ]þˆ¨+^Ž3D„;ù,Ì-]¸¯[m§ä½’Ë–£0ÙÆ â2ˆƒ¸BÏlª&ð:&Ǽ’žï6¾.7Ï7ñ½cÊÀ˜ˆ!.uÏ+rýì)„ÿë/ŠPàÁPÃ&¨k>ö)_± c}Šqf¤0&QcÚM’ÕTuY!\˜»ª±¿9† 1ãŸ+å ŒwEš" ë/ê|«b.h¬qÉáXlš+¥Þ@ qï˜ß'渟‹-L_·¨(†PÐŒõµ§Ÿ¾= …À§·úîÝ»¥ººZ¶lÙ"ü±8p@ÙQ>,§OŸV!¨Z@‚ÁÊ•+ç'{¡vÝéǨ:ñÑG)2I4ÈÒÐРÔÝÙŸì着*|šÏ=ó 3›P@%¾i ¶mÙ$‘28iê/ëùÖ­·ÔÇz¢¼åøœ ‘àÏþìÏòå•ZΟ/–2H$°±â¤“€R§ùRëñƒü@Þxã õƒh{+—º½:¿Â1¬ ˜Þ…Ï(ýQ›\°º¶N/þ©t‚Dpõ›£ræà>ém½¦~D)'âýß©P·#¶;½å{[¯ËÉþ` pR`Ç÷þ£Ü½ç x×7†qéiØn"¡àÚ×_Èçÿþ¯Ò Ïr&<–oºOvƒP°dõÝÓÍrFçóA&ƒ¸•£0ð)©¾‘£4~—UÕ(9úH!L$†ôw¶Þbè¹jdå„ q¶GïOŒ×³–‡QabCíX_E¬Q,äå° Ôß}^.~ñX³‹B-'-eMx^´žŠy-¾†T2ó±Þ˜‡ô_€F@# Ðh¦ˆ€ËO$¡^¾ä ä¥`€m.#&Œû¥Ly¢#SÚû:[E*€Á9ƒýbp›B8… ˜ãmIR…™i0(Ž!p=Çy Õ‘øC¢Õ üP4ðû¨€Ù±²·{  2€,á5 RE®)S5„‚*†n@™œmqC^J•òþnH³Óª$Ç-õ(@9/"©@»ØYl(6jY…<u¶zCÃ) ÊO-¢ó$¯ ¦1ep.éAs4˜óò¼¢úrT3€17§£»[‚ x’f8‚‚ù—è I4àü¯¨9—á*LjLØ#‹P n—³0H”r/Q//ȰÌZ5±ðଠ‹¼HÖp“Lo‘-8gÏn|f]†-Ø74b£d†NpãÅ„¾s³|Z„e€”>ÔÞ*-ß^Ùø†$b§aÍòÍžÂN¨¾Y6î’½$á%+1¤íIÆz áAX˜À—á.ÌÏ܉‘OŠDc¾3H*H`Î õ WY­&„}‚A~Ý…ýg÷Ç,ƒ¤Þ÷3LÓÆ k?Ž›`†¥ëË*Å –¯¾K^záEÙºe~/ÇùݹM€ÐŽÆPâ44oÛ¶Möïß/‡’þþ~yóÍ7•dþ‘#Gäù矗Ç\jjjÌßÒÛT_]lab±˜ê7†9 1þâÅ‹J¹—¶¿‡zH…´øÞ÷¾'ëÖ­“¶¶6õYáœnïÑ™ &_«¾½-Ô¥ÛÌ‹oBg;-†28šívÌ—2¨ÂðÝï~W*++©@ÅÈ+bD£Qùío{Ë•ÄÑV}¸åÃ)˜­|í¢‹Í?«xJü)6yAÅog¥Ê—Ÿq›UÑ×ù0Ùjºk›Ô/_ãt­|òÚÿ€Wõ€22÷u´@nÿš„ðù\'z.´_>hJšþ¦»¶ÊöÇ_€½´ßc4àÞ8û•þ÷‘öKgòå-Û°Mxá¿HÓ†íêØ\þ¡!®¤ grcR©1žÛŸù°RUß”'C°=]×¾•eë·Ø§Œ»¥¡?ÚÓ /s!‡ßKôô¯(Pθ™Œó=98¦ìD/•ö›ÊËŸ “%œ2ûãO¯øH͈QŸž/Ñ>x¤`‘‚ÆÿR$ÆàúE\°ð€äG˜ƒ•›vȦ‡¿‹õŠé“XÆÖÉïŠPÅÈb=x†ºÚ%…-Ã)L–¦ŠU¡|Ô·Ŧ˜ˆEÏÍ«ù³I áÇ™CŸ8Û£÷§Ž@BÝ7>‡÷ÑJ¨w¬Æ‚a—´^üj´—‰!>¬/9=ißšziúL€F@# Ðh !à@½ 0$ÞêaÉÆ*,BšáH.ˆ!þ|¶4ÏÈ…Ê.D4àoÊl~ dÑ€*.IÀ& `Iˆ™¢Ÿsi>†í¡´«cÎãÁ<Ä‚ êåC*ò„x:c/ cqŸ'°Ÿ.2òÁ0R‚ý4€ÚfU£iü±^àAOc§›DåUy”æ;Ä`ŠÏûê4ë|n¦\_ëšMRŠnzˆ£ ˜;xIjNˆô »|ö ª”?äIP­/E4hU#%‡:¦`\HB%1WQ+^œ}0ÎR‘Ëë/ÇØˆ†Z†$;Öe¯|ž ´qpS†t^£àÂŒÅqÏç|xÁ—6&SÒ~ñ‚´_¹(½ð¥SC1©¼y½4ïy^·<,8AØê€*/ÎgñE£ÖÜc ÚãÝ#$5Xרµ»RvŸØïííB,CµÅnÀ ¶Å`5ƒâô¥ b ¯¾òªÜßVI໹XûÄl£×ØØ¨ì$lß¾]<(_|ñ…ܼyS~ñ‹_(rßÓ0ýÀÌŠ£êl·q1æO'Ú¯¿þZöíÛ'$=zT’L‚ûî»O‘ ¨4ÁP(ÐÎç¤ ó¹wJ_·yA*(}³tŽ‹²±¾óį̈)”‰)D* “ÏV}(¦€ÙÊ×®K±ù“ÙF ¤_þò—vVÓÞ† ¡øp=|Æ™pN;Ã\@#é]÷?*>ÿH®|ý¹Ê)yºÞöYvHTè¸r.ß".>,© ô„‚Œ ÿpäÿ\nž?©Êó _—¬Ý${^ü3Y¹eg¾s¹“ƃMëÅoòEr!&}E…**Ô-_›'dRI$¾”m `ðº‰Rç^?óeþNÌËkêá¬1¹Ñ?Ñ8; ­RQ·hLè%““¡¾N.€¨qÏ8W™‡yþ@G«´Y$‘“¹ú2:)6”H àb )] Ä€ÀP³tùè“‹|—ŒGa(½œ¿:bKÃÚ»KB(`¦># ¶`cE刮V¨u\…JÆÆ|¹…v²¸Wf¡ëú·c>¾«1'¨·¼¾¿ã¦DTÝØ\è”ü± ¼qH(èk¿‘?æ1­²aYþ=wCŸŒj~3erÌö^‘‹Gµ”å’†÷ÏPï[Ç#$àLÔ9?E9¦Üf}¢F@# Ðhæ+.ON¼åqñBÁÀW;ˆ°!E, Á G‚Ašê³_{Îwƒ°¼ÇLM¨XÈšJi(0„ÂÜ  \< x1Ÿ r¯$€K ŒdþAó±òRžß4 ªÏ.QÆ®c.Ùaõ 8ãÏlÌÔÿ¦]xž5Ý×aNñ„Ñÿóå‹`žì ˆø=è<¼ {x¹u—)Í0&† OËS\ÁÙ¼éÔx°ðÞJ!Ç)žŒÕ' «€þÇ{aì>bKD[Y;/ž•˧N‚·Ñ‹¡W\‡/Ù¾W–ìxJj×nC?xÅH ñ¦…J=ñÖ{ÑT VÄÐJ¹U¬0 s!ĉ*@úëÖ=`@™ÏHƒô‚ãì¿ÅP†EÑ›‰±)ýÊ *ü 1eLû ¯èêé ç3!<±÷!zŠT0ÏšuKu6nÜ(kÖ¬‘‡~X…D ¡úÌ™3òÍ7ßÈ… ”ÑšFêçž{Nî¾ûneC¸%}`N¸zõª¼ÿþûJ™€!ð,ÂÔÜܬìa/½ô’R¡ Ãí|OI¨;}|ðjKq!ø¢ÓBB`ä‰f!ÕZ×U# (ˆöîÝ+Ÿþ¹\ºt©à9ôš¾¹*#÷Vß^f¾³Ž”ª¦”~>aRåG1Î,íÐ8œˆZqQ'Ñ^.¨Lhˆìꀗz×g|DÃm;ˆ G Ppí›cê7&0âîFXˆUÛvá˜c!eäÒYÝ#¡¢†þ¨'؉ŠË7<*Æ$~¶rëýrö³}j’N#1ñÝ7¯@b혳GÞÒÈ?ˆ˜K翟?èƒWüª-l÷ø‰ ‰á( ‡XÂ4¼ Æðpù­^œHV/i’êe+¤§åŠÊ0E…‹G?ic³Z (T ëÕBÁÑw~•WŽ(tž}Œ¤ŠÊ†%R³l% ÞW€®¡àâ±²ëùÿl.ÀØ'¹åX±U3˜{&»7ØÀ7†“%’fª—6+ã¼m°g(k'HýŠõãÆc#ñ§ª'>ø]RÁd¥šŸS¥‚ãå«÷~/÷}ï©,@\QgbýgaQ.u2ö°#±ÞĽvÙ*õÞþ³úÄnËL¶<_HHá½b`Ñ<\U-eÕ³ä}Å16Äû X‡:¤¬r¼sáðÿá$b‡âܪÃv<‚¹ÏíÁíbCmê5QÉpZ’›Ý"XÔI# Ðh4YDsO7Bùñ2 ^à€``†F`x#€ýlŒÅ«cgMå¾B ˜É4ÂND4 0Iòmèv&3ܪРÌ!lE¾õÆLr$ `,†²¨ xýØâÙ˲Ažh@{/Io ÞW|„‚—ýéL+ip¦*ˆÞî`FM(õá¹{T&–”u¥ú%Ü™hØË'U®Õ¯Žói,U×ÐÈsìkxŽ2Ò ˆä¸¦eä òhÀ“SººÄÀ¦XÐ+ÑO¸ÍYíϤcÂרä”cNFßûÅ7Èæ{ÑW><|ùÊÄÇ 6¡ç‘áF¯ÊÛŠ ¢aýƒ· c ©ðwQÆŸüL9Aí§q>æ¨*aŒ¨~cvó¥ Ô56•žë—áÄð  ö£Ó¿k=PlØ´GÖ|÷O%²t5&A1¨\`~K›Æ~=ä ú¨ìÚµKy¸Ó ž/ª|üñÇÊ3žñÏ>û¬<ýôÓÒÔÔ„¯õC0›ÕÒy[ôööÊ”žýÒÚ E"|'VUUÉîÝ»eïÞ½J½›ª>„¥ï)Ä÷?: ”¦J(†+dËÖm²mË&‰”iBÁ|ïãBõÓ¤‚B¨ècŠ–/_.?úÑäç?ÿ¹´··O¹%.L¦ê| ùþ²œDf9ôAÁ*¯õ K$oöØõŽ…g…•Akx†è«ùÃd€×6câv=¶+j—äKVÊWÏaÞœ)hŒÎAƨòôÇöýÄ‚ÉCR€ÐÏó/ÞøW¹|ò°*ljgÊu*äÁÚ{R†ã|ŠØ¡!šet\¹ ËÖm’š¦U“><¦ ¹~î„|ñÖ/óäê–¯‘Í?S°4ì6CÅ¡²¡ ç-j²NÃä±·^“Ý/ýWeØ{¡i¸o‘¯Þÿ¼á¯©ÙþZˆ7>øäØÓóï9NHÚ8öÖ¯¤žô\à¨Y²Rîyò%©jlÊŸÇA‚åU²ñ'ä³–ŸªÏÒðtÿöø§Jýbýý©sœ©~„’Á‰~/ç} œŸÜG9U Ͳ顧äÐïÿY…rˆõCuc?úó.Y¾é^xŽLLH1ÇFÐ~E¬ Œ!oÐó$5;™Ê—Tl-*2ŒM4º·^<%'÷ÿ; Ê““\¸˜WQ»TÖlß#Ç÷ÝPÙŇäâñO¤aÍFYµu×-XÙePpùËCSÃjlE­÷ÄëÔ§o«…Ð-=/uîûØ`¿œ‡’ÉÕo¾Èç°ëî{XBcI%‹ Oò,v÷Fw«|ýáÒ% .oÕ5­FÈŒ§¥ß£>ìn—“½!½-×îØÀ½¸ZîÆ¹õcûç%RòÕ~ˆbÁ‹X‡ü²®1"µøŽ¿Ý)¡†&LȰ¸™ˆ œJkzAi¿~÷—y/P™!nbý©‡SY'€F@# Ðhæ—7+Þʘx*â⯔têƒeBrA6ŠÐT/¸i"¢Ÿ§’T3ÂV4 Ñ@…T“Ï<§)“1„/gò |¦È°í‚`ì$€pàV¤/æn ‡@Ö©æa¹u¦àÌѱg:¥Ji†8pTà‚PN£²i‰vœ_}6Í2ÀÉu€dKgŒÁ¡¢ŒË…ªTÊc u d°Ì+I¨K(X&) •B¸ºÑìX¯/ŒPA8Ê#T” •;ðè¦'}Þ®Ù~â C‡ * # }Áþ(Ð%öù<—ëK# ™æó9Ê>¶¯™õ2`ôˆöõÉÍo/`æ*æ1”mOg&ÞÕ7KÃÆ]²â‘—%ܸ˜A‘ù T$‰9/Ö†òmHX7)˜°.cXá‰AN'Æq¡ªëb)CáîކNgw¬”ÊÖ× _Æ‹ à<ÊÓ)EŸ»À ¡à7¿þìÿhŸ$â·± 5o9 ¯þXžxìAE((tÎB8V]]-/¿ü²’ѧ|þ;ï¼#ôˆïïï—ßÿþ÷òå—_*å’ ¨]QQqËßBhçB©#ÃÐ ôÝwß•7ß|SΞ=‹g:„ÀBX†¬ ™€¯õë× ¶ ­ëη¶’PðæÛïÉøƒô"\îT~WI(ؽ{¬]»Zʰn¨ÓÂD`œ§›…Ù]k€F@Ô‰ …ðÖ[oMI±À‡új’uÒ'ÆñB-%¶ Là^í‘rL›kÀò®JM8€x‘#3Mr»áI~þð{Ø^VÅs¡Ä_’h²Wb—r ªŽÓ«¹«÷’!s²›ó¦e8Ý#W/Ç«?¥Ó{®\ë‡'7$ ]›!;< ¦¾UNÆ—+—ŽÈ—Ÿ¾ãüJÌ­Å.L Ó8·ží×O}!—¾üLrþ¯‡ Èçòù˜uÃ50ÞŸ=ø®\8»_Œ 5Áõy$ØP.C©nùêó7ÆkÆ-Ç=˜¼F2€Fygb{¿=~P.8RÁVi\¹^BUˆT`¡±0)cÈë1 A ±êû;o(…‚–'á~ Ì1ó"Å$ÿÜ×rá ´ßÂØ1R½~%ú¤M.&f(Ñqõ¼;ð+ÔM• ÿ·XìŠPK¸Uá€ä Sª|’„™ˆ©½ƒ×åл?“ÁX«„+j€X<ªý=íPi8.—O–,úÑÆuðøgÊ Ó?ÔR’ë>ŒïÐÒ*‚q6‹]çä³·ÿAÖ¶?,•K–‹ÆM’ò«¸Ï1™`°W{ÛÕþÒu[à}¿B•iÿIƆ$ÆDÙÂ*)ƒòíùƒR~¨A*2€•gc«¯íš\ýúˆ\;s ’©# C)W¤3’öÜ:ÁÊbøjáTé•,ÆÛÐÑqN¿ûOÒÛXU©ð„RÄÆÊMŒù£*|…á‡dcØ£B?°_\zûP‡÷e*CøR®­¶pºo¸Ý2œê’“‡ÿ ÃmÒ´ñ)G Q/0#‘'£4vŸ=ò¾àI«üõeâŠx –³úDa‰û¸òý6^†/-ƒ‰®‚mæùvâ½Òöíi9zà55öy¼åZ¤Ð÷kï{È>Mm xö·]:'G÷¿†ï&sl„¯VãÜaY·ã‘1çf‘ï)ùº»^zæwW(é‘$î5^xÛXÉíË)ñ…*ìCùmGË7ùö$ÑžʇΠÅð]0lIŠzá¡U³t£Ô6®“8<|üðþÉ‹Þ΋ŠTÂ×s †ÃçvAŒæ6‡ÑA«õ¥€F@# Xظ@bt…S˜'@ê»**ÙXÄ "!¹÷\ÏÍ0àχä$”« eÅV4à,U‘ Ù`$œB Š<§”Dƒ,Ô 0uFy¾Ï `ü¥rä‚,ˆžÙ[âP4ðbÎÇP >xŸ»1Çv#Ì‚[SÎYqI#4¼|]A (9¢š³ày;?yQÆS´VmyŸYS2ǘÔ5æ®:Wù}i†kÕ5¼~–Ë00÷ÌuAö¾¥Eó.eضª7_6)¨I$ B1öKʱNRLý ©(¢ú£Cª0‘rç>ǹ:HbÊñãE<0Û®BpÃ{Š ¶Èb*ƒJ6Åt„uÍDX)…~Ï8CH ì6ƒbõ¥ ›PðÑþw§L(h^µ^^}eá œÝ´jÕ*ù‹¿ø Ù±c‡lÛ¶My”Ÿcœ>}Z‘ ŽâðáÃÇñè’M›6É#<¢”%î»ï>¡µz›Y‘srµM(xýõ×¥»ªOùg»ñ‹· >ú  !Ü×åtZ˜àÉG'€F`±! …„555rèÐ!õãEÕ‚¬¹Úo.¬k!}wýK©“~©5RxÈÆûYN\dˆg¤8-íƒ i(HM™rÙ> ”¥÷îo``Dœû‹Ê8™ÉÅ%Á Œ†±@¯|~è§0êšRç¬*=ÜãðXÎ֘Dzî”tÆÎɧýI[Âkéµm_›sØÕïÕºo½¬—}.Oè7®ËÁÿñÍ#žç8y’£p{¥â#Åá‰sòëßIð’¹üd”I¥  åƒ*Ó0Îã97Â! Ÿ‘ŽgíÓ¦´%© ¬¦ëA£½zHÖ@¬ú¡\—ô_¼.ç/wxtË*Püja)“N+#rÆD…õv ÌÄ2Xˆj‹ž–Î.Œ[ʬ'Òý’«Ã"€Ä%)'O¿!WÛ?—`¸ kU$€•$ŒÒC=qCÂV¶PÍè@ûû>º2A9ìÃnIU".¡•èÇ“§þ ×»ŽÚ‡Fm³hëEC9Sõj8)½û¯ lHÀƒréݪS|–ÆJTÇ–Æv¦<ƒ®´}&½ãÔá2ÃX8)çZ÷1iÿôŒT`!‡öSÕÁ~häÃ&‰ 刨pnôËu\©ªUeÚ¸H1<З\ªPãþÀßKeýÒ<É…vi<°‚AÕƒ±ãqÐÛ&'N¼.ó bH$‡(¬¬{ŽX]ë<"ûÏšX…"ªwSñ!‰ötc²†~V\d1°Pd=b¾>¹xý#ižº¥»‡ûzòmQ8cÁÕô­tÊé‹oɕփkQù/,ˆb“TÀö¤(ûiͼ¢žV9ñÕ¯o)Ã>°ú„ĘâÚßEüÞê:5éwïÿX·$Ë ·iuwÔÓ%§Ï¿)­ý_Ù©­_(#†Ì¦u?ãÜ3çß–¶¯ œÛ'‰JKŸã^ù÷I$FíäŠõŠûÈkâ>ýž}(¿Mb¼Ûí郇ϑÁ™M.²÷ƒÉ(„WÒ!躜//ÙÍØ`—zÏ×±kÿD†°ÎU ÞC«ùqþ½£Ðh4ÀÜ!à Öë†zALü ¿¤©Z ÈeŠl`¤çßr–“h`#•Ã3- Ò˜âØD lUš¹¨rÁçœ'—" ˜#2FÂ<Æi<¢AÙD\ ‚P/ðÜ0 €`À>”ý {ðrû _VC( €¸ˆ“6;ñ½•L`»w{÷@IDAT…i®Ã¼'›Ÿ(C©u’ã|XI^ecói~N#£MÒçeŽkJY†1ãÆM1: ê˜À<ÕÙ.«º·{“‹”‰Q^&)ôýçÅs-çK9ÖµDõ%ÑÀ…y[(‰Ñ>mÎØsÍ6`ˆuCâßU*bI†ŽPÍsAñÀ…y²Û^c`Ÿù1©°úÚ¥dÿ­qBƒ»=L²xئqu÷bQG‘$ð!ˆÐÜ Ö4Ld0¯ÀXQã¢Ø2P^¡;/]”˧OJ´¿¯èþ®Ûô€,ÛòÔ ,¥Ž.¶G<*Ä„ _ÀöåAf¡þ*,×@ÊQN(ÄÉF¨F»/ã>ÇÐ$WwksÄù1ŒÅb)ÃÀ˜±  âþLˆUÄú}Pã}¤ŒWÖø4è¿‹Q„8KM%-k^#?üáåñÇöàwqqyPÓ‡Fëææf¹ë®»”bC!\¹rE)Ðkž!žyæç,Où©ôëí<§¥¥E>üðCEäøàƒ¤Š9|î`?<ù䓲wï^¥R@•ˆ…‚b¡•Ó%TÀ‘/:ˆuI,óo¶`¡Ô×Ì/(ŸC¶¾ùæáYwwwž W^^.PðÉçÿ÷ÛâƒYÕ…¿s‘î $‚Î!xÂcõ¤¥/®^pŽ¿?*WÿâðLÁbƒÂä¹ “1lÅoÈP¦C†.t®&æ§vÎôÈðô§š¬kiÄŠ·ËÐ,2Œ—åð|ª" ·ŒS–ã\;»¬€<¥‚‚iÌs«ªO¢£à©“ì‹¶ŒŠU/ø{C¶œ¯ ÊS'f Ê„´\m„·°1@—ÀT/(äˆ<æ\Ö¯­õV#tÁ²×·A¨ ^i+xª:H‡1×Ä2PÁèC-8žXÎ0Ô3†A"¸%Yõ!691 ³/{®©×-רmqN÷™W4Ý-ÑÎ1åqÝiÔ5¸¸áv>Yr\· û„ís`…ªCôÊ­à޶³/'¼WF‹û*>Á}å8—ý‡oq¨H`ÍNäÖ0Þèxɺ>‰þ¾™!WwúTg°è×Ý~^½ ]Ã¥vªºBUV–€ ²nxX·Ó¤‚Bhéc€F@# ˜[\nª$¡^€'„š!A…E CÁê LI~n«/Í õ… _–]ËþÀV5`4ƒ4 ÒT5Ù Çç˜$„,#ÒöeEoÍÐ ¤!3q›¹À9|†M =[7åI¨‘¥ÅbY8܃x!d! ,nœãqÀ /ú¼$}æ€Ïå&I–]8ÿ9‹s&Rí×X…mTvžÏý•‘ëD¸ƒ˜#wvXÞöc šïijl‰¸Ëa`È¥á¬P„ö,Ô3XQäg¹V’Ë`„xÛ8=êûÁr)§$œH‹ÏRà Gák˜‹ýð<Äß,É"~  Xa€€oxA8 ùjn*•U+#¹R´PŠc*‚:d$è«úª¾ÆÀãœ|lÂytþ ã×åÂÖ™lƒ½ó÷Ç–a‘Ö{®| G•¯Ñœ~ËÖL/y@®hØ´GV<öC‰TV‰;MÈ(è{¨+A¡z±o ªÉóÅÍö;ÚgŽ‚‰¤hHð^ÜeäÑ+ÔƒÕ”2Ö'-tŠ%<ç¼GÚµèÎþ¤s!m7nTÆìýû÷ËÁƒ¥««KÞÿ}ùꫯòªO=õ”²ØNPÎ|ôþÄ ʧŸ~ª¤÷íÛ'ׯ_WÎQ$<öØcЏACT A…–¿y $‘PðÖ;ï‹R((’P0ÞãÞ@W8L >¶µµI'&dððæc ùR¦¹*£µµU}i“ùEò¦¦¦R6C}YÑ;? ºŒ‰¡¥×ëbÆjéÒ¥˜ F\d>0>OUU•D»nÊqµ¨@ò4bì­Ú11XdVc’“¾r ±ú  ЋI9¤ÞNuÜ<0ò×ÓÚ™oì;«†äÛ«­ÒÑz’7ðfÇ(e ãÔNÁ›s #ŒIs%ÞCâÉzWTVJm^[Ú}¤½§Ðh4i!ÀßEË ðSSU.Ë<ÒT‰ÔNüɉSÓ*QŸ¬Ðh4@±¸ŠÌ]oäëc~„F0‰Yª T‚‘)d¡,¶´Ù½n´ª¹˜œ©  JmQ4#õð,Å•&¹û´‡r?]cœÕ´QDƒ8çܘ{÷B"8(~°-9çf¨?HÁ²°˃Ø'É d :ÆO/BÖ¹8?wVTÛˆKïm{.(ðg´·²:ÇÔá<;CeÐ`ðÛ/ª Èõç°.f\¹ ©ÁÓ`ma0Ÿ6®%Kijv-TßàÅŽuB/ˆ(ì™Êa̲錤¹ƒõ†\¤*\Ǹ¥§`Fleœ°±/ÐÀ`*+•Ã3‚µˆ(Nš<¨ Ãy Åc͇)Çþ© G¥CxÔçBåx!ìYj4˜“h¥BêuÕ X'çXÀ7Tè4 Ôqkœp¬0¬:Ûìû‘ebÁ›YqÌ™Ÿ1”B¾ ¬ï vtJû¥³{pj“ qaÞcêÂ)þ Õ.•úM»eå#/K¸q¥qŒÔÓ…µ+7B°~LJIƒn¶aD<¦º‡jCH n*T¶v2@±IfÈó3bg04Â".ƒd …• F‘Û ±Â}€BÌþ`ø$ÕjOÿYÌÌ„PðÀÎmÀÚÀjkkåûßÿ¾lÙ²Eî¹ç¡jÁ_|¡lHÿöoÿ¦Ô øž*È?ü°Ð1Q§ÉHã·òøñãòÎ;ïäÃLð˜ä¼]»v)2Á³Ï>«0ç1’R"¡àÃýå7¿AÈM(XH]Wòºò)mA%Oœ8!” ¡¡|÷îÝ%'ÌU”•á—¶?X=ôPÉIüÒÒeLmxß XqœQ™`¢ä –Køñ¿œè,Ô@ÎýÊQIøŸ’Æä<}é‚:ŸƒÌµ¯Ôñ±Êw3&I˺1Ñ»yCú°v·)©÷l 2wé8¼ {äzÿqLJ1aÃ\­øµM"K0?-3àQŠðÜèÆïo”ŠÛî°”7=%5 áhkç­‰ã}“¸þ˜î88É®·J¤ù¯&9Éñ±.ÃÆ$»‹ «Þ}”Ó0FWÁ=úÏ'Èñq¦ß»º (ãìj¬Æ¦Àá;+,Bò÷Å[¾RÂkþO5QÎKü¹y›ß÷î`J‚+; €¦i4€F@#`#à)G|X„0š‹ärçÄI¨—/‰ðtÑI0P! ^¢Ó4øÍE}JQÆ0æ· ôs’ÂJÌÇf¶VI$`{H*ÀáQD|Ž˜y%U5HÁ{/g"¹ €ÁóDÈôûB!ÒAH Dh7<`¹=Pwxp›„Ë JÃ*•hðSa«Ÿ`ôUÞì8® ° Æ8çÐHÍó™,#2wMïwÓX¬âÒÛF[GF ẠPpõæh4.[ù0ƒù’€›Tà ~åJx1’P ÚáF˜ +  RY0‘9¬Ç0hAmbøE $™l¤¬Ù ŸI4Àç '«œ;Ê)©ˆf$ˆõBò:ŠM”-+ÌÙ`¯êûN(.„÷s—Õ€d€‚¥ƒg¬>t1œŽ» ô'úQãéÅϾA€çªþ…á^Éýçûœ„+1쀒±Ç{¨'ˆ2îc*nðYוKÒvþ´ôv´Ia‹!D—ËR(,Ýýœ„V˜ã8ˆ°¬#ëE’ÝT‚zA„tú Ÿ‡!}ưx¹A®`û9‚Ǭ”‹cN϶ yÊëͶ Ýw@’DøB8%Í4MˆU Ò“ÀÝÍÐŽ7ô• 3Á/+Wo´Éo~ý;ùhÿ»’˜FÈ*ÜI„gÿ¯^½ZV¬X!;vìP¤éVpá¹|ù²;vL…D ¹`ûöíêÀy½ÞAàüùóòÞ{ï)BÁ'Ÿ|"ÃÃfص Rõá…^G}T9yŽ\µpöR©Œì{w¿üáß/=ø}Êok„ÃÝ»÷ Ý C8áNÃuM "0òDSðãùwzøó ެiÆ )uš«2nÞ¼©Ú‚wܪU«JÝ ¥T Ë˜¬$’h¬€&zNEB艨¤/~¦ Ò`•çú0bI ;ØQP©À]µ´`¾kDHs`ŒóhO»$‡‡:oH†ÛÎÉg‡ÿ²X,Â3#¼FwoY×lH8Ùº\¿tC:ÿl+ä©u Š9 t÷$’¹YþÙxß#ÒØ¼•µ?efá¼H˵ñÏû Ãßmÿó±Gǯ˛±Ÿ,&¬¾=7çiŒ«ÊUÓWIä}õ¤.cì*ô^cU•ÂÇîh¬Vˆ¬|q4.p´²I¡Õ„R±OÔ[€F@# ÐÜÁ¸h¡ÄÜm®“;C^ÊxUÃP+`N–´M. zÂÌ÷42AÈôƒ˜o¦PÝQ¶^ ¼Ìu@î8‰Y€Ž÷0çÃÞ Ã*TqƒªëxÁXk_jåPì&ƒÅd¾ð=Ÿ…"`8…q•áýe (¢ˆ•ùÅW/ÉþúÉ{9ŒÇŒ{H#ߨ„ŠÂ¨^<ްù¥V¡ .ž¥•@^È'kÕÚ£í¦­xދſ'¡ªîÆzq!ì`mpÔ=dµcôABGÒ†‰;I4–WŽÆvtxŽ 0t‚"ÀØ‹ƒPÑÓ'‘hRü)“ˆ‘Ç«D;„c gx aÝùò• ¢] x"£‰9 H DÄC¼úÍ„¾và­ƒj£ˆÊ 8ðüü0’Ô:¿=/×N}%C=jMÔyíT÷kÖn–¦­KUÓZ UÖ™uäÅ 0ؼg^ U pŽ¡£M}æá¸dÂi“y(ÿd #Å…,4 ùÑ}”ad^£_L`eÐY ýbÔIJð-ß9 ~ýg‘ ` ~« Eô'+H* "Á< Œâ$\½zU>ÿüs9}ú´rZ¥‡=_+A€Ë;cQÞb»¤££C>úè#…ITW§m±®®N93ÜÁK/½¤pãóÒBL$||ð°ìøèínGû&Ž ¡`ûöûnc·&,ÄNŸ¤Î ŽT@v'%ZÖ­[§¾Àøà]â4WeðË…íà䫾ÌÔ'~Qé2¦ªÆjj8ÍÖY0Ù+—¬PÙg1±:ßñ%ÈC_©ç~¬IÈÛEî^eÎ8è¡àÓ¯EÎ_ » ϘÎ7äÊÙÀH¿ ?÷×R¿lÓlUYç«Ðh4w X„rÁÛN'€F@# Ðhæ/ŒÕî…Z‚ ¾ÚAÉ …$;„ðŠ`oé4¼UçáÏyOÀv¨ Áñ™ü€)¥QD‘r(4•ù%ïiT ’0gŒ d}Õ’Êù%1˜T,)ÉaI ø‡€R¤¢lÈbHóDð‹àé X^²(!„O€’¯Â(xð™ Þí¨Ð6nJÝ“p ,€fm㣽¥Ì”e‚UçÛ ôNƒ¡: £¢’Ňwœoy¸ bžñód ÔÖˆgå*qUBá&”„V¡vØÕÍ·Õ 0‚‰’$*A©0x#äC¦/* 0 Ô9sùÇ“ ´$^Ñ¢AJšdé]X…Ì…¤+j%‹pˆ³ŽDÑàðâ6 ”1Ø&XЪ¯'ÈÒÆ ý< õËž+ßÊõ³ßÈ0ÂkNÅàQƒ%Û÷ÊòKEÃrÔa=LLy®’íW÷Õ4Pª0q€+U*'Øu…ÑE‘ ,ã‹‹¡DíϨÜ`çõVº#Ê aÄÆÁnxÛ‰°RX_ö‘]–…wEéKæ9šPPšbˆ[‘àþûïWFr*…÷ôôÈ[o½¥”ÃÄ‚'Ÿ|RÙçÔïpiŠ_p¹P‰à³Ï>“}ûö)|.]º¤Èlt&~{÷îU/*AP9z¡b5B(x„‚Ž)ý¾’P°uÛ=rß½[¥á·í¯á×ɺÂã"°àH6{ʾ'“s·å|0We0– •XÞl´ƒr÷ºŒ :Úñ‘ÆÊÆmÞMQ|ñÂ'’‚$•þÖ7‰lXy€U/„ý““—DN]Á¤s*ìU*R· &#·”³ÇéÅjyê•ÿ Š&˜Ôé¤Ðh4€F@# Ðh4‹(&¸ƒi¯c¾êà Lr F<€y$Œ±·9‘@Ðç7¤%œ“Væl»ñt«Õu€%0ØW—ÁLh¸RÉ©+™yH©§s>‰A?i Ü`\Òù‹D%Þ7()ìÏ.ÑÀl×?‚éYïƒâ¨Çç8$a„Lðƒ\@ýI6ðƒ„@¢$OÞø8—És ¥]ƒ$“6AÀ¹bMeHý <\Hñ7À‰‡Æ` ’ †n•/ßÃÃ]àÙŸÏˬö¬þu-[&¤òøTn˜¨Ê£Ÿç¨vâ|öµºÉ^,ƒCB¸‡¢’»Ñ"Þž.*RE³Rƒá&æ|‹’ô÷"¤eÖ€ZÑ_PµðX@/t  x¦Ó€¢Œòj}Ç6ô“dÕ‚Áö6i¿ø´_¾$q¨_â"Tß,µ«·ÊÊÇ_•²Zì“`½3’÷9‚ Q¸·\ï@bƒ„axÜõE2`_@!†²'=óApEjÑoæú”÷©ä,i´;¬ ’ äƒù·öG9°Æýár HBÈ÷ëËЧÍŠ!,_µ^¾ûÝgd×έë£×ŒÇöò2ü>ýéŸþ©R/ qü7ÞPa¨þ‹_üB¾üòK¥\@ž={$Ì>wP¢Ú5ÔI& ¢CD$ñ,AûÞÖ­[…Ê$lÛ¶M…‹X¨dvéLÛ¶lÂc”ŠtZ”˜Oè ¨i¼)³Â×l¥¹*cõêÕÂ×l%~™é2¦†®Æjj8ÍÅYYÄ•»yÒîH~<ÿS¡€sl•0‡ŽBmñ+ ¸&€µYµD¤¾ Ÿz"ÒxE.}ý+Ä– 'ÿ(;÷þDê›´Z…žÞh4€F@# Ðh4;—7+Þʘx*ââ¯4ÈÙÁ2S½ ŠÐiL8oCJÀÓº¶J*Äi/¢^¬ÕP°ªº ‹¶ð쮨ǔRíuâFŒvÊ®ç è‡$~€qlá5f{V'‡@,èí—ôp*oh O ùxï $1ñž Eƒ‘¦öHà?Tèäá·€á>!¢Â& lAÅÀ /|Ìý©pèaǶ ÒSÝÞÉXÅ0C s´ã¡zªNÇâ¿pjQ!a’ rÃ0S¶^ Œï³F4QÂU_'žµëàA£´Õ€ÉÚÁóì…u Þº†leôÆg¹Ž.1ZZn¦&‰Ñ<Ù¢ÏcèÓH$¹Ô pÇË‘|þˆøüeˆ<b• ¨`€c~õ=†_Ú¢íÂyéC|çd¼¸‘%+dÙΧeé}OI°v Ñc’¸1oc’J$yàD*„تÎë°he¤@dIc d7B<ØÉå/l„»ÊPÄ {ÜÛ€±-«â¾m‹¨œ¾dN(–PðÊ«?–ëVâ;¥ð½>'•_…lÞ¼YÖ¯_/«V­’?üPöïß//^”S§N©-éÏ<óŒR.زe ð\pfÆi÷ÂåË—…ê o¿ý¶8p@ZiÍš5òÔSO)…†ˆð¹«ßsÓ®` /˜9¡ Q:-Zÿݾh»N7L#°8Èa‚6ÐߪÇ9s#ˆûv¢³A?æúƒP-äÜ„·µËLòV¤lÕîÖãÒ{óKIƤäM*°ÑÓ[€F@# Ðh4€F@#pç!à‚z+”†zêQ¨± ÝQ$ƒ\Kcg˜³Ÿ†º ë¬ýþœ$aÏ(†P†!¤F÷åK—H9$ãÝ xÊA( ·4 ¯ÊPy5¬£0fÒðζ´/PNu€F«±æç$Ä8~ª$ciI q¡#Ò’Ä$<KH&ƒ¼’€Ÿ9V©DZøRÒøVvvøª.pß @ë$¨WDm=P `ó¼ðDpaá@yòÛ øØš»h3O²“òìÇ ð²NB'B‰~ªÐó]’À[#=Õ  XPÑ[E6°ó±ó³ÅÕŠ¯ÀÓ¸¦A³‡Ã¸«ªÅ½¼I`xTùù,ì6ðÀdí°/r\£v³9Éu‚Hpõ âRÀ>I}ílær›E¸†8”)">IÒ[dœ”Nô‚—HGþ ¯ ‘èËJçµnîë—,Ç{©rÅY±óI©Ûö˜ø«MB Y`Ý™Š``!Ž1Cy¾£SÄ”mbŒïvÕ ˜ì}E:`GîÁ;ºŒ"ûJaêø3qÀ É¥¾­ñå¸OÙèÝŠÀLOî}Hºº:•TýmþœUÛVv&¹àž{îQ†ô?þXÚÛÛå“O>‘¯¿þZ©0$ÂÓO?­¹bz±%†€8• ¨PÐÖÖ†ßùœ ñï|G+Ø~ªÌÇßÜéö‡&L±;ï|M*¸óú\·X#0¯`ì»T‚“Fsæœ_r.‡ÓC)B!Q©˜G¨„„b“"FVbÑ^û#½Õh4€F@# Ðh4;—êUÃP/ˆ‰ƒ4B"dñÊ •l€ fn|çL¡ë Ò2ÁT 2#öÅie[ïýåK—K#^Áº¥P'€Ì7˜0˜‘ `zOÓ°IYv°ð1¿ÆQõÞ.ÈHÁ@nö\~’¼(K ÜlžÏ‰7òLBÉ Þ7 Yxî§úû$5—h϶i„SHÁ¨;d fCÕ|+)¢>)¼ øÃ @ÑÀw€¤Ê!™l\X(p{ÝJ†Ø…­j{Þ˜h€(@ã3à ð3ô5?ã+ˆk‘—J4DâŽB¾ 1¬O$ÓâÉÀ`˜;| HD€ºƒÂ˜Ç‘}’bôL!‡:ËCpf÷ˆ»¦J\ @où]ìð,[‘#lƒ5·ùº[õT¿HŒeÆõky,Îs_1‹RèÇDÀ#ƒa¿¤|#8L¥H¿!-áœÄ­cJë¨Ñä»K—­’¦¦•RÛ´ZyUSFÜ@¼váÿèïÊaâŒXôfB¡vìù1Yóå‘㔓/œï½D¨(¾ „(4’0”¢ŒT<ƒK]ð‡’ÁÀ0B(Ä¡^¡N¢x5ƒ$ާ†aÐæ„¾)“B™x™ mE²‰nh b¸„`9dñ.Á @}x!"3lŒØ¶ÎfÀ`o“˜¡"pgL™Áå-W#X¹ˆ‘>Á™ÀE N¹ƒ¦àûeû‚!q‡šá<,ˇþ)dda,’‡m¨Vµà¹…bÏsŸ×¨…þ‘v0¶“L`@qBâP^p.žŒiÖíz›.1ôUÔ1Äq7DBA:š‘¡î„D{AlIG(pù¼YÖ,»¿#«6‹'Œ°œÔ)høFr@$H@2Qä“` >´þ(RA|]’F¿găРB®H ¼¾Pº£Ë`8ˆ)© áæ<6Qäâ&Éýb˜\i“uœ™èý‡€&ÜÞ.kjj’W^yE¶nݪŒê ‹pôèQ¹víšüÓ?ý“?~\lrÁý÷߯Œï··ÆÅ•N†yx÷Ýw¡àóÏ?ÇÏj\%6mÚ¤È$ìÙ³gÁ¶±2$¼ùö{òÎÛoMP.—;vÊÝî’2>uº3=c¸3Ú¬[©Ð,Ò˜'_i©s€É‰‰h‡ v_œìTý¹F@# Ðh4€F@# ÐhžPJøòÖ K6@h„2(„$;’AF÷Üô¼©°&@^èÃk{0'ñ" ^@$X¿y§”×5ÁPIu«N4–Ñ‚I-åüF%§ÑÖùömã¶óð-tëCµ1ËT„¡Xæ0Йeĺû%94 ‚ £P6è—8ŒÜ‰>ìÃ{Þ$ÀÐ= Dƒ!'B׈= À;Þ>ð=ðˆ‘A%ƒHH4ôØí‡ì¾ n(xü~8•Ã0ïL668¦vGa„ƒ¸ŽáìÃôÆTá29 ƒ<22Êð@ou¸.Žô•ÓKb²2X')Àq>2ÌwOcÊAŠÙ¸y8t™aÌÃóê¯kÙ2„€ˆÀyÜ/(Fd`\ÎÀË? RFV²Çè(2ªÝV Ü $úÓ2Ø‘€pÎOC­¡ˆÖ¸Q¸dj“Òvý=éî: 2J£”•/E½ª%„°  0Š€1Ç…ãÞwÖM‘P÷Ïu‘DÃûĪ˜êocÂA§WŒºÞwwZl¯ ’§¸?ö‡ÝöE8ï§âJÔWÝfŠ!4¯Z/¯¼úcaÈ­PPšäoÞæÍ›©à¡‡RáàÂ… râÄ åÍìØ1åÅϰ àåoáITøàƒ„Ê$Môõõ)’Þ2ü†±½O=õ”¼üòËRSScþÖ/vMVM›Pðúë¯Kw'ž)ø;I €P°g÷ƒrïömà‚`Y¢g¼IŠÕÏÎ=ÀÒUÐhæ:#œ¹*²¾Y¤º0Á;_¡ &~-ÞCìGS© ÿÞÑh4€F@# Ðh4À$¸<P ƒ"^Ù˜„E€rC#€d`dhœº1lØk€L ÒI\ZŒ´,R% P(X¹n“”Õ4 xäBE>ÛÆexÒ3„ fʰi(áÅÍ0\†@ɶ[žºnX¶»2œšm2 LO~U¦QF¨" áʾ[†R¨$‡%Þq¨€p†¬d¼h@Ž#|BrhvˆvW»»ú@0 ™ÀЉ&ÑÀôÂ\¦^T8 L<üa ›bêB^Ì|©˜À•…1¾‹ÿ—¾…Ì#¼å9æ["–õuâ^µJüÀÝÇ{øQ":›NJ¯T2iû1n2i RmÉd1ÖámíLJ ±(ˆ “rðZ7*‘o8 ¨.Ê`ÔtHñB"?2A X­´!>(~Ë—HYl)ø|‰x» jªeèó°ê %öæ€÷ï+ö'ûÛH@†ŸmÀrS†ßºïÔ~ä$5v¬ï•CfèÉq²XË nN‚…Baú&ÂÊSް0¼¨Ü¢îCöÈ>Ó/F_1O(†Pд|-¼ê_Õ„‚YêC†xâ‰'T8„]»v)þ}ûöI'Ôrh”?yò¤9rDyõ?ýôÓÒÐРH³Tg;88(ü±jIׯ_ÇïMNÊËË…ícX‡Ç{LV¯^-ÕÕÕøI^<ß(£­øúœ:¡àÑGÄsPýE=çθãt·óIç¶­ Õh4#€ù±´‚#päŒÈ›DÊ©:W aî)7º‡¥¥ãíŸêC€F@# Ðh4€F@# ˜:ž0Ô ðò24騩\@ƒ\œqÕ'^Lî Ò2ÁNÍL|긕ª¬ª—ë·H㊠ ¤,Œ“Jb¦1H¸+#3 ÝNc·Â¶€×¸”ÆNˆó«Ä¸ð…óWÒä0h– Œ@M@ðäs¦Do—Ä;{$‡I|| ƒ¶ ô ªc$"¤B!l£½óúéî粆$³ 8ÀN‹˜ù˽þ>¥jày‚¡üA Ç¡€—?ÞP6æ„VpA‹ÏGÙAéGr —Lvèeôg©•Æe.Ôs<¨`$ õóœ¤ ƒ!&ºïøê5‘hU)ÎØÎ¢f-KÆ€»y™HÂA°­Ä m7GcD‚hgŽØÀŸå ƒ4Bä@ŠIEã0PuI_[¡7`¤/²¢¹rŒíŠ´X Pq¦L:.Ѿ«•«"m#Ÿµ®hÂØ¨Â¸hŸá4¼e ÕI°z¹„ëÖc¬Ôš!DFdlÂø0bIÁ{ D7I©@Iò=ïUØH÷“ ƒ°Àñ¢Â”,’2TØËÐ_‚)š6VcE )WKŸ8 C(XÖ¼Fž{áûòÄcj…‚Yèg–õõõò'ò'rï½÷ Cüñ”ƒB8§KèõNõ†Dxî¹çäá‡–ŠŠ)È; ˜åý~s¶Ê$|ýõ× »¥•âÛD" 7n4U<Ö³Ô,×k®²7 﫾ê.‚PPßùhth®ª«Ë™'Œó¤;Oj§«¡ÐÜñ0ðÕ·"T-X³TùçªJ7^7»àý‘ìʦw4€F@# Ðh4€F@#0Ü^÷ª£â­Bh„šA„FCÁê 0„á~ô²ZÀ>¿!-áœÄðÑhóåÔkÒ°t¥4¯Ý,+7ˆ7aýðì^è) ‹ª4Æ×ÒcÙ”äp"¯^ŠIz8.à $°OrA„ƒT,îÒIëf°ÀÀ—ˆb(X½~üðRaË­¤‚`¤L©øÃ$@Ý Ì" ÄÛãR/—­ú0‡c ´„qýšðE çùI(¨¬ϲ¥â‚wª<™¢F.°5<0Ø3)SMÐ?ÈCð0¡BA+ d \;Ù!%†q¿&%9|Æ«C¡|’±(aöŒú(¨’PY' T6!dB„>!T¾L<ðŠ/«\eƒ:p&—ÑiúF`(–Pð âÝ?¸ë^M(˜Ã¾b˜ƒÕ«WËÝwß­^û÷ï—Ó§OËÅ‹åÊ•+ÊpOÅ’ h¬g˜¢Û™HÄ;þ¼¼÷Þ{ŠLðé§ŸÊðð0¾¿]ªþ>ú¨ w°sçNÉ Hcog¥K\6 oïûP~óú¯¥XBÁ"„¥Ä(/ÎìFÏ~nCãxøý›¿ùU2eSþú¯ÿZIˆ”²*‹¥ŒÞÞ^ùÛ¿ý[MUU•üÕ_ý•p[Ê´ØÊ ³L§©#`D{dðŸþÛÄÀ«Á¿z‡Tü×”T2.÷ß¹ô`PãøÖïJÅÿ[®7C“çk]5”„Ü›•ܘˆ![씯 Lwáúˆï°¶ 'c˜C§Ôš„ ! ¥Bc<2ÏÍ¿#ávv£·0¾«öŠl?0úøDïÒ}È×L5é2¦ŠVQÔ<3½q¿2½q僴âtÇ®.cêcQc¥±"7ÁVÓI# Ðh4€ÂxÊ’êedàEí…b_2ýIwUI&(<Ú;¡®×ÈIšvsûÚil}˜W¯Y{·,]½Q" +ÌÐX±uÁøî¢”7½½­U\*”K‡·· ÞÐa]AL×ïïª˜Ô ‹»æ˜y>îÊFu|l¹þ¶Ióµ¯ÉfG¾Âåuòìù;9üÞÿ+-I412‘äBë©'g•µ5²­©[z±>rê>„ç€$°3À7’„œê§E*+ðá8‡’×ßÇã|Xà°.£(ãZLXÕ¿2½qEH¦3®‚«Dj_ÔeŒ3”FÖX‚cÂ7«ÑðŒðÛF×ï4€F@# ¸ãpÁ@é !<Œ•ž²„øë¤­«FÚ†*¥O¼*ÜÁÈÌuêpUÕ4Êòåk¤qùjÈªÃ¸î”Ø¥qÑ20ŽÊ‘Æh¥)•Oçè¼ãŒ·ã-Ô“PÀk˜|¨)eóiäžGexàtä ²AH°ŸÚ)²¤^²Él« ôH^vÃ=ƒí”Ä`\†:à]ÞG¢ JHXHåI À  ÃOôvšD’H6ð…ð`gÈÂÉù P²DE¹¸B„FÇP°*È>„ܽJÎ>VÄ`€®q&<&Ýðþ—jŸi+Gr0(%‹¼.ø.jL8/œƒ}d i€!¯DO¿ä ÿŸ‹[D /<=½ º`íÈãúÒÿÏÞ{FÇu]é‚»rrA@0gQY²¢-Ù²dɶږÛínËmËöë™yÝÿzõ¯5ýfÍZógVûÍ{NzrËý^K²lË-Û’eÉÊ™’(æ ’r.•Ã|ß¹uÁ"P…@àlò ªn8á;çž{ïÙßÞ›$¶‰bÁg(&§?<)}gzÄÐ\Ï-Dª;›¤qg‡ˆ3Ýý¤ø¦½pè€ÐXWåg¡r‰KÙ‘0üðCyàä;ßùŽ´´´`¾\økt||\‘–^h\KÒ@uuµ|ýë_—‡zH¶mÛ&5Û399)jÿÒ!¹0%ûA(øÕ¯/ï¿ï y íÛ7iBÁÂt˕뒓 ®(´te5EEÀ+‹Í»î“š†rá“·¥ûÄ+ÒwþcñM"#AJÀ«]³EÖm¾E6tÂ’£ë!yïÄ¢VQ¦Ðh4€F@# Ðh4«h鬮ˆtOUË…p)<Ø„õ !ávHm-b·CA­Ý§§P„!`¢Ä`‰NrDÅšZ‰‚MY%Š…ò(b(NÛ·gP¢¡°Œ_€wƒ!(¸„h`ÔÓøä¨ÊcX£CékÅX°BÁîÈn’Ê<ðpPˆ "fÁ$Yäþ—.£I8Àù’ªaám4H´üi$>IËöi‰ƒ€Ÿ[–Dƒ†—„XP}Îþæ±$èVŠq‹¡,,p«O– HŠhJVšq bS£b™Ñ€ápH®ÂCYòl‰Wb<Ö U îöTGàŒ™pIg³þ±q™Kß…° õù$)"ŸJ%²³Ï޶KóÕ[Ä]÷Ä+’ÖŒ\ȯnb1Ô Þ¢°øÀ‹B)ìóK×V$ŒÙDƒÂnDIÒ(Ù †2ƒQ¸åg¸Î$™?/ƒßF¡¬ðèPZ¾V*ë6IIe‹”Õn„÷‹x]cô-Çç HVÿ±)„cP 0¾Êk°m†XáùÓ?è3.’DÏE}8>ˆ¾Çx±Â©øpÞ°bí-¾eXÝX÷OÌEª¢þÉÔ‹ Á°“ ëgÎ iFf5Ч-æò`ëÎkåË_¼Oò@{(Xˆ^™žô¸ÝÔÔ$»wï–{î¹G…xå•WdhhHy 8{ö¬¼ð òÈ#ÈwÜ!Ô{KèáÑG•7ß|Sººº@ 3o»ví’¯}íkŠT@âò¯t €XW(¡ c}+¸Œ˜Sµh€€ñ²„PHpóÍ7ÏÔÀ¹ñnVJœÜ«•VÝéhY XÀì¯P)mkøR¤E# Ðh4€F@# Ðh4 ŒÀ˜¿D.ŽTKÿd…#$VàÆÍ l½VÕõPÓ:.Yí…ïæO(—©@dAÊ:])¹ç@mˆy0~Aqª\¥CÉl¡â6)Ö:ÌðË¢¬Ì2¬¶¸¸ÊoÞ Oð€H¥iEKƒÔmn‡ÎJå`zذL!\½„`258&~ “$Çbýòð âFø„‰YD7¼€\«É’ªRxe,‡•âè:·Cl.†ƒ€’EGÐgj¬ù%ÿ+"Ƕ: \æê“!xNˆNœ‹Ï&ñ0wàX_Tb´7+CN¦ *áÇðóã «`sÚÿÞV÷œS…p`>ŒÈH¿_Îwdb üH!tpšë¥yO§4niW9û;Q‰¤ë6Ö?æ÷!Å0ªD™' b¨1ôO‚h0 ¯ l‚o á5¼£ £ÀÃB¡”‰€„P¬8Û©¼xíGeÈ$€D¢AYõ:„ýÜ òG*wIiu+"F ßz! ¦½?”"ÌgâÒ¶¸èÂü†‘Ž„7”cÅQ$#î†ÑŽ…¿•$_ä2žŒš(ªÐBÚQY¥ÐêéóòG€„‚ŸCù{ìØAxI„èɒͶ=7È_ÿå_Hc}­šS³®w/! oÐÖÖ¦¼0ÄÀ«¯¾*?ùÉOÐßÇäüy«Õ÷;ï¼S¾ÿýï+Ôé*/^”Ç{LyG8qâ„LÁkçm’¾úÕ¯ Ëéìì”ööö¢’ ­ïBŸGBÁ“Oÿ‡|¸/_7"”î­ Ejј,‹Ñ°D³æ§.ÃD"ûçJÂj1Ú’Q}„F@# Ðh4€F@# Ðh4+ÁÉr¹0Z-#ÓeÐ¿Ú "TUÕÊÚæiêØ,%Õ´.†2/I7'(nñÿ²dOKõtÂs”Ì|Á/Ÿò”•]† FLLÉR¶¦N¢~¿²Zøàþž¢pM?~qHü LŒÂ£”ÌÞiè`©ZŸ¿¤'Àú…®—m°ô€áö8Á °‹ Þ Á¸D(8¡àûß~XZš”Â8FŒ–e½lÙ²E)÷¯»î:yæ™gTX†Rùß××'ï¿ÿ¾<øàƒòðÃËš5kp›K7×Ìm.ÉO?ý´<ñÄrøðaÏ2& Åpï½÷Ê< ›7o–šx€Ñ!Ÿ¼ç–vel¹ŒP0™OÈ Ö‰ ÷-dôˆHFC×h4³ ›»ˆ/θéF6ýtöé“)înGü“陽'†G]ÆlTRÿ^®XyÖç×ç,`äÓçVŸï¸Òe¤C©¶j¬R¡’zÛRb÷©ûPÿ)‘‰wñ™Ç<›º5z«F@# Ðh4¬tÔƒPP)¾:QkA„‚·´F¥®Õ-®*¸O"Ä©H¤1D…9 «s~‡Ks‹ J`êó¡Ôx"P èòžVÙ°6VVÀp/n¥…>¾\Œç¾„è2.aEå=ÑÎàũ X—¯]o! OMHLY¦GÄ?æoÿ¨@2˜–àØÔ `¡ ‚Ãô$B!€`Àî£âÃf·‰Ãƒ ¥7¥ø„»—ÇËüq–¹ÑßvE@`›ÔHRÂDýÃȳGb¡)ŒŒ/¶Õ†RPá°!áqÚ$¨ÃÖü‰cøYóÀî Ôx£ž')+3ËŒŸ %Dü19wÚ/}=A(é óNÀ26Üuƒ4îÚ«ý2ã>ë2ÏëCba±ò]ƒYÁc¬× «´\b$ÿ€tÇ5:…„`)Ù o Â7⇇ÂK„àÕÀ²A8Tx©Ìæù'Ù£ÏÛ«r#ÑÀ/V#l_`w–a,4JeM§¸ÜUR^ëÒ’:—ÚT¨žd…Ð8<—XÐq y`z ˆÃ C,€ñ¶[áåÂâAµOKY ˆ'Qô9ñMHa4àÂAý²•àxxQ d-#1Ç©ƒ ü“± x› KÆêD;/"à ¬–å†À|Û¶néixÞÐrÅ!ÀÜ{÷î•ææfa(‚_þò—ò§?ýIÊzÿþýÒÓÓ# ‘ðÍo~S¾øÅ/JYž—2HÄ¿—_~YöíÛ'.\9+¢ˆzwß}·ÊcÇŽª¼ÕB& \¾@ ~kx(Є‚ #HïÊM*È-}¬F@#°ºˆ‘’ß—$ HÙç‹eÙÕùcå‹{¢ËȬ•€É' Ý]FîcJcu…`…CÎÑå×Àß)ÂhýIdäw¹×]©Ðh4€F ON6J<øÂ wP˜r ^Ú^d¡ì›„¾ÿÈ‘çñι®ã7Ár| \Òãù†ñÑ!Tæ)å/•à w Õ6ʧ»û8—ê]•Ê?ž£váÝŒÏ(|ãy®.ïõY°r”@™Œä/Ãìª6—ÔaQ†›~,Òó“¡¼=ƒ ¢Áˆ“ D4Hôú”_&G¡@FÈ *ET‚·O<T”(ÏžR|â»Þ èQÀDF@X¡ÑD.’L4ÀñP%'^ ÔK ¬™ñeîÏòI ÿáˆô^ÊÐHÀ3ß,X‚äŠõ·í•µ×ìD[¡hb/Ë(õõV€D}½À¥ çj^d‰ g¾>rÄÆpàž˜âDy%5¸þàé‚Êx\‹x[ƒxò ‚ L{ÇÄGO$, Ñ@A­#§d¼÷øvXZ·n@IDATD7(ÁXW „w(«Yð ›ÄS¾¡Ö£îkp°A ¬8ïÑ|Æ£¥ 1Q|HPr—›ÍÆá—Fƒ £€ö+A˜q°0B@hbR¢È-IeD8_å8RþÍXFkx°LŽÇÊA*`Yl‡V¤r‰7D(Ø}½ÐC ôì¢åÊE€^è‰à†nPÊþÛo¿]ž|òIù裤¿¿_y8sæŒ<ÿüóò½ï}On¼ñFIå•úÈ‘#ò(Bg0¤Â©S§$Àý²sçNyä‘G„ù–”p>$QïÒ|å"—[Í'§ýòø¿=)¼‡ù n‚‡‚ví¡ 7”WçQúŽº:û]·Z# ȆØçê3,a,õl§èý€F@#°XàEЊ…r¦RXÅØ*Œ‚'?\¬ èr4€F@# X%ŒùK¤g¬Jú'*%!¡ °†ow ¹ .ÐÕYìPlÇ ø Ñ#Þ0¼.}…]ü‚X`oÆ3,~/+Ï>i×Á¡4c¥æT,Ý9IÇê2™+¬·mn’6.uDEK£ÔmjŸ!D~™îoß\çÇd¼gDÂþ D¦E!Ðe}Jk¦d™žô‰}p$ tÀP€Ãk§ Þ 4åU¡H4˜ÑÀ«\rû|S "ôFíì¸HÁèØœ>ô‚ð o‰ÃQ ‡ðbPÕ"k×ß*•;ñl'¶™$%¶_y³HÊ"™H´ÙPÜc‘½9ÓéŽgEjçeä†ä:¡Œ8Ýࣳ3K>P_j &|G –ºïŠ]>•ý­­­R__/[·n•×^{Mžzê)9{ö¬tww C#:tH>÷¹ÏÉw¿û]éììTÁÁAùÅ/~!¿ýío娱câõz1•Å¥±±qÆÃÁ¶mSQ¡<ЛÁj ~ú³•·ßxE¦&ñ¼yùCeJJ+jå¾/Ü'µUð”¤'Δ é M*ÐA# ÐÌA/:Ñ M(˜ƒ‹Þ Ðh–!ô.án©¾ó6]]jÑh4¢!ƒB9‡t z§c¡—YÆ×¦€Û%äu5"mDÚ‚T‹]•ÀJ@`p²áªedºLBQûŒ®1Ÿ¶A¿+-"­à ¸aì|ùõAELŒCHá1è«ÏAß «`Žm NòâB¹´"&ñ‹åÊ­n¡Ü¦µÖÈJQËõK o(Öàž]mçq°V†TUÛj‡±Š¹Îº\ºXuPD扂ˆ»œxýÁ>ªlª“ú-p{á•´q™’‰ }*¤ÂôˆWü^¸Æ÷ú ÷,Ž‚#a|¢þI2=9%6 àÔ@ ›Ý‚ñg…µ¦.óñYjS¿M¢Í Ï بH(¦.ÕÁ¢ë¸_†úƒoJëžTÙ¿Öm^Bbaw6‹³×I¢žÙÆnØ{JbcÇ$:}N(iÒëó÷‰eü4ò!ÙÂ)aèÁ€× ¡bñ&IðÛ^ŽK É儇•ê°Ú·âtkÛ¢AÀ'A߸„*î¹ý LMŒˆá6¢ ü„’ Å"˜áÍ2nïÐ ë?$m7IûÎ/#\ÂZ0žÐV*ãFs %ŽúÄ6ŸØnú « B)XBbéÆì=Dàu˜YÁO êÚB¾ê{"oub2•aE;Ô\Io- ‚ÇH1‡uÕÖ§%(ˆP°ó:ùÞwH(ب=¬Ð‘äFÈ™M›6)RÀ5×\#þóŸåé§Ÿ–‘‘9zô¨ôõõÉÛo¿-=ô ‡ðÌ3ÏÈé 2‘Ëå’|P¾ñoÈž={T>ôè³ÚÄ$¼þê‹y vnÝ,££ÃêÞ´ÚpÓíÍ<õjÑh4Ë g‚HÚCÁe°è€F`Ù"@b ĂʗmuÅ4À…ɇ‘^A‚µàÑX¹V†Ž@ ¨áê< 3…^ŽáùXš®Gº ÆŸZ4W2=UÒ=T+SAt¢Œ%Ÿkλ ºÄF$zOϨՊƒ8ÇÅF´4ŽœÕ3˜ž Pâ5àõ” ã ÷óJ)‡ Ÿv*ÿP9¥1K,žC1§RJPåêW‘û¨04C«{& Ýž›Š@fv…”îwÿ.E®°8+Á“ÀddÁ¤D‚À´ÃVR&¶Ö]G >Ë0ª×Õß°ÄÂQ‰Yœ°\‡ÅþÀ0B&xer`Tüã“ L‘hú(ˆ F謹>_L&X%Ô‰^ÃmPx›D’ Ü.x6pƒlPj»„üžÑåGü19wÚ/}=AXê“jQ˜¬ûÔiÞ»]Jë«P7*½ÑˆÆnxì#89(± Xq Ÿ–\ƒh×·]Ú á—ºh¤Q·"@ËŽ!Õ,Ê¡OG¯–®…—ƒ:ˆ`Ž× •ᜠ°0O)Â6TÃÐß •Ä@, à”ðä„„I(ÀXñÓó~‡@B tB¡æM4@àú„ýâ=¯H M׊»¬ ×<5pÀWÓÛçæ$’”H&àD– XA*˜5_¿â E 1À¤>°íð¡B„`æ=srþ_2–Á9Ž¢Ú¶P§ÐÑgd¡ÿB·í•o}ë²m‹yPœ^XÞ¹TVVÊUW]%;vì{ï½WüqùÃþe÷¨¼ÿþûráÂE,éííQ~_ýõŠLp×]w)OvûêT{L(¸ï>!¡ÀƒðBZ4ÙXWW6Tô~€F`•#€(˜ÕZ4€FàÊAÀ_ÂŒG£&L‹F@# ÐŒÀ8Î| éOH‘Œ°¤ø2K¸6ÏÄi—‰Äƒ¤³H0ü”/"mCÒ¢¸89Ø(}y0r¸8¡”ʳÍð(ÞÑ*Bƒj;×hsÎV .ABH g¡ƒÃs޽¡Úñ ÆNªüðGqRd®,«a]­x¼X’¬h3·©O– %' *aã2/#ì=#‘÷`qÞªB] ò„%A °¸ª Ü_ En©ØÊša^ƒýTé.>V6Xª»+ Œ…µ·ýañ”Ãi¾UªÚ›•{üH ¤>ck0=<&ÞžA ŒŽ+²Apb Ý‚~,‚Ä`)OÏðJÛ *ÉDtÚàÚÀB¡Ü™àqã·Ë²>A‘ \†·ƒTPÎTÞ ¼£Qé=¡tÒ… ì¥nYËÕÒ´w«¸+áA€®æÈܱA?ø¾„‡I<È”Ùð9'_¾A‘ H6Àe†bÜŒ18 uà§{&|É,6w¡”O®^†kÐbw`Ä’•‡¬¿¹\v‰•WÂÀu…b<2  ™&©Êý0B%ø&ÇÙ`rrLBóÀ±‡²?ƒ']H¤˜+¶qziP‚ߦ$ ÌMê“à‘ŒÀDoæÎd²‚¹­ÐÏŒe(êÆ¬œ“ê=kþ¹xJ(øêƒ÷˦Îví¡`ñºjÉK"!²¹¹YÖ­['›7o–Ïþóò“ŸüDöï߯B˜loo—¯}íkrË-·È–-[¤­­mÕŽ ~öèã’·‡ ¶iB9¦ôgvR=-d?k  +“Ó§OKWWØÇV5¹lß¾½¨5Z¬2Nž<)ç΃Û1»´´´¨‰¯˜ ¡ ­S§Né2rUce€D·e®«¾1¾d€üøwêå%Ú{Ì8/±.µ}vñH0{¾‰“œ~¼ìõ5~Q±ßÿøììRÿŽc%³ñë"%°u ‘Tì…Tš•LZµ¦Ënïij9u9z«F@# Ð,O8ïÛ«D¦æ~ï`KîfÍ×·)Ôß/\¾MÿÒh4«êOþˆôHƒHù®ÁC #Ho!Ñøó!¤­HZ4W qpf¸Nzò ¢-ßk ÑÎMëDš›àÀ\¾z,´¬ŽÁÂZÆÅBŒH3Lßqa¹Z‘9꘰À¥‚PYSqeŸR|âý]q Ô£ÊU<• ¤øc|ç»>C#ðÂWÛª@(ï–cá¾7$2zLbL:ˆiov•ù)Á!‰M]PXD`]VXéÊÞÓL @…¥¹ Ê`‹½tI°²¢¬e±c̹ÊÉ:1ú£¢¥Qê6µ+ùQ@Âa¸ÇõŠ·oTðf0©¼hÀ wþrÑ@e÷÷04Ÿš´¨è$XáÀ O¥e ™rAÂà ĆO˜C4Ådt ,½çƒ°, Ã~a„‚ŠÖi½f‡4ìÜ(®²R\ègXðS2ݨ¯W¢£‡ÁÉ9b FfF…:· ?Q†´Àº`7s› Ÿ@2 ™C¸­žZ„ñ¾Õï°þ·Ð›H× •á@â` *‰H+=Ðs¿cm1†c-X÷"üò€íô„¡¾‰ùG\àŸŒeÀ ;‰¡b,.”ZƒjÇ%zC¥êÓæƒÀ|m­ÐŸ÷ªùÔAŸ{å!à„gšÎÎNÊ`ïÞ½òûßÿ^}ôQñz½òÀ(O7n”ŠŠ XÙ#Ü ç©U(ÓÓyü>)o¼öR~!4¡`Ž–ù7ùÒ“ÀüóZ”¢xh&#éÙgŸUÊø;î¸CŠM*X¬2>üðCyþùçU¼ºf!›ª˜ …D—‘¢+' ^ÒïCjD£µÔ!iÑ,s'Ë¥o¼R§Ê%X ¡ÀU¶Î‘VèýÝб^ŠÑpjüà¹@xO‡i3Üé»ÖIÜ k|K9P Á*_=áHºWš5*Ò’Ùãa(õ  ¤XÜ`=Ð>… MÓRYó ÊÚëÊt[)—¶Œx4a>ø1Æ“¬¡ªçœ?1„s@¢ÄCãê3æïE<ù3è*K]ʵ=]Ú[\µHPþºëaq^….ð„2u)°²AbsR9‹¾I¸ˆ†"R·…Þ "ž’°o  Æejp û¨Lœ¿â‡§ÁBµ>÷?$ÓDº€ tCŒ|ýe@G$Pqc³Ã£A‰UJJ-ârØ„$¼ŒŒDddîûq|4R¡ nK»´\½]j6¶Š³ˆ q(Ó³]z¯ˆ‘¨· JlÞŒŠƒ‰‰ÄeŸÉáÀ7 Ì ”B”¸!°ºk2“¾[@l±ªxAÆõ•õäåKÐáùÁnÕ?ÆDÏÅSÒß £x/`(ƒB¤¾í&iÝr¿Ôµ\ˆÅ‚B|žQ87@oP.®y[IŠ@9œH2HH܇¹ˆ |Škr$#a¾±¸„sÏáñ BE!âaôIH˘$Ñs¦„!'æAÖó£–¥C@ –û•RrYY™ìÚµKšššäšk®‘±±1å• ±¡ixOWÏ-+¥µùµ# Éÿúå¿É{o½¦ ùA§.+ŽTÀvNNNJ¿"•´²e°îlYT Ñ>Xê2r«NxØ·V5e-ž`"ÇÆ{• ¾¸ß¸£x±–ñ1ZQÌ(y¬§ÎÏÚ˜úgÌæ5øQÀB—ÀYõ5ë¾HaAE쉘n|i±Uc[[êSIXH—¿v3½U# Ð\ İؘ뽃íá}bö½ÂyöJh©®£F`y €5[ê«T*¤Fó=?×2Y•‚õ]M’+ÆçÊ»H½À¡b1KåöÛ(ï ,Ò#¾³ "dÂK8€Ü®„ºœ¶!ݦ¶è?e‹@ÏD•tÕÊTÐÝ\‚s¾ÈSª ^½Ú$í ®A¾5N:>™hØ ˆÅÛë¡$êapSŠë”^Ö(„1—kVþái¯t:,}º•—&Ae’ߟö]_“Ö­÷KYU;ðMLVÄ–×I1ÔmfÄ5®È)Ê€ÇRu¼jBR˜ƒTóOWý¦ÊLÞ)òÌuS†2T¨xP°Ð‹‚–™¦™«r-OW0šPP0túÄÔ××ãUäz7È‚«™L@xH(xêégåƒ}o",N¢e–¥µrÛ­·Êö-¡—4ž-’v믬\q¤N­­­rÝuשø(íííY™ï‹Uc°.—KŇɷžÙŽ·m®ËȆ’±_c•NÙŽ"“=ré 3ép<ÈñR—ƒÄx£2I9¯Ñh4€F@# ˜'TþÒ2½‰|QèªÔ"7ºhœݱJÜ~:‘zð9ŒD5*­y,¹ÐkIÒV$žg´ñ˜!¤“Hgú`§\äãChPk–Õ‰ï›ò]fýÏ"aí^•Á:r}…ºÖ¼SåKF¨R‹_iGb¹-›+âD¼ÀQÁŠùr]žmhF¢u~ª·mzafÛùhlb¯ '諤‰çÓ²ßÄŽ –ebÎ:°=Ƹ±°ŒVçr}í$cò}ÙõkFfQ︉}ĺSŽ#E£{Z¹új‘¿ÿ{‘›oF~ÈÎTNQ#Ęó—N¿€¯Ø$8F·Z4Ë“ƒÒ7V%Ó!Ä0ç;é-jÀµ¿~¦€jL‡¼Ö Ë&?x¨èO✠Æ:†¹¨×#’…“ +‚DÖÓ(Ê~*IlSßMâ(…ŽÇ~#¬&yZI#|'¾¨ÃÕÄb*í¡Œðd7,Ðý»¸èlwÔ§xœ*MQçå*É „ÂZR¯\Û[àÝÀæD(„O õ¹Âd‘±²{lâ(G ´ƒ‡®0ÑW4VIý¦èn£ `h i¾Ñ~™<×-1x6A(Ë©â Ìð à4¨:ðï|dÃ]×KÓ®MRRSñÆq{)·Lc7Ü÷–DFŽ€K€‡ öér’ÑÀ¹öV±WoAý’”ö¹\ƒXg”‹§ÂCÁ96üЕ'ÖÜ»qï·¤uÓ=â)[®Æ¥†<ˆƒ eQÀYx8À bØ#̽`^Ixx°$*E¢ôH ȇ }’uÄa\#*¬<¢ÌœŸ{µç™± ²º@`°0쉉//-‹Ž€&,:ä«¢@z& .‡!ÌW³J(¸ùÆeCg›¸Ýœ›µhòGàÒÓCþç.Év¼À܈o†< ë“bËb•qË-·Èž={ð|c‘…hÉ ºŒÜF‡Æ*7œ2eƒ+±†»¥}ï­™˺/š}ÿ0ëqú€F@# Ðh4y À5˜óHo!A¢ò=€D¥÷q­šëÉ\k âšÊhnƒGY¥¤'™€Šms–‹þ$ðX*ש§ÒúF$泉Jk*¹©XçùfYøªŽ1ϧrŸçïDº º±;¾Îz§"ýýÄ'Ëà6–¥ŠJÉkN¬ß„©ø£Îõ¥+ë»)y…õìBz ú:E†0ëŸÜ~ækæÙ‚ï×!Q™ÎöœF"Ö¬'ÉXoWíçù&ÖTò±\z æù<—õ;ˆÄóIB æ$¶‡˜›}Ä×b&æË>"ÆìOo¶=¹x,”ŸªÍĘBâ¹™1K媫€K’RTš Ž)œ$ÄŸùî@b{ˆÀ2A „Xög†ë¤g´Z†;`S6­?©—.®u= I º8MŵÇŘïBO‚Á‹˜ãJÜÖÝå:„Ah„"ÊoN|˜:hqo*$•rШpâAX‚ÓÅóh@¸ò{©[Ößrµ¬½z‹8B!Á^C²+£ÿ ċyR½•oñ z¼ÅæÇš›Ä^‹5`RTs½#¸pF.ž:$Ã=ðÀ%š«·ËÚMŸ—¦5W‰3îiDâk È 1\Š æÍy!…Vÿ±)<X€ãl6°Gs ‡”ÖÇ=’ XóB3P±oUä%žT¸d*ÃVÞ`dŒë@µ¿èQ£ªðõ™y#P¡`ÛîëåË÷ß#ím­ðPm²ßò.ZŸ Xñ̇PÐѱN\*ÌÒŠ‡I7p0Þ((ó…ʶ²²R˜R£Œªª*aZ(!YA—‘º«ÜpÊt”¤‚µ[®’ë¿úw™˺obì‚&dEI Ðh4€F`À°UÞ@zé<SQI°.«ÄTPÏ>–ë´XoV kÉÊ’ÿ>?B¢PÑÝÓŒ‚›Û’…ùR!Î4Ôƒtéc¤ÛîDªGJê¨p éÖ¼™ ]±[ ÷›ueÛ)˜Ç»H»îBڄĺ¼‚ô*ëÄãM"¾¦•.ì9‚ô6öü݇D²C.çŸÁq‡¸žJï$1°Þ™$ß>b}ØGû‘XÎR¦ºÑByíZÄ.# KHÓlà,!!â1¤³Hw#Õ!iÑ,1Ó!—t ÖIÿd… $8pIt¶ˆ´6ƒOÅëܼ—²m ñÅõ„. .׸¸èÊ`íÙˆk¥Â0ñÊDZóò“nÊña‡ƒ•ç‚ »Ì9OHH‘ʈG|W"ãÇ ãl¡YúLãÚÞYÚ…,H ¥`ZFÏ®Âc¥ŠKQ†ÖäNÆ•‡ñ%Ú(UëÚ$씿„*ˆ|25؇4!þ±) ‚ðj+ZèU4ê¶´KÓÎMR·µ¡C\ @à^bŽÅdEð¬qž8-ññŸ,[BÍÓÂÉ6±×ì2j|àšÊå„ îãÊÅ3G x „„'(€PPßv“´ny@êZ®;½ø'•7 fª¡®q> Ì–ǰ ¬©¤kP fÏŸô`Êk}8§ŒtsIŠl2nÊ·ŒpËX¾Þ™B ßÿÎÃRQNF­€F ó'\‘*átpèíK€€AKº.R#° KD»Û#¥5)óhp8N“*-éà{Pº5Štçèí@fôu•½W# XaPIþÒï¨D†þ)'IZCÎéxê–¨_N¡cÎù|èÅäëI…þ‘Ö#Qñ}‰í é`i¾Ì“Ø0A7>㲟$‚·HŠà1¹ I ÌFµjÅž¿óÁä žŸä“?óe‘˜Á”‹ÔÔ \B¼ ¸æÝ†Bo¯¡Œœ½—}Óô Ûõ$M,Z– ¿GÎŽÔJßD¥Db6¥CÏ·.U0¶]·_”aúŒf.ßœêx\à1^pHð(ƒ¸ÖXÐÍ2Èv\Ït}~™Váô4 Ž“‰ÈK‘ ðI¥.'5¾”â»ÅTšŠR³9*4ާXFÔ×+QXŸG 4^Öè ׋½jP„q˜m_D¬òî„l°—:a\ŽùÊ_ö9½TunH0‚Ma|"ü2ÝwQ¼}™žï@P^x;È÷~£Bê?köl–ö›wKYSƒØN`Ⱥ$”ÛÆUxì¸D†>˜c{±¼W¤nBÚ­¶ò6qÔì«§ —I'‰‰Â#<3ÕõA…y(('³ÇÅç#  0Ð×n¸[:v]*ê6ßx•8½0¿dRÊŒ“”ıÀ± Ã!5 ií¯¾'úEk£É*,çɼýÆïiˈòÁ317¨3 û“± †^@ÓFxüäw-‹‚À¡c§åç>*ÇŽa‰.«²Ë¶]× Û¶n”>†Àb#Ð "A7BLÜަ°ÊÍ¡B p8¹~HƲòžÐæpêÒBEa §Üž„¡€õGh¸w´‰¥[¹RvZØSɨp†ŽnÃã¡îˆQN·ÿ ŸP„Z%hÉ!IÙCÌwQÊCèò\ ‹@%ɱŒˆ¿GbãG%:Ñ iº¹™¿RU ˆH$°Um|f,Ðã´Î^d¬ŠÙvŒE@˜™iú¾¢±Jvî„〸"À¿ø†FÅÛ;òAD¦‡ÇBa^¦qLŽŠ@›ë%Òvý&iÜÖ!žº è~±Dm5.¦lã*:ü¡D&N€K€1Mý2çÚ[ÅV¹ãÂdä|}Ä-2:|^z»ŽKßùS„‰B¼’ [¾,kÛo“òª±‚P€J€àP r;?¯%Aˆ…ý÷ažÀuË1e-«U×­u·U`¾ Ùˆ¬sŽÀ/á(*ä€rÙ’¥Œ ªè…bž’± ×Àù Œ/ky½ÂÞ"ªÿ<ËÕ§gF€„‚ÇýYþ„‚G–­ Øa72—¢÷jV'“Ó~ù寞•ö½)Ó“|AÍþlTZQ+7#”¼ò@«‚WçÈ)~«õH*>¦:G€F@#PTbxáÁKåé£oãÝ+ ’¸[ÜžŠI*ˆ¢­¾è®(y\0ÌŠi˜PÔ²ê2‹KV%'…¯àF@*ìï’3ÇÞÁuËZ„VªjÒ¤‚U7žtƒ5« OÐÞ7¨”O·A+ÁÖV‘¶6‡"1˜åÜ9#ùéƒ?!t…¿i“ÈÕW‹tvì´FºxQäÀ‘?„™Zä4R†ííÛE®º Ú¹õÐÎaÑ}ʳgáöÖ´GŽ¿ÍÓ©è'!â4«A+~¢eæÉv°=ë liiÀÂ8ÛD«zSþ €9ʶ$k*®wø7£ÐbŸy3+Ê*ÚÝm䟜Ÿ±÷ò¿(æÌzñ;e…Ö/r&×>âÂ,±5ûˆí§e"Ûz@îGÜ–¥,<…ÔÕ}ë€B䆌üR¦°ã±{÷^Ú ·Í ãQºyHÈ>ßA‚SÐýZ4‹…=ôNTÈÙázñ\ö…=GnÂT²ÎùJ¡‡§>Ž:¶+G0ñÇÀÄ‚ky‹×esAè<`ž(Ù kd°$è©`¶pޠ坲”Nn0¾§SQi˜ ¨9†y˜Ä›uv Æ<”(#2ñ 8‡$À=d™Z ;jwнþZ(hqO±:¶±U €U<ê‡ñ>Ê0a[€2ætˆY>íPÌ:ܸg›ÞppesƒÔm^¯¬ç£ðhÅý.0<$“ýC˜˜ßø´„§q¯Å1¤¬ÐC;$ ‰§ºRܵRQ[ "A©”"Ù]v“K¨Fúqû$ïa â² 1®–™Xìq4Þ öÚ=3d“9ULw}à¾?pñ´\C#°â ¡à§?ûWyïÝ×ó"|úÓŸ–æ¦zqØ #Ò®8 uƒŠ‚@Чˆ¢ä«3Ñh4"!À—È(bçEùr‰ƒq¦åÇ.a¸óì=-çÏÂçñMÁÃ$Öd\RY½–?MR[ß"­®‘Š ¸çÌQh1ø È÷¿/RË..îQ‰tæŒÈ~$òüó°lÅ-,å+_¹í6Ã÷7êTŠsá–ă1Xº½óŽÈc‰¼÷ž‘‡YïrhânºIä«_5”ÝP,H ¬ç8ÇQ ? %•Ð/¾(ò¯ÿ*rüø¥Åg   W‚¢Ò ý‘þóp³ÿ‘öv#–Á:’À6`YÇäó!|4Ý/¿,òÔS"§N]^ßt…0¿¿ù‘o~Sð e\âÕš&œŠüøÇ A‘FHxøÖ·Dþò/ëÊs!•ìÛgœÿÁsOÎ¥X—;Œ¾¼ývûËp'žmØG´n9vLäñÇEþô'‡Ù¥‘ ðÝïŠ\w”IPH°Ä6•\{­A® aÃâüôÓ"?ý©1&¸›”-[ôú@вÐL‡\Ò3V‰pU2,ŒPàÀeÕÙ‚aÞŒK —ÿŒ‚w¡+¿PùÇ1×ÄAb `.PÞ pQºÖbžÜ€Ï6(à0'›ŠHÜ,¼Xñ9÷¥!y2憜|¾¹…^úª¾%ÎI”Ù'ï)‰…Q·eln¯Ùˆ@ÂHR´›Í)Vñ¨O"û$:y·×8 µb-Yƒï(«çsÈøÉøÎ¿?Òõ¹Í…Ð HÆ 0º´¬Æ#Õ-õpw‘¬ÛcQš `ÚG(Àqx'°;xßGè>í¨+ÖT?çÐŽðÄi‰’Èd÷²%ØæÀ^¿Gy°°8pßU]`öI–þ=§J÷ÉxWBø\•§Ô·Ý$k;ï’ÚŠõâRžDXn©€ä•-þ¤O¯#>_)¥ÊL\ïÜÎß¼Ÿ›×®Ræs„ã_±«ÔµIýÉT†šW.aqé¤<¿e*C]—,cV;ò,Bž;šP;VúH@¾˜„‚×_{Q¦¼^œžýÞ@÷ÝwŸt¬kÆ+/yjÏ·d}¼F 5xZТÐh.!À—*±r•äÛ˜ñʘë™ú¸ÕŠ@00-Ÿ{KŽ}ü²Œ*%±W‚pæK3¼xÉt:ÝXppcÝ¿Š÷urÕ_”Í»nÛìE› ü“òƋɅÓ`æ<¥¤¬JÜéÜ|}^gЮ‡^•ïý^&A,hLE² Ly§Ã£BXÔ¯é½7}Y¶¢]‹!Ó“ãrôãåà‡ÏËøPª›xzGûeÇUwc= J¢e"$LzGäØWäÔ‘7AÌè‡ÎgkN~x)à8ÕƉîS'îR9º¦Sv^{”ï·`ü@a´Œd|´OÞĘìÙ¤1YÛØ.å•õ²nýîeÔ*]€FàŠC`5îF‚Î>­TCAB2•þ¦’œSÑM…|%$P¾u«á]ÀT†›™RñÜØ(Ò Í TÚÓs¥½Ý8÷Ë_6¾“Œ0û¹“uà¹Lüþ_ÿ«á¹@e€?ÉŸæ6ó“…Ï~Ö¨#­óU°ó4÷ÖÓz\ؼYä–[DžxBäw¿Ëìeç1 qºÏ ³Û@ ¦ç³ŒÙŸôPÀò®¹fîùôR@ìRI¶>b»ØG$;ÐO×Gô\À>!င ö³)ìÖyÑA6a9L³…Ä“Ì`î›Ä—óHàžHY›§éO@!Lø=rv¤V½D¸ƒB<TáY>šRH(Èýu¹*/ò9PFÁØbŠŒ€Ö…ù¿×m;Ü1€ùc«Âë”Çî„R’ A¥D5ñ® bއrÏæºWO(-.Ü3â "ÓŒ‚›@â5â°CI|Ð.«90š’Ø-ÐáÔ%ãd¿È%ŠK¶@GÅÑvÜP±~’ÜŽba¥ècGáâÿÌ 1ŸXÆO£6‰Z°¶zêÅZŠû‘Íü+±Ç‰îÁw¼Ûͧ? i‡­¤LlžR#²êsŽ Ž„…à+Ã_$ú\)«Í÷û,ã*%ùw$”³§öƒ½9”¼9çï´^÷Á>W¡¥ûųGäƒ7ž’‹°¦÷ޤ]ˆ€8ÁäóƒH្ú5ëœTÀHZùï{ëWráÌÇÊC¯uSü¨K!æùÅþd(‚Þ‹'å­.½çË4¬4R¸fBðØÁä›S!&dÞ/nùì·áÚ+2¦ØÎ!¿0>ßuõÍá蹇¸`G Z4À¼ÀÙýH™Öá©1£2?™PÀB±0 åÀúO"û·¢Ñé”Þ<žB÷Þ+rô¨aýOÅýßýÈý÷^f+Ⳍ¿ÜG‚= > ËöXOñÌ|NG‡È#ˆ<ôá®?›R?ù\¶an½Õ DP¹þä“X@Ù1'†=HÕâ5@À3ÏgJu>Ïe©$[c’>ˆG¶>¢²ŸÄƒ0p6É,—Döû¡P¡2ƒÖ4*ægR&ƒ¼%2¡-…B w¢Rº‡ëd2à–0…HC"§àR­«¿9`zZ±ƒÕ8S„JGÜ0|Ç@&X’ÔFx“$$ ¯q*?ÄðËn03ÖËÉ'à;ßCx<ϵá;>Ã^(Ω@‡Â|¹º´§ÂØVµJÔpi_E?ègµCÍçœÓ“bÎÏ´>¬Â£G$2¸Ob>Ü’èPÌÇ•rþÒ±à°X¼Ý— u(’8BÄÙK1Xk@6hKi#ªű̘d s³b)ú£Xí0‹°XâèvŒÕçxGã'qÊ«pÿŸ@AÒK<Ã}Ù,p >koÅøØ&V7î™æØG臬ׯPäÿ®#ïË…îcX#˜<8¯Ù°í+Ò²ë+RVÛ‰±a¹ë° è“8ˆ@3SðL³…c„aèÕùò·)$ˆ¤’Le¨q8Sjª³sÛ–©ŒtíÈ-g}TB(ظm¯|ýkÊ–M¢Cä¶>tÕ!0_BÇãÂkX–wèU‡ªnp1Èð”QŒìuÀrG€–Ê¥µ ŠTÃêÈùO¤yÛ59U;†—¤1ÆÉƒXñrQ^ «4-4Pù{èƒ?Êñï*‹só0zÆð ž}ÜØ[,vE<LJ}¾NSi?‚p¡à”Ô4´ÉuŸú óÔÔŸx çöÀ̈Þ6œ°®¨w„\„ÊîþžOäOÏü¿2Ø®±±a!©º®¡¶Ãø¯FYÔ³ýÓP*õŸE{Î*‹uz1X0qpøƒçäðþd Þ X‡å.Ó ýø%9}â]àiÌ/t—Y‹ˆš†Võ‰• Ñdxà,b‰*ýX‹ ü}üã?ƒ¬Ñ!;¯þì²i* 5$w"´úbHŽªš¦BN×çh4KkC³ŒBëû¦ó CPáNB­Ûç¸)N“k ´p»v‰|æ3F8‚¿À=œnÿs*¶o¾ÙMpäHú³ÚÚD¾÷=C™Nr@¡B%ü–-Fh‡O>yÿýô9§TXñŒ¾>#¥?Ûðtê|*è©€y¤’l}D"ɹö­?õ)‘o4Â6˜Ê ’ ˆ%•>…Ê0ܹsFH‹Ùyð‘ú -…@ ³IïD…œ®o °p¬W;.sx:UQº³y\ ÑÎ…ËJÃØ$S @‘ë? ’,’K:A2Ø€ù¥|~sCRÅ•}øÃ¹ ô¤c–ú«²@o¼è$VÌg^ÌÒ˜pÿ›:.\¹äâu/Ñ€–Ùþ^ à±óa’ðžm†O G›»äˆÊ,µYúݱ¨_"¬e-Ðg»€ËÆe.Ø,Bõ“½WXy^‘° œ;)ýÝ'*¯z~_A„‡³ ¡?/Íë?-¥•­™ ‹€‰.bõ P(¡à+_¾_:;ÖÜ‚IJzàÓ-ÕdD€„‚GÿÇ/¤ôP@BÀB!°ä¤?â9þÓ?ý“jŸ–ÿøÿ¯‰)Ü&ΕRÆ(b‹þó?ÿ³B¢ ‹qÿðÿ€5¹<årÀp¥•Nvá™CûWã!áhÖ~áH Q™÷ó’òmíé¡À‹œ³ãj)ø§âã ÐGÿ Že|ó¦­{SžWð¸rÂZnÏS)óœ³1Œ—îÃ÷a± —ºoìùÿàn÷·ÆïÙm03©ºù¿6{~¯šÕ¢m_¸M´@<«$”–ת¶Ü eøn¸¬·Ã#ôÁÚüýמTáX#Ø6ÀóÀ¨ìûiïÜ+ Mësª(•Ñ­»å¦OÿuNdzëÝÎRäß‘õxZŒõÉ+ø‘ô]<€˜9UõÍrÝ-IÛú½RRZ®wÚ! Å2=ÐK]â×5¶g-§ œEø‡Þúµô?‚P£È&®È$MøóðÄPHùó9‡uîQ„§Ó#­ë÷¨q²¶e+¼'— Ü“ o ‡|=r`ßääÑ7€/,-Ð'c#=rÛZÚwIu-þ–™°Më·\/{Ò#áµRRAm=DZrC lOš¹=ÍéþnÜ+n¿|gÏÄå¿õ/À•ŽÊ R–á™ÚB…5Ól!1`ÇŽüf{ñ|H%·.ÁÜžË'ã$1°NéHÜÿÝïîþë¡ôJ%|'è‡Õíi(Æø¡X'j g ½4@qèqüK!¬S*R@0ˆgÐ`Í{o¡"Ÿç¦"@L`þ!¡€a#RI¶>ʇP`æOÜHÌ w³\â0Ûc…y|®Ÿ,òÑGxÁ{¶ðq[?rÏFEÿ.Ó!—ôŒUJßD•L #80ü;1µ4ã2Å£³é=»µ»Ò²Àµû‡)‚÷íàE°§Ì¡žMð^Ð{…ãx='YGÇè^ï?« ‹Å6ÄbwCé Å<$<ð¶DFæ®@Wg-îGÝ5àP ­¶rŒ{R‚PÜÃź1¡ÑU|!ðèZžÖâ†x Õ4R&¬â ÿ0vPÂÀ#¡ƒ˜*T¸óÝ( ktÜòL™ ŸÀÐdÉXpy_ëzû:ÁÖˆMì+Î-¬Ùúû/2Ôkôa /…ãP?ôZΤZy—!ÿ [oœÉ>ÛÖ“çe“ÜÑÓEÿ9„0 ¥ˆ{ççÿN•ç)©H“Eõï„R<€u·â߆ýxI?òÑKò>Â1Œ#Ü­ý鑤º®Uv\}7žEãòú ¦©ÛÒof]ÝˆëØ´n›\uÃdýÆkà N\œ{.“8íë¤áZRâô±·Ô^z, )a°÷“eI*°B‘TUÝ”ç˜Ä"Hbó2ôÔذH–ë½ÃÌaâuó›ñ ^šÀŠB€cz)Ó«øTXÓ½þl¡âžbZ¿Sñ½¿Èë¸vPžÜy§aéγeýzQ®ø†Ií¦ÒýwD>ø@¤÷KZ×Ó ªû" çôxJ¨ÿÒ— BA#³ehÈ})t½Tàâ÷,!¡€ž R)âóé#†à{6ûh ‹ë7Ü rûíFXƒYEª~%Î$¬›¤zxì1ƒ@\yþwăäóYÏ×^3Rr9.ˆ}â]?ùõMOsöë ˜ð{äâX• x+Åvà2ÂØÍSªpY¯[cL…*ܦF-@€ï×Q,lG1·D0Ïù?ó®§ÊJ$[)J›„<£+q`žàüÀ¹„ L¤ðÐ9$ñÃ9,–-Þ_ÓÝRÒ)k#0ÆPm˜ÕŽ95Â;«j7ï5hªÌ¼æ¢í©îq8$6Õ#±‘ÃÐwfÊPÖBH4)|BbÝD ¬Ýè“$¢”ÓîSh3 6ºôŸQV§o‡"dèó9MÊ+x\ÀÉL1Áw*à]õbw\Œ©8ÂB{.1ÿˆDýT¤Ã›a‰*öòô @xWÏYû} É©Cï!Dá'¸åNâ4Œ•¤¾í&éÜóM!±ÀáâóJ†,`½ q\¿3{mÎÔD)†¨ÁŸ„AxS5Þy²Rȧ^Taò-ãp&oæ_¨dhG< wHh…$NuÍ¢Öx ­Êj;O V[ëö.&Ü#žþõïäý÷Þ„gÖÜ Ÿûìݲcë&í¡`1;k—U|mÆ*S7]#p%"@Ûê )•QK¹ÔÄ'á2,ïuÈ ëkÓ ââóŽË'þEN¼úêÝUZ!{¾ð-–S,Œ^‰ è:/$\ó©eóŽ[eMË©€;{ZðÏ, ¸Üpá×¹Gn¼ýëò»§þoõBÈ㨠ï½plÎ)é6¨gäGEu1…^èàèÁWQ§ zA/«j»îÿßѾ[Ä F|zA}àAÁåI¡ˆHRÎ{àÄ¡WU(žTRV%Ûö|Fvî½[ª@âè>ýQÎy-Åeuróg¾!QôuUm3ép²€Ð䔵­[e÷5÷H÷©pޱ: údxè‚l^Šd)“!6¸øUì1™¥X½[# XíP/ΔIOA…2ÝTÔÏ–dEÈÙ³†²ùÙg ‹z.†ÓªŸ ·Ÿþôì3¡8NÒsa—d‚ŸþÔø¤5?÷SÿŸÿ³HgçÜóYx´K)ô‚@Bë¹õ2¡G‚ßÿ^ä¿ý7C1®¬<’Žèê2Êþû¿OM¤ I!Á‚Yp;Ë4IIÙ*/$dóüTÇTÀ”Jrí£‹E\ä7¿1 Äâµ×ð %ß×¾–*g<0àÙ…ÉG^}UäÝw œH¤¸ûnsï¥O÷ç?‹üìg—¶ñÇÃfÐsC*áíYjÑ ÁÉ é®¯Æ*QXZ@(hÀ4ØÒ îM 8?†Qo±ª·‚òÁ<ƒÂŽaÕè-pÆ{A›á½€aàj?›Ø+÷–òQæË”Œem£R}‘-Îg×Õ´@·UmŠքDžÙÇãwxâ48ïIl:CÆu1Jœ•G:¢ <ðÞÂð ±êÍâp\ ëu—‰XH‚p >´¤w÷«§IlÑ Oô²À{ˆSjŒÅ£P°0Ô  Éc|Ááƒz¼à#†ù˜áh¸Vìµ{@¸Ù‚^7¨$ÏE äMy¥ëð{r¡ë¸òÐXˆwµñÚïÊÚwIYU;ÖP-EB@  h]̪D€„‚§ž~V>ØGBÁ$0À3W)­¨‘›Ænó¦ šP+½»xdÒ/^Y)srA ùƒü@í³c±ª‚–*E–•RF%,fL¬Ø¦òT–@óÄn¥•1E®þð‡óDeeŸ^‰ÅÉüÁ‘èÐ9ôjø@IDATïÿøÆ¥Ü/oœ”ŽÚrYWë‘JSl°Ð˜!~üàtwÿ;<ÈöJ.Ôð¹ý3_‘ÎëR,"' Ëe\Ñ›A?ÜÒ^G³ a*ºÍUóT‡3Á~$òÌ3"ƒƒXçH,tÐãÀ‰©If>\™ñEÁùA(P %‰t“öljRÏcš-ô&p×]"×]—Z¹OòÝüL¥Ø&¡áµ× ëýT䆀w¸”BBS*!¡ )À<¾Ðósé£ãÇE~üc‘_ýÊè#Ó’¹ÿþËÉfH8 ùÀö-IL$XðÝ3™\bǰgÎ Ù°¹%û'-¿ -·Z4óE ³IïD…œ©¡€a² s-ÐŒK¾£51Ô }ê|«¶"·ƒtõ/†{CœØÂºÜj¡iæúÖgX„¼ „qOðá>àÀÜèÙ]+Øö 㑞¤³Ä³½Rö"$MøíåU ßìJ_E.ˆÄ&{¡§ÅM·öðd B)䡞ð¶ò6q®ù\¿·@a «xî?´¨§¤lZFwðô¼Œ, [\dLZ{ÏXGÇ$ƒy%,¿ÃƒïHdá@¨€\±,þhpm䨿ElU[ÑF“p8·Ðj«j[FP ƒUîe ìåèÜ`ØžF±…A4€5Æ€³áÑ°ǰÞhٮƘE¡8œ X%µ(îÊ*RRŽP|ðâ`/"߉üI(ȵϣôº8 σqÂi P¶ù •G§;\²~Ï_ɺm_wYªF\{Ê»€ ×ê• XËq£¥÷ˆ%‰%õázÅzŸá¬ðh!‰cÒŠñJ&1Fº ~unã!Æð‰E*ÃêÆ¼P„µœLí°¨p ˜½@>1  œ{r[aPÍÖR P¡`ËŽkäË_ºOÖ·é) Õ›43N(¸I::Ö‰Û…ùN‹F`‘Xr‰7ß|óLsÉ–,3[ç÷e¥”ᆅÎBcµÒʘßàYg³ÏoºùSˆs¿WjKÝòúÿø/25Ò/ÓA™òGäÌ ~ºÞÆZ™"1ñ…ú°¶…‹5l¹ý‹rýCÿ‡Ð[A:I7®ø5ˆé—_~kœ‡zvTþiÙˆòbrV&?Ãbð­pO»eË–tÙ/ûíaXO ž‡’s@&ÆûÅ? 2b×WÂDÓF©kl›·‚<ŒÐ1}½'dðâ)¸Ðó*ët*f«ëÖI9Üÿ³ÿòôJóþž3p£QüÓÊe¿§´JåYeܸW ¹Š59ÌA¶“PiB%Ô5´Í øâ„Â<„OZ ölÏo‹óÞñ!ùäðë39]¥²ëºÏËq’…ßÌÞÅýRЉ{6€õì@èz'p¨øX€µF±%Ž…ŠiŒ„©˜@¸?ÆÉ ô@¯$…pœ”•Ãô+'Éw°Z„DŽ,i‚,à ÀüUðg‹=½§¤¿÷´§½XX±‚üX/µ¸¶Ö4o‚neÉ£2¶ž=8VGG.¢oú$€¾¡‡ŒÊê5*ÄûF‹F@#°J ¾7›ÎwíZÃ¥:H¨(ÿ÷ùå/AP€²'YHH& $ï3¿ô‘È£Š¼ñÜfcñ>YèE`¶'s?óeØ‚ÙB2Ág>c„O˜½®û©Të­Ô„óxŠ!•PP©€8e#ëT¤<ç¨ÐéÎÏÖG|÷yâ #ÍÛ@Ò1fxƒdfÛÓáÌýÙHÙ<3˜e˜ŸÕø½…@§E#0¦C.é«”¾‰*™ ºðªïs¤Qú¦u"ÍÐ…—R·¶¼ïæW^çF­.•ÉtÄ)þ(1‹Ä x¤¢5‚¹Ê¥s¹3$n8BRbó‰%R÷†&d¸A÷z¤x†Æû¢Ù5xw ’’ïux²³8ðþD%;kÇ9bu¯Å9Û1 "(~¡ô…kûXhÛàž=ˆôÁ o(LÕIEøã¨»JÙM¡Àžð£Ü§›dvÔ2U;¨ U Xîçwó=Ä<•û™r+ÏXòðÌzთ{ ËLÌðöÚ݆G³áIíP!I¨0e°šoúc™ŠúT "í sàÙ"Œñ…·d¸Š±`Z,Sv„òpF1Ø<ÐÏ—€/R†! /y$Z¨9}¬ˆ&ì·ú냽ä왣ˆF4Ý<<)$ƺªPŽæ uëý²fýâ.á{ÊFH÷u´CM^X«Qa7¸÷²µ‰¤±Hï~!\«$ ”©ÄAánx´ð·’¤ã‹\Qžy$Š+ä£v,Ãk­¦/Å9… ¶íºNþêë_•¦†p;ŠÐçKÑp]¦F`˜/¡ÀåÔ¯‹ÐMºˆ$–ň["ARÕW]ÆlDÒÿ^IX-F[Ò#yåìqÂó…ÓåTOEµ|ð«ɹƒo‹?UivK,x¬¨o–«ø–ì¸ë!©lÂ*L™Ý!(Áß~ûmùío‹µÜ¡W  ÁK ö}a«<÷ÜsÙ»_j|ðA¬.½Ò6KSgvS±zöôÇrà½ßÊÐÀ9$ ÂólFvåºÝSRRA;bÝN6m¿D°šÉ$˺ˆï‚Û÷ýïþ‡ŒÂ‚?@ r;¬*œn^6Ëà`³|ê–ܹHÖ|g»?†Òü  >ß ??ÞW#È;Eª/Ö.q`¡¤¬R6í¸ õ{¥´ƒEÆ‘§‹{SÔk;ÆŸ©$7·/æg w†˜ò ;ˆkÛ¶ÉšÖÍ R †Zðz‡e|¸G½ä×Ö¶@Y „4Â>ÙyÕgÔ‹ºÛC+™…N`¹Ø}æ9}ôì?ƒq2)!xˆÒÝ$,1l°æ°£ïèq¢¡!6ï¾C¶íþŒx0&‹-Tž3ìƒ),·¬‹— ‰+]'÷É}±á‹Ê#Ç>Ç£ãÞ…64µl•«®¿_Öuî.°”…;óÀ'Gߒü ¾éQ\¿‚|ƒBÉŠë—×O)¬XšÛvÊv„Åh^wå’¶E³F`!@£AAfõTNÑM(hÁþ "¿þõ\B÷3<ž'Ó •Ýxæ“W^™K(àI<7ÝùTŽÏ¶‚Ç=F®½Vd7æàTÌÉ÷Þ3Ê¢•}&1-ñSÃ2ÒÞÓ)÷ñ|«H³ë›œ?U©¤§õÿla( ¨øO%™úˆ¤öÑÓO£¿Ùá)„íI…3Ïå9,?•¤k/ÍÅ3Ãì<Û±)Ig_Z4y!0á÷Èű*ðVâ½ÑQ¡À±Î‘ÖfLc|ÍÔ:ñEÒÏÞP‰L×pÌïÀIy+À=…·Œì~<ó[„£¤Ô”JgDƒˆ½R‹ïæ©J6bN]gd”ÈOé÷Ô 6SÌùVñTj«)ï 1Û”X5b‹·ƒˆòˆ²¾†k{ ¢þ~Ü£&ð^ ² T$ƒÄ’^W”ã®…Ð*ÛQ½C¬[PN9êa’T¥ÒÌU¨x¶v¨F]þ'æƒ ~ïI‰LuÃ9ïQÌdyIrø ê3ý’\Í™jÏ|Á^ôXÊyÇð°ädgöyrÞæ÷™¬g¾§ Xò[,bA˜±–À¡H-Wô,A² ´òÔK…«ãXP pxÓ€">Ž÷]E~1Û’©<ïa§Ž|’úY™I=6³æe62·Ïú¶›¤sÏ7…ć‹ïÓfÁøŠ:+’‚Ŭ”™gÒ1æ&õ‰ãçðŒËºü×ÌiE-c&×y~) ó,qµž^(¡à{| !…eäàÉ)Z49(BÁ¯ y`x(Є‚9ê ‹€À² ,B;u@V,pŸV!7Ü%ÕkÛåâÑ}ÒýÑë2pê€LÑ* (žÊ©ié”–]7Èúkï’ÚöR —êùJ ?þñóú¬›ö¥y¸¤{Å8”©^¾MbsëÉÃòÈ#HYYñ•’ù¶!ÛñAÿ”¼óÚrlÿK2ëíH"ÖûìóÆGzd¨¿KF¡¸,¯¬ƒ¢2GÅ4ÞŸ|°çÕ—^Fð¡ÜH^^_ ûºeÒ;(·Üý(·^~@Ò/Z¶¢>o½ôs¹ØuçŒÀ~ ËÀ¤sø> / çÎìq/ ë¶'íÿWÖ) õ†!V¼ÜÓÒz)-Ä©ÀűÄ=vl±‚$‹b ‰Ï•—ŸûïÊÃ]h66oD_~[Öt¤,ΊE1wIñ fa$9ôõœ”÷^}BzÏ“©É(­Ó(?' tƒxÐ…Ø‘å†;þ a06˜ÙÍû“$šI.¦Lq¢Oªë°:œ·Äel¤Wö½ù+j^•qZ’¤º®À_ºï#ýrÓ-¶ÞwI qX‡A.úàí_É©ÃoA7ÔŸváj¡"á]¢çüaÙsÝýŠdÓÖ Ñ-:OÀÒ#À[9uÌÐw§^ÿT§ À“èe€!ΞMC0¥<ÏÉK/ç§SZ×€,W›† FBC-$K ´€›6Á¬˜DÔYB…þ¾}"]]³v¤øI3é¼ÎàyuŽGfÁ0$¤zÄó‚e-”ôé„måù©”û$0³Ù’­@ÂU}”®Ý$~ãT˜Ñó1NWïtd.›už]ßt¿ÁÕt¬Ow€Þ®ÈŽÀ¨¯Tº†jetº\BP â¡ ÓG;„‚4º´ìµY9G K¥gªBFC¥Š9”ëwÎF© ‰ èªà ÁDÄ-C©ˆ®ÅG¥²ä°”•¬á8Þcìx_¡›vS©Œ÷eÉO×ëTä’XNe.¼XAR¾kñX*„ϬGµÐêÜpËΊÆ/¹¶ÂÓ¯y•kûpÜ)Á¸$ æ,“’êåÝY]‡¢JAb€’ÙŠrXf© O 3.äYº…gQ¬‡ Ç Dèµ#C;¢þ>„;øuÄ}Þ Ì÷IuÞ2ùc¯BHŠšÝb/mEÓlð¤)û g,VFŸ/bIãŠ}na?"©Ð‰1šWŸã>šš®#Ê…³'•‘F!Þ 8,6^û]ijû””¸ëÄ ò;¯‹×® Æžž -xT^8½×ÅÆõ‡G}·z*$ޱÌ& y Æ<öÄC0$áú¼5Xá pAËPÄ U‚ÿdl‡ S‰P- ‹XÜðÞ€>4¼0¤šÍ ®Âª8±BAÖ‰7oÛ)½#r¡wÞ,áaFy÷¸×ôJñ,ʃÎRpJñ ëA–ÆÉ„a”.#>îk¬.G„Üéå9®Þ{ç]ùxÿ;0”âÚ7*2K)ŒÌn¾Q 2£¤÷.4šT°Ðëü5WvÄaoèÜ!•k;¤ãÚ;$èP q²JébÜQR*%P~—€``) Z–nû°Ðûä“OÊ^s¾|‘Pðúë¯+BÁßþíߪ Ùz ‡LñNyS>|ë×3ÖÓôLP¿f½Ô•¿nèüÓãP^ö@ÑÚ ã¿ RPòwN¤àAEîË¿ÿïrüÐ+âc|;ü.x  4„—M G‚x¡:}ì]2àKý!tAj+÷ÿÿ;9úñË8ÖPóQÝŽÍr¼”Ãò›VΓCp©>¨ÊˆáÅ` ¿ÏÖ*6yàoþYœ Wû,^‚ʇ€Í”·¦XcM )—¶Ì£ö“Jì„„0ņ÷ÆæNógQ?ƒþi9ß}@ÎwÀ¢c—²?§ä|ç´¤‚¢V EfTàxÿ÷rž,ÂXx ð¥Î‰q]^Ù øjµ áElGŽ•0¼\ÐÊŸî÷OzFŸ¹ë‹ÿky,AÆGúäà¾çTÌΆy©ª¶UÚ:¯Ê+w¾ä÷Ÿ“ןÿ™œ<ö¦ ÷¡òØsqáÖWþĵÆëŠ!8.œùXÞÄõ†ÅÊÖÝ·çU^±&Ù£çüqyå¹IÿÅ“* …Y­lÜðŠârÃ…-æ^ß1Ì#~¿W.vƸ²JSë„t€™€F`å!@ÎI™Ö(ª°àJE·ÇXp¾ *Žß_„Öÿé”Î$#ðüTB%û»ïŠtw§Úklãù©,÷¹7•Òº÷Ý ¨ÍZTT™<)ˆ«…fÐÈ;Ó_¶7U›yC.¤ »Àz²­©ˆX©ê:»üÖV˜E#¥ª;ÏOJ [‘HAœÓõIÄ9ßz“tÁöRó:[NõMçYaöñüÍ[ͤ|îÖ¢Ȇ@ïD%õ2p#<”ºHM…Èz\†õu†®z _- ¨ýœÒ㫳S52õÿ³÷ÞQr]×™ï®Ø9'äœA’ æ R4E…±‚-ÉÖ8Œ­Ië­§Y³Ö„÷‡Ö¿ðÇ[ofͼ™ñØó<3òxüœd˲dII1ˆ9‰ °Ñè€Î9U÷û}§êVWWWUwWwÝàÝÀíªºuî ûœ{뜳¿ý퉧Wýdhí1Ót“»ìý92#Ð €Á?Ò3Ž«ÕJ Àª*¬†ùn½×]&NΠ)#½Œ¥ñÂ9¯õeò7lºFqk ÂA1´?ÝQÛÇøàKÀ@:9Ög¤°¢©¦MžèaÊ DɨꞋ䛩 å´ ]¨NÌ¡Ýó›5‚0ˆk%^/|§pÈa6µã­¯(8‰ÑCïTàYn/ë·‘ú{,\s˜ð5¨Ožù*ÒÚá:%[,‘®V} ÜîÖ«Ö|ñ¤µ4_tëÆ|‘‚rÛvç7lÓÞ/X”0S$ V@@0Ž­ ÄtÃXNŠ@1ž(ÄAb½ng,¿«€tt8qs‘ÄØeŸÃF™ûðº¬eÀü¨ûs±’»ÌO˜¿NM–*PYÒ•oY¨Îó¨ …Ä|ý¥ŸØ[¯ ôG€õwòù¯…‘ 3ýDŸ®]LÏÑ´ôúV9¥‹_FºF|]Í%<ÚVè¸êî]Ô…Ì0èÓº¶„ðÆÜ¿mݺÉ|†‚4åøoªü_Ô›ªn¿0_«DLÒDï­ÃpZ[JãÀŸþéŸÎPZ¶X ^zé%;|ø0Œ·÷¤~µrÞ3óíïï¶Ÿ¿ø$  °¸Ìzò7ðf¾£ @Œï“"G0ìuá4À€kx|̈y—½I2ж]?gm-PΈ”ØžƒØþß‚ò½ÚW;È÷8†Öf£ÉJ@ƒ ŽgN¼h÷>ü•Œ™+ß@28 ±nó~Û¹ïA۸堕¸0B¿ 410 Ãòì4ùMAá7Ah‡Ë”uÖ„C÷|&cþ =©:‹`0aÈÕõ¿ÛöÜ7ï¬ÔvéºW Ri£ô_B˜¢¢ %™¦š9²§GÙ\‘—·'¸TT±Ùž•Ñ?ÐíÀ£#€3X@°É¥¾)%†ýB¼Á¥ƒAò @¢ö(|† ÷J$èÄ^¯bØÀøØ±÷~[ FcQá*´Î“¡½»ëãäoíâÙ7Ý8-ÿ%Âu||æMÆì£‹k}ÑSÀ±7¿gŸÃØ•ÒòZÛ{øqBDdñxõ¦½ª¾òÚofY+PNqi%u|Üví{ÈqÆÑû¶&k<ÿŽP1Ix»vù¤ë¯iÿ>ÆAƒKZ9Zðê~éénCG“l½²AY £ °<£­'-‹Œ»W¼ùòÿ°+t/KŠí>ð¸íØÿ€U — †!!ÄHrþäkö1ý"ЇXz©*ȨZÿ¤¯Õ¯ìT«%2ëȰQgÍÍf'Of{àåé]ï}N}=}:näW…L" h6–ylÈhnÜ߉eZG&x!€!õ±èÈ$*3SøµUõÍ$¹@^ú={Ìöîõ>Í|U[•G&ñtœ©%f~aéZS³Õ[åêÈ$b7Ðu™BA¨®:øm›—HÕrìçXàl^ùû‰nk LL†ìz/†ïŽ:ëªÜÅ6_x“×$ضɬ<á(¿ðn¿+Î÷ÕZËP… NF"qs.Õ-š ¶aììPKX/síýÃ8) ¶¯Ý× ™§–EŠ­àqii•ó¬+ƒ€gðÏX!ž=ÞóÇ{ ÉãœC‹ âq®‡Ž<¼§˜ËØè<¼£Å|Éo'ó-Ã¥'qÆôúR´xݦbÃ6Ñöž·ÇëŸß´tËšËëÖþQ¨‰HÃQ W@gÜ2LOÎhÇÌfk{†þpfK¯/§uu[” ¤­¹Ñ.ù Î&ÉÜ'@ÂlL°fÛVXRk“iŘýÁäw)-HªDgT×M§äÞ͇lé5foFK(pÊÑ·B[Àœœ®²Þ«.'ÿO ä (PVãÜímÌM}ñ5àk`É4 @Ág?û«©ªdîä?Ô–L±~FyiÀä¥6ÿ"_¾òр¼…—Û… ò¹Ü-ÆÄXðƒüÀî¾ûn‡RÍ+£e¼h’…KW{“ur@¢Øå2JÞýÀˆ%Ï=UX´‰½`ýæ½xtw:ZûÔ¯³½×‚pt„Mþ• ðÈS¿‰ñÿØ@k7ì±Ú†­ö³ýž]¾ðž[GɨþÑûÏÙAŒþ…€Ò% £¢²¿ãЧlãöÃÎ0[„‡³£ÒK¹` £eYY½+œýðe—ÿ ݓǺd ‚1ŒÖçO½žX8Ç÷l¢„>ع÷”šä~+VËŽÛ_ü—Æú˜½’³Aa£)P¢¼†ÊzgßN¾tKÔ¿ý êQÔQh ÇE®Â,Ð'Úü؆gþxå„@Ň¡Þ«¬ZgÛ Êß$S¤—-6pZX¡³e¸¿U"FN"´gßÁ'lý–ý°Ô<Á `†¡cÊÖn‡v   øF ÿ»}¯ÏŸ~-OP4’,PeonúÐN2ž[›Ï'™9ʘdßõàÀff]æÖ–X7ãG-÷åƒO|ݶí>êî±QˆÉ`÷ÕÚ^ å}À º×&h›ú^í»óèçæ,Hãú܇¯:6P4&u…éS¹ÊÊë'¬± [ï€mánÎÏ=U…¦òÒù·Ýøóe€Ž<ôe;tï³äY3=f¨ózîóÍ€Avî»ßÞyõ»nƒµ{Ë_¾nS xL¹š—ËP.P€@ €[Æl²¬u®UÙ¤ª*hÈ@,2Z§–á·Z÷™Â%(@Ù äéuP½×¯O?ÿ¬p ½.ÙÚªtž‘=ýï³B'8`¶y³wfú•糫·òÈ$sõ‘ØRõ”ž‡ê­<2I.PfÈtê:_]Ót{‚ãS³§¡™r÷ÏùHj w¸È®÷TX{¹õæ(c;^›”ÉnšbKNô {3PãRµ5UÚHlî9çR©Ç x\ƒ0Hfý̇»Xû°!| @·b +a~\Ž'v¡Øóx_í»Øë$Á0ÞÖ°Ä?L{h»0 ð\uìòPf"º÷À¾’7¹va•âX8¯t!ÐÌGÔÙ+#6Òj±gm¢ç,ùPM·×w…ü ¯µPå> •í¢Þz8Ç Z‡zí¸ºZõeh,²Gsîä;¬óÁBŠf;?FŠÚuwÛÆŸ¶ÚM±Æ1©õ Œ€2”ë=ý#ѾÌÔcË•…7{7žG~¶½€˜8€c Œ÷í¤ØÇë>! pÆýM*Õ—¨¿«\žrµ#ˆ®Üý/VøÀ…ȳ¬Oâeô‡ÿÍNŸú‡ˆ, àO¢Rü6û¸Eðöíµ®®ö!óû}¹EÕ÷‹½ 5póV ·¡òü&­^ t7ô[ßúVÞ …&Yl¾^žË¿WÎÍ~U…v6hóã'Ýœ?ޮᑵQÔ±+LdNo„èë\¢-‘²ª{úÿgÛ±û~<áS ‚ä+Ãï<Çï}øËvÏe!Îeïîh† ïr6´ÓD´ôwaÝ{ð1+  V…l`#G€ˆ#~ÉÎêAùˀ߅»(¥´´Ñ¼•xïçO‘wBÂèjËλ©[½w*ë+*p"¯€Á¡¼á]à¾Fߢà°>…G·XÞ÷9Ûº#;`E†eQ¹y"õÚýüßüBƒ à>¶ðÒx¯*SðëWNc?i÷ »µw{_g|-ø Zú"¼æE½/ƒw)}³iëÁŒéoÆI1.ÜûЗˆ­ ³@,JŸ ¨ràî§­p‹Æ‰Œê½×'“9Yä…¡ð ïüü/Ë„úR¬b®‡ÿÐ`/`œ§1X¬œsð®_pìÅ%Ðxç!êÏÚµÛìñÏüCÛ¶ëÈŒ{@÷g”{¢aí»ëþÏlhÁˆÿ¦+e ¯“#¯Ûþ»žÆ‘33àÓ˜Òߣ‰¬|Ó¢ñ‘D]ˆˆS¼`›·²€€6l>À>[bPO_’|§0§O¼œWˆõd;à•»X¨¿f‰p¯×4lvÌjÏì* ~èƒjò?ø¸m4 £M'‡Ø rI.ƒ³À ¹¡Äìtžì2˜§ `Pwmwwú7ÓŸ=c¹÷ œþ&³‘½˜Ío••)Ö0ay`Å"¾Kj.Ùß˸¿iSæïÍt¤‹ê+PCºh} »ÚœMÄ®°¿Y&q>(![(\}ÄÜ8g©>ÙÀÚ”8 [X²\媽Ù@©:ºžáxŠCÓ¸ì?i|鋯™è*!ÜAu –áä.*å…  =¦{kê°Ë P0ÿe×ÌÊÜFŸnŒ–XË`¹µ–ÚèMdS¡¾“±Igm5Â?Oz¡|¿ÁšZ¡ö8ÐúZ@ƒ Œ†…¬ãJ63÷Ö×N&÷Œ¦zีiâUè÷]ÒÄ@`ÝáÒDpÀdTH|'C«@_å?Ï2Æ{/Ødׇëo"ï!.^y€‚påÀ»-P$ÀzA-n¾¹ººý±¬eеc8Ð4(¸ÚxÚÕóa'ÐÛ¼ëYöq5oEƒÓëJGõ¯±(qã0eìjB g¸G¼Ü•*p[Þ¦ŠtD ŸsÉ„ÿ-«´ÇŸù&žÆ9d¦üåÍ.¯ê5ëvbÌÆ;Bõaƒ¥·§Í6ØY—ˆZ²Ï}ó‘Ôµõ›¬zÊAèÓ%¢ÄìëÂð?¿<²•34Øgo¿üÇÉöÚÜ)«\c÷=ò5Œ«ÚÊ.Óe´AÌ Ù$ÞO“¸GÜ14ØmýPé·]¿`;ùðØgþtR³"µ9 ÆO2sÁ BMŒŸ>UTgÕE:—¨L….èîl¶¡cÝxì·ÚOü*Þð÷ºï3ýѦÙ6@_þ»ÿ»£Ë²‘VW·Éê×ïÊ”ü¦œ“×@'ó•hA¡ÕÔmXSNbTB‡bÃH¢´¼:k6 GÐLhSïý8ûL)Ùø˜HèÓ»P‚ýw}Úî¸ëI«g¬‹5"ÑVƒÀ==ùk.T‰€ ™DžQbÙuàÑ$¨@a*:Ú›¬åê)ØîœuY¶‰’Òjâ¤ÉC)³h|H!Ð……½èÃK«åêÛ{ç“vôѯ»Ôô«Àé¤ÑÜ4ý›VZAØFf f\L˜@ë7ï3aíøâkÀ×Àm¨1-ccwΠٚ'oLŽ3Ê ¹Ù,( ^–:¬Æ™Œü2:ëzžßYe¡žð¥¥7væìdב2Ëœ³b(¸ãŽÌᔇ õé^ø*Wõ-OÙ¨÷ ˜AÌ YÀÇ& ÁC1¼¼+f¾Ê8¯#SÝÛGElà«Å ‘.ª·Ú9ŠA"“d#¨O½:gºNÓ(MŽpÜDZ‡C˜¿„„w¾ø˜S×{+ÔYÿH¡MLæ7x(Ø ]€9/-kÎz¯ô׆#1Pmyëµ(:iÅØ8õÈŸ„€WHÚÈO¯ #Þ(B€õsãTéeív£«ÍÍÅ(f}è ƯœŽ.<à¢u«bšh»*ñÇ £ õc]ç~«ÜÑ qÜ é•)us O+c¼ó]›èøÀ&‡y¾NŽ‘QJ~^¾·ø5RsÀÂu÷`K.uaê2µãfèjÕ—¥«å²]»ð‘µ4_\0„*Þß‘‚rÛvç7lÝÚ»­ HFã#573íƒÄÇá” ñá.šYÙöM¦·Òè`Ü'G÷M+#¿gùtÃïòiǬLüY5:þ²&ò¿ð5àk`95à –S»~Þ‹ÑÀl‹Ébr» ×ÊÓùâÅ‹84bX ²´g¼=–PnV2Š^¾|ÙQoذÁö(¾æмÁE3ï—±„Jõ³Zˆ[[ãsrûž®bþ5| âpî4›ìp”f÷hßtšÔw16Ê[¿“z6þ^ˆð¢Ý³ÏÏ㌼'ªjÙ¤NÈ8ˆñFâ–ß8ò žý[½Ó‹z•QsíúÝPè?‘Pà `Q…Ê®¶~³èœbËÉ«z©DÔü¢V¨@Kg-Lûûn, T còù“¯ºØõ^= 1pσ¿HÌ÷íÞ©¬¯EÅeö©ÏþC»†1VLbq ƒ »±‰Qg¬Â`ÛM\ùÆóïÙ(àÕ}Œ8÷m×.:&‚ ÷wýü¬2f H! €Ž0Fh1lÙu7Fç-PÊà0…G:Þ5°C4žy–‚S®¬âˆ^A¢@ÆzX# rxû–”ÙÖG\¼ÕCÐqê÷oõHÜ3¾Ô±-t»öË?ˆ×Q.P<0¤ï‘G¦6¡K±t´~ «Ã~Â{<Ã8Át"ïý ›ï°Ýw<¸aÇ9‡ˆ d ¡r¤ŽÆm—3‚ ªj×ÙÏþÂ$4.£þ.á•1É&èã}€Ña®¿ré„‘—BEhœ\¿rûÔ¨UU¯w÷|zµFG­ãz#`—øf«6Rk`?Ù´m6¸!ýZ}–WW8’iƒ*SêUrn¬5ó³=[õc½üVüúÌo•‡ýdæ9ÿ“¯Õ¨ýäëЃ*›Tbé•áX†çtý¿ ι@ÙŒÎÊK×ÎåÉ®ëe¨Ï$™®3B6P úÙŒúéùfžx‹w&0Ä•+fÌä@Æ ©­e¾‰¥<Óï°<ý³yû+‹£G;ð<õëS2Ly+=©½™d±}T‡5U:ÎR'W¹J¯ët}ºˆYAõÍʬÀŸåGa¨Í¢¾ø˜§& å¿Þ‹á»£ÎúFò w ¢Ö1ö((‡ -¢Ø浸°Ô*Yo…¢€ 1Çò]ï¨?ALÂãÉÃÛa R'.”‚ˆØúäÑíÞëZ¡TôëÎÇM³±Áfèèû)ƒt ºI)FÆÏ$Ñu[¸ú [&ÍdŒp¤µCužsF‰ô± ºZõeŒY[ók¾p’uàUÇä—  ²a¿mÜû[³í Æ {[Ì»‚0q |7rĤ1Å~…€‡.¬ý"¦;#<ˆX4®=–]4Iˆ<|á}P ¬=%AÖ½“ºnU¬Ù8ruYÌŸÜí`mÌ­©ð'·×"‡Ý»q}.¦\ÿZ_¾| Ü ø€‚›¡e¿Œ|5À,xuIŒIí±cÇìûßÿ¾3Æ?þøãK*¸Ye¼÷Þ{ö£ýãB=õÔSK*cÌ/Csð¸ajut¿¶¹4059 òÿ³ËßN]c¶å÷¡Ãý·œTd_ý ç~c:Mê;Ppù¿¤ž¿°qºó?Í>?32ʈ¯ÿAŒ÷2²ßÀà÷£ïþ_„"øeÛN óè"=‚µ¨—‡q›$sIœ}@;¹qs‚< —Jdä–Õ-¢ÇÆMïÜB^U?^ßxé“FÒ0:Ý´ãN;tß³ìáÏý³%ïþ{ï·„g‰ô †ƒI6G´±3΢\ú]×ì̇¯Ø‡ïýz°îÐsƒ8ónk6ì¶µ3Dí˜*.lß÷€¾çY«Qß³qUPXŒB»çPxRÖØÎ{l瞣vìÍ¿Õà‡îr±:\»ü‘}|úMÛwç©Y¦½ÐްÛKûbÕ| †5!šÃ„¨Ÿ'ÆfêÑûÎ{•^7Aÿ/6×%òÊW؃þNÇ!À†˜ éÅ«¿õÚçÙø¾Ï¡Ó']x /¿¹^Ô(’+쇗‡îÁâ²*kX·Ã t^À’ê“IÄž°ûއ8DºpcÒÍûE“€]Æ¡ÃItÊeB¼È¸ü™Ó‘¨`;¼ÿÆ÷0)œ4ŠnÚ[/&‹°iZ]·fˆ¹ŸÉ‹n·7£—1bò{0_)۸C¿)2ö~’rÂëk`•j@¥¹°„2ëHl\Ïhi.Ot/¡w½÷9õ5—ÁZédœ¨@†úté‡fA׋-!UdäÈG²ùŸŽ¹D†}Ö‘¶woæ”ï¿ovüøìïd\° “¨žƒñß«Y_‹áÑìÞ{3ƒtA&…—‘§ã|ûh¡À ¯ÜššøØÈ®Aak6ÓһN¯`,ìçÂPèðÅ×À<508V`׺+¬¥·ÒúGóˆá~-·ê¶M,$ìÀó¬Áí™l  Æ¥þjkª´‘E„;X[³*¦™b)…∵^b)a)„C›P(lÕx@ƒ±‰M†a! ñÖd2,ÆóX¬Ö2ð€˜ô÷[ósí ‰…NëÁÂHÄÊø²ž.+«±"ÖÔ…ÿe”×£cʳÖrLi­¿= kN±Ò9qé¹ †Ë¾p.Ø`SüÄlÜ&G» ,èr¾ƒ×^~/nÐ 8=\u@Áa ­ To~‡3µÃy±‹!BõtFl} b‰tµjË`O@ÆKgÞ³æOáDÐ 6ƒ:¿@©i8d›ïø’ÕnyˆÈ°øqó„¢ZÇ‘—Œàtè@ƒ)€è¦±ˆ‘<Àø#– ë›Pqe<½ëOÎã25ø‡'AöËèGÈ@A)eП·ªŒñ!Š^<¨ g;Ø/pepŸX»±Žƒ*â ñÿúð5àk`ek`ßþC¶g—ØXApúâk`…i`nëÌ «°ªÓÏS+Ô’a<'úúfÒM/UuoFª»ÚQ„WÐr´CÚOz#›‰•ÚÔÔ´TCÃÏgh ˆYY„Ê‘kӵѮ€]£°¼Ã-¾B,” 6Ç?§ÿ•gê»#Méß°Ëmìœ}AÊrUõöÀãß°çÿæÿaa ];Fhy¥÷áÑüTî»< åýQ@¡T¾¬S©¢P ÙÂ1”aÌ‘á_ùß8£D™<ûlœ5@¬éÒØhöÒKÆ"ý›x؃L¡”R†&$ÒEíûÍß4ûâ³3,ðû6/PAzÞú<Ÿ>š‹MByd/2>”V ÙDvŒ³É!\á}¾ø˜C½ÃEÖÔYcí}å6 1÷[ØüLÙ—pû¯gè®Ç†VÂ2HËÂOºôŒZó`¥µŽ”¡×ü¶ÃÁ)Ø &­Žåv¡²às²wxðóGIciäRAç>ª¶É`% Ì죀 2åCL,èCí’ 2Ç’§J?kÅ.Àb÷Š„®à=ƒÄ ŸPÓ_)ë¶âôz¦Ëøéý©‰z^“âFßÔÌõ>TˆÁC|°›pÜK:ľƒäáŒÂ6áB#Ćùd0Øðçé2 B¥›,TºÝ%›¨_êo_–v¨ªÚžÚ·®ÝjY¨®Vc4{l°ß?zË®_>Ǻ·Ÿ~M›§dPM¦Sk7>h[vée”³é÷þÑ?²ÿüŸÿ³]ºt‰…*“W_V½"xDl­_€aü&·X!î¸ûIè½aï¾ñ—ŽÞ\^]íWð¦n±èÌ¿õ}÷+ý hÔw,_ Y7E„bOÊ”3l'?fy£ú¶\=kN½îèØGGúAßËûCTÿl‚hq†È»@Fä¥{å¹ÿך.¼Ÿ\ô*<À£Ïü´ôû—¢ˆYyˆ ªfƒÝuôsÐÌŸ¶¦óïº4ò¿ ½¼Èg„à7(RªOÙ"x†Ïý צRýšm¶ûÀcT ‚dîína#m8w(‹Y5_'Tïk—OÛEÆÉµ«§`EÆ}Øõ¼õƉΠ.(Ý–fß°éѰ~‡c¤8óÑËöÆÏþÈyökì¶·|ì!ÖlÚck`X ±YHh OÄ6 1¼8ÃýZOh…Ã÷>km-íÚ¥\–#lXµ4ŸA§SŒÉé ±7Œ»Ó“0Eóàxù¯¾| ܞз™IT¦ÛœË‹}.¦bØŠä…_å.]:)\׿k®Áê'£;¿¯³D×êHÑîËK^¡ H %Þ-±Æ¾ë/²‰Éü%“V]:eÕà¶ #s†§öÌ.ÃPŠ€@áEÁ`äùI˜Áž±Bžµ¼êgj’çîóèq€`c€ñÇX‡rpÎâ¡J'=ð„¥I•ËÚdœcÄ^Üdì…OÐ>šÖ a –”.(ŒD­Œy?ÃË’ô 3n¢žÿñPüˆU¯2 »ƒ] ŒÎ<'Ú ®±Pë”I˜ Fø ˆá‰>ÚݘßΉ@°Œr> ~‚RV#5è†;`c¨âžPÝ’­ˆçïÅsµ#ÙãdžÒޏ7}|48ÆïÖM­À|uµÒË`íÞÕrÙ®]IèKŒ.$ùŠº¤9Ù3®Ø·˜‚!2P !чô…B#¸>Q:Qý{ý H]Ì’ºÃ½£ËoqŽeÁ«c¢Nù¼äjG@lšìÂÒGâi¥qëË’j ð¤hI´Gáži%ÈiÇÝ&i÷ŠºEN:ÉþI¹.¦gRZz¿ _W)CÚÕ=®º:ÛœSV¾¿!©ºðßû¸ˆ?ùoEÉy–)Ïóûï¿?ò 4[<Í<ó×e7«Œ‡~ØËS †åh‡À Ÿô2"l,JÇÿâ_ü Œ=PÌ-‘tuuÙïüÎïÌÊ­šM·oûÛ³Î/ôÄrç¿Ðú,Uú6 ^Âóë¹çžË;Ë5¥c¶smϨ¼s_¢ ¹§ËËëíþ'¾nõ4ßó{ÖÜt’9±X  jï¾n½=-М7Yã™7m÷¡Çìȃ_Æ@™ê1°DuI.Ìç—Ÿ@íЯ¿öüX;aú;âæ&ôóËq~©F†ìÿÐN廹ˆÂ;<ðø¯`„ÔmìÌ/§…§’ŠúkÛ®{“ õÕÐ` à^^‰«SB´HŠ*¶aBäm/ú|EFè5kw%“k b‚²Á¾‹ÖNç›L°BßÄhs3`‚·_þÿìFÛ%êczÑL ¿ek}¡1²fÃ.²`л¯}×mXÐvý‚|ÿ¹e¸©¡?XøÆØ \ ‰ƒ]ÖÛ¦-‡’ ‚I6ºdˆ£´|ÚÀ#à†Bix¢kżዯ_¾LS_l–ëgJ^˜26˸Ÿ.š;Ëàœ‹NžìºV^úé’ šNeg3–«ìL þ*èÈ¥òÓåÁ;õ-³ßû½8°@Œ?lßnöwþŽÙW¾B˜+Œý2ö¤Ë©SD>ù‰Yssú7ñÏ2dIH_ÿz\ªÛÁƒfGÆ_FÀÛÔΔ³§«Ló­Åö‘€ÒsF½tñ€jW&ˆBG&Q{¿üe³a~ƒ®\1SDpΈñ?¯ë”õqp>¨ø2K±©Ý(PPg݃„;XàúÅËP!"ºE;xö‚A뵯u» s´v,¯¸Uñz¾¯ÖZ‡Êm0e>aX[`ÍË òVNaTëW^ë9s  ôsÕ0‡B&ÐoDüª^ûag(g%”0šLZ¬˜ù+!0L ƒÁ,dƒ F ï˜õ'bºNôLþØ¢Ìɵ~Б*h@C°ÿ l ðn aÍ*¾Y/VàLPŒ7,*ù„ñ×… H®h³÷ìgÎ>9:䌿Z¸&ŘŒ„Š€çÿÔ䘅h›§XLÁ^0‹Alô†´O›ÅFºù~¦qTa&†÷c¹ÔÏ‘Xò K.ª¨±påN‹”ÃP©˜¾Üïx9*Íj›G;GcöØv+-˜¹Î'¯å¼Æª+êmÿ]Ÿ²µ=¯ãa|æÄ+Ötñtƒ,ö§œqpÃuOO+ Ó&û…/þÓžÏËY¿Ly‹¶ïa~ú½c—¡÷ŒûŠ=Y {-^öÅ„R(*,gÃA _9ñ Û¹_ÆêÆç£ .µÈ˜/F OdÌ/”—ÉIAa± ­áe§1©±ÖÕÙ<T 0©¡>t+äŠ/·^ÚÃëÙ±ëEvº½ÀZ"62°Â褭)°ý £vh͈ՕÌÞ0¹õµ÷kp[h»»äÚ?ÕZDgžÓEó]öÓ6g$ `¡ €Ô T¶ŽL¢²ud’Ó§ÍtdhsSá dà–±^ý s °ëañ;V3û¯ÿ5ÎRa#ÓUC`™D¿5ìØáb-;ö…JHÌ™Ü% ¡‡Cz½UÏlm]l©,õQ¦6çÒ±*,`I6`¶X"ÉÛž=5>P]ÿû³=là‰~þ9è +óNú¯¾Ðó¸`¤ÌÆ56<ž? @ºÔ£j€a7Âô¬•çŸÂ¿2=/STÄpÅÎjÅ©@Gv’ÓB¾:{il2d—ú«­y¨ÒFò w –¯­ŒYö¿bô‚-P’Y]œ ’0ÊsVá,€• cj—çaH ž‰Ú» «Ã˜×:¡ßâ@‹Â½¬~Ø ØO§ŸÅÜ%Vƒq¬è Á6Î3[óß›4豄°“³C¯ÿ0c¸¤¸œG~ :b­蹈µlaX^âi ÅÓ^þq}ºöÊè‰ „L0yV#ÒóÔû¡ Ond]¥ûƒëSC' “Ç'X‡ð¯¯÷I€aØ"‘ …‹Y Ü‘9ÍЧ2œè7‰uûmRýT-×ÉêÓD$’&_æhG2÷fµ—AˆŽk>´KgY_o'êbLªM ”ºÍغíOYý–‡­°¤–«¢gæ"à$À9{0Láú"C¨¬Ïa—ÆHBÀûòz«ËÈ6®Rª8¯·¹Ú‘©Œ<úl^õø'Z·¦žiµÀ1šÎ¯cº X*cö²@IDATíYÓMȲN@¬é í ë¶Ò%Ì#1¨À/Ãו7VVû¸*--Ÿu¯xmó_} ¬ ,ý.ûjhµ_G_¾n‰4Yܺu«}ö³Ÿµ?ù“?YpÂÁIÛ½¾ßž>È&÷j&Ó …°fý.èñ7Ú¦mwZÏ«vÃçé_²¡>&Ö,ldh=òçd×Ù#OÿvÖõþr7y` ËžÿëgMs†bÑþ×Ôoµ{1î¯ß¼ïçR c8 о1±º•×´Â9ä *Ã[ã½×¿‡‡ù_8fµ1Š‡Ã¡ûžµ£ü’•àr3Dm-I£Œ×FÁØhʆ8À¢,…¹@[ òhBw• ó¨j€ES:Í0Ž{âÖVçÜÀ<.¿åI¦`&h²—~ôû NÒöqç±³fÃ^»ûþ¿ck6î²(›ha60œð6A:Z/Y+þåH%AôW^YðekT ¶ vúzÚ­º6‹ÁjúT¿ ãI’0^=¥¥lÚ-‘¸MI6(SE ñq˜-RE`ŽÒ²érR€*Õ—[ªÑ ½~¥Ä~r¾Ô®öD­Ï#±ulš³IRš´×šb¶¾bÜ>µ}ÀžÜ1hEá”MÀ[Z{¿ðÛF8®9PA®y ï‡=5­ç=Ÿz.ý½:2I.C¹ÒËØ¢k2ü~  ë³´3ûÛ¿5Û½;3¨¡ Ëõþýf{÷jW2nPϰi™¬öåËqfÍOa$Ë* -T€.8ƒP}å³>ˆ³$¤ƒ dÜW{3ÉröQ®rUéBlÙDzÖቬºÚäOã ìªs¡8R’{—ù¯Ÿd h&³hhï(†â°œÕóìÌÎ6Š{R†˜Œö€y ñ*gHÙ™R"1Ñm+çlÙu£ {“ØdN«çMÏX¡5VZëH™æ (§¬¾bÒꘊºp|Ψ’€Ð¹‚ŠB(2€‹µ¢ž=¯`)×—[‘ågfÊç¤ÑO4Ú8ï­/¢2«+œ€Îó¼‰á±'”Çsó1¼Ç,Ðn Ê 95(ÌÁøDJ]¼zäùšÊh0œŸÐK¨À0ܹ:»õ2F~¼ÅËŠäà V ð¸Oó(õ9¾˜NѨ˜¼¶ \¡ö9è½ÂäH!1PƒE„N˜Øêt 5O‰Á! ð`rbµj•*6õ‰ô‡ä(Ãyëü¸!q× 7ï¼:Ëõùz[WO¯®·aj;ãéܱWíú峬ùûv)˜¸¢æõwÝ–ÇlëÝ×Êk÷ÀlQ €½w VõQB§z?¥~Öï©×w*±<ƒ…úÃQÌ³ÖæJ®ãÞrï9¯ •3ê˜ Æ’ÙÊËüf¶5YpodÐn»zÞ®^úµú¸Y¬Ù°Çžüü?¶u÷1ÎÙ¸Ê ¢íÏwœdÈ.ã©0uÕÐ=&DÛ2Â/UH/_ïU }ñ1 s2î—”ÇQú^šÅ¼ 0("U‚ÄÒ™;4~JËäé—TÒ·/·Nƒ!ûÞ™ ûñ¹Rk¿8e³•j),ðx,hcAÇ^p½7lW{£öÕƒ=V]”ßFå­k­_òŠÖ€~Öfþ´Í®®g°žýMÜs^Fç\’ízò¯]#˜·\Ô³aÜ}!­é"–Ùµ©žI:øþ÷Íî¸ÃìW~EáL©â›íÎ9ó×î¬ÿé?™ýá殯«Nï¼cöä“f›6åÈ4í«óçÍ~÷w1°áç3¿”Ñ"—q?›Ž•‹®›«üP{ã¡ dyKBP}r"]„ÓJ?éþÄk@¯‰a~ÿzlª~ÊÚû‹¬«/lƒc¡¬·ÿBtæ€<Žd^òdЀ[R`1(m® ÀÐ@¯Jã33Ò½,WÌëÑk쫱žñ"æùÐJ &­ºtʪË€Ö᳚maÞ«W…80ÊSᜒQ/aДq´£ÿ† öãÝÅà^Ä:"ˆG loP»KƒJëe… nÄæ[žÀ°90Ê;C6é9Žñüd#îÅ”@ÚPÿ»ð üvŒÁl0°@`ƒq<ÍG9ÆXË8‚Î-%Ѐ5^ll殟öu³Æ(]ŒvzECVRXb‚µÎ,-a] «ÀÔ8H×vš-–¾„4À<ß{O\ïSõÈljo‚ ÀÎ( ´ÀÕ¥ô–b`žT¸´…”!ïw™é—y:€B¢Ô™/nï2Ä€A‚Æó¦?g£¼Ï‡EÙÎ{¾iv>m%•›ãιãñßʨúa©C¡,¤ƒ3‡Û$R_º~%=cdjˆ5}¨¾–êþÄÏ}"”£p}r¼¬ä2x8uÌGšššìÏþìÏxnâ0Zee{m kˆôTeÕåÜcQB’³¥¼ªÎJqð Ápà÷´É§Xÿ_¾| øð5àk ¡f(¾øð5àkàæi@ÆjQVýê¯þ*ŽMeöãÿ˜Åý´5SMÂxtÞÒkßxä’íÙÀd‹<Ê+×àÑ\C¨»bû«?ú¶õ÷´ÅÃ!@£ºý[*ó!¼òrغënÛ²ãng,]j•Ë8}êƒìµç¿…`Üà @ÁžƒÙ£¿ð[è§ÃK]v¦üb?:ZÙ4OmüTT5¤œ‰¿ QÏêÚIP(ð[®žµ­;ÌJ›~Búíë!&fÂÃ!ÈFO!´”)¬!÷œÙŸÿ¹›‹ ì‰MùlpoXP±ñ0_ûZœò?GryËÙ[oÅ?ý©Ù¯ÿúlf†^Øe¤«tï~/ßÅô‘òÐõÒsºø!=ç~¼Á\Ýî¹Çì©§Òs˜ýù̳“'3ëQcR‡/¾fh€¹Ô‘@¿Õc ÙpYØzG¢60R¸ jC¼…LFÔ%@niÉ öVç@Î{1 i •°kFègŒWØý”ÎÙzI·’€MUŽ¡ ouŒÍùHyá¤ÕVLY÷¨v Sb"#d…P†3xf) c´Âr ³îë´þ¡€Ši²P¯q¶¶@0ƒS‘óìWNQ ©ÍF"²½ß‡ãøŒv© æOÎÔN]’ô$*€v"VŒq–:L’N`ã1 Åc‰Ðuc<ÇÄpÀ!oÆ„ütÖÜ¥äõÁ•79ê®UHOza:»Ø@ót1“…©w1óù ÀÄæÐ^@1 ö¤×y†xã΀,Ðm’!zZxŸmþ¯õgTà® Mú•ný2¦U¨wŒ“ö+ç­­¹ÉÚڛݸÉP)(·mw~Ã6íý‚–bøOí+ÖÓS PÁÏÀd/ê#Nº¨ÿØK˜ìáúXý'Qzžøñ3ÓWj‡^ý§k;ïw£Ì-SCÆê^*à!Dêžèi"è2̹Ha÷T ÓVž3µµsovi¼ðŽW ‹Ü2™ëºä·ø<4n*ð¤€Í¯º5ÛÙ\½µ€ÕgttÐ:Û®xUscW!TÇùˆŒñ-ÍgíÚåÓ.ÜG®kÄ6¡pý½íÉdQ¼Kjê7%?/îÍl}víÊ©d6Ü䪓¥åÓ¬ú2Â*­hH¦SAg[“»vÓÖƒÉóþ›å×À¡ N¶Ø_~ÙÌ*®ôQOœ†z;¸ãˆóUïÎÍwØ>Bâ¼úu{ëäKÖ‰sÛË—JmsÕ¸=»{uƒç–_Ó~ óÒÀ©°™k'·È áŒ)Éôù, ©wß5ë›k¥¤ˆ¿•5M›­òJ'†jR$xûm³'’§2¾‘×%›¶.T#H,-ºþܹŒ—%OÊ(~ü¸ÙïüŽÙ /Ä }7cŒHÙDå LðòËfù—ñrZ[ãžøÙ®I?ßÔdö¯ÿu<Ÿ¯~ÕlýúôL¨›Œëßý®™ÀÒ§@j§g$ÓUÒŸôôÑGÙ7ØÓG^é›âú¬ï¿ÏÉ1HT¶Ò©½<ñDf‰Ò]d~€ç Ës¶F°r£¬/¾fk€û’{3ƒ"^Þñ++$(B,dSA^9x[Ïp± Ç–hxwD*ÐÀ…OàöÅå 0ÉJê‹^lš뱨4ÓÂÙ­]ê3c€-.õWÛµá ™ ~~RW³š2çjKܺo† i:À³5@ÃCb'H>ËRKLšF©DÀu×7Ü 8dÀ…*Ð#xŠp“ÉqmFp-`®ƒD`1¸Ã`Ôÿ §b>sÔïÉ&ª¼Ô2½/ðåç´ Ÿà<÷ãç 06Æðl–—ô$åàƒOÈ 1Œ1Î&`3á'Mà‚8Ð@À{…S˜p19RÛ镳ð×Ôð ÞÕ½¬!;

üðÄÃÝ“Ô œ¥®[ëõËöúÿohljá8l¿õÌ(Þ£l,±9{Û ñ½…=mÓJq96·H´õŸm¨!ãžÞ¹ôW-°[¯_´Žö+é_eý,÷‹gß¶—ü{ÖÓÑìÒ À°mÏQ{üÙeÝFÎ-Ý3kER¾GøÉ~lÍlè'$¥à®;fG»‚3%‚ÉÎ;²÷^ÿ+Öî¢×'tz¸B(‹­;ïž™8å“6¥Z¯_°Æ3J"Úúûî÷>f|•ž{ûnXz±™V }_yÅLÃrÆ —éäŒq¢öÓ®\2ޱ¾íúÇÖÕy=W2÷€5ƒ]ī쬰ƒ Å9/q † pñÌ[Ö‰÷·' 9"]%=œ¼/²¼Ê›¨ýúy{í…ïØc€[ÖmÏ’rÊzº[í̇/³ÉĦ¢°káÔ6lqŸûgðÉé?è3mP+f3që®{ÜÆbjþ k¶Zm³î]ÕïõÛ°ù€Û”MMŸú^úÖý{µñCÛ²ó.«!T£FOœÅƒÛ²ªf#ÇšÔ$É÷J;0Ðè¤Q;4„O٣Ǻä÷©oä 6@øŽÖKlæNZ¡VªL¬v¹1²Ÿ\(³öAÑk¬¨ ÈZ6Ä‹ ½ÅÝÏi±Un‘’J+é£ê[9¾öÁóÖÒ¶.–Ú½‡ñÖ¼óV{¯²úwQ_)¿í[ ƒwSSÜË_2mL ˜ÉÐ.&·Qñʸ‘üþÀìÕWy@0‘5Mžüò¼¿ÂÜàêÕ,&Nü±Ù¿úWfßùŽYy9!úÚ°í†Þ·‘g‰B Ì%2ˆ+|¼íeüVHùå™/ý:Øjô¬nfÎáí”·¼ôóÙ Vå‘/C»ô·w¯Ù–-fb^ Bm¿p!ŠP;ÔÕA?ù³>ˆëKŸe¨Wzé:›,¦”ç÷¾gvú´YMMÜ ªº,¢ðÒÝ\"ýüçñ:îßoLÜãl b¨P^Ò½Â;8¡v«ÿ3‰°9ð™.ñÏ}25` éày”"ò¾¯)hbèðzÝ4 W lßî){.Ø÷ØÒ£« §ý"¡òî‰‹Ž›4è+tì­#e6 ›C>´__C€‚B–>ø¡¹+hÏÐ0 1 œ›Fk­¦ç—„9Ýt˜Îií”Xßö$èì Fø)£@ü’L'\Êñ>UFyÖJ·ê"O…¡Ó¼¾(Zà РÈnvkê”uµ£Vgnê~eˆMo•W˜¹s\âí( b1…ŸÝ¬˜±5ecœŸà'ƒ‰Q@ã<ޡÀ0Áç%Pר˜êËoÈXÜÑ¢w°Ûn„Ú\›#€Ú“@ƒ’*ô»¿ÙE„!($œ§s±~LäPû¥“ Yž!; 0uS‰¶; |¼å-?¥õm*/˜Ñ¸˜,_À¶åDºõô{Û–~‰qîØ+v½é,¬t½®ÿã XØßºÍØöÿfµ;,ļ ÖÃï­Æ±)¥_$$6=Ý?çÈïŒn 0ö !P¤ùÆp…ÅÐCE7yyaÄ\09ÐAÝéÃUR† ñ &kaYÿ x ƒÅtü˜GiíÜcQ®9Æ|çù†; Ð+s¢ª\sãyäë'ñ5àkÀ×€¯_«]ù­:V{«ýúûð5°b4 š²7Ú† ؓ݋‘éc»ôÚ?a«bÊjJc¶µ!ÇîÊiÅtEF†úí­WÿÌê1òí¼ã?qúÛéw¢‚”á°å*›¼ цHÃÚíÞÇ›ú*¯êº É2'@è7]iŽ|[Òì)ÅØÈ ;õa.þ›°13—(|ÁÉ÷Ÿ³SÇ_´Í;ÛþÃOر‹~LlheÈ`d¸ÿ+öÞņ;½ˆ6+jÖÙnîÁ…ˆ®ÿøÌ›l8LØO|ƒðwκ¼§³ÕÞyõÏíê%ŒB MéÞ;?弩¼sz°‹çÞ²ëWÎÚÞƒÙZÆF®¶h“¨:ÔïüÈŽ½ù78ÂÅ‹ `ÏÇÝçÔ?Ú­Œ³ÿð§\8}§rÏ~ô}µÎý<õb*MFûçO¿iÇ^û.ÞX#xÙ•ÌÈðßzí¢½øÃo½]ÚÐ4ž[ìþ'~Å6soÍêÝ@àÅüÀB×i7ÃÞñu€6wÍHÊN˜µŠJ¹e lï]eC Cß\^W  `ö}áU^ %õ5ëíž½ZÓµó.ÂÕÞˆh)´'·cÔõÅ×Àb4€­ÚtÌ%2°Ë(,×ZïY+/{m¼jã:—(ŒÒx×k£Õ»>×µúN Uòæ—1Z¿!zÐx×.tÃV†o1\¼¨‡æ´UÚ[×±)(•1WÛæª»Ú® ™ V15x  •!`†ÊLm‡Ê€@ÆüôöæªÏbúHíP=¢P™^ ¡6ÌWÔ&Ô߯¼o«t«ö H¡öó›•ÚÞÔ¼Ù÷ZŽªÔ“þ{_ Ó@°AAd îá„äÈÈ>4µÞáÂ%c4Э:®G#CŸ»()ÃÜîÎÎÇÙkÅ&¯ð %L Äf 4m¢)‹r~K»1ZbW*­“W±ä#%“V]:eÕhÊA $#&‡B„0J«a¹„9£Ö¶jŒ—´£¯Õz;1ÈCñžëù–#_4p©Ø ]‹M@aêâ@Àüt¸ð ÍÅfP€a>0®±ø£žïå‘ì*qšÒµnëÙhâsÖ‚°$`äu„ôºŽ¶‘@êqØçÇl #îk»qÖžã<ÿÆX7O0€|£4åhÕü¿Je4†‘Mâ€n^NY“ºÐŠ„Ò+*(姯ÐJ0<Qß(†ÓR¤Ô%¬˜U¶Yû8e È“ª« {÷½ºÆ nƒ2è¿1~³O¿Ïï4k©Aš™Ò®YJË~bç=ß´u;Ÿ²ÒÊ- /&ûãa¤D Ëà‚Y9)¼c\€í)@!±Nô`Ñ‘.Ê“ñèB)¬’2B<SkÒ›´R>kŒr/éèä}+ó¼ O €RwíÚŽuÓJ©ª__¾| øð5pS5 eƒ/¾| ø¸åp^ì¶”•—±ߢI. nyíæ_Ñ¢¿¨ ÔÓ¼h»<Šð=´ Ê»„8ã:^íï¾ögÖw EMÃ+¯š¦1÷Òߌ×'k7îNc1{ zÿ×úßìÈ#_I8¾ ¬ £Þž6ûðýŸØGïü­ór–ñq>28Ðm/ýø÷­½µ1™\a **êìÒùwH!ùEÎ7lô`ÝsÇcÎê%ÕFNÓù÷íÃw~`MÞµº†­¶£½Œÿ%è¿Ï`Åñ¦ Ãæé_Â;ýaØpGœ1Cì£Oÿqê§ûÌ+#‘Èåuø¾ÏÚõk0XðÇÿ'í¹ïý[;úèWM†ÿ²ÊzF¡¢¿˜â§³ÎÖ¦dV•½ým(MžK3ŠQþÊ¥ln|ÈÆF\Ï:wuÇñ¬ ‚¸wy·µ+LAÚfˆÆ^†âTÆßxîí4ø€«Wýº]..¡—Þ…;X»ÍûˆÈ.Á<ñîÏÿÜÝûYôÂ$"}tܸb¾ûc;}ü§nœ{õO^œáÀ7šíúåSèí²5ž}×j×nµÍÛ͙cT^ý½mv£õ2 ¯Ù•‹Ç­·»5™cyeƒÝuô €tv$ÏÍõF}dãLÌ —ÐÇ cdç~˜T&”W7Ø(BW/dŸ}àÊëÄÖŒüEËÚÀ½³*ûtéG?ïÚ)¼Ð¹N¡"6n;H½v² Æ ‹ËˆeÀHO» © Æ Æä@/F>D›¦ „Ûи*)«L/Â}..©°{€ÝàgŽÑBqc{:®Û[/ÿ±ðˆ £ªfq€Ë¬r46>¦ßša(èíie¬×aÂ`”"X´\ƒúóü{d¡¯†¸wš.î™*”ÐÆ½ÐHžzvHt¿«Þé ‚qî µïâ¹w’,°SÔÔYÍ ‚¡± ]êŠZߨ<û¸ŠÃÄN{ší€`cÇð—JË>2&§&¬€lžÓ“ !0‹˜$ÆÚKGêÈráF{©-ÿ0¶ ÅÓ^ƒæêÑô*Cæüv”.ìyæcPt3::-F¬ ·$së?<Äa-å÷kbF@ £0Ê\wŒW͉ð`™€žÚ¬‡ÙK‘6B5˜ZeY…•Àt¦¶—²F+†Õ@l¾¤i€þëîh!t\£µ\¿„=ˆq»ð)(·mw~Ã6íýk€z aN‚6òe–Êa§ŠŒºÊd@gæ{Ì3[aôZC•¹ŠyÕ_¾| øð5ðIÒÀܻˬa<þå¿ü—®”BPÿüŸÿsØ3—Ö…áv)£‹N¿£˜¡H%ôKßúÖ·Ü«;±Dü2–H‘«(›ÝçÑ5f‡ÿt~Ú‡Zö#<Ë;.ÇÓÇð˜ºö…ò5“„p©|Œü_Îðíü62\È©˜ cœ“AMÆ÷ëM'­ªú‚Bh®ËkX ÂPÀFK_wå×1¾Ž' Ùkí‘§ÿ^£ sÎËyV!6ã{FÔ‹§~îü+äÿîëßÅØÿ¾c1ñ[ù.XD¯.£kêõ›÷cÌ7gõDßM¸ƒëM§’†niyÃåÅÓoàþVÎëg|É…EÐjcèŽ;ŸL~åB6 ÏŒî£-Ðí·_uù"!véÂx®(ìÆiblöŒàñÑOdh—¨>%Ä«èÉ¿‹GùÞÄ}3["lPí>ð0á >¶coü¥Ó—ú²À ½íäÇ`p”™x„‹>QÌêmRUÊ;ù¡/;ÏÎ}úŒB È›jxb€øŽÙDáÞí¯œ!{VÊIýïÔ/Ïÿõ¿¢Â;åt!PĽü2Þñ&ÏËc~Ӷöv‰Ë0UL²á"cþ›/ý;¡½  D/™¾.ëT q2̽PĆVUÝz€*%óÊôFl2´Ë(><Üg#Í}€ š ã*e£ŒXªêëq(HG¡D¯ž_yª¿w|Ôö36Â<ô3•«s¶c˜¿ˆñ¿·«ÅZšÏZ¯gž„éïÉØ˜‰™a;10HÄZ±vã^;òÀ—ØŒeW8M´!5¡ënˆÅ¤ƒ¶\¾ø> ˜RƯâÂB×ʘT? P1 ë‚Ú#Ï$‰ÆJ Ô­Û‘–ûôÇ ‰bG¹ë¾ÏÛ«/|ÇÆ`*Ðfk7L¾ûCî¯7è—bWž@8½%˜4ž+«×NgÈ;Õi^]ôe|ìuÍH§º‡²ÂèÜÞ[‹é¢4<[RÃf¸´ýòÿX")…I!ã³=Kþ×ø­xlæ—×zg~žãÓèDÀÚ`*Ðd)Ïû{vëàfN¸L€‚l}Ÿ@%ú%„ÁàÂ' hÍ«+Šª­o~Ç–¥îâ„Ü{æòž‡¹ §Nsè^Y÷Déh­‰$ZÃhM8:2ìX Ɖé0Î>îô)jþ±nyy´¥VeÖ{•U»f›Ý Ý¿X,ŠðÞ_ˆhÜìºãa˜Ù/ý‘µÃè pŽL4²eç½öð§ÍÖne¶\²¦ŒS¼ÀÆ"›‹èD`#Ó1‡Ã²çàcvðî§.(lBî—"<Ýó¬_¼ýó?#”Ì%·±9 ˜AG&ÑóG Gþʬ°êkcREçÔîtqã4mLŠaA÷Uº¸ñËæeª¸´lÊ.™„èûùþvx…ö¾â½‹¿‚K[ˆŒO¬„uD·5e ¶±jg2‹‰¶˜8u‚ÍÙûA+­š— d†¡Ó•(Ÿ±Ü}íú| Ì¥‘íd!Ü™ëRÿ{_Kª=Ò¶ql]Ò\ýÌV¨4÷™Š*(¶®X¡](·ã£km3¬û£7lc¸Ï qðäÍlB& Áà‚Ê¢!æ²!¼ê€ã¯ƒc ™PlÃí G™Sy³ûÅÕÚ(oçKŒÐæ}€Ðñp Qvë ±õ `  SQëœ(µÎñ"e=ઔGµÖÖYuE%`†Öq¬)(H E˜"ÎÍY·9ƒ+_¦ÚÜõ¡¸ÛºÚx;éf^~+>Å übzc¼ñ¿´°Â…5€PЦp>C;fµ[W»•^ÂT/™&¡MÑã3Àx ($V¨õ ÖFŒ)\‚c0È`]±ÆI ÜãALŠ[å)LƒéH‘^*Û·uÀÜ”—Zj­¥*0h—JÁÀi7X³yÕs<9D4H³l%˘žì[Dc†C sJR&irËÊ ^̽ÏxÝZ¯ÂÇ~‡˜öò‘ºÍØÖ=_¬Q>Q}™¼#Œ‘)cÖ…S°þI¦Ø»JÞr€t¼0"3.Óþ€p=ØŒYÕeÔWÛ– kíʵëÜÞ“pFkWÅí¥ÊI«¯¯Ï1h¿þèÑ£vï½÷˾_³*çWÒ×€¯_¾| äÐ@–™`Ž+ü¯| øð5àk «dD|ò³ÿØyïŸûèkÓ]Þ SxwŒÅºX õ²ò:Û÷§ápͺŽ=SÆ¢2, F¤[Œ³˜Ôµò.˜I[€W¿'ÊKuÌ$lÀxù¹¯ý/væøÏìıŸØ¬ ì$àÙ,£îˆ[ì@¡¾c‹¥‡~Éê×mw„2ª;£#åé¢r+ñ¯ÀC¿·óZú× ú¬wC{Mý¦׉mAôé_úÆÿ†·ùÛ„8fí½Y°g#Š‹°vÃn;|ä3®ÏÊ«×Ì (Hd&óÚºÍöÄgþmß}¿}ðÎí aÜÆSZª[ yý Ï«k7:Oõ´d³>Ê£}ý¦}ÐÞW;ÏrÕ¹¬jm„*=›È\Yµ.¾³ˆ=„+ÐGº±}÷}ý¥b;uì;óÑK°ˆM ² ‚Æh Ì{p'aªë6¸ Þ8Q˜ž2éâ@°D<óÅjׯœ¦ß²k„Bè‘^)iâÆõ¬©ßHYºPUµë¸?æ8C¶ÔU?2WÒÞ­;î²rX>zÿ9;wòU°&Uâ}PÇ}û);r?mkØ’Õà/f‡}‡Ÿpý÷1!Ê¢ Fª—~jÞj¿˜M6l>˜àÓPJ]æ(—Ê©pàÈÓVY»Þ>xûv`F¿êŸ¦;•S]·Ñ13(DËB(´EªDyæ(LƒwϺguÙ²óîÔdî½€ íPÍ=ÙÅ=—L»cvZÏBhHo]mMÉ´ÛvÜ3+ßÕv"–08ŒÀq F— 6'ïvœÍÅÎîNëo‡N•FE Z\TQ¨ ÑBNNÊÊ áÅí'Ç?ù} ä¯ 6sh З6þ•¾­M×ph,úò‰ÒÀÕÞÉBë›,°6Â"œ¯µ5°ìŽvÚ®p§UÃ^ ¹Ü­’@Šü°æ—3瘕“ÃVW6Ào3 g:`5¸Y@Oƒ,½ä /ku%±ì°©à„ÅB"Ãx=¡‡!)Šï‰'™sLÉx›E©aÒÔ×5X]u­F4ÿUJ¬×ü¥£¯Õz;mŒùN>^Þù—<ÿ+ë*ÖZYQ¥EÑQö:—S4vówæçb'Óz£n¬˜rYwˆÃXŸÀ¢7.ð>Àƒ±±8»ÁŒ €Q'bõ—¨¾.t„Û“˜^÷vÛ®67'ˆÝ„€å€ BÔ³˜µV1ûZ׺`95wò¦Mc0j4~ô!OÛèð`Þãvç=ß´u;ŸBGU€ÍÎüoBV{ažYÞw§¹ÐhW[æÛ¯ôö ÔÙÙId„^.xûí·íÁ´xÀä苯_¾| ø¸Ý4pËABï}ûÛßvzÕÄB±•–Zn—2***’ºR›ÊÊ2£?¿ŒÅhou^{»ôùJѾ ó2´—a”AU¡nàÍ=µ÷Èòp¤F€îßzŒÃuŽr¼ƒ±ŒîÙD@yOÿÊ7ÿ£ö—Q®ƒÜ|D´ÿ»÷=`¥ÿß@?ÂfF‘կߑõR¥ßˆgyUÍZvèŽj> äÁR^YçâÔËØ,l’_ûmò‡æ±¤´œºÍ4ö«0à«0tþÒoüŸxh ¿¸­/~/ê¶Í͚̄â’JÛ¹÷~[GŒûÏCWß•a Þ0 9úö<À+ªGQkE ÖA`QÀ/T¢¨©ÛäbÒoزö„vbÖ·qÜ ¯ú£@qq•ëçêºuVZVÇQ“u³/½|¶l¿Ó¾ôkÿ‡ËW4÷270Ʋ‰Úwÿc¿l{=š-Éœç¥ã0ãLà‡Ù9*ôŒ2¾ ØqOú>ÆIãd |…'¨øPk@UÍtSÏ8 `Œ>b_ý­󯍻ª1þÏâ—bèWû.a3l…áèí ¡ |u(6…g(«¬…¶µÊ ŠKéÔZ1Þ5ÚÄ›è>ÚÍ=ª1=—A9÷líu Û[Míioi„í¢Ã± 1VâmÛê^Ë*êr–§ñáž°`l‚EC´ÿC„è†eÃ…`LjsOÏ€òªz^5&K`Y(çºtáYçÓ"ÒðÑxÞ†Þjr âu3Dè…î®k„\i>ÈŠËㆂ2€Å”-€EºèÜúÍ{íK¿ú¯ÛŠòVŸÕ¯™ýüÐý½~Ã.ûÅ_ù_­«³Y±j€-™ž5?¬Y¿“´ßvLÚÒ­‚­%SÚô:­–Ïbe9Ýô¡}Æ‹­ëv[¸ÝŽy0‰6… àU OÈäÞkCùyGyyø¯¾fi@…9Žq¼=ë[ÿD. læKáÞ®pÄ£ÝäJí—KrÔ;¡±˜}ª›+ÿ»Û@xÛðT؆tÅŠìòD¥½\k[#½¶/ÒnëÃý Ì4ìßÊf‡‚“VÄ‘*¹€ç{†Šlh´`i x‡i_sQ¨ãÙ,„ó]7çÕ+lxA€¼ƒ©@¾›ÔgÖ奥€Ž GVUû`uMD<ðqê:ƒ»óL×÷šr­æoX›×0×VÞxWwöݰžÀѧjle¼×š¡†õWEI3îTIµËU6ÞWSyÌ3'8\óXÑÊ«N\x‡DãòÔ•ò  Ó°ÂH¨ òó\h  uÒQ`ƒq¼·Å4 ºq1°VãPÈ,UÇÝœriž>a˜ 4@Ò€À!¡² +*(³(kµRê^ó˜êR˜é F)G÷ŽÂD¸h²BRPoIvAO¿<È“\¬þð~(`‡XÝé*áí¿e ¿î–ËÖ|ñ¡î.²à7!üö_µû¾ˆ“ |1Q²Ï£úеÏQ¨UE&ß;Æé‘u— ÂwAÖ}ð; ’„®bC¤g½«1$¤Z€µô侪 ¬Û¤ŒÃ÷?f{޵ݽì›,nå­¸ ££ƒµ~·µ´´Øk¯½æ€>ú¨ÕÕÕáÄ¿OVDeýJøð5àkÀ×€¯Eh ±BXD‹¼T@!ø<‰F¸î]˜ãõv)£Þ»åÖ•_FŽt›~u»ôùJêD]®C^¶pžÉ“xà´Œ°±—«·xÌY6d,ßw¸ 2à¹xŽ9/Š©º”b,ÝYú›\ËBF›¹ÄBË1زЕÇDlÏ ÊZㇵyÀ¢WiRë)ÃùN.òB›-¢ÁÏ*´3ÊUu­Žõ6É]aâý¨{€2Øk‚@ ùˆú^€±@x›3^Ô¶ŠêµŽ±`=Ì êSÕ[ !OÄâ0_ð‚îqýråxEô© !¢ðS´KžRjKØ=4&sèe^ Å3  Q0b’Í3énBl#ôÆ£žAs4®‹4¤³ÇQì†EÇ™±~<׸~díú].mˆ´ž>Ó«íÒ^Z‹Á]Îý¹Ò¦_»>k¬ôtÙÛ§^µ`LçÞÌî*>62aCÝÓc«¡~W‰¶Rχ9DÔ¼Jꜭš2ò˺±œF~Ms|žüŸý„ãEöö}ÉCš*ÞËñ)B?ûâk@ÇÓ¹‡0b/hdpr¬ÖÖ…úm/ì;"V\™¿‡¹€ £0 ±nšf4Ð`p$j#ã%ŒÂR…OpPævϤÀØ<ɉW|~Ê{4`¯Ms±¢ò2«Âó¼½±äø.ê{& ³ç³2°Êðír'½>+o<„Ý ï†Çá¹o¨›üV&  (\d•°—•BíÖú‰z§·C§’âü]Ê”u:ë¯ÝÉ´z3O]ͼÝ2O”.éò ÂDÁ{Â$…|c¸•LÆø)ôëÖBtÅø8óz˜°´6åPø­ð`™€^½F‹êõBÎ!ÞWô.a½ZÀú¢”×bÖpJãÚè”Î[ö!d`—ÎÜúÛÛXÅQr¨/±Ò* ]4<ž—€žÈ0;Åá„k¼Ëæ*ƒµj@‚K§ß0Ý‚_ãÖ»‹¼Ìç~­¨ÚΚç[»ýÓÁå…N´¯ {ʉW!>ÐgÁZŒfìéxdÖNÓ’rX¹¿à@yNÔÐ×·Y]ÝÖÞ!Ç›8ØdZ«ÿÀ?(4‚À¯¿þº ‹ðøãÛš50cúà‚ÕßÉ~ | øð5ð ×€fÊ·\–HÞ(¿Œtdÿìë*»nn×on—>_‰ý£Es¶p ­¯üq ÂB¯dŸ‚ku,H´aÀ怎¹|ø]Ý”ùMJLÒiÝ—³dõw´°Ø¢ÎÅq©Jb#z¦øôKUBþùhs‘ºá™¡#·ˆ°À1è2ä:6T “5¹KYØ·ÙsÔIýY€‡ˆŽ¥õ¥ò,±›n`iòOÏ%®óÂ.Â’¤§žý9Þ¿b­˜¸ÑeH;Ÿ²WZGäíåy|e«ß8€‚þŽa6Ôâ‚léüó¾òÒ€n]a·eˆÿ>ÇuŽÕ(ÂÈ=Ë¡½û8Np,µÝqy~Šã!޲ èѯGõó·³€¯s! úyýgåE‰ì?÷s|‰cÇbñrdáËí¥ ¦64µ¡Xö‚bkš¨²šÐ:Ûî¶½7l]f@Æ×•+s b“xócÈ[?,ÃãÖ?\°<@GeˆM¨+ 4`ž>44dã]L¯YaI1X¦¬W +Ê-Z\ àÀuQQh@HyÔ;[+™e2¦ŽôÁPÐæ€“X¾ó°Ë.{§–âI^ À¿ˆy©ï)&Ûœe{m™oz,¾9u•©°9Ë@鮯ÎnÎÚ Püë•(¬“2Ö“ô.V>cyhˆXàåøw€ Ÿ :.…¤2¤ú•0ß›ž ¥¿‡Ñ·Â'Tæ(`P [‘­j¤ž’3 2¯Âɪ'ßð z×zéÜ+iRó×{—Ž7®ÏÕZ¯^€Á°{}~?rµkïìÿ Àúí¬ù¨?’’±RÔIc„:poÅ+è]%½‘¸FWÌL5ó“—“—~5•ñÒK/Û•+WÜXM¶ã6{£ûPa.¸~ýºÜsÏ=öÄOØÆ}pÁmÖß~s| øð5ðIÒ@>»ûŸ$ýømõ5àkÀ×€¯_¾| øð50o T”UÙ‘ýG­¼¤Â: Qmi/¬Þþ>q[ãàm.÷[_û ÷ÉskÞÙû } ,LìyÛÓ2Èÿ˜ã$Gª5€9¥žoeh—CÝ—9æ‹‘AD壽º¾ƒc¾"¬Úªÿ!$vp(¤ÃËç9ãà¦úmàðâŽÍÒ—g#Ðw_æPžãî–Ì@–Nd';‚Ê€a¡:~„kT·W8®qÌ×+ðÄnŽ_à8Ì1ÀñÇK¡,ôÙ¤úoá@Cz]ÇåðÅ×@ ŒaBíš,‚Á ÐZ&Ê죱B"!Úá@¥ÁÅÜè9 ^†¯2 Ê`2¨‰ âÑ‚Õ+4ÐëàXÔz‡‹m&ƒÀÃãÑ¥e4!™ÀkvÃó(à‚i1âj^"f. ,Z¤£CiÔ ³ä\Ñó^4ë|G?¡ÞŽ Ïë|¼¼—Aå³²¬«Xke…&äÙ-“¬ŒÖžáÚ¹ÿó€tF^X2 »ïyÅh$çÍt¾ ‘Ð%J‹_£o{WâwÊ[{'‰vб~iGhƒÁ¸ ðÜ¥ßGÈ|Švˆž}ƒúDLcc¡øxÑéÇ\Xƒ™÷¨ ŸÐÕ6 4à¢@ÕåEåŽÁ­¶¸RÂp7Ä hB¤Éßõ í *4a˜::Ý&Ú­ZÃè¼øyïB)$XbT+ Õ,ƶ»Œõu[ãÉ·íjÓæáù…; GÛrð«¶aÇÓ„[O×næ:WW¾›"Ìåä? °]é +@C¨G@áù¨‡coP½ƒÕÌÄÞ€„`Ô°@?ˆŽ¦`fÐ=w»–Ñ×Ùj'Ž¿O˜ÍÿŸ½7 ’ãH¯¿¼Ê£*ë®B p$Á«ÉæÙMvSj=;Òê°5~Œ4f»;&ýÐjôce¶Z³ý±¿Öv5šÓØJ²Ýîm­4Ò¶dÝRŸÙ¼ ’ ‰(ê¾³*ï;sßóÈHd²®¬D]p¢22Â#Üý¹Gd„ï{÷â½’!̰ï¿ÿ¾œ?^áØ±cš\°ÿ‡€n¡F@# ØwhRÁ¾ëRÝ €F ðÁ?žHÊ­ÉQ‰D£ˆ‘¹™øFÔ@ŸC# Ðh6@zùE‘ÀßnüÐÔ ‘±åjó˜ãš(õ ö*ßC–µÒRÊ&cc¢¿œm uH0Т<ä"±{nÎùlQÂq(º–0É_€‡Nc&uתŸÞ÷#@» å_ÂrËM,_`Â2ƒ…‘9rX˜8gOò½ÖiP,/}øä[#ÏqË,w± @ÓÎ<,$"Âr ÖüÎ2žÅr Ï1Ž—ª2„ÓÎzº°`^]º± `áñ¬3¢U$“ú±ÞŽ…d¶má9'°läQöžŸõz ËaýX.ë_`›P†þ/ãó–ó¶Ÿ—ôZ†{b~K–%,ÃXˆBD«ãxnª ëj¬ˆƒÙ®¬³œZ·aûa,&Ælûá ,fñxØ,T™f±ý~,ló,g°°m]X|X˜ûÎc¹ŒåS,w°pÞµ[qc}ˆå9,¬S/޶S'À zAêq¨ÌA½àN.$m¶$Â"„Á ÃÇmjµ¸ÁBv ›ÊN;/.óB4*Ñ\LI»ÏE+ÈX>ᓹ^¹k ²úA¦p[Z¬Am¦×l±h1¤@4ˆÃöI¿x*ƒÁ‹ç«ÓYw(uy›ÞÊ%.@:H3’È'%ëºäàÍŠËîI6z[íô¶*5†šµ£1ž²úÄm5ãÛ«VÐ\«9ŠTP¾áW‡SÇ×@aË áÙ®ê¶XŒ1H õl yôyÁT4€A=† WGƒ ˆ9’ b!ïyÆÅhÐX«V50!$#2g_À32TîfȤ@IDAT‡U(/Bna¼ÞÂG†”º ·†ðq÷ªs¯gJ9ŒaÕ‡ìB<{“ðAâ 3ÕaA¦ OÈÄÍÏdj|H²‰XÆá È‘Çþé;ñsPûèTÏøªM,³&_²á¡ “F@# Ðìr0 Ï *-aLEX"³´ìÝKT‹— ­wa££!qD‰ãxÖ˜ðL¤âòÑ•wäòíK•#(O›€©ï° NÎ9P&§Ç.¾—„'i9ÔI#ð€ð⼇°ÐxLÃ/澕AŸ7ÆÐ4æÆùvHÃ3Uh.Ï‹cÍ 'ðÏ`Ib¡mÊ<žÃŸså˜ßWÇÓ`ÎãY®qitócXx<¯1–]¾©Çs.åÒø]žWÇš‘X·s? ×b¡Á›äˆ9,óXØ6ÓxϲyÖ…—y;– žceý°é¾ÄãÙ†~,4¶³<ÜTYÓø$a€e± Ä­ 1f^®G¶“—w‹Ù^ž×Äšç7±æy°Ô‹1Ûv ‰ĘerÎÞœ·7ûˆ˜°\æç:ëȉÛcy ûk¡¼°i,<9Fª1åqì{î×I#°¨^0_ôÊ"Ô & ù ê}6C½à°}I¼ÖòôÊØéCWª|obP>ŽHFEÜ lÿ`ÇÅÛdÉŠßNDJÒbI«¶7–hP¾A˜âÞ‘Žƒl¨…’ö4¤“xàÀ§ !õX\¨¸¤„ï4èRÍ ää…oÞL¶]Ý#Íþ6ñ{šU‡õja>ƒ­—Ïl…™Ÿ÷zeç5w¬ñi³Ýe¨pd¼—3á“?«.§K ‹Ð߆õ"Œï¹æ8@2Èaž#›3ˆ™4Brårx”ñÏ®¹<ǘ¶ž8ÏRÈò‡ ?›™ÀÑ}á8Hja˜Gªg.Fy|ðÚ÷€xàF8Få鯎B}Lp—U H›`C­af즌ߺ"óÓ£hK}ÊA„98xæ›Ò…·?vfª"÷þ°>Ä‹ú¡¯®W5‘àÞÈ••Ÿ3ìH9­–•1$µ<Ì) Ç%.³³³òé§Ÿ*RÁ+¯¼"gÏž•íOû0c¯Û®Ðh4[G€S:i4Hƒ½þÃwþQþî‡ß’©ù ø²[ýF¨aÒh4½-}›Ik<Ãh ~Ù†½³"Z(ËcÃ0)È_;&çƒ]^i;äS*®šTP+½©±pÆšd.U§6u*3ÚUûªWi/¢1Ÿ‹™6z,óÓ²ÑR^øi3ÇG«ÛB>휟¦Ý$:ðÜÌGã *!Ððo[°ºáÄóÐXÎ¥‹Yp,û¹ðü,‡ ¿¯LiïV0fÛHPàb¦”iæ5?y’"¸ðx¶“mf[M‚o›\LLkµ»uÒlˆ‰K´è”XÑ!³ð¾o*³‡å$Â#PÉ Qö­Ôs+ÇÆ .ùé䀼7w„Oå¶h®DpCqÀóœ^éH¬$4áâôZóâľFaQ€;Í£êÚ/7Žæ`€l° ëð·)räÞ±Ý5›§Šh@¯[,%õˆõàn>x’7#ä”×÷j$ª” ¶¦œ¾j ¶VÞ´pc«fÐ` éze¬ævzÿ›ûͰx ¸ã™”LZŠÀ €6e3$`ÁÈlI#|B/‡ÏÆ ÔHSÝÃ?ñTT©DàáÀ ²• š­*¤X^´ÅE%ƒ*å¥@ îÞø\Ƈ¯J,¶„¦‘ÈkþVŠYw¥ýÀÓràèkÒ~øy¨uPŽÁ¨FÀpÀÉ‚p'Øy¼¶¡©ÅsÀuàËTÂ;A)‹c”ƒ ®¨1˜j &, ¡€dAÈžŸéa(#cq`¼©æ>ôâ pq¡rÁ•+WT8*<þøãâñãã¡I Ðh4»õx¿ëj¥+¤Ðh¶T:)÷£oËßþèÿ’éÙI”)AL‚ô÷“¾®>ñ"`&Ÿ’Ï&ÞÞpÍ였èi>"]þƒ>F—±÷±ê ö&êo,ÅÒa¹6óñÆ2#— ž8=ÍGu@Lc¥ÇÕ†‰lß5ø‰š‹¶90‘Ûdo€’Â¥T_ ë¯NB`+¶ž­Ëænõx2L„¹íA}²Î&q`³eÔÓÞzŽ©®W#ާ½ƒ‹NB€&õ ¬Ó³»„ nÍäÓl—‚jÁ)眴GU¨€ª^ÝÅÇCòÁ|Ÿ\Zè•hÎMS÷}‰Tˆ©”2,ô .Þ#4Á°vðéhm‘Rb^rɰd—¦¤X|*û'Ù@[OÊ0 Ãò=²AN i0¹âP4Àé­ ИºŒhàf|yìø ¯ÁDƒ_‡4C2ß C®Þ÷•Û ŠTàªâ؃²W¸IPÐ ó“(À³ ®•(´+Y++ؽÊP¬ìÑ2r6·¸Ü^%úE,Š\¤‚\&#YÇsÙ´dàŒ‘ÅwrP6È’˜Psôbó&Suè„4ÉlåGøö±cˆa:lkM^ŸË!| Xâáî­/djlH’©šÀþÜ|ê?ûkÒwòÄ×Ü'v'¤Êd’Ú-iH#á¼’ ¦uQ! H&`â)çç)%‘ä E&€ê‚I*°‚TPIe¿? eˆ!%£ ÷J*•’ÑÑQE.¸yó¦ô÷÷Ë‹/¾(O?ý´ø|ÕlÞ‡'Ýz€F@# ØhRÁîè] €F` Üß»Ÿ½)ýý¿¹ÅƒñÔ‘Gä_¼ö›røÀqx=xÁŽ·ÉLdJnÿýǃ¤»V x. ´a’¢ZÉe÷ÊKǾ&OúZ­Ý5·ERó2ÿæõšûjmÔeì>¬¾>ø r®÷˵º«æ¶‘ð5‰~8Rs_­AO›¼4 Ë¨…ÍÊm+=®VމZß·óTóŒøÃ¹C;;0ï¸2ÑnƒA'€F@# Ðì5Š ó•_½åy”EX„XÑ%3Ÿ\ϵIÔ N8ä8b¶‡l©Z?¯«Ÿp‡ö\‰tÉO&ŽÊp"$™Œî›¨‡I4hok—cGåàÀ ÈÆûàužw4<³s)HÍCò=‘ldFÒ±iÉÃË:‡÷Ù\|±áDÖ½¨ ˵ˆP1(‡K ¢ Ÿ’Õ Ã"ž…,ô6w ý>Õx0ª‹ äýÖ@»¼!qP€X÷%øá³bX,\1ó˜Ÿ÷å‡×~Ù£}ÙÙVÍÏì¿2¨Da¥…ù, •!W á`À§1½Cy1›‚ÃENò9(Z”@øÁ|J:EHÚ—@Dȃ„ÇxȃÐ(²‰ ”Ì©&D’K˜¿™…JÂ'¤ÒR\ŠH|aN),˜}‰ƒ6•Ž=ù;rèÔ/‰Ûß!³bž‡j$ pA;+ã„cde^U*ÆÊo{8 Ë©ŠH`nRŸEä–5ýA}áýÁí†ÂÔTÜ3³â!Æ…§N\ï.Œi+ÖÓó2u€Yä-²Ow eP·±±1E.¸}û¶üøÇ?Vä‚/}éK 2Æ”N€F@# Øyö© ˆ{þ°Þ¹s,U«ôööÊéÓ§Šäv•qãÆ QÞГ'O6´yȕݺuK—±T5V©œe;°ªÔ¦©¸é¿¬|]s¥öwço >ì%d»Š—:0Å"®í©Ú‡Ypû+Ÿ?¼—ÿç»ÿ¤60ߎ–_}^¼VY²ŒËB¢ “òÖÏޔ黔ÐÃË ^žmޤ¤æýòäSOÊ‘ÃGî+‡D„¦&Œ%QŸ ¦\!+/œz}ƒ¹áx¡ËØuX9¼–MõyÆ–ØTŸ;0‰¦ËØX·k¬6~/ÑXí,V– ürM¨=™÷ËŒônlë\€F@# ØE¤K Ã࿉þæôÜOX.xe$ß,[»¥ß‘ÓŽYéµÇTH€í¨ËfËøÞÄ \ ÷ÈtÒ/ùR}DÂ=äܩǥ§«[„è26vah¬6†smV•Ú""#ÿSåëš+Î.‘þÿ$âÿß F|+&TB0õÿvíÃÊ„‚ÌÐÿ)ßtÉͼÔàmÂ嵊ï¨ÈíøEºÈ÷BI,&寇2?¾¸VÞ…²³»üámyöðëòèà“•]\É"\Â#?’÷‡ÿyÙöµ¾øÝ!ù­§þÝZY–íÓeì>¬ÞúGy÷Î÷–õÓZ_zÊà›gw­,ËöQªýƒ‘ë2–¡Rû‹ÆJ«Ú#cùÖÝp ~aùDþ‹üƒªX“àwò <¯“F@# Ðh4A€ ?K 3D¡^0UðË•l›ôØb2õ‚Ç‚4[A@ß)^pÉO'ä½¹ƒÉz”Ѳžj=vö¼ >.mm Nà 0äZè ‚¼Å ]veüÆHvÄŸW/º0–ç_焇ÈŒ7_¤FÒLlF P;ÈÌK.:÷`ˆ  @á?ü)¤PoÔ«B4@½•ª‡j€¹/+˜D¯¿EZümM·¨kÅ8I‹¡b+ðÜ$.À¨ËUs+ /÷h³"Ü îÇR>¡ú¾ÿ›P]F+Å¿ ®Ä C‚âÂg!Ï5ƒl®yÌKæyNOYô 2i„O@Ø„bÛñ™Ë×§hàÀüpqqQ ‘Ô@\Á8®'y;ÏJûñoH÷À+P£l“Bxᘬ]h§ÎA&aÇÆëKµåøá7\¥Ä"±åò Ì\ÇÙ@~Qù‰“Ibá„sxhËÈ%@}}E¼;::äìÙ³rôèQéééQü^¯WœN§Z¥¬ØÓE„qøâjé)cqÉq’Hð4«¦~ìŒÅdxfF.€\ð>ˆ Þ'«ï «ÝØtêšA=æçç•Ãà… „ª/½ô’ÂA“ ‹·>›F@# Ðl =G*`³bøqŸžžV¤‚(ب"mG¬;Ûá òA´ƒr_ºŒÕÆpb®íÀªR›^àÓw+_×\¡õßuzÒåØt|Á³Á(ã:Tû0pþt|DÞ½Ýö<^Viék»¯(‹©u\.[”‘K³2?¼ú½A9ÝkI®_–¥DX&¦Æäûoü£<ûÈWÅå¼ç™“Î%g° á¤q®ÚY¾­oçòk|Óeì>¬òÅì¦úœý½™>çpÐe¬qQ¬Ø¥±ZÈ_5Vk€³bW£±"¡L'€F@# Ðh¶†É“PKH"œÕ ×jë‘£öEtÍI5oÕúY[©Ýp<$Ì”K =ÍAú¿Ž“Ñ!åÌà9,g%èoVêˆs <ž)Ç®<¥+çÅË+`ø¿2Y2€†yì° ¶»ÅîwÛ!É÷œÁ9àužAC–ú¼ÁWÖƒî¬6J¼G4Hƒ(O‚h#.eøI4€¢ FâïïQPH|èG„(„[:H Ààg…š¹*­füãœ7¥ñ—A³Ú1UùÙi•l••r™æÇC\ñ´™JST7(9œJÑ@Ù1n¨n@G®, àÝŸƒzFj$dN¡˜WÛÖ"Øp2k±$Źy)`^U…ÞP¸›°ñO*„ÍÍdÅGZ†îHoÇ!,ÒÕ’–¦€´øZ¥2q^E XVǰ#$A(¨Ôˆ(BÂ²ÜÆ´SåÇ·e¡†2xÿ¨`T›u68qB¾ùÍo I&°ƒLUŠ l£¸ «æÞeW¼¹ñ¾O†DèM¥¤=–£ñ¸|FýŸ\ð”¢(«´Úµß™·× U d||\~ö³ŸÉSO=%t´¤‚3•œuÒh4Àv!°ü—w»JÝB9dáõõõ©O^úûû·p¶Ú‡nWTíà‹!׈.cc¨j¬6†smV¯ÍÖsæ ¹5Gï ðàyê¦g‡q^¾çäS9Yœ"K½$M¿üêW~[õ÷¢œ>ú„ü¿?øs‰ebrãι5|MΜxÌ8XÿÕh4€F@# Ðh4A “y¸èQ S0~‘íDH„ˆœrÎË üVã·)]‰õËOÆÊp<(ê!´Ã[öØárüèq øüx/§‰/®V(À;†MJ¯/{™5w4‚ÑXÉO&æ+¯šÛ,P4pp{¡(˜ßÝzÐ Àü@2C'DfA,ˆJKvqJ ɼ3Czže5 )ƒ?¼ÙÕÙLE Ÿ^ˆÈ’u$;HMâFŒt»„_“x‚0þÂÀÈÐ 6x,Û tÀv* z³Ýʳœ8 ~f…ñ½ÚÈYö@7öVáfž‡;”•Ü<`šût(e<8¿J‰y¥7¯ æÀ D΃ó˜{qá`–W!r ¨lïÿ ŒºY†ÀÎ,ÙH$ÈoI¦¡NŘ@ˆxr×›nåZd*D„€ä„L†gäÎÄMqpìCmÀëÊéöJgkŸè< ‚A³t;¥Õ±ÆP#h/$^w%„I° nFX„²íbh#Ì•2¡¼Î(Té`2®[µªTˆ Ç£…aöaJÉÁÄÁhö¦þ655©~(š0œ P+±²0lï‰vb^¾ÙmòåDtc ¶ƒsê¯ÌÎÊ·^]n,-I¡6v"1\3‰ápX&Æá½÷Þ“óçÏË+¯¼"‡Róµ;Q/]¦F@# Ð<\ðcO%2)õc†<ðù/®Ái»Ê`,¤G}Ï7yíàCº.ccƒCcµ1œ˜k;°Úxm¶ž³P´È|ÂpiàKÛO¹>#qB#“[/¯œtiÂ$Å™óât$§Ý-‡œ”Ïo$Ä…»;5¤I&xúS# Ðh4€F@# Ðì0T/ˆ—œ/8eêwr!i³%å¨#,O¸¦$hAªlsjlUñŽé”ï wɧ3.™I8%_ª¯ =äìñSÒÝÖ.M Ã?,µ†±Œ†s šøª^Z+ž¹0hfaø¢! <‹›äyc 1ßO\%eÜ3êEwèÕMã,0Î;š`I7s( À°J¢Áâ¸dÂcpFÇ:Ô r±e<­4| +Ñ`yX‹4b£'lQE0°‚<`E{I" ªʧN7HP7pàÓ‚‰ö&¼ýÃ#¨Ü½•=žÕßè*hqÀ=l—áÎLe¬—åÇf]@(æ8T€XY€¯ £W>—¹Ñ»P’LTÈ$ª6ñgaPîæƒ¸î¡¢â1lâàY3 ÏÀ1]•Æfï(E+ Ú^7ˆ, ´#TÉ(x Çß‘IK3š›ZÀóá5kŒ-%Ý_6‚s½Äœ[ª&à*•Êa8ò„8ñšUë ñUcT…^Øe ?ÕuR…]=«kbB˰¨{ÉNHÕ÷McK]y_ ¹ ¥¥E:::”’òøø¸|þùçJ5À$;Õuò-‹Å„ËÌÌŒªË‰'TX*$;q_ÓI# Ðh4B@“ …¤>F@#°ç(æK²4•©ë$Æý›[œ–ñ¹‘urêÝ€F@# Ðh4€F@#°Û€ÉI00&Ä)ᢡ‚ò-%öE9åš•.kžÓUFå• @Øñ?#Òú‹bñŸ‡!ú€\›’÷¯¿+×G®H"ƒYkãWž¯ü½=Ô,}râä BàÐЃ!äÏ {4 ‰eãa d¡µ2BBªJ†´8c¸3,™ò4Øâ˜r*eR0ðÓè†Í.”Që0‚ÒÙÈ2윯©Yŧgy®–>)8§ ª…lJÅCWŠó#pÐFè„è¼ÒK’O;†nØb" £Ï‰:Ó½è †ªÁCG@–ÆFE4€’ÇG5ƒ&E4pÁ lƒ\=¡£â†D‹ò8G¥îÀÎÄõ{Ø*C±i4åv+Œ¿4–sAYÖÀŒï<–‰P“X@C2‰LyV:íƒD0rýªÌÜ–Œòõzƒ»Ÿ§GºÒ%‰âœiœ+•Æg:S÷9Nº÷·ZÑ`!2«vŒaü\sÜ€=D÷;âa è IO°Uš¡ôÑÝÜ)¡Ž#Šl`Cß[=A(€ </[޵2Ù ˜ÃµÅ^·¼Æ­¾VãZÅø² õo^çUDz!g(,Øê{;^F&†1¿õk{Ív0ì®)Þ­~„nÁµhQJ*ꊽ×i[\k‚ê U z{{åܹsr÷î]¹xñ¢ ƒKµõ6ÖS½Æ7*\½zUŽ;&/¾ø¢<ùä“âÁ}L'€F@# ÐlM*Ø*‚úx€F`ß P@¨ƒ…ñ¸„z¼âmY›XHÅä¿wŸ Þ¾C7D# Ðh4€F !ШçÌÀkËv‡æ÷<S+æ—êüû¿ + ²‹ccJ`izªnB á*›žW÷#0Ö¥`uI¤šX<ÒOR’S”Ž'bÊKD%u‹zÉ U½¤V—)ÄÃjIB·m.„vpˆD'> t†zTø„–@»t·öJ+>ËW¿a„‡2B j%J„㌉cD˯ËþæF¡L*(A9¤2’HRªú†þí(ƒ¤³þË*¼É/k´C…œ@{,¼>Y_¹°6YÎ:ÙMå‚¶¶6ééé*Tðî»ïʵk×$ŸoÌ=kjÜ·;NË®¡ÙÙY¹qã†üèG?Rä‚gžyF|PiÑI# Ðh4õ" Iõ"§Óhöx×HÇs2ryAiwž+¥+£ñˆüàý¿ƒ´Ýg+öꯀF@# Ðh4Ø.9黑#×¥k4!¾hFYï0¹Mµì",9 ‡Lõ5ÉÓ­2v4 ©&Ó̦QÔhvÐ~”€CÒLu»ª ZcÕÕÖ/ÁÃO‹¯óúFT(}XA2H‹´µæ1¦ øÈK.——$T âôðN‚X]PDƒD*!…bIbØ–ÇØc¾zê±²Š× .f¤Žˆ‘clvX…Opàzp»<âÄgg¨Û 0|ÆZÈãcË>ÄERÊø(C{¹DÞLeêp¼^Tvü!©±¢ŒuæWX?À2¹ÆlÀJt6ñ}Ív þ ¤íØÄéëÉZ­\pöìYE.xë­·äÒ¥K š™^Ï™ë?&“ÉÈî]$ Éücyþùçå¹çž“`0xUúH€F@# xÈФ‚‡¬Ãus5µ(á¥1:“ÁäѼ´tB®ünÆ,¤ñÞÿâMùôÆ»2z±W†N·HÞÁ q4D õ‚ Ô ¡^0^ʧY·²z唿GŽ@JÝ BÁðä-ùà‹Ë¥[CV} ¯5.ô 4â±³çåÔÉG$ä ®g… >Ó0†×Ò<<øáyLƒŸÅU=x6ÓóVIz»‘›ÅÒXgzÃØPÊ$ gl£ ¸i`¤|º¥TVæÛÅeØÀ€íÉÀA"Úálî‚ ëðØÎó}¼>!<&9ÈÃç–@4ˆ/*2Â`_7‹A40BXäÊFÁ4¼Üã4Þ+ ¬0Ä:Ýð8gØ/ŒÁP2pºâôÄŽï&ÙÀ‚û}E‚2õf_aÝ´ëV¶±fl'Ž)%…oNᢟ+¡0€‘I, ZŒäh<ŽÁö½VjMBÁèçŸ*…‚ ŒüõƧ÷öž–Щה †ä"¯°æVàåै*àë²IÀ×!yD d}žå9\kÉT„¡¤R‰Æ¢‹.Êzž3|B6—ÜÔê < ©÷¥êð æÎ±Ù;Ñj.]èÓζr û¸¸pê8$mÐ H,@›lA„9É¥c,à Æ‹ø[H.ar+±RT¡,ÃÀ{•¡PžA‘ 8 9~¨ŽPŒÏ÷Ÿ”¡Ât³Å´V;¬ª½¼nPÛ‚TBŸ×ß ÞÀá 3@ƒ=Ã" *rÁÏ~ö3ùðÕÆNÑð,9Œ×©©)™››Sõyã7äÙgŸ•^xA…p¨¨­4¼d}B€F@# Øo˜O¤û­]º=€F`óà=Óé´I“Á‰…´dâyÁ{¿‘𢸄Éï¿û·‰…ÁXÏ«¸xÁ¦ ,â»N€F@# Ðh47M±¬"<ý“ i›I©ë!b+”¤ Ä.-óié˜HÊ»¯KÏvIÚ«U ÖÃOï×lX.oîšÜŒNIÇø J·ÌNÏË݉!x8Gë"´‡ZäÈá“ròøi ú›¡l¾Š±FCÓcÛF=Å"€ÁŒÆÒ÷ :a Uá x@•”Jªx/W¶+{  ›ÛŒŒöš­VázΠ½Y v‚!'%™TFéÌâˆä¢ó &,÷:NÛÝj(2ˆÆ_+ ™¡jà’¡œ.¼^q`±CòÞ†O $ð-&¹`Ew(ã.IfWsEõ7')̉ŠUB)pRµo——aÁX-€D0výŠÌ ß©;Ü[ÜzúuñyB\Án``Ž’*,¸ºâúPDJåWe@ð+_s$äRQID–$ƒº"™ÉIáÃ’ù ‘Žc.)óà‰‹Sruôªšò8AdÁ¤U‡¯EúZˆ¤›Ž¶ƒÒh•f¨ØÊƒe­g^' ¬” ÜPI4À+’ѲÜÀ ÷†E`(¥d@ÒJ9Õ:?w­U†RS¨”jžióŸk•±Z;6_Ê–Žpáš?pà€twwËñãÇå«_ýªP¹àý÷ß—X,¶¥s×{0Ç2U æççettT.\¸ È/¾ø¢t"üŽRÈ©÷äú8€F@# x(Ф‚‡¢›u#5 àCýàcm2{3"Q òé¼T¢Ÿá¥±¹»pdV=d÷v”¯=÷ 2>3*?|ç7rzG# Ðh4€F`Ÿ"àJååü[“òÂ÷F9À õ«Í&ªôÇäÅ‘<•?ùr·úÜìyt~€FàÁ!ÊÅ…ËÜä‚X·`k+A•ÞÊÊÈ¿¹r{aÀì?&ž µ a›;åC™›á(ÏD›p)“@8‚6ñBöž^ÛT6 Wº©hÀP ¹(B($$ŸŠ5„l@oõ<©+ °ÙšI©,Øaܶ¢Aî€AÕ2Ç€¢G\£àòAÒÒöÌã Áât‚;У«Y‰]þi‘3>;-3wnK2í9¨Ôãýoƒ¼y’îGŸG°³¶|Xиê´ÒÃbmáñA -ߌæF#'ú»$éT ¡bP60>ÓPЈE£Ø•t:©<ÓÓXÑ`žù×&oC\À!Nˆø úBÒÓÞ'!»t·õUˆ›€@gmN\ÓT- Ñ~``@‘ Þ~ûm¡zA$©k¼oµjT¡jÉ Àº<õÔSòÒK/I__ßVO¯×h4}ŒÀŽ“ Rxèú£?ú#±ÌÝ?üÃ?”–ÄRk`Ú/e„Ãaù“?ù…Lss³üÞïýžð³‘I—ÑH4÷ƹvuŸ;»DýÎÆ€Ì-Š|ñ ‘ù#!.2ñˆ\úûÚÇÛ<"Í/‰œâùÿPå 6µÊÿø_ÿ™$¢)¾)ñ¾Ü½‰»%8…äÄ‹—ý¢#)þtô:eÂñ¹ŒF'Ô±™|JÞ¾ó2÷ÖUõxè8+ÿÝ ÿkeÛz+œ úÓ·þ‡õ²Uöë2vVƒ]O Ï_­ôÑz+ É™Mõ¹“íçtë‹ý«_«Åjvbn#ZgÑhv3Ç>_'/LIh.½Ü#¸V¥1¹ W[H ƒ¾ÊE¹¡IFè˜LÊcoOÉ|—W†O6öݸVuô6€F`sÂ¥aô¥çnéèácòÈà#ÒÑÚ%nJä— 4ˆS‘€É#©Ð{Z­»¥T–¼·Ð½lt¦4¹ªU`°¶ÀØY‘üöøÔýH™§«Ô †2(Ž €‰Þ×DÀ"®fµBý†œ;”KÀ< Õ‰\lBÝ`iª¡Dö›>ªÕDƒD\â˜ß³àw@ ì  d‚› ðlöøâ t‚sèg¶ÙEU_Õ—P/0Æ• ÐJ+ƈR0À: ݪá,¼Z*ÊãœÛé½oÊpÜqQ<8œÝ$3lS–dJ''drè¦Ä!®‘«ËÀêjë—àÀ³âï}DlÌ“‚À´Úõ‘EÿÏ'ÃÒäö‰ßåCþ{Óãk]6Œ+ µl\59aÀwÙÑ%˜/²´ƒlà†ÂAQ’P¯ˆÅ¡n€yï$È+4“|ÀÐ ©TŸ iÿ #!T’ ÷ƒ¡ñë  t @4°c|tÛ¤!Bж·â„m*Bi¡”Ѝ±Å)V(p¬Xx-áÚáøQd—*u‚Bdca$Xžá8fq­Ù@h(y‚XG¸Ž·òýe“(ƒa:¶˜Ö*£”Àü ë‹°/V_+ªBCÆÜÓeØbéõî@tuuI{{»ô÷÷+þ»ï¾«Ô hܯ‡LS_MîÅ29/ÌerrRXŸóçÏKÊ!:i4€F ÷žšjí݆m|Àþì³ÏTI^<@gË1ÊYô~)ƒñL¬ÚÚÚ„ßtFt÷ŸoW÷¹ýÁ7bfD$òŽˆñ>ƒ¼¤¤‡° K­dÇ‹fË×DÏTöÚñ2~¼ëœ”ºJr¼ïŒY9ŸÇá““]çåhÛÙʶõVa`šÿ|½l•ýºŒÝ‡Õc}/nªÏý½™>y;åLϳºŒÊU°úŠÆjãׇÆjg±ŠFX§=€=W”Ž©„ôAí¨s2.ÁpV\ÉœØó†·zÎi•„ß!Km™è÷ËØ@@"!ˆÌÉû=Ýz]ùf„-8ùÙ¼tÅW'ÀCM~ù—îixåD=¦ðI(À®|ë["?ü¡ñp’XpøzDŽ^ ËÄá€dñì©“F@#°ó3V)Fí’c*-¯Ì»uUê±³çåıSÒÖÒ€6oêNF¹uT‚ANY{iì…œ~­Ð”&¾ÄOf+Iã°Å²Ê”ßCZ†U;âÆ+¬@ְ ê€Â¤ÝI2È¥”Ú€³’œ»#ÙØ¬d&¤ CÅŠ0æ7 Õ$Äcgÿb,¨1A¢T ÜP2°£®(¸FÁåk‚ýÛ[/B,Àhl¥ªAÕðQÆÓÊ ¨ª,ÆG‰Ä&ä¯<~”®|7r`>Ï/<†ŸK.çµÂ¨>zås™Ÿ—4 ˜E„@¨'y{OKèÔkâ±Àæ0ˆ•óÔ¸>Âñ9™¹-ó‘)¥Bi¡Àï "\@+ŒîZ<øtƒ cƒq}Ýk…ÙqÚ;“xŒ1Ñ ‡´µu€(QPäν%A&ˆ±¯# ’Á ‚õD:ðš%‰AÙ€Nq2,pDzAÔk†A4 .c³n„O¸²íöI{k·œE¸ˆƒ¡.ñá¹ÄJƒ?‰8ì{&t¾"+ß–ÿ嵓5æÀJ˜ƒ« =\k&oeÙ¼†Á¥|îe;7ùe2x-c@÷L5†qîeƒx“e58;ÃÜttt`|´ÉÁƒ¹à½÷Þ“ .Èôô´/ .rC§[ZZ.¬C!=tÒh4@-Vyè•UoÓh4{¾Nà½éÓÛ«ÔÙwøC óÅoEÂ+³4Á«ƒKu¢Áßsl4€F@# Ð’ Ý\”Çßž–¾ÛQñE³âFø${¦(¶ŒAå‰Ì"7 ˆ­œsY%éuÈb‡[®?Ú&Ÿ}©KÂP@Òio#Ð3“¾¡˜«¶äÙgEþõ¿ÅN53rÒöÚ5‘ÿØÜ¢>ݧÐw'&­ÓI™:ä_¶OÑh¶bÒ& ø”Âýï©ãkŸ<‡å¬îÀ ¹{¾{ê´s0t‚½ÊóÚ¬‰³¹ÎÔôùÈIØ'óP3ˆ!„” ’K’[‚L|Q‘Ìc¶òi £.kxJ¨Ð Шϱb…ñÛévañ"t¼ÏÕ§Gœ0^Û=M0€Ã‹ °xCïæð LÖ@"»vYfîÞ£; Ó¦{“ ¶žý†øúW  dxį“f–ÆedvXf¢ãpjC¹Š´#²_iû¸"øØ`P·Ã"îsùÅçkÛ/~O‹xApƒ´`-{ݯS”",¨ð UÕRDƒÖ¼â­àa|”ÀCb‹l6-‘XFÝE¥h@2B*“”,ðÉ<ð ™…CÿèìˆÜ»%§”玞“v´US×ëÝÆìgˆ  Z[[¥§§Gž{î9¹xñ¢¼ñÆ266¦))isg‰"|‡N€F@# X 'ð¥êÿøUýì`â ñÕè´_ʃ¬Ø&¿¿ñ“KºŒF¾Ý¾ýÒç+‘΃Tp{,왕{Ìï`.;þY’¥÷°A¿2™¨èO€F@# Ðh6†€7žSõO½1!IqL`©åx…m|Ò°arØ™)HS4'­³)åÕÞ;“w¾Þ'wO4kÕ‚Á¾+suL&¤˪‰2̈¡+Ç/'ðªÏQb¶† ]Ë\JZNA“ VEVïÐl ŘMòKN8°ãZ.;{o¶`_³KzzHÿÑ~ñÓÛ¼€Ð ¦•L/`ÓP Ã¥…ÞÕH†2A:(ÁÀ-eysÂ)KnxÃGFOzS+C²éK/så­‹s=$e„ãó2³8.N(4xœ˜3sú¥© ä ;BB(oûceC?p±»1GYîHH  Ðoð´ÎƒXPD¨Š\tV2P4Èe¢ L>¢)ioŒ¸4$õ­¶ˆr$·*• ÐR \@UÆ•ÓåV¡œXw4ùA4pDä©^éJÁ+ƒfº™Û1Þ•±cД2 ô6W˜`{yªÚÁs\¬å!srGU|NŠÏÎÊÌð„ǽ^B ²ö-ƒ¯IàØ—Ä#x }Réƒiµëcxúº Ï I }U€G¾I(à1ùb}k*„p‹Hç³ÆgA0°‹ƒêh+UEZ íp7‹ÛÝO 0¾,¼IH Ñ UÆUØæ¡T@bE.•<ÆU<™$ê“A5‘J‚d•h4"ét ʉ X¦(2ÃLxj Y9u䌴Û1 z…„$b[Œ/aÜÔßæGÝÙ×HV›1°nq‘$kܯ ¸>„`%6tØvV†Uà5eÞïx’:ÓZeXT¸Ü„Ï`H¼‡µ«³ÀxïÝ¡PH-$<óÌ3òñÇË›o¾)·oßÞ1rÁl²>µF@# ÐìavœT@"™xfr‚YÛè´_Êpƒqü ±Òe4zôíþóí—>_‰4_eS˜wáR;1Ç¢¤‹|ñþ߯žaÅ]Ææ°jEx‚Íôãn¦?˜ÌØlŸë26~}h¬4V+n˾aI(aÒ¯ÙÓ*Ù|Z¸/ïfO°e•×_Š€;™—'.LÈóÿ4*¡Ù´’«ßL”·,fåÌG³âÈä_ì—»'!‰¯ÓžCÀÈKp!-TX51Ü&‰a¸? $fejJM¼¯ÜÉqæA 4C vH.†©3 êLþv·„º|boÎËXì²DóSÒæl‘#/y$«<å " º*U™À(ÅGR­€4ø*ƒöã}ÐR6š™=u(¾$+))sÔ}Ÿ—1倛ã_Àã<¬lˆ6‚ãÊû½!iF\uJÛ·øÚÄG#§i<'XÆÊ)Êë#ÙáÅ °ƒ]ÒÄ©ô=Ï¥¯òèŒdÂð2†33?¬ÈXba«‰†gz·c4,#£)UƒŒS(ØQ Úíjòhàƒ²ë ŸàI‹}Vq€„`Áü«RTY `Á¸Rã ãJ‘@X¨‚,R%æ7Iþ¯Œ;’WjæÇ¹qŒÞöKSÓ2qû–ÄÂ0”2lËÝ\r!ÌApàYñ÷=…† Q×5®·'/#äÁêÆbƒeæ"/ŠÖQÅíˆ$ÄbÇß9_â÷>¡M©(¢Ä!bºkj%Îò%ï$¶¶’øñ¼PÀ|P ! ¨b‘‡RF&“¹ Ž )¥dΦ$]’hK ¡¨¼°Á¶­Dœ‘7¨„a™À£¿¥z¨u@ªX£¿AÔ1ýr, wÜKUÏk! Â$ ($´”‚»B˜×ª&Ü;ÁæÖÖ(ƒD#UÕÉ$Ïl®”mÏÝÜÜ,\ºººä©§ž’Ï?ÿ\)\ƒªUža³vQâxã¢ß‡wQ§èªh4m@€O;ž‘`e£t+Yý»ÆjulöëžýÒçÕýcÃË]סG¥­çTõæûÖ£©´¼ùöG÷mßÙ ¿€IЧ¾&ý­'Äë €ïR¬øÕê•)¨@y«í¾oû–c÷m[oƒ.c=„îíß V”¼{Ðý¡ËØøõ¡±ÒXÝ»’k¬aÒ¤€IT+fL—ÒsâuøÕ=zY,ä‡éMû NÀŸ¼4'OÿdBZgÒÆ„|Mt¥ râ³YjóH¤Í-‹øÔio!XÊ€ ï·µì"ÝÝ‚ÙaÃð±²y““"\j$޵5Ï[ã½I# h°… NCÈÉW¦6yúPŸO‚sãl‚‘Ë‚çYx瓲h™Ã+!w«tZ ±,¿ï­V–q“1o5Ës-ÿV]Å{ùÍ5î]-ÿÞ,ãúØ%›»#±tXtÜŠ´”@Œp(ðyÍ ƒ¦ ÆS¿7#°A4h‚Øû­›žèøGÕ‡{im¬,˜w°;a¨wºÅQ6”º[I¾çŒ2¼àuN2Aå§QÇ ³9HíÒK’OÅB4`]ð °|ƒGbRÑÒ0@ÇA4 QÅF¢œº¨hàÁÀ½‘² s”gvœAí¡±*hûoGÛTRN]œ—ÎÉäê„~¿!]*/¿,˜ 4$ïé]43#ò£‰¼÷‘áöFbI weñË›øÝÇDjm—ÀmÄ|7Ôa›[«( á*ÆZ™H* RA­D•ªÔH]ÒXj¦‡ûhãVËÜêñ5;[oÜnŠIbžÛ÷¿ùu lv‹{|P(€QÑcS¦jÓ²¦¤Öa”L!B"“™Ôœ½mÒá; A ÊnÀ†Œ»q°ÀÀX¢a`±ãËF3x0—(K£…’âô¦’Ï+ÂWä$Å}åT¢ÇqÙø¾—ËȤ£24IûùÛkŒ«¥íC"ß0D‚m€È ’Gdƒ&o3H­ÊëšTè;#m+†°£Ø“Ùnȱ{»O*A =2@IDAT1©~ôW!‚ r±9 ?ŸÑ’û¥Ä³ï6óYM40SŠh/Ÿl Ÿ`·©p ÑJ ôwAÝ€d†W°{@ g9¥ˆÁ±EIy—Õ,C@Ï~Þ™8Þ×ò@!™’‰«—efänÝáxÊæ“/KðÐãâ€Ú„êâĶ Õº>f–Æedú–ÌD&$ ¯v˜ÅUÞñ§zŒ™ç7ÆHøç$ùd!9àå¯È,ØÖ„PA„Op€Ô²V;Ôùp3ü€ ãÆlK ‚dsy¹;vWƦÆ%…°Sõ¤ÓG•gμ,'ºAn‚ÒF12ƒ.ÆøÑI)¡€lcAÈ ð¶°ÿñÝL(ƒ0“ ×bQ¨u«' %8Æ Ã L%¨+ÓñÊýGm¬óÏše¤xƒŽð„ªàx7Ô ªÆkån÷a>\\¨\pæÌ¹uë–"|òÉ'‡{ù¦7nàvZ>øà¼ò¼,_ùÊW”Ê‚V.X½Sfþ…D4À^FÀxúÚË-Ðu×h45à ¯§ 2‡Æ[+¥K÷^ˆÖÊ·]ûò ?t\ ¶ p]ŽF@# ¨NK2ö(NH;m5dÍë<·>ìÁ#`EŒÚæ…”ôÞ‰*r@ó\R|±œ¸±æsŸ9‡M’‡,†<2qØ/Ó}²Øî‘ƒ·#ÒsIlù5&oŸxBäßþ[‘/Ù¼Çd¦Jœü£G &᪠ɭÓ)uÞ›çZ%á¿ç!悤~çx\zîÆ¤c*!…Œx!·oÏ”q) CU¬Å)óM2qÄ/Sðˆµ!´B+ˆ¥¬¸R˜€F[‹:N»m ¹‘×#qÄö.Z:YßÉJÎï‹f!ã òì·JÆk—¥ÊÀD8òôÝŠH×xL…n`ÝxÞT“]"­.™îõÉèñf™íñJØ™‰-? ï½w£Ò=š€ºCRË™ÎÃØ€ëÈaÁ9€s«[fQÿ±£‰„\â‹ä¤u6)MèGqÑ1oÒç”H‰/Âó7í5žãB¢ØøÃiqb½.ï~À‘‡0…sFP—DñÓË™m©õD™\ÖL$Ô"ÐøB• j¤ŒÞ´PBxêqé˜Hªrh£ê·Uâ—,tyd²ß/ãX8qÞ:“Ry]Ÿ`Çxf;2.»Äš1Vº½ª?Ø×ŠÐÍá”xãÆ˜"ÆEXÖ2+ñ ÎÛéUXhm«‘؇-óii™KãYqf`ÔDyp–œÓªÆòƯ›œ©í¼âÛÓ$Óßñ Ãæý`úëî@ ³I E†;Xã6¿VmÝ>\»^ B}ÆûôjÜ% #—d>&áÔ l^is‡¤ÝÓrÄ6W\ƒ§§¹Jê’4®Ë ŽÙ'I Dã ~ÜE#Zµ„yõ¸c˜”O5{« å>uM&G%MÙwÞÀ6‘j­ÖˆÌCEÀ%äÓmÀ†ö>}[<ÍâÅü‚ß²Ó‡ÛÜæúÃc«Ï‹•„þ ‚§ã˜ Jµ@ ÓÏ>Ì&Ã*|B.¹(9’â‹*oåØ-¬Tˆ8G¸1¥ãP4cl¡NVü®SßévbAÈÈð;›šÄéñІM†O°Á{Þ†í(ð˜JR¤‚òEC È”±¹™º%áq´£Ny~$ö[_“Àѧ@þî4žsÌ“@£úýþ±; Uˆ¡É+I-*¯þÍŽJ›¶°R=Æ’B%‘¥DX¦í$³ˆô·ÈFH_ƒyÜâù¸|zùSºƒPI¨aÔI(xéüëòÌé—¤«µÏ ¸/(’Æaá1\>ÔÏs 1X2¤’Êõ!@P‰ä‡Ñ œ|¸¨¤Æˆ1NŠ}Wg}–O»V™(î‰ [‡P'nŽI¶co›@< ,Ý ¼yA¦é‹C­cNúA2 .¦Å‘Æ9pí°O™X‡êÆñÃq†ñþæ#!¹z¾] ˜Ç‹±tèÆ¢ ~º Ý Í@ha©ÜaGV.ìK$Õ/°ä1Fx=fІh³c, Wo“»'ÐG¨¯áîѸœùõù‡bÁsòZ ý‰uË¡ŸsÀ< yp‘$QiÆBÎi1°Å˜œ1à:®M’úoF!)¢M¥ÎÀ“ؘ÷’ˆyåúDÿÈ0~8(7k•‘cAE¦auÚ=Âxc\PPgjy§$«&ô· cVÙÓ6p®<Œü\’x³‹2•˜”æT‡´J³»MIö¯zÏÔ}¯|›W+yüFFuísuµüÜ·‹Ê0<ÐoÃ}¼¡è4¸g‹i%"oüaÃa¶.ÊLlFõ‰6YÍð ^^ýP6ð j¥w>Ó±²ÀÈisƒ BˆY$ <¼= ›¨ð 0òæ³xÞé$¹G4X„Æé†+¨ÒI ¬Q,´ÅâÙÊ<yýBÁ‚$Õ \>…h`Á=φßhŽ#k&'KS2}gH¢³3’Wê ÆoDU1뮺à$xVü}A5!(¥TtY»k]†Ã™»- ä-6Àx½n%7‘Á$œì:!=Í™a7iÆYÖ¹³½0ž–ëÀõîøˆ¤R4èoWöóÏý  ^’P°ýk•b $'aÁ [~Új"6ǺÊÏìU÷ŸÕò«„ò»yŽz?×(£„z‘h…_b£•Roa»ç8®½¾¾>E.ÀûÆ«¯¾*o½õ–¼ûî»åså¤IH* Á`||\Õçé§Ÿ–W^y\j©uª  åoþæoðŠØ&ì? tÒh4{ ãÍ{¯ÕZ×W# ÐìS(½Ø<¼O[§›¥Ðhöœ¬ÌaZ§Ý€Ë3gåÑwg¤a ü‘ ˆœ4]=Ñ i…1’Iz‡·"k7Œïœº]S¥±‹×5"«Ø·Ë˦Áëß¹-O^˜TÎv¨ °\k%/iµ@@u Œ§I%KByfŸüt^‘©@@%Óº‘s˜yx µ\è Þ¼–öé¤R4 9€^ö-ØF’=Âk%uËíXhh^—°Q>I7 ÛT ª&X‡F¦^ô_[”/žî”^îUë+ÏïF›‰;É«¦H_3ü¼:ïK ‡AR'¿k$=¸¬–Ìþ'¾þ¥ÕrÝ¿„²Vëó>z` ï¿‘k‡åÚùé‹Éc¸ŽÚ'Š”CrÉz‰$„ƒ œøl^áÉü$%ô‚tÂ1BÃüZã$ ;`°Ã#ÎMgOTÚ¦,J]à8Î9 rÉÇ/ôÈT2šäñw¦6U¿Zõg™®4—¬RÖÜsÊ&y-H®¡ ÄšuÆx·sÁõËkCÐÍÖ¤ôÇ@š•ÔùÔyèT ˆeCd­ŠèmÛƒ~ P'ÈE1EVg¸V45Š”N\P_1Œ«›¯>=ŽMõ‚D!) ‰ñ¹‚Òêí”VO»¸ Œd…7»òº…’û%Äm§÷¶!O_¶ž‘8c´qA>JØ›F8zøòHê˜r5•qYÂ^í§gï.+cx~H†gnK,Ù6ô<0Ƀ|h¤åáøþn‡·y…h©õ6úÌ¥?uÜfúê…$/°?씋cÝÁî*¢n„™ˆÓ’‰LI¤ƒy„ˆÎÁÀkÖ³\Ý:?H:) |Ø !iPVµÀj^ñ4@[ð¬cƒ1Œê.o“x bàt•Ã'xÜ™Ÿ•ðÔ´¤qØv¢çÛlb¸ˆàá§Å{à ˆ Ö§Á}±›ÉwhêÆºá06[F槺ٱÞÓP)8( {É«u£×`„;S#rcè†L¨‘Îð¹oó¸öwõËGÎËcK³¤U ÔƒÊסÂp½L’)±ÿ² Ã2r[½ãþúƒcax®#dþªõbù©ˆÂûÛ‰{”º—0,×MŽÊ]ߟµÊ°2ìÆ\õ}×SùîX_»ì(z¹÷@«££CŽ9¢B¼ýöÛÊ Oå€z®¹­6‘ĬùùyE.˜„• yä¶Ê6¾#=äéÀ*dÄ_þå_Êïÿþï+E‡‡Ý|€F`" I{°Ót•5ý‹^Ñ[¯JZnÿ6U·L# Ðì è•czèì‹í³FЫ»w8"ÏÿÓ¨R†³Ê£ºÞf®fà_v¾VÐhDÆdß} qG•Ü} #2½Ði|¥Ì='‰MéûαŠ4„’„àVÞm[~±¡)´'ßV°ÝʱŌU ‡0vÔI(°A•#Øã“ÔlìP\QFºX¯òðTcIæâ²”š—  Z¡Óß'>o‡’ç‡u†3jÊ×´I`X„,Œz42Sk$(Ë0)ãa%?+Z®,¼ MC \¨qaì" Ê€¤ ̧‚ܲ`Ñ 2Tùë´#›OÊí¹!]Wxì„ÁŒØ™Éô87¿ós ¡BGž7bË[KA[öBÝ"V*|Œ÷$†8ÊzwÇat<Õñ½é1—¹`LÒKã0ä甚A!òˆ/ß(²Aä.EɬúùMÇc_@XŒ/ 00* uªKÿG¥yàKâ™B©8P€´ÚØ ÉÄÂ]™ŽN!FšOç*ÿnúòwHç€t‡úÅ rA¹Ih”(FUk\ƒH™\^.]»,7ï\“H$"9ôCåšßD#OyTžÂr¼­OøDc¡ŒþÆ}uR!%¸u2ï%T/HÂ>‡ß@ŽÂ %`© ’ªˆ%^$cð¼kaA … ®q”A‚yîÊÁ›_Y³Œeí0ÆŽÁÙ}ãbó-_~„ÄžÎÎNåù~èÐ!y饗ä½÷Þ“7ß|Sfggw„\Àûs8V É|ðœÿüs¥Xð[¿õ[Ò„3:i4½„€&ì¥ÞÒuÕhÖE`Ù+Bå-mÝÃvOÔ™Ì4€F`ï °ì·gïT{ß×”J'/ÍÉËÿ߈ôÀ»z=e‚†B#2<‡îÍWy#2¸”‘ßë‰í Ñw?$_4'çßšBh§¼ûµ¾e’õ*ôÁz†fs<Ôƒ*{ QE‚ËVI¡Ùrìå­œhű ™À% <3dŠ,»î+ëÜÑ ßU¢¾z@…GØuÝç*&aü\´K1©±:o½n„ñwx%ØæmŽáʬbW„A: £z&Ÿ’D.&s©9 ¸[¤Õß+mÞnxµ»`v¬ñ /ak’.–j#«ªc­zâ¾²(@Bq™ðRZâPbYЧàR6f@Tà§×éB¤x-9ñ»,âE¨CȽÜðuÊ0HÕréf}ÌÏ{†“ 22G¦à•Ÿ†as7ŒMô®ÐAqÚá™]kÔÙ«a¥ˆ4#9| 4‚@âô„ÄÛqTm+ÁØXDgR‹ !²KP6H,4”h@ïä"ÂÉÖ~"Tù§õ‘×Å×}Jœ^x›ÛIa©J5ÆÕ(È&C“—%’XÄØ„¼z¬Wº“«N9¢DŸv|jŽUAã4ûœ×o>}Gnݺ!q(E¨kºŽÆ`9ÜÉÕ\*Ä%3òŸ6öpUÂäBǯKÖö!j:¤^Ò\ˆo¸Z2Ûñù•O+Y²…´|8ò£Ê÷•+9x‰Å3Ãè(ä_•ÞòÚ!.¦:‡ž Ï<#røðòýæ7J3ïã›[ % Ï/—áѳfâd/É OúÈXªÏ9bU¼3á¥ÃÈ;<,xºLθR.Õˆ<Ô¹éåŠ÷µ˜ÊÌ)Syá‘cÇ YâòÃåWÉ$WÎk®lGÌþ$Î,o³‰x²?à h&¼ôùpF&ù ÝÜ ÏuÃ+¾²¡Ö ûŒK­´ÉdÙ!;bÆ1Â~÷C1‹ò´—WxïVclYej|aý0™­ÆC>ðZà6¼äð‹5Z±‰ç ÒÇ™3ÆçXDìY¥ú)_EÀ`††Dð.]}ÎuU1̱Ýß/âŽã”ã–×CžšLÌÃk ñËÆ6&}åâÅÚ× ãùÌ÷Ö›êÄ53ê}¿¼TÝC,0ÌRÁᙟL@©À Å‚^) &¹NÛƒ@1n“Ü‚ÞÝ0p•ê+³ ýÖÜ듦äïáÕ_Ï-g3%ÓXš+Â=‘T>!‹T/pÞ–O‡´{:Å¢Rüª"4R޼rRE\Wa`èS›•D¿a€³`=œ´ÊäBR"™¤DS( J#YüîYÙ8àTÀqäŒÙðÝ…;?­%XÅׄ7~7Œ¦V !„ÏÕ¨$𼦱’ë% ¼–y^#¦IÂ’ú}Ñ€u-‡^˜|dvHfàž…œún4wµôʶÃÒ I{7=¤¡ÀzV·Cµ¿ŽþØ V,Ãêñ‹ÅݤP%é€2ó¥âq·öK †äB.…ïÀxg¢3P6•,HyàœƒªÁNªoÙàß2øšŽ>#v¾iX_oì^ÿBFænK"ÆÓj`ï¢?ƒ=g¤d?ÂbØx}"­u š}±-™š“ë·¯ÉðÝ;’LJVõ4íçŸû—òÄà ÒÞÒ)V¨ZsøÝÃo´U©¿;%^_ÜNÜqšŠ ±"nŒ+¨ ¨û¯Ír*¦ãŠ<À¯V*”êX¡FPĽÁR« ª#4 ¯Ö,ãœ÷+†q±¸p`$©v˜÷›rý÷ã‡j!$„B!<ÚõʳÏ>+ü±üô§?Å#È(^c ;ÒìÞ©¸\póæMeXÿÆ7¾!çÎÃã—q]ìHÅv Ðcxb›©:òï|GõÓY>ê¤Ðhö÷žöH…ùã÷É'ŸÈw¿û]¼Øåå—_n8©`»Ê¸ˆ‰‰ïÿûÊ`úꫯ6œTÅ$ .cc[cµ1œ˜ëAceÅ Š?Ð!a ŠÙ%Y¸ü¿HO&ÖKÎ.)öþï²ü]•“çi v­z”ÙŽøÞßWò¤'î×þïÊ÷•+~HMþÖSÿ®²9‘ŒÉÔÕ˜\©ÀRÁÉÎ'å냿RÙŸ…'É )¼?üÏ•më­øƒñ_>öß®—Mï×h4]„@ñŽ×úýèm>*ßÕªö–Oä¿È?ÔÚ¥·Õ½¡^žW„‚ΉøêÒô”è¥ñï7~Cäç~Î0fÒ8HC=¤)•Q”ò²4®Ò Jã(¤Då[߸ÚÜ«Ùc‰ü.ú÷é§1g‰‰Ù@@ Czoõg³?â˜,/§ž‘¸ôßX’áÁfÈìÃ`ޤ”  `ÕDÌI(¨5൥Œä$®¬—tÿÿüÏ‹ü›cŒMùˆ#Ç ÇüŸþ©@Ÿu½$Ž89Ìs0±}Äó?ÿçeD cgÕ_áÙw¿ø‹÷Ɖ=$'G’8ÎH`¿@6V]7.†ûªSÝ·Ê1ÊqÇq±rlÿû/òOÿ$BRѯÿºq/ ±håØ&™„€êĺ=ú¨¯‰/}ÉÓ¬3¯M.Ä€õfI.˜™a}¿ýíÊ=„ªTo8ýѬLôdâî:=Xp[+Æí’[r N8ÆV)Ôç“@«[\0žÛì8OyÈ×yºMV€×pªˆ° .ÆÓK2•€«YÚƒA2è‚·nÇ5‚4ÕÝ©8Ε†ŠŠW>^å¸÷ÔÉá6q/@HÀûñ"ˆ|ûN(“Ä‚–@ÎñžïuAáÀ&n‡Ë0N²^å{…"PÊŸÞ͸YœM2:èW$O{ÊîïFBÁ¡ö£r^õ¦È¸×í€eSuÁfûLøË.X«µÊ° ^t^› ] U ÕçN I¾ç4êŒPY<—2Ñ¡²å_šÜ6¢·û¤øúŸ@؃s!bÜ×»Y(#Ü^‘»P°Hƒ³dž©^Ñß1€1ï…Q»ê~³Ê5höy>““¡ñ!¹~óºLM£|nTáÞ%·µ&Ô_|Vž;ùe †ºq¹¡p¾Q!%x>Ê„£U@ ö Æ0ŽS¡@ NlÞf£|^¯<¦œJI0iÀg²âwy9V-k•‘ÃoyHk–[0Ê ÁuŸêÅÔè°Õ’'—<‹>÷”OA~ïtÖ¤£ÕN¤ÞY¸\p÷î]p8ÉK/½$çÏŸÇ£ž‚D¥†A`¢ŠÄ_üÅ_ÈüÁàÑ¿Ç:i4=€í÷\Šá…|ñHI* „΃HÛQëÎvðGóA´ƒ¬^]ÆÆF‡Æjc81׃ÆÊéÆîÃOJxöÿgïM€ã¸®,Ñ[ª€BaßH€ À}ßDR”Hе[–-K¶e·—n¯Ó3Ó=ã˜è螎˜è‰é˜ˆ=1?fþÿÝãžioí¶åݲdK²¬]"%’"%Šû ÜûŽÚÿ9/+ ‰DV¡ª°’ÊK&ª*ë­÷½ÌÊ÷î¹ç^”v)Î]¼"O9©0f`'b³¶_»Èå¶x°ˆ©©ß˜2ŸÞzVjÉH+Ù=ŒÍ¾Â%\iAuò[äÇ.Î <…ã¾çÏde& K¼‰ÄçæÁÞÜû³­[¶l d®66Óý~ð·Ãøûa.™ 5[¦G‹j® ÈýÏ\–´€zRÓxù¥/ Ê"UUØ 5lö›CÏm"iÌ_¹R3bL8i¬¤Çþ“OjiŒù¬Þ³^f!Ë€›žfáæ-A _ýªfì¤7¹•7ÛÈ>Ð[šÆQ‚h½ÿ~ÁØ7záÓj¶kûvK“п§Q”›|Øì“?û³1û® lAfaÝÆ>ÐÈ>S} ~Øç}û¬ë0·-Õç·ßNxÐŽ% X¥æú”vŒJëbø†"RÜ”“qmãxY ¿#°„m6ßCÞ ¯áÅúqôÚ +ýMã¹xØ!‘@ðÞ:s*Ùcy1¨e50~Â3\{s*jZ2ј‚1˜‡b/í’ü¼")÷×HUa-Þ`À7õU± ŒÝ¯áÂu€¦Úze`æ!\ýrN§˜×­ | àDJº,híª6ÁÀ6:Áï?B&û}Ràu‹?àN hlÄ}ãÜÕcÒÒuy~{ ×o–z€ üÞ"Ü64+½ú1¦=¼ã=bìDBCx±•PÝSð[;!Æfêp`ï…¡3(úS4XÀÍ Â$ô*öðp·:2 ƒÙ಄û;Ðä4¿}ªÄÌÿ dånñV.ÑŒÝú½tB¿Q&tÕ:ÐðÊuil—Q€!æ#  ,P% ÕËdAYá0ÒŒyϧ/’ÓgNÓÚ%aeüåõ˜¬©].­‘uu«¤¨ Ó/¡P(`\‰¼ö0ÆŠE!†ßuHb äS`q©µ˜*=> s®Ìݱ²-ÊÌôTš:ÔüD=½.Õu« •ie·vºb<‡ð¨Á3ÖV0ž©]²] Ó0èýØï¢C×±¹n‹­[¶l ذ5pËk ¨gT¶½qCê/ ¤f( “=æÿóÖ(ß­ ìVš Á€GR¼Ó››ÂÏ4Òh™«pÓ–@iz2…F{2(ÐÏ ¶tFK=½¤IŸùïþ²€ƒ„¡CO¢¼Ïé1m¿é¡m 0 ½ÕyžL 4³faàqd¤£WIX½àÿüϵ° 3ÝmiàMe”6·Ûê3A¤Ú7°èɘ_d'hE„"€YxOOó”BòÀv‚ÜÁð©d6ÇŸ<^SÉ&qžsŽcóSyÙ'¿0½áZvÍš‰€&£É`a'‘ÌÍp ò'šqžï93ûyí1?Ù¤éì´Îjnó: [ÉOˆ€‚7åÜ& ˆ1¬ó|ýë"_ùЦŽU&¢ßC2å ô…¤²uXò‡Â2Ïw[¦_DúÜKD-®É ªôÂÛ¾ª@Š+òÅ@AÒH—AÞÙH/ö‚‘Ȱ »¥­¿EŠóˤ²`¡”ø«¢À«5ƒ„ Bœ¿Ú)Íí}2 ïè¤QO0ņGš‰aDšô:ƒÒÑ7 ïy°€%@´¬øÂhG«t ^…Áxt^Œ•úÂÕÒP±T9hªä<´3‰Ó#ZöA×#›4p" ¢úoƒa<’ç¨*ÆŒO€4Tzèk¦ë wºÀI#ž_¢ Å>€ªü48C¢ÁA‰Ñ M‚`2ˆXKAtÌ#™ƒ ÐwO^!À»¤`ázñWƒY¿ÔI]µuÊ…›¤õQès> jJÉòÚµR‰ð €E±±Å~M2æt| GäàÑwäÒå‹204<ÛØu£ Ã?Û×ì–Ý+·É‚â*ñbL/}2A!¨áT˜Î]ÌÃ8B8ðAÊ(K$¤Í_¦c8¨‡š—8Åyœtu(=¿ž!‡×´u0¯A7ÛÊë’£.µÌ·Ç߀œ<ªt$Ý>Ùd. ƒA˜Ï¿s \½zU È ðòË/+&çõµæÇ³Þ|û„¶k4†Å&¨€Àލ;wîL²LG]v¶l ؘ ŒýâÏDé3P&Ù îµàZzAf‚f¶êØX4hòr&úA°‚]Gf“ÐÖUfzbª™Ö•TˆõËwIÝòríÂéÆûkGápG$K`Öæ`g”ýLJ°ðú½êˆÏ_*[÷þ)öÐSoðéý¨­¯‘Cÿ׋™+ÀN9©¸°çvŠ-¶rÒ®é(8‡°‰âÂÆDAèRÓ\ËÉ:rÍ—,À~ckÀÖÀ­®â>×]î—ï´‰ ^––BÁ–-"ÿá?ˆ44X&I{’†WIÃN¡Á•‡Ùp¯}›Ù_B[Z4è1ßø†Èž=½Ætæ÷4VÒóœvü`LCC6 Úf!ƒ³psŸ1æï»ÏÚèÊôz¼{]/z Á>0¿Ù`­§±z͵4ÖZ…°ª#Õ9²XQ?´°ÞѨð ¨ÐÝØdO'4f[é”y8é@³9þœƒì77faØ ‚f¬€(zZ98ç¬Ö*Ty³šãôå/ká6¨§\„†‚|¾øE-LÃ,XIª¹Í´»v‰ ¡% €ß3ô lj!F(3”İ)¹Ì5†B`™¦k…lþþ° Ú MÑÓû—Ì‘ž<„×܉áÈAü%yR@Aa™OÜ ô×íT9•ÌÂðQ„ÀˆÂ™Ð8§b–çÖÄd¹ôŒªc8Ô/݃­`(‘òÂR寅ç4b£‹OºFår{·\ï½:à ̎Ä0߃ºÏÀöÒãîCÈ„N‰IÀ¼¿ÎV‹2ï7 Æu•‹¥ª B¼ü} ÔDÃ%ÁlœX¿8\0̪¦ãsÂàJPE<„gö›†fвÃâ©*fìzꕱU›ÊhJc.¿s\ hœxüÅ #ìG¹D«–Hœ@€Xî8¦b´÷º„‡º%Òß.±Q„ Âh2/× ±(g Z|%Õâ)ªWQ8IQ9™®Î‚½âjÇ%°i T&óPVƒ½¢®¼A ÈpaPWñ Æ<‚ûÀÀp¿;vDÎ7“aõ›“ÛütçgdëêÝRYT†6$öÄ€–)±`?~Ó0oqŸp"¬`½Íð.¨ƒó0~£× á00€#‚€jDÐJ.„ýPéYp†u0lX0Ï$m?À¡„Ïç ÈÊb eüê sÁ€B/€íéM0S½æ´Q>§Ì0Dm+ž¿É&Ëö:tHÙL6ƒí¬ϧ·¸`%€±/½ôRRßÃx.äg2JðáÉô>ceWikÀÖ€­[TÀ!Ói{frøf£ÒÝð˜)á®]GfÚµu•™ž˜jæuå¢Ò…²ë‘¿’çÚ¿.#ý7¥̰/¼ Ç38A-«m× Xôco¯ß¹,rµ `)ðúrÇž¯KÝRlb§½ à Ӥ²¿ÊTD×^mk‘_>÷´ Ž bÓª@î¼c§ìÙ„-¶&ѽ2zúºäÝ£û¥éÊEéíéD|Øî7NÄ^õ˪åëeç¶=RQÃArÍg(Â~kkÀÖÀm¤"Ķ_è¦Áã7¥44ˆüû¯yU›Ñ“úÐâ«“–ž›©4vÂSFé|—.œi´·2Ü›ËN÷ÞAòþûØå5! ¡tïÞÉñ4j˜­[©ÚEFH-¼ðU_­Œ»ì?%ݺ¥¹YÓ Û¢ ©ói4ž Á<<ÌÀŒ\úÀrŒzÔÛ’Íë™3Éx÷³a;ZÛ“—âîQuLLc8“ΘMà癕Ìöø“‚ ‚¥K'¶† gR lj€ÄÄ ÎïcÇÆŹô¹Ïia=îÀ,l C&¼‹7d¸]¯º8¯ŒÂ¹ßØ(²q£Èï~g͈Àynn[±oèu˜ç6¯I†M!{‡Y˜ö…€vÞ¯6„,l;äðÂ4 Õ€gg³äÁ›;/Z1gÎQ¸­ÆÀLîõäî€5#ÔAIu> ©y°›Á œ¸äØ*•-ÿh Þ£¢|Di|EÙN¼:áÁO\­²íñþ˜c|y ƒ½``´[Zû.KI~%¼‘«¤¹›}# Ñã;{¡·elª÷ÜDµN'¼Ýc­h<‘ì3 9(XY·^J +ÅooGÔû¼ÏÁpž598p¦©d+A³ •/‘†ƒlNϯÔoCBÌ¿:øŒäò ìö_4c2š«“üªåÀM„$˽á9³Fz Àø:ÅôŽ„䀷»ƒÌºÑ›ýÕÅBW!èÚ¯øò"€`ø@c4Èp“¸Èç(ö °4T¯h Îö×ÇdcNñK-åRÓy¹z£6u©„ì¤:Ý·ý“r×ú}R(Ô²šT(“¿?#ÌEŽQ2o8ÂÃ$œ ‹€1À _t®€¦ôü˜®UEžlOe[‡ñšË¶®Û4½á¹ÈpLæ‚Uˆ>øàƒ \ð.ž¿†È5B¯ý.°Ÿõ€ÉÑGUFö;òŠ ˆÛE*È31«õ¤ýž#ËñìM–n2ìÚbkÀÖ€­ù¨> ØbkÀÖ€­y¥âú5®Ú#ûÿ[yí7#ÃÜ€Uï ÈÉ&8dÍ5Ã# c]3À?Yó:aãίÈÖ}ÿ nØÄ³eÖ4@Z¾¶öVyÿÄalZEÄ äºñgo7P7tTœOl ©ø©³¦áY¨}£ã7Rn@Ì@3¸‰r±ùœ<ÿêoäÂåóe2ê=lrpÑ ›•­7Rûcû>™lA®ù’Ìõ›Ò÷m=GçzÌìúçµèXÒ1,«ŽÁ“*•pc¦±Qäþû5À€1Ù~ò‘ÿñ?4C/½tø°Í6yñE-n;è(•G>ºÐ@øýï v¼4£øŽ¢bÓÓ˜hÞÓÞxC;ø^ÖsäˆÈ‡êg4oñ'ŸÔ(ÙoÞ,̨ª]4ØRò€Æ{¾Ò“:•ÐÛœÆl³ˆº¡ÜÊóšžàFaý×®iÆQ‡i45÷FÚOZ ™ª'Nˆ<ÿ¼ftfù/Ð` $ÃÞX§ñ= ñV}`¡ÿË!•¾•°ŸÔY8¶fa‡×^aÛ,$ès Šb*%¥à÷Ké”ì fIî [Àl?A<¬„,éÂ{pü×­ðéNÌM 稑倞WŸø„ÈŸþ©6wxé¹ÅkáŸþIä•W´pôèg^‡'üÛ;‘ÀŽ9ç°9ÌB6s›×ÛÜÔ$RZª•Ék[Emƒ^g_£€²WþáD~ùK-YMØ.Þ ž{N„`ˆ»ïÖÀœ§V‚îkObV_Úç²Õ@<ìÈ€ W΀—Û!Å ¥¸ €‚÷´°°añÃDɪ£Æ=Ñ;xðSÔ39Øw”LÐ@c/€!à‚î>¨ê}Џ¨ÁØ­ÒÉÿ ý`È×paBð´Ž`QÆ"=Bº÷, u:¯á'÷&ü&f“qòfN[ŠÕ‹6½Q Jáy9Eƒq×8ï[Æû?Óèª^qŸÀø©ëZ¡Cðû¡nyø3îÞ#¯JϤL“¸/²\RÊß"uÐî‚áß žô~ăåÐWXÜDåÁ>IÏ~‘q ]¹YPÖ UE °˜ó ùG°OÔ%ãýØêU`ƒÙ”dÒPµí«G8 ô/1|"(ý˜“úýô¥³rúìIQ»Ð7Ì«®†ªErçŠ;eóÚ=R”ÄÉ,]¨0 c>ßÇ=yÚ³ #}zåxÜ/*d:Ãy¨Þã<Ëàw É©Þrè£^§þš¶¼>Q‡C]Cè+Åxjgì¿ Éµ¶¶äO•À—.Åcò}òw÷wXöôΙŽX#°€mhÇs$C4¹ú°KÕØÉ}¢[Yä ¾»±5‚ó®_¿ŽÇÆç€-ÿ"EKq-ê7”[¹·vÛm ظÝ4€§S[l ذ50ÿ4àÍÈÚíO¯LÞýÃÿƒPïÀ‹F:.˜Ä‰EMIõÙ†ë·VÅðF²eV5À}€ Áj 5s! rSèt*D~˵Ër ý«7šîºƒ*.a9¼æ+˪¤¦z¡¬Y¾AJŠ`XÉPBн.4ÅÆòKÊ0'÷fœðد-ë·`ƒÍí„ ž¾¹Ô|A:{nÂK©SºñÚ7Ї}/§ø ¥ª¢ZÕ6ÈÊ¥k¤¦r殩›mòìï.'χ—6>Œ‚1ˆas£·¿O:ºÆ;rÍg,~¶ÞÏ”¾ ”KW.À³åœ´u´"öf?(ôFÄ›ç•ÒârØ*¤®¦NÖ¬Ü(%Ìçèl鯮ÇÖÀtiÀ;‘ºæA ô¦ùí¡±†=€Þ& ‰¤N' QèÑσFQ;it4n°Ñ8ü꫚1›DVáå3Ah褑”ÆRþhêB/+RÜ©FiTäk?ÓÓèÍøñ Umayˆ‡*¿ý­È7¿)òÙÏj†L½ã+ûÉÃ,4 Ò“Û*DqÓîÊ‘ŸþT3ðÒ›œ6ÐÐM°¤0ÄÄC‰XÔ¹aÎ>üýß‹><¦OЮ*/o†Kxê©Ôà ¬úÀÊùÏVýà÷<þ¸f¤æg£Ðü쳚Q˜ãj!C òÄ7KAPò ´Ý’ë:5L˜0¸ƒßÍÅø§¥€l©„ <¬6=yÍ…ƒóV†1$¨€ÌƹÅï –¡aþW¿ÒŒïz^{CX…Zàumlà8Ð³Í Db¬ŸŒ?ÿ¹t!¸„@Îmã|ã|&Û€UYœËd) àF>×ðàõÏó'˜ï!zZ¼†ò]J€V §í·9h tPàÖáÜ ¾B·î ¸"_<º†½ýÐ!Љ“¡ …ð¶®¶ü> /?:»8§'iãèÐB Žã› S·!EÓÔé²Òb©®(f@ Tɶ†p? X¨ ŠÉ®Û æ?ûB&„0ÖUVÕ9m¸}´ãHóû®13ü]ž+O–Á`¼¸¨V | àÖ ³p„ ‡¾¦nê]›g4žK}áµ@ChTï˜AŒWO…0W"=›â9@ZqŽšïo—:òØoèCInºbX/ qè)ܤ•®J ±/©UŽ Q<_„ãaìõk@ƒÐ ÖFgŒÑ€ì‹ËKE~™xù[ÂXf0æ1„EÅñÞ‰cXË]F;ÑF²Xä k—l’û¶>*‹Ž"¿s41+UÈ0FP\ à+À;€öóüÌÇo&§"o‰9 H|¸GÍEÎ[g!~û9Ç¡oWòës×DÈ©0Œª0 lØ$m?®sŽ×œ3P©®7®eöß–Ô çü¬hì&Ð`>_úðÕgs2™¬ûöížtñ-ëÍÏÐÛp455aïk„°¿çÏŸW¡>‰p[¼nm±5`kÀÖÀüÒžl±5`kÀÖÀ|Ô€Còý%²rÃÇ¥ zWÏËg_“Ö+Èð@ÖÜañ•KyÍ*©_¹[–­y@*jV`m”fÓs>vÓnÓüÓâGïñýã‡äÐÑ·åFGìI}2„E„±"zgÌG.²¼ðÄÈ÷ú°`ß·eû¦ØXzé„ü×/üTšZ.d¿ÁuðBx"”À`¼jéêIj2}¾õ8pðý·åàÑðRê 6ü@ßIƒ¾pð`“‡¾äû¥éîù˜lÛ¸ÃTØÔ?ŽÀø}îÒi N¨úYb °[¥±~™¸á]Ø–‚6ŒAE96’k>=ÿ¬½Î¾¹Ðìîï–ÃãÇKWO‡Œ`ŽF±ÑÅ&&íd ñ`žúA…Y· ^vßµO¶¬Û®³¦»"[³¤|yk/÷‹Sß³¶ª—GPMZ ÝV!ôĸÿ+zxý³þŠëQÅF§75½üiØ$¸À,4ºcÓȲ cZ éÍL£¼•‘–@ ¦Á“åwvjCéénµH)³P@/o«:õ´/Š|ûÛ£к¡˜yxЀBáæû@ã¸Uy4¾²cûÀ2ÉAÛÎ>XoS#X·q<øÙ(dBøÔ§48½×Â|}|ï{Ú8ñ³… ”z¥ŸqÕ{ƒ°€úÚ:™–“†lêÕJ©ú0WãO#:A"C£¡=!KA*Pç;çꊵÅq$KÃIèB ÃìÚC…i 8ö¿þµÈo~3P çåk*à¿c}<ÌÂyÍ#0Á?þ£˜áµ¤ÏeÍZš0¤ €teø`™ëKuI¤£ï@Qž â°ejˆ Áûᢈ2œg_žŸ×9…e>q{(ÀøLU@‚.‘ážy#0Œ¦»yX×ÄÛŸ•X ÐHÚ©õÐ l3—%†RÀ‡HÔ/á‘2/JP?²¹ujaUžËKKÓ¥•Á¿^Ð ’=.!ƒƒ>*`¬øH܉õÖXÁb5`?è‘SC,ð¾ÇahtШ:Šöâ7WhdÉ^OÈ4mRCl}ÉBY¨_ÒÊ6¡ÇT¶¬”c„çqÝN7ï2 µÄI¦{“ ¡×NÀ»ZõÛ®#]¹Üp»ð[dReh€¹‡ <ÀdЇ#‚qèêÂÚ©/³uxb êׯ']–.\# •ËÅu³›÷xŽ#~7’)RŒ9CGö÷÷ʧɅæ&°,ä>×ÝùÙ´b‡Ô”×B¼® ¦†¡ ÄÁ‘lt†‡Uu~Ü‚°/'ˆ¿Ñúý†ýPùq©µ¹Ôë#Y¶E‘ŸJÓªýqaý`çÕxd\úG:! ÞóMx ’µ€Ç ÐpM*øt}8}Zë6 -õ™ªzýV¯ô.ÿã?yì1k‚5¾ó-Œõh!·Sz``‚Ñ·êF¯u‡,RN¥3@§wÌÕøÓNP=êéÙondTÀW³ÑñweÓ&kf Ž#õJ†]Ø¿½{.pú™±W2¼üòÄù¥§Õ­<ú¨ ÑÏé¯ü$ÓÀÕ«ú™±×t×%S¥›Û:¸@/a=xXɶm" ‘B ƒÇ™UR«s#é/ó&ÃkX¥±ÏM¢´cƒn Pa]h¸-M’sÜ×JŸ”ÖøÅV—O£4FMQ"`%ˆÉPÀæ96Ì¢ ÚíW/¯¸Æ…N`‚ €.ˆÂâSl422Ÿ¡§ ÅïóJYIŒi…ÿ#/£T“¸ÿó½[ `ŒÄ6&ÏãPÁÚˆ¦ò(ú qÅy°@ÃÁØ ÊÔ?%ãiÇàí¯Œ ŽA®$îžu AEñBYU·AÊ@gï6ƒ­Ø=ãïžR„a¢ÍA›÷'Æå1¦ç|µ‹qéY©1]5’ƒ®L×q°Hž_Š À®Á1Á\ cî…c!,èÀ ‚ëbhëÞ0Ø@ ë"g7ç©à‘ @ AAÅÕÞ»¥¿eE•R]R?°00ÂãúRM˜dÌ9¿¯¶^•sgIóµ+`ôÈ PPˆ}°}Û“»Öí•âümfÐX¯ í ­p’‰@‰a~<@]ðA ¹AáÍŽéUGpNŸnü¬~U¦©×¡t¤®UÓß´ý`ŸX‡©9Udgšo k6AßÇóãr°_­x¸±±Øn}ÎÏ·VOlÏj0oy·!¬G_Æs1Ã$÷¹‰sÖ ŠQá˜èÆÓ¼1Õ»Hà‚âîQu˜›>îs:c6û`w躛‹ñgà * èà * 1lb©ò0{8'qÿÀ4ê鯣€,p;}âÀÔÎ0Á‹1ÊgþhP³ó À'PÀsŽyî¦ë-râä18$´a^ãy'‡¹Û°p™ìX»W1Ò 6ˆßoÎE€\ÅU¸1!.@‰rzPW­D‡{¦aHBÀ½6Î;'Cox0y!Ð Á|@æ‚Ø žÿ¦©¶ÀÌV¤µ2«¿éúáTýE?x=%@q´_cɪ;q ! LSÜ3š Àz‚G+ž©Oœ8! *4¸·5ßeÑ¢EÀªãѲgüïv¢á ÷ðÀØ5`?«¸Ö5 ×Í|׉Ý>[¶n Ø ‚[cœìVÚ°5`kÀÖÀ,h ‚M±ëm× €@‚’ÂÙ†ÖlA¸2l(xÕÏ0<®\m‘_ý Â#ÜÐZ†Åwo_¼þî+²Fú•)6°Mýð‚š~ã*жí~ØôõGn\0D@M%6É3zµ\»,ϼøS¹vãŠFóˆ”êŠjyŒ+—¯•¢Â€x°âp9±Ï…O„2¡vÁ¢ jÊ2 ô„QœÔJЦ€? õ §/(×|éK¶ogZßd@à&>ÌKVÊöÍ;e ÂEäƒÍÁƒ ¨RCZ;®Ë[ハ ‡+E‹}æ}óà+²|É*© Ä[·‹\ðõ"BZ¡Aš1Û­„›4ô„¦ñq:•A”Fôˆ³Ê1ñ\*ã%7giŒ%­z:!°žßV^Üd&@ ÑqTòVeÑ€N*òfaý4d›7þhaÒõ[ )ìIIOOðÉ„ô£ 1aECšihÔf{¬bˆÒ ܪ©ÚEv †<øÊW¬A,ïÇ?Öh÷Ó5P~ëâBi­/T5õ!”ªVlb'tjÅŒA@û`wÌÕøë½ ¨€ãf±,Y¢û­úÈpï¾;>Üçõš5Ösƒ×œ¿ô0c˜‚JôpœOÔÕ¼æuÍùÉpæ¹Íëšsɪì#Ù˜÷Ês­?“ ÁŠ ©9ר?Öuï½Z{~ùK‘³g'¶Ë¢ô6³ÛY\·iíSã5ˆ 2àÖa\{9ˆËíâ……RVS î|×øÄÿS•ÐÙ àyߨ¹šMñ©ºe¸wdλÔzóù–°0£k¿ô€=,S k‡ÄºˆÆYEõR4Ø@¢§| µP"zP7Ø  vé¢>0Là^ þƒ¡"ÂA€ ÀjFìØBÊFbüÄó-Á Mç ° s ǃ@ õu2<„;Ï«ì¯1Y€õP•ŒFóäzç´¡˜x܃0è ÖbeÅùðÄÄ ‹s‘Ï%þB€PX˜R0• p…YxŸÃóD¡ôøáàg]’Þäú‰Ä+ïiXŸ*ˆ‹Þóv:ä)í>›¥®ØDòi€Çx8}eD”bîÁˆU“áÃØ4.¬‘x KÌ;À9jг!|“fÌ9O9Ÿ>.—ñÂõo”^ö9ÈÚ%›ä>04.XŸ€H®@¸Ë€Á¸›L¨†Ì `Œ£ q0 òJUB<³˜0u(6…d­æÚ2ÿœK?2/ÝN™žzê)àQ;°D9‚eB nq¹Íë ªJ›dLZõÈS²yÝ6ìÏk’ ea#…í!l8¸Ìñ'$ÎþœÃ#ƒðDÒŒ€.l`0Vœ‡Þi$×|iŠœÖ¯fZßœ/…E²tñ2¹÷®eíj„‡)*‡í ›Jc[Bj“´¦j#ÅŠ¥àýSGT?#Œ´w´É•kÍ6¨`ZGÞ.l®5À;¢ËlP47ŠÔí0Æ;è&'ï«ôð§ç56n”wô‹/j^ì/NH>î#h¼´ÐèIƒþdÞõ‹‹44¨Ííqeóë§÷de° <¬~#èÏÃ,4A£¨Y¸9H`zuO&ìCccê>À‹È2tƒ±Ü\ú`̯¿Çï<ð€È7¾¡'?…º¤Ñ×*¤ƒ1Þ ¾zÓªRé %:À+ÅÝAɃWmJÑd0K*`Ä\¿Þ>T 6¾êF}ýç׎€†{£ÐPF†‚ Œ×$çÅÒ¥ÖsƒÞdd· ½+Ëæõ¤ƲÍï©Ë§ŸÖBs°ýfá8pnû|æo´ùüÎ;™Ïm–@¦^‡ ÕÖN,“º¨‚—(¯)ÞcöîÕ>žyF ‹01‡:Ó_ê•+Ëá©VY"…}:•â#ôæI¯pyO•,íy?®ïÂr‰+|â8Ógìt…Ò`Ž)£x^øóRâð̦=†ë&q+ñ;ÅëÁàÃ6ᥕÁPŸø\ùŠÆÔÜ4?¾FÝÉgÙDs¼ šæãþòH”à & Ö2„BIC Ùæâq‚F‘÷f‚ 6A ®ºcÆa€¬ˆF Ä €>Ü*Ð7Æ›‡Ç:úò·ë>¤cBD·‘îù½ÃAŒ€­¡àÜí’B¾”z±ŽÌÕ~žx=0JO‡fÐ[fMn¼! 5ð’­D`¸§'õ±s§äBóeVŒHÙ—ÃzÝùÅNPS^‹ðÕ”ÜJʶvz[֨ųC¬(šýX/œÂZ‹¡4çB‚`¾jdz!=ÿ r Øá¬î¾ûnàTSì{ÍEC u®û0ž›S ¸ÿõÞ|à÷+е¡<û­­[¶fC|RžS!’ì¯Iña±ÿWõW`\ä¢fúäv©ƒ”Bû·«S/Žo}ë[pæ€7Ç4Š]Ç4*ó)Êó± øÊäÏîùoc'LïFƒò÷oýeòl^'®kÁȈìozN:Þ:üÞãÌ“eUÒ–™Lœx3›Xæ2íÏ™k€žßÜó°lÙ°]j°'\¥D‰ ß“Â=1AIG˜p út€ž?Ió޵Yì:”™;]Epý_ëê‘sNHóµ+22ÄHfO(Ę޻ñ>¹³~­;Á¬1„g2?öÍ,p`~8Kð;‡kMí%Ø ¢}xþÄu@qâ7ÉG #˜ Ë$ްl‹ƒà„ĵ”øHŸš‹ Éᜡ:b背S”´ý Ž¨ì/8 qŸÃ~‹ƒ!J´+cŠ5ÛÙ cÁk×®UìÀVõBŠÑN#ÿ\ ôdP ¸àž÷Øž]x&ãÁpóiß•€ †jJ§Ÿþy,KëeÏž=·Dh‡¹w»N[¶fOxšŸ[¡Wç‡~¨A´U*dÖTZy»ÔA¤Ÿ®+Æ-š äŸ]ÇTfÚ­™×ó±qs;=²´bÃØ Ó»….ubó1!lXôŽt©O1xNtÞwç°þµäÃscUÍiËL&N¼¡gÅþ ŒæŒöçiÑ Ûõ` ¨_Ø8Ž™À²pìS0ª¤¼¬R:ºoªd¤çìD<{Òà“2q.¥·¿G>8~ôÔ. háî@\H.ªçNbXä›éñ\Ü@œDrÍ7I±Óòõlè;GµÕ‹û!ÚfYºÆsŽÖ GYi…´uhÆÄ@‰ùš.¯ý]æðyüR_º*uüv?Ì ûû´kÔ|Þþœ¹"0 y¤p`ü6ÿ„HqØ”Ê úßüÍ3zB¢Ä Þ“è¡ýÐCÃÁ·¿mm”gòtÆËTFds½4ÔÄ`%ôŒæ‘NÈ4€ =Ų`•.U;È ÊðJV1ŒçVeëçØþT} —G:aÖ­Ó<ÚÍéhhbxL& #ñÕ¯jžâV†ê·Þù?ÿGë YiäZc‘|xw X 4à[X Šº'™g:Û‚U¹vXõa®Æ_o#ëØ€%=7,búYí•€#¨àÎ;5–Ä ž мý6 M}OƒbCƒ€vBòŒO0|ò‡‰ì߯….`Ø2¤ÎkŽ…•pn“¹„ó*áuȹÃò/~Q„ã–J¨öùË_¢oDäý¯ aPn4äÃÕÒ¹ÀŸªû¼Y1Ü’Ýî…W9Bä*…å>©¨HžÔõ4ÖNþX5iUx¿‡‡AÏwؼç¥Ä㥰µ¡À\ì8Æw<ÏâLǼülۤܧL¼Nh¤hqÀp£ý@¨Tò~xèÄë†!Ïúq¬‘5!Ñ|B”aÜðY?Ï:TMq*<€J‹œxMæGz…!dÛ8ˆã~•ç8€ÆQÞV! &ƒ ÿd4ˆ *ŒÆdáÝÂ8Áù0îuШÚP8ªÖ¨¿ÉêUc5@†\ÝiíV u¶Q Àb@F7À0xÝâÅý’L š@}³ßГù~ÌDl,ÀÂ*ì“iñ†@ Üo­€ne`WßÙuÌ´®¸'Ðtå’œ8yL…Ôöo'^GVCe<×°p™ìX»WÖ/Z#E¸ÎTØî1è¿]ÊXŽ‹ÖJ² ¤íOÅ1¿’óD…=´È@PB<¨yBôËLÕÁ~èe[4#ãSiúG˜ ‚”ÔõúØyèÊ–™Óm:•TÖXKC9üùæ›xl;¤BÌ\Í©Kæý¿ àîN0M]°ù7ÞÝ]Ê0¯ÈRç­o–.] öP¿@¤«“‰L»ϵÔ/÷.m±5`kÀÖÀ\i ÅÓæ\5Ç®×Ö€­[¶æDXh…ðÀÝÚ~U:{:¥ Ç¡ñz}RVTüÅŠ ß™ëB ë¸ ÍXX·\»,CÃ(,q´Và(.*Á:/¹ÌÍX\ à2(ÝÛQn¿BC“Ò¿¬¸\JKÊ¥²¼JJ¾ !b9›‡s¦g¨ÒÌë Ù†aÄÂ3&ŸqçHh°oë¸!'Î~lõ±}ËÎ9z¿§¯GFƒ#8F¥»·3Ù65–ÃCÉPê L v6‹1~}ˆ=™m¾òLz¥aŒQëÍVÌÉKÒ7ا¨S=0Ú3d@5Æ´aQ#ÆP3"éyR½Îš¾Õe’ŵ‚¤n7 ­Æ fÇÜÍVÂðôêêí’ö›X˜w·Ë Ðô~l”—VÊbèŠ×œ-¶æJ!¯Kz+ó¥æ:¼ý&ÐsÊÏ~¦Å:â ‘OÚšÊ\/‡qÜ™îäIÊ\?o|Mg¼LeD6æ§ñ‘F[†_0 cl’æ}2êÆFÍ oE‹ ê]eÈ4—® °Ae)ð6™)ìéÑnE/Ê>Ð~2ÆöÀ«>B]Ò¸œN84â~ò“Öú$ ý»ßÕ¼éÙ®4Ò9udïB9O/rW(E=£êH“-{É\Ž¿ÞãLcŽ+þv,Y¢…•à«Yš›E^}uâœáx2¿Àƒs’á=ÈèAð Á4Ø“"šcÎyC0 ùúb‚4]Éfq^§Ìd3·“â ÛØÔ$òÿ àÕpÑjúHǶHÖ‚'Ÿaø_üÂXš,Å»ÍR0N/©>D  6ãqŽ€'<Ôýe>)¯+o!(ê¹Áÿ©JhFêPT´§ZÖLåÅÁΆkQø|;ÑÀæó;ÄW—õ¢a¿Œ"t×$a„Ë€Â' l#X;1î=YÑ&érÆ-¦§z$6ahTZu‚1 ŒN4šÀ¶Û@™ß-…>§ä¸¤$€p|^x Ûá2Öõ¼Iˆ9Çuîác‡¤©¹ ?c½`ÐÐÁ5Ùµrí’M²cݽ²jñzÉç¤蜮©™]CìÔ¶²ÐY¨PY…pP+V¬P¡ḩ“d:oü,ªÈ:)Á7ñ IpÁR v`Ûî¸ãÅ–íÌÀ¹%ëJ3Ì@@A]]?°é„mÿÞ÷¾'ñ¡ÀÓ͸ðXÜÂbT…ik ?ó·Ô,dX°Ú?e?x˜ó°½œVòQ«£¹å°éסÙ/ÍŽáY`üó™+̺¥N=XOZ÷*­“Y.óXÍ£Û½Ž¯}íkVÓÐ>—…æTà…7ÊßüÍߨ&»áÁPTT”Eó3Kz»ÔAŠ]WìSÀjÓ13•¤LeבR5·í…1Ææs+6¡ËŽ?š ±R]]mSF%f5.Î^<)¯xI®·Ý€1|TW£x$²;ê4HÖV×É®;ï•Íë¶fu=Ðp{òÜqyuÿ‹ÒcäÐð Öð|¡“áHßÞP·DÿØg¥¼Ä´‰mUžeƒ‘ œ¹pJŽ?(-W.ËàÈ Ú<¢°¼©öþæ>ëâúè©§D¾ð…ñžõzlÆÉ?ÿ³È‹/Nj”†±ñè®9vwµŒÂè«K1˜ Š{ÒlQ§œ ©tÊq .Œ¢ën¶Çߨ¾§ÑžlfP$xކsĦ•„sÞøÜ2¼ò <MúáÜNµvmnÖB¼ñ†æ¹Èk†eq®èI4H7Æ·Fc[  Àꚦþž!˹<ãg¶ƒãøÒKØè׿ùìgEöí³‰Àk‚ 2h˜î!mÃRÑ 0ÔFè×âÒ1VûQ  7O¢x„s/ ·ò|!K/@Õý*Ë‚á/‘á˜ò†#ôÁ¼”¸ù`'ˆV¡y¼v'êÏ_ìCALÜyEѯõ#»þ½€@õp4$AqË  ÏÔ`-ð;K$÷7þS×1 x­3 ëª=ô¾VãÁ:qN¦S†~ÜxN1$ÚOŶÀ,ȯ ®Qêpë€ñž^/tA´tÀ_D¾gXÃî1!€ Èn0 pH0¤D‚„ñÌ;]Ö\Ñ@oªþÚ7‚õ1ºívÁ˜×«±0|~òz§Ä ”ôУz‹ûè€Ô‰ü8AóЦ®H÷ã®ÐO8ÈpÑØ4Ʊ®F;Oêü„~í:²×U,ÆãÚ |púœ¿x^†ÁŒ‘ëÄÙ³ú.¹kýýR½`™xvÑ9/Æ3*ÆcƒI¢Æ,Žk-6ˆç4†yÀX» ÁƒŸâ àw%hp(gmÌ£ÃHDÛp}89îóʼn³Q‡Ó‡}}^ª–æö']?*$®'žÛÏVœëšr«ÏΕh· W=–´_lݺUŽ;¦Â"pov.„{P ‹@pAKK‹jËš5k°„Ú¦@fãíl´‘÷ð•XcGH®É@ÜS; ûÓO?-ßøÆ7¦Í†Ær ´x ϵ7°Ö¢žl™{ ôvw[¦_V Œé¯åö.Q{ ™Ã>H°sçÎd hšn¹]ê šk¦ue×1ݳoþ—w»Ž9ÑyáõÄØYçÎS€™Ç‡Û2xKmذAV­]>ÿi[8 /ÿç_}VÞ9ò–tt¶«Ø“VÕÝÄêëjëiëlƒ÷)@K­’;ÇéA´ûê3rèýwP~›¶!3.>à!úZk < ;åÓÿ#ÞœDÿ̇ÛöÎVùÍ‹?—óMg”×ûd‹u‘mðF?sþ„<þÈS²¬a…^Ü´¼²MC0ºê¹Gƒ4cgÎ¥Ð|åZSrÿ«Fßuk¶Lj϶Í\l>+O?óéĶžCêëäS~NÕÔ'‹‹CO½ðÔà¸Y=ÀñûA°cð0ÊÀP?À'Þ¬ó°ÐÑÑ6TÐ?Ð'o¿÷º¼¶ÿ𸿡€ Æú’ï1/o´_S ƒmWåá}ŸHë‰?[úN¶/Ã7\˜2,C@ºøÀ@R]ƒ×$Â7Úo|ñ¼AîžìcØBZo^h¤sá<<÷«c:6ê-ª²OÙ°Ô7ÖÙîàúP² ”êÿê_‰Ü{ïÄ:hT%­? Å4´…F /él-i|œÌ«šÞý4¼Z ½Eh”O'x¦‘O|"5;ñ<ÌB#1Ûnå5B½XÌeèŸÙþt}0y½èÙ’¯zR…OHÕ½®#©zÀã'iÒ¿'KÂOª±TL˜@ïñãwVÉ{÷ÖÊ@ Œ2 ñ E(J^ÂóT??D ÆìI¥Ó¹s *à±zõøo𛨘î¿_äã·М?/òòË‚]Úñyù)ÝÜàX5ÏëÓ*Ó9·S5Œ×%ÖêÚÂF¹<ú¨vƒlfá5ƹ Ï=c(“‚Á°TÞ?B· aÛb©Ø KÂ=y`'À\ŒãÈA((E˜ ‚ \`·IØ™r(i,K ‚H`8âÊP=öÝ|yG˜ƒ¸T¶XŽ&ÁÀf2«Qù'@Ø“°U §Ñ=wá³>ÌóŠ cçpdX¼.Ÿä*'ÆP"B$…÷Òý'O$Þ0 £(S}©Œ©‰T0LNHÏl4žëϬ¦:œÈo¶gz6ˆæ¡$Œ1’©àÁ!2 èx÷ü‘ €°o#3tBªçâD˳z Ì ™öù01D…O‹‰ºq{ÈáHÞ›Ÿàò"d|Þ1p ûM0ãÕs` Hˆ$Ð×§­QO(ýâ{]¿Ômò"1¤·ë°ÔUkÙë7Ûå̹SÒ|õr‚îÝ0¿õ˜äµû{WÝ%[7#Äb @>|–€þ w$ ãzsžúÂgÄ0;Æ1îò ,‚„°ÁëŠeÆñüƯg©¡C†„™Di¿Î¥ÉÝ‘´%Û_N£h“aç</Àšƒà²¼ÿþûÀ-÷Zî Mcõ–Eñ>Þ6,РOpÛF´Ù†3 ø"aØpêñLùq>“OQ¨‹wß}W Èæ` ¦¨P;»­ˆðÄ1÷2@s¯ì:ÌIýÙÖUjÝÜ®ßÜncNÔëoû[(à"?óAÉ(D lPòj‘¸Füõ…énç÷ôÖ~ÿÄayéßI‹مþúšERVR÷÷õ~³ë¦\»Þ"a¤oë¸.7f`2PõÝ šû§Ÿýg9 @A?¨å)ܘ(ëÃ`P‚´ aðáéàá3*öµ¿LéEMúû7ßyEÞ=º_Qá«üØdñbaZjÿââRó=0 v%ºSÕAcuw_§;=€ú]òç_ý Å` U>µ¿ìg‹Y†Ð…×SE K†…»þå,¾Ž€v‘†^]ÈT°ã:ÝÂØ¤g.ž–sÏ€b›¡Ñ!YsþÔ8PÇ>›"¾|Œ7½62²MT–UgO…1ÃOR0Vm]mò,)œ: n>҉͹âÂ"èfæ]± ƒÐÞÑ zœ¢Àƒ×üAzz»åI€^j*a|³ÙÒ·EÕiOu L¯}Ó“ —ꊚ ` s!L©å¼üôÙª°%ƒ`sÐʼn먢xÍôá:ÁuËël€sp›¸±~©b Ñ󨝶fRù0Êm8Ü.›÷ÃxŸ‹\@¯e<;`'E !` QÐÊøNZwxâÀýqbíôúæ{PZ¡AÜ*?3qS?PÆSRýïÛ7Ñ{\¯”àfÑ=¹iÌ1 Ó[ÌéôÏéúÀö|‘J¨ÃÇO߶Ū,“í'^;ŠQ‚:3 ½Üó‘ïrÖ仺¤HŽßU-]5ãì—E}A T`´Q«Qï©SÙè4îfrüÍ×Aæóü¼t©È¿(²k×ÄùH#Öo¾aœÂõd^7éæ·y¼ÌùsùL†^—V’n.Y¥Ÿì™ª`XÎe‚¬˜,î!N¢É|èµA–jÆ-9†pá^OÎáX.™ Jký’_ª^€†¬.OËúÓœŒD°&m>™&á~—âç§?møs€y}‚(c`'ÀOG>¼ä(Ð~ &ù½Ê²?:{A$”?=0Z{¡Ðã‡7>Àºt’r€bñk•2§–Gã2æŒö`+‹ãÕ…ÃãŽ×ë Æ‚R°Æ!€$ö 4vƒ Ö£&ƒ¿È `ù¦Ën©Â'„ãà ¥{0˜ ŸçqiŒyÐ}(t"€>´|*ö'•æ´4zÊñ©Æ2–,™ Î1I•þö®#ˆ}’&„y,2†ü¯_øyPà/ðË?%ë×lÆ&<íÁ¿ÈM“‘Ñ¡§ö¡Þ‘ñ6X°û4‰Ð Ùr£Y®Þh‘a˜}رھù.PÉï–b„¹á†K+Ê|óÝWä,ŒÔ}tt—Z.Õà€<´çQËèu} Œ ðéâ²eý6Y¶d•øÑf6åéMôn¼³ß:øŠ:úâ|F•Gú¹K§Pþ~Ù}' /Ó ŒÇyéÊE€&ú“¥ ‹eå’5ÉÏ“½áfð‹“1‚tòùçu²BLßs| Ô¸ v]<0Η•`£;!QЈöö÷áèÆc3cúåb´¿¬´rÌãEÏâ•t ðþW€¦AÝôÀóÐ \èÔ×6È·¾þUÛáì„Ýxçe•Š}^ѰBÜk@[#O‘¿Hª`È_½lMÖù–'[0ƒ÷{˜[ï}ž#5À»ú¸o÷òiÍVµˆ£ŽØvŽç©sÇäå7ŸG?úÔçc§ÞG;j›F·*Yölê;Yé$oئ.Ì©WÞzIŽŸý ™º¤¸LvlÞ)%EÜ\N-7ÀøÝ+Ï ÌÈÉ$ ¡à‹ívÈæõ[ÁÚPÆZÄÆ¦AG’§ßÀ O7@6¨ µzío¦Q.x.¾Ø'»{EJ»à¥5¡aðÔ)íØ»wbIØlÂÃÅÄóôh¡÷±•`Ó7I«oÆŸãt*O~z±Óûƒ-ÏîsZ\w‚ RI*#*ßé ¯Ì—©°ý¹ö! ØT}À=M R î¸Cäë_Ù¾]£—7¶™yéAÿOÿ¤y•82‰”·Ë‚–A¹¼²¡<ÉÔE}PÔJ~¶|C}R¯VB}Zét®ÆßÜF`,°’Í›µ³VÆr^7 {*ÌÃw¤bëàæ1Ý’Ë8L¥ œg¼?`3Z”àñ6ARÜC CBÆ[Æk vHdTõ`)ˆM@¡ñIS~r‚òÞ_æ“òºBî€Ï£ø?e À€ Šü(Ö4óUbq†; йõ7¾ã>? Ï…qÉó"T€K7¼cÏp­‹% JÐ{Á€á-ÂZÑPt¯Ö òh/c°Í|!%¿Z¬ã³qUX„D›PP <¤TTz:#hI…§È¬>ïƒÀ Áx °DEÆcù hò [AX‡`ü'Ø8„sd3ÐÎëu²qScø„¡Qí¾Ñ=0y7è롪Í.ð"¼l ŠPƒXWú}`ˆˆ"TÃk@…9жƒXÿÄ¡#·Ò3ßA Û8)õ1næÓ‹]y—ƒM|ü×qÎ -¿KHœÞòô~‡|êàmŸëøc'ÈùKç`ìU,Ú\M(%×µK6ÉŽu÷Ê üN_†#P:Gq„Ÿ‹â·ûNŒ™Ãð‡ÏjÞó>’˜ß–%Ú'gCü&kA ÀŸ›6m’Ý»wË‘#Gäõ×_ÇãÓÕäÞÃl´ÅXÇžSy=à‚Õ`íºï¾ûdýúõ³ËËæ=ÔÃ2èÎ “å§÷¾ŸÂŠ Ù†nà~Ñ;ø‡?€ÁÓL¦nû{[¶LО"M'í¶l ظ50 cÀsÏ='¯¾úªBšfÒ.„ãQ·¸†±‘1Ê —†ðAµµý*À×T‡é]¿eýrﮇàŒxÄáÃfÝ‚zYÚ°B ×-1|ký–yFa¸å‚¡ FÌ'>öyÙ¸æ©(«€³%|&ðýx2×Ö.’Ÿ=ó/rê µöAl¿ý_“{vìSL æÒix^ Á(èfïܺSV-]ãh‰ÐØÉº’‚þ"x‰½€@„ÃÇÞEùÇÃò„z˜.P½Þ-?ã/dp#MÆØtaB1-”UɦµwÈŽ-;… é„e{0.F±:Çï \Y·z³Ò×€!£¬ÀÒ£²2OEy•lÛt—ú¬þ`L¹ñå†Iy)½¬¸I—E¾„®èEß 6‰×¼’ ÄrU<ùèdóÚ-ØpoÌ è¨¶º¡>ÊågðÔï°€a>„Þ¶oº[×5޵ïfSßã*6ÀÜ ÑÕsdÿ{oIËÕ‹ Ĥ<Åö;v¿^Lå0,ÊÉ3ÇåC0:è‹Zæ}hÏÇdÏŽû#ˆ>术K/—•KWË™õÛå¥×Ÿ0&&ù˜»¶Ø˜ 0¾ý–·Z¥²m(uuô&96ˆ@S’:¿¡'qyùÄ44ŠÒ šÌ ÂòyX ãЛãÓ[¥K>`›ØþeËDΞË][+òÇ,ò•¯ˆ44¨ Ó±/ ïX6ÛÎ>˜…†WVB~*#±UzÖc¥¦¥—:¬¹öž;샕ašeR>tœ¶a>®yŠ|ç;‚À©AãŽ}ô…dËÛmÒ± @Nl`$ñŒQ–‚¢^MÒI: F*ÎÕø›ûÁ냠2à9dœX ˜€mñEkÂø6.—öÆtzñ[ ½ú±a ÞÕÌ8,ƒáðÜ á™ÖRÒÍmÎëT«Â–/×êd˜«9¨çá<x¦ú™±×4÷O(&¨mÓA‘>·DÁR Qè5ñø\¨ðIQe8iq¢ b½D†ASõ¸2PO±À™ÈC(Àïà÷Èæ/v‚¡ ;qD¢µf$Œó3Ñ&S™Š½FëbЂ½À=š‡ÐRàÌ(Üê׸Œ›Ë³6Œ#¯¬a”ðž ‹k=4‚!= êžçWHÏ“Y°\¸u#:+úmÒ‹&ÄX&æGŒLaŸz&“ͧC`ÅšKŸ@v³NBoó^@½˜ÞѨt¬ä‚.<@G¸o¼/DèÒ"0ŽäK1 òB÷ÆUªÒôǺ±=H€á à€_á>çpiÀ UWâ÷Q½g(ʸM Çô6«ƒŽC}òÁñ#r©é‚ "ô -r‘í«wÊ=[>&uU‹Õz]5XÒmb<¨× žãðúÅáåï ˜NŸaÿÆV€!FPàŽx´ñpx Á¡d.êà¼ÊQWZ£MOÛ<¯cMÁÈÇq¡®&ßG1–o¿ŸY ¨½B¬Ÿ*ÁW‹5ÍŽ;TH„7ÞxC…²Õ÷!f¶KÄóÚO4»bÅ ¡Ý+OÓî…­\¹R±éfÓo†ü%KïçÌ.Kç¸=Ñ4m㎠(H£ û+[¶&Õ€ý‹:©Šì¶l Ü àƒ×¥K—äÙgŸÍP ÷K bXèä+Ú-"Dow‰`1zõÚUl~h˜nx,_ºr €zàƒ) Í ƒ½G¦ª\Óü‹Ÿù¦l^³eœ‘‘eø^aiý yhßcÊš›t4ßìF¸…-²¼qÕ„a`,ø{ï¾_îë½éóa(·¬½i|¯]P/ÜóˆýðØ bÊ{„”„¬‡îSzú·\kV ½íW-]ý4Þ¢‰Äºc˜»ŒwoŒy¯’@G4¨ç!´C JïÙ/+—­†Qw˜V§e0àõ0l «gè^07üð—ß‘ —ÏpÐ+Cà p¡·=ùŠ:›¯6ISË9ßtZÜóqi\´4ùµùMA~€ËÁ(~€6XÇ}%˜&Ê&ý>‚=ø:&¸‘—lV’k>–Õ‡ðï}pÀ‚ëªhgîØæ |sˆ‹ºb€C6`Þ65_Wöÿ^Í™í×åÀ{oN̦¾uÝøpµõŠüáK´ ã"ƒCý±±ÕÛiæ|ׯW–Õ/“»·ïŵ³SŠÂI' õpè0:(Ðlt–lƒÉý»?¦ôbÌËyLö†Ö(-.—ú…õ „a^óØïgGqÄ+ޏ¤£µHzº ddȧ3 Q)ð‡¤´rH*ªÅ Êã[Uœ0èT¶Êš£©éèià#­þ·¾%rú´ÈÓOk4ífã7æ²ÔÕ‰üÑi†o³Rh€¼Ž{ f¡Á<µ; ÌO<¡?¯\Ñ 6hà€^ ´Òh¨d›ÈD o¼ëõ°mŒeOã-)ü™fãF†žžùdJÀ}+¥èTÜ7Æ ó°}V±CÓ@Ç•aü@ïd}à÷zनô³éƒ2Ú*¥‡ûg>#ò䓚1×ð•zKýÂãHQ÷éKæoÇ>_¾,ØÉ¯t·:Gášk²úƒN¹ÞX$ÝUÚóFq÷¨§c* NiÌÎV§s1þc½{ǹE¶‚ R±oŒ¥ÖÞ½õ–6¦V,zZöår<ÌÀà?ñ ‘–‘gž±þðš Nyí`ÓYÈšÐÔ$òÝ8¡×2öšnnó:"@…¯™¨e ¼ÕäÀ‘ŸýL¨è×®^ëܶMäÑG­™*x¹vM9ô,ÉWÌ·´!5’ ?o¢ˆop±tÃý/ɃKvQ5Œ¦¸v=ðÔæðL‡Ð´íÎÃ_¬3bðPç-)Ãñ|a,ˆÇx"¬DÛÊÑ]Žñú£òN€,ðŽpšZЉ9Å^€°d/EFdz x %à,s®{þþ)Ñ_'6”ÏÀšèl ü”:=¿Õò =pê ^Ç`(Ó ”†qÿB”¬%ÆÂ'D1wFƒ` j@®É#d6Àùl JìK*a}A¬y• .]º,híy¡k1¬½ÐøB=|>—åK¡žðÌ@£¬úÝ5êç“:ÓKM¼"­–^ûœ…Té™ì¬ƒëØëpÐ8söÖÍ—ñӆ߶ä<ÔúžéßG6ìhýa©¬jÀxðšM!êf5¦W}Ú3¹H`ÌNÝ&æçüØx¤¸!ÎVÓ(PÝLÕoÎC>ó¢ïb¢é*Ùy£‚ì÷óE4ˆóà^ì6lÄúk @Ò^¬ûôý¼lËM•ž ¦b}³ÈHÝœÆúö5„{ä‘GðˆbÔ”—ºµ LJ±?Ú°5•ð”n‹­[¶n} ðï%x81V®2Œø„d9øÂ¾k·N>,BaÂO¶—FöÞ^l §ld¼CÂb±|æ±/Éë¶)£ã„¢‘†Ì aаh‰4]½¤| )Ð êôår`CЩ¼ÇéAž‰Ð½°z‘"”@Œê¬€žÜôæ)c*‚žAĹׅ›ž­7oÈÍ®ö¤§¾þÛí‚<’Øpàî(=ïÛ:aàH¿ ò؃OÈúU0þX=ÖÉÌðç_ÿK\Ø qËxù/ƘÎáÆÃ@¼søumAŠþVáÞ»î·$ÛÌñ„‘|ˆí`·xS؇0æ—Eº§>ÓϦ¾õöq|/]>'o~Cxž@^?Fa8Ž»ÀL°së©_Ô Tzµ¤‚eÚ ¯óMç’‰ÈR@v-R ô•€ÉÒ†•ØX¨P$)ÓÚ_̸BA·\o)ÆQ*Ãý^xȹ`ôÀšIuʸɭWJÄ_<"‹zeaC®]ãîäŒ7qZ* ]xãÙ>ñ§£ 'KÀhžÐôh§!^Êk†E>7Ð`Ùˆ;EH£oÞáÆäþý"‡Y·›xVB7Æ={DV(ÇMgla×LäG?ÒÀ ºa’u`ãLO©Wê—×4Ïs¬¶ÉR˜‡€™lÇÁª0^»»v‰lÙ¢]›{÷j!RÎœÑæ:Á F€&Wî¾[»×èîËzyd~Hs‰"þyDQ½ë>¢¯œB#ôãżÈQòÀ醡샸fÝ#|.‡9¼µ àšÊ•I•NŒ—Æ×8ÃçQÐnì.à³§.«iÔŠÍ"›A<^ŠºÉì…ù/ø]3­Üì,LÈçMÃTúÜ FLòÜ>ñç$ßU`5~+yo (…ò·(ÑVJN|Ç÷ñÄ8–_¬}0 Ú'¶þ»¢@å0¦Åù¬ƒ!0ãà¡Ïö¡½è‡s' –Dö%ŽºÙL²^„.àz-„p £©ÄçÂ;…ð\Ï ÓiT‹laˆ[2>€v—4È£®§@[ü„OÀuDˆ8€ êYýrŸ4jÓs`òA/WÁ’V=¸òaì³Øð¦Ñ÷v~«§^Æ·?~êˆìºó^©«Y¤ŸÎù•å7Ô7Ê"éÅœJhÐ&ûÀ‚š: T€„ÜŒëëïN•%«ó,ŸÀ…2ÄW nòaC£»·kJ ‚`aŽ” ˆ×7hP}ðžG¥¶²vÒ6VUÔÈSŸü²\½Ñ"^,˜×‹M¶5„X”ýƒýÊ»¾µ—N+ƒ6éGBhj¹ˆ4!©¬¨Fxlr[uÈÐ º0/ã=b;A AK¿,Ë—¬’:.àµíO€Jºå<.Nœz_.‚¥€‹pÒàŸ¹xR"•ÞÇÝH³@Ç…ùY·rŒí!Ô@*мIæbfê³Ré’ÎÞNUÁÕ• e!æÜdB¶‹2X@½®6‡‡ ‚R*JaÔHȬê;Q'õL0Ðè(<ƒÓCŠ0lÃu0t0LÁ®{¥¡vIÊd'¸ŽyI ÅcëBèkõ²u)ó¿ ðÇ™ÃbØX†ý~jD˜“³`Þ‚€ŒF¡ŸR´Ò åÉð€Wû¼²tíMWÙ˜v¾¿÷„¥áloúfÒøHju ŒðQF{z;Ó³ž›Á4JÐ8IC¤Õü¥¡ÿÇ?Ö<©µ’Æÿ%0!áá>þ‹Ä't踿*zyP g¢§üÑ£ZûôsÆW¶‡•0,ÛI¨T@i+ªw23ÑðŠûøIeÄŸÐt‚íça*`Òt}hjR¿=²|¹©P|dûÍÀ¶›žëëp²êK¡Q#]x ½&Ró[¨+ÚFÀ†û!Ƭ¨¡` LëQN}æªÓÙ½ïæWT`>oþÌë‡axdâUõöÛ‚€¹ˆO…çLyŒÂë®±QdÜsv]ò{>ó(üãê@IDAT ð…£ðšKuÝéã`L¯¿Ïvn3<Î1Î_^_œ£d.à5ÌMnÞCx¯aˆsßX/dI!ƒ…Œæ»%X€2>ÂBv./Œg±Pž„i$£A *ÏEU‚Qs“!rXŽ”ïy^ ðêÝ»ÆR4€Õrzlãç1cáÃhÃff'ÀyF ×Q€ &ù$º™) AsÚ¤±[o”£„~9 C9:g-ÞïðŠ‹Èkp,V.¢-0Œè#ÇŽcÈk”¹æ°Ž æg.ž’Ó΃e°ã‚öéýU­ËìÏÚ%›d󊲶q 1`ø70Ĺí禅8x93LÒªï8GÝêÈ(¬ã`¨2ºÂo«ϳ P3¿h¬A#þœ×A ƒÞþ±fý.ó~@_Å66MV¢ýw†4@c=™Ê’néÒ¥Xâ\Qà2Ј>Â=©¬[=`óºgÉC›osÃ6,àsç…, eX³pߟûKÙÈ® T¼àôñŒ ZI|y,y L€?ÛbkÀÖ€­\5`ZÍçZŒÏÖ€­j€`€?üpÆ”1ÓåÏXÃo‘‚ùàÆ‡DÒ[-â†çm,ôÔ!]y bÉ÷‚žÆÉ–Wå{?ý¶<¼÷ã²iíVx)d’ÕUÆÍÆT'múd¢ØŠÊ’ÉèõÝ?€…ñ4‰FŠ{><ƒc^üÙVCO‘«­-ò»WžA9XôCX½l­ì¹k6'ߦ·8=à×­Z}lÄ dôÐ`8‚dh '“Áõ¶+rèýwp€· ¼X Ÿí×äÕ·_’º…õ`£Û$܈5ƒ“ülCÌû[wK €¡#æ÷BÈN°›ã›Vo‘×¼$o|M•JpÂ¥ËçåØÉ#)A ÜÒÂhž¦æÌéG0zz:’‹&‚\jª¨ð“6 ýò`ó†× CPTy¥A³®o´ƒ! VÁÐÿØŸ‚Mƒá4ÀL?”}ÝÎtKÂjDð»ÔÞѪX*Z®5É¥+dï]ÈݘF¶öBàÊÕÖf¾Uâ„aOü¾Ø2ÿ502ì‘K*¤åb… pcÞ c\ ¸÷AlF&î1 "F}÷ÂÁ~Ÿ´4$ƒù¾bC®å[gƒÁ7‘…Wà%œNhŒ4‡5¢‘›TêH——ßÑØLºóƒ5 €Uz¼›š4£•g´9 ¡4lš ±/Š>,²o_fmÓËeœ÷o[ë'Áfa]V z~ó°¦·Êc•ÖxîüyMWdT Ž3zº¿÷žÖÁœ‡›^ =an ¼/Ð;Uá˜ð0‰w4"þ x`Ì)‚q²(]èæMgÌžL§³=þ¦¾&?f *8p@äW¿Ò’™Ó¼!èå¿Àf…æùo•”À3xÀ*Mdv༰’éœÛ:4æð:ÏäZgÛÈh@f—Á¢½C<áñÑðèàZwµã†7wŒ§Ùí©'Õ§6ÊqÛàšBhóƒD‚0ÈÂ&Éu r´K`à¸À §ÛëF˜€`àduކR$ÏT¬€þ¦ò?Îð, ­<íqx¨|N4`žõX„öAgÂ(“EX?ìŠß;(`Š1ñÃpí¡OeŸÕ¾I_ßXîéÇubžûðÂÎsăgs—ÓU§S6õÆ6(ÜUÓRäIè)«<ª†Ù¯ƒóÆ ã½Q¼¸D}†FÀˆÎSð8ØBh!˜C£¸ƒ`3Àúqf€ÆV!ÂÑPω`û€®<|Åt{>Á+¥…^)@Ø„b„R(ð"äï•IAÃÐŒX†1L¦1¦Md €k,2Qe+)*Ez¦™¡:Øn}øž\l¾¤â­3tG.²}Ín¹gËÃRW¹ë9<››ç=¸w1lWé•°ßã‘L‰oÐo•>q³3êÊ$ЋQ¯s^î­Ó!¹ôc:êµË˜5 pýªÛ㙟 µ±&{k†!†Öšá^r{Á׊gû÷ Þ»w¯:*ÁÊÆ{z.â(µ¡¡Aš››Õý&Û2¸—MÀÀ—îí0 ïaüüç?W€ˆL@ ¸Ëçï˲:<—!¤Ö-Þ‹É-¤ýºò7Ùx5ó=¿Ñ ú}[Ӈʉ?üyfYê[õGeÒž·’μë£~fZæÁ?öƒúåg­¼&Þjµ$ò©´ÚwZ>í½Ê£*gZŽÄ7Zy<¥Ú”¨T¥{¯÷M%IA°¹Öc¼ª/P2³è?‰öª¢ñ½Öþ¸üöƒ¸ÄÒøÁ”òØ&§Ü¹”LNš.’õ'êQu© Ôœf´•†mÑ¿Jô;ÙV|¥%e­Jgzz9xež¤úTjþÑê7.,Š?ßH¬Je^-åØ+O(Ñò럴<§ç` ú{íuÏô?üpXš»ñ;™Ì˜ùoh‡°ej¸å@¼ñ]ĆKSS“šD®­]»vjZ0åž­:ÎÚ‘ñyøÃQ‡®«èY4º Ød´ë˜\©³¡«É[a§˜ WïS%±ú Í GC²}ñÉóDÈFšH›W!õe+eÓâ Éï]Xô…¢£r¸ååä¹ÉÞ¸€*¯*ª,Ù”¿çc`yi¹|üÁ'åé_}OmP…#A9sþ$öÔ;äíC¯ËÖ ;dÃÚÍRj0øO¹b‹øc^hˆñÎEzÈg*j‘d~ÀDè©?84˜ð´ŽÃÃ|,ã=Yù0–‹°®®¾.ùųÿ’42sã±²´Jø3BªùLD°F–† â;ÃõU•ÕBfƒÿŸ½7 ’#¹Î_ÞGÝ7ª GáFh Ñ 4}°OvSÝ$ErHq(j)þ͘i×L2Û±ÕjÌ–?hk¶fkk36³ÍŒ4;)¶(ŠÉæÕ7úDã¾o  @]@ÝGfVfVû}Ï#²² ™UY'ª€t +"<Üßsáîááïó÷¨D~÷ãßêM*ŠÛà.âÐñä¯}{"C挋¥àî6ß´v ÜQü6ÙÕÜ­PÇ<ôù+Ø€ïÁ ³ó¦Næú ”?zúP~PA†ïò;áºÓ°Á¯œ—ÿñÿÕŽšöÂŽ”ÞžL‚ †Ð&‡¥—7û •ý_|ékfÑJsgv-±ŒÜìj“ÏŽ~(—¯_T÷¡ð¨\ºv»ÓC˜£'\0¹6hbB±¦®:*¸3š“ùbÈ'ÑØ Ü返ﶌ‡'½?¦&ìttÊÉ£›š8ÏubÜ%}·KåÖ(ðcçÛ†Õõ²m}ú6­‡@Qb}²DÆ¢r­ýŽ\n»-4xAW %å1Y»qâùçaµ,¢PÀ”aç8­LFR£RæËg¸ æÔ)‘¿ù‘_þR°r•?7ÍŸs·6ý©ÓÕÂLáÂL|lÛ« Vò¤)y|ÈüÁÌJyî¸"€*xÿø'[D Y– ‚\î¦S€ç"ÌT7Öág?iiÁJÔ·ò[V°éÐ:ü€j¸ûû•Wì;G`PÀñÙÁ¶@°‹0gªÀlú8çB‘7†Å4‚ `¥ |hP"•Ùùv+Í*Xêç?¥®™ËB@XðÔçL«SÛq†Ð”îèd;ýë¿6V!à—Ú©)‰ ¸ä"Û=üíªµ‘\Y¦kÛ|lß…::ŒBó0Ûíûï‹üíߊ|øaÞ²&¡¸ªõÉHVoà@Á³?LÄ×yÅòH"„ÝØÀpþÍÇ>Ÿ 40dŠ¥¼ç)qºÏ!Ð?~n?o2ÀfvqCQêÍÀ¢çð³±j ï]Ç+˜3ºhÈ,8£nü6±Ý' Á Úœs J&áæêS4›Ÿöw7poàÀ¼=™ 9UÚl?\ÈŒCc Ì)þ²6z§¬…ÿy ’„çÜøÎ À½A ,¸ªæµ– Œ™|”óX# ˜àsaxà.u]8·âì2ð=h×éxÂû̯ÀiÐÊ~G¬ lö}¶_î>÷a—Láû„@ó,Ä (€e MGtÀ<ãp@š$HÌ7‹ÙT(ÿq€Éî'€Æê‡2/ z4ð 7 ‹ôAŽäjÍÅzNøI[ÏСÏmœ‰¨<燴eU‚÷¬ ®¬Îã`Gµíô ÖÄWv´0@JNZ°¬8±‹?8ÐÿÞ¡#Ã4,²~¬«º5€\èBüÈvb‡T4¤m…×ËŠê>1Ú¥ýqzYá9A¸´áðqãdªë#VÛ›=»bŽ{(~ËÒ¼-\`= t/¿ü²| XŸ`^9Âo½{¸ÙˆV †1ߣBŸåÙ—k/¼ð‚!梴¤UÖ‰ ¦ÙŽùÔ•<ðõ¯}RvPÐÑÑ¡s‹I7s\Pðû/'äù=I©,E切`2*ÏÙwu˜Ö|ˆgxë+[G4Œ7¼‡þ—Æ$Y³•þìx§Ûç¶3ïzû#õÒâH¾&­QVk“0‰f>­yÁ¬È„{¼"¦3wÌ9‰1F³ó•Ž%S¶œ30ØŒõ¬´ÖM¤5  }–• -Nö¹ÖÜãÏ®BNva ¡»þ6V¤eg3ær°ðc(šcv”hkM´|äÁ"^šVÏ-òvÑR`nó·äfó0) L"­³•™þ4°L–§¢b<ÓgêN^¸ žÌf?…ì|JŠÙÅÒtüƒŸ‚xÄe €Êÿïø¸ô†æ(Øw˜´.’ËšÈÃ,$01Û˜E¦{™”ƒ6Q`?ÿùÏUÿüóÏ/8¨`©x;vL{vc| *àK¨È£°Ö:Yq‚Àýb¸¿$KŒÉg×+WvSB™¿Zþðñÿ=ŽŒJ÷…Q9P»+¶5ì“/<ôÌý8h à³¶ßfâf:)õWÊ×÷üÏ3%›ÿ}¼¥¹ù©}Ïb<(o}ðK,>ı0•®žN(Q{¥¾ã¹c}ç¶Ý²ÿѧdmSËüùæ À)ƒÇ3ùuTHß"¨­ãšœ8sL.à a€ŽßÜ¡Ïzðœ´FCXØgàÄp4<"?}ãGrþÊY¬{¡ÿCŽå%òõ/ý>LËo'‡ÙAŸ;å×4­ƒ„¥½³M®´]Ö„a(»oܸ¦;W¸#;p|òz=™(ÊØç÷©Ë„LdžVƒß¾ÝOPÒQIÝß߇Ý01øÒôåɹ<£YöËõKÈëëíWåV÷Í‚ LE=]RØí 9eì¿Wò&(± îr–{íêÙ²~›=uH~ñæOu±> ó£¬;-Q¬_»YÖ5·LÊξÃ]ìv 5ƒò,Ð_/ó@%o€§ý±Ÿ¯¼X\‘ûoE¾ùM£°Æ‡ä´Jn˜ÖTSå0#©»¡©œ.ðƒ™ÊÕ÷ïŒß'9Ýpì¸vÍX>`ú\æÑÿÃÀv@,ýáSñSŸ•³çΛošòÒú'äÁ#߃l,L·ô>ã¦ÆóšõÇwŠ–AÎòO[›È¿ÿ÷fç¿]‡©$¸XFëÿüÏ{‚šÈc V §¦4€*‚ua"ë6eóªXÎẠ+åô§gÏŠ<(XÌ™ŽnÓ¹˜Q>•Š™,L'SZb˜iás)ŸÎÚ"’e$°€ |§Þ¨PÁ‚¥¼ñF^Eù]yì‚\˜ïÊÀË1yè¡ÂÀì‡ã¼ÿ¾i3ýä ¹žûùò9°…†·ß6VJ¾9þsÏån£Ù´@:tHäïÿ^°Âl S1Yé‡j|Ò»ªDØ!ÿ ‡TÀHôs‡g\Re˜½RâŠr§6,à'qu©º(¹²Ò9éQkÈ~ã1‡ÄxpÜuaW6V|m uu.ö\xá®Â *-Ìh@^\ì¼éUË}B/eÕxT‡DðN·$æ\…6‹†w|¥c òa{¶il¢H‡MÝ¡$WWlçÈç VšôÙ}€1Ë•Ç8@¢v¿E9禕Õ(6‡¿íÊúÂwm1¬l \PKe¶™ÿ^xŸ:»ù¡Z0ÊÜ¥­#×û`ÙŽÖ :D%(`€æ,›½&Yh‰6`=W¼\#=…ù1­;¬]»VJJJ2 f(øæK ùeb9¨ÒA’ã1ç#:´RáÌkŒe:&šwº=dëøe§3C1R`@å3ç3ú×|ÞãÍèJºšÈŠ0wt(4,õ¦áÅrœ¡«zofÖHCÃzàÂæMò7åC§ž˜2YçšÂD+}-§ÊoâÈu7C)+ò¶™ZeÓ’(A¤µ Û´õfž?LCT…nOu˜TŸ ëâp-DmëÊÒªyñZ•÷<×›8aFа’Y×(?¢ì>Ä$¬ä¤a² „•€éõ”G”Só« -ú$¢„™ i¬ìž)7R%Ò04&sͺ1ccãiùï'£òÑ XÛÄRÂlA;p QÐïl ÓO’g-+.p'*Í“s1}±iKÁƒeg=è+h1êÁŽ\äQXóž­¬ø’ߺu+6¾],ŒA1ÕŠ‘†cŽa``jàK¬*؉öH@ün> ²>ˆ]Ù÷£Ø™šÂÂÅ@ Þ†Ó–*pW}Å¿úâïÊêæuòÞG¿‘«­—Õ(^{ûîHÀ·Ûåôù²w÷òÊs¯äÒ`öu°f$d䮌˜ÿÿÙ¯þ;±oÁ Á@£˜¼X³¬hÌ%I;~þæOŒȇ!_|é+²÷‘'ô4º…ä¡ÑX+ؼa{T@“®Ã9ŒÀ CeyÕ$2ªävO(€§/ËCI°DÒ™äxŸÄ°12:(þ,z¬ @ËÃ#X´±}ÙªoÒ9 ¿Ùg*abÝêõ69=.GysBÏö¹nõusAëo|C¿E’øØ¼ÕÑ&ŸýànPä“í„m/8eÝ$IÝ¿‰À+ÓŒõ|7d¿¦J‚ µùîT ûd ·T?T›jJåKû7ÉÚú²iɃ©¨¬–v±Û®úzJ¤yÝDŸ™–À=¼I07JÐ Pº.hkùÁDZZ“8£¬/ÇîN,N©2¹½]„?*¯©¨îè¬Y_ß3ðàmòándîxÇ5ñN9ý¬c UštS@…=ù€ T|Þ¸!ò—i§øøÕò²Ü<ðyP9Ê:Ñd?óT@‹ÜõÏz1Óäñã.o½eèÁÿ¦ú¬§"– ð}¢ùx=—@ÐËøŸþ“(9hòž®¥x²…Å69^à$U°ÍǸ1 +Öcj`ù›ø|þâ/ÌŽù¹ìx·éQ‰Nú,Û”À5‘üÝ;ÐÞÊÀñÆîN3) eJ™óÙÓõ†-S¶©ÖVs=)Ô‹¥|þSXg.é¶‚åÇ·vÎ@E9æX8Sàó¦bŸm„òZw*- 'Û"zTnTij Sv|>äGàl÷ìù‚ýhþ•n ØùœI‹Ïg6m›íŒÀ—“'MÞ°arÿæ3cŸa»æ¯»Û\³¼ä9CèZW&]-\µ½?B"Ñ c3võA××wR|VƒªÓ,0¢ùQOêÄgjûu§[ÏœJtìÜOE±ÄHÓðq¨# 8Påú¬XåLÌÅY°C_twžO8ãXÛ…µ/”¤pŸàÆ‘®\…x`å€î\°>á‚u6 È‘ œ±h~$ñnâ¢-æðº6kVñu‘Õ†äkÆ~€ ü¥0OïMˆ`§F}–0Ðú^À¾•}.ä@Y ôÕLSôUóM‡”ì·‰ öqJÞLzÆ[ Ûš$OzMvŸñ@ÛP÷ Ô¸ Ï0ø~W .Ä£MÃZÁ8@ÃãqËÍú °™‰Âò"ãð]¹8î°¶ÂbXa <.ÝCcÚ‡¼è+T‚Tøà6})@|e¥K-ø ¢!è#×cdŸÀÏF%„ÚV €»ò PÀÈŽZ µN¼pÁ×uŽjš Yð‡ó2 œ`þ¨\I¨üìk¦GS‰ÈéΔé¢L:„„ø¾°d®µ\†®-K%ɼL õÁAiñߟ”iYñš¬/çÓšÖ:G~M¦ÄÉWšÄŠ FR|.‘ù“é‹,'ëÎ =ó3!Ú<o?#•ÛÄ‘2¼Fâüúé˜|Ø:w@ÁŠ€K¶ qÈ3óXÒ‹CƒŽ¾Îüq[ZZœÑRñ jŒõ ¥ž/tà «È£0©ÎVVåX¬ý£?ú#¬Mÿë¡çugtaœŠ©–»° B|•x¹= ëÕUµràѧeýšÒvëŠ9ñ™œ¿zFM'R;:: w£ôÀä‡|÷›ÿ ûDÏ/} ˜¾íÿöÇ­Ö âPt381Þ5T7ÊêÆµ@Ó¬&vðCƒ»ëŸúLza®¦äóÞ/äƒOßÁâ v !øýyùs¯ÉóO½‚…,X/r ¿æUÍ\0™ãŽòž¾Û9@ð›eQ€r£š*ù¸»™Jw*íÝýÑ(^øQ‰É£5îÍ@õîÛÌOÀ奲­$']*ì >À˜ Ü%‹ï*0ç섈.Áì5ÌÕçVãz#·4q‘3[>¹ |î:§žmI`Ç™ñxÜ!ñÆ– »…ÙdX U x7\@°ÇrŸ0Ð 3ïñpš{5ª…veÕX—¸QßBCI…S|%)€ºÞmòÍ‚@¡Œr¥ƒ |áâÀï-½Ý\áWáÐÒ€õ¹ðný¸­ZÒS¥8Ÿ+ÓÙ?œ2­¾6qd´µ°Ž3•½®dë‰YáçÁåy¶°dE·ø‚xR*×)bº à.â°j€_|s~ü¢°lƒ¥~7*Ð Á¿0Á¶h@já(Æw„á0]Šà爊§'‚sÓnªË}Ræw£-y¤‚n íbS:ëÆÀ¶eZ¡0H Ô›ˆ$Þc«t;Ô©ˆÑï`+¶+äáQÛ( T²¤%ŠwÔ±ógäÚÍ6¬ƒp£ˆ6@›SÁÇëwÉ‹¼,ë6b3 ú€Í‹°{Þ(‰À6ëûœ Ôÿ ÒÒt¿º`=& 7 (Ë[«½0A?1Tž3×%Ø—–)µ²`—Ñ”tN§“•ƒ.%øÌÝ”‡õÌUFsbUÌ´L%Àµü:H¹æÁ ›»áZ‹kôÐz×eîE (€¿.¸ÛâfDî¦þ§¥¥%³N™«\\‡!Piu`®¼©¯ À€ ‘ß às¦ôӓ݆CÇ“$>€tü‹ƒ`0íQ8l÷ùRÁËÉó¨¹zF‚•òª~6™xSß?T°3p”VÓ+e<3ð4¼MŒ=6Ûì2é8Î[ôY^ÍN¢81ùY” åÆH«tÍ`Šh•Oóñ6Ø÷ )¥¥ñ¸;¥Á2+M-éN䳘éA]ûàLÿ1³þ·Ò[<ó kÐçšQæó9 µV„´ÖÁ’§ajQDœ=øhP^äÐ`+úäÀXÒÑòóȲá¨q<çóav;?ËCè…†‰1ÖZÏŸÑ̬÷qƲóBc˜”ÁæÁ¨Ÿ±ö€s¦Õ.ËgÂKÃ6åõ“Ë\‹ÍÙBAP ’_Ð?Fã² $—•Dl;vìPFDp-tX*Ï<óŒ<òÈ#ÚÁ£+yÖ:f++¶‘]»vÉŸüÉŸ¨5{@.ŒÛÌ©°ûæûßÿþ] «á;ö{ßûÞ]ñÅ®MÊ믿«¨æ,î† 4`W ÐòRàKž kî¾^U×([6Þn¸8"ŸüD†G‡ð’OÉÀð€?sXê±cþ_¼ö/1iXZ9±Ÿ ‡†äÿøßåÒÕ³ºóžM kä ° °iýñûJÄ‹ .šÈä„a ˆÖ›Wç *ˆBqÿÎÇ¿‘·?øµŒ„ÌŽ3ŸÏ/Ï>ñ¢¼ú—¥¼lfÅÝB´'7êTZ2ùǃM@N 4Y_QN3ˆV€ìèÞbå§uŠ™eÇ4'8¸ðÀ8‚7VZ e™Êò‰:0ÑØÐ,OínÖUqâãÆ°w¨e‡å.o>ËêÊZin\pqlÖ úûÔ †]7äUQ†]¢VàÇì°Õîí¸âqùI K‘ƒ}YÛPev­PTö‰Þ ìþ´éõž&Ibh¨Ük>8 - ÆBUþQÙ¸˜ FþæX^[QY(-*aù+4Ç,·J^•«3Õ¡ï+˜"„/¸»É A÷X»a¸Ú/ÃÕ>qAAå´•3d¡dºÏ?».|·ÑuÇw¿+²~}ösÎg@w¿ú•„Übö1\ì]¨þ2•;ió7›þ0•ÆÔkÒ#À€¿7·TÈÕ52Ž]º÷O€tï“è÷ª1__/QX-ð¸Zò<}à|AÌ}¡\儦êÀ|œš€¡,/Ðï¶ô8v×Űªº@ ¸8›ÑOYse„»¾µL\dÆ/ã>A­Lp¡˜îÒ©JXC¨ÆP\@—è2µ2u+à/>‰$Pæ„kõ¬$À»æP– p~˜À«}~šn‡µ4>¬¹f¬+É©ÝnÍ6îfqßǰènø†ÕÀWs‹<òð>ùùoÿA.]X“‰P$$‡Ž}(/>õr^_î‹%(ú#»ÕySÎ_>¥ \ˆã®ùï|ýd릇òºe@µ \ã‡úìC4•¿+¿zçg27 ^(•Ÿ|ìùÊ+ßÊô³çš;G‹7ãXdÈ Tû‰ÂŸè'½¬¬ /¥úÌx›– hm¢Pw§Áäc¶Ë¢¦«+`y…/UªaÞÝÜuŮǀÿn¹Ùif{\ ò¦åŠZX,Èôg‚…¦"à½X¬Ên#l¡Ð½QæeÊZ<™QüX‡µ.¾–ÁZAvè“ÎÞ’0„k˃òäöÕ¸÷Ç~.Ö2dÓшeü'‰]m#>¬ Hu/}‹aYH»kT1ÍÅ|ºƒhmÍ€Ór–æî¿ó‘o}ËXc˜šèÜ9*°W:¦Þ_äëþ†€ô7eŠ¿~÷u`ZŸÅ£f”™úR™þÎ;Æí­1ü%0Ps{ë¥k=¬Ü— …iøzOWCQWŒj”;Äíì¸àvò߀noaÀ*>.@æèg Æ"$ÂO]'hÀ_ J}Æëâçü}Øk°Ž\”ϸOàB0~ Æ‡c¥“þÑaJîhs"Ž;”PšeXC2ß_º ÷Áå7‹d€ ÂU(SÄ{áÖ è)ƒ›ŸxÔ õqc÷5‘ú ZSaýåxÎy¨–ÑR6è-¤Í›ê ‚ &Qä‡ÞäMCúES$“GV” ­¤ñØh%€àªG—‚2Ê"üâÐrA– ¢p›¸ †¸ç ø¾JÀÅB î…jzj9AŸ¦ö"=E¥îE<à—”ÂÅÜ£TA—^ “ ®ŒÛdÓz£r“âÙEðnKT€]ŸIÐÚ{nËå+çäFû Ýá;—Ê”Âbâ û¾$v>/åøÞLÝ6€`Œê †|ë)%ãZ.2ÅÖñÀê[†‚ù˶N· €*V ­Kv%æx>¬rñ ¬Šá¾–¿kiY¸ ¥jàÎëQÌi *8xð \»ví®µ¥-ØV®ÃýA/¾ø¢<öØcja!»---ÓZ3ÈN;Ýùlÿ⥴<@A)\¤0¡‹|jg†@{jÔñÚ• ë$ÞËfŒB<_»ÈÂ!WÓ[Šk:º!=î:OZÚ}AS̉ÄxËè‘yG=7çN%P múmå2çš@ù˜yÄ„pG Áx¶=bɃ²0T ÒÆxÏ5ÝíOЏÁ¢2#ó˜337ÑüzÇ®§©pòkÀA-˜å}·(€M‰+“Œ•ÓR‘©•WïäþÃbi*PÏ­, ²À|’;üµÂ|5€¶‚=†Ó%&5y'ʱ*C-Î BÀºiË UøËL¬ùX¼y­üY~Ä+æÀ¥ÄÜ'û.iâ¾^Ú±,‰™×e2’&‰°`4†‰ÈNÄ彫PÀì³ Ã%%7sS7j?ÛÙä/¦^+T0}•Šw‹(JàA”žœ=nô]5Û@ôdª$&ÁU‹ô™m™îYz¼Ä¹sµ¦ªòJ |òÿíÿ‘þá~¼ÛSص<,·o-9¨€ÊͶW±s(|LÑïܶ¿]˜tOV -„ìbPÂ:þ‘üì·ÿ(C@ÿ#°=¾û€|íµoIMuÝB°)˜´ ‘hŽ?[œ¹‡ÉX`ƒºšú ¨ ‚í]·dóú;A3Í ÍÝ¢Î6¢›æýK%@-/. oJ1ä’2ªÌŒ£ýðyòÃfªÅ93\ò&˜" Ë™€2ûÑž³eÃ{ìW•– bhw·áb#‰7.Ãò”¿ S)ópàfϰ<¾­I?ž¸({¹³_Þ8|EÍܶ4TÊ#› ¥µA椵›Žúñ¸<«9¹TxW`ùåGjäÀÛ“ï¯î¸ìå—EþÍ¿1,âaO„À€<£¡!cycÀú–lÝ*°*0ÿ%² ;븘þðaãÖ!;~‰ÎÇa¼k]¹ô5TËÃÐVðè¡#êû-46`Ç+¯WSëwò¤À„«®LM½k.&CÙÑÈ}?Ê(Gç ¸åìãur~_+fìž+­•‘»ŸS¥øa'°£ ÈâŠõºØü.ểóìEèWh“3 ¨Åÿ,È8·ã؆ó…pÑ—jQ³ÊŽNm AÚAË21,rß"”;‘Ð ÒŸ¼W\p!àRóåØaîôåø&ð—¦aI {3ŠÔÙ.»²p…Z%ð»K`о\|(+ݪђ‹Ž ºàŸ5Ž3ÞTØc½^óeµNfì,Ln¿xÎôªŒÈJOzEÓÂËŠ‹ïn5¯ ysú•cŸ×m ’è'~ôgZ3€Ët]>p‰Å±i ¬¨û|ƒdž+ŸÙ<‚í>!Jª@ƒóîñB«¥àÚ`TªÊ‚X#Ð>ËpEâÇûÛIÀKvÛãnÈ/†oß×äìųp-xåf¿´cániÜ Oìøœ<²å)X3Ä÷•ýºNe ¿£²Ú»º,PÅ ¢ 0°¾³xžÆ÷<xz:MYRñƒç¢tQxνV¶‰9ÈwꓘVVÛÁÃAùp÷Ï‹áÇ0Ûj‹ûöíS·ï½÷>KÎÝ3p7ÃѵÁàà Z.ذaƒ<ûì³²ÿ~-/]~ûáŒÖx;ÐBÁ×^ ÈÂ|Â(^©ô…M) úzÁ_8@À®—ä»Zïðõ`vðó3ÍïÔûHÃdˆÇÈ¥yiW†Qjê´Èƒì•Ó¨ˆ6Zg&"¸)¸6dVNÞÀ5#H‰ r%a‘žt9F2VãjÁäÓâ‘¶}“ÓOcé’2NÕÂÏÞæ‚$Z&–Aÿ~Æåƒ•𬴬æÚÊjÊj×6­‡%€òéñõ-ôö/ý.µLúµÞ¼–)Mη¬Ù°(€N<ŽŸùLþéW¯ëî~2¥²õÑûä÷¾üíIæâ3ZÌÌ F`ŠñêË.,O,5d+€37qâÇΈæÆ5ÒÖުѡð¨\½~Qž{òó˜û™É\vúìsº¼8s +¨•‚êZ,úb1d…ʉ¦ÿù±Âï‚Sn÷u£-]‘M-Ph-PXîòƒ®;ŠWöŸj‡‚ô»™hÑ€ò²åÕ}»S®·]…k”™)v¾âñÞI 4—OÎwˆ ©›š*¥£wTÞ?uSG±ƒ  î8³#±±9Ø’³ ÜÃã(”¼çöÕËöc½R1hêw‹SdM«{÷ŠlÙ‚U&¼/°(["/½dÌås‘žþA¹¨K`ýÒÓúϧºLø‡ùÉOÌÔüT3]ßi.•[›àž¶¡ñÚ¼³¦TúV¥±=4SÖ•u>hå+_ùæ7Eª&@e™JЂÚOj,`~”/܆|Î?V' aÙy¬§à³|ôî×x‚8n}öÂj£°Åü XFLûd«Ç ’k°ÛyÞW71 œ‡2°sÔE~¡/çP‡kÔ£òÈõÎ4@é~ €"ôˆ±kâõ9¯'—¨+*¿¨Œ`¡Ö,ÑqÝq” ‡Ó!üÉ»üÀµL‡;ñ,óˆ?Óê~cýÀh hˆeþz ” ÀÅAÐ$€MÖ´H@×\¶“ý…ªÙm†ÛTzÚàTñÓEeC€T w>È‚‹¿Lp…¾¤ þšžéŠ<hÁÀ­[Wñ\üü&L‹/À§úq…$ñžT@Ùã­f»OH`a±€lÆöIR#IéŠê7¯ºO@× z\R— %ŸT”¢-ÃRˆ@žçGÎÁ7óM¸6V 5iÍ6loÞ,Ï?ô´¬_»]‚°V@å—ÄU޹‘­µ!xÀ ê²`ÜŒw.šêW+zƒ˜!¿v)Z°úM îÒ‘A °^àø¨AãÊヲßó ÓÊŠ.!¨dÃF g6ƒè˜Êù¦i¯óå]Ì¿r$@«Ü©ÜÐÐ T4^ºtI<('Nœ°DK_‚ :;;¥.ùhAáwÞQ÷Õ;wîÄ|È+ûÒ-2×^+Pð•Ež  ¬„]„– 7¾f¹~F5/ǯûuöð6ýH8'À°Ä„!0¸ ˜×M zÅ? ‚ô€ò¥Õ ‰Ó:QÀ‘ôqnØèkŸ§šJÁXÖ}¦Ä©Q€ó¾UHV3˜tæÜä×¢£>¬—¦¶L/h ™˜ÿõÜ¢§ÑHÏKÜ36xaá*œ¬¤Ld_ªæ·ƒ*àÉÀ"fÇç8j™äöPʪ‰7åç-ž€Ú<<– ëý¬ {D1=ÿhn-c0Vâ_Ær€uÅúª¼,Zú\Pnv0/ãu:`· ëù)_%Ž´8ª¬Ágj­(-¿– åGò(¦‚ÆB@’Òl‚ (`ŸïÀƆ"¨`6Ò+<­ùb)<}1eQE %°l%@…ç6øãýã?þcùñ\˜Å¬¥|c’ À÷Å0Uœ_ 89ñ±‚ú++]zð…™HLL'81 òº@Óîí]7')S§KÏ{ÜÉ~æÒIù‡_üPî`§ýÌïÞ¶G¾ùåïȪú&[Ê?Ã#ƒò@7nµfØV”UÊŽ‡vë¡LdÖIEY…lß¼[>=ò*Óiy¡­£U®˜0µÖÿVg›œ¹p"C­²¼Jöl‡¢(OHbq£h@n÷tbýÏ-õ͹-(äÉ¿˜ÑtMP_»J¶lÚ.—®]Ð -w :ú‘lhÙ¢ Á)äÂGå,…„C£Òܼ¶à²†Fä4žgžèê¤mÙþ ´ãéÞcMãZY™ÑB?è6ãÈ©OdÓÆ­ÓòäGïíÞ.Èù¼ìغnT°ó5+ÐòÅ+·éßO¤¡¾Qê³]2LM‹rw ÿò#£´êk²RLœ’.ëØÞ´ Ìç݀߃’ t÷Ê/_•R¿WAC¡ü ÷qŒ ##ؾCözonª”g|þÛÄ‹sÅp%Є÷cs3¸º€ÀU*¬ù›Mà»ý¿ùÏÿY¤­MÇ¡Ùd_ˆ´qø?¿¼»ZnnÅ|ÇšÝÜ\!­UJ}WD\–u…àuOiðôñÝïÈÔÂðYüú×ÜAËyB>®Ï>^/Ÿ¾¼ ‹QñE“²ù\¿½þ•'×òˆNaŽË?]çZä"±]~¢A>øâ:éY]j¯õ-2×åJž»žË±ŽI  ˜oÅÐÑ…õe€ ®â<{[ð¡8h·?«»À|¤\Ç>;ËEÂb 89JÄ;ƒ~ñà•–„"‘îâ\àåê2@YÜñìõÁêØGb£p=ðÂõAÖ `ÞË>ôP6NªŒ’Õ‚½°JPê+Ÿ`”ÔQž…TF9˜i}¬nÔ(“"S°LŒU.Ô:“ÇôËL%Š<¦<»å!+>–IK(°V“ÆÀ ðTš»ÃÑfi.Û}B.&€qÜð × .P°-d“BY{F¢jÉ€À[×Q‰ ¶Éî6¸t€æÂô¼ìl¿ºï5ÙݸIêK«°)ÃÛ0'dï’ŸJ &Ò¨ NNôäŸ"U““JøñÆ"ŒœgA®V"Z*°Ëoj1·¿ÓÈJÝA@fšÈ‹ÃŽ#scU̵ò%PRR"ü­‚u´;vÈ'Ÿ|"GŽQºTòß‹ÀõÌîîn´á›‡JP è’›ëj‹*  àË/:äÀ£´è€©Åè&´;`ì4ì;ðŒ*eZ^¢BÃ5qæ|@]hF p¾‚tàš›Ž½öÚÓ¤ùßÈ´H¢(¢Š¸§àÄ‹¨4"Q÷b·Í[ù9UùÌÉ$ÓíÚ³CþߟüŸøèåGìƒ3$†#!ùÍû¿Õëä±]cñn5Ÿý©¬ Éõ›W3ÑÈxMsKæz©Nh^“ŠE;Ð Â…«gå•翘³üÜa}þòùûŸÿ-™#v¶i ä¹tý‚üègÿ@„.¤… EÔwçæ‡å[_ý®45®Fœ5iš–Rî›tApúÂI세*{wMë¡ÔæažÀ‰ØzOÞÿø-ìú0»¨Þ¹u—<þÈyrÂD¥ÏKëeuÓ:¹Õusã”tB™ûó7*¿÷¥oËÚÏýäµ³òó·~šq›àÇNö­¶É·ÉÉ‹:W[/ÉßAÎ!˜h#BvÝêõòµßù¦¬ï{0Ù­¯mgŸxIZé>ϘÏáØ™Ãˆ4Ê3^‚ß´ÅTe8”ù=P²¯jhÆ.,‚O K!ïúí§GÂ-Ç'Œl—{Ÿ•Èšî)ò…H$,GN*ï~øëÌ8ÈEéz¸ïxl÷Ý퇠¡€ žØû´ºþ Ý0äuôôgª¬î©—±À|÷x16‘“çÊÛþFÛiî2²AlË7;Úзþ …>ý–ijX-¯½ôUy–P²ÓLÀ~H`!žU³|ñůÈö-g'Õ•Žî[ò:èÞî5iêšäÕ¾,oËÝf'¸O/øPêoº*Ʊ£lp k”fl™.ír½ÁNÍ“O7Ip4!O¾Õ.¾Øâ|ÜQñx§9e²H]Wxo‚å*ÉéË¥ 8èŒN´­¼!4nò&(àÌÊ/)ò_þ‹`•ÏX6( ÛB&á³¾¼«FNh”0Ú—ènãìþYÕ–QÎû!À׬|ç;Æ… ɮסC"¯¿.rãFvì¤sÊëÊ®j9ùä*®ñÉX©[ÁŒ ˜šÞz¦O\´ŸºLC>¹Ïí­•¡ZÌ«`]¡æ•J‹F`YåØÓräÅ&ém‚"]wü.¯•E‹Ñ©ÚL ƒ,е@g½йë0·~;õoc¼5Šö%¯×<=F)î°‡‚逰pŠb]),T³ÇœHMž£òJÒzÅÅc€ÿÃb€ ;¾|¿¸±Ëу£ 4 ùo/®nìö/à3ÆÝÑAo~åx`ÞçÄöE¬мî]eÌ„lùxåKÏ7ëlóÌ6}‘GæQeNáy¨U<ŒqjòŸŒÀÃÀ ýo³!g€PäGã2åo<ž–1bð[€ ƒD"…q èLiç|ÂéKôøKGc ÈØH»ÄC=Ø4Ï1föLJaQà…}_’Ç7î• jC¨,§ŠÌn—”-¾Á3´U nUßo´D !k=€à- þàý Ä“I¾Åôú¼V8]ÿ°…d‰`.‡ieE¹‘ÇiÅžB@IDATYÍ…O1Ï}%º ‹={öÈêÕ«Õ…îñãÇÕ-B„–ÒîAàf¨;° Ö××'ííÜ€1óª¹SùÒ‹Ny€‚ ¨É5*z‚Øk °”θæèd[¤ÑÑHßóplCÃPåFœM¸Hñ>Ç0‰×´wµÚˆG0Æȉ´‘ˆ'8WÚR2¼@µ5ãh@ŠIHÚ¶eÀ£­ØvªæÞÌO˜†©ÊÛð`q”Þã9Oìò“?¯M*žR"¦ø”‡’&E$µd£iX(%¯²9’‡ºbàûA˨IÔ›“9+ä/òj™Veeq°ÎUOÚ|ŽLjÕ%S–‘7XM–“ïFñ€º1Ú¤À_ë–kßS²Vv=€ŸÊ´•—@j}ˆF~/^¦lÌÇ`Ò“™Yù!«±„à ®ŽË0º¢’4Y ú›m¡ÀÈ¡ l³NôÞÇÇä“ÞÁ…­úÁ ö æÁ•@±æE %pßI€ Ö­['µµµ:QìééQôçÈȈ¾ôªáÇ· »éè.Ÿ¯òÿéÁ{D¢ùíÁ_Âü_‰>þ±<öÈ~Ù \%v¿ÛJùËØÙÍt¶»Ê–ŠÀš*˜Û[â@àÃúµ›2\ù¿ÒzQ~þÛŸÈçŸ}M¸Sœ àþÁ^ùøèòágïªév)p¢EÿøÆßÁÙ-$7S‚ª¡€=wé´œ¿rf&2zŸs£ÊŠÙ½}P)o*xI笜:B•î[ °_·z£T•W9]® †ÑÑaìüï—›í×åØé£Ø}C†”ŒÏ ¥y½¼ kù4#8‰âÎîÇ}J:»oédÖ h€®$ž‡rxmS že­ÄpÝÕÝ®;ù?>ò>Ò·ÛE–ºšzyþéW´­d"³N¨ ¿· W¯]Ô&¼5†öu»Õ—¨åá3ضq»<²ó1ì¸ÿL=ýwäoÿTnvݧö=‹íRY^™QÐ,18Ü/­·®¡]Rà„»¾^yî5y|Ï“Y0§K!oZ‘¸ °Ë5X›èºÓ §eõª5²mËNȺm¨ ÖÄËhOÀ\^ŸtÜi—Sg(r^úP_;T㙿ðôrK˜¦¼´\Ù±OŸøTº{ºŒ¼ Üÿå;ÿ$]·;d7ä¸ ò –”A!Ý'·ºo,s\®\¿ ÀÀuŸMVÌÄ ´nƒ,ÙþmÄý¬ ¬_³ñ.PÁ-7ÔZÆIIèâÜtîN¦‚ .º©iO©k –»î×Ðò ‚ j*Jä‰ëar ¤ÑˆT”øÕÔ뇧®b± Ãb—õí~X°¸rCF‡'>4)Àèby°Ö/½ºVF¡ô=ðf»ÔÝ^Ø¡hÀ%‡_\-g°»$œ/l>; n,LÏ7ðMƒWƲC5~˜ýHe_LjïL#ÛÖVÁ¶Ù(ÝN,"pU¡À€]:òÖ["¿ú•ȱc‚‰4˜yá’%±Êuåáùíéö:î$Ÿx:Tž·m«Â½uP”§dݵa]Ç™ ÷®µ¥2Rå—Æ[£÷ÎuG ært{@KX`½+\¿.0ý%òé§Ó‚;:6”Ëñg¥î"¸¿í¡*+óJ/ÚÍžCw¤|º'èáâ£uòÁ—ÖICPÚ7V(0iÝÕ!€‡f»Œu—ô2 ìܽ¹¥B¿Ð,Wv×ÈH¥–‹‰R÷ýI:íÁ|nR•˜+¬‚òo'üºw\póãV )ËÀõ†„ü@|=PÉ…WCÆ¢V 2HF‰Fànäù¿7Øh½ KñÚ&`PNáÑ÷ÆÆdlK|z³^?,$í-뀿hÑ€@·fÓaÍE%‡kŸ+ñ%âw"=Lª»(3òéò55j¡ÀêªdAp͹š½*Mà©} {I8k,U³çjí…4Q^ô}ä#à=‘‡ñEÂÊ—•ÏÜm×®øÌh€y*£©{'Ø × t‘ÄwëøxfSÃub÷°>1_ Ñð¸)ñè°öK-ÛÚ,BsÝ:yz׋²gÛ“R,SÐÑè nøfd UT¨ïPÌgpUÔ£½ûôž«¼ ¬ñ}Eûþ&#Cè̘¯C 4ïïÌŽ¾ç„ut^ä°4XÁ<ÔmA. £J¦ð?ÓÉŠ *}®oXÀŒ4žCf|)œM1å}*ÞõpÝÆõa‚ öïß/§NÒß(6ËÜ‹ kPX/bXÛäÇv:¤ Óv¾eiøžÃŠb˜4†=Ƕ=€InòÎ4ê Gd`€"ÐOŒe<¥}8Œ2ús¤£‘'Žï$`»<`DyM_D¼ºH0üíádH€Íç«bdh\Ta žFO™ÓhÞe° z1Á‹wXû¯9’袌&¯¡a¸… 0@N'’é·!Úî˜GÙóÄ>LhÎ˜Š´xíàFAI’„V#lzŒ4õ&¦Ê¾­åWðÒ€EDË`•Žq¼§Åâ}>`+°æžÍƒ7x©qƒÕÒ4cxÛµÎe5ÉGƒ2Bçu ¥mG–•.þîȸ¼·Ì´PðÉÁ·eh.vTr8< 3øb(J (¢î? p’Q ;Nüµ´´Àœ]¥D Óu¯k§ôéÀÎÖÎeYyúìî C9†Å!¼]Í”háŠ:<<$ƒ#%Ò;””ÎÞr®uJù£ðÿ€lJðROI$ þƒBåk<^«‡Ê’ Y¿þE9záö¤ÂPÁùæ˜Ä°ÈÀ’AÏ W>;Û1)]® *[;±+ÁÊ›÷JG󮼜h UȪƺ㙴ú†òó÷ŽÉ±óÝ0Vƒ… ¯*´û¤¿¡áqñxšu‡5wé3„cðù{}XFc“ËF0µç $H$4-ÿŒÇ\rèT»>Sx[Á”J*  nëJHËÚ ZtcpóNRú!û‘ˆ´u¶ÊÉ‹½ûqX[€ùR˜bä.rî̈c!%Œg0<_j ¾®WªCªÊðѳöéìwÉí¡ÉuÈ0²NRXØô6KÓšÏɵ¶ËúóØ…;(ÛoÀ· µ>bh‚Yý!ìnN§j•W€kÖ>.}#Á»ž‡Í+• m#@•b‘Ä C¡R9{e@Ê«ò—õ»Ö]"YϽ«Ï“—M{®ù¸8U]÷¸KÑöÑþ¹Û~Ç)½Ã—äÔÅ>XvHãBÇq숉aK&)Cá°Œl Á×\…Ô]Änwîz-¶¼ia¤w´D¢ãõøA‘:–Ö®V9u¹ÖÅ`lÃ"0@041JŸéÈè Æ?JÏ´iŸ×/uõÛ± ¾^Ž_œØòµáˆGšW?-]}ŸAX£¼n;Ð.Èá³'àO‹4q,ÎŒÑO·Ñ?fê$0^óû¾IÏ’&EÏ\H hV ûå|+\9L'@8s¹OÂwì´Ÿ\¼>:‰&o1íYÔ?›:¥˜¶-tWZ›ÖbûBƒr§³,/iêA–˜>˜+Ñõ[·3}!ŒòOG+Wþ±°¦c9N`­‹ò«j+eM]¥Ä±ÐïE›è ヂñgL~òáEéI{ïhä¡7WèîøåNãÏ ´ëXW.»Ü–íG{¥ª~Æ‚.¹¾½FN?Ù WwÖÈh¥W•1ì:|Gö|r[j`Ȭ(?.€Üi*‘30ƒÀΑ;²í{±LêSQ>ZsØxÏ•®¨§ï÷[ªäÈ MËÓoæû2ÕÆù«¿y÷]]QÉ(‘ xRy Rúƒ‚J øÂ vˆ{DÝœ;'rô¨±LÀ8Þ¿a´Â+gö×ËÑçWKÜi?5ÄáGúâžZ‰”¸eßÁ.yèD¯”„ÌürjÚ\×Ìw ù=Û,ýõØ)umDöƒNËåAñÄ9†.qàsèê2.ðÈ®j%â7D~û[Lœ Üȸûžæü¯ˆAw$v° ³¥LF¾²^», §íh¾ýg¸Ú/WwTHä•õ$Ã<¶P‹Ìß_“O5Ê©§WIú"ŸõùÇë¤ÖH:Ù'»PÞU¡y âð×ݹ¾Lûù•‡«\(‘Æ”b(D´^@·0ñï¨Hn#æ=˜ÓÃz›Ö zAäô—|EG›Ê ì4Ô“ÂuB2é“‘ž‡aÅ©;ÿÆñ..Tpt9"Xć{ƒªKó¿dÊŒG“€TܳŒ˜·¹ À§E4pA¿”R|³”—×âÜ-(ßÜ耘Žï€ °nÂï<"³Iå Ôk¤Sq õ]‘h¨®Eðn£"i!žj”ký[$~Þ'íÃÒPY‚yw™ÔV¥ Öz2HŸ. èæ@­ dñ³Àw±§Õ„8¿ÇQsop¢7P9ÎßÔ°yàÛ$g?ŸZ·™®ç"«™hï?p èŽÒªªª€‰n”—_~YNœ8!}ô‘ô÷÷«Âó~Êíž´\o¨ À.·“øº¦ 8|«R_+Í ÞÖ@ì1×´H`Gs·ø³]09{:ÉòÇr§{ò³l`|g¬têxlÎuý›§/p¾ c8ÆT¾)#×Gy4-2:£À%ÒYpŸÜ4N£ÎXså]-??äõB3á &78à¾]Ï´¥¤g ê”…•<4 #¹±lv0Ü©¤·„A¤ÂLÉíò1-XÚ½²•þäoÓç}“ÞÔ@×,øçû×®ÿDZdÂÆ3;ƒÊXó˜k-o2“•PoÛy4ž÷ O“Žy‘€UÆæQ^˜»Ææþᑉ9Y(ؼy³¼òÊ+ê>ÄÈ´!ÐBÁ§¾[0 Àeÿ¡(Ë‚ääÙÛ²(R±E %P”ÀÂJ€æ¼ƒ4ɻ̧£0ßü“·.BÉÙ-=(ìð!½;!§Vf£»ñ>Ç„ ë»ýÜxˆ9ßñ.>bñ†O%° ‡ÝB"ü!àþذW~ý1vpÂâVàt! óç#ãh¬ŠëÓ­éøáätYY2§\„ G¢yg=rÑ+W:ïÎK‹##M7V H„ø»€ˆuá;;®&ã%¸ƒgî€ßù¤S"½~˜S4JÇPÈ)?y³Jdì˜P˜`ˆîœËÍ?CsÐK¹Ür³·Š{"M ÜG ŽXr"m`Gr.ÈðƒFš3÷9AŠ yå#còáÉ™øéN’X…ë$4NzVß~òÕÙ#Ž:›$šŸüÖàÇ[ c·ÓǧÓrìR~ J?ä}óì™7œtÉ'“ròêÝÏ÷ô¹Oj3N9u-™åÏ3Ÿ|œ½Æ,Ù¢ w-þ £ýßÁ êË.×8ʆÅ+´mClGP”3„îxóÐ(d’¿Œ‹)o‚BŒY²Ö6ÐÝ»`¨äžÈ0+Î×J¥õö%^æ |>c1 £?pcê#»‡ì+±j.ØAЋÆ=ò³÷nä€Îi…Cáø¤²³o9ï–+“åÉ~ŽŒeÆ’д®våJžœc×ñË~ÔqrZ»,‹qL`‘r$júN.ú— ¬;uø×¹ni-;ØãgxÈ)ÃGg7EOU…oe†A–~ýÉY úÙ§Mˆa××PÈ(jG"19v¥Àš—Ŧ'¸J ÂêÉpÿd°˜w¥ ø+õÈõUÒ»:('`Š}-¶`¦¾ùvƒDgTra€¾áo¯-“Ömr»Ò{K Àô •É 0tµ”Ë”šÜѾáÒ ”¥ƒÒxsD‚¡„š‹Ì%3îr(¡{]™\ÛY e}%vvCa†øK0µ¿áòlƒ2s €mT¼ê‡vB,#ªíØ>u-̵×vGT±ÍÝó ä5tý_º×”JÛö*(Éá{,!ë® Éº«#pá :´7޳ü¨GH@))õÊ”Ý]g´m­Î z½óHÏô®H€;g;À£•“'E~6wS Ì;‚ô½Ã1…@Oú/¥Âz;aMJÚ¤3C  ÂØèa>Ö"¸Ó$+CÕÔÏ|{µQ„Wy¡ ç; w`žVÈ´oUîêe=ÚØj¤0)Á³s›Ý:+a:úÀc}9ÚU¥>‹<Þ†Šç<—‡Nõëó)ŒçmG¤ø¡c#Ú èVõŽI}×d¾,5ÓALÓÊý‡?yûmúL2i9(ð¹ðyôöšc*ÜáÑZ9} A¢hoSû ÛàÅÇê¤í¨¡3ðĬGŸi¼‚Ë’ñ™Ë¢v¿ì‡¼»Ðž;6•Ëm $¢âþÄSQíëë/ HÓ­°TôIElWì1ô_öãô¹››+å,Üe…P¹7c5 €O'úÕ@]P.=R+M7`Må]ƒþRÓA_™xN­«}M>)ÜÚ\¡Ïú6úÝ dŸÂzÃl%ÀOŸ*æ“ÉJ( WK̹ Ü[âõœÇ&úvUÊÏ–ê’¤ÇóŽÆàBep£DÂkPöÆZ.(׋Š0§ƒ–òÐN±ÕÍå¯ßW¸6p:èbgæöVH=²‘$î­ 2@§ `ѳß¼þ \‚ù bHHYe âÊæðˆà7-Øß…0/¦)J``sÓtÞ!i‰Ws`ãOüFÓPBDm[5ˆcN‡Û„1º5àüiiÝ€–ùBäwM.C"ý×%2Ò L n|SÎ>„“›ñ-¿Æ*eÖ†n`æÁ»¨–?¼8zîmª)“ «*¤óÒÕž1ÁkÀä˜=»bŽ¢ŠX" Ð*k €Ð ²eËyî¹çäÜ€2­™{2žtȃï]Ò6ÌQ%…{Z,F)s&bsÔjªaH™„L‹÷·Õ(`5Wä‡(¸27@ÁÆå™gžYt@ÁñÓWäøÑe/­J²¢yßø—ÿækry¯Ðwý/qEưåÏÿüÏ•+wÿÙŸý™¢Ã²÷ ìùþ÷¿¯¢¡¿ø?ýÓ?U¿ñ )«"Â¥¹²*¼4sO¹õX)<ÊüÕò¿|îÿÎ+̱ñüŇÿ[æ~Èø³çõš~-?ný…ô~x!sßãôʦú]ÓÒ´óCøÓ3­ò7o‘Bg¡Šbñia“lwaï*;èËùØâ>õ=95˜%*vœǰ`]p°òbÖH ÝÃá|y9MµÒ’vv¹±nÍÿ˜`Ý‹«.ÍʃIËm(—°Ôg§šrÌ¢=åÎl.¹†Ÿ¡©õ˜RþÙ¥\±2†süENNÐsÔË–].Jä…çÀê#mªN&ÓFb£ôé>µî¹ˆXå"?|àŒD ÉC:sÍG%8S‚% Ö9_ Ë¬Øp2f*ãdydè-˜¼s<Ë “éO´x6=Òš2NLO^ïÒÂçX¾6šUv´“8žùpÞg~wÚüí#+-äLºùÓP‰9%ÉÑ®²è @A7m0uàØ›©‰MC‡`´î¾ü’øˆÈÀ ß¶Û7®‘ßå1,¼¦åÿøËŸNCuåÜJaõ™æú‡aZž üóûê%—Òá˜TÁ|PbT8zb\¢p@‘Žöâ÷¨‚!(ëOx*­#Øm–K¹L­„˪€@‹%P–a¼¬ŒŠà* ™Ž¦àÃXTf™B•ð7 À(™1(amŸêÜï‡Òù2L£— Ťº7*•P—ŽÄÍîu¶i(²©D„ŸÊTîªg~o4©?LÓçµ~Ë#ž;¯©t=*ƒ% (;i²‘`„“O‹Vܰ.âFɸ`ºòC™£ØQA9©´åB€¹ÇU€Ýh6t‘L‡(qèåÕrkS•.*P¢ÜIX/¬†$ '‚Iøx^H |ðÌF ¨¾ €ˆÖ |hS¼Dœ˜¿Ñ$&ÍRç8Ì<ÇýN½O6*¡ bªl‚ç7´°QÝ3&%xþ¤ÉyÙ8ò‡Ê}Pxûe°. À‚q*/ð}hÊ—“44úî°ìý [ ÓÖ…/‚@ø›Ch@âøÓMh“Y ÅtØúá}ë\ ¦IÁåè+•è3%@÷ù#è“ ,QaáŠíšyØWXgíkhïcPúÇ ¿0âã~ì`µU¨Ò€G‰öÒ!P†ÀpÑ ¶ßžƒ¶kޏX¼a2ЀÐX縑œè/NX+ »57\”TT¤X‚EÑ@ú%°ŒU&¸¿"È€ 7K©ð5²Ç §+ËV!U¹k•™Vjì]ÖÜ¥ >4½õn!0 Z iqŸyøbÒ"K¶®¬ŒÅ-ÔßnW8õ6@bû£u¾C.·6fD1ߥչánío à¶º$0íU[`ÁÒXc%¶J$±¯å x὞Ã|øà»£/ëÛüz÷°œ¸vGüx÷ø±؇÷Zsm©lX–ÚÊRµj[;â¶,‹¸JëðyÊw)î¥Õ°r 1¸ËÑê7©hHÒ\[2ú£³¤ ýîK`æßYÙˆä?ØŸ², $‡oC^æ;~9ñHñÛ›-榕U&ä)ŒUÎRl.áÎdÛŠÕ‡æË¼˜ÿ¾•Át•Kët‹@…å‘#Gä½÷ÞÔ¹ó¾t÷ˆ¼ñNJ~ÿw¤¨FŸÀk7Á>ÂSœ«Õëœ3²àÚ¥gæš_Ò¼D´y ’ÙžßÐÝóÒJZ%ÂWCõ) eŠxMξí iÏyU9mèàù1V"?uÓÜñOÛ¾:þ¥á|Á 9O·uÚ  çdÁx»d<3쩆·Š…#ù…;Ó›k=ѹœuô™ENó£ 5)”RQ ¸ÅtS¯ ùƒ|ɤüZiŒ¡Z0CWÏM]4-r°>Ê—Ù5˜2¢Ø–¬Ì]SÒB~ÖEÉ¢.ˆQ׊1ÔX “ÒÜ3´¬<$Ï<ü¢<×+¥‡{m}–Öy¯Ï…˃+É9Y(  àÀêÂDŸ¿ò\ø?§ÏÁÂð‰C224 uš‰ƒ ¾õùêᆰÀܙүÔûœ¥ßÓ@¤×éÓ§µ ÜIL?º î4ÝnËŠ/7Û”ûBʫȣpi.…¬ /ÍÜS.E=V úŽÜX»+¯0#wäzßÄŽí,‡ÆÌ.tîÂí u‰»_”VxJe۪Ǧ¥É¤üØýí¡sòúíÒ݉ãL)ã ìÆG¾ÍiŽË¼ž-ÂYfm XȬůÐÇ,ïv5Š™‚ℨH¦r3'mð‹Rщ_/w9C)ê¥Â@.Fpé†y(ek mkmer™´ôÛ=Gh€%Œw“ ù˜–JS‚#îu •€ Øù~ ¦ë¹Ëü^>î€ç/ g&-OøüQ¯h ¨Ö:ðÜ=xþZ‘Èzþt/ƒyò$Ú)kî _îŠß~bª5¦»RÏ+‚VNÁÈ-X³ b½@Y…ÆáÏ‘Š }‘.ØÎèN*L¹XÇ…&Ôý†mÀ‚…ò¦¥[X0 Ü€NÀº0z³ ¤I ÏÜ‚18aŠßgyÑ¿ÞpY+¦ì‡¬?­6@@à‚ v˜-ÏbúB%€]nétÏ(«á_}ôÏ{ñ½t øs8váÙ+ʸP‚ žnèÎÚðeXhÖåóiyà­„Ex¼ˆ¬…W&®¬«‘òU1(M£¸FóîcpY‚R4) (ÌÆÇh¢B/F=°VˆÀ˜ 'ú„Ö ÜxW\P GÞ@)ÎËd€OyZ `~ᕳ¸O%/é2Øêœ‚Ö¤kÞÖ`Ðv¸Ö]ušéÉßJ5é é‹<XYÑ]‡¥twCÈàƒÅLÃ0“èÈ-l•èèÜãéX'X/ÑÔjô¼rNÂÈÓ®ïð—Zûãrâæ¨øñžø0Ç8ÕTтiZ%¦ºOð+X';¯žpƒišüç{×h~Ð7¨,Ïl¦ë"­Òi€ô \xçš–Š-EØå·Ë4—ã4õHs‡ êã`»PÍP«U E (¾Óª««uãkSS“ìܹS>¬¿•.`—¸Úš’·?rÈkŸ‡¥•Tþ|[²%½ÐW°*éqãž¾m1P¡ŸæØƒÌc¿…M¿6ããTÉŽ PMÍô©¨W £æd¿„5{\SCÑ(G’€üãßùV~Z* !æv`òB™ôÛ^ËžOÜG&*Æíž¯yI·Ì]ýKëPZ>Ü0u²ÿ²ÜZXS(ïYv­Mf&=#ÊU™¡œZ`M£Åd&CKÿZÕ0éÈ@«…#i“#´>Ö¹?P"Á2ì xäóUÉ30åZhÄŽÍÿë77 M3˜®"¥EY}f¬÷Â4v¡á:v£þ× WèUAYÀg^ä1³„‹²*¶«™[‰ÈÕñaHÅ€À‚úÊ ¬‚Ò¢$0Y1›H6Êðè3…ˆne¦áªÂä*›zè×-Ng2ÌRH­ÉÃ^½`z®ªÌƸ óð 4W9Y¾…(#yÌ"ÜöKwõOdƒ¼?‹\ ›4ÅÁ©Ÿ“ùštJ=,!,,ýeG-×ó§nq ¾?‰™îD™¬£Ì­ÆQ( ízU>yè5‰ÃEР噑 W$ò­JÌ¥ïÌÈp Ø/‰­É…¯)àÙ̃óŠÉšJ—A1]»$åÌÊÃJüÊñ[…ÝÉAÁØä »%÷Ò©¤W†{wÉèà€Ð7Ìêê¬eQ·Ú%U«°»5\nÐQW\€+$]Ù ß…)Ý­=hÃNf(Qq¼$tA{Ö¬ïÊÄ®hþ²C$2*}06…´h˜ ˆoX@ñ%°â,­¿;¨Ñg¼p©à……1ÀuùÎfVãõyX2c3)™WëO9!0³)æa+ e6¦.Z)ë‡ífA †% fQë fägXØ·¸J @íIØ ù>ß—¬J>øoüÞ÷¾§ü¸·¦:Ü/<***2²bÊÊè+yaC‘Gáò\ Y^š¹§\ŠzÜ/<æ.åü9‡àûú¯þùCøþîÃâ—;GWI°y‡”ÂÔ$-ðEÃ.”®ë—$4Ôƒ*Ìüðöwa—H ‚M[v@)T-Wä[¡&z¥“œ¢O›3Ey‘Ç´"Êܤ¬ëkð< yÄ]<é\JdÈëIv‹yL–I¾«¢¬Ší*_ÛÈŽPû Mç iì ¦b¦ŠÈ–@OŸ´­¹!—–òQšþ[ÚÀå‘‹[öÊûŸû–´7<“ù´ºK[¦åÊ­·l­ôWžÂúO±ÃÞ,Ž-TY¹ƒÿüÖýò龯Ë@É6I'ŠjŽ…’íýC‡ ‰KÝ.°¼œ*Á/»°è˜l›ßV×Åç¹ ]FÅ]ô 5Kxp#àkð½6óNæ\ÏÛ……Úš&ìŒlŽÃµ,xÐäYöÕäTàóÇಌ£d ÒPþ\%Rky.ú–’¡Á[‰ôËØØäC¥êü­ð—M-·uÎ~‚ᱨu=7L²‚Ø€ ƒÒòjXà«@\& ~ ˜Æ…£ßµºìÌç\ýÖ:£ é9/ññK`Œ£IxûžZô³æ3ÖŽu­!•<´’À¼°°`Ü- o‘‡ŠÇ6©?Ê*…¶‹ÈµË'¤«ýšD#a4ƒ¹½ kž†›¤­óK$š’pd ÊqÐSuŒ‘å<þFaù’?Z"Í"¥ÔÞc¬¸a©§V¼X_ðÂZÕ–Æ i„{žJ¸|X WXuP0q4Hc×*„µµ`àWY5Ú»A%:Ëð¢õø«çÉÒǸ5 6™8`u„»øp«®X…x(à´ß˜ñf¡y8ýX÷Ïî¯ZªÙÿ™®u Ù#¬‘b0UâéÜÌÌžM1GQ*¾ßJJè( ®¶nÝ*­­ÜÅ|B®\¹bÖjW˜¬0¤É»%¥¦Æ%Û6bèÀë”`@ªàù_­X†#‰ LE´ù¯i‰µRÝ´ýnFZ#X‰<à°ÉüI=Áé#QcÔû bõ}Oš.Hƒ45ÎRö3·5Ðòèhg•#â@!‰y©M ŠÚáHE7ëª)xm³Œäaëæ¨©‘€4&ä“Ïõ ÷™Ÿç(¢¾+˜^A¤™hB-Û´˜Œ‚U’|Wê¼653õ ÚÀ +EžúÚ³R±rŒ³ò1i™¿z׆¾á…´æÄ<7fg~–_Ÿ "”¤U&žƒ¸õØLZıîv9yÅÃ;ï‡GRòîŹY( ¸‡.Š Tœ÷ô™!ÜÃ"HðÔSOeJà…O¶…÷ ¿ß¿è²*ò(¼õ-…¬ /ÍÜS.E=îs—rîœq@C\¼!Ÿ¿¡ïã†ê ù_¿ýyùÑÙq¼9Á €‚ÖsGe¾¸ã[Á8 Ê58¡oÛŒ@øá-†¢Š(J (¢æ+4?ªá°ŠÈ–À8V™Îo; [®’½'Þ1¦ê³,â9Ík^غW~óòÊÕ Ê¸ f~ͺÄ"r]¹¤£¾2¹Õ¼UzjW˪ž[ Z‘öæÍrøñW¥}õVì ÂB}ñ9,¨|‹Äæ+¾¿àJ–’É*€š°xù°x\íâ¸Àí¹‰µVc |¾œ²ó‡‡6ÊpߘZ¯‚âžý‚««³ %©¨sJym\|˜)×Õù™;A.Ñ+µR_ºZÊýµðßE=VvS0ÿ ÀrA;2–A€ Âá~j—p¨oÁ¬µýÉJ Á “6ÐÀå^°@(0Ýø ˜ñʤ´²ŠÓ îõÂÿ¹ÛëÓ< R TŒR9@Ñ*°Â’1“9¥Í•m{÷¨ÊÒ¢ÆhØ}¿+O‘‡Ð —UV:zû»äVÛe¹Ó}SbQš‰š¹Y­cÒaמoÈêµÏ“RúÏ蘄GF$ŠÊP("¡HŠ*‘œcãG`Ý™:‰Êì/²-ôe™¹º°Ö>|Ü\÷ >¸Qhª)“õuA©uǤ¹Ì!uåp-T‚Í Ö4Þþ4²Z=Ü"HîSدú‘t‰é[ú8x­!+=ŠXw’qP#Ì“|¤€Ö»ææR9¶‡ùµ˜ÿþ’ÍÍÍPÆ×¨[„ÁÁAùàƒääÉ“‹Ý“róïÀPZ~ón\*ᯡž`%Ž™T*ã5Š¿úZÀ…íñ <ÊWª¾›5ßdvÄ`CÇ‹9{@›ß¹uM{áÿ|N¼°}X„áq,Á:IBûúäÝÊwžß Yþ|² EZE %P”@QE %ðÀKàöªùä‰/JÍ@·ll;»$òˆcáùÔ®gå­ç¿%m-KLwÚ- ëË„ t—`Õáâ–}R劋;| VÔÉ¡}¯Ê™OË8ÅP”Àò–€ órü莡Nâ‰ÍâŽßõ‚+\ÂnOPêJ¥¦´YJ½åP2B!ï„RЮ |§å€ïÇì^n\»OR‰¨ÄãQÈ%*#ÃÝ2Øßºd@ZLT Ô8:¡ u»á2Kƒþñ—”Ãmްp–éZ!Ý'¸U(F&™úÙõœæh–ÖÂ`šd™[å@&fæ“"™ed§XLYCáÝÝÙ w—d ï6Ú8{3÷#»lö±¶n“´l|FÖµÀŽdøCFÛ«(KI¢nVbAIÀ È86‡DЭÂ1, $d ƒÁ‘Œ†`Ék<¡±¨*ã X5 ÂeÂèX\€k˜®wË ¿[|Ðö<ñhÐ0(aÄë–ÍÍUÒX]ÏTÅÊe•I,Ýä>5ù*ÃÐJo4ŒÙuÊ“ž”óòÈPçÉt<ò•kž,‹Ù‹È’7ÐqÇôÎ;eÇŽj¹ààÁƒräÈX Zxcë=mïLË›ï&ä«_òH9JüÇ ЗѕmM¸ž«{D1^õèTÎ㚀*¸©§ªŸÿ™F]à‚#‘Z@"Ò°­¾ð-m<ØÐ$Dœqw¤kd!téd ñtíh3J€ƒ­~Ç,PA ,Ë$ Z@276b,€j—†ƒ^àµRÓ¤>0)ù^°ù;ƒ‰ÇQ#2ԔǤ4©í|qwŸ±jüs«)¯x®œ¬²q®gdÊŒ=½‡?¸§ámÆãá¨øxªY@·õ&oÛ ­ôvFMCjæD˨ ƒ  *Üä{PŸ&äí "Ãèd?›°}ûvyòÉ'a+,7 …¥ýìøy9qüæöýep$ûo}G¾ö»¯Â‚ æ åº?- PÁý!Êb-Š(J (ÙI †ГWÚ5S>'_Ú¿]¼jþÑС?Ìžö6¼€“XørIM]ƒ”Á-C&ýº;;á?t\ntÞ‘coʳn1‹‹øÿÙ{³&9Ž+]ðä¾×’µU`A$H‚ R\E©)J"»ÕT÷H׺ïèE6ópßî}è§éi³~h³±1›—y™? µÆ¦§ÛÆd›ÛC‘’î ±…µ (µgVîÛ|ßñˆ¬¬B-™Y –r*#Âãø9î'Â="ü|~ŽÕ€Õ€Õ€Õ€Õ€ÕÀk€†ä3¿$~¬Èûó?þ³~éMÉ`ß&«ûGœ`À€Á¢\x/(H¾ø ÀW°ê÷4Œm×0yªÓÍ-5©Z ÊÂÔ!IÏ= ž˜à4³È-ñ qß°OºKŠ–±_§æ‘»võÀwg°[úÃÒ퇆w¬¼÷rÅ1\h[ðæÂ^®‹^ 8ýí…ñÞç!^ ¸J¹;Ö'CCOa2¿b€XœJ]Ðà*V_dzzLÒ©›ÛâÑ@•¥ :Ó1oè~4€”“´ ‹w ÝMã/‡—´7•ºG¶ÛßèNÝqs¾æRÜ< äÒrºšWC??EÑr‹Whóu×0-L`–•qO몈•Á—¾9ç„24dä:ýyÕ´wø°ì?ðš ö<xçàj~ô/î uª‹ð"5yŸtÁÄÅÕº¼c*è{Å|FÄ‚d U5ž¤±ÏE$³³)Édš ò¸Ý* A£W·A§ rüâ4"~x$ \ AWXöh X”ŒKOab=¸ý1. äŽlU1'Õ<Âça<ðâËÆóž ´ß‡±ýM=jj_1+ð†"ÁÀä‹‚>À0 (étGت2Øw7™Ö•‘Kƒ;œ¥ÓóIshèÓÆ CCßÞ¤|[ÜjÀÕÁ###Òßß/\Mýúë¯Ë| ~ø!¼›4’Òå·Ó[:#9s¡"ÉO¼òã?Cˆ¢°1—ù8ä3‘ ÏAögŽy|«p‹ 0@&_ƒf€[FÐBjËV¯<4VfîÖò0ú:œV¨¦ãÕ—pžDôT@Z@ë¢ûèã¤wØb|65§-µ&x€v;àx‰àÔËCï 8O ÿiKã:U%ÃGŽ„J8«ýÍk)”)Ï}d™p ¬¿ ЭV_©×û!䢘¶¤h 96åT¢þ9ªcen2)Ò­¸–Ócü†íã.7ZÆðÔ¼ú. ùÌ7GÌ@œce¥'¸§GfË<üÛâ7ŸT7(`Ÿbhí……ˆn¬,dlQ:òÑ1ùô£#’jPð‹_îJ@UnA[tãY6VVV­j \©Êäô¼ UþؾzlJ>$Kp×W@¬;>øé²»§“MúZ¥ÛŽÎ™ŸÁ‡iIÎ\š´ ‚V/€¥·°°°°°hI9w¸R«Ö_úüß幓’î¹[K -q»“˜S³É!ùÞ Ž~M®í;(©x7&-hñ±©Y T`¸ø­oË[oü÷RÃþ´ë±àVÿ>9òÊÏRø©ÌuêTQ³õ°tV÷’j Æ%õ`0ˆÕÆO\0ϧdàñ6ç²8·¸W2sÃ>ã% h:cÛZK}˜…ïÙã•äÞ"ŒäôHÇ êµ'ICþ@q¯¡.õJ€ÑS'¾é¼ £¬5¸.'ˆ€.þ9Ñíqb«kíøQé&¬ Ë<6@ëÞGj’ì}X†ö"=&Í‹… Ú˜“…Ùkðw:ËI:3ãéœär [6 >þ5&‡ggnÁ8ÊvøñK4–@Lk à½/퀑4¢ñ­½ ‰ –¼íðRº"Ï sÐÐn®WdXNH3x´¢ (43,Q.ízÇ€ÐP°2œËu÷tEwÕ¥bUÎ}õ‘L\=/ù,î[×8åÔ®ÙÍÈè+rðÉ¿”dò!ñÁðïÁ‹¦Æ>„{ЃL\©êBk&E oUô»j ¦+c«XY,”e!E)dP@ÿ)ÊB* ðÎ"Â3hPࠈР[d$iÜž7+¥/ÞðÉñË t<QÏ îÿGG’²ž úºâ2Òß!>´»(ù˜\ûõ´ÊÁ(¤ëÎL˜ÿJG9šM®(Ç6+w×K,Ä?âô4–#OÕ,þÖÂÜ*(¢MƱ浧^y–wxSiÈ7<É…'ÈÂèÏ•dä˜kª€ èLiÑæš£OGÚÆ\¡@È;§Û÷P@@Áðð0¼jáy³M‰€‚޼# sôP ÚZW’z( àç?{s×y(pcŸ¨®&ìÖjÀjÀj`‡5ÀÇ,>$™ø`0PvÛ8W⇬>ìq}. @éñ!çw&ø±ºYá O¹Ú«««««««­Õ—¾uH¦ûöȱg,.ž'Î}*Mœ—h&e&Z™ŽwÉÕ}Ë™Ç^„1üLŒJ ¢rÝÐÕ"CK.¬><ûØóe$å…ã¿—ç½Ï×1ù¦³Rëjˆj³]òÕ“¯ÈQ\ãK£OI:pG[Ww]Qö¤ÕÀ]ÐŒ~Õ(¦IáÁ ƒRåQL|Þ„ç‚óˆW~ìÜé«÷“Ìüò0ý$ …ÝàÁXä:•ÚRbp§ŽIûŽÞ" 0Ü'/ïœÀä„s<”T Aw¬îÍâÀ†Ë`ÃÊâ›Q©:yÞpn­Yk—^I{¶!"ú§§hSDêîØ+C½`hDìx¬b®À¸º°0!‹éÛð 7'óóã’Yœát~Ë€Uÿù×5ÈfS Ñ4ˆD¢êÕ€Þ ¢‰.‰a¬bè BðÔàÇŠkW]7è‚ÿÔ¹Fêùk_KCOM,×sÖJVÆöꊡ"g ’án]¿¬žWëGk]ŸÆür×›rÝû’Ì_ë“ä,Ⱦìƒ÷‹¼¨· ‰†àN<¬Æ¯baI©T—“IlÉ—4ŒçsÒˆoP%(µ˜!¿u /¿•éÚÔ¢ÄQ¿¾Î¨ìè’çG»å@¼"!õÞBðMC‰F AC6FÏšL¼çëêY‹žó[M¼‡4ŠXs5ZÔèYð¶£^±5¹ÙV[¦@ ƒƒƒrðàA<÷ÜsrêÔ)lçJëÍ6 ½X“?)J²;$#û0 †|vrîZàÑ`Œ…çÈ7}Ó½@ÓÏhè7Æy ØOI„’>ZÆã3MÕšÍ|œu÷u4 ÿñ›E Ô8iFäBA|ýâ˜cÊ™º¨xT9Îä+h ‡xãrÆSÖE«FZS†ídy¶[ÁF>å‡}üÇH®[ÊæYSÛ¥ñOÛκ)KÓNÒ’ê“s ðš½æèiìWy”MI8r ù”có~c$ð<åzÁ_üôÀà¼Öøî„sÚ$²¡–Ò  …LafâÉ{žƒÛóK}•ñ70‡ê¬VÅü­gcõ)—˜hå lë©£×+½{gè(ÀØM@y4|óሒ‘^é‹Â+A´`‚8Àç!|0¢.tŽtGnÜõc>ãe-ßø¸ô /;3ÐøÐÄ:<® ¦Ñäaf§!FvgœuW^kMÔã§î—Ë„bÐAŽ ðêêAˆ„¼TòIéÑuƒáujê¢,¦n`0+ós7°²lºm„PR{i- ÁÜ,̘pöùáÑãC'Dñ,ñpã“P8.ñÎn¸°< BA0μû­æÐ“{-Ô‹3SÎ}NÊ35:`Ö‰~ÍÇyw›׀|jÜZT,åøáïÁMꪄ•ý7o\ à<€×ò¡—‘åýHemôã‹J9ñc)%^‘b¥ ™šÌ"DAˆÝeƒ~€l|9„ )I,â—X *]áš# ¬HöÁpÈ´QäêX¤‚è§X¾¯e!¬zKªš*úV©\•Å\Q%_ÈaUsAæÒyx6 Ѐ‹Q:í,bتð iʨa&••«·Sr寬ü7ÏÈS{ð‚ºê½ ÍLT+Òƒ,—“5@IDATû1Œwðâ®ú÷ ̇!<WŒæpµéñ€ã Y*y‚£ãÆî;¼µ`›?ëÉðÆ0¯ÆñJunú/ÇC×þÕ¦H[Ìj % КL&¥»»[äðáÃrú4b¶?ŽgåžÎ¸Ø×í%žš®É[,Éßü !x»Ñcø}×­)lÅH¦'¹yž¥f¤Æ;‰¾›h75ô”Ó@OÞ䃿ØÃI>ªùà ”Å_d¨d†Gðâùb tÀäC#?<ÏcÖÖäro)ðŽÁ«å -Ë‘N5¡çh §l#JÏ9r´m¤UÆÆ,C怞%ZHàáTCËB¤©/‹6ª‡k#¸À•B°[½ w˜]iaæ.Ì7û†NùQ>M6Ð(ÞõœšÍýë‚:©ž@Ëõ“¿ùÈÀÁ€S”Í%zùp=X@As:Ûi*;[³Ó·ò¬¬¬VÑ@¾X’¾¼(?}í¹UÎÞ™U!›Å‡šMVVVVVVVwI4F§°*”“0B_}Z˜H j°¦Ë}/&̸ÒDç10¹V¦Ì t~ XEZÀêÒ =6ÄÁö\D^#8RmŒ<&_æõÉÁ½s n@1u† Õ+ËÊ0ðZä`Œãu¡g›¬v‡üðrÐÒ‰m?Â…Äjxx/œÁöª¤göceñ£0œÃffa[VKß°OºKŠ–aüv§â—¦Yã¡NéEx†9ˆöE`wƒ+GR­j@:˜Ò.IWÞœiÆÖƒPzõäLjë1ÝŒã»Qgz pú´ê©‘¾êÑNëK€CL°cìèì…žòR…A±ˆp •JAR “27s ƒx5¸¦^ ¶hà¬at1÷ àÅØÇ q/ô〠pA$Š?Ô1!Ð &ax4 Wƒ ŒÃA´P`Þ®^ðÌr¯2ëj£¹CÌ¡në+ÙAC>uJg—šFY5¤ ÏÊ0:nQWE€ǯž“Ëc_Ã?ƒ{†î¥~TWû;ÕÈRŽ}G*‘§ñ „‘ܹޥ »c5Цø,êêêÒ˜ð¼úê«òoÿöoròäIg k“ñ6ã÷Ú•«y÷ý¢üù×¢4ëÓ¼ïô·?NGv1ì3TÃpLK©ùºÄLü]¢W"Ú•ÁG8OôòQzcöçèγÀViâÛ å µ YZ]Œ)”MeŽ5zùÌ5’ð¦€È"jÞ'”+«|Òòr}ScÍ#(‚ûÊÀÑ„ÞÜwB¶ì˜ Áì`À|§šõáÈœÝàWæ†]p¸³nP¯“&G0«Â¨,Uª9MèV€gqŽ)ã…@Oi6/“©#hÜÆh´À­9©×Ø”rÀ àGi$y$Çò?Ô> à±Ç³€çÒÜË *¸—¯Ž­›Õ€ÕÀ®Ñ@…¿ûàKùÎSlØæ*>êR³óX¨²ä©`ÃB–ÀjÀjÀjÀjÀjÀjÀj`5@4W»óϦ{O¼>ÙHBÿî½ÚÙY Ü+àäh “üø“^)dz¤œTŠ™ ŒãX…ËYדq‰{ö`µâÞ¢ÃX_çu'¸1 #\w°îÇ’Žh¯DüQÄ:G,ò† áº8N ãÏÄŒ7+æêçV£çô.fÀ•³ÍfÂÙ)±*=ÎmŒâ°ó¯1%“ûehø `]œ• Àg©ôM¬Ä¾¡û¦§Ç$º¹å L¸ŠöMòÓó 23ôN ]ØÒ«A,žVSG:ˆÆ4ˆÃ« ¾ ©à Äjú¢®ÌþŠë¡³ïzzÅ©Y®Iz+cIW¸—‹@œ=õ‘Ü“ìb·«ký_¡æ +ñ¤ÿTBàD¿^íú6ð0@s½M6÷«2›© ¿Âà†>Έ~Xj2èIø%жó(®¡†j¢r5f0À1[b†`|ïˆ!2yß04B ‡"<5¤³’Ø “ÏËÂlJ.]») Ù¬vᆪ7½Ë[íàp·ìëà†Â]@rÀI êGtÑ$X&Œ×FË œc0ÔóÔ5ÞG¶$­+£hUÖPïzžÝ±Ø9 Ð3Áµk×䫯¾’Ë—/£?·7†mw‰Õ:ùU ¡¼òüó! 9.ñïKýÈ@Lm–z5Œú #=ß;|ºož|Ug¬% zoáyRªçÍs@è”äÐêˆH:øG<Ð|Ö‡´šON<¢L$§Œ†<Ð|7üë‚w=Cªg0œ8²³,C2pÏ%¢\0Ä!y›°Ìc=ÉSÚ®ã7tdÃd Ê’”H8Ïä°6ëÿ*ïzÔŸ" pâ%¨&å¨üPmkat¤ï/uYÜ1×ÂeÇòN™Ø$S’{ å…uª¬e(œÇ(ç©~Î¥BB 6Æ?à‘?|íA˜æ¥¢äÖL•×^{MöîÝ‹ÇÐÒ]ÕLÙVh>üü”|öѱ!ZÑÚrÚûTÀxllL.]º¤7o²'Ÿ|ry«6y´S2Ο?/W¯^ÂÕ/ÃÃÃòøão²æË‹±{áÂ+c¹ZV=²ºZU-«f>hº:uúËz;‹•¼|~õúñÊR¥(/<ôz=›¨ðò•£rSNaB( û’Éá‡ÕÏ3Þåz°6}«éÂ+ 0žhñoHÓ‹ð¤0 O@ðòy*Ò€A_܇û¦Q ¢€x1·ÔLT x=Ú O xèð¥TöÈüBVnÞœ‘¼m&½ùâÃòú¡½2Øá•@€*¼¤8Ô{G8¡^t.½8©šÇ7Æ &/=Ðk÷Q–D½U±ï;V'ߊ˜sÆ8%nóg]ð¼À[„ã¦ý•÷‘¶Ãí[mʴŬÚÑ@ ýóÌ™3òÅ_Èøø¸ÌÎÎâ¹wo/^IÞÿ°(Ý=>yì>1¡OUܾŒøUÑøÚW` ã á$Òãí ʱÔ"·î 2Å´ydV½.·Õ·xgÔêðÝQ«¢?Z-r›¨¯ 55ðãÝ‘Ï Š%)“Q¢ÙÕF>Ëëiüp\¯ ìYgõB4Ö”í3$zÉ×½X<â¹ï{(@ȰŒÖ"šN£££òÒK/Éààà¶ Nž¾,'Ž" s3¨›«¨µ«Iêßþâ—òóŸ½)}½IÕÃÚÔ»çÌÒ›À}Òf¢¸{æw¿û¾ì½²Õ ‚’qôèQù÷ÿw|@†Ô­ÇVƒ ø€²2š»±­®šÓ©4]ý?ÿõ·õÆç0‘ñû³¿©¯ÜI„“òß½ð?Ö³3Ù´LžIË € ˜¼y|àyù‹ƒ[?_,çä3€>½üV=¯q'æ< Y|ŒåÑg?=q^]ÚýìÕgäðÞˆüòùÑ…~'ýòÁWWåüE¬èp};â|ßÜÊÉo¿Р‰Ô ^ÿå‡Då7—ò¥ª|pa^ŽœoŽ?¹îf•?›kN¹ Ú— Ë/_lšÞX«ÌêÊÞWß%¶r,™ºÕ(­}Z«««««û]ºU§1[ íµ&Ö C⾚Ä: XíŽ0(wEú¤?> #c¯D2Àï ª·vŨ»tN•#¹Feî#Ô€ÈÜ|n‘ïî0¡‹Ilº’×%Îø€„\]2ÃËÝ¿dW=Èö9©×êݱ~)ô>ŠÉm†dÁjÇZ“¾×ëþ6 És0¾¥@Š®bޑޯµ6Y|çÏÎÜ6@è”aèÑ€`ƒBÄÄò' ÐÃ)ÐëAˆ àðáÏ㬞։|äA®ü¨§S%hF}O²®‘•tîêo‚Ô°±‚~É(#LäëcrãÚ72uóšò07aXR®³ç‹J9ñc)%^±¤Ó\;ˆ6Ÿa¼ÔÍNÊpˆë XÓë)À @sGðh®I2Z“ýÝ ®3*LMösAL›3órúÜU¹:9/¥FÛ‘áÕÄo<”¿~ù€¼úôˆô±îý (©8üqÿû¢`cÖªñþdNv+JxM¼øö-ˆ`È£)1ìÓð„¶9}ý¼V‚BÜûåÚLëÊHÃXDyÐgµÞiÙd5°ƒàüù‰'䨱cu0÷KJ¥jòÇ?¶!C/Œìèÿ€ @×® 0'í§›ã=ÈGû¶ŽšÇ}&Œ4Z“ÁG´OëЂc“K€YãÏã:xe9º’–ùÀXá};HôH` ÈW@‚1º`Àz @ –Ô<-Eï.ä+Ë5Ôq«Þ¦.,¢ ”ò•’Àq é»ò5ÀêÂH6¤1å±³^"kðÑöêr)¥]¡QáÊ™õƒWëÈÿZÖH~ÌÔ¶Z“¯^dÕëHˆ3Ç¡qØ äqaPð$ç‰æÓè¨ôöön; àø±á¹Š€‚“¬­£ûTÀ¦¤Ói 1o*¨ •BŒ¦mH;!ƒug;"‘bbm};8hYÍÝVWÍé‰T𮦦`(H©ŠóÙì-s°Ê/ŸŒq馀D$ •L\© Ä—Ï—2ëòÌäB(iøés¯9x?øêÜeLbÌáÛ‹¯xQÃ ÚµÛ òëß—i ÑÓ•À— ºË,c„ül±"Séæ^NIßoþƒŠ+éY‡fù³Î»YF+ZѯE+׃úµ2¨…æ’ÕUsz"•ÕÕîÕ86Y X X X X ìv ÔðmU\œ“Rfß3x6ò°Ô7ìƒw‚V¸—›<$½¡~éî‘x¬OCL°æt+ÁÎÊßeÓ²ü\µ*é–ájûÆJ;†¼;šàÒ뉆©ß»,ê/ ƒ/Œ^†PÀ÷nWç^xÁ+)À£TÌáû· ûS·/Hzöª¤'w~nK<P%« Râh:òÁ›½/¸@öÃÑ(¼tlO0‡`È bµ6¿ÙÍ ir^ãªããÙõN±ìš¯EOVõ2˜àçÇ·^»KFs#ã—¿–Ëc_Ë">ôÉÝx³¹M¤jxÞ ¾+•èa :tÕDá- £ÜÃÆš“6Ñ80§#Ò›;'åiü©ßMôÁbÙ'—&'åìÅë2qó¶Ðƒ&oVÓ=Iùá3ûä¥Ç÷Jw<,µÜ‚z¡'©2܋˵S°À*èmÄñþ±,Ì«%ZÄ8¾Õy¯FÔdÞ:24Täx\Yªàº–›`ɬÚÓ@&“‘O?ýTÞzë- w@ÏfüjßÝ,uófE?ý«°t“‰É`žGwâÁ矋 À 6€5ö8´ØE¾Înƒ„ôeÐó“—åAÀ!Aà ùèiþ€žËæ± {7ä:Fo•©, '`×Åú䥼=Œ€r˜ÎFŽÃtÐÌO¹˜¾5ç°ïƒ`j¢÷üÇ1èñË:1ÄS Ÿ½FZÆù¡^X®ª œ åDH fd³AÒö’!’–å¾²t€¨õox’Êäk–!4å(R‘  e’ò taÊþšïüx½(¤ÕÅóÐ&^ ÍãÅp²9•ôë÷\Ì6Ü)¡™4:jÍèé^£¹ï@¼ÑGFFä…^ÒÛ'¼ñ¶:플}ûöi;è©€û[¨+£9­Z]5§'R=hº:|ø°|v}²yl%c5?ò¤L\<‹Âœ\º1]—Ä——E øÇÆê“—=,}] ù×?­ÓÙ««««««««««««Ö5P†ïrŽŒÕÞ €ßÊÉ!ôŽ”¥¿«KúÒì°7"!x&ð…`E¤¡¿Ñ°†9.øÕG¾3 K÷÷Îî2÷ìŒgÎrø6TŽ‘!è¡€.ø=õРy@døÂOý ¶¼pà誳kÂSÌbQ5ÂTÀóW/¦oÉÜÌe ¦Fá:¶Ó[4àå: dè/B'p‘ |¸A„1Œ dB8„m¬S‘ x5HH`„ Â(øu¡ ÜkÎ{‚œ™8cï$ZBÔ’cf» nYžÆ ½Y>¤U¶Ì¢uý™”‡šîqXFZ,fåìןÊñ1É.²Oò ·žª‘'¤Ôù:läû¡.gÅzël¶´ÄHo@öcáÿpW \£Æ0 ëôó*îý|Ñ''¾™s—'e>…ñ @ ÷i¥’ÏŒöÉž”CôKG÷#oÜ¿5xÝð &dsŸÀ0¯!Sh Çý¤áÜ{àÞglÆ’‰ DÛóC"0 Ë‚F= ¸å[©ô Úue0Æ@)ô‚‚Vð°‡V[©.Pýä“Oä½÷ÞÓPÔ·nݺoÁ®^€A”‹KòñÇ^ùÁkx®…8.Ôð¨á ÁÄõÿŽƒ‘ñ^`Î1lm<ªÓóy :×Ö®,‡—šÜqŽã‘ãÉç0plØj¬'OH‡áÍ}æãÏ• oüʧ–êˆBÆÐÏ:³î¤ç¼#Õk ™xæ0Ÿ©1ü¡*›ŠSÚ, ª²BZ1ó˜¦þ(e‰y½(ó ~TÓä§ÉlÙ>Sk©µÔ<ÈæÖ€°oõÕá” TºÃÓx/pÉ"¨ rªçº´ ®é{5c¹B¼ç—?ÐC¢á¸:«¦Òè¨4¥¨{hé‰Vnµ*1¾ÙË/¿\y x«ÓNÉøþ÷¿/4h²³oG;V°2š»;¬®šÓ©4]íÝ7(Ÿý/ÿ_ó Ø&JN@ôï{Xzzzä±XJ>:uQ®LÒe›yŒó%%‹ÈwŽÊO^~BžüÖyïø7ÛTËÖjÀjÀjÀjÀjÀjÀjÀjÀjÀjÀj`wh ”I©ºZÄŠ_Lö.ͤ6ßþ`¤C}ƒÒÑ‘dÂ'{»ãˆ£ž :ÁËIYׯ‰_Þ8ìA¼r×°èAüqd™Ô°Wze¬ FYŒÒÆ¥8($ð(ûHFž BŒÕî&誧ôˆ ?+•ìœó)© v{:?'s  <˜ž“têæ¶ Üjä²)I{gqy0åŽkïH„îséÕ †?‚ ¢Ä»:è€7ƒ z4ðc[¿O\f4¤3¼S †Y?çxÍñ‡cNû››Å¹cxºÊ{D­8C.ï &Þ‡îíæ1ÿ“A/€5ÆÎ•ëWÏK¾ÝphZ¹ëM)GŸ•jnù=÷Æô÷Á <1•dă0Îåi¢ŸWªI*rôÔ¹peB2Ù<îc3WÄËØJúÉÓòÚc²¨^0õ~1áRèuCç ¸b¼ pÕusSe,rQð ôÉ1ÉKz= 7Ls¿U ðÆ›£ìªx:A(«!Y/$,²™´ž _¢ß°ØÊwéQ¡Þ6#Ø–µX¡z‰&˜àý÷ßWÏôˆ{¿z&XÑ4=D9ñeQzûýòôÓ~ htç)3éP¤ïjjvF%£;Ç6À)AZ¥ÙÚ‡}Xˆ¶nÝÁ± K€÷ä»õ0à f†}ž×÷"­ ÊA `@™0€á ôÅP œj羆8àøøó+uxò™jÛ]ÐÀ’÷0αåLn;ÉÏ/Pä@ïÏ&¬‚’7ñ£ tè¨1Óf5î㔞uê¯ï¬ký@ Ydf¼#!C•d-…G ÞÉIË©IšË´¹PòPà•wNY@«ŸÝ´½7ÞªZÔxgg'â¹àígÓNÈèrÛ•8XÍi×êª9=‘êAÓÕžÒžæ¿”x(ða6°güç7ž•ÿöõçdj6%3© \’WÕ]²Cz;ãÒß“àk„¼ïNJmg½,o«««««««««««TºUÏÍ«K}Nü¶“"‰¤t H8‡ß' 9\¸é—©hI†0uÕƒ•ÀA®H®'b;®äÅ䮺¯wÏ5Ý,ÝÒðÇÃܪAÙ9Ë‰ßÆ•ÎõB»O† þÕFAÂݪ«$ô;T{—«ß \Ù“ÔÂ$<\РƒB'À`šã=Àë±ÉDƒAÆKâE\¬Î^ fqèÍ‚áü ‹X€¸ïÑh@Æ£†Ð®ê?þ£¹Å5Zè,¿ÞN÷”# ÷‡JaÙY5,Ë1ha¸GdTJe™º=.×.}-·n\‘B»€_TʉK)ñ \5£ºÆ‘úÕ¸;;ÏîÈ$"~50­Z‹Uú9±Dã·æäô¹kryü:îÕ|?'ÝÉ<ˆãÙ„®l†!Ìs„6 xO,t|`xctg)}çá ƒ·%1V›±!xÕè· À‰ª =0ŸÝš<Ì z0x+ÃÉÔ‘Æ~¥Ö:Óƒÿøl…ü-é•C(“Y¤"w–%8>3±Þ,bDÞ„ãzx`„!ÒðD"޲n»±»f"u!j|†áÀeª.¿ôXs*<¶D“›¥¤$èJóPÞ9G]›‰Ñ‹#À0&ê€ü)-÷õ@µ%y ~ý.Þ¶<i‹éY)eæ0Q c²™?m¹]ƒû%ÞÛ ÷ð0ÀyQ|°¤·Kàb±,Óé²ÄÃyéïÊ þ¢!¬^'‘® ÅÔ2 ¹³¼”®.ÆÊ¨ñÍùTcœ#€!ÜÄInéu˸Ó|V/†?q«ª©ãXê*Ù="CC‡0QxÊpÓ^.ge~ú¢dÒ·%—OËBêVËÏnЀ—Š+ðiš€·z“r"YxȘ¹…H¸# ðûGƒ(À\p@ÀÁ‘h žéC ÇFbŸ^ œû‚÷þá>­8 z¼rBãªvÒ¸‰eõÛÆ2¼§Ü>Aòm–QÄu¸yý’\:¡+à2¼Kz½ne7ÞVãRŽ}W*ÑÃPCÇR½7.ºm!ØÝíñÊcƒ!‰P Úo²Ÿ`Ç¿xí¦œ½pM&nÞF¨LxSq¯K 5>°')?|fŸ¼ôø^éx("¤ýr7‚pš±†'ÜC¸Ï @3Vé>ò95Ü'êAÅ1´i˜0ÀýC¬&C½o´Ñˆí]W†„X_´ƒ #&îÛd5°XXXãÇËÉ“'…!xü ‚ Õ53]•#ÊË›…—]Ùõ¹@Àû³>( À€»ÈR€i0h‘Ö€ HC6òôMÆÐ0®è¨€/Çl]£=ÍØ'‚†u1Ð c,‡Ý]ÅSlÏ?>É_ ðË}èòaÝL"xÅé1ŒIK#¾ñ¾€|R³¼r#gF¨WÇ|ºã„&¶‰’Y¦0@ŽæCÅЛ%mÚ£Á@ήŸü Ö~)Ÿ¹Ì7¹8Âómª×—rU‡8g8åM!‚)CËc»2<ÏÑñ«w}›¼ñÆ*§ÊgÄ6¥÷>:.Ç¿øHRP°-v¿6¶…¹ej5`5`5`5оüøèñ‡í‡Oû´%­¬¬¬¬¬¬¬¬¬¬–k ‚Ðe¸©/aõx»€/ UýÃÒ90 °³Z·a‚–˘9^„-‹] ¹²LÌ%÷Á{AXº#Qñ»Æ]ÇÇ2µ"¬ÍŽË{ã‚Ó9’‡†qÈTœpwfƒk¤e(5ÞÁ`É2<žžPÌ™t+žþ®|ÐU”a&\]A=]#"¡ŠÙ%¬È.W ê½bêú×’È€@ƒ,¼är [âÑ€×T0äº8æÑ£w××—!ž• ƒh$Ëx%&a€ b1„R€Ñ–û~´Ã iss‚{/WšÓ]±&ˆÝû[Þ+4!˜›ËÐð~¢a–ÆÒ JÀûNïÃ-’zpÿž=ý@W$»Hý¶·Ò·yBJ¯K5¸F¡p½˜Ýߑހìï ʾ$#¹CÄFýœ—£XôʱÓåüÅká‘Vwê¼­¦Ã{ò£çöÉ·Ý+Ñ0ŒD¸–«¨Õa1Ü{¡ZÊI ¡C8þxÆñÆÂ8Àƒ+¾„Pá¼þÎx‡ŠhXŽ?Hrá=xŸx#ðYCF!Í›_Ëlæg] ×@ãú†7ч*¸Ã±Ô½›‘lËîV ÌÍÍÉçŸ.§N†8˜ŸŸ7Û]¤ñ«%ùོ¼þ å£3ž 4´›žeVû{`çªùzØÐ¸!tµ?Ÿ#(¡Ær-IÚ¥ÁÍ€@Â,’š»|‚Ñ#Õ;‚Ja>sxùfG<[ñ.„<ÖQÇnPž&‚ªZP˜œ•;÷•áa ||GÔ@“0`Ê@ Φ‡7hˆžC=ʰ­{;à{Ú‰m¦êÎmƒ#F5N}°ž@jsÌ汬þ²-øg°uth2X†çZª ‡”§^(çô?æ‹5ùÕŸòÎÉö=P0<<,“““xÞ³[Ÿ(xÿÈÛ²`[¯\‡£l›j-c«««ûO|•ÈÃ;B¶TÅdŠyí`¬¾§öÆeO>Ì›L¿W&š÷¦ð Éx~4·†ü˜n.EC¾–tUÂ䤕ќn­®šïƒVW÷®®*ƒ3…²\Ÿ/ÊØ­œL-6_׿zŠ¥²°°°°Ø=¨²R\œ“J!ƒ S¶øÔb F:$Ñ7$‰dÒ 8çºNb Þlº9¬¾^Ä3ývª,‰°O:ð^€è°uÕYÀئa”§„´Ö*[е ÚBÝ­0‹¹†c—‡»µ2îЕ?þV¦ÎP— ›Ãi†u#Üð ™Ì ŒJãŸ0½å@Öƒkõ™²Ù4Y ×”!‚¡°z03tB¼SB„Õ«AB‚aLõ+ÐÀð •À ‹À›¾~_©Á€4õ·€ZL÷¾rh\#ƒCYß´(ƒá&2‹ó2vîK¹>>&ùvàå®7¥}VªA4åÞ˜ê>0”'†±¢7JpÈ ¯Ó‰}IeŠrô«³ráâ„d²YÜ_m TÐËOžHÊkuÉÈh÷ 'ÈX(ü­H¨“ÀcDzC¡e‰‰…Ô o—ý–âÀp<­ßEëÉ`]Þ˘µx°Ž Õ€öx ¡,V¬~¯·(Ç’ïz ܸqC~ÿûß˧Ÿ~ªž R©n«öúäý®Lààäü™¢ôôyåù"ßãt/t2Ú¦iôÖî†_׃WéãŒþ¯ÒЯ‡KÞ jj`7úä,´ßÑ­æ¸ q@&y3Ÿ`<5cl$€&q&6à;eù^Äð Ì⺭ŠVÒ-E€áL7ÿÔÎŽ-ëî˜Ûëí!%C$У«ZEýé‰÷„R€ ªbam±ÖUó¸gÊñôz‰-ªÐS¶…í$¨àl«Æ…€¶šCyò€u5"g<ëuÜcµ*Z_õöÀ,ê‡ï¤aYÈai“”™"O¶3¥ÿúÝà– ¶3ä (˜ŸFS–Zä¶låֆڂư¼Òã˜u1Ua]pŽ<èja+6Jl/‡_ Œ7޳h?랬u¡²°e>‹á?þ´¶Jãê–ü˜ËóZCî8tÌÕCf!) ø“¾¬Ù¯ß ÈÛ'6ï¡à^üÍ/~)?ÿÙ›Ò×›\Ö~U‚ýYSî“M{ÂjÀjÀjÀjàÁ×_æ(Hcrk›¼=øJ´-´°°Ø ðcÎ_¤+c¡ˆDƒú).'®Áu¨MVVVVVVj€±Ã˹4ˆÏbQ?Œ—œ!m#u î—xO¯„cpoæuÛàbŠÐQnd³Åª¤á½`rÁ‡~éOà/• &é= èÊÛ’ñVä¡‘Û?NRÓÀ‡Øñê¡€Ó¡®wÜj0xëÇfœ=ÁXýœ'wèQ—»Vfî›Ð•ÆyÄ}ºÄõHvÊÐ0VÊcÕv!,*ÕBÝ£A©œ—é©1xavæ–øàÙ‚÷†+µ£ð`¸  AŒÞ â] 4àÄ~$  ]Üã^Rã0_:y¤ ^¬lw;‹Þð8ʼn]iN+޹Ü=ÀÅ=O:‰Æ_"dÉ è"ê}óú%¹tþ·¤ ítÊjxTʱïJ%z€‚Ô£A¦+{‡·¡€GD䱡0Bl ½ExDáK÷U¡ 2vyRÎ]¸&·§q¯À @cÕ=Iùá3ûäÅGú$‰Åª\sÁp)²óZ/Ž !àçŽ^x»ú—B=¸Ã0ô\P…7Wæû: ã’¯¡\ðR“24l=!l2­×¯Ö…÷ä°-H5Ô¿~nR¶-þ`kàÊ•+räÈ9vì˜\¿~Ý‚ V¹ÜéTU>|/+]Ýqé„'}tpÀÂ8ŒÿÜ3a`§—äÐnLÔ†Àé™J|§#´¢ çH@[:O¦4ºs†~äS.¹ïõ‰õ*£Òz JMÿ,ïÒSÊ±Ž õ.‘Ž™GY<âÌ °¢Ø5´äA"¬ÕÆÔk a”ÏSük6‘–þ_T8ðá9ÂG)µI½°ÝÜG–2ÆiãÕ‡¬1~ðßÔ¢Qº‚xRéëD‰Nâ.ÌdzéWòËÛÇý2¿HzSÖ%Ýh{ðàAqCÜ‹€‚ÿ`]ÂUÏ[PÁªj±™VVV»G|W`È (Ø=×ܶÔjÀjàþÔ]ûõÁMò3ûâr}¶`C!ÜŸ—ÑÖÚjÀjÀjÀj`5P‘·œMTiPà…ëïÎþaé€a–Æ93Y»UÍ(`ö¹P.Ë"¾É¦½r%\Bh„  ƒA,ì7+òh˜%P€<‹ëSºœÉ¯4Öu„ÅYC)`–Ü€œó @‚Æäoe´§«ÕÂ'¨Gƒágp *RÌÏØ›Öp s ×tÅa:}îÿg°}~K€¼–U\sþ5 ÐÀÐ  ADcFÁ cq V?ŒË>üÑ pG‚›{7”‚G<Ðb³ÚͨÖÔ æ‘ åçÎ|&“ׯH6Ív+*âeT#OH9þ²T°­y` WÙ•ÚÞó#½x ÊCI„¦á>x¤ÖDd—.Âhsìô˜œ¿pEæR)c/ítH”yø ñv}O*þ~¼ ûàq‘Æœíë—Í4÷À`PžŽJO”Þ!Œ™¦™rtúÊåèWßÈ…‹’ÉÒ“E{mùÉS}ò£ÈpRÂAsm›©ƒ¥±ØÍ ñ”¡ >ÿüsùæ›odffákøÎÐ^?ÜMº¤Š®]*Ègùä{?ŒI8ÂuóŽA€4êО¬‹Ÿ^,6õüp D1öŠÉŸ=:*§¾ñÈßìž±[«««««û_%¬ /¥g°X«kÛ4ÒEI黸¸øñÜlq>µm%r":?»y€ 2p;]–x°&‰<À=]”sƉ.½…+ˆ9 LA±Õ{ê1atr¼aån-ÿµÎ qO(Šrfµ¹ð ÈœhöÐe¸•![­+† `ã–Ý\ÃJvAúCRB€ ¬eܯÕj±>!“™qÀÓÈoôAÐö-V÷h@%å)‹>ã¥1.q¿øp?#XuIà/&‘X\BXÙŠbí Gƒ ,%þ îÞ+ cÀ•ªL´¬;÷WWÎÌÞ–+¿–[“W¤ÇýÚÄÄ?Ù4¦P(.ø‘Œì{‡^©…ãR¬ú¤þóå8“†'sRÙª,*0ˆì ØàÙ}~y¤»* ï¢ø*]øšëƒå€C·åëË·äÊÄ$^·Ì•ÑðˆñÍïÑ1QÃÆìÔ ~ÇU²÷šøœ½|ù²‚ ÆÆÆdzzc ÁN6µ¢û§Oå$Ùç“§ã™4žP€ç ÑôIàÚµP€ç<‡á[WÒƒ6!ñŸöWƒÎ<.‘O€ÁÒÜ58ëyÖÙ aÀ}5ìë9ðg†“–€I=`«õÄ–Æ~Ö‰´äÈEw)x‘Ïú¸¼)Yl Iïì¯î ®[c¨¯€ÛG:8zÁáºÉõÎÀrKà¶Ÿšc%Üv‚‚úÂ1i)Ú P;ÖÑy.sü®âiÙù¥A&’Ë=ò«?lPðÒK/Iÿ¶ Nž¾,_ÿXRs³l¹Ö½ (XO;­»ë ‚*zéÉ“'µÖQ a‹Å¥X`­5emêE?0\]õööêÇÚ­nѼÞvBWÍצ}ÊhÇý"Ãï Èý‡ÖTæ\ö–\œ>U?_Æ$Ï|ŽH8<àážîÂ%ļv¹~žù(bW†üpÇ·J*”ÃÈ}VÏðô?8…»Ë’œÜøE¶y·Óf¼ô—QO̯åWsGÖJ]@ÓëÇá”6ÃjÀjÀjÀjà^Ô=Ç%1îvÒ³Ig'¥©ç‡KßÃÄwJè³ca†Ï#›¬¬¬¬¬î 0~y9—–bz†SÛÛkS×à~‰÷ôJ8qb·Çg³¥Š0’aäË<²/Êø|EzBx„ÎhÀLÓ9A˜V·Àœæ$±g)?ÒÓu8 of3Ìf ß=¬o9Ùlel›®h”úaŒÁŸ|c´uÃ'TËyÌ•æ “Z˜”¹é1ɤnÉ|úVÔÎm ÐÀ½ö9xH{gqkÀ¸×÷ÜrR>ÞÑ%Q 0ÚF£$$ J`‚ò>Z`†)Á¯ÿäÄE¹vù¬ÌNMÀÍ?Ü­wÊÞ¾Gä[~ #}OH8 Œž6/ õÆý2’„ѬËè3°×K¦X–¹Å‚¤3%™ƒ78€¡„Æ#-²éŸPÀ#‡F"r ¯&±3,,_ÍôÁ|¾‚¹£)9{yR®OÏKa!ÔÕb­ìÈá^z|¯tÇ îh`ÀXüÂT«Ñ$å$„s!fèŽÄ1¤˜3cƒúwEƒÀF«¦vdT¨«-¸ë´£VÊé˜å!ÀBf¨=ÁV6íz Tà ˆá ~÷»ß©g.‚Ûí`v Î+sŽsÃzŒ9jºÏ-޹ÍC:+ ´~͹9YÆ]E„Ò@@£>Ç×XM#¶ŽÈe¾ñSÀÛ‘†nŒç ™Àq]s°Äú4Þs´àj³ç œc/*hÆ\zWôw¶AA*“|(…ÿð¾ÃöqtdÁ}Ž4¤s¨`¸ð„ µ"À€ù¬ëb þ Ã9’ïcØÓÂK2Yã4¨#y°X‰ð ž+<0<Ù“F—¨ ¥«r!“çyŒó>äé!~ëmBá LÔ°¶AëKJ4 _¬Ÿ„‡‚ ¼}<ˆ÷ Ó~–i6ŽŽ ´]ngÈ `ÞØe6ªŸl¤¡Öίñ…ÑKm5`5`5°ë5€gp«Hà½pY*ðËUŒGe'pP®­6XI·Ç~¾Úd5`5`5`5phÏ~úÙd5`5`5`5`5`5°¤ Ví—±Úº Ch»€/ UýÃÒ90€pïá‰{|*q<‹Ø¶Ù"Wa—er¡(]ðv7ˆOÊž`UBf~Ivï¾×À²ð Nk48(•\ ûŒº^ÌÏÉÜìU)|0=5&éÔÍ-Ð Rv8¤¥ÉŽ\&£@4n`ë÷འ*qx3 7†X¬K‚Ñ8ê3!·'¯JnqAb´ó»wø°ì?ðÂF<-AZMVYåÎEükLUx1ŒdT‘B† HÆñù|U½,°?—7¯>¡Z.@\A‡,n „£aÙ“ ËC}AyÛ°ç›´“ŸÃµt_ž¿.çÆ&d>“S½¨±¨±òMì?óð ü€‚Cûû¥#rmYM”´$V»Op¡æŸþô'9wîœÜ¸qÞA>i3Ñ8Mƒ©À.fåB³f õ‰ž°HÀ5æÃ:ŒÿOaðÅü,m½jÀÇ1÷½jäG>Êj>¶4òëTî*ÿºñŸ4ÊõU(O^ð›ïÃVyS.ýèóuÆk–¥q™yã™Ü)c-åã<ëÃó؆bð4€SìÀF¾¿€£á Z>WH¥ `ÞæJzÚÅùà uK“?Xâ¿ ¯Ðš¯‰sîR‘ŒDC¯jH'?¨,’Ê€„¶GEâPyh¯Æ€¯µvˆÈ›§XžWZ눭)ë†ÿU­·iY\úØ3ÀÓ6ò6ج•”­¡'-Z¶ßhÇ Õ@BÓV£é%€8•A)0p¤óºð†rõÞy ~ývHÞ>Ö> àÅ_Ü~@Áx(°€‚µîœɿ렂P($ÿøÿ¨e ¯ŽŽŽ-oøƒ"£³³³®+¶)‘Hl¹®¬ŒæUººj¾6íSîD;ëi™Ñ>tPöï}x=²eçÒ9ü_ï/˲VVVVVVVVVVVV-j ‚¥ÅY)ç ™FGÎæ¶˜‚‘Iô I"™„anÁë“Ø-2Úfòü÷`ÀÈÀÅû "ÄüéíðËP'æ‰8AOùô,#3·œ&×°º´‡p[ï©™•Ç€(ÜTc…*f”9ÑÌÕò<‡IrºH¯…ÁC' iP VÆ]ÐñDPjñ^s`*cå÷ÐÈs¸Þd¹-e¬NO¥áÉ 5‰ûE€ &%³8Úü– *ðžÁ¿Æ”Í,ÜÀ° 0áÏOE¬|/Ñ?îvÒþÑåÑ'ÿJº“£.àžutN^Ý»4ÌEà=¡†Ð%q÷ÞEè…i¤«"åBVŠ3R®ze¡™Œˆ ²Ô»&a_^E}!öÁ€éôȈÃ[BCøá­ÀSm®T½Iàpô«oäÂÅqÉds¸íéåûO퓟¾ø-Ùו`×u×mó!d‹ö[èÇ›À=¢ýºBŸÇ/Õ&•ì<ð!ð`xÃðŒ0)ìÓ^„<¨u"«yá•‚áT˜j¸‡ª‹(Cï&[ ÃƼ¿;©„ö~Ök‡GÃ5`Ã=¨ÖN¶Ã‡´'Í–ºß5påÊ¡W‚ááaéëë“T*¥Mr4sìJâù‰D$˜± ù´WÑ›ëÑ€eøÇ2Ÿ}ö™†PhTà zåÀ+ýÒû­ºž§xœúÕ O£±1Òëû ò¹ò«þ™ J»°4Ü×\ýi½- ÖúÊÂCçMB?™‘^É–öqÃ:Ê(oþš±ˆFu=Âyæc‡õ-)³<ööÁœ \.0-ýÂ0ŽV‹|²k¤ÇóKz üÎÁ”C» -ÊB6´­üÉW ìØj3)„íÀ–ôÌ5m0õfèÃ×25áñi.G$/l‰Û>Óîõì$֑˜¥åÄ:(SÔÏðæ¡º_JæpÏ¢ ”pj‹Ã55 ßàý;:%1½¨’ÀÛxA0mtC$ð¾as(Y½ð‰T¼jðèPö;î?òvtgXò›·á¡`“€ö/öíJ' (8j=l—~›å{×A˜_yå•z}ƒÁ¥šzæ&wáú6Kb@IDATpxÛuee4³í„®š¯Mû”;ÑŽEÆzZCòÒáWå§?ø›õÈ–›œNTðëeyöÀjÀjÀjÀjÀjÀjÀjÀjÀjÀjÀjÀj y ”à€€º‰gøƒvRƸΡ‰ÄãˆOÃy;\v¶ cÕÓ1^†ÑŒ 7×8V’Á® ôD¼â‡‘Y—˜ëäî’ûòFc첌ÁÉ:1N£¢s@3ù¼Œ˜©¶2p¯Ü]]ùé) ë7®_Œ`¬ÈMví“"®[ „2À"e¸TÌege~îšd§d~Fí-T!kþ±bwå}ÒÞñÓO¼)ûG_’8¼3ø\÷û ˜e\[¸w¸¯PZ°ÔÀÒâ‘>ÌçŒÀ³A–&†N(Óà…±ÄëQçu[ŪfxC•zÁ©Aý£ ÞpÑ|ú ¹<~ŒUŽ¡gY;š8ø¯”<="ÝqñUáIà! ˆ÷!>®Þ p ¡{öì§•Œ¯\Ío€ÜŸŸŸ—¹¹9Œ•ºÁô“O>‘±±±¦ÃSPðè÷úeï·»uU¿Mù|oÁS––qÝÃÇ' Ë|þ[ª©’¡«ã$3õ™mvyßZŽçÔp®4æ¼9_ðdˆÒ¸Fx5E³o‚ŸÈy’UB=\ã90ÊÓ¸ÿ'c$ÐÐèÏç sLØS·e¸)m¤è)R‚y`¹È2FpCã <à·4ÐkµÁƒy*úº¢ÇäÒ0Ðz‘€ç8LšC`€ºÔA(ß00ºvÁ ¬yPcàGuc£­×ºàYÈ6"Oyk»ù¨AJðjóOë¢ÛÕHC9„T”QBuŒ#†6pZ©WƒD Œpj¯úגЋÞG†=)Ž W…R÷øÀ XðPà—?´òà‘G‘çž{ng<X@®ãÝOwT@l`¥j­Œ•YûØêjmݬ<³ºZ)s;Žw¢ŠŒµôO—N±NêÛ»Éù•ÐÞ6Y X X X X X X X X X X X ´¬ʹ´ÓT`Tãìk©kp¿Ä{z%à ~.®â¼ë}”8wž‡÷‚<½+2•.K<ä‘þpYúc5‰ÂNhâ7×(N“S™M©¤†Óø-èßÊhîZª]ù` Ž…;qá—¦}«0¼÷õ#t%x Р’_Ôì„ÌÎ_“\a†³›’ÉLo™Gƒæ[¹D Åäñ?–‡G¿+‘h xKmX¢Z}¯]Ñ8Cà@ ÀÎï&˜‹x?£¸ý VÀ 1Æuw“7;Èrü\¾>#ç®Þ–‰Û3R( oWT“Û{’òýC#ò½'öJ2± Õ¡½ˆÌÌj_Ö©±^nÍW S†ÔË©–ÕKn©Œ:×Mî´ÑŽMJ´Åï_ (Иèµ`5ï\Ç¿F°Ë©t:w6o½õ–ܾ}[Ã4ò^m_¯ ÈÞCI E1¦¹L5úrì^ö@öK ÄLìçx¼›„]±Ž²¤ÓûzÎäs—j~iêœÐî:p? 㦄1ÂôŽ{Z¼È$ÆÝ>(“@ îÑünÌ×F*2ÉNÏp—mñ ÃGÈÀ œC×qˆôاwrTÃ7øPÆR½Œ žõQÑ(Có?ùé1Nhx–Ó3NE@çò`(‡` ‚X“`¤ÇŽ–À+ŸFz7QŽz€`°=8OPË‘¹‚¦[¢Åqž 4V Ce˜3Ø'…Éqåܹ5Þx\`iŒ'Ü!5³Ç¼:xlM{ÈŸ`ÓfÒð=Pë‹ßª£æ—Š^ù?Þö) `!M–m>3)‚+èÙ/Œ¡9à»d¢&- ðJͦ kKsʃÔÀÎܪøj`$˜"lmÍ1`³Ï›ò†7É]¯  Гªä$ŽV,MÏK¥Rz£OòbS gQ7Ê79Æ@ïT@ÛNzþ¹ºÓ1QÛƒ:™ ¡rMÃ…uUЄ¨g ÐSß‚X”IÃ#`Ëcï Pྟuwö]Z-°ÖÊhBÞ”Î_¶™ÌèhÀ…C¨W ò&SÐ×Ã#€^Ô?¨—¼MÐÛ²À7ù?ßñÉû¥]@Áo¼! {Í"Õ6½…¡6ë¦>?)Ÿ~xDàñ§™äÃsëo~ñKù?{SúzñŒl¦¥iITÐ’º,±Õ€Õ€Õ€ÕÀNk@_8Í›éN‹¶ò¬¬¬¬¬¬¬¬¬¬î1 Tà†›áÊù ìܘ&åäh‹ÉcZçà>I ~r CÜÒìu‹œîMr®úËA5üËÀŸû­Å¬tF 2Д¾@Æe3MíÆ_×V`U»ÆRçAÃ÷—†”ˆ³Å0Fˆ©++1U͉ÿFwô eLXNa#5ÒXF'÷®üˆqÏ¿ÆkÞݱW{‘j1/€ïèêÍTú¶ÌÍ\’ÂŒLOI:usK•ø RŽ¿&“•½2}3"Á© ÂT¤+àCG@¶ 7”—Ž "´ÜÃ÷U¥â“T¦,GO}#.!ÔBTëKIÍ-Ðìï÷ŸÚ'oê“áXY PD8N¨ÑßN,±Rã‘sÈ h b•6ô†‹,€‚ø§IïCcnQàP Áý{h›d”aÅâ²É´~;€¦âxUMT@YÔ•5lRå¶84@@Áïÿû<øäÀ+ƒy”`Ô/ÂL`{è15‚öLä}kú¬˜¯ï:8‹~Ë}Àý° ƒ1öià6¦wcˆ&ÓÜn ØtçïÒ:ýºø7‰«êI«BÐ’zʰ‹SΛƒæ{IËòØ(=øã¿1´»õçySÈQ†Fpz_`žõ¦ ~­…òâ1ó 0´uãyCiÚ¤ a+™‹àÃ}ò$%a~¯—1› O3ž-AO dâÃ;’2úÐ ¦^Ðb§ z<”6ËtD®Èã_™úG2Ít®æ¬þC Ük¢|Ø2Ó8\/Ê4ò)Ó{ `€4F¨^_ì²›°Œ §P„÷yÇ/ï÷n P0<< à!ž7Û”(xÿÝ?ÈÌô-HÐÆ¬+É ÖUÏ–´OÔ-S¥ed5`5`5`5°Uà÷¥ë·äW¿{ày‰DBògÏ>.þÊá­aùX X ¬Ð@6_”cg/É_œÅ*¥’ìéë‘¿ø”|kd`¥=´°°°°°°¸;(Á;U6ÕØÝF5‚‘¸tôï•Bøƒ˜Äçíœ °H° ¡f2%‰ùkÒ®Él†!³ÖÍ4ß™¬¾CfrZcÐÓ[AãyäoÌ0û׿k2¿ˆ˜ô˜CïéF8†¨W"!xJ ý2nÙÖep–^ë¤,ŒÁp³2\­Ö·-êÊ•ìþH·ÔBX» ‰æ$@CÃÏ ßUy«îs’‚hš¿.Ùì´ä°Jœ¡šJ¸|þ¸â?”rôY©úû¤XFŸ,ÓœbŒ.Ó‹Ÿƒói\Ö ¯*AK:°À¾¯£(`U:poÅCîýµRêÎßWtê1>5+§Ï]“ËãסŒUÛAVV\ÿã«åOH®ƒº­UhfÃ5iäçªî` Fu]ï ò†þ±=+‰kËëKSÖ¶ÉØ@¶uvè³íÐõÞÔÕªcγVëjÀܺu cÜÆFaÞ/|w€‚>x(€Éc—鉿½ÃŒ ìÓHjXçž©áW+£÷/û$ äìý\¯‡jàÖ]dàWÅ#‡ÿ±uLõÊFX攺ħy›¶gõ^@ 4gyx·®4†Sº–ÀïÒXB/îàæeE˜@ËÕõÜ6QU" ýèJCðx£ÿÒXnji*FÞZPHÜ¥lŽÿÎmÚ Tð±|ýÖ¬|zj î+ÄT"~à@|¥«¡}|CÞα­¹*­sá‡_^ùw/¥{µ^w[GLx8{Y>øòœ~  õLÉCC=Tp·/Œ•o5`5`5`5`5`5 ‚2Œ•Å4•üFs±kj,ÖÕÃŽEá)À÷ÖkêšõÞŠ·³ˆïžƒÓ ObaY2[ÁN€ b! `Ý£ ‹€ hºQw\©{à] €qN”3ÄkÌ£’T5àŸ¡pîôxNÎOV$ƒËä…ŠSy ø‹ (èOøà1¡&‘€qáýx܇ÙöVe¨>è¢ucª{XÀ~M½*Ð|°¹v/¬ÖV†sÍýpŸï‡w^óW¾ã/ÙýPhPΧ›9/ùü¼Ì§0@È„…Ô )"( xÒ÷#€_ò¸}‘¤T¼=â JÑ7(eßC0Ö ó*ß&¤‡kÒ«"SX€}¡„ë^B<êÅ ô«G:Â>éêð AÀWþÍß»›½æex(»r[ÎŒËÄÍÛp-]P£˜©uó¿úãòýCÃò½§G%Ù½ dIÍÓmÂø±ÚÙ 5RX¨V¤wÇì…Ç gE¾a< o€äÁ}Œ_ݯÒû r¸¦ž Ñ»‡|cÛ/Cå9õ× µù³^;¼hïÁµwÇ+Þ·»h¸oS«¶ØZ8r䈼õÖ[Ò à•=2 @A ?°&“.ŸLÏx€DCô’iãœó^Âû—epÓzj„ ƒ‰òAaœW£2vÕg/ïo®ª×rà[÷^€<šß]9¸æY®ž§¡›…—‡Gpz óqžõ@ôÏüº¡XtÉ8OÚ*ÇqÔO ô¾À¶@„…õ4``ê̱_ëZöYz`‹X5šêÍj}Ì›‚N½ ru¾Q©µ‚*‡…XNÏ8 :#µá†7m3\:1 0s™”RáðaüTžù¯5 @VÙ‡:›ÄšS’O°¹¬¯¡c}ö8ÔmÈ‹ò` xÍÝ (B°š«? Þ„LêŸZ¤^Y;}‡Cr…šüë¼òžl¤~{~ XPÁ:ʱ§¬¬| x0 Å$[€ëLÆlÚ ð¥§7eÜ‘jx3Î0auŸ'mǮݒ³—&äê$&Y3’ÃêðP((ÉNLvȾ=}òÔÈíÚ‰š&S±T–Ë×oËÙ± ¬ìX>á² öþîyéÛ$\ŠÁ¸Q¹Æóœ œ™OÉ7WnÊ­Ùy™šY[s)ÄÌjÜÖX$"{z»dt¸m‘½ÉÆâÛ¶¯ÖkÛ¼IÆ:ÑŒû1_4}}.W0q87Éz[Š—>ºvã¶¼wìœÌ \«¨Û?$?~é&°ù±e“Õ€Õ€Õ€Õ€Õ€ÕÀƒ  `ex((g¯µM@†¶hWŸt K(C_véë>cá¹Àüe ÛéTßÀyézd \–( þŠ' qRgÀ¾çݤÊsèÊ\AÒˆ_õÊ©U›ÌË"&­iÜÐTäT½1aÌÂSBF`~?ýe„óÒõKñ°Wº±ƒ{wŠKƒ ­˜3yïñ;.ÜI×X§*ÞeK4š¢ü¼i±V:tÖÌ5÷cîÄO€S¬W7U迯t·EAJ0†W*ÈÁ¸~öfA²AÉÇ`pñ„` â= #IX0Z¸É~ò.:sn¬&“øàþòãx½º¢>€fàÍÓ5ÝÑ îuxÌ`¡-¾¯›úØ™‹rþâU™[ 'üÝ>àV²‰íá½ yíñN9ôhtÇjá8Å4ú31Ã5`؃qQJÎû<„Fr‹ä¨ žŒøµ ô€¹Š—Ž¡}§dèàÖ¿^ÁÖwšo‡3ÐëýÒÆi½j¶Ä¦‚ ~ûÛßÊÍ› ùbžeë5Ñx(VÆR«Y] ½,‰þ†[‘†z>ÍÊ_5ý:çз  yšnÿi&½®@wÊ‘+ùº.ûyl Êc¹JžüYˆ[sïsL2a˜Çš˜Ä|@¿êÒºä».ô—¼ €?ù°(ú2¨­ òÌ æÞ¨¿Ö”ýyK–Æ.[O†Æp arQÜw³P„ævò ·ê‰rhH7:£2t?¶”­ÔªLjŸ5#_PȨ:<¨¼º´ƒÞ4OK² œ«ÈúðÀIœ™ÕªS¢¶Åy/R}¨$—tÕ-Ô¬ÀÅÔ ‚{‘”¿j  ]Ál¿æƒXÁ#šÍz˜Cïfÿ7GŽ{$•f*¼j-–g>úè£òÆoClçÂ8z(øàÈeÆz(X~î¡#ó¦qUÈVÅjÀjÀj`'5àÃÇU²«W²·20`—düÆeyüá§›ª]ôçSÆàæuø4UÐí: Ì-däãSçå£ßÈM¸BL-慮拘h¨Â0êäG³a€ ¸Z‡îæÿò{‡å;÷ãœûš¿¶ÚnÁˆÿ›ÿ÷9e/“ä4râ+äð`/Ü’Æå©Gö5žjjŸ&GŽž‘÷•i ò…²r( ]Ô˜§Àª”0¼MD#a]ùþWöyá,¶3Ý«õÚÎ6ï&Þó錼ûùy糯dòö¬Þs>,…#¨åµçŸÂÎÆýf7é˶ÕjÀjÀjÀjÀjà~Õ@¥”×på<@àt©®³¿­µÆ#V<9 ‰Þ~ aE>çŠm2(Ãꆱ-Sª >Yd¡ºaóÛÓY‘nìs¸&Îfß‘8óŽ y|Leªra¶(WfKìs’~õ …O)0˜²ž7ß-êÞå|Åh~ÌÊ«!@ƒ€·"=ÁŠtÂͽK ͽS‘UëDÖà?ã*wÅ”ùªe–ÚAVÆzúÝXW^x3ãO$¡ŒnϤåÒLQnË’ãª\?MF&Ñø±U ŸÕBt^ﯥoâéŲŒ¨²ìþ€÷UÀ[•8B(`A;A šV½GpfûŠŸ¼i€e¾øê¹pqá³0<º-tx6¹ùþùÉÿ?{oÇ‘ ÞZ°öX pßDŠÔB‰ÙÚZR·¥î¶ºmµw¿7çÍyçýèÏ›ã>gÎû9>3oæÙÓãñ;>í–»m÷.©ÕÚ¥¦¨…"ÅE$Á@ìû^TÍ÷ÝÈ(€P(,À•™‘7âÞ¸™÷‹{esI&¿ÐÀ—pÿyñÖ§WÅëãc<ÜDß¹¾‡bк–¡ÑÒQ+y­ «èé-YôQ:íX4Wà^×ÿüÏÿ,---) ¶?V'Õá¡  ¬Ñ–ót¼ÇøÁ–«È™ìzóTœz6 ¼˜÷(ßa4ã^…á˜yúTÀ³Tw´>Öež4ë>6ê¶?žÏlCßCú9qàOé"| †i5ªÓHŽ ­“¯{± ­ìó”‚ #Oð×¶BÃ#ØÒ›¢8$¨™dÊg%ß»ø§Om²ÊN£º1’ãYzk0'À>b œPuÊúMuZ7§‘ÿÑó68Ï:ÁVõoõ‰ œÄQ·øñ<p´ZÐèB,Ï<ü‘Gл–¤µòp߀È€ RsOK)'=˜ç‡²’ÁÔ5 àAvG°&&Òpò˜d®°¹&¤â¦ åßÞö˧à­* @ACCƒ<ýôÓRSS³¢€‚O>ÿR>>ñôt¶£íSïr¶+Ybȃï|÷OäÛ¿û‚”—•xZIFéò–SëT@DØÕ«WåúõëÚÙ‘÷íÛ·œ:Ñ—Äjðhll”[·nI0T„ÏîÝËk`!*öÊ•+ŽG ½Ãé*%y$MW/H^F¡¶Ž^ ~òá?ÊWƒÏ%UHd2,‡ëŸÕs|ÝÁ òLÿ-}gc¢jgýÞi士qÄ üàrŸÐµß±EÓêIvÆJâSC!¹‰“üpné×òÉhgæÍä‘M·Ÿ.­ˆÆáJS›üè×'ä"&º¸baöÔ W\O h@cxgÏ€´´uKãƒ{ååç]ЃÀà𨜃—‚~ZÓI¡ì,Š…E$®`?ÓxS~ùÁi¹0CäžœµMðÿà•Þª+V T°VåZ„jé< WŽÆwäçï}&ç®4IW/b¶òËÑKƒ#ŒY:uló7â¶ã¼ö‘xÓF° 0•÷‡-ÀU\¬ƒïž‹Mpƒê’Ó€Ó€Ó€Ó€ÓÀÓ@Þ "Cw0÷ûãÌ…DÎÄJꂊÉ+.•`&²—‘-Tø:Ïñ†ú7„…þÃaÉïɦ‚ ©Ì J&Œ¯œ~÷1žËÿ1±­Âp«ÞÔ-r¥#&­Ü¢,'³“’¹·WC0€œ8Ï„¥ží¥0Ç/e…a¬@Ÿì磒YMƒ}ðXe ¢ Ý pLè…pPy¬ñùÉÚ!Qô¶+u¢¡¼ImÇcêš§ª«¦®°œ½=!0`„')k1}c9h“÷/ŸÀf¯Ýx{E@¶‡\ÁŠbbhsÍ'Ðß›àðËË·äÆíVx!ä·HzR¿üÄùÊŽb©€÷à.$ +ú©s#S +VÎÖýTÑdç«—zÿ°^ X&:†ñ=ú<“Ÿ ¼{ÁzéžÜ‡gªá̽¼Š<"t•k)?ó·s¸|ø²íU…ÑçRøº²÷Ž,  ©©iQ€‚šƒ›à4ÞE|4S£#²/zFzP…´Ó0ìY‹õ~…›S•lŒÐ4 Óè3»Òãˆ5´òAui9³ó4HÓ¬:¼Ý¸§ïq¡šïtæp cÀFŽ>yEâFrìA¡·.óQÊTz”U>(@îÆ›yÓ»žÃ‘i/é¡>¿°D5FJ«’°æ¸wÊÅDïÔ¥-cZFJ<ßxÞŽ”Ûäkø–Â9ãíõ³+Ë *‡Ãâx¤vÓ8]¥¦'Rm4]ýêÕ_J¸G@úq|Ü|øÙ»2˜u[rŠ\)zêÉÏ.‘??ü?ã(&=}Ýò¼õ_º.*™™Y²oûA)…ǃĴ]ÑôÓÓˆ/”ÿôtmb5I÷u•{w޼‹³I\nÕòI‰gdÎäÁêðøƒ™u¸ÃÔ4Ð #ÿÛŸ•g.£aÆÁKôLPˆ8®%EyºŠ¡½§+ðqÄ(ÝÏ_G8ªÊ‹àÎ}~&[ÓItŸ—’ÊrÄL1Ѱ{öòmùþOÞ•fL¢0À” @ÞbÙÕP-%…y’7©#ðXÐ70"·îtÊíö.mo¢.Rd™ÙZ•+%áѼà}ÑÕÛ/o~tNÞùôKiDZ eÞF/p² 3þ|oØ´¹$[þôH¥=\pkï\ê•Îö¾éÓ€Ó€Ó€Ó€ÓÀji€‚‰ÑA Pf¸Êš[T!…•µ’qw€@j3ÓºZÍX·|° „zfh„^¬Àn˜¾4'*U0væ‡2ÎÀT"'ía¤»Ð“ÆÖ€ŠQäÍäùr4<©!xtRš¦§m†‚:ЫAì¥Ey“RD,Å¡ÌL¬Jç Q${‰ñç|`( ³SíP×ï–0¡Œq‘ï}gƆ +ñÕ`É£zÇcJW§šÃr½}\úÐ7¸b-%Ó¿DöÕfÉ–ÊlÉÏÎÐÕ«*£†E˜j:›}Æ5àóþê6¹@As{‡ŒtOãÕbÓŽªb9vÝ[+%¹èW:#€Šh÷úV á bý°´)Œä hôã@¥€Þ»'-ÿØH?Â"x üøF-ˆ`dÏ`73ËÜ €¢—T0o;t"ì\Üç G.9 ¤¨ô yP!™9&T WµóEDƒµ1Só­„<ÜzK0û¦f€† ZïÕ¬U7Æv? ©¡š÷1ú7¨•‚þcMôp ;äA?ê' ‚X€Æx…`Ÿ5ŒÄñ•Q ¡”ÖÄÚ¦8ÁóÈžÑðÈc†ÒóŽ- e™Ï$¢¼&àiyFƒ'@~êÕQ1”eÚ+ÃÖÓ¬“R0 ³µqÚÕ,3Э‰šFuÞ5 =\­<¨nZëÇþ«N°c¤¡¾µFȹLµ,4%êô{ò3ßèVuÄLОš|³å©ù’Ñ…ƒ48˜¤À¼”ƒmäþkx Ra_¯§W)5D]q*úgoÅä·ê¡ÀÓ³G“ʦ¡¡A((//_q@Áé“K_O'šgûËÜÎPU.­šÖ¨€šÔ86\á?0€ØQ+Vƒeg<žbM¯D;øu65wqºâGvç`DÇey ìŒÀe.'A8–ÁÌ˧’HŸÈƒ „atiÙ5ÀUó-í½ ( köM¥…räà.9´»^Š ratç*¸E8„/¯7ɯÞ?-íÝÆ¸G—‰-½ò›gd7Œôµ•¥)ÉB…ön‘Ž==…ù!©©(I‰ž}õZS»üÓkÊÍæ Žù RUV,¿ûÌa¹ÇfÉGœZ†s`’o_/a,á «º§¯Û4€“ãˆÖª\ ˆíN§ ‚lÎ^º-¿xÿ¤\ºÑ¢?øñD C†ÐSǽ˜ÂpíšøÜçs=ñÙžŠNl¸ä4à4à4à4à4°40 Cö<L Nxº€?bŠç•KqU­da\ʱ*æU]Z¤8¾ ó/*°Å·bú­8ïEAx È‹w"rµ-,C¨ó›`¥A ‹>SdgôŒclAØ55¦Â'l©€yº9Ð (àêm|›M›Z÷Œ·ÓkÆ‘¥÷ÊǻќÊñÃ÷ß—­cXø0yc욥׻œ‘•á“u!Ù^™ J` P@¹R¸æã¸>¿pU¯Ü†§A<¯²Oç8X“/ϸ+ùKÔˆÄ3Ú&n·Öm‚a¾Hþáçˆd=Rž nµtÉÉ ×RÐ BeY¡Þ¿ÍV?ïV¼ â/•ÔÖÕ'ÿòÆ ¹týN|P^WU&úâ1噯s¥úšrC¼TÄ´\î´VåZîvÞkõ 0ð.<üäO¤­³(ë €UüR½©Xž>|>cò¿üà^S‹k¯Ó€Ó€Ó€Ó€ÓÀ†Ô@«q#X—Ä`V¢+8©u§«ÔôDªª+Žë¶îlïÿè—^¸Ùî“0>»gÚ#-ÞÍyøåªÿ¿ÂSA;Œ½ eçÈ _y ^ þ1ï³f)q5t5‹©ËXS()È“ß{îQùúã÷ËxÃà1*3“z À*ª‡öm—¶®~ùûŸ¾‹Á¡ò Ë–)ç3ËÎRÛ©VÊfåd\Éo¨§ä ¼ê½€u³6¯@ - ‰ÁuP…J©í#_òÉËÈŽö™Ó†¿'å´ âÁ#‰-<2Š=g¢dÔõÅdx›’6G5~†ŽÝÃiùÕ[“râ4=ÄÕÏjRJ P’¢îa¢u*àµ*,,Ô¿•¼n«Á£¨¨Hø·R‰@Ç#5í:]¥¦'Rm\]Åä«/HA^¡üøÕÿ.g¯œ’ÈØ„þ%jgP†aöKͦÍü‘ÊÇñíÆ‰c®N7 *À ^ 22aÐ(6€}‚eéÁ.@9̼l:ì7t™Ñ°OÆ`‡¥­ÅLh§2-¾º*ÙQ™){aO,ʈH&WZc ÅÀ5¶`éR¡øÖR—é°èÊPK$°Yºe½\%Îm `{òåqêæ¨\‡ÇǾQ¬ÈLså¾UáJm÷ÕfÉ®ª…‚ôÃ<5šú5?råV§\¼z[š¢pai”ZlÚQ]"ÇÔÉѽ5R°4»Ë´D`Ë$êfß` ~Zûa’ù Á°ø>§·Ü™ñ¤@‚øÑÔÎÝæ1×=5%aj{óµ#t.Xj’8ª   Þxã ioo_ `›ÔÞ_m´ç{«ÑÍMÓ6óø À½ë=/ôžö¼p¼¢79Ï!ÏvQ‚ =)X‚ Ý̾†G@ž–Åc¦÷ª0Iä(£Iù2Çh˜­ü¹RßäGñ`b ý4 “€Çü#˜Á†G 9ç½y‚T `ð éÈÓð ƒ tªS'J)`À“Ñ<é ‘õ` Þ pž¹di&„+G² ôèTwÈSØ€'§‡J1Êxr°ljl?³ü¸4Ò3qÝ?Ïë0gP ù¬Akf.öMy_ð£Í¬øožÊFäcö<™Édޤ5@ÿä󮉽ŽìüGpƒñþ`ä!Ø3 R¯½> `÷îݺº¬¬Lísˆ·äìó·äôÉ¥¯§mLxwÍQsï´ï|÷Oä;/½(å¥%æ6›ƒÖe¯¼Ö%¨`åÕâ88 8 Ü{ðI~n}àiÙ\Ù gOÊçç>–Ë·¿”¾>ÄÈ‹HaA‰ÔWo•ƒ»’‡•†ª­R¿rÀ õ| ÂXšÐÜÖ%í½ÒÞ3 CÃÂd]ia®4`Å~}eé’ ääqåv«\kj—‘Q)ÎË‘ºÊr>Ф¤0ß n©DÖ†ànýÚviëèE½ãp×–¼¼l)/*Ò¢<©(á¶ ¥š9Ld8‚T'3óa¨¯,-Œƒ ˆæ*ˆq´7'”d"!ÕÊ—H7 ãns{œºx#^SYQ>Vﺫ€‚»-Ýñw¡ŸßÁäC0 ¡Ï䆲¤×p[m…”§ÖWâJÅÎr×Iñ>¼|³EºVEŸÎÁzey±ìÙ‚ -è—+Qvö“k·Ûàw ˜qÉ fHAAŽÔ"ôÃ|P?©¦¢‚\ùúуø°Ÿ”C{¶ê½‘e,œHrÉiÀiÀiÀiÀiÀi`Ch ‚ñJ+XóŠ+d|¨ÞÂpXÀ8å O4Î¥ Çxÿ˜ø;áÐ`P'}ôHCœz3ЕÀ˜,ÏΕŒì¬8Ѐ!í|Ý `á9`å³Ñ~xFÇ|0¤ròÚ¶.¾c3îúö-!ukŸD¸5xRà„;>ƦäRåödW#,OãÂêŠf^cY.´º•·ô¬Ë;G£%Ëðøæ1=Ÿ½=*—ïŒÊð¸1rP£k)ç/(Ø^‘-y95ÂpÉi,Åk>޾ÿù…«Òxù¦ô‹ڄ>—ßÂCÛ*å™C›åÀ– ÉÏD¿™Óž¨a<#8÷cô\@äN"(ϱX f4LXèjd|_ißctù¬ƒý×KêMÃ{~®)ê‰Æ»§¬°ilçռώDž7E½_Ó`äŠlx ¤(صµDPž}r÷­{q+ÆTŸǘ·‡ã0G%|¯˜óúzᤤ‚P'€qÆÅ>JòÞÇ&õ<àûiÔWc¸žD],NroÜ£4xkIþHCµ³N}SbkžÆ«N‚WɳZROZ±c…稩#0ðèÈyÖfyÚð¬LÜ‘ R ¿À&±ùäG…•ÚJH:&†Mà{šZ3,'CIÏLËT{*>ö¼òô™@¿jŸy”ËK“8&õ6 âjà• qh´nÖI£¾/´nm–ʆ'v¼>z[ОÌZ à/½ì©(w•h¨`•íØ8 8 ¬ daÕÊö†=ˆ×½Y½ÿ ðR†ß %2àF.±ÙŠ.(Ì/Ö—ìúhÕêIÁª ³—oÉ«~!M­2Hx|î“-™Xý“Ÿ“-µ<{d¿<²Ç¢…‹D&åÔ¥ëòê§¥¹£GFFªÙ™p_š CiN([¶ÁpùG¿ó8…)Õ?Ï\¹)'Î\VÂÐð¸ŒbÖŒ“›QÔ¹3áÚ,øù¹!yüàyþ±ûáÙ±ú–9Ñõ”˜ˆ”¥ w3 ¸qáj“ôÃ%-Ò»`n¨ò\ .£p4‚wõJ+€ALöÖT”¨÷†d,VS®DþC£còñWäíOÏéäÒ(<‹â>÷)¸@ïØ´yº‚Oé vJÍþÉʱXB ýècjàÅÞ—ÐÌæ8[c &‘(¤c䨑Ÿå8ÃyÝÂh¬žw”Fqkb6fo<(È$þÇ=ʪ8šKð‚IÆ<Í}5¥{²¡ !)h [–õÁóWÈó¤hÍ.©¼4rG¥luu>À¤š2€ã<2˜Ç¤ X%€] Ëm$ Ø"&–'ˆQ=!èóùgB/xd¨›Dh?¶“ÐÅe95öƒz 4€=©GoÈD! B0å jHË£n£ NÍá*qÇ$£Q– ôfkä55±Ž.¨£©b¶øì-ˆX’¤ô@`Y²mê©Â²ö'¦ ¼‡_'"ŸžŽbîO³õcµµµÒÚÚºb  >|÷Méén‡üFkó JüÞ·¿á<̧¨U>ww-«ÜXÇÎiÀiÀi  ð…œ‹9þ¹”º†á¢ü_sBÞýìVl÷+  YiÒnµv©±³+¤·o®JF–4¯+Ÿÿ<>øü’òˆÀh93±þ›w:uEöŸ¾xTv5ÔÌ$‰sRàNgüðµßÊ—ˆØÓ;(Cžkÿ8ÑŒFpw`4={¹ À…ÇdÏÖÚK;œ€Ñwº´‰žr`üÍêðÓf¯ú–×÷ZsG|ÌLƒùƒX9žÁ¸Ë˜&†½p½Yþߟ¼ƒ0&“Qý6x·øãß9& 5³C¬–\¶‰ì3MðÂñ‹÷OÊ € :à€2'K½Ühî”Æwäk¡inÏ4 ƒ3§hÈ­ˆt¿¡ó¬5óO|#)ÀeŒgæó9‡ÿºšÔT^ÔÉúè±Àp7¨Wð"oæG9®@"™%@–׎ï­µÎÔ"èù.òr´ð?”ƒí §B‚|ŒŽLªmdb“ü€‚Ï–PÀ…n+•,  «³Mï…ø$ ª6U¨>*ãίŽ’ŒTV‡±ãâ4à4à4à4°q4Àîgågï}ŽpÃÚ° VõÔc{ݦ ÁÝ9óiÀ¤Á +ºï`:]Ƨ*àÀ©§Hþ¿Ÿ¼+ï~QhÄdòc2(?'GWD3Di‡±Šüäù«ð6‘ÿü¾¥áô䌟QÄB|ã·g体Õ%«pß ÷äÁÉή>„tørDùÿ/¨?+Ós©7£þÅBt•½½§/^”®Þ+Ëî~˜¸ÌojâßK!x*Ø\Yb—mKÀù«Ír«Þ£¸˜*#¤À·“‚ VK.6+è.Þ¼#ÿðÓwåò­Vx21+?xŽÉy0~çb[/ú*ûÁ Íñ%<<ðpûæJý#½M+Q'=†˜ñßö¾\Bȃ1~ax‰÷L(+S=_ô´16PðúG_È…͸—øÙ•z¢W‚¾v\>;wM½Kð#‹º(D¸ƒÍ›Já­!Oú‡\è•®žALJO*ˆáµOá>ê—?{ñ „,Yþ~”z ¥Ó€Ó€Ó€Ó€Ó€ÓÀšÓ&Žíj9uÛ c1x àj^Œ5 Å) ŒT 4ÀjÞ•PKŒ™ÅïœàÇÌv<|<ÞïS@NHéÑ€Æ/3ÿ»æT=—@£ðN€¦B×v›_*k+mÞxþŠrà ßžüŽÓäMòë¾fz'hйrs?1M+“pŽ»´$h²[æC‚Éf¾wîàqêæ¨\o—¾Qx@£1h ¦}w°«*$™ð:¨Fl\Ÿ¯y`škÍýøžº#-˜¿Çwç›òB™òÍÃÛä«ë¤$?¤Ï‹x4ÄÃo$ô7>Û”~ðÝfŒ(Å~Lze½î¦Ç p÷TC»Çe­òÐë`×ÈâwæÕÍ{ä1CW‹çâJlP ¤(Ø PÀnlž |÷°¯™w Õfß¡i¦6„ÌOxøh’Ã1³tÅ>w1ÿ…ò†Ê£ÇFzV)@O#5éðÞȃû&ŸÕÒpÍzyÐHnj4¯2øs>¥@IDATæá”þÚ3Þ3HÉh²6uÇ·šïÝKh´ ‘À24Þ³.NÀîqÒ×&ó=ÉØ5Ž«`„À“^Ã#˜‚x yz0R’È è9¤”¥éÿx4õ:R­+iL>òP/÷õz¡€†sÂ1½OQÇLôb`‡†ƒfAQ9+°À+CÎæú£nðÎ )›­ož1Z&‘ù3y&yây €Iö1ö TÈZó±Á (8yzRC$¯mîÜDkPÀ¹L—ÖŽ¨`í\ '‰Ó€Ó€ÓÀúÔ2=0þà5ÄCò4®þ Â<¸o;\Pb£§â-Ž`fêvk·|pêVo·HçRIt×~­¥Cnà«øi=úÀN¸Q߇ô\‰àƒ² õ¾~†ÑkÍ:p ÃWç•[w”×ï>õpR6ô p^cžžv6TÉ£ûwÊÞíµ’ C*`¬—Ÿj(þ5VcðÙE D£ºû<ŒÅôšð,V /GbÛ®auùàД§‚B„X <©&\•·£§_Û5 Y3z¢z¢Á;ÂC0Ž·cRÅ& ¼°Ç4N÷ Iwß®3 êàKÃEYa~Òú¶lâ–Fgö# ˜øË•ÌL«)y3”À¿ýæc ñÁö2Ñ=ÿcw£ßlǪû|uƒK@AŒèÇ¿¸,'/\‡Q? ½ J€)$¦•¨“¼~ °ÌùkMˆùi@\íÿÐÞmøÛ¢áGޤ½»_>ú¢.=¯À+Ĉ\i‚“w³âûC£ò!îå÷O^f\¿kÊŠ ä…c‡Úd;îo¸ @'‚Õ„}¨ÿôÅ›òs„bàõíÇñgç¯KuY‰üÙ7¿â}ˆÅ«v;NNNNNNNÓ4  Ì‘¸r‰)hÀÕ€1ŒÏâ 4ðÀÑ(f\q~9W¹›ª0ÆÒìS^ èZ}Ð@=.øáÍ ÎðM”•¥+ß8ó1¬'üר)µ4ŠòôP îª43._ý-Wl ÉŽ „¦ËòŒ «Îu•r„! ¡^x“ þ0!OOâ/0*Þ–á5 ´Nã,&­}™¹ñs¾Ì<•YzìÞË’…K| 6C¶P—P%4ãÄàMå[øšHsþF·œ¿tSºñý9ψé4íжJy|w…ª HÁD7Â$Pˆ0ì‹H aì3ICj˜Áä¾·ÃÃÚéÞßo-ìw~„çxGQaøÜ°Ï@x.ˆu©ç× [€gàRÓ|ºò«NÑ'yϪaªƒçcŽ\*gW~½kà7Þ×_]ÚÛÛñØ_xlÀð–[Û@Aƒdçeè•YŽ1‡¾ùü3†iî#3vx Éëy0jsÏ”é}Ñ»pBÃðý¤tæ¹` ès /k9¥3†tãPŸm¡8ÖÈoyÓFÏD¹Ôx«µvØè€Æy–6ØàÅšm¾îñ]j˜€€ ïOÊÌ<@”È@4<hÔŽ·À­}*‰µQ-1Š*ƒ?~á¨qi0ç€jG}•ÔW—Éßÿô=9ÓxSÇX4n¿ýñ9yîÑ’÷ÌD Áž-U¨;,O<¼Gö﨓Ң ,àJø“0så~ÂG„Õ-.Êœ0%MøÞ»U¾òÐ^f_‡Äqž‘é}Ty'È/«¼f¦Õ”‹FóÓoÈ'ð€a ßñMVžl¿zð!*ÐzÙÝP-{·ÕÉ#¶ËÏÞ9©+êrêHL+Qç8ôrâÌå)@AN¶<ùð>ùîóAÎ\ÄñDüWô­8쬯Ä=P+?~ó„tdÀò©$‚>šá¹âõß~¡€–©ÞT,Ïïߦ –Äzê*cð\P&ÔÙßÿì=€ †eG>èâè¡]²mØ"±¬ÛwppppppH¦D ŽÜ1\LpÀÅ*>ÎÞF.a2 ÷áQÏ«Á „OÀºíY@NHûaØ¢AÛx2È—€†NÈÌØÇ0Xqþn €ã8Ù'aØã§â''ÓüÝËËÊðɺV¡g#Dœ7É>S®`&P€F[êÕž'(%~`3¹Åèc`ö Îúë*E{:H`³t{ó¨Ê)Å'¿ #<¬ ôKßÈ„tN"”à¤ôGex,ºê@ƒrD¯ÜY“-…¡}C¯uj×<ŠÀà°Íà;ÿ‚\Å"…Áá!t ~Õ->»o³¼øÈV©+Æ÷òƒJL½ €M¸ÀÆ· oC_DÌÌ™ê®ì‡Éú"û8Ã"0”ÂzáApÏTËâM_ôN:ºZ4W`£i€€‚W^y%å˜ñP°€‚zÉÂüf¢9Ø `$Ö97λq BÙù,š¥í}´*£ïóWÃ"è †–V/Ë}¼ËŒQãV¬AÓÜG¦òDY¼ZcÜV¹`ŒV‘´&‚øŽÃËyg4lƒÉB>y’7y©I^÷Uºóg)­ƒ•à l ‚ôw™"Ü?æ;ƒ¼9?© (8XYäª5° ó±ÑCvÕL²ø1A»êÑà¡Fg K„¸z˜™VS®.€`Þ‡W ‚6˜r° ŸýðORÿ‰²Q×ÙÐq]U)úUžl­©Ð•úÛê°:%!­D½¸Ÿœ½"ýÃXm…ÄûíÀÎzùƒ¯Ñ{.½Þ«5›Jå¹Çr4tÃ?þâ} I’H3×>½ üà†?`"€èñûwÊ㸗¨›™‰>Å4< 7[åU„? »T’ÞùìK*˜©0wì4à4à4à4à4à4–¬ÀNíûaÀf›±ª Ÿ04Àj_XÒ£QŒó8{» I Ú´Q£.|5àwÊ£'§ý\qÈ𠈇ÌBè¬B&È €¶AŒ#éÕ€!¥ Ÿ@c¢7Ö_Ñ’VA'\kPP‹ˆp[+³¥¾4ÏuÔ¢KwC°=èBp|§ù³Ñ7a$.Ë J] Ü[ÃÆmÆ…hÁ½Õ1ˆ|,AÇ­¦­~Þ¦Ö‹ì*©Êø3Ý3ÌWx"âC˜ƒ¹x½U®0?2 @š—ŸØ#OMø DÇ% OiV5ŸÈîœÓ€Ó@°€‚¦&„ÚÄ3j¡d÷IÍ}P7&Ç ZC, ¿¬o%»o Þ0ÄëËŠ?ºÆÜ”Æœš}ÎðmF€>-HÌ´s£ûH@KžZ'A“:ÊIô˜ÀZ@£ ,`†¡ ¸¬yšMžä䭪ǖäj¤Ç>ëQ^JnÌdžáflˆêÂØQ‡ê…TÆ (/†0uZïäzüQF¦I•‘„Ð2áV)#ÚjH 'äÀþ´úQ–óYz‚õ Vz÷äÐ0 ZÛg Ô­z¶ï#ãчýÄ€°3obu¼Âä§@ æñ‹à}J@Ái äñÇ—êêêyç‚ç0…“g¾¼.§>;.Ý]ÐK ÷¼ð|㥗å÷¾ý ©ÚT¡óÁ)°q$wAwT0ŠÁÚ_þå_jÓ³Ðþ‹¿ø ).ÆhpÓFáÑÓÓ#ý×­š)**’ï}ï{Âír&Ç#um®†®R—&}ÊÕh‡ã±ðõ) å?¿Ð #øÿß^½¹`®–¿p±Wé21Òztk¡ü”O%Íä‘›o„û½4‡5ŒocÄ÷ôÃeßIe ÐØÓ¿ææÊ¿ûÖWäÑûwèJk{.q˕⻷ÕÈöºJ¹‚•ú”Š ‡v¸ß›Hèí«Á+§¹z:•D×ðu0Â"&¢†zƒ0B#pŸ „¥¤;ˆkÿ«NÃ8UHœD¤ç…ç?°à @Žb„7`ø„¹uÁk32–¸ã§ûy†3h¼Ý&O>¸W¾óìá94þŽsÉ’—øÖÜÑ-­Ý}³x*êLäÅÄqï8ú+Ýü¿ûÙˆtö Êï?ÿ¨<ÏÉÛrpWƒü¯ÿãKÒÑ3™|R‹îÛ6O7ȳìjÉEÏ­gÀÐ6•"¤ÃWØ5 P`ÏsË †ÿ gŽ ,ýʄߦ•¨“ºnÃ5ùíéËú¡D^ {qÆþ*„H–(c>w*(äàE §0i<}‰úxû“ózYGeYÀ “ â±S€ÌcàE ÁèØ8À*cêå‚Ï´ \{—R×@}i¶¾7l‰®¡pJïKŸ {ªrå+ðXrö²Oþâ#{Æmœœœœ6žlÀ˜lH6|‚plÃP üxˆ 0ùÅŠáè$µ¤Xzš4À²=ÈØ°™pgŒeˆèÊcõj °ÁôjÐæJ ¸H-„¨Æ0<‰àÀt`Å!=ç—GéëpGe¦ì­ Ii.tät?dˆš|Y9¸°&,†/«Iz‚|\EÉI$º?‡²±ƒÖЃA&¼êÑ Bš s 5'¬wyîš<óÈ~i¨N¬`ëã–<¶×o’'`ü¦ëö9X!œ¯­,UPéxPÀœ…w"+ýË`PfÒxÞ#ìR@ýˆMÿ1B|™`´.G˜zQ¨ƒA}¡Tƒîÿðí§äfs¼dÂãBVÊcò³*aúG¥wpHšÚºåì•&5ær`K÷ûWàÀˆ*„(`x‚d‰m…'›XveˆÎ…k}zSØ0GCe¹¨y¾w`nø»ää—×°2ýŽ~sßÙ+·¤ ?Göm­•ì$+ÚÉ#?7[Ø»raR cÜ,´#Ù`wµä¢ñûB ŒB—L¯Ôl*Qš±À? $_‰:‚!(º=P¿oJÐW‚.¹?_âu¼gìÝZ­,m²r$:ÔéÄÁ5Å ‚±åæÚÒ£C˜ÐûDsVïàþ†Œ^„C¨(ášK©j 'Ó/ÛʧBj\l•”Þ¶þòü y°>_ßýÝSõØónë4à4à4à4à4°Ñ5`:Lò ÒhÀ¶Ïòh€IÑ( ÓsEcc̻ԤSË0”²&˜]½ê¦¼`}š( 1ÌÎAèx3À˜ŸcMæ-%|uš8Ã1Ìy«³ø”O¿yÐÖÈ&Ç1v#à€¶ü¥·>5í=°%$;6eI>€ø´ÕÆ]ÄÓ: ˆfßÐ…ÝOÜrR›e(<¬¡e^’&Ç#m]eüÁy¦|" JàÑ€a7;‚oÃÈø(¾§cÒ1æ—þpßœøŽLŸÀÒ“ð+ŠךÀ—¢\~擄¤ÞÒ²¤º(CòpLcˬ4Ï5åüÕÛrþÒuéîE8Ü×éÜÒ‡êK䑆yê–ÆrÇêÓ¤Õ mÌbݶìZ  à¾Ò,§5˜â|ÖâŒÑ·%/¶]ëP²x ëy€À å z¢ñµ6f䣪U­‹`S… ÀÐ##(›tOÛ`À ¦=@BOJ)U4Øc—Uâg¨l©M1þd×,Ù Íõ…% +rù‰œ™Ÿ%™B»ñbú’pÖñÓä*@ýƒÃC lHG·ÇîÛ,/(—ÚÈÇÕ¼‹$†®ŒÓ€ÓÀ¢4@@ÁücI=äÔìß&™0Ñ(n^|ØÕiã?-È4ˆk&n|Üü4R¯|ðoJ;§Ec3óX ߥ4h3Ï{·qŸï{¾d5Ÿ50‰Fmì¡|Ü„Í$@z*@Ò9”'­áÏ-eÀù8Ò!Ÿd»zŽêSQX'ë%ñbÊušöã´ãYÏX#¼¡¢ì¦½4ªƒTõfä5^jÐ.°PZÞ'ˆJ7Ò[€*††¨òÁ [.h%ò==3Ÿº`6þâ P("e¢Ú&xÀ>ë3ŒÑŸõÑ“y±ÖIp² D¶—WŒÕë9îh ¼280ÿõÚ*Új¯š ­´,ƒäéÕÌþ¥†Œ‡S7C|@Á™ÓcPðû/½(U•.äÁìž°6sî:¨ ¨ê¿ú«¿Rí1É\P°4÷ÑÉÔ¼QxÆuÅ6åçç'kî’òÔÕ·ºJ]šô)W£÷:‘‘9~ü¸|úé§ÒÜܬ.õh襷ªŠ‘™ &d„«²¹ Ú gÒ¿¢«_’ã ²âBùƒçÈßþë[:X¤+ós—›Ô}ýÛŸl’#pwþ VK—-ÿ3~f‹˜œ(È›òÚÀÁ+ ¸)'\®HïÇÊé¾áQÀ*ÿ!\Ãäq †ùqéKïÀ<38L™Cœà›-òÊIB0D°µvêªÿ8ñ<;¼Ù0tó/Y2XŒl¡Ïƒjx5 +ülמ)ŒWnµÉ{'/ÈŸó Í›öƒúÁ f¢¡Zþý·žÄµÏ›mL= Úü£k}^ƒ«³p£¹]UÕÕôÇO7Î *˜Æ®ƒU’‹à ëmÒpSÀ›¿˜íJÔIàGoÿt9K!gâµ[ŒŒsÑÒKE'@6±-ç®6É}å×6kÞ-C0´…M3uaóÝÖiÀiÀiÀiÀiÀiÀi`-h h€á§—°ªMn-Ѐ ñð ÑÂ'@¹€m±%lÕ}, ¢üþˆê Å)œ´öÃÀà÷D +„Åúàáp‘t)áØnÚ lâdþ|@¨m7MgÊœ,Q_dÄ`MPÝúéq-SªŠ3¥¾Å8¬: _§ò²À†'@;}1òõaÕ²M1†8€þ©w]Îó>˜èN>Ð2&,‚× z#˜`‚¨qÞñXu]…|áu凭^°”ØÁÒR(}#¤ß4þØÔý¤×Ü»!S½æð¶ÑÔÑ#á½ïúÍ„òÃêÿ¹:§íPsl_~b<¹¿N6å#4‰z.ÁJd„.ah ¦VäG‡ð¯ÞÈG8:¯Ÿúóñe®ý MF?Ư–™ý8<@(v¾ø–ƒ7ž}2VX‰üõÏß9!{k«Óû™OW¾"†À}Žç –ã*ƒž5^wI¡+µî4ðá‡ʯýkiiiÑÅ6 5 Œ GHõþí’•Çû݈o/}g˜ãýÈ3Ìû6d¾ž@óòYšÉ”A>Ïãœ1°c'4l(Ì>Ÿ†š¦lSÚ«…Õ¨Ïü@½PBPÒãPp÷>ÅûLëÀšÇY”mQf,ƒºùì% ÒxÆxŽ'X~5)P‚´jFG[i(gqH@¶'°œ)cŒîxÈy WÛ¥•xuZB|ï 5ÉÔ¡w­V sÁ‹u`¼!PCÌ1ÕƒÙ gr²¼†`#ñŸùJ}¶X%Áñ^ Äȧ&É€·Ž ”§iõ¤×Aéì5Bí<¡\ #Êjý̆Øtbè¨ ’Ñ;Ûjˆ9gò«Ì,ÇPpîÌFlÂãzqi]hஃ $xüñÇãÊÊ\âjÖxE ;…GvvöŠëÊñHè8 쮆®aYN¯F;îU“˜=¹qã†üà?Ë—/«—ÆèKLœ‰EáF¿}LþæoþFžûæï'ž^7û!Lü<óÈ>¸]_¼wJWÜG`¨niî~¹|³U^ûð y`w½{pÍW²q\ ˜ z51göþä½|»U>9{.úoË€GLÀõ?î‚pÐÇ-Ã,5qÙ‚p?üõGréÃp ,R[^"ßýÚc²µnÓRY$-O@@CM¹<ô€\ á"¼0 y±íÙ¾™¡ÀÓž˜8ÙW‰ %zM¨¿£w)¨€ô\éÞÑÓ¯:f=é¦Õ’‹}`d ^¢ ±Ò~)i%ê¤qžal¢×ˆD€Í_ê–ž:qýlbøŒË·îÈ ô§TR ˆª1.òûþ$—(¹ä4à4à4à4à4à4à4°n4€ f‘§@møŽõc\Íï³&ÃŒÕ`yx ¶D|ê´_ÒÏ, †XüæÄÄ,¿-ütëO[dU¯™ðd ½ám%€Ù`Y˜Ê|Ň¿ú¡qxLb‹°tCa@ŸWŒŽì•°º¥™’Ÿ“‰•çôN—-y!¿0N}ÐŽ¡QD&¨qЀ¨´D Á4%2^;ÇšÔ1Ûol&(O#†=H,:xYs<Ö–®2`tÏÀ·¤Ú¼<Ã0ü$^¸©ý®9»ÄÕ›mrßúÍmºØ#Ûýò›‡ä«ÔK ܼϦäJxpþ €A.쇹Eñ¾èËšZ“Sí@X ã{Ž€ƒ â1Ü< `Çšè×!Á³‡@‰%§ttµ°oÉb¹ Ö†Nœ8!¿ùÍo¤­­m€‚û¥ú> rst~N_à¸Á§Âà]ÿzOr·¢×™:}žp…¿ЩÂù´žÑݘ“=Z’€†ó!¦R”Å.Ÿ)ô`ÀDÞ4‡[à€Ö…¾ûMÍà¡s)¬ƒ'@aeA9îÛ2F,sdxâ4ä= ÜÓC’°¬Ê‚ò…µ¹°å±VF^”Œg=p‚šÁµ(Kè?5«ŒqIPŒeH‚rZ97œsEm ›4…´<½°’†3F„oP«ô´@€PZ %¥×;»DýQno"3ü¤åaÜ{–‡´Ѐc´ Æÿ>suBÉo2É„{úò¼,©*Ì‚PPr‚!#è€ €¿˜NØÓÆJÐÃ$gÝy j á8“´œ©Ç7PßñÅjÆÆ€‰uêŬø#¯T’)Éþªw<6®®Æa×?0ÁùK×¥óœ¯á7ébÓÁš|yt[ž<¼§\JÐ×§¦æèe`¢ó j€Kd8=û¹W†ÔÓ©¦Åe_w<â’/q' ]-‘£+¾>4ðñÇ Ã´··/Pp€‚’‰°žzã©Qí…1\ï\Ü~|Bòž×cš±í ª…ÝÜ5ñvÕ²ÈÅ>½ãðƒ7+òñ^æy’$ÔaÂ#ðÿð¾#(ÇäM=¥±šLiè¦×c¨g…üCò ölŠq Ï|5uëVŸ_|~(/ÔyíY  œÊç÷Þ½8ˆóØ… ²*׿1)ªž¥îpNOÐÜ兩NUrCÃSÔ@x`êg X%÷¹°ˆ2©Ô”Fw0ùè5Â>gT -ó©dàdíeâ±ñv€KÏà7pˆ6û¬ß$­òð‚¹.æœ ‘À±‹m!äÏÄq”y°Ô‹ oNÎñK œ<>¢ †½Êæ O–½{÷n9zô¨ää$Ù’Q.-ïó3òùÉÒ×݉vZHÇÜu2¼Ø‹/½,P0·ŽÖú™5*XëJrò9 8 8 ,F(нÖ÷¿ÿ}¹téRJƒXÖÏ0 W.ž“ÌÞ°þC äɾŽ ¼ÅòÄÃ{dçæMréV«?uIN7ÞÒé4DsuÿðˆtÂ{AVéÿOß}+R¦V›¬vs)SS[§ü_?zSÎ#\W`30ÉVQR €D…À}?eäªo¦Ñpíj”NLF¤›:áþÿ§ï|ªá¬±º¬(_¾õÔCòÔá}êò3ݺS-ÊÎ’Í›Jã䞎"ÄÃÎÞ$ ¿d%„VˆbÆŠ#ºÛÏÀàB‰º+„û8%&¸Ê‰†é„‘¨*/^¨øœç‰²] ¹hœÏJð¤Ä~cûÊœÂ-pb%êäÇK"òX¯úër'£÷©ëž‡ûãá}ÛäÐî†E³ÊÌ J}e¹T–¯¯çÝ¢ê 8 8 8 8 8 8 ܳ°@*€©L‰@NÀÆb¿m+æéá`Ò °\@òÔ‰^`@'9Y¯XÐy€ˆUôÓ@Žz4"ÔÇ€Œç}ÈÐXÁwüåg¤*?CÊ àe«¸CøóO€: K.Xe A†ý–À~,Ê©H|}ÐÓþt¥\ÄÇè&~Óè¬üÕ2€‰xÑ0œ^³·é±xXòæÀè–!b¬—Óöä¡–°´< oÇãÞÐU ÷Óø(¾ß¿¸/wdpx)o˜Aï‘c{kä…kdsIHrrá¡À닱ð¨DÇ‚F6< dÛ½bà^÷å•À9ÌVìÇ޽Ϻ&‡zðc@ëÐgÀº?T 1ô_5­1 Ë!m8Þ}«Kóg^]r9/<0Â+‹/ß™44ª§>´\ÚÈ  €!(x@ª, €ïk VEñÄ3CÁxWÓ C3 öjFÇ!ßa4󗉿¦§‘åQŸÒšL§¹™Ô¤¤YÛ;9“÷Aùe5Ö{òè»4&Ÿˆ;”äøAy°$ê„|&¼êÄ9µœƒ ï† ó1 ÌF\”C[°¯R(åxÞð—(xjõFV“oƺ¯-1íd-¦]†'ë4l¬ùžð¶Øùi`ׄ¶ÄÀS©Y@åð„Ò6²(éð~‡¸Oú ”£w¶•£ Î×±*3óH´U9ÏkiŠÆ¤Q ="Ö¯» ³ ÌÕ™ªÇè̈Ù.•L•I}@ W´‘ům ÇùÁ˜Çß‘ËÇ%]@ÁóÏ?/ I=00²mb~©fŸýèÓ³râøûÒÛÕ¦z×s6Y<Ç âªX×;¼×\rpppXF ðꫯ. P`Ùs"%ÜqM†¯|(÷Ãf¯Ÿ-ÆH9X½­®Rª7•Èþ›åNG¯||ö2 è±~Xx]ˆûþѲ îóÿìů`œeW«ÝÐÞ!ùÛ¿-goK«FÔU–É·ž~Xön©‘P.8J1é¹Z‡‰+Á/#þbº ‚´ý—ï~&o|tVC°Îb¸MüúуòµÇ*ˆy+èÂ?€‰ÄDôá$Fh®¢Œ6qLLOˆ” ±P¢æ¨CNLZP¯yŽ—’VK.'J°šÞ&ö•61Û©“ár§@: ±04:åaa1òÍGK¯%S×=“Ëu•¥òÌ£ûç+–ôÁH ­aﯤD.ÓiÀiÀiÀiÀiÀiÀi`ƒi h`¿„üt Î Y ¶-Ѐ“Öq¯ÑÂ'xÅø.>I½4ÅÌ4ÐiGñ¨€ÁŒ Ÿ@O„%EyR kiƆˆ+ŸŸ‹ó\¦‡È#œG^oÞ†ÐÉvC¡  ¡Ç€+b0þ©;gh|I,ŸøÝ¨! §+t¢$ýŠÝ£éNŸ\¼|K®7·ÉÈ(Cxn‘›—ŸØ#OÜW+•ÅÙà»Öô]¯¯ 3P‚V6È¢×?ô]Ü7þì©o&5.Z¾ q0‚¦L|gfP0ÜqÓðO“öõ ȃ€© OF sÿί«ó,‰æT@#¯‡3Ì­Íq&=@ÁƒìBÈÞw|ë¡{z†~¯yÒƒ€¹i(6÷*MÈ&ñŒaÃù-æóî•Ñgi°£ÿqÞTŠ1BóYpádžU^9rÐl¼ãüÕ”M §xª8Ä–d¦´1+ØÀ“AïœMô^ Â©!Ÿåqdåg-Rh2à³vØlÜ_–PT&ßk£–¥,¬Éá/ÛÎdæ ¸€@j­ÂI¶T1”Õæãº˜2”Ü$ÒÞÁÄ}ø Á¨± `惿ñi`È`À#A¯¼q¨ápÞ|Û‚ÌuÀ–•*½‘ G8¦fÕŸäø…™Jìɽšd·Þa’͵‹aéíÈè0™-.ÑCµµµ2 0ÝJ% >xïMéîlC°WennP0·nÖÛ÷F]oWÌÉë4à4°¦5ÀxôôRðæ›oªK½t„!æÞHÓ’³õ æW¤SÅÝ/ƒñQà‚Í04Ö`%úÖÚ yôÀvù§WËù«M:à“÷?»(/=$eðp°Úi«`n´tÊ©K7P@ãf%BüÇ?xVön­ƒ{{Lê%Iø1i‘N¢§†×><-¿ÂC 0æåȳGö+!ÑpŸNý‹)CÃ8A‰i.wùô0@õ\‘>„ëÆ4ðAGOJ º7—HØ`…Y^ Ó)H;WZ-¹Œ¬S!!"Û7äMÍ%Üù+Q'"… àºõìš~+¥Ó$‚I"ð>12:&9ˆËë’Ó€Ó€Ó€Ó€Ó€Ó€Ó€Ó@zP %tn:^‰õjÀiez1àä÷j È/j\ d¾ð½Ä u?âÃ3|Â`GP†‹ ¥# î¬ß5ùðNÆ¿àÄ<ˆd< §¦Ï±7uo£6ŠÆUpú?!ÙYü„,ݵôæ ¡Œã1SUüŸšðßø×ƒ¯Þh“ 7¥¹£á(Ã:1K/ dä¡óÈvùêÁgBqƒÒ´bÐ-=fÄtõ=¾wyãØäÝÏö0¾%xÆ[­oXzn.ú Ä#B`Û³Ô4®èù…×ÄǵÊd5í²TÆ®üZÔ@z€‚‡¤jß.ɤkx~iûʼnûÜš©ÑR¼“Ô&¬}HÏšç€z.0KŸ­8oÃð]nz¸wwÓ•¾ÈƮЧÖÔBž¦”¢=%Û[Ål)Ê+/–¥¬0O3‘ƒ>ï½3¹jÞTɶ±,þÐace34>Ȩ€ˆ`Á¼7ŒDZB•Áj °0Uư"_åà9#xç@ ÿÈZ‰yž25ŸígÍF£¶Êxg ¬,f(XÛNošpoÓùŒRa«WŽ4Ø×ÙGm·(ofˆêÓ\%d`Ÿ&<Œ`B¾Ù#G‚ )eBÀ*åÉ|sÄø5Èa…”…|LëXµñ¦ §ôÇPMÏÜko DZ™3ÏÍwœ(Hôd:_™tÎY@AW‡¤£¿õ^&=«Èzoµ“ßi`j §§G¾÷½ï­Séﱉìëë[BƒlñÖÆõ *Hh=W¨W”`¥{žºÿ/ßÿ™töÑõR «þ‡åVkç]Ш~ùÖuÃOqé‘àÐîz¹Wƒî'4aYvûa„~ Þ ~öîIé0†^†V`¸ƒï|õ)-œ2Z/ Ã*‹H B$&5t'¬¦H8‚Á˜ ‹«·[5w+=n4wÊž­µ TÉwØÕéêÂä’sSnNHŠó—×k5䢽$áúŒbåÕÎõº@`C:i%êÌ@.Â$®Mc³¹½W†ÉM!Ì?x"ðn°PÊBȆ밉¡,ºá#в~®ÜqÉiÀiÀiÀiÀiÀiÀiÀi`Ù4`½èÄõŒð œ”ž4À˜;S£eŒnŽ9{¾Ä¤†Ï>åT=Œ¶ÀÂõü¨†8Sà5Æ¢~xCË•‚œLÉÅ÷C>VMH>ÆýœÜÎËò\ ÇÇœ`g[¼öøÚŽÁS êVÞ i¬åJp~GÐPÀ0ö]Í{`ï¸÷êC=М€ºsåï!]…'2°¡UÎ7^—n„,$Ð:[àPC¹<~_<¸«ZŠñ ™¾E##Âø2iˆdŸz&·Ø„9à><0ñ¾dc‚çÃ,¤ðVËûæÀÇðH>\üê~”Ø×9ÉÑ!葞Þ^Ìý !üeŸÜim•–&x¸vUúúž`ii>]ùq=xÑ}ôþâ=/ø1Z^_Wzíiàý÷ß—×_}‘!–Ê}»%SçOÐ3Ð_¦Þ”4°ó®DûO¼ã O±ùj|ž0`a]¥OS5ô?ËÒÀÍ“Ø5ž2u*0Áì[`OI ¦qxjM>O˜¹S÷Y%âöÁ‹e5Ïs½Ï³ ÀV ³]¦.¯Ž¦Ñ°>Щ!Ü3½³, ÁöÑðÏRš,Cùî5Æt"¢ÓO^”SýPn¶ßˆ-õÉ L”Ê*HB‰xÊx]0dÔ‘)NS¾'‰õ)ËH 5^D™ =¦¢‘<d‡cj-±{ ï„z/`Q¤*3Õ`Ù-`€Ú!WýÕ ed`ý3P&„k™?YgOóSM?ëÓõáŽVNT°rºu5; ,»"0Ì9sfÙëu®A àƒ'Üu]rw[ƒÂ¥']Ýo«Ý$ûvÔÉ{Ÿ}©•Lb…s[\ÓÝ…ÆjóÆÆ@NötG¿}såŠ è•á½OÏË¿¼õ‰t÷™h®úÿÊC{ä»ÏèqW9õ  ýwâ\ (¨,/™Ü›%õU¥qPÁÀð¨\¸ÞŒ ÷/hH&ˆâó ×ã¼2SµàÆd]jZ ¹2áæµ<lA@JK{êoßöº´š°ufeehHNØÒk =Dô`ÂæÊí69¸»a^9éyâ"®ç™K·¦ÑéwдpÐWÊàîÖ âD°úàd†¸ä4à4à4à4à4à4à4à4°²˜h@ÎQ®‚Æ@.ÁJ7 4 ±ã¶hŒFz;}¾49'ðMÅ?“àÖ©`DÚ±¤Ïãj߀¾æåå`’, ÿ‹ò²á-$y¯€a5”!™­fV‚söß&ºKÇw£ ðŒ„¾àTØ/µXz„‰€‹4ÓF«!—õÁ ëÃ7_<9è(GW1¬€‡s<9qþ ¾YÛd‹=&¹„5tì¾Íòâá-R¿©@²êƒ]%:OucÆ­¾‘ñ¦€F.lX@>$´ bF@Pd„à üÄ“Bàqì.óˆáþŠá^‹àùƒw‡I|SN@¦Éþ6Dk•Ž#™2† ãcccpË=,##C2ïxƒȸÝüëëí–Ñ¡!xˆˆ€s[¨kô,ÆuZŽ”º®¼g Ÿ!ÖR¸¸:Ö„Þxã ùÉO~"mmm:²P áÓpäaÙ´wdj8PzÙ3h`7IWþc—O5ˆë1öÍÚv¢èq@Q‰5b£6-H¼­ïc鯖+Üq* ¾4ÒÇsÍ_\-?0ÀSH)âEpÄw»zFÐwº2F è(Ç<}Ï1Låb¾åÁæáy¨?Zµ H¦Õ™|=ã XNùê–ÅqÖò÷ÆÛËÒøN@wYyàiØÒôO™ÈÊ£™ ?áâæ~”…Œ F=øU]yùÆ -iÀ äê tÏÐ{Ô j¤¸êy€:AÉi€zíWÏ^Áeg>’ À}…:Ø|“7Õ¢²âØ¾Š -µàPÊåùÙ±cG<äÁJ{(øðƒ·Åy(Xžë¶^kq ‚õzåœÜNNZt…79ºokW= 3`:E…S+«mþêl½‘¡ÇŒîpÄNˆ%—€1êo4·K Ê©&®è?~ê¢üè×'¤³Ç(Záè¡]ò‡_{ Fà¢T«Z6:ùß°Ãz`ÅE˜Ô{žæZy_T#w5ÈÛŸ]q‚àJS«4Þ‚!yë܆d‚7®7µËg®Åå/׊‡ïÛ?ž¹C=w÷`•}&"R» `‡„•ñ‰ô«!W6Œõ ÕRPwàÝ íÝýòáéKÚöù윈iië‘sWoA[¤maZ‰:þ ÀÇ4Þ4€z8qæ²ìÛV§À™DÝÙ}z8ÓxS~ˆð$Ý)¬a©ª(‘û¶×ʹ+MªV¬>yï³ ²«¾ÈS÷¸å±Ö·ôœÒ;8$·ïté÷h5¼rT–'¿7鮳o`Hny´U¸‡«Ð7’¥i´è7•å…èG¦$£wyNNNNNNNéjÀ Xžqk™üX©Ì6ÞÁhP·à“L†G`OŽ`Ý‘G=#¼–ZÚãj¿óB'°6†~c,z¸%H5.§óñ]Àýz4ÈÍ‘ÂÂ5âædd@ 1§QvcHH•%K¬ãOËÄUÒ2 w< #c\‰+ké vki¾3(o¶ÊuxÓcè=vƒtÒËOì‘'÷×ɦâ<ôÕ„>Æ•¿ ðý1~†z¢QkVb¿"= zL % Ì9ï÷.óø¿ÿÛßÊ•+WÐ>Þ?ž¼hëdúäïÈŽ îqÞçMè÷ à1·ñòÓ¸ŒéèjÙ»ªî¾(xå•W4-U,”Pðèax(Ø+xÿØG¿Ù­±Ý„qߢ2šÃã«éaÖ'$²˜ÏxÃâ®ÿ¹z_-Èæ§§Ôè C¹Vdd#¿˜X×ÿzBEÖ×ÁHÌÒÄ} @üY£ä àŸáO9˜À[ËAr•ÁÕrä§ÕÐüçÕy™Lž!Ÿ§X±‚còjA–" 9‘/uÀÄ_SÖ€H-ïQpc^9#Ê™ê@@½ V-ʼØÀLojá>å5¼âÀœ4 ŒÌ¬WéY‚pìyj0õ°µH¨ÜvñùEyáK5SÇðj e 5§hû± 0‹2a;ic8T€! Xw\ØŸÔÆP"Ch~ќ󊢦åIõõõòÌ3ÏHMMz…ZžZg×òéé‹òÉGï;@ÁlÕÜs9ëTÀ—ÄÕ«Wåúõëz“ðfÙ·oß²^¸ÕâÑØØ(·nÝ‚Á$(µµµB%Ë™8ã`ÐñXX«kQWv¥éÂÒ;ЍŽYòáïØŽäF­0VŸ ÉMÐñî¥o\>¸œ!ˆdb½ÙpQ¹”4„UøÿöÖ§0º–É‘ûw`RÈL`ͬ39»aˆ»œèFЭՕ3IW嘆ÑjFmOÈ7å[O=˜´ ÇO_º!ÿ“w±ún SH£@äzîªüŒµ­=æú0îü£vÊýÎQ"Kt|šBUIIXøìüU„qh•£ì‘Ýõ•ðlBÃÇØUÆo8+¯ýö ¡&Êth÷æ~q…ƶ͛dKu¹ÜhéÀ@<&M­ÝòÊkÇåßýî²^(f¦q«ÏB§ÿüúG24 ÿ¨H¡¬LÙcôCû¶Î$×ãI .\k–ïÿôÄä#ÇáÛj+å_|\¶ÔÌæ±rù!ÁO>´W~øúq•shtLŽŸnTcò×»“ž³û=¯Ï§ç®È/Þ?¥q­BDëùâ²ÔTËsG4Øýð®­(•ßî ’HLÚ[Íòÿ /·uZ‚>¾ýÕÃòàÞäý?±üBûý£çµÄÉFÂÑiÏöø‰9v2ðåÌ:øî¸Ø”Ú3mŽª\¶Ó€Ó€Ó€Ó€Ó€ÓÀÕ@"ЀcE›üt¹KÇ+tÓÂ7auΤäÂXäZ½#Ò50†p_œô_z²È©šÆ¥hL‚¦Ò˜Ãyü> |‡Õ£7çÁ›A.¾ArCÉÈ€ Üÿ¤daŸßæ€Ö$_cqϰËl—¤a<²óÕ“¿ý¬—ÊÃØFz&ÿâqõÊe9{öœÊµÖüó^x•@à³À—ÅE,0!*ƒ÷»KAPÐÔÔ”²‡‚úG•MûöPkæEôˆûVß0‘áŽùø3{Ç@IDATNá);Ù˜ç ÍÏÌE>Ÿ/z@Ó4 Û¦_c<Î!)‰W^ Z’Þ;e`Ê¡áoŒäjšGݤÁ>åaý n°7rå«\¦NFNrgbP , 0Ð}ü¨yÚ>ƒ¸çÝ„ „äÍ?rׯb ÁæC>R°ü™*Ï|+Ï*øYŒs j` ÔÊ+dTx•‚§Q«5ÉOñdIšõ™Œ÷ÝS}ie¨/†ñ€¡£àiD‰C*”;òt„çõ¤¶‘ÂLAHC®V¯ 0ð*Š¢ «$ÀòT Yet×8ã'BOàœÑ<©–+Pð(úve%æƒ9¶Y¡t¡ñ¶œ:õ±ôvuÄûÔ|¬n}ñ¥—å÷_zQª*7Íš‹œ¯¬;·ö5°î@ü9uê”üüç?WcüSO=µì ‚ÕâqòäIyíµ×$++Kž}öÙeêx¤v®5]eâÙ`™sçÖÇ`>5-;ªÅh€“*[àjþ;–'-62–pw޼‹³0Ö_n•ŸžîLJ;3³0”ÿôtm<›Æ½áqo`ÏM}‡ÆÄ_¼û&{²äýÏ/ÊãwÁ@]ôS1×i?wù–ü콓҆‰#&®P©ƒ¡³¼dŠ.u®K§¤Î0ÂÛ4÷ËÅk-ò àßzê!¸äüÿÙ{Ó ;®ëLð¼}¯U@(ì 6‚AÜ QE‰)‘”¨¥-Ù-¶g<Ñ!ËîpGxì‰Ñ…ºg"ôÃêV‡Ç²<Ž9¬±Ù#Sí%‘E‰‹Haá (Ô‚Ú«Þ«·Ì÷Ì|õjõê½B-ç¯2óæ½÷ÜûåÍ›™÷|÷GÉÉÌWá‹ñÉgOÈuBÎ_éÁ _çLqñJ·Z(x«Û½—Xš¨OÆ#òÜ©3òü©7ç.Ä=Ë×Ï&˜ß¿eïv‰g/ CaüÛWÏa…ø+ZÖ¬¦?°c“l‡ò¿)•”:ø‡ãJ® êÂÊÿ7a1à(ÏAÑé¹a`_£[ *:i­`¶Àz*’ßud”ÏXÍ“1žåMÇDäýwRbÁº¦:Ic"ò<'Μ—Ÿ<{RÞ¾2Ñ7ÛZêåƒPn'b%æJK„cUÉ©7ÏËi¬€gßd`?ùzÇŒ¤‚¥ªW}2.G¿ø*\ôàõ×}òÏ?x×¹Gn’¸Êñºx ýe@νÓÂÇ›pñŽöùu°´À3¥¡eÒ¬ìM»:¤ òzájƒ¤£Ëè$þôö Ë7l1¤M?ÐÞD?xúùÓòkX‘ Ò›}!Æþ\cÌb ¢Ü¸s‹Zœ ¹‚x\ý–)î9v@I;ðŸë¹¹ a¤u" æô™‹òÊÙwÐ?ýò‘»o‘ãGöÎ(’}àÈTäO½ëhƒñ¥aä•Ðöûb@'IÂ}ÇöÍm™üA×o€ñâ+ç°ÚÆ û‡FañáÜ4Rûö[®Ê‹pçÁq÷×ÎWÛ¦‘ 2 *ç…Siû`%dÛÆÖª º‡Æ'ûMQùÌícZ±ý³ìx„‚'_…¯ÓÎòHi³eц€!`†€!°ÂpliK…äঔÜœuñ€„üt¡…÷üLNÒãy¹ÂåY¼3ŽÀ´ù™Îa¹2˜Ñ`ê[YeŸN4}íéí×÷G¾›Ò…B(ˆw9X1HÁ…B’ èJß9É0”»˜òOÆBKÕAÑë¾ÿ`®žÊDV«” @ÅY(Ѿ‚*1%Ê ÈPö^3JòÀö;XüîJsÆ{ï˜&ÃAë:c•Îääçå$¾I{út•|ŸêÞ•.nïX/wîo—#»6H]¦Gd„`žõãÝ}…J"_$ wü^Æ*¨Ý¶àÞ 0Œï}¸°(°Õú.óâ Nz·Ÿá@Ca¤n øfXF2H4Z Jà9¯Ç ®!ÛM€äA7¸ÏI<²°*¨ŒPp;,€Ë¸+Aàœž’îôFçW…®Š`}z8ŠSžr´ÞŠ£4G^G®b~–I…."Ø?¹eYšŽªkƱ,¤aœ=Ðõì(ŒÖhÚßKÂÓšsÒÀ†ò˜ÿœÕûZ2ö§¨¯YˆÖ AËB^m;#0Ž©Læ§âòï¦/ŽT «z]ËÐvj:þqd2ói³tŸr4à@¬W’ÿxˆSE‹¬óºõÕxm›[šž@˜Góª-äqÛÏìŒ×60ƒ¡F².éÈãÇ8^k—0€2Tº–x$Ìiy$°$äÖMO™Š†Æ;¥9×h¯b]ƒÎªóùbúÒrIJNOVvÎWÆÔóƒ#i˜†2u~æßr:)©xT¡¤¦²±ç`.þ2~TÞ“©¿®¹^>ó¡»tEÊÔò–☦â÷îØ(·Ý¸KžÅjrâÒɲoÿôy(êß–P sÒŠí¢ùú+˜Üº ~öÀoüK°Z0W Iù Èwæâ”ÂøZÉû¿„bú™…˜ˆGÆ ÍA¿8vãN-‹-&û²2€zŽŒ¨¼—AÞHAa‚Ѷ~|´°.iØ„NK/Úà­8âu kGÞwL¶oœ™ÀR†&óÞåï(ÑŸ„¶jl V3^=§.!’ <Ÿ<^2G`Á¢xTzû‡µý”µ˜>ôž[_{i±“ö©¨í- x’n)zqf KQ¯®×VXiøà]7É?À:ÃÈ4Ä‘ŠôüòeX$xSWO±_Ñê-°ß“xÁ@eözôùÒP«2·‘$rÏ-òp¹1ŒëÀz^Áå[?ý<ùüII@ÁÎéA½>Cè;c¨_ ô-ªD§5/ ÙŒÑt@‚ÈÛ—zઢ[åhñã_Ÿ”—1¹—i’d#Nú’`Æð<£âŸÄŽ­ ¡ôÍAb «ŽoÿìEùùóN+­ ï«©D (þþ±¶¯4m+H9½÷¨’žJã¹Ï>w uðŒã=Ã{ej Ï`¦õÒ“¦àüÓÌz)q½þ~¸Gpåëi„€ýÉ„”íuÀ}·lÊ)¦Ç¾»–ÅM]ÙÆ•áf¹ªƒÀŠ#p|óæÍrôèQe.oݺµ:H””²T2:::´´TÀýj® 4塺ܰâGòäóŸÿ¼ôõ!­OèùÛBò­е†*¥wî”ÇÏŸq)LÆÜ`qµ]Ž|õ«_-ûºÍT"Ç…#GŽÌtjÙÅQYzdß6y&Ö¹Š÷L‚_†b‘ciŠm¼CÁ§^Nͬ<'yZa¢ýß>ð.Ù‡Õ×+ð}y&žþ͇î”KP Ÿ¿Ü­*¯ c5u+u Ç¤Öl*ac[³|â¾Ûuuõ|¤º{à èRE%±àY7V^/4Ðð¥JüÝägXmž†òšòÆzÇ¥K&§+ÍÃ}¾ÏÖaù]‡öʽ·ïGíÅÕäSÓ–S Në¼÷˜Ð¢Às'ÞÒëÊÙïtöj¹LÏv–ö‘wo–Ý{LönÛ¤ öÒó¥û$Ðji Ü©qSÏ׺^”G+÷Ý~“N^þ÷Ÿ<÷NŸ¡Rž¿™‚’) |ÿÈ=·Ê £L µ(“*îƒKš%± ä ´oÏ üNuý1ycjÝyÚ³UþäÓï—ïÿâeyd*ãi½d–ØÏ|0±„]KãWÚ984 Ò¥ÆlaV*Þ1çm`]Nà=@ÒËÔ@È%Z ™!°Q´¥4pïGg°jÀ ¬è/~´12ÍÔÀ´Sûmi#󸆘Zކ€!`†€!P `±îÀ¦„ÜÔœ—öTA`äH PÐÁ’W\ ý¿s‚ž&ßá †÷òhˆâ‘¬´æa2fßwSrdkñ]3:2¤ß!½CyûZZºÇäâÕA¹Ú7$} ÖÆªCˆïÇ»­^ñ»3x±ï]p“¥Éí|‹ƒhÍ÷âúú¤ºæŠ³Iø¦¢åÑõŽwÔ¢òo°~¼òc‘®åÜ]®v,ÅÉ}·¥ÂÃUÓ­­ (iÁd8pU«q,õ!öùW_•×andtT•BÅk³€ß¾]Þ}`£¬o«G_r¿°²Ý‡ïº3ðÂL÷;ÓàÂÀ‡v:n\Åú”ºÏ`ßb:šáWå—©Œbý¼F/Ã-Wär¾l®ëá£K Ü×¾ 1wo`½˰AV¥²øñ,ÿò/ÿ²@BÁ²þÀðdBBûBél÷y¿:ÊkgêÇn%P!MŲª±AÏ1 3ñ9Í'IılÄ §l=$Á€¬1œrÈ¥'ïE6´ å"âA÷µ­Î¾Ïs¹ g˜×‘Á³DE±Â5e Ø~¶“bxVKÀ¦nÜKëšÎIMJƒ–¡9¹Ç‰Ó=ÂÓÀm3zÚÊ6°Æ97 ›¸˜`„‚Å gy«ÀÄÛQ5J[‚2ø’wûí·]$“ɪK]*Ç—C‡a)·´ƒ/Y&£¼î±±b?$)d!„>¬wíÚ¥Ö<¼~ÕÐ@skÕ &c~,7nÜ(O=õ”¼ôÒKó'ž!¯ýÞ½{eß¾}3œ]~Qœ´ùÃÞ…i»<óÛ×Õ79ˆì+£î*mÖšŠ»&X0 Yô»à"¦Èܤ™!°ÿz«©YêT|–¨ÄM”¤å„@ê8S IÍ=[7Êü·ÊSÏ¿"?‚‹*`ùNIe& ¢8¬‚‰ÂÌûv(]ÊŽÍëä,¦¬_¢©8Œcå÷ÔЙֿiq¡¦øêÇJº( t…ð®[öÁ"D&ßÏʉ7.‚ Ñ ³Î+oiZîÓåD3ê³׊×a÷Ö Ò‚I6Ï<ýÔô3‡pÍv!ß}ô^¹eÿYù \B¼ söú>%Wíonk‘;Ã7åÑBßóÄe®ÀµÚƒòëá~‚ׂ„‚uõrpgÇ\Ù¤Öõ¢pö­f¬xﱃ¸òý_¾`j“ÖÐiJÛÎëuìà.¬Žß­®¸’jj¨U™ìwï»ó&uÇð/?^ΜïTÅ~©ü&÷€äñž£ûпw甌¾~^I$ñþˆ…§×¹´ öË›nØ*mM ²çf¸»p\„ Ž8“{¬J{&c‘‘ã@ ."vv¬W«7ïÙŽ},“›%Ðw.ï#ïÛn–dóF³œ6XE˜)Ä äßëëqM¯€`ÄkÒ÷‡öl›–œDƒ­›Z”`D7zýö&¸|™˜v\’lÂ=@Kך‘öf1,†€!`†€!°ð;bK_mk}›ê¤–ê" ;óð˜í&¡€©ð Dò£øâ7̶«BäPºÝØøŠá{ Ã9\äiú8<.[’Ù·u,„ô0 ëLãY×}•>ªGåB× tÁŠ™g5M….âÝ4ä2î;8¿;Qõ~XMBÀ÷.¾Ë¡ðÁ C2‘1nè@¦5­d*&©TV –Æ£ ‚æÇ1éo(@á‹Â=ŸK ðDá ƒŠ–¬ŒVe1,ÁñÈÂû2ÏA&´Ê0·î**xLEÒÆABÆ"“Q9VY‰É[ïtbÀ;rÛQÝí‚­\Ûx•r¿/1Wã݃´ á©ÿ–Y³¬:e ðì³ÏÊ~ô#¹téÒ´y™²° ãزáÀM‚ÅM>þ¸7uTçÈî¸P㔎+$ ¸ûÁ€Ã<,šÀsR áS9Ž0a²Ÿi…½&uIÌç¹ ` ŒvÊb=H6p T†3ŠÏ üsöá œvà9¢Êi§%Z²ã´ÎÈ ™ª˜GYN¾¬'¥8n:ã'Ÿ™N9¯åÔ•õc]€ó³†8G…¾­šKzpëÉúRÙÏ:³­Lªe±}Z_oÖש+ΫòŸ`h,â™Ï‘IkDEËÕú±¼VyÉ# ³(F”ÿ>b„³ïs\$8¨¢LUê+èZ–êdâmg]±ëL íð¬PŸêJd€Ü £8ÌDÙ¨ã5?ëåDk¡9¶Ñcú\.>¯d*¶®³¼ Ê£? Ö·éÜŸ ‰mV!+ŽTÀkP__¯¿Z^¥Aeoµ¾¥˜p@3¥ˆÌ¾oXÍŽÍÔ3†ÕTD¦755ÉÃ?,gΜ‘¡¡…­H'¾ÍÍÍòÑ~T]£L/}ùÅp²f;|„7×§ä®Ã7¨‚• ´>Lè C1OÅesCÊë”*dÛZê•\@eÜl+¬ìÚ$ÿùO> óíi]Y²eCólÉ'Ň¡´¾. þóç?‰ ­ VÓ—úìJK*¹÷oß$íP(¿y\…›ƒ.¸qè…5º >ÐÛ  ¦ùú^f©€üOò LbŒKV¿l^ß2©<àJç½ÛÛ募û¸Zp˜–`ñhH6B)_ågJû=²oGÜ `EPÿˆZŠèƒÙõ¸µÈã—«Á×A¡ÚAÒ]±C¥)'Ñ* a(Ì·Â]Ë<…rWï€ú°ìîT“öTàÖcÂŽ˜µ·6J È$t‰1Ç%/Vƒeß´{«|á>Šrû±PÈ/›Ö5ɶM³_C/s-ëåÉ`¯MÆ#rxï6U,÷Ã~?,[\éê—NÔ—çIˆ ¡`,4çÆd\'5½2¦nkR& mD=Þuë>Ù ’Æ¥Îkráj AÙOƒÍè qm6¡ï’Là¶oY/_úÜ'pGÑθì‰f¾@BÇ&Xñh¬Oh ›ƒ¡Q½—®¢Od0ÉKâM*Õq`]#LÓ¦¢¸wè&%¢ÄœÙd4  ƒ{ŽwáÞäg_¥!ÿ´w¦À{uîÕ¿øw‘Ξ>ý lǵÛÖÞ6-9I»`Ùã/þ݇åÒU¤E­X.ÉSïÏ OüÏø \î¤_Ö‚¶ošÓ©eÙ±!`†€!` A ÖÀžÆ¼Â+JGƒ_Z7¤ Hƒ9G)Txç2P†b…5¢Å¤ªLŸLå;ƒ\Àêþ:5€•ÁPüzîŽìlƒË¶¼ŒÂ²âHo7Þ¡zä­nºRË™Î!¹|­ŠD´Í˜iu»Õ‹oUìÂ=¶ê>V hÉ ï£dDôDHßM#©€ÄAR§µ5Ÿ¶}¢´â”+´n ÄâÒy'øÁã¼(gK¬\yTñâ%0îvf¬Òàdœ|ã9ùê[Òs n³p!PÁÂáëåÎ=­r¨%' a(ƒÔÕ®§”Hà”lq¨õ (ŠaÙÊ(ÖpYîóñ<Ë¡’[*û½UýN:*˹ǀq‚iSÒgõYƒ$N9qÍsà „ª§òœ‰X?l‹Ö 4ÊqàÔ½ôAé (Ý#8Ù9f9 sž+ø¼ü$A”G¦¶€Ê´AáÑv ]ñ™È|ÌÉÖ2]I bŸgˆ ÷´nm UüòrXBsßá`¤|øµ„ò±œÀw®:(bî߉•,x ÄÄ —å%f€Äp4µ /~9]IL’Â\ŠB¨hMcÅIîÆáò€rY÷8V·”’ ¨€=ºuCù:9…t3Z[ U€Zš¡ok®Ó_/­c ;d±:< üùbMòÓ„ð+mÇbêEœ“°*°¿m ÐB¦ïy½H¼‚¬A3ñóY&˜©ILâqåwåñÅe•[ïZÖ«´®´D@¥<9ºº…¦÷HlqÚ¾°×¬j—É^ɾJ«[Û[@‚ÙZôOKó°Q˜ì§ÌÒ¤êÍ LdÁ< ¹·r­Xðž%a%¹Ñ± •cc ÐñáŠ1–Å~¸2 ­k(A$ZZ+8°k³Z\Á-£¸p\˜)(µD¤p=ÂoD’YæL k;7ÏŸv&Yg†€!`†ÀBX_–C›’²oCDÚCÒÇ;VIÇñ^ê¾Úè*{w’Xݸ 8îàò@¨¥JO¼ß ®[¼çãåUBa\¬û˜Hg<çOFÉbI”©2àF!•—mÍ9Œï•|¸NF@,À®\„ ½³—ûð>•+×@N•¾¡±ªX5 `œ–ŠëJÒªA'Þ5iyޝÄ!X ä÷Mª ¬lå÷(­å¥P¦‰áÛŽnô]–íaû‰Cé·&qå "_(èJAƒ‹ĉ/Ï^P³ì^zœ÷.”ÉP¬¸Â5BÁ/^<-gÞ¼(ƒ Òç&–Šz(–µ=~ C8¶]67ƒ4•î ÑÌÖwY`­ïå&£ØoËBsi¥@H¿ï}ï“¶6‡ø=çxRÛBw$ÀøÃ ÷«³kW '„eóQ‡PŽÁꌒy0Þr\v­°õž9gä¥ X#xìÒòUÄŒçéthw­hq(ÏY”îóÏQè»ã¹&BFæÅÊpªgYT„; htNÈÕXUT3sä*s©½F^-DKpë™*O3  LFE¹ÛNÏMå;²€3ò²uœ/t¬,h*·nùš˜Ï9;jr§^Ž…µ´ e!–K¥;wyà¤tÊg"F¹m@[ ´r„4^PÓk~GŽWB1/RÒeýN9Î<§wˆ›Í£äÐvqëÉä3Õͦ$Ö9‰§'_Ï31tJå_^—‰gõÁ€W…õf9JÐ=DzëÇy4Öÿ',*à–•N=Õ+ç^î—ñ1œ\` ¡à¾ûîÓ÷Z®Uxæ7¿“çžû¥ jð*)×{»]%ͱf†€!°< K“÷¿ÿý˜tË?þã?Jw÷|þÀ¡8M­“¶cÊÝwß­>â–GK^ *×8SÀ²Âʼn˜…•H2CÀ5aXvN¼üE çOdî6Ðzx¡å—]‘Êð6ž ªÎÊ Y`N®ôŽÁ„$Õ lG«ƒjQ¯™êC TÞ{«ýgJ³Ð¸j–É"N’†’å½ö9÷óñµÐz{é‰}µ1ñʮՖÄ’Ê $¯Ô"m9²-!`†€!`¥ЕÁd:rçŽÍ°BUe8Lú Î|#)ÞKHj’¦ø4…ÿqNŽÇ`>£ÌÂo0%`R|n­F¨€á7ÖÓPž¦þuÈ¿@IÈHN‘±µ1 ‡ÖÁˆÝcÒ$YzFròvç€tCùñê \ŶZD¶+uµ34¤alL‚=:iO·„¡ ¿má*ß·!P ¨õ7XÛŠ€HLwtáläyEY tûEl9á× êÛŠ`é‹À§·'ÊÅ–‡… œî1‚¦§« î`* QÍÃ2ðþɰ–dÀ,Mää…“¯Èkoœ—‘QÇÅš±À?…Û·[v‚ˆß 0†Çÿ÷Ý¥¸?®§ ZßXŽ!‚yµß ÂöÀŠ¥ãBbÎñŠn'¨À: æÙ¨Ìô)¹ x.ÇfZ¦ P¡à¸l¸ñ„ãx–阉Á™Ï(ì«Â]÷!È%Ö9Ï/*õ‘„ª`&åC0UT#Þ±ÀÊqà ÉŽiX,±Ï4ìoPdså;sh`"’xH%·fbZæA:7ÙL ˜´ˆb:D±¢Ne±EM€]Ô…s*ǤHnœ’¸Gu7X/kå©°wbÙ>'0­Ó>g¥:ö)š2‘Oe1!óë /%8ùxZÛ¡Šz¢ê°ƒ,œw¡|'§¤g^bÊsä0#ëï"ð€`»‹?´Nà´™uá|–—[îzV¸‹Ÿ‰­“6H гn»ŠÖ"ܼÄ\ ¨k‚elZÝp‡È†Ž‹Ê ¶ î^yªGÞ~y@Ɔxm<Ø,÷h‘–&(™¹Œ”¡J}Wñ5¾?–LF%;hÖìo ćßw·¼ÿÝwH#¬ˆo9Æ+ºd!f>ZRñîAUÖ¬šVp•¨ŒPðn¸<8,áuè(T0hM€×žC±ÞúJÀYŒ¯|lpU?ã5-·8¯éœxÝÕUòÞØÌ–Áà(‡ÛÆ)O‹ôöL©„0ì ÿ¹BqèäUsÿ.9åiw¥‚ßSÄk¥©Œw²:å»Åh,å:åjùZÿ‰ç4­0¯–«Ù¨öæ1þ¢l>?œö:ez ´.¨S³ ̯b4·g!ääÇ9MƒsJ ¦ÒaƒM§¥§\ZC¤uö¼F*ÃIŒxG&q'›_¼¬“gÕÀiÓ—–ïì³.³$0°Æ”É|lŽYîQ†ÖÑ­“ÊD>ÔUIŠ¥Ó†29àyøx'¡àÂ˃ x²´Ø²þ” h5©Vá™ßœPBAwçe´ÉkÁìÒŒP0;6káŒ÷¥±Újm4 C`I ±€ :$d~à+W®(±` ûLÞ'ÿõ¿?#YL‚щ´lÅGú^ÒŠš0CÀ0 CÀ0 CÀ0 e-+mm‰ÈÍurÃú¸4‡ÒR—íƒý4Z «3· œWó¸:ó¹÷’é?*ž‹ÖàJ&¨IÐäøÃ‚¼•y©éU£àL⫔ˠ¬T,$©d&] fhǶ õrdg›Œt_’‘ḯËË•tDÎöŽIwÿ¨\è®þ‘ª¸N`;éÖ+³Å¥aphT­©«+ÎpŸ»+Ù©æí¢&ûÝΰë)‘ $; :Ö8㧦¡b;ܧ=ÔéÁ!h6=éäå¨Må,UÕT>;}’ …5•×¥c¶ãJéÍ4ÔdkV®Š÷÷X"OP9Ï$(Iwœsj…€ek›QÈf©Tž3™Ø^þgw(Ã}Îñe'C7ftÚÆ:x„ÍÏ”:HS1rJf[=—,e?âéÔÊ«² wï:בï(òõ4 zQpäæG.-בÏ#¦QTÜk9š™í£L=Ï2ði„ÑNûyžøºíd”çˆÄ9g§Ö,X”æ ñ‰B‡}¸Ö}ýé. h¡ì‚†¥%üHÊ%øñ.öÀÃÊ£?(Ö·alvq]`û,ùÊE äi¼ra57 C`9#@?â­­­úãGQ:VSE½ƒò¿=ñš¾tøüXER:±°œdu3 CÀ0 CÀ0 CÀX2’aŸìi*È¡¶‚lm‹IKKLï‡áϤô|L'Èu2Þus@«ù!¸àƒÅÆêá¦À%°ê`ÜS>«©}g287Ò'’Fyyu…à‹ÕA9?ÌöKß«:aŽÉ÷ë,#ŽH Šæø¦b;våýr$‡5ƒ¼ ÷^‘Ñ¡¹ ’ÁÙAŸ¤¡0¸Ò;RU÷ ŽEp(®pDoèëv­À½!æÔªÉ Z3I2‘úDT’P0)ŸŒÃ…\8)þª(o¯Séjëq\?_×™×Ê!DüuÐm8j ÏM…Z/ÈŒèõS a\7×r2ŠfœK¬,7ì–™tN~ñ«ræìE†‹ ˜2·ÇtÈG·IGsLb!(¥ØîëÜw—ý=HK$Ë lݺUîºë.9vì˜lÛ¼QÝŒ(§ÌñʯéÐoxÍ]rTc¡*w—Aû¬ ³#ðƒü@¾ûÝïJgg§Î›ÎžÒ9€5ŠÍGA(8p„Œ‹ªHwÊT¢#™ª’Ѩ¼Võ?Èž’XÚWÑ”©©„Ç‘÷Œä *×yJAyŒ]'Íå“4à)äy†ÊuOMNi<Çh\€]PžϨ:§–ËóØb~˜Jj–”÷òò<ú³£¼F¬# ÑúrוËʪœ×-Ëg¡Îý](€„¨mf:OéÏr&ˆlŸæA™Î£Æ«ÛïHÒxdCF§NÜC2%Rè–ÇÔéìÈÉÀYŽ Þɯ׎ek›PW `>ïzñ@ÉN41h³›–É_·LÜrÔR‚Ö‹×étžÂœ–*…çÃzyídjÇÊãëäñÈHŽàô-Wß |2ëJgž¡àwý’®€P°®µ]Þ{コH±ö F(xð¡¡À¹ðkö¯‘ Ö쥷††Àõ@ ÿoü1 q~À{³Òûc†€!`”‡€~——ÔR†€!`†À E`c}DnêHʾ†1i ŒI}$/1¸9ðG©,C£¨$(Q›IeM²ÓÍW÷òØ ³YÇ£{ƒ LÌÓ´~8®Åk–¿Ìe€V—NsA(ÓS9ÙÖ–›uRˆÕËÒ}ÂÛW¤óÚ°ô ÉÅ«ƒU%Pz6—ÓŸSçoÿàˆtª5 °šÏ!$aÉ Ž¹ št¯¯Kà8¦«ýbˆ ƒ4¢ùv^ ^; x¹5PR<ð"¹…¢òÕ••ZŸ™¯³pµ÷2‘‘E÷ÉÈ ¿{M^;s^F*twÀf}üÝ{åî7K[cäŽÀZc÷1)†¹îó™;V1k-wÖ55È ;·Êá}{å†ÃG¥}󩯯Ç=þ>S˜«³W3•cqË ¾ùÍo–í3>òÈæc÷8„‚ˆS¸Õ]/öªvæ[¹ÊJ`*‰qÔõû:Ó»Ö K°$C40~2­£@f~ÏŠ[¾žÔÒÁñ˜jf¦cà³ÖQGë>#)ÓSØ3››F+à®êgÅ”0 ’‘_Ó!3ÿ« §œÒgyAóN<ÛvñØQØë–â¸ÂÁ™CÀ3kÕÜçÅ©2Ÿ‰¤>wÜ:;ÄW•®Šx¤Qâ‚kÙyP S>ókéN4wUšsÞçc>TÜ4Ž5m7ÛOºÒ3¥’!œ#ÏUC&˜™¡xàExqØ’¤DùEE63ÌJò:Úh$š)Žy½x žhÏL/S=9 pævÎiµ5CiZï¬WÛŠœdP9îEs;éÇJPDd‘ÀD^ÙLÌ}÷X½s%qÌÂÀ(•É-ÿ;i4Ú‰rcÔVö§ÔMÏz©¼ÈVJãfÛ/IîµI“âëïÖ`"Ui9±Z`dz$'Œög¤û­!I/ÜåWj ®ž•Ó¯\Óta0ïoÛ^/ˆüå„©2¢0xl{llˆ–“ÝÒ†€!`\gXå¶·=¡Ï ¯*Ý0SÎóÃKǤëÞ y×î­ò»×}ò瘋±`†€!`×–dH4åäÆuiOe¤¹ ¦ñá^Í~Gš¤¯Gå0©NîîJÜüØFû±BæŒÃXéžhTï>¬àô7l@rLÆSÙQb ×E­°¥$\!D¹ÎžŽ“Uý«YFX…U’X5;X£Ž¶:Kg‹ e Òã¹Ø3(o{GºûGäµ´tg@4˜E¡@0÷ .Ñ †ð:Ñ?0R$\ËlSu)bG¥‰\&$">‰„@4ˆÅ$2‚Ÿf빚“«uU)„k^²Z»€~¢V PG•µ®_(&…úó0¿«˜£©x¡• Ä«•०±k c,-rúl—œ|ã¼ôô H6›U± €S“Þ±^îØß.Gv¬¡–6Ý¡ÜûÜë#ši‘8î$Ð79oÝÜܬî@×ÁíǺú˜´5ÕK]ó:I®Û$©úFIÄc‚i)U*Ve¼Æ\Ç>ôu²Yû®ºq´„‹l™e¯6• X‡ñ±Qé9s²8nUV/oL§ÙÛ¯¬¤™sM/³T’·Ï-S{û1Ó/S{û^¦² ˜©Ð©q^AÜÖ"Ô²\”ZÕ{þòs .æñ±\Ãé×ÎË‹/üJ®õt¡`¹^¤e^¯ëN*ÈÃWÛË/¿¬0ÅãqÉdaÕÄmµÈu×ÊŒNW;˜Œò5¬ «jÞƒ!önˆK÷и¼r~ç 9|h_tÆK?”K͉ æŸ'›žž*#ŒI¬~0RA9èYCÀ0®?¶¥ «I ðÂ+—¥¬ç‡—~V»Ù’ÒgG‘Ê<\lk†€!`,%$ îh‰Ê¡-u²»5&MÙNzÊå,t¹Tôºµ `…úÄc¢Š4_Ÿ…ËaÌ¡¬¢6¦{}PÏè!ã|sªoe/Ñ–‘¢²>éál·m¨—ÃMY¬šÑ /ÙH³¼3œ“³Wúe ‹Þxçš\E‘AT…®‚ PÙJ«¡ O’ðõŒG`Ù .uuu L¸OH‚t‹†&ú›Cì# T¶:{J<(î{qnÍÃþ…º‚— QŸo–©ä dŒŒääÙgåÌùN•ÍqUŽèŽm—-­õ…ëˆâ}c÷‡¢Yö}޾AB ûZ«RiQÀëwÜ…h-#Ëèc$´ø °¤’ úb²±U’ ¤R)u[À~©i¾˜¯‘pfP¢$Í$’¨[ÂSxî+^ÁxUÕ>ï#Ù†Äí»ŽÉò¹…ÙÙ¥F RB뙇Ïþ,†@ùPð}F((4K9 YÞ§¥³CÀ0 UŠÀx./¯^–= 5t4Í2ñ´JÛnÍ2 C`¥!àÇ$_ +Ó¢¡™4 +­5V_CÀ0 C`m"Še{\ÃÅÁæÆ¨4ì—À³=ßã‡Âmb²ÜZƒr: ë(P ²=·;׫ò{h4£äZ48{¥O÷¯tõËUX6èùjY5ÈfsX½ï¹OpVž«U°Lý°F RÙ;á>!‚°nP_B4ç3 ä$ RÂŒ$‚%ŸzÀ¬<ÿ»³êò`æ ¨û­$|üÝ{åî7K[cä‹åкJZ±<òüûÏ<*Cƒp=KXáïwþ4ÁMrC6˜ ¬žøói  Fš7I0Q/!Ü/$ðÇô¥!?Ò/…Áñ ‚KéIÛ_“|ûÛß–…¸¬.f(ä2’Bµ`@ª çå¸É¨«˜?$±pH¯Gs×#Rmõur3Lîçáˆ{l4-c°*šÍäX2¸Ò‚ÁPZ.\.¸7È‚Ð_ƒÕ×\†eMøk.uŸÀùÕ0,Z%a~>× á@A]%¤Qi@WˆFÆ%bKØŸ“ /§ï•>ºÈ`¡òî Q(’Ñß·î*oZ#ÈÂ--ÎÓ-‚çfýÕWp)øÜ¾Æ¶èF!Ë‚Œñ|XΜë™à¢œ§SF+$$caùðí»äÞC[¤>ßÀeÉÙý±¨û|×Á[&Æ’0®%Ƙ¹Æ’BîS´/ )Ç+Ü ¯òÃ×o¼ò©ëô7Ö„†B}D÷ìÏrB §§GhaÚ‚!`Ô#ÔßµVúu'ðE÷Î;ï,âNJÕ«EF4­9V&£üÞgXVµ¯ÊGµº)ifð<üD~÷D·ìnK¨éMšÆ¦k„©ìòêJ¶Ò CÀ0æC €É]Ì_ƒP€•¬H³UXóAfç CÀ0 eƒ@ ßT7À*Ü᎔lƒ«ƒ¦(¼£ÈaÕùxŠØÆb]ÕßýÄQqO`\2ÃŽ/ˆ—‚BZ<œÆJb5”¨Ì¨¤‡R ]š«O4@Ù覂Ÿñ‰P’ÇdT„U.©bÉzG¹Þ@l%÷e4“•q FF†d´÷ª\ê’³×2ÒöËÅžQéê®Ñ —“~Ò0wîRJ4 Y{ºQˆÑuÈ l±,d%Át}J"±„Äá>!‚OŸG˜è,NÛhf€rTY;aé°”H0)Kĺo…Â? ÊÉsçåäkg¥çZ?ÈÙŠ,Þ±^îÜß.GvmÆdTòvØ}>ÿ˜èÞ›“ú§†€!°Ê0BÁ*¿Àסy×TÀ6/…bÎd”ß» +ê|ÊOiýª|¬®WJšg¼Ô—‘~ø5|åÒ0X~¡Þ*Ší]»䨶ò-ÉôÃòÁûéŲ›²šdÜ»·InÚ<Å!çHœï“ÿûÙ+s¤˜|ª>”ã;LÆdXf<2¬¬_ÍØ1¦D.÷{P§ú±À†F1w‹_ÉÜÿ”¦Ø¡!`†€!`,#ZSa9¸)!ñm°¾>"MxàÛŠŠþ*Bà¦7ED¦!W(éò€fÉ ™Q†°ö!X-ˆ:+æi¾Þd,?¬¸¦I\;_$tº«@Ø’ÊÉ¡u¡õÀ‘›7JºÑ .õB?.W®ÈÕÁQu£P ÷ $¦ŒÃBƸ¸V ´°j04&=}P À¢¬Ê†@€I’`ˆK8’ƺ”ԧ∠(É5…~8˜‡ tGè¯ ã£¦ðÕ•‚Ó¯s…ˆ €Pð‰3òÚ¹wd."8ïPIxôÖv9¾§QÖ'2ñÃúWç#Øýacɤ1qt½"±cf1]z¨E—ÙˆÚì!`K‚@ª®Q††úá¹j~%ÿb*ô«çNÈ3¿ü©\뾺@BÁ‡P°à×@^#¬‹lM4 CÀ0 CÀ0 CÀ0 CÀ¨ õ± ÜØžCIÙØ‘ÆDXbY(û‡a–ŠáÜø"´fX!î¦&*â4‚.@І‹ƒµ¯Pˆ…¢úÓx]ší(Ç 9(VÓƒm!g2V"VQIƒ”Žëˆ¨Ç5%eÛ†9²³U‰c™ºPVzÇäíÎéîí“óýÒ=˜‘¾±qX5¨PC¯'þÐuBÑ}êÄ@÷ ^%¿hÆ‚Z4H%bØÂUBLš’’„ ‚p>7]>µÆN†ØÍÕëÁ™ó=òúÙ‹rþR§ŒVH( Å‡ß¾KÞÓÆ4(³¸Ÿìþ°±„uÚ˜ˆqʺB>R•vwMB¨,†ÀõEàÖ[o<ÎåÌ«/KÏÍZ ~þ³IÏÕ+ &´o0 µº.«¥\{¢®–+ií0 CÀ0 CÀ0 CÀ0 CÀX¨Öïh†U önHJ+,ŠÑýV˜>äòY‰‡5þ õÇRnvþ” J¢E˜³‚œ&æ‹ëjgKÏ%ß&H­.¬bPØóW¶åò²¿£EFúd¸¯ V Ò’õGåòXHÎv Kwÿ¨\è”®þá*»Opk‘†òœ ‚X[€"7€m(Ñ W>¡õ‚d" ’Á Ä@8èº6(oÂ:Ao߀d³ÙŠ,ìjo’{wÈm{6JÝX'˜ #ZÎj»æŠ²Ýç¥]ÞÙWrÀÂÆD]ýKK0Þ¸[H§o1†€!`,$<öØcòÿç_åM%CÕF²G(èî¼l„‚Ú@¼æKü†ºæá0 CÀ0 CÀ0 CÀ0 CÀ0 ™ˆÁ,ü¾õ19¼µ¤‚ˆ4Ç%ÅZØñeášÀwÍm‡EŽ›ƒ ö¹t¡ƒr5CëYù‘¼®¸ŠÖ7>º7@ðÁWÞ3äi ¥.üáúàÁ6k « ®y*–d0%-Iô%*Mѯvúcr$“—4”þÃp™0–‘K}i9wm\ÆÐÅÞxçš\î¬2ÑÀQòjçÄŸÁ¡Qu‰¡&@K\(ø%É¢>ipeJ5^®ù·‡·4ÉGŽï•65K,’‚÷JÎîKæýwÉ<6ߦÙ@IDATñ…"B]W1°æbÜ‚ùï9KaµAÀ#ìÚµ „<ç}°’ŒPP T­Ì©©`*"vl†€!`†€!`†€!`†€!`” °¾.,7mNÊ ÙP‘X%ˆ‚`€Âdú~(üa½^àª@|uW@¥¯®HóV!Ó²ÒË8LÌÓ$w×47}ÃKBàq! —cŽIo“áLeVèèW1ô«º\aÜ/yõ9à—í q9²§Yòˆ f„..ö ÊÙ+}º¥gH®Ââ@ßÐXUÈê:Õ—ýÃE…G¯“Ûw5Éæuކ´,IŠÁîÇJ‰%óŒ».•î=p—»í†€!°TÜ|óÍòÙÏ~V–‚PðÔÏ,f¡`©®ìÚ•c¤‚µ{í­å†€!`†€!`kYò,˜E€?’O}ú1yä#Ɔ†Éïµ³ä±hCÀC`ú¨êY¦[>hN:%¯½öšÞˆÛ¶m“ÇWµ¶K%ãĉòÆoèÃmûöírðàÁª¶ƒàÓ§O›Œ2P5¬ÊÉMbXÕ«Ññ¼|ÿdšüÀ¦y…dp?;šs¯ÀúL žíÓüófDš,G†W_ؽúyqómײŒÞálÙׂ8ŽcBg!×#à÷‰É˜¯:ç «ùÇIÃjíbõÿ½Ô)ÏŸ¸¢]Á‡ÜpfB-†€!`k–„_nÙ•£;›¥­!&ñHPiX €‚ ø¢I× ?’V‹û ¬õ‡aªÀUx`‰ 0 ´`€É[_”. `ÁŠQÇt‡P’ºV y~2Ô-¢M†aUÅ~åG¿ÍÀéWQç}¯nçzÙ¿©AI9X5È¢BUÓ¹Ë=òúÛ]r¥oDÞº:$ýKC4Øß±N>xk‡lIBo »?8.ØXâ°Ê3# î‚w1Vƒê¥cíå‹°ZX¬[·nZ-†‡‡%›õHw§ÛÚÚf$„Ãa%L%'Äb1Y¿~ýŒ¦æMÆdRa5TPÍ~U__? 3ѳ¿÷Û“oÉoŸZ†@°1BÁâñ´æG`Å‘ hRëÅ_”Ç\•ñ÷Ýw_ÕIK%ã¹çž“'žxBÈ»ÿþû«N*Èd2b2æ¿ ˜Â°*'ê|œŠÕ| þ¿/vKS"(_xpÛ¼‚F`ÂpèJ\~ˆ”Y¬0x½sTóÏ› Ê•á•5Šº}ÿT|ïD¯5ïv-ËøÖo»ä7gù"W^؉OŸ»gSy‰‘ªwx¤…^“Qb†•õ«2º‰¬õ{ð©S—äìko)T¬âˆ&KÌÊ– ¥1 CÀ0V $Yîj‹a…tìß”ú¸î ‚ê+žMÌöK!’‚’ °ReU$)> 4x.pPÈŽIaøQ×7È÷H"Á@}~;9PÄÄʵ‚É0¬–°_…àN KMë»õŒìIŽßB¢A»äãMr¾wL^¿Ø+—{‡áF¡_®\¬ªEƒ;ön’¿A:ZQ'Ü&Å`÷‡% wóÃ=JæòGR›2àb—²CÀ0V $¼øÜÓ2uÛ&9rãiªKÁ*í ÷’—ßî a÷‡v‡9ïo¬v±š£Ky]˶†€!`¬4ŒP°Ò®Øê©ïŠ#Ð÷È6¸ƒLFy¨VåáÄT†ÕòªüÚXJCÀ0 C`N÷]ë– ¯Ÿ„yÉ4\Ôà{· ¤‚Ö‰D¶g†€!`¬b¶ÔûåXGXnÚ˜ææ‰an&…]a|Ìß¼ãÒ +úqçŠWÇ„6-p:ÍÑT©õ‚~ü¸=zTE‡B47WݰT2î¾ûn¹ãŽ;´òôÓRí@²‚É(Uê<œ˜Ê°Z^X•_Ki†€!`8\–ïýâ„<ñýgd¨®m°r2–¨“ ÛvÏèsÒp3 CÀ0V ¡€O¶·Då¶urhs¤">‰¡ØÇ|Ca<+ù¡^laÓ`S{‘TàO4MÀàŸ°ÏžOŠŒJ„=º5ð'0O…¼¾P ÊrÇw½*¶\3îø¶7†ÚŸVz¿ F@˜AH„bjãú‚쇋Fð `™5/ãƒ]’€ƒ‚ÄRM…oéÜŠp?`¢8$Øý!6–TiÜ­›aÜÍ‚Ü5É\Œv[ûc†ÀŠCà¥Sæò`Å]´UVá‘ ¨LuüÇU‚ÃØØ˜D£ÎËf%ù½<¬µ K!ƒXT¹p0s¡3ùœa5¹Ž «¹Ð™|n)°âäUw§œ=õÂdá³] ùåK#¯Ïrvzô8&ÎtaÅAùãÿZ–ñÊ•y§·|×<ýçBò¥ÎSÓŸ%f4“—7p-LÆ,•DVÖ¯JºÃ¬»ké‡Ë­®Þ!9s±K®ööÃDm¾˜à'eÓÎý’lhž';a†€!`¬d걎ãÀ†ˆÜ¶«Y¶´&%H.¦hB鮀«Z•gPâ³ „H0)Ÿg’ù°:¶¸Bä‚éÁd(Ɔ•Ó5VY¿G.'z}.˃ ÔG`­ ó¹³µY³Ùýa÷GÆÝ‰ni{†€!`¬HH(xá7OËðàê_2VÎÒ $ŸúôcòÈG> Eã-³$·hC ,J^óæNïÃÇP*•ª˜TÀ ËølݸqãÜ‚ì¬!`†À‚(`2fxðšŒó…bþÀ©³|ÛY‰3jç%—/H¿rÃZ–‘ #Çee†«ë­7v=LFyàò*V†Õ|¬µ{0 …Ç8L:ç1Nñý>QåÊî¥~ÝXe.,šW;o†€!`\o¸øyS}PŽnôË­~imH`¥t\‚aL…©‰õq|ìàyÈç_¬’¸ »†Î]=Ͷ¨õWî "½«õ!o!›˜ÛÆä-29M‡E‚‚çÁd(&†»ÔÚìWA»?œqm,©ñ¸‹±—3Y:¶{Öbì;§ØÿlÇ0V&O>ý¼<÷«Ÿ¡`e^¾UUë‘ ZZZäêÕ«ÃʨW^yÅH¡g™ CÀ˜Õ_ãOn>â`ù­æÁd”1Ö3AÁW^ÚJS™Œò‘3¬ «ò(?årëW$Ä’uÒÚ¾MÖmì0ü=ûF((ÿŠZJCÀ0 åŒ@<ì—½ëãrÛözÙÕ“dÄ/0Làç<ëÙŒäû;¡ô_$.L·ƒ@¥w nýDóJVTçaƽ0îXo Ô¯žŸ$ø "ñz'*®RA>3"ºR0†•õ+»?l,‘¥9VÓjŒŸß8umJs\Ѹ„¯‰Þö CÀXüäéçä?ý¡ ô¡¾ó/d3 +â²®ØJ–M*àä#­ œ>}º¢Æf¡]úå/)÷Þ{oEù-“!`†ÀÌ„C9¼»Cî¹uÏÌ ,ÖX…t ŽËS¯_[…-³&5Bsh>(RÂa¸ßŠ'$žLÂ4md‚ Z,¨‘T+v•"Ào»tÚqŸQIü)‡ÐËþ­DŒå©L&#ü…ÃaýUXŒe#SçüÒc"p Yq ;ɹ\J*Û˜r]ÁT Ï§CaZ/=syÿ\ÁKëmKdкÙ8˜t´†s=B[\äfèŽl«“öõ-‹†$4[{XG’²¹¢UݔԹDù7©L§+`[ÚÆ &¥7†•ƒƒõ«I·‡ÞCvÚXâõŠªÞ|¹?Ž?ó<Ö¼*ØÖ0 åˆ-P0ÐÏ9Ð’÷ÕY*ë >k.fÁÇ¢@Ù³8$lß¾½b‰´Tðâ‹/Ê›o¾);v쨸Ëh†€!0&æ÷mÛ Ÿ¹ÿØävd¬bèbâÌ”ø¬]Åmµ¦ÕD€Äg¥Y&¨&®k©,º´{üñÇåÉŸ¶4©]¹&… ˆ 0ÏïÇêy_$ᔨŠs÷݉éõa€bFú$?ÌUO("V‡VÍ“4H6)‰@ ˜â©Ç ’ÊÅG‚«@/äÆa†@òcªèfzÉ ñf‘æFg_WÜ; àJd$} ÀÔÿR„m8´))Gw6IGsLâhzÈ‚õH¥íš«ˆøBQ 4mFâbèaà*¶ià`à aî{+ÄŠJ+/ÀµÑAÀsÛp…àOœ÷GAè€k“1AÌ0¬¬_ÙýacIíÇÄ-²'= HºõΉ·¿†€!`¬H(x¡`\«µVŲI´T°uëViii‘îîîŠp¢µ‚—^zI¾õ­oÉÇ>ö±ŠÊ°L†€!`†€!`†€!`KÀ©S§äÉ'Ÿ”ÎÎΊ…ÇãqÙ´i“4`å„CÀ¨]}OÓýPàë*y·Õ¨—¬Ì,-¾à¦ç*zæ÷B‰Þ‹ÒmE2Xní”6ð6¥|rÛú‚hõKK+ÜùÔ'…ñ³†¹ÚáY˜”õW“ìÀVÉ%íQ"Á¤Äίóèv*¶3¤'F&VÚ;¬_M¹Iìþ°±d±ãîL…’2§ô8;4 C`¹!pêÔË2xíªŒŽ £jó_ŽËƒÇÌåÁr»«´>e“ Ø~úT5J°&@°F†€!`†€!`¬ º/¿on×}×<-vŸ5BÁ<8Ùéê!° RA(’÷¾÷½‹"°ê½½½òÕ¯~U] ÜxãòØci‹b±˜|ùË_VkÕk¢‰ «AFWW—üñÿ±BÓÜܬn$¸­f0å£iXVtåR­{æ¿òÉ]Ò7’•?ýæó‚›ËŽË[oTf5Æúî¼ð,V§OŸÖñœBwíÚ%ögVõÕ›&£xIçÝ1¬æ…¨˜À°*B1ïŽa5/DÅ««Ç\øcøà?(ýèG%‘pýš[»¸¥–A«stg—É,ÎWúÎ;…? †€!P9þXÌê'QV.ÑÒ€»Ò¹•üÜ"ŒÂ¼¦ø›Õ=‚/_]›øSëþ˜Ç LŸ§ù~¼^üIÌ1à|E2¢IÈ…‹¸ÐXl ƒõ6l ÉÍ;𥽹^"!Ÿ„|õh6ˆMÕhG?ÜÀ]ƒ/“@ª6ÉC¨d²[„’Uä¹Þw[¶-Pß&>´A^àšlÁ>®Ó»øª ‰¡k&ð²~e÷GqœæøacImÇÝü æÊ𜠠?ž}“}aº±á“Å‚!`Ë… î—FXT£eË¿yVÃŽÀ‚H\M  }ûö 'ü* ô+H“™õW%Ÿþô§‹æ3i ““UÕž<–»’epEgj”8-f…Ðl›ŒÙ™oXMÇd¶Ãj6d&âýø¶iN8Cr÷Ðü~HsÙ¬ ¥abÓ ¾¼5ØõðP›»XÇö¦¦¦šŒí&cþkí¥0¬<$æßVócä¥0¬<$æß®¬¨|÷ÞÛàû¼Ä¯úü(”—b©e”W«¹Sµ¶¶Êž={„Ï; †€!°¨´žÉæ?ÇÏÍ•ÛT¾kÀdž*Ç750C7 ¥VH*‘¡ß$‹SÚD‚>ÙÕ«Ûëä†õq©$ ÀºIi¹ÓÛ¡„ˆXÊiG‰b_ü3`å EA؈ô$foz û aÌH$Ðô<©iÜ:)¶ÓsøI:Ç<&ÃȰšÖQ¬_Ù=XTv¯°û£èÆ…½ºô]w–vh¹×=á’<³»•ÉðÜÑàùÆzéPíŽ×Óî@‹0 C`e"0a¡À+ó ®ÜZÏü¥4G{¨”ä‘GE*`ñž¢ÿk_ûÚÒì”!`«NŒ%cQ“<>t†°ªÇ*³Á|‡9“~LP¥±2óY2CÀ0 CÀ0æG€ßk$×U38p@Ô‘’[·¦dsSLb!¸7Á l5*±¦“ f…‡JþYȳæYhúÙˆ³ À “1:“ÏV“ñ˜ëȰš Éç «ÉxØ‘!`†À²CÀËî’¬© -˜Tä–[nNóill\t™S  [º[` µ…•*ƒ+z¼vÐE}=ÌþU9˜Œò5¬ «ÅÞƒAŒGmÍ)º8&ãã9yýÂUÙÖÁÕ2óNòôiÂVÞ´6º«ræÏª«m,)($YŠûœÏ?ïz¸—J•-Ëk…è3Öd”‡–]òpb*Ãʰ²ñjö>pÿý÷Ë‘#G4]%ñ{¤Ú¡–2†††äÉ'Ÿ”Ÿþô§U«v[[›>|X6n,ï]§j‚­ C`"’¾rY˜îÃmAƒH0 ~2Vßׯ‡Å¬ÎT…¶CX. Ó“"šÞG Ìë¸îY¨Lc>„ŠddFD²å»H ‚dÝÑ•ÛwÔÉö„4'ðJàŸÑƒVÊþ†€!`,9¹¾+"ãcx`ðŒ«˜`Dë V6<‹8pãšÜêHÏÌ[ÑŠŒ>o×O·=pÍ£ÖHƒË†žê²€Ï*Èð7A†çކrx4žI V ,†€!°Â0BÁ ¿€« ú &°Íœ@üýßÿ}ùË¿üKÉÂ÷bWÁœ;wN¾þõ¯C±6.wß}wUW¯H°wïÞb5IŒ¨vX $Ôº&£üžaXV‹K"á Ù³EÞ¼Ø%ÃcùÞ3'äß—A*à˜™’ž«z¢ZNGÙÄúnÙPÉR`EÛµÛMFù×ܰ2¬;¶Ï„ õ«™P™9nµ`µnÝ:!™€j~+T;ÔBß1Þ|óMùÖ·¾%Ï<óŒ^Àö“˜~ôèQ©Å=V:Z†ÀŠB y˜lZ t[Ä´î] kü޲gr{pi Y(…H éÀ T긊/J·ÉÈ¡*ó[8IE²$’ ¶¶Ä$ J8«e›%˜TS;0 CÀ¨%¹ŒûüÀ|º÷¼¡<Ùf H¯Ï($œ?^WkrëþàdóæÍU)›…,Åä•É(ÿrV†Uù”Ÿr¥õ«x4,÷ÞºGþé'/ÈX:#?üõ«róÝó6x<“–‹gNK.Ÿ‘p( {·¶Ë– ŽâbÞÌn‚•†Õlí²v̆ÌôxÃj:&³ÅV³!3=Þ°šŽÉl1†ÕlÈL_ X‘HPëvT[F¿Z&øÎw¾#.\LÈ¥ÇÓ/UÙ1{öì‘ãÇKKKKÙy,¡!`̇ˆ¼G]>Á|©5añž.7ÓBeÌ^ % õ9º-%‡áæ 5–hØ/´V`Á0 C`# Ï<t¸.óùáå)·Y^úZÊ(·.–®,¾üå/‰Óüîá·ÉÔ@+«3¹S›ë;f¶¬&c*ºàî̲Ø×°ZÞXõõçöŒP°PÄ,}­¨ˆTÀÊЄç§>õ)9qℼõÖ[U©'­úúúäé§Ÿ–Ó§OËûßÿ~y衇jbæ¿*¶B CÀX¡`@íÞ,wÞ-?{ñ5¹ÒÓ/ÿûÿõ=iÜ~“Ô7·ÍXrflTοö²ôv^ÔyÁºxT>ûà„  †€!`†€!`,t:-/¼ð‚|ûÛßÖo°‘‘ÉåJV1/´À)ééJèî»ï–C‡'§$±CCÀX ¾pB|u´P]]Ò0ï\ÀŠR˜y†õ .±’ÔGóω& Ðô4&ý}®éjŠÍ"=ò0ø£IñEáÖ *’‰Aî0J‚7ÄB~ÙÕì—cý²»9 õ A‰xÙÖ0 eŽ€?RhÑ­] 8!7Ø¥ xÀ3F´B ]1¸ä¡[Ìóëó†Vt éa¸ÖDYYññlJ ?ˆ4x^ÕÁ­BµdŒöëóÑ‚•Êà3n&l&h}ìÏâ¸víÚ⠰܆€!P6F((*K¸TL*`ÝhróóŸÿ¼|á _¨šiL–ËU1—/_–ú§’§žzJ>üá˽÷Þ+4‡jÁ0 Õ„@s}B>÷‰÷È«o_‘N Þ¹Ú%]¿”æ¶inß,ÉT£~¥G‡¥¯çŠt]xK†ûÁôÍI2‘OÜw«Üv`Ûj‚ÄÚb†€!`K€-Å:uJh™à·¿ý­~Ï1®š!‰È{Þó¹çž{„û C :øèò€? %+ij:3†ßÈ)@©£gU¡‚{P}^3SIø°.Œ‘L RîBÉS (‡è›¤‚–dPnÞ’’[·ÖÉúà°DÓ½°J•€ÄÅŒ8Û_CÀ0V¾H¼¤š%ÏÌ(ž7£z®­/>Y|a¾óyï}é 9¸îI¨ëž¬r¯¢ ’0iC> xæ| Â!`+#¬Ä«¶ºëì}…VÔJºAØ·oŸ|îsŸš¼©ö$WÉœ={V¾þõ¯ëd׃>¨RF.¨èrY&CÀX†`aàÆíò¥ÿéÃò¿þŸÿ*—»û$3:"çÏH÷¥sX郠?ƒ`2,›“ñ,&ûÁö¦ë„Gî¹Yþè¡ãp°¨¡|¢bU2 CÀ0 Z!Ào6Z…ûÞ÷¾§dZŠc\µ\xõæ·"]<ðÀBk C šL(i¦— ßÔTÔx¦¤‹ fËCHÏÀ<Å0[z&˜YF(à“]­q9¾«^ö·'¥1’,ø†F$?î–=IFQ˜í†€!`,[fyèsÆ}~xÊ{mÃ,éyNŸOÌÃçˆ&vÿÌ’§"ÞsÍ•1KÑ¥Òmß0 刀 –ãU±:-Z …䮻ù›¿ù›ªOFqrkppP†††äk_ûš<ñÄjµà¾ûî³É)뿆€!°*ˆ€püÐ.ùoÿñò_ÿégòóß¾³ÃYýMm Ëz6¶6ÉÿðÐ]òлn’º$ÍËY0 CÀ0 C`nFGGåå—_–þð‡ròäIéïï¯ ™À«Å±cÇäᇖ͛7ÏècÕKg[CÀX8\ZÈp%&\•À„´Ÿf¦]7þ8,ÑÍš”vVŠ˜.=$…ñ1ƒ’? agå©y°dÀà áÛÂõ‰\‰ŒÝõYÙ²» ¡@NÂñœøuµ*ôF³ÈP¡öÇ0 C`Y#îÉa Vûûãp«÷: ~º€Û\íà¯îçGáâ ˜Ó÷…áV®qpyjV+Ë8Že$CÙ¸â¡[„jÈÐ]ÉAÈpŸoXå1n^ûc+#¬ µ«¹hR1‹ÅbòÁ~P²Ù¬üíßþmÕ‰”QJ.øÆ7¾!ßýîwåŽ;î÷½ï}²cÇ&±`†ÀŠE Ê¡6Ë—ÿøyùõ ò£ç^•^}[®öÂ%LVš“²{s«?¼KÞ{Ë ÒÖ\'±È„/»Ûp«¸!`†€!`ÔÞÞ^ùõ¯-?ûÙÏä7ÞP²6¿Ûªm™ ´G•O}êS²{÷n ÌÜl)6¶oTB. Fú¡ˆÉ‚ …N˜Êø¥¦¢'êNó¨öÄU¡`eh!=*yú™†{‚ ©€Dþ\Bw+‘ÌŽ‰Š¡LY‡Qלµ’fA9 CÀ0–7…1Òèæd5?Ÿ9.©À­›¨xéóc.x@(ÀŸîwøŒÂãÈG£èª`lÄ·tMeàÉæÈ¶¿†€!`,sH(øäï}VþÈýÒØÐPúоÌknÕ[ T…T@ ’ɤÐ='hQ —¾“_ÃÃÃúûö·¿-?ùÉOdïÞ½BË·Ür‹D£®Àȶ" CÀ¨%˜ nmJÉÝ =°]Æ`Š8±4÷A˜ a|FBJ&(ù^«e•¬lCÀ0 CÀX4pîÜ9ùùÏ.¿ùÍoäòåËBKŒ¯eðáå¶ÛnSB¿Ñ‚EŸïµ”jek®À¤r¤èæ ƒY?h¿<59%Š•ÙÒ/…Œ’jÛ®!`†À2E€Ïƒ¢Û‚2ŸÅ<%éÙ¼Ÿ9, d,Sx­Z†€!`”"àù—„‚Gº_šŒPP í/ªF*`{R©”|èC’x<.ý×-cc4­W»À‰1þ~õ«_Éï~÷;iii‘;ï¼Sî¾ûnÙ¶m[Å‚ó`Hž:uJ^{í5¡/P–uøðáŠË›)#eœ8qBW q²mûöírðàÁ™’VçùKåŠ$“17Œ†ÕÜø”ž5¬Jј{¿R¬BÁ€Ô'ñ“ùIR•ʘ»æ“ÏšŒÉxÌuD¬^zé%yûí·•ä¶k×.¹á†æÊ²às###úŒ2óCgXÍ‘—°ò˜kXÍ‘—b5aõÜsÏIWW—4à£~ß¾}ÒÞÞî5³*[–}úôéEË Kº^xAÉüt:-üö¨uà÷Ýâ}ò“ŸTKrF(¨5âVþZF€«=}±èxrŽÉiX`  iÉŒ9[Äùir&¦}4ÿ ~˜®Æ$‡k¦ÚAÐqs€¨4_­fª±„t)d85°¿†€!`Ë_4å<h} Ö ¼§ËXÌaP ®ºä)ÐBˆþ0Üó¸DZ"(Œãyƒ÷RZÖñEá†Ï%žW¾XºåñUCF– Û¤ ºgÀ3åbkÁ0 匀C(xÌËù"YÝ`¯Ê î½÷^inn–¯|å+:1VeÓŠãŠúå¤WáÐ5]"pR‹+eH6XH •…_|QüqUÆÓ BµI”ÁÉÉ'žxBO÷ßÕI™LÆd”yá «2B2Ãʰ²ñjö>Àûã™gž‘ÿøÇªxúÈG>RuRÁÐÐɘýL:cXM‚cÎÃjNx&4¬&Á1çÁjÂê?ø‚·lÌïj“ :;;¥R$o¼úê«ò‹_üB‰ÖW¯^Urw­]”^üD"¡–ã~øaÅÆ\”¢cû†@õðA>N‚@‹ª¬q% ÐÅA _0"(Q|®ßjš©¦bHCÉJQ¦Íõh´?óªj¦ ˜%Q}d¬DCÀ0 j#àO4LI’š ú¼qIi$ @‰¯ üH5 JÓÃENaøšß| Âp‡@e?òúNú©y*‘Æ3 Ädºá!¡ŽÏB †€!`,cŒP°Œ/ŽUmU'°ôX,¦®¾ô¥/©+„çŸ~’ÐZÐ5'Õøã*®öù‡ø9pà€ÜqÇräÈ©«+ñ÷4GE¨âD(WØpuO-Ë¥  LÆÜVsãSzÖ°*Ecî}Ãjn|JÏV¥h̽O+=ÛÃá°’pæN½ð³|Ö™Œòp3¬ÊÉ© +Êï¾Õ«©_Ñ:ÇöZ¹à÷ÀBdð¹üÖ[o©Å6’¡/]º¤ß@´˜³V JûÊÆ塇’{î¹G u´ôfÁ0jŒ@‘0eÕ%­LàŠ Š®¼ª”’þöÎÎŽªÌÛowBö„%ìKH »a_A°ƒëè(·ùuÆe\æ7ãç6Ÿ3ã2£ãˆ#êTFQPA‘]ö°oa3$!a  ý½Ï©~;§o×½}»ûv÷½ÝÿóK¥¶SuN=u»NÕyÿç}có¡3|¥¿gv¥¡(£«0-ˆ€ˆ€4-LЭŽx¢½I©²ý¨hŸÈCò§ch§ÒÅ -#êÕYFIU²’µXBà›ßüæS”TC›D`Ô˜ê¶Ë‰&†ƒ—QwýºàÖ 0(¢.cÊìÙ³íSŸú”]pÁvÎ9ç Šq¥f:æV­Z•¦+V¤ûŒ  žª "äÁᇞD¸¯nt¢ ¼)PÆøñãÓr£Ë@¡2ê£*Võq"—X‰Ï•F§‘ô»"܆!B͘1£Ñ¨’w•QÖ &$Oº½ó«ÞE± ½ÏG«½öÚË6ÜpCÛj«­úì­wR–Œñ½•àᇶ뮻.yU !‚¾}†:á€oª7¿ùÍÉãß4m]FÈ¡®ÊÑE ã‚1¹  Í㮚{%0w͈O\Mw¤e5ê£?Sò|¸6Â#øß)^ ¬ÓM5Ëí mŒít=eŒ®»¦«Ö$бfu!pÃÛ8«Cã /EXœ`b(¬÷„Õ±u!… p´9©íñ6Éôù¾ä '„¨.2ˆ°x6h)íãx)èTP¥º l¶ÙfuçUFÑEÀÃåRôÁ¹xFõÜ~ûíöï|Ç}ôÑÁ)¤Î³"vÀ“Ón»í–<*àÁ ²±¤Óމ´Á¤üuQw6FšÆ¨0êEÇk£“ʨŸ¨X‰•þ«ÿô÷QMå ØŒŰ³#K#SŒüU½S«ÞE± ½ÏŪwF‘c$±Â†{ é<Ûù>hdâÜ´µ•e¬^½Úî¿ÿ~»á†Ò÷¡ÞÈÇwÊp âš7Úh#{ÃÞ`'œpBZ4šG”£ùðX¸p¡uÖY¶`Á;ýôÓ‡§#¤Tžƒ‘ð"ÒöùÏ[û¿›ú>ÿÜçÌ>ûÙ"ÄÁê•Öá¡ ÛÜÍô˜©›F›Tž—™ænHiǘâA\LÐñüJ?Îã_»ÁfÌ”éÖî¬ñTõd¤h§&…Qä2ú@Gˆ€ˆ€ 5WW>îau\(àaÆn²µw”wö_wy)ðu ¨Û««–™½¸Êuo‚ÀäÐì§­¡Í!ÑÖÐæxBô¶î¹¥…øm°ÊXû’µÍÙÙì‘þÛ%ÎýêWmÍ–[¦ÁVôóЇˆ}aÒ¤Iib™mì‹ïòý@ÿPLé¢õŸˆ€ˆ€´(AóTó îè~ûígÛo¿}òZðË_þ²Ë`ŸçŠeŒøLÏ>û¬…üY³f¥‘6Œ¶a./6U^å2 fRõÓ+±ªŸ@ý9õ»}¬B¸Vÿ•÷-'¢*£>fbU'r‰•XÕO þœ#éw…dzÁLt6RÈåË—'Á-·Übwß}·=õÔSéÛi¸<ä×M=÷ÜsO;õÔSmï½÷NuV¸ƒœ–E`ˆ`˜I.¤ š¹N‚ 5%õHaÒP”QÔ@ÿ‹€ˆ€45 ƹVÍÛÚˆho¼Â)¬N§h µE"ƒ¶1ã¬ÃÃé´Ñ¥0±LhâQFjÓ:Ë ô‰2”D@D@D@L`ÈDQS¼`¬Ÿ9sfó“ŸüÄ{ì±Ø=lóWÜm a˜бw饗&o;ì°Cªó{ìa³gÏN.Œ†­¢*XD@D@D@D@D e ¶`Ù²ev×]w¥x#Àƒ"‚»Lî E`ýÚ×¾ÖŽ=öØäÝ onòN0ÜwEåvmã'Û˜ñך£…&!éxe­­{~EŠMÝæ¢ƒöÉæÀób¤ióe›äaH¹QÈC"¬ó0¤öIY»‡F`ÿP”‘ Õ" " MM`ÌÔÍ××/óN°nÕòÔÞ°s̆[ZÛ„)¾ÔæmÏFÞÞtÐKÆüBT°ní )OÇ:9~’‡îñóºè˜i[6¬ ê…‡„v¯Oû´-Š6-‰ :Å ëKÒ’ˆ€ˆ€ˆ@ ¹¨€ú;6y8òÈ#“ÛÌßýîwvþùç'מ}¬ÿ dø¯tê‘èä»ãŽ;ÒhœiÓ¦Ùœ9s Án»í–B:àTID@D@D@D@D@* ðmÁ÷Ä}÷Ýg‹-J! þô§?%A³y#ÈëN|XBØüñ¶óÎ;§PúîÉ iY†‘BÃAE‹@˜Fi2Ú³›Ûi¥Y™ŸÃÉÓé©]i(Êè*L " " MK t«#á ¢ý ý‰„p­´½!Ì·O“B#dÇ4´ ¯ç2ÊêuÕ\D@D@D O†ET5d”ËV[m•br~øávÙe—Ù…^˜<Džf˜‡êòôÓOÛ’%Kìºë®K ¹³ë®»¦i—]v±™3gš:ۚᮩ" " " " "0ôBDpÿý÷'žžxâ {á…’7„x+hÖ4qâD›7o^ u0wîÜ$& ”’ˆ@@€±„„ñ&F‚"À+a’0Àó$±“DäÁàã ¯Xä˜HCQF”¥¹ˆ€ˆ@óHÂÞ~¤u>'¹ «ý°Î6…íɘß)RKíMgÛB»ãáwÚ¼MjË…q´Q©MkL„Ju­,ƒº)‰€ˆ€ˆ€ ˆÀ°Š ¢æŒ‚azË[ÞbGu”]yå•vñÅ'ã}äi¦yŒ(¢N„J “ð÷¿ÿ}òd€ÈO ˜:ñ„’ˆ€ˆ€ˆ€ˆ€ˆÀÈ#á ðDpï½÷¦ O/¾øb¼üòËIDÐL! ÊîÂÔ©Smß}÷µ£>:y& lÄe¤´M†ŸÀº—ž·YÐᆞ¦`Ї5p×ÎmL°1¹ é4b´S<àÕ%†uÇóOÛº—žK"‚1ž¿ÍCÚ'o¼ÞM5ŸN±ÁP”‘* ÿD@D@ššÀ«Ï.-¸±~ìF[™y[CÃrŠÃã³.C¾;" ¤Î‹«¼)ò ¡}’·3¾¿}Âd3{ŽAôÖ)dK¡{ž[f¯¬Iù^Æö^†§¬Mëxy -(‰€ˆ€ˆ€ „@Sˆ âB\pÚi§Ùë_ÿz»öÚkí’K.1Fù4k¢spÍš5i¢Žx2@dpÍ5פ0ŒôÙqÇ“À‘ÁìÙ³m“M:ã6ëE©^" " " " " ¥ <öØcé!ß*Ë—/7Ä!>^ç.Ä›]D7}út;øàƒíHM7kÖ¬$ö–˜ èh.MJ yÀ…ôË#B;ë™<à¡ ¤Þù1â$qÌz!A·£†¢ŒnjED@D ) ¤ÞÞ$ÁZf˜OB‚’ãu€cÒ<«C{S’cCËðrz¤¬Þ=öiƒˆ€ˆ€ˆ@½šJT•qÁüùóí°ÃKnCó›ßØõ×_Ÿ:ë"_3Îé<ŒÎDê‡È`Ù²evóÍ7§‘>ãÆ³Í6Û,þ ‘ÁvÛm—B)4ãõ¨N" " " " "0Z ðn¿jÕ*[´h‘=ðÀI@€ àùçŸïzçGL€ˆ •R»»¢9s¦½îu¯³8 …¤›0aBE·Òu¨®" " " " " " " " CC )Eqétl1tÐA¶Ç{¤p„F ÔÀ’%K"[ÓÏ_yåcŠôÔSO¥NÉË.», &Ožl3fÌH ðj@È„-·ÜÒÃTuÆœê<Pþð‡Ó#оð…/óF&•Q?M±+ý Vÿ èï£:›Ê=wÝuWzž³}§v²üã¶ÑF…;Úʼý]Wõ“+±Òß`õßÀhøûxá…’?ü°=øàƒöä“O¦Pˆ˜x¯o/•w“|W!&˜;w®m¼ñÆ)T"%Ö!Ð>qš»žâö‘—¸wî-Ú±öE[÷¼‡ExùE…0ÎÝNOOáÚˆa=m kŸº™çÇåôú¿yò¯ÃUµ§öIZûïcðýCQF*Tÿ‰€ˆ€451oãõ£½ñö#óNðêÊ'а¾w̆[XÛÚ¥6C[3eÓâòw¶9ë^|.…âéX÷²·M=ßæ~àÞ^·1›l×°2Ö­z*yä!ÜB»·}”ß6Ž ¥n|»’ˆ€ˆ€ˆ@½šZT1vìØd`Ùpà “ñýÔSOµ;î¸Ã.¿ür»é¦›ºBDþfŸ3’)™°bÅŠ$’àZðd€»ÑiÓ¦¥ÑC fú(¢Y³f¥ËZºtiš»u0FDqN•Qß/H¬êãD.±+=¯ªÿ0PÅs—ð8ƒÁJeTç_¹G¬*‰T_«êl*÷ˆU%‘êëCÍŠ÷n„¾ˆ~ÆŒðÔ#&Þ»[9!Tæ{âCI^ ¶Ùf›â€o¬¶6u®¶ò½UÝG1 4cÖ ºHàš:Â`Èé sàëÉÔ}àB:®ÃŸq„Q å^W†¢Œ¢Tý/" "ÐÌ\˜Vš"d;Sh„Î\™ð ÛqäqAAºg\vŒ·Q -#B/xûF™éuWï¼Ýî…VD@D@D Ÿª¼ôólƒ|^ŒêgÂð2oÞ<[¹re ‹põÕW§0 ­:j(:-éÄ$!4xüñÇíºë®KB:ýÆßE˜ÎM:=Z DPèI€ïÂ<úè£öÈ#Øm·ÝÖ• ïggu–ñnÍû8óVýžèº¨Î…-¶Ø"}/|ðÁ6{ölÃKß•ÞÐ*Óºˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ThóN3—ìµn¢úâ_zé¥d„¿öÚk“!~ñâÅ­{QuÔ¥ X0ÚˆÑGÛo¿½m·ÝvÉ›žú“èL½÷Þ{Ó¡ŒÜÂCB£E *£þ;#Vb¥¿Áê¿‘ò÷±zõê4:–+4iRzŽóümdRõÓ+±â]Jƒå¿ƒVøû 4â\¾BDÀ|Ù²e]žÖ®]ÛržÎÊïHÏ­„3 ¼BÂN‡pròJГ•¶T'°páÂ$¶Y°`~úéÕ3jO¯òî¼Qµ}þóÖþÅ/öz\Õ ŸûœÙg?kë^zÞ:^xÆG{¾â.¤'yØ5Öài€Q ë|tfò4àï”>b´Ãó‘¿Ã3ïK !Hx)OŒS ZŠ2Š èf&ðê3Oš½üRjOÆlè! Ævzc[xÄñÖVxÃyÕÃêØoo¼M"¬Njoð^€÷¯uk ï¬ÓÞøÂŽWÖZ YàsÚ¬—ñªŸ‡p ”ÑY׎—×XÛNsÌy´ß¨ÏýêWm‡+޼cOœ81õãЗÃ2Ûñ†'búïô2P2¦~W@Š€ˆ€ˆ@hyQAÎtâ "0 óðúë¯O–Gr¢ã›^XbN‡âŒ3’q ÁÁ¶Ûnk[mµU7oÕ˜ä.^k$“ʨF¿çv±êɤÚ±ªF¦çv±êɤÚ±ªF¦çv±êɤÚ±ªF¦çv±êɤږÑÄŠ÷~¼<öØcIXŒˆ€ePÉšo„Á{ï½·Í›7ÏvØa#Üïꈇ%$¨$¦uÙÚÆM¶¶iÞãn§ÛY0¶…{玗žsWÒîæyŒ‹Œ&n˜F”¶áÚG‹Ž?ÅBî‚9\W;¦u/z~?†Ôî^Ú&xX0e¤Bõ_ëð¤®þ3wꣀ1WšwÈ™m²‰yLM³Ù³Íý‚·þuê D`”hŸºiV§‘ŠWW-7óö†4ÆÛÇßy›·=’güä$2KíM§àµcÍjß³ÊÏõеàs<_ûXo“¼½šæaºB÷ ° ¼òxûؾÁ¤¢ Ú´ 8gR,P]%~±¢‚œp“'ONS„8þøãí¹çž³»îº+ n»í¶k5?n$.Wë€]ºtib+:&™júôé)l˜L £°‰ÊêHü…èšD@D@D@D`ð¬]»6‰| Sðä“O&ñ^X~öÙg»ÂðÎa F“x 'Ï÷ËN;ídûì³í¹çž†ð—x­£Uïâ9--‹Àè"ÐæßìþáÞyÑ™‘Ä 2k_*ÜT{8„7ꤽɠâáºB$dÇx 뎗V§sux|ë¶ÎqCQÆèºk#ìjüøÇf—^jîBÈ a‡J“ ]íVLî1Ó³·¿ÝlSý¬$"Ъ´©él?ÂxŸ®¦J~ö¥ö‰chGRæÎÿªÓ¯2¢]ë,£Ê©óÒµ," " "PQ'*¨ÄB'‰Ñ÷Ä$=å”SlõêÕvï½÷Ú¢E‹R˜„|pT¹X NtîF…Qžg‰x¶áÕ æ°DTƒ|¾ùæ›'7­Ù)´(" " " "Ђ¬\¹2  àõ*æ„{Á !ñjZðr¥ÊxØÌGkî²Ë.¶ûî»Û®»îšºÝE4ïÔ¼_+¬Á  ×IE å 02´c-#1_u¬7ÓaÚ'mìDÝõ|r)]Œí ßšç­ãå—üÚ}äæ÷`0®yÚæÇŽqO¤¶ Üuuçò¡(#ªÿZ‡À~döÍošw–!ê’ï%ÿí1¹W"û¿ÿ·ø½ó…ƒÖ! šŠÀ¨$°nõJuð²ÿÝŽ±öIVÇÃëÚ _àasHmàæ¦°Þ¯{ÑC¼â}È.hçauÆÓ¶‚ÀCLž¼˜{Æ1Bóxêðswx(Â"4¢Œ1„k@Œ0ÖËèlß:Ü+´ ·þõ¢‚œ£r/Á÷Ûo?{ùå—í™gž±{î¹'… dÂ#'n´¦ŠŽâœ!Ët*/^¼8¦ ÏtˆÒ1:Åãêáͱ|cb¢Àª¤©uJŸzê©ôn·lÙ²®9â<°?ÌãÝwä:ò”º@D€ç9sæØn»í–DÒOá¬ÛAZ¯zÈ‚žuCÌ+.pƒÎ8Œ9—CÏ„Înžd=é4¡øÈÐŽ5/Ú:âL»g „ $`"e.釢Œ¢Pýß.»ÌìßÿÝì–[ܸè"•þ&ŽEXpãE8B#TK·ÞZxE¸é¦â<"x{é.3ÍN:ÉìÔSÍcvV;ZÛE@D ã%¥æÀÅjí´9¢‚¶ ÓÖ—·/» tø7A;bÚ(oŽÚÁƒ¡Ÿ”·Q|;¼´Ê…okµŒ ×E=ô¿ˆ€4úRÎ?ÿüäMÁ 8À“á FŠJ"0Ü$*¨qèØc"Ѹí¶ÛÚ¡‡šDÄ|Edp÷Ýw§ ‘©JˆA;#Ä•‰‘kzì½yßð€ÜÔÝß!4`ÔVÌcyÚ´iÞÇÑÙ)Ryb­‹€ˆ€ˆ€ˆ€ô‰ïj„)@Ê;â˜ó¾Kžð®‹` æÔÆÍ;.¢YDx!` ïÀ È£÷ÛÚµWD „@nuºwf9×qUýfÆ ´Oëø¦Î¨–(Ê(¹4mjBÓ¾òóÞí òKó;þ’‘oé¹üßÿmvöÙæJÆõåò{¥îUÔöÚK¢‚žÔ´EO µ3mH½íG×1Y{CÍJÛÚ1¦A.£ñdtFh8U«V%Qƒ9è¡¿€pí‡~¸D §­ö‡€DuRã£7‰BD‡vX—ÈࡇJ!.%‘Rwt>Ç(¶î{Š5–!8ÀkA,3§óOˆ ¶ß~û$:˜îªtÄÌ7ÜpÃ~{: Ã÷ûÇ2eí°ÃIVVÇþnSõ“+±jå¿Á[}D B³ &¤xØ„Õid¢m¹óÎ;UFPŪHYÄjd²zÉÝ #ÀÛBÊ9ûÖ®]›D!ë,+ÕO€wU¼q!" ¤ÁìÙ³Óz„3à;B"‚úy*§ˆ@uŒöl›¸‘Û_^-\Ng.¤míKÉ•4 Úq9í.¦ÛpÿìaÚÝuµ?ˆ:ÝTç/¡“kjŽñ!¤CQFõ+Ôž¦!€ñÿÿÑìê«Í_jWËûp|¤ˆÙdÇà9wgŽ¡°,ñŽQm_ä§ìçŸï)>àX‡éU”çÑ\D`@Ú&LMíFãî­ Ò:B¸ÇRò`Ðé…€<x(ð¿ñöqþ<èà‰ ãeoo0’¹·ƒ¶ †ÇÛ¥6o¯Ú&ú@2÷ Ó2Öz¼—Ý6–2Ïàmu/Ü#P]%hZôÅà’¾šHôÍhPGÐÐ|¸ ¬îš´XùÕDp@ð‡ÿØcÙ}÷Ý— Õ<ð€-Y²¤Å®rè«ÙÕJ†;â›Üý]™èOLˆ>ÄÑËÕ\Äð¾ÑÝïýò—¿L†Àùóç7\T 2ªÝÕžÛŪ'“j[Ī™žÛ‡ŠÕ5×\c—¹{ÐÜ•çÉ'Ÿl<ïk*£çý-Û"VeTÊ·‰U9—²­ÍŠMì„!@,ÀÄrLˆð4€˜“÷+‰ÊîæÀ¶M:5 ]0Íœ93 ]CˆŒÈ@¡½ÆXG‹€”h뮤§xljFŒ&cM§G?KMˆƒ7¨´onDiëŒ[›j C)¥cŠEò®{Þ ÀžÚ'mÔé¦Ú 0CPFQýßÔ.¾ØìÚkÍV¯®^Íw4{Ï{ÌŽ=¶ðà5üÄl¥ÇawïžÆ9~ós…ãz!v\àÒïÔ› ¡ß'Ö" •Ú'o´~"µÎÔ‘Ú›NQ"7â'þø)ÖæÂ‚”òü¯¸èmõÓIøÖæbƒ1ã<Æ~?¶}òÆgå+cÝjoÓü[©}¼‹!ÆÂvJ" " " ' QÁÀvŽC&áAO¼ YLϸÊqAL?üpê î:z%P+´ãé€Î[F…è!ËÜ›I“&¥Î^„Ü#ÄLŒ(¦CïkÖx¯AHœWeÔV¬êãD.±j.VŒ æï£ÏþF'žƒ*£>ªbU'r‰Us±B°Ú;ïy–î¸ãŽ$@8°Ò;ècâYbæ±*væJ!@¨¼à}`G7ž0P<ïëï J" "0èºDb‚(Aáþìw…él”x.>ˆüÌSH„Îö"7ÔEy=´Üœ~÷;³?ý©zÝÜ3}ýëf\x(ÈÛÁm¶1wÝcvÌ1æ£lÌ~ñ ³ÿú/ó8æªyGLõójˆ@óÈŒüÝ*åß©½Iëio<#í“ÑNegkhQ¯Î2*šÊ¬T-Š€ˆ€ˆ€ô‘€D}Ö—ìt.2Åèx Ù¸í?ôÐCSÇ0ÁÁ •ÀÄ|\f–A»/uoÕ¼tž×ê@G`ðè£v èøå±=¸süu×]—ÜãÝ€ B,3úxÚ´ié}áD9tBÿ†Ži–TFýDÅJ¬ëoÏx«aëŒ3ê]gNDP*£>XbU'r‰Õбâ}¡)¡˜52G(ë±L­ð^‚—&ÞQÄ1ˆRã ð~È»íĬY³’€Olãý!<wH%j¯¸p•Émc¼[ǽîÀ?R“«éŽ´ì£F}ôgJž·Óæž ðl€ëtSÍrûăA£F;ÝCECÍMåõ‘ÀÒ¥fÞÓc{V?ðƒ4;ð@óŸžyÒdÿ]"ð~ûèGÍÞüf³«®2Ûw_ó‘8=Ѧ#бÆ=• pÃÛ8‘Cã /EX_¦-Šöc-!Ü[‰«´ÑÖÐæ¤¶ÇÛ$GÐæû’7œ!ù¹#,B#ÊH¡h7ÀKAç»:õQ0o¤ÞÈSÀ pIËÄhVæ¢þä*p¼0!4 ŒÛ•†ŽÄx6/áý D¬#.@lóXF|À6&ŒŠt>GBH#—éÆˆÓè¤2ê'*Vb5ƒ<¯_~ùåôüàïQ#SŒ(W½S«ÞE± ½ÏËXñ·^©rÁ@¾Œ`€õðX✓÷Àð6ÀœmJƒO€w;ÞÙf¹x ¦™3g¦pZá…ŒûËûy•D`4X¸p¡uÖY¶`Á;ýôÓGÃ%Ú5æÏržímŸÿ¼µñ‹ý/ïsŸ3ûìg‹«WZ‡·mîfzÌÔM £Mj;¼ýHs7¤´cLñ .&èx~¥çñ¯Ý(4fÊtk wÖnx)ò“ÕŸs˜FaËè?9$-2{×»Ìn¹¥¼¸)«ü ÍGNtýnÊ3f[ÙŒgHúI:=}f{»/¾ÿýf?ù‰ùËS÷í¬m¸aV Jx™{ÎÿF\ð™„|ÇMvîÞÇc\k'U^­óxˆ«ä!‚:m±EV‘F_“÷Au]ËDŒÁz—é+Båw=ÚÊÇ=¬Ž÷K·±±›lí»}™Éã@'¡N¡k¯®Zföâ*×½ykB°Ÿ¶‰6‡ÄßS§wDoëž[Zˆß«Œµ/YÛœÍy´(¿ÿŸûÕ¯Ú÷²Âwý<ô'1¯¸L,³}|?ð-Á÷}Èô/ÇÔ¢uˆˆÀ("@¿Ñûýˆ–‘x–ü÷ÿ·¿ø;’ 3õÖÎa®Èh-ž¦Ü°ÅÃa=öè„GDx2X¼xqð€Qtø„ç‚j%,uÕ>tî/†ùrˆ؇°`Cÿà ÑAØÆ2sF¾MñTÎ3ÐÄo)ÿ= ô|eÇ«Œ2*åÛĪœKÙ֑ŠÉðPSvÝÆsBeÔGQ¬êãD.±*g…¡ÿ9ï\~öÙg»&Þ¿bB(À>Ö• òm—xÇP¼—ž Ïa3gÎLs–„æÞ㘔D@D i `˜Á˜“F‚f.¤Ó÷$†š’š§°>RÓ 6~àú IH°~µki(Êè*L MIãzo¡!ùô%aÔÆ¸]–®½ÖìÆqÓTì½í6󎱲œE½~øC³+¯ì¾Ÿ¿½÷.Â1x?KÍä}l©¼ë¯7w eöÄæqæüÏÃÿ>˜¨+çCü@(‡Ýv3{ýëÍŽ<²0ò×R”Á±7¾Ñ\ÕXÄ•çyåª.³_ýÊÜ…Ua„¥üÝw7û‡0Ûo¿BQqú´ +xÀÐC¯úH¥B˜€§ ®Å ©¬¹s{)l¶™Ù 'a*ò²~û[³Ûo/®!ßÞ—e˜î´“Ùë^W6úr¬òhoügä?ÊõuÈ„ë7úRú¢¢}ÊÛ¿÷© ê–ÛWüœCQFe±Z¸Ç½úàšoÂ,ïæíß—ybßíþü¼õÖ[Ó€R<bØÌŸ·³¼ØÏŸïØzKœ‡ðˆ·¸à©«\„6Ùp|ÓRîk^óšd‹h„!êB™ |¥\®“>úIHØ=¨7¡)Ÿ0•×çémN_ ,—-[–]p]»{û×› ý3wß}wò‰Í» õCðÓ[ªç~r<ßàíûþþ€·Iú°ñlãï ûºG¦vØ¡®~XrúŸHü6HV™‚MåvÖùÑ×Áµö–°5r?ùý0Q6÷”~y~GÔ{×]wµ™3gÖUÿÞÊÓþ‘G@¢‚&¼§<€˜øCŽ„Ð`®¿øó@áAŽÁ›‡"ÜùãÍ€eìe8æ#@CÇüjgæžDç4 :÷Êuî7Ûx™ÈÅ!8 F€@ÄzÁjuÒv0êóqɇ7MÌÄ:Û˜ØÆ‡]¥WŽç=ŒöŸy¾Î²Rsà}‹ˆm·Ý6 ¶Ûn»4çãžwªÄû—ÍqßT ú ´µµŽ Æû OýˆkéÎÑže:x;ÕÆ6ÜQcôñç¢uO|ã&ø¢¯'7ÕEyx1°W‹NLÎK>ÒP”QÔ@ÿ7-:Þk‰ì0þc`v†wd ì20N|éKføCaälþÎæ\åçEìðã—×o«­Š}„X¨Lˆ~÷;³sÎ1»æšÂpÏ6Î×Ù™_yHZüñÂcÃ/~aþ‚aF؇7½ÉÜJQš½ÛF·4÷R’®2xgL“þ÷†pàoþÆŒ:ÿò—fÿôOfwÞY+òwKïWJ‚‚wì6‚|W_mvÆE”7ÊÊùQ¦RJykÝW*Ï~7êØûÞ‡¥¢¸D Ôï,®¡ØÚ¿ÿùmy¦ÙqÇb‡þEG  ƹVÍÛÚˆho¼ìV§S4Ú¢N‘AÛ˜qÖáátÚh‹Rÿ푼­Im”ÿfÛ0|y¾ô·À2ex¶†”‘Ú´Î2½@ªÃÐVdÔÿ"Ð7÷ß¿}ùË_Nvúè÷ÿÄ'>‘Da\ÿƒ·mçŸ~(ƒèOà;”üôñc>úè£ý±x\ò|QV‹k]|÷?ÿó?É»u~ÎÁ7ð¥—^šìï}ï{=2ÑuÐËʉmô“\|ñÅ®W»2šÇ$úAÈes­\Æû#]|7þü´çªg~·ËßýîwSŸ epMGq„½ç=ïIßñõœ#òœãíü¯ýëÔÿ÷åÝï~wb\Ë£l=÷AÇ/ü}€¼¸—pÉí>çž{n4ŒÇ­¼g_µôŸÿùŸ)ÜeØô¨/ýRy¢êßþíßï|{,c7ú—ù—$.ˆm•sê cêþ¸¿×Põf;SÜKî#÷qÁÉ'Ÿlûï¿ÿ€K•uÑzkð·¥V Fè\h@cÃ7ô•á„صÑSO=•ø­p­#­Ž4< ™zKx€s¿ó†(_gˆNB„BƒÐaž/³^«Áì­^Ú/" " ÍH€«J‘b>~™‡0€²Xç‰w'Úç|^)`?Û”š›¼|¤# @<0cÆŒ´ŒRŸ}¼3ñAÌœ©ÖÇ|s_©j'" ë ´ŸlcÆûhoôl…&íìxe­­{~EŠMÝæ¢ƒöÉæÀób¤ióe›´Iq’Ü(ä!Öy˜Rû¤¬ÝC#`4Š2ŠÊèÿ¦%àmjU¯TÚߕܺaöÚ×Þjt˜÷zí}´œ+;{Íš2P6¢†²Äv âþ¾—Œã‘ç®»Ì-?fŒ¶÷>²$$à<õ$ús˜õO?õ)ó!fûX!2¨uD >(È_F{æ¢xøÑ̾ò•âœe}Gäqo™= ÂaÏÁˆNŸ$Î÷ô[o¿ÊÎù„J™ŸßñŽw¸Ã™º Z|õÌ/»ì²$`ÀÆô‚·}½õ„ÇgX`ßø øÞùÎwÚAT·Aš~Žçz# ·²#o>g0.çŠz±Á#½«Öý¤^?ûÙÏ 6܇äåÆ2ÌàéúCúí²Ë.ÉÞûóù½÷Þ›Düfj¥J¡Až—}L›nºiiŸ÷ñ?øAò–—Z‚¿¥ûî»Ïõ…ï³7¼á ²-åÀGù²D-ü S4 ÅÄnŠDÇê^{í•l4V<àxè!.àó%þ1À°·VœWóÁ'À)^*j•¢ƒJBå:ù%ð[Á]bD±Ì<Ö™31ºí¸XWç{­» }" " "À; *o>âxoaž/³šØyh3ããœ9ï5Õæ´±zïiÔÚó ÀsÞÄÄ6ÞWB4€€ ĸC[C•&" C@àë_7ï¬ZP›·cs@§døhã^ ½íîÝ ½s¤iáÕPõÔ°2>ò3&¥æ%à±ÃÝsa˜¯0„tUúºë Ãú?ÿ³Ù¼yÕ]ówPe!@™1½Jöš›©+ž˜3âž„€QöxÀPÞKÇ}qP•ÿ9¯wÈÛýWqͧžêÔõ}r=ŽªUûYðÿa†è¡gNÊ5å‚W„ ðØ@ÜåZåô¨T(äõa£îÅSÿüüuTIY†‰ÀÛßaÆßzEÓé mNpjíS[“~ÃmžzIý)ƒv-%t™@Á‡æöRšv‹@ß ”õ/°žg¸™Û<”}½%ú*È÷›ßü&á,Xúæ1ªãߨû<”ñFæ·½ím©Ÿ¿·òc?}).¼ðÂt Ô«/‰òé×!Œ÷×ý½•ºsÌ1u‰ª±ìKù‘·Ú¹Ê¶Ç1ÌËö³ ‘BxàúÊòåça™-x3ø’{búë¿þëš‚þŠÊö—zÎYyl¬cŠóĶ˜#pøö·¿Bo `©7Ñ×Fa;^ëÒ°CÖ{¼ò\½·Þ#÷ÚGì•E§jîÕ€ÑZŒÞ">4„ .@h€ÛæÄR¡á«Ç°=b!¶À…ÑÐÐÐ3ÕRÆå—B“‹Ê„ ±-:äÄ„ØQ"–ØÆrBŒÀ6ŽW}xÏà# £?/|‡X Ÿ‡( òòqÃûIX޶Ž9ëeÛFá‘{żƒðþŠ@ñ±ð.âÞ1Âû€Þ7FîïAW&"PB€ÒL#!yG·R“à›Þû‘’ÁÜßëJ†aÂüÅ_˜~ºù°Ä•/b–碓=hî±§Ü;Q·óùÔlþ‚Ú¿ó•Åo¡‡*µ}ö)ËÑû6iœŒµ<л½’ÏÙg›]pÁà ¨¹ 7Ý‚°þX®¬Ãú½}_â÷Õ×ßIßKÑ €G ¹«$"Pqþë¿þ«;|¹Ó ï³fÍJý脱ÆCÿGž%~É%—ØÁl[º¸AÁ­·Þšì9‘¯žóÐCÈ…C=ÔvÚi§dˆãkÍ#\tÑEI Piäæ{|·ÝvKßéÔ{£Þi‡…üZè»APðýï?}ãáa ZÕ(ÍýüÚ×¾f‹-êv?¹ží·ß>õY!ý[97˜`{#Ü9sJCB^{ýg‘Â[@¬3¯ÅoÁ.S–‰ Èô£"ã5Šþl9'ð¬Àï 1Lüvù-å×TV†¶.Œ¢ûMç+S™Ø€ AÌyh,swq<Иhäxò`Á Ôš ÓÁHˆ BŒÀ•‡8}Ñ™_¹ß R.4`9ŸØ_9ñ‚¶8ok’V­E@D u àc&Ÿøøà㈉í±ë!`ïÑÞðá–eÛØGöé#¥u3}­9m<± „€€9ël°!”e®÷‚¾RV~hïpö Äµñ Ü=nòàæîsÙì­o5·:Ôo4Æ+‚÷!4$ùÀ÷ÝÝkêY-aàÆ+uöP£þ²kÞVLµŽóNw÷…\)¸†¾&wœFÿW•JOã^›ºŒú7Ýdvæ™æŒrîþØ}›,2R„FøÕ¯Ì-æV‚ÒÓwÛwÕì£JÖo&†÷Õ4,q¸&%ap‘OßHô¿ÓÏM(‚ùóç§°ô§Ó‚íå[ßú–kÞîéê7Ç6~ÄôÑ8ÏñÇoÇw\]çáø+®¸"‰ô«œÓ‰;ÿûÃþàMþ¯“P ßÎò‰'žh't’7•Ó“} ;@ôåP¿|Л¥3“aþHØ‘~øÃ&aÃÌ™3ë7ÄñÍ0ÿùÏžîI ꤿ‘<𜈽 y°páÂä%"êÎ> w{Ø$ôoäéo|cúmDŸ&þîïþ.y|ðFØÀ`‹²Dò‘‡ûBØ ~S‘'üíßþ­ë! !õ‰ß$÷Žß)¿Í_ù{¡(Sý1AOstÿ‹É¨$P&6»¨Ïx˜„à€F‚Æ1r0GpP¦¢•PGÐEÓ ñ¢Ãg=—GcÄD£Ç<ŸXgËy¾ØŽ(/=!4àå‰íl ÑÛØ_6ÑHr>% ø`EÈÇs„,3g@,óqyØÎ2ÛØÏ³>žýpã=€‰m1¯¶ŸíLJ"@û‹W#ÄŒ°Ë›{g=íw¥h€w…x_A& pÚi…¨À;—ýE±z…0Šc¸÷‘pÉÐí#íä“ÍþüÏÍvÞ¹»¿ì,t’ðƒ…AßGû¥Äè}÷¢é= C¾±GòNþTf¾ÃzE'~:ÖGpºUÀ<è³Ù&›˜[Š þý7ßlœÚÜJPnŒ÷÷f»á†"BD„4¨7!zÀ[é¼ó̪y7Øc³ÏÞ|˜«yçIq=„-x÷»Íý›}ï{…wƒâLëÿG„pôÑfmd”Ù|cwQÁŽ;š}â…wÂ?ÔJ2Üå³d”炵Øl¨H¡¼$m!'€ËøHd?ô¡ÙÞ{ï<Ði#Þ~ò“Ÿ´¯~õ«ç®nÂŒÐôÅÓCÚÔŸËþð‡Kσ0ÿÓŸþt×hú3pe ½‰ i¶{ÀÁ{užè[ÿsoË14oâÏî¼þy><cÿ7o3+EØ0ÌÿÕ_ýUb× Ëù#qÏ>ðؾûîëÍåF=ìÇ{l^àa¦‘ègC°­­ÒøÏ½Éï2{¿úRú’¿@__ÞOwÊ)§$oæ•õˆ¾l.x¥þ ÷B…ˆ%¼V÷¥\åÙ$*Ù÷w@WW­c®]hÔh¤˜ÂàŒ›”0eÔM*”F0,ÅËO_ Pâ%%¦Ä:s¶åóØÛc/?!F@xb…|Î2ù*·‘ŸíùDî$" %À3!Æ|æˆöÂà϶0øÇþÊm‘7„€sçÆÿÞ–óýñìèõéøÑA€6—QÞ ™ 0±ÌÇ.Ÿñ>‚X§VhrŒ&wcˆûp6f×{e¢ƒÊü‡¹¿_3„ ï¿FiFÀ—%¶ûH=¼Œ¢µÈá£è’ñ¯•Éʼnöÿh>ä¯rO12ß¿å»%w7í G³;î(ŒæoyKáQa‡ aùËÞM;x&{ßûÌðP–ÜåsòlP¶¯¯ÛqÔQEÝöܳj Z€¿*Ü¥SQV*ÏOÅG?Zœ#÷2@>ìsÕ?4ÿé~4"7%¦08W΄mE” =âlôýyìèä½"¶UÎùMÀžëUJ€0~ùÈGl÷ÝwO}Ë•—É·1áª1òâ‘ #äýèô?êÏï=\4Fue⻜Мç!«“Ÿ‘‚Ä µú´‘Nhìèǧ ¾ÙD¼öµ¯Mßö•åæë Zåmí§>õ)ûÊW¾ÒM$A?ÓUW]eozÓ›ÒÀƒVí `ÀÄßüÍߨžÞ>c3(KØ8à;äC’ˆ €{ýõ×'¡ý$CÅ€ßCþ[¢Î„<ÈE e×ÁoŠA"䪺–ÕCÛš“€DÍy_šºVjϺܰí!ûòí±Çų1ÎÁ\IM€vж"„¼ë! S‚‰v0„Xfž··®“Î'" " "0„0Üû¨<ûç6{ì±ú Fà#ã’±ý;ß1Ðl¶`A1Z¾Ú(;:èóNúj†~jàßîþ‚bþ‚R_}8׿h>ì®!O˜ŒîþÞR3aXǸÏ(þŋͭ=³»÷Κ^zQ¾£=F< ÌœYõáè£!ýãàIzø€žRÃ>÷ÊéÚÊJÁÁᇛÝxc!ÏýuÜ6o^áá ßË•÷(¶çs¼Tà±¢R´y¼Ï0y°@ä¡$" #”Þè{EPÍŽÂ¥Óç|{Ë!î=#Ê£?(°pž¿v¡†ìÞ΃k}¾×óóÐOÄ Ïè?Šóæsú«®¸âŠn.òÙOÝ9'Fðz})ðŒP)’ÀCæÕW_<2ø¯Õ^ ¸xœ ¤Vâ>½ÁßRÀ6ËxüFH‚`(žÅ+ï=ý5üîêIõæ«ç\Ê3rHT0rîeS\ GµŽÎh 4<Ș0ÌÐPbˆá¡ŠñŽ ¼ °ž+ìšâBU‰–!ƶÁ¨0¿Ó\pÀoË—«íÏ¡¾üp“ô™Ï|&yZàeƒ¿-&^`òeö³mùrlc;†æ|¨;‰¿?Ê!Ç…1ˆù@ÛQï•/Å9w;RÊà+\‰ «V+ƒö‰zÇ2s^¾ƒ‚ÜÁ1'_LúãX¶ÅzˆØF›CžÊmìãã+ÊàoWa¤0ØÇ3%îS×ã|ñ{Ö\†‹Ï{ž=耈9˸×ãã9ÚòÒ–Ñf0±¬Ìáºs*WD@D@†ˆ€CÚ»ÞU„&øìg̓ór\_áäC\À;õ?ýSáíàïÿÞl—] a@}giL.)j»îZ„8èüv¯ëÄ|c'„B™¨€‘ù¸‹öo ÿ¨®ë”¥™ÿ€xÃ=ƒúKV‘…9忉: 2(KxdÀ»Dµ„. í‘ÌñðÃó®.JèqPÅ~ge†÷†²äïÉóÅ^{õ GQ–_ÛD@D  ÐgËÿÞ„qiŒz'/ž„‰þ.γ—?3ù&ï-q„•çÁ³t¥a9?×­·ÞšúÁ¢Ÿ+öò ÒE~ì«6§ D„ÐÎû¾n¹å;ñÄS?wµã›q{ÜÏzQÿ]ü=ïØ´röôk²NüP$úwèÇ¡¿3Òîýˆúµ¢¸#®Aóá% QÁðòU¥Ó¨ðÀ¬öÐÄ•F0®±Ì5Æ„ÌC|€à€‰ÑÝy#5ªÀêb‡@þR0•à·ï½÷V)Pf.ZÈ×c9„ ±Nþü%‘¿b^ñ‚Á¾<_ˆ òy’rû+Lk#ážýÜsÏMÊVÊɧ8Ž9ç¢QNl9ûb'‘¸zÇeEž˜G~Ö™87sRl‹å˜Çö\Qʾ0RÇþ8Oåq¬‡±9žMù<_ÎY±®ƒåÈWy>¶óû q?™Ø¿Iæ¬Ç>>("á6ŸøfŒ.&Oy9/ëœ'¦X¯ÜÇ:yÂO9¨ Ï<óÌÄ:ö3 ŽÃ<¶1휃zUÎÙ‰kúÚ×¾Ö#OG}#ÅuÖ»-Ž£N´1J"ÐÊx®âi€IDùÄ6F>ÐYÁ³™ç%ÏÈxN³Î²’ˆ€ˆ€ˆÀ('€aÛãê&Ïÿïÿ™]y¥ù‡KýPx7'$ÂÿüÙO˜qFÕcdªDYý-Ͻ4ù SyMùnñïŸÄÃß»ú•û°`AwAAµùûYÕDùߺUóp/:¿µzäOoÇ÷8¨s}ßú–Ùm·•{Q á¸ÖZ‡jç×vhØ8vÛm·ô]o•ŒYùí»ý¾ž'ŒÈy¹ôŸÒW-Ýí‚°ÊþOB_÷ňžŸ{ª‡ÛÁÃ}ƒ¹H‚A;ùz~L3/s? aA¿I½‰~¼6Üwß}ÝØ#2Èû&ë=_óÍœ93õµçÜ/¾øâ$>ᚨ§’ô•€~5}%¦üƒF :°«0cÆŒn†.Œ=<„™Óð¡ºÃøƒè rÎ> iJ"ÐjûEƒóó÷Q-…Ñ<ŒèäË·Åz¾ŸmaØe™¿½ /¼°ªŸ<¤²ó{ŠÿclËËÀûÂ?zLÍü¼2oëqÞ|žó‡±³ò2ò¼ý]ÎE<ð@*C^µ”_7yòõ|9ŽgÏÉH¹[Kâ›8&æ‘/ÖcÎv–+×#þ‚Xå w)?._f¾žŸ;Ž­6§<ÊQÑL€gìˆ 0Ï—éPÀUaˆÃ$Í¿]»ˆ€ˆ€ ®ï<°‰îÒÉ€Œ›ûLøÛk ôË\sMáµà«_5Ûyç^iŠ j|£%Ï5 65¯P „'œ;·vqïóá…±Ö}Ž˜¼·¾¯Å‹ oÝ,ÖÜøPêÅ ,oå6H`¿ù™L-M\ç{ßk¶ãŽý.”žXE@D ¹ÐoÈ7x_bÿÊþÆþœOƒ•}ŠØJòþÍÊzaìÏû&Ù?×Û$#õ7ÍóP:¿ñ6!7f3€jÉ’%ÉCbåµö·œ¡8®?÷z•ÝSxÔº¾žý=«ò·È Ý/ùËî„ê]ép<åïwJ"Ðô–²/àµTc™x03Lj†ŠeF·Òp…à…ËL ™³Mƒá½Ç*½ù„‘7æý©!Çöß÷ƒm`¦ŒÁµÎsk°Ë c<÷¼RåܟߎŽÑL |ˆ†` – Wjù 0eÞ™ÕzwÍ|uí" " " ý €‘ÄGSÚÛÞfvÔQf]döƒ˜Ýq‡ù@}'dDûe—Çz¸%ïu¯ï¸ÁÊ…Û;Ø“Ë~Üö#\öþ£dœG0áß6),@-fäéoBXAØ‚:\[§"\4ê*R󗼞®»ÎÌÝ′•„Züõ¯‹ë­¬/åSj‚…Êüù:B~„O(c ã¯þÊl¿ý""/SË" "0‚f€où&TžÁ@µ~]ú!ñüšF¢ežúR·2 Ô>Oú%GC?}51 +ØÕº‘§‘óYÞ®¿á o° .¸ «ožþm¼H|ûÛß¶K.¹ÄŽ;î8;øàƒÓ€•F–­s\ŒÜ{;ꮌƨVƒDÃ…·.žL4˜ù2a`œ ¡sÖ°ÑœCID@D@D@úC€KF À³Ë!`Îv:B0ï8t°œÏ+?RûS#" " " }"À¨¶í¶+\öŸrŠÙï_•ÿð‡ê£àópÆEïÈNò|ÿ`/{ßN áðÛßšaˆGT€(Aô÷xŸQ—œm} ÷ЗúcÌï‹! 1Ax ¤Džð࣓0àu¯ë.,ð8Îö¥/™Ýxcqùq,ãIG_êÂq°ùæ7Ínº©ü¼äqƒ†p‚ù /kJ" " 冾¯çaf¥—ªF?E-;KEõ{¬Ò§Q)n ÓóÏ?Ÿl1=àWÙ_SMÜ1X—Ïïá­o}k ƒ»hÑ¢.›õ Ã.D\ìÂÀsÎ9Ç8à;ú裓ýl ÷~°®Eçm4ϽPM™q¤µW¨Ä BlÀ2âJë¢ó)DÌq#˜‹âc“w>¼cªüÆËSÑ" " " "Ѐ¿û$ã5#Ûy¤Ùå—›}3»þúÞðzŒbĈòyØžÊÄù6Þ5ÊûQžæ" " " "ÐrpµÏtòÉf‡VŒ\ÿþ÷Íp·_-aÈðA†-¨à¡‡Ì>ÿùÂý?¡ ZMHsôÑ„>ô°à»ti¾Ç|t‹yÐê"¼„dzöÏbžª]³lÁ‚Â[A÷³Õ^£œï|Ç ‚†²ô¾÷™x Ùøñe{µMZ–@³ [ *ÞW[fäŸ2eJQö}©0} ]ÔÆßI~~ì)ùz_Ω¼ý'°ÕV[Ù>ðÛk¯½ì¿ø…G+z8ÙµâŒÜ~ LW]u•ýñLaðr€ÀDIrä4´,uˆ„eŠ»ü<#ÌB,W®#FUâƒ|Btë,3¡S¬òœ²–E@D@D ~|ÔNòuˆ 0Ÿ6mZš‡8€uÌëÇñaÌœö?Öã€9Û”D@D@D@D`Ô@X°õÖfŸþt!øÆ7Ìp»_-!*À[À`'ÂP'œD ƒ]Þ`ŸŸ 8Ü0`•¢‚(SoÉßyíŸ0{Íkú†^)ÜðླËK9ôP³ÓN럄ò3j« ;ü›/_öŠ©"ÐÕl ”ˆñïÍe^ "Äc?ªªC@€gý[¯óÐHóæÍs§F·Ø¯ýk»ãŽ;zxÚÆîÄt‘{"ºçž{ìoÿöo=âÕvêïÿ‘v¨D#íŽêzšŠl L½¥-·Ü2‰ 䄲uTc¹Èáëx<ˆí,³9¸’ˆ€ˆ€ŒDó ¤ç#‰‰u¦XÎäÃû@jÍ%‰¿]“ˆ€ˆ€ˆÀ pѦ½÷½…WŒÞÕFÈã=`(DÿþïEh¼"TKþŽ˜Bì¼saßdóa–æ½èfwßmöã×HT;ï`lé%3È·‘‡}LœCID@D@†ŠÀlÄþcBÀrXηáu |´¥e"êí+û•D@D@D@D@™FyÜÞßv›ÙŠå…yÿCr×_¾·1[.x áªuð~ÃEÿ»Þe6sfÆmY@ºâŠÂ€^ËëBÊ8Dÿýçšwž¹ {x0 üAµP‘ÛCz¦ë}Ç;ÌfÏî» €û‰—ÁXµ,Â)rH!̈r5&†Ðž³žOqi‘/Ö5f&€gF~Ó•‰pͱ <傳2Q!«õɔ՛Fn讬§ÖûGqýl;ì°ƒp v饗څ^˜ìGqVîá5×\c{{˜¤cŽ9&û4½$*½÷^WÞâ¢#Io—"âJáûØy˜“EZ 4ÑA¬‡u&ŽQx†Þî†ö‹€ˆÀÈ%@' ±óø8eâ#…õ °-–™G–ù¨áøJa@tÜÄvÖc[Ù‡çÈ¥«+he¯|øÃ¶Îx¯zéZ7ü­u—ák˜|ÔñK>¥¹¯¯u—£¸¥#•ï²ô½æßhIò±Ð§*ÑË[Ï܃6¿¬4Ò x _#$Bµ„ë}•ö9uþÔuœÇN!8¦,!(øèGÍ{Õ«»ÿ÷wÔ.AÙ9†rÛM7™ýô§f?ÞÓ ÿ±Þ®¾Úìæ›Í‡ ž l¿}1qûPàQ¢Ä˜Ôëå|÷»f×^[=¼Â>û˜ýÙŸ™m³M¯§R†æ'p¥Çá^~â‰Í_ÑÖ0¤ïN?÷ÝË÷hLñ=šçm`t*ôÕàÙqùòåÝŒ÷ÕDõVjåÊ•=Dô÷lãíB5[Fôåe`c¨ 'ÒØežgÑ/÷ö·¿ÝæÌ™cgœq†-#lTgâÜìïGq„De”Ï%*å?]þè!ÀËn^ ZO ¡A¥!¶çb„|c!6 ôBˆ òm•ÛYg? •D õÜåÁ!¢bÝaðA˜ØóÊý±Ä¼“%p~¦ØÆœùçªtV~mP]l·ÎLþÝ´ÎůúôŠ‹³×2ù2ßSˆ BXßZÌI1þ+ê ^u1¡R Àuñ@¼<=òˆy<ÆêŠ7 öeÉß«&Îé#u¥‡®b²1–ÖÔUÈfòȶx1î*» K p·Æ®T2W&„ôńЃmýIÎ=×ÜâP~4!#>ô!³ÝwïågÖÖa"°Ö[kø-¢” âû•ïÕøÎe™ïØü6–c¸òsÅ6ÍE Yðûœé"³G¼½æý3Ò 7ÜàÚ°?KçØÖ—ù7ÞØ£{·aÀ®–ÊD†¡Ú1Õ¶„wåüÚ¸žÁ¼&~ôçtÐAîØi…ýà?Höœ¨Ãƒ>˜¾Kb]óÑM@¢‚Ñ}ÿuõ"P“ J{ª©« Ä2_,3å|;#q‘"<0±Î˱½lmè„SÑB€gö8wyŠ!†æ!È·³/¶çyC$@GHLœ7:Fòv¡Ú~¶+‰€ˆ€ˆ€T'@{S´§|wñÍ…<ÿN"ßK|'‘Xfjõ¤÷…¸ƒßø†ÙEFj\Ù3ÒÝu§'ž0»åsw‡ÕÙyç$´)Íàœª^ 0pú(H·€˜¿—ÞµWýÞ?PšIï£$œ(=ñ n¼÷Þr¦ôÀƒwq–¦FWã¹ç̾õ-ó Ë=E Q Ž8ÂÜr[4oqÑ>µøeô©ú´½¤˜‡€€¶‹onÚêàBÛ‹ ò㢭‹ó¤“ê?h2³= .îsQÁ’%KlÑ¢E®S;$ýÞûRå¥K—¢¼påiÏ=÷L?ù¶|™0—ñ7Û9öÞ}ëý;ºï¾û<òÒmÝ®'Î× sž1•×Êõ3h³/ús­”} ‡®úÉO~ÒMTÀïÁ Ó§OïÏiuÌ# QÁ»¡ºhñÀKvdt¦…óĶØÏzµíˆðâ„X9„XŽyl‹9Ûy¹âœJ" "0P| Ðñ€a?&TÙ,Ç<¶WÛbö³Ìq:ùäbƒXFtÀr>ñòë±?¶Åz>g™ò”D@†—tœ0E' Ët Äœ—|öÅ~ö… ¶‘7¶1e¶ó!”GÊŸ}eûÈÛ™Çq±}x©©tœmuþnm7ßÑžó>À;ÛbŠ|ì£S7¶Ç¹ósƶV›WvV¶ZýG|}ñŽAÀ¿}Óä£í‹_4´[¸ÖŸ?ßl—] £ây—õß°ûÌ5»ì2s¿¹fî:ÙÙ^-íº«Ùn»™»×*ϱùææ/ÏåûØú㛹Ëf{Ë[ aBÊÄ-ÿ‘Gšq@{‡“ß¶|ÇŽÆmuÞ.óíý´e´Õl‹yµosΡ$ÍH`¦·¥»z›|½‹s¯¿ó/wá1ÇS÷3à.o+.õ¶ˆ}yÚgŸ}¼¹Ù¶¦A|o‡™p¿Ï»o¤_{ØŸ#½]¯%H /!Üÿý]¾â­4çY±ñÆ{sûD·ëÀÃ.þîų¦Þ„M‚çU_ž?”›ÿ(k†·Ù|¯(‰$*Ðï@D`D ÑìKc[ŒÄ<ïä‹mœ'–c/D±^9çò ,¨œhÌ™ØNÇ"/¬#rˆ¼±œç<•ùc;çb9Ÿsê¦$ÃE€p>ÎË&þžóø0ò“—eö1)_g™|ùÀûïݼ‹óîß ¼C°uöÅö˜j¼ƒ)51¾³}ÿ!š=ûl!ðÑvá…ÅèÿÝzÏ·ÞGÀ(zŒûÌ&TKtˆ¿ÿýf;íT=¤ž j2Ý%²}æ3f_ûZ1*Ÿ‘ú”K0~‡¨€2ª¹âç óÀõž~ºe’0† Ž`BÎÝ,ÉG”Ú¹çöP¿p/ܨ’ öñÝs–™`Äß ÷îÔSÍþâ/ÌvØ¡º‘ŸP=ÔýwQÉdáB³Ÿþ´ú9òüûîköå/â”|»–›ŽßȽóš®Ò ªP´×1§m¦† ËyëL‘7æ ªŠN#ƒF€ßíÑGmwÜq‡7õÏv•àºïÿûÞ´®²7¾ñ½>ðl°ÐÛG}´[¿2}lOxƒZ‰¿­#Ž8Âð6€«ýHˆÎ>ûl[°`7YÞf•¤[<ÜÒ™gži>ø`ƒxIö¦ß„¸|Dºúê«íõ¯}Ýîç.ÝÙň§vZupÎZ‰òþ÷ÿ·òïèBD½»×"7ºöIT0ºî·®VD †âàRpFþ|;—ëùrž7ïxŒ¼ùþ|9?ÇUŠ BˆÀœýˆ*眘('Ö™³ÛYæ|ǶÊý¬‡È¼äcËìg[”û+×¹çĤV@IDAT¶8wäóä×;ðQ‡†á»VÊë€h6ÝÔÌG7úÐÉbª<džòÜ€Ñu|±¥}Ÿ—Û‡zNÈ€ÏÞ¼w¿ða ‰kÂý÷šýó?Þ ðZP‚ß\•…J¹”(D©i 0ʘ6i4¥èŸˆkŽv›yÙ Äì£mcN[žçÑ\š•ç«r4÷z{Æyê‹×B\sÍ5)<£èñ𢷠+Ý3ÎS.{ÞŸç¬W¾Ÿ¾öµ¯õ¦üD›:uj]—>ÝÅ„ˆ~ùË_¦óÅA¹):‚‚Íý¯ Õ);7‚Ïœ9Ó2|ï{ßKB„8G+ÍñA؇<Œâ.ÂQüñL÷çÍ3.¢äþ°ïCIlxöä 6úÓŸ’Xƒã·p¯Lˆ˜s_à÷¤¿gqß¹ŸÜÇ<üñFø žsJ"‰ ô;(%/!1/ͤ" " " " " uˆ÷jæ%"Åö`¼a$?ºy§ntÔÆ<ŽoŹ<´À]{ë[Ín¾ÙÌGÆ5$Ñ}Üqfÿ÷f{íUx¨ubþFÞþvó¡Å¨ü¾ô w#)9×ân€í¬³ /eå"B¨f8Åe3#ø û€Èa8ÆŒ3Ù3¤!Õ/â ÂIaþüîá'*Œ )³Ñ×ÐJé$•0$åmQåþ‘¸ír\[¬Gûí5sÚ3¶3góÊãc]shFê?ùÉOzäŸoØ¢E‹º‰‰«Ë„›‘ïüÆy ¯°e×3ßÛ„ œ7þ†ÊòåÛȇ7ʸ馛ºyI‰ð¿ÔÏ <—*߉wòGýèG“À'×ÎËh…e þˆ+.ô÷Ž\0÷ã?)6Ã'Or/ça‚a"¸‡0âÜÇÊã9 ÞêïPãñII: HT Ÿ‚ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ :HéôŒ9xtÞåFöEmtðQ¼³°²ãtª;$§Í;9‡¤@ÒwoxþƒÍ¾þus¿ÆÅ¨ò¾Ÿ¥0îy¤Ùûßoî{·ð€ÿÞ··¼x'x8Ôã‚Ý;ÑS½ýoª+!2øØÇа ?ûYuaA×ÙÂìÙEöÝ×Ü¿òð‹ áÿ™Ï˜ýä'塈7ín““¨ƒÒÄÈC¼TNÄ%ãñÅî»›¹q¦+!4€#÷¢‰sMœ(/`9Èç`3mÔhMqí1§­Î'¶ç‚‚ðVÀö8f´²Óu·~¯3fÌðf÷SöóŸÿ<”g|žx/ÍßMó}±Œ1ûo|£qÄiD}_ÿ0¨üã·³Ï>;…=ÈêQïÑyâoånãï=öX¾»å–yÆœvÚiI^ð6íp¾SæÞ#ú‘ø›ÙÔC½Û=m·ÝvvÞyç%÷ýeïÃÓ÷Þ{oÃEÿ{ì‘Â2p<v8D⺭ÐÏFÝOÊ-ãŽ×†zß¹sAäe.ìü‰ ñNßq]̹NÄÓ‚f /3þçž<öqBxxȲu[ 1ÁI'd3gÎLÌÒÜšP}<×¹ë€@‚ó0áJ˜°Þ‰oûï_œ‹óbøÇ8D÷)×úÄ…ÁQ’,Ü@`[o],WÖ;Ö97ÓŠë… ˆ8Ö '©Üz:ío¸Áìƒ,¼6À$OœïßþÍìÍo.˜çûb™kàú—,1ûЇ x2¨L0½à3霮ý‡§ò7¢+™{äF´äQ¡²|­7F¸VŽ nª ae0V†e&Û˜òm±/æCXM5„YµlÙ2¼¯Há0fc8Ƹߗ{_vŒÒˆ †ã< äïž¿\î?ámßÃÞþ"V`bÛo1dcˆGP‚ŒÜ}©s­Û…—‚UÞf?ôÐC©ü§½Â{åÂy®¿o @˜êí7ñH¼Cc@_îï)/»—#8“ûS+•݇þÜOÊ îÔ:ÃrCGŠ:ô…ç9¿3Î÷øãûëØ‹éZðʰ£ 7sã$(;/e“ŸópX>åï3Ï=÷\ qÁ}ã1ÀVÜÛÞµ8jßÈ& QÁȾ¿º:¨›€Du£êWÆ\XBN”‹ XÏó±>Ò£´ê©5Ò®½å¯c:†eÜècØf9Æ5ŒïLx)@HÐipkØ5SåæS”‹1Q‘õ–É9§ó¸ êÔ½Zý¹^Rž¿ØRû ñÇ‘›²ú’þîï̾ûÝBœPyœ*´ù—B\ÑêB^B[¸¢4}ÿûæ” Fim-p“=’Ený½ï˜BLÀy W9ïo:®u`¸åÝ-&ý­y³'®ƒzapgï¬q­ÌŠÆï>Žiäa@Ôμ)··ð,C"o_êÇq¸Ÿœ#žŸ}­C%¿¸~ÎÇÄùàБnœƒyÜGÎÁÄ{9s%è@ß^{;ö‹€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€” C“FRÞ¹IÇ`¤ØÏ<–cßH™ç×>R®iÔ\ÎÕ\ý6þN,0 4aÐï«QŸ2£Ã=æõÖC?Çôõ¸8?†‘[o-¼Ķ|N˜ ¼BPNo‰<œ¯óYTšÑœý­ké µ±U ð¼ÎÛ¨V½ŽFÔ»’lòö¬Úr#ÊÖ9š›@£Œ±Ívž N½U·8g_æx!È=Ô{lëÜßã*ëÅ3¡Qçâ<=W#ÎQyZ}$*}÷\W," " " " " " "0Lè` ±@n€ˆêĶÈÛGÒ¼Ò03’®M×"ƒB€ð ÄìÆÓAYr—ÆÉƒDÙ¾Êm„¸åsßÇ•{ŠõÍ€·¥QO@Ïëî?h£ó­ù¶|9Ï£e $* wQ× " " " " " " "Ð2ÂèÂXo™ PEE@†–€Ç‹öÊ…'‚2¿ú•ÙQG™MŸ^;dÇe¶¯|Åì àsù5x ypåú¼”ŸA[GµOÝof5Õ¶w?Zk" " "ÐÚ$*híû§Ú‹€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€´(J#Dˆ ¸œÊ}-z‰¥ÕÉ×VzÁÚ(%0a‚Ùœ9f7ÞXîa`ɳ}Ìì ͎=Öl×]Í6ÛÌlâD3¼<ñ„Ùí·›~1Ç[AY"äÁ©§šm³MÙ^m…ô¼.¿éâRÎE[E@D@F6‰ FöýÕÕ‰€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€´)ZäF©š"0öÞÛ좋ÊE„EXºÔì¼óÌðZ@èn%…Lxå•"<ÂêÕf,WK'Ÿlöú×›M›V-‡¶2j—FÙ ×劀ˆ€ˆ@ Ô€£]" " " " " " " " " "0ìN9Åìâ‹Í–-+•",! ª…5¨Ì_¹Ž˜à“Ÿ4›=[¡*Ùh]D@D@D@DÀ$*Ð@D@D@D@D@D@D@D@D@D@š™á ¾ô%³öv³_ÿÚì…S[B$¼å-fùˆÙî»›UwqcÀê," " " "0²è-qdÝO]ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆÀH#@(ƒw6ûæ7ÍÎ?ßì{ß3»óN³—_îß•NšdvØafï¿ÙÁ›!Z d‚’ˆ€ˆ€ˆ€ˆ€”¨ Š6‰€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ@SÀè¿õÖf ˜|²Ùm·™]q…ÙM7™Ý¿Ù“Oš½òJy•Ç3Ûn»ÂÁþû›y¤ÙÌ™fol6~|ù1Ú*" " " " $*ÐOAD@D@D@D@D@D@D@D@D@Z &O.¦Í77;ôP³5kÌÖ®5[µÊìÙg‹Ð«W›EÞ)ȘM3cޏ`Â3<È3A+ÜqÕQD@D@D@š‚€DMqT èL‘Ö­3ëè0‹9ÛÛÛ qAIs~¨ Ðtˆˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€4$  ú_D@D@D@D a:ß4v>HD@D@D@D@D@D@D@D@D@D@D@D@D@D@D`„¨`„ÜH]†ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€4š€Â4š¨Î'"Ð'ë<Îߊ+ìÁ´gŸ}ÖÖ®]kãÇ·‰'ÚÖ[om3gÎt¯}cútNeh ‰ ÃQgè5kÖØ¥—^j?þñí¥—^²ŽŽŽ4q*„l°Í;×>ýéOÛ„ úQ‚‰ BOÇŠ€ ˆÀ3ÏóæÍ³Í7ß¼‰¯@Uè/‰ úKNÇ5 «W¯¶U«VÙóÏ?ol°M™2Å&Ožl§[%qŒâÇ`×0nܸV©~]õÄX|Ûm·¥{UíŒÇ3f̰vØ¡ZmðH€à„¿åÊÄ߯+¯¼b/¼ðBTî׺ˆÀààïîŽ;î°3Î8Ö.]šþÃË bÚªm·ÝÖÞúÖ·Úá‡>8•ÐYE@D@D@D@D@D@D@D@D@D@†€DÆ^„À‹/¾˜F+ãýž{+W&5† L:bd3ê 7Ü0©wÝuWcÚ~ûí ÷úÙ0ŽÞ}÷ÝÉÀþÀ$c*bŒîq ¸þG1}út›3gŽÍ;7¹g½¯‰óÞyç¶xñâ$¼`T8‰óãV>®åÛÛÛûzê>åG4qõÕW§ÑçÕÄÕýXWèîûý÷ßoO<ñDµÓ•nG¬Áµ#<‰iÒ¤Ii¿¥á!ÆÊZ¥×“§ÖñÚ7´xfóŒÃ ]oŠg8Ï@&ž <Ç7Ùd“4:¾Þó(ßÀ ,[¶Ì.¼ðB{衇RÛTyFžé÷ÝwŸýïÿþ¯í¹çžº?•€´." " " " " " " " " -N@¢‚¿£©úÄq»|å•W&AAß_~ùå䂹7#ã“O>™ "³1&O›6ÍöÞ{o;î¸ãl§v2”\ÇÍ7ßl—_~yDp÷1ŒãJºì:0®=úè£i¤èE]d¾{ì±é0¸õ–ðàðï|'óC|ÁÈoRˆ/ðìÀ9ßõ®wõvº~ï§L\×ßzë­5ÏñC©™^ˆJ=»dɒįæ;ÃhÉ!sXâΛß"&<& ·¥¢êZ– À³çÝÂ… mùòå}þ‹ ¡1žß¸ÛÇx½Ç{¤¿UDAJƒG€v AZYû¥ò<æ?òÈ#ÍE@D@D@D@D@D@D@D@D@D`„èÝ9B.T—Ѻ à‘à¿øE2j`¤Â0ñz¯ cÇ2‘ðn€Ðàšk®±}öÙÇN<ñDÛm·Ýê=]Ÿóaȿ뮻ìç?ÿy0²³Þë·ïœƒãp¿bÅŠd˜Ç»ÀÛßþö$.¨U)ÊZ´h‘=óÌ3U³1š˜:f¢þ7ÝtSºŽjå`ØÇcÂV[mU-KÚŽ‹üóÏ??‰L0h5*1šúá‡N à5á˜cŽI.UŽÎ##Ff„P>ø`¿eŒ8/ϪóÎ;ϦNjóæÍ³SN9% €ÊòkÛÀÐ6Ðæô–h_i[•D@D@D@D@D@D@D@D@D@D@F‰ FÖýQWƒà±Ç³þð‡i¤+dL¸™®¸âŠd ?úè£íïxGCG¥#ÀuôYge×]w]Š ‰s`äA`ðøãÛI'do{ÛÛªž6„ U3tî@¸0˜ ÞW]uUÍ"I€ŸQɵuÅøßHAåÁ*~¬‡…ß ”ùóçÛîÿŸ½;¶­ªîÄ¿*•5*•”•Š)õiÔˆ 5¢`óQD‘hì;ˆmÔDbßEÁˆ4Ѝ4Š(6” ö‰±%Óü¬dŒJ¤þÿÍÏ>®Ç~ûí½ö>çžsï¹ï­9ƹçÜݬ½Ö\Í^k~¿s®»ÜÅ©*UU £OËî£ú¾-d¥ Ž>úètØa‡5Ñ Ùª§æÐ@~wL©C×N¹nŽÇ×K«ªªªªªªªªªªªªªªªªªªªÖ@•T°•P³°·€¢3Î8£¤rt½¯\Îé¥.¹ä’æûä“O^JøfĈ믿¾)Ç÷¿ÿýÝQ–“ëY*€5ä]È~»ë*ôñÿðMdR…2G*“}b캞”G} DZxЃ”žüä'7[Ql4ýzÕÀ¾ªcù2HT%ýèŸÆðþð‡éÜsÏm"ÁsÌ1é–·¼eé¶zn¢l c;d/c`IþÓúOé&7¹Ié’-=‡,ö­o}+}ö³ŸmÞEÈŠÞ¡¢ãxïØVûçx@R–*UUUUUUUUUUUUUUUUUUUU3 TRAm k§Ñ¾úÕ¯¦³Î:«ËÇ›%ö¾úê«Óÿù?ÿ'zê©£á÷Kù¦ÙƒúÌ3Ïlö˜\¬J€j"|ó›ß\kR@GÝ–"NØnÀ67½éM'©KÙ7S2EHw{‡ŸtÒIuK„ͬ€ú¬m§Íê£Þ¢·\uÕU ÉÀþ‹¿ø‹ÛN_ë˜a¤‚›ßüæMd˜Rþ20_ºf+ÏýÓ?ýSºà‚ b›w²¶™ÛçÏýÜÏ¥ýèGéÿñ›wÿît§­Ìj}vÕ@Õ@Õ@Õ@Õ@Õ@Õ@Õ@Õ@Õ@Õ@Õ@Õ@Õ@Õ@Õ@Õ@Õ@ÕÀZiàçÖ*753û½x´^sÍ5é­o}kbüßLBAV>àûÛßþv:çœsŽ,#-¼þõ¯o@˜U r¾=SÄ‚u^®ê·$À«C9$ñŽ]gù÷ÿ÷&bÁk^óštíµ×®sVkÞªö+ ØÁ~ùå—ïWå^eaov³›¥Ã?¼8.ÿò/ÿr:øàƒòÁ*󲑴ÚD›1×0¿È„iúßyc»O•ªªªªªªªªªªªªªªªªªªªª5P#ܨ‹úk‹5À oïmá«y›Î+ÿù?ÿçôßÿûo¶-ø…_ø…q@ôy·Op½÷ÿøÇÓžð„y³’þå_þ%½ë]ïj@þ6h1OB@uá—§†÷œyË9O~6z-bÅu×]×x÷¥¥ÌBg¯óí¼«›ÿøÇéì³ÏNÿãütÛÛÞ¶}ºþ®¨˜¨^âBÐg1žy' K-"Þ!_øÂÒ˜îxÇ;.’D½§¥_ú¥_J{ØÃÒ¯þê¯6‘ xóÿÛ¿ý[s…±ïV·ºUºÿýïŸî~÷»§ÿøÿcëÎõú9å}ìš)×­WÉjnªªªªªªªªªªªªªªªªªªªV«-ø«}NM½j`TÀÿóÏ?¿ÙçxôâŸ] ´õ½ï}ït¿ûÝ/pÀ ˜ÐP¤|D° Á_üÅ_4D „Œ=Ãu—^ziHJ¦ Ç /¼° ¯<˜È`úAÔ”ç×~íׂ„ûyUŠ@àsýõ×§¿üË¿lˆ}ù™ú¼¾{W}L=|å+_)‚„¶>¸Ç=î‘þÛûoKË ò.w¹K:î¸ãv§IOÚ†È Úº¦çï}ï{Ígr†tþöoÿ6½ãïH/ùËRËîÕUU£Ä~ 'ìq­~š=Çξóï¤?ÿó?ŸD:s¯ñòâ‹/N¿÷{¿×´öH¼þ3—¼£öîu¯{¥¼u€Dœ3v#öù®R5P5P5P5P5P5P5P5P5P5P5P5P5P5P5P50Ml,ìËÕ¦2M_õªªª­Õ@%l­þëÓ¦àîW\‘¾úÕ¯NòäÁè?þøã›½R¥/ïJ€ýßýÝߥ÷¿ÿý 0?¦| Ô?ÿó?7Þ®ˆ cÂs]„Ýžºå¼yä‘éQzT㥘„ççÙÇúö·¿}3¹~Þ3üÊ+¯l¶ˆÈyÊÀNþݾ…$ÿÒ—¾TÌÖù/ÿ%Ý÷¾÷-^3ïIzAR@,èŠ ›ºæM¿HB§_vÙeé‡?üa÷–ÞÿÕõw¿ûÝ&b³íqÝ{C=X5P5°[ú¨qPˆý>ÑGã7~#Ýç>÷IGuTúä'?ÙôOÇK‚È„ðó“Ÿü¤F))jŽsÞ³¥wíIÕK«ªªªªªªªªö „KúÔ§RRú¿ÿ7…A'¥ÿú_SºÝíRzÜãRxÁ¤`:ï;å­%©¨¨¨XXð†/~ñ‹M4_‘ 9²-³Ýò–·Lw»ÛÝÒa‡ÖàlfUªöU pôüð‡?Ü`0p™ÿs'ŽgzЃç¥}µÜÛ½\•T°ÝkpÈï/ºè¢I¡þÏøG?úÑWxßKªÈ@pùÔSOm©~ðƒ¥[šs^è?øÁÀ¸”î&B$‰)‚ìð¬g=« ÷oÐì›((¢Qve@4xðƒÜlÑÀ³^„é­£ð6þ›¿ù›†¤1”?e¿éMoÚLœ†®Yô¸´ûBrw©û‚7û·» Ÿ.ê„m4Æ€)Š„h ‡rÈØåõ|Õ@ÕÀD ó®>.ŒrˆeÞcòà÷ýï¿’ ÆUÏW T T T T T T T T T ,¦$‚W½*B”"ÔZ á¼f‘¼Â¹%~zJ·¹Íbé×»ªªªªö \sÍ5é}ï{_B&`/÷É[²_ÿÃ?üCúÆ7¾Ñ8ÉœtÒIÉv”UªöU ˆ2û¹Ï}®ÙJFÈÌá“spÆÃöÕ²oçrURÁv®½}$ïÀX!­…ŸŒ½Ã?<=ñ‰Ol˜Kc×wϘòH ž÷éOº{É^ÿ# |ö³Ÿíõto_ŒMõ­o}+ýøÇ?nümêSN9¥ñ¾ÇóÓã~á‚=üÖoýVúØÇ>Ö°m±Ž’ë¸äY¬nù¾·ZäA;á}ÛÛÞ6½õ­oM?ýéOG³À´eê.aaôæzAÕ@ÕÀ¨òþÀ>°!ðˆBPc…Z•ªªªªªªªªª¢8˜7€o¸!¥ØÖ0Åv‹)Öí ÌãÚ¯zuƒ@$|™-[„ñqd#B÷Ú¶Aß&`¹,ÿëý¯½Êâzã×ç?ÿù&¯òéùR/"k­fLÙ’‰HHc¤åÔ_6*tHoˆc¢®Xªg¤³UÖu_¾=O߉M¾”Q»ÖÎnr“›¤[ÝêVÍçW~åWvo§Ó—žcêÞxâÚ’˜èÿÓ?ýSS~ÏÓ´gm鷸Ť0i©K emUè?e¤guhœ¥ç×~íךqΖ@Æ+J"¿ÒÈ"mú+‰ótj¼èжG¿¥wíªû'£:°½ù?g¢ìÐÑ»!x¦ge}[žñŒg¤;v4I›wíÚ•lã‘AH ¡{“¶wQ†g>ó™éNwºÓ¼ÙÙ²ëà@ì1QÖ©ÛÑô¥…„òµ¯}­!Œ!öпOÖaÖîƒË¬ën~´ßÆ­_|qÓžõ½<.ÈO–œ€»öç3&î±ýŒm…DêŠç|ó›ßLçœsNC ’ÒîGÚócûعÈat‰”dÌôþ”®²äï¬gzÍmÜx’ë_Ä û¬õüH¼Úïe鎑Lô¯¾÷³òîE :øàƒ»jjÚÆ*ûç á5ù§ú§M;ȺÉc¼Ñ ¢¡1±d^‘&}yæ™ aJÚy|‘û/¤ªT T T T T l[ 9/4)ýñ§`Ò¥`ψ¥é1]wÝŒ€`ïÛ˜¤˜D•îªçªªªªªªªÒ'>ñ‰Æžb…ÃöÆœ(ÿgٯ؞ØRÙÙ«T T T ¬›êÈ´n5²Ÿå÷¥/}iÔ»8ÂcüÀ\š†xtòtåíÈ#¯$ÀÛ© —È3&™Áëo¬›ö¤©[nuó:íÞ·Yÿjl-¼²ÏOI€V×…± `;xN?¼ÞM2¯ OÞµ· ‚÷=Ó=@ â¹®'¢؃ Éè(Ü(ñD°§×‡?üáf‚ lõÌ!‘/}‚7½²Ñ ýÙ~äáøÊëÁzõÕWïÖM_~•EÿFz(‰ò+èàÚk¯m¢”ú¼úÉ:r爘 ÿ—¿üåppzH£ ¦Š4Ôo_Ÿ’?íoG èXk{ºè^ŸëH[Àn'Rps hj6~s=¨/`7ÝYé]’UÔu~–1@ßA&øbìÓª •ÚûäÕØ; ω²ÒG*Їi´-í¦Oè >%âŒü‹´ }NéKtà“Ç9y5ÎÉÒÇÉ'ŸÜxÐç|©íZ„ùšG”OúCB¯H†}¤‚UöO¤;¤å-µEäõÐWCeÊǵ-¤1„±¡wãꬒ ²ÖêwÕ@Õ@Õ@ÕÀ¶Ó@¬ 2AÌ«bœâ¥7­®3¿ò‰ˆUéþ`© ÈvMƒi©Ô«ªªªªªªö3 pD´ŽÎvÛ\ü“N:)zè¡M”S!ÖÛìÏì¸"6V©¨¨X7 TRÁºÕÈ~–Ÿ ÜŒ¿sçÎ¥ƒ^μúÆHòi0$ÎóÆ`Ÿ0èûƒvxG£K"|v@Sºg³Ï0>úè .:ò…Y*DúTRI£öuÆg4á¿S]xžòºWżãæÏ~ö³›mæI'_ Dûô§?Þ÷¾÷ííŸÏMý–'åâüø@C4°ȪDž‘3Æž ¶ECIÔ9ÀõïxÇnÿÒõCçrÝs>ô¡5àÝÓŸþô&’ÃÐ=íãî¬úî“|¡@$ Â%‘ÞØ5¥û·âœ1×öc‚°4Ò¿›†vŠóÞ÷¾w€ß½?ÿ¿Ñº–Žv mCÔD]Èùú¶¸ÄÕ»Ñ ŒQúÀ¡@š®‘ß1Q†k®¹¦)b€º\D2øœ o ËŸ%ŸS—Ëzò^ë“ÜÿVÑ?‘îDd0^•ÞAê>;ì°ÆÑ—Ï¡cÆ ïku9$ û )rHõxÕ@Õ@Õ@ÕÀ6Ö@$#ìOJW\‘²¿xA,ÍEãÛl‡`k„*UU7j ˆ®ÍÖ"Aˆmú ‡„X›…‘$EÈО)j7^?å×*ÒœòÜzMÕ@ÕÀ~£kyÙ¹Äú›ƒã#bë£lejÝšˆ¨ÿûß¿‰ÙV°gÖ5w[#õwÕÀþ¡ãÏG>ò‘ÆÉ픓+ Q¤õu‹ZRIûG›\ËR2Z3~JÆ„§é*€x€“]tQ1 ò*ŸaÜۢ÷xމÁ@èóuõÈËÿ¼ç/<:KÀŽAÑDÊþßë,@6 ðyŒ$$ûë¿þë†m:V&€®}Ú…›æ}^íÆÒêž×6ÅÒýë_ŸN9å”Q𼛆ºûà?ØÔ%ïÝî}CÿË“~ÿùϾÙÎd/E:Eê¸à‚ öbwóe²®O" ‰v¼+¶ȡߕa£bLá,]éŸxâ‰M¨³¦ë~¡ÒxÙO! (Ï2ÛÝ2Ê0–ðZć1Q¿BÈMh_Œë[Y×ÚO|ä!ÿ¯Z´Ÿ.©`YÏ56¼m/`X†~õ[´…®%+´Óéû-í)䉾{ÛHÿD„¼Ýín׌éCéÓ‡H>HŒSQAŸºþúë‹·ˆ¶$Uªªªªª¶"òSú³?Ké²Ë6F(h\¤ƒx‡V©¨èh ÖS± OÁÆM±À˜üÿ!R—Â#'¥»Ým~RÁ*Òìd»þ[5P5°k€Ý©àÿ‹-¬ým3ˆ` ìFHÖÙl•m=¹F"hk¤þ®Ø¿5À& £Ìöè<þ<ô¡];RÁÏíßUUK¿•`Àæ=”à°é—~iéÙh2º3’ C}_Dåü”<sÚHÂüï/<J¹$trÐA­ Ä*={Þs&c!ò¥ Ì:} 0Þ¿ßøÆ76 áª€]mÓ^ìöâäMmžÇ6pz„‚ü\z‘ÞOó|ÏÔoi#½ë]ïj@ûÒ}ú?’ˆHF}BwH$ï|ç;ïä±:íK£t èd5iXFý[¤h{ïÿû›-JÏÞÎç´êc2O¤ô"rðØÞ꺶ˆiamì=9¦‡©çõ‰U’Þ€ÖÆ“e ”«ä7ñ^1BÚ‹’¡6Ú?mcs{Üc´: ÇÈoÝDô)ï£Ò8¤Ü7¿ùÍëÖ]åÕÿ«ªªªÖ_"wQ:&z)\Ëù 2yºÙÍRºímSì·5Ûâ`è`éÇCÉ×ãUÛV7úZ¬§cÂ>ûè/¢”¹~!2Î*Òܶ ®¯¨X…ØزÙu­ßÙEب}ˆ}§K*øõ_ÿõ…m «({M³j j`k5`üa›6îäñg™xÌ2KW#,S›5­¹4 ƒL…±oyË[6ìÀ¹0ñb “ÂÝ0DÝÛÚíkÝ †ø1DxŽIÃþ BúÛBH§C9d[¨Øv[Æ¥Qvá±g%/içß@ðNPG²ÔEH<çŸ~:í´ÓF7íYÆõ¥HcÏ:Ÿ'êCç=®ÿYx ýèG?*&!„·º|îsŸ»W¨±|£:áýîw¿{Bšpólá0æÕŒ‰øå/9ýæoþæ¤è9}ßÀD[>Ìã¥-¯«`ûò¸Ñc"<ˆtñƒü ˜”2ýê¯þjºÃîP¼ÎIíQÿ°%Å” ›±Àö&·¾õ­›óË®k„eDÊ*¼Ê(zŽ|œ‘!D<1öÎ;¦ Mi¿ÞU«}Ó‚¢¸Œå Ñïö·¿}S6síÚ8éÓ}Cn ½ˆp令¿ö=SËÏ¢ÞíŸÈ•w½ë]›ç7†D;øf„‡=ꨣ&)Üã$Êíù"€T©¨¨¨¨ØV°_D£ŠÉýp¶#z^:þø”Ž8bæAïü°è¥˜ˆ¤Xð§tùå)}æ3)&$7 ¼;óáÔ3UUVAÄYEšµºªªª–¤vŒ®ÄúºkËXÒãj2UUU+Õ@%¬T½5ñ’ „t °dUâ~“ð@Ë Ð©lÂÆhLÂç+Ïþ €TØêyHswºÓŠÀûн[q\ÝÙŸ} PÈÒ ‘ L(y§#Öt'–}eóÌ[Üâ‡(0\›®j{¶˜(L9=ubö/}éKMè®|¼ï[[v}jdƒLš‘·›…g0¸ ì²q=oÀ¥òb¿ð…/DÏÖŸ÷¼ç K@P óXÿFLÁâq{\3Véëž¡í«£+¯¼² Ÿ6ô« ðg?ûÙ&’ÉFöN3N‘ºõ­mm$Œ[7½Uþ¯NvíÚQk/+Ž-ò ¯ªàò˜ |üãoÚléZ‹>{ÕÛOIŒîVQ×?ùÉOÒ¥—^Z$‡[{‘zè¡M¤<.é»ú¹ˆC[Dȳv¦¯ÿ_Ž`D_‘U}ãA~¤º:øàƒÓcó˜†âý,oÆSãÜwb/dd ÛºhëÊ-âM[܇la<¥e™¢ -"íŸÊ…(s·ûÅ/~q0 Æu(3%¯tkÌ#ci󶌪R5P5P5P5P5°í4 ÜzÌbáÕŸõ;Þ1¥·½-ÅD$ÅäqO¢§ç#ôhLÚSúèGS:ï¼”b¾ŒÌ‘þ4ëѪªªªªªªÐ€è]Û/û{G•ªªªí¦J*Øn5¶å×Ët ʈ¾¤‚1ÕLºâ8°dLè¼I÷ö”@zÙÏ^oá¡ ¬–—D»€ö‰sö»þÔ§>UØÜK7"u<ç9ÏI;b«€µ<˜xêC€jÀ¿p÷ÀÖ1ÑV?6ö /p`wÒÛ½ Ç£ø„Nh€z»<+£tDlð<€y»¿Ëÿ2l ˜< ]oÛ†’Üô¦7MÏzÖ³°m¨íÉ?¢’‚´‡0û„'ôSýpÝ#¨ áÐÍ%—\ÒD†ê[YoÚ¥þrÿûßt‘€¾þÅ_üE±®øêú!yHȯª®•^"ôˆ(ðÔ§>µw_?„#u,¿o}ë[{ßOú5púÙÏ~vºÕ­nÕ¨ÍØ²BKÖýзþ_Šêãùp@zÆ3žÑôuؕܗîw¿û5‘@>÷¹Ï5àùï|çî¥Í¸ù‚¼`m–G>ñ‰Oôê$'`¾¨q›ÛÜ&ÚýmÜ¢[d¸eËÔþIö^{¿ŠŠ` ŸB*@DAp">)«ü'5ªT T T T T l+ D¨˜\Í" eü”SR°{S칸÷æ$>ÈA°K§žšÒc›âeœÒ½î•bRµ÷=õHÕ@Õ@Õ@Õ@Õ@Õ@ÕÀÏ4ÀÆØµ¯ZcWRAm"UUÛQ•T°kmɳ*ðdL7@’U‰ôyމ—¥}Ç»éy0`éßþíß6 O©¼ô~ÐA•.Y»s€.`Ý©@{é‹l¡@È)Àê±öïY@6õR [WóôˆC6à—DÝ,¿÷½ï…ÃMxÜôˆí>áAKQ&Ü&?w¿ûݰº/Ú< ËëñÁ¤Yž—Iâek+ $†’K ìKÞZæ{Õ‘ˆ¥­r„‚ßýÝßc••g€ø^xa~Ä^ßòØ^6©ÀBE]‹¤ =)7¢b0]»™<î•á%ÐδGÛL´ÅqÀºº¥uá3Ö.¥Áÿa{ؤ±øjû‰>ÒXÎö*B4‡È0˪kàûw¿ûݽœ9/ÚP1¨//òáø]îr—ôð‡?<]pÁùÖ=¾éV{Û Ïsã¡ñζC‚¥¯\@{eèÇ•ßG_¾Ýín×—ú¢Qh×ηÉ|ˆGÆÞPZtr/ Ax—ëSË’yû§ºU.ÑVJ–èZTã]”ĵS·>XfÙKyªçªªªªª–¦[qˆu{¯Ä¶K1qJ1qì=½ÇÁ˜4ÄQ‹b} Ì»=.YÚ?l%?ýiŠIÔ,o…«‰¢00OÚÐsísOOÖR1ߎÉÖìYìô³ŠgŽeQ<ÖMÝÉC¬ÁWV~ÄoQ(ˆv@×1çÚ¡wåäÀ’Ÿ-Zƪuk­=ê\y‘f|ÌWýüMQîÂÁ ¸±0MaøK±ðO±ÀO±Y]ßʶ|D4²`[ðÎÚ)ÂS•ªªµ×@—P°ö®¬¨¨(h`o„ªpq=U5°L L%À„Ü]•L%-˜ôNSËá9«ô]•~I—§8° €=$@¡Ö÷ <Ô¿ä%/iön×~†Äµöwç¹Ìóüꫯº´9Žc „>R|óæ²–D~~#ö}á _Øèct]ÞW4p]Û¸ç=ï¹´ÈøÀšH¥< =öØŒƦԑr ??¥_JhDlŠV`|¹á†2нӗ!ú¯æ“N:©ñLoƒ‹È€Iu×>¾ŒçΓF&!!]´E_Ñ JÑ"Ú÷ø­LOúÓ›¶6Ô.ó=ža뉱ö.2bLˆŸÓÊß­kãg‰´ä}¨ÿŒåè΃Ÿ”³+ÆÞéÀþ>P¾{ýFþWÚw_>rºêad¬ÎòõÆâ±~büѲhçcé; Õ¾/ß¿ìïEû§6†U"й¶-:„í†D í ö”¤n}PÒN=W5P5P5P5°ÖÄù”¤g®Tº<2ÓAçØ–*ØÊ)&ú)k³ˆ"ñ/B#Í¢ 䇙ò“)öN›EW4Ç©yž9èL¶«rï϶±Ê·Îõ±WaJ_ùJJ_ûZ öó,ož•Ÿs¢†0aûÏ}ðƒS„sš™ó@üÜFž¡ñf[£ˆæ5/ÁhêØDá{˜ÒW¤0&Ìê̳¡^þòY;]¤/ •¿_{ X»±ÛYóÙöѺ¿mãr\¤Ç¯Äo[<6öŸ;ÜáÑ­)ù»…—Öu×]×Ö=!=Û:­ÇÙÅØ.åù½nZ‹þ¿Ê<( [T¶_³ô9²Ð9‡—>a# 2Ûm¥!i;¾ˆªœñØAØ6ÚB§"Jv·¯aûU/ê×GÔH¤êZ„ANE;vì(¦ÓNsY¿W‘·±6ŸóÎqÊv ôÁˆm‡“g7Ž#ôRÒkNgÊ7§'N{ìjÚFîÚ;±çÞ&Þ§ú¾Ñçˆ7å9l:? ’©¶Âö/Zp_ZÊljm/oEÌ.hŒàtÄ.4fGœ’ŸUÔï”çºÆ–y\cÇbS£gv`¶oú³ùM}V¾Îø£ž9ítëY_5j_t '™§}i3ìzê–°Óæßùù¾ÿú¯ÿz°î8Õƒ–]îöóû~/0ïK¦«˜_:‰í˜Œ—éÑÜ}žô @c"¿}^Ë&SÊ¡sOÇò±ÎÓÓHg¢#„õfzÕŸ—ÃTRA Exi/¢!`9ç/ëÇä|ŠŽ\cûÐØësŒT CaÈMzëË{Λo‘;w6Ïlú­Ÿ™È¸¸¾,ÀÎÄüª0Œëó" /ò{ÔQG¥G<â£Ï¦“BÐ!Nõ¦†W~uÉš§ô˜@˜.#¼ºÅœç|òɽÄmfYõ0Tž©ÇMÒÆÚÜXZÊc)Ð} QÂØmrh"7$&ˆ&ßy›€¡ëòñÖµ>˜é9Íö·±A[c•„÷g_[&«MÄWM*“m Ÿ¡~ª.,•}Ê;y¬üë~~#ýÀoA|ùå—êSùEdøÆ7¾Q$drIßü&ëP^-Òv„A¢JÕ@Õ@Õ@Õ@ÕÀ¶Ó°­ö±I|ûÛ)&÷3ïãeÐóôÓS0ºS¼´g``ÌYcR4#"]LÔg@,õœsf`¯<õ²axlÒŠmôštÝ0b0û Ö!þpJþç³ç;à-8„µ3Å„"¥~{7%[E<æ1)&™ƒÚ}¢¯ü±.jÊèë”XPÎ ¢ký韦y8#ô•Ÿ—¶¼œ{nJÏ~нɦåC†l¯¹fö õa­çÊþ3cîî|«#$×E4¼8~Å+f䊩úÞXë‡z¥ÿ³Ïž‘FbíW¬g ²ö¼^ô¹ˆ±ýWóÌ0J7 ¿zïÓoΪ:xF“-:@IDATÓs€!é¸ãfDúD´…×¾v¦¯¬KÏÍDî=Ú\lߨ[&ýÁ9Ï]vš‘Èvg©åüóS„XLM»§§L¼Ø}ÑÏ~ä6‚0sÆ3’̉'¦@ö$ÊtïËÿ÷õ¾±ñäu¯ƒ(Ìê®M€’_ÄϬ۰dÍîóßìo|ã›5¾5=ûg€šuÐëï|gú«¿ú« Êëokr[è\_üâFæ¼c½ÉÞ $JË3Ùoˆg³Ãx.ûKÞJP„ÇeØñ7#ﯹ.”¯k‚ØZRyûÄúü oxÃn[ññ>ù´M$è¦)óÎ;o·Û骫?ú£?êݲ•îÿ<Þáw20R¾Õ‹ã>¹NÔ‡za³´]뽃(6ÅFÖÎǼ¿W•·±6/ŸìtâZ¶%y¡í“Nèô¢‹.Jw½ë]Ó‰1Vç›WèÛ³Øu½ì)Žy^_ßÈõÀ¦h;ÕyAg¶é7½éM»û»r¼æ5¯Ù£m°á<Ș°ùQnmÖÇõÊiPX†¾yd%Ùç•UÕï”|Ðõ‡cþ”ñŠÜæsý²5~ä#i¢)Ûîþ°Qa›¼ôÒKŒ…MUnëVúÚ–ç«k„iôÌ:&gÄüAÔPuE´!cm[œ{]̆ګ±öÌ3Ï\¹]·'¿¾{ þ_5°ÐItÆÜiJÏÔiúX¥{æ9'ý)ƒ©ë ÆmQ†xßcâþU¿ÀÇò°ç½L½ôxH ]à…Îßn2µ]gו èµ ßá‡>øÒè¦ëýû°Šñ:$&êǽëé›õ¡{óq ß¡qÙ×¾^&½TGÊ€m:ÏØ$ˆ%1žü]xF,ƒT°cÇŽôä'?¹—PPÊÃvQný΢>·Û¾ëö•céŸÞ-˜Ð¶-±¸‹ Kuµ)B¿CkǵƒX;/=M:ïØôvgWßБVôןøwŸïþPíÈG›DˆÙµkF½@þKRêylxßûR I³þ¦vE;±EŠïE/lTc¶ûü,ù²Þ¸ZÓ‹T:Õ6ÓÍÏfåýi¢d’·¶¾»yu·½ƒíƒ7µí&é¼$%gvAt[êãü >!éºT/¹N<ƒÅ–¹lÌ«r,ZeÞJm^Û&k/fJm[[æÉë_$]Ñ{»8O©¾ODÉeC”'öó1ÉõpMÙ]ζ¨œJº‘çnwL{•¶~Š0 ìùYí<å6ÈÆHWÚ‘h¶<ܵ×)²Êú-=_YÕ¯­žõ©¡úUvv/Q™ÕïóƒxªÿL-_7Ÿ ò.ÝÂN²¾»×ôý¯®þ,HÂò{üñÇ7d¯R³õ­º“Ò®Æý|Èæ7–ö¢çû)V‹¦V齃¨zªqÚKr• ‡ô ¬c"Ï},£©”Ê g,ë~Þ‹ k²4¹1‰áå½#7¨Ç)ÕÀ¼¾=Ö¥zp¦zF·ÓÒF>øàö¡ÞßêI¨ý®h£¼…K¢þxÀ›0o¥˜Pœ^¥0]Ê« t—@1”÷)Ä ã×-…ëœCäeÌÛ³K“…©C^•è¨-î‹bìµ-Á“žô¤†~ÜqÇ5¤šö¢k¬ÜÞ-Õ%A:ÃbžG6R×&œ¥±Ñd¹/ò@7Æ*“ßÒµcÏꦹ‘ÿ!ÔWIÔÇ®0ƽúÕ¯nÁ¥¼—ÒY÷sË蟈y¼QJâ=lœ,è¸t^úŒâÍ%€:惧3âD„Æm€þR¾ÚÏéþöœ0˜†{å ¨–vIJÏqNˆ|.¼0U&´Ÿð`‹ì ÂCÌwŠòîwÏ"˜÷sKùêKÈ=AfÂûîi ¢)ç?8_9ÛõlkR=·Ÿçwx$§ç<'Ťzö̱{ûîÿõuŽTðÌg¦&ÊE· tíN`Îʨ܀ýe§9¤¿ð^M/zÑLgÚ•ö5hO "y ƒh3%)µAçAÞþö¡£¤ºš7¿¥|Õsk¯ëü®8&B¯WÀe¸˜ïáXЗ†óν?"…œc+°pZ²íæ4ó·t­é99½ímoK€¹’ÃD¾¯ý½Ùy`§˜j×oç³ý›Í­›éFÓd‡j§Á¶#…ídÙ@§Ö PàˆˆPjíòÌû{Õyëk¯Ž±e¼å-o‰£.n€ä!À¹]6WÎi¯H8×^{í HݾÇo;ô¯ożÅs¥3¸yEDK" M‘¾²»x-:Ƈ"²à{JÝj3ú4bò‘4¦Èªëw(Ú­!À}d¥©õ Ó8=¢<©«©ý$çÁøsnDizwÌ‘´ŒgCuïi»–ŽÙ™E”¹2HÀ™ØÑ¾.ÿnùØ¼ßÆŸ’ yÞô¦^_#LÕT½néÊyÑŽ | ÿ¼ ÎÔ K ˆ—' ít½à SÄÀ2Œž’Ö:_cÐ7É) ÙÇk;Šzœòò×6úH(^.¥(tܱcÇ\ŒÉ¬K€ê/w/J/e{þdQ6/L Ē軼Á·¬¦ÇúH¾û` TÇ@'ô‘ÉžÉØ(ÿ˜®ÚiXLM‚Ô‹:؈¨{l=8ö=-1"7òŒu¸W½û¨[ï“y…®1ÀK¢/«—ͪkõ×GHÊy”gcÖIô ùÒÖX3•lSzÖ”s&¹·ŽýƒííXïI‹ú¶àºÏ}îÓl•3/‹¼ôŒ­<·¬þ©ÞŒP¸ˆJÞ»Cb¡øõ,„;슶d¬+Ýï¢-Brë>¯þ_5P5P5P5P5°%@°E†öáMÝ'ŒÃ¶xÚÓRzêSS¸Xζ%ˆyàÊÄœðk. œWb~Ú„è=æþƒôÖvHã)&ggvF±ðLÁàž|Û"Tˆ¸ Â޻ǭb¾Ûäù1Ö>á¹Ò:ù³Ÿ^¤ÀþÀºqï›zŽJànÏ-»‰ÆàÙêl^ñLyGˆ¨„aOáe/Ka˜™`,UmTº¶$øã?Náây㱦Ø+zÁgçÿ¥­íôÝe‰4ûÒ³%ˆh¶@Y´~sÕ/;‚ˆlO²È‚ü¢î´›±6ÓW¦œŸú½ßh€]]Ä?éÝõ?»UX³¾kƒÕm%‰Ê뙼kgcǽóïÜDÌÉŽmËZù€M…Í$K¶³ç€ã;wîœl¯Ù윢doâÈÔ¶áØªP˜vëí¬ÇyÒäA¾#lÂlY>¤4Ä€6®ÀÞÇ^ÂfÂæðæ©ÍîTͤö¡œ—œæ²¾·"oˆH4¹ŒÊ£žØlê¶³v=¸F[ij)‹@;%j@ŽpÐnçÒRW<â}sÑÞÕ{;ç ßíþ§!°ç±Û.bWGNweo·í…­ÞÖ•~+Þ.@^³h‹ïó ƒÐÉI«Ývó5íï­¨_8 mÔ_»Œô«ohïô¼o÷]ùVGÿ$ZÛ°#ºgªp\D†ês>Ö¿8€z¶1ì—ÆÀvÿRçÎ!yþý#‚QŸ}žSh7Ãïu7ŽNóÞY¯¯Ø  œ}_gi'­#– µ¯]ä÷Ôô‡@bµÉU{ëˇÁeìš¾û¶Ó1`¬—Z‰¤¡Þ ÀS€ïu,»ö2¥•³ Ö¹x3Æhô¢±×Ñ"â¹S&DòÒ}Ij£Žu!Ý|Èß< }÷þþo‚pô)å©ãØc´ÿ|Θ˜p—D=b¶öM J÷wÊ6¥}•ž!OƤ­`*–òµŠs&‘&Š×‡¡íia6±›*ú€ÅEwÚ½_;{U„ ݬºVo\ Æ>ñ> ÆäÓdºO´cûë}ò“Ÿì;ÝC(0ÎðBß ±E…‰´¼«·’äñI?´ þ\„#¥“CcË„´yê¹ôœ­8·¬þi¬·hE,âmHèÐBÒ{¹[×Ú’w¶ö2$tíó¶ÿ¡ôêñªªªªª-ÑÐÝgˆT SˆÈ4^ýö½uDzüãS (‹ƒcwp 2ºc>›§ô˜Ç “ ”mHbíÐl¡œ¶j‹ùqÑ@TƒÒ}¢ ØN ÖöM$ˆ¡ô‡Žç¨ʰ¥àŠ+RLXú‰ïyÏ,||ßsb>ˆLj¶ˆ}§7æž 0ŒðÌÏ@3=ý‡I&9EË™ëùў麔3<<0›ö5ö̰É5åB(Ì ›d´W |x27QDiD$9ŒöÅ,كؚ.@‘¥§Ùèš<ØÏ"f Õ‘~!:X€„±xJ±ÈšE$0ÿÕ +±žo"8Ý÷·Éî=ÝÿË´iwÒ“ˆ{Éc÷Õóû”xj/Ûö¦ûÝï~é¡}hc3@¾Ù Þš°d³¦üô§?Ýë½|ÔQG¥G>ò‘ÁZÔÒº=;å『ea_ xº#lî+ÉVäA(zûŸç5±5òK_úÒ="¢Ê7{ÈN‹¨Ñ¶QqÏ^“ÓTæS#*òB[^ò’—4ŽPݵ¶ÿÕS&p`iÛ®à)/xÁ šÈ¬@aØDvˆQÊ$zÅñ~´5€¼wŸÓÎË¢¿·*oqúÈŽ[ê`gW´S¿vJÿúBÀ{b.ÐÆ–œc a+A,¡¿’h˹>¥}ÐA¥>ð цýÕý9 úg«vÏ¥ADÔi×ÛÌGcîÆn,šm_žu”%—]û”—‡?üáÝ,‡äC@ `‡kc~Ï8âˆÆvœÛZ÷y[U¿€vŸLâÈõ«¿Â#èZ} ”7΋Zm[ºsH5ö¬±±G¹wíÚÕôõÖÏ X¿ôléyÓ%B×YgÕr;‘ì@}qx¹µ«çcŽ9&ýÎïüÎî¶¥mغ¡]ÏB²ñÓMߘÞ-òÿ/÷˜e?­¦W5ÐÒ€ŽäÅWòs¹:vM+Ù¹ J xNP'îëÀ¹íŸïi{Î*ËÑ~ÖVý¦/ëöÚÍ‹kÓ ·E=b4ŽI_{Ñ–û^NÝ´Ü;…нÏÿîí’ú®SGíIkäo LwgtÁ)Ç7SÚLÔ¡çæÉ…ÉÞT¡@ó˜¸nʸ1–N÷¼tÛ½îù©ÿw'*SïÛŠë,l€£ÂÄĬŸuÛh7ôe¢ù…/|¡™lžp {,æº×·ÿ7É·]ïºÍ¬k‹ ¤+ >Qf{! ‘fº-ú³8²hÂÎãëÏ›!ê™1Á„Y(±Ò{"çÇ5êÈÛ[˜:z…ãA±¯ì¢ãdN«¾—Õ?5,€K¤:ÄPGRy€½¢[b!j?½’ëy^T©¨¨¨¨ØÖ°8òÈ/¾“Šá¢ñ€ðÈ<èØŽ>:…+W ‹`¿'üpjå3}€½y™Hrá Õx[“€ï˜ïñøGšè#¦i»Æò˜F(¨Ö÷îr)Åœ",ð³ýæc®Ùš" DØÙXà÷G0#„'ÖB¤‚¾òË'€Kò/¾c®LÚ $<÷ëöë¯ïÏ¿ ŸûÜûäÍlå—–6 lÖ„<óík`NSÆ–"‹Ô³ˆò¡žKÛ°“Ãèá¬ÊÃ@Þ´HÁHŸéIô ‘/bßèXˆõ߯-̈hH(a×kÚ°ÿH)1ïl„—=Â}vE=‹r¡vE›Ô×”qÙivŸ¥‹0Ô¿vîL鯘õI:’omCÛEdµAí¦-®±¥Âc;Löi_ßý=”Ÿîuþp%¼µúÎÔcû‘xɲënÛZ/[/fðí×£ß[;:m‹õ"g ¶•¶®y2¨¥5´ŽeÃÄ UÄË@ ´ØuÀÏzÖ³Š¶Ê­Ê\¢í©ÍVÝg#±ý+»Õ¡ß®ŽûÒ¤Siª“’°ƒ°Õ¶m(ì*<”Ûdiä´ØÞÙ|8ß›ÕQ¦Qzî”s[•·6A€Íâ™±=¬Áï®®ç€hÛhgYØÎiDàèê1_“¿Eøîw¿ÛDû=:æ…· ""G¶¶AÿOŽÈWl¼Èm;öÕW_Ýœ[„TÐî§òÀÊù†},×ηôO‰w)Ûª–mÇ<•HÓÚ`·½æû·ª~ÛcH»~•±;ißúç›ßüæ=ìùê÷²Ë.KÄç‚ÚãT¾~+¿cFT¥j`k4 “Ly¡™­Œ—þÀÈK©Àp|J9 Üca¶·¦&–óT¦Ð.ö$*‰‰ oÕí*À­)õ¨]t'ÚÚÀÚ$ÀärQñ’òR*úòâØˆ+OÍߢåÊ÷;´#„ö„(ŸÏß©_ CFæÔí6´ã)ÄüŒU|w'À«xÆ:¥iÒ„9j@ÔAnŸ˜¥ c}Î;B=›lZ4MÑ¡Iê”þ¸J]õåSÛ6éµà×~ûÄbÄX{}I‘ „w3ÞX ñ@À’·'âÝtŒ1ž±™bQeü—olùöD{,Ê¢žk¢0Xü0ph;û«XøÝ.Âà2•$ÞÍmR6Ä“¤½¨îêÑJ„áóªT T T T T lk D$¨@·çyì?;*€P^È1÷ˆgSÄ™M‰—ø‰'¦ˆskA4šÄÜ ؆wR:üðȨ´-@x_…ûS 7Ôþ$å0*ªB© áÍÖ1WN{Ü €ç™Ô.†»"-s ;¹OÝÙ}·îu Èüâ§@Âfù’'àªPðᙾò•£toFA~ Ãvä2‘'DúDxúG=jÆÈßëqR¦öôÑ%-tï™òÿFê9Ö; P=D*@0 ÏÃ`h焞_ýêY¹²9{ÐuÌùB¼üå),ñÃdÞ¶»vÍt'/ú’BxEÇBnölu[™õ¶ýQúÖ"ò¤Mª“e§ÙÖJ&ã EPÛ¹sF¥ MÊ‘7"oÊúÊWΈ?ÍÁÖ:Š=¸‚à#B‡6ë·Ö>Ú´u"ÒrG€,Uöo °ŸdbÀÚök64vÂ. •ï±6·Æn§ã ˜5d×¶™ïËßl:@×ÇT¾f[„5ÿ#òËc"¢;¥tûdòЗ¯u8ÆÆÃþÙ[ŒŒìMtîº!½·Ó\ä÷VçM$äç=ïy]hgcãlÆ.ŒDÐŽèñ•˜[°‰hã%=.æN"°iùtÁû>ÝIþóGÏi;(ʃçÚ¦aJZ}é#Jˆ€q÷»ß}°-h÷ç<ç9MV[¤æ~®o^¤ÔÃcÞ9¤»íP¿ò.2ˆúÑ#=tÆNÌ&J@IDmí¥m£T¢H{ ÷3²Í½<æO¯‰-è9§å›#œ¨Úë¾"•T°¯Ôä6,‡Í@<&»U“ 0c’'IÝ딣ÄVÊ×?)ûªx! ¥Ué¼(M4wìØ±-Õ 7í H_A´ €]— -—ô“ÓrÿØä0_Û÷í~/Õ©À}í­ÿ½è¦êÒ{¡JoUâù^ÄöFºüòË‹¬~àh˜§ç1QGS¼×ÇÒYô¼qfÊx²húëxŸ‰Z_¹õlL à…ñ×B´$Æñk®¹¦Ùãj X®ý·™Â¥´Wq®¯Ìù9@bÌsQm¸O°-J0jsø-í7“mò¶ï^mÌÄØx¼™¢®• ñäþ¢ðà™·¿)£qÊûÆ"ìQaøä9±èBl3Ë¿ŠgY Þóž÷,’ èX[ú.{W`öÛã>‡D;©[ i§¯¨¨¨Øv°ýSž’‚­ÊÊ8-ûÞ“¼äçïzWŠI)w\JOú pž–ÊøU1/K§Ÿ>‹p9ÓnA4й æ>½ïù^ðÖÅ@ÐØÊ+&`3Ð=æba='F›˜Hì}Ïœ–<â{3Ûs€ œàÊo»üÙ?ú£á–±fÝK+D+ mRAxw6õ·× q Ö]±¨×}ç ‚eóÚÊS¬C7$­g‹RÔD‹¡ù"Éߘšíè¹-ôá³cÇìöÕ¯ô­Ãc½²;j‚ôÚivë±ý,ºT¯yû„ö¹öïU¤™Ó—ÿ!]у±Bûo ò½¾åM[€Ø¡ø5u`‹€ n’”ž*‹L§¦=vIq 5~£–ŒúVûoð +ˆ¶‹]I„ìœÚ>×µ®!H3ö.,‰2—DQfß&Â¥~,m îE/¥üL9g D(°'Öï]"Äï"õ‰zûØÇF 'Sòµ]¯1fµVz¯j"d©[dMÔ着ªªýFÖ ¼à_ÿú“¬qP½­@60Hýº×¥tÚi)6âí¸Û÷MùÍ[[õØ7˜å{êîŠ.€ 0$cà¾-hjBÎȧFZp2FϺ±É ÀY¸ì. :”Ͼãao÷.¡Âõò`«žá}‘rš"&vE¤7d{@.±ÍE ¤ÏiËÀ1:_2ú½Œz^÷ü®Ú!H¤ƒ‚`[«6øß½X9µ5‘9Juy+ÏÝŽ ê ®l ¢]ê%cçΉÝkò“ám$º×ýo ýD¸©mZŸM#ÖvUªh(úøˆXÃ9cžõõ7cÛÀ!;_[ó:¼xî}£ÿôåS@Ìm?kòÐÎϺýælÓµÝpÒçfæ«ò†D ’ÆBAÖ€¿«K¸PˆÎ×w¿çéWí{ÙÀúôšòÜvZ~+ûÉ'ŸÜl1…Pày@ê^ïù"¤9\õå{3ÚÞ"õk ä‰n=!tÇ7:ÉòµˆÆ¥.ºvÔGÆvLS 9-ϵoìüËØRk‘úÎi¯ÛwÌDªT l·™à% ÊÙËrŒy6oI2H\\¤ÉX/¯òÜÇò^àÝsÝÿ ÒBV›œíKBÂÄx±”„÷¼ æv@ýUBØdwŸs·x¹L‰@@ŸS¶ä舗 v6FJ0¡è†7’¿î£ïÉ__z‹“‹¦'>ñ‰Í¾m¥4­˜×&PB„•DºS& Æ„A&*y¥çtϙԚÜ>0Œ‰&BUnÔÝc{RÚ­Ô¶½/„tÿr„?ÅB.‰t»} ïz}B[ë.<ú®rlj]+çO¢–(Ú+ß‹[%Æ“ìû…ØXùí0èŠ:òWá}6Ï$ÛXdkŒO„× âXH³­*ï*Ÿkbì@¾)½ƒ½S,–ô sz³xó-ó‹²*UUUUUûŒ€ráuÔ€ø1¿k¼ÿcí4Y€.¶DRc¸>¥ˆq: áä[D8'üÁÌÂÎ÷Øv'y·»¥tûÛ§ôýï÷ïÿhæµ<$ò·h…Œ¥·>(Û–Kùï»×1u ü÷Òý±¾NÀ[^áC 9BºQG±¦k„~ ú$œWÒ+_9»'Â…oÈ›¼/ýö±eÕs¬k >a7ëQûDr°¥Ã˜Ä\==øÁ)½ó3oþ>â€è"'ð˜ÒñØs¶ê¼-“ºi·}y°EÄÔ-l2DÒˆ¨rƒ$¾çvÙNâ¸ãRxcÝØ¦»×Ôÿ«BÖ„¢r„cÓšGþ&r]pšà<`mûy€ØÞ؈Û@¥½ÙÛÿ·ïY‡<´ó³n¿ÙÕq[ì'¢I°ï,Ë.¹H¹·*oìÊ>ņËEOúŒ©mwâhʶ´Ja²kS¹ ©ÏñC„‚)¶ëvšìe"&° qÒÉ¢¯åc»Õ/Û­H)íòp¨érÙ}³C¶õá[ü [gΉ¨jõÑvºß9<[Üw ýýv„ .‘ Ìw Uô †›öB««)YDuÓªÿW T T T T ¬•bþ‘8`¶%@ôï˜y¬ÏãmÄ·…‚¨o~ólßôE ) G‹XÅú¼ì¾€ý˜ÅË»˜ÔÜ' J 2ƒç."¼¯é`ˆ´ÐN“ç8²ã÷¾×ÞŸlÑ ?9½bŠÞæ@øW¾2¥~4Eh´Y4Ï(•·§©¿7£ž9xÄbPÂÀèc*¹DÈ~:‘ /]ú¹ÃÖÛT¡ž÷ŠjÑVœ>9¥ _OOÆ”>AàE¾XDØ"´u]dÙíq‘üÔ{ÖZlì勨’€ýìm‘Ö‡¨ö=íßÏÏ|æ3{€àœ}D!f‹è®1×!íü¯Ûoݺµµác;›§ÄV-œ“J¶¯U–g«ò¦ uu2¥œ¿„±nûc+Y5©€í‘]®-úݘí¾}}þÁ–6¯À$ØU» :ûþmh»Õï¯Ä;¹«gõ[Òó÷b^Ù-?[Ø{ñPØ6ÁØ&pTåØOèæq(u>þó뜹š·}[3ž’ ×”’xˆ/“TÀ£•Q½d„Ïy2Xy+‡—°|l›ƒ‰} Xö}E%þ|d_Jƒ1¦}mGòÛÿ{l¢‘ÛuŸw§—F ÐÎzY© §5ôme2ßyŸ2•¿±>ÛNw•¿õ½cŽ9¦éÇ¥mLLô=¡ÒMº‡„¦,žLHŒ!À¼*›£íÕbÉ6+ÝEo;êåúë¯ocˆC¢L!hï>›UׯSáÇ´Õ>¢–„ñÔ„´41ÎåÖGžFöWôžÒÇ×mëk>@Ç-¶»@,ø\„pe`[?xŸÓÝ”1l,½ívÚ¢Çû¥´õ‡-„4Ÿ¢$u+–’v깪ªªªm¯À»yüžÒa‡¥{”ÒùçÏÔ>о¯À@˜ 6÷ZWÅœknðN]#„—a^g1g‹Tàžÿ¶ða—á 4d8¶ï|‰ìéšEYbjù…{ö°‡¶,@*P™T`«<ë  ö‚ÈòŽÌ$õ°²§ô'2‹ˆÒÒ!‡L–ÇÊ¿ÌzV/}õ¬ž†ô"@ê!ú¾ü«—ì…?d¯ ¢!qôÝ¿ÎÇb­Ø´ó¡<~ðƒ)6?.÷·|¯6'jIŸh‹úŽï1âP÷þX5í}ਛTýß×Á"+5âyø¢-]àu-ö…Lg»ÈžÙí´×!ó”m+®å5Í9„#›a£âaþΈ(ó©O}ªq átÕu[u~×9o}e_&¸ß—~>Æ.©Ž²Í®ý;_³ß}}“Hþúd_¨_˜âØ»åg;݈ÝÔÚ½_[°Í§åö8”·u?^Ië^CûxþxåêL¼ÜKâ¥Écóè£^Z(^€ÌÅ_܃¥gëèÂÃÀ›a@”ÛkŒTàv`ì>ðôŠW¼b¡Iß@¶ì0°Ö$`[`RÁvŒZû´ó†€ÖÎ;{_Ú F{é sÚÎa>Ú>†s °u ÄëF ¨cõùî¾PÛÙð a{ÖAèT9€çw^1Kú¼É¶ýLJJ^úHcàœv\eó4`‘lBË#{̃ßD ù@dƒ¡Éšãê±@íÝ${³Ä{äãÿxo´}ӻ虱¯¦<уí,Îÿ-¼„, M^yÿûðXÐ?„x36¹E(ƒþ§‡„1±à /lHCy79׿-ªµ‘J^øm4ͺ_½"ÝQ©Ý‰ù‡ù–÷ÐõŒ©b¡mÞ£ªT T T T T ìӲРĸýæ‰ÈÞ§…ùán0TžuÖ,|ócâ¹ûÔÒIJÀȧˆmlés¬L·¦z"䈌Ë9=Ç Ù)\Ú51‡ô ÷aí•%‹úˆ}‡ƒ±;‹,‘Ë—Ïçoeœ#ˆ¸iÂúG8ñfË€ pnš,ZÏ~„ƒ!±õ™´çD™¨-JÝm7Q×%]!˜ˆf0Eô•¡vå~ëH¤yuOïk¾v›¢žzÍzk€¤Ïaƒ]pÈŽ2¥Dúlð][ã:äaJ™¶ò¤‘Ç?þñƒ"[qöªf·à\ÅYòúXßøÃŽžŠ×ÖCÒ­nu« ÕáÔò®sÞúÊ ]÷½}׎H'¢ù°Á³Ï‰Ìæâ£­çz’Žv^²;Ž=kYç9¤tû¦64„Ql·ú•ß®”ì{ìˆ ]±]EWOÝkJÿs˜ê¶3׳ۖòSJsÝÎí­éuËaÍÏ>­ ÏÓ1R% ?aéN9å” ulia) Cò­o}Ë¿E8=èA*\s衇6áªÇƒ•—ÎW\‘Ž:ê¨â³§ž4)®°ÞL¡Káç»ÌÖvØH›åéÛ~öF{±^Æ%¤‚R=Ç °c7$@Lû“• Úˆh2Àà}á ³ýä#rÒ( nov u¬wŠV0U½ò鳨Ì?ô¡”ÞûÞ“ÍYXv| ]ôY«º©@tƒ!áÀm Âé _˜ÒË^–y™yù·Ï·#Rðõ…B½>üá)½ô¥)öÑÛ˜þÛÏ)ý^´žü=†ñÝZ©@d„íH*ÓÕ2Ë4O4ŽÝ•UT lŽú@~OÞ(©€Ý¢Üªvmæë‡ÍÑöÆž‚¨ñ¢½¨±g~!æ(m˜ 0 °d»²•&‡ƒ‡Çû‹-¾¯.6–›=ï^ç¼í™Ó™Ý¾{lÞÿé˜ÝV`‹dvöm[]øtÛù¼ÏXÕõúf,g[Õ~|wÏÉǾ\¿C ¿ˆ}¤€©õ‚¼ÁÛ$†}EÖÛem_Ñr-Ç à’)Þp€]»v5á~œp#´ô\P($ea¨b•Ä úv±Ož—õJ_´‚±½ÁÇÒò¢>¿úÕ¯N§vZ.{ìžeŸÏQ$Jéòzäqº‘¹”þªÎ)aá¤LtÇ@yX„Ïä:$@> câÅ&ü÷7¥?üÃPΣ_$yßN¢~zŒ´»‹sßXäîþ·ùáú  §³ÏN±'Øtqä$…|$¥§?=Eˆ°õÐÇê“îæõ|_äž=µ¿žÿéjY¹ŽuZLÐg¤¥e¥YÓ©X¢Ø<ûÀOÎF}ö©¶ææ$ÐMhÙ}Þ:äaj¹¶ú:!ÙE­|~ÌMØÄº¶ º¥OÎT_üâÓé§Ÿ¯¾³7Ån¹Îy[V½±Ñ©^ð‚¤÷¼ç=m›}Åqö(6yö¤n_Öó—‘»Q·_Jw,Ïûjý®rü¡ë®ôÝk¶Ëÿ•T°]jjÎ'¸<à“J(”̇‚]ÿÉO~²a~Mº©u‘A^øó?‰½ò°°Æ$GRÜŒ‰kJêíû Ö?ýéOÓ9çœÓlÁÐf¶¯úmŸ{î¹Í6 B`û_„Í ÷¼C‡ÄË @qÏ{Þsè’µ;n@—o|ãòÉ”¶¢œ€½‡=ìa½/è\H ß8æZ/6ìR“Á©¢|"öÕ>J˜"ÊLÔ¥­/ K>Õ[_›WÞÆ¶þÐv'–%ˆ=ôzä‘GŽ&iÂwÙe—¥ë×z„lËRåÁNÁ¢Êæjp>e+í xj¬“¼#¤ä-[ è« çRŸ7ñ4wÝþ$ŒÂ÷•$-J×XtÿJ’‰¥kÖõœwÐØ»ÖØUj?æ=È È+Uªªªªªö[ ˜/Üâ)½ä%)¬Ç³ß%e ¬«÷‘í ”ãcK11Þ~D‚¶Þ­KÞø1ê 3¯>c ¼X„¦ô–·¤÷UŽxÐ~f¬Ë#´æì¾X¬­ T”Htv޹Dt‹’¾cŽ.°s%¹éj™dC|ÜãR„Qۛ貌ôkUKÐÀ»5±uã¢ÂVÜ•ÀZ¼ë ½yX´œ›}»3§ Ñ”_ûÚ×6‘ îq{ôFV†3pa#F.°mñFêt¬¬ëœ·±¼O9<ð†7¼¡Á”D'ÐGØ ³hÇ"|p‚b“síܹs÷‡ãÚP[ÏilÆw_¿d'ãÙí›íüì«õ;T'˥ѕ>²U÷šíòÿ6œýmÕÖ|NÕ€å…èEH-‰ OD€ä7¿ùÍtÌ1ÇLòú6п/¾øâÆ»x ˜iPÅüzÙà9&Ç€¼¡4×Îä‡îǼŒKéì/çÔ³Ðìi"f IcE”ø{äöˆqéŽw¼c3¶à}Õ¸ëÚ©iúÒÚh]s…XÓw´9Dà¯6›?H1SÞY}ù[å1‹Xï`ÛM 5!‡LcÆ?ó¨+ˆr'SHY¶Í°PÜnýQáòË/ŒvQPasJ¿2¦•”ciÔóUUUUUûŒ⽘N8!¥Oº È#+÷×Bgž9ÛΡyÏZýàƒS,g‘xX‡&&•)­)½ÿý)< ¶¾8÷1/”ˆÜ‹ªþÓÀo[÷w\Š}(S„L±u cÌx” Àzl_“Ø”žö´ÕnsÑŸûñ£ìH%€?¸1žNûŠ1}Ǻ¬øÌvZëô{LWaßDhÖÉ·~ƒ­½CªT ¬©†¼–9,±IncÅa§qW¬×»¶ŠuÈC7Ÿëþ?;;{Ší¤mÈÖÂNÄñ‹îÙ²°[Šûžð¬á€=m•²Îy[´ÜÚ2ìæë_ÿzC–i§Ã¾…®ï+‡´¦–­›Eÿçñ °+  ÔËu«ÄËŸnmaÐúÐ!˜(‡6¥½À}æÑ%"ÈãÿøI[<˜Tä-5ƼÜåCÛxýë_ŸN<ñÄÐì=òþío»™ jãc/ÌGØÇ¡Åü™œš˜^uÕUm•íõÛ³~øÃ6lÍ#Ž8¢ÉR ‰6jb+OÒ±M@5/,è ¹g¯‡È»LÇ{le¢ïžoGСÛO‡ðxD>Ü|K8g‚þ1=¢ ú$âÇ¡±÷êžð„It÷™è#é?ˆ,ê‘á%áE¤ßWÖ€> ž§ö’+‰~m‘‡>ô¡½zÍiiï"C¢-!ļùÍon"Ò<ò‘œD”š·®Mä½G†$÷mWÄ×{ßi³>Äÿú·±×Gz:tæÝr‹ðº+=cèÙ9n<Ô‹$oW„Q™Ðçæ7¿y1ic‰w½2—DY•­$ôeü- «ë3ÃÿØÇ>¶!.Z8!þÈ×Áat¿o·5ÄŠ[Þò–Íö- ‹HÝú`­Õ{ªªªªöi ˜;Üç>)&)çýEó ï¿kõG‘Ì—‡ò „~Æ3R°ãS {JÈ;f^sîFvíJ±wÜz b>¶0©@a”  ,$m¬ßcÃé“Ôì÷”.ºhVÆ¡¨a;O˜”bÝ‹ÅF5kõ'ìG1Ñ·†EH¥{ô˜'o;‹°€ü̆N KÌË›ö¶põƪÕk€-³kcôÔ!@ljŽD_̶¿ö=l…ìmY‡<´ó³~³SøÀxȳm^yå•MdÖ¶½U]Ø”ÃÛ˜{V-뜷yËþ—­ˆ]‘mª-;ƒLp\ÙÐÙ£úúR¾Þùl³ËǶâ›ÃT·oÊ·_Žåm_©ß¡­^Ø’ÙXAßýì‘ëÐ-Wû¾ÂŒ³}Yý]5°Z :m\C˜"Wž‹Ä ®è˜qßI@à 1¶¶ŸiR#rÀ”0õíûôïz×»6ó{ßûÞö©âoyÍ$ƒ¹O.‡óùÓ7(åÄ7s`¢ EÉ“[]x9ÑÉV‰6`káîÛ’gúô;Ú×LùíEzØa‡5žÐS'f@cÀ>@±¡$ô |þÃØÿ((,µ £É ÀÓ1“#r™†ÒÓ>y rÈ!C—4Çs´×XšÚ%í±ç¨ôéÀd p¯ßÉŸßm¡we[¶ EZ0¹û<ï“‚ö‘~ë·~«[Û—ÒzµÕJ‰`¢úì¥aháB[¿õ­oÝ¥Ú¾>i2 äy¶ ®Ò™:¤zÐÒx¶Ý¼£Ûz۬ߢHØa¥ÔFµ?ºÆ(j÷ÒrnWLKmR[G”ùpx4!ƒx?ëâ˪k¬qmèãÿxqlP.D!ÑöŒÁù}Ì÷1~Ä-8‘€6CèÕ¤¯Í MeýÔó[GRrY¤!÷lý¢OT©¨¨¨¨¨hi Öa àÞ:´ÇÏJb’°Ç¡µø'ÖsM„Xkô BADÅ 43µ÷’4Ž9åJ$æ×±š–4ð?æâƒ¤DõPÖó“b®ÙDb@æF¸Ë]RzúÓS°ùSR,àò•{~ËÃй=¯Üüÿkc>(¶ÊŒõèdQ7A´ öûð-Å-&ïÃç‡Î¨ó©õ>”F÷øñ‰“ÁYgÕ8Aåòd[éTÛu¾w#ß뜷©åâÔÚ Ín÷´ˆ\ľ´™XÌÔ<]Çî̶Ùöõ´ˆl÷úe3vm«ÆÄ’­yLW°²îýúöR"ŸŒ¥»Nç÷É×)g5/û• ÀÀ„§>õ©Í>ç¥=¥»Š1續±îuSÿˆ~øá àÒìLIËüa{XÚ`^)Z¥´ J›91Ù¶¡=ñìæO~€E›™¯nü¯”©¾{¦S.À³vëE4U¼twìØÑDçBiL€‡ú„‰9K]{9e`qì~çõ1 ÛÓÃX¢—hèÓÆDh¿€=«Ô.rzž³ Á~æaÌ«¸Dz‘GÀ¦m^øÂî1‰¢c¥tÞ/Üçˆ(?ïf so}{†6¨Î|ëãê®+Η Ýë÷çÿõ= 4I£$úޱê¾÷½oïäM;´­q{,zˆº´˜@dSßË®ké)ÓQ’áE{YTr»ë¦À†5‹mm‚‡‡‡Ö˜‡ÿ¢yÈ÷ÉKûݦ­{g—åÅ»R=(?£‚oÑ;ô׌õ }^Ä¢±1Åûƒù¨ŸœÏö·>ŠÑϘgŽÒ½Õÿ#¦Ø¢CYép©[Ì£­zmÕ@Õ@Õ@ÕÀ¶Ò@Ì=bA4û,’ñnH1y¾s]=¶ƒ„ µþ|Ç|ºÙ D(è¿syGÙKl? LüXHfÂY`PDûB˜WbÞÙ€ão{[Š…Ú,"A_}™<&‚ Ã$ŒyŸ¿¬ëm]QÒ¡¨_H®›–Á6Xª)&ãý9ÔæÃ¦1¨sýmHè¶ãt0téÇ—•æ"l.kKÙC!õŸªi€ínGôãâ×^söMØšrakè®áÙ×úÒ[‡<Œ•‘=ÃgÝ…. ؾØBÙ›Û6N]‡¯Í*Ó:ç­¤¶+Ž~Ýö,"sv.*Ý¿Nç”áßøÆ^eÇ-J*ÈåÛ®õ+ßl„œÛ¶S‘=žüä'7¶Ã\Æy¾9¢µÓs¯ç°wÎ+ë:þ¬ˆn<¯zêõU³Í·»ÝíÒi§Öxdo…NÃ&N€×¾ÉΔ<¼XN>ù䨆íSnYÊ5^¼f7C h€)žÙ%1X ½¯I®ãç<ç9餓N §ÝW~=a§:è ¾Ó½ÇLf9²‡{0Ý{c!?Ø.dЦ÷¸Ç-Ô¦¦L¶ö‹¼L§ä=lI1&N×^{mÚ%¬gGŒWñS$×I»þx4‘G¥@ÄuWª7m«Ê4 g§Ô>ƒðƒü`0a“h¤áঈɡtWQ×<ÍEʱÆH>%¯ÝkôOyÁA„w½ë]EòM÷þEþêïò¢"jè+&ò×_}C.Ä ÎÑ Jc ‚”­Æ„>E{Av[Tôóî‚rÑ´Vq]‹ž!*ͼ¢íxàóÞV¯¯¨¨¨¨Xo Dd¤ô˜Ç¤ôÌg¦`2Îáyr$ä°Â–AF@í"Ûóäc‘kc~—þ;ù1ŸŒPÐ×ròú­#c²2iƒçxl£lÔáç[ç.`¬Ý /=úˆšÍ÷î­È±Î‹ lëàšüÔcÍßgú²óÿf+ ºœ"—\’b/Ñá+­› †Dˆ¹w¯ nÄyn=.+ÍX4yys¯„Wj»Êm²÷Æz°j`ûi€¾kwíU$áEhkz¤6‡¶XgZ»÷É:ä!çK»v9ö¶Ÿ’]"ß¿ßÊÀVÖu(S¯m‡°­Èë:ç­Oì¸}NŠw¸ÃÛs_:ËQoêÄ=×ÔÔ±àî]¹(©É3·:úΘîóc×µÏ#º‰’áÞ*UUUUUû”ÂÃ,6Nž,¥§<%¥¼ Å>GÓ<¥yù¿îu3€±'ÒØn==ð)B/îþwm~˜'»Àñ1oqtlýlÔÕ iã÷~/¥‹.ê'nðjÍkf †r^ƒ{Õ¨Sˆ$Ê Ð$z•ˆÞ%`{ÒVtQÌåb®±`è\"ÚŒ1tã®lä„Q@IDAT‰íØà躈¬áΆΦXФ˜4Ÿ/¾X€Ÿï;³¬4EnDŠZGŠÎpÞy)ö›ìËE=V5°Oi€}³k‡âD1¶á>÷¹Ï5N6íó쨢$­Á×!9¿òH]bRÁT;ENk+¿Ùqé½-§ºuÝ>¿Y¿×9o] Õù8ÜM§oKî5Sÿ‡ÉpúfD ê×¥4lqÜ%HÀá8W-ÓÆµê—¾8{vûŠ1ÐX¶±JÄgãE[¤ÏªKàj_ã÷P…¿­©©’ ºµWÿßr Ðx/zÑ‹Oîel}…ó Þc]°Ë…_ˆmgºJEønl™reŒÛÝí‰yè²)±ë‡\.¶|¶¹îºXäËEÆœîF¾ÈóŠ<­»ùåüØ­çä˽뜷–Íýì$œP»$‘?§ú—GĬÏDD¦yúÒXÞE8óÌ3›ÒÝzî»IŽÓ̓­39ÓuÛ{Nc_¯_åä`&úiW¶Ñ5N­gi±á"tëä·û·û\·¹§-Îsôé^÷½ï}o¯íÚ÷mÅï5œ o…ê3×M&ÙKZHj°Ð`¶, á›Q q—™´ÑgLF„P¿W°Æ?‹$eYÆ~Ì; ÍG‘žÀšÒä@^ºd_ù†&yùZ¬üÛ¯¾$H‹‚6¥tÛç2elOõö=óüå-tìE ¬)éyžô]›Ûºm¼Äìéþw÷wó&³Çõù%d_v¹ò½hÛFD´ŠrQeôÃîËq‡þQV‹•'=éIMˆíîK2ß:¥N¹ÆókBÉ_À+£ ÆûÆÉ[W¤cÿ·O<±1Õ²D_QÁv Úô˜L)û”kÆž³ŒóSÆ)× å CX7í²»_Uûãf°0T&ŒCBÿ€j:ÛíîY–L©káßF6¬Øî„?çC:Ú6‹þèc¢ë£-[Ä#&ˆÂ1ÍâÔµÚ¿w•öÞ'SÚÔÐ5êxG+lÁ¢/nD§ž,·}ÌÎ;›í’†òÜWÇQì&*2Q‰lÒMÃ{¡Ô††tÐNgÊ5íëçýM߯}}ãcŒµÄÂe³ˆ‰²S/©¨¨¨¨XŽÈm`ÔoÀ1‚A̹ÂÂ:ó䋤@vD×ù.…º7oŠ5BLÌÊÞíË)Íü©Èש€.Î8c,Ç-&H³ôéæ³Ÿ‹ùaCȘÿÉóÝ!/€dÑ$„ÝWl?€fu Œv‰ b£ö]°ÿºëfD¿ßýî®b3’Ht¶¤ϱÅEì?>ñ‰YÝ÷•ÀÖ…K$Éö=bCÇý<ðBú€p:⋾qöÙ³vkë+zC"£uúÇL±7Ùð6!Ú|Dò Vo¹ÍkO%Rþ÷ŠWÌÈȹ®åEtŒ˜Ëî%ËL3ëJ»èÓ•~/Ê…²r¡Wm,Ö4M$ :iÁZQÛA(ð[{•žü#´¸§JÕÀkÀZú!±í 0Œ3F¶ˆsÏ=7šô¿5xÇœuØdÞóž÷4öÌ6Φ(‚o)²à:ä!—Û·µ±5{ÛÆÄƒ£[ÌfŠz9묳ûÛ&rƘ=A¾?ùÉOîµÕûÑ2íÙ뜷eÕ]çn¸á†=lkô ç)9ΰÏ]|ñÅMd\8J»_,#ÿïë·aò)…‹íÈ‘PtR}¹‹‚) 9Íìõ«Œ?l¡ÑÚ¸#;á;ßùÎf»V}o WaÃ¥g6ݶ3lo;uì`çþq Ûíe×®]Må¡ýÜUÿ®¤‚Uk¸¦¿°Å1Âþ;bâ~ôÑG‘þK óQçꆙò €‘½š€Äös<—ùRíˇ#PˆféöVÊÿÍßüMtõÝÓwÌËÌ^7wOLO@$PDúôU¤ ƒd_˜w÷å% ¦$|m´Ýë r¯U†·÷LezìcÛ¼b˜˜SÅKäXÚ@þÍ»ÝD ™pE·^̾Ç&nSŸÝ½NÝ™ˆyä‘ ô刀¢—ôÜM‡Þµo 8augÊ5Ö6ºétÿ×?Ô糂©o±ÁƒZûµúÑFLr€V¢K õ9}TŸW×Å¿ýõ,e–í 0qŠx–±¸Ša8Ê£qaHÚuÄ‹ýÚk¯m؇?úÑæª#éKK¾”Q]Ѿ2%ê†kôã bCW?Úµ ¯(!ë úÓ¡‡¶¹Oì±@ÍyÓx™ …·ˆè›ôaÜúl?‡t×Y|a ª„3[h[L¯¿þúÁô‡Òœ·®õ)“Ee"hú·­üÎmÀwþÈ] K°¢K{çYtÚ"Â"øѕe´;ã¬÷b ½†í?•õ«^{,zôA }õºÈ¸ìuŒX ß8 —-4òˆh?f>}² =õ¥»È1úaôøá8ñBݘ!AV©¨¨¨¨ا4 Œu\,÷I«@ØûìkIkjw ÀÞ}Cüà룢ÇvûúÍþ 8÷~W®¾2A_ûÚ™çz¬!bb5÷ϼÚǶGXvy2á£/¿}Ï3¿?î¸ØÛ=¯ŽÕgÌuc12|‘ÃE0ˆug,Jg!ú¬o‡ ®á"ì1k+Úú©§¦ôýïÏ@î!Ò…²Š@Y#êš¾†îÉ…½#Ö×M»ÊÇú¾Ãa"Âð ·=ÏÑÆ|´;õD´U$žÿúo[–™¦ú|ö³Såf¤€¾rÓ’…ör饳ö¢ÍÜ®´-mƵ~gA’P†*UÛ@÷¾÷½§0vˆ¶ ¡ÀV‰@26]P‹Ç¶ûõyOgûD.6» @÷¾|>¯Cr^ØØíÛUì÷çD¤#6vy¶ú‚žÑO¬«—-ìPÒ÷mKÏûÞ÷¾=Èú½O§êÝuR‘_8ÈG¦©eXç¼M-ÔëØÙµ‡¶½‘s# ŸÛC;­¿ rß#â•:CÖéö‹öµ‹þ–¦úÖ.áÈ;œáDû¼úê«^ÒÍ'ØÒP›Ø_ê—®Ø9ÆîÚµk2íû‚ðÊ1Š-6ÒµAr €Sg¶®sÌ1Ý»{_÷ºüÿmúÚ×¾ÓŒŸÍ‹â‚ƒöÆÎNäíëAhT·ðÆ!œ¥¹x:3´<¡&Y5°A  €~^ì^êÀÖ ®Ã(yfúº ²ý›È ˜>›Ùá¼ÀM0€Ø@Qà¬<ý½d >Êg°‘e÷©dð²4 Eþ}O/“`”gѕɢ|žó³Æ&A€. Í’x–‰ŽzX¥d`èéZN˜û©àTΓ²ûHÇ·üú¦[“³¾ Z¾wßô¦"¨'mAÛ¼û´Ç´quÀÊ¡˜¼tL€BÎigʲ,¡#i#²µQ¤$`dnS^zòä£[tÈ[&¿ÐmIÔôßð†74e•®6gò“Ë,Ò›"tà…{rx ˆBð¯a ÷¼8í_ÿkûžçZ ä&“Eõd’¡_9–É êHº>ò Ø6Že‡2ÉÃÔ¾âZlXcA/ò¢OZôâ9ž»"/&PMòK7&âʫʯ¶â÷¢bLT¿˜ŸÈ#ô¡~Õ½>¬_å63O»‘§\WÀYmÑE»ÿÿ"\¨²hK˪kmüúX(ò,"¨c}ð¸0œ*ÓX×öéÇÇB£4F_,VûHËhwòª.Œ]úú¢Sä† m„NéBù­ä'—À»J:cekOÆ4ó )ã”þë£n}ŒkD_’ù¶p/ËÐÓX¾§žÏïGåÃ0/ = WlT§¥gÔsUUUUU[¢롘k6ŸCßyjïö8>ôO¬×Ò‹_<î±=tÿfgx¸‹„× O™cŽ“°ÏFc.¶‡Ä¼i7è»Ç‰ýÓ}þÐcÔ¯0óˆÅbq﫬ÛÀ´òÆœ·ùä«¥1åyÉ,=â)&£ùÎõüÂz¶ÿþ(…kåp•î3UèÙv±‰cù®˜·7¤›X;5[-”®n÷=ùBpè«“e§i=Ä‚ÓO/ëJäŸy$Ö»£:š'½zmÕÀ 5ÀÎ,·6ggoƒYÖç¶4:q݇ ‡„=ž­2ÛÀº %' T§ØaÖ!YÅìõ@B6’,lL•8Ñ[SÛ¾xÈ!‡,Ý›Ÿí›ˆg:yù`£`WñM¿ê€#ã$ÙN•Ó`“+ÈùºE¾×9o‹”§{öÀÉUúÜ7ØÖvÍ&ÎQŒs—zÐ'؇]ÛŽÊŽ¬Í¨§n?é>oìÿl Ôþä‡M»”¶gv4vWÏ÷¼¾g²k±ÕJkLöõúU~ãÏñÇߨ{E¥h×ý! hЛºÖÇØ ;Œíñ"딓,Ž sªè«¢œ³Ag1þ‡‘GØGÙû´5ypéËñÍ”J*ØLm×gmH:LýÀ–Œà<,}txŸ<Àg€Ø}~û0øoµÑ<+1ƒ=ïmùöÉeqüûxùø(Ç""­ ˆz¦gåA2?ÇwIä È]`RÁfˆ<}ÖD]F™s=™¨"`Ì™°äöí[¹s[Ð>´m$¿W)ž©Ýæ¶ àlçͳ]#¹ÍÊÛ<â>/iåo·Siäþ0Ozòâ…ïcÂ-Ͷ,’¦þëc°ôÓCÎo~F®'ßž£lê)×];SÓ§>l OfñŒüœ|l«¿•9“*è)çW>‰óù÷¢y•F®_‹ª¶ä´}ŽûsT×H!@ZåXv]›0Z˜‰ökBšC×åãÊ­/a¤KJ[«˜Œb¸Þ“q­G–ÕîÚ:ÕÇEݰo#Æ8}ÄGòX²‘~ÓS¤æþ¨?É r|¨_ŸÜ~r¿õ-?%Y–žJϘzÎ⣹$ʨԭJZªçªªªª¶µb-làáÖúÊy gm$ðfßynÌÖVb.{¬Ùä5¥÷¾wæÞ—Ù˜{Å$¨ïÌ DÜÓ€x™ÂfÀ -Ìüé£ï¹¶mxÆ3†£¡Ã_e“ðþ kól»„Ÿ­cÆnÙ²ó<éƒl‹Î” ÔÙ”2ŽeX›-cá;­Ík{Y-Ü—gÑ/:kðâãäûúÕ²Ó¤#ýCÞl €êRt¥p±¾è%º ^OV lØØ_ô¢Å®8g4kHëâ,7|€˜×‡#„5±5{¶‹äëÚß¶2FTn^W·Ï÷ý^‡<È» '"QZÛYÀ<’í~~·½Øý¿,aãb‡È"?>ê‚˺`'‘õÑ—ö Û­Nós¦|¯sÞ¦äê5lE'œpB¼&^·‡½N{à˜#B(»’v®€¼>YØÏŸóœçDÀ›Kà¿Ý·ò5ó|«ÇgÄ܇=I®wu¯]pØÑÚí³>Lí´ÓNkì_%ÛþR¿Y7lÖ¯ˆm™Þô¦75¸W[í~DZpÊÈv+²}Ï#ôŽ%úK»­ä<ô?íö6ϳ6rí£ÒFR©÷V l Ø>Û]2X²™åð¢+½8†òâ…)lu{Pë^ PŽHQeã OŸu”U÷ÁEÛiIW^ü>Ë”Uëa(¯ôÓ^\ ]·.Ç7#¿«Ô‡ü¯²®±ˆíufqÞ'žHüõ{ª¸ëñ¢$®›’®k–¥gi­Ëç賬ñv™z*ÕÛÐ9 Kž ¶ª) Ò2…UªªªªªöI „1=½êU)Ýö¶)â8{M)Q?<ŽÒ‰'¦`ÐÏöLoú‡nÛòãÚ07žÖùÈ0± /£ò·‰ÆH­pÙ¤ó—½,… `Joû,_>ºÇD9;žûÜûÿa*w¯˜ýÞ^z¶ÍEËã´ÿ➣ Á¶<°¥@D½|NÏ­[zˆ~"äx°ßSúã?Ná^·gt†y2' ä ú¦ëyÚ|âAí&¢$#}â õ²ª­×€õ+Âÿ‹£ÏÚ6—§¾(m)•ù:€˜0ì;wîlˆûÒ*ëye3´‡:p–gp°kƒ®go±®ž§¬î›"¼ÚžÐòÐG h§É~ÅCd_õ²ìü­sÞÚzØèozc‡C,xÿûßß8ãä6À~—É&}Ï¡#ä8 OóeˆöiK†—¾ô¥Á}o³µ¨íiOk¢+ŒÙ¾ö—úÍzSÏ;b.€X`ë õÕ֫릌"¬"ñØæw^Bg¨_‘x‘UlŸ‘Ûšs¤û¿ñg+m~–ú·j j j`\èÓL=V5P5P5P5°Ïh€#‚½ØÿðgžÓ´ñžÍ'¶.ï0 6ñaœŸË9¼Û" TŠ8¸{ƒùÀþƒJºŒf¡¹°áu#Öôž{·Çü0¬Ý³sCNÀÍ׿>J’bSÖÐá\û³6`20é5¶‚j"ˆ³ðÆþßHó9™ï;æ·MùŸõ¬™.Þö¶›s§ˆÕÛŸNN Y^\Á¸&¯ÿZG•ãÌ3S„úJ ¡¸DÞQQ. |1±ÿÕ,šBé9ëRÏ킉ÐðÀ¦Y–ÒUW¥tÁ3À<¼G½ñ•5¶$LáiÜxòÓ‚rºç×#â¸ÿì³S:ï¼nžÃIУm&´µ!YEšÚ¯>®!Ï„÷gÓVx#¾÷ÊžuTDRM±m^ìó–‚µ;ÓÙ^þìÀ2ÛÌÐ3êñ}RÖo¢)òHÎÂÃvDZ|þfÇå¥t<ì°ÃbP+{>çëºßl¶è<(ÞiŒqG~؆‘uȃ|ÓoîÏÆ; ÀÈ;¸ÏD] QŒ‘ô¥g{‚ øºaÌvøµ•«È ¶=@r«L&à) $eç{Î"uµYy[f›ïë+"dŒÙٜ׶‘ >ó™Ï¤K.ùÿÙ»(9ª+ÿãW9Fe”3 H(€ADÐ6l0¶×ØÇ»>œóß³ëõŸ¿wm¼kl—`XAȈ¨€åˆÊ9ç,”þó{øµ«»«{zfºgºg¾ïœ¦{º«ê½úTõ éÞwß_Üw0ìžÐ¿ÝiY_%ƒ¨ò°&]jUÈÔ÷Ôßê·¸ß[]O¯UA•sUÁW-»–í k‡ Vð¿¨Üd%Ý#…µ\¼¾Jž‰½×uÍcßKtîÚNÇx¨ X×OË,Z´ÈU¨»Öþ8º¾š¬£ßZÎZÂì/nÓ{ì1·ì‚~ÿ¨ iXS¥p%0÷÷mØ1S}¯RHÁßh €@rýOO¥¹ÿ© äf@&j*þ‡?ü¡Ð?P%ÚŸ÷@Š(°|ùrûÙÏ~ù F˜²ŠÿOÁl.­×–jÓ?6L˜0¡àß_Ëh Cÿ c·iÓ&ø6¯sT@ëøýÛ¿ý[Ò%/ô—]­ÿ÷ fo–EfsŽÒ2l*„À‹/¾èf¾|ûÛß.ˆ)Þ_!Ι“¬ *ç\(_ugÿ*o6ož¬ï÷u SÁz³ŒU€°àô\2Âe—}œV™þâü¡“z¬» –+ˆYðÉ.(žj°VÁ|Ä5n­³ªÒºJxи Ôñ ûGâ‚Ò¸.‘bõj³õëÍ6oþú¡ñiA0À ^þúœ•ø ³þÙP>Ke¹¾õïrRŸKl%\b  €b·Ýöõòa·Ø7š=ñÄ×XΫ ”¯ èüYÆ e® ¿*Mh‹‚‰;碬tÍ5ãVç©sW%§‚ŠNîšè3ùi¼’/ô(øs±KHÐŒù‚(N©eÓuްîÝÛº”L£å0víú:ÑEÿP­ûF³ëUm²`¦²õïÿu’ŠÎßß±Ç,ÊÏZ^@ <2/(ìº÷tOÉWÉJ<Ð}§þ m€ä=dâ˜êQ³=5V¹è^\ºôëqËÎ'dÈD¿#ôÐß”´¤g}‡ô½Ð÷[ß›ÂZºî™Âúáór% ›Õ„­å­Y´ L+8©íúû]ºšþÝW êêCË$ªä·×õÐ{úû£ã øêßÔ¿_:2]ãȆ1h‚†ÎYæ æ«Ü½&ÜÉ]A݉u +¸—ì¼U™RI2õæT‚ÙþzÊBýú # –kÙ_ð;TÁFÝò×ñ”¼ €¦fHë7híûMå9ÓcKç=ï'óèzhÜJ¸PÐ9ÕJ £ê:èßÙtOèšî*øÿ©Ž§{@  .+(¬cê;á›®•ªIêð÷Oaýj¢ˆþ½&˜D¤*ÿ¯ ²Ž®¹š¾:¦î‰õ¶Ó}á¿£þû©{U÷ƒ‚ÏÉîS?Öàs.]_]}Ou=4£_ß}ƒç”Êk·ªµ¨"ˆ–×ï@]Cý>Ð{òÔý#cý[­ú’¯îƒt5ÿý£{M¿‹õž*Ñ*þ¦ß?ú¾§³ÏTÇNRAªRl‡@8^ð—ÐgŸ}Öe¿%¢PÖð‚¬lesõR‰ŽÉû €@EX¹r¥+_v,ÉŒ9ýAQÙѬk«?8Öôi•-L–Ùªcèw·2ßU>­4þÒYظù¼dú å´‚R¿ZSJÔô‘Ñ£G»õøøv"%ÞG b TP1¯{…;k%lU¢^ëÿ™zVPFA=´WP»¤åul|a§¬Ž½0þÿíþX ¾€=†ÎYA|ÿì¥1é|slß…CQ’ ü5¦‚0uãÓ¸ÔÔúÇùT‚µ_ïÿ_]·®»¿ÞêCÇô}èYAöâ\ól»Î±ŸK q÷¼¿tîJØ(‰sl¿þgYëúþûæû-ª{&Ž©ñú{E^¯î½§‡³Ì4nÿðçY”gOç ‡?w݃4 ÐßóàÔÌÚTgárÈ„«/võ¬@]°_õ­Í™þûdYÁ÷¯ó×Cç­;ѹ§Úü¾²*É¿»ø±¯‡Ž§‡JrìTÏ%Ñv™›Ž¼÷¡°÷u ] 5]ÇâÞ»þ\u,}?ü=¡*‰®¿´­…µT’ ü14ÿÐ9j ê#Ùxü¾©>ûsÖ³ÎÅ÷“Ž{/Û®oÐDcÓ2(þúïC»Œ‹{ûIô:èîûÖw=•ЉŽYÒ÷ù“JIÙ " ì,•YJÖ”‘¥õš2ù‹4Yÿ|†䪀ûÊ*O–T `ñŒ3lóæÍ6pà@W¶^Ù©ÊÕ_f•u­DeL¯)(³«m•I¯¤°dM C JÈ&ú‹O²}ù,ûTšqþüùî}’N™Ô,}LˆÏ@ʵ€þ17³‰’Zù dÁ?<–¸ùcøçâPAËâ.}Ÿþ¹8}¶Æ¥ß™hºfvL_6éðñÇðÏé¯Î_ #z”EÓw.Ýþ™8¦l2}¯xÿtþnðÇä¹B”æßÝÕWiövËz éè?Õ@rØùßKÇX‚ÇKçëLŽMÇNG+iR‡CqÎ5]÷€CðYAf=2ÙŠsΩŽ'Û®opÜ™<ï`?‰^—uÿaãÊìÖ#ï!€@Î ¨¬ËªU«\y­Dƒ×ÿ”˜R)e €@Ñ|€WåÊ’5•ºZ»v­mÙ²Å&Nœèþrï³ÑƒÙ«ú½­$½—¬©ÜÚ€‚2·Zû‹–ûºÞ» Êï)£=YÓ_fU¦±GÉ6ã3@@@@@À TÀ€… (05wîÜHy °4˶_¿~Që…mÇ{ €ñZ‡KÕfÏžíÖe‹ßâoï(p¬ªz”¤©ºfªßyç–ÊhÆRIN€}ã´ÞÚ’%K ½7´ô ”TBC@@@@ (|ñŽÂŽÀç Pî´&Ïæ‚rÛÉš_ë;Ù6|† . rV]»vµ{î¹Ç-g¾UúÞÕr5W]u•ýà?°fÍš¥ïÀ©L8`Ÿþy¡cð•1 Ý @@@@@*p €@¡šÉ8fÌWj[ÉgÏžìS­Z5kß¾½=Ú:wîyŸ €EÐïÚk¯½¶`yßÚöòË/Û¶mÛŠv€¶ÖR5-[¶t¿ÓÕWÆ – -X_•–ó~iŒíÛ·'=¿ôA·nÝ’nLJ € € € € €€ ©ÀKðŒ Tûºë®s¥¹µN·gΜ1%è3=ÓºÞ4@â ¨,ýСC]²ÖÌ™3mêÔ©¶sçÎâð¯{ªB«V­ìšk®±aƹêµjÕ*ñq9@ö=zÔV¯^mZ#Y«W¯žõéӇ劒!ñ € € € €D ŒâàH$ RÙzøváÂ7»•®^„g@ =Õ«W·víÚ¹ÀÿÈ‘#mãÆ¶téR0V‚Á‘#GìâÅ‹I;Ólôüü|kÛ¶­uìØÑ.¿ürëÒ¥‹©‚~—ësZùÐuÕRz>}útÜÉéš7mÚÔFŒa£FŠûœ7@@@@@D$$’á}H*@@*)"€%P–*ÀèѤIëÝ»·«£ågŽ?nû÷ï·“'Oºà±ÈJ2P唵f£kiU”Q’‚zM+¿J";v¬ 2ÄvïÞmZáܹsîºëžÐýРAwP¥¢üÞœ €Y#À[Ys) € €é © Š@È€’‚ —\r‰µiÓÆ%(™ÀWŽQ÷JFÐRjþÙýÀʽ€®}^^ž«FѺuëÈý¡W" ”{N@²C Q#+X{Ëlóf³={¬à'WAÒ¬]½dÏþí=^!€ €8M ÑÄ¡`SuJþ­/(Âë² © ,Ôé@(¦€‚ÇU«òG¸bò•ûݸ?Êý%æ@È ýyõ±Ç̾ÿ}³¬ Ü–2`­ ÒL zè5 @@ J@“Eþó?ÿÓöíÛggΜqHš7oî–:Ú(eþEº”Áé@@@@r/P¿¾™ÿ0(±à¯•µÊýùs‚ € €@14™¨E‹¦êªRJõÉb ²KFH*È+E@@@@’¸@@¢ —8-Úžl@æ*gîÐ@@@@@@@rY€¤‚\¾zŒ@@@@@@@ TA\ € € € € € € €@. TËW±#€ € € € € € € A’ 2ˆË¡@@@@@@@Èe’ rùê1v@@@@@@@2(@RAq94 € € € € € € €¹,@RA._=ÆŽ € € € € € € €@H*È .‡F@@@@@@@ —H*Èå«ÇØ@@@@@@@È @Õ ›C#€ € € €d±À©S§lÛ¶m¶víZÛ±c‡íÚµË €@ºNž<é’×öìÙc•*U2%T©RÅ=W«VÍš6mj½zõ²«®ºÊ%¶Õ¨Q#]]s@(¡I%dw@@@@ Û.^¼è*L›6Í%( £*.\p3C;wîlmÛ¶µ-ZX£FÜ R%Ô¯_?ÛOñ!€äˆÀ5×\c={ötÕpT­`ïÞ½.É`Æ .Émݺu¶iÓ&ûøãÝÿ“®¿þz—`P¯^½9C†‰ €@ù © ü^[Î @@@pÉ“'O¶O?ýÔpT‘@ ƒ¶>}ú¸¤ÍÕ,QÍÕC3H+W®Œ €i¨U«–K^S¢›¾BŽžOŸ>m[¶l±yóæÙçŸn+W®´õë×Û|`£F²¡C‡ZݺuÓ6„ €E © h^l € € €ä„À‰'ì³Ï>³I“&ÙÆ]’@ïÞ½íÆotkWk=ëš5k’<W“A"€åC@Ikz¨)‰Í/q jª”Ó½{w7nœ-X°À%èÿ_O=õ”K4¸ûî»­k×®. ®|hp €äŽI¹s­) € € € ’À¶mÛlâĉ6cÆ ÓÖZ£úÖ[ouÁÍôÔ:Ö4@²I@ÿoÊËËs#FØ AƒÜ’=&L°Å‹›–IPÂÁðáÃMKôÐ@@ ôødéYÓ € € € Q .ØÒ¥Kmüøñ¶|ùrkܸ±Ýu×]®l´f€j‰ €Ù.  z(@‰qJ”›>}º½øâ‹.¹à›ßü¦µlÙ2ÛOƒñ!€ PnH*(7—’A@@@Š,pþüyWúõ×_wË\vÙenFgÏž=Ý2¾ÜtE6âÜ@rK@Ëô´nÝÚ|ðAëܹ³ýïÿþ¯«ÂsôèQ{à¬]»v‘årëÌ- €¹%@RAn]/F‹ € € €Ä (¡`æÌ™öÚk¯ÙŽ;lذavçwZ›6mXê N‹7@rI råÊnI„ë®»ÎZ´haO?ý´[áÔ©SöÈ#X‡H,È¥ ÊX@rR rNŽšA#€ € € €8-y0wî\{óÍ7m×®]6räHSYhÍÞÔúÔ4@ʃ€–CèÑ£‡=úè£ÖµkW[µj•½ð ¶eË–òpzœ €Y-@RAV_‡ € € €$X¶l™M˜0ÁU4‹sܸqniÍì¤!€ Pž”,×±cGW¡@ÏK–,1-û³{÷îòtšœ  €Y'Àß.³î’0 @@@@ 5mÛ¶ÙäÉ“ÝlÍ!C†ØwÜaÍ›7§ tj|l… ƒUªT±öíÛÛC=d­Zµ²Y³fÙŒ3ìÌ™39x6 @Ü © 7®£D@@@¢Nœ8aÓ§O·Ù³g[÷îÝmÔ¨QÖºuk ¢”ø@ < (± [·nvçwZ½zõÜ@›7o6- DC@ô T~SŽˆ € € €d\`ñâÅnvfýúõí†n°ž={Kdœ@²D@K!\sÍ5îqîÜ9{õÕWíØ±cY2:† €@ù © |]OÎ@@@*€ÀŽ;lΜ9¦çAƒ¹‡‚+4@*’@5lìØ±Ö®];[°`ÍŸ?ß¾ú꫊DÀ¹"€ P*$” 3 € € € €é¸xñ¢-[¶Ì-ZäJ?2Ä•~NÏÑ9  €¹%pÉ%—¸%€”\÷öÛoS­ ·.£EÈ’ räB1L@@@@@ªN°téR;yò¤õíÛ×%TªT @*¤€–þ¹êª«¬uëÖ¶qãFW±àÌ™3Ò‚“F@ S$dJ–ã"€ € € €Xµj•­X±Â:wîl—_~¹U¯^=½pH@rG víÚ6bÄÓr|ðK¼ËÑ3R@²_€¤‚ì¿FŒ@@@pGµuëÖÙÁƒ­G.±@0»îºë¬Q£Föå—_Ú–-[ìüùó° € €@šH*H$‡A@@@2-°yófÛ°aƒµlÙÒ:uêäfdfºOŽ €@.äççÛW\aZaîܹvúôé\6cD@ 'ªæÄ($ € € € €€›y©Ù—}ûöµvíÚ!‚@Dàĉ6iÒ$ûâ‹/\ÙïZµjÙ€ìÚk¯µzõêE¶ãéؾ}»Íž=Û¶mÛæfƒkvøõ×_omÚ´±*Uª¤£ Ž@±† bÓ¦M³ùóçÛ¸qã¬N:Å:;!€ €@´IÑü„ € € €d¥À©S§l×®]vìØ1kÕª•5kÖ,+ÇÉ ÊF@AÞY³f¹å1ü:d={ö$©Àƒðœ6O?ýÔÞ}÷]Ó=¦¦™ázÜvÛmÖ°aôõÃ(ª@÷îÝ­nݺ.áåÀÖ Awoõ8l €Ñ$D{ð € € € •{÷îuI7¶æÍ›[Õªü³NV^¨2Ô¹sç\©o=û¦D” .øyF m'Ož4Ý_gΜ‰S¥æ3u¿©/%Í,_¾ÜŽ9âfŸ8Ðú÷ïoyyy‘1ð5jXçÎmÏž=¶fÍW=CïÑ@@ düí³d~ì € € €”Š€f\®ŸDïÇmÈJ Y³f.©`×®]¡÷M…Âàd@H“Ii‚ä0 € € € €@&´^¹µk×¶Zµje²+Žd•€ª³T«V-nL 6´êիǽÏ[ AƒV¹re—ˆwáÂ…ŠÁÙ#€ &’ ÒÉa@@@@L h]h=X ®e²oŽ”¥À°aÃìÒK/ub?ŽÞ½{[=H²ò l§OŸvç¨snÑ¢…õéÓǺtéb5jÔ(ô\RÝ@}¬\¹Ò–.]ê®ÝÜ® 4°6mÚØàÁƒÝsµjÕR=dF¶Û²e‹éqòäIÓ}ªïXÓ¦M­J•*Iû[¿~½»tmuOêþÎËË‹ÛgÓ¦M6þ|÷ÝÜ·oŸ»ÿuï´lÙÒú÷ïo;w¶š5kÆíÇ € €@E © "\eÎ@@@@ c Zþîw¿sÁHÓ+Uªd=ö˜ 4ȪW¯îúUà~„ ¶`Á;vì˜)˜¯mýöÚèƒ>p #FŒ°1cƸÀ~Æý×k<Ï>û¬K*ÐXÔhßûÞ÷\0õ¯›¥ôôî»ïÚĉ]0Üëî»ï¶±cǦœ(!—… Úøñã]²ÃÙ³gíüùóÎIŸÉVMd½ö?'à!CìpùDÛèý²êW}ïÝ»×d7}út;tèéœÕ4&5Ž:ç×_ÝÒo¹å»á†\‚…Û¨ÿQÃûï¿ïî;%¸(è®ìW}êZôêÕËî½÷^—РĎÒnJÂùíok6lp÷‚úïÚµ«=úè£Ö®]»„ÃÑ~O<ñD仩 yägW§N·ß_|ao½õ–KæP‚Î?h }®dއzÈ=–Èp@|€ €ä¨@éÿ 0G¡6 € € € €aª6 ­f|û¦× ¬ë³÷Þ{ÏÞyçW™àܹs~“¸gÏ`VàxÅŠ.€©ÙØ™ `jܱcWE€dãŒø_ß8qâDܱô^ªÇRUûܹsíÈ‘#‘ÀnX²J¥)¨¬@q²VVýê>úè#°VUÔO4VÎï3Ïé:¿cºG »·ÂîoŸ8püøq÷½T2*xß°“Q?úN>þøãöðÃÛ€ÒZ-"¬OÞC@²I€¤‚lºŒ@@@@ Ü¨|ýË/¿lŸ~ú©)€™(pÙ2eÕ¯®ñk¯½f“&M2-7ª“Î_Û*Я¥~ó›ßØßÿýßÛå—_î–†HÅgóæÍöä“Ošfè”÷ÇSÀ]ã|á…\‡ú¥ÙÂ|ÂÞKuLún¾úê«öÙgŸ™_R9– ”ü!sUò¸öÚk“.¿‘êXØ@È’ rá*1F@@@@œØ¿¿ý÷ÿ·› œ)¯åmÛ¶ukÔ+à}ðàA[½zµ©:@0°©¦‚Æo¾ù¦}ç;ß±fÍšåÔùe°:WU(ƒ/ý¯ý•  µìûôéã+ä¥åk×®µiÓ¦¹×A3Ù6nÜ82ƒ\û6,á2eÕ¯ÎMmU°P >Øòòò\Y•öïܹ³ ZïÞ½Û6mÚd‹/¶mÛ¶E4~ýüÒK/ÙOúÓ¤Ëø>´¼‚ªhÖ}XBAË–-ÝýY¿~}·ƒ*gñ«òÆÛo¿í–õP€\l2ðIÁs¨Q£†µnÝÚ=´D‰Î]É~)«î7%Tüå/qשC‡¹HÀ˜@@" TPd2v@@@@@ ¹€f¡+ë· p<ØÆŒã‚ÅÕ«W7­Õ®¦Ä­Ù>uêT—\ଠñìÙ³ÝúïMš4)r‰{œlV‚À¼yóÜŒq?Öüü|»÷Þ{Ýlp¸e¥‡‚ír1b„›5?þüHI|y;ÖyÕ©SǪjÕªV­Z5بç²êwΜ96cÆŒ¸„-u¡ðݺus‰ºgtÎ dëÜèÖ}5eÊ”È}¢€·’O–.]j—\r‰ùóŽ:ÑÀï¿ÿ¾­Y³&*yC7hÐÀy:Ԕؠ¾Õ¯–Ðx'L˜à‚쇪$¶TC Ë¬{©êJ^ѹ¨éþ¸êª«ìöÛo·¶ ?ºgä®m.\èî3-9l6lp‰Í›7§ZA†× € PnH*(·—–C@@@(+•T÷MÞûî»Ï®¿þz¼UÀ6ØT…àp\›ƒ• ôZÍöíÛ'œqüðC·@£F\`Ø¿û\Výjæ»fúoß¾=jH jßÿýî:ÇÞÚPç¬sz衇\òÀo¼IJй|ôÑGÖ«W/K6s^3¢™úÁ¦ûó»ßý®]sÍ5qI š½à 7¸jÏ>û¬}þùçœÝú¨ë»nݺÁCäìk¹kÙˆáÇ›¯†{22îÑ£‡ó‰MpY¾|¹íܹ3êZÆîÏÏ € €@y © ¼\IÎ@@@@ «ü p•ëO° X%èUÍ@K›—*q¬~ü<—_ïØ±#næûe—]æf‡v^JÐèØ±c”­f’Ë«°Ùôeѯ– ÐLÿDš’Ty!,á$jÿþ  þ°aìqãÆ‘•”¡d -¥Ö´‡–H8räHÔÇši¯ŽÂ”Ä¡m¾óï¸Yýµk׎:N®ý -5qå•WZ­Zµ’_‰ªXôÖJ Ù³gOdù¤áC@@ ÇH*Èñ Èð@@@@²O@3ÀUÎ^eíS À*p«ö±3¢(_¶l™©t~ykaÁ}-Q³fÍ”NU3èc·U‚`‰û°•E¿ëÖ­3õ{îܹÈt®ýû÷w3å#o¦ðB‰JB 6-!‘è¼µôª]+$hß~ýúiY¼¼<·\@ß¾}M÷x.6-k ª Œ»w’>ôˆ=gÝkJØ !€ €å]€¤‚ò~…9?@@@@RP°¸gÏž…Θ–Khß¾}ÜìiÍ@×L÷òÖ”(qöìÙ¨ÓRU‡`iÿ¨c~ÐRJƶØÀyð3ÿº,úݼys\µ ª «àÇ|Ö}àNv¨:Bìý£¤„nݺ¹õ­qÇ&sǗͯµìA§N¢*\6^U‘Ð~±ç¬ê!Á$‘ÂŽÃç € €@® T«WŽq#€ € € €d­€Ý©ƃ'¡ýºtéè=tèP\ð=¸_®¾VIùØà¸fÔÇÀ_ض͛7 þÆî_ýnÚ´).© E‹q $±c û¹jÕªîѳoªR å ‚ÜJ8ˆQßµk×"WHð}é>MæðŸeûsq¿›ùùù¦$–`“©–ž !€ €å]àoê,ïgÊù!€ € € € ÓÇŸ@IDATõë× ^*X;£?N¥Ð!6iÒ$.@eüO:e âÖ¶lÙ¨O%© ,úݵkWÜò'Ož´%K–¤¼DFÐCI±}ŸdL6Ð>aI)ºÏb:‚Ççu´€¬T± Ø”üBRAP„× € P^H*(¯W–óB@@@ÈI­[>~ü¸ H_¼x1.œ“'ù×A‡%Ìž=Û†jª&¬ÚÃÑ£GmÆŒ¦ÒþÁÖ²eËBgÿ—v¿ <«T~ìÒ Ó¦Msç›<ŸD¯•d{<™„%Ÿh¹‡ØêaÉ+‰úâ}sßÉâ\'ì@@ò @RAy¸Šœ € € € €@¹¨S§N\R’ 0ViûØì¹|âJèÕ«—íܹӔ8¡¦ª o½õ–5lØÐ:tèšD¡J¯¿þº­[·.*°®uïuÌ5j$e)í~5ÞØ P×3l¹‚¤ƒOòa½zõBï-›TP·nÝÐm“ž@@*¨@t½¦ ŠÀi#€ € € € -5kÖ ¡[z=[Æ[’qèœÆŒc­[·Ž:ÌâÅ‹í¿ø…Mœ8Ñ%øÀ»fÜë³_þò—öî»ïº¿£ª;|ãß°¶mÛú·>—v¿gΜÉx™|UvèØ±cÜR Jfð )A°rþÁÏy € €€ R—à@@@@,ЬvD÷ÃÑ2åuf¹–"PRÁÆMÁw5ÂU½à©§ž²çž{ÎÊepòäIWÞ?l-û#FXÿþýã‚êÞ0ö¹4ûU?¬tþÕW_m]»v5}^’V»vm»ì²Ë¬E‹q‡‘›.Ô¿*^øvŸùÏxF@@ (@RAPƒ× € € € €”±€ÊÿŸ={6j*k¯ ¥Ñ‚çÒèoæÌ™¶råÊHBïSãPò€J&HÔ,8p ÝqÇÖ¬Y³D›Å½_šýÖªU+nI ¨]»v6räHÓõ-iSâ@¢–ŸŸï–:. å&–dHt ÞG@¨¸‰ÿ¤YqM8s@@@@ÊL ,© Aƒ%žÍvBaK*(Ð|áÂ…°ÍÓþÞÖ­[m„ ¶k׮ȱ5sÿàÁƒ¶ÿþBÇѾ}{»ë®»lÀ€.0V ràÀ‹ÒîWÕürA[-K Ÿ“%†]ì—õë×K*8qâD\EŒbwÀŽ € €åZ€¤‚r}y99@@@@\Ø·o_ܬ}…KZ"?ÌÁºƒŸi ‚`à;øYº_«Z€–9ðý)IàG?ú‘ii‚Ï?ÿÜ.\hÛ¶msIªÞиqckÙ²¥{téÒÅúõëg5*rP¾,úÕ8å}úôéãáÇãªRD>Lã UB¨V­ZÔ•´á—›ˆú€@@ˆ © „@@@@(+•§_±b…i{°5lØ0cIšEla•‚Ÿ'{]Ô¥Ö¯_o*Ãï[ß¾}Ý:ßo¼Ñ†îJô«z‚Ž­±ê¡Šz.î ÿ²è·mÛ¶V»ví¨¤‚Ò ì‡%¥¬^½Ú:d­[·öü)?ëZõZ§|p6D@È:’ ²î’0 @@@@\ؾ}»-^¼ØÈëÖ­›òé(Ы¥b׺oÒ¤‰Õ¨Q#å㤺a^^^\`^n_–?ly„°coذÁï±cÇÂ>}Ï/q  ¾é<}E% 7iÀ/칬ú½ôÒK­N:ni?®5kÖØÆ]åÞþ³t>]ýq•<¢ëÖ¡C7.ÿ~aϺG,X`E¹Ö…“Ï@@²[ rvÑ!€ € € € {J xå•WìÓO?µ“'O¦|*÷¯ w°©l}=,???øvZ^7kÖ,.YAcWB„f±§Ò´|ÁÓO?mk×®-Òìu_•‚mÙ²e¦`w&[YõÛ­[7SÅ€`;wîœMŸ>ÝöîÝ|;í¯{õêe—\r‰Å&‰|ñÅEòÞºu«=ûì³.Ji¿L@ÈZ’ ²öÒ00@@@@\PYÿçž{ÎSI,˜3gŽKBˆ]ú@Áè-Z¸rÿéöP¢BãÆã*Ìš5ËöíÛWhwªÈðä“Oš’ /JkÕª•Õ«WÏ-eà÷›7ožýêW¿²_|Ñ-!Ãt¯Ëª_«–wÐs°iÖ¿*œ9s&øvZ_«BÂW\—ÔðÙgŸ™ÌƒKP$êX üãÝu‰­¤‘hÞG@(,P>®#g € € € …šÿ§?ýÉ8`·Þzk\P×Y3ÆHWà6¶ :ÔT¾>­R¥J6hÐ We`÷îÝ‘.ôúõ×_·|ÐZ·ny?øBcÖ¬uăK·IöZË9têÔÉõíKé+X­ã­[·ÎÆI¤Ð¶zÔ¬Y3ò¬„UZhÙ²¥)Q cÇŽ)Us(«~e­k©@~°ƒª5üápI£FŠK:HfxêÔ)ÓuØ´i“ 6Ìš6mšpó!C†¸—`% õýÒK/¹ûrðàÁqU+üÁ-ZdÏ?ÿ¼»V$xž@@Š#@RAŹ֜) € € € €@œ8qÂ^}õU›?¾Ý~ûíÖ¿«[·®‰fˆ+ÈüÆoØ–-[âfåkvy¿~ýŠ´æ}QOQÁæÉ“'»ü.\p»«:ÀìÙ³MUÆŒc½{÷ŽìwìØa“&Mrj%Kø}òòòìôéÓEªX0nÜ8;|ø°Íœ9Ó WÓñô&*ÈPAyµà³^W©RާċáÇÛÈ‘#]†ßÎíóŸ²ê·mÛ¶vã7º„ýû÷GF%%•¬^½Úy«:E­Zµ"çÙ°à…î-5¡¥2æÎk{öìqVªfѰaCÓraM‰Ý»w7]¿`å %8<óÌ3î8òkÔ¨Qd÷7Ú{ï½çî×WÐý«ëUÔê‘ó@@ §H*È©ËÅ`@@@@rA@%îÜU°XWÍ× ü_ÿú×n6¸à œ«’‚³úÜlýù)@°­¥^yåûðÃÝ1•¼Q½zu¿YÔsYõ[¹re»ùæ›MFÓ§O$Rhp2ýüóÏMË!èÞÑ="Wù•¬¡à¿î§;wº¤·®‘÷Ð6>Á#êdÿúƒú¾é¦›Üõ\¿~}d?}¬Ä„^xÁ%;è:«"„îMõ{­Uâ[ßú–½óÎ;¦ãÐ@@Ê¿Iåÿs† € € € €¥, ¤‚ï~÷»6eÊW¡àÌ™3.¬ °^k¶¹‚Á> ;<íÿýïßU)H4óúè#7ëÛ÷°õŸuìØÑ~µôÐ¥Ñêׯo?øÁܘ'NœhŒë66˜­¶’´”@›6ml×®]qûöƦM›ì÷¿ÿ½«ˆ €ºš–3¸ë®»Ü2µk×v‰ vë¡„ UHPà{ß¾}nÆ¿–•Ðxýøô¬€ùK/½äü5¶ØVVýúq(iä{ßûž)HÿÖ[o¹% bï ÿ³wñûÆ>ëX·Ür‹uîÜ94"¸½’T•¢Fö?ÿó?¶nÝ:—4ÜÆ÷|O×äºë®³{î¹ÇUOP"D²å%‚ûò@@ ÷H*ÈýkÈ € € € €d¡€‚®š½ÿÀXŸ>}\¹øeË–%œ‘¯à·· Ô_rÉ%…ˆƒ§¬¤€:uê¸@¯®«|¾‚Ç©6ðÌoÕª•½ùæ›.àì—CK ¨À­·Þj½{÷v3äu®Ú_®˜Ö³–H´Ó/¿ü²­\¹2ØÖ>šI?zôh·¯ŽëÏGcð¯õ¬‡î*Ñÿâ‹/ÚÌ™3ݲ~»+VØÞ½{­uëÖn,þʪ_ß¿®U«–[Ž`ðàÁ®BĬY³líÚµ.qÂo“èY×¶K—.6pà@ëÛ·¯["!ÕŠJÐ>r™…½¶/ï!€ €¹.@RA®_AÆ € € € Õ ´ªê€ðÛ¶m³/¿üÒ•è?uê”KPà]³Ì[¶lé‚òª  mQZóæÍíñÇwK ¨t¾Ö5²¼¼¼¢Æ…‡jW^y¥+½¿aÃW@x%-¨úB·nÝܳË Pû¦î/ùK·½ª ¨¿Æ¨ÚÂÔ©SmÕªU®?Æõ×_oz(÷ Eðµ>—•»?ü°8pÀ-Z Ž+Ø­ŠÝ»wwc÷Ç+«~}ÿÁg%4nÜØÆŒã)” ¡ê{öì±£GºŠ 2ÖuTEÝ+J>‘«öÕùëQÔ¦cêZªòÀm·Ýæ’d¥¥(t_ª/Ÿ¸ —Øk­d•ú§r×ZÛk|:D׺¨ã‹Ý¾¸÷wq÷‹í_?÷ïßßžxâ ;|ø°»gu뜋’¸v\ÞC@rA èâÌ…³bŒ € € € €d‘€‚¸z´oßÞÚµk |+H®‡fèëQܦ}äTpW3øýq‹s÷cP¿ú9QÓ2Z¶@‰¾)BUš5kæßJéYý(®ñ*aCyß6oÞìª(!B­¬úõãIô¬= V ÚWbгš·×ëDþú¬(MÇôý*áET¯µúÑ=r饗º±–äÞMeÌŽ¿‹»_ؘô½P2‡OxIv‡íÏ{ € €@. TËW±#€ € € €䔀¾*@™‰ >—ôøÅk*ÁV-K „ÄÖXý üâÚ(@Û·’,‚Ç+«~S½p¼©îWÒí|Ÿþ9Õã¥ó~K¥ÏâöWÜýÂÆ¤cÑ@@Š&PüôçŠ&Åù"€ € € € €@Z<µì–P”ÎvìØáJ÷÷ÑLz_¥@ï—U¿Á1ñ@@\ © ×®ãE@@@@ Ç4hà’‚§±aÃ;zô¨+§|?•×Ë–-³µk׺å üöJ&hÑ¢EÔš÷eÕ¯Ï € €ä¢I¹xÕ3 € € € €9, `½zõ¢–+8yò¤?Þ6oÞ\¤Ä‚M›6Ù /¼`[·néÒ¥‹åççG½WVýF ‚@@È1ª96^†‹ € € € €9.PµjUkÓ¦­^½ÚNœ89›ùóçÛ¾}ûìšk®±«¯¾ÚZ¶liÚ6¶?Þ”LðÁØgŸ}fû÷ï· .D6«U«–Ýzë­Ö¼yóÈ{zQVýF ‚@@È1ø?‘çØ 0\@@@@È=›o¾ÙV¬Xa_~ùedðJظq£«:ðÚk¯YÆ ­~ýúîQ£F ;~ü¸íÝ»×:ä–:8wîœ={6²¿^T¯^Ýî½÷^ëÝ»·{õaÁeÕoì8ø@@\ © W®ãD@@@@  ¨RÁÃ?lO=õ”­_¿>Ri@¾úê+÷8uê”íܹ3²LÂÅ‹ÝÒzkJBøÆ7¾a×_½[^!l›²ê7l,¼‡ € €@.T W‰1"€ € € € PÎ*W®l½zõ²ù—±÷ßß>úè#;xð`ÔYú$‚¨7C~ÈË˳AƒÙwÞimÛ¶ ­Pàw+«~}ÿ<#€ € k$äÚc¼ € € € €Y% òüµk×v³éý ú&Mš˜ÊõÓ’ T©RÅš7on÷ß¿3Æ–/_n .t• vìØa§OŸ=€ß¯cÇŽ.1áŠ+®0o^©R¥Ð}‚oúýK»ßàx € €@®T+WŠq"€ € € €d¥€‚âÿþïÿnû÷ï7•ë¯U«– p×­[7+Ç›mƒR@õêÕÙµ×^kW_}µ?ÞΞ=kÇŽ³“'Oºä-‹ D:uê˜*Ô¬YÓTu jÕªîQÔó*«~‹:N¶G@@ ¬H*(ë+@ÿ € € € €9- Àv½zõ,??ßT©@ÁêTfËçôIg`ð2S=|“©š¯á]ý³ß®$ÏeÕoIÆÌ¾ € €”¦I¥©M_ € € € €åV@Áét»Ë-TNÌ{úç"ìZ¢M}þ¹Dcg@@r\ rŽŸá#€ € € € € € € €@†H*È,‡E@@@@@@@ ×H*Èõ+Èø@@@@@@@ÈI‚å° € € € € € € €äºI¹~? € € € € € € € © C°@@@@@@@\ © ׯ ãG@@@@@@@ C$d–Ã"€ € € € € € € ë$äúdü € € € € € € €dH€¤‚ ÁrX@@@@@@@r]€¤‚\¿‚Œ@@@@@@@ T!X‹ € € € € € € €@® TëWñ#€ € € € € € € !’ 2Ëa@@@@@@@Èu’ rý 2~@@@@@@@2$@RA†`9, € € € € € € €¹.@RA®_AÆ € € € € € € €@†H*È,‡E@@@@@@@ תæú 0~@@@@Ü8}ú´Íž=Û¦M›f‡²êÕ«[÷îÝmäȑ֮]»Ü<)FNàøñã6aÂ[²d‰:uÊjÕªeƒ ²#FXýúõ+œ'Œ €åO€¤‚òwM9#@@@@ '8` ,°ùóç»ñ^¼xÑöíÛgmÛ¶%© '® ƒD lÛ¶Í%HmذÁô{¬R¥JvìØ1ëÛ·/IÜ" € P.H*(—‘“@@@@rOàÂ… vþüyÓ³oúYe) ÙæS§Nu3Ï9buêÔ±«®ºÊlyyye94úÎBý;wî\äw™ ô³ži € €@y © <\EÎ@@@@Ò&ðÑGÙ›o¾i{÷îÌ<_´h‘K(0`€U­Ê?«¦ ›!€ €d½@å¬!D@@@@JQ`ݺuvèСH% UÏ8yò¤mݺÕTÅ€† € €@E © "]mÎ@@@@ 8}út¤”}pã3g΄¾܆× € €”7êt•·+Êù € € € €ÐúàK–,±É“'ÛîÝ»]/íÚµ³áÇ[÷îÝ3Ô+‡E ô4h`ÕªU³¯¾ú*ªó† ZõêÕ£Þã*Š€þðÁؼyóìðáÃnž={ÚèÑ£­I“&…óD@ B TP!/;' € € €]@³·µ®üÔ©SÝ:ó:ÂêÕ«­qãÆ$“=²X`ذaîÞþòË/#• z÷îm=zô°ZµjeñÈ™8~ü¸M™2ÅV¬XùÀªU«ìŠ+® © sì@¬ © +.ƒ@@@@rCàܹsny?Ú³gÏFýìßç\På_ýêW®"lj'¬nݺ֬Y3ËËËËåÓbì”H@• ÂþpáÂ…—@@ ûH*ÈþkÄ@@@@@ ªT©bõêÕsÉê¶R¥JîQŠC +@@²F€¤‚¬¹ @@@@²I råÊÙ4Æ‚ € €@™ð§â2a§S@@@@@@@²_€¤‚ì¿FŒ@@@@@@@2`ùƒ2a§S@@@@ ûNŸ>m»wï¶Ã‡»Áž9sÆöíÛ7pm³téÒ¸÷õF^^ž5oÞÜêÔ©úyªoªßÅ‹ÛÊ•+mÏž=vöìYwì¦M›Z¯^½¬gÏžV¿~ýTµÝúõëmëÖ­öÕW_YÆ ­{÷îîØ~£óçÏÛŠ+ì³Ï>³Í›7Û©S§Üv]ºt±!C†X«V­¬J•*~s÷|áÂ[·níØ±Ã·V­Zî¸5²¢–ÔWk×®u×ââÅ‹®ïnݺYݺu£úL×Ù0ö®‰?×M›6ÙüùómãÆîÞ”m~~¾µlÙÒú÷ïo;w¶š5kúÍ‹ô¼eËÓãäÉ“¦ëשS'Óý{­ýAµ­î£ãÇ»k¬û±k×®V¯^=¿IJÏúÞ}ùå—î>×µ¨]»¶;NãÆ‹|ï¤ÔaÁFêÓÛ¶m¶}ûv;xð U«VÍt϶k×Î.»ì2ëØ±£Õ¨Q#ÕÆn§ï“úÒï ßÿ£s•W³fÍÜ÷Zß1½—î¶wï^ûâ‹/ÜwT¿[Ž9bU«Vu¿CtõûD×N¿¿J«é÷¨îã£GZ¥J•L×[cHõw§~O¬ZµÊ–/_n»vír¿·u]½i‹-¬OŸ>&ÓT¯¡îe]#GMß…'NÄ‘èûªßMaM¿SõÿÝK4@È]’ r÷Ú1r@@@@ £3gδW^yÅöïßéGÁü`S iÊ”)6}úôàÛ‘× Æ~ó›ß´Ûo¿ÝÊ"¤øbçÎöÞ{ïÙŒ3\SIZÕxÓcÒ¤I.ˆ(öÈ#Ø 7Üà‚y 8>ÿüó6oÞ<,ö=gÎûüóÏíg?û™ º;]°`=ûì³.©ÀwàÀö½ï}Ï5¸ma¯ß}÷]›8q¢ úcÝ}÷Ý6vìØb'R$볬ǮÀj²k¢±+ üÖ[o¹ªº.Ák£ûBŸ+€úÐC¹çDÉaÃoû[Û°aC$Xªï£>w­µÿ¡C‡ì¿þë¿lõêÕ‘íõþàÁƒíÁLùšëþ~î¹çì“O>qÉ+þzëûsçwº„7]Mýéz¿ñÆ.À®ï·Õ¯žå¨&;%l\zé¥6zôh6lX‘“Z žøÀU&ðAáè3øú'ù(xüøã»àì€R¾uMÕgðÚj6{"sU%hß¾½ ÌkŒ¾Íš5Ëz÷îm 4Hiƽªa¨ò‚‚þi¶¼ª(8›Î¦ÀþŸÿüg—0£sóÁì°>¼³¾‹O>ù¤Kð3fLÊI-r?~¼©²„L“õ¥þ}ÚVwí¯D‹S¡Cß½_|Ñ”(¥ª>àžè\õûFßù·ß~Û>ýôSûÎw¾ãD”$•îöñÇ»„] ‹fø« J¢J2úè£Ü¾J¾ÒïÌdÍ›ªš†’d¡$'UfI”p£ª…y©Ïd}ËQÇPÿ‰úI6n>C@쨜Ã` € € € €Ù& ÿE™õ6~ͶUP¬(ÇQPYÕ ž~úiW>YBïSAB•kíµ×\u…°eü¶©Hšl_m£€ëo~ó›:uªKH¶½ÿ,lŒaïùíuŸ«š@›6m"³ûõ™úW„¹…5%è¾×xƒíæ›oveðUž?]Mß1Ù¬—k²s ö©ï™ÈkÖ¬±cÇŽ? }­óWe€?ýéO®ŠƒúMµ/@}ÿõ}T \×>˜pá·Iö¬eTuBxýŽH–P<ŽÆ©¾u=~ÿûßÛÂ… “&7÷Mõµ’HT‘!6¡@‰$ßýîwü5®W_}Õ]C-%‘,¨;—¶×R ú^hŠDÉ2J¢(i"€*©õ¸/¹ä’HÐVUXô­f—+P§µßGŽ™¨›¤ï+àöòË/»Òú:ß`S€,”T²D&Ë¢û®È¯u/(¡@Ë(0훪_´nÝÚ=äÖ²±3«u_h&¾f¼k ƒ:øÝÓú¬òü£FrÕ2toú¦„‚iÓ¦YãÆÝÿû¬öëÖ­‹ú~éû§%=Té M‰J˜ Z*èÛ¯_?4h[æ@mYê\x^´h‘sÔ8”hü$›ª¨¯D¾Ë~[¬u=Ú¶mk5r{]§/¿üÒ]Ç`2®¡~7(©@IJZ‚!•j$:?U0Ñò%Ú?¶Õ©SÇõ¯ßú]¢]/·ÿ=çïU½Ð¬~5M¦Z^@IêÃ7¹ÿà?°«¯¾:au %(E®Á¦}eªGçÎÝþJªP…]oUð¿3u~úYcøéOº¬Gß¾}]¥U€ñM×%8^½Ÿì÷`Ïž=Ó¾l‡ Ï € Pz$”ž5=!€ € € €9% ²í ¢ùà¡‚r f)Hè›’îºë.»çž{ü[QÏ ¸¥J’ ôðA+:µ÷رc­OŸ>. ¨>S)v-çÎÙ^+ˆ¦ bMš4‰O*?¨´¾ÔÁ€ë•W^é™ Öil jæ²Î-ÝßTÆXѶQ¢I0¡EI&W]u•«  ´’Zt_h]—^x!®:À† Ü}¡à¿fN§»©ÿ믿ޖ,Yâ‚Ò>(®ïfÉëû¤@¸ÆÛV®\i³gÏvûùÏ´ÝwÜáü:vºšÌ*éœñ¯äŒþð‡.­À´¾·êÓ÷GŒáÆ6yòd{ÿý÷Ý÷ª°ïµùS¦LqI±cWÂÏwÞi-Z´ˆ\;m£ï–‚Ýú~=ÿüó¶lÙ²¨êJøÑ’JPD¢d&ßß„ ÜõˆM(ÐÒZÒ`àÀ¦óõ¾ê_÷úÕ¾º.¾ €–|¢?~qŸ•<¢dÝ“þwŽ¥±<òÈ#‘ëvü9sæØŒ3â ”€¢å ºuëæ–ùð×Лêwš*¹èšh95]_U,P‚ƒ’¶”dl7Þx£»§ýõ»ù¿øET¢™úù×ýWSò@XÓïð¢,}v ÞC@² © ì¯#@@@@²R@Á àâ …D\Œ F÷„|ðJû+ð« –«M›6*Ÿ­ •‚X ÒªïO>ù$Õ1 T°ìšk®)òPTjÝC÷Þ{¯›®™æ2PSP²W¯^.YX`³È`‡8`PX×ü°¡C‡ºëïÂÚI÷…fxëú¨d}0h«ªÖ‘Wp_Ëd¢©ËU1AߌU¥UUPõŽ`SòرK$(AA÷˜fæ§³©•ý=®cë{6`À«_¿~TWºÿÕô¬ óÝwßí¶Õw^ðDMË èœ4>Ø´ßßýÝßÙ­·Þêª6¯]p;Ͳÿ‡ø·l‚’†|‚†¶Q2„,• ÏDMIGJžÐX‚­eË–.p¯¤„0[½§j JbÒ’Zž@‰JªPPX"E°ŸD¯·oßnO=õ”«Èà“6´­O(Ð}ÈV”T¡c›lî¿ÿ~Suÿ;*ø¹®ŸÆÿÐC¹ë¨Š¾Ê%”ô¢{-¶Š‡~ßçk[O¯ÿO¤ëÿÁãò@²Gàë¿eÏx  € € € €.X¬àã·¾õ-ÓÌò°@–‚g Ð2$.H¬™Îš  F¦Ê ¶Ž7䦽ªÁ`Æ££n‰£©öÇv© (¹D¥Ú‡îàaöº6ªn¡ä‚ØùË—/w%îÓ5ãj‰-Klš¬ÍZ£½¸MkÙkªP@+{²UÞ]KQ+h„LS%Ä^;¡÷ìÙcÁÊaû—ä=Ý“JDQ‰þ` õ=qâDÛ¼ys¤JÀÎ;MK ìÝ»7Ò¥‚íªÎ¡YãÁD–È%|¡™û¾¤¿?”úLä÷Û¥ò¬D%O—WÐ~J\Pu€Â’|3´T‚ ‚Mã×ò ±Uü6û÷ïwËÄ~ÿuï´-X.#8ûÞïö¬ítï»ï>÷{&x=öOöžÆòôÓO›’K‚þ©&hŸÏ?ÿû¬K¶&´¤šP q©òÊŽ;¢\UÑB÷Jì²aç|ïŠ+®° ßrU‚c‹ú@@ Â TPáo@@@@ìP0V3´•(jS°O²ØÐ 'H¦ÙÈZ;^뺧:û7Õ±²]ñŒÖ²EY·]×NûÅ–¹?qâDT`¶x#*|/n53^cß”<0uêT·ÜÁ§Ÿ~êJÎk<¾©<ÿ-·Üâ’Yü{é~nÕªU\¥‡3fزeËŠõ}‰߆ â–xhݺµõêÕ+Ê"v¿D?ëúõíÛ7îû­%N•ëׂ®:¶–ÄÐr)©V)H4ž¢¾öìY{饗LKBǤûâûßÿ¾ :4%U¸î¯q(i&6™*•ñ©Dl²MX‹TŽÅ6 € P1H*¨×™³D@@@rB@  uV°ÊákÙ„`ÓLéØÙÒÁϽnÑ¢…+y^X‰ýDûó~út?×€OµécƒÈJ6Q•€L7WÕ Ú”ÛÞÏJt?~¼=óÌ3næypJ(ÐR%)³<^ØëvíÚű5«ÿÉ'Ÿ´·ß~;nÙ‚°c${oÓ¦MvòäɨM´„€®EqÛe—]—T ÇDKYh ±x%6ÄþŽ(îxRÝOK^¼þúë6eÊ”¨¥X|Bª7“N’7ìœô»ª8¿§t)!xŸÉSÕ]Šó;3Ù¸ù @ʇ@Õòqœ € € € €@EPp, “…f'@VÜvEöÏÖs×lìØjZ›¾4’ d¢òô7ß|³[î@pßTÊ>v ݺusKÄ–¥÷û¤ëY• n¸á;pà€{踪  €òË/¿ì*)ÜtÓMvíµ×º¥‚ …AAô]»v™Êý[ØÌøàç…½VyÿØäí£Ùõúž«Qh a³îUÉ$vv~aý–ôó‰'ÚÒ¥KÝxü±Š“P }å[yEÉK–,)V²„Ž{m÷ïßoú~Äþ.õcç@*®I÷Úsæ € € € €@¹ЬðØàq¹99N¤Ø ŽÆN‹}°b쨾œ_´h‘©€ª$¨Å&(Ø}Çw¸òüÅè¦H»è{2zôh[»v­i ?&De-+ðüóÏÛ›o¾iýû÷·o¼ÑUOH% ¯d#¶)) •ýc÷ó?‡UœÐgêOIÁöž>WRAXbBpßt¾Þ±c‡«D;>%šh)T+hLº_Ty!öXÓ¦M3-]Qœ{\ɱÇ;zô¨KÒH§ÇB@ò!@RAù¸Žœ € € € €d¡@5lܸq¦òõ6láˆ#L%þµmi4•ÌÿÑ~d—\r‰½ÿþûQ¥ùUµ@‰šµ®²ý3gδ=z¸D„+®¸"鬸°À·ÎG• JЯS§NhRBXfï‡U(QRAiÎÀWò€ªNlܸ1j)Ýï½÷žÝ{ï½Î?•ëvžÚOçv®©3l›ÒN¼ï!€ €@v TÎÎa1*@@@@@ |4iÒÄ­aŸ¨š†Þ/Îló’è(€|ÿý÷Ûc=f}ûö MhPÀZAúÅ‹Ûã?nO<ñ„mÞ¼Ù-—Ö·ªÄÎ~×vJbP5‘â6ùh‰ƒØc(B`SYÿ°1(1¡4“ 4Öo~ó›Ö«W¯¨~5¶?þØU‰8~üxpè _Ë5¶ºE‹ùAãÆ­cÇŽI“FŠyhvC@r @¥‚rp9@@@@È^I“&¹`|¢ÀðÔ©S­_¿~nf{IfôU@Kh‰¾¿øâ ûðÃmáÂ…Q3ëuLÂõP©ýuëÖÙ£>êö‰ ò+h–8¡àyX ?Õñ*¹!¬ BX¢Æ– ¡ýuœÒL,P¥‚ûî»ÏöíÛgëׯœ®*A¼úê«Ö¼ysç_Ø5×u ;§«¯¾:å¥)"‡¼¨]»¶«”Ñ¢E‹Oy @0#©€»@@@@RˆQ] ]¦­‹\{ÚŠy ëgÍše‡NxU˜0a‚]zé¥Ö¶mÛ„ÛeâáTÖÒ½{÷¶]»v¹ñNž<Ù½&B((¿uëV×’mÚ´‰RX_=zÔΞ=ë*Díâ~ÿØÍU} 6±!Ñä¯1èóÒjJèܹ³[þâ…^°Ý»wGº>tè½øâ‹¦ :u Mð«ÒCX2D»víläÈ‘¦ª%maÇ/é1Ù@ÊË”ŸkÉ™ € € € €d‰@ØlmÍÔh³d¨qÃÈå±ÇL¿qêÔ){ûí·mÛ¶mQ#Q™yămÅŠ6{öl;räHðíR{­à|5\¢À=÷Üc¿ûÝïì‘G±fÍšEA &K—.µO>ù$.Q"Ñ2ÇŽsý¨áà•Ûòóó-v–¢1ø¤‚Øcdúg}Ÿ®»î:6l˜i¼Á¶aÃ?~¼KÞ¾ûZ×FÕ b¿›J¶Ðï%”ôÛ'?#€ €A’ ‚¼F@@@@ aÀÒX= C ^æÊØÓqþé<ÆG}d«V­2•»÷­C‡öãÿØè‚øþ}%¼óÎ;¦@sI– ðÇ+î³f×+P¯ôcÆŒ±Ç{ÌͶ´5¾•+Wº Á~ÐWàþøcÛ¿d3ÝcÇŽ5U*¸ýöÛ­eË–‘ÏôB3ò'Mšd{öì‰z¿¬~PrÁe—]fwÝuW\Å‚íÛ·›–mˆmZÂAý`Se[qÛ²eËâª"´jÕÊêÖ­·l€’"ä;]'Nw%ÞOK|ûÛß¶öíÛGYKJ¼ñƶpáBSòN¢¦e1´LE°éÞJ¶OpÛL½Öï¦Òüý”©óภ€ \€¤‚ä>|Š € € € ðWDcg +˜¤ VY¶²í"åååÅY)èË•§:^ÍZ_¼x±©||iµ\{iÖfÄkÙƒ­[·F\¯ºê*ëÝ»· xwéÒÅ®¾új«_¿~äpú>i ]ó°€}dÃR|¡ïýå—_n ŠÛÞ½{Ý}PVRAXð[• Ž?Ý–,Yb§NŠBAù›nºÉ|@YÁú[o½Õhj5sý­·Þr ‘Ëø…*ÄÞÏ p«€*[Ïž=£%ô™îß¹sçš–A(jS’…‚MvW^y¥5lØ0øväµ´ C°éû§c)I¡¨M•#ŠšÖ‡®³Kn¸á†8£mÛ¶Ù+¯¼b;vìÛÕºuë·îÝk±>¡HÛºÞzïWV 0 @ʯIå÷Úrf € € € €@ÚPŠ…¬€V¶”kOû ó€ hjMúØ ­ŸžJPS¥åŸ|òISÙ÷ÒÖåòØ‹y¹ÒºÛîÝ»íý÷ßûNŒ=Ú:wîµ,Fƒ lÔ¨QÖ´iÓ¨1(À~ó ó, Í6W0ÖE5Y%ØUJ}̘1Ö»wïH™v•=Ÿ4i’+g®™Ù~ åYš ryìeyƒÍ›7Ï4süøñã‘a(À}Ûm·¹™õ Ç6ͦ¿ýöÛÝ÷Eɾ)¨üöÛo»ý4ë>MKj¨R† ´óÙÉæ\÷º|Ö>{žg¯uþùçW³G$"Áý,MòòË/—|°<òÈ#å7ÞùÝå÷8º-£ëœÈë“N:©ÜtÓMå{ßûÞIFù­ÿð‡?¬f¯Èu3çO½å<¸òÊ+«Ä¤ŒM½¥I~È, ¹®d©„Œg»ó-çff€H"@–¤Èõ;É%™a"ËIŒN¨ë¨Óî”ÝzŽç¼ýþ÷¿_n¾ùæ‘Ù8òù¶mÛ*çË.»¬dY Ð\IÍ;-'@€ @€ô\ Áª3Î8〻‡hKAîêM1k­' úÖ[oU¹7VÇ.XÕóÎt¹ÂXd¶‚;w0yîFN°-  Œ& ™;†ìLеõîñÜ ž€t’ ZÎ]nz5ŽMm{·mÆ*?ÝÜežäÖmÆ mƒç­ßIâM‚ð jg¯·ÿ³dF–I=í}ý‰<&pž@sÎÁœo ž?üðÃU¢P‚ÊÙ=öØê·›À¦ÕO{ZÏÉÔw饗Vçv~ëí¶:‘⥗^ª×­³-¤¬³3Õú”$¥<&i&É4 –ç÷×£ƒø9'¯¾úêƒfi׆ü¶ríɬ Û·o? ¬$üá¨x²DIúœúrÝJûâ3ºÏ ¸^N¡]½ã}/ã°~ýú²cÇŽjv‹Ö¥’ø‘ĂԹbÅŠ‘"3~IªÈµà¨œêcœDˆ$µäZ› rýˆo’Ü‘s4Iégú›~ÖÆùNÈT—Ùî1ÉIúÈ8ÕÇæ¸Ô›%.b§ÔçÔ“”¡¡¡fehW¶÷ @€þTпc£e @€ @€¾íM‡_IDATHqݺueË–-exxx¤} *%€”ÀVƒu°)_HPi<Áª‘ÂèIîЭï|N’E½%˜—=f{öì9À«þN‚‰_ÿú׫ÀbîïõÖä¶÷Ú*õ%¡ ÁëŒk½%Xž©úw—v‚Źs?AÙ§žzj¤Œ”µiÓ¦rúé§Wwç·Þµ^×1‘ÇN8¡Jd©©ÏÚ3ûH~×iK~¿Ù[ûR³víÚrýõ×rù|7}¿ýöÛ«sfçHкÞêzsþ'€ž{]gëµ£þ~?õ©OUwÂçNùvwà·~·~¾|ùòòÕ¯~µZ ׫ֲs]Êž6$ÈÞúY}|ýxâ‰'–‹/¾¸ú-Öïuâ1ã™™rHòH’)²¥-I:Ê 0_üâ«€|]_–ɸõÖ[«qüýïÀŒµk¬s½I¹­ã™ëp»~æ;I‚J‚Åá¶$¸d†‡, Ñš‘ºÓþzœ[ë‰sëëÃÕás @ ÿfö_“´ˆ @€ @ _ÌË”åŸþô§Û8j %Hµ`Á‚™ýÚ·n´+wí~ík_«î˜Î]Çí¶V¯|³ø~ë[ߪÉS5ÃC“ÛÞι›ïýùÏ®îøoê?õ%Q ³Œ' Þ¹ =ÿÖ-3üö·¿÷š÷­ÇŽ~¾zõêêÜÊì­[ÎÁ: ;ôÎëÖ-çef]H¢K^ÆØO=ßøÆ7ʾð…êÎùÖòò<õ&ÐºÆ xÇã¶Ûn«ö‰$¤üË“ñÍo~³œwÞyc^‡Fÿsl¶üö.z‰oûÛÕuoP›êf^gŸèÖî¸vï.7Ü´#²:–i÷^ûèrõ:AÃLþtéÒò³Ÿý¬šáa,¯¬EÿÙÏ~¶J&ÈÃiWŽÏžÀa…yÌÝœŠ}¬öOEÛ;9&íÆ²Ý{£û?Ñ6d:úÑ gŸ}v¹ä’Kª±]~»×ëís‡ú½÷Þ;rzÎË,©PßÅÞîØñ¾—Àî5×\Sý.sgüƒï/å9Úu™ ¤' Ÿe8>üáü^êÏõ˜>åwxà 7”O~ò“U<³ä.÷ÑË ´–“v®\¹²Zb!†™éa²ç{ÊJbG’t²<ÀæÍ›Ë_þò—ƒõ­õç9çœsªŒ´£¾F´~§õùDÏ—Öcó<ýûò—¿\î¸ãŽòÜsÏ$td\r^Å*3´nóçϯڗY2ŽÏ›™·¥Y’ ãš~f‰„‰$/¥¿™"׫ýèGÕŒ¹6ÞÒÆ$ÊdY  Ðlïÿ£t³» õ @€ @€@'~ðƒ”;ï¼³ÜrË-Õ]“(S¨Ç'w´fŒúaK)¬ÜI©Óëé°ÄËÝÅ Æ-Y²¤ †µ»“6ÿ[*ÒŸ%¼ÌÝü¹s6eLdK[Þ|óͪ¬Lež`Ve ¶«».;Çešð¬ž»ëãrgm¢Ü’8¯LIþ /TÓ¾§Íic¼Ö¬YS=&xØÚÿ8å{™&>ËK$Ù }dìd[G—Õ˶wrLÒî¬#Ÿ½¶ËÝóI9ÔøN´ úf*ø€SgÆ4çòá‚Ñ£ó:íÌo¢.+mM›sNê\nWÖXïåœJÀ:{Îý$Eä7œ:S‚Æ tç¼ÌcêN;ޤþÔ§ø¤®Ô™ºÿóŸÿTËä·—zã–$€ô9‰¹.j¬Æêc»÷ë>g¬²BÚÑzn¤î,™ $Ô$Ð>ž>Oô|i×¶¸ä”åcr Ëì‡û­×®¿ôk÷îÝ•k®«¹–dür]M2ÒÉ'Ÿ<’DÛì“ÝÒæ\ÃÓæ,¡‘¿©3c™D‚$¡Ä4ãØ©1O[s®}þóŸ¯î¾ûîê<Ïq¾C€Œ-0ù1Œ]¦O @€ @€:,Pê Ø‘‚:Õ´ÛÇå˜ÝRŽï±­åŒçy‚{éoîN°-¹luci>¯ÛX¿:°‡ÿéeÛ;9&iw0ØœˆÝDÛàóÐÐP5Å=ž“ž`SVön“icÚœ=ô€O}µS¾¿ö±ڞϧbKrFúŸ¿Mu¿§¢ê$@€ƒ$ ©`FS_ @€ @€HÐ(Á $ä®ÔN†Ž­XM4W×[}êÇúýÉO9'z>6­ÎÖöv«Ï)÷HÇìHʨûÕÚ×^<ŸªzÇê[f„IRÁáf$ëxï @€ L,åòàã½C€ @€ ÐG²çÌì6 @à`,‘Y(2ÃË‘&y\ºw @€ÀôT0=Ç]¯  @€ @€† $8’éý³þxv p°Àk¯½V-/“%.úiVŸƒ[ê ÐIÍ+-%@€ @€¦±À1ÇS%äÌì6 @à`]»vUK}èCêé²·Ä; @`p$ ÎXê  @€ 0À‹-*Ù_ýõòÏþs€{ªk @`òÏ?ÿ|y÷Ýw˲eËÊìÙ³'_#  @€I#ž @€ @€úW`ñâÅ%ûîÝ»Ëßÿþ÷²ÿþþm¬– @€)xï½÷ʳÏ>[Þyç²fÍš2gΜ)h…*  @€Àà H*¼1Õ# @€ @`,XP–,YRæÍ›W^}õÕjÆ‚ì¦. @€I —7Þx£JÂ*3g LÓ @ EÀ_Ô O  @€ @€ý*0cÆŒrÒI'UûŽ;ÊK/½Ô¯MÕ. 0%>úhÙ·o_9÷Üs«$¼)i„J  @€À H*ÀAÕ% @€ @`0V®\YV¬XQ%dÍèLól#@€JµäA’ öîÝ[6lØPæÏŸ…耤‚A*† @€ ÐmE‹•U«V•£>º<ýôÓåÅ_ìv•Ê'@€x衇ÊîÝ»ËòåËK’ðfÍšÕˆvk$h‚€¤‚&Œ’6 @€ @€ÞȧŸ~zY»vmùë_ÿZ¶mÛVöïßφLkÌÜó›ßü¦¼õÖ[媫®* .œÖ:O€:- © Ó¢Ê#@€ @€tQà”SN)guV•`°eË–2<<ÜÅÚM€ú_àñǯfïY¼xqùÄ'>QæÍ›×ÿÖB Ð I ,M%@€ @€Ìœ9³œsÎ9eݺueëÖ­å‘G)ûöíC€¦¥Àž={ʯýë’Çë®»®{ì±ÓÒA§  @€@7$tSWÙ @€ @€.œ|òÉÕ˜‹-*YCú‰'žèB-Š$@€ý/°iÓ¦²}ûöræ™g– .¸À,ý?dZH€ TÐÀAÓd @€ @`z d¶‚õë×W‰¯¼òJ¹ï¾û,ƒ0½O ½'@€À´xì±ÇÊý÷ß_öîÝ[n¾ùæ’d; ÐyY/R‰ @€ @€Ý8æ˜cÊå—_^víÚU²–ôÐÐPL9þøã»]µò  @€À” ìܹ³Üu×]åoû[Ù¸qcY½zu9ꨣ¦¼]@€QÀLƒ8ªúD€ @€ ¼ÀŒ3ÊŠ+Ê•W^Y²ÂæÍ›K¦€þ÷¿ÿ=ð}×A˜Þ»wï.wÜqGyæ™gª™{.»ì²²`Á‚é¢÷ @ ‹’ ºˆ«h @€ @€@7² ÂÇ?þñríµ×V³ÜsÏ=å—¿ü¥Ä‚n¢+›¦T ßýîwË–-[ʪU«ªe–-[6¥mR9tË úë @€ 0гgÏ._|qÙ·o_¹ûî»ËÏþóêùõ×__,…0ÐC¯s˜vYò [·n-K—.-·Þzk•X$; Ð=IݳU2 @€ @ 'sçέ–AH‚A ~õ«_•×_½|îsŸ«‚-=i„J @€@{ì±rçw–ááárÚi§•Ûn»­¬]»¶uÔQ]¬UÑ @€@$8 @€ @€ 0oÞ¼’5¥.\X~üã—?þñåÕW_-×]w]¹à‚ J>· @€¦ ìÙ³§üâ¿(¿ûÝïÊ?þñrÞyç•[n¹¥œzê©Å MMí%@€¦ H*hêÈi7 @€ @`”Àœ9sʆ ÊâÅ‹« }ôÑòï|§<þøãUrAîìœ1cƨ£¼$@€ý'ðÞ{ïU¿~ò“Ÿ”矾jàM7ÝT>ó™Ï”¡¡!ÏúoÈ´ˆX@RÁ®® @€ @€ÓO Ó@¯ZµªÜ~ûíeÍš5eÓ¦Må(O=õTY¿~}¹úê««ÏM=ýÎ =&@€@Þ}÷ÝòÄOT¿žyæ™òæ›oVË$¡à#ùHY°`„‚& ¤6 @€À@ H*¨áÔ @€ @€@©¦ƒ>î¸ãʵ×^[Î>ûìrÏ=÷”?ýéOå¾ûî+=ôPœ¹ð ËG?úÑr 'Î8i @`J2+ÁÎ;ËÃ?\-ß³k×®²wïÞrüñÇ—7–K/½´z.!nJ‡Iå 0$LãÁ×u @€ @`p²ÌÁ¬Y³ª5§3kÁUW]U6oÞ\%<ùä“eÛ¶meîܹeéÒ¥eíÚµeùòååÄO¬¦”>úè£ËüùóËìÙ³HÏ @ §û÷ï/ï¼óN•,°gÏžòÚk¯•W^y¥ —§Ÿ~ºüë_ÿ*o¿ývùïÿ[ýmºüòËË%—\R>øÁú{ÔÓ‘R8X@RÁÁ&Þ!@€ @€ ŒÀÌ™3«äÓN;­¬\¹²ºãsëÖ­ÕÌ â<ûì³å¹çž+¹û3‰ÙsÌ™gžYn¼ñÆêq`0t„¦Làþûï/wÝuW•Lƒìÿûßÿª=‰I8ÿüóËE]TV¯^].\(™`ÊFKÅ @à@IzxE€ @€H$ Ì™3§,^¼¸\qÅÕÝŸY§zÇŽeûöíåå—_.™n:wŠæýLE€tB IÈ,8Iªf$X¶lY9ãŒ3Ê’%KʼyóªÏó7ËF€ô€¤‚þ -!@€ @€t] 3dV‚ìYþà¸ãŽ+guÖÈÝ¢õÝ£ù 1 LÂ'Y@IDATxìwÐUEšÿÛ Q‰‚ $£d$¨`Âì8AÑ™q’;µêÖæª­­ÚÚ~Uâì¬ëÌfÄ™q ¢¨€J’E$ƒ`Å~|zÏýõ{Þsó¹ñývÕyÏ}ï=¡ûÓ'<ýô·Ÿ>äÛƒÉ)‰€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€$NàÐĨŠ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€xfèB0£D`uX0C×€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€”ˆÀá%:®+" " "P_~ù¥[¿~}άSŠ€ˆ€Bàè£vݺu+dWí#"!ðí·ßºýû÷»?üÐ}ñÅîÐCuÇsŒ;á„ÜQGÙZÿŠ@ýسgÛ»woýP%:#@{€vA)Ò¦M›Ü'Ÿ|â}È!‡8v ÿvØaþ3k–Ã?<µqÄþó‘G™Ú×@D@D@D@ò& aFÞÈ´ƒˆ€ˆ€T/÷ßßÝrË-Õ›AåLD@D ~ýú¹_ýêW ¾Ó?" …øàƒÜüùóÝ‚ Ü{ï½çèH8ýôÓÝ„ Ü™gžé; ;²öÚ"0{öl7uêÔÚÊ´r+" M˜íÚ¥HwÞy§[·n]JˆŠ0°•\4kÖÌ‹XY7oÞÜ [Š{ì±î¸ãŽóËñÇïZ´há·CðʶìÃ1”D@D@D@²0#;#m!" " " " " " "Påèt˜1c†Û²eK*§o¾ù¦ï48õÔS J" " " "ÐÔ|ýõ׎¥˜Dt Ä'žx¢kݺµ;ùä“]Û¶m]»víüg¢”± äPtbHk_z& aF=×®Ê&" " " " "PÕ8àV¯^]Õy¬ÆÌ1ºï”SNñŽájÌŸòTDÉ zX˜¾ùæ?µ SœH˜’ÑgÈ6ÕG}ä—mÛ¶5Ø«C‡>RÙgœá:uêäZµjåZ¶lé#˜5ØXÿˆ€ˆ€ˆ@& aF®|]D@D@D@D@D ²˜óYSPå_mÚ´q7Üpƒ›8qbþ;kÄì۷ϱ¼úê«îCñQ4 ä† âºuëæN:é$Ç*J" " "ÐÔ H˜ÑÔ¯•_D@D@D@D@D bŒ³²Z<‹T[¾¢|¡Ì¢$!Bj³ãÛo¿õ?1ï9á¶ «­$" " " "PZØ`»víò˼yóÜØ±c½˜ºk×®ŠžQZô:ºˆ€ˆ@ 0£*IY¨Oˆ2~õ«_UMá˜V…Õ–¯ª¤ŒT5=z¸qãÆ¹-Z¸O?ýÔÌ$”6£55IUW]ÚÌíÙ³ÇíÝ»7íïú!ž€˜ÅsÑ·" " å%€Xö‰'žpo¿ý¶›üðCÿ9º-SÇ}ñÅþøÙʇhs(‰€ˆ€ˆ@S& aFS®}•]D@D I8ñÄݯ~õ«&YvZD@ÊI`õêÕî–[n)ç)‹>×ÑGíG§3²NID@D ~ T›˜¤~I«d" MíÚ•J‡z¨?5QÅŠIˆ2h¼ýöÛ~Ù½{·Ûµk—Cp±ÿ~¿ð;‚¸„€aˆ’ˆ€ˆ€4ef4åÚWÙE@D@D@D@D@D € Câ½HúHxkFM2’‘ç;ôC9ÄáÈ?òÈ#]³fÍÜá‡î¿K‡†íXÂı9^1!°éTผ?S¢ ŒÞä\ä<uÔQÎ:%ÒíKY!JgÑÅš7oî×Ñí9îÇìöáø¯-Z¸ãŽ;Ο/ºŸþZ&€=Å´]Ñ©»°‹¶lÙâ6lØà¦OŸîöîÝ[ËÅTÞE@D@D ¤2{4Jzj\D@D@D@D@D@D šØô+DÎPÔŒjª™Òæ!£·mÛæG>2’ÿõHBpЪU+ÇÔÇsLZaâ‡öíÛû)ÓŽ?þøT¦ß{ï=÷ꫯ娧3€k’…Ïq Qk×®õ ;vtýû÷oÔ‰îÀ‚ü­Y³Æ‹:Ž=öX¿O=¼è‚mÙ†rlß¾Ýo»yóf÷î»ïúíÉåíСƒëÝ»·ëÚµ«?Ü”D@D@D@D ž `öéÓÇ/ .,ÊÞ«gN*›ˆ€ˆ€@@ ]" " " " " " žs`n¹_¿~ŠœÑ® „ ˆ ¯=gηnÝ:/@(¦èˆ&OžìF•:̪U«Üý÷ßïE©/ ø0zôhìÓN;-voÊ2kÖ,÷Ì3Ϥ~GLrà 7¸ &¤¾‹~`¿Ù³g»gŸ}6õÓW\áEˆ4Ͻ~ýz÷ /¸¥K—ú¹ÖS–-[æÏß«W/wÁ¸Áƒ»N8!k´ŽàúXc¸¾x^FG×X1”]20£ u ¨&LÙ±qãF7cÆ ·xñâ´bƒ|óüÑG9–01EK±éƒ>HEñˆ;eŠN—ÂÿÑï¢û2ßyt>t;Ö[o½åæÏŸïž~úi·cÇŽè®þ'²Bæ\g¹è¢‹\ëÖ­m§/êƒÀĉ‹’ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€d# aF6Bú]D@D@D@D@D@D@êŒÀÎ;Ýc=ææÍ›×@”мysåõGáE Lu´&¬¿ýöÛ$?üpÇb餓NòûÛÿ¬;î8?ÕŠbS¥°”#!Ì@ˆŸçž{ÎObç=òÈ#|(7ÛÁAFÈæwÞq3gÎôÓ® Χv±ãh]û˜ògïÞ½~šEͨýúT D@D@D@D@D@D ”þ¿÷¤”gѱE@D@D@D@D@D@D@ª‚-0õ†EŠ@ð€¨bàÀnРA®S§NŽi<8à#?,_¾Ü­X±Â½ýöÛ©‡rˆëСƒëÒ¥‹C¬À1ºwïîºuëÖ œL=2|øp/ØÅ 6 þAä@‡wTȸ¡\‡Ý»w»GyÄ—á©E‹~ÊŠSO=ÕóaNu"lß¾Ý1 ôŸþyª$ï½÷ž{þùç]ûöíýÔ.啤2 %'À8S§NõÓå0…’ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€¤# aF:2ú^D@D@D@D@D@D@êSm¼ôÒK ¦/a´ÿ%—\â&L˜àN<ñÄ¥>ýôÓÝàÁƒÝ‹/¾è}ôQ·eËÿ;"‹¶mÛºk¯½Ö± B¸„ÈãÇ?þ±(‘M˜ÁïL±òÀ¸%K–¤‡‚sp¾r$Q„+¬­œ}öÙîÜsÏu={ötÍš5Ke1•éÓ§»5kÖ¸/¿ü2õÛ¶mÛܺuë\ÿþýË&*I\D@D@D@D@D@D@D@ª†€„USʈˆ€ˆ€ˆ€ˆ€ˆ€T–ÀÑGíúõë×(âAes¥³'IÑÂWp죎:Ê1"V”açF1zôh1ƒi:>þøcÿÓÚµk½€‚ÈD”H—7¤n„û0eÊ‚ ǵD¤‰¾}ûúH¡ Â~/Åú›o¾ñ‡=ì°Ã\»víÜ…^èÎ?ÿüF¢6‚ßСC½ˆƒðµH$¬_{í5QƒH$J" " " " " " " M“€„M³ÞUjhD€)(î¸ãŽFßë‹ú!Àô ï¿ÿ¾3á%CT ')#ZjÄl·råJ‚ßhlذÁíܹÓOcÝ'Ÿÿ¿úê+ybÑ¢E~ŠÛ÷”SNq#GŽô3ì»r¬’À檫®rãÇwÍ›7O{ZÄ#C† ñláË´&–Á¼þúë®OŸ>~Êû^k¦CàЦST•TD@D@D@D@D@D ø÷7ß|3Ófú­† ` !XrI­Zµr,aÚ·oŸ#ÒE±iÇŽ~Š•­[·¦E„ŒáÇû©T?¼¼cK„0½Ëرc3Š2,³Gy¤ìÑ£Gûʯ¹¯Þxã ·{÷îßë¦C@ÂŒ¦S×*©ˆ€ˆ€ˆ€ˆ€ˆ€d$°iÓ&wË-·¸;ï¼3ãvú±v  ˆŠ(Ž=öXÇ’K"jFt[¢f >(&qŒ_|ÑGãøöÛoý¡ˆXѳgO?ÍÊÉ'Ÿ\ÌáóÞAS·)ƒ)~rMmÛ¶u;vtGqDƒ]víÚåX”ê‹â¢È´iÓ¦¾ ¦Òˆ€ˆ€ˆ€ˆ€ˆ€ˆ€$N ¼ÃMϾ(" " " " " " "+¦ a –\S |ýõ× 6%’Åa‡Öà»|þáx«V­rLa²ÿþÔ®'t’5j”ëÕ«Wê»r}@€‚Àâ„NÈë”::uêäZ·nÝ@ˆp¥XñJ^ÑÆe!0aÂÇ’ëýS–Lé$" " " " " " UI@3ª²Z”)HžÀqÇçX„"D„¿E?mƒ©KÂtâ‰':–BÓ[o½å£e0݇%¦:t¨2dˆãs-%Dш2>ùä“Z*†òš½{÷úéŸX+‰€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ@&fd¢£ßD@D@D@D@D@D@D ŽâøãoP":•G #Sâ÷;v4ˆÁö-[¶ôK¦}Óýöé§Ÿº ¸åË—§ÎOô®]»º‘#GºvíÚ¥Ûµj¿oÞ¼¹kÑ¢EƒüQN„6MKƒõO͘={¶Ÿþ‰µ’ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€d" aF&:úMD@D@D@D@D@D@êˆ"Š6mÚ¸£Ž:*Uª-[¶¸¥K—ºwß}7­pAÁž={üvÛ¶mKíË4&­ZµÊ{Ê€Ðcݺu^˜ñþûï§Ž‰p„)Lúöí›ú®–>0 K˜¾øâ ?•It™p}¨_fÔoݪd" " " " " "£>Úõë×ÏuëÖ-¯ý´qí8öØc}wéÒ%•é/¿üÒ-^¼Ø=ýôÓnûöí>²ƒEÏ`Í4[·nu3gÎt¯¼òŠûúë¯SûvèÐÁuïÞ½Q„ˆÔ>¼óÎ;~ “×^{-µBÁƒûiLˆnÀ€nóæÍ±‰éL¦M›æÞxã /Š8å”S|Ô¦ß`š„«W¯vLÉa‰ÈcÇŽutL?’OB °hÑ"aˆ¥Ž;ú)LN=õTûªæÖ‡z¨c‰¦Ã;Ì!RÅÖ­[ÝêÕ«ÝÎ;S "= Ú`éСƒëÞ½»;ùä“ .â¢eìØ±#uŒæÍ›ûó4È AR?Ôè‡÷Þ{ϱ„ Q3”ê‹ÀÞ½{ýtÏž=ÛM:ÕÝpà nòäÉõS0•DD@D@D@D@D@D qÉxWÏ–(" " " " " " "$„LUN!Âñã¦aà;¦1IJ”ñÕW_¹eË–¹E‹5˜æ£U«VnäÈ‘®gÏžIµècíß¿ßç÷ÕW_uˆ4rMÛ¶mso¾ù¦£¼aBtRM“0oú," " " " " " "PzŠ˜QzÆ:ƒˆ€ˆ€ˆ€ˆ€ˆ€Ô¦ZèׯŸëÖ­[MäW™Ì3X]ØT&›7oö„#<Ò{ì±~º qbüÎÖpk¦Gyùå—}4 û…HC‡uC† qD쨦Ÿ•+WºfÍšùˆDQ¦ôÉ'Ÿ¸õë×7(#Û3L—.]üt0™ö×o" " " " " " " õK@ÂŒú­[•LD@D@D@D@D@ò"€ cÊ”)yí£k‡À 'œàÚµkçš7oîvíÚåzè!/BèÕ«—;õÔS½@âe1þC@XÁ–lbÎA¤Ž—^zÉŸÃ!?;-ã”SNa³ªKˆX–,Yâóuå•Wº3Î8ó‹ËègŸ}æ.sçÎõÓÅ„Û ÊàÞª6ñI˜G}(- 3JËWGš!pàÀ·iÓ&5AQ3j¦ÚrÎ( êµ{÷î.œ¢ãƒ>p‹/ö‹ìðÃ÷B¢Z ¾`!òCË–-ÝÉ'Ÿì£?têÔÉuîÜÙÿØ#]” ¢Hpü}ûöÙáý56`À¿ÿG}”ú>ÓòO>Ê)p`“… :òxÉ%—¸3Ï<Ó30A B„'kÖ¬q?þ¸Û°aCƒ"À¥OŸ>^„Òàý#" " " " " " "ФH˜Ñ¤ª[…¨UŸ~ú©{÷ÝwÝçŸî§  ³ïÄOô¥µZ&å»ú ʸõÖ[ýt&wÜqGõeP9*š@ß¾}¢AlܸÑ?SâúÕW_9ž=éÏ!„ çœsŽCdѦMGT0}ñÅ~z®­01m B^x!ü:ãgÄ={öôâ„#¥Lˆ@(Ë7ß|ãY­^½ÚíØ±ÃO»rÖYgy1 ¿Ãçõ×_wóæÍó¢&‹BÞø½wïÞnذaŽh%JõG€h/Lÿĵ¯$" ¥&À»1%bA„ƒ¼ y¿üñÞ¿¥Î‹Ž/" " " "?Òz2òÏöˆ ãoÅŠîé§Ÿvo½õ–f0Áرcݘ1cäˆðÒ¿Å c9ì\.îhÚ»Ú n2dˆzíÙ³§Ñ´ùä—gÓÒ¥KÝÚµkݸqãÜÕW_툢¨Áâ De4ÂijìÉ'Ÿ ¿Êéó¤I“ÜäÉ“½0-§ Üèè£v:tð‹;wz‘Êûï¿ïŸÃÏ<óŒ;æ˜c|äD.LcM0èØ±£?~¼ëÑ£Gôgý_'&L˜àÎ?ÿü´Ñbꤘ*†ˆ@•àÝ9sæLÿÞ%ZI„‘¼ˆ¥‹\U%ÙW6D@D@D@D É0£É_ " " " "PíÞ~ûm7}út/ΰ¼nݺÕ}øá‡>D~ëÖ­ík­E@D #FؾñÆŽ³°/b :ƒ#˜€‡ÏóçÏ÷Ó“\uÕU~š;®íkÿ»Þ¿¿)LÄ R&¦pAlBd$›7oN 0(ùH—`ˆ¨ã²Ë.s£GöLÓm«ïk›ÀÞ½{ ‘35£¶ëR¹Z @”©Ù³g7xóN?í´Óü4[¼»”D@ª›éG#î%!¨:餓ü=Š›“,E%Ιdþs=VS)g®<´ˆ@vŸ|ò‰{ï½÷ü@ ¶fÚTÚu¥œ>UÂŒìõ¢-D@D@D@D@D ¢èeÄv˜è¥ñÎ;ï4è ·Ñg (xóÍ7ÝÃ?ì/^ì§èàwDŒü¿øâ‹]«V­¼ÎM"]°æ9„Ѻ6lpëÖ­sˆÆ,Îåy§ó bÆE]”µKd œÍÍš5K Â<åógu‹-ü±âöcêÜ&!Ì;ß’‰Œ8>³fÍòeF̸„ó†pò§Ÿ~º›8q¢cÊŽ¡T¿ˆž2uêTÅ…H.J" "PJ´x‡‰éMx3Ý¡„!}ê$@à=÷Üã§ÀæÄFFÈ{íµ×z‘s)r]‰s–¢ÙŽÙTÊ™ƒ~È€E'fª8üøC¾ÿýïû6}©"‘I˜‘{ýhK ÀéÄÈ:£é\¢³…Œ&%(”ŠŒveÄ7×#9Þ²eËB©ýD@D * 0ÇsÏ=ç–/_že‚©.¿ürwòÉ'û|óÌ”q ì˜6mš{íµ×ü³“홲Ä:P˜dРA^DÆ;¼˜D‡Sß¾}Ó>ŸtïÞÝÛ tP!ä8õÔS]ûöí >-b LK²páB?u‹½3°K8öNõ¶mÛºþýû»¡C‡:¦›Rª€LTÿ¥­®~ôÑG~t›‰Ã¸ÿy†•rt[uPn’&À; "ÂDží¼¿tM%MYÇؽ{·[³fMƒÈ7ØÕØâ±ýéà¤sG y$ÑÈ(tëHMìd:P“&Àsµ_¿~®[·nMšC=žçÝÚµkݲeËR‘+pâ27ýøñãóz– 1b„@ İi=8Q|­f X"V`)uBd‚S¡ "N"eÐY‹h¢ØÄTW\q…;ï¼óÜöíÛ}ÙµÌ9pˆó; EÈ(–´öìèâYÆ4CØFt¢óÞºñÆý4BÙ -D !F­?õÔSÞ1è;»k×®UwMÑཆøÐÿóþQ´ #¢µT7BØŸ=ö˜Ÿ’;—{ÿì³Ïö¶ïqÇ—±Ð…ž3ãA«ðǦRÎ*D¯,‰@Í0kX€R?K$Ìi볈€ˆ€ˆ@ÕÀP¢£çå—_nGF H˜Ñ‰þɃŽ}ŒP±D'#£Å«I˜AT˜ .¸À+¸¹æI„Ö;v¬¦1±ŠÓ:tlM™2%‘cé ÕE€N¦1ÙµkW*cˆ'zõêåGƒ¤¾ÌñVˆˆ™0ƒ]éÐb©T¢ƒK)Çe ‹’ˆ@e%ƒh=«V­Je€gÛ¤I“$ÌHч|Ðɉ؇ëÊm‚j»¦FŽé§-Ù´i“ìÁ»˜÷ïr 3¬æ´ú$0cÆ 7gΜ”ÀšRnܸÑG“#¢\¡S÷Õ'-•JD@ª—€„Õ[7Ê™ˆ€ˆ€ˆ@J­bÍ! Ú¤ TÛuEçé˜1c|„"Ç[Ê(%H’Àü|ÇDÎPÔŒ$ÉVþXˆ'˜Ê„QÁ–xŽ ¬(Ô‘‹¸-<Çå¹”) ³[kH’@µÙnI–MǪ j¼¦ˆ˜qóÍ7û)ˆÚÄû–h4”D@ê›ÀÖ­[½ +,%v8S"Î*Ôž§Ï" " ¥' «­ôŒu(šSÐá)1FÑ(u€ yë­·úéLî¸ãŽ [ê§Z#Às–0}ùå—^XAçS¶¹©ÃýøüÙgŸùèˆ=,qŒÖ­[;¢ü(‰@S @Ô¦jÓ¦MS(®Ê("PˆìÇ»VID@D@D@D öH˜Q{u¦‹€ˆ€ˆ€ˆ€ˆ€ˆ@ÉÐI_£DKVà&r`¦à`þiÄV¿L†gÈ!~Äm®â kÖ¬q+V¬pDY±Ä9è,RÄ #¢u½˜0a‚;ÿüóó6Õ;•OD@D@D YD3|ýõ×S/Y¶o×®¢æ­E@D H˜Q•¤,Š€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ@1pÜ"šhÖ¬™#ü9‰ðÇ‹-òS#1o=Óš0uÒ¡‡{ªÏ?ÿ܇OóÍ7ÝÌ™3ÝÚµkSÛ!êèÚµ«;í´ÓRßéƒÔ;½{÷:"g(jF½×¶Ê'" " •#€QõîÝ»Ó 2…ÑÀýô“šÆ¤rõ¢3‹€ˆ@¾$ÌÈ—˜¶(FäÒ Dúæ›oŒÊµL0ê÷ã?¶¬é$:âˆ#á^sMtRq)“Ý_…^SÑóéÿ%Àû†¹é;vìè6nܘ‚swÚ´inݺunðàÁ®sçÎþ>äžäùÂs“g&÷ê»ï¾ë–/_î–.]ê?§rð¢Q£F¹ž={†_ë³Ô5gžyÆ=ðÀnòäÉîú믯ë²V²pØ f—“l7³åÂ|ñ}:ûg¶;ÏÂl […cñìÃnc!ar,l0l–Lb¶lç!¿,øàÿðÌã]Pès·˜¨ " "P‹$̨ÅZSžE@D@D  ÀÙºjÕ*·uëV_Z–tEήY³fE¿öÿã,¤êì³ÏŽýݾÄ…Óã¿óÎ;>¬û¶mÛ|ƒ1Î":áqzx≮S§N~TÂgœáN>ùä¼aœk×®]^òBŽK'Øðáý3“rîÛ·ÏmذÁ-[¶Ì‡ªätzõêÕË1ŸßòŸôš—«Ží|¬±)¨?ÊÀµÅBÝZ›—{”ëˆNhÚ\íÛ·÷‘½2µñÂãë³Ô3ž»DéR¨]¹[ɵ[Få\D@D@D  ¸óÎ;ÝŽ;2æÎo~ó›ØmpŽâÌ0`@ltéŒ6À)„ÇN¢lÎuœ¨t\ 4ÈwDuïÞÝ; sqÆâL[²d‰»÷Þ{SyƉ‰€çŽç^xÁMŸ>=å|¶ q3¢‡ñ­·Þj_'ºÆ9‡PÏ=÷œãœpÊ”—PæY?묳¼£ ÇY&0eÔàçŸÞ½üò˾®âòA^ç :Ô]sÍ5¾ÎÓCÜð?ÿó?^tw,ûŽë ÝuEÙ('"™¨Ó9S™Š©_Xp}Þu×]–E8q¢»ùæ›Sßåò¡œuL~¸~¸Oøpm/\¸0åæ9÷'œÌ”!N¥ò #ç>׫Rý@pÁ³š÷÷#ïž[aâyÃ’-ñγÂqãÆ¹1cÆøŽ“lûéwÈ—À+¯¼âî¿ÿþØŽs;öÆOùd£Ž2;.ûfsŒÚ¶ù®)N°G}ÔG• _¹$ò„sAÑ(¾óïx'q6q†•;<‡}‡`fÑ¢EîñÇ÷âŒp›¸Ït,"ÞÀÁøƒüÀGÐÀ‘M\ q£á¢ÛeúŸk“È”;ê´ü‡ûÛwÅÔ¯#z\Ê“O*w“7„Dg¸®¥ŸKÂq˵D}RçœsN.»i› ȸýöÛ8’Q­ˆnA§ftJÑÉ…xŠç÷ž…ëË?ïRîIŒ>G FBÙžùqÇ«–ïÈ; µ&Îäù^Ëeª¶Ê‡$A€çK1 [‘(xØTá½ÍóoþüùÞæ$ÚFºŽâtçÆþEpMƒk¯½ÖGTËEœI^ÂÄó—ç0bVë|ncÛÓàI'žDç 4gΜFBñLçÃÆf?ÚW_}µ¢„ 0*„‰# ì\Úk´îZÔ’èþáÿÔá}÷ÝçÝçž{®ŒÇ…ù'¯ùÚÑáyøœîš²íÒ•«˜:Ž;&åHwX^Âu%ê˜û áÓ_þòý&Wö´Ÿþú׿úò}ï{ßóÑY²è³ˆ€ˆ€ˆ€Ô 3j­Æ”_h"èa!„-áD²ûŽuœ³Í¾gÔ!‡£‰j:ŠqôDNìÃÂÈ5Ή g.Ná°ÓŠŽf„Œ#ZC´£>zìtÿã¤#Ç#çJ—²96Óí—í{‹ŒDûÓŸþÔ€9çƒå£#G3Ž?¶‡!RãÁwDC€ÑM7ÝTÐ>X#Ê@ðòàƒ6QÀ–º¡csÁ)tBâ¨d´Ü=÷ÜãÏ7… uÊÈ+F›YÊ÷ºâüŒÀK•ÃŽ®+]¿ä¥uÌ5BG÷a¯-Q—tê2z•kŠ: þØžŽë|áòJå#{:ê¹ç5£|ÜË}&ž¥<#™‰ç!Ïέ#$Aƒ{ç:ÏWîMÞ¼gíÙGHq¢$!Êàyšî\î2s>ÞoˆK˜Â‹Î"ÊÌÈ\ʪ$"PyLm@4†PàÚ€–ÃLÏ#¢oñn Eì‡íŠÍÉó/LØya{€ýL8ý‹Ê3’D§óŠ+üsÒ¦e+Äf§Lˆ±Ç‰ˆWÆ0…œ#Ü?î3v< ›=Æv”»ç%ïþ·öï ÚIƃ÷Êý#œð?•Ø'ßkX 'b v"‰:Æv¤n؆óÚovÄ6Dáû+®¸"6šï/ʃ­I"¯–;ëB®©pÿèç¦ZÇDÇxøá‡ý44Ô›%îmîMêÖÜKÖæ¦M(Åuiueûj-M‘mzîž%<‡y¾êƒÊ—Ï|ÎÏ}ÉûÇüD¹¾‹Ø÷' ÏgÊAþ) Ïuž ¬s=f¾e·Çæ§<<“8mxsnÊCù(+ïÊÆ3®˜c†yŽû̹x>òÎ¦Žø¶œ®,áû;é¼pNÊL`ɹ9'eç} Sì¯$Î[®sUâZåÚ!ed1ûŽ,V‡…Þ¥>~ôÚÌÆ[ñ.ë$åÄ÷h> »¸¿aH{"_n’y %aFHCŸE@D@D@ª†Æ!K™¾ÁF*Ga "ì~\â7¦œ QM4ÂpòYbDæL%1;†$Fî3zŒltZÒÑn !ÎK:¹ éÈÄàÆ™Ëh= p†7£šMÀ÷4´0néÐN2a¨Â•‘ytÌY‚ yèÝ»·Y æ3…Î5‹Át#æ¸5®Lþæoþ&o#›ãÌ;8‚›éIpÆ‘¨Ç6mÚøÐÄ:uòÇdô:ê„Ï–0ÂùžpÊ}úôit~Øþù~$ûÐXæ<”!L4ž™J#.Ѱ>|xìu·}¥ë—ØØ%Øßؽ´Ø‡6ÏìÄ!¼+c‡bcYž_¹r¥·Ÿ±wòM”‡¶Ï–-[R¢ Ú"د”‹rcW’òÄ39É„MÌô*/¾ø¢Ú±qdÃA^çÎýBg‹Ùn´#ˆ†€MÎ{ƒDÄ4„¹0<óÌ3s¶›íœSÈunf8ÓÌY½ð®²ökkGq Ú$´˜z†Ñw×°aÃü»ÎÚtä;¼,…\S¶oܺ)Ö1õDÛûÞDÔí:¦¢D$Ê}FÇ×6×uA›€(\gÜ›jÄ]Qú®)À†ß ñ÷Ïa|Ø!Øë¥L<»xïñLæYËýÈ»‰w3>´L÷'Ûó~àîð½ðì¥ã”w¨u8ãÃ÷Ô¥K×¶m[ÿ.Ž>»“,#ï-Ê„Šüó®`Õ:4zgäz^ÞßæËâÍ1™â‹AgI–?–Ù$Ø%¼397ÏO¸²Ðž¡ ‡=B™àÊ{œÏeü«øÏ`ÊÂ=C¹©ClSìRügÔ#×6Q¦û.d\êã‡çÊ•!m¨ð~ϧ<áùì3vÏó)òœÁ®eá^à^„!S3å9÷A©Ÿ›–·¸uþwAÜQôˆ€ˆ€ˆ€$Lç'#œXH4j0¬~ö³Ÿ58ÁÿóþOƒïrù# ct>èdÄAÇüÐhq‰ÆF!zŸ~úé”p€ïi„0W. Ž\c;ó&ã8Äè&axc ÒA„°#œ†-á8#“JV¦§žzÊ7²í¸° âæÍŽvNѸ¢Nh<0’цæØÄù¶víZ¿ÄE­°sÄ­a1ï 0£Ž4æp40] uƒóÁçc[:þáOYH8¬i"¢8p mî×8± ƒËB¡Á”)ÿöoÿæÿ·?8Ÿ ¹®lÿp]Éú%•ªc\t^XâÚ2dˆûùÏÞH`Dà Ç=#+©Ï^xÁ7òix*•—÷6‹RÓ#€ÃG]κZ£gœ6J"+ÄžØkI:Ûs=wSÚG4‹%lÍûFd˜6mš}åë€vB:ÁvjÃÈl^ê{[„Ž|:‹9vK\¢ÓŸHsˆ°9­³™&"é!@-D¬m‚;£GvcÇŽõö?¶1b:’èØ  “TâœÏ?ÿ¼tF§Š%åØóDÄ& ¯uÚ $¦ ¡-3sæLß©`b:k^yåïÇÏ'1E¡‰<(+øLmž{…Ž>¢1Ðæ=BòI9ÂD³X¢ö/ÿò/ PÖB®);fܺ)Ö1…D†dDµ%î5",Ò¾ F  =M˜¶×ƒ¸Ÿè¼U¦L€NÛßýîw>¨qÀoôÿñ±‘l›b×t3ˆ‡ö9®–¸wË!fL×ÙN3ï,|eLsîoÇ ×lÇ»müøñþ™Ïó ô…Ûû™w8Ï&{çr<ü}?ùÉO¼˜!ßãsœ?þñÞ7fïAŽ0‚g[Råà}ÅûžLó…Ÿ0<_\¾y’x–^rÉ%^Gç~ºz‹;†}G9íýþì³ÏzŸ`&ßÓ¢Á€ÁMØ3\³üŸ‹ß´œçªÄµŠï–Ø<Øͯi¼mmuH½á3ÃWË»4´Ël[[—úøv[çË¿:bü½Ø»Ø™…ˆ%°/è/xâ‰'¼À9Ýs1Ó,ãw¼òÊ+½°-_ûÔÊZìZÂŒb jš$@£5<¢:ŠÇTúó9S¢á€|Ùe—y¡Í‚8qæÛ¡Ec#eŸÉ“'{£ÔòCcÇK’ Ƕ5èì¸öˆS®»î:Ï(¡Ï÷Î7Þx£od25Œ9PMŒ@£+_&Ê AŽö;ßùŽoÈZþlƒ§ùoûÛ”P†ßiÐиÁ9Og[%S%ë—rWªŽq¦"Ü £áh@fêH ¾]ýõÞq:kÃc鳈€ˆ€Tš8!qŒÆEc¨tþtþìmÌhSDt1š.[G¶ #`qxÿáð9v&Ã\ØÈùÚ ÖàX´9°ÅqT‡Ò—%é„(q6´%ʉð誫®ò‘íûè7=´¥~ÿûßûNÛfîܹ©¨ùð°6y@ ìúhÇíFÿèG?JÙ¼aí:ƒ¢Â Ë_¹×M±ŽiÐ.÷õ–ÉΧ I'ê9Ó¶á±õYê•¢@ó?Y逌~g¿%±&Â7žåag'ïI:7NÄ=ÛÉ÷>‘“t„¢¹lùâŒð±Ï~Äá{0Ûþ¹þNÞ௱DÔª«¯¾Úû°rØ~¬M8¾ƒxnñ>cî›ëgê¡Ãc=æm|ëžA3¿þõ¯½ô?ø¿æ“7®¢!Že ”½«³å)"Äv×^{­ü•M _®sUêZ…!ŠÂ-‘W!h"b&ök¾÷Q¶säò»„¹PÒ6" " " uGã#C,£t*ãŒeôN8ò‡†2 ¥|…e0Îáï~÷»%q¸ÚyÂ5†+˰1Šzè!81Ó‰2Âc 0sPØ‚!M#„£¡ o8-Ü/ÝgÀ0¦Ÿ:"?éŽ`œ´4Öi ZÂ8g#ÎOD-Õ*Q¿”»RuŒ Ä®ãO}1â1—DC3]#3—ýµˆ€ˆ€”š#;EŠ A¡Rí@¨(;-ßNìe¢L`k…¶4íÚшs¹ÒÁ¶F 1räȲØB8¤uK„‰Ð9MÔ¢Â^>—„ÍO$:„)´HŒ>^ºt©Z‘ï¨D:þh!?ãŒ32 f,¢œßÑÈa« …iÇIzÝ”ê˜öí‚0Q_¹Þ¹n_ŸE@Š'€/#ùí™ÎQy6#¬úéOšvž½õèx… ìKkÞ»›…ó…â"„Üu×]~Þ·I‹³xÿóŸO¼Ïk ¶Í÷|øÃ¢žuFm¢ÜI$òKtTì†O“K,ä?Üá‰Ï2äJ‡=oÙŽé‡3 š óÌ~ˆeˆÚÂtrÑ(æ¿á™M„D½†öQo´2‡Ag鸔ó\•ºV·œhêÔ©ŽuÈÿ%‘ƒáÈý?ê(ÊLËavùï­°®ø\êã‡ç+„!e᱄hè¿þë¿Ü-·Ü’vJrÛÖÖ”¿ü=÷ÜãùØ÷¶†!÷×çâ¾áÚ"q¯>øàƒþþ`ªãjû–z̡ԹÔñE@D@D@D h¬ä+Ê u„"$l#såZÂÐCÝÏH»|y¡Ñ†PÇc9F,aóOX"DË Lp®ÊyÛ± £),Ñè"4d¾Â FÛ9(ô`¤B&Q†Ç&ánçœÖ$l˜ÐÀfk53*Q¿ð©dÓ¸ 8ä‡F% Jî%¨u8ñxߕۙWëܪ)ÿØhùv¾Xþ±Sé\ ûÆíÚ…t(Ó6±Î¹ØÁvÎbÖ8ÇW¬XÑ úLeI$×DÞ‰v¦_´D{€Èù3¨„!Œ–Î&ʰóÐɃXŠŽ5»'YÓÀ&­aFS«c؇NÔ÷ í‚BÚâVßZ‹€”ŽùL3€0#à C”qóÍ7§–8ñ¾ûîó¢¼Ð?Ã;ç9ûóîD°€Ï‰g4.üR,¼CíÎó!‘¢ð³å+ ÌD¨GÞ§‡ßÊ:kÙžKø°ò± ('"ÄPÁ±Xb °o\"Z…ufÂhP¼[ñ%Â? ÿ#Р³™h X⽌ø2|#Î *•\ÊJç;õe°/>DÎM>øÌs‘$çDÉÚ®#1ˆ‹ißÒ 3Êu®J]«° êÑʬN°{ˆâB} J…'õÈõI>©ÃW_}ÕïC½Rÿéî‡R?¼6 eHäfîw®SK< tÁ!Ÿ!Lî½÷Þ68ÇÂÞãyÁó†ˆ5 žäY‚mºõ †ópÏòœaúîQ«ËK©×f”š°Ž/" " "P—0ô¢!qi a”’ã‡#“ÈåJ4¶–„礄 Î7D2ŠnØa¢Á†CK÷™†Æ3Ó—pÌ\=€Œæ£‘h‰úÈ÷ü¶oÒëJÔ/e¨dÓˆ$´;!½-ѨÄñ¨IŽX£R]k­D¡aþY%ÌhD;üiXÇIæ½þŠƒÐð¤sÁÚð…ý‡­†Í:¥±Õ°íóÈ>QžcG;«²å”óÒèÙ³gÚŽ›è1áŒ#žò„íÎ_H}DŸÄÿM±ŽiÐ. ]b‰ìÍÎ;féŒR¨£»!QÏé:+QG:§4etâ3%Õý÷ßïGê e0õ¾«tþF£Ïš5+ýq饗úè°™Úÿ<'®½öZïg»û±"ž¹¾G,ï™ÖL‘ˆùðÈ”*ˆ(ò>É%! ß;새…ç[Ø1œË±2mC¤XÞiDû ƒ“²þt‚SF¦ }–ˆ&“"ôÈÄ•göÊ•+Ø6\ðûÑ~äË·?× ~ŸÞ½{{A¬ñÙQéžûå:W%¯U¦íEÔ9÷äÒÝ[lƒÏ•)Ÿ‰t‚í™ÎF*õñÉ ©†p‰Š†ýÛßþ¶ï–H=ŽܦKË—/÷×d(*æD ü‹_ü"6Â̈bCD¦‘™w0êr±#ݹJñ½„¥ ªcŠ€ˆ€ˆ€Ô%œ‰æ`d5˜ù.4 s…@C‰[6•z®ÇËu;ÂÛ1s˜0TU‡Û¤ûLÃ㚆, œgl©GýQÑF>Øhc']ÞKù}¥ê—2U²Ž¹5ACË®'ê< /:]Ac‹º‹kÈ—²^tìx8lhÈSŠšÏHߊ€ˆ€4]Ø·,–°A£6 ípÛ6Ûa2S‡¤s´gÛ¿Ðßi`3†‰N:è̆ Ëö™Ž,¸ØÈak³.uÙ°)£m4ÚÕ"ÌhŠuLGm]ÂÙ›`‰ë)0 -NÔH¶¡-9e»Öô»ˆ@r¸?é|gj¦±”«(ƒ÷Þœ9s½7蔿ð ùkìøÑõرcÝ /¼àÅöa Äø’Œš‘QõDV²çùY°`7n\N Þ1ˆ ¢ÂŒ¤§1!_ˆ1ÆœöS¾iüøñnæÌ™^ ú-yµ$P‚ò1¸&j' ®øñìŸïÙòÂ{™g=þ"¨"Öˆ{Þ—ë\•¾V±»ìÚ6vD=‰cb¿‡k|5™R©Ï¹“bÈ5ýì³Ïº 6¤üé䟨—\rIìuÉõË5eˆP)(#ä…òg?û™º *ÄÖ WÈg 3 ¡¦}D@D@D@ê–F*4ÎX0øpNZUmØX­E ”‡h˜PßÒ-Œ<þžésôXl CX•Z˜Á(h#††BÔPÏ”ÿzü­’uŒã' -B’r-¸‡p¬ÜsÏ=~´ tÂ02‘pà¥vØ×c='Y&D·Ýv›i:eÊ”$­c‰€ˆ@Ý Ê! 3誻B7aC"T¤[ÊÚØ•´èäg£Ù¦–6|´ ´pzÒù×& =€-Xj;ö@tô0õfõUËõTLÞ+YÇØøŒðeNw:[¬=Íõ@8ñW^yź&L;¡ÜÙžN§¨à©˜òk_Ìx¯=Há´¹Š28:‘˜& |Ÿð¹ì²ËüàŸÌ9øÿ¿"îã™±qãÆÔ ~åØLw’¤0ƒã}€¡0ƒNbžYtàFß)ì¦íÛ·{[ 2Ø û°whxìègòRè1ÉÿøbÌ7Ãñß~ûmoפfP¾õë×7àÃóá "Î|QHXÒ¥r«Ò×*~ר]‚š÷cT\šŽU¦ïK}|ÎCîgø¡Âgâ(žq×%ç^»vm#Ñ-¢.®ñ\ììÑïÿûÞÖFùÉÄ6©ß$ÌHФŽ#" " "PÓp¼bÜÑeNI+Dz Ì2sÏEðµ\`4ÆB×òà41cFbE£aQnÞÙ̉ªFT uŒ ‡ÆÎ}N6‡#¹þpx0ÿ%ÊvB“²0Zƒýr Z#ÕQSÙä¾5§yMe\™2 44DÙ e_¢Óa›`÷Ӊ¼ó±­=À[¦žÞ‘&6‰–iéÒ¥Ž%©D{ zޤއ{1‡|¸O½®†:>|¸£ÃQ±DÎ O–hƒ3Š›ò„þg[›€ŽD=_”Ö"Pø ˆjù»ßýÎß§ö¬ÎG”AÎvð ;œiÛ3X#:ˆ&[Iˆ¬ à« ÅÙŽ‘ëïƒ ò{xÇ[Þyg!ËeZ/FöG}^ ðÓóVÛûˆÈDÑŽ"fdâŠ'rÀ•5L5‘´Ï¦\çªôµŠ‘û+äJD¦á ²V±×M©Ï5$ÃÁƒ7º.±ìYÄùÂôÚk¯5ºçxÆ`?Ä 9Â}Ãψ3n¸áoó‡;ÂmJõYÂŒR‘ÕqE@D@D@j‚œDvÂD‹ç—¬‰BI^¨¨K™hLN˜†…Rù TCs t>èŒ!Làã?îï1:8Â(-œ,DÕÀ!‹cÌÁðœÌû˜D£´üäuF¦B€Q†Œ¨$r†¢fÔn­c3Q—ŒÖcÎj:clií–*·œÓÈÔ!“ÛQ2o…³œ(ÑN¶Ì{éפTCÓQrõÕW{Ûþ™gžñ¢'DNÖ JYÉ'!î™J©MF刢ÁèW];I] :Ž4&°eË)ƒw ½L”qóÍ7û(—ÑÎüÆGq>ÂEØÎg›®]»æ-Ê`?"UD#,!âŠ,bÛb"ƒzŸD(°À?È “-Z¤=ùá¹æ 1ÄIGöH›‰<~@˜»!¦±z;‘K¢õŠp¦¾šr+î<å¼Vã¦-yùå—ýûŽ.ØLÑzŠ«›tß•úøœ7I†ÜƒQñ"é0ŠMXVlô¨hu˜/7"t1 }åLf”“¶Î%" " "PU`0ìÁô#¢™Ã £AŠÈx8ÂXtÿjþ'X\ã‹r&1¿/ò¸gu–ﬨfõš·j©cîI?üáý€ùóç»Í›7ûè,ÜCaÂAûÒK/ù¨5ÌÊ\´;rq…ÇÑg(:xà7yòdwýõ×—ã”:G¹OgÔ#<â¤Ñ9Ô±i±C¬=Àg¾³D[{&ê ¶ß«}M{ ì·üâ$§3*lÿØoù¬áÅÈÍ3Î8Cëù€KpÛj©cÄ'NôOˆ±‰R‰8›NÁðþáz¤­À‚HcÒ¤I¾MIô %d ìܹÓM›6Í­[·.É&etëÖ-ç¶8ïÒhG*‘0ñ»…÷x®%ÀŸÄ;ÈöE€81lÒþ‘#Gºyóæ5…OÇ3|â¢LXxNm7ô­Qf¢„D…%¶O9ל¨¿Q)ã”Ä$òC¦£e|¹Uµ–Ïb×4pãFш¼üòË}C«˜sÐx Ûù`§ºReT[s{î¹~äNVî?B¦Acÿþý©)´pÐ2¥ŽŸþô§Þ[Š:«ˆ€ˆ€¤'€S‡jÔ9˜~ýRmp,ß}÷Ý~ʵ°ã;™vmlZÚ8±gB±¶Ì²e˼s½ÚÊ–K~(gXۇ儖.vÄ/í'Fn2úY©2ª­Ž»wïîèìe”>S¬ZµÊ 4hD= Þ =pã7:控£VID D‡øãÿèß¡ ¢eË–>âe>¢ r7ÕȶmÛܬY³ ê0 %9µ é¬fÿt‰)$Úµkç§3¶ŽrÎCÔ žYéž=ø4Â(Ÿ÷g9…dØ tðÛÀ1lê“5ÏÔжáyþŸŽ‡}ß4ê«á7ì¢8ÛÁö+d]ÎsUúZE\„ß!ï>kGP_ýë_Ý‹/¾èÎ9ço‡Í[4Sä–(ïRŸó%Í0|Yy˜fŸrô~ç{»OmÛRDp±c—b-aF)¨ê˜" " " UMŽ"#?øàƒT^iX`ôž}öÙ…2S)¤S¹¶úÃ?¬Ya†-e£Ì¡AËw8OqÄ*Õ6j­c:5Ï8lØ0ïÅ™A‡ÆîÝ»ý£NÃŒy+™妛nò!ö›Ö¥#€Ó©_¿~Þa^º³èÈ" " "PyA}ôQ?·tØQˆ oß¾ÞV!úÂåèh=Ëý³Ï>ë÷§S¤¶?Ñ@¢ 7¡Ýé SªmÕXÇ´A 9ÎrÑEùéD ãŽPŠyåÃFÈ?öØc®}ûö¾}^K#bkûÊQîë¾0|Ztˆ‡‰öz¾îܳ¬ƒÙŽGs’ ñAôI›ù'©™ÚŒô8aèÑiLx>!Ì(VÔ˜K™8?õG'5O»ñ?B ììÊR /Ä1¡¿Ðò…mí,·ß ]—ë\Õr­!–ˆ+D”Epr¦N±O5á›aj¢` ¸@ œÎ& Ù—òøåb'΢Œq32Ùê!—jù,aFµÔ„ò!" " "P64ææÎëCÚI1l1r¯»î:7aÂûº®×8éh0† O ìP¬Rך@᪹Žé°sDÒxî¹çü‚@Ã¥\›Ìõ>hÐ ?b  TYÅ‹ÈȨÛo¿½âùPD@D@D Ô˜Òpýúõ F»ÒùB[àꫯö#K‡JŸŽÚ¬Ãpæ´h(Õ>j¯cF^ ƒÎL:9gΜé§9 Û¨t^1Ý!áó‰j©$"P<ü_={öô÷ù–¸ß~øa?8‚K¹t§ëT·c&±Æ·Áô¥gÑùMÔÎðÙ³uëVßyŽX1z^„dø.Âw'ϨÓO?½Ñ¶I”ߎÁù8/»°cX°#À°cG×°0ßLøÅòï„ûÇ}.×¹ªåZÅÆt¿\ÓøÂ¶oßî¢Bþg ‘[fEƒ„L½£LKyür1äùwe$z]ÆMyeRMÿK˜QMµ¡¼ˆ€ˆ€ˆ€”…J~ŒÛ0fw̘1îüóÏ¿®ëÏ”™Æ8sFZb´„„F£ö×µPÇ4´GáCÿð‡?ø‘rFŸ‘¯¿þº„¤Äk"8™è˜B¤¡$" " õJ€©Õ]&"e\|ñÅMB”aå¦=€ÍvFÑˆŽ¢¶íµ®=µPÇ„ˆZÙ±cGÞ‘êá´hH˜Q{ןr\\\sÍ5~ „Oá3ŸQü§žzª‘ËTTaÔ©°´Œbçý’‹¸#Ü/úSä;½Jô8™þ§¼Dñ¡Ó7&2åÑt‰$¦ 4xFñϰ|¦œ—ËgòµaÃ÷ç?ÿÙaÄùd8ÓaÏ‚_KÈžgj>QGˆÊ'ø Ó?Ó`¤ñ 3h¤íÚµË7ÊiÈ5…w]¡¾ÆàÇPË©–꘼.œyO™fÈÎF„p¯7¥ûÓÊ_î5¢ŒÛn»Í‡Ìœ2eJ¹O¯ó‰€ˆ@M ³“ÃŒvS*ì¨M€€í–«½@gö¶o˜¨OF‚6¥D{;,fÀ†Ôˆg£¬ë‘M\{ ßkªš¹ÔR3øÒK/õS2ý¨¥¸ûÕ~ÓZD 0ˆñ¯¿þzÇT½tøó%ñü{ä‘GüÀ Fé3ÕG¦”N|A4D ùøëâ΃p‹h›qSŠÄm_Èw¼ë(ëÚµk˜võ»ßýnƒ)$ðQÐAŽ˜ÀŒð)¢T‰(_¿þõ¯‘<ˆœ“èCaX=! ¼Âw8SÅa#ádÊ+>ÁpÛû€óǽ;m›|×å:W5^«gžy¦ëÕ«—Ä´^\ƒLgÂ'Q¢E¦­ùå/é#M!’É–’>~©b“öèÑ#ö¹ƒ–ß?þøãÅf ž[µ’$̨•šR>E@D@D ‰ 1@CÃ?l€˜Z6×ùÙ7.DÆ£õsM|Quz®ûVËvÌMˆù…^He Ñ rz4|ë=q=ÙH‚ðº¢ñƒ¡ŸËèjfTkuL~ ý&î3YÔI.Îp_}.Œ÷Bx?ví%" õO€Hkçw^¢Žéú§V| éà±Ñšæ„eíFÛ — lÞ8[¾uëÖ±Žàt¹æ–‡tÛTû÷´°Áè°„ˆ :ôù­Þíèu“ï5UÍŒj­ŽiD¯;FÈÚH︎Âj毼‰@5@ …ðà7¿ù¤cï4Þ“üã½ø”ŽÝLƒVè¨ûáj©Å I²e U|‹aÄD+D* Zï >3¾ÛÌDó âO‡$òÈt% `áýž!шÖAþe¤KÓ§Ow«W¯ÎY˜Axœø‚¼äjo¥ËKôûr«Z¯U83µ öSúÉâ[o½Õ ÎùýÁôÓ{a§ÅÕQ”o’ǯ4CH0°geÅgXKéÐZʬò*" " "Ðt à|Áø‹*äi  "Î5qJqŽ7ž¹$ÔåD•`©åKœ^QñÁž={¼X#W}-3 qÂè –0Qöz˜Ò¥Òu: B¾é>s²„ Kœ8G$ÊHGMß‹€ˆ€TŠá†×­[çX+•v<|ë ±3ç3ý†µ°;ÂDÇo®ö ŒZŒFÝW Ÿ»téâêaûsçÎõ‘ÌBÇw-”§` ¶¶D.‰Ñø8v£ÂO¦ôÊ6êŽö#õž|òI/^ȶ}.ù©ä6t†0¢™©0Ñ´páB/ÎÈÕ–³ý±åà‚h‰¶A-$ÚÑë!ŸkªšËX©:&R%#Ë™:“ÏÙÚÚÆö¡òÃD{ zχ¿ë³ˆ@q®¸â 7dÈFâ|C3fÌp~øaÆtèСÑ(üBµ$Ì €,¢wV­Zåý[<ÃÐÅÿá»gìÀ :2ËóÇE‹5ê„çÝ=iÒ¤’=‰ZŒÿ48C¶ññ$]¯å©˜ãW’!þü¨HsóæÍ üˆùpÈÕ6Éç˜Ù¶•0#!ý." " "P5èdŽÎáj}Á‚†„¦Hƒ!š0f5&WO?ý´Û±cGl'2ÎE„(ã çHã´Ø‘#G6A¸¼»îºË=÷Üs¾ƒFg&c•ƪyœÙ(ù~øa7sæÌX–ÕÆ`T¨ƒÓaÉ’%>d`Øà¤œ8âó‰ÒRéòV¢Žé™5k–û÷ÿw7uêT·bÅ /¦k4rm±®Ÿ0áäˆÞ¯áïú," å&`6MtÚÑyÉHÂZ5_nŽõp>Þ_\™l¤z(g5–Q¢,aB¬Í=vcÇÑÁ‹`4ìDa?œÊÑÎæöF„#<m¦ü{ä‘GÜã?^3Bä° qŸéŒcº‹P˜;ÄèùË_¼ [-´‹£Çá7DÝ<©‹§žzÊÛŒ¸®…{„öí‚0å{M…ûVÛçJÔ1÷ã”)SÜí·ßîž}öY/Ð@°Ãs3.цçz™3gŽos…ÛР] $"PD¨½îºë\=u#D¤ž)Ê,Sy„ïr‰_‰÷i-%¦mašãPŒ€ÁûÓ|!: Ÿc}ûöuL…î“d™±_˜Â$*’D˜µc’Ø}l‡M‡]M=`[<ØG?‹vØY½UËšöe #5ä{MUKYâòQ‰:æ@´È}ƒ€Ÿ{kÚS´ ¸OiOÓ&ؽ{·Bà ˆ°˜û”ÎRîG%Ò@ðƒüÀý÷ÿ·´dïîÏ?ÿùÏ?W£#÷É÷5í÷ðÞÅ7Ä;{˜ßj!ñ\:t¨†ea@ïÁhä |‚#FŒhi$ɲÒöà]MÔØrM¼«Íç•ë>¼çÏŸß 2Ït¢5y,ßzÅ®Àˆó¥•ë\µx­â ²Æî‚g)ßãW’!¾*žA<—,a·¯Y³Æ ¤r½'¸¿r-۳ΎW굄¥&¬ã‹€ˆ€ˆ€$F !"1à4´„1†zŸn&ÌÀ KƒÕúM7ÝÔ ´íÌ¿HÇ;#ù­aÂqhlaÌad¢ÂÅ #êNF‹¾A˹iá< w–§ZZÓ˜b>Qʰñ GÂs³À&,4V1|qdS~œnÑd\£ßWÛÿ„f6l˜›wp~Æpúʇã±NZÂ6z1 ŠõRŽNH’S¹ë˜û†ûŒÄu€° –D`Á)Ã5D$¶ãúáÞâú ¯~£ÁÅœ©t¼(•‡#Ù¨$"žÏ-:zéd²„SŒÆ›”D@JOáö l6KhYèÀÅ–À®¥#‚„ýàÓ:¸gé$ÆN íyîoFùrì}ì@ÎAd=ÚæçølÃ9nÛy,/µ¶Æ&Ú‘.$„âs¦£`¡Ì´·èœ;á„R[Ú ´ÏÒ1m¼jåBg#¢»èô+ù\SÕZ6ËW¹ë˜ö× ‰kƒÎÚÒ´OX¸W¹§¸¹ï¢Ñ§ #0`@ª}aåÑZD y< /¾øb÷ÐCùûÒÎÀ3žè±Ü·D°±w©ýÎ` `øˆ¬““5ï:}yoÔJâY‰ß1ô!8D¸H”O³(ïBìÿh§y’eå9'n$¹¾_©?„2qLyeP›ÙAávth÷ïßßû\ñ‘fKä“èeØ;wöö˜½lßr«Ò×*÷Eôþ1éÖ0Žò·ç“,õñÉc%rà#D ^ÿô ðüâ•-qï¼øâ‹îH P̶O’¿K˜‘$MKD@D@D ¤0DièM˜0Á‡°œƒ Åp˜âŒ]Žƒ¡výõ×û))p@Zã„cÐL7U †0bñ8‡˜î#tä†ç®¥Ï:ur?úÑ|h¼¥K—zŽÖ˜¶rà$cTb82Ñ~ ×ðÅÆ<Àµn–:ÅIÎ9çxJØø¦\8¥s¹®BÕø¹œuLãg Žûðþà>C„a"§tœpjP'^x¡e™n;}Ÿ<ÄGt6sï"ÒPˆ':â·Ð·" ¥$€HÇ,~l×pÔç¶âÚØDº¡#žé Ã:]LŒWÞ“HYLçâÞt¢„¸ý«ñ;lb±°E”MTØùDž±‹)k(fNWF3Òn¢ã ntuºý*õ=uJ{±0e…)ä)—kªRyÏõ¼å®c"åÑ‹íÞ´·YèTI—hS"à>|¸oÿ#¦W(K.¹$5­PèA 9}út7yòd?Ø‚ûÔ÷£FòûѦ´„‹Pü†.î}lÛF×ø¤xVð.b_žaåHø2^2…­ù ñ‡1þð@tYÄ!‹¤óhb6ž¥á»‰ú@ô’éK^ÙïÑGõƒÙ¢ïõlyí|PDÁÀ5X„Ïq´IÑ+u“©ü\ø{ì1ß>iÒ$ Eý…å:W%¯U„¬d¸fx?Ú€¦lõÀ}.rF;¥>¾å³T ñrâûOwMÁlüøñ^0ÚÿØòØä\_™"l1°páÂ…>B4¼*‘$̨uSD@D@D `tø2bÇØ’%K|#* °ƒãl¥3:NALƒŽÆÅO~ò7cÆ o3J'ݱ؞ÆÅLmÈH²PO3üßò®Ù†F¦5æø.jL‡û”ã3y „8ƒ2b¤¢f§ºéòByàŒñ‹ó•ÐÏL‚c7]J’EC¾ËV–7¢7p]Ù&™®¦siß¾}l*É2YÞX'q\ŽQ®:† ®!B}“95²…Ÿ©/õ„°¤ÏH•t±p?}NŽ¢Œ¿û»¿ó]Ì®$" "žNCFI²V*?Fë!âÄ~gkÔam9ÂbdNp>‡‰ºcŠÌÌ}oSû…ÛÙgì]l]Ú8~±­°›C{{&zÛßÖ´¢LéB{Û>åXc»Ó!G¤¢Æ=;¶éÚIa¾(;ŒçÂ{ŽŽƒL<’dÇ0—ú°2`{Ò)@”7Ä…\Sv¬$Ë•ä1ËYÇÜÜ'ÔÁÖƒÑfè áþ²v°•+\s/Ñîæd*DeÔÒHû°,ú,µJ€çÄ÷¿ÿ}/Bàý¶ãî1‡¨ÑÎÏ1}eŒZã7Rï „÷Þ{¯÷ œwÞyÁ«éÞ lOG>ÏbDª`¯ _A9yCHBgxØqKÇo˜x3íI®ëá¾ù~F,B§P˜Á{‘*ÓÇåwS¹=þøã>"T¾¢ Ë#õ†„¨öüæš`êc1{î¹Þ6BhÁ»„‘ç=BNDO<ñ„ŠDþÙ',‡‡u¹ÎU©kD(ÅWÍûÍ¢5ãC mIcGlS"Ï„")~g*ͨ/¹ÔÇ·|±NŠ!þ}»ßÉ?‚i¦$>_Âs#¤EèÃ5i‰kêOú“ÎË4zØë!Sž+l?wî\/²2k6|ÆÙñJ¹–0£”tulÄ `Tá˜ùÙÏ~æ4Dh(aðc°â0Ä0Å!Hç9ÅÐ 3„ƒˆ8ÌW‹aÆT(‹Æ F €4xØ ®…T¥q‚óã:Sâœù‡QMÞ`ŒWCbЉï|ç;~ÊF50RF0,<0VYÓ… v fxÓ0 ¬4Ÿ£Îæhù’dA#†Æ(!¦É\s©ËyeÔ#××Î\WŒ  ~¹®8Û1õKÜu•d™,o¬“µö;÷ uE»{ÌÁ^:É«’ˆ@ù à7 Ê,ë[ «LœÇóÿ/ù‹§"fãùo ?ÐW\áî»ï¾ø¼S‰ØÀ ÞǼ·y§òÌeÞÙ¶p>" ¬_¿Þ #x^Hƒï¬\6> Þ%œßÄVN[ã›ä2°ß’^ó\ÄGdzÓ¶Çþðí áÏOÞɼ§É7¢±¦Þ`‡+ß¶>6u(‡º´D^˜ò†i¨ðÇá…× B<"P1 Qõk‰<ÆùÓø½\çªÔµJälKO\ãØZˆ{sOðäz¢Ù'Q °ÅøÎö×Û‡©ÔÇÏU,CÊÃýÎsk$Œ ‚hé®lz¦#äš ¹`³ýîw¿óöSb‡r Xò\Ax‹oÒžgøû¹‡„ä{_„,òý,aF¾Ä´½ˆ€ˆ€ˆ@UÀñ‡’‡ ½¨^-´#lè”ÇHÄàÏ–Øž0Æ8×1 Qçr, :~£AJ#êX¤öóŸÿÜ;)i¨ñ; ËL £™†£+MyOã)zìLÇ(õo4Ö`wÍ5×xþ4È/bŒ^ÊAžYhÂ:É'%É'6 uFåÑ¥Þù.ß<Å] \í6òk+ƒ0É2…,“>n¹ê˜%Ñ/Xhˆ#ò¡³ƒk‰û‹|à`fá:‚q:¶!}j €ÍÈ» ;HQ3*W#Øé·Ýv›·/hP/ˆŠq¶š½Î¹KαY°Ñqâ"°à8,|æ7l/j«Lœ8Ñ Dè¬ÀöÄ>Žn¥ƒ€õæ›oöy¦c[¯Úì Ú5ˆPXàɨ[ìblmÚØq8Ía‹ “œ5ßç“’dsýïÿþï=Wìä<æ›':JèdÂf-ôšJ²\Æ3éc–«Žé¨7nœ_¸§hp-Á—¶%× mkpeº_‡Ö" ¥%À³±Ú<à}d&P ²*ßñLBœ¾óˆ.»õ ƒPüj¶9¥3š…íÍÄ»w ïŽË;Ü:M£¥ ý-éÿ)ߨy¡"<ïÇrùò8S·1(GQ„Žm:ö±GyçñœE,A=Xg3>2¶1Ÿg:Æaùì3õuõÕW{*"»°#œ:!r ‰èdðÂß—°ÍÄb[Å¥rž«×*ï]³I Xd6&ïA®)ì.îê0ä 3|Ô6OÔç]êãGë¬P†¼ÿí~»¯ã¾‹žûÊ+¯ô¢£0BÛ $F<ö׿þÕ …`Ëè}̽‚íÿÝï~×ýíßþmÚk6zÞ$þÏÞS‘ÄYt (Œy,Å&8Ó¦‹;> ¶|N&Œe–jO4ŠPb³”"%É‚Æ ˜$Æ…\ Æ'É2Ù1Y—긥®c+÷ ‚%¨Œ`£c‚¥,J•#€=ƒS›Ah¡ {Å:‡ó‰hGÇ2K>‰sÑa] ç5o¥JI² S?_qv\¹’¸¦’,—å±Ç䨥®cË?°,J" µA€LDš9s¦PX®}>mÚ4qŠeü$žØDãžþy/ê £%° b@ò¦d>?Þ—Ö¡iû$9r¤¬íÐå6x&‰÷M.yæí´ÓE,°ßK±†ÉO<ñ„ŸƒNçhgtx^wˆ!˜òá²Ë.óÚà^k°ÿ÷~fZ_¦~{üñÇýÔˆkˆv’©N9>ÂÓ1m-QÆø?[*×¹Ê}­"¾êª«üLEÔ/qŸõÃ=†`È)0L7 ­ÔÇóeŸ“`ˆ‹ûiŽ.¼ðœœƒ r¿üå/}„ "Ç𜉠Á,Ÿ " ®'„>tÜ%ƒ|2% glZeD2lKt0û-,_ºÏˆmg¬X±Â-Z´È9…:åüÔ'¢eê‘<À1IïÞ½}”Œ\Ä5áyËu®r_«05 h p R'\÷pD´À”cNåͽ‘M0Pêã‡udŸ eHÙ("'¢© ,Éçzäügžy¦û‡ø?ÍϲeËü³•h,\0ä˜LŸÄ”…„€Gã‹øŒk˜í^q”*I˜Q*²:®ˆ€ˆ€ˆ€ˆ€ˆ€Ôœz ‚1®]ÊQÊ$aF)éêØ" " " " " "PCp1ê…«¢fÔPÅ)«" " " " " 5A€ÑÛt¶æ› Ýó³¯å“Nr:ý MtØ=¡”)‰rZþ˜¢cîܹîÓO?µ¯üšúmÛ¶-JpÐà€þCY‰BÁ’O¢£:©D'6`Ê‘Êy®r\«ÆŒ{ª˜ûÊŽ“n]êã§;o9ZQe'ßij 1K¹Rébq”«:ˆ€ˆ€ˆ€ˆ€ˆ€ˆ@"˜—ó¶ÛnswÝuW"ÇÓAD@D ž 02“Ь•D@D@D@D@ꇣî—/_î£KX©ˆ.1bĈ¬‘Bl{­E@D J@3¢Dô¿ˆ€ˆ€ˆ€ˆ€ˆ€4a„ÎdQjL€P˜Œ˜"Ä%£*qV”а„’e®X›ë—M̳ËÈÖ¹„Œ‡1 „ó2b(×ã4.Iü7Œ £|6O0yçZ ¯œ—²M…9‹£!}ãØøÛzg-1× éhÏ5Õ3Ã(ÊÊ(;æ\^¿~½# ÿó½Í%Þ©S'Ιùn¹¸¦ŠIéê‘ùžù AB8[¦*êÞ½{bõHÔÂ:s­ Âxçwüµ»bÅ Ï× ×ëÀÝСCë"Êåäž'b†¢fsõj_¨ØÎ/¿ü²Ch¦³Î:ËÛÒõ 0Ë¥Ï" å# aFùXëL" " " " " " 5J€NõgžyÆ/VFÊ[‡,‘u;{ölßuâÙ>£gÏžnâĉnÈ!.œã—ÑX$V®\郸#î8«W¯vÏ>û¬}|ô;G>kÄo¾ù¦w<.X°Àw2‡£Â¢Çš?¾?׀ܸñãý4tôzhö™Rë•aÈv!6lØàž{î9÷Ê+¯øˆá6öyéÒ¥næÌ™ž!‘`ÊõPˆ£7ßz|ñŽØqѹçžëó€x(—sS\ç\ƒ–È?Â#Ä;ˆ{ž|òI7oÞÃßã>#¼A¼±}ûöÿËÞyÍUyú’@9 å,¡D D" 3‹± öØàÁãZv];[»l¨ùË[3µLmÙãµg<ƒÍØàcl0ƒ6AY"%‚@ åayŽ}>ß¿îþR÷×Ï©ºº÷»á„çœÛº÷¼¿û¾áÚk¯ ðDRIª¶M<÷ÜsÑC "#„#FŒhQdÃØ£/³‰¿ñÂ$öý÷ßpý̽Q(á……¥+$BÓÐörï®ÐfÛ  H@€º2žëž|òÉfÏ«òØç‡ïëÊ,l›$Ðöf´=Ss”€$  H@€$P—WAH˜Z&€A–p%$˜¼C°@B @¸ &í8ã{¾¨^SÌŸ??Š;xàœIÀ–òaÒ0äO˜Š‹/¾8®[®yˆa5/^EYer‚±À’BS`HGHš6‘<ôÐCÑ 8£~¥©žfÛŠž>e< ¬ÁƒJJŒ˜â%‚ö2N1dÓÖ­[ãxà„.åŠlèƒRýاOŸèá„~D(ÁXAÁBIÙ~¼ñÆ£ç‹lÝÊÙf,"PBèƒØ#¼ççQŽgŽükü[€$  H@íM†xBDPŸMxË(÷={Û€²fdi¸- H@€$  H  ÈøÛ¿ýÛ²Â40¦¦¦ãáç?ÿyG XÀØÜ¯_¿0vìØ0~üøÖ1ÃÆ£Á~çÎ9k¼$àYkŒÚ΋åƒáÃÿŽ;ròY¿~}X¶lY˜1cF:thSýŠm @H‚0„¼R¢cÆŒ 3gÎŒâÚAh ÂdlÙ²%ºó}õÕW£w‡4QIûžú$dÅÈ‘#£Ç‡J¿ «W†‰YZÓÿ2X§ðˆ"ø²nܸqqLôìÙ3§q ûÄ‘|`A°DdÓ’x¡Ü~¤|¼²dû‘p8ŒËT>ýH˜šjû! c˜ÄN¢Œ^½zÅ{ …g¡,ÊA¨“$  H@Ea*ÂЖ¼¬5[[kÝ#\ÎzDã‡0”ˆ­M€ZC@aFkèy­$  H@€$ .DCï[o½=%è5£åŽ]½zu4ž3ÁŒÇ ûì8Éöç¯1ŽjGJ”;{öìð¹Ï}.ÆM.&ì b¼‚ÜsÏ=Q\€@€ôúë¯Gq70—›ê‘a©¶1q;jÔ¨pÝu×D òãᢋ.j k‚X'…‡ÁÛýȽHŸK­éÇôÅ®˜áÏW¬IÕöcdm& "Ÿ¬„KÕ„»!ÏZMxDAÈÂÚ$ H@@i<¿>üðÃѳÜĉ£yøðáѳÏ<£°æ™“mÖ,ÅžMK—æQ TG€1‰ˆ˜çržíyf&l£aLªãéU@.…¹<üK€$  H@@CÀ@œŒÄ ¢ÌÆãa„ áæ›oŽá'Љ˜\ÆÐŽ7„Í›7G7ÎÙ"ȇð'7ÝtSôºQ,&§É„6I¼.ð÷¶mÛb}²yg·1úãÝ ÛÇL>.øD8—`åL|O™2%Ì™3'z? 3‰Px_ n¯$ÕÃbmƒÂúM)WÇLò^xá…a÷îÝáþûïÏñ^‚7„3„”aÜJmÕxG¡¬Ô¬ñ¨RM?ROB”0–®¹æšQF¡6t…}‹-Š^QÃ& H@@£ๅÿÓói!û÷ï϶y¶à™ !1y³æž»ø›…íô ›¶É‹óL¨”À—¿üåølÌû^]d¤ñUi^ž/ H Ÿ€ÂŒ|"þ- H@€$  H@(ƒt#GŽŒžð€PLL‘²â«zB}0ùŒ!¥l>„0i)&š 5“ŸÏ¡C‡šÂ‹¤¼³kBV`ÐÇ»FJÉ[_ý3±]NâÎ'| Þ7Rz÷ÝwÃ;Ÿ„â¨D˜‘m{=0Lm-´FàòéO: kJ‰2Òµô3!K´dÃÊ8p Š^Þ{ï½è‰%ŸÖmÕˆ|Q3}úôœ~¤éËJú‘º‘[®ºêª.ç#±Ï_Óoˆ¡¸·õš‘OÇ¿%  H Ñð,Ä3P “VNû # e!äY¡„àc)ô e°g)ÄiáY–mÖñ=qÊÏ}(E€ñ3xðàR§xL@ÕfTÎ %  H@€$  H ‘ 0¼àï—\rIIï‰"B90if0¹L>óçϯ( ÁÙ|˜/5Ž¡ãÆ¯¿Râ‹DßpÏß•æÃWƒ,Ù„ÇŒRÂŒíÛ·–l2dH`©4¥¯³^6(£~)÷ÕùåÔÃüú§¿i"‡¤]e­áˆ !¿Jy?iË~DPÂøËö#eÅòF°qìØ±püøñœâèo–¶JäŸ_F[åò)Ööt¼Üu±|Š1,7ßJÏÃëFŒl"Ž:âˆ>ø ÂI©+õcj“k H@€º¼c ܽ÷Þ{Ê+â³g×h™­€$  ´ Û&s‘€$  H@€$ z'€þßøFøö·¿]ïM±þy0ô³´g:餓ÂÀÛ5ŒI{Ö¿³òF˜Á’ŸÒ°dSGõã€áIL¥ ‚†ðO¬M€$ F'°uëÖpÏ=÷„eË–5{†it6¶_€$=f8$  H@ F€¯X_yå•kµÍ•€$ÐñÞ|óÍŽ/´•%6/ôÝJ5xy±0'½zõ ýû÷ˆ*Z“N<ñÄ0xðàh¤Æ¨o*Ÿ@·nÝ ò‡i~¿tD?2$ö#ãÂTšÀ•W^.¿üòfýTúªÚ8ŠñÌw‚Úè k! tmxÀj”ô›ßü&zbã}¢-Sz&bž›ðpÆß,ÉÛYò†–޵eÌK€$Ðf´Eó€$  ÔbÉßu×]uTc«* H@@k 0‰ ‰‘ò›:ujX¸paU¤}Õ¬{ôèFŒ†^Íå }ÍÑ£G›}UŠ £OŸ>Íúh¸çž{ a¨©}Ô“Å$ H@€$  H@(F@aF12î—€$  H@€$  t!„ؘ1cF˜8qbŽ×Œ-[¶„çŸ>Œ;6;å”SÊn5‚‡ ={ö,~£ì ëøÄ?ü0r<á„ 7ÜN;í´È¤P“y²bÅŠðä“O6 c‚(cÊ”)E½n4R?><œyæ™…º¯Z÷4R¢ê’€$  H@€$Ðe (Ìè²]kÃ$  H@… àZ£ŒI€Ú—†ê7ß|³} 1w TH€ð9ºñÒÀ%!®xöÙgãß×^{m˜5kVèß¿8餓"ƒü”Ä»ví o¼ñFÌoöìÙáâ‹/Ž×å_Ó(?~<<óÌ3aß¾}ášk® §Ÿ~z I’¼gÀîàÁƒ1|ÌÏ~ö³ ŒÅœqÆQ˜QŠY¹ýد_¿¢>ú( ! !m©òöÛo‡³Î:+\rÉ%áÄO,U…9vÕUWSeôàQ/Ï–€$ÐÙz÷îÝÙU°| H@€:€€ÂŒ€l€$ Z"@¼ò»ï¾»–ªd]$  tI„†¸ë®»ºdÛlTý@pxbÆ Ñ»BÒ|Cq¼÷Þ{ñøÌ™3ÃÀ£Ç‡$*à\ÎCбqãÆ°fÍš(,ÀãÞ"žsÎ9 é5®d xàþ‡ÑyçæÌ™Ó&æèÑ£Q°…§ŒuëÖEQLM\÷óÏ?? 0 í.¸.·“Ȇð(©éCúȦM› ö#uÖHT}]ìTÐRÝd%%  H@€$ # 0£Á:ÜæJ@€$  H@@c ÄÆ•W^öìÙ½]à5!¥Í›7‡ûï¿?zÊèÛ·o6lXôø€ç ùxWؽ{w“·tk¼A4j ɨQ£ÂÓO?· Tž {ì±K„ˆZgä³B”1f̘pùå—‡éÓ§—…±œ~ü×ý×(°8õÔSÃàÁƒc¾x:a)Öœ”_¿²*äI€$  H@€$  % 0£(H@€$  H@€ºDxeèÖ­[xðÁcX DYc<Ûˆ0XZJˆ ð®1bĈpòÉ'·tz—×nOY3 H@$ 0ã,Ü’€$  H@€$  $€Ñšcx0 l`_%©X>äUIJeç×§Ü|8oîܹÑÆO<^~ùå°cÇŽèƒP-%ÚAxŒäUƒÐ\pA gRìÚbm¯7†Q²u¦ø;‰3† /^V¯^C›ãI’dòäÉQÔAØ“JÇ´¶¹uÇ; ýxÑEEÑN©~äºl¢ýùû²ÇÝ–€$  H@h[„ÎÃ;ÛöíÛã; ÞÑnºé¦è}-û¬Ú¶¥š›$  ´†@î›tkròZ H@€$  H@@%ЧOŸ0uêÔ°uëÖ€'ŒóãÆ‹á+*i2ùL™2%'ŸñãLJ‘#GV’MDÊ1EªO¥ù ( M&LëÖ­ /¾øb m²k×®Àx„ã@T€%Þ“!Ï cÇŽ 3f̈ Á0)•º CÄ(ˆ)¶lÙùà%dÒ¤I¡gÏžñ Å /¼0Žçž{.,_¾…  ª ùŸ†îjB€´U>YˆÖÞý˜&­½ÚºÝæ' H@€$Иzè¡(TA8^ñPÇRHDÎs-®LÀ{£¶z·´ŸÑÚª«µ‘€$  H@€$  H@€$  H@€$ÐDàwÞ‰aöšv|²AXF<²6I Q xoÔVÏë1£¶úÃÚH@€$  H@€$  H@€$  H@@ ¼(¡E !™¼<6,n7 Ž.Õd…]ª;mŒ$  H@€$  H@€$  H@€‡ÀäÉ“ÃÚµkÃáÇ›MXÁ‘#G†nÝ4…6Aq£æ ?~<Üwß}aåÊ•q<÷èÑ#L›6-|ík_ ŒéJ“÷F¥ÄÚ÷|Ú—¯¹K@€$  H@€$  H@€$  H@íDàÊ+¯ »ví [¶l‰^cœ}öÙ£ôI'ÔN¥š­ÚžÀ¡C‡Â³Ï>vìØÑ”ùÆ×¾ô¥ª„ÞMkbCaFMtƒ•€$  H@€$  H@€$  H@€*%€ã¯þê¯Âž={ÂÑ£G£{À€†~¨¤ç×$?þ¸êzyoT®].T˜Ñ.XÍT€$  H@€$  H@€$  H@è'Ÿ|r>|xGe¨+ÞµÓ]'ÖNU¬‰$  H@€$  H@€$  H@€$  H@èZft­þ´5€$  H@€$  H@€$  H@€$  ÔC™ÔPgX H@€$  H@€$  H@(Làƒ>'tR8á„ Ÿà^ H@uHà£> ˆËñãÇ ¿sÝ»w={ö  „"h«tðàÁXåò›Ú·o߸®4®'/~›Iݺu‹y•ó}èСpìØ±ðñLJ=z„>}ú4ûm߿ػwo8zôh<ð4hPd“_ß#GŽÄsS»È“:•“Ê©ù>|8ìÛ·/ÖúÃ2¨[ÿþýcýÊi9u¢”AûYØNÿRî)§œ—O,ý ~ïÞ½›±-§üRç”ëÒþ£¼z›Ôµ­Æ}šî…Ä€û"?Á>…¿¥~#ª½7ÊégêC_ó–Æ(õaéÕ«W¼/¯å$î-òyÿý÷ão÷ ÷Vµ¿S¥ÊýðÃcyéwŒß^î;ʤÎüÞôë×/®KåSɱò~‘*ÉÑs%  H@€$  H@€$  H@mD€ ú7†­[·†Áƒ‡±cÇÆÉþ6ÊÞl$  t Œ‚Û·o[¶l «V­ ëÖ­‹BŒ“Û1Ž=:œuÖYaÒ¤Iq»”ñµœFìÚµ+<óÌ3aÛ¶mò1<Ι3'œvÚie‹R9ëׯ/½ôR¬3û0žÎŸ?? ><Ö?—¿ÆØ»dÉ’ø›N¸îŠ+®ˆ¿ïˆ0î¾ûî»aÙ²eáå—_ŽŒ0^#P?~|˜7o^8ûì³sÄÉŸ~úéøçÂéôÓOgžyfÎyùuáï–êÃ9žé«5kÖ„W_}5¼÷Þ{Q ñƒñ©§žfÍš¦M›ëØÚ~BÂÿ{p ¯Xø?v"dIeš:ƒpìŒ3Î'N¬J|CÛóSK¼ªé?ʨ‡±I=Ûz,0¦¸÷·¤$ĉdþyòÉ'c¿gv5m6,\pÁÅÕÞ-õ3…ïÙ³'Þ Üü†qp÷4ªQ£FÅ{u̘1:‘ÏæÍ›ã½•ò¡ÞˆŠÈ‹ß'S§†6µ»Ú Æ(÷ üßxãx?# ¡”¤{læÌ™a„ aĈñ7¨Ø½Vn]f”KÊó$  H@€$  H@€$  H Ã ¼ùæ›á»ßýnxýõ×£aòÎ;ïlf”ëðJY $ VÀxÉoÛÃ?–.]™…²{íµ×£>¦OŸn¸á†(42dH¡SËÚ÷»ßý.|ÿû߯åtÁ;ï¼þÓúOQ’ö•³þå//^ Éé|Œ–×_}É/ÌtüÓ?ýS4ê¦ë0Ú"¸À(Šƒão¿ývüz=ƒá–ÿÖ®]¾ùÍoFÃo:ƹÿïÿý¿œ<1¨þõ_ÿu‹†ÜRõAØ€ãÙgŸý°aÆœ:¥òé§'žx" h¾ð…/„sÎ9§¨=]ShgÚ‰xæ‘G ;wîŒÞB [î¾K.¹$ö/î¶H¥xUÛÔ«ÖÇf{…{î¹'Žù$Ì(ÔGxq¸÷Þ{ Šûðóï|' !òOªöÞ(ÕÏ,¸/~ýë_‡Ç{, ‡²^>6mÚÔT Æ1¢~VÀ1%„YŒ÷Ç<Þ_ˆs²ù¤ó€!"»ùæ›Ã¢E‹¢ªZõFüA½””âNùüÆñ›K¹ÜKˆ4ðRmR˜Q-9¯“€$  H@€$  H@€$ v'°|ùò€1ŒÉs ˆ+W®l³¯&Û½ò  H _‚ÿö·¿ ÿò/ÿ½e2Df/á8†D ¥×]w]\0ÔV“ð@”_^¡}åäÛÿjò*TyñûóÏ?…#xˆÈÏ;Õ "t³©PžäW,–®¥>ä‰Qû_ÿõ_Ë/¾ÿÎ^Whû­·Þ ÿ÷ÿþßðùÏ>,X° ŠBÊ5 S_<ð@ü‚?¿…Ê+g_òŽRιåœSˆukûr å[h_9ulë±Ùžc1Bkû¡Wïùã­Ãtn)–…®K÷¢²ÿøÇaÅŠ1äH©|ð0’Ä·ß~{˜1cFôðBþšR>-ý¦!ZúÁ~vïÞþÝ¿ûw/ùm-U~ ø ½ÿþûÃSO=UÖýœòC Åïõ /¼¾üå/Gqpµ^qf$ª®%  H@€$  H@€$  H æð•/_ƒbŒ;å”S¢»ûÖ|­Xs ´B@ÃÀ°‰÷¼V`ìËOüƱtëÖ-q¤/º1L"8xð` Ð’!3?ïZþ›¶¼òÊ+-Š2R*1Ȧk*YÓOÿñÿ1sk<¤>âú'ߨŽá/OìGHÃù-%ŒÆ´ÿ{ßû^رcGÎé„nàÿ@<ÐnŒêâ)'¿l.Ä`œåC8ÆS{¦Zë¿¶lk{…‘#GFå …EÅ€p a~¿‘íwö·uBLG~¿³“î ÆãoŒO~«ò×áä¿ý·ÿÏ%TÑ·¾õ­N$µ—|hm-Ò…ò~ñ‹_BŽàå‡û¢Ü„h ¯:ˆ}S½¹–2 ™’½Ç(›6 *¡Í)!Hù»¿û»p×]wÅPYï霖Öí{'¶TºÇ%  H@€$  H@€$  H@%œþùaïÞ½ÑhEŒo\ÄW2_"kI@èP„á L_Égb³Q£FEo@Ò1r!ð„׃ô•;.ø1ö'ÁF6Ÿzݦ|Ž(!i$BA`(>|xN8„öhóš5kâÿ9„=Àˆ‹Á{ðàÁ±Æ½‚XzoÙ²%lܸ1G$A_a@æÿ/ú³%ƒ9ýËùˆ-RÂ`xÀ`͸`Lüæ7¿‰a]i$fŠÏ8ãŒ&Oœ¿páÂhOù¶ÇºÖú¯-ÛØÞcá²Ë.k"PoîkBödì?ýôÓC=Øl–ðBÑ·oßfûÛz¿_,¶nÝï ÆÛСCÃĉãXå^M÷cY6!Æà>§„^Ù¾}{§žzjS>ˆ<S„9Ák ÷~61ö¯½öÚpÖYgEvÙc…¶¹gþþïÿ>Ö=+Ê€a¢XƸ·¹W¹ïYK!ÐÚ³gOS¶Ü«S&MšÛÞt Ì …e‚ò4 H@€$  H@€$  H@èxLúßzë­áÆoŒ“ùÕ|¡Øñµ¶D H@¹0.þô§?ž2’!3’1ý‹_üb4bO‰¯è÷»ßÅP|éÍ—â\ËÝ])-^¼8Š.’Ñ럄Á£Â Ä„²Â˜Šá¶=¡’7 D3&L—_~y\ðN„Ôãí½÷Þ ¸ÉëuðŒ!šÿÃJyÍ ? _²nݺ¦2¹~Ú´i1lù였û}Pî¯~õ«¦ñ@1Væ3Ÿ‰žȧ#R­õ_[¶¹½ÇÂ¥—^XRBˆúÕ¯~5Çs ›ÿú_ÿk/¤ó:ce¸Á‰yóæåŒ7Ú@Ø‘%K–Äû:ýÞ±þÑ~Ŷˆ¬Häƒ0ï2䓟 ˆø‡ø‡ðôÓOÇß¾Ôfî;jRJÝ[œÏ=Éý…À"ý¾°Ñ×%—\¾ð…/D!ûRB AZ´hQ¼–ñ%µã7ÞÏ=÷\¸æškrîÍxQ ÿüñ×½…=, H@€$  H@€$  H@è,ímˆë¬vY®$ÐøÒ|ÅŠÑP˜ZŒÿ´ÓN‹†ØÉ“'7ûúQx 41t%S>õ¾Æ›^"î¼óÎpî¹ç†¶Šõ”)Sâ’ÎkÏuedæÌ™áöÛoFè|a óÙ³g‡~ýú…o~ó›p Yã/¢‰‹/¾¸¤ñ˜ „·ÉŠmŸ HÌedÛŒà£2Fb<¤r|ðÁf/ú©_G¤Zë¿¶lsGŽ…¶¬w{ä•eqöÙg‡¯|å+Q´”?Î/qŒ±ýä“OFo?©>6lH›ñ¾À ÷;ƒ’à)€×œ¯ýëñú§žz*G¸ôüóÏGˆ¸ò¯K׳æž|øá‡s~ws öEÀÄ=^,á„ûzxøÈ†hùÙÏ~›ñôQIê˜;²’y®$  H@€$  H@€$  H@€ºŒæ¸ßÏöh_mßqÇÑ-~¾q3Ût ÿ_þò—Ãõ×_Cj”2Df¯«·mÄxÁX›DÕʧwÝuWÏä‹2²õBQ(d‚ Â5$ÑDöš´'¬(ƒý½ìd=e¤ó³kxÍŸ??ǃá`^zé¥cxöšöÜ®¥þkËvvÔXhË:·W^°8ï¼ó¢`‚&Å~·5àƒß®B‰|æÎþÃø%ÃýôêÕ+Üpà 99È>«V­Êkä—ƒ€ Ïù¡P÷ƒ§R¢Œl^W\qE ³’më»ï¾½fTRJaF–¬Û€$  H@€$  H@€$  H@hC¸äýõ×Ãû￟“+®ûñ”QÊèŸ.ÀÅÿg?ûÙè^¿˜±3[k¾bÇ{Áä„3茶`€ÅS¢¾äÏd‹Õ‡¾äËúlÂ0¼yóæPÊx‹7…ëñ”Q®ÑQFîlj©Ìì¹mµ]Ký×Vm"ŸŽ mYïöÈ ³fÍŠÞ0©Ó’@ qpòFäsæ™g†¯}íkQœÖR] ë3zôèf÷!"¤RÞƒvíÚ–.]šsÿ%o•xaã\D&ù÷žnJÝÛ…Ú¥0£÷I@€$  H@€$  H@€$  H  n‚/¼³)}yŽ¡°Ü„8ãsŸû\ é‘oì,7Z</Þ)-Z”ãý¡³êJ(B1&¡QõDÀñ8¿_¶mÛVò«þM›653å6¬Ù¹„»Ia'8§½S­õ_[¶·#ÇB[Ö»=òJ,ç-‰2(Ÿ1L¦|A&DŒÝróA’/"¼(%ÌxõÕWÃrPàå£P^9'øƒÐJù÷ä{ï½WÒNl‚ÂŒBTÜ' H@€$  H@€$  H@€$ 6 À—Ýù†rŒ›x;È7ä·T®ý‡ÞÌHØÒuµ|¼OŸ>áOÿôO›yœè¬:’ù†Ø–ê3bĈfýI…R¡LŽ;Ö̸œo€.Un¾· ÎEÀSŽÁ»T¾•«µþ«¤î-Û‘c¡¥ºtöqX0Æ+¹/Üì|äSÉ0`@AaF©{kõêÕÍ~w§L™Ò¬>åp¥ü| ¨B÷_©üº•:è1 H@€$  H@€$  H@€$  H z…<àž¿ÜpÕ—\Wâ!¢Rƒo-¶Œ3ùÆæ£G6^dëŽÈ&_œÃ—øyò ÁÙëÒv¡°%ãÆ+ëÚ”Gk×]¥ÿZË!{}5c!{}WÙFÐP‰£X»ØìÞÚ»woÉ{kíÚµÍDQˆKöïß_ÕýÇ®M^:MÅo{¡¾.Ö…Åȸ_€$  H@€$  H@€$  H@­$PH˜1hР61X¶²j^Þ† yªøàƒš ¹…Š"J¾0ƒ/ý.\Z sCÞ¯¼òJÀëF6;¶YžÙãn·?jÆBûתãKèÝ»w3AE5µ ŸüÄø/• …yûí·ÃÃ?ÜÌûF©|Ò±BÞ1ð†4~üø²Ëf$š®%  H@€$  H@€$  H@€$ÐÆŠ 3* YÑÆU2»v @æ{Ìh©DxØ·o_“€céÒ¥aþüùaîܹ1,I¡<ð¨G€gŸ}6à•#%¼°Œ3FaFÒIëjÆB'Uµ]‹m«ß¸Bù”º×Q9r¤YÛ–,YÒl_kvª¨’¤0£Zž+ H@€$  H@€$  H@€$ ìÞ½;†¦È^‚[üBÆÆì9nw}„2™7o^ضm[“!cï}÷ÝEÓ§O¡RX“dp^¿~}¸÷Þ{c+% Õ³gÏäéØJT\7"C‡5 Ú«ýxE!S%÷šÂŒöê ó•€$  H@€$  H@€$  H@hhx68xð`3#a%Ƽ†Ø¿îºëÂoûÛ°aƦq²jÕªðþÏÿ ‹- S§N „¾aÌìÙ³'¼ûî»áÑG ù¡FŽ>ÿùÏG!G`³‰(J X˜“!C†´"¨h¦™'tR˜8qb\JyîÈ\7fäño H@€$  H@€$  H@€$  ´ x={öŒÞ>þøã¦8>ú裦¿Ýh\Œ‹^½zEáBž”ð†ñãÿ8þyÊ)§Ä1DØ’ì8Jç"Üøìg?&Ožs& 42t¿ä3¸òÊ+^hZ+Œã~6mZ tP%IaF%´ñþÉf¹cÇŽN¢)ÌÈö†Û€$  H@¨AÛ·o_O ÎH‰/)˜Ä9ýôÓðaÃÒn×€$  H@€$  Ô63šó^ÿÁTUÓj=\`Ì?á„rÊDPMH•jëS¸„_ÿú×áСCM$Z|éK_Šáo–-[Ö®]˜ÚµkWì'D>C‡sA&Lˆa ‰š2¬“ ÇftTUsìØ±aÛ¶m9¿o3ªù½k«f+Ìh+’æ# H@€$ v"À$ɦM›rrg·–¼P(ÌÈAã€$  H@€$ š"0dÈf îÛû÷ïßL,QªòxPØ¿UÆÅSN9¥™{æŽ?^ªÈfÇd1o™ÿ&~®›˜9sfd™ý­\·n]XµjU˜;wn3ÎÍshû= 3Úž©9J@€$ÐNxQüÎw¾6nÜUÂÄ\œ3gN¸ýöÛÛ©D³íêx±a<ýÃ?üCزeK|ÁA”1oÞ¼pÓM7ÕLó‰:nܸ_4©¼&%÷•5SQ+" H@€$ v €˜šçv„ú<ãššgd“$ z!0kÖ¬0räȰoß¾&ÏÔ}éÒ¥áÜsÏÇŠäSe<ûì³áÞ{ï3ÒþJÖÇ!2²×0Ïðä“O†I“&…>}úd5ÛF”ñ /„þçŽmiv‚;*"5§ éã‰'Æ1ѯ_¿(Úic¼có÷#a÷!¿YÁÎÎ;ã=Úc!Ý ­]OŸ>=†ýÁ qbÉïÝ<mðÁgG'…MÜò$  H@¨ŠM¸w|æ™gr®Çm¢ÂŒ$þQ¼° Èxþùç›®âa¯XjI˜ÁW+W_}uœ¼aÌ“ .½ôRØ4õœ€$  H@]•À›o¾¾ûÝï†×_=~Y~çw\½wïÞ½«6ÙvI@]ŒÆÖ „w> [‘Þëiâ²e˯~õ«ð™Ï|¦¤çN¼*$AócÕ¦¾}ûÆ?ðÔ0߯’ü¯õSY„OyñÅÃ?ýÓ?ŰªÉÐ™Ž»®œÞR†vïÞÝfÅŠqÃ1†eÂ×&/ åY0ÚÓO|´Ãa@8‡ØZøT^ËŽ¹Â±ùGÎxñ¥³áKð’3{ölŸ}þˆ©Å-„Mü®ýøÇ?Îù½{ùå—£áüóÏó«•Ü3Ø(Ø;v,œzê©ßo 3Zì6O€$  H – øX˽S¿u«µqÅ×€Làà!Ï1$^ÒZú’¥~{ÀšK@€$  Hà–/_6lØ 5qýOÜpÃþ‘‘[@í¸è¢‹Â/~ñ‹@“4ïÀ#?ùÉO¢q#!Fúìñ‡Ž"B‡üô§?mòRA>k´­¤õW^yeX½zuÓü×"öøá>ÿùχɓ'Gª^2ËG-Ô©5uˆøO4²_xá…¡ \Ó¸àÿ<–Å‹GJŽ#"ÂHKb0fo°¦ïF½KØÔ2vÇæï{ƒ¾0aÖÅ_N;í´(ÄáL~?Lq2ê±ÏÛ{<^~ùåá©§žŠž×Òý·o}ë[aóæÍã#FŒˆL‹ 48A‚ ~ _}õÕxÏþå_þeÅs³ 3Ú»ÇÍ_€$  H@m@€—„Š1Ú¦YH@€$  Ô\MóÌ„8_ÎDouÕ…VVø„¡Î;ï¼(´ ,IJUñBOšð•7¢ÎgÿÔܵR>m£?iSº¿ªSùåù·$  H@@×!ÿÞÔuZfK$ F"pÖYg…¯}íká'?ùIü"~×®]q®¢æ ˜óà+n¾úÆKïÍÞyÎ&æ)ÊJâ „|™¿aÆÀ;z¡DžÔEW_}u¸ì²Ëb8?ß \N8'ÿ:æÊ­{¡:¶&ÏÖ\›_—Bí`þ°XÛ˜zî¹çÂ÷¾÷½ï'ãÇýƒ¨‚k™KáÜ4WÉßÌ“âU…8+V¬ˆBæÍ’çÎáž{î §vZô_×jÿnK^…êÐUÆf¥c!Ÿ!…¸ÏŸzê©xÒç…÷á:˜/.4Ϊí¯j¯Ë¯c¡|JÝù×§¿á™ÿ»QI>õ©OEÏÙsÊÙÎýÕ.ç Ï‘€$  H@@€—_~9¼ó‰?/¼Pä'žyä‘üÝño Ö<˜òS*aHçAŒüù€˜qï¾ûnÀµb^4yˆäá 7Ž|Ý0yòäøbà ,†å&Ê"6çÓO?ó&_^¶ˆýÈ"íä¡{õêÕaÙ²eaíÚµM/ÛÆ 3f̸³£üöJÔvŸºRx°—>òyIJ¢Ô &Ô¸Ï妖Xç0AÁK&n>qáG?Ñï<S‡qãÆ…ÓO?=L™2%NT”*PÜÓ.‚Ú–Ÿx±-6®èï‰'†3Î8#ÿ²Xßöè_êI¾|AAÝèâj3™3iÒ¤fõhiGGõq¶L  Hçžfá^ãoú—ûû —Üô%ýÊýÅX3I@€$  H@€ºéÓ§‡ÿøÿcøío^zé¥8ÃüÆWæB˜/bþaàÀñÝÞ¼yqî%Íy0‡DX§õë×ÇóiL˜0¡™X£3ò"´ ‚ •Ì0o’ê> `.Œy—K/½4γ¥: Ö`ndË–-q>‹yæKò#ùu`þèÌ3ÏŒsÌO`lÅH%ókm™g[Ö‡ùºY³fÅyFê‹iÓ¦ý¸æÿò/ÿ’ÎW¿úÕØ¿Œ!>J¥k¯½6 }cÂü]Jxá`>Ì7j§s*]·%¯bew…±YéXÈgÁ|ؾð…8~~ùË_ÆpüFð¿Œ-î9úï3 ¥jû«ÚëòëÀÜ^ö~§o¹ßÓïHþùÅþæwjöìÙq¾>}àÅo`%ùpîå—_C1=ûì³qŽxãÆñžaÞ2-Ü+ðM s–Ü—ü¾1˼eº7‹Õ·Øþ>ùÑû¸ØA÷K@€$P_pµuË-·”¬4÷Ýw_Ésjá ÆZ^Py8ª6a¼æéïÿþï >,ñ‡ø‚—D½”óxÄ|)0uêÔø\H•œ_w¼0,^¼8|ûÛßn:„aý¯þꯢ؂>Ää<óR–N¦\ aÓ 9/…ðà¥:œJ%Di/sæÌ Ç/롸 ˜âU¸¦¸˜{æ™gb_«Ä&&'}^ìe¡Ëÿú_ÿ+NxË«¥ý<ÄÓοþ뿎èÙóKµ‰²jû·P¾ˆ`øZæë_ÿz¶ -nwdSÆO1¶ù¤%5:/–L\Ð>„HÅ^.[ll'Ÿ€è®»î*Y ^Nï¾ûî’çxP€$  H@@­à݇w b‰÷ÞLÍ ` dþ…xÆðÚ¿ÿ8ׄ؂÷ÿBsNgùЈë9‡9£Bç5/±ùæÂø „y1¼.0'Cž|Â|F±: â ÎÔ¥’:p]òŠš>¼©¶î©5­É³5צòÓãyò\QŠ ó%÷w{ì±&ÁÌ9!Êøô§?Ý¢#•—Ö”û_þˉ6Ñ)ýçÿüŸ£—8·UjK^-Õ©žÇf¹c¡%é^GdÃÜ"ój7Oð±\KÂjû«Úëòۓ͇9\~ߪIäÃï k~ïªÍ'[6÷*sáä‹0 ¶2Ò½KxÈh«Çô˜‘¥ï¶$  H@5C€NÄ­I<¸cÐÆ¯bå凗͇z(<úè£EÃV+ŸT¼^¬Zµ* ®¿þúø0\ìü´Ÿryx̦´oûöíeû/~ñ‹¢†k®Í*ß³ù´v›6á¥äßþíßâd õ*'Q'¦nÉûãºÜ{šI(ÆýI?_Ô$ H@€$  H@芘[@üÀRIbÞáD[$DY*IÌ·áý²ÒÄumU÷Tvkòl͵©ü´ÆHÞ’¡œs™ß[¾|yS¸]öáý€Tʹžó³‰køXiݺuQ(“ŽaÈÏ 5ÒþÖ¬Û’WKõ¨ç±YîXh‰Aº×¹gMSiª¶¿ª½.¿~m™O5¿7ùõÉþçæ‘;*åÎ$wT©–# H@€Z ÀKéÈ‘#ÃÛo¿Ýt&B –üTÌûy¡)ô2ƒCñOúÓüì¢!8=8ãy21£rÆ Ï—)ahFØjo ù†út^KkÄ¢"PV±ÔÚ¯Šå‹°á…^÷Þ{osʃíC)Œº‘çÃáKâÁ>¼!ÀèŽ;îˆâŒbåÛkD^~ô£åˆ(`‹‘ž‡yÊ‚uI áNˆËIù…BØÐ¯¨É³žX*W”+Ñb^9R}²ëÎî_êÒ}ÌÁ%+÷ ô”èK^&Q·3¦èúóSÈÎåoT& H@€$  H@€$ЕB˜yæDRjí—ù|À“Í|1d·ôñT*ßµ$оf´/_s—€$  H Jà Bx‘”xYÁðžMÇ‹¹Âä!' ½|ð¢²råʦ¬8/+ãÇ131à'—h|¹OÌÌÕ«W‡7ß|3G0€ï*ýº ø@!ÿ›ßü¦I”áš|I€Á ÷¶þ¢ ~ðƒ„w>q™L¨ÃÌ™3£{̘11L ìpo™…ßÖ@€$ 0¾ÿÉŸüI\8Ì‹ Æó;ï¼3çl íÿûÿïœ}åü±——^PÈ1Æ\Î=÷Ü¢n1âc8&üÉâÅ‹£AŸ²Ø€˜¼ìTjH&†(B‚d¼Æ«bˆ+®¸" K0\ãEà­·ÞŠžÆWNË:'µéá‡ÎeÀ&ˆc®ºêªf‹©S§Æ>AœAè™òßÿûÏ9M5ã*'“?üÑ™ýK:«Ù02¥ÄØž;wnøÚ×¾ÖL`4|øð0kÖ¬°páÂØŸK–, 6lÄÓ5I@€$  H@€$ ®D€òÌýñÑsùÇJµ‘ó’xˆÍŠ=øèŒ¥˜·áRyzLh{ 3Úž©9J@€$P0𳑠Š,ˆÛ¥ªŽP€ð*ŸùÌg¢Pâ‘GiÒcÍš5Ñ!a?*Iˆ²¢ êóÅ/~1Ç ç D#,m™Q¼üòËáÙgŸmÊ–—5\'Þzë­‘Q±—7öc4ÿ³?û³Ž‚Ð0IÕŸÄL*å‘DfæÏŸn¾ùæè¹£©‚Ø0`@l`ìÿÎw¾Ó$”á0Þžyæ™(ê@|Ó™©3û—vwV#Ì@¸“ML: ö¡o‹%ú ñÑm·Ý¿©$dL±<Ý/ H@€$  H@€j‰¨ða’“˜x´å£"æÜ˜û*6/‡82˜ãØûï¿¿É£-ídÞŽ¹O>~3I@µA@aFmôƒµ€$  H ƒ ôêÕ+ÜtÓMá†nˆ¢‚JŠÇ¨¼V TáÅ•$00Æ€OQŸb‰—Kî+Iˆ^¦¾„<ËIˆkµ3sóæÍM—Е–ßtqotFÿÒ„ÎìcBÌðUÇo¼ÑD±ÎòåËãÄ@5¢¨¦ŒÜ€$  H@€$  H@uN€ÉwÜqGøáçè²aMháJ˜Kai)თð”qË-·„éÓ§GO-]çq H ã(Ìè8Ö–$ H@@"€0c{6áÕz¥‰§I“&TòlwT"ÜÇúõësŠ#tD¹¡&²Â!õÿðÃã!x àçïrÛ…ªcþ!C²Ù·¸/ Yaåf]A¶˜I;ÐYýKs:³KùÞcO<ñD`âwœ¥ÂÔ´Sw˜­$  H@€$  H@¨| õo|#<ùä“á¹çž‹aLÍËœVöcªü ã ƒ^˜a~eĈaîܹaáÂ…Íæ,ópšª@IDAT¯õo H s(Ìèî–* H@@@¥ÎBb/6`_!‚-5•—( Õ¨Ú;2>|8Ƣ̖‰À‚P"ûöíËî.k¸Uäå‘Ê@Õ?xðà²ò¨ö$ú"ßÈ0#ë²Ú¼[{]gõ/õîÌ>f,0¹€€)'úßùÎw§?ýépÖYg…SO=5ö®5[;Ò¼^€$  H@€$ z$€W^Â_qÅÑsƪU«âÇG;vìx¤e>…y6æOð8Ëb Bã}væÌ™—L@íP˜Q»}cÍ$  H@è+0"£HǨ×–>ø ¾%á_þã^°žS¡P#¨ñ_yå•Ïå¶±Pت½…'žxb|!ÍÖ•—Uú­‘Sgö1ÞO˜`R¸¨I$Ã=´qãÆð½ï}/zŠ!„ϬY³¢Ç&"¸Î$ H@€$  H@€sÎ9q¡íÌIòÑMš§d® ñ ž2h˜$ ú!à[?}eM%  H@hG¼äìÞ½;lݺ5¼úê«ÑpŒ§B“ Ô8xð`I÷íXµvÉš9 åî³ ÅC=”ÝÕªmŒð¥Ü.¶*óÌÅ|-€8ÃôGµÐÇr®¾úê(ôyíµ×â}”jÈø[½zuüdذaá¼óÎ‹Ëøñã£Ç¯<)×€$  H@€$  4"J9?œr#²°Íè ft…^´ €$  TMa† š5kÂóÏ?½E:t¨êüêåB\ â£=b ”þC† iÏbÌ»ZècÆÀøO„wÞygxðÁã=†§™ä=ƒª#ÞA…W%K–„Ù³g‡ „ÓO?=Žò0I@€$  HxÄ#Œ¡ÏˆŽ H@€$ z# 0£ÞzÌúJ@€$Ðf`¼ôÒKáG?úQxã7šå‹†³…zÖ#Æd„ ù'šeR£;ð¦€á>?ÑÎAƒ5 ’^K3QÚ»wï0gΜ0|øð–N÷x;¨•>æ¾;vløò—¿f̘~ó›ß„·ß~;†¸Éá™æé§ŸŽ^k.»ì²ð©O}* ;˜|7I@€$  4.„½„ÃCЋW6ž/qán’€$  H@@½P˜Q/=e=%  H@hSLì-]º4|ûÛߎâ”9‚&øðò0tèÐ0`À€Ð¯_¿èù!ZòòåË£§tm=­1–Ÿ|òÉͪÌ$ç 7ÜFÝìX%;0¤#ðÿ‰·S稵>Æ{Êå—_æÎV¬Xï?QxÐØ¿ôœ‘H>ˆ:›6m þç&Nœ˜¹–€$  H@h@o¾ùføîw¿^ýõø®‚G¶³Ï>»Õ‚òDi“%  H@€:‰€ÂŒNo±€$  t¼]¼ûî»á?øAŽ(Cöˆ#Âyç.ºè¢J¡G+ºmÛ¶°wïÞºf œ m´)±#ø¹çž›v¹®SµÚÇ}ûö —\rI¸à‚ Âúõë£@cÙ²eaË–-a÷îÝM´?'Þ rÇw®3I@€$  4&Dñ„ $”É;ï¼V®\¦Nؘ@lµ$  H@@ÝP˜Qw]f…%  H@h-Â'<ùä“ÑnÊ O„ܸõÖ[âE‹Òî.½F„ѳgÏ@H—”0†ïÙ³'ýéºÎ Ôr6‡ÉôÉ“'GOO<ñD`A ‘ÄBŒÍßýîwáœsÎ óçϯóÞ°ú€$  H@Õèß¿ôbˆg5<âéçI“$  H@€ê…À‰õRQë) H@€ÚŠÀÑ£GãWúÙü˜Ü[°`A¸òÊ+³»»ô6mFŒ’M„xQ˜‘%RßÛõÐÇxm5jTøìg?n»í¶pê©§æ@?pà@X»vmÎ>ÿ€$  H@h,çŸ~¸âŠ+ÂìÙ³ÃÂ… £p—Py& H@€$  Ô =fÔKOYO H@€bØ| üqtgÛ­[ù5‡Žnp³yaÀ&„ ž3%õêÕ+Œ7.¼õÖ[MMÆ›ÈæÍ› ¼-4BBŸðØðá‡ÂÔsª§>¦®sæÌ ›6mŠa†w„TxÑà^o¤û3µßµ$  H@@C‡Þ o¼ñÆøžRïÏéö©$  H@@ãh> Ýx l±$  H@u@ƒìÉ'ŸÜLœñœ/êËMÜ B%¤ë˜Ø9rdú³Å5FbÂ~Ôsâ ³‰'æ4ÑÊêÕ«cÜæœ]ôDPòÅÄ®>xð`Ý·ºÞú˜úN™2%‡;÷Ùþýû£+ç€H@€$  4B1*Êh¸n·Á€$  H KP˜Ñ%ºÑFH@€º>„xµèÝ»wNcfìܹ3g_©?ȇ‰¼|-%”“ð&W –zN°ÄN¼ælÚºukX²dIôš‘Ýß·d0¹Ë’M]%¤Kg÷q¾*˸Ð6÷'KV(ƒpfàÀÆ/Ì}€$  H@€$  H@@]P˜QÝd%%  H@€‚ ´Ù„ý•W^Éî*¹Ñ—<œsù¼þúë1\Bμ?Ž;V®\~ò“Ÿ„U«Vå­¯?á9f̘Ÿ9[s<¼øâ‹aÅŠUy€%b™Ý»wg³­ÙíîÝ»7§À`Íš55[çr+ÖY}Œ` Ïk¯½¶mÛV¶· ¸¯]»6Ç£ !N§& H@€$  H@€$  H@õJ@aF½öœõ–€$  4 ŒÌ§žzjNË=ž}öÙ°iÓ¦ã/á`ÎOx˘0aBÎn¼e,^¼8lܸ1'Ÿt_þ#4xþùçÃøÃ(\HÇêy=hРpñŇä4ãÝwß ßþö·ÃO< ìˆ-ð*R,!XÙµkWxóÍ7ÃÓO?î¿ÿþðË_þ² ËbytÖ~Bää uöîÝ^xá…ðÞ{ïD)ÑÎ;vTä¥%]ÛYëÎèc<òHøŸÿó†{î¹',_¾<Þ‹ð+”[\óòË/Çñ“=¯ù÷kö¸Û€$  H@€$  H@€j@·Z¯ õ“€$  H@‰! fΜ–-[Ö$øàƒ¢çŠï~÷»áê«¯ŽžQ`<Ç£Çÿò/ÿ2'4†ø3Ï<3‹0¾¯[·.|ï{ß Ÿþô§ÃðáÃåRñ¢Ê}üñÇÃöíÛã5ÃGÖpÔÑ?°8ýôÓÕW^~ñ‹_ĶR}nذ!|ÿûßž#Î;ï¼(^À{×ÐvÄ/ðÅØŽ€~xyë­·â±3f„k®¹& ¨åÔ§OŸÒ…º'ñ }N>gÁ‚¡oß¾±­´„¹õÖ[sÆU­¶±3ú˜ûjÏž=Ë£>…LsæÌ‰ÞYFÇPº¿8Q÷+÷×;ï¼Ó„’sƦNÚ´Ï H@€$  H@€$  H@õF@aF½õ˜õ•€$  40ž={†K.¹$zb@x‘†]¼4<óÌ3M ½Ù‡ î¸ãŽ€  %Œí—^zi4¼ó%2Æ“Þ7^}õÕ0mÚ´0tèÐ>¯‹“÷ Äýúõ #GŽ [¶l ûöíKY×åzÈ!QÔB[à÷”àøØcÅþ0aÁØðàÁ°ÿþØ~Œðù)qÍß_kÚæ‚ .O=õTNøÚ‡¨±@f:t(ŽÄ,7ÝtS€I=¤Žîc¼ÛpŸ‘›`‰¼“0†ìp÷÷ã/;f86iÒ¤ð™Ï|&Œ1¢0[G H@€$  H@€$  H@ (Ì(ˆÅ€$  Ô"„2Y´hQxðÁ£0 [OŒº|¡ŸMxvÈO䃡ú¶Ûn‹!)6oÞÜrƒ<¼øâ‹ù—Å¿1#ö¸è¢‹ÂìÙ³c¸zfа±cdž¯|å+°/½ôRäˆ×Œl:räHô¢'R ¾ä3f̘¸.un-£OñÊ0þü(@É S¨QÊWµÐ–RuèÈ>F°Bø<‹dï<¬ ÂH"§bõMž2>õ©O…sÏ=·Øiî—€$  H@€$  H@€$PfÔE7YI H@€ ¾„ÇÀ›Á /¼ ¼ù‚t.Æ]ŒÑ…¼`ŒÇ+ÆW¿úÕðÐCÅð|Õ_,/ÎÇK|B[\vÙe1|e¤„$ûwÚŸ]sN·nÝb”ä€}Ý»wÏžÖáÛÔaüøñQœAŸ{î¹°uëÖ(RÁ“HK 1œ ‚G„éÓ§Çð(xÖ(–Ú’E!†ìk©?RÝðÞÀ¸J!LJ¼¯Œ5ªÉ#Dʃu[¶©­ó¥nÕÇ0"ü chéÒ¥ÑcÞWf”Jô¢©)S¦D¯6x2al™$  H@€$  H@€$  Ô3…õÜ{Ö]€$Ѐ0Ò><ÜyçaÆŒ1Ì_ êV r@$€ñüÚk¯-jØÅ|á…†Y³f…'Ÿ|2†B!¯cÇŽÅO ˆ(É€±øÌ3ÏŒçcÜ&Þ¯GdA¸„ ¥e"|8묳bÈÚƒ(‘H-$BLÜ|óÍ1d a]V¯^Å/„ð€†uÖU`ÂøA¼O;í´@˜¶9§TjK7nŒõƒk9ý‘êG] ›Á¸b,ñãêøñã±W”ÃyW_}uÁqÕ–mJucÝ–ùvTsÏÜzë­aÞ¼yáùçŸc ÁKbÊ8"1~Xh#qW„— Æ”I€$  H@€j—sxÄó(ïz& H@€Š8á#ÂÇÅ{D€$ z"@x€[n¹¥d•1|Þwß}%Ï©§ƒÍ1öîØ±#†%áo<[`”G€p ÜÄ$ÂîÝ»ÃöíÛc^„î / Ù. Š™„ ÌT/ä#¿|Î¥,D $Œý…òο®3þÆx_Ô— cD§Î,KË”òŽQ¬îmÉQõCPA¿#œ©¦NÔ5;äMXÆK)ÑI[¶)Ë­½òmï>Nmà^á7ŠÐAŒ%î/¼xàa……qãRlS^õ²~å•WÂ]wÝU²º¾î¾ûî’çxP€$  H@@gདw:>dá}™÷9ޗׯ_V­Zxÿᣎb‰÷ÞL€$ F%P¾¥¢Q Ùn H@€jš^ °´6áùbäÈ‘q)7/x¨$áÍG9"ŽJòms1’6,.í‘[²ÀÈŸÄ"­­k5c!•Ù–mJy²n¯|Û»S¸WK±˜$  H@€$  H c òg!¥5B‹´?‰.ø !m#Â࣌´ð"Œ;wFÁý–-[¦M›â‡œÛRâ}Ý$ H@ht 3}Ø~ H@€$  H@€$ .C`ëÖ­ÑhÖedC$  tq“'O½{÷n—V¾ñÆ1Ì"Œ$º`1á`^à#yÁ@€× ¼ž„õž={â>„Õ&¼‘òaI€$ÐÈf4rïÛv H@€$  H@€$ .EàÑG ÷ÜsO—j“‘€$Е ´gˆo}ë[1ÄHgó›:uj 7ÚÙõ°| H@@gÐTgÒ·l H@€$  H@€$  H@€$ÐE 4(\zé¥aðàÁ]´…6K€$P=f”Çɳ$  H@€$  H@€$  H@€Ê @è’¡C‡†O}êSaîܹ¡W¯^e\å)€$ ®K@aF×í[[& H@€$  H@€$  H@€:Œ@Ïž=ÀÂØ±cÃUW]æÌ™z÷îÝaå[$  H V (̨՞±^€$  H@€$  H@€$  H † Ä2dH>|x5jT7n\˜4iR\ô’QÃgÕ$  H Ã (Ìèpä( H@€$  H@€$  H@€êƒÀ 'œN9å”èù¢_¿~¡ÿþaàÀqA”AÈ’#FÄ…c'žxb}4ÌZJ@€:€ÂŒ„mQ€$  H@€$  H@€$  H £ ª@(‘]ŸtÒI¥[·n¡{÷îq}òÉ'ÇmiÁã1EÂÒ·o߀0ƒaÆ Aƒç(Äè¨Þ´ H@¨g 3ê¹÷¬»$  H@€$  H@€$  H@(@ફ® ³gÏŽ" #Æ@ Á’IœÑ£GÀ‚(‘kDIœÁù& H@€ª' 0£zv^) H@€$  H@€$ º#0}úô0sæÌhtÃHWnúè£ 騱cqùøãs.ç«éôe6ycØkï20bd,7}øá‡!ÕûðáÃáøñãÍ.Í7^ÒËU³’Ùá¸ò,ô[²téÒ°k×®ÌHéØM„& H@€jƒ€ÂŒÚèk! H@€$  H@€$ !pÖYg…Ïþó‹&<XHï¿ÿ~Aa_Yãêž/°«fTSF¥ÂŒÝ»wÇúÓŽ#GŽf$·ýˆLøJ¼Ra†e”o¤—•¬ ºÊ=¸nݺNfð;g’€$  H 6(̨~°€$  H@€$  H@èˆ'0zVšð’±ÿþ’—!b oʨ&uD‡Š‚ŒRõK“J¼}dó³Œ,ÒÛ²*Í'{TVY¥·k…UéZzT€$ F" 0£‘zÛ¶J@€$  H@€$  H „üHa?Ò:ÿrB|¤%…1É?§ÔßQF ÁRªÔD[Òv©óóYF>‘â˪8›ü#²Ê'RüïZdUI¤â-óˆ$  H@]€ÂŒ®Ð‹¶A€$  H@€$  H@mL#çáÇãBÖG-XBòÀ˜¡G1„IÁ ììˆ2>üðÃèé#…KHëüê$OR ]R‰8Ã2~/jÉgZèoYɪ‘îAÂ:™$  H@|*pH@€$  H@€$  H@ÍàÉâÈ‘#aï޽͎ew Æèß¿¨ÆÙQe8p ¨°$µ¥gÏž¡_¿~ 2Òµ´Ã2ÒkY•æ“=*«,Ò۵ʪšßÅÒ-õ¨$  H@õJ |yn½¶ÐzK@€$  H@€$  H@€$  H@€$ N" ÇŒNo±€$  H@€$  H@¨5)´È±cÇ_ ã1£P"ÔG¯^½a?eRIØŽ(ƒpx°`My|ðA¡f„¾}û†îÝ»ÇvÐ&ÚSn² Y9®Šß-ÞåßÅ)zD€$ ®D@aFWêMÛ" H@€$  H@€$ VÀ˜zèС°oß¾’¹ b4hPE‚Œ”aG”Áœ6 0)•úôéX*d¤ü,#‘hy-«–¥3d•H´¼î*¬Zn©gH@€$Ð(Ìè ½h$  H@€$  H@€$ &ï¿ÿ~X½zuزeK8~üxôŠ1|øð0f̘èá£éD7Ú…ÀÞ½{ÃÛo¿öìÙ=¯ôèÑ#ôë×/ è©Ä»J»TÎL+&Àý´råÊx?!†èÖ­[7n\˜2eJìÓŠ3ô H@€$Ѐf4`§Ûd H@€$  H@€$  $x°8zôh0°]ÌËFõž={ÆËXWâe¢#Ê@€A;(kóæÍaÉ’%á7ÞˆaLN:é¤hD¾þúëäI“¢a™†¤0&‰EKëllSV¡DˆŒ×¤F,ãå—_<òHضm[dDØ›‹/¾8œqÆ1N–Y£³‚E­«;v„Ÿÿüçáõ×_÷c›¾üÊW¾FÕÔµÞŽ¦Š¶°Ñíh¡ –€$  H  P˜Ñ;Õ&I@€$  H@€$  H \|àÀpðàÁxÉÇ\ðRÄ„/!!ʨD˜Ñe`LÅC_÷#ÌÀ[žRb „I`R©÷†läûÑG¥ìsÖ^Þ2Ö­[—gìØ±aÚ´i…öÇÇn-Ž+Âmܸ1ìÚµ«iœÓLJnú› ïþ! H@€r(ÌÈÁá€$  H@€$  H@h< Љ  D xž¨6µwJR¥ÚBªmG¶ŒR½ŒBâžBû`Øè¬`PëãªXßQ÷lªõvdëZj»#ÚQª|I@€$Ð5 (Ìèšýj«$  H@€$  H@€$P”,ð,Áš¯ÜYç'}šBŒ”Û8±”*ƒ¼ñú—¤u£–‘xj¿¬~OÅqUhtÞ×UXn{%  H@h 3¥§m§$  H@€$  H@€þ@Ñá 5¤¯Ãóá ÌèÝ»wèׯ_ÊßWíèèqUHà•ÏÍ¿%  H@h  3£Ÿm¥$  H@€$  H@€š ”ÀˆÊÛ•¤¬gŒÆ$ÿúŽ*¯'œpBô”A™•$Œ´ÉpJ› %B›àd÷îÝ1T åÑfÊdû”SN  Æ C‡mæE£œ2ààÀ¸'׌92öM~öìÙ6nÜ냇Ôv¼… >¼h_RK:¿\V´uÛ¶maË–-aß¾}Q„sðàÁÈ O+#FŒ}ûöc)•AªI´{×®]±ÚIŸ 0 ömÊ/•±sçÎðî»ïÆs8qL} ÆŒSTh”íÚF¿¾÷Þ{± ¥Aþ|èKxÒ–rY¥:fËH㊲G´¯ Y1SïÞ½ÃàÁƒc™ÅÆQÊ;­ •Á1úˆþ¡ÜÔ„Wx³ Œç­[·Fv0&DYC† ãÇýû÷c„¼R¬ …(âœÔ-+êDÛñ°Ã¹”I[I-݃å–3+ðOj‡RäŸÖeä—é߀$  4êž‹‘­•€$  H@€$  H@@—"€±C>ÆlŒµm+I•`PÍ=³ytTˆ"’QµR:Æbڂуq2>³& ˆíÛ·Gã}2¨s ‰6bü¦òg̘Î9çœ(V N¤beăøCý3Ï<6lØë@ß\wÝuaæÌ™M}ƒ1}åÿgï=Ÿí¨®üý¶1Øä,„,¡€D” „Y䌩ñÌ”ýbj¦fÞMÍË©š?d^§&|MF$‘ƒD’ Êd„D´ ÿxöüÖõ¾}»Oº÷žγ«Îí¾}ºwxöîpöúôZ¿ÿ}±iÓ¦bçÎ}~² G æ˜Õ?¾ÿùÏžÄ&üÿæ›o6l(¨ýžbßX²âƒeË–Ô &‘½úê«ÅÚµkS_}òÉ'•ùÀ! mDDh¡,òˆ<ËKúœ¾¤žíŒ£èÿªqTUFyì"´ í\"}öÙÅܹsÓ8|ê©§Š|0Õ­<†8/$ .LÞ;8>Ænˆq"Ï|Ùl\mݺµ¸óÎ;“0R$®=œ'œ#!P‰ïÊËfe”÷/ÿíÈÏóò>Ý(£\¦ÿK@€$Ð[fôVÛZ H@€$  H@€$ '€'ŒíÎ1‚‡!<Þp/£$O,»UF¹ÍþÇ ÚhOƒ~ÕªUÅ+¯¼R`äŽýâûfKDO<ñD2Æc„FQ.#ò `E‚W¹,ê‰AüÅ_,V®\™Œü˜›%„ˆ* \vÙe}Þ&¢¬fÇÓî‡z(y®€G]ý#êAAÇÒ.êÝjÊû#_ãÙ†á1eà}¢™PNˆ"¼.¾øâä-„>'}„˜Q£D9f!!‚ ?ñÊQ•òº#rxòÉ'“8d°ã–ÔŸró2ªú…ïˉmÔO÷Ýw_š”ÇZCY0Á‹©ªŒØ7ÎñFã ¡É=÷ÜS¬Y³&…o‰cñ²xñâ$<â:QÕŸùùѨŒÈ³¼lÆŠý»QF¹^þ/ H@@ïP˜Ñ»}oË%  H@€$  H@€zoýš!BC´Š£vxNÀx[eÜ[1¦v£Œv¶ú‚v—Û‡<)„A?Øài‚ðpÃ@NhŒÿìG¨“ÜëÆlÄ+V¬HžN<ñÄJVx _ŒÃ!hˆòXb$ÇÃÁc=–Dat§½x€àxêO"´JϱˆK_A˜êN_4cÅq”wÿý÷'O!å>¦í|È—ö:ƒcØc>ü ^®SÔ­¼Ìû£ê¶Ñ'*<„X€> l ã™<èƒ`e°?Âú Ï0yàúåc–¾@ÀP·¶!ò€u„‰¡ÏÊ)oå F`[ž¨+!CÚGôÅÔ©SSxš¼ŒòØÍËÉ×a‚ØOmò>- ‚h}ŠÐ†Ô¨ ÆÞ.Uã Ï.÷Þ{oñÜsÏ%®Q'xã}± c²®ŒüüheìFþ±l…U7ʈú¸”€$  H@ 3€$  H@€$  H@è!´1B·›0c´m”0 ’7et’ºQÆwÄU !ÀH}ÒI'3gÎLŸ‰'ö¢iB¼R~áØiûöíÅêÕ«“× ØåD‡~x2j³Ž‘ø yḼ>Û¶mKÇSfUæí .ù8"oŽƒ!}ˆ $>ÍÆ¡PhפI“’À¡nìF{ËKúƒ1J¢O£.'œpBbýˆ`„}šç”ÁùA7”Â%p牄(㢋.JÞ2 Á¬.åçGÝ>¶çýQ·_7ʨ+Ûí€$  ô…½×ç¶X€zœ“¿ýío{œ‚Í—€$0üx#Ñ$ H@ë0Ò†17–å6!(ˆÆÚ²À ¼ùÿn”e†·…ø?_†¡c-Fc|àõ¢NØ€ñƒ;ß#ÐÃ9‗_~9åÁ.”AÊ×ó:äë›6mêó‡Š K–,)Î>ûì$ ÀÐÞ*RPg¼ä^XÇsìY³’ø Ï¿¼ŽðáñÇOFü¼¯ie^rÉ%ÉcÿG;Øß˜ˆ'ÝU¡)òòõC¾ëx‰ýñ8AŒ¥K—gœqFÄþ°˜6mZqçwöÕƒï¨#¢ú#xÁsîܹ‰)l 8Ap„,wÝuW Iâ òï¢E‹ú„Q¯¨C,Cœ„gòA"ËÇÑÓO?]\pÁÉÓF”‘/£?b™‡Ø†6Ñ~ÆÞ*àÇØF0B¢ï¢P¯*¡Ež_³uÆâ<¯äc‘v ææ›oNžª1õoåü¨ªG]äûv» Úb’€$  H@P˜á8€$  ôÞ úÿøkµÍ•€$  H@€Ú%€‘“·ùà ¡+ªB Ñ<1¾V«Žc[7ʈ²1|¦¢N`Ax›/ˆÎ:ë¬d¸CnäS^âyñ„ o¿ývß.xˆÐì{ŒµˆåFf¼öášk®Iâ ìÒðM^x|`¶ã"¼5P‘—^z)yíÀßÈHŒwÍ›7÷;–¾<óÌ3“!Ÿ0Ñ·y;ØŽ× <Šº"Â~ôA(­P<2DýcYÚ­ïßà€Ç ×_}òtu‰ÀÞ·ß~{_8¾Ï½6 î8ï¼óÒ¾ˆ&ø?ïòaPGú/Âz"úŒ£ºv !„@`C}õ9ããÔSO-®½öÚb÷îÝ©,Ê$!ÂÙ¹sggÿ·¥ÿßè<¬”¹„Àƒ#¨Ëm·Ý–Æ6ç-‰þà¼Å{‰9ƒ£¤ müA¤ƒ ƒp1Ô%ù#¹ì²Ë’¸¤îZíÈû#òh¶lu\u» úÕ$ H@€ àSã@€$  H@€$  H@@u1t7J]ñ4Љ²eDÝ1ðc 'ŒDUÂŽñï·‰ÊÇÓ à …‘‹ ÂxÊÀ{F#AFž7†üK/½4yÀk¹êŒÚˆ¨;ÂÂuDbãO„1>¾‹%FíuëÖ¥Ð$±%‚¼ VÉ þUí`?êû?ÿó?Þ>ryž°¢êÚ‘ïëä‹Qÿ¦›nJu©ãÇX¤„A¤¢ŽÈ‡ïñ<‚À¡ ¢—ªþ`?_'¡þo½õVá?gF¿ê/ ¤(£+ ï‹-*^yå•d Ïë€è/”Q*QBy,ÁáòË/o*NÉûã˜cŽIÞA­‰v,\¸°@¼B9ÚÁ1Ô#äøœUŒÝÈ7_FU!Rb?ò"\ÎÝwß¼‰ð? QB¼“Їu×’(£YDyù²ÝvŒÖ2ò6¹. H@Àø% 0cüö­-“€$  H@€$  H@@[0tb„ÆHß(!0Àø]6¢7:&¾ëVQ^£%Æz>lÛMåᄈ%R•AÃ7 M´“¨Fkú#/£*¼xŒ@T‘‹"0ЇÁ¼|<íÀËAÙ[ùàYá )/£œGþ?ù0¶çÛ©C³°8Uü(—ÍBBäýÁ¸, Q/DäÙJŸWµ‘⌲g”¼­­²Ê‰uÚAÝËçüK‘Z-ƒö^|ñÅ©/ãØœUl«ZF„ç)ódD6ëׯ/îºë®$î!_lðö‚ „ò0Õ¥(£•þ(çÑn;Fkåvù¿$  H@㓀ŒñÙ¯¶J€$  H@€$  H@f¼?DÑu‚ˆø~¨—ÊFt¼eäFýr™xc£z|7qâÄá4â»Ñ¾ÄØßLÈÑJªòA$Óˆe+ù–÷!?ÆŸ:Ï&ñ}ùØfÿ#.iEØÒ,ŸªïÿûßkÖ¬)6mÚÔWoD„/¹þúë“çnÿªzºM€$  Œ 3FC/X H@€$  H@€$  Œ §xKÀ Ìzw¼dàрIJ·Ï»Qõ§”…·–U Cuí#ŒIÕ~± £ù‡~˜>ð`÷‚/¾ø"…æÈ=Mày"÷TAípŠ2YR.e!´¨Juí¨j,0ìGÊY±Ž' –yB”€AŸ©*ß|ÿN×óvÐÞvx•Û}^UWÄ*x.©ú®®îUazBDQ>&oGUù8bì0NG|b¼ÒG´aëÖ­ÆåQF§ýQǪÝvÄþœ <ð@ñþûï÷»fà!ƒ°)xˆ¡mU©«ªcbÛP·#òÍ—Ý(#/Ïu H@€zƒ€ÂŒÞèg[) H@€$  H@€$ JxJ ÔÆbRnÀÏ@ŒAøÆóv èÝ(cêþýû‹o¾ù&µCxUÂ(“r¸ˆ|xìÞ½;Éß|óÍâ½÷Þëã„Á Ÿ:^‘W;œâ–0C¨†øü;ÖëÚÑJßä¬Èkß¾}ÖéoU¬ev„ãÈ=?4Ê;¾£Œø”ó‹}†¢”QÕŽ(#ú$þowm ÄH'íh6Ž`PGy)Cî‚þn·?È“úÓïumé´?`¼`Á‚jçÎ;ï,öîÝÛׄ={ö¤óèÈ#,&OžœÆì`Çn³>ï´QéèóFãj°eDY.%  H@èM 3z³ßmµ$  H@€$  H@@@ðé§Ÿ¦0 ñz†W¼òñf< áA;©[e¾„²0¨ÖÑ£þŠë pX³fMqÇw;vìèg‡Ã¤I“Š©S§&™Ã£Dˆ29òÆoO<ñD2ª·ÃªJQ>£0õ¡L];ÊÇÅÿž«XQÚCÿæBŽk&‰¼ce4 Í1\íˆ:°¤MƒIÑΑ2“È·®ÆçÒÉ'Ÿ\Ìš5+‰„Ø "œõÖ­[ÓX$ÄP$ú2ÛMÔŸvPvÕùQ׎Vʡދ/Nç ‚&Ä$Ú¹À9±|ùòb„ Ã2vó:¦ä}ÞèZ2Ø2òúº. H@@ïP˜Ñ{}n‹%  H@€$  H@€zœZ ¶%ŒõŽ;IÝ*Cj³vPŒõˆêŒöï¼óNñðûvíêgŒçÿùóç3gÎLoÿrÈ!ò _„Ôå¹çžkWn”ot0åtÚôw«Ã?<±ÉEˆ+ª ùêeäùTí?\í¨*«“my;õMU;êÆ¢žK~ý1wîÜ4–(¡LÕØÅSˆ úU½QPú½QŸTµ£_á þaì,Y²¤xÿý÷‹M›6%»Ó®—_~¹8þøã‹ /¼0Ã1vóª ¦ÑçUý1Teäù¸. H@@ïP˜Ñ{}n‹%  H@€$  H@€z˜o†ct¯2Ô"ZàÍ| œ¬·kH Ã?yc\îFUâNŒØk×®-¶mÛÖÏP~ì±ÇK—.M ¼Jä‰2gÂ’O»EèxQ֫䋤Ó2¢¾›ùàá œÈû¨£ŽJ}‡n!”õj–òvp|UeÓ>°ŠPueÐŽèX6«{þ}«íˆ>©kGÕ8ÂcÄõ×__\tÑEÉ;Iôy+òç¼c9\)gÅz»ýA½¯ô ý1qâÄââ‹/NžbcíÂãÇêÕ«“(O!ôK«©•þl;ºQF«íu? H@€Æ?…ã¿m¡$  H@€$  H@€ú`Lýì³Ï*Eh ÛqØa‡%aF»[ ô`œ­f uaîkà+lëú¨m±A];ò2XgüÒïUí¨GóæÍ+-Z”ÚÝJ;è'Æðp¥œU'c—z!*â\ÇcýÁ¹‚gŒ•+W´1Ò{ï½W<óÌ3ÉKÈ©§žÚr¿´ÒƒmG7Ê.%  H@@{¿ä% H@€$  H@€$  ŒiÏëÜõ‡— ¼ft’0Ð’wîy¡œO7ÊhרM}÷îÝ;ÀCá'”E´‰2etÊŠ~@0Á#wUl‘'ýB9uí ÜDÙ›!9Þ}÷ÝbÚ´i¾‹|YæíàÂsÖ‚¶å A¬ÊåäûÔ­—˨Ú/g…ÁžqÖNj¥ ò‹rªÚQ7Ž$ æøê«¯úú¼®näϧÝú×åWµ=ÚÐéØ%OÆçzŒ]˜ŸsÎ9¢Âù|ùå—}E¿öÚkÅC=”„9„üi¥m­ôÇ`ÛÑ2ú ¸" H@@ÏP˜ÑóC@€$  H@€$  H@½Lã&¡0œóÁÀÚNÂ0ËC-Æø:ãÿp—AÝ1–‡ðƒvµš0¨c¤-'<‡ä<š•ÁøUùD¾ðA$FíØ^µŒ~i§äùWåÛÊí˜9sf ¨ˆþ£®o¼ñFqæ™g„tÉS];]Q¾&?¶ÝuêÆÿò±åv´Ëª®årZý¿n!îAÄP'ˆ*·£.ŸºzD;8Žþ¯Jå2ÚeU•gyÛGQ\~ùåãà•W^éhqN¬Zµª8ᄊ뮻. 4ÊÇò´£Ñù1Øvt»Œºþ¨j¿Û$  H@ßÚû•5¾YØ: H@€$  H@€$  ô Ÿ€¨¡Ê@#(ƒ Éñl•½e üÀ0Ì’·öÛ1<ã9ã9íam&”í!OR^ù碷Þz«X¿~}Ãð„Á“ÆZŒôŒ¶0#¬L^FªD“?ä›·¡j÷r;ËqÊ)§»wïN!O☵k×óçÏOá*òqQÕŒñ/¼ðBñüóÏŸ~úid1è%cªNpPnG»¬ªÚ1˜ Ç8blä}ûÁ|¨_¾=ÊÊÛ±}ûö­„‘‰ã£u!ŠØ//£¡íyä‘G ùä“bÆ ÅO<‘öËE QX>|Y¯JíÖ»œGÞú¢ª?ècúºŽÕi§VL:µ œ ù‘`³nݺä1ƒˆ3D;ðаsçÎâÕW_-6nܘ<§på0.‚-ÛZIä[U÷üXÚÁ§®ù¾Uë9«hGy¿(ƒþnW3eÊ”$rÊ…Œ#D;ˆ_Ž<òÈ4N£ òG„±zõêâ™gž©Gå:¶ÒŽalÑŽòØ-çWõ”Á²®_òvDœ“K–,)e<ðÀçI¤M›6%±ÏÑGÆ[>NšõG7ú|8Ë.%  H@èM 3z³ßmµ$  H@€$  H@@ÀpJØ èa¸mFgBW`xãmùøn•7ŒÃí ¯^¦M›Vüñ}í¢=|ÿÜsñõëy@IDATÏ¥ð#sæÌ)&L˜PuÔQIh±wïÞ‚ð%öìÙ“„´™º ÄC6|0L#h@œÛs^×nÝóãóväÂ’|ÊoÄŠñ@ˆ‰mÛ¶x6ˆDýW­Z•3gÎLí§ßé¼"zƒýÙDXœE‹%±!eÚIêŒó‘í8üðǤÏëú#Ê€ ýÙNš7o^YÐç!L¡ð&²ÿþä9ƒ~  ˆð0²óq ^5Þ~ûíÚqT®C¹Ï«ÆÇ0®³”×î‹2MS×/Áª|2®¼òÊÂÑIxÉK/½TLœ8±¸ùæ›ß8›õG¹Œ2“ºÿ£0É2êêçv H@€zƒ€ÂŒÞèg[) H@€$  H@€$ >8 Ï!:ú¾hqáÁ—_~Yk¬%›n•q衇:I„1Úb°=ñÄ‹… &ã9‚ƒHˆ ž~úéâ7ÞH^3`ÆqlGœ‚ Ô\pA) V€ xÒ œºDý1ÒwšòvP^U¢Œf¬,XPìÚµ«xøá‡SŠÈ£:1^ýõ$0!/Ê¤í¹ oxÖXºti´+Ì ¿3DÙåe+í(“ÿŸ³Ê·çëQ}Ý®˜ñ <”ÇŒ͛7'¯ä ;ÆP+ã(¯ë­´ƒý¨?aŠ:9×£ ú¿®_‚Ërš4iRqíµ×„ºaìÄØ$¿Çûì³>cržëÇ{lqÊ)§çw^ ßq '$oyê¼.°:aƃuÎSÔ7ß–¯×µ£ª<´-¯WžW¾NÛo¸á†ôÜýì³Ï¦Ð&xG ƒz¾/ùÑæÓO?½ÀÛa<(‹ö`p§ma§^Uåçí oÆNž8ŽºþƒüSUùäÇTõ?õ!ü ˪¶äýe°ýóD]Êuäû¼œˆT¨3žV¶nÝÚÐcJ+ãˆñ@? h •Ç.Û¨kùœk6Ž8.Oy;¢ ò-·™kõn6®è+DK|ðA±bÅŠ$J þ„ÍÁC aM`§ªþÈ¿o¶^ÕŽò1Ý(£\¦ÿK@€$лú?åö.[. H@€$0 àrvÆ ÅÊ•+SìjÞcâÓË–-K£°ÚVI€$  ŒjY1Ö¶›¾þúë‘B£„Q˜¼ËÆìFÇäß Uˆyñüpæ™g&• 1h€6 ¨K›§OŸž¼g`Tï½÷Ò1z§`hFÜÂs)oúãoÑf™àu”;gΜJÞ숅ü¦L™’¼ `¤æ™7¯o]=1ÒWµƒ:]zé¥)ŒFeÎ=÷ÜâøãoÙK †r<_ ,زeKñî»ï&<ŸS?òŨ}ÜqÇ¥ösÎ9a+Âx0⪫®J‚jú”¶R¸•SÞx,Y²$G9Á†þ Våã«þ§­yÿÉP5䇨»*åýßÃ|vïÞݯ_#å”·ƒïØqÆ´iÓ’x‡°.” CêÓÊ8‚1b¸â…aJ£sþ"” Þ^ƒ­Œ£fíà{òÍû…s1c:6Kô;¿ßuƒ× Ä%ô/ãdòäɉE9ªþ(ïÓèÿrTíÛ2ªÊu›$  H@½I@aFoö»­–€$  H@£žoQ1iwûí·ëׯï«/±š™gÒÿ¦›njyr¹/W$  H@€Z&À3Y¼ÝËòÁ„4ˆ†cÖÛIÃQF|„Á1†cÇ̲ΰMÝIÔŸgM¼´ñÁˆŽ(9Æ^ŒÝš1þã5 Ž ÏguVò"@9싈!ö‰%eÄ:e–ëeäû°_”Áz]BL@ÝDP?ÄÒ[í—(£5bŸ|òIòø ¾ƒBÊÃpÛH¬#Y´hQŸþQ‡(#ö%y"f Æ8Žv´“ØÿŠ+®H}‡×‡?þ8±+óŒÿËýe!$@`ãˆq!Ž«kGÏ~ˆvÞÐqùE—ÇQ‹÷‘Ù³g§²)üªãD¾Œ£åË—§ñü`ßGÞåe³vžd`ɾÑïÔ«Õ„P…>AÜ´gÏžÔÆyĸˆzÖõG³²šµƒã»]F´­YÝý^€$ ñO@aÆøïc[( H@€Æ$&.qm»qãÆ~õg‚‘7¬ˆûͤ#®sM€$  H@CO#'FT>$ŒÉU ã*† žˆr}Õþù¶á,ƒzP/< ’À‹©ÎcûÒ ©Áiëù·²Êi4^­¬:¹.6n©ßJ@€$0V ”Õ–Xo H@€$ qE—¶GuTå?o­ñoT™$  H@€$  H@€$  H@£™€3FsïX7 H@€$ÐÃp“KLë¹sçëׯïO{„ )ö4o5š$  H@€†Ž@„!¬o ã1£*Š€p„¹à¹­/Ý(kx°`IyUa,hb_Á¾„e«É2d帪?[Oˆ'hOžB˜^2X²­Õ„p%Däoõädå¸òüè~|ðÁý7tù¿•+W}ôQ_ø)®}\ÛÃk Bµ<0 ×ⱎ/>‡rH¶±lWÔÖå¦Zœ$  H`ÔP˜1ê»È J@€$  H@€$  H`è Ìàc’€$ ñMaÆk¯½–Ĉ2ª„!Î@„ÇQ" < Åç°Ã+=ôЂåGQyä‘ÅÑG>lGìa’€$  H 1…ùø­$  H@€$  H@€$  H@“ðbB‹Q§ á‚ „ˆ2?üð>aÆqÇWL˜0¡˜8qb1iÒ¤$ÜhÇ+Q§uò8 H@ÀX# 0c¬õ˜õ•€$  H@€$  H@€$  H@]"@ˆ(ÂFñ!4Jžsrì±Ç&aÆI'TL:µ˜9sf1}úô‚ïL€$  ü…Ž H@€$  H@€$  H@€$ ¶ üá(øìÙ³§X·n]ò¤(ãôÓO/Î;ï¼$Ò 4ŠI€$Ðëfôú°ý€$  H@€$  H@€$  H`ð¬±oß¾ôyýõ׋M›6Ë—//.\Xz衃ÌÝÃ%  H@c›€ÂŒ±ÝÖ^€$  H@€$  H@€$  Œ*„=Y³fMñÉ'Ÿ¤&óçÏ/:è QUG+# H@è&w³0Ë’€$  H@€$  H@€$  H@è [·n-ž~úéäE£7Zl+%  H@Õô˜QÍÅ­€$  H@€$  H@€$  H`Ì ŒÈYgUbä»ï¾KËXÿÓŸþ”¶}ûí·Å7ß|S°üê«¯Š¯¿þ:-ñxñ‡?ü¡øòË/Ó6Žë4mذ!yΘ8qb§Yxœ$  H`ÌP˜1æ»ÐH@€$  H@€$  H uóæÍ+æÎÛúî) H@X¹reñÁttìPtÅWßÿ}Ê*„üÏaŸ\˜¢ –ˆ2âóÅ_|>ûì³âÓO?MÞ/öíÛW|þùç}ù7ªïÇœÄöñ; H@Àx' 0c¼÷°í“€$  H@€$  H@@FaƯýël‹«€$0ð1’ÂŒýèGÅšËNÚ‰xÏ1>ùä“bÿþýIœñÑGï¿ÿ~ñÎ;ï;wîLž5ªòG2UyºM€$0Ö(Ìk=f}%  H@€$  H@€$  H@@—xàÅQG•>S¦Lé+•p'{÷î-öìÙSüû¿ÿ{±k×®¾ï\‘€$  H ?÷ÿ×ÿ$  H@€$  H@€$  H@€$ИÀÁ\ Ô¸à‚ ’h£ñÞ~+ H@èm 3z»ÿm½$  H@€$  H@€$  H@€$  H@ÃH@aÆ0Â5k H@€$  H@€$  H@€$  H@€z›€ÂŒÞî[/ H@€$  H@€$  H@€$  H@À0P˜1ŒpÍZ€$  H@€$  H@€$  H@€$ Þ& 0£·ûßÖK@€$  H@€$  H@€$  H@€$0Œf #\³–€$  H@€$  H@€$  H@€$  H · (Ìèíþ·õ€$  H@€$  H@€$  H@€$  #…Ã׬%  H@€$  H@€$  H@€$  H@èm 3z»ÿm½$  H@€$  H@€$  H@€$  H@ÃH@aÆ0Â5k H@€$  H@€$  H@€$  H@€z›ÀOz»ù¶^€$  H@€$  H@€$0º |ûí·Å¶mÛŠwÞy§øê«¯Šƒ:¨˜6mZ1uêÔ´>ºkoí$  H@€f8$  H@€$  H@€$  H@£˜À믿^¬X±¢xë­·’0ãÀ,f̘QüíßþmZþøÇ:ÇÅÝgÕ$  H@@¡0ÃA  H@€$0ª ðfo…mß¾½`}„ ŬY³ŠÃ;lT×ÛÊI@€$  H@*kÖ¬)Ö­[W|þùç}Y~ðÁÅ‚ ŠÉ“'|pßvW$  H 5_ýuñÊ+¯}ôQñý÷ß!z›9sfñ“Ÿ u$ÊlÆÐíÕ m:ZæÔK†çªÒKm«$  H@À°ÀEï† Š•+W&aÆŸþô§â„N(.\X,[¶¬8öØc‡­l3–€$  H@€$0Z`4ÄЕ§ï¾û®øä“O’€]aFNÆu H@­xï½÷ŠßýîwÅîÝ»û„çž{nñOÿôOÅá‡ÞZ&mî5e¶YÅAïÞ m4$3èI 3z²Ûm´$  H@ýþüç?o¿ývqûí·ëׯï«ðûï¿_ð·nºé¦âG?úQßw®H@€$  Œï¾ûn±uëÖâ‹/¾H=ñÄ‹9sæ‡zèøo¼-[¶l)víÚ•„„™8qâ¨StPQ®¤nû°€2S H@ãŒÀþýûÓõ‘[$BFá±µQúæ›oŠÍ›7x.B4‡8ŽðRS¦L)8à€F‡–Ù0ÓQöe/´q”!·:c„€ÂŒ1ÒQVS€$  ô~ØnÛ¶­Ø¸qc¿¦#ØØ»woñÒK/Ë—/7¤I?:þ# H@€Æ7 %k×®-î½÷Þ¾3þùŸÿ¹˜>}úøn¼­xé{衇R˜Ö1¨á¥o´©ÓN;­xõÕW „Iü&"1ö§M›Vüìg?6f* H`¼ˆëi»í$ü Ï"{öì)ip>å”SŠ¿ÿû¿O!x½DÔi™íÖq$÷ï…6Ž$_Ë»fŒÝ¾³æ€$  H`\`Ò7pÏ[Nlã I&N;ì°ò×þ/ H@€$0N ÚÃôÎ;ûZÈ3ãçŸÞ÷¿+h‡5ጫHûöíucjÁ‚ÉÍ>cûOúÓbæÌ™ÅìÙ³‹ŸüÄiþè;—€ºAà™gžIÞ]¹‡D»ëå—_žÂîz]*.% œ€Ol9 ×%  H@€F B•uÔQi’‘ ø<ñ±>uWSq]€$  ô&ßÊìÍ~ÎVÆ1uüñÇW^yeñå—_¦·³f R¯ o2œlÌ[€Šb·ü"ÿ#ìc©0ÃQ" TP˜QEÅm€$  H@#N Þ›;wnz áûï¿ï«Ó„ ŠÅ‹§ž}]‘€$  H@€$0Ž `è;òÈ#Çq mš$ÐK]‹·"¼Np}›4iRqúé§¼¨3ÚsVUáJê¶ööX? H ;ft‡³¥H@€$  ´I€¸'tRqÛm·G}t±cÇŽôcQÆùçŸ_\tÑEmæèî€$  H@€$  H@#MàücqÇwo½õV Ï„aÆ¿ýÛ¿¥9 ‘®_³òçÏŸ_lݺ5…à}§L™RL›6MoÄ¥$0€€ÂŒHÜ  H@€$0Züìg?+æÍ›WLœ8±ØµkWñÕW_'œpB1cÆŒâC-Õ´€$  H@€$  H@-øú믋-[¶}ôQßüqz!§oÃ(^¹øâ‹“ÇŒ÷Þ{/Õ™9ªÙ³gˆ3 15Š;ΪI`„ (Ìá°x H@€$ Æxk‚¶|L€$  H@½EàOúSñùçŸ'.-G¨ûå—_€€1ãHUÂXrØa‡p@Õ×ý¶}ûí·)>ü|P|öÙgoôR&ÞÜp³Žponxq;þøã;~+–ú~òÉ')=õ#¿ƒ:¨¯.þóŸ‹÷ß?‰“÷ïß_P/ö;î¸ãÒÛ¸„³¨r¡Þ—Á­Pî‡~˜êXÐ'<£Ãâˆ#ŽH^îŽ=öØacMÞ={Rÿ0h?.ãa§½Vû—ùŸ~úijyñÅ•†ÀÁŽ©áècÆ Ú@0Ûƒ ÝèãèC–Œú’> -Œ«?üáéüdŒs~!Ì?æ˜c:Syy®K@c‡÷¾±’¸NÝxã附k2ׯC=tP×ã±Òvë) tN@aFçìÚCž×\sMqúé§'c;¢ƒ5kÖ/¿ürrñŽc6ûaˆÇ}úÕW_] †®„XaÓ¦MÉM;žë`<¨s°8üðÓ(âç?ÿyqæ™g3gÎL‚VëÕŒù PùýïŸê³sçÎÁ†|RˆC&Ož\Ì™3§¸à‚ ’@£‘Pá…^(Ö¯_Ÿú–<&äol³m°cªY»:écò|ðÁÓøamþÅ/~ÑÑXèVÓS„5°ç¦=U xI<ùä“Ó˜b‰Ç$ H`´@ Ç3†I@«f´JÊý$  H@€$  H@€$ ®@ðÀ$¯ucð]»vmÝ×ɨ»`Á‚dì-»Gp€Ã?.Õß}÷ÝJï yæˆH˜_ýõbÑ¢EI ç†V"€Õ«WÛ·oïÛý”SNIáú0–?õÔSÉ DžÞyçbïÞ½ÅÂ… ;2ÆçyU­Ã1Ì‹/¾˜˜b@ÇKF£ôÚk¯¥·„ ÀbÉ’%ÉH#qDä׈uï³Ï>[¬[·.‰CÊ<"ö£ß~ûí⪫®*¦NZë!…üม. fL‘g£vuÚÇäùôÓO÷7Œ‡óÎ;¯­±Ðí>†^1èÆÕ+¯¼’D¢ªRœ_œOŒ©ë®».‰‘á˜$  H@ÀX& 0c,÷žu—€$  H@€$  H kxCC)oÒóö:oðò–8.ôy{Ü$ =¼ðLâø*ƒþîÝ»“èã™gžIb‡:Cq]ÙÊŸxâ‰äÕÏÄ›'¬D³Äõãxž¨^¨Ë}÷Ý—¼D”÷‰ý)«ª=ñ}§KòܰaCqÿý÷'!õi5±/†wŒê\#¯¿þúbÒ¤IEYSίŽmĈ'”7Þx£©8„|¬<üðÃÉ îå»ð6s9}ýõ׃æW7¦¢¬ºv ¦«ò¬Úu¨ZŽDà ±ãŠ{(un%ê/8„6™1cF[žXZÉß}$  H@@· 8kÐmâ–' H@€$  H@À˜$°cÇŽ~€·ê1,!ÌÀm>!ˆ3m’€†ž!C8¿ð  EYDA(‘: xû¾,Àèûä“O¦Ð‘7KÄ„S8âˆ#Òã>^#xëÑá¢|–\0:ã¥ð&årò¼ëÖ1˜ãÅï „îÈE´+ÿŸüëÚZ—+ÛVÜqÇ0/DâZG?İ Ä Fr„ALXí–[niË“C”‡(Cþc=–„!B!Oú·ñôå³oÎâêøë_ÿºòÚá¸Æ"êb<ÇpäÜ!œU'÷›F¬8G¹Žsm§Žœ‡q.ržò¡|BƒZ«ªÞuù“O~¿à|ë{~ |ª¶³÷gBh Ç=0¯C«ë‘Åïî“ôi7åÒWˆß°™0aBË}‚×(ž7¸æ2¾¸Ãý ƒJ¡Óxš2eJzêqVŇ:Äõžþ…#a­#~‡ ã)žÈFU¢Íª:¹MÃA@aÆpP5O H@€$  H@€Æ?ü0…:àßHLÀ2ɬ0#ˆ¸”ÀÐ@èð«_ý*MÖ“3“ì„B@<‰ ü+®¸"Šb[¾äü¬:G1<1YO¸„¡xæÌ™éí|ŒN%0t`ˆÂ „„c«ñꫯ&CF”óÖ[oÏ=÷\ò¨£Ý„WŒÑ¹(ÃÛìÙ³“a‚üöíÛ—öÁ(uÈ!‡´[DÃý¹®á©£,ÊÀð¶xñâ$8!ÿcÐÀ †0‚ã ²yóæ>ã9¡:üñâŒ3ÎHa60ò´“ƒqƒF"úÑ˼yóÒ êáwÂØpŽ„ o^xa2\– 0x6Á ‰ˆƒD^<òHÁ5>R§c*ޝZöbÓGu'!ÊÀÈvþùç§þ9ùä““G ÆçX3óCx!Ɔèn«úÌmj\Ûn¿ýö¾k=÷˜_þò—çBˆÉÄ=!ðμqïáºÊ¹Ãý1óSO=5…ŽB(1ØÄuPo¾ùfƒ„0ƒ{$ç&×DÎSÎGî¹gr:ýôÓ“!¿YÜQ÷qÂŒñyB¬r×]wÕzÈáÚýWõWIœ‘7ëô%bFîÛÜwàsæ™g¦pZ|ð°V‰û$÷9ʆc3n½õÖ~c©ªn¸×¶ áy0¾è瘄ˆqƇûïôéÓ%’¨ªK¾ ÷IÆíADñ‹_ü¢˜;wnÇBŠçŸ>qâÞÂØâÙéÚk¯MÏ4ƒ|äõv]íP˜Ñ.1÷—€$  H@€$  H g ”ߨDÕ¶ždÃ%0ÄHð‰Ä„=Ÿ²0cÙ²eiò>öke‰Àã+DLþcd¢¼²1?òC(0gΜôýš5kú„lúé§“‘ áF¬v^0Œa¼Æ qöÙgK—.MÆÞîä:ƒñßSç¡JðD˜€!œ:Dšöƒg ¸^vÙeé Ó¼MQ>F(Dx A bD6AQ%Љ2ª–îâºJÿ,X° ¸ä’K ’QöoÔbÐáÍáH5èŸY³f¥ºÇv–lã #bŸ²0£“1yV-{±1*oÛ¶-ü‚ Æd ÑœG¹a c/c1sÞyççœsN±qãÆt>…á9Êw)‘$€à×óH\ãâaçZĵF\GãZû²Ä˜Î=}¸n]yå•é:Ƚ¡“„„ë7ÎײX¢*O„#ˆD3r®"„Ãpâ’ªczè¡bÓ¦MµÞ08†öÒþºD™1´Ä½ nßáÞŽ§ Dˆy_Ò—^ziKB•Nëǽúþç’x'D.ä…±P—x¾`Ü è@`Êõ™1×(ÑÏ<+qÿZ¸paºs­öˆMƒy›x>á~ÝÉ=¡ÉŠ+'žÑ"1^¹ÿ˜$0RfŒyË•€$  H@€$  H@€FŒÀ¢E‹’q‡7pà ¢™a £†åk®¹¦Ø½{w Ï à­ÓðòœãûFKŒ‘Î:ë¬â¶Ûn+Xb„Š„ÑšÏP'ÞšEÄ€@!F¯«®ºªX¾|yz;:¶——¼!Œ‘ƒ%í'¯0$b`!ÜB•¼å<ÊÿÇñÔAo·V½©‹ahòäÉÅ 7Ü\• &çH¨D%ˆH†ÃˆT®w³ÿóºõJsŽ„X'ø0&ó4:G/¼…AŽs²Ñ¾‘¯K ŒˆãõÅ8ŽAfðÔÌ`α„h¸çž{’0àÆo,Ó5»‡E™,1Ô#î „ËVùñáe1¡Š¨÷Òºó•ýËmÏóke£ý`óh¥œVö¡ÊuÉE­äÑî>x4ùßÿýߢ DŒÜ¯¹¶V‰cw2ðŒ…Ø/­&¼M¼ð I´ƒ¤ë®».…7êû*Yê–3DœÇ³âvÆ6mãž0ðˆÑŠ…·´O:é¤dÔÌNˆ30ŽaF¯õq•è‰>Á0;Zú$Η)x#ÀãÆpžÝ¸/!b˜7o^ºòìÆ5á×Ô²Á#ýÓ?„ÒÂCPˆ ›µ/ê ‹‘_39á!eŸ|òÉ鹑û ®¥Ü3ðD€ ú„ˆ„%^7ðtôÿøé9³,žàþ†=DÍ1ôç÷ŽAG>U‰ë<÷¨^K\7ï¸ãŽÄ=æà:Š(/[„ «º_Ò_[ep_FÉXcÑcïÓO?Mcqûöí)ìÇÇáþNè²ùóç§ß>CUõcƒÐ8Œ«#ìÇX»üòËÛz.B$DX \D^K–,i+Ž1I`¨ (Ìj¢æ' H@€$  H@˜€å,&L™„c¢aÆ­·ÞZ,[¶l´pü7>d’üî»ïNoZÒbûpü÷»-ìÞ$.¿Ña-7š´ZŒ‹/N^*ê R­æÕÎ~·ÂÇM™2%ÏÚ5œn¤,Hùè£Úæxû oFW™¢žù’cx #c:ƒ7sO~L·×{±1¢bÔÍÅ:xQ!”Ëi§ÖðÍøn÷åI`¤`@^ð„8ÁY~?`B3ð,GÈ“üZ‡1vx”hÔ„<ßoÞ¼¹ÏàÎþˆâÎ;ï¼âúë¯OÂŒº{D®·„ÅÀÃGî=ƒp„!"UY`Èv>‘¸>?ú裄ˆòÚóE~ãu ï»îº«xòÉ'ûyL¡_ÒH”Ááw@.®€b „23¸æ ï$®Ó<.'1‚HäñÇOßåã3Ï£“u2ó²ÈA Þ;¨g«Bžmðà•MžÙÕëNêì1è„À;9Èc$  H@€$  H@ß0d1¡Å0‚Lø2©‡ÓØ €0¯'»víJý}H¿š$ Á@„P6`ðŠ7KÛ)ƒC»^*ÚÉ¿n_®ñùÛÊì‡1ýC©;¤v;EŽËŸÙ'ÿÜ8R›Áÿÿ† (ÜÙWå±²lpá ïNú£*ÿÁnëÅ>®2oÙ²%úÖ¯_?ÀÍü`{¼Æ"e: AÃßüÍß„u(½IãÅC<‡ò5¯ˆš¥ 6xéȽ 7FzÊ>÷Üs\Kó<¹ÖROêQ Až=ôPúííÊu½=á¡‚p5¹§Q%½öÚk)¤XÞ׌3¼’\yå•Dyí(OXô3}ž§gŸ}¶À£ÆPß_ £FHÆc$îã¼,·!¾«[2¾9.OsçÎMžÀò¼óï]—@·è1£[¤-G€$  H@€$  H@³0@`hÊMå þò÷­6×ìˆZÍ¿n¿={ö 0Žó–3îêÛ1‚Dþð@¬B ˜!îCìWMÄ1CµDRÊІ¨ËP•Ói>½ØÇ¸¦Ç3oX‡Q2«W¯NdÜáóV6îëËÞV:åìq‹¶]}õÕÅM7Ý”BJ”ï-y›&L˜B;àñ" ò=b\Î5BZ”¯…q<×â'žx¢Ÿ¾C`qóÍ7'O ¹¸.Ž+/©/ÞðŠ„7Â’DÚ½{wò^„½ìU*öqÙœL~øábÅŠýú«UQm<[äc„RñεhÑ¢–ïɱöÔSOõ=ìÝ»7yh™1cÆ^»3xŠáE€üO,ˆZ"ÅëF~<çí.{qiÞ î!¡' 0c虚£$  H@€$  H@€$0 `ÄG”ÀcÆdÞºd‰‘$Ä4mÇŽ c©ÉˆHx»ºzå7ÞHbŠ<°íæ`+¿Aá]†[˜A}ËÆLú3Ò´Ý 1~ÀH÷1ofóV6 ƆBKÞÚÇž3N=õÔdž3gNz£¹Î¨<Æ»ÃêK ’×.Â7ÂãØcp«:ˆ#„œÀ_ãgàM£îâ½iÓ¦!žðØ4yòä~ªÊÍ·qM_ºtizä ®»Ò1þ+Ìȉµ¾Î}ù±ÇKaH¸‡FjU”ÁþxÈ{ýõ×ûÝãñÜ„ ¦!ãó²Ë.K}š‹Æÿíäíh´$”9ò²ðîÅ3W+VBŸ”Cì VâþÒÉsM£ºú:! 0£j# H@€$  H@€$  Œ·ûÄ>±É™Ôg[20:!ÐÈ `c½ñ¼9á£Ü¦mÛ¶|†*µòöõP”…(£,ÌŠ|Çr£¡1†ÝxãÉ@‹!/w/Ï9†0ã!oì³/6Î8ãŒd$Öˆ6–GŸuo•Ææë®»n@‡FÇs a§=qžGÂCQYܸ߱qcº·åÛSqá…xÁh7®höìÙòz þà\GœejýGXš;î¸#q{tˆ2~ùË_&¯(Íî­\W¹Ææiúôé}V'ÜÉ÷Í×éã²È†ç¤Fc-?¾uÇFþŒ­5kÖ¤ûC9ÄO9ï矾ß}†ï2uÔQ>#”aùÿˆP˜1"Ø-T€$  H@€$  H@i¼•Š¡ ã0‚ >Ät-á/†“b“án'oÒb<Ô}øpöd}Þ£¡1bôÅ(öÌ3Ïk×®M§0¸Q{ÎCÞˆæóÊ+¯$çŸ~±pá‚7¼ÜÔ÷±ßŒ}ˆZ43´—[JHί\˜0 ùåýùñaÙKFw„Qí–O~”ÏyúòË/÷«B <=š¢“|É»÷d„·ß~{ ç÷è\”qâ‰'¶Ä”¾ÎÇ<§M›Ö‘×îåw¸ÇøâY)ÆÛP^£) !ÅöíÛSþ1^zé¥$òk$Ì N<Óåcü'?ùIòÞâsHt9ÒfŒtX¾$  H@€$  9&cˆ±ŒA‚ C&õ™Ì“JŸ~úizÓŒøÈ±/“=˜ôje’´*Ê!.îˆ1H‘õª„1ƒÉNâï↞I1&Þ(ƒ‰;âØ3Y{ '´üönř̊7Yy‹ºü–õçí%Ê­JQvùªª}ÙF;èú*ÚAùlgüè;\5ói%®p]YåíLtòV!.ŸaIÿS.u§¿˜ †a«m)çßìÿáh{¹aùå—_¨ÊPõaÞ†`˜÷ †£ÿ4Ê è€çýªU«Š|°Ø²eK?·Ùd‡1‰ë× ¬ç&Î%ŒOž¡ƒ*Œø!a`É+ròÉ'§{&×áÁ$®ŸN9唎 Aƒ)ÛcÿB`4ô1ciÞ¼y鹄°%¯½öZ mR~ÛŸZG(!ÜÖó=¡PZ5Dþ¥Õ®I`üÀ€ß“h1ÏaUç<ßñìËyU¾gM:5=w³O'©ÊØOxTÀCC¹Ž”Ñ+Ç pY±bE±ó‘Ú`Dð¢¯Ë žeøíÓ‰Hg \˜Aó „w‹¡üKÝ/^œžÍø‰ßŸxóâ÷Y7%<µð»>Øq,ã›q8Øgš¨‡K –Ààž®[ºÇK@€$  H@€†˜¢ â˜?ðÀI°ÀD“1×_}«^ÒÇ\àN›oãð??L†0ƒI\i§ÃrÕ›@öó|˜œÂξL|!ÌÀ]ì9çœSÌ;wÐî|KP_ÚÇd±ƒÃ N»i+m´Qeã#bƒF‰·Ä1P‚Äde剉ÞW_}5‰3òí±Î1oÅž}öÙ•¼Ø<àF\y&™dcâaFÒH0áÆ †}&àèÃùóç§e'“‰QGÄo¿ývju`=ÒfÊD ‚ c"ma,ÔMF¾­,‡»íå>¤­´±œð €§*Eº*1Ñ /&FŒA„5lã À>!¬ aÆŒ3Rÿ±„±I#M€qÊÛ—¼•ºó‡kçK$Æ-â„Y³f%×sÎ „¹iÆ ÅO<‘Æ;––\K«Œ)й–7z+µ•vrÝä^4”¢ºVÊuŸ¿m}ŒÀbâĉ陈·¹7oÞœ¼Ô ŒBè””wïÞ]Üwß}éy‚P(ñ ÷—Ö¹&Þ&P%æÞ–ŸG9!žÑx^cŸ<ñ{¥ê^ïÓhs3¿7ƾˆ¯ËeÅw.à·áK«–?“ð;ˆß±íÔü¦Ëó¡D~ x뤿ù[[l£ŒNòHà/[øí5sæÌ4^C\ÂX›¿Íê~—½ð }/Dnx_⥓F …£¥'¬‡$  H@€$  Ä Lðc,‹„ñø‚ .HF~ ÊÏ>ûlñâ‹/ˆËÌþ™I¸Aå­¥%K–Ë–-+¦L™Ò'6À€0‚|˜ ªzã“<0* d@HÁÛ;ä…È£ÝÄ$ŒˆÄ×Åa½<9–çËCÀ™ØZ°`Azóˆ ®º·…¨ãý÷ß_é%#ÏC•±Ÿ}ȃæ™gžY9aÆ„#oÉ2)H1ñXåÑ!/ub$¯[·.‰`-Z”ÜÛ¶39ùá„~}ú‡¸ÍÔ Ë*†°†_”y饗¦7}#ŸN–Ýh{+}H{9øT¥èóÎ:kÀXa2!Æhø0¾[é?ÊÁ5=ÇÒçž{n¾T‰ªêä6 Îó•+W¦qœ.xó÷’K.I†c®™2êÆ*ãõêÕÃQ½®ä‰Qãí˯…áéBCxWºaX }ÌxC°ÃÏܸ?óŒ€@#÷íG}´à¼ä êÁ3#O—/8—êîOUmäž•_ëc¼ ưγÕñvfåæKú¦ªøm‹œß¢U˜ªœìs\9ñü>”©Õú´[&¿G¸æsOayð{?ÂÑòØGĽ$o7ÂZ¢( o·Ü8 (ÌNºæ- H@€$  H@]'À¤Vnd£L 2A…HOLêÔy ˆ 3 „±€ý˜à¹öÚkÓ„ù`L5J”'’ÿßY­{ç(¼òüqÏ=÷¤NÁŽk Þ½xFáZY%‚)SBÇ—¿ªÿyNB,Â3Äp$„ÜDèE[ø=‚¸„{AYl¿ìÕ^Ãje8Úkž½C`xΘÞágK%  H@€$  H` @,€W‹gžy&½í' LFb@Ä€GÜüæ‰m ˜ cŠÉ »îº+½ÁÓN>¼éôàƒ¦ò®¸âŠä?/§nQÆÝwß¹„I0&«¨oºñV7âêKh&¦ÂÐÆ„¢&µxsˆð&å„'Þ^EÀ‰ÉÛò.·u“·G}tªOÕ^6ðbRöÔÀ¤íàXúúÁ•:3ùÆ[QÁ™úãÑ„|˜£ÝUnœ£þ±äx¼Ÿ0щ§Žr›(7Î0„FI„;ÔAGLF¾­.»Õöáìú60Oß1™Œ—þ„ü³äã0úïÉ'ŸLcmùòå•"¡V¹ºŸr1iŸo«[g_ÞÂ̯©ìK¼+õ‚(#Øà}ˆk`Ü/Øž_wc¿^\¶3¦F3Ÿ±ÐÇÜË Æ}–{4Þl¸Dâ>ÌsIèœ@Ý5­ü\Ün <+“w9ÿðÈÔn~½º?–‹.º(ýž»óÎ;ûy¥CtÀ¶¿û»¿KÏÐìÛ(•û"öå:Ës{Ýo¹Ø¯Ù’ç}¼Š6s°yÕ•Åo\^(àwmîÑ<áIÊ ¼X–Ç–Ípju„Ý>RfŒyË•€$  H@€$ ®ÀÐÎ$?FyŒô¼itÒI'¥·3g̘‘ ÊLø0ñ¡Gò‰ŒËLö`À˜nUÛÍQùÏ;7…i€r!à*?7P`4Ä€!!(0é„0ƒ¶"! žAÂðH{'LûÁ8o!‚ÈÓi§VüêW¿Jb¶c¤ãxÚš'ÞhåS•¹£j²C¢ßSg&ôøÐLÒ. ý”‡ ÞÃ; õÈ=…ÐO„¢ar‘7¡š¥?xÙxì±Ç’÷|òCÇŸsÎ9}LPWŒ@”P…m0ÅóHUÛš•ß­¶·Ò‡ÔŸ±3þüÊj#° M9Ñw´ƒÄ,BúŽó‡·å8.„5!Ì`¼ãR˜qG_F¢ÿË3{öì–ú/Žs)0þÊFÎk®,ËßUQãzˆp(D_±Ï©§žšîñ/,¹'pÿÈï1x‹âšËµ¹•7sÇ:'ÚX¾¶·;¦F3ƒ±ÔÇ<,]º4Ý7ò1IHºpñ_î«ÑÌÞºI`4à»êüá·âŠN¯÷œ›¹á<ڌ๕{rìï²Hbƒk®¹&ýþ dfþœÂïA„v·ÝvÛ€ßqevÜ׫ú:BB¶"l/ç™ÿÏñx.l>yžUëUbäã‹ß¦<£ð»1Æ¿Sé˜óB0Îožá®cU½Ý&Ff4¢ãw€$  H@€$0.0¹˜·‡˜œÁðLH„ ˜câŠÉÞÌÁ³Æd„‘u`¬Ç5,†ç< û" „”—ÜåçùlÞ¼9yÝh'˜<W”ExEàí¼nLŸ>}€ûXÞ\ ·à´ /!L^‘; r@¤ó>¤ýƒÚíÃhc€~#ú‘q\÷&Zô‚¼ÿØNðiÖÑ_.%ðȃq‰óž± Ãçx£ëAì˵>¿ÄvÆj•ÇŸø¾¼äüªÊ§¼ßhþÆ S‘¸gpÿ9ùä““ƒØ>^—¼uË=ë[þ–q;cj4³k}\u_ṋ¾‰ç¬ÑÌÛºI`´àY·êB˜‘ßOÛ­?Âݪ{!÷ÔVîÉí–7Þ÷ç7å­·Þš¼"6¶ˆ¥Éo§K.¹d€Çˆœ ÷µªÐ•bXëô-êf GË÷ˆqðøC;ã^IÝÚS£¥-UõÉ>†'\ëžWªê[%xÂP齢ЖÛ$Ð:Ρð¤Ïc]'¬h5g„Ó!ˆc¸®bï÷hïP/ùíÀs7ly†Žþ¢¯î¸ãŽôû„ßSubR®¹Û96Ωꫡ®ûPæÇ½™)vìØ‘Dò‘7¿ ùÆólø–?Ò~^dà{“F¶ Y H@€$  H@ÀpÀ‡—†[n¹%-Ë¢Œ(“ D&ºøTøØù âh”ÆÞôÉóaâAku‰ ´M›6%aH>™ÆÛËK–,i(ÊÈóÄÃdVî ƒ7€‰SÌW7u¹òÊ+‹«¯¾:s&Íêq޹W ŽÁŸº»7ß|³Ø¾}{¿]ˆañÅ'6&ì¨#〉Qb—Ëï—iƒF¢í ªÓÑW´áª«®JýÇ8l§ÿðâ¹PŸÓ¬ÿ:ª¨õ KeA×µ\€Õ×m FeƆ úB.Õ×g #x•È uÇŒæí°àú†‡¥<¾é(`‚üûFëˆ[öìÙ“Bwáµh,$(åëZ;cj4·q¤úÏS÷ßñøã'‘Kþº~ëÖ­[“¨1ßyªøýÕn B»Ç·ý¹7ó»‰yBdûí·]äû°^%‚Ç#VYDS>n´ý¿xñâ¿!ðd‰è„¶ð›šßÍ<{DbìñÛ±üœß»”ÀHhÿª8’µµl H@€$  H@@xkqÂu×]— íuoEÖ¼a„G øybr‘I<-à5 lÄÉ÷e|x¹œâ>u Ï  pDB@@ø‘Ù³g·üæ)õ%ìo]å ïLfu;1ÜÉ-œ™`ƒgž0ø52úÁq×®] ­ô ý׊‘‡úâ-‚±ƒ—”:!N^¯ªõn·½ªƒÙÆ9‹Nû z ŸyjÖù¾®K 'ÀX*'Bãð%F‡0chÚ¹sgòlQqa°(_ð€ñôÓO§PF‘G^.ÂÂCý÷ÿw*«Ñu®—þçZ‰·G®¡Ü‡#ÜËG}4=ï Þ( aÄs Ûógm®Çixaa¬„‡âYë‚ .Hs‘-c–¶³Ì={!øaÿ*&½4vlëè% 0côö5“€$  H@€$ !"€‡ IíLÐ`tÊߦ*¼­Ôn>Ï9o F,>u #.Àó|[+ëLxÒ&µÂØÆä“tüߪP¥•²†sØ—ßã-)>u‰6æ“‘ìGŒºíx˜äÕðHLbvÒö:&#µ}<´a¤ØYî@¸bǸ´qãÆ~B) |¸ÖcâZÂ,¬s.“0ö.[¶, .0xDâxÄ00ˆä ®Ía¡ ÜŒ³?á’rCrä5––ˆÏn¼ñÆd {ã7úµ¡ ŒdíB˜‹f`,É s´ý¹ÿŽãž¥0bÑŸùý™ÿù´2¦F{w»^Ä3cAŒhÜOC˜Á¹ƒa˜çžxN –KñXE8¬È+¾s) ´OO„§+_³ñ„g8D‹Í< F©Ü;yä‘~×L¾#ô÷èfç,ßó<Îý:îÕÀW•hƒï{-!fCœ@”{q°BLz÷Ýw'q}Wæ§ Dýˆ ãÙÁËc=V,\¸°àû±p¦¿úÜyçéw]ryö"¤\.(e_Æ7Ïxe|g’Àh  0c4ô‚u€$  H@€$ QG1ÃPáÉ£,ALÐȈǛÇ|òÄäÆ"Bs´›þøÇ?¦É©0x0¡Ç„,† l£11é†!'&ߨsyòïâûª6 Ê yB˜Á[ð£9 EÛGº}ôŸè–íößH·ÁòG/®‡x8`Rþ©§žJ׳¼¶ù›“lGŒQðÿÅ_œ )0 3fI0BŒ6”þ`,ƨ7 \—KYŽø¿Æš ¢ÂÐFH Ä,qSAÖ«oU•羇Ðï%­ùªòéÖ6Ú½téÒ>Ïå{t+cª[uí´œn÷1ÁÓO?==Ïä÷bžIø”¨y»8gñluùå—'7þí¾ÅŸçåº$ð¢±ó/ùyÉ=ïÿý¿ÿ—î„hfÔ&$ž7HÆï Já¸åË—·F¯‚ea÷ŸE‹)ÌøK·%a^­/ƽ9"–Ûo¿=ý¶áš ËH܇¹¯áí/÷4·1x›@”ØÎ=š{#c…:pï–x”‡ÊåS—{î¹'ÝcògžÏç& ŒV 3FkÏX/ H@€$ D€ù¼YÅÄëü CýÎ[V& H@ÃI€Iªf“’­”O>å /&ò ¤r>U‚&ÞxàŽÄ"L Å›RQV”1’ 0±ÇD#o}…'‘x›ë~p€“¿Õíh´dÂ9Ÿtfß*O(ò®ï†»íÃUï<_ÚÀ[xô Ë0¶Ñô!¦yÿñÖ¹ICE`òäÉ)üoÛ®\¹r@|ñ(‡ë8ÆaY¹Á‚ï ïpÕUW¥pOÄkÇÀT#D>‹0 aÄàÍMŒF<—’Gxá`_®1åk~äK{ec†çfÇÅñõ¤|ÂuÑN¼+ÀãBÁò=¤ªôEx%Â@ļôSY”•;”,ªVmËËÏ×1úÜzë­i¬àê°&q Ë÷k4¦b¿¡l×PæÙÍ>>þøã‹k¯½6'¯¿þzRq¯T´+_† ãŒ3ÎHáKa2’Ï)yÝ\—Àx!€(O\ããÚεOQ½¹žuÖYéÞX¾oroÙ²% øžþù>#y°áº¿dÉ’¢ôø¾¼ ñ^Ôƒï©<.ºè¢4ïÃ=„z1/DÝðÆQ¾‡–óoÿsíþÅ/~‘D<óäbAB@!PøÍo~“îÁù=—ç•Õ«W<ã„€†¾F€‰°Ë.»,yIÁCXÝ3ìDð[A,ÏôÿüË¿$ïyyÃÅ2·x\ aeú*Oˆ,f”_ŠÈ÷q]#M@aÆH÷€åK@€$  ÔàÇ&?2ùáÉ@~Hò†"oóñr´¿ñ\Û0¿€Æ¡œdj'/&&1h—]Â3!Æg¨uj§^CU.ù0¡†XdëÖ­ir/&ZàË2ƒvëPõf÷PyBi·.±·Úå Ç’û3b&CéC&j™ E˜Aß±dŸÁößpÔÝ<Ç ˆ$ `L2yqža<çIžqÍβ*gýŠ+®è" "Óйn`džöƒÛoÜÀ‰ÉqÌùžc(£T³75É oxýàzO[Ó–‘Nܨ ®èáÆ38L`qMåü晜ý0Œaü ýÏy6§/8WâÁ¨Q›†’b’n¸!Ý+¹þP7ú£UA7íA˜ÂX!¯NÇíÊv¿¡Ê³›}ÌùÂx€kŒ%Œ¼½÷ D,ôÂÎÜöcxå|(…ƒ…K H sˆ!]Åï ®s¹°œŸëׯO^k87¹–òû±3÷<0𠘋)¨ÍŒ3’¸kh«¿1àùŠëA$Ä€xàšÁu{$÷äÝ»w'!ð¿þë¿ÖÞÓ#ñ¸äúH¿Ñgx þˆÝž|òÉ䡊{ ÷äH\G ƒÂ=O!Œã>Ž‘1Àœ¢Jîã|¸&ó=}Âs=×lŽç÷}ÂÄ‹„–ËÅ©Qîp,ÙFžhG¹Æ ÏhݪS¹|ÿ—@+f´BÉ}$  H@€ºN€É~øýîw¿K?£ü äÃÄ7?J[ýÁÇ»”€$0Ú 0†¡n8Æ2&M»ý*†²mÛ¶¥7á6mÚ”Öñ„‹CÙfî#L 3¡˜' o­ óc†b½›mŠúVåA?1©»víÚô¶$“òLÖGÿU•ï6 T@ pÝu×%ÁâÞæå ¾ovÎ3/0Jaâú ¨Ê†bÄ ñ¹vc<€UÞ§\oòÁ…8FÎŽÃÒì¸r>Ãù?×J„/|0Â`(ãš øò W>!Ì`Ùî³ùP²À`ƒQ ®m¢~íÖ !a4hk§cj(Ûý<Ôyv«ñZ‚ALKˆ|è§Є(ƒ%ç®I^"öîÝ›BZ –Î Ý„çâÃ5”ó—%÷ª¸äBލ%‡nºé¦$ªâžÖjB„5gΜ~8–¹ >ܹ†síˆr©ëí^Û[­ÓhÞûžxþ¦¢ßà³bÅŠ$\àE&®ï‘ð~Â1wÝuW»pÝ´óÏ´|`É=&„ÜçC˜Á}0ØÇqìO?w³¨bK~‹ÐÞªDÛ³& Œf­_!Gs+¬›$  H@À¸#À0oH¼öÚkÚÆÐ_|1¹rdòÎ$ H`<(O|EÛxc C“£ƒIL¢ñ†8nøó7ª“g+Çb´Äe2ñ¨qQÌ$_ž˜Øc‘ XêE;ó‰]&àöíÛ7@h‘瑯“ùä#ß3“˜ùþùÞí¶G[˜ å-Êûï¿?½¥W×ô†iú1[þÃW7‘:u6ÏÞ!ÀùÎØãÃõ­ÓĘåÙ’o¶šï|ÚI”5VŒ\yÃz¸ÒP²À¨?†ý¡SCÙ®`?y’÷p÷qÔŸó„ð6& H`d ðÌ·(ÎýG}´@0ž¢fü_ÞßÅ/„Z¾|yqÎ9çôÄ>–<3âAŠgD¿åçöòs#¿ òßò¯ßÁâoûÛôÛ(Ú‰÷ < ÞÀkDˆ=Y.]º4=§à–ßcˆ[òÄïOžíËÏ÷ù>±ÎuQ*Â×(#¾îå…^˜Â°”ÇåòìÆdL›$0š (ÌͽcÝ$  H@@ÀˆÅåæ Á oY)ÌèáAbÓ%0N 0QZeTšöƒ }bµ×¹ão“™Ä>òÈ#[=dÐû1ÙGÈ âãm#¤0ÒðV6†P®ëlc¢T¤?¼Í…›^D{­&ò€'o|Eje’9öŠåHµ}(êyDî¾ûîÊþC04kÖ¬ÔšCœ1Øþ‹ò]J@€$ ñ@€g¤òs>ž:1pWWµ­ŽÏÉË–-K‚FDÓìñ€×(žýêuE0Îo ôxßLø„ÌÿÒ„ß ÌõT%žéÙ1⹡JöI§ÇQïÁËó5¡} i‚Ð_‘3C¸pù˜bÌ-Y²$‰)ƒB_ó›Šp$­ÖaŽƒ>Ç»á©ø=Ù( ¦uùR6@V­ZÕï÷$ûãµ…ß’y»ëòq»F’€ÂŒ‘¤oÙ€$  H@µøáÈ=–üHÏ?D™p+oæuw]@3'˜xdR)Ÿ(ãzˆ(ÃXKLú­^½:…¦ÊELêârvá…ɰO|ãºÉ4®ûL·“˜ä^‘ 3XÏÿo'¿Nö©¶wR׺cðTòÜsÏÕöÞWѨÿÜ´Ûuõq»$  H@‹0ßrË-}¡àx¾'”¢äva@QÁ -üf ž«ÛñÀïÄlY"ÌÀà^Îxff>†<rðlÍï ÿéyþ£ ƒIähÏL°ÀC*žð»ï”ãëÜsÏM"îÁ”W>¶Ó>éô8Ê̱ÏïBûò[ O1gÆvÂzUýžBÌ‚xaÆŒ©¯ ¡‚ ݆ òa¾ß¢ÑßÌËQ!ÝàÐO­x-lig9Q¯Ë/¿¼X·nÝaÆâÅ‹;:Êeø¿†›€ÂŒá&lþ€$  H@àÇ7?Qï_¿¾Ï8ÉI~ú£«#¬$ÿ½3{¶ªHóvŠ  ‚" *Š€‚  ‚–8—¥VY]Q}ÙÑQÑ7Ý7Ý@ßTGtôu ]]Úji©XNଈ¢¢" ¨ ˆZj9ëÇ“_çéd±öxöÙÓy2b½ÏÞk­Ì|r­µó}ó—oJ GàôĹš‡™å}þT%sëÖ­û…ÍeæÕÒ¥Kc(Þ¡ kG6œË)áxl'ÇNÕ=Õ·¯euÀAŽõÄq›$  H@€ª ÿtÍ5×Ä¥ùS j ÏßL„ ’#ž ÂéøQšIi–‚@°˜>s.Ì œô«‰œ@^­Nøf̘ûée Äõ-W³mÒìq”o0Ǧú!¡N;}óÍ7ñcÚ§–P†kdöìÙq£} Ê`Cƒ0ƒ}Ø8 ھÑÔŠ:–åY¶¼âp„J7Lèv 3º½…,Ÿ$  H@¦pL0Ðó“Ÿü$‚Ûö†°ÇC”ÁÌÜeË– S2V[p€±åÂúV íÛn&8q 3ûްºy™ŒÈn¨DäŬ1¶<á|ܽ{wt`7RÎQ-¬sžGþ¾SuÏËP|ßH=Ø—¶+k?ÖyV”Q¤ëÿ€$  H 2´òõÃ@t«£O³u"Ñ7G$†è¤]©Ù6iö8ê5˜cxmô]=¯lX’p¨R+ꘗ¥Žzè¡(FÉ?'Ú âŒFm»ü¾—@»(Ìhió‘€$  H@h˜F"!+ØB½Ï, Âe6£Øo¸  H CxÖ±mß¾}  vìØEjÍΆ8Yo[ ƒË =!nqŠÕ;cý™u—‹LÈAÆPê'Çn^]¢g¼ýöÛQäÂò(õ&fîq\¾Žs­c;YwÊV© ™UÇVORBdEA´ÝPŠjj±õ{ H@€$  H`øÀ/øòË/,ÝBͱwŒ¨;|®~¨éˆ~¨„u€$  H@è_ ¡àgVîŠ+bxBEýÛÞÖLøÿ¤±.o>ëaÀ‹/¾¸_ä‚¡bF\fà1Ó)OD/* !›ï“¿O"€b”†9ß·Ú{Äyl$BüÂ1˜ *Á©ÇúÙõ&B?ñÄáÑGáë=®“u§Œü†"rÌëÏç´!u@œQL„6nä÷¸™ö+æéÿ€$  H@Àð$€-VÉYåä“O®¹„Ëð$f­»‘€ÂŒnlË$ H@€$  H@ÚÀ„ âË,g’'fmܸ1®÷œ>ïÌgð½ƒè lõ¦´vvq½cÄlõ¤]»v…gŸ}6ðÚH"¤íI'×ÂÎÛºukxî¹çÂ'Ÿ|’\úž2®[·.Ü~ûíáõ×_oh9“NÖÊ ªA<1˜6¤\Åè¶¼wîÜYÊØ%  H@€$  T"À$…õë×ïg/Z´¨cKïT*«ŸK …Õèø$  H@€$  H ?í´Ó¢¨ Ïže8XW÷‘G‰ËƒäßÕzO¤–C!êF½ä ȳå‰å<ØŠ0ò}ò÷Ô¡IqÙ¢V¼ñÆUÏC,ç²zõê°víÚ@ýIˆKfÍš—ÀʃÃ<ž~úéýœ{ù~~øaÜï–[n ¯¾újøî»ïò¯k¾ïdÝSá*µá[o½•v©úŠ0P±ý¶mÛت]yû­Y³&ÀÓ$ H@€$  H Ï?ÿ|´ s{ŒèŽçœsNŒØÈ¹ÜW$pP'37o H@€$  H@€Ê œp ᬳΊâ…Ý»wìôÒK/ÅH,űxñâ¸ÜËUäËž¤Y†‚è;v숃è[¶l ï¾ûn\jÕªUq©’´oÙëøñãÛûï¿?ð5¢ ÂÈNš4)PFÄäƒh‚s¥â¸ãŽØŸ7Gydü<˜G”ñàƒFÑÆôéÓK#2!Å“O>E%ûœ´ÎX q‘F>ûì³£^{íµçÞ™gžÅ‰á§Ÿ~ˆªÁ¬¬Ç{,.ƒÈ€º²OÙÒ'.¼édÝ)JjÃ\ÔBR¯É“'ïÓ†´3×e&,pJ´)ŸíÙ³'}¯KÚÑÍ´iÓök?X¿òÊ+±Y&¿†N⛎ ‚I5QMÇ fÆ€úŒ@£Ñ¾ú¬úûT‡HeôéO™$  ÔK€ LNøüóÏ÷9¤ÌÙg'ÿ‘@—ð°ËÄâH@€$  H@€ @¤„DŒ¸ï¾û–ý@HÀ’.øž:uj8üðÃã–¢à´úâ‹/â>  Ì BÇp<Ç|ùå—5…/pv!¢H³“X‚A}Ö÷9sf,'ù‘ÂŒ .¸ }ôÑqÔ’œƒµ)ù’8†%Bx=ãŒ3¢€:ãxCÀAD –/ALBž,ËÁF9pê×›­Ì™3'ž+Œæ<›6m ˆ0ˆ"B™Ù÷«¯¾Š"„ä–;á»ÓO?=–—ãêM¬;e¤ ¾äÑIM<þøãmÈr'´ ‘ThÃåË—GD!Q‡SN9%¶ |H´‚™Ô~ÇsL3fLl?䇆H#ìCÛ%mlê,î6“$  H ]î¹çžØ— Ï@¿ á'}Øâ’kí*ùH@½A{˜É ÉI¥>ï¼ó¢ý‘þ÷U½@@aF/´’e”€$  H@€$ aI€¨_|qŒô@ôÖÖM ñ‘ØX'2ÂØ±cã× „#Ì@t„é8^“È!ÿ¬ì=ù#j t,ˤ„Àƒ¨ ̳Ô$R ðx'”p¾/]º4.ò / ÌÔç<,˂й0ƒ 2HäÁÒ.8î7oÞ< –Hç¯õzÒI'…•+W>Òþ”ñÑ1`H8\>ƒ_¢°/‚¢—Ð,Òˆ0£Óug𣬠OTjC"Œ ~)Õ± "–i!ƒÏˆ¾‘Úω¼GRj?Ä-I ¿ð$  H@}C E«T!ú6lˆ}ú 3ØèÃŽ7.nôeéw±Ñ¯ f„JDý\Ã@”çµå1þ|…]9ß÷…=ÑLR€$  H@€†#Ü®»îº¸Ô‘*ˆhPŒ8Àx¯Æ‰r"(pÎzf'â'šÂÂÇæÂòÉüO„ŽI‘øŒÄÿˆ.¹ä’(!šBr €@„Qi© œõóæÍ ,½Â)M8îˆ>Â,«»îº+.ë’GÝ@h€$ AÒùá(aÉ’%QØ1eÊ”†£ tºî´9üˆ²ÂÒ#)Hªc=mˆÈföìÙáÒK/BŸ¼ý¸Y&%_*%›×bû‰Ä$ H@@ÿ@HAŸ¡ØOÍkJ¡'‰¾Ç!Ì ò 6>£ÿ†¨“>+‚Q^ékÒ¿!/Þs6þ畾ý–$0Íó÷½$Ð{ˆÀ—GËà9@´ ¢@rß›$ÐKfôRkYV H@€$  H@¨Iç ³ëxMŽaœ¶8wI8|qúàÜMÑp³5’’¹xÎ]Oâ8–ÁYÍ’,?€sŠ¥CˆŠQ+‘³p<Ëqମ׉Åq—_~yt’3[‰P²‰kž7çKËfÀ»˜hÄ´‘6¨u(;ÇRß3f„3Ï<3GÙäÜxŸÿ_Ì3ÿ„ aÅŠ1d636‰Ü€˜ h¤ýaÎþX.\Î9çœ8»ùqm$a ÿ×rüwºî´áe—]Ûq—tM§:óZ­  ƒ%,ACû±ôIÙya?ÚlÁ‚ñ8Þ#ìÉÛ‹÷ùÿyY|/ H@@o H­¢·Z-DzÄýвD¿’¾VÚè‡ñ}—¢(ƒÿÿõ_ÿ5öåÊÎçg@o@„A”Ä<XiÑ¢EQÀÕ[5±´aO‰T$  H@€$  H@=L€^¢3üô§?N^ª‚ó†þF3ýÏ?ÿü8ãŸÙ}8~;î¸À²¤#Ž8",[¶,:‡óó ¶h$±$)êFÔDÏ`9,Y‚sg5âÄÔQË„08üñÇÇsÖõ&êMY9ÏÌ™3côŒ?þ8°QD “K`Ì;·â©)ϹçžÏÃ~Û¶m‹åÇϲ+$0£¬#N<ñÄ8‹’ïøÿê«¯Ž‚ò¥<´I½‰üqì!`b"?°D ƒðÃÁO]Ž<òÈ0mÚ´pê©§Ær$1ß³¤IDàö¡îµR'ëN9iCÄ&ð$ íw¢„¤6¤ÞÔ§Rr=„s°üÒy`®;òayÖj?®K“$  H@½O.Ëß½üòË…·ÍÔ-[1²Yµs%mµ}üNè ˆëb G˜½a’@¯8`¯Ñü}¯ÞrK@€$  H@€*`F ÂDÍÎÌÇdFôÀ¹(p„¦V'Ï5¢ 6D”“|pV¥È),4eoU"/ô‹ƒú Æ#j¨Wô‘˜# 3ø G"De¬q´'AõDtÐL"/ò&jFf=¨ ì*qK¼É›2TÚ¯R¹:Ywòæz¦î\;‰%mwê_Oâ…C±ý’°†emCÞGƒi¿Jlý<„_ÿú×á7¿ù($  H GüêW¿ŠËŽõHq+“>Úš5kÂm·Ý—Pë¤8â†nGuTŲú…$  H šó^t¢¤æ) H@€$  H@h€@ wÜÀ!ûíÊà1BÁÎÊiÕyò2èM„¶v&Ä)Dˆ¨'JDµråLˆRoBûl#`tˆ¿ÙJ@@ç Œè|,$  H@€$  H@€$  H@@¿`‰’ƒr®p¿¶¯õ’€$ ÚfÔfä€$  H@€$  H@€$  H@€$  H )Ê›ÂæA€$ Þ%À …k¯½¶w+`É%  ô]»v…»ï¾»GJk1%  H@€$  H@€$ ¡" 0c¨Èz^ H@@—3fLøùÏÞ¥¥³X€ú‡ÀÆfôOsZ H@€$  H@€$  4MÀ¥LšFç€$  H@€$  H@€$  H@€$  H :…Õùø­$  H@€$  H@€$  H@€$  H@hš€ÂŒ¦Ñy $  H@€$  H@€$  H@€$  H@¨N@aFu>~+ H@€$  H@€$  H@€$  H@€š& 0£it( H@€$  H@€$  H@€$  H@€ª8¨ú×~+ H@€$  H@€$  H@è,ï¿ÿ>|ñÅaÔ¨QaÄçv¶5Ì]€$Ð>øàƒ°eË–ðÉ'ŸÄ;6Ìž=;ðzÀtG!-…þ—€Â / H@€$  H@€$  H@èZ ¶¬[·.lÛ¶-}ôÑañâÅaâĉ¸tm‹Y0 H@@{<ñÄáž{î {öì‰ý‚1cÆ„¿ýÛ¿ ‹- #GŽlO!ÌEuP˜Q'(w“€$  H@€$  H@€$ öxá…ÂM7ݶnÝDÍ8ï¼óÂèÑ£Û_s”€$  H k¼úê«áµ×^ _~ùå@™Þxã0þ|…D|Ó-ftKKX H@€$  T @Øf”ÿ¯¼òJøè£ÿqÄaæÌ™aÒ¤IŽòc H@€$  ô×_=¼ÿþûá»ï¾ ï½÷^ؾ}{øê«¯fôGóZ H@@Óð‘SÙgÅ}ü_  0£ÔÍS€$  H@ øË_þÖ¬Yî¿ÿþ(ÌàP„̼öÚkÃ!‡ÒÀÙÜU€$  H@½E`Ú´iá˜cމëÇÓæûÀ½Õ†–V€$  w 3†û`ý%  H@€ºžÀ|xà@xÆ”vïÞ×Î\¾|y˜2eJúØW H@€$  ô¹sçÆh,erä‘G†3Î8CaFßµ²’€$  H@ýM@aF·¯µ“€$  H@è„i&ts1}ñÅq‰…E2þ/ H@€$ÐOÆ–.]Î9çœpÐA…#FôSõ¬‹$  H@À0  0c4²U”€$  ô /¿ü2<ûì³èß|óM8ôÐCÃÔ©SìY³ú¥ŠÖ£X&äÅ_ ~øaœ…7f̘0}úô0cÆŒ”¦<Ë8 Œ9r¿/<ðÀ0jÔ¨ý>÷ H@€$  ô#²>q?ÖÓ:I@€$  ô…ýצÖH€$З¾ÿþû(ÈøÍo~#|ûí·1tíœ9sÂ?ÿó?÷e­ÔÐøî»ïÂ[o½¸®üp!ÌX²dIøû¿ÿû¡/@9Œ?>Ìž=;°|É×_bMmÄ#GuTgq7 H@€$  H@€$  H@è… nž€$  4L€óO>ù$¼üòË ë¨DaÆž={«¯¾:° ‘3òÿ¾èà› &„+®¸"Lš4)áƒ4qâĸ¶6¢ “$  H@€$  H@€$  t/…ÝÛ6–L€$  H@‘!›‰˜qÒI'…O?ý4°´ÉèÑ£cÔI@€$  H@€$  H@@wP˜ÑÝícé$  H@€$ Æ5jTÜD" H@Í iĈÍdïQ­:OÓð@ H@€$  H@€zŠ€ÂŒžj. + H@€$  H@¨Nà¯ýkxóÍ7ûï¾¾þúë]gêÔ©á¸ãŽ 4¼Ü_~ùeعsgرcG\ ê£> Ÿþy8ðÀøqãÂQGf̘—Šâ³J©Uç©t~?—€$  H@€$  H ¿ /L·¥µ“€$  H@€$  „7Þx#Ü~ûíá•W^ ß|óMŒ´³dÉ’pÙe—…£>zØúàƒÂÓO?ž|òÉðöÛoGaÆÇ¾úê«-c̘1‘Ç‚ ÂE]¦OŸ^ʦUç)=¹J@€$  kôMß{ï½°{÷îðÉ'Ÿ„/¾ø"nDÍ<øàƒÃ¡‡&Nœ…Ä“&MTÔ·2ÐùË_®]»Âûï¿x#HF°L¾™±&Ož?+;¾‘ÏÚ•L©íÏ>û, ³¿ýöÛÀ2±©^Ç|˜0aBKx"†ÿðÃ"pì ^iGò;äCbÛ!L~íÈ#oËv3LySÏwÞyg í¸&‰tÈr¾GqD´Ù¸.¹?LèE 3z±Õ,³$  H` D8o Òwß}ÄbÕ1¬è°—%:î‡vX`à¥ÞÄ,Úd~úé§ÑÂa†1ÕØ±cÑGÒñãÇ×{Ú}öã|ÌbN3v9çÌSšíÌ _ö£.ìwì±Ç†)S¦Ä²äûÅ{Ú”!è”Ä’pŨd6œ›Iõ°à¼É0£,” G Ê;˜ÔS®#Œrœ$,÷ìÙßç(W¥ë*ͲƘ/KõÔ©™ö…ÎÊOÛP_œ3\—ͦv´q^6òãzæzâÞÆ)ÃFÝàÉý…Ç­žöÌÏí{ HàÿàÔE”AÔŒ”pââ .ÂŒmÛ¶…5kÖ„Gy$Š2xþç‰þCzñ›p '” 3ZužûÍo~“4ðC’–ÿøÇU;ê òcH½öÚkÑ0Å Nà”ãcŠp„ n!8óÌ3£QÌ`r½‰s½ôÒKáÎ;ïŒÂʈQqÕUWE#ç=ôP4F0Ž)†Æá‡·eË–…óÎ;¯Þ,Þ2`%g³…ÀŠ„!›ŒKS‡¹sç64àW‹ùàŒØ²eKxþùçã+ŽÚœrДö Œi¶jBf0üùÏŽ΋󡘨¥ëŠóc^zé¥û]WµêÔlûrÞÍ›7‡»îº+ 3(/3/^˜ßhjWçåBPµÏuÅuM;â°à59Hpú¤ûëä“OŽ÷Î'“$Ð8~7‹©ì³â>ýð?Ï•G}4þÖòœ©•x>ñWL­:Oñ¼þ/ H@€$0| Éí©§žŠ>ÄÔøŠ"â"ýIÏ>ûlxùå—Ã9çœæÏŸ'8Ä/øƒéñÇëׯçÃ'RÍNÀÃäü äyÁÄ :Gj¥vå?ëÖ­‹óà…Ÿ¡ZÂ7â¹çž gŸ}vX¾|yŒRï@?“|ˆÌ÷ÄOÄs h¨”ð9’ðãßµ×^N;í´šËL¶#TæN0LyãƒÅЍžëXYzë­·"?|²ø ¹O:餲]ýL]K@aF×6“€$  o üñŒ‰j$0òî½÷ÞÒ]0¦è¬#z@HPLitä1Fôæ}Ù }ñ8f408qŠ1Œ7sæÌºÔî 0¼™Å›F8ƒë„ˆCn»í¶hØ¡ ÏeC$AÞC%Ì Šaß1f©ÆQ5òâP $ãYg…êÕÄ©NÕX BA ‚³ f œ•¥×_=:PÖc´ž{î¹1òBÙ¾Ô¾4ª%¾¯t]á| Í.¼ðÂèœÈÏS­NƒißtÞ¼Lˆ„àܨ0£m î3fíÓ–8-¸f*ÙìÏýÁL"±Ð–`xo’€$P/­[·Æß²¢(#ÍRã7†g9ÏCˆÕp6S«ÎS<¯ÿK@€$  Oøðu=öØcq’B5K!&1a»[›Éõø_Ò¹èÿâW`²þ¥Z‚t> „ ”ÈÏþóèª&bhW^ôåñaýéOŠe¬æoHõI¯±VÐïÇtå•WÆISÕêűäÁ¤8é¤^Žø¬ðqáC;ñÄ« 3Ú‘GâÐ †)o|·ÜrK¼.±ßê¹'¸vñí!rBäBV“z…€ÂŒ^i)Ë) H@fèˆcø &qŽJs>Ǩ¤óÏŒƒFóÂ@BÌ1 SN9¥fq)Ož0à8ƒn¸!^óYâØ²Y½eû6úBˆûî»/CÌ.¨Ç"ÊD„»ï¾;FAP‚p¤L “—© Ú¦«W¯Ž+އZ ^Dc`†ÛÊ•+£1]<.±.~ÞÈÿœ£ÒÌ‹JulûrÞbžeŸÕªG'Ú˜k㦛nŠŽ§¢Ø¨Ry“˜ƒû’Т 3*‘òs H H³Ðp®æ‰ÈJ_|qŒ¬Tfð»Zü oÕyò2ø^€$  H`x *Àƒ>#£æ$Æ}¼²]•>*Âq Ÿðg1Iˆ%ok 8¿¢„!øÒùøŽ„P™¥"Xv¿  ʉdš}d&A–•D!íÌ‹Hy7Þxc\¾$÷·á“BATN–À…)õA/¶‰KA2ÐO}~ô£ÕŒD‚Qþªt„ßÓö.QÂ1–Ø ò.mˆŠ6$Ïä×á¸ô>±-¾¶#”g'’7ׂüeþ""Œ°qmò=×-ô`Î5†¨†ëÎyÛ§zù*n$ 0£[Å2I@€$ ÂÑ!žÈS™áRiH>gýƲY°)Ò†Nž0féôcˆb •£ã ccSÂã ò°æf£kmr öÔ£¢XGÊ” =ÞcL¶:Q7 !6ꘆ%‘˜eŒ!K=)3 ˆ>1™ŒtŒ"Ä*ðÀÍDõÀ"4!¡ ×®];°lõ†-mù1¦qä¬Ò±u,/sÉ%—¤j ¼²ô ×åL ¶E®gòG,PÉ‘Λ^»¡})K'Ú˜vºÿþûÃÃ?¼Ï}Ã}Å )×moî%ʈ('…RE˜Áuf’€$P/œžÌäË{ÇÂ9 `pL`Œ±aP#Œ Âg’?Fâm…¡†ÚŸefrä‰:p½Ð~$ pœˆòtÌ1ÇÄ%4òÏÒ{®fV—]WiŸüµÓíKY:ÑÆ8kØ…%µ%ÌhË.º(ÎZç=7‰ûˆvå¾ÄQÂãho“$ z ð{”~“Ò1DÝaMl~OêM­:O½ùõâ~üæoذ!κäNâwÿºë®‹Ïù^¬“e–€$  H@CI€{|-Lì™;wn˜7o^ôE1i‰1e‰ecñÍüîw¿‹ÒÉo„?ƒÉ5j 3ð“‚Wü&)á3A¼|Ùe—ü Å2°/>&áû!2(ð‹Tò‰´+/üDÿ@XÄÔ ßK¢ÂVžð ‘`€âÖ[ouÃAÂÀ?ÄwVÊ¢dü^©ØçŒ3Î?ûÙÏb´Œœ!ö~ʄЀIBˆ\ø¿š¯£yPîN1$oüø!ñæ‰kë?øA\V†û$çI;ã{eIeˆÄñ¦öËÏã{ t+…ÝÚ2–K€$0Ì `¨.Z´(n  £aRf`(aü4šèØccaaDa˜MQFY E9O˜È›o¾9§i?D¨í.\XQUŸö-¾b„ ìHƒ× j¬X±" "‰ä f+0÷U ®ÛöŠŠ¢ òÄøÇ8‡Mq;ÂÄÌê`ÎCbf ”ïÃ$D ©°¦`Ͳ$ÌÞ€*ø”0 q pMÀ/‰30ÈÞxã(tcž¸^˜5ÍFÂf&GQ˜áÜÌu•ç•Þw²})C§Ú˜Ù 3¸7RÂ)±|o¸SDWE'÷#!?¹¦Õpàá¾4I@¨—F¶<ñ;Ås½‘Ôªó4’g¯íËoèŽ;öºÒOA8i’€$  H@ØŸbú¥ ücë"¨$pHG3éþ|ô·R"räØéûôÊä•¢€1ÇÕW_ý>4ÊÊÁg ŽS^&2ñqB‘Ü?“òáµ]y1™ƒIFùÒÄø®½öÚ°lÙ²Ò蹩œ þÝ_“\ØÍÄ)ŽÇ7Q5ƒ%‹BüVÕÄ5ä‹ÿ‘%`˜ÄD›–;•¯yW§’7mG=sQ \¸G®¹æšÒ%z`†ß¾[„9Åspn“º™€ÂŒnnË& H@À@xpùå—‡9sæD†Q­¤ Ae÷þð‡‚å<œ`ÆhQ‘_« œ'QÇ¢ gMˤäçx¢ `³µ2zQC¾´†a4‰,ø¢Ì8§ |Î`K†08óÛßþv ¬&ŽŒq„*y=ê);¢ Ê@dþð‡aéÒ¥¥³œ“x„r ’Ç!‘ù# a9•¢¨$íÓ®×N¶/uìT#œaYš˜¨_Q%a>âò¢ä¿N=‘Nñ»à7C|€8aFYÚ•>(&Ø_ž˜„ÃD„õ$/ˆ%˜h•Dë%:LS„Ïü\i—ü3|cõú.ê)[;òè$C|=0.ÚmÓö.íƒ(ƒÉ`•|‘pÇ‹± ¾H&Š¥ÉZy»ø^ÝH <6R7–Ô2I@€$ `°žAû‘"ìá@IDAT믿>†Á«%ÊȳFA–ÍMBâ1°+Š˜,„СU©yt’!¾¢âr0°ÃOKä\ê_+q°?Y‰BSl“ZÇû½:E öÕÝ©’™¯$  H@bÍĈŠaÑ1ó’ƒâ”SN‰¢ ”áíH™ÌtÀJ‰r°œ ‘zöƒË䉙 ,iÒHâ\ÌÀ¸êª«bd…jkn¦óÒÌ:)Îd@‡£LûwâµíK=;ÙÆ´eј¦<ÝÒ&¸ÌSz8œs§39ò fk$µê<äé¾€$P™¶³£ÿë¿þ+¬^½:0£¡†IÀp"@tÉâ䞇ÅþoΤ(`à;&ùs+S»ò""Öæ‰åoYj¥È'ß§ì=¾¸"„•˜ݵh[<ôÐCq9¿V Û‘G'áŸ]žðé¦A=m½|ïÄ2¢›Û$?·ï%ÐMftSkX H@€z†F[1bÂŒf#4 l@ÙOô‡v%ŒX„ùÌbf ù‚0Œ$ (Œà<Áƒ™$f+ÿŠ+ö›±Pé<_”·XfêõÑGU:¬­Ÿw¢}©`'ÛQ aVó„p‰-¬k’€$0¤+Ô!ck$µê<äé¾€$P™À /¼nºé¦pà 7„ßýîwá™gžÙ/zå£ýF@ RE±_‹Ý_M€ß', –%7nÜ~ç,¥våUôeQîi{—ÁÀ§ÔhŸ…/,çŠÏ‚åY‹vçÆgUÌçùçŸÿó?ÿ— Î}l–%íߎ<:ɰ,Ê “Ĉ–Ѩ°!¶ŠƒK_%Ðm›2Òm¥·<€$  H C0ŠPÓöÙg —ƒQÃ’%KÚjHPVTêy=zô~ƒéù÷•Þ'D)Ü#a1fù¿^Å;" ªJa1+åÏù ©I”h¢?}×Î×Nµ/uìds0[%Oi½YÚ—Y µÖ Íõýð%€3Œk™YKˆ{xϽs‘gB¹±cÇf!Ð"„m3‰ë“å¨8/çdÙ²gù³æïîÝ»£ø‰g Ï Ê@Ķb(ÜfÊ“ŽÁÉJ½wìØÅ„p'OÊÈóçõæÿnL´ÎbÚ¾88i?ê@û%v“&MŠÑ—ŠNÑjuâ´çL‰ÿ‹Ôtýð]žÈŸ6†]+ÎS«ÝiK~q"ä=l(/ÇÒž´%×r­såõ({ò!¬2¯éžÁaɹyF#äz­':yàd¦¼i-hÎ Ûb‚%ù–%Ú;1/û>ÿŒ:× ¬`–ò£ÌÜëÔk§Þ:äç÷½$Ð[ˆòǬpž¥ èð[Ìo6ö‹I@¿ ?”‹.ÊÇù÷E|Ç2&Åe6°Å/ž»ø;óÂ÷S@ÐÇÅfj¦_H¶ÉŽ€¿9,Sä„haËSO=5Pü^DuÂn;óÌ3Ãܹs£Ÿó6“Ú‘G'–EyÁ/Z¼4ÃÎc$Ðíft{ Y> H@€º††Y2Ò0Žs5=…ä»ô}#…Æð úƒzíL ¬¼ýöÛûdÉ€ õzóÍ7÷ù¼ž8ÁN X0hÀ?C™0”‹NYœ©,C™w­swª})W'Û˜ö8õÔS㬕mÿ+¢MXÇôüct˜°  ®¢³£W¿ï À2³eË–8È›ìsm3ÃýÅ :ƒÌ Îâ8Ã6{ö솞© þ>öØcaݺuñ¼8Ð-ZÎ?ÿüó0(üòË/Ö¦\3€æº¦ <ÃqpâDãXK ü7›øaÐiãÆ‘ïyžRw~(#ÓD¦9ùä“c½ yÛ-Î,ÊH™7oÞxð>ÖP?ÊJ=h? ˆLCËs÷Z³žp&>úè£ñ¹’8³®uñ·˜20úØüöÙgGŽUžO)5sÎUæ|¥<üF2“^ŠŠ•„p y~Ò® øÝãú$ø àÚåºÁy S~«¹^aŒ€nÖ¬Y1?„!ÕÒk¯½ySmÈýYLÏ>ûlR?çÚšµ çÏŸ_öuü ^8k™OÛq¯}üñÇû Y’0ƒPÜ\3„¡fæ§IèOÌ„æw–ß^l'þofð­?éX+ H — `OÐgCt† ”„̼҇£Ï•Qñs°/ç)öy޶ÚoW^©os}P|\ÍÔ‹¾g‘QÏGŸùšk®‰> ò£ýHôµŸ|òÉØ¥,ôMéÏÓ×f"Qчªðg¨óè4Cì‰bûÁ¨–ýW—K §4ï%ê©jZX H@€$P ) +ŒŒWŒbÄü&CÏË#êË¥;öÂhf°&O ­]»6*ÿóÏëyϱ ”æ‰ÿÛ!ÌÀÀ-FÒVÉ@ÎË4œÞw²ðdižK.¹$®Ž”÷ÜsOpf=9,]É ixàYûÊ+¯„§Ÿ~::µdæ9R+á¤D Áà÷9çœÜIieçáùEHtÖN‰sÍ›7/ú VCðÄOD‘÷VY¢ œ‡AýK/½4®ÛÜÌ BêñàƒF#¿Ié÷'Ï.×°B0rÁON ¤ãŒ\¿~}`íâäÔ¬V.êA[1èwÚu¯«  Ü}÷ÝáÝwß­vê8K™‚e‰ßÄ­8b By¢ÿ@ݸv0‹ÑJYJbIfû!ì¹è¢‹¢8'e­ÄõÁõ€3¸®Ë®›t.Ê…„ÁMÖsFˆTm}fÄwÜqGŒb‘ÎQ|%?®¶²Äoâ f…2ìOß‹û¡Ô† bŸ¬è´Mç…×=B@~?.¼ð°lÙ²ý–šKûû* ô6žôíy¾Yˆß»f~c{›‚¥—€ú‰}5lú´Ø3Rt2úÉ5˜:s¾²þàP ‚·+/üLeö}ÛV¦j"ì•ë®».üùÏŽ}×¼O»Ò'î¹çblülÑ«7/ÿPæÑi†eK™ F©ÇvÏù^½H@aF/¶še–€$  H ¥0RôÂFlÁ–fõb3HÀ@a1LbK Ñæ“áÔÄ+Ö Á !­LõƒÉ“µFf &¯^9¶Ú˜Á·¥K—ÆAõ‡~8&~ ´1@É@"ƒˆi–<Î f•0ƒÇ4üð¼eðúOúSÐç9ÕHbrDg`ÐöÚk¯ÂŸZçà~aË×(?wÝuW|6Ålùþé="¤Ç<Îðç™Ê€w#‘8†AüÛn»-:i‹Ïé”OþJ¹Èæžâ÷¬X—|ß¡|Ïï)Âø"*!E¥Aõ²r°/mGt~‹/¾øâø aY™²„4w‚–íSë3øò[ߊóÛŠúõáæ›oޝô%êI”A ‚C¢gÔfÀ§>ŽáGy$:õËðeys#„àYÌõsÕUWE§qQìȱ­à “Jן#´¸é¦›âk½¼xn$^4üý(ki?“@ïHýJ„{»Úacô>5k  t#ú_Ø<؈2è÷bÔÛk¤Nô“Êlž©­~޶+/ò V9W–ÞCTQ&$f??øÁ¢P»?Z1êíœ|Œ|O„7"Ç-\¸p¿ˆ¯yÞéýPæÑI†\ø\‹×%6³~½Ôú¾ö3…ýܺÖM€$ šÍ} ¦m{íc<õ{Âbàg(F$ƒiC½ŒÉPÖ¡—ÏÝ-mL¨|ǹ0d™4)áPaPGr ªâ~É’%1ä§3&©áñŠƒæ¾ûî‹Ñòs0ØÊ3‡ ‘U¸Æ¹–ˆ¦A„†ü™†8‚eI˜uÃR D h4!ò`f;ý!ý6àÀÄQǹIä#5lNÇâX"â˫ԓ8Ž{áÖ[o÷JÑYE=`@ýpï0#‹sòg1‚òóû¬ž¼[±‘En¿ýöy„¶Ìm3"JP~82ð?œ˜ù <õáYA›Â`åÊ•¼ós2cšhydö/r#¯2Ç3Ñ"8§k+ÎÃu‘'ú):mKâš  §íRAù™íMÛQ8 (âúåÙÈglµ¢ –ˆBœC¿&%ÉÜ7<‡áNd ˜Ò6D!¿$&I÷ Çrɨ˜8çBÀ‘R#¼9†òÀºÌÉóJå*ò¢l|ÇõÍ}OYRëå•Êî«$Лˆhe’€$Ы¿÷Þ{£ð›>\nCP'ú¬ôwÒF5¬¦ÿ߈»xþÄm(„ íÊ«RÙÓ²~ªw=¯0'ò"vdµs!df)C¢`0Á$-ÃGÿ´h ‚fc©Aúû—]vY´oò¶-+ÛPåÑI†Ô™þ|± ƒÊ—ñó3 t#…ÝØ*–I€$ !'€À€HkÖ¬Ùg]ù”9P2†yÍgbD0˜”Ò1½òZ4€R¹´aù ^“0^€[°`AÕ0ôƒÉÃc«è–6NƒjÌ|'4?á<` „*Ü2ðMø}fÜã¤bʹçž—§¨^[¿í ã°J N16"0 Íà7Ï(®qgSÄ#"¯0°›®}¾c‰žCÌ®m4q.Ê‚ãŒAu®e¥ ¥NyÒ’\Ç\³\Û¼¦üqÆq=#îÀIXÏ2=ä‰0…N¹3A(žÍÔeÊ”)Qœ‚㊼c0Û Ÿq‚r×rò5Ê£Öþ´‘2xàý–ÉbyÄ) öÃö£|pMü¿Pï$` ?x‚vçYÿó=L~™#%ÎÖó#|0‚/œ¬yâÿÓO?= Y öw.j®V~ú“ùñi_”§•!Ú•W²%R]Ò+6Ñ(+àãxúÏõž‘76öârlÀ´< BœmotžOe ‡&ƒÀ8ÏX2!EJ,‰Á³]£NG΃ӈóS®Y³fÅbÎ…Ð ?¢³W¯^EGÉÉʵŒ‰kžzTK8¢(gÿ|¶ùpìøÃXÏ|ðŸ|ˆÀ½µvíÚ(Ð Ïv;´ ‚AÀïcJüÐvü®œþùQ”Qæ¦Ì ¼#–Dà’;šx衇bT ~—óDĉ+VäźsŽÙ…^ûgôÝŠýž¼.D=Ë}Sùweï±Êúߨ/Ø­µ¶+¯Jâe¸Á!o»Œé»²aû1Ñ»‘>}å}‘rÑogéNÊJ¿¹Þölefˆ ‚ =·[á’ÿßî64? ´‹€ÂŒv‘6 H@€º†ÀÌD½ë®»bøùT0 RfBc#ÌÀá_ÌHûb sŽ^M ^`ˆQ¿â a÷©¿©· tkã,a–kŒKÄÌögË s®Kœ t3˜‰ƒÃÔÿpÐ\yå•q˜Ùù8)«9&!‚ƒ Ñÿ îþáx®1ÀO$ D<ÛM8LɇÙUW]Ë}”›å6úGgJD‡Aˆ„°£šÓ ÷A>0Í}ÌqäÍ`}‘u'Åò½X.Q ³èòAúTŽ¡|…1ùæ¢òã>§ìÌ^«$¬a?X80a #D ø“xÀ§&¿ËÕÆºä‘,Øò®¥b;æûP¿i{Å,ˆ'pLVê‡p Q/±Á?%ΘíG?úQ|nr”%òaV&÷b ¢n¤þ×,‘4psMµ#•ñBPC¿¬/ún\üFp¿öÊõѦæ! H@@w`iOúËùà3ârÄË–-«;BC#µ¢律°Yòr¿oæÿvå•ì?¢ÝåuHb“fÊÞÊcè?#ÆïЙˆˆôµ±IS¢ϲÊôw™”ÐhlfÈò†Ø9ù®Éd4ÊÃý%ÐKfôRkYV H@€ZB€Áfßæ& ˜0ó8C´%™váIÌÀ˜cI–”˜õœ ¦Ï}íMÝÜÆÜs̼f0™7Yk—ÙdŒ3«„Ô È*ÌèÍk°ÑRÑ‘¬Õ¤Ë΋ð‚Èwß}÷>Ïw®#œtÍ3¸‡HÇYÊuÊÿ•5ògFT.Ì ò çˆ6*•‡"Ñ#åi„ ÑI‹h¡Öà4pºâd#rE *?g«ßSv„ŠˆOrÇ(u%j‚™<ÊG¥üaK”–lm¥Äïÿ#Šì•g¿¥ÅßS®ïz¯\ÿÕîX³„G‘;‘[`§J¢ŒÄ•Wöc‰ÚepH\;)Ò ×};R/XU‹r’—KAFNÃ÷€$  tìµyäʈ€yñâÅC"ÊàüØ“'OŽKö%;›Ï‹Q+ùl°©y!bFLœóĆÈë8Øú öxx`£årÉ1//}ù´äa³y &N2„ “ò„= Ÿzûÿù±Ü_& ô }¯ü^)µå”€$  H@F;àÌ Æ Î^K—.6¢ êÎl†<$9Ÿa¢R7…80Üëz¡8dð™Äk¯½6%!O Ò²«iøÀASm@º Ž#*$òÔìsóq=²„‚j¢Œ”3÷‰òƒ,Oˆ3Šƒôù÷D¸ ´q.”ãû3fÄeLˆ(Q+Q^ò&‘bjßì÷”ŽÐ<AýzDé8ÚæÌ.˯~牨³mï²&½’h¢0‚뀭‰kç%b•”èË .eæ]1ï´OñÎDeAœš'f 2“¯]‰òÂ,O­ä•Ÿ×÷€$  H Ý˜ T& ²ÂP÷ÛîmD”'V·‚I»òÂî)Ö ¡þ¬F}„­¨wµs`Ÿ²œaѦ#zJ¾„cµsÔú®™<:É¥s{úaëaƒ4*®ÁfA`žGߨÅËï%ÐIûZ½,‰yK@€$ *pØ;íìN‡½…9½y´ ΃!ŒA<œFá´½áÒóô׿þ5ÎØn×Lë<ïN¼¯t]aÐ}ýõ×(RKóì¥69rdŒe†}žpT`h7jœççðýð!ÀuDXÔ<ñQ<äßWzÏýÃò!DÌà¼õ$ÄPD)FÆà™ÊóµRÂÈïRî%O–’`&S½‰gƒòDØh×DÁ–ߣ°cvÂ’F퇓YTyÚµkW`ë6Gk^Æü=õ@t–'œÅDTIË´äß5ú§%ìsî,©ƒ3¼xýÕ:7Ž\fRæ áKœ´+Áªxï¶’W»êa>€$  H Œ‘ò¾~Ú‡þOQœš¾+{Ŧ(;OÙ¾é3„ÏE{†eEׯ_¿O‡´­Wú‰yä‡|ÿvåE>ň‚ôŸ|òÉ–‰òz ö=}ôbàsÂ~kUj4N2DŽÍ˜'®)¢¥6âã%Rå­·Þ' ävQ~^ßK Û(Ìè¶±<€$  ”ÀXÁè**â idà€ýéìv0„‹¥ùßéð·b`¥ZCý!™ќ;`“B†:ÿn8?uçº*†@§}ûAœÒkmÌ 6ƒÐ¹s‚{U»î–Þ(¾b„†fïgž Dààºl$•-WÓ­šƒ Á [žd'G½K_¤ca@-w:¾ÑWœºlybQF±-ò}*½çþÇ©8­ 䙌x¥U³Ê*åߪϙV— 2»çž{ârjˆ…Š}‘Fòf†c‘;×LQ RÏ9qÓVùo!œé_µkæ¬`–'x±4ÑÃ?l4¯Œï%  H@è9ôÍÙr[—J ЮWhÁÒs,ZÍ®(Cô?ú‰Å¼×¬Y…ÏõæO¿ð™gž ¿ÿýïÃsÏ=WZŽvå…­€Í÷_é[ßwß}C.ænfO™ qtQ¬‘Ú¯yt’!y3¡ èã}ä‘GbäŒz|@ˆ2n»í¶h_õº6µ»¯Ãƒ€ÂŒáÑÎÖR€$ЈjQ Â0Lk¢×SI QTÙEe=†h½Kx0x†Jñ^N8˜]\΄ÁAŠƒ„½\×Jeçzàº*2 ÅÌì^Olcœ"èa| j Ø•EÌéõö±ü­!Àu†ãŠk¨èpäZÌx£¥äš-†#¦lÕîž·E1ÎÓâÀ~£eêýáŠCŒ-OeÑòïk½/ð;ÍÒÌÐë…DÛ1 -p lÚ´)ÜtÓMá†nO<ñDdW¯3<¯ww›8}Y§‘5ÆyöæŽaÊ„0£x]æehå{8±„M‘7ÞxcÜüñÈ«÷s+ëè¹$  H@¾ðAY¯h×á¡Zd=ˆÑ/Ãõßÿýß1úZ5»¢Œ0ý«²%SX*~)¾­Zá‚Ìþö·¿ üãc?¶L Ò®¼à¹bÅŠýÄèÔ‰ò±TK£œ¨ÇWÀáðÍ7ßxà•±ž~)í·nݺý|øãŠÂ„våA>bHÞÔ{ùòåûµ×â-·Ü—4©ÆvÛÞeO¸vï¼óΆ&ë‘·I&pP§ `þ€$  H ^D7`°'IÏ:Š}BÍãÊÎË> £LgÐ"%΃ALøô<‚Dú>½2(„háöÛooH’Žï¦Wêyì±Ç†³Ï>;®©l Îlذ!¬^½:,]ºt?áFÚ¯ìÉŒUÎ_\³¾ì˜N†AHØwÚ6%Þ3xFxÅz®«t\·½vª‰¼òÊ+¯D† Lr ©•GáÉ p„TS§N­u¨ß÷9žKˆðxþóžÁbžÛ¼ç5]3|NÔŸN&œ­E‡+å«6øN¹‹à\ûÅð®¬WYÞ8;JÐyâw¶(xË¿¯õ¾RÝS{×:¾¾ç™Çï+Îݵk×0â:xýõ×ã2$<ïÒ3’cÇwÜ~¢žJu)ópàœ¬çy[õÔS1Çûkõ–÷â‹/Ž})úZÉ.á•øp~ðƒ„i{£ ¦/ŽýB_ð£>ŠÂ úaˆ Òò‹e RYÚ•×¢E‹Â£>—dI\(7ê˜p´råÊ(H!:nY#•“W|ï¾ûn´5é£cKâúÇüÇØ7/¶ÇË/¿þçþ'FV|ñÅ£/?">Æ2_"li·»îºkÀ _΋(9Fó9©yüÿœBèÔ÷‚ "cìtMÒ~ø\‰yÑEÅ(¿9#Úî=öXàÞIv("“²èÈ)/_%ÐMftSkX H@€ªÀBH°uëÖýèxÓg`ãÌ3ÏŒtä1™ŠâÑFžˆÇ . 38aiŒƒ²ÙΜᡇÚçØüܽöžÁ–Å‹Çp˜ |¤„±ƒúœšçe†&†ƒ:0Â}ûí·ãl–¥hf€(•£¯p„ݧì)1Ј¡Ç †Ù³gGc™zbT3ðÅ +¢^Hhc8Ü— "Êàž‚#¡FËøx#B ÷Ξu+òâ^‡s¢‘Ð/áw%ý¶Tã5˜2y¬$  H@hsÎ9'úð)¤>.Â"0ìØ±#ö™ŒD?›¿ èa/ã“`š>}ÉF}'úYDÝÈ#ÐѯDÜ€Ý5eÊ”(Ì ¯Åç” û [Œòå}ÏJþ!ÊÔ®¼`uíµ×F6ØŠipû‰Wô‹” 6a‰Ê´L%ßÓ·Äž„1lñaáJ\é·]¶(¸Ç'"6p ç§¾ÓöŠZ8ÿ¸qã¢?‘ó°/åbùü˜9¿äÃÌE©=Û‘GÊ« SÞø†ˆzÂý@S¢}î½÷ÞèÄFBXƒ/’{¿#“¨`Ÿxrü–ˆ»iS“º€ÂŒno!Ë' H@ÀŒSÔÜ ø¦8†‹_ÿú×Q…N‡—YU9°H}ï`,§ë CY \WsçÎj}¾ÃhÇhD „ˆ§Ò¬‹njöN´1Ž Œf6¸âÈ œ=ˆ-´ÅÉÁ>ܯ8œžþùÈ8ñcB®rý™†ž?8q¦átÁ‰Å³¥—ŸµÕZúrHü~E‚ÕÎÓ‰ïp8–µ Ï}~k›M<[9Ïž')ñÎÿOŸwë+}ú 8®ùÝ`éú,8‚S¢Nü†²áØÅù¸pá€ãžçe™ ’ߨ2î霭xåÚcæ¿ýíJÔ•¾"‹Ä §wrSÚ?ñâ7ƒßú†ôëv”ñjWùÍG€$  T#@¿Ñ.KÚåÑØ:ôoÐ÷Ê…)Bç¥Ì@vq`ºZžé;úHDÅà|,I’|aé{°l$ú®ô7ÙÊåøPÊDìßμð×\wÝuqù ¼É§C9èG²Ñ'Ç[ÒN D*Øcybì^‹‰s$±y‘'Ìð!&aç‡1þ±$Iç¢Ïúãÿ8œp ¥}×vä‘ÊÂk»æy/ß»œ ö‘[ò>?¶1þ€§Ÿ~:ÚÉwT´]zé¥1Ú/¾â¢Mçå{ t …ÝÒ–C€$ š0úæÏŸ£]0ЛNzu1"1²0ªR8;"!ÐqO" Žá *œzA¸@ýü'ºF{JÒÔ›0‰8F¸NÒ`3šqRôBý¨O»Û˜k…ë$% 8“²ð]fðÎfâä‰AAœ=—_~y[ó2ø¾ý¸ÏpLÞqÇ1BQþusù‹ŽLÊÊgeŸ×[Ž…Gñ8ä’#´Þsuz?~ ‰ÒÅl4Df<q¦ó{Stˆó,ÄùÈwl8îqàkŠ\R‰¼ÁoÙ`=äÇè,Å‚“¹‰öE‹C‘ÊÆ#/D¢Å¾÷9K¯Ñocch¯v–ß¼$  H@@%Ø-—\rI¡•ˆ©_‡Ãä¢<’g~|Pçž{n¸òÊ+ÿÿû¿Ç #ù÷õ¼GPA„ úz<ð@ôý”Ù•·é§ÑŸ%:Q1+ 3(K»ò¢¯XÛÁ }íbŸÆô³Ùj%΃ˆÎ]LLl¢¿I4 ÀŒ M¥?ì®„Ź›ÓŽ<òüÚÍ0ÏÎ×\sMüè‘GÙÏŽÇ&,k7ÊŒ û‚ .ˆKÖÐÆeBšY΋ˆ:ù BâÅýÃ3ÁßDÑW H@€º@,`Ó¬_¿>N) R™ñ=`Ç3`–¾ý3ü6ø1RbÒCþú¼ì•ˆhˆ3ð‘€INôEó¾Uñ8òC‚Ïd)luì—Z©]yÑ/f²ƒüø÷gÅÁ~µz¥òS?Ž¥/@˜èu´SYÂ&MÑ.6oÞ}gD?I>²c’ cΜ9‘]-~íÈ£XÎv2,æ ÷믿>ÚûÜ´]QÀžŽÁþäÚåž@ „ˆÛˆý±›¸g’H» Þû"ßW ´ƒ€ÂŒvP6 H@€ZF€™‹.º(KþóŸã‚eWtÆT``·l‡Î9aùË_Æe›GØ»²sQx:ôDIXºti4¤ˆÄÁ¬nŒb–9!a ø¨–0"0úxMÂŽ«dôU;W+¿Kÿ~ô£hì3Â:£šÅHeùbÄvœÁ#¢0xÊÿÔ³Rj%‹2†|Vï í†à‡ò3 üØcí3û!Õë‡3281µ²Nù¹[qÞv¶1lˆJƒs§Èºuë¢Ã§’qM])÷÷3¸?b™†Z=ôÐ~¢ îOfÂ=€ç:ÂJBÅö¢`Ž:±åÂ Ä ¹(¬¯²e¿±8—+9˜ë©³¢òðÎéD_½ øKå-{åw á"NDê™–0Aˆ29éð;ŒƒG%¿=)ñ›{œ¼¹ ƒû‚ç.¿Áýø]àþ‡} ~CvîÜ#0Á Kr‚sïðÛMí§?ýiìƒôë  H@@ÿ`¹:ü%ˆ èÛ`à 4E Мþ }FD B#ÎàúF¤¿û»¿ Ë÷.A›¾1¢TúŒõ&ìl–@过þ(“s2ÐßÂW…m‚²‘?ý̲¾µ|Û•lô2‘ Û‘ºÀ”(t0¥^ôé?Ã1Kª~8RG>Kœ+Õ‹~<ÂÎK>´‘NxO›ÀsQwìW¸áCD¨R/¿väQ¬_;óÆÖAð²råÊx `ç~`Rv6,‰8¾ðLB ÎE›þÓ?ýS¼–·ÓŽø÷êå],ÿK`( Tö”e®ž[€$  ‚kŒ ŒÈ鬳atÕ8ks&#¶RVœƒ‰Ù ¦ÌÂä\,O€Æ(~:ÿœÃ* aHÿâ¿ï¼óNHá;ö«–HaÆ,ù¦A' ¡»!1 >m¯Zƒ52Ò¡`ÈÀðÆ,¨Æ-¯|W+µ’y^uÕUq  C˜Á)ÚºÔ›hWŒ_ڙВ\O\0` Œ<¨'×U>@–Ÿ¿•uªó¶«ÉCf„é„#÷ ƒ‘Ü_ .âá~àþá•vã=Óð"À5¬­<‚÷%ÏLfuáì×Ä3³øÜLÏÜn®3¢<žûü&äÂFžÃ”¿ÙÄósä‰gÏ ~ãû!¥úÐá7…þQ›XÊ$‰-`ÊÒmüw¸7`ŸG ‚Y·‹yšm;~/’³œÁ~‹o»í¶ýx]Ç8¿=& H ÿÐ'ç9GŸ›ç‚I@¯Àg}ƒ Œ˜€Ádú~ø´ø{šþ¯ÅD_Ÿ ÏDö¥OÞL—Æ?jîܹ1ú¡œ—g,yó¼eljW^ô±áÊFÿ:-C‹X‚ºád˜QG÷›ù=Áþ¡ ØÈ‡(´_âÇùÙ†¼Ö{”ñmGeù¶‹a1o˜-¦ôõ¹'¸`Êw°Äþ¡|ÅÄ}€ŸøÄOŒÂmöi¦]‹çõ {°CAÕsJ@€$0äèt'#ãå;v H:ì޹zºZè¬3àŸs¥Î?ßa a;ÿ|ŽÆŒMö-îSÌ—rc2PMy1Îê9®xž¡þv‰ ud°ɘMFNâƒT«îÅ2·’åÀ9G9“±Ýh™8Oªwº®0ißt]qmU2ª[Y§œ×Pœ·m ' g6fúp-q¯&ãš:r±Á—­Ûœ‡ïû“ÌDëɱ‹/îkQõå7†-OÌ\KÂ?ž¤E ‘cšÙ—û•ß4ùzÊÛ·oë^å ™{šãS4ªT.®„[üÞôS‚bœ¹<´lÚ´i ŠI|:ðÁÿ¾AÀû\˜à3‰>‹û·óúbC•¸…‹ß{ê›GÉ©Äk¨Êãy% ö@8Ë-·Äˆ~ô+S(þf~gÚWjs’€$PϰdÓÇ©7a;·*%[¼Uç«vžvæ…§¢nì“¡¶QÚ‘GY»µ‹až7÷>¤fÒP·C3eò  (Ì(ñ H@€zŽ@2b[p:ÿÎà˜f:þ ,´bÖÁ`ë\ëøT¿fêXëÜéûV²ÀhdljæZÈóle†ú¼íhcê@>ˆAØL(H¬ÅÙþ8dÍÛï 'lÑKdfþ"—øzÓ ìñ§)ÍôË…„ñ%rƒhÌl$!D CÝóD4#¶~MüÎ~™Y^¹0á¹Gr±!ܪv:%Â(³ ëb…>iŸV¾Rž¼LœQħCÙw ï—fÅå î¢ïyµ²ÞžKè –Æ{øá‡£h‘hB)´~;Ý:Scs•€$  H@è7M»é·Ú[ H@€$  H@è8sH-&DN îÕAC¯%"õB8ä† â–±¨71(}Ï=÷Ä+¢Ó´#10Æ–'Ú’u·nÝš\×{Ža ¨E)!ìB C„ª~Nˆs`¤¾)qMpp/ä ‘ ‘¾òÏióçŸ>²Ï÷ª÷ÌxDl—_·ä•" U¾é¼•xQ®b™Ò1¾J@½KÑN~ÓÒMC¡§wIYr H@€$ n%°¯eß­¥´\€$  H@€$зD?~|=zô>ud€÷ý÷ßßç³Jÿ0`sï½÷ÆéJûtëçDa©yBÜÀ áz$QÆêÕ«c„…üñÄû !À‡åLz%!NA(ÔHb–æ`Ð1%êÌ–‹5øÜYÂ+OÌ"߸qc\%ÿ|(ÞWŠ„D;壑”–Jkä˜J¼XZÇ$ ô–0:餓bÈÿ©S§†9sæ4ê¼ÿèX# H@€$ ^ 0ø8ϽPKË( H@€$  H@]K€^–^8ꨣöYšÁ]÷‰–Pmûl¦ä×?û±\ CÊŸÃ!D~ƒ–úÓŸâ28^xaÌ—e?ŠQ78çW_}vîÜEÜK,%C»!:þøãC-A Ñ<ˆP¸"%®Ä! œÒæ,ÅB>,Ëóúë¯fº#(I‰,_ÃuÀëé§ŸÎ9眊¼,„:æõ¦~0©Ä+åç«$Лøm£Ÿ€pŒßÁ²gZoÖÌRK@€$   3†KK[O H@€$  H@]L`„ áüóÏÔI`Á¬xfðÿþ÷¿O=õTŒÌÀ~ È XزeK`é¢!ðy%|þùç]\Ûý‹Æ¬ß3Î8#N%„º“ZÀàÖ[o ?þx˜4iRŒ.Â`> 8 äH" –E#‚ÎÓŽs„Û·o"Ê–‘ž|òÉ8àOÙ'Nœ ÐV”‘Ayõ3ÛŒüU«VÅ Õ"¦¤¼ºå•eLØà€p€ë!âDDÀ@ AÓvD A°‹ÔŽÔ…Ùáçž{î~Ë•¤z|ðÁaÑ¢EñúàZH÷ × KÛ°, ÷y! @üÃýÃ`&킃<9–÷ŸÚ€rA£–0ƒ2"² ŸtÍr" "†Pg¢jp^òATqÅW„O¹À€Ï4\tÑEᬳÎØ—Ï‹‰¨´9×Ë ÔI ¡Q*ØàÎ=Fô ÷ìÉ—cóDÛäeÌ¿+¾GèATŒçž{nŸex¨‚êÌýJ©ä¤÷œ/çÅõœxɃò¦²ðeæ{^ó„^ ,¨Ê+?Æ÷€$  H@€$ vP˜ÑNÚæ% H@€$  H@ °$ƒÌ ê?¸w fõ§Ä2⌲Č|–>`&>¢…v‹ÊÊÔÌg Ö#Na`œAt¢ ù¿øûŸ|òÉáÒK/‘+X†Áðv&ÊpÜqÇ…ë®».F8@$€ €ç=íX!äå$âƒëDÊ`I þïµDT ®G¢?¼ùæ›1ê u þˆ%Ø*%ÚPý´å²eËêª?¢„«®º*Fâ@”Är$/òÄÿùý”—¿çºCh AD­Dy¹fYjˆ%…ˆÀ‘'¹ðƒû“<Ф/"®À‹-%Ž«‡×´iÓâõÂR?½x½¤úú* H@€$  H@ýMàÿ,áþ®§µ“€$  H@€$ .'À /ƒû?ûÙÏ™gžˆ¼°aÆŠù¼_ºtiÜŸ(ˆˆÁL}3îY¡Zb qGŠDÁ¾ ðòY£©ì8ÎS﹈Á’&ˆTXŠâ‘G‰‘Šb ÊEy§L™E le‚üÙ—üXOE`5Ô‘'h?Dˆ N=õÔ¸üÌúõëc›A¡RBÔÁò³gÏŽKsÌ™3'Š;êÏ™ø§ˆ´?R„Šâþ•þÌyÈsÉ’%‘×/Ëð Ð¨Æ 2–/_æÏŸŽ?þø@4ŒzüˆX‚8Ñ+Ö­[õˆ1¸V¸ŽN;í´x?±$÷ç­'5Q‹Õ«W‡M›6í#ÆHç  ¸_igê›팅<Ÿyæ™À5ƒ@#]»i¿ü•ã§ídpï#ä!ÚL¥$ß×÷€$  ú,1¶yóæ¸ŒÙÐåä™%  H@½Oà€½¡ ÿ/îiï×ÇH@€†5Öä¾þúë«2`Àä†n¨º_J@Àà lܸ1üò—¿¬z"fšÿêW¿ªºÏpý’AY~×XÎ`÷îÝq&>3Üf–AÜ3fÄÁ`¥“ðãp³l øŽýª‰3Òr) ž³L‚‡I“&ÅÈÕŽ+kfø§e;( ƒôˆMønDAÙPw–„@pÂ',ßÂ@6 ÎËà4,(gŠB€™;8à,g@œ~ÊЌء¬žµ>#Úågù–× üDS ü0‚1âÄG}t,üÔ«NÅrp0¨O¾$ò˜>}zd”‹ŠÇÿoÅyƒ={öĺ#¢]XʃkAuF”Â+íÈ“FÊš—¶çüäIÈs×®]ñ3¸s]‘/\Øè’'÷ùrqÍ6“¸wÒ=K›³}üñDZ­©×mA{—µqŠêAÛq­pqý缸Ÿ3¸q.ÊÞ,¯fêé1€$ áH€¾ }Q~›Ùèk§~}>6¾Ï#e9a÷`ÿ˜$  H@ՀŒáÚòÖ[€ú’Îp…}Ù´VJèA 3ZÓh $ãfc œ½ Æ`€¿˜œ&j¯ì[¶Oñþg`˜A^Žkv°—|9eçäßì¹(ugP=ÕŸs1xÎà6*E6€UªÏ`Ë@9šM”ƒòSÊÃÿ”ÆÔƒ:T«G£ùÂ=Ei¤ý‹ù´ê<œ—:#*‚eãÚ„zÀÿ+µe±lõüOù‹yrm’\ì$þ­Ì—ºQOò¦½97ùp½òZOJ¼Ò9Ò½”ÊË+u0I@€$P¿¡üþóÛÊ{^ÓFŸ„ßìô»M ¡%BZ„‘lˆ,\$¡d¾oêŸrþZ‰>Ï¿ýÛ¿"£™$  H@Õ€Vìpmyë- H@€$  H  B`@·l†}¥â§àJßWúœÞV ö’£KgT*Ÿ'áBµ}ʾcž­Ó‰2¤ í( × Ì›ZuÊ„D)²Ë`ËVÏñ”Ÿ%lØÚ™¨ë`óí¯v22/ H@@»üçþgxíµ×¢8ƒ<“ˆqï“h#‰Šùœ÷l7ÒÆÿƒIDé"j—I€$0œ (ÌέoÝ%  H`X ûì¸DËĉe ŸKÀšJ@@ 3ªÀñ+ H@€$  H@€$  H@€$ rãÇS¦L 'tR8å”SÂÔ©SÑGŽ8âˆpðÁ—ä§€$ aH@aÆ0lt«, H@€$  H@€$  H@€ê!0bĈ0f̘0a„0yòä0iÒ¤pÌ1ÇÄè¼;vlÜX¾däÈ‘È& H@€ö% 0c_þ' H@€$  H@€$  H@€ú‚ÀV°ñÑÄA£Y ¢8äC¨Q£â롇-;찀Ђ¨£GŽû±/ûr,ç0I@€$P›€ÂŒÚŒÜC€$  H@€$  H@€$  ô_üâá³Ï>‹b )’Ejðnðʆh#m,EÂ{£`ôT³[X H@èR 3º´a,–$  H@€$  H@€$  H@h–ÀÌ™3›=Ôã$  H@h1…-êé$  H@ÝN€õ@ÿå_þ¥Û‹iù$  ô<-[¶„ÿøÿèùzX H@è?«V­ l& H@ZØØ& H@€$ 0Ãk@€$0̆rÞ¼yìÖVW€$  H@HŽ>úhm‚ÃW è‹ê|@IDATH@CH`̘1CxvO- H@@/ÑK…µ¬€$  H@€$  H@€$  H@€$  H —(Ìè¥Ö²¬€$  H@€$  H@€$  H@€$  ô…=Õ\V€$  H@€$  H@€$  H@€$ ^" 0£—Z˲J@€$  H@€$  H@€$  H@€$ÐSfôTsYX H@€$  H@€$  H@€$  H@€z‰€ÂŒ^j-Ë* H@€$  H@€$  H@€$  H@@O8¨§Jka%  H@€$  H k |úé§aóæÍaûöíᬳΠÇ|×–Õ‚I@€$  H@€$  H ]f´‹´ùH@€$  H@èC_ýuxûí·ÃúõëÃsÏ=vîÜ<ðÀXS…}ØàVI€$  H@€$  H a 3Fæ€$  H@€†7ï¿ÿ>ìÙ³'<ûì³aÆ áµ×^‹ÿüñÇá›o¾ |pxæ™gÂe—]FŽ9¼aY{ H@€$  H@€$ aO@aư¿  H@€$  H >_|ñEa<ùä“áÅ_ »wï}ôQøüóÏã ˆ”qÌ1Ç„… †óÎ;/t&g}dÝK€$  H@€$  H Ÿ è%ëçÖµn€$  H@€IàÛo¿ »ví O=õTŒñÖ[oÅèŸ|òIøî»ïâÙÇŽN?ýô°hÑ¢0kÖ¬0qâÄpøá‡‡#F 2w—€$  H@€$  H@@ïP˜Ñûmh $  H@€$  ´œÀ_þò—°iÓ¦°~ýúðòË/‡>ø °TÉW_}ób¹’3fÄègœqF8öØc£c̘1á€hyy<¡$ F ðãÆó ñØôéÓÃèÑ£=ûK@€$  H@€M@aÆ z H@€$  H@ýAÑÅ›o¾27nÜvîÜ£c|öÙg±‚.ˆ†1þü°`Á‚0sæÌpÄG„ñãÇ–11I@è&;vì?üp™ÝsÏ=aÒ¤IᤓN ³gÏ'Ÿ|r˜0a‚B²nj0Ë" H@€$  H  (ÌèãÆµj€$  H@€j`9’?ü0<óÌ3aÆ aëÖ­QŒAt –1!rÈ!á”SN‰K•0ë|òäÉQŒq衇Ö:½ßK@è·ß~;>ÓxƱ±€zè¡(Ê8á„b$SO=5sÌ1á ƒt“u¬±ÌX€$  H@@ŸÐâìó¶z€$  H@€Ê|þùçq€’0ÿ/½ôRؽ{wøè£Â_|w'ÆñÇÎ:ë¬!ƒ÷DÇ;vl1bDÙ)ýL@W˜3gN¸þúë€ÒsŽåMØÞyç°eË–ðÔSO…qãÆ…)S¦„Y³fÅhÓ¦MsÉ“®jI # H@€$  H ÷ (Ìèý6´€$  H@€ê"ðÍ7ßÄåIc<÷ÜsÙäÌ"ÿôÓOÃ÷ßÏÁå¼yó¢ ƒPÿGydŒŽqðÁו‡;I@èGuTX±bE\z‰(@<ó6oÞ—6áý_ÿú׸íÚµ+lÛ¶-<ÿüóQ¤AT |É“Ã?Ü%Oº¥Q-‡$  H@€$ % 0£GÎbK@€$  H@¨‡‚ f‡3àˆ ãµ×^ ï¿ÿ~üìë¯¿Ž§9rd˜1cF\ª„æ„ôg r̘1õdá>€º’Ñ}xޱñ\ã9wæ™gÆçbŒW^y%FÒà¹Ès’g#Kž à`É"MŸ>=œvÚiqCìá’']ÙÜJ€$  H@@WP˜ÑÕÍcá$  H@€$  4G૯¾ [·naúe0¹gÏž8;œ32`9iÒ¤cÁ‚Ðý'N ‡vX`“$ ~"pÀ„Q£FÅçϾ©S§ÆeKV®\>øàƒðÆo„_|1.ñôÞ{ï"l°mß¾= ÚÖ­[k,yrê©§Æc9Ç¡‡ÚO˜¬‹$  H@€$  …CÖÓJ@€$  H@h7ï¾û.0 øÌ3Ï„§Ÿ~:†ægÀ‘¥J¾ýöÛXgÏž.\ ÙOt ,M€† –gâÙÇvüñÇ–nZ¼xqøè£bÄŒ—^z)FÍÈ—‹áøŸzê©°iÓ¦8û›ÁÅ/¿ü2–•°ûDÄ@ŒAÿc=6L˜0!Œ;60‹Ü$ H`8 ‚ÏC6–<9ñÄÃüùóãò&;wî ¯¾újŒ¦A¢O>ù$>[ó%OÖ®]Ÿ©ÿ½3 –«8ïw{ÁÆbßI€BBBBhA öÝ8x!ÞâØN¥\NU*ó)kÅò¯2N\)cŒcŒ³ƒ‹„-HIh„±šÀ_O'}}æÜ3sgî̽w–§«æÞ™3gé~NÏÌÛoÿú}I•BÊ"j Ú0úP'÷*Û. H@€$  H ”€ÂŒR¾’€$  H@€$Ð>þøãÀJnÄ+V¬L‘ƧŸ~ûí·_œ\$U «¹>øà¸Ê›•â H@èN ¥XºdÊ”)ñ»qQŠÖ®]…Øv<Ê!àH)O?üð®”'Dã@¸aé\ï½÷^×x E`á·[›v7¿ÙÑ ›‚¾Lý»` S¯}öÙ'>ȺõuÏÁg,Dj8ÚÏwíFÜÚ_‘ÆZ¡ôõ}ðü€$  H  (ÌhÇ»j›$  H@mN1ŽðÛn»-N ÷GsqÈ–úÜsÏ­ÚIÊ*N½gŸ}6:í7nÜWTâèäÓ}H1À#9ý˜P9rdÌu~È!‡ôyóp¶šûé§ŸŽue‚au¤~ˆ1¨Û AƒâªQ&$ÈÃ>dÈ~j|øá‡±Ž÷Ýw_ ŽøœqÆaêÔ©5sBˆ±nݺðØc…—_~9N°°ëÐÇÒ=AœA V¼Ž=º¡“)ÍÒG¨‚”… †-[¶Ä{OXw&Ž>úè8ÁÏÄ~=åÝwßQ-ZxÎÄqÇfÏžýõœ»ŽE0…cÉ’%ñûdçαÏ⸧p¿˜ø#U á÷YáR•´³ ªî½m”€š‡ß§)å )¡Y‘»1vB DØWLìòxþùçãö‡z(Nî’ò»{¨|‡[j'€=ñøãGû»º? "‹.º(¦¼©özØÕŒ]ðÐ?è+ü®'{›ºÓ·Ò˜W°·ð›ŽÝÔ—…:ìØ±#Ö1uÄÆHc„Œ¨#}–ñ cl9>ý]ø\Ý{ï½qìKø¡æ‚ .tPÍÕ¡íØ¨|vзÒ=âóI»Ë`kÑæ &ÄH8loDi–>B?X¶lY•ñ½ÆûŽ(Á/ã‚zëÏ=÷\˜7o^üL0æb¬Å›>Õ(ž¸'žC€$  ôÆX}Q3Ï) H@€Ê`âü‰'ž8·qæôGÁ‰ƒ‡TOÔ8°pèápÂYüÚk¯u­6ùY©àøÃi;þü(:ÀÙOèlœ€.„ÝÆ¹`Á‚8iÀkVÆá,*©n&¦M› ýáDÃAºzõêðè£Æ:ÂG0õªE˜Aÿa‚ûˆQ¸?2*µ{Íš5‘b”É“'‡3fÔ%Ðh¶>Â}ç¾ÞxãÑ>W8baÌ$Â7¾ñpØa‡uª¶Ñ¿æÎ…08}¹oLRàÔ'ªƒ¥;8ñ]Bª’åË—ÙDË`õfºGÜBì3AÀä “LÕë4ï^·H@@–¶!µ<˜¨¾[ÄÉ÷1‚CRœ$Ñëúõëãk~yò„mC™:th´¥˜Tf2¾¯'à³mhõçÛ·ov!ö6¶U~_±]ø½íé·Û’ßoÆ,ˆs˜èæÁ„OõÅVå÷Ÿ(€èWˆy{‚±v1"r„ºØˆ2ÊÕ‘>J4¢H`Ÿ~úéÑ>f|Ð_‘4°!ù !¤À^BØÂ¶I“&Õ$Ì ½<òH´ƒ¹G´½Òýá¾>îÁŒŸÛóÏ??ÞŸÞŽ…š­ð½uë­·FÁ c& lÀ›ñ6g=ßSð{øá‡£KãÜ|‡<¸®ñU|þ½†$  H@¨—€ÂŒz z¼$  H@ýNqCZÉÔŸÇ™ÎêÇJ œy8­pÖy€cÒj5ueßä´ÅÙÌD,Ϋ™3g†³Î:+:ÿ«9O¥}!¬Zµ*üሎX&phöT¨íçÁª2êÆy«\|ñÅuMÚ÷tmÞ§Žˆ3’“m8N©Oµ7Ї$ôTh7÷•✭[·ÆÇ·¿ýí^EzhÆ>B?ÅùO_Èú õE´AØuÚŒs¶7…Ï-}›s¦Â½KÒ6ÿ‡È÷„Õ×LpRßÇÍ “cÆŒ ¬ÚFŒA„“þšñ>I@@)¾›±y¤”'Dõâû› ‘#BOì»dOaW0Êä=ðq¾2Ïd<ß–òàˆmן¶v ö vM%aó°µ±•¹ÏYû§|‹þômâAdú ö±.¹ä’Ak½…z!È@Ø‚(ë•cd¯…ýÍûäÅ_Œ‚çÅ‹‡K/½4Ú%õLÚg¯Sé9<©oÃðŸþГ>{N¢Ý}÷ÝQ(E?JçÊî“Îuy`3s_¸Ïù—EƵŠ3š±*± Qó…m¿ûÝïâ÷Qzks2¶` –ìZÄ)Ü»jøçëäk H@€$Ðjf´Ú³¾€$  D'P8üò¨™®ä€ÅqzÇwÄIœuµ8ó×â5‚œ„8ð¸êª«ê ŒÓ‹¬„‹Sµ7§-çbeõ¢½ßúÖ·ú$²GoêWt @¢mÜ~ûí‘kÑ>=mÃaH B<3ÉRk¤‡fí#8D™8*Wxçõرcã*¹rû¹½÷¸ˆ~càÇÙw>gœßLö1)C$Âh#Æ`"¯Ö‰€Þ×Ò#%  H ØŒˆ*RDD¬2ǦK“ì5ñbŸ$;/ 8ˆ°@DŽC¤A„Ò·5b2¾šú·Ê>üþ Äo ãrBUldìMÆL¼#*®FìP‰9„Œ è?ßüæ7cš“zÚNÔ–›nº©+eãŽÞìú/½¨Ûw¾ó(Úˆ±Z-õg CZLð´¡7…Ï.ù,óYÅ&«¦4sÁö,ǃ>BŸf,‰MŠj‘€$  H@¨€ÂŒÚx¹·$  H@M@GQ»[ÍÊœ_8 o›-¬l$lt5…}™„/—³‘Ã-·ÜÓ—Mpã¼% !®Y IôAƒÅú³úˆú±: gWšˆMõ¢„½&ÒBŠ«¯¾:†¾NïWûŸë°*î÷¿ÿ}ŒxQtip,–˜É¾8$æT`Ë$É86 çÛŒ#«Ti;íÉœëäKf„{„£Ç#«a°’‡k¶ÝÜV{ÕRš¹py”+¼G¤ÿ0ADØvKcð¹$ÂÎÒ¥Kc_㻀ÏTún#d9r§vZübbŽÐ÷ÞƒÆð÷,€úšÂº”ò;ƒˆG£GŽßõØWL%‰ ^l~’ÝŠ]HÔª”ò„ß`lWì´Jbá¾nS³œŒ °Ûª0‘Ž=“^1bĈuªšvaÃc+ñç·›T†Løs_‹&¸±ÿI=†íÉÄ6çÃÞÆþǶ$*v'vc²R½Ø‡"ÔA4ã Æ(µÆ¿ýío£ížgÁ¹‘V‡:b3>€Bì4&`¼“­mEXDE<Úikmg¹ý©;c>wù{D{Ðv>¯ØaØj)Bü¤¶Óï¸oùó”»v³÷‘žÆD¹@8†P!J9R¹ö»]€$  t:…Þl¿$  H  à¼d¢òG?úQÅÉäÔ4H¬ö¿îºëÒ¦øgÒüã’må^à $M@‘ó%QpRå'ëÙç$y¡?þøè€ÅÁÇvY8¿ˆ¬Aqxâè[¶lYÌ»‹0öC(@>^êñµ¯}­&GŽÜùó燛o¾9:TÓyùÏ„ÁÁÎ9眉_œÆÔvS7¬Öc¢€ú‘®…ÐÅ©ðŽäf-ԕл8ã³…vzòäÉQtƒè‡¼_ð€Çчp6s`V‹#²úH–KÑs÷ˆ[UMZKc°º”ï&Ä|Ž(ô­4Ù4nܸ0tèÐøÝÁĈ«¥ÃݳH@(Lè3ù˃ïwR—L›6-Š2RÄ ~o™˜ÇáÁo^l0&òÜ•ò„”ü>tbö+©½°Ýz*ˆ%®¿þú–c¾üå/DZEOÇó>6<¶2¶`¾)ƒ¨tˆzó‘óa̘1# -IAÆ=£/0®á\LØ3¹½…MÀýž3gN¢c‡§ÂsúÇ7Þ~øÃî-Ç"¨ÆÎÍìX’‚‡ó2V¢½<Òx…úq硽ˆH’ýÂ=`RTïì6Æ«´Ÿ~|衇fßò¹$  H@@fôÈ·%  H@hNLž6¬ªÊáHÃAš/8B‡ï^µXOÁAÇJw" äE83gΜ.¸à‚8ÉŠ ¢R!“±8BqÒßsÏ=ÑŸŽÁ‘ÈJÊ… Fç1+«)8q²2 @¶Àq̘1áòË/VdVà4fUáÔ©S£CóþûïBÎYC<{íþzŽsç1«³«)qæ#˜¹øâ‹ #Ð?¸gLœàx¤Ý8&pßÉ_Mi…>RÔV÷"\ÉFš!jÊܹsbÃQ«}ßOIÔÄw‘yˆŽ‹‰¶­Ê­ýJ! H@ÍF›‹ïy؈yù `b1Ñá˜øÞº;Õ‘»°)ø-FÀÁjìO~«±QˆžÀo¯;¥0iŽ=R­M‚ºè7•èõŽ H5rï½÷Š2ˆtrÙe—ÅH)Øû•lmîõA´C@”½È‡m]Ëäx-íGäCŠ•U«Vue›[—¾È¡’Ø€úa2Æ@è@_E4Ò¬ãô™Àæ"m\–'ï‘®ïŠ+®ˆ‘á¢d ÷ |N"0 í¥xð¹CÔÞSi…>RÔÚË‚¾(Œ§2¥ÿåyÃm€$  H@ÿK@a†=A€$  ô’N)ãwÝuWt gOƒÀ´pÀV»ÊÇûãE8@Áé—Jº&iMpÂ#è©°ª 'l6ÂÇà`$ -¹ q®9ªóçNõà Gˆc‘ԅɃf YLøa&5²« ¹8àˉ2òíF¤#Þ„¯f2½šbé~5{É·—שâÀNá™ùÈ…ÜÒL0Xê'Àç‘Ùé§ŸEL†ðýÑ“«þ+{ H@h&Ø&)å 6©RÊÄÙ”'L*#Ö倒”'¬ÄÇ>æËÛ|ÍÔÎv¬ 6&‚êuëÖu‹”Á>‘îjMG_Àæäžb‡"ú r]*Ø¢DÔ@ÌÍy5“ãy–/_Þ-RBÐk®¹&L™2%Ú •éúØ)<°‡±©‰ "!š ‘&šµ Ad€ž c"„ô¤˜é‰#lˆ¦Án°Çfæ•J«ô‘¢6`£²aënXÞЉÉ÷¶«E€$  H : 3ªãä^€$  H RLPã(Ïœ”„ÂE”î7ç\B+s§‚cÕi6ß\©°2ŽUa8ÓR.döG`#÷[»óSãPãu-…ÉD 8ê˜T&ZH³:åXÝ•Ÿ €/¬¬¥à¯åž¶B)×~‘2ˆI¡¬8(EmaE/^,Ý ðå3Ëjž “÷w?O¬Ä¬õ³ØÓù}_€Z“Â=&|y`³œtÒIaúôéQŒÁ)¢SRZ ÀÅ㽃]š&O[³å­Wkì$ìmìîlAD}ÕUWE[ªtöXž#àþ_zé¥q<0wZB¢~¤‚À€HnDÖèI0L¿àølªD΃ÀàꫯŽÑð’(<¿šÿˆ0ˆö‡€„qÁ>ûìë\ͱ±Ÿ‘ù!]ŸñŸ±žÄiÿôŸ¶ò¨¦´B)×ø`÷#cl“ }ž{Θ°™Å8©¾þ—€$  H@Í@@aF3Üë  H@@K`õ"« 'œ ‚„ õˆ2Ò¹pà²r '|V˜Áû»v튡sI•‚X \a?&‡ -8o/¼ð¸¯ž‰à´ÚŸUg´½ Q²NDêˆóE5+ëiS+ô‘ríƒ Œèc„¼NQ3øÐYÉêʾfX®~Ͷϟ7DP8ß™4ãuO%­ˆíi?ß—€$ Î%€­—Rž Šd"~Ò¤Iq¢”‰f¢Ú„T ùIçÎ¥Ö?-Ç.Z´hQÈd1ØÈDfCàÚQF¶ö¤§AŒ'+ÌàzLŽŸwÞy=Úµ=öXŒ®’js3fÄH}ô¯ÞlA&ç‰øÕ¬ãÔ6ÆɦMÛ°w±Çúª´J©Ô~Æô?Ä©ŸÓ‰Â‚{xéA+]Û÷$  H@@;(ïÅo§VÚ H@€$Ð`8¢ýÒK/•œ™ÕbÓ¦M‹«®JÞèå Va3&:[_yå•®³¾˜‰_V¿ù¢¨°jÓ¦MÑYŸ}Ç#NbÒ¥Ô#ÊÈž³Ù°yñlòbl{ñ¼úH¥vât%œ3+t ÃMíTHÃkVɑΦ“ ¢'Õ2øÏJTœÖ|F-€$ FÀæ4hP|°’ÈgØŠü6#%åÂa¢«U*+W®Œ©0õ¬’зÒy:ý=Òb¿ÿþû%(N=õÔx_•š {ŸÈŒ=²6vöÂðrÑCp¿é#ÙBZB&Ü%VnöñmÏ ØÆ˜€±A_•Vè#•ÚŽ°„5ŒI_™CµA2â!¢¯X$  H@€*hÎe•ë컀$  H`À ÎaÉ’%%éApô‘œ<àt?~|·6ã{úé§»mORó+' ‰ETV.ÿË¿üK›°€$Ðì˜`g⾚( ˆSyìØ±#lÙ²%þžßÿýQÌ:bĈ0jÔ¨‹óEhvýQ?&òä#Q :4N`çõÖ a÷û"; Îx ’ {—qA¶0nÁ~CHÚI…1cÔ© ¨}ê©§ýžqW#K«ô‘JmN}ÅD†Dä“äHÿ#U¢—¼p¨Òy}O€$  t"…x×m³$  H@uÀy‡C4ï„űÉvvQ]ú¿ƒÉKMÞ^D„‹M…J8Ó gœwü’;‡YÖiÆq„8>ù䓈:Nçn§ÿ8žó ڷsçÎpë­·ÆÈ!0idi…>ÒS{“–ýp´²JQBê÷¼Ï Ã|0ö{íXø|žÕ¦¬Hå³3?E[áóŽØ‰É&8%NTÂ9¯^½º‘Ø& H@hLBc»òÇoû®]»âãùçŸö&bL&©I•‚}KÊ~ï:)ºBO·{€T"I ™ö‡é ]°/°Y™Oö×À6A(š"d¯ËvÒO`›fË 'œÐ‘)l06È¢ÀÑßgÏžöÝwßüÛ½~Ý }¤šÆa÷có"Ì j$âäÔïw>ôÐC1õ!ì=®¦~î# H@€Z…€ÂŒV¹SÖS€$ ¦!ÀŠ´^x¡d¥•cõ“²}QXùÈ껬0ÙÛo¿¼—-L“j"’—ÉbñT À‡0ß8ÏSÁAÍDû¯ýëpõÕWÇr$¶BI*ýOâ ÄA8ðÏ<óÌpï½÷v‚8ˆ>‰ƒ–>íRøÜ jBŒ±|ùòøY±Îç-…ç3ÉäÑl˜€a²„U‚y‘T»0±€$Ð^ÆŽ.¾øâh1ã™gž‰Ñ’ø˜‰VÆ#ÜxüñÇãoÜ‘GFŽ£i`[Mp·¥Ê­a<@±|a<À¸ Ñ;5qÏ 3˜G¬]–¿.B›?þñÝÆ-ŒtZA\D?fœ”« LB°ØàÜsÏm˜°¦úHO} Øñ )éW/½ôRסô?Ä\_sY$  H@€Š (Ì(æâV H@€$P–@štÏïÀäu£Ãߦkpw¬æÇžfà$ÆÉž/8Ðóûæ÷i·×8±I/qÁ„ßüæ7%bø‚ðÎäÙ>çœs £kÔʤúH5mJ"öEx0cw¾ôeË–Eç:GìÃ?˜àiõpØ/˜˜B±nݺ8YEßHŽû=öØ#НHUB: #Ž8"~æiæ=õÿK@@+`R›Iêã?>Lž<9ÚCL¸òÈï!“ÊØ4<ˆ4†mIÊVœրhn¤<á'¦0H|ò÷›ñ¶{_ÆEçf<€]›fpÏŠÄ#IàÑulæs2ºè¢‹¢0cóæÍ%U¥ßvÛmQ tþùçGÛ¶Þˆp­ÐGJ ¼Èްwù®@”h™>GAÔŒ0ƒÔ‡|Y§¤›$  H@Àn 3ì€$  H FLÒf#/¤Ãq’62ôm:/ÿqn‘†$_XÕÅ*¸|aÅÎÅlÁ‘Æ9p¤wZá¾퉆'žx¢¤ùÜOVƒÂ‹gœqF˜2eJ ×]²c /Z¡ÔМ¸+}ðØc)Mn¼ñÆ®ÃiëúõëÃÂ… ££»ëyÂ*S&¡è+W®Œá¾ ÏÌ$+ùÜ0ÁBšL>1)‚E§s‹Üd«) H@e `E¤ÁcðàÁñ·žß;"2°"‰Ô\7nŒ‘£˜ˆÅæ·síÚµaþüùñw,¤xísŸû\Ùk¶ËpÀÊxbwö•€-_tnÆ)µD¶>Ø·Œ ²¡)‘#êdÏÙJωx6sæÌ(DB\-DL£ï#h7n\Ü4>½ˆÖ }$Ûþjžó]AʾøHû±6cø.±H@€$  t' 0£;·H@€$ ŠpzæWžá|ÆIU´‚­âɪ|j‘èƒÕIyg+§¤Ž¬þÏœ¸Ô±·ŽÅì¹Zíy ý|å•WF.L$d +ÁˆŒÀÄ<FD¤¨˜:uj¯"Œ´Bɶ¿Ú爈,Â*¹M›6uFøg&f&L˜P— ¥ë„}üÁŽx¢¥,]º4¶…×8âÓ¤“ˆ0ˆŽŸI&¶½o§—€$ $€;‘ß<L°žrÊ)Q”Éo=RÊ&œ±xlÛ¶-NÒ.^¼¸+å “ÙDÓ8ꨣÚVÀx Ù é¶±[Û³/ ãÆùÂx ŸÂ}Õ‘h_}UÇ|Ýší5}ü¼óÎ  |ðÁnc&ÄGDºÀ6dl@_ž6mZŒ Q«Ø }¤7÷‡ï\|/¤q1ö5i+`3wªð§7<=F€$ Î! 0£sîµ-•€$  H ApzÒ9[pE´ÈîSÏsDEçGPðÞ{ïu;5ØüvÄ#ùðÆÝlã ˆfH?ñ½ï}/Üu×]Q|‘w`󚉵äžF€€Øà¬³Îª)ÅI+ô‘ÞÜjøÃ‡)_¶nÝÚ5@c²fîܹák_ûZoNÝoǰ’û¿jÕª˜èÍ7ßìú¬ð!= a˜Y%I˜o¢e hêÔÉ‹~»1^H€šŽö-i x °8á„bd1&¬c Òàñâ‹/ÆÉY&hIq†MRž¤tr¤8|å+_‰¤;$M_ÚŸþ̃41ôsú?i%T+Ðh…>’Ú[ËÚî¹çF.DÎH…È-<ð@7wZúÌÄÀÿ€$  H …•èøž$  H@( €6/zHŽë‚ݲ‰ó39Œ5ëæyÊ훽ÛóâŽíô•K¬Ã™Jä‡!C†DÇ!õù?ÄLÚ3ñ°|ùò=ãì³ÏŽÇæ÷Ï¿æøfï#ù:Wûš~ˆh(ˆRUZ%Ç$L³>„dç‘&0˜ä _%§;ÎzúH_EÀiV6ÖK€$PŽv$6lÊ~ÿIyBZ3~[‰¨Åä,ölØ"[µÜuZi;¶6_¶ béKaü‹ìyçëB½Š„ßé ØÞ‘È¤u¹óÎ;£È Ÿš†ý¸ÏDÐ@¼ýì³ÏF›ñ¢‹.Šâƒ¢´2“J+ô‘T×ZÿcïYá ß©’¨ttP 2‹E€$  HàOfü‰…Ï$  H@@U˜Ìýè£Jö%ôs_;8‹Î_îºEÂöu¢9ļÜD}¸âŠ+ÂèÑ£cäŒG}4†â.¹©»_p¯Yгqûöíq(éPz´BÉ·µÚ×ô#VÍ’[çtšl¡ÍDÑ`•QIŠúkµ×èËý˜Ð EÉš5kbˆv¢cЈ”AØeÈ}IßsK@@;À`Å<Rž`W‘¶+“׈3ˆ0°nݺøûÊÄw;ÆØ?Ù‚ýŸ¾*)‚× uD*å®[$ `<ЗuLuj…ÿq¶gÙ²e1µ _òc=Ú’¤ïزeK¸üòËÔ)S*ÚŽ­ÐGz{ŸèGD!Ý Ÿ÷ôY€Óý÷ßN:é¤hs÷öü' H@€Ú‘€ÂŒv¼«¶I€$ >%€#3?éŒ"å×í‹‹'¡E~%õ D¾¤:&ïã¼-r2æí„×8µIQAnd±“'Oˆ3H]‚#_àÎj°ùóçÇÕŸ—]vYtÄæ÷K¯ÿôšÿÍÖG²u«õ91LÀan©°B–r8g;4cÁÁ„#F„c=6öòµç?ÓÍXwë$ H@hFDˆÀ®â‘MyòÆoÄ4zí*Ì(C0ÈÛë¼gï¿ÿ~ ªCV”ÁùÙ2©ŽÙýd_7²~­x."ˆ ß-."bö+‘ò°ùˆB‚8ù—¿üeŒ¬wÉ%—ÄèEmOü³ï5[ÉÖ­ÖçD œ6mZ°#XIq ã*„[ØÞ H@€$ ÿ% 0Þ  H@€j$€ƒ‰é·ß~»ëHr73)ÝW…ógCĦ뤺¤×é?ÛqÐf‰8‰qæZþD€ðÄ1&Ô.Q0f̘ˆ‹- ;wîüÓŽÿ÷ G,9Ó¼0ù0räÈnû°!Ý—fî#…¯a#aÌgÍšÓ™¼õÖ[ñHœü„z&j)AŠDC5\¢Ovåž“óšI¢¢Pà}rQO* H@èØ@¤ãÁ¤-¥]£30 ½Øé©0ȾNÛõŸñ@ÑùS]ò×I‚ì1ŒúR<’¯C«¼NQÕL˜0!¦æ™7o^Œü’"Ä¥¶0 …ÏÝwß…DŽ ÏçKº/YþÍÖGòu®å5ýúôéaéÒ¥q¬šÚ‰xèÁ cÆŒ‰éS¤—ZÎí¾€$  H  |¶e›$  H@@_À•ŸÐE‘&§ûâÚœ?;ÉŸ®A]pøå Û T²YaF Ž’LÖ3Qê©§†¯~õ«áoÿöoÃùçŸó¨—ì¸û÷‚4wÝuWY1N+ô‘|»j}Møb„)gœqFÉ¡„/&Ç<Ú|i–‰œÃùÏp¾®¾–€$  H >üî7Ëo}-)>[›/[d…ÑÙ÷ñœñ@Ñù“  Æù:*ÌÈS*}M$5¢ª‘šçoþæobŠ>^ç9rÔ믿î¼óΰaÆBÁL+ô‘ÒÖ×þŠH#3gÎŒG²G¿øâ‹1e$Œ²¥¿²íô¹$  H@(" 0£ˆŠÛ$  H@@E“º¬šÂÉ™_MUá45½…¶(b‚œ‡ù‚ã0/Ø`ÎbV0YŠ À çâØ±cÃ5×\~ô£ÅüÈù½¤<Ôù÷xÝ }¤¨ÞµnƒQFSœ-¬ |øá‡» WtÄf)ù\€$ V&À¤{>v6vb6`#ÛÈx H˜Áx€qA¾ 6wÎt&yZ¥¯÷Úk¯˜òpöìÙQ´M*¼¢q×¶mÛ¢`»(Ú^+ô‘ÒV×þ ûž´'žxbI´<†´&Ù-Žjgì€$  ´…ís/m‰$  H@ýD€Hûï¿·«!| gp_°E9p¶’R"_Èõ¯#ÎWBç¾òÊ+ùÝ}#€c®S§N ßøÆ7 ÅäQ~òÉ' ….­ÐGrMîÕK81"œuÖY%Ç3)±nݺ°xñâ’í¾€$  H@íB[›/[°·d'¢³ï×û¼\DìÖ¼(›kQGÆÙ¸âå—_î3AyöZíðœ%Ç|øú׿£häS– Â!RÂŒ¼Ø¥úH#î‚,y±ö«¯¾,Xøo‘€$  H@ؽ˜O€$  H@µ`åÓGÑí &£ó¡Z»íÔË DâØ±cGÉÑLŠxàñQòÆî„->òÈ#ó›ãê8ÂÊZª#€ƒ{üøñáÏþìÏÂСCKÂáþÚk¯ ]Z¡”4¦Žûí·_˜2eJ8úè£K΂–UrÙÏ„+äJùB€$ &Àx›/_°}ú*Bã|„>„LˆçÔ‹ñ@>½!Û5ÃR"£vØa᪫®ŠÑ!ò"Ä8E÷¦úHuzÞk̘11ê ‘FRA¨²hÑ¢°qãÆ®H/ŽÿK@€$Љftâ]·Í€$  ÔEG\‘臡Zû¢¶‡V¶P!C†æ;Æ;lذìîñ93Ö¯_ßm»Êøâ¿FŽp6æ ¡ª·oßžßW,6{éVé^n ý }íœsÎ) çÍjLúìÂ… {yf“€$  H@ÍK[/?AOmôE=DÁØVØóÙÂäÿÞ{ïŠ&¼±ÑŠ„ŒòçÉžÓçÅ?üð0qâÄn‘ Ù›1cƒli…>’­o=Ïù,œwÞyFÙòÆo„¹sç5# Åç€$  t,…{ëm¸$  H@½%€Ó‰pÁLHg ¡…×®]›ÝÔç¬fÛ²eKÀ©•-¬F:öØc³›ºžSG"<äWΑSú™gžégq×ÅÛð áyÉ›œ/8_É+/­ÐGòu®ç5+5O=õÔpòÉ'—œ†ˆ"3HŸÃdAÑ„Aɾ€$  H@-B€ñ‚ˆ|aãl”‚ìy:ꨀ›·ÁH9G„‡¾J¹’­C»=gLÓ|aLf´BÉ·£ž×¤8<ýôÓõ²å‰'žÏ>ûlŒö☠KÆç€$  t…vÇm¯$  H@u@qÐAÅhÙ“áˆÛ´iSaj‹ì~µ>gr{ñâÅüÅ©àТ£GN›Jþ§:æÓo|üñÇÑ¡‹8£K–AÖŸ¨¬þBp‘-8³óÎqÞOü‰h’-ÍÔG²õª÷9ý‘DÍÈæZ§¿mݺ5æ–fÂ@[$  H@@; ¶vÞ>d‚þùçŸï–r¤Þ63 U\¶`sÕmÿý÷ÏnîzNÝH7—šA´Œ•+Wö‰€¤ëâ}ød Æ4‰´1ðÎÛµŒ òB—Vè#¼MŒ0.ÀöO…þöðÃÇþ ·ì{iÿK@€$ N  g´î²m”€$  H á<ðÀ! {b„¬b{ä‘G²›ëzþþûï‡5kÖDÇiöD¬Î#:Á!‡’Ý\òáÆ¤I“J¶ñâå—_ŽŽ±VË+£3ŸSÇ¢‰¾.Ü[®a|þóŸïæŒOui…>’êÚˆÿ8þ M˜0¡ätäYì±ÇâgƒÉ‹$  H@hL.1ì€(iöâüùó»‰(JvªñcŒ%K–t‹ G„„•ìaÆŒ ò…:" Í‹ òû5ãkìò|½aKôEÝI×Ç-/Áfl-­ÒG²u®÷9¢Œ3Ï<30Ê–åË—ÇÈð³H@€$ N% 0£Sï¼í–€$  H .¬’7n\7'(“Ћ- „®·|úé§qµÝþð‡QàèÂÉZi¢›»ãÇïæÑøôÓOÇ(õÖ±?'úB>_7ÎÏ¢Ò®Ì^zé¥n`V…9º¹~+ô‘FrÂñLT‘Y³f•ÜœæÏ=÷\ìo•úk#ëâ¹$  H@@ ZÅa‡ÖMÀ$ôêÕ«»¥¶èMzÌ™3'lÞ¼¹›-Êx ’P›ërÊ)aøðáÝR’Ê„ó’r®Õ cÆÙ˜ /ŒÈ¾ß¨çŒ òcÎ͘ 9.]¯úHªk#þcïÏœ93 †²¶?ãY¢f ’qƒE€$  t"…x×m³$  H@uØc=9›‰Z‘-LB¯_¿>üîw¿ o¾ùfö­šŸ³2î÷¿ÿ}Œ˜‘=˜¸8XÉo\©à#•Æi§Öm7°÷Þ{o ßo=…Õj„A¾îºëÂܹsë9UÇ–0¸Ù‚óµ(ÇsÚ‡•läø~ã7Ò¦^ýç^ÒÎ|áÚäõ.*­ÐGŠê]Ï6V*Ò/§NZrøÓ×!X*9±/$  H@ÀØo¿ýÂØ±c»Ù£LÜßrË-ÑŽ¯'B¶ì<íì·ß~»¤¥ˆ-ˆØ±Ï>û”lÏ¿ ’Ãé§ŸÞM¬Í¹‰j†qy=…ˆ|·ÞzkøÍo~Ó/BÆùˆØå•„¤DPÏý€c‚ü8HŒ Šã­ÐGê¹÷EÇ"B¬}ðÁ—¼ÍâRjr/,€$  H  (ÌèÄ»n›%  H@h¢œwÞyÝœ¡8b‰šqÓM7…]»vÕ|-œ¤D¸ñÆãy²é3púᄽä’KʦÐÈ^•[8Å)›-¬0Û°aC¼ùªóŽÍì¾EωæÁj1êøÿþßÿ ÷ßXµjUÑ® ÙÆõp€²R0[?àì,W üêW¿ ÿøÿî¸ãŽèŒ-·o¹í;.\–-[V²KÊÙ]i•b+ô‘’F5à<¦OŸ^²z“>#œ|ë H@€$Ð.XùöÙgRŠäE¤ ùõ¯mä¬=_mÛ@#š¸ýöÛ£Ý=• bØ‹/¾8sÌ1#è¥ý§L™ˆÜ€ýš-ˆ=î¹çžxÞDΠ]ØÉŒn¾ùæ0oÞ¼ºÑÙú=gܲiÓ¦n‚mÆŒ Ê• „ý× ×^{m¯Sj…6æ…,ˆá‡Z1£UúH9n½ÙN›'OžÛÙ("2ø\(Ìè U‘€$  H ”&¾k‡Ù H@€$ÐOöÜsÏèàÄ‹Ã4[pÖ!V Dð…^WÒåµÙýÓsV=ùä“á®»î 7nì&—UGˆAÈ%]MÁ99räÈ(äøÅ/~pð¦‚#uÍš5í¬\š={vŒR)´,‚¢<ú裱žHˆ†€s¸(¤oºVOÿI‚è‚·£GîæÔÄiÌê´¼”{@øèr…ãŒlÙ²%Š]ˆÚ@ÎcR¼T:Žó!AXCÈ]DÙh0"bʹçž[ÑÞ }¤»Þn§ŸwÜq1„1úT˜LèͤD:Þÿ€$  H  Ľ袋¢x" ÁÚµkÃÏ~ö³pÎ9çD¢éJ¶6íK"mK–,‰ã‰¼ˆ{–¨x{íµWUH-\~ùåá…^Ï>ûl¼F:ñ,‘ô;œþùÑN&B_¥‚]LºÄèëÖ­‹mO‘(òu­tž¢÷ˆÈä=bÆ>Ó³¦ˆ}óv%¶=¶w¹ÂØŠ1ðC°rüñÇwKO™?c ¢=q{6 ã-ƈ3ÊÝÛVè#ù6×ûš>G¿‡û¶mÛºN—¿o]oøD€$  t…p“m¢$  H@}Gç*' 8'SaRÁÑ(p,ßå‚ô#'œpBØÿýc” Ä ˆñꫯF§&"¦„Î:ü8ïED#¨Fä‘êBHÝ3Î8#:0Yu—u–â@E´À ¹+V„aÆŕMƒŽuä:Ô÷y%çω$‘Î…Ã4»*]»Úÿ´ŸðÇpÄ ‹£f¬êã=Ø’;]ó’ª'çI'Tö2ÜŽáAv á\Ü Ònzè¡1'4÷…öâœf_RÒÞ>ùÈ'8~/»ì²x޲ÿ¿7Z¡ôÔ†Z߇%}! ýß" H@€Ú•v0¶+6&âêl =&¡±%±s`{2&À†eâ;!bblklá§žz*Š$˜ÌFøŒ=›-'N —^ziÀ^/'Ècc#θá†J&ÊyûwéÒ¥qrÄGÄzb‹3þ Žˆ»±Éy`'3`\ÀkÆ3©0È )Ò{ÕþGì0šqÀ„ ¢­OD6XbWÞwß}±žÙó¥T•R2€%BpD(´á íäža!/ìÄ6쇘ƒ{’ºS¢N›6­[ÅlýZ¥dë܈çãÆ‹ àO‹$  H@èt 3:½Ø~ H@€ê"€8€|ÂßøÆ7bè\œvÙ‚ã"+¿p摇%ŽE|Áƒý’C6/Èà|LîãHe[%‡cöÚé9[„W\qE¼.+âÒŠ6öÁŒ#˜Õg8ŽIÙÁj3êˆ'hzv¶(ô,Že"]ô¶àÐE‚CV¬HÃ!š®8$-ƒÉœµ\»\õÛÅ>°Ý¹sgtÄâÅñË>ˆd’#™ºp?X È5ó÷ƒëuÖY1òÇôTZ¡ôÔ†Zß§Í8¹-]wÝu%‚šZÏåþ€$  H Ù µ¶+â &¢SA €È»[û[›H ØÛIHŒ½Íä5ÂìѼ ƒó!|ýÊW¾£ÜOþgy¥ë±‘L+ô‘rìz»¦D{$ª b‹$  H@ètµYðNËöK@€$ 8îF8ÜHó‘wâèL«Ì NQvSšà¾ä’KâJ,Ľ)œ‡¼ÇW^ye\õv÷ÝwÇHÙsáh,'¼Èî—}Žó'(¢½õ”äèÄ ‹C¸RẤ™:ujÅ•‚Zp`ã\Φ"AŒÂëì6®‡£:Õ£èú¬dE÷ƒçÕ–Vè#Õ¶¥Úý!±z”h'ˆ},€$  H  iqãÒàaÏfíÊ1v­%Ù œQx%B¥ssÒw !-6r~Ü‚(qH6òG¥sòð3gΌ尿ë)‰ÂÄ,yqvþÜ\ûœ¨•ʤI“¢MŠýŸ^3N¢~@IDAT#zF¶ô4&`_R÷!’áµ"™Vè#YxRï0®¥O5âÚžC€$  4…ÍvG¬$  H@-IçèÈ‘#÷¿ýí®••]kÖ¬)Éß\KÃpâ¸#4.Ž,DµŠ®…8ƒÐÄ¤à —2!‚‰ð¢Ö‚0‚(3f̈ÂÄõÔç0ç#ŠEO…•lcÇŽ _ýêWcèJû³Ò:â '} «áòÎçìñÉœÝÆs¾\“)ýI~Ÿž^·Bé© µ¼O¦ß’s•ˆ;vìèv8LjÓí$n€$  H@MB€¨ ³gÏŽ©ùæÍ›.\X×d4þãÇ6(BpÆÕŠÊ!Á.&êéTHÛǸ…ˆuGj-ØåÔQõ#E cŽz cƤq驤¨€¤w¡.•ÊÑG~ðƒ„‡z(,X° F1)gû—ÛÎù‡=2"™ž®›¯S+ô‘|ëy@ÏÑbHçCÔ•|a<Ð[±Qþ\¾–€$  H@ÍL@aF3ßë& H@@Cà$ÒN³äbÎÈFœ¤ä&f•" „¤ä`%“ÒEá~³×g"›Ð¿ˆ&plžtÒI"uGшÂy¨+ƆïN51}úô°bÅŠ^–PÁ¬+W`Ʊ'Ÿ|r|œp Qèшú±Â\Ù¬^ƒYQºøç¡«aÝ“ã7Ã*:Vk‘*…üÙ„ÓE,]-—o7Ç"6á^&g3õÄQÜÛÒ¬}„ÏNâTh;¢–zCQsÞSO=5|ë[ß wÞygX¿~}×ç,mD= H@€$Ð׈æ•Rå%¶Ç,ØO¤ô2dH8ýôÓêU«â¸€‰é|´¶¢ë2AÍä²¹*£4Î…¨¡Ç¸qãºêHjC¢T& XæXÆ*Ôqøî1‰Z ù:¥×ØíD™;wnC¥{•Þç?c®MÔ>êϽÅ~­TàÊx€ñ ÂwÆ@Œ;H±Áõ*µ™ci#‘ø¸§´[¶·c´fí#Œ¸)ª Ÿ ÆzõŠ&`÷µ¯}-~þHåCšÊÄ›~tÊ)§Ä÷*Ý?ß“€$  H@í@à3» OÛ¡!¶A€$ ÈÇ{õÕWWDS䦛nª¸O»½‰¹ƒtÆ 1. œ²3p*öEášä/ÆéDîbî áŒqr±ú+åeƱ™œÄ8 ‰hCŒmÀŒzrŸ¸ö1ÇEÚˆ_z#á\Øÿ´“63& Õ ØÎû´þ­J›aÆ£5S¡òIéc`Àçƒ{_︦)µ'ŒÈ§Ï ‚ûÞÜÇ|ßiÖ׌T*ŒX$  H@hoFÌhïûkë$  H@ØMG&ÎNÂ즈8–íDÌÂæš8ïx ¶@‚S¬þ›ԇ ñ¾t¼fëÈs`8yP'øP?Ò}ð:ÕÿÔ¯/™QV‹•SÔ…:Àƒëò>ÎØzœ‚IpD9ˆ²íåÜ\8ÿétͳo¦>B{aÀæpàž7ª/"âÁN7çåQϽÌóôµ$  H@¨D{‡èØ<ØáØ"ؘ²wŠ®Í5™ÔçAŠ7l\&ⱇÒ{3kscïö¥ š¯'×bžB¢J0à‘ì6öIcÚÔ—Ì8wp¯CÁ ÁFªc¬zÆ%œ±î ý‚ö¦{ÃµÒøƒñC#íâ<ÿfê#,€ ã ín”½s„ö<Òù¹Û-€$  H S(Ìè”;m;%  H@ˆ˜lˆ’™qíj¯‰SŒ ô.ÔÇp_®ƒ`§YJ3ô‘4)ЗL¸†E€$  z&ôë©3܈.x4kAÁxi ÆLY.Ô¥?xõ×u²m+÷¼úc$}Yúúü}YwÏ- H@€ê!ИdåõÔÀc%  H@€$  H@€$  H@€$  H@@›P˜Ñ¦7ÖfI@€$  H@€$  H@€$  H@€$0ðf ü=°€$  H@€$  H@€$  H@€$  ´)…mzcm–$  H@€$  H@€$  H@€$  H@O@aÆÀßk  H@€$  H@€$  H@€$  H@@›P˜Ñ¦7ÖfI@€$  H@€$  H@€$  H@€$0ðf ü=°€$  H@€$  H@€$  H@€$  ´)…mzcm–$  H@€$  H@€$  H@€$  H@O@aÆÀßk  H@€$  H@€$  H@€$  H@@›P˜Ñ¦7ÖfI@€$  H@€$  H@€$  H@€$0ðf ü=°€$  H@€$  H@€$  H@€$  ´)…mzcm–$  H@€$  H@€$  H@€$  H@O@aÆÀßk  H@€$  H@€$  H@€$  H@@›P˜Ñ¦7ÖfI@€$  H@€$  H@€$  H@€$0ðf ü=°€$  H@€$  H@€$  H@€$  ´)…mzcm–$  H@€$  H@€$  H@€$  H@O@aÆÀßk  H@€$  H@€$  H@€$  H@@›P˜Ñ¦7ÖfI@€$  H@€$  H@€$  H@€$0ðf ü=°€$  H@€$  H@€$  H@€$  ´)…mzcm–$  H@€$  H@€$  H@€$  H@O@aÆÀßk  H@€$  H@€$  H@€$  H@@›P˜Ñ¦7ÖfI@€$  H@€$  H@€$  H@€$0ðf ü=°€$  H@€$  H@€$  H@€$  ´)…mzcm–$  H@€$  H@€$  H@€$  H@O@aÆÀßk  H@€$  H@€$  H@€$  H@@›ø|›¶ËfI@€$P†Àk¯½~üã—y×Í€$Ð(ï¼óN£Nåy$  H@ %pÿý÷‡+V4ôœžL€ºظqc÷n‘€$  H # (ÌèÈÛn£%  H “ |ôÑGaåÊ•ŒÀ¶K@€$  H £ ìØ±#ð°H@€$  H@@ÿ0•Iÿpö*€$  H@€$  H@€$  H@€$  t …xÓm²$  H@€$  H@€$  H@€$  H@ýC@aFÿpö*€$  H@€$  H@€$  H@€$  t …xÓm²$  H@€$  H@€$  H@€$  H@ýC@aFÿpö*€$  H@€$  H@€$  H@€$  t …xÓm²$  H@€$  H@€$  H@€$  H@ýC@aFÿpö*€$  H@€$  H@€$  H@€$  t Ïw`›m²$  H £ xàáïÿþï;š—€$Ð6nÜ~úÓŸöÇ¥¼†$  H &çw^àa‘€$ ¾%Àx€qE€$  (̰H@€:ŒÀ{ìÆŒÓa­¶¹€$  H@@"pøá‡;&H0ü/ H  ìµ×^}xvO- H@@+0•I+Ý-ë* H@€$  H@€$  H@€$  H@@KP˜ÑR·ËÊJ@€$  H@€$  H@€$  H@€$ÐJf´Òݲ®€$  H@€$  H@€$  H@€$  ´…-u»¬¬$  H@€$  H@€$  H@€$  H@­D@aF+Ý-ë* H@€$  H@€$  H@€$  H@@KP˜ÑR·ËÊJ@€$  H@€$  H@€$  H@€$ÐJf´Òݲ®€$  t$?þ8ð°H@€$  H@Iàþçâ˜àÓO?íL¶Z€$  H@-Nàó-^«/ H@€ÚŠÀG}žþù°råʰsçÎðòË/‡×_=|ö³Ÿ ûì³O>|x=zt8å”S¾ð…¶j»‘€$  H@€þ—Ào¼ÇÏ=÷\0.øðÃãàðÃÇw\˜4iR8äCÂg>ó±I@€$  H@MN@aF“ß «' H@@çx뭷¼yóœ9sÂ+¯¼Þÿýè|ÅKÙc=¢svùòåáâ‹/³gÏî8¶T€$  H@Bà™gž wÞygX»vmøãÿ>øàƒ86 ZÆç>÷¹(ÎX²dIؼys¸úê«Ãa‡Ö!dl¦$  H@€Z—€ÂŒÖ½wÖ\€$ 6"°cÇŽpÓM7…Ç{,ìÚµ+|òÉ'ÝZG47ß|3ðõêÕ 3ºrƒ$  H@€Z›Àý÷ßî½÷Þ°iÓ¦ðÞ{ïuk )MØÎÁö\ 0£%7H@€$  H ù(Ìh¾{b$  H@è08UW¬X~øá¸"®§æ'glOûù¾$  H@€$Ð:Hiøàƒ†uëÖ…?þ¸ÇŠ3Ž`l`‘€$  H@€šŸ€ÂŒæ¿GÖP€$ 6'@Ú’ùóçwetÐAaÊ”)á¨£Ž ƒ ¯¿þzذaC ÏôØæTlž$  H@€:‹À£>¶lÙR"Êøìg?ÆN:é¤pÈ!‡ÄèyÛ¶m «V­ _úÒ—bZ“΢dk%  H@€$Кf´æ}³Ö€$  ´ ÷ß?æŽ~úé§KZ4xðàpÍ5ׄSO=5Š2È%M “·ß~;¼óÎ;aß}÷-Ù߀$  H@@ëؾ}{xòÉ'cêÂl+.¼ðÂpþùçÆ_üâcÊÃwß}7¦0A´Áv‹$  H@€$Ðüf4ÿ=²†€$  ´1·Þz+<óÌ3%ù£÷ÜsÏ0jÔ¨0}úô(ÊHÍgEœ‚ŒD£øÿ«¯¾zè¡€cû“O> ûï¿7n\¸áV H@€$  <µk׆;wF6ÕÑÅÌ™3ÃñÇj§²×^{ÅèéµÿÿDàÓO? ‹- «W¯Ž¢öÏþóáØc Ó¦M‹cƒ?íé3 H@€$  ô/…ýËÛ«I@€$ ¬v{á…J¶í·ß~a̘1%¢Œ’|QH€üÚ„~¾å–[‘Hf°ª7‘G,€$  H@hVŒ d bmÄYQFö}Ÿw'Ã9sæ„•+WƈƒDY²dI· Ú¶H@€$  H` (Ì(ò^W€$  ì&ðÁ„—_~¹„‘1† R²Í=`u‚Œ×^{­kg^ïÚµ«ëµO$  H@€$ÐŒ06ÈÆŒ ,Õ@¬ýúë¯Çhé(Æy¶é=ÿK@€$  H ¿|¶¿.äu$  H@€ºÀq˜_G¸Ý}öÙ§ûÎn‘€$  H@€Ú’cÆÙ˜€±E€$  H@h} 3ZÿÚ H@€Z˜ÎWVpe ¡Š ”Ýäs H@€$  H  0&È 3˜Æ¤oºM“€$  H@è( 3:êvÛX H@€šé7òXò »2®Ùî”õ‘€$  H@@ß`LÀØ [06°H@€$  H@­O@˾õï¡-€$  H Å ä°4ç3ŸùL‹·ÊêK@€$  H@ÕpLP-)÷“€$  H@@k0IakÞ7k- H@@ øä“O›o¾^yå•®ÕpÏ?ÿ|×óÔ$ÂoÙ²%ìÚµ+mŠÿ c¼ß~û…C9¤d{¥üãã¹6mÚÞxãÀkÎϹöÞ{ï°ï¾û†#<2Œ1"zè¡}"é«:°ª6½úê«ÁÇ^zé¥n8Þ{ï½ðì³ÏvÛΆ=öØ#|ðÁ‘Cṯ¿þzX»vmxî¹çÂÛo¿ÞyçÈn¯½ö ûï¿d:räÈpÐAœ¡ºMÔ›ûÆù©'÷gèС%ÓŸV®\ÛÇsVUÒ?N<ñÄøøÒ—¾T²¿/$  H@€žöøÎ;KR¾ûî»Ý*¶cÇŽ°~ýúh fßÄÆ;üðÃþð…ìæÂçØÌœ{øå—_o½õV`Ó’*…öã±Ç†öÜsÏÂóÔ³±/ë7X~øá‡±ŠØÐ<ò…qW¹¶a¿c·×µðƒ>›7o6lˆc7Ø~ôÑGá‹_übØgŸ}â8ƒ16|5÷*_g^SoîçåœÜ§¬[Æ Œ ¶oß÷cœÇ½3fL8ì°ÃŒºRÖm€$  H`(Ìè^R€$ Î$€Ãð7¿ùMX·n]€¢\Ò8Ô®½öÚnŽAÂ# øþ÷¿]'É=Á9÷â‹/†¹sç†Õ«WG'!œyô!ÚC»ùð~Z˜öÃ!KýX]i‘€$  H@h>Øiˆµ±Û*ìÁr…{Dc :B¾,_¾<Ì™3'ÚöDáÃ~ì©`ï"hF°dÉ’h»ž~úé1¢FOǽß_u@ˆŽ½Ä&Euaãr!œÿð¼\a\…жD A ÑÓX ®D½`<‚€âª«®Š‚øJ×I×GLø0 ÑÙNôEÚŠøä¦›n >úhŒæ—õp¿+±ñƒE€$  H 9(ÌhŽû`-$  H@èˆê]uÆñD»(*8çn½õÖ(ÊÀIˆˆ£–‚cÇÎ>ˆW_}u\eUË9ú³°¨Æ¡Y©þ8+Sô¢ýx'îoûÛ¸ÑIµ%9B׬Y½8E‰`Qä<ÏŸ“cyd ¯à|þå/ïU9G0÷>EÐÈžÃç€$  H@O ãlØüØÛHD‘ Ò[5‚Œ, Žg Q¶ïÙgŸ]SÚ¿þ®ã<‡l›ª}Îyʳ8bˆûï¿?ÜsÏ=Q]‹­šq§mõÔS%Q`ïe 6j‘èÛ~èСѮÏî½yÛm·E?A‚(qD„8íVö?ŽSVbáðËŠ28'Ô¯|å+Ç/"üu8)]œ¬º#Gq6zNÚeË–E1Áyç×tuHDhY©Â8Zq$×R8áŸášœ¨ÃõÜsÏ —\rI8üðû9§irÈ!1ª Bœ›o¾9®ŠãXœ¸D¼˜;wn¸æškØTS¡ˆ.’³œûKº™ÓN;-Þ_xàèÅy@„~d‘€$  H@h>Ø”<²¥(ÝÿLºcçU*ˆ¤Sú’¬p€ñÂ…‹/¾8sÌ1eσ]‰è™HqO?ýt‰`„sæÌ‰¶/öo¹2Pu@ÜZS¼:ÓþZLJð¶ØáY¶cÇŽi ±½ó÷.Ùá‡zh0. Âo ã,"‹0æã×RiSÆ‘ˆ@Î?ÿüÀXóP7ô„Œÿ²lj¹ŽûJ@€$  4ž€±ÌÏÔ3J@€$ ~#€‚US„ÈÍœ«„DZ;ì0¢‹"Qû³z ![Ä8 ³…t'œŸ‰þr¥êP®n½ÝÎ ´Å‹Ç(é8ĉBqå•WF1 ŽÐrgð¸q㢈ƒpÆ©àŒ%õÊÖ­[Ó¦ªÿã|M¢ çˆn¸¿8|“³žÿÜo@ùˆ+U_¨ÍwÄYMhnœãÙ×mÞl›' H@èWLŽcKi Eúê× tØÅ°/‰@”†T°ÿ/»ì²h3A.Ù‹éýììU¢>0~@pÝ÷’ˆlYaBöxž7CòujÄë+VD!|–-bØN˜0¡›(#{MÆ ¤ŽA3|wº“lZî iÔR¤¨*³fÍŠõ 5i¹ç\a"Æ ˆs,€$  H@ÍA@aFsÜk! H@€j&€CAÆã?^âðF0~üø0qâÄŠŽÂtAxLⓞƒ0ÇÙBHà^x!®œËnOÏ›¡©.úŸÚD “äôäÜXfÏž…Õ\+9¸I3’ 8µq\÷¶ ¼`UÜÌ™3 Wöö¼r¢V}þêW¿ ?ùÉObXê¢H+ÂÃvJ@€I€If&ñIÕ÷ÿññ7[ÒÒwˆ˜sÒÞe i-¦M›#äU§cHo‚€Áv^¬Ðfùòå]Ò1é3Ô!Õ¥‘ÿ -Z´¨ÛéÓ§GÁ6é «)ˆ3ˆbˆŸ ÂwRšd#¦÷ªù(„ԊÆ ëůšãÝG€$  H ÿ (Ìèæ^Q€$  4„“ɬ´Ê;aIræ™g†l¤†j.Èq¤ÅÈ;‰ò@¾è¢Ò u(ªW=Û˜PX¿~} ZH*¬ÄQ´–’˜fÁ KHèÞî !˜/¼ðªD7½¹F;ƒÐ†h=ôP5á O TŒ ÓÎ\l›$  H ^|ðA ²ÀÏ~ö³ðóŸÿ<¦ÂCñä“OƨY±k½×òøR¤Ø ÷ [E/¥!û~ÑsˆŠ‰¶=ŽûÇxFQi†:Õ«ÞmØì¤"ÌFËÀ¾Ÿ2eJ‰È¢§ëÀ’qV>­ç¯™°ÜyŒ“ZqĈAE€$  H 5h¹µÆ}²–€$  H òoذ¡$Z÷E\k!ÌíQGs?õÔS]‡¿óÎ;!å2ί¶k†:tU´AO›äsH˜ðÃEùª+]q +ä²§ù®]»²›ªzNdœëW\qEÀ!l© IóBÄ‘‡~8FƒÙ¾}{7qÏIÛCHh"ÎdCx×~%€$  t" `Î;7 3ˆæ–R3n ±0v)¿Á–¾!„ÔÙB Òêí»ï¾ÙÍU='’ÞèÑ£ÃæÍ›KÎËx œ0£êPUãjÜ û0Ï–ñˆü¸¨§S3&È çä5=‡ë’±¶öjO´|_€$  4…Íu?¬$  H@¨šNoVÇeËÞ{ï…_úÒ—²›«~Ž#'_V˜Aã×_=>ò‚€f¨CÕ«rG„(y®ð2dH•gøÓn¬ŽãX„i’‚Ü܈?¸N-BD7ÇsLÎ8¹ñ'Ƶ>K9ÁÇŒ–,YæÏŸ£gIƒè37nŒHgŸ}vü,¸ ±VÂî/ H@@{{ ¡#).HÕ†mCd~kI‘‡(Á0ö¥¥ïp’™®rì±ÇFñ@6êEz¯§ÿØ™ŒæÍ›W"JàþQŽ´%yA@3Ô¡§võæ}ÚE»³…1AoÆZ0c¬†°‚Ï…hˆ]x]­ÐQÈØ±c{%ºÉ¶Ãç€$  H@ýO@aFÿ3÷Š€$  H !˜ÜÇ ž-LÞ³:±·…ãqöå á{Éœf4Còu­÷5mÍse’§éÊ•+k>=áášu˜s Ä.µ3’È#ﯹB~÷Ûo¿8á0tèИž†H<òHìã8àwîÜž}öÙ¸yÖO8ᄪåŽ×æK@@›øä“ObZ0R€!pD؈„­Dt¢NÍœ93þv"Ð "›¥ï0¡ÝšO‡Áxû³·…ñ@þxî=ã¼0£êÐÛvötl³iLØŸö!䥗^êéðnï#xÇå˜2&€iµbî ‘7z#ºéV!7H@€$  ô+…ýŠÛ‹I@€$ ÆÀ™ÇD>ô-“öõ¬JÄyΤu¾àD̯k†:äëÙˆ×0Ep’-„þýïßmu`vŸrÏ9)_²…°ß8aIMb¬JdˆþNHjVö2ÉôØcÅ &ÂwŽ}íÚµè4X}j´’¹_^U€– „‹üñ€‘L,ŒßJ¤-AÈ›ŸÔØÚ·ïÕ 0&à>d ãzļØGE¢ÆŒ ²¥ê­O£žÃ”1v{¶ HZ½zu¯D»DgËócLÀ5ªfdëâs H@€$ Ö" 0£µî—µ•€$  H@‘@Eäqà@=à€ò›«~MÚ¢8°+ëàåzù•xÍP‡ªV厴!mËœ¥Û·oÏnªë9¢&1,O€{ÁªRDÆ gœqF˜;wn\ÌäÃúõëãŠHð&L³fÍ DÚ°H@€:…“É‹/D˜B¸ÈD2¶â „ü6Ž5*vØaq%§pi†v"ÊÈÛ­Ô‹ñ@‘°¢Ú:3(v0È_¯êPm»jÙ1A^”ÁñD áѨ˜ Ú4&º¦ç‘€$  H@ 3†»W•€$  H@uÀ!š«Ë “°¢·''NXÙó³J2ï„m†:ô¶åŽ£M8aû²à$£d Td2šÕþØ2¤ù:묳¸qãÂᇮàt€:özÞF§*+°mz[8áM‘X›qA¶4C²õiÔó"±v£ÎÎCd“áÇ-#ñ¿$  H@hs½·Ðی͓€$  H@ÍN (¯pŠøÐÛºãheeX~u×* IÝ uèm[‹ŽC˜RÔ&œ¦'N¬+M ×c5á½GíŠÒ¢ÐÛ%!šá>‘ºdÍš51‚ÆÊ•+cÈv"glÛ¶-,]º4œyæ™QÀAv‹$  H ]¾aÅŠaþüùñwAƇ~í~dEêˆ#ŽˆÓ| Ü/²[© ¢‚lô»ZkˆØƒ{ž?GkdÏ× uÈÖ§QÏiWQßFŒ„˜¢žˆ$ÔqÏ=÷ Ç|9•cب¶x H@€$ æ  0£9€$  H@5`‚g^¾ ¨ ßwo£1° g|~嫿òy›¡ùö×ûš6åÛÉ9÷ÙgŸ8 â‰'Öu‰‘„UŒ–æ&ÀÄ©MHsª`=ôPן3?þx˜6mZL‚€Ç" H@hU¤©à÷Ž”^Ï<óLxùå—ã?ö i¼¦OŸ£FuÔQÑ6*š´nÕ¶·j½`¿æ v ã‚¢ñB~ߢ׌Š¢Èa'ç#q4CŠÚPï6ÚZÄ»pöìÙaß}÷­ëœ{ï½÷îÆ³®“z°$  H@@SP˜ÑÔ·ÇÊI@€$ bå8`q¤ö¶p,^¼8ÞdÒ¤IÑÉÞY”l­$  ´2"#²‹ß·U«V…;wD~ÿ Nž<9 ±]ÝßñlÁÉj®|º†f¨C¶žzŽö€ˆ«DÓ9‹¸¤÷üßþø ðY1bDmL ‰”aÍgb̘1á‰'žˆZ/¾øbؾ}{hlÞ¼9,\¸0N^´1ަj“GD.Y¹re\éMø}Vû²ª› «á»sÁ=:œrÊ)q‚¥Rå»=ûì³ñÁªq"£°òǘ DxÃ9ë}Tª‡ïµûMkÝ/kÂsÏ=n¸á†ðä“O~ÃøžÃ^"-×ĉcÚ‰|ïù]×¼=†ß9ÆØëITCm׬YÓvØa½ª<ãÆÙBô„ yN3Ô![Ï¢çiã;”Ik¢£?>̘1#¦îBÁwž¥ù 0À~Í 3ˆ~BÚµ£Ž:ªj8µaãŠ+¢°#mã?ãÆE¥êêÅï~^Mç7¨"yaI:®è?cØf# 2öBÌ„H·hìQt·I@€$  H 3ì€$  H E ¤‰á¹sçvµ§#+¼—.]Z³0ƒÇLFfºœ˜PÖåÒ24CRãq²²ZI„4!Ë{8`iSQÄtlö?Ç|IHh&eYYºxñâpþùçgw÷y@ ÁÊQ>LHœvÚi1RéL˜Ô`ÀÒ·H#sÓM7…Ç{,Fµùä“Oº]ÑÙ›o¾C²¯^½º¬0ã©§ž ·ß~{q¤‰ÊìÉø~e…,„Üo¢¦X:›€ý¦üýç·˜( <Þ~ûíøÈ÷&“œ<øîDÀVË$iù«õîl¾«ùÌSO ÏÔ ›‚ú¶k¡Íì#¢ uÖYáä“OŽ©ëò©*Ú•A»´ ¡(}Qh*üö ñ(‚Z ãDÞÙÔ(|N`÷•f¨Cªý—~8ƒßîTÔ*Ì`L@„©ð]Ad4"hEÄ" H@€$ j (̨–”ûI@€$ &#ÀdFJ©u²¢‹•û#GŽŒ+ú«©6!Ø™\Bx-LNà¤/çtl†:dë‹#a"“ThÎe&ÕÎqôÑGÂw“Î ÎÉ„û¤I“bXï´Ýÿ`²â ƒŠŽûaÆÅ>òÈ#ÄÏ“‘–¾!@„ Vô>üðÃ]ª•®Äd ÇÂ’/Z´(¦¦©FP“ÈQt>·uþê7ô[~Ÿ‰ÖR$>ê Ú'¦L™'u«=?Ÿ1&†ùíDEô &B™ FàÈûL”’ƒ+Í9ä¸ ÿÄO ÇsLœ\®öz½Ù~çÖ­[ë¸eË–’:R?¾Ó©²¨³<°#ò«ð{S‡f9!+ÜdꉔÕŠX›¥ Öã %šãìï¿‘Iqˆp£šÂç–ßÕ¬-ÍqØÅ\£œh§êÚ‡ ŠñŸã¬X›ñã‚Z"ÁðÅX.I¼Åu³O:5ÚFÍHäý/ H@€$Ð…=ò} H@€$Ф˜@01yòäpë­·vÕ’É&E~ùË_†«¯¾ºl´‹t+É|ðÁpÇwÄÉŠ´ó“WùœsÎ)»šµêêËÿ4‘’u&#TÁ1=vìØª&Th“gœqF‰0ƒ‰¥U«V…ÿú¯ÿ —_~yœ¤É^»Òs&‚¨ALøpÏ,íG€‰ÆC=4 wÒdÞOúÓökh“´è•W^ óçÏ/™(¡jˆd˜P&|;â1&a7lØ£Þš¿¨ªqZV”Áw÷‘Â|×òÙeÒ™hL63écélýÕo¶oß…?þxÉêᄂÏ÷°LÄöÔ×\ÚŸÉ\>|æˆÆÀhOB&HI5„”Ï, 6ŒUóLÊòMÀ÷Gª#õ/*ØO?ýtœÐæ»;Û^;DÒ˜±;eÉUW]#˜1p[kàsÄïvjV¬8”1â„ .¸ l´‹ÔJŽ¿ùæ›c¿Ï 8?ãú ¿E¥ê­ß!yaŸýéÓ§×ôýÂo?ßKDÉ 3_Üpà 1ЙgžÙã÷d¶nDÞÂ.á»}„ ¾³p|. H@€Úœ€ÂŒ6¿Á6O€$ ö&@8aœLd£;àðùÊ$#9¦ ¹Ø [p¸â$ áx™¤ÈVˆwÞyaøîÜÊ•J3Ô!Õ°ã87oÞœ6E‡)íc;“¬eæÕW_íJàpÍ&ˆ&Nœ'op⦂C–h$¤‹9ûì³Ãé§Ÿ£$à´Í®‘ÄÏ<óL`ÕÕLô2¼§‰®üù|Ý:˜Ð¤¿⺧Âg•tå¢Òôt|§¾ÏwŸ)¾û²î×\sMS¤ ˆª˜œBLQ´b˜Id&†Y ›-ãÇW^yeañÝÂd÷‹É)ÎYmžì9}Þ>ú³ßй^v%|D¸Ég­Òï‹ØDô@øÀïd6u@OõÄá·’ö V¢c‚¡+ÑaGýæÍ›Ï £'Áõæs´ÛbÙ²e1ÂÄ´iÓâïOíˆ÷ù®CÓSI¿Så&Ú{:Þ÷›‹ŸìÒ9sæ”’¦ tæÌ™ñ7-õ‚1ÂŽEDœeÐJÆŒ%ˆ¤S©4CRýèßüvóyHeýúõá¶Ûn‹¿íÁ°ßù^e;‚Daˆ;ó…ˆ9|æcðHeÓ¦MQœÁƈ¶ÊEá:[·n|±9ø¾dì lG‹$  H@@ûÐêkÿ{l %  H@hc8 -|Ùe—…ÿüÏÿŒ“©¹8Uq®âÅÑÊ$"“’8cqR2 ‚ÀGmÊ3žŽ%—2¡­2ô4)Ò uHõÆ™ŠSšUÅi,“/Û¶m ×_}xà"ƒ$š`²…ÉsD¬ôK…•°RàÊd œRÁ‰Êd0Ûï½÷Þ8a…è…Õ´œƒ 4&¦˜â8žs4YÅ=à•&ºÒµüßÚª™ìzî¹çÂO~ò“¸§¹ˆ­M¢ñµç; ÁŸ¥T˜€5jT\ ‹(#&IŠé}&cHgˆb¢„ &K²Xœ1Z'~OønEÔÆw$“^0BlÖ‰¥?û v1iÇ5ËÙˆ/èDÛZºtiœ¬¬FìP©¯ðD¨ÆÄ'ÿùídB˜Ïvo b{î¹'Š2˜|&ªXo v¿ë|÷P7þ_tÑEM%Î@DCÄ"—0ÉÞSá7ªšß©žÎãûÍAÑÄ%—\£C1ñ°(lý‡z(F†Bx­™}èËŒø|°_þ3‚˜˜óqÄ=ö—f¨Cj3¿Oˆ±ï$±Ÿ‘ù»£æ fg\„ÝNû“ð6òŸˆÃwÐ…^Ùò;ˆH“ÂwßDDÈmÏy0–‚oÀ˜ï´ôH÷‡ë×ûÝ™Úì H@€$ æ' 0£ùï‘5”€$  H@ 0QˆÕ‘7ÝtSIä œ«ÉÙš&Xp62ÁÀH/d/€C,ÈJ“™Ùcš¡ÔÇ)ùÒÉMÄTòpÐ&Ç3Îižg…Çd,“²ßúÖ·"W&ÐSaD<àÉuÙŸç8ZyŸGv¢7Ë}(·š.íãÿÎ!€°€¬œÄÙ?c·ŠpäÕ~ö:‡TiKù¾ƒY¶0 2f̘˜¾$»½§ç ˜ŒÊ–¡C‡FÑVV”‘}¿Óž3 ÅäûwÞÙ5!Å÷>|:U˜ÑŸý†´b„»ç7»š <î¿OL6f ‘yòѳ²ïgŸsG]("¤«W¯Ž)ˆ Q¾ÁêñN8!0Ìw¿•LŒ2 ?V©#ŠJ“œéúìCD¯ßþö·qÿY³fÕü¹æ\DÁ¡ÏÑãÿ³w§ÑrUeâÿ·ÓdB d$$!2’„)È ‚ØJ+.t­vµÝÚíêv¿ðM¯~ÑjkÛ´ÊBA¦I!d‚„Œ„„ „‰ŒA@i¤ÿùn{ßÿ®s«î­ª[usoê»×ªTݪsö9çsNUÎÙû9ÏÎïrOË!(NTŽa\èTåÿn:rÓ¹¿ ùÿåìl |à\ƒáMövἃŽf¶“ÿOè(΃Öööú¹üî8æ˜cÂ_ÿõ_Ç, ùw‹Àa|/¸â|”óaŽoŽû¼¯-Ë—_~y6lXÕÁa=aØÖƒ¡È¤&"%ø}᷇߀|ÛùÞ”s`^~ÇÈÈ…xòß=~ÓxP¸žà·c~+©Ÿï(û¢X7× \ðlQ@P@h 3Zc?»• ( € (° Ð!I ]îòæîUî˜Ìƒ.h¤QG¥BC"cÉs( ±µÞ¹ßÖVîv#°„N˜âÐÉ!0=G•:_é¤án]¶Îî†Ë;h¨‡FWgóÚTþLf‘{²pž/‹I€ï*€tôØcÅtãÜíÙYÚðTG«=ÓÁY^èÜ #¦ÖBgJÞiÃüüþÕúXër{ÓôüÎÑ™•wnÓyN'_«–îóëA€ ÛÌ÷ÔÒº|_ †úÒ—¾³º1üçyá¸É¯òÏÒkþÿ#sAQ.ƒ—Ótåž{Â:°^¬Cñ{¸hÑ¢vçéüÆä…ï?•‚$¸f8p`¸zOÀ6£È@BVñ7™ß¶âµB¾œô:]cP'¿P@P@Öð̯5ö³[©€ ( €=T€†N:>HL¡‘ÔÂ4 ÖRh,¤óƒ;í3™Ætî2V{gô4 r')Ü‘K`C==a0£s–Î'‚)î½÷ÞèP®”†W:qé˜Á½RIL4ÂÒµpá°~ýúv Ýåæ§‘O^¸“ŸŽ þ®Ôè›ê –ýÉsj8NÇJšÆç}C€ï+¤ž'(ƒ:Q¸““ï0#|/+í µoJÅ`(¾/ü~ÖZè|-þFðlf›Z%[kúîµ,;ÕÛÖua{È Âo C‘=£Ü÷–ß*~È*ÄõL¥ÂoŒ.¾øâø=ã÷€ (¾ƒÅóˆruàIF.²‘q‡ß†a쨤ëBÖ+­{:N:šÏÏP@P@z¦€=s¿¸V ( € (Ð"¤ùþÖ·¾K造3FÄz;™È!ñN.céॱÎÞ·Þz+>hÔ#ƒ†>Rx³4 ÒaC0@WKOX±I/N0ŹçžS¦§ŒthÐqA€ ×xwVh$§ñ”Tç4XãŠiê ¡C„ÆnviDÇ–» YË›çj^0¤Qœý“îHg~ö•eßà{G†wè`£ã»žwìØÛgŸ}6ÞMNF¦!ØÇâݾÅNa:‚ªýŽå†éîýü=¾Ë|ï- ThÅã†ÿçÈ @±8TÿŸÒYIç&çunæ¦|Ïø˜Œ œû‰ƒ,©àL¶ ê§Ó´\ÀIš6=œ:OÐBqˆ"Ö‹À‘ .¸ ÖUM‡3¿œKðÿ1Á!Ì™3'þÖðûÝ…ó7Î=,XDZ!ƒó\ø?bÆŒ1„Nh3ºsï4fYŸûÜçâ>ä¼’ïç’÷Vs¬æk@O£%pÌsnA2DQ?Áßœ£òÝ `€ïþ,—¯®”ž°¸q.ε×d¸ žk®‹8߯‰ók¼®¦àÃy9fyñ[Ã÷‘ëÎÛ9?aÿqN’®¹X®·Ò5æÕìWöÉW¿úÕ¸ÎÔ›~3yߢ€ ( € (Ðûºv–Ýû¶×5V@P@z”#GŽŒi½ip§³«¯4ÒèǃCRÓG‡ Á,‡ÆV–Cƒ,’,·‘¥'¬ÛHg ¡4>c@Û϶³Ý:aù-¦îj;Óò»úÌÿl™@Ø£s=ô¦ŒŽÒ±Ì¶XÖUñ½3?Á?¥ÿߨµ«ùšsÜyä‘ñApçœWæç­LÃs\ž]zÂ:pžÅƒ ® x`Àÿóœ¯@QëÿùLϹ:lùrÁƒýÇ~cÎK0H×µúr Ùuçw'ët帨uœ^P@P qµ·Z5nÙÖ¤€ ( € (°G€†µf5 S7õÜEÞ¨³·×å§ ŒFnû¬Yû-­'¯¬»eß`_§;0 Ð8í´Óâ]Ñt½þúë1½?Ž £Ã]Ñhp-óµjÉ;]“ß÷ZK¹z¨£žºj]¶Ó÷^V;nDa8¯uëÖ•2ÑéHáô:ƒ2ò#€à ~ûøË3°&aÆ 1ýG¿{L³zõêvà 0lCCÑé]ïw›ùz%3¥Þzòmîìõk¯½³)‘%ƒ`þ¦C™Ž^²w0Ä ÿ'CǺ¥÷ ðª'Ȱ³-ïŽóÖž¾|oxð=nd!ƒß¯f~kš}ÍѬu·^P@P@R3J=üKP@P@Øk4îsÇ3©ÄI«=qâÄ0OJþÅ‹Ç;É7mÚÓ‘¯]»6Œ;6vÊq§fO)Üí¾e˖؉J@ s‡.ÛEG©» <¡c“»x«éؤC˜»Ã¹cì7†™Jéú¹{™ýÆñ—¾Wx°«9þX7ê îf70hf|ÿžyæ™(–/‡ãŠÀŒj‡Èç-÷š¬0| Þ©ðšÀÔ˜¦\a‚G®!/|g ø ÓUGAù<½®ö¸é¨ŽÎ>ã»·bÅŠøûO  ÇÇ!ßë¡C‡Æá.ȰD I£;™;[7?W@P@P@¨OÀÀŒúÜœKP@P@hšwËuÔQ1€À‹É“'‡¹sç†åË—Ç`:Ãéø'½?¢Ü Þiõó 'e7ëÂú­Y³&v 2̈<øœÎP¶‰;UÉø÷ Ó¦M‹ã¾ó~¥BpÃ7Þ;\Ó4a¤Tïé=‚þó?ÿ³ÝÆ,›@k¯½6¼ýöÛáG?úQ\ß4läå‰'ž Û@'h^ø›l%çŸ~»LD0‚ÃÊ•+c6)u<õ`Àöï¿ÿþ±C•}Gð ÁµŒé¼f؆¼¡SšŠdNç1Ë#(åq<Ñ‘{úé§Ç»ë;ZÇÙoûÛ¸/™Ÿb`Û˰;dP(W̘={vú¡™Ù³8¸Äz²Ÿ XÁ‚ug¿% Ö‹ 2(`AFq?·gÕªUá®»îjÊqS\VOý[3òï ß-†õàѨ}ÌoÙ€øÝã÷-Ž7Žs¾c•3ÊáX`¿ç…úN>ùä^‘êwÞ oüŽ€G€ßk¬ Ö›1cF7n\ p#°«Qî¹—¯P@P@P@š#``Fs\­UP@P@è²ÉtB’y€ä)S¦„‡~8ÞIMG<ÜNý¤I“b C=üõ®(™%|ðÁ8ì Y ÈQ ˜(W7>¤ÌtàWÊüÁãtTRG…ÎK:nË:“ ð °Lî>ï¨mG¹B@ ŸåCD±/v桇ŠXç¼;¯‡i)l(¹ð «¬¡ƒš¬÷Ýw_<ÈdÀ¶wTèÜå8¡ãšÎîóÎ;/vîVJκaNPIG… ˆbÀFšžŽd:Ãé$¯´œ4m½ÏdH™3gN X"[Ú•ÜóeйÏñÇ÷†à :»;úÞPw3Ž›|zòkL9~Š™(ø]"cFGdêÙ.~ëÈ A Wþ{±ΣRáû_ü àØ#0ƒ †ž\øó½æ7„¡Xø½âûGàÿL:5q±xóý²( € ( € ( € ô.3z×þrmP@P@P è\ìׯ_.€K:‰ Рóœà:òèL_ºtiÌ@†C=´©RtVßvÛm1(ãÕW_­ªC<_!:ÑéD¥£•á>®¸âŠ˜Å Ÿ†×tLvõ®pæ§#“ †®ÖE=ydfX´hQ¸õÖ[cÇ5WS˜Žm§ó™LÕd<¡ƒœ`‚Ûo¿=îs²fT[èà& …lì/²JÐÙKba»Úñ‹5™(:ËFQ\v5S7ÇþwÞ=„á½j Ó C Ç.\pAüŽ•«ƒýïórÓtö^ñ¸élúžô9N«|gó°D ÉÓU›¼N^“ ‚` †éȃAˆ"ȈïAkyáxf˜Ž…¼Ô@ G¹ã<Ÿno½&p‰l$dÈà»M@Fú^3< ¿åݱ ÉÔŒïÓÞÚv—«€ ( € ( € ´š@é•l«m½Û«€ ( € ( € ô":¹cša)Ð ƒ;¬Ú„Îe‚4Èðøã‡éÓ§Ç;¬éält¡ô¦›nŠA)DZÐ Áð!‡ì·ß~ñÎo:vÉp@P@*tÓ ¹lÙ²xgü¾ð…8_úœgÖøðá±Ã2u¾ó\®€ÎárC¢¤ ÌXÉyG> ù]ù,³R@C‚0?¤©°xà“êa]¤=ztœžmàŽx¶}ëÖ­1Ó lÝÅïTwñyÅŠá–[n‰Áy– ¶‘h²p|°~l#Ù8èô%h'e¿`èÞ»ûî»ã÷§vZq11H„zȰ‘J-NÌÓ§OŸhÐŒŽd²~Ã1E»”e†ýÄ9tÚcÁwƒ ƒTtá{ÃþcŸ]|ñÅe‡yÁ¶ÑÇMZ‡ÞðŒÇk±8@ÖŒFöuvØa%ƒ|‡ø+.—€ Ö±˜1…ãGO+l id0t(ü>ñ›Àï'ÑͅŽãb JOÛ×GP@P@P s3:7r P@ö)´¿öµ¯íSÛäÆ( €=Q ÝõÜèu£ÓòcûX ` ÃøÄOŒwZÓÁG‡;RÃk0LïÌÓˆB Æüùóã#ïä¦n1&ƒå‘nŸ  :æ¹Ã=&„qÏ=÷ÄŒi}øŒÎö»îº+\{íµˆTèœýÜç>Î?ÿüôV øÁ~PPAÇù¿øÅ؉Ù6ážt̳.ÔI`ËW¿úÕ’»êé”gX¼C—»ÔÙŽ|¸êd[ò"Ý}Ï0K–,‰C¤  ¦aȆ'!8wF¨Ÿ Ž : *xä‘Gâz—“¯zMPA8dØÈƒ2ð9ûì³cö :pÙN–‡9A ¬ãÂ… ã¼i8>#˜‡ìtü³«0É7¾ñ¸®,Ÿ Žûï¿?v"§õá8œ9sf˜5kVz«ä™}O0L£ A& ŸCJ 6IË`[XŸ#F„8 ¡Âz& ²¼ð=!p)èà˜ž7o^ìÀg¿³îy9á„zÜäu÷†×=œQ,óhFá8.W7Y3Ø_ÅÀ ~÷x Óñé)…߆râ7” GÏlp‘=gúž :Ž9Ö»\°Y£¶…ï4ß#‹ ( @s8?·( € ( €˜áq € ( @‹ p‡1_P@Þ-@‡3—dÎ å?é=ÐÁL'>Ðt¦nÞ¼9 qæ™g†±cÇÆÎêz·<:*tà®_¿> °R!x`„ 1À#½×Ñ3æ “@༩›ýÐÓ3’Çoî@ÖèàÆ¾³Â÷„¬-µlÛ¶­$Y[°! Á5–¿˜Q † p¢™ÁSÔ]î÷„õHEùþáý|ˆ>#ð¡Úïb^W£^HE£ Ä㊀ Öã”LGdé… :üŽZP@P@P@öm3öíýëÖ) € ( € ( @‹ ¤ôýdQ8î¸ãbÁ¤Ï§£;¶ °xúé§ã°dРº³†}X·n] KD^H»?uêÔ²¨ùtÅ×Ì7nܸ@Ö‚¼C•u$x€@ž^Êu“õc×®]ULt¶x8‘€0Cv <¸³ÙÛ>gÿ²Ÿy¤À >änþâ>m›©½à˜%ëKîÀê\D Q5Ais’ã«V­*éè'(ƒà 3’Ö_†½)fÍ¢™ÁeP?û*Ä!°¡\`F¹à‘Z‚¤þÿ­íú+~+ÉpðR>ñà ¾³3f̈ARdJÛØõ¥Zƒ ( € ( € ( @O00£§ï!×OP@P@¨C€ ² rÈ!¡ÿþaòäÉaîܹ1ãÅ[o½3g¼ð 1‚L gœqF°g˜‡J…!6nÜX’-ƒ;Ò?þø8ôC¥ù*½O§i¿~ýb¦:1Saݺƒ ÕfóHóv÷3C„ðغukÛ¢ xá.y†%`¨’®²œ¼øâ‹%î‡vXÌú€-…cÌya¿¦á<ò÷{Úk 8^óNz‚N<ñÄ8„O­ëK‡8Ç.Ù3òýGP æd…¡#Ýâwñ½÷Þ+¡À¦™>d¤G¾Ï+-—À‡bðC˜tçoC©Töðǵkׯ-FØ~ë¦ïNˆ€3^óÛÀûP@P@P@Ö00£uöµ[ª€ ( € ( €-(@ç$©ò °'ðbÊ”)±ãpùòå±Cž@‚;v„§žz*vr7wß¾}ÛI1ÌCÞÍp@ìÜ®wH‚N:é¤xwyZ À¤üçAVž\FƒG^Xo†g¡“væÌ™Ñ²+° …#/) $¯š× d:  #e)¡3›À þ®5Уše6j Š¿ÐÉ]ïp,‘U&?®q ƒBd&±„€Q ÂÀ)CÍ0"+ß¡|Ø$–C@W¹ì()`ƒ€®TxÿÞoô3ß!²ÐÁï(=ï¼óN\ ¿½dš8qbüý%˜¨hÙèõ±>P@P@P@ž)``FÏÜ/®• ( € ( € (ÐP:¯É@°éôO?ýô8Œ‰iøçŸ>qrå•W¶Ë‚Az~8òBG~10!ÿ¼³×ÌOVb¡CöÕW_íñd®;vl4Kût$3ìÆÝw߇~áùI“&…£>º®»÷ ôÀ"/,£˜E#ÿ¼£×ÔE€FêT'û–GO Ì` –(:ÐÉÝ•¬$Ì[œŸe¨‚‡9’øíàÁ÷2^ç§÷õL X nÈëLë’¿Çë°‘b0QnØ“â¼]ù›@2†,¹ãŽ;âï#=~g'L˜ƒ2 3ugöŽ®l“ó* € ( € ( € 4GÀÀŒæ¸Z« ( € ( € (Ð#è|'KC† ‰)÷|ðÁDðúë¯ÇNéb¦ :;é(MùiÃè$-‘>«æ™ÎT:׋…ÎÎÔÁYü¬'ýM€Ã¸qãÂsÏ=^yå•hÇúѹ%C´°±`Á‚8d µÃ† £QM¡Ü‹à )C ˯µìÞ½»]}Xó Ф':Øé¤/v²ãX­e¹í"{bá8/š§i¥¿ùžò]Ï ûƒc³Y…úk Ìàw­<Âñ±ÓÌB°>/|‡ø=ã7aÚ´iaèС1SQ=ßÓf®³u+ € ( € ( € ìÚ[qöÎzºTP@¨B€Ôæßýîw«˜ÒIP@z‚@W:•»ºþ ?2pàÀ˜É`2g¬X±"Œ5ª]} Ì(.“ÉC9¤øvÕÓa‰©ýó! X^¹NÙª+îÆ L9ï¼óbçì<^xá…¶¥³léaÛ¶maéÒ¥qè2hŒ3¦S;TèXÎm¨<R´-¨‹/èÐî©Ù2Ø4 ŠAA¼ßÕÀŒ~ô£CÍ“ Ëkv‡~ZVoxæ{Î#/›|GynFàAå?øÝ*7tÇp¹à2Ÿð=lV¶ Ž‘#GƬ8üž’‰hĈ1 £¸>¹_³_Ïš5+þÆ4{9Ö¯€ (Ђ¥- ( € (°ï ˜±ïïc·PP …h4§CÍ¢€ ( @5t*ÒÉIc0CmÑÎîb'&›å2¤ÀŠj–Un–Ÿ:Tóúé$g™½¥ôéÓ'\xá…1 ÙGr!x"¶' ²sçΘdôèÑáÜsϸEï4wü³D¤ÏõLƈ~ýúÅŽäFÕÙèz’(ç@0 õ‚¨ƒã8¯Ÿ@˜b0L½ËØæ+Ã1M° ffôQ.0ƒ@°rÁ`Ǭ'™dRá7„¡€ÈSnž4]WŸÉ4sÉ%—Ä`² õ„ '~“xXP@P@P@zŽ€=g_¸& ( € ( € ( À^ @ J+@'v±Ðy].“AqºJÓ¹[.ø u˜W𝧽™3l"àˆ€ˆF†â;’‚È|(·<‚#x™&/|ÿÈZÓÌÀ «Ê¢€ ( € ( € ( @Gft¤ãg ( € ( € ( €1ƒF¹ÌtŠÓyzÌ1ÇÔ¥DÇzj ¯€ŽñrÃäÓôÄב}âÈ# Ç;vì«W¯ŽAt³½© `ýúõ1ÛA§œrJú¨í9ei{ãÿ^ôíÛ7œ}öÙu»§úúÀ¹'ÜáŸÖ©Ü3å%Òp åVO!K ™ŠÙ1ðØ›ÃPÔ³-Íœ‡€‡rÆdÙµkW8ꨣºxöÁK/½ôRI½W˜Q.X‰À>+êáaŠø¢Œ+ € ( € ( € t·€Ý-îòP@P@P@^&Àáå%Ì °¢ÞÂü 5P,ftÐAÅ·{Íßtìòyûô醿Gùûùëã?>ð(–µk׆'Ÿ|2¼ûî»Åü[P@P@P@n00£Û¨] ( € ( € (Ð{ÈÜpÜqÇ•lCI04ÇöíÛKÞ¯æ²ep·ýš5kJ&ÿÄ'>Q¶sµd¢^úý#FŒƒ.Ù‚7Þx#} ®$M@æò²sçÎè^ÌöOÓÈ×d‘àQ,dû`?vGÁ¡˜ NüM›6E»Z×»§Ÿ~:™‘ÏKf–R2UôÀ0CyáûÿÄOt)sNª@(–.]Ú.ˆ‚e˜AH¥ÂïÓðáÃcvŸ|²ò,Z´(‘åïûZP@P@P@î00£;µ]– ( € ( € (ÐKÈø@PA^ÈT@ÀòåËó·«zÍ(K–,i7”ï§œrJUuôƉ<Á2ï`&è  †k(‚ÈT’Æð «V­ŠÃ=§oÆß %B&“b§<<º£{ì±G^daÈ‹gŸ}6»ª×ÌC¶—|ýÙ'C† i—¢ª ÷ñ‰È˜C`D¿~ýJ¶¿ „ùóçwix~KÈ”qÏ=÷´ËbBPÎèÑ£c&’…þà;D`û0/Ô½aÆXw=ÇJ^ATóæÍ ×_} ‡EP@P@P@jÚ·úT;§Ó) € ( € ( € ´Œ³'œpB»ÎQîFä‘Gjºýí·ßް?þx‰A 'žxb`Ø‚ÞP à.ÿZÊþð‡8 I>üÃgðȃ5RqÐ!^4Ù¸qcxê©§õ5»°^ì‚3òB–—_~9«i¯ ØÁ!Mò²eË–°páÂ8¤Iþ~G¯YgŽ=‚:òB Ç8ûÂR*À1pòÉ'‡ñãÇ·;†çî»ï?üp]Ç#YWîúõ¯GòïAA,s„ U /Ãþ›8qb»ã„ì>‹/·Þzk ÒÈ¿¥[Zþ/Ö‰@Œë®».ü÷ÿwx衇¶mÛÊOì» ( € ( € ( € ”00£ Šo) € ( € ( € ” Ð1Kpžy¡Ã’»ÑþóŸÇ! òÏʽæŽó{ï½7Üpà ¡(R¡~2"œ}öÙe‡ÍHÓõ”ç]»v…›nº)|ç;ß Ë–- d±è¬Ð¼~ýúè•OKÐAq˜Žô9™2ÈTB‡s^nyàÂm·Ý^|ñÅü£N_³ÏF†;ÿ‹Á •f&0ƒálòBPõÔÚÉ×Qík²Š àŒ¼àNƆ_ýêWqx—ü³r¯Ÿ{î¹pË-·„9sæ”dk¡þ1cÆ„Q£F•d')WG«¾GÀÊÔ©Sc€FnðþûïÇÀ˜›o¾9ü⿈ÃËð^g…ㆌ;wÜqG x Ð(Ï`ÂüÆ Ó¦Mk7œO¥º9N§L™9Š^bbH“þð‡á·¿ýmUAE_¬×O~ò“ðýï?Ì;7fôؽ{w»u­´N¾¯€ ( € ( € ( ¥ƒƒj¢€ ( € ( € ( @C9$vÌ®^½º$¸€ÎT†Ö “ qãÆ…£Ž:ª¤–wß}7åŽÍG}4p—}^®`Ö¬YaÀ€ùÛ=ö5Ù"Ö¬Y[郠ž:è vëM ÅŠ+Â]wÝhÈ C•­¡Rá³I“&Å ˆ|^:µé`Þ¾}{8묳ÂÈ‘#cðD>ìIªöÍÓO?Ø é@çò¹çžŽ;î¸vYÒ|é™}OÇ<ËL…úî¿ÿþpÀÄ€†’`9¬ëI  ë*ŒW¼ð mÕ² ¥ñæ›o†3Ï<3÷ŸqŒ’éàÉ'ŸŒÛÞVÁž}œ~úéUäó¶Êk‚§&„cïo~,ìóÒK/Å€¾LG†þýûÇïÙp~yë­·ÁY;LÇñÈñBV1˜ƒ:.¸à‚x\—;¦+¹@vÎ9ç‚§žx≒À!‚3†u%ÓÏñÇוߎc‚EX¶Y18ÞȲ¼)‰ bàG¥õñ}P@P@P@00Ãã@P@P@P *:Vé,ýä'?~ô£ÅÖ4#òt²ÒJ&2@0 Ç~ûí;c_}õÕØ©O@éy¡ýŒ3ÎÓ§O ]Ð Øð à‚j¸³þÈ#ŒAl?ÛEg3½tînÞ¼9vðæYèžzè¡•&í‘ï3¼*[·n tFSèü'P¢˜•!ß‚U¸ãþ¼óÎ Ó¦M‹C(äŸWzM&Œ‹.º(f#¹÷Þ{cv‚.òÂßÕt48B3ÃÎðº³Â:=º-[(òÂvçiäÁ)ù´]yM Å1Ç>õ©O2c¤B`H¾l^S „ɗ˰§œrJÌ”Á0üm©^/¾·|ÈØ2oÞ¼¸Ò÷ úšþ2%ÇË AƒÚ•¨—àŠ®Ž?2g|þóŸÁ>ø`ÌêÃoS­… +²MߓՇ@*ŽÁj¾7µ.ÇéP@P@P@ö]3öÝ}ë–) € ( € ( €M sœ “&M ýúõ‹Y{ì±8¬AgAtè6,vŠÓÁÙ·oßšïŠ'¨ƒ )kºÜÅ_OG.ë³ÿþû·e^ nêJÙ.*2ÛO°C6,[¶,hµ¡RItîŽ;6ÚáXmÁŒ û2tèаråʰxñâ Ñ™;Ë`;=öØ0|øðØQMG8ëO½Õ‚g¤¡Óüž{î‰9ÅÀê![ÂðÀ67ºP'ëM` Û‚ýÒ¥Kc`@Gþl'CÌI Ö‘àŽz:Øë=nmQ®>2p ³Òþá8ã½F²Y\ž hgÍš5ññì³ÏÆ!c: Òà{KÖö!û„ß~O°­ö˜ìl{øDÁïõ¯_¿>¬^½:>¿ôÒK%™>Šuñg^ÖmĈ10ƒcŸïQ£Ö¯¸LÿV@P@P@Øw>°çBù/·õì»Ûè–) € ( € ( € 4I€KÊ·Þz+vľú꫱sœOÞãÁçt´Ò)L§8™". ÛF-A ùê“bÓ¦Ma×®]±c•€ :P ‡Óȧíìõ+¯¼¶îÉzÁºSXׯãj‚ á4^{íµ@ †ôعsg`†0aÝh`Ûy¦#šÛ^Mý•ÖW–ÁrÙ†ð`¹h$w:èé}b` ëHG}WÖ­«ÇM¥ýÚˆ÷ Æ`ß`ÁñÀqÆ÷ïß½f–ÉP!o¼ñF<&Y>ûƒc4Ö„}A`¿|Ø'¬YxØ]ùNt¶]dR!p‡uäÁïû‘c'¶u`]8^ÒqÂß<ø¾Ñ™²Ÿ+ € ( € ( € T00£’Œï+ € ( € ( € Ô,À0t–óH÷ЙI9îâoTç&ËH…ºë-¬g ƒu«·s˜zÒöS_Ú~¶™õÖ[wGÛÆr°`Ùi[xNËã9-¿Qö¬Ë 3›¯)iweÄŠêø‡u(çŸÈžÀëF°¼F7uljU³äë×Èíîlái¹ø¤Gún¥ý‘ŽÉÎêkÖç¬Wú­Ê÷#Ç.ëÈs£Ž•fmƒõ* € ( € ( € ô3zϾrMP@P@P@P@P@P@P@P — 4~°×^àê* € ( € ( € ( € ( € ( € ( € ( €Í00£Y²Ö«€ ( € ( € ( € ( € ( € ( € ( €-/``FË( € ( € ( € ( € ( € ( € ( € ( @³ Ìh–¬õ* € ( € ( € ( € ( € ( € ( € ( @Ë ˜Ñò‡€ ( € ( € ( € ( € ( € ( € ( € (Ð,3š%k½ ( € ( € ( € ( € ( € ( € ( € (Ðòf´ü! € ( € ( € ( € ( € ( € ( € ( € 4KÀÀŒfÉZ¯ ( € ( € ( € ( € ( € ( € ( € ´¼€- € ( € ( € ( € ( € ( € ( € ( €Í00£Y²Ö«€ ( € ( € ( € ( € ( € ( € ( €-/``FË( € ( € ( € ( € ( € ( € ( € ( @³ Ìh–¬õ* € ( € ( € ( € ( € ( € ( € ( @Ë ˜Ñò‡€ ( € ( € ( € ( € ( € ( € ( € (Ð,3š%k½ ( € ( € ( € ( € ( € ( € ( € (Ðòf´ü! € ( € ( € ( € ( € ( € ( € ( € 4KÀÀŒfÉZ¯ ( € ( € ( € ( € ( € ( € ( € ´¼€- € ( € ( € ( € ( € ( € ( € ( €Í00£Y²Ö«€ ( € ( € ( € ( € ( € ( € ( €-/``FË( € ( € ( € ( € ( € ( € ( € ( @³ Ìh–¬õ* € ( € ( € ( € ( € ( € ( € ( @Ë ˜Ñò‡€ ( € ( € ( € ( € ( € ( € ( € (Ð,3š%k½ ( € ( € ( € ( € ( € ( € ( € (Ðòf´ü! € ( € ( € ( € ( € ( € ( € ( € 4KÀÀŒfÉZ¯ ( € ( € ( € ( € ( € ( € ( € ´¼€- € ( € ( € ( € ( € ( € ( € ( €Í00£Y²Ö«€ ( € ( € ( € ( € ( € ( € ( €-/``FË( € ( € ( € ( € ( € ( € ( € ( @³ Ìh–¬õ* € ( € ( € ( € ( € ( € ( € ( @Ë ˜Ñò‡€ ( € ( € ( € ( € ( € ( € ( € (Ð,3š%k½ ( € ( € ( € ( € ( € ( € ( € (Ðòf´ü! € ( € ( € ( € ( € ( € ( € ( € 4KÀÀŒfÉZ¯ ( € ( € ( € ( € ( € ( € ( € ´¼€- € ( € ( € ( € ( € ( € ( € ( €Í00£Y²Ö«€ ( € ( € ( € ( € ( € ( € ( €-/``FË( € ( € ( € ( € ( € ( € ( € ( @³ Ìh–¬õ* € ( € ( € ( € ( € ( € ( € ( @Ë ˜Ñò‡€ ( € ( € ( € ( € ( € ( € ( € (Ð,3š%k½ ( € ( € ( € ( € ( € ( € ( € (Ðòf´ü! € ( € ( € ( € ( € ( € ( € ( € 4KÀÀŒfÉZ¯ ( € ( € ( € ( € ( € ( € ( € ´¼€- € ( € ( € ( € ( € ( € ( € ( €Í00£Y²Ö«€ ( € ( € ( € ( € ( € ( € ( €-/``FË( € ( € ( € ( € ( € ( € ( € ( @³ Ìh–¬õ* € ( € ( € ( € ( € ( € ( € ( @Ë ˜Ñò‡€ ( € ( € ( € ( € ( € ( € ( € (Ð,3š%k½ ( € ( € ( € ( € ( € ( € ( € (Ðòf´ü! € ( € ( € ( € ( € ( € ( € ( € 4KÀÀŒfÉZ¯ ( € ( € ( € ( € ( € ( € ( € ´¼€- € ( € ( € ( € ( € ( € ( € ( €Í00£Y²Ö«€ ( € ( € ( € ( € ( € ( € ( €-/``FË( € ( € ( € ( € ( € ( € ( € ( @³ Ìh–¬õ* € ( € ( € ( € ( € ( € ( € ( @Ë ˜Ñò‡€ ( € ( € ( € ( € ( € ( € ( € (Ð,3š%k½ ( € ( € ( € ( € ( € ( € ( € (Ðòf´ü! € ( € ( € ( € ( € ( € ( € ( € 4KÀÀŒfÉZ¯ ( € ( € ( € ( € ( € ( € ( € ´¼€- € ( € ( € ( € ( € ( € ( € ( €Í00£Y²Ö«€ ( € ( € ( € ( € ( € ( € ( €-/``FË( € ( € ( € ( € ( € ( € ( € ( @³ Ìh–¬õ* € ( € ( € ( € ( € ( € ( € ( @Ë ˜Ñò‡€ ( € ( € ( € ( € ( € ( € ( € (Ð,3š%k½ ( € ( € ( € ( € ( € ( € ( € (Ðòf´ü! € ( € ( € ( € ( € ( € ( € ( € 4KÀÀŒfÉZ¯ ( € ( € ( € ( € ( € ( € ( € ´¼€- € ( € ( € ( € ( € ( € ( € ( €Í00£Y²Ö«€ ( € ( € ( € ( € ( € ( € ( €-/``FË( € ( € ( € ( € ( € ( € ( € ( @³ Ìh–¬õ* € ( € ( € ( € ( € ( € ( € ( @Ë ˜Ñò‡€ ( € ( € ( € ( € ( € ( € ( € (Ð,3š%k½ ( € ( € ( € ( € ( € ( € ( € (Ðòf´ü! € ( € ( € ( € ( € ( € ( € ( € 4KÀÀŒfÉZ¯ ( € ( € ( € ( € ( € ( € ( € ´¼€- € ( € ( € ( € ( € ( € ( € ( €Í00£Y²Ö«€ ( € ( € ( € ( € ( € ( € ( €-/``FË( € ( € ( € ( € ( € ( € ( € ( @³ Ìh–¬õ* € ( € ( € ( € ( € ( € ( € ( @Ë ˜Ñò‡€ ( € ( € ( € ( € ( € ( € ( € (Ð,3š%k½ ( € ( € ( € ( € ( € ( € ( € (Ðòf´ü! € ( € ( € ( € ( € ( € ( € ( € 4KÀÀŒfÉZ¯ ( € ( € ( € ( € ( € ( € ( € ´¼À‡[^@P@P@P@P@P`øóŸÿ^}õÕ°sçÎðú믇ýöÛ/xàáè£p@øà½ooÜín’ ( € ( @00£îWIP@P@P@P@¨GàùçŸ=ôPX¿~}x饗Â;ï¼Þ{ï½ðþûïÇê>ô¡…øÃáØc #FŒS§N  ùÈGêYœó( € ( € ( @øß=¥ŠéœDP@P@P@P@P ‡ ìÚµ+ÜÿýaÞ¼y×ï¾ûn Ȩ´ºgü¿ÿ÷ÿÂG?úÑ0räÈp饗†áÇ Q Ì÷P@P@è‚€]ÀsVP@P@P@P@P`o ÌŸ??Üzë­á¹çž o¿ýv¨õ^<49äðµ¯}-œrÊ)gìíêòP@P@ö9‡2Ùçv©¤€ ( € T •ñ]wݶmÛoú°Ã “&M “'O®<“Ÿ( € ( € ( @X·n]¸í¶Û† Ú†+©ueÉ®A–§Ÿ~: 6,|ðÁVAàÃ¥,[¶,¼ñÆ1ƒl³fÍŠ×Îì‡ ( € ( € ´ €-¸ÓÝdP@hMƕ޲eK¸óÎ;cJcS_š†T3Zó˜p«P@P@z·À+¯¼n¾ùæ°qãÆvAGqD˜:uj:thèÛ·oØÿýÃk¯½vîܵ—,Yžþù°×dÛ €»³òÖ[o…x ¬^½:.÷ø@XµjU5j”áù¹ ( € ( @K ˜Ñ’»ÝV@P@V 8ãwÞiÛ|þ¦ñÕ¢€ ( € ( €½K€@ †/yê©§/ò2sæÌpÑE…~ýú†)! ûƒü`èß¿ Òæ:àÒK/ kÖ¬ ÷ÜsOX»vmøÓŸþ3_dÑYyÿý÷ÃÿøÇ’åÐQMPGguû¹ ( € ( €û¢€ûâ^u›P@P@P@P@P`Ÿ Û+þð‡?”lç„ bÐÅàÁƒc0Fþ!<öÛo¿˜AcÊ”)a̘1aùòåaÁ‚aäÈ‘ñý|_+ € ( € ( @× Ì躡5( € ( € ( € ( € ( €Ý*@–‹W_}5A’ü±},œþùaàÀí‚2Ò4ù3Ù4xL›6-Œ?>0?[P@P@P ±f4ÖÓÚP@P@P@P@P@¦ ¼ôÒKq8‘|A}úô GuTøð‡kköMy]¾V@P@P@Æ |°qUY“ ( € ( € ( € ( € ( @w¼ñÆáüì6ûIDATþçJuÄGÄaJJÞôP@P@Øëµ…NïõÕuP@P@Öxÿý÷Ã믿6oÞ^xá…°cÇŽ°k×®xGÜ'>ñ‰xÜСCà 'œŽ<òȲ(þóŸÃË/¿çcþ~î¹çÚMûÖ[oű©Û}°ç îœãŽ»ƒ>¸ÜÇíÞc½Yæ† ³Ï>S+ïÞ½;¼ýöÛ±®8 ~øáaÈ!áøãÇsL»:ªyƒuf¯½öZøÈG>Ž=öØ0hР’YùlÉ’%aÕªUq:îìÛ·o8é¤“ÂØ±cÃÇ?þñ’é‹üïÿþo`Ý·oß÷cxsW"ޤxf;X.ßü`ùxç|àmîׯ_Ë;-'ÒNSË©§°=‡vXÅý_OΣ€ ( € (ÐXwÞy'<óÌ3aÍš5açÎ`Š?ýéOñ|òÀ d¸5jTúè’sý¶³ï¾ûnÜ–Ãë»7ß|3ÎG]ÔÁµÛQܧ©\Ùf¶=/XqÍXnäÓuôšk®•öÛo¿Ž&ó3P@P@.|`OCp}-Á]X¨³* € ( € T °aΜ9ñAãã{ch¤CŸXåhФo̘1qi%ó²eË–ð½ï}¯-ƒÓ>ê¢Q5/tð÷Òç|6nܸðõ¯½b+õdðØc…G}4.ïücÛzó9ëMÉ׆YƲž={v rHËìì™Çyóæ…ë®».ÖKÃ% Ù_ýêWÀž+W® ¿øÅ/b£'cGÁŒÆÖ³Ï>;\}õÕñ½rÿ°=ìƒûï¿?gàÆƒíÈ÷>lSG…à‰‹/¾8œwÞym“ÑûÓŸþ´b@LÛ„¼`ìðk¯½66Hw2©+ € ( € t£Àïÿûx.¹`Á‚x®Ìù1瑜—r~Ìù<籜OÒN°5狜°QM¹í¶Û¯~õ«¦çÜôÛßþv?~|§ç©ižjž9w}ä‘GÚ:ÿÙ Òyvªƒë ¶©\a»¾ùÍo†áÇ—û8žo¯]»6žë\M0Áœ‡³¼´¬dǹ=äÆ —^zi9rdü»låÞ$øãûßÿ~ *Oûåšk® 3f̈ܯ¼òJ¸á†bPFž¡g¶“esÒ¿ÿ²K`Ÿsmrûí·Çeä×IlOÚêâQ)(#UN È_ýÕ_Å€žôÞ­·Þî»ï¾¸’Þ«õ™õ¸êª«âuAP@P@Æ ”?Knür¬QP@P éžxâ‰pÓM7…mÛ¶ÅFO‹…†I wFÑJ& îò¢‘»íR!«wç1]G…úÈ.Q©D@ù]ciZ2J<ôÐCáî»ï4Z2]Z¿4Mþœ>KëNcòòåËÃ…^?«¹{Ž:X. µ©ðš:y,\¸0üüç?.©ñ6MǼ¼Ç6•+ÌÏú°^düàoS‹¥˜2ºøyþ7!Ô•öͦM›:tϧ¯ôšF|pŠA9•¦÷}P@P@æ p®9wîÜð›ßü&,T\îœ>­Ù87¤Óÿ'?ùI<—ýüç?³6tLö9²Gä…ås>K 2¼5ªp½‘²ÇuT'×'• ÛÈuëXÜ62Šüú×¿Ž™)8×çº#7–‘2ƒ,[¶,fÓ;ýôÓc€™: pHëÈþaX·TRÀ Ù1~ö³ŸEOöQ^¸®`ùéº-ÿ,½æšãŽ;î‹/ŽÁ3µ\C¤:ŠÏd ,Ú\¾áz²+eãÆaÒ¤I1ã_Wêq^P@P@òf”wñ]P@P [èü'ˆ‚;ÑhÀ£±²šBc% ‚¤fþ<0ƒ»žH…KpA½…MMË¥¦“g4h– `èh¹¬; œ¤¦‘ i“Ê+¢!YGŠÓ¤zy¿œ/¿4êþÇüG ú(7Mª£–göwò奒i>M5¯1oDo5ËrP@P@Ž8/#3AËt”×r~̹'îœÏ$ðå/9f€¨”}‚5aè‹b`ï“=Ìz?W;$!óuT¸༶+çÈ\[°¾Ô“—¥K—†ë¯¿>PϹ-ó$N¶;êþô§?‡Ì—Qéu¹kÞ£>‚½Y·Žð(WS~ô£…'Ÿ|2Î_nšJëÔÑû\WýØ7Å@—Žê¨ô޵³•êñ}P@P@òf”wñ]P@P [˜´Û·o/i cŒ)S¦„#F†þ ÐÈÇY4ò‘‰Æ3 ŽÈ °j<þøãmoÓ HB^h -¤ÏI7|òÉ'—mè#0ƒ»ñŠwlQW¿~ýÃlqÄm`ÉìÁö=ýôÓ%w¤ñÛCCêèÑ£c#rZ~µÏl<ð@¼­ØðIãejdäu13Ó³·ÜrKl„Í—Ëúsçw2ö30Ü=Gze9ŠÓÿøÇÛöõp'ã©§žšWÓS“j™»ÛÒz•LPålG¥ahª¬ÂÉP@P@$@Æ‚2vîÜYÒYÏÐC† ‰YÎx&8À Οzê©°cÇŽ¶¬stŽ“YíÆo ó7Sqˆ Vù¨£ŽŠŸs›²Gð>Ù¬ u]tÑE ÉœÁ5@§R.«×•²UpMð‚ÅÏ FÁ‚õÍ ?¸¦àœmÅlØÜÍ5T>Ûýàƒ†±cÇÆ€”â9^wG¯Ù.²²^Å Œüº‚:XF1P‚ët¸^ȃ䙎a(±4hP LǓ놼)—lÁ5 ìþžõ©´øªŸiü¾óÎ;cæT'¾gŸ}v lÁ†áNhÀeù4^æ…FÐ{î¹'z¦÷YwÆŒN©¤id¦1”úiì=óÌ3cÐ Á4§Âøàù8ÓÌC°F^°úâ¿®¸âŠ6ƒüóâkœÓ›ú¼|SiŒî|:_+ € ( € 4W€Žñyóæµ Ê­ , ã›sçtNO°3Ãè1o„ϸ>àA sñ\2m ç§\˜ÁuA^žf ê¸øâ‹Ãi§V±ž|¾J¯gÍš¦NÚv½ÂºþÛ¿ý[Ér¹vø§ú§¸­åêaÛ ü.ÎuÙf çàkOŸ>=œtÒI1™ù8§Æë%¦eû¸뮻J« ܸ÷Þ{ã5Eê)ÔKÖ’t­C§œrJ˜9sf¼Fãz€@í•+WÆ ‰bVÎÛ-ZTÀNÐÃå—_‡oäÚ„íLÇ®gœqF !ð=Ù°\pAÌ*˜†•äâ‘®¿°ÊƒTòÏ‹¯¹bض!|¹®0è;‰ø¬€ ( € 4^ÀÀŒÆ›Z£ ( € (P“ŒÙœg² sŸÔN8!6BæÒˆÇ]S4ÎÑHð £ÅÀ ×høLŸ? ©—†N–Wk¡AÌ4Θ1#œuÖYñN69XÇJ…õ¡q™ùÈú‘ Ò4hsW̵îD㎹ØB`È—¾ô¥˜1$¥öåN;Æi°d›S¡a•¡`~øá¶a>£!÷ _øBlä,nó³ýl7®ÿõ_ÿÕ6/M.\—Í>(Wh´Î÷M¹iÒ{¬ßºuë£>šÞŠÏdò ·‘c‡—,À?P@P@ª Ÿ a²¡qî–Ê„ ÂUW]ÏéóóO>OsNÏy+ øê«¯ÆÙ9g%îd¨TÈÀAÀçÒœ‡æ…ë Î#é€'KÃyçÏQ‹ûù<•^3O>çØiòyŽ®õÚ‚ón†^!£p®ÜQö ²\vÙeñœà ‚°S!àk)2×üPkáÚ ]Wp>O@Źçž¯uX'ö1u¬Mý¹ Á\WPG~,@C\³åë”®í¸î»úê«cÖŒ 6´­2AãÇ×]ù|mìyÁ¾àQMášóæ›o.É|Â|,ƒuHÙ9ª©ËiP@P@j¨Üb^[=N­€ ( € (P§ ¦d¼È “d²¨Ô±Ÿ¦¥1”úb_ú¼™Ï:‘ƒô¾|Ð IÀAg…ÆG—Ï9眰zõê¶;»hüäÎ7¶i˜®µ¤ÆSIiÔdø<À#eÿ(6ZÒ8IÃi>$ ½ÜGfbPF¾^ÜQFƒ,ÓTBáÎ:¶‹FpÒ»Zh`gœpR\§Â~§á”FøjÌÓ|>+ € ( € 4^€ó@²°› ç³tÆDÝÑù$íœ{4AÎ…Sö²`ÈL]LS®p½3ȤÇüy¡.Þ[²dIZƒ¬|d¿ ƒFÊÂO¿7^³í ÑÁõDµÃiàF°7Û‚Û˜!8¿'P…çz ÒuÏž=;§’#xæ|¼\` çî×äÇC"âÝÑ5û‘k$¯’õ§ìC  ×^)à>~Pç?zpœq š ×riÓ{>+ € ( € 4^ ó–óÆ/ÓP@P@2 ó±šùˆÆ¾Žp³ÙãËÔHX|¿™ÓxHPHß¾}c£n-G ؓՂyóRÎ"ÿ¼³×d ñtâĉ%AÍG¶<èi Œá®Âr­y]¸ÓÉŠy!ƒI±Îüój_ôBÃéܹsÛè™—†Yîd=- ( € ( €{O€óW†­xå•WJV‚ d²µU{NO¦ †äü::÷ ¨HY4ÒûÅg,>ýéO‡/ù˳D°ž/pnù½ï}/üË¿üK˜?~I}±Þîú› ® \èìü»¸N ß8hР’¬LÃõÛÜ•B }úô)ÉrÑQ\p}‘‚µ¹Néìšë+‚8òáD¬¡Î<"¯»–×dd˜‚ÒóÂ6@T«}^‡¯P@P@:00£s#§P@P@š*@V!óBÇþÆó·zìëÎ+­8ÁÅí¦ñ´³†çŽêcsN=nܸ@€F^èL'X·³BpÃìýÃ?üCÌÎP)Së¹{÷îðÔSO…ï~÷»áÛßþv|¯gËjÆçõ^SÎ5EñüŸkŠ®fp-@À7C7Ö€ÎþÊÏݱ¢®bÖ¾J†\W÷×\_t¥àñÛßþ6lÚ´©$à› ‚ŠÇ]W–å¼ ( € ( €å Ì(ïâ» ( € ( @· ²—q•óB \Æ”~饗ò·÷©×4ži+ € ( €{Q€ÀŒ|H|x p¡ÖÒÕ ‘r™>ÊeѨe½¨óî»ïŽC¢ä3gÎŒÁ;Åk²ZêvZP@P@ê>\ý¤N©€ ( € (Ð 2f0,Åi§ïbJË î“O>΂Ï¢cĈ½6S€y)wþå ƒi»ëyæ/ÆDα«­‡†È#<²drÀ{™;;+Œ÷Lƒ|^ا] Ì`éÛo¿=äw-ÀCJì‰':„IŽíkP@P`/ ”j„sI‚««ÍÀ–¯>çÈ0ô…óe2©¸[mÖæ#ãðÃÓ¦M §žzjX³fM¸ï¾ûÂÊ•+Û Â2ÈúAÆ>²v\pÁáózj!HŸt-‘¿nÄ:ãÌ£ž,\W¸®à˜8ðÀ;]=®+¸¾È ×\_ÔS0b“ 6”÷ 2$œuÖYq×S¯ó( € ( € Ô.``FífΡ€ ( € 4T€?†2¹øâ‹Ã–-[JîR£Ñ‘áL¸Ë‰ Ò"3ðäÉ“{d# ¤D¦ÁwÛ¶mqX’×_=ðà}‚MòÔb£cCa«¬ŒlŒûœ¿.\ƒ :jPgÿÐxºxñâ|öØpÊ’õ¬yä‘°víÚ¶Ù9FÈÂ1RénǶ‰}¡€ ( € (Ð-dd [F1›çr‹-j—Å¡š•âü¸˜AŽóèâ{ÕÔÅ4 ð˜0aB ö^¾|y Þ¸qc»õæ\ýÎ;ï tÚÌQK HµëSít[<ýôÓ1 €a9Gf˜ž ^ÎÍ z('Sír=×\_ä…aD!襣@r¶‹k®EòRoêX±bExì±ÇbÖ•T'× aÂõE1ÓHšÆgP@P@Æ ˜ÑxSkT@P@j ÑsôèÑáïÿþïÃ7Þï°Ë+á9$ Ðxæ™gâ]OS§N gžyfèׯ_>é^yÍú±^4BÓØËzÒ˜Jƒ)¼¦á:eì••¬°Pî>:th<UÞ„ìp])tÆóàbäÈ‘ñz‚ :ä…óx2·qÞIPxw®y–.]æÏŸ½1&(%¿¦¨wˆ’îØ®ð%“JâÓßüæ7áÐCÁå2qp¼ÜqÇ1%?¦¸¦ ˆ¿žàl=´Ù¾}{ÉuØôéÓãµg½Y8ºÃÑe( € ( €û¢€ûâ^u›P@P W СÊ)§Æ4ž3gNxðÁÃË/¿\²-8ÐÀÆadÒàN<îv" m=u%•×ñë³iÓ¦pà 7„uëÖÅh‚zrciq3SÆ’Ù³g‡üàmi£¹SíW¿úU ¾¸è¢‹BÿþýƱ'ƒ iŸþù¶*©kÀ€áòË/ïðn¸¶ /HsLã)w¦Âw eCjGwØ¥é}V@P@è†iöy/ù7ªk‚~?ó™ÏÄsK‘óà  V­Z³øÐ]ÈB@ȼyóâ5 y€B÷ìÑ®/…óu†‚áÚˆáC(˜¼¾k×®Àu×|ì¦%ÊÖ=ø¸®àúb÷îÝm+Að>×\‡” æh›°Â‹{ï½7®×g©p3kÖ¬. »˜êòYP@P 63jórjP@P ©4¾qgÚUW]Î8㌘v–ÆI†É {4^’±áç?ÿy|þ¾P×8Öy½µ¼æÎ5møÃÆà„¼Ázh<$ØäC‰cT|ðÁ%i}¹ûí¹çž‹w“Õ²ÜfLûñ<¦l¦á›»ô( ±`Á‚ØÊ¶0Á(ÆÐÏ>Èã¹£Ïk-ÜhóÄO”ÜÑFF”K.¹$.»Ö:^P@P yœ»—ë0Ÿ8qb8þøã»8͹çðáÃàAƒÊ.§Þ-c 8þô§?æÎÛ–Ý:9¯'`˜óÝF„t´®'üô§?ç‰pž<ðÀxMÁµëž,ð°yóæÀõEO(œ¿ÔBÀ†L¶òÇ?þq¼&b¸D¶ë ¦áú¢8\ÍŒ3â4 ­Xi{ׯ_³Ž­#‚l áØÌýÒç>+ € ( € 4WÀÀŒæúZ» ( € (P³ f4¾Ñ¹ÏMgŸ}v aeË–ÅF½T)AdÕxôÑGãÐW\qEú¨éÏU\ýõ1h„`…TÈð@2%dz 1—m¢ñ/o¸¦•Œ¤ùÝÛ…ì¤KÎ.Ó:ÑPšTÓú‹™– ‚2^¦Ö†Nö#A6dËÈ\‡šl(ŒómQ@P@èYN”;ïã<žaè:è .­0çž§sÐ.UVffÆ35¤a7Òd;vìˆÙðš˜ÁuC>þøã%YãX>}ú„É“'‡ÓO?=f$&]Sä&\'ÝtÓM=&0ƒ`ë7–œ×³=)À› ®?(å®+ضSO=5\zé¥ñz0ßÖ8S'ÿm„¡S Éë'`è´ÓNëÖ`þNVÕP@P@–00£¥v·«€ ( €½I€8{y~øáa̘1qØÒ ÓØ—CœAƒ$C4»pWÛc=Fòõ 8¡UP`½I•\©!‘ý1üJцõ µðý÷ßßfJ#5ãC“©$¿ó.oØLõ°&LˆÛ]ošé;w†»ï¾;¦7Nõb3bĈ˜j¸\ƒšÎgP@P@½#À9Z œÈÏ rà³f54b«O8á„ð‰O|¢]UfÍóûf–Õ«W‡Å‹· Ê €à³Ÿýl8p`Ì0ÑÑùp oæzV[7Ãl_:&ÈPA&>‚ÀS¶½ôY±Þ{†EäzŠë ®ëJ†!1qͯcØ ±Â5N¥ë³âºø· ( € ( @c Ìh¬§µ) € ( €M “žÆ´±cÇÆ´¸Œ3|ë­·¶Ý…EÃÁk×®í–À —.]Z2î3Á ¤ÛeØzÒí6®ŠJq›¿'[FºK@‹iÓ¦…«¯¾:lß¾=f#yæ™gÁ¤Vf_p÷ÙLHSùd’mæáøá¼ÿ裎Yò¸Þã5×õP%ƒÀ êÏË…^† È:bQ@P@Ø;ž‰íw—ª€ ( € Ô%@C u3gÎŒw\Ý{ï½mõÐÁÏð"µAyÔÒðGc3éyóBƒ.©{SPëÿæ›o–l Û1nܸx‡¯F„FSWyƉ†RöÅG>ò‘øÌßõÜi<½ýöÛÛ†K¡žƒ>8‡ðaQ@P@è¹Çw\Ì—füþ÷¿/9·ë¹kâp% ­‘ Òºt]k'~º®HutöLP2לçå”SN‰Áè½-(ƒm(nY9F€ax†=|ï½÷b€=^ézk YËuYîÆµÊwÜ6oÞ\ðÍ:0$Œß¹–¯P@P@î00£ûÍ]¢ ( € (Ð%êŽ8âˆ0zôèfÐÌQï¾ûnÙ!BHƒKÃ_±Ð0HPGµLOã-ËÉ ó“j¸7/1#F*ÜñÈmƒË¥vNÓvõ™Fûûî»/Þ5—êb™¤;f8˜rû+Mç³ ( € ( ÀÞ #×È(— ÙÖÈšÀ°õ𦺚ýœ†,).'e)¾Ÿþæ<µ8Ì\WäQMP똞ùòÂ5Eµ×&ù|{û5Õp~Ï5F*\W¤ánr¥™ÃÛ<òÈ#aÅŠÑ4-Ÿ²eRoÀGªËgP@P@® |°k³;· ( € ( ÀÞ !”¬ yc(Ÿ4ôUjüeZ‹Ÿ§ÀŒZ¶#r#ÍGC_¾>éýJÏ4X敦kæû—ЀšoÏîݻúuëš¹ØX74«V­ sçÎ-¹C‘Œ(Œ+Í]uP@P@ž-À°œ—çåOúS˜¿g¨<:é›UhHAÙ]Yùœç…sz¶‹NýJ…Ì<Šçÿ¬×Õ”ü<Ÿž:k "àš"†ÈëêÎ×8æ™SX6×\_4»¼ôÒK1hÿÅ_,YÔyç‡^,^–Lä ( € ( €Ý"`ÆŒnav! ( € ( @e$i¼¬¥±ŒÆÞ;w–”ÁøÄ::è ’FbO·lÙ³pt4oúŒ»4>ÓPKæŒTh„¤A°š€©ï¼óÎðÄO¤Ù÷Ê3ɘaŸ2€p·ã­·Þ‡aŒç#FıŸ½bûöíqüSÁt„ áÔSO­©1:Íï³ ( € ( @÷ 0ô™ìR0ï€_ºtišŽLwµœçW»ö<ð@¸çž{â¹,A½#Gެy9œ‹?ôÐCí‚¥û÷ïßi¶'¸®àÚ G³î\W0 Y":+d¦ãº‚ó|(®)¸¶¨Æ,÷ß»à’Î–ÝŒÏ °f¸lRŽ2ƒ`Â"ýúõ‹Ù@j <él]±ãÚjÓ¦M%Ž×LŸ>=^ËtV‡Ÿ+ € ( € 4_ÀÀŒæ»P@P ¢ 4†Î™3'Ž7|ÖYgÅΊ3üßÜ Å]xy!)j;*å3¸³‹FÙqãÆU @jaC9‚-æÍ›† V1u1 ”¬û7Þ§%Àdo?üð0`O jRNS”a[|ðÁ°`Á‚Ø Lƒ3§40ÌÁ3 Ř“æ 4´{ì±·?m+ÁXå~ÜHÚfÖ«i„Nuù¬€ ( € (°÷8‡›:ujxüñÇK3Þyçðãÿ8¼òÊ+áœsΉöÕ®%A dZغuk¬›àŽb!„ój‚}×®]Ïå¹– @ƒóÕŽ Ù%–-[n¾ù渌 @B#j1p„†a©q“×wð ‘SpäÎIÞ+êf9ääwÒðƒ8_ås‚G¶î 4™6mZ >HÓsMÁ9t dàýÍ›7Ç@î«®ºª­Ž4=ÏÏ?ÿ|¸ãŽ;Âc=8oî Aiý.½ôÒ¸?-Z¸þ¡‘GîľK¦áú"=Ø×<È!ÈåÌ3ÏŒY Ë7ÔËuÅ /¼Ð–¥ƒúR°<׎åæcšb!0„}ÚY`Oq>ÿV@P@¨N }Kquó9• ( € ( @hL$õ1 ¤4XÒÐHC*wJ0AÙ-¸#Ž[õòq”i´#‚FᎠuqG˜4âQHƤÀåÎ7>£a™à õN?ýôx7Wª›z yòÉ'cÃcª‡L¿üå/ã>N>ùä¶u§¡FARÓèJ0 4ä²ü|8´Œîzæ.5²…pWÙOúÓ@cr¥ÂºòÈóýðÆoÄÆø5kÖÄ:¿øÅ/¶KL°û±|ñæ›oRRÓP^m¡‘uèСáßøFUCÈT[¯Ó) € ( € T/À¹:çâœëðœ9oäÜ—sc2IpÞÉy;ßd]ã¼kλ¾ƒi™—÷Óù&sîÌ2òÂù8篩³ŸyR}œÏ\Í<œsóšóûô ` ?‡MõŽ?>Ìš5«ê!§L™æÎÏÙV Ë {ÈêÕ«ã6²Žl#ÛÆ2¹^Á€õ¢PÙ¸ÖIëÄö.^¼8^÷„à †<¡¶ë ®;Ja¹°­lW1Ð$.¤ÿaÛ¾ò•¯Äë‚îÓþ)®ëÌø¬Üz³½) ûšk®‰C¡à™†·d,ò‚ѶmÛÚœóÏ*½fŸüíßþm8í´ÓÌàW É÷P@P@.”žÑw¡"gU@P@¨]€FDïR¡–Æ;4²qg d®»îº¶†Dæ!À€M¹CŽÂºÓX˜i8=ñÄã`·ÜrË^ Ì`ýhåNCx»ZØNê¡§k¯½66̦z±$%oˆå3ìx¿Ö Ž_;ì°´ŸP@P@ºY€sr:Ïé8Ÿ¿'Ж@„TRÐsžÈzœ'sþ—œ# ×d³+e0çÿO=õTX±bEøÐ|ˆCpá% ]Dq¥8"‚Y)ê¸wîü\èÒ…‚‚.DÁˆ¢p %Jp@#zQD(F#ÞëS— §ÛNÒÝÉMºãSМtr†:¿³©zóž·²S®Áy ›¾SZ—*.\ˆ éô;•îM¿K[Ž£„ñ–-[b ±ØÀo:~¤·3I¢ Á„¤÷=wîÜÐÚÚ+Rì$°É–kÚl&`Ìi$ÑdŸç¢2 å£)åœu F²µáHÞ‹çR@P@ªU€*$g0Žlkk‹ãÄìØšûjŒŸîåG¨^ÁRw)Ù9ý-cú}ûö…K—.…+W®ÄĆì\"»ï`?744ÄåK¨–1cÆŒ‚×èxÆ 6lˆ×¦rIÙ–ï$­°lIö~w³ãÎ;éS§âR‰)I…û,Á€ã¶oß–-[«kp®±n,søðáX1$Ý÷Ëü‹¹÷Ÿ?¯à;v$¡üûWõDª’è’ž'ŽüžÊ„{÷î óæÍë¿Mæ…wúw(ñç%‚¹» ( € (P‚€‰%`¹« ( € (0Òy+ *É”»íèèˆezºÇA”àÔB‰O@”u§9c–Ï ˜ßÊÑ7Â…t©$ð¦Üùóçc‚C¡sqnÖ,^ºti¬ìÁ2'% \RÆ™ò»4ªrð}°Æs”2f›Þã8á¥6ãT÷`lÞêKû¦ÒýÅ‹ höÃ~|Ou’;xnÇ÷”ÎÃ9y‹‘$ÎC£J %œyÛk§€k:¦”-AXž#å°m ( € ( €c+Àø˜ ›7oŽããëׯ>T<(¦zãYªÛ±Ì^sssç3f.Ôøg?ó€mÛ¶…õë×ÇjxTŒ Y˜ÄéÁƘŒKIì âIâ$3ž¦ÿ¥6ú¼{÷îÐÔÔ¨„×ÝÝS!#10ó ®›ß¸–Ï Ñâ_¿ª ”ÔÂqô±¾¾>¬[·..ƒÂòÜÕ;ئäpæÙŠù×Lßy^sÞdÆ=sl:GÚR%åäÉ“±’IzÞÌ£xF---qÜž®“®Å±$^¤ó›÷ïßÇóܼy³¿ú ó*¤Pq¥®®®~Æ\€9 Éâ,}2œÆ|yP)sËá\ÏcP@P@?Mà¯_ƒÀÿ-ø§Ý¹÷«€ ( € T˜  葨@YÞ”âŸþ+ ˜xcK°·èpJš(æÖþñf× Ô.–Åà÷2 Êñ! b¨À$B*D¤s|ûöm\#›`'S­ô›>§$ŽãÍ0öåg®K€y°ë1|ʼnþt¦ÑGl&–Òèç±cǵk×úÈœ‡dÖ 'ù£ØFŸX ûàÁƒ9o .X° ìß¿?ð6bj¼=‡×@I,i¿b¶Xa\N ½˜ó» ( € ( @éŒY{{{㸕*k$g0æåŸçŒÁÃ3v¥âcYª \ÀØŽñ2ÛbÇw\‹D>œûåË—ñøŒÍ/óÏ~ÆÙŒÉgÍš¯Ã5HH`[ìuSàÚ܉Ì)HР/ü“Ÿë’˜Ì–¥Yš¿$3ÎÃ9ø0æ'Qù÷ÐØØ“’qãÜ©ï̡ؗc¹/®Å|i k¥{Ióæ$pà@¸wï^NU>–3!A?›°Ã½3gÄo8 +æi®6œsy¬ ( € ( ÀïVÌøÝÄß( € ( €c"@ŒÁ0’/¨*A 0Ø R!€Y©AÂB7ÄyhòáÍ5’r½t­bËâ²?e>”næ\©ï IpH}Ïö…ãHÄ aƒÆ¾COÙ‡@$Á]®Ã÷bŽË^—Ÿ¹W‚¦,!ÃÏ4®M2 •HJIÊàXÃKÕOR# Melbµµµi· ( € ( €ãL€ñ)ãC>Œ‘©rÀø8·¹]öa<Ì–±çPãàˆ8ž„>i.ÁµÒxœñ=çf ÊõøŒt#‘„„’'X~%Ý+×åzÜý¬ñ÷dÆü`áÂ…ñ<œ‹FÿÓ'ÿ<$¹0?ÈÎò÷)ô¾eç#ìSŽ ×$i“à‘÷²víÚ˜H2Ô½§cØb–³3§ó æÙÄ î½ÔõìõüYP@P`tLÌg¯¢€ ( € ”$@à²ÔÄ€’.·ó@μ݊úZÎ¹Ê ~Ò®Unã­¾ü’¿8I àíºr÷AP:Û ý.ûwV@P@ßü£}4«”3©'Àطܱ}¶åœçrÛpûL¥>$ާFÂ:•;Ê™³ÈÁ¼"ÿžøÝpûšúçVP@P`tÊ­Žn?½š ( € ( €#*À[m”NoÕqrŸù‰¥\”òǯ_¿Î9„d*iØP@P@P`| 0¯ ñ;Û %Vdÿ>ÔÏÌ+˜_dóŠlµŒìßüYP@P ²L̨ìçcïP@P@þOT$ɯŒÁÚ̬ÿÊ%—riÖ³¾sçN\;<ÇÛl”sfi› ( € ( € ŒOæùŸ?zzzrÁ‹½{–F|úôiNb ³fÍŠKÖ{÷S@P@¨3*çYØP@P@Q`Íç9sæä”•¦ô0ÐsçÎ…¾¾¾¢{CBÇ7™3gr’:Xë¹±±ÑrÃEKº£ ( € ( €Õ'0{öì0uêÔÀ$©}ùò%œ={6tuu•”œñâÅ‹pâĉÀ6Û˜Wp › ( € ( @u ”¿(wuÞ¯½V@P@P 46mZLÎàm¶ÔÞ½{N::;;êU«ÂâÅ‹ ù%P>þÚÛÛÃåË—ÃÇU3RcY”†††°qãÆô+· ( € ( € (0&L˜êêê£G 4æ ·nÝŠË'®\¹2¬X±"V¼øûïßCòTì#ãêÕ«áæÍ›áÕ«W¤ñÔjjj¦M›âñéwnP@P@ªKà¯_ÄÿTW—í­ ( € ( €##@bÅÅ‹Ñ#Gr*]´A)bÊ“”1}úôøvÚ¤I“b€õlj¬ûüõëל ?þü°gÏžÐÜÜHÒ°) € ( € ( Àøxüøq8tèPxòäIÎM²¼!ÕúH®`™ÃÚÚÚ0yòäøù‰á?~Œó *ñ1¿È†ìIúرcGhii‰ÇçœÜ/ ( € ( €U#`bFÕ<*;ª€ ( € (0Ò< „²tÉéÓ§Ã÷ïß ^"½ÕF‚I¼ÑöóçÏøÉ?€„ŽE‹…ÖÖÖXm#­éüýý®€ ( € ( €Õ/ÀáöíÛáèÑ£Š|ÌòI4¶Ì+Òœ‚c 5*ümݺ5lذ!&‹sŒMP@P :L̨Îçf¯P@P@FH€äŒOŸ>…»w¶¶ÐÑÑQ0ˆ:Ôå®R¾˜¥KÖ¬YßfK CëßP@P@P úHôîîîŽK², •0ÊiTê[¾|y¬’ÑØØ+n˜”QޤÇ( € ( €•#`bFå< {¢€ ( € (0†QIÐèêê íííáÁƒ1¨J0µÐÛnFYꤾ¾>.[Â’%MMMaÊ”)1p:†·â¥P@P@P`Œ¨~ÁR‡Tæ»ÿ~LöìYxóæM\¦¤P·Hòž9sfœ[,^¼8,Y²$~gYÅTe£ÐqþNP@P zL̨žgeOP@P@FAàÇáÛ·oqY“¾¾¾À:Ï===ý¿c9Þ`#)ƒÏĉë>§Ï(tÑK( € ( € ( @… ÜÍ|‚¹ÛÞÞÞ8¯`ˇ¿×ÔÔĤnæÿüóOÿœ‚ß[!£Â°ÝS@P@J01£D0wW@P@øóÒÚÏÜy ²%Iæ€ ( € ( € #À¼‚¥iiËœÂyE1z ( € T·€‰Õýüì½ ( € ( € ( € ( € ( € ( € ( € T°€¯øUðñk ( € ( € ( € ( € ( € ( € ( € (PÝ&fT÷ó³÷ ( € ( € ( € ( € ( € ( € ( € (PÁ&fTðñk ( € ( € ( € ( € ( € ( € ( € (PÝ&fT÷ó³÷ ( € ( € ( € ( € ( € ( € ( € (PÁÿ‡2ñP·’VåIEND®B`‚stargz-snapshotter-0.14.3/docs/integration.md000066400000000000000000000156311440204344700212660ustar00rootroot00000000000000# Integration of eStargz with other tools This document lists links and information about integrations of stargz-snapshotter with tools in commuinty. You can refer to [issue #258 "Tracker issue for adoption status"](https://github.com/containerd/stargz-snapshotter/issues/258) for the list of the latest status of these integrations. ## Kubernetes To use stargz snapshotter on Kubernetes nodes, you need to use containerd as the CRI runtime. You also need to run stargz snapshotter on the node. ### Kind See [`/README.md#quick-start-with-kubernetes`](/README.md#quick-start-with-kubernetes). ### k3s k3s >= v1.22 supports stagz-snapshotter as an experimental feature. `--snapshotter=stargz` for k3s server and agent enables this feature. ``` k3s server --snapshotter=stargz ``` Refer to [k3s docs](https://docs.k3s.io/advanced#enabling-lazy-pulling-of-estargz-experimental) for more details. The following is a quick demo using [k3d](https://github.com/k3d-io/k3d) (k3s in Docker). ```console $ k3d cluster create mycluster --k3s-arg='--snapshotter=stargz@server:*;agent:*' $ cat <<'EOF' | kubectl --context=k3d-mycluster apply -f - apiVersion: v1 kind: Pod metadata: name: nodejs spec: containers: - name: nodejs-stargz image: ghcr.io/stargz-containers/node:17.8.0-esgz command: ["node"] args: - -e - var http = require('http'); http.createServer(function(req, res) { res.writeHead(200); res.end('Hello World!\n'); }).listen(80); ports: - containerPort: 80 EOF $ kubectl --context=k3d-mycluster get po nodejs -w $ kubectl --context=k3d-mycluster port-forward nodejs 8080:80 & $ curl 127.0.0.1:8080 Hello World! $ k3d cluster delete mycluster ``` ### Google Kubernetes Engine There is no node image includes stargz snapshotter by default as of now so you need to manually customize the nodes. A brief instrcution of enabling stargz snapshotter is the following: - Create a Kubernetes cluster using containerd-supported Linux node images like `ubuntu_containerd`. containerd must be >= v1.4.2. - SSH into each node and install stargz snapshotter following [`./INSTALL.md`](./INSTALL.md#install-stargz-snapshotter-for-containerd-with-systemd). You need this installation on all worker nodes. - Optionally apply configuration to allow stargz-snapshotter to access private registries following [`./overview.md`](./overview.md#authentication). ### Amazon Elastic Kubernetes Service There is no AMI includes stargz snapshotter by default as of now so you need to manually customize the nodes. A brief instrcution of enabling stargz snapshotter is the following: - Create a Kubernetes cluster using containerd-supported Linux AMIs. containerd must be >= v1.4.2. e.g. Amazon EKS optimized Amazon Linux AMIs with [containerd runtime bootstrap flag](https://docs.aws.amazon.com/eks/latest/userguide/eks-optimized-ami.html). - SSH into each node and install stargz snapshotter following [`./INSTALL.md`](./INSTALL.md#install-stargz-snapshotter-for-containerd-with-systemd). You need this installation on all worker nodes. - Optionally apply configuration to allow stargz-snapshotter to access private registries following [`./overview.md`](./overview.md#authentication). ## CRI runtimes ### containerd See [`./INSTALL.md`](./INSTALL.md#install-stargz-snapshotter-for-containerd-with-systemd) > :information_source: There is also a doc for [integration with firecracker-containerd](https://github.com/firecracker-microvm/firecracker-containerd/blob/24f1fcf99ebf6edcb94edd71a2affbcdae6b08e7/docs/remote-snapshotter-getting-started.md). ### CRI-O See [`./INSTALL.md`](./INSTALL.md#install-stargz-store-for-cri-opodman-with-systemd). ## High-level container engines ### Docker #### Moby Moby supports lazy pulling of eStargz since [`5c1d6c957b97321c8577e10ddbffe6e01981617a`](https://github.com/moby/moby/commit/5c1d6c957b97321c8577e10ddbffe6e01981617a) . See [`./INSTALL.md`](./INSTALL.md#install-stargz-snapshotter-for-dockermoby-with-systemd) for details. #### Docker Desktop Docker Desktop 4.12.0 "Containerd Image Store (Beta)" uses stargz-snapshotter. Refer to [Docker documentation](https://docs.docker.com/desktop/containerd/). ### nerdctl See the [docs in nerdctl](https://github.com/containerd/nerdctl/blob/main/docs/stargz.md). ### Podman See [`./INSTALL.md`](./INSTALL.md#install-stargz-store-for-cri-opodman-with-systemd). ## Image builders ### BuildKit #### Building eStargz BuildKit >= v0.10 supports creating eStargz images. See [`README.md`](/README.md#building-estargz-images-using-buildkit) for details. #### Lazy pulling of eStargz BuildKit >= v0.8 supports stargz-snapshotter and can perform lazy pulling of eStargz-formatted base images during build. `--oci-worker-snapshotter=stargz` flag enables this feature. You can try this feature using Docker Buildx as the following. ``` $ docker buildx create --use --name lazy-builder --buildkitd-flags '--oci-worker-snapshotter=stargz' $ docker buildx inspect --bootstrap lazy-builder ``` The following is a sample Dockerfile that uses eStargz-formatted golang image (`ghcr.io/stargz-containers/golang:1.18-esgz`) as the base image. ```Dockerfile FROM ghcr.io/stargz-containers/golang:1.18-esgz AS dev COPY ./hello.go /hello.go RUN go build -o /hello /hello.go FROM scratch COPY --from=dev /hello / ENTRYPOINT [ "/hello" ] ``` Put the following Go source code in the context directory with naming it `hello.go`. ```golang package main import "fmt" func main() { fmt.Println("Hello, world!") } ``` The following build performs lazy pulling of the eStargz-formatted golang base image. ```console $ docker buildx build --load -t hello /tmp/ctx/ $ docker run --rm hello Hello, world! ``` ### Kaniko #### Building eStargz Kaniko >= v1.5.0 creates eStargz images when `GGCR_EXPERIMENT_ESTARGZ=1` is specified. See [`README.md`](/README.md#building-estargz-images-using-kaniko) for details. ### ko ko >= v0.7.0 creates eStargz images when `GGCR_EXPERIMENT_ESTARGZ=1` is specified. Please see also [the docs in ko](https://github.com/ko-build/ko/blob/f70e3cad38c3bbd232f51604d922b8baff31144e/docs/advanced/faq.md#can-i-optimize-images-for-estargz-support). ## P2P image distribution ### IPFS See [`./ipfs.md`](./ipfs.md) ### Dragonfly Change the `/etc/containerd-stargz-grpc/config.toml` configuration to make dragonfly as registry mirror. `127.0.0.1:65001` is the proxy address of dragonfly peer, and the `X-Dragonfly-Registry` header is the address of origin registry, which is provided for dragonfly to download the images. ```toml [[resolver.host."docker.io".mirrors]] host = "127.0.0.1:65001" insecure = true [resolver.host."docker.io".mirrors.header] X-Dragonfly-Registry = ["https://index.docker.io"] ``` For more details about dragonfly as registry mirror, refer to [How to use Dragonfly With eStargz](https://d7y.io/docs/setup/integration/stargz/). ## Registry-side conversion of eStargz ### Harbor See the docs in Harbor: https://github.com/goharbor/acceleration-service stargz-snapshotter-0.14.3/docs/ipfs.md000066400000000000000000000171301440204344700177000ustar00rootroot00000000000000# Running containers on IPFS (experimental) :information_source: This document isn't for Kubernetes environemnt. For information about node-to-node image sharing on Kubernetes, please refer to [the docs in nerdctl project](https://github.com/containerd/nerdctl/tree/main/examples/nerdctl-ipfs-registry-kubernetes). You can run OCI-compatible container images on IPFS with lazy pulling. To enable this feature, add the following configuration to `config.toml` of Stargz Snapsohtter (typically located at `/etc/containerd-stargz-grpc/config.toml`). ```toml ipfs = true ``` > NOTE: containerd-stargz-grpc tries to connect to IPFS API written in `~/.ipfs/api` (or the file under `$IPFS_PATH` if configured) via HTTP (not HTTPS). ## IPFS-enabled OCI Image For obtaining IPFS-enabled OCI Image, each descriptor in an OCI image must contain the following [IPFS URL](https://docs.ipfs.io/how-to/address-ipfs-on-web/#native-urls) in `urls` field. ``` ipfs:// ``` `` is the Base32 case-insensitive CIDv1 of the blob that the descriptor points to. An image is represented as a CID pointing to the OCI descriptor of the top-level blob of the image (i.e. image index). The following is an example OCI descriptor pointing to the image index of an IPFS-enabled image: ```console # ipfs cat bafkreie7754qk7fl56ebauawdgfuqqa3kdd7sotvuhsm6wbz3qin6ssw3a | jq { "mediaType": "application/vnd.oci.image.index.v1+json", "digest": "sha256:80d6aec48c0a74635a5f3dc106328c1673afaa21ed6e1270a9a44de66e8ffa55", "size": 314, "urls": [ "ipfs://bafkreiea22xmjdakorrvuxz5yeddfdawoox2uipnnyjhbknejxtg5d72ku" ] } ``` ## Lazy pulling with Stargz Snapshotter If layer descriptors of an image contain the URLs described above and these blobs are formatted as eStargz, Stargz Snapshotter mounts them from IPFS to the container's rootfs using FUSE with lazy pulling support. Thus container can startup without waiting for the entire image contents being locally available. Necessary chunks of contents (e.g. each file in the rootfs) are fetched from IPFS on-demand. If the container image isn't eStargz or the snapshotter isn't Stargz Snapshotter (e.g. overlayfs snapshotter), containerd fetches the entire image contents from IPFS and unpacks it to the local directory before starting the container. Thus possibly you'll see slow container cold-start. ## Examples This section describes some examples of storing images to IPFS and running them as containers. Make sure IPFS daemon runs on your node. For example, you can run an IPFS daemon using the following command. ``` ipfs daemon ``` :information_source: If you don't want IPFS to communicate with nodes on the internet, you can run IPFS daemon in offline mode using `--offline` flag or you can create a private IPFS network as described in Appendix 1. ### Running a container with lazy pulling `ctr-remote image ipfs-push` command converts an image to IPFS-enabled eStargz and stores it to IPFS. ```console # ctr-remote i pull ghcr.io/stargz-containers/python:3.9-org # ctr-remote i ipfs-push ghcr.io/stargz-containers/python:3.9-org bafkreie7754qk7fl56ebauawdgfuqqa3kdd7sotvuhsm6wbz3qin6ssw3a ``` The printed IPFS CID (`bafkreie7754qk7fl56ebauawdgfuqqa3kdd7sotvuhsm6wbz3qin6ssw3a`) points to an OCI descriptor which points to the image index of the added image. ```console # ipfs cat bafkreie7754qk7fl56ebauawdgfuqqa3kdd7sotvuhsm6wbz3qin6ssw3a | jq { "mediaType": "application/vnd.oci.image.index.v1+json", "digest": "sha256:80d6aec48c0a74635a5f3dc106328c1673afaa21ed6e1270a9a44de66e8ffa55", "size": 314, "urls": [ "ipfs://bafkreiea22xmjdakorrvuxz5yeddfdawoox2uipnnyjhbknejxtg5d72ku" ] } ``` You can run this image from IPFS using that CID as an image reference for `ctr-remote image rpull`. `--ipfs` option is needed for enabling this. Note that `ctr-remote` accepts an IPFS CID as the image reference but doesn't support `/ipfs`-prefixed path as of now. We're working on eliminating this limitation. ```console # time ( ctr-remote i rpull --ipfs bafkreie7754qk7fl56ebauawdgfuqqa3kdd7sotvuhsm6wbz3qin6ssw3a && \ ctr-remote run --snapshotter=stargz --rm -t bafkreie7754qk7fl56ebauawdgfuqqa3kdd7sotvuhsm6wbz3qin6ssw3a foo python -c 'print("Hello, World!")' ) fetching sha256:80d6aec4... application/vnd.oci.image.index.v1+json fetching sha256:16d36f86... application/vnd.oci.image.manifest.v1+json fetching sha256:236b4bd7... application/vnd.oci.image.config.v1+json Hello, World! real 0m1.099s user 0m0.047s sys 0m0.037s ``` ### Running a container without lazy pulling Though eStargz-based lazy pulling is highly recommended for speeding up the container startup time, you can store and run non-eStargz images with IPFS as well. In this case, containerd fetches the entire image contents from IPFS and unpacks it to the local directory before starting the container. You can add a non-eStargz image to IPFS using `--estargz=false` option. ```console # ctr-remote i pull ghcr.io/stargz-containers/python:3.9-org # ctr-remote i ipfs-push --estargz=false ghcr.io/stargz-containers/python:3.9-org bafkreienbir4knaofs3o5f57kqw2the2v7zdhdlzpkq346mipuopwvqhty ``` You don't need FUSE nor stargz snapshotter for running this image but will see slow container cold-start. This example uses overlayfs snapshotter of containerd. ```console # time ( ctr-remote i rpull --snapshotter=overlayfs --ipfs bafkreienbir4knaofs3o5f57kqw2the2v7zdhdlzpkq346mipuopwvqhty && \ ctr-remote run --snapshotter=overlayfs --rm -t bafkreienbir4knaofs3o5f57kqw2the2v7zdhdlzpkq346mipuopwvqhty foo python -c 'print("Hello, World!")' ) fetching sha256:7240ac9f... application/vnd.oci.image.index.v1+json fetching sha256:17dc54f4... application/vnd.oci.image.manifest.v1+json fetching sha256:6f1289b1... application/vnd.oci.image.config.v1+json fetching sha256:9476e460... application/vnd.oci.image.layer.v1.tar+gzip fetching sha256:64c0f10e... application/vnd.oci.image.layer.v1.tar+gzip fetching sha256:4c25b309... application/vnd.oci.image.layer.v1.tar+gzip fetching sha256:942374d5... application/vnd.oci.image.layer.v1.tar+gzip fetching sha256:3fff52a3... application/vnd.oci.image.layer.v1.tar+gzip fetching sha256:5cf06daf... application/vnd.oci.image.layer.v1.tar+gzip fetching sha256:419e258e... application/vnd.oci.image.layer.v1.tar+gzip fetching sha256:1acf5650... application/vnd.oci.image.layer.v1.tar+gzip fetching sha256:b95c0dd0... application/vnd.oci.image.layer.v1.tar+gzip Hello, World! real 0m11.320s user 0m0.556s sys 0m0.280s ``` ## Appendix 1: Creating IPFS private network You can create a private IPFS network as described in the official docs. - https://github.com/ipfs/go-ipfs/blob/v0.10.0/docs/experimental-features.md#private-networks The following is the summary. First, generate a key and save it to `~/.ipfs/swarm.key` (or under `$IPFS_PATH` if configured) of nodes you want to have in the network. IPFS only connects to peers having this key. ``` go install github.com/Kubuxu/go-ipfs-swarm-key-gen/ipfs-swarm-key-gen@latest ~/go/bin/ipfs-swarm-key-gen > ~/.ipfs/swarm.key ``` Select nodes as a bootstrap nodes. IPFS daemons learn about the peers on the private network from them. Configure all non-bootstrap nodes to recognize only our bootstrap nodes instead of public ones like the following example. ``` ipfs bootstrap rm --all ipfs bootstrap add /ip4//tcp/4001/ipfs/ ``` :information_source: You can get Peer ID of a node by `ipfs config show | grep "PeerID"`. Finally, start all nodes in the private network. ``` export LIBP2P_FORCE_PNET=1 ipfs daemon ``` `LIBP2P_FORCE_PNET=1` makes sure that the daemon uses the private network and fails if the private network isn't configured. stargz-snapshotter-0.14.3/docs/overview.md000066400000000000000000000272101440204344700206050ustar00rootroot00000000000000# Containerd Stargz Snapshotter Plugin Overview __Before get through this overview document, we recommend you to read [README](../README.md).__ Pulling image is one of the time-consuming steps in the container startup process. In containerd community, we have had a lot of discussions to address this issue as the following, - [#3731 Support remote snapshotter to speed up image pulling](https://github.com/containerd/containerd/issues/3731) - [#2968 Support `Prepare` for existing snapshots in Snapshotter interface](https://github.com/containerd/containerd/issues/2968) - [#2943 remote filesystem snapshotter](https://github.com/containerd/containerd/issues/2943) The solution for the fast image distribution is called *Remote Snapshotter* plugin. This prepares container's rootfs layers by directly mounting from remote stores instead of downloading and unpacking the entire image contents. The actual image contents can be fetched *lazily* so runtimes can startup containers before the entire image contents to be locally available. We call these remotely mounted layers as *remote snapshots*. *Stargz Snapshotter* is a remote snapshotter plugin implementation which supports standard compatible remote snapshots functionality. This snapshotter leverages [eStargz](/docs/stargz-estargz.md) image, which is lazily-pullable and still standard-compatible. Because of this compatibility, eStargz image can be pushed to and lazily pulled from [OCI](https://github.com/opencontainers/distribution-spec)/[Docker](https://docs.docker.com/registry/spec/api/) registries (e.g. ghcr.io). Furthermore, images can run even on eStargz-agnostic runtimes (e.g. Docker). When you run a container image and it is formatted by eStargz, stargz snapshotter prepares container's rootfs layers as remote snapshots by mounting layers from the registry to the node, instead of pulling the entire image contents. This document gives you a high-level overview of stargz snapshotter. ![overview](/docs/images/overview01.png) ## Stargz Snapshotter proxy plugin Stargz snapshotter is implemented as a [proxy plugin](https://github.com/containerd/containerd/blob/04985039cede6aafbb7dfb3206c9c4d04e2f924d/PLUGINS.md#proxy-plugins) daemon (`containerd-stargz-grpc`) for containerd. When containerd starts a container, it queries the rootfs snapshots to stargz snapshotter daemon through an unix socket. This snapshotter remotely mounts queried eStargz layers from registries to the node and provides these mount points as remote snapshots to containerd. Containerd recognizes this plugin through an unix socket specified in the configuration file (e.g. `/etc/containerd/config.toml`). Stargz snapshotter can also be used through Kubernetes CRI by specifying the snapshotter name in the CRI plugin configuration. We assume that you are using containerd (> v1.4.2). ```toml version = 2 # Plug stargz snapshotter into containerd # Containerd recognizes stargz snapshotter through specified socket address. # The specified address below is the default which stargz snapshotter listen to. [proxy_plugins] [proxy_plugins.stargz] type = "snapshot" address = "/run/containerd-stargz-grpc/containerd-stargz-grpc.sock" # Use stargz snapshotter through CRI [plugins."io.containerd.grpc.v1.cri".containerd] snapshotter = "stargz" disable_snapshot_annotations = false ``` This repo contains [a Dockerfile as a KinD node image](/Dockerfile) which includes the above configuration. ## State directory Stargz snapshotter mounts eStargz layers from registries to the node using FUSE. The all files metadata in the image are preserved on the filesystem and files contents are fetched from registries on demand. At the root of the filesystem, there is a *state directory* (`/.stargz-snapshotter`) for status monitoring for the filesystem. This directory is hidden from `getdents(2)` so you can't see this with `ls -a /`. Instead, you can directly access the directory by specifying the path (`/.stargz-snapshotter`). State directory contains JSON-formatted metadata files for each layer. In the following example, metadata JSON files for overlayed 7 layers are visible. In each metadata JSON file, the following fields are contained, - `digest` contains the layer digest. This is the same value as that in the image's manifest. - `size` is the size bytes of the layer. - `fetchedSize` and `fetchedPercent` indicate how many bytes have been fetched for this layer. Stargz snapshotter aggressively downloads this layer in the background - unless configured otherwise - so these values gradually increase. When `fetchedPercent` reaches to `100` percents, this layer has been fully downloaded on the node and no further access will occur for reading files. Note that the state directory layout and the metadata JSON structure are subject to change. ```console # ctr-remote run --rm -t --snapshotter=stargz docker.io/stargz/golang:1.12.9-esgz test /bin/bash root@1d43741b8d29:/go# ls -a / . bin dev go lib media opt root sbin sys usr .. boot etc home lib64 mnt proc run srv tmp var root@1d43741b8d29:/go# ls /.stargz-snapshotter/* /.stargz-snapshotter/sha256:2b1fc65cafe05b65acc9e9f186df4dd81ae74c58ef73d89ecfc15e7286b3e960.json /.stargz-snapshotter/sha256:42d56485c1f672e394a02855048774621731c8fd44a54dc816a421a3a52b8482.json /.stargz-snapshotter/sha256:6a5826d877de5c93fb4a9e1d0369cfdef6d43df2610562501ebf42e4bcb2ef73.json /.stargz-snapshotter/sha256:a4d35801573274df19d9c2ae2aed80eba96d5aa69a38c464e1f01f9abf81e34e.json /.stargz-snapshotter/sha256:ab13100112faac6e04d2da2281db3df942efc8cef2532ab2cac688c6232944d8.json /.stargz-snapshotter/sha256:e8cc31024eb09fe216ad906392aec139038330c6d29dfd3fe5c81c4b2dd21430.json /.stargz-snapshotter/sha256:f077511be7d385c17ba88980379c5cd0aab7068844dffa7a1cefbf68cc3daea3.json root@1d43741b8d29:/go# cat /.stargz-snapshotter/* {"digest":"sha256:2b1fc65cafe05b65acc9e9f186df4dd81ae74c58ef73d89ecfc15e7286b3e960","size":131339690,"fetchedSize":7939690,"fetchedPercent":6.045156646859757} {"digest":"sha256:42d56485c1f672e394a02855048774621731c8fd44a54dc816a421a3a52b8482","size":10047608,"fetchedSize":2047608,"fetchedPercent":20.379059374131632} {"digest":"sha256:6a5826d877de5c93fb4a9e1d0369cfdef6d43df2610562501ebf42e4bcb2ef73","size":54352828,"fetchedSize":2302828,"fetchedPercent":4.236813584014432} {"digest":"sha256:a4d35801573274df19d9c2ae2aed80eba96d5aa69a38c464e1f01f9abf81e34e","size":70359295,"fetchedSize":2259295,"fetchedPercent":3.211082487395588} {"digest":"sha256:ab13100112faac6e04d2da2281db3df942efc8cef2532ab2cac688c6232944d8","size":7890588,"fetchedSize":2140588,"fetchedPercent":27.12837116828302} {"digest":"sha256:e8cc31024eb09fe216ad906392aec139038330c6d29dfd3fe5c81c4b2dd21430","size":52934435,"fetchedSize":2634435,"fetchedPercent":4.976788738748227} {"digest":"sha256:f077511be7d385c17ba88980379c5cd0aab7068844dffa7a1cefbf68cc3daea3","size":580,"fetchedSize":580,"fetchedPercent":100} ``` ## Registry-related configuration You can configure stargz snapshotter for accessing registries with custom configurations. The config file must be formatted with TOML and can be passed to stargz snapshotter with `--config` option. ### Authentication Stargz snapshotter doesn't share private registries creds with containerd. Instead, this supports authentication in the following methods, - Using `$DOCKER_CONFIG` or `~/.docker/config.json` - Proxying and scanning CRI Image Service API - Using Kubernetes secrets (type = `kubernetes.io/dockerconfigjson`) #### dockerconfig-based authentication By default, This snapshotter tries to get creds from `$DOCKER_CONFIG` or `~/.docker/config.json`. Following example enables stargz snapshotter to access to private registries using `docker login` command. [`nerdctl login`](https://github.com/containerd/nerdctl) can also be used for this. Stargz snapshotter doesn't share credentials with containerd so credentials specified by `ctr-remote`'s `--user` option in the example is just for containerd. ```console # docker login (Enter username and password) # ctr-remote image rpull --user : docker.io//ubuntu:18.04 ``` #### CRI-based authentication Following configuration (typically located at `/etc/containerd-stargz-grpc/config.toml`) enables stargz snapshotter to pull private images on Kubernetes. The snapshotter works as a proxy of CRI Image Service and exposes CRI Image Service API on the snapshotter's unix socket (i.e. `/run/containerd-stargz-grpc/containerd-stargz-grpc.sock`). The snapshotter acquires registry creds by scanning requests. You must specify `--image-service-endpoint=unix:///run/containerd-stargz-grpc/containerd-stargz-grpc.sock` option to kubelet. ```toml # Stargz Snapshotter proxies CRI Image Service into containerd socket. [cri_keychain] enable_keychain = true image_service_path = "/run/containerd/containerd.sock" ``` #### kubeconfig-based authentication This is another way to enable lazy pulling of private images on Kubernetes. Following configuration (typically located at `/etc/containerd-stargz-grpc/config.toml`) enables stargz snapshotter to access to private registries using kubernetes secrets (type = `kubernetes.io/dockerconfigjson`) in the cluster using kubeconfig files. You can specify the path of kubeconfig file using `kubeconfig_path` option. It's no problem that the specified file doesn't exist when this snapshotter starts. In this case, snapsohtter polls the file until actually provided. This is useful for some environments (e.g. single node cluster with containerized apiserver) where stargz snapshotter needs to start before everything, including booting containerd/kubelet/apiserver and configuring users/roles. If no `kubeconfig_path` is specified, snapshotter searches kubeconfig files from `$KUBECONFIG` or `~/.kube/config`. ```toml # Use Kubernetes secrets accessible by the kubeconfig `/etc/kubernetes/snapshotter/config.conf`. [kubeconfig_keychain] enable_keychain = true kubeconfig_path = "/etc/kubernetes/snapshotter/config.conf" ``` Please note that kubeconfig-based authentication requires additional privilege (i.e. kubeconfig to list/watch secrets) to the node. And this doesn't work if kubelet retrieve creds from somewhere not API server (e.g. [credential provider](https://kubernetes.io/docs/tasks/kubelet-credential-provider/kubelet-credential-provider/)). ### Registry mirrors and insecure connection You can also configure mirrored registries and insecure connection. The hostname used as a mirror host can be specified using `host` option. If an optional field `insecure` is `true`, snapshotter tries to connect to the registry using plain HTTP instead of HTTPS. ```toml # Use `mirrorhost.io` as a mirrored host of `exampleregistry.io` and # use plain HTTP for connecting to the mirror host. [[resolver.host."exampleregistry.io".mirrors]] host = "mirrorhost.io" insecure = true # Use plain HTTP for connecting to `exampleregistry.io`. [[resolver.host."exampleregistry.io".mirrors]] host = "exampleregistry.io" insecure = true ``` `header` field allows to set headers to send to the server. ```toml [[resolver.host."registry2:5000".mirrors]] host = "registry2:5000" [resolver.host."registry2:5000".mirrors.header] x-custom-2 = ["value3", "value4"] ``` > NOTE: Headers aren't passed to the redirected location. The config file can be passed to stargz snapshotter using `containerd-stargz-grpc`'s `--config` option. ## Make your remote snapshotter It isn't difficult for you to implement your remote snapshotter using [our general snapshotter package](/snapshot) without considering the protocol between that and containerd. You can configure the remote snapshotter with your `FileSystem` structure which you want to use as a backend filesystem. [Our snapshotter command](/cmd/containerd-stargz-grpc/main.go) is a good example for the integration. stargz-snapshotter-0.14.3/docs/pre-converted-images.md000066400000000000000000000153771440204344700227720ustar00rootroot00000000000000# Trying pre-converted images We have several pre-converted stargz images on Github Container Registry (`ghcr.io/stargz-containers`), mainly for benchmarking purpose. This document lists them. :information_source: You can build eStargz from Dockerfile using BuildKit, [using Docker Buildx](../README.md#building-estargz-images-using-buildkit) or [Kaniko](../README.md#building-estargz-images-using-kaniko). :information_source: You can convert arbitrary images into eStargz optimized for your workload, using [`ctr-remote` command](/docs/ctr-remote.md). :information_source: You can convert arbitrary images into eStargz on the registry-side, using [`estargz.kontain.me`](https://estargz.kontain.me). ## Pre-converted images :information_source: You can request new pre-converted images from our CI repository ([`github.com/stargz-containers/image-ci`](https://github.com/stargz-containers/image-ci)). In the following table, image names listed in `Image Name` contain the following suffixes based on the type of the image. - `org`: Legacy image copied from `docker.io/library` without optimization. Layers are normal tarballs. - `esgz`: eStargz-formatted version of the `org` images. `ctr-remote images optimize` command is used for the optimization. `Optimized Workload` column describes workloads used for building `esgz` images. We optimized these images for benchmarking which is based on [HelloBench](https://github.com/Tintri/hello-bench) so we specified "hello-world"-like workloads for the command. See [benchmarking script](/script/benchmark/hello-bench/src/hello.py) for the exact command option specified for `ctr-remote images optimize`. |Image Name|Optimized Workload| ---|--- |`ghcr.io/stargz-containers/alpine:3.15.3-org`|Executing `echo hello` on the shell| |`ghcr.io/stargz-containers/alpine:3.15.3-esgz`|Executing `echo hello` on the shell| |`ghcr.io/stargz-containers/drupal:9.3.9-org`|Code execution until up and ready message (`apache2 -D FOREGROUND`) is printed| |`ghcr.io/stargz-containers/drupal:9.3.9-esgz`|Code execution until up and ready message (`apache2 -D FOREGROUND`) is printed| |`ghcr.io/stargz-containers/fedora:35-org`|Executing `echo hello` on the shell| |`ghcr.io/stargz-containers/fedora:35-esgz`|Executing `echo hello` on the shell| |`ghcr.io/stargz-containers/gcc:11.2.0-org`|Compiling and executing a program which prints `hello`| |`ghcr.io/stargz-containers/gcc:11.2.0-esgz`|Compiling and executing a program which prints `hello`| |`ghcr.io/stargz-containers/golang:1.18-org`|Compiling and executing a program which prints `hello`| |`ghcr.io/stargz-containers/golang:1.18-esgz`|Compiling and executing a program which prints `hello`| |`ghcr.io/stargz-containers/jenkins:2.60.3-org`|Code execution until up and ready message (`Jenkins is fully up and running`) is printed| |`ghcr.io/stargz-containers/jenkins:2.60.3-esgz`|Code execution until up and ready message (`Jenkins is fully up and running`) is printed| |`ghcr.io/stargz-containers/jruby:9.3.4-org`|Printing `hello`| |`ghcr.io/stargz-containers/jruby:9.3.4-esgz`|Printing `hello`| |`ghcr.io/stargz-containers/node:17.8.0-org`|Printing `hello`| |`ghcr.io/stargz-containers/node:17.8.0-esgz`|Printing `hello`| |`ghcr.io/stargz-containers/perl:5.34.1-org`|Printing `hello`| |`ghcr.io/stargz-containers/perl:5.34.1-esgz`|Printing `hello`| |`ghcr.io/stargz-containers/php:8.1.4-org`|Printing `hello`| |`ghcr.io/stargz-containers/php:8.1.4-esgz`|Printing `hello`| |`ghcr.io/stargz-containers/pypy:3.9-org`|Printing `hello`| |`ghcr.io/stargz-containers/pypy:3.9-esgz`|Printing `hello`| |`ghcr.io/stargz-containers/python:3.10-org`|Printing `hello`| |`ghcr.io/stargz-containers/python:3.10-esgz`|Printing `hello`| |`ghcr.io/stargz-containers/r-base:4.1.3-org`|Printing `hello`| |`ghcr.io/stargz-containers/r-base:4.1.3-esgz`|Printing `hello`| |`ghcr.io/stargz-containers/redis:6.2.6-org`|Code execution until up and ready message (`Ready to accept connections`) is printed| |`ghcr.io/stargz-containers/redis:6.2.6-esgz`|Code execution until up and ready message (`Ready to accept connections`) is printed| |`ghcr.io/stargz-containers/rethinkdb:2.4.1-org`|Code execution until up and ready message (`Server ready`) is printed| |`ghcr.io/stargz-containers/rethinkdb:2.4.1-esgz`|Code execution until up and ready message (`Server ready`) is printed| |`ghcr.io/stargz-containers/tomcat:10.1.0-jdk17-openjdk-bullseye-org`|Code execution until up and ready message (`Server startup`) is printed| |`ghcr.io/stargz-containers/tomcat:10.1.0-jdk17-openjdk-bullseye-esgz`|Code execution until up and ready message (`Server startup`) is printed| |`ghcr.io/stargz-containers/postgres:14.2-org`|Code execution until up and ready message (`database system is ready to accept connections`) is printed| |`ghcr.io/stargz-containers/postgres:14.2-esgz`|Code execution until up and ready message (`database system is ready to accept connections`) is printed| |`ghcr.io/stargz-containers/wordpress:5.9.2-org`|Code execution until up and ready message (`apache2 -D FOREGROUND`) is printed| |`ghcr.io/stargz-containers/wordpress:5.9.2-esgz`|Code execution until up and ready message (`apache2 -D FOREGROUND`) is printed| |`ghcr.io/stargz-containers/mariadb:10.7.3-org`|Code execution until up and ready message (`mysqld: ready for connections`) is printed| |`ghcr.io/stargz-containers/mariadb:10.7.3-esgz`|Code execution until up and ready message (`mysqld: ready for connections`) is printed| |`ghcr.io/stargz-containers/php:8.1.4-apache-bullseye-org`|Code execution until up and ready message (`apache2 -D FOREGROUND`) is printed| |`ghcr.io/stargz-containers/php:8.1.4-apache-bullseye-esgz`|Code execution until up and ready message (`apache2 -D FOREGROUND`) is printed| |`ghcr.io/stargz-containers/rabbitmq:3.9.14-org`|Code execution until up and ready message (`Server startup complete`) is printed| |`ghcr.io/stargz-containers/rabbitmq:3.9.14-esgz`|Code execution until up and ready message (`Server startup complete`) is printed| |`ghcr.io/stargz-containers/elasticsearch:8.1.1-org`|Code execution until up and ready message (`started`) is printed| |`ghcr.io/stargz-containers/elasticsearch:8.1.1-esgz`|Code execution until up and ready message (`started`) is printed| |`ghcr.io/stargz-containers/nixos/nix:2.3.12-org`|Executing `echo hello` on the shell| |`ghcr.io/stargz-containers/nixos/nix:2.3.12-esgz`|Executing `echo hello` on the shell| ## lazy-pulling-enabled KinD node image You can enable lazy pulling of eStargz on [KinD](https://github.com/kubernetes-sigs/kind) using our prebuilt node image [`ghcr.io/containerd/stargz-snapshotter:${VERSION}-kind`](https://github.com/orgs/containerd/packages/container/package/stargz-snapshotter) namespace. Example: ```console $ kind create cluster --name stargz-demo --image ghcr.io/containerd/stargz-snapshotter:0.12.1-kind ``` Please refer to README for more details. stargz-snapshotter-0.14.3/docs/rootless.md000066400000000000000000000043671440204344700206210ustar00rootroot00000000000000# Rootless execution of stargz snapshotter This document lists links and information about how to run Stargz Snapshotter and Stargz Store from the non-root user. ## nerdctl (Stargz Snapshotter) Rootless Stargz Snapshotter for nerdctl can be installed via `containerd-rootless-setuptool.sh install-stargz` command. Please see [the doc in nerdctl repo](https://github.com/containerd/nerdctl/blob/v1.1.0/docs/rootless.md#stargz-snapshotter) for details. ## Podman (Stargz Store) > NOTE: This is an experimental configuration leveraging [`podman unshare`](https://docs.podman.io/en/latest/markdown/podman-unshare.1.html). Limitation: `--uidmap` of `podman run` doesn't work. First, allow podman using Stargz Store by adding the following store configuration. Put the configuration file to [`/etc/containers/storage.conf` or `$HOME/.config/containers/storage.conf`](https://github.com/containers/podman/blob/v4.3.1/docs/tutorials/rootless_tutorial.md#storageconf). > NOTE: Replace `/path/to/home` to the actual home directory. ``` [storage] driver = "overlay" [storage.options] additionallayerstores = ["/path/to/homedir/.local/share/stargz-store/store:ref"] ``` Start Stargz Store in the namespace managed by podman via [`podman unshare`](https://docs.podman.io/en/latest/markdown/podman-unshare.1.html) command. ``` $ podman unshare stargz-store --root $HOME/.local/share/stargz-store/data $HOME/.local/share/stargz-store/store & ``` Podman performs lazy pulling when it pulls eStargz images. ``` $ podman pull ghcr.io/stargz-containers/python:3.9-esgz ```

Creating systemd unit file for Stargz Store It's possible to create systemd unit file of Stargz Store for easily managing it. An example systemd unit file can be found [here](../script/podman/config/podman-rootless-stargz-store.service) After installing that file (e.g. to `$HOME/.config/systemd/user/`), start the service using `systemctl`. ``` $ systemctl --user start podman-rootless-stargz-store ```
## BuildKit (Stargz Snapshotter) BuildKit supports running Stargz Snapshotter from the non-root user. Please see [the doc in BuildKit repo](https://github.com/moby/buildkit/blob/8b132188aa7af944c813d02da63c93308d83cf75/docs/stargz-estargz.md) (unmerged 2023/1/18) for details. stargz-snapshotter-0.14.3/docs/smaller-estargz.md000066400000000000000000000102501440204344700220470ustar00rootroot00000000000000# Creating smaller eStargz images The following flags of `ctr-remote i convert` and `ctr-remote i optimize` allow users optionally creating smaller eStargz images. - `--estargz-external-toc`: Separate TOC JSON into another image (called "TOC image"). The result eStargz doesn't contain TOC so we can expect a smaller size than normal eStargz. - `--estargz-min-chunk-size`: The minimal number of bytes of data must be written in one gzip stream. If it's > 0, multiple files and chunks can be written into one gzip stream. Smaller number of gzip header and smaller size of the result blob can be expected. `--estargz-min-chunk-size=0` produces normal eStargz. ## `--estargz-external-toc` usage convert: ```console # ctr-remote i pull ghcr.io/stargz-containers/ubuntu:22.04 # ctr-remote i convert --oci --estargz --estargz-external-toc ghcr.io/stargz-containers/ubuntu:22.04 registry2:5000/ubuntu:22.04-ex ``` Layers in eStargz (`registry2:5000/ubuntu:22.04-ex`) don't contain TOC JSON. TOC image (`registry2:5000/ubuntu:22.04-ex-esgztoc`) contains TOC of all layers of the eStargz image. Suffix `-esgztoc` is automatically added to the image name by `ctr-remote`. Then push eStargz(`registry2:5000/ubuntu:22.04-ex`) and TOC image(`registry2:5000/ubuntu:22.04-ex-esgztoc`) to the same registry: ```console # ctr-remote i push --plain-http registry2:5000/ubuntu:22.04-ex # ctr-remote i push --plain-http registry2:5000/ubuntu:22.04-ex-esgztoc ``` Pull it lazily: ```console # ctr-remote i rpull --plain-http registry2:5000/ubuntu:22.04-ex fetching sha256:14fb0ea2... application/vnd.oci.image.index.v1+json fetching sha256:24471b45... application/vnd.oci.image.manifest.v1+json fetching sha256:d2e4737e... application/vnd.oci.image.config.v1+json # mount | grep "stargz on" stargz on /var/lib/containerd-stargz-grpc/snapshotter/snapshots/1/fs type fuse.rawBridge (rw,nodev,relatime,user_id=0,group_id=0,allow_other) ``` Stargz Snapshotter automatically refers to the TOC image on the same registry. ### optional `--estargz-keep-diff-id` flag for conversion without changing layer diffID `ctr-remote i convert` supports optional flag `--estargz-keep-diff-id` specified with `--estargz-external-toc`. This converts an image to eStargz without changing the diffID (uncompressed digest) so even eStargz-agnostic gzip decompressor (e.g. gunzip) can restore the original tar blob. ```console # ctr-remote i pull ghcr.io/stargz-containers/ubuntu:22.04 # ctr-remote i convert --oci --estargz --estargz-external-toc --estargz-keep-diff-id ghcr.io/stargz-containers/ubuntu:22.04 registry2:5000/ubuntu:22.04-ex-keepdiff # ctr-remote i push --plain-http registry2:5000/ubuntu:22.04-ex-keepdiff # ctr-remote i push --plain-http registry2:5000/ubuntu:22.04-ex-keepdiff-esgztoc # crane --insecure blob registry2:5000/ubuntu:22.04-ex-keepdiff@sha256:2dc39ba059dcd42ade30aae30147b5692777ba9ff0779a62ad93a74de02e3e1f | jq -r '.rootfs.diff_ids[]' sha256:7f5cbd8cc787c8d628630756bcc7240e6c96b876c2882e6fc980a8b60cdfa274 # crane blob ghcr.io/stargz-containers/ubuntu:22.04@sha256:2dc39ba059dcd42ade30aae30147b5692777ba9ff0779a62ad93a74de02e3e1f | jq -r '.rootfs.diff_ids[]' sha256:7f5cbd8cc787c8d628630756bcc7240e6c96b876c2882e6fc980a8b60cdfa274 ``` ## `--estargz-min-chunk-size` usage conversion: ```console # ctr-remote i pull ghcr.io/stargz-containers/ubuntu:22.04 # ctr-remote i convert --oci --estargz --estargz-min-chunk-size=50000 ghcr.io/stargz-containers/ubuntu:22.04 registry2:5000/ubuntu:22.04-chunk50000 # ctr-remote i push --plain-http registry2:5000/ubuntu:22.04-chunk50000 ``` Pull it lazily: ```console # ctr-remote i rpull --plain-http registry2:5000/ubuntu:22.04-chunk50000 fetching sha256:5d1409a2... application/vnd.oci.image.index.v1+json fetching sha256:859e2b50... application/vnd.oci.image.manifest.v1+json fetching sha256:c07a44b9... application/vnd.oci.image.config.v1+json # mount | grep "stargz on" stargz on /var/lib/containerd-stargz-grpc/snapshotter/snapshots/1/fs type fuse.rawBridge (rw,nodev,relatime,user_id=0,group_id=0,allow_other) ``` > NOTE: This flag creates an eStargz image with newly-added `innerOffset` funtionality of eStargz. Stargz Snapshotter < v0.13.0 cannot perform lazy pulling for the images created with this flag. stargz-snapshotter-0.14.3/docs/stargz-estargz.md000066400000000000000000000002171440204344700217240ustar00rootroot00000000000000# eStargz: Standard-Compatible Extensions to Tar.gz Layers for Lazy Pulling Container Images Moved to [`/docs/estargz.md`](/docs/estargz.md). stargz-snapshotter-0.14.3/docs/verification.md000066400000000000000000000001241440204344700214140ustar00rootroot00000000000000# Content Verification in eStargz Moved to [`/docs/estargz.md`](/docs/estargz.md). stargz-snapshotter-0.14.3/estargz/000077500000000000000000000000001440204344700171425ustar00rootroot00000000000000stargz-snapshotter-0.14.3/estargz/build.go000066400000000000000000000420261440204344700205740ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /* Copyright 2019 The Go Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. */ package estargz import ( "archive/tar" "bytes" "compress/gzip" "context" "errors" "fmt" "io" "os" "path" "runtime" "strings" "sync" "github.com/containerd/stargz-snapshotter/estargz/errorutil" "github.com/klauspost/compress/zstd" digest "github.com/opencontainers/go-digest" "golang.org/x/sync/errgroup" ) type options struct { chunkSize int compressionLevel int prioritizedFiles []string missedPrioritizedFiles *[]string compression Compression ctx context.Context minChunkSize int } type Option func(o *options) error // WithChunkSize option specifies the chunk size of eStargz blob to build. func WithChunkSize(chunkSize int) Option { return func(o *options) error { o.chunkSize = chunkSize return nil } } // WithCompressionLevel option specifies the gzip compression level. // The default is gzip.BestCompression. // This option will be ignored if WithCompression option is used. // See also: https://godoc.org/compress/gzip#pkg-constants func WithCompressionLevel(level int) Option { return func(o *options) error { o.compressionLevel = level return nil } } // WithPrioritizedFiles option specifies the list of prioritized files. // These files must be complete paths that are absolute or relative to "/" // For example, all of "foo/bar", "/foo/bar", "./foo/bar" and "../foo/bar" // are treated as "/foo/bar". func WithPrioritizedFiles(files []string) Option { return func(o *options) error { o.prioritizedFiles = files return nil } } // WithAllowPrioritizeNotFound makes Build continue the execution even if some // of prioritized files specified by WithPrioritizedFiles option aren't found // in the input tar. Instead, this records all missed file names to the passed // slice. func WithAllowPrioritizeNotFound(missedFiles *[]string) Option { return func(o *options) error { if missedFiles == nil { return fmt.Errorf("WithAllowPrioritizeNotFound: slice must be passed") } o.missedPrioritizedFiles = missedFiles return nil } } // WithCompression specifies compression algorithm to be used. // Default is gzip. func WithCompression(compression Compression) Option { return func(o *options) error { o.compression = compression return nil } } // WithContext specifies a context that can be used for clean canceleration. func WithContext(ctx context.Context) Option { return func(o *options) error { o.ctx = ctx return nil } } // WithMinChunkSize option specifies the minimal number of bytes of data // must be written in one gzip stream. // By increasing this number, one gzip stream can contain multiple files // and it hopefully leads to smaller result blob. // NOTE: This adds a TOC property that old reader doesn't understand. func WithMinChunkSize(minChunkSize int) Option { return func(o *options) error { o.minChunkSize = minChunkSize return nil } } // Blob is an eStargz blob. type Blob struct { io.ReadCloser diffID digest.Digester tocDigest digest.Digest } // DiffID returns the digest of uncompressed blob. // It is only valid to call DiffID after Close. func (b *Blob) DiffID() digest.Digest { return b.diffID.Digest() } // TOCDigest returns the digest of uncompressed TOC JSON. func (b *Blob) TOCDigest() digest.Digest { return b.tocDigest } // Build builds an eStargz blob which is an extended version of stargz, from a blob (gzip, zstd // or plain tar) passed through the argument. If there are some prioritized files are listed in // the option, these files are grouped as "prioritized" and can be used for runtime optimization // (e.g. prefetch). This function builds a blob in parallel, with dividing that blob into several // (at least the number of runtime.GOMAXPROCS(0)) sub-blobs. func Build(tarBlob *io.SectionReader, opt ...Option) (_ *Blob, rErr error) { var opts options opts.compressionLevel = gzip.BestCompression // BestCompression by default for _, o := range opt { if err := o(&opts); err != nil { return nil, err } } if opts.compression == nil { opts.compression = newGzipCompressionWithLevel(opts.compressionLevel) } layerFiles := newTempFiles() ctx := opts.ctx if ctx == nil { ctx = context.Background() } done := make(chan struct{}) defer close(done) go func() { select { case <-done: // nop case <-ctx.Done(): layerFiles.CleanupAll() } }() defer func() { if rErr != nil { if err := layerFiles.CleanupAll(); err != nil { rErr = fmt.Errorf("failed to cleanup tmp files: %v: %w", err, rErr) } } if cErr := ctx.Err(); cErr != nil { rErr = fmt.Errorf("error from context %q: %w", cErr, rErr) } }() tarBlob, err := decompressBlob(tarBlob, layerFiles) if err != nil { return nil, err } entries, err := sortEntries(tarBlob, opts.prioritizedFiles, opts.missedPrioritizedFiles) if err != nil { return nil, err } var tarParts [][]*entry if opts.minChunkSize > 0 { // Each entry needs to know the size of the current gzip stream so they // cannot be processed in parallel. tarParts = [][]*entry{entries} } else { tarParts = divideEntries(entries, runtime.GOMAXPROCS(0)) } writers := make([]*Writer, len(tarParts)) payloads := make([]*os.File, len(tarParts)) var mu sync.Mutex var eg errgroup.Group for i, parts := range tarParts { i, parts := i, parts // builds verifiable stargz sub-blobs eg.Go(func() error { esgzFile, err := layerFiles.TempFile("", "esgzdata") if err != nil { return err } sw := NewWriterWithCompressor(esgzFile, opts.compression) sw.ChunkSize = opts.chunkSize sw.MinChunkSize = opts.minChunkSize if sw.needsOpenGzEntries == nil { sw.needsOpenGzEntries = make(map[string]struct{}) } for _, f := range []string{PrefetchLandmark, NoPrefetchLandmark} { sw.needsOpenGzEntries[f] = struct{}{} } if err := sw.AppendTar(readerFromEntries(parts...)); err != nil { return err } mu.Lock() writers[i] = sw payloads[i] = esgzFile mu.Unlock() return nil }) } if err := eg.Wait(); err != nil { rErr = err return nil, err } tocAndFooter, tocDgst, err := closeWithCombine(writers...) if err != nil { rErr = err return nil, err } var rs []io.Reader for _, p := range payloads { fs, err := fileSectionReader(p) if err != nil { return nil, err } rs = append(rs, fs) } diffID := digest.Canonical.Digester() pr, pw := io.Pipe() go func() { r, err := opts.compression.Reader(io.TeeReader(io.MultiReader(append(rs, tocAndFooter)...), pw)) if err != nil { pw.CloseWithError(err) return } defer r.Close() if _, err := io.Copy(diffID.Hash(), r); err != nil { pw.CloseWithError(err) return } pw.Close() }() return &Blob{ ReadCloser: readCloser{ Reader: pr, closeFunc: layerFiles.CleanupAll, }, tocDigest: tocDgst, diffID: diffID, }, nil } // closeWithCombine takes unclosed Writers and close them. This also returns the // toc that combined all Writers into. // Writers doesn't write TOC and footer to the underlying writers so they can be // combined into a single eStargz and tocAndFooter returned by this function can // be appended at the tail of that combined blob. func closeWithCombine(ws ...*Writer) (tocAndFooterR io.Reader, tocDgst digest.Digest, err error) { if len(ws) == 0 { return nil, "", fmt.Errorf("at least one writer must be passed") } for _, w := range ws { if w.closed { return nil, "", fmt.Errorf("writer must be unclosed") } defer func(w *Writer) { w.closed = true }(w) if err := w.closeGz(); err != nil { return nil, "", err } if err := w.bw.Flush(); err != nil { return nil, "", err } } var ( mtoc = new(JTOC) currentOffset int64 ) mtoc.Version = ws[0].toc.Version for _, w := range ws { for _, e := range w.toc.Entries { // Recalculate Offset of non-empty files/chunks if (e.Type == "reg" && e.Size > 0) || e.Type == "chunk" { e.Offset += currentOffset } mtoc.Entries = append(mtoc.Entries, e) } if w.toc.Version > mtoc.Version { mtoc.Version = w.toc.Version } currentOffset += w.cw.n } return tocAndFooter(ws[0].compressor, mtoc, currentOffset) } func tocAndFooter(compressor Compressor, toc *JTOC, offset int64) (io.Reader, digest.Digest, error) { buf := new(bytes.Buffer) tocDigest, err := compressor.WriteTOCAndFooter(buf, offset, toc, nil) if err != nil { return nil, "", err } return buf, tocDigest, nil } // divideEntries divides passed entries to the parts at least the number specified by the // argument. func divideEntries(entries []*entry, minPartsNum int) (set [][]*entry) { var estimatedSize int64 for _, e := range entries { estimatedSize += e.header.Size } unitSize := estimatedSize / int64(minPartsNum) var ( nextEnd = unitSize offset int64 ) set = append(set, []*entry{}) for _, e := range entries { set[len(set)-1] = append(set[len(set)-1], e) offset += e.header.Size if offset > nextEnd { set = append(set, []*entry{}) nextEnd += unitSize } } return } var errNotFound = errors.New("not found") // sortEntries reads the specified tar blob and returns a list of tar entries. // If some of prioritized files are specified, the list starts from these // files with keeping the order specified by the argument. func sortEntries(in io.ReaderAt, prioritized []string, missedPrioritized *[]string) ([]*entry, error) { // Import tar file. intar, err := importTar(in) if err != nil { return nil, fmt.Errorf("failed to sort: %w", err) } // Sort the tar file respecting to the prioritized files list. sorted := &tarFile{} for _, l := range prioritized { if err := moveRec(l, intar, sorted); err != nil { if errors.Is(err, errNotFound) && missedPrioritized != nil { *missedPrioritized = append(*missedPrioritized, l) continue // allow not found } return nil, fmt.Errorf("failed to sort tar entries: %w", err) } } if len(prioritized) == 0 { sorted.add(&entry{ header: &tar.Header{ Name: NoPrefetchLandmark, Typeflag: tar.TypeReg, Size: int64(len([]byte{landmarkContents})), }, payload: bytes.NewReader([]byte{landmarkContents}), }) } else { sorted.add(&entry{ header: &tar.Header{ Name: PrefetchLandmark, Typeflag: tar.TypeReg, Size: int64(len([]byte{landmarkContents})), }, payload: bytes.NewReader([]byte{landmarkContents}), }) } // Dump all entry and concatinate them. return append(sorted.dump(), intar.dump()...), nil } // readerFromEntries returns a reader of tar archive that contains entries passed // through the arguments. func readerFromEntries(entries ...*entry) io.Reader { pr, pw := io.Pipe() go func() { tw := tar.NewWriter(pw) defer tw.Close() for _, entry := range entries { if err := tw.WriteHeader(entry.header); err != nil { pw.CloseWithError(fmt.Errorf("Failed to write tar header: %v", err)) return } if _, err := io.Copy(tw, entry.payload); err != nil { pw.CloseWithError(fmt.Errorf("Failed to write tar payload: %v", err)) return } } pw.Close() }() return pr } func importTar(in io.ReaderAt) (*tarFile, error) { tf := &tarFile{} pw, err := newCountReadSeeker(in) if err != nil { return nil, fmt.Errorf("failed to make position watcher: %w", err) } tr := tar.NewReader(pw) // Walk through all nodes. for { // Fetch and parse next header. h, err := tr.Next() if err != nil { if err == io.EOF { break } else { return nil, fmt.Errorf("failed to parse tar file, %w", err) } } switch cleanEntryName(h.Name) { case PrefetchLandmark, NoPrefetchLandmark: // Ignore existing landmark continue } // Add entry. If it already exists, replace it. if _, ok := tf.get(h.Name); ok { tf.remove(h.Name) } tf.add(&entry{ header: h, payload: io.NewSectionReader(in, pw.currentPos(), h.Size), }) } return tf, nil } func moveRec(name string, in *tarFile, out *tarFile) error { name = cleanEntryName(name) if name == "" { // root directory. stop recursion. if e, ok := in.get(name); ok { // entry of the root directory exists. we should move it as well. // this case will occur if tar entries are prefixed with "./", "/", etc. out.add(e) in.remove(name) } return nil } _, okIn := in.get(name) _, okOut := out.get(name) if !okIn && !okOut { return fmt.Errorf("file: %q: %w", name, errNotFound) } parent, _ := path.Split(strings.TrimSuffix(name, "/")) if err := moveRec(parent, in, out); err != nil { return err } if e, ok := in.get(name); ok && e.header.Typeflag == tar.TypeLink { if err := moveRec(e.header.Linkname, in, out); err != nil { return err } } if e, ok := in.get(name); ok { out.add(e) in.remove(name) } return nil } type entry struct { header *tar.Header payload io.ReadSeeker } type tarFile struct { index map[string]*entry stream []*entry } func (f *tarFile) add(e *entry) { if f.index == nil { f.index = make(map[string]*entry) } f.index[cleanEntryName(e.header.Name)] = e f.stream = append(f.stream, e) } func (f *tarFile) remove(name string) { name = cleanEntryName(name) if f.index != nil { delete(f.index, name) } var filtered []*entry for _, e := range f.stream { if cleanEntryName(e.header.Name) == name { continue } filtered = append(filtered, e) } f.stream = filtered } func (f *tarFile) get(name string) (e *entry, ok bool) { if f.index == nil { return nil, false } e, ok = f.index[cleanEntryName(name)] return } func (f *tarFile) dump() []*entry { return f.stream } type readCloser struct { io.Reader closeFunc func() error } func (rc readCloser) Close() error { return rc.closeFunc() } func fileSectionReader(file *os.File) (*io.SectionReader, error) { info, err := file.Stat() if err != nil { return nil, err } return io.NewSectionReader(file, 0, info.Size()), nil } func newTempFiles() *tempFiles { return &tempFiles{} } type tempFiles struct { files []*os.File filesMu sync.Mutex cleanupOnce sync.Once } func (tf *tempFiles) TempFile(dir, pattern string) (*os.File, error) { f, err := os.CreateTemp(dir, pattern) if err != nil { return nil, err } tf.filesMu.Lock() tf.files = append(tf.files, f) tf.filesMu.Unlock() return f, nil } func (tf *tempFiles) CleanupAll() (err error) { tf.cleanupOnce.Do(func() { err = tf.cleanupAll() }) return } func (tf *tempFiles) cleanupAll() error { tf.filesMu.Lock() defer tf.filesMu.Unlock() var allErr []error for _, f := range tf.files { if err := f.Close(); err != nil { allErr = append(allErr, err) } if err := os.Remove(f.Name()); err != nil { allErr = append(allErr, err) } } tf.files = nil return errorutil.Aggregate(allErr) } func newCountReadSeeker(r io.ReaderAt) (*countReadSeeker, error) { pos := int64(0) return &countReadSeeker{r: r, cPos: &pos}, nil } type countReadSeeker struct { r io.ReaderAt cPos *int64 mu sync.Mutex } func (cr *countReadSeeker) Read(p []byte) (int, error) { cr.mu.Lock() defer cr.mu.Unlock() n, err := cr.r.ReadAt(p, *cr.cPos) if err == nil { *cr.cPos += int64(n) } return n, err } func (cr *countReadSeeker) Seek(offset int64, whence int) (int64, error) { cr.mu.Lock() defer cr.mu.Unlock() switch whence { default: return 0, fmt.Errorf("Unknown whence: %v", whence) case io.SeekStart: case io.SeekCurrent: offset += *cr.cPos case io.SeekEnd: return 0, fmt.Errorf("Unsupported whence: %v", whence) } if offset < 0 { return 0, fmt.Errorf("invalid offset") } *cr.cPos = offset return offset, nil } func (cr *countReadSeeker) currentPos() int64 { cr.mu.Lock() defer cr.mu.Unlock() return *cr.cPos } func decompressBlob(org *io.SectionReader, tmp *tempFiles) (*io.SectionReader, error) { if org.Size() < 4 { return org, nil } src := make([]byte, 4) if _, err := org.Read(src); err != nil && err != io.EOF { return nil, err } var dR io.Reader if bytes.Equal([]byte{0x1F, 0x8B, 0x08}, src[:3]) { // gzip dgR, err := gzip.NewReader(io.NewSectionReader(org, 0, org.Size())) if err != nil { return nil, err } defer dgR.Close() dR = io.Reader(dgR) } else if bytes.Equal([]byte{0x28, 0xb5, 0x2f, 0xfd}, src[:4]) { // zstd dzR, err := zstd.NewReader(io.NewSectionReader(org, 0, org.Size())) if err != nil { return nil, err } defer dzR.Close() dR = io.Reader(dzR) } else { // uncompressed return io.NewSectionReader(org, 0, org.Size()), nil } b, err := tmp.TempFile("", "uncompresseddata") if err != nil { return nil, err } if _, err := io.Copy(b, dR); err != nil { return nil, err } return fileSectionReader(b) } stargz-snapshotter-0.14.3/estargz/build_test.go000066400000000000000000000363031440204344700216340ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /* Copyright 2019 The Go Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. */ package estargz import ( "archive/tar" "bytes" "compress/gzip" "fmt" "io" "reflect" "testing" ) func TestSort(t *testing.T) { longname1 := longstring(120) longname2 := longstring(150) tests := []struct { name string in []tarEntry log []string // MUST NOT include "./" prefix here want []tarEntry wantFail bool allowMissedFiles []string }{ { name: "nolog", in: tarOf( file("foo.txt", "foo"), dir("bar/"), file("bar/baz.txt", "baz"), file("bar/bar.txt", "bar"), ), want: tarOf( noPrefetchLandmark(), file("foo.txt", "foo"), dir("bar/"), file("bar/baz.txt", "baz"), file("bar/bar.txt", "bar"), ), }, { name: "identical", in: tarOf( file("foo.txt", "foo"), dir("bar/"), file("bar/baz.txt", "baz"), file("bar/bar.txt", "bar"), file("bar/baa.txt", "baa"), ), log: []string{"foo.txt", "bar/baz.txt"}, want: tarOf( file("foo.txt", "foo"), dir("bar/"), file("bar/baz.txt", "baz"), prefetchLandmark(), file("bar/bar.txt", "bar"), file("bar/baa.txt", "baa"), ), }, { name: "shuffle_reg", in: tarOf( file("foo.txt", "foo"), file("baz.txt", "baz"), file("bar.txt", "bar"), file("baa.txt", "baa"), ), log: []string{"baa.txt", "bar.txt", "baz.txt"}, want: tarOf( file("baa.txt", "baa"), file("bar.txt", "bar"), file("baz.txt", "baz"), prefetchLandmark(), file("foo.txt", "foo"), ), }, { name: "shuffle_directory", in: tarOf( file("foo.txt", "foo"), dir("bar/"), file("bar/bar.txt", "bar"), file("bar/baa.txt", "baa"), dir("baz/"), file("baz/baz1.txt", "baz"), file("baz/baz2.txt", "baz"), dir("baz/bazbaz/"), file("baz/bazbaz/bazbaz_b.txt", "baz"), file("baz/bazbaz/bazbaz_a.txt", "baz"), ), log: []string{"baz/bazbaz/bazbaz_a.txt", "baz/baz2.txt", "foo.txt"}, want: tarOf( dir("baz/"), dir("baz/bazbaz/"), file("baz/bazbaz/bazbaz_a.txt", "baz"), file("baz/baz2.txt", "baz"), file("foo.txt", "foo"), prefetchLandmark(), dir("bar/"), file("bar/bar.txt", "bar"), file("bar/baa.txt", "baa"), file("baz/baz1.txt", "baz"), file("baz/bazbaz/bazbaz_b.txt", "baz"), ), }, { name: "shuffle_link", in: tarOf( file("foo.txt", "foo"), file("baz.txt", "baz"), link("bar.txt", "baz.txt"), file("baa.txt", "baa"), ), log: []string{"baz.txt"}, want: tarOf( file("baz.txt", "baz"), prefetchLandmark(), file("foo.txt", "foo"), link("bar.txt", "baz.txt"), file("baa.txt", "baa"), ), }, { name: "longname", in: tarOf( file("foo.txt", "foo"), file(longname1, "test"), dir("bar/"), file("bar/bar.txt", "bar"), file("bar/baa.txt", "baa"), file(fmt.Sprintf("bar/%s", longname2), "test2"), ), log: []string{fmt.Sprintf("bar/%s", longname2), longname1}, want: tarOf( dir("bar/"), file(fmt.Sprintf("bar/%s", longname2), "test2"), file(longname1, "test"), prefetchLandmark(), file("foo.txt", "foo"), file("bar/bar.txt", "bar"), file("bar/baa.txt", "baa"), ), }, { name: "various_types", in: tarOf( file("foo.txt", "foo"), symlink("foo2", "foo.txt"), chardev("foochar", 10, 50), blockdev("fooblock", 15, 20), fifo("fifoo"), ), log: []string{"fifoo", "foo2", "foo.txt", "fooblock"}, want: tarOf( fifo("fifoo"), symlink("foo2", "foo.txt"), file("foo.txt", "foo"), blockdev("fooblock", 15, 20), prefetchLandmark(), chardev("foochar", 10, 50), ), }, { name: "existing_landmark", in: tarOf( file("baa.txt", "baa"), file("bar.txt", "bar"), file("baz.txt", "baz"), prefetchLandmark(), file("foo.txt", "foo"), ), log: []string{"foo.txt", "bar.txt"}, want: tarOf( file("foo.txt", "foo"), file("bar.txt", "bar"), prefetchLandmark(), file("baa.txt", "baa"), file("baz.txt", "baz"), ), }, { name: "existing_landmark_nolog", in: tarOf( file("baa.txt", "baa"), file("bar.txt", "bar"), file("baz.txt", "baz"), prefetchLandmark(), file("foo.txt", "foo"), ), want: tarOf( noPrefetchLandmark(), file("baa.txt", "baa"), file("bar.txt", "bar"), file("baz.txt", "baz"), file("foo.txt", "foo"), ), }, { name: "existing_noprefetch_landmark", in: tarOf( noPrefetchLandmark(), file("baa.txt", "baa"), file("bar.txt", "bar"), file("baz.txt", "baz"), file("foo.txt", "foo"), ), log: []string{"foo.txt", "bar.txt"}, want: tarOf( file("foo.txt", "foo"), file("bar.txt", "bar"), prefetchLandmark(), file("baa.txt", "baa"), file("baz.txt", "baz"), ), }, { name: "existing_noprefetch_landmark_nolog", in: tarOf( noPrefetchLandmark(), file("baa.txt", "baa"), file("bar.txt", "bar"), file("baz.txt", "baz"), file("foo.txt", "foo"), ), want: tarOf( noPrefetchLandmark(), file("baa.txt", "baa"), file("bar.txt", "bar"), file("baz.txt", "baz"), file("foo.txt", "foo"), ), }, { name: "not_existing_file", in: tarOf( file("foo.txt", "foo"), file("baz.txt", "baz"), file("bar.txt", "bar"), file("baa.txt", "baa"), ), log: []string{"baa.txt", "bar.txt", "dummy"}, want: tarOf(), wantFail: true, }, { name: "not_existing_file_allow_fail", in: tarOf( file("foo.txt", "foo"), file("baz.txt", "baz"), file("bar.txt", "bar"), file("baa.txt", "baa"), ), log: []string{"baa.txt", "dummy1", "bar.txt", "dummy2"}, want: tarOf( file("baa.txt", "baa"), file("bar.txt", "bar"), prefetchLandmark(), file("foo.txt", "foo"), file("baz.txt", "baz"), ), allowMissedFiles: []string{"dummy1", "dummy2"}, }, { name: "duplicated_entry", in: tarOf( file("foo.txt", "foo"), dir("bar/"), file("bar/baz.txt", "baz"), dir("bar/"), file("bar/baz.txt", "baz2"), ), log: []string{"bar/baz.txt"}, want: tarOf( dir("bar/"), file("bar/baz.txt", "baz2"), prefetchLandmark(), file("foo.txt", "foo"), ), }, { name: "hardlink", in: tarOf( file("baz.txt", "aaaaa"), link("bazlink", "baz.txt"), ), log: []string{"bazlink"}, want: tarOf( file("baz.txt", "aaaaa"), link("bazlink", "baz.txt"), prefetchLandmark(), ), }, { name: "root_relative_file", in: tarOf( dir("./"), file("./foo.txt", "foo"), file("./baz.txt", "baz"), file("./baa.txt", "baa"), link("./bazlink", "./baz.txt"), ), log: []string{"baa.txt", "bazlink"}, want: tarOf( dir("./"), file("./baa.txt", "baa"), file("./baz.txt", "baz"), link("./bazlink", "./baz.txt"), prefetchLandmark(), file("./foo.txt", "foo"), ), }, { // GNU tar accepts tar containing absolute path name: "root_absolute_file", in: tarOf( dir("/"), file("/foo.txt", "foo"), file("/baz.txt", "baz"), file("/baa.txt", "baa"), link("/bazlink", "/baz.txt"), ), log: []string{"baa.txt", "bazlink"}, want: tarOf( dir("/"), file("/baa.txt", "baa"), file("/baz.txt", "baz"), link("/bazlink", "/baz.txt"), prefetchLandmark(), file("/foo.txt", "foo"), ), }, } for _, tt := range tests { for _, srcCompression := range srcCompressions { srcCompression := srcCompression for _, logprefix := range allowedPrefix { logprefix := logprefix for _, tarprefix := range allowedPrefix { tarprefix := tarprefix t.Run(fmt.Sprintf("%s-logprefix=%q-tarprefix=%q-src=%d", tt.name, logprefix, tarprefix, srcCompression), func(t *testing.T) { // Sort tar file var pfiles []string for _, f := range tt.log { pfiles = append(pfiles, logprefix+f) } var opts []Option var missedFiles []string if tt.allowMissedFiles != nil { opts = append(opts, WithAllowPrioritizeNotFound(&missedFiles)) } rc, err := Build(compressBlob(t, buildTar(t, tt.in, tarprefix), srcCompression), append(opts, WithPrioritizedFiles(pfiles))...) if tt.wantFail { if err != nil { return } t.Errorf("This test must fail but succeeded") return } if err != nil { t.Errorf("failed to build stargz: %v", err) } defer rc.Close() zr, err := gzip.NewReader(rc) if err != nil { t.Fatalf("failed to create gzip reader: %v", err) } if tt.allowMissedFiles != nil { want := map[string]struct{}{} for _, f := range tt.allowMissedFiles { want[logprefix+f] = struct{}{} } got := map[string]struct{}{} for _, f := range missedFiles { got[f] = struct{}{} } if !reflect.DeepEqual(got, want) { t.Errorf("unexpected missed files: want %v, got: %v", want, got) return } } gotTar := tar.NewReader(zr) // Compare all wantTar := tar.NewReader(buildTar(t, tt.want, tarprefix)) for { // Fetch and parse next header. gotH, wantH, err := next(t, gotTar, wantTar) if err != nil { if err == io.EOF { break } else { t.Fatalf("Failed to parse tar file: %v", err) } } if !reflect.DeepEqual(gotH, wantH) { t.Errorf("different header (got = name:%q,type:%d,size:%d; want = name:%q,type:%d,size:%d)", gotH.Name, gotH.Typeflag, gotH.Size, wantH.Name, wantH.Typeflag, wantH.Size) return } got, err := io.ReadAll(gotTar) if err != nil { t.Fatal("failed to read got tar payload") } want, err := io.ReadAll(wantTar) if err != nil { t.Fatal("failed to read want tar payload") } if !bytes.Equal(got, want) { t.Errorf("different payload (got = %q; want = %q)", string(got), string(want)) return } } }) } } } } } func next(t *testing.T, a *tar.Reader, b *tar.Reader) (ah *tar.Header, bh *tar.Header, err error) { eofA, eofB := false, false ah, err = nextWithSkipTOC(a) if err != nil { if err == io.EOF { eofA = true } else { t.Fatalf("Failed to parse tar file: %q", err) } } bh, err = nextWithSkipTOC(b) if err != nil { if err == io.EOF { eofB = true } else { t.Fatalf("Failed to parse tar file: %q", err) } } if eofA != eofB { if !eofA { t.Logf("a = %q", ah.Name) } if !eofB { t.Logf("b = %q", bh.Name) } t.Fatalf("got eof %t != %t", eofB, eofA) } if eofA { err = io.EOF } return } func nextWithSkipTOC(a *tar.Reader) (h *tar.Header, err error) { if h, err = a.Next(); err != nil { return } if h.Name == TOCTarName { return nextWithSkipTOC(a) } return } func longstring(size int) (str string) { unit := "long" for i := 0; i < size/len(unit)+1; i++ { str = fmt.Sprintf("%s%s", str, unit) } return str[:size] } func TestCountReader(t *testing.T) { tests := []struct { name string ops func(*countReadSeeker) error wantPos int64 }{ { name: "nop", ops: func(pw *countReadSeeker) error { return nil }, wantPos: 0, }, { name: "read", ops: func(pw *countReadSeeker) error { size := 5 if _, err := pw.Read(make([]byte, size)); err != nil { return err } return nil }, wantPos: 5, }, { name: "readtwice", ops: func(pw *countReadSeeker) error { size1, size2 := 5, 3 if _, err := pw.Read(make([]byte, size1)); err != nil { if err != io.EOF { return err } } if _, err := pw.Read(make([]byte, size2)); err != nil { if err != io.EOF { return err } } return nil }, wantPos: 8, }, { name: "seek_start", ops: func(pw *countReadSeeker) error { size := int64(5) if _, err := pw.Seek(size, io.SeekStart); err != nil { if err != io.EOF { return err } } return nil }, wantPos: 5, }, { name: "seek_start_twice", ops: func(pw *countReadSeeker) error { size1, size2 := int64(5), int64(3) if _, err := pw.Seek(size1, io.SeekStart); err != nil { if err != io.EOF { return err } } if _, err := pw.Seek(size2, io.SeekStart); err != nil { if err != io.EOF { return err } } return nil }, wantPos: 3, }, { name: "seek_current", ops: func(pw *countReadSeeker) error { size := int64(5) if _, err := pw.Seek(size, io.SeekCurrent); err != nil { if err != io.EOF { return err } } return nil }, wantPos: 5, }, { name: "seek_current_twice", ops: func(pw *countReadSeeker) error { size1, size2 := int64(5), int64(3) if _, err := pw.Seek(size1, io.SeekCurrent); err != nil { if err != io.EOF { return err } } if _, err := pw.Seek(size2, io.SeekCurrent); err != nil { if err != io.EOF { return err } } return nil }, wantPos: 8, }, { name: "seek_current_twice_negative", ops: func(pw *countReadSeeker) error { size1, size2 := int64(5), int64(-3) if _, err := pw.Seek(size1, io.SeekCurrent); err != nil { if err != io.EOF { return err } } if _, err := pw.Seek(size2, io.SeekCurrent); err != nil { if err != io.EOF { return err } } return nil }, wantPos: 2, }, { name: "mixed", ops: func(pw *countReadSeeker) error { size1, size2, size3, size4, size5 := int64(5), int64(-3), int64(4), int64(-1), int64(6) if _, err := pw.Read(make([]byte, size1)); err != nil { if err != io.EOF { return err } } if _, err := pw.Seek(size2, io.SeekCurrent); err != nil { if err != io.EOF { return err } } if _, err := pw.Seek(size3, io.SeekStart); err != nil { if err != io.EOF { return err } } if _, err := pw.Seek(size4, io.SeekCurrent); err != nil { if err != io.EOF { return err } } if _, err := pw.Read(make([]byte, size5)); err != nil { if err != io.EOF { return err } } return nil }, wantPos: 9, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { pw, err := newCountReadSeeker(bytes.NewReader(make([]byte, 100))) if err != nil { t.Fatalf("failed to make position watcher: %q", err) } if err := tt.ops(pw); err != nil { t.Fatalf("failed to operate position watcher: %q", err) } gotPos := pw.currentPos() if tt.wantPos != gotPos { t.Errorf("current position: %d; want %d", gotPos, tt.wantPos) } }) } } stargz-snapshotter-0.14.3/estargz/errorutil/000077500000000000000000000000001440204344700211715ustar00rootroot00000000000000stargz-snapshotter-0.14.3/estargz/errorutil/errors.go000066400000000000000000000020521440204344700230330ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package errorutil import ( "errors" "fmt" "strings" ) // Aggregate combines a list of errors into a single new error. func Aggregate(errs []error) error { switch len(errs) { case 0: return nil case 1: return errs[0] default: points := make([]string, len(errs)+1) points[0] = fmt.Sprintf("%d error(s) occurred:", len(errs)) for i, err := range errs { points[i+1] = fmt.Sprintf("* %s", err) } return errors.New(strings.Join(points, "\n\t")) } } stargz-snapshotter-0.14.3/estargz/errorutil/errors_test.go000066400000000000000000000026301440204344700240740ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package errorutil import ( "errors" "testing" ) func TestNoError(t *testing.T) { if err := Aggregate(nil); err != nil { t.Errorf("Aggregate(nil) = %v, wanted nil", err) } if err := Aggregate([]error{}); err != nil { t.Errorf("Aggregate(nil) = %v, wanted nil", err) } } func TestOneError(t *testing.T) { want := errors.New("this is A random Error string") if got := Aggregate([]error{want}); got != want { t.Errorf("Aggregate() = %v, wanted %v", got, want) } } func TestMultipleErrors(t *testing.T) { want := `3 error(s) occurred: * foo * bar * baz` err := Aggregate([]error{ errors.New("foo"), errors.New("bar"), errors.New("baz"), }) if err == nil { t.Errorf("Aggregate() = nil, wanted %s", want) } else if got := err.Error(); got != want { t.Errorf("Aggregate() = %s, wanted %s", got, want) } } stargz-snapshotter-0.14.3/estargz/estargz.go000066400000000000000000001006211440204344700211500ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /* Copyright 2019 The Go Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. */ package estargz import ( "bufio" "bytes" "compress/gzip" "crypto/sha256" "errors" "fmt" "hash" "io" "os" "path" "sort" "strings" "sync" "time" "github.com/containerd/stargz-snapshotter/estargz/errorutil" digest "github.com/opencontainers/go-digest" "github.com/vbatts/tar-split/archive/tar" ) // A Reader permits random access reads from a stargz file. type Reader struct { sr *io.SectionReader toc *JTOC tocDigest digest.Digest // m stores all non-chunk entries, keyed by name. m map[string]*TOCEntry // chunks stores all TOCEntry values for regular files that // are split up. For a file with a single chunk, it's only // stored in m. chunks map[string][]*TOCEntry decompressor Decompressor } type openOpts struct { tocOffset int64 decompressors []Decompressor telemetry *Telemetry } // OpenOption is an option used during opening the layer type OpenOption func(o *openOpts) error // WithTOCOffset option specifies the offset of TOC func WithTOCOffset(tocOffset int64) OpenOption { return func(o *openOpts) error { o.tocOffset = tocOffset return nil } } // WithDecompressors option specifies decompressors to use. // Default is gzip-based decompressor. func WithDecompressors(decompressors ...Decompressor) OpenOption { return func(o *openOpts) error { o.decompressors = decompressors return nil } } // WithTelemetry option specifies the telemetry hooks func WithTelemetry(telemetry *Telemetry) OpenOption { return func(o *openOpts) error { o.telemetry = telemetry return nil } } // MeasureLatencyHook is a func which takes start time and records the diff type MeasureLatencyHook func(time.Time) // Telemetry is a struct which defines telemetry hooks. By implementing these hooks you should be able to record // the latency metrics of the respective steps of estargz open operation. To be used with estargz.OpenWithTelemetry(...) type Telemetry struct { GetFooterLatency MeasureLatencyHook // measure time to get stargz footer (in milliseconds) GetTocLatency MeasureLatencyHook // measure time to GET TOC JSON (in milliseconds) DeserializeTocLatency MeasureLatencyHook // measure time to deserialize TOC JSON (in milliseconds) } // Open opens a stargz file for reading. // The behavior is configurable using options. // // Note that each entry name is normalized as the path that is relative to root. func Open(sr *io.SectionReader, opt ...OpenOption) (*Reader, error) { var opts openOpts for _, o := range opt { if err := o(&opts); err != nil { return nil, err } } gzipCompressors := []Decompressor{new(GzipDecompressor), new(LegacyGzipDecompressor)} decompressors := append(gzipCompressors, opts.decompressors...) // Determine the size to fetch. Try to fetch as many bytes as possible. fetchSize := maxFooterSize(sr.Size(), decompressors...) if maybeTocOffset := opts.tocOffset; maybeTocOffset > fetchSize { if maybeTocOffset > sr.Size() { return nil, fmt.Errorf("blob size %d is smaller than the toc offset", sr.Size()) } fetchSize = sr.Size() - maybeTocOffset } start := time.Now() // before getting layer footer footer := make([]byte, fetchSize) if _, err := sr.ReadAt(footer, sr.Size()-fetchSize); err != nil { return nil, fmt.Errorf("error reading footer: %v", err) } if opts.telemetry != nil && opts.telemetry.GetFooterLatency != nil { opts.telemetry.GetFooterLatency(start) } var allErr []error var found bool var r *Reader for _, d := range decompressors { fSize := d.FooterSize() fOffset := positive(int64(len(footer)) - fSize) maybeTocBytes := footer[:fOffset] _, tocOffset, tocSize, err := d.ParseFooter(footer[fOffset:]) if err != nil { allErr = append(allErr, err) continue } if tocOffset >= 0 && tocSize <= 0 { tocSize = sr.Size() - tocOffset - fSize } if tocOffset >= 0 && tocSize < int64(len(maybeTocBytes)) { maybeTocBytes = maybeTocBytes[:tocSize] } r, err = parseTOC(d, sr, tocOffset, tocSize, maybeTocBytes, opts) if err == nil { found = true break } allErr = append(allErr, err) } if !found { return nil, errorutil.Aggregate(allErr) } if err := r.initFields(); err != nil { return nil, fmt.Errorf("failed to initialize fields of entries: %v", err) } return r, nil } // OpenFooter extracts and parses footer from the given blob. // only supports gzip-based eStargz. func OpenFooter(sr *io.SectionReader) (tocOffset int64, footerSize int64, rErr error) { if sr.Size() < FooterSize && sr.Size() < legacyFooterSize { return 0, 0, fmt.Errorf("blob size %d is smaller than the footer size", sr.Size()) } var footer [FooterSize]byte if _, err := sr.ReadAt(footer[:], sr.Size()-FooterSize); err != nil { return 0, 0, fmt.Errorf("error reading footer: %v", err) } var allErr []error for _, d := range []Decompressor{new(GzipDecompressor), new(LegacyGzipDecompressor)} { fSize := d.FooterSize() fOffset := positive(int64(len(footer)) - fSize) _, tocOffset, _, err := d.ParseFooter(footer[fOffset:]) if err == nil { return tocOffset, fSize, err } allErr = append(allErr, err) } return 0, 0, errorutil.Aggregate(allErr) } // initFields populates the Reader from r.toc after decoding it from // JSON. // // Unexported fields are populated and TOCEntry fields that were // implicit in the JSON are populated. func (r *Reader) initFields() error { r.m = make(map[string]*TOCEntry, len(r.toc.Entries)) r.chunks = make(map[string][]*TOCEntry) var lastPath string uname := map[int]string{} gname := map[int]string{} var lastRegEnt *TOCEntry var chunkTopIndex int for i, ent := range r.toc.Entries { ent.Name = cleanEntryName(ent.Name) switch ent.Type { case "reg", "chunk": if ent.Offset != r.toc.Entries[chunkTopIndex].Offset { chunkTopIndex = i } ent.chunkTopIndex = chunkTopIndex } if ent.Type == "reg" { lastRegEnt = ent } if ent.Type == "chunk" { ent.Name = lastPath r.chunks[ent.Name] = append(r.chunks[ent.Name], ent) if ent.ChunkSize == 0 && lastRegEnt != nil { ent.ChunkSize = lastRegEnt.Size - ent.ChunkOffset } } else { lastPath = ent.Name if ent.Uname != "" { uname[ent.UID] = ent.Uname } else { ent.Uname = uname[ent.UID] } if ent.Gname != "" { gname[ent.GID] = ent.Gname } else { ent.Gname = uname[ent.GID] } ent.modTime, _ = time.Parse(time.RFC3339, ent.ModTime3339) if ent.Type == "dir" { ent.NumLink++ // Parent dir links to this directory } r.m[ent.Name] = ent } if ent.Type == "reg" && ent.ChunkSize > 0 && ent.ChunkSize < ent.Size { r.chunks[ent.Name] = make([]*TOCEntry, 0, ent.Size/ent.ChunkSize+1) r.chunks[ent.Name] = append(r.chunks[ent.Name], ent) } if ent.ChunkSize == 0 && ent.Size != 0 { ent.ChunkSize = ent.Size } } // Populate children, add implicit directories: for _, ent := range r.toc.Entries { if ent.Type == "chunk" { continue } // add "foo/": // add "foo" child to "" (creating "" if necessary) // // add "foo/bar/": // add "bar" child to "foo" (creating "foo" if necessary) // // add "foo/bar.txt": // add "bar.txt" child to "foo" (creating "foo" if necessary) // // add "a/b/c/d/e/f.txt": // create "a/b/c/d/e" node // add "f.txt" child to "e" name := ent.Name pdirName := parentDir(name) if name == pdirName { // This entry and its parent are the same. // Ignore this for avoiding infinite loop of the reference. // The example case where this can occur is when tar contains the root // directory itself (e.g. "./", "/"). continue } pdir := r.getOrCreateDir(pdirName) ent.NumLink++ // at least one name(ent.Name) references this entry. if ent.Type == "hardlink" { org, err := r.getSource(ent) if err != nil { return err } org.NumLink++ // original entry is referenced by this ent.Name. ent = org } pdir.addChild(path.Base(name), ent) } lastOffset := r.sr.Size() for i := len(r.toc.Entries) - 1; i >= 0; i-- { e := r.toc.Entries[i] if e.isDataType() { e.nextOffset = lastOffset } if e.Offset != 0 && e.InnerOffset == 0 { lastOffset = e.Offset } } return nil } func (r *Reader) getSource(ent *TOCEntry) (_ *TOCEntry, err error) { if ent.Type == "hardlink" { org, ok := r.m[cleanEntryName(ent.LinkName)] if !ok { return nil, fmt.Errorf("%q is a hardlink but the linkname %q isn't found", ent.Name, ent.LinkName) } ent, err = r.getSource(org) if err != nil { return nil, err } } return ent, nil } func parentDir(p string) string { dir, _ := path.Split(p) return strings.TrimSuffix(dir, "/") } func (r *Reader) getOrCreateDir(d string) *TOCEntry { e, ok := r.m[d] if !ok { e = &TOCEntry{ Name: d, Type: "dir", Mode: 0755, NumLink: 2, // The directory itself(.) and the parent link to this directory. } r.m[d] = e if d != "" { pdir := r.getOrCreateDir(parentDir(d)) pdir.addChild(path.Base(d), e) } } return e } func (r *Reader) TOCDigest() digest.Digest { return r.tocDigest } // VerifyTOC checks that the TOC JSON in the passed blob matches the // passed digests and that the TOC JSON contains digests for all chunks // contained in the blob. If the verification succceeds, this function // returns TOCEntryVerifier which holds all chunk digests in the stargz blob. func (r *Reader) VerifyTOC(tocDigest digest.Digest) (TOCEntryVerifier, error) { // Verify the digest of TOC JSON if r.tocDigest != tocDigest { return nil, fmt.Errorf("invalid TOC JSON %q; want %q", r.tocDigest, tocDigest) } return r.Verifiers() } // Verifiers returns TOCEntryVerifier of this chunk. Use VerifyTOC instead in most cases // because this doesn't verify TOC. func (r *Reader) Verifiers() (TOCEntryVerifier, error) { chunkDigestMap := make(map[int64]digest.Digest) // map from chunk offset to the chunk digest regDigestMap := make(map[int64]digest.Digest) // map from chunk offset to the reg file digest var chunkDigestMapIncomplete bool var regDigestMapIncomplete bool var containsChunk bool for _, e := range r.toc.Entries { if e.Type != "reg" && e.Type != "chunk" { continue } // offset must be unique in stargz blob _, dOK := chunkDigestMap[e.Offset] _, rOK := regDigestMap[e.Offset] if dOK || rOK { return nil, fmt.Errorf("offset %d found twice", e.Offset) } if e.Type == "reg" { if e.Size == 0 { continue // ignores empty file } // record the digest of regular file payload if e.Digest != "" { d, err := digest.Parse(e.Digest) if err != nil { return nil, fmt.Errorf("failed to parse regular file digest %q: %w", e.Digest, err) } regDigestMap[e.Offset] = d } else { regDigestMapIncomplete = true } } else { containsChunk = true // this layer contains "chunk" entries. } // "reg" also can contain ChunkDigest (e.g. when "reg" is the first entry of // chunked file) if e.ChunkDigest != "" { d, err := digest.Parse(e.ChunkDigest) if err != nil { return nil, fmt.Errorf("failed to parse chunk digest %q: %w", e.ChunkDigest, err) } chunkDigestMap[e.Offset] = d } else { chunkDigestMapIncomplete = true } } if chunkDigestMapIncomplete { // Though some chunk digests are not found, if this layer doesn't contain // "chunk"s and all digest of "reg" files are recorded, we can use them instead. if !containsChunk && !regDigestMapIncomplete { return &verifier{digestMap: regDigestMap}, nil } return nil, fmt.Errorf("some ChunkDigest not found in TOC JSON") } return &verifier{digestMap: chunkDigestMap}, nil } // verifier is an implementation of TOCEntryVerifier which holds verifiers keyed by // offset of the chunk. type verifier struct { digestMap map[int64]digest.Digest digestMapMu sync.Mutex } // Verifier returns a content verifier specified by TOCEntry. func (v *verifier) Verifier(ce *TOCEntry) (digest.Verifier, error) { v.digestMapMu.Lock() defer v.digestMapMu.Unlock() d, ok := v.digestMap[ce.Offset] if !ok { return nil, fmt.Errorf("verifier for offset=%d,size=%d hasn't been registered", ce.Offset, ce.ChunkSize) } return d.Verifier(), nil } // ChunkEntryForOffset returns the TOCEntry containing the byte of the // named file at the given offset within the file. // Name must be absolute path or one that is relative to root. func (r *Reader) ChunkEntryForOffset(name string, offset int64) (e *TOCEntry, ok bool) { name = cleanEntryName(name) e, ok = r.Lookup(name) if !ok || !e.isDataType() { return nil, false } ents := r.chunks[name] if len(ents) < 2 { if offset >= e.ChunkSize { return nil, false } return e, true } i := sort.Search(len(ents), func(i int) bool { e := ents[i] return e.ChunkOffset >= offset || (offset > e.ChunkOffset && offset < e.ChunkOffset+e.ChunkSize) }) if i == len(ents) { return nil, false } return ents[i], true } // Lookup returns the Table of Contents entry for the given path. // // To get the root directory, use the empty string. // Path must be absolute path or one that is relative to root. func (r *Reader) Lookup(path string) (e *TOCEntry, ok bool) { path = cleanEntryName(path) if r == nil { return } e, ok = r.m[path] if ok && e.Type == "hardlink" { var err error e, err = r.getSource(e) if err != nil { return nil, false } } return } // OpenFile returns the reader of the specified file payload. // // Name must be absolute path or one that is relative to root. func (r *Reader) OpenFile(name string) (*io.SectionReader, error) { fr, err := r.newFileReader(name) if err != nil { return nil, err } return io.NewSectionReader(fr, 0, fr.size), nil } func (r *Reader) newFileReader(name string) (*fileReader, error) { name = cleanEntryName(name) ent, ok := r.Lookup(name) if !ok { // TODO: come up with some error plan. This is lazy: return nil, &os.PathError{ Path: name, Op: "OpenFile", Err: os.ErrNotExist, } } if ent.Type != "reg" { return nil, &os.PathError{ Path: name, Op: "OpenFile", Err: errors.New("not a regular file"), } } return &fileReader{ r: r, size: ent.Size, ents: r.getChunks(ent), }, nil } func (r *Reader) OpenFileWithPreReader(name string, preRead func(*TOCEntry, io.Reader) error) (*io.SectionReader, error) { fr, err := r.newFileReader(name) if err != nil { return nil, err } fr.preRead = preRead return io.NewSectionReader(fr, 0, fr.size), nil } func (r *Reader) getChunks(ent *TOCEntry) []*TOCEntry { if ents, ok := r.chunks[ent.Name]; ok { return ents } return []*TOCEntry{ent} } type fileReader struct { r *Reader size int64 ents []*TOCEntry // 1 or more reg/chunk entries preRead func(*TOCEntry, io.Reader) error } func (fr *fileReader) ReadAt(p []byte, off int64) (n int, err error) { if off >= fr.size { return 0, io.EOF } if off < 0 { return 0, errors.New("invalid offset") } var i int if len(fr.ents) > 1 { i = sort.Search(len(fr.ents), func(i int) bool { return fr.ents[i].ChunkOffset >= off }) if i == len(fr.ents) { i = len(fr.ents) - 1 } } ent := fr.ents[i] if ent.ChunkOffset > off { if i == 0 { return 0, errors.New("internal error; first chunk offset is non-zero") } ent = fr.ents[i-1] } // If ent is a chunk of a large file, adjust the ReadAt // offset by the chunk's offset. off -= ent.ChunkOffset finalEnt := fr.ents[len(fr.ents)-1] compressedOff := ent.Offset // compressedBytesRemain is the number of compressed bytes in this // file remaining, over 1+ chunks. compressedBytesRemain := finalEnt.NextOffset() - compressedOff sr := io.NewSectionReader(fr.r.sr, compressedOff, compressedBytesRemain) const maxRead = 2 << 20 var bufSize = maxRead if compressedBytesRemain < maxRead { bufSize = int(compressedBytesRemain) } br := bufio.NewReaderSize(sr, bufSize) if _, err := br.Peek(bufSize); err != nil { return 0, fmt.Errorf("fileReader.ReadAt.peek: %v", err) } dr, err := fr.r.decompressor.Reader(br) if err != nil { return 0, fmt.Errorf("fileReader.ReadAt.decompressor.Reader: %v", err) } defer dr.Close() if fr.preRead == nil { if n, err := io.CopyN(io.Discard, dr, ent.InnerOffset+off); n != ent.InnerOffset+off || err != nil { return 0, fmt.Errorf("discard of %d bytes != %v, %v", ent.InnerOffset+off, n, err) } return io.ReadFull(dr, p) } var retN int var retErr error var found bool var nr int64 for _, e := range fr.r.toc.Entries[ent.chunkTopIndex:] { if !e.isDataType() { continue } if e.Offset != fr.r.toc.Entries[ent.chunkTopIndex].Offset { break } if in, err := io.CopyN(io.Discard, dr, e.InnerOffset-nr); err != nil || in != e.InnerOffset-nr { return 0, fmt.Errorf("discard of remaining %d bytes != %v, %v", e.InnerOffset-nr, in, err) } nr = e.InnerOffset if e == ent { found = true if n, err := io.CopyN(io.Discard, dr, off); n != off || err != nil { return 0, fmt.Errorf("discard of offset %d bytes != %v, %v", off, n, err) } retN, retErr = io.ReadFull(dr, p) nr += off + int64(retN) continue } cr := &countReader{r: io.LimitReader(dr, e.ChunkSize)} if err := fr.preRead(e, cr); err != nil { return 0, fmt.Errorf("failed to pre read: %w", err) } nr += cr.n } if !found { return 0, fmt.Errorf("fileReader.ReadAt: target entry not found") } return retN, retErr } // A Writer writes stargz files. // // Use NewWriter to create a new Writer. type Writer struct { bw *bufio.Writer cw *countWriter toc *JTOC diffHash hash.Hash // SHA-256 of uncompressed tar closed bool gz io.WriteCloser lastUsername map[int]string lastGroupname map[int]string compressor Compressor uncompressedCounter *countWriteFlusher // ChunkSize optionally controls the maximum number of bytes // of data of a regular file that can be written in one gzip // stream before a new gzip stream is started. // Zero means to use a default, currently 4 MiB. ChunkSize int // MinChunkSize optionally controls the minimum number of bytes // of data must be written in one gzip stream before a new gzip // NOTE: This adds a TOC property that stargz snapshotter < v0.13.0 doesn't understand. MinChunkSize int needsOpenGzEntries map[string]struct{} } // currentCompressionWriter writes to the current w.gz field, which can // change throughout writing a tar entry. // // Additionally, it updates w's SHA-256 of the uncompressed bytes // of the tar file. type currentCompressionWriter struct{ w *Writer } func (ccw currentCompressionWriter) Write(p []byte) (int, error) { ccw.w.diffHash.Write(p) if ccw.w.gz == nil { if err := ccw.w.condOpenGz(); err != nil { return 0, err } } return ccw.w.gz.Write(p) } func (w *Writer) chunkSize() int { if w.ChunkSize <= 0 { return 4 << 20 } return w.ChunkSize } // Unpack decompresses the given estargz blob and returns a ReadCloser of the tar blob. // TOC JSON and footer are removed. func Unpack(sr *io.SectionReader, c Decompressor) (io.ReadCloser, error) { footerSize := c.FooterSize() if sr.Size() < footerSize { return nil, fmt.Errorf("blob is too small; %d < %d", sr.Size(), footerSize) } footerOffset := sr.Size() - footerSize footer := make([]byte, footerSize) if _, err := sr.ReadAt(footer, footerOffset); err != nil { return nil, err } blobPayloadSize, _, _, err := c.ParseFooter(footer) if err != nil { return nil, fmt.Errorf("failed to parse footer: %w", err) } if blobPayloadSize < 0 { blobPayloadSize = sr.Size() } return c.Reader(io.LimitReader(sr, blobPayloadSize)) } // NewWriter returns a new stargz writer (gzip-based) writing to w. // // The writer must be closed to write its trailing table of contents. func NewWriter(w io.Writer) *Writer { return NewWriterLevel(w, gzip.BestCompression) } // NewWriterLevel returns a new stargz writer (gzip-based) writing to w. // The compression level is configurable. // // The writer must be closed to write its trailing table of contents. func NewWriterLevel(w io.Writer, compressionLevel int) *Writer { return NewWriterWithCompressor(w, NewGzipCompressorWithLevel(compressionLevel)) } // NewWriterWithCompressor returns a new stargz writer writing to w. // The compression method is configurable. // // The writer must be closed to write its trailing table of contents. func NewWriterWithCompressor(w io.Writer, c Compressor) *Writer { bw := bufio.NewWriter(w) cw := &countWriter{w: bw} return &Writer{ bw: bw, cw: cw, toc: &JTOC{Version: 1}, diffHash: sha256.New(), compressor: c, uncompressedCounter: &countWriteFlusher{}, } } // Close writes the stargz's table of contents and flushes all the // buffers, returning any error. func (w *Writer) Close() (digest.Digest, error) { if w.closed { return "", nil } defer func() { w.closed = true }() if err := w.closeGz(); err != nil { return "", err } // Write the TOC index and footer. tocDigest, err := w.compressor.WriteTOCAndFooter(w.cw, w.cw.n, w.toc, w.diffHash) if err != nil { return "", err } if err := w.bw.Flush(); err != nil { return "", err } return tocDigest, nil } func (w *Writer) closeGz() error { if w.closed { return errors.New("write on closed Writer") } if w.gz != nil { if err := w.gz.Close(); err != nil { return err } w.gz = nil } return nil } func (w *Writer) flushGz() error { if w.closed { return errors.New("flush on closed Writer") } if w.gz != nil { if f, ok := w.gz.(interface { Flush() error }); ok { return f.Flush() } } return nil } // nameIfChanged returns name, unless it was the already the value of (*mp)[id], // in which case it returns the empty string. func (w *Writer) nameIfChanged(mp *map[int]string, id int, name string) string { if name == "" { return "" } if *mp == nil { *mp = make(map[int]string) } if (*mp)[id] == name { return "" } (*mp)[id] = name return name } func (w *Writer) condOpenGz() (err error) { if w.gz == nil { w.gz, err = w.compressor.Writer(w.cw) if w.gz != nil { w.gz = w.uncompressedCounter.register(w.gz) } } return } // AppendTar reads the tar or tar.gz file from r and appends // each of its contents to w. // // The input r can optionally be gzip compressed but the output will // always be compressed by the specified compressor. func (w *Writer) AppendTar(r io.Reader) error { return w.appendTar(r, false) } // AppendTarLossLess reads the tar or tar.gz file from r and appends // each of its contents to w. // // The input r can optionally be gzip compressed but the output will // always be compressed by the specified compressor. // // The difference of this func with AppendTar is that this writes // the input tar stream into w without any modification (e.g. to header bytes). // // Note that if the input tar stream already contains TOC JSON, this returns // error because w cannot overwrite the TOC JSON to the one generated by w without // lossy modification. To avoid this error, if the input stream is known to be stargz/estargz, // you shoud decompress it and remove TOC JSON in advance. func (w *Writer) AppendTarLossLess(r io.Reader) error { return w.appendTar(r, true) } func (w *Writer) appendTar(r io.Reader, lossless bool) error { var src io.Reader br := bufio.NewReader(r) if isGzip(br) { zr, _ := gzip.NewReader(br) src = zr } else { src = io.Reader(br) } dst := currentCompressionWriter{w} var tw *tar.Writer if !lossless { tw = tar.NewWriter(dst) // use tar writer only when this isn't lossless mode. } tr := tar.NewReader(src) if lossless { tr.RawAccounting = true } prevOffset := w.cw.n var prevOffsetUncompressed int64 for { h, err := tr.Next() if err == io.EOF { if lossless { if remain := tr.RawBytes(); len(remain) > 0 { // Collect the remaining null bytes. // https://github.com/vbatts/tar-split/blob/80a436fd6164c557b131f7c59ed69bd81af69761/concept/main.go#L49-L53 if _, err := dst.Write(remain); err != nil { return err } } } break } if err != nil { return fmt.Errorf("error reading from source tar: tar.Reader.Next: %v", err) } if cleanEntryName(h.Name) == TOCTarName { // It is possible for a layer to be "stargzified" twice during the // distribution lifecycle. So we reserve "TOCTarName" here to avoid // duplicated entries in the resulting layer. if lossless { // We cannot handle this in lossless way. return fmt.Errorf("existing TOC JSON is not allowed; decompress layer before append") } continue } xattrs := make(map[string][]byte) const xattrPAXRecordsPrefix = "SCHILY.xattr." if h.PAXRecords != nil { for k, v := range h.PAXRecords { if strings.HasPrefix(k, xattrPAXRecordsPrefix) { xattrs[k[len(xattrPAXRecordsPrefix):]] = []byte(v) } } } ent := &TOCEntry{ Name: h.Name, Mode: h.Mode, UID: h.Uid, GID: h.Gid, Uname: w.nameIfChanged(&w.lastUsername, h.Uid, h.Uname), Gname: w.nameIfChanged(&w.lastGroupname, h.Gid, h.Gname), ModTime3339: formatModtime(h.ModTime), Xattrs: xattrs, } if err := w.condOpenGz(); err != nil { return err } if tw != nil { if err := tw.WriteHeader(h); err != nil { return err } } else { if _, err := dst.Write(tr.RawBytes()); err != nil { return err } } switch h.Typeflag { case tar.TypeLink: ent.Type = "hardlink" ent.LinkName = h.Linkname case tar.TypeSymlink: ent.Type = "symlink" ent.LinkName = h.Linkname case tar.TypeDir: ent.Type = "dir" case tar.TypeReg: ent.Type = "reg" ent.Size = h.Size case tar.TypeChar: ent.Type = "char" ent.DevMajor = int(h.Devmajor) ent.DevMinor = int(h.Devminor) case tar.TypeBlock: ent.Type = "block" ent.DevMajor = int(h.Devmajor) ent.DevMinor = int(h.Devminor) case tar.TypeFifo: ent.Type = "fifo" default: return fmt.Errorf("unsupported input tar entry %q", h.Typeflag) } // We need to keep a reference to the TOC entry for regular files, so that we // can fill the digest later. var regFileEntry *TOCEntry var payloadDigest digest.Digester if h.Typeflag == tar.TypeReg { regFileEntry = ent payloadDigest = digest.Canonical.Digester() } if h.Typeflag == tar.TypeReg && ent.Size > 0 { var written int64 totalSize := ent.Size // save it before we destroy ent tee := io.TeeReader(tr, payloadDigest.Hash()) for written < totalSize { chunkSize := int64(w.chunkSize()) remain := totalSize - written if remain < chunkSize { chunkSize = remain } else { ent.ChunkSize = chunkSize } // We flush the underlying compression writer here to correctly calculate "w.cw.n". if err := w.flushGz(); err != nil { return err } if w.needsOpenGz(ent) || w.cw.n-prevOffset >= int64(w.MinChunkSize) { if err := w.closeGz(); err != nil { return err } ent.Offset = w.cw.n prevOffset = ent.Offset prevOffsetUncompressed = w.uncompressedCounter.n } else { ent.Offset = prevOffset ent.InnerOffset = w.uncompressedCounter.n - prevOffsetUncompressed } ent.ChunkOffset = written chunkDigest := digest.Canonical.Digester() if err := w.condOpenGz(); err != nil { return err } teeChunk := io.TeeReader(tee, chunkDigest.Hash()) var out io.Writer if tw != nil { out = tw } else { out = dst } if _, err := io.CopyN(out, teeChunk, chunkSize); err != nil { return fmt.Errorf("error copying %q: %v", h.Name, err) } ent.ChunkDigest = chunkDigest.Digest().String() w.toc.Entries = append(w.toc.Entries, ent) written += chunkSize ent = &TOCEntry{ Name: h.Name, Type: "chunk", } } } else { w.toc.Entries = append(w.toc.Entries, ent) } if payloadDigest != nil { regFileEntry.Digest = payloadDigest.Digest().String() } if tw != nil { if err := tw.Flush(); err != nil { return err } } } remainDest := io.Discard if lossless { remainDest = dst // Preserve the remaining bytes in lossless mode } _, err := io.Copy(remainDest, src) return err } func (w *Writer) needsOpenGz(ent *TOCEntry) bool { if ent.Type != "reg" { return false } if w.needsOpenGzEntries == nil { return false } _, ok := w.needsOpenGzEntries[ent.Name] return ok } // DiffID returns the SHA-256 of the uncompressed tar bytes. // It is only valid to call DiffID after Close. func (w *Writer) DiffID() string { return fmt.Sprintf("sha256:%x", w.diffHash.Sum(nil)) } func maxFooterSize(blobSize int64, decompressors ...Decompressor) (res int64) { for _, d := range decompressors { if s := d.FooterSize(); res < s && s <= blobSize { res = s } } return } func parseTOC(d Decompressor, sr *io.SectionReader, tocOff, tocSize int64, tocBytes []byte, opts openOpts) (*Reader, error) { if tocOff < 0 { // This means that TOC isn't contained in the blob. // We pass nil reader to ParseTOC and expect that ParseTOC acquire TOC from // the external location. start := time.Now() toc, tocDgst, err := d.ParseTOC(nil) if err != nil { return nil, err } if opts.telemetry != nil && opts.telemetry.GetTocLatency != nil { opts.telemetry.GetTocLatency(start) } if opts.telemetry != nil && opts.telemetry.DeserializeTocLatency != nil { opts.telemetry.DeserializeTocLatency(start) } return &Reader{ sr: sr, toc: toc, tocDigest: tocDgst, decompressor: d, }, nil } if len(tocBytes) > 0 { start := time.Now() toc, tocDgst, err := d.ParseTOC(bytes.NewReader(tocBytes)) if err == nil { if opts.telemetry != nil && opts.telemetry.DeserializeTocLatency != nil { opts.telemetry.DeserializeTocLatency(start) } return &Reader{ sr: sr, toc: toc, tocDigest: tocDgst, decompressor: d, }, nil } } start := time.Now() tocBytes = make([]byte, tocSize) if _, err := sr.ReadAt(tocBytes, tocOff); err != nil { return nil, fmt.Errorf("error reading %d byte TOC targz: %v", len(tocBytes), err) } if opts.telemetry != nil && opts.telemetry.GetTocLatency != nil { opts.telemetry.GetTocLatency(start) } start = time.Now() toc, tocDgst, err := d.ParseTOC(bytes.NewReader(tocBytes)) if err != nil { return nil, err } if opts.telemetry != nil && opts.telemetry.DeserializeTocLatency != nil { opts.telemetry.DeserializeTocLatency(start) } return &Reader{ sr: sr, toc: toc, tocDigest: tocDgst, decompressor: d, }, nil } func formatModtime(t time.Time) string { if t.IsZero() || t.Unix() == 0 { return "" } return t.UTC().Round(time.Second).Format(time.RFC3339) } func cleanEntryName(name string) string { // Use path.Clean to consistently deal with path separators across platforms. return strings.TrimPrefix(path.Clean("/"+name), "/") } // countWriter counts how many bytes have been written to its wrapped // io.Writer. type countWriter struct { w io.Writer n int64 } func (cw *countWriter) Write(p []byte) (n int, err error) { n, err = cw.w.Write(p) cw.n += int64(n) return } type countWriteFlusher struct { io.WriteCloser n int64 } func (wc *countWriteFlusher) register(w io.WriteCloser) io.WriteCloser { wc.WriteCloser = w return wc } func (wc *countWriteFlusher) Write(p []byte) (n int, err error) { n, err = wc.WriteCloser.Write(p) wc.n += int64(n) return } func (wc *countWriteFlusher) Flush() error { if f, ok := wc.WriteCloser.(interface { Flush() error }); ok { return f.Flush() } return nil } func (wc *countWriteFlusher) Close() error { err := wc.WriteCloser.Close() wc.WriteCloser = nil return err } // isGzip reports whether br is positioned right before an upcoming gzip stream. // It does not consume any bytes from br. func isGzip(br *bufio.Reader) bool { const ( gzipID1 = 0x1f gzipID2 = 0x8b gzipDeflate = 8 ) peek, _ := br.Peek(3) return len(peek) >= 3 && peek[0] == gzipID1 && peek[1] == gzipID2 && peek[2] == gzipDeflate } func positive(n int64) int64 { if n < 0 { return 0 } return n } type countReader struct { r io.Reader n int64 } func (cr *countReader) Read(p []byte) (n int, err error) { n, err = cr.r.Read(p) cr.n += int64(n) return } stargz-snapshotter-0.14.3/estargz/estargz_test.go000066400000000000000000000063721440204344700222170ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /* Copyright 2019 The Go Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. */ package estargz import "testing" // Tests *Reader.ChunkEntryForOffset about offset and size calculation. func TestChunkEntryForOffset(t *testing.T) { const chunkSize = 4 tests := []struct { name string fileSize int64 reqOffset int64 wantOk bool wantChunkOffset int64 wantChunkSize int64 }{ { name: "1st_chunk_in_1_chunk_reg", fileSize: chunkSize * 1, reqOffset: chunkSize * 0, wantChunkOffset: chunkSize * 0, wantChunkSize: chunkSize, wantOk: true, }, { name: "2nd_chunk_in_1_chunk_reg", fileSize: chunkSize * 1, reqOffset: chunkSize * 1, wantOk: false, }, { name: "1st_chunk_in_2_chunks_reg", fileSize: chunkSize * 2, reqOffset: chunkSize * 0, wantChunkOffset: chunkSize * 0, wantChunkSize: chunkSize, wantOk: true, }, { name: "2nd_chunk_in_2_chunks_reg", fileSize: chunkSize * 2, reqOffset: chunkSize * 1, wantChunkOffset: chunkSize * 1, wantChunkSize: chunkSize, wantOk: true, }, { name: "3rd_chunk_in_2_chunks_reg", fileSize: chunkSize * 2, reqOffset: chunkSize * 2, wantOk: false, }, } for _, te := range tests { t.Run(te.name, func(t *testing.T) { name := "test" _, r := regularFileReader(name, te.fileSize, chunkSize) ce, ok := r.ChunkEntryForOffset(name, te.reqOffset) if ok != te.wantOk { t.Errorf("ok = %v; want (%v)", ok, te.wantOk) } else if ok { if !(ce.ChunkOffset == te.wantChunkOffset && ce.ChunkSize == te.wantChunkSize) { t.Errorf("chunkOffset = %d, ChunkSize = %d; want (chunkOffset = %d, chunkSize = %d)", ce.ChunkOffset, ce.ChunkSize, te.wantChunkOffset, te.wantChunkSize) } } }) } } // regularFileReader makes a minimal Reader of "reg" and "chunk" without tar-related information. func regularFileReader(name string, size int64, chunkSize int64) (*TOCEntry, *Reader) { ent := &TOCEntry{ Name: name, Type: "reg", } m := ent chunks := make([]*TOCEntry, 0, size/chunkSize+1) var written int64 for written < size { remain := size - written cs := chunkSize if remain < cs { cs = remain } ent.ChunkSize = cs ent.ChunkOffset = written chunks = append(chunks, ent) written += cs ent = &TOCEntry{ Name: name, Type: "chunk", } } if len(chunks) == 1 { chunks = nil } return m, &Reader{ m: map[string]*TOCEntry{name: m}, chunks: map[string][]*TOCEntry{name: chunks}, } } stargz-snapshotter-0.14.3/estargz/externaltoc/000077500000000000000000000000001440204344700214725ustar00rootroot00000000000000stargz-snapshotter-0.14.3/estargz/externaltoc/externaltoc.go000066400000000000000000000175331440204344700243620ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /* Copyright 2019 The Go Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. */ package externaltoc import ( "archive/tar" "bytes" "compress/gzip" "encoding/binary" "encoding/json" "fmt" "hash" "io" "sync" "github.com/containerd/stargz-snapshotter/estargz" digest "github.com/opencontainers/go-digest" ) type GzipCompression struct { *GzipCompressor *GzipDecompressor } func NewGzipCompressionWithLevel(provideTOC func() ([]byte, error), level int) estargz.Compression { return &GzipCompression{ NewGzipCompressorWithLevel(level), NewGzipDecompressor(provideTOC), } } func NewGzipCompressor() *GzipCompressor { return &GzipCompressor{compressionLevel: gzip.BestCompression} } func NewGzipCompressorWithLevel(level int) *GzipCompressor { return &GzipCompressor{compressionLevel: level} } type GzipCompressor struct { compressionLevel int buf *bytes.Buffer } func (gc *GzipCompressor) WriteTOCTo(w io.Writer) (int, error) { if len(gc.buf.Bytes()) == 0 { return 0, fmt.Errorf("TOC hasn't been registered") } return w.Write(gc.buf.Bytes()) } func (gc *GzipCompressor) Writer(w io.Writer) (estargz.WriteFlushCloser, error) { return gzip.NewWriterLevel(w, gc.compressionLevel) } func (gc *GzipCompressor) WriteTOCAndFooter(w io.Writer, off int64, toc *estargz.JTOC, diffHash hash.Hash) (digest.Digest, error) { tocJSON, err := json.MarshalIndent(toc, "", "\t") if err != nil { return "", err } buf := new(bytes.Buffer) gz, _ := gzip.NewWriterLevel(buf, gc.compressionLevel) // TOC isn't written to layer so no effect to diff ID tw := tar.NewWriter(gz) if err := tw.WriteHeader(&tar.Header{ Typeflag: tar.TypeReg, Name: estargz.TOCTarName, Size: int64(len(tocJSON)), }); err != nil { return "", err } if _, err := tw.Write(tocJSON); err != nil { return "", err } if err := tw.Close(); err != nil { return "", err } if err := gz.Close(); err != nil { return "", err } gc.buf = buf footerBytes, err := gzipFooterBytes() if err != nil { return "", err } if _, err := w.Write(footerBytes); err != nil { return "", err } return digest.FromBytes(tocJSON), nil } // The footer is an empty gzip stream with no compression and an Extra header. // // 46 comes from: // // 10 bytes gzip header // 2 bytes XLEN (length of Extra field) = 21 (4 bytes header + len("STARGZEXTERNALTOC")) // 2 bytes Extra: SI1 = 'S', SI2 = 'G' // 2 bytes Extra: LEN = 17 (len("STARGZEXTERNALTOC")) // 17 bytes Extra: subfield = "STARGZEXTERNALTOC" // 5 bytes flate header // 8 bytes gzip footer // (End of the eStargz blob) const FooterSize = 46 // gzipFooterBytes returns the 104 bytes footer. func gzipFooterBytes() ([]byte, error) { buf := bytes.NewBuffer(make([]byte, 0, FooterSize)) gz, _ := gzip.NewWriterLevel(buf, gzip.NoCompression) // MUST be NoCompression to keep 51 bytes // Extra header indicating the offset of TOCJSON // https://tools.ietf.org/html/rfc1952#section-2.3.1.1 header := make([]byte, 4) header[0], header[1] = 'S', 'G' subfield := "STARGZEXTERNALTOC" // len("STARGZEXTERNALTOC") = 17 binary.LittleEndian.PutUint16(header[2:4], uint16(len(subfield))) // little-endian per RFC1952 gz.Header.Extra = append(header, []byte(subfield)...) if err := gz.Close(); err != nil { return nil, err } if buf.Len() != FooterSize { panic(fmt.Sprintf("footer buffer = %d, not %d", buf.Len(), FooterSize)) } return buf.Bytes(), nil } func NewGzipDecompressor(provideTOCFunc func() ([]byte, error)) *GzipDecompressor { return &GzipDecompressor{provideTOCFunc: provideTOCFunc} } type GzipDecompressor struct { provideTOCFunc func() ([]byte, error) rawTOC []byte // Do not access this field directly. Get this through getTOC() method. getTOCOnce sync.Once } func (gz *GzipDecompressor) getTOC() ([]byte, error) { if len(gz.rawTOC) == 0 { var retErr error gz.getTOCOnce.Do(func() { if gz.provideTOCFunc == nil { retErr = fmt.Errorf("TOC hasn't been provided") return } rawTOC, err := gz.provideTOCFunc() if err != nil { retErr = err return } gz.rawTOC = rawTOC }) if retErr != nil { return nil, retErr } if len(gz.rawTOC) == 0 { return nil, fmt.Errorf("no TOC is provided") } } return gz.rawTOC, nil } func (gz *GzipDecompressor) Reader(r io.Reader) (io.ReadCloser, error) { return gzip.NewReader(r) } func (gz *GzipDecompressor) ParseTOC(r io.Reader) (toc *estargz.JTOC, tocDgst digest.Digest, err error) { if r != nil { return nil, "", fmt.Errorf("TOC must be provided externally but got internal one") } rawTOC, err := gz.getTOC() if err != nil { return nil, "", fmt.Errorf("failed to get TOC: %v", err) } return parseTOCEStargz(bytes.NewReader(rawTOC)) } func (gz *GzipDecompressor) ParseFooter(p []byte) (blobPayloadSize, tocOffset, tocSize int64, err error) { if len(p) != FooterSize { return 0, 0, 0, fmt.Errorf("invalid length %d cannot be parsed", len(p)) } zr, err := gzip.NewReader(bytes.NewReader(p)) if err != nil { return 0, 0, 0, err } defer zr.Close() extra := zr.Header.Extra si1, si2, subfieldlen, subfield := extra[0], extra[1], extra[2:4], extra[4:] if si1 != 'S' || si2 != 'G' { return 0, 0, 0, fmt.Errorf("invalid subfield IDs: %q, %q; want E, S", si1, si2) } if slen := binary.LittleEndian.Uint16(subfieldlen); slen != uint16(len("STARGZEXTERNALTOC")) { return 0, 0, 0, fmt.Errorf("invalid length of subfield %d; want %d", slen, 16+len("STARGZ")) } if string(subfield) != "STARGZEXTERNALTOC" { return 0, 0, 0, fmt.Errorf("STARGZ magic string must be included in the footer subfield") } // tocOffset < 0 indicates external TOC. // blobPayloadSize < 0 indicates the entire blob size. return -1, -1, 0, nil } func (gz *GzipDecompressor) FooterSize() int64 { return FooterSize } func (gz *GzipDecompressor) DecompressTOC(r io.Reader) (tocJSON io.ReadCloser, err error) { if r != nil { return nil, fmt.Errorf("TOC must be provided externally but got internal one") } rawTOC, err := gz.getTOC() if err != nil { return nil, fmt.Errorf("failed to get TOC: %v", err) } return decompressTOCEStargz(bytes.NewReader(rawTOC)) } func parseTOCEStargz(r io.Reader) (toc *estargz.JTOC, tocDgst digest.Digest, err error) { tr, err := decompressTOCEStargz(r) if err != nil { return nil, "", err } dgstr := digest.Canonical.Digester() toc = new(estargz.JTOC) if err := json.NewDecoder(io.TeeReader(tr, dgstr.Hash())).Decode(&toc); err != nil { return nil, "", fmt.Errorf("error decoding TOC JSON: %v", err) } if err := tr.Close(); err != nil { return nil, "", err } return toc, dgstr.Digest(), nil } func decompressTOCEStargz(r io.Reader) (tocJSON io.ReadCloser, err error) { zr, err := gzip.NewReader(r) if err != nil { return nil, fmt.Errorf("malformed TOC gzip header: %v", err) } zr.Multistream(false) tr := tar.NewReader(zr) h, err := tr.Next() if err != nil { return nil, fmt.Errorf("failed to find tar header in TOC gzip stream: %v", err) } if h.Name != estargz.TOCTarName { return nil, fmt.Errorf("TOC tar entry had name %q; expected %q", h.Name, estargz.TOCTarName) } return readCloser{tr, zr.Close}, nil } type readCloser struct { io.Reader closeFunc func() error } func (rc readCloser) Close() error { return rc.closeFunc() } stargz-snapshotter-0.14.3/estargz/externaltoc/externaltoc_test.go000066400000000000000000000052161440204344700254140ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package externaltoc import ( "bytes" "compress/gzip" "fmt" "testing" "github.com/containerd/stargz-snapshotter/estargz" ) // TestGzipEStargz tests gzip-based external TOC eStargz func TestGzipEStargz(t *testing.T) { estargz.CompressionTestSuite(t, gzipControllerWithLevel(gzip.NoCompression), gzipControllerWithLevel(gzip.BestSpeed), gzipControllerWithLevel(gzip.BestCompression), gzipControllerWithLevel(gzip.DefaultCompression), gzipControllerWithLevel(gzip.HuffmanOnly), ) } func gzipControllerWithLevel(compressionLevel int) estargz.TestingControllerFactory { return func() estargz.TestingController { compressor := NewGzipCompressorWithLevel(compressionLevel) decompressor := NewGzipDecompressor(func() ([]byte, error) { buf := new(bytes.Buffer) if _, err := compressor.WriteTOCTo(buf); err != nil { return nil, err } return buf.Bytes(), nil }) return &gzipController{compressor, decompressor} } } type gzipController struct { *GzipCompressor *GzipDecompressor } func (gc *gzipController) String() string { return fmt.Sprintf("externaltoc_gzip_compression_level=%v", gc.GzipCompressor.compressionLevel) } // TestStream tests the passed estargz blob contains the specified list of streams. func (gc *gzipController) TestStreams(t *testing.T, b []byte, streams []int64) { estargz.CheckGzipHasStreams(t, b, streams) } func (gc *gzipController) DiffIDOf(t *testing.T, b []byte) string { return estargz.GzipDiffIDOf(t, b) } // Tests footer encoding, size, and parsing of gzip-based eStargz. func TestGzipFooter(t *testing.T) { footer, err := gzipFooterBytes() if err != nil { t.Fatalf("failed gzipFooterBytes: %v", err) } if len(footer) != FooterSize { t.Fatalf("footer length was %d, not expected %d. got bytes: %q", len(footer), FooterSize, footer) } _, gotTOCOffset, _, err := (&GzipDecompressor{}).ParseFooter(footer) if err != nil { t.Fatalf("failed to parse footer, footer: %x: err: %v", footer, err) } if gotTOCOffset != -1 { t.Fatalf("ParseFooter(footerBytes) must return -1 for external toc but got %d", gotTOCOffset) } } stargz-snapshotter-0.14.3/estargz/go.mod000066400000000000000000000003401440204344700202450ustar00rootroot00000000000000module github.com/containerd/stargz-snapshotter/estargz go 1.19 require ( github.com/klauspost/compress v1.16.0 github.com/opencontainers/go-digest v1.0.0 github.com/vbatts/tar-split v0.11.2 golang.org/x/sync v0.1.0 ) stargz-snapshotter-0.14.3/estargz/go.sum000066400000000000000000000034701440204344700203010ustar00rootroot00000000000000github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/klauspost/compress v1.16.0 h1:iULayQNOReoYUe+1qtKOqw9CwJv3aNQu8ivo7lw1HU4= github.com/klauspost/compress v1.16.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/urfave/cli v1.22.4/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/vbatts/tar-split v0.11.2 h1:Via6XqJr0hceW4wff3QRzD5gAk/tatMw/4ZA7cTlIME= github.com/vbatts/tar-split v0.11.2/go.mod h1:vV3ZuO2yWSVsz+pfFzDG/upWH1JhjOiEaWq6kXyQ3VI= golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= stargz-snapshotter-0.14.3/estargz/gzip.go000066400000000000000000000154531440204344700204520ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /* Copyright 2019 The Go Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. */ package estargz import ( "archive/tar" "bytes" "compress/gzip" "encoding/binary" "encoding/json" "fmt" "hash" "io" "strconv" digest "github.com/opencontainers/go-digest" ) type gzipCompression struct { *GzipCompressor *GzipDecompressor } func newGzipCompressionWithLevel(level int) Compression { return &gzipCompression{ &GzipCompressor{level}, &GzipDecompressor{}, } } func NewGzipCompressor() *GzipCompressor { return &GzipCompressor{gzip.BestCompression} } func NewGzipCompressorWithLevel(level int) *GzipCompressor { return &GzipCompressor{level} } type GzipCompressor struct { compressionLevel int } func (gc *GzipCompressor) Writer(w io.Writer) (WriteFlushCloser, error) { return gzip.NewWriterLevel(w, gc.compressionLevel) } func (gc *GzipCompressor) WriteTOCAndFooter(w io.Writer, off int64, toc *JTOC, diffHash hash.Hash) (digest.Digest, error) { tocJSON, err := json.MarshalIndent(toc, "", "\t") if err != nil { return "", err } gz, _ := gzip.NewWriterLevel(w, gc.compressionLevel) gw := io.Writer(gz) if diffHash != nil { gw = io.MultiWriter(gz, diffHash) } tw := tar.NewWriter(gw) if err := tw.WriteHeader(&tar.Header{ Typeflag: tar.TypeReg, Name: TOCTarName, Size: int64(len(tocJSON)), }); err != nil { return "", err } if _, err := tw.Write(tocJSON); err != nil { return "", err } if err := tw.Close(); err != nil { return "", err } if err := gz.Close(); err != nil { return "", err } if _, err := w.Write(gzipFooterBytes(off)); err != nil { return "", err } return digest.FromBytes(tocJSON), nil } // gzipFooterBytes returns the 51 bytes footer. func gzipFooterBytes(tocOff int64) []byte { buf := bytes.NewBuffer(make([]byte, 0, FooterSize)) gz, _ := gzip.NewWriterLevel(buf, gzip.NoCompression) // MUST be NoCompression to keep 51 bytes // Extra header indicating the offset of TOCJSON // https://tools.ietf.org/html/rfc1952#section-2.3.1.1 header := make([]byte, 4) header[0], header[1] = 'S', 'G' subfield := fmt.Sprintf("%016xSTARGZ", tocOff) binary.LittleEndian.PutUint16(header[2:4], uint16(len(subfield))) // little-endian per RFC1952 gz.Header.Extra = append(header, []byte(subfield)...) gz.Close() if buf.Len() != FooterSize { panic(fmt.Sprintf("footer buffer = %d, not %d", buf.Len(), FooterSize)) } return buf.Bytes() } type GzipDecompressor struct{} func (gz *GzipDecompressor) Reader(r io.Reader) (io.ReadCloser, error) { return gzip.NewReader(r) } func (gz *GzipDecompressor) ParseTOC(r io.Reader) (toc *JTOC, tocDgst digest.Digest, err error) { return parseTOCEStargz(r) } func (gz *GzipDecompressor) ParseFooter(p []byte) (blobPayloadSize, tocOffset, tocSize int64, err error) { if len(p) != FooterSize { return 0, 0, 0, fmt.Errorf("invalid length %d cannot be parsed", len(p)) } zr, err := gzip.NewReader(bytes.NewReader(p)) if err != nil { return 0, 0, 0, err } defer zr.Close() extra := zr.Header.Extra si1, si2, subfieldlen, subfield := extra[0], extra[1], extra[2:4], extra[4:] if si1 != 'S' || si2 != 'G' { return 0, 0, 0, fmt.Errorf("invalid subfield IDs: %q, %q; want E, S", si1, si2) } if slen := binary.LittleEndian.Uint16(subfieldlen); slen != uint16(16+len("STARGZ")) { return 0, 0, 0, fmt.Errorf("invalid length of subfield %d; want %d", slen, 16+len("STARGZ")) } if string(subfield[16:]) != "STARGZ" { return 0, 0, 0, fmt.Errorf("STARGZ magic string must be included in the footer subfield") } tocOffset, err = strconv.ParseInt(string(subfield[:16]), 16, 64) if err != nil { return 0, 0, 0, fmt.Errorf("legacy: failed to parse toc offset: %w", err) } return tocOffset, tocOffset, 0, nil } func (gz *GzipDecompressor) FooterSize() int64 { return FooterSize } func (gz *GzipDecompressor) DecompressTOC(r io.Reader) (tocJSON io.ReadCloser, err error) { return decompressTOCEStargz(r) } type LegacyGzipDecompressor struct{} func (gz *LegacyGzipDecompressor) Reader(r io.Reader) (io.ReadCloser, error) { return gzip.NewReader(r) } func (gz *LegacyGzipDecompressor) ParseTOC(r io.Reader) (toc *JTOC, tocDgst digest.Digest, err error) { return parseTOCEStargz(r) } func (gz *LegacyGzipDecompressor) ParseFooter(p []byte) (blobPayloadSize, tocOffset, tocSize int64, err error) { if len(p) != legacyFooterSize { return 0, 0, 0, fmt.Errorf("legacy: invalid length %d cannot be parsed", len(p)) } zr, err := gzip.NewReader(bytes.NewReader(p)) if err != nil { return 0, 0, 0, fmt.Errorf("legacy: failed to get footer gzip reader: %w", err) } defer zr.Close() extra := zr.Header.Extra if len(extra) != 16+len("STARGZ") { return 0, 0, 0, fmt.Errorf("legacy: invalid stargz's extra field size") } if string(extra[16:]) != "STARGZ" { return 0, 0, 0, fmt.Errorf("legacy: magic string STARGZ not found") } tocOffset, err = strconv.ParseInt(string(extra[:16]), 16, 64) if err != nil { return 0, 0, 0, fmt.Errorf("legacy: failed to parse toc offset: %w", err) } return tocOffset, tocOffset, 0, nil } func (gz *LegacyGzipDecompressor) FooterSize() int64 { return legacyFooterSize } func (gz *LegacyGzipDecompressor) DecompressTOC(r io.Reader) (tocJSON io.ReadCloser, err error) { return decompressTOCEStargz(r) } func parseTOCEStargz(r io.Reader) (toc *JTOC, tocDgst digest.Digest, err error) { tr, err := decompressTOCEStargz(r) if err != nil { return nil, "", err } dgstr := digest.Canonical.Digester() toc = new(JTOC) if err := json.NewDecoder(io.TeeReader(tr, dgstr.Hash())).Decode(&toc); err != nil { return nil, "", fmt.Errorf("error decoding TOC JSON: %v", err) } if err := tr.Close(); err != nil { return nil, "", err } return toc, dgstr.Digest(), nil } func decompressTOCEStargz(r io.Reader) (tocJSON io.ReadCloser, err error) { zr, err := gzip.NewReader(r) if err != nil { return nil, fmt.Errorf("malformed TOC gzip header: %v", err) } zr.Multistream(false) tr := tar.NewReader(zr) h, err := tr.Next() if err != nil { return nil, fmt.Errorf("failed to find tar header in TOC gzip stream: %v", err) } if h.Name != TOCTarName { return nil, fmt.Errorf("TOC tar entry had name %q; expected %q", h.Name, TOCTarName) } return readCloser{tr, zr.Close}, nil } stargz-snapshotter-0.14.3/estargz/gzip_test.go000066400000000000000000000067331440204344700215120ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /* Copyright 2019 The Go Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. */ package estargz import ( "bytes" "compress/gzip" "fmt" "testing" ) // TestGzipEStargz tests gzip-based eStargz func TestGzipEStargz(t *testing.T) { CompressionTestSuite(t, gzipControllerWithLevel(gzip.NoCompression), gzipControllerWithLevel(gzip.BestSpeed), gzipControllerWithLevel(gzip.BestCompression), gzipControllerWithLevel(gzip.DefaultCompression), gzipControllerWithLevel(gzip.HuffmanOnly), ) } func gzipControllerWithLevel(compressionLevel int) TestingControllerFactory { return func() TestingController { return &gzipController{&GzipCompressor{compressionLevel}, &GzipDecompressor{}} } } type gzipController struct { *GzipCompressor *GzipDecompressor } func (gc *gzipController) String() string { return fmt.Sprintf("gzip_compression_level=%v", gc.GzipCompressor.compressionLevel) } // TestStream tests the passed estargz blob contains the specified list of streams. func (gc *gzipController) TestStreams(t *testing.T, b []byte, streams []int64) { CheckGzipHasStreams(t, b, streams) } func (gc *gzipController) DiffIDOf(t *testing.T, b []byte) string { return GzipDiffIDOf(t, b) } // Tests footer encoding, size, and parsing of gzip-based eStargz. func TestGzipFooter(t *testing.T) { for off := int64(0); off <= 200000; off += 1023 { checkFooter(t, off) checkLegacyFooter(t, off) } } // TODO: check fallback func checkFooter(t *testing.T, off int64) { footer := gzipFooterBytes(off) if len(footer) != FooterSize { t.Fatalf("for offset %v, footer length was %d, not expected %d. got bytes: %q", off, len(footer), FooterSize, footer) } _, got, _, err := (&GzipDecompressor{}).ParseFooter(footer) if err != nil { t.Fatalf("failed to parse footer for offset %d, footer: %x: err: %v", off, footer, err) } if got != off { t.Fatalf("ParseFooter(footerBytes(offset %d)) = %d; want %d", off, got, off) } } func checkLegacyFooter(t *testing.T, off int64) { footer := legacyFooterBytes(off) if len(footer) != legacyFooterSize { t.Fatalf("for offset %v, footer length was %d, not expected %d. got bytes: %q", off, len(footer), legacyFooterSize, footer) } _, got, _, err := (&LegacyGzipDecompressor{}).ParseFooter(footer) if err != nil { t.Fatalf("failed to parse legacy footer for offset %d, footer: %x: err: %v", off, footer, err) } if got != off { t.Fatalf("ParseFooter(legacyFooterBytes(offset %d)) = %d; want %d", off, got, off) } } func legacyFooterBytes(tocOff int64) []byte { buf := bytes.NewBuffer(make([]byte, 0, legacyFooterSize)) gz, _ := gzip.NewWriterLevel(buf, gzip.NoCompression) gz.Header.Extra = []byte(fmt.Sprintf("%016xSTARGZ", tocOff)) gz.Close() if buf.Len() != legacyFooterSize { panic(fmt.Sprintf("footer buffer = %d, not %d", buf.Len(), legacyFooterSize)) } return buf.Bytes() } stargz-snapshotter-0.14.3/estargz/testutil.go000066400000000000000000002077461440204344700213660ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /* Copyright 2019 The Go Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. */ package estargz import ( "archive/tar" "bytes" "compress/gzip" "crypto/sha256" "encoding/json" "errors" "fmt" "io" "math/rand" "os" "path/filepath" "reflect" "sort" "strings" "testing" "time" "github.com/containerd/stargz-snapshotter/estargz/errorutil" "github.com/klauspost/compress/zstd" digest "github.com/opencontainers/go-digest" ) func init() { rand.Seed(time.Now().UnixNano()) } // TestingController is Compression with some helper methods necessary for testing. type TestingController interface { Compression TestStreams(t *testing.T, b []byte, streams []int64) DiffIDOf(*testing.T, []byte) string String() string } // CompressionTestSuite tests this pkg with controllers can build valid eStargz blobs and parse them. func CompressionTestSuite(t *testing.T, controllers ...TestingControllerFactory) { t.Run("testBuild", func(t *testing.T) { t.Parallel(); testBuild(t, controllers...) }) t.Run("testDigestAndVerify", func(t *testing.T) { t.Parallel(); testDigestAndVerify(t, controllers...) }) t.Run("testWriteAndOpen", func(t *testing.T) { t.Parallel(); testWriteAndOpen(t, controllers...) }) } type TestingControllerFactory func() TestingController const ( uncompressedType int = iota gzipType zstdType ) var srcCompressions = []int{ uncompressedType, gzipType, zstdType, } var allowedPrefix = [4]string{"", "./", "/", "../"} // testBuild tests the resulting stargz blob built by this pkg has the same // contents as the normal stargz blob. func testBuild(t *testing.T, controllers ...TestingControllerFactory) { tests := []struct { name string chunkSize int minChunkSize []int in []tarEntry }{ { name: "regfiles and directories", chunkSize: 4, in: tarOf( file("foo", "test1"), dir("foo2/"), file("foo2/bar", "test2", xAttr(map[string]string{"test": "sample"})), ), }, { name: "empty files", chunkSize: 4, in: tarOf( file("foo", "tttttt"), file("foo_empty", ""), file("foo2", "tttttt"), file("foo_empty2", ""), file("foo3", "tttttt"), file("foo_empty3", ""), file("foo4", "tttttt"), file("foo_empty4", ""), file("foo5", "tttttt"), file("foo_empty5", ""), file("foo6", "tttttt"), ), }, { name: "various files", chunkSize: 4, minChunkSize: []int{0, 64000}, in: tarOf( file("baz.txt", "bazbazbazbazbazbazbaz"), file("foo1.txt", "a"), file("bar/foo2.txt", "b"), file("foo3.txt", "c"), symlink("barlink", "test/bar.txt"), dir("test/"), dir("dev/"), blockdev("dev/testblock", 3, 4), fifo("dev/testfifo"), chardev("dev/testchar1", 5, 6), file("test/bar.txt", "testbartestbar", xAttr(map[string]string{"test2": "sample2"})), dir("test2/"), link("test2/bazlink", "baz.txt"), chardev("dev/testchar2", 1, 2), ), }, { name: "no contents", chunkSize: 4, in: tarOf( file("baz.txt", ""), symlink("barlink", "test/bar.txt"), dir("test/"), dir("dev/"), blockdev("dev/testblock", 3, 4), fifo("dev/testfifo"), chardev("dev/testchar1", 5, 6), file("test/bar.txt", "", xAttr(map[string]string{"test2": "sample2"})), dir("test2/"), link("test2/bazlink", "baz.txt"), chardev("dev/testchar2", 1, 2), ), }, } for _, tt := range tests { if len(tt.minChunkSize) == 0 { tt.minChunkSize = []int{0} } for _, srcCompression := range srcCompressions { srcCompression := srcCompression for _, newCL := range controllers { newCL := newCL for _, srcTarFormat := range []tar.Format{tar.FormatUSTAR, tar.FormatPAX, tar.FormatGNU} { srcTarFormat := srcTarFormat for _, prefix := range allowedPrefix { prefix := prefix for _, minChunkSize := range tt.minChunkSize { minChunkSize := minChunkSize t.Run(tt.name+"-"+fmt.Sprintf("compression=%v,prefix=%q,src=%d,format=%s,minChunkSize=%d", newCL(), prefix, srcCompression, srcTarFormat, minChunkSize), func(t *testing.T) { tarBlob := buildTar(t, tt.in, prefix, srcTarFormat) // Test divideEntries() entries, err := sortEntries(tarBlob, nil, nil) // identical order if err != nil { t.Fatalf("failed to parse tar: %v", err) } var merged []*entry for _, part := range divideEntries(entries, 4) { merged = append(merged, part...) } if !reflect.DeepEqual(entries, merged) { for _, e := range entries { t.Logf("Original: %v", e.header) } for _, e := range merged { t.Logf("Merged: %v", e.header) } t.Errorf("divided entries couldn't be merged") return } // Prepare sample data cl1 := newCL() wantBuf := new(bytes.Buffer) sw := NewWriterWithCompressor(wantBuf, cl1) sw.MinChunkSize = minChunkSize sw.ChunkSize = tt.chunkSize if err := sw.AppendTar(tarBlob); err != nil { t.Fatalf("failed to append tar to want stargz: %v", err) } if _, err := sw.Close(); err != nil { t.Fatalf("failed to prepare want stargz: %v", err) } wantData := wantBuf.Bytes() want, err := Open(io.NewSectionReader( bytes.NewReader(wantData), 0, int64(len(wantData))), WithDecompressors(cl1), ) if err != nil { t.Fatalf("failed to parse the want stargz: %v", err) } // Prepare testing data var opts []Option if minChunkSize > 0 { opts = append(opts, WithMinChunkSize(minChunkSize)) } cl2 := newCL() rc, err := Build(compressBlob(t, tarBlob, srcCompression), append(opts, WithChunkSize(tt.chunkSize), WithCompression(cl2))...) if err != nil { t.Fatalf("failed to build stargz: %v", err) } defer rc.Close() gotBuf := new(bytes.Buffer) if _, err := io.Copy(gotBuf, rc); err != nil { t.Fatalf("failed to copy built stargz blob: %v", err) } gotData := gotBuf.Bytes() got, err := Open(io.NewSectionReader( bytes.NewReader(gotBuf.Bytes()), 0, int64(len(gotData))), WithDecompressors(cl2), ) if err != nil { t.Fatalf("failed to parse the got stargz: %v", err) } // Check DiffID is properly calculated rc.Close() diffID := rc.DiffID() wantDiffID := cl2.DiffIDOf(t, gotData) if diffID.String() != wantDiffID { t.Errorf("DiffID = %q; want %q", diffID, wantDiffID) } // Compare as stargz if !isSameVersion(t, cl1, wantData, cl2, gotData) { t.Errorf("built stargz hasn't same json") return } if !isSameEntries(t, want, got) { t.Errorf("built stargz isn't same as the original") return } // Compare as tar.gz if !isSameTarGz(t, cl1, wantData, cl2, gotData) { t.Errorf("built stargz isn't same tar.gz") return } }) } } } } } } } func isSameTarGz(t *testing.T, cla TestingController, a []byte, clb TestingController, b []byte) bool { aGz, err := cla.Reader(bytes.NewReader(a)) if err != nil { t.Fatalf("failed to read A") } defer aGz.Close() bGz, err := clb.Reader(bytes.NewReader(b)) if err != nil { t.Fatalf("failed to read B") } defer bGz.Close() // Same as tar's Next() method but ignores landmarks and TOCJSON file next := func(r *tar.Reader) (h *tar.Header, err error) { for { if h, err = r.Next(); err != nil { return } if h.Name != PrefetchLandmark && h.Name != NoPrefetchLandmark && h.Name != TOCTarName { return } } } aTar := tar.NewReader(aGz) bTar := tar.NewReader(bGz) for { // Fetch and parse next header. aH, aErr := next(aTar) bH, bErr := next(bTar) if aErr != nil || bErr != nil { if aErr == io.EOF && bErr == io.EOF { break } t.Fatalf("Failed to parse tar file: A: %v, B: %v", aErr, bErr) } if !reflect.DeepEqual(aH, bH) { t.Logf("different header (A = %v; B = %v)", aH, bH) return false } aFile, err := io.ReadAll(aTar) if err != nil { t.Fatal("failed to read tar payload of A") } bFile, err := io.ReadAll(bTar) if err != nil { t.Fatal("failed to read tar payload of B") } if !bytes.Equal(aFile, bFile) { t.Logf("different tar payload (A = %q; B = %q)", string(a), string(b)) return false } } return true } func isSameVersion(t *testing.T, cla TestingController, a []byte, clb TestingController, b []byte) bool { aJTOC, _, err := parseStargz(io.NewSectionReader(bytes.NewReader(a), 0, int64(len(a))), cla) if err != nil { t.Fatalf("failed to parse A: %v", err) } bJTOC, _, err := parseStargz(io.NewSectionReader(bytes.NewReader(b), 0, int64(len(b))), clb) if err != nil { t.Fatalf("failed to parse B: %v", err) } t.Logf("A: TOCJSON: %v", dumpTOCJSON(t, aJTOC)) t.Logf("B: TOCJSON: %v", dumpTOCJSON(t, bJTOC)) return aJTOC.Version == bJTOC.Version } func isSameEntries(t *testing.T, a, b *Reader) bool { aroot, ok := a.Lookup("") if !ok { t.Fatalf("failed to get root of A") } broot, ok := b.Lookup("") if !ok { t.Fatalf("failed to get root of B") } aEntry := stargzEntry{aroot, a} bEntry := stargzEntry{broot, b} return contains(t, aEntry, bEntry) && contains(t, bEntry, aEntry) } func compressBlob(t *testing.T, src *io.SectionReader, srcCompression int) *io.SectionReader { buf := new(bytes.Buffer) var w io.WriteCloser var err error if srcCompression == gzipType { w = gzip.NewWriter(buf) } else if srcCompression == zstdType { w, err = zstd.NewWriter(buf) if err != nil { t.Fatalf("failed to init zstd writer: %v", err) } } else { return src } src.Seek(0, io.SeekStart) if _, err := io.Copy(w, src); err != nil { t.Fatalf("failed to compress source") } if err := w.Close(); err != nil { t.Fatalf("failed to finalize compress source") } data := buf.Bytes() return io.NewSectionReader(bytes.NewReader(data), 0, int64(len(data))) } type stargzEntry struct { e *TOCEntry r *Reader } // contains checks if all child entries in "b" are also contained in "a". // This function also checks if the files/chunks contain the same contents among "a" and "b". func contains(t *testing.T, a, b stargzEntry) bool { ae, ar := a.e, a.r be, br := b.e, b.r t.Logf("Comparing: %q vs %q", ae.Name, be.Name) if !equalEntry(ae, be) { t.Logf("%q != %q: entry: a: %v, b: %v", ae.Name, be.Name, ae, be) return false } if ae.Type == "dir" { t.Logf("Directory: %q vs %q: %v vs %v", ae.Name, be.Name, allChildrenName(ae), allChildrenName(be)) iscontain := true ae.ForeachChild(func(aBaseName string, aChild *TOCEntry) bool { // Walk through all files on this stargz file. if aChild.Name == PrefetchLandmark || aChild.Name == NoPrefetchLandmark { return true // Ignore landmarks } // Ignore a TOCEntry of "./" (formated as "" by stargz lib) on root directory // because this points to the root directory itself. if aChild.Name == "" && ae.Name == "" { return true } bChild, ok := be.LookupChild(aBaseName) if !ok { t.Logf("%q (base: %q): not found in b: %v", ae.Name, aBaseName, allChildrenName(be)) iscontain = false return false } childcontain := contains(t, stargzEntry{aChild, a.r}, stargzEntry{bChild, b.r}) if !childcontain { t.Logf("%q != %q: non-equal dir", ae.Name, be.Name) iscontain = false return false } return true }) return iscontain } else if ae.Type == "reg" { af, err := ar.OpenFile(ae.Name) if err != nil { t.Fatalf("failed to open file %q on A: %v", ae.Name, err) } bf, err := br.OpenFile(be.Name) if err != nil { t.Fatalf("failed to open file %q on B: %v", be.Name, err) } var nr int64 for nr < ae.Size { abytes, anext, aok := readOffset(t, af, nr, a) bbytes, bnext, bok := readOffset(t, bf, nr, b) if !aok && !bok { break } else if !(aok && bok) || anext != bnext { t.Logf("%q != %q (offset=%d): chunk existence a=%v vs b=%v, anext=%v vs bnext=%v", ae.Name, be.Name, nr, aok, bok, anext, bnext) return false } nr = anext if !bytes.Equal(abytes, bbytes) { t.Logf("%q != %q: different contents %v vs %v", ae.Name, be.Name, string(abytes), string(bbytes)) return false } } return true } return true } func allChildrenName(e *TOCEntry) (children []string) { e.ForeachChild(func(baseName string, _ *TOCEntry) bool { children = append(children, baseName) return true }) return } func equalEntry(a, b *TOCEntry) bool { // Here, we selectively compare fileds that we are interested in. return a.Name == b.Name && a.Type == b.Type && a.Size == b.Size && a.ModTime3339 == b.ModTime3339 && a.Stat().ModTime().Equal(b.Stat().ModTime()) && // modTime time.Time a.LinkName == b.LinkName && a.Mode == b.Mode && a.UID == b.UID && a.GID == b.GID && a.Uname == b.Uname && a.Gname == b.Gname && (a.Offset >= 0) == (b.Offset >= 0) && (a.NextOffset() > 0) == (b.NextOffset() > 0) && a.DevMajor == b.DevMajor && a.DevMinor == b.DevMinor && a.NumLink == b.NumLink && reflect.DeepEqual(a.Xattrs, b.Xattrs) && // chunk-related infomations aren't compared in this function. // ChunkOffset int64 `json:"chunkOffset,omitempty"` // ChunkSize int64 `json:"chunkSize,omitempty"` // children map[string]*TOCEntry a.Digest == b.Digest } func readOffset(t *testing.T, r *io.SectionReader, offset int64, e stargzEntry) ([]byte, int64, bool) { ce, ok := e.r.ChunkEntryForOffset(e.e.Name, offset) if !ok { return nil, 0, false } data := make([]byte, ce.ChunkSize) t.Logf("Offset: %v, NextOffset: %v", ce.Offset, ce.NextOffset()) n, err := r.ReadAt(data, ce.ChunkOffset) if err != nil { t.Fatalf("failed to read file payload of %q (offset:%d,size:%d): %v", e.e.Name, ce.ChunkOffset, ce.ChunkSize, err) } if int64(n) != ce.ChunkSize { t.Fatalf("unexpected copied data size %d; want %d", n, ce.ChunkSize) } return data[:n], offset + ce.ChunkSize, true } func dumpTOCJSON(t *testing.T, tocJSON *JTOC) string { jtocData, err := json.Marshal(*tocJSON) if err != nil { t.Fatalf("failed to marshal TOC JSON: %v", err) } buf := new(bytes.Buffer) if _, err := io.Copy(buf, bytes.NewReader(jtocData)); err != nil { t.Fatalf("failed to read toc json blob: %v", err) } return buf.String() } const chunkSize = 3 // type check func(t *testing.T, sgzData []byte, tocDigest digest.Digest, dgstMap map[string]digest.Digest, compressionLevel int) type check func(t *testing.T, sgzData []byte, tocDigest digest.Digest, dgstMap map[string]digest.Digest, controller TestingController, newController TestingControllerFactory) // testDigestAndVerify runs specified checks against sample stargz blobs. func testDigestAndVerify(t *testing.T, controllers ...TestingControllerFactory) { tests := []struct { name string tarInit func(t *testing.T, dgstMap map[string]digest.Digest) (blob []tarEntry) checks []check minChunkSize []int }{ { name: "no-regfile", tarInit: func(t *testing.T, dgstMap map[string]digest.Digest) (blob []tarEntry) { return tarOf( dir("test/"), ) }, checks: []check{ checkStargzTOC, checkVerifyTOC, checkVerifyInvalidStargzFail(buildTar(t, tarOf( dir("test2/"), // modified ), allowedPrefix[0])), }, }, { name: "small-files", tarInit: func(t *testing.T, dgstMap map[string]digest.Digest) (blob []tarEntry) { return tarOf( regDigest(t, "baz.txt", "", dgstMap), regDigest(t, "foo.txt", "a", dgstMap), dir("test/"), regDigest(t, "test/bar.txt", "bbb", dgstMap), ) }, minChunkSize: []int{0, 64000}, checks: []check{ checkStargzTOC, checkVerifyTOC, checkVerifyInvalidStargzFail(buildTar(t, tarOf( file("baz.txt", ""), file("foo.txt", "M"), // modified dir("test/"), file("test/bar.txt", "bbb"), ), allowedPrefix[0])), // checkVerifyInvalidTOCEntryFail("foo.txt"), // TODO checkVerifyBrokenContentFail("foo.txt"), }, }, { name: "big-files", tarInit: func(t *testing.T, dgstMap map[string]digest.Digest) (blob []tarEntry) { return tarOf( regDigest(t, "baz.txt", "bazbazbazbazbazbazbaz", dgstMap), regDigest(t, "foo.txt", "a", dgstMap), dir("test/"), regDigest(t, "test/bar.txt", "testbartestbar", dgstMap), ) }, checks: []check{ checkStargzTOC, checkVerifyTOC, checkVerifyInvalidStargzFail(buildTar(t, tarOf( file("baz.txt", "bazbazbazMMMbazbazbaz"), // modified file("foo.txt", "a"), dir("test/"), file("test/bar.txt", "testbartestbar"), ), allowedPrefix[0])), checkVerifyInvalidTOCEntryFail("test/bar.txt"), checkVerifyBrokenContentFail("test/bar.txt"), }, }, { name: "with-non-regfiles", minChunkSize: []int{0, 64000}, tarInit: func(t *testing.T, dgstMap map[string]digest.Digest) (blob []tarEntry) { return tarOf( regDigest(t, "baz.txt", "bazbazbazbazbazbazbaz", dgstMap), regDigest(t, "foo.txt", "a", dgstMap), regDigest(t, "bar/foo2.txt", "b", dgstMap), regDigest(t, "foo3.txt", "c", dgstMap), symlink("barlink", "test/bar.txt"), dir("test/"), regDigest(t, "test/bar.txt", "testbartestbar", dgstMap), dir("test2/"), link("test2/bazlink", "baz.txt"), ) }, checks: []check{ checkStargzTOC, checkVerifyTOC, checkVerifyInvalidStargzFail(buildTar(t, tarOf( file("baz.txt", "bazbazbazbazbazbazbaz"), file("foo.txt", "a"), file("bar/foo2.txt", "b"), file("foo3.txt", "c"), symlink("barlink", "test/bar.txt"), dir("test/"), file("test/bar.txt", "testbartestbar"), dir("test2/"), link("test2/bazlink", "foo.txt"), // modified ), allowedPrefix[0])), checkVerifyInvalidTOCEntryFail("test/bar.txt"), checkVerifyBrokenContentFail("test/bar.txt"), }, }, } for _, tt := range tests { if len(tt.minChunkSize) == 0 { tt.minChunkSize = []int{0} } for _, srcCompression := range srcCompressions { srcCompression := srcCompression for _, newCL := range controllers { newCL := newCL for _, prefix := range allowedPrefix { prefix := prefix for _, srcTarFormat := range []tar.Format{tar.FormatUSTAR, tar.FormatPAX, tar.FormatGNU} { srcTarFormat := srcTarFormat for _, minChunkSize := range tt.minChunkSize { minChunkSize := minChunkSize t.Run(tt.name+"-"+fmt.Sprintf("compression=%v,prefix=%q,format=%s,minChunkSize=%d", newCL(), prefix, srcTarFormat, minChunkSize), func(t *testing.T) { // Get original tar file and chunk digests dgstMap := make(map[string]digest.Digest) tarBlob := buildTar(t, tt.tarInit(t, dgstMap), prefix, srcTarFormat) cl := newCL() rc, err := Build(compressBlob(t, tarBlob, srcCompression), WithChunkSize(chunkSize), WithCompression(cl)) if err != nil { t.Fatalf("failed to convert stargz: %v", err) } tocDigest := rc.TOCDigest() defer rc.Close() buf := new(bytes.Buffer) if _, err := io.Copy(buf, rc); err != nil { t.Fatalf("failed to copy built stargz blob: %v", err) } newStargz := buf.Bytes() // NoPrefetchLandmark is added during `Bulid`, which is expected behaviour. dgstMap[chunkID(NoPrefetchLandmark, 0, int64(len([]byte{landmarkContents})))] = digest.FromBytes([]byte{landmarkContents}) for _, check := range tt.checks { check(t, newStargz, tocDigest, dgstMap, cl, newCL) } }) } } } } } } } // checkStargzTOC checks the TOC JSON of the passed stargz has the expected // digest and contains valid chunks. It walks all entries in the stargz and // checks all chunk digests stored to the TOC JSON match the actual contents. func checkStargzTOC(t *testing.T, sgzData []byte, tocDigest digest.Digest, dgstMap map[string]digest.Digest, controller TestingController, newController TestingControllerFactory) { sgz, err := Open( io.NewSectionReader(bytes.NewReader(sgzData), 0, int64(len(sgzData))), WithDecompressors(controller), ) if err != nil { t.Errorf("failed to parse converted stargz: %v", err) return } digestMapTOC, err := listDigests(io.NewSectionReader( bytes.NewReader(sgzData), 0, int64(len(sgzData))), controller, ) if err != nil { t.Fatalf("failed to list digest: %v", err) } found := make(map[string]bool) for id := range dgstMap { found[id] = false } zr, err := controller.Reader(bytes.NewReader(sgzData)) if err != nil { t.Fatalf("failed to decompress converted stargz: %v", err) } defer zr.Close() tr := tar.NewReader(zr) for { h, err := tr.Next() if err != nil { if err != io.EOF { t.Errorf("failed to read tar entry: %v", err) return } break } if h.Name == TOCTarName { // Check the digest of TOC JSON based on the actual contents // It's sure that TOC JSON exists in this archive because // Open succeeded. dgstr := digest.Canonical.Digester() if _, err := io.Copy(dgstr.Hash(), tr); err != nil { t.Fatalf("failed to calculate digest of TOC JSON: %v", err) } if dgstr.Digest() != tocDigest { t.Errorf("invalid TOC JSON %q; want %q", tocDigest, dgstr.Digest()) } continue } if _, ok := sgz.Lookup(h.Name); !ok { t.Errorf("lost stargz entry %q in the converted TOC", h.Name) return } var n int64 for n < h.Size { ce, ok := sgz.ChunkEntryForOffset(h.Name, n) if !ok { t.Errorf("lost chunk %q(offset=%d) in the converted TOC", h.Name, n) return } // Get the original digest to make sure the file contents are kept unchanged // from the original tar, during the whole conversion steps. id := chunkID(h.Name, n, ce.ChunkSize) want, ok := dgstMap[id] if !ok { t.Errorf("Unexpected chunk %q(offset=%d,size=%d): %v", h.Name, n, ce.ChunkSize, dgstMap) return } found[id] = true // Check the file contents dgstr := digest.Canonical.Digester() if _, err := io.CopyN(dgstr.Hash(), tr, ce.ChunkSize); err != nil { t.Fatalf("failed to calculate digest of %q (offset=%d,size=%d)", h.Name, n, ce.ChunkSize) } if want != dgstr.Digest() { t.Errorf("Invalid contents in converted stargz %q: %q; want %q", h.Name, dgstr.Digest(), want) return } // Check the digest stored in TOC JSON dgstTOC, ok := digestMapTOC[ce.Offset] if !ok { t.Errorf("digest of %q(offset=%d,size=%d,chunkOffset=%d) isn't registered", h.Name, ce.Offset, ce.ChunkSize, ce.ChunkOffset) } if want != dgstTOC { t.Errorf("Invalid digest in TOCEntry %q: %q; want %q", h.Name, dgstTOC, want) return } n += ce.ChunkSize } } for id, ok := range found { if !ok { t.Errorf("required chunk %q not found in the converted stargz: %v", id, found) } } } // checkVerifyTOC checks the verification works for the TOC JSON of the passed // stargz. It walks all entries in the stargz and checks the verifications for // all chunks work. func checkVerifyTOC(t *testing.T, sgzData []byte, tocDigest digest.Digest, dgstMap map[string]digest.Digest, controller TestingController, newController TestingControllerFactory) { sgz, err := Open( io.NewSectionReader(bytes.NewReader(sgzData), 0, int64(len(sgzData))), WithDecompressors(controller), ) if err != nil { t.Errorf("failed to parse converted stargz: %v", err) return } ev, err := sgz.VerifyTOC(tocDigest) if err != nil { t.Errorf("failed to verify stargz: %v", err) return } found := make(map[string]bool) for id := range dgstMap { found[id] = false } zr, err := controller.Reader(bytes.NewReader(sgzData)) if err != nil { t.Fatalf("failed to decompress converted stargz: %v", err) } defer zr.Close() tr := tar.NewReader(zr) for { h, err := tr.Next() if err != nil { if err != io.EOF { t.Errorf("failed to read tar entry: %v", err) return } break } if h.Name == TOCTarName { continue } if _, ok := sgz.Lookup(h.Name); !ok { t.Errorf("lost stargz entry %q in the converted TOC", h.Name) return } var n int64 for n < h.Size { ce, ok := sgz.ChunkEntryForOffset(h.Name, n) if !ok { t.Errorf("lost chunk %q(offset=%d) in the converted TOC", h.Name, n) return } v, err := ev.Verifier(ce) if err != nil { t.Errorf("failed to get verifier for %q(offset=%d)", h.Name, n) } found[chunkID(h.Name, n, ce.ChunkSize)] = true // Check the file contents if _, err := io.CopyN(v, tr, ce.ChunkSize); err != nil { t.Fatalf("failed to get chunk of %q (offset=%d,size=%d)", h.Name, n, ce.ChunkSize) } if !v.Verified() { t.Errorf("Invalid contents in converted stargz %q (should be succeeded)", h.Name) return } n += ce.ChunkSize } } for id, ok := range found { if !ok { t.Errorf("required chunk %q not found in the converted stargz: %v", id, found) } } } // checkVerifyInvalidTOCEntryFail checks if misconfigured TOC JSON can be // detected during the verification and the verification returns an error. func checkVerifyInvalidTOCEntryFail(filename string) check { return func(t *testing.T, sgzData []byte, tocDigest digest.Digest, dgstMap map[string]digest.Digest, controller TestingController, newController TestingControllerFactory) { funcs := map[string]rewriteFunc{ "lost digest in a entry": func(t *testing.T, toc *JTOC, sgz *io.SectionReader) { var found bool for _, e := range toc.Entries { if cleanEntryName(e.Name) == filename { if e.Type != "reg" && e.Type != "chunk" { t.Fatalf("entry %q to break must be regfile or chunk", filename) } if e.ChunkDigest == "" { t.Fatalf("entry %q is already invalid", filename) } e.ChunkDigest = "" found = true } } if !found { t.Fatalf("rewrite target not found") } }, "duplicated entry offset": func(t *testing.T, toc *JTOC, sgz *io.SectionReader) { var ( sampleEntry *TOCEntry targetEntry *TOCEntry ) for _, e := range toc.Entries { if e.Type == "reg" || e.Type == "chunk" { if cleanEntryName(e.Name) == filename { targetEntry = e } else { sampleEntry = e } } } if sampleEntry == nil { t.Fatalf("TOC must contain at least one regfile or chunk entry other than the rewrite target") } if targetEntry == nil { t.Fatalf("rewrite target not found") } targetEntry.Offset = sampleEntry.Offset }, } for name, rFunc := range funcs { t.Run(name, func(t *testing.T) { newSgz, newTocDigest := rewriteTOCJSON(t, io.NewSectionReader(bytes.NewReader(sgzData), 0, int64(len(sgzData))), rFunc, controller) buf := new(bytes.Buffer) if _, err := io.Copy(buf, newSgz); err != nil { t.Fatalf("failed to get converted stargz") } isgz := buf.Bytes() sgz, err := Open( io.NewSectionReader(bytes.NewReader(isgz), 0, int64(len(isgz))), WithDecompressors(controller), ) if err != nil { t.Fatalf("failed to parse converted stargz: %v", err) return } _, err = sgz.VerifyTOC(newTocDigest) if err == nil { t.Errorf("must fail for invalid TOC") return } }) } } } // checkVerifyInvalidStargzFail checks if the verification detects that the // given stargz file doesn't match to the expected digest and returns error. func checkVerifyInvalidStargzFail(invalid *io.SectionReader) check { return func(t *testing.T, sgzData []byte, tocDigest digest.Digest, dgstMap map[string]digest.Digest, controller TestingController, newController TestingControllerFactory) { cl := newController() rc, err := Build(invalid, WithChunkSize(chunkSize), WithCompression(cl)) if err != nil { t.Fatalf("failed to convert stargz: %v", err) } defer rc.Close() buf := new(bytes.Buffer) if _, err := io.Copy(buf, rc); err != nil { t.Fatalf("failed to copy built stargz blob: %v", err) } mStargz := buf.Bytes() sgz, err := Open( io.NewSectionReader(bytes.NewReader(mStargz), 0, int64(len(mStargz))), WithDecompressors(cl), ) if err != nil { t.Fatalf("failed to parse converted stargz: %v", err) return } _, err = sgz.VerifyTOC(tocDigest) if err == nil { t.Errorf("must fail for invalid TOC") return } } } // checkVerifyBrokenContentFail checks if the verifier detects broken contents // that doesn't match to the expected digest and returns error. func checkVerifyBrokenContentFail(filename string) check { return func(t *testing.T, sgzData []byte, tocDigest digest.Digest, dgstMap map[string]digest.Digest, controller TestingController, newController TestingControllerFactory) { // Parse stargz file sgz, err := Open( io.NewSectionReader(bytes.NewReader(sgzData), 0, int64(len(sgzData))), WithDecompressors(controller), ) if err != nil { t.Fatalf("failed to parse converted stargz: %v", err) return } ev, err := sgz.VerifyTOC(tocDigest) if err != nil { t.Fatalf("failed to verify stargz: %v", err) return } // Open the target file sr, err := sgz.OpenFile(filename) if err != nil { t.Fatalf("failed to open file %q", filename) } ce, ok := sgz.ChunkEntryForOffset(filename, 0) if !ok { t.Fatalf("lost chunk %q(offset=%d) in the converted TOC", filename, 0) return } if ce.ChunkSize == 0 { t.Fatalf("file mustn't be empty") return } data := make([]byte, ce.ChunkSize) if _, err := sr.ReadAt(data, ce.ChunkOffset); err != nil { t.Errorf("failed to get data of a chunk of %q(offset=%q)", filename, ce.ChunkOffset) } // Check the broken chunk (must fail) v, err := ev.Verifier(ce) if err != nil { t.Fatalf("failed to get verifier for %q", filename) } broken := append([]byte{^data[0]}, data[1:]...) if _, err := io.CopyN(v, bytes.NewReader(broken), ce.ChunkSize); err != nil { t.Fatalf("failed to get chunk of %q (offset=%d,size=%d)", filename, ce.ChunkOffset, ce.ChunkSize) } if v.Verified() { t.Errorf("verification must fail for broken file chunk %q(org:%q,broken:%q)", filename, data, broken) } } } func chunkID(name string, offset, size int64) string { return fmt.Sprintf("%s-%d-%d", cleanEntryName(name), offset, size) } type rewriteFunc func(t *testing.T, toc *JTOC, sgz *io.SectionReader) func rewriteTOCJSON(t *testing.T, sgz *io.SectionReader, rewrite rewriteFunc, controller TestingController) (newSgz io.Reader, tocDigest digest.Digest) { decodedJTOC, jtocOffset, err := parseStargz(sgz, controller) if err != nil { t.Fatalf("failed to extract TOC JSON: %v", err) } rewrite(t, decodedJTOC, sgz) tocFooter, tocDigest, err := tocAndFooter(controller, decodedJTOC, jtocOffset) if err != nil { t.Fatalf("failed to create toc and footer: %v", err) } // Reconstruct stargz file with the modified TOC JSON if _, err := sgz.Seek(0, io.SeekStart); err != nil { t.Fatalf("failed to reset the seek position of stargz: %v", err) } return io.MultiReader( io.LimitReader(sgz, jtocOffset), // Original stargz (before TOC JSON) tocFooter, // Rewritten TOC and footer ), tocDigest } func listDigests(sgz *io.SectionReader, controller TestingController) (map[int64]digest.Digest, error) { decodedJTOC, _, err := parseStargz(sgz, controller) if err != nil { return nil, err } digestMap := make(map[int64]digest.Digest) for _, e := range decodedJTOC.Entries { if e.Type == "reg" || e.Type == "chunk" { if e.Type == "reg" && e.Size == 0 { continue // ignores empty file } if e.ChunkDigest == "" { return nil, fmt.Errorf("ChunkDigest of %q(off=%d) not found in TOC JSON", e.Name, e.Offset) } d, err := digest.Parse(e.ChunkDigest) if err != nil { return nil, err } digestMap[e.Offset] = d } } return digestMap, nil } func parseStargz(sgz *io.SectionReader, controller TestingController) (decodedJTOC *JTOC, jtocOffset int64, err error) { fSize := controller.FooterSize() footer := make([]byte, fSize) if _, err := sgz.ReadAt(footer, sgz.Size()-fSize); err != nil { return nil, 0, fmt.Errorf("error reading footer: %w", err) } _, tocOffset, _, err := controller.ParseFooter(footer[positive(int64(len(footer))-fSize):]) if err != nil { return nil, 0, fmt.Errorf("failed to parse footer: %w", err) } // Decode the TOC JSON var tocReader io.Reader if tocOffset >= 0 { tocReader = io.NewSectionReader(sgz, tocOffset, sgz.Size()-tocOffset-fSize) } decodedJTOC, _, err = controller.ParseTOC(tocReader) if err != nil { return nil, 0, fmt.Errorf("failed to parse TOC: %w", err) } return decodedJTOC, tocOffset, nil } func testWriteAndOpen(t *testing.T, controllers ...TestingControllerFactory) { const content = "Some contents" invalidUtf8 := "\xff\xfe\xfd" xAttrFile := xAttr{"foo": "bar", "invalid-utf8": invalidUtf8} sampleOwner := owner{uid: 50, gid: 100} data64KB := randomContents(64000) tests := []struct { name string chunkSize int minChunkSize int in []tarEntry want []stargzCheck wantNumGz int // expected number of streams wantNumGzLossLess int // expected number of streams (> 0) in lossless mode if it's different from wantNumGz wantFailOnLossLess bool wantTOCVersion int // default = 1 }{ { name: "empty", in: tarOf(), wantNumGz: 2, // (empty tar) + TOC + footer want: checks( numTOCEntries(0), ), }, { name: "1dir_1empty_file", in: tarOf( dir("foo/"), file("foo/bar.txt", ""), ), wantNumGz: 3, // dir, TOC, footer want: checks( numTOCEntries(2), hasDir("foo/"), hasFileLen("foo/bar.txt", 0), entryHasChildren("foo", "bar.txt"), hasFileDigest("foo/bar.txt", digestFor("")), ), }, { name: "1dir_1file", in: tarOf( dir("foo/"), file("foo/bar.txt", content, xAttrFile), ), wantNumGz: 4, // var dir, foo.txt alone, TOC, footer want: checks( numTOCEntries(2), hasDir("foo/"), hasFileLen("foo/bar.txt", len(content)), hasFileDigest("foo/bar.txt", digestFor(content)), hasFileContentsRange("foo/bar.txt", 0, content), hasFileContentsRange("foo/bar.txt", 1, content[1:]), entryHasChildren("", "foo"), entryHasChildren("foo", "bar.txt"), hasFileXattrs("foo/bar.txt", "foo", "bar"), hasFileXattrs("foo/bar.txt", "invalid-utf8", invalidUtf8), ), }, { name: "2meta_2file", in: tarOf( dir("bar/", sampleOwner), dir("foo/", sampleOwner), file("foo/bar.txt", content, sampleOwner), ), wantNumGz: 4, // both dirs, foo.txt alone, TOC, footer want: checks( numTOCEntries(3), hasDir("bar/"), hasDir("foo/"), hasFileLen("foo/bar.txt", len(content)), entryHasChildren("", "bar", "foo"), entryHasChildren("foo", "bar.txt"), hasChunkEntries("foo/bar.txt", 1), hasEntryOwner("bar/", sampleOwner), hasEntryOwner("foo/", sampleOwner), hasEntryOwner("foo/bar.txt", sampleOwner), ), }, { name: "3dir", in: tarOf( dir("bar/"), dir("foo/"), dir("foo/bar/"), ), wantNumGz: 3, // 3 dirs, TOC, footer want: checks( hasDirLinkCount("bar/", 2), hasDirLinkCount("foo/", 3), hasDirLinkCount("foo/bar/", 2), ), }, { name: "symlink", in: tarOf( dir("foo/"), symlink("foo/bar", "../../x"), ), wantNumGz: 3, // metas + TOC + footer want: checks( numTOCEntries(2), hasSymlink("foo/bar", "../../x"), entryHasChildren("", "foo"), entryHasChildren("foo", "bar"), ), }, { name: "chunked_file", chunkSize: 4, in: tarOf( dir("foo/"), file("foo/big.txt", "This "+"is s"+"uch "+"a bi"+"g fi"+"le"), ), wantNumGz: 9, // dir + big.txt(6 chunks) + TOC + footer want: checks( numTOCEntries(7), // 1 for foo dir, 6 for the foo/big.txt file hasDir("foo/"), hasFileLen("foo/big.txt", len("This is such a big file")), hasFileDigest("foo/big.txt", digestFor("This is such a big file")), hasFileContentsRange("foo/big.txt", 0, "This is such a big file"), hasFileContentsRange("foo/big.txt", 1, "his is such a big file"), hasFileContentsRange("foo/big.txt", 2, "is is such a big file"), hasFileContentsRange("foo/big.txt", 3, "s is such a big file"), hasFileContentsRange("foo/big.txt", 4, " is such a big file"), hasFileContentsRange("foo/big.txt", 5, "is such a big file"), hasFileContentsRange("foo/big.txt", 6, "s such a big file"), hasFileContentsRange("foo/big.txt", 7, " such a big file"), hasFileContentsRange("foo/big.txt", 8, "such a big file"), hasFileContentsRange("foo/big.txt", 9, "uch a big file"), hasFileContentsRange("foo/big.txt", 10, "ch a big file"), hasFileContentsRange("foo/big.txt", 11, "h a big file"), hasFileContentsRange("foo/big.txt", 12, " a big file"), hasFileContentsRange("foo/big.txt", len("This is such a big file")-1, ""), hasChunkEntries("foo/big.txt", 6), ), }, { name: "recursive", in: tarOf( dir("/", sampleOwner), dir("bar/", sampleOwner), dir("foo/", sampleOwner), file("foo/bar.txt", content, sampleOwner), ), wantNumGz: 4, // dirs, bar.txt alone, TOC, footer want: checks( maxDepth(2), // 0: root directory, 1: "foo/", 2: "bar.txt" ), }, { name: "block_char_fifo", in: tarOf( tarEntryFunc(func(w *tar.Writer, prefix string, format tar.Format) error { return w.WriteHeader(&tar.Header{ Name: prefix + "b", Typeflag: tar.TypeBlock, Devmajor: 123, Devminor: 456, Format: format, }) }), tarEntryFunc(func(w *tar.Writer, prefix string, format tar.Format) error { return w.WriteHeader(&tar.Header{ Name: prefix + "c", Typeflag: tar.TypeChar, Devmajor: 111, Devminor: 222, Format: format, }) }), tarEntryFunc(func(w *tar.Writer, prefix string, format tar.Format) error { return w.WriteHeader(&tar.Header{ Name: prefix + "f", Typeflag: tar.TypeFifo, Format: format, }) }), ), wantNumGz: 3, want: checks( lookupMatch("b", &TOCEntry{Name: "b", Type: "block", DevMajor: 123, DevMinor: 456, NumLink: 1}), lookupMatch("c", &TOCEntry{Name: "c", Type: "char", DevMajor: 111, DevMinor: 222, NumLink: 1}), lookupMatch("f", &TOCEntry{Name: "f", Type: "fifo", NumLink: 1}), ), }, { name: "modes", in: tarOf( dir("foo1/", 0755|os.ModeDir|os.ModeSetgid), file("foo1/bar1", content, 0700|os.ModeSetuid), file("foo1/bar2", content, 0755|os.ModeSetgid), dir("foo2/", 0755|os.ModeDir|os.ModeSticky), file("foo2/bar3", content, 0755|os.ModeSticky), dir("foo3/", 0755|os.ModeDir), file("foo3/bar4", content, os.FileMode(0700)), file("foo3/bar5", content, os.FileMode(0755)), ), wantNumGz: 8, // dir, bar1 alone, bar2 alone + dir, bar3 alone + dir, bar4 alone, bar5 alone, TOC, footer want: checks( hasMode("foo1/", 0755|os.ModeDir|os.ModeSetgid), hasMode("foo1/bar1", 0700|os.ModeSetuid), hasMode("foo1/bar2", 0755|os.ModeSetgid), hasMode("foo2/", 0755|os.ModeDir|os.ModeSticky), hasMode("foo2/bar3", 0755|os.ModeSticky), hasMode("foo3/", 0755|os.ModeDir), hasMode("foo3/bar4", os.FileMode(0700)), hasMode("foo3/bar5", os.FileMode(0755)), ), }, { name: "lossy", in: tarOf( dir("bar/", sampleOwner), dir("foo/", sampleOwner), file("foo/bar.txt", content, sampleOwner), file(TOCTarName, "dummy"), // ignored by the writer. (lossless write returns error) ), wantNumGz: 4, // both dirs, foo.txt alone, TOC, footer want: checks( numTOCEntries(3), hasDir("bar/"), hasDir("foo/"), hasFileLen("foo/bar.txt", len(content)), entryHasChildren("", "bar", "foo"), entryHasChildren("foo", "bar.txt"), hasChunkEntries("foo/bar.txt", 1), hasEntryOwner("bar/", sampleOwner), hasEntryOwner("foo/", sampleOwner), hasEntryOwner("foo/bar.txt", sampleOwner), ), wantFailOnLossLess: true, }, { name: "hardlink should be replaced to the destination entry", in: tarOf( dir("foo/"), file("foo/foo1", "test"), link("foolink", "foo/foo1"), ), wantNumGz: 4, // dir, foo1 + link, TOC, footer want: checks( mustSameEntry("foo/foo1", "foolink"), ), }, { name: "several_files_in_chunk", minChunkSize: 8000, in: tarOf( dir("foo/"), file("foo/foo1", data64KB), file("foo2", "bb"), file("foo22", "ccc"), dir("bar/"), file("bar/bar.txt", "aaa"), file("foo3", data64KB), ), // NOTE: we assume that the compressed "data64KB" is still larger than 8KB wantNumGz: 4, // dir+foo1, foo2+foo22+dir+bar.txt+foo3, TOC, footer want: checks( numTOCEntries(7), // dir, foo1, foo2, foo22, dir, bar.txt, foo3 hasDir("foo/"), hasDir("bar/"), hasFileLen("foo/foo1", len(data64KB)), hasFileLen("foo2", len("bb")), hasFileLen("foo22", len("ccc")), hasFileLen("bar/bar.txt", len("aaa")), hasFileLen("foo3", len(data64KB)), hasFileDigest("foo/foo1", digestFor(data64KB)), hasFileDigest("foo2", digestFor("bb")), hasFileDigest("foo22", digestFor("ccc")), hasFileDigest("bar/bar.txt", digestFor("aaa")), hasFileDigest("foo3", digestFor(data64KB)), hasFileContentsWithPreRead("foo22", 0, "ccc", chunkInfo{"foo2", "bb"}, chunkInfo{"bar/bar.txt", "aaa"}, chunkInfo{"foo3", data64KB}), hasFileContentsRange("foo/foo1", 0, data64KB), hasFileContentsRange("foo2", 0, "bb"), hasFileContentsRange("foo2", 1, "b"), hasFileContentsRange("foo22", 0, "ccc"), hasFileContentsRange("foo22", 1, "cc"), hasFileContentsRange("foo22", 2, "c"), hasFileContentsRange("bar/bar.txt", 0, "aaa"), hasFileContentsRange("bar/bar.txt", 1, "aa"), hasFileContentsRange("bar/bar.txt", 2, "a"), hasFileContentsRange("foo3", 0, data64KB), hasFileContentsRange("foo3", 1, data64KB[1:]), hasFileContentsRange("foo3", 2, data64KB[2:]), hasFileContentsRange("foo3", len(data64KB)/2, data64KB[len(data64KB)/2:]), hasFileContentsRange("foo3", len(data64KB)-1, data64KB[len(data64KB)-1:]), ), }, { name: "several_files_in_chunk_chunked", minChunkSize: 8000, chunkSize: 32000, in: tarOf( dir("foo/"), file("foo/foo1", data64KB), file("foo2", "bb"), dir("bar/"), file("foo3", data64KB), ), // NOTE: we assume that the compressed chunk of "data64KB" is still larger than 8KB wantNumGz: 6, // dir+foo1(1), foo1(2), foo2+dir+foo3(1), foo3(2), TOC, footer want: checks( numTOCEntries(7), // dir, foo1(2 chunks), foo2, dir, foo3(2 chunks) hasDir("foo/"), hasDir("bar/"), hasFileLen("foo/foo1", len(data64KB)), hasFileLen("foo2", len("bb")), hasFileLen("foo3", len(data64KB)), hasFileDigest("foo/foo1", digestFor(data64KB)), hasFileDigest("foo2", digestFor("bb")), hasFileDigest("foo3", digestFor(data64KB)), hasFileContentsWithPreRead("foo2", 0, "bb", chunkInfo{"foo3", data64KB[:32000]}), hasFileContentsRange("foo/foo1", 0, data64KB), hasFileContentsRange("foo/foo1", 1, data64KB[1:]), hasFileContentsRange("foo/foo1", 2, data64KB[2:]), hasFileContentsRange("foo/foo1", len(data64KB)/2, data64KB[len(data64KB)/2:]), hasFileContentsRange("foo/foo1", len(data64KB)-1, data64KB[len(data64KB)-1:]), hasFileContentsRange("foo2", 0, "bb"), hasFileContentsRange("foo2", 1, "b"), hasFileContentsRange("foo3", 0, data64KB), hasFileContentsRange("foo3", 1, data64KB[1:]), hasFileContentsRange("foo3", 2, data64KB[2:]), hasFileContentsRange("foo3", len(data64KB)/2, data64KB[len(data64KB)/2:]), hasFileContentsRange("foo3", len(data64KB)-1, data64KB[len(data64KB)-1:]), ), }, } for _, tt := range tests { for _, newCL := range controllers { newCL := newCL for _, prefix := range allowedPrefix { prefix := prefix for _, srcTarFormat := range []tar.Format{tar.FormatUSTAR, tar.FormatPAX, tar.FormatGNU} { srcTarFormat := srcTarFormat for _, lossless := range []bool{true, false} { t.Run(tt.name+"-"+fmt.Sprintf("compression=%v,prefix=%q,lossless=%v,format=%s", newCL(), prefix, lossless, srcTarFormat), func(t *testing.T) { var tr io.Reader = buildTar(t, tt.in, prefix, srcTarFormat) origTarDgstr := digest.Canonical.Digester() tr = io.TeeReader(tr, origTarDgstr.Hash()) var stargzBuf bytes.Buffer cl1 := newCL() w := NewWriterWithCompressor(&stargzBuf, cl1) w.ChunkSize = tt.chunkSize w.MinChunkSize = tt.minChunkSize if lossless { err := w.AppendTarLossLess(tr) if tt.wantFailOnLossLess { if err != nil { return // expected to fail } t.Fatalf("Append wanted to fail on lossless") } if err != nil { t.Fatalf("Append(lossless): %v", err) } } else { if err := w.AppendTar(tr); err != nil { t.Fatalf("Append: %v", err) } } if _, err := w.Close(); err != nil { t.Fatalf("Writer.Close: %v", err) } b := stargzBuf.Bytes() if lossless { // Check if the result blob reserves original tar metadata rc, err := Unpack(io.NewSectionReader(bytes.NewReader(b), 0, int64(len(b))), cl1) if err != nil { t.Errorf("failed to decompress blob: %v", err) return } defer rc.Close() resultDgstr := digest.Canonical.Digester() if _, err := io.Copy(resultDgstr.Hash(), rc); err != nil { t.Errorf("failed to read result decompressed blob: %v", err) return } if resultDgstr.Digest() != origTarDgstr.Digest() { t.Errorf("lossy compression occurred: digest=%v; want %v", resultDgstr.Digest(), origTarDgstr.Digest()) return } } diffID := w.DiffID() wantDiffID := cl1.DiffIDOf(t, b) if diffID != wantDiffID { t.Errorf("DiffID = %q; want %q", diffID, wantDiffID) } telemetry, checkCalled := newCalledTelemetry() sr := io.NewSectionReader(bytes.NewReader(b), 0, int64(len(b))) r, err := Open( sr, WithDecompressors(cl1), WithTelemetry(telemetry), ) if err != nil { t.Fatalf("stargz.Open: %v", err) } wantTOCVersion := 1 if tt.wantTOCVersion > 0 { wantTOCVersion = tt.wantTOCVersion } if r.toc.Version != wantTOCVersion { t.Fatalf("invalid TOC Version %d; wanted %d", r.toc.Version, wantTOCVersion) } footerSize := cl1.FooterSize() footerOffset := sr.Size() - footerSize footer := make([]byte, footerSize) if _, err := sr.ReadAt(footer, footerOffset); err != nil { t.Errorf("failed to read footer: %v", err) } _, tocOffset, _, err := cl1.ParseFooter(footer) if err != nil { t.Errorf("failed to parse footer: %v", err) } if err := checkCalled(tocOffset >= 0); err != nil { t.Errorf("telemetry failure: %v", err) } wantNumGz := tt.wantNumGz if lossless && tt.wantNumGzLossLess > 0 { wantNumGz = tt.wantNumGzLossLess } streamOffsets := []int64{0} prevOffset := int64(-1) streams := 0 for _, e := range r.toc.Entries { if e.Offset > prevOffset { streamOffsets = append(streamOffsets, e.Offset) prevOffset = e.Offset streams++ } } streams++ // TOC if tocOffset >= 0 { // toc is in the blob streamOffsets = append(streamOffsets, tocOffset) } streams++ // footer streamOffsets = append(streamOffsets, footerOffset) if streams != wantNumGz { t.Errorf("number of streams in TOC = %d; want %d", streams, wantNumGz) } t.Logf("testing streams: %+v", streamOffsets) cl1.TestStreams(t, b, streamOffsets) for _, want := range tt.want { want.check(t, r) } }) } } } } } } type chunkInfo struct { name string data string } func newCalledTelemetry() (telemetry *Telemetry, check func(needsGetTOC bool) error) { var getFooterLatencyCalled bool var getTocLatencyCalled bool var deserializeTocLatencyCalled bool return &Telemetry{ func(time.Time) { getFooterLatencyCalled = true }, func(time.Time) { getTocLatencyCalled = true }, func(time.Time) { deserializeTocLatencyCalled = true }, }, func(needsGetTOC bool) error { var allErr []error if !getFooterLatencyCalled { allErr = append(allErr, fmt.Errorf("metrics GetFooterLatency isn't called")) } if needsGetTOC { if !getTocLatencyCalled { allErr = append(allErr, fmt.Errorf("metrics GetTocLatency isn't called")) } } if !deserializeTocLatencyCalled { allErr = append(allErr, fmt.Errorf("metrics DeserializeTocLatency isn't called")) } return errorutil.Aggregate(allErr) } } func digestFor(content string) string { sum := sha256.Sum256([]byte(content)) return fmt.Sprintf("sha256:%x", sum) } type numTOCEntries int func (n numTOCEntries) check(t *testing.T, r *Reader) { if r.toc == nil { t.Fatal("nil TOC") } if got, want := len(r.toc.Entries), int(n); got != want { t.Errorf("got %d TOC entries; want %d", got, want) } t.Logf("got TOC entries:") for i, ent := range r.toc.Entries { entj, _ := json.Marshal(ent) t.Logf(" [%d]: %s\n", i, entj) } if t.Failed() { t.FailNow() } } func checks(s ...stargzCheck) []stargzCheck { return s } type stargzCheck interface { check(t *testing.T, r *Reader) } type stargzCheckFn func(*testing.T, *Reader) func (f stargzCheckFn) check(t *testing.T, r *Reader) { f(t, r) } func maxDepth(max int) stargzCheck { return stargzCheckFn(func(t *testing.T, r *Reader) { e, ok := r.Lookup("") if !ok { t.Fatal("root directory not found") } d, err := getMaxDepth(t, e, 0, 10*max) if err != nil { t.Errorf("failed to get max depth (wanted %d): %v", max, err) return } if d != max { t.Errorf("invalid depth %d; want %d", d, max) return } }) } func getMaxDepth(t *testing.T, e *TOCEntry, current, limit int) (max int, rErr error) { if current > limit { return -1, fmt.Errorf("walkMaxDepth: exceeds limit: current:%d > limit:%d", current, limit) } max = current e.ForeachChild(func(baseName string, ent *TOCEntry) bool { t.Logf("%q(basename:%q) is child of %q\n", ent.Name, baseName, e.Name) d, err := getMaxDepth(t, ent, current+1, limit) if err != nil { rErr = err return false } if d > max { max = d } return true }) return } func hasFileLen(file string, wantLen int) stargzCheck { return stargzCheckFn(func(t *testing.T, r *Reader) { for _, ent := range r.toc.Entries { if ent.Name == file { if ent.Type != "reg" { t.Errorf("file type of %q is %q; want \"reg\"", file, ent.Type) } else if ent.Size != int64(wantLen) { t.Errorf("file size of %q = %d; want %d", file, ent.Size, wantLen) } return } } t.Errorf("file %q not found", file) }) } func hasFileXattrs(file, name, value string) stargzCheck { return stargzCheckFn(func(t *testing.T, r *Reader) { for _, ent := range r.toc.Entries { if ent.Name == file { if ent.Type != "reg" { t.Errorf("file type of %q is %q; want \"reg\"", file, ent.Type) } if ent.Xattrs == nil { t.Errorf("file %q has no xattrs", file) return } valueFound, found := ent.Xattrs[name] if !found { t.Errorf("file %q has no xattr %q", file, name) return } if string(valueFound) != value { t.Errorf("file %q has xattr %q with value %q instead of %q", file, name, valueFound, value) } return } } t.Errorf("file %q not found", file) }) } func hasFileDigest(file string, digest string) stargzCheck { return stargzCheckFn(func(t *testing.T, r *Reader) { ent, ok := r.Lookup(file) if !ok { t.Fatalf("didn't find TOCEntry for file %q", file) } if ent.Digest != digest { t.Fatalf("Digest(%q) = %q, want %q", file, ent.Digest, digest) } }) } func hasFileContentsWithPreRead(file string, offset int, want string, extra ...chunkInfo) stargzCheck { return stargzCheckFn(func(t *testing.T, r *Reader) { extraMap := make(map[string]chunkInfo) for _, e := range extra { extraMap[e.name] = e } var extraNames []string for n := range extraMap { extraNames = append(extraNames, n) } f, err := r.OpenFileWithPreReader(file, func(e *TOCEntry, cr io.Reader) error { t.Logf("On %q: got preread of %q", file, e.Name) ex, ok := extraMap[e.Name] if !ok { t.Fatalf("fail on %q: unexpected entry %q: %+v, %+v", file, e.Name, e, extraNames) } got, err := io.ReadAll(cr) if err != nil { t.Fatalf("fail on %q: failed to read %q: %v", file, e.Name, err) } if ex.data != string(got) { t.Fatalf("fail on %q: unexpected contents of %q: len=%d; want=%d", file, e.Name, len(got), len(ex.data)) } delete(extraMap, e.Name) return nil }) if err != nil { t.Fatal(err) } got := make([]byte, len(want)) n, err := f.ReadAt(got, int64(offset)) if err != nil { t.Fatalf("ReadAt(len %d, offset %d, size %d) = %v, %v", len(got), offset, f.Size(), n, err) } if string(got) != want { t.Fatalf("ReadAt(len %d, offset %d) = %q, want %q", len(got), offset, viewContent(got), viewContent([]byte(want))) } if len(extraMap) != 0 { var exNames []string for _, ex := range extraMap { exNames = append(exNames, ex.name) } t.Fatalf("fail on %q: some entries aren't read: %+v", file, exNames) } }) } func hasFileContentsRange(file string, offset int, want string) stargzCheck { return stargzCheckFn(func(t *testing.T, r *Reader) { f, err := r.OpenFile(file) if err != nil { t.Fatal(err) } got := make([]byte, len(want)) n, err := f.ReadAt(got, int64(offset)) if err != nil { t.Fatalf("ReadAt(len %d, offset %d) = %v, %v", len(got), offset, n, err) } if string(got) != want { t.Fatalf("ReadAt(len %d, offset %d) = %q, want %q", len(got), offset, viewContent(got), viewContent([]byte(want))) } }) } func hasChunkEntries(file string, wantChunks int) stargzCheck { return stargzCheckFn(func(t *testing.T, r *Reader) { ent, ok := r.Lookup(file) if !ok { t.Fatalf("no file for %q", file) } if ent.Type != "reg" { t.Fatalf("file %q has unexpected type %q; want reg", file, ent.Type) } chunks := r.getChunks(ent) if len(chunks) != wantChunks { t.Errorf("len(r.getChunks(%q)) = %d; want %d", file, len(chunks), wantChunks) return } f := chunks[0] var gotChunks []*TOCEntry var last *TOCEntry for off := int64(0); off < f.Size; off++ { e, ok := r.ChunkEntryForOffset(file, off) if !ok { t.Errorf("no ChunkEntryForOffset at %d", off) return } if last != e { gotChunks = append(gotChunks, e) last = e } } if !reflect.DeepEqual(chunks, gotChunks) { t.Errorf("gotChunks=%d, want=%d; contents mismatch", len(gotChunks), wantChunks) } // And verify the NextOffset for i := 0; i < len(gotChunks)-1; i++ { ci := gotChunks[i] cnext := gotChunks[i+1] if ci.NextOffset() != cnext.Offset { t.Errorf("chunk %d NextOffset %d != next chunk's Offset of %d", i, ci.NextOffset(), cnext.Offset) } } }) } func entryHasChildren(dir string, want ...string) stargzCheck { return stargzCheckFn(func(t *testing.T, r *Reader) { want := append([]string(nil), want...) var got []string ent, ok := r.Lookup(dir) if !ok { t.Fatalf("didn't find TOCEntry for dir node %q", dir) } for baseName := range ent.children { got = append(got, baseName) } sort.Strings(got) sort.Strings(want) if !reflect.DeepEqual(got, want) { t.Errorf("children of %q = %q; want %q", dir, got, want) } }) } func hasDir(file string) stargzCheck { return stargzCheckFn(func(t *testing.T, r *Reader) { for _, ent := range r.toc.Entries { if ent.Name == cleanEntryName(file) { if ent.Type != "dir" { t.Errorf("file type of %q is %q; want \"dir\"", file, ent.Type) } return } } t.Errorf("directory %q not found", file) }) } func hasDirLinkCount(file string, count int) stargzCheck { return stargzCheckFn(func(t *testing.T, r *Reader) { for _, ent := range r.toc.Entries { if ent.Name == cleanEntryName(file) { if ent.Type != "dir" { t.Errorf("file type of %q is %q; want \"dir\"", file, ent.Type) return } if ent.NumLink != count { t.Errorf("link count of %q = %d; want %d", file, ent.NumLink, count) } return } } t.Errorf("directory %q not found", file) }) } func hasMode(file string, mode os.FileMode) stargzCheck { return stargzCheckFn(func(t *testing.T, r *Reader) { for _, ent := range r.toc.Entries { if ent.Name == cleanEntryName(file) { if ent.Stat().Mode() != mode { t.Errorf("invalid mode: got %v; want %v", ent.Stat().Mode(), mode) return } return } } t.Errorf("file %q not found", file) }) } func hasSymlink(file, target string) stargzCheck { return stargzCheckFn(func(t *testing.T, r *Reader) { for _, ent := range r.toc.Entries { if ent.Name == file { if ent.Type != "symlink" { t.Errorf("file type of %q is %q; want \"symlink\"", file, ent.Type) } else if ent.LinkName != target { t.Errorf("link target of symlink %q is %q; want %q", file, ent.LinkName, target) } return } } t.Errorf("symlink %q not found", file) }) } func lookupMatch(name string, want *TOCEntry) stargzCheck { return stargzCheckFn(func(t *testing.T, r *Reader) { e, ok := r.Lookup(name) if !ok { t.Fatalf("failed to Lookup entry %q", name) } if !reflect.DeepEqual(e, want) { t.Errorf("entry %q mismatch.\n got: %+v\nwant: %+v\n", name, e, want) } }) } func hasEntryOwner(entry string, owner owner) stargzCheck { return stargzCheckFn(func(t *testing.T, r *Reader) { ent, ok := r.Lookup(strings.TrimSuffix(entry, "/")) if !ok { t.Errorf("entry %q not found", entry) return } if ent.UID != owner.uid || ent.GID != owner.gid { t.Errorf("entry %q has invalid owner (uid:%d, gid:%d) instead of (uid:%d, gid:%d)", entry, ent.UID, ent.GID, owner.uid, owner.gid) return } }) } func mustSameEntry(files ...string) stargzCheck { return stargzCheckFn(func(t *testing.T, r *Reader) { var first *TOCEntry for _, f := range files { if first == nil { var ok bool first, ok = r.Lookup(f) if !ok { t.Errorf("unknown first file on Lookup: %q", f) return } } // Test Lookup e, ok := r.Lookup(f) if !ok { t.Errorf("unknown file on Lookup: %q", f) return } if e != first { t.Errorf("Lookup: %+v(%p) != %+v(%p)", e, e, first, first) return } // Test LookupChild pe, ok := r.Lookup(filepath.Dir(filepath.Clean(f))) if !ok { t.Errorf("failed to get parent of %q", f) return } e, ok = pe.LookupChild(filepath.Base(filepath.Clean(f))) if !ok { t.Errorf("failed to get %q as the child of %+v", f, pe) return } if e != first { t.Errorf("LookupChild: %+v(%p) != %+v(%p)", e, e, first, first) return } // Test ForeachChild pe.ForeachChild(func(baseName string, e *TOCEntry) bool { if baseName == filepath.Base(filepath.Clean(f)) { if e != first { t.Errorf("ForeachChild: %+v(%p) != %+v(%p)", e, e, first, first) return false } } return true }) } }) } func viewContent(c []byte) string { if len(c) < 100 { return string(c) } return string(c[:50]) + "...(omit)..." + string(c[50:100]) } func tarOf(s ...tarEntry) []tarEntry { return s } type tarEntry interface { appendTar(tw *tar.Writer, prefix string, format tar.Format) error } type tarEntryFunc func(*tar.Writer, string, tar.Format) error func (f tarEntryFunc) appendTar(tw *tar.Writer, prefix string, format tar.Format) error { return f(tw, prefix, format) } func buildTar(t *testing.T, ents []tarEntry, prefix string, opts ...interface{}) *io.SectionReader { format := tar.FormatUnknown for _, opt := range opts { switch v := opt.(type) { case tar.Format: format = v default: panic(fmt.Errorf("unsupported opt for buildTar: %v", opt)) } } buf := new(bytes.Buffer) tw := tar.NewWriter(buf) for _, ent := range ents { if err := ent.appendTar(tw, prefix, format); err != nil { t.Fatalf("building input tar: %v", err) } } if err := tw.Close(); err != nil { t.Errorf("closing write of input tar: %v", err) } data := append(buf.Bytes(), make([]byte, 100)...) // append empty bytes at the tail to see lossless works return io.NewSectionReader(bytes.NewReader(data), 0, int64(len(data))) } func dir(name string, opts ...interface{}) tarEntry { return tarEntryFunc(func(tw *tar.Writer, prefix string, format tar.Format) error { var o owner mode := os.FileMode(0755) for _, opt := range opts { switch v := opt.(type) { case owner: o = v case os.FileMode: mode = v default: return errors.New("unsupported opt") } } if !strings.HasSuffix(name, "/") { panic(fmt.Sprintf("missing trailing slash in dir %q ", name)) } tm, err := fileModeToTarMode(mode) if err != nil { return err } return tw.WriteHeader(&tar.Header{ Typeflag: tar.TypeDir, Name: prefix + name, Mode: tm, Uid: o.uid, Gid: o.gid, Format: format, }) }) } // xAttr are extended attributes to set on test files created with the file func. type xAttr map[string]string // owner is owner ot set on test files and directories with the file and dir functions. type owner struct { uid int gid int } func file(name, contents string, opts ...interface{}) tarEntry { return tarEntryFunc(func(tw *tar.Writer, prefix string, format tar.Format) error { var xattrs xAttr var o owner mode := os.FileMode(0644) for _, opt := range opts { switch v := opt.(type) { case xAttr: xattrs = v case owner: o = v case os.FileMode: mode = v default: return errors.New("unsupported opt") } } if strings.HasSuffix(name, "/") { return fmt.Errorf("bogus trailing slash in file %q", name) } tm, err := fileModeToTarMode(mode) if err != nil { return err } if len(xattrs) > 0 { format = tar.FormatPAX // only PAX supports xattrs } if err := tw.WriteHeader(&tar.Header{ Typeflag: tar.TypeReg, Name: prefix + name, Mode: tm, Xattrs: xattrs, Size: int64(len(contents)), Uid: o.uid, Gid: o.gid, Format: format, }); err != nil { return err } _, err = io.WriteString(tw, contents) return err }) } func symlink(name, target string) tarEntry { return tarEntryFunc(func(tw *tar.Writer, prefix string, format tar.Format) error { return tw.WriteHeader(&tar.Header{ Typeflag: tar.TypeSymlink, Name: prefix + name, Linkname: target, Mode: 0644, Format: format, }) }) } func link(name string, linkname string) tarEntry { now := time.Now() return tarEntryFunc(func(w *tar.Writer, prefix string, format tar.Format) error { return w.WriteHeader(&tar.Header{ Typeflag: tar.TypeLink, Name: prefix + name, Linkname: linkname, ModTime: now, Format: format, }) }) } func chardev(name string, major, minor int64) tarEntry { now := time.Now() return tarEntryFunc(func(w *tar.Writer, prefix string, format tar.Format) error { return w.WriteHeader(&tar.Header{ Typeflag: tar.TypeChar, Name: prefix + name, Devmajor: major, Devminor: minor, ModTime: now, Format: format, }) }) } func blockdev(name string, major, minor int64) tarEntry { now := time.Now() return tarEntryFunc(func(w *tar.Writer, prefix string, format tar.Format) error { return w.WriteHeader(&tar.Header{ Typeflag: tar.TypeBlock, Name: prefix + name, Devmajor: major, Devminor: minor, ModTime: now, Format: format, }) }) } func fifo(name string) tarEntry { now := time.Now() return tarEntryFunc(func(w *tar.Writer, prefix string, format tar.Format) error { return w.WriteHeader(&tar.Header{ Typeflag: tar.TypeFifo, Name: prefix + name, ModTime: now, Format: format, }) }) } func prefetchLandmark() tarEntry { return tarEntryFunc(func(w *tar.Writer, prefix string, format tar.Format) error { if err := w.WriteHeader(&tar.Header{ Name: PrefetchLandmark, Typeflag: tar.TypeReg, Size: int64(len([]byte{landmarkContents})), Format: format, }); err != nil { return err } contents := []byte{landmarkContents} if _, err := io.CopyN(w, bytes.NewReader(contents), int64(len(contents))); err != nil { return err } return nil }) } func noPrefetchLandmark() tarEntry { return tarEntryFunc(func(w *tar.Writer, prefix string, format tar.Format) error { if err := w.WriteHeader(&tar.Header{ Name: NoPrefetchLandmark, Typeflag: tar.TypeReg, Size: int64(len([]byte{landmarkContents})), Format: format, }); err != nil { return err } contents := []byte{landmarkContents} if _, err := io.CopyN(w, bytes.NewReader(contents), int64(len(contents))); err != nil { return err } return nil }) } func regDigest(t *testing.T, name string, contentStr string, digestMap map[string]digest.Digest) tarEntry { if digestMap == nil { t.Fatalf("digest map mustn't be nil") } content := []byte(contentStr) var n int64 for n < int64(len(content)) { size := int64(chunkSize) remain := int64(len(content)) - n if remain < size { size = remain } dgstr := digest.Canonical.Digester() if _, err := io.CopyN(dgstr.Hash(), bytes.NewReader(content[n:n+size]), size); err != nil { t.Fatalf("failed to calculate digest of %q (name=%q,offset=%d,size=%d)", string(content[n:n+size]), name, n, size) } digestMap[chunkID(name, n, size)] = dgstr.Digest() n += size } return tarEntryFunc(func(w *tar.Writer, prefix string, format tar.Format) error { if err := w.WriteHeader(&tar.Header{ Typeflag: tar.TypeReg, Name: prefix + name, Size: int64(len(content)), Format: format, }); err != nil { return err } if _, err := io.CopyN(w, bytes.NewReader(content), int64(len(content))); err != nil { return err } return nil }) } var runes = []rune("1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") func randomContents(n int) string { b := make([]rune, n) for i := range b { b[i] = runes[rand.Intn(len(runes))] } return string(b) } func fileModeToTarMode(mode os.FileMode) (int64, error) { h, err := tar.FileInfoHeader(fileInfoOnlyMode(mode), "") if err != nil { return 0, err } return h.Mode, nil } // fileInfoOnlyMode is os.FileMode that populates only file mode. type fileInfoOnlyMode os.FileMode func (f fileInfoOnlyMode) Name() string { return "" } func (f fileInfoOnlyMode) Size() int64 { return 0 } func (f fileInfoOnlyMode) Mode() os.FileMode { return os.FileMode(f) } func (f fileInfoOnlyMode) ModTime() time.Time { return time.Now() } func (f fileInfoOnlyMode) IsDir() bool { return os.FileMode(f).IsDir() } func (f fileInfoOnlyMode) Sys() interface{} { return nil } func CheckGzipHasStreams(t *testing.T, b []byte, streams []int64) { if len(streams) == 0 { return // nop } wants := map[int64]struct{}{} for _, s := range streams { wants[s] = struct{}{} } len0 := len(b) br := bytes.NewReader(b) zr := new(gzip.Reader) t.Logf("got gzip streams:") numStreams := 0 for { zoff := len0 - br.Len() if err := zr.Reset(br); err != nil { if err == io.EOF { return } t.Fatalf("countStreams(gzip), Reset: %v", err) } zr.Multistream(false) n, err := io.Copy(io.Discard, zr) if err != nil { t.Fatalf("countStreams(gzip), Copy: %v", err) } var extra string if len(zr.Header.Extra) > 0 { extra = fmt.Sprintf("; extra=%q", zr.Header.Extra) } t.Logf(" [%d] at %d in stargz, uncompressed length %d%s", numStreams, zoff, n, extra) delete(wants, int64(zoff)) numStreams++ } } func GzipDiffIDOf(t *testing.T, b []byte) string { h := sha256.New() zr, err := gzip.NewReader(bytes.NewReader(b)) if err != nil { t.Fatalf("diffIDOf(gzip): %v", err) } defer zr.Close() if _, err := io.Copy(h, zr); err != nil { t.Fatalf("diffIDOf(gzip).Copy: %v", err) } return fmt.Sprintf("sha256:%x", h.Sum(nil)) } stargz-snapshotter-0.14.3/estargz/types.go000066400000000000000000000307351440204344700206450ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /* Copyright 2019 The Go Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. */ package estargz import ( "archive/tar" "hash" "io" "os" "path" "time" digest "github.com/opencontainers/go-digest" ) const ( // TOCTarName is the name of the JSON file in the tar archive in the // table of contents gzip stream. TOCTarName = "stargz.index.json" // FooterSize is the number of bytes in the footer // // The footer is an empty gzip stream with no compression and an Extra // header of the form "%016xSTARGZ", where the 64 bit hex-encoded // number is the offset to the gzip stream of JSON TOC. // // 51 comes from: // // 10 bytes gzip header // 2 bytes XLEN (length of Extra field) = 26 (4 bytes header + 16 hex digits + len("STARGZ")) // 2 bytes Extra: SI1 = 'S', SI2 = 'G' // 2 bytes Extra: LEN = 22 (16 hex digits + len("STARGZ")) // 22 bytes Extra: subfield = fmt.Sprintf("%016xSTARGZ", offsetOfTOC) // 5 bytes flate header // 8 bytes gzip footer // (End of the eStargz blob) // // NOTE: For Extra fields, subfield IDs SI1='S' SI2='G' is used for eStargz. FooterSize = 51 // legacyFooterSize is the number of bytes in the legacy stargz footer. // // 47 comes from: // // 10 byte gzip header + // 2 byte (LE16) length of extra, encoding 22 (16 hex digits + len("STARGZ")) == "\x16\x00" + // 22 bytes of extra (fmt.Sprintf("%016xSTARGZ", tocGzipOffset)) // 5 byte flate header // 8 byte gzip footer (two little endian uint32s: digest, size) legacyFooterSize = 47 // TOCJSONDigestAnnotation is an annotation for an image layer. This stores the // digest of the TOC JSON. // This annotation is valid only when it is specified in `.[]layers.annotations` // of an image manifest. TOCJSONDigestAnnotation = "containerd.io/snapshot/stargz/toc.digest" // StoreUncompressedSizeAnnotation is an additional annotation key for eStargz to enable lazy // pulling on containers/storage. Stargz Store is required to expose the layer's uncompressed size // to the runtime but current OCI image doesn't ship this information by default. So we store this // to the special annotation. StoreUncompressedSizeAnnotation = "io.containers.estargz.uncompressed-size" // PrefetchLandmark is a file entry which indicates the end position of // prefetch in the stargz file. PrefetchLandmark = ".prefetch.landmark" // NoPrefetchLandmark is a file entry which indicates that no prefetch should // occur in the stargz file. NoPrefetchLandmark = ".no.prefetch.landmark" landmarkContents = 0xf ) // JTOC is the JSON-serialized table of contents index of the files in the stargz file. type JTOC struct { Version int `json:"version"` Entries []*TOCEntry `json:"entries"` } // TOCEntry is an entry in the stargz file's TOC (Table of Contents). type TOCEntry struct { // Name is the tar entry's name. It is the complete path // stored in the tar file, not just the base name. Name string `json:"name"` // Type is one of "dir", "reg", "symlink", "hardlink", "char", // "block", "fifo", or "chunk". // The "chunk" type is used for regular file data chunks past the first // TOCEntry; the 2nd chunk and on have only Type ("chunk"), Offset, // ChunkOffset, and ChunkSize populated. Type string `json:"type"` // Size, for regular files, is the logical size of the file. Size int64 `json:"size,omitempty"` // ModTime3339 is the modification time of the tar entry. Empty // means zero or unknown. Otherwise it's in UTC RFC3339 // format. Use the ModTime method to access the time.Time value. ModTime3339 string `json:"modtime,omitempty"` modTime time.Time // LinkName, for symlinks and hardlinks, is the link target. LinkName string `json:"linkName,omitempty"` // Mode is the permission and mode bits. Mode int64 `json:"mode,omitempty"` // UID is the user ID of the owner. UID int `json:"uid,omitempty"` // GID is the group ID of the owner. GID int `json:"gid,omitempty"` // Uname is the username of the owner. // // In the serialized JSON, this field may only be present for // the first entry with the same UID. Uname string `json:"userName,omitempty"` // Gname is the group name of the owner. // // In the serialized JSON, this field may only be present for // the first entry with the same GID. Gname string `json:"groupName,omitempty"` // Offset, for regular files, provides the offset in the // stargz file to the file's data bytes. See ChunkOffset and // ChunkSize. Offset int64 `json:"offset,omitempty"` // InnerOffset is an optional field indicates uncompressed offset // of this "reg" or "chunk" payload in a stream starts from Offset. // This field enables to put multiple "reg" or "chunk" payloads // in one chunk with having the same Offset but different InnerOffset. InnerOffset int64 `json:"innerOffset,omitempty"` nextOffset int64 // the Offset of the next entry with a non-zero Offset // DevMajor is the major device number for "char" and "block" types. DevMajor int `json:"devMajor,omitempty"` // DevMinor is the major device number for "char" and "block" types. DevMinor int `json:"devMinor,omitempty"` // NumLink is the number of entry names pointing to this entry. // Zero means one name references this entry. // This field is calculated during runtime and not recorded in TOC JSON. NumLink int `json:"-"` // Xattrs are the extended attribute for the entry. Xattrs map[string][]byte `json:"xattrs,omitempty"` // Digest stores the OCI checksum for regular files payload. // It has the form "sha256:abcdef01234....". Digest string `json:"digest,omitempty"` // ChunkOffset is non-zero if this is a chunk of a large, // regular file. If so, the Offset is where the gzip header of // ChunkSize bytes at ChunkOffset in Name begin. // // In serialized form, a "chunkSize" JSON field of zero means // that the chunk goes to the end of the file. After reading // from the stargz TOC, though, the ChunkSize is initialized // to a non-zero file for when Type is either "reg" or // "chunk". ChunkOffset int64 `json:"chunkOffset,omitempty"` ChunkSize int64 `json:"chunkSize,omitempty"` // ChunkDigest stores an OCI digest of the chunk. This must be formed // as "sha256:0123abcd...". ChunkDigest string `json:"chunkDigest,omitempty"` children map[string]*TOCEntry // chunkTopIndex is index of the entry where Offset starts in the blob. chunkTopIndex int } // ModTime returns the entry's modification time. func (e *TOCEntry) ModTime() time.Time { return e.modTime } // NextOffset returns the position (relative to the start of the // stargz file) of the next gzip boundary after e.Offset. func (e *TOCEntry) NextOffset() int64 { return e.nextOffset } func (e *TOCEntry) addChild(baseName string, child *TOCEntry) { if e.children == nil { e.children = make(map[string]*TOCEntry) } if child.Type == "dir" { e.NumLink++ // Entry ".." in the subdirectory links to this directory } e.children[baseName] = child } // isDataType reports whether TOCEntry is a regular file or chunk (something that // contains regular file data). func (e *TOCEntry) isDataType() bool { return e.Type == "reg" || e.Type == "chunk" } // Stat returns a FileInfo value representing e. func (e *TOCEntry) Stat() os.FileInfo { return fileInfo{e} } // ForeachChild calls f for each child item. If f returns false, iteration ends. // If e is not a directory, f is not called. func (e *TOCEntry) ForeachChild(f func(baseName string, ent *TOCEntry) bool) { for name, ent := range e.children { if !f(name, ent) { return } } } // LookupChild returns the directory e's child by its base name. func (e *TOCEntry) LookupChild(baseName string) (child *TOCEntry, ok bool) { child, ok = e.children[baseName] return } // fileInfo implements os.FileInfo using the wrapped *TOCEntry. type fileInfo struct{ e *TOCEntry } var _ os.FileInfo = fileInfo{} func (fi fileInfo) Name() string { return path.Base(fi.e.Name) } func (fi fileInfo) IsDir() bool { return fi.e.Type == "dir" } func (fi fileInfo) Size() int64 { return fi.e.Size } func (fi fileInfo) ModTime() time.Time { return fi.e.ModTime() } func (fi fileInfo) Sys() interface{} { return fi.e } func (fi fileInfo) Mode() (m os.FileMode) { // TOCEntry.Mode is tar.Header.Mode so we can understand the these bits using `tar` pkg. m = (&tar.Header{Mode: fi.e.Mode}).FileInfo().Mode() & (os.ModePerm | os.ModeSetuid | os.ModeSetgid | os.ModeSticky) switch fi.e.Type { case "dir": m |= os.ModeDir case "symlink": m |= os.ModeSymlink case "char": m |= os.ModeDevice | os.ModeCharDevice case "block": m |= os.ModeDevice case "fifo": m |= os.ModeNamedPipe } return m } // TOCEntryVerifier holds verifiers that are usable for verifying chunks contained // in a eStargz blob. type TOCEntryVerifier interface { // Verifier provides a content verifier that can be used for verifying the // contents of the specified TOCEntry. Verifier(ce *TOCEntry) (digest.Verifier, error) } // Compression provides the compression helper to be used creating and parsing eStargz. // This package provides gzip-based Compression by default, but any compression // algorithm (e.g. zstd) can be used as long as it implements Compression. type Compression interface { Compressor Decompressor } // Compressor represents the helper mothods to be used for creating eStargz. type Compressor interface { // Writer returns WriteCloser to be used for writing a chunk to eStargz. // Everytime a chunk is written, the WriteCloser is closed and Writer is // called again for writing the next chunk. // // The returned writer should implement "Flush() error" function that flushes // any pending compressed data to the underlying writer. Writer(w io.Writer) (WriteFlushCloser, error) // WriteTOCAndFooter is called to write JTOC to the passed Writer. // diffHash calculates the DiffID (uncompressed sha256 hash) of the blob // WriteTOCAndFooter can optionally write anything that affects DiffID calculation // (e.g. uncompressed TOC JSON). // // This function returns tocDgst that represents the digest of TOC that will be used // to verify this blob when it's parsed. WriteTOCAndFooter(w io.Writer, off int64, toc *JTOC, diffHash hash.Hash) (tocDgst digest.Digest, err error) } // Decompressor represents the helper mothods to be used for parsing eStargz. type Decompressor interface { // Reader returns ReadCloser to be used for decompressing file payload. Reader(r io.Reader) (io.ReadCloser, error) // FooterSize returns the size of the footer of this blob. FooterSize() int64 // ParseFooter parses the footer and returns the offset and (compressed) size of TOC. // payloadBlobSize is the (compressed) size of the blob payload (i.e. the size between // the top until the TOC JSON). // // If tocOffset < 0, we assume that TOC isn't contained in the blob and pass nil reader // to ParseTOC. We expect that ParseTOC acquire TOC from the external location and return it. // // tocSize is optional. If tocSize <= 0, it's by default the size of the range from tocOffset until the beginning of the // footer (blob size - tocOff - FooterSize). // If blobPayloadSize < 0, blobPayloadSize become the blob size. ParseFooter(p []byte) (blobPayloadSize, tocOffset, tocSize int64, err error) // ParseTOC parses TOC from the passed reader. The reader provides the partial contents // of the underlying blob that has the range specified by ParseFooter method. // // This function returns tocDgst that represents the digest of TOC that will be used // to verify this blob. This must match to the value returned from // Compressor.WriteTOCAndFooter that is used when creating this blob. // // If tocOffset returned by ParseFooter is < 0, we assume that TOC isn't contained in the blob. // Pass nil reader to ParseTOC then we expect that ParseTOC acquire TOC from the external location // and return it. ParseTOC(r io.Reader) (toc *JTOC, tocDgst digest.Digest, err error) } type WriteFlushCloser interface { io.WriteCloser Flush() error } stargz-snapshotter-0.14.3/estargz/zstdchunked/000077500000000000000000000000001440204344700214705ustar00rootroot00000000000000stargz-snapshotter-0.14.3/estargz/zstdchunked/zstdchunked.go000066400000000000000000000130721440204344700243500ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package zstdchunked import ( "bufio" "bytes" "encoding/binary" "encoding/json" "fmt" "hash" "io" "sync" "github.com/containerd/stargz-snapshotter/estargz" "github.com/klauspost/compress/zstd" digest "github.com/opencontainers/go-digest" ) const ( // ManifestChecksumAnnotation is an annotation that contains the compressed TOC Digset ManifestChecksumAnnotation = "io.containers.zstd-chunked.manifest-checksum" // ManifestPositionAnnotation is an annotation that contains the offset to the TOC. ManifestPositionAnnotation = "io.containers.zstd-chunked.manifest-position" // FooterSize is the size of the footer FooterSize = 40 manifestTypeCRFS = 1 ) var ( skippableFrameMagic = []byte{0x50, 0x2a, 0x4d, 0x18} zstdFrameMagic = []byte{0x28, 0xb5, 0x2f, 0xfd} zstdChunkedFrameMagic = []byte{0x47, 0x6e, 0x55, 0x6c, 0x49, 0x6e, 0x55, 0x78} ) type Decompressor struct{} func (zz *Decompressor) Reader(r io.Reader) (io.ReadCloser, error) { decoder, err := zstd.NewReader(r) if err != nil { return nil, err } return &zstdReadCloser{decoder}, nil } func (zz *Decompressor) ParseTOC(r io.Reader) (toc *estargz.JTOC, tocDgst digest.Digest, err error) { zr, err := zstd.NewReader(r) if err != nil { return nil, "", err } defer zr.Close() dgstr := digest.Canonical.Digester() toc = new(estargz.JTOC) if err := json.NewDecoder(io.TeeReader(zr, dgstr.Hash())).Decode(&toc); err != nil { return nil, "", fmt.Errorf("error decoding TOC JSON: %w", err) } return toc, dgstr.Digest(), nil } func (zz *Decompressor) ParseFooter(p []byte) (blobPayloadSize, tocOffset, tocSize int64, err error) { offset := binary.LittleEndian.Uint64(p[0:8]) compressedLength := binary.LittleEndian.Uint64(p[8:16]) if !bytes.Equal(zstdChunkedFrameMagic, p[32:40]) { return 0, 0, 0, fmt.Errorf("invalid magic number") } // 8 is the size of the zstd skippable frame header + the frame size (see WriteTOCAndFooter) return int64(offset - 8), int64(offset), int64(compressedLength), nil } func (zz *Decompressor) FooterSize() int64 { return FooterSize } func (zz *Decompressor) DecompressTOC(r io.Reader) (tocJSON io.ReadCloser, err error) { decoder, err := zstd.NewReader(r) if err != nil { return nil, err } br := bufio.NewReader(decoder) if _, err := br.Peek(1); err != nil { return nil, err } return &reader{br, decoder.Close}, nil } type reader struct { io.Reader closeFunc func() } func (r *reader) Close() error { r.closeFunc(); return nil } type zstdReadCloser struct{ *zstd.Decoder } func (z *zstdReadCloser) Close() error { z.Decoder.Close() return nil } type Compressor struct { CompressionLevel zstd.EncoderLevel Metadata map[string]string pool sync.Pool } func (zc *Compressor) Writer(w io.Writer) (estargz.WriteFlushCloser, error) { if wc := zc.pool.Get(); wc != nil { ec := wc.(*zstd.Encoder) ec.Reset(w) return &poolEncoder{ec, zc}, nil } ec, err := zstd.NewWriter(w, zstd.WithEncoderLevel(zc.CompressionLevel), zstd.WithLowerEncoderMem(true)) if err != nil { return nil, err } return &poolEncoder{ec, zc}, nil } type poolEncoder struct { *zstd.Encoder zc *Compressor } func (w *poolEncoder) Close() error { if err := w.Encoder.Close(); err != nil { return err } w.zc.pool.Put(w.Encoder) return nil } func (zc *Compressor) WriteTOCAndFooter(w io.Writer, off int64, toc *estargz.JTOC, diffHash hash.Hash) (digest.Digest, error) { tocJSON, err := json.MarshalIndent(toc, "", "\t") if err != nil { return "", err } buf := new(bytes.Buffer) encoder, err := zstd.NewWriter(buf, zstd.WithEncoderLevel(zc.CompressionLevel)) if err != nil { return "", err } if _, err := encoder.Write(tocJSON); err != nil { return "", err } if err := encoder.Close(); err != nil { return "", err } compressedTOC := buf.Bytes() _, err = io.Copy(w, bytes.NewReader(appendSkippableFrameMagic(compressedTOC))) // 8 is the size of the zstd skippable frame header + the frame size tocOff := uint64(off) + 8 if _, err := w.Write(appendSkippableFrameMagic( zstdFooterBytes(tocOff, uint64(len(tocJSON)), uint64(len(compressedTOC)))), ); err != nil { return "", err } if zc.Metadata != nil { zc.Metadata[ManifestChecksumAnnotation] = digest.FromBytes(compressedTOC).String() zc.Metadata[ManifestPositionAnnotation] = fmt.Sprintf("%d:%d:%d:%d", tocOff, len(compressedTOC), len(tocJSON), manifestTypeCRFS) } return digest.FromBytes(tocJSON), err } // zstdFooterBytes returns the 40 bytes footer. func zstdFooterBytes(tocOff, tocRawSize, tocCompressedSize uint64) []byte { footer := make([]byte, FooterSize) binary.LittleEndian.PutUint64(footer, tocOff) binary.LittleEndian.PutUint64(footer[8:], tocCompressedSize) binary.LittleEndian.PutUint64(footer[16:], tocRawSize) binary.LittleEndian.PutUint64(footer[24:], manifestTypeCRFS) copy(footer[32:40], zstdChunkedFrameMagic) return footer } func appendSkippableFrameMagic(b []byte) []byte { size := make([]byte, 4) binary.LittleEndian.PutUint32(size, uint32(len(b))) return append(append(skippableFrameMagic, size...), b...) } stargz-snapshotter-0.14.3/estargz/zstdchunked/zstdchunked_test.go000066400000000000000000000122261440204344700254070ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package zstdchunked import ( "bytes" "crypto/sha256" "fmt" "io" "sort" "testing" "github.com/containerd/stargz-snapshotter/estargz" "github.com/klauspost/compress/zstd" ) // TestZstdChunked tests zstd:chunked func TestZstdChunked(t *testing.T) { estargz.CompressionTestSuite(t, zstdControllerWithLevel(zstd.SpeedFastest), zstdControllerWithLevel(zstd.SpeedDefault), zstdControllerWithLevel(zstd.SpeedBetterCompression), // zstdControllerWithLevel(zstd.SpeedBestCompression), // consumes too much memory to pass on CI ) } func zstdControllerWithLevel(compressionLevel zstd.EncoderLevel) estargz.TestingControllerFactory { return func() estargz.TestingController { return &zstdController{&Compressor{CompressionLevel: compressionLevel}, &Decompressor{}} } } type zstdController struct { *Compressor *Decompressor } func (zc *zstdController) String() string { return fmt.Sprintf("zstd_compression_level=%v", zc.Compressor.CompressionLevel) } // TestStream tests the passed zstdchunked blob contains the specified list of streams. // The last entry of streams must be the offset of footer (len(b) - footerSize). func (zc *zstdController) TestStreams(t *testing.T, b []byte, streams []int64) { t.Logf("got zstd streams (compressed size: %d):", len(b)) if len(streams) == 0 { return // nop } // We expect the last offset is footer offset. // 8 is the size of the zstd skippable frame header + the frame size (see WriteTOCAndFooter) sort.Slice(streams, func(i, j int) bool { return streams[i] < streams[j] }) streams[len(streams)-1] = streams[len(streams)-1] - 8 wants := map[int64]struct{}{} for _, s := range streams { wants[s] = struct{}{} } magicLen := 4 // length of magic bytes and skippable frame magic bytes zoff := 0 numStreams := 0 for { if len(b) <= zoff { break } else if len(b)-zoff <= magicLen { t.Fatalf("invalid frame size %d is too small", len(b)-zoff) } delete(wants, int64(zoff)) // offset found remainingFrames := b[zoff:] // Check if zoff points to the beginning of a frame if !bytes.Equal(remainingFrames[:magicLen], zstdFrameMagic) { if !bytes.Equal(remainingFrames[:magicLen], skippableFrameMagic) { t.Fatalf("frame must start from magic bytes; but %x", remainingFrames[:magicLen]) } } searchBase := magicLen nextMagicIdx := nextIndex(remainingFrames[searchBase:], zstdFrameMagic) nextSkippableIdx := nextIndex(remainingFrames[searchBase:], skippableFrameMagic) nextFrame := len(remainingFrames) for _, i := range []int{nextMagicIdx, nextSkippableIdx} { if 0 < i && searchBase+i < nextFrame { nextFrame = searchBase + i } } t.Logf(" [%d] at %d in stargz (nextFrame: %d/%d): %v, %v", numStreams, zoff, zoff+nextFrame, len(b), nextMagicIdx, nextSkippableIdx) zoff += nextFrame numStreams++ } if len(wants) != 0 { t.Fatalf("some stream offsets not found in the blob: %v", wants) } } func nextIndex(s1, sub []byte) int { for i := 0; i < len(s1); i++ { if len(s1)-i < len(sub) { return -1 } else if bytes.Equal(s1[i:i+len(sub)], sub) { return i } } return -1 } func (zc *zstdController) DiffIDOf(t *testing.T, b []byte) string { h := sha256.New() zr, err := zstd.NewReader(bytes.NewReader(b)) if err != nil { t.Fatalf("diffIDOf(zstd): %v", err) } defer zr.Close() if _, err := io.Copy(h, zr); err != nil { t.Fatalf("diffIDOf(zstd).Copy: %v", err) } return fmt.Sprintf("sha256:%x", h.Sum(nil)) } // Tests footer encoding, size, and parsing of zstd:chunked. func TestZstdChunkedFooter(t *testing.T) { max := int64(200000) for off := int64(0); off <= max; off += 1023 { size := max - off checkZstdChunkedFooter(t, off, size, size/2) } } func checkZstdChunkedFooter(t *testing.T, off, size, cSize int64) { footer := zstdFooterBytes(uint64(off), uint64(size), uint64(cSize)) if len(footer) != FooterSize { t.Fatalf("for offset %v, footer length was %d, not expected %d. got bytes: %q", off, len(footer), FooterSize, footer) } gotBlobPayloadSize, gotOff, gotSize, err := (&Decompressor{}).ParseFooter(footer) if err != nil { t.Fatalf("failed to parse footer for offset %d, footer: %x: err: %v", off, footer, err) } if gotBlobPayloadSize != off-8 { // 8 is the size of the zstd skippable frame header + the frame size (see WriteTOCAndFooter) t.Fatalf("ParseFooter(footerBytes(offset %d)) = blobPayloadSize %d; want %d", off, gotBlobPayloadSize, off-8) } if gotOff != off { t.Fatalf("ParseFooter(footerBytes(offset %d)) = off %d; want %d", off, gotOff, off) } if gotSize != cSize { t.Fatalf("ParseFooter(footerBytes(offset %d)) = size %d; want %d", off, gotSize, cSize) } } stargz-snapshotter-0.14.3/fs/000077500000000000000000000000001440204344700160735ustar00rootroot00000000000000stargz-snapshotter-0.14.3/fs/config/000077500000000000000000000000001440204344700173405ustar00rootroot00000000000000stargz-snapshotter-0.14.3/fs/config/config.go000066400000000000000000000072571440204344700211470ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /* Copyright 2019 The Go Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the NOTICE.md file. */ package config const ( // TargetSkipVerifyLabel is a snapshot label key that indicates to skip content // verification for the layer. TargetSkipVerifyLabel = "containerd.io/snapshot/remote/stargz.skipverify" // TargetPrefetchSizeLabel is a snapshot label key that indicates size to prefetch // the layer. If the layer is eStargz and contains prefetch landmarks, these config // will be respeced. TargetPrefetchSizeLabel = "containerd.io/snapshot/remote/stargz.prefetch" ) type Config struct { HTTPCacheType string `toml:"http_cache_type"` FSCacheType string `toml:"filesystem_cache_type"` // ResolveResultEntryTTLSec is TTL (in sec) to cache resolved layers for // future use. (default 120s) ResolveResultEntryTTLSec int `toml:"resolve_result_entry_ttl_sec"` ResolveResultEntry int `toml:"resolve_result_entry"` // deprecated PrefetchSize int64 `toml:"prefetch_size"` PrefetchTimeoutSec int64 `toml:"prefetch_timeout_sec"` NoPrefetch bool `toml:"noprefetch"` NoBackgroundFetch bool `toml:"no_background_fetch"` Debug bool `toml:"debug"` AllowNoVerification bool `toml:"allow_no_verification"` DisableVerification bool `toml:"disable_verification"` MaxConcurrency int64 `toml:"max_concurrency"` NoPrometheus bool `toml:"no_prometheus"` // BlobConfig is config for layer blob management. BlobConfig `toml:"blob"` // DirectoryCacheConfig is config for directory-based cache. DirectoryCacheConfig `toml:"directory_cache"` FuseConfig `toml:"fuse"` } type BlobConfig struct { ValidInterval int64 `toml:"valid_interval"` CheckAlways bool `toml:"check_always"` // ChunkSize is the granularity at which background fetch and on-demand reads // are fetched from the remote registry. ChunkSize int64 `toml:"chunk_size"` FetchTimeoutSec int64 `toml:"fetching_timeout_sec"` ForceSingleRangeMode bool `toml:"force_single_range_mode"` // PrefetchChunkSize is the maximum bytes transferred per http GET from remote registry // during prefetch. It is recommended to have PrefetchChunkSize > ChunkSize. // If PrefetchChunkSize < ChunkSize prefetch bytes will be fetched as a single http GET, // else total GET requests for prefetch = ceil(PrefetchSize / PrefetchChunkSize). PrefetchChunkSize int64 `toml:"prefetch_chunk_size"` MaxRetries int `toml:"max_retries"` MinWaitMSec int `toml:"min_wait_msec"` MaxWaitMSec int `toml:"max_wait_msec"` } type DirectoryCacheConfig struct { MaxLRUCacheEntry int `toml:"max_lru_cache_entry"` MaxCacheFds int `toml:"max_cache_fds"` SyncAdd bool `toml:"sync_add"` Direct bool `toml:"direct" default:"true"` } type FuseConfig struct { // AttrTimeout defines overall timeout attribute for a file system in seconds. AttrTimeout int64 `toml:"attr_timeout"` // EntryTimeout defines TTL for directory, name lookup in seconds. EntryTimeout int64 `toml:"entry_timeout"` } stargz-snapshotter-0.14.3/fs/fs.go000066400000000000000000000374631440204344700170470ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /* Copyright 2019 The Go Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the NOTICE.md file. */ // // Example implementation of FileSystem. // // This implementation uses stargz by CRFS(https://github.com/google/crfs) as // image format, which has following feature: // - We can use docker registry as a backend store (means w/o additional layer // stores). // - The stargz-formatted image is still docker-compatible (means normal // runtimes can still use the formatted image). // // Currently, we reimplemented CRFS-like filesystem for ease of integration. // But in the near future, we intend to integrate it with CRFS. // package fs import ( "context" "fmt" "os/exec" "strconv" "sync" "time" "github.com/containerd/containerd/log" "github.com/containerd/containerd/reference" "github.com/containerd/containerd/remotes/docker" "github.com/containerd/stargz-snapshotter/estargz" "github.com/containerd/stargz-snapshotter/fs/config" "github.com/containerd/stargz-snapshotter/fs/layer" commonmetrics "github.com/containerd/stargz-snapshotter/fs/metrics/common" layermetrics "github.com/containerd/stargz-snapshotter/fs/metrics/layer" "github.com/containerd/stargz-snapshotter/fs/remote" "github.com/containerd/stargz-snapshotter/fs/source" "github.com/containerd/stargz-snapshotter/metadata" memorymetadata "github.com/containerd/stargz-snapshotter/metadata/memory" "github.com/containerd/stargz-snapshotter/snapshot" "github.com/containerd/stargz-snapshotter/task" metrics "github.com/docker/go-metrics" fusefs "github.com/hanwen/go-fuse/v2/fs" "github.com/hanwen/go-fuse/v2/fuse" digest "github.com/opencontainers/go-digest" ocispec "github.com/opencontainers/image-spec/specs-go/v1" "github.com/sirupsen/logrus" "golang.org/x/sys/unix" ) const ( defaultFuseTimeout = time.Second defaultMaxConcurrency = 2 ) var fusermountBin = []string{"fusermount", "fusermount3"} type Option func(*options) type options struct { getSources source.GetSources resolveHandlers map[string]remote.Handler metadataStore metadata.Store metricsLogLevel *logrus.Level overlayOpaqueType layer.OverlayOpaqueType additionalDecompressors func(context.Context, source.RegistryHosts, reference.Spec, ocispec.Descriptor) []metadata.Decompressor } func WithGetSources(s source.GetSources) Option { return func(opts *options) { opts.getSources = s } } func WithResolveHandler(name string, handler remote.Handler) Option { return func(opts *options) { if opts.resolveHandlers == nil { opts.resolveHandlers = make(map[string]remote.Handler) } opts.resolveHandlers[name] = handler } } func WithMetadataStore(metadataStore metadata.Store) Option { return func(opts *options) { opts.metadataStore = metadataStore } } func WithMetricsLogLevel(logLevel logrus.Level) Option { return func(opts *options) { opts.metricsLogLevel = &logLevel } } func WithOverlayOpaqueType(overlayOpaqueType layer.OverlayOpaqueType) Option { return func(opts *options) { opts.overlayOpaqueType = overlayOpaqueType } } func WithAdditionalDecompressors(d func(context.Context, source.RegistryHosts, reference.Spec, ocispec.Descriptor) []metadata.Decompressor) Option { return func(opts *options) { opts.additionalDecompressors = d } } func NewFilesystem(root string, cfg config.Config, opts ...Option) (_ snapshot.FileSystem, err error) { var fsOpts options for _, o := range opts { o(&fsOpts) } maxConcurrency := cfg.MaxConcurrency if maxConcurrency == 0 { maxConcurrency = defaultMaxConcurrency } attrTimeout := time.Duration(cfg.FuseConfig.AttrTimeout) * time.Second if attrTimeout == 0 { attrTimeout = defaultFuseTimeout } entryTimeout := time.Duration(cfg.FuseConfig.EntryTimeout) * time.Second if entryTimeout == 0 { entryTimeout = defaultFuseTimeout } metadataStore := fsOpts.metadataStore if metadataStore == nil { metadataStore = memorymetadata.NewReader } getSources := fsOpts.getSources if getSources == nil { getSources = source.FromDefaultLabels(func(refspec reference.Spec) (hosts []docker.RegistryHost, _ error) { return docker.ConfigureDefaultRegistries(docker.WithPlainHTTP(docker.MatchLocalhost))(refspec.Hostname()) }) } tm := task.NewBackgroundTaskManager(maxConcurrency, 5*time.Second) r, err := layer.NewResolver(root, tm, cfg, fsOpts.resolveHandlers, metadataStore, fsOpts.overlayOpaqueType, fsOpts.additionalDecompressors) if err != nil { return nil, fmt.Errorf("failed to setup resolver: %w", err) } var ns *metrics.Namespace if !cfg.NoPrometheus { ns = metrics.NewNamespace("stargz", "fs", nil) logLevel := logrus.DebugLevel if fsOpts.metricsLogLevel != nil { logLevel = *fsOpts.metricsLogLevel } commonmetrics.Register(logLevel) // Register common metrics. This will happen only once. } c := layermetrics.NewLayerMetrics(ns) if ns != nil { metrics.Register(ns) // Register layer metrics. } return &filesystem{ resolver: r, getSources: getSources, prefetchSize: cfg.PrefetchSize, noprefetch: cfg.NoPrefetch, noBackgroundFetch: cfg.NoBackgroundFetch, debug: cfg.Debug, layer: make(map[string]layer.Layer), backgroundTaskManager: tm, allowNoVerification: cfg.AllowNoVerification, disableVerification: cfg.DisableVerification, metricsController: c, attrTimeout: attrTimeout, entryTimeout: entryTimeout, }, nil } type filesystem struct { resolver *layer.Resolver prefetchSize int64 noprefetch bool noBackgroundFetch bool debug bool layer map[string]layer.Layer layerMu sync.Mutex backgroundTaskManager *task.BackgroundTaskManager allowNoVerification bool disableVerification bool getSources source.GetSources metricsController *layermetrics.Controller attrTimeout time.Duration entryTimeout time.Duration } func (fs *filesystem) Mount(ctx context.Context, mountpoint string, labels map[string]string) (retErr error) { // Setting the start time to measure the Mount operation duration. start := time.Now() // This is a prioritized task and all background tasks will be stopped // execution so this can avoid being disturbed for NW traffic by background // tasks. fs.backgroundTaskManager.DoPrioritizedTask() defer fs.backgroundTaskManager.DonePrioritizedTask() ctx = log.WithLogger(ctx, log.G(ctx).WithField("mountpoint", mountpoint)) // Get source information of this layer. src, err := fs.getSources(labels) if err != nil { return err } else if len(src) == 0 { return fmt.Errorf("source must be passed") } defaultPrefetchSize := fs.prefetchSize if psStr, ok := labels[config.TargetPrefetchSizeLabel]; ok { if ps, err := strconv.ParseInt(psStr, 10, 64); err == nil { defaultPrefetchSize = ps } } // Resolve the target layer var ( resultChan = make(chan layer.Layer) errChan = make(chan error) ) go func() { rErr := fmt.Errorf("failed to resolve target") for _, s := range src { l, err := fs.resolver.Resolve(ctx, s.Hosts, s.Name, s.Target) if err == nil { resultChan <- l fs.prefetch(ctx, l, defaultPrefetchSize, start) return } rErr = fmt.Errorf("failed to resolve layer %q from %q: %v: %w", s.Target.Digest, s.Name, err, rErr) } errChan <- rErr }() // Also resolve and cache other layers in parallel preResolve := src[0] // TODO: should we pre-resolve blobs in other sources as well? for _, desc := range neighboringLayers(preResolve.Manifest, preResolve.Target) { desc := desc go func() { // Avoids to get canceled by client. ctx := log.WithLogger(context.Background(), log.G(ctx).WithField("mountpoint", mountpoint)) l, err := fs.resolver.Resolve(ctx, preResolve.Hosts, preResolve.Name, desc) if err != nil { log.G(ctx).WithError(err).Debug("failed to pre-resolve") return } fs.prefetch(ctx, l, defaultPrefetchSize, start) // Release this layer because this isn't target and we don't use it anymore here. // However, this will remain on the resolver cache until eviction. l.Done() }() } // Wait for resolving completion var l layer.Layer select { case l = <-resultChan: case err := <-errChan: log.G(ctx).WithError(err).Debug("failed to resolve layer") return fmt.Errorf("failed to resolve layer: %w", err) case <-time.After(30 * time.Second): log.G(ctx).Debug("failed to resolve layer (timeout)") return fmt.Errorf("failed to resolve layer (timeout)") } defer func() { if retErr != nil { l.Done() // don't use this layer. } }() // Verify layer's content if fs.disableVerification { // Skip if verification is disabled completely l.SkipVerify() log.G(ctx).Infof("Verification forcefully skipped") } else if tocDigest, ok := labels[estargz.TOCJSONDigestAnnotation]; ok { // Verify this layer using the TOC JSON digest passed through label. dgst, err := digest.Parse(tocDigest) if err != nil { log.G(ctx).WithError(err).Debugf("failed to parse passed TOC digest %q", dgst) return fmt.Errorf("invalid TOC digest: %v: %w", tocDigest, err) } if err := l.Verify(dgst); err != nil { log.G(ctx).WithError(err).Debugf("invalid layer") return fmt.Errorf("invalid stargz layer: %w", err) } log.G(ctx).Debugf("verified") } else if _, ok := labels[config.TargetSkipVerifyLabel]; ok && fs.allowNoVerification { // If unverified layer is allowed, use it with warning. // This mode is for legacy stargz archives which don't contain digests // necessary for layer verification. l.SkipVerify() log.G(ctx).Warningf("No verification is held for layer") } else { // Verification must be done. Don't mount this layer. return fmt.Errorf("digest of TOC JSON must be passed") } node, err := l.RootNode(0) if err != nil { log.G(ctx).WithError(err).Warnf("Failed to get root node") return fmt.Errorf("failed to get root node: %w", err) } // Measuring duration of Mount operation for resolved layer. digest := l.Info().Digest // get layer sha defer commonmetrics.MeasureLatencyInMilliseconds(commonmetrics.Mount, digest, start) // Register the mountpoint layer fs.layerMu.Lock() fs.layer[mountpoint] = l fs.layerMu.Unlock() fs.metricsController.Add(mountpoint, l) // mount the node to the specified mountpoint // TODO: bind mount the state directory as a read-only fs on snapshotter's side rawFS := fusefs.NewNodeFS(node, &fusefs.Options{ AttrTimeout: &fs.attrTimeout, EntryTimeout: &fs.entryTimeout, NullPermissions: true, }) mountOpts := &fuse.MountOptions{ AllowOther: true, // allow users other than root&mounter to access fs FsName: "stargz", // name this filesystem as "stargz" Debug: fs.debug, } if isFusermountBinExist() { log.G(ctx).Infof("fusermount detected") mountOpts.Options = []string{"suid"} // option for fusermount; allow setuid inside container } else { log.G(ctx).WithError(err).Infof("%s not installed; trying direct mount", fusermountBin) mountOpts.DirectMount = true } server, err := fuse.NewServer(rawFS, mountpoint, mountOpts) if err != nil { log.G(ctx).WithError(err).Debug("failed to make filesystem server") return err } go server.Serve() return server.WaitMount() } func (fs *filesystem) Check(ctx context.Context, mountpoint string, labels map[string]string) error { // This is a prioritized task and all background tasks will be stopped // execution so this can avoid being disturbed for NW traffic by background // tasks. fs.backgroundTaskManager.DoPrioritizedTask() defer fs.backgroundTaskManager.DonePrioritizedTask() defer commonmetrics.MeasureLatencyInMilliseconds(commonmetrics.PrefetchesCompleted, digest.FromString(""), time.Now()) // measuring the time the container launch is blocked on prefetch to complete ctx = log.WithLogger(ctx, log.G(ctx).WithField("mountpoint", mountpoint)) fs.layerMu.Lock() l := fs.layer[mountpoint] fs.layerMu.Unlock() if l == nil { log.G(ctx).Debug("layer not registered") return fmt.Errorf("layer not registered") } // Check the blob connectivity and try to refresh the connection on failure if err := fs.check(ctx, l, labels); err != nil { log.G(ctx).WithError(err).Warn("check failed") return err } // Wait for prefetch compeletion if !fs.noprefetch { if err := l.WaitForPrefetchCompletion(); err != nil { log.G(ctx).WithError(err).Warn("failed to sync with prefetch completion") } } return nil } func (fs *filesystem) check(ctx context.Context, l layer.Layer, labels map[string]string) error { err := l.Check() if err == nil { return nil } log.G(ctx).WithError(err).Warn("failed to connect to blob") // Check failed. Try to refresh the connection with fresh source information src, err := fs.getSources(labels) if err != nil { return err } var ( retrynum = 1 rErr = fmt.Errorf("failed to refresh connection") ) for retry := 0; retry < retrynum; retry++ { log.G(ctx).Warnf("refreshing(%d)...", retry) for _, s := range src { err := l.Refresh(ctx, s.Hosts, s.Name, s.Target) if err == nil { log.G(ctx).Debug("Successfully refreshed connection") return nil } log.G(ctx).WithError(err).Warnf("failed to refresh the layer %q from %q", s.Target.Digest, s.Name) rErr = fmt.Errorf("failed(layer:%q, ref:%q): %v: %w", s.Target.Digest, s.Name, err, rErr) } } return rErr } func (fs *filesystem) Unmount(ctx context.Context, mountpoint string) error { if mountpoint == "" { return fmt.Errorf("mount point must be specified") } fs.layerMu.Lock() l, ok := fs.layer[mountpoint] if !ok { fs.layerMu.Unlock() return fmt.Errorf("specified path %q isn't a mountpoint", mountpoint) } delete(fs.layer, mountpoint) // unregisters the corresponding layer l.Done() fs.layerMu.Unlock() fs.metricsController.Remove(mountpoint) if err := unmount(mountpoint, 0); err != nil { if err != unix.EBUSY { return err } // Try force unmount log.G(ctx).WithError(err).Debugf("trying force unmount %q", mountpoint) if err := unmount(mountpoint, unix.MNT_FORCE); err != nil { return err } } return nil } func unmount(target string, flags int) error { for { if err := unix.Unmount(target, flags); err != unix.EINTR { return err } } } func (fs *filesystem) prefetch(ctx context.Context, l layer.Layer, defaultPrefetchSize int64, start time.Time) { // Prefetch a layer. The first Check() for this layer waits for the prefetch completion. if !fs.noprefetch { go l.Prefetch(defaultPrefetchSize) } // Fetch whole layer aggressively in background. if !fs.noBackgroundFetch { go func() { if err := l.BackgroundFetch(); err == nil { // write log record for the latency between mount start and last on demand fetch commonmetrics.LogLatencyForLastOnDemandFetch(ctx, l.Info().Digest, start, l.Info().ReadTime) } }() } } // neighboringLayers returns layer descriptors except the `target` layer in the specified manifest. func neighboringLayers(manifest ocispec.Manifest, target ocispec.Descriptor) (descs []ocispec.Descriptor) { for _, desc := range manifest.Layers { if desc.Digest.String() != target.Digest.String() { descs = append(descs, desc) } } return } func isFusermountBinExist() bool { for _, b := range fusermountBin { if _, err := exec.LookPath(b); err == nil { return true } } return false } stargz-snapshotter-0.14.3/fs/fs_test.go000066400000000000000000000061571440204344700201020ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /* Copyright 2019 The Go Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the NOTICE.md file. */ package fs import ( "context" "fmt" "testing" "time" "github.com/containerd/containerd/reference" "github.com/containerd/containerd/remotes/docker" "github.com/containerd/stargz-snapshotter/fs/layer" "github.com/containerd/stargz-snapshotter/fs/remote" "github.com/containerd/stargz-snapshotter/fs/source" "github.com/containerd/stargz-snapshotter/task" fusefs "github.com/hanwen/go-fuse/v2/fs" digest "github.com/opencontainers/go-digest" ocispec "github.com/opencontainers/image-spec/specs-go/v1" ) func TestCheck(t *testing.T) { bl := &breakableLayer{} fs := &filesystem{ layer: map[string]layer.Layer{ "test": bl, }, backgroundTaskManager: task.NewBackgroundTaskManager(1, time.Millisecond), getSources: source.FromDefaultLabels(func(refspec reference.Spec) (hosts []docker.RegistryHost, _ error) { return docker.ConfigureDefaultRegistries(docker.WithPlainHTTP(docker.MatchLocalhost))(refspec.Hostname()) }), } bl.success = true if err := fs.Check(context.TODO(), "test", nil); err != nil { t.Errorf("connection failed; wanted to succeed: %v", err) } bl.success = false if err := fs.Check(context.TODO(), "test", nil); err == nil { t.Errorf("connection succeeded; wanted to fail") } } type breakableLayer struct { success bool } func (l *breakableLayer) Info() layer.Info { return layer.Info{} } func (l *breakableLayer) RootNode(uint32) (fusefs.InodeEmbedder, error) { return nil, nil } func (l *breakableLayer) Verify(tocDigest digest.Digest) error { return nil } func (l *breakableLayer) SkipVerify() {} func (l *breakableLayer) Prefetch(prefetchSize int64) error { return fmt.Errorf("fail") } func (l *breakableLayer) ReadAt([]byte, int64, ...remote.Option) (int, error) { return 0, nil } func (l *breakableLayer) WaitForPrefetchCompletion() error { return fmt.Errorf("fail") } func (l *breakableLayer) BackgroundFetch() error { return fmt.Errorf("fail") } func (l *breakableLayer) Check() error { if !l.success { return fmt.Errorf("failed") } return nil } func (l *breakableLayer) Refresh(ctx context.Context, hosts source.RegistryHosts, refspec reference.Spec, desc ocispec.Descriptor) error { if !l.success { return fmt.Errorf("failed") } return nil } func (l *breakableLayer) Done() {} stargz-snapshotter-0.14.3/fs/layer/000077500000000000000000000000001440204344700172075ustar00rootroot00000000000000stargz-snapshotter-0.14.3/fs/layer/layer.go000066400000000000000000000517121440204344700206600ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /* Copyright 2019 The Go Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the NOTICE.md file. */ package layer import ( "bytes" "context" "fmt" "io" "os" "path/filepath" "sync" "time" "github.com/containerd/containerd/log" "github.com/containerd/containerd/reference" "github.com/containerd/stargz-snapshotter/cache" "github.com/containerd/stargz-snapshotter/estargz" "github.com/containerd/stargz-snapshotter/estargz/zstdchunked" "github.com/containerd/stargz-snapshotter/fs/config" commonmetrics "github.com/containerd/stargz-snapshotter/fs/metrics/common" "github.com/containerd/stargz-snapshotter/fs/reader" "github.com/containerd/stargz-snapshotter/fs/remote" "github.com/containerd/stargz-snapshotter/fs/source" "github.com/containerd/stargz-snapshotter/metadata" "github.com/containerd/stargz-snapshotter/task" "github.com/containerd/stargz-snapshotter/util/cacheutil" "github.com/containerd/stargz-snapshotter/util/namedmutex" fusefs "github.com/hanwen/go-fuse/v2/fs" digest "github.com/opencontainers/go-digest" ocispec "github.com/opencontainers/image-spec/specs-go/v1" "github.com/sirupsen/logrus" ) const ( defaultResolveResultEntryTTLSec = 120 defaultMaxLRUCacheEntry = 10 defaultMaxCacheFds = 10 defaultPrefetchTimeoutSec = 10 memoryCacheType = "memory" ) // Layer represents a layer. type Layer interface { // Info returns the information of this layer. Info() Info // RootNode returns the root node of this layer. RootNode(baseInode uint32) (fusefs.InodeEmbedder, error) // Check checks if the layer is still connectable. Check() error // Refresh refreshes the layer connection. Refresh(ctx context.Context, hosts source.RegistryHosts, refspec reference.Spec, desc ocispec.Descriptor) error // Verify verifies this layer using the passed TOC Digest. // Nop if Verify() or SkipVerify() was already called. Verify(tocDigest digest.Digest) (err error) // SkipVerify skips verification for this layer. // Nop if Verify() or SkipVerify() was already called. SkipVerify() // Prefetch prefetches the specified size. If the layer is eStargz and contains landmark files, // the range indicated by these files is respected. Prefetch(prefetchSize int64) error // ReadAt reads this layer. ReadAt([]byte, int64, ...remote.Option) (int, error) // WaitForPrefetchCompletion waits untils Prefetch completes. WaitForPrefetchCompletion() error // BackgroundFetch fetches the entire layer contents to the cache. // Fetching contents is done as a background task. BackgroundFetch() error // Done releases the reference to this layer. The resources related to this layer will be // discarded sooner or later. Queries after calling this function won't be serviced. Done() } // Info is the current status of a layer. type Info struct { Digest digest.Digest Size int64 // layer size in bytes FetchedSize int64 // layer fetched size in bytes PrefetchSize int64 // layer prefetch size in bytes ReadTime time.Time // last time the layer was read } // Resolver resolves the layer location and provieds the handler of that layer. type Resolver struct { rootDir string resolver *remote.Resolver prefetchTimeout time.Duration layerCache *cacheutil.TTLCache layerCacheMu sync.Mutex blobCache *cacheutil.TTLCache blobCacheMu sync.Mutex backgroundTaskManager *task.BackgroundTaskManager resolveLock *namedmutex.NamedMutex config config.Config metadataStore metadata.Store overlayOpaqueType OverlayOpaqueType additionalDecompressors func(context.Context, source.RegistryHosts, reference.Spec, ocispec.Descriptor) []metadata.Decompressor } // NewResolver returns a new layer resolver. func NewResolver(root string, backgroundTaskManager *task.BackgroundTaskManager, cfg config.Config, resolveHandlers map[string]remote.Handler, metadataStore metadata.Store, overlayOpaqueType OverlayOpaqueType, additionalDecompressors func(context.Context, source.RegistryHosts, reference.Spec, ocispec.Descriptor) []metadata.Decompressor) (*Resolver, error) { resolveResultEntryTTL := time.Duration(cfg.ResolveResultEntryTTLSec) * time.Second if resolveResultEntryTTL == 0 { resolveResultEntryTTL = defaultResolveResultEntryTTLSec * time.Second } prefetchTimeout := time.Duration(cfg.PrefetchTimeoutSec) * time.Second if prefetchTimeout == 0 { prefetchTimeout = defaultPrefetchTimeoutSec * time.Second } // layerCache caches resolved layers for future use. This is useful in a use-case where // the filesystem resolves and caches all layers in an image (not only queried one) in parallel, // before they are actually queried. layerCache := cacheutil.NewTTLCache(resolveResultEntryTTL) layerCache.OnEvicted = func(key string, value interface{}) { if err := value.(*layer).close(); err != nil { logrus.WithField("key", key).WithError(err).Warnf("failed to clean up layer") return } logrus.WithField("key", key).Debugf("cleaned up layer") } // blobCache caches resolved blobs for futural use. This is especially useful when a layer // isn't eStargz/stargz (the *layer object won't be created/cached in this case). blobCache := cacheutil.NewTTLCache(resolveResultEntryTTL) blobCache.OnEvicted = func(key string, value interface{}) { if err := value.(remote.Blob).Close(); err != nil { logrus.WithField("key", key).WithError(err).Warnf("failed to clean up blob") return } logrus.WithField("key", key).Debugf("cleaned up blob") } if err := os.MkdirAll(root, 0700); err != nil { return nil, err } return &Resolver{ rootDir: root, resolver: remote.NewResolver(cfg.BlobConfig, resolveHandlers), layerCache: layerCache, blobCache: blobCache, prefetchTimeout: prefetchTimeout, backgroundTaskManager: backgroundTaskManager, config: cfg, resolveLock: new(namedmutex.NamedMutex), metadataStore: metadataStore, overlayOpaqueType: overlayOpaqueType, additionalDecompressors: additionalDecompressors, }, nil } func newCache(root string, cacheType string, cfg config.Config) (cache.BlobCache, error) { if cacheType == memoryCacheType { return cache.NewMemoryCache(), nil } dcc := cfg.DirectoryCacheConfig maxDataEntry := dcc.MaxLRUCacheEntry if maxDataEntry == 0 { maxDataEntry = defaultMaxLRUCacheEntry } maxFdEntry := dcc.MaxCacheFds if maxFdEntry == 0 { maxFdEntry = defaultMaxCacheFds } bufPool := &sync.Pool{ New: func() interface{} { return new(bytes.Buffer) }, } dCache, fCache := cacheutil.NewLRUCache(maxDataEntry), cacheutil.NewLRUCache(maxFdEntry) dCache.OnEvicted = func(key string, value interface{}) { value.(*bytes.Buffer).Reset() bufPool.Put(value) } fCache.OnEvicted = func(key string, value interface{}) { value.(*os.File).Close() } // create a cache on an unique directory if err := os.MkdirAll(root, 0700); err != nil { return nil, err } cachePath, err := os.MkdirTemp(root, "") if err != nil { return nil, fmt.Errorf("failed to initialize directory cache: %w", err) } return cache.NewDirectoryCache( cachePath, cache.DirectoryCacheConfig{ SyncAdd: dcc.SyncAdd, DataCache: dCache, FdCache: fCache, BufPool: bufPool, Direct: dcc.Direct, }, ) } // Resolve resolves a layer based on the passed layer blob information. func (r *Resolver) Resolve(ctx context.Context, hosts source.RegistryHosts, refspec reference.Spec, desc ocispec.Descriptor, esgzOpts ...metadata.Option) (_ Layer, retErr error) { name := refspec.String() + "/" + desc.Digest.String() // Wait if resolving this layer is already running. The result // can hopefully get from the cache. r.resolveLock.Lock(name) defer r.resolveLock.Unlock(name) ctx = log.WithLogger(ctx, log.G(ctx).WithField("src", name)) // First, try to retrieve this layer from the underlying cache. r.layerCacheMu.Lock() c, done, ok := r.layerCache.Get(name) r.layerCacheMu.Unlock() if ok { if l := c.(*layer); l.Check() == nil { log.G(ctx).Debugf("hit layer cache %q", name) return &layerRef{l, done}, nil } // Cached layer is invalid done() r.layerCacheMu.Lock() r.layerCache.Remove(name) r.layerCacheMu.Unlock() } log.G(ctx).Debugf("resolving") // Resolve the blob. blobR, err := r.resolveBlob(ctx, hosts, refspec, desc) if err != nil { return nil, fmt.Errorf("failed to resolve the blob: %w", err) } defer func() { if retErr != nil { blobR.done() } }() fsCache, err := newCache(filepath.Join(r.rootDir, "fscache"), r.config.FSCacheType, r.config) if err != nil { return nil, fmt.Errorf("failed to create fs cache: %w", err) } defer func() { if retErr != nil { fsCache.Close() } }() // Get a reader for stargz archive. // Each file's read operation is a prioritized task and all background tasks // will be stopped during the execution so this can avoid being disturbed for // NW traffic by background tasks. sr := io.NewSectionReader(readerAtFunc(func(p []byte, offset int64) (n int, err error) { r.backgroundTaskManager.DoPrioritizedTask() defer r.backgroundTaskManager.DonePrioritizedTask() return blobR.ReadAt(p, offset) }), 0, blobR.Size()) // define telemetry hooks to measure latency metrics inside estargz package telemetry := metadata.Telemetry{ GetFooterLatency: func(start time.Time) { commonmetrics.MeasureLatencyInMilliseconds(commonmetrics.StargzFooterGet, desc.Digest, start) }, GetTocLatency: func(start time.Time) { commonmetrics.MeasureLatencyInMilliseconds(commonmetrics.StargzTocGet, desc.Digest, start) }, DeserializeTocLatency: func(start time.Time) { commonmetrics.MeasureLatencyInMilliseconds(commonmetrics.DeserializeTocJSON, desc.Digest, start) }, } additionalDecompressors := []metadata.Decompressor{new(zstdchunked.Decompressor)} if r.additionalDecompressors != nil { additionalDecompressors = append(additionalDecompressors, r.additionalDecompressors(ctx, hosts, refspec, desc)...) } meta, err := r.metadataStore(sr, append(esgzOpts, metadata.WithTelemetry(&telemetry), metadata.WithDecompressors(additionalDecompressors...))...) if err != nil { return nil, err } vr, err := reader.NewReader(meta, fsCache, desc.Digest) if err != nil { return nil, fmt.Errorf("failed to read layer: %w", err) } // Combine layer information together and cache it. l := newLayer(r, desc, blobR, vr) r.layerCacheMu.Lock() cachedL, done2, added := r.layerCache.Add(name, l) r.layerCacheMu.Unlock() if !added { l.close() // layer already exists in the cache. discrad this. } log.G(ctx).Debugf("resolved") return &layerRef{cachedL.(*layer), done2}, nil } // resolveBlob resolves a blob based on the passed layer blob information. func (r *Resolver) resolveBlob(ctx context.Context, hosts source.RegistryHosts, refspec reference.Spec, desc ocispec.Descriptor) (_ *blobRef, retErr error) { name := refspec.String() + "/" + desc.Digest.String() // Try to retrieve the blob from the underlying cache. r.blobCacheMu.Lock() c, done, ok := r.blobCache.Get(name) r.blobCacheMu.Unlock() if ok { if blob := c.(remote.Blob); blob.Check() == nil { return &blobRef{blob, done}, nil } // invalid blob. discard this. done() r.blobCacheMu.Lock() r.blobCache.Remove(name) r.blobCacheMu.Unlock() } httpCache, err := newCache(filepath.Join(r.rootDir, "httpcache"), r.config.HTTPCacheType, r.config) if err != nil { return nil, fmt.Errorf("failed to create http cache: %w", err) } defer func() { if retErr != nil { httpCache.Close() } }() // Resolve the blob and cache the result. b, err := r.resolver.Resolve(ctx, hosts, refspec, desc, httpCache) if err != nil { return nil, fmt.Errorf("failed to resolve the source: %w", err) } r.blobCacheMu.Lock() cachedB, done, added := r.blobCache.Add(name, b) r.blobCacheMu.Unlock() if !added { b.Close() // blob already exists in the cache. discard this. } return &blobRef{cachedB.(remote.Blob), done}, nil } func newLayer( resolver *Resolver, desc ocispec.Descriptor, blob *blobRef, vr *reader.VerifiableReader, ) *layer { return &layer{ resolver: resolver, desc: desc, blob: blob, verifiableReader: vr, prefetchWaiter: newWaiter(), } } type layer struct { resolver *Resolver desc ocispec.Descriptor blob *blobRef verifiableReader *reader.VerifiableReader prefetchWaiter *waiter prefetchSize int64 prefetchSizeMu sync.Mutex r reader.Reader closed bool closedMu sync.Mutex prefetchOnce sync.Once backgroundFetchOnce sync.Once } func (l *layer) Info() Info { var readTime time.Time if l.r != nil { readTime = l.r.LastOnDemandReadTime() } return Info{ Digest: l.desc.Digest, Size: l.blob.Size(), FetchedSize: l.blob.FetchedSize(), PrefetchSize: l.prefetchedSize(), ReadTime: readTime, } } func (l *layer) prefetchedSize() int64 { l.prefetchSizeMu.Lock() sz := l.prefetchSize l.prefetchSizeMu.Unlock() return sz } func (l *layer) Check() error { if l.isClosed() { return fmt.Errorf("layer is already closed") } return l.blob.Check() } func (l *layer) Refresh(ctx context.Context, hosts source.RegistryHosts, refspec reference.Spec, desc ocispec.Descriptor) error { if l.isClosed() { return fmt.Errorf("layer is already closed") } return l.blob.Refresh(ctx, hosts, refspec, desc) } func (l *layer) Verify(tocDigest digest.Digest) (err error) { if l.isClosed() { return fmt.Errorf("layer is already closed") } if l.r != nil { return nil } l.r, err = l.verifiableReader.VerifyTOC(tocDigest) return } func (l *layer) SkipVerify() { if l.r != nil { return } l.r = l.verifiableReader.SkipVerify() } func (l *layer) Prefetch(prefetchSize int64) (err error) { l.prefetchOnce.Do(func() { ctx := context.Background() l.resolver.backgroundTaskManager.DoPrioritizedTask() defer l.resolver.backgroundTaskManager.DonePrioritizedTask() err = l.prefetch(ctx, prefetchSize) if err != nil { log.G(ctx).WithError(err).Warnf("failed to prefetch layer=%v", l.desc.Digest) return } log.G(ctx).Debug("completed to prefetch") }) return } func (l *layer) prefetch(ctx context.Context, prefetchSize int64) error { defer l.prefetchWaiter.done() // Notify the completion // Measuring the total time to complete prefetch (use defer func() because l.Info().PrefetchSize is set later) start := time.Now() defer func() { commonmetrics.WriteLatencyWithBytesLogValue(ctx, l.desc.Digest, commonmetrics.PrefetchTotal, start, commonmetrics.PrefetchSize, l.prefetchedSize()) }() if l.isClosed() { return fmt.Errorf("layer is already closed") } rootID := l.verifiableReader.Metadata().RootID() if _, _, err := l.verifiableReader.Metadata().GetChild(rootID, estargz.NoPrefetchLandmark); err == nil { // do not prefetch this layer return nil } else if id, _, err := l.verifiableReader.Metadata().GetChild(rootID, estargz.PrefetchLandmark); err == nil { offset, err := l.verifiableReader.Metadata().GetOffset(id) if err != nil { return fmt.Errorf("failed to get offset of prefetch landmark: %w", err) } // override the prefetch size with optimized value prefetchSize = offset } else if prefetchSize > l.blob.Size() { // adjust prefetch size not to exceed the whole layer size prefetchSize = l.blob.Size() } // Fetch the target range downloadStart := time.Now() err := l.blob.Cache(0, prefetchSize) commonmetrics.WriteLatencyLogValue(ctx, l.desc.Digest, commonmetrics.PrefetchDownload, downloadStart) // time to download prefetch data if err != nil { return fmt.Errorf("failed to prefetch layer: %w", err) } // Set prefetch size for metrics after prefetch completed l.prefetchSizeMu.Lock() l.prefetchSize = prefetchSize l.prefetchSizeMu.Unlock() // Cache uncompressed contents of the prefetched range decompressStart := time.Now() err = l.verifiableReader.Cache(reader.WithFilter(func(offset int64) bool { return offset < prefetchSize // Cache only prefetch target })) commonmetrics.WriteLatencyLogValue(ctx, l.desc.Digest, commonmetrics.PrefetchDecompress, decompressStart) // time to decompress prefetch data if err != nil { return fmt.Errorf("failed to cache prefetched layer: %w", err) } return nil } func (l *layer) WaitForPrefetchCompletion() error { if l.isClosed() { return fmt.Errorf("layer is already closed") } return l.prefetchWaiter.wait(l.resolver.prefetchTimeout) } func (l *layer) BackgroundFetch() (err error) { l.backgroundFetchOnce.Do(func() { ctx := context.Background() err = l.backgroundFetch(ctx) if err != nil { log.G(ctx).WithError(err).Warnf("failed to fetch whole layer=%v", l.desc.Digest) return } log.G(ctx).Debug("completed to fetch all layer data in background") }) return } func (l *layer) backgroundFetch(ctx context.Context) error { defer commonmetrics.WriteLatencyLogValue(ctx, l.desc.Digest, commonmetrics.BackgroundFetchTotal, time.Now()) if l.isClosed() { return fmt.Errorf("layer is already closed") } br := io.NewSectionReader(readerAtFunc(func(p []byte, offset int64) (retN int, retErr error) { l.resolver.backgroundTaskManager.InvokeBackgroundTask(func(ctx context.Context) { // Measuring the time to download background fetch data (in milliseconds) defer commonmetrics.MeasureLatencyInMilliseconds(commonmetrics.BackgroundFetchDownload, l.Info().Digest, time.Now()) // time to download background fetch data retN, retErr = l.blob.ReadAt( p, offset, remote.WithContext(ctx), // Make cancellable remote.WithCacheOpts(cache.Direct()), // Do not pollute mem cache ) }, 120*time.Second) return }), 0, l.blob.Size()) defer commonmetrics.WriteLatencyLogValue(ctx, l.desc.Digest, commonmetrics.BackgroundFetchDecompress, time.Now()) // time to decompress background fetch data (in milliseconds) return l.verifiableReader.Cache( reader.WithReader(br), // Read contents in background reader.WithCacheOpts(cache.Direct()), // Do not pollute mem cache ) } func (l *layerRef) Done() { l.done() } func (l *layer) RootNode(baseInode uint32) (fusefs.InodeEmbedder, error) { if l.isClosed() { return nil, fmt.Errorf("layer is already closed") } if l.r == nil { return nil, fmt.Errorf("layer hasn't been verified yet") } return newNode(l.desc.Digest, l.r, l.blob, baseInode, l.resolver.overlayOpaqueType) } func (l *layer) ReadAt(p []byte, offset int64, opts ...remote.Option) (int, error) { return l.blob.ReadAt(p, offset, opts...) } func (l *layer) close() error { l.closedMu.Lock() defer l.closedMu.Unlock() if l.closed { return nil } l.closed = true defer l.blob.done() // Close reader first, then close the blob l.verifiableReader.Close() if l.r != nil { return l.r.Close() } return nil } func (l *layer) isClosed() bool { l.closedMu.Lock() closed := l.closed l.closedMu.Unlock() return closed } // blobRef is a reference to the blob in the cache. Calling `done` decreases the reference counter // of this blob in the underlying cache. When nobody refers to the blob in the cache, resources bound // to this blob will be discarded. type blobRef struct { remote.Blob done func() } // layerRef is a reference to the layer in the cache. Calling `Done` or `done` decreases the // reference counter of this blob in the underlying cache. When nobody refers to the layer in the // cache, resources bound to this layer will be discarded. type layerRef struct { *layer done func() } func newWaiter() *waiter { return &waiter{ completionCond: sync.NewCond(&sync.Mutex{}), } } type waiter struct { isDone bool isDoneMu sync.Mutex completionCond *sync.Cond } func (w *waiter) done() { w.isDoneMu.Lock() w.isDone = true w.isDoneMu.Unlock() w.completionCond.Broadcast() } func (w *waiter) wait(timeout time.Duration) error { wait := func() <-chan struct{} { ch := make(chan struct{}) go func() { w.isDoneMu.Lock() isDone := w.isDone w.isDoneMu.Unlock() w.completionCond.L.Lock() if !isDone { w.completionCond.Wait() } w.completionCond.L.Unlock() ch <- struct{}{} }() return ch } select { case <-time.After(timeout): w.isDoneMu.Lock() w.isDone = true w.isDoneMu.Unlock() w.completionCond.Broadcast() return fmt.Errorf("timeout(%v)", timeout) case <-wait(): return nil } } type readerAtFunc func([]byte, int64) (int, error) func (f readerAtFunc) ReadAt(p []byte, offset int64) (int, error) { return f(p, offset) } stargz-snapshotter-0.14.3/fs/layer/layer_test.go000066400000000000000000000027101440204344700217110ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /* Copyright 2019 The Go Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the NOTICE.md file. */ package layer import ( "testing" "time" memorymetadata "github.com/containerd/stargz-snapshotter/metadata/memory" ) func TestLayer(t *testing.T) { TestSuiteLayer(t, memorymetadata.NewReader) } func TestWaiter(t *testing.T) { var ( w = newWaiter() waitTime = time.Second startTime = time.Now() doneTime time.Time done = make(chan struct{}) ) go func() { defer close(done) if err := w.wait(10 * time.Second); err != nil { t.Errorf("failed to wait: %v", err) return } doneTime = time.Now() }() time.Sleep(waitTime) w.done() <-done if doneTime.Sub(startTime) < waitTime { t.Errorf("wait time is too short: %v; want %v", doneTime.Sub(startTime), waitTime) } } stargz-snapshotter-0.14.3/fs/layer/node.go000066400000000000000000000512671440204344700204760ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /* Copyright 2019 The Go Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the NOTICE.md file. */ package layer import ( "bytes" "context" "encoding/json" "errors" "fmt" "io" "os" "sort" "strings" "sync" "syscall" "time" "github.com/containerd/containerd/log" "github.com/containerd/stargz-snapshotter/estargz" commonmetrics "github.com/containerd/stargz-snapshotter/fs/metrics/common" "github.com/containerd/stargz-snapshotter/fs/reader" "github.com/containerd/stargz-snapshotter/fs/remote" "github.com/containerd/stargz-snapshotter/metadata" fusefs "github.com/hanwen/go-fuse/v2/fs" "github.com/hanwen/go-fuse/v2/fuse" digest "github.com/opencontainers/go-digest" "github.com/sirupsen/logrus" "golang.org/x/sys/unix" ) const ( blockSize = 4096 whiteoutPrefix = ".wh." whiteoutOpaqueDir = whiteoutPrefix + whiteoutPrefix + ".opq" opaqueXattrValue = "y" stateDirName = ".stargz-snapshotter" statFileMode = syscall.S_IFREG | 0400 // -r-------- stateDirMode = syscall.S_IFDIR | 0500 // dr-x------ ) type OverlayOpaqueType int const ( OverlayOpaqueAll OverlayOpaqueType = iota OverlayOpaqueTrusted OverlayOpaqueUser ) var opaqueXattrs = map[OverlayOpaqueType][]string{ OverlayOpaqueAll: {"trusted.overlay.opaque", "user.overlay.opaque"}, OverlayOpaqueTrusted: {"trusted.overlay.opaque"}, OverlayOpaqueUser: {"user.overlay.opaque"}, } func newNode(layerDgst digest.Digest, r reader.Reader, blob remote.Blob, baseInode uint32, opaque OverlayOpaqueType) (fusefs.InodeEmbedder, error) { rootID := r.Metadata().RootID() rootAttr, err := r.Metadata().GetAttr(rootID) if err != nil { return nil, err } opq, ok := opaqueXattrs[opaque] if !ok { return nil, fmt.Errorf("Unknown overlay opaque type") } ffs := &fs{ r: r, layerDigest: layerDgst, baseInode: baseInode, rootID: rootID, opaqueXattrs: opq, } ffs.s = ffs.newState(layerDgst, blob) return &node{ id: rootID, attr: rootAttr, fs: ffs, }, nil } // fs contains global metadata used by nodes type fs struct { r reader.Reader s *state layerDigest digest.Digest baseInode uint32 rootID uint32 opaqueXattrs []string } func (fs *fs) inodeOfState() uint64 { return (uint64(fs.baseInode) << 32) | 1 // reserved } func (fs *fs) inodeOfStatFile() uint64 { return (uint64(fs.baseInode) << 32) | 2 // reserved } func (fs *fs) inodeOfID(id uint32) (uint64, error) { // 0 is reserved by go-fuse 1 and 2 are reserved by the state dir if id > ^uint32(0)-3 { return 0, fmt.Errorf("too many inodes") } return (uint64(fs.baseInode) << 32) | uint64(3+id), nil } // node is a filesystem inode abstraction. type node struct { fusefs.Inode fs *fs id uint32 attr metadata.Attr ents []fuse.DirEntry entsCached bool } func (n *node) isRootNode() bool { return n.id == n.fs.rootID } func (n *node) isOpaque() bool { if _, _, err := n.fs.r.Metadata().GetChild(n.id, whiteoutOpaqueDir); err == nil { return true } return false } var _ = (fusefs.InodeEmbedder)((*node)(nil)) var _ = (fusefs.NodeReaddirer)((*node)(nil)) func (n *node) Readdir(ctx context.Context) (fusefs.DirStream, syscall.Errno) { ents, errno := n.readdir() if errno != 0 { return nil, errno } return fusefs.NewListDirStream(ents), 0 } func (n *node) readdir() ([]fuse.DirEntry, syscall.Errno) { // Measure how long node_readdir operation takes (in microseconds). start := time.Now() // set start time defer commonmetrics.MeasureLatencyInMicroseconds(commonmetrics.NodeReaddir, n.fs.layerDigest, start) if n.entsCached { return n.ents, 0 } isRoot := n.isRootNode() var ents []fuse.DirEntry whiteouts := map[string]uint32{} normalEnts := map[string]bool{} var lastErr error if err := n.fs.r.Metadata().ForeachChild(n.id, func(name string, id uint32, mode os.FileMode) bool { // We don't want to show prefetch landmarks in "/". if isRoot && (name == estargz.PrefetchLandmark || name == estargz.NoPrefetchLandmark) { return true } // We don't want to show whiteouts. if strings.HasPrefix(name, whiteoutPrefix) { if name == whiteoutOpaqueDir { return true } // Add the overlayfs-compiant whiteout later. whiteouts[name] = id return true } // This is a normal entry. normalEnts[name] = true ino, err := n.fs.inodeOfID(id) if err != nil { lastErr = err return false } ents = append(ents, fuse.DirEntry{ Mode: fileModeToSystemMode(mode), Name: name, Ino: ino, }) return true }); err != nil || lastErr != nil { n.fs.s.report(fmt.Errorf("node.Readdir: err = %v; lastErr = %v", err, lastErr)) return nil, syscall.EIO } // Append whiteouts if no entry replaces the target entry in the lower layer. for w, id := range whiteouts { if !normalEnts[w[len(whiteoutPrefix):]] { ino, err := n.fs.inodeOfID(id) if err != nil { n.fs.s.report(fmt.Errorf("node.Readdir: err = %v; lastErr = %v", err, lastErr)) return nil, syscall.EIO } ents = append(ents, fuse.DirEntry{ Mode: syscall.S_IFCHR, Name: w[len(whiteoutPrefix):], Ino: ino, }) } } // Avoid undeterministic order of entries on each call sort.Slice(ents, func(i, j int) bool { return ents[i].Name < ents[j].Name }) n.ents, n.entsCached = ents, true // cache it return ents, 0 } var _ = (fusefs.NodeLookuper)((*node)(nil)) func (n *node) Lookup(ctx context.Context, name string, out *fuse.EntryOut) (*fusefs.Inode, syscall.Errno) { isRoot := n.isRootNode() // We don't want to show prefetch landmarks in "/". if isRoot && (name == estargz.PrefetchLandmark || name == estargz.NoPrefetchLandmark) { return nil, syscall.ENOENT } // We don't want to show whiteouts. if strings.HasPrefix(name, whiteoutPrefix) { return nil, syscall.ENOENT } // state directory if isRoot && name == stateDirName { return n.NewInode(ctx, n.fs.s, n.fs.stateToAttr(&out.Attr)), 0 } // lookup on memory nodes if cn := n.GetChild(name); cn != nil { switch tn := cn.Operations().(type) { case *node: ino, err := n.fs.inodeOfID(tn.id) if err != nil { n.fs.s.report(fmt.Errorf("node.Lookup: %v", err)) return nil, syscall.EIO } entryToAttr(ino, tn.attr, &out.Attr) case *whiteout: ino, err := n.fs.inodeOfID(tn.id) if err != nil { n.fs.s.report(fmt.Errorf("node.Lookup: %v", err)) return nil, syscall.EIO } entryToAttr(ino, tn.attr, &out.Attr) default: n.fs.s.report(fmt.Errorf("node.Lookup: uknown node type detected")) return nil, syscall.EIO } return cn, 0 } // early return if this entry doesn't exist if n.entsCached { var found bool for _, e := range n.ents { if e.Name == name { found = true } } if !found { return nil, syscall.ENOENT } } id, ce, err := n.fs.r.Metadata().GetChild(n.id, name) if err != nil { // If the entry exists as a whiteout, show an overlayfs-styled whiteout node. if whID, wh, err := n.fs.r.Metadata().GetChild(n.id, fmt.Sprintf("%s%s", whiteoutPrefix, name)); err == nil { ino, err := n.fs.inodeOfID(whID) if err != nil { n.fs.s.report(fmt.Errorf("node.Lookup: %v", err)) return nil, syscall.EIO } return n.NewInode(ctx, &whiteout{ id: whID, fs: n.fs, attr: wh, }, entryToWhAttr(ino, wh, &out.Attr)), 0 } n.readdir() // This code path is very expensive. Cache child entries here so that the next call don't reach here. return nil, syscall.ENOENT } ino, err := n.fs.inodeOfID(id) if err != nil { n.fs.s.report(fmt.Errorf("node.Lookup: %v", err)) return nil, syscall.EIO } return n.NewInode(ctx, &node{ id: id, fs: n.fs, attr: ce, }, entryToAttr(ino, ce, &out.Attr)), 0 } var _ = (fusefs.NodeOpener)((*node)(nil)) func (n *node) Open(ctx context.Context, flags uint32) (fh fusefs.FileHandle, fuseFlags uint32, errno syscall.Errno) { ra, err := n.fs.r.OpenFile(n.id) if err != nil { n.fs.s.report(fmt.Errorf("node.Open: %v", err)) return nil, 0, syscall.EIO } return &file{ n: n, ra: ra, }, fuse.FOPEN_KEEP_CACHE, 0 } var _ = (fusefs.NodeGetattrer)((*node)(nil)) func (n *node) Getattr(ctx context.Context, f fusefs.FileHandle, out *fuse.AttrOut) syscall.Errno { ino, err := n.fs.inodeOfID(n.id) if err != nil { n.fs.s.report(fmt.Errorf("node.Getattr: %v", err)) return syscall.EIO } entryToAttr(ino, n.attr, &out.Attr) return 0 } var _ = (fusefs.NodeGetxattrer)((*node)(nil)) func (n *node) Getxattr(ctx context.Context, attr string, dest []byte) (uint32, syscall.Errno) { ent := n.attr opq := n.isOpaque() for _, opaqueXattr := range n.fs.opaqueXattrs { if attr == opaqueXattr && opq { // This node is an opaque directory so give overlayfs-compliant indicator. if len(dest) < len(opaqueXattrValue) { return uint32(len(opaqueXattrValue)), syscall.ERANGE } return uint32(copy(dest, opaqueXattrValue)), 0 } } if v, ok := ent.Xattrs[attr]; ok { if len(dest) < len(v) { return uint32(len(v)), syscall.ERANGE } return uint32(copy(dest, v)), 0 } return 0, syscall.ENODATA } var _ = (fusefs.NodeListxattrer)((*node)(nil)) func (n *node) Listxattr(ctx context.Context, dest []byte) (uint32, syscall.Errno) { ent := n.attr opq := n.isOpaque() var attrs []byte if opq { // This node is an opaque directory so add overlayfs-compliant indicator. for _, opaqueXattr := range n.fs.opaqueXattrs { attrs = append(attrs, []byte(opaqueXattr+"\x00")...) } } for k := range ent.Xattrs { attrs = append(attrs, []byte(k+"\x00")...) } if len(dest) < len(attrs) { return uint32(len(attrs)), syscall.ERANGE } return uint32(copy(dest, attrs)), 0 } var _ = (fusefs.NodeReadlinker)((*node)(nil)) func (n *node) Readlink(ctx context.Context) ([]byte, syscall.Errno) { ent := n.attr return []byte(ent.LinkName), 0 } var _ = (fusefs.NodeStatfser)((*node)(nil)) func (n *node) Statfs(ctx context.Context, out *fuse.StatfsOut) syscall.Errno { defaultStatfs(out) return 0 } // file is a file abstraction which implements file handle in go-fuse. type file struct { n *node ra io.ReaderAt } var _ = (fusefs.FileReader)((*file)(nil)) func (f *file) Read(ctx context.Context, dest []byte, off int64) (fuse.ReadResult, syscall.Errno) { defer commonmetrics.MeasureLatencyInMicroseconds(commonmetrics.ReadOnDemand, f.n.fs.layerDigest, time.Now()) // measure time for on-demand file reads (in microseconds) defer commonmetrics.IncOperationCount(commonmetrics.OnDemandReadAccessCount, f.n.fs.layerDigest) // increment the counter for on-demand file accesses n, err := f.ra.ReadAt(dest, off) if err != nil && err != io.EOF { f.n.fs.s.report(fmt.Errorf("file.Read: %v", err)) return nil, syscall.EIO } return fuse.ReadResultData(dest[:n]), 0 } var _ = (fusefs.FileGetattrer)((*file)(nil)) func (f *file) Getattr(ctx context.Context, out *fuse.AttrOut) syscall.Errno { ino, err := f.n.fs.inodeOfID(f.n.id) if err != nil { f.n.fs.s.report(fmt.Errorf("file.Getattr: %v", err)) return syscall.EIO } entryToAttr(ino, f.n.attr, &out.Attr) return 0 } // whiteout is a whiteout abstraction compliant to overlayfs. type whiteout struct { fusefs.Inode id uint32 fs *fs attr metadata.Attr } var _ = (fusefs.NodeGetattrer)((*whiteout)(nil)) func (w *whiteout) Getattr(ctx context.Context, f fusefs.FileHandle, out *fuse.AttrOut) syscall.Errno { ino, err := w.fs.inodeOfID(w.id) if err != nil { w.fs.s.report(fmt.Errorf("whiteout.Getattr: %v", err)) return syscall.EIO } entryToWhAttr(ino, w.attr, &out.Attr) return 0 } var _ = (fusefs.NodeStatfser)((*whiteout)(nil)) func (w *whiteout) Statfs(ctx context.Context, out *fuse.StatfsOut) syscall.Errno { defaultStatfs(out) return 0 } // newState provides new state directory node. // It creates statFile at the same time to give it stable inode number. func (fs *fs) newState(layerDigest digest.Digest, blob remote.Blob) *state { return &state{ statFile: &statFile{ name: layerDigest.String() + ".json", statJSON: statJSON{ Digest: layerDigest.String(), Size: blob.Size(), }, blob: blob, fs: fs, }, fs: fs, } } // state is a directory which contain a "state file" of this layer aiming to // observability. This filesystem uses it to report something(e.g. error) to // the clients(e.g. Kubernetes's livenessProbe). // This directory has mode "dr-x------ root root". type state struct { fusefs.Inode statFile *statFile fs *fs } var _ = (fusefs.NodeReaddirer)((*state)(nil)) func (s *state) Readdir(ctx context.Context) (fusefs.DirStream, syscall.Errno) { return fusefs.NewListDirStream([]fuse.DirEntry{ { Mode: statFileMode, Name: s.statFile.name, Ino: s.fs.inodeOfStatFile(), }, }), 0 } var _ = (fusefs.NodeLookuper)((*state)(nil)) func (s *state) Lookup(ctx context.Context, name string, out *fuse.EntryOut) (*fusefs.Inode, syscall.Errno) { if name != s.statFile.name { return nil, syscall.ENOENT } attr, errno := s.statFile.attr(&out.Attr) if errno != 0 { return nil, errno } return s.NewInode(ctx, s.statFile, attr), 0 } var _ = (fusefs.NodeGetattrer)((*state)(nil)) func (s *state) Getattr(ctx context.Context, f fusefs.FileHandle, out *fuse.AttrOut) syscall.Errno { s.fs.stateToAttr(&out.Attr) return 0 } var _ = (fusefs.NodeStatfser)((*state)(nil)) func (s *state) Statfs(ctx context.Context, out *fuse.StatfsOut) syscall.Errno { defaultStatfs(out) return 0 } func (s *state) report(err error) { s.statFile.report(err) } type statJSON struct { Error string `json:"error,omitempty"` Digest string `json:"digest"` // URL is excluded for potential security reason Size int64 `json:"size"` FetchedSize int64 `json:"fetchedSize"` FetchedPercent float64 `json:"fetchedPercent"` // Fetched / Size * 100.0 } // statFile is a file which contain something to be reported from this layer. // This filesystem uses statFile.report() to report something(e.g. error) to // the clients(e.g. Kubernetes's livenessProbe). // This file has mode "-r-------- root root". type statFile struct { fusefs.Inode name string blob remote.Blob statJSON statJSON mu sync.Mutex fs *fs } var _ = (fusefs.NodeOpener)((*statFile)(nil)) func (sf *statFile) Open(ctx context.Context, flags uint32) (fh fusefs.FileHandle, fuseFlags uint32, errno syscall.Errno) { return nil, 0, 0 } var _ = (fusefs.NodeReader)((*statFile)(nil)) func (sf *statFile) Read(ctx context.Context, f fusefs.FileHandle, dest []byte, off int64) (fuse.ReadResult, syscall.Errno) { sf.mu.Lock() defer sf.mu.Unlock() st, err := sf.updateStatUnlocked() if err != nil { return nil, syscall.EIO } n, err := bytes.NewReader(st).ReadAt(dest, off) if err != nil && err != io.EOF { return nil, syscall.EIO } return fuse.ReadResultData(dest[:n]), 0 } var _ = (fusefs.NodeGetattrer)((*statFile)(nil)) func (sf *statFile) Getattr(ctx context.Context, f fusefs.FileHandle, out *fuse.AttrOut) syscall.Errno { _, errno := sf.attr(&out.Attr) return errno } var _ = (fusefs.NodeStatfser)((*statFile)(nil)) func (sf *statFile) Statfs(ctx context.Context, out *fuse.StatfsOut) syscall.Errno { defaultStatfs(out) return 0 } // logContents puts the contents of statFile in the log // to keep that information accessible for troubleshooting. // The entries naming is kept to be consistend with the field naming in statJSON. func (sf *statFile) logContents() { ctx := context.Background() log.G(ctx).WithFields(logrus.Fields{ "digest": sf.statJSON.Digest, "size": sf.statJSON.Size, "fetchedSize": sf.statJSON.FetchedSize, "fetchedPercent": sf.statJSON.FetchedPercent, }).WithError(errors.New(sf.statJSON.Error)).Error("statFile error") } func (sf *statFile) report(err error) { sf.mu.Lock() defer sf.mu.Unlock() sf.statJSON.Error = err.Error() sf.logContents() } func (sf *statFile) attr(out *fuse.Attr) (fusefs.StableAttr, syscall.Errno) { sf.mu.Lock() defer sf.mu.Unlock() st, err := sf.updateStatUnlocked() if err != nil { return fusefs.StableAttr{}, syscall.EIO } return sf.fs.statFileToAttr(uint64(len(st)), out), 0 } func (sf *statFile) updateStatUnlocked() ([]byte, error) { sf.statJSON.FetchedSize = sf.blob.FetchedSize() sf.statJSON.FetchedPercent = float64(sf.statJSON.FetchedSize) / float64(sf.statJSON.Size) * 100.0 j, err := json.Marshal(&sf.statJSON) if err != nil { return nil, err } j = append(j, []byte("\n")...) return j, nil } // entryToAttr converts metadata.Attr to go-fuse's Attr. func entryToAttr(ino uint64, e metadata.Attr, out *fuse.Attr) fusefs.StableAttr { out.Ino = ino out.Size = uint64(e.Size) if e.Mode&os.ModeSymlink != 0 { out.Size = uint64(len(e.LinkName)) } out.Blksize = blockSize out.Blocks = out.Size / uint64(out.Blksize) if out.Size%uint64(out.Blksize) > 0 { out.Blocks++ } mtime := e.ModTime out.SetTimes(nil, &mtime, nil) out.Mode = fileModeToSystemMode(e.Mode) out.Owner = fuse.Owner{Uid: uint32(e.UID), Gid: uint32(e.GID)} out.Rdev = uint32(unix.Mkdev(uint32(e.DevMajor), uint32(e.DevMinor))) out.Nlink = uint32(e.NumLink) if out.Nlink == 0 { out.Nlink = 1 // zero "NumLink" means one. } out.Padding = 0 // TODO return fusefs.StableAttr{ Mode: out.Mode, Ino: out.Ino, // NOTE: The inode number is unique throughout the lifetime of // this filesystem so we don't consider about generation at this // moment. } } // entryToWhAttr converts metadata.Attr to go-fuse's Attr of whiteouts. func entryToWhAttr(ino uint64, e metadata.Attr, out *fuse.Attr) fusefs.StableAttr { out.Ino = ino out.Size = 0 out.Blksize = blockSize out.Blocks = 0 mtime := e.ModTime out.SetTimes(nil, &mtime, nil) out.Mode = syscall.S_IFCHR out.Owner = fuse.Owner{Uid: 0, Gid: 0} out.Rdev = uint32(unix.Mkdev(0, 0)) out.Nlink = 1 out.Padding = 0 // TODO return fusefs.StableAttr{ Mode: out.Mode, Ino: out.Ino, // NOTE: The inode number is unique throughout the lifetime of // this filesystem so we don't consider about generation at this // moment. } } // stateToAttr converts state directory to go-fuse's Attr. func (fs *fs) stateToAttr(out *fuse.Attr) fusefs.StableAttr { out.Ino = fs.inodeOfState() out.Size = 0 out.Blksize = blockSize out.Blocks = 0 out.Nlink = 1 // root can read and open it (dr-x------ root root). out.Mode = stateDirMode out.Owner = fuse.Owner{Uid: 0, Gid: 0} // dummy out.Mtime = 0 out.Mtimensec = 0 out.Rdev = 0 out.Padding = 0 return fusefs.StableAttr{ Mode: out.Mode, Ino: out.Ino, // NOTE: The inode number is unique throughout the lifetime of // this filesystem so we don't consider about generation at this // moment. } } // statFileToAttr converts stat file to go-fuse's Attr. // func statFileToAttr(id uint64, sf *statFile, size uint64, out *fuse.Attr) fusefs.StableAttr { func (fs *fs) statFileToAttr(size uint64, out *fuse.Attr) fusefs.StableAttr { out.Ino = fs.inodeOfStatFile() out.Size = size out.Blksize = blockSize out.Blocks = out.Size / uint64(out.Blksize) out.Nlink = 1 // Root can read it ("-r-------- root root"). out.Mode = statFileMode out.Owner = fuse.Owner{Uid: 0, Gid: 0} // dummy out.Mtime = 0 out.Mtimensec = 0 out.Rdev = 0 out.Padding = 0 return fusefs.StableAttr{ Mode: out.Mode, Ino: out.Ino, // NOTE: The inode number is unique throughout the lifetime of // this filesystem so we don't consider about generation at this // moment. } } func fileModeToSystemMode(m os.FileMode) uint32 { // Permission bits res := uint32(m & os.ModePerm) // File type bits switch m & os.ModeType { case os.ModeDevice: res |= syscall.S_IFBLK case os.ModeDevice | os.ModeCharDevice: res |= syscall.S_IFCHR case os.ModeDir: res |= syscall.S_IFDIR case os.ModeNamedPipe: res |= syscall.S_IFIFO case os.ModeSymlink: res |= syscall.S_IFLNK case os.ModeSocket: res |= syscall.S_IFSOCK default: // regular file. res |= syscall.S_IFREG } // suid, sgid, sticky bits if m&os.ModeSetuid != 0 { res |= syscall.S_ISUID } if m&os.ModeSetgid != 0 { res |= syscall.S_ISGID } if m&os.ModeSticky != 0 { res |= syscall.S_ISVTX } return res } func defaultStatfs(stat *fuse.StatfsOut) { // http://man7.org/linux/man-pages/man2/statfs.2.html stat.Blocks = 0 // dummy stat.Bfree = 0 stat.Bavail = 0 stat.Files = 0 // dummy stat.Ffree = 0 stat.Bsize = blockSize stat.NameLen = 1<<32 - 1 stat.Frsize = blockSize stat.Padding = 0 stat.Spare = [6]uint32{} } stargz-snapshotter-0.14.3/fs/layer/testutil.go000066400000000000000000001074761440204344700214320ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /* Copyright 2019 The Go Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the NOTICE.md file. */ package layer import ( "bytes" "compress/gzip" "context" "crypto/sha256" "encoding/json" "fmt" "io" "math/rand" "net/http" "os" "path" "path/filepath" "strings" "syscall" "testing" "time" "github.com/containerd/containerd/reference" "github.com/containerd/stargz-snapshotter/cache" "github.com/containerd/stargz-snapshotter/estargz" "github.com/containerd/stargz-snapshotter/fs/reader" "github.com/containerd/stargz-snapshotter/fs/remote" "github.com/containerd/stargz-snapshotter/fs/source" "github.com/containerd/stargz-snapshotter/metadata" "github.com/containerd/stargz-snapshotter/task" tutil "github.com/containerd/stargz-snapshotter/util/testutil" fusefs "github.com/hanwen/go-fuse/v2/fs" "github.com/hanwen/go-fuse/v2/fuse" "github.com/klauspost/compress/zstd" digest "github.com/opencontainers/go-digest" ocispec "github.com/opencontainers/image-spec/specs-go/v1" "golang.org/x/sys/unix" ) const ( sampleChunkSize = 3 sampleData1 = "0123456789" sampleData2 = "abcdefghij" ) var srcCompressions = map[string]tutil.CompressionFactory{ "zstd-fastest": tutil.ZstdCompressionWithLevel(zstd.SpeedFastest), "gzip-bestspeed": tutil.GzipCompressionWithLevel(gzip.BestSpeed), "externaltoc-gzip-bestspeed": tutil.ExternalTOCGzipCompressionWithLevel(gzip.BestSpeed), } func TestSuiteLayer(t *testing.T, store metadata.Store) { testPrefetch(t, store) testNodeRead(t, store) testNodes(t, store) } var testStateLayerDigest = digest.FromString("dummy") func testPrefetch(t *testing.T, factory metadata.Store) { data64KB := string(tutil.RandomBytes(t, 64000)) defaultPrefetchSize := int64(10000) landmarkPosition := func(t *testing.T, l *layer) int64 { if l.r == nil { t.Fatalf("layer hasn't been verified yet") } if id, _, err := l.r.Metadata().GetChild(l.r.Metadata().RootID(), estargz.PrefetchLandmark); err == nil { offset, err := l.r.Metadata().GetOffset(id) if err != nil { t.Fatalf("failed to get offset of prefetch landmark") } return offset } return defaultPrefetchSize } tests := []struct { name string chunkSize int // default is "sampleChunkSize" minChunkSize int in []tutil.TarEntry wantNum int // number of chunks wanted in the cache wants []string // filenames to compare prefetchSize func(*testing.T, *layer) int64 prioritizedFiles []string }{ { name: "no_prefetch", in: []tutil.TarEntry{ tutil.File("foo.txt", sampleData1), }, wantNum: 0, prioritizedFiles: nil, }, { name: "prefetch", in: []tutil.TarEntry{ tutil.File("foo.txt", sampleData1), tutil.File("bar.txt", sampleData2), }, wantNum: chunkNum(sampleData1), wants: []string{"foo.txt"}, prefetchSize: landmarkPosition, prioritizedFiles: []string{"foo.txt"}, }, { name: "with_dir", in: []tutil.TarEntry{ tutil.Dir("foo/"), tutil.File("foo/bar.txt", sampleData1), tutil.Dir("buz/"), tutil.File("buz/buzbuz.txt", sampleData2), }, wantNum: chunkNum(sampleData1), wants: []string{"foo/bar.txt"}, prefetchSize: landmarkPosition, prioritizedFiles: []string{"foo/", "foo/bar.txt"}, }, { name: "several_files_in_chunk", minChunkSize: 8000, chunkSize: 1000000000, // do not chunk in: []tutil.TarEntry{ tutil.Dir("foo/"), tutil.File("foo/foo1", data64KB), tutil.File("foo2", "bb"), tutil.File("foo22", "ccc"), tutil.Dir("bar/"), tutil.File("bar/bar.txt", "aaa"), tutil.File("foo3", data64KB), }, // NOTE: we assume that the compressed "data64KB" is still larger than 8KB // landmark+dir+foo1, foo2+foo22+dir+bar.txt+foo3, TOC, footer wantNum: 5, // foo1 + foo2 + foo22 + bar.txt + foo3 wants: []string{"foo/foo1", "foo2", "foo22", "bar/bar.txt", "foo3"}, prefetchSize: landmarkPosition, prioritizedFiles: []string{"foo/", "foo/foo1", "foo2", "foo22", "bar/", "bar/bar.txt", "foo3"}, }, { name: "several_files_in_chunk_chunked", minChunkSize: 8000, chunkSize: 32000, in: []tutil.TarEntry{ tutil.Dir("foo/"), tutil.File("foo/foo1", data64KB), tutil.File("foo2", "bb"), tutil.Dir("bar/"), tutil.File("foo3", data64KB), }, // NOTE: we assume that the compressed chunk of "data64KB" is still larger than 8KB // landmark+dir+foo1(1), foo1(2), foo2, dir+foo3(1), foo3(2), TOC, footer wantNum: 3, // foo1(2) + foo2 (foo3(1) shouldn't be in a separated stream) wants: []string{"foo/foo1", "foo2"}, prefetchSize: landmarkPosition, prioritizedFiles: []string{"foo/", "foo/foo1", "foo2"}, }, } for _, tt := range tests { for srcCompressionName, srcCompression := range srcCompressions { cl := srcCompression() t.Run("testPrefetch-"+tt.name+"-"+srcCompressionName, func(t *testing.T) { chunkSize := sampleChunkSize if tt.chunkSize > 0 { chunkSize = tt.chunkSize } minChunkSize := 0 if tt.minChunkSize > 0 { minChunkSize = tt.minChunkSize } sr, dgst, err := tutil.BuildEStargz(tt.in, tutil.WithEStargzOptions( estargz.WithChunkSize(chunkSize), estargz.WithMinChunkSize(minChunkSize), estargz.WithPrioritizedFiles(tt.prioritizedFiles), estargz.WithCompression(cl), )) if err != nil { t.Fatalf("failed to build eStargz: %v", err) } blob := newBlob(t, sr) mcache := cache.NewMemoryCache() mr, err := factory(sr, metadata.WithDecompressors(cl)) if err != nil { t.Fatalf("failed to create metadata reader: %v", err) } defer mr.Close() vr, err := reader.NewReader(mr, mcache, digest.FromString("")) if err != nil { t.Fatalf("failed to create reader: %v", err) } l := newLayer( &Resolver{ prefetchTimeout: time.Second, backgroundTaskManager: task.NewBackgroundTaskManager(10, 5*time.Second), }, ocispec.Descriptor{Digest: testStateLayerDigest}, &blobRef{blob, func() {}}, vr, ) if err := l.Verify(dgst); err != nil { t.Errorf("failed to verify reader: %v", err) return } prefetchSize := int64(0) if tt.prefetchSize != nil { prefetchSize = tt.prefetchSize(t, l) } if err := l.Prefetch(defaultPrefetchSize); err != nil { t.Errorf("failed to prefetch: %v", err) return } if blob.calledPrefetchOffset != 0 { t.Errorf("invalid prefetch offset %d; want %d", blob.calledPrefetchOffset, 0) } if blob.calledPrefetchSize != prefetchSize { t.Errorf("invalid prefetch size %d; want %d", blob.calledPrefetchSize, prefetchSize) } if cLen := len(mcache.(*cache.MemoryCache).Membuf); tt.wantNum != cLen { t.Errorf("number of chunks in the cache %d; want %d: %v", cLen, tt.wantNum, err) return } lr := l.r if lr == nil { t.Fatalf("failed to get reader from layer: %v", err) } for _, file := range tt.wants { id, err := lookup(lr.Metadata(), file) if err != nil { t.Fatalf("failed to lookup %q: %v", file, err) } e, err := lr.Metadata().GetAttr(id) if err != nil { t.Fatalf("failed to get attr of %q: %v", file, err) } wantFile, err := lr.OpenFile(id) if err != nil { t.Fatalf("failed to open file %q", file) } blob.readCalled = false if _, err := io.Copy(io.Discard, io.NewSectionReader(wantFile, 0, e.Size)); err != nil { t.Fatalf("failed to read file %q", file) } if blob.readCalled { t.Errorf("chunks of file %q aren't cached", file) return } } }) } } } func lookup(r metadata.Reader, name string) (uint32, error) { name = strings.TrimPrefix(path.Clean("/"+name), "/") if name == "" { return r.RootID(), nil } dir, base := filepath.Split(name) pid, err := lookup(r, dir) if err != nil { return 0, err } id, _, err := r.GetChild(pid, base) return id, err } func chunkNum(data string) int { return (len(data)-1)/sampleChunkSize + 1 } type region struct { begin int64 end int64 // inclusive } func isDup(a, b region) bool { if a.begin < b.begin { return a.end >= b.begin } // b.begin <= a.begin return b.end >= a.begin } func newBlob(t *testing.T, sr *io.SectionReader) *sampleBlob { return &sampleBlob{ t: t, r: sr, } } type sampleBlob struct { t *testing.T r *io.SectionReader readCalled bool calledPrefetchOffset int64 calledPrefetchSize int64 calledRegions []region // sorted } func (sb *sampleBlob) Authn(tr http.RoundTripper) (http.RoundTripper, error) { return nil, nil } func (sb *sampleBlob) Check() error { return nil } func (sb *sampleBlob) Size() int64 { return sb.r.Size() } func (sb *sampleBlob) FetchedSize() int64 { return 0 } func (sb *sampleBlob) ReadAt(p []byte, offset int64, opts ...remote.Option) (int, error) { if len(p) > 0 { target := region{offset, offset + int64(len(p)) - 1} if len(sb.calledRegions) == 0 { sb.calledRegions = []region{target} } else { pos := 0 found := false for i, r := range sb.calledRegions { if target.begin < r.begin { pos = i found = true break } } if !found { pos = len(sb.calledRegions) } if pos > 0 { b := sb.calledRegions[pos-1] if isDup(b, target) { sb.t.Fatalf("reading on the previous region is duplicated: %+v and %+v", b, target) } } if pos+1 < len(sb.calledRegions) { a := sb.calledRegions[pos+1] if isDup(a, target) { sb.t.Fatalf("reading on the next region is duplicated: %+v and %+v", a, target) } } sb.calledRegions = append(sb.calledRegions[:pos], append([]region{target}, sb.calledRegions[pos:]...)...) } } sb.readCalled = true return sb.r.ReadAt(p, offset) } func (sb *sampleBlob) Cache(offset int64, size int64, option ...remote.Option) error { sb.calledPrefetchOffset = offset sb.calledPrefetchSize = size return nil } func (sb *sampleBlob) Refresh(ctx context.Context, hosts source.RegistryHosts, refspec reference.Spec, desc ocispec.Descriptor) error { return nil } func (sb *sampleBlob) Close() error { return nil } const ( sampleMiddleOffset = sampleChunkSize / 2 lastChunkOffset1 = sampleChunkSize * (int64(len(sampleData1)) / sampleChunkSize) ) func testNodeRead(t *testing.T, factory metadata.Store) { sizeCond := map[string]int64{ "single_chunk": sampleChunkSize - sampleMiddleOffset, "multi_chunks": sampleChunkSize + sampleMiddleOffset, } innerOffsetCond := map[string]int64{ "at_top": 0, "at_middle": sampleMiddleOffset, } baseOffsetCond := map[string]int64{ "of_1st_chunk": sampleChunkSize * 0, "of_2nd_chunk": sampleChunkSize * 1, "of_last_chunk": lastChunkOffset1, } fileSizeCond := map[string]int64{ "in_1_chunk_file": sampleChunkSize * 1, "in_2_chunks_file": sampleChunkSize * 2, "in_max_size_file": int64(len(sampleData1)), } for sn, size := range sizeCond { for in, innero := range innerOffsetCond { for bo, baseo := range baseOffsetCond { for fn, filesize := range fileSizeCond { for _, srcCompression := range srcCompressions { cl := srcCompression() t.Run(fmt.Sprintf("reading_%s_%s_%s_%s", sn, in, bo, fn), func(t *testing.T) { if filesize > int64(len(sampleData1)) { t.Fatal("sample file size is larger than sample data") } wantN := size offset := baseo + innero if remain := filesize - offset; remain < wantN { if wantN = remain; wantN < 0 { wantN = 0 } } // use constant string value as a data source. want := strings.NewReader(sampleData1) // data we want to get. wantData := make([]byte, wantN) _, err := want.ReadAt(wantData, offset) if err != nil && err != io.EOF { t.Fatalf("want.ReadAt (offset=%d,size=%d): %v", offset, wantN, err) } // data we get from the file node. f, closeFn := makeNodeReader(t, []byte(sampleData1)[:filesize], sampleChunkSize, factory, cl) defer closeFn() tmpbuf := make([]byte, size) // fuse library can request bigger than remain rr, errno := f.Read(context.Background(), tmpbuf, offset) if errno != 0 { t.Errorf("failed to read off=%d, size=%d, filesize=%d: %v", offset, size, filesize, err) return } if rsize := rr.Size(); int64(rsize) != wantN { t.Errorf("read size: %d; want: %d; passed %d", rsize, wantN, size) return } tmpbuf = make([]byte, len(tmpbuf)) respData, fs := rr.Bytes(tmpbuf) if fs != fuse.OK { t.Errorf("failed to read result data for off=%d, size=%d, filesize=%d: %v", offset, size, filesize, err) } if !bytes.Equal(wantData, respData) { t.Errorf("off=%d, filesize=%d; read data{size=%d,data=%q}; want (size=%d,data=%q)", offset, filesize, len(respData), string(respData), wantN, string(wantData)) return } }) } } } } } } func makeNodeReader(t *testing.T, contents []byte, chunkSize int, factory metadata.Store, cl tutil.Compression) (_ *file, closeFn func() error) { testName := "test" sr, tocDgst, err := tutil.BuildEStargz( []tutil.TarEntry{tutil.File(testName, string(contents))}, tutil.WithEStargzOptions(estargz.WithChunkSize(chunkSize), estargz.WithCompression(cl)), ) if err != nil { t.Fatalf("failed to build sample eStargz: %v", err) } r, err := factory(sr, metadata.WithDecompressors(cl)) if err != nil { t.Fatalf("failed to create reader: %v", err) } rootNode := getRootNode(t, r, OverlayOpaqueAll, tocDgst, cache.NewMemoryCache()) var eo fuse.EntryOut inode, errno := rootNode.Lookup(context.Background(), testName, &eo) if errno != 0 { r.Close() t.Fatalf("failed to lookup test node; errno: %v", errno) } f, _, errno := inode.Operations().(fusefs.NodeOpener).Open(context.Background(), 0) if errno != 0 { r.Close() t.Fatalf("failed to open test file; errno: %v", errno) } return f.(*file), r.Close } func testNodes(t *testing.T, factory metadata.Store) { for _, o := range []OverlayOpaqueType{OverlayOpaqueAll, OverlayOpaqueTrusted, OverlayOpaqueUser} { testNodesWithOpaque(t, factory, o) } } func testNodesWithOpaque(t *testing.T, factory metadata.Store, opaque OverlayOpaqueType) { data64KB := string(tutil.RandomBytes(t, 64000)) hasOpaque := func(entry string) check { return func(t *testing.T, root *node, cc cache.BlobCache, cr *calledReaderAt) { for _, k := range opaqueXattrs[opaque] { hasNodeXattrs(entry, k, opaqueXattrValue)(t, root, cc, cr) } } } tests := []struct { name string chunkSize int minChunkSize int in []tutil.TarEntry want []check }{ { name: "1_whiteout_with_sibling", in: []tutil.TarEntry{ tutil.Dir("foo/"), tutil.File("foo/bar.txt", ""), tutil.File("foo/.wh.foo.txt", ""), }, want: []check{ hasValidWhiteout("foo/foo.txt"), fileNotExist("foo/.wh.foo.txt"), }, }, { name: "1_whiteout_with_duplicated_name", in: []tutil.TarEntry{ tutil.Dir("foo/"), tutil.File("foo/bar.txt", "test"), tutil.File("foo/.wh.bar.txt", ""), }, want: []check{ hasFileDigest("foo/bar.txt", digestFor("test")), fileNotExist("foo/.wh.bar.txt"), }, }, { name: "1_opaque", in: []tutil.TarEntry{ tutil.Dir("foo/"), tutil.File("foo/.wh..wh..opq", ""), }, want: []check{ hasOpaque("foo/"), fileNotExist("foo/.wh..wh..opq"), }, }, { name: "1_opaque_with_sibling", in: []tutil.TarEntry{ tutil.Dir("foo/"), tutil.File("foo/.wh..wh..opq", ""), tutil.File("foo/bar.txt", "test"), }, want: []check{ hasOpaque("foo/"), hasFileDigest("foo/bar.txt", digestFor("test")), fileNotExist("foo/.wh..wh..opq"), }, }, { name: "1_opaque_with_xattr", in: []tutil.TarEntry{ tutil.Dir("foo/", tutil.WithDirXattrs(map[string]string{"foo": "bar"})), tutil.File("foo/.wh..wh..opq", ""), }, want: []check{ hasOpaque("foo/"), hasNodeXattrs("foo/", "foo", "bar"), fileNotExist("foo/.wh..wh..opq"), }, }, { name: "prefetch_landmark", in: []tutil.TarEntry{ tutil.File(estargz.PrefetchLandmark, "test"), tutil.Dir("foo/"), tutil.File(fmt.Sprintf("foo/%s", estargz.PrefetchLandmark), "test"), }, want: []check{ fileNotExist(estargz.PrefetchLandmark), hasFileDigest(fmt.Sprintf("foo/%s", estargz.PrefetchLandmark), digestFor("test")), }, }, { name: "no_prefetch_landmark", in: []tutil.TarEntry{ tutil.File(estargz.NoPrefetchLandmark, "test"), tutil.Dir("foo/"), tutil.File(fmt.Sprintf("foo/%s", estargz.NoPrefetchLandmark), "test"), }, want: []check{ fileNotExist(estargz.NoPrefetchLandmark), hasFileDigest(fmt.Sprintf("foo/%s", estargz.NoPrefetchLandmark), digestFor("test")), }, }, { name: "state_file", in: []tutil.TarEntry{ tutil.File("test", "test"), }, want: []check{ hasFileDigest("test", digestFor("test")), hasStateFile(t, testStateLayerDigest.String()+".json"), }, }, { name: "file_suid", in: []tutil.TarEntry{ tutil.File("test", "test", tutil.WithFileMode(0644|os.ModeSetuid)), }, want: []check{ hasExtraMode("test", os.ModeSetuid), }, }, { name: "dir_sgid", in: []tutil.TarEntry{ tutil.Dir("test/", tutil.WithDirMode(0755|os.ModeSetgid)), }, want: []check{ hasExtraMode("test/", os.ModeSetgid), }, }, { name: "file_sticky", in: []tutil.TarEntry{ tutil.File("test", "test", tutil.WithFileMode(0644|os.ModeSticky)), }, want: []check{ hasExtraMode("test", os.ModeSticky), }, }, { name: "symlink_size", in: []tutil.TarEntry{ tutil.Symlink("test", "target"), }, want: []check{ hasSize("test", len("target")), }, }, { name: "several_files_in_chunk", minChunkSize: 8000, in: []tutil.TarEntry{ tutil.Dir("foo/"), tutil.File("foo/foo1", data64KB), tutil.File("foo2", "bb"), tutil.File("foo22", "ccc"), tutil.Dir("bar/"), tutil.File("bar/bar.txt", "aaa"), tutil.File("foo3", data64KB), }, // NOTE: we assume that the compressed "data64KB" is still larger than 8KB // landmark+dir+foo1, foo2+foo22+dir+bar.txt+foo3, TOC, footer want: []check{ hasFileContentsWithPreCached("foo22", 0, "ccc", chunkInfo{"foo2", "bb", 0, 2}, chunkInfo{"bar/bar.txt", "aaa", 0, 3}, chunkInfo{"foo3", data64KB, 0, 64000}), hasFileContentsOffset("foo2", 0, "bb", true), hasFileContentsOffset("bar/bar.txt", 0, "aaa", true), hasFileContentsOffset("bar/bar.txt", 1, "aa", true), hasFileContentsOffset("bar/bar.txt", 2, "a", true), hasFileContentsOffset("foo3", 0, data64KB, true), hasFileContentsOffset("foo22", 0, "ccc", true), hasFileContentsOffset("foo/foo1", 0, data64KB, false), hasFileContentsOffset("foo/foo1", 0, data64KB, true), hasFileContentsOffset("foo/foo1", 1, data64KB[1:], true), hasFileContentsOffset("foo/foo1", 2, data64KB[2:], true), hasFileContentsOffset("foo/foo1", 3, data64KB[3:], true), }, }, { name: "several_files_in_chunk_chunked", minChunkSize: 8000, chunkSize: 32000, in: []tutil.TarEntry{ tutil.Dir("foo/"), tutil.File("foo/foo1", data64KB), tutil.File("foo2", "bb"), tutil.Dir("bar/"), tutil.File("foo3", data64KB), }, // NOTE: we assume that the compressed chunk of "data64KB" is still larger than 8KB // landmark+dir+foo1(1), foo1(2), foo2+dir+foo3(1), foo3(2), TOC, footer want: []check{ hasFileContentsWithPreCached("foo2", 0, "bb", chunkInfo{"foo3", data64KB[:32000], 0, 32000}), hasFileContentsOffset("foo2", 0, "bb", true), hasFileContentsOffset("foo2", 1, "b", true), hasFileContentsOffset("foo3", 0, data64KB[:len(data64KB)/2], true), hasFileContentsOffset("foo3", 1, data64KB[1:len(data64KB)/2], true), hasFileContentsOffset("foo3", 2, data64KB[2:len(data64KB)/2], true), hasFileContentsOffset("foo3", int64(len(data64KB)/2), data64KB[len(data64KB)/2:], false), hasFileContentsOffset("foo3", int64(len(data64KB)-1), data64KB[len(data64KB)-1:], true), hasFileContentsOffset("foo/foo1", 0, data64KB, false), hasFileContentsOffset("foo/foo1", 1, data64KB[1:], true), hasFileContentsOffset("foo/foo1", 2, data64KB[2:], true), hasFileContentsOffset("foo/foo1", int64(len(data64KB)/2), data64KB[len(data64KB)/2:], true), hasFileContentsOffset("foo/foo1", int64(len(data64KB)-1), data64KB[len(data64KB)-1:], true), }, }, } for _, tt := range tests { for _, srcCompression := range srcCompressions { cl := srcCompression() t.Run(tt.name, func(t *testing.T) { opts := []tutil.BuildEStargzOption{ tutil.WithEStargzOptions(estargz.WithCompression(cl)), } if tt.chunkSize > 0 { opts = append(opts, tutil.WithEStargzOptions(estargz.WithChunkSize(tt.chunkSize))) } if tt.minChunkSize > 0 { opts = append(opts, tutil.WithEStargzOptions(estargz.WithMinChunkSize(tt.minChunkSize))) } sgz, tocDgst, err := tutil.BuildEStargz(tt.in, opts...) if err != nil { t.Fatalf("failed to build sample eStargz: %v", err) } testR := &calledReaderAt{sgz, nil} r, err := factory(io.NewSectionReader(testR, 0, sgz.Size()), metadata.WithDecompressors(cl)) if err != nil { t.Fatalf("failed to create reader: %v", err) } defer r.Close() mcache := cache.NewMemoryCache() rootNode := getRootNode(t, r, opaque, tocDgst, mcache) for _, want := range tt.want { want(t, rootNode, mcache, testR) } }) } } } func getRootNode(t *testing.T, r metadata.Reader, opaque OverlayOpaqueType, tocDgst digest.Digest, cc cache.BlobCache) *node { vr, err := reader.NewReader(r, cc, digest.FromString("")) if err != nil { t.Fatalf("failed to create reader: %v", err) } rr, err := vr.VerifyTOC(tocDgst) if err != nil { t.Fatalf("failed to verify reader: %v", err) } rootNode, err := newNode(testStateLayerDigest, rr, &testBlobState{10, 5}, 100, opaque) if err != nil { t.Fatalf("failed to get root node: %v", err) } fusefs.NewNodeFS(rootNode, &fusefs.Options{}) // initializes root node return rootNode.(*node) } type testBlobState struct { size int64 fetchedSize int64 } func (tb *testBlobState) Check() error { return nil } func (tb *testBlobState) Size() int64 { return tb.size } func (tb *testBlobState) FetchedSize() int64 { return tb.fetchedSize } func (tb *testBlobState) ReadAt(p []byte, offset int64, opts ...remote.Option) (int, error) { return 0, nil } func (tb *testBlobState) Cache(offset int64, size int64, opts ...remote.Option) error { return nil } func (tb *testBlobState) Refresh(ctx context.Context, host source.RegistryHosts, refspec reference.Spec, desc ocispec.Descriptor) error { return nil } func (tb *testBlobState) Close() error { return nil } type check func(*testing.T, *node, cache.BlobCache, *calledReaderAt) func fileNotExist(file string) check { return func(t *testing.T, root *node, cc cache.BlobCache, cr *calledReaderAt) { if _, _, err := getDirentAndNode(t, root, file); err == nil { t.Errorf("Node %q exists", file) } } } func hasFileDigest(filename string, digest string) check { return func(t *testing.T, root *node, cc cache.BlobCache, cr *calledReaderAt) { _, n, err := getDirentAndNode(t, root, filename) if err != nil { t.Fatalf("failed to get node %q: %v", filename, err) } ni := n.Operations().(*node) attr, err := ni.fs.r.Metadata().GetAttr(ni.id) if err != nil { t.Fatalf("failed to get attr %q(%d): %v", filename, ni.id, err) } fh, _, errno := ni.Open(context.Background(), 0) if errno != 0 { t.Fatalf("failed to open node %q: %v", filename, errno) } rr, errno := fh.(*file).Read(context.Background(), make([]byte, attr.Size), 0) if errno != 0 { t.Fatalf("failed to read node %q: %v", filename, errno) } res, status := rr.Bytes(make([]byte, attr.Size)) if status != fuse.OK { t.Fatalf("failed to get read result of node %q: %v", filename, status) } if ndgst := digestFor(string(res)); ndgst != digest { t.Fatalf("Digest(%q) = %q, want %q", filename, ndgst, digest) } } } func hasSize(name string, size int) check { return func(t *testing.T, root *node, cc cache.BlobCache, cr *calledReaderAt) { _, n, err := getDirentAndNode(t, root, name) if err != nil { t.Fatalf("failed to get node %q: %v", name, err) } var ao fuse.AttrOut if errno := n.Operations().(fusefs.NodeGetattrer).Getattr(context.Background(), nil, &ao); errno != 0 { t.Fatalf("failed to get attributes of node %q: %v", name, errno) } if ao.Attr.Size != uint64(size) { t.Fatalf("got size = %d, want %d", ao.Attr.Size, size) } } } func hasExtraMode(name string, mode os.FileMode) check { return func(t *testing.T, root *node, cc cache.BlobCache, cr *calledReaderAt) { _, n, err := getDirentAndNode(t, root, name) if err != nil { t.Fatalf("failed to get node %q: %v", name, err) } var ao fuse.AttrOut if errno := n.Operations().(fusefs.NodeGetattrer).Getattr(context.Background(), nil, &ao); errno != 0 { t.Fatalf("failed to get attributes of node %q: %v", name, errno) } a := ao.Attr gotMode := a.Mode & (syscall.S_ISUID | syscall.S_ISGID | syscall.S_ISVTX) wantMode := extraModeToTarMode(mode) if gotMode != uint32(wantMode) { t.Fatalf("got mode = %b, want %b", gotMode, wantMode) } } } func hasValidWhiteout(name string) check { return func(t *testing.T, root *node, cc cache.BlobCache, cr *calledReaderAt) { ent, n, err := getDirentAndNode(t, root, name) if err != nil { t.Fatalf("failed to get node %q: %v", name, err) } var ao fuse.AttrOut if errno := n.Operations().(fusefs.NodeGetattrer).Getattr(context.Background(), nil, &ao); errno != 0 { t.Fatalf("failed to get attributes of file %q: %v", name, errno) } a := ao.Attr if a.Ino != ent.Ino { t.Errorf("inconsistent inodes %d(Node) != %d(Dirent)", a.Ino, ent.Ino) return } // validate the direntry if ent.Mode != syscall.S_IFCHR { t.Errorf("whiteout entry %q isn't a char device", name) return } // validate the node if a.Mode != syscall.S_IFCHR { t.Errorf("whiteout %q has an invalid mode %o; want %o", name, a.Mode, syscall.S_IFCHR) return } if a.Rdev != uint32(unix.Mkdev(0, 0)) { t.Errorf("whiteout %q has invalid device numbers (%d, %d); want (0, 0)", name, unix.Major(uint64(a.Rdev)), unix.Minor(uint64(a.Rdev))) return } } } func hasNodeXattrs(entry, name, value string) check { return func(t *testing.T, root *node, cc cache.BlobCache, cr *calledReaderAt) { _, n, err := getDirentAndNode(t, root, entry) if err != nil { t.Fatalf("failed to get node %q: %v", entry, err) } // check xattr exists in the xattrs list. buf := make([]byte, 1000) nb, errno := n.Operations().(fusefs.NodeListxattrer).Listxattr(context.Background(), buf) if errno != 0 { t.Fatalf("failed to get xattrs list of node %q: %v", entry, err) } attrs := strings.Split(string(buf[:nb]), "\x00") var found bool for _, x := range attrs { if x == name { found = true } } if !found { t.Errorf("node %q doesn't have an opaque xattr %q", entry, value) return } // check the xattr has valid value. v := make([]byte, len(value)) nv, errno := n.Operations().(fusefs.NodeGetxattrer).Getxattr(context.Background(), name, v) if errno != 0 { t.Fatalf("failed to get xattr %q of node %q: %v", name, entry, err) } if int(nv) != len(value) { t.Fatalf("invalid xattr size for file %q, value %q got %d; want %d", name, value, nv, len(value)) } if string(v) != value { t.Errorf("node %q has an invalid xattr %q; want %q", entry, v, value) return } } } func hasEntry(t *testing.T, name string, ents fusefs.DirStream) (fuse.DirEntry, bool) { for ents.HasNext() { de, errno := ents.Next() if errno != 0 { t.Fatalf("faield to read entries for %q", name) } if de.Name == name { return de, true } } return fuse.DirEntry{}, false } func hasStateFile(t *testing.T, id string) check { return func(t *testing.T, root *node, cc cache.BlobCache, cr *calledReaderAt) { // Check the state dir is hidden on OpenDir for "/" ents, errno := root.Readdir(context.Background()) if errno != 0 { t.Errorf("failed to open root directory: %v", errno) return } if _, ok := hasEntry(t, stateDirName, ents); ok { t.Errorf("state direntry %q should not be listed", stateDirName) return } // Check existence of state dir var eo fuse.EntryOut sti, errno := root.Lookup(context.Background(), stateDirName, &eo) if errno != 0 { t.Errorf("failed to lookup directory %q: %v", stateDirName, errno) return } st, ok := sti.Operations().(*state) if !ok { t.Errorf("directory %q isn't a state node", stateDirName) return } // Check existence of state file ents, errno = st.Readdir(context.Background()) if errno != 0 { t.Errorf("failed to open directory %q: %v", stateDirName, errno) return } if _, ok := hasEntry(t, id, ents); !ok { t.Errorf("direntry %q not found in %q", id, stateDirName) return } inode, errno := st.Lookup(context.Background(), id, &eo) if errno != 0 { t.Errorf("failed to lookup node %q in %q: %v", id, stateDirName, errno) return } n, ok := inode.Operations().(*statFile) if !ok { t.Errorf("entry %q isn't a normal node", id) return } // wanted data rand.Seed(time.Now().UnixNano()) wantErr := fmt.Errorf("test-%d", rand.Int63()) // report the data root.fs.s.report(wantErr) // obtain file size (check later) var ao fuse.AttrOut errno = n.Operations().(fusefs.NodeGetattrer).Getattr(context.Background(), nil, &ao) if errno != 0 { t.Errorf("failed to get attr of state file: %v", errno) return } attr := ao.Attr // get data via state file tmp := make([]byte, 4096) res, errno := n.Read(context.Background(), nil, tmp, 0) if errno != 0 { t.Errorf("failed to read state file: %v", errno) return } gotState, status := res.Bytes(nil) if status != fuse.OK { t.Errorf("failed to get result bytes of state file: %v", errno) return } if attr.Size != uint64(len(string(gotState))) { t.Errorf("size %d; want %d", attr.Size, len(string(gotState))) return } var j statJSON if err := json.Unmarshal(gotState, &j); err != nil { t.Errorf("failed to unmarshal %q: %v", string(gotState), err) return } if wantErr.Error() != j.Error { t.Errorf("expected error %q, got %q", wantErr.Error(), j.Error) return } } } // getDirentAndNode gets dirent and node at the specified path at once and makes // sure that the both of them exist. func getDirentAndNode(t *testing.T, root *node, path string) (ent fuse.DirEntry, n *fusefs.Inode, err error) { dir, base := filepath.Split(filepath.Clean(path)) // get the target's parent directory. var eo fuse.EntryOut d := root for _, name := range strings.Split(dir, "/") { if len(name) == 0 { continue } di, errno := d.Lookup(context.Background(), name, &eo) if errno != 0 { err = fmt.Errorf("failed to lookup directory %q: %v", name, errno) return } var ok bool if d, ok = di.Operations().(*node); !ok { err = fmt.Errorf("directory %q isn't a normal node", name) return } } // get the target's direntry. ents, errno := d.Readdir(context.Background()) if errno != 0 { err = fmt.Errorf("failed to open directory %q: %v", path, errno) } ent, ok := hasEntry(t, base, ents) if !ok { err = fmt.Errorf("direntry %q not found in the parent directory of %q", base, path) } // get the target's node. n, errno = d.Lookup(context.Background(), base, &eo) if errno != 0 { err = fmt.Errorf("failed to lookup node %q: %v", path, errno) } return } func digestFor(content string) string { sum := sha256.Sum256([]byte(content)) return fmt.Sprintf("sha256:%x", sum) } // suid, guid, sticky bits for archive/tar // https://github.com/golang/go/blob/release-branch.go1.13/src/archive/tar/common.go#L607-L609 const ( cISUID = 04000 // Set uid cISGID = 02000 // Set gid cISVTX = 01000 // Save text (sticky bit) ) func extraModeToTarMode(fm os.FileMode) (tm int64) { if fm&os.ModeSetuid != 0 { tm |= cISUID } if fm&os.ModeSetgid != 0 { tm |= cISGID } if fm&os.ModeSticky != 0 { tm |= cISVTX } return } type chunkInfo struct { name string data string chunkOffset int64 chunkSize int64 } func hasFileContentsWithPreCached(name string, off int64, contents string, extra ...chunkInfo) check { return func(t *testing.T, root *node, cc cache.BlobCache, cr *calledReaderAt) { buf := readFile(t, root, name, int64(len(contents)), off) if len(buf) != len(contents) { t.Fatalf("failed to read contents %q (off:%d, want:%q) got %q", name, off, longBytesView([]byte(contents)), longBytesView(buf)) } if string(buf) != contents { t.Fatalf("unexpected content of %q: %q want %q", name, longBytesView(buf), longBytesView([]byte(contents))) } for _, e := range extra { cr.called = nil // reset test data := readFile(t, root, e.name, e.chunkSize, e.chunkOffset) if string(data) != e.data { t.Fatalf("unexpected contents of %q (%+v): %q; wanted %q", e.name, e, longBytesView(data), longBytesView([]byte(e.data))) } if len(cr.called) != 0 { t.Fatalf("unexpected read on %q: offsets: %v", e.name, cr.called) } } } } func hasFileContentsOffset(name string, off int64, contents string, fromCache bool) check { return func(t *testing.T, root *node, cc cache.BlobCache, cr *calledReaderAt) { cr.called = nil // reset test buf := readFile(t, root, name, int64(len(contents)), off) if len(buf) != len(contents) { t.Fatalf("failed to read contents %q (off:%d, want:%q) got %q", name, off, longBytesView([]byte(contents)), longBytesView(buf)) } if string(buf) != contents { t.Fatalf("unexpected content of %q: %q want %q", name, longBytesView(buf), longBytesView([]byte(contents))) } t.Logf("reader calls for %q: offsets: %+v", name, cr.called) if fromCache { if len(cr.called) != 0 { t.Fatalf("unexpected read on %q: offsets: %v", name, cr.called) } } else { if len(cr.called) == 0 { t.Fatalf("no call happened to reader for %q", name) } } } } func readFile(t *testing.T, root *node, filename string, size, off int64) []byte { _, n, err := getDirentAndNode(t, root, filename) if err != nil { t.Fatalf("failed to get node %q: %v", filename, err) } ni := n.Operations().(*node) fh, _, errno := ni.Open(context.Background(), 0) if errno != 0 { t.Fatalf("failed to open node %q: %v", filename, errno) } rr, errno := fh.(*file).Read(context.Background(), make([]byte, size), off) if errno != 0 { t.Fatalf("failed to read node %q: %v", filename, errno) } buf, status := rr.Bytes(make([]byte, size)) if status != fuse.OK { t.Fatalf("failed to get read result of node %q: %v", filename, status) } return buf } type calledReaderAt struct { io.ReaderAt called []int64 } func (r *calledReaderAt) ReadAt(p []byte, off int64) (int, error) { r.called = append(r.called, off) return r.ReaderAt.ReadAt(p, off) } // longBytesView is an alias of []byte suitable for printing a long data as an omitted string to avoid long data being printed. type longBytesView []byte func (b longBytesView) String() string { if len(b) < 100 { return string(b) } return string(b[:50]) + "...(omit)..." + string(b[len(b)-50:]) } stargz-snapshotter-0.14.3/fs/metrics/000077500000000000000000000000001440204344700175415ustar00rootroot00000000000000stargz-snapshotter-0.14.3/fs/metrics/common/000077500000000000000000000000001440204344700210315ustar00rootroot00000000000000stargz-snapshotter-0.14.3/fs/metrics/common/metrics.go000066400000000000000000000236411440204344700230340ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package commonmetrics import ( "context" "sync" "time" "github.com/containerd/containerd/log" digest "github.com/opencontainers/go-digest" "github.com/prometheus/client_golang/prometheus" "github.com/sirupsen/logrus" ) const ( // OperationLatencyKeyMilliseconds is the key for stargz operation latency metrics in milliseconds. OperationLatencyKeyMilliseconds = "operation_duration_milliseconds" // OperationLatencyKeyMicroseconds is the key for stargz operation latency metrics in microseconds. OperationLatencyKeyMicroseconds = "operation_duration_microseconds" // OperationCountKey is the key for stargz operation count metrics. OperationCountKey = "operation_count" // BytesServedKey is the key for any metric related to counting bytes served as the part of specific operation. BytesServedKey = "bytes_served" // Keep namespace as stargz and subsystem as fs. namespace = "stargz" subsystem = "fs" ) // Lists all metric labels. const ( // prometheus metrics Mount = "mount" RemoteRegistryGet = "remote_registry_get" NodeReaddir = "node_readdir" StargzHeaderGet = "stargz_header_get" StargzFooterGet = "stargz_footer_get" StargzTocGet = "stargz_toc_get" DeserializeTocJSON = "stargz_toc_json_deserialize" PrefetchesCompleted = "all_prefetches_completed" ReadOnDemand = "read_on_demand" MountLayerToLastOnDemandFetch = "mount_layer_to_last_on_demand_fetch" OnDemandReadAccessCount = "on_demand_read_access_count" OnDemandRemoteRegistryFetchCount = "on_demand_remote_registry_fetch_count" OnDemandBytesServed = "on_demand_bytes_served" OnDemandBytesFetched = "on_demand_bytes_fetched" // logs metrics PrefetchTotal = "prefetch_total" PrefetchDownload = "prefetch_download" PrefetchDecompress = "prefetch_decompress" BackgroundFetchTotal = "background_fetch_total" BackgroundFetchDownload = "background_fetch_download" BackgroundFetchDecompress = "background_fetch_decompress" PrefetchSize = "prefetch_size" ) var ( // Buckets for OperationLatency metrics. latencyBucketsMilliseconds = []float64{1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384} // in milliseconds latencyBucketsMicroseconds = []float64{1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024} // in microseconds // operationLatencyMilliseconds collects operation latency numbers in milliseconds grouped by // operation, type and layer digest. operationLatencyMilliseconds = prometheus.NewHistogramVec( prometheus.HistogramOpts{ Namespace: namespace, Subsystem: subsystem, Name: OperationLatencyKeyMilliseconds, Help: "Latency in milliseconds of stargz snapshotter operations. Broken down by operation type and layer sha.", Buckets: latencyBucketsMilliseconds, }, []string{"operation_type", "layer"}, ) // operationLatencyMicroseconds collects operation latency numbers in microseconds grouped by // operation, type and layer digest. operationLatencyMicroseconds = prometheus.NewHistogramVec( prometheus.HistogramOpts{ Namespace: namespace, Subsystem: subsystem, Name: OperationLatencyKeyMicroseconds, Help: "Latency in microseconds of stargz snapshotter operations. Broken down by operation type and layer sha.", Buckets: latencyBucketsMicroseconds, }, []string{"operation_type", "layer"}, ) // operationCount collects operation count numbers by operation // type and layer sha. operationCount = prometheus.NewCounterVec( prometheus.CounterOpts{ Namespace: namespace, Subsystem: subsystem, Name: OperationCountKey, Help: "The count of stargz snapshotter operations. Broken down by operation type and layer sha.", }, []string{"operation_type", "layer"}, ) // bytesCount reflects the number of bytes served as the part of specitic operation type per layer sha. bytesCount = prometheus.NewGaugeVec( prometheus.GaugeOpts{ Namespace: namespace, Subsystem: subsystem, Name: BytesServedKey, Help: "The number of bytes served per stargz snapshotter operations. Broken down by operation type and layer sha.", }, []string{"operation_type", "layer"}, ) ) var register sync.Once var logLevel logrus.Level = logrus.DebugLevel // sinceInMilliseconds gets the time since the specified start in milliseconds. // The division by 1e6 is made to have the milliseconds value as floating point number, since the native method // .Milliseconds() returns an integer value and you can lost a precision for sub-millisecond values. func sinceInMilliseconds(start time.Time) float64 { return float64(time.Since(start).Nanoseconds()) / 1e6 } // sinceInMicroseconds gets the time since the specified start in microseconds. // The division by 1e3 is made to have the microseconds value as floating point number, since the native method // .Microseconds() returns an integer value and you can lost a precision for sub-microsecond values. func sinceInMicroseconds(start time.Time) float64 { return float64(time.Since(start).Nanoseconds()) / 1e3 } // Register registers metrics. This is always called only once. func Register(l logrus.Level) { register.Do(func() { logLevel = l prometheus.MustRegister(operationLatencyMilliseconds) prometheus.MustRegister(operationLatencyMicroseconds) prometheus.MustRegister(operationCount) prometheus.MustRegister(bytesCount) }) } // MeasureLatencyInMilliseconds wraps the labels attachment as well as calling Observe into a single method. // Right now we attach the operation and layer digest, so it's possible to see the breakdown for latency // by operation and individual layers. // If you want this to be layer agnostic, just pass the digest from empty string, e.g. // layerDigest := digest.FromString("") func MeasureLatencyInMilliseconds(operation string, layer digest.Digest, start time.Time) { operationLatencyMilliseconds.WithLabelValues(operation, layer.String()).Observe(sinceInMilliseconds(start)) } // MeasureLatencyInMicroseconds wraps the labels attachment as well as calling Observe into a single method. // Right now we attach the operation and layer digest, so it's possible to see the breakdown for latency // by operation and individual layers. // If you want this to be layer agnostic, just pass the digest from empty string, e.g. // layerDigest := digest.FromString("") func MeasureLatencyInMicroseconds(operation string, layer digest.Digest, start time.Time) { operationLatencyMicroseconds.WithLabelValues(operation, layer.String()).Observe(sinceInMicroseconds(start)) } // IncOperationCount wraps the labels attachment as well as calling Inc into a single method. func IncOperationCount(operation string, layer digest.Digest) { operationCount.WithLabelValues(operation, layer.String()).Inc() } // AddBytesCount wraps the labels attachment as well as calling Add into a single method. func AddBytesCount(operation string, layer digest.Digest, bytes int64) { bytesCount.WithLabelValues(operation, layer.String()).Add(float64(bytes)) } // WriteLatencyLogValue wraps writing the log info record for latency in milliseconds. The log record breaks down by operation and layer digest. func WriteLatencyLogValue(ctx context.Context, layer digest.Digest, operation string, start time.Time) { ctx = log.WithLogger(ctx, log.G(ctx).WithField("metrics", "latency").WithField("operation", operation).WithField("layer_sha", layer.String())) log.G(ctx).Logf(logLevel, "value=%v milliseconds", sinceInMilliseconds(start)) } // WriteLatencyWithBytesLogValue wraps writing the log info record for latency in milliseconds with adding the size in bytes. // The log record breaks down by operation, layer digest and byte value. func WriteLatencyWithBytesLogValue(ctx context.Context, layer digest.Digest, latencyOperation string, start time.Time, bytesMetricName string, bytesMetricValue int64) { ctx = log.WithLogger(ctx, log.G(ctx).WithField("metrics", "latency").WithField("operation", latencyOperation).WithField("layer_sha", layer.String())) log.G(ctx).Logf(logLevel, "value=%v milliseconds; %v=%v bytes", sinceInMilliseconds(start), bytesMetricName, bytesMetricValue) } // LogLatencyForLastOnDemandFetch implements a special case for measuring the latency of last on demand fetch, which must be invoked at the end of // background fetch operation only. Since this is expected to happen only once per container launch, it writes a log line, // instead of directly emitting a metric. // We do that in the following way: // 1. We record the mount start time // 2. We constantly record the timestamps when we do on demand fetch for each layer sha // 3. On background fetch completed we measure the difference between the last on demand fetch and mount start time // and record it as a metric func LogLatencyForLastOnDemandFetch(ctx context.Context, layer digest.Digest, start time.Time, end time.Time) { diffInMilliseconds := float64(end.Sub(start).Milliseconds()) // value can be negative if we pass the default value for time.Time as `end` // this can happen if there were no on-demand fetch for the particular layer if diffInMilliseconds > 0 { ctx = log.WithLogger(ctx, log.G(ctx).WithField("metrics", "latency").WithField("operation", MountLayerToLastOnDemandFetch).WithField("layer_sha", layer.String())) log.G(ctx).Logf(logLevel, "value=%v milliseconds", diffInMilliseconds) } } stargz-snapshotter-0.14.3/fs/metrics/layer/000077500000000000000000000000001440204344700206555ustar00rootroot00000000000000stargz-snapshotter-0.14.3/fs/metrics/layer/layer.go000066400000000000000000000030371440204344700223230ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package layermetrics import ( "github.com/containerd/stargz-snapshotter/fs/layer" metrics "github.com/docker/go-metrics" "github.com/prometheus/client_golang/prometheus" ) var layerMetrics = []*metric{ { name: "layer_fetched_size", help: "Total fetched size of the layer", unit: metrics.Bytes, vt: prometheus.CounterValue, getValues: func(l layer.Layer) []value { return []value{ { v: float64(l.Info().FetchedSize), }, } }, }, { name: "layer_prefetch_size", help: "Total prefetched size of the layer", unit: metrics.Bytes, vt: prometheus.CounterValue, getValues: func(l layer.Layer) []value { return []value{ { v: float64(l.Info().PrefetchSize), }, } }, }, { name: "layer_size", help: "Total size of the layer", unit: metrics.Bytes, vt: prometheus.CounterValue, getValues: func(l layer.Layer) []value { return []value{ { v: float64(l.Info().Size), }, } }, }, } stargz-snapshotter-0.14.3/fs/metrics/layer/metrics.go000066400000000000000000000050411440204344700226520ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package layermetrics import ( "sync" "github.com/containerd/stargz-snapshotter/fs/layer" metrics "github.com/docker/go-metrics" "github.com/prometheus/client_golang/prometheus" ) func NewLayerMetrics(ns *metrics.Namespace) *Controller { if ns == nil { return &Controller{} } c := &Controller{ ns: ns, layer: make(map[string]layer.Layer), } c.metrics = append(c.metrics, layerMetrics...) ns.Add(c) return c } type Controller struct { ns *metrics.Namespace metrics []*metric layer map[string]layer.Layer layerMu sync.RWMutex } func (c *Controller) Describe(ch chan<- *prometheus.Desc) { for _, e := range c.metrics { ch <- e.desc(c.ns) } } func (c *Controller) Collect(ch chan<- prometheus.Metric) { c.layerMu.RLock() wg := &sync.WaitGroup{} for mp, l := range c.layer { mp, l := mp, l wg.Add(1) go func() { defer wg.Done() for _, e := range c.metrics { e.collect(mp, l, c.ns, ch) } }() } c.layerMu.RUnlock() wg.Wait() } func (c *Controller) Add(key string, l layer.Layer) { if c.ns == nil { return } c.layerMu.Lock() c.layer[key] = l c.layerMu.Unlock() } func (c *Controller) Remove(key string) { if c.ns == nil { return } c.layerMu.Lock() delete(c.layer, key) c.layerMu.Unlock() } type value struct { v float64 l []string } type metric struct { name string help string unit metrics.Unit vt prometheus.ValueType labels []string // getValues returns the value and labels for the data getValues func(l layer.Layer) []value } func (m *metric) desc(ns *metrics.Namespace) *prometheus.Desc { return ns.NewDesc(m.name, m.help, m.unit, append([]string{"digest", "mountpoint"}, m.labels...)...) } func (m *metric) collect(mountpoint string, l layer.Layer, ns *metrics.Namespace, ch chan<- prometheus.Metric) { values := m.getValues(l) for _, v := range values { ch <- prometheus.MustNewConstMetric(m.desc(ns), m.vt, v.v, append([]string{l.Info().Digest.String(), mountpoint}, v.l...)...) } } stargz-snapshotter-0.14.3/fs/reader/000077500000000000000000000000001440204344700173355ustar00rootroot00000000000000stargz-snapshotter-0.14.3/fs/reader/reader.go000066400000000000000000000351431440204344700211340ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /* Copyright 2019 The Go Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the NOTICE.md file. */ package reader import ( "bufio" "bytes" "context" "crypto/sha256" "fmt" "io" "os" "runtime" "sync" "time" "github.com/containerd/stargz-snapshotter/cache" "github.com/containerd/stargz-snapshotter/estargz" commonmetrics "github.com/containerd/stargz-snapshotter/fs/metrics/common" "github.com/containerd/stargz-snapshotter/metadata" "github.com/hashicorp/go-multierror" digest "github.com/opencontainers/go-digest" "golang.org/x/sync/errgroup" "golang.org/x/sync/semaphore" ) const maxWalkDepth = 10000 type Reader interface { OpenFile(id uint32) (io.ReaderAt, error) Metadata() metadata.Reader Close() error LastOnDemandReadTime() time.Time } // VerifiableReader produces a Reader with a given verifier. type VerifiableReader struct { r *reader lastVerifyErr error lastVerifyErrMu sync.Mutex prohibitVerifyFailure bool prohibitVerifyFailureMu sync.RWMutex closed bool closedMu sync.Mutex verifier func(uint32, string) (digest.Verifier, error) } func (vr *VerifiableReader) storeLastVerifyErr(err error) { vr.lastVerifyErrMu.Lock() vr.lastVerifyErr = err vr.lastVerifyErrMu.Unlock() } func (vr *VerifiableReader) loadLastVerifyErr() error { vr.lastVerifyErrMu.Lock() err := vr.lastVerifyErr vr.lastVerifyErrMu.Unlock() return err } func (vr *VerifiableReader) SkipVerify() Reader { return vr.r } func (vr *VerifiableReader) VerifyTOC(tocDigest digest.Digest) (Reader, error) { if vr.isClosed() { return nil, fmt.Errorf("reader is already closed") } vr.prohibitVerifyFailureMu.Lock() vr.prohibitVerifyFailure = true lastVerifyErr := vr.loadLastVerifyErr() vr.prohibitVerifyFailureMu.Unlock() if err := lastVerifyErr; err != nil { return nil, fmt.Errorf("content error occurs during caching contents: %w", err) } if actual := vr.r.r.TOCDigest(); actual != tocDigest { return nil, fmt.Errorf("invalid TOC JSON %q; want %q", actual, tocDigest) } vr.r.verify = true return vr.r, nil } func (vr *VerifiableReader) Metadata() metadata.Reader { // TODO: this shouldn't be called before verified return vr.r.r } func (vr *VerifiableReader) Cache(opts ...CacheOption) (err error) { if vr.isClosed() { return fmt.Errorf("reader is already closed") } var cacheOpts cacheOptions for _, o := range opts { o(&cacheOpts) } gr := vr.r r := gr.r if cacheOpts.reader != nil { r, err = r.Clone(cacheOpts.reader) if err != nil { return err } } rootID := r.RootID() filter := func(int64) bool { return true } if cacheOpts.filter != nil { filter = cacheOpts.filter } eg, egCtx := errgroup.WithContext(context.Background()) eg.Go(func() error { return vr.cacheWithReader(egCtx, 0, eg, semaphore.NewWeighted(int64(runtime.GOMAXPROCS(0))), rootID, r, filter, cacheOpts.cacheOpts...) }) return eg.Wait() } func (vr *VerifiableReader) cacheWithReader(ctx context.Context, currentDepth int, eg *errgroup.Group, sem *semaphore.Weighted, dirID uint32, r metadata.Reader, filter func(int64) bool, opts ...cache.Option) (rErr error) { if currentDepth > maxWalkDepth { return fmt.Errorf("tree is too deep (depth:%d)", currentDepth) } rootID := r.RootID() r.ForeachChild(dirID, func(name string, id uint32, mode os.FileMode) bool { e, err := r.GetAttr(id) if err != nil { rErr = err return false } if mode.IsDir() { // Walk through all files on this stargz file. // Ignore the entry of "./" (formated as "" by stargz lib) on root directory // because this points to the root directory itself. if dirID == rootID && name == "" { return true } if err := vr.cacheWithReader(ctx, currentDepth+1, eg, sem, id, r, filter, opts...); err != nil { rErr = err return false } return true } else if !mode.IsRegular() { // Only cache regular files return true } else if dirID == rootID && name == estargz.TOCTarName { // We don't need to cache TOC json file return true } offset, err := r.GetOffset(id) if err != nil { rErr = err return false } if !filter(offset) { // This entry need to be filtered out return true } fr, err := r.OpenFileWithPreReader(id, func(nid uint32, chunkOffset, chunkSize int64, chunkDigest string, r io.Reader) (retErr error) { return vr.readAndCache(nid, r, chunkOffset, chunkSize, chunkDigest, opts...) }) if err != nil { rErr = err return false } var nr int64 for nr < e.Size { chunkOffset, chunkSize, chunkDigestStr, ok := fr.ChunkEntryForOffset(nr) if !ok { break } nr += chunkSize if err := sem.Acquire(ctx, 1); err != nil { rErr = err return false } eg.Go(func() error { defer sem.Release(1) err := vr.readAndCache(id, io.NewSectionReader(fr, chunkOffset, chunkSize), chunkOffset, chunkSize, chunkDigestStr, opts...) if err != nil { return fmt.Errorf("failed to read %q (off:%d,size:%d): %w", name, chunkOffset, chunkSize, err) } return nil }) } return true }) return } func (vr *VerifiableReader) readAndCache(id uint32, fr io.Reader, chunkOffset, chunkSize int64, chunkDigest string, opts ...cache.Option) (retErr error) { gr := vr.r if retErr != nil { vr.storeLastVerifyErr(retErr) } // Check if it already exists in the cache cacheID := genID(id, chunkOffset, chunkSize) if r, err := gr.cache.Get(cacheID); err == nil { r.Close() return nil } // missed cache, needs to fetch and add it to the cache br := bufio.NewReaderSize(fr, int(chunkSize)) if _, err := br.Peek(int(chunkSize)); err != nil { return fmt.Errorf("cacheWithReader.peek: %v", err) } w, err := gr.cache.Add(cacheID, opts...) if err != nil { return err } defer w.Close() v, err := vr.verifier(id, chunkDigest) if err != nil { vr.prohibitVerifyFailureMu.RLock() if vr.prohibitVerifyFailure { vr.prohibitVerifyFailureMu.RUnlock() return fmt.Errorf("verifier not found: %w", err) } vr.storeLastVerifyErr(err) vr.prohibitVerifyFailureMu.RUnlock() } tee := io.Discard if v != nil { tee = io.Writer(v) // verification is required } if _, err := io.CopyN(w, io.TeeReader(br, tee), chunkSize); err != nil { w.Abort() return fmt.Errorf("failed to cache file payload: %w", err) } if v != nil && !v.Verified() { err := fmt.Errorf("invalid chunk") vr.prohibitVerifyFailureMu.RLock() if vr.prohibitVerifyFailure { vr.prohibitVerifyFailureMu.RUnlock() w.Abort() return err } vr.storeLastVerifyErr(err) vr.prohibitVerifyFailureMu.RUnlock() } return w.Commit() } func (vr *VerifiableReader) Close() error { vr.closedMu.Lock() defer vr.closedMu.Unlock() if vr.closed { return nil } vr.closed = true return vr.r.Close() } func (vr *VerifiableReader) isClosed() bool { vr.closedMu.Lock() closed := vr.closed vr.closedMu.Unlock() return closed } // NewReader creates a Reader based on the given stargz blob and cache implementation. // It returns VerifiableReader so the caller must provide a metadata.ChunkVerifier // to use for verifying file or chunk contained in this stargz blob. func NewReader(r metadata.Reader, cache cache.BlobCache, layerSha digest.Digest) (*VerifiableReader, error) { vr := &reader{ r: r, cache: cache, bufPool: sync.Pool{ New: func() interface{} { return new(bytes.Buffer) }, }, layerSha: layerSha, verifier: digestVerifier, } return &VerifiableReader{r: vr, verifier: digestVerifier}, nil } type reader struct { r metadata.Reader cache cache.BlobCache bufPool sync.Pool layerSha digest.Digest lastReadTime time.Time lastReadTimeMu sync.Mutex closed bool closedMu sync.Mutex verify bool verifier func(uint32, string) (digest.Verifier, error) } func (gr *reader) Metadata() metadata.Reader { return gr.r } func (gr *reader) setLastReadTime(lastReadTime time.Time) { gr.lastReadTimeMu.Lock() gr.lastReadTime = lastReadTime gr.lastReadTimeMu.Unlock() } func (gr *reader) LastOnDemandReadTime() time.Time { gr.lastReadTimeMu.Lock() t := gr.lastReadTime gr.lastReadTimeMu.Unlock() return t } func (gr *reader) OpenFile(id uint32) (io.ReaderAt, error) { if gr.isClosed() { return nil, fmt.Errorf("reader is already closed") } var fr metadata.File fr, err := gr.r.OpenFileWithPreReader(id, func(nid uint32, chunkOffset, chunkSize int64, chunkDigest string, r io.Reader) error { // Check if it already exists in the cache cacheID := genID(nid, chunkOffset, chunkSize) if r, err := gr.cache.Get(cacheID); err == nil { r.Close() return nil } // Read and cache b := gr.bufPool.Get().(*bytes.Buffer) b.Reset() b.Grow(int(chunkSize)) ip := b.Bytes()[:chunkSize] if _, err := io.ReadFull(r, ip); err != nil { gr.putBuffer(b) return err } err := gr.verifyAndCache(nid, ip, chunkDigest, cacheID) gr.putBuffer(b) return err }) if err != nil { return nil, fmt.Errorf("failed to open file %d: %w", id, err) } return &file{ id: id, fr: fr, gr: gr, }, nil } func (gr *reader) Close() (retErr error) { gr.closedMu.Lock() defer gr.closedMu.Unlock() if gr.closed { return nil } gr.closed = true if err := gr.cache.Close(); err != nil { retErr = multierror.Append(retErr, err) } if err := gr.r.Close(); err != nil { retErr = multierror.Append(retErr, err) } return } func (gr *reader) isClosed() bool { gr.closedMu.Lock() closed := gr.closed gr.closedMu.Unlock() return closed } func (gr *reader) putBuffer(b *bytes.Buffer) { b.Reset() gr.bufPool.Put(b) } type file struct { id uint32 fr metadata.File gr *reader } // ReadAt reads chunks from the stargz file with trying to fetch as many chunks // as possible from the cache. func (sf *file) ReadAt(p []byte, offset int64) (int, error) { nr := 0 for nr < len(p) { chunkOffset, chunkSize, chunkDigestStr, ok := sf.fr.ChunkEntryForOffset(offset + int64(nr)) if !ok { break } var ( id = genID(sf.id, chunkOffset, chunkSize) lowerDiscard = positive(offset - chunkOffset) upperDiscard = positive(chunkOffset + chunkSize - (offset + int64(len(p)))) expectedSize = chunkSize - upperDiscard - lowerDiscard ) // Check if the content exists in the cache if r, err := sf.gr.cache.Get(id); err == nil { n, err := r.ReadAt(p[nr:int64(nr)+expectedSize], lowerDiscard) if (err == nil || err == io.EOF) && int64(n) == expectedSize { nr += n r.Close() continue } r.Close() } // We missed cache. Take it from underlying reader. // We read the whole chunk here and add it to the cache so that following // reads against neighboring chunks can take the data without decmpression. if lowerDiscard == 0 && upperDiscard == 0 { // We can directly store the result to the given buffer ip := p[nr : int64(nr)+chunkSize] n, err := sf.fr.ReadAt(ip, chunkOffset) if err != nil && err != io.EOF { return 0, fmt.Errorf("failed to read data: %w", err) } if err := sf.gr.verifyAndCache(sf.id, ip, chunkDigestStr, id); err != nil { return 0, err } nr += n continue } // Use temporally buffer for aligning this chunk b := sf.gr.bufPool.Get().(*bytes.Buffer) b.Reset() b.Grow(int(chunkSize)) ip := b.Bytes()[:chunkSize] if _, err := sf.fr.ReadAt(ip, chunkOffset); err != nil && err != io.EOF { sf.gr.putBuffer(b) return 0, fmt.Errorf("failed to read data: %w", err) } if err := sf.gr.verifyAndCache(sf.id, ip, chunkDigestStr, id); err != nil { sf.gr.putBuffer(b) return 0, err } n := copy(p[nr:], ip[lowerDiscard:chunkSize-upperDiscard]) sf.gr.putBuffer(b) if int64(n) != expectedSize { return 0, fmt.Errorf("unexpected final data size %d; want %d", n, expectedSize) } nr += n } commonmetrics.AddBytesCount(commonmetrics.OnDemandBytesServed, sf.gr.layerSha, int64(nr)) // measure the number of on demand bytes served return nr, nil } func (gr *reader) verifyAndCache(entryID uint32, ip []byte, chunkDigestStr string, cacheID string) error { // We can end up doing on demand registry fetch when aligning the chunk commonmetrics.IncOperationCount(commonmetrics.OnDemandRemoteRegistryFetchCount, gr.layerSha) // increment the number of on demand file fetches from remote registry commonmetrics.AddBytesCount(commonmetrics.OnDemandBytesFetched, gr.layerSha, int64(len(ip))) // record total bytes fetched gr.setLastReadTime(time.Now()) // Verify this chunk if err := gr.verifyChunk(entryID, ip, chunkDigestStr); err != nil { return fmt.Errorf("invalid chunk: %w", err) } // Cache this chunk if w, err := gr.cache.Add(cacheID); err == nil { if cn, err := w.Write(ip); err != nil || cn != len(ip) { w.Abort() } else { w.Commit() } w.Close() } return nil } func (gr *reader) verifyChunk(id uint32, p []byte, chunkDigestStr string) error { if !gr.verify { return nil // verification is not required } v, err := gr.verifier(id, chunkDigestStr) if err != nil { return fmt.Errorf("invalid chunk: %w", err) } if _, err := v.Write(p); err != nil { return fmt.Errorf("invalid chunk: failed to write to verifier: %w", err) } if !v.Verified() { return fmt.Errorf("invalid chunk: not verified") } return nil } func genID(id uint32, offset, size int64) string { sum := sha256.Sum256([]byte(fmt.Sprintf("%d-%d-%d", id, offset, size))) return fmt.Sprintf("%x", sum) } func positive(n int64) int64 { if n < 0 { return 0 } return n } type CacheOption func(*cacheOptions) type cacheOptions struct { cacheOpts []cache.Option filter func(int64) bool reader *io.SectionReader } func WithCacheOpts(cacheOpts ...cache.Option) CacheOption { return func(opts *cacheOptions) { opts.cacheOpts = cacheOpts } } func WithFilter(filter func(int64) bool) CacheOption { return func(opts *cacheOptions) { opts.filter = filter } } func WithReader(sr *io.SectionReader) CacheOption { return func(opts *cacheOptions) { opts.reader = sr } } func digestVerifier(id uint32, chunkDigestStr string) (digest.Verifier, error) { chunkDigest, err := digest.Parse(chunkDigestStr) if err != nil { return nil, fmt.Errorf("invalid chunk: no digest is recorded(len=%d): %w", len(chunkDigestStr), err) } return chunkDigest.Verifier(), nil } stargz-snapshotter-0.14.3/fs/reader/reader_test.go000066400000000000000000000016771440204344700222000ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /* Copyright 2019 The Go Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the NOTICE.md file. */ package reader import ( "testing" memorymetadata "github.com/containerd/stargz-snapshotter/metadata/memory" ) func TestReader(t *testing.T) { TestSuiteReader(t, memorymetadata.NewReader) } stargz-snapshotter-0.14.3/fs/reader/testutil.go000066400000000000000000000621341440204344700215470ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /* Copyright 2019 The Go Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the NOTICE.md file. */ package reader import ( "bytes" "compress/gzip" "fmt" "io" "os" "path" "path/filepath" "strings" "sync" "testing" "time" "github.com/containerd/stargz-snapshotter/cache" "github.com/containerd/stargz-snapshotter/estargz" "github.com/containerd/stargz-snapshotter/metadata" "github.com/containerd/stargz-snapshotter/util/testutil" tutil "github.com/containerd/stargz-snapshotter/util/testutil" "github.com/klauspost/compress/zstd" digest "github.com/opencontainers/go-digest" "golang.org/x/sync/errgroup" ) type region struct{ b, e int64 } const ( sampleChunkSize = 3 sampleMiddleOffset = sampleChunkSize / 2 sampleData1 = "0123456789" lastChunkOffset1 = sampleChunkSize * (int64(len(sampleData1)) / sampleChunkSize) ) var srcCompressions = map[string]tutil.CompressionFactory{ "zstd-fastest": tutil.ZstdCompressionWithLevel(zstd.SpeedFastest), "gzip-bestspeed": tutil.GzipCompressionWithLevel(gzip.BestSpeed), "externaltoc-gzip-bestspeed": tutil.ExternalTOCGzipCompressionWithLevel(gzip.BestSpeed), } func TestSuiteReader(t *testing.T, store metadata.Store) { testFileReadAt(t, store) testCacheVerify(t, store) testFailReader(t, store) testPreReader(t, store) } func testFileReadAt(t *testing.T, factory metadata.Store) { sizeCond := map[string]int64{ "single_chunk": sampleChunkSize - sampleMiddleOffset, "multi_chunks": sampleChunkSize + sampleMiddleOffset, } innerOffsetCond := map[string]int64{ "at_top": 0, "at_middle": sampleMiddleOffset, } baseOffsetCond := map[string]int64{ "of_1st_chunk": sampleChunkSize * 0, "of_2nd_chunk": sampleChunkSize * 1, "of_last_chunk": lastChunkOffset1, } fileSizeCond := map[string]int64{ "in_1_chunk_file": sampleChunkSize * 1, "in_2_chunks_file": sampleChunkSize * 2, "in_max_size_file": int64(len(sampleData1)), } cacheCond := map[string][]region{ "with_clean_cache": nil, "with_edge_filled_cache": { region{0, sampleChunkSize - 1}, region{lastChunkOffset1, int64(len(sampleData1)) - 1}, }, "with_sparse_cache": { region{0, sampleChunkSize - 1}, region{2 * sampleChunkSize, 3*sampleChunkSize - 1}, }, } for sn, size := range sizeCond { for in, innero := range innerOffsetCond { for bo, baseo := range baseOffsetCond { for fn, filesize := range fileSizeCond { for cc, cacheExcept := range cacheCond { for srcCompressionName, srcCompression := range srcCompressions { srcCompression := srcCompression() t.Run(fmt.Sprintf("reading_%s_%s_%s_%s_%s_%s", sn, in, bo, fn, cc, srcCompressionName), func(t *testing.T) { if filesize > int64(len(sampleData1)) { t.Fatal("sample file size is larger than sample data") } wantN := size offset := baseo + innero if remain := filesize - offset; remain < wantN { if wantN = remain; wantN < 0 { wantN = 0 } } // use constant string value as a data source. want := strings.NewReader(sampleData1) // data we want to get. wantData := make([]byte, wantN) _, err := want.ReadAt(wantData, offset) if err != nil && err != io.EOF { t.Fatalf("want.ReadAt (offset=%d,size=%d): %v", offset, wantN, err) } // data we get through a file. f, closeFn := makeFile(t, []byte(sampleData1)[:filesize], sampleChunkSize, factory, srcCompression) defer closeFn() f.fr = newExceptFile(t, f.fr, cacheExcept...) for _, reg := range cacheExcept { id := genID(f.id, reg.b, reg.e-reg.b+1) w, err := f.gr.cache.Add(id) if err != nil { w.Close() t.Fatalf("failed to add cache %v: %v", id, err) } if _, err := w.Write([]byte(sampleData1[reg.b : reg.e+1])); err != nil { w.Close() t.Fatalf("failed to write cache %v: %v", id, err) } if err := w.Commit(); err != nil { w.Close() t.Fatalf("failed to commit cache %v: %v", id, err) } w.Close() } respData := make([]byte, size) n, err := f.ReadAt(respData, offset) if err != nil { t.Errorf("failed to read off=%d, size=%d, filesize=%d: %v", offset, size, filesize, err) return } respData = respData[:n] if !bytes.Equal(wantData, respData) { t.Errorf("off=%d, filesize=%d; read data{size=%d,data=%q}; want (size=%d,data=%q)", offset, filesize, len(respData), string(respData), wantN, string(wantData)) return } // check cache has valid contents. cn := 0 nr := 0 for int64(nr) < wantN { chunkOffset, chunkSize, _, ok := f.fr.ChunkEntryForOffset(offset + int64(nr)) if !ok { break } data := make([]byte, chunkSize) id := genID(f.id, chunkOffset, chunkSize) r, err := f.gr.cache.Get(id) if err != nil { t.Errorf("missed cache of offset=%d, size=%d: %v(got size=%d)", chunkOffset, chunkSize, err, n) return } defer r.Close() if n, err := r.ReadAt(data, 0); (err != nil && err != io.EOF) || n != int(chunkSize) { t.Errorf("failed to read cache of offset=%d, size=%d: %v(got size=%d)", chunkOffset, chunkSize, err, n) return } nr += n cn++ } }) } } } } } } } func newExceptFile(t *testing.T, fr metadata.File, except ...region) metadata.File { er := exceptFile{fr: fr, t: t} er.except = map[region]bool{} for _, reg := range except { er.except[reg] = true } return &er } type exceptFile struct { fr metadata.File except map[region]bool t *testing.T } func (er *exceptFile) ReadAt(p []byte, offset int64) (int, error) { if er.except[region{offset, offset + int64(len(p)) - 1}] { er.t.Fatalf("Requested prohibited region of chunk: (%d, %d)", offset, offset+int64(len(p))-1) } return er.fr.ReadAt(p, offset) } func (er *exceptFile) ChunkEntryForOffset(offset int64) (off int64, size int64, dgst string, ok bool) { return er.fr.ChunkEntryForOffset(offset) } func makeFile(t *testing.T, contents []byte, chunkSize int, factory metadata.Store, comp tutil.Compression) (*file, func() error) { testName := "test" sr, dgst, err := testutil.BuildEStargz([]testutil.TarEntry{ testutil.File(testName, string(contents)), }, testutil.WithEStargzOptions(estargz.WithChunkSize(chunkSize), estargz.WithCompression(comp))) if err != nil { t.Fatalf("failed to build sample estargz") } mr, err := factory(sr, metadata.WithDecompressors(comp)) if err != nil { t.Fatalf("failed to create reader: %v", err) } vr, err := NewReader(mr, cache.NewMemoryCache(), digest.FromString("")) if err != nil { mr.Close() t.Fatalf("failed to make new reader: %v", err) } r, err := vr.VerifyTOC(dgst) if err != nil { vr.Close() t.Fatalf("failed to verify TOC: %v", err) } tid, _, err := r.Metadata().GetChild(r.Metadata().RootID(), testName) if err != nil { vr.Close() t.Fatalf("failed to get %q: %v", testName, err) } ra, err := r.OpenFile(tid) if err != nil { vr.Close() t.Fatalf("Failed to open testing file: %v", err) } f, ok := ra.(*file) if !ok { vr.Close() t.Fatalf("invalid type of file %q", tid) } return f, vr.Close } func testCacheVerify(t *testing.T, factory metadata.Store) { for _, skipVerify := range [2]bool{true, false} { for _, invalidChunkBeforeVerify := range [2]bool{true, false} { for _, invalidChunkAfterVerify := range [2]bool{true, false} { for srcCompressionName, srcCompression := range srcCompressions { srcCompression := srcCompression() name := fmt.Sprintf("test_cache_verify_%v_%v_%v_%v", skipVerify, invalidChunkBeforeVerify, invalidChunkAfterVerify, srcCompressionName) t.Run(name, func(t *testing.T) { sr, tocDgst, err := testutil.BuildEStargz([]testutil.TarEntry{ testutil.File("a", sampleData1+"a"), testutil.File("b", sampleData1+"b"), }, testutil.WithEStargzOptions(estargz.WithChunkSize(sampleChunkSize), estargz.WithCompression(srcCompression))) if err != nil { t.Fatalf("failed to build sample estargz") } // Determine the expected behaviour var wantVerifyFail, wantCacheFail, wantCacheFail2 bool if skipVerify { // always no error if verification is disabled wantVerifyFail, wantCacheFail, wantCacheFail2 = false, false, false } else if invalidChunkBeforeVerify { // errors occurred before verifying TOC must be reported via VerifyTOC() wantVerifyFail = true } else if invalidChunkAfterVerify { // errors occurred after verifying TOC must be reported via Cache() wantVerifyFail, wantCacheFail, wantCacheFail2 = false, true, true } else { // otherwise no verification error wantVerifyFail, wantCacheFail, wantCacheFail2 = false, false, false } // Prepare reader verifier := &failIDVerifier{} mr, err := factory(sr, metadata.WithDecompressors(srcCompression)) if err != nil { t.Fatalf("failed to prepare reader %v", err) } defer mr.Close() vr, err := NewReader(mr, cache.NewMemoryCache(), digest.FromString("")) if err != nil { t.Fatalf("failed to make new reader: %v", err) } if verifier != nil { vr.verifier = verifier.verifier vr.r.verifier = verifier.verifier } off2id, id2path, err := prepareMap(vr.Metadata(), vr.Metadata().RootID(), "") if err != nil || off2id == nil || id2path == nil { t.Fatalf("failed to prepare offset map %v, off2id = %+v, id2path = %+v", err, off2id, id2path) } // Perform Cache() before verification // 1. Either of "a" or "b" is read and verified // 2. VerifyTOC/SkipVerify is called // 3. Another entry ("a" or "b") is called verifyDone := make(chan struct{}) var firstEntryCalled bool var eg errgroup.Group var mu sync.Mutex eg.Go(func() error { return vr.Cache(WithFilter(func(off int64) bool { id, ok := off2id[off] if !ok { t.Fatalf("no ID is assigned to offset %d", off) } name, ok := id2path[id] if !ok { t.Fatalf("no name is assigned to id %d", id) } if name == "a" || name == "b" { mu.Lock() if !firstEntryCalled { firstEntryCalled = true if invalidChunkBeforeVerify { verifier.registerFails([]uint32{id}) } mu.Unlock() return true } mu.Unlock() <-verifyDone if invalidChunkAfterVerify { verifier.registerFails([]uint32{id}) } return true } return false })) }) if invalidChunkBeforeVerify { // wait for encountering the error of the first chunk read start := time.Now() for { if err := vr.loadLastVerifyErr(); err != nil { break } if time.Since(start) > time.Second { t.Fatalf("timeout(1s): failed to wait for read error is registered") } time.Sleep(10 * time.Millisecond) } } // Perform verification if skipVerify { vr.SkipVerify() } else { _, err = vr.VerifyTOC(tocDgst) } if checkErr := checkError(wantVerifyFail, err); checkErr != nil { t.Errorf("verify: %v", checkErr) return } if err != nil { return } close(verifyDone) // Check the result of Cache() if checkErr := checkError(wantCacheFail, eg.Wait()); checkErr != nil { t.Errorf("cache: %v", checkErr) return } // Call Cache() again and check the result if checkErr := checkError(wantCacheFail2, vr.Cache()); checkErr != nil { t.Errorf("cache(2): %v", checkErr) return } }) } } } } } type failIDVerifier struct { fails []uint32 failsMu sync.Mutex } func (f *failIDVerifier) registerFails(fails []uint32) { f.failsMu.Lock() defer f.failsMu.Unlock() f.fails = fails } func (f *failIDVerifier) verifier(id uint32, chunkDigest string) (digest.Verifier, error) { f.failsMu.Lock() defer f.failsMu.Unlock() success := true for _, n := range f.fails { if n == id { success = false break } } return &testVerifier{success}, nil } type testVerifier struct { success bool } func (bv *testVerifier) Write(p []byte) (n int, err error) { return len(p), nil } func (bv *testVerifier) Verified() bool { return bv.success } func checkError(wantFail bool, err error) error { if wantFail && err == nil { return fmt.Errorf("wanted to fail but succeeded") } else if !wantFail && err != nil { return fmt.Errorf("wanted to succeed verification but failed: %w", err) } return nil } func prepareMap(mr metadata.Reader, id uint32, p string) (off2id map[int64]uint32, id2path map[uint32]string, _ error) { attr, err := mr.GetAttr(id) if err != nil { return nil, nil, err } id2path = map[uint32]string{id: p} off2id = make(map[int64]uint32) if attr.Mode.IsRegular() { off, err := mr.GetOffset(id) if err != nil { return nil, nil, err } off2id[off] = id } var retErr error mr.ForeachChild(id, func(name string, id uint32, mode os.FileMode) bool { o2i, i2p, err := prepareMap(mr, id, path.Join(p, name)) if err != nil { retErr = err return false } for k, v := range o2i { off2id[k] = v } for k, v := range i2p { id2path[k] = v } return true }) if retErr != nil { return nil, nil, retErr } return off2id, id2path, nil } func testFailReader(t *testing.T, factory metadata.Store) { testFileName := "test" for srcCompressionName, srcCompression := range srcCompressions { srcCompression := srcCompression() t.Run(fmt.Sprintf("%v", srcCompressionName), func(t *testing.T) { for _, rs := range []bool{true, false} { for _, vs := range []bool{true, false} { stargzFile, tocDigest, err := testutil.BuildEStargz([]testutil.TarEntry{ testutil.File(testFileName, sampleData1), }, testutil.WithEStargzOptions(estargz.WithChunkSize(sampleChunkSize), estargz.WithCompression(srcCompression))) if err != nil { t.Fatalf("failed to build sample estargz") } br := &breakReaderAt{ ReaderAt: stargzFile, success: true, } bev := &testChunkVerifier{true} mcache := cache.NewMemoryCache() mr, err := factory(io.NewSectionReader(br, 0, stargzFile.Size()), metadata.WithDecompressors(srcCompression)) if err != nil { t.Fatalf("failed to prepare metadata reader") } defer mr.Close() vr, err := NewReader(mr, mcache, digest.FromString("")) if err != nil { t.Fatalf("failed to make new reader: %v", err) } defer vr.Close() vr.verifier = bev.verifier vr.r.verifier = bev.verifier gr, err := vr.VerifyTOC(tocDigest) if err != nil { t.Fatalf("failed to verify TOC: %v", err) } notexist := uint32(0) found := false for i := uint32(0); i < 1000000; i++ { if _, err := gr.Metadata().GetAttr(i); err != nil { notexist, found = i, true break } } if !found { t.Fatalf("free ID not found") } // tests for opening non-existing file _, err = gr.OpenFile(notexist) if err == nil { t.Errorf("succeeded to open file but wanted to fail") return } // tests failure behaviour of a file read tid, _, err := gr.Metadata().GetChild(gr.Metadata().RootID(), testFileName) if err != nil { t.Errorf("failed to get %q: %v", testFileName, err) return } fr, err := gr.OpenFile(tid) if err != nil { t.Errorf("failed to open file but wanted to succeed: %v", err) return } mcache.(*cache.MemoryCache).Membuf = map[string]*bytes.Buffer{} br.success = rs bev.success = vs // tests for reading file p := make([]byte, len(sampleData1)) n, err := fr.ReadAt(p, 0) if rs && vs { if err != nil || n != len(sampleData1) || !bytes.Equal([]byte(sampleData1), p) { t.Errorf("failed to read data but wanted to succeed: %v", err) return } } else { if err == nil { t.Errorf("succeeded to read data but wanted to fail (reader:%v,verify:%v)", rs, vs) return } } } } }) } } type breakReaderAt struct { io.ReaderAt success bool } func (br *breakReaderAt) ReadAt(p []byte, off int64) (int, error) { if br.success { return br.ReaderAt.ReadAt(p, off) } return 0, fmt.Errorf("failed") } type testChunkVerifier struct { success bool } func (bev *testChunkVerifier) verifier(id uint32, chunkDigest string) (digest.Verifier, error) { return &testVerifier{bev.success}, nil } func testPreReader(t *testing.T, factory metadata.Store) { data64KB := string(tutil.RandomBytes(t, 64000)) tests := []struct { name string chunkSize int minChunkSize int in []tutil.TarEntry want []check }{ { name: "several_files_in_chunk", minChunkSize: 8000, in: []tutil.TarEntry{ tutil.Dir("foo/"), tutil.File("foo/foo1", data64KB), tutil.File("foo2", "bb"), tutil.File("foo22", "ccc"), tutil.Dir("bar/"), tutil.File("bar/bar.txt", "aaa"), tutil.File("foo3", data64KB), }, // NOTE: we assume that the compressed "data64KB" is still larger than 8KB // landmark+dir+foo1, foo2+foo22+dir+bar.txt+foo3, TOC, footer want: []check{ hasFileContentsWithPreCached("foo22", 0, "ccc", chunkInfo{"foo2", "bb", 0, 2}, chunkInfo{"bar/bar.txt", "aaa", 0, 3}, chunkInfo{"foo3", data64KB, 0, 64000}), hasFileContentsOffset("foo2", 0, "bb", true), hasFileContentsOffset("bar/bar.txt", 0, "aaa", true), hasFileContentsOffset("bar/bar.txt", 1, "aa", true), hasFileContentsOffset("bar/bar.txt", 2, "a", true), hasFileContentsOffset("foo3", 0, data64KB, true), hasFileContentsOffset("foo22", 0, "ccc", true), hasFileContentsOffset("foo/foo1", 0, data64KB, false), hasFileContentsOffset("foo/foo1", 0, data64KB, true), hasFileContentsOffset("foo/foo1", 1, data64KB[1:], true), hasFileContentsOffset("foo/foo1", 2, data64KB[2:], true), hasFileContentsOffset("foo/foo1", 3, data64KB[3:], true), }, }, { name: "several_files_in_chunk_chunked", minChunkSize: 8000, chunkSize: 32000, in: []tutil.TarEntry{ tutil.Dir("foo/"), tutil.File("foo/foo1", data64KB), tutil.File("foo2", "bb"), tutil.Dir("bar/"), tutil.File("foo3", data64KB), }, // NOTE: we assume that the compressed chunk of "data64KB" is still larger than 8KB // landmark+dir+foo1(1), foo1(2), foo2+dir+foo3(1), foo3(2), TOC, footer want: []check{ hasFileContentsWithPreCached("foo2", 0, "bb", chunkInfo{"foo3", data64KB[:32000], 0, 32000}), hasFileContentsOffset("foo2", 0, "bb", true), hasFileContentsOffset("foo2", 1, "b", true), hasFileContentsOffset("foo3", 0, data64KB[:len(data64KB)/2], true), hasFileContentsOffset("foo3", 1, data64KB[1:len(data64KB)/2], true), hasFileContentsOffset("foo3", 2, data64KB[2:len(data64KB)/2], true), hasFileContentsOffset("foo3", int64(len(data64KB)/2), data64KB[len(data64KB)/2:], false), hasFileContentsOffset("foo3", int64(len(data64KB)-1), data64KB[len(data64KB)-1:], true), hasFileContentsOffset("foo/foo1", 0, data64KB, false), hasFileContentsOffset("foo/foo1", 1, data64KB[1:], true), hasFileContentsOffset("foo/foo1", 2, data64KB[2:], true), hasFileContentsOffset("foo/foo1", int64(len(data64KB)/2), data64KB[len(data64KB)/2:], true), hasFileContentsOffset("foo/foo1", int64(len(data64KB)-1), data64KB[len(data64KB)-1:], true), }, }, } for _, tt := range tests { for srcCompresionName, srcCompression := range srcCompressions { srcCompression := srcCompression() t.Run(tt.name+"-"+srcCompresionName, func(t *testing.T) { opts := []tutil.BuildEStargzOption{ tutil.WithEStargzOptions(estargz.WithCompression(srcCompression)), } if tt.chunkSize > 0 { opts = append(opts, tutil.WithEStargzOptions(estargz.WithChunkSize(tt.chunkSize))) } if tt.minChunkSize > 0 { t.Logf("minChunkSize = %d", tt.minChunkSize) opts = append(opts, tutil.WithEStargzOptions(estargz.WithMinChunkSize(tt.minChunkSize))) } esgz, tocDgst, err := tutil.BuildEStargz(tt.in, opts...) if err != nil { t.Fatalf("failed to build sample eStargz: %v", err) } testR := &calledReaderAt{esgz, nil} mr, err := factory(io.NewSectionReader(testR, 0, esgz.Size()), metadata.WithDecompressors(srcCompression)) if err != nil { t.Fatalf("failed to create new reader: %v", err) } defer mr.Close() memcache := cache.NewMemoryCache() vr, err := NewReader(mr, memcache, digest.FromString("")) if err != nil { t.Fatalf("failed to make new reader: %v", err) } rr, err := vr.VerifyTOC(tocDgst) if err != nil { t.Fatalf("failed to verify TOC: %v", err) } r := rr.(*reader) for _, want := range tt.want { want(t, r, testR) } }) } } } type check func(*testing.T, *reader, *calledReaderAt) type chunkInfo struct { name string data string chunkOffset int64 chunkSize int64 } func hasFileContentsOffset(name string, off int64, contents string, fromCache bool) check { return func(t *testing.T, r *reader, cr *calledReaderAt) { tid, err := lookup(r, name) if err != nil { t.Fatalf("failed to lookup %q", name) } ra, err := r.OpenFile(tid) if err != nil { t.Fatalf("Failed to open testing file: %v", err) } cr.called = nil // reset test buf := make([]byte, len(contents)) n, err := ra.ReadAt(buf, off) if err != nil { t.Fatalf("failed to readat %q: %v", name, err) } if n != len(contents) { t.Fatalf("failed to read contents %q (off:%d, want:%q) got %q", name, off, longBytesView([]byte(contents)), longBytesView(buf)) } if string(buf) != contents { t.Fatalf("unexpected content of %q: %q want %q", name, longBytesView(buf), longBytesView([]byte(contents))) } t.Logf("reader calls for %q: offsets: %+v", name, cr.called) if fromCache { if len(cr.called) != 0 { t.Fatalf("unexpected read on %q: offsets: %v", name, cr.called) } } else { if len(cr.called) == 0 { t.Fatalf("no call happened to reader for %q", name) } } } } func hasFileContentsWithPreCached(name string, off int64, contents string, extra ...chunkInfo) check { return func(t *testing.T, r *reader, cr *calledReaderAt) { tid, err := lookup(r, name) if err != nil { t.Fatalf("failed to lookup %q", name) } ra, err := r.OpenFile(tid) if err != nil { t.Fatalf("Failed to open testing file: %v", err) } buf := make([]byte, len(contents)) n, err := ra.ReadAt(buf, off) if err != nil { t.Fatalf("failed to readat %q: %v", name, err) } if n != len(contents) { t.Fatalf("failed to read contents %q (off:%d, want:%q) got %q", name, off, longBytesView([]byte(contents)), longBytesView(buf)) } if string(buf) != contents { t.Fatalf("unexpected content of %q: %q want %q", name, longBytesView(buf), longBytesView([]byte(contents))) } for _, e := range extra { eid, err := lookup(r, e.name) if err != nil { t.Fatalf("failed to lookup %q", e.name) } cacheID := genID(eid, e.chunkOffset, e.chunkSize) er, err := r.cache.Get(cacheID) if err != nil { t.Fatalf("failed to get cache %q: %+v", cacheID, e) } data, err := io.ReadAll(io.NewSectionReader(er, 0, e.chunkSize)) er.Close() if err != nil { t.Fatalf("failed to read cache %q: %+v", cacheID, e) } if string(data) != e.data { t.Fatalf("unexpected contents of cache %q (%+v): %q; wanted %q", cacheID, e, longBytesView(data), longBytesView([]byte(e.data))) } } } } func lookup(r *reader, name string) (uint32, error) { name = strings.TrimPrefix(path.Clean("/"+name), "/") if name == "" { return r.Metadata().RootID(), nil } dir, base := filepath.Split(name) pid, err := lookup(r, dir) if err != nil { return 0, err } id, _, err := r.Metadata().GetChild(pid, base) return id, err } type calledReaderAt struct { io.ReaderAt called []int64 } func (r *calledReaderAt) ReadAt(p []byte, off int64) (int, error) { r.called = append(r.called, off) return r.ReaderAt.ReadAt(p, off) } // longBytesView is an alias of []byte suitable for printing a long data as an omitted string to avoid long data being printed. type longBytesView []byte func (b longBytesView) String() string { if len(b) < 100 { return string(b) } return string(b[:50]) + "...(omit)..." + string(b[len(b)-50:]) } stargz-snapshotter-0.14.3/fs/remote/000077500000000000000000000000001440204344700173665ustar00rootroot00000000000000stargz-snapshotter-0.14.3/fs/remote/blob.go000066400000000000000000000320241440204344700206340ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /* Copyright 2019 The Go Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the NOTICE.md file. */ package remote import ( "context" "fmt" "io" "regexp" "sort" "strings" "sync" "time" "github.com/containerd/containerd/reference" "github.com/containerd/stargz-snapshotter/cache" "github.com/containerd/stargz-snapshotter/fs/source" ocispec "github.com/opencontainers/image-spec/specs-go/v1" "golang.org/x/sync/errgroup" "golang.org/x/sync/singleflight" ) var contentRangeRegexp = regexp.MustCompile(`bytes ([0-9]+)-([0-9]+)/([0-9]+|\\*)`) type Blob interface { Check() error Size() int64 FetchedSize() int64 ReadAt(p []byte, offset int64, opts ...Option) (int, error) Cache(offset int64, size int64, opts ...Option) error Refresh(ctx context.Context, host source.RegistryHosts, refspec reference.Spec, desc ocispec.Descriptor) error Close() error } type blob struct { fetcher fetcher fetcherMu sync.Mutex size int64 chunkSize int64 prefetchChunkSize int64 cache cache.BlobCache lastCheck time.Time lastCheckMu sync.Mutex checkInterval time.Duration fetchTimeout time.Duration fetchedRegionSet regionSet fetchedRegionSetMu sync.Mutex fetchedRegionGroup singleflight.Group fetchedRegionCopyMu sync.Mutex resolver *Resolver closed bool closedMu sync.Mutex } func makeBlob(fetcher fetcher, size int64, chunkSize int64, prefetchChunkSize int64, blobCache cache.BlobCache, lastCheck time.Time, checkInterval time.Duration, r *Resolver, fetchTimeout time.Duration) *blob { return &blob{ fetcher: fetcher, size: size, chunkSize: chunkSize, prefetchChunkSize: prefetchChunkSize, cache: blobCache, lastCheck: lastCheck, checkInterval: checkInterval, resolver: r, fetchTimeout: fetchTimeout, } } func (b *blob) Close() error { b.closedMu.Lock() defer b.closedMu.Unlock() if b.closed { return nil } b.closed = true return b.cache.Close() } func (b *blob) isClosed() bool { b.closedMu.Lock() closed := b.closed b.closedMu.Unlock() return closed } func (b *blob) Refresh(ctx context.Context, hosts source.RegistryHosts, refspec reference.Spec, desc ocispec.Descriptor) error { if b.isClosed() { return fmt.Errorf("blob is already closed") } // refresh the fetcher f, newSize, err := b.resolver.resolveFetcher(ctx, hosts, refspec, desc) if err != nil { return err } if newSize != b.size { return fmt.Errorf("Invalid size of new blob %d; want %d", newSize, b.size) } // update the blob's fetcher with new one b.fetcherMu.Lock() b.fetcher = f b.fetcherMu.Unlock() b.lastCheckMu.Lock() b.lastCheck = time.Now() b.lastCheckMu.Unlock() return nil } func (b *blob) Check() error { if b.isClosed() { return fmt.Errorf("blob is already closed") } now := time.Now() b.lastCheckMu.Lock() lastCheck := b.lastCheck b.lastCheckMu.Unlock() if now.Sub(lastCheck) < b.checkInterval { // do nothing if not expired return nil } b.fetcherMu.Lock() fr := b.fetcher b.fetcherMu.Unlock() err := fr.check() if err == nil { // update lastCheck only if check succeeded. // on failure, we should check this layer next time again. b.lastCheckMu.Lock() b.lastCheck = now b.lastCheckMu.Unlock() } return err } func (b *blob) Size() int64 { return b.size } func (b *blob) FetchedSize() int64 { b.fetchedRegionSetMu.Lock() sz := b.fetchedRegionSet.totalSize() b.fetchedRegionSetMu.Unlock() return sz } func makeSyncKey(allData map[region]io.Writer) string { keys := make([]string, len(allData)) keysIndex := 0 for key := range allData { keys[keysIndex] = fmt.Sprintf("[%d,%d]", key.b, key.e) keysIndex++ } sort.Strings(keys) return strings.Join(keys, ",") } func (b *blob) cacheAt(offset int64, size int64, fr fetcher, cacheOpts *options) error { fetchReg := region{floor(offset, b.chunkSize), ceil(offset+size-1, b.chunkSize) - 1} discard := make(map[region]io.Writer) err := b.walkChunks(fetchReg, func(reg region) error { if r, err := b.cache.Get(fr.genID(reg), cacheOpts.cacheOpts...); err == nil { return r.Close() // nop if the cache hits } discard[reg] = io.Discard return nil }) if err != nil { return err } return b.fetchRange(discard, cacheOpts) } func (b *blob) Cache(offset int64, size int64, opts ...Option) error { if b.isClosed() { return fmt.Errorf("blob is already closed") } var cacheOpts options for _, o := range opts { o(&cacheOpts) } b.fetcherMu.Lock() fr := b.fetcher b.fetcherMu.Unlock() if b.prefetchChunkSize <= b.chunkSize { return b.cacheAt(offset, size, fr, &cacheOpts) } eg, _ := errgroup.WithContext(context.Background()) fetchSize := b.chunkSize * (b.prefetchChunkSize / b.chunkSize) end := offset + size for i := offset; i < end; i += fetchSize { i, l := i, fetchSize if i+l > end { l = end - i } eg.Go(func() error { return b.cacheAt(i, l, fr, &cacheOpts) }) } return eg.Wait() } // ReadAt reads remote chunks from specified offset for the buffer size. // It tries to fetch as many chunks as possible from local cache. // We can configure this function with options. func (b *blob) ReadAt(p []byte, offset int64, opts ...Option) (int, error) { if b.isClosed() { return 0, fmt.Errorf("blob is already closed") } if len(p) == 0 || offset > b.size { return 0, nil } // Make the buffer chunk aligned allRegion := region{floor(offset, b.chunkSize), ceil(offset+int64(len(p))-1, b.chunkSize) - 1} allData := make(map[region]io.Writer) var readAtOpts options for _, o := range opts { o(&readAtOpts) } // Fetcher can be suddenly updated so we take and use the snapshot of it for // consistency. b.fetcherMu.Lock() fr := b.fetcher b.fetcherMu.Unlock() b.walkChunks(allRegion, func(chunk region) error { var ( base = positive(chunk.b - offset) lowerUnread = positive(offset - chunk.b) upperUnread = positive(chunk.e + 1 - (offset + int64(len(p)))) expectedSize = chunk.size() - upperUnread - lowerUnread ) // Check if the content exists in the cache r, err := b.cache.Get(fr.genID(chunk), readAtOpts.cacheOpts...) if err == nil { defer r.Close() n, err := r.ReadAt(p[base:base+expectedSize], lowerUnread) if (err == nil || err == io.EOF) && int64(n) == expectedSize { return nil } } // We missed cache. Take it from remote registry. // We get the whole chunk here and add it to the cache so that following // reads against neighboring chunks can take the data without making HTTP requests. allData[chunk] = newBytesWriter(p[base:base+expectedSize], lowerUnread) return nil }) // Read required data if err := b.fetchRange(allData, &readAtOpts); err != nil { return 0, err } // Adjust the buffer size according to the blob size if remain := b.size - offset; int64(len(p)) >= remain { if remain < 0 { remain = 0 } p = p[:remain] } return len(p), nil } // fetchRegions fetches all specified chunks from remote blob and puts it in the local cache. // It must be called from within fetchRange and need to ensure that it is inside the singleflight `Do` operation. func (b *blob) fetchRegions(allData map[region]io.Writer, fetched map[region]bool, opts *options) error { if len(allData) == 0 { return nil } // Fetcher can be suddenly updated so we take and use the snapshot of it for // consistency. b.fetcherMu.Lock() fr := b.fetcher b.fetcherMu.Unlock() // request missed regions var req []region for reg := range allData { req = append(req, reg) fetched[reg] = false } fetchCtx, cancel := context.WithTimeout(context.Background(), b.fetchTimeout) defer cancel() if opts.ctx != nil { fetchCtx = opts.ctx } mr, err := fr.fetch(fetchCtx, req, true) if err != nil { return err } defer mr.Close() // Update the check timer because we succeeded to access the blob b.lastCheckMu.Lock() b.lastCheck = time.Now() b.lastCheckMu.Unlock() // chunk and cache responsed data. Regions must be aligned by chunk size. // TODO: Reorganize remoteData to make it be aligned by chunk size for { reg, p, err := mr.Next() if err == io.EOF { break } else if err != nil { return fmt.Errorf("failed to read multipart resp: %w", err) } if err := b.walkChunks(reg, func(chunk region) (retErr error) { id := fr.genID(chunk) cw, err := b.cache.Add(id, opts.cacheOpts...) if err != nil { return err } defer cw.Close() w := io.Writer(cw) // If this chunk is one of the targets, write the content to the // passed reader too. if _, ok := fetched[chunk]; ok { w = io.MultiWriter(w, allData[chunk]) } // Copy the target chunk if _, err := io.CopyN(w, p, chunk.size()); err != nil { cw.Abort() return err } // Add the target chunk to the cache if err := cw.Commit(); err != nil { return err } b.fetchedRegionSetMu.Lock() b.fetchedRegionSet.add(chunk) b.fetchedRegionSetMu.Unlock() fetched[chunk] = true return nil }); err != nil { return fmt.Errorf("failed to get chunks: %w", err) } } // Check all chunks are fetched var unfetched []region for c, b := range fetched { if !b { unfetched = append(unfetched, c) } } if unfetched != nil { return fmt.Errorf("failed to fetch region %v", unfetched) } return nil } // fetchRange fetches all specified chunks from local cache and remote blob. func (b *blob) fetchRange(allData map[region]io.Writer, opts *options) error { if len(allData) == 0 { return nil } // We build a key based on regions we need to fetch and pass it to singleflightGroup.Do(...) // to block simultaneous same requests. Once the request is finished and the data is ready, // all blocked callers will be unblocked and that same data will be returned by all blocked callers. key := makeSyncKey(allData) fetched := make(map[region]bool) _, err, shared := b.fetchedRegionGroup.Do(key, func() (interface{}, error) { return nil, b.fetchRegions(allData, fetched, opts) }) // When unblocked try to read from cache in case if there were no errors // If we fail reading from cache, fetch from remote registry again if err == nil && shared { for reg := range allData { if _, ok := fetched[reg]; ok { continue } err = b.walkChunks(reg, func(chunk region) error { b.fetcherMu.Lock() fr := b.fetcher b.fetcherMu.Unlock() // Check if the content exists in the cache // And if exists, read from cache r, err := b.cache.Get(fr.genID(chunk), opts.cacheOpts...) if err != nil { return err } defer r.Close() rr := io.NewSectionReader(r, 0, chunk.size()) // Copy the target chunk b.fetchedRegionCopyMu.Lock() defer b.fetchedRegionCopyMu.Unlock() if _, err := io.CopyN(allData[chunk], rr, chunk.size()); err != nil { return err } return nil }) if err != nil { break } } // if we cannot read the data from cache, do fetch again if err != nil { return b.fetchRange(allData, opts) } } return err } type walkFunc func(reg region) error // walkChunks walks chunks from begin to end in order in the specified region. // specified region must be aligned by chunk size. func (b *blob) walkChunks(allRegion region, walkFn walkFunc) error { if allRegion.b%b.chunkSize != 0 { return fmt.Errorf("region (%d, %d) must be aligned by chunk size", allRegion.b, allRegion.e) } for i := allRegion.b; i <= allRegion.e && i < b.size; i += b.chunkSize { reg := region{i, i + b.chunkSize - 1} if reg.e >= b.size { reg.e = b.size - 1 } if err := walkFn(reg); err != nil { return err } } return nil } func newBytesWriter(dest []byte, destOff int64) io.Writer { return &bytesWriter{ dest: dest, destOff: destOff, current: 0, } } type bytesWriter struct { dest []byte destOff int64 current int64 } func (bw *bytesWriter) Write(p []byte) (int, error) { defer func() { bw.current = bw.current + int64(len(p)) }() var ( destBase = positive(bw.current - bw.destOff) pBegin = positive(bw.destOff - bw.current) pEnd = positive(bw.destOff + int64(len(bw.dest)) - bw.current) ) if destBase > int64(len(bw.dest)) { return len(p), nil } if pBegin >= int64(len(p)) { return len(p), nil } if pEnd > int64(len(p)) { pEnd = int64(len(p)) } copy(bw.dest[destBase:], p[pBegin:pEnd]) return len(p), nil } func floor(n int64, unit int64) int64 { return (n / unit) * unit } func ceil(n int64, unit int64) int64 { return (n/unit + 1) * unit } func positive(n int64) int64 { if n < 0 { return 0 } return n } stargz-snapshotter-0.14.3/fs/remote/blob_test.go000066400000000000000000000546531440204344700217070ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /* Copyright 2019 The Go Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the NOTICE.md file. */ package remote import ( "bytes" "fmt" "io" "mime" "mime/multipart" "net/http" "net/textproto" "sort" "strconv" "strings" "sync" "sync/atomic" "testing" "time" "github.com/containerd/stargz-snapshotter/cache" ) const ( testURL = "http://testdummy.com/v2/library/test/blobs/sha256:deadbeaf" rangeHeaderPrefix = "bytes=" sampleChunkSize = 3 sampleMiddleOffset = sampleChunkSize / 2 sampleData1 = "0123456789" lastChunkOffset1 = sampleChunkSize * (int64(len(sampleData1)) / sampleChunkSize) defaultPrefetchChunkSize = 0 ) // Tests ReadAt and Cache method of each file. func TestReadAt(t *testing.T) { sizeCond := map[string]int64{ "single_chunk": sampleChunkSize - sampleMiddleOffset, "multi_chunks": 2*sampleChunkSize + sampleMiddleOffset, } innerOffsetCond := map[string]int64{ "at_top": 0, "at_middle": sampleMiddleOffset, } baseOffsetCond := map[string]int64{ "of_1st_chunk": sampleChunkSize * 0, "of_2nd_chunk": sampleChunkSize * 1, "of_last_chunk": sampleChunkSize * (int64(len(sampleData1)) / sampleChunkSize), } blobSizeCond := map[string]int64{ "in_1_chunk_blob": sampleChunkSize * 1, "in_3_chunks_blob": sampleChunkSize * 3, "in_max_size_blob": int64(len(sampleData1)), } prefetchChunkSizeCond := map[string]int64{ "single_get_prefetch": 0, "multiple_get_prefetch": sampleChunkSize * 2, } type cacheCond struct { reg region mustHit bool } transportCond := map[string]struct { allowMultiRange bool cacheCond []cacheCond }{ "with_multi_reg_with_clean_cache": { allowMultiRange: true, cacheCond: nil, }, "with_single_reg_with_clean_cache": { allowMultiRange: false, cacheCond: nil, }, "with_multi_reg_with_edge_filled_cache": { allowMultiRange: true, cacheCond: []cacheCond{ {region{0, sampleChunkSize - 1}, true}, {region{lastChunkOffset1, int64(len(sampleData1)) - 1}, true}, }, }, "with_single_reg_with_edge_filled_cache": { allowMultiRange: false, cacheCond: []cacheCond{ {region{0, sampleChunkSize - 1}, true}, {region{lastChunkOffset1, int64(len(sampleData1)) - 1}, true}, }, }, "with_multi_reg_with_sparse_cache": { allowMultiRange: true, cacheCond: []cacheCond{ {region{0, sampleChunkSize - 1}, true}, {region{2 * sampleChunkSize, 3*sampleChunkSize - 1}, true}, }, }, "with_single_reg_with_sparse_cache": { allowMultiRange: false, cacheCond: []cacheCond{ {region{0, sampleChunkSize - 1}, true}, {region{2 * sampleChunkSize, 3*sampleChunkSize - 1}, false}, }, }, } for sn, size := range sizeCond { for in, innero := range innerOffsetCond { for bo, baseo := range baseOffsetCond { for bs, blobsize := range blobSizeCond { for pc, prefetchchunksize := range prefetchChunkSizeCond { for tc, trCond := range transportCond { t.Run(fmt.Sprintf("reading_%s_%s_%s_%s_%s_%s", sn, in, bo, bs, pc, tc), func(t *testing.T) { if blobsize > int64(len(sampleData1)) { t.Fatal("sample file size is larger than sample data") } wantN := size offset := baseo + innero if remain := blobsize - offset; remain < wantN { if wantN = remain; wantN < 0 { wantN = 0 } } // use constant string value as a data source. want := strings.NewReader(sampleData1) // data we want to get. wantData := make([]byte, wantN) _, err := want.ReadAt(wantData, offset) if err != nil && err != io.EOF { t.Fatalf("want.ReadAt (offset=%d,size=%d): %v", offset, wantN, err) } // data we get through a remote blob. blob := []byte(sampleData1)[:blobsize] // Check with allowing multi range requests var cacheChunks []region var except []region for _, cond := range trCond.cacheCond { cacheChunks = append(cacheChunks, cond.reg) if cond.mustHit { except = append(except, cond.reg) } } tr := multiRoundTripper(t, blob, allowMultiRange(trCond.allowMultiRange), exceptChunks(except)) // Check ReadAt method bb1 := makeTestBlob(t, blobsize, sampleChunkSize, prefetchchunksize, tr) cacheAll(t, bb1, cacheChunks) checkRead(t, wantData, bb1, offset, size) // Check Cache method bb2 := makeTestBlob(t, blobsize, sampleChunkSize, prefetchchunksize, tr) cacheAll(t, bb2, cacheChunks) checkCache(t, bb2, offset, size) }) } } } } } } } func cacheAll(t *testing.T, b *blob, chunks []region) { for _, reg := range chunks { id := b.fetcher.genID(reg) w, err := b.cache.Add(id) if err != nil { w.Close() t.Fatalf("failed to add cache %v: %v", id, err) } if _, err := w.Write([]byte(sampleData1[reg.b : reg.e+1])); err != nil { w.Close() t.Fatalf("failed to write cache %v: %v", id, err) } if err := w.Commit(); err != nil { w.Close() t.Fatalf("failed to commit cache %v: %v", id, err) } w.Close() } } func checkRead(t *testing.T, wantData []byte, r *blob, offset int64, wantSize int64) { respData := make([]byte, wantSize) t.Logf("reading offset:%d, size:%d", offset, wantSize) n, err := r.ReadAt(respData, offset) if err != nil { t.Errorf("failed to read off=%d, size=%d, blobsize=%d: %v", offset, wantSize, r.Size(), err) return } respData = respData[:n] if !bytes.Equal(wantData, respData) { t.Errorf("off=%d, blobsize=%d; read data{size=%d,data=%q}; want (size=%d,data=%q)", offset, r.Size(), len(respData), string(respData), len(wantData), string(wantData)) return } // check cache has valid contents. checkAllCached(t, r, offset, wantSize) } func checkCache(t *testing.T, r *blob, offset int64, size int64) { if err := r.Cache(offset, size); err != nil { t.Errorf("failed to cache off=%d, size=%d, blobsize=%d: %v", offset, size, r.Size(), err) return } // check cache has valid contents. checkAllCached(t, r, offset, size) } func checkAllCached(t *testing.T, r *blob, offset, size int64) { cn := 0 whole := region{floor(offset, r.chunkSize), ceil(offset+size-1, r.chunkSize) - 1} if err := r.walkChunks(whole, func(reg region) error { data := make([]byte, reg.size()) id := r.fetcher.genID(reg) r, err := r.cache.Get(id) if err != nil { return fmt.Errorf("missed cache of region={%d,%d}(size=%d): %v", reg.b, reg.e, reg.size(), err) } defer r.Close() if n, err := r.ReadAt(data, 0); (err != nil && err != io.EOF) || int64(n) != reg.size() { return fmt.Errorf("failed to read cache of region={%d,%d}(size=%d): %v", reg.b, reg.e, reg.size(), err) } cn++ return nil }); err != nil { t.Errorf("%v", err) return } } // Tests ReadAt method for failure cases. func TestFailReadAt(t *testing.T) { // test failed http respose. r := makeTestBlob(t, int64(len(sampleData1)), sampleChunkSize, defaultPrefetchChunkSize, failRoundTripper()) respData := make([]byte, len(sampleData1)) _, err := r.ReadAt(respData, 0) if err == nil || err == io.EOF { t.Errorf("must be fail for http failure but err=%v", err) return } // test broken body with allowing multi range checkBrokenBody(t, true) // with allowing multi range checkBrokenBody(t, false) // with prohibiting multi range // test broken header checkBrokenHeader(t, true) // with allowing multi range checkBrokenHeader(t, false) // with prohibiting multi range } func checkBrokenBody(t *testing.T, allowMultiRange bool) { respData := make([]byte, len(sampleData1)) r := makeTestBlob(t, int64(len(sampleData1)), sampleChunkSize, defaultPrefetchChunkSize, brokenBodyRoundTripper(t, []byte(sampleData1), allowMultiRange)) if _, err := r.ReadAt(respData, 0); err == nil || err == io.EOF { t.Errorf("must be fail for broken full body but err=%v (allowMultiRange=%v)", err, allowMultiRange) return } r = makeTestBlob(t, int64(len(sampleData1)), sampleChunkSize, defaultPrefetchChunkSize, brokenBodyRoundTripper(t, []byte(sampleData1), allowMultiRange)) if _, err := r.ReadAt(respData[0:len(sampleData1)/2], 0); err == nil || err == io.EOF { t.Errorf("must be fail for broken multipart body but err=%v (allowMultiRange=%v)", err, allowMultiRange) return } } func checkBrokenHeader(t *testing.T, allowMultiRange bool) { r := makeTestBlob(t, int64(len(sampleData1)), sampleChunkSize, defaultPrefetchChunkSize, brokenHeaderRoundTripper(t, []byte(sampleData1), allowMultiRange)) respData := make([]byte, len(sampleData1)) if _, err := r.ReadAt(respData[0:len(sampleData1)/2], 0); err == nil || err == io.EOF { t.Errorf("must be fail for broken multipart header but err=%v (allowMultiRange=%v)", err, allowMultiRange) return } } func TestParallelDownloadingBehavior(t *testing.T) { type regionsBoundaries struct { regions []region start int64 end int64 } type testData struct { name string regions [3]regionsBoundaries roundtripCount int64 chunkSize int64 content string } tests := []testData{ { name: "no_data", regions: [3]regionsBoundaries{}, roundtripCount: 0, chunkSize: 4, }, { name: "same_regions", regions: [3]regionsBoundaries{ { regions: []region{ { b: 0, e: 3, }, }, start: 0, end: 3, }, { regions: []region{ { b: 0, e: 3, }, }, start: 0, end: 3, }, { regions: []region{ { b: 0, e: 3, }, }, start: 0, end: 3, }, }, roundtripCount: 1, chunkSize: 4, content: "test", }, { name: "same_regions_multiple_values", regions: [3]regionsBoundaries{ { regions: []region{ { b: 0, e: 3, }, { b: 4, e: 7, }, }, start: 0, end: 7, }, { regions: []region{ { b: 0, e: 3, }, { b: 4, e: 7, }, }, start: 0, end: 7, }, { regions: []region{ { b: 0, e: 3, }, { b: 4, e: 7, }, }, start: 0, end: 7, }, }, roundtripCount: 1, chunkSize: 4, content: "test1234", }, { name: "different_regions", regions: [3]regionsBoundaries{ { regions: []region{ { b: 0, e: 3, }, }, start: 0, end: 3, }, { regions: []region{ { b: 4, e: 7, }, }, start: 4, end: 7, }, { regions: []region{ { b: 8, e: 11, }, }, start: 8, end: 11, }, }, roundtripCount: 3, chunkSize: 4, content: "test12345678", }, { name: "some_overlap", regions: [3]regionsBoundaries{ { regions: []region{ { b: 0, e: 3, }, }, start: 0, end: 3, }, { regions: []region{ { b: 0, e: 3, }, }, start: 0, end: 3, }, { regions: []region{ { b: 4, e: 7, }, }, start: 4, end: 7, }, }, roundtripCount: 2, chunkSize: 4, content: "test1234", }, } var wg sync.WaitGroup // we always run 3 routines routines := 3 for _, tst := range tests { var ( tr = &callsCountRoundTripper{ content: tst.content, } b = &blob{ fetcher: &httpFetcher{ url: "test", tr: tr, }, chunkSize: tst.chunkSize, size: int64(len(tst.content)), cache: cache.NewMemoryCache(), } ) start := make(chan struct{}) wg.Add(routines) var contentBytes [3][]byte for i := 0; i < routines; i++ { p := make([]byte, len(tst.content)) contentBytes[i] = p allData := make(map[region]io.Writer) if i < len(tst.regions) { offset := int64(0) for j := range tst.regions[i].regions { r := tst.regions[i].regions[j] var ( base = positive(r.b - offset) lowerUnread = positive(offset - r.b) upperUnread = positive(r.e + 1 - (offset + int64(len(p)))) expectedSize = r.size() - upperUnread - lowerUnread ) allData[tst.regions[i].regions[j]] = newBytesWriter(p[base:base+expectedSize], lowerUnread) } } go func() { <-start // by blocking on channel start we can ensure that the goroutines will run at approximately the same time defer wg.Done() b.fetchRange(allData, &options{}) }() } close(start) // starting wg.Wait() // We expect the number of round trip calls to be 1, since we are making 5 calls to fetchRange with // overlapping intervals. if tr.count != tst.roundtripCount { t.Errorf("%v test failed: the round trip count should be %v, but was %v", tst.name, tst.roundtripCount, tr.count) } // Check for contents for j := range contentBytes { start := tst.regions[j].start end := tst.regions[j].end for i := start; i < end; i++ { if contentBytes[j][i] != []byte(tst.content)[i] { t.Errorf("%v test failed: the output sequence is wrong, wanted %v, got %v", tst.name, []byte(tst.content)[start:end], contentBytes[j][start:end]) break } } } } } func makeTestBlob(t *testing.T, size int64, chunkSize int64, prefetchChunkSize int64, fn RoundTripFunc) *blob { var ( lastCheck time.Time checkInterval time.Duration ) return makeBlob( &httpFetcher{ url: testURL, tr: fn, }, size, chunkSize, prefetchChunkSize, cache.NewMemoryCache(), lastCheck, checkInterval, &Resolver{}, time.Duration(defaultFetchTimeoutSec)*time.Second) } func TestCheckInterval(t *testing.T) { var ( tr = &calledRoundTripper{} firstTime = time.Now() b = &blob{ fetcher: &httpFetcher{ url: "test", tr: tr, }, lastCheck: firstTime, } ) check := func(name string, checkInterval time.Duration) (time.Time, bool) { beforeUpdate := time.Now() time.Sleep(time.Millisecond) tr.called = false b.checkInterval = checkInterval if err := b.Check(); err != nil { t.Fatalf("%q: check mustn't be failed", name) } time.Sleep(time.Millisecond) afterUpdate := time.Now() if !tr.called { return b.lastCheck, false } if !(b.lastCheck.After(beforeUpdate) && b.lastCheck.Before(afterUpdate)) { t.Errorf("%q: updated time must be after %q and before %q but %q", name, beforeUpdate, afterUpdate, b.lastCheck) } return b.lastCheck, true } // second time(not expired yet) secondTime, called := check("second time", time.Hour) if called { t.Error("mustn't be checked if not expired") } if !secondTime.Equal(firstTime) { t.Errorf("lastCheck time must be same as first time(%q) but %q", firstTime, secondTime) } // third time(expired, must be checked) if _, called := check("third time", 0); !called { t.Error("must be called for the third time") } } type callsCountRoundTripper struct { count int64 content string } func (c *callsCountRoundTripper) RoundTrip(req *http.Request) (res *http.Response, err error) { atomic.AddInt64(&c.count, 1) time.Sleep(50 * time.Millisecond) // sleep for 50 milliseconds to emulate the http call and to make sure that we can run tests on parallel goroutines convertBody := func(r io.ReadCloser) io.ReadCloser { return r } header := make(http.Header) header.Add("Content-Length", fmt.Sprintf("%d", len(c.content))) return &http.Response{ StatusCode: http.StatusOK, Header: header, Body: convertBody(io.NopCloser(bytes.NewReader([]byte(c.content)))), }, nil } type calledRoundTripper struct { called bool } func (c *calledRoundTripper) RoundTrip(req *http.Request) (res *http.Response, err error) { c.called = true res = &http.Response{ StatusCode: http.StatusOK, Header: make(http.Header), Body: io.NopCloser(bytes.NewReader([]byte("test"))), } return } type RoundTripFunc func(req *http.Request) *http.Response func (f RoundTripFunc) RoundTrip(req *http.Request) (*http.Response, error) { return f(req), nil } type bodyConverter func(r io.ReadCloser) io.ReadCloser type exceptChunks []region type allowMultiRange bool func multiRoundTripper(t *testing.T, contents []byte, opts ...interface{}) RoundTripFunc { multiRangeEnable := true doNotFetch := []region{} convertBody := func(r io.ReadCloser) io.ReadCloser { return r } for _, opt := range opts { if v, ok := opt.(allowMultiRange); ok { multiRangeEnable = bool(v) } else if v, ok := opt.(exceptChunks); ok { doNotFetch = []region(v) } else if v, ok := opt.(bodyConverter); ok { convertBody = (func(r io.ReadCloser) io.ReadCloser)(v) } } emptyResponse := func(statusCode int) *http.Response { return &http.Response{ StatusCode: statusCode, Header: make(http.Header), Body: io.NopCloser(bytes.NewReader([]byte{})), } } return func(req *http.Request) *http.Response { // Validate request if req.Method != "GET" || req.URL.String() != testURL { return emptyResponse(http.StatusBadRequest) } ranges := req.Header.Get("Range") if ranges == "" { return emptyResponse(http.StatusBadRequest) } if !strings.HasPrefix(ranges, rangeHeaderPrefix) { return emptyResponse(http.StatusBadRequest) } rlist := strings.Split(ranges[len(rangeHeaderPrefix):], ",") if len(rlist) == 0 { return emptyResponse(http.StatusBadRequest) } // check this request can be served as one whole blob. var sorted []region for _, part := range rlist { begin, end := parseRangeString(t, part) sorted = append(sorted, region{begin, end}) } sort.Slice(sorted, func(i, j int) bool { return sorted[i].b < sorted[j].b }) var sparse bool if sorted[0].b == 0 { var max int64 for _, reg := range sorted { if reg.e > max { if max < reg.b-1 { sparse = true break } max = reg.e } } if max >= int64(len(contents)-1) && !sparse { t.Logf("serving whole range %q = %d", ranges, len(contents)) header := make(http.Header) header.Add("Content-Length", fmt.Sprintf("%d", len(contents))) return &http.Response{ StatusCode: http.StatusOK, Header: header, Body: convertBody(io.NopCloser(bytes.NewReader(contents))), } } } if !multiRangeEnable { if len(rlist) > 1 { return emptyResponse(http.StatusBadRequest) // prohibiting multi range } // serve as single part response begin, end := parseRangeString(t, rlist[0]) target := region{begin, end} for _, reg := range doNotFetch { if target.b <= reg.b && reg.e <= target.e { t.Fatalf("Requested prohibited region of chunk(singlepart): (%d, %d) contained in fetching region (%d, %d)", reg.b, reg.e, target.b, target.e) } } header := make(http.Header) header.Add("Content-Length", fmt.Sprintf("%d", target.size())) header.Add("Content-Range", fmt.Sprintf("bytes %d-%d/%d", target.b, target.e, len(contents))) header.Add("Content-Type", "application/octet-stream") part := contents[target.b : target.e+1] return &http.Response{ StatusCode: http.StatusPartialContent, Header: header, Body: convertBody(io.NopCloser(bytes.NewReader(part))), } } // Write multipart response. var buf bytes.Buffer mw := multipart.NewWriter(&buf) for _, part := range rlist { mh := make(textproto.MIMEHeader) mh.Set("Content-Range", fmt.Sprintf("bytes %s/%d", part, len(contents))) w, err := mw.CreatePart(mh) if err != nil { t.Fatalf("failed to create part: %v", err) } begin, end := parseRangeString(t, part) if begin >= int64(len(contents)) { // skip if out of range. continue } if end > int64(len(contents)-1) { end = int64(len(contents) - 1) } for _, reg := range doNotFetch { if begin <= reg.b && reg.e <= end { t.Fatalf("Requested prohibited region of chunk (multipart): (%d, %d) contained in fetching region (%d, %d)", reg.b, reg.e, begin, end) } } if n, err := w.Write(contents[begin : end+1]); err != nil || int64(n) != end+1-begin { t.Fatalf("failed to write to part(%d-%d): %v", begin, end, err) } } mw.Close() param := map[string]string{ "boundary": mw.Boundary(), } header := make(http.Header) header.Add("Content-Type", mime.FormatMediaType("multipart/text", param)) return &http.Response{ StatusCode: http.StatusPartialContent, Header: header, Body: convertBody(io.NopCloser(&buf)), } } } func failRoundTripper() RoundTripFunc { return func(req *http.Request) *http.Response { return &http.Response{ StatusCode: http.StatusInternalServerError, Header: make(http.Header), Body: io.NopCloser(bytes.NewReader([]byte{})), } } } func brokenBodyRoundTripper(t *testing.T, contents []byte, multiRange bool) RoundTripFunc { breakReadCloser := func(r io.ReadCloser) io.ReadCloser { defer r.Close() data, err := io.ReadAll(r) if err != nil { t.Fatalf("failed to break read closer faild to read original: %v", err) } return io.NopCloser(bytes.NewReader(data[:len(data)/2])) } tr := multiRoundTripper(t, contents, allowMultiRange(multiRange), bodyConverter(breakReadCloser)) return func(req *http.Request) *http.Response { return tr(req) } } func brokenHeaderRoundTripper(t *testing.T, contents []byte, multiRange bool) RoundTripFunc { tr := multiRoundTripper(t, contents, allowMultiRange(multiRange)) return func(req *http.Request) *http.Response { res := tr(req) res.Header = make(http.Header) return res } } func parseRangeString(t *testing.T, rangeString string) (int64, int64) { rng := strings.Split(rangeString, "-") if len(rng) != 2 { t.Fatalf("falied to parse range %q", rng) } begin, err := strconv.ParseInt(rng[0], 10, 64) if err != nil { t.Fatalf("failed to parse beginning offset: %v", err) } end, err := strconv.ParseInt(rng[1], 10, 64) if err != nil { t.Fatalf("failed to parse ending offset: %v", err) } return begin, end } stargz-snapshotter-0.14.3/fs/remote/resolver.go000066400000000000000000000505511440204344700215640ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /* Copyright 2019 The Go Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the NOTICE.md file. */ package remote import ( "context" "crypto/sha256" "fmt" "io" "math/rand" "mime" "mime/multipart" "net/http" "path" "strconv" "strings" "sync" "time" "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/log" "github.com/containerd/containerd/reference" "github.com/containerd/containerd/remotes/docker" "github.com/containerd/stargz-snapshotter/cache" "github.com/containerd/stargz-snapshotter/fs/config" commonmetrics "github.com/containerd/stargz-snapshotter/fs/metrics/common" "github.com/containerd/stargz-snapshotter/fs/source" "github.com/hashicorp/go-multierror" rhttp "github.com/hashicorp/go-retryablehttp" digest "github.com/opencontainers/go-digest" ocispec "github.com/opencontainers/image-spec/specs-go/v1" ) const ( defaultChunkSize = 50000 defaultValidIntervalSec = 60 defaultFetchTimeoutSec = 300 defaultMaxRetries = 5 defaultMinWaitMSec = 30 defaultMaxWaitMSec = 300000 ) func NewResolver(cfg config.BlobConfig, handlers map[string]Handler) *Resolver { if cfg.ChunkSize == 0 { // zero means "use default chunk size" cfg.ChunkSize = defaultChunkSize } if cfg.ValidInterval == 0 { // zero means "use default interval" cfg.ValidInterval = defaultValidIntervalSec } if cfg.CheckAlways { cfg.ValidInterval = 0 } if cfg.FetchTimeoutSec == 0 { cfg.FetchTimeoutSec = defaultFetchTimeoutSec } if cfg.MaxRetries == 0 { cfg.MaxRetries = defaultMaxRetries } if cfg.MinWaitMSec == 0 { cfg.MinWaitMSec = defaultMinWaitMSec } if cfg.MaxWaitMSec == 0 { cfg.MaxWaitMSec = defaultMaxWaitMSec } return &Resolver{ blobConfig: cfg, handlers: handlers, } } type Resolver struct { blobConfig config.BlobConfig handlers map[string]Handler } type fetcher interface { fetch(ctx context.Context, rs []region, retry bool) (multipartReadCloser, error) check() error genID(reg region) string } func (r *Resolver) Resolve(ctx context.Context, hosts source.RegistryHosts, refspec reference.Spec, desc ocispec.Descriptor, blobCache cache.BlobCache) (Blob, error) { f, size, err := r.resolveFetcher(ctx, hosts, refspec, desc) if err != nil { return nil, err } blobConfig := &r.blobConfig return makeBlob(f, size, blobConfig.ChunkSize, blobConfig.PrefetchChunkSize, blobCache, time.Now(), time.Duration(blobConfig.ValidInterval)*time.Second, r, time.Duration(blobConfig.FetchTimeoutSec)*time.Second), nil } func (r *Resolver) resolveFetcher(ctx context.Context, hosts source.RegistryHosts, refspec reference.Spec, desc ocispec.Descriptor) (f fetcher, size int64, err error) { blobConfig := &r.blobConfig fc := &fetcherConfig{ hosts: hosts, refspec: refspec, desc: desc, maxRetries: blobConfig.MaxRetries, minWaitMSec: time.Duration(blobConfig.MinWaitMSec) * time.Millisecond, maxWaitMSec: time.Duration(blobConfig.MaxWaitMSec) * time.Millisecond, } var handlersErr error for name, p := range r.handlers { // TODO: allow to configure the selection of readers based on the hostname in refspec r, size, err := p.Handle(ctx, desc) if err != nil { handlersErr = multierror.Append(handlersErr, err) continue } log.G(ctx).WithField("handler name", name).WithField("ref", refspec.String()).WithField("digest", desc.Digest). Debugf("contents is provided by a handler") return &remoteFetcher{r}, size, nil } log.G(ctx).WithError(handlersErr).WithField("ref", refspec.String()).WithField("digest", desc.Digest).Debugf("using default handler") hf, size, err := newHTTPFetcher(ctx, fc) if err != nil { return nil, 0, err } if blobConfig.ForceSingleRangeMode { hf.singleRangeMode() } return hf, size, err } type fetcherConfig struct { hosts source.RegistryHosts refspec reference.Spec desc ocispec.Descriptor maxRetries int minWaitMSec time.Duration maxWaitMSec time.Duration } func jitter(duration time.Duration) time.Duration { if duration <= 0 { return duration } return time.Duration(rand.Int63n(int64(duration)) + int64(duration)) } // backoffStrategy extends retryablehttp's DefaultBackoff to add a random jitter to avoid overwhelming the repository // when it comes back online // DefaultBackoff either tries to parse the 'Retry-After' header of the response; or, it uses an exponential backoff // 2 ^ numAttempts, limited by max func backoffStrategy(min, max time.Duration, attemptNum int, resp *http.Response) time.Duration { delayTime := rhttp.DefaultBackoff(min, max, attemptNum, resp) return jitter(delayTime) } // retryStrategy extends retryablehttp's DefaultRetryPolicy to debug log the error when retrying // DefaultRetryPolicy retries whenever err is non-nil (except for some url errors) or if returned // status code is 429 or 5xx (except 501) func retryStrategy(ctx context.Context, resp *http.Response, err error) (bool, error) { retry, err2 := rhttp.DefaultRetryPolicy(ctx, resp, err) if retry { log.G(ctx).WithError(err).Debugf("Retrying request") } return retry, err2 } func newHTTPFetcher(ctx context.Context, fc *fetcherConfig) (*httpFetcher, int64, error) { reghosts, err := fc.hosts(fc.refspec) if err != nil { return nil, 0, err } desc := fc.desc if desc.Digest.String() == "" { return nil, 0, fmt.Errorf("Digest is mandatory in layer descriptor") } digest := desc.Digest pullScope, err := docker.RepositoryScope(fc.refspec, false) if err != nil { return nil, 0, err } // Try to create fetcher until succeeded rErr := fmt.Errorf("failed to resolve") for _, host := range reghosts { if host.Host == "" || strings.Contains(host.Host, "/") { rErr = fmt.Errorf("invalid destination (host %q, ref:%q, digest:%q): %w", host.Host, fc.refspec, digest, rErr) continue // Try another } // Prepare transport with authorization functionality tr := host.Client.Transport if rt, ok := tr.(*rhttp.RoundTripper); ok { rt.Client.RetryMax = fc.maxRetries rt.Client.RetryWaitMin = fc.minWaitMSec rt.Client.RetryWaitMax = fc.maxWaitMSec rt.Client.Backoff = backoffStrategy rt.Client.CheckRetry = retryStrategy } timeout := host.Client.Timeout if host.Authorizer != nil { tr = &transport{ inner: tr, auth: host.Authorizer, scope: pullScope, } } // Resolve redirection and get blob URL blobURL := fmt.Sprintf("%s://%s/%s/blobs/%s", host.Scheme, path.Join(host.Host, host.Path), strings.TrimPrefix(fc.refspec.Locator, fc.refspec.Hostname()+"/"), digest) url, header, err := redirect(ctx, blobURL, tr, timeout, host.Header) if err != nil { rErr = fmt.Errorf("failed to redirect (host %q, ref:%q, digest:%q): %v: %w", host.Host, fc.refspec, digest, err, rErr) continue // Try another } // Get size information // TODO: we should try to use the Size field in the descriptor here. start := time.Now() // start time before getting layer header size, err := getSize(ctx, url, tr, timeout, header) commonmetrics.MeasureLatencyInMilliseconds(commonmetrics.StargzHeaderGet, digest, start) // time to get layer header if err != nil { rErr = fmt.Errorf("failed to get size (host %q, ref:%q, digest:%q): %v: %w", host.Host, fc.refspec, digest, err, rErr) continue // Try another } // Hit one destination return &httpFetcher{ url: url, tr: tr, blobURL: blobURL, digest: digest, timeout: timeout, header: header, orgHeader: host.Header, }, size, nil } return nil, 0, fmt.Errorf("cannot resolve layer: %w", rErr) } type transport struct { inner http.RoundTripper auth docker.Authorizer scope string } func (tr *transport) RoundTrip(req *http.Request) (*http.Response, error) { ctx := docker.WithScope(req.Context(), tr.scope) roundTrip := func(req *http.Request) (*http.Response, error) { // authorize the request using docker.Authorizer if err := tr.auth.Authorize(ctx, req); err != nil { return nil, err } // send the request return tr.inner.RoundTrip(req) } resp, err := roundTrip(req) if err != nil { return nil, err } // TODO: support more status codes and retries if resp.StatusCode == http.StatusUnauthorized { log.G(ctx).Infof("Received status code: %v. Refreshing creds...", resp.Status) // prepare authorization for the target host using docker.Authorizer if err := tr.auth.AddResponses(ctx, []*http.Response{resp}); err != nil { if errdefs.IsNotImplemented(err) { return resp, nil } return nil, err } // re-authorize and send the request return roundTrip(req.Clone(ctx)) } return resp, nil } func redirect(ctx context.Context, blobURL string, tr http.RoundTripper, timeout time.Duration, header http.Header) (url string, withHeader http.Header, err error) { if timeout > 0 { var cancel context.CancelFunc ctx, cancel = context.WithTimeout(ctx, timeout) defer cancel() } // We use GET request for redirect. // gcr.io returns 200 on HEAD without Location header (2020). // ghcr.io returns 200 on HEAD without Location header (2020). req, err := http.NewRequestWithContext(ctx, "GET", blobURL, nil) if err != nil { return "", nil, fmt.Errorf("failed to make request to the registry: %w", err) } req.Header = http.Header{} for k, v := range header { req.Header[k] = v } req.Close = false req.Header.Set("Range", "bytes=0-1") res, err := tr.RoundTrip(req) if err != nil { return "", nil, fmt.Errorf("failed to request: %w", err) } defer func() { io.Copy(io.Discard, res.Body) res.Body.Close() }() if res.StatusCode/100 == 2 { url = blobURL withHeader = header } else if redir := res.Header.Get("Location"); redir != "" && res.StatusCode/100 == 3 { // TODO: Support nested redirection url = redir // Do not pass headers to the redirected location. } else { return "", nil, fmt.Errorf("failed to access to the registry with code %v", res.StatusCode) } return } func getSize(ctx context.Context, url string, tr http.RoundTripper, timeout time.Duration, header http.Header) (int64, error) { if timeout > 0 { var cancel context.CancelFunc ctx, cancel = context.WithTimeout(ctx, timeout) defer cancel() } req, err := http.NewRequestWithContext(ctx, "HEAD", url, nil) if err != nil { return 0, err } req.Header = http.Header{} for k, v := range header { req.Header[k] = v } req.Close = false res, err := tr.RoundTrip(req) if err != nil { return 0, err } defer res.Body.Close() if res.StatusCode == http.StatusOK { return strconv.ParseInt(res.Header.Get("Content-Length"), 10, 64) } headStatusCode := res.StatusCode // Failed to do HEAD request. Fall back to GET. // ghcr.io (https://github-production-container-registry.s3.amazonaws.com) doesn't allow // HEAD request (2020). req, err = http.NewRequestWithContext(ctx, "GET", url, nil) if err != nil { return 0, fmt.Errorf("failed to make request to the registry: %w", err) } req.Header = http.Header{} for k, v := range header { req.Header[k] = v } req.Close = false req.Header.Set("Range", "bytes=0-1") res, err = tr.RoundTrip(req) if err != nil { return 0, fmt.Errorf("failed to request: %w", err) } defer func() { io.Copy(io.Discard, res.Body) res.Body.Close() }() if res.StatusCode == http.StatusOK { return strconv.ParseInt(res.Header.Get("Content-Length"), 10, 64) } else if res.StatusCode == http.StatusPartialContent { _, size, err := parseRange(res.Header.Get("Content-Range")) return size, err } return 0, fmt.Errorf("failed to get size with code (HEAD=%v, GET=%v)", headStatusCode, res.StatusCode) } type httpFetcher struct { url string urlMu sync.Mutex tr http.RoundTripper blobURL string digest digest.Digest singleRange bool singleRangeMu sync.Mutex timeout time.Duration header http.Header orgHeader http.Header } type multipartReadCloser interface { Next() (region, io.Reader, error) Close() error } func (f *httpFetcher) fetch(ctx context.Context, rs []region, retry bool) (multipartReadCloser, error) { if len(rs) == 0 { return nil, fmt.Errorf("no request queried") } var ( tr = f.tr singleRangeMode = f.isSingleRangeMode() ) // squash requesting chunks for reducing the total size of request header // (servers generally have limits for the size of headers) // TODO: when our request has too many ranges, we need to divide it into // multiple requests to avoid huge header. var s regionSet for _, reg := range rs { s.add(reg) } requests := s.rs if singleRangeMode { // Squash requests if the layer doesn't support multi range. requests = []region{superRegion(requests)} } // Request to the registry f.urlMu.Lock() url := f.url f.urlMu.Unlock() req, err := http.NewRequestWithContext(ctx, "GET", url, nil) if err != nil { return nil, err } req.Header = http.Header{} for k, v := range f.header { req.Header[k] = v } var ranges string for _, reg := range requests { ranges += fmt.Sprintf("%d-%d,", reg.b, reg.e) } req.Header.Add("Range", fmt.Sprintf("bytes=%s", ranges[:len(ranges)-1])) req.Header.Add("Accept-Encoding", "identity") req.Close = false // Recording the roundtrip latency for remote registry GET operation. start := time.Now() res, err := tr.RoundTrip(req) // NOT DefaultClient; don't want redirects commonmetrics.MeasureLatencyInMilliseconds(commonmetrics.RemoteRegistryGet, f.digest, start) if err != nil { return nil, err } if res.StatusCode == http.StatusOK { // We are getting the whole blob in one part (= status 200) size, err := strconv.ParseInt(res.Header.Get("Content-Length"), 10, 64) if err != nil { return nil, fmt.Errorf("failed to parse Content-Length: %w", err) } return newSinglePartReader(region{0, size - 1}, res.Body), nil } else if res.StatusCode == http.StatusPartialContent { mediaType, params, err := mime.ParseMediaType(res.Header.Get("Content-Type")) if err != nil { return nil, fmt.Errorf("invalid media type %q: %w", mediaType, err) } if strings.HasPrefix(mediaType, "multipart/") { // We are getting a set of chunks as a multipart body. return newMultiPartReader(res.Body, params["boundary"]), nil } // We are getting single range reg, _, err := parseRange(res.Header.Get("Content-Range")) if err != nil { return nil, fmt.Errorf("failed to parse Content-Range: %w", err) } return newSinglePartReader(reg, res.Body), nil } else if retry && res.StatusCode == http.StatusForbidden { log.G(ctx).Infof("Received status code: %v. Refreshing URL and retrying...", res.Status) // re-redirect and retry this once. if err := f.refreshURL(ctx); err != nil { return nil, fmt.Errorf("failed to refresh URL on %v: %w", res.Status, err) } return f.fetch(ctx, rs, false) } else if retry && res.StatusCode == http.StatusBadRequest && !singleRangeMode { log.G(ctx).Infof("Received status code: %v. Setting single range mode and retrying...", res.Status) // gcr.io (https://storage.googleapis.com) returns 400 on multi-range request (2020 #81) f.singleRangeMode() // fallbacks to singe range request mode return f.fetch(ctx, rs, false) // retries with the single range mode } return nil, fmt.Errorf("unexpected status code: %v", res.Status) } func (f *httpFetcher) check() error { ctx := context.Background() if f.timeout > 0 { var cancel context.CancelFunc ctx, cancel = context.WithTimeout(ctx, f.timeout) defer cancel() } f.urlMu.Lock() url := f.url f.urlMu.Unlock() req, err := http.NewRequestWithContext(ctx, "GET", url, nil) if err != nil { return fmt.Errorf("check failed: failed to make request: %w", err) } req.Header = http.Header{} for k, v := range f.header { req.Header[k] = v } req.Close = false req.Header.Set("Range", "bytes=0-1") res, err := f.tr.RoundTrip(req) if err != nil { return fmt.Errorf("check failed: failed to request to registry: %w", err) } defer func() { io.Copy(io.Discard, res.Body) res.Body.Close() }() if res.StatusCode == http.StatusOK || res.StatusCode == http.StatusPartialContent { return nil } else if res.StatusCode == http.StatusForbidden { // Try to re-redirect this blob rCtx := context.Background() if f.timeout > 0 { var rCancel context.CancelFunc rCtx, rCancel = context.WithTimeout(rCtx, f.timeout) defer rCancel() } if err := f.refreshURL(rCtx); err == nil { return nil } return fmt.Errorf("failed to refresh URL on status %v", res.Status) } return fmt.Errorf("unexpected status code %v", res.StatusCode) } func (f *httpFetcher) refreshURL(ctx context.Context) error { newURL, headers, err := redirect(ctx, f.blobURL, f.tr, f.timeout, f.orgHeader) if err != nil { return err } f.urlMu.Lock() f.url = newURL f.header = headers f.urlMu.Unlock() return nil } func (f *httpFetcher) genID(reg region) string { sum := sha256.Sum256([]byte(fmt.Sprintf("%s-%d-%d", f.blobURL, reg.b, reg.e))) return fmt.Sprintf("%x", sum) } func (f *httpFetcher) singleRangeMode() { f.singleRangeMu.Lock() f.singleRange = true f.singleRangeMu.Unlock() } func (f *httpFetcher) isSingleRangeMode() bool { f.singleRangeMu.Lock() r := f.singleRange f.singleRangeMu.Unlock() return r } func newSinglePartReader(reg region, rc io.ReadCloser) multipartReadCloser { return &singlepartReader{ r: rc, Closer: rc, reg: reg, } } type singlepartReader struct { io.Closer r io.Reader reg region called bool } func (sr *singlepartReader) Next() (region, io.Reader, error) { if !sr.called { sr.called = true return sr.reg, sr.r, nil } return region{}, nil, io.EOF } func newMultiPartReader(rc io.ReadCloser, boundary string) multipartReadCloser { return &multipartReader{ m: multipart.NewReader(rc, boundary), Closer: rc, } } type multipartReader struct { io.Closer m *multipart.Reader } func (sr *multipartReader) Next() (region, io.Reader, error) { p, err := sr.m.NextPart() if err != nil { return region{}, nil, err } reg, _, err := parseRange(p.Header.Get("Content-Range")) if err != nil { return region{}, nil, fmt.Errorf("failed to parse Content-Range: %w", err) } return reg, p, nil } func parseRange(header string) (region, int64, error) { submatches := contentRangeRegexp.FindStringSubmatch(header) if len(submatches) < 4 { return region{}, 0, fmt.Errorf("Content-Range %q doesn't have enough information", header) } begin, err := strconv.ParseInt(submatches[1], 10, 64) if err != nil { return region{}, 0, fmt.Errorf("failed to parse beginning offset %q: %w", submatches[1], err) } end, err := strconv.ParseInt(submatches[2], 10, 64) if err != nil { return region{}, 0, fmt.Errorf("failed to parse end offset %q: %w", submatches[2], err) } blobSize, err := strconv.ParseInt(submatches[3], 10, 64) if err != nil { return region{}, 0, fmt.Errorf("failed to parse blob size %q: %w", submatches[3], err) } return region{begin, end}, blobSize, nil } type Option func(*options) type options struct { ctx context.Context cacheOpts []cache.Option } func WithContext(ctx context.Context) Option { return func(opts *options) { opts.ctx = ctx } } func WithCacheOpts(cacheOpts ...cache.Option) Option { return func(opts *options) { opts.cacheOpts = cacheOpts } } type remoteFetcher struct { r Fetcher } func (r *remoteFetcher) fetch(ctx context.Context, rs []region, retry bool) (multipartReadCloser, error) { var s regionSet for _, reg := range rs { s.add(reg) } reg := superRegion(s.rs) rc, err := r.r.Fetch(ctx, reg.b, reg.size()) if err != nil { return nil, err } return newSinglePartReader(reg, rc), nil } func (r *remoteFetcher) check() error { return r.r.Check() } func (r *remoteFetcher) genID(reg region) string { return r.r.GenID(reg.b, reg.size()) } type Handler interface { Handle(ctx context.Context, desc ocispec.Descriptor) (fetcher Fetcher, size int64, err error) } type Fetcher interface { Fetch(ctx context.Context, off int64, size int64) (io.ReadCloser, error) Check() error GenID(off int64, size int64) string } stargz-snapshotter-0.14.3/fs/remote/resolver_test.go000066400000000000000000000342501440204344700226210ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /* Copyright 2019 The Go Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the NOTICE.md file. */ package remote import ( "bytes" "context" "fmt" "io" "net/http" "net/url" "regexp" "strings" "testing" "github.com/containerd/containerd/reference" "github.com/containerd/containerd/remotes/docker" "github.com/containerd/stargz-snapshotter/fs/source" rhttp "github.com/hashicorp/go-retryablehttp" digest "github.com/opencontainers/go-digest" ocispec "github.com/opencontainers/image-spec/specs-go/v1" ) func TestMirror(t *testing.T) { ref := "dummyexample.com/library/test" refspec, err := reference.Parse(ref) if err != nil { t.Fatalf("failed to prepare dummy reference: %v", err) } var ( blobDigest = digest.FromString("dummy") blobPath = fmt.Sprintf("/v2/%s/blobs/%s", strings.TrimPrefix(refspec.Locator, refspec.Hostname()+"/"), blobDigest.String()) refHost = refspec.Hostname() ) tests := []struct { name string hosts func(t *testing.T) source.RegistryHosts wantHost string error bool }{ { name: "no-mirror", hosts: hostsConfig( &sampleRoundTripper{okURLs: []string{refHost}}, ), wantHost: refHost, }, { name: "valid-mirror", hosts: hostsConfig( &sampleRoundTripper{okURLs: []string{"mirrorexample.com"}}, hostSimple("mirrorexample.com"), ), wantHost: "mirrorexample.com", }, { name: "invalid-mirror", hosts: hostsConfig( &sampleRoundTripper{ withCode: map[string]int{ "mirrorexample1.com": http.StatusInternalServerError, "mirrorexample2.com": http.StatusUnauthorized, "mirrorexample3.com": http.StatusNotFound, }, okURLs: []string{"mirrorexample4.com", refHost}, }, hostSimple("mirrorexample1.com"), hostSimple("mirrorexample2.com"), hostSimple("mirrorexample3.com"), hostSimple("mirrorexample4.com"), ), wantHost: "mirrorexample4.com", }, { name: "invalid-all-mirror", hosts: hostsConfig( &sampleRoundTripper{ withCode: map[string]int{ "mirrorexample1.com": http.StatusInternalServerError, "mirrorexample2.com": http.StatusUnauthorized, "mirrorexample3.com": http.StatusNotFound, }, okURLs: []string{refHost}, }, hostSimple("mirrorexample1.com"), hostSimple("mirrorexample2.com"), hostSimple("mirrorexample3.com"), ), wantHost: refHost, }, { name: "invalid-hostname-of-mirror", hosts: hostsConfig( &sampleRoundTripper{ okURLs: []string{`.*`}, }, hostSimple("mirrorexample.com/somepath/"), ), wantHost: refHost, }, { name: "redirected-mirror", hosts: hostsConfig( &sampleRoundTripper{ redirectURL: map[string]string{ regexp.QuoteMeta(fmt.Sprintf("mirrorexample.com%s", blobPath)): "https://backendexample.com/blobs/" + blobDigest.String(), }, okURLs: []string{`.*`}, }, hostSimple("mirrorexample.com"), ), wantHost: "backendexample.com", }, { name: "invalid-redirected-mirror", hosts: hostsConfig( &sampleRoundTripper{ withCode: map[string]int{ "backendexample.com": http.StatusInternalServerError, }, redirectURL: map[string]string{ regexp.QuoteMeta(fmt.Sprintf("mirrorexample.com%s", blobPath)): "https://backendexample.com/blobs/" + blobDigest.String(), }, okURLs: []string{`.*`}, }, hostSimple("mirrorexample.com"), ), wantHost: refHost, }, { name: "fail-all", hosts: hostsConfig( &sampleRoundTripper{}, hostSimple("mirrorexample.com"), ), wantHost: "", error: true, }, { name: "headers", hosts: hostsConfig( &sampleRoundTripper{ okURLs: []string{`.*`}, wantHeaders: map[string]http.Header{ "mirrorexample.com": http.Header(map[string][]string{ "test-a-key": {"a-value-1", "a-value-2"}, "test-b-key": {"b-value-1"}, }), }, }, hostWithHeaders("mirrorexample.com", map[string][]string{ "test-a-key": {"a-value-1", "a-value-2"}, "test-b-key": {"b-value-1"}, }), ), wantHost: "mirrorexample.com", }, { name: "headers-with-mirrors", hosts: hostsConfig( &sampleRoundTripper{ withCode: map[string]int{ "mirrorexample1.com": http.StatusInternalServerError, "mirrorexample2.com": http.StatusInternalServerError, }, okURLs: []string{"mirrorexample3.com", refHost}, wantHeaders: map[string]http.Header{ "mirrorexample1.com": http.Header(map[string][]string{ "test-a-key": {"a-value"}, }), "mirrorexample2.com": http.Header(map[string][]string{ "test-b-key": {"b-value"}, "test-b-key-2": {"b-value-2", "b-value-3"}, }), "mirrorexample3.com": http.Header(map[string][]string{ "test-c-key": {"c-value"}, }), }, }, hostWithHeaders("mirrorexample1.com", map[string][]string{ "test-a-key": {"a-value"}, }), hostWithHeaders("mirrorexample2.com", map[string][]string{ "test-b-key": {"b-value"}, "test-b-key-2": {"b-value-2", "b-value-3"}, }), hostWithHeaders("mirrorexample3.com", map[string][]string{ "test-c-key": {"c-value"}, }), ), wantHost: "mirrorexample3.com", }, { name: "headers-with-mirrors-invalid-all", hosts: hostsConfig( &sampleRoundTripper{ withCode: map[string]int{ "mirrorexample1.com": http.StatusInternalServerError, "mirrorexample2.com": http.StatusInternalServerError, }, okURLs: []string{"mirrorexample3.com", refHost}, wantHeaders: map[string]http.Header{ "mirrorexample1.com": http.Header(map[string][]string{ "test-a-key": {"a-value"}, }), "mirrorexample2.com": http.Header(map[string][]string{ "test-b-key": {"b-value"}, "test-b-key-2": {"b-value-2", "b-value-3"}, }), }, }, hostWithHeaders("mirrorexample1.com", map[string][]string{ "test-a-key": {"a-value"}, }), hostWithHeaders("mirrorexample2.com", map[string][]string{ "test-b-key": {"b-value"}, "test-b-key-2": {"b-value-2", "b-value-3"}, }), ), wantHost: refHost, }, { name: "headers-with-redirected-mirror", hosts: hostsConfig( &sampleRoundTripper{ redirectURL: map[string]string{ regexp.QuoteMeta(fmt.Sprintf("mirrorexample.com%s", blobPath)): "https://backendexample.com/blobs/" + blobDigest.String(), }, okURLs: []string{`.*`}, wantHeaders: map[string]http.Header{ "mirrorexample.com": http.Header(map[string][]string{ "test-a-key": {"a-value"}, "test-b-key-2": {"b-value-2", "b-value-3"}, }), }, }, hostWithHeaders("mirrorexample.com", map[string][]string{ "test-a-key": {"a-value"}, "test-b-key-2": {"b-value-2", "b-value-3"}, }), ), wantHost: "backendexample.com", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { fetcher, _, err := newHTTPFetcher(context.Background(), &fetcherConfig{ hosts: tt.hosts(t), refspec: refspec, desc: ocispec.Descriptor{Digest: blobDigest}, }) if err != nil { if tt.error { return } t.Fatalf("failed to resolve reference: %v", err) } checkFetcherURL(t, fetcher, tt.wantHost) // Test check() if err := fetcher.check(); err != nil { t.Fatalf("failed to check fetcher: %v", err) } // Test refreshURL() if err := fetcher.refreshURL(context.TODO()); err != nil { t.Fatalf("failed to refresh URL: %v", err) } checkFetcherURL(t, fetcher, tt.wantHost) }) } } func checkFetcherURL(t *testing.T, f *httpFetcher, wantHost string) { nurl, err := url.Parse(f.url) if err != nil { t.Fatalf("failed to parse url %q: %v", f.url, err) } if nurl.Hostname() != wantHost { t.Errorf("invalid hostname %q(%q); want %q", nurl.Hostname(), nurl.String(), wantHost) } } type sampleRoundTripper struct { t *testing.T withCode map[string]int redirectURL map[string]string okURLs []string wantHeaders map[string]http.Header } func getTestHeaders(headers map[string][]string) map[string][]string { res := make(map[string][]string) for k, v := range headers { if strings.HasPrefix(k, "test-") { res[k] = v } } return res } func (tr *sampleRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) { reqHeader := getTestHeaders(req.Header) for host, wHeaders := range tr.wantHeaders { wantHeader := getTestHeaders(wHeaders) if ok, _ := regexp.Match(host, []byte(req.URL.String())); ok { if len(wantHeader) != len(reqHeader) { tr.t.Fatalf("unexpected num of headers; got %d, wanted %d", len(wantHeader), len(reqHeader)) } for k, v := range wantHeader { gotV, ok := reqHeader[k] if !ok { tr.t.Fatalf("required header %q not found; got %+v", k, reqHeader) } wantVM := make(map[string]struct{}) for _, e := range v { wantVM[e] = struct{}{} } if len(gotV) != len(v) { tr.t.Fatalf("unexpected num of header values of %q; got %d, wanted %d", k, len(gotV), len(v)) } for _, gotE := range gotV { delete(wantVM, gotE) } if len(wantVM) != 0 { tr.t.Fatalf("header %q must have elements %+v", k, wantVM) } delete(reqHeader, k) } } } if len(reqHeader) != 0 { tr.t.Fatalf("unexpected headers %+v", reqHeader) } for host, code := range tr.withCode { if ok, _ := regexp.Match(host, []byte(req.URL.String())); ok { return &http.Response{ StatusCode: code, Header: make(http.Header), Body: io.NopCloser(bytes.NewReader([]byte{})), Request: req, }, nil } } for host, rurl := range tr.redirectURL { if ok, _ := regexp.Match(host, []byte(req.URL.String())); ok { header := make(http.Header) header.Add("Location", rurl) return &http.Response{ StatusCode: http.StatusMovedPermanently, Header: header, Body: io.NopCloser(bytes.NewReader([]byte{})), Request: req, }, nil } } for _, host := range tr.okURLs { if ok, _ := regexp.Match(host, []byte(req.URL.String())); ok { header := make(http.Header) header.Add("Content-Length", "1") return &http.Response{ StatusCode: http.StatusOK, Header: header, Body: io.NopCloser(bytes.NewReader([]byte{0})), Request: req, }, nil } } return &http.Response{ StatusCode: http.StatusNotFound, Header: make(http.Header), Body: io.NopCloser(bytes.NewReader([]byte{})), Request: req, }, nil } func TestCheck(t *testing.T) { tr := &breakRoundTripper{} f := &httpFetcher{ url: "test", tr: tr, } tr.success = true if err := f.check(); err != nil { t.Errorf("connection failed; wanted to succeed") } tr.success = false if err := f.check(); err == nil { t.Errorf("connection succeeded; wanted to fail") } } type breakRoundTripper struct { success bool } func (b *breakRoundTripper) RoundTrip(req *http.Request) (res *http.Response, err error) { if b.success { res = &http.Response{ StatusCode: http.StatusPartialContent, Header: make(http.Header), Body: io.NopCloser(bytes.NewReader([]byte("test"))), } } else { res = &http.Response{ StatusCode: http.StatusInternalServerError, Header: make(http.Header), Body: io.NopCloser(bytes.NewReader([]byte{})), } } return } func TestRetry(t *testing.T) { tr := &retryRoundTripper{} rclient := rhttp.NewClient() rclient.HTTPClient.Transport = tr rclient.Backoff = backoffStrategy f := &httpFetcher{ url: "test", tr: &rhttp.RoundTripper{Client: rclient}, } regions := []region{{b: 0, e: 1}} _, err := f.fetch(context.Background(), regions, true) if err != nil { t.Fatalf("unexpected error = %v", err) } if tr.retryCount != 4 { t.Fatalf("unxpected retryCount; expected=4 got=%d", tr.retryCount) } } type retryRoundTripper struct { retryCount int } func (r *retryRoundTripper) RoundTrip(req *http.Request) (res *http.Response, err error) { defer func() { r.retryCount++ }() switch r.retryCount { case 0: err = fmt.Errorf("dummy error") case 1: res = &http.Response{ StatusCode: http.StatusTooManyRequests, Header: make(http.Header), Body: io.NopCloser(bytes.NewReader([]byte{})), } case 2: res = &http.Response{ StatusCode: http.StatusServiceUnavailable, Header: make(http.Header), Body: io.NopCloser(bytes.NewReader([]byte{})), } default: header := make(http.Header) header.Add("Content-Length", "4") res = &http.Response{ StatusCode: http.StatusOK, Header: header, Body: io.NopCloser(bytes.NewReader([]byte("test"))), } } return } type hostFactory func(tr http.RoundTripper) docker.RegistryHost func hostSimple(host string) hostFactory { return func(tr http.RoundTripper) docker.RegistryHost { return docker.RegistryHost{ Client: &http.Client{Transport: tr}, Host: host, Scheme: "https", Path: "/v2", Capabilities: docker.HostCapabilityPull, } } } func hostWithHeaders(host string, headers http.Header) hostFactory { return func(tr http.RoundTripper) docker.RegistryHost { return docker.RegistryHost{ Client: &http.Client{Transport: tr}, Host: host, Scheme: "https", Path: "/v2", Capabilities: docker.HostCapabilityPull, Header: headers, } } } func hostsConfig(tr *sampleRoundTripper, mirrors ...hostFactory) func(t *testing.T) source.RegistryHosts { return func(t *testing.T) source.RegistryHosts { tr.t = t return func(refspec reference.Spec) (reghosts []docker.RegistryHost, _ error) { host := refspec.Hostname() for _, m := range mirrors { reghosts = append(reghosts, m(tr)) } reghosts = append(reghosts, hostSimple(host)(tr)) return } } } stargz-snapshotter-0.14.3/fs/remote/util.go000066400000000000000000000060151440204344700206740ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /* Copyright 2019 The Go Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the NOTICE.md file. */ package remote // region is HTTP-range-request-compliant range. // "b" is beginning byte of the range and "e" is the end. // "e" is must be inclusive along with HTTP's range expression. type region struct{ b, e int64 } func (c region) size() int64 { return c.e - c.b + 1 } func superRegion(regs []region) region { s := regs[0] for _, reg := range regs { if reg.b < s.b { s.b = reg.b } if reg.e > s.e { s.e = reg.e } } return s } // regionSet is a set of regions type regionSet struct { rs []region // must be kept sorted } // add attempts to merge r to rs.rs with squashing the regions as // small as possible. This operation takes O(n). // TODO: more efficient way to do it. func (rs *regionSet) add(r region) { // Iterate over the sorted region slice from the tail. // a) When an overwrap occurs, adjust `r` to fully contain the looking region // `l` and remove `l` from region slice. // b) Once l.e become less than r.b, no overwrap will occur again. So immediately // insert `r` which fully contains all overwrapped regions, to the region slice. // Here, `r` is inserted to the region slice with keeping it sorted, without // overwrapping to any regions. // *) If any `l` contains `r`, we don't need to do anything so return immediately. for i := len(rs.rs) - 1; i >= 0; i-- { l := &rs.rs[i] // *) l contains r if l.b <= r.b && r.e <= l.e { return } // a) r overwraps to l so adjust r to fully contain l and reomve l // from region slice. if l.b <= r.b && r.b <= l.e+1 && l.e <= r.e { r.b = l.b rs.rs = append(rs.rs[:i], rs.rs[i+1:]...) continue } if r.b <= l.b && l.b <= r.e+1 && r.e <= l.e { r.e = l.e rs.rs = append(rs.rs[:i], rs.rs[i+1:]...) continue } if r.b <= l.b && l.e <= r.e { rs.rs = append(rs.rs[:i], rs.rs[i+1:]...) continue } // b) No overwrap will occur after this iteration. Instert r to the // region slice immediately. if l.e < r.b { rs.rs = append(rs.rs[:i+1], append([]region{r}, rs.rs[i+1:]...)...) return } // No overwrap occurs yet. See the next region. } // r is the topmost region among regions in the slice. rs.rs = append([]region{r}, rs.rs...) } func (rs *regionSet) totalSize() int64 { var sz int64 for _, f := range rs.rs { sz += f.size() } return sz } stargz-snapshotter-0.14.3/fs/remote/util_test.go000066400000000000000000000043271440204344700217370ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /* Copyright 2019 The Go Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the NOTICE.md file. */ package remote import ( "reflect" "testing" ) func TestRegionSet(t *testing.T) { tests := []struct { input []region expected []region }{ { input: []region{{1, 3}, {2, 4}}, expected: []region{{1, 4}}, }, { input: []region{{1, 5}, {2, 4}}, expected: []region{{1, 5}}, }, { input: []region{{2, 4}, {1, 5}}, expected: []region{{1, 5}}, }, { input: []region{{2, 4}, {6, 8}, {1, 5}}, expected: []region{{1, 8}}, }, { input: []region{{1, 2}, {1, 2}}, expected: []region{{1, 2}}, }, { input: []region{{1, 3}, {1, 2}}, expected: []region{{1, 3}}, }, { input: []region{{1, 3}, {2, 3}}, expected: []region{{1, 3}}, }, { input: []region{{1, 3}, {3, 6}}, expected: []region{{1, 6}}, }, { input: []region{{1, 3}, {4, 6}}, // region.e is inclusive expected: []region{{1, 6}}, }, { input: []region{{4, 6}, {1, 3}}, // region.e is inclusive expected: []region{{1, 6}}, }, { input: []region{{4, 6}, {1, 3}, {7, 9}, {2, 8}}, expected: []region{{1, 9}}, }, { input: []region{{4, 6}, {1, 5}, {7, 9}, {4, 8}}, expected: []region{{1, 9}}, }, { input: []region{{7, 8}, {1, 2}, {5, 6}}, expected: []region{{1, 2}, {5, 8}}, }, } for i, tt := range tests { var rs regionSet for _, f := range tt.input { rs.add(f) } if !reflect.DeepEqual(tt.expected, rs.rs) { t.Errorf("#%d: expected %v, got %v", i, tt.expected, rs.rs) } } } stargz-snapshotter-0.14.3/fs/source/000077500000000000000000000000001440204344700173735ustar00rootroot00000000000000stargz-snapshotter-0.14.3/fs/source/source.go000066400000000000000000000225101440204344700212220ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package source import ( "context" "fmt" "strings" "github.com/containerd/containerd/images" "github.com/containerd/containerd/labels" "github.com/containerd/containerd/reference" "github.com/containerd/containerd/remotes/docker" "github.com/containerd/stargz-snapshotter/fs/config" digest "github.com/opencontainers/go-digest" ocispec "github.com/opencontainers/image-spec/specs-go/v1" ) // GetSources is a function for converting snapshot labels into typed blob sources // information. This package defines a default converter which provides source // information based on some labels but implementations aren't required to use labels. // Implementations are allowed to return several sources (registry config + image refs) // about the blob. type GetSources func(labels map[string]string) (source []Source, err error) // RegistryHosts returns a list of registries that provides the specified image. type RegistryHosts func(reference.Spec) ([]docker.RegistryHost, error) // Source is a typed blob source information. This contains information about // a blob stored in registries and some contexts of the blob. type Source struct { // Hosts is a registry configuration where this blob is stored. Hosts RegistryHosts // Name is an image reference which contains this blob. Name reference.Spec // Target is a descriptor of this blob. Target ocispec.Descriptor // Manifest is an image manifest which contains the blob. This will // be used by the filesystem to pre-resolve some layers contained in // the manifest. // Currently, only layer digests (Manifest.Layers.Digest) will be used. Manifest ocispec.Manifest } const ( // targetRefLabel is a label which contains image reference. targetRefLabel = "containerd.io/snapshot/remote/stargz.reference" // targetDigestLabel is a label which contains layer digest. targetDigestLabel = "containerd.io/snapshot/remote/stargz.digest" // targetImageLayersLabel is a label which contains layer digests contained in // the target image. targetImageLayersLabel = "containerd.io/snapshot/remote/stargz.layers" // targetImageURLsLabelPrefix is a label prefix which constructs a map from the layer index to // urls of the layer descriptor. targetImageURLsLabelPrefix = "containerd.io/snapshot/remote/urls." // targetURsLLabel is a label which contains layer URL. This is only used to pass URL from containerd // to snapshotter. targetURLsLabel = "containerd.io/snapshot/remote/urls" ) // FromDefaultLabels returns a function for converting snapshot labels to // source information based on labels. func FromDefaultLabels(hosts RegistryHosts) GetSources { return func(labels map[string]string) ([]Source, error) { refStr, ok := labels[targetRefLabel] if !ok { return nil, fmt.Errorf("reference hasn't been passed") } refspec, err := reference.Parse(refStr) if err != nil { return nil, err } digestStr, ok := labels[targetDigestLabel] if !ok { return nil, fmt.Errorf("digest hasn't been passed") } target, err := digest.Parse(digestStr) if err != nil { return nil, err } var neighboringLayers []ocispec.Descriptor if l, ok := labels[targetImageLayersLabel]; ok { layersStr := strings.Split(l, ",") for i, l := range layersStr { d, err := digest.Parse(l) if err != nil { return nil, err } if d.String() != target.String() { desc := ocispec.Descriptor{Digest: d} if urls, ok := labels[targetImageURLsLabelPrefix+fmt.Sprintf("%d", i)]; ok { desc.URLs = strings.Split(urls, ",") } neighboringLayers = append(neighboringLayers, desc) } } } targetDesc := ocispec.Descriptor{ Digest: target, Annotations: labels, } if targetURLs, ok := labels[targetURLsLabel]; ok { targetDesc.URLs = append(targetDesc.URLs, strings.Split(targetURLs, ",")...) } return []Source{ { Hosts: hosts, Name: refspec, Target: targetDesc, Manifest: ocispec.Manifest{Layers: append([]ocispec.Descriptor{targetDesc}, neighboringLayers...)}, }, }, nil } } // AppendDefaultLabelsHandlerWrapper makes a handler which appends image's basic // information to each layer descriptor as annotations during unpack. These // annotations will be passed to this remote snapshotter as labels and used to // construct source information. func AppendDefaultLabelsHandlerWrapper(ref string, prefetchSize int64) func(f images.Handler) images.Handler { return func(f images.Handler) images.Handler { return images.HandlerFunc(func(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) { children, err := f.Handle(ctx, desc) if err != nil { return nil, err } switch desc.MediaType { case ocispec.MediaTypeImageManifest, images.MediaTypeDockerSchema2Manifest: for i := range children { c := &children[i] if images.IsLayerType(c.MediaType) { if c.Annotations == nil { c.Annotations = make(map[string]string) } c.Annotations[targetRefLabel] = ref c.Annotations[targetDigestLabel] = c.Digest.String() var layers string for i, l := range children[i:] { if images.IsLayerType(l.MediaType) { ls := fmt.Sprintf("%s,", l.Digest.String()) // This avoids the label hits the size limitation. // Skipping layers is allowed here and only affects performance. if err := labels.Validate(targetImageLayersLabel, layers+ls); err != nil { break } layers += ls // Store URLs of the neighbouring layer as well. urlsKey := targetImageURLsLabelPrefix + fmt.Sprintf("%d", i) c.Annotations[urlsKey] = appendWithValidation(urlsKey, l.URLs) } } c.Annotations[targetImageLayersLabel] = strings.TrimSuffix(layers, ",") c.Annotations[config.TargetPrefetchSizeLabel] = fmt.Sprintf("%d", prefetchSize) // store URL in annotation to let containerd to pass it to the snapshotter c.Annotations[targetURLsLabel] = appendWithValidation(targetURLsLabel, c.URLs) } } } return children, nil }) } } func appendWithValidation(key string, values []string) string { var v string for _, u := range values { s := fmt.Sprintf("%s,", u) if err := labels.Validate(key, v+s); err != nil { break } v += s } return strings.TrimSuffix(v, ",") } // TODO: switch to "github.com/containerd/containerd/pkg/snapshotters" once all tools using // // stargz-snapshotter (e.g. k3s) move to containerd version where that pkg is available. const ( // targetImageLayersLabel is a label which contains layer digests contained in // the target image and will be passed to snapshotters for preparing layers in // parallel. Skipping some layers is allowed and only affects performance. targetImageLayersLabelContainerd = "containerd.io/snapshot/cri.image-layers" ) // AppendExtraLabelsHandler adds optional labels that aren't provided by // "github.com/containerd/containerd/pkg/snapshotters" but can be used for stargz snapshotter's extra functionalities. func AppendExtraLabelsHandler(prefetchSize int64, wrapper func(images.Handler) images.Handler) func(images.Handler) images.Handler { return func(f images.Handler) images.Handler { return images.HandlerFunc(func(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) { children, err := wrapper(f).Handle(ctx, desc) if err != nil { return nil, err } switch desc.MediaType { case ocispec.MediaTypeImageManifest, images.MediaTypeDockerSchema2Manifest: for i := range children { c := &children[i] if !images.IsLayerType(c.MediaType) { continue } if _, ok := c.Annotations[targetURLsLabel]; !ok { // nop if this key is already set c.Annotations[targetURLsLabel] = appendWithValidation(targetURLsLabel, c.URLs) } if _, ok := c.Annotations[config.TargetPrefetchSizeLabel]; !ok { // nop if this key is already set c.Annotations[config.TargetPrefetchSizeLabel] = fmt.Sprintf("%d", prefetchSize) } // Store URLs of the neighbouring layer as well. nlayers, ok := c.Annotations[targetImageLayersLabelContainerd] if !ok { continue } for j, dstr := range strings.Split(nlayers, ",") { d, err := digest.Parse(dstr) if err != nil { return nil, err } l, ok := layerFromDigest(children, d) if !ok { continue } urlsKey := targetImageURLsLabelPrefix + fmt.Sprintf("%d", j) if _, ok := c.Annotations[urlsKey]; !ok { // nop if this key is already set c.Annotations[urlsKey] = appendWithValidation(urlsKey, l.URLs) } } } } return children, nil }) } } func layerFromDigest(layers []ocispec.Descriptor, target digest.Digest) (ocispec.Descriptor, bool) { for _, l := range layers { if l.Digest == target { return l, images.IsLayerType(l.MediaType) } } return ocispec.Descriptor{}, false } stargz-snapshotter-0.14.3/go.mod000066400000000000000000000123571440204344700166010ustar00rootroot00000000000000module github.com/containerd/stargz-snapshotter go 1.19 require ( github.com/containerd/console v1.0.3 github.com/containerd/containerd v1.7.0-rc.2 github.com/containerd/continuity v0.3.0 github.com/containerd/stargz-snapshotter/estargz v0.14.3 github.com/docker/cli v23.0.1+incompatible github.com/docker/go-metrics v0.0.1 github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da github.com/hanwen/go-fuse/v2 v2.2.0 github.com/hashicorp/go-multierror v1.1.1 github.com/hashicorp/go-retryablehttp v0.7.2 github.com/klauspost/compress v1.16.0 github.com/moby/sys/mountinfo v0.6.2 github.com/opencontainers/go-digest v1.0.0 github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b github.com/opencontainers/runtime-spec v1.1.0-rc.1 github.com/prometheus/client_golang v1.14.0 github.com/rs/xid v1.4.0 github.com/sirupsen/logrus v1.9.0 golang.org/x/sync v0.1.0 golang.org/x/sys v0.6.0 google.golang.org/grpc v1.53.0 google.golang.org/protobuf v1.28.1 k8s.io/api v0.26.2 k8s.io/apimachinery v0.26.2 k8s.io/client-go v0.26.2 k8s.io/cri-api v0.27.0-alpha.3 ) require ( github.com/AdaLogics/go-fuzz-headers v0.0.0-20230106234847-43070de90fa1 // indirect github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20221215162035-5330a85ea652 // indirect github.com/Microsoft/go-winio v0.6.0 // indirect github.com/Microsoft/hcsshim v0.10.0-rc.7 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/containerd/cgroups v1.1.0 // indirect github.com/containerd/cgroups/v3 v3.0.1 // indirect github.com/containerd/fifo v1.1.0 // indirect github.com/containerd/go-cni v1.1.9 // indirect github.com/containerd/ttrpc v1.2.0 // indirect github.com/containerd/typeurl/v2 v2.1.0 // indirect github.com/containernetworking/cni v1.1.2 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect github.com/cyphar/filepath-securejoin v0.2.3 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/docker/docker v20.10.20+incompatible // indirect github.com/docker/docker-credential-helpers v0.7.0 // indirect github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c // indirect github.com/emicklei/go-restful/v3 v3.10.1 // indirect github.com/go-logr/logr v1.2.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-openapi/jsonpointer v0.19.5 // indirect github.com/go-openapi/jsonreference v0.20.0 // indirect github.com/go-openapi/swag v0.19.14 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.2 // indirect github.com/google/gnostic v0.5.7-v3refs // indirect github.com/google/go-cmp v0.5.9 // indirect github.com/google/gofuzz v1.2.0 // indirect github.com/google/uuid v1.3.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/imdario/mergo v0.3.13 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/mailru/easyjson v0.7.6 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/moby/locker v1.0.1 // indirect github.com/moby/sys/sequential v0.5.0 // indirect github.com/moby/sys/signal v0.7.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/opencontainers/runc v1.1.4 // indirect github.com/opencontainers/selinux v1.11.0 // indirect github.com/pelletier/go-toml v1.9.5 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_model v0.3.0 // indirect github.com/prometheus/common v0.37.0 // indirect github.com/prometheus/procfs v0.8.0 // indirect github.com/rogpeppe/go-internal v1.9.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/stretchr/testify v1.8.2 // indirect github.com/urfave/cli v1.22.12 // indirect github.com/vbatts/tar-split v0.11.2 // indirect go.etcd.io/bbolt v1.3.7 // indirect go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/otel v1.12.0 // indirect go.opentelemetry.io/otel/trace v1.12.0 // indirect golang.org/x/mod v0.7.0 // indirect golang.org/x/net v0.7.0 // indirect golang.org/x/oauth2 v0.4.0 // indirect golang.org/x/term v0.5.0 // indirect golang.org/x/text v0.7.0 // indirect golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 // indirect golang.org/x/tools v0.5.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect gotest.tools/v3 v3.4.0 // indirect k8s.io/klog/v2 v2.90.1 // indirect k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 // indirect k8s.io/utils v0.0.0-20230220204549-a5ecb0141aa5 // indirect sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect sigs.k8s.io/yaml v1.3.0 // indirect ) // Import local package for estargz. replace github.com/containerd/stargz-snapshotter/estargz => ./estargz stargz-snapshotter-0.14.3/go.sum000066400000000000000000002237021440204344700166240ustar00rootroot00000000000000cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/AdaLogics/go-fuzz-headers v0.0.0-20230106234847-43070de90fa1 h1:EKPd1INOIyr5hWOWhvpmQpY6tKjeG0hT1s3AMC/9fic= github.com/AdaLogics/go-fuzz-headers v0.0.0-20230106234847-43070de90fa1/go.mod h1:VzwV+t+dZ9j/H867F1M2ziD+yLHtB46oM35FxxMJ4d0= github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20221215162035-5330a85ea652 h1:+vTEFqeoeur6XSq06bs+roX3YiT49gUniJK7Zky7Xjg= github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20221215162035-5330a85ea652/go.mod h1:OahwfttHWG6eJ0clwcfBAHoDI6X/LV/15hx/wlMZSrU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg= github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE= github.com/Microsoft/hcsshim v0.10.0-rc.7 h1:HBytQPxcv8Oy4244zbQbe6hnOnx544eL5QPUqhJldz8= github.com/Microsoft/hcsshim v0.10.0-rc.7/go.mod h1:ILuwjA+kNW+MrN/w5un7n3mTqkwsFu4Bp05/okFUZlE= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/cilium/ebpf v0.7.0/go.mod h1:/oI2+1shJiTGAMgl6/RgJr36Eo1jzrRcAWbcXO2usCA= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM= github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw= github.com/containerd/cgroups/v3 v3.0.1 h1:4hfGvu8rfGIwVIDd+nLzn/B9ZXx4BcCjzt5ToenJRaE= github.com/containerd/cgroups/v3 v3.0.1/go.mod h1:/vtwk1VXrtoa5AaZLkypuOJgA/6DyPMZHJPGQNtlHnw= github.com/containerd/console v1.0.3 h1:lIr7SlA5PxZyMV30bDW0MGbiOPXwc63yRuCP0ARubLw= github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U= github.com/containerd/containerd v1.7.0-rc.2 h1:Me1LnvqNQPl56LrVpVkNiQPPLomEKgZi2wKbe6ixx6w= github.com/containerd/containerd v1.7.0-rc.2/go.mod h1:N8hwWslQgbkbPIQulOL9Qgsw5x7VWZppXQLZburjSso= github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg= github.com/containerd/continuity v0.3.0/go.mod h1:wJEAIwKOm/pBZuBd0JmeTvnLquTB1Ag8espWhkykbPM= github.com/containerd/fifo v1.1.0 h1:4I2mbh5stb1u6ycIABlBw9zgtlK8viPI9QkQNRQEEmY= github.com/containerd/fifo v1.1.0/go.mod h1:bmC4NWMbXlt2EZ0Hc7Fx7QzTFxgPID13eH0Qu+MAb2o= github.com/containerd/go-cni v1.1.9 h1:ORi7P1dYzCwVM6XPN4n3CbkuOx/NZ2DOqy+SHRdo9rU= github.com/containerd/go-cni v1.1.9/go.mod h1:XYrZJ1d5W6E2VOvjffL3IZq0Dz6bsVlERHbekNK90PM= github.com/containerd/ttrpc v1.2.0 h1:we4O9wzVsBA1HUVRGU8CWFsbjy2P/U2g9raVu5XXNI0= github.com/containerd/ttrpc v1.2.0/go.mod h1:YYyNVhZrTMiaf51Vj6WhAJqJw+vl/nzABhj8pWrzle4= github.com/containerd/typeurl/v2 v2.1.0 h1:yNAhJvbNEANt7ck48IlEGOxP7YAp6LLpGn5jZACDNIE= github.com/containerd/typeurl/v2 v2.1.0/go.mod h1:IDp2JFvbwZ31H8dQbEIY7sDl2L3o3HZj1hsSQlywkQ0= github.com/containernetworking/cni v1.1.2 h1:wtRGZVv7olUHMOqouPpn3cXJWpJgM6+EUl31EQbXALQ= github.com/containernetworking/cni v1.1.2/go.mod h1:sDpYKmGVENF3s6uvMvGgldDWeG8dMxakj/u+i9ht9vw= github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cyphar/filepath-securejoin v0.2.3 h1:YX6ebbZCZP7VkM3scTTokDgBL2TY741X51MTk3ycuNI= github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/docker/cli v23.0.1+incompatible h1:LRyWITpGzl2C9e9uGxzisptnxAn1zfZKXy13Ul2Q5oM= github.com/docker/cli v23.0.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/docker v20.10.20+incompatible h1:kH9tx6XO+359d+iAkumyKDc5Q1kOwPuAUaeri48nD6E= github.com/docker/docker v20.10.20+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A= github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0= github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c h1:+pKlWGMw7gf6bQ+oDZB4KHQFypsfjYlq/C4rfL7D3g8= github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA= github.com/docker/go-metrics v0.0.1 h1:AgB/0SvBxihN0X8OR4SjsblXkbMvalQ8cjmtKQ2rQV8= github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= github.com/emicklei/go-restful/v3 v3.10.1 h1:rc42Y5YTp7Am7CS630D7JmhRjq4UlEUuEKfrDac4bSQ= github.com/emicklei/go-restful/v3 v3.10.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonreference v0.20.0 h1:MYlu0sBgChmCfJxxUKZ8g1cPWFOB37YSZqewK7OKeyA= github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.19.14 h1:gm3vOOXfiuw5i9p5N9xJvfjvuofpyvLA9Wr6QfK5Fng= github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/gnostic v0.5.7-v3refs h1:FhTMOKj2VhjpouxvWJAV1TL304uMlb9zcDqkl6cEI54= github.com/google/gnostic v0.5.7-v3refs/go.mod h1:73MKFl6jIHelAJNaBGFzt3SPtZULs9dYrGFt8OiIsHQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/hanwen/go-fuse/v2 v2.2.0 h1:jo5QZYmBLNcl9ovypWaQ5yXMSSV+Ch68xoC3rtZvvBM= github.com/hanwen/go-fuse/v2 v2.2.0/go.mod h1:B1nGE/6RBFyBRC1RRnf23UpwCdyJ31eukw34oAKukAc= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= github.com/hashicorp/go-hclog v0.9.2 h1:CG6TE5H9/JXsFWJCfoIVpKFIkFe6ysEuHirp4DxCsHI= github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/go-retryablehttp v0.7.2 h1:AcYqCvkpalPnPF2pn0KamgwamS42TqUDDYFRKq/RAd0= github.com/hashicorp/go-retryablehttp v0.7.2/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk= github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.16.0 h1:iULayQNOReoYUe+1qtKOqw9CwJv3aNQu8ivo7lw1HU4= github.com/klauspost/compress v1.16.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348 h1:MtvEpTB6LX3vkb4ax0b5D2DHbNAUsen0Gx5wZoq3lV4= github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA= github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg= github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc= github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU= github.com/moby/sys/mountinfo v0.6.2 h1:BzJjoreD5BMFNmD9Rus6gdd1pLuecOFPt8wC+Vygl78= github.com/moby/sys/mountinfo v0.6.2/go.mod h1:IJb6JQeOklcdMU9F5xQ8ZALD+CUr5VlGpwtX+VE0rpI= github.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5lXtc= github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo= github.com/moby/sys/signal v0.7.0 h1:25RW3d5TnQEoKvRbEKUGay6DCQ46IxAVTT9CUMgmsSI= github.com/moby/sys/signal v0.7.0/go.mod h1:GQ6ObYZfqacOwTtlXvcmh9A26dVRul/hbOZn88Kg8Tg= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= github.com/onsi/ginkgo/v2 v2.4.0 h1:+Ig9nvqgS5OBSACXNk15PLdp0U9XPYROt9CFzVdFGIs= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/onsi/gomega v1.23.0 h1:/oxKu9c2HVap+F3PfKort2Hw5DEU+HGlW8n+tguWsys= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b h1:YWuSjZCQAPM8UUBLkYUk1e+rZcvWHJmFb6i6rM44Xs8= github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b/go.mod h1:3OVijpioIKYWTqjiG0zfF6wvoJ4fAXGbjdZuI2NgsRQ= github.com/opencontainers/runc v1.1.4 h1:nRCz/8sKg6K6jgYAFLDlXzPeITBZJyX28DBVhWD+5dg= github.com/opencontainers/runc v1.1.4/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg= github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.1.0-rc.1 h1:wHa9jroFfKGQqFHj0I1fMRKLl0pfj+ynAqBxo3v6u9w= github.com/opencontainers/runtime-spec v1.1.0-rc.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI= github.com/opencontainers/selinux v1.11.0 h1:+5Zbo97w3Lbmb3PeqQtpmTkMwsW5nRI3YaLpt7tQ7oU= github.com/opencontainers/selinux v1.11.0/go.mod h1:E5dMC3VPuVvVHDYmi78qvhJp8+M586T4DlDRYpFkyec= github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw= github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE= github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo= github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rs/xid v1.4.0 h1:qd7wPTDkN6KQx2VmMBLrpHkiyQwgFXRnkOLacUiaSNY= github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli v1.22.4/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli v1.22.12 h1:igJgVw1JdKH+trcLWLeLwZjU9fEfPesQ+9/e4MQ44S8= github.com/urfave/cli v1.22.12/go.mod h1:sSBEIC79qR6OvcmsD4U3KABeOTxDqQtdDnaFuUN30b8= github.com/vbatts/tar-split v0.11.2 h1:Via6XqJr0hceW4wff3QRzD5gAk/tatMw/4ZA7cTlIME= github.com/vbatts/tar-split v0.11.2/go.mod h1:vV3ZuO2yWSVsz+pfFzDG/upWH1JhjOiEaWq6kXyQ3VI= github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.etcd.io/bbolt v1.3.7 h1:j+zJOnnEjF/kyHlDDgGnVL/AIqIJPq8UoB2GSNfkUfQ= go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/otel v1.12.0 h1:IgfC7kqQrRccIKuB7Cl+SRUmsKbEwSGPr0Eu+/ht1SQ= go.opentelemetry.io/otel v1.12.0/go.mod h1:geaoz0L0r1BEOR81k7/n9W4TCXYCJ7bPO7K374jQHG0= go.opentelemetry.io/otel/trace v1.12.0 h1:p28in++7Kd0r2d8gSt931O57fdjUyWxkVbESuILAeUc= go.opentelemetry.io/otel/trace v1.12.0/go.mod h1:pHlgBynn6s25qJ2szD+Bv+iwKJttjHSI3lUAyf0GNuQ= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.7.0 h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA= golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/oauth2 v0.4.0 h1:NF0gk8LVPg1Ml7SSbGyySuoxdsXitj7TvgvuRxIMc/M= golang.org/x/oauth2 v0.4.0/go.mod h1:RznEsdpjGAINPTOF0UH/t+xJ75L18YO3Ho6Pyn+uRec= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 h1:vVKdlvoWBphwdxWKrFZEuM0kGgGLxUOYcY4U/2Vjg44= golang.org/x/time v0.0.0-20220210224613-90d013bbcef8/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.5.0 h1:+bSpV5HIeWkuvgaMfI3UmKRThoTA5ODJTUd8T17NO+4= golang.org/x/tools v0.5.0/go.mod h1:N+Kgy78s5I24c24dU8OfWNEotWjutIs8SnJvn5IDq+k= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 h1:DdoeryqhaXp1LtT/emMP1BRJPHHKFi5akj/nbx/zNTA= google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.53.0 h1:LAv2ds7cmFV/XTS3XG1NneeENYrXGmorPxsBbptIjNc= google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools/v3 v3.4.0 h1:ZazjZUfuVeZGLAmlKKuyv3IKP5orXcwtOwDQH6YVr6o= gotest.tools/v3 v3.4.0/go.mod h1:CtbdzLSsqVhDgMtKsx03ird5YTGB3ar27v0u/yKBW5g= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= k8s.io/api v0.26.2 h1:dM3cinp3PGB6asOySalOZxEG4CZ0IAdJsrYZXE/ovGQ= k8s.io/api v0.26.2/go.mod h1:1kjMQsFE+QHPfskEcVNgL3+Hp88B80uj0QtSOlj8itU= k8s.io/apimachinery v0.26.2 h1:da1u3D5wfR5u2RpLhE/ZtZS2P7QvDgLZTi9wrNZl/tQ= k8s.io/apimachinery v0.26.2/go.mod h1:ats7nN1LExKHvJ9TmwootT00Yz05MuYqPXEXaVeOy5I= k8s.io/client-go v0.26.2 h1:s1WkVujHX3kTp4Zn4yGNFK+dlDXy1bAAkIl+cFAiuYI= k8s.io/client-go v0.26.2/go.mod h1:u5EjOuSyBa09yqqyY7m3abZeovO/7D/WehVVlZ2qcqU= k8s.io/cri-api v0.27.0-alpha.3 h1:RT3W8OnLFpk9MUod99GwYeNPnzhEqVH0aQE8zBKZ9ds= k8s.io/cri-api v0.27.0-alpha.3/go.mod h1:dwMiSnrLiMmrAsTo/fObV8+efaoI9hHa1IlL++hdDIs= k8s.io/klog/v2 v2.90.1 h1:m4bYOKall2MmOiRaR1J+We67Do7vm9KiQVlT96lnHUw= k8s.io/klog/v2 v2.90.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 h1:+70TFaan3hfJzs+7VK2o+OGxg8HsuBr/5f6tVAjDu6E= k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280/go.mod h1:+Axhij7bCpeqhklhUTe3xmOn6bWxolyZEeyaFpjGtl4= k8s.io/utils v0.0.0-20230220204549-a5ecb0141aa5 h1:kmDqav+P+/5e1i9tFfHq1qcF3sOrDp+YEkVDAHu7Jwk= k8s.io/utils v0.0.0-20230220204549-a5ecb0141aa5/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k= sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= stargz-snapshotter-0.14.3/ipfs/000077500000000000000000000000001440204344700164245ustar00rootroot00000000000000stargz-snapshotter-0.14.3/ipfs/client/000077500000000000000000000000001440204344700177025ustar00rootroot00000000000000stargz-snapshotter-0.14.3/ipfs/client/client.go000066400000000000000000000135571440204344700215220ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package client import ( "encoding/json" "fmt" "io" "mime/multipart" "net/http" "net/url" "os" "path/filepath" "strings" "github.com/mitchellh/go-homedir" ma "github.com/multiformats/go-multiaddr" manet "github.com/multiformats/go-multiaddr/net" ) // Client is an IPFS API client. type Client struct { // Address is URL of IPFS API to connect to. Address string // Client is http client to use for connecting to IPFS API Client *http.Client } // New creates a new IPFS API client of the specified address. func New(ipfsAPIAddress string) *Client { return &Client{Address: ipfsAPIAddress, Client: http.DefaultClient} } // FileInfo represents the information provided by "/api/v0/files/stat" API of IPFS. // Please see details at: https://docs.ipfs.tech/reference/kubo/rpc/#api-v0-files-stat type FileInfo struct { Blocks int `json:"Blocks"` CumulativeSize uint64 `json:"CumulativeSize": ""` Hash string `json:"Hash": ""` Local bool `json:"Local": ""` Size uint64 `json:"Size"` SizeLocal uint64 `json:"SizeLocal"` Type string `json:"Type"` WithLocality bool `json:"WithLocality"` } // StatCID gets and returns information of the file specified by the cid. func (c *Client) StatCID(cid string) (info *FileInfo, retErr error) { if c.Address == "" { return nil, fmt.Errorf("specify IPFS API address") } client := c.Client if client == nil { client = http.DefaultClient } ipfsAPIFilesStat := c.Address + "/api/v0/files/stat" req, err := http.NewRequest("POST", ipfsAPIFilesStat, nil) if err != nil { return nil, err } q := req.URL.Query() q.Add("arg", "/ipfs/"+cid) req.URL.RawQuery = q.Encode() resp, err := client.Do(req) if err != nil { return nil, err } defer func() { if retErr != nil { io.Copy(io.Discard, resp.Body) resp.Body.Close() } }() if resp.StatusCode/100 != 2 { return nil, fmt.Errorf("failed to stat %v; status code: %v", cid, resp.StatusCode) } var rs FileInfo if err := json.NewDecoder(resp.Body).Decode(&rs); err != nil { return nil, err } return &rs, nil } // Get get the reader of the data specified by the IPFS path and optionally with // the offset and length. func (c *Client) Get(p string, offset *int, length *int) (_ io.ReadCloser, retErr error) { if c.Address == "" { return nil, fmt.Errorf("specify IPFS API address") } client := c.Client if client == nil { client = http.DefaultClient } ipfsAPICat := c.Address + "/api/v0/cat" req, err := http.NewRequest("POST", ipfsAPICat, nil) if err != nil { return nil, err } q := req.URL.Query() q.Add("arg", p) if offset != nil { q.Add("offset", fmt.Sprintf("%d", *offset)) } if length != nil { q.Add("length", fmt.Sprintf("%d", *length)) } req.URL.RawQuery = q.Encode() resp, err := client.Do(req) if err != nil { return nil, err } defer func() { if retErr != nil { io.Copy(io.Discard, resp.Body) resp.Body.Close() } }() if resp.StatusCode/100 != 2 { return nil, fmt.Errorf("failed to cat %v; status code: %v", p, resp.StatusCode) } return resp.Body, nil } // Add adds the provided data to IPFS and returns its CID (v1). func (c *Client) Add(r io.Reader) (cidv1 string, retErr error) { if c.Address == "" { return "", fmt.Errorf("specify IPFS API address") } client := c.Client if client == nil { client = http.DefaultClient } ipfsAPIAdd := c.Address + "/api/v0/add" pr, pw := io.Pipe() mw := multipart.NewWriter(pw) contentType := mw.FormDataContentType() go func() { fw, err := mw.CreateFormFile("file", "file") if err != nil { pw.CloseWithError(err) return } if _, err := io.Copy(fw, r); err != nil { pw.CloseWithError(err) return } if err := mw.Close(); err != nil { pw.CloseWithError(err) return } pw.Close() }() req, err := http.NewRequest("POST", ipfsAPIAdd, pr) if err != nil { return "", err } req.Header.Add("Content-Type", contentType) q := req.URL.Query() q.Add("cid-version", "1") q.Add("pin", "true") req.URL.RawQuery = q.Encode() resp, err := client.Do(req) if err != nil { return "", err } defer func() { io.Copy(io.Discard, resp.Body) resp.Body.Close() }() if resp.StatusCode/100 != 2 { return "", fmt.Errorf("failed to add; status code: %v", resp.StatusCode) } var rs struct { Hash string `json:"Hash"` } if err := json.NewDecoder(resp.Body).Decode(&rs); err != nil { return "", err } if rs.Hash == "" { return "", fmt.Errorf("got empty hash") } return rs.Hash, nil } // GetIPFSAPIAddress get IPFS API URL from the specified IPFS repository. // If ipfsPath == "", then it's default is "~/.ipfs". // This is compatible to IPFS client behaviour: https://github.com/ipfs/go-ipfs-http-client/blob/171fcd55e3b743c38fb9d78a34a3a703ee0b5e89/api.go#L69-L81 func GetIPFSAPIAddress(ipfsPath string, scheme string) (string, error) { if ipfsPath == "" { ipfsPath = "~/.ipfs" } baseDir, err := homedir.Expand(ipfsPath) if err != nil { return "", err } api, err := os.ReadFile(filepath.Join(baseDir, "api")) if err != nil { return "", err } a, err := ma.NewMultiaddr(strings.TrimSpace(string(api))) if err != nil { return "", err } _, iurl, err := manet.DialArgs(a) if err != nil { return "", err } iurl = scheme + "://" + iurl if _, err := url.Parse(iurl); err != nil { return "", err } return iurl, nil } stargz-snapshotter-0.14.3/ipfs/client/client_test.go000066400000000000000000000037651440204344700225610ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ // This test should run via "make test-ipfs". package client import ( "bytes" "flag" "io" "testing" ) var ipfsAPI string func init() { flag.StringVar(&ipfsAPI, "ipfs-api", "", "Address of IPFS API") } func TestIPFSClient(t *testing.T) { if ipfsAPI == "" { t.Log("Specify IPFS API address for IPFS client tests") t.Skip() return } t.Logf("IPFS API address: %q", ipfsAPI) c := New(ipfsAPI) sampleString := "hello world 0123456789" d := bytes.NewReader([]byte(sampleString)) cid, err := c.Add(d) if err != nil { t.Errorf("failed to add data to IPFS: %v", err) return } checkData(t, c, cid, 0, len(sampleString), sampleString, len(sampleString)) checkData(t, c, cid, 10, 4, sampleString[10:14], len(sampleString)) } func checkData(t *testing.T, c *Client, cid string, off, len int, wantData string, allSize int) { st, err := c.StatCID(cid) if err != nil { t.Errorf("failed to stat data from IPFS: %v", err) return } if st.Size != uint64(allSize) { t.Errorf("unexpected size got from IPFS %v; wanted %v", st.Size, allSize) return } dGotR, err := c.Get("/ipfs/"+cid, &off, &len) if err != nil { t.Errorf("failed to get data from IPFS: %v", err) return } dGot, err := io.ReadAll(dGotR) if err != nil { t.Errorf("failed to read data from IPFS: %v", err) return } if string(dGot) != wantData { t.Errorf("unexpected data got from IPFS %q; wanted %q", string(dGot), wantData) return } } stargz-snapshotter-0.14.3/ipfs/converter.go000066400000000000000000000061651440204344700207720ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package ipfs import ( "bytes" "context" "encoding/json" "fmt" "strings" "os" "github.com/containerd/containerd" "github.com/containerd/containerd/content" "github.com/containerd/containerd/images/converter" "github.com/containerd/containerd/platforms" ipfsclient "github.com/containerd/stargz-snapshotter/ipfs/client" ocispec "github.com/opencontainers/image-spec/specs-go/v1" ) // Push pushes the provided image ref to IPFS with converting it to IPFS-enabled format. func Push(ctx context.Context, client *containerd.Client, ref string, layerConvert converter.ConvertFunc, platformMC platforms.MatchComparer) (cidV1 string, _ error) { return PushWithIPFSPath(ctx, client, ref, layerConvert, platformMC, nil) } func PushWithIPFSPath(ctx context.Context, client *containerd.Client, ref string, layerConvert converter.ConvertFunc, platformMC platforms.MatchComparer, ipfsPath *string) (cidV1 string, _ error) { ctx, done, err := client.WithLease(ctx) if err != nil { return "", err } defer done(ctx) img, err := client.ImageService().Get(ctx, ref) if err != nil { return "", err } var ipath string if idir := os.Getenv("IPFS_PATH"); idir != "" { ipath = idir } if ipfsPath != nil { ipath = *ipfsPath } // HTTP is only supported as of now. We can add https support here if needed (e.g. for connecting to it via proxy, etc) iurl, err := ipfsclient.GetIPFSAPIAddress(ipath, "http") if err != nil { return "", err } iclient := ipfsclient.New(iurl) desc, err := converter.IndexConvertFuncWithHook(layerConvert, true, platformMC, converter.ConvertHooks{ PostConvertHook: pushBlobHook(iclient), })(ctx, client.ContentStore(), img.Target) if err != nil { return "", err } root, err := json.Marshal(desc) if err != nil { return "", err } return iclient.Add(bytes.NewReader(root)) } func pushBlobHook(client *ipfsclient.Client) converter.ConvertHookFunc { return func(ctx context.Context, cs content.Store, desc ocispec.Descriptor, newDesc *ocispec.Descriptor) (*ocispec.Descriptor, error) { resultDesc := newDesc if resultDesc == nil { descCopy := desc resultDesc = &descCopy } ra, err := cs.ReaderAt(ctx, *resultDesc) if err != nil { return nil, err } cidv1, err := client.Add(content.NewReader(ra)) if err != nil { return nil, err } resultDesc.URLs = []string{"ipfs://" + cidv1} return resultDesc, nil } } func GetCID(desc ocispec.Descriptor) (string, error) { for _, u := range desc.URLs { if strings.HasPrefix(u, "ipfs://") { return u[7:], nil } } return "", fmt.Errorf("no CID is recorded") } stargz-snapshotter-0.14.3/ipfs/go.mod000066400000000000000000000057721440204344700175450ustar00rootroot00000000000000module github.com/containerd/stargz-snapshotter/ipfs go 1.19 require ( github.com/containerd/containerd v1.7.0-rc.2 github.com/mitchellh/go-homedir v1.1.0 github.com/multiformats/go-multiaddr v0.8.0 github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b ) require ( github.com/AdaLogics/go-fuzz-headers v0.0.0-20230106234847-43070de90fa1 // indirect github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20221215162035-5330a85ea652 // indirect github.com/Microsoft/go-winio v0.6.0 // indirect github.com/Microsoft/hcsshim v0.10.0-rc.7 // indirect github.com/containerd/cgroups v1.1.0 // indirect github.com/containerd/continuity v0.3.0 // indirect github.com/containerd/fifo v1.1.0 // indirect github.com/containerd/ttrpc v1.2.0 // indirect github.com/containerd/typeurl/v2 v2.1.0 // indirect github.com/cyphar/filepath-securejoin v0.2.3 // indirect github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c // indirect github.com/go-logr/logr v1.2.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.2 // indirect github.com/google/go-cmp v0.5.9 // indirect github.com/google/uuid v1.3.0 // indirect github.com/ipfs/go-cid v0.1.0 // indirect github.com/klauspost/compress v1.16.0 // indirect github.com/klauspost/cpuid/v2 v2.0.9 // indirect github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 // indirect github.com/minio/sha256-simd v1.0.0 // indirect github.com/moby/locker v1.0.1 // indirect github.com/moby/sys/mountinfo v0.6.2 // indirect github.com/moby/sys/sequential v0.5.0 // indirect github.com/moby/sys/signal v0.7.0 // indirect github.com/mr-tron/base58 v1.2.0 // indirect github.com/multiformats/go-base32 v0.0.3 // indirect github.com/multiformats/go-base36 v0.1.0 // indirect github.com/multiformats/go-multibase v0.0.3 // indirect github.com/multiformats/go-multihash v0.1.0 // indirect github.com/multiformats/go-varint v0.0.6 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/runc v1.1.4 // indirect github.com/opencontainers/runtime-spec v1.1.0-rc.1 // indirect github.com/opencontainers/selinux v1.11.0 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/sirupsen/logrus v1.9.0 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/otel v1.12.0 // indirect go.opentelemetry.io/otel/trace v1.12.0 // indirect golang.org/x/crypto v0.1.0 // indirect golang.org/x/mod v0.7.0 // indirect golang.org/x/net v0.7.0 // indirect golang.org/x/sync v0.1.0 // indirect golang.org/x/sys v0.6.0 // indirect golang.org/x/text v0.7.0 // indirect golang.org/x/tools v0.5.0 // indirect google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // indirect google.golang.org/grpc v1.53.0 // indirect google.golang.org/protobuf v1.28.1 // indirect lukechampine.com/blake3 v1.1.6 // indirect ) stargz-snapshotter-0.14.3/ipfs/go.sum000066400000000000000000000657501440204344700175740ustar00rootroot00000000000000cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= github.com/AdaLogics/go-fuzz-headers v0.0.0-20230106234847-43070de90fa1 h1:EKPd1INOIyr5hWOWhvpmQpY6tKjeG0hT1s3AMC/9fic= github.com/AdaLogics/go-fuzz-headers v0.0.0-20230106234847-43070de90fa1/go.mod h1:VzwV+t+dZ9j/H867F1M2ziD+yLHtB46oM35FxxMJ4d0= github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20221215162035-5330a85ea652 h1:+vTEFqeoeur6XSq06bs+roX3YiT49gUniJK7Zky7Xjg= github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20221215162035-5330a85ea652/go.mod h1:OahwfttHWG6eJ0clwcfBAHoDI6X/LV/15hx/wlMZSrU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg= github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE= github.com/Microsoft/hcsshim v0.10.0-rc.7 h1:HBytQPxcv8Oy4244zbQbe6hnOnx544eL5QPUqhJldz8= github.com/Microsoft/hcsshim v0.10.0-rc.7/go.mod h1:ILuwjA+kNW+MrN/w5un7n3mTqkwsFu4Bp05/okFUZlE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E= github.com/cilium/ebpf v0.7.0/go.mod h1:/oI2+1shJiTGAMgl6/RgJr36Eo1jzrRcAWbcXO2usCA= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM= github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw= github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U= github.com/containerd/containerd v1.7.0-rc.2 h1:Me1LnvqNQPl56LrVpVkNiQPPLomEKgZi2wKbe6ixx6w= github.com/containerd/containerd v1.7.0-rc.2/go.mod h1:N8hwWslQgbkbPIQulOL9Qgsw5x7VWZppXQLZburjSso= github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg= github.com/containerd/continuity v0.3.0/go.mod h1:wJEAIwKOm/pBZuBd0JmeTvnLquTB1Ag8espWhkykbPM= github.com/containerd/fifo v1.1.0 h1:4I2mbh5stb1u6ycIABlBw9zgtlK8viPI9QkQNRQEEmY= github.com/containerd/fifo v1.1.0/go.mod h1:bmC4NWMbXlt2EZ0Hc7Fx7QzTFxgPID13eH0Qu+MAb2o= github.com/containerd/ttrpc v1.2.0 h1:we4O9wzVsBA1HUVRGU8CWFsbjy2P/U2g9raVu5XXNI0= github.com/containerd/ttrpc v1.2.0/go.mod h1:YYyNVhZrTMiaf51Vj6WhAJqJw+vl/nzABhj8pWrzle4= github.com/containerd/typeurl/v2 v2.1.0 h1:yNAhJvbNEANt7ck48IlEGOxP7YAp6LLpGn5jZACDNIE= github.com/containerd/typeurl/v2 v2.1.0/go.mod h1:IDp2JFvbwZ31H8dQbEIY7sDl2L3o3HZj1hsSQlywkQ0= github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cyphar/filepath-securejoin v0.2.3 h1:YX6ebbZCZP7VkM3scTTokDgBL2TY741X51MTk3ycuNI= github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c h1:+pKlWGMw7gf6bQ+oDZB4KHQFypsfjYlq/C4rfL7D3g8= github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/ipfs/go-cid v0.1.0 h1:YN33LQulcRHjfom/i25yoOZR4Telp1Hr/2RU3d0PnC0= github.com/ipfs/go-cid v0.1.0/go.mod h1:rH5/Xv83Rfy8Rw6xG+id3DYAMUVmem1MowoKwdXmN2o= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.16.0 h1:iULayQNOReoYUe+1qtKOqw9CwJv3aNQu8ivo7lw1HU4= github.com/klauspost/compress v1.16.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g= github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg= github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc= github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU= github.com/moby/sys/mountinfo v0.6.2 h1:BzJjoreD5BMFNmD9Rus6gdd1pLuecOFPt8wC+Vygl78= github.com/moby/sys/mountinfo v0.6.2/go.mod h1:IJb6JQeOklcdMU9F5xQ8ZALD+CUr5VlGpwtX+VE0rpI= github.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5lXtc= github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo= github.com/moby/sys/signal v0.7.0 h1:25RW3d5TnQEoKvRbEKUGay6DCQ46IxAVTT9CUMgmsSI= github.com/moby/sys/signal v0.7.0/go.mod h1:GQ6ObYZfqacOwTtlXvcmh9A26dVRul/hbOZn88Kg8Tg= github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ= github.com/multiformats/go-base32 v0.0.3 h1:tw5+NhuwaOjJCC5Pp82QuXbrmLzWg7uxlMFp8Nq/kkI= github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= github.com/multiformats/go-base36 v0.1.0 h1:JR6TyF7JjGd3m6FbLU2cOxhC0Li8z8dLNGQ89tUg4F4= github.com/multiformats/go-base36 v0.1.0/go.mod h1:kFGE83c6s80PklsHO9sRn2NCoffoRdUUOENyW/Vv6sM= github.com/multiformats/go-multiaddr v0.8.0 h1:aqjksEcqK+iD/Foe1RRFsGZh8+XFiGo7FgUCZlpv3LU= github.com/multiformats/go-multiaddr v0.8.0/go.mod h1:Fs50eBDWvZu+l3/9S6xAE7ZYj6yhxlvaVZjakWN7xRs= github.com/multiformats/go-multibase v0.0.3 h1:l/B6bJDQjvQ5G52jw4QGSYeOTZoAwIO77RblWplfIqk= github.com/multiformats/go-multibase v0.0.3/go.mod h1:5+1R4eQrT3PkYZ24C3W2Ue2tPwIdYQD509ZjSb5y9Oc= github.com/multiformats/go-multihash v0.0.15/go.mod h1:D6aZrWNLFTV/ynMpKsNtB40mJzmCl4jb1alC0OvHiHg= github.com/multiformats/go-multihash v0.1.0 h1:CgAgwqk3//SVEw3T+6DqI4mWMyRuDwZtOWcJT0q9+EA= github.com/multiformats/go-multihash v0.1.0/go.mod h1:RJlXsxt6vHGaia+S8We0ErjhojtKzPP2AH4+kYM7k84= github.com/multiformats/go-varint v0.0.6 h1:gk85QWKxh3TazbLxED/NlDVv8+q+ReFJk7Y2W/KhfNY= github.com/multiformats/go-varint v0.0.6/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b h1:YWuSjZCQAPM8UUBLkYUk1e+rZcvWHJmFb6i6rM44Xs8= github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b/go.mod h1:3OVijpioIKYWTqjiG0zfF6wvoJ4fAXGbjdZuI2NgsRQ= github.com/opencontainers/runc v1.1.4 h1:nRCz/8sKg6K6jgYAFLDlXzPeITBZJyX28DBVhWD+5dg= github.com/opencontainers/runc v1.1.4/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg= github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.1.0-rc.1 h1:wHa9jroFfKGQqFHj0I1fMRKLl0pfj+ynAqBxo3v6u9w= github.com/opencontainers/runtime-spec v1.1.0-rc.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI= github.com/opencontainers/selinux v1.11.0 h1:+5Zbo97w3Lbmb3PeqQtpmTkMwsW5nRI3YaLpt7tQ7oU= github.com/opencontainers/selinux v1.11.0/go.mod h1:E5dMC3VPuVvVHDYmi78qvhJp8+M586T4DlDRYpFkyec= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/otel v1.12.0 h1:IgfC7kqQrRccIKuB7Cl+SRUmsKbEwSGPr0Eu+/ht1SQ= go.opentelemetry.io/otel v1.12.0/go.mod h1:geaoz0L0r1BEOR81k7/n9W4TCXYCJ7bPO7K374jQHG0= go.opentelemetry.io/otel/trace v1.12.0 h1:p28in++7Kd0r2d8gSt931O57fdjUyWxkVbESuILAeUc= go.opentelemetry.io/otel/trace v1.12.0/go.mod h1:pHlgBynn6s25qJ2szD+Bv+iwKJttjHSI3lUAyf0GNuQ= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210506145944-38f3c27a63bf/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU= golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.7.0 h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA= golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.5.0 h1:+bSpV5HIeWkuvgaMfI3UmKRThoTA5ODJTUd8T17NO+4= golang.org/x/tools v0.5.0/go.mod h1:N+Kgy78s5I24c24dU8OfWNEotWjutIs8SnJvn5IDq+k= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 h1:DdoeryqhaXp1LtT/emMP1BRJPHHKFi5akj/nbx/zNTA= google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.53.0 h1:LAv2ds7cmFV/XTS3XG1NneeENYrXGmorPxsBbptIjNc= google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= lukechampine.com/blake3 v1.1.6 h1:H3cROdztr7RCfoaTpGZFQsrqvweFLrqS73j7L7cmR5c= lukechampine.com/blake3 v1.1.6/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= stargz-snapshotter-0.14.3/ipfs/resolver.go000066400000000000000000000056511440204344700206230ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package ipfs import ( "context" "encoding/json" "fmt" "io" "path" "os" "github.com/containerd/containerd/remotes" ipfsclient "github.com/containerd/stargz-snapshotter/ipfs/client" ocispec "github.com/opencontainers/image-spec/specs-go/v1" ) type resolver struct { scheme string client *ipfsclient.Client } type ResolverOptions struct { // Scheme is the scheme to fetch the specified IPFS content. "ipfs" or "ipns". Scheme string // IPFSPath is the path to the IPFS repository directory. IPFSPath string } func NewResolver(options ResolverOptions) (remotes.Resolver, error) { s := options.Scheme if s != "ipfs" && s != "ipns" { return nil, fmt.Errorf("unsupported scheme %q", s) } var ipath string if idir := os.Getenv("IPFS_PATH"); idir != "" { ipath = idir } if options.IPFSPath != "" { ipath = options.IPFSPath } // HTTP is only supported as of now. We can add https support here if needed (e.g. for connecting to it via proxy, etc) iurl, err := ipfsclient.GetIPFSAPIAddress(ipath, "http") if err != nil { return nil, fmt.Errorf("failed to get IPFS URL from ipfs path") } return &resolver{ scheme: s, client: ipfsclient.New(iurl), }, nil } // Resolve resolves the provided ref for IPFS. ref must be a CID. // TODO: Allow specifying IPFS path or URL. This requires to modify `reference` pkg because // // it's incompatbile to the current reference specification. func (r *resolver) Resolve(ctx context.Context, ref string) (name string, desc ocispec.Descriptor, err error) { rc, err := r.client.Get(path.Join("/", r.scheme, ref), nil, nil) if err != nil { return "", ocispec.Descriptor{}, err } defer rc.Close() if err := json.NewDecoder(rc).Decode(&desc); err != nil { return "", ocispec.Descriptor{}, err } if _, err := GetCID(desc); err != nil { return "", ocispec.Descriptor{}, err } return ref, desc, nil } func (r *resolver) Fetcher(ctx context.Context, ref string) (remotes.Fetcher, error) { return &fetcher{r}, nil } func (r *resolver) Pusher(ctx context.Context, ref string) (remotes.Pusher, error) { return nil, fmt.Errorf("immutable remote") } type fetcher struct { r *resolver } func (f *fetcher) Fetch(ctx context.Context, desc ocispec.Descriptor) (io.ReadCloser, error) { cid, err := GetCID(desc) if err != nil { return nil, err } return f.r.client.Get(path.Join("/", f.r.scheme, cid), nil, nil) } stargz-snapshotter-0.14.3/metadata/000077500000000000000000000000001440204344700172435ustar00rootroot00000000000000stargz-snapshotter-0.14.3/metadata/memory/000077500000000000000000000000001440204344700205535ustar00rootroot00000000000000stargz-snapshotter-0.14.3/metadata/memory/reader.go000066400000000000000000000163351440204344700223540ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package memory import ( "fmt" "io" "math" "os" "time" "github.com/containerd/stargz-snapshotter/estargz" "github.com/containerd/stargz-snapshotter/metadata" digest "github.com/opencontainers/go-digest" ) type reader struct { r *estargz.Reader rootID uint32 idMap map[uint32]*estargz.TOCEntry idOfEntry map[string]uint32 estargzOpts []estargz.OpenOption } func newReader(er *estargz.Reader, rootID uint32, idMap map[uint32]*estargz.TOCEntry, idOfEntry map[string]uint32, estargzOpts []estargz.OpenOption) *reader { return &reader{r: er, rootID: rootID, idMap: idMap, idOfEntry: idOfEntry, estargzOpts: estargzOpts} } func NewReader(sr *io.SectionReader, opts ...metadata.Option) (metadata.Reader, error) { var rOpts metadata.Options for _, o := range opts { if err := o(&rOpts); err != nil { return nil, fmt.Errorf("failed to apply option: %w", err) } } telemetry := &estargz.Telemetry{} if rOpts.Telemetry != nil { telemetry.GetFooterLatency = estargz.MeasureLatencyHook(rOpts.Telemetry.GetFooterLatency) telemetry.GetTocLatency = estargz.MeasureLatencyHook(rOpts.Telemetry.GetTocLatency) telemetry.DeserializeTocLatency = estargz.MeasureLatencyHook(rOpts.Telemetry.DeserializeTocLatency) } var decompressors []estargz.Decompressor for _, d := range rOpts.Decompressors { decompressors = append(decompressors, d) } erOpts := []estargz.OpenOption{ estargz.WithTOCOffset(rOpts.TOCOffset), estargz.WithTelemetry(telemetry), estargz.WithDecompressors(decompressors...), } er, err := estargz.Open(sr, erOpts...) if err != nil { return nil, err } root, ok := er.Lookup("") if !ok { return nil, fmt.Errorf("failed to get root node") } rootID, idMap, idOfEntry, err := assignIDs(er, root) if err != nil { return nil, err } r := newReader(er, rootID, idMap, idOfEntry, erOpts) return r, nil } // assignIDs assigns an to each TOC item and returns a mapping from ID to entry and vice-versa. func assignIDs(er *estargz.Reader, e *estargz.TOCEntry) (rootID uint32, idMap map[uint32]*estargz.TOCEntry, idOfEntry map[string]uint32, err error) { idMap = make(map[uint32]*estargz.TOCEntry) idOfEntry = make(map[string]uint32) curID := uint32(0) nextID := func() (uint32, error) { if curID == math.MaxUint32 { return 0, fmt.Errorf("sequence id too large") } curID++ return curID, nil } var mapChildren func(e *estargz.TOCEntry) (uint32, error) mapChildren = func(e *estargz.TOCEntry) (uint32, error) { if e.Type == "hardlink" { return 0, fmt.Errorf("unexpected type \"hardlink\": this should be replaced to the destination entry") } var ok bool id, ok := idOfEntry[e.Name] if !ok { id, err = nextID() if err != nil { return 0, err } idMap[id] = e idOfEntry[e.Name] = id } e.ForeachChild(func(_ string, ent *estargz.TOCEntry) bool { _, err = mapChildren(ent) return err == nil }) if err != nil { return 0, err } return id, nil } rootID, err = mapChildren(e) if err != nil { return 0, nil, nil, err } return rootID, idMap, idOfEntry, nil } func (r *reader) RootID() uint32 { return r.rootID } func (r *reader) TOCDigest() digest.Digest { return r.r.TOCDigest() } func (r *reader) GetOffset(id uint32) (offset int64, err error) { e, ok := r.idMap[id] if !ok { return 0, fmt.Errorf("entry %d not found", id) } return e.Offset, nil } func (r *reader) GetAttr(id uint32) (attr metadata.Attr, err error) { e, ok := r.idMap[id] if !ok { err = fmt.Errorf("entry %d not found", id) return } // TODO: zero copy attrFromTOCEntry(e, &attr) return } func (r *reader) GetChild(pid uint32, base string) (id uint32, attr metadata.Attr, err error) { e, ok := r.idMap[pid] if !ok { err = fmt.Errorf("parent entry %d not found", pid) return } child, ok := e.LookupChild(base) if !ok { err = fmt.Errorf("child %q of entry %d not found", base, pid) return } cid, ok := r.idOfEntry[child.Name] if !ok { err = fmt.Errorf("id of entry %q not found", base) return } // TODO: zero copy attrFromTOCEntry(child, &attr) return cid, attr, nil } func (r *reader) ForeachChild(id uint32, f func(name string, id uint32, mode os.FileMode) bool) error { e, ok := r.idMap[id] if !ok { return fmt.Errorf("parent entry %d not found", id) } var err error e.ForeachChild(func(baseName string, ent *estargz.TOCEntry) bool { id, ok := r.idOfEntry[ent.Name] if !ok { err = fmt.Errorf("id of child entry %q not found", baseName) return false } return f(baseName, id, ent.Stat().Mode()) }) return err } func (r *reader) OpenFile(id uint32) (metadata.File, error) { e, ok := r.idMap[id] if !ok { return nil, fmt.Errorf("entry %d not found", id) } sr, err := r.r.OpenFile(e.Name) if err != nil { return nil, err } return &file{r, e, sr}, nil } func (r *reader) OpenFileWithPreReader(id uint32, preRead func(id uint32, chunkOffset, chunkSize int64, chunkDigest string, r io.Reader) error) (metadata.File, error) { e, ok := r.idMap[id] if !ok { return nil, fmt.Errorf("entry %d not found", id) } sr, err := r.r.OpenFileWithPreReader(e.Name, func(e *estargz.TOCEntry, chunkR io.Reader) error { cid, ok := r.idOfEntry[e.Name] if !ok { return fmt.Errorf("id of entry %q not found", e.Name) } return preRead(cid, e.ChunkOffset, e.ChunkSize, e.ChunkDigest, chunkR) }) if err != nil { return nil, err } return &file{r, e, sr}, nil } func (r *reader) Clone(sr *io.SectionReader) (metadata.Reader, error) { er, err := estargz.Open(sr, r.estargzOpts...) if err != nil { return nil, err } return newReader(er, r.rootID, r.idMap, r.idOfEntry, r.estargzOpts), nil } func (r *reader) Close() error { return nil } type file struct { r *reader e *estargz.TOCEntry sr *io.SectionReader } func (r *file) ChunkEntryForOffset(offset int64) (off int64, size int64, dgst string, ok bool) { e, ok := r.r.r.ChunkEntryForOffset(r.e.Name, offset) if !ok { return 0, 0, "", false } dgst = e.Digest if e.ChunkDigest != "" { // NOTE* "reg" also can contain ChunkDigest (e.g. when "reg" is the first entry of // chunked file) dgst = e.ChunkDigest } return e.ChunkOffset, e.ChunkSize, dgst, true } func (r *file) ReadAt(p []byte, off int64) (n int, err error) { return r.sr.ReadAt(p, off) } func (r *reader) NumOfNodes() (i int, _ error) { return len(r.idMap), nil } // TODO: share it with db pkg func attrFromTOCEntry(src *estargz.TOCEntry, dst *metadata.Attr) *metadata.Attr { dst.Size = src.Size dst.ModTime, _ = time.Parse(time.RFC3339, src.ModTime3339) dst.LinkName = src.LinkName dst.Mode = src.Stat().Mode() dst.UID = src.UID dst.GID = src.GID dst.DevMajor = src.DevMajor dst.DevMinor = src.DevMinor dst.Xattrs = src.Xattrs dst.NumLink = src.NumLink return dst } stargz-snapshotter-0.14.3/metadata/memory/reader_test.go000066400000000000000000000020071440204344700234020ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package memory import ( "io" "testing" "github.com/containerd/stargz-snapshotter/metadata" "github.com/containerd/stargz-snapshotter/metadata/testutil" ) func TestReader(t *testing.T) { testutil.TestReader(t, readerFactory) } func readerFactory(sr *io.SectionReader, opts ...metadata.Option) (testutil.TestableReader, error) { r, err := NewReader(sr, opts...) if err != nil { return nil, err } return r.(*reader), nil } stargz-snapshotter-0.14.3/metadata/metadata.go000066400000000000000000000101331440204344700213500ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package metadata import ( "io" "os" "time" "github.com/containerd/stargz-snapshotter/estargz" digest "github.com/opencontainers/go-digest" ) // Attr reprensents the attributes of a node. type Attr struct { // Size, for regular files, is the logical size of the file. Size int64 // ModTime is the modification time of the node. ModTime time.Time // LinkName, for symlinks, is the link target. LinkName string // Mode is the permission and mode bits. Mode os.FileMode // UID is the user ID of the owner. UID int // GID is the group ID of the owner. GID int // DevMajor is the major device number for device. DevMajor int // DevMinor is the major device number for device. DevMinor int // Xattrs are the extended attribute for the node. Xattrs map[string][]byte // NumLink is the number of names pointing to this node. NumLink int } // Store reads the provided eStargz blob and creates a metadata reader. type Store func(sr *io.SectionReader, opts ...Option) (Reader, error) // Reader provides access to file metadata of a blob. type Reader interface { RootID() uint32 TOCDigest() digest.Digest GetOffset(id uint32) (offset int64, err error) GetAttr(id uint32) (attr Attr, err error) GetChild(pid uint32, base string) (id uint32, attr Attr, err error) ForeachChild(id uint32, f func(name string, id uint32, mode os.FileMode) bool) error OpenFile(id uint32) (File, error) OpenFileWithPreReader(id uint32, preRead func(id uint32, chunkOffset, chunkSize int64, chunkDigest string, r io.Reader) error) (File, error) Clone(sr *io.SectionReader) (Reader, error) Close() error } type File interface { ChunkEntryForOffset(offset int64) (off int64, size int64, dgst string, ok bool) ReadAt(p []byte, off int64) (n int, err error) } type Decompressor interface { estargz.Decompressor // DecompressTOC decompresses the passed blob and returns a reader of TOC JSON. // // If tocOffset returned by ParseFooter is < 0, we assume that TOC isn't contained in the blob. // Pass nil reader to DecompressTOC then we expect that DecompressTOC acquire TOC from the external // location and return it. DecompressTOC(io.Reader) (tocJSON io.ReadCloser, err error) } type Options struct { TOCOffset int64 Telemetry *Telemetry Decompressors []Decompressor } // Option is an option to configure the behaviour of reader. type Option func(o *Options) error // WithTOCOffset option specifies the offset of TOC func WithTOCOffset(tocOffset int64) Option { return func(o *Options) error { o.TOCOffset = tocOffset return nil } } // WithTelemetry option specifies the telemetry hooks func WithTelemetry(telemetry *Telemetry) Option { return func(o *Options) error { o.Telemetry = telemetry return nil } } // WithDecompressors option specifies decompressors to use. // Default is gzip-based decompressor. func WithDecompressors(decompressors ...Decompressor) Option { return func(o *Options) error { o.Decompressors = decompressors return nil } } // A func which takes start time and records the diff type MeasureLatencyHook func(time.Time) // A struct which defines telemetry hooks. By implementing these hooks you should be able to record // the latency metrics of the respective steps of estargz open operation. type Telemetry struct { GetFooterLatency MeasureLatencyHook // measure time to get stargz footer (in milliseconds) GetTocLatency MeasureLatencyHook // measure time to GET TOC JSON (in milliseconds) DeserializeTocLatency MeasureLatencyHook // measure time to deserialize TOC JSON (in milliseconds) } stargz-snapshotter-0.14.3/metadata/testutil/000077500000000000000000000000001440204344700211205ustar00rootroot00000000000000stargz-snapshotter-0.14.3/metadata/testutil/testutil.go000066400000000000000000000676761440204344700233520ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package testutil import ( "compress/gzip" "fmt" "io" "math/rand" "os" "path" "path/filepath" "reflect" "strings" "testing" "time" "github.com/containerd/stargz-snapshotter/estargz" "github.com/containerd/stargz-snapshotter/metadata" tutil "github.com/containerd/stargz-snapshotter/util/testutil" "github.com/hashicorp/go-multierror" "github.com/klauspost/compress/zstd" digest "github.com/opencontainers/go-digest" ) func init() { rand.Seed(time.Now().UnixNano()) } var allowedPrefix = [4]string{"", "./", "/", "../"} var srcCompressions = map[string]tutil.CompressionFactory{ "zstd-fastest": tutil.ZstdCompressionWithLevel(zstd.SpeedFastest), "zstd-default": tutil.ZstdCompressionWithLevel(zstd.SpeedDefault), "zstd-bettercompression": tutil.ZstdCompressionWithLevel(zstd.SpeedBetterCompression), "gzip-no-compression": tutil.GzipCompressionWithLevel(gzip.NoCompression), "gzip-bestspeed": tutil.GzipCompressionWithLevel(gzip.BestSpeed), "gzip-bestcompression": tutil.GzipCompressionWithLevel(gzip.BestCompression), "gzip-defaultcompression": tutil.GzipCompressionWithLevel(gzip.DefaultCompression), "gzip-huffmanonly": tutil.GzipCompressionWithLevel(gzip.HuffmanOnly), "externaltoc-gzip-bestspeed": tutil.ExternalTOCGzipCompressionWithLevel(gzip.BestSpeed), "externaltoc-gzip-bestcompression": tutil.ExternalTOCGzipCompressionWithLevel(gzip.BestCompression), "externaltoc-gzip-defaultcompression": tutil.ExternalTOCGzipCompressionWithLevel(gzip.DefaultCompression), "externaltoc-gzip-huffmanonly": tutil.ExternalTOCGzipCompressionWithLevel(gzip.HuffmanOnly), } type ReaderFactory func(sr *io.SectionReader, opts ...metadata.Option) (r TestableReader, err error) type TestableReader interface { metadata.Reader NumOfNodes() (i int, _ error) } // TestReader tests Reader returns correct file metadata. func TestReader(t *testing.T, factory ReaderFactory) { sampleTime := time.Now().Truncate(time.Second) sampleText := "qwer" + "tyui" + "opas" + "dfgh" + "jk" data64KB := string(tutil.RandomBytes(t, 64000)) tests := []struct { name string chunkSize int minChunkSize int in []tutil.TarEntry want []check }{ { name: "empty", in: []tutil.TarEntry{}, want: []check{ numOfNodes(2), // root dir + prefetch landmark }, }, { name: "files", in: []tutil.TarEntry{ tutil.File("foo", "foofoo", tutil.WithFileMode(0644|os.ModeSetuid)), tutil.Dir("bar/"), tutil.File("bar/baz.txt", "bazbazbaz", tutil.WithFileOwner(1000, 1000)), tutil.File("xxx.txt", "xxxxx", tutil.WithFileModTime(sampleTime)), tutil.File("y.txt", "", tutil.WithFileXattrs(map[string]string{"testkey": "testval"})), }, want: []check{ numOfNodes(7), // root dir + prefetch landmark + 1 dir + 4 files hasFile("foo", "foofoo", 6), hasMode("foo", 0644|os.ModeSetuid), hasFile("bar/baz.txt", "bazbazbaz", 9), hasOwner("bar/baz.txt", 1000, 1000), hasFile("xxx.txt", "xxxxx", 5), hasModTime("xxx.txt", sampleTime), hasFile("y.txt", "", 0), hasXattrs("y.txt", map[string]string{"testkey": "testval"}), }, }, { name: "dirs", in: []tutil.TarEntry{ tutil.Dir("foo/", tutil.WithDirMode(os.ModeDir|0600|os.ModeSticky)), tutil.Dir("foo/bar/", tutil.WithDirOwner(1000, 1000)), tutil.File("foo/bar/baz.txt", "testtest"), tutil.File("foo/bar/xxxx", "x"), tutil.File("foo/bar/yyy", "yyy"), tutil.Dir("foo/a/", tutil.WithDirModTime(sampleTime)), tutil.Dir("foo/a/1/", tutil.WithDirXattrs(map[string]string{"testkey": "testval"})), tutil.File("foo/a/1/2", "1111111111"), }, want: []check{ numOfNodes(10), // root dir + prefetch landmark + 4 dirs + 4 files hasDirChildren("foo", "bar", "a"), hasDirChildren("foo/bar", "baz.txt", "xxxx", "yyy"), hasDirChildren("foo/a", "1"), hasDirChildren("foo/a/1", "2"), hasMode("foo", os.ModeDir|0600|os.ModeSticky), hasOwner("foo/bar", 1000, 1000), hasModTime("foo/a", sampleTime), hasXattrs("foo/a/1", map[string]string{"testkey": "testval"}), hasFile("foo/bar/baz.txt", "testtest", 8), hasFile("foo/bar/xxxx", "x", 1), hasFile("foo/bar/yyy", "yyy", 3), hasFile("foo/a/1/2", "1111111111", 10), }, }, { name: "hardlinks", in: []tutil.TarEntry{ tutil.File("foo", "foofoo", tutil.WithFileOwner(1000, 1000)), tutil.Dir("bar/"), tutil.Link("bar/foolink", "foo"), tutil.Link("bar/foolink2", "bar/foolink"), tutil.Dir("bar/1/"), tutil.File("bar/1/baz.txt", "testtest"), tutil.Link("barlink", "bar/1/baz.txt"), tutil.Symlink("foosym", "bar/foolink2"), }, want: []check{ numOfNodes(7), // root dir + prefetch landmark + 2 dirs + 1 flie(linked) + 1 file(linked) + 1 symlink hasFile("foo", "foofoo", 6), hasOwner("foo", 1000, 1000), hasFile("bar/foolink", "foofoo", 6), hasOwner("bar/foolink", 1000, 1000), hasFile("bar/foolink2", "foofoo", 6), hasOwner("bar/foolink2", 1000, 1000), hasFile("bar/1/baz.txt", "testtest", 8), hasFile("barlink", "testtest", 8), hasDirChildren("bar", "foolink", "foolink2", "1"), hasDirChildren("bar/1", "baz.txt"), sameNodes("foo", "bar/foolink", "bar/foolink2"), sameNodes("bar/1/baz.txt", "barlink"), linkName("foosym", "bar/foolink2"), hasNumLink("foo", 3), // parent dir + 2 links hasNumLink("barlink", 2), // parent dir + 1 link hasNumLink("bar", 3), // parent + "." + child's ".." }, }, { name: "various files", in: []tutil.TarEntry{ tutil.Dir("bar/"), tutil.File("bar/../bar///////////////////foo", ""), tutil.Chardev("bar/cdev", 10, 11), tutil.Blockdev("bar/bdev", 100, 101), tutil.Fifo("bar/fifo"), }, want: []check{ numOfNodes(7), // root dir + prefetch landmark + 1 file + 1 dir + 1 cdev + 1 bdev + 1 fifo hasFile("bar/foo", "", 0), hasChardev("bar/cdev", 10, 11), hasBlockdev("bar/bdev", 100, 101), hasFifo("bar/fifo"), }, }, { name: "chunks", chunkSize: 4, in: []tutil.TarEntry{ tutil.Dir("foo/"), tutil.File("foo/small", sampleText[:2]), tutil.File("foo/large", sampleText), }, want: []check{ numOfNodes(5), // root dir + prefetch landmark + 1 dir + 2 files numOfChunks("foo/large", 1+(len(sampleText)/4)), hasFileContentsOffset("foo/small", 0, sampleText[:2]), hasFileContentsOffset("foo/large", 0, sampleText[0:]), hasFileContentsOffset("foo/large", 1, sampleText[1:]), hasFileContentsOffset("foo/large", 2, sampleText[2:]), hasFileContentsOffset("foo/large", 3, sampleText[3:]), hasFileContentsOffset("foo/large", 4, sampleText[4:]), hasFileContentsOffset("foo/large", 5, sampleText[5:]), hasFileContentsOffset("foo/large", 6, sampleText[6:]), hasFileContentsOffset("foo/large", 7, sampleText[7:]), hasFileContentsOffset("foo/large", 8, sampleText[8:]), hasFileContentsOffset("foo/large", 9, sampleText[9:]), hasFileContentsOffset("foo/large", 10, sampleText[10:]), hasFileContentsOffset("foo/large", 11, sampleText[11:]), hasFileContentsOffset("foo/large", 12, sampleText[12:]), hasFileContentsOffset("foo/large", int64(len(sampleText)-1), ""), }, }, { name: "several_files_in_chunk", minChunkSize: 8000, in: []tutil.TarEntry{ tutil.Dir("foo/"), tutil.File("foo/foo1", data64KB), tutil.File("foo2", "bb"), tutil.File("foo22", "ccc"), tutil.Dir("bar/"), tutil.File("bar/bar.txt", "aaa"), tutil.File("foo3", data64KB), }, // NOTE: we assume that the compressed "data64KB" is still larger than 8KB // landmark+dir+foo1, foo2+foo22+dir+bar.txt+foo3, TOC, footer want: []check{ numOfNodes(9), // root dir, prefetch landmark, dir, foo1, foo2, foo22, dir, bar.txt, foo3 hasDirChildren("foo/", "foo1"), hasDirChildren("bar/", "bar.txt"), hasFile("foo/foo1", data64KB, int64(len(data64KB))), hasFile("foo2", "bb", 2), hasFile("foo22", "ccc", 3), hasFile("bar/bar.txt", "aaa", 3), hasFile("foo3", data64KB, int64(len(data64KB))), hasFileContentsWithPreRead("foo22", 0, "ccc", chunkInfo{"foo2", "bb", 0, 2, digest.FromString("bb").String()}, chunkInfo{"bar/bar.txt", "aaa", 0, 3, digest.FromString("aaa").String()}, chunkInfo{"foo3", data64KB, 0, 64000, digest.FromString(data64KB).String()}), hasFileContentsOffset("foo/foo1", 0, data64KB), hasFileContentsOffset("foo2", 0, "bb"), hasFileContentsOffset("foo2", 1, "b"), hasFileContentsOffset("foo22", 0, "ccc"), hasFileContentsOffset("foo22", 1, "cc"), hasFileContentsOffset("foo22", 2, "c"), hasFileContentsOffset("bar/bar.txt", 0, "aaa"), hasFileContentsOffset("bar/bar.txt", 1, "aa"), hasFileContentsOffset("bar/bar.txt", 2, "a"), hasFileContentsOffset("foo3", 0, data64KB), hasFileContentsOffset("foo3", 1, data64KB[1:]), hasFileContentsOffset("foo3", 2, data64KB[2:]), hasFileContentsOffset("foo3", int64(len(data64KB)/2), data64KB[len(data64KB)/2:]), hasFileContentsOffset("foo3", int64(len(data64KB)-1), data64KB[len(data64KB)-1:]), }, }, { name: "several_files_in_chunk_chunked", minChunkSize: 8000, chunkSize: 32000, in: []tutil.TarEntry{ tutil.Dir("foo/"), tutil.File("foo/foo1", data64KB), tutil.File("foo2", "bb"), tutil.Dir("bar/"), tutil.File("foo3", data64KB), }, // NOTE: we assume that the compressed chunk of "data64KB" is still larger than 8KB // landmark+dir+foo1(1), foo1(2), foo2+dir+foo3(1), foo3(2), TOC, footer want: []check{ numOfNodes(7), // root dir, prefetch landmark, dir, foo1, foo2, dir, foo3 hasDirChildren("foo", "foo1"), hasFile("foo/foo1", data64KB, int64(len(data64KB))), hasFile("foo2", "bb", 2), hasFile("foo3", data64KB, int64(len(data64KB))), hasFileContentsWithPreRead("foo2", 0, "bb", chunkInfo{"foo3", data64KB[:32000], 0, 32000, digest.FromString(data64KB[:32000]).String()}), hasFileContentsOffset("foo/foo1", 0, data64KB), hasFileContentsOffset("foo/foo1", 1, data64KB[1:]), hasFileContentsOffset("foo/foo1", 2, data64KB[2:]), hasFileContentsOffset("foo/foo1", int64(len(data64KB)/2), data64KB[len(data64KB)/2:]), hasFileContentsOffset("foo/foo1", int64(len(data64KB)-1), data64KB[len(data64KB)-1:]), hasFileContentsOffset("foo2", 0, "bb"), hasFileContentsOffset("foo2", 1, "b"), hasFileContentsOffset("foo3", 0, data64KB), hasFileContentsOffset("foo3", 1, data64KB[1:]), hasFileContentsOffset("foo3", 2, data64KB[2:]), hasFileContentsOffset("foo3", int64(len(data64KB)/2), data64KB[len(data64KB)/2:]), hasFileContentsOffset("foo3", int64(len(data64KB)-1), data64KB[len(data64KB)-1:]), }, }, } for _, tt := range tests { for _, prefix := range allowedPrefix { prefix := prefix for srcCompresionName, srcCompression := range srcCompressions { srcCompression := srcCompression() t.Run(tt.name+"-"+srcCompresionName, func(t *testing.T) { opts := []tutil.BuildEStargzOption{ tutil.WithBuildTarOptions(tutil.WithPrefix(prefix)), tutil.WithEStargzOptions(estargz.WithCompression(srcCompression)), } if tt.chunkSize > 0 { opts = append(opts, tutil.WithEStargzOptions(estargz.WithChunkSize(tt.chunkSize))) } if tt.minChunkSize > 0 { t.Logf("minChunkSize = %d", tt.minChunkSize) opts = append(opts, tutil.WithEStargzOptions(estargz.WithMinChunkSize(tt.minChunkSize))) } esgz, _, err := tutil.BuildEStargz(tt.in, opts...) if err != nil { t.Fatalf("failed to build sample eStargz: %v", err) } telemetry, checkCalled := newCalledTelemetry() r, err := factory(esgz, metadata.WithDecompressors(srcCompression), metadata.WithTelemetry(telemetry)) if err != nil { t.Fatalf("failed to create new reader: %v", err) } defer r.Close() t.Logf("vvvvv Node tree vvvvv") t.Logf("[%d] ROOT", r.RootID()) dumpNodes(t, r, r.RootID(), 1) t.Logf("^^^^^^^^^^^^^^^^^^^^^") for _, want := range tt.want { want(t, r) } if err := checkCalled(); err != nil { t.Errorf("telemetry failure: %v", err) } // Test the cloned reader works correctly as well esgz2, _, err := tutil.BuildEStargz(tt.in, opts...) if err != nil { t.Fatalf("failed to build sample eStargz: %v", err) } clonedR, err := r.Clone(esgz2) if err != nil { t.Fatalf("failed to clone reader: %v", err) } defer clonedR.Close() t.Logf("vvvvv Node tree (cloned) vvvvv") t.Logf("[%d] ROOT", clonedR.RootID()) dumpNodes(t, clonedR.(TestableReader), clonedR.RootID(), 1) t.Logf("^^^^^^^^^^^^^^^^^^^^^") for _, want := range tt.want { want(t, clonedR.(TestableReader)) } }) } } } t.Run("clone-id-stability", func(t *testing.T) { var mapEntries func(r TestableReader, id uint32, m map[string]uint32) (map[string]uint32, error) mapEntries = func(r TestableReader, id uint32, m map[string]uint32) (map[string]uint32, error) { if m == nil { m = make(map[string]uint32) } return m, r.ForeachChild(id, func(name string, id uint32, mode os.FileMode) bool { m[name] = id if _, err := mapEntries(r, id, m); err != nil { t.Fatalf("could not map files: %s", err) return false } return true }) } in := []tutil.TarEntry{ tutil.File("foo", "foofoo"), tutil.Dir("bar/"), tutil.File("bar/zzz.txt", "bazbazbaz"), tutil.File("bar/aaa.txt", "bazbazbaz"), tutil.File("bar/fff.txt", "bazbazbaz"), tutil.File("xxx.txt", "xxxxx"), tutil.File("y.txt", ""), } esgz, _, err := tutil.BuildEStargz(in) if err != nil { t.Fatalf("failed to build sample eStargz: %v", err) } r, err := factory(esgz) if err != nil { t.Fatalf("failed to create new reader: %v", err) } fileMap, err := mapEntries(r, r.RootID(), nil) if err != nil { t.Fatalf("could not map files: %s", err) } cr, err := r.Clone(esgz) if err != nil { t.Fatalf("could not clone reader: %s", err) } cloneFileMap, err := mapEntries(cr.(TestableReader), cr.RootID(), nil) if err != nil { t.Fatalf("could not map files in cloned reader: %s", err) } if !reflect.DeepEqual(fileMap, cloneFileMap) { for f, id := range fileMap { t.Logf("original mapping %s -> %d", f, id) } for f, id := range cloneFileMap { t.Logf("clone mapping %s -> %d", f, id) } t.Fatal("file -> ID mappings did not match between original and cloned reader") } }) } func newCalledTelemetry() (telemetry *metadata.Telemetry, check func() error) { var getFooterLatencyCalled bool var getTocLatencyCalled bool var deserializeTocLatencyCalled bool return &metadata.Telemetry{ GetFooterLatency: func(time.Time) { getFooterLatencyCalled = true }, GetTocLatency: func(time.Time) { getTocLatencyCalled = true }, DeserializeTocLatency: func(time.Time) { deserializeTocLatencyCalled = true }, }, func() error { var allErr error if !getFooterLatencyCalled { allErr = multierror.Append(allErr, fmt.Errorf("metrics GetFooterLatency isn't called")) } if !getTocLatencyCalled { allErr = multierror.Append(allErr, fmt.Errorf("metrics GetTocLatency isn't called")) } if !deserializeTocLatencyCalled { allErr = multierror.Append(allErr, fmt.Errorf("metrics DeserializeTocLatency isn't called")) } return allErr } } func dumpNodes(t *testing.T, r TestableReader, id uint32, level int) { if err := r.ForeachChild(id, func(name string, id uint32, mode os.FileMode) bool { ind := "" for i := 0; i < level; i++ { ind += " " } t.Logf("%v+- [%d] %q : %v", ind, id, name, mode) dumpNodes(t, r, id, level+1) return true }); err != nil { t.Errorf("failed to dump nodes %v", err) } } type check func(*testing.T, TestableReader) func numOfNodes(want int) check { return func(t *testing.T, r TestableReader) { i, err := r.NumOfNodes() if err != nil { t.Errorf("num of nodes: %v", err) } if want != i { t.Errorf("unexpected num of nodes %d; want %d", i, want) } } } func numOfChunks(name string, num int) check { return func(t *testing.T, r TestableReader) { nr, ok := r.(interface { NumOfChunks(id uint32) (i int, _ error) }) if !ok { return // skip } id, err := lookup(r, name) if err != nil { t.Errorf("failed to lookup %q: %v", name, err) return } i, err := nr.NumOfChunks(id) if err != nil { t.Errorf("failed to get num of chunks of %q: %v", name, err) return } if i != num { t.Errorf("unexpected num of chunk of %q : %d want %d", name, i, num) } } } func sameNodes(n string, nodes ...string) check { return func(t *testing.T, r TestableReader) { id, err := lookup(r, n) if err != nil { t.Errorf("failed to lookup %q: %v", n, err) return } for _, en := range nodes { eid, err := lookup(r, en) if err != nil { t.Errorf("failed to lookup %q: %v", en, err) return } if eid != id { t.Errorf("unexpected ID of %q: %d want %d", en, eid, id) } } } } func linkName(name string, linkName string) check { return func(t *testing.T, r TestableReader) { id, err := lookup(r, name) if err != nil { t.Errorf("failed to lookup %q: %v", name, err) return } attr, err := r.GetAttr(id) if err != nil { t.Errorf("failed to get attr of %q: %v", name, err) return } if attr.Mode&os.ModeSymlink == 0 { t.Errorf("%q is not a symlink: %v", name, attr.Mode) return } if attr.LinkName != linkName { t.Errorf("unexpected link name of %q : %q want %q", name, attr.LinkName, linkName) return } } } func hasNumLink(name string, numLink int) check { return func(t *testing.T, r TestableReader) { id, err := lookup(r, name) if err != nil { t.Errorf("failed to lookup %q: %v", name, err) return } attr, err := r.GetAttr(id) if err != nil { t.Errorf("failed to get attr of %q: %v", name, err) return } if attr.NumLink != numLink { t.Errorf("unexpected numLink of %q: %d want %d", name, attr.NumLink, numLink) return } } } func hasDirChildren(name string, children ...string) check { return func(t *testing.T, r TestableReader) { id, err := lookup(r, name) if err != nil { t.Errorf("failed to lookup %q: %v", name, err) return } attr, err := r.GetAttr(id) if err != nil { t.Errorf("failed to get attr of %q: %v", name, err) return } if !attr.Mode.IsDir() { t.Errorf("%q is not directory: %v", name, attr.Mode) return } found := map[string]struct{}{} if err := r.ForeachChild(id, func(name string, id uint32, mode os.FileMode) bool { found[name] = struct{}{} return true }); err != nil { t.Errorf("failed to see children %v", err) return } if len(found) != len(children) { t.Errorf("unexpected number of children of %q : %d want %d", name, len(found), len(children)) } for _, want := range children { if _, ok := found[want]; !ok { t.Errorf("expected child %q not found in %q", want, name) } } } } func hasChardev(name string, maj, min int) check { return func(t *testing.T, r TestableReader) { id, err := lookup(r, name) if err != nil { t.Errorf("cannot find chardev %q: %v", name, err) return } attr, err := r.GetAttr(id) if err != nil { t.Errorf("cannot get attr of chardev %q: %v", name, err) return } if attr.Mode&os.ModeDevice == 0 || attr.Mode&os.ModeCharDevice == 0 { t.Errorf("file %q is not a chardev: %v", name, attr.Mode) return } if attr.DevMajor != maj || attr.DevMinor != min { t.Errorf("unexpected major/minor of chardev %q: %d/%d want %d/%d", name, attr.DevMajor, attr.DevMinor, maj, min) return } } } func hasBlockdev(name string, maj, min int) check { return func(t *testing.T, r TestableReader) { id, err := lookup(r, name) if err != nil { t.Errorf("cannot find blockdev %q: %v", name, err) return } attr, err := r.GetAttr(id) if err != nil { t.Errorf("cannot get attr of blockdev %q: %v", name, err) return } if attr.Mode&os.ModeDevice == 0 || attr.Mode&os.ModeCharDevice != 0 { t.Errorf("file %q is not a blockdev: %v", name, attr.Mode) return } if attr.DevMajor != maj || attr.DevMinor != min { t.Errorf("unexpected major/minor of blockdev %q: %d/%d want %d/%d", name, attr.DevMajor, attr.DevMinor, maj, min) return } } } func hasFifo(name string) check { return func(t *testing.T, r TestableReader) { id, err := lookup(r, name) if err != nil { t.Errorf("cannot find blockdev %q: %v", name, err) return } attr, err := r.GetAttr(id) if err != nil { t.Errorf("cannot get attr of blockdev %q: %v", name, err) return } if attr.Mode&os.ModeNamedPipe == 0 { t.Errorf("file %q is not a fifo: %v", name, attr.Mode) return } } } func hasFile(name, content string, size int64) check { return func(t *testing.T, r TestableReader) { id, err := lookup(r, name) if err != nil { t.Errorf("cannot find file %q: %v", name, err) return } attr, err := r.GetAttr(id) if err != nil { t.Errorf("cannot get attr of file %q: %v", name, err) return } if !attr.Mode.IsRegular() { t.Errorf("file %q is not a regular file: %v", name, attr.Mode) return } sr, err := r.OpenFile(id) if err != nil { t.Errorf("cannot open file %q: %v", name, err) return } data, err := io.ReadAll(io.NewSectionReader(sr, 0, attr.Size)) if err != nil { t.Errorf("cannot read file %q: %v", name, err) return } if attr.Size != size { t.Errorf("unexpected size of file %q : %d (%q) want %d (%q)", name, attr.Size, longBytesView(data), size, longBytesView([]byte(content))) return } if string(data) != content { t.Errorf("unexpected content of %q: %q want %q", name, longBytesView(data), longBytesView([]byte(content))) return } } } type chunkInfo struct { name string data string chunkOffset int64 chunkSize int64 chunkDigest string } func hasFileContentsWithPreRead(name string, off int64, contents string, extra ...chunkInfo) check { return func(t *testing.T, r TestableReader) { extraMap := make(map[uint32]chunkInfo) for _, e := range extra { id, err := lookup(r, e.name) if err != nil { t.Errorf("failed to lookup extra %q: %v", e.name, err) return } extraMap[id] = e } var extraNames []string for _, e := range extraMap { extraNames = append(extraNames, e.name) } id, err := lookup(r, name) if err != nil { t.Errorf("failed to lookup %q: %v", name, err) return } fr, err := r.OpenFileWithPreReader(id, func(id uint32, chunkOffset, chunkSize int64, chunkDigest string, cr io.Reader) error { t.Logf("On %q: got preread of %d", name, id) ex, ok := extraMap[id] if !ok { t.Fatalf("fail on %q: unexpected entry %d: %+v", name, id, extraNames) } if chunkOffset != ex.chunkOffset || chunkSize != ex.chunkSize || chunkDigest != ex.chunkDigest { t.Fatalf("fail on %q: unexpected node %d: %+v", name, id, ex) } got, err := io.ReadAll(cr) if err != nil { t.Fatalf("fail on %q: failed to read %d: %v", name, id, err) } if ex.data != string(got) { t.Fatalf("fail on %q: unexpected contents of %d: len=%d; want=%d", name, id, len(got), len(ex.data)) } delete(extraMap, id) return nil }) if err != nil { t.Errorf("failed to open file %q: %v", name, err) return } buf := make([]byte, len(contents)) n, err := fr.ReadAt(buf, off) if err != nil && err != io.EOF { t.Errorf("failed to read file %q (off:%d, want:%q): %v", name, off, contents, err) return } if n != len(contents) { t.Errorf("failed to read contents %q (off:%d, want:%q) got %q", name, off, longBytesView([]byte(contents)), longBytesView(buf)) return } if string(buf) != contents { t.Errorf("unexpected content of %q: %q want %q", name, longBytesView(buf), longBytesView([]byte(contents))) return } if len(extraMap) != 0 { var exNames []string for _, ex := range extraMap { exNames = append(exNames, ex.name) } t.Fatalf("fail on %q: some entries aren't read: %+v", name, exNames) } } } func hasFileContentsOffset(name string, off int64, contents string) check { return func(t *testing.T, r TestableReader) { id, err := lookup(r, name) if err != nil { t.Errorf("failed to lookup %q: %v", name, err) return } fr, err := r.OpenFile(id) if err != nil { t.Errorf("failed to open file %q: %v", name, err) return } buf := make([]byte, len(contents)) n, err := fr.ReadAt(buf, off) if err != nil && err != io.EOF { t.Errorf("failed to read file %q (off:%d, want:%q): %v", name, off, contents, err) return } if n != len(contents) { t.Errorf("failed to read contents %q (off:%d, want:%q) got %q", name, off, longBytesView([]byte(contents)), longBytesView(buf)) return } if string(buf) != contents { t.Errorf("unexpected content of %q: %q want %q", name, longBytesView(buf), longBytesView([]byte(contents))) return } } } func hasMode(name string, mode os.FileMode) check { return func(t *testing.T, r TestableReader) { id, err := lookup(r, name) if err != nil { t.Errorf("cannot find file %q: %v", name, err) return } attr, err := r.GetAttr(id) if err != nil { t.Errorf("cannot get attr of file %q: %v", name, err) return } if attr.Mode != mode { t.Errorf("unexpected mode of %q: %v want %v", name, attr.Mode, mode) return } } } func hasOwner(name string, uid, gid int) check { return func(t *testing.T, r TestableReader) { id, err := lookup(r, name) if err != nil { t.Errorf("cannot find file %q: %v", name, err) return } attr, err := r.GetAttr(id) if err != nil { t.Errorf("cannot get attr of file %q: %v", name, err) return } if attr.UID != uid || attr.GID != gid { t.Errorf("unexpected owner of %q: (%d:%d) want (%d:%d)", name, attr.UID, attr.GID, uid, gid) return } } } func hasModTime(name string, modTime time.Time) check { return func(t *testing.T, r TestableReader) { id, err := lookup(r, name) if err != nil { t.Errorf("cannot find file %q: %v", name, err) return } attr, err := r.GetAttr(id) if err != nil { t.Errorf("cannot get attr of file %q: %v", name, err) return } attrModTime := attr.ModTime if attrModTime.Before(modTime) || attrModTime.After(modTime) { t.Errorf("unexpected time of %q: %v; want %v", name, attrModTime, modTime) return } } } func hasXattrs(name string, xattrs map[string]string) check { return func(t *testing.T, r TestableReader) { id, err := lookup(r, name) if err != nil { t.Errorf("cannot find file %q: %v", name, err) return } attr, err := r.GetAttr(id) if err != nil { t.Errorf("cannot get attr of file %q: %v", name, err) return } if len(attr.Xattrs) != len(xattrs) { t.Errorf("unexpected size of xattr of %q: %d want %d", name, len(attr.Xattrs), len(xattrs)) return } for k, v := range attr.Xattrs { if xattrs[k] != string(v) { t.Errorf("unexpected xattr of %q: %q=%q want %q=%q", name, k, string(v), k, xattrs[k]) } } } } func lookup(r TestableReader, name string) (uint32, error) { name = strings.TrimPrefix(path.Clean("/"+name), "/") if name == "" { return r.RootID(), nil } dir, base := filepath.Split(name) pid, err := lookup(r, dir) if err != nil { return 0, err } id, _, err := r.GetChild(pid, base) return id, err } // longBytesView is an alias of []byte suitable for printing a long data as an omitted string to avoid long data being printed. type longBytesView []byte func (b longBytesView) String() string { if len(b) < 100 { return string(b) } return string(b[:50]) + "...(omit)..." + string(b[len(b)-50:]) } stargz-snapshotter-0.14.3/nativeconverter/000077500000000000000000000000001440204344700207015ustar00rootroot00000000000000stargz-snapshotter-0.14.3/nativeconverter/estargz/000077500000000000000000000000001440204344700223605ustar00rootroot00000000000000stargz-snapshotter-0.14.3/nativeconverter/estargz/estargz.go000066400000000000000000000117001440204344700243650ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package estargz import ( "context" "fmt" "io" "github.com/containerd/containerd/archive/compression" "github.com/containerd/containerd/content" "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/images" "github.com/containerd/containerd/images/converter" "github.com/containerd/containerd/images/converter/uncompress" "github.com/containerd/containerd/labels" "github.com/containerd/stargz-snapshotter/estargz" "github.com/containerd/stargz-snapshotter/util/ioutils" "github.com/opencontainers/go-digest" ocispec "github.com/opencontainers/image-spec/specs-go/v1" ) // LayerConvertWithLayerAndCommonOptsFunc converts legacy tar.gz layers into eStargz tar.gz // layers. Media type is unchanged. Should be used in conjunction with WithDockerToOCI(). See // LayerConvertFunc for more details. The difference between this function and // LayerConvertFunc is that this allows to specify additional eStargz options per layer. func LayerConvertWithLayerAndCommonOptsFunc(opts map[digest.Digest][]estargz.Option, commonOpts ...estargz.Option) converter.ConvertFunc { if opts == nil { return LayerConvertFunc(commonOpts...) } return func(ctx context.Context, cs content.Store, desc ocispec.Descriptor) (*ocispec.Descriptor, error) { // TODO: enable to speciy option per layer "index" because it's possible that there are // two layers having same digest in an image (but this should be rare case) return LayerConvertFunc(append(commonOpts, opts[desc.Digest]...)...)(ctx, cs, desc) } } // LayerConvertFunc converts legacy tar.gz layers into eStargz tar.gz layers. // Media type is unchanged. // // Should be used in conjunction with WithDockerToOCI(). // // Otherwise "containerd.io/snapshot/stargz/toc.digest" annotation will be lost, // because the Docker media type does not support layer annotations. func LayerConvertFunc(opts ...estargz.Option) converter.ConvertFunc { return func(ctx context.Context, cs content.Store, desc ocispec.Descriptor) (*ocispec.Descriptor, error) { if !images.IsLayerType(desc.MediaType) { // No conversion. No need to return an error here. return nil, nil } info, err := cs.Info(ctx, desc.Digest) if err != nil { return nil, err } labelz := info.Labels if labelz == nil { labelz = make(map[string]string) } ra, err := cs.ReaderAt(ctx, desc) if err != nil { return nil, err } defer ra.Close() sr := io.NewSectionReader(ra, 0, desc.Size) blob, err := estargz.Build(sr, append(opts, estargz.WithContext(ctx))...) if err != nil { return nil, err } defer blob.Close() ref := fmt.Sprintf("convert-estargz-from-%s", desc.Digest) w, err := content.OpenWriter(ctx, cs, content.WithRef(ref)) if err != nil { return nil, err } defer w.Close() // Reset the writing position // Old writer possibly remains without aborted // (e.g. conversion interrupted by a signal) if err := w.Truncate(0); err != nil { return nil, err } // Copy and count the contents pr, pw := io.Pipe() c := new(ioutils.CountWriter) doneCount := make(chan struct{}) go func() { defer close(doneCount) defer pr.Close() decompressR, err := compression.DecompressStream(pr) if err != nil { pr.CloseWithError(err) return } defer decompressR.Close() if _, err := io.Copy(c, decompressR); err != nil { pr.CloseWithError(err) return } }() n, err := io.Copy(w, io.TeeReader(blob, pw)) if err != nil { return nil, err } if err := blob.Close(); err != nil { return nil, err } if err := pw.Close(); err != nil { return nil, err } <-doneCount // update diffID label labelz[labels.LabelUncompressed] = blob.DiffID().String() if err = w.Commit(ctx, n, "", content.WithLabels(labelz)); err != nil && !errdefs.IsAlreadyExists(err) { return nil, err } if err := w.Close(); err != nil { return nil, err } newDesc := desc if uncompress.IsUncompressedType(newDesc.MediaType) { if images.IsDockerType(newDesc.MediaType) { newDesc.MediaType += ".gzip" } else { newDesc.MediaType += "+gzip" } } newDesc.Digest = w.Digest() newDesc.Size = n if newDesc.Annotations == nil { newDesc.Annotations = make(map[string]string, 1) } newDesc.Annotations[estargz.TOCJSONDigestAnnotation] = blob.TOCDigest().String() newDesc.Annotations[estargz.StoreUncompressedSizeAnnotation] = fmt.Sprintf("%d", c.Size()) return &newDesc, nil } } stargz-snapshotter-0.14.3/nativeconverter/estargz/estargz_test.go000066400000000000000000000040461440204344700254310ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package estargz import ( "context" "testing" "github.com/containerd/containerd/images" "github.com/containerd/containerd/images/converter" "github.com/containerd/containerd/platforms" "github.com/containerd/stargz-snapshotter/estargz" "github.com/containerd/stargz-snapshotter/util/testutil" ocispec "github.com/opencontainers/image-spec/specs-go/v1" ) // TestLayerConvertFunc tests eStargz conversion. // TestLayerConvertFunc is a pure unit test that does not need the daemon to be running. func TestLayerConvertFunc(t *testing.T) { ctx := context.Background() desc, cs, err := testutil.EnsureHello(ctx) if err != nil { t.Fatal(err) } lcf := LayerConvertFunc(estargz.WithPrioritizedFiles([]string{"hello"})) docker2oci := true platformMC := platforms.DefaultStrict() cf := converter.DefaultIndexConvertFunc(lcf, docker2oci, platformMC) newDesc, err := cf(ctx, cs, *desc) if err != nil { t.Fatal(err) } var tocDigests []string handler := func(hCtx context.Context, hDesc ocispec.Descriptor) ([]ocispec.Descriptor, error) { if hDesc.Annotations != nil { if x, ok := hDesc.Annotations[estargz.TOCJSONDigestAnnotation]; ok && len(x) > 0 { tocDigests = append(tocDigests, x) } } return nil, nil } handlers := images.Handlers( images.ChildrenHandler(cs), images.HandlerFunc(handler), ) if err := images.Walk(ctx, handlers, *newDesc); err != nil { t.Fatal(err) } if len(tocDigests) == 0 { t.Fatal("no eStargz layer was created") } } stargz-snapshotter-0.14.3/nativeconverter/estargz/externaltoc/000077500000000000000000000000001440204344700247105ustar00rootroot00000000000000stargz-snapshotter-0.14.3/nativeconverter/estargz/externaltoc/converter.go000066400000000000000000000324511440204344700272530ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package externaltoc import ( "context" "encoding/json" "fmt" "io" "sort" "time" "github.com/containerd/containerd/archive/compression" "github.com/containerd/containerd/content" "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/images" "github.com/containerd/containerd/images/converter" "github.com/containerd/containerd/images/converter/uncompress" "github.com/containerd/containerd/labels" "github.com/containerd/containerd/reference" "github.com/containerd/stargz-snapshotter/estargz" esgzexternaltoc "github.com/containerd/stargz-snapshotter/estargz/externaltoc" estargzconvert "github.com/containerd/stargz-snapshotter/nativeconverter/estargz" "github.com/containerd/stargz-snapshotter/util/ioutils" "github.com/opencontainers/go-digest" ocispecspec "github.com/opencontainers/image-spec/specs-go" ocispec "github.com/opencontainers/image-spec/specs-go/v1" ) // LayerConvertFunc converts legacy tar.gz layers into eStargz tar.gz layers. // // finalize() callback function returned by this function will return the image that contains // external TOC of each layer. Note that the returned image by isn't stored to the containerd image // store so far so the caller needs to do it. // // Media type is unchanged. // // Should be used in conjunction with WithDockerToOCI(). // // Otherwise "containerd.io/snapshot/stargz/toc.digest" annotation will be lost, // because the Docker media type does not support layer annotations. // // WithCompression() in esgzOpts will be ignored but used the one for external TOC instead. func LayerConvertFunc(esgzOpts []estargz.Option, compressionLevel int) (convertFunc converter.ConvertFunc, finalize func(ctx context.Context, cs content.Store, ref string, desc *ocispec.Descriptor) (*images.Image, error)) { return layerConvert(func(c estargz.Compression) converter.ConvertFunc { return estargzconvert.LayerConvertFunc(append(esgzOpts, estargz.WithCompression(c))...) }, compressionLevel) } // LayerConvertWithLayerAndCommonOptsFunc converts legacy tar.gz layers into eStargz. // Media type is unchanged. Should be used in conjunction with WithDockerToOCI(). See // LayerConvertFunc for more details. The difference between this function and // LayerConvertFunc is that this allows to specify additional eStargz options per layer. func LayerConvertWithLayerAndCommonOptsFunc(opts map[digest.Digest][]estargz.Option, commonOpts []estargz.Option, compressionLevel int) (convertFunc converter.ConvertFunc, finalize func(ctx context.Context, cs content.Store, ref string, desc *ocispec.Descriptor) (*images.Image, error)) { return layerConvert(func(c estargz.Compression) converter.ConvertFunc { return estargzconvert.LayerConvertWithLayerAndCommonOptsFunc(opts, append(commonOpts, estargz.WithCompression(c), )...) }, compressionLevel) } // LayerConvertLossLessConfig is configuration for LayerConvertLossLessFunc. type LayerConvertLossLessConfig struct { CompressionLevel int ChunkSize int MinChunkSize int } // LayerConvertLossLessFunc converts legacy tar.gz layers into eStargz tar.gz layers without changing // the diffIDs (i.e. uncompressed digest). // // finalize() callback function returned by this function will return the image that contains // external TOC of each layer. Note that the returned image by isn't stored to the containerd image // store so far so the caller needs to do it. // // Media type is unchanged. // // Should be used in conjunction with WithDockerToOCI(). // // Otherwise "containerd.io/snapshot/stargz/toc.digest" annotation will be lost, // because the Docker media type does not support layer annotations. // // WithCompression() in esgzOpts will be ignored but used the one for external TOC instead. func LayerConvertLossLessFunc(cfg LayerConvertLossLessConfig) (convertFunc converter.ConvertFunc, finalize func(ctx context.Context, cs content.Store, ref string, desc *ocispec.Descriptor) (*images.Image, error)) { return layerConvert(func(c estargz.Compression) converter.ConvertFunc { return layerLossLessConvertFunc(c, cfg.ChunkSize, cfg.MinChunkSize) }, cfg.CompressionLevel) } func layerConvert(layerConvertFunc func(estargz.Compression) converter.ConvertFunc, compressionLevel int) (convertFunc converter.ConvertFunc, finalize func(ctx context.Context, cs content.Store, ref string, desc *ocispec.Descriptor) (*images.Image, error)) { type tocInfo struct { digest digest.Digest size int64 } esgzDigest2TOC := make(map[digest.Digest]tocInfo) // TODO: currently, all layers of all platforms are combined to one TOC manifest. Maybe we can consider // having a separated TOC manifest per platform. converterFunc := func(ctx context.Context, cs content.Store, desc ocispec.Descriptor) (*ocispec.Descriptor, error) { cm := esgzexternaltoc.NewGzipCompressionWithLevel(nil, compressionLevel) c := cm.(*esgzexternaltoc.GzipCompression) cf := layerConvertFunc(c) desc2, err := cf(ctx, cs, desc) if err != nil { return desc2, err } var layerDgst digest.Digest if desc2 != nil { layerDgst = desc2.Digest } else { layerDgst = desc.Digest // no conversion happened } dgst, size, err := writeTOCTo(ctx, c, cs) if err != nil { return nil, err } esgzDigest2TOC[layerDgst] = tocInfo{dgst, size} return desc2, nil } finalizeFunc := func(ctx context.Context, cs content.Store, ref string, desc *ocispec.Descriptor) (*images.Image, error) { var layers []ocispec.Descriptor for esgzDigest, toc := range esgzDigest2TOC { layers = append(layers, ocispec.Descriptor{ MediaType: ocispec.MediaTypeImageLayerGzip, Digest: toc.digest, Size: toc.size, Annotations: map[string]string{ "containerd.io/snapshot/stargz/layer.digest": esgzDigest.String(), }, }) } sort.Slice(layers, func(i, j int) bool { return layers[i].Digest.String() < layers[j].Digest.String() }) mfst, err := createManifest(ctx, cs, ocispec.ImageConfig{}, layers) if err != nil { return nil, err } tocImgRef, err := getTOCReference(ref) if err != nil { return nil, err } return &images.Image{ Name: tocImgRef, Target: *mfst, }, nil } return converterFunc, finalizeFunc } func getTOCReference(ref string) (string, error) { refspec, err := reference.Parse(ref) if err != nil { return "", err } refspec.Object = refspec.Object + "-esgztoc" // TODO: support custom location return refspec.String(), nil } func layerLossLessConvertFunc(compressor estargz.Compressor, chunkSize int, minChunkSize int) converter.ConvertFunc { return func(ctx context.Context, cs content.Store, desc ocispec.Descriptor) (*ocispec.Descriptor, error) { if !images.IsLayerType(desc.MediaType) { // No conversion. No need to return an error here. return nil, nil } info, err := cs.Info(ctx, desc.Digest) if err != nil { return nil, err } labelz := info.Labels if labelz == nil { labelz = make(map[string]string) } ra, err := cs.ReaderAt(ctx, desc) if err != nil { return nil, err } defer ra.Close() sr := io.NewSectionReader(ra, 0, desc.Size) ref := fmt.Sprintf("convert-estargz-from-%s", desc.Digest) w, err := content.OpenWriter(ctx, cs, content.WithRef(ref)) if err != nil { return nil, err } defer w.Close() // Reset the writing position // Old writer possibly remains without aborted // (e.g. conversion interrupted by a signal) if err := w.Truncate(0); err != nil { return nil, err } // Copy and count the contents esgzUW, esgzUncompressedInfoCh := calcUncompression() orgUW, orgUncompressedInfoCh := calcUncompression() countW := new(ioutils.CountWriter) mw := io.MultiWriter(io.MultiWriter(w, countW), esgzUW) var ew *estargz.Writer if compressor != nil { ew = estargz.NewWriterWithCompressor(mw, compressor) } else { ew = estargz.NewWriter(mw) } if chunkSize > 0 { ew.ChunkSize = chunkSize } ew.MinChunkSize = minChunkSize if err := ew.AppendTarLossLess(io.TeeReader(sr, orgUW)); err != nil { return nil, fmt.Errorf("cannot perform compression in lossless way: %w", err) } tocDgst, err := ew.Close() if err != nil { return nil, err } n := countW.Size() if err := esgzUW.Close(); err != nil { return nil, err } if err := orgUW.Close(); err != nil { return nil, err } esgzUncompressedInfo := <-esgzUncompressedInfoCh orgUncompressedInfo := <-orgUncompressedInfoCh // check the lossless conversion if esgzUncompressedInfo.diffID.String() != orgUncompressedInfo.diffID.String() { return nil, fmt.Errorf("unexpected diffID %q; want %q", esgzUncompressedInfo.diffID.String(), orgUncompressedInfo.diffID.String()) } if esgzUncompressedInfo.size != orgUncompressedInfo.size { return nil, fmt.Errorf("unexpected uncompressed size %q; want %q", esgzUncompressedInfo.size, orgUncompressedInfo.size) } // write diffID label labelz[labels.LabelUncompressed] = esgzUncompressedInfo.diffID.String() if err = w.Commit(ctx, n, "", content.WithLabels(labelz)); err != nil && !errdefs.IsAlreadyExists(err) { return nil, err } if err := w.Close(); err != nil { return nil, err } newDesc := desc if uncompress.IsUncompressedType(newDesc.MediaType) { if images.IsDockerType(newDesc.MediaType) { newDesc.MediaType += ".gzip" } else { newDesc.MediaType += "+gzip" } } newDesc.Digest = w.Digest() newDesc.Size = n if newDesc.Annotations == nil { newDesc.Annotations = make(map[string]string, 1) } newDesc.Annotations[estargz.TOCJSONDigestAnnotation] = tocDgst.String() newDesc.Annotations[estargz.StoreUncompressedSizeAnnotation] = fmt.Sprintf("%d", esgzUncompressedInfo.size) return &newDesc, nil } } type uncompressedInfo struct { diffID digest.Digest size int64 } func calcUncompression() (*io.PipeWriter, chan uncompressedInfo) { pr, pw := io.Pipe() infoCh := make(chan uncompressedInfo) go func() { defer pr.Close() c := new(ioutils.CountWriter) diffID := digest.Canonical.Digester() decompressR, err := compression.DecompressStream(pr) if err != nil { pr.CloseWithError(err) close(infoCh) return } defer decompressR.Close() if _, err := io.Copy(io.MultiWriter(c, diffID.Hash()), decompressR); err != nil { pr.CloseWithError(err) close(infoCh) return } infoCh <- uncompressedInfo{ diffID: diffID.Digest(), size: c.Size(), } }() return pw, infoCh } func writeTOCTo(ctx context.Context, gc *esgzexternaltoc.GzipCompression, cs content.Store) (digest.Digest, int64, error) { ref := "external-toc" + time.Now().String() w, err := content.OpenWriter(ctx, cs, content.WithRef(ref)) if err != nil { return "", 0, err } defer w.Close() if err := w.Truncate(0); err != nil { return "", 0, err } c := new(ioutils.CountWriter) dgstr := digest.Canonical.Digester() n, err := gc.WriteTOCTo(io.MultiWriter(io.MultiWriter(w, dgstr.Hash()), c)) if err != nil { return "", 0, err } if err := w.Commit(ctx, int64(n), ""); err != nil && !errdefs.IsAlreadyExists(err) { return "", 0, err } if err := w.Close(); err != nil { return "", 0, err } return dgstr.Digest(), c.Size(), nil } func createManifest(ctx context.Context, cs content.Store, config ocispec.ImageConfig, layers []ocispec.Descriptor) (*ocispec.Descriptor, error) { // Create config configDgst, configSize, err := writeJSON(ctx, cs, &config, nil) if err != nil { return nil, err } // Create manifest mfst := ocispec.Manifest{ Versioned: ocispecspec.Versioned{ SchemaVersion: 2, }, MediaType: ocispec.MediaTypeImageManifest, Config: ocispec.Descriptor{ MediaType: ocispec.MediaTypeImageConfig, Digest: configDgst, Size: configSize, }, Layers: layers, } mfstLabels := make(map[string]string) for i, ld := range mfst.Layers { mfstLabels[fmt.Sprintf("containerd.io/gc.ref.content.l.%d", i)] = ld.Digest.String() } mfstLabels["containerd.io/gc.ref.content.c.0"] = configDgst.String() mfstDgst, mfstSize, err := writeJSON(ctx, cs, &mfst, mfstLabels) if err != nil { return nil, err } return &ocispec.Descriptor{ MediaType: ocispec.MediaTypeImageManifest, Digest: mfstDgst, Size: mfstSize, }, nil } func writeJSON(ctx context.Context, cs content.Store, data interface{}, labels map[string]string) (digest.Digest, int64, error) { raw, err := json.Marshal(data) if err != nil { return "", 0, err } size := len(raw) ref := "write-json-ref" + digest.FromBytes(raw).String() w, err := content.OpenWriter(ctx, cs, content.WithRef(ref)) if err != nil { return "", 0, err } defer w.Close() if err := w.Truncate(0); err != nil { return "", 0, err } if _, err := w.Write(raw); err != nil { return "", 0, err } if err = w.Commit(ctx, int64(size), "", content.WithLabels(labels)); err != nil && !errdefs.IsAlreadyExists(err) { return "", 0, err } dgst := w.Digest() if err := w.Close(); err != nil { return "", 0, err } return dgst, int64(size), nil } stargz-snapshotter-0.14.3/nativeconverter/estargz/externaltoc/converter_test.go000066400000000000000000000152661440204344700303170ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package externaltoc import ( "compress/gzip" "context" "encoding/json" "io" "testing" "github.com/containerd/containerd/content" "github.com/containerd/containerd/images" "github.com/containerd/containerd/images/converter" "github.com/containerd/containerd/platforms" "github.com/containerd/stargz-snapshotter/estargz" "github.com/containerd/stargz-snapshotter/util/testutil" digest "github.com/opencontainers/go-digest" ocispec "github.com/opencontainers/image-spec/specs-go/v1" ) // TestLayerConvertFunc tests eStargz conversion. // TestLayerConvertFunc is a pure unit test that does not need the daemon to be running. func TestLayerConvertFunc(t *testing.T) { ctx := context.Background() desc, cs, err := testutil.EnsureHello(ctx) if err != nil { t.Fatal(err) } lcf, finalize := LayerConvertFunc(nil, gzip.BestSpeed) docker2oci := true platformMC := platforms.DefaultStrict() cf := converter.DefaultIndexConvertFunc(lcf, docker2oci, platformMC) newDesc, err := cf(ctx, cs, *desc) if err != nil { t.Fatal(err) } targetRef := "docker.io/library/hello:target" externalTOCImg, err := finalize(ctx, cs, targetRef, newDesc) if err != nil { t.Fatal(err) } if externalTOCImg.Name != targetRef+"-esgztoc" { t.Fatalf("external TOC ref; got = %q; wanted = %q", externalTOCImg.Name, targetRef+"-esgztoc") } layerDigests := make(map[digest.Digest]struct{}) var tocDigests []string handler := func(hCtx context.Context, hDesc ocispec.Descriptor) ([]ocispec.Descriptor, error) { if images.IsLayerType(hDesc.MediaType) { layerDigests[hDesc.Digest] = struct{}{} } if hDesc.Annotations != nil { if x, ok := hDesc.Annotations[estargz.TOCJSONDigestAnnotation]; ok && len(x) > 0 { tocDigests = append(tocDigests, x) } } return nil, nil } handlers := images.Handlers( images.ChildrenHandler(cs), images.HandlerFunc(handler), ) if err := images.Walk(ctx, handlers, *newDesc); err != nil { t.Fatal(err) } if len(tocDigests) == 0 { t.Fatal("no eStargz layer was created") } ra, err := cs.ReaderAt(ctx, externalTOCImg.Target) if err != nil { t.Fatal(err) } defer ra.Close() sr := io.NewSectionReader(ra, 0, ra.Size()) var manifest ocispec.Manifest if err := json.NewDecoder(sr).Decode(&manifest); err != nil { t.Fatal(err) } for _, l := range manifest.Layers { targetLayer, ok := l.Annotations["containerd.io/snapshot/stargz/layer.digest"] if !ok { t.Fatal("external TOC must contain target layer in annotation") } d, err := digest.Parse(targetLayer) if err != nil { t.Fatal(err) } t.Logf("GOT: %v", d) delete(layerDigests, d) } if len(layerDigests) != 0 { t.Fatalf("some layers don't have external TOC: %+v", layerDigests) } } // TestLayerConvertLossLessFunc tests eStargz conversion with lossless mode. // TestLayerConvertLossLessFunc is a pure unit test that does not need the daemon to be running. func TestLayerConvertLossLessFunc(t *testing.T) { ctx := context.Background() desc, cs, err := testutil.EnsureHello(ctx) if err != nil { t.Fatal(err) } orgRootFS := rootFS(ctx, t, cs, desc) lcf, finalize := LayerConvertLossLessFunc(LayerConvertLossLessConfig{ CompressionLevel: gzip.BestSpeed, }) docker2oci := true platformMC := platforms.DefaultStrict() cf := converter.DefaultIndexConvertFunc(lcf, docker2oci, platformMC) newDesc, err := cf(ctx, cs, *desc) if err != nil { t.Fatal(err) } targetRef := "docker.io/library/hello:target" externalTOCImg, err := finalize(ctx, cs, targetRef, newDesc) if err != nil { t.Fatal(err) } if externalTOCImg.Name != targetRef+"-esgztoc" { t.Fatalf("external TOC ref; got = %q; wanted = %q", externalTOCImg.Name, targetRef+"-esgztoc") } newRootFS := rootFS(ctx, t, cs, newDesc) if len(orgRootFS) != len(newRootFS) { t.Fatalf("size of rootfs; got = %d; want = %d", len(orgRootFS), len(newRootFS)) } for i := range orgRootFS { if orgRootFS[i] != newRootFS[i] { t.Fatalf("rootfs[%d]; got = %d; want = %d", i, len(orgRootFS), len(newRootFS)) } } layerDigests := make(map[digest.Digest]struct{}) wantDiffIDs := make(map[digest.Digest]struct{}) for _, d := range orgRootFS { wantDiffIDs[d] = struct{}{} } var tocDigests []string handler := func(hCtx context.Context, hDesc ocispec.Descriptor) ([]ocispec.Descriptor, error) { if images.IsLayerType(hDesc.MediaType) { layerDigests[hDesc.Digest] = struct{}{} ra, err := cs.ReaderAt(ctx, hDesc) if err != nil { t.Fatal(err) } defer ra.Close() gr, err := gzip.NewReader(io.NewSectionReader(ra, 0, ra.Size())) if err != nil { t.Fatal(err) } diffID, err := digest.FromReader(gr) if err != nil { t.Fatal(err) } delete(wantDiffIDs, diffID) } if hDesc.Annotations != nil { if x, ok := hDesc.Annotations[estargz.TOCJSONDigestAnnotation]; ok && len(x) > 0 { tocDigests = append(tocDigests, x) } } return nil, nil } handlers := images.Handlers( images.ChildrenHandler(cs), images.HandlerFunc(handler), ) if err := images.Walk(ctx, handlers, *newDesc); err != nil { t.Fatal(err) } if len(wantDiffIDs) != 0 { t.Fatalf("some unexpected rootfs: %+v", wantDiffIDs) } if len(tocDigests) == 0 { t.Fatal("no eStargz layer was created") } ra, err := cs.ReaderAt(ctx, externalTOCImg.Target) if err != nil { t.Fatal(err) } defer ra.Close() sr := io.NewSectionReader(ra, 0, ra.Size()) var manifest ocispec.Manifest if err := json.NewDecoder(sr).Decode(&manifest); err != nil { t.Fatal(err) } for _, l := range manifest.Layers { targetLayer, ok := l.Annotations["containerd.io/snapshot/stargz/layer.digest"] if !ok { t.Fatal("external TOC must contain target layer in annotation") } d, err := digest.Parse(targetLayer) if err != nil { t.Fatal(err) } t.Logf("GOT: %v", d) delete(layerDigests, d) } if len(layerDigests) != 0 { t.Fatalf("some layers don't have external TOC: %+v", layerDigests) } } func rootFS(ctx context.Context, t *testing.T, cs content.Store, desc *ocispec.Descriptor) []digest.Digest { conf, err := images.Config(ctx, cs, *desc, platforms.All) if err != nil { t.Fatal(err) } rfs, err := images.RootFS(ctx, cs, conf) if err != nil { t.Fatal(err) } return rfs } stargz-snapshotter-0.14.3/nativeconverter/estargz/externaltoc/fetcher.go000066400000000000000000000056371440204344700266720ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package externaltoc import ( "context" "fmt" "io" "github.com/containerd/containerd/platforms" "github.com/containerd/containerd/reference" "github.com/containerd/containerd/remotes" "github.com/containerd/containerd/remotes/docker" esgzexternaltoc "github.com/containerd/stargz-snapshotter/estargz/externaltoc" "github.com/containerd/stargz-snapshotter/fs/source" "github.com/containerd/stargz-snapshotter/util/containerdutil" "github.com/opencontainers/go-digest" ocispec "github.com/opencontainers/image-spec/specs-go/v1" ) func NewRemoteDecompressor(ctx context.Context, hosts source.RegistryHosts, refspec reference.Spec, desc ocispec.Descriptor) *esgzexternaltoc.GzipDecompressor { return esgzexternaltoc.NewGzipDecompressor(func() ([]byte, error) { resolver := docker.NewResolver(docker.ResolverOptions{ Hosts: func(host string) ([]docker.RegistryHost, error) { if host != refspec.Hostname() { return nil, fmt.Errorf("unexpected host %q for image ref %q", host, refspec.String()) } return hosts(refspec) }, }) return fetchTOCBlob(ctx, resolver, refspec, desc.Digest) }) } func fetchTOCBlob(ctx context.Context, resolver remotes.Resolver, refspec reference.Spec, dgst digest.Digest) ([]byte, error) { // TODO: support custom location of TOC manifest and TOCs using annotations, etc. tocImgRef, err := getTOCReference(refspec.String()) if err != nil { return nil, err } _, img, err := resolver.Resolve(ctx, tocImgRef) if err != nil { return nil, err } fetcher, err := resolver.Fetcher(ctx, tocImgRef) if err != nil { return nil, err } // TODO: cache this manifest manifest, err := containerdutil.FetchManifestPlatform(ctx, fetcher, img, platforms.DefaultSpec()) if err != nil { return nil, err } return fetchTOCBlobFromManifest(ctx, fetcher, manifest, dgst) } func fetchTOCBlobFromManifest(ctx context.Context, fetcher remotes.Fetcher, manifest ocispec.Manifest, layerDigest digest.Digest) ([]byte, error) { for _, l := range manifest.Layers { if len(l.Annotations) == 0 { continue } ldgst, ok := l.Annotations["containerd.io/snapshot/stargz/layer.digest"] if !ok { continue } if ldgst == layerDigest.String() { r, err := fetcher.Fetch(ctx, l) if err != nil { return nil, err } defer r.Close() return io.ReadAll(r) } } return nil, fmt.Errorf("TOC not found") } stargz-snapshotter-0.14.3/nativeconverter/nativeconverter.go000066400000000000000000000012661440204344700244530ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ // Package nativeconverter requires this empty file to pass golangci-lint package nativeconverter stargz-snapshotter-0.14.3/nativeconverter/zstdchunked/000077500000000000000000000000001440204344700232275ustar00rootroot00000000000000stargz-snapshotter-0.14.3/nativeconverter/zstdchunked/zstdchunked.go000066400000000000000000000207611440204344700261120ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package zstdchunked import ( "context" "fmt" "io" "github.com/containerd/containerd/archive/compression" "github.com/containerd/containerd/content" "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/images" "github.com/containerd/containerd/images/converter" "github.com/containerd/containerd/images/converter/uncompress" "github.com/containerd/containerd/labels" "github.com/containerd/stargz-snapshotter/estargz" "github.com/containerd/stargz-snapshotter/estargz/zstdchunked" "github.com/containerd/stargz-snapshotter/util/ioutils" "github.com/klauspost/compress/zstd" "github.com/opencontainers/go-digest" ocispec "github.com/opencontainers/image-spec/specs-go/v1" "github.com/sirupsen/logrus" ) type zstdCompression struct { *zstdchunked.Decompressor *zstdchunked.Compressor } // LayerConvertWithLayerOptsFunc converts legacy tar.gz layers into zstd:chunked layers. // // This changes Docker MediaType to OCI MediaType so this should be used in // conjunction with WithDockerToOCI(). // See LayerConvertFunc for more details. The difference between this function and // LayerConvertFunc is that this allows to specify additional eStargz options per layer. func LayerConvertWithLayerOptsFunc(opts map[digest.Digest][]estargz.Option) converter.ConvertFunc { return LayerConvertWithLayerOptsFuncWithCompressionLevel(zstd.SpeedDefault, opts) } // LayerConvertFunc converts legacy tar.gz layers into zstd:chunked layers. // // This changes Docker MediaType to OCI MediaType so this should be used in // conjunction with WithDockerToOCI(). // // Otherwise "io.containers.zstd-chunked.manifest-checksum" annotation will be lost, // because the Docker media type does not support layer annotations. // // SpeedDefault (level 3) is used for the compression level. // See also: https://pkg.go.dev/github.com/klauspost/compress/zstd#EncoderLevel func LayerConvertFunc(opts ...estargz.Option) converter.ConvertFunc { return LayerConvertFuncWithCompressionLevel(zstd.SpeedDefault, opts...) } // LayerConvertWithLayerOptsFuncWithCompressionLevel converts legacy tar.gz layers into zstd:chunked layers. // This function allows to specify the compression level of zstd. // // This changes Docker MediaType to OCI MediaType so this should be used in // conjunction with WithDockerToOCI(). // See LayerConvertFunc for more details. The difference between this function and // LayerConvertFunc is that this allows to specify additional eStargz options per layer and // allows to specify the compression level. func LayerConvertWithLayerOptsFuncWithCompressionLevel(compressionLevel zstd.EncoderLevel, opts map[digest.Digest][]estargz.Option) converter.ConvertFunc { if opts == nil { return LayerConvertFuncWithCompressionLevel(compressionLevel) } return func(ctx context.Context, cs content.Store, desc ocispec.Descriptor) (*ocispec.Descriptor, error) { // TODO: enable to speciy option per layer "index" because it's possible that there are // two layers having same digest in an image (but this should be rare case) return LayerConvertFuncWithCompressionLevel(compressionLevel, opts[desc.Digest]...)(ctx, cs, desc) } } // LayerConvertFuncWithCompressionLevel converts legacy tar.gz layers into zstd:chunked layers with // the specified compression level. // // This changes Docker MediaType to OCI MediaType so this should be used in // conjunction with WithDockerToOCI(). // See LayerConvertFunc for more details. The difference between this function and // LayerConvertFunc is that this allows configuring the compression level. func LayerConvertFuncWithCompressionLevel(compressionLevel zstd.EncoderLevel, opts ...estargz.Option) converter.ConvertFunc { return func(ctx context.Context, cs content.Store, desc ocispec.Descriptor) (*ocispec.Descriptor, error) { if !images.IsLayerType(desc.MediaType) { // No conversion. No need to return an error here. return nil, nil } uncompressedDesc := &desc // We need to uncompress the archive first if !uncompress.IsUncompressedType(desc.MediaType) { var err error uncompressedDesc, err = uncompress.LayerConvertFunc(ctx, cs, desc) if err != nil { return nil, err } if uncompressedDesc == nil { return nil, fmt.Errorf("unexpectedly got the same blob after compression (%s, %q)", desc.Digest, desc.MediaType) } defer func() { if err := cs.Delete(ctx, uncompressedDesc.Digest); err != nil { logrus.WithError(err).WithField("uncompressedDesc", uncompressedDesc).Warn("failed to remove tmp uncompressed layer") } }() logrus.Debugf("zstdchunked: uncompressed %s into %s", desc.Digest, uncompressedDesc.Digest) } info, err := cs.Info(ctx, desc.Digest) if err != nil { return nil, err } labelz := info.Labels if labelz == nil { labelz = make(map[string]string) } uncompressedReaderAt, err := cs.ReaderAt(ctx, *uncompressedDesc) if err != nil { return nil, err } defer uncompressedReaderAt.Close() uncompressedSR := io.NewSectionReader(uncompressedReaderAt, 0, uncompressedDesc.Size) metadata := make(map[string]string) opts = append(opts, estargz.WithCompression(&zstdCompression{ new(zstdchunked.Decompressor), &zstdchunked.Compressor{ CompressionLevel: compressionLevel, Metadata: metadata, }, })) blob, err := estargz.Build(uncompressedSR, append(opts, estargz.WithContext(ctx))...) if err != nil { return nil, err } defer blob.Close() ref := fmt.Sprintf("convert-zstdchunked-from-%s", desc.Digest) w, err := cs.Writer(ctx, content.WithRef(ref)) if err != nil { return nil, err } defer w.Close() // Reset the writing position // Old writer possibly remains without aborted // (e.g. conversion interrupted by a signal) if err := w.Truncate(0); err != nil { return nil, err } // Copy and count the contents pr, pw := io.Pipe() c := new(ioutils.CountWriter) doneCount := make(chan struct{}) go func() { defer close(doneCount) defer pr.Close() decompressR, err := compression.DecompressStream(pr) if err != nil { pr.CloseWithError(err) return } defer decompressR.Close() if _, err := io.Copy(c, decompressR); err != nil { pr.CloseWithError(err) return } }() n, err := io.Copy(w, io.TeeReader(blob, pw)) if err != nil { return nil, err } if err := blob.Close(); err != nil { return nil, err } // update diffID label labelz[labels.LabelUncompressed] = blob.DiffID().String() if err = w.Commit(ctx, n, "", content.WithLabels(labelz)); err != nil && !errdefs.IsAlreadyExists(err) { return nil, err } if err := w.Close(); err != nil { return nil, err } newDesc := desc newDesc.MediaType, err = convertMediaTypeToZstd(newDesc.MediaType) if err != nil { return nil, err } newDesc.Digest = w.Digest() newDesc.Size = n if newDesc.Annotations == nil { newDesc.Annotations = make(map[string]string, 1) } tocDgst := blob.TOCDigest().String() newDesc.Annotations[estargz.TOCJSONDigestAnnotation] = tocDgst newDesc.Annotations[estargz.StoreUncompressedSizeAnnotation] = fmt.Sprintf("%d", c.Size()) if p, ok := metadata[zstdchunked.ManifestChecksumAnnotation]; ok { newDesc.Annotations[zstdchunked.ManifestChecksumAnnotation] = p } if p, ok := metadata[zstdchunked.ManifestPositionAnnotation]; ok { newDesc.Annotations[zstdchunked.ManifestPositionAnnotation] = p } return &newDesc, nil } } // NOTE: this converts docker mediatype to OCI mediatype func convertMediaTypeToZstd(mt string) (string, error) { ociMediaType := converter.ConvertDockerMediaTypeToOCI(mt) switch ociMediaType { case ocispec.MediaTypeImageLayer, ocispec.MediaTypeImageLayerGzip, ocispec.MediaTypeImageLayerZstd: return ocispec.MediaTypeImageLayerZstd, nil case ocispec.MediaTypeImageLayerNonDistributable, ocispec.MediaTypeImageLayerNonDistributableGzip, ocispec.MediaTypeImageLayerNonDistributableZstd: return ocispec.MediaTypeImageLayerNonDistributableZstd, nil default: return "", fmt.Errorf("unknown mediatype %q", mt) } } stargz-snapshotter-0.14.3/nativeconverter/zstdchunked/zstdchunked_test.go000066400000000000000000000053661440204344700271550ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package zstdchunked import ( "context" "testing" "runtime/debug" "github.com/containerd/containerd/images" "github.com/containerd/containerd/images/converter" "github.com/containerd/containerd/platforms" "github.com/containerd/stargz-snapshotter/estargz" "github.com/containerd/stargz-snapshotter/estargz/zstdchunked" "github.com/containerd/stargz-snapshotter/util/testutil" ocispec "github.com/opencontainers/image-spec/specs-go/v1" ) // TestLayerConvertFunc tests zstd:chunked conversion. // TestLayerConvertFunc is a pure unit test that does not need the daemon to be running. func TestLayerConvertFunc(t *testing.T) { ctx := context.Background() desc, cs, err := testutil.EnsureHello(ctx) if err != nil { t.Fatal(err) } lcf := LayerConvertFunc(estargz.WithPrioritizedFiles([]string{"hello"})) docker2oci := true platformMC := platforms.DefaultStrict() cf := converter.DefaultIndexConvertFunc(lcf, docker2oci, platformMC) newDesc, err := cf(ctx, cs, *desc) if err != nil { t.Log(string(debug.Stack())) t.Fatal(err) } metadata := make(map[string]string) mt := make(map[string]struct{}) handler := func(hCtx context.Context, hDesc ocispec.Descriptor) ([]ocispec.Descriptor, error) { mt[hDesc.MediaType] = struct{}{} for k, v := range hDesc.Annotations { if k == estargz.TOCJSONDigestAnnotation || k == zstdchunked.ManifestChecksumAnnotation || k == zstdchunked.ManifestPositionAnnotation { metadata[k] = v } } return nil, nil } handlers := images.Handlers( images.ChildrenHandler(cs), images.HandlerFunc(handler), ) if err := images.Walk(ctx, handlers, *newDesc); err != nil { t.Fatal(err) } if _, ok := mt[ocispec.MediaTypeImageLayerZstd]; !ok { t.Errorf("mediatype %q is not created", ocispec.MediaTypeImageLayerZstd) } if _, ok := metadata[estargz.TOCJSONDigestAnnotation]; !ok { t.Errorf("%q is not set", estargz.TOCJSONDigestAnnotation) } if _, ok := metadata[zstdchunked.ManifestChecksumAnnotation]; !ok { t.Errorf("%q is not set", zstdchunked.ManifestChecksumAnnotation) } if _, ok := metadata[zstdchunked.ManifestPositionAnnotation]; !ok { t.Errorf("%q is not set", zstdchunked.ManifestPositionAnnotation) } } stargz-snapshotter-0.14.3/recorder/000077500000000000000000000000001440204344700172705ustar00rootroot00000000000000stargz-snapshotter-0.14.3/recorder/recorder.go000066400000000000000000000022001440204344700214160ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ // Package recorder provides log recorder package recorder import ( "encoding/json" "io" "sync" ) type Entry struct { Path string `json:"path"` ManifestDigest string `json:"manifestDigest,omitempty"` LayerIndex *int `json:"layerIndex,omitempty"` } func New(w io.Writer) *Recorder { return &Recorder{ enc: json.NewEncoder(w), } } // Recorder is thread-safe. type Recorder struct { enc *json.Encoder mu sync.Mutex } func (ll *Recorder) Record(e *Entry) error { ll.mu.Lock() defer ll.mu.Unlock() return ll.enc.Encode(e) } stargz-snapshotter-0.14.3/script/000077500000000000000000000000001440204344700167675ustar00rootroot00000000000000stargz-snapshotter-0.14.3/script/benchmark/000077500000000000000000000000001440204344700207215ustar00rootroot00000000000000stargz-snapshotter-0.14.3/script/benchmark/config-containerd/000077500000000000000000000000001440204344700243125ustar00rootroot00000000000000stargz-snapshotter-0.14.3/script/benchmark/config-containerd/etc/000077500000000000000000000000001440204344700250655ustar00rootroot00000000000000stargz-snapshotter-0.14.3/script/benchmark/config-containerd/etc/containerd-stargz-grpc/000077500000000000000000000000001440204344700314545ustar00rootroot00000000000000stargz-snapshotter-0.14.3/script/benchmark/config-containerd/etc/containerd-stargz-grpc/config.toml000066400000000000000000000002121440204344700336110ustar00rootroot00000000000000# the value of noprefetch will be replaced during benchmarking noprefetch = true debug_address = "/run/containerd-stargz-grpc/debug.sock" stargz-snapshotter-0.14.3/script/benchmark/config-containerd/etc/containerd/000077500000000000000000000000001440204344700272135ustar00rootroot00000000000000stargz-snapshotter-0.14.3/script/benchmark/config-containerd/etc/containerd/config.toml000066400000000000000000000002241440204344700313530ustar00rootroot00000000000000version = 2 [proxy_plugins] [proxy_plugins.stargz] type = "snapshot" address = "/run/containerd-stargz-grpc/containerd-stargz-grpc.sock" stargz-snapshotter-0.14.3/script/benchmark/config-podman/000077500000000000000000000000001440204344700234425ustar00rootroot00000000000000stargz-snapshotter-0.14.3/script/benchmark/config-podman/etc/000077500000000000000000000000001440204344700242155ustar00rootroot00000000000000stargz-snapshotter-0.14.3/script/benchmark/config-podman/etc/containers/000077500000000000000000000000001440204344700263625ustar00rootroot00000000000000stargz-snapshotter-0.14.3/script/benchmark/config-podman/etc/containers/policy.json000066400000000000000000000001341440204344700305520ustar00rootroot00000000000000{ "default": [ { "type": "insecureAcceptAnything" } ] } stargz-snapshotter-0.14.3/script/benchmark/config-podman/etc/stargz-store/000077500000000000000000000000001440204344700266615ustar00rootroot00000000000000stargz-snapshotter-0.14.3/script/benchmark/config-podman/etc/stargz-store/config.toml000066400000000000000000000001211440204344700310150ustar00rootroot00000000000000# the value of noprefetch will be replaced during benchmarking noprefetch = true stargz-snapshotter-0.14.3/script/benchmark/hello-bench/000077500000000000000000000000001440204344700231015ustar00rootroot00000000000000stargz-snapshotter-0.14.3/script/benchmark/hello-bench/prepare.sh000077500000000000000000000023521440204344700251000ustar00rootroot00000000000000#!/bin/bash # Copyright The containerd Authors. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. set -euo pipefail CONTEXT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )/" REPO="${CONTEXT}../../../" MEASURING_SCRIPT="${REPO}/script/benchmark/hello-bench/src/hello.py" REBOOT_CONTAINERD_SCRIPT="${REPO}/script/benchmark/hello-bench/reboot_containerd.sh" if [ $# -lt 1 ] ; then echo "Specify benchmark target." echo "Ex) ${0} --all" echo "Ex) ${0} alpine busybox" exit 1 fi TARGET_REPOSITORY="${1}" TARGET_IMAGES=${@:2} DISABLE_ESTARGZ="true" "${REBOOT_CONTAINERD_SCRIPT}" "${MEASURING_SCRIPT}" --repository=${TARGET_REPOSITORY} --op=prepare ${TARGET_IMAGES} stargz-snapshotter-0.14.3/script/benchmark/hello-bench/reboot_containerd.sh000077500000000000000000000061661440204344700271510ustar00rootroot00000000000000#!/bin/bash # Copyright The containerd Authors. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. set -euo pipefail CONTAINERD_ROOT=/var/lib/containerd/ CONTAINERD_CONFIG_DIR=/etc/containerd/ REMOTE_SNAPSHOTTER_SOCKET=/run/containerd-stargz-grpc/containerd-stargz-grpc.sock REMOTE_SNAPSHOTTER_ROOT=/var/lib/containerd-stargz-grpc/ REMOTE_SNAPSHOTTER_CONFIG_DIR=/etc/containerd-stargz-grpc/ RETRYNUM=30 RETRYINTERVAL=1 TIMEOUTSEC=180 function retry { local SUCCESS=false for i in $(seq ${RETRYNUM}) ; do if eval "timeout ${TIMEOUTSEC} ${@}" ; then SUCCESS=true break fi echo "Fail(${i}). Retrying..." sleep ${RETRYINTERVAL} done if [ "${SUCCESS}" == "true" ] ; then return 0 else return 1 fi } function kill_all { if [ "${1}" != "" ] ; then ps aux | grep "${1}" \ | grep -v "benchmark" \ | grep -v grep \ | grep -v "hello.py" \ | grep -v $(basename ${0}) \ | sed -E 's/ +/ /g' | cut -f 2 -d ' ' | xargs -I{} kill -9 {} || true fi } function cleanup { rm -rf "${CONTAINERD_ROOT}"* if [ -f "${REMOTE_SNAPSHOTTER_SOCKET}" ] ; then rm "${REMOTE_SNAPSHOTTER_SOCKET}" fi if [ -d "${REMOTE_SNAPSHOTTER_ROOT}snapshotter/snapshots/" ] ; then find "${REMOTE_SNAPSHOTTER_ROOT}snapshotter/snapshots/" \ -maxdepth 1 -mindepth 1 -type d -exec umount "{}/fs" \; fi rm -rf "${REMOTE_SNAPSHOTTER_ROOT}"* } echo "cleaning up the environment..." kill_all "containerd" kill_all "containerd-stargz-grpc" cleanup if [ "${DISABLE_PREFETCH:-}" == "true" ] ; then sed -i 's/noprefetch = .*/noprefetch = true/g' "${REMOTE_SNAPSHOTTER_CONFIG_DIR}config.toml" else sed -i 's/noprefetch = .*/noprefetch = false/g' "${REMOTE_SNAPSHOTTER_CONFIG_DIR}config.toml" fi if [ "${DISABLE_ESTARGZ:-}" == "true" ] ; then echo "DO NOT RUN remote snapshotter" else echo "running remote snaphsotter..." if [ "${LOG_FILE:-}" == "" ] ; then LOG_FILE=/dev/null fi containerd-stargz-grpc --log-level=debug \ --address="${REMOTE_SNAPSHOTTER_SOCKET}" \ --config="${REMOTE_SNAPSHOTTER_CONFIG_DIR}config.toml" \ 2>&1 | tee -a "${LOG_FILE}" & # Dump all log retry ls "${REMOTE_SNAPSHOTTER_SOCKET}" fi echo "running containerd..." containerd --config="${CONTAINERD_CONFIG_DIR}config.toml" & CTRCMD=ctr-remote if ! which "${CTRCMD}" ; then if ! which ctr ; then echo "ctr nor ctr-remote not found" exit 1 fi CTRCMD=ctr fi retry "${CTRCMD}" version stargz-snapshotter-0.14.3/script/benchmark/hello-bench/reboot_store.sh000077500000000000000000000065461440204344700261610ustar00rootroot00000000000000#!/bin/bash # Copyright The containerd Authors. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. set -euo pipefail PODMAN_CONFIG_DIR=/etc/containers/ PODMAN_STORAGE_CONFIG_FILE="${PODMAN_CONFIG_DIR}storage.conf" REG_STORAGE_CONFIG_FILE="/etc/stargz-store/config.toml" REG_STORAGE_ROOT=/var/lib/stargz-store/ REG_STORAGE_DIR="${REG_STORAGE_ROOT}store/" REG_STORAGE_POOL_LINK="${REG_STORAGE_ROOT}store/pool" REG_STORAGE_MOUNTPOINT="${REG_STORAGE_DIR}" RETRYNUM=30 RETRYINTERVAL=1 TIMEOUTSEC=180 function retry { local SUCCESS=false for i in $(seq ${RETRYNUM}) ; do if eval "timeout ${TIMEOUTSEC} ${@}" ; then SUCCESS=true break fi echo "Fail(${i}). Retrying..." sleep ${RETRYINTERVAL} done if [ "${SUCCESS}" == "true" ] ; then return 0 else return 1 fi } function kill_all { if [ "${1}" != "" ] ; then ps aux | grep "${1}" \ | grep -v grep \ | grep -v "hello.py" \ | grep -v $(basename ${0}) \ | sed -E 's/ +/ /g' | cut -f 2 -d ' ' | xargs -I{} kill -9 {} || true fi } function cleanup { umount "${REG_STORAGE_MOUNTPOINT}" || true rm -rf "${REG_STORAGE_DIR}" || true if [ -d "${REG_STORAGE_ROOT}pool/" ] ; then for POOL in $(ls "${REG_STORAGE_ROOT}pool/") ; do umount "${REG_STORAGE_ROOT}pool/${POOL}" || true for MP in $(ls "${REG_STORAGE_ROOT}pool/${POOL}") ; do umount "${REG_STORAGE_ROOT}pool/${POOL}/${MP}" || true done done fi rm -rf "${REG_STORAGE_ROOT}"* rm "${PODMAN_STORAGE_CONFIG_FILE}" || true podman system reset -f } echo "cleaning up the environment..." kill_all "stargz-store" cleanup if [ "${DISABLE_PREFETCH:-}" == "true" ] ; then sed -i 's/noprefetch = .*/noprefetch = true/g' "${REG_STORAGE_CONFIG_FILE}" else sed -i 's/noprefetch = .*/noprefetch = false/g' "${REG_STORAGE_CONFIG_FILE}" fi mkdir -p "${PODMAN_CONFIG_DIR}" if [ "${DISABLE_ESTARGZ:-}" == "true" ] ; then echo "DO NOT RUN additional storage" cat < "${PODMAN_STORAGE_CONFIG_FILE}" [storage] driver = "overlay" graphroot = "/var/lib/containers/storage" runroot = "/run/containers/storage" EOF else echo "running remote snaphsotter..." if [ "${LOG_FILE:-}" == "" ] ; then LOG_FILE=/dev/null fi cat < "${PODMAN_STORAGE_CONFIG_FILE}" [storage] driver = "overlay" graphroot = "/var/lib/containers/storage" runroot = "/run/containers/storage" [storage.options] additionallayerstores = ["${REG_STORAGE_MOUNTPOINT}:ref"] EOF mkdir -p "${REG_STORAGE_MOUNTPOINT}" stargz-store --log-level=debug \ --config="${REG_STORAGE_CONFIG_FILE}" \ "${REG_STORAGE_MOUNTPOINT}" \ 2>&1 | tee -a "${LOG_FILE}" & # Dump all log retry ls "${REG_STORAGE_POOL_LINK}" > /dev/null fi stargz-snapshotter-0.14.3/script/benchmark/hello-bench/run.sh000077500000000000000000000114021440204344700242420ustar00rootroot00000000000000#!/bin/bash # Copyright The containerd Authors. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. set -euo pipefail LEGACY_MODE="legacy" ESTARGZ_NOOPT_MODE="estargz-noopt" ESTARGZ_MODE="estargz" ZSTDCHUNKED_MODE="zstdchunked" CONTEXT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )/" REPO="${CONTEXT}../../../" # NOTE: The entire contents of containerd/stargz-snapshotter are located in # the testing container so utils.sh is visible from this script during runtime. # TODO: Refactor the code dependencies and pack them in the container without # expecting and relying on volumes. source "${REPO}/script/util/utils.sh" MEASURING_SCRIPT="${REPO}/script/benchmark/hello-bench/src/hello.py" BENCHMARKOUT_MARK_OUTPUT="BENCHMARK_OUTPUT: " if [ $# -lt 1 ] ; then echo "Specify benchmark target." echo "Ex) ${0} --all" echo "Ex) ${0} alpine busybox" exit 1 fi TARGET_REPOSITORY="${1}" TARGET_IMAGES=${@:2} NUM_OF_SAMPLES="${BENCHMARK_SAMPLES_NUM:-1}" REBOOT_SCRIPT= if [ "${BENCHMARK_RUNTIME_MODE}" == "containerd" ] ; then REBOOT_SCRIPT="${REPO}/script/benchmark/hello-bench/reboot_containerd.sh" elif [ "${BENCHMARK_RUNTIME_MODE}" == "podman" ] ; then REBOOT_SCRIPT="${REPO}/script/benchmark/hello-bench/reboot_store.sh" else echo "Unknown runtime: ${BENCHMARK_RUNTIME_MODE}" exit 1 fi TMP_LOG_FILE=$(mktemp) WORKLOADS_LIST=$(mktemp) function cleanup { local ORG_EXIT_CODE="${1}" rm "${TMP_LOG_FILE}" || true rm "${WORKLOADS_LIST}" exit "${ORG_EXIT_CODE}" } trap 'cleanup "$?"' EXIT SIGHUP SIGINT SIGQUIT SIGTERM function output { echo "${BENCHMARKOUT_MARK_OUTPUT}${1}" } function measure { local OPTION="${1}" local REPOSITORY="${2}" "${MEASURING_SCRIPT}" ${OPTION} --repository=${REPOSITORY} --op=run --runtime="${BENCHMARK_RUNTIME_MODE}" ${@:3} } if [[ -z "${BENCHMARK_PROFILE:-}" ]]; then echo "Run single experiment" additional_flags='--experiments=1' else echo "Run the experiment for ${BENCHMARK_PROFILE}s" additional_flags="--profile=$BENCHMARK_PROFILE" fi mkdir -p /tmp/hello-bench-output echo "=========" echo "SPEC LIST" echo "=========" uname -r cat /etc/os-release cat /proc/cpuinfo cat /proc/meminfo mount df echo "=========" echo "BENCHMARK" echo "=========" output "[" for SAMPLE_NO in $(seq ${NUM_OF_SAMPLES}) ; do echo -n "" > "${WORKLOADS_LIST}" # Randomize workloads for IMAGE in ${TARGET_IMAGES} ; do for MODE in ${LEGACY_MODE} ${ESTARGZ_NOOPT_MODE} ${ESTARGZ_MODE} ${ZSTDCHUNKED_MODE} ; do echo "${IMAGE},${MODE}" >> "${WORKLOADS_LIST}" done done sort -R -o "${WORKLOADS_LIST}" "${WORKLOADS_LIST}" echo "Workloads of iteration [${SAMPLE_NO}]" cat "${WORKLOADS_LIST}" # Run the workloads for THEWL in $(cat "${WORKLOADS_LIST}") ; do echo "The workload is ${THEWL}" IMAGE=$(echo "${THEWL}" | cut -d ',' -f 1) MODE=$(echo "${THEWL}" | cut -d ',' -f 2) echo "===== Measuring [${SAMPLE_NO}] ${IMAGE} (${MODE}) =====" if [ "${MODE}" == "${LEGACY_MODE}" ] ; then # disable lazy pulling DISABLE_ESTARGZ="true" "${REBOOT_SCRIPT}" measure "--mode=legacy" ${TARGET_REPOSITORY} ${IMAGE} "$additional_flags" fi if [ "${MODE}" == "${ESTARGZ_NOOPT_MODE}" ] ; then echo -n "" > "${TMP_LOG_FILE}" # disable prefetch DISABLE_PREFETCH="true" LOG_FILE="${TMP_LOG_FILE}" "${REBOOT_SCRIPT}" measure "--mode=estargz-noopt" ${TARGET_REPOSITORY} ${IMAGE} "$additional_flags" check_remote_snapshots "${TMP_LOG_FILE}" fi if [ "${MODE}" == "${ESTARGZ_MODE}" ] ; then echo -n "" > "${TMP_LOG_FILE}" LOG_FILE="${TMP_LOG_FILE}" "${REBOOT_SCRIPT}" measure "--mode=estargz" ${TARGET_REPOSITORY} ${IMAGE} "$additional_flags" check_remote_snapshots "${TMP_LOG_FILE}" fi if [ "${MODE}" == "${ZSTDCHUNKED_MODE}" ] ; then echo -n "" > "${TMP_LOG_FILE}" LOG_FILE="${TMP_LOG_FILE}" "${REBOOT_SCRIPT}" measure "--mode=zstdchunked" ${TARGET_REPOSITORY} ${IMAGE} "$additional_flags" check_remote_snapshots "${TMP_LOG_FILE}" fi done done output "]" stargz-snapshotter-0.14.3/script/benchmark/hello-bench/src/000077500000000000000000000000001440204344700236705ustar00rootroot00000000000000stargz-snapshotter-0.14.3/script/benchmark/hello-bench/src/elasticsearch/000077500000000000000000000000001440204344700265025ustar00rootroot00000000000000stargz-snapshotter-0.14.3/script/benchmark/hello-bench/src/elasticsearch/elasticsearch.yml000066400000000000000000000000341440204344700320340ustar00rootroot00000000000000discovery.type: single-node stargz-snapshotter-0.14.3/script/benchmark/hello-bench/src/gcc/000077500000000000000000000000001440204344700244245ustar00rootroot00000000000000stargz-snapshotter-0.14.3/script/benchmark/hello-bench/src/gcc/main.c000066400000000000000000000001161440204344700255120ustar00rootroot00000000000000#include int main(int argc, char *argv[]) { printf("hello\n"); } stargz-snapshotter-0.14.3/script/benchmark/hello-bench/src/go/000077500000000000000000000000001440204344700242755ustar00rootroot00000000000000stargz-snapshotter-0.14.3/script/benchmark/hello-bench/src/go/main.go000066400000000000000000000012261440204344700255510ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package main import "fmt" func main() { fmt.Println("hello") } stargz-snapshotter-0.14.3/script/benchmark/hello-bench/src/hello.py000077500000000000000000000610651440204344700253600ustar00rootroot00000000000000#!/usr/bin/env python # Copyright The containerd Authors. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # The MIT License (MIT) # # Copyright (c) 2015 Tintri # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in all # copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. import os, sys, subprocess, select, random, urllib2, time, json, tempfile, shutil, itertools TMP_DIR = tempfile.mkdtemp() LEGACY_MODE = "legacy" ESTARGZ_NOOPT_MODE = "estargz-noopt" ESTARGZ_MODE = "estargz" ZSTDCHUNKED_MODE = "zstdchunked" DEFAULT_OPTIMIZER = "ctr-remote image optimize --oci" DEFAULT_PULLER = "nerdctl image pull" DEFAULT_PUSHER = "nerdctl image push" DEFAULT_TAGGER = "nerdctl image tag" BENCHMARKOUT_MARK = "BENCHMARK_OUTPUT: " CTR="ctr" PODMAN="podman" def exit(status): # cleanup shutil.rmtree(TMP_DIR) sys.exit(status) def tmp_path(): tmp_path.nxt += 1 return os.path.join(TMP_DIR, str(tmp_path.nxt)) tmp_path.nxt = 0 def tmp_copy(src): dst = tmp_path() if os.path.isdir(src): shutil.copytree(src, dst) else: shutil.copyfile(src, dst) return dst def genargs_for_optimization(arg): if arg == None or arg == "": return "" else: return '-args \'["%s"]\'' % arg.replace('"', '\\\"').replace('\'', '\'"\'"\'') def format_repo(mode, repository, name): if mode == ESTARGZ_MODE: return "%s/%s-esgz" % (repository, name) elif mode == ESTARGZ_NOOPT_MODE: return "%s/%s-esgz-noopt" % (repository, name) elif mode == ZSTDCHUNKED_MODE: return "%s/%s-zstdchunked" % (repository, name) else: return "%s/%s-org" % (repository, name) class RunArgs: def __init__(self, env={}, arg='', stdin='', stdin_sh='sh', waitline='', mount=[]): self.env = env self.arg = arg self.stdin = stdin self.stdin_sh = stdin_sh self.waitline = waitline self.mount = mount class Bench: def __init__(self, name, category='other'): self.name = name self.category = category def __str__(self): return json.dumps(self.__dict__) class BenchRunner: ECHO_HELLO = set(['alpine:3.15.3', 'nixos/nix:2.3.12', 'fedora:35', 'ubuntu:22.04']) CMD_ARG_WAIT = {'rethinkdb:2.4.1': RunArgs(waitline='Server ready'), 'glassfish:4.1-jdk8': RunArgs(waitline='Running GlassFish'), 'drupal:9.3.9': RunArgs(waitline='apache2 -D FOREGROUND'), 'jenkins:2.60.3': RunArgs(waitline='Jenkins is fully up and running'), 'redis:6.2.6': RunArgs(waitline='Ready to accept connections'), 'tomcat:10.1.0-jdk17-openjdk-bullseye': RunArgs(waitline='Server startup'), 'postgres:14.2': RunArgs(waitline='database system is ready to accept connections', env={'POSTGRES_PASSWORD': 'abc'}), 'mariadb:10.7.3': RunArgs(waitline='mysqld: ready for connections', env={'MYSQL_ROOT_PASSWORD': 'abc'}), 'wordpress:5.9.2': RunArgs(waitline='apache2 -D FOREGROUND'), 'php:8.1.4-apache-bullseye': RunArgs(waitline='apache2 -D FOREGROUND'), 'rabbitmq:3.9.14': RunArgs(waitline='Server startup complete'), 'elasticsearch:8.1.1': RunArgs(waitline='"started"', mount=[('elasticsearch/elasticsearch.yml', '/usr/share/elasticsearch/config/elasticsearch.yml')]), } CMD_STDIN = {'php:8.1.4': RunArgs(stdin='php -r "echo \\\"hello\\n\\\";"; exit\n'), 'gcc:11.2.0': RunArgs(stdin='cd /src; gcc main.c; ./a.out; exit\n', mount=[('gcc', '/src')]), 'golang:1.18': RunArgs(stdin='cd /go/src; go run main.go; exit\n', mount=[('go', '/go/src')]), 'jruby:9.3.4': RunArgs(stdin='jruby -e "puts \\\"hello\\\""; exit\n'), 'r-base:4.1.3': RunArgs(stdin='sprintf("hello")\nq()\n', stdin_sh='R --no-save'), } CMD_ARG = {'perl:5.34.1': RunArgs(arg='perl -e \'print("hello\\n")\''), 'python:3.10': RunArgs(arg='python -c \'print("hello")\''), 'pypy:3.9': RunArgs(arg='pypy3 -c \'print("hello")\''), 'node:17.8.0': RunArgs(arg='node -e \'console.log("hello")\''), } # complete listing ALL = dict([(b.name, b) for b in [Bench('alpine:3.15.3', 'distro'), Bench('fedora:35', 'distro'), Bench('ubuntu:22.04', 'distro'), Bench('rethinkdb:2.4.1', 'database'), Bench('postgres:14.2', 'database'), Bench('redis:6.2.6', 'database'), Bench('mariadb:10.7.3', 'database'), Bench('python:3.10', 'language'), Bench('golang:1.18', 'language'), Bench('gcc:11.2.0', 'language'), Bench('jruby:9.3.4', 'language'), Bench('perl:5.34.1', 'language'), Bench('php:8.1.4', 'language'), Bench('pypy:3.9', 'language'), Bench('r-base:4.1.3', 'language'), Bench('drupal:9.3.9'), Bench('jenkins:2.60.3'), Bench('node:17.8.0'), Bench('tomcat:10.1.0-jdk17-openjdk-bullseye', 'web-server'), Bench('wordpress:5.9.2', 'web-server'), Bench('php:8.1.4-apache-bullseye', 'web-server'), Bench('rabbitmq:3.9.14'), Bench('elasticsearch:8.1.1'), # needs "--srcrepository=docker.io" Bench('nixos/nix:2.3.12'), ]]) def __init__(self, repository='docker.io/library', srcrepository='docker.io/library', mode=LEGACY_MODE, optimizer=DEFAULT_OPTIMIZER, puller=DEFAULT_PULLER, pusher=DEFAULT_PUSHER, runtime="containerd", profile=0): if runtime == "containerd": self.controller = ContainerdController(mode == ESTARGZ_NOOPT_MODE or mode == ESTARGZ_MODE or mode == ZSTDCHUNKED_MODE) elif runtime == "podman": self.controller = PodmanController() else: print 'Unknown runtime mode: '+runtime exit(1) self.repository = repository self.srcrepository = srcrepository self.mode = mode self.optimizer = optimizer self.puller = puller self.pusher = pusher profile = int(profile) if profile > 0: self.controller.start_profile(profile) def cleanup(self, cid, bench): self.controller.cleanup(cid, self.fully_qualify(bench.name)) def fully_qualify(self, repo): return format_repo(self.mode, self.repository, repo) def run_task(self, cid): cmd = self.controller.task_start_cmd(cid) startrun = time.time() rc = os.system(cmd) runtime = time.time() - startrun assert(rc == 0) return runtime def run_echo_hello(self, image, cid): cmd = self.controller.create_echo_hello_cmd(image, cid) startcreate = time.time() rc = os.system(cmd) createtime = time.time() - startcreate assert(rc == 0) return createtime, self.run_task(cid) def run_cmd_arg(self, image, cid, runargs): assert(len(runargs.mount) == 0) cmd = self.controller.create_cmd_arg_cmd(image, cid, runargs) startcreate = time.time() rc = os.system(cmd) createtime = time.time() - startcreate assert(rc == 0) return createtime, self.run_task(cid) def run_cmd_arg_wait(self, image, cid, runargs): cmd = self.controller.create_cmd_arg_wait_cmd(image, cid, runargs) startcreate = time.time() rc = os.system(cmd) createtime = time.time() - startcreate assert(rc == 0) cmd = self.controller.task_start_cmd(cid) runtime = 0 startrun = time.time() # line buffer output p = subprocess.Popen(cmd, shell=True, bufsize=1, stderr=subprocess.STDOUT, stdout=subprocess.PIPE) while True: l = p.stdout.readline() if l == '': continue print 'out: ' + l.strip() # are we done? if l.find(runargs.waitline) >= 0: runtime = time.time() - startrun # cleanup print 'DONE' cmd = self.controller.task_kill_cmd(cid) rc = os.system(cmd) assert(rc == 0) break p.wait() return createtime, runtime def run_cmd_stdin(self, image, cid, runargs): cmd = self.controller.create_cmd_stdin_cmd(image, cid, runargs) startcreate = time.time() rc = os.system(cmd) createtime = time.time() - startcreate assert(rc == 0) cmd = self.controller.task_start_cmd(cid) startrun = time.time() p = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) print runargs.stdin out, _ = p.communicate(runargs.stdin) runtime = time.time() - startrun print out assert(p.returncode == 0) return createtime, runtime def run(self, bench, cid): name = bench.name image = self.fully_qualify(bench.name) print "Pulling the image..." pullcmd = self.controller.pull_cmd(image) startpull = time.time() rc = os.system(pullcmd) assert(rc == 0) pulltime = time.time() - startpull runtime = 0 createtime = 0 if name in BenchRunner.ECHO_HELLO: createtime, runtime = self.run_echo_hello(image=image, cid=cid) elif name in BenchRunner.CMD_ARG: createtime, runtime = self.run_cmd_arg(image=image, cid=cid, runargs=BenchRunner.CMD_ARG[name]) elif name in BenchRunner.CMD_ARG_WAIT: createtime, runtime = self.run_cmd_arg_wait(image=image, cid=cid, runargs=BenchRunner.CMD_ARG_WAIT[name]) elif name in BenchRunner.CMD_STDIN: createtime, runtime = self.run_cmd_stdin(image=image, cid=cid, runargs=BenchRunner.CMD_STDIN[name]) else: print 'Unknown bench: '+name exit(1) return pulltime, createtime, runtime def convert_echo_hello(self, src, dest, option): period=10 cmd = ('%s %s -cni -period %s -entrypoint \'["/bin/sh", "-c"]\' -args \'["echo hello"]\' %s %s' % (self.optimizer, option, period, src, dest)) print cmd rc = os.system(cmd) assert(rc == 0) def convert_cmd_arg(self, src, dest, runargs, option): period = 30 assert(len(runargs.mount) == 0) entry = "" if runargs.arg != "": # FIXME: this is naive... entry = '-entrypoint \'["/bin/sh", "-c"]\'' cmd = ('%s %s -cni -period %s %s %s %s %s' % (self.optimizer, option, period, entry, genargs_for_optimization(runargs.arg), src, dest)) print cmd rc = os.system(cmd) assert(rc == 0) def convert_cmd_arg_wait(self, src, dest, runargs, option): mounts = '' for a,b in runargs.mount: a = os.path.join(os.path.dirname(os.path.abspath(__file__)), a) a = tmp_copy(a) mounts += '--mount type=bind,src=%s,dst=%s,options=rbind ' % (a,b) period = 90 env = ' '.join(['-env %s=%s' % (k,v) for k,v in runargs.env.iteritems()]) cmd = ('%s %s -cni -period %s %s %s %s %s %s' % (self.optimizer, option, period, mounts, env, genargs_for_optimization(runargs.arg), src, dest)) print cmd rc = os.system(cmd) assert(rc == 0) def convert_cmd_stdin(self, src, dest, runargs, option): mounts = '' for a,b in runargs.mount: a = os.path.join(os.path.dirname(os.path.abspath(__file__)), a) a = tmp_copy(a) mounts += '--mount type=bind,src=%s,dst=%s,options=rbind ' % (a,b) period = 60 cmd = ('%s %s -i -cni -period %s %s -entrypoint \'["/bin/sh", "-c"]\' %s %s %s' % (self.optimizer, option, period, mounts, genargs_for_optimization(runargs.stdin_sh), src, dest)) print cmd p = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE) print runargs.stdin out,_ = p.communicate(runargs.stdin) print out p.wait() assert(p.returncode == 0) def push_img(self, dest): cmd = '%s %s' % (self.pusher, dest) print cmd rc = os.system(cmd) assert(rc == 0) def pull_img(self, src): cmd = '%s %s' % (self.puller, src) print cmd rc = os.system(cmd) assert(rc == 0) def copy_img(self, src, dest): cmd = 'crane copy %s %s' % (src, dest) print cmd rc = os.system(cmd) assert(rc == 0) def convert_and_push_img(self, src, dest): self.pull_img(src) cmd = '%s --no-optimize %s %s' % (self.optimizer, src, dest) print cmd rc = os.system(cmd) assert(rc == 0) self.push_img(dest) def optimize_img(self, name, src, dest, option): self.pull_img(src) if name in BenchRunner.ECHO_HELLO: self.convert_echo_hello(src=src, dest=dest, option=option) elif name in BenchRunner.CMD_ARG: self.convert_cmd_arg(src=src, dest=dest, runargs=BenchRunner.CMD_ARG[name], option=option) elif name in BenchRunner.CMD_ARG_WAIT: self.convert_cmd_arg_wait(src=src, dest=dest, runargs=BenchRunner.CMD_ARG_WAIT[name], option=option) elif name in BenchRunner.CMD_STDIN: self.convert_cmd_stdin(src=src, dest=dest, runargs=BenchRunner.CMD_STDIN[name], option=option) else: print 'Unknown bench: '+name exit(1) self.push_img(dest) def prepare(self, bench): name = bench.name src = '%s/%s' % (self.srcrepository, name) self.copy_img(src=src, dest=format_repo(LEGACY_MODE, self.repository, name)) self.convert_and_push_img(src=src, dest=format_repo(ESTARGZ_NOOPT_MODE, self.repository, name)) self.optimize_img(name=name, src=src, dest=format_repo(ESTARGZ_MODE, self.repository, name), option="") self.optimize_img(name=name, src=src, dest=format_repo(ZSTDCHUNKED_MODE, self.repository, name), option="--zstdchunked") def operation(self, op, bench, cid): if op == 'run': return self.run(bench, cid) elif op == 'prepare': self.prepare(bench) return 0, 0, 0 else: print 'Unknown operation: '+op exit(1) class ContainerdController: def __init__(self, is_lazypull=False): self.is_lazypull = is_lazypull def pull_cmd(self, image): base_cmd = "%s i pull" % CTR if self.is_lazypull: base_cmd = "ctr-remote i rpull" cmd = '%s %s' % (base_cmd, image) print cmd return cmd def create_echo_hello_cmd(self, image, cid): snapshotter_opt = "" if self.is_lazypull: snapshotter_opt = "--snapshotter=stargz" cmd = '%s c create --net-host %s -- %s %s echo hello' % (CTR, snapshotter_opt, image, cid) print cmd return cmd def create_cmd_arg_cmd(self, image, cid, runargs): snapshotter_opt = "" if self.is_lazypull: snapshotter_opt = "--snapshotter=stargz" cmd = '%s c create --net-host %s ' % (CTR, snapshotter_opt) cmd += '-- %s %s ' % (image, cid) cmd += runargs.arg print cmd return cmd def create_cmd_arg_wait_cmd(self, image, cid, runargs): snapshotter_opt = "" if self.is_lazypull: snapshotter_opt = "--snapshotter=stargz" env = ' '.join(['--env %s=%s' % (k,v) for k,v in runargs.env.iteritems()]) cmd = '%s c create --net-host %s %s '% (CTR, snapshotter_opt, env) for a,b in runargs.mount: a = os.path.join(os.path.dirname(os.path.abspath(__file__)), a) a = tmp_copy(a) cmd += '--mount type=bind,src=%s,dst=%s,options=rbind ' % (a,b) cmd += '-- %s %s %s' % (image, cid, runargs.arg) print cmd return cmd def create_cmd_stdin_cmd(self, image, cid, runargs): snapshotter_opt = "" if self.is_lazypull: snapshotter_opt = "--snapshotter=stargz" cmd = '%s c create --net-host %s ' % (CTR, snapshotter_opt) for a,b in runargs.mount: a = os.path.join(os.path.dirname(os.path.abspath(__file__)), a) a = tmp_copy(a) cmd += '--mount type=bind,src=%s,dst=%s,options=rbind ' % (a,b) cmd += '-- %s %s ' % (image, cid) if runargs.stdin_sh: cmd += runargs.stdin_sh # e.g., sh -c print cmd return cmd def task_start_cmd(self, cid): cmd = '%s t start %s' % (CTR, cid) print cmd return cmd def task_kill_cmd(self, cid): cmd = '%s t kill -s 9 %s' % (CTR, cid) print cmd return cmd def cleanup(self, name, image): print "Cleaning up environment..." cmd = '%s t kill -s 9 %s' % (CTR, name) print cmd rc = os.system(cmd) # sometimes containers already exit. we ignore the failure. cmd = '%s c rm %s' % (CTR, name) print cmd rc = os.system(cmd) assert(rc == 0) cmd = '%s image rm %s' % (CTR, image) print cmd rc = os.system(cmd) assert(rc == 0) def start_profile(self, seconds): out = open('/tmp/hello-bench-output/profile-%d.out' % (random.randint(1,1000000)), 'w') p = subprocess.Popen( [CTR, 'pprof', '-d', '/run/containerd-stargz-grpc/debug.sock', 'profile', '-s', '%ds' % (seconds)], stdout=out ) class PodmanController: def pull_cmd(self, image): cmd = '%s pull docker://%s' % (PODMAN, image) print cmd return cmd def create_echo_hello_cmd(self, image, cid): cmd = '%s create --name %s docker://%s echo hello' % (PODMAN, cid, image) print cmd return cmd def create_cmd_arg_cmd(self, image, cid, runargs): cmd = '%s create --name %s docker://%s ' % (PODMAN, cid, image) cmd += runargs.arg print cmd return cmd def create_cmd_arg_wait_cmd(self, image, cid, runargs): env = ' '.join(['--env %s=%s' % (k,v) for k,v in runargs.env.iteritems()]) cmd = '%s create %s --name %s '% (PODMAN, env, cid) for a,b in runargs.mount: a = os.path.join(os.path.dirname(os.path.abspath(__file__)), a) a = tmp_copy(a) cmd += '--mount type=bind,src=%s,dst=%s ' % (a,b) cmd += ' docker://%s %s ' % (image, runargs.arg) print cmd return cmd def create_cmd_stdin_cmd(self, image, cid, runargs): cmd = '%s create -i ' % PODMAN for a,b in runargs.mount: a = os.path.join(os.path.dirname(os.path.abspath(__file__)), a) a = tmp_copy(a) cmd += '--mount type=bind,src=%s,dst=%s ' % (a,b) cmd += '--name %s docker://%s ' % (cid, image) if runargs.stdin_sh: cmd += runargs.stdin_sh # e.g., sh -c print cmd return cmd def task_start_cmd(self, cid): cmd = '%s start -a %s' % (PODMAN, cid) print cmd return cmd def task_kill_cmd(self, cid): cmd = '%s kill -s 9 %s' % (PODMAN, cid) print cmd return cmd def cleanup(self, name, image): print "Cleaning up environment..." cmd = '%s kill -s 9 %s' % (PODMAN, name) print cmd rc = os.system(cmd) # sometimes containers already exit. we ignore the failure. cmd = '%s rm %s' % (PODMAN, name) print cmd rc = os.system(cmd) assert(rc == 0) cmd = '%s image rm %s' % (PODMAN, image) print cmd rc = os.system(cmd) assert(rc == 0) cmd = os.path.join(os.path.dirname(os.path.abspath(__file__)), '../reboot_store.sh') print cmd rc = os.system(cmd) assert(rc == 0) def main(): if len(sys.argv) == 1: print 'Usage: bench.py [OPTIONS] [BENCHMARKS]' print 'OPTIONS:' print '--repository=' print '--srcrepository=' print '--all' print '--list' print '--list-json' print '--experiments' print '--profile=' print '--runtime' print '--op=(prepare|run)' print '--mode=(%s|%s|%s)' % (LEGACY_MODE, ESTARGZ_NOOPT_MODE, ESTARGZ_MODE, ZSTDCHUNKED_MODE) exit(1) benches = [] kvargs = {} # parse args for arg in sys.argv[1:]: if arg.startswith('--'): parts = arg[2:].split('=') if len(parts) == 2: kvargs[parts[0]] = parts[1] elif parts[0] == 'all': benches.extend(BenchRunner.ALL.values()) elif parts[0] == 'list': template = '%-16s\t%-20s' print template % ('CATEGORY', 'NAME') for b in sorted(BenchRunner.ALL.values(), key=lambda b:(b.category, b.name)): print template % (b.category, b.name) elif parts[0] == 'list-json': print json.dumps([b.__dict__ for b in BenchRunner.ALL.values()]) else: benches.append(BenchRunner.ALL[arg]) op = kvargs.pop('op', 'run') trytimes = int(kvargs.pop('experiments', '1')) if not op == "run": trytimes = 1 experiments = range(trytimes) profile = int(kvargs.get('profile', 0)) if profile > 0: experiments = itertools.count(start=0) # run benchmarks runner = BenchRunner(**kvargs) for bench in benches: cid = '%s_bench_%d' % (bench.name.replace(':', '-').replace('/', '-'), random.randint(1,1000000)) elapsed_times = [] pull_times = [] create_times = [] run_times = [] for_start = time.time() for i in experiments: start = time.time() pulltime, createtime, runtime = runner.operation(op, bench, cid) elapsed = time.time() - start if op == "run": runner.cleanup(cid, bench) elapsed_times.append(elapsed) pull_times.append(pulltime) create_times.append(createtime) run_times.append(runtime) print 'ITERATION %s:' % i print 'elapsed %s' % elapsed print 'pull %s' % pulltime print 'create %s' % createtime print 'run %s' % runtime if profile > 0 and time.time() - for_start > profile: break row = {'mode':'%s' % runner.mode, 'repo':bench.name, 'bench':bench.name, 'elapsed':sum(elapsed_times) / len(elapsed_times), 'elapsed_pull':sum(pull_times) / len(pull_times), 'elapsed_create':sum(create_times) / len(create_times), 'elapsed_run':sum(run_times) / len(run_times)} js = json.dumps(row) print '%s%s,' % (BENCHMARKOUT_MARK, js) sys.stdout.flush() if __name__ == '__main__': main() exit(0) stargz-snapshotter-0.14.3/script/benchmark/test.sh000077500000000000000000000135471440204344700222510ustar00rootroot00000000000000#!/bin/bash # Copyright The containerd Authors. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. set -euo pipefail CONTEXT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )/" REPO="${CONTEXT}../../" # This project's Dockerfile doesn't work without BuildKit. export DOCKER_BUILDKIT=1 BENCHMARK_TARGETS="${BENCHMARK_TARGETS:-}" if [[ -z "$BENCHMARK_TARGETS" ]]; then echo "BENCHMARK_TARGETS must be specified." exit 1 fi BENCHMARKING_BASE_IMAGE_NAME="benchmark-image-base" BENCHMARKING_NODE_IMAGE_NAME="benchmark-image-test" BENCHMARKING_NODE=hello-bench BENCHMARKING_CONTAINER=hello-bench-container BENCHMARK_USER=${BENCHMARK_USER:-stargz-containers} export BENCHMARK_RUNTIME_MODE=${BENCHMARK_RUNTIME_MODE:-containerd} BENCHMARKING_TARGET_BASE_IMAGE= BENCHMARKING_TARGET_CONFIG_DIR= if [ "${BENCHMARK_RUNTIME_MODE}" == "containerd" ] ; then BENCHMARKING_TARGET_BASE_IMAGE=snapshotter-base BENCHMARKING_TARGET_CONFIG_DIR="${CONTEXT}/config-containerd" elif [ "${BENCHMARK_RUNTIME_MODE}" == "podman" ] ; then BENCHMARKING_TARGET_BASE_IMAGE=podman-base BENCHMARKING_TARGET_CONFIG_DIR="${CONTEXT}/config-podman" else echo "Unknown runtime: ${BENCHMARK_RUNTIME_MODE}" exit 1 fi if [ "${BENCHMARKING_NO_RECREATE:-}" != "true" ] ; then echo "Preparing node image..." docker build ${DOCKER_BUILD_ARGS:-} -t "${BENCHMARKING_BASE_IMAGE_NAME}" \ --target "${BENCHMARKING_TARGET_BASE_IMAGE}" "${REPO}" fi DOCKER_COMPOSE_YAML=$(mktemp) TMP_CONTEXT=$(mktemp -d) function cleanup { local ORG_EXIT_CODE="${1}" rm "${DOCKER_COMPOSE_YAML}" || true rm -rf "${TMP_CONTEXT}" || true exit "${ORG_EXIT_CODE}" } trap 'cleanup "$?"' EXIT SIGHUP SIGINT SIGQUIT SIGTERM cp -R "${BENCHMARKING_TARGET_CONFIG_DIR}" "${TMP_CONTEXT}/config" cat < "${TMP_CONTEXT}/Dockerfile" FROM ${BENCHMARKING_BASE_IMAGE_NAME} RUN apt-get update -y && \ apt-get --no-install-recommends install -y python jq && \ go install github.com/google/go-containerregistry/cmd/crane@v0.8.0 COPY ./config / ENV CONTAINERD_SNAPSHOTTER="" ENTRYPOINT [ "sleep", "infinity" ] EOF docker build -t "${BENCHMARKING_NODE_IMAGE_NAME}" ${DOCKER_BUILD_ARGS:-} "${TMP_CONTEXT}" echo "Preparing docker-compose.yml..." cat < "${DOCKER_COMPOSE_YAML}" version: "3.7" services: ${BENCHMARKING_NODE}: image: ${BENCHMARKING_NODE_IMAGE_NAME} container_name: ${BENCHMARKING_CONTAINER} privileged: true init: true working_dir: /go/src/github.com/containerd/stargz-snapshotter environment: - NO_PROXY=127.0.0.1,localhost - HTTP_PROXY=${HTTP_PROXY:-} - HTTPS_PROXY=${HTTPS_PROXY:-} - http_proxy=${http_proxy:-} - https_proxy=${https_proxy:-} tmpfs: - /tmp:exec,mode=777 volumes: - "${REPO}:/go/src/github.com/containerd/stargz-snapshotter:ro" - "/dev/fuse:/dev/fuse" - "containerd-data:/var/lib/containerd:delegated" - "containerd-stargz-grpc-data:/var/lib/containerd-stargz-grpc:delegated" - "containers-data:/var/lib/containers:delegated" - "additional-store-data:/var/lib/stargz-store:delegated" volumes: containerd-data: containerd-stargz-grpc-data: containers-data: additional-store-data: EOF echo "Preparing for benchmark..." OUTPUTDIR="${BENCHMARK_RESULT_DIR:-}" if [ "${OUTPUTDIR}" == "" ] ; then OUTPUTDIR=$(mktemp -d) fi echo "See output for >>> ${OUTPUTDIR}" LOG_DIR="${BENCHMARK_LOG_DIR:-}" if [ "${LOG_DIR}" == "" ] ; then LOG_DIR=$(mktemp -d) fi LOG_FILE="${LOG_DIR}/containerd-stargz-grpc-benchmark-$(date '+%Y%m%d%H%M%S')" touch "${LOG_FILE}" echo "Logging to >>> ${LOG_FILE} (will finally be stored under ${OUTPUTDIR})" echo "Benchmarking..." FAIL= if ! ( cd "${CONTEXT}" && \ docker-compose -f "${DOCKER_COMPOSE_YAML}" build ${DOCKER_BUILD_ARGS:-} \ "${BENCHMARKING_NODE}" && \ docker-compose -f "${DOCKER_COMPOSE_YAML}" up -d --force-recreate && \ docker exec \ -e BENCHMARK_RUNTIME_MODE -e BENCHMARK_SAMPLES_NUM -e BENCHMARK_PROFILE \ -i "${BENCHMARKING_CONTAINER}" \ script/benchmark/hello-bench/run.sh \ "${BENCHMARK_REGISTRY:-ghcr.io}/${BENCHMARK_USER}" \ ${BENCHMARK_TARGETS} &> "${LOG_FILE}" ) ; then echo "Failed to run benchmark." FAIL=true fi echo "Collecting data inside ${BENCHMARKING_CONTAINER}..." docker exec -i "${BENCHMARKING_CONTAINER}" \ tar zcf - -C /tmp/hello-bench-output . | tar zxvf - -C "$OUTPUTDIR" echo "Harvesting log ${LOG_FILE} -> ${OUTPUTDIR} ..." tar zcvf "${OUTPUTDIR}/result.log.tar.gz" "${LOG_FILE}" if [ "${FAIL}" != "true" ] ; then echo "Formatting output..." if ! ( tar zOxf "${OUTPUTDIR}/result.log.tar.gz" | "${CONTEXT}/tools/format.sh" > "${OUTPUTDIR}/result.json" && \ cat "${OUTPUTDIR}/result.json" | "${CONTEXT}/tools/plot.sh" "${OUTPUTDIR}" && \ cat "${OUTPUTDIR}/result.json" | "${CONTEXT}/tools/percentiles.sh" "${OUTPUTDIR}" && \ cat "${OUTPUTDIR}/result.json" | "${CONTEXT}/tools/table.sh" > "${OUTPUTDIR}/result.md" && \ cat "${OUTPUTDIR}/result.json" | "${CONTEXT}/tools/csv.sh" > "${OUTPUTDIR}/result.csv" ) ; then echo "Failed to formatting output (but you can try it manually from ${OUTPUTDIR})" FAIL=true fi fi echo "Cleaning up environment..." docker-compose -f "${DOCKER_COMPOSE_YAML}" down -v if [ "${FAIL}" == "true" ] ; then exit 1 fi exit 0 stargz-snapshotter-0.14.3/script/benchmark/tools/000077500000000000000000000000001440204344700220615ustar00rootroot00000000000000stargz-snapshotter-0.14.3/script/benchmark/tools/csv.sh000077500000000000000000000044261440204344700232210ustar00rootroot00000000000000#!/bin/bash # Copyright The containerd Authors. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. set -euo pipefail JSON="$(mktemp)" cat > "${JSON}" CONTEXT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )/" source "${CONTEXT}/util.sh" MODES=( ${TARGET_MODES:-} ) if [ ${#MODES[@]} -eq 0 ] ; then MODES=("legacy" "estargz-noopt" "estargz" "zstdchunked") fi IMAGES=( ${TARGET_IMAGES:-} ) if [ ${#IMAGES[@]} -eq 0 ] ; then IMAGES=( $(cat "${JSON}" | jq -r '[ .[] | select(.mode=="'${MODES[0]}'").repo ] | unique[]') ) fi # Ensure we use the exact same number of samples among benchmarks MINSAMPLES= for IMGNAME in "${IMAGES[@]}" ; do for MODE in "${MODES[@]}"; do THEMIN=$(min_samples "${JSON}" "${IMGNAME}" "${MODE}") if [ "${MINSAMPLES}" == "" ] ; then MINSAMPLES="${THEMIN}" fi MINSAMPLES=$(echo "${MINSAMPLES} ${THEMIN}" | tr ' ' '\n' | sort -n | head -1) done done INDEX="image,operation" for MODE in "${MODES[@]}"; do INDEX="${INDEX},${MODE}" done echo "${INDEX}" for IMGNAME in "${IMAGES[@]}" ; do PULLLINE="${IMGNAME},pull" for MODE in "${MODES[@]}"; do PULLTIME=$(percentile "${JSON}" "${MINSAMPLES}" "${IMGNAME}" "${MODE}" "elapsed_pull") PULLLINE="${PULLLINE},${PULLTIME}" done echo "${PULLLINE}" CREATELINE="${IMGNAME},create" for MODE in "${MODES[@]}"; do CREATETIME=$(percentile "${JSON}" "${MINSAMPLES}" "${IMGNAME}" "${MODE}" "elapsed_create") CREATELINE="${CREATELINE},${CREATETIME}" done echo "${CREATELINE}" RUNLINE="${IMGNAME},run" for MODE in "${MODES[@]}"; do RUNTIME=$(percentile "${JSON}" "${MINSAMPLES}" "${IMGNAME}" "${MODE}" "elapsed_run") RUNLINE="${RUNLINE},${RUNTIME}" done echo "${RUNLINE}" done stargz-snapshotter-0.14.3/script/benchmark/tools/format.sh000077500000000000000000000014201440204344700237050ustar00rootroot00000000000000#!/bin/bash # Copyright The containerd Authors. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. set -euo pipefail OUTPUT_MARK="BENCHMARK_OUTPUT: " grep "${OUTPUT_MARK}" | sed -e 's/^'"${OUTPUT_MARK}"'//g' | sed -e ':begin;$!N;s/,\n\(\(}\|]\),*\)/\n\1/g;tbegin;P;D' stargz-snapshotter-0.14.3/script/benchmark/tools/percentiles.sh000077500000000000000000000065641440204344700247500ustar00rootroot00000000000000#!/bin/bash # Copyright The containerd Authors. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. set -euo pipefail JSON="$(mktemp)" cat > "${JSON}" CONTEXT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )/" source "${CONTEXT}/util.sh" if [ "${1}" == "" ] ; then echo "Specify directory for output" exit 1 fi DATADIR="${1}/" echo "output into: ${DATADIR}" MODES=( ${TARGET_MODES:-} ) if [ ${#MODES[@]} -eq 0 ] ; then MODES=("legacy" "estargz-noopt" "estargz" "zstdchunked") fi IMAGES=( ${TARGET_IMAGES:-} ) if [ ${#IMAGES[@]} -eq 0 ] ; then IMAGES=( $(cat "${JSON}" | jq -r '[ .[] | select(.mode=="'${MODES[0]}'").repo ] | unique[]') ) fi GRANULARITY="${BENCHMARK_PERCENTILES_GRANULARITY:-}" if [ "${GRANULARITY}" == "" ] ; then GRANULARITY="10" fi # Ensure we use the exact same number of samples among benchmarks MINSAMPLES= for IMGNAME in "${IMAGES[@]}" ; do for MODE in "${MODES[@]}"; do THEMIN=$(min_samples "${JSON}" "${IMGNAME}" "${MODE}") if [ "${MINSAMPLES}" == "" ] ; then MINSAMPLES="${THEMIN}" fi MINSAMPLES=$(echo "${MINSAMPLES} ${THEMIN}" | tr ' ' '\n' | sort -n | head -1) done done function template { local GRAPHFILE="${1}" local IMGNAME="${2}" local MODE="${3}" local OPERATION="${4}" local SAMPLES="${5}" cat < "${CSVFILE}" for MODE in "${MODES[@]}"; do for OPERATION in "pull" "create" "run" ; do DATAFILE="${RAWDATADIR}${IMAGE}-${MODE}-${OPERATION}.dat" PLTFILE="${PLTDATADIR}result-${IMAGE}-${MODE}-${OPERATION}.plt" template "${IMGDATADIR}result-${IMAGE}-${MODE}-${OPERATION}.png" \ "${IMGNAME}" "${MODE}" "${OPERATION}" "${MINSAMPLES}" > "${PLTFILE}" for PCTL in $(seq 0 "${GRANULARITY}" 100) ; do TIME=$(PERCENTILE=${PCTL} percentile "${JSON}" "${MINSAMPLES}" "${IMGNAME}" "${MODE}" "elapsed_${OPERATION}") echo "${PCTL} ${TIME}" >> "${DATAFILE}" echo "${IMGNAME},${MODE},${OPERATION},${PCTL},${TIME}" >> "${CSVFILE}" done echo 'plot "'"${DATAFILE}"'" using 0:2:xtic(1) with boxes lw 1 lc rgb "black" notitle' >> "${PLTFILE}" gnuplot "${PLTFILE}" done done done stargz-snapshotter-0.14.3/script/benchmark/tools/plot.sh000077500000000000000000000060641440204344700234040ustar00rootroot00000000000000#!/bin/bash # Copyright The containerd Authors. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. set -euo pipefail JSON="$(mktemp)" cat > "${JSON}" CONTEXT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )/" source "${CONTEXT}/util.sh" if [ "${1}" == "" ] ; then echo "Specify directory for output" exit 1 fi DATADIR="${1}/" echo "output into: ${DATADIR}" MODES=( ${TARGET_MODES:-} ) if [ ${#MODES[@]} -eq 0 ] ; then MODES=("legacy" "estargz-noopt" "estargz" "zstdchunked") fi IMAGES=( ${TARGET_IMAGES:-} ) if [ ${#IMAGES[@]} -eq 0 ] ; then IMAGES=( $(cat "${JSON}" | jq -r '[ .[] | select(.mode=="'${MODES[0]}'").repo ] | unique[]') ) fi # Ensure we use the exact same number of samples among benchmarks MINSAMPLES= for IMGNAME in "${IMAGES[@]}" ; do for MODE in "${MODES[@]}"; do THEMIN=$(min_samples "${JSON}" "${IMGNAME}" "${MODE}") if [ "${MINSAMPLES}" == "" ] ; then MINSAMPLES="${THEMIN}" fi MINSAMPLES=$(echo "${MINSAMPLES} ${THEMIN}" | tr ' ' '\n' | sort -n | head -1) done done PLTFILE_ALL="${DATADIR}result.plt" GRAPHFILE_ALL="${DATADIR}result.png" cat < "${PLTFILE_ALL}" set output '${GRAPHFILE_ALL}' set title "Time to take for starting up containers(${PERCENTILE} pctl., ${MINSAMPLES} samples)" set terminal png size 1000, 750 set style data histogram set style histogram rowstack gap 1 set style fill solid 1.0 border -1 set key autotitle columnheader set xtics rotate by -45 set ylabel 'time[sec]' set lmargin 10 set rmargin 5 set tmargin 5 set bmargin 7 plot \\ EOF NOTITLE= INDEX=1 for IMGNAME in "${IMAGES[@]}" ; do echo "[${INDEX}]Processing: ${IMGNAME}" IMAGE=$(echo "${IMGNAME}" | sed 's|[/:]|-|g') DATAFILE="${DATADIR}${IMAGE}.dat" SUFFIX=', \' if [ ${INDEX} -eq ${#IMAGES[@]} ] ; then SUFFIX='' fi echo "mode pull create run" > "${DATAFILE}" for MODE in "${MODES[@]}"; do PULLTIME=$(percentile "${JSON}" "${MINSAMPLES}" "${IMGNAME}" "${MODE}" "elapsed_pull") CREATETIME=$(percentile "${JSON}" "${MINSAMPLES}" "${IMGNAME}" "${MODE}" "elapsed_create") RUNTIME=$(percentile "${JSON}" "${MINSAMPLES}" "${IMGNAME}" "${MODE}" "elapsed_run") echo "${MODE} ${PULLTIME} ${CREATETIME} ${RUNTIME}" >> "${DATAFILE}" done echo 'newhistogram "'"${IMAGE}"'", "'"${DATAFILE}"'" u 2:xtic(1) fs pattern 1 lt -1 '"${NOTITLE}"', "" u 3 fs pattern 2 lt -1 '"${NOTITLE}"', "" u 4 fs pattern 3 lt -1 '"${NOTITLE}""${SUFFIX}" \ >> "${PLTFILE_ALL}" NOTITLE=notitle ((INDEX+=1)) done gnuplot "${PLTFILE_ALL}" stargz-snapshotter-0.14.3/script/benchmark/tools/table.sh000077500000000000000000000041151440204344700235100ustar00rootroot00000000000000#!/bin/bash # Copyright The containerd Authors. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. set -euo pipefail JSON="$(mktemp)" cat > "${JSON}" CONTEXT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )/" source "${CONTEXT}/util.sh" MODES=( ${TARGET_MODES:-} ) if [ ${#MODES[@]} -eq 0 ] ; then MODES=("legacy" "estargz-noopt" "estargz" "zstdchunked") fi IMAGES=( ${TARGET_IMAGES:-} ) if [ ${#IMAGES[@]} -eq 0 ] ; then IMAGES=( $(cat "${JSON}" | jq -r '[ .[] | select(.mode=="'${MODES[0]}'").repo ] | unique[]') ) fi # Ensure we use the exact same number of samples among benchmarks MINSAMPLES= for IMGNAME in "${IMAGES[@]}" ; do for MODE in "${MODES[@]}"; do THEMIN=$(min_samples "${JSON}" "${IMGNAME}" "${MODE}") if [ "${MINSAMPLES}" == "" ] ; then MINSAMPLES="${THEMIN}" fi MINSAMPLES=$(echo "${MINSAMPLES} ${THEMIN}" | tr ' ' '\n' | sort -n | head -1) done done cat < "${CALCTEMP}" local PYTHON_BIN= if which python &> /dev/null ; then PYTHON_BIN=python elif which python3 &> /dev/null ; then # Try also with python3 PYTHON_BIN=python3 else echo "Python not found" exit 1 fi cat < /sys/fs/cgroup/init/cgroup.procs || : # enable controllers sed -e 's/ / +/g' -e 's/^/+/' < /sys/fs/cgroup/cgroup.controllers \ > /sys/fs/cgroup/cgroup.subtree_control fi # necessary host configuration for CRI-O # https://github.com/kubernetes-sigs/cri-tools/blob/ec9e336fd8c21c4bab89a6aed2c4a138c8cfae75/.github/workflows/crio.yml#L36-L45 sysctl -w net.ipv4.conf.all.route_localnet=1 iptables -t nat -I POSTROUTING -s 127.0.0.0/8 ! -d 127.0.0.0/8 -j MASQUERADE # The target only runs CRI-O and Stargz Store for test. cat < /lib/systemd/system/demo.target [Unit] Description=testing CRI-O Wants=stargz-store.service crio.service EOF exec /sbin/init --unit=demo.target stargz-snapshotter-0.14.3/script/config/000077500000000000000000000000001440204344700202345ustar00rootroot00000000000000stargz-snapshotter-0.14.3/script/config/etc/000077500000000000000000000000001440204344700210075ustar00rootroot00000000000000stargz-snapshotter-0.14.3/script/config/etc/containerd-stargz-grpc/000077500000000000000000000000001440204344700253765ustar00rootroot00000000000000stargz-snapshotter-0.14.3/script/config/etc/containerd-stargz-grpc/config.toml000066400000000000000000000007761440204344700275520ustar00rootroot00000000000000# Append configurations for Stargz Snapshotter in TOML format. # Enables CRI-based keychain # Stargz Snapshotter works as a proxy of CRI. # kubelet MUST listen stargz snapshotter's socket (unix:///run/containerd-stargz-grpc/containerd-stargz-grpc.sock) # instead of containerd for image service. # i.e. add `--image-service-endpoint=unix:///run/containerd-stargz-grpc/containerd-stargz-grpc.sock` option to kubelet. [cri_keychain] enable_keychain = true image_service_path = "/run/containerd/containerd.sock" stargz-snapshotter-0.14.3/script/config/etc/containerd/000077500000000000000000000000001440204344700231355ustar00rootroot00000000000000stargz-snapshotter-0.14.3/script/config/etc/containerd/config.toml000066400000000000000000000016241440204344700253020ustar00rootroot00000000000000# See also: https://github.com/kubernetes-sigs/kind/blob/fd64a56b0c3d5654eb6d22bce812e2a87eac5853/images/base/files/etc/containerd/config.toml # explicitly use v2 config format version = 2 # - Set default runtime handler to v2, which has a per-pod shim # - Enable to use stargz snapshotter [plugins."io.containerd.grpc.v1.cri".containerd] default_runtime_name = "runc" snapshotter = "stargz" disable_snapshot_annotations = false [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc] runtime_type = "io.containerd.runc.v2" # Setup a runtime with the magic name ("test-handler") used for Kubernetes # runtime class tests ... [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.test-handler] runtime_type = "io.containerd.runc.v2" # Use stargz snapshotter [proxy_plugins] [proxy_plugins.stargz] type = "snapshot" address = "/run/containerd-stargz-grpc/containerd-stargz-grpc.sock" stargz-snapshotter-0.14.3/script/config/etc/default/000077500000000000000000000000001440204344700224335ustar00rootroot00000000000000stargz-snapshotter-0.14.3/script/config/etc/default/kubelet000066400000000000000000000001771440204344700240160ustar00rootroot00000000000000KUBELET_EXTRA_ARGS=--fail-swap-on=false --image-service-endpoint=unix:///run/containerd-stargz-grpc/containerd-stargz-grpc.sockstargz-snapshotter-0.14.3/script/config/etc/systemd/000077500000000000000000000000001440204344700224775ustar00rootroot00000000000000stargz-snapshotter-0.14.3/script/config/etc/systemd/system/000077500000000000000000000000001440204344700240235ustar00rootroot00000000000000stargz-snapshotter-0.14.3/script/config/etc/systemd/system/stargz-snapshotter.service000066400000000000000000000004701440204344700312700ustar00rootroot00000000000000[Unit] Description=stargz snapshotter After=network.target Before=containerd.service [Service] Type=notify Environment=HOME=/root ExecStart=/usr/local/bin/containerd-stargz-grpc --log-level=debug --config=/etc/containerd-stargz-grpc/config.toml Restart=always RestartSec=1 [Install] WantedBy=multi-user.target stargz-snapshotter-0.14.3/script/config/usr/000077500000000000000000000000001440204344700210455ustar00rootroot00000000000000stargz-snapshotter-0.14.3/script/config/usr/local/000077500000000000000000000000001440204344700221375ustar00rootroot00000000000000stargz-snapshotter-0.14.3/script/config/usr/local/bin/000077500000000000000000000000001440204344700227075ustar00rootroot00000000000000stargz-snapshotter-0.14.3/script/config/usr/local/bin/kind-entrypoint.sh000077500000000000000000000025131440204344700264050ustar00rootroot00000000000000#!/bin/bash # Copyright The containerd Authors. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. set -euo pipefail # Copied from moby project (Apache License 2.0) # https://github.com/moby/moby/blob/a9fe88e395acaacd84067b5fc701d52dbcf4b625/hack/dind#L28-L38 # cgroup v2: enable nesting if [ -f /sys/fs/cgroup/cgroup.controllers ]; then # move the processes from the root group to the /init group, # otherwise writing subtree_control fails with EBUSY. # An error during moving non-existent process (i.e., "cat") is ignored. mkdir -p /sys/fs/cgroup/init xargs -rn1 < /sys/fs/cgroup/cgroup.procs > /sys/fs/cgroup/init/cgroup.procs || : # enable controllers sed -e 's/ / +/g' -e 's/^/+/' < /sys/fs/cgroup/cgroup.controllers \ > /sys/fs/cgroup/cgroup.subtree_control fi exec $@ stargz-snapshotter-0.14.3/script/cri-containerd/000077500000000000000000000000001440204344700216705ustar00rootroot00000000000000stargz-snapshotter-0.14.3/script/cri-containerd/const.sh000066400000000000000000000014141440204344700233520ustar00rootroot00000000000000#!/bin/bash # Copyright The containerd Authors. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. set -euo pipefail NODE_BASE_IMAGE_NAME="cri-containerd-image-base" NODE_TEST_IMAGE_NAME="cri-containerd-image-test" PREPARE_NODE_IMAGE="cri-containerd-prepare-image" stargz-snapshotter-0.14.3/script/cri-containerd/mirror.sh000066400000000000000000000034151440204344700235410ustar00rootroot00000000000000#!/bin/bash # Copyright The containerd Authors. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. set -euo pipefail if [ "${TOOLS_DIR}" == "" ] ; then echo "tools dir must be provided" exit 1 fi LIST_FILE="${TOOLS_DIR}/list" HOST_FILE="${TOOLS_DIR}/host" SS_REPO="/go/src/github.com/containerd/stargz-snapshotter" RETRYNUM=30 RETRYINTERVAL=1 TIMEOUTSEC=180 function retry { local SUCCESS=false for i in $(seq ${RETRYNUM}) ; do if eval "timeout ${TIMEOUTSEC} ${@}" ; then SUCCESS=true break fi echo "Fail(${i}). Retrying..." sleep ${RETRYINTERVAL} done if [ "${SUCCESS}" == "true" ] ; then return 0 else return 1 fi } cd "${SS_REPO}" git config --global --add safe.directory "${SS_REPO}" PREFIX=/out/ make ctr-remote mv /out/ctr-remote /bin/ctr-remote containerd & retry ctr-remote version HOST=$(cat "${HOST_FILE}") cat "${LIST_FILE}" | sort | uniq | while read IMAGE ; do MIRROR_URL="${HOST}"$(echo "${IMAGE}" | sed -E 's/^[^/]*//g' | sed -E 's/@.*//g') echo "Mirroring: ${IMAGE} to ${MIRROR_URL}" ctr-remote images pull "${IMAGE}" ctr-remote images optimize --oci --period=1 "${IMAGE}" "${MIRROR_URL}" ctr-remote images push --plain-http "${MIRROR_URL}" done stargz-snapshotter-0.14.3/script/cri-containerd/test-legacy.sh000077500000000000000000000050331440204344700244510ustar00rootroot00000000000000#!/bin/bash # Copyright The containerd Authors. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. set -euo pipefail CONTEXT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )/" CONTAINERD_SOCK=unix:///run/containerd/containerd.sock SNAPSHOTTER_SOCK=unix:///run/containerd-stargz-grpc/containerd-stargz-grpc.sock source "${CONTEXT}/const.sh" IMAGE_LIST="${1}" LOG_TMP=$(mktemp) LIST_TMP=$(mktemp) function cleanup { ORG_EXIT_CODE="${1}" rm "${LOG_TMP}" || true rm "${LIST_TMP}" || true exit "${ORG_EXIT_CODE}" } TEST_NODE_ID=$(docker run --rm -d --privileged \ -v /dev/fuse:/dev/fuse \ --tmpfs=/var/lib/containerd:suid \ --tmpfs=/var/lib/containerd-stargz-grpc:suid \ "${NODE_TEST_IMAGE_NAME}") echo "Running node on: ${TEST_NODE_ID}" FAIL= for i in $(seq 100) ; do if docker exec -i "${TEST_NODE_ID}" ctr version ; then break fi echo "Fail(${i}). Retrying..." if [ $i == 100 ] ; then FAIL=true fi sleep 1 done # If container started successfully, varidate the runtime through CRI if [ "${FAIL}" == "" ] ; then if ! ( echo "===== VERSION INFORMATION =====" && \ docker exec "${TEST_NODE_ID}" runc --version && \ docker exec "${TEST_NODE_ID}" containerd --version && \ echo "===============================" && \ docker exec -i "${TEST_NODE_ID}" /go/bin/critest --runtime-endpoint=${CONTAINERD_SOCK} --image-endpoint=${SNAPSHOTTER_SOCK} ) ; then FAIL=true fi fi # Dump all names of images used in the test docker exec -i "${TEST_NODE_ID}" journalctl -xu containerd > "${LOG_TMP}" cat "${LOG_TMP}" | grep PullImage | sed -E 's/.*PullImage \\"([^\\]*)\\".*/\1/g' > "${LIST_TMP}" cat "${LOG_TMP}" | grep SandboxImage | sed -E 's/.*SandboxImage:([^ ]*).*/\1/g' >> "${LIST_TMP}" cat "${LIST_TMP}" | sort | uniq > "${IMAGE_LIST}" docker kill "${TEST_NODE_ID}" if [ "${FAIL}" != "" ] ; then exit 1 fi exit 0 stargz-snapshotter-0.14.3/script/cri-containerd/test-stargz.sh000077500000000000000000000162541440204344700245260ustar00rootroot00000000000000#!/bin/bash # Copyright The containerd Authors. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. set -euo pipefail CONTEXT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )/" REPO="${CONTEXT}../../" REGISTRY_HOST="cri-registry" TEST_NODE_NAME="cri-testenv-container" CONTAINERD_SOCK=unix:///run/containerd/containerd.sock SNAPSHOTTER_SOCK=unix:///run/containerd-stargz-grpc/containerd-stargz-grpc.sock PREPARE_NODE_NAME="cri-prepare-node" source "${CONTEXT}/const.sh" source "${REPO}/script/util/utils.sh" IMAGE_LIST="${1}" TMP_CONTEXT=$(mktemp -d) DOCKER_COMPOSE_YAML=$(mktemp) CONTAINERD_CONFIG=$(mktemp) SNAPSHOTTER_CONFIG=$(mktemp) TMPFILE=$(mktemp) LOG_FILE=$(mktemp) MIRROR_TMP=$(mktemp -d) function cleanup { ORG_EXIT_CODE="${1}" docker-compose -f "${DOCKER_COMPOSE_YAML}" down -v || true rm -rf "${TMP_CONTEXT}" || true rm "${DOCKER_COMPOSE_YAML}" || true rm "${CONTAINERD_CONFIG}" || true rm "${SNAPSHOTTER_CONFIG}" || true rm "${TMPFILE}" || true rm "${LOG_FILE}" || true rm -rf "${MIRROR_TMP}" || true exit "${ORG_EXIT_CODE}" } trap 'cleanup "$?"' EXIT SIGHUP SIGINT SIGQUIT SIGTERM # Prepare the testing node and registry cat < "${DOCKER_COMPOSE_YAML}" version: "3.3" services: cri-testenv-service: image: ${NODE_TEST_IMAGE_NAME} container_name: ${TEST_NODE_NAME} privileged: true tmpfs: - /tmp:exec,mode=777 volumes: - /dev/fuse:/dev/fuse - "critest-containerd-data:/var/lib/containerd" - "critest-containerd-stargz-grpc-data:/var/lib/containerd-stargz-grpc" image-prepare: image: "${PREPARE_NODE_IMAGE}" container_name: "${PREPARE_NODE_NAME}" privileged: true entrypoint: - sleep - infinity tmpfs: - /tmp:exec,mode=777 environment: - TOOLS_DIR=/tools/ volumes: - "critest-prepare-containerd-data:/var/lib/containerd" - "critest-prepare-containerd-stargz-grpc-data:/var/lib/containerd-stargz-grpc" - "${REPO}:/go/src/github.com/containerd/stargz-snapshotter:ro" - "${MIRROR_TMP}:/tools/" registry: image: registry:2 container_name: ${REGISTRY_HOST} volumes: critest-containerd-data: critest-containerd-stargz-grpc-data: critest-prepare-containerd-data: critest-prepare-containerd-stargz-grpc-data: EOF docker-compose -f "${DOCKER_COMPOSE_YAML}" up -d --force-recreate CONNECTED= for i in $(seq 100) ; do if docker exec "${TEST_NODE_NAME}" curl -k --head "http://${REGISTRY_HOST}:5000/v2/" ; then CONNECTED=true break fi echo "Fail(${i}). Retrying..." sleep 1 done if [ "${CONNECTED}" != "true" ] ; then echo "Failed to connect to containerd" exit 1 fi # Mirror and optimize all images used in tests echo "${REGISTRY_HOST}:5000" > "${MIRROR_TMP}/host" cp "${IMAGE_LIST}" "${MIRROR_TMP}/list" cp "${REPO}/script/cri-containerd/mirror.sh" "${MIRROR_TMP}/mirror.sh" docker exec "${PREPARE_NODE_NAME}" /bin/bash /tools/mirror.sh # Configure mirror registries for containerd and snapshotter docker exec "${TEST_NODE_NAME}" cat /etc/containerd/config.toml > "${CONTAINERD_CONFIG}" docker exec "${TEST_NODE_NAME}" cat /etc/containerd-stargz-grpc/config.toml > "${SNAPSHOTTER_CONFIG}" cat "${IMAGE_LIST}" | sed -E 's/^([^/]*).*/\1/g' | sort | uniq | while read DOMAIN ; do echo "Adding mirror config: ${DOMAIN}" cat <> "${CONTAINERD_CONFIG}" [plugins."io.containerd.grpc.v1.cri".registry.mirrors."${DOMAIN}"] endpoint = ["http://${REGISTRY_HOST}:5000"] EOF if [ "${BUILTIN_SNAPSHOTTER:-}" == "true" ] ; then cat <> "${CONTAINERD_CONFIG}" [plugins."io.containerd.snapshotter.v1.stargz".registry.mirrors."${DOMAIN}"] endpoint = ["http://${REGISTRY_HOST}:5000"] EOF else cat <> "${SNAPSHOTTER_CONFIG}" [[resolver.host."${DOMAIN}".mirrors]] host = "${REGISTRY_HOST}:5000" insecure = true EOF fi done echo "==== Containerd config ====" cat "${CONTAINERD_CONFIG}" echo "==== Snapshotter config ====" cat "${SNAPSHOTTER_CONFIG}" docker cp "${CONTAINERD_CONFIG}" "${TEST_NODE_NAME}":/etc/containerd/config.toml docker cp "${SNAPSHOTTER_CONFIG}" "${TEST_NODE_NAME}":/etc/containerd-stargz-grpc/config.toml # Replace digests specified in testing tool to stargz-formatted one docker exec "${PREPARE_NODE_NAME}" ctr-remote i ls cat "${IMAGE_LIST}" | grep "@sha256:" | while read IMAGE ; do URL_PATH=$(echo "${IMAGE}" | sed -E 's/^[^/]*//g' | sed -E 's/@.*//g') MIRROR_TAG="${REGISTRY_HOST}:5000${URL_PATH}" OLD_DIGEST=$(echo "${IMAGE}" | sed -E 's/.*(sha256:[a-z0-9]*).*/\1/g') echo "Getting the digest of : ${MIRROR_TAG}" NEW_DIGEST=$(docker exec "${PREPARE_NODE_NAME}" ctr-remote i ls name=="${MIRROR_TAG}" \ | grep "sha256" | sed -E 's/.*(sha256:[a-z0-9]*).*/\1/g') echo "Converting: ${OLD_DIGEST} => ${NEW_DIGEST}" docker exec "${TEST_NODE_NAME}" \ find /go/src/github.com/kubernetes-sigs/cri-tools/pkg -type f -exec \ sed -i -e "s|${OLD_DIGEST}|${NEW_DIGEST}|g" {} \; done # Rebuild cri testing tool docker exec "${TEST_NODE_NAME}" /bin/bash -c \ "cd /go/src/github.com/kubernetes-sigs/cri-tools && make && make install -e BINDIR=/go/bin" # Varidate the runtime through CRI if [ "${BUILTIN_SNAPSHOTTER:-}" != "true" ] ; then docker exec "${TEST_NODE_NAME}" systemctl restart stargz-snapshotter fi docker exec "${TEST_NODE_NAME}" systemctl restart containerd CONNECTED= for i in $(seq 100) ; do if docker exec "${TEST_NODE_NAME}" ctr version ; then CONNECTED=true break fi echo "Fail(${i}). Retrying..." sleep 1 done if [ "${CONNECTED}" != "true" ] ; then echo "Failed to connect to containerd" exit 1 fi echo "===== VERSION INFORMATION =====" docker exec "${TEST_NODE_NAME}" runc --version docker exec "${TEST_NODE_NAME}" containerd --version echo "===============================" docker exec "${TEST_NODE_NAME}" /go/bin/critest --runtime-endpoint=${CONTAINERD_SOCK} --image-endpoint=${SNAPSHOTTER_SOCK} echo "Check if stargz snapshotter is working" docker exec "${TEST_NODE_NAME}" \ ctr-remote --namespace=k8s.io snapshot --snapshotter=stargz ls \ | sed -E '1d' > "${TMPFILE}" if ! [ -s "${TMPFILE}" ] ; then echo "No snapshots created; stargz snapshotter might be connected to containerd" exit 1 fi echo "Check all remote snapshots are created successfully" if [ "${BUILTIN_SNAPSHOTTER:-}" == "true" ] ; then docker exec "${TEST_NODE_NAME}" journalctl -u containerd \ | grep "${LOG_REMOTE_SNAPSHOT}" \ | sed -E 's/^[^\{]*(\{.*)$/\1/g' > "${LOG_FILE}" else docker exec "${TEST_NODE_NAME}" journalctl -u stargz-snapshotter \ | grep "${LOG_REMOTE_SNAPSHOT}" \ | sed -E 's/^[^\{]*(\{.*)$/\1/g' > "${LOG_FILE}" fi check_remote_snapshots "${LOG_FILE}" exit 0 stargz-snapshotter-0.14.3/script/cri-containerd/test.sh000077500000000000000000000122741440204344700232140ustar00rootroot00000000000000#!/bin/bash # Copyright The containerd Authors. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. set -euo pipefail CONTEXT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )/" REPO="${CONTEXT}../../" SNAPSHOTTER_SOCK_PATH=/run/containerd-stargz-grpc/containerd-stargz-grpc.sock source "${CONTEXT}/const.sh" source "${REPO}/script/util/utils.sh" CNI_PLUGINS_VERSION=$(get_version_from_arg "${REPO}/Dockerfile" "CNI_PLUGINS_VERSION") CRI_TOOLS_VERSION=$(get_version_from_arg "${REPO}/Dockerfile" "CRI_TOOLS_VERSION") GINKGO_VERSION=v1.16.5 if [ "${CRI_NO_RECREATE:-}" != "true" ] ; then echo "Preparing node image..." TARGET_STAGE= if [ "${BUILTIN_SNAPSHOTTER:-}" == "true" ] ; then TARGET_STAGE="--target kind-builtin-snapshotter" fi docker build ${DOCKER_BUILD_ARGS:-} -t "${NODE_BASE_IMAGE_NAME}" ${TARGET_STAGE} "${REPO}" docker build ${DOCKER_BUILD_ARGS:-} -t "${PREPARE_NODE_IMAGE}" --target containerd-base "${REPO}" fi TMP_CONTEXT=$(mktemp -d) IMAGE_LIST=$(mktemp) function cleanup { local ORG_EXIT_CODE="${1}" rm -rf "${TMP_CONTEXT}" || true rm "${IMAGE_LIST}" || true exit "${ORG_EXIT_CODE}" } trap 'cleanup "$?"' EXIT SIGHUP SIGINT SIGQUIT SIGTERM BUILTIN_HACK_INST= if [ "${BUILTIN_SNAPSHOTTER:-}" == "true" ] ; then # Special configuration for CRI containerd + builtin stargz snapshotter cat < "${TMP_CONTEXT}/containerd.hack.toml" version = 2 [debug] format = "json" level = "debug" [plugins."io.containerd.grpc.v1.cri".containerd] default_runtime_name = "runc" snapshotter = "stargz" disable_snapshot_annotations = false [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc] runtime_type = "io.containerd.runc.v2" [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.test-handler] runtime_type = "io.containerd.runc.v2" [plugins."io.containerd.snapshotter.v1.stargz"] cri_keychain_image_service_path = "${SNAPSHOTTER_SOCK_PATH}" metadata_store = "memory" [plugins."io.containerd.snapshotter.v1.stargz".cri_keychain] enable_keychain = true EOF BUILTIN_HACK_INST="COPY containerd.hack.toml /etc/containerd/config.toml" fi cat < "${TMP_CONTEXT}/test.conflist" { "cniVersion": "0.4.0", "name": "containerd-net", "plugins": [ { "type": "bridge", "bridge": "cni0", "isGateway": true, "ipMasq": true, "promiscMode": true, "ipam": { "type": "host-local", "ranges": [ [{ "subnet": "10.88.0.0/16" }] ], "routes": [ { "dst": "0.0.0.0/0" } ] } }, { "type": "portmap", "capabilities": {"portMappings": true} } ] } EOF USE_METADATA_STORE="memory" if [ "${METADATA_STORE:-}" != "" ] ; then USE_METADATA_STORE="${METADATA_STORE}" fi SNAPSHOTTER_CONFIG_FILE=/etc/containerd-stargz-grpc/config.toml if [ "${BUILTIN_SNAPSHOTTER:-}" == "true" ] ; then SNAPSHOTTER_CONFIG_FILE=/etc/containerd/config.toml fi # Prepare the testing node cat < "${TMP_CONTEXT}/Dockerfile" # Legacy builder that doesn't support TARGETARCH should set this explicitly using --build-arg. # If TARGETARCH isn't supported by the builder, the default value is "amd64". FROM ${NODE_BASE_IMAGE_NAME} ARG TARGETARCH ENV PATH=$PATH:/usr/local/go/bin ENV GOPATH=/go # Do not install git and its dependencies here which will cause failure of building the image RUN apt-get update && apt-get install -y --no-install-recommends make && \ curl -Ls https://dl.google.com/go/go1.19.linux-\${TARGETARCH:-amd64}.tar.gz | tar -C /usr/local -xz && \ go install github.com/onsi/ginkgo/ginkgo@${GINKGO_VERSION} && \ mkdir -p \${GOPATH}/src/github.com/kubernetes-sigs/cri-tools /tmp/cri-tools && \ curl -sL https://github.com/kubernetes-sigs/cri-tools/archive/refs/tags/v${CRI_TOOLS_VERSION}.tar.gz | tar -C /tmp/cri-tools -xz && \ mv /tmp/cri-tools/cri-tools-${CRI_TOOLS_VERSION}/* \${GOPATH}/src/github.com/kubernetes-sigs/cri-tools/ && \ cd \${GOPATH}/src/github.com/kubernetes-sigs/cri-tools && \ make && make install -e BINDIR=\${GOPATH}/bin && \ curl -Ls https://github.com/containernetworking/plugins/releases/download/v${CNI_PLUGINS_VERSION}/cni-plugins-linux-\${TARGETARCH:-amd64}-v${CNI_PLUGINS_VERSION}.tgz | tar xzv -C /opt/cni/bin && \ systemctl disable kubelet COPY ./test.conflist /etc/cni/net.d/test.conflist ${BUILTIN_HACK_INST} RUN sed -i 's/^metadata_store.*/metadata_store = "${USE_METADATA_STORE}"/g' "${SNAPSHOTTER_CONFIG_FILE}" ENTRYPOINT [ "/usr/local/bin/entrypoint", "/sbin/init" ] EOF docker build -t "${NODE_TEST_IMAGE_NAME}" ${DOCKER_BUILD_ARGS:-} "${TMP_CONTEXT}" echo "Testing..." "${CONTEXT}/test-legacy.sh" "${IMAGE_LIST}" "${CONTEXT}/test-stargz.sh" "${IMAGE_LIST}" stargz-snapshotter-0.14.3/script/cri-o/000077500000000000000000000000001440204344700200005ustar00rootroot00000000000000stargz-snapshotter-0.14.3/script/cri-o/const.sh000066400000000000000000000013611440204344700214630ustar00rootroot00000000000000#!/bin/bash # Copyright The containerd Authors. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. set -euo pipefail NODE_BASE_IMAGE_NAME="cri-o-image-base" NODE_TEST_IMAGE_NAME="cri-o-image-test" PREPARE_NODE_IMAGE="cri-o-prepare-image" stargz-snapshotter-0.14.3/script/cri-o/mirror.sh000066400000000000000000000034151440204344700216510ustar00rootroot00000000000000#!/bin/bash # Copyright The containerd Authors. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. set -euo pipefail if [ "${TOOLS_DIR}" == "" ] ; then echo "tools dir must be provided" exit 1 fi LIST_FILE="${TOOLS_DIR}/list" HOST_FILE="${TOOLS_DIR}/host" SS_REPO="/go/src/github.com/containerd/stargz-snapshotter" RETRYNUM=30 RETRYINTERVAL=1 TIMEOUTSEC=180 function retry { local SUCCESS=false for i in $(seq ${RETRYNUM}) ; do if eval "timeout ${TIMEOUTSEC} ${@}" ; then SUCCESS=true break fi echo "Fail(${i}). Retrying..." sleep ${RETRYINTERVAL} done if [ "${SUCCESS}" == "true" ] ; then return 0 else return 1 fi } cd "${SS_REPO}" git config --global --add safe.directory "${SS_REPO}" PREFIX=/out/ make ctr-remote mv /out/ctr-remote /bin/ctr-remote containerd & retry ctr-remote version HOST=$(cat "${HOST_FILE}") cat "${LIST_FILE}" | sort | uniq | while read IMAGE ; do MIRROR_URL="${HOST}"$(echo "${IMAGE}" | sed -E 's/^[^/]*//g' | sed -E 's/@.*//g') echo "Mirroring: ${IMAGE} to ${MIRROR_URL}" ctr-remote images pull "${IMAGE}" ctr-remote images optimize --oci --period=1 "${IMAGE}" "${MIRROR_URL}" ctr-remote images push --plain-http "${MIRROR_URL}" done stargz-snapshotter-0.14.3/script/cri-o/test-legacy.sh000077500000000000000000000052171440204344700225650ustar00rootroot00000000000000#!/bin/bash # Copyright The containerd Authors. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. set -euo pipefail CONTEXT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )/" CRIO_SOCK=unix:///run/crio/crio.sock PAUSE_IMAGE_NAME_PATH=/pause_name source "${CONTEXT}/const.sh" IMAGE_LIST="${1}" LOG_TMP=$(mktemp) LIST_TMP=$(mktemp) function cleanup { ORG_EXIT_CODE="${1}" rm "${LOG_TMP}" || true rm "${LIST_TMP}" || true exit "${ORG_EXIT_CODE}" } RETRYNUM=100 RETRYINTERVAL=1 TIMEOUTSEC=180 function retry { local SUCCESS=false for i in $(seq ${RETRYNUM}) ; do if eval "timeout ${TIMEOUTSEC} ${@}" ; then SUCCESS=true break fi echo "Fail(${i}). Retrying..." sleep ${RETRYINTERVAL} done if [ "${SUCCESS}" == "true" ] ; then return 0 else return 1 fi } TEST_NODE_ID=$(docker run --rm -d --privileged \ -v /dev/fuse:/dev/fuse \ --tmpfs=/var/lib/containers:suid \ --tmpfs=/var/lib/stargz-store:suid \ "${NODE_TEST_IMAGE_NAME}") echo "Running node on: ${TEST_NODE_ID}" retry docker exec "${TEST_NODE_ID}" /go/bin/crictl --runtime-endpoint=${CRIO_SOCK} stats # If container started successfully, varidate the runtime through CRI FAIL= if ! ( echo "===== VERSION INFORMATION =====" && \ docker exec "${TEST_NODE_ID}" runc --version && \ docker exec "${TEST_NODE_ID}" crio --version && \ echo "===============================" && \ docker exec -i "${TEST_NODE_ID}" /go/bin/critest --runtime-endpoint=${CRIO_SOCK} ) ; then FAIL=true fi echo "Dump all names of images used in the test: ${IMAGE_LIST}" docker exec -i "${TEST_NODE_ID}" journalctl -xu crio > "${LOG_TMP}" cat "${LOG_TMP}" | grep "Pulling image: " | sed -E 's/.*Pulling image: ([^"]*)".*/\1/g' > "${LIST_TMP}" docker exec -i "${TEST_NODE_ID}" cat "${PAUSE_IMAGE_NAME_PATH}" >> "${LIST_TMP}" cat "${LIST_TMP}" | sort | uniq > "${IMAGE_LIST}" echo "Cleaning up..." docker kill "${TEST_NODE_ID}" if [ "${FAIL}" != "" ] ; then exit 1 fi exit 0 stargz-snapshotter-0.14.3/script/cri-o/test-stargz.sh000077500000000000000000000143741440204344700226370ustar00rootroot00000000000000#!/bin/bash # Copyright The containerd Authors. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. set -euo pipefail CONTEXT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )/" REPO="${CONTEXT}../../" REGISTRY_HOST="cri-registry" TEST_NODE_NAME="cri-testenv-container" CRIO_SOCK=unix:///run/crio/crio.sock PREPARE_NODE_NAME="cri-prepare-node" source "${CONTEXT}/const.sh" source "${REPO}/script/util/utils.sh" IMAGE_LIST="${1}" TMP_CONTEXT=$(mktemp -d) DOCKER_COMPOSE_YAML=$(mktemp) CRIO_CONFIG=$(mktemp) STORE_CONFIG=$(mktemp) TMPFILE=$(mktemp) LOG_FILE=$(mktemp) MIRROR_TMP=$(mktemp -d) function cleanup { ORG_EXIT_CODE="${1}" docker-compose -f "${DOCKER_COMPOSE_YAML}" down -v || true rm -rf "${TMP_CONTEXT}" || true rm "${DOCKER_COMPOSE_YAML}" || true rm "${CRIO_CONFIG}" || true rm "${STORE_CONFIG}" || true rm "${TMPFILE}" || true rm "${LOG_FILE}" || true rm -rf "${MIRROR_TMP}" || true exit "${ORG_EXIT_CODE}" } trap 'cleanup "$?"' EXIT SIGHUP SIGINT SIGQUIT SIGTERM RETRYNUM=100 RETRYINTERVAL=1 TIMEOUTSEC=180 function retry { local SUCCESS=false for i in $(seq ${RETRYNUM}) ; do if eval "timeout ${TIMEOUTSEC} ${@}" ; then SUCCESS=true break fi echo "Fail(${i}). Retrying..." sleep ${RETRYINTERVAL} done if [ "${SUCCESS}" == "true" ] ; then return 0 else return 1 fi } # Prepare the testing node and registry cat < "${DOCKER_COMPOSE_YAML}" version: "3.3" services: cri-testenv-service: image: ${NODE_TEST_IMAGE_NAME} container_name: ${TEST_NODE_NAME} privileged: true tmpfs: - /tmp:exec,mode=777 volumes: - /dev/fuse:/dev/fuse - "critest-crio-data:/var/lib/containers" - "critest-crio-stargz-store-data:/var/lib/stargz-store" image-prepare: image: "${PREPARE_NODE_IMAGE}" container_name: "${PREPARE_NODE_NAME}" privileged: true entrypoint: - sleep - infinity tmpfs: - /tmp:exec,mode=777 environment: - TOOLS_DIR=/tools/ volumes: - "critest-prepare-containerd-data:/var/lib/containerd" - "critest-prepare-containerd-stargz-grpc-data:/var/lib/containerd-stargz-grpc" - "${REPO}:/go/src/github.com/containerd/stargz-snapshotter:ro" - "${MIRROR_TMP}:/tools/" registry: image: registry:2 container_name: ${REGISTRY_HOST} volumes: critest-crio-data: critest-crio-stargz-store-data: critest-prepare-containerd-data: critest-prepare-containerd-stargz-grpc-data: EOF docker-compose -f "${DOCKER_COMPOSE_YAML}" up -d --force-recreate retry docker exec "${PREPARE_NODE_NAME}" curl -k --head "http://${REGISTRY_HOST}:5000/v2/" # Mirror and optimize all images used in tests echo "${REGISTRY_HOST}:5000" > "${MIRROR_TMP}/host" cp "${IMAGE_LIST}" "${MIRROR_TMP}/list" cp "${REPO}/script/cri-o/mirror.sh" "${MIRROR_TMP}/mirror.sh" docker exec "${PREPARE_NODE_NAME}" /bin/bash /tools/mirror.sh # Configure mirror registries for CRI-O and stargz store docker exec "${TEST_NODE_NAME}" cat /etc/containers/registries.conf > "${CRIO_CONFIG}" docker exec "${TEST_NODE_NAME}" cat /etc/stargz-store/config.toml > "${STORE_CONFIG}" cat "${IMAGE_LIST}" | sed -E 's/^([^/]*).*/\1/g' | sort | uniq | while read DOMAIN ; do echo "Adding mirror config: ${DOMAIN}" cat <> "${CRIO_CONFIG}" [[registry]] prefix = "${DOMAIN}" insecure = true blocked = false location = "${REGISTRY_HOST}:5000" EOF cat <> "${STORE_CONFIG}" [[resolver.host."${DOMAIN}".mirrors]] host = "${REGISTRY_HOST}:5000" insecure = true EOF done echo "==== CRI-O (containers/image) config ====" cat "${CRIO_CONFIG}" echo "==== Store config ====" cat "${STORE_CONFIG}" docker cp "${CRIO_CONFIG}" "${TEST_NODE_NAME}":/etc/containers/registries.conf docker cp "${STORE_CONFIG}" "${TEST_NODE_NAME}":/etc/stargz-store/config.toml # Replace digests specified in testing tool to stargz-formatted one docker exec "${PREPARE_NODE_NAME}" ctr-remote i ls cat "${IMAGE_LIST}" | grep "@sha256:" | while read IMAGE ; do URL_PATH=$(echo "${IMAGE}" | sed -E 's/^[^/]*//g' | sed -E 's/@.*//g') MIRROR_TAG="${REGISTRY_HOST}:5000${URL_PATH}" OLD_DIGEST=$(echo "${IMAGE}" | sed -E 's/.*(sha256:[a-z0-9]*).*/\1/g') echo "Getting the digest of : ${MIRROR_TAG}" NEW_DIGEST=$(docker exec "${PREPARE_NODE_NAME}" ctr-remote i ls name=="${MIRROR_TAG}" \ | grep "sha256" | sed -E 's/.*(sha256:[a-z0-9]*).*/\1/g') echo "Converting: ${OLD_DIGEST} => ${NEW_DIGEST}" docker exec "${TEST_NODE_NAME}" \ find /go/src/github.com/kubernetes-sigs/cri-tools/pkg -type f -exec \ sed -i -e "s|${OLD_DIGEST}|${NEW_DIGEST}|g" {} \; done # Rebuild cri testing tool docker exec "${TEST_NODE_NAME}" /bin/bash -c \ "cd /go/src/github.com/kubernetes-sigs/cri-tools && make && make install -e BINDIR=/go/bin" # Varidate the runtime through CRI docker exec "${TEST_NODE_NAME}" systemctl restart stargz-store docker exec "${TEST_NODE_NAME}" systemctl restart crio CONNECTED= for i in $(seq 100) ; do if docker exec "${TEST_NODE_NAME}" /go/bin/crictl --runtime-endpoint=${CRIO_SOCK} stats ; then CONNECTED=true break fi echo "Fail(${i}). Retrying..." sleep 1 done if [ "${CONNECTED}" != "true" ] ; then echo "Failed to connect to CRI-O" exit 1 fi echo "===== VERSION INFORMATION =====" docker exec "${TEST_NODE_NAME}" runc --version docker exec "${TEST_NODE_NAME}" crio --version echo "===============================" docker exec "${TEST_NODE_NAME}" /go/bin/critest --runtime-endpoint=${CRIO_SOCK} echo "Check all remote snapshots are created successfully" docker exec "${TEST_NODE_NAME}" journalctl -u stargz-store \ | grep "${LOG_REMOTE_SNAPSHOT}" \ | sed -E 's/^[^\{]*(\{.*)$/\1/g' > "${LOG_FILE}" check_remote_snapshots "${LOG_FILE}" exit 0 stargz-snapshotter-0.14.3/script/cri-o/test.sh000077500000000000000000000057211440204344700213230ustar00rootroot00000000000000#!/bin/bash # Copyright The containerd Authors. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. set -euo pipefail CONTEXT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )/" REPO="${CONTEXT}../../" source "${CONTEXT}/const.sh" source "${REPO}/script/util/utils.sh" CRI_TOOLS_VERSION=$(get_version_from_arg "${REPO}/Dockerfile" "CRI_TOOLS_VERSION") GINKGO_VERSION=v1.16.5 if [ "${CRI_NO_RECREATE:-}" != "true" ] ; then echo "Preparing node image..." docker build ${DOCKER_BUILD_ARGS:-} -t "${NODE_BASE_IMAGE_NAME}" --target crio-stargz-store "${REPO}" docker build ${DOCKER_BUILD_ARGS:-} -t "${PREPARE_NODE_IMAGE}" --target containerd-base "${REPO}" fi USE_METADATA_STORE="memory" if [ "${METADATA_STORE:-}" != "" ] ; then USE_METADATA_STORE="${METADATA_STORE}" fi TMP_CONTEXT=$(mktemp -d) IMAGE_LIST=$(mktemp) function cleanup { local ORG_EXIT_CODE="${1}" rm -rf "${TMP_CONTEXT}" || true rm "${IMAGE_LIST}" || true exit "${ORG_EXIT_CODE}" } trap 'cleanup "$?"' EXIT SIGHUP SIGINT SIGQUIT SIGTERM # Prepare the testing node cat < "${TMP_CONTEXT}/Dockerfile" # Legacy builder that doesn't support TARGETARCH should set this explicitly using --build-arg. # If TARGETARCH isn't supported by the builder, the default value is "amd64". FROM ${NODE_BASE_IMAGE_NAME} ARG TARGETARCH ENV PATH=$PATH:/usr/local/go/bin ENV GOPATH=/go # Do not install git and its dependencies here which will cause failure of building the image RUN apt-get update && apt-get install -y --no-install-recommends make && \ curl -Ls https://dl.google.com/go/go1.19.linux-\${TARGETARCH:-amd64}.tar.gz | tar -C /usr/local -xz && \ go install github.com/onsi/ginkgo/ginkgo@${GINKGO_VERSION} && \ mkdir -p \${GOPATH}/src/github.com/kubernetes-sigs/cri-tools /tmp/cri-tools && \ curl -sL https://github.com/kubernetes-sigs/cri-tools/archive/refs/tags/v${CRI_TOOLS_VERSION}.tar.gz | tar -C /tmp/cri-tools -xz && \ mv /tmp/cri-tools/cri-tools-${CRI_TOOLS_VERSION}/* \${GOPATH}/src/github.com/kubernetes-sigs/cri-tools/ && \ cd \${GOPATH}/src/github.com/kubernetes-sigs/cri-tools && \ make && make install -e BINDIR=\${GOPATH}/bin RUN echo "metadata_store = \"${USE_METADATA_STORE}\"" >> /etc/stargz-store/config.toml ENTRYPOINT [ "/usr/local/bin/entrypoint" ] EOF docker build -t "${NODE_TEST_IMAGE_NAME}" ${DOCKER_BUILD_ARGS:-} "${TMP_CONTEXT}" echo "Testing..." "${CONTEXT}/test-legacy.sh" "${IMAGE_LIST}" "${CONTEXT}/test-stargz.sh" "${IMAGE_LIST}" stargz-snapshotter-0.14.3/script/criauth/000077500000000000000000000000001440204344700204265ustar00rootroot00000000000000stargz-snapshotter-0.14.3/script/criauth/create-pod.sh000077500000000000000000000071511440204344700230140ustar00rootroot00000000000000#!/bin/bash # Copyright The containerd Authors. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. set -euo pipefail REMOTE_SNAPSHOT_LABEL="containerd.io/snapshot/remote" TEST_POD_NAME=testpod-$(head /dev/urandom | tr -dc a-z0-9 | head -c 10) TEST_POD_NS=ns1 TEST_CONTAINER_NAME=testcontainer-$(head /dev/urandom | tr -dc a-z0-9 | head -c 10) KIND_NODENAME="${1}" KIND_KUBECONFIG="${2}" TESTIMAGE="${3}" echo "Creating testing pod...." cat < 100" exit 1 fi ((LAYERSNUM+=1)) LABEL=$(docker exec -i "${KIND_NODENAME}" ctr-remote --namespace="k8s.io" \ snapshots --snapshotter=stargz info "${LAYER}" \ | jq -r ".Labels.\"${REMOTE_SNAPSHOT_LABEL}\"") echo "Checking layer ${LAYER} : ${LABEL}" if [ "${LABEL}" == "null" ] ; then echo "layer ${LAYER} isn't remote snapshot" exit 1 fi done if [ ${LAYERSNUM} -eq 0 ] ; then echo "cannot get layers" exit 1 fi exit 0 stargz-snapshotter-0.14.3/script/criauth/mirror.sh000066400000000000000000000026321440204344700222770ustar00rootroot00000000000000#!/bin/bash # Copyright The containerd Authors. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. set -euo pipefail SRC="${1}" DST="${2}" SS_REPO="/go/src/github.com/containerd/stargz-snapshotter" RETRYNUM=30 RETRYINTERVAL=1 TIMEOUTSEC=180 function retry { local SUCCESS=false for i in $(seq ${RETRYNUM}) ; do if eval "timeout ${TIMEOUTSEC} ${@}" ; then SUCCESS=true break fi echo "Fail(${i}). Retrying..." sleep ${RETRYINTERVAL} done if [ "${SUCCESS}" == "true" ] ; then return 0 else return 1 fi } update-ca-certificates cd "${SS_REPO}" git config --global --add safe.directory "${SS_REPO}" PREFIX=/out/ make ctr-remote containerd & retry /out/ctr-remote version /out/ctr-remote images pull "${SRC}" /out/ctr-remote images optimize --oci "${SRC}" "${DST}" /out/ctr-remote images push -u "${REGISTRY_CREDS}" "${DST}" stargz-snapshotter-0.14.3/script/criauth/run-kind.sh000077500000000000000000000105051440204344700225150ustar00rootroot00000000000000#!/bin/bash # Copyright The containerd Authors. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. set -euo pipefail NODE_IMAGE_NAME="cri-stargz-snapshotter-node:1" NODE_BASE_IMAGE_NAME="cri-stargz-snapshotter-node-base:1" NODE_TEST_CERT_FILE="/usr/local/share/ca-certificates/registry.crt" REGISTRY_HOST=kind-cri-private-registry # Arguments KIND_CLUSTER_NAME="${1}" KIND_USER_KUBECONFIG="${2}" KIND_REGISTRY_CA="${3}" REPO="${4}" REGISTRY_NETWORK="${5}" DOCKERCONFIGJSON_DATA="${6}" TMP_BUILTIN_CONF=$(mktemp) TMP_CONTEXT=$(mktemp -d) SN_KUBECONFIG=$(mktemp) function cleanup { local ORG_EXIT_CODE="${1}" rm "${SN_KUBECONFIG}" rm -rf "${TMP_CONTEXT}" rm -rf "${TMP_BUILTIN_CONF}" exit "${ORG_EXIT_CODE}" } trap 'cleanup "$?"' EXIT SIGHUP SIGINT SIGQUIT SIGTERM if [ "${KIND_NO_RECREATE:-}" != "true" ] ; then echo "Preparing node image..." TARGET_STAGE= if [ "${BUILTIN_SNAPSHOTTER:-}" == "true" ] ; then TARGET_STAGE="--target kind-builtin-snapshotter" fi docker build ${DOCKER_BUILD_ARGS:-} -t "${NODE_BASE_IMAGE_NAME}" ${TARGET_STAGE} "${REPO}" fi # Prepare the testing node with enabling k8s keychain cat < "${TMP_CONTEXT}/config.containerd.append.toml" [plugins."io.containerd.grpc.v1.cri".registry.configs."${REGISTRY_HOST}:5000".tls] ca_file = "${NODE_TEST_CERT_FILE}" EOF BUILTIN_HACK_INST= if [ "${BUILTIN_SNAPSHOTTER:-}" == "true" ] ; then # Special configuration for CRI containerd + builtin stargz snapshotter cat < "${TMP_CONTEXT}/containerd.hack.toml" version = 2 [debug] format = "json" level = "debug" [plugins."io.containerd.grpc.v1.cri".containerd] default_runtime_name = "runc" snapshotter = "stargz" disable_snapshot_annotations = false [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc] runtime_type = "io.containerd.runc.v2" [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.test-handler] runtime_type = "io.containerd.runc.v2" [plugins."io.containerd.grpc.v1.cri".registry.configs."${REGISTRY_HOST}:5000".tls] ca_file = "${NODE_TEST_CERT_FILE}" [plugins."io.containerd.snapshotter.v1.stargz"] cri_keychain_image_service_path = "/run/containerd-stargz-grpc/containerd-stargz-grpc.sock" [plugins."io.containerd.snapshotter.v1.stargz".cri_keychain] enable_keychain = true [plugins."io.containerd.snapshotter.v1.stargz".registry.configs."${REGISTRY_HOST}:5000".tls] ca_file = "${NODE_TEST_CERT_FILE}" EOF BUILTIN_HACK_INST="COPY containerd.hack.toml /etc/containerd/config.toml" fi cp "${KIND_REGISTRY_CA}" "${TMP_CONTEXT}/registry.crt" cat < "${TMP_CONTEXT}/Dockerfile" FROM ${NODE_BASE_IMAGE_NAME} COPY registry.crt "${NODE_TEST_CERT_FILE}" COPY ./config.containerd.append.toml /tmp/ RUN cat /tmp/config.containerd.append.toml >> /etc/containerd/config.toml && \ update-ca-certificates ${BUILTIN_HACK_INST} EOF docker build -t "${NODE_IMAGE_NAME}" ${DOCKER_BUILD_ARGS:-} "${TMP_CONTEXT}" # cluster must be single node echo "Cleating kind cluster and connecting to the registry network..." kind create cluster --name "${KIND_CLUSTER_NAME}" \ --kubeconfig "${KIND_USER_KUBECONFIG}" \ --image "${NODE_IMAGE_NAME}" KIND_NODENAME=$(kind get nodes --name "${KIND_CLUSTER_NAME}" | sed -n 1p) # must be single node docker network connect "${REGISTRY_NETWORK}" "${KIND_NODENAME}" echo "===== VERSION INFORMATION =====" docker exec "${KIND_NODENAME}" containerd --version docker exec "${KIND_NODENAME}" runc --version echo "===============================" echo "Configuring kubernetes cluster..." CONFIGJSON_BASE64="$(cat ${DOCKERCONFIGJSON_DATA} | base64 -i -w 0)" cat </dev/null 2>&1 && pwd )/" REPO="${CONTEXT}../../" REGISTRY_HOST=kind-cri-private-registry REGISTRY_NETWORK=kind_cri_registry_network DUMMYUSER=dummyuser DUMMYPASS=dummypass TESTIMAGE_ORIGIN="ghcr.io/stargz-containers/ubuntu:22.04" TESTIMAGE="${REGISTRY_HOST}:5000/library/ubuntu:22.04" KIND_CLUSTER_NAME=kind-cri-stargz-snapshotter PREPARE_NODE_NAME="kind-cri-prepare-node" PREPARE_NODE_IMAGE="kind-cri-prepare-image" source "${REPO}/script/util/utils.sh" if [ "${KIND_NO_RECREATE:-}" != "true" ] ; then echo "Preparing preparation node image..." docker build ${DOCKER_BUILD_ARGS:-} -t "${PREPARE_NODE_IMAGE}" --target containerd-base "${REPO}" fi AUTH_DIR=$(mktemp -d) DOCKERCONFIG=$(mktemp) DOCKER_COMPOSE_YAML=$(mktemp) KIND_KUBECONFIG=$(mktemp) MIRROR_TMP=$(mktemp -d) function cleanup { local ORG_EXIT_CODE="${1}" rm -rf "${AUTH_DIR}" || true rm "${DOCKER_COMPOSE_YAML}" || true rm "${DOCKERCONFIG}" || true rm "${KIND_KUBECONFIG}" || true rm -rf "${MIRROR_TMP}" || true exit "${ORG_EXIT_CODE}" } trap 'cleanup "$?"' EXIT SIGHUP SIGINT SIGQUIT SIGTERM echo "Preparing creds..." prepare_creds "${AUTH_DIR}" "${REGISTRY_HOST}" "${DUMMYUSER}" "${DUMMYPASS}" echo -n '{"auths":{"'"${REGISTRY_HOST}"':5000":{"auth":"'$(echo -n "${DUMMYUSER}:${DUMMYPASS}" | base64 -i -w 0)'"}}}' > "${DOCKERCONFIG}" echo "Preparing private registry..." cat < "${DOCKER_COMPOSE_YAML}" version: "3.5" services: testenv_registry: image: registry:2 container_name: ${REGISTRY_HOST} environment: - HTTP_PROXY=${HTTP_PROXY:-} - HTTPS_PROXY=${HTTPS_PROXY:-} - http_proxy=${http_proxy:-} - https_proxy=${https_proxy:-} - REGISTRY_AUTH=htpasswd - REGISTRY_AUTH_HTPASSWD_REALM="Registry Realm" - REGISTRY_AUTH_HTPASSWD_PATH=/auth/auth/htpasswd - REGISTRY_HTTP_TLS_CERTIFICATE=/auth/certs/domain.crt - REGISTRY_HTTP_TLS_KEY=/auth/certs/domain.key volumes: - ${AUTH_DIR}:/auth image-prepare: image: "${PREPARE_NODE_IMAGE}" container_name: "${PREPARE_NODE_NAME}" privileged: true entrypoint: - sleep - infinity tmpfs: - /tmp:exec,mode=777 environment: - REGISTRY_CREDS=${DUMMYUSER}:${DUMMYPASS} volumes: - "criauth-prepare-containerd-data:/var/lib/containerd" - "criauth-prepare-containerd-stargz-grpc-data:/var/lib/containerd-stargz-grpc" - "${AUTH_DIR}/certs/domain.crt:/usr/local/share/ca-certificates/rgst.crt:ro" - "${REPO}:/go/src/github.com/containerd/stargz-snapshotter:ro" - "${MIRROR_TMP}:/tools/" volumes: criauth-prepare-containerd-data: criauth-prepare-containerd-stargz-grpc-data: networks: default: external: name: ${REGISTRY_NETWORK} EOF cp "${REPO}/script/criauth/mirror.sh" "${MIRROR_TMP}/mirror.sh" if ! ( cd "${CONTEXT}" && \ docker network create "${REGISTRY_NETWORK}" && \ docker-compose -f "${DOCKER_COMPOSE_YAML}" up -d --force-recreate && \ docker exec "${PREPARE_NODE_NAME}" /bin/bash /tools/mirror.sh \ "${TESTIMAGE_ORIGIN}" "${TESTIMAGE}" ) ; then echo "Failed to prepare private registry" docker-compose -f "${DOCKER_COMPOSE_YAML}" down -v docker network rm "${REGISTRY_NETWORK}" exit 1 fi echo "Testing in kind cluster (kubeconfig: ${KIND_KUBECONFIG})..." FAIL= if ! ( "${CONTEXT}"/run-kind.sh "${KIND_CLUSTER_NAME}" \ "${KIND_KUBECONFIG}" \ "${AUTH_DIR}/certs/domain.crt" \ "${REPO}" \ "${REGISTRY_NETWORK}" \ "${DOCKERCONFIG}" && \ sleep 20 && \ echo "Trying to pull private image with secret..." && \ "${CONTEXT}"/create-pod.sh "$(kind get nodes --name "${KIND_CLUSTER_NAME}" | sed -n 1p)" \ "${KIND_KUBECONFIG}" "${TESTIMAGE}" ) ; then FAIL=true fi docker-compose -f "${DOCKER_COMPOSE_YAML}" down -v kind delete cluster --name "${KIND_CLUSTER_NAME}" docker network rm "${REGISTRY_NETWORK}" if [ "${FAIL}" == "true" ] ; then exit 1 fi exit 0 stargz-snapshotter-0.14.3/script/demo-store/000077500000000000000000000000001440204344700210455ustar00rootroot00000000000000stargz-snapshotter-0.14.3/script/demo-store/docker-compose.yml000066400000000000000000000023321440204344700245020ustar00rootroot00000000000000version: "3.4" services: store_demo: build: context: ../../ target: podman-base args: NO_PROXY: "${NO_PROXY}" HTTP_PROXY: "${HTTP_PROXY}" HTTPS_PROXY: "${HTTPS_PROXY}" http_proxy: "${http_proxy}" https_proxy: "${https_proxy}" container_name: store_demo privileged: true stdin_open: true tty: true working_dir: /go/src/github.com/containerd/stargz-snapshotter entrypoint: /bin/bash environment: - NO_PROXY=127.0.0.1,localhost,registry2-store:5000 - HTTP_PROXY=${HTTP_PROXY} - HTTPS_PROXY=${HTTPS_PROXY} - http_proxy=${http_proxy} - https_proxy=${https_proxy} - GOPATH=/go tmpfs: - /tmp:exec,mode=777 volumes: - /dev/fuse:/dev/fuse - "${GOPATH}/src/github.com/containerd/stargz-snapshotter:/go/src/github.com/containerd/stargz-snapshotter:ro" - "containers-data:/var/lib/containers" - "additional-store-data:/var/lib/stargz-store" registry2: image: registry:2 container_name: registry2-store environment: - HTTP_PROXY=${HTTP_PROXY} - HTTPS_PROXY=${HTTPS_PROXY} - http_proxy=${http_proxy} - https_proxy=${https_proxy} volumes: containers-data: additional-store-data: stargz-snapshotter-0.14.3/script/demo-store/etc/000077500000000000000000000000001440204344700216205ustar00rootroot00000000000000stargz-snapshotter-0.14.3/script/demo-store/etc/containers/000077500000000000000000000000001440204344700237655ustar00rootroot00000000000000stargz-snapshotter-0.14.3/script/demo-store/etc/containers/policy.json000066400000000000000000000001341440204344700261550ustar00rootroot00000000000000{ "default": [ { "type": "insecureAcceptAnything" } ] } stargz-snapshotter-0.14.3/script/demo-store/etc/containers/registries.conf000066400000000000000000000000731440204344700270140ustar00rootroot00000000000000[registries.insecure] registries = ['registry2-store:5000']stargz-snapshotter-0.14.3/script/demo-store/etc/containers/storage.conf000066400000000000000000000002721440204344700263010ustar00rootroot00000000000000[storage] driver = "overlay" graphroot = "/var/lib/containers/storage" runroot = "/run/containers/storage" [storage.options] additionallayerstores = ["/var/lib/stargz-store/store:ref"] stargz-snapshotter-0.14.3/script/demo-store/etc/stargz-store/000077500000000000000000000000001440204344700242645ustar00rootroot00000000000000stargz-snapshotter-0.14.3/script/demo-store/etc/stargz-store/config.toml000066400000000000000000000002361440204344700264270ustar00rootroot00000000000000metrics_address = "127.0.0.1:8234" disable_verification = true [[resolver.host."registry2-store:5000".mirrors]] host = "registry2-store:5000" insecure = true stargz-snapshotter-0.14.3/script/demo-store/run.sh000077500000000000000000000042341440204344700222130ustar00rootroot00000000000000#!/bin/bash # Copyright The containerd Authors. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. set -euo pipefail REPO=$GOPATH/src/github.com/containerd/stargz-snapshotter REG_STORAGE_CONFIG_FILE="/etc/stargz-store/config.toml" REG_STORAGE_ROOT=/var/lib/stargz-store/ REG_STORAGE_MOUNTPOINT="${REG_STORAGE_ROOT}store/" RETRYNUM=30 RETRYINTERVAL=1 TIMEOUTSEC=180 function retry { local SUCCESS=false for i in $(seq ${RETRYNUM}) ; do if eval "timeout ${TIMEOUTSEC} ${@}" ; then SUCCESS=true break fi echo "Fail(${i}). Retrying..." sleep ${RETRYINTERVAL} done if [ "${SUCCESS}" == "true" ] ; then return 0 else return 1 fi } function kill_all { if [ "${1}" != "" ] ; then ps aux | grep "${1}" \ | grep -v grep \ | grep -v "hello.py" \ | grep -v $(basename ${0}) \ | sed -E 's/ +/ /g' | cut -f 2 -d ' ' | xargs -I{} kill -9 {} || true fi } function cleanup { podman system reset -f || true umount "${REG_STORAGE_MOUNTPOINT}" || true rm -rf "${REG_STORAGE_ROOT}"* } echo "cleaning up the environment..." cleanup kill_all "stargz-store" echo "copying config from repo..." cp -R "${REPO}/script/demo-store/etc/"* "/etc/" echo "preparing commands..." ( cd "${REPO}" && PREFIX=/tmp/out/ make clean && \ PREFIX=/tmp/out/ make -j2 && \ PREFIX=/tmp/out/ make install ) echo "running stargz store..." mkdir -p "${REG_STORAGE_MOUNTPOINT}" stargz-store --log-level=debug \ --config="${REG_STORAGE_CONFIG_FILE}" \ "${REG_STORAGE_MOUNTPOINT}" & retry ls "${REG_STORAGE_ROOT}store/pool" stargz-snapshotter-0.14.3/script/demo/000077500000000000000000000000001440204344700177135ustar00rootroot00000000000000stargz-snapshotter-0.14.3/script/demo/.env000066400000000000000000000001021440204344700204750ustar00rootroot00000000000000GOPATH=/go HTTP_PROXY= HTTPS_PROXY= http_proxy= https_proxy= HOME=stargz-snapshotter-0.14.3/script/demo/config.cni.conflist000066400000000000000000000005141440204344700234730ustar00rootroot00000000000000{ "cniVersion": "0.4.0", "name": "demo", "plugins" : [{ "type": "bridge", "bridge": "optimizer0", "isDefaultGateway": true, "forceAddress": false, "ipMasq": true, "hairpinMode": true, "ipam": { "type": "host-local", "subnet": "10.10.0.0/16" } }, { "type": "loopback" }] } stargz-snapshotter-0.14.3/script/demo/config.containerd.toml000066400000000000000000000002241440204344700242000ustar00rootroot00000000000000version = 2 [proxy_plugins] [proxy_plugins.stargz] type = "snapshot" address = "/run/containerd-stargz-grpc/containerd-stargz-grpc.sock" stargz-snapshotter-0.14.3/script/demo/config.stargz.toml000066400000000000000000000004131440204344700233640ustar00rootroot00000000000000metrics_address = "127.0.0.1:8234" disable_verification = true ipfs = true # metadata_store = "db" [[resolver.host."registry2:5000".mirrors]] host = "registry2:5000" insecure = true [directory_cache] direct = true [snapshotter] allow_invalid_mounts_on_restart = true stargz-snapshotter-0.14.3/script/demo/docker-compose.yml000066400000000000000000000023731440204344700233550ustar00rootroot00000000000000version: "3.4" services: containerd_demo: build: context: ../../ target: demo args: NO_PROXY: "${NO_PROXY}" HTTP_PROXY: "${HTTP_PROXY}" HTTPS_PROXY: "${HTTPS_PROXY}" http_proxy: "${http_proxy}" https_proxy: "${https_proxy}" container_name: containerd_demo privileged: true stdin_open: true tty: true working_dir: /go/src/github.com/containerd/stargz-snapshotter entrypoint: /bin/bash environment: - NO_PROXY=127.0.0.1,localhost,registry2:5000 - HTTP_PROXY=${HTTP_PROXY} - HTTPS_PROXY=${HTTPS_PROXY} - http_proxy=${http_proxy} - https_proxy=${https_proxy} - GOPATH=/go tmpfs: - /tmp:exec,mode=777 volumes: - /dev/fuse:/dev/fuse - "${GOPATH}/src/github.com/containerd/stargz-snapshotter:/go/src/github.com/containerd/stargz-snapshotter:ro" - "demo-containerd-data:/var/lib/containerd" - "demo-containerd-stargz-grpc-data:/var/lib/containerd-stargz-grpc" registry2: image: registry:2 container_name: registry2 environment: - HTTP_PROXY=${HTTP_PROXY} - HTTPS_PROXY=${HTTPS_PROXY} - http_proxy=${http_proxy} - https_proxy=${https_proxy} volumes: demo-containerd-data: demo-containerd-stargz-grpc-data: stargz-snapshotter-0.14.3/script/demo/run.sh000077500000000000000000000057061440204344700210660ustar00rootroot00000000000000#!/bin/bash # Copyright The containerd Authors. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. set -euo pipefail REPO=$GOPATH/src/github.com/containerd/stargz-snapshotter CONTAINERD_CONFIG_DIR=/etc/containerd/ CONTAINERD_ROOT=/var/lib/containerd/ REMOTE_SNAPSHOTTER_CONFIG_DIR=/etc/containerd-stargz-grpc/ REMOTE_SNAPSHOTTER_ROOT=/var/lib/containerd-stargz-grpc/ REMOTE_SNAPSHOTTER_SOCKET=/run/containerd-stargz-grpc/containerd-stargz-grpc.sock CNI_CONFIG_DIR=/etc/cni/net.d/ RETRYNUM=30 RETRYINTERVAL=1 TIMEOUTSEC=180 function retry { local SUCCESS=false for i in $(seq ${RETRYNUM}) ; do if eval "timeout ${TIMEOUTSEC} ${@}" ; then SUCCESS=true break fi echo "Fail(${i}). Retrying..." sleep ${RETRYINTERVAL} done if [ "${SUCCESS}" == "true" ] ; then return 0 else return 1 fi } function kill_all { if [ "${1}" != "" ] ; then ps aux | grep "${1}" | grep -v grep | sed -E 's/ +/ /g' | cut -f 2 -d ' ' | xargs -I{} kill -9 {} || true fi } function cleanup { rm -rf "${CONTAINERD_ROOT}"* if [ -f "${REMOTE_SNAPSHOTTER_SOCKET}" ] ; then rm "${REMOTE_SNAPSHOTTER_SOCKET}" fi if [ -d "${REMOTE_SNAPSHOTTER_ROOT}snapshotter/snapshots/" ] ; then find "${REMOTE_SNAPSHOTTER_ROOT}snapshotter/snapshots/" \ -maxdepth 1 -mindepth 1 -type d -exec umount "{}/fs" \; fi rm -rf "${REMOTE_SNAPSHOTTER_ROOT}"* } echo "copying config from repo..." mkdir -p "${CONTAINERD_CONFIG_DIR}" "${REMOTE_SNAPSHOTTER_CONFIG_DIR}" "${CNI_CONFIG_DIR}" && \ cp "${REPO}/script/demo/config.containerd.toml" "${CONTAINERD_CONFIG_DIR}config.toml" && \ cp "${REPO}/script/demo/config.stargz.toml" "${REMOTE_SNAPSHOTTER_CONFIG_DIR}config.toml" && \ cp "${REPO}/script/demo/config.cni.conflist" "${CNI_CONFIG_DIR}optimizer.conflist" echo "cleaning up the environment..." kill_all "containerd" kill_all "containerd-stargz-grpc" cleanup echo "preparing commands..." ( cd "${REPO}" && PREFIX=/tmp/out/ make clean && \ PREFIX=/tmp/out/ make -j2 && \ PREFIX=/tmp/out/ make install ) echo "running remote snaphsotter..." containerd-stargz-grpc --log-level=debug \ --address="${REMOTE_SNAPSHOTTER_SOCKET}" \ --config="${REMOTE_SNAPSHOTTER_CONFIG_DIR}config.toml" & retry ls "${REMOTE_SNAPSHOTTER_SOCKET}" echo "running containerd..." containerd --config="${CONTAINERD_CONFIG_DIR}config.toml" $@ & stargz-snapshotter-0.14.3/script/generated-files/000077500000000000000000000000001440204344700220255ustar00rootroot00000000000000stargz-snapshotter-0.14.3/script/generated-files/generate.sh000077500000000000000000000061231440204344700241600ustar00rootroot00000000000000#!/bin/bash # Copyright The containerd Authors. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. set -euo pipefail CONTEXT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )/" REPO="${CONTEXT}../../" source "${REPO}/script/util/utils.sh" GOBASE_VERSION=$(go_base_version "${REPO}/Dockerfile") # TODO: get the following versions from go.mod once we add them. PROTOC_VERSION=3.17.3 GOGO_VERSION=v1.3.2 COMMAND="${1}" if [ "${COMMAND}" != "update" ] && [ "${COMMAND}" != "validate" ] ; then echo "either of \"update\" or \"validate\" must be specified" exit 1 fi TMP_CONTEXT=$(mktemp -d) GENERATED_FILES=$(mktemp -d) function cleanup { local ORG_EXIT_CODE="${1}" rm -rf "${GENERATED_FILES}" || true rm -rf "${TMP_CONTEXT}" || true exit "${ORG_EXIT_CODE}" } trap 'cleanup "$?"' EXIT SIGHUP SIGINT SIGQUIT SIGTERM cat < "${TMP_CONTEXT}/Dockerfile" FROM golang:${GOBASE_VERSION} AS golang-base ARG PROTOC_VERSION=${PROTOC_VERSION} ARG GOGO_VERSION=${GOGO_VERSION} ARG TARGETOS TARGETARCH RUN apt-get update && apt-get --no-install-recommends install -y unzip && \ PARCH=\$(echo \${TARGETARCH} | sed -e 's/amd64/x86_64/' -e 's/arm64/aarch_64/') && \ wget -O /tmp/protoc.zip \ https://github.com/google/protobuf/releases/download/v\${PROTOC_VERSION}/protoc-\${PROTOC_VERSION}-\${TARGETOS}-\${PARCH}.zip && \ unzip /tmp/protoc.zip -d /usr/local && \ go install github.com/gogo/protobuf/protoc-gen-gogo@\$GOGO_VERSION WORKDIR /go/src/github.com/containerd/stargz-snapshotter FROM golang-base AS generate COPY . . RUN git add -A && \ go generate -v ./... && \ mkdir /generated-files && \ git ls-files -m --others -- **/*.pb.go | tar -cf - --files-from - | tar -C /generated-files -xf - FROM scratch AS update COPY --from=generate /generated-files / FROM golang-base AS validate COPY . . RUN git add -A && \ go generate -v ./... && \ DIFFS=\$(git status --porcelain -- **/*.pb.go 2>/dev/null) ; \ if [ "\${DIFFS}" ]; then \ echo "Unexpected generated files; Please run \"make generate\"" && \ git diff && \ echo \${DIFFS} && \ exit 1 ; \ else \ echo OK ; \ fi EOF case ${COMMAND} in update) DOCKER_BUILDKIT=1 docker build --progress=plain --target update -f "${TMP_CONTEXT}/Dockerfile" -o - "${REPO}" | tar -C "${GENERATED_FILES}/" -x if ! [ -z "$(ls -A ${GENERATED_FILES}/)" ]; then cp -R "${GENERATED_FILES}/"* "${REPO}" ; fi ;; validate) DOCKER_BUILDKIT=1 docker build --progress=plain --target validate -f "${TMP_CONTEXT}/Dockerfile" "${REPO}" ;; esac stargz-snapshotter-0.14.3/script/integration/000077500000000000000000000000001440204344700213125ustar00rootroot00000000000000stargz-snapshotter-0.14.3/script/integration/containerd/000077500000000000000000000000001440204344700234405ustar00rootroot00000000000000stargz-snapshotter-0.14.3/script/integration/containerd/config.containerd.toml000066400000000000000000000005701440204344700277310ustar00rootroot00000000000000version = 2 [plugins."io.containerd.snapshotter.v1.stargz"] root_path = "/var/lib/containerd-stargz-grpc/" disable_verification = false metadata_store = "memory" [plugins."io.containerd.snapshotter.v1.stargz".blob] check_always = true [plugins."io.containerd.snapshotter.v1.stargz".registry.mirrors."registry-integration.test"] endpoint = ["http://registry-alt.test:5000"] stargz-snapshotter-0.14.3/script/integration/containerd/config.stargz.toml000066400000000000000000000002511440204344700271110ustar00rootroot00000000000000metadata_store = "memory" ipfs = true [blob] check_always = true [[resolver.host."registry-integration.test".mirrors]] host = "registry-alt.test:5000" insecure = true stargz-snapshotter-0.14.3/script/integration/containerd/entrypoint.sh000077500000000000000000000451411440204344700262170ustar00rootroot00000000000000#!/bin/bash # Copyright The containerd Authors. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. set -euo pipefail # NOTE: The entire contents of containerd/stargz-snapshotter are located in # the testing container so utils.sh is visible from this script during runtime. # TODO: Refactor the code dependencies and pack them in the container without # expecting and relying on volumes. source "/utils.sh" PLUGIN=stargz REGISTRY_HOST=registry-integration.test REGISTRY_ALT_HOST=registry-alt.test DUMMYUSER=dummyuser DUMMYPASS=dummypass USR_ORG=$(mktemp -d) USR_MIRROR=$(mktemp -d) USR_REFRESH=$(mktemp -d) USR_TMPDIR=$(mktemp -d) USR_NORMALSN_UNSTARGZ=$(mktemp -d) USR_STARGZSN_UNSTARGZ=$(mktemp -d) USR_NORMALSN_STARGZ=$(mktemp -d) USR_STARGZSN_STARGZ=$(mktemp -d) USR_NORMALSN_ZSTD=$(mktemp -d) USR_STARGZSN_ZSTD=$(mktemp -d) USR_NORMALSN_PLAIN_STARGZ=$(mktemp -d) USR_STARGZSN_PLAIN_STARGZ=$(mktemp -d) USR_NORMALSN_IPFS=$(mktemp -d) USR_STARGZSN_IPFS=$(mktemp -d) USR_STARGZSN_CTD_IPFS=$(mktemp -d) LOG_FILE=$(mktemp) function cleanup { ORG_EXIT_CODE="${1}" rm -rf "${USR_ORG}" || true rm -rf "${USR_MIRROR}" || true rm -rf "${USR_REFRESH}" || true rm -rf "${USR_TMPDIR}" || true rm -rf "${USR_NORMALSN_UNSTARGZ}" || true rm -rf "${USR_STARGZSN_UNSTARGZ}" || true rm -rf "${USR_NORMALSN_STARGZ}" || true rm -rf "${USR_STARGZSN_STARGZ}" || true rm -rf "${USR_NORMALSN_PLAIN_STARGZ}" || true rm -rf "${USR_STARGZSN_PLAIN_STARGZ}" || true rm -rf "${USR_NORMALSN_ZSTD}" || true rm -rf "${USR_STARGZSN_ZSTD}" || true rm -rf "${USR_NORMALSN_IPFS}" || true rm -rf "${USR_STARGZSN_IPFS}" || true rm -rf "${USR_STARGZSN_CTD_IPFS}" || true rm "${LOG_FILE}" exit "${ORG_EXIT_CODE}" } trap 'cleanup "$?"' EXIT SIGHUP SIGINT SIGQUIT SIGTERM RETRYNUM=100 RETRYINTERVAL=1 TIMEOUTSEC=180 function retry { local SUCCESS=false for i in $(seq ${RETRYNUM}) ; do if eval "timeout ${TIMEOUTSEC} ${@}" ; then SUCCESS=true break fi echo "Fail(${i}). Retrying..." sleep ${RETRYINTERVAL} done if [ "${SUCCESS}" == "true" ] ; then return 0 else return 1 fi } function kill_all { if [ "${1}" != "" ] ; then ps aux | grep "${1}" | grep -v grep | grep -v $(basename ${0}) | sed -E 's/ +/ /g' | cut -f 2 -d ' ' | xargs -I{} kill -9 {} || true fi } CONTAINERD_ROOT=/var/lib/containerd/ CONTAINERD_STATUS=/run/containerd/ REMOTE_SNAPSHOTTER_SOCKET=/run/containerd-stargz-grpc/containerd-stargz-grpc.sock REMOTE_SNAPSHOTTER_ROOT=/var/lib/containerd-stargz-grpc/ function reboot_containerd { kill_all "containerd" kill_all "containerd-stargz-grpc" rm -rf "${CONTAINERD_STATUS}"* rm -rf "${CONTAINERD_ROOT}"* if [ -f "${REMOTE_SNAPSHOTTER_SOCKET}" ] ; then rm "${REMOTE_SNAPSHOTTER_SOCKET}" fi if [ -d "${REMOTE_SNAPSHOTTER_ROOT}snapshotter/snapshots/" ] ; then find "${REMOTE_SNAPSHOTTER_ROOT}snapshotter/snapshots/" \ -maxdepth 1 -mindepth 1 -type d -exec umount "{}/fs" \; fi rm -rf "${REMOTE_SNAPSHOTTER_ROOT}"* if [ "${BUILTIN_SNAPSHOTTER}" == "true" ] ; then if [ "${CONTAINERD_CONFIG:-}" != "" ] ; then containerd --log-level debug --config="${CONTAINERD_CONFIG:-}" 2>&1 | tee -a "${LOG_FILE}" & else containerd --log-level debug --config=/etc/containerd/config.toml 2>&1 | tee -a "${LOG_FILE}" & fi else if [ "${SNAPSHOTTER_CONFIG:-}" == "" ] ; then containerd-stargz-grpc --log-level=debug \ --address="${REMOTE_SNAPSHOTTER_SOCKET}" \ 2>&1 | tee -a "${LOG_FILE}" & # Dump all log else containerd-stargz-grpc --log-level=debug \ --address="${REMOTE_SNAPSHOTTER_SOCKET}" \ --config="${SNAPSHOTTER_CONFIG}" \ 2>&1 | tee -a "${LOG_FILE}" & fi retry ls "${REMOTE_SNAPSHOTTER_SOCKET}" containerd --log-level debug --config=/etc/containerd/config.toml & fi # Makes sure containerd and containerd-stargz-grpc are up-and-running. UNIQUE_SUFFIX=$(date +%s%N | shasum | base64 | fold -w 10 | head -1) retry ctr snapshots --snapshotter="${PLUGIN}" prepare "connectiontest-dummy-${UNIQUE_SUFFIX}" "" } function optimize { local SRC="${1}" local DST="${2}" local PLAINHTTP="${3}" local OPTS=${@:4} ctr-remote image pull -u "${DUMMYUSER}:${DUMMYPASS}" "${SRC}" ctr-remote image optimize ${OPTS} --oci "${SRC}" "${DST}" PUSHOPTS= if [ "${PLAINHTTP}" == "true" ] ; then PUSHOPTS=--plain-http fi ctr-remote image push ${PUSHOPTS} -u "${DUMMYUSER}:${DUMMYPASS}" "${DST}" } function convert { local SRC="${1}" local DST="${2}" local PLAINHTTP="${3}" local OPTS=${@:4} PUSHOPTS= if [ "${PLAINHTTP}" == "true" ] ; then PUSHOPTS=--plain-http fi ctr-remote image pull -u "${DUMMYUSER}:${DUMMYPASS}" "${SRC}" ctr-remote image convert ${OPTS} --oci "${SRC}" "${DST}" ctr-remote image push ${PUSHOPTS} -u "${DUMMYUSER}:${DUMMYPASS}" "${DST}" } function copy { local SRC="${1}" local DST="${2}" ctr-remote i pull --all-platforms "${SRC}" ctr-remote i tag "${SRC}" "${DST}" ctr-remote i push -u "${DUMMYUSER}:${DUMMYPASS}" "${DST}" } function copy_out_dir { local IMAGE="${1}" local TARGETDIR="${2}" local DEST="${3}" local SNAPSHOTTER="${4}" TMPFILE=$(mktemp) UNIQUE=$(date +%s%N | shasum | base64 | fold -w 10 | head -1) ctr-remote run --snapshotter="${SNAPSHOTTER}" "${IMAGE}" "${UNIQUE}" tar -c "${TARGETDIR}" > "${TMPFILE}" tar -C "${DEST}" -xf "${TMPFILE}" ctr-remote c rm "${UNIQUE}" || true rm "${TMPFILE}" } function dump_dir { local IMAGE="${1}" local TARGETDIR="${2}" local SNAPSHOTTER="${3}" local REMOTE="${4}" local DEST="${5}" reboot_containerd if [ "${REMOTE}" == "true" ] ; then run_and_check_remote_snapshots ctr-remote images rpull --user "${DUMMYUSER}:${DUMMYPASS}" "${IMAGE}" else ctr-remote images pull --snapshotter="${SNAPSHOTTER}" --user "${DUMMYUSER}:${DUMMYPASS}" "${IMAGE}" fi copy_out_dir "${IMAGE}" "${TARGETDIR}" "${DEST}" "${SNAPSHOTTER}" } function run_and_check_remote_snapshots { echo -n "" > "${LOG_FILE}" ${@:1} check_remote_snapshots "${LOG_FILE}" } # Copied from moby project (Apache License 2.0) # https://github.com/moby/moby/blob/a9fe88e395acaacd84067b5fc701d52dbcf4b625/hack/dind#L28-L38 # cgroup v2: enable nesting if [ -f /sys/fs/cgroup/cgroup.controllers ]; then # move the processes from the root group to the /init group, # otherwise writing subtree_control fails with EBUSY. # An error during moving non-existent process (i.e., "cat") is ignored. mkdir -p /sys/fs/cgroup/init xargs -rn1 < /sys/fs/cgroup/cgroup.procs > /sys/fs/cgroup/init/cgroup.procs || : # enable controllers sed -e 's/ / +/g' -e 's/^/+/' < /sys/fs/cgroup/cgroup.controllers \ > /sys/fs/cgroup/cgroup.subtree_control fi echo "===== VERSION INFORMATION =====" containerd --version runc --version echo "===============================" cat <> /etc/containerd/config.toml [debug] format = "json" level = "debug" EOF if [ "${BUILTIN_SNAPSHOTTER}" != "true" ] ; then cat <> /etc/containerd/config.toml [proxy_plugins] [proxy_plugins.stargz] type = "snapshot" address = "/run/containerd-stargz-grpc/containerd-stargz-grpc.sock" EOF fi echo "Logging into the registry..." cp /auth/certs/domain.crt /usr/local/share/ca-certificates update-ca-certificates retry nerdctl login -u "${DUMMYUSER}" -p "${DUMMYPASS}" "${REGISTRY_HOST}" reboot_containerd OK=$(ctr-remote plugins ls \ | grep io.containerd.snapshotter \ | sed -E 's/ +/ /g' \ | cut -d ' ' -f 2,4 \ | grep "${PLUGIN}" \ | cut -d ' ' -f 2) if [ "${OK}" != "ok" ] ; then echo "Plugin ${PLUGIN} not found" 1>&2 exit 1 fi echo "Preparing images..." copy ghcr.io/stargz-containers/ubuntu:22.04-org "${REGISTRY_HOST}/ubuntu:22.04" copy ghcr.io/stargz-containers/alpine:3.15.3-org "${REGISTRY_HOST}/alpine:3.15.3" stargzify "${REGISTRY_HOST}/ubuntu:22.04" "${REGISTRY_HOST}/ubuntu:sgz" optimize "${REGISTRY_HOST}/ubuntu:22.04" "${REGISTRY_HOST}/ubuntu:esgz" "false" optimize "${REGISTRY_HOST}/ubuntu:22.04" "${REGISTRY_HOST}/ubuntu:zstdchunked" "false" --zstdchunked optimize "${REGISTRY_HOST}/alpine:3.15.3" "${REGISTRY_HOST}/alpine:esgz" "false" optimize "${REGISTRY_HOST}/alpine:3.15.3" "${REGISTRY_ALT_HOST}:5000/alpine:esgz" "true" # images for external TOC and min-chunk-size # TODO: support external TOC suffix other than "-esgztoc" optimize "${REGISTRY_HOST}/ubuntu:22.04" "${REGISTRY_HOST}/ubuntu:esgz-50000" "false" --estargz-min-chunk-size=50000 optimize "${REGISTRY_HOST}/ubuntu:22.04" "${REGISTRY_HOST}/ubuntu:esgz-ex" "false" --estargz-external-toc ctr-remote i push -u "${DUMMYUSER}:${DUMMYPASS}" "${REGISTRY_HOST}/ubuntu:esgz-ex-esgztoc" convert "${REGISTRY_HOST}/ubuntu:22.04" "${REGISTRY_HOST}/ubuntu:esgz-ex-keep-diff-id" "false" --estargz --estargz-external-toc --estargz-keep-diff-id ctr-remote i push -u "${DUMMYUSER}:${DUMMYPASS}" "${REGISTRY_HOST}/ubuntu:esgz-ex-keep-diff-id-esgztoc" if [ "${BUILTIN_SNAPSHOTTER}" != "true" ] ; then ############ # Tests with IPFS if standalone snapshotter echo "Testing with IPFS..." export IPFS_PATH="/tmp/ipfs" mkdir -p "${IPFS_PATH}" ipfs init ipfs daemon --offline & retry curl -X POST localhost:5001/api/v0/version >/dev/null 2>&1 # wait for up # stargz snapshotter (default labels) ctr-remote i pull --user "${DUMMYUSER}:${DUMMYPASS}" "${REGISTRY_HOST}/ubuntu:22.04" CID=$(ctr-remote i ipfs-push "${REGISTRY_HOST}/ubuntu:22.04") reboot_containerd run_and_check_remote_snapshots ctr-remote i rpull --ipfs "${CID}" copy_out_dir "${CID}" "/usr" "${USR_STARGZSN_IPFS}" "stargz" # stargz snapshotter (containerd labels) ctr-remote i pull --user "${DUMMYUSER}:${DUMMYPASS}" "${REGISTRY_HOST}/ubuntu:22.04" CID=$(ctr-remote i ipfs-push "${REGISTRY_HOST}/ubuntu:22.04") reboot_containerd run_and_check_remote_snapshots ctr-remote i rpull --use-containerd-labels --ipfs "${CID}" copy_out_dir "${CID}" "/usr" "${USR_STARGZSN_CTD_IPFS}" "stargz" # overlayfs snapshotter ctr-remote i pull --user "${DUMMYUSER}:${DUMMYPASS}" "${REGISTRY_HOST}/ubuntu:22.04" CID=$(ctr-remote i ipfs-push --estargz=false "${REGISTRY_HOST}/ubuntu:22.04") reboot_containerd ctr-remote i rpull --snapshotter=overlayfs --ipfs "${CID}" copy_out_dir "${CID}" "/usr" "${USR_NORMALSN_IPFS}" "overlayfs" echo "Diffing between two root filesystems(normal vs stargz snapshotter(default labels), IPFS rootfs)" diff --no-dereference -qr "${USR_NORMALSN_IPFS}/" "${USR_STARGZSN_IPFS}/" echo "Diffing between two root filesystems(normal vs stargz snapshotter(containerd labels), IPFS rootfs)" diff --no-dereference -qr "${USR_NORMALSN_IPFS}/" "${USR_STARGZSN_CTD_IPFS}/" kill_all ipfs fi ############ # Tests for refreshing and mirror echo "Testing refreshing and mirror..." reboot_containerd echo "Getting image with normal snapshotter..." ctr-remote images pull --user "${DUMMYUSER}:${DUMMYPASS}" "${REGISTRY_HOST}/alpine:esgz" copy_out_dir "${REGISTRY_HOST}/alpine:esgz" "/usr" "${USR_ORG}" "overlayfs" echo "Getting image with stargz snapshotter..." run_and_check_remote_snapshots ctr-remote images rpull --user "${DUMMYUSER}:${DUMMYPASS}" "${REGISTRY_HOST}/alpine:esgz" REGISTRY_HOST_IP=$(getent hosts "${REGISTRY_HOST}" | awk '{ print $1 }') REGISTRY_ALT_HOST_IP=$(getent hosts "${REGISTRY_ALT_HOST}" | awk '{ print $1 }') echo "Disabling source registry and check if mirroring is working for stargz snapshotter..." iptables -A OUTPUT -d "${REGISTRY_HOST_IP}" -j DROP iptables -L copy_out_dir "${REGISTRY_HOST}/alpine:esgz" "/usr" "${USR_MIRROR}" "stargz" iptables -D OUTPUT -d "${REGISTRY_HOST_IP}" -j DROP echo "Disabling mirror registry and check if refreshing works for stargz snapshotter..." iptables -A OUTPUT -d "${REGISTRY_ALT_HOST_IP}" -j DROP iptables -L copy_out_dir "${REGISTRY_HOST}/alpine:esgz" "/usr" "${USR_REFRESH}" "stargz" iptables -D OUTPUT -d "${REGISTRY_ALT_HOST_IP}" -j DROP echo "Disabling all registries and running container should fail" iptables -A OUTPUT -d "${REGISTRY_HOST_IP}","${REGISTRY_ALT_HOST_IP}" -j DROP iptables -L if ctr-remote run --rm --snapshotter=stargz "${REGISTRY_HOST}/alpine:esgz" test tar -c /usr > /usr_dummy_fail.tar ; then echo "All registries are disabled so this must be failed" exit 1 else echo "Failed to run the container as expected" fi iptables -D OUTPUT -d "${REGISTRY_HOST_IP}","${REGISTRY_ALT_HOST_IP}" -j DROP echo "Diffing root filesystems for mirroring" diff --no-dereference -qr "${USR_ORG}/" "${USR_MIRROR}/" echo "Diffing root filesystems for refreshing" diff --no-dereference -qr "${USR_ORG}/" "${USR_REFRESH}/" ############ # Tests for stargz filesystem echo "Testing stargz filesystem..." # Test with a normal image echo "Getting normal image with normal snapshotter..." OVERLAYFSSN=$(mktemp -d --tmpdir="${USR_TMPDIR}") dump_dir "${REGISTRY_HOST}/ubuntu:22.04" "/usr" "overlayfs" "false" "${OVERLAYFSSN}" echo "Getting normal image with stargz snapshotter..." STARGZSN=$(mktemp -d --tmpdir="${USR_TMPDIR}") dump_dir "${REGISTRY_HOST}/ubuntu:22.04" "/usr" "stargz" "false" "${STARGZSN}" echo "Diffing between two root filesystems(normal vs stargz snapshotter, normal rootfs)" diff --no-dereference -qr "${OVERLAYFSSN}/" "${STARGZSN}/" # Test with an eStargz image echo "Getting eStargz image with normal snapshotter..." dump_dir "${REGISTRY_HOST}/ubuntu:esgz" "/usr" "overlayfs" "false" "${USR_NORMALSN_STARGZ}" echo "Getting eStargz image with stargz snapshotter..." dump_dir "${REGISTRY_HOST}/ubuntu:esgz" "/usr" "stargz" "true" "${USR_STARGZSN_STARGZ}" echo "Diffing between two root filesystems(normal vs stargz snapshotter, eStargz rootfs)" diff --no-dereference -qr "${USR_NORMALSN_STARGZ}/" "${USR_STARGZSN_STARGZ}/" # Test with a zstd:chunked image echo "Getting zstd:chunked image with normal snapshotter..." dump_dir "${REGISTRY_HOST}/ubuntu:zstdchunked" "/usr" "overlayfs" "false" "${USR_NORMALSN_ZSTD}" echo "Getting zstd:chunked image with stargz snapshotter..." dump_dir "${REGISTRY_HOST}/ubuntu:zstdchunked" "/usr" "stargz" "true" "${USR_STARGZSN_ZSTD}" echo "Diffing between two root filesystems(normal vs stargz snapshotter, zstd:cunked rootfs)" diff --no-dereference -qr "${USR_NORMALSN_ZSTD}/" "${USR_STARGZSN_ZSTD}/" # Test with a external TOC image echo "Getting external TOC image with normal snapshotter..." EX_OVERLAYFSSN=$(mktemp -d --tmpdir="${USR_TMPDIR}") dump_dir "${REGISTRY_HOST}/ubuntu:esgz-ex" "/usr" "overlayfs" "false" "${EX_OVERLAYFSSN}" echo "Getting external TOC image with stargz snapshotter..." EX_STARGZSN=$(mktemp -d --tmpdir="${USR_TMPDIR}") dump_dir "${REGISTRY_HOST}/ubuntu:esgz-ex" "/usr" "stargz" "true" "${EX_STARGZSN}" echo "Diffing between two root filesystems(normal vs stargz snapshotter, eStargz (external TOC) rootfs)" diff --no-dereference -qr "${EX_OVERLAYFSSN}/" "${EX_STARGZSN}/" # Test with a external TOC + keep-diff-id image echo "Getting external TOC image (keep diff id) with normal snapshotter..." EXLL_OVERLAYFSSN=$(mktemp -d --tmpdir="${USR_TMPDIR}") dump_dir "${REGISTRY_HOST}/ubuntu:esgz-ex-keep-diff-id" "/usr" "overlayfs" "false" "${EXLL_OVERLAYFSSN}" echo "Getting external TOC image (keep diff id) with stargz snapshotter..." EXLL_STARGZSN=$(mktemp -d --tmpdir="${USR_TMPDIR}") dump_dir "${REGISTRY_HOST}/ubuntu:esgz-ex-keep-diff-id" "/usr" "stargz" "true" "${EXLL_STARGZSN}" echo "Diffing between two root filesystems(normal vs stargz snapshotter, eStargz (external TOC, keep-diff-id) rootfs)" diff --no-dereference -qr "${EXLL_OVERLAYFSSN}/" "${EXLL_STARGZSN}/" # Test with a eStargz with min-chunk-size=50000 image echo "Getting eStargz (min-chunk-size=50000) with normal snapshotter..." E50000_OVERLAYFSSN=$(mktemp -d --tmpdir="${USR_TMPDIR}") dump_dir "${REGISTRY_HOST}/ubuntu:esgz-50000" "/usr" "overlayfs" "false" "${E50000_OVERLAYFSSN}" echo "Getting eStargz (min-chunk-size=50000) with stargz snapshotter..." E50000_STARGZSN=$(mktemp -d --tmpdir="${USR_TMPDIR}") dump_dir "${REGISTRY_HOST}/ubuntu:esgz-50000" "/usr" "stargz" "true" "${E50000_STARGZSN}" echo "Diffing between two root filesystems(normal vs stargz snapshotter, eStargz (min-chunk-size=50000) rootfs)" diff --no-dereference -qr "${E50000_OVERLAYFSSN}/" "${E50000_STARGZSN}/" ############ # Checking compatibility with plain stargz reboot_containerd echo "Getting (legacy) stargz image with normal snapshotter..." dump_dir "${REGISTRY_HOST}/ubuntu:sgz" "/usr" "overlayfs" "false" "${USR_NORMALSN_PLAIN_STARGZ}" echo "Getting (legacy) stargz image with stargz snapshotter..." TEST_CONTAINERD_CONFIG= TEST_SNAPSHOTTER_CONFIG= if [ "${BUILTIN_SNAPSHOTTER}" == "true" ] ; then cp /etc/containerd/config.toml /tmp/config.containerd.noverify.toml sed -i 's/disable_verification = false/disable_verification = true/g' /tmp/config.containerd.noverify.toml TEST_CONTAINERD_CONFIG="/tmp/config.containerd.noverify.toml" else echo "disable_verification = true" > /tmp/config.stargz.noverify.toml cat /etc/containerd-stargz-grpc/config.toml >> /tmp/config.stargz.noverify.toml TEST_SNAPSHOTTER_CONFIG="/tmp/config.stargz.noverify.toml" fi CONTAINERD_CONFIG="${TEST_CONTAINERD_CONFIG}" SNAPSHOTTER_CONFIG="${TEST_SNAPSHOTTER_CONFIG}" \ dump_dir "${REGISTRY_HOST}/ubuntu:sgz" "/usr" "stargz" "true" "${USR_STARGZSN_PLAIN_STARGZ}" echo "Diffing between two root filesystems(normal vs stargz snapshotter, plain stargz rootfs)" diff --no-dereference -qr "${USR_NORMALSN_PLAIN_STARGZ}/" "${USR_STARGZSN_PLAIN_STARGZ}/" ############ # Try to pull this image from different namespace. ctr-remote --namespace=dummy images rpull --user "${DUMMYUSER}:${DUMMYPASS}" \ "${REGISTRY_HOST}/ubuntu:esgz" ############ # Test for starting when no configuration file. mv /etc/containerd-stargz-grpc/config.toml /etc/containerd-stargz-grpc/config.toml_rm reboot_containerd mv /etc/containerd-stargz-grpc/config.toml_rm /etc/containerd-stargz-grpc/config.toml exit 0 stargz-snapshotter-0.14.3/script/integration/test.sh000077500000000000000000000125111440204344700226300ustar00rootroot00000000000000#!/bin/bash # Copyright The containerd Authors. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. set -euo pipefail CONTEXT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )/" REPO="${CONTEXT}../../" INTEGRATION_BASE_IMAGE_NAME="integration-image-base" INTEGRATION_TEST_IMAGE_NAME="integration-image-test" REGISTRY_HOST=registry-integration.test REGISTRY_ALT_HOST=registry-alt.test CONTAINERD_NODE=testenv_integration DUMMYUSER=dummyuser DUMMYPASS=dummypass IPFS_VERSION=v0.17.0 source "${REPO}/script/util/utils.sh" if [ "${INTEGRATION_NO_RECREATE:-}" != "true" ] ; then echo "Preparing node image..." TARGET_STAGE=snapshotter-base if [ "${BUILTIN_SNAPSHOTTER:-}" == "true" ] ; then TARGET_STAGE=containerd-snapshotter-base fi # Enable to check race # Temporary disable race check until docker/cli fixing race issue # https://github.com/docker/cli/pull/3264 # BUILD_FLAGS="-race" BUILD_FLAGS="" docker build ${DOCKER_BUILD_ARGS:-} -t "${INTEGRATION_BASE_IMAGE_NAME}" \ --target "${TARGET_STAGE}" \ --build-arg=SNAPSHOTTER_BUILD_FLAGS="${BUILD_FLAGS}" \ "${REPO}" fi USE_METADATA_STORE="memory" if [ "${METADATA_STORE:-}" != "" ] ; then USE_METADATA_STORE="${METADATA_STORE}" fi SNAPSHOTTER_CONFIG_FILE=/etc/containerd-stargz-grpc/config.toml if [ "${BUILTIN_SNAPSHOTTER:-}" == "true" ] ; then SNAPSHOTTER_CONFIG_FILE=/etc/containerd/config.toml fi DOCKER_COMPOSE_YAML=$(mktemp) AUTH_DIR=$(mktemp -d) SS_ROOT_DIR=$(mktemp -d) TMP_CONTEXT=$(mktemp -d) function cleanup { local ORG_EXIT_CODE="${1}" rm "${DOCKER_COMPOSE_YAML}" || true rm -rf "${AUTH_DIR}" || true rm -rf "${SS_ROOT_DIR}" || true rm -rf "${TMP_CONTEXT}" || true exit "${ORG_EXIT_CODE}" } trap 'cleanup "$?"' EXIT SIGHUP SIGINT SIGQUIT SIGTERM cp -R "${CONTEXT}/containerd" \ "${REPO}/script/util/utils.sh" \ "${TMP_CONTEXT}" cat < "${TMP_CONTEXT}/Dockerfile" FROM ${INTEGRATION_BASE_IMAGE_NAME} RUN apt-get update -y && \ apt-get --no-install-recommends install -y iptables jq && \ go install github.com/google/crfs/stargz/stargzify@71d77da419c90be7b05d12e59945ac7a8c94a543 && \ wget https://dist.ipfs.io/go-ipfs/${IPFS_VERSION}/go-ipfs_${IPFS_VERSION}_linux-amd64.tar.gz && \ tar -xvzf go-ipfs_${IPFS_VERSION}_linux-amd64.tar.gz && \ cd go-ipfs && \ bash install.sh COPY ./containerd/config.containerd.toml /etc/containerd/config.toml COPY ./containerd/config.stargz.toml /etc/containerd-stargz-grpc/config.toml COPY ./containerd/entrypoint.sh ./utils.sh / RUN sed -i 's/^metadata_store.*/metadata_store = "${USE_METADATA_STORE}"/g' "${SNAPSHOTTER_CONFIG_FILE}" ENV CONTAINERD_SNAPSHOTTER="" ENTRYPOINT [ "/entrypoint.sh" ] EOF docker build ${DOCKER_BUILD_ARGS:-} -t "${INTEGRATION_TEST_IMAGE_NAME}" ${DOCKER_BUILD_ARGS:-} "${TMP_CONTEXT}" echo "Preparing creds..." prepare_creds "${AUTH_DIR}" "${REGISTRY_HOST}" "${DUMMYUSER}" "${DUMMYPASS}" echo "Preparing docker-compose.yml..." cat < "${DOCKER_COMPOSE_YAML}" version: "3.3" services: ${CONTAINERD_NODE}: image: ${INTEGRATION_TEST_IMAGE_NAME} container_name: testenv_integration privileged: true environment: - NO_PROXY=127.0.0.1,localhost,${REGISTRY_HOST}:443,${REGISTRY_ALT_HOST}:5000 - HTTP_PROXY=${HTTP_PROXY:-} - HTTPS_PROXY=${HTTPS_PROXY:-} - http_proxy=${http_proxy:-} - https_proxy=${https_proxy:-} - BUILTIN_SNAPSHOTTER=${BUILTIN_SNAPSHOTTER:-} tmpfs: - /tmp:exec,mode=777 volumes: - "${REPO}:/go/src/github.com/containerd/stargz-snapshotter:ro" - ${AUTH_DIR}:/auth - /dev/fuse:/dev/fuse - "integration-containerd-data:/var/lib/containerd" - "integration-containerd-stargz-grpc-data:/var/lib/containerd-stargz-grpc" registry: image: registry:2 container_name: ${REGISTRY_HOST} environment: - HTTP_PROXY=${HTTP_PROXY:-} - HTTPS_PROXY=${HTTPS_PROXY:-} - http_proxy=${http_proxy:-} - https_proxy=${https_proxy:-} - REGISTRY_AUTH=htpasswd - REGISTRY_AUTH_HTPASSWD_REALM="Registry Realm" - REGISTRY_AUTH_HTPASSWD_PATH=/auth/auth/htpasswd - REGISTRY_HTTP_TLS_CERTIFICATE=/auth/certs/domain.crt - REGISTRY_HTTP_TLS_KEY=/auth/certs/domain.key - REGISTRY_HTTP_ADDR=${REGISTRY_HOST}:443 volumes: - ${AUTH_DIR}:/auth registry-alt: image: registry:2 container_name: "${REGISTRY_ALT_HOST}" volumes: integration-containerd-data: integration-containerd-stargz-grpc-data: EOF echo "Testing..." FAIL= if ! ( cd "${CONTEXT}" && \ docker-compose -f "${DOCKER_COMPOSE_YAML}" build ${DOCKER_BUILD_ARGS:-} \ "${CONTAINERD_NODE}" && \ docker-compose -f "${DOCKER_COMPOSE_YAML}" up --abort-on-container-exit ) ; then FAIL=true fi docker-compose -f "${DOCKER_COMPOSE_YAML}" down -v if [ "${FAIL}" == "true" ] ; then exit 1 fi exit 0 stargz-snapshotter-0.14.3/script/ipfs/000077500000000000000000000000001440204344700177305ustar00rootroot00000000000000stargz-snapshotter-0.14.3/script/ipfs/entrypoint.sh000077500000000000000000000015211440204344700225010ustar00rootroot00000000000000#!/bin/bash # Copyright The containerd Authors. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. set -euo pipefail REPO_PATH=/go/src/github.com/containerd/stargz-snapshotter ipfs init ipfs daemon --offline & curl --retry 10 --retry-all-errors --retry-delay 3 -X POST localhost:5001/api/v0/version >/dev/null 2>&1 # wait for up $@ stargz-snapshotter-0.14.3/script/ipfs/test.sh000077500000000000000000000036411440204344700212520ustar00rootroot00000000000000#!/bin/bash # Copyright The containerd Authors. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. set -euo pipefail CONTEXT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )/" REPO="${CONTEXT}../../" IMAGE_NAME="testipfs" source "${REPO}/script/util/utils.sh" GOBASE_VERSION=$(go_base_version "${REPO}/Dockerfile") IPFS_VERSION=v0.17.0 TMP_CONTEXT=$(mktemp -d) function cleanup { local ORG_EXIT_CODE="${1}" rm -rf "${TMP_CONTEXT}" || true exit "${ORG_EXIT_CODE}" } trap 'cleanup "$?"' EXIT SIGHUP SIGINT SIGQUIT SIGTERM cat < "${TMP_CONTEXT}/Dockerfile" FROM golang:${GOBASE_VERSION} RUN apt-get update -y && apt-get install -y fuse3 && \ wget https://dist.ipfs.io/go-ipfs/${IPFS_VERSION}/go-ipfs_${IPFS_VERSION}_linux-amd64.tar.gz && \ tar -xvzf go-ipfs_${IPFS_VERSION}_linux-amd64.tar.gz && \ cd go-ipfs && \ bash install.sh COPY ./entrypoint.sh /entrypoint.sh ENTRYPOINT ["/entrypoint.sh"] EOF cp "${CONTEXT}/entrypoint.sh" "${TMP_CONTEXT}/entrypoint.sh" docker build --progress=plain -t "${IMAGE_NAME}" ${DOCKER_BUILD_ARGS:-} "${TMP_CONTEXT}" docker run --rm --privileged \ --device /dev/fuse \ --tmpfs /tmp:exec,mode=777 \ -w /go/src/github.com/containerd/stargz-snapshotter/ipfs \ -v "${REPO}:/go/src/github.com/containerd/stargz-snapshotter:ro" \ "${IMAGE_NAME}" go test -v -run TestIPFSClient ./client/... --ipfs-api=http://localhost:5001 stargz-snapshotter-0.14.3/script/k3s-argo-workflow/000077500000000000000000000000001440204344700222655ustar00rootroot00000000000000stargz-snapshotter-0.14.3/script/k3s-argo-workflow/go.yaml.template000066400000000000000000000063041440204344700253730ustar00rootroot00000000000000# Example golang CI based on https://github.com/argoproj/argo-workflows/blob/7dc6515ce1ef76475ac7bd2a7a3c3cdbe795a13c/examples/ci.yaml apiVersion: argoproj.io/v1alpha1 kind: Workflow metadata: generateName: ci-example- spec: # entrypoint is the name of the template used as the starting point of the workflow entrypoint: ci-example arguments: parameters: - name: revision value: 09c3a5e # a temporary volume, named workdir, will be used as a working directory # for this workflow. This volume is passed around from step to step. volumeClaimTemplates: - metadata: name: workdir spec: accessModes: [ "ReadWriteOnce" ] resources: requests: storage: 1Gi templates: - name: ci-example inputs: parameters: - name: revision steps: - - name: golangci-lint template: golangci-lint-example arguments: parameters: - name: revision value: "{{inputs.parameters.revision}}" - - name: gosec template: gosec-example - - name: build template: build-golang-example # the test step expands into three parallel steps running # different operating system images. each mounts the workdir # and runs the compiled binary from the build step. - - name: test template: run-hello arguments: parameters: - name: os-image value: "{{item.image}}:{{item.tag}}" withItems: - { image: 'ghcr.io/stargz-containers/alpine', tag: '3.10.2-${IMAGE_TYPE}' } - { image: 'ghcr.io/stargz-containers/ubuntu', tag: '22.04-${IMAGE_TYPE}' } - { image: 'ghcr.io/stargz-containers/fedora', tag: '30-${IMAGE_TYPE}' } - name: golangci-lint-example inputs: parameters: - name: revision artifacts: - name: code path: /go/src/github.com/golang/example git: repo: https://github.com/golang/example.git revision: "{{inputs.parameters.revision}}" container: image: ghcr.io/stargz-containers/golangci-lint:v1.40.1-${IMAGE_TYPE} command: [sh, -c] args: [" cd /go/src/github.com/golang/example/hello && golangci-lint run ./... "] volumeMounts: - name: workdir mountPath: /go - name: gosec-example container: image: ghcr.io/stargz-containers/gosec:v2.8.0-${IMAGE_TYPE} command: [sh, -c] args: [" cd /go/src/github.com/golang/example/hello && gosec ./... "] volumeMounts: - name: workdir mountPath: /go - name: build-golang-example container: image: ghcr.io/stargz-containers/golang:1.15.3-buster-${IMAGE_TYPE} command: [sh, -c] args: [" cd /go/src/github.com/golang/example/hello && go build -v . "] volumeMounts: - name: workdir mountPath: /go - name: run-hello inputs: parameters: - name: os-image container: image: "{{inputs.parameters.os-image}}" command: [sh, -c] args: [" uname -a ; cat /etc/os-release ; /go/src/github.com/golang/example/hello/hello "] volumeMounts: - name: workdir mountPath: /go stargz-snapshotter-0.14.3/script/k3s-argo-workflow/run.sh000077500000000000000000000134711440204344700234360ustar00rootroot00000000000000#!/bin/bash # Copyright The containerd Authors. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. set -euo pipefail CONTEXT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )/" REPO="${CONTEXT}../../" K3S_VERSION=master K3S_REPO=https://github.com/k3s-io/k3s K3S_CONTAINERD_REPO=https://github.com/k3s-io/containerd K3S_NODE_REPO=ghcr.io/stargz-containers K3S_NODE_IMAGE_NAME=k3s K3S_NODE_TAG=1 K3S_NODE_IMAGE="${K3S_NODE_REPO}/${K3S_NODE_IMAGE_NAME}:${K3S_NODE_TAG}" K3S_CLUSTER_NAME="k3s-demo-cluster-$(date +%s%N | shasum | base64 | fold -w 10 | head -1)" ORG_ARGOYAML=$(mktemp) TMP_K3S_REPO=$(mktemp -d) TMP_GOLANGCI=$(mktemp) TMP_K3S_CONTAINERD_REPO=$(mktemp -d) function cleanup { ORG_EXIT_CODE="${1}" rm "${ORG_ARGOYAML}" || true rm -rf "${TMP_K3S_REPO}" || true rm -rf "${TMP_K3S_CONTAINERD_REPO}" exit "${ORG_EXIT_CODE}" } trap 'cleanup "$?"' EXIT SIGHUP SIGINT SIGQUIT SIGTERM function argo_yaml() { local IMAGE_TYPE="${1}" local TMP_CUSTOM_ARGOYAML=$(mktemp) cp "${ORG_ARGOYAML}" "${TMP_CUSTOM_ARGOYAML}" sed -i 's|containerRuntimeExecutor: docker|containerRuntimeExecutor: pns|g' "${TMP_CUSTOM_ARGOYAML}" cat "${TMP_CUSTOM_ARGOYAML}" rm "${TMP_CUSTOM_ARGOYAML}" } function replace_image() { local TARGET_FILE="${1}" local IMAGE_ORG="${2}" local IMAGE_NEW="${3}" if ! cat "${TARGET_FILE}" | grep "${IMAGE_ORG}" > /dev/null 2>&1 ; then echo "error: image ${IMAGE_ORG} not specified" 1>&2 cat "${TARGET_FILE}" exit 1 fi sed -i "s|${IMAGE_ORG}|${IMAGE_NEW}|g" "${TARGET_FILE}" } function go_ci_yaml() { IMAGE_TYPE="${1}" envsubst < "${CONTEXT}/go.yaml.template" } function run { local IMAGE_TYPE="${1}" local SNAPSHOTTER="${2}" local ELAPSED_RESULT_FILE="${3}" # Prepare cluster configuration local CUSTOM_ARGOYAML=$(mktemp) argo_yaml "${IMAGE_TYPE}" > "${CUSTOM_ARGOYAML}" local TMP_GOCI_YAML=$(mktemp) go_ci_yaml "${IMAGE_TYPE}" > "${TMP_GOCI_YAML}" # Create argo cluster k3d cluster create "${K3S_CLUSTER_NAME}" --image="${K3S_NODE_IMAGE}" \ --k3s-arg='--snapshotter='"${SNAPSHOTTER}"'@server:*;agent:*' kubectl create ns argo kubectl apply -n argo -f "${CUSTOM_ARGOYAML}" # Wait for the cluster is ready local RETRYNUM=30 local RETRYINTERVAL=1 local TIMEOUTSEC=180 for i in $(seq ${RETRYNUM}) ; do if [ $(kubectl get -n argo pods -o json | jq -r '.items[]' | wc -l) -ne 0 ] ; then if [ $(kubectl get -n argo pods -o json | jq '.items[] | select(.status.phase != "Running" and .status.phase != "Succeeded")' | wc -l) -eq 0 ] then echo "argo is ready" break fi fi echo "Waiting for argo is ready..." sleep ${RETRYINTERVAL} done # Run the workflow and get the elapsed time argo submit -n argo --watch "${TMP_GOCI_YAML}" local START=$(argo list -n argo --completed -o json | jq -r '.[0].status.startedAt') local FINISH=$(argo list -n argo --completed -o json | jq -r '.[0].status.finishedAt') local ELAPSED=$(expr $(date --date "${FINISH}" +%s) - $(date --date "${START}" +%s)) echo '{"type" : "'"${IMAGE_TYPE}"'", "snapshotter" : "'"${SNAPSHOTTER}"'", "elapsed" : "'"${ELAPSED}"'"}' | tee -a "${ELAPSED_RESULT_FILE}" # Finalize k3d cluster delete "${K3S_CLUSTER_NAME}" rm "${CUSTOM_ARGOYAML}" rm "${TMP_GOCI_YAML}" } RESULT_FILE="${RESULT:-}" if [ "${RESULT_FILE}" == "" ] ; then RESULT_FILE=$(mktemp) fi echo "result to ${RESULT_FILE}" wget -O "${ORG_ARGOYAML}" https://raw.githubusercontent.com/argoproj/argo-workflows/v3.4.3/manifests/quick-start-minimal.yaml git clone -b ${K3S_VERSION} --depth 1 "${K3S_REPO}" "${TMP_K3S_REPO}" sed -i "s|github.com/k3s-io/stargz-snapshotter .*$|$(realpath ${REPO})|g" "${TMP_K3S_REPO}/go.mod" echo "replace github.com/containerd/stargz-snapshotter/estargz => $(realpath ${REPO})/estargz" >> "${TMP_K3S_REPO}/go.mod" # typeurl version stargz-snapshotter indirectly depends on is incompatible to the one github.com/k3s-io/containerd depends on. # We use older version of typeurl which the both of the above are compatible to. # We can remove this directive once k3s upgrades typeurl version to newer than v1.0.3-0.20220324183432-6193a0e03259. echo "replace github.com/containerd/typeurl => github.com/containerd/typeurl v1.0.2" >> "${TMP_K3S_REPO}/go.mod" cat "${TMP_K3S_REPO}/go.mod" sed -i -E 's|(ENV DAPPER_RUN_ARGS .*)|\1 -v '"$(realpath ${REPO})":"$(realpath ${REPO})"':ro|g' "${TMP_K3S_REPO}/Dockerfile.dapper" sed -i -E 's|(ENV DAPPER_ENV .*)|\1 DOCKER_BUILDKIT|g' "${TMP_K3S_REPO}/Dockerfile.dapper" ( cd "${TMP_K3S_REPO}" && \ git config user.email "dummy@example.com" && \ git config user.name "dummy" && \ cat ./.golangci.json | jq '.run.deadline|="10m"' > "${TMP_GOLANGCI}" && \ cp "${TMP_GOLANGCI}" ./.golangci.json && \ go mod tidy && \ make deps && \ git add . && \ git commit -m tmp && \ REPO="${K3S_NODE_REPO}" IMAGE_NAME="${K3S_NODE_IMAGE_NAME}" TAG="${K3S_NODE_TAG}" SKIP_VALIDATE=1 make ) #1 run "org" "overlayfs" "${RESULT_FILE}" run "esgz" "stargz" "${RESULT_FILE}" #2 run "org" "overlayfs" "${RESULT_FILE}" run "esgz" "stargz" "${RESULT_FILE}" #3 run "org" "overlayfs" "${RESULT_FILE}" run "esgz" "stargz" "${RESULT_FILE}" stargz-snapshotter-0.14.3/script/k3s/000077500000000000000000000000001440204344700174675ustar00rootroot00000000000000stargz-snapshotter-0.14.3/script/k3s/create-pod.sh000077500000000000000000000070741440204344700220610ustar00rootroot00000000000000#!/bin/bash # Copyright The containerd Authors. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. set -euo pipefail REMOTE_SNAPSHOT_LABEL="containerd.io/snapshot/remote" TEST_POD_NAME=testpod-$(head /dev/urandom | tr -dc a-z0-9 | head -c 10) TEST_POD_NS=ns1 TEST_CONTAINER_NAME=testcontainer-$(head /dev/urandom | tr -dc a-z0-9 | head -c 10) K3S_NODENAME="${1}" K3S_KUBECONFIG="${2}" TESTIMAGE="${3}" echo "Creating testing pod...." cat < 100" exit 1 fi ((LAYERSNUM+=1)) LABEL=$(docker exec -i "${K3S_NODENAME}" ctr --namespace="k8s.io" \ snapshots --snapshotter=stargz info "${LAYER}" \ | jq -r ".Labels.\"${REMOTE_SNAPSHOT_LABEL}\"") echo "Checking layer ${LAYER} : ${LABEL}" if [ "${LABEL}" == "null" ] ; then echo "layer ${LAYER} isn't remote snapshot" exit 1 fi done if [ ${LAYERSNUM} -eq 0 ] ; then echo "cannot get layers" exit 1 fi exit 0 stargz-snapshotter-0.14.3/script/k3s/mirror.sh000066400000000000000000000026321440204344700213400ustar00rootroot00000000000000#!/bin/bash # Copyright The containerd Authors. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. set -euo pipefail SRC="${1}" DST="${2}" SS_REPO="/go/src/github.com/containerd/stargz-snapshotter" RETRYNUM=30 RETRYINTERVAL=1 TIMEOUTSEC=180 function retry { local SUCCESS=false for i in $(seq ${RETRYNUM}) ; do if eval "timeout ${TIMEOUTSEC} ${@}" ; then SUCCESS=true break fi echo "Fail(${i}). Retrying..." sleep ${RETRYINTERVAL} done if [ "${SUCCESS}" == "true" ] ; then return 0 else return 1 fi } update-ca-certificates git config --global --add safe.directory "${SS_REPO}" cd "${SS_REPO}" PREFIX=/out/ make ctr-remote containerd & retry /out/ctr-remote version /out/ctr-remote images pull "${SRC}" /out/ctr-remote images optimize --oci "${SRC}" "${DST}" /out/ctr-remote images push -u "${REGISTRY_CREDS}" "${DST}" stargz-snapshotter-0.14.3/script/k3s/run-k3s.sh000077500000000000000000000077111440204344700213360ustar00rootroot00000000000000#!/bin/bash # Copyright The containerd Authors. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. set -euo pipefail K3S_VERSION=master K3S_REPO=https://github.com/k3s-io/k3s K3S_CONTAINERD_REPO=https://github.com/k3s-io/containerd REGISTRY_HOST=k3s-private-registry K3S_NODE_REPO=ghcr.io/stargz-containers K3S_NODE_IMAGE_NAME=k3s K3S_NODE_TAG=1 K3S_NODE_IMAGE="${K3S_NODE_REPO}/${K3S_NODE_IMAGE_NAME}:${K3S_NODE_TAG}" # Arguments K3S_CLUSTER_NAME="${1}" K3S_USER_KUBECONFIG="${2}" K3S_REGISTRY_CA="${3}" REPO="${4}" REGISTRY_NETWORK="${5}" DOCKERCONFIGJSON_DATA="${6}" TMP_BUILTIN_CONF=$(mktemp) TMP_CONTEXT=$(mktemp -d) SN_KUBECONFIG=$(mktemp) TMP_K3S_REPO=$(mktemp -d) TMP_K3S_CONTAINERD_REPO=$(mktemp -d) TMP_GOLANGCI=$(mktemp) function cleanup { local ORG_EXIT_CODE="${1}" rm "${SN_KUBECONFIG}" rm -rf "${TMP_CONTEXT}" rm -rf "${TMP_BUILTIN_CONF}" rm -rf "${TMP_K3S_REPO}" rm -rf "${TMP_K3S_CONTAINERD_REPO}" rm "${TMP_GOLANGCI}" exit "${ORG_EXIT_CODE}" } trap 'cleanup "$?"' EXIT SIGHUP SIGINT SIGQUIT SIGTERM echo "Preparing node image..." git clone -b ${K3S_VERSION} --depth 1 "${K3S_REPO}" "${TMP_K3S_REPO}" sed -i "s|github.com/k3s-io/stargz-snapshotter .*$|$(realpath ${REPO})|g" "${TMP_K3S_REPO}/go.mod" echo "replace github.com/containerd/stargz-snapshotter/estargz => $(realpath ${REPO})/estargz" >> "${TMP_K3S_REPO}/go.mod" # typeurl version stargz-snapshotter indirectly depends on is incompatible to the one github.com/k3s-io/containerd depends on. # We use older version of typeurl which the both of the above are compatible to. # We can remove this directive once k3s upgrades typeurl version to newer than v1.0.3-0.20220324183432-6193a0e03259. echo "replace github.com/containerd/typeurl => github.com/containerd/typeurl v1.0.2" >> "${TMP_K3S_REPO}/go.mod" cat "${TMP_K3S_REPO}/go.mod" sed -i -E 's|(ENV DAPPER_RUN_ARGS .*)|\1 -v '"$(realpath ${REPO})":"$(realpath ${REPO})"':ro|g' "${TMP_K3S_REPO}/Dockerfile.dapper" sed -i -E 's|(ENV DAPPER_ENV .*)|\1 DOCKER_BUILDKIT|g' "${TMP_K3S_REPO}/Dockerfile.dapper" ( cd "${TMP_K3S_REPO}" && \ git config user.email "dummy@example.com" && \ git config user.name "dummy" && \ cat ./.golangci.json | jq '.run.deadline|="10m"' > "${TMP_GOLANGCI}" && \ cp "${TMP_GOLANGCI}" ./.golangci.json && \ go mod tidy && \ make deps && \ git add . && \ git commit -m tmp && \ REPO="${K3S_NODE_REPO}" IMAGE_NAME="${K3S_NODE_IMAGE_NAME}" TAG="${K3S_NODE_TAG}" SKIP_VALIDATE=1 make ) cat < "${TMP_BUILTIN_CONF}" configs: ${REGISTRY_HOST}:5000: tls: ca_file: /registry.crt EOF echo "Createing k3s cluster" k3d cluster create "${K3S_CLUSTER_NAME}" --image="${K3S_NODE_IMAGE}" \ --registry-config="${TMP_BUILTIN_CONF}" -v "${K3S_REGISTRY_CA}":/registry.crt:ro \ --k3s-arg='--snapshotter=stargz@server:*;agent:*' k3d kubeconfig get "${K3S_CLUSTER_NAME}" > "${K3S_USER_KUBECONFIG}" K3S_NODENAME="$(k3d node list | grep ${K3S_CLUSTER_NAME}-server-0 | cut -d " " -f 1 | tr -d '\n')" docker network connect "${REGISTRY_NETWORK}" "${K3S_NODENAME}" echo "Configuring kubernetes cluster..." CONFIGJSON_BASE64="$(cat ${DOCKERCONFIGJSON_DATA} | base64 -i -w 0)" cat </dev/null 2>&1 && pwd )/" REPO="${CONTEXT}../../" REGISTRY_HOST=k3s-private-registry REGISTRY_NETWORK=k3s_registry_network DUMMYUSER=dummyuser DUMMYPASS=dummypass TESTIMAGE_ORIGIN="ghcr.io/stargz-containers/ubuntu:22.04" TESTIMAGE="${REGISTRY_HOST}:5000/library/ubuntu:22.04" K3S_CLUSTER_NAME=k3s-stargz-snapshotter PREPARE_NODE_NAME="cri-prepare-node" PREPARE_NODE_IMAGE="cri-prepare-image" source "${REPO}/script/util/utils.sh" if [ "${K3S_NO_RECREATE:-}" != "true" ] ; then echo "Preparing preparation node image..." docker build ${DOCKER_BUILD_ARGS:-} -t "${PREPARE_NODE_IMAGE}" --target containerd-base "${REPO}" fi AUTH_DIR=$(mktemp -d) DOCKERCONFIG=$(mktemp) DOCKER_COMPOSE_YAML=$(mktemp) K3S_KUBECONFIG=$(mktemp) MIRROR_TMP=$(mktemp -d) function cleanup { local ORG_EXIT_CODE="${1}" rm -rf "${AUTH_DIR}" || true rm "${DOCKER_COMPOSE_YAML}" || true rm "${DOCKERCONFIG}" || true rm "${K3S_KUBECONFIG}" || true rm -rf "${MIRROR_TMP}" || true exit "${ORG_EXIT_CODE}" } trap 'cleanup "$?"' EXIT SIGHUP SIGINT SIGQUIT SIGTERM echo "Preparing creds..." prepare_creds "${AUTH_DIR}" "${REGISTRY_HOST}" "${DUMMYUSER}" "${DUMMYPASS}" echo -n '{"auths":{"'"${REGISTRY_HOST}"':5000":{"auth":"'$(echo -n "${DUMMYUSER}:${DUMMYPASS}" | base64 -i -w 0)'"}}}' > "${DOCKERCONFIG}" echo "Preparing private registry..." cat < "${DOCKER_COMPOSE_YAML}" version: "3.5" services: testenv_registry: image: registry:2 container_name: ${REGISTRY_HOST} environment: - HTTP_PROXY=${HTTP_PROXY:-} - HTTPS_PROXY=${HTTPS_PROXY:-} - http_proxy=${http_proxy:-} - https_proxy=${https_proxy:-} - REGISTRY_AUTH=htpasswd - REGISTRY_AUTH_HTPASSWD_REALM="Registry Realm" - REGISTRY_AUTH_HTPASSWD_PATH=/auth/auth/htpasswd - REGISTRY_HTTP_TLS_CERTIFICATE=/auth/certs/domain.crt - REGISTRY_HTTP_TLS_KEY=/auth/certs/domain.key volumes: - ${AUTH_DIR}:/auth image-prepare: image: "${PREPARE_NODE_IMAGE}" container_name: "${PREPARE_NODE_NAME}" privileged: true entrypoint: - sleep - infinity tmpfs: - /tmp:exec,mode=777 environment: - REGISTRY_CREDS=${DUMMYUSER}:${DUMMYPASS} volumes: - "k3s-prepare-containerd-data:/var/lib/containerd" - "k3s-prepare-containerd-stargz-grpc-data:/var/lib/containerd-stargz-grpc" - "${AUTH_DIR}/certs/domain.crt:/usr/local/share/ca-certificates/rgst.crt:ro" - "${REPO}:/go/src/github.com/containerd/stargz-snapshotter:ro" - "${MIRROR_TMP}:/tools/" volumes: k3s-prepare-containerd-data: k3s-prepare-containerd-stargz-grpc-data: networks: default: external: name: ${REGISTRY_NETWORK} EOF cp "${REPO}/script/k3s/mirror.sh" "${MIRROR_TMP}/mirror.sh" if ! ( cd "${CONTEXT}" && \ docker network create "${REGISTRY_NETWORK}" && \ docker-compose -f "${DOCKER_COMPOSE_YAML}" up -d --force-recreate && \ docker exec "${PREPARE_NODE_NAME}" /bin/bash /tools/mirror.sh \ "${TESTIMAGE_ORIGIN}" "${TESTIMAGE}" ) ; then echo "Failed to prepare private registry" docker-compose -f "${DOCKER_COMPOSE_YAML}" down -v docker network rm "${REGISTRY_NETWORK}" exit 1 fi echo "Testing in k3s cluster (kubeconfig: ${K3S_KUBECONFIG})..." FAIL= if ! ( "${CONTEXT}"/run-k3s.sh "${K3S_CLUSTER_NAME}" \ "${K3S_KUBECONFIG}" \ "${AUTH_DIR}/certs/domain.crt" \ "${REPO}" \ "${REGISTRY_NETWORK}" \ "${DOCKERCONFIG}" && \ echo "Waiting until secrets fullly synced..." && \ sleep 30 && \ echo "Trying to pull private image with secret..." && \ "${CONTEXT}"/create-pod.sh "$(k3d node list | grep ${K3S_CLUSTER_NAME}-server-0 | cut -d " " -f 1 | tr -d '\n')" \ "${K3S_KUBECONFIG}" "${TESTIMAGE}" ) ; then FAIL=true fi docker-compose -f "${DOCKER_COMPOSE_YAML}" down -v k3d cluster delete "${K3S_CLUSTER_NAME}" docker network rm "${REGISTRY_NETWORK}" if [ "${FAIL}" == "true" ] ; then exit 1 fi exit 0 stargz-snapshotter-0.14.3/script/kind/000077500000000000000000000000001440204344700177145ustar00rootroot00000000000000stargz-snapshotter-0.14.3/script/kind/create-pod.sh000077500000000000000000000071511440204344700223020ustar00rootroot00000000000000#!/bin/bash # Copyright The containerd Authors. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. set -euo pipefail REMOTE_SNAPSHOT_LABEL="containerd.io/snapshot/remote" TEST_POD_NAME=testpod-$(head /dev/urandom | tr -dc a-z0-9 | head -c 10) TEST_POD_NS=ns1 TEST_CONTAINER_NAME=testcontainer-$(head /dev/urandom | tr -dc a-z0-9 | head -c 10) KIND_NODENAME="${1}" KIND_KUBECONFIG="${2}" TESTIMAGE="${3}" echo "Creating testing pod...." cat < 100" exit 1 fi ((LAYERSNUM+=1)) LABEL=$(docker exec -i "${KIND_NODENAME}" ctr-remote --namespace="k8s.io" \ snapshots --snapshotter=stargz info "${LAYER}" \ | jq -r ".Labels.\"${REMOTE_SNAPSHOT_LABEL}\"") echo "Checking layer ${LAYER} : ${LABEL}" if [ "${LABEL}" == "null" ] ; then echo "layer ${LAYER} isn't remote snapshot" exit 1 fi done if [ ${LAYERSNUM} -eq 0 ] ; then echo "cannot get layers" exit 1 fi exit 0 stargz-snapshotter-0.14.3/script/kind/mirror.sh000066400000000000000000000026321440204344700215650ustar00rootroot00000000000000#!/bin/bash # Copyright The containerd Authors. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. set -euo pipefail SRC="${1}" DST="${2}" SS_REPO="/go/src/github.com/containerd/stargz-snapshotter" RETRYNUM=30 RETRYINTERVAL=1 TIMEOUTSEC=180 function retry { local SUCCESS=false for i in $(seq ${RETRYNUM}) ; do if eval "timeout ${TIMEOUTSEC} ${@}" ; then SUCCESS=true break fi echo "Fail(${i}). Retrying..." sleep ${RETRYINTERVAL} done if [ "${SUCCESS}" == "true" ] ; then return 0 else return 1 fi } update-ca-certificates git config --global --add safe.directory "${SS_REPO}" cd "${SS_REPO}" PREFIX=/out/ make ctr-remote containerd & retry /out/ctr-remote version /out/ctr-remote images pull "${SRC}" /out/ctr-remote images optimize --oci "${SRC}" "${DST}" /out/ctr-remote images push -u "${REGISTRY_CREDS}" "${DST}" stargz-snapshotter-0.14.3/script/kind/run-kind.sh000077500000000000000000000147321440204344700220110ustar00rootroot00000000000000#!/bin/bash # Copyright The containerd Authors. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. set -euo pipefail NODE_IMAGE_NAME="stargz-snapshotter-node:1" NODE_BASE_IMAGE_NAME="stargz-snapshotter-node-base:1" NODE_TEST_CERT_FILE="/usr/local/share/ca-certificates/registry.crt" SNAPSHOTTER_KUBECONFIG_PATH=/etc/kubernetes/snapshotter/config.conf REGISTRY_HOST=kind-private-registry # Arguments KIND_CLUSTER_NAME="${1}" KIND_USER_KUBECONFIG="${2}" KIND_REGISTRY_CA="${3}" REPO="${4}" REGISTRY_NETWORK="${5}" DOCKERCONFIGJSON_DATA="${6}" TMP_BUILTIN_CONF=$(mktemp) TMP_CONTEXT=$(mktemp -d) SN_KUBECONFIG=$(mktemp) function cleanup { local ORG_EXIT_CODE="${1}" rm "${SN_KUBECONFIG}" rm -rf "${TMP_CONTEXT}" rm -rf "${TMP_BUILTIN_CONF}" exit "${ORG_EXIT_CODE}" } trap 'cleanup "$?"' EXIT SIGHUP SIGINT SIGQUIT SIGTERM if [ "${KIND_NO_RECREATE:-}" != "true" ] ; then echo "Preparing node image..." TARGET_STAGE= if [ "${BUILTIN_SNAPSHOTTER:-}" == "true" ] ; then TARGET_STAGE="--target kind-builtin-snapshotter" fi docker build ${DOCKER_BUILD_ARGS:-} -t "${NODE_BASE_IMAGE_NAME}" ${TARGET_STAGE} "${REPO}" fi # Prepare the testing node with enabling k8s keychain cat <<'EOF' > "${TMP_CONTEXT}/config.stargz.overwrite.toml" [kubeconfig_keychain] enable_keychain = true kubeconfig_path = "/etc/kubernetes/snapshotter/config.conf" EOF cat < "${TMP_CONTEXT}/config.containerd.append.toml" [plugins."io.containerd.grpc.v1.cri".registry.configs."${REGISTRY_HOST}:5000".tls] ca_file = "${NODE_TEST_CERT_FILE}" EOF echo "KUBELET_EXTRA_ARGS=--fail-swap-on=false" > "${TMP_CONTEXT}/kubelet" BUILTIN_HACK_INST= if [ "${BUILTIN_SNAPSHOTTER:-}" == "true" ] ; then # Special configuration for CRI containerd + builtin stargz snapshotter cat < "${TMP_CONTEXT}/containerd.hack.toml" version = 2 [debug] format = "json" level = "debug" [plugins."io.containerd.grpc.v1.cri".containerd] default_runtime_name = "runc" snapshotter = "stargz" disable_snapshot_annotations = false [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc] runtime_type = "io.containerd.runc.v2" [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.test-handler] runtime_type = "io.containerd.runc.v2" [plugins."io.containerd.grpc.v1.cri".registry.configs."${REGISTRY_HOST}:5000".tls] ca_file = "${NODE_TEST_CERT_FILE}" [plugins."io.containerd.snapshotter.v1.stargz".kubeconfig_keychain] enable_keychain = true kubeconfig_path = "/etc/kubernetes/snapshotter/config.conf" [plugins."io.containerd.snapshotter.v1.stargz".registry.configs."${REGISTRY_HOST}:5000".tls] ca_file = "${NODE_TEST_CERT_FILE}" EOF BUILTIN_HACK_INST="COPY containerd.hack.toml /etc/containerd/config.toml" fi cp "${KIND_REGISTRY_CA}" "${TMP_CONTEXT}/registry.crt" cat < "${TMP_CONTEXT}/Dockerfile" FROM ${NODE_BASE_IMAGE_NAME} COPY registry.crt "${NODE_TEST_CERT_FILE}" COPY ./config.stargz.overwrite.toml ./config.containerd.append.toml /tmp/ COPY kubelet /etc/default/kubelet RUN cat /tmp/config.stargz.overwrite.toml > /etc/containerd-stargz-grpc/config.toml && \ cat /tmp/config.containerd.append.toml >> /etc/containerd/config.toml && \ update-ca-certificates ${BUILTIN_HACK_INST} EOF docker build -t "${NODE_IMAGE_NAME}" ${DOCKER_BUILD_ARGS:-} "${TMP_CONTEXT}" # cluster must be single node echo "Cleating kind cluster and connecting to the registry network..." kind create cluster --name "${KIND_CLUSTER_NAME}" \ --kubeconfig "${KIND_USER_KUBECONFIG}" \ --image "${NODE_IMAGE_NAME}" KIND_NODENAME=$(kind get nodes --name "${KIND_CLUSTER_NAME}" | sed -n 1p) # must be single node docker network connect "${REGISTRY_NETWORK}" "${KIND_NODENAME}" echo "===== VERSION INFORMATION =====" docker exec "${KIND_NODENAME}" containerd --version docker exec "${KIND_NODENAME}" runc --version echo "===============================" echo "Configuring kubernetes cluster..." CONFIGJSON_BASE64="$(cat ${DOCKERCONFIGJSON_DATA} | base64 -i -w 0)" cat < "${SN_KUBECONFIG}" apiVersion: v1 kind: Config clusters: - name: default-cluster cluster: certificate-authority-data: ${CA} server: https://${KIND_NODENAME}:${APISERVER_PORT} contexts: - name: default-context context: cluster: default-cluster namespace: default user: default-user current-context: default-context users: - name: default-user user: token: ${TOKEN} EOF docker exec -i "${KIND_NODENAME}" mkdir -p $(dirname "${SNAPSHOTTER_KUBECONFIG_PATH}") docker cp "${SN_KUBECONFIG}" "${KIND_NODENAME}:${SNAPSHOTTER_KUBECONFIG_PATH}" stargz-snapshotter-0.14.3/script/kind/test.sh000077500000000000000000000112161440204344700212330ustar00rootroot00000000000000#!/bin/bash # Copyright The containerd Authors. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. set -euo pipefail CONTEXT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )/" REPO="${CONTEXT}../../" REGISTRY_HOST=kind-private-registry REGISTRY_NETWORK=kind_registry_network DUMMYUSER=dummyuser DUMMYPASS=dummypass TESTIMAGE_ORIGIN="ghcr.io/stargz-containers/ubuntu:22.04" TESTIMAGE="${REGISTRY_HOST}:5000/library/ubuntu:22.04" KIND_CLUSTER_NAME=kind-stargz-snapshotter PREPARE_NODE_NAME="cri-prepare-node" PREPARE_NODE_IMAGE="cri-prepare-image" source "${REPO}/script/util/utils.sh" if [ "${KIND_NO_RECREATE:-}" != "true" ] ; then echo "Preparing preparation node image..." docker build ${DOCKER_BUILD_ARGS:-} -t "${PREPARE_NODE_IMAGE}" --target containerd-base "${REPO}" fi AUTH_DIR=$(mktemp -d) DOCKERCONFIG=$(mktemp) DOCKER_COMPOSE_YAML=$(mktemp) KIND_KUBECONFIG=$(mktemp) MIRROR_TMP=$(mktemp -d) function cleanup { local ORG_EXIT_CODE="${1}" rm -rf "${AUTH_DIR}" || true rm "${DOCKER_COMPOSE_YAML}" || true rm "${DOCKERCONFIG}" || true rm "${KIND_KUBECONFIG}" || true rm -rf "${MIRROR_TMP}" || true exit "${ORG_EXIT_CODE}" } trap 'cleanup "$?"' EXIT SIGHUP SIGINT SIGQUIT SIGTERM echo "Preparing creds..." prepare_creds "${AUTH_DIR}" "${REGISTRY_HOST}" "${DUMMYUSER}" "${DUMMYPASS}" echo -n '{"auths":{"'"${REGISTRY_HOST}"':5000":{"auth":"'$(echo -n "${DUMMYUSER}:${DUMMYPASS}" | base64 -i -w 0)'"}}}' > "${DOCKERCONFIG}" echo "Preparing private registry..." cat < "${DOCKER_COMPOSE_YAML}" version: "3.5" services: testenv_registry: image: registry:2 container_name: ${REGISTRY_HOST} environment: - HTTP_PROXY=${HTTP_PROXY:-} - HTTPS_PROXY=${HTTPS_PROXY:-} - http_proxy=${http_proxy:-} - https_proxy=${https_proxy:-} - REGISTRY_AUTH=htpasswd - REGISTRY_AUTH_HTPASSWD_REALM="Registry Realm" - REGISTRY_AUTH_HTPASSWD_PATH=/auth/auth/htpasswd - REGISTRY_HTTP_TLS_CERTIFICATE=/auth/certs/domain.crt - REGISTRY_HTTP_TLS_KEY=/auth/certs/domain.key volumes: - ${AUTH_DIR}:/auth image-prepare: image: "${PREPARE_NODE_IMAGE}" container_name: "${PREPARE_NODE_NAME}" privileged: true entrypoint: - sleep - infinity tmpfs: - /tmp:exec,mode=777 environment: - REGISTRY_CREDS=${DUMMYUSER}:${DUMMYPASS} volumes: - "kind-prepare-containerd-data:/var/lib/containerd" - "kind-prepare-containerd-stargz-grpc-data:/var/lib/containerd-stargz-grpc" - "${AUTH_DIR}/certs/domain.crt:/usr/local/share/ca-certificates/rgst.crt:ro" - "${REPO}:/go/src/github.com/containerd/stargz-snapshotter:ro" - "${MIRROR_TMP}:/tools/" volumes: kind-prepare-containerd-data: kind-prepare-containerd-stargz-grpc-data: networks: default: external: name: ${REGISTRY_NETWORK} EOF cp "${REPO}/script/kind/mirror.sh" "${MIRROR_TMP}/mirror.sh" if ! ( cd "${CONTEXT}" && \ docker network create "${REGISTRY_NETWORK}" && \ docker-compose -f "${DOCKER_COMPOSE_YAML}" up -d --force-recreate && \ docker exec "${PREPARE_NODE_NAME}" /bin/bash /tools/mirror.sh \ "${TESTIMAGE_ORIGIN}" "${TESTIMAGE}" ) ; then echo "Failed to prepare private registry" docker-compose -f "${DOCKER_COMPOSE_YAML}" down -v docker network rm "${REGISTRY_NETWORK}" exit 1 fi echo "Testing in kind cluster (kubeconfig: ${KIND_KUBECONFIG})..." FAIL= if ! ( "${CONTEXT}"/run-kind.sh "${KIND_CLUSTER_NAME}" \ "${KIND_KUBECONFIG}" \ "${AUTH_DIR}/certs/domain.crt" \ "${REPO}" \ "${REGISTRY_NETWORK}" \ "${DOCKERCONFIG}" && \ echo "Waiting until secrets fullly synced..." && \ sleep 30 && \ echo "Trying to pull private image with secret..." && \ "${CONTEXT}"/create-pod.sh "$(kind get nodes --name "${KIND_CLUSTER_NAME}" | sed -n 1p)" \ "${KIND_KUBECONFIG}" "${TESTIMAGE}" ) ; then FAIL=true fi docker-compose -f "${DOCKER_COMPOSE_YAML}" down -v kind delete cluster --name "${KIND_CLUSTER_NAME}" docker network rm "${REGISTRY_NETWORK}" if [ "${FAIL}" == "true" ] ; then exit 1 fi exit 0 stargz-snapshotter-0.14.3/script/optimize/000077500000000000000000000000001440204344700206275ustar00rootroot00000000000000stargz-snapshotter-0.14.3/script/optimize/optimize/000077500000000000000000000000001440204344700224675ustar00rootroot00000000000000stargz-snapshotter-0.14.3/script/optimize/optimize/entrypoint.sh000077500000000000000000000252571440204344700252540ustar00rootroot00000000000000#!/bin/bash # Copyright The containerd Authors. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. set -euo pipefail REGISTRY_HOST=registry-optimize.test DUMMYUSER=dummyuser DUMMYPASS=dummypass ORG_IMAGE_TAG="${REGISTRY_HOST}/test/test:org$(date '+%M%S')" OPT_IMAGE_TAG="${REGISTRY_HOST}/test/test:opt$(date '+%M%S')" NOOPT_IMAGE_TAG="${REGISTRY_HOST}/test/test:noopt$(date '+%M%S')" TOC_JSON_DIGEST_ANNOTATION="containerd.io/snapshot/stargz/toc.digest" UNCOMPRESSED_SIZE_ANNOTATION="io.containers.estargz.uncompressed-size" REMOTE_SNAPSHOTTER_SOCKET=/run/containerd-stargz-grpc/containerd-stargz-grpc.sock ## Image for doing network-related tests # # FROM ubuntu:22.04 # RUN apt-get update && apt-get install -y curl iproute2 # NETWORK_MOUNT_TEST_ORG_IMAGE_TAG="ghcr.io/stargz-containers/ubuntu:22.04-curl-ip" ######################################## RETRYNUM=100 RETRYINTERVAL=1 TIMEOUTSEC=180 function retry { local SUCCESS=false for i in $(seq ${RETRYNUM}) ; do if eval "timeout ${TIMEOUTSEC} ${@}" ; then SUCCESS=true break fi echo "Fail(${i}). Retrying..." sleep ${RETRYINTERVAL} done if [ "${SUCCESS}" == "true" ] ; then return 0 else return 1 fi } function prepare_context { local CONTEXT_DIR="${1}" cat < "${CONTEXT_DIR}/Dockerfile" FROM scratch COPY ./a.txt ./b.txt accessor / COPY ./c.txt ./d.txt / COPY ./e.txt / ENTRYPOINT ["/accessor"] EOF for SAMPLE in "a" "b" "c" "d" "e" ; do echo "${SAMPLE}" > "${CONTEXT_DIR}/${SAMPLE}.txt" done mkdir -p "${GOPATH}/src/test/test" && \ cat <<'EOF' > "${GOPATH}/src/test/test/main.go" package main import ( "os" ) func main() { targets := []string{"/a.txt", "/c.txt"} for _, t := range targets { f, err := os.Open(t) if err != nil { panic("failed to open file") } f.Close() } } EOF GO111MODULE=off go build -ldflags '-extldflags "-static"' -o "${CONTEXT_DIR}/accessor" "${GOPATH}/src/test/test" } function validate_toc_json { local MANIFEST=${1} local LAYER_NUM=${2} TOCJSON_ANNOTATION="$(cat ${MANIFEST} | jq -r '.layers['"${LAYER_NUM}"'].annotations."'${TOC_JSON_DIGEST_ANNOTATION}'"')" LAYER_DIGEST="$(cat ${MANIFEST} | jq -r '.layers['"${LAYER_NUM}"'].digest')" TOCJSON_DIGEST="$(/tmp/out/ctr-remote ${GETTOCDIGEST_COMMAND} ${LAYER_DIGEST})" if [ "${TOCJSON_ANNOTATION}" != "${TOCJSON_DIGEST}" ] ; then echo "Invalid TOC JSON (layer:${LAYER_NUM}): want ${TOCJSON_ANNOTATION}; got: ${TOCJSON_DIGEST}" return 1 fi echo "Valid TOC JSON (layer:${LAYER_NUM}) ${TOCJSON_ANNOTATION} == ${TOCJSON_DIGEST}" return 0 } function check_uncompressed_size { local MANIFEST=${1} local LAYER_NUM=${2} local LAYER_TAR=${3} SIZE_ANNOTATION="$(cat ${MANIFEST} | jq -r '.layers['"${LAYER_NUM}"'].annotations."'${UNCOMPRESSED_SIZE_ANNOTATION}'"')" SIZE=$(cat "${LAYER_TAR}" | ${DECOMPRESS_COMMAND} | wc -c) if [ "${SIZE_ANNOTATION}" != "${SIZE}" ] ; then echo "Invalid uncompressed size (layer:${LAYER_NUM}): want ${SIZE_ANNOTATION}; got: ${SIZE}" return 1 fi echo "Valid uncompressed size (layer:${LAYER_NUM}) ${SIZE_ANNOTATION} == ${SIZE}" return 0 } function check_optimization { local TARGET=${1} LOCAL_WORKING_DIR="${WORKING_DIR}/$(date '+%H%M%S')" mkdir "${LOCAL_WORKING_DIR}" nerdctl pull "${TARGET}" && nerdctl save "${TARGET}" | tar xv -C "${LOCAL_WORKING_DIR}" LAYERS="$(cat "${LOCAL_WORKING_DIR}/manifest.json" | jq -r '.[0].Layers[]')" echo "Checking layers..." GOTNUM=0 for L in ${LAYERS}; do tar --list -f "${LOCAL_WORKING_DIR}/${L}" | tee "${LOCAL_WORKING_DIR}/${GOTNUM}" ((GOTNUM+=1)) done WANTNUM=0 for W in "${@:2}"; do cp "${W}" "${LOCAL_WORKING_DIR}/${WANTNUM}-want" ((WANTNUM+=1)) done if [ "${GOTNUM}" != "${WANTNUM}" ] ; then echo "invalid numbers of layers ${GOTNUM}; want ${WANTNUM}" return 1 fi for ((I=0; I < WANTNUM; I++)) ; do echo "Validating tarball contents of layer ${I}..." diff "${LOCAL_WORKING_DIR}/${I}" "${LOCAL_WORKING_DIR}/${I}-want" done crane manifest "${TARGET}" | tee "${LOCAL_WORKING_DIR}/dist-manifest.json" && echo "" INDEX=0 for L in ${LAYERS}; do echo "Validating TOC JSON digest of layer ${INDEX}..." validate_toc_json "${LOCAL_WORKING_DIR}/dist-manifest.json" "${INDEX}" check_uncompressed_size "${LOCAL_WORKING_DIR}/dist-manifest.json" \ "${INDEX}" \ "${LOCAL_WORKING_DIR}/${L}" ((INDEX+=1)) done return 0 } function append_toc { local TARGET="${1}" if [ "${INVISIBLE_TOC}" != "true" ] ; then echo "stargz.index.json" >> "${TARGET}" fi } echo "===== VERSION INFORMATION =====" containerd --version runc --version echo "===============================" echo "Logging into the registry..." cp /auth/certs/domain.crt /usr/local/share/ca-certificates update-ca-certificates retry nerdctl login -u "${DUMMYUSER}" -p "${DUMMYPASS}" "https://${REGISTRY_HOST}" echo "Running containerd and BuildKit..." buildkitd --oci-cni-binary-dir=/opt/tmp/cni/bin & containerd --log-level debug & retry buildctl du retry nerdctl version echo "Building sample image for testing..." CONTEXT_DIR=$(mktemp -d) prepare_context "${CONTEXT_DIR}" echo "Preparing sample image..." nerdctl build -t "${ORG_IMAGE_TAG}" "${CONTEXT_DIR}" nerdctl push "${ORG_IMAGE_TAG}" echo "Loading original image" nerdctl pull "${NETWORK_MOUNT_TEST_ORG_IMAGE_TAG}" nerdctl pull "${ORG_IMAGE_TAG}" echo "Checking optimized image..." WORKING_DIR=$(mktemp -d) git config --global --add safe.directory '/go/src/github.com/containerd/stargz-snapshotter' PREFIX=/tmp/out/ make clean PREFIX=/tmp/out/ GO_BUILD_FLAGS="-race" make ctr-remote # Check data race /tmp/out/ctr-remote ${OPTIMIZE_COMMAND} -entrypoint='[ "/accessor" ]' "${ORG_IMAGE_TAG}" "${OPT_IMAGE_TAG}" nerdctl push "${OPT_IMAGE_TAG}" || true cat < "${WORKING_DIR}/0-want" accessor a.txt .prefetch.landmark b.txt EOF append_toc "${WORKING_DIR}/0-want" cat < "${WORKING_DIR}/1-want" c.txt .prefetch.landmark d.txt EOF append_toc "${WORKING_DIR}/1-want" cat < "${WORKING_DIR}/2-want" .no.prefetch.landmark e.txt EOF append_toc "${WORKING_DIR}/2-want" check_optimization "${OPT_IMAGE_TAG}" \ "${WORKING_DIR}/0-want" \ "${WORKING_DIR}/1-want" \ "${WORKING_DIR}/2-want" echo "Checking non-optimized image..." /tmp/out/ctr-remote ${NO_OPTIMIZE_COMMAND} "${ORG_IMAGE_TAG}" "${NOOPT_IMAGE_TAG}" nerdctl push "${NOOPT_IMAGE_TAG}" || true cat < "${WORKING_DIR}/0-want" .no.prefetch.landmark a.txt accessor b.txt EOF append_toc "${WORKING_DIR}/0-want" cat < "${WORKING_DIR}/1-want" .no.prefetch.landmark c.txt d.txt EOF append_toc "${WORKING_DIR}/1-want" cat < "${WORKING_DIR}/2-want" .no.prefetch.landmark e.txt EOF append_toc "${WORKING_DIR}/2-want" check_optimization "${NOOPT_IMAGE_TAG}" \ "${WORKING_DIR}/0-want" \ "${WORKING_DIR}/1-want" \ "${WORKING_DIR}/2-want" # Test networking & mounting work # Make bridge plugin manipulate iptables instead of nftables as this test runs # in a Docker container that network is configured with iptables. # c.f. https://github.com/moby/moby/issues/26824 update-alternatives --set iptables /usr/sbin/iptables-legacy # Try to connect to the internet from the container # CNI-related files are installed to irregular paths (see Dockerfile for more details). # Check if these files are recognized through flags. TESTDIR=$(mktemp -d) /tmp/out/ctr-remote ${OPTIMIZE_COMMAND} \ --period=20 \ --cni \ --cni-plugin-conf-dir='/etc/tmp/cni/net.d' \ --cni-plugin-dir='/opt/tmp/cni/bin' \ --add-hosts='testhost:1.2.3.4,test2:5.6.7.8' \ --dns-nameservers='8.8.8.8' \ --mount="type=bind,src=${TESTDIR},dst=/mnt,options=bind" \ --entrypoint='[ "/bin/bash", "-c" ]' \ --args='[ "curl example.com > /mnt/result_page && ip a show dev eth0 ; echo -n $? > /mnt/if_exists && ip a > /mnt/if_info && cat /etc/hosts > /mnt/hosts" ]' \ "${NETWORK_MOUNT_TEST_ORG_IMAGE_TAG}" "${REGISTRY_HOST}/test:1" # Check if all contents are successfuly passed if ! [ -f "${TESTDIR}/if_exists" ] || \ ! [ -f "${TESTDIR}/result_page" ] || \ ! [ -f "${TESTDIR}/if_info" ] || \ ! [ -f "${TESTDIR}/hosts" ]; then echo "the result files not found; bind-mount might not work" exit 1 fi # Check if /etc/hosts contains expected contents if [ "$(cat ${TESTDIR}/hosts | grep testhost | sed -E 's/([0-9.]*).*/\1/')" != "1.2.3.4" ] || \ [ "$(cat ${TESTDIR}/hosts | grep test2 | sed -E 's/([0-9.]*).*/\1/')" != "5.6.7.8" ]; then echo "invalid contents in /etc/hosts" cat "${TESTDIR}/hosts" exit 1 fi echo "hosts configured:" cat "${TESTDIR}/hosts" # Check if the interface is created by the bridge plugin if [ "$(cat ${TESTDIR}/if_exists)" != "0" ] ; then echo "interface didn't configured:" cat "${TESTDIR}/if_exists" echo "interface info:" cat "${TESTDIR}/if_info" exit 1 fi echo "Interface created:" cat "${TESTDIR}/if_info" # Check if the contents are downloaded from the internet SAMPLE_PAGE=$(mktemp) curl example.com > "${SAMPLE_PAGE}" if ! [ -s "${SAMPLE_PAGE}" ] ; then echo "sample page file is empty; failed to get the contents of example.com; check the internet connection" exit 1 fi echo "sample contents of example.com" cat "${SAMPLE_PAGE}" SAMPLE_PAGE_SHA256=$(cat "${SAMPLE_PAGE}" | sha256sum | sed -E 's/([^ ]*).*/sha256:\1/g') RESULT_PAGE_SHA256=$(cat "${TESTDIR}/result_page" | sha256sum | sed -E 's/([^ ]*).*/sha256:\1/g') if [ "${SAMPLE_PAGE_SHA256}" != "${RESULT_PAGE_SHA256}" ] ; then echo "failed to get expected contents from the internet, inside the container: ${SAMPLE_PAGE_SHA256} != ${RESULT_PAGE_SHA256}" echo "got contetns:" cat "${TESTDIR}/result_page" exit 1 fi echo "expected contents successfly downloaded from the internet, in the container. contents:" cat "${TESTDIR}/result_page" exit 0 stargz-snapshotter-0.14.3/script/optimize/test.sh000077500000000000000000000133471440204344700221550ustar00rootroot00000000000000#!/bin/bash # Copyright The containerd Authors. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. set -euo pipefail CONTEXT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )/" REPO="${CONTEXT}../../" REGISTRY_HOST=registry-optimize.test REPO_PATH=/go/src/github.com/containerd/stargz-snapshotter DUMMYUSER=dummyuser DUMMYPASS=dummypass OPTIMIZE_BASE_IMAGE_NAME="optimize-image-base" OPTIMIZE_TEST_IMAGE_NAME="optimize-image-test" source "${REPO}/script/util/utils.sh" CNI_PLUGINS_VERSION=$(get_version_from_arg "${REPO}/Dockerfile" "CNI_PLUGINS_VERSION") NERDCTL_VERSION=$(get_version_from_arg "${REPO}/Dockerfile" "NERDCTL_VERSION") if [ "${OPTIMIZE_NO_RECREATE:-}" != "true" ] ; then echo "Preparing node image..." # Enable to check race docker build ${DOCKER_BUILD_ARGS:-} -t "${OPTIMIZE_BASE_IMAGE_NAME}" \ --target snapshotter-base \ --build-arg=SNAPSHOTTER_BUILD_FLAGS="-race" \ "${REPO}" fi DOCKER_COMPOSE_YAML=$(mktemp) AUTH_DIR=$(mktemp -d) TMP_CONTEXT=$(mktemp -d) function cleanup { local ORG_EXIT_CODE="${1}" rm "${DOCKER_COMPOSE_YAML}" || true rm -rf "${AUTH_DIR}" || true rm -rf "${TMP_CONTEXT}" || true exit "${ORG_EXIT_CODE}" } trap 'cleanup "$?"' EXIT SIGHUP SIGINT SIGQUIT SIGTERM cat <<'EOF' > "${TMP_CONTEXT}/test.conflist" { "cniVersion": "0.4.0", "name": "test", "plugins" : [{ "type": "bridge", "bridge": "test0", "isDefaultGateway": true, "forceAddress": false, "ipMasq": true, "hairpinMode": true, "ipam": { "type": "host-local", "subnet": "10.10.0.0/16" } }, { "type": "loopback" }] } EOF cat < "${TMP_CONTEXT}/Dockerfile" # Legacy builder that doesn't support TARGETARCH should set this explicitly using --build-arg. # If TARGETARCH isn't supported by the builder, the default value is "amd64". FROM ${OPTIMIZE_BASE_IMAGE_NAME} ARG TARGETARCH RUN apt-get update -y && \ apt-get --no-install-recommends install -y jq iptables zstd && \ go install github.com/google/go-containerregistry/cmd/crane@v0.8.0 && \ mkdir -p /opt/tmp/cni/bin /etc/tmp/cni/net.d && \ curl -Ls https://github.com/containernetworking/plugins/releases/download/v${CNI_PLUGINS_VERSION}/cni-plugins-linux-\${TARGETARCH:-amd64}-v${CNI_PLUGINS_VERSION}.tgz | tar xzv -C /opt/tmp/cni/bin && \ curl -sSL https://github.com/containerd/nerdctl/releases/download/v${NERDCTL_VERSION}/nerdctl-full-${NERDCTL_VERSION}-linux-\${TARGETARCH:-amd64}.tar.gz | tar -C /usr/local -zx bin/buildkitd bin/buildctl # Installs CNI-related files to irregular paths (/opt/tmp/cni/bin and /etc/tmp/cni/net.d) for test. # see entrypoint.sh for more details. COPY ./test.conflist /etc/tmp/cni/net.d/test.conflist EOF docker build -t "${OPTIMIZE_TEST_IMAGE_NAME}" ${DOCKER_BUILD_ARGS:-} "${TMP_CONTEXT}" echo "Preparing creds..." prepare_creds "${AUTH_DIR}" "${REGISTRY_HOST}" "${DUMMYUSER}" "${DUMMYPASS}" echo "Testing..." function test_optimize { local OPTIMIZE_COMMAND="${1}" local NO_OPTIMIZE_COMMAND="${2}" local GETTOCDIGEST_COMMAND="${3}" local DECOMPRESS_COMMAND="${4}" local INVISIBLE_TOC="${5}" cat < "${DOCKER_COMPOSE_YAML}" version: "3.3" services: testenv_opt: image: ${OPTIMIZE_TEST_IMAGE_NAME} container_name: testenv_opt privileged: true working_dir: ${REPO_PATH} entrypoint: ./script/optimize/optimize/entrypoint.sh environment: - NO_PROXY=127.0.0.1,localhost,${REGISTRY_HOST}:443 - OPTIMIZE_COMMAND=${OPTIMIZE_COMMAND} - NO_OPTIMIZE_COMMAND=${NO_OPTIMIZE_COMMAND} - GETTOCDIGEST_COMMAND=${GETTOCDIGEST_COMMAND} - DECOMPRESS_COMMAND=${DECOMPRESS_COMMAND} - INVISIBLE_TOC=${INVISIBLE_TOC} tmpfs: - /tmp:exec,mode=777 volumes: - "${REPO}:${REPO_PATH}:ro" - ${AUTH_DIR}:/auth:ro - "optimize-containerd-data:/var/lib/containerd" - "optimize-containerd-stargz-grpc-data:/var/lib/containerd-stargz-grpc" - "optimize-buildkit-data:/var/lib/buildkit" registry: image: registry:2 container_name: ${REGISTRY_HOST} environment: - REGISTRY_AUTH=htpasswd - REGISTRY_AUTH_HTPASSWD_REALM="Registry Realm" - REGISTRY_AUTH_HTPASSWD_PATH=/auth/auth/htpasswd - REGISTRY_HTTP_TLS_CERTIFICATE=/auth/certs/domain.crt - REGISTRY_HTTP_TLS_KEY=/auth/certs/domain.key - REGISTRY_HTTP_ADDR=${REGISTRY_HOST}:443 volumes: - ${AUTH_DIR}:/auth:ro volumes: optimize-containerd-data: optimize-containerd-stargz-grpc-data: optimize-buildkit-data: EOF local FAIL= if ! ( cd "${CONTEXT}" && \ docker-compose -f "${DOCKER_COMPOSE_YAML}" build ${DOCKER_BUILD_ARGS:-} testenv_opt && \ docker-compose -f "${DOCKER_COMPOSE_YAML}" up --abort-on-container-exit ) ; then FAIL=true fi docker-compose -f "${DOCKER_COMPOSE_YAML}" down -v if [ "${FAIL}" == "true" ] ; then exit 1 fi } test_optimize "image optimize --oci --zstdchunked" \ "image optimize --no-optimize --oci --zstdchunked" \ "image get-toc-digest --zstdchunked" \ "zstd -d" \ "true" test_optimize "image optimize --oci" \ "image optimize --no-optimize --oci" \ "image get-toc-digest" \ "gunzip" \ "false" exit 0 stargz-snapshotter-0.14.3/script/podman/000077500000000000000000000000001440204344700202455ustar00rootroot00000000000000stargz-snapshotter-0.14.3/script/podman/config/000077500000000000000000000000001440204344700215125ustar00rootroot00000000000000stargz-snapshotter-0.14.3/script/podman/config/podman-rootless-stargz-store.service000066400000000000000000000007171440204344700306710ustar00rootroot00000000000000[Unit] Description=Stargz Store service for Podman [Service] # This pipes stargz-store's IO to the shell otherwise they are lost and can't be managed by systemd. # TODO: fix this and do not use pipe ExecStart=/bin/bash -c "podman unshare stargz-store --log-level=debug --root %h/.local/share/stargz-store/data %h/.local/share/stargz-store/store 2>&1 | cat" ExecStopPost=podman unshare umount %h/.local/share/stargz-store/store [Install] WantedBy=default.target stargz-snapshotter-0.14.3/script/podman/config/storage.conf000066400000000000000000000002021440204344700240170ustar00rootroot00000000000000[storage] driver = "overlay" [storage.options] additionallayerstores = ["/home/rootless/.local/share/stargz-store/store:ref"] stargz-snapshotter-0.14.3/script/podman/config/test-podman-rootless.sh000077500000000000000000000016231440204344700261560ustar00rootroot00000000000000#!/bin/bash # Copyright The containerd Authors. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. set -eux -o pipefail if [[ "$(id -u)" = "0" ]]; then # Switch to the rootless user via SSH; This is the same approach as done in nerdctl CI systemctl start sshd exec ssh -o StrictHostKeyChecking=no rootless@localhost "$0" "$@" else systemctl --user start podman-rootless-stargz-store exec "$@" fi stargz-snapshotter-0.14.3/script/podman/run_test.sh000077500000000000000000000023351440204344700224520ustar00rootroot00000000000000#!/bin/bash # Copyright The containerd Authors. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. set -euo pipefail STARGZ_STORE_SERVICE=podman-rootless-stargz-store # Lazy pulling and run podman pull ghcr.io/stargz-containers/alpine:3.10.2-esgz podman run --rm ghcr.io/stargz-containers/alpine:3.10.2-esgz echo hello # Run (includes lazy pulling) podman run --rm ghcr.io/stargz-containers/python:3.9-esgz echo hello # Print store log to be checked by the host LOG_REMOTE_SNAPSHOT="remote-snapshot-prepared" journalctl --user -u "${STARGZ_STORE_SERVICE}" | grep "${LOG_REMOTE_SNAPSHOT}" # Non-lazy pulling podman run --rm ghcr.io/stargz-containers/ubuntu:22.04-org echo hello systemctl --user stop "${STARGZ_STORE_SERVICE}" stargz-snapshotter-0.14.3/script/podman/test.sh000077500000000000000000000035351440204344700215710ustar00rootroot00000000000000#!/bin/bash # Copyright The containerd Authors. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. set -euo pipefail CONTEXT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )/" REPO="${CONTEXT}../../" source "${REPO}/script/util/utils.sh" NODE_IMAGE_NAME_BASE=test-podman-rootless-node-base NODE_IMAGE_NAME=test-podman-rootless-node if [ "${PODMAN_NO_RECREATE:-}" != "true" ] ; then echo "Preparing node image..." docker build ${DOCKER_BUILD_ARGS:-} --progress=plain -t "${NODE_IMAGE_NAME_BASE}" --target podman-rootless "${REPO}" fi TEST_LOG=$(mktemp) STORE_LOG=$(mktemp) TMP_CONTEXT=$(mktemp -d) function cleanup { local ORG_EXIT_CODE="${1}" rm -rf "${TMP_CONTEXT}" || true rm "${TEST_LOG}" || true rm "${STORE_LOG}" || true exit "${ORG_EXIT_CODE}" } trap 'cleanup "$?"' EXIT SIGHUP SIGINT SIGQUIT SIGTERM cp "${CONTEXT}/run_test.sh" "${TMP_CONTEXT}/run_test.sh" cat < "${TMP_CONTEXT}/Dockerfile" FROM ${NODE_IMAGE_NAME_BASE} COPY run_test.sh /run_test.sh CMD ["/bin/bash", "--login", "/run_test.sh"] EOF docker build ${DOCKER_BUILD_ARGS:-} --progress=plain -t "${NODE_IMAGE_NAME}" "${TMP_CONTEXT}" docker run -t --rm --privileged "${NODE_IMAGE_NAME}" | tee "${TEST_LOG}" cat "${TEST_LOG}" | grep "${LOG_REMOTE_SNAPSHOT}" | sed -E 's/^[^\{]*(\{.*)$/\1/g' > "${STORE_LOG}" check_remote_snapshots "${STORE_LOG}" stargz-snapshotter-0.14.3/script/util/000077500000000000000000000000001440204344700177445ustar00rootroot00000000000000stargz-snapshotter-0.14.3/script/util/make.sh000077500000000000000000000032141440204344700212200ustar00rootroot00000000000000#!/bin/bash # Copyright The containerd Authors. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. set -euo pipefail CONTEXT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )/" REPO="${CONTEXT}../../" IMAGE_NAME="minienv" source "${REPO}/script/util/utils.sh" GOBASE_VERSION=$(go_base_version "${REPO}/Dockerfile") TMP_CONTEXT=$(mktemp -d) function cleanup { local ORG_EXIT_CODE="${1}" rm -rf "${TMP_CONTEXT}" || true exit "${ORG_EXIT_CODE}" } trap 'cleanup "$?"' EXIT SIGHUP SIGINT SIGQUIT SIGTERM cat < "${TMP_CONTEXT}/Dockerfile" FROM golang:${GOBASE_VERSION} RUN apt-get update -y && apt-get --no-install-recommends install -y fuse3 EOF MAKECMD="make ${@} PREFIX=/tmp/out/" docker build -t "${IMAGE_NAME}" ${DOCKER_BUILD_ARGS:-} "${TMP_CONTEXT}" docker run --rm --privileged \ --device /dev/fuse \ --tmpfs /tmp:exec,mode=777 \ -w /go/src/github.com/containerd/stargz-snapshotter \ -v "${REPO}:/go/src/github.com/containerd/stargz-snapshotter:ro" \ "${IMAGE_NAME}" /bin/sh -c "git config --global --add safe.directory '/go/src/github.com/containerd/stargz-snapshotter' && ${MAKECMD}" stargz-snapshotter-0.14.3/script/util/utils.sh000066400000000000000000000054251440204344700214460ustar00rootroot00000000000000#!/bin/bash # Copyright The containerd Authors. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Preparing creds for provided user and password for private registry(only for testing purpose) # See also: https://docs.docker.com/registry/deploying/ function prepare_creds { local OUTPUT="${1}" local REGISTRY_HOST="${2}" local USER="${3}" local PASS="${4}" mkdir "${OUTPUT}/auth" "${OUTPUT}/certs" openssl req -subj "/C=JP/ST=Remote/L=Snapshotter/O=TestEnv/OU=Integration/CN=${REGISTRY_HOST}" \ -addext "subjectAltName = DNS:${REGISTRY_HOST}" \ -newkey rsa:2048 -nodes -keyout "${OUTPUT}/certs/domain.key" \ -x509 -days 365 -out "${OUTPUT}/certs/domain.crt" htpasswd -Bbn "${USER}" "${PASS}" > "${OUTPUT}/auth/htpasswd" } # Check if all snapshots logged in the specified file are prepared as remote snapshots. # Whether a snapshot is prepared as a remote snapshot must be logged with the key # "remote-snapshot-prepared" in JSON-formatted log. # See also /snapshot/snapshot.go in this repo. LOG_REMOTE_SNAPSHOT="remote-snapshot-prepared" function check_remote_snapshots { local LOG_FILE="${1}" local REMOTE=0 local LOCAL=0 REMOTE=$(jq -r 'select(."'"${LOG_REMOTE_SNAPSHOT}"'" == "true")' "${LOG_FILE}" | wc -l) LOCAL=$(jq -r 'select(."'"${LOG_REMOTE_SNAPSHOT}"'" == "false")' "${LOG_FILE}" | wc -l) if [[ ${LOCAL} -gt 0 ]] ; then echo "some local snapshots creation have been reported (local:${LOCAL},remote:${REMOTE})" return 1 elif [[ ${REMOTE} -gt 0 ]] ; then echo "all layers have been reported as remote snapshots (local:${LOCAL},remote:${REMOTE})" return 0 else echo "no log for checking remote snapshot was provided; Is the log-level = debug?" return 1 fi } # Get version from ARG directive in the specified Dockerfile. function get_version_from_arg { local DOCKERFILE="${1}" local ARGNAME="${2}" cat "${DOCKERFILE}" | grep "${ARGNAME}=" | head -1 | sed -E 's/ARG +'"${ARGNAME}"'=v?([^ ]+).*/\1/g' | tr -d '\n' } # Get version of golang base image from the specified Dockerfile. function go_base_version { local DOCKERFILE="${1}" cat "${DOCKERFILE}" | grep -E 'FROM\s+golang:' | head -1 | sed -E 's/FROM +[^:]*:([^ ]+).*/\1/g' | tr -d '\n' } stargz-snapshotter-0.14.3/script/util/verify-no-patent.sh000077500000000000000000000026561440204344700235230ustar00rootroot00000000000000#!/bin/bash # Copyright The containerd Authors. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Copied from https://github.com/containerd/nerdctl/blob/v1.1.0/hack/verify-no-patent.sh # Modified for stargz snapshotter project CONTEXT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )/" REPO="${CONTEXT}../../" echo "Verifying that the patented NewARC() is NOT compiled in (https://github.com/hashicorp/golang-lru/blob/v0.5.4/arc.go#L15)" set -eux -o pipefail # Clear GO_BUILD_LDFLAGS to embed the symbols (cd $REPO && GO_BUILD_LDFLAGS="" make) for O in containerd-stargz-grpc ctr-remote stargz-store ; do go tool nm ${REPO}/out/$O >${REPO}/out/$O.sym if ! grep -w -F main.main ${REPO}/out/$O.sym; then echo >&2 "ERROR: the symbol file seems corrupted" exit 1 fi if grep -w NewARC ${REPO}/out/$O.sym; then echo >&2 "ERROR: patented NewARC() might be compiled in?" exit 1 fi done echo "OK" stargz-snapshotter-0.14.3/service/000077500000000000000000000000001440204344700171235ustar00rootroot00000000000000stargz-snapshotter-0.14.3/service/config.go000066400000000000000000000046131440204344700207230ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package service import ( "github.com/containerd/stargz-snapshotter/fs/config" "github.com/containerd/stargz-snapshotter/service/resolver" ) type Config struct { config.Config // KubeconfigKeychainConfig is config for kubeconfig-based keychain. KubeconfigKeychainConfig `toml:"kubeconfig_keychain"` // CRIKeychainConfig is config for CRI-based keychain. CRIKeychainConfig `toml:"cri_keychain"` // ResolverConfig is config for resolving registries. ResolverConfig `toml:"resolver"` // SnapshotterConfig is snapshotter-related config. SnapshotterConfig `toml:"snapshotter"` } // KubeconfigKeychainConfig is config for kubeconfig-based keychain. type KubeconfigKeychainConfig struct { // EnableKeychain enables kubeconfig-based keychain EnableKeychain bool `toml:"enable_keychain"` // KubeconfigPath is the path to kubeconfig which can be used to sync // secrets on the cluster into this snapshotter. KubeconfigPath string `toml:"kubeconfig_path"` } // CRIKeychainConfig is config for CRI-based keychain. type CRIKeychainConfig struct { // EnableKeychain enables CRI-based keychain EnableKeychain bool `toml:"enable_keychain"` // ImageServicePath is the path to the unix socket of backing CRI Image Service (e.g. containerd CRI plugin) ImageServicePath string `toml:"image_service_path"` } // ResolverConfig is config for resolving registries. type ResolverConfig resolver.Config // SnapshotterConfig is snapshotter-related config. type SnapshotterConfig struct { // AllowInvalidMountsOnRestart allows that there are snapshot mounts that cannot access to the // data source when restarting the snapshotter. // NOTE: User needs to manually remove the snapshots from containerd's metadata store using // ctr (e.g. `ctr snapshot rm`). AllowInvalidMountsOnRestart bool `toml:"allow_invalid_mounts_on_restart"` } stargz-snapshotter-0.14.3/service/cri.go000066400000000000000000000075201440204344700202330ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package service import ( "fmt" "strings" "github.com/containerd/containerd/reference" "github.com/containerd/stargz-snapshotter/fs/source" digest "github.com/opencontainers/go-digest" ocispec "github.com/opencontainers/image-spec/specs-go/v1" ) // TODO: switch to "github.com/containerd/containerd/pkg/snapshotters" once all tools using // // stargz-snapshotter (e.g. k3s) move to containerd version where that pkg is available. const ( // targetRefLabel is a label which contains image reference and will be passed // to snapshotters. targetRefLabel = "containerd.io/snapshot/cri.image-ref" // targetLayerDigestLabel is a label which contains layer digest and will be passed // to snapshotters. targetLayerDigestLabel = "containerd.io/snapshot/cri.layer-digest" // targetImageLayersLabel is a label which contains layer digests contained in // the target image and will be passed to snapshotters for preparing layers in // parallel. Skipping some layers is allowed and only affects performance. targetImageLayersLabel = "containerd.io/snapshot/cri.image-layers" ) const ( // targetImageURLsLabelPrefix is a label prefix which constructs a map from the layer index to // urls of the layer descriptor. This isn't contained in the set of the labels passed from CRI plugin but // some clients (e.g. nerdctl) passes this for preserving url field in the OCI descriptor. targetImageURLsLabelPrefix = "containerd.io/snapshot/remote/urls." // targetURsLLabel is a label which contains layer URL. This is only used to pass URL from containerd // to snapshotter. This isn't contained in the set of the labels passed from CRI plugin but // some clients (e.g. nerdctl) passes this for preserving url field in the OCI descriptor. targetURLsLabel = "containerd.io/snapshot/remote/urls" ) func sourceFromCRILabels(hosts source.RegistryHosts) source.GetSources { return func(labels map[string]string) ([]source.Source, error) { refStr, ok := labels[targetRefLabel] if !ok { return nil, fmt.Errorf("reference hasn't been passed") } refspec, err := reference.Parse(refStr) if err != nil { return nil, err } digestStr, ok := labels[targetLayerDigestLabel] if !ok { return nil, fmt.Errorf("digest hasn't been passed") } target, err := digest.Parse(digestStr) if err != nil { return nil, err } var neighboringLayers []ocispec.Descriptor if l, ok := labels[targetImageLayersLabel]; ok { layersStr := strings.Split(l, ",") for i, l := range layersStr { d, err := digest.Parse(l) if err != nil { return nil, err } if d.String() != target.String() { desc := ocispec.Descriptor{Digest: d} if urls, ok := labels[targetImageURLsLabelPrefix+fmt.Sprintf("%d", i)]; ok { desc.URLs = strings.Split(urls, ",") } neighboringLayers = append(neighboringLayers, desc) } } } targetDesc := ocispec.Descriptor{ Digest: target, Annotations: labels, } if targetURLs, ok := labels[targetURLsLabel]; ok { targetDesc.URLs = append(targetDesc.URLs, strings.Split(targetURLs, ",")...) } return []source.Source{ { Hosts: hosts, Name: refspec, Target: targetDesc, Manifest: ocispec.Manifest{Layers: append([]ocispec.Descriptor{targetDesc}, neighboringLayers...)}, }, }, nil } } stargz-snapshotter-0.14.3/service/keychain/000077500000000000000000000000001440204344700207165ustar00rootroot00000000000000stargz-snapshotter-0.14.3/service/keychain/cri/000077500000000000000000000000001440204344700214735ustar00rootroot00000000000000stargz-snapshotter-0.14.3/service/keychain/cri/cri.go000066400000000000000000000110311440204344700225730ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package cri import ( "context" "errors" "fmt" "sync" "time" "github.com/containerd/containerd/log" "github.com/containerd/containerd/reference" distribution "github.com/containerd/containerd/reference/docker" "github.com/containerd/stargz-snapshotter/service/resolver" runtime "k8s.io/cri-api/pkg/apis/runtime/v1" ) // NewCRIKeychain provides creds passed through CRI PullImage API. // This also returns a CRI image service server that works as a proxy backed by the specified CRI service. // This server reads all PullImageRequest and uses PullImageRequest.AuthConfig for authenticating snapshots. func NewCRIKeychain(ctx context.Context, connectCRI func() (runtime.ImageServiceClient, error)) (resolver.Credential, runtime.ImageServiceServer) { server := &instrumentedService{config: make(map[string]*runtime.AuthConfig)} go func() { log.G(ctx).Debugf("Waiting for CRI service is started...") for i := 0; i < 100; i++ { client, err := connectCRI() if err == nil { server.criMu.Lock() server.cri = client server.criMu.Unlock() log.G(ctx).Info("connected to backend CRI service") return } log.G(ctx).WithError(err).Warnf("failed to connect to CRI") time.Sleep(10 * time.Second) } log.G(ctx).Warnf("no connection is available to CRI") }() return server.credentials, server } type instrumentedService struct { cri runtime.ImageServiceClient criMu sync.Mutex config map[string]*runtime.AuthConfig configMu sync.Mutex } func (in *instrumentedService) credentials(host string, refspec reference.Spec) (string, string, error) { if host == "docker.io" || host == "registry-1.docker.io" { // Creds of "docker.io" is stored keyed by "https://index.docker.io/v1/". host = "index.docker.io" } in.configMu.Lock() defer in.configMu.Unlock() if cfg, ok := in.config[refspec.String()]; ok { return resolver.ParseAuth(cfg, host) } return "", "", nil } func (in *instrumentedService) getCRI() (c runtime.ImageServiceClient) { in.criMu.Lock() c = in.cri in.criMu.Unlock() return } func (in *instrumentedService) ListImages(ctx context.Context, r *runtime.ListImagesRequest) (res *runtime.ListImagesResponse, err error) { cri := in.getCRI() if cri == nil { return nil, errors.New("server is not initialized yet") } return cri.ListImages(ctx, r) } func (in *instrumentedService) ImageStatus(ctx context.Context, r *runtime.ImageStatusRequest) (res *runtime.ImageStatusResponse, err error) { cri := in.getCRI() if cri == nil { return nil, errors.New("server is not initialized yet") } return cri.ImageStatus(ctx, r) } func (in *instrumentedService) PullImage(ctx context.Context, r *runtime.PullImageRequest) (res *runtime.PullImageResponse, err error) { cri := in.getCRI() if cri == nil { return nil, errors.New("server is not initialized yet") } refspec, err := parseReference(r.GetImage().GetImage()) if err != nil { return nil, err } in.configMu.Lock() in.config[refspec.String()] = r.GetAuth() in.configMu.Unlock() return cri.PullImage(ctx, r) } func (in *instrumentedService) RemoveImage(ctx context.Context, r *runtime.RemoveImageRequest) (_ *runtime.RemoveImageResponse, err error) { cri := in.getCRI() if cri == nil { return nil, errors.New("server is not initialized yet") } refspec, err := parseReference(r.GetImage().GetImage()) if err != nil { return nil, err } in.configMu.Lock() delete(in.config, refspec.String()) in.configMu.Unlock() return cri.RemoveImage(ctx, r) } func (in *instrumentedService) ImageFsInfo(ctx context.Context, r *runtime.ImageFsInfoRequest) (res *runtime.ImageFsInfoResponse, err error) { cri := in.getCRI() if cri == nil { return nil, errors.New("server is not initialized yet") } return cri.ImageFsInfo(ctx, r) } func parseReference(ref string) (reference.Spec, error) { namedRef, err := distribution.ParseDockerRef(ref) if err != nil { return reference.Spec{}, fmt.Errorf("failed to parse image reference %q: %w", ref, err) } return reference.Parse(namedRef.String()) } stargz-snapshotter-0.14.3/service/keychain/crialpha/000077500000000000000000000000001440204344700225015ustar00rootroot00000000000000stargz-snapshotter-0.14.3/service/keychain/crialpha/crialpha.go000066400000000000000000000116701440204344700246200ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package crialpha import ( "context" "errors" "fmt" "sync" "time" "github.com/containerd/containerd/log" "github.com/containerd/containerd/reference" distribution "github.com/containerd/containerd/reference/docker" "github.com/containerd/stargz-snapshotter/service/resolver" runtime_alpha "github.com/containerd/containerd/third_party/k8s.io/cri-api/pkg/apis/runtime/v1alpha2" runtime "k8s.io/cri-api/pkg/apis/runtime/v1" "github.com/containerd/stargz-snapshotter/util/criutil" ) // NewAlphaCRIKeychain provides creds passed through CRI PullImage API. // Same as NewCRIKeychain but for CRI v1alpha API. // Containerd doesn't drop v1alpha API support so our proxy also exposes this API as well. func NewCRIAlphaKeychain(ctx context.Context, connectCRI func() (runtime_alpha.ImageServiceClient, error)) (resolver.Credential, runtime_alpha.ImageServiceServer) { server := &instrumentedAlphaService{config: make(map[string]*runtime_alpha.AuthConfig)} go func() { log.G(ctx).Debugf("Waiting for CRI service is started...") for i := 0; i < 100; i++ { client, err := connectCRI() if err == nil { server.criMu.Lock() server.cri = client server.criMu.Unlock() log.G(ctx).Info("connected to backend CRI service") return } log.G(ctx).WithError(err).Warnf("failed to connect to CRI") time.Sleep(10 * time.Second) } log.G(ctx).Warnf("no connection is available to CRI") }() return server.credentials, server } type instrumentedAlphaService struct { runtime_alpha.UnimplementedImageServiceServer cri runtime_alpha.ImageServiceClient criMu sync.Mutex config map[string]*runtime_alpha.AuthConfig configMu sync.Mutex } func (in *instrumentedAlphaService) credentials(host string, refspec reference.Spec) (string, string, error) { if host == "docker.io" || host == "registry-1.docker.io" { // Creds of "docker.io" is stored keyed by "https://index.docker.io/v1/". host = "index.docker.io" } in.configMu.Lock() defer in.configMu.Unlock() if cfg, ok := in.config[refspec.String()]; ok { var v1cfg runtime.AuthConfig if err := criutil.AlphaReqToV1Req(cfg, &v1cfg); err != nil { return "", "", err } return resolver.ParseAuth(&v1cfg, host) } return "", "", nil } func (in *instrumentedAlphaService) getCRI() (c runtime_alpha.ImageServiceClient) { in.criMu.Lock() c = in.cri in.criMu.Unlock() return } func (in *instrumentedAlphaService) ListImages(ctx context.Context, r *runtime_alpha.ListImagesRequest) (res *runtime_alpha.ListImagesResponse, err error) { cri := in.getCRI() if cri == nil { return nil, errors.New("server is not initialized yet") } return cri.ListImages(ctx, r) } func (in *instrumentedAlphaService) ImageStatus(ctx context.Context, r *runtime_alpha.ImageStatusRequest) (res *runtime_alpha.ImageStatusResponse, err error) { cri := in.getCRI() if cri == nil { return nil, errors.New("server is not initialized yet") } return cri.ImageStatus(ctx, r) } func (in *instrumentedAlphaService) PullImage(ctx context.Context, r *runtime_alpha.PullImageRequest) (res *runtime_alpha.PullImageResponse, err error) { cri := in.getCRI() if cri == nil { return nil, errors.New("server is not initialized yet") } refspec, err := parseReference(r.GetImage().GetImage()) if err != nil { return nil, err } in.configMu.Lock() in.config[refspec.String()] = r.GetAuth() in.configMu.Unlock() return cri.PullImage(ctx, r) } func (in *instrumentedAlphaService) RemoveImage(ctx context.Context, r *runtime_alpha.RemoveImageRequest) (_ *runtime_alpha.RemoveImageResponse, err error) { cri := in.getCRI() if cri == nil { return nil, errors.New("server is not initialized yet") } refspec, err := parseReference(r.GetImage().GetImage()) if err != nil { return nil, err } in.configMu.Lock() delete(in.config, refspec.String()) in.configMu.Unlock() return cri.RemoveImage(ctx, r) } func (in *instrumentedAlphaService) ImageFsInfo(ctx context.Context, r *runtime_alpha.ImageFsInfoRequest) (res *runtime_alpha.ImageFsInfoResponse, err error) { cri := in.getCRI() if cri == nil { return nil, errors.New("server is not initialized yet") } return cri.ImageFsInfo(ctx, r) } func parseReference(ref string) (reference.Spec, error) { namedRef, err := distribution.ParseDockerRef(ref) if err != nil { return reference.Spec{}, fmt.Errorf("failed to parse image reference %q: %w", ref, err) } return reference.Parse(namedRef.String()) } stargz-snapshotter-0.14.3/service/keychain/dockerconfig/000077500000000000000000000000001440204344700233535ustar00rootroot00000000000000stargz-snapshotter-0.14.3/service/keychain/dockerconfig/dockerconfig.go000066400000000000000000000027251440204344700263450ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package dockerconfig import ( "context" "github.com/containerd/containerd/log" "github.com/containerd/containerd/reference" "github.com/containerd/stargz-snapshotter/service/resolver" "github.com/docker/cli/cli/config" ) func NewDockerconfigKeychain(ctx context.Context) resolver.Credential { return func(host string, refspec reference.Spec) (string, string, error) { cf, err := config.Load("") if err != nil { log.G(ctx).WithError(err).Warnf("failed to load docker config file") return "", "", nil } if host == "docker.io" || host == "registry-1.docker.io" { // Creds of docker.io is stored keyed by "https://index.docker.io/v1/". host = "https://index.docker.io/v1/" } ac, err := cf.GetAuthConfig(host) if err != nil { return "", "", err } if ac.IdentityToken != "" { return "", ac.IdentityToken, nil } return ac.Username, ac.Password, nil } } stargz-snapshotter-0.14.3/service/keychain/kubeconfig/000077500000000000000000000000001440204344700230325ustar00rootroot00000000000000stargz-snapshotter-0.14.3/service/keychain/kubeconfig/kubeconfig.go000066400000000000000000000175031440204344700255030ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package kubeconfig import ( "bytes" "context" "fmt" "os" "sync" "time" "github.com/containerd/containerd/log" "github.com/containerd/containerd/reference" "github.com/containerd/stargz-snapshotter/service/resolver" dcfile "github.com/docker/cli/cli/config/configfile" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" utilruntime "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/apimachinery/pkg/util/wait" "k8s.io/apimachinery/pkg/watch" "k8s.io/client-go/kubernetes" "k8s.io/client-go/tools/cache" "k8s.io/client-go/tools/clientcmd" "k8s.io/client-go/util/workqueue" ) const dockerconfigSelector = "type=" + string(corev1.SecretTypeDockerConfigJson) type options struct { kubeconfigPath string } type Option func(*options) func WithKubeconfigPath(path string) Option { return func(opts *options) { opts.kubeconfigPath = path } } // NewKubeconfigKeychain provides a keychain which can sync its contents with // kubernetes API server by fetching all `kubernetes.io/dockerconfigjson` // secrets in the cluster with provided kubeconfig. It's OK that config provides // kubeconfig path but the file doesn't exist at that moment. In this case, this // keychain keeps on trying to read the specified path periodically and when the // file is actually provided, this keychain tries to access API server using the // file. This is useful for some environments (e.g. single node cluster with // containerized apiserver) where stargz snapshotter needs to start before // everything, including booting containerd/kubelet/apiserver and configuring // users/roles. // TODO: support update of kubeconfig file func NewKubeconfigKeychain(ctx context.Context, opts ...Option) resolver.Credential { var kcOpts options for _, o := range opts { o(&kcOpts) } kc := newKeychain(ctx, kcOpts.kubeconfigPath) return kc.credentials } func newKeychain(ctx context.Context, kubeconfigPath string) *keychain { kc := &keychain{ config: make(map[string]*dcfile.ConfigFile), } ctx = log.WithLogger(ctx, log.G(ctx).WithField("kubeconfig", kubeconfigPath)) go func() { if kubeconfigPath != "" { log.G(ctx).Debugf("Waiting for kubeconfig being installed...") for { if _, err := os.Stat(kubeconfigPath); err == nil { break } else if !os.IsNotExist(err) { log.G(ctx).WithError(err). Warnf("failed to read; Disabling syncing") return } time.Sleep(10 * time.Second) } } // default loader for KUBECONFIG or `~/.kube/config` // if no explicit path provided, KUBECONFIG will be used. // if KUBECONFIG doesn't contain paths, `~/.kube/config` will be used. loadingRule := clientcmd.NewDefaultClientConfigLoadingRules() // explicitly provide path for kubeconfig. // if path isn't "", this path will be respected. loadingRule.ExplicitPath = kubeconfigPath // load and merge config files clientcfg, err := clientcmd.NewNonInteractiveDeferredLoadingClientConfig( loadingRule, // loader for config files &clientcmd.ConfigOverrides{}, // no overrides for config ).ClientConfig() if err != nil { log.G(ctx).WithError(err).Warnf("failed to load config; Disabling syncing") return } client, err := kubernetes.NewForConfig(clientcfg) if err != nil { log.G(ctx).WithError(err).Warnf("failed to prepare client; Disabling syncing") return } if err := kc.startSyncSecrets(ctx, client); err != nil { log.G(ctx).WithError(err).Warnf("failed to sync secrets") } }() return kc } type keychain struct { config map[string]*dcfile.ConfigFile configMu sync.Mutex // the following entries are used for syncing secrets with API server. // these fields are lazily filled after kubeconfig file is provided. queue *workqueue.Type informer cache.SharedIndexInformer } func (kc *keychain) credentials(host string, refspec reference.Spec) (string, string, error) { if host == "docker.io" || host == "registry-1.docker.io" { // Creds of "docker.io" is stored keyed by "https://index.docker.io/v1/". host = "https://index.docker.io/v1/" } kc.configMu.Lock() defer kc.configMu.Unlock() for _, cfg := range kc.config { if acfg, err := cfg.GetAuthConfig(host); err == nil { if acfg.IdentityToken != "" { return "", acfg.IdentityToken, nil } else if !(acfg.Username == "" && acfg.Password == "") { return acfg.Username, acfg.Password, nil } } } return "", "", nil } func (kc *keychain) startSyncSecrets(ctx context.Context, client kubernetes.Interface) error { // don't let panics crash the process defer utilruntime.HandleCrash() // get informed on `kubernetes.io/dockerconfigjson` secrets in all namespaces informer := cache.NewSharedIndexInformer( &cache.ListWatch{ ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { // TODO: support legacy image secret `kubernetes.io/dockercfg` options.FieldSelector = dockerconfigSelector return client.CoreV1().Secrets(metav1.NamespaceAll).List(ctx, options) }, WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { // TODO: support legacy image secret `kubernetes.io/dockercfg` options.FieldSelector = dockerconfigSelector return client.CoreV1().Secrets(metav1.NamespaceAll).Watch(ctx, options) }, }, &corev1.Secret{}, 0, cache.Indexers{}, ) // use workqueue because each task possibly takes long for parsing config, // wating for lock, etc... queue := workqueue.New() defer queue.ShutDown() informer.AddEventHandler(cache.ResourceEventHandlerFuncs{ AddFunc: func(obj interface{}) { key, err := cache.MetaNamespaceKeyFunc(obj) if err == nil { queue.Add(key) } }, UpdateFunc: func(old, new interface{}) { key, err := cache.MetaNamespaceKeyFunc(new) if err == nil { queue.Add(key) } }, DeleteFunc: func(obj interface{}) { key, err := cache.DeletionHandlingMetaNamespaceKeyFunc(obj) if err == nil { queue.Add(key) } }, }) go informer.Run(ctx.Done()) if !cache.WaitForCacheSync(ctx.Done(), informer.HasSynced) { return fmt.Errorf("Timed out for syncing cache") } // get informer and queue kc.informer = informer kc.queue = queue // keep on syncing secrets wait.Until(kc.runWorker, time.Second, ctx.Done()) return nil } func (kc *keychain) runWorker() { for kc.processNextItem() { // continue looping } } // TODO: consider retrying? func (kc *keychain) processNextItem() bool { key, quit := kc.queue.Get() if quit { return false } defer kc.queue.Done(key) obj, exists, err := kc.informer.GetIndexer().GetByKey(key.(string)) if err != nil { utilruntime.HandleError(fmt.Errorf("failed to get object; don't sync %q: %v", key, err)) return true } if !exists { kc.configMu.Lock() delete(kc.config, key.(string)) kc.configMu.Unlock() return true } // TODO: support legacy image secret `kubernetes.io/dockercfg` data, ok := obj.(*corev1.Secret).Data[corev1.DockerConfigJsonKey] if !ok { utilruntime.HandleError(fmt.Errorf("no secret is provided; don't sync %q", key)) return true } configFile := dcfile.New("") if err := configFile.LoadFromReader(bytes.NewReader(data)); err != nil { utilruntime.HandleError(fmt.Errorf("broken data; don't sync %q: %v", key, err)) return true } kc.configMu.Lock() kc.config[key.(string)] = configFile kc.configMu.Unlock() return true } stargz-snapshotter-0.14.3/service/plugin/000077500000000000000000000000001440204344700204215ustar00rootroot00000000000000stargz-snapshotter-0.14.3/service/plugin/plugin.go000066400000000000000000000045071440204344700222540ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package plugin import ( "context" "time" "github.com/containerd/containerd/defaults" "github.com/containerd/containerd/pkg/dialer" grpc "google.golang.org/grpc" "google.golang.org/grpc/backoff" "google.golang.org/grpc/credentials/insecure" runtime_alpha "github.com/containerd/containerd/third_party/k8s.io/cri-api/pkg/apis/runtime/v1alpha2" "github.com/containerd/stargz-snapshotter/service/keychain/crialpha" "github.com/containerd/stargz-snapshotter/service/plugincore" "github.com/containerd/stargz-snapshotter/service/resolver" ) func init() { plugincore.RegisterPlugin(registerCRIAlphaServer) } func registerCRIAlphaServer(ctx context.Context, criAddr string, rpc *grpc.Server) resolver.Credential { connectAlphaCRI := func() (runtime_alpha.ImageServiceClient, error) { conn, err := newCRIConn(criAddr) if err != nil { return nil, err } return runtime_alpha.NewImageServiceClient(conn), nil } criAlphaCreds, criAlphaServer := crialpha.NewCRIAlphaKeychain(ctx, connectAlphaCRI) runtime_alpha.RegisterImageServiceServer(rpc, criAlphaServer) return criAlphaCreds } func newCRIConn(criAddr string) (*grpc.ClientConn, error) { // TODO: make gRPC options configurable from config.toml backoffConfig := backoff.DefaultConfig backoffConfig.MaxDelay = 3 * time.Second connParams := grpc.ConnectParams{ Backoff: backoffConfig, } gopts := []grpc.DialOption{ grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithConnectParams(connParams), grpc.WithContextDialer(dialer.ContextDialer), grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(defaults.DefaultMaxRecvMsgSize)), grpc.WithDefaultCallOptions(grpc.MaxCallSendMsgSize(defaults.DefaultMaxSendMsgSize)), } return grpc.Dial(dialer.DialAddress(criAddr), gopts...) } stargz-snapshotter-0.14.3/service/plugincore/000077500000000000000000000000001440204344700212725ustar00rootroot00000000000000stargz-snapshotter-0.14.3/service/plugincore/plugin.go000066400000000000000000000127211440204344700231220ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package plugincore import ( "context" "errors" "fmt" "net" "os" "path/filepath" "time" "github.com/containerd/containerd/defaults" "github.com/containerd/containerd/log" "github.com/containerd/containerd/pkg/dialer" "github.com/containerd/containerd/platforms" ctdplugin "github.com/containerd/containerd/plugin" "github.com/containerd/stargz-snapshotter/service" "github.com/containerd/stargz-snapshotter/service/keychain/cri" "github.com/containerd/stargz-snapshotter/service/keychain/dockerconfig" "github.com/containerd/stargz-snapshotter/service/keychain/kubeconfig" "github.com/containerd/stargz-snapshotter/service/resolver" grpc "google.golang.org/grpc" "google.golang.org/grpc/backoff" "google.golang.org/grpc/credentials/insecure" runtime "k8s.io/cri-api/pkg/apis/runtime/v1" ) // Config represents configuration for the stargz snapshotter plugin. type Config struct { service.Config // RootPath is the directory for the plugin RootPath string `toml:"root_path"` // CRIKeychainImageServicePath is the path to expose CRI service wrapped by CRI keychain CRIKeychainImageServicePath string `toml:"cri_keychain_image_service_path"` // Registry is CRI-plugin-compatible registry configuration Registry resolver.Registry `toml:"registry"` } func RegisterPlugin(registerCRIAlphaServer func(ctx context.Context, criAddr string, rpc *grpc.Server) resolver.Credential) { ctdplugin.Register(&ctdplugin.Registration{ Type: ctdplugin.SnapshotPlugin, ID: "stargz", Config: &Config{}, InitFn: func(ic *ctdplugin.InitContext) (interface{}, error) { ic.Meta.Platforms = append(ic.Meta.Platforms, platforms.DefaultSpec()) ctx := ic.Context config, ok := ic.Config.(*Config) if !ok { return nil, errors.New("invalid stargz snapshotter configuration") } root := ic.Root if config.RootPath != "" { root = config.RootPath } ic.Meta.Exports["root"] = root // Configure keychain credsFuncs := []resolver.Credential{dockerconfig.NewDockerconfigKeychain(ctx)} if config.Config.KubeconfigKeychainConfig.EnableKeychain { var opts []kubeconfig.Option if kcp := config.Config.KubeconfigKeychainConfig.KubeconfigPath; kcp != "" { opts = append(opts, kubeconfig.WithKubeconfigPath(kcp)) } credsFuncs = append(credsFuncs, kubeconfig.NewKubeconfigKeychain(ctx, opts...)) } if addr := config.CRIKeychainImageServicePath; config.Config.CRIKeychainConfig.EnableKeychain && addr != "" { // connects to the backend CRI service (defaults to containerd socket) criAddr := ic.Address if cp := config.Config.CRIKeychainConfig.ImageServicePath; cp != "" { criAddr = cp } if criAddr == "" { return nil, errors.New("backend CRI service address is not specified") } connectCRI := func() (runtime.ImageServiceClient, error) { conn, err := newCRIConn(criAddr) if err != nil { return nil, err } return runtime.NewImageServiceClient(conn), nil } criCreds, criServer := cri.NewCRIKeychain(ctx, connectCRI) // Create a gRPC server rpc := grpc.NewServer() runtime.RegisterImageServiceServer(rpc, criServer) criAlphaCreds := registerCRIAlphaServer(ctx, criAddr, rpc) // Prepare the directory for the socket if err := os.MkdirAll(filepath.Dir(addr), 0700); err != nil { return nil, fmt.Errorf("failed to create directory %q: %w", filepath.Dir(addr), err) } // Try to remove the socket file to avoid EADDRINUSE if err := os.RemoveAll(addr); err != nil { return nil, fmt.Errorf("failed to remove %q: %w", addr, err) } // Listen and serve l, err := net.Listen("unix", addr) if err != nil { return nil, fmt.Errorf("error on listen socket %q: %w", addr, err) } go func() { if err := rpc.Serve(l); err != nil { log.G(ctx).WithError(err).Warnf("error on serving via socket %q", addr) } }() credsFuncs = append(credsFuncs, criAlphaCreds, criCreds) } // TODO(ktock): print warn if old configuration is specified. // TODO(ktock): should we respect old configuration? return service.NewStargzSnapshotterService(ctx, root, &config.Config, service.WithCustomRegistryHosts(resolver.RegistryHostsFromCRIConfig(ctx, config.Registry, credsFuncs...))) }, }) } func newCRIConn(criAddr string) (*grpc.ClientConn, error) { // TODO: make gRPC options configurable from config.toml backoffConfig := backoff.DefaultConfig backoffConfig.MaxDelay = 3 * time.Second connParams := grpc.ConnectParams{ Backoff: backoffConfig, } gopts := []grpc.DialOption{ grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithConnectParams(connParams), grpc.WithContextDialer(dialer.ContextDialer), grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(defaults.DefaultMaxRecvMsgSize)), grpc.WithDefaultCallOptions(grpc.MaxCallSendMsgSize(defaults.DefaultMaxSendMsgSize)), } return grpc.Dial(dialer.DialAddress(criAddr), gopts...) } stargz-snapshotter-0.14.3/service/resolver/000077500000000000000000000000001440204344700207645ustar00rootroot00000000000000stargz-snapshotter-0.14.3/service/resolver/cri.go000066400000000000000000000302451440204344700220740ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package resolver // ===== // This is CRI-plugin-compatible registry hosts configuration. // Some functions are ported from https://github.com/containerd/containerd/blob/v1.5.2/pkg/cri as noted on each one. // TODO: import them from CRI package once we drop support to continerd v1.5.x (cri v1alpha2) // ===== import ( "context" "crypto/tls" "crypto/x509" "encoding/base64" "errors" "fmt" "net" "net/http" "net/url" "os" "path/filepath" "strings" "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/reference" "github.com/containerd/containerd/remotes/docker" dconfig "github.com/containerd/containerd/remotes/docker/config" "github.com/containerd/stargz-snapshotter/fs/source" rhttp "github.com/hashicorp/go-retryablehttp" runtime "k8s.io/cri-api/pkg/apis/runtime/v1" ) // Registry is registry settings configured type Registry struct { // ConfigPath is a path to the root directory containing registry-specific // configurations. // If ConfigPath is set, the rest of the registry specific options are ignored. ConfigPath string `toml:"config_path" json:"configPath"` // Mirrors are namespace to mirror mapping for all namespaces. // This option will not be used when ConfigPath is provided. // DEPRECATED: Use ConfigPath instead. Remove in containerd 1.7. Mirrors map[string]Mirror `toml:"mirrors" json:"mirrors"` // Configs are configs for each registry. // The key is the domain name or IP of the registry. // This option will be fully deprecated for ConfigPath in the future. Configs map[string]RegistryConfig `toml:"configs" json:"configs"` } // Mirror contains the config related to the registry mirror type Mirror struct { // Endpoints are endpoints for a namespace. CRI plugin will try the endpoints // one by one until a working one is found. The endpoint must be a valid url // with host specified. // The scheme, host and path from the endpoint URL will be used. Endpoints []string `toml:"endpoint" json:"endpoint"` } // RegistryConfig contains configuration used to communicate with the registry. type RegistryConfig struct { // Auth contains information to authenticate to the registry. Auth *AuthConfig `toml:"auth" json:"auth"` // TLS is a pair of CA/Cert/Key which then are used when creating the transport // that communicates with the registry. // This field will not be used when ConfigPath is provided. // DEPRECATED: Use ConfigPath instead. Remove in containerd 1.7. TLS *TLSConfig `toml:"tls" json:"tls"` } // AuthConfig contains the config related to authentication to a specific registry type AuthConfig struct { // Username is the username to login the registry. Username string `toml:"username" json:"username"` // Password is the password to login the registry. Password string `toml:"password" json:"password"` // Auth is a base64 encoded string from the concatenation of the username, // a colon, and the password. Auth string `toml:"auth" json:"auth"` // IdentityToken is used to authenticate the user and get // an access token for the registry. IdentityToken string `toml:"identitytoken" json:"identitytoken"` } // TLSConfig contains the CA/Cert/Key used for a registry type TLSConfig struct { InsecureSkipVerify bool `toml:"insecure_skip_verify" json:"insecure_skip_verify"` CAFile string `toml:"ca_file" json:"caFile"` CertFile string `toml:"cert_file" json:"certFile"` KeyFile string `toml:"key_file" json:"keyFile"` } // RegistryHostsFromCRIConfig creates RegistryHosts (a set of registry configuration) from CRI-plugin-compatible config. // NOTE: ported from https://github.com/containerd/containerd/blob/v1.5.2/pkg/cri/server/image_pull.go#L332-L405 func RegistryHostsFromCRIConfig(ctx context.Context, config Registry, credsFuncs ...Credential) source.RegistryHosts { paths := filepath.SplitList(config.ConfigPath) if len(paths) > 0 { return func(ref reference.Spec) ([]docker.RegistryHost, error) { hostOptions := dconfig.HostOptions{} hostOptions.Credentials = multiCredsFuncs(ref, append(credsFuncs, func(host string, ref reference.Spec) (string, string, error) { config := config.Configs[host] if config.Auth != nil { return ParseAuth(toRuntimeAuthConfig(*config.Auth), host) } return "", "", nil })...) hostOptions.HostDir = hostDirFromRoots(paths) return dconfig.ConfigureHosts(ctx, hostOptions)(ref.Hostname()) } } return func(ref reference.Spec) ([]docker.RegistryHost, error) { host := ref.Hostname() var registries []docker.RegistryHost endpoints, err := registryEndpoints(config, host) if err != nil { return nil, fmt.Errorf("get registry endpoints: %w", err) } for _, e := range endpoints { u, err := url.Parse(e) if err != nil { return nil, fmt.Errorf("parse registry endpoint %q from mirrors: %w", e, err) } var ( rclient = rhttp.NewClient() config = config.Configs[u.Host] ) rclient.Logger = nil // disable logging every request if config.TLS != nil { if tr, ok := rclient.HTTPClient.Transport.(*http.Transport); ok { tr.TLSClientConfig, err = getTLSConfig(*config.TLS) if err != nil { return nil, fmt.Errorf("get TLSConfig for registry %q: %w", e, err) } } else { return nil, errors.New("TLS config cannot be applied; Client.Transport is not *http.Transport") } } client := rclient.StandardClient() authorizer := docker.NewDockerAuthorizer( docker.WithAuthClient(client), docker.WithAuthCreds(multiCredsFuncs(ref, credsFuncs...))) if u.Path == "" { u.Path = "/v2" } registries = append(registries, docker.RegistryHost{ Client: client, Authorizer: authorizer, Host: u.Host, Scheme: u.Scheme, Path: u.Path, Capabilities: docker.HostCapabilityResolve | docker.HostCapabilityPull, }) } return registries, nil } } // NOTE: Ported from https://github.com/containerd/containerd/blob/v1.5.2/pkg/cri/server/image_pull.go#L316-L330 func hostDirFromRoots(roots []string) func(string) (string, error) { rootfn := make([]func(string) (string, error), len(roots)) for i := range roots { rootfn[i] = dconfig.HostDirFromRoot(roots[i]) } return func(host string) (dir string, err error) { for _, fn := range rootfn { dir, err = fn(host) if (err != nil && !errdefs.IsNotFound(err)) || (dir != "") { break } } return } } // toRuntimeAuthConfig converts cri plugin auth config to runtime auth config. // NOTE: Ported from https://github.com/containerd/containerd/blob/v1.5.2/pkg/cri/server/helpers.go#L295-L303 func toRuntimeAuthConfig(a AuthConfig) *runtime.AuthConfig { return &runtime.AuthConfig{ Username: a.Username, Password: a.Password, Auth: a.Auth, IdentityToken: a.IdentityToken, } } // getTLSConfig returns a TLSConfig configured with a CA/Cert/Key specified by registryTLSConfig // NOTE: Ported from https://github.com/containerd/containerd/blob/v1.5.2/pkg/cri/server/image_pull.go#L316-L330 func getTLSConfig(registryTLSConfig TLSConfig) (*tls.Config, error) { var ( tlsConfig = &tls.Config{} cert tls.Certificate err error ) if registryTLSConfig.CertFile != "" && registryTLSConfig.KeyFile == "" { return nil, fmt.Errorf("cert file %q was specified, but no corresponding key file was specified", registryTLSConfig.CertFile) } if registryTLSConfig.CertFile == "" && registryTLSConfig.KeyFile != "" { return nil, fmt.Errorf("key file %q was specified, but no corresponding cert file was specified", registryTLSConfig.KeyFile) } if registryTLSConfig.CertFile != "" && registryTLSConfig.KeyFile != "" { cert, err = tls.LoadX509KeyPair(registryTLSConfig.CertFile, registryTLSConfig.KeyFile) if err != nil { return nil, fmt.Errorf("failed to load cert file: %w", err) } if len(cert.Certificate) != 0 { tlsConfig.Certificates = []tls.Certificate{cert} } tlsConfig.BuildNameToCertificate() // nolint:staticcheck } if registryTLSConfig.CAFile != "" { caCertPool, err := x509.SystemCertPool() if err != nil { return nil, fmt.Errorf("failed to get system cert pool: %w", err) } caCert, err := os.ReadFile(registryTLSConfig.CAFile) if err != nil { return nil, fmt.Errorf("failed to load CA file: %w", err) } caCertPool.AppendCertsFromPEM(caCert) tlsConfig.RootCAs = caCertPool } tlsConfig.InsecureSkipVerify = registryTLSConfig.InsecureSkipVerify return tlsConfig, nil } // defaultScheme returns the default scheme for a registry host. // NOTE: Ported from https://github.com/containerd/containerd/blob/v1.5.2/pkg/cri/server/image_pull.go#L316-L330 func defaultScheme(host string) string { if h, _, err := net.SplitHostPort(host); err == nil { host = h } if host == "localhost" || host == "127.0.0.1" || host == "::1" { return "http" } return "https" } // addDefaultScheme returns the endpoint with default scheme // NOTE: Ported from https://github.com/containerd/containerd/blob/v1.5.2/pkg/cri/server/image_pull.go#L316-L330 func addDefaultScheme(endpoint string) (string, error) { if strings.Contains(endpoint, "://") { return endpoint, nil } ue := "dummy://" + endpoint u, err := url.Parse(ue) if err != nil { return "", err } return fmt.Sprintf("%s://%s", defaultScheme(u.Host), endpoint), nil } // registryEndpoints returns endpoints for a given host. // It adds default registry endpoint if it does not exist in the passed-in endpoint list. // It also supports wildcard host matching with `*`. // NOTE: Ported from https://github.com/containerd/containerd/blob/v1.5.2/pkg/cri/server/image_pull.go#L431-L464 func registryEndpoints(config Registry, host string) ([]string, error) { var endpoints []string _, ok := config.Mirrors[host] if ok { endpoints = config.Mirrors[host].Endpoints } else { endpoints = config.Mirrors["*"].Endpoints } defaultHost, err := docker.DefaultHost(host) if err != nil { return nil, fmt.Errorf("get default host: %w", err) } for i := range endpoints { en, err := addDefaultScheme(endpoints[i]) if err != nil { return nil, fmt.Errorf("parse endpoint url: %w", err) } endpoints[i] = en } for _, e := range endpoints { u, err := url.Parse(e) if err != nil { return nil, fmt.Errorf("parse endpoint url: %w", err) } if u.Host == host { // Do not add default if the endpoint already exists. return endpoints, nil } } return append(endpoints, defaultScheme(defaultHost)+"://"+defaultHost), nil } // ParseAuth parses AuthConfig and returns username and password/secret required by containerd. // NOTE: Ported from https://github.com/containerd/containerd/blob/v1.5.2/pkg/cri/server/image_pull.go#L176-L214 func ParseAuth(auth *runtime.AuthConfig, host string) (string, string, error) { if auth == nil { return "", "", nil } if auth.ServerAddress != "" { // Do not return the auth info when server address doesn't match. u, err := url.Parse(auth.ServerAddress) if err != nil { return "", "", fmt.Errorf("parse server address: %w", err) } if host != u.Host { return "", "", nil } } if auth.Username != "" { return auth.Username, auth.Password, nil } if auth.IdentityToken != "" { return "", auth.IdentityToken, nil } if auth.Auth != "" { decLen := base64.StdEncoding.DecodedLen(len(auth.Auth)) decoded := make([]byte, decLen) _, err := base64.StdEncoding.Decode(decoded, []byte(auth.Auth)) if err != nil { return "", "", err } fields := strings.SplitN(string(decoded), ":", 2) if len(fields) != 2 { return "", "", fmt.Errorf("invalid decoded auth: %q", decoded) } user, passwd := fields[0], fields[1] return user, strings.Trim(passwd, "\x00"), nil } // TODO(random-liu): Support RegistryToken. // An empty auth config is valid for anonymous registry return "", "", nil } stargz-snapshotter-0.14.3/service/resolver/registry.go000066400000000000000000000106671440204344700231750ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package resolver import ( "fmt" "net/http" "time" "github.com/containerd/containerd/reference" "github.com/containerd/containerd/remotes/docker" "github.com/containerd/stargz-snapshotter/fs/source" rhttp "github.com/hashicorp/go-retryablehttp" ) const defaultRequestTimeoutSec = 30 // Config is config for resolving registries. type Config struct { Host map[string]HostConfig `toml:"host"` } type HostConfig struct { Mirrors []MirrorConfig `toml:"mirrors"` } type MirrorConfig struct { // Host is the hostname of the host. Host string `toml:"host"` // Insecure is true means use http scheme instead of https. Insecure bool `toml:"insecure"` // RequestTimeoutSec is timeout seconds of each request to the registry. // RequestTimeoutSec == 0 indicates the default timeout (defaultRequestTimeoutSec). // RequestTimeoutSec < 0 indicates no timeout. RequestTimeoutSec int `toml:"request_timeout_sec"` // Header are additional headers to send to the server Header map[string]interface{} `toml:"header"` } type Credential func(string, reference.Spec) (string, string, error) // RegistryHostsFromConfig creates RegistryHosts (a set of registry configuration) from Config. func RegistryHostsFromConfig(cfg Config, credsFuncs ...Credential) source.RegistryHosts { return func(ref reference.Spec) (hosts []docker.RegistryHost, _ error) { host := ref.Hostname() for _, h := range append(cfg.Host[host].Mirrors, MirrorConfig{ Host: host, }) { client := rhttp.NewClient() client.Logger = nil // disable logging every request tr := client.StandardClient() if h.RequestTimeoutSec >= 0 { if h.RequestTimeoutSec == 0 { tr.Timeout = defaultRequestTimeoutSec * time.Second } else { tr.Timeout = time.Duration(h.RequestTimeoutSec) * time.Second } } // h.RequestTimeoutSec < 0 means "no timeout" var header http.Header var err error if h.Header != nil { header = http.Header{} for key, ty := range h.Header { switch value := ty.(type) { case string: header[key] = []string{value} case []interface{}: header[key], err = makeStringSlice(value, nil) if err != nil { return nil, err } default: return nil, fmt.Errorf("invalid type %v for header %q", ty, key) } } } config := docker.RegistryHost{ Client: tr, Host: h.Host, Scheme: "https", Path: "/v2", Capabilities: docker.HostCapabilityPull | docker.HostCapabilityResolve, Authorizer: docker.NewDockerAuthorizer( docker.WithAuthClient(tr), docker.WithAuthCreds(multiCredsFuncs(ref, credsFuncs...))), Header: header, } if localhost, _ := docker.MatchLocalhost(config.Host); localhost || h.Insecure { config.Scheme = "http" } if config.Host == "docker.io" { config.Host = "registry-1.docker.io" } hosts = append(hosts, config) } return } } func multiCredsFuncs(ref reference.Spec, credsFuncs ...Credential) func(string) (string, string, error) { return func(host string) (string, string, error) { for _, f := range credsFuncs { if username, secret, err := f(host, ref); err != nil { return "", "", err } else if !(username == "" && secret == "") { return username, secret, nil } } return "", "", nil } } // makeStringSlice is a helper func to convert from []interface{} to []string. // Additionally an optional cb func may be passed to perform string mapping. // NOTE: Ported from https://github.com/containerd/containerd/blob/v1.6.9/remotes/docker/config/hosts.go#L516-L533 func makeStringSlice(slice []interface{}, cb func(string) string) ([]string, error) { out := make([]string, len(slice)) for i, value := range slice { str, ok := value.(string) if !ok { return nil, fmt.Errorf("unable to cast %v to string", value) } if cb != nil { out[i] = cb(str) } else { out[i] = str } } return out, nil } stargz-snapshotter-0.14.3/service/service.go000066400000000000000000000115271440204344700211200ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package service import ( "context" "path/filepath" "github.com/containerd/containerd/log" "github.com/containerd/containerd/reference" "github.com/containerd/containerd/snapshots" "github.com/containerd/containerd/snapshots/overlay/overlayutils" stargzfs "github.com/containerd/stargz-snapshotter/fs" "github.com/containerd/stargz-snapshotter/fs/layer" "github.com/containerd/stargz-snapshotter/fs/source" "github.com/containerd/stargz-snapshotter/metadata" esgzexternaltoc "github.com/containerd/stargz-snapshotter/nativeconverter/estargz/externaltoc" "github.com/containerd/stargz-snapshotter/service/resolver" snbase "github.com/containerd/stargz-snapshotter/snapshot" "github.com/hashicorp/go-multierror" ocispec "github.com/opencontainers/image-spec/specs-go/v1" ) type Option func(*options) type options struct { credsFuncs []resolver.Credential registryHosts source.RegistryHosts fsOpts []stargzfs.Option } // WithCredsFuncs specifies credsFuncs to be used for connecting to the registries. func WithCredsFuncs(creds ...resolver.Credential) Option { return func(o *options) { o.credsFuncs = append(o.credsFuncs, creds...) } } // WithCustomRegistryHosts is registry hosts to use instead. func WithCustomRegistryHosts(hosts source.RegistryHosts) Option { return func(o *options) { o.registryHosts = hosts } } // WithFilesystemOptions allowes to pass filesystem-related configuration. func WithFilesystemOptions(opts ...stargzfs.Option) Option { return func(o *options) { o.fsOpts = opts } } // NewStargzSnapshotterService returns stargz snapshotter. func NewStargzSnapshotterService(ctx context.Context, root string, config *Config, opts ...Option) (snapshots.Snapshotter, error) { var sOpts options for _, o := range opts { o(&sOpts) } hosts := sOpts.registryHosts if hosts == nil { // Use RegistryHosts based on ResolverConfig and keychain hosts = resolver.RegistryHostsFromConfig(resolver.Config(config.ResolverConfig), sOpts.credsFuncs...) } userxattr, err := overlayutils.NeedsUserXAttr(snapshotterRoot(root)) if err != nil { log.G(ctx).WithError(err).Warnf("cannot detect whether \"userxattr\" option needs to be used, assuming to be %v", userxattr) } opq := layer.OverlayOpaqueTrusted if userxattr { opq = layer.OverlayOpaqueUser } // Configure filesystem and snapshotter fsOpts := append(sOpts.fsOpts, stargzfs.WithGetSources(sources( sourceFromCRILabels(hosts), // provides source info based on CRI labels source.FromDefaultLabels(hosts), // provides source info based on default labels )), stargzfs.WithOverlayOpaqueType(opq), stargzfs.WithAdditionalDecompressors(func(ctx context.Context, hosts source.RegistryHosts, refspec reference.Spec, desc ocispec.Descriptor) []metadata.Decompressor { return []metadata.Decompressor{esgzexternaltoc.NewRemoteDecompressor(ctx, hosts, refspec, desc)} }), ) fs, err := stargzfs.NewFilesystem(fsRoot(root), config.Config, fsOpts...) if err != nil { log.G(ctx).WithError(err).Fatalf("failed to configure filesystem") } var snapshotter snapshots.Snapshotter snOpts := []snbase.Opt{snbase.AsynchronousRemove} if config.SnapshotterConfig.AllowInvalidMountsOnRestart { snOpts = append(snOpts, snbase.AllowInvalidMountsOnRestart) } snapshotter, err = snbase.NewSnapshotter(ctx, snapshotterRoot(root), fs, snOpts...) if err != nil { log.G(ctx).WithError(err).Fatalf("failed to create new snapshotter") } return snapshotter, err } func snapshotterRoot(root string) string { return filepath.Join(root, "snapshotter") } func fsRoot(root string) string { return filepath.Join(root, "stargz") } func sources(ps ...source.GetSources) source.GetSources { return func(labels map[string]string) (source []source.Source, allErr error) { for _, p := range ps { src, err := p(labels) if err == nil { return src, nil } allErr = multierror.Append(allErr, err) } return } } // Supported returns nil when the remote snapshotter is functional on the system with the root directory. // Supported is not called during plugin initialization, but exposed for downstream projects which uses // this snapshotter as a library. func Supported(root string) error { // Remote snapshotter is implemented based on overlayfs snapshotter. return overlayutils.Supported(snapshotterRoot(root)) } stargz-snapshotter-0.14.3/snapshot/000077500000000000000000000000001440204344700173225ustar00rootroot00000000000000stargz-snapshotter-0.14.3/snapshot/snapshot.go000066400000000000000000000550571440204344700215240ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package snapshot import ( "context" "fmt" "os" "path/filepath" "strings" "syscall" "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/log" "github.com/containerd/containerd/mount" "github.com/containerd/containerd/snapshots" "github.com/containerd/containerd/snapshots/overlay/overlayutils" "github.com/containerd/containerd/snapshots/storage" "github.com/containerd/continuity/fs" "github.com/moby/sys/mountinfo" "github.com/sirupsen/logrus" "golang.org/x/sync/errgroup" ) const ( targetSnapshotLabel = "containerd.io/snapshot.ref" remoteLabel = "containerd.io/snapshot/remote" remoteLabelVal = "remote snapshot" // remoteSnapshotLogKey is a key for log line, which indicates whether // `Prepare` method successfully prepared targeting remote snapshot or not, as // defined in the following: // - "true" : indicates the snapshot has been successfully prepared as a // remote snapshot // - "false" : indicates the snapshot failed to be prepared as a remote // snapshot // - null : undetermined remoteSnapshotLogKey = "remote-snapshot-prepared" prepareSucceeded = "true" prepareFailed = "false" ) // FileSystem is a backing filesystem abstraction. // // Mount() tries to mount a remote snapshot to the specified mount point // directory. If succeed, the mountpoint directory will be treated as a layer // snapshot. If Mount() fails, the mountpoint directory MUST be cleaned up. // Check() is called to check the connectibity of the existing layer snapshot // every time the layer is used by containerd. // Unmount() is called to unmount a remote snapshot from the specified mount point // directory. type FileSystem interface { Mount(ctx context.Context, mountpoint string, labels map[string]string) error Check(ctx context.Context, mountpoint string, labels map[string]string) error Unmount(ctx context.Context, mountpoint string) error } // SnapshotterConfig is used to configure the remote snapshotter instance type SnapshotterConfig struct { asyncRemove bool noRestore bool allowInvalidMountsOnRestart bool } // Opt is an option to configure the remote snapshotter type Opt func(config *SnapshotterConfig) error // AsynchronousRemove defers removal of filesystem content until // the Cleanup method is called. Removals will make the snapshot // referred to by the key unavailable and make the key immediately // available for re-use. func AsynchronousRemove(config *SnapshotterConfig) error { config.asyncRemove = true return nil } func NoRestore(config *SnapshotterConfig) error { config.noRestore = true return nil } func AllowInvalidMountsOnRestart(config *SnapshotterConfig) error { config.allowInvalidMountsOnRestart = true return nil } type snapshotter struct { root string ms *storage.MetaStore asyncRemove bool // fs is a filesystem that this snapshotter recognizes. fs FileSystem userxattr bool // whether to enable "userxattr" mount option noRestore bool allowInvalidMountsOnRestart bool } // NewSnapshotter returns a Snapshotter which can use unpacked remote layers // as snapshots. This is implemented based on the overlayfs snapshotter, so // diffs are stored under the provided root and a metadata file is stored under // the root as same as overlayfs snapshotter. func NewSnapshotter(ctx context.Context, root string, targetFs FileSystem, opts ...Opt) (snapshots.Snapshotter, error) { if targetFs == nil { return nil, fmt.Errorf("Specify filesystem to use") } var config SnapshotterConfig for _, opt := range opts { if err := opt(&config); err != nil { return nil, err } } if err := os.MkdirAll(root, 0700); err != nil { return nil, err } supportsDType, err := fs.SupportsDType(root) if err != nil { return nil, err } if !supportsDType { return nil, fmt.Errorf("%s does not support d_type. If the backing filesystem is xfs, please reformat with ftype=1 to enable d_type support", root) } ms, err := storage.NewMetaStore(filepath.Join(root, "metadata.db")) if err != nil { return nil, err } if err := os.Mkdir(filepath.Join(root, "snapshots"), 0700); err != nil && !os.IsExist(err) { return nil, err } userxattr, err := overlayutils.NeedsUserXAttr(root) if err != nil { logrus.WithError(err).Warnf("cannot detect whether \"userxattr\" option needs to be used, assuming to be %v", userxattr) } o := &snapshotter{ root: root, ms: ms, asyncRemove: config.asyncRemove, fs: targetFs, userxattr: userxattr, noRestore: config.noRestore, allowInvalidMountsOnRestart: config.allowInvalidMountsOnRestart, } if err := o.restoreRemoteSnapshot(ctx); err != nil { return nil, fmt.Errorf("failed to restore remote snapshot: %w", err) } return o, nil } // Stat returns the info for an active or committed snapshot by name or // key. // // Should be used for parent resolution, existence checks and to discern // the kind of snapshot. func (o *snapshotter) Stat(ctx context.Context, key string) (snapshots.Info, error) { ctx, t, err := o.ms.TransactionContext(ctx, false) if err != nil { return snapshots.Info{}, err } defer t.Rollback() _, info, _, err := storage.GetInfo(ctx, key) if err != nil { return snapshots.Info{}, err } return info, nil } func (o *snapshotter) Update(ctx context.Context, info snapshots.Info, fieldpaths ...string) (snapshots.Info, error) { ctx, t, err := o.ms.TransactionContext(ctx, true) if err != nil { return snapshots.Info{}, err } info, err = storage.UpdateInfo(ctx, info, fieldpaths...) if err != nil { t.Rollback() return snapshots.Info{}, err } if err := t.Commit(); err != nil { return snapshots.Info{}, err } return info, nil } // Usage returns the resources taken by the snapshot identified by key. // // For active snapshots, this will scan the usage of the overlay "diff" (aka // "upper") directory and may take some time. // for remote snapshots, no scan will be held and recognise the number of inodes // and these sizes as "zero". // // For committed snapshots, the value is returned from the metadata database. func (o *snapshotter) Usage(ctx context.Context, key string) (snapshots.Usage, error) { ctx, t, err := o.ms.TransactionContext(ctx, false) if err != nil { return snapshots.Usage{}, err } id, info, usage, err := storage.GetInfo(ctx, key) t.Rollback() // transaction no longer needed at this point. if err != nil { return snapshots.Usage{}, err } upperPath := o.upperPath(id) if info.Kind == snapshots.KindActive { du, err := fs.DiskUsage(ctx, upperPath) if err != nil { // TODO(stevvooe): Consider not reporting an error in this case. return snapshots.Usage{}, err } usage = snapshots.Usage(du) } return usage, nil } func (o *snapshotter) Prepare(ctx context.Context, key, parent string, opts ...snapshots.Opt) ([]mount.Mount, error) { s, err := o.createSnapshot(ctx, snapshots.KindActive, key, parent, opts) if err != nil { return nil, err } // Try to prepare the remote snapshot. If succeeded, we commit the snapshot now // and return ErrAlreadyExists. var base snapshots.Info for _, opt := range opts { if err := opt(&base); err != nil { return nil, err } } if target, ok := base.Labels[targetSnapshotLabel]; ok { // NOTE: If passed labels include a target of the remote snapshot, `Prepare` // must log whether this method succeeded to prepare that remote snapshot // or not, using the key `remoteSnapshotLogKey` defined in the above. This // log is used by tests in this project. lCtx := log.WithLogger(ctx, log.G(ctx).WithField("key", key).WithField("parent", parent)) if err := o.prepareRemoteSnapshot(lCtx, key, base.Labels); err != nil { log.G(lCtx).WithField(remoteSnapshotLogKey, prepareFailed). WithError(err).Warn("failed to prepare remote snapshot") } else { base.Labels[remoteLabel] = remoteLabelVal // Mark this snapshot as remote err := o.commit(ctx, true, target, key, append(opts, snapshots.WithLabels(base.Labels))...) if err == nil || errdefs.IsAlreadyExists(err) { // count also AlreadyExists as "success" log.G(lCtx).WithField(remoteSnapshotLogKey, prepareSucceeded).Debug("prepared remote snapshot") return nil, fmt.Errorf("target snapshot %q: %w", target, errdefs.ErrAlreadyExists) } log.G(lCtx).WithField(remoteSnapshotLogKey, prepareFailed). WithError(err).Warn("failed to internally commit remote snapshot") // Don't fallback here (= prohibit to use this key again) because the FileSystem // possible has done some work on this "upper" directory. return nil, err } } return o.mounts(ctx, s, parent) } func (o *snapshotter) View(ctx context.Context, key, parent string, opts ...snapshots.Opt) ([]mount.Mount, error) { s, err := o.createSnapshot(ctx, snapshots.KindView, key, parent, opts) if err != nil { return nil, err } return o.mounts(ctx, s, parent) } // Mounts returns the mounts for the transaction identified by key. Can be // called on an read-write or readonly transaction. // // This can be used to recover mounts after calling View or Prepare. func (o *snapshotter) Mounts(ctx context.Context, key string) ([]mount.Mount, error) { ctx, t, err := o.ms.TransactionContext(ctx, false) if err != nil { return nil, err } s, err := storage.GetSnapshot(ctx, key) t.Rollback() if err != nil { return nil, fmt.Errorf("failed to get active mount: %w", err) } return o.mounts(ctx, s, key) } func (o *snapshotter) Commit(ctx context.Context, name, key string, opts ...snapshots.Opt) error { return o.commit(ctx, false, name, key, opts...) } func (o *snapshotter) commit(ctx context.Context, isRemote bool, name, key string, opts ...snapshots.Opt) error { ctx, t, err := o.ms.TransactionContext(ctx, true) if err != nil { return err } defer func() { if err != nil { if rerr := t.Rollback(); rerr != nil { log.G(ctx).WithError(rerr).Warn("failed to rollback transaction") } } }() // grab the existing id id, _, usage, err := storage.GetInfo(ctx, key) if err != nil { return err } if !isRemote { // skip diskusage for remote snapshots for allowing lazy preparation of nodes du, err := fs.DiskUsage(ctx, o.upperPath(id)) if err != nil { return err } usage = snapshots.Usage(du) } if _, err = storage.CommitActive(ctx, key, name, usage, opts...); err != nil { return fmt.Errorf("failed to commit snapshot: %w", err) } return t.Commit() } // Remove abandons the snapshot identified by key. The snapshot will // immediately become unavailable and unrecoverable. Disk space will // be freed up on the next call to `Cleanup`. func (o *snapshotter) Remove(ctx context.Context, key string) (err error) { ctx, t, err := o.ms.TransactionContext(ctx, true) if err != nil { return err } defer func() { if err != nil { if rerr := t.Rollback(); rerr != nil { log.G(ctx).WithError(rerr).Warn("failed to rollback transaction") } } }() _, _, err = storage.Remove(ctx, key) if err != nil { return fmt.Errorf("failed to remove: %w", err) } if !o.asyncRemove { var removals []string const cleanupCommitted = false removals, err = o.getCleanupDirectories(ctx, t, cleanupCommitted) if err != nil { return fmt.Errorf("unable to get directories for removal: %w", err) } // Remove directories after the transaction is closed, failures must not // return error since the transaction is committed with the removal // key no longer available. defer func() { if err == nil { for _, dir := range removals { if err := o.cleanupSnapshotDirectory(ctx, dir); err != nil { log.G(ctx).WithError(err).WithField("path", dir).Warn("failed to remove directory") } } } }() } return t.Commit() } // Walk the snapshots. func (o *snapshotter) Walk(ctx context.Context, fn snapshots.WalkFunc, fs ...string) error { ctx, t, err := o.ms.TransactionContext(ctx, false) if err != nil { return err } defer t.Rollback() return storage.WalkInfo(ctx, fn, fs...) } // Cleanup cleans up disk resources from removed or abandoned snapshots func (o *snapshotter) Cleanup(ctx context.Context) error { const cleanupCommitted = false return o.cleanup(ctx, cleanupCommitted) } func (o *snapshotter) cleanup(ctx context.Context, cleanupCommitted bool) error { cleanup, err := o.cleanupDirectories(ctx, cleanupCommitted) if err != nil { return err } log.G(ctx).Debugf("cleanup: dirs=%v", cleanup) for _, dir := range cleanup { if err := o.cleanupSnapshotDirectory(ctx, dir); err != nil { log.G(ctx).WithError(err).WithField("path", dir).Warn("failed to remove directory") } } return nil } func (o *snapshotter) cleanupDirectories(ctx context.Context, cleanupCommitted bool) ([]string, error) { // Get a write transaction to ensure no other write transaction can be entered // while the cleanup is scanning. ctx, t, err := o.ms.TransactionContext(ctx, true) if err != nil { return nil, err } defer t.Rollback() return o.getCleanupDirectories(ctx, t, cleanupCommitted) } func (o *snapshotter) getCleanupDirectories(ctx context.Context, t storage.Transactor, cleanupCommitted bool) ([]string, error) { ids, err := storage.IDMap(ctx) if err != nil { return nil, err } snapshotDir := filepath.Join(o.root, "snapshots") fd, err := os.Open(snapshotDir) if err != nil { return nil, err } defer fd.Close() dirs, err := fd.Readdirnames(0) if err != nil { return nil, err } cleanup := []string{} for _, d := range dirs { if !cleanupCommitted { if _, ok := ids[d]; ok { continue } } cleanup = append(cleanup, filepath.Join(snapshotDir, d)) } return cleanup, nil } func (o *snapshotter) cleanupSnapshotDirectory(ctx context.Context, dir string) error { // On a remote snapshot, the layer is mounted on the "fs" directory. // We use Filesystem's Unmount API so that it can do necessary finalization // before/after the unmount. mp := filepath.Join(dir, "fs") if err := o.fs.Unmount(ctx, mp); err != nil { log.G(ctx).WithError(err).WithField("dir", mp).Debug("failed to unmount") } if err := os.RemoveAll(dir); err != nil { return fmt.Errorf("failed to remove directory %q: %w", dir, err) } return nil } func (o *snapshotter) createSnapshot(ctx context.Context, kind snapshots.Kind, key, parent string, opts []snapshots.Opt) (_ storage.Snapshot, err error) { ctx, t, err := o.ms.TransactionContext(ctx, true) if err != nil { return storage.Snapshot{}, err } var td, path string defer func() { if err != nil { if td != "" { if err1 := o.cleanupSnapshotDirectory(ctx, td); err1 != nil { log.G(ctx).WithError(err1).Warn("failed to cleanup temp snapshot directory") } } if path != "" { if err1 := o.cleanupSnapshotDirectory(ctx, path); err1 != nil { log.G(ctx).WithError(err1).WithField("path", path).Error("failed to reclaim snapshot directory, directory may need removal") err = fmt.Errorf("failed to remove path: %v: %w", err1, err) } } } }() snapshotDir := filepath.Join(o.root, "snapshots") td, err = o.prepareDirectory(ctx, snapshotDir, kind) if err != nil { if rerr := t.Rollback(); rerr != nil { log.G(ctx).WithError(rerr).Warn("failed to rollback transaction") } return storage.Snapshot{}, fmt.Errorf("failed to create prepare snapshot dir: %w", err) } rollback := true defer func() { if rollback { if rerr := t.Rollback(); rerr != nil { log.G(ctx).WithError(rerr).Warn("failed to rollback transaction") } } }() s, err := storage.CreateSnapshot(ctx, kind, key, parent, opts...) if err != nil { return storage.Snapshot{}, fmt.Errorf("failed to create snapshot: %w", err) } if len(s.ParentIDs) > 0 { st, err := os.Stat(o.upperPath(s.ParentIDs[0])) if err != nil { return storage.Snapshot{}, fmt.Errorf("failed to stat parent: %w", err) } stat := st.Sys().(*syscall.Stat_t) if err := os.Lchown(filepath.Join(td, "fs"), int(stat.Uid), int(stat.Gid)); err != nil { if rerr := t.Rollback(); rerr != nil { log.G(ctx).WithError(rerr).Warn("failed to rollback transaction") } return storage.Snapshot{}, fmt.Errorf("failed to chown: %w", err) } } path = filepath.Join(snapshotDir, s.ID) if err = os.Rename(td, path); err != nil { return storage.Snapshot{}, fmt.Errorf("failed to rename: %w", err) } td = "" rollback = false if err = t.Commit(); err != nil { return storage.Snapshot{}, fmt.Errorf("commit failed: %w", err) } return s, nil } func (o *snapshotter) prepareDirectory(ctx context.Context, snapshotDir string, kind snapshots.Kind) (string, error) { td, err := os.MkdirTemp(snapshotDir, "new-") if err != nil { return "", fmt.Errorf("failed to create temp dir: %w", err) } if err := os.Mkdir(filepath.Join(td, "fs"), 0755); err != nil { return td, err } if kind == snapshots.KindActive { if err := os.Mkdir(filepath.Join(td, "work"), 0711); err != nil { return td, err } } return td, nil } func (o *snapshotter) mounts(ctx context.Context, s storage.Snapshot, checkKey string) ([]mount.Mount, error) { // Make sure that all layers lower than the target layer are available if checkKey != "" && !o.checkAvailability(ctx, checkKey) { return nil, fmt.Errorf("layer %q unavailable: %w", s.ID, errdefs.ErrUnavailable) } if len(s.ParentIDs) == 0 { // if we only have one layer/no parents then just return a bind mount as overlay // will not work roFlag := "rw" if s.Kind == snapshots.KindView { roFlag = "ro" } return []mount.Mount{ { Source: o.upperPath(s.ID), Type: "bind", Options: []string{ roFlag, "rbind", }, }, }, nil } var options []string if s.Kind == snapshots.KindActive { options = append(options, fmt.Sprintf("workdir=%s", o.workPath(s.ID)), fmt.Sprintf("upperdir=%s", o.upperPath(s.ID)), ) } else if len(s.ParentIDs) == 1 { return []mount.Mount{ { Source: o.upperPath(s.ParentIDs[0]), Type: "bind", Options: []string{ "ro", "rbind", }, }, }, nil } parentPaths := make([]string, len(s.ParentIDs)) for i := range s.ParentIDs { parentPaths[i] = o.upperPath(s.ParentIDs[i]) } options = append(options, fmt.Sprintf("lowerdir=%s", strings.Join(parentPaths, ":"))) if o.userxattr { options = append(options, "userxattr") } return []mount.Mount{ { Type: "overlay", Source: "overlay", Options: options, }, }, nil } func (o *snapshotter) upperPath(id string) string { return filepath.Join(o.root, "snapshots", id, "fs") } func (o *snapshotter) workPath(id string) string { return filepath.Join(o.root, "snapshots", id, "work") } // Close closes the snapshotter func (o *snapshotter) Close() error { // unmount all mounts including Committed const cleanupCommitted = true ctx := context.Background() if err := o.cleanup(ctx, cleanupCommitted); err != nil { log.G(ctx).WithError(err).Warn("failed to cleanup") } return o.ms.Close() } // prepareRemoteSnapshot tries to prepare the snapshot as a remote snapshot // using filesystems registered in this snapshotter. func (o *snapshotter) prepareRemoteSnapshot(ctx context.Context, key string, labels map[string]string) error { ctx, t, err := o.ms.TransactionContext(ctx, false) if err != nil { return err } defer t.Rollback() id, _, _, err := storage.GetInfo(ctx, key) if err != nil { return err } mountpoint := o.upperPath(id) log.G(ctx).Infof("preparing filesystem mount at mountpoint=%v", mountpoint) return o.fs.Mount(ctx, mountpoint, labels) } // checkAvailability checks avaiability of the specified layer and all lower // layers using filesystem's checking functionality. func (o *snapshotter) checkAvailability(ctx context.Context, key string) bool { ctx = log.WithLogger(ctx, log.G(ctx).WithField("key", key)) log.G(ctx).Debug("checking layer availability") ctx, t, err := o.ms.TransactionContext(ctx, false) if err != nil { log.G(ctx).WithError(err).Warn("failed to get transaction") return false } defer t.Rollback() eg, egCtx := errgroup.WithContext(ctx) for cKey := key; cKey != ""; { id, info, _, err := storage.GetInfo(ctx, cKey) if err != nil { log.G(ctx).WithError(err).Warnf("failed to get info of %q", cKey) return false } mp := o.upperPath(id) lCtx := log.WithLogger(ctx, log.G(ctx).WithField("mount-point", mp)) if _, ok := info.Labels[remoteLabel]; ok { eg.Go(func() error { log.G(lCtx).Debug("checking mount point") if err := o.fs.Check(egCtx, mp, info.Labels); err != nil { log.G(lCtx).WithError(err).Warn("layer is unavailable") return err } return nil }) } else { log.G(lCtx).Debug("layer is normal snapshot(overlayfs)") } cKey = info.Parent } if err := eg.Wait(); err != nil { return false } return true } func (o *snapshotter) restoreRemoteSnapshot(ctx context.Context) error { mounts, err := mountinfo.GetMounts(nil) if err != nil { return err } for _, m := range mounts { if strings.HasPrefix(m.Mountpoint, filepath.Join(o.root, "snapshots")) { if err := syscall.Unmount(m.Mountpoint, syscall.MNT_FORCE); err != nil { return fmt.Errorf("failed to unmount %s: %w", m.Mountpoint, err) } } } if o.noRestore { return nil } var task []snapshots.Info if err := o.Walk(ctx, func(ctx context.Context, info snapshots.Info) error { if _, ok := info.Labels[remoteLabel]; ok { task = append(task, info) } return nil }); err != nil && !errdefs.IsNotFound(err) { return err } for _, info := range task { if err := o.prepareRemoteSnapshot(ctx, info.Name, info.Labels); err != nil { if o.allowInvalidMountsOnRestart { logrus.WithError(err).Warnf("failed to restore remote snapshot %s; remove this snapshot manually", info.Name) // This snapshot mount is invalid but allow this. // NOTE: snapshotter.Mount() will fail to return the mountpoint of these invalid snapshots so // containerd cannot use them anymore. User needs to manually remove the snapshots from // containerd's metadata store using ctr (e.g. `ctr snapshot rm`). continue } return fmt.Errorf("failed to prepare remote snapshot: %s: %w", info.Name, err) } } return nil } stargz-snapshotter-0.14.3/snapshot/snapshot_test.go000066400000000000000000000440331440204344700225530ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package snapshot import ( "context" _ "crypto/sha256" "fmt" "os" "path/filepath" "syscall" "testing" "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/mount" "github.com/containerd/containerd/pkg/testutil" "github.com/containerd/containerd/snapshots" "github.com/containerd/containerd/snapshots/storage" "github.com/containerd/containerd/snapshots/testsuite" ) const ( remoteSampleFile = "foo" remoteSampleFileContents = "remote layer" brokenLabel = "containerd.io/snapshot/broken" ) func prepareWithTarget(t *testing.T, sn snapshots.Snapshotter, target, key, parent string, labels map[string]string) string { ctx := context.TODO() if labels == nil { labels = make(map[string]string) } labels[targetSnapshotLabel] = target if _, err := sn.Prepare(ctx, key, parent, snapshots.WithLabels(labels)); !errdefs.IsAlreadyExists(err) { t.Fatalf("failed to prepare remote snapshot: %v", err) } return target } func TestRemotePrepare(t *testing.T) { testutil.RequiresRoot(t) ctx := context.TODO() root, err := os.MkdirTemp("", "overlay") if err != nil { t.Fatal(err) } defer os.RemoveAll(root) sn, err := NewSnapshotter(context.TODO(), root, bindFileSystem(t)) if err != nil { t.Fatalf("failed to make new remote snapshotter: %q", err) } // Prepare a remote snapshot. target := prepareWithTarget(t, sn, "testTarget", "/tmp/prepareTarget", "", nil) defer sn.Remove(ctx, target) // Get internally committed remote snapshot. var tinfo *snapshots.Info if err := sn.Walk(ctx, func(ctx context.Context, i snapshots.Info) error { if tinfo == nil && i.Kind == snapshots.KindCommitted { if i.Labels[targetSnapshotLabel] != target { return nil } if i.Parent != "" { return nil } tinfo = &i } return nil }); err != nil { t.Fatalf("failed to get remote snapshot: %v", err) } if tinfo == nil { t.Fatalf("prepared remote snapshot %q not found", target) } // Stat and validate the remote snapshot. info, err := sn.Stat(ctx, tinfo.Name) if err != nil { t.Fatal("failed to stat remote snapshot") } if info.Kind != snapshots.KindCommitted { t.Errorf("snapshot Kind is %q; want %q", info.Kind, snapshots.KindCommitted) } if label, ok := info.Labels[targetSnapshotLabel]; !ok || label != target { t.Errorf("remote snapshot hasn't valid remote label: %q", label) } } func TestRemoteOverlay(t *testing.T) { testutil.RequiresRoot(t) ctx := context.TODO() root, err := os.MkdirTemp("", "remote") if err != nil { t.Fatal(err) } defer os.RemoveAll(root) sn, err := NewSnapshotter(context.TODO(), root, bindFileSystem(t)) if err != nil { t.Fatalf("failed to make new remote snapshotter: %q", err) } // Prepare a remote snapshot. target := prepareWithTarget(t, sn, "testTarget", "/tmp/prepareTarget", "", nil) defer sn.Remove(ctx, target) // Prepare a new layer based on the remote snapshot. pKey := "/tmp/test" mounts, err := sn.Prepare(ctx, pKey, target) if err != nil { t.Fatalf("faild to prepare using lower remote layer: %v", err) } if len(mounts) != 1 { t.Errorf("should only have 1 mount but received %d", len(mounts)) } m := mounts[0] if m.Type != "overlay" { t.Errorf("mount type should be overlay but received %q", m.Type) } if m.Source != "overlay" { t.Errorf("expected source %q but received %q", "overlay", m.Source) } var ( bp = getBasePath(ctx, sn, root, pKey) work = "workdir=" + filepath.Join(bp, "work") upper = "upperdir=" + filepath.Join(bp, "fs") lower = "lowerdir=" + getParents(ctx, sn, root, pKey)[0] ) for i, v := range []string{ work, upper, lower, } { if m.Options[i] != v { t.Errorf("expected %q but received %q", v, m.Options[i]) } } // Validate the contents of the snapshot data, err := os.ReadFile(filepath.Join(getParents(ctx, sn, root, pKey)[0], remoteSampleFile)) if err != nil { t.Fatalf("failed to read a file in the remote snapshot: %v", err) } if e := string(data); e != remoteSampleFileContents { t.Fatalf("expected file contents %q but got %q", remoteSampleFileContents, e) } } func TestRemoteCommit(t *testing.T) { testutil.RequiresRoot(t) ctx := context.TODO() root, err := os.MkdirTemp("", "remote") if err != nil { t.Fatal(err) } defer os.RemoveAll(root) sn, err := NewSnapshotter(context.TODO(), root, bindFileSystem(t)) if err != nil { t.Fatalf("failed to make new remote snapshotter: %q", err) } // Prepare a remote snapshot. target := prepareWithTarget(t, sn, "testTarget", "/tmp/prepareTarget", "", nil) defer sn.Remove(ctx, target) // Prepare a new snapshot based on the remote snapshot pKey := "/tmp/test" mounts, err := sn.Prepare(ctx, pKey, target) if err != nil { t.Fatal(err) } // Make a new active snapshot based on the remote snapshot. snapshot, err := os.MkdirTemp("", "snapshot") if err != nil { t.Fatal(err) } defer os.RemoveAll(snapshot) m := mounts[0] if err := m.Mount(snapshot); err != nil { t.Fatal(err) } defer mount.Unmount(snapshot, 0) if err := os.WriteFile(filepath.Join(snapshot, "bar"), []byte("hi"), 0660); err != nil { t.Fatal(err) } mount.Unmount(snapshot, 0) // Commit the active snapshot cKey := "/tmp/layer" if err := sn.Commit(ctx, cKey, pKey); err != nil { t.Fatal(err) } // Validate the committed snapshot check, err := os.MkdirTemp("", "check") if err != nil { t.Fatal(err) } defer os.RemoveAll(check) mounts, err = sn.Prepare(ctx, "/tmp/test2", cKey) if err != nil { t.Fatal(err) } m = mounts[0] if err := m.Mount(check); err != nil { t.Fatal(err) } defer mount.Unmount(check, 0) data, err := os.ReadFile(filepath.Join(check, "bar")) if err != nil { t.Fatal(err) } if e := string(data); e != "hi" { t.Fatalf("expected file contents %q but got %q", "hi", e) } } func TestFailureDetection(t *testing.T) { testutil.RequiresRoot(t) tests := []struct { name string broken []bool // top element is the lowest layer overlay bool // whether appending the topmost normal overlay snapshot or not wantOK bool }{ { name: "flat_ok", broken: []bool{false}, wantOK: true, }, { name: "deep_ok", broken: []bool{false, false, false}, wantOK: true, }, { name: "flat_overlay_ok", broken: []bool{false}, overlay: true, wantOK: true, }, { name: "deep_overlay_ok", broken: []bool{false, false, false}, overlay: true, wantOK: true, }, { name: "flat_ng", broken: []bool{true}, wantOK: false, }, { name: "deep_ng", broken: []bool{false, true, false}, wantOK: false, }, { name: "flat_overlay_ng", broken: []bool{true}, overlay: true, wantOK: false, }, { name: "deep_overlay_ng", broken: []bool{false, true, false}, overlay: true, wantOK: false, }, } check := func(t *testing.T, ok bool, err error) bool { if err == nil { if !ok { t.Error("check all passed but wanted to be failed") return false } } else if errdefs.IsUnavailable(err) { if ok { t.Error("got Unavailable but wanted to be non-error") return false } } else { t.Errorf("got unexpected error %q", err) return false } return true } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { ctx := context.TODO() root, err := os.MkdirTemp("", "remote") if err != nil { t.Fatal(err) } defer os.RemoveAll(root) fi := bindFileSystem(t) sn, err := NewSnapshotter(context.TODO(), root, fi) if err != nil { t.Fatalf("failed to make new Snapshotter: %q", err) } fs, ok := fi.(*bindFs) if !ok { t.Fatalf("Invalid filesystem type(not *filesystem)") } // Prepare snapshots fs.checkFailure = false pKey := "" for i, broken := range tt.broken { var ( targetName = fmt.Sprintf("/tmp/testTarget%d", i) key = fmt.Sprintf("/tmp/testKey%d", i) labels = make(map[string]string) ) if broken { labels[brokenLabel] = "true" } target := prepareWithTarget(t, sn, targetName, key, pKey, labels) defer sn.Remove(ctx, target) pKey = target } if tt.overlay { key := "/tmp/test" _, err := sn.Prepare(ctx, key, pKey) if err != nil { t.Fatal(err) } cKey := "/tmp/layer" if err := sn.Commit(ctx, cKey, key); err != nil { t.Fatal(err) } defer sn.Remove(ctx, cKey) pKey = cKey } // Tests if we can detect layer unavailablity key := "/tmp/snapshot.test" fs.checkFailure = true defer sn.Remove(ctx, key) if _, err := sn.Prepare(ctx, key, pKey); !check(t, tt.wantOK, err) { return } fs.checkFailure = false key2 := "/tmp/test2" if _, err = sn.Prepare(ctx, key2, pKey); err != nil { t.Fatal(err) } defer sn.Remove(ctx, key2) fs.checkFailure = true if _, err := sn.Mounts(ctx, key2); !check(t, tt.wantOK, err) { return } }) } } func bindFileSystem(t *testing.T) FileSystem { root, err := os.MkdirTemp("", "remote") if err != nil { t.Fatalf("failed to prepare working-space for bind filesystem: %q", err) } if err := os.WriteFile(filepath.Join(root, remoteSampleFile), []byte(remoteSampleFileContents), 0660); err != nil { t.Fatalf("failed to write sample file of bind filesystem: %q", err) } return &bindFs{ root: root, t: t, broken: make(map[string]bool), } } type bindFs struct { t *testing.T root string checkFailure bool broken map[string]bool } func (fs *bindFs) Mount(ctx context.Context, mountpoint string, labels map[string]string) error { if _, ok := labels[brokenLabel]; ok { fs.broken[mountpoint] = true } if err := syscall.Mount(fs.root, mountpoint, "none", syscall.MS_BIND, ""); err != nil { fs.t.Fatalf("failed to bind mount %q to %q: %v", fs.root, mountpoint, err) } return nil } func (fs *bindFs) Check(ctx context.Context, mountpoint string, labels map[string]string) error { if fs.checkFailure { if broken, ok := fs.broken[mountpoint]; ok && broken { return fmt.Errorf("broken") } } return nil } func (fs *bindFs) Unmount(ctx context.Context, mountpoint string) error { return syscall.Unmount(mountpoint, 0) } func dummyFileSystem() FileSystem { return &dummyFs{} } type dummyFs struct{} func (fs *dummyFs) Mount(ctx context.Context, mountpoint string, labels map[string]string) error { return fmt.Errorf("dummy") } func (fs *dummyFs) Check(ctx context.Context, mountpoint string, labels map[string]string) error { return fmt.Errorf("dummy") } func (fs *dummyFs) Unmount(ctx context.Context, mountpoint string) error { return fmt.Errorf("dummy") } // ============================================================================= // Tests backword-comaptibility of overlayfs snapshotter. func newSnapshotter(ctx context.Context, root string) (snapshots.Snapshotter, func() error, error) { snapshotter, err := NewSnapshotter(context.TODO(), root, dummyFileSystem()) if err != nil { return nil, nil, err } return snapshotter, func() error { return snapshotter.Close() }, nil } func TestOverlay(t *testing.T) { testutil.RequiresRoot(t) testsuite.SnapshotterSuite(t, "Overlay", newSnapshotter) } func TestOverlayMounts(t *testing.T) { ctx := context.TODO() root, err := os.MkdirTemp("", "overlay") if err != nil { t.Fatal(err) } defer os.RemoveAll(root) o, _, err := newSnapshotter(ctx, root) if err != nil { t.Fatal(err) } mounts, err := o.Prepare(ctx, "/tmp/test", "") if err != nil { t.Fatal(err) } if len(mounts) != 1 { t.Errorf("should only have 1 mount but received %d", len(mounts)) } m := mounts[0] if m.Type != "bind" { t.Errorf("mount type should be bind but received %q", m.Type) } expected := filepath.Join(root, "snapshots", "1", "fs") if m.Source != expected { t.Errorf("expected source %q but received %q", expected, m.Source) } if m.Options[0] != "rw" { t.Errorf("expected mount option rw but received %q", m.Options[0]) } if m.Options[1] != "rbind" { t.Errorf("expected mount option rbind but received %q", m.Options[1]) } } func TestOverlayCommit(t *testing.T) { ctx := context.TODO() root, err := os.MkdirTemp("", "overlay") if err != nil { t.Fatal(err) } defer os.RemoveAll(root) o, _, err := newSnapshotter(ctx, root) if err != nil { t.Fatal(err) } key := "/tmp/test" mounts, err := o.Prepare(ctx, key, "") if err != nil { t.Fatal(err) } m := mounts[0] if err := os.WriteFile(filepath.Join(m.Source, "foo"), []byte("hi"), 0660); err != nil { t.Fatal(err) } if err := o.Commit(ctx, "base", key); err != nil { t.Fatal(err) } } func TestOverlayOverlayMount(t *testing.T) { ctx := context.TODO() root, err := os.MkdirTemp("", "overlay") if err != nil { t.Fatal(err) } defer os.RemoveAll(root) o, _, err := newSnapshotter(ctx, root) if err != nil { t.Fatal(err) } key := "/tmp/test" if _, err = o.Prepare(ctx, key, ""); err != nil { t.Fatal(err) } if err := o.Commit(ctx, "base", key); err != nil { t.Fatal(err) } var mounts []mount.Mount if mounts, err = o.Prepare(ctx, "/tmp/layer2", "base"); err != nil { t.Fatal(err) } if len(mounts) != 1 { t.Errorf("should only have 1 mount but received %d", len(mounts)) } m := mounts[0] if m.Type != "overlay" { t.Errorf("mount type should be overlay but received %q", m.Type) } if m.Source != "overlay" { t.Errorf("expected source %q but received %q", "overlay", m.Source) } var ( bp = getBasePath(ctx, o, root, "/tmp/layer2") work = "workdir=" + filepath.Join(bp, "work") upper = "upperdir=" + filepath.Join(bp, "fs") lower = "lowerdir=" + getParents(ctx, o, root, "/tmp/layer2")[0] ) for i, v := range []string{ work, upper, lower, } { if m.Options[i] != v { t.Errorf("expected %q but received %q", v, m.Options[i]) } } } func getBasePath(ctx context.Context, sn snapshots.Snapshotter, root, key string) string { o := sn.(*snapshotter) ctx, t, err := o.ms.TransactionContext(ctx, false) if err != nil { panic(err) } defer t.Rollback() s, err := storage.GetSnapshot(ctx, key) if err != nil { panic(err) } return filepath.Join(root, "snapshots", s.ID) } func getParents(ctx context.Context, sn snapshots.Snapshotter, root, key string) []string { o := sn.(*snapshotter) ctx, t, err := o.ms.TransactionContext(ctx, false) if err != nil { panic(err) } defer t.Rollback() s, err := storage.GetSnapshot(ctx, key) if err != nil { panic(err) } parents := make([]string, len(s.ParentIDs)) for i := range s.ParentIDs { parents[i] = filepath.Join(root, "snapshots", s.ParentIDs[i], "fs") } return parents } func TestOverlayOverlayRead(t *testing.T) { testutil.RequiresRoot(t) ctx := context.TODO() root, err := os.MkdirTemp("", "overlay") if err != nil { t.Fatal(err) } defer os.RemoveAll(root) o, _, err := newSnapshotter(ctx, root) if err != nil { t.Fatal(err) } key := "/tmp/test" mounts, err := o.Prepare(ctx, key, "") if err != nil { t.Fatal(err) } m := mounts[0] if err := os.WriteFile(filepath.Join(m.Source, "foo"), []byte("hi"), 0660); err != nil { t.Fatal(err) } if err := o.Commit(ctx, "base", key); err != nil { t.Fatal(err) } if mounts, err = o.Prepare(ctx, "/tmp/layer2", "base"); err != nil { t.Fatal(err) } dest := filepath.Join(root, "dest") if err := os.Mkdir(dest, 0700); err != nil { t.Fatal(err) } if err := mount.All(mounts, dest); err != nil { t.Fatal(err) } defer syscall.Unmount(dest, 0) data, err := os.ReadFile(filepath.Join(dest, "foo")) if err != nil { t.Fatal(err) } if e := string(data); e != "hi" { t.Fatalf("expected file contents hi but got %q", e) } } func TestOverlayView(t *testing.T) { ctx := context.TODO() root, err := os.MkdirTemp("", "overlay") if err != nil { t.Fatal(err) } defer os.RemoveAll(root) o, _, err := newSnapshotter(ctx, root) if err != nil { t.Fatal(err) } key := "/tmp/base" mounts, err := o.Prepare(ctx, key, "") if err != nil { t.Fatal(err) } m := mounts[0] if err := os.WriteFile(filepath.Join(m.Source, "foo"), []byte("hi"), 0660); err != nil { t.Fatal(err) } if err := o.Commit(ctx, "base", key); err != nil { t.Fatal(err) } key = "/tmp/top" _, err = o.Prepare(ctx, key, "base") if err != nil { t.Fatal(err) } if err := os.WriteFile(filepath.Join(getParents(ctx, o, root, "/tmp/top")[0], "foo"), []byte("hi, again"), 0660); err != nil { t.Fatal(err) } if err := o.Commit(ctx, "top", key); err != nil { t.Fatal(err) } mounts, err = o.View(ctx, "/tmp/view1", "base") if err != nil { t.Fatal(err) } if len(mounts) != 1 { t.Fatalf("should only have 1 mount but received %d", len(mounts)) } m = mounts[0] if m.Type != "bind" { t.Errorf("mount type should be bind but received %q", m.Type) } expected := getParents(ctx, o, root, "/tmp/view1")[0] if m.Source != expected { t.Errorf("expected source %q but received %q", expected, m.Source) } if m.Options[0] != "ro" { t.Errorf("expected mount option ro but received %q", m.Options[0]) } if m.Options[1] != "rbind" { t.Errorf("expected mount option rbind but received %q", m.Options[1]) } mounts, err = o.View(ctx, "/tmp/view2", "top") if err != nil { t.Fatal(err) } if len(mounts) != 1 { t.Fatalf("should only have 1 mount but received %d", len(mounts)) } m = mounts[0] if m.Type != "overlay" { t.Errorf("mount type should be overlay but received %q", m.Type) } if m.Source != "overlay" { t.Errorf("mount source should be overlay but received %q", m.Source) } if len(m.Options) != 1 { t.Errorf("expected 1 mount option but got %d", len(m.Options)) } lowers := getParents(ctx, o, root, "/tmp/view2") expected = fmt.Sprintf("lowerdir=%s:%s", lowers[0], lowers[1]) if m.Options[0] != expected { t.Errorf("expected option %q but received %q", expected, m.Options[0]) } } stargz-snapshotter-0.14.3/store/000077500000000000000000000000001440204344700166175ustar00rootroot00000000000000stargz-snapshotter-0.14.3/store/fs.go000066400000000000000000000425641440204344700175710ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package store import ( "bytes" "context" "encoding/base64" "encoding/json" "errors" "fmt" "io" "os/exec" "sync" "syscall" "time" "github.com/containerd/containerd/log" "github.com/containerd/containerd/reference" "github.com/containerd/stargz-snapshotter/cache" "github.com/containerd/stargz-snapshotter/fs/layer" "github.com/containerd/stargz-snapshotter/fs/remote" fusefs "github.com/hanwen/go-fuse/v2/fs" "github.com/hanwen/go-fuse/v2/fuse" digest "github.com/opencontainers/go-digest" "golang.org/x/sync/singleflight" ) const ( defaultLinkMode = syscall.S_IFLNK | 0400 // -r-------- defaultDirMode = syscall.S_IFDIR | 0500 // dr-x------ defaultFileMode = 0400 // -r-------- layerFileMode = 0400 // -r-------- blockSize = 4096 poolLink = "pool" layerLink = "diff" blobLink = "blob" layerInfoLink = "info" layerUseFile = "use" fusermountBin = "fusermount" ) func Mount(ctx context.Context, mountpoint string, layerManager *LayerManager, debug bool) error { timeSec := time.Second rawFS := fusefs.NewNodeFS(&rootnode{ fs: &fs{ layerManager: layerManager, nodeMap: new(idMap), layerMap: new(idMap), }, }, &fusefs.Options{ AttrTimeout: &timeSec, EntryTimeout: &timeSec, NullPermissions: true, }) mountOpts := &fuse.MountOptions{ AllowOther: true, // allow users other than root&mounter to access fs FsName: "stargzstore", Debug: debug, } if _, err := exec.LookPath(fusermountBin); err == nil { mountOpts.Options = []string{"suid"} // option for fusermount; allow setuid inside container } else { log.G(ctx).WithError(err).Debugf("%s not installed; trying direct mount", fusermountBin) mountOpts.DirectMount = true } server, err := fuse.NewServer(rawFS, mountpoint, mountOpts) if err != nil { return err } go server.Serve() return server.WaitMount() } type fs struct { layerManager *LayerManager // nodeMap manages inode numbers for nodes other than nodes in layers // (i.e. nodes other than ones inside `diff` directories). // - inode number = [ 0 ][ uint32 ID ] nodeMap *idMap // layerMap manages upper bits of inode numbers for nodes inside layers. // - inode number = [ uint32 layer ID ][ uint32 number (unique inside `diff` directory) ] // inodes numbers of noeds inside each `diff` directory are prefixed by an unique uint32 // so that they don't conflict with nodes outside `diff` directories. layerMap *idMap knownNode map[string]map[string]*layerReleasable knownNodeMu sync.Mutex } type layerReleasable struct { n fusefs.InodeEmbedder released bool mu sync.Mutex } func (lh *layerReleasable) releasable() bool { lh.mu.Lock() released := lh.released lh.mu.Unlock() return released && isForgotten(lh.n.EmbeddedInode()) } func (lh *layerReleasable) release() { lh.mu.Lock() lh.released = true lh.mu.Unlock() } func isForgotten(n *fusefs.Inode) bool { if !n.Forgotten() { return false } for _, cn := range n.Children() { if !isForgotten(cn) { return false } } return true } type inoReleasable struct { n fusefs.InodeEmbedder } func (r *inoReleasable) releasable() bool { return r.n.EmbeddedInode().Forgotten() } func (fs *fs) newInodeWithID(ctx context.Context, p func(uint32) fusefs.InodeEmbedder) (*fusefs.Inode, syscall.Errno) { var ino fusefs.InodeEmbedder if err := fs.nodeMap.add(func(id uint32) (releasable, error) { ino = p(id) return &inoReleasable{ino}, nil }); err != nil || ino == nil { log.G(ctx).WithError(err).Debug("cannot generate ID") return nil, syscall.EIO } return ino.EmbeddedInode(), 0 } // rootnode is the mountpoint node of stargz-store. type rootnode struct { fusefs.Inode fs *fs } var _ = (fusefs.InodeEmbedder)((*rootnode)(nil)) var _ = (fusefs.NodeLookuper)((*rootnode)(nil)) // Lookup loads manifest and config of specified name (image reference) // and returns refnode of the specified name func (n *rootnode) Lookup(ctx context.Context, name string, out *fuse.EntryOut) (*fusefs.Inode, syscall.Errno) { // lookup on memory nodes if cn := n.GetChild(name); cn != nil { switch tn := cn.Operations().(type) { case *fusefs.MemSymlink: copyAttr(&out.Attr, &tn.Attr) case *refnode: copyAttr(&out.Attr, &tn.attr) default: log.G(ctx).Warn("rootnode.Lookup: uknown node type detected") return nil, syscall.EIO } out.Attr.Ino = cn.StableAttr().Ino return cn, 0 } switch name { case poolLink: sAttr := defaultLinkAttr(&out.Attr) cn := &fusefs.MemSymlink{Data: []byte(n.fs.layerManager.refPool.root())} copyAttr(&cn.Attr, &out.Attr) return n.fs.newInodeWithID(ctx, func(ino uint32) fusefs.InodeEmbedder { out.Attr.Ino = uint64(ino) cn.Attr.Ino = uint64(ino) sAttr.Ino = uint64(ino) return n.NewInode(ctx, cn, sAttr) }) } refBytes, err := base64.StdEncoding.DecodeString(name) if err != nil { log.G(ctx).WithError(err).Debugf("failed to decode ref base64 %q", name) return nil, syscall.EINVAL } ref := string(refBytes) refspec, err := reference.Parse(ref) if err != nil { log.G(ctx).WithError(err).Warnf("invalid reference %q for %q", ref, name) return nil, syscall.EINVAL } sAttr := defaultDirAttr(&out.Attr) cn := &refnode{ fs: n.fs, ref: refspec, } copyAttr(&cn.attr, &out.Attr) return n.fs.newInodeWithID(ctx, func(ino uint32) fusefs.InodeEmbedder { out.Attr.Ino = uint64(ino) cn.attr.Ino = uint64(ino) sAttr.Ino = uint64(ino) return n.NewInode(ctx, cn, sAttr) }) } // refnode is the node at /. type refnode struct { fusefs.Inode fs *fs attr fuse.Attr ref reference.Spec } var _ = (fusefs.InodeEmbedder)((*refnode)(nil)) var _ = (fusefs.NodeLookuper)((*refnode)(nil)) // Lookup returns layernode of the specified name func (n *refnode) Lookup(ctx context.Context, name string, out *fuse.EntryOut) (*fusefs.Inode, syscall.Errno) { // lookup on memory nodes if cn := n.GetChild(name); cn != nil { switch tn := cn.Operations().(type) { case *layernode: copyAttr(&out.Attr, &tn.attr) default: log.G(ctx).Warn("rootnode.Lookup: uknown node type detected") return nil, syscall.EIO } out.Attr.Ino = cn.StableAttr().Ino return cn, 0 } targetDigest, err := digest.Parse(name) if err != nil { log.G(ctx).WithError(err).Warnf("invalid digest for %q", name) return nil, syscall.EINVAL } sAttr := defaultDirAttr(&out.Attr) cn := &layernode{ fs: n.fs, digest: targetDigest, refnode: n, } copyAttr(&cn.attr, &out.Attr) return n.fs.newInodeWithID(ctx, func(ino uint32) fusefs.InodeEmbedder { out.Attr.Ino = uint64(ino) cn.attr.Ino = uint64(ino) sAttr.Ino = uint64(ino) return n.NewInode(ctx, cn, sAttr) }) } var _ = (fusefs.NodeRmdirer)((*refnode)(nil)) // Rmdir marks this layer as "release". // We don't use layernode.Unlink because Unlink event doesn't reach here when "use" file isn't visible // to the filesystem client. func (n *refnode) Rmdir(ctx context.Context, name string) syscall.Errno { targetDigest, err := digest.Parse(name) if err != nil { log.G(ctx).WithError(err).Warnf("invalid digest for %q during release", name) return syscall.EINVAL } current, err := n.fs.layerManager.release(ctx, n.ref, targetDigest) if err != nil { log.G(ctx).WithError(err).Warnf("failed to release layer %v / %v", n.ref, targetDigest) return syscall.EIO } if current == 0 { n.fs.knownNodeMu.Lock() lh, ok := n.fs.knownNode[n.ref.String()][targetDigest.String()] if !ok { n.fs.knownNodeMu.Unlock() log.G(ctx).WithError(err).Warnf("node of layer %v/%v is not registered", n.ref, targetDigest) return syscall.EIO } lh.release() delete(n.fs.knownNode[n.ref.String()], targetDigest.String()) if len(n.fs.knownNode[n.ref.String()]) == 0 { delete(n.fs.knownNode, n.ref.String()) } n.fs.knownNodeMu.Unlock() } log.G(ctx).WithField("refcounter", current).Infof("layer %v/%v is marked as RELEASE", n.ref, targetDigest) return syscall.ENOENT } // layernode is the node at //. type layernode struct { fusefs.Inode attr fuse.Attr fs *fs refnode *refnode digest digest.Digest } var _ = (fusefs.InodeEmbedder)((*layernode)(nil)) var _ = (fusefs.NodeCreater)((*layernode)(nil)) // Create marks this layer as "using". // We don't use refnode.Mkdir because Mkdir event doesn't reach here if layernode already exists. func (n *layernode) Create(ctx context.Context, name string, flags uint32, mode uint32, out *fuse.EntryOut) (node *fusefs.Inode, fh fusefs.FileHandle, fuseFlags uint32, errno syscall.Errno) { if name == layerUseFile { current := n.fs.layerManager.use(n.refnode.ref, n.digest) log.G(ctx).WithField("refcounter", current).Infof("layer %v / %v is marked as USING", n.refnode.ref, n.digest) } return nil, nil, 0, syscall.ENOENT } var _ = (fusefs.NodeLookuper)((*layernode)(nil)) // Lookup routes to the target file stored in the pool, based on the specified file name. func (n *layernode) Lookup(ctx context.Context, name string, out *fuse.EntryOut) (*fusefs.Inode, syscall.Errno) { switch name { case layerInfoLink: info, err := n.fs.layerManager.getLayerInfo(ctx, n.refnode.ref, n.digest) if err != nil { log.G(ctx).WithError(err).Warnf("failed to get layer info for %q: %q", name, n.digest) return nil, syscall.EIO } buf := new(bytes.Buffer) if err := json.NewEncoder(buf).Encode(&info); err != nil { log.G(ctx).WithError(err).Warnf("failed to encode layer info for %q: %q", name, n.digest) return nil, syscall.EIO } infoData := buf.Bytes() sAttr := defaultFileAttr(uint64(len(infoData)), &out.Attr) cn := &fusefs.MemRegularFile{Data: infoData} copyAttr(&cn.Attr, &out.Attr) return n.fs.newInodeWithID(ctx, func(ino uint32) fusefs.InodeEmbedder { out.Attr.Ino = uint64(ino) cn.Attr.Ino = uint64(ino) sAttr.Ino = uint64(ino) return n.NewInode(ctx, cn, sAttr) }) case layerLink, blobLink: // Check if layer is already known if name == layerLink { n.fs.knownNodeMu.Lock() if lh, ok := n.fs.knownNode[n.refnode.ref.String()][n.digest.String()]; ok { var ao fuse.AttrOut if errno := lh.n.(fusefs.NodeGetattrer).Getattr(ctx, nil, &ao); errno != 0 { return nil, errno } copyAttr(&out.Attr, &ao.Attr) n.fs.knownNodeMu.Unlock() return n.NewInode(ctx, lh.n, fusefs.StableAttr{ Mode: out.Attr.Mode, Ino: out.Attr.Ino, }), 0 } n.fs.knownNodeMu.Unlock() } // Resolve layer l, err := n.fs.layerManager.getLayer(ctx, n.refnode.ref, n.digest) if err != nil { cErr := ctx.Err() if errors.Is(cErr, context.Canceled) || errors.Is(err, context.Canceled) { // When filesystem client canceled to lookup this layer, // do not log this as "preparation failure" because it's // intensional. log.G(ctx).WithError(err).Debugf("error resolving layer (context error: %v)", cErr) return nil, syscall.EIO } log.G(ctx).WithField(remoteSnapshotLogKey, prepareFailed). WithField("layerdigest", n.digest). WithError(err). Debugf("error resolving layer (context error: %v)", cErr) log.G(ctx).WithError(err).Warnf("failed to mount layer %q: %q", name, n.digest) return nil, syscall.EIO } if name == blobLink { sAttr := layerToAttr(l, &out.Attr) cn := &blobnode{l: l} copyAttr(&cn.attr, &out.Attr) return n.fs.newInodeWithID(ctx, func(ino uint32) fusefs.InodeEmbedder { out.Attr.Ino = uint64(ino) cn.attr.Ino = uint64(ino) sAttr.Ino = uint64(ino) return n.NewInode(ctx, cn, sAttr) }) } var cn *fusefs.Inode var errno syscall.Errno err = n.fs.layerMap.add(func(id uint32) (releasable, error) { root, err := l.RootNode(id) if err != nil { return nil, err } var ao fuse.AttrOut errno = root.(fusefs.NodeGetattrer).Getattr(ctx, nil, &ao) if errno != 0 { return nil, fmt.Errorf("failed to get root node: %v", errno) } copyAttr(&out.Attr, &ao.Attr) cn = n.NewInode(ctx, root, fusefs.StableAttr{ Mode: out.Attr.Mode, Ino: out.Attr.Ino, }) rr := &layerReleasable{n: root} n.fs.knownNodeMu.Lock() if n.fs.knownNode == nil { n.fs.knownNode = make(map[string]map[string]*layerReleasable) } if n.fs.knownNode[n.refnode.ref.String()] == nil { n.fs.knownNode[n.refnode.ref.String()] = make(map[string]*layerReleasable) } n.fs.knownNode[n.refnode.ref.String()][n.digest.String()] = rr n.fs.knownNodeMu.Unlock() return rr, nil }) if err != nil || errno != 0 { log.G(ctx).WithField(remoteSnapshotLogKey, prepareFailed). WithField("layerdigest", n.digest). WithError(err). WithField("errno", errno). Debugf("failed to get root node") if errno == 0 { errno = syscall.EIO } return nil, errno } return cn, 0 case layerUseFile: log.G(ctx).Debugf("\"use\" file is referred but return ENOENT for reference management") return nil, syscall.ENOENT default: log.G(ctx).Warnf("unknown filename %q", name) return nil, syscall.ENOENT } } // blobnode is a regular file node that contains raw blob data type blobnode struct { fusefs.Inode l layer.Layer attr fuse.Attr } var _ = (fusefs.InodeEmbedder)((*blobnode)(nil)) var _ = (fusefs.NodeOpener)((*blobnode)(nil)) func (n *blobnode) Open(ctx context.Context, flags uint32) (fh fusefs.FileHandle, fuseFlags uint32, errno syscall.Errno) { return &blobfile{l: n.l}, 0, 0 } // blob file is the file handle of blob contents. type blobfile struct { l layer.Layer } var _ = (fusefs.FileReader)((*blobfile)(nil)) func (f *blobfile) Read(ctx context.Context, dest []byte, off int64) (fuse.ReadResult, syscall.Errno) { s, err := f.l.ReadAt(dest, off, remote.WithContext(ctx), // Make cancellable remote.WithCacheOpts(cache.Direct()), // Do not pollute mem cache ) if err != nil && err != io.EOF { return nil, syscall.EIO } return fuse.ReadResultData(dest[:s]), 0 } var _ = (fusefs.FileGetattrer)((*blobfile)(nil)) func (f *blobfile) Getattr(ctx context.Context, out *fuse.AttrOut) syscall.Errno { layerToAttr(f.l, &out.Attr) return 0 } func copyAttr(dest, src *fuse.Attr) { dest.Ino = src.Ino dest.Size = src.Size dest.Blocks = src.Blocks dest.Atime = src.Atime dest.Mtime = src.Mtime dest.Ctime = src.Ctime dest.Atimensec = src.Atimensec dest.Mtimensec = src.Mtimensec dest.Ctimensec = src.Ctimensec dest.Mode = src.Mode dest.Nlink = src.Nlink dest.Owner = src.Owner dest.Rdev = src.Rdev dest.Blksize = src.Blksize dest.Padding = src.Padding } func layerToAttr(l layer.Layer, out *fuse.Attr) fusefs.StableAttr { // out.Ino out.Size = uint64(l.Info().Size) out.Blksize = blockSize out.Blocks = out.Size / uint64(out.Blksize) if out.Size%uint64(out.Blksize) > 0 { out.Blocks++ } out.Nlink = 1 out.Mode = layerFileMode out.Owner = fuse.Owner{Uid: 0, Gid: 0} // out.Mtime // out.Mtimensec // out.Rdev // out.Padding return fusefs.StableAttr{ Mode: out.Mode, } } func defaultFileAttr(size uint64, out *fuse.Attr) fusefs.StableAttr { // out.Ino out.Size = size out.Blksize = blockSize out.Blocks = out.Size / uint64(out.Blksize) if out.Size%uint64(out.Blksize) > 0 { out.Blocks++ } out.Nlink = 1 out.Mode = defaultFileMode out.Owner = fuse.Owner{Uid: 0, Gid: 0} // out.Mtime // out.Mtimensec // out.Rdev // out.Padding return fusefs.StableAttr{ Mode: out.Mode, } } func defaultDirAttr(out *fuse.Attr) fusefs.StableAttr { // out.Ino out.Size = 0 // out.Blksize // out.Blocks // out.Nlink out.Mode = defaultDirMode out.Owner = fuse.Owner{Uid: 0, Gid: 0} // out.Mtime // out.Mtimensec // out.Rdev // out.Padding return fusefs.StableAttr{ Mode: out.Mode, } } func defaultLinkAttr(out *fuse.Attr) fusefs.StableAttr { // out.Ino out.Size = 0 // out.Blksize // out.Blocks // out.Nlink out.Mode = defaultLinkMode out.Owner = fuse.Owner{Uid: 0, Gid: 0} // out.Mtime // out.Mtimensec // out.Rdev // out.Padding return fusefs.StableAttr{ Mode: out.Mode, } } // idMap manages uint32 IDs with automatic GC for releasable objects. type idMap struct { m map[uint32]releasable max uint32 mu sync.Mutex cleanupG singleflight.Group } type releasable interface { releasable() bool } // add reserves an unique uint32 object for the provided releasable object. // when that object become releasable, that ID will be reused for other objects. func (m *idMap) add(p func(uint32) (releasable, error)) error { m.cleanupG.Do("cleanup", func() (interface{}, error) { m.mu.Lock() defer m.mu.Unlock() max := uint32(0) for i := uint32(0); i <= m.max; i++ { if e, ok := m.m[i]; ok { if e.releasable() { delete(m.m, i) } else { max = i } } } m.max = max return nil, nil }) m.mu.Lock() defer m.mu.Unlock() if m.m == nil { m.m = make(map[uint32]releasable) } for i := uint32(0); i <= ^uint32(0); i++ { if i == 0 { continue } e, ok := m.m[i] if !ok || e.releasable() { r, err := p(i) if err != nil { return err } if m.max < i { m.max = i } m.m[i] = r return nil } } return fmt.Errorf("no ID is usable") } stargz-snapshotter-0.14.3/store/manager.go000066400000000000000000000340061440204344700205630ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package store import ( "context" "fmt" "strconv" "strings" "sync" "time" "github.com/containerd/containerd/log" "github.com/containerd/containerd/reference" "github.com/containerd/stargz-snapshotter/estargz" "github.com/containerd/stargz-snapshotter/estargz/zstdchunked" "github.com/containerd/stargz-snapshotter/fs/config" "github.com/containerd/stargz-snapshotter/fs/layer" layermetrics "github.com/containerd/stargz-snapshotter/fs/metrics/layer" "github.com/containerd/stargz-snapshotter/fs/source" "github.com/containerd/stargz-snapshotter/metadata" esgzexternaltoc "github.com/containerd/stargz-snapshotter/nativeconverter/estargz/externaltoc" "github.com/containerd/stargz-snapshotter/task" "github.com/containerd/stargz-snapshotter/util/namedmutex" "github.com/docker/go-metrics" digest "github.com/opencontainers/go-digest" ocispec "github.com/opencontainers/image-spec/specs-go/v1" ) const ( remoteSnapshotLogKey = "remote-snapshot-prepared" prepareSucceeded = "true" prepareFailed = "false" defaultMaxConcurrency = 2 ) func NewLayerManager(ctx context.Context, root string, hosts source.RegistryHosts, metadataStore metadata.Store, cfg config.Config) (*LayerManager, error) { refPool, err := newRefPool(ctx, root, hosts) if err != nil { return nil, err } maxConcurrency := cfg.MaxConcurrency if maxConcurrency == 0 { maxConcurrency = defaultMaxConcurrency } tm := task.NewBackgroundTaskManager(maxConcurrency, 5*time.Second) r, err := layer.NewResolver(root, tm, cfg, nil, metadataStore, layer.OverlayOpaqueAll, func(ctx context.Context, hosts source.RegistryHosts, refspec reference.Spec, desc ocispec.Descriptor) []metadata.Decompressor { return []metadata.Decompressor{esgzexternaltoc.NewRemoteDecompressor(ctx, hosts, refspec, desc)} }, ) if err != nil { return nil, fmt.Errorf("failed to setup resolver: %w", err) } var ns *metrics.Namespace if !cfg.NoPrometheus { ns = metrics.NewNamespace("stargz", "fs", nil) } c := layermetrics.NewLayerMetrics(ns) if ns != nil { metrics.Register(ns) } return &LayerManager{ refPool: refPool, hosts: hosts, resolver: r, prefetchSize: cfg.PrefetchSize, noprefetch: cfg.NoPrefetch, noBackgroundFetch: cfg.NoBackgroundFetch, backgroundTaskManager: tm, allowNoVerification: cfg.AllowNoVerification, disableVerification: cfg.DisableVerification, metricsController: c, resolveLock: new(namedmutex.NamedMutex), layer: make(map[string]map[string]layer.Layer), refcounter: make(map[string]map[string]int), }, nil } // LayerManager manages layers of images and their resource lifetime. type LayerManager struct { refPool *refPool hosts source.RegistryHosts resolver *layer.Resolver prefetchSize int64 noprefetch bool noBackgroundFetch bool backgroundTaskManager *task.BackgroundTaskManager allowNoVerification bool disableVerification bool metricsController *layermetrics.Controller resolveLock *namedmutex.NamedMutex layer map[string]map[string]layer.Layer refcounter map[string]map[string]int mu sync.Mutex } func (r *LayerManager) cacheLayer(refspec reference.Spec, dgst digest.Digest, l layer.Layer) (_ layer.Layer, added bool) { r.mu.Lock() defer r.mu.Unlock() if r.layer == nil { r.layer = make(map[string]map[string]layer.Layer) } if r.layer[refspec.String()] == nil { r.layer[refspec.String()] = make(map[string]layer.Layer) } if cl, ok := r.layer[refspec.String()][dgst.String()]; ok { return cl, false // already exists } r.layer[refspec.String()][dgst.String()] = l return l, true } func (r *LayerManager) getCachedLayer(refspec reference.Spec, dgst digest.Digest) layer.Layer { r.mu.Lock() defer r.mu.Unlock() if r.layer == nil || r.layer[refspec.String()] == nil { return nil } if l, ok := r.layer[refspec.String()][dgst.String()]; ok { return l } return nil } func (r *LayerManager) getLayerInfo(ctx context.Context, refspec reference.Spec, dgst digest.Digest) (Layer, error) { manifest, config, err := r.refPool.loadRef(ctx, refspec) if err != nil { return Layer{}, fmt.Errorf("failed to get manifest and config: %w", err) } return genLayerInfo(ctx, dgst, manifest, config) } func (r *LayerManager) getLayer(ctx context.Context, refspec reference.Spec, dgst digest.Digest) (layer.Layer, error) { gotL := r.getCachedLayer(refspec, dgst) if gotL != nil { return gotL, nil } // resolve the layer and all other layers in the specified reference. var ( result layer.Layer resultChan = make(chan layer.Layer) errChan = make(chan error) ) manifest, _, err := r.refPool.loadRef(ctx, refspec) if err != nil { return nil, fmt.Errorf("failed to get manifest and config: %w", err) } var target ocispec.Descriptor var preResolve []ocispec.Descriptor var found bool for _, l := range manifest.Layers { if l.Digest == dgst { l := l found = true target = l continue } preResolve = append(preResolve, l) } if !found { return nil, fmt.Errorf("unknown digest %v for ref %q", target, refspec.String()) } for _, l := range append([]ocispec.Descriptor{target}, preResolve...) { l := l // Check if layer is already resolved before creating goroutine. gotL := r.getCachedLayer(refspec, l.Digest) if gotL != nil { // Layer already resolved if l.Digest.String() != target.Digest.String() { continue // This is not the target layer; nop } result = gotL continue } // Resolve the layer go func() { // Avoids to get canceled by client. ctx := context.Background() gotL, err := r.resolveLayer(ctx, refspec, l) if l.Digest.String() != target.Digest.String() { return // This is not target layer } if err != nil { errChan <- fmt.Errorf("failed to resolve layer %q / %q: %w", refspec, l.Digest, err) return } // Log this as preparation success log.G(ctx).WithField(remoteSnapshotLogKey, prepareSucceeded).Debugf("successfully resolved layer") resultChan <- gotL }() } if result != nil { return result, nil } // Wait for resolving completion var l layer.Layer select { case l = <-resultChan: case err := <-errChan: log.G(ctx).WithError(err).Debug("failed to resolve layer") return nil, fmt.Errorf("failed to resolve layer: %w", err) case <-time.After(30 * time.Second): log.G(ctx).Debug("failed to resolve layer (timeout)") return nil, fmt.Errorf("failed to resolve layer (timeout)") } return l, nil } func (r *LayerManager) resolveLayer(ctx context.Context, refspec reference.Spec, target ocispec.Descriptor) (layer.Layer, error) { key := refspec.String() + "/" + target.Digest.String() // Wait if resolving this layer is already running. r.resolveLock.Lock(key) defer r.resolveLock.Unlock(key) gotL := r.getCachedLayer(refspec, target.Digest) if gotL != nil { // layer already resolved return gotL, nil } // Resolve this layer. var esgzOpts []metadata.Option if target.Annotations != nil { if tocOffsetStr, ok := target.Annotations[zstdchunked.ManifestPositionAnnotation]; ok { if parts := strings.Split(tocOffsetStr, ":"); len(parts) == 4 { tocOffset, err := strconv.ParseInt(parts[0], 10, 64) if err == nil { esgzOpts = append(esgzOpts, metadata.WithTOCOffset(tocOffset)) } } } } l, err := r.resolver.Resolve(ctx, r.hosts, refspec, target, esgzOpts...) if err != nil { return nil, err } // Verify layer's content labels := target.Annotations if labels == nil { labels = make(map[string]string) } if r.disableVerification { // Skip if verification is disabled completely l.SkipVerify() log.G(ctx).Debugf("Verification forcefully skipped") } else if tocDigest, ok := labels[estargz.TOCJSONDigestAnnotation]; ok { // Verify this layer using the TOC JSON digest passed through label. dgst, err := digest.Parse(tocDigest) if err != nil { log.G(ctx).WithError(err).Debugf("failed to parse passed TOC digest %q", dgst) return nil, fmt.Errorf("invalid TOC digest: %v: %w", tocDigest, err) } if err := l.Verify(dgst); err != nil { log.G(ctx).WithError(err).Debugf("invalid layer") return nil, fmt.Errorf("invalid stargz layer: %w", err) } log.G(ctx).Debugf("verified") } else { // Verification must be done. Don't mount this layer. return nil, fmt.Errorf("digest of TOC JSON must be passed") } // Prefetch this layer. We prefetch several layers in parallel. The first // Check() for this layer waits for the prefetch completion. if !r.noprefetch { go func() { r.backgroundTaskManager.DoPrioritizedTask() defer r.backgroundTaskManager.DonePrioritizedTask() if err := l.Prefetch(r.prefetchSize); err != nil { log.G(ctx).WithError(err).Debug("failed to prefetched layer") return } log.G(ctx).Debug("completed to prefetch") }() } // Fetch whole layer aggressively in background. We use background // reader for this so prioritized tasks(Mount, Check, etc...) can // interrupt the reading. This can avoid disturbing prioritized tasks // about NW traffic. if !r.noBackgroundFetch { go func() { if err := l.BackgroundFetch(); err != nil { log.G(ctx).WithError(err).Debug("failed to fetch whole layer") return } log.G(ctx).Debug("completed to fetch all layer data in background") }() } // Cache this layer. cachedL, added := r.cacheLayer(refspec, target.Digest, l) if added { r.metricsController.Add(key, cachedL) } else { l.Done() // layer is already cached. use the cached one instead. discard this layer. } return cachedL, nil } func (r *LayerManager) release(ctx context.Context, refspec reference.Spec, dgst digest.Digest) (int, error) { r.refPool.release(refspec) r.mu.Lock() defer r.mu.Unlock() if r.refcounter == nil || r.refcounter[refspec.String()] == nil { return 0, fmt.Errorf("ref %q not tracked", refspec.String()) } else if _, ok := r.refcounter[refspec.String()][dgst.String()]; !ok { return 0, fmt.Errorf("layer %q/%q not tracked", refspec.String(), dgst.String()) } r.refcounter[refspec.String()][dgst.String()]-- i := r.refcounter[refspec.String()][dgst.String()] if i <= 0 { // No reference to this layer. release it. delete(r.refcounter, dgst.String()) if len(r.refcounter[refspec.String()]) == 0 { delete(r.refcounter, refspec.String()) } if r.layer == nil || r.layer[refspec.String()] == nil { return 0, fmt.Errorf("layer of reference %q is not registered (ref=%d)", refspec, i) } l, ok := r.layer[refspec.String()][dgst.String()] if !ok { return 0, fmt.Errorf("layer of digest %q/%q is not registered (ref=%d)", refspec, dgst, i) } l.Done() delete(r.layer[refspec.String()], dgst.String()) if len(r.layer[refspec.String()]) == 0 { delete(r.layer, refspec.String()) } log.G(ctx).WithField("refcounter", i).Infof("layer %v/%v is released due to no reference", refspec, dgst) } return i, nil } func (r *LayerManager) use(refspec reference.Spec, dgst digest.Digest) int { r.refPool.use(refspec) r.mu.Lock() defer r.mu.Unlock() if r.refcounter == nil { r.refcounter = make(map[string]map[string]int) } if r.refcounter[refspec.String()] == nil { r.refcounter[refspec.String()] = make(map[string]int) } if _, ok := r.refcounter[refspec.String()][dgst.String()]; !ok { r.refcounter[refspec.String()][dgst.String()] = 1 return 1 } r.refcounter[refspec.String()][dgst.String()]++ return r.refcounter[refspec.String()][dgst.String()] } func colon2dash(s string) string { return strings.ReplaceAll(s, ":", "-") } // Layer represents the layer information. Format is compatible to the one required by // "additional layer store" of github.com/containers/storage. type Layer struct { CompressedDigest digest.Digest `json:"compressed-diff-digest,omitempty"` CompressedSize int64 `json:"compressed-size,omitempty"` UncompressedDigest digest.Digest `json:"diff-digest,omitempty"` UncompressedSize int64 `json:"diff-size,omitempty"` CompressionType int `json:"compression,omitempty"` ReadOnly bool `json:"-"` } // Defined in https://github.com/containers/storage/blob/b64e13a1afdb0bfed25601090ce4bbbb1bc183fc/pkg/archive/archive.go#L108-L119 const gzipTypeMagicNum = 2 func genLayerInfo(ctx context.Context, dgst digest.Digest, manifest ocispec.Manifest, config ocispec.Image) (Layer, error) { if len(manifest.Layers) != len(config.RootFS.DiffIDs) { return Layer{}, fmt.Errorf( "len(manifest.Layers) != len(config.Rootfs): %d != %d", len(manifest.Layers), len(config.RootFS.DiffIDs)) } var ( layerIndex = -1 ) for i, l := range manifest.Layers { if l.Digest == dgst { layerIndex = i } } if layerIndex == -1 { return Layer{}, fmt.Errorf("layer %q not found in the manifest", dgst.String()) } var uncompressedSize int64 var err error if uncompressedSizeStr, ok := manifest.Layers[layerIndex].Annotations[estargz.StoreUncompressedSizeAnnotation]; ok { uncompressedSize, err = strconv.ParseInt(uncompressedSizeStr, 10, 64) if err != nil { log.G(ctx).WithError(err).Warnf("layer %q has invalid uncompressed size; exposing incomplete layer info", dgst.String()) } } else { log.G(ctx).Warnf("layer %q doesn't have uncompressed size; exposing incomplete layer info", dgst.String()) } return Layer{ CompressedDigest: manifest.Layers[layerIndex].Digest, CompressedSize: manifest.Layers[layerIndex].Size, UncompressedDigest: config.RootFS.DiffIDs[layerIndex], UncompressedSize: uncompressedSize, CompressionType: gzipTypeMagicNum, ReadOnly: true, }, nil } stargz-snapshotter-0.14.3/store/refs.go000066400000000000000000000155041440204344700201120ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package store import ( "context" "encoding/json" "fmt" "os" "path/filepath" "sync" "time" "github.com/containerd/containerd/log" "github.com/containerd/containerd/platforms" "github.com/containerd/containerd/reference" "github.com/containerd/containerd/remotes/docker" "github.com/containerd/stargz-snapshotter/fs/source" "github.com/containerd/stargz-snapshotter/util/cacheutil" "github.com/containerd/stargz-snapshotter/util/containerdutil" digest "github.com/opencontainers/go-digest" ocispec "github.com/opencontainers/image-spec/specs-go/v1" ) const ( refCacheEntry = 30 defaultManifestCacheTime = 120 * time.Second ) func newRefPool(ctx context.Context, root string, hosts source.RegistryHosts) (*refPool, error) { var poolroot = filepath.Join(root, "pool") if err := os.MkdirAll(poolroot, 0700); err != nil { return nil, err } p := &refPool{ path: poolroot, hosts: hosts, refcounter: make(map[string]*releaser), } p.cache = cacheutil.NewLRUCache(refCacheEntry) p.cache.OnEvicted = func(key string, value interface{}) { refspec := value.(reference.Spec) if err := os.RemoveAll(p.metadataDir(refspec)); err != nil { log.G(ctx).WithField("key", key).WithError(err).Warnf("failed to clean up ref") return } log.G(ctx).WithField("key", key).Debugf("cleaned up ref") } return p, nil } type refPool struct { path string hosts source.RegistryHosts refcounter map[string]*releaser cache *cacheutil.LRUCache mu sync.Mutex } type releaser struct { count int release func() } func (p *refPool) loadRef(ctx context.Context, refspec reference.Spec) (manifest ocispec.Manifest, config ocispec.Image, err error) { manifest, config, err = p.readManifestAndConfig(refspec) if err == nil { log.G(ctx).Debugf("reusing manifest and config of %q", refspec.String()) return } log.G(ctx).WithError(err).Debugf("fetching manifest and config of %q", refspec.String()) manifest, config, err = p.fetchManifestAndConfig(ctx, refspec) if err != nil { return ocispec.Manifest{}, ocispec.Image{}, err } if err := p.writeManifestAndConfig(refspec, manifest, config); err != nil { return ocispec.Manifest{}, ocispec.Image{}, err } // Cache it so that next immediate call can acquire ref information from that dir. p.mu.Lock() _, done, _ := p.cache.Add(refspec.String(), refspec) p.mu.Unlock() go func() { // Release it after a reasonable amount of time. // If use() funcs are called for this reference, eviction of this won't be done until // all corresponding release() funcs are called. time.Sleep(defaultManifestCacheTime) done() }() return manifest, config, nil } func (p *refPool) use(refspec reference.Spec) int { p.mu.Lock() defer p.mu.Unlock() r, ok := p.refcounter[refspec.String()] if !ok { _, done, _ := p.cache.Add(refspec.String(), refspec) p.refcounter[refspec.String()] = &releaser{ count: 1, release: done, } return 1 } r.count++ return r.count } func (p *refPool) release(refspec reference.Spec) (int, error) { p.mu.Lock() defer p.mu.Unlock() r, ok := p.refcounter[refspec.String()] if !ok { return 0, fmt.Errorf("ref %q not tracked", refspec.String()) } r.count-- if r.count <= 0 { delete(p.refcounter, refspec.String()) r.release() return 0, nil } return r.count, nil } func (p *refPool) readManifestAndConfig(refspec reference.Spec) (manifest ocispec.Manifest, config ocispec.Image, _ error) { mPath, cPath := p.manifestFile(refspec), p.configFile(refspec) mf, err := os.Open(mPath) if err != nil { return ocispec.Manifest{}, ocispec.Image{}, err } defer mf.Close() if err := json.NewDecoder(mf).Decode(&manifest); err != nil { return ocispec.Manifest{}, ocispec.Image{}, err } cf, err := os.Open(cPath) if err != nil { return ocispec.Manifest{}, ocispec.Image{}, err } defer cf.Close() if err := json.NewDecoder(cf).Decode(&config); err != nil { return ocispec.Manifest{}, ocispec.Image{}, err } return manifest, config, nil } func (p *refPool) writeManifestAndConfig(refspec reference.Spec, manifest ocispec.Manifest, config ocispec.Image) error { mPath, cPath := p.manifestFile(refspec), p.configFile(refspec) if err := os.MkdirAll(filepath.Dir(mPath), 0700); err != nil { return err } if err := os.MkdirAll(filepath.Dir(cPath), 0700); err != nil { return err } mf, err := os.Create(mPath) if err != nil { return err } defer mf.Close() if err := json.NewEncoder(mf).Encode(&manifest); err != nil { return err } cf, err := os.Create(cPath) if err != nil { return err } defer cf.Close() return json.NewEncoder(cf).Encode(&config) } func (p *refPool) fetchManifestAndConfig(ctx context.Context, refspec reference.Spec) (ocispec.Manifest, ocispec.Image, error) { // temporary resolver. should only be used for resolving `refpec`. resolver := docker.NewResolver(docker.ResolverOptions{ Hosts: func(host string) ([]docker.RegistryHost, error) { if host != refspec.Hostname() { return nil, fmt.Errorf("unexpected host %q for image ref %q", host, refspec.String()) } return p.hosts(refspec) }, }) _, img, err := resolver.Resolve(ctx, refspec.String()) if err != nil { return ocispec.Manifest{}, ocispec.Image{}, err } fetcher, err := resolver.Fetcher(ctx, refspec.String()) if err != nil { return ocispec.Manifest{}, ocispec.Image{}, err } plt := platforms.DefaultSpec() // TODO: should we make this configurable? manifest, err := containerdutil.FetchManifestPlatform(ctx, fetcher, img, plt) if err != nil { return ocispec.Manifest{}, ocispec.Image{}, err } r, err := fetcher.Fetch(ctx, manifest.Config) if err != nil { return ocispec.Manifest{}, ocispec.Image{}, err } defer r.Close() var config ocispec.Image if err := json.NewDecoder(r).Decode(&config); err != nil { return ocispec.Manifest{}, ocispec.Image{}, err } return manifest, config, nil } func (p *refPool) root() string { return p.path } func (p *refPool) metadataDir(refspec reference.Spec) string { return filepath.Join(p.path, "metadata--"+colon2dash(digest.FromString(refspec.String()).String())) } func (p *refPool) manifestFile(refspec reference.Spec) string { return filepath.Join(p.metadataDir(refspec), "manifest") } func (p *refPool) configFile(refspec reference.Spec) string { return filepath.Join(p.metadataDir(refspec), "config") } stargz-snapshotter-0.14.3/task/000077500000000000000000000000001440204344700164255ustar00rootroot00000000000000stargz-snapshotter-0.14.3/task/task.go000066400000000000000000000132631440204344700177230ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package task import ( "context" "sync" "sync/atomic" "time" "golang.org/x/sync/semaphore" ) // NewBackgroundTaskManager provides a task manager. You can specify the // concurrency of background tasks. When running a background task, this will be // forced to wait until no prioritized task is running for some period. You can // specify the period through the argument of this function, too. func NewBackgroundTaskManager(concurrency int64, period time.Duration) *BackgroundTaskManager { return &BackgroundTaskManager{ backgroundSem: semaphore.NewWeighted(concurrency), prioritizedTaskSilencePeriod: period, prioritizedTaskStartNotify: make(chan struct{}), prioritizedTaskDoneCond: sync.NewCond(&sync.Mutex{}), } } // BackgroundTaskManager is a task manager which manages prioritized tasks and // background tasks execution. Background tasks are less important than // prioritized tasks. You can let these background tasks not to use compute // resources (CPU, NW, etc...) during more important tasks(=prioritized tasks) // running. // // When you run a prioritised task and don't want background tasks to use // resources you can tell it this manager by calling DoPrioritizedTask method. // DonePrioritizedTask method must be called at the end of the prioritised task // execution. // // For running a background task, you can use InvokeBackgroundTask method. The // background task must be able to be cancelled via context.Context argument. // The task is forced to wait until no prioritized task is running for some // period. You can specify the period when making this manager instance. The // limited number of background tasks run simultaneously and you can specify the // concurrency when making this manager instance too. If a prioritized task // starts during the execution of background tasks, all background tasks running // will be cancelled via context. These cancelled tasks will be executed again // later, same as other background tasks (when no prioritized task is running // for some period). type BackgroundTaskManager struct { prioritizedTasks int64 backgroundSem *semaphore.Weighted prioritizedTaskSilencePeriod time.Duration prioritizedTaskStartNotify chan struct{} prioritizedTaskStartNotifyMu sync.Mutex prioritizedTaskDoneCond *sync.Cond } // DoPrioritizedTask tells the manager that we are running a prioritized task // and don't want background tasks to disturb resources(CPU, NW, etc...) func (ts *BackgroundTaskManager) DoPrioritizedTask() { // Notify the prioritized task execution to background tasks. ts.prioritizedTaskStartNotifyMu.Lock() atomic.AddInt64(&ts.prioritizedTasks, 1) close(ts.prioritizedTaskStartNotify) ts.prioritizedTaskStartNotify = make(chan struct{}) ts.prioritizedTaskStartNotifyMu.Unlock() } // DonePrioritizedTask tells the manager that we've done a prioritized task // and don't want background tasks to disturb resources(CPU, NW, etc...) func (ts *BackgroundTaskManager) DonePrioritizedTask() { go func() { // Notify the task completion after `ts.prioritizedTaskSilencePeriod` // so that background tasks aren't invoked immediately. time.Sleep(ts.prioritizedTaskSilencePeriod) atomic.AddInt64(&ts.prioritizedTasks, -1) ts.prioritizedTaskDoneCond.L.Lock() ts.prioritizedTaskDoneCond.Broadcast() ts.prioritizedTaskDoneCond.L.Unlock() }() } // InvokeBackgroundTask invokes a background task. The task is started only when // no prioritized tasks are running. Prioritized task's execution stops the // execution of all background tasks. Background task must be able to be // cancelled via context.Context argument and be able to be restarted again. func (ts *BackgroundTaskManager) InvokeBackgroundTask(do func(context.Context), timeout time.Duration) { for { // Wait until all prioritized tasks are done for { if atomic.LoadInt64(&ts.prioritizedTasks) <= 0 { break } // waits until a prioritized task is done ts.prioritizedTaskDoneCond.L.Lock() if atomic.LoadInt64(&ts.prioritizedTasks) > 0 { ts.prioritizedTaskDoneCond.Wait() } ts.prioritizedTaskDoneCond.L.Unlock() } // limited number of background tasks can run at once. // if prioritized tasks are running, cancel this task. if func() bool { ts.backgroundSem.Acquire(context.Background(), 1) defer ts.backgroundSem.Release(1) // Get notify the prioritized tasks execution. ts.prioritizedTaskStartNotifyMu.Lock() ch := ts.prioritizedTaskStartNotify tasks := atomic.LoadInt64(&ts.prioritizedTasks) ts.prioritizedTaskStartNotifyMu.Unlock() if tasks > 0 { return false } // Invoke the background task. if some prioritized tasks added during // execution, cancel it and try it later. var ( done = make(chan struct{}) ctx, cancel = context.WithTimeout(context.Background(), timeout) ) defer cancel() go func() { do(ctx) close(done) }() // Wait until the background task is done or canceled. select { case <-ch: // some prioritized tasks started; retry it later cancel() return false case <-done: // All tasks completed } return true }() { break } } } stargz-snapshotter-0.14.3/task/task_test.go000066400000000000000000000175151440204344700207660ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package task import ( "context" "fmt" "sync" "testing" "time" ) // TestBackgroundTasks tests background task manager. func TestBackgroundTasks(t *testing.T) { doGo := func(f func()) { invoked := make(chan struct{}) go func() { invoked <- struct{}{} f() }() <-invoked time.Sleep(10 * time.Millisecond) } wait := func(t *testing.T, name string, done func() bool) { ch := make(chan struct{}) go func() { for !done() { time.Sleep(10 * time.Millisecond) } ch <- struct{}{} }() select { case <-ch: case <-time.After(5 * time.Second): t.Fatalf("timeout for %q", name) } } tests := []struct { name string concurrency int64 checkInterval time.Duration context func(t *testing.T, pm *BackgroundTaskManager, task1, task2, task3, task4 *sampleTask) assert func(task1, task2, task3, task4 *sampleTask) bool }{ { name: "privilege_running", concurrency: 1, checkInterval: 100 * time.Millisecond, context: func(t *testing.T, pm *BackgroundTaskManager, task1, task2, task3, task4 *sampleTask) { pm.DoPrioritizedTask() doGo(func() { pm.InvokeBackgroundTask(task1.do, 24*time.Hour) }) time.Sleep(300 * time.Millisecond) // wait for long time... }, assert: func(task1, task2, task3, task4 *sampleTask) bool { return (task1.assert(false, false, false)) }, }, { name: "concurrency", concurrency: 2, checkInterval: time.Duration(0), // We don't care prioritized tasks now context: func(t *testing.T, pm *BackgroundTaskManager, task1, task2, task3, task4 *sampleTask) { doGo(func() { pm.InvokeBackgroundTask(task1.do, 24*time.Hour) }) wait(t, "task1 started", task1.checkStarted()) doGo(func() { pm.InvokeBackgroundTask(task2.do, 24*time.Hour) }) wait(t, "task2 started", task2.checkStarted()) doGo(func() { pm.InvokeBackgroundTask(task3.do, 24*time.Hour) }) doGo(func() { pm.InvokeBackgroundTask(task4.do, 24*time.Hour) }) time.Sleep(300 * time.Millisecond) // wait for long time... }, assert: func(task1, task2, task3, task4 *sampleTask) bool { return (task1.assert(true, false, false) && task2.assert(true, false, false) && task3.assert(false, false, false) && task4.assert(false, false, false)) }, }, { name: "cancel", concurrency: 2, checkInterval: 100 * time.Millisecond, context: func(t *testing.T, pm *BackgroundTaskManager, task1, task2, task3, task4 *sampleTask) { doGo(func() { pm.InvokeBackgroundTask(task1.do, 24*time.Hour) }) wait(t, "task1 started", task1.checkStarted()) doGo(func() { pm.InvokeBackgroundTask(task2.do, 24*time.Hour) }) wait(t, "task2 started", task2.checkStarted()) pm.DoPrioritizedTask() wait(t, "task1 canceled", task1.checkCanceled()) wait(t, "task2 canceled", task2.checkCanceled()) }, assert: func(task1, task2, task3, task4 *sampleTask) bool { return (task1.assert(true, false, true) && task2.assert(true, false, true)) }, }, { name: "resume", concurrency: 2, checkInterval: 100 * time.Millisecond, context: func(t *testing.T, pm *BackgroundTaskManager, task1, task2, task3, task4 *sampleTask) { doGo(func() { pm.InvokeBackgroundTask(task1.do, 24*time.Hour) }) wait(t, "task1 started", task1.checkStarted()) doGo(func() { pm.InvokeBackgroundTask(task2.do, 24*time.Hour) }) wait(t, "task2 started", task2.checkStarted()) pm.DoPrioritizedTask() wait(t, "task1 canceled", task1.checkCanceled()) wait(t, "task2 canceled", task2.checkCanceled()) task1.reset() task2.reset() pm.DonePrioritizedTask() wait(t, "task1 resumed", task1.checkStarted()) wait(t, "task2 resumed", task2.checkStarted()) }, assert: func(task1, task2, task3, task4 *sampleTask) bool { return (task1.assert(true, false, false) && task2.assert(true, false, false)) }, }, { name: "finish_partial", concurrency: 1, checkInterval: time.Duration(0), // We don't care prioritized tasks now context: func(t *testing.T, pm *BackgroundTaskManager, task1, task2, task3, task4 *sampleTask) { doGo(func() { pm.InvokeBackgroundTask(task1.do, 24*time.Hour) }) wait(t, "task1 started", task1.checkStarted()) doGo(func() { pm.InvokeBackgroundTask(task2.do, 24*time.Hour) }) task1.finish() wait(t, "task1 done", task1.checkDone()) wait(t, "task2 started", task2.checkStarted()) }, assert: func(task1, task2, task3, task4 *sampleTask) bool { return (task1.assert(true, true, false) && task2.assert(true, false, false)) }, }, { name: "finish_all", concurrency: 1, checkInterval: time.Duration(0), // We don't care prioritized tasks now context: func(t *testing.T, pm *BackgroundTaskManager, task1, task2, task3, task4 *sampleTask) { doGo(func() { pm.InvokeBackgroundTask(task1.do, 24*time.Hour) }) wait(t, "task1 started", task1.checkStarted()) doGo(func() { pm.InvokeBackgroundTask(task2.do, 24*time.Hour) }) task1.finish() wait(t, "task1 done", task1.checkDone()) wait(t, "task2 started", task2.checkStarted()) task2.finish() wait(t, "task2 done", task2.checkDone()) }, assert: func(task1, task2, task3, task4 *sampleTask) bool { return (task1.assert(true, true, false) && task2.assert(true, true, false)) }, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { var ( pm = NewBackgroundTaskManager(tt.concurrency, tt.checkInterval) task1 = newSampleTask() task2 = newSampleTask() task3 = newSampleTask() task4 = newSampleTask() ) tt.context(t, pm, task1, task2, task3, task4) if !tt.assert(task1, task2, task3, task4) { t.Errorf("assertion failed:status=(task1:%q,task2:%q,task3:%q,task4:%q)", task1.dumpStatus(), task2.dumpStatus(), task3.dumpStatus(), task4.dumpStatus()) } }) } } type sampleTask struct { started bool done bool canceled bool mu sync.Mutex finishCh chan struct{} } func newSampleTask() *sampleTask { return &sampleTask{ finishCh: make(chan struct{}), } } func (st *sampleTask) checkStarted() func() bool { return func() bool { st.mu.Lock() defer st.mu.Unlock() return st.started } } func (st *sampleTask) checkDone() func() bool { return func() bool { st.mu.Lock() defer st.mu.Unlock() return st.done } } func (st *sampleTask) checkCanceled() func() bool { return func() bool { st.mu.Lock() defer st.mu.Unlock() return st.canceled } } func (st *sampleTask) do(ctx context.Context) { st.mu.Lock() st.started = true st.mu.Unlock() select { case <-st.finishCh: st.mu.Lock() st.done = true st.mu.Unlock() case <-ctx.Done(): st.mu.Lock() st.canceled = true st.mu.Unlock() } } func (st *sampleTask) finish() { st.finishCh <- struct{}{} } func (st *sampleTask) reset() { st.mu.Lock() st.started, st.done, st.canceled = false, false, false st.mu.Unlock() st.finishCh = make(chan struct{}) } func (st *sampleTask) dumpStatus() string { st.mu.Lock() defer st.mu.Unlock() return fmt.Sprintf("started=%v,done=%v,canceled=%v", st.started, st.done, st.canceled) } func (st *sampleTask) assert(started, done, canceled bool) bool { st.mu.Lock() defer st.mu.Unlock() return (st.started == started) && (st.done == done) && (st.canceled == canceled) } stargz-snapshotter-0.14.3/util/000077500000000000000000000000001440204344700164405ustar00rootroot00000000000000stargz-snapshotter-0.14.3/util/cacheutil/000077500000000000000000000000001440204344700204015ustar00rootroot00000000000000stargz-snapshotter-0.14.3/util/cacheutil/lrucache.go000066400000000000000000000077301440204344700225250ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package cacheutil import ( "sync" "github.com/golang/groupcache/lru" ) // LRUCache is "groupcache/lru"-like cache. The difference is that "groupcache/lru" immediately // finalizes theevicted contents using OnEvicted callback but our version strictly tracks the // reference counts of contents and calls OnEvicted when nobody refers to the evicted contents. type LRUCache struct { cache *lru.Cache mu sync.Mutex // OnEvicted optionally specifies a callback function to be // executed when an entry is purged from the cache. OnEvicted func(key string, value interface{}) } // NewLRUCache creates new lru cache. func NewLRUCache(maxEntries int) *LRUCache { inner := lru.New(maxEntries) inner.OnEvicted = func(key lru.Key, value interface{}) { // Decrease the ref count incremented in Add(). // When nobody refers to this value, this value will be finalized via refCounter. value.(*refCounter).finalize() } return &LRUCache{ cache: inner, } } // Get retrieves the specified object from the cache and increments the reference counter of the // target content. Client must call `done` callback to decrease the reference count when the value // will no longer be used. func (c *LRUCache) Get(key string) (value interface{}, done func(), ok bool) { c.mu.Lock() defer c.mu.Unlock() o, ok := c.cache.Get(key) if !ok { return nil, nil, false } rc := o.(*refCounter) rc.inc() return rc.v, c.decreaseOnceFunc(rc), true } // Add adds object to the cache and returns the cached contents with incrementing the reference count. // If the specified content already exists in the cache, this sets `added` to false and returns // "already cached" content (i.e. doesn't replace the content with the new one). Client must call // `done` callback to decrease the counter when the value will no longer be used. func (c *LRUCache) Add(key string, value interface{}) (cachedValue interface{}, done func(), added bool) { c.mu.Lock() defer c.mu.Unlock() if o, ok := c.cache.Get(key); ok { rc := o.(*refCounter) rc.inc() return rc.v, c.decreaseOnceFunc(rc), false } rc := &refCounter{ key: key, v: value, onEvicted: c.OnEvicted, } rc.initialize() // Keep this object having at least 1 ref count (will be decreased in OnEviction) rc.inc() // The client references this object (will be decreased on "done") c.cache.Add(key, rc) return rc.v, c.decreaseOnceFunc(rc), true } // Remove removes the specified contents from the cache. OnEvicted callback will be called when // nobody refers to the removed content. func (c *LRUCache) Remove(key string) { c.mu.Lock() defer c.mu.Unlock() c.cache.Remove(key) } func (c *LRUCache) decreaseOnceFunc(rc *refCounter) func() { var once sync.Once return func() { c.mu.Lock() defer c.mu.Unlock() once.Do(func() { rc.dec() }) } } type refCounter struct { onEvicted func(key string, value interface{}) key string v interface{} refCounts int64 mu sync.Mutex initializeOnce sync.Once finalizeOnce sync.Once } func (r *refCounter) inc() { r.mu.Lock() defer r.mu.Unlock() r.refCounts++ } func (r *refCounter) dec() { r.mu.Lock() defer r.mu.Unlock() r.refCounts-- if r.refCounts <= 0 && r.onEvicted != nil { // nobody will refer this object r.onEvicted(r.key, r.v) } } func (r *refCounter) initialize() { r.initializeOnce.Do(func() { r.inc() }) } func (r *refCounter) finalize() { r.finalizeOnce.Do(func() { r.dec() }) } stargz-snapshotter-0.14.3/util/cacheutil/lrucache_test.go000066400000000000000000000067641440204344700235720ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package cacheutil import ( "fmt" "testing" ) // TestLRUAdd tests Add API func TestLRUAdd(t *testing.T) { c := NewLRUCache(10) key, value := "key1", "abcd" v, _, added := c.Add(key, value) if !added { t.Fatalf("failed to add %q", key) } else if v.(string) != value { t.Fatalf("returned different object for %q; want %q; got %q", key, value, v.(string)) } key, newvalue := "key1", "dummy" v, _, added = c.Add(key, newvalue) if added || v.(string) != value { t.Fatalf("%q must be originally stored one; want %q; got %q (added:%v)", key, value, v.(string), added) } } // TestLRUGet tests Get API func TestLRUGet(t *testing.T) { c := NewLRUCache(10) key, value := "key1", "abcd" v, _, added := c.Add(key, value) if !added { t.Fatalf("failed to add %q", key) } else if v.(string) != value { t.Fatalf("returned different object for %q; want %q; got %q", key, value, v.(string)) } v, _, ok := c.Get(key) if !ok { t.Fatalf("failed to get obj %q (%q)", key, value) } else if v.(string) != value { t.Fatalf("unexpected object for %q; want %q; got %q", key, value, v.(string)) } } // TestLRURemoe tests Remove API func TestLRURemove(t *testing.T) { var evicted []string c := NewLRUCache(2) c.OnEvicted = func(key string, value interface{}) { evicted = append(evicted, key) } key1, value1 := "key1", "abcd1" _, done1, _ := c.Add(key1, value1) _, done12, _ := c.Get(key1) c.Remove(key1) if len(evicted) != 0 { t.Fatalf("no content must be evicted after remove") } done1() if len(evicted) != 0 { t.Fatalf("no content must be evicted until all reference are discarded") } done12() if len(evicted) != 1 { t.Fatalf("content must be evicted") } if evicted[0] != key1 { t.Fatalf("1st content %q must be evicted but got %q", key1, evicted[0]) } } // TestLRUEviction tests that eviction occurs when the overflow happens. func TestLRUEviction(t *testing.T) { var evicted []string c := NewLRUCache(2) c.OnEvicted = func(key string, value interface{}) { evicted = append(evicted, key) } key1, value1 := "key1", "abcd1" key2, value2 := "key2", "abcd2" _, done1, _ := c.Add(key1, value1) _, done2, _ := c.Add(key2, value2) _, done22, _ := c.Get(key2) if len(evicted) != 0 { t.Fatalf("no content must be evicted after addition") } for i := 0; i < 2; i++ { c.Add(fmt.Sprintf("key-add-%d", i), fmt.Sprintf("abcd-add-%d", i)) } if len(evicted) != 0 { t.Fatalf("no content must be evicted after overflow") } done1() if len(evicted) != 1 { t.Fatalf("1 content must be evicted") } if evicted[0] != key1 { t.Fatalf("1st content %q must be evicted but got %q", key1, evicted[0]) } done2() // effective done2() // ignored done2() // ignored if len(evicted) != 1 { t.Fatalf("only 1 content must be evicted") } done22() if len(evicted) != 2 { t.Fatalf("2 contents must be evicted") } if evicted[1] != key2 { t.Fatalf("2nd content %q must be evicted but got %q", key2, evicted[1]) } } stargz-snapshotter-0.14.3/util/cacheutil/ttlcache.go000066400000000000000000000065071440204344700225270ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package cacheutil import ( "sync" "time" ) // TTLCache is a ttl-based cache with reference counters. // Each elements is deleted as soon as expiering the configured ttl. type TTLCache struct { m map[string]*refCounterWithTimer mu sync.Mutex ttl time.Duration // OnEvicted optionally specifies a callback function to be // executed when an entry is purged from the cache. OnEvicted func(key string, value interface{}) } // NewTTLCache creates a new ttl-based cache. func NewTTLCache(ttl time.Duration) *TTLCache { return &TTLCache{ m: make(map[string]*refCounterWithTimer), ttl: ttl, } } // Get retrieves the specified object from the cache and increments the reference counter of the // target content. Client must call `done` callback to decrease the reference count when the value // will no longer be used. func (c *TTLCache) Get(key string) (value interface{}, done func(), ok bool) { c.mu.Lock() defer c.mu.Unlock() rc, ok := c.m[key] if !ok { return nil, nil, false } rc.inc() return rc.v, c.decreaseOnceFunc(rc), true } // Add adds object to the cache and returns the cached contents with incrementing the reference count. // If the specified content already exists in the cache, this sets `added` to false and returns // "already cached" content (i.e. doesn't replace the content with the new one). Client must call // `done` callback to decrease the counter when the value will no longer be used. func (c *TTLCache) Add(key string, value interface{}) (cachedValue interface{}, done func(), added bool) { c.mu.Lock() defer c.mu.Unlock() if rc, ok := c.m[key]; ok { rc.inc() return rc.v, c.decreaseOnceFunc(rc), false } rc := &refCounterWithTimer{ refCounter: &refCounter{ key: key, v: value, onEvicted: c.OnEvicted, }, } rc.initialize() // Keep this object having at least 1 ref count (will be decreased in OnEviction) rc.inc() // The client references this object (will be decreased on "done") rc.t = time.AfterFunc(c.ttl, func() { c.mu.Lock() defer c.mu.Unlock() c.evictLocked(key) }) c.m[key] = rc return rc.v, c.decreaseOnceFunc(rc), true } // Remove removes the specified contents from the cache. OnEvicted callback will be called when // nobody refers to the removed content. func (c *TTLCache) Remove(key string) { c.mu.Lock() defer c.mu.Unlock() c.evictLocked(key) } func (c *TTLCache) evictLocked(key string) { if rc, ok := c.m[key]; ok { delete(c.m, key) rc.t.Stop() // stop timer to prevent GC to this content anymore rc.finalize() } } func (c *TTLCache) decreaseOnceFunc(rc *refCounterWithTimer) func() { var once sync.Once return func() { c.mu.Lock() defer c.mu.Unlock() once.Do(func() { rc.dec() }) } } type refCounterWithTimer struct { *refCounter t *time.Timer } stargz-snapshotter-0.14.3/util/cacheutil/ttlcache_test.go000066400000000000000000000113031440204344700235540ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package cacheutil import ( "sync" "testing" "time" ) // TestTTLAdd tests Add API func TestTTLAdd(t *testing.T) { c := NewTTLCache(time.Hour) key, value := "key1", "abcd" v, _, added := c.Add(key, value) if !added { t.Fatalf("failed to add %q", key) } else if v.(string) != value { t.Fatalf("returned different object for %q; want %q; got %q", key, value, v.(string)) } key, newvalue := "key1", "dummy" v, _, added = c.Add(key, newvalue) if added || v.(string) != value { t.Fatalf("%q must be originally stored one; want %q; got %q (added:%v)", key, value, v.(string), added) } } // TestTTLGet tests Get API func TestTTLGet(t *testing.T) { c := NewTTLCache(time.Hour) key, value := "key1", "abcd" v, _, added := c.Add(key, value) if !added { t.Fatalf("failed to add %q", key) } else if v.(string) != value { t.Fatalf("returned different object for %q; want %q; got %q", key, value, v.(string)) } v, _, ok := c.Get(key) if !ok { t.Fatalf("failed to get obj %q (%q)", key, value) } else if v.(string) != value { t.Fatalf("unexpected object for %q; want %q; got %q", key, value, v.(string)) } } // TestTTLRemove tests Remove API func TestTTLRemove(t *testing.T) { var evicted []string c := NewTTLCache(time.Hour) c.OnEvicted = func(key string, value interface{}) { evicted = append(evicted, key) } key1, value1 := "key1", "abcd1" _, done1, _ := c.Add(key1, value1) _, done12, _ := c.Get(key1) c.Remove(key1) if len(evicted) != 0 { t.Fatalf("no content must be evicted after remove") } done1() if len(evicted) != 0 { t.Fatalf("no content must be evicted until all reference are discarded") } done12() if len(evicted) != 1 { t.Fatalf("content must be evicted") } if evicted[0] != key1 { t.Fatalf("1st content %q must be evicted but got %q", key1, evicted[0]) } } // TestTTLRemoveOverwritten tests old gc doesn't affect overwritten content func TestTTLRemoveOverwritten(t *testing.T) { var evicted []string c := NewTTLCache(3 * time.Second) c.OnEvicted = func(key string, value interface{}) { evicted = append(evicted, key) } key1, value1 := "key1", "abcd1" _, done1, _ := c.Add(key1, value1) done1() c.Remove(key1) // remove key1 as soon as possible // add another content with a new key time.Sleep(2 * time.Second) value12 := value1 + "!" _, done12, _ := c.Add(key1, value12) time.Sleep(2 * time.Second) // spent 4 sec (larger than ttl) since the previous key1 was added. // but the *newly-added* key1 hasn't been expierd yet so key1 must remain. v1, done122, getOK := c.Get(key1) if !getOK { t.Fatalf("unexpected eviction") } if s1, ok := v1.(string); !ok || s1 != value12 { t.Fatalf("unexpected content %q(%v) != %q", s1, ok, value12) } time.Sleep(2 * time.Second) done122() done12() // spent 4 sec since the new key1 was added. This should be expierd. if _, _, ok := c.Get(key1); ok { t.Fatalf("%q must be expierd but remaining", key1) } } // TestTTLEviction tests contents are evicted after TTL witout remaining reference. func TestTTLEviction(t *testing.T) { var ( evicted []string evictedMu sync.Mutex ) c := NewTTLCache(time.Second) c.OnEvicted = func(key string, value interface{}) { evictedMu.Lock() evicted = append(evicted, key) evictedMu.Unlock() } key1, value1 := "key1", "abcd1" key2, value2 := "key2", "abcd2" _, done1, _ := c.Add(key1, value1) done1() // evict key1 on expiering ttl _, done2, _ := c.Add(key2, value2) _, done22, _ := c.Get(key2) // hold reference of key2 to prevent eviction time.Sleep(3 * time.Second) // wait until elements reach ttl evictedMu.Lock() if len(evicted) != 1 { t.Fatalf("1 content must be removed") } if evicted[0] != key1 { t.Fatalf("1st content %q must be evicted but got %q", key1, evicted[0]) } evictedMu.Unlock() done2() // effective done2() // ignored done2() // ignored evictedMu.Lock() if len(evicted) != 1 { t.Fatalf("only 1 content must be evicted") } evictedMu.Unlock() done22() evictedMu.Lock() if len(evicted) != 2 { t.Fatalf("2 contents must be evicted") } if evicted[1] != key2 { t.Fatalf("2nd content %q must be evicted but got %q", key2, evicted[1]) } evictedMu.Unlock() } stargz-snapshotter-0.14.3/util/containerdutil/000077500000000000000000000000001440204344700214645ustar00rootroot00000000000000stargz-snapshotter-0.14.3/util/containerdutil/manifest.go000066400000000000000000000154461440204344700236330ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package containerdutil import ( "context" "encoding/json" "fmt" "io" "sort" "time" "github.com/containerd/containerd/content" "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/images" "github.com/containerd/containerd/platforms" "github.com/containerd/containerd/remotes" ocispec "github.com/opencontainers/image-spec/specs-go/v1" ) func ManifestDesc(ctx context.Context, provider content.Provider, image ocispec.Descriptor, platform platforms.MatchComparer) (ocispec.Descriptor, error) { var ( limit = 1 m []ocispec.Descriptor wasIndex bool ) if err := images.Walk(ctx, images.HandlerFunc(func(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) { switch desc.MediaType { case images.MediaTypeDockerSchema2Manifest, ocispec.MediaTypeImageManifest: p, err := content.ReadBlob(ctx, provider, desc) if err != nil { return nil, err } if err := ValidateMediaType(p, desc.MediaType); err != nil { return nil, err } var manifest ocispec.Manifest if err := json.Unmarshal(p, &manifest); err != nil { return nil, err } if desc.Digest != image.Digest { if desc.Platform != nil && !platform.Match(*desc.Platform) { return nil, nil } if desc.Platform == nil { p, err := content.ReadBlob(ctx, provider, manifest.Config) if err != nil { return nil, err } var image ocispec.Image if err := json.Unmarshal(p, &image); err != nil { return nil, err } if !platform.Match(platforms.Normalize(ocispec.Platform{OS: image.OS, Architecture: image.Architecture})) { return nil, nil } } } m = append(m, desc) return nil, nil case images.MediaTypeDockerSchema2ManifestList, ocispec.MediaTypeImageIndex: p, err := content.ReadBlob(ctx, provider, desc) if err != nil { return nil, err } if err := ValidateMediaType(p, desc.MediaType); err != nil { return nil, err } var idx ocispec.Index if err := json.Unmarshal(p, &idx); err != nil { return nil, err } var descs []ocispec.Descriptor for _, d := range idx.Manifests { if d.Platform == nil || platform.Match(*d.Platform) { descs = append(descs, d) } } sort.SliceStable(descs, func(i, j int) bool { if descs[i].Platform == nil { return false } if descs[j].Platform == nil { return true } return platform.Less(*descs[i].Platform, *descs[j].Platform) }) wasIndex = true if len(descs) > limit { return descs[:limit], nil } return descs, nil } return nil, fmt.Errorf("unexpected media type %v for %v: %w", desc.MediaType, desc.Digest, errdefs.ErrNotFound) }), image); err != nil { return ocispec.Descriptor{}, err } if len(m) == 0 { err := fmt.Errorf("manifest %v: %w", image.Digest, errdefs.ErrNotFound) if wasIndex { err = fmt.Errorf("no match for platform in manifest %v: %w", image.Digest, errdefs.ErrNotFound) } return ocispec.Descriptor{}, err } return m[0], nil } // Forked from github.com/containerd/containerd/images/image.go // commit: a776a27af54a803657d002e7574a4425b3949f56 // unknownDocument represents a manifest, manifest list, or index that has not // yet been validated. type unknownDocument struct { MediaType string `json:"mediaType,omitempty"` Config json.RawMessage `json:"config,omitempty"` Layers json.RawMessage `json:"layers,omitempty"` Manifests json.RawMessage `json:"manifests,omitempty"` FSLayers json.RawMessage `json:"fsLayers,omitempty"` // schema 1 } // ValidateMediaType returns an error if the byte slice is invalid JSON or if // the media type identifies the blob as one format but it contains elements of // another format. func ValidateMediaType(b []byte, mt string) error { var doc unknownDocument if err := json.Unmarshal(b, &doc); err != nil { return err } if len(doc.FSLayers) != 0 { return fmt.Errorf("media-type: schema 1 not supported") } switch mt { case images.MediaTypeDockerSchema2Manifest, ocispec.MediaTypeImageManifest: if len(doc.Manifests) != 0 || doc.MediaType == images.MediaTypeDockerSchema2ManifestList || doc.MediaType == ocispec.MediaTypeImageIndex { return fmt.Errorf("media-type: expected manifest but found index (%s)", mt) } case images.MediaTypeDockerSchema2ManifestList, ocispec.MediaTypeImageIndex: if len(doc.Config) != 0 || len(doc.Layers) != 0 || doc.MediaType == images.MediaTypeDockerSchema2Manifest || doc.MediaType == ocispec.MediaTypeImageManifest { return fmt.Errorf("media-type: expected index but found manifest (%s)", mt) } } return nil } // Fetch manifest of the specified platform func FetchManifestPlatform(ctx context.Context, fetcher remotes.Fetcher, desc ocispec.Descriptor, platform ocispec.Platform) (ocispec.Manifest, error) { ctx, cancel := context.WithTimeout(ctx, time.Minute) defer cancel() r, err := fetcher.Fetch(ctx, desc) if err != nil { return ocispec.Manifest{}, err } defer r.Close() var manifest ocispec.Manifest switch desc.MediaType { case images.MediaTypeDockerSchema2Manifest, ocispec.MediaTypeImageManifest: p, err := io.ReadAll(r) if err != nil { return ocispec.Manifest{}, err } if err := ValidateMediaType(p, desc.MediaType); err != nil { return ocispec.Manifest{}, err } if err := json.Unmarshal(p, &manifest); err != nil { return ocispec.Manifest{}, err } return manifest, nil case images.MediaTypeDockerSchema2ManifestList, ocispec.MediaTypeImageIndex: var index ocispec.Index p, err := io.ReadAll(r) if err != nil { return ocispec.Manifest{}, err } if err := ValidateMediaType(p, desc.MediaType); err != nil { return ocispec.Manifest{}, err } if err = json.Unmarshal(p, &index); err != nil { return ocispec.Manifest{}, err } var target ocispec.Descriptor found := false for _, m := range index.Manifests { p := platforms.DefaultSpec() if m.Platform != nil { p = *m.Platform } if !platforms.NewMatcher(platform).Match(p) { continue } target = m found = true break } if !found { return ocispec.Manifest{}, fmt.Errorf("no manifest found for platform") } return FetchManifestPlatform(ctx, fetcher, target, platform) } return ocispec.Manifest{}, fmt.Errorf("unknown mediatype %q", desc.MediaType) } stargz-snapshotter-0.14.3/util/criutil/000077500000000000000000000000001440204344700201135ustar00rootroot00000000000000stargz-snapshotter-0.14.3/util/criutil/alpha.go000066400000000000000000000026071440204344700215340ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ // Copied from https://github.com/containerd/containerd/blob/v1.7.0-beta.2/pkg/cri/util/alpha.go // for allowing building stargz-snapshotter with older version of containerd package criutil import ( "github.com/containerd/containerd/protobuf/proto" "google.golang.org/protobuf/reflect/protoreflect" ) func AlphaReqToV1Req( alphar protoreflect.ProtoMessage, v1r interface{ Unmarshal(_ []byte) error }, ) error { p, err := proto.Marshal(alphar) if err != nil { return err } if err = v1r.Unmarshal(p); err != nil { return err } return nil } func V1RespToAlphaResp( v1res interface{ Marshal() ([]byte, error) }, alphares protoreflect.ProtoMessage, ) error { p, err := v1res.Marshal() if err != nil { return err } if err = proto.Unmarshal(p, alphares); err != nil { return err } return nil } stargz-snapshotter-0.14.3/util/ioutils/000077500000000000000000000000001440204344700201305ustar00rootroot00000000000000stargz-snapshotter-0.14.3/util/ioutils/countwriter.go000066400000000000000000000016061440204344700230470ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package ioutils import "sync" type CountWriter struct { n int64 mu sync.Mutex } func (c *CountWriter) Write(p []byte) (n int, err error) { c.mu.Lock() c.n += int64(len(p)) c.mu.Unlock() return len(p), nil } func (c *CountWriter) Size() (n int64) { c.mu.Lock() n = c.n c.mu.Unlock() return } stargz-snapshotter-0.14.3/util/namedmutex/000077500000000000000000000000001440204344700206075ustar00rootroot00000000000000stargz-snapshotter-0.14.3/util/namedmutex/namedmutex.go000066400000000000000000000027571440204344700233200ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ // Package namedmutex provides NamedMutex that wraps sync.Mutex // and provides namespaced mutex. package namedmutex import ( "sync" ) // NamedMutex wraps sync.Mutex and provides namespaced mutex. type NamedMutex struct { muMap map[string]*sync.Mutex refMap map[string]int mu sync.Mutex } // Lock locks the mutex of the given name func (nl *NamedMutex) Lock(name string) { nl.mu.Lock() if nl.muMap == nil { nl.muMap = make(map[string]*sync.Mutex) } if nl.refMap == nil { nl.refMap = make(map[string]int) } if _, ok := nl.muMap[name]; !ok { nl.muMap[name] = &sync.Mutex{} } mu := nl.muMap[name] nl.refMap[name]++ nl.mu.Unlock() mu.Lock() } // Unlock unlocks the mutex of the given name func (nl *NamedMutex) Unlock(name string) { nl.mu.Lock() mu := nl.muMap[name] nl.refMap[name]-- if nl.refMap[name] <= 0 { delete(nl.muMap, name) delete(nl.refMap, name) } nl.mu.Unlock() mu.Unlock() } stargz-snapshotter-0.14.3/util/testutil/000077500000000000000000000000001440204344700203155ustar00rootroot00000000000000stargz-snapshotter-0.14.3/util/testutil/compression.go000066400000000000000000000045411440204344700232110ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package testutil import ( "bytes" "io" "github.com/containerd/stargz-snapshotter/estargz" esgzexternaltoc "github.com/containerd/stargz-snapshotter/estargz/externaltoc" "github.com/containerd/stargz-snapshotter/estargz/zstdchunked" "github.com/klauspost/compress/zstd" ) type Compression interface { estargz.Compressor estargz.Decompressor // DecompressTOC decompresses the passed blob and returns a reader of TOC JSON. // This is needed to be used from metadata pkg DecompressTOC(io.Reader) (tocJSON io.ReadCloser, err error) } type CompressionFactory func() Compression type zstdCompression struct { *zstdchunked.Compressor *zstdchunked.Decompressor } func ZstdCompressionWithLevel(compressionLevel zstd.EncoderLevel) CompressionFactory { return func() Compression { return &zstdCompression{&zstdchunked.Compressor{CompressionLevel: compressionLevel}, &zstdchunked.Decompressor{}} } } type gzipCompression struct { *estargz.GzipCompressor *estargz.GzipDecompressor } func GzipCompressionWithLevel(compressionLevel int) CompressionFactory { return func() Compression { return gzipCompression{estargz.NewGzipCompressorWithLevel(compressionLevel), &estargz.GzipDecompressor{}} } } type externalTOCGzipCompression struct { *esgzexternaltoc.GzipCompressor *esgzexternaltoc.GzipDecompressor } func ExternalTOCGzipCompressionWithLevel(compressionLevel int) CompressionFactory { return func() Compression { compressor := esgzexternaltoc.NewGzipCompressorWithLevel(compressionLevel) decompressor := esgzexternaltoc.NewGzipDecompressor(func() ([]byte, error) { buf := new(bytes.Buffer) if _, err := compressor.WriteTOCTo(buf); err != nil { return nil, err } return buf.Bytes(), nil }) return &externalTOCGzipCompression{compressor, decompressor} } } stargz-snapshotter-0.14.3/util/testutil/ensurehello.go000066400000000000000000000050221440204344700231700ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package testutil import ( "compress/gzip" "context" "fmt" "io" "net/http" "os" "github.com/containerd/containerd/content" "github.com/containerd/containerd/content/local" "github.com/containerd/containerd/images/archive" "github.com/opencontainers/go-digest" ocispec "github.com/opencontainers/image-spec/specs-go/v1" ) const ( // HelloArchiveURL points to an OCI archive of `hello-world`. // Exported from `docker.io/library/hello-world@sha256:1a523af650137b8accdaed439c17d684df61ee4d74feac151b5b337bd29e7eec` . // See https://github.com/AkihiroSuda/test-oci-archives/releases/tag/v20210101 HelloArchiveURL = "https://github.com/AkihiroSuda/test-oci-archives/releases/download/v20210101/hello-world.tar.gz" // HelloArchiveDigest is the digest of the archive. HelloArchiveDigest = "sha256:5aa022621c4de0e941ab2a30d4569c403e156b4ba2de2ec32e382ae8679f40e1" ) // EnsureHello creates a temp content store and ensures `hello-world` image from HelloArchiveURL into the store. func EnsureHello(ctx context.Context) (*ocispec.Descriptor, content.Store, error) { // Pulling an image without the daemon is a mess, so we use OCI archive here. resp, err := http.Get(HelloArchiveURL) if err != nil { return nil, nil, err } defer resp.Body.Close() sha256Digester := digest.SHA256.Digester() sha256Hasher := sha256Digester.Hash() tr := io.TeeReader(resp.Body, sha256Hasher) gzReader, err := gzip.NewReader(tr) if err != nil { return nil, nil, err } tempDir, err := os.MkdirTemp("", "test-estargz") if err != nil { return nil, nil, err } cs, err := local.NewStore(tempDir) if err != nil { return nil, nil, err } desc, err := archive.ImportIndex(ctx, cs, gzReader) if err != nil { return nil, nil, err } resp.Body.Close() if d := sha256Digester.Digest().String(); d != HelloArchiveDigest { err = fmt.Errorf("expected digest of %q to be %q, got %q", HelloArchiveURL, HelloArchiveDigest, d) return nil, nil, err } return &desc, cs, nil } stargz-snapshotter-0.14.3/util/testutil/estargz.go000066400000000000000000000041471440204344700223310ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package testutil import ( "bytes" "io" "github.com/containerd/stargz-snapshotter/estargz" digest "github.com/opencontainers/go-digest" ) type buildEStargzOptions struct { estargzOptions []estargz.Option buildTarOptions []BuildTarOption } type BuildEStargzOption func(o *buildEStargzOptions) error // WithEStargzOptions specifies options for estargz lib func WithEStargzOptions(eo ...estargz.Option) BuildEStargzOption { return func(o *buildEStargzOptions) error { o.estargzOptions = append(o.estargzOptions, eo...) return nil } } // WithBuildTarOptions option specifies the options for tar creation func WithBuildTarOptions(to ...BuildTarOption) BuildEStargzOption { return func(o *buildEStargzOptions) error { o.buildTarOptions = append(o.buildTarOptions, to...) return nil } } func BuildEStargz(ents []TarEntry, opts ...BuildEStargzOption) (*io.SectionReader, digest.Digest, error) { var beOpts buildEStargzOptions for _, o := range opts { o(&beOpts) } tarBuf := new(bytes.Buffer) if _, err := io.Copy(tarBuf, BuildTar(ents, beOpts.buildTarOptions...)); err != nil { return nil, "", err } tarData := tarBuf.Bytes() rc, err := estargz.Build( io.NewSectionReader(bytes.NewReader(tarData), 0, int64(len(tarData))), beOpts.estargzOptions...) if err != nil { return nil, "", err } defer rc.Close() vsb := new(bytes.Buffer) if _, err := io.Copy(vsb, rc); err != nil { return nil, "", err } vsbb := vsb.Bytes() return io.NewSectionReader(bytes.NewReader(vsbb), 0, int64(len(vsbb))), rc.TOCDigest(), nil } stargz-snapshotter-0.14.3/util/testutil/tar.go000066400000000000000000000166651440204344700214500ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package testutil // This utility helps test codes to generate sample tar blobs. import ( "archive/tar" "fmt" "io" "os" "strings" "time" ) // TarEntry is an entry of tar. type TarEntry interface { AppendTar(tw *tar.Writer, opts BuildTarOptions) error } // BuildTarOptions is a set of options used during building blob. type BuildTarOptions struct { // Prefix is the prefix string need to be added to each file name (e.g. "./", "/", etc.) Prefix string } // BuildTarOption is an option used during building blob. type BuildTarOption func(o *BuildTarOptions) // WithPrefix is an option to add a prefix string to each file name (e.g. "./", "/", etc.) func WithPrefix(prefix string) BuildTarOption { return func(o *BuildTarOptions) { o.Prefix = prefix } } // BuildTar builds a tar blob func BuildTar(ents []TarEntry, opts ...BuildTarOption) io.Reader { var bo BuildTarOptions for _, o := range opts { o(&bo) } pr, pw := io.Pipe() go func() { tw := tar.NewWriter(pw) for _, ent := range ents { if err := ent.AppendTar(tw, bo); err != nil { pw.CloseWithError(err) return } } if err := tw.Close(); err != nil { pw.CloseWithError(err) return } pw.Close() }() return pr } type tarEntryFunc func(*tar.Writer, BuildTarOptions) error func (f tarEntryFunc) AppendTar(tw *tar.Writer, opts BuildTarOptions) error { return f(tw, opts) } // DirectoryBuildTarOption is an option for a directory entry. type DirectoryBuildTarOption func(o *dirOpts) type dirOpts struct { uid int gid int xattrs map[string]string mode *os.FileMode modTime time.Time } // WithDirModTime specifies the modtime of the dir. func WithDirModTime(modTime time.Time) DirectoryBuildTarOption { return func(o *dirOpts) { o.modTime = modTime } } // WithDirOwner specifies the owner of the directory. func WithDirOwner(uid, gid int) DirectoryBuildTarOption { return func(o *dirOpts) { o.uid = uid o.gid = gid } } // WithDirXattrs specifies the extended attributes of the directory. func WithDirXattrs(xattrs map[string]string) DirectoryBuildTarOption { return func(o *dirOpts) { o.xattrs = xattrs } } // WithDirMode specifies the mode of the directory. func WithDirMode(mode os.FileMode) DirectoryBuildTarOption { return func(o *dirOpts) { o.mode = &mode } } // Dir is a directory entry func Dir(name string, opts ...DirectoryBuildTarOption) TarEntry { return tarEntryFunc(func(tw *tar.Writer, buildOpts BuildTarOptions) error { var dOpts dirOpts for _, o := range opts { o(&dOpts) } if !strings.HasSuffix(name, "/") { panic(fmt.Sprintf("missing trailing slash in dir %q ", name)) } var mode int64 = 0755 if dOpts.mode != nil { mode = permAndExtraMode2TarMode(*dOpts.mode) } return tw.WriteHeader(&tar.Header{ Typeflag: tar.TypeDir, Name: buildOpts.Prefix + name, Mode: mode, ModTime: dOpts.modTime, Xattrs: dOpts.xattrs, Uid: dOpts.uid, Gid: dOpts.gid, }) }) } // FileBuildTarOption is an option for a file entry. type FileBuildTarOption func(o *fileOpts) type fileOpts struct { uid int gid int xattrs map[string]string mode *os.FileMode modTime time.Time } // WithFileOwner specifies the owner of the file. func WithFileOwner(uid, gid int) FileBuildTarOption { return func(o *fileOpts) { o.uid = uid o.gid = gid } } // WithFileXattrs specifies the extended attributes of the file. func WithFileXattrs(xattrs map[string]string) FileBuildTarOption { return func(o *fileOpts) { o.xattrs = xattrs } } // WithFileModTime specifies the modtime of the file. func WithFileModTime(modTime time.Time) FileBuildTarOption { return func(o *fileOpts) { o.modTime = modTime } } // WithFileMode specifies the mode of the file. func WithFileMode(mode os.FileMode) FileBuildTarOption { return func(o *fileOpts) { o.mode = &mode } } // File is a regilar file entry func File(name, contents string, opts ...FileBuildTarOption) TarEntry { return tarEntryFunc(func(tw *tar.Writer, buildOpts BuildTarOptions) error { var fOpts fileOpts for _, o := range opts { o(&fOpts) } if strings.HasSuffix(name, "/") { return fmt.Errorf("bogus trailing slash in file %q", name) } var mode int64 = 0644 if fOpts.mode != nil { mode = permAndExtraMode2TarMode(*fOpts.mode) } if err := tw.WriteHeader(&tar.Header{ Typeflag: tar.TypeReg, Name: buildOpts.Prefix + name, Mode: mode, ModTime: fOpts.modTime, Xattrs: fOpts.xattrs, Size: int64(len(contents)), Uid: fOpts.uid, Gid: fOpts.gid, }); err != nil { return err } _, err := io.WriteString(tw, contents) return err }) } // Symlink is a symlink entry func Symlink(name, target string) TarEntry { return tarEntryFunc(func(tw *tar.Writer, buildOpts BuildTarOptions) error { return tw.WriteHeader(&tar.Header{ Typeflag: tar.TypeSymlink, Name: buildOpts.Prefix + name, Linkname: target, Mode: 0644, }) }) } // Link is a hard-link entry func Link(name, linkname string) TarEntry { now := time.Now() return tarEntryFunc(func(w *tar.Writer, buildOpts BuildTarOptions) error { return w.WriteHeader(&tar.Header{ Typeflag: tar.TypeLink, Name: buildOpts.Prefix + name, Linkname: linkname, ModTime: now, AccessTime: now, ChangeTime: now, }) }) } // Chardev is a character device entry func Chardev(name string, major, minor int64) TarEntry { now := time.Now() return tarEntryFunc(func(w *tar.Writer, buildOpts BuildTarOptions) error { return w.WriteHeader(&tar.Header{ Typeflag: tar.TypeChar, Name: buildOpts.Prefix + name, Devmajor: major, Devminor: minor, ModTime: now, AccessTime: now, ChangeTime: now, }) }) } // Blockdev is a block device entry func Blockdev(name string, major, minor int64) TarEntry { now := time.Now() return tarEntryFunc(func(w *tar.Writer, buildOpts BuildTarOptions) error { return w.WriteHeader(&tar.Header{ Typeflag: tar.TypeBlock, Name: buildOpts.Prefix + name, Devmajor: major, Devminor: minor, ModTime: now, AccessTime: now, ChangeTime: now, }) }) } // Fifo is a fifo entry func Fifo(name string) TarEntry { now := time.Now() return tarEntryFunc(func(w *tar.Writer, buildOpts BuildTarOptions) error { return w.WriteHeader(&tar.Header{ Typeflag: tar.TypeFifo, Name: buildOpts.Prefix + name, ModTime: now, AccessTime: now, ChangeTime: now, }) }) } // suid, guid, sticky bits for archive/tar // https://github.com/golang/go/blob/release-branch.go1.13/src/archive/tar/common.go#L607-L609 const ( cISUID = 04000 // Set uid cISGID = 02000 // Set gid cISVTX = 01000 // Save text (sticky bit) ) func permAndExtraMode2TarMode(fm os.FileMode) (tm int64) { tm = int64(fm & os.ModePerm) if fm&os.ModeSetuid != 0 { tm |= cISUID } if fm&os.ModeSetgid != 0 { tm |= cISGID } if fm&os.ModeSticky != 0 { tm |= cISVTX } return } stargz-snapshotter-0.14.3/util/testutil/util.go000066400000000000000000000015531440204344700216250ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package testutil import ( "math/rand" "testing" ) // RandomBytes returns the specified number of random bytes func RandomBytes(t *testing.T, n int) []byte { b := make([]byte, n) if _, err := rand.Read(b); err != nil { t.Fatalf("failed rand.Read: %v", err) } return b } stargz-snapshotter-0.14.3/version/000077500000000000000000000000001440204344700171505ustar00rootroot00000000000000stargz-snapshotter-0.14.3/version/version.go000066400000000000000000000015011440204344700211610ustar00rootroot00000000000000/* Copyright The containerd Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package version var ( // Version is the version number. Filled in at linking time (via Makefile). Version = "" // Revision is the VCS (e.g. git) revision. Filled in at linking time (via Makefile). Revision = "" )