pax_global_header00006660000000000000000000000064152167714140014522gustar00rootroot0000000000000052 comment=4d8a9399575f6a8a89e3fa4c2591f21070e40250 math-comp-hierarchy-builder-4d8a939/000077500000000000000000000000001521677141400173565ustar00rootroot00000000000000math-comp-hierarchy-builder-4d8a939/.gitattributes000066400000000000000000000000401521677141400222430ustar00rootroot00000000000000*.elpi linguist-language=prolog math-comp-hierarchy-builder-4d8a939/.github/000077500000000000000000000000001521677141400207165ustar00rootroot00000000000000math-comp-hierarchy-builder-4d8a939/.github/workflows/000077500000000000000000000000001521677141400227535ustar00rootroot00000000000000math-comp-hierarchy-builder-4d8a939/.github/workflows/main.yml000066400000000000000000000053331521677141400244260ustar00rootroot00000000000000# This is a basic workflow to help you get started with Actions name: docker CI # Controls when the action will run. Triggers the workflow on push or pull request # events but only for the master branch on: push: branches: [ master ] tags: [ "v*.*.*" ] pull_request: branches: [ master ] jobs: opam: runs-on: ubuntu-latest strategy: fail-fast: false matrix: coq_version: - '8.20' - '9.0' - '9.1' - '9.2' steps: - uses: actions/checkout@v2 - uses: coq-community/docker-coq-action@v1 with: opam_file: './rocq-hierarchy-builder.opam' coq_version: ${{ matrix.coq_version }} export: 'OPAMWITHTEST' # space-separated list of variables env: OPAMWITHTEST: 'true' release: runs-on: ubuntu-latest if: startsWith(github.ref, 'refs/tags/') needs: [opam] steps: - name: Checkout uses: actions/checkout@v3 - name: Inject slug/short variables uses: rlespinasse/github-slug-action@v4 - name: Create archive run: | VERSION="${GITHUB_REF_NAME_SLUG#v}" git archive -o hierarchy-builder-$VERSION.tar.gz --prefix=hierarchy-builder-$VERSION/ $GITHUB_SHA . - name: Release uses: softprops/action-gh-release@v1 with: files: hierarchy-builder-*.tar.gz fail_on_unmatched_files: true prerelease: true generate_release_notes: true name: Hierarchy Builder ${{ github.ref }} - name: Use OCaml 4.14.x uses: ocaml/setup-ocaml@v3 with: ocaml-compiler: 4.14.x opam-local-packages: | !coq-hierarchy-builder*.opam - name: Write PAT env: OPAM_PUBLISH_TOKEN: ${{ secrets.OPAM_PUBLISH_TOKEN }} run: | mkdir -p ~/.opam/plugins/opam-publish printf "$OPAM_PUBLISH_TOKEN" > ~/.opam/plugins/opam-publish/coqelpibot.token - name: Setup SSH uses: webfactory/ssh-agent@v0.8.0 with: ssh-private-key: ${{ secrets.BOT_SSH_KEY }} - name: Install opam-publish # 2.0.3 because more recent versions do not respect OPAMYES run: opam install -y -j 2 opam-publish=2.0.3 - name: Publish run: | eval $(opam env) git config --global user.name coqelpibot git config --global user.email coqelpibot@inria.fr OPAM_SUITE=released TAG=`git tag --sort=-v:refname|head -1` opam-publish --tag=$TAG --packages-directory=$OPAM_SUITE/packages --repo=coq/opam --no-browser -v ${TAG##v} https://github.com/math-comp/hierarchy-builder/releases/download/$TAG/hierarchy-builder-${TAG##v}.tar.gz math-comp-hierarchy-builder-4d8a939/.github/workflows/nix-action-rocq-9.0.yml000066400000000000000000004005521521677141400270230ustar00rootroot00000000000000jobs: ExtLib: needs: - coq runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (ExtLib) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.0\" --argstr job \"ExtLib\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "ExtLib" QuickChick: needs: - coq - mathcomp-boot - ExtLib - simple-io runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (QuickChick) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.0\" --argstr job \"QuickChick\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: ExtLib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "ExtLib" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: simple-io' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "simple-io" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "QuickChick" coq: needs: - rocq-core runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (coq) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.0\" --argstr job \"coq\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "coq" coq-bits: needs: - coq - mathcomp-algebra - mathcomp-algebra-tactics runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (coq-bits) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.0\" --argstr job \"coq-bits\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra-tactics' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-algebra-tactics" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "coq-bits" coqeal: needs: - coq - mathcomp-ssreflect - mathcomp-algebra - multinomials - mathcomp-real-closed runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (coqeal) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.0\" --argstr job \"coqeal\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-ssreflect' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-ssreflect" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: bignums' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "bignums" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: multinomials' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "multinomials" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-real-closed' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-real-closed" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "coqeal" coquelicot: needs: - coq - mathcomp-boot runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (coquelicot) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.0\" --argstr job \"coquelicot\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "coquelicot" deriving: needs: - coq - mathcomp-ssreflect runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (deriving) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.0\" --argstr job \"deriving\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-ssreflect' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-ssreflect" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "deriving" fourcolor: needs: - coq - mathcomp-boot - mathcomp-fingroup - mathcomp-algebra runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (fourcolor) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.0\" --argstr job \"fourcolor\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-fingroup' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-fingroup" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "fourcolor" hierarchy-builder: needs: - rocq-core runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (hierarchy-builder) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.0\" --argstr job \"hierarchy-builder\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq-elpi' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "coq-elpi" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "hierarchy-builder" mathcomp: needs: - rocq-core - mathcomp-character - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.0\" --argstr job \"mathcomp\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-character' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-character" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp" mathcomp-algebra: needs: - rocq-core - mathcomp-order - mathcomp-fingroup - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-algebra) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.0\" --argstr job \"mathcomp-algebra\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-order' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-order" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-fingroup' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-fingroup" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: micromega-plugin' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "micromega-plugin" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-algebra" mathcomp-algebra-tactics: needs: - coq - mathcomp-ssreflect - mathcomp-algebra - mathcomp-zify runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-algebra-tactics) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.0\" --argstr job \"mathcomp-algebra-tactics\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"\ Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-ssreflect' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-ssreflect" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq-elpi' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "coq-elpi" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-zify' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-zify" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-algebra-tactics" mathcomp-analysis: needs: - coq - mathcomp-reals - mathcomp-field - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-analysis) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.0\" --argstr job \"mathcomp-analysis\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-reals' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-reals" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-field' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-field" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-analysis" mathcomp-analysis-stdlib: needs: - coq - mathcomp-analysis - mathcomp-reals-stdlib - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-analysis-stdlib) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.0\" --argstr job \"mathcomp-analysis-stdlib\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"\ Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-analysis' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-analysis" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-reals-stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-reals-stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-analysis-stdlib" mathcomp-bigenough: needs: - rocq-core - mathcomp-boot runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-bigenough) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.0\" --argstr job \"mathcomp-bigenough\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-bigenough" mathcomp-boot: needs: - rocq-core - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-boot) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.0\" --argstr job \"mathcomp-boot\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-boot" mathcomp-character: needs: - rocq-core - mathcomp-field - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-character) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.0\" --argstr job \"mathcomp-character\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-field' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-field" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-character" mathcomp-classical: needs: - coq - mathcomp-ssreflect - mathcomp-algebra - mathcomp-finmap - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-classical) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.0\" --argstr job \"mathcomp-classical\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-ssreflect' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-ssreflect" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-finmap' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-finmap" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-classical" mathcomp-experimental-reals: needs: - coq - mathcomp-reals - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-experimental-reals) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.0\" --argstr job \"mathcomp-experimental-reals\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-reals' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-reals" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-experimental-reals" mathcomp-field: needs: - rocq-core - mathcomp-solvable - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-field) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.0\" --argstr job \"mathcomp-field\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-solvable' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-solvable" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-field" mathcomp-fingroup: needs: - rocq-core - mathcomp-boot - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-fingroup) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.0\" --argstr job \"mathcomp-fingroup\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-fingroup" mathcomp-finmap: needs: - coq - mathcomp-boot runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-finmap) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.0\" --argstr job \"mathcomp-finmap\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-finmap" mathcomp-order: needs: - rocq-core - mathcomp-boot - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-order) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.0\" --argstr job \"mathcomp-order\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-order" mathcomp-real-closed: needs: - coq - mathcomp-ssreflect - mathcomp-algebra - mathcomp-field - mathcomp-fingroup - mathcomp-solvable runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-real-closed) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.0\" --argstr job \"mathcomp-real-closed\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-ssreflect' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-ssreflect" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-field' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-field" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-fingroup' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-fingroup" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-solvable' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-solvable" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-real-closed" mathcomp-reals: needs: - coq - mathcomp-classical - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-reals) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.0\" --argstr job \"mathcomp-reals\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-classical' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-classical" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-reals" mathcomp-reals-stdlib: needs: - coq - mathcomp-reals - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-reals-stdlib) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.0\" --argstr job \"mathcomp-reals-stdlib\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-reals' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-reals" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-reals-stdlib" mathcomp-single: needs: - rocq-core - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-single) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.0\" --argstr job \"mathcomp-single\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: micromega-plugin' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "micromega-plugin" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-single" mathcomp-solvable: needs: - rocq-core - mathcomp-algebra - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-solvable) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.0\" --argstr job \"mathcomp-solvable\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-solvable" mathcomp-ssreflect: needs: - coq - mathcomp-boot - mathcomp-order runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-ssreflect) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.0\" --argstr job \"mathcomp-ssreflect\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-order' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-order" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-ssreflect" mathcomp-word: needs: - coq - mathcomp-algebra - mathcomp-ssreflect - mathcomp-fingroup runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-word) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.0\" --argstr job \"mathcomp-word\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-ssreflect' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-ssreflect" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-fingroup' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-fingroup" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-word" mathcomp-zify: needs: - coq - mathcomp-boot - mathcomp-algebra - mathcomp-fingroup runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-zify) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.0\" --argstr job \"mathcomp-zify\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-fingroup' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-fingroup" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-zify" multinomials: needs: - coq - mathcomp-boot - mathcomp-algebra - mathcomp-finmap - mathcomp-fingroup runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (multinomials) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.0\" --argstr job \"multinomials\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-finmap' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-finmap" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-fingroup' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-fingroup" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "multinomials" odd-order: needs: - coq - mathcomp-character runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (odd-order) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.0\" --argstr job \"odd-order\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-character' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-character" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "odd-order" reglang: needs: - coq - mathcomp-ssreflect runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (reglang) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.0\" --argstr job \"reglang\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-ssreflect' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-ssreflect" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "reglang" rocq-core: needs: [] runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (rocq-core) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.0\" --argstr job \"rocq-core\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "rocq-core" simple-io: needs: - coq - ExtLib runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (simple-io) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.0\" --argstr job \"simple-io\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: ExtLib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "ExtLib" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "simple-io" name: Nix CI for bundle rocq-9.0 on: pull_request: paths: - .github/workflows/nix-action-rocq-9.0.yml pull_request_target: paths-ignore: - .github/workflows/nix-action-rocq-9.0.yml types: - opened - synchronize - reopened push: branches: - master math-comp-hierarchy-builder-4d8a939/.github/workflows/nix-action-rocq-9.1.yml000066400000000000000000004005521521677141400270240ustar00rootroot00000000000000jobs: ExtLib: needs: - coq runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (ExtLib) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.1\" --argstr job \"ExtLib\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "ExtLib" QuickChick: needs: - coq - mathcomp-boot - ExtLib - simple-io runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (QuickChick) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.1\" --argstr job \"QuickChick\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: ExtLib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "ExtLib" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: simple-io' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "simple-io" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "QuickChick" coq: needs: - rocq-core runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (coq) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.1\" --argstr job \"coq\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "coq" coq-bits: needs: - coq - mathcomp-algebra - mathcomp-algebra-tactics runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (coq-bits) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.1\" --argstr job \"coq-bits\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra-tactics' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-algebra-tactics" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "coq-bits" coqeal: needs: - coq - mathcomp-ssreflect - mathcomp-algebra - multinomials - mathcomp-real-closed runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (coqeal) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.1\" --argstr job \"coqeal\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-ssreflect' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-ssreflect" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: bignums' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "bignums" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: multinomials' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "multinomials" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-real-closed' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-real-closed" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "coqeal" coquelicot: needs: - coq - mathcomp-boot runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (coquelicot) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.1\" --argstr job \"coquelicot\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "coquelicot" deriving: needs: - coq - mathcomp-ssreflect runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (deriving) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.1\" --argstr job \"deriving\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-ssreflect' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-ssreflect" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "deriving" fourcolor: needs: - coq - mathcomp-boot - mathcomp-fingroup - mathcomp-algebra runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (fourcolor) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.1\" --argstr job \"fourcolor\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-fingroup' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-fingroup" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "fourcolor" hierarchy-builder: needs: - rocq-core runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (hierarchy-builder) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.1\" --argstr job \"hierarchy-builder\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq-elpi' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "coq-elpi" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "hierarchy-builder" mathcomp: needs: - rocq-core - mathcomp-character - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.1\" --argstr job \"mathcomp\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-character' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-character" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp" mathcomp-algebra: needs: - rocq-core - mathcomp-order - mathcomp-fingroup - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-algebra) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.1\" --argstr job \"mathcomp-algebra\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-order' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-order" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-fingroup' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-fingroup" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: micromega-plugin' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "micromega-plugin" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-algebra" mathcomp-algebra-tactics: needs: - coq - mathcomp-ssreflect - mathcomp-algebra - mathcomp-zify runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-algebra-tactics) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.1\" --argstr job \"mathcomp-algebra-tactics\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"\ Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-ssreflect' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-ssreflect" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq-elpi' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "coq-elpi" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-zify' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-zify" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-algebra-tactics" mathcomp-analysis: needs: - coq - mathcomp-reals - mathcomp-field - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-analysis) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.1\" --argstr job \"mathcomp-analysis\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-reals' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-reals" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-field' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-field" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-analysis" mathcomp-analysis-stdlib: needs: - coq - mathcomp-analysis - mathcomp-reals-stdlib - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-analysis-stdlib) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.1\" --argstr job \"mathcomp-analysis-stdlib\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"\ Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-analysis' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-analysis" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-reals-stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-reals-stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-analysis-stdlib" mathcomp-bigenough: needs: - rocq-core - mathcomp-boot runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-bigenough) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.1\" --argstr job \"mathcomp-bigenough\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-bigenough" mathcomp-boot: needs: - rocq-core - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-boot) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.1\" --argstr job \"mathcomp-boot\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-boot" mathcomp-character: needs: - rocq-core - mathcomp-field - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-character) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.1\" --argstr job \"mathcomp-character\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-field' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-field" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-character" mathcomp-classical: needs: - coq - mathcomp-ssreflect - mathcomp-algebra - mathcomp-finmap - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-classical) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.1\" --argstr job \"mathcomp-classical\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-ssreflect' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-ssreflect" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-finmap' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-finmap" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-classical" mathcomp-experimental-reals: needs: - coq - mathcomp-reals - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-experimental-reals) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.1\" --argstr job \"mathcomp-experimental-reals\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-reals' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-reals" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-experimental-reals" mathcomp-field: needs: - rocq-core - mathcomp-solvable - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-field) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.1\" --argstr job \"mathcomp-field\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-solvable' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-solvable" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-field" mathcomp-fingroup: needs: - rocq-core - mathcomp-boot - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-fingroup) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.1\" --argstr job \"mathcomp-fingroup\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-fingroup" mathcomp-finmap: needs: - coq - mathcomp-boot runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-finmap) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.1\" --argstr job \"mathcomp-finmap\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-finmap" mathcomp-order: needs: - rocq-core - mathcomp-boot - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-order) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.1\" --argstr job \"mathcomp-order\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-order" mathcomp-real-closed: needs: - coq - mathcomp-ssreflect - mathcomp-algebra - mathcomp-field - mathcomp-fingroup - mathcomp-solvable runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-real-closed) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.1\" --argstr job \"mathcomp-real-closed\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-ssreflect' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-ssreflect" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-field' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-field" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-fingroup' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-fingroup" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-solvable' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-solvable" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-real-closed" mathcomp-reals: needs: - coq - mathcomp-classical - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-reals) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.1\" --argstr job \"mathcomp-reals\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-classical' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-classical" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-reals" mathcomp-reals-stdlib: needs: - coq - mathcomp-reals - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-reals-stdlib) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.1\" --argstr job \"mathcomp-reals-stdlib\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-reals' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-reals" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-reals-stdlib" mathcomp-single: needs: - rocq-core - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-single) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.1\" --argstr job \"mathcomp-single\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: micromega-plugin' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "micromega-plugin" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-single" mathcomp-solvable: needs: - rocq-core - mathcomp-algebra - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-solvable) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.1\" --argstr job \"mathcomp-solvable\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-solvable" mathcomp-ssreflect: needs: - coq - mathcomp-boot - mathcomp-order runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-ssreflect) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.1\" --argstr job \"mathcomp-ssreflect\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-order' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-order" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-ssreflect" mathcomp-word: needs: - coq - mathcomp-algebra - mathcomp-ssreflect - mathcomp-fingroup runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-word) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.1\" --argstr job \"mathcomp-word\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-ssreflect' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-ssreflect" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-fingroup' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-fingroup" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-word" mathcomp-zify: needs: - coq - mathcomp-boot - mathcomp-algebra - mathcomp-fingroup runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-zify) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.1\" --argstr job \"mathcomp-zify\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-fingroup' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-fingroup" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-zify" multinomials: needs: - coq - mathcomp-boot - mathcomp-algebra - mathcomp-finmap - mathcomp-fingroup runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (multinomials) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.1\" --argstr job \"multinomials\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-finmap' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-finmap" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-fingroup' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-fingroup" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "multinomials" odd-order: needs: - coq - mathcomp-character runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (odd-order) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.1\" --argstr job \"odd-order\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-character' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-character" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "odd-order" reglang: needs: - coq - mathcomp-ssreflect runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (reglang) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.1\" --argstr job \"reglang\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-ssreflect' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-ssreflect" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "reglang" rocq-core: needs: [] runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (rocq-core) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.1\" --argstr job \"rocq-core\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "rocq-core" simple-io: needs: - coq - ExtLib runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (simple-io) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.1\" --argstr job \"simple-io\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: ExtLib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "ExtLib" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "simple-io" name: Nix CI for bundle rocq-9.1 on: pull_request: paths: - .github/workflows/nix-action-rocq-9.1.yml pull_request_target: paths-ignore: - .github/workflows/nix-action-rocq-9.1.yml types: - opened - synchronize - reopened push: branches: - master math-comp-hierarchy-builder-4d8a939/.github/workflows/nix-action-rocq-9.2.yml000066400000000000000000004026601521677141400270270ustar00rootroot00000000000000jobs: ExtLib: needs: - coq runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (ExtLib) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.2\" --argstr job \"ExtLib\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "ExtLib" QuickChick: needs: - coq - mathcomp-boot - ExtLib - simple-io runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (QuickChick) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.2\" --argstr job \"QuickChick\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: ExtLib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "ExtLib" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: simple-io' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "simple-io" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "QuickChick" coq: needs: - rocq-core runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (coq) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.2\" --argstr job \"coq\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "coq" coq-bits: needs: - coq - mathcomp-algebra - mathcomp-algebra-tactics runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (coq-bits) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.2\" --argstr job \"coq-bits\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra-tactics' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-algebra-tactics" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "coq-bits" coqeal: needs: - coq - mathcomp-ssreflect - mathcomp-algebra - multinomials - mathcomp-real-closed runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (coqeal) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.2\" --argstr job \"coqeal\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-ssreflect' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-ssreflect" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: bignums' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "bignums" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: multinomials' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "multinomials" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-real-closed' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-real-closed" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "coqeal" coquelicot: needs: - coq - mathcomp-boot runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (coquelicot) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.2\" --argstr job \"coquelicot\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "coquelicot" deriving: needs: - coq - mathcomp-ssreflect runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (deriving) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.2\" --argstr job \"deriving\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-ssreflect' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-ssreflect" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "deriving" fourcolor: needs: - coq - mathcomp-boot - mathcomp-fingroup - mathcomp-algebra runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (fourcolor) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.2\" --argstr job \"fourcolor\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-fingroup' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-fingroup" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "fourcolor" hierarchy-builder: needs: - rocq-core runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (hierarchy-builder) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.2\" --argstr job \"hierarchy-builder\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq-elpi' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "coq-elpi" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "hierarchy-builder" mathcomp: needs: - rocq-core - mathcomp-character - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.2\" --argstr job \"mathcomp\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-character' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-character" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp" mathcomp-algebra: needs: - rocq-core - mathcomp-order - mathcomp-fingroup - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-algebra) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.2\" --argstr job \"mathcomp-algebra\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-order' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-order" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-fingroup' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-fingroup" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: micromega-plugin' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "micromega-plugin" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-algebra" mathcomp-algebra-tactics: needs: - coq - mathcomp-ssreflect - mathcomp-algebra - mathcomp-zify runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-algebra-tactics) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.2\" --argstr job \"mathcomp-algebra-tactics\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"\ Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-ssreflect' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-ssreflect" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq-elpi' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "coq-elpi" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-zify' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-zify" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-algebra-tactics" mathcomp-analysis: needs: - coq - mathcomp-reals - mathcomp-field - mathcomp-bigenough - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-analysis) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.2\" --argstr job \"mathcomp-analysis\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-reals' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-reals" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-field' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-field" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-bigenough' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-bigenough" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-analysis" mathcomp-analysis-stdlib: needs: - coq - mathcomp-analysis - mathcomp-reals-stdlib - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-analysis-stdlib) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.2\" --argstr job \"mathcomp-analysis-stdlib\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"\ Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-analysis' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-analysis" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-reals-stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-reals-stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-analysis-stdlib" mathcomp-bigenough: needs: - coq - mathcomp-boot runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-bigenough) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.2\" --argstr job \"mathcomp-bigenough\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-bigenough" mathcomp-boot: needs: - rocq-core - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-boot) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.2\" --argstr job \"mathcomp-boot\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-boot" mathcomp-character: needs: - rocq-core - mathcomp-field - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-character) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.2\" --argstr job \"mathcomp-character\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-field' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-field" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-character" mathcomp-classical: needs: - coq - mathcomp-ssreflect - mathcomp-algebra - mathcomp-finmap - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-classical) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.2\" --argstr job \"mathcomp-classical\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-ssreflect' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-ssreflect" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-finmap' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-finmap" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-classical" mathcomp-experimental-reals: needs: - coq - mathcomp-reals - mathcomp-bigenough - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-experimental-reals) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.2\" --argstr job \"mathcomp-experimental-reals\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-reals' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-reals" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-bigenough' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-bigenough" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-experimental-reals" mathcomp-field: needs: - rocq-core - mathcomp-solvable - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-field) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.2\" --argstr job \"mathcomp-field\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-solvable' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-solvable" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-field" mathcomp-fingroup: needs: - rocq-core - mathcomp-boot - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-fingroup) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.2\" --argstr job \"mathcomp-fingroup\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-fingroup" mathcomp-finmap: needs: - coq - mathcomp-boot runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-finmap) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.2\" --argstr job \"mathcomp-finmap\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-finmap" mathcomp-order: needs: - rocq-core - mathcomp-boot - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-order) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.2\" --argstr job \"mathcomp-order\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-order" mathcomp-real-closed: needs: - coq - mathcomp-ssreflect - mathcomp-algebra - mathcomp-field - mathcomp-fingroup - mathcomp-solvable - mathcomp-bigenough runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-real-closed) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.2\" --argstr job \"mathcomp-real-closed\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-ssreflect' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-ssreflect" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-field' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-field" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-fingroup' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-fingroup" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-solvable' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-solvable" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-bigenough' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-bigenough" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-real-closed" mathcomp-reals: needs: - coq - mathcomp-classical - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-reals) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.2\" --argstr job \"mathcomp-reals\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-classical' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-classical" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-reals" mathcomp-reals-stdlib: needs: - coq - mathcomp-reals - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-reals-stdlib) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.2\" --argstr job \"mathcomp-reals-stdlib\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-reals' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-reals" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-reals-stdlib" mathcomp-single: needs: - rocq-core - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-single) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.2\" --argstr job \"mathcomp-single\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: micromega-plugin' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "micromega-plugin" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-single" mathcomp-solvable: needs: - rocq-core - mathcomp-algebra - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-solvable) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.2\" --argstr job \"mathcomp-solvable\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-solvable" mathcomp-ssreflect: needs: - coq - mathcomp-boot - mathcomp-order runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-ssreflect) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.2\" --argstr job \"mathcomp-ssreflect\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-order' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-order" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-ssreflect" mathcomp-word: needs: - coq - mathcomp-algebra - mathcomp-ssreflect - mathcomp-fingroup runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-word) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.2\" --argstr job \"mathcomp-word\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-ssreflect' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-ssreflect" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-fingroup' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-fingroup" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-word" mathcomp-zify: needs: - coq - mathcomp-boot - mathcomp-algebra - mathcomp-fingroup runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-zify) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.2\" --argstr job \"mathcomp-zify\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-fingroup' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-fingroup" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-zify" multinomials: needs: - coq - mathcomp-boot - mathcomp-algebra - mathcomp-finmap - mathcomp-fingroup - mathcomp-bigenough runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (multinomials) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.2\" --argstr job \"multinomials\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-finmap' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-finmap" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-fingroup' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-fingroup" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-bigenough' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-bigenough" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "multinomials" odd-order: needs: - coq - mathcomp-character runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (odd-order) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.2\" --argstr job \"odd-order\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-character' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-character" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "odd-order" reglang: needs: - coq - mathcomp-ssreflect runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (reglang) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.2\" --argstr job \"reglang\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-ssreflect' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-ssreflect" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "reglang" rocq-core: needs: [] runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (rocq-core) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.2\" --argstr job \"rocq-core\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "rocq-core" simple-io: needs: - coq - ExtLib runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (simple-io) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.2\" --argstr job \"simple-io\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: ExtLib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "ExtLib" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "simple-io" name: Nix CI for bundle rocq-9.2 on: pull_request: paths: - .github/workflows/nix-action-rocq-9.2.yml pull_request_target: paths-ignore: - .github/workflows/nix-action-rocq-9.2.yml types: - opened - synchronize - reopened push: branches: - master math-comp-hierarchy-builder-4d8a939/.github/workflows/nix-action-rocq-master.yml000066400000000000000000004330141521677141400300070ustar00rootroot00000000000000jobs: ExtLib: needs: - coq - stdlib runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (ExtLib) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"ExtLib\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "ExtLib" QuickChick: needs: - coq - mathcomp-boot - ExtLib - simple-io runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (QuickChick) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"QuickChick\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: ExtLib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "ExtLib" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: simple-io' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "simple-io" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "QuickChick" bignums: needs: - rocq-core - stdlib runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (bignums) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"bignums\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "bignums" coq: needs: - rocq-core runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (coq) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"coq\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "coq" coq-bits: needs: - coq - mathcomp-algebra - mathcomp-algebra-tactics - stdlib runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (coq-bits) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"coq-bits\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra-tactics' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-algebra-tactics" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "coq-bits" coq-elpi: needs: - rocq-core runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (coq-elpi) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"coq-elpi\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "coq-elpi" coqeal: needs: - coq - mathcomp-ssreflect - mathcomp-algebra - bignums - multinomials - mathcomp-real-closed runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (coqeal) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"coqeal\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-ssreflect' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-ssreflect" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: bignums' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "bignums" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: multinomials' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "multinomials" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-real-closed' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-real-closed" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "coqeal" deriving: needs: - coq - mathcomp-ssreflect - stdlib runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (deriving) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"deriving\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-ssreflect' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-ssreflect" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "deriving" fourcolor: needs: - coq - mathcomp-boot - mathcomp-fingroup - mathcomp-algebra runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (fourcolor) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"fourcolor\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-fingroup' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-fingroup" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "fourcolor" hierarchy-builder: needs: - rocq-core - coq-elpi runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (hierarchy-builder) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"hierarchy-builder\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq-elpi' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "coq-elpi" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "hierarchy-builder" mathcomp: needs: - rocq-core - mathcomp-character - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"mathcomp\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-character' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-character" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp" mathcomp-algebra: needs: - rocq-core - mathcomp-order - mathcomp-fingroup - hierarchy-builder - micromega-plugin runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-algebra) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"mathcomp-algebra\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-order' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-order" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-fingroup' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-fingroup" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: micromega-plugin' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "micromega-plugin" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-algebra" mathcomp-algebra-tactics: needs: - coq - mathcomp-ssreflect - mathcomp-algebra - coq-elpi - mathcomp-zify runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-algebra-tactics) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"mathcomp-algebra-tactics\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-ssreflect' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-ssreflect" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq-elpi' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "coq-elpi" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-zify' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-zify" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-algebra-tactics" mathcomp-analysis: needs: - coq - mathcomp-reals - mathcomp-field - mathcomp-bigenough - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-analysis) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"mathcomp-analysis\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-reals' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-reals" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-field' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-field" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-bigenough' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-bigenough" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-analysis" mathcomp-analysis-stdlib: needs: - coq - mathcomp-analysis - mathcomp-reals-stdlib - stdlib - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-analysis-stdlib) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"mathcomp-analysis-stdlib\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-analysis' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-analysis" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-reals-stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-reals-stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-analysis-stdlib" mathcomp-bigenough: needs: - coq - mathcomp-boot runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-bigenough) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"mathcomp-bigenough\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-bigenough" mathcomp-boot: needs: - rocq-core - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-boot) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"mathcomp-boot\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-boot" mathcomp-character: needs: - rocq-core - mathcomp-field - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-character) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"mathcomp-character\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-field' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-field" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-character" mathcomp-classical: needs: - coq - mathcomp-ssreflect - mathcomp-algebra - mathcomp-finmap - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-classical) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"mathcomp-classical\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-ssreflect' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-ssreflect" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-finmap' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-finmap" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-classical" mathcomp-experimental-reals: needs: - coq - mathcomp-reals - mathcomp-bigenough - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-experimental-reals) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"mathcomp-experimental-reals\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-reals' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-reals" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-bigenough' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-bigenough" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-experimental-reals" mathcomp-field: needs: - rocq-core - mathcomp-solvable - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-field) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"mathcomp-field\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-solvable' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-solvable" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-field" mathcomp-fingroup: needs: - rocq-core - mathcomp-boot - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-fingroup) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"mathcomp-fingroup\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-fingroup" mathcomp-finmap: needs: - coq - mathcomp-boot runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-finmap) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"mathcomp-finmap\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-finmap" mathcomp-order: needs: - rocq-core - mathcomp-boot - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-order) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"mathcomp-order\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-order" mathcomp-real-closed: needs: - coq - mathcomp-ssreflect - mathcomp-algebra - mathcomp-field - mathcomp-fingroup - mathcomp-solvable - mathcomp-bigenough runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-real-closed) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"mathcomp-real-closed\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"\ Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-ssreflect' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-ssreflect" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-field' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-field" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-fingroup' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-fingroup" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-solvable' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-solvable" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-bigenough' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-bigenough" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-real-closed" mathcomp-reals: needs: - coq - mathcomp-classical - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-reals) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"mathcomp-reals\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-classical' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-classical" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-reals" mathcomp-reals-stdlib: needs: - coq - mathcomp-reals - stdlib - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-reals-stdlib) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"mathcomp-reals-stdlib\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"\ Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-reals' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-reals" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-reals-stdlib" mathcomp-single: needs: - rocq-core - hierarchy-builder - micromega-plugin runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-single) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"mathcomp-single\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: micromega-plugin' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "micromega-plugin" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-single" mathcomp-solvable: needs: - rocq-core - mathcomp-algebra - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-solvable) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"mathcomp-solvable\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-solvable" mathcomp-ssreflect: needs: - coq - mathcomp-boot - mathcomp-order runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-ssreflect) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"mathcomp-ssreflect\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-order' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-order" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-ssreflect" mathcomp-word: needs: - coq - mathcomp-algebra - mathcomp-ssreflect - mathcomp-fingroup - stdlib runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-word) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"mathcomp-word\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-ssreflect' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-ssreflect" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-fingroup' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-fingroup" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-word" mathcomp-zify: needs: - coq - mathcomp-boot - mathcomp-algebra - mathcomp-fingroup - stdlib runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-zify) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"mathcomp-zify\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-fingroup' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-fingroup" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-zify" micromega-plugin: needs: - rocq-core runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (micromega-plugin) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"micromega-plugin\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "micromega-plugin" multinomials: needs: - coq - mathcomp-boot - mathcomp-algebra - mathcomp-finmap - mathcomp-fingroup - mathcomp-bigenough runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (multinomials) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"multinomials\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-finmap' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-finmap" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-fingroup' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-fingroup" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-bigenough' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-bigenough" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "multinomials" odd-order: needs: - coq - mathcomp-character runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (odd-order) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"odd-order\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-character' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-character" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "odd-order" reglang: needs: - coq - mathcomp-ssreflect - stdlib runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (reglang) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"reglang\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-ssreflect' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-ssreflect" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "reglang" rocq-core: needs: [] runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (rocq-core) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"rocq-core\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "rocq-core" rocq-elpi: needs: [] runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (rocq-elpi) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"rocq-elpi\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "rocq-elpi" simple-io: needs: - coq - ExtLib runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (simple-io) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"simple-io\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: ExtLib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "ExtLib" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "simple-io" stdlib: needs: - rocq-core runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (stdlib) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"stdlib\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "stdlib" name: Nix CI for bundle rocq-master on: pull_request: paths: - .github/workflows/nix-action-rocq-master.yml pull_request_target: paths-ignore: - .github/workflows/nix-action-rocq-master.yml types: - opened - synchronize - reopened push: branches: - master math-comp-hierarchy-builder-4d8a939/.gitignore000066400000000000000000000010651521677141400213500ustar00rootroot00000000000000.*.aux *.a *.cma *.cmi *.cmo *.cmx *.cmxa *.cmxs *.glob *.ml.d *.ml4.d *.mli.d *.mllib.d *.mlpack.d *.native *.coq.d *.o *.v.d *.vio *.vos *.vok *.vo .coq-native/ .csdp.cache .lia.cache .nia.cache .nlia.cache .nra.cache csdp.cache lia.cache nia.cache nlia.cache nra.cache Makefile.coq Makefile.coq.conf .coqdeps.d Makefile.test-suite.coq Makefile.test-suite.coq.conf .coqdeps.test-suite *.v.hb *.v.hb.old coq.hb HB/common/log.compat.elpi _minted-* *.aux *.log *.out !*.v.out *.synctex.gz *.toc *.vrb *.fls *.nav *.bbl *.blg *.fdb_latexmk *.vtc *.dot config.stamp math-comp-hierarchy-builder-4d8a939/.nix/000077500000000000000000000000001521677141400202325ustar00rootroot00000000000000math-comp-hierarchy-builder-4d8a939/.nix/config.nix000066400000000000000000000052101521677141400222150ustar00rootroot00000000000000{ format = "1.0.0"; attribute = "hierarchy-builder"; default-bundle = "rocq-9.1"; bundles = let mcHBcommon = { mathcomp.override.version = "master"; }; coqMcHBcommon = { mathcomp.override.version = "master"; mathcomp.job = true; mathcomp-single.job = true; graph-theory.job = false; fourcolor.override.version = "master"; odd-order.override.version = "master"; mathcomp-finmap.override.version = "master"; mathcomp-classical.override.version = "master"; mathcomp-analysis.override.version = "master"; reglang.override.version = "master"; coq-bits.override.version = "master"; deriving.override.version = "master"; mathcomp-bigenough.override.version = "master"; multinomials.override.version = "master"; mathcomp-real-closed.override.version = "master"; coqeal.override.version = "master"; mathcomp-zify.override.version = "master"; mathcomp-algebra-tactics.override.version = "master"; mathcomp-word.override.version = "master"; coquelicot.override.version = "master"; ExtLib.override.version = "master"; simple-io.override.version = "master"; QuickChick.override.version = "master"; # jasmin.override.version = "main"; jasmin.job = false; # currently broken autosubst.job = false; ConCert.job = false; interval.job = false; }; in { "rocq-master" = { rocqPackages = mcHBcommon // { rocq-core.override.version = "master"; stdlib.override.version = "master"; rocq-elpi.override.version = "master"; micromega-plugin.override.version = "master"; bignums.override.version = "master"; }; coqPackages = coqMcHBcommon // { coq.override.version = "master"; stdlib.override.version = "master"; coq-elpi.override.version = "master"; bignums.override.version = "master"; coquelicot.job = false; }; }; "rocq-9.2" = { rocqPackages = mcHBcommon // { rocq-core.override.version = "9.2"; micromega-plugin.override.version = "master"; micromega-plugin.job = false; }; coqPackages = coqMcHBcommon // { coq.override.version = "9.2"; }; }; "rocq-9.1" = { rocqPackages = mcHBcommon // { rocq-core.override.version = "9.1"; }; coqPackages = coqMcHBcommon // { coq.override.version = "9.1"; }; }; "rocq-9.0" = { rocqPackages = mcHBcommon // { rocq-core.override.version = "9.0"; }; coqPackages = coqMcHBcommon // { coq.override.version = "9.0"; }; }; }; cachix.coq = {}; cachix.coq-community = {}; cachix.math-comp.authToken = "CACHIX_AUTH_TOKEN"; } math-comp-hierarchy-builder-4d8a939/.nix/coq-nix-toolbox.nix000066400000000000000000000000531521677141400240120ustar00rootroot00000000000000"dd198b999f8526670a6f71a28bc1ea6ef7393cc5" math-comp-hierarchy-builder-4d8a939/.nix/coq-overlays/000077500000000000000000000000001521677141400226565ustar00rootroot00000000000000math-comp-hierarchy-builder-4d8a939/.nix/coq-overlays/mathcomp-single/000077500000000000000000000000001521677141400257455ustar00rootroot00000000000000math-comp-hierarchy-builder-4d8a939/.nix/coq-overlays/mathcomp-single/default.nix000066400000000000000000000000611521677141400301060ustar00rootroot00000000000000{ mathcomp }: mathcomp.override {single = true;} math-comp-hierarchy-builder-4d8a939/.vscode/000077500000000000000000000000001521677141400207175ustar00rootroot00000000000000math-comp-hierarchy-builder-4d8a939/.vscode/settings.json000066400000000000000000000074441521677141400234630ustar00rootroot00000000000000{ "spellright.language": [], "spellright.documentTypes": [ "markdown", "plaintext" ], "search.exclude": { ".*.aux": true, "*.a": true, "*.cma": true, "*.cmi": true, "*.cmo": true, "*.cmx": true, "*.cmxa": true, "*.cmxs": true, "*.glob": true, "*.ml.d": true, "*.ml4.d": true, "*.mli.d": true, "*.mllib.d": true, "*.mlpack.d": true, "*.native": true, "*.o": true, "*.v.d": true, "*.vio": true, "*.vo": true, ".coq-native/": true, ".csdp.cache": true, ".lia.cache": true, ".nia.cache": true, ".nlia.cache": true, ".nra.cache": true, "csdp.cache": true, "lia.cache": true, "nia.cache": true, "nlia.cache": true, "nra.cache": true, "Makefile.coq": true, "Makefile.coq.conf": true, ".coqdeps.d": true, "**/_minted-*": true, "**/*.aux": true, "**/*.log": true, // "**/*.out": true, // .v.out is used for expected test output "**/*.synctex.gz": true, "**/*.toc": true, "**/*.vrb": true, "**/*.fls": true, "**/*.nav": true, "**/*.bbl": true, "**/*.blg": true, "**/*.fdb_latexmk": true, "**/*.vtc": true }, "files.exclude": { ".*.aux": true, "*.a": true, "*.cma": true, "*.cmi": true, "*.cmo": true, "*.cmx": true, "*.cmxa": true, "*.cmxs": true, "*.glob": true, "*.ml.d": true, "*.ml4.d": true, "*.mli.d": true, "*.mllib.d": true, "*.mlpack.d": true, "*.native": true, "*.o": true, "*.v.d": true, "*.vio": true, "*.vo": true, ".coq-native/": true, ".csdp.cache": true, ".lia.cache": true, ".nia.cache": true, ".nlia.cache": true, ".nra.cache": true, "csdp.cache": true, "lia.cache": true, "nia.cache": true, "nlia.cache": true, "nra.cache": true, "Makefile.coq": true, "Makefile.coq.conf": true, ".coqdeps.d": true, "**/_minted-*": true, "**/*.aux": true, "**/*.log": true, // "**/*.out": true, // .v.out is used for expected test output "**/*.synctex.gz": true, "**/*.toc": true, "**/*.vrb": true, "**/*.fls": true, "**/*.nav": true, "**/*.bbl": true, "**/*.blg": true, "**/*.fdb_latexmk": true, "**/*.vtc": true, "**/.*.aux": true, "**/*.a": true, "**/*.cma": true, "**/*.cmi": true, "**/*.cmo": true, "**/*.cmx": true, "**/*.cmxa": true, "**/*.cmxs": true, "**/*.glob": true, "**/*.ml.d": true, "**/*.ml4.d": true, "**/*.mli.d": true, "**/*.mllib.d": true, "**/*.mlpack.d": true, "**/*.native": true, "**/*.coq.d": true, "**/*.o": true, "**/*.v.d": true, "**/*.vio": true, "**/*.vos": true, "**/*.vok": true, "**/*.vo": true, "**/.coq-native/": true, "**/.csdp.cache": true, "**/.lia.cache": true, "**/.nia.cache": true, "**/.nlia.cache": true, "**/.nra.cache": true, "**/csdp.cache": true, "**/lia.cache": true, "**/nia.cache": true, "**/nlia.cache": true, "**/nra.cache": true, "**/Makefile.coq": true, "**/Makefile.coq.conf": true, "**/.coqdeps.d": true, "**/Makefile.test-suite.coq": true, "**/Makefile.test-suite.coq.conf": true, "**/.coqdeps.test-suite": true, "**/*.dot": true } }math-comp-hierarchy-builder-4d8a939/AUTHORS.md000066400000000000000000000003251521677141400210250ustar00rootroot00000000000000Copyright (C) 2020 - Cyril Cohen (Inria) - Pierre Roux (Onera) - Kazuhiko Sakaguchi (University of Tsukuba) - Enrico Tassi (Inria) This software is released under the terms of the MIT license, see LICENSE file. math-comp-hierarchy-builder-4d8a939/Changelog.md000066400000000000000000000246501521677141400215760ustar00rootroot00000000000000# Changelog ## [1.10.3] - 2026-06-24 Compatible with - Coq 8.20 with Coq-Elpi 3.0.x - Rocq 9.0 with Rocq-Elpi 3.0.x - Rocq 9.1 with Rocq-Elpi 3.0.x - Rocq 9.2 with Rocq-Elpi 3.3.x - **Fix** Compilation on 9.2 ## [1.10.2] - 2026-01-28 Compatible with - Coq 8.20 with Coq-Elpi 3.0.x - Rocq 9.0 with Rocq-Elpi 3.0.x - Rocq 9.1 with Rocq-Elpi 3.0.x - **Fix** HB.howto - **Change** Blacklist internal HB constants - **Fix** Honour #[export] in HB.saturate ## [1.10.1] - 2025-09-08 Compatible with - Coq 8.20 with Coq-Elpi 3.0.x - Rocq 9.0 with Rocq-Elpi 3.0.x - Rocq 9.1 with Rocq-Elpi 3.0.x - **Fix** HB.about ## [1.10.0] - 2025-07-21 Compatible with - Coq 8.20 with Coq-Elpi 3.0.x - Rocq 9.0 with Rocq-Elpi 3.0.x - Rocq 9.1 with Rocq-Elpi 3.0.x ## [1.9.1] - 2025-04-29 Drop compatibility with 8.18 and 8.19. Rename opma package to rocq-hierarchy-builder. ## [1.9.0] - 2025-04-15 Compatible with - Coq 8.18 with Coq-Elpi 2.0.0 - Coq 8.19 with Coq-Elpi 2.0.1 - Coq 8.20 with Coq-Elpi 2.4.x - Rocq 9.0 with Coq-Elpi 2.4.x Compile without coqc compatibility shim on Rocq 9.0 Compile without Stdlib on Rocq 9.0 ## [1.8.1] - 2025-01-25 Compatible with - Coq 8.18 with Coq-Elpi 2.0.0 - Coq 8.19 with Coq-Elpi 2.0.1 - Coq 8.20 with Coq-Elpi 2.4.x - Rocq 9.0 with Coq-Elpi 2.4.x ## [1.8.0] - 2024-12-14 Compatible with - Coq 8.18 with Coq-Elpi 2.0.0 - Coq 8.19 with Coq-Elpi 2.0.1 - Coq 8.20 with Coq-Elpi 2.2.x and 2.3.x ### General - **Bugfixes** several error messages have been fixed to display more faithful error messages. - **New warning** in case no instance is created. - **Bugfixes** the regression which forbad dependent functions to be instances has been fixed. ## [1.7.1] - 2024-12-06 Compatible with - Coq 8.18 with Coq-Elpi 2.0.0 - Coq 8.19 with Coq-Elpi 2.0.1 - Coq 8.20 with Coq-Elpi 2.2.x and 2.3.x ### General - **Speedup** `HB.instance` does not try to infer classes that inherit from a class that is known to have no instance (for the given type) - **Speedup** `toposort` on `gref` uses OCaml's maps and sets rather than lists ## [1.7.0] - 2024-01-10 Compatible with - Coq 8.18 with Coq-Elpi 2.0.0 - Coq 8.19 with Coq-Elpi 2.0.1 - **Removed** the `#[primitive_class]` attribute, making it the default. - **New** `HB.saturate` to saturate instances w.r.t. the current hierarchy - **Removed** the `#[infer]` attribute made obsolete by reverse coercions since Coq 8.16 ## [1.6.0] - 2023-09-20 Compatible with - Coq 8.16 with Coq-Elpi 1.15.x and 1.16.x - Coq 8.17 with Coq-Elpi 1.17.x and 1.18.x - Coq 8.18 with Coq-Elpi 1.19.x This version is required if Elpi is >= 1.17.0 ### General - **Speedup** speedup in coercion compression - **Speedup** accumulate clauses in batches (on Coq-Elpi >= 8.18.0) - **Change** remove generation of eta expanded instances (was unused) ## [1.5.0] - 2023-08-04 Compatible with - Coq 8.15 with Coq-Elpi 1.14.x - Coq 8.16 with Coq-Elpi 1.15.x and 1.16.x - Coq 8.17 with Coq-Elpi 1.17.x and 1.18.x - Coq 8.18 with Coq-Elpi 1.19.x This version is required if Elpi is >= 1.17.0 ### General - **Fix** spilling before predicate declaration - **Fix** unnecessary use of grafting slowing down compilation on MathComp 2.0 - **New** better "missing join" error message ## [1.4.0] - 2022-09-29 Compatible with - Coq 8.15 with Coq-Elpi 1.14.x - Coq 8.16 with Coq-Elpi 1.15.x and 1.16.x ### General - **Fix** `HB.pack` works with structures about functions, and not just types. - **Fix** `HB.about` and `HB.graph` now display shortest names. - **New** Command `HB.howto` to find all possible ways to instanciate structures. - **New** Structures now support keys which type's head is a global reference. (Only keys corresponding to the coercion classes `Sortclass` and `Funclass` were accepted). ## [1.3.0] - 2022-07-27 Compatible with - Coq 8.15 with Coq-Elpi 1.14.x - Coq 8.16 with Coq-Elpi 1.15.x ### General - **Fix** Structures can be keyd on sorts (eg `Prop`) and products (eg `T -> U`) - **New** Mixin parameters can depend on structure instances inferred using previous mixins (see [this test](tests/interleave_context.v)) ## [1.2.1] - 2022-01-10 Compatible with - Coq 8.13 or 8.14 with Coq-Elpi 1.11.x - Coq 8.15 with Coq-Elpi 1.12.x ### General - **Fix** Do not unfold let-ins in instances (speedup) - **Fix** Test suite for Coq 8.15 ## [1.2.0] - 2021-09-24 Compatible with - Coq 8.13 or 8.14 with Coq-Elpi 1.11.x ### General - **Fix** Do not impose useless universe constraints on `option` and `prod` by using custom inductive types. - **New** Check for instances which break Forgetful Inheritance, attribute `#[non_forgetful_inheritance]` to disable the check. - **New** Factory instances are canonically (key `Factory.sort`) instances of all the structures they can fulfill. This can be used inside proofs to provide canonical instances on a type. E.g. `(factoryInstance : SomeStructure.sort _)` works if `factoryInstance` can be used to build `SomeStructure` - **New** `Strategy Opaque` for named mixins, improving conversion performance on generated terms - **New** Attributes `#[primitive]` and `#[primitive_class]` for `HB.structure/mixin/factory` to generate primitive records. - **New** Attribute `#[doc="text"]` supported by all commands and used by `HB.about` - **New** Attribute `#[hnf]` supported by `HB.instance` ### Commands - **New** `HB.locate` to find where an instance comes from - **New** `HB.about` to display HB specific info attached to a HB generated constant ### Tactics - **New** Tactic in term `HB.pack` and `HB.pack_for` taking a key `K` and a bunch of factories and building a structure instance on `K`. E.g. `pose K_fooType : Foo.type := HB.pack K f1 f2 ..` works if factories `f1 f2 ..` provide all mixins needed by structure `Foo`. ## [1.1.0] - 2021-03-30 Compatible with - Coq 8.11 with Coq-Elpi 1.6.2, - Coq 8.12 with Coq-Elpi 1.8.2, - Coq 8.13 with Coq-Elpi 1.9.5. ### General - **Experimental** support for structures with a function as the carrier, for e.g. hierarchies of morphisms. - **Fix** Type inference of parameters for HB commands improved, it can now rely on the right hand side of factories and mixins - **Fix** Removed a hack that included phantom fields in mixins and factories in order to prevent erasure from section discharge. - **Cosmetic** Changed naming convention for canonical instances e.g. `T_is_a_Ring` is now renamed to `T_Ring`. This name should still not be relied upon. - **Cleanup** The elpi code has been split into several files, one for each command and a folder for common code. - **Fix** Speedup `toposort` in elpi code. - **Doc** The file `structures.v` contains a detailed documentation of each command. ### Commands - **Deprecated** `HB.instance K F` in favor of `HB.instance Definition`. - **New** `HB.export` is like `Export` except that the module is stored in a database for later rexport. - **New** `HB.reexport` reexports all the modules that have been previously flagged by `HB.export`, as well as all the `HB.instance` that have been flagged by the attribute `#[export]`. - **New** `HB.check` is like `Check` but supports logging and can be disabled on a selection of Coq versions. - **New** `HB.graph` generates the graph of structures as a dot file. (One may use `tred file.dot | xdot -` to visualize the output). - **Extended** `HB.structure` to generate methods `.on` and `.copy` (see `structures.v` for their documentation). ### Attributes - **New** `#[export]` attribute can be given to `HB.instance` in order to have instances (re)declared by `HB.reexport`. - **New** `#[compress_coercions]` attribute (off by default) to shorten coercions paths in the synthesis of instances. When instanciating structures one by one, (e.g. T is declared as a Semiring, then as a Ring, then as a Field, etc) the coercions used to pile up, we now compress these chains of application. - **New** `#[log]` and `#[log(raw)]` to print Coq commands equivalent to what HB is doing. The raw print is the only one which is reparsable. - **New** `#[key="T"]` to flag paramter `T` as the key of the mixin/factory. The definition `indexed` used to serve this purpose is deprecated and will not do anything. - **New** `#[infer(P)]` can be used to tell `HB.structure` to set things up so that parameter `P` is automatically inferred. E.g. if `P : Ring.type` then `Structure.type` will take a `t : Type` and trigger a canonical inference. to infer the `t_is_a_Ring : Ring.type` associated to `t`. If `Structure` has a function carrier, one has to write `#[infer(P = "_ -> _")]`. - **New** `#[arg_sort]` for `HB.structure` generates an intermediate sort projection called `arg_sort` which is prioritary as a coercion and which unfolds to `sort`. It is meant to be the sort of arguments of operations (see `mathcomp/fingroup/fingroup.v` for more information). - **New** `#[local]` for `HB.instance` so that they do not survive sections. ### Tooling - **New** environment variable `COQ_ELPI_ATTRIBUTES="hb(log(raw))"` to have HB commands write patch files containing Coq commands equivalent to what HB did. These patch files have extension `.v.hb` and are named after the file they apply to. - **New** `coq.hb` command line utility to patch/reset files. - **New** The CI is now testing mathcomp and plan B (using nix). ## [1.0.0] - 2020-12-16 Requires Coq-Elpi 1.6 or 1.7 or 1.8 and Coq 8.11 or 8.12 or 8.13. - Use Coq's elaborator to typecheck factories and structures (coercions are now inserted properly) - New attribute `#[mathcomp]` for `HB.structure` to synthesize backward compatibility code for the Mathematical Components library. When the mixin contains a single axiom its name can be given as `#[mathcomp(axiom="eq_axiom")]`. - `HB.instance Definition name : factory T := term` works even if term is not a known builder. In this case the type (key) is read from the factory (the type of the definition). ## [0.10.0] - 2020-08-08 - HB now supports parameters (experimental). - Port to Coq-Elpi 1.5. - Better error message in case classes are not defined in the right order. - Structure operations are not reexported by substructures. - Spurious trivial `TYPE` structure removed from demo1. ## [0.9.1] - 2020-06-03 - `HB.instance` can be applied directly to a definition as in `HB.instance Definition foo := Bar.Build T ...` - Port to Coq-Elpi version 1.4 - Operations `op` from factory `f` are not bound to `f_op` anymore, they are now bound to `op` and potentially masked operations are accessible via `Super.op`. ## [0.9.0] - 2020-03-11 First public release for Coq 8.10 and 8.11. math-comp-hierarchy-builder-4d8a939/HB/000077500000000000000000000000001521677141400176475ustar00rootroot00000000000000math-comp-hierarchy-builder-4d8a939/HB/README.md000066400000000000000000000030001521677141400211170ustar00rootroot00000000000000## File structure - `HB/foo.elpi` implements the main entry point for `HB.foo` (or its variants) - `HB/common/foo.elpi` provides code used by more than one command - Each file `foo.elpi` should put its public API in the namespace `foo.` and its private code in `foo.private.`, if you need to access predicates in the private space then the API needs to be reworked (don't commit code accessing private stiff, even if Elpi won't prevent you from using it). ## Naming conventions - `under-foo.do! Arg [ Code ]` enriches the context with `foo`, the runs `std.do! [ Code ]` - `under-foo.then Arg F Out` enriches the context with `foo`, the runs `F Out`, as a consequence on can use the spilling expression `{under-foo.then Arg F}` - `foo_bar` projection from foo to its field bar - `foo->bar` conversion from type foo to type bar (it can be arbitrarily complex) - `get-foo` reads foo from the Coq world - `findall-foo` reads foo from `hb.db`, the output is sorted whenever it makes sense - `declare-foo` predicate adding to the Coq environment a `foo` - `postulate-foo` predicate assuming a `foo` (e.g. declaring a Coq section variable) - `TheType`, `TheClass`, `TheFoobar` the thing the current code is working on, eg the type of the structure begin defined - `FooAlias` see `phant-abbrev`, used to talk about the non canonical name of `Foo` - when foo is the constructor of a data type with type `A1 -> .. -> AN -> t` we define `mk-foo` as: `mk-foo A1 .. AN (foo A1 .. AN)` math-comp-hierarchy-builder-4d8a939/HB/about.elpi000066400000000000000000000352761521677141400216510ustar00rootroot00000000000000/* Hierarchy Builder: algebraic hierarchies made easy This software is released under the terms of the MIT license */ namespace about { func main string ->. main S :- coq.locate-all S All, std.filter All (x\sigma gr a\ std.once (x = loc-gref gr ; x = loc-abbreviation a)) L, if (L = []) (coq.error "HB: unable to locate" S) true, std.forall L (about.main-located S). func main-located string, located ->. main-located S (loc-gref GR) :- class-def (class Class GR MLwP), !, private.main-structure S Class GR MLwP. main-located _ (loc-gref Class) :- class-def (class Class GR MLwP), !, gref->modname_short GR "." M, coq.gref->id GR St, S is M ^ "." ^ St, private.main-structure S Class GR MLwP. main-located S (loc-gref (indt I)) :- factory->constructor (indt I) _, !, private.main-factory S I. main-located S (loc-gref (const C)) :- factory->constructor (const C) _, !, private.main-factory-alias S C. main-located S (loc-gref (const C)) :- exported-op M _ C, !, private.main-operation S M C. main-located S (loc-gref GR) :- factory-alias->gref GR F ok, not (F = GR), !, main-located S (loc-gref F). main-located S (loc-abbreviation A) :- phant-abbrev GR PhB A, is-factory (indt F), factory->constructor (indt F) GR, !, private.main-factory->constructor S F PhB GR. main-located S (loc-abbreviation A) :- coq.notation.abbreviation-body A NArgs _, coq.notation.abbreviation A {coq.mk-n-holes NArgs} T, coq.safe-dest-app T (global GR) _, !, main-located S (loc-gref GR). main-located S (loc-gref GR) :- from Factory Mixin GR, !, private.main-builder S Factory Mixin. main-located S (loc-gref GR) :- std.filter {coq.CS.db-for _ (cs-gref GR)} (not1 unif-hint?) LV, coq.CS.db-for GR _ LP, std.filter {coq.coercion.db} (c\c = coercion GR _ _ _) LC, if (LV = [], LP = [], LC = []) (coq.error "HB: uninteresting constant" {coq.pp->string {private.pp-loc-of GR}}) true, if (not (LV = [])) (private.main-canonical-value S LV) true, if (not (LP = [])) (private.main-canonical-projection S GR LP) true, if (not (LC = [])) (private.main-coercion S LC) true. main-located S (loc-abbreviation _) :- coq.error "HB: unknown abbreviation" S. /* things also used in paths.elpi ------------------------------------------ */ shorten coq.pp.{ v , h, hv, hov , spc , str , box , glue , brk , empty }. func bulletize1 (func A -> coq.pp), A -> coq.pp. bulletize1 F X (glue [str "- ", M]) :- F X M. % @gares func bulletize list A, (func A -> coq.pp) -> coq.pp. bulletize [] _ empty :- !. bulletize L F (glue [brk 0 0 | PLB]) :- std.map L (bulletize1 F) PL, std.intersperse (brk 0 0) PL PLB. % Print shortest qualified identifier of the module containing a gref func pp-module gref -> coq.pp. pp-module GR (str ID) :- gref->modname_short GR "." ID. func unif-hint? cs-instance -> . unif-hint? (cs-instance _ (cs-gref GR) _) :- coq.CS.db-for GR _ [_|_]. func not1 (pred i:A), A. not1 P X :- not (P X). /* ------------------------------------------------------------------------- */ /* ----------------------------- private code ------------------------------ */ /* ------------------------------------------------------------------------- */ namespace private { shorten coq.pp.{ v , h, hv, hov , spc , str , box , glue , brk , empty }. func docstring-for-file string -> prop. docstring-for-file Rex (docstring Loc Doc) :- docstring Loc Doc, loc.fields Loc File _ _ _ _, rex.match {calc(".*" ^ Rex)} File, !. func main-canonical-value string, list cs-instance ->. main-canonical-value S CanonicalValues :- group-by-loc CanonicalValues CanonicalValuesL, %format PpCanonicalValues = box (v 4) [ str "HB: ", str S, str " is canonically equipped with structures:", {bulletize CanonicalValuesL pp-canonical-solution-list}], % print coq.say {coq.pp->string PpCanonicalValues}, coq.say. func group-by-loc list cs-instance -> list (pair (option loc) (list cs-instance)). group-by-loc [] []. group-by-loc [cs-instance P V GR|L] [pr (some Loc) [cs-instance P V GR|SameLoc]|Rest1] :- decl-location GR Loc, !, std.partition L (x\ sigma GR1\ x = cs-instance _ _ GR1, decl-location GR1 Loc) SameLoc Rest, group-by-loc Rest Rest1. group-by-loc [I|Rest] [pr none [I]|Rest1] :- group-by-loc Rest Rest1. func pp-canonical-solution-list pair (option loc) (list cs-instance) -> coq.pp. pp-canonical-solution-list (pr none [CS]) Pp :- pp-canonical-solution CS Pp. pp-canonical-solution-list (pr (some Loc) L) Pp :- Pp = box (v 0) { std.append {std.intersperse spc {std.map L pp-canonical-solution}} [ spc, {pp-loc Loc} ] }. func pp-canonical-solution cs-instance -> coq.pp. pp-canonical-solution (cs-instance _Proj _Pat GR) Pp :- coq.env.typeof GR T, coq.prod-tgt->gref T F, if (class-def (class _ F _)) (gref->modname_short F "." ID) (coq.gref->string F ID), Pp = box (hov 0) [ str ID ]. func main-canonical-projection string, gref, list cs-instance. main-canonical-projection S Proj CanonicalProjectionValues :- %format PpCanonicalProjectionOrigin = box (hov 4) [ str "HB:", spc, str S, spc, str "is a canonical projection", spc, {pp-loc-of Proj}], PpCanonicalProjectionValues = box (v 4) [ str "HB: ", str S, str " has the following canonical values:", {bulletize CanonicalProjectionValues pp-canonical-value}], % print coq.say {coq.pp->string PpCanonicalProjectionOrigin}, coq.say {coq.pp->string PpCanonicalProjectionValues}, coq.say. func pp-canonical-value cs-instance -> coq.pp. pp-canonical-value (cs-instance _Proj (cs-gref GR) _Sol) Pp :- coq.term->pp (global GR) V, Pp = box (hov 2) [ V , spc, {pp-loc-of GR} ]. func main-coercion string, list coercion. main-coercion S [coercion GR _ Src Tgt|_] :- % format if (class-def (class _ Src _) ; class-def (class Src _ _)) (Source = str {gref->modname_short Src "."}) (coq.term->pp (global Src) Source), if2 (Tgt = grefclass TGR) (if (class-def (class _ TGR _) ; class-def (class TGR _ _)) (Target = str {gref->modname_short TGR "."}) (coq.term->pp (global TGR) Target)) (Tgt = sortclass) (Target = str "Sortclass") (Target = str "Funclass"), PpCoercionOrigin = box (hov 4) [ str "HB:", spc, str S, spc, str "is a coercion from", spc, Source, str" to ", Target, spc, {pp-loc-of GR}], % print coq.say {coq.pp->string PpCoercionOrigin}, coq.say. func main-operation string, mixinname, constant -> . main-operation S MixinSource _ :- % fetch mixin->first-class MixinSource Class, class-def (class Class Structure _), !, % format PpOriginStructure = box (hov 4) [ str "HB:", spc, str S, spc, str "is an operation of structure", spc, {pp-module Structure}, spc, {pp-loc-of Structure}], PpOriginMixin = box (hov 4) [ str "HB:", spc, str S, spc, str "comes from mixin", spc, {pp-module MixinSource}, spc, {pp-loc-of MixinSource}], % print coq.say {coq.pp->string PpOriginStructure}, coq.say {coq.pp->string PpOriginMixin}, coq.say. func main-structure string, classname, structure, mixins. main-structure S Class Structure MLwP :- % fetch list-w-params_list MLwP ML, std.map-filter ML (m\r\ sigma P O OPS\ mixin->first-class m Class, std.findall (exported-op m P O) OPS, std.map OPS (c\out\ sigma p\ c = exported-op m p out) r) OPLL, std.flatten OPLL Operations, std.map {std.findall (sub-class Class CS_ CoeS_ NS_)} (x\r\ x = sub-class Class r _ _) SubClasses, std.map {std.findall (sub-class Cs_ Class Coes_ Ns_)} (x\r\ x = sub-class r Class _ _) SuperClasses, % format PpOrigin = box (hov 4) [ str "HB: ", str S, str " is a structure", spc, {pp-loc-of Structure} ], PpOperations = box (v 4) [ str "HB: ", str S, str " characterizing operations and axioms are:", {bulletize Operations pp-const}], PpClass = box (v 4) [ str "HB: ", {pp-module Class}, str " is a factory for the following mixins:", {bulletize ML (m\r\ sigma tmp\ if (mixin->first-class m Class) (pp-module m tmp, r = glue [tmp, str " (* new, not from inheritance *)"]) (pp-module m r))}], PpSubClasses = box (v 4) [ str "HB: ", {pp-module Class}, str " inherits from:", {bulletize SubClasses pp-module}], PpSuperClasses = box (v 4) [ str "HB: ", {pp-module Class}, str " is inherited by:", {bulletize SuperClasses pp-module}], % print coq.say {coq.pp->string PpOrigin}, coq.say {coq.pp->string PpOperations}, coq.say {coq.pp->string PpClass}, coq.say {coq.pp->string PpSubClasses}, coq.say {coq.pp->string PpSuperClasses}, print-docstring Structure, coq.say. func main-factory->constructor string, inductive, gref, gref. main-factory->constructor S F PhBuild Build :- % fetch gref->deps Build DMLwP, list-w-params_list DMLwP DML, factory-provides (indt F) PMLwP, list-w-params_list PMLwP PML, coq.env.projections F FieldsOpts, std.map-filter FieldsOpts (x\r\ x = some r) Fields, coq.arguments.implicit PhBuild [Implicits], compute-arg-type DMLwP Fields [] ParamsNames TName FieldsNames ArgsTypes, compute-field-info FieldsNames Implicits FieldsNamesInfo, std.map ParamsNames (n\r\r = str n) ParamsPp, % format PpOrigin = box (hov 4) [ str "HB: ", str S, str " is a factory constructor", spc, {pp-loc-of Build} ], PpRequires = box (v 4) [ str "HB: ", str S, str " requires its subject to be already equipped with:", {bulletize DML pp-module}], PpProvides = box (v 4) [ str "HB: ", str S, str " provides the following mixins:", {bulletize PML pp-module}], PpUsage = box (v 4) [box h {std.intersperse spc [ str "HB: arguments:", glue {std.intersperse spc [str S | ParamsPp]}, str TName, glue FieldsNamesInfo]}, {bulletize ArgsTypes pp-arg-type}], % print coq.say {coq.pp->string PpOrigin}, coq.say {coq.pp->string PpRequires}, coq.say {coq.pp->string PpProvides}, coq.say {coq.pp->string PpUsage}, print-docstring Build, coq.say. func compute-arg-type list-w-params mixinname, list constant, list term -> list id, id, list id, list (pair id coq.pp). compute-arg-type (w-params.cons ID Ty Rest) F Acc [ID|PN] TN FN [pr ID PPTy |Xs] :- coq.term->pp Ty PPTy, @pi-parameter ID Ty x\ compute-arg-type (Rest x) F [x|Acc] PN TN FN Xs. compute-arg-type (w-params.nil ID Ty Rest) F Acc [] ID FN [pr ID PPTy|Xs] :- coq.term->pp Ty PPTy, @pi-parameter ID Ty x\ compute-arg-type.fields F {std.length (Rest x)} {std.rev [x|Acc]} Xs FN. :index(1) func compute-arg-type.fields list constant, int, list term -> list (pair id coq.pp), list id. compute-arg-type.fields [] _ _ [] []. compute-arg-type.fields [C|Cs] NDeps Args [pr ID PPTy|Xs] [ID|FN] :- exported-op _ C OP, !, coq.env.typeof (const OP) Ty, coq.gref->id (const OP) ID, coq.subst-prod Args Ty TyArgs, (@pplevel! 200 => coq.term->pp TyArgs PPTy), compute-arg-type.fields Cs NDeps Args Xs FN. compute-arg-type.fields [OP|Cs] NDeps Args [pr ID PPTy|Xs] [ID|FN] :- % factories don't get exported ops, so we hack their types :-/ coq.env.typeof (const OP) OrigTy, copy OrigTy Ty, coq.gref->id (const OP) ID, coq.subst-prod Args Ty TyArgs, coq.mk-n-holes NDeps Deps, coq.subst-prod Deps TyArgs TyArgsDeps, coq.subst-prod [_] TyArgsDeps TyArgsDepsRecord, ToDrop is NDeps + 2, (@pplevel! 200 => coq.term->pp TyArgsDepsRecord PPTy), @pi-parameter ID TyArgsDepsRecord op\ (pi L L1 X\ copy (app[global(const OP)|L]) X :- std.drop ToDrop L L1, coq.mk-app op L1 X, !) => compute-arg-type.fields Cs NDeps Args Xs FN. func main-factory string, inductive. main-factory S Factory :- % fetch coq.env.projections Factory Ps, std.map-filter Ps (x\r\ x = some r) Fields, gref->deps (indt Factory) DMLwP, list-w-params_list DMLwP DML, factory-provides (indt Factory) PMLwP, list-w-params_list PMLwP PML, % format PpOrigin = box (hov 4) [ str "HB: ", str S, str " is a factory", spc, {pp-loc-of (indt Factory)} ], PpOperations = box (v 4) [ str "HB: ", str S, str " operations and axioms are:", {bulletize Fields pp-const}], PpRequires = box (v 4) [ str "HB: ", str S, str " requires the following mixins:", {bulletize DML pp-module}], PpProvides = box (v 4) [ str "HB: ", str S, str " provides the following mixins:", {bulletize PML pp-module}], % print coq.say {coq.pp->string PpOrigin}, coq.say {coq.pp->string PpOperations}, coq.say {coq.pp->string PpRequires}, coq.say {coq.pp->string PpProvides}, print-docstring (indt Factory), coq.say. func main-factory-alias string, constant. main-factory-alias S _Const :- coq.say "HB: todo HB.about for factory alias" S. func main-builder string, factoryname, mixinname. main-builder _S From To :- coq.say "HB: todo HB.about for builder from" {gref->modname_short From "."} "to" {gref->modname_short To "."}. func compute-field-info.aux list id, list implicit_kind -> list coq.pp. compute-field-info.aux [] _ []. compute-field-info.aux [Name|NS] [explicit|IS] [str Name|PS] :- compute-field-info.aux NS IS PS. compute-field-info.aux [Name|NS] [implicit|IS] [glue[str"[",str Name,str"]"]|PS] :- compute-field-info.aux NS IS PS. compute-field-info.aux [Name|NS] [maximal|IS] [glue[str"{",str Name,str"}"]|PS] :- compute-field-info.aux NS IS PS. compute-field-info.aux [Name|NS] [] [str Name|PS] :- compute-field-info.aux NS [] PS. func compute-field-info list id, list implicit_kind -> list coq.pp. compute-field-info Names Impls O :- compute-field-info.aux {std.rev Names} {std.rev Impls} Pp, std.intersperse spc {std.rev Pp} O. func pp-const constant -> coq.pp. pp-const F (str ID) :- coq.gref->id (const F) ID. func pp-arg-type pair id coq.pp -> coq.pp. pp-arg-type (pr ID PPTy) (box (hov 2) [str ID, str" :", spc, PPTy]). :functional pred pp-if-verbose o:coq.pp, i:(func -> coq.pp). pp-if-verbose V P :- get-option "verbose" tt, !, P V. pp-if-verbose empty _. func pp-loc-of gref -> coq.pp. pp-loc-of GR PP :- decl-location GR Loc, !, pp-loc Loc PP. pp-loc-of _ coq.pp.empty. func pp-loc loc -> coq.pp. pp-loc Loc (coq.pp.glue PP) :- loc.fields Loc File _ _ Line _, QFile is "\"" ^ File ^ "\", line " ^ {std.any->string Line}, PP = [str "(from ", str QFile, str")"]. func docstring->pp string -> coq.pp. docstring->pp Txt (glue Doc) :- rex.replace "\n" " " Txt PlainTxt, rex.split " " PlainTxt Words, std.filter Words (w\not (w = "")) NEWords, std.map NEWords (w\r\ r = str w) PpWords, std.intersperse spc PpWords Doc. func docstring-of gref -> option coq.pp. docstring-of GR (some Doc) :- decl-location GR Loc, docstring Loc Txt, !, docstring->pp Txt Doc. docstring-of _ none. func pp-docstring-of gref -> coq.pp. pp-docstring-of GR D :- docstring-of GR (some D), !. pp-docstring-of _ coq.pp.empty. func print-docstring gref ->. print-docstring GR :- if (docstring-of GR (some Doc)) (coq.say {coq.pp->string (box (hov 5) [str"Doc: ",Doc])}) true. }} math-comp-hierarchy-builder-4d8a939/HB/builders.elpi000066400000000000000000000137371521677141400223460ustar00rootroot00000000000000/* Hierarchy Builder: algebraic hierarchies made easy This software is released under the terms of the MIT license */ namespace builders { func begin context-decl ->. begin CtxSkel :- std.assert!(coq.next-synterp-action (begin-module Name)) "synterp code did not open module", if-verbose (coq.say {header} "begin module for builders"), log.coq.env.begin-module Name none, builders.private.factory CtxSkel IDF GRF, % the Super module to access operations/axioms shadowed by the ones in the factory if-verbose (coq.say {header} "begin module Super"), log.coq.env.begin-module "Super" none, if (GRF = indt FRecord) (std.do! [ std.forall {coq.env.projections FRecord} builders.private.declare-shadowed-constant, ]) true, if-verbose (coq.say {header} "ended module Super"), log.coq.env.end-module-name "Super" _, log.coq.env.begin-section Name, if-verbose (coq.say {header} "postulating factories"), builders.private.postulate-factories Name IDF CtxSkel . } % "end" is a keyword, be put it in the namespace by hand func builders.end. builders.end :- std.do! [ current-mode (builder-from _ _ _ ModName), log.coq.env.end-section-name ModName, findall-builders LFIL, std.fold LFIL [] builders.private.declare-1-builder Clauses, if (Clauses = []) (coq.error "No builders to declare, did you forget HB.instance?") true, std.findall (abbrev-to-export F_ N_ A_) ExportClauses, coq.env.current-path CurModPath, std.filter ExportClauses (export.private.abbrev-in-module CurModPath) ExportClausesFiltered, % TODO: Do we need this module? std.assert!(coq.next-synterp-action (begin-module Name)) "synterp code did not open module", log.coq.env.begin-module Name none, acc-clauses current Clauses, acc-clauses current ExportClausesFiltered, log.coq.env.end-module-name Name Exports, log.coq.env.end-module-name ModName _, export.module {calc (ModName ^ "." ^ Name)} Exports, ]. /* ------------------------------------------------------------------------- */ /* ----------------------------- private code ------------------------------ */ /* ------------------------------------------------------------------------- */ func factory.cdecl->w-mixins context-decl -> w-mixins context-decl. namespace builders.private { % [declare-1-builder (builder _ F M B) From MoreFrom] Given B of type FB, it % declares all the new builders F to M via B. % From holds the (from F Mi Bi) new clauses during folding. :index (1) func declare-1-builder builder, list prop -> list prop. declare-1-builder (builder _ SrcFactory TgtMixin _) FromClauses FromClauses :- (FromClauses => from SrcFactory TgtMixin _), !, if-verbose (coq.say {header} "skipping duplicate builder from" {nice-gref->string SrcFactory} "to" {nice-gref->string TgtMixin}). declare-1-builder (builder _ SrcFactory TgtMixin B) FromClauses [from SrcFactory TgtMixin B|FromClauses] :- if-verbose (coq.say {header} "declare builder from" {nice-gref->string SrcFactory} "to" {nice-gref->string TgtMixin}). % We add breviations for all constants what will be shadowed by projections % if the factory. :index (1) func declare-shadowed-constant option constant ->. declare-shadowed-constant none. declare-shadowed-constant (some C) :- coq.gref->id (const C) Id, std.forall {coq.locate-all Id} (declare-shadowed-located Id). :index (_ 1) func declare-shadowed-located string, located. declare-shadowed-located Id (loc-gref GR) :- @global! => log.coq.notation.add-abbreviation Id 0 (global GR) ff _. declare-shadowed-located Id (loc-abbreviation Abbrev) :- coq.notation.abbreviation-body Abbrev NArgs T, @global! => log.coq.notation.add-abbreviation Id NArgs T ff _. func postulate-factory-abbrev term, list term, id, factoryname -> term. postulate-factory-abbrev TheType Params Name Falias TheFactory :- std.do! [ std.assert-ok! (factory-alias->gref Falias F) "HB", phant-abbrev F _ Fabv, coq.notation.abbreviation Fabv {std.append Params [TheType]} Package, Msg is "Unable to declare factory " ^ Name, std.assert-ok! (coq.typecheck-ty Package _) Msg, log.coq.env.add-section-variable-noimplicits Name Package C, TheFactory = global (const C), ]. % Only record fields can be exported as operations. :index (1) func define-factory-operations term, list term, term, gref. define-factory-operations TheType Params TheFactory (indt I) :- !, coq.env.indt I _ NIParams _ _ _ _, NHoles is NIParams - 1 - {std.length Params}, coq.env.projections I PL, std.forall PL (define-factory-operation TheType Params TheFactory NHoles). define-factory-operations _ _ _ _. :index (_ _ _ _ 1) func define-factory-operation term, list term, term, int, option constant. define-factory-operation _ _ _ _ none. define-factory-operation TheType Params TheFactory NHoles (some P) :- coq.mk-n-holes NHoles Holes, std.append Holes [TheFactory] Holes_Factory, std.append Params [TheType|Holes_Factory] Args, T = app[global (const P)|Args], std.assert-ok! (coq.typecheck T _) "Illtyped applied factory operation", coq.gref->id (const P) Name, @local! => log.coq.notation.add-abbreviation Name 0 T ff _. func factory context-decl -> string, gref. factory (context-item IDF _ T _ _\ context-end) IDF GR :- !, coq.safe-dest-app T (global GR) _. factory (context-item _ _ _ _ R) IDF GR :- !, pi x\ factory (R x) IDF GR. factory _ _ _ :- !, coq.error "the last context item is not a factory". func postulate-factories id, string, context-decl. postulate-factories ModName IDF CDecl :- factory.cdecl->w-mixins CDecl (pr FLwP _), context.declare.params-key FLwP ParamsSection FKey FLwA, std.assert! (FLwA = [triple GRF _ _]) "HB: cannot declare builders for more than one factory at a time", gref->deps GRF DepswPRaw, context.declare.mixins FKey ParamsSection DepswPRaw _ _ _, std.map ParamsSection triple_2 FParams, postulate-factory-abbrev FKey FParams IDF GRF TheFactory, define-factory-operations FKey FParams TheFactory GRF, acc-clause current (current-mode (builder-from FKey TheFactory GRF ModName)). }math-comp-hierarchy-builder-4d8a939/HB/common/000077500000000000000000000000001521677141400211375ustar00rootroot00000000000000math-comp-hierarchy-builder-4d8a939/HB/common/compat_acc_clauses_all.elpi000066400000000000000000000002261521677141400264520ustar00rootroot00000000000000:index (1) func acc-clauses scope, list prop. acc-clauses Scope CL :- coq.elpi.accumulate-clauses Scope "hb.db" {std.map CL (c\r\ r = clause _ _ c)}. math-comp-hierarchy-builder-4d8a939/HB/common/compat_add_secvar_all.elpi000066400000000000000000000010351521677141400262770ustar00rootroot00000000000000func log.coq.env.add-section-variable-noimplicits id, term -> constant. log.coq.env.add-section-variable-noimplicits Name Ty C :- if (Name = "_") (ID is "fresh_name_" ^ {std.any->string {new_int}}) (ID = Name), % elpi:if version coq-elpi < 2.4.0 @local! => coq.env.add-section-variable ID Ty C, % elpi:endif % elpi:if version coq-elpi >= 2.4.0 @local! => coq.env.add-section-variable ID _ Ty C, % elpi:endif log.private.log-vernac (log.private.coq.vernac.variable ID Ty), @local! => log.coq.arguments.set-implicit (const C) [[]]. math-comp-hierarchy-builder-4d8a939/HB/common/database.elpi000066400000000000000000000414331521677141400235630ustar00rootroot00000000000000/* Hierarchy Builder: algebraic hierarchies made easy This software is released under the terms of the MIT license */ shorten coq.{ term->gref, subst-fun, safe-dest-app, mk-app, mk-eta, subst-prod }. %%%%%%%%% HB database %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% func from_factory prop -> factoryname. from_factory (from X _ _) X. func from_mixin prop -> mixinname. from_mixin (from _ X _) X. func from_builder prop -> term. from_builder (from _ _ X) (global X). func mixin-src_mixin prop -> mixinname. mixin-src_mixin (mixin-src _ M _) M. func mixin-src_src prop -> term. mixin-src_src (mixin-src _ _ S) S. func local-canonical-gref prop -> constant. local-canonical-gref (local-canonical C) C. func class_name hbclass -> classname. class_name (class N _ _) N. func class_structure hbclass -> structure. class_structure (class _ S _) S. func class-def_name prop -> classname. class-def_name (class-def (class N _ _)) N. func mixin-class_class prop -> classname. mixin-class_class (mixin-class _ C) C. func mixin-class_mixin prop -> mixinname. mixin-class_mixin (mixin-class M _) M. func classname->def classname -> hbclass. classname->def CN (class CN S ML) :- class-def (class CN S ML), !. func classname->mixins classname -> mixins. classname->mixins CN MLwP :- class-def (class CN _ MLwP), !. func module-to-export_module prop -> modpath. module-to-export_module (module-to-export _ _ M) M. func module-to-export_module-nice prop -> id. module-to-export_module-nice (module-to-export _ M _) M. func instance-to-export_instance prop -> constant. instance-to-export_instance (instance-to-export _ _ M) M. func instance-to-export_instance-nice prop -> id. instance-to-export_instance-nice (instance-to-export _ M _) M. func abbrev-to-export_name prop -> id. abbrev-to-export_name (abbrev-to-export _ N _) N. func abbrev-to-export_body prop -> term. abbrev-to-export_body (abbrev-to-export _ _ B) (global B). func clause-to-export_clause prop -> prop. clause-to-export_clause (clause-to-export _ C) C. func extract-builder prop -> builder. extract-builder (builder-decl B) B. func leq-builder builder, builder ->. leq-builder (builder N _ _ _) (builder M _ _ _) :- N =< M. func sub-class? hbclass, hbclass ->. sub-class? (class C1 _ ML1P) (class C2 _ ML2P) :- not (C1 = C2), list-w-params_list ML1P ML1, list-w-params_list ML2P ML2, std.forall ML2 (m2\ std.exists! ML1 (m1\ m1 = m2)). % [factory-provides F MLwP] computes the mixins MLwP generated by F func factory-provides factoryname -> mixins. factory-provides FactoryAlias MLwP :- std.do! [ std.assert-ok! (factory-alias->gref FactoryAlias Factory) "HB", gref->deps Factory RMLwP, w-params.map RMLwP (factory-provides.base Factory) MLwP ]. func mixin->factories mixinname -> list factoryname. mixin->factories M FL :- std.do! [ std.findall (from F_ M B_) AllF, std.map AllF from_factory FL ]. :index(1) func factory-provides.base factoryname, list term, term, list (w-args mixinname) -> list (w-args mixinname). factory-provides.base Factory Params T _RMLwP MLwP :- std.do! [ std.findall (from Factory T_ F_) All, std.map All from_mixin ML, std.map All from_builder BL, std.map2 BL ML (factory-provides.one Params T) MLwP, ]. func factory-provides.one list term, term, term, mixinname -> w-args mixinname. factory-provides.one Params T B M (triple M PL T) :- std.do! [ std.assert-ok! (coq.typecheck B Ty) "Builder illtyped", subst-prod [T] {subst-prod Params Ty} TyParams, std.assert! (extract-conclusion-params T TyParams PL) "The conclusion of a builder is a mixin whose parameters depend on other mixins", ]. func extract-conclusion-params term, term -> list term. extract-conclusion-params TheType (prod _ S T) R :- !, @pi-decl _ S x\ extract-conclusion-params TheType (T x) R. extract-conclusion-params TheType (app [global GR|Args]) R :- !, std.do! [ std.assert-ok! (factory-alias->gref GR Factory) "HB", factory->nparams Factory NP, std.map Args (copy-pack-holes TheType TheType) NewArgs, std.take NP NewArgs R]. extract-conclusion-params TheType T R :- whd1 T T1, !, extract-conclusion-params TheType T1 R. % [factories-provide FL ML] computes the mixins ML generated by all F in FL % % cons tp p\ nil t\ [pr f1 [p,t]] % f1 p t = m1 t, m2 p t % cons tp p\ nil t\ [pr m1 [t], pr m2 [p,t]] func factories-provide list-w-params factoryname -> mixins. factories-provide FLwP MLwP :- list-w-params.flatten-map FLwP factory-provides UnsortedMLwP, w-params.map UnsortedMLwP (p\t\ toposort-mixins) MLwP. func undup-grefs list gref -> list gref. undup-grefs L UL :- coq.gref.list->set L S, coq.gref.set.elements S UL. func undup-sorts list sort -> list sort. undup-sorts L R :- if (std.mem L prop) (R1 = [prop]) (R1 = []), if (std.mem L sprop) (R2 = [sprop]) (R2 = []), if (std.mem L (typ _)) (R3 = [typ _]) (R3 = []), std.flatten [R1, R2, R3] R. % also prunes cs-default func undup-cs-patterns list cs-pattern -> list cs-pattern. undup-cs-patterns L R :- std.map-filter L (x\r\ x = cs-gref r) LGR, undup-grefs LGR ULGR, std.map ULGR (x\r\ r = cs-gref x) R1, std.map-filter L (x\r\ x = cs-sort r) LS, undup-sorts LS ULS, std.map ULS (x\r\ r = cs-sort x) R2, if (std.mem L cs-prod) (R3 = [cs-prod]) (R3 = []), std.flatten [R1, R2, R3] R. % Mixins can be topologically sorted according to their dependencies func toposort-mixins list (w-args mixinname) -> list (w-args mixinname). toposort-mixins In Out :- std.map In triple_1 ML, std.map ML (m\r\sigma D D1\ gref->deps m D1, list-w-params_list D1 D, std.map D (d\r\r = pr d m) r) ES2, std.flatten ES2 ES, toposort-proj triple_1 ES In Out. func toposort-proj (func A -> gref), list (pair gref gref), list A -> list A. toposort-proj Proj ES In Out :- !, toposort-proj.acc Proj ES [] In Out. func topo-find B -> A. func toposort-proj.acc (pred i:A, o:gref), list (pair gref gref), list gref, list A -> list A. toposort-proj.acc _ ES Acc [] Out :- !, std.map {std.gref.toposort ES Acc} topo-find Out, !. toposort-proj.acc Proj ES Acc [A|In] Out :- std.do![ Proj A B, topo-find B A => toposort-proj.acc Proj ES [B|Acc] In Out ]. % Classes can be topologically sorted according to the subclass relation func toposort-classes.mk-class-edge prop -> pair classname classname. toposort-classes.mk-class-edge (sub-class C1 C2 _ _) (pr C2 C1). func toposort-classes list classname -> list classname. toposort-classes In Out :- std.do! [ std.findall (sub-class C1_ C2_ _ _) SubClasses, std.map SubClasses toposort-classes.mk-class-edge ES, std.gref.toposort ES In Out, ]. func findall-classes -> list hbclass. findall-classes CLSortedDef :- std.do! [ std.findall (class-def C_) All, std.map All class-def_name CL, toposort-classes CL CLSorted, std.map CLSorted classname->def CLSortedDef, ]. func findall-classes-for.unsorted list mixinname, list classname -> list classname. findall-classes-for.unsorted [] CL CL :- !. findall-classes-for.unsorted [M|ML] CLAcc Out :- std.do! [ std.findall (mixin-class M C_) All, std.map All mixin-class_class CL, findall-classes-for.unsorted ML {std.append CL CLAcc} Out ]. func findall-classes-for list mixinname -> list hbclass. findall-classes-for ML CLSortedDef :- std.do! [ findall-classes-for.unsorted ML [] CL, toposort-classes CL CLSorted, std.map CLSorted classname->def CLSortedDef, ]. func findall-builders -> list builder. findall-builders LFIL :- std.map {std.findall (builder-decl B_)} extract-builder LFILunsorted, std.bubblesort LFILunsorted leq-builder LFIL. func findall-has-mixin-instance cs-pattern -> list prop. findall-has-mixin-instance P CL :- std.findall (has-mixin-instance P _ _) CL. func has-mixin-instance_key prop -> cs-pattern. has-mixin-instance_key (has-mixin-instance P _ _) P. func findall-mixin-src term -> list mixinname. findall-mixin-src T ML :- std.map {std.findall (mixin-src T M_ V_)} mixin-src_mixin ML. func findall-factory->constructor -> list prop. findall-factory->constructor L :- std.map {std.findall (findall-factory->constructor.aux _)} findall-factory->constructor.make L. pred findall-factory->constructor.aux o:prop. findall-factory->constructor.aux (factory->constructor F C) :- is-factory F, factory->constructor F C. func findall-factory->constructor.make prop -> prop. findall-factory->constructor.make (findall-factory->constructor.aux P) P. func findall-local-canonical -> list constant. findall-local-canonical CL :- std.map {std.findall (local-canonical C_)} local-canonical-gref CL. % [distinct-pairs-below C AllSuper C1 C2] finds C1 and C2 in % AllSuper (all super classes of C) such that C1 != C2 % and for which there is no join C3. % If there exists a join C3 of C1 and C2 then C is a subclass % of C3 (otherwise C should have been declared before C3) % % / --- /-- C1 % C -- no C3 != % \ --- \-- C2 % % [findall-newjoins C AllSuper] finds all C1 and C2 such that C is a (new) join for % them pred distinct-pairs-below i:hbclass, i:list hbclass, o:hbclass, o:hbclass. distinct-pairs-below CurrentClass AllSuper C1 C2 :- std.mem AllSuper C1, std.mem AllSuper C2, % no cut until here, since we don't know which C1 and C2 to pick std.do! [ cmp_term C1 C2 lt, C1 = class C1n _ _, C2 = class C2n _ _ , not(sub-class? C1 C2), not(sub-class? C2 C1), if (join C1n C2n C3n) (assert-building-bottom-up CurrentClass C3n C1n C2n, fail) % a join, not a valid pair true, % no join, valid pair ]. pred assert-building-bottom-up i:hbclass, i:classname, i:classname, i:classname. assert-building-bottom-up CurrentClass C3n C1n C2n :- class-def (class C3n X Y), CurrentClass = class CC _ _, if (not (sub-class? CurrentClass (class C3n X Y))) (gref->modname CC 1 "." Before, gref->modname_short C3n "." After, gref->modname_short C1n "." C1nS, gref->modname_short C2n "." C2nS, Msg1 is "- declare structure " ^ Before ^ " before structure " ^ After ^ " if " ^ After ^ " inherits from it;", Msg2 is "- declare an additional structure that inherits from both " ^ C1nS ^ " and " ^ C2nS ^ " and from which " ^ Before ^ " and/or " ^ After ^ " inherit.", coq.error "You must declare the hierarchy bottom-up or add a missing join." "There are two ways out:" Msg1 Msg2) true. func distinct-pairs_pair prop -> pair hbclass hbclass. distinct-pairs_pair (distinct-pairs-below _ _ X Y) (pr X Y). func findall-newjoins hbclass, list hbclass -> list (pair hbclass hbclass). findall-newjoins CurrentClass AllSuper TodoJoins :- std.findall (distinct-pairs-below CurrentClass AllSuper C1_ C2_) JoinOf, std.map JoinOf distinct-pairs_pair TodoJoins. func class-coverage list classname -> coq.gref.set. class-coverage CNL CSet :- std.map CNL classname->mixins CMLLwP, std.map CMLLwP list-w-params_list CMLL, coq.gref.list->set {std.flatten CMLL} CSet. func assert-good-coverage! list mixinname, list classname ->. assert-good-coverage! MLSortedRev CNL :- std.do! [ coq.gref.list->set MLSortedRev MLSet, class-coverage CNL CMLSet, if (not(coq.gref.set.equal MLSet CMLSet)) (coq.gref.set.diff CMLSet MLSet Extra, coq.error "I could not find classes covering exactly mixins:" {std.any->string MLSortedRev} "In particular the covering" CNL "also includes mixins:" {coq.gref.set.elements Extra} "This should never happen, please report a bug.") true ]. %%%%% Coq Database %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [get-structure-coercion S1 S2 F] finds the coecion F from the structure S1 to S2 func get-structure-coercion structure, structure -> term. get-structure-coercion S T (global F) :- coq.coercion.db-for (grefclass S) (grefclass T) L, if (L = [pr F _]) true (coq.error "No one step coercion from" S "to" T). func get-structure-sort-projection structure -> term. get-structure-sort-projection (indt S) Proj :- !, coq.env.projections S L, if (L = [some P, _]) true (coq.error "No canonical sort projection for" S), Proj = global (const P). get-structure-sort-projection S _ :- coq.error "get-structure-sort-projection: not a structure" S. func get-structure-class-projection structure -> term. get-structure-class-projection (indt S) T :- !, coq.env.projections S L, if (L = [_, some P]) true (coq.error "No canonical class projection for" S), T = global (const P). get-structure-class-projection S _ :- coq.error "get-structure-class-projection: not a structure" S. func get-constructor gref -> gref. get-constructor (indt R) (indc K) :- !, if (coq.env.indt R _ _ _ _ [K] _) true (coq.error "Not a record" R). get-constructor I _ :- coq.error "get-constructor: not an inductive" I. % finding for locally defined structures func get-cs-structure cs-instance -> structure. get-cs-structure (cs-instance _ _ (const Inst)) Struct :- std.do! [ coq.env.typeof (const Inst) InstTy, coq.prod-tgt->gref InstTy Struct, is-structure Struct, ]. func get-cs-instance cs-instance -> constant. get-cs-instance (cs-instance _ _ (const Inst)) Inst. func has-cs-instance gref, cs-instance ->. has-cs-instance GTy (cs-instance _ (cs-gref GTy) _). func mixin-src->has-mixin-instance prop -> prop. mixin-src->has-mixin-instance (mixin-src (global GR) M I) (has-mixin-instance (cs-gref GR) M IHd) :- term->gref I IHd. mixin-src->has-mixin-instance (mixin-src (app [global GR|_] ) M I) (has-mixin-instance (cs-gref GR) M IHd) :- term->gref I IHd. mixin-src->has-mixin-instance (mixin-src (prod _ _ _ ) M I) (has-mixin-instance cs-prod M IHd):- term->gref I IHd. mixin-src->has-mixin-instance (mixin-src (sort U) M I) (has-mixin-instance (cs-sort U) M IHd):- term->gref I IHd. % this auxiliary function iterates over the list of arguments of an application, % and create the necessary unify condition for each arguments % and at the end returns the mixin-src clause with all the conditions func mixin-instance-type->mixin-src.aux list term, % list of arguments term, % head of the original application mixinname, % name of mixin term, % instance body list prop % Cond list -> prop. mixin-instance-type->mixin-src.aux [] T M I Cond (mixin-src T M I :- Cond). mixin-instance-type->mixin-src.aux [A|Args] T M I Cond (pi a \ C a) :- pi a \ sigma Ta\ coq.mk-app T [a] Ta, mixin-instance-type->mixin-src.aux Args Ta M I [coq.unify-eq A a ok|Cond] (C a). % transforms the type of a mixin instance into a % mixin-src clause with eventual conditions regarding its parameters :index (1) func mixin-instance-type->mixin-src term, % type of the instance Ty mixinname, % name of mixin term, % instance body I of type Ty list prop % Cond list -> prop. mixin-instance-type->mixin-src (app _ as F) M I Cond C :- factory? F (triple _ _ Subject), safe-dest-app Subject Hd Args, mixin-instance-type->mixin-src.aux Args Hd M I Cond C. mixin-instance-type->mixin-src (prod N_ _ F) M I Cond (pi a \ C a) :- pi a\ sigma Ia \ coq.mk-app I [a] Ia, mixin-instance-type->mixin-src (F a) M Ia Cond (C a). func has-mixin-instance->mixin-src prop -> prop. has-mixin-instance->mixin-src (has-mixin-instance _ M IHd) C :- std.do![ T = global IHd, coq.env.typeof IHd Ty, mixin-instance-type->mixin-src Ty M T [] C, ]. func get-canonical-structures term -> list structure. get-canonical-structures TyTrm StructL :- std.do! [ term->cs-pattern TyTrm Pat, !, coq.CS.db-for _ Pat DBGTyL, std.map-filter DBGTyL get-cs-structure StructL, ]. func get-canonical-instances term -> list constant. get-canonical-instances TyTrm StructL :- term->cs-pattern TyTrm Pat, coq.CS.db-for _ Pat DBGTyL, std.map-filter DBGTyL get-cs-instance StructL. func has-CS-instance? term, structure ->. has-CS-instance? TyTerm (indt Struct) :- term->cs-pattern TyTerm Pat, coq.env.projections Struct [some Proj, _], coq.CS.db-for (const Proj) Pat L, not(L = []). pred structure-nparams i:structure, o:int. structure-nparams Structure NParams :- class-def (class Class Structure _), factory->nparams Class NParams. func factory? term -> w-args factoryname. factory? S (triple F Params T) :- not (var S), !, safe-dest-app S (global GR) Args, factory-alias->gref GR F ok, factory->nparams F NP, !, std.split-at NP Args Params [T|_]. % [find-max-classes Mixins Classes] states that Classes is a list of classes % which contain all the mixins in Mixins. % Although it is not strictly necessary, but desirable for debugging, % we use a heuristic that tries to minimize the number % of classes by assuming Mixins are reversed topologically sorted. % Note: works with flat mixins, no params pred find-max-classes i:list mixinname, o:list classname. find-max-classes [] []. find-max-classes [M|Mixins] [C|Classes] :- mixin->first-class M C, std.do! [ class-def (class C _ MLwP), list-w-params_list MLwP ML, std.filter Mixins (x\ not (std.mem! ML x)) Mixins', find-max-classes Mixins' Classes ]. find-max-classes [M|_] _ :- coq.error "HB: cannot find a class containing mixin" M. math-comp-hierarchy-builder-4d8a939/HB/common/log.elpi000066400000000000000000000463601521677141400226040ustar00rootroot00000000000000/* Hierarchy Builder: algebraic hierarchies made easy This software is released under the terms of the MIT license */ % This file contains proxies for the API to write into the Coq state (eg add % an inductive, set implicit arguments...). This has two purposes: % - give nicer error messages % - we want to be able to log to a file all these actions (WIP), this file is % were logging takes place. Hence we never call, say, coq.evn.add-* directly, % but always via this proxy namespace log.coq { :index (1) func arguments.set-implicit gref, list (list implicit_kind). arguments.set-implicit GR I :- coq.arguments.set-implicit GR I, if (@local!) (Local = tt) (Local = ff), log.private.log-vernac (log.private.coq.vernac.implicit Local {coq.gref->id GR} I). func env.add-location gref ->. env.add-location GR :- if (get-option "elpi.loc" Loc) % remove when coq-elpi > 1.9 (acc-clause library (decl-location GR Loc)) true. func strategy.set list constant, conversion_strategy ->. strategy.set CL S :- coq.strategy.set CL S, log.private.log-vernac (log.private.coq.vernac.strategy CL S). :index (1) func env.add-const-noimplicits id, term, term, opaque? -> constant. env.add-const-noimplicits Name Bo Ty Opaque C :- std.do! [ if (not(ground_term Ty ; ground_term Bo)) (coq.error "HB: cannot infer some information in" Name ":" {coq.term->string Ty} ":=" {coq.term->string Bo}) true, avoid-name-collision Name Name1, coq.env.add-const Name1 Bo Ty Opaque C, env.add-location (const C), if (var Ty) (Ty? = none) (Ty? = some Ty), log.private.log-vernac (log.private.coq.vernac.definition Name1 Ty? Bo), @local! => arguments.set-implicit (const C) [[]], ]. :index (1) func env.add-const id, term, term, opaque? -> constant. env.add-const Name Bo Ty Opaque C :- std.do! [ if (not(ground_term Ty ; ground_term Bo)) (coq.error "HB: cannot infer some information in" Name ":" {coq.term->string Ty} ":=" {coq.term->string Bo}) true, avoid-name-collision Name Name1, coq.env.add-const Name1 Bo Ty Opaque C, env.add-location (const C), if (var Ty) (Ty? = none) (Ty? = some Ty), log.private.log-vernac (log.private.coq.vernac.definition Name1 Ty? Bo), ]. func env.add-const-noimplicits-failondup id, term, term, opaque? -> constant. env.add-const-noimplicits-failondup Name Bo Ty Opaque C :- std.do! [ if (not(ground_term Ty ; ground_term Bo)) (coq.error "HB: cannot infer some information in" Name ":" {coq.term->string Ty} ":=" {coq.term->string Bo}) true, coq.env.add-const Name Bo Ty Opaque C, env.add-location (const C), if (var Ty) (Ty? = none) (Ty? = some Ty), log.private.log-vernac (log.private.coq.vernac.definition Name Ty? Bo), @local! => arguments.set-implicit (const C) [[]], ]. func env.add-parameter id, term -> constant. env.add-parameter ID Ty C :- std.do! [ @global! => coq.env.add-axiom ID Ty C, log.private.log-vernac (log.private.coq.vernac.parameter ID Ty), ]. func env.add-indt indt-decl -> inductive. env.add-indt Decl I :- std.do! [ if (not(coq.ground-indt-decl? Decl)) (coq.error "HB: cannot infer some information in" {coq.indt-decl->string Decl}) true, coq.env.add-indt Decl I, (coq.env.record? I P ; P = ff), log.private.log-vernac (log.private.coq.vernac.inductive Decl P), env.add-location (indt I), % copy the current value of implicit arguments coq.env.indt I _ _ _ _ KS _, log.private.log-implicits-of ff (indt I), std.forall KS (k\ env.add-location (indc k), log.private.log-implicits-of ff (indc k)), std.forall {coq.env.projections I} (p\ sigma c\ if (p = some c) (env.add-location (const c), log.private.log-implicits-of ff (const c)) true), ]. :index (_ 1) func env.begin-module id, option (pair modtypath id) . env.begin-module Name none :- coq.env.begin-module Name none, log.private.log-vernac (log.private.coq.vernac.begin-module Name none). env.begin-module Name (some (pr Sig SigName)) :- std.do! [ coq.env.begin-module Name (some Sig), log.private.log-vernac (log.private.coq.vernac.begin-module Name (some SigName)), ]. func env.begin-module-type id ->. env.begin-module-type Name :- std.do! [ coq.env.begin-module-type Name, log.private.log-vernac (log.private.coq.vernac.begin-module-type Name), ]. func env.end-module-name id -> modpath. env.end-module-name Name M :- coq.env.end-module M, log.private.log-vernac (log.private.coq.vernac.end-module Name). func env.end-module-type-name id -> modtypath. env.end-module-type-name Name M :- std.do! [ coq.env.end-module-type M, log.private.log-vernac (log.private.coq.vernac.end-module-type Name), ]. func env.begin-section id ->. env.begin-section Name :- std.do! [ coq.env.begin-section Name, log.private.log-vernac (log.private.coq.vernac.begin-section Name), ]. func env.end-section-name id. env.end-section-name Name :- std.do! [ coq.env.end-section, log.private.log-vernac (log.private.coq.vernac.end-section Name), ]. func notation.add-abbreviation id, int, term, bool -> abbreviation. notation.add-abbreviation Name NArgs Body OnlyParsing O :- coq.notation.add-abbreviation Name NArgs Body OnlyParsing O, log.private.log-vernac (log.private.coq.vernac.abbreviation Name NArgs Body). func env.export-module id, modpath ->. env.export-module MPNice M :- std.do! [ coq.env.export-module M, log.private.log-vernac (log.private.coq.vernac.export-module MPNice), ]. func env.import-module id, modpath ->. env.import-module MPNice M :- std.do! [ coq.env.import-module M, log.private.log-vernac (log.private.coq.vernac.import-module MPNice), ]. func coercion.declare coercion -> . coercion.declare C :- std.do! [ @global! => @reversible! => coq.coercion.declare C, C = coercion GR _ SRCGR TGTCL, coq.gref->id GR Name, log.private.log-vernac (log.private.coq.vernac.coercion Name SRCGR TGTCL), ]. } % Since CS.foo is not a valid predicate name we can't use it % in the namespace, so we just define it here with the full name func log.coq.CS.declare-instance constant ->. log.coq.CS.declare-instance C :- std.do! [ if (@local!) (Local = tt) (Local = ff), coq.CS.declare-instance (const C), coq.gref->id (const C) Id, std.last {coq.gref->path (const C)} M, std.last {coq.env.current-path} M1, if (M = M1) (Name = Id) (Name is M ^ "." ^ Id), log.private.log-vernac (log.private.coq.vernac.canonical Name Local), ]. func log.coq.check term -> term, term, diagnostic. log.coq.check Skel Ty T D :- std.do! [ coq.elaborate-skeleton Skel Ty T D, if (get-option "fail" tt) (Fail = tt) (Fail = ff), log.private.log-vernac (log.private.coq.vernac.check Skel Fail), ]. func refine term, goal -> list sealed-goal. % to silence a warning, since this is only in tactics func log.refine term, goal -> list sealed-goal. log.refine T G GL :- std.do! [ refine T G GL, G = goal _ _ _ Solution _, log.private.log-tactic Solution, ]. func refine.no_check term, goal -> list sealed-goal. % to silence a warning, since this is only in tactics func log.refine.no_check term, goal -> list sealed-goal. log.refine.no_check T G GL :- std.do! [ refine.no_check T G GL, G = goal _ _ _ Solution _, log.private.log-tactic Solution, ]. namespace log.private { %%%%% Logging Utils %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% func log-implicits-of bool, gref -> . log-implicits-of Local GR :- coq.arguments.implicit GR I, if (std.forall I (i\ std.forall i (x\ x = explicit))) (IMP = [[]]) (IMP = I), log.private.log-vernac (log.private.coq.vernac.implicit Local {coq.gref->id GR} IMP). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Coq document % This is a very minimalistic AST to represent a Coq document equipped with % pretty printing facilities. % % When "complete enough" this should be moved to coq-elpi proper. kind coq.vernac type. type coq.vernac.begin-module string -> option string -> coq.vernac. type coq.vernac.end-module string -> coq.vernac. type coq.vernac.begin-module-type string -> coq.vernac. type coq.vernac.end-module-type string -> coq.vernac. type coq.vernac.begin-section string -> coq.vernac. type coq.vernac.end-section string -> coq.vernac. type coq.vernac.import-module string -> coq.vernac. type coq.vernac.export-module string -> coq.vernac. type coq.vernac.definition string -> option term -> term -> coq.vernac. type coq.vernac.variable string -> term -> coq.vernac. type coq.vernac.parameter string -> term -> coq.vernac. type coq.vernac.inductive indt-decl -> bool -> coq.vernac. type coq.vernac.abbreviation string -> int -> term -> coq.vernac. type coq.vernac.notation string -> int -> term -> coq.vernac. type coq.vernac.coercion string -> gref -> class -> coq.vernac. type coq.vernac.canonical string -> bool -> coq.vernac. type coq.vernac.implicit bool -> string -> list (list implicit_kind) -> coq.vernac. type coq.vernac.comment A -> coq.vernac. type coq.vernac.check term -> bool -> coq.vernac. type coq.vernac.strategy list constant -> conversion_strategy -> coq.vernac. } func with-logging (func) ->. func log.private.log-vernac log.private.coq.vernac ->. func log.private.log-tactic term ->. /* Hierarchy Builder: algebraic hierarchies made easy This software is released under the terms of the MIT license */ % implementation of logging and vernac printing with-logging P :- (get-option "elpi.hb.log" _, NICE = tt ; get-option "elpi.hb.log.raw" _, NICE = ff), !, get-option "elpi.loc" Loc, !, loc.fields Loc FILE Start Stop _ _, LocStr is "characters " ^ {std.any->string Start} ^ "-" ^ {std.any->string Stop}, FILENAME is FILE ^ ".hb", open_append FILENAME OC1, std.string.concat "\n" ["","HIERARCHY BUILDER PATCH v1",LocStr,""] PATCH1, output OC1 PATCH1, close_out OC1, (log.private.logger L NICE => P), log.private.logger-close L, std.intersperse coq.pp.spc L PP, coq.pp->string (coq.pp.box (coq.pp.v 0) PP) S, open_append FILENAME OC2, output OC2 S, close_out OC2. with-logging P :- (get-option "log" tt, NICE = tt ; get-option "log.raw" tt, NICE = ff), !, (log.private.logger L NICE => P), log.private.logger-close L, std.intersperse coq.pp.spc L PP, coq.pp->string (coq.pp.box (coq.pp.v 0) PP) S, coq.say "(* \n" S "\n*)". with-logging P :- P. log.private.log-vernac V :- log.private.logger L Nice, !, if (Nice = tt) (PPALL = []) (PPALL = [@ppall!]), log.private.logger-extend L {PPALL => log.private.coq.vernac->pp [V]}. log.private.log-vernac _. log.private.log-tactic P :- log.private.logger L Nice, !, if (Nice = tt) (PPALL = []) (PPALL = [@ppall!]), log.private.logger-extend L {PPALL => @holes! => coq.term->pp P}. log.private.log-tactic _. % The main entry point to print vernacular commands is coq.vernac->pp shorten log.private.coq.vernac.{ begin-module , end-module , begin-section, end-section }. shorten log.private.coq.vernac.{ begin-module-type , end-module-type }. shorten log.private.coq.vernac.{ import-module , export-module }. shorten log.private.coq.vernac.{ definition , variable , comment , check }. shorten log.private.coq.{ vernac.inductive , vernac.implicit , vernac.parameter }. shorten log.private.coq.vernac.{ canonical , abbreviation , notation , coercion , strategy }. shorten log.private.{ coq.vernac }. shorten coq.pp.{ box , h , spc , v , str , hv , hov, glue, brk }. namespace log.private { pred logger o:list coq.pp, o:bool. :index (1) func logger-extend list coq.pp, coq.pp ->. logger-extend [] _ :- coq.error "HB: logger was closed". logger-extend (uvar as X) V :- X = [V|FRESH_]. logger-extend [_|XS] V :- logger-extend XS V. func logger-close list coq.pp ->. logger-close (uvar as X) :- X = []. logger-close [_|XS] :- logger-close XS. func coq.vernac->pp list coq.vernac -> coq.pp. coq.vernac->pp L (box (v 0) L2) :- std.map L coq.vernac->pp1 L1, std.intersperse spc L1 L2. func coq.vernac->pp1 coq.vernac -> coq.pp. coq.vernac->pp1 (begin-module Name none) PP :- PP = box h [str "Module ", str Name, str "."]. coq.vernac->pp1 (begin-module Name (some TyName)) PP :- PP = box h [str "Module ", str Name, str " : ", str TyName, str "."]. coq.vernac->pp1 (end-module Name) PP :- PP = box h [str "End ", str Name, str "."]. coq.vernac->pp1 (begin-module-type Name) PP :- PP = box h [str "Module Type ", str Name, str "."]. coq.vernac->pp1 (end-module-type Name) PP :- PP = box h [str "End ", str Name, str "."]. coq.vernac->pp1 (begin-section Name) PP :- PP = box h [str "Section ", str Name, str "."]. coq.vernac->pp1 (end-section Name) PP :- PP = box h [str "End ", str Name, str "."]. coq.vernac->pp1 (definition Name none Body) PP :- PP = box (hv 2) [str "Definition ", str Name, str " :=", spc, B, str "."], coq.term->pp Body B. coq.vernac->pp1 (definition Name (some Ty) Body) PP :- PP = box (hv 2) [str "Definition ", str Name, str " : ", T, str " :=", spc, B, str "."], coq.term->pp Ty T, coq.term->pp Body B. coq.vernac->pp1 (variable Name Ty) (box (hv 2) [box h [str "Variable ", str Name, str " :"], spc, TY, str "."]) :- coq.term->pp Ty TY. coq.vernac->pp1 (vernac.parameter Name Ty) (box (hv 2) [box h [str "Parameter ", str Name, str " :"], spc, TY, str "."]) :- coq.term->pp Ty TY. coq.vernac->pp1 (import-module Name) (box h [str "Import ", str Name, str "."]). coq.vernac->pp1 (export-module Name) (box h [str "Export ", str Name, str "."]). coq.vernac->pp1 (notation KM NParams Term) (box (hv 2) [box h [str "Notation \"'",str KM,str"' "|StrParams], str "\" := (", spc, B, str ") (at level 1)."]) :- !, coq.vernac->ppabbrterm NParams Term StrParams B. coq.vernac->pp1 (abbreviation Name NParams Term) (box (hv 2) [box h [str "Notation ",str Name|StrParams], str " := (", spc, B, str ")."]) :- coq.vernac->ppabbrterm NParams Term StrParams B. coq.vernac->pp1 (canonical Name Local) (box h [Locality, str "Canonical ", str Name, str "."]) :- local->locality Local Locality. coq.vernac->pp1 (coercion Name SRC TGT) (box h [str "#[reversible] Coercion ", str Name, str " : ", str S, str " >-> ", str T, str "."]) :- coq.gref->path SRC SP, std.string.concat "." {std.take-last 2 SP} S', S is S' ^ "." ^ {coq.gref->id SRC}, if2 (TGT = sortclass) (T = "Sortclass") (TGT = funclass) (T = "Funclass") (TGT = grefclass GR, coq.gref->path GR GRP, std.string.concat "." {std.take-last 2 GRP} T', T is T' ^ "." ^ {coq.gref->id GR}). coq.vernac->pp1 (vernac.inductive I Primitive) (glue [str Start, PP, str Stop]) :- coq.vernac->ppinductive I [] PP, if (Primitive = tt) (Start = "Set Primitive Projections. ", Stop = "Unset Primitive Projections. ") (Start = "", Stop = ""). coq.vernac->pp1 (vernac.implicit Local Name [[]]) (box h [Locality, str "Arguments ", str Name, str " : clear implicits."]) :- !, local->locality Local Locality. coq.vernac->pp1 (vernac.implicit Local Name [L]) (box h [Locality, str "Arguments ", str Name, spc, glue PP, str "."]) :- local->locality Local Locality, std.map L coq.vernac->ppimparg PP1, std.intersperse spc PP1 PP. coq.vernac->pp1 (comment A) (box (hov 2) [str"(*", str S, str"*)"]) :- std.any->string A S. coq.vernac->pp1 (check T Fail) (box (hov 2) [Failure, str"Check", spc, PPT, str"."]) :- (@holes! => coq.term->pp T PPT), fail->failure Fail Failure. coq.vernac->pp1 (strategy L opaque) (box (hov 2) [str"Strategy opaque [", glue PPL , str"]."]) :- std.map L (c\r\sigma id\coq.gref->id (const c) id, r = str id) LID, std.intersperse spc LID PPL. coq.vernac->pp1 (strategy L expand) (box (hov 2) [str"Strategy expand [", glue PPL , str"]."]) :- std.map L (c\r\sigma id\coq.gref->id (const c) id, r = str id) LID, std.intersperse spc LID PPL. coq.vernac->pp1 (strategy L (level N)) (box (hov 2) [str"Strategy ",str NPP,str" [", glue PPL , str"]."]) :- std.any->string N NPP, std.map L (c\r\sigma id\coq.gref->id (const c) id, r = str id) LID, std.intersperse spc LID PPL. func local->locality bool -> coq.pp. local->locality tt (str "Local "). local->locality ff (str "Global "). func fail->failure bool -> coq.pp. fail->failure tt (str "Fail "). fail->failure ff (str ""). func coq.vernac->ppimparg implicit_kind -> coq.pp. coq.vernac->ppimparg explicit (str "_"). coq.vernac->ppimparg maximal (str "{_}"). coq.vernac->ppimparg implicit (str "[_]"). :index (3) func coq.vernac->ppinductive indt-decl, list (pair implicit_kind term) -> coq.pp. coq.vernac->ppinductive (parameter ID IMPL TY I) Acc R :- @pi-parameter ID TY p\ coq.vernac->ppinductive (I p) [pr IMPL p|Acc] R. coq.vernac->ppinductive (record ID SORT KID RD) ParamsRev (box (v 0) [Hack1, PP, Hack2]) :- PP = (box (hov 0) [ box (hov 0) [str "Record", spc, str ID, brk 1 4, glue ParamsPP, str " : ", SortPP, brk 1 2, str":= ", str KID], brk 1 2, box (hv 2) [str"{", spc, glue FieldsPP, str"}"], str"."]), Hack1 = glue [str "Section ", str ID, str ".", spc, str "Local Unset Implicit Arguments.", spc], Hack2 = glue [spc, str "End ", str ID, str".", spc], std.rev ParamsRev Params, coq.vernac->ppinductiveparams Params ParamsPP, coq.term->pp SORT SortPP, coq.vernac->pprecordfields RD FieldsPP. coq.vernac->ppinductive (inductive ID IsInd Arity Ks) ParamsRev PP :- PP = (box (hov 0) [ str CO,str "Inductive", spc, box (hov 0) [ str ID, brk 1 4, glue ParamsPP, ArityPP, str " :="], brk 0 2, box (hv 2) [str" ", glue KsPp], str "."]), std.rev ParamsRev Params, coq.vernac->ppinductiveparams Params ParamsPP, std.map Params snd ParamsAsArgs, if (IsInd = tt) (CO = "") (CO = "Co"), coq.arity->pp Arity ArityPP, @pi-inductive ID Arity x\ coq.mk-app x ParamsAsArgs (X x), coq.vernac->ppinductiveconstructor (Ks (X x)) KsPp. func coq.vernac->ppinductiveconstructor list indc-decl -> list coq.pp. coq.vernac->ppinductiveconstructor [] []. coq.vernac->ppinductiveconstructor [constructor ID Arity|Ks] PP :- PP = [str ID,{coq.arity->pp Arity},SEP|Rest], if (Ks = []) (SEP = str"") (SEP = glue [brk 1 0, str "| "]), coq.vernac->ppinductiveconstructor Ks Rest. func coq.vernac->ppinductiveparams list (pair implicit_kind term) -> list coq.pp. coq.vernac->ppinductiveparams [] []. coq.vernac->ppinductiveparams [pr Imp T|Rest] PP :- PP = [box (hov 2) [str A,ID,str " : ", TY,str B]|PPRest], coq.term->pp T ID, decl T _ Ty, coq.term->pp Ty TY, if2 (Imp = explicit) (A = "(", B = ")") (Imp = maximal) (A = "{", B = "}") (A = "[", B = "]"), coq.vernac->ppinductiveparams Rest PPRest. func coq.vernac->pprecordfields record-decl -> list coq.pp. coq.vernac->pprecordfields end-record []. coq.vernac->pprecordfields (field _ ID TY F) [ str ID, str " : ", TYPP, str ";", spc|FPP] :- % TODO attributes coq.term->pp TY TYPP, @pi-parameter ID TY p\ coq.vernac->pprecordfields (F p) FPP. :index (1 1) func coq.vernac->ppabbrterm int, term -> list coq.pp, coq.pp. coq.vernac->ppabbrterm 0 T [] B :- !, @holes! => coq.term->pp T B. coq.vernac->ppabbrterm N (fun _ _ F) [spc,str ID|StrParams] B :- ID is "X" ^ {std.any->string N}, coq.id->name ID Name, M is N - 1, @pi-decl Name (sort prop) x\ coq.vernac->ppabbrterm M (F x) StrParams B. } math-comp-hierarchy-builder-4d8a939/HB/common/phant-abbreviation.elpi000066400000000000000000000322721521677141400255750ustar00rootroot00000000000000/* Hierarchy Builder: algebraic hierarchies made easy This software is released under the terms of the MIT license */ % Kit to build abbreviations /à la/ *pack*, that is % [Notation N x_0 .. x_n := C x_0 .. _ _ id .. x_i .. _ id _ _ id] % with a variable number of [_] between each [id], and where % - [x_i] is given by the user % - [_] correspond to arguments that are left implicit, % - [id] trigger unification as described in % - [Phant x] to infer the canonical structure on x % % See /Canonical Structures for the working Coq user/ by Mahboubi and Tassi % This type is private, build it via the APIs below typeabbrev phant-term phant.private.phant-term. namespace phant { % [add-abbreviation Name PhT C A] builds a definition "phant_Name" for the % term T and an abbreviation Name as per Ph. % Use the API below to build a PhT as you like. func add-abbreviation string, phant-term -> constant, abbreviation. add-abbreviation N (private.phant-term AL T1) C Abbrev :- std.do! [ NC is "phant_" ^ N, std.assert-ok! (coq.elaborate-skeleton T1 TTy T) "add-abbreviation: T illtyped", log.coq.env.add-const-noimplicits NC T TTy @transparent! C, private.build-abbreviation 0 (global (const C)) AL NParams AbbrevT, @global! => log.coq.notation.add-abbreviation N NParams AbbrevT tt Abbrev, ]. % [of-gref WithCopy GR RealMixinArgs PT] % builds a phant-term taking all parameters, % the type, then inferring automatically all structures covering the mixins % GR depends on. RealMixinArgs is a list of mixins one wants to explicitly % pass (instead of being inferred) % If WithCopy = tt, an extra argument is added after all the parameters % and before the source keu to replace the target key by a user chosen one. func of-gref bool, gref, list mixinname -> phant-term. of-gref WithCopy GRF RealMixinArgs PhBody:- !, std.do! [ std.assert! (gref->deps GRF MLwP) "mk-phant-term: unknown gref", std.assert! (coq.env.typeof GRF FTy) "mk-phant-term: F illtyped", coq.mk-eta (-1) FTy (global GRF) EtaF, % toposort-mixins ML MLSorted, MLwP = MLwPSorted, % Assumes we give them already sorted in dep order. std.rev {list-w-params_list MLwPSorted} MLSortedRev, std.map RealMixinArgs (m\ r\ r = private.this-mixin-is-real-arg m) RMClauses, std.filter MLSortedRev (m\ not(std.mem! RealMixinArgs m)) MLSortedRevFiltered, find-max-classes MLSortedRevFiltered CNL, assert-good-coverage! MLSortedRevFiltered CNL, RMClauses => if (WithCopy = ff) (w-params.then MLwP fun-real fun-real (ps\ t\ ml\ o\ private.mk-phant-term.classes EtaF CNL ps t t ml o) PhBody) (w-params.fold MLwP fun-real (private.mk-phant-term-with-copy EtaF CNL) PhBody ) ]. % API à la carte: start with a term and wrap it up ------------------------- % A term with no phantom arguments func init term -> phant-term. init T (private.phant-term [] T). % [fun-real N T Ph Ph1] Adds a real argument named N of type T around Ph func fun-real name, term, (term -> phant-term) -> phant-term. fun-real N T F Res :- !, private.phant-fun (private.real N) T F Res. % [fun-unify Msg X1 X2 Ph Ph1] Adds an argument that will foce the unification % of X1 with X2 and print Msg is case of error around Ph func fun-unify option term, term, term, phant-term -> phant-term. fun-unify OMsg X1 X2 (private.phant-term AL F) (private.phant-term [private.unify|AL] UF) :- std.assert-ok! (coq.typecheck X1 T1) "fun-unify: X1 illtyped", std.assert-ok! (coq.typecheck X2 T2) "fun-unify: X2 illtyped", if (OMsg = some M) (Msg = {{lib:hb.not_a_msg lp:M}}) (Msg = {{lib:hb.nomsg}}), UF = {{fun unif_arbitrary : lib:hb.unify lp:T1 lp:T2 lp:X1 lp:X2 lp:Msg => lp:F}}. % [fun-implicit N T Ph Ph1] Adds an implicit argument name N of type T areound Ph func fun-implicit name, term, (term -> phant-term) -> phant-term. fun-implicit N Ty (t\ private.phant-term AL (F t)) (private.phant-term [private.implicit|AL] (fun N Ty F)). % [fun-infer-type N T Ph Ph1] Adds an argument N of type T such that one passes % a value V of type {{ Type }} the corresponding canonical VC of type T is passed % for N , eg `fun T (phT : phant T) => Ph` func fun-infer-type class, name, term, (term -> phant-term) -> phant-term. fun-infer-type sortclass N Ty (t\private.phant-term AL (Bo t)) Out :- coq.name-suffix N "ph" PhN, fun-implicit N Ty (t\private.phant-term [private.infer-type N sortclass|AL] (fun PhN {{ lib:@hb.phant lp:t }} _\ Bo t)) Out. fun-infer-type funclass N Ty (t\private.phant-term AL (Bo t)) Out :- coq.name-suffix N "ph" PhN, fun-implicit N Ty (t\private.phant-term [private.infer-type N funclass|AL] (fun PhN {{ lib:@hb.phantom (_ -> _) lp:t }} _\ Bo t)) Out. fun-infer-type (grefclass Class) N Ty (t\private.phant-term AL (Bo t)) Out :- coq.name-suffix N "ph" PhN, private.build-type-pattern Class Pat, fun-implicit N Ty (t\private.phant-term [private.infer-type N (grefclass Class)|AL] (fun PhN {{ lib:@hb.phantom lp:Pat lp:t }} _\ Bo t)) Out. % TODO: this looks like a hack to remove func append-fun-unify phant-term -> phant-term. append-fun-unify (private.phant-term LP T) (private.phant-term LPU T) :- std.append LP [private.unify] LPU. /* ------------------------------------------------------------------------- */ /* ----------------------------- private code ------------------------------ */ /* ------------------------------------------------------------------------- */ namespace private { % phant-term is a pair of a list of argument kinds together with a term kind phant-term type. type phant-term list phant-arg -> term -> phant-term. % phant-arg encode these three kind of arguments % - [x_i] is encoded using [real x_i] % - [_] using [implicit] % - [id] using [unify] % - [Phant x] using [infer-type] kind phant-arg type. type real name -> phant-arg. type infer-type name -> class -> phant-arg. type implicit phant-arg. type unify phant-arg. shorten coq.{ mk-app }. pred this-mixin-is-real-arg o:mixinname. func phant-fun phant-arg, term, (term -> phant-term) -> phant-term. phant-fun Arg Ty PhF (phant-term [Arg|ArgL] (fun N Ty F)) :- if (Arg = real N) true (N = `_`), @pi-decl N Ty x\ PhF x = phant-term ArgL (F x). % [phant-fun-mixin N Ty PF PUF] states that PUF is a phant-term % which quantifies [PF x] over [x : Ty] (with name N) % Ty must be an (applied) mixin M, and the phantom status of this mixin % is determined by [this-mixin-is-real-arg M]. func phant-fun-mixin name, term, (term -> phant-term) -> phant-term. phant-fun-mixin N Ty PF (private.phant-term [Status|AL] (fun N Ty F)) :- !, std.do! [ @pi-decl N Ty t\ PF t = private.phant-term AL (F t), coq.safe-dest-app Ty (global Mixin) _, if (this-mixin-is-real-arg Mixin) (Status = private.real N) (Status = private.implicit) ]. func fun-unify-mixin term, name, term, (term -> phant-term) -> phant-term. fun-unify-mixin T N Ty PF Out :- !, std.do! [ coq.safe-dest-app Ty (global M) _, Msg is "fun-unify-mixin: No mixin-src on " ^ {coq.term->string T}, std.assert! (mixin-src T M Msrc) Msg, (@pi-decl `m` Ty m\ fun-unify none m Msrc (PF m) (PFM m)), fun-implicit N Ty PFM Out ]. % [phant-fun-struct T S Params PF PSF] states that PSF is a phant-term % which postulate a structure [s : S Params] such that [T = sort s] % and then outputs [PF s] func phant-fun-struct term, name, structure, list term, (term -> phant-term) -> phant-term. phant-fun-struct T Name S Params PF Out :- std.do! [ get-structure-sort-projection S SortProj, mk-app (global S) Params SParams, mk-app SortProj Params SortProjParams, % Msg = {{lib:hb.nomsg}}, Msg = some {{lp:SParams}}, (@pi-decl Name SParams s\ fun-unify Msg T {mk-app SortProjParams [s]} (PF s) (UnifSI s)), fun-implicit Name SParams UnifSI Out ]. % A *pack* notation can be easiliy produced from a phant-term using % [add-abbreviation N PT C], which states that C is a new constant % which name is phant_N, and which produces a simple notation % with name N using the data of the phant-term PT to reconstruct a notation % [Notation N x0 .. xn := C x0 _ _ id .. xi .. _ id _ _ id] % as described above. func build-abbreviation int, term, list phant-arg -> int, term. build-abbreviation K F [] K F. build-abbreviation K F [real N|AL] K'' (fun N _ AbbrevFx) :- !, pi x\ build-abbreviation K {mk-app F [x]} AL K' (AbbrevFx x), K'' is K' + 1. build-abbreviation K F [infer-type N sortclass|AL] K'' (fun N _ AbbrevFx) :- !, pi x\ build-abbreviation K {mk-app F [{{ lib:hb.Phant lp:x }}]} AL K' (AbbrevFx x), K'' is K' + 1. build-abbreviation K F [infer-type N funclass|AL] K'' (fun N _ AbbrevFx) :- !, pi x\ build-abbreviation K {mk-app F [{{ lib:hb.Phantom (_ -> _) lp:x }}]} AL K' (AbbrevFx x), K'' is K' + 1. build-abbreviation K F [infer-type N (grefclass Class)|AL] K'' (fun N _ AbbrevFx) :- !, build-type-pattern Class Pat, pi x\ build-abbreviation K {mk-app F [{{ lib:hb.Phantom lp:Pat lp:x }}]} AL K' (AbbrevFx x), K'' is K' + 1. build-abbreviation K F [implicit|AL] K' FAbbrev :- !, build-abbreviation K {mk-app F [_]} AL K' FAbbrev. build-abbreviation K F [unify|AL] K' FAbbrev :- !, build-abbreviation K {mk-app F [{{lib:@hb.id _ _}}]} AL K' FAbbrev. % [build-type-pattern GR Pat] cheks that GR : forall x_1 ... x_n, Type % and returns Pat = GR _ ... _ (that is GR applied to n holes). % Note that n can be 0 when GR : Type. func build-type-pattern gref -> term. build-type-pattern GR Pat :- build-type-pattern.aux GR {coq.env.typeof GR} Pat. func build-type-pattern.aux gref, term -> term. build-type-pattern.aux GR T {{ lp:Pat _ }} :- coq.unify-eq T (prod N S T') ok, !, @pi-decl N S x\ build-type-pattern.aux GR (T' x) Pat. build-type-pattern.aux GR T (global GR) :- coq.unify-eq T {{ Type }} ok, !. build-type-pattern.aux _ _ _ :- coq.error "HB: wrong carrier type". % [mk-phant-term F PF] states that % if F = fun p1 .. p_k T m_0 .. m_n => _ % then PF = phant-term % [real p_1, ... real p_k, real T, implicit, .., implicit, % implicit, .., implicit, % implicit, unify, % implicit, unify, % implicit, .., implicit, unify, % unify, ..., unify, % ..., % implicit, .., implicit, % implicit, unify, % implicit, unify, % implicit, .., implicit, unify, % unify, ..., unify] % {{fun p_1 ... p_k T m_0 .. m_n => % fun q_1 .. q_l => % [find t | T ~ t] % [find s_0 | t ~ s_0] % [find c_0 | s_0 ~ SK q_1 .. q_l t c_0] % [find m'_{i_0_0}, .., m'_{i_0_n0} | c_0 ~ CK m'_{i_0_0} .. m'_{i_0_n0}] % fun & hb.unify m_{i_0_0} m'_{i_0_0} & ... & hb.unify m_{i_0_n0} m'_{i_0_n0} => % ... % fun q'_1 .. q'_l' => % [find t | T ~ t] % [find s_k | t ~ s_k] % [find c_k | s_k ~ SK q'_1 .. q'_l' y c_k] % [find m'_{i_k_0}, .., m'_{i_k_nk} | c_0 ~ CK m'_{i_k_0} .. m'_{i_k_nk}] % fun & hb.unify m_{i_0_0} m'_{i_0_0} & ... & hb.unify m_{i_k_nk} m'_{i_k_nk} => % F p_1 ... p_k T m_i0_j0 .. m_il_jl}} func mk-phant-term.mixins term, term, classname, phant-term, list term, name, term, (term -> list (w-args mixinname)) -> phant-term. mk-phant-term.mixins Target Src CN PF Params N Ty MLwA Out :- std.do! [ class-def (class CN SI _), mk-app (global SI) Params SIParams, coq.name-suffix N "local" Nlocal, (@pi-decl Nlocal Ty t\ sigma SK KC ML ParamsT SKPT\ std.do! [ std.map (MLwA t) triple_1 ML, std.append Params [t] ParamsT, SKPT = app [global {get-constructor SI} | ParamsT], ClassTy t = app [global CN | ParamsT], (@pi-decl `s` SIParams s\ @pi-decl `c` (ClassTy t) c\ sigma PF2\ std.do![ synthesis.under-mixins.then (MLwA t) (fun-unify-mixin Target) (mk-phant-term.mixins.aux t Params c CN PF) PF2, fun-unify none s {mk-app SKPT [c]} PF2 (PFU t s c), ]), Body t = {fun-unify none t Src {phant-fun-struct t `s` SI Params s\ {fun-implicit `c` (ClassTy t) (PFU t s)}}} ]), fun-implicit Nlocal Ty Body Out ]. mk-phant-term.mixins.aux T Params C CN PF X :- std.do![ get-constructor CN KC, synthesis.infer-all-gref->deps Params T KC KCM, fun-unify none KCM C PF X, ]. func mk-phant-term.class term, term, classname, phant-term -> phant-term. mk-phant-term.class Target Src CN PF CPF :- !, std.do! [ class-def (class CN _ CMLwP), w-params.fold CMLwP fun-implicit (mk-phant-term.mixins Target Src CN PF) CPF, ]. func mk-phant-term.classes term, list classname, list term, term, term, list (w-args mixinname) -> phant-term. mk-phant-term.classes EtaF CNF PL Target Src MLwA PhF :- !, std.do! [ std.map MLwA triple_1 ML, synthesis.under-mixins.then MLwA phant-fun-mixin (out\ sigma FPLTM\ std.do! [ synthesis.infer-all-these-mixin-args PL Target ML EtaF FPLTM, std.fold CNF (phant-term [] FPLTM) (mk-phant-term.class Target Src) out]) PhF ]. func mk-phant-term-with-copy term, list classname, list term, name, term, (term -> list (w-args mixinname)) -> phant-term. mk-phant-term-with-copy EtaF CNF PL N Ty MLwA PhF :- !, std.do! [ (@pi-decl N Ty target\ @pi-decl N Ty src\ sigma Body\ mk-phant-term.classes EtaF CNF PL target src (MLwA target) Body, fun-unify none target src Body (BodyUnif target src)), fun-real N Ty (target\ {fun-real N Ty (BodyUnif target)}) PhF ]. }} math-comp-hierarchy-builder-4d8a939/HB/common/stdpp.elpi000066400000000000000000000334731521677141400231560ustar00rootroot00000000000000/* Hierarchy Builder: algebraic hierarchies made easy This software is released under the terms of the MIT license */ % This file contains additions to elpi or coq-elpi standard library % elpi:if version < 2.0.0 kind triple type -> type -> type -> type. type triple A -> B -> C -> triple A B C. func triple_1 triple A B C -> A. triple_1 (triple A _ _) A. func triple_2 triple A B C -> B. triple_2 (triple _ B _) B. func triple_3 triple A B C -> C. triple_3 (triple _ _ C) C. % elpi:endif namespace std { func nlist int, A -> list A. nlist N X L :- std.map {std.iota N} (_\ y\ y = X) L. :index (_ 1) func list-diff list A, list A -> list A. list-diff X [] X. list-diff L [D|DS] R :- std.filter L (x\ not(x = D)) L1, list-diff L1 DS R. func list-uniq list A -> list A. pred list-uniq.seen i:A. list-uniq [] []. list-uniq [X|XS] YS :- list-uniq.seen X, !, list-uniq XS YS. list-uniq [X|XS] [X|YS] :- list-uniq.seen X => list-uniq XS YS. func list-eq-set list A, list A. list-eq-set L1 L2 :- list-diff L1 L2 [], list-diff L2 L1 []. pred under.do! i:((A -> prop) -> A -> prop), i:list prop. under.do! Then LP :- Then (_\ std.do! LP) _. func map-triple (func A -> A1), (func B -> B1), (func C -> C1), triple A B C -> triple A1 B1 C1. map-triple F G H (triple X Y Z) (triple X1 Y1 Z1) :- F X X1, G Y Y1, H Z Z1. func sort.split list A -> list A, list A. sort.split [] [] [] :- !. sort.split [X] [X] [] :- !. sort.split [X,Y|TL] [X|L1] [Y|L2] :- sort.split TL L1 L2. % sort.merge can take a relation but keeps only the first solution returned. % There is a cut after the call to `Rel X1 X2`. func sort.merge (pred i:A, i:A), list A, list A -> list A. sort.merge _ [] L L :- !. sort.merge _ L [] L :- !. sort.merge Rel [X1|L1] [X2|L2] [X1|M] :- Rel X1 X2, !, sort.merge Rel L1 [X2|L2] M. sort.merge Rel [X1|L1] [X2|L2] [X2|M] :- sort.merge Rel [X1|L1] L2 M. :index(1) func sort list A, (pred i:A, i:A) -> list A. sort [] _ [] :- !. sort [X] _ [X] :- !. sort L Rel M :- sort.split L L1 L2, sort L1 Rel S1, sort L2 Rel S2, sort.merge Rel S1 S2 M. func bubblesort list A, (pred i:A, i:A) -> list A. bubblesort [] _ [] :- !. bubblesort [X] _ [X] :- !. bubblesort [X,Y|TL] Rel [X|Rest1] :- Rel X Y, !, bubblesort [Y|TL] Rel Rest1. bubblesort [X,Y|TL] Rel [Y|Rest1] :- bubblesort [X|TL] Rel Rest1. % TODO: pred toposort i:(A -> A -> prop), i:list A, o:list A. % pred edge? i:int, i:int. % toposort edge? [1,2,3,4] TopoList func topovisit list (pair A A), A, list A, list A -> list A, list A. topovisit _ X VS PS VS PS :- std.mem PS X, !. topovisit _ X VS _ _ _ :- std.mem VS X, !, halt "cycle detected.". topovisit ES X VS PS VS' [X|PS'] :- toporec ES {std.map {std.filter ES (e\ fst e X)} snd} [X|VS] PS VS' PS'. func toporec list (pair A A), list A, list A, list A -> list A, list A. toporec _ [] VS PS VS PS. toporec ES [X|XS] VS PS VS'' PS'' :- topovisit ES X VS PS VS' PS', toporec ES XS VS' PS' VS'' PS''. func toposort list (pair A A), list A -> list A. toposort ES XS XS'' :- toporec ES XS [] [] _ XS', % @gares: meme!, instead of mem std.filter XS' (std.mem! XS) XS''. namespace gref { func topovisit coq.gref.map coq.gref.set, classname, coq.gref.set, list classname, coq.gref.set -> coq.gref.set, list classname, coq.gref.set. topovisit _ X VS PS PSS VS PS PSS :- coq.gref.set.mem X PSS, !. topovisit _ X VS _ _ _ _ _ :- coq.gref.set.mem X VS, !, halt "cycle detected.". topovisit ES X VS PS PSS VS' [X|PS'] PSS'' :- std.once (coq.gref.map.find X ES M ; coq.gref.set.empty M), toporec ES {coq.gref.set.elements M} {coq.gref.set.add X VS} PS PSS VS' PS' PSS', coq.gref.set.add X PSS' PSS''. :index (_ 1) func toporec coq.gref.map coq.gref.set, list classname, coq.gref.set, list classname, coq.gref.set -> coq.gref.set, list classname, coq.gref.set. toporec _ [] VS PS PSS VS PS PSS. toporec ES [X|XS] VS PS PSS VS'' PS'' PSS'' :- topovisit ES X VS PS PSS VS' PS' PSS', toporec ES XS VS' PS' PSS' VS'' PS'' PSS''. :index (1) func add-to-neighbours coq.gref.set, pair gref gref, coq.gref.map coq.gref.set -> coq.gref.map coq.gref.set. add-to-neighbours VS (pr _ V) A A :- not(coq.gref.set.mem V VS), !. add-to-neighbours _ (pr K V) A A1 :- coq.gref.map.find K A L, !, coq.gref.map.add K {coq.gref.set.add V L} A A1. add-to-neighbours _ (pr K V) A A1 :- coq.gref.map.add K {coq.gref.set.add V {coq.gref.set.empty} } A A1. :index(1) func toposort list (pair gref gref), list gref -> list gref. toposort ES XS XS'' :- !, std.fold XS {coq.gref.set.empty} coq.gref.set.add VS, std.fold ES {coq.gref.map.empty} (add-to-neighbours VS) EM, toporec EM XS {coq.gref.set.empty} [] {coq.gref.set.empty} _ XS'' _ . } func time-do! list prop ->. time-do! []. time-do! [P|PS] :- std.time P Time, !, if (constant P C _) true (C = P), coq.say Time ">>" C, time-do! PS. } namespace compat { % TODO: replace with std.map-filter when coq-elpi > 1.9.2 :index (1) func map-filter list A, (A -> B -> prop) -> list B. map-filter [] _ []. map-filter [X|XS] F [Y|YS] :- F X Y, !, map-filter XS F YS. map-filter [_|XS] F YS :- map-filter XS F YS. } func print-ctx. print-ctx :- declare_constraint print-ctx []. constraint print-ctx mixin-src { rule \ (G ?- print-ctx) | (coq.say "The context is:" G). } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% func coq.term-is-gref? term -> gref. coq.term-is-gref? (global GR) GR. coq.term-is-gref? (pglobal GR _) GR. coq.term-is-gref? (app [Hd|_]) GR :- coq.term-is-gref? Hd GR. coq.term-is-gref? (let _ _ T x\x) GR :- coq.term-is-gref? T GR. func coq.prod-tgt->gref term -> gref. coq.prod-tgt->gref T GR :- whd1 T T1, !, coq.prod-tgt->gref T1 GR. coq.prod-tgt->gref (prod N Src Tgt) GR :- !, @pi-decl N Src x\ coq.prod-tgt->gref (Tgt x) GR. coq.prod-tgt->gref End GR :- coq.term->gref End GR. % TODO: move to coq-elpi proper / move to coq.pp in coq-elpi >= 1.9 :index(1) func coq.indt-decl->string indt-decl -> string. coq.indt-decl->string (parameter ID _ Ty D) S :- coq.id->name ID Name, (@pi-decl Name Ty x\ coq.indt-decl->string (D x) S1), S is "Parameter" ^ ID ^ " : " ^ {coq.term->string Ty} ^ "\n" ^ S1. coq.indt-decl->string (inductive _ _ _ _) "NYI". coq.indt-decl->string (record ID Ty KID RD) S :- coq.record-decl->string RD S1, S is ID ^ " : " ^ {coq.term->string Ty} ^ " := " ^ KID ^ " {\n" ^ S1 ^ "}". :index(1) func coq.record-decl->string record-decl -> string. coq.record-decl->string end-record "". coq.record-decl->string (field _ ID Ty D) S :- coq.id->name ID Name, (@pi-decl Name Ty x\ coq.record-decl->string (D x) S1), S is " " ^ ID ^ " : " ^ {coq.term->string Ty} ^ ";\n" ^ S1. :index(1) func coq.ground-indt-decl? indt-decl ->. coq.ground-indt-decl? (parameter ID _ Ty D) :- ground_term Ty, coq.id->name ID Name, (@pi-decl Name Ty x\ coq.ground-indt-decl? (D x)). coq.ground-indt-decl? (inductive _ _ _ _). coq.ground-indt-decl? (record _ Ty _ RD) :- ground_term Ty, coq.ground-record-decl? RD. :index(1) func coq.ground-record-decl? record-decl ->. coq.ground-record-decl? end-record. coq.ground-record-decl? (field _ ID Ty D) :- ground_term Ty, coq.id->name ID Name, (@pi-decl Name Ty x\ coq.ground-record-decl? (D x)). % TODO: remove when coq-elpi > 1.9.3 % func copy-indt-decl indt-decl -> indt-decl. % copy-indt-decl (parameter ID I Ty D) (parameter ID I Ty1 D1) :- % copy Ty Ty1, % @pi-parameter ID Ty1 x\ copy-indt-decl (D x) (D1 x). % copy-indt-decl (inductive ID CO A D) (inductive ID CO A1 D1) :- % copy-arity A A1, % coq.id->name ID N, coq.arity->term A1 T, @pi-decl N T i\ std.map (D i) copy-constructor (D1 i). % % @pi-inductive ID A1 i\ std.map (D i) copy-constructor (D1 i). % requires Coq-Elpi 1.9.x % copy-indt-decl (record ID T IDK F) (record ID T1 IDK F1) :- % copy T T1, % copy-fields F F1. % func copy-fields record-decl -> record-decl. % copy-fields end-record end-record. % copy-fields (field Att ID T F) (field Att ID T1 F1) :- % copy T T1, % @pi-parameter ID T1 x\ copy-fields (F x) (F1 x). % func copy-constructor indc-decl -> indc-decl. % copy-constructor (constructor ID A) (constructor ID A1) :- copy-arity A A1. % TODO: move to coq-elpi proper func coq.gref.list->set list gref -> coq.gref.set. coq.gref.list->set L S :- std.fold L {coq.gref.set.empty} coq.gref.set.add S. % [coq.abstract-indt-decl Section I AbsI] abstracts I over the Section variables % which becomes parameter nodes of the indt-decl type :index(1) func coq.abstract-indt-decl list constant, indt-decl -> indt-decl. coq.abstract-indt-decl [] X X1 :- copy-indt-decl X X1. coq.abstract-indt-decl [C|CS] X (parameter ID explicit Ty1 X1) :- coq.gref->id (const C) ID, coq.env.typeof (const C) Ty, copy Ty Ty1, @pi-parameter ID Ty x\ (copy (global (const C)) x :- !) => coq.abstract-indt-decl CS X (X1 x). % [coq.abstract-const-decl Section I AbsI] abstracts I over the Section variables % which becomes fun nodes :index (1) func coq.abstract-const-decl list constant, pair term term -> pair term term. coq.abstract-const-decl [] (pr X Y) (pr X1 Y1) :- copy X X1, copy Y Y1. coq.abstract-const-decl [C|CS] X (pr (fun Name Ty1 X1) (prod Name Ty1 X2)) :- coq.gref->id (const C) ID, coq.id->name ID Name, coq.env.typeof (const C) Ty, copy Ty Ty1, @pi-parameter ID Ty x\ (copy (global (const C)) x :- !) => coq.abstract-const-decl CS X (pr (X1 x) (X2 x)). % [coq.copy-clauses-for-unfold CS CL] generates clauses for the copy predicate % to unfold all constants in CS :index(1) func coq.copy-clauses-for-unfold list constant -> list prop. coq.copy-clauses-for-unfold [] []. coq.copy-clauses-for-unfold [C|CS] [ClauseApp,Clause|L] :- coq.env.const C (some B) _, ClauseApp = (pi B1 Args Args1 B2 Args2 R\ copy (app[global (const C)|Args]) R :- !, copy B B1, std.map Args copy Args1, hd-beta B1 Args1 B2 Args2, unwind B2 Args2 R), Clause = (pi B1\ copy (global (const C)) B1 :- !, copy B B1), coq.copy-clauses-for-unfold CS L. % like fold-map, needed for coq-elpi < 1.9 func coq.fold-map term, A -> term, A. coq.fold-map X A Y A :- name X, !, X = Y, !. % avoid loading "coq.fold-map x A x A" at binders coq.fold-map (global _ as C) A C A :- !. coq.fold-map (sort _ as C) A C A :- !. coq.fold-map (fun N T F) A (fun N T1 F1) A2 :- !, coq.fold-map T A T1 A1, pi x\ coq.fold-map (F x) A1 (F1 x) A2. coq.fold-map (let N T B F) A (let N T1 B1 F1) A3 :- !, coq.fold-map T A T1 A1, coq.fold-map B A1 B1 A2, pi x\ coq.fold-map (F x) A2 (F1 x) A3. coq.fold-map (prod N T F) A (prod N T1 F1) A2 :- !, coq.fold-map T A T1 A1, (pi x\ coq.fold-map (F x) A1 (F1 x) A2). coq.fold-map (app L) A (app L1) A1 :- !, std.fold-map L A coq.fold-map L1 A1. coq.fold-map (fix N Rno Ty F) A (fix N Rno Ty1 F1) A2 :- !, coq.fold-map Ty A Ty1 A1, pi x\ coq.fold-map (F x) A1 (F1 x) A2. coq.fold-map (match T Rty B) A (match T1 Rty1 B1) A3 :- !, coq.fold-map T A T1 A1, coq.fold-map Rty A1 Rty1 A2, std.fold-map B A2 coq.fold-map B1 A3. coq.fold-map (primitive _ as C) A C A :- !. coq.fold-map (uvar M L as X) A W A1 :- var X, !, std.fold-map L A coq.fold-map L1 A1, coq.mk-app-uvar M L1 W. % when used in CHR rules coq.fold-map (uvar X L) A (uvar X L1) A1 :- std.fold-map L A coq.fold-map L1 A1. func cs-pattern->term cs-pattern -> term. cs-pattern->term (cs-gref GR) T :- coq.env.global GR T. cs-pattern->term (cs-sort prop) (sort prop) :- !. cs-pattern->term (cs-sort sprop) (sort sprop) :- !. cs-pattern->term (cs-sort _) T :- coq.elaborate-skeleton {{ Type }} _ T ok. cs-pattern->term cs-prod T :- coq.elaborate-skeleton (prod `x` Ty_ x\ Bo_ x) _ T ok. func term->cs-pattern term -> cs-pattern. term->cs-pattern (prod _ _ _) cs-prod :- !. term->cs-pattern (sort U) (cs-sort U) :- !. term->cs-pattern T (cs-gref GR) :- coq.term->gref T GR, !. term->cs-pattern T _ :- coq.error T "HB database: is not a valid canonical key". % --------------------------------------------------------------------- % kit for closing a term by abstracting evars with lambdas % we use constraints to attach to holes a number % and replace them by a special node, to later be bound % via a lambda namespace abstract-holes { % we add a new constructor to terms to represent terms to be abstracted type abs int -> term. % bind back abstracted subterms func bind int, int, term -> term. bind I M T T1 :- M > I, !, T1 = {{ fun x => lp:(B x) }}, N is I + 1, pi x\ % we allocate the fresh symbol for (abs M) (copy (abs N) x :- !) => % we schedule the replacement (abs M) -> x bind N M T (B x). bind M M T T1 :- copy T T1. % we perform all the replacements % for a term with M holes, returns a term with M variables to fill these holes % the clause see is only generated for a term if it hasn't been seen before % the term might need to be typechecked first or main generates extra holes for the % type of the parameters func main term -> term. main T1 T3 :- std.do! [ % we put (abs N) in place of each occurrence of the same hole (pi T Ty N N' M \ fold-map T N (abs M) M :- var T, not (seen? T _), !, coq.typecheck T Ty ok, fold-map Ty N _ N', M is N' + 1, seen! T M) => (pi T N M \ fold-map T N (abs M) N :- var T, seen? T M, !) => fold-map T1 0 T2 M, % we abstract M holes (M abs nodes) bind 0 M T2 T3, % cleanup constraint store purge-seen!, ]. % all constraints are also on _ so that they share % a variable with the constraint to purge the store % we query if the hole was seen before, and if so % we fetch its number func seen? term -> int. seen? X Y :- declare_constraint (seen? X Y) [X,_]. % we declare it is now seen and label it with a number func seen! term, int ->. seen! X Y :- declare_constraint (seen! X Y) [X,_]. % to empty the store func purge-seen!. purge-seen! :- declare_constraint purge-seen! [_]. constraint seen? seen! purge-seen! { % a succesful query, give the label back via M rule (seen! X N) \ (seen? X M) <=> (M = N). % an unsuccesful query rule \ (seen? X _) <=> false. rule purge-seen! \ (seen! _ _). rule \ purge-seen!. } }math-comp-hierarchy-builder-4d8a939/HB/common/synthesis.elpi000066400000000000000000000337161521677141400240550ustar00rootroot00000000000000/* Hierarchy Builder: algebraic hierarchies made easy This software is released under the terms of the MIT license */ % This file implements a simple form of "type inference" for arguments which % are mixins and can be inferred looking at the \lambda Prolog context, in % particular [mixins-src] context entries (the one of Coq looks at CS databases % and such, which cannot be easily manipulated on the fly). % % If provides function to infer this kind of arguments and to declare a context % made of mixins to be used for such inference. The idea is that one has % a bunch of mixins at hand and does want to pass them down to other terms, % without explictly saying exactly where they should be used. namespace synthesis { % [infer-all-these-mixin-args Ps T ML F X] fills in all the arguments of F % which are misxins in ML, abstracts the others func infer-all-these-mixin-args list term, term, list mixinname, term -> term. infer-all-these-mixin-args Ps T ML F SFX :- std.do! [ std.assert-ok! (coq.typecheck F Ty) "try-infer-these-mixin-args: F illtyped", coq.mk-eta (-1) Ty F EtaF, coq.subst-fun {std.append Ps [T]} EtaF FT, private.instantiate-all-these-mixin-args FT T ML SFX, ]. % [infer-all-gref->deps Ps T GR X] fills in all the arguments of GR % which are misxins in gref->deps GR, other arguments are abstracted func infer-all-gref->deps list term, term, gref -> term. infer-all-gref->deps Ps T GR X :- std.do! [ std.assert! (gref->deps GR MLwP) "BUG: gref->deps should never fail", list-w-params_list MLwP ML, coq.env.typeof GR Ty, coq.mk-eta (-1) Ty (global GR) EtaF, coq.subst-fun {std.append Ps [T]} EtaF FT, private.instantiate-all-these-mixin-args FT T ML Xraw, infer-holes-depending-on-params T Xraw X, ]. % [infer-holes-depending-on-params TheType T NewT] func infer-holes-depending-on-params term, term -> term. infer-holes-depending-on-params T (app [global GR|Args]) (app [global GR|Args1]) :- !, std.map Args (infer-holes-depending-on-pack T) Args1. infer-holes-depending-on-params _ X X. func class-of-phant term -> gref, gref, gref. class-of-phant (prod N T F) X Y Z :- @pi-decl N T x\ class-of-phant (F x) X Y Z. class-of-phant (global GR) Y Z X :- class-def (class X GR _), !, get-constructor X Y, get-constructor GR Z. class-of-phant (app[global GR|_]) Y Z X :- class-def (class X GR _), !, get-constructor X Y, get-constructor GR Z. func infer-holes-depending-on-pack term, term -> term. infer-holes-depending-on-pack T (app [global GR | Args]) S :- ((coq.gref->id GR GRS, rex.match "phant.*" GRS /*TODO: phant-clone? GR N*/); pack? GR _), coq.env.typeof GR Ty, class-of-phant Ty KC SC C, factory->nparams C N, std.take N Args Params, !, std.do! [ infer-all-args-let Params T KC ClassInstance ok, std.rev [ClassInstance,T|{std.rev Params}] NewArgs, S = app[global SC| NewArgs ] ]. infer-holes-depending-on-pack _ X X. % [infer-all-args-let Ps T GR X Diagnostic] fills in all the Args in % app[global GR, Ps, T | Args] % and generates a term % let `a1` ty1 t1 a1\ .... app[global GR, p1, .. pn, T, a1, .. , an] % if Diagnostic is ok, else X is unassigned func infer-all-args-let list term, term, gref -> term, diagnostic. infer-all-args-let Ps T GR X Diag :- std.do! [ coq.env.typeof GR Ty, coq.mk-eta (-1) Ty (global GR) EtaF, coq.subst-fun {std.append Ps [T]} EtaF FT, private.instantiate-all-args-let FT T X Diag, ]. % [assert!-infer-mixin TheType M Out] infers one mixin M on TheType and % aborts with an error message if the mixin cannot be inferred func assert!-infer-mixin term, mixinname -> term. assert!-infer-mixin T M B :- if (private.mixin-for T M B) true (coq.error "HB: cannot inhabit mixin" {nice-gref->string M} "on"{coq.term->string T}). % Given TheType it looks all canonical structure instances on it and makes % all their mixins available for inference :index (_ 1) func local-canonical-mixins-of.aux term, list structure -> list prop. local-canonical-mixins-of.aux _ [] []. local-canonical-mixins-of.aux T [S|Ss] MSL'' :- std.do! [ private.structure-instance->mixin-srcs T S MSL, MSL => local-canonical-mixins-of.aux T Ss MSL', std.append MSL MSL' MSL'', ]. func local-canonical-mixins-of term -> list prop. local-canonical-mixins-of T MSL :- std.do! [ get-canonical-structures T CS, std.map CS (s\c\ sigma w\ class-def (class c s w)) Cl, toposort-classes Cl ClSorted, std.map ClSorted (c\s\ sigma w\ class-def (class c s w)) CSSorted, local-canonical-mixins-of.aux T CSSorted MSL, ]. % Given TheType and a factory instance (on it), makes all the mixins provided by % the factory available for inference. func under-mixin-src-from-factory.do! term, term, list prop. under-mixin-src-from-factory.do! TheType TheFactory LP :- private.factory-instance->new-mixins [] TheFactory ML, std.map ML (m\c\ c = mixin-src TheType m TheFactory) MLClauses, MLClauses => std.do! LP. % Given TheType and a factory instance (on it), builds all the *new* mixins % provided by the factory available for and passes them to the given % continuation func under-new-mixin-src-from-factory.do! term, term, (list mixinname -> prop). under-new-mixin-src-from-factory.do! TheType TheFactory LP :- findall-mixin-src TheType OldMixins, private.factory-instance->new-mixins OldMixins TheFactory NewML, std.map NewML (m\c\ c = mixin-src TheType m TheFactory) NewMLClauses, NewMLClauses => std.once (LP NewML). % [under-mixins.then MLwP Pred F] states that F has shape % fun p_1 .. p_k T, % (m_0 : M_0 ..p.. T) .. (m_n : M_n ..p.. T m_i0 .. m_ik) => % Body m_0 .. m_n % where MLwP contains M_0, .., M_n (under p_1 .. p_k) % and Body is such that [..,mixin-src T M_i m_i,..] => Pred Body % and ..p.. is a list of terms built using p_1 .. p_k and T func under-mixins.then list (w-args mixinname), (pred i:name, i:term, i:(term -> A), o:A), (func A -> ) -> A. under-mixins.then [] _ Pred Body :- !, Pred Body. under-mixins.then [triple M Args T|ML] MkFun Pred Out :- std.do! [ infer-all-gref->deps Args T M MTy, (@pi-decl `m` MTy m\ mixin-src T M m => under-mixins.then ML MkFun Pred (Body m)), MkFun `m` MTy Body Out, ]. % [mixins-w-params.fun MLwP Pred F] states that F has shape % fun p_1 .. p_k T, % (m_0 : M_0 ..p.. T) .. (m_n : M_n ..p.. T m_i0 .. m_ik) => % Body m_0 .. m_n % where MLwP contains M_0, .., M_n (under p_1 .. p_k) % and Body is such that [..,mixin-src T M_i m_i,..] => Pred Body % and ..p.. is a list of terms built using p_1 .. p_k and T func mixins-w-params.fun mixins, (func list term, term -> term) -> term. mixins-w-params.fun L P Out :- !, w-params.then L mk-fun mk-fun (p\ t\ ml\ under-mixins.then ml mk-fun (P p t)) Out. % [mixins-w-params.length LwP N] states N is Nmixins+Nparams func mixins-w-params.length mixins -> int. mixins-w-params.length MLwP N :- w-params.nparams MLwP Nparams, std.length {list-w-params_list MLwP} Nmixins, N is Nparams + Nmixins. func infer-coercion-tgt mixins -> class. infer-coercion-tgt (w-params.cons ID Ty F) CoeClass :- @pi-parameter ID Ty x\ infer-coercion-tgt (F x) CoeClass. infer-coercion-tgt (w-params.nil _ {{ Type }} _) sortclass :- !. infer-coercion-tgt (w-params.nil _ {{ forall x, _ }} _) funclass :- !. % do not use {{ _ -> _ }} since Funclass can be a dependent function! infer-coercion-tgt (w-params.nil _ T _) (grefclass GR) :- coq.term->gref T GR. :index (_ _ 2) func w-args.check-key list term, term, list (w-args A) -> prop. w-args.check-key _PS _T [] true :- !. w-args.check-key PS T [triple _ _ T|LwA] P :- !, w-args.check-key PS T LwA P. w-args.check-key _PS _T _LwA false :- !, coq.error "HB: all mixins must have the same key". func list-w-params.check-key list-w-params A ->. list-w-params.check-key MLwP :- !, w-params.then MLwP ignore ignore w-args.check-key _. /* ------------------------------------------------------------------------- */ /* ----------------------------- private code ------------------------------ */ /* ------------------------------------------------------------------------- */ namespace private { % [mixin-for T M MI] synthesizes an instance of mixin M on type T using % the databases [mixin-src] and [from] func mixin-for term, mixinname -> term. mixin-for T M MICompressed :- mixin-src T M Tm, !, %if-verbose (coq.say {header} "Trying to infer mixin for" M), std.assert-ok! (coq.typecheck Tm Ty) "mixin-for: Tm illtyped", %%%%% mterm %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% factory? Ty (triple Factory Params _), if (M = Factory) (MI = Tm) ( private.builder->term Params T Factory M B, coq.subst-fun [Tm] B MI ), %if-verbose (coq.say {header} "Trying to compress mixin for" {coq.term->string MI}), compress-coercion-paths MI MICompressed. func drop int, list A -> list A. drop 0 L L :- !. drop N [_|XS] L :- !, N1 is N - 1, drop N1 XS L. func compress-copy -> term, term. compress-copy (app [global (const C) | L]) R :- sub-class C2 C3 C NparamsC, drop NparamsC L [app [global (const C') | L']], sub-class C1 C2 C' NparamsC', drop NparamsC' L' L'', sub-class C1 C3 C'' NparamsC'', std.append {coq.mk-n-holes NparamsC''} L'' HL'', CHL'' = app [global (const C'') | HL''], coq.typecheck CHL'' _ ok, !, compress-copy CHL'' R. compress-copy (app L) (app L1) :- !, std.map L compress-copy L1. compress-copy X X. func compress-coercion-paths term -> term. compress-coercion-paths MI MICompressed :- if (get-option "compress_coercions" tt) (compress-copy MI MICompressed) (MI = MICompressed). func mixin-for_mixin-builder prop -> term. mixin-for_mixin-builder (mixin-for _ _ B) B. % [builder->term Params TheType Src Tgt MF] finds a builder from Src to Tgt % and fills in all the mixins required by the builder using mixin-src, obtaining % a function (MF = Builder Params TheType InferredStuff : Src -> Tgt) func builder->term list term, term, factoryname, mixinname -> term. builder->term Ps T Src Tgt B :- !, std.do! [ from Src Tgt FGR, F = global FGR, gref->deps Src MLwP, list-w-params_list MLwP ML, infer-all-these-mixin-args Ps T ML F B, ]. % [instantiate-all-these-mixin-args T F M_i TFX] where mixin-for T M_i X_i states that % if F ~ fun xs (m_0 : M_0 T) .. (m_n : M_n T ..) ys % => F xs m_0 .. m_{i-1} m_i m_{i+1} .. m_n ys % then TFX := fun xs m_0 .. m_{i-1} m_{i+1} .. m_n ys % => F xs m_0 .. m_{i-1} X_i m_{i+1} .. m_n ys % thus instanciating an abstraction on mixin M_i with X_i func instantiate-all-these-mixin-args term, term, list mixinname -> term. instantiate-all-these-mixin-args (fun _ Tm F) T ML R :- coq.safe-dest-app Tm (global TmGR) _, factory-alias->gref TmGR M ok, std.mem! ML M, !, if (mixin-for T M X) true (coq.error "HB: Unable to find mixin" {nice-gref->string M} "on subject" {coq.term->string T}), !, instantiate-all-these-mixin-args (F X) T ML R. instantiate-all-these-mixin-args (fun N Ty F) T ML (fun N Ty FX) :- !, @pi-decl N Ty m\ instantiate-all-these-mixin-args (F m) T ML (FX m). instantiate-all-these-mixin-args F _ _ F. func instantiate-all-args-let term, term -> term, diagnostic. instantiate-all-args-let (fun N Tm F) T (let N Tm X R) Diag :- !, std.do! [ coq.safe-dest-app Tm (global TmGR) _, factory-alias->gref TmGR M ok, if (mixin-for T M X) (@pi-def N Tm X m\ instantiate-all-args-let (F m) T (R m) Diag) (Diag = error Msg, Msg is "cannot synthesize mixin " ^ {nice-gref->string M} ^ " for " ^ {coq.term->string T}), ]. instantiate-all-args-let F _ F ok. % [structure-instance->mixin-srcs TheType Structure] finds a CS instance for % Structure on TheType (if any) and builds mixin-src clauses for all the mixins % which can be candidates from that class instance. It finds instances which are % concrete, that is not by projecting a rich type (a variable) to its class. pred structure-instance->mixin-srcs i:term, i:structure, o:list prop. structure-instance->mixin-srcs T S MSLC :- std.do! [ structure-key SortProj _ S, class-def (class (indt Class) S CMLwP), structure-nparams S NParams, coq.mk-n-holes NParams Holes, std.append Holes [ST] HolesST, coq.mk-app (global (const SortProj)) HolesST SortHolesST, % find an instance in ST coq.unify-eq T SortHolesST ok, % we look for an instance which is concrete, we take the parts get-constructor S KS, coq.mk-app (global KS) {std.append Holes [T, CT]} KSHolesC, coq.unify-eq ST KSHolesC ok, % if the class instance is concrete, we take the parts get-constructor (indt Class) KC, std.length {list-w-params_list CMLwP} CMixinsN, coq.mk-n-holes CMixinsN MIL, coq.mk-app (global KC) {std.append Holes [T | MIL]} CBody, coq.unify-eq CT CBody ok, % we finally generare micin-src clauses for all mixins std.map MIL (structure-instance->mixin-srcs.aux T) MSLL, std.flatten MSLL MSLC, ]. % this catch all sucks a bit, but is very relevant. Some instance, like % unification hints (canonical coercions) which require a type which is too rich % fail the second unif problem structure-instance->mixin-srcs _ _ []. structure-instance->mixin-srcs.aux2 Params T Class (some P) M :- coq.mk-app (global (const P)) {std.append Params [T,Class]} M. func structure-instance->mixin-srcs.aux term, term -> list prop. structure-instance->mixin-srcs.aux T F CL :- factory-instance->new-mixins [] F ML, std.map-filter ML (m\c\ not (mixin-src T m _), c = mixin-src T m F) CL. % [factory-instance->new-mixins OldMixins FI MSL] find all the mixins % which can be generated by the factory instance FI which are not part of % OldMixins (that is, the contribution of FI to the current context) func factory-instance->new-mixins list mixinname, term -> list mixinname. factory-instance->new-mixins OldMixins X NewML :- std.assert-ok! (coq.typecheck X XTy) "mixin-src: X illtyped", if (not (coq.safe-dest-app XTy (global _) _)) (coq.error "Term:\n" {coq.term->string X} "\nhas type:\n" {coq.term->string XTy} "\nwhich is not a record") true, coq.term->gref XTy Src, factory-provides Src MLwP, list-w-params_list MLwP ML, std.filter ML (m\ not(std.mem! OldMixins m)) NewML. }} math-comp-hierarchy-builder-4d8a939/HB/common/utils-synterp.elpi000066400000000000000000000046601521677141400246620ustar00rootroot00000000000000/* Hierarchy Builder: algebraic hierarchies made easy This software is released under the terms of the MIT license */ % runs P in a context where Coq #[attributes] are parsed func with-attributes (func). with-attributes P :- attributes A, coq.parse-attributes A [ att "verbose" bool, att "mathcomp" bool, att "mathcomp.axiom" string, att "short.type" string, att "short.pack" string, att "key" string, att "arg_sort" bool, att "log" bool, att "log.raw" bool, att "compress_coercions" bool, att "export" bool, att "skip" string, att "local" bool, att "fail" bool, att "doc" string, att "primitive" bool, att "non_forgetful_inheritance" bool, att "hnf" bool, ] Opts, !, Opts => (save-docstring, P). func if-verbose (func) -> . if-verbose P :- get-option "verbose" tt, !, P. if-verbose _. % header of if-verbose messages func header -> string. header Msg :- Msg is "[" ^ {std.any->string {gettimeofday}} ^ "] HB: ". % approximation, it should be logical path, not the file name func coq.env.current-library -> string. coq.env.current-library L :- loc.fields {get-option "elpi.loc"} L _ _ _ _, !. coq.env.current-library "dummy.v". % this is only declared in hb.db, this declaration is only to avoid a warning pred docstring o:loc, o:string. func save-docstring. save-docstring :- if (get-option "elpi.loc" Loc, get-option "elpi.phase" "interp", get-option "doc" Txt) (coq.elpi.accumulate _ "hb.db" (clause _ _ (docstring Loc Txt))) true. func compute-filter option string -> list string. compute-filter none []. compute-filter (some S) MFilter :- % S is a component of the current modpath coq.env.current-path P, rex_split "\\." S L, compute-filter.aux P L MFilter, !. compute-filter (some S) MFilter :- coq.locate-module S M, coq.modpath->path M MFilter. func compute-filter.aux list string, list string -> list string. compute-filter.aux [S|_] [S] [S] :- !. compute-filter.aux [S|XS] [S|SS] [S|YS] :- !, compute-filter.aux XS SS YS. compute-filter.aux [X|XS] L [X|YS] :- compute-filter.aux XS L YS. func list-uniq list A -> list A. pred list-uniq.seen i:A. list-uniq [] []. list-uniq [X|XS] YS :- list-uniq.seen X, !, list-uniq XS YS. list-uniq [X|XS] [X|YS] :- list-uniq.seen X => list-uniq XS YS. func record-decl->id indt-decl -> id. record-decl->id (parameter _ _ _ D) N :- pi p\ record-decl->id (D p) N. record-decl->id (record N _ _ _) N. math-comp-hierarchy-builder-4d8a939/HB/common/utils.elpi000066400000000000000000000340761521677141400231640ustar00rootroot00000000000000/* Hierarchy Builder: algebraic hierarchies made easy This software is released under the terms of the MIT license */ % This file contains some HB specific utilities accumulate HB/common/utils-synterp. shorten coq.{ term->gref, subst-fun, safe-dest-app, mk-app, mk-eta, subst-prod }. func if-arg-sort (func) ->. if-arg-sort P :- get-option "arg_sort" tt, !, P. if-arg-sort _. func if-MC-compat (func option gref ->) ->. if-MC-compat P :- get-option "mathcomp" tt, !, P none. if-MC-compat P :- get-option "mathcomp.axiom" S, !, std.assert! (coq.locate S GR) "The name passed to the mathcomp.axiom attribute does not exist", P (some GR). if-MC-compat _. func with-locality (func) ->. with-locality P :- if (get-option "local" tt) (A = @local!) (A = @global!), A => P. func acc-clause scope, prop. acc-clause Scope C :- coq.elpi.accumulate Scope "hb.db" (clause _ _ C). /* Uncomment and remove HB/common/compat_acc_clauses_*.elpi once requiring coq-elpi >= 1.18.0, which implies Coq >= 8.17 pred acc-clauses i:scope, i:list prop. acc-clauses Scope CL :- coq.elpi.accumulate-clauses Scope "hb.db" {std.map CL (c\r\ r = clause _ _ c)}. */ % TODO: Should this only be used for gref that are factories? (and check in the first/second branch so?) % Should we make this an HO predicate, eg "located->gref S L is-factory? GR" % TODO: rename since this is HB specific and is expected to return a factory :index (_ 2) func located->gref string, list located -> gref. located->gref _ [loc-gref GR|_] GR. located->gref _ [loc-abbreviation Abbrev|_] GR :- phant-abbrev GR _ Abbrev, !. located->gref S [loc-abbreviation _|_] _ :- coq.error S "is an abbreviation out of the control of HB". located->gref S [loc-modpath _|_] _ :- coq.error S "should be a factory, but is a module". located->gref S [loc-modtypath _|_] _ :- coq.error S "should be a factory, but is a module type". located->gref S [] _ :- coq.error "Could not locate name" S. % TODO: generalize/rename when we support parameters func argument->gref argument -> gref. argument->gref (str S) GR :- !, located->gref S {coq.locate-all S} GR. argument->gref X _ :- coq.error "Argument" X "is expected to be a string". func argument->term argument -> term. argument->term (str S) (global GR) :- !, argument->gref (str S) GR. argument->term (trm T) T1 :- !, std.assert-ok! (coq.elaborate-skeleton T _ T1) "not well typed term". argument->term X _ :- coq.error "Argument" X " is expected to be a term or a string". func argument->ty argument -> term. argument->ty (str S) T1 :- !, argument->gref (str S) GR, std.assert-ok! (coq.elaborate-ty-skeleton (global GR) _ T1) "global reference is not a type". argument->ty (trm T) T1 :- !, std.assert-ok! (coq.elaborate-ty-skeleton T _ T1) "not well typed type". argument->ty X _ :- coq.error "Argument" X " is expected to be a type or a string". func builder->string builder -> string. builder->string (builder _ _ _ B) S :- coq.term->string (global B) S. func nice-gref->string gref -> string. nice-gref->string X Mod :- coq.gref->path X Path, std.rev Path [Mod1,Mod2|_], !, Mod is Mod2 ^ "_" ^ Mod1. nice-gref->string X S :- coq.term->string (global X) S. func gref->modname gref, int, string -> string. gref->modname GR NComp Sep ModName :- coq.gref->path GR Path, std.rev Path Mods, std.length Path Len, if (Len >= NComp) true (coq.error "Not enough enclosing modules for" {coq.gref->string GR}), std.take NComp Mods L, std.string.concat Sep {std.rev L} ModName. func gref->modname-label gref, int, string -> string. gref->modname-label GR NComp Sep ModName :- coq.gref->path GR Path, std.rev Path PathRev, std.length PathRev Len, if (Len >= NComp) (N = NComp) (N = Len), std.take N PathRev L, std.string.concat Sep {std.rev [{coq.gref->id GR}|L]} ModName. func cs-pattern->name cs-pattern -> string. cs-pattern->name cs-prod "prod". cs-pattern->name (cs-sort _) "sort". cs-pattern->name cs-default "default". cs-pattern->name (cs-gref GR) Name :- gref->modname-label GR 1 "_" Name. func string->modpath string -> modpath. string->modpath S MP :- std.filter {coq.locate-all S} (l\l = loc-modpath _) L, L = [loc-modpath MP]. func gref->modname_short1 modpath, string, list string -> string. gref->modname_short1 _ S [] S :- !. gref->modname_short1 MP "" [X|L] L' :- !, gref->modname_short1 MP X L L'. gref->modname_short1 MP S _ S :- string->modpath S MP, !. gref->modname_short1 MP S [X|L] S' :- gref->modname_short1 MP {std.string.concat "." [X,S]} L S'. % Print shortest qualified identifier of the module containing a gref % Sep is used as separator func gref->modname_short gref, string -> string. gref->modname_short GR Sep IDS :- coq.gref->path GR Path, string->modpath {std.string.concat "." Path} MP, gref->modname_short1 MP "" {std.rev Path} ID, rex.replace "[.]" Sep ID IDS. func avoid-name-collision string -> string. avoid-name-collision S S1 :- coq.locate-all S L, if (std.mem L (loc-gref GR), coq.gref->path GR P, coq.env.current-path P) (S1 is S ^ "__" ^ {std.any->string {new_int}}) (S1 is S). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % function to predicate generic constructions % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% func mk-nil -> list A. mk-nil []. func mk0 A -> A. mk0 F R :- constant R F []. func mk1 (A -> B), A -> B. mk1 F X1 R :- constant R F [X1]. func mk2 (A -> A -> C), A, A -> C. mk2 F X1 X2 R :- constant R F [X1, X2]. func mk3 (A -> A -> A -> D), A, A, A -> D. mk3 F X1 X2 X3 R :- constant R F [X1, X2, X3]. func mk4 (A -> A -> A -> A -> E), A, A, A, A -> E. mk4 F X1 X2 X3 X4 R :- constant R F [X1, X2, X3,X4]. func mk-fun name, term, (term -> term) -> term. mk-fun N Ty Body (fun N Ty Body). % generic argument to pass to w-params func ignore name, term, (term -> A) -> A. ignore _ _ F X :- (pi x y\ F x = F y), X = F (sort prop). % combining body and type func mk-fun-prod name, term -> (term -> pair term term), pair term term. mk-fun-prod N Ty (x\ pr (Body x) (Type x)) (pr (fun N Ty Body) (prod N Ty Type)). func mk-parameter implicit_kind, name, term, (term -> indt-decl) -> indt-decl. mk-parameter IK Name X F (Decl : indt-decl) :- !, Decl = parameter {coq.name->id Name} IK X F. func mk-parameter implicit_kind, name, term, (term -> arity) -> arity. mk-parameter IK Name X F (Decl : arity) :- !, Decl = parameter {coq.name->id Name} IK X F. func params->holes list-w-params A -> list term. params->holes (w-params.nil _ _ _) []. params->holes (w-params.cons _ _ F) [_|PS] :- pi x\ params->holes (F x) PS. func fresh-type -> term. fresh-type Ty :- Ty = {{Type}}, std.assert-ok! (coq.typecheck-ty Ty _) "impossible". %%%%%%%%%%%%%%%%%%%%%% % w-params interface % %%%%%%%%%%%%%%%%%%%%%% :index (1) func apply-w-params w-params A, list term, term -> A. apply-w-params (w-params.cons _ _ PL) [P|PS] T R :- !, apply-w-params (PL P) PS T R. apply-w-params (w-params.nil _ _ L) [] T R :- !, R = L T. apply-w-params _ _ _ _ :- coq.error "apply-w-params". :index (1) func w-params.nparams w-params A -> int. w-params.nparams (w-params.cons _ _ F) N :- pi x\ w-params.nparams (F x) M, N is M + 1. w-params.nparams (w-params.nil _ _ _) 0. % [w-params.fold AwP Cons Nil Out] states that Out has shape % Cons `x_1` T_1 p_1 \ .. \ Nil [p_1 .. p_n] `T` Ty F % where AwP = w-params.cons `x_1` T_1 p_1 \ ... \ w-params.nil `T` Ty F :index (1) func w-params.fold w-params A, (func name, term, (term -> B) -> B), (func list term, name, term, (term -> A) -> B) -> B. w-params.fold L Cons Nil Out :- w-params.fold.params L Cons Nil [] Out. :index (1) func w-params.fold.params w-params A, (func name, term, (term -> B) -> B), (func list term, name, term, (term -> A) -> B), list term % accumulator -> B. w-params.fold.params (w-params.cons ID PTy F) Cons Nil RevPs Out :- !, std.do! [ coq.id->name ID N, (@pi-decl N PTy p\ w-params.fold.params (F p) Cons Nil [p|RevPs] (Body p)), Cons N PTy Body Out]. w-params.fold.params (w-params.nil ID TTy F) _ Nil RevParams Out :- !, std.do! [ coq.id->name ID N, std.rev RevParams Params, Nil Params N TTy F Out, ]. % [w-params.then AwP Cons Nil Out] states that Out has shape % Cons `x_1` T_1 p_1 \ .. \ Nil [p_1 .. p_n] `T` Ty t \ Body % where Pred [p_1 .. p_n] T Body % and AwP = w-params.cons `x_1` T_1 p_1 \ ... \ w-params.nil `T` Ty F :index (1) func w-params.then w-params A, (func name, term, (term -> C) -> C), (func name, term, (term -> B) -> C), (func list term, term, A -> B) -> C. w-params.then L Cons Nil Pred Out :- w-params.fold L Cons (ps\ n\ ty\ f\ out\ sigma Body\ (@pi-decl n ty t\ Pred ps t (f t) (Body t)), Nil n ty Body out) Out. func w-params.map w-params A, (func list term, term, A -> B) -> w-params B. w-params.map AL F BL :- w-params.then AL mk-w-params.cons-name mk-w-params.nil-name F BL. % TODO: make combinators pass id func mk-w-params.cons-name name, term, (term -> w-params A) -> w-params A. mk-w-params.cons-name N T F (w-params.cons ID T F):- coq.name->id N ID. func mk-w-params.nil-name name, term, (term -> A) -> w-params A. mk-w-params.nil-name N T F (w-params.nil ID T F):- coq.name->id N ID. % on the fly abstraction func bind-nil id, term, term, A -> w-params A. bind-nil N T X V (w-params.nil N T A) :- V = A X. func bind-cons id, term, term, w-params A -> w-params A. bind-cons N T X V (w-params.cons N T A) :- V = A X. % Specific to list-w-params func list-w-params_list list-w-params A -> list A. list-w-params_list AwP R :- w-params.then AwP ignore ignore (p\ t\ x\ std.map x triple_1) R. :index (1) func list-w-params.append list-w-params A, list-w-params A -> list-w-params A. list-w-params.append (w-params.nil N T ML1) (w-params.nil N T ML2) (w-params.nil N T ML) :- pi x\ std.append (ML1 x) (ML2 x) (ML x). list-w-params.append (w-params.cons N Ty ML1) (w-params.cons N Ty ML2) (w-params.cons N Ty ML) :- pi x\ list-w-params.append (ML1 x) (ML2 x) (ML x). :index (1) func list-w-params.rcons list-w-params A, (func list term, term -> w-args A) -> list-w-params A. list-w-params.rcons LwP F R :- list-w-params.rcons.aux LwP F [] R. :index (1) func list-w-params.rcons.aux list-w-params A, (func list term, term -> w-args A), list term -> list-w-params A. list-w-params.rcons.aux (w-params.nil N T ML1) F Acc (w-params.nil N T ML2) :- pi x\ sigma Last\ F {std.rev Acc} x Last, std.append (ML1 x) [Last] (ML2 x). list-w-params.rcons.aux (w-params.cons N Ty ML1) F Acc (w-params.cons N Ty ML2) :- pi x\ list-w-params.rcons.aux (ML1 x) F [x|Acc] (ML2 x). func list-w-params.flatten-map list-w-params A, (func A -> list-w-params B) -> list-w-params B. list-w-params.flatten-map (w-params.cons N T L) F (w-params.cons N T L1) :- @pi-parameter N T p\ list-w-params.flatten-map (L p) F (L1 p). list-w-params.flatten-map (w-params.nil N TTy L) F (w-params.nil N TTy L1) :- @pi-parameter N TTy t\ list-w-params.flatten-map.aux (L t) F (L1 t). func list-w-params.flatten-map.aux list (w-args A), (func A -> list-w-params B) -> list (w-args B). list-w-params.flatten-map.aux [] _ []. list-w-params.flatten-map.aux [triple M Ps T|L] F Res1 :- F M MwP, apply-w-params MwP Ps T ML, list-w-params.flatten-map.aux L F Res, std.append ML Res Res1. % [build-list-w-params TheParams TheType Factories ListWParams] % Params is a list of pairs (section variable, its type). % ListWParams has as many w-params.cons as TheParams and the terms % in Factories are abstracted wrt the first component of TheParams. func build-list-w-params list (triple id term term), term, list (w-args A) -> list-w-params A. build-list-w-params [triple ID P Pty|PS] TheType Factories (w-params.cons ID Pty1 R) :- std.do! [ copy Pty Pty1, (@pi-parameter ID Pty1 p\ (copy P p :- !) => build-list-w-params PS TheType Factories (R p)), ]. build-list-w-params [] TheType Factories (w-params.nil Name TT1 R) :- std.do! [ std.assert-ok! (coq.typecheck TheType TT) "BUG: TheType does not typecheck", copy TT TT1, coq.gref->id {coq.term->gref TheType} Name, (@pi-parameter Name TT1 t\ (copy TheType t :- !) => std.map Factories (std.map-triple (=) (x\ std.map x (copy-pack-holes TheType t)) (copy-pack-holes TheType t)) (R t)), ]. :index (1) func copy-pack-holes term, term, term -> term. copy-pack-holes TheType NewType Term Out :- std.do! [ (pi Args NewArgs CSInstance ParamsRev ParamsRevCopy Pack \ (copy (app[global Pack | Args]) (app[global Pack | NewArgs]) :- pack? Pack _, std.rev Args [CSInstance,TheType|ParamsRev], !, std.map ParamsRev copy ParamsRevCopy, std.rev [{{ lib:elpi.hole }},NewType|ParamsRevCopy] NewArgs)) => copy Term Out, ]. func pack? gref -> classname. pack? (indc K) C :- coq.env.indc K _ _ _ KTy, prod-last-gref KTy (indt I), % TODO: use new API std.once (class-def (class C (indt I) _)). func distribute-w-params list-w-params A -> list (one-w-params A). distribute-w-params (w-params.cons N T F) L :- pi x\ distribute-w-params (F x) (L1 x), std.map (L1 x) (bind-cons N T x) L. distribute-w-params (w-params.nil N T F) L :- pi x\ std.map (F x) (bind-nil N T x) L. % Specific to one-w-params func w-params_1 one-w-params A -> A. w-params_1 X Y :- w-params.then X ignore ignore (p\ t\ triple_1) Y. func disable-id-phant term -> term. disable-id-phant T T1 :- (pi fresh fresh1 t v\ copy {{lib:@hb.id lp:t lp:v}} {{lib:@hb.id_disabled lp:t lp:fresh lp:v lp:fresh1}} :- !) => (pi fresh fresh1 t v\ copy {{lib:@hb.ignore lp:t lp:v}} {{lib:@hb.ignore_disabled lp:t lp:fresh lp:v lp:fresh1}} :- !) => copy T T1. func re-enable-id-phant term -> term. re-enable-id-phant T T1 :- (pi f1 f2 t v\ copy {{lib:@hb.id_disabled lp:t lp:f1 lp:v lp:f2}} {{lib:@hb.id lp:t lp:v}} :- !) => (pi f1 f2 t v\ copy {{lib:@hb.ignore_disabled lp:t lp:f1 lp:v lp:f2}} {{lib:@hb.ignore lp:t lp:v}} :- !) => copy T T1. func prod-last term -> term. prod-last (prod N S X) Y :- !, @pi-decl N S x\ prod-last (X x) Y. prod-last X X :- !. func prod-last-gref term -> gref. prod-last-gref (prod N S X) GR :- !, @pi-decl N S x\ prod-last-gref (X x) GR. prod-last-gref X GR :- coq.term->gref X GR. % saturate a type constructor with holes func saturate-type-constructor term -> term. saturate-type-constructor T ET :- coq.typecheck T TH ok, coq.count-prods TH N, coq.mk-app T {coq.mk-n-holes N} ET. math-comp-hierarchy-builder-4d8a939/HB/context.elpi000066400000000000000000000072461521677141400222170ustar00rootroot00000000000000/* Hierarchy Builder: algebraic hierarchies made easy This software is released under the terms of the MIT license */ namespace context { pred declare i:factories, o:mixins, o:list term, o:term, o:list prop, o:list constant. declare FLwP MLwP Params TheKey MSL CL :- !, std.do! [ factories-provide FLwP MLwPRaw, declare.params-key MLwPRaw ParamsSection TheKey _MLwA, std.map ParamsSection triple_2 Params, declare.mixins TheKey ParamsSection MLwPRaw MLwP MSL CL ]. func declare.params-key w-params A -> list (triple id term term), term, A. declare.params-key MLwP Params TheKey Out :- !, std.do! [ if-verbose (coq.say {header} "declaring parameters and key as section variables"), declare.params MLwP Params KId KTy F, log.coq.env.add-section-variable-noimplicits KId KTy C, TheKey = global (const C), Out = F TheKey ]. pred declare.params i:w-params A, o:list (triple id term term), o:id, o:term, o:(term -> A). declare.params (w-params.cons PId PTy F) [triple PId P PTy|Params] KId KTy Out :- !, std.do! [ log.coq.env.add-section-variable-noimplicits PId PTy C, P = global (const C), declare.params (F P) Params KId KTy Out ]. declare.params (w-params.nil KId KTy F) [] KId KTy F :- !. % [declare.mixins TheType Parameters Factories Clauses] postulates a % (section) context with all the mixins provided by the factories and all % the structure instances we can derive on TheType from these. Clauses % contain mixin-src for each postulated mixin :index (1) func declare.mixins term, list (triple id term term), mixins -> mixins, list prop, list constant. declare.mixins TheType TheParamsSection MLwPRaw MLwP MSL CL :- std.do! [ if-verbose (coq.say "Here is the list of mixins to declare (the order matters): " {list-w-params_list MLwPRaw}), std.map TheParamsSection triple_2 TheParams, apply-w-params MLwPRaw TheParams TheType MLwAllArgsRaw, std.fold MLwAllArgsRaw (triple [] [] []) (private.postulate-mixin TheType) (triple CL MSL MLwPRev), acc-clauses current {std.map CL (cs\r\ r = local-canonical cs)}, std.rev MLwPRev MLwPSection, build-list-w-params TheParamsSection TheType MLwPSection MLwP, acc-clauses current MSL, ]. /* ------------------------------------------------------------------------- */ /* ----------------------------- private code ------------------------------ */ /* ------------------------------------------------------------------------- */ namespace private { % Given a type T, a fresh number N, and a mixin M it postulates % a variable "mN" inhabiting M applied to T and % all its dependencies, previously postulated and associated % to the corresponding mixin using mixin-for :index (1) func postulate-mixin term, w-args mixinname, triple (list constant) (list prop) (list (w-args mixinname)) -> triple (list constant) (list prop) (list (w-args mixinname)). postulate-mixin TheType (triple M Ps T) (triple CL MSL MLwP) (triple OutCL [MC|MSL] [NewMwP|MLwP]) :- MSL => std.do! [ Name is "local_mixin_" ^ {gref->modname M 2 "_"}, if-verbose (coq.say "HB: postulate" Name "on" {coq.term->string T}), synthesis.infer-all-gref->deps Ps T M TySkel, % was synthesis.infer-all-mixin-args Ps T M TySkel, % if-verbose (coq.say "HB: postulate-mixin checking" TySkel), % std.assert-ok! (coq.typecheck Ty _) "postulate-mixin: Ty illtyped", std.assert-ok! (coq.elaborate-ty-skeleton TySkel _ Ty) "postulate-mixin: Ty illtyped", log.coq.env.add-section-variable-noimplicits Name Ty C, factory? Ty NewMwP, MC = mixin-src T M (global (const C)), MC => get-option "local" tt => instance.declare-all TheType {findall-classes-for [M]} NewCSL, std.map NewCSL snd NewCL, std.append CL NewCL OutCL ]. }} math-comp-hierarchy-builder-4d8a939/HB/export.elpi000066400000000000000000000101611521677141400220420ustar00rootroot00000000000000/* Hierarchy Builder: algebraic hierarchies made easy This software is released under the terms of the MIT license */ func export.any id ->. export.any S :- coq.locate-all S L, if (L = []) (coq.error "HB: cannot locate" S) true, if (L = [X]) (export.any.aux S X) (coq.error "HB:" S "is ambiguous:" L). func export.any.aux id, located ->. export.any.aux S (loc-gref GR) :- export.abbrev S GR, !. export.any.aux S (loc-modpath MP) :- export.module S MP, !. export.any.aux S X :- coq.error "HB:" S "denotes" X "which is not supported for exporting". % [export.module Module] exports a Module now adds it to the collection of % modules to export in the end of the current enclosing module, % by the command HB.Exports % CAVEAT: "module" is a keyword, we put it in the namespace by hand func export.module id, modpath ->. export.module NiceModule Module :- !, log.coq.env.export-module NiceModule Module, coq.env.current-library File, acc-clause current (module-to-export File NiceModule Module). func export.abbrev id, gref ->. export.abbrev NiceName GR :- !, coq.env.current-library File, acc-clause current (abbrev-to-export File NiceName GR). func export.clause prop ->. export.clause Clause :- !, coq.env.current-library File, acc-clauses current [Clause, clause-to-export File Clause]. func export.reexport-all-modules-and-CS option string ->. export.reexport-all-modules-and-CS Filter :- std.do! [ coq.env.current-library File, export.private.compute-filter Filter MFilter, if-verbose (coq.say {header} "exporting under the module path" MFilter), % NODE: std.list-uniq is for coq < 8.13 std.findall (module-to-export File NiceModule_ Module_) ModsCL, std.filter {std.list-uniq ModsCL} (export.private.module-in-module MFilter) ModsCLFiltered, std.map ModsCLFiltered module-to-export_module-nice NiceMods, std.map ModsCLFiltered module-to-export_module Mods, if-verbose (coq.say {header} "exporting modules" NiceMods), std.forall2 NiceMods Mods log.coq.env.export-module, std.findall (instance-to-export File NiceInstance_ Const_) InstCL, std.filter {std.list-uniq InstCL} (export.private.instance-in-module MFilter) InstCLFiltered, std.map InstCLFiltered instance-to-export_instance Insts, if-verbose (coq.say {header} "exporting CS instances" Insts), std.forall Insts log.coq.CS.declare-instance, std.findall (abbrev-to-export File NiceAbbrev_ GR_) InstAbbL, std.filter {std.list-uniq InstAbbL} (export.private.abbrev-in-module MFilter) InstAbbLFiltered, std.map InstAbbLFiltered abbrev-to-export_name AbbNames, std.map InstAbbLFiltered abbrev-to-export_body AbbBodies, if-verbose (coq.say {header} "exporting Abbreviations" AbbNames), std.forall2 AbbNames AbbBodies (n\b\@global! => log.coq.notation.add-abbreviation n 0 b ff _), std.findall (clause-to-export File Clause_) ClausesL, if-verbose (coq.say {header} "exporting Clauses" Clauses), std.map ClausesL clause-to-export_clause Clauses, acc-clauses current Clauses ]. namespace export.private { :index (1) func prefixL list A, list A ->. prefixL [] _. prefixL [X|Xs] [X|Ys] :- prefixL Xs Ys. func abbrev-in-module list string, prop ->. abbrev-in-module PM (abbrev-to-export _ _ GR) :- coq.gref->path GR PC, prefixL PM PC. func module-in-module list string, prop ->. module-in-module PM (module-to-export _ _ M) :- coq.modpath->path M PC, prefixL PM PC. func instance-in-module list string, prop ->. instance-in-module PM (instance-to-export _ _ C) :- coq.gref->path (const C) PC, prefixL PM PC. func compute-filter option string -> list string. compute-filter none []. compute-filter (some S) MFilter :- % S is a component of the current modpath coq.env.current-path P, rex_split "\\." S L, compute-filter.aux P L MFilter, !. compute-filter (some S) MFilter :- coq.locate-module S M, coq.modpath->path M MFilter. % @gares: same predicate in synterp: code clone? func compute-filter.aux list string, list string -> list string. compute-filter.aux [S|_] [S] [S] :- !. compute-filter.aux [S|XS] [S|SS] [S|YS] :- !, compute-filter.aux XS SS YS. compute-filter.aux [X|XS] L [X|YS] :- compute-filter.aux XS L YS. } math-comp-hierarchy-builder-4d8a939/HB/factory.elpi000066400000000000000000000457401521677141400222030ustar00rootroot00000000000000/* Hierarchy Builder: algebraic hierarchies made easy This software is released under the terms of the MIT license */ namespace factory { func declare argument ->. declare A :- private.declare-asset A private.asset-factory. func declare-mixin argument ->. declare-mixin A :- private.declare-asset A private.asset-mixin. kind factory-abbrev type. type by-classname gref -> factory-abbrev. type by-phantabbrev abbreviation -> factory-abbrev. :index (_ 1) func declare-abbrev id, factory-abbrev -> abbreviation. declare-abbrev Name (by-classname GR) Abbrev :- % looks fishy (the parameters are not taken into account) @global! => log.coq.notation.add-abbreviation Name 1 (fun _ _ t\ app[global GR,t]) tt Abbrev. declare-abbrev Name (by-phantabbrev Abbr) Abbrev :- coq.notation.abbreviation-body Abbr Nargs AbbrTrm, @global! => log.coq.notation.add-abbreviation Name Nargs AbbrTrm tt Abbrev. func argument->w-mixins argument -> w-mixins argument. argument->w-mixins (indt-decl Decl) (pr MLwP ArgwP) :- !, std.do! [ pdecl->w-mixins Decl (pr MLwP DeclwP), w-params.map DeclwP (_\ _\ x\ y\ y = indt-decl x) ArgwP ]. argument->w-mixins (const-decl Id none Decl) (pr MLwP ArgwP) :- !, std.do! [ pdecl->w-mixins Decl (pr MLwP DeclwP), w-params.map DeclwP (_\ _\ x\ y\ y = const-decl Id none x) ArgwP, ]. argument->w-mixins (const-decl Id (some Body) Decl as CDecl) (pr MLwP ArgwP) :- !, std.do! [ if-verbose (coq.say {header} "arguments->w-mixins on const-decl Decl=" CDecl), pdecl->w-mixins Decl (pr MLwP DeclwP), if-verbose (coq.say {header} "arguments->w-mixins on const-decl Decl=" Decl "\nwith MLwP =" MLwP), std.length {list-w-params_list MLwP} NML, if-verbose (coq.say "ML length =" NML), w-params.map DeclwP (ps\ t\ x\ y\ sigma Dummies Args AppBody\ std.do! [ std.nlist NML (sort prop) Dummies, std.append ps [t|Dummies] Args, coq.subst-fun Args Body AppBody, y = const-decl Id (some AppBody) x]) ArgwP ]. argument->w-mixins (ctx-decl Decl) (pr MLwP ArgwP) :- !, std.do! [ cdecl->w-mixins Decl (pr MLwP DeclwP), w-params.map DeclwP (_\ _\ x\ y\ y = ctx-decl x) ArgwP ]. func argument-name argument -> string. argument-name (const-decl Id _ _) Id. argument-name (indt-decl (parameter _ _ _ R)) Id :- argument-name (indt-decl (R (sort prop))) Id. argument-name (indt-decl (record Id _ _ _)) Id. argument-name (indt-decl (inductive Id _ _ _)) Id. argument-name (ctx-decl _) "_" :- !. func pdecl->w-mixins indt-decl -> w-mixins indt-decl. pdecl->w-mixins ((parameter ID _ TySkel Rest : indt-decl) as Decl) Out :- private.is-key Decl, !, private.key-decl-w-mixins "parameter" ID TySkel Rest private.pdecl->w-mixins.mixins Out. pdecl->w-mixins (parameter ID _ TySkel Rest : indt-decl) Out :- !, private.param-decl-w-mixins "parameter" ID TySkel Rest pdecl->w-mixins Out. pdecl->w-mixins (_ : indt-decl) _ :- !, coq.error "HB: declaration must have at least one parameter". func pdecl->w-mixins arity -> w-mixins arity. pdecl->w-mixins ((parameter ID _ TySkel Rest : arity) as Decl) (Out:w-mixins arity) :- private.is-key Decl, !, private.key-decl-w-mixins "parameter" ID TySkel Rest private.pdecl->w-mixins.mixins Out. pdecl->w-mixins (parameter ID _ TySkel Rest : arity) (Out:w-mixins arity) :- !, private.param-decl-w-mixins "parameter" ID TySkel Rest pdecl->w-mixins Out. pdecl->w-mixins (_ : arity) _ :- !, coq.error "HB: declaration must have at least one parameter". func cdecl->w-mixins context-decl -> w-mixins context-decl. cdecl->w-mixins (context-item _ _ _ (some _) _) _ :- !, coq.error "HB: local definition is not supported in this context". cdecl->w-mixins (context-item ID _ TySkel none Rest as Decl) Out :- private.is-key Decl, !, private.key-decl-w-mixins "context-item" ID TySkel Rest private.cdecl->w-mixins.mixins Out. cdecl->w-mixins (context-item ID _ TySkel none Rest) Out :- !, private.param-decl-w-mixins "context-item" ID TySkel Rest cdecl->w-mixins Out. cdecl->w-mixins _ _ :- !, coq.error "HB: declaration must have at least one parameter". /* ------------------------------------------------------------------------- */ /* ----------------------------- private code ------------------------------ */ /* ------------------------------------------------------------------------- */ namespace private { shorten coq.{ term->gref, subst-fun, safe-dest-app, mk-app, mk-eta, subst-prod }. % Type to share code between HB.mixin and HB.factory e(that supports alias factories) kind asset type. type asset-mixin asset. type asset-factory asset. func check-key-attribute-consistency id ->. check-key-attribute-consistency _ :- not(get-option "key" _), !. check-key-attribute-consistency ID :- get-option "key" ID, !. check-key-attribute-consistency ID :- get-option "key" ID1, !, coq.error "HB:" {calc ("The #[key=\"" ^ ID1 ^ "\"] attribute")} "does not match the selected subject" ID. func is-key indt-decl ->. is-key (parameter ID _ _ _\ record _ _ _ _ : indt-decl) :- !, check-key-attribute-consistency ID. is-key (parameter ID _ _ _\ inductive _ _ _ _ : indt-decl) :- !, check-key-attribute-consistency ID. is-key (parameter ID _ _ _ : indt-decl) :- get-option "key" ID, !. is-key (parameter ID _ _ p\ parameter _ _ (M p) _ : indt-decl) :- pi p\ factory? (M p) _, !, check-key-attribute-consistency ID. func is-key arity ->. is-key (parameter ID _ _ _\ arity _ : arity) :- !, check-key-attribute-consistency ID. is-key (parameter ID _ _ _ : arity) :- get-option "key" ID, !. is-key (parameter ID _ _ p\ parameter _ _ (M p) _ : arity) :- pi p\ factory? (M p) _, !, check-key-attribute-consistency ID. func is-key context-decl ->. is-key ((context-item ID _ _ _ _\ context-end) : context-decl) :- !, check-key-attribute-consistency ID. is-key (context-item ID _ _ _ _ : context-decl) :- get-option "key" ID, !. is-key (context-item ID _ _ _ p\ context-item _ _ (M p) _ _ : context-decl) :- pi p\ factory? (M p) _, !, check-key-attribute-consistency ID. func mixin-decl-w-mixins string, string, term, (term -> A), (pred i:A, o:pair (list (w-args mixinname)) A) -> pair (list (w-args mixinname)) A. mixin-decl-w-mixins DeclKind ID TySkel Rest Conv Out :- std.do! [ if-verbose (coq.say {header} "processing mixin" DeclKind ID), std.assert! (not (var TySkel)) "HB: no type provided for mixin", disable-id-phant TySkel TySkelNoId, std.assert-ok! (coq.elaborate-ty-skeleton TySkelNoId _ TyNoId) "HB: mixin illtyped", re-enable-id-phant TyNoId Ty, std.assert! (factory? Ty (triple F Ps T)) "HB: Not a factory applied to the key variable", std.assert! (pi x y\ Rest y = Rest x) "HB: Factories cannot be explicitly mentioned in the subsequent declaration", Dummy = sort prop, Conv (Rest Dummy) (pr MLwA R), Out = pr [triple F Ps T|MLwA] R ]. :index(1) func key-decl-w-mixins string, string, term, (term -> A), (pred i:A, o:pair (list (w-args mixinname)) A) -> pair mixins (w-params A). key-decl-w-mixins DeclKind ID TySkel Rest Conv Out :- std.do! [ if-verbose (coq.say {header} "processing key" DeclKind), std.assert-ok! (coq.elaborate-ty-skeleton TySkel _ Ty) "key illtyped", coq.string->name ID N, @pi-decl N Ty t\ Conv (Rest t) (pr (MLwA t) (R t)), if (var Ty) (fresh-type Ty) true, Out = pr (w-params.nil ID Ty MLwA) (w-params.nil ID Ty R) ]. :index (1) func param-decl-w-mixins string, string, term, (term -> A), (func A -> pair mixins (w-params A)) -> pair mixins (w-params A). param-decl-w-mixins DeclKind ID TySkel Rest Conv Out :- if-verbose (coq.say {header} "processing param" DeclKind), std.assert-ok! (coq.elaborate-ty-skeleton TySkel _ Ty) "param illtyped", coq.string->name ID N, @pi-decl N Ty p\ Conv (Rest p) (pr (MLwP p) (R p)), if (var Ty) (fresh-type Ty) true, Out = pr (w-params.cons ID Ty MLwP) (w-params.cons ID Ty R). func pdecl->w-mixins.mixins indt-decl -> pair (list (w-args mixinname)) indt-decl. pdecl->w-mixins.mixins (parameter ID _ TySkel Rest : indt-decl) Out :- !, mixin-decl-w-mixins "parameter" ID TySkel Rest pdecl->w-mixins.mixins Out. pdecl->w-mixins.mixins (R : indt-decl) (pr [] R) :- !. func pdecl->w-mixins.mixins arity -> pair (list (w-args mixinname)) arity. pdecl->w-mixins.mixins (parameter ID _ TySkel Rest : arity) Out :- !, mixin-decl-w-mixins "parameter" ID TySkel Rest pdecl->w-mixins.mixins Out. pdecl->w-mixins.mixins (R : arity) (pr [] R) :- !. func cdecl->w-mixins.mixins context-decl -> pair (list (w-args mixinname)) context-decl. cdecl->w-mixins.mixins context-end (pr [] context-end) :- !. cdecl->w-mixins.mixins (context-item _ _ _ (some _) _) _ :- !, coq.error "HB: local definition is not supported in this context". cdecl->w-mixins.mixins (context-item ID _ TySkel none Rest) Out :- !, mixin-decl-w-mixins "parameter" ID TySkel Rest cdecl->w-mixins.mixins Out. % The identity builder func declare-id-builder factoryname -> prop. declare-id-builder GR (from GR GR (const C)) :- std.do! [ gref->deps GR GRD, synthesis.mixins-w-params.fun GRD (declare-id-builder.aux GR) IDBodySkel, std.assert-ok! (coq.elaborate-skeleton IDBodySkel IDType IDBody) "identity builder illtyped", log.coq.env.add-const-noimplicits "identity_builder" IDBody IDType @transparent! C, ]. declare-id-builder.aux GR Params TheType (fun `x` Ty x\x) :- synthesis.infer-all-gref->deps Params TheType GR Ty. % [mk-factory-abbrev Str GR CL FactAbbrev] % creates an abbreviation for GR names Str and creates a phant-abbrev clause in CL. % FactAbbrev is the short name for the factory (either an alias of the class record) func mk-factory-abbrev string, gref -> list prop, factory-abbrev. mk-factory-abbrev Str GR Aliases FactAbbrev :- if (factory-alias->gref GR _ ok) (Aliases = [], FactAbbrev = by-classname GR) (phant.of-gref ff GR [] PhTerm, phant.add-abbreviation Str PhTerm PhC Abbrv, Aliases = [phant-abbrev GR (const PhC) Abbrv], FactAbbrev = by-phantabbrev Abbrv). % [declare-asset Asset AssetKind] unifies the code paths for % mixins, factories (and alias factories) func declare-asset argument, asset ->. declare-asset Arg AssetKind :- std.do! [ argument-name Arg Module, if-verbose (coq.say {header} "start module and section" Module), log.coq.env.begin-module Module none, log.coq.env.begin-section Module, if-verbose (coq.say {header} "converting arguments" Arg "to factories"), argument->w-mixins Arg (pr FLwP ArgwP), if-verbose (coq.say {header} "converting factories" FLwP "to mixins"), %%% factories-provide FLwP MLwP, if-verbose (coq.say {header} "declaring context" FLwP), context.declare FLwP MLwP Params TheKey MixinSrcClauses SectionCanonicalInstance, if (Arg = indt-decl _) ( apply-w-params ArgwP Params TheKey (indt-decl (record _ Sort _ Fields)), if-verbose (coq.say {header} "declare mixin or factory"), declare-mixin-or-factory MixinSrcClauses SectionCanonicalInstance Params TheKey Sort Fields MLwP Module AssetKind ) ( apply-w-params ArgwP Params TheKey (const-decl _ (some Sort) _), if-verbose (coq.say {header} "declare factory alias"), declare-factory-alias MixinSrcClauses SectionCanonicalInstance Params TheKey Sort MLwP Module ) ]. pred declare-mixin-or-factory i:list prop, i:list constant, i:list term, i:term, i:term, i:record-decl, i:list-w-params factoryname, i:id, i:asset. declare-mixin-or-factory MixinSrcClauses SectionCanonicalInstance TheParams TheType Sort1 Fields GRFSwP Module D :- std.do! [ if-verbose (coq.say {header} "declare record axioms_"), Kname = "Axioms_", RDeclSkel = record "axioms_" Sort1 Kname Fields, std.assert-ok! (coq.elaborate-indt-decl-skeleton RDeclSkel RDecl) "record declaration illtyped", abstract-over-section TheParams TheType MixinSrcClauses SectionCanonicalInstance coq.abstract-indt-decl RDecl RDeclClosed _, if (get-option "primitive" tt) (@primitive! => log.coq.env.add-indt RDeclClosed R) (log.coq.env.add-indt RDeclClosed R), log.coq.env.end-section-name Module, % We need to anyway declare the record inside the section % since closing the section purges the unused universe level we may have % allocated by typechecking the skeleton just above coq.env.indt R tt _ _ _ [K] _, GRK = indc K, @global! => log.coq.arguments.set-implicit (indt R) [[]], @global! => log.coq.arguments.set-implicit GRK [[]], factories-provide GRFSwP MLwP, w-params.nparams MLwP NParams, build-deps-for-projections R MLwP GRDepsClausesProjs, GRDepsClauses = [gref->deps (indt R) MLwP, gref->deps (indc K) MLwP|GRDepsClausesProjs], % GRDepsClauses => mk-factory-sort MLwP (indt R) _ FactorySortCoe, % FactorySortCoe = coercion GRFSort _ _ _, % TODO: should this be in the Exports module? if-verbose (coq.say {header} "declare notation Build"), GRDepsClauses => phant.of-gref ff GRK [] PhGRK, GRDepsClauses => phant.add-abbreviation "Build" PhGRK BuildConst BuildAbbrev, if-verbose (coq.say {header} "declare notation axioms"), if (D = asset-mixin) ((GRDepsClauses => mk-factory-abbrev "axioms" (indt R) FRClauses FactAbbrev), (GRDepsClauses => FRClauses => declare-id-builder (indt R) IdBuilderClause), Clauses = [IdBuilderClause|FRClauses]) (GRDepsClauses => mk-factory-abbrev "axioms" (indt R) Clauses FactAbbrev), if-verbose (coq.say {header} "start module Exports"), log.coq.env.begin-module "Exports" none, std.flatten [Clauses, GRDepsClauses, [ is-factory (indt R), factory->constructor (indt R) GRK, factory->nparams (indt R) NParams, phant-abbrev GRK (const BuildConst) BuildAbbrev, % gref->deps GRFSort MLwP, % factory-sort FactorySortCoe, ]] NewClauses, acc-clauses current NewClauses, list-w-params_list MLwP MLwoP, std.map MLwoP (_\ r\ r = maximal) Implicits, /* std.map {list-w-params_list MLwP} (_\ r\ r = maximal) Implicits, */ @global! => log.coq.arguments.set-implicit GRK [[maximal|Implicits]], % @global! => log.coq.coercion.declare FactorySortCoe, log.coq.env.end-module-name "Exports" Exports, log.coq.env.end-module-name Module _, if-verbose (coq.say {header} "end modules and sections; export" Exports), export.module {calc (Module ^ ".Exports")} Exports, GRDepsClauses => declare-abbrev Module FactAbbrev _, ]. :index (1) func declare-factory-alias list prop, list constant, list term, term, term, list-w-params factoryname, id. declare-factory-alias MixinSrcClauses SectionCanonicalInstance TheParams TheType Ty1Skel GRFSwP Module :- std.do! [ if-verbose (coq.say {header} "declare constant axioms_"), std.assert-ok! (coq.elaborate-ty-skeleton Ty1Skel _ Ty1) "Illtyped alias factory", abstract-over-section TheParams TheType MixinSrcClauses SectionCanonicalInstance coq.abstract-const-decl (pr Ty1 _) (pr Ty1Closed _) Section, log.coq.env.add-const-noimplicits "axioms_" Ty1Closed _ @transparent! C, std.assert! (safe-dest-app Ty1 (global PhF) _Args) "Argument must be a factory", std.assert-ok! (factory-alias->gref PhF F) "HB", std.assert! (factory->constructor F FK) "BUG: Factory constructor missing", MixinSrcClauses => synthesis.infer-all-gref->deps TheParams TheType FK MFK, std.assert-ok! (coq.typecheck MFK MFKTy) "BUG: typecking of former factory constructor failed", (pi Args\ copy (app[global F|Args]) (app[global (const C)|Section])) => copy MFKTy MFKTyC, abstract-over-section TheParams TheType MixinSrcClauses SectionCanonicalInstance coq.abstract-const-decl (pr MFK MFKTyC) (pr MFKClosed MFKTyCClosed) _, log.coq.env.add-const-noimplicits "Axioms_" MFKClosed MFKTyCClosed @transparent! CK, GRK = const CK, log.coq.env.end-section-name Module, @global! => log.coq.arguments.set-implicit GRK [[]], factories-provide GRFSwP MLwP, GRDepsClauses = [gref->deps (const C) MLwP, gref->deps (const CK) MLwP], GRDepsClauses => phant.of-gref ff GRK [] PhGRK0, % GRDepsClauses => mk-factory-sort MLwP (const C) _ FactorySortCoe, % FactorySortCoe = coercion GRFSort _ _ _, if (mixin->first-class F _) (PhGRK = PhGRK0) (phant.append-fun-unify PhGRK0 PhGRK), GRDepsClauses => phant.add-abbreviation "Build" PhGRK _ _, GRDepsClauses => mk-factory-abbrev "axioms" (const C) Clauses FactAbbrev, if-verbose (coq.say {header} "start module Exports"), log.coq.env.begin-module "Exports" none, w-params.nparams MLwP NParams, std.flatten [ Clauses, GRDepsClauses, [ is-factory (const C), factory->nparams (const C) NParams, factory->constructor (const C) GRK, % gref->deps GRFSort MLwP, % factory-sort FactorySortCoe ] ] NewClauses, acc-clauses current NewClauses, %@global! => log.coq.coercion.declare FactorySortCoe, log.coq.env.end-module-name "Exports" Exports, log.coq.env.end-module-name Module _, if-verbose (coq.say {header} "end modules and sections; export" Exports), export.module {calc (Module ^ ".Exports")} Exports, GRDepsClauses => declare-abbrev Module FactAbbrev _, ]. % [build-deps-for-projections I ML CL] builds a [gref-dep] for each projection P % of I such that P depends on "ML @ [I]" (each operation depends on the the % deps of the record plus the record itself) func build-deps-for-projections inductive, mixins -> list prop. build-deps-for-projections R MLwP CL :- std.do! [ compat.map-filter {coq.env.projections R} (x\y\x = some y) MixinOps, list-w-params.rcons MLwP (pl\t\r\ r = triple (indt R) pl t) MLRwP, std.map MixinOps (gr\r\ r = gref->deps (const gr) MLRwP) CL, ]. % Section handling in Coq is smart, in the sense it it only abstracts over % variables that aoccur. We don't want that for mixin/factories, so we implement % our own discharging. Note that definitions (like canonical instance) have % to be abstracted too. :index (1) func abstract-over-section list term, term, list prop, list constant, (func list constant, A -> A), A -> A, list term. abstract-over-section TheParams TheType MixinSrcClauses SectionCanonicalInstance F X X1 Section :- % compute section variables to be used for discharging std.map MixinSrcClauses mixin-src_src Mixins, std.append TheParams [TheType|{std.rev Mixins}] Section, std.map Section (x\r\ x = global (const r)) SectionVars, % We discharge by hand the record declaration so that we can be sure all % parameters and mixins are abstracted (even if unused). coq.copy-clauses-for-unfold SectionCanonicalInstance CopyUnfold, CopyUnfold => F SectionVars X X1. func mk-factory-sort mixins, gref -> gref, coercion. mk-factory-sort MLwP GR (const FactorySortCst) Coe :- if-verbose (coq.say {header} "declaring tagged sort for GR=" GR), synthesis.mixins-w-params.fun MLwP (mk-factory-sort.term GR) FactorySort, std.assert-ok! (coq.typecheck FactorySort FactorySortTy) "HB: cannot elaborate sort", log.coq.env.add-const-noimplicits "sort" FactorySort FactorySortTy ff FactorySortCst, synthesis.mixins-w-params.length MLwP MLwPLength, std.nlist {calc (MLwPLength + 1)} implicit MLwPImplicits, (@global! => log.coq.arguments.set-implicit (const FactorySortCst) [MLwPImplicits]), synthesis.infer-coercion-tgt MLwP CoeClass, Coe = coercion (const FactorySortCst) MLwPLength GR CoeClass. func mk-factory-sort.term gref, list term, term -> term. mk-factory-sort.term GR P T (fun `_` Ty _\ T) :- synthesis.infer-all-gref->deps P T GR Ty. }}math-comp-hierarchy-builder-4d8a939/HB/graph.elpi000066400000000000000000000016721521677141400216310ustar00rootroot00000000000000/* Hierarchy Builder: algebraic hierarchies made easy This software is released under the terms of the MIT license */ namespace graph { func to-file string ->. to-file File :- !, std.do! [ open_out File OC, output OC "digraph Hierarchy { ", std.forall {coq.coercion.db} (private.pp-coercion-dot OC), output OC "}", close_out OC, ]. /* ------------------------------------------------------------------------- */ /* ----------------------------- private code ------------------------------ */ /* ------------------------------------------------------------------------- */ namespace private { func pp-coercion-dot out_stream, coercion ->. pp-coercion-dot OC (coercion _ _ Src (grefclass Tgt)) :- class-def (class Src _ _), class-def (class Tgt _ _), !, std.do! [ output OC {gref->modname_short Tgt "_"}, output OC " -> ", output OC {gref->modname_short Src "_"}, output OC ";\n", ]. pp-coercion-dot _ _. }}math-comp-hierarchy-builder-4d8a939/HB/howto.elpi000066400000000000000000000160671521677141400216740ustar00rootroot00000000000000/* Hierarchy Builder: algebraic hierarchies made easy This software is released under the terms of the MIT license */ namespace howto { :index (1) func main-trm term, string, option int ->. main-trm T STgt Depth :- coq.term->gref T GR, main-gref GR STgt Depth. :index (1) func main-str string, string, option int ->. main-str S STgt Depth :- coq.locate S GR, main-gref GR STgt Depth. :index (1) func main-gref gref, string, option int ->. main-gref GR STgt Depth :- class-def (class _ GR _), !, private.mixins-in-structures [GR] MLSrc, main-from MLSrc STgt Depth. main-gref GR STgt Depth :- private.structures-on-gref GR SL, private.mixins-in-structures SL MLSrc, main-from MLSrc STgt Depth. :index (1) func main-from list mixinname, string, option int ->. main-from MLSrc STgt Depth :- private.mixins-in-structures [{coq.locate STgt}] MLTgt, private.list-diff MLTgt MLSrc ML, if (ML = []) (coq.say "HB: nothing to do.") (main-from.aux MLSrc ML Depth). :index (_ _ 1) func main-from.aux list mixinname, list mixinname, option int ->. main-from.aux MLSrc ML (some Depth) :- main-increase-depth MLSrc ML Depth false. main-from.aux MLSrc ML none :- main-increase-depth MLSrc ML 3 true. :index (1) func main-increase-depth list mixinname, list mixinname, int, prop. main-increase-depth MLSrc ML Depth AutoIncrease :- private.paths-from-for-step MLSrc ML Depth R, if (not (R = [])) (private.pp-solutions R) (if AutoIncrease (Depth' is Depth + 1, coq.say "HB: no solution found at depth" Depth "looking at depth" Depth', main-increase-depth MLSrc ML Depth' true) (coq.error "HB: no solution found, try to increase search depth.")). /* ------------------------------------------------------------------------- */ /* ----------------------------- private code ------------------------------ */ /* ------------------------------------------------------------------------- */ namespace private { shorten coq.pp.{ v , hov , spc , str , box , glue }. % L1 \subseteq L2 func incl list A, list A ->. incl L1 L2 :- std.forall L1 (std.mem! L2). % R = L1 \ L2 func list-diff list A, list A -> list A. list-diff L1 L2 R :- std.filter L1 (about.not1 (std.mem L2)) R. % R = L1 U L2 func union list A, list A -> list A. union L1 L2 R :- std.fold L2 L1 (x\l\l'\if (std.mem l x) (l' = l) (l' = [x|l])) R. func insert-sorted (func A, A ->), A, list A -> list A. insert-sorted _ X [] [X] :- !. insert-sorted Rel X [Y|T] [X,Y|T] :- Rel X Y, !. insert-sorted Rel X [Y|T] [Y|T'] :- insert-sorted Rel X T T', !. func lt-gref gref, gref. lt-gref X Y :- gref->modname_short X "." SX, gref->modname_short Y "." SY, !, SX s< SY. pred size-order i:(func list A, list A), i:list A, i:list A. size-order Rel L1 L2 :- std.length L1 S1, std.length L2 S2, !, (S1 i< S2; (S1 = S2, !, Rel L1 L2)). pred lexi-order i:list gref, i:list gref. lexi-order [] []. lexi-order [X1|_] [X2|_] :- lt-gref X1 X2. lexi-order [X|T1] [X|T2] :- lexi-order T1 T2. % [structures-on-gref GR ML] list structures [GR] is equipped with func structures-on-gref gref -> list structure. structures-on-gref GR SL :- std.filter {coq.CS.db-for _ (cs-gref GR)} (about.not1 about.unif-hint?) LV, std.map LV structures-on-gref.aux SL. func structures-on-gref.aux cs-instance -> structure. structures-on-gref.aux (cs-instance _ _ GR) F :- coq.prod-tgt->gref {coq.env.typeof GR} F, std.once (class-def (class _ F _)). % [mixins-in-structures SL ML] list mixins in structures [SL] func mixins-in-structures list structure -> list mixinname. mixins-in-structures SL ML :- std.fold SL [] mixins-in-structures.aux ML. func mixins-in-structures.aux structure, list mixinname -> list mixinname. mixins-in-structures.aux F L L' :- std.once (class-def (class _ F MLWP)), union L {list-w-params_list MLWP} L'. % a type to store a factory along with the mixins it depends on % and the mixins it provides kind factory_deps_prov type. type fdp factoryname -> list mixinname -> list mixinname -> factory_deps_prov. % get all available factories in the above type func list_factories -> list factory_deps_prov. list_factories FL :- std.map-filter {findall-factory->constructor} list_factories.aux FL. func list_factories.aux prop -> howto.private.factory_deps_prov. list_factories.aux (factory->constructor F _) (fdp F DML PML) :- gref->deps F FD, list-w-params_list FD DML, list-w-params_list {factory-provides F} PML. % [paths-from-for-step MLSrc ML K R] returns in [R] a list of sequences % of at most [K] factories that could, starting from mixins [MLSrc], % build exactly the mixins [ML] func paths-from-for-step list mixinname, list mixinname, int -> list (list factoryname). paths-from-for-step MLSrc ML K R :- std.filter {list_factories} (fd\sigma pml\fd = fdp _ _ pml, incl pml ML) FL, paths-from-for-step-using MLSrc ML K [] [] FL _ R. % [paths-from-for-step-using MLSrc ML K Pre KnownPre FL KnownPre' R] % same as [paths-from-for-step MLSrc ML K R] using only factories in [FL] % [Pre] is a (sorted) prefix that is looked into the list of known (sorted) % prefixes [KnownPre] to avoid generating identical solutions up to permutations :index (1) func paths-from-for-step-using list mixinname, list mixinname, int, list factoryname, list (list factoryname), list factory_deps_prov -> list (list factoryname), list (list factoryname). paths-from-for-step-using _ _ K _ KnownPre _ KnownPre [] :- K i< 0, !. paths-from-for-step-using _ _ _ Pre KnownPre _ KnownPre [] :- std.mem KnownPre Pre, !. paths-from-for-step-using _ [] _ Pre KnownPre _ [Pre|KnownPre] [[]] :- !. paths-from-for-step-using MLSrc ML K Pre KnownPre FL [Pre|KnownPre'] R :- K' is K - 1, std.filter FL (p\sigma dml\p = fdp _ dml _, incl dml MLSrc) FLdep, std.fold FLdep (pr KnownPre []) (paths-from-for-step-using.aux MLSrc ML FL K' Pre) (pr KnownPre' R). func paths-from-for-step-using.aux list mixinname, list mixinname, list factory_deps_prov -> int, list factoryname, factory_deps_prov, pair (list (list factoryname)) (list (list factoryname)), pair (list (list factoryname)) (list (list factoryname)). paths-from-for-step-using.aux MLSrc ML FL' K' Pre (fdp F _ MLF) (pr KnPre L) (pr KnPre' R) :- std.append MLSrc MLF MLSrc', list-diff ML MLF ML', insert-sorted lt-gref F Pre Pre', std.filter FL' (p\sigma pml\p = fdp _ _ pml, incl pml ML') FML', paths-from-for-step-using MLSrc' ML' K' Pre' KnPre FML' KnPre' R', std.map R' (l\r\r = [F|l]) R'', std.append L R'' R. func pp-solutions list (list factoryname) ->. pp-solutions LLF :- std.sort LLF (size-order lexi-order) SLLF, % format PpSolutions = box (v 4) [ str "HB: solutions (use 'HB.about F.Build' to see the arguments of each factory F):", {about.bulletize SLLF pp-solution}], % print coq.say {coq.pp->string PpSolutions}, coq.say, coq.say "For a guide on declaring MathComp instances please refer to the following link: https://github.com/math-comp/math-comp/wiki/How-to-declare-MathComp-instances", coq.say. func pp-solution list factoryname -> coq.pp. pp-solution L (box (hov 0) PLS) :- std.map L about.pp-module PL, std.intersperse (glue [str ";", spc]) PL PLS. }}math-comp-hierarchy-builder-4d8a939/HB/instance.elpi000066400000000000000000000500571521677141400223350ustar00rootroot00000000000000/* Hierarchy Builder: algebraic hierarchies made easy This software is released under the terms of the MIT license */ namespace instance { % [declare-existing T F] equips T with all the canonical structures that can be % built using factory instance F func declare-existing argument, argument ->. declare-existing T0 F0 :- std.do! [ argument->ty T0 T, % TODO: change this when supporting morphism hierarchies argument->term F0 F, std.assert-ok! (coq.typecheck F FTy) "HB: declare-existing illtyped factory instance", std.assert! (coq.safe-dest-app FTy (global FactoryAlias) _) "The type of the instance is not a factory", std.assert-ok! (factory-alias->gref FactoryAlias Factory) "HB: ", private.declare-instance Factory T F Clauses _ _, acc-clauses current Clauses, ]. % [declare-const N B Ty CFL CSL] adds a Definition N : Ty := B where Ty is a factory % and equips the type the factory is used on with all the canonical structures % that can be built using factory instance B. CFL contains the list of % factories being defined, CSL the list of canonical structures being defined. func declare-const id, term, arity -> list (pair id constant), list (pair id constant). declare-const Name BodySkel TyWPSkel CFL CSL :- std.do! [ std.assert-ok! (coq.elaborate-arity-skeleton TyWPSkel _ TyWP) "Definition type illtyped", coq.arity->term TyWP Ty, std.assert-ok! (coq.elaborate-skeleton BodySkel Ty Body) "Definition illtyped", % handle parameters via a section -- begin if (TyWP = arity SectionTy) ( % Do not open a section when it is not necessary (no parameters) % A side effect of opening a section is loosing meta data associated % with instances, in particular builder tags are lost if-verbose (coq.say "HB: skipping section opening"), SectionBody = Body ) ( std.assert! (coq.next-synterp-action (begin-section SectionName)) "synterp code did not open section", log.coq.env.begin-section SectionName, private.postulate-arity TyWP [] Body SectionBody SectionTy ), % identify the factory std.assert! (coq.safe-dest-app SectionTy (global FactoryAlias) Args) "The type of the instance is not a factory", std.assert-ok! (factory-alias->gref FactoryAlias Factory) "HB", std.assert! (factory->nparams Factory NParams) "Not a factory synthesized by HB", % declare the constant for the factory instance private.hack-section-discharging SectionBody SectionBodyHack, private.optimize-body SectionBodyHack OptimizedBody, if (Name = "_") (RealName is "HB_unnamed_factory_" ^ {std.any->string {new_int} }) (RealName = Name), % unfold local instances in the type of C if (current-mode (builder-from _ _ _ _)) (std.do![ findall-local-canonical LocalCSL, coq.copy-clauses-for-unfold LocalCSL UnfoldClauses, UnfoldClauses => copy SectionTy SectionTyUnfolded, ]) (SectionTy = SectionTyUnfolded), % call HB.instance TheType TheFactory std.drop NParams Args [TheType|_], if (var TheType) (coq.error "HB: The instance subject must be explicitly given.\nUse:\n HB.instance Definition _ : M := ...\n HB.instance Definition _ := M.Build ...") true, log.coq.env.add-const-noimplicits-failondup RealName OptimizedBody SectionTyUnfolded @transparent! C, TheFactory = (global (const C)), private.check-non-forgetful-inheritance TheType Factory, private.declare-instance Factory TheType TheFactory Clauses CFL CSL, if (CSL = []) (coq.warning "HB" "HB.no-new-instance" "HB: no new instance is generated") true, % handle parameters via a section -- end if (TyWP = arity _) true ( if-verbose (coq.say {header} "closing instance section"), log.coq.env.end-section-name SectionName ), % we accumulate clauses now that the section is over acc-clauses current Clauses ]. % [not-subclass-of X C] holds if C does not inherit from X func not-subclass-of classname, hbclass ->. not-subclass-of HasNoInstance (class C _ _) :- not(sub-class C HasNoInstance _ _). % [declare-all T CL MCSTL] given a type T and a list of class definition % CL in topological order (from least dep to most) looks for classes % for which all the dependencies (mixins) were postulated so far and skips the % rest. For each fulfilled class it declares a local constant inhabiting the % corresponding structure and declares it canonical. % Each mixin used in order to fulfill a class is returned together with its name. func declare-all term, list hbclass -> list (pair id constant). declare-all _ [] []. declare-all T [class _ Struct _|Rest] L :- has-instance T Struct, !, declare-all T Rest L. declare-all T [class Class Struct MLwP|Rest] [pr Name CS|L] :- infer-class T Class Struct MLwP S Name STy Clauses, !, decl-const-in-struct Name S STy CS, Clauses => declare-all T Rest L. declare-all T [class HasNoInstance _ _|Rest] L :- % filter out classes we can't build for sure std.filter Rest (not-subclass-of HasNoInstance) Rest1, declare-all T Rest1 L. % for generic types, we need first to instantiate them by giving them holes, % so they can be used to instantiate the classes :index (_ 2) func declare-all-on-type-constructor term, list hbclass -> list (pair id constant). declare-all-on-type-constructor _ [] []. declare-all-on-type-constructor TK [class _ Struct _|Rest] L :- saturate-type-constructor TK T, has-instance T Struct, !, declare-all-on-type-constructor TK Rest L. declare-all-on-type-constructor TK [class Class Struct MLwP|Rest] [pr Name CS|L] :- %TODO: compute the arity of the Class subject and saturate up to that point % there may even be more than one possibility saturate-type-constructor TK T, infer-class T Class Struct MLwP S Name _STy Clauses, !, abstract-holes.main S SC, std.assert-ok! (coq.typecheck SC SCTy) "declare-all-on-type-constructor: badly closed", decl-const-in-struct Name SC SCTy CS, Clauses => declare-all-on-type-constructor TK Rest L. declare-all-on-type-constructor TK [class HasNoInstance _ _|Rest] L :- % filter out classes we can't build for sure std.filter Rest (not-subclass-of HasNoInstance) Rest1, declare-all-on-type-constructor TK Rest1 L. func has-instance term, structure ->. has-instance T Struct :- if (has-CS-instance? T Struct) (if-verbose (coq.say {header} "skipping already existing" {nice-gref->string Struct} "instance on" {coq.term->string T})) fail. % we build it func infer-class term, classname, gref, factories -> term, string, term, list prop. infer-class T Class Struct MLwP S Name STy Clauses:- std.do![ params->holes MLwP Params, get-constructor Class KC, if (synthesis.infer-all-args-let Params T KC KCApp ok) (if-verbose (coq.say {header} "we can build a" {nice-gref->string Struct} "on" {coq.term->string T})) fail, Name is {cs-pattern->name {term->cs-pattern T}} ^ "__canonical__" ^ {gref->modname Struct 2 "_" }, if-verbose (coq.say {header} "declare canonical structure instance" Name), get-constructor Struct KS, coq.safe-dest-app T THD _, private.optimize-class-body THD {std.length Params} KCApp KCAppNames Clauses, coq.mk-app (global KS) {std.append Params [T, KCAppNames]} S, if-verbose (coq.say {header} "structure instance for" Name "is" {coq.term->string S}), coq.typecheck S STy ok, % failure may be due to a parameter not rich enough see #435 ]. func decl-const-in-struct string, term, term, constant ->. decl-const-in-struct Name S STy CS:- std.do![ if (ground_term S) (S1 = S, STy1 = STy) (abstract-holes.main S S1, std.assert-ok! (coq.typecheck S1 STy1) "HB: structure instance illtyped after generalizing over holes"), log.coq.env.add-const-noimplicits Name S1 STy1 @transparent! CS, % Bug coq/coq#11155, could be a Let with-locality (log.coq.CS.declare-instance CS), % Bug coq/coq#11155, should be local acc-clause current (local-canonical CS), if-verbose (coq.say {header} "structure instance" Name "declared"), ]. func declare-factory-sort-deps gref ->. declare-factory-sort-deps GR :- std.do! [ if-verbose (coq.say {header} "required instances on factory sort for" GR), Name is "SortInstances" ^ {std.any->string {new_int}}, log.coq.env.begin-module Name none, log.coq.env.begin-section Name, mk-factory-sort-deps GR CSL, log.coq.env.end-section-name Name, log.coq.env.end-module-name Name _, std.forall CSL (x\ sigma CS\ x = pr _ CS, log.coq.CS.declare-instance CS) ]. func declare-factory-sort-factory gref ->. declare-factory-sort-factory GR :- std.do! [ if-verbose (coq.say {header} "required instances on factory sort for" GR), Name is "SortInstances" ^ {std.any->string {new_int}}, log.coq.env.begin-module Name none, log.coq.env.begin-section Name, mk-factory-sort-factory GR CFL CSL, log.coq.env.end-section-name Name, log.coq.env.end-module-name Name _, std.forall {std.append CFL CSL} (x\ sigma CS\ x = pr _ CS, log.coq.CS.declare-instance CS) ]. pred context.declare i:factories, o:mixins, o:list term, o:term, o:list prop, o:list constant. func mk-factory-sort-deps gref -> list (pair id constant). mk-factory-sort-deps AliasGR CSL :- std.do! [ std.assert-ok! (factory-alias->gref AliasGR GR) "HB: mk-factory-sort-deps", gref->deps GR MLwPRaw, context.declare MLwPRaw MLwP SortParams SortKey SortMSL _, SortMSL => synthesis.infer-all-gref->deps SortParams SortKey GR FSort, log.coq.env.add-section-variable-noimplicits "f" FSort CF, GCF = global (const CF), factory-sort (coercion GRFSort _ GR _), SortMSL => synthesis.infer-all-gref->deps SortParams SortKey GRFSort KSort, coq.mk-app KSort [GCF] KFSortEta, list-w-params_list MLwP ML, std.length ML NMLArgs, coq.mk-n-holes NMLArgs SortMLHoles, std.append {std.append SortParams [SortKey|SortMLHoles]} [GCF] KFSortArgs, coq.mk-app (global GRFSort) KFSortArgs KFSort, std.assert-ok! (coq.unify-eq KFSortEta KFSort) "HB: KRSort not an app", std.map SortMSL (c\ o\ sigma m t\ c = mixin-src _ m t, o = mixin-src KFSort m t) KFSortMSL, KFSortMSL => synthesis.under-mixin-src-from-factory.do! KFSort GCF [declare-all KFSort {findall-classes-for ML} CSL] ]. func mk-factory-sort-factory gref -> list (pair id constant), list (pair id constant). mk-factory-sort-factory AliasGR CFL CSL :- std.do! [ std.assert-ok! (factory-alias->gref AliasGR GR) "HB", gref->deps GR MLwPRaw, context.declare MLwPRaw MLwP SortParams SortKey SortMSL _, SortMSL => synthesis.infer-all-gref->deps SortParams SortKey GR FSort, log.coq.env.add-section-variable-noimplicits "f" FSort CF, std.length {list-w-params_list MLwP} NMLArgs, coq.mk-n-holes NMLArgs SortMLHoles, GCF = global (const CF), coq.mk-app (global GR) {std.append SortParams [GCF|SortMLHoles]} FGCF, declare-const "_" GCF (arity FGCF) CFL CSL ]. % create instances for all possible combinations of types and structure compatible func saturate-instances cs-pattern -> . saturate-instances Filter :- std.do! [ findall-has-mixin-instance Filter ClausesHas, std.map ClausesHas has-mixin-instance_key KL, undup-cs-patterns KL UKL, std.map UKL cs-pattern->term TL, findall-classes AllClasses, std.map ClausesHas has-mixin-instance->mixin-src Clauses, Clauses => std.map2 TL UKL (t\k\CI\sigma Classes\ std.filter AllClasses (no-instance-for k) Classes, declare-all-on-type-constructor t Classes CI) CIL, private.clauses-for-export {std.flatten CIL} ClausesExport, acc-clauses current ClausesExport, ]. func no-instance-for cs-pattern, hbclass ->. no-instance-for K (class _ S _) :- get-structure-sort-projection S (global Proj), coq.CS.db-for Proj K []. /* ------------------------------------------------------------------------- */ /* ----------------------------- private code ------------------------------ */ /* ------------------------------------------------------------------------- */ namespace private { shorten coq.{ term->gref, subst-fun, safe-dest-app, mk-app, mk-eta, subst-prod }. func declare-instance factoryname, term, term -> list prop, list (pair id constant), list (pair id constant). declare-instance Factory T F Clauses CFL CSL :- current-mode (builder-from T TheFactory FGR _), !, if (get-option "local" tt) (coq.error "HB: declare-instance: cannot make builders local. If you want temporary instances, make an alias, e.g. with let T' := T") true, !, declare-canonical-instances-from-factory-and-local-builders Factory T F TheFactory FGR Clauses CFL CSL. declare-instance Factory T F Clauses CFL CSL :- declare-canonical-instances-from-factory Factory T F Clauses1 CFL CSL, clauses-for-export {std.append CFL CSL} Clauses2, std.append Clauses1 Clauses2 Clauses. func clauses-for-export list (pair id constant) -> list prop. clauses-for-export CL ECL :- if (get-option "export" tt) (coq.env.current-library File, std.map CL (x\r\ sigma i c\ x = pr i c, r = instance-to-export File i c) ECL) (ECL = []). % [add-mixin T F _ M Cl] adds a constant being the mixin instance for M on type % T built from factory F func add-mixin term, factoryname, bool, mixinname -> list prop, list (pair id constant). add-mixin T FGR MakeCanon MissingMixin [MixinSrcCl, BuilderDeclCl] CSL :- std.do! [ new_int N, % timestamp synthesis.assert!-infer-mixin T MissingMixin Bo, MixinSrcCl = mixin-src T MixinName (global (const C)), BuilderDeclCl = builder-decl (builder N FGR MixinName (const C)), std.assert-ok! (coq.typecheck Bo Ty) "declare-instances: mixin illtyped", safe-dest-app Ty (global MixinNameAlias) _, std.assert-ok! (factory-alias->gref MixinNameAlias MixinName) "HB", std.assert! (MissingMixin = MixinName) "HB: anomaly: we built the wrong mixin", % If the mixin instance is already a constant there is no need to % alias it. if (Bo = global (const C)) true (Name is {gref->modname FGR 2 "_"} ^"__to__" ^ {gref->modname MixinName 2 "_"}, if-verbose (coq.say {header} "declare mixin instance" Name), log.coq.env.add-const-noimplicits Name Bo Ty @transparent! C), if (MakeCanon = tt, whd (global (const C)) [] (global (indc _)) _) (std.do! [ if-verbose (coq.say {header} "declare canonical mixin instance" C), with-locality (log.coq.CS.declare-instance C), CSL = [pr "_" C] ]) (CSL = []), ]. func add-all-mixins term, factoryname, list mixinname, bool -> list prop, list (pair id constant). add-all-mixins T FGR ML MakeCanon Clauses CSL :- std.do! [ std.map ML (m\ o\ sigma ClL CSL\ add-mixin T FGR MakeCanon m ClL CSL, o = pr ClL CSL) ClLxCSL_L, std.unzip ClLxCSL_L ClLL CSLL, std.flatten ClLL Clauses, std.flatten CSLL CSL ]. % [postulate-arity A Acc T TS] postulates section variables % corresponding to parameters in arity A. TS is T applied % to all section variables (and hd-beta reduced). Acc should % be [] at call site. func postulate-arity arity, list term, term -> term, term. postulate-arity (parameter ID _ S A) Acc T T1 Ty :- std.assert-ok! (coq.typecheck-ty S _) "arity parameter illtyped", if-verbose (coq.say {header} "postulating" ID), if (var S) (coq.fresh-type S) true, log.coq.env.add-section-variable-noimplicits ID S C, Var = global (const C), postulate-arity (A Var) [Var|Acc] T T1 Ty. postulate-arity (arity Ty) ArgsRev X T Ty :- hd-beta X {std.rev ArgsRev} X1 Stack1, unwind X1 Stack1 T. % We find the new mixins that F build, we build them and shedule them % for becoming builders at section closing time. We also declare % all canonical instances these new mixins allow for, so that the user % can access their theory and notations func declare-canonical-instances-from-factory-and-local-builders factoryname, term, term, term, factoryname -> list prop, list (pair id constant), list (pair id constant). declare-canonical-instances-from-factory-and-local-builders Factory T F _TheFactory FGR Clauses CFL CSL :- std.do! [ synthesis.under-new-mixin-src-from-factory.do! T F (NewMixins\ std.do! [ add-all-mixins T FGR NewMixins ff Clauses CFL, ]), list-w-params_list {factory-provides Factory} ML, Clauses => declare-all T {findall-classes-for ML} CSL, ]. % [declare-canonical-instances-from-factory T F] given a factory F % it uses all known builders to declare canonical instances of structures % on T func declare-canonical-instances-from-factory factoryname, term, term -> list prop, list (pair id constant), list (pair id constant). declare-canonical-instances-from-factory Factory T F ClausesHas CFL CSL :- std.do! [ % The order of the following two "under...do!" is crucial, % priority must be given to canonical mixins % as they are the ones which guarantee forgetful inheritance % hence we add these clauses last. synthesis.local-canonical-mixins-of T MLCano, synthesis.under-mixin-src-from-factory.do! T F [ MLCano => std.do! [ list-w-params_list {factory-provides Factory} ML, add-all-mixins T Factory ML tt Clauses CFL, std.map-filter Clauses (mixin-src->has-mixin-instance ) ClausesHas, ClausesHas => declare-all T {findall-classes-for ML} CSL, % declare-all-on-type-constructor doesn't work here ] ], ]. % If you don't mention the factory in a builder, then Coq won't make % a lambda for it at section closing time. func hack-section-discharging term -> term. hack-section-discharging B B :- current-mode no-builder, !. hack-section-discharging B B1 :- current-mode (builder-from _ TheFactory _ _), !, std.assert-ok! (coq.typecheck TheFactory TheFactoryTy) "TheFactory is illtyped (BUG)", B1 = {{ let _ : lp:TheFactoryTy := lp:TheFactory in lp:B }}. hack-section-discharging B B. % unfolds the constant used for the phant abbreviation to avoid storing all % the phantom abstrctions and idfun that were used to trigger inference func optimize-body term -> term. optimize-body (app[global (const C)| Args]) Red :- (phant-abbrev _ (const C) _ ; (rex_match "phant_" {coq.gref->id (const C)})), !, coq.env.const C (some B) _, hd-beta B Args HD Stack, unwind HD Stack Red. optimize-body (let _ _ T x\x) Red :- !, optimize-body T Red. optimize-body X X. func hnf term -> term. hnf X R :- get-option "hnf" tt, !, unwind {whd X []} R. hnf X X. :index (_ _ 1) func optimize-class-body term, int, term -> term, list prop. optimize-class-body T NParams (let _ _ MBo R) R1 Clauses :- std.do! [ declare-mixin-name {hnf MBo} MC CL1, if (T = global (indt _), MC = global (const C), not(coq.env.opaque? C)) (log.coq.strategy.set [C] (level 1000)) true, % opaque stops simpl optimize-class-body T NParams (R MC) R1 CL2, std.append CL1 CL2 Clauses, ]. optimize-class-body _ _ (app L) (app L) []. func declare-mixin-name term -> term, list prop. declare-mixin-name (global _ as T) T [] :- !. declare-mixin-name T (global GR) [] :- mixin-mem T GR, !. declare-mixin-name T T [] :- coq.safe-dest-app T (global GR) _, not (from _ _ GR), not (get-option "hnf" tt), !. declare-mixin-name T (global (const C)) [mixin-mem T (const C)] :- std.do! [ Name is "HB_unnamed_mixin_" ^ {std.any->string {new_int}}, if-verbose (coq.say {header} "Giving name" Name "to mixin instance" {coq.term->string T}), log.coq.env.add-const-noimplicits Name T _ @transparent! C, ]. func check-non-forgetful-inheritance term, gref. check-non-forgetful-inheritance _ _ :- get-option "non_forgetful_inheritance" tt, !. check-non-forgetful-inheritance T Factory :- std.do! [ if (coq.safe-dest-app T (global (const HdSym)) _, structure-key HdSym _ Super) ( coq.warning "HB" "HB.non-forgetful-inheritance" "non forgetful inheritance detected.\n" "You have two solutions:" "1. (Best practice) Reorganize your hierarchy to make" {nice-gref->string Factory} "depend on" { calc ({nice-gref->string Super} ^ ".") } "See the paper \"Competing inheritance paths in" "dependent type theory\" (https://hal.inria.fr/hal-02463336) for more" "explanations" "2. Use the attribute #[non_forgetful_inheritance] to disable this check." "We strongly advise you encapsulate this instance inside a module," "in order to isolate it from the rest of the code, and to be able" "to import it on demand. See the above paper and the file" "https://github.com/math-comp/hierarchy-builder/blob/master/tests/non_forgetful_inheritance.v" "to witness devastating effects." ) true ]. }} math-comp-hierarchy-builder-4d8a939/HB/pack.elpi000066400000000000000000000070001521677141400214350ustar00rootroot00000000000000 /* Hierarchy Builder: algebraic hierarchies made easy This software is released under the terms of the MIT license */ namespace pack { pred main i:term, i:list argument, o:term. main Ty Args Instance :- std.do! [ std.assert! (not(var Ty)) "HB.pack: the structure to pack cannot be unknown, use HB.pack_for", std.assert! (coq.safe-dest-app {unwind {whd Ty []}} (global Structure) Params) "HB.pack: not a structure", std.assert! (class-def (class Class Structure _)) "HB.pack: not a structure", std.assert! (Args = [trm TSkel|FactoriesSkel]) "HB.pack: not enough arguments", get-constructor Class KC, get-constructor Structure KS, std.assert-ok! (d\ (coq.elaborate-ty-skeleton TSkel _ T d, d = ok) ; coq.elaborate-skeleton TSkel _ T d ) "HB.pack: not a well typed key", private.elab-factories FactoriesSkel T Factories, if (var T) (coq.error "HB.pack: you must pass a type or at least one factory") true, if2 (T = app[global (const SortProj)|ProjParams], structure-key SortProj ClassProj _) (AllFactories = [app[global (const ClassProj)|ProjParams] | Factories], Tkey = T) % already existing class on T (def T _ _ Tkey) % we unfold letins if we can, they may hide constants with CS instances (AllFactories = Factories) (AllFactories = Factories, Tkey = T), % it's a factory, won't add anything private.synth-instance Params KC KS T Tkey AllFactories Instance, ]. /* ------------------------------------------------------------------------- */ /* ----------------------------- private code ------------------------------ */ /* ------------------------------------------------------------------------- */ namespace private { pred synth-instance.aux i:list term, i:gref, i:gref, i:term, i:term, i:list term, i:list prop, o:term. synth-instance.aux Params KC KS T Tkey [Factory|Factories] MLCano Instance :- synthesis.under-new-mixin-src-from-factory.do! Tkey Factory (_\ synth-instance.aux Params KC KS T Tkey Factories MLCano Instance). synth-instance.aux Params KC KS T Tkey [] MLCano Instance :- MLCano => std.do! [ std.assert-ok! (synthesis.infer-all-args-let Params Tkey KC ClassInstance) "HB.pack: cannot infer the instance", std.append Params [T, ClassInstance] InstanceArgs, Instance = app[global KS | InstanceArgs] ]. pred synth-instance i:list term, i:gref, i:gref, i:term, i:term, i:list term, o:term. synth-instance Params KC KS T Tkey Factories Instance :- if (coq.safe-dest-app Tkey (global _) _) (synthesis.local-canonical-mixins-of Tkey MLCano) (MLCano = []), synth-instance.aux Params KC KS T Tkey Factories MLCano Instance. pred elab-factories i:list argument, i:term, o:list term. elab-factories [] _ []. elab-factories [trm FactorySkel|More] T [Factory|Factories] :- std.assert-ok! (coq.elaborate-skeleton FactorySkel FTy MaybeFactory) "HB.pack: illtyped factory", if2 (factory? {unwind {whd FTy []}} (triple _ _ T1)) % a factory (Factory = MaybeFactory) (coq.safe-dest-app {unwind {whd FTy []}} (global GR) _, structure-key SortP ClassP GR) % a structure instance (coq.mk-n-holes {structure-nparams GR} Params, std.append Params [MaybeFactory] ParamsF, coq.mk-app (global (const SortP)) ParamsF T1, coq.mk-app (global (const ClassP)) ParamsF Factory) (coq.error "HB: argument" {coq.term->string MaybeFactory} "is not a factory, it has type:" {coq.term->string FTy}), std.assert-ok! (coq.unify-eq T T1) "HB.pack: factory for the wrong type", elab-factories More T Factories. }} math-comp-hierarchy-builder-4d8a939/HB/status.elpi000066400000000000000000000055351521677141400220550ustar00rootroot00000000000000/* Hierarchy Builder: algebraic hierarchies made easy This software is released under the terms of the MIT license */ namespace status { pred print-hierarchy. print-hierarchy :- std.do! [ coq.say "--------------------- Hierarchy -----------------------------------", std.findall (class-def CL_) CL, std.forall CL private.pp-class, coq.say "", coq.say "--------------------- Builders -----------------------------------", std.findall (from A_ B_ C_) FL, std.forall FL private.pp-from, std.findall (mixin-src T_ M_ V_) ML, if (ML = []) true ( coq.say "", coq.say "--------------------- Local mixin instances ----------------------", std.forall ML private.pp-mixin-src ), std.findall (builder-decl BD_) BDL, if (BDL = []) true ( coq.say "", coq.say "--------------------- Builder declarations ----------------------", std.forall BDL private.pp-builder-decl ), std.findall (current-mode BF_) BFL, if (BFL = []) true ( coq.say "", coq.say "--------------------- Current mode ----------------------", std.forall BFL private.pp-current-mode ), ]. /* ------------------------------------------------------------------------- */ /* ----------------------------- private code ------------------------------ */ /* ------------------------------------------------------------------------- */ namespace private { pred pp-from i:prop. pp-from (from F M T) :- coq.say "From" {coq.term->string (global F)} "to" {coq.term->string (global M)}, coq.say " " {coq.term->string (global T)}, coq.say "". pred pp-list-w-params i:mixins, i:term. pred pp-list-w-params.list-triple i:list (w-args mixinname), i:term. pred pp-list-w-params.triple i:w-args mixinname. pp-list-w-params (w-params.cons N Ty LwP) T :- @pi-parameter N Ty p\ pp-list-w-params (LwP p) {coq.mk-app T [p]}. pp-list-w-params (w-params.nil N TTy LwP) T :- @pi-parameter N TTy t\ pp-list-w-params.list-triple (LwP t) {coq.mk-app T [t]}. pp-list-w-params.list-triple L S :- coq.say {coq.term->string S} ":=", std.forall L pp-list-w-params.triple. pp-list-w-params.triple (triple M Params T) :- coq.say " " {coq.term->string (app [global M|{std.append Params [T]}])}. pred pp-class i:prop. pp-class (class-def (class _ S MLwP)) :- pp-list-w-params MLwP (global S). pred pp-mixin-src i:prop. pp-mixin-src (mixin-src T M C) :- coq.say {coq.term->string T} "is a" {nice-gref->string M} "thanks to" {coq.term->string C}. pred pp-builder-decl i:prop. pp-builder-decl (builder-decl (builder N F M GR)) :- coq.say "builder" GR "with serial number" N "will build mixin" M "from factory" F. pred pp-current-mode i:prop. pp-current-mode (current-mode (builder-from TheType TheFactory GRF Mod)) :- coq.say "The current key is" TheType "with factory" TheFactory "corresponding to Global Ref" GRF "in module" Mod. }} math-comp-hierarchy-builder-4d8a939/HB/structure.elpi000066400000000000000000000671201521677141400225700ustar00rootroot00000000000000/* Hierarchy Builder: algebraic hierarchies made easy This software is released under the terms of the MIT license */ namespace structure { % HB.structure Definition S P1 P2 := { T of F1 P1 T & F2 P1 (P2*P2) T } % cons p1\ cons p2\ nil t\ [triple f1 [p1] t,triple f2 [p1, {{p1 * p2}}] t] pred declare i:string, i:term, i:sort. declare Module BSkel Sort :- std.do! [ disable-id-phant BSkel BSkelNoId, std.assert-ok! (coq.elaborate-skeleton BSkelNoId _ BNoId) "illtyped structure definition", re-enable-id-phant BNoId B, private.sigT->list-w-params B GRFSwP ClosureCheck, factories-provide GRFSwP PMLwP, list-w-params.flatten-map GRFSwP gref->deps RMLwP, % TODO: extract code from factories-provide list-w-params.append PMLwP RMLwP UnsortedMLwP, w-params.map UnsortedMLwP (p\t\ toposort-mixins) MLwP, list-w-params_list PMLwP PML, list-w-params_list MLwP ML, synthesis.list-w-params.check-key MLwP, if (ClosureCheck = tt, not({std.length PML} = {std.length ML})) (coq.warning "HB" "HB.implicit-structure-dependency" "pulling in dependencies:" {std.map {std.list-diff ML PML} nice-gref->string} "\nPlease list them or end the declaration with '&'") true, private.if-class-already-exists-error Module {findall-classes-for ML} ML, private.if-coverage-not-good-error ML, % TODO: check we never define the superclass of an exising class if-verbose (coq.say {header} "start module" Module), log.coq.env.begin-module Module none, private.declare-class+structure MLwP Sort ClassName Structure SortProjection ClassProjection Factories StructKeyClause, w-params.map MLwP (_\_\_\ mk-nil) NilwP, ClassAlias = (factory-alias->gref ClassName ClassName ok), CurrentClass = (class ClassName Structure MLwP), ClassName = indt ClassInd, coq.env.indt ClassInd _ _ _ _ [ClassK] _, GRDepsClauses = [gref->deps (indt ClassInd) NilwP, gref->deps (indc ClassK) MLwP], std.map ML (m\ o\ o = mixin-class m ClassName) MixinMems, std.filter ML (m\ not (mixin->first-class m _)) NewMixins, std.map NewMixins (m\ r\ r = mixin->first-class m ClassName) MixinFirstClass, if-verbose (coq.say {header} "structure: new mixins" NewMixins), if-verbose (coq.say {header} "structure: mixin first class" MixinFirstClass), if-verbose (coq.say {header} "declaring clone abbreviation"), w-params.then MLwP phant.fun-real phant.fun-real (private.clone-phant-body ClassName SortProjection Structure) PhClone, phant.add-abbreviation "clone" PhClone _ _, if-verbose (coq.say {header} "declaring pack_ constant"), (ClassAlias => class-def CurrentClass => GRDepsClauses => MixinMems => w-params.then MLwP mk-fun mk-fun (private.pack-body ClassName) Pack), if-verbose (coq.say {header} "declaring pack_ constant =" Pack), log.coq.env.add-const-noimplicits "pack_" Pack _ @transparent! ConstPack, GRPack = const ConstPack, if-arg-sort ( if-verbose (coq.say {header} "define arg_sort"), std.assert-ok! (coq.typecheck SortProjection SortProjTy) "HB: BUG: cannot retype projection", log.coq.env.add-const-noimplicits "arg_sort" SortProjection SortProjTy ff ArgSortCst ), if-verbose (coq.say {header} "start module Exports"), log.coq.env.begin-module "Exports" none, %(ClassAlias => class-def CurrentClass => % GRDepsClauses => MixinFirstClass => gref->deps GRPack MLwP => % phant.of-gref tt GRPack [] PhRepack), %if-verbose (coq.say {header} "declaring pack abbreviation =" PhRepack), % phant.add-abbreviation "pack" PhRepack _ PackAbbrev, if (get-option "short.type" ShortType) ( if-verbose (coq.say {header} "short name for type:" ShortType), (@global! => log.coq.notation.add-abbreviation ShortType 0 (global Structure) ff _)) true, coq.mk-app (global Structure) {coq.mk-n-holes {w-params.nparams MLwP}} HB_Instance, if (get-option "short.pack" ShortPack) (std.do! [ if-verbose (coq.say {header} "declaring pack abbreviation:" ShortPack), % coq.notation.abbreviation-body PackAbbrev NPackAbbrev PackAbbrevTrm, % @global! => log.coq.notation.add-abbreviation % ShortPack NPackAbbrev PackAbbrevTrm ff _ coq.notation.add-abbreviation-for-tactic ShortPack "HB.pack_for" [trm HB_Instance] ]) true, % (std.do! [ % PackAbbrevName is Module ^ ".pack", % if-verbose (coq.say {header} "declaring pack abbreviation:" PackAbbrevName), % coq.notation.add-abbreviation-for-tactic PackAbbrevName "HB.pack_for" [trm HB_Instance], %]), if-verbose (coq.say {header} "making coercion from type to target"), synthesis.infer-coercion-tgt MLwP CoeClass, if-arg-sort (private.declare-sort-coercion CoeClass Structure (global (const ArgSortCst))), private.declare-sort-coercion CoeClass Structure SortProjection, if-verbose (coq.say {header} "exporting unification hints"), ClassAlias => Factories => GRDepsClauses => private.declare-unification-hints SortProjection ClassProjection CurrentClass NewJoins, % Register in Elpi's DB the new structure % NOT TODO: All these acc are correctly locaed in an Export Module if (ClassName = indt ClassInd) (std.do![ if-verbose (coq.say {header} "exporting coercions from class to mixins"), std.forall {coq.env.projections ClassInd} (private.export-mixin-coercion ClassName) ]) (coq.say "declare:" ClassName "should be an inductive", fail), if-verbose (coq.say {header} "accumulating various props"), std.flatten [ Factories, [is-structure Structure], NewJoins, [class-def CurrentClass], GRDepsClauses, [gref->deps GRPack MLwP], MixinMems, [StructKeyClause] ] NewClauses, acc-clauses current NewClauses, if-verbose (coq.say {header} "stop module Exports"), log.coq.env.end-module-name "Exports" Exports, log.coq.env.import-module "Exports" Exports, if-verbose (coq.say {header} "declaring on_ abbreviation"), private.mk-infer-key CoeClass ClassProjection NilwP (global Structure) PhClass, phant.add-abbreviation "on_" PhClass _ ClassOfAbbrev, (pi c\ coq.notation.abbreviation ClassOfAbbrev [c] (ClassOfAbbrev_ c)), if-verbose (coq.say {header} "declaring `copy` abbreviation"), coq.mk-app (global ClassName) {params->holes NilwP} AppClassHoles, @global! => log.coq.notation.add-abbreviation "copy" 2 {{fun T C => (lp:(ClassOfAbbrev_ C) : (lp:AppClassHoles T)) }} tt _, if-verbose (coq.say {header} "declaring on abbreviation"), @global! => log.coq.notation.add-abbreviation "on" 1 {{fun T => (lp:{{ ClassOfAbbrev_ {{_}} }} : (lp:AppClassHoles T)) }} tt _OnAbbrev, log.coq.env.end-module-name Module ModulePath, if-verbose (coq.say {header} "end modules; export" Exports), export.module {calc (Module ^ ".Exports")} Exports, if-verbose (coq.say {header} "exporting operations"), ClassAlias => Factories => GRDepsClauses => private.export-operations Structure SortProjection ClassProjection MLwP [] EX MLToExport, % TODO: issue an Arguments op T : rename, where T is the name written by % the user in Definition foo := { T of ... } if-verbose (coq.say {header} "operations meta-data module: ElpiOperations"), ElpiOperationModName is {calc (Module ^ "ElpiOperations")}, log.coq.env.begin-module ElpiOperationModName none, acc-clauses current {std.append EX MixinFirstClass}, log.coq.env.end-module-name ElpiOperationModName ElpiOperations, export.module ElpiOperationModName ElpiOperations, if-verbose (coq.say {header} "abbreviation factory-by-classname"), ClassAlias => NewClauses => factory.declare-abbrev Module (factory.by-classname ClassName) ClassAbbrev, export.clause (phant-abbrev ClassName ClassName ClassAbbrev), NewClauses => if-MC-compat (private.mc-compat-structure Module ModulePath MLToExport {w-params.nparams MLwP} ClassProjection GRPack), % Automatic saturation disabled since it is expensive % NewClauses => instance.saturate-instances, ]. /* ------------------------------------------------------------------------- */ /* ----------------------------- private code ------------------------------ */ /* ------------------------------------------------------------------------- */ namespace private { shorten coq.{ term->gref, subst-fun, safe-dest-app, mk-app, mk-eta, subst-prod }. % const Po : forall p1 .. pm T m1 .. mn, Extra (Eg Extra = forall x y, x + y = y + z) % const C : forall p1 .. pm s, Extra % Po P1 .. PM T M1 .. MN PoArgs -> C P1 .. PM S PoArgs pred clean-op-ty i:list prop, i:term, i:term, o:term. clean-op-ty [] _ T1 T2 :- copy T1 T2. clean-op-ty [exported-op _ Po C|Ops] S T1 T2 :- gref->deps (const Po) MLwP, w-params.nparams MLwP NParams, std.length {list-w-params_list MLwP} NMixins, (pi L L1 L2 Params Rest PoArgs\ copy (app [global (const Po)| L]) (app [global (const C) | L2]) :- !, std.split-at NParams L Params [_|Rest], std.drop NMixins Rest PoArgs, std.append Params [S|PoArgs] L1, std.map L1 copy L2) => clean-op-ty Ops S T1 T2. pred operation-body-and-ty i:list prop, i:constant, i:structure, i:term, i:term, i:list term, i:term, i:w-args A, o:pair term term. operation-body-and-ty EXI Poperation Struct Psort Pclass Params _T (triple _ ParamsOp _) (pr Bo Ty) :- std.do! [ mk-app (global Struct) Params StructType, mk-app Psort Params PsortP, mk-app Pclass Params PclassP, Bo = fun `s` StructType Body, Ty = prod `s` StructType BodyTy, (@pi-decl `s` StructType s\ sigma Carrier Class\ std.do! [ mk-app PsortP [s] Carrier, mk-app PclassP [s] Class, synthesis.under-mixin-src-from-factory.do! Carrier Class [ % just in case.. synthesis.infer-all-gref->deps ParamsOp Carrier (const Poperation) (Body s), std.assert-ok! (coq.typecheck (Body s) (DirtyTy s)) "export-1-operation: Body illtyped", clean-op-ty EXI s (DirtyTy s) (BodyTy s), ], ]), ]. % given an operation (a mixin projection) we generate a constant projection the % same operation out of the package structure (out of the class field of the % structure). We also provide all the other mixin dependencies (other misins) % of the package structure. pred export-1-operation i:mixinname, i:structure, i:term, i:term, i:one-w-params mixinname, i:option constant, i:list prop, o:list prop. export-1-operation _ _ _ _ _ none EX EX :- !. % not a projection, no operation export-1-operation M Struct Psort Pclass MwP (some Poperation) EXI EXO :- !, std.do! [ coq.gref->id (const Poperation) Name, w-params.then MwP mk-fun-prod ignore (operation-body-and-ty EXI Poperation Struct Psort Pclass) (pr Body BodyTy), if-verbose (coq.say {header} "export operation" Name), log.coq.env.add-const-noimplicits Name Body BodyTy @transparent! C, w-params.nparams MwP NP, NImplicits is NP + 1, std.iota NImplicits INI, std.map INI (_\r\ r = maximal) Implicits, @global! => log.coq.arguments.set-implicit (const C) [Implicits], EXO = [exported-op M Poperation C|EXI] ]. % Given a list of mixins, it exports all operations in there pred export-operations.aux i:structure, i:term, i:term, i:one-w-params mixinname, i:list prop, o:list prop. export-operations.aux Struct ProjSort ProjClass MwP EX1 EX2 :- !, std.do! [ w-params_1 MwP (indt M), coq.env.projections M Poperations, std.fold Poperations EX1 (export-1-operation (indt M) Struct ProjSort ProjClass MwP) EX2, ]. pred mixin-not-already-declared i:one-w-params mixinname. mixin-not-already-declared MwP :- w-params_1 MwP M, not(mixin->first-class M _), M = indt _. pred export-operations i:structure, i:term, i:term, i:mixins, i:list prop, o:list prop, o:list mixinname. export-operations Structure ProjSort ProjClass MLwP EX1 EX2 MLToExport :- std.do! [ distribute-w-params MLwP LMwP, std.filter LMwP mixin-not-already-declared LMwPToExport, std.fold LMwPToExport EX1 (export-operations.aux Structure ProjSort ProjClass) EX2, std.map LMwPToExport w-params_1 MLToExport, ]. pred mk-coe-class-body i:factoryname, % From class i:factoryname, % To class i:mixins, % To mixins i:list term, i:term, % Params, T i:list (w-args mixinname), o:term. mk-coe-class-body FC TC TMLwP Params T _ CoeBody :- std.do! [ mk-app (global FC) {std.append Params [T]} Class, list-w-params_list TMLwP TML, std.map TML (from FC) Builders, std.map Builders (x\r\mk-app (global x) Params r) BuildersP, factory->nparams TC TCNP, mk-app (global {get-constructor TC}) {coq.mk-n-holes TCNP} KCHoles, (pi c\ sigma Mixes\ std.map BuildersP (builder\r\ r = app[builder, T, c]) Mixes, mk-app KCHoles [T | Mixes] (ClassCoercion c)), CoeBody = {{ fun (c : lp:Class) => lp:(ClassCoercion c) }} ]. pred mk-coe-structure-body i:structure, % From structure i:structure, % To structure i:factoryname, % To factory (for nparams) i:term, % class coercion i:term, % sort projection i:term, % class projection i:list term, i:term, % Params, T i:list (w-args mixinname), o:term. mk-coe-structure-body StructureF StructureT TC Coercion SortProjection ClassProjection Params _T _ SCoeBody :- std.do! [ mk-app (global StructureF) Params StructureP, mk-app SortProjection Params SortP, mk-app ClassProjection Params ClassP, mk-app Coercion Params CoercionP, factory->nparams TC TCNP, mk-app (global {get-constructor StructureT}) {coq.mk-n-holes TCNP} PackPH, SCoeBody = {{ fun s : lp:StructureP => (* let T := lp:SortP s in*) lp:PackPH (lp:SortP s) (lp:CoercionP (lp:SortP s) (lp:ClassP s)) }}, ]. % [declare-coercion P1 P2 C1 C2] declares a structure and a class coercion % from C1 to C2 given P1 P2 the two projections from the structure of C1 pred declare-coercion i:term, i:term, i:hbclass, i:hbclass. declare-coercion SortProjection ClassProjection (class FC StructureF FMLwP) (class TC StructureT TMLwP) :- std.do! [ gref->modname StructureF 2 "_" ModNameF, gref->modname StructureT 2 "_" ModNameT, CName is ModNameF ^ "_class__to__" ^ ModNameT ^ "_class", SName is ModNameF ^ "__to__" ^ ModNameT, if-verbose (coq.say {header} "declare coercion" SName), w-params.then FMLwP mk-fun mk-fun (mk-coe-class-body FC TC TMLwP) CoeBody, ErrorMessage is "The structures " ^ ModNameF ^ " and " ^ ModNameT ^ " are incompatible: the coercion between them cannot be synthesized", std.assert-ok! (coq.elaborate-skeleton CoeBody Ty CoeBody') ErrorMessage, if-verbose (coq.say {header} "declare coercion hint" CName), log.coq.env.add-const-noimplicits CName CoeBody' Ty @transparent! C, log.coq.coercion.declare (coercion (const C) 1 FC (grefclass TC)), Coercion = global (const C), w-params.then FMLwP mk-fun ignore (mk-coe-structure-body StructureF StructureT TC Coercion SortProjection ClassProjection) SCoeBody, ErrorMessage is "The structures " ^ ModNameF ^ " and " ^ ModNameT ^ " are incompatible: the coercion between them cannot be synthesized", std.assert-ok! (coq.elaborate-skeleton SCoeBody STy SCoeBody') ErrorMessage, if-verbose (coq.say {header} "declare unification hint" SName), log.coq.env.add-const-noimplicits SName SCoeBody' STy @transparent! SC, log.coq.coercion.declare (coercion (const SC) 0 StructureF (grefclass StructureT)), log.coq.CS.declare-instance SC, w-params.nparams FMLwP NparamsSC, acc-clause current (sub-class FC TC SC NparamsSC) ]. pred join-body i:int, i:int, i:structure, i:term, i:term, i:term, i:term, i:term, i:list term, i:name, i:term, i:(term -> A), o:term. join-body N1 N2 S3 S2_Pack S1_sort S3_to_S1 S2_class S3_to_S2 P N _Ty _F (fun N S3P Pack) :- !, mk-app (global S3) P S3P, !, @pi-decl N S3P s\ sigma S3_to_S1_Ps S3_to_S2_Ps S1_sortS3Ps S2_classS3Ps Holes1 Holes2 \ std.do! [ coq.mk-n-holes N2 Holes2, coq.mk-n-holes N1 Holes1, mk-app S3_to_S1 {std.append P [s]} S3_to_S1_Ps, mk-app S1_sort {std.append Holes1 [S3_to_S1_Ps]} S1_sortS3Ps, mk-app S3_to_S2 {std.append P [s]} S3_to_S2_Ps, mk-app S2_class {std.append Holes2 [S3_to_S2_Ps]} S2_classS3Ps , mk-app S2_Pack {std.append Holes2 [S1_sortS3Ps, S2_classS3Ps]} (Pack s) ]. pred declare-join i:hbclass, i:pair hbclass hbclass, o:prop. declare-join (class C3 S3 MLwP3) (pr (class C1 S1 _) (class C2 S2 _)) (join C1 C2 C3) :- Name is "join_" ^ {gref->modname S3 2 "_"} ^ "_between_" ^ {gref->modname S1 2 "_"} ^ "_and_" ^ {gref->modname S2 2 "_"}, get-structure-coercion S3 S2 S3_to_S2, get-structure-coercion S3 S1 S3_to_S1, get-structure-sort-projection S1 S1_sort, get-structure-class-projection S2 S2_class, get-constructor S2 S2_Pack, factory->nparams C1 N1, factory->nparams C2 N2, if-verbose (coq.say {header} "declare unification hint" Name), w-params.fold MLwP3 mk-fun (join-body N1 N2 S3 (global S2_Pack) S1_sort S3_to_S1 S2_class S3_to_S2) JoinBody, std.assert-ok! (coq.typecheck JoinBody Ty) "declare-join: JoinBody illtyped", log.coq.env.add-const-noimplicits Name JoinBody Ty @transparent! J, log.coq.CS.declare-instance J. % TODO: this works under the invariant: we never have two classes that % contain exactly the same mixins. HB.structure should enforce this % and eventually just alias the existing one rather than failing. % TODO: HB.structure should check we are not inserting the class % in the middle of existing ones. Possible fix: always declare all intermediate % possibilities but without proper names (requires the previous TODO about % aliasing already existing stuff). pred declare-unification-hints i:term, i:term, i:hbclass, o:list prop. declare-unification-hints SortProj ClassProj CurrentClass NewJoins :- std.do! [ findall-classes All, std.filter All (sub-class? CurrentClass) AllSuper, std.forall AllSuper (declare-coercion SortProj ClassProj CurrentClass), findall-newjoins CurrentClass AllSuper TodoJoins, std.map TodoJoins (declare-join CurrentClass) NewJoins ]. % For each mixin we declare a field and apply the mixin to its dependencies % (that are previously declared fields recorded via field-for-mixin) pred synthesize-fields i:term, i:list (w-args mixinname), o:record-decl. synthesize-fields _T [] end-record. synthesize-fields T [triple M Args _|ML] (field _ Name MTy Fields) :- std.do! [ Name is {gref->modname M 2 "_"} ^ "_mixin", if-verbose (coq.say {header} "typing class field" M), std.assert! (synthesis.infer-all-gref->deps Args T M MTy) "anomaly: a field type cannot be solved", @pi-decl `m` MTy m\ mixin-src T M m => synthesize-fields T ML (Fields m) ]. pred synthesize-fields.body i:list term, i:term, i:list (w-args mixinname), o:indt-decl. synthesize-fields.body _Params T ML (record "axioms_" {{ Type }} "Class" FS) :- synthesize-fields T ML FS. pred mk-record+sort-field i:sort, i:name, i:term, i:(term -> record-decl), o:indt-decl. mk-record+sort-field Sort _ T F (record "type" (sort Sort) "Pack" (field _ "sort" T F)). pred mk-class-field i:classname, i:list term, i:term, i:list (w-args mixinname), o:record-decl. mk-class-field ClassName Params T _ (field [canonical ff] "class" (app [global ClassName|Args]) _\end-record) :- std.append Params [T] Args. % Builds the axioms record and the factories from this class to each mixin pred declare-class+structure i:mixins, i:sort, o:factoryname, o:structure, o:term, o:term, o:list prop, o:prop. declare-class+structure MLwP Sort (indt ClassInd) (indt StructureInd) SortProjection ClassProjection AllFactories (structure-key SortP ClassP (indt StructureInd)):- std.do! [ if-verbose (coq.say {header} "declare axioms record"MLwP ), % TODO: enhance elpi-typechecker to deduce the type of `mk-parameter explicit` from the argmuments % passed to w-params.then w-params.then MLwP (mk-parameter explicit : (pred i:name, i:term, i:(term -> indt-decl), o:indt-decl)) (mk-parameter explicit) synthesize-fields.body ClassDeclaration, std.assert-ok! (coq.typecheck-indt-decl ClassDeclaration) "declare-class: illtyped", (@primitive! => log.coq.env.add-indt ClassDeclaration ClassInd), coq.env.projections ClassInd Projs, % TODO: put this code in a named clause w-params.nparams MLwP NParams, std.map2 {list-w-params_list MLwP} Projs (m\ p\ r\ sigma P\ std.assert! (p = some P) "BUG: we build a class with an anonymous field", r = from (indt ClassInd) m (const P)) Factories, AllFactories = [factory->nparams (indt ClassInd) NParams | Factories], if-verbose (coq.say {header} "declare type record"), w-params.then MLwP (mk-parameter explicit : (pred i:name, i:term, i:(term -> indt-decl), o:indt-decl)) (mk-record+sort-field Sort) (mk-class-field (indt ClassInd)) StructureDeclaration, std.assert-ok! (coq.typecheck-indt-decl StructureDeclaration) "declare: illtyped", if (get-option "primitive" tt) (@primitive! => log.coq.env.add-indt StructureDeclaration StructureInd) (log.coq.env.add-indt StructureDeclaration StructureInd), coq.env.projections StructureInd [some SortP, some ClassP], global (const SortP) = SortProjection, global (const ClassP) = ClassProjection, ]. % Declares "sort" as a Coercion Proj : Structurename >-> CoeClass. pred declare-sort-coercion i:class, i:structure, i:term. declare-sort-coercion CoeClass StructureName (global Proj) :- if-verbose (coq.say {header} "declare sort coercion"), log.coq.coercion.declare (coercion Proj 0 StructureName CoeClass). pred if-class-already-exists-error i:id, i:list hbclass, i:list mixinname. if-class-already-exists-error _ [] _. if-class-already-exists-error N [class _ S ML1wP|CS] ML2 :- list-w-params_list ML1wP ML1, if (std.list-eq-set ML1 ML2) (coq.error "Structure" {nice-gref->string S} "contains the same mixins as" N) (if-class-already-exists-error N CS ML2). pred export-mixin-coercion i:classname, i:option constant. export-mixin-coercion _ none. export-mixin-coercion ClassName (some C) :- coq.env.typeof (const C) CTy, coq.prod-tgt->gref CTy MixinGR, if-verbose (coq.say {header} "export class to mixin coercion for mixin" {nice-gref->string MixinGR}), log.coq.coercion.declare (coercion (const C) _ ClassName (grefclass MixinGR)). pred mc-compat-structure i:string, i:modpath, i:list mixinname, i:int, i:term, i:gref, i:option gref. mc-compat-structure ModuleName _Module NewMixins CNParams ClassProjection GRPack Axioms :- std.do! [ CompatModuleName is "MathCompCompat" ^ ModuleName, log.coq.env.begin-module CompatModuleName none, % to avoid collisions log.coq.env.begin-module ModuleName none, if (Axioms = some GR) (@global! => log.coq.notation.add-abbreviation "axiom" 0 (global GR) ff _) true, if (NewMixins = [NewMixin]) (std.do! [ if-verbose (coq.say "mc-compat-structure: declaring notations 'axioms', 'mixin_of' and 'Mixin'"), factory->nparams NewMixin NewMixinNP, MArgs is NewMixinNP + 1, mk-eta MArgs {coq.env.typeof NewMixin} (global NewMixin) EtaNewMixin, @global! => log.coq.notation.add-abbreviation "axioms" MArgs EtaNewMixin ff _, @deprecated! "mathcomp 2.0.0" "use the factory instead" => @global! => log.coq.notation.add-abbreviation "mixin_of" MArgs EtaNewMixin ff _, std.assert! (factory->constructor NewMixin FK) "BUG: Factory constructor missing", std.assert! (phant-abbrev FK _ PhAbb) "BUG: missing phant-abbrev", @deprecated! "mathcomp 2.0.0" "use the F.Build instead" => @global! => log.coq.notation.add-abbreviation "Mixin" 0 {coq.notation.abbreviation PhAbb {coq.mk-n-holes MArgs}} ff _, if-verbose (coq.say "mc-compat-structure: declaring pack abbreviation"), @deprecated! "mathcomp 2.0.0" "use native HB Structure.pack instead" => phant.add-abbreviation "mcpack" {phant.of-gref ff GRPack [NewMixin]} _ _, ]) (if-verbose (coq.say "mc-compat-structure: not exactly one new mixin")), if-verbose (coq.say "mc-compat-structure: declaring notation 'class_of'"), std.assert-ok! (coq.typecheck ClassProjection ClassProjectionTy) "wtf", CArgs is CNParams + 1, mk-eta CArgs ClassProjectionTy ClassProjection EtaClassProjection, @global! => log.coq.notation.add-abbreviation "class_of" CArgs EtaClassProjection ff _, log.coq.env.end-module-name ModuleName _, log.coq.env.end-module-name CompatModuleName MCCompat, log.coq.env.export-module CompatModuleName MCCompat, %coq.env.import-module Module, ]. pred clone-phant-body i:factoryname, i:term, i:structure, i:list term, i:term, i:list (w-args mixinname), o:phant-term. clone-phant-body ClassName SortProjection ((indt I) as Structure) PL T _ PhF :- std.do! [ std.assert! (coq.env.indt I _ _ _ _ [PackC] _) "wtf", mk-app (global (indc PackC)) {std.append PL [T]} PackPLT, mk-app (global Structure) PL SPL, (@pi-decl `cT` SPL cT\ mk-app (global ClassName) {std.append PL [T]} CPL, @pi-decl `c` CPL c\ (Ph cT c) = {phant.fun-unify none T {mk-app {mk-app SortProjection PL} [cT]} {phant.fun-unify none cT {mk-app PackPLT [c]} {phant.init {mk-app PackPLT [c]}} }}), PhF = {phant.fun-real `cT` SPL cT\ {phant.fun-implicit `c` CPL c\ Ph cT c }} ]. % [pack-body ClassName P T MLwA B] asserts % B = fun m0 ... mn => Pack P T (Class P T m0 ... mn) % under a context with P and T pred pack-body i:classname, i:list term, i:term, i:list (w-args mixinname), o:term. pack-body ClassName PL T MLwA F :- std.do! [ class-def (class ClassName S _), get-constructor ClassName BuildC, get-constructor S PackS, synthesis.under-mixins.then MLwA mk-fun (pack-body.aux PL T BuildC PackS) F, ]. pack-body.aux PL T BuildC PackS Body :- !, std.do! [ synthesis.infer-all-gref->deps PL T BuildC Class, mk-app (global PackS) {std.append PL [T, Class]} Body ]. pred mk-infer-key i:class, i:term, i:mixins, i:term, o:phant-term. mk-infer-key CoeClass K (w-params.nil ID _ _) St PhK :- @pi-parameter ID St t\ phant.init {mk-app K [t]} (PhKBo t), phant.fun-infer-type CoeClass {coq.id->name ID} St PhKBo PhK. mk-infer-key CoeClass K (w-params.cons ID Ty W) St R :- @pi-parameter ID Ty t\ mk-infer-key CoeClass {mk-app K [t]} (W t) {mk-app St [t]} (PhT t), phant.fun-implicit {coq.id->name ID} Ty PhT R. pred if-coverage-not-good-error i:list mixinname. if-coverage-not-good-error ML :- coq.gref.list->set ML MS, std.forall ML (if-coverage-not-good-error.one MS). pred if-coverage-not-good-error.one i:coq.gref.set, i:mixinname. if-coverage-not-good-error.one MS M :- mixin->first-class M C, !, class-coverage [C] CMS, if (coq.gref.set.subset CMS MS) true (coq.gref.set.elements {coq.gref.set.remove M CMS} MissinFromCurrent, coq.error "HB: the first structure declared in this hierarchy containing" {nice-gref->string M} "is" {nice-gref->string C} "which also contains" {std.map MissinFromCurrent nice-gref->string} "." "\nThe are two ways to fix this problem:" "1) change the current structure to contain" {std.map MissinFromCurrent nice-gref->string} "as well;" "2) amend the hierarchy by declaring a structure before" {nice-gref->string C} "which contains at most" {std.map {coq.gref.set.elements {coq.gref.set.inter CMS MS}} nice-gref->string}). if-coverage-not-good-error.one _ _. % new class is the first covering M pred product->triples i:term, o:list (w-args factoryname), o:bool. product->triples {{ lib:hb.prod lp:A lp:B }} L ClosureCheck :- !, product->triples B GRB ClosureCheck, product->triples A GRA _, std.append GRA GRB L. product->triples {{ True }} [] tt :- !. product->triples {{ False }} [] ff :- !. product->triples A [GR] tt :- std.assert! (factory? A GR) "A structure can only mention known factories". pred sigT->list-w-params i:term, o:list-w-params factoryname, o:bool. sigT->list-w-params (fun N T B) L C :- coq.name->id N ID, % TODO: we should read the ID from the definition type which is an arity containing ids L = w-params.cons ID T Rest, @pi-decl N T p\ sigT->list-w-params (B p) (Rest p) C. sigT->list-w-params {{ lib:@hb.sigT _ lp:{{ fun N Ty B }} }} L C :- coq.name->id N ID, % TODO: we should read the ID from the definition type which is an arity containing ids L = w-params.nil ID Ty Rest, @pi-decl N Ty t\ product->triples (B t) (Rest t) C. }} math-comp-hierarchy-builder-4d8a939/HB/structures.v000066400000000000000000001314471521677141400222730ustar00rootroot00000000000000(* Support constants, to be kept in sync with shim/structures.v *) From Corelib Require Import ssreflect ssrfun. Add Search Blacklist "Builders_". Add Search Blacklist "__canonical__". Add Search Blacklist "__to__". Add Search Blacklist "_between_". Add Search Blacklist "_mixin". Variant error_msg := NoMsg | IsNotCanonicallyA (x : Type). Definition unify T1 T2 (t1 : T1) (t2 : T2) (s : error_msg) := phantom T1 t1 -> phantom T2 t2. Definition id_phant {T} {t : T} (x : phantom T t) := x. Definition id_phant_disabled {T T'} {t : T} {t' : T'} (x : phantom T t) := Phantom T' t'. Definition nomsg : error_msg := NoMsg. Definition is_not_canonically_a x := IsNotCanonicallyA x. Definition new {T} (x : T) := x. Definition eta {T} (x : T) := x. Definition ignore {T} (x: T) := x. Definition ignore_disabled {T T'} (x : T) (x' : T') := x'. (* ********************* structures ****************************** *) From elpi Require Import elpi. Register unify as hb.unify. Register id_phant as hb.id. Register id_phant_disabled as hb.id_disabled. Register ignore as hb.ignore. Register ignore_disabled as hb.ignore_disabled. Register Corelib.Init.Datatypes.None as hb.none. Register nomsg as hb.nomsg. Register is_not_canonically_a as hb.not_a_msg. Register Corelib.Init.Datatypes.Some as hb.some. Register Corelib.Init.Datatypes.pair as hb.pair. Register Corelib.Init.Datatypes.prod as hb.prod. Register Corelib.Init.Specif.sigT as hb.sigT. Register Corelib.ssr.ssreflect.phant as hb.phant. Register Corelib.ssr.ssreflect.Phant as hb.Phant. Register Corelib.ssr.ssreflect.phantom as hb.phantom. Register Corelib.ssr.ssreflect.Phantom as hb.Phantom. Register Corelib.Init.Logic.eq as hb.eq. Register Corelib.Init.Logic.eq_refl as hb.erefl. Register new as hb.new. Register eta as hb.eta. #[deprecated(since="HB 1.0.1", note="use #[key=...] instead")] Notation indexed T := T (only parsing). Declare Scope HB_scope. Notation "{ A 'of' P & .. & Q }" := (sigT (fun A => (prod P .. (prod Q True) ..)%type)) (at level 0, A at level 99) : HB_scope. Notation "{ A 'of' P & .. & Q & }" := (sigT (fun A => (prod P .. (prod Q False) ..)%type)) (at level 0, A at level 99) : HB_scope. Global Open Scope HB_scope. (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (** This data represents the hierarchy and some other piece of state to implement the commands of this file *) #[interp] Elpi Db hb.db lp:{{ typeabbrev mixinname gref. typeabbrev classname gref. typeabbrev factoryname gref. typeabbrev structure gref. typeabbrev (w-args A) (triple A (list term) term). kind w-params type -> type. type w-params.cons id -> term -> (term -> w-params A) -> w-params A. type w-params.nil id -> term -> (term -> A) -> w-params A. typeabbrev (list-w-params A) (w-params (list (w-args A))). typeabbrev (one-w-params A) (w-params (w-args A)). typeabbrev mixins (list-w-params mixinname). typeabbrev factories (list-w-params mixinname). typeabbrev (w-mixins A) (pair mixins (w-params A)). %%%%% Classes %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % (class C S ML) represents a class C packed in S containing mixins ML. % Example: % % HB.mixin Record IsZmodule V := { ... } % HB.mixin Record Zmodule_IsLmodule (R : ringType) V of Zmodule V := { ... } % HB.structure Definition Lmodule R := {M of Zmodule M & Zmodule_IsLmodule R M} % % The class description for Lmodule would be: % % class (indt «Lmodule.axioms») /* The record with all mixins */ % (indt «Lmodule.type») /* The record with sort and class */ % (w-params.cons "R" {{ Ring.type }} P \ /* The first parameter, named "R" */ % w-params.nil "M" {{ Type }} T \ /* The key of the structure */ % [..., /* deps of IsZmodule.mixin */ % triple (indt «IsZmodule.mixin») [] T, /* a mixins with its params */ % triple (indt «Zmodule_IsLmodule.mixin») [P] T ]) /* another mixins */ % % If some mixin parameters depend on other mixins (through a canonical instance that % can be inferred from them). Since our structure does not account for dependencies % between mixins (the list in the end is flat), we compensate by replacing canonical % instances by calls to `S.Pack T {{lib:elpi.hole}}`, and extending the reconstruction % mecanism of mixins to also reinfer these holes. kind hbclass type. type class classname -> structure -> mixins -> hbclass. % class-def contains all the classes ever declared pred class-def o:hbclass. %%%%% Builders %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [from FN MN F] invariant: % "F : forall p1 .. pn T LMN, FN p1 .. pn T LMN1 -> MN c1 .. cm T LMN2" where % - LMN1 and LMN2 are sub lists of LMN % - c1 .. cm are terms built using p1 .. pn and T % - [factory-requires FN LMN] % [from _ M _] tests whether M is a declared mixin. pred from o:factoryname, o:mixinname, o:gref. %%%%% Abbreviations %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [phant-abbrev Cst AbbrevCst Abbrev] % Stores phantom abbreviation Abbrev associated with Cst % AbbrevCst is the constant that serves as support % e.g. Definition AbbrevCst := fun t1 t2 (phant_id t1 t2) => Cst t2. % Notation Abbrev t1 := (AbbrevCst t1 _ idfun). pred phant-abbrev o:gref, o:gref, o:abbreviation. % [factory-alias->gref X GR] when X is already a factory X = GR % however, when X is a phantom abbreviated gref, we find the underlying % factory gref GR associated to it. func factory-alias->gref gref -> gref, diagnostic. factory-alias->gref PhGR GR ok :- phant-abbrev GR PhGR _, !. factory-alias->gref GR GR ok :- phant-abbrev GR _ _, !. factory-alias->gref GR _ (error Msg) :- !, Msg is {coq.term->string (global GR)} ^ " is not a factory or its library (" ^ { std.string.concat "." {std.drop-last 1 {coq.gref->path GR} } } ^ ") was not correctly imported". %%%%% Cache of known facts %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [factory->constructor F K] means K is a constructor for % the factory F. :index(2) func factory->constructor factoryname -> gref. % [factory->nparams F N] says that F has N parameters :index(2) func factory->nparams factoryname -> int. % [is-structure GR] tests if GR is a known structure pred is-structure o:gref. % [is-factory GR] tests if GR is a known factory pred is-factory o:gref. % [sub-class C1 C2 Coercion12 NparamsCoercion] C1 is a sub-class of C2, % see also sub-class? which computes it on the fly :index (2 2 1) pred sub-class o:classname, o:classname, o:constant, o:int. % [gref->deps GR MLwP] is a (pre computed) list of dependencies of a know global % constant. The list is topologically sorted :index(2) func gref->deps gref -> mixins. % [join C1 C2 C3] means that C3 inherits from both C1 and C2 pred join o:classname, o:classname, o:classname. % Section local memory of names for mixins, so that we can reuse them % and build terms with simpler conversion problems (less unfolding % in order to discover two mixins are the same) % @gares : is it really a func. Ideally I think so, bu we load mixin-mem via % `Clauses =>` in infer-class. Should perform a dynamic check? func mixin-mem term -> gref. %%%%%% Memory of exported mixins (HB.structure) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Operations (named mixin fields) need to be exported exactly once, % but the same mixin can be used in many structure, hence this memory % to keep the invariant. % Also we remember which is the first class/structure that includes % a given mixin, assuming the invariant that this first class is also % the minimal class that includes this mixin. % [mixin->first-class M C] states that C is the first/minimal class % that contains the mixin M :index(2) func mixin->first-class mixinname -> classname. % memory of exported operations (TODO: document fiels) pred exported-op o:mixinname, o:constant, o:constant. % memory of factory sort coercion pred factory-sort o:coercion. % memory of canonical projections for a structure (X.sort, X.class, X.type) pred structure-key o:constant, o:constant, o:structure. %%%%%% Membership of mixins to a class %%%%%%%%%%%%%%%% % [mixin-class M C] means M belongs to C pred mixin-class o:mixinname, o:classname. %% database for HB.context %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [mixin-src T M X] states that X can be used to reconstruct % an instance of the mixin [M T …], directly or through a builder. % Since HB.builders sections can declare canonical instances of % mixins that do not yet form a structure, we cannot resort to % Coq's CS database (which is just for structures). pred mixin-src o:term, o:mixinname, o:term. % [has-mixin-instance K M G] states that G is a reference to an instance % of mixin M for subject K pred has-mixin-instance o:cs-pattern, o:mixinname, o:gref. %% database for HB.builders %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [builder N TheFactory TheMixin S] is used to % remember that the user run [HB.instance S] hence [HB.end] has to % synthesize builders from TheFactory to TheMixin mixins generated by S. % N is a timestamp. kind builder type. type builder int -> factoryname -> mixinname -> gref -> builder. pred builder-decl o:builder. %% database for builder-local canonical instances %%%%%%%%%%%%%%%%%%%%%%% pred local-canonical o:constant. % To tell HB.end what we are doing kind declaration type. % TheType, TheFactory and it's name and the name of the module encloding all that type builder-from term -> term -> factoryname -> id -> declaration. type no-builder declaration. pred current-mode o:declaration. %% database for HB.export / HB.reexport %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % library, nice-name, object pred module-to-export o:string, o:id, o:modpath. pred instance-to-export o:string, o:id, o:constant. pred abbrev-to-export o:string, o:id, o:gref. pred clause-to-export o:string, o:prop. %% database for HB.locate and HB.about %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% pred decl-location o:gref, o:loc. % [docstring Loc Doc] links a location in the source text and some doc pred docstring o:loc, o:string. }}. (* This database is used by the parsing phase only *) #[synterp] Elpi Db export.db lp:{{ pred module-to-export o:string, o:modpath. }}. (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (** This is like Locate but tells you the file and line at which the constant or inductive was generated. *) #[arguments(raw)] Elpi Command HB.locate. Elpi Accumulate Db hb.db. (* Since it can become rather large, accumulating the DB is often by far the most expensive accumulation. It is then worth sharing its cache between the commands. To this end, we accumulate the DB first in each command to ensure the same dependencies and maximize cache hits. For instance, this can save a few (2 or 3) percents of total compilation time on MathComp. *) Elpi Accumulate lp:{{ :name "start" main [str S] :- !, if (decl-location {coq.locate S} Loc) (coq.say "HB: synthesized in file" Loc) (coq.say "HB" S "not synthesized by HB"). main _ :- coq.error "Usage: HB.locate .". }}. Elpi Typecheck. Elpi Export HB.locate. (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (** This is like About but understands HB generated stuff, namely - structures, eg Foo.type - classes, eg Foo - factories, eg Bar - factory constructors, eg Bar.Build - canonical projections, eg Foo.sort - canonical value, eg Z, prod, ... *) #[arguments(raw)] Elpi Command HB.about. Elpi Accumulate Db hb.db. Elpi Accumulate File "HB/common/stdpp.elpi". Elpi Accumulate File "HB/common/utils.elpi". Elpi Accumulate File "HB/common/database.elpi". Elpi Accumulate File "HB/common/compat_acc_clauses_all.elpi". Elpi Accumulate File "HB/common/log.elpi". Elpi Accumulate File "HB/common/compat_add_secvar_all.elpi". Elpi Accumulate File "HB/about.elpi". Elpi Accumulate lp:{{ :name "start" main [str S] :- !, with-attributes (with-logging (about.main S)). main _ :- coq.error "Usage: HB.about .". }}. Elpi Typecheck. Elpi Export HB.about. (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (** [HB.howto (T) Foo.type d] prints possible sequences of factories to equip a type [T] with a structure [Foo.type], taking into account structures already instantiated on [T]. The search depth [d] is the maximum length of the sequences, 3 by default. The first argument [T] is optional, when ommited [Foo.type] is built from scratch. Finally, the first argument can be another structure [Bar.type], in which case [Foo.type] is built starting from [Bar.type]. *) #[arguments(raw)] Elpi Command HB.howto. Elpi Accumulate Db hb.db. Elpi Accumulate File "HB/common/stdpp.elpi". Elpi Accumulate File "HB/common/database.elpi". Elpi Accumulate File "HB/common/compat_acc_clauses_all.elpi". Elpi Accumulate File "HB/common/compat_add_secvar_all.elpi". Elpi Accumulate File "HB/common/utils.elpi". Elpi Accumulate File "HB/common/log.elpi". Elpi Accumulate File "HB/about.elpi". Elpi Accumulate File "HB/howto.elpi". Elpi Accumulate lp:{{ :name "start" main [trm T, str STgt] :- !, with-attributes (with-logging (howto.main-trm T STgt none)). main [trm T, str STgt, int Depth] :- !, with-attributes (with-logging (howto.main-trm T STgt (some Depth))). main [str T, str STgt] :- !, with-attributes (with-logging (howto.main-str T STgt none)). main [str T, str STgt, int Depth] :- !, with-attributes (with-logging (howto.main-str T STgt (some Depth))). main [str STgt] :- !, with-attributes (with-logging (howto.main-from [] STgt none)). main [str STgt, int Depth] :- !, with-attributes (with-logging (howto.main-from [] STgt (some Depth))). main _ :- coq.error "Usage: HB.howto [()|] [].". }}. Elpi Typecheck. Elpi Export HB.howto. (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (** This command prints the status of the hierarchy (Debug) *) #[arguments(raw)] Elpi Command HB.status. Elpi Accumulate Db hb.db. Elpi Accumulate File "HB/common/stdpp.elpi". Elpi Accumulate File "HB/common/database.elpi". Elpi Accumulate File "HB/common/compat_acc_clauses_all.elpi". Elpi Accumulate File "HB/common/log.elpi". Elpi Accumulate File "HB/common/compat_add_secvar_all.elpi". Elpi Accumulate File "HB/common/utils.elpi". Elpi Accumulate File "HB/status.elpi". Elpi Accumulate lp:{{ :name "start" main [] :- !, status.print-hierarchy. main _ :- coq.error "Usage: HB.status.". }}. Elpi Typecheck. Elpi Export HB.status. (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (** This command prints the hierarchy to a dot file. You can use [[ tred file.dot | xdot - ]] to visualize file.dot *) #[arguments(raw)] Elpi Command HB.graph. Elpi Accumulate Db hb.db. Elpi Accumulate File "HB/common/stdpp.elpi". Elpi Accumulate File "HB/common/database.elpi". Elpi Accumulate File "HB/common/compat_acc_clauses_all.elpi". Elpi Accumulate File "HB/common/compat_add_secvar_all.elpi". Elpi Accumulate File "HB/common/utils.elpi". Elpi Accumulate File "HB/common/log.elpi". Elpi Accumulate File "HB/graph.elpi". Elpi Accumulate lp:{{ :name "start" main [str File] :- with-attributes (with-logging (graph.to-file File)). main _ :- coq.error "Usage: HB.graph .". }}. Elpi Typecheck. Elpi Export HB.graph. (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (** [HB.mixin] declares a mixin Syntax to create a mixin [MixinName] with requirements [Factory1] .. [FactoryN]: [[ HB.mixin Record MixinName T & Factory1 T & … & FactoryN T := { op : T -> … … property : forall x : T, op … … } ]] Synthesizes: - [MixinName T] abbreviation for the type of the (degenerate) factory - [MixinName.Build T] abbreviation for the constructor of the factory Note: [T & f1 T & … & fN T] is syntactic sugar for [T (_ : f1 T) … (_ : fN T)] Supported attributes: - [#[primitive]] experimental attribute to make the mixin/factory primitive, - [#[verbose]] for a verbose output. *) #[arguments(raw)] Elpi Command HB.mixin. Elpi Accumulate Db hb.db. Elpi Accumulate File "HB/common/stdpp.elpi". Elpi Accumulate File "HB/common/database.elpi". Elpi Accumulate File "HB/common/compat_acc_clauses_all.elpi". Elpi Accumulate File "HB/common/compat_add_secvar_all.elpi". Elpi Accumulate File "HB/common/utils.elpi". Elpi Accumulate File "HB/common/log.elpi". Elpi Accumulate File "HB/common/synthesis.elpi". Elpi Accumulate File "HB/common/phant-abbreviation.elpi". Elpi Accumulate File "HB/instance.elpi". Elpi Accumulate File "HB/context.elpi". Elpi Accumulate File "HB/export.elpi". Elpi Accumulate File "HB/factory.elpi". Elpi Accumulate lp:{{ :name "start" main [A] :- with-attributes (with-logging (factory.declare-mixin A)). }}. #[synterp] Elpi Accumulate File "HB/common/utils-synterp.elpi". #[synterp] Elpi Accumulate Db export.db. #[synterp] Elpi Accumulate lp:{{ shorten coq.env.{ begin-module, end-module, begin-section, end-section, export-module }. pred actions i:id. actions N :- begin-module N none, begin-section N, end-section, begin-module "Exports" none, end-module E, end-module _, export-module E, coq.env.current-library File, coq.elpi.accumulate current "export.db" (clause _ _ (module-to-export File E)). main [indt-decl D] :- record-decl->id D N, with-attributes (actions N). main _ :- coq.error "Usage: HB.mixin Record T & F A & … := { … }.". }}. Elpi Typecheck. Elpi Export HB.mixin. (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (** [HB.pack] and [HB.pack_for] are tactic-in-term synthesizing a structure instance. In the middle of a term, in a context expecting a [Structure.type], you can write [HB.pack T F] to use factory [F] to equip type [T] with [Structure]. If [T] is already a rich type, eg [T : OtherStructure.type] or if [T] is a global constant with canonical structure instances attached to it, then this piece of info is used to infer a [Structure]. If the context does not impose a [Structure.type] typing constraint, then you can use [HB.pack_for Structure.type T F]. You can pass zero or more factories like [F] but they must all typecheck in the current context (the type is not enriched progressively). Structure instances are projected to their class in order to obtain a factory. Examples: [[ pose Fa : IsSomething T := IsSomething.Build T ... pose A : A.type := HB.pack T Fa. pose Fb : IsMore A := IsMore.Build ... pose B := HB.pack_for B.type T A Fb. ]] If [Structure.type] as parameters [P1..Pn] then you should use [HB.pack T F1..Fn] or [HB.pack_for (Structure.type P1..Pn) T F1..Fn] *) Elpi Tactic HB.pack_for. Elpi Accumulate Db hb.db. Elpi Accumulate File "HB/common/stdpp.elpi". Elpi Accumulate File "HB/common/database.elpi". Elpi Accumulate File "HB/common/compat_acc_clauses_all.elpi". Elpi Accumulate File "HB/common/compat_add_secvar_all.elpi". Elpi Accumulate File "HB/common/utils.elpi". Elpi Accumulate File "HB/common/log.elpi". Elpi Accumulate File "HB/common/synthesis.elpi". Elpi Accumulate File "HB/pack.elpi". Elpi Accumulate lp:{{ :name "start" solve (goal _ _ S _ [trm Ty | Args] as G) GLS :- with-attributes (with-logging (std.do! [ pack.main Ty Args InstanceSkel, std.assert-ok! (coq.elaborate-skeleton InstanceSkel S Instance) "HB.pack_for: the instance does not solve the goal", log.refine.no_check Instance G GLS, ])). }}. Elpi Typecheck. Elpi Export HB.pack_for. Elpi Tactic HB.pack. Elpi Accumulate Db hb.db. Elpi Accumulate File "HB/common/stdpp.elpi". Elpi Accumulate File "HB/common/database.elpi". Elpi Accumulate File "HB/common/compat_acc_clauses_all.elpi". Elpi Accumulate File "HB/common/compat_add_secvar_all.elpi". Elpi Accumulate File "HB/common/utils.elpi". Elpi Accumulate File "HB/common/log.elpi". Elpi Accumulate File "HB/common/synthesis.elpi". Elpi Accumulate File "HB/pack.elpi". Elpi Accumulate lp:{{ :name "start" solve (goal _ _ Ty _ Args as G) GLS :- with-attributes (with-logging (std.do! [ pack.main Ty Args InstanceSkel, std.assert-ok! (coq.elaborate-skeleton InstanceSkel Ty Instance) "HB.pack: the instance does not solve the goal", log.refine.no_check Instance G GLS, ])). }}. Elpi Typecheck. Elpi Export HB.pack. (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (** [HB.structure] declares a packed structure. Syntax to declare a structure combing the axioms from [Factory1] … [FactoryN]. The second syntax has a trailing [&] to pull in factory requirements silently. [[ HB.structure Definition StructureName params := { A of Factory1 … A & … & FactoryN … A }. HB.structure Definition StructureName params := { A of Factory1 … A & … & FactoryN … A & }. ]] Synthesizes: - [StructureName A] the type of the class that regroups all the factories [Factory1 … A] … [FactoryN … A]. - [StructureName.type params] the structure type that packs together [A] and its class. - [StructureName.sort params] the first projection of the previous structure, - [StructureName.clone params T cT] a legacy repackaging function that eta expands the canonical [StructureName.type] of [T], using [cT] if provided. - [StructureName.class sT : StructureName sT] projects out the class of [sT : StructureName.type params], - [StructureName.copy T T' : StructureName T] returns the class of the canonical [StructureName.type] of [T], and gives it the type [Structure T]. It is thus ready to use in combination with HB.instance, as in [[ (* Cloning a structure from another one, given by the user *) HB.instance Definition _ := StructureName.copy T cT. ]] - [StructureName.on T : StructureName T] infers the class of the canonical [StructureName.type] of [T]. This is a shortcut for [StructureName.Copy T T], and it will succeeds if a reduction of [T] is canonically a [StructureName.type]. Disclaimer: any function other that the ones described above, including pattern matching (using Gallina [match], [let] or tactics ([case], [elim], etc)) is an internal and must not be relied upon. Also hand-crafted [Canonical] declarations of such structures will break the hierarchy. Use [HB.instance] instead. Supported attributes: - [#[mathcomp]] attempts to generate a backward compatibility layer with mathcomp: trying to infer the right [StructureName.pack], - [#[arg_sort]] defines an alias [StructureName.arg_sort] for [StructureName.sort], and declares it as the main coercion. [StructureName.sort] is still declared as a coercion but the only reason is to make sure Coq does not print it. Cf ##[fingroup.v]##. - [#[short(type="shortName")]] produces the abbreviation [shortName] for [Structure.type] - [#[short(pack="shortName")]] produces the abbreviation [shortName] for [HB.pack_for Structure.type] - [#[primitive]] experimental attribute to make the structure a primitive record, - [#[verbose]] for a verbose output. *) #[arguments(raw)] Elpi Command HB.structure. Elpi Accumulate Db hb.db. Elpi Accumulate File "HB/common/stdpp.elpi". Elpi Accumulate File "HB/common/database.elpi". Elpi Accumulate File "HB/common/compat_acc_clauses_all.elpi". Elpi Accumulate File "HB/common/compat_add_secvar_all.elpi". Elpi Accumulate File "HB/common/utils.elpi". Elpi Accumulate File "HB/common/log.elpi". Elpi Accumulate File "HB/common/synthesis.elpi". Elpi Accumulate File "HB/common/phant-abbreviation.elpi". Elpi Accumulate File "HB/export.elpi". Elpi Accumulate File "HB/instance.elpi". Elpi Accumulate File "HB/context.elpi". Elpi Accumulate File "HB/factory.elpi". Elpi Accumulate File "HB/structure.elpi". Elpi Accumulate lp:{{ :name "start" main [const-decl N (some B) Arity] :- std.do! [ % compute the universe for the structure (default ) prod-last {coq.arity->term Arity} Ty, if (ground_term Ty) (Sort = Ty) (Sort = {{Type}}), sort Univ = Sort, with-attributes (with-logging (structure.declare N B Univ)), ]. }}. #[synterp] Elpi Accumulate File "HB/common/utils-synterp.elpi". #[synterp] Elpi Accumulate Db export.db. #[synterp] Elpi Accumulate lp:{{ shorten coq.env.{ begin-module, end-module, begin-section, end-section, import-module, export-module }. pred actions i:id. actions N :- begin-module N none, begin-module "Exports" none, end-module E, import-module E, end-module _, export-module E, begin-module {calc (N ^ "ElpiOperations")} none, end-module O, export-module O, coq.env.current-library File, coq.elpi.accumulate current "export.db" (clause _ _ (module-to-export File E)), coq.elpi.accumulate current "export.db" (clause _ _ (module-to-export File O)), if (get-option "mathcomp" tt ; get-option "mathcomp.axiom" _) (actions-compat N) true. pred actions-compat i:id. actions-compat ModuleName :- CompatModuleName is "MathCompCompat" ^ ModuleName, begin-module CompatModuleName none, begin-module ModuleName none, end-module _, end-module O, export-module O, % is this a bug? % coq.env.current-library File, % coq.elpi.accumulate current "export.db" (clause _ _ (module-to-export File O)). true. main [const-decl N _ _] :- !, with-attributes (actions N). main _ :- coq.error "Usage: HB.structure Definition := { A of A & … & A }". }}. Elpi Typecheck. Elpi Export HB.structure. (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* [HB.saturate [key]] saturates all instances (of all known keys, if key is not given) w.r.t. the current hierarchy. When two (unrelated) files are imported it might be that the instances declared in one file are sufficient to instantiate structures declared in the other file. This command reconsiders all types with a canonical structure instance and see if the they are also equipped with new ones. *) #[arguments(raw)] Elpi Command HB.saturate. Elpi Accumulate Db hb.db. Elpi Accumulate File "HB/common/stdpp.elpi". Elpi Accumulate File "HB/common/database.elpi". Elpi Accumulate File "HB/common/compat_acc_clauses_all.elpi". Elpi Accumulate File "HB/common/compat_add_secvar_all.elpi". Elpi Accumulate File "HB/common/utils.elpi". Elpi Accumulate File "HB/common/log.elpi". Elpi Accumulate File "HB/common/synthesis.elpi". Elpi Accumulate File "HB/common/phant-abbreviation.elpi". Elpi Accumulate File "HB/export.elpi". Elpi Accumulate File "HB/instance.elpi". Elpi Accumulate File "HB/context.elpi". Elpi Accumulate File "HB/factory.elpi". Elpi Accumulate lp:{{ main [] :- !, with-attributes (with-logging (instance.saturate-instances _)). main [str "Type"] :- !, with-attributes (with-logging (instance.saturate-instances (cs-sort _))). main [str K] :- !, coq.locate K GR, with-attributes (with-logging (instance.saturate-instances (cs-gref GR))). main [trm T] :- !, term->cs-pattern T P, with-attributes (with-logging (instance.saturate-instances P)). main _ :- coq.error "Usage: HB.saturate [key]". }}. Elpi Typecheck. Elpi Export HB.saturate. (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (** [HB.instance] associates to a type all the structures that can be obtained from the provided factory inhabitant. Syntax for declaring a canonical instance: [[ HB.instance Definition N Params := Factory.Build Params T … ]] Supported attributes: - [#[export]] to flag the instance so that it is redeclared by [#[HB.reexport]] - [#[local]] to indicate that the instance should not survive the section. - [#[non_forgetful_inheritance]] allows non forgetful inheritance, i.e. inheritance via an instance declaration rather than via dependencies. See tests/non_forgetful_inheritance.v and "Competing inheritance paths in dependent type theory" (https://hal.inria.fr/hal-02463336) - [#[verbose]] for a verbose output. - [#[hnf] to compute the head normal form of CS instances before declaring them *) #[arguments(raw)] Elpi Command HB.instance. Elpi Accumulate Db hb.db. Elpi Accumulate File "HB/common/stdpp.elpi". Elpi Accumulate File "HB/common/database.elpi". Elpi Accumulate File "HB/common/compat_acc_clauses_all.elpi". Elpi Accumulate File "HB/common/compat_add_secvar_all.elpi". Elpi Accumulate File "HB/common/utils.elpi". Elpi Accumulate File "HB/common/log.elpi". Elpi Accumulate File "HB/common/synthesis.elpi". Elpi Accumulate File "HB/context.elpi". Elpi Accumulate File "HB/instance.elpi". Elpi Accumulate lp:{{ :name "start" main [const-decl Name (some BodySkel) TyWPSkel] :- !, with-attributes (with-logging (instance.declare-const Name BodySkel TyWPSkel _ _)). main [T0, F0] :- !, coq.warning "HB" "HB.deprecated" "The syntax \"HB.instance Key FactoryInstance\" is deprecated, use \"HB.instance Definition\" instead", with-attributes (with-logging (instance.declare-existing T0 F0)). }}. #[synterp] Elpi Accumulate lp:{{ shorten coq.env.{ begin-section, end-section }. main [const-decl _ _ (arity _)] :- !. main [const-decl _ _ (parameter _ _ _ _)] :- !, SectionName is "hb_instance_" ^ {std.any->string {new_int} }, begin-section SectionName, end-section. main [_, _] :- !. main _ :- coq.error "Usage: HB.instance Definition := T ...". }}. Elpi Typecheck. Elpi Export HB.instance. (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (** [HB.factory] declares a factory. It has the same syntax of [HB.mixin] *) #[arguments(raw)] Elpi Command HB.factory. Elpi Accumulate Db hb.db. Elpi Accumulate File "HB/common/stdpp.elpi". Elpi Accumulate File "HB/common/database.elpi". Elpi Accumulate File "HB/common/compat_acc_clauses_all.elpi". Elpi Accumulate File "HB/common/compat_add_secvar_all.elpi". Elpi Accumulate File "HB/common/utils.elpi". Elpi Accumulate File "HB/common/log.elpi". Elpi Accumulate File "HB/common/synthesis.elpi". Elpi Accumulate File "HB/common/phant-abbreviation.elpi". Elpi Accumulate File "HB/instance.elpi". Elpi Accumulate File "HB/context.elpi". Elpi Accumulate File "HB/export.elpi". Elpi Accumulate File "HB/factory.elpi". Elpi Accumulate lp:{{ :name "start" main [A] :- with-attributes (with-logging (factory.declare A)). }}. #[synterp] Elpi Accumulate File "HB/common/utils-synterp.elpi". #[synterp] Elpi Accumulate Db export.db. #[synterp] Elpi Accumulate lp:{{ shorten coq.env.{ begin-module, end-module, begin-section, end-section, export-module }. pred actions i:id. actions N :- begin-module N none, begin-section N, end-section, begin-module "Exports" none, end-module E, end-module _, export-module E, coq.env.current-library File, coq.elpi.accumulate current "export.db" (clause _ _ (module-to-export File E)). main [indt-decl D] :- record-decl->id D N, with-attributes (actions N). main [const-decl N _ _] :- with-attributes (actions N). main _ :- coq.error "Usage: HB.factory Record T & F A & … := { … }.\nUsage: HB.factory Definition T of F A := t.". }}. Elpi Typecheck. Elpi Export HB.factory. (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (** [HB.builders] starts a section to declare the builders associated to a factory. [HB.end] ends that section. Syntax to declare builders for factory [Factory]: [[ HB.builders Context A (f : Factory A). … HB.instance A someFactoryInstance. … HB.end. ]] [HB.builders] starts a section (inside a module of unspecified name) where: - [A] is a type variable - all the requirements of [Factory] were postulated as variables - [f] is variable of type [Factory A] - all classes whose requirements can be obtained from [Factory] are declared canonical on [A] - for each operation [op] and property [prop] (named fields) of [Factory A] a [Notation] named [op] and [property] for the partial application of [op] and [property] to the variable [f] The former [op] and [property] are aliased [Super.op] and [Super.property] [HB.end] ends the section and closes the module and synthesizes - for each structure inhabited via [HB.instance] it defined all builders to known mixins Supported attributes: - [#[verbose]] for a verbose output. *) #[arguments(raw)] Elpi Command HB.builders. Elpi Accumulate Db hb.db. Elpi Accumulate File "HB/common/stdpp.elpi". Elpi Accumulate File "HB/common/database.elpi". Elpi Accumulate File "HB/common/compat_acc_clauses_all.elpi". Elpi Accumulate File "HB/common/compat_add_secvar_all.elpi". Elpi Accumulate File "HB/common/utils.elpi". Elpi Accumulate File "HB/common/log.elpi". Elpi Accumulate File "HB/common/synthesis.elpi". Elpi Accumulate File "HB/common/phant-abbreviation.elpi". Elpi Accumulate File "HB/instance.elpi". Elpi Accumulate File "HB/context.elpi". Elpi Accumulate File "HB/export.elpi". Elpi Accumulate File "HB/factory.elpi". Elpi Accumulate File "HB/builders.elpi". Elpi Accumulate lp:{{ :name "start" main [ctx-decl C] :- with-attributes (with-logging (builders.begin C)). }}. #[synterp] Elpi Accumulate File "HB/common/utils-synterp.elpi". #[synterp] Elpi Accumulate lp:{{ shorten coq.env.{ begin-module, end-module, begin-section }. pred actions i:id. actions N :- begin-module N none, begin-module "Super" none, end-module _, begin-section N. main [ctx-decl _] :- !, with-attributes (actions {calc ("Builders_" ^ {std.any->string {new_int} })}). main _ :- coq.error "Usage: HB.builders Context A (f : F1 A).". }}. Elpi Typecheck. Elpi Export HB.builders. #[arguments(raw)] Elpi Command HB.end. Elpi Accumulate Db hb.db. Elpi Accumulate File "HB/common/stdpp.elpi". Elpi Accumulate File "HB/common/database.elpi". Elpi Accumulate File "HB/common/compat_acc_clauses_all.elpi". Elpi Accumulate File "HB/common/compat_add_secvar_all.elpi". Elpi Accumulate File "HB/common/utils.elpi". Elpi Accumulate File "HB/common/log.elpi". Elpi Accumulate File "HB/common/synthesis.elpi". Elpi Accumulate File "HB/instance.elpi". Elpi Accumulate File "HB/context.elpi". Elpi Accumulate File "HB/export.elpi". Elpi Accumulate File "HB/builders.elpi". Elpi Accumulate lp:{{ :name "start" main [] :- with-attributes (with-logging builders.end). }}. #[synterp] Elpi Accumulate File "HB/common/utils-synterp.elpi". #[synterp] Elpi Accumulate Db export.db. #[synterp] Elpi Accumulate lp:{{ shorten coq.env.{ end-module, end-section, begin-module, end-module, export-module }. pred actions. actions :- end-section, begin-module {calc ("Builders_Export_" ^ {std.any->string {new_int} })} none, end-module M, end-module _, export-module M, coq.env.current-library File, coq.elpi.accumulate current "export.db" (clause _ _ (module-to-export File M)). main [] :- !, with-attributes actions. main _ :- coq.error "Usage: HB.end.". }}. Elpi Typecheck. Elpi Export HB.end. (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (** [HB.export Modname] does the work of [Export Modname] but also schedules [Modname] to be exported later on, when [HB.reexport] is called. [HB.export Constname] does nothing, but schedules [Constname] to be made available via a Notation at HB.reexport time. Note that the list of things to be exported is stored in the current module, hence the recommended way to do is [[ Module Algebra. HB.mixin .... HB.structure ... Module MoreExports. ... End MoreExports. HB.export MoreExports. ... HB.builders ... Lemma aux_fact : .... HB.export aux_fact. ... HB.end. ... Module Export. HB.reexport. End Exports. End Algebra. Export Algebra.Exports. ]] Supported attributes: - [#[verbose]] for a verbose output. *) #[arguments(raw)] Elpi Command HB.export. Elpi Accumulate Db hb.db. Elpi Accumulate File "HB/common/stdpp.elpi". Elpi Accumulate File "HB/common/database.elpi". Elpi Accumulate File "HB/common/compat_acc_clauses_all.elpi". Elpi Accumulate File "HB/common/compat_add_secvar_all.elpi". Elpi Accumulate File "HB/common/utils.elpi". Elpi Accumulate File "HB/common/log.elpi". Elpi Accumulate File "HB/export.elpi". Elpi Accumulate lp:{{ :name "start" main [str M] :- !, with-attributes (with-logging (export.any M)). main _ :- coq.error "Usage: HB.export M.". }}. #[synterp] Elpi Accumulate File "HB/common/utils-synterp.elpi". #[synterp] Elpi Accumulate Db export.db. #[synterp] Elpi Accumulate lp:{{ shorten coq.env.{ export-module }. pred actions i:list located. actions [loc-modpath MP] :- !, export-module MP, coq.env.current-library File, coq.elpi.accumulate current "export.db" (clause _ _ (module-to-export File MP)). actions []. main [str M] :- !, with-attributes (actions {coq.locate-all M}). main _ :- coq.error "Usage: HB.export M.". }}. Elpi Typecheck. Elpi Export HB.export. (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (** [HB.reexport] Exports all modules, canonical instances and constants that were previously exported via [HB.export]. It is useful to create one big module with all exports at the end of a file. It optionally takes the name of a module or a component of the current module path (a module which is not closed yet) *) #[arguments(raw)] Elpi Command HB.reexport. Elpi Accumulate Db hb.db. Elpi Accumulate File "HB/common/stdpp.elpi". Elpi Accumulate File "HB/common/database.elpi". Elpi Accumulate File "HB/common/compat_acc_clauses_all.elpi". Elpi Accumulate File "HB/common/compat_add_secvar_all.elpi". Elpi Accumulate File "HB/common/utils.elpi". Elpi Accumulate File "HB/common/log.elpi". Elpi Accumulate File "HB/export.elpi". Elpi Accumulate lp:{{ :name "start" main [] :- !, with-attributes (with-logging (export.reexport-all-modules-and-CS none)). main [str M] :- !, with-attributes (with-logging (export.reexport-all-modules-and-CS (some M))). main _ :- coq.error "Usage: HB.reexport.". }}. #[synterp] Elpi Accumulate File "HB/common/utils-synterp.elpi". #[synterp] Elpi Accumulate Db export.db. #[synterp] Elpi Accumulate lp:{{ shorten coq.env.{ export-module }. pred module-in-module i:list string, i:prop. module-in-module PM (module-to-export _ M) :- coq.modpath->path M PC, std.appendR PM _ PC. % sublist pred actions i:option id. actions Filter :- coq.env.current-library File, compute-filter Filter MFilter, std.findall (module-to-export File Module_) ModsCL, std.filter {list-uniq ModsCL} (module-in-module MFilter) ModsCLFiltered, std.forall ModsCLFiltered (x\sigma mp\x = module-to-export _ mp, export-module mp). main [] :- !, with-attributes (actions none). main [str M] :- !, with-attributes (actions (some M)). main _ :- coq.error "Usage: HB.reexport.". }}. Elpi Typecheck. Elpi Export HB.reexport. (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) From elpi.apps Require Import locker. Elpi Export mlock As HB.lock. (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* Inactive command: [HB.declare] This command populates the current section with canonical instances. Syntax: [[ HB.declare Context (p1 : P1) ... (pn : Pn) (t : T) & F0 & ... & Fk. ]] Effect: [[ Variables (p1 : P1) ... (pn : Pn) (t : T). Variable m0 : M0 ... T. HB.instance Definition _ : M0 ... T := m0. .. Variable mk : Ml ... T. HB.instance Definition _ : Ml ... T := ml. ]] where: - factories F0 .. Fk produce mixins M0 .. Ml. Supported attributes: - [#[verbose]] for a verbose output. *) #[arguments(raw)] Elpi Command HB.declare. Elpi Accumulate Db hb.db. Elpi Accumulate File "HB/common/stdpp.elpi". Elpi Accumulate File "HB/common/database.elpi". Elpi Accumulate File "HB/common/compat_acc_clauses_all.elpi". Elpi Accumulate File "HB/common/compat_add_secvar_all.elpi". Elpi Accumulate File "HB/common/utils.elpi". Elpi Accumulate File "HB/common/log.elpi". Elpi Accumulate File "HB/common/synthesis.elpi". Elpi Accumulate File "HB/common/phant-abbreviation.elpi". Elpi Accumulate File "HB/export.elpi". Elpi Accumulate File "HB/instance.elpi". Elpi Accumulate File "HB/context.elpi". Elpi Accumulate File "HB/factory.elpi". Elpi Accumulate lp:{{ :name "start" main [Ctx] :- Ctx = ctx-decl _, !, with-attributes (with-logging ( factory.argument->w-mixins Ctx (pr FLwP _), context.declare FLwP _ _ _ _ _)). main _ :- coq.error "Usage: HB.declare Context ". }}. Elpi Typecheck. Elpi Export HB.declare. (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (** [HB.check T] acts like [Check T] but supports the attribute [#[skip="rex"]] that skips the action on Coq version matches rex. It also understands the [#[fail]] attribute. *) #[arguments(raw)] Elpi Command HB.check. Elpi Accumulate Db hb.db. Elpi Accumulate File "HB/common/stdpp.elpi". Elpi Accumulate File "HB/common/database.elpi". Elpi Accumulate File "HB/common/compat_acc_clauses_all.elpi". Elpi Accumulate File "HB/common/compat_add_secvar_all.elpi". Elpi Accumulate File "HB/common/utils.elpi". Elpi Accumulate File "HB/common/log.elpi". Elpi Accumulate lp:{{ :name "start" main [trm Skel] :- !, with-attributes (with-logging (check-or-not Skel)). main _ :- coq.error "usage: HB.check (term).". pred check-or-not i:term. check-or-not Skel :- coq.version VersionString _ _ _, if (get-option "skip" R, rex_match R VersionString) (coq.warning "HB" "HB.skip" {get-option "elpi.loc"} "Skipping test on Coq" VersionString "as requested") (log.coq.check Skel Ty T Result, if (Result = error Msg) (if (get-option "fail" tt) (coq.say "The command did fail as expected with message:" Msg) (coq.error "HB.check:" Msg)) (if (get-option "fail" tt) (coq.error "The command did not fail") (coq.say "HB.check:" {coq.term->string T} ":" {coq.term->string Ty}))). }}. Elpi Typecheck. Elpi Export HB.check. (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (** Technical notations from /Canonical Structures for the working Coq user/ *) Notation "`Error_cannot_unify: t1 'with' t2" := (unify t1 t2 None) (at level 0, format "`Error_cannot_unify: t1 'with' t2", only printing) : form_scope. Notation "`Error: t `is_not_canonically_a T" := (unify t _ (Some (is_not_canonically_a, T))) (at level 0, T at level 0, format "`Error: t `is_not_canonically_a T", only printing) : form_scope. math-comp-hierarchy-builder-4d8a939/LICENSE000066400000000000000000000017771521677141400203770ustar00rootroot00000000000000Permission 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. math-comp-hierarchy-builder-4d8a939/Makefile000066400000000000000000000137661521677141400210330ustar00rootroot00000000000000# -*- Makefile -*- ###################################################################### # USAGE: # # # # make all: Build the MathComp library entirely, # # make test-suite: Run the test suite, # # make only TGTS="...vo": Build the selected libraries of MathComp. # # # # The rules this-config::, this-build::, this-only::, # # this-test-suite::, this-distclean::, this-clean:: # # and __always__:: may be extended. # # # # Additionally, the following variables may be customized: # SUBDIRS?= COQBIN?=$(dir $(shell command -v coqtop || command -v rocq)) COQTOP=$(shell command -v coqtop || echo "$(COQBIN)rocq repl") COQMAKEFILE?=$(shell command -v coq_makefile || echo "$(COQBIN)rocq makefile") COQDEP?=$(COQBIN)coqdep COQPROJECT?=_CoqProject COQMAKEOPTIONS?= COQMAKEFILEOPTIONS?= V?= VERBOSE?=V TGTS?= ###################################################################### # local context: ----------------------------------------------------- .PHONY: all config build only test-suite test-suite-stdlib clean distclean __always__ .SUFFIXES: H:= $(if $(VERBOSE),,@) # not used yet TOP = $(dir $(lastword $(MAKEFILE_LIST))) COQMAKE = $(MAKE) -f Makefile.coq $(COQMAKEOPTIONS) COQMAKE_TESTSUITE = $(MAKE) -f Makefile.test-suite.coq $(COQMAKEOPTIONS) COQMAKE_TESTSUITE_STDLIB = $(MAKE) -f Makefile.test-suite-stdlib.coq $(COQMAKEOPTIONS) BRANCH_coq:= $(shell $(COQTOP) -v | head -1 | grep -E '(trunk|master)' \ | wc -l | sed 's/ *//g') # coq version: ifneq "$(BRANCH_coq)" "0" COQVVV:= dev else COQVVV:=$(shell $(COQTOP) --print-version | cut -d" " -f1) endif COQV:= $(shell echo $(COQVVV) | cut -d"." -f1) COQVV:= $(shell echo $(COQVVV) | cut -d"." -f1-2) # export to sub- targets export COQBIN export COQMAKEFILE export COQV export COQVV export COQVVV # all: --------------------------------------------------------------- all: $(MAKE) config $(MAKE) build $(MAKE) test-suite # Makefile.coq: ------------------------------------------------------ Makefile.coq: $(COQPROJECT) Makefile $(COQMAKEFILE) $(COQMAKEFILEOPTIONS) -f $(COQPROJECT) -o Makefile.coq # Test suite --------------------------------------------------------- Makefile.test-suite.coq: $(COQPROJECT).test-suite Makefile $(COQMAKEFILE) $(COQMAKEFILEOPTIONS) -f $(COQPROJECT).test-suite -o Makefile.test-suite.coq # Test suite Stdlib -------------------------------------------------- Makefile.test-suite-stdlib.coq: $(COQPROJECT).test-suite-stdlib Makefile $(COQMAKEFILE) $(COQMAKEFILEOPTIONS) -f $(COQPROJECT).test-suite-stdlib -o Makefile.test-suite-stdlib.coq # Global config, build, clean and distclean -------------------------- config: sub-config this-config build: sub-build this-build only: sub-only this-only test-suite: sub-test-suite this-test-suite test-suite-stdlib: sub-test-suite-stdlib this-test-suite-stdlib clean: sub-clean this-clean distclean: sub-distclean this-distclean # Local config, build, clean and distclean --------------------------- .PHONY: this-config this-build this-only this-test-suite this-test-suite-stdlib this-distclean this-clean this-config:: __always__ @if $$(command -v coqc >/dev/null) ; then \ if [ -e config.stamp -a "`coqc --print-version`" = "`cat config.stamp 2>/dev/null`" ] ; then \ echo 'already configured';\ else\ coqc --print-version > config.stamp;\ echo 'configuring for ' `coqc --print-version`;\ if (coqc --version | grep -q '8.20') ; then \ echo '*****************************************************************';\ echo 'old coq version detected, double check the diff before committing';\ echo '*****************************************************************';\ sed -i.bak -e 's/From Corelib/From Coq/' `find . -name \*.v` ; \ sed -i.bak -e 's/IntDef/ZArith/' `find . -name \*.v` ; \ fi;\ fi ; fi # Remove all of the above when requiring Rocq >= 9.0 this-build:: this-config Makefile.coq +$(COQMAKE) this-only:: this-config Makefile.coq +$(COQMAKE) only "TGTS=$(TGTS)" this-test-suite:: build Makefile.test-suite.coq +$(COQMAKE_TESTSUITE) this-test-suite-stdlib:: build Makefile.test-suite-stdlib.coq +$(COQMAKE_TESTSUITE_STDLIB) this-distclean:: this-clean rm -f config.stamp rm -f Makefile.coq Makefile.coq.conf rm -f Makefile.test-suite.coq Makefile.test-suite.coq.conf rm -f Makefile.test-suite-stdlib.coq Makefile.test-suite-stdlib.coq.conf this-clean:: __always__ @if [ -f Makefile.coq ]; then $(COQMAKE) cleanall; fi @if [ -f Makefile.test-suite.coq ]; then $(COQMAKE_TESTSUITE) cleanall; fi @if [ -f Makefile.test-suite-stdlib.coq ]; then $(COQMAKE_TESTSUITE_STDLIB) cleanall; fi # Install target ----------------------------------------------------- .PHONY: install install: __always__ Makefile.coq $(COQMAKE) install # counting lines of Coq code ----------------------------------------- .PHONY: count COQFILES = $(shell grep '.v$$' $(COQPROJECT)) count: @coqwc $(COQFILES) | tail -1 | \ awk '{printf ("%d (spec=%d+proof=%d)\n", $$1+$$2, $$1, $$2)}' # Additionally cleaning backup (*~) files ---------------------------- this-distclean:: rm -f $(shell find . -name '*~') # Make in SUBDIRS ---------------------------------------------------- ifdef SUBDIRS sub-%: __always__ @set -e; for d in $(SUBDIRS); do $(MAKE) -C $$d $(@:sub-%=%); done else sub-%: __always__ @true endif # Make of individual .vo --------------------------------------------- structures.vo : %.vo: __always__ Makefile.coq +$(COQMAKE) $@ $(addsuffix o,$(wildcard examples/*.v examples/*/*.v tests/*.v tests/unit/*.v)): __always__ config build Makefile.test-suite.coq Makefile.test-suite-stdlib.coq +$(COQMAKE_TESTSUITE) $@ +$(COQMAKE_TESTSUITE_stdlib) $@ nix: nix-shell --arg do-nothing true --run "updateNixToolBox && genNixActions" .PHONY: nix math-comp-hierarchy-builder-4d8a939/Makefile.coq.local000066400000000000000000000003771521677141400226770ustar00rootroot00000000000000# Coq does not know about Elpi Accumulate File, so we declare the dependency here HB/structures.vo : $(wildcard HB/*.elpi HB/common/*.elpi) clean:: $(SHOW)'CLEAN *.hb *.hb.old' $(HIDE) find . -name \*.hb -delete $(HIDE) find . -name \*.hb.old -delete math-comp-hierarchy-builder-4d8a939/Makefile.test-suite.coq.local000066400000000000000000000020051521677141400247720ustar00rootroot00000000000000COQ_MINOR=$(shell echo $(COQ_VERSION) | cut -d . -f 2 | cut -d + -f 1) output_for=`\ if [ -e $(1).out.$(COQ_MINOR) ]; then\ echo $(1).out.$(COQ_MINOR);\ else\ echo $(1).out;\ fi` DIFF=\ @if [ -z "$$COQ_ELPI_ATTRIBUTES" ]; then \ echo OUTPUT DIFF $(1);\ $(COQTOP) $(COQFLAGS) $(COQLIBS) -topfile $(1) \ < $(1) 2>&1 \ | sed 's/Coq < *//g' \ | sed 's/Rocq < *//g' \ | grep -v '^$$' \ | grep -v -e "Skipping rcfile" -e "is declared" -e "is defined" -e "Loading ML file" -e "Welcome to Coq" -e "Welcome to Rocq" \ | sed 's/characters \([0-9]\+\)-[0-9]\+/character \1/' \ > $(1).out.aux;\ diff -u --strip-trailing-cr $(call output_for,$(1)) $(1).out.aux;\ fi post-all:: $(call DIFF, tests/err_missin_subject.v) $(call DIFF, tests/compress_coe.v) $(call DIFF, tests/err_miss_key.v) $(call DIFF, tests/missing_join_error.v) $(call DIFF, tests/not_same_key.v) $(call DIFF, tests/hnf.v) $(call DIFF, tests/err_miss_dep.v) $(call DIFF, tests/err_bad_mix.v) $(call DIFF, tests/err_instance_nop.v) math-comp-hierarchy-builder-4d8a939/README.md000066400000000000000000000157511521677141400206460ustar00rootroot00000000000000[![Actions Status](https://github.com/math-comp/hierarchy-builder/workflows/CI/badge.svg)](https://github.com/math-comp/hierarchy-builder/actions) [![project chat](https://img.shields.io/badge/zulip-join_chat-brightgreen.svg)](https://coq.zulipchat.com/#narrow/stream/237868-Hierarchy-Buidlder) HB logo ### Hierarchy Builder Hierarchy Builder (HB) provides high level commands to declare a hierarchy of algebraic structure (or interfaces if you prefer the glossary of computer science) for the Coq system. Given a structure one can develop its theory, and that theory becomes automatically applicable to all the examples of the structure. One can also declare alternative interfaces, for convenience or backward compatibility, and provide glue code linking these interfaces to the structures part of the hierarchy. HB commands compile down to Coq modules, sections, records, coercions, canonical structure instances and notations following the *packed classes* discipline which is at the core of the [Mathematical Components](https://github.com/math-comp/math-comp) library. All that complexity is hidden behind a few concepts and a few declarative Coq commands. ## Example ```coq From HB Require Import structures. From Coq Require Import ssreflect ZArith. HB.mixin Record IsAddComoid A := { zero : A; add : A -> A -> A; addrA : forall x y z, add x (add y z) = add (add x y) z; addrC : forall x y, add x y = add y x; add0r : forall x, add zero x = x; }. HB.structure Definition AddComoid := { A of IsAddComoid A }. Notation "0" := zero. Infix "+" := add. Check forall (M : AddComoid.type) (x : M), x + x = 0. ``` This is all we need to do in order to declare the `AddComoid` structure and write statements in its signature. We proceed by declaring how to obtain an Abelian group out of the additive, commutative, monoid. ```coq HB.mixin Record IsAbelianGrp A of IsAddComoid A := { opp : A -> A; addNr : forall x, opp x + x = 0; }. HB.structure Definition AbelianGrp := { A of IsAbelianGrp A & IsAddComoid A }. Notation "- x" := (opp x). ``` Abelian groups feature the operations and properties given by the `IsAbelianGrp` mixin (and its dependency `IsAddComoid`). ```coq Lemma example (G : AbelianGrp.type) (x : G) : x + (- x) = - 0. Proof. by rewrite addrC addNr -[LHS](addNr zero) addrC add0r. Qed. ``` We proceed by showing that `Z` is an example of both structures, and use the lemma just proved on a statement about `Z`. ```coq HB.instance Definition Z_CoMoid := IsAddComoid.Build Z 0%Z Z.add Z.add_assoc Z.add_comm Z.add_0_l. HB.instance Definition Z_AbGrp := IsAbelianGrp.Build Z Z.opp Z.add_opp_diag_l. Lemma example2 (x : Z) : x + (- x) = - 0. Proof. by rewrite example. Qed. ``` ## Documentation For a tutorial, see the [platform docs](https://github.com/rocq-prover/platform-docs/tree/main/src/hierarchy_builder). This [paper](https://hal.inria.fr/hal-02478907) describes the language in details, and the corresponding talk [is available on youtube](https://www.youtube.com/watch?v=F6iRaTlQrlo). The [wiki](https://github.com/math-comp/hierarchy-builder/wiki) gathers some tricks and FAQs. If you want to work on the implementation of HB, this [recorded hacking session](https://www.youtube.com/watch?v=gmaJjCbzqO0) may be relevant to you. ### Installation & availability
(click to expand)

- You can install HB via OPAM ```shell opam repo add rocq-released https://rocq-prover.org/opam/released opam install rocq-hierarchy-builder ``` - You can use it in nix with the attribute `rocqPackages_9_X.hierarchy-builder` e.g. via `nix-shell -p rocq_9_0 -p rocqPackages_9_0.hierarchy-builder`

### Key concepts
(click to expand)

- a *mixin* is a bare bone building block of the hierarchy, it packs operations and axioms. - a *factory* is a package of operations and properties that is elaborated by HB to one or more mixin. A mixin is hence a trivial factory. - a *structure* is declared by attaching zero or more factories to a type. - a *builder* is a user provided piece of code capable of building one or more mixins from a factory. - an *instance* is an example of a structure: it provides all operation and fulfills all axioms.

### The commands of HB
(click to expand)

- HB core commands: - `HB.mixin` declares a mixin, - `HB.structure` declares a structure, - `HB.factory` declares a factory, - `HB.builders` and `HB.end` declare a set of builders, - `HB.instance` declares a structure instance, - `HB.declare` declares a context with parameters, key and mixins. - `HB.saturate` reconsiders all mixin instances to see if some newly declared structure can be inhabited - HB core tactic-in-term: - `HB.pack` to synthesize a structure instance in the middle of a term. - HB utility commands: - `HB.export` exports a module and schedules it for re-export - `HB.reexport` exports all modules, instances and constants scheduled for re-export - `HB.lock` locks a definition behind an opaque symbol and an unfolding equation using Coq module system - HB queries: - `HB.about` is similar to `About` but prints more info on HB structures, like the known instances and where they are declared - `HB.locate` is similar to `Locate`, prints file name and line of any global constant synthesized by HB - `HB.graph` prints the structure hierarchy to a dot file - `HB.howto` prints sequences of factories to equip a type with a given structure - HB debug commands: - `HB.status` dumps the contents of the hierarchy (debug purposes) - `HB.check` is similar to `Check` (testing purposes) The documentation of all commands can be found in the comments of [structures.v](HB/structures.v), search for `Elpi Command` and you will find them. All commands can be prefixed with the attribute `#[verbose]` to get an idea of what they are doing. For debugging and teaching purposes, passing the attributes `#[log]` or `#[log(raw)]` to a HB command prints Coq commands which are *almost* equivalent to its effect. Hence, copy-pasting the displayed commands into your source file is not expected to work, and we strongly recommend against it.

### Demos
(click to expand)

- [demo1](examples_stdlib/demo1/) and [demo3](examples/demo3/) declare and evolve a hierarchy up to rings with various clients that are tested not to break when the hierarchy evolves - [demo2](examples_stdlib/demo2/) describes the subtle triangular interaction between groups, topological space and uniform spaces. Indeed, 1. all uniform spaces induce a topology, which makes them topological spaces, but 2. all topological groups (groups that are topological spaces such that the addition and opposite are continuous) induce a uniformity, which makes them uniform spaces. We solve this seamingly mutual dependency using HB.

math-comp-hierarchy-builder-4d8a939/_CoqProject000066400000000000000000000003111521677141400215040ustar00rootroot00000000000000HB/structures.v -arg -w -arg -elpi.accumulate-syntax -arg -w -arg +elpi.typecheck -arg -w -arg -elpi.typecheck-syntax -arg -w -arg -elpi.flex-clause -Q HB HB -R tests HB.tests -R examples HB.examples math-comp-hierarchy-builder-4d8a939/_CoqProject.test-suite000066400000000000000000000030711521677141400236170ustar00rootroot00000000000000-arg -w -arg -redundant-canonical-projection -arg -w -arg -projection-no-head-constant -arg -w -arg -abstract-large-number -arg -w -arg -disj-pattern-notation -arg -w -arg -notation-overridden -arg -w -arg +elpi.typecheck examples/readme.v examples/hulk.v examples/demo3/hierarchy_0.v examples/demo3/hierarchy_1.v examples/demo3/hierarchy_2.v examples/demo3/test_0_0.v examples/demo3/test_1_0.v examples/demo3/test_2_0.v examples/demo4/hierarchy_0.v examples/demo5/hierarchy_0.v # examples/cat/cat.v examples/cat/cat.v tests/test_howto.v tests/type_of_exported_ops.v tests/duplicate_structure.v tests/instance_params_no_type.v tests/test_CS_db_filtering.v tests/subtype.v tests/log_impargs_record.v tests/compress_coe.v tests/grefclass.v tests/local_instance.v tests/lock.v tests/interleave_context.v tests/not_same_key.v #tests/factory_sort.v tests/hb_pack.v tests/declare.v tests/short.v tests/instance_before_structure.v tests/primitive_records.v tests/non_forgetful_inheritance.v tests/fix_loop.v tests/test_synthesis_params.v tests/hnf.v tests/fun_instance.v tests/issue284.v tests/issue287.v tests/two_hier.v tests/instance_merge_with_param.v tests/instance_merge_with_distinct_param.v tests/instance_merge.v tests/unit/enrich_type.v tests/unit/mixin_src_has_mixin_instance.v tests/unit/mk_src_map.v tests/unit/close_hole_term.v tests/unit/struct.v tests/factory_when_notation.v tests/saturate_on.v tests/saturate_export.v tests/bug_435.v tests/bug_447.v tests/unimported_relevant_class.v tests/unimported_irrelevant_class.v -R tests HB.tests -R examples HB.examples -Q HB HB math-comp-hierarchy-builder-4d8a939/_CoqProject.test-suite-stdlib000066400000000000000000000026731521677141400251050ustar00rootroot00000000000000-arg -w -arg -redundant-canonical-projection -arg -w -arg -projection-no-head-constant -arg -w -arg -abstract-large-number -arg -w -arg -disj-pattern-notation -arg -w -arg -notation-overridden -arg -w -arg +elpi.typecheck examples_stdlib/demo1/hierarchy_0.v examples_stdlib/demo1/hierarchy_1.v examples_stdlib/demo1/hierarchy_2.v examples_stdlib/demo1/hierarchy_3.v examples_stdlib/demo1/hierarchy_4.v examples_stdlib/demo1/hierarchy_5.v examples_stdlib/demo1/test_0_0.v examples_stdlib/demo1/test_1_0.v examples_stdlib/demo1/test_2_0.v examples_stdlib/demo1/test_3_0.v examples_stdlib/demo1/test_3_3.v examples_stdlib/demo1/test_4_0.v examples_stdlib/demo1/test_4_3.v examples_stdlib/demo1/test_5_0.v examples_stdlib/demo1/test_5_3.v examples_stdlib/demo2/classical.v examples_stdlib/demo2/stage10.v examples_stdlib/demo2/stage11.v examples_stdlib/FSCD2020_material/V1.v examples_stdlib/FSCD2020_material/V2.v examples_stdlib/FSCD2020_material/V3.v examples_stdlib/FSCD2020_material/V4.v examples_stdlib/FSCD2020_talk/V1.v examples_stdlib/FSCD2020_talk/V2.v examples_stdlib/FSCD2020_talk/V3.v examples_stdlib/Coq2020_material/CoqWS_demo.v examples_stdlib/Coq2020_material/CoqWS_abstract.v examples_stdlib/Coq2020_material/CoqWS_expansion/withHB.v examples_stdlib/Coq2020_material/CoqWS_expansion/withoutHB.v tests_stdlib/exports.v tests_stdlib/exports2.v tests_stdlib/funclass.v -R tests_stdlib HB.tests_stdlib -R examples_stdlib HB.examples_stdlib -Q HB HB math-comp-hierarchy-builder-4d8a939/build-support/000077500000000000000000000000001521677141400221675ustar00rootroot00000000000000math-comp-hierarchy-builder-4d8a939/build-support/coq/000077500000000000000000000000001521677141400227515ustar00rootroot00000000000000math-comp-hierarchy-builder-4d8a939/build-support/coq/extra-lib.nix000066400000000000000000000077721521677141400253750ustar00rootroot00000000000000{ lib }: with builtins; with lib; recursiveUpdate lib (rec { versions = let truncate = n: v: concatStringsSep "." (take n (splitVersion v)); opTruncate = op: v0: v: let n = length (splitVersion v0); in op (truncate n v) (truncate n v0); in rec { /* Get string of the first n parts of a version string. Example: - truncate 2 "1.2.3-stuff" => "1.2" - truncate 4 "1.2.3-stuff" => "1.2.3.stuff" */ inherit truncate; /* Get string of the first three parts (major, minor and patch) of a version string. Example: majorMinorPatch "1.2.3-stuff" => "1.2.3" */ majorMinorPatch = truncate 3; /* Version comparison predicates, - isGe v0 v <-> v is greater or equal than v0 [*] - isLe v0 v <-> v is lesser or equal than v0 [*] - isGt v0 v <-> v is strictly greater than v0 [*] - isLt v0 v <-> v is strictly lesser than v0 [*] - isEq v0 v <-> v is equal to v0 [*] - range low high v <-> v is between low and high [**] [*] truncating v to the same number of digits as v0 [**] truncating v to low for the lower bound and high for the upper bound Examples: - isGe "8.10" "8.10.1" => true - isLe "8.10" "8.10.1" => true - isGt "8.10" "8.10.1" => false - isGt "8.10.0" "8.10.1" => true - isEq "8.10" "8.10.1" => true - range "8.10" "8.11" "8.11.1" => true - range "8.10" "8.11+" "8.11.0" => false - range "8.10" "8.11+" "8.11+beta1" => false */ isGe = opTruncate versionAtLeast; isGt = opTruncate (flip versionOlder); isLe = opTruncate (flip versionAtLeast); isLt = opTruncate versionOlder; isEq = opTruncate pred.equal; range = low: high: pred.inter (versions.isGe low) (versions.isLe high); }; /* Returns a list of list, splitting it using a predicate. This is analoguous to builtins.split sep list, with a predicate as a separator and a list instead of a string. Type: splitList :: (a -> bool) -> [a] -> [[a]] Example: splitList (x: x == "x") [ "y" "x" "z" "t" ] => [ [ "y" ] "x" [ "z" "t" ] ] */ splitList = pred: l: # put in file lists let loop = (vv: v: l: if l == [] then vv ++ [v] else let hd = head l; tl = tail l; in if pred hd then loop (vv ++ [ v hd ]) [] tl else loop vv (v ++ [hd]) tl); in loop [] [] l; pred = { /* Predicate intersection, union, and complement */ inter = p: q: x: p x && q x; union = p: q: x: p x || q x; compl = p: x: ! p x; true = p: true; false = p: false; /* predicate "being equal to y" */ equal = y: x: x == y; }; /* Emulate a "switch - case" construct, instead of relying on `if then else if ...` */ /* Usage: ```nix switch-if [ if-clause-1 .. if-clause-k ] default-out ``` where a if-clause has the form `{ cond = b; out = r; }` the first branch such as `b` is true */ switch-if = c: d: (findFirst (getAttr "cond") {} c).out or d; /* Usage: ```nix switch x [ simple-clause-1 .. simple-clause-k ] default-out ``` where a simple-clause has the form `{ case = p; out = r; }` the first branch such as `p x` is true or ```nix switch [ x1 .. xn ] [ complex-clause-1 .. complex-clause-k ] default-out ``` where a complex-clause is either a simple-clause or has the form { cases = [ p1 .. pn ]; out = r; } in which case the first branch such as all `pi x` are true if the variables p are not functions, they are converted to a equal p if out is missing the default-out is taken */ switch = var: clauses: default: with pred; let compare = f: if isFunction f then f else equal f; combine = cl: var: if cl?case then compare cl.case var else all (equal true) (zipListsWith compare cl.cases var); in switch-if (map (cl: { cond = combine cl var; inherit (cl) out; }) clauses) default; }) math-comp-hierarchy-builder-4d8a939/build-support/coq/meta-fetch/000077500000000000000000000000001521677141400247665ustar00rootroot00000000000000math-comp-hierarchy-builder-4d8a939/build-support/coq/meta-fetch/default.nix000066400000000000000000000057311521677141400271400ustar00rootroot00000000000000{ lib, stdenv, fetchzip }@args: let lib' = lib; in let lib = import ../extra-lib.nix {lib = lib';}; in with builtins; with lib; let default-fetcher = {domain ? "github.com", owner ? "", repo, rev, name ? "source", sha256 ? null, ...}@args: let ext = if args?sha256 then "zip" else "tar.gz"; fmt = if args?sha256 then "zip" else "tarball"; pr = match "^#(.*)$" rev; url = switch-if [ { cond = isNull pr && !isNull (match "^github.*" domain); out = "https://${domain}/${owner}/${repo}/archive/${rev}.${ext}"; } { cond = !isNull pr && !isNull (match "^github.*" domain); out = "https://api.${domain}/repos/${owner}/${repo}/${fmt}/pull/${head pr}/head"; } { cond = isNull pr && !isNull (match "^gitlab.*" domain); out = "https://${domain}/${owner}/${repo}/-/archive/${rev}/${repo}-${rev}.${ext}"; } { cond = !isNull (match "(www.)?mpi-sws.org" domain); out = "https://www.mpi-sws.org/~${owner}/${repo}/download/${repo}-${rev}.${ext}";} ] (throw "meta-fetch: no fetcher found for domain ${domain} on ${rev}"); fetch = x: if args?sha256 then fetchzip (x // { inherit sha256; }) else fetchTarball x; in fetch { inherit url ; }; in { fetcher ? default-fetcher, location, release ? {}, releaseRev ? (v: v), }: let isVersion = x: isString x && match "^/.*" x == null && release?${x}; shortVersion = x: if (isString x && match "^/.*" x == null) then findFirst (v: versions.majorMinor v == x) null (sort versionAtLeast (attrNames release)) else null; isShortVersion = x: shortVersion x != null; isPathString = x: isString x && match "^/.*" x != null && pathExists x; in arg: switch arg [ { case = isNull; out = { version = "broken"; src = ""; broken = true; }; } { case = isPathString; out = { version = "dev"; src = arg; }; } { case = pred.union isVersion isShortVersion; out = let v = if isVersion arg then arg else shortVersion arg; in let given-sha256 = release.${v}.sha256 or ""; sha256 = if given-sha256 == "" then lib.fakeSha256 else given-sha256; rv = release.${v} // { inherit sha256; }; in { version = rv.version or v; src = rv.src or fetcher (location // { rev = releaseRev v; } // rv); }; } { case = isString; out = let splitted = filter isString (split ":" arg); rev = last splitted; has-owner = length splitted > 1; version = "dev"; in { inherit version; src = fetcher (location // { inherit rev; } // (optionalAttrs has-owner { owner = head splitted; })); }; } { case = isAttrs; out = let { version = arg.version or "dev"; src = (arg.fetcher or fetcher) (location // (arg.location or {})); }; } { case = isPath; out = { version = "dev" ; src = builtins.path {path = arg; name = location.name or "source";}; }; } ] (throw "not a valid source description") math-comp-hierarchy-builder-4d8a939/coq-hierarchy-builder.opam000066400000000000000000000010011521677141400244060ustar00rootroot00000000000000opam-version: "2.0" name: "coq-hierarchy-builder" version: "dev" maintainer: "Enrico Tassi " authors: [ "Cyril Cohen" "Kazuhiko Sakaguchi" "Enrico Tassi" ] license: "MIT" homepage: "https://github.com/math-comp/hierarchy-builder" bug-reports: "https://github.com/math-comp/hierarchy-builder/issues" dev-repo: "git+https://github.com/math-comp/hierarchy-builder" depends: [ "coq-core" "rocq-hierarchy-builder" {= version} ] synopsis: "Compatibility package for rocq-hierarchy-builder" math-comp-hierarchy-builder-4d8a939/default.nix000066400000000000000000000007041521677141400215230ustar00rootroot00000000000000{ config ? {}, withEmacs ? false, print-env ? false, do-nothing ? false, update-nixpkgs ? false, ci-matrix ? false, override ? {}, coq-override ? {}, ocaml-override ? {}, global-override ? {}, bundle ? null, job ? null, inNixShell ? null, src ? ./., }@args: let auto = fetchGit { url = "https://github.com/coq-community/coq-nix-toolbox.git"; ref = "master"; rev = import .nix/coq-nix-toolbox.nix; }; in import auto ({inherit src;} // args) math-comp-hierarchy-builder-4d8a939/etc/000077500000000000000000000000001521677141400201315ustar00rootroot00000000000000math-comp-hierarchy-builder-4d8a939/etc/rocqy-hb.png000066400000000000000000014322531521677141400223750ustar00rootroot00000000000000‰PNG  IHDRŸ6X9"Ù'iCCPkCGColorSpaceAdobeRGB1998(‘c``RH,(Èa``ÈÍ+) rwRˆˆŒR`ÅÀÌ Ë Ä ÂÀ—˜\\ààÃ0|»ÆÀ¢/ë‚ÌÂ”Ç ¸RR‹“�ô ÎN.(*a``̲•ËK @ì [$)Ì^bdo±Ó!ì`5ö°š� g û�Í—f3�ìâK‡°@l¨½ 蘒Ÿ”ªò½†¡¥¥…&‰~ JR+J@´s~AeQfzF‰‚#0¤R<ó’õtŒ ŒÌ@áQý9žŒbgb€›#ÁÀà¿”��åB̤—�a�ÿT„˜š!ƒ€>þ9É¥EePc™Œñ;wJfH‰Å—8eXIfMM*‡i Ÿ 6¨.Ôù@IDATxì½`\Ùy¥y*gäœ �sÎd³£ÔÝnµ,Yã•Ö–-Ùë�=#‡]ÏXë°ã±-[òh<¶4–dIVÎj¥NìÜÍœC3g$H¤*T{þW(d“D�MDž+ý( ê…û¾W TGç?Ð�i@À5 ®A— " " “�€›Êa±<¬6Ö–†ˆ€ˆ€ˆ€ˆ€Üs$>Ýs·\," "0†Â<ö"Ö&ÖVËþÖg}™õuV‚¥!" " " " " " " " YˆpË ¬�³¶²Î±zX)V?«‹õ k=KCD@D@D@D@D@D@D@D@²"`N'”>ÁÚÆºÌêc™àtc�ås¿ÇÒ�{Š€÷žºZ]¬ˆ€ˆ€Ü™öº'x8k±«c岜vöPЃº2?òó|8|¼çÚœN» _/eY”9¢4D@D@D@D@Dàž ñ鞸ͺH�»@À„¥Ö*ÖC¬5¬jVËí⫹Qµ„°¢5‚™µ~t±ñî¿~)#>q3Gx²G ¸gH|ºgnµ.TD@Dà ØßÊ–9œîg-`™ƒ)ÆrD§ŠN‹[ÂX·(‚9õäx ¸púBÁ -|wݰv< ¸gH|ºgnµ.TD@D`”ìod=ë�¬‡Y³XŬ ætÊ‹ù±¨9„µ ):5P˜ç�ßër^³mÜÜ&àç—ôðñÁœSN~-ý”¾Š€ˆ€ˆ€ˆ€ˆÀô' ñiúßc]¡ˆ€ˆÀèØßÆ:–‰NV³Y&:ùYðPQ*.`{]s+æ…ÐR@Ñ€èdãýå¦áÉG!*²ˆ'gXæS«�µÝyF_D@D@D@D@Dà ñé¸ÉºD�¬ �ásX%,Gt2!©¦<ˆsBÌuŠ ¾Ò‡ü7|:›§Ïbûäç¶ÝÙ7ÖªgB–†ˆ€ˆ€ˆ€ˆ€Ü3$>Ý3·Z*" "p fM²àðÇê:§“µÑÕW±nA‹g…PUêC,ì‚—¢S_ÚétÓãR�òú\(ˆyáñ¸‘Jqã´�•Óíõ¤ˆ€ˆ€ˆ€ˆ€LSŸ¦é�Õe‰€ˆ€ŒHÀœHælzëIÖü�Ÿ�NõA¬]ÅòÙ!T—ù ¹ØvôQG²ºÝ ö/·-døx(àFG—³ƒåEUÝn?½&" " " " Ó�€Ä§évGu=" " #°p þ¾ŸõnÖ2V+À‚Ÿn¥úÊ ÖÌ�b)[ìjG):Ù12ÃÃTòXÔ�hÈÄ'çY ¯cÙßß$KCD@D@D@D@¦=‰OÓþëE@D@˜èd-oXïb­d•³Â,Gtj¬aÝÂ(–´Ù^7:§“ãÆá¢ó)t!agß%çUs>Õ±òXY" " " " "0í H|šö·X(" ÷<J@޳i=mõºå?Gùè¬HWÇöºul¯[ÙÊL§’´èd«ÕeÓ^gǸՠñ yQ/*8r²©¾~·­dYƔħ[�Óó" " " " ÓŠ€Ä§iu;u1" " ÃXvÓ Ö&Ö}¬y,Ëx²Ö7'0¼ºŒ™Nt:­l ¢®"Àö8î†èdÇïg蓉O…\ï«c8q6޽GºÍ}e®§™¬­, ˜ö$>Mû[¬ �{Ž@.¯ØrœdYk]«�d9¢SUY«çE±jnõ~gõ:7W¯{»N';þ�Ãïw¡�ç˜U2ñÉ^ޱšnÜN?‹€ˆ€ˆ€ˆ€ˆÀt% ñiºÞY]—ˆ€Ü[ªä´³mࣉN‹Xær2—‘½6Ø^·rnËæE'ωNvÎŒû)p¡ºÄ—ÊK¥úÌyÕȲü'G�⣆ˆ€ˆ€ˆ€ˆ€L[Ÿ¦í­Õ…‰€ˆÀ=AÀÜL³Y°,Ó©…5ØZÇï {Ñ\Äò¹aÌo ¢ºÔç´×�¥èdçÍ  ü”¿J‹½<¯í}¶ª^ «ˆu"³�E@D@D@D@D`º�ø4]אַKD@¦/ËM²Ö:k©{ˆµŠUŲÖ:Ëy‚ÇíBI¡ f„±dVÍu”ä{a$š�Ƥ½ÎÎ{«aBWq®ÅœC{G¯ýí-f™%ñéVÐô¼ˆ€ˆ€ˆ€ˆÀ´! ñiÚÜJ]ˆˆ€L{¶j� 6ëX&:Yk]Ë2”è-J·ÖÕ–ÓåÔÆâYaÔ•û�u#às9áßc‘édçiXðxnăŠb�p:ír¸�…¡¿0Ò¾z]D@D@D@D@¦:‰OSýjþ" "0ý XkÝÖFÖý¬f–9‡œUëøè´³µ0ÐÛD§yl­«b¾R4ìrÂÅÁ¶·>–µ¿MİóÚ z‘�›-Ž1˦a⓵šh–biˆ€ˆ€ˆ€ˆ€ˆÀ´% ñiÚÞZ]˜ˆ€Li&ÊÔ±Ö°Ö³°Ìå4ØZg‚NQž f†°tN˜«É±µ.oâZë8·[ ¬å¯¶ÜæçAO�’¥6˜Z$>M­û¥ÙŠ€ˆÀt$âEµ²6°,<|ËÚê¬5mðïT„«Öµ6ÒåÔBkS•%~ä„Ýl­ãVcÑZgYMn~I²1.ÞÛ‡xO?®võ¡¤ÀãäH¥ÏœÝW/�Z8ÞT øÔcRVFhۜݴ•ˆ€ˆ€ˆ€ˆ€LMƒÿ£~jN_³˜¢ìïO#ËV¬³ñ…¬R–¹œ,g˜[¨†âóg„X̬  (—­kÁa«Ö�Þ„”9ü-щ+æõ$ú±ïÍ<¿£.§çÏ�Ý)Ü¿<†ÇÖ š±nyœÌ Övç¢ø‹zЕ÷žÝêF*Õ—Ç×Íåeud¶Õ£ˆ€ˆ€ˆ€ˆ€L7Ÿ¦ÛÕõˆ€ˆÀä%@ù¬á‚S¶'`œAÍ…Ìrjm b]N³kƒ(+ô0@Üÿj™04V«ÖÙ±=œ@N�÷`óö¼¶§ §/ô"AçS?{ïú©$…¾z^Åy¤Ìr•ÅprŸ8ÿ¦? ) �oK˜ãËBÇmÕ»­YB›ˆ€ˆ€ˆ€ˆ€ˆÀ”$ ñiJÞ6MZD@¦–±6²V³êYÖVgÏ4ÍÙjp^4V°¸9„¹M!Ô”y‘óÀÏŒ'·2ñ&SÜ﮼\üÒ~-…�oÆñÒŽNì:Ô�s—{ÑÑ™rZúÒ'L M§Î%ðæéó›L?Ê~xy-…>Ì ƒ‹â“‰q¢¾Œ%ñ){ŒÚRD@D@D@D`Š�ø4Ån˜¦+" S„€‰Ju,k©ÛĚϲ¶º\–…m;Ã\F>¯‰.§™Aº‚lÅ:B\΄&8™Ói,†#:ÑîÔFÑiËÞn<·­û�uãr{ �=)çÜv^�?‚üòEðEŠpþÀwp…Ûï¢Hµ¤%˜õ´ì:l…¾ÜæÔ‡ðòζÞõçó¬þ9–Zﲦ© E@D@D@D@¦‰OSéni®" "0ù ˜›ÉrŒ`e\N¬a9ßâB?æÔ1Ç©9ˆæÚÊ ½ˆEÌå”n«KÁÉ$-k¯sœNt5½±·O¿~ {�PtºšBw|HéòøBÈ-Ÿ�²–'Pذ ñ«'qõÌt^;Ž=tF]¼Ei�wT­wa—¸ã5æúÌýætæ°šXÛX" " " " "0íH|šv·T$" ãNÀÚÇ*YX²¬Å®„e�Úƒg¬­ÎÚ͖Σµ!ˆª/rÀí÷ µÕ1TiX‹÷¾‹ÃÉsâkœk»–ÄŽƒqlÞÚ�퇺péJŠáâÑÉ…@8yUËPÜø0ò«W"œWo0]þ\äU.Å©]ÇpòBÂq?™pÆÅð²k½+6Áá­w–ƒ%ñ)kŠÚPD@D@D@D`*üP0•&­¹Š€ˆ€L ö7dëÖ}¬™,�†\N”¥Ê‹XØÆ"¶¨Í`¦“µÕÇ©­Îq8qBnÚ­ºãý8~>�mûº°e7Þ<ÙƒKWûÐÍö:.·áX 6¢¨á~ä–-B V¯�æ$[ªŽÃ.DAízœ;ð]´µÇ±e_7ƒÇC BO·:ÝæK¦õ.�­w³ëƒ­w}Özg¹OŸa©õî6üô’ˆ€ˆ€ˆ€ˆÀÔ$ ñijÞ7ÍZD@&’@€'7wÓã¬õ¬zVk0Ë)ð`&�=Ë[ÃNžSM©1s9ñ¯Ž BcÙVÇy8çððD&+]¸’Äî#ЏjÝþcqœ½”ÀÕÎ>gõ:ÛÖíñ#ZЀ¢¦PT?b¥­ð…Š�ç]M±¦éŠ€ˆÀ0k�……¯b™Ói-ËZíLtrlA&*å3ÇhÁŒ0–Ï a[ëJÍåtÃkñã]Ñ);�†;Œ~ØÌåOôãÀ©8^£Ëiûþ;ÛÕìúÐÅ<§¾¾ô|�rÊæ¡¸áä×­E4&¼l·s»© q˜èÔoüž‰áÁœºŸÖàÊé7(õbç¡´Ôênƒ[ßî§õ®$½êÅ'ãWβÖ;‰O·§×D@D@D@D@¦$‰OSò¶iÒ" "0nL)cÝÏ2ÑiáÀÏ9|4A nQYB—ÓÜ0–¶„Q_壣Ç\N.ÓjÒ‚S&NÉvƒa¢“­œ×ÕÝ�½t#mÞÆ,§ƒ=8×–À5†Š÷&'±¢&äW,EnÕ ¶Ö-@0·’­u1vÖy±Éq:ÝbŽ.ŠQ¾`ò+WÀù�}‰âS7ZE4˜Î“ºÅ®ƒO›že\¬õnnC¯ìê¤kªÏD<Ÿ>ËjÜX߈€ˆ€ˆ€ˆ€ˆÀ4 ñiÜD]‚ˆ€Œûû0ƒõë–e;•²lu6gx©:51@|õ¼(Í ¡ºÔ‹œ°;�D�Åäž¾1�lå<7•§ŽŠN\­î¹m�ض¿“¢S�Ý)çünoyåÍ _ᄈGØ2Š2Ë)�·7À=÷€ËiäÉÚ5¹Ü~DŠ›‘S2�üGÏ&pôt/æÏ 9šÖ;š¥Zê(æjyg/$B<ôlV+ë–†ˆ€ˆ€ˆ€ˆ€LŸ¦Í­Ô…ˆ€ˆÀ]!`ýcKX�±Ö±êX…,ËyrF8èqZêVµF° %„Ê"/Â7ó�ÆÑåDÑ©�¢SûÕ$vŽãÅ�]Øy° ç/§E§þ~[±Žáà5«PØørË!”[ ¯?#8ñéÖº‘E'gãôŽXå�”q¼¸xôY\nïåªw=˜Û4ˆhhóÛ|çñ¸œÿf×…L|² YëÝÖ‹,Ó¹4D@D@D@D@D`Z�ø4-n£.BD@Þ6s4YÛ—…ˆo`YžSËÒšœïü˜—«ÖE±’«»Íªåªutì¸j�µÝ9YN£Ñpì £ŽË‰_½ý8z!‰ízðúî<Çå«)¶Ü¥¨Ø¸ŒPtªÛˆÒ–G‘W± þh¼^‹V¬{k–Ó('‹õ¢ _‚@¤Ýç±›âÓÕÎb¡Q´ÞQnÊ�yÐÚ`› ‡×•²UïV°ŠYçG9+m." " " " “–€Ä§I{k41sæ¶1ÁÃN�²,LÜÜ7&:9ò‰*Š‚X<;Ä•ë"˜Yíc¨¸æ9YÎÒxˆN^:„ÌtåZ Ûű•!âûŽöàìÅÚ¹j]¾LõÅ�ư1Ì&è¦è”HO'°…‚Ó®Z÷æ©nŠP}èæªu)æ+YHx$¯õëQÔð ò*Í�d¢“e9¥E§ëW¬K_ßÛûÊóÒEå—:9RÞüÑ@ë]óš‚£:´—ZVèìú ŧÛ×rµV³~ÄJ±4D@D@D@D@D`Ê�ø4åo¡.@D@²&`ÿæ7³ÞÁºà{�,ìÚ¿›BHkçG°�!â•…^ƒnxÙ|7..'¶Õ1® í)ì>’À«»º°ëp7ηõ²­-é´ÜÙD½¾òË硸a#òk×"RÔ¨#«ÆLtJ3²¯&hù¶Þ-F€áå׺Ncçy¥#†Üˆ‰^CÛÞê;g^kNÔ�y�A<óš=‰T.·_Ʋ¶Çã·ÚWÏ‹€ˆ€ˆ€ˆ€ˆÀT" ñi*Ý-ÍUD@ù•°~Šen§zVËÂÅ��xÑÚŠNógQÆ<§ óœ¬ín¬E§L–So8r¦[þÆîn<Ñã´ÚuX–Sº× a††çU/GQÝ}Ìs¢ðc!â�\Î3ýçÌòœ²R~2þv]t]Ì@~Å"œÙ{ÇÎÆqèDËØ¢˜íªwvz?[ª¨,õãð‰n»Wv,ô]â!hˆ€ˆ€ˆ€ˆ€L}Ÿ¦þ=Ôˆ€ˆÀ­˜¸d.šŒèTÃï-ãi0D¼0ÏǶº(V´1»!€¢<†ˆ3‡hÔZGÑi\GºõÎÇõòè¼:Çܧ¶ö¶²5pas�±çYŠjØ^VàÁœ† ‰O¶£¹ÑlÕ»o³Øx¨!" " " " S›€Ä§©}ÿ4{¸ ®¶•ëž`mdU±Ltr4;*KÒyNKg‡ÑPa!â^:pœŽµ1u:Ù<ÌrJ2ÍèèÙ^¼¾·¯ííÁ‘“i—SgO }ŽŽä‚/œ‹®VWØx?³•V#’_ o°à:—ÓÝÏsâ³vn¯/‚¼òÅœ[=:ÚöcW½;w)E¾^'“j¤Ceºóba7W½ ⇯xÐÝ“Šq?s>Õ³ö�t ½." " " " “�€Ä§É~‡4?Èž€9�,¬úIÖ–‰Nƒ+×ÙªqM _3?ŠE-!Ô”yež“�N' ïc9ímÜén Ö¦M‰ÙH)ì?Î,'¶Õí`{Ýé t9u$ïMË0.·ÑÂF¶Õ­A>[ërË +ƒ‡"�…|[[�ÓZw·'x§Ç£++”W‡üšÕ¸za¯§‡î­T•DGuD»�~»°ïH—9Ó,Þî¥Ä§Q‘ÔÆ" " " " “‘€Ä§ÉxW4'�Ì)ó^Ö&Ö ¢“-\MmÝ´èTUìE8àfÛÚØæ9™Þd+Ö™Ëéøù$[ÒºñÚžN¶–ÅÑv-‰Î.®XgŠ Yþpò+ér²,'f:…sà åqÿá«Ö�wk§vÛÁÖ;¾î£+¿zNïþÚ¯ubÛÁ²ÃÇ,§l† ~Ä„b¶Þ™û‰â“íVÄZËú7VKCD@D@D@D@¦,‰OSöÖiâ" "û7|.ëgX±jYÖ^ç /íF–#´na ‹étª(ò0Dœ¢Ó¯\7˜åÄܦƒÌrz}_7vJ»œ®X–S<-"¹\v×¢¨~= ëïGNé|ºœJ\NN,Õ€Ó)íŠÊ\×dz4áÈí ZÒŠ³¨®œz�¡ã=8u>…Æj_V­wv=v…Q¶ÞÍåýúAÔkn°Ÿ²{;‡õ KCD@D@D@D@¦,‰OSöÖiâ" ÷0Sff°ÞÍzŒÕÈ*d9V/C�ÌA³nQKg…QV8ö+×Ù‰-ËÉV¬{ót/ÞØ×‰-û˜åtª—;RÃ\Nt ù£È)ŸÏððMlW[Ã6»™ÌrÊŸä.'^àMG:x<«D�[m'^Ņ˽Øs4îˆO7ÝåOúȯ®Ò‡úʶïOÒ –µÞI|º3=-" " " "05H|š÷I³#`¢SËV¯{„5‹eíYŽMÈ2�ZêCØ@ÑiÙœ0ÊÇAtʸœ®ÑÑ´�.§W÷taûÁnœ»È,§.f9%\KÌk çU£€ÙH…�rË"”S�?ÆÕìœéOz—9ßb0x<E.ƒÇ}Á\ëìÀÞ#=x`ÙèZï¸øŠüÞJ÷ÓŽ�äáäu­àI Xm·8¹ž�IO@âÓ¤¿Eš ˆ€8âR9¼‹õV3ËD'çßpU‹úª 6-‰bEk˜+­ù ¸¸*ÜØd:™Hâæs9áŠu[÷wá�½Ý8|2ŽËW“èèάXG—S †œ²yl«Û€üªUˆ°5Í,d«Z�â®Ái²e9‘ì(†Ózçñ#RÔ‚Ha®žÙŠ7OÅq†«ÞÕs%ÁT*»¶AÛ*t¡¹.ˆXÄÇÖ»Þ Ÿ2‡ÛlÖf–†ˆ€ˆ€ˆ€ˆ€LIŸ¦ämÓ¤E@î–Ù]Ã2§Óã,!E'—*‹ƒØ°$‚5 ¢¨ãêu!®^Ç®;sÍ ï.k:ÖVgáD—¯¥p€+Ö½F—Ó®ÃÝ8K—S»e9%†g9Õ  Ö²œÖ;YNÁX¼ŽË)ýg'½j]v¢ ¯y\ƃ‹Ò1ôºˆ€ˆ€ˆ€ˆ€LFŸ&ã]ÑœD@îUöo²µYYˆ¸­^7“e¢“Ÿ•�Š(:-H‹N U^ä˜èäµöµ»ët2NŠF¦ÓmIì<Ôƒ×vwáà‰n\º’œ½i×’å5ÅŠ›˜å´Öœb¥sŠMþ,'?IçºpêÒ�ûê3?NâÙ�)lÞ=zËX?o€›­wÑ¢fs«Ð}ù[Øz{ ¥^²:�ÝË[ Û*bë]m€­“tÇSÖzgïË÷z™¥!" " " " Sހħ)wË4a�iHÀþ-neY{ݬF–­^—v:Ñ SRpD§µt;5Òé4¢“µë¹˜åÔÑÕGá$Ž×)8m£ËéÔ…®\MQɈ2."…ȯXŠ‚º È«^Î0ñ†nçM —Sm‰ úó~¢÷ãÃÿ#AÌéqì|?¬ît¸Ü>r*‘SÒŠŽ‹q±-�cg“Îjƒ£9¦­zW[áGe©‡Žw[ë]k9KâÓh@j[�IC@âÓ¤¹šˆˆÀ=HÀÄ¥¬'X›X ,[ÙÌÚî`ÁÞ&:­œÆZf:ͨ¡èvÃ{—�N—Ó©‹Ilß߃×÷Òåtœ.'k«c–Sr 0ÛíáùKf;‚S~ÍÄŠf1稔+ÖENåŠc2f99öåäÅ~Ä–ÎÎ8äG™aÕ1ìÅ;þ6Óz—G'ØòøÅ­>bû²9f^ÊrPû2°4߃–š€‰O¶cËV½û4K­w„ !" " " "0µH|šZ÷K³˜¼ Ëñ1§ÓFV-ËD'GÁ± ñê’ VÌ�`9…§¦ª´èäóݽöºL–Sww?öéÁ«ær:ÐE—S¯“åÔs�Ë©ùÕ+QÔ° y•ËÊ­¡Ë)—m€ì¤@–œ2®(^Å$Qê>�¯ôâ™)œh±³vÂÿô©8Ú®Ýí‰ö;yOa¶ÞùQæduàÈé^tw÷Áï7ÓÈÃ|W¶e”"ã¬Æ ~øª‡A²-pþ%–†ˆ€ˆ€ˆ€ˆ€L)Ÿ¦ÔíÒdE@¦8�0翊e+×m`U²,PÚQ&ÌñRWš…,›Fm¹1f:ÝM§“­XgùP™Ý´ãp^ÙÙ…½G»ùs׺RH ¸œ,Ë)RЄâ†�(¬Ûˆhé<¶ÚÑåä ÓÕcÇèãÂwTqL-ñj¶OP<úÈ?µÇ�ætØäţ˽(Ís᯾Ö;¸ëÝžL„³¶EBy5Æ*ÑqiN�OàB{j¸a†íà$nñ�!õÓÝÖXÉÖ»?Þ<9Øz·†/YëÝS¿ÅÄô´ˆ€ˆ€ˆ€ˆ€Ü!‰OwN»‰€ˆÀ(ĸíZ–µ×™€PβV*g˜ ÔXÄ:‰/k�ÐõäEØD'6ßÝ� qkßsóñD?ŸLàU¶Õme?—Àå«I:t2®%;9È­ZŒ’ú�W³‘üF®â–ï„iÛdÇ»­îÅ=}øEF¯Ï¬táÀ©‘5s�õe.‡óýÊ )”å»ðý7Øg7ÃåA \Šhq3®^Ø‹KíÌ}:“@�‰O£8¿ÓzÇ ò9 AŸlO)­õ®ˆu�¥!" " " " S†€Ä§)s«4Q�)H ‡s^Çz’µšeÁÑöœ3,k©¥ÎœNQ,™BU1E§ W¯»K¢“ßÄ«6f7í~3ÎÖºNì:D—Óå$óˆRèM¦Å“0Wh+¨[‡¢ÆMÈ-]¬Œ-dÌr¢ÊVr3Ñi¢Æ×^LáÉÕ^ü·r.Ý8ÿš}ð/–5»ñ«“`NUz‹óWúñ_?{ëýn<ÎÛûy ÷)Äܧ’¹píý&®13kß±8Vͳιì†Ý3óÂY¾×܆~ÄֻµjÚªw X?diˆ€ˆ€ˆ€ˆ€ˆÀ”! ñiÊÜ*MTD` 0�i=k¸èdî'gøýnÌ®7§S [B¨(ò"¸;¢õ&¸ø¥gÀå´e¶ìïÆ±Óq\¦ÕÙ�r)›ˆÇ¤Ð4ßœ jÖ"RÔ_°`Ò­X÷Ã-)üì/JØ:gbÒÍF/�M­unÇå´ Á�×N�XFåÈë‹P|j…Ÿ"Tg÷eì?nìûP”ë†åMe;,㫱*€šòöé²ÖL/ÍA÷ÖhŒTÜ\CD@D@D@D@&ހħ‰c¯3‹€L/&˜è´‘eAâ§Ó è x0·)„u‹¢X0#ˆ2¶U.w¿ýö:s9õQ—9ß–ÂNˆ¿±‡YNG†²œ½¢ W¥ ÓÕ”W» Eu÷1@|)‚¹ÕLb­ÒÆ»µŽ¬n;â4.=õFŠÙOüý÷ÒísÖJ33©çE\1ûÜBÅ¿²¹Ÿíy£Pxn{æÑ¿h”]n:ؘ—áj€mÇ_ÀÙóq¼y*�â<›ðÍųÏdî'‹ù™×4ñÉ6ÉeYë]%ë8KCD@D@D@D@¦‰OSâ6i’" “˜€‰N¶R�‰N�³V²Ì¡e9#DÑi^sëİ`f%ù^Ltâž&2 Ï(Êì“Íc&Ë©«§ŸBS^ß×�^±î�­u#]ï7_Nâo#€—÷™•n¯3ÑÑsý¸tµÝÌ#7*—BÔ¯¾Ó…k\Åoë¡><·‹-‡Ç²|FšCv¯³õŽŸ?ZÆ—áò‰p‰Ž³mz°¨%hZYÖÃf »ØzÄSQ/®v$}|ªŽe”Ä'BИ$>M�û¤YŠ€L>ô+¡„õë1ÖB–‰GXÎ0Ñi~së¹zÝü”ÒÅðSêy›¢“—ª“y{.qźí¶bÝŽ.æ u3Ü:½b]r0ˉ.§¼*Š +PX»9‹™íT O —n«a.§,Ý8—5!ÕÅn$izú½÷úðÛð¬ÅîÅ=)|â›É›Šwµ%.,�鯝=êsòŸ>û“$^;0NŽ(*о@ ù+à�££ë"vêÁÙ‹)T•f¿ê��öÑþTWésé·îë°§ì=·ŽõMVKCD@D@D@D@&=‰O“þi‚" “Œ€‰NÖöô0ËD§V–9�¥ÃAN¶×EØ^@±9�LtâFŽÓé�8ÖZ×Ë´C\=í5®V÷úî.;{ãŠu,üQä”ÏG!]NùÕ«.œA—Sá”q9Óàh­uá·ßíw»/¿�Ä“«¼ø—§ð…gS̵Üì-ß;ß�cçSøòæ”Bþ yñØò~|üë½t"½eó»ú„Ý^—Û�HÉl PKpöÀ÷pê<[!éL«*ìÂñœö^1w[QŽ­�Al?ÐI¡­ßu‹Xͬí#Dˆ€ˆ€ˆ€ˆ€ˆÀ$ À5•4D@D@² `ÿ^Ö±~–õ[¬ŸfÍg±¬ ÑÛÁæDñÞóñSëbheVOAŽÇq¯˜¹èN4'<^¬µn;Ý3_{ö*¾òt;^ÞÑÁ¡8®°¥ËV­³ë"ù5(ky µK?ŒêEDqÃ&D gÂ̇ÛÃ)ššqG³°«ÿQSìŸý¢ßi¥ûæ+)üÛs),j¢öÇË8x:{š§.õã{¯¥øíÂxÂ�GúpÙ1ewM.òPóaóî,*›a­wnfhõÆÛÑvì9$˜ˆîáÍ\À€ù0[.³ž½ÝVoŠm„ûzø>H™øiušõj6sÑ6" " " " "0Ñä|šè; ó‹€Lv&:Õ³e½“ÕÂ*fXŽ#'7æÅâ–VÏ Ó¡@a�N\©ŒšAÚédŽrxL^`Þ¥ö¶2/èÅí�N€øå«I¶q¥œpq;¤ÛíCnÅ<7>„‚šu ¹žÉëèrò¸ûäÏrº‹å6Y~S>ý=ûe?¾ô\‘� ßy%4þ•Rø]L?Ù~ÛÓ�åÏÆnâÕq:¢>ñá~þ/{p¡ý&Þä©eÍnÔ–¸a"Ô—žÏn‘¹~ }^:Ðò+—#ÊUÛÏnÇa®8¸ûpë†ÑG1)Ûáå{©¶Ì�®�¸y«sÝ…Üw=ëó¬óÙGÛ‰€ˆ€ˆ€ˆ€ˆÀD�ø4Qäu^�ÉNÀD§™,k­{ˆemN&:QI‹N…¹>Çéd¢ÓÌ:? s½ðó_U�LìÈ^^°#¦‡‡6Ëý>u�E{:ñÒÎ.ÇáÔÆ<§îx&³È_86Š›AžµÖåÕPìÈe»WÚÐ:ÙV¬Ë\ß­ ¹Nào½ËçMÿýK½øÔà¿)�gwf®9½ç¶Ã}Žà· Á�mo^ÿÚ­Ž=üù—÷õá“ßêÅÇ5€ÿò™Ýà ²ûWL‡”¹¥r ñ*pá3?Nr):ŸFw¾~ºÑBù lÜ€«çv0£+‰W¹ áÒÙAøèfËfdZïòé [03ˆWvvÒé–2áÓÞ�‹YßËæ8ÚFD@D@D@D@&’€Ä§‰¤¯s‹€LFöïâ\–‰N&ÞÄ2§‰ÓZG3Š üXÙjN§fÔø�Oç“Ï^¥Út§¢““çDsÏÁq¼´£ÛžŽŸK ýZ’-[2[¹Â9(¬Û€¢¦¹zÝ"båðøÂdÜtYõ9Å™L¹qµ ¨¡»(@Žÿåg}øÔ÷zß"e¶ËæÑKC[y¡³CŸâ¶ ½bXʲðûã, ˜´$>MÚ[£‰‰€Œs�ä±Ö±a­f•³Lt¢ü`™J@EQ«çG°‚ÂScÕ]�ØZ—¤Xuü|[÷wã ¶b<у¶òœ\ÌsÊ+Ÿ‡’;+×Yx¸7XÀ9¥ÿéžj­uÆÓÆûïóâßmð⻯&ñÉo§³œìyzÖÏõàWÿÆWì©›ŽÙ}‹POÒýô×_Úÿ¦ßâÉhHp×…�n¬œåÆòV³?Ø’ÂçŸa®V÷-vÕÓO7W¤l�¼pø‡Ž¨¸ƒÁñ÷/‹"J‘-éÌÄMsÜåDÝΪwO¿æA<‘2¯]-ËS‰O£º/ÚXD@D@D@D`¼ H|oâ:ŸˆÀd `ÁHÕ¬M¬Y YÖÆdng˜ó¥¶<„U ÂX>;ŒúJb!7¼Ìê¹§“­Xæâ—ή~ì>ÕƒWvuaûþ.f;õâ ]NñÁ<'¶jùcÌqZJÑéȯYÍ<§ú�<§©ÝZ—aûÌŽ`x÷±\K&&}ïõ¬o¤a­sÿø›“'Gµr]æ¸Øäţ˽Gpú…¿Š3W+³ÅÝyt‚ÇÄʲE²=íÇqäds¼XÈ §Œ»m¤³™Håç{¯©*€êR?�pÔ±>½žõÖ]ž9�¨!" " " " w‰€Ä§»R‡˜,¨y˧�¬&–}€·–;gXöRsmÈÉsZ<;Äú‚MщrÕ�ˆNÖZ×Gáéâå¶ìÆËl­Û´›íf)§Ý.e!Q6è� EJ�_·†!â!¿b99•S:ÏÉÜ:ëZݸo¾ý×ÞÁÖÄ“ûñÁ¿Œ®Øg—oYOæzú¥�g§¡XNÓÓ±L@²@ð‘†9Ø2­‘�å.'H¼7Ù�çv¥œóšãén OCsâ{(¿ùl½;}å8W0Lb;ÝOóšh¿Å0A´¼Ð㸟ħw·ÐñFÖžQJ›Š€ˆ€ˆ€ˆ€ˆÀ¸�ø4®¸u2� @ Ä ·–º‡X+X–“c­uÖºäŒHÈë|¨_17‚ùt¤T2Ø9pÃs‡¢“­ZgíaGÎ$ðÊî.¼º«“G½¸|ݪulëóø‘[2 ›œ`êHѶi•Àí ²ÕÊ\VS7DÜÀ¾�íu5ÅnŠP)XVSfd4·ÌÏKgº±çx_V®§Ì>_1…¿ú?¾ø,CÙo¡?ùøWîƒx±¬Ùíd;ýÌ:/jKÝøòæ$þ_ bIFKÙ w«f{ð�Wo�3•9çè­õÎV',¢›msŸ¾ƒk]Iì>D²=†’<ß'ämn§-£ »)Z…ð£W¯¡£+Éw'jXëXŸACD@D@D@D`r�ø49ï‹f%"ðö Øó:–¹œîgÙ vÖZgn¤`!âÅù~,h c]N³¹šXQ¾A¿ËÉzº#§E§xØÇUÍ^ÜÑ…7öuá4[ëÚ;’ ÕΈ .ø#(¨Z�¢Æû‘WµáÜjxü¹£ÒzØTÌs2gN„fžLÛœñû§§’È‹¸ðü®!áÉØß8æÕ»±ýÍÛosã>ç®ôcçÑ>§…ïV‘™/¡°U–ïÂï¿Ï�ùQZt2a03vð¼+f�•ød޹~¶M†:¾¡ÜZt´âŠw æ|%Pš?hºËLç¶�>¶Þ50쾩:€mûÅÍVb4ñé ¬+·ÝY/Š€ˆ€ˆ€ˆ€ˆÀ�ø4AàuZ�1#`ÿ®µ²Þɺ�5ƒUÌìqòzÝh¨ `Åœ°#<Õ•y‘—ãu0Ö*6Zщš �JÌsêîck]ÏoëÀÖ½]8…ÁÕÌsÊ8[\.®äVÈUëê7¢ ~b¥sér*gk]È ¦žÊ.§YÕ.|ä=~<݇?ýB/‰¤‡­*—ÍhªpãÇÛ†öËfÛæ«/$ñŸÚ7èZ2‘ÉD°S—ú±¸Éí8¯¬eòÿ0‰/¿�rîí�ÇÞ{¢ïßäè‘7¾t×~v¹¼NvWnåbG|ºÌpùí\ÙpÙì #‚fs"{_š`Z’çż!ì8ØÅVÂ~S¯f³æ³žÍæ8ÚFD@D@D@D@Æ›€Ä§ñ&®ó‰€Œ�0¼œe¢ÓZV-«€åX‰LTŠE¬µ.„å­a´6¹Š®8f!â¶ì˜u?ÙülMNŒjrq•6æ9ˆã…m�Øq¨ ml­»Ö5ÔÂå¬ZW1¥ /¨_�pþ ø‚yt9Y•�sj·ÖÙ5œ½ÜO‡W, «‹YnÕgÛÞlTºpŠYP£ûOö;�ã¶b�Ýãßexø‘s&x¥E¨/°%oóîÛ `æ *ˆ¦·îˆí\n½½][ïBi·ÛÙ}ß@WOûŽÄq®-…ª/R©ì®Ý¶ Ó™×Ú@Aޝ$xÕÎ �öžžuû‹å" " " " "0Þ$>�7q�ODàn°Þ¶BÝzÖ㬕¬2VË INû\YaKf…±tNÍ5~äÓåàxsÈŒÖådÇÌ„ˆ_`ˆø–}Ýx~{ëq‚¤»z†>ûÛªuù5ËPl«ÖU¯aèt]N1 Vž·ß�ìxSmX8ø#K=ø>W¦ëa‹¡�ËÀüûŽžËNDIï5ô5B®+»¬ñ¡�¾ûÝOO®òâ‡[Ù†ÆwDq®ŸøF/^Þ7t/Þ²Ó°'ì=§é*Ì9\s‘öâ]úÖî·ÛF¬l>"\½ðê…½8s)Ž=oÆQMñi4Ãës9+Þ5×qq›sìý¾ŠUÎ:5šci[£û_¼ã1#�CD@F&`¢“µÒmd=ÆZƲ<'¢œaÂR]¥­ZÆb Ou öfX³—ÿêÝIk�4"~ü|/ïêÀ+\¹îÈé8Ú®¥�g„:Âù(ª]�âfŠN•+ˆULéUëÒD‡¾þÝEË[<áÀàî!‡×� Oƒ÷cºU}© ï^ãÅß}·—¢‘ 3«\\1Ï‹?aËß+YŠNCW”vjY{ÞXk» åÖQ�\áˆO—¯%±•­wk„8w{K�û"þòžn¼±§'¹rÝ•á!â.7Â9å(j¸Å�� V±Aæ9¹½gµ³éÐZ—aõÍWRˆ‘é�S£P‹2;ßäÑîI/5,[™Î³¿ð ‹fx°”«Ø<Ù‡o¿’DOw"<ÙùB”o2.®lÎ?úm¸ê�µÞ… Ü™=_EwO;[ïzpød/W° på½ìx/›ï,ä—øhïXÆL|ÝÀúë=dÜSCD@D@D@D@Æ€€Ä§1€ªCŠ€ÜuæI©g™ËéaV «„5"nyN f„±j>óœè)ͧË$à¦pt‡­uœ,êR{ ;õàµ=]Øýf7.0Düš…ˆæf 62Ïé!‰?€hi+³}Šà¡èdc*®ZçLœ_B¼„÷Ð]ÔPîÂ~v( |Ûa«è·Ëlü6/]íGYž 'n‘ûdbK7OiyR/ñ ‘ågÚúð·ßîŇú�ç?ýÛ^”ò–á4š‘ô0»�vüÑ kÓ{|…ÇÎ÷㥽çÛ­�à´Þ1ç+V:9¥ópñèó|?%˜Ö�9ÌpÍ0^e±-Zħ(÷_šÉÚ9šci[kŸÆš°Ž/"ðv˜èdíD&:½ƒe¢S‹RDº}./æÅâ–V/c?ˆæyœ¦ÁV®‘5;”3ÌVe.§u–Cgx•‚Ó¬cg¸ÂÖºÎî¡3'D¼|.Jœñ�ˆ΄7XÀ–(ûguêæ9¥I¤¿šÃƲ�rÂ.4”%ñæÙщ:Ã�5Ò÷Ç/ô£ºø­âS!)ë]>D9‡çw¦ð³�vëÃÿýéƒÅ‡æcç–AõS+=øûïeiŸ˜T��—çíX5Ûƒlòáøù>ŠOÙ(Wt?Ñ!Ì©DAíZ\:þ¢#dî8Ø�WFQšËàqƒ>°MÌ‘—ó`~S›·vð=›²ß•jÖZ–ħêe�ñ% ñi|yël" Ù°›f°~ŠõËÜ–ñä¬\g¼KŠüX6+Âöº0f2D¼€ÜÍ×lá:.AÏ/YêMΧù®P·çH‚yN]\ƾç.%p•.§Þä� à ä ¿j)Šš¡€°a†G{ý¹ w¸œFqâ,ç7^›ÄÒmo™ÐmkCûä·zq¡½L…'»>”æÕ»ñâ ¢õ¾™Un§ÍìÂ7~÷Ÿ8y wÔ·Øz÷·ÿWŸ{:‰Îžì©µÖ¹±‡çiXк“gÆÓÛSXÐàÆ÷ß…ØEåȈ"¯b‚±2t·ŸÂ‰s ì=GÙ¾�‡ôÍÌinúhïHˉj® 0|ÜÇÖ=gÇB>½žõVKCD@D@D@D@&‰O“â6h" ìߤfÖ¬‡YM,s:9ÿVYÐreI«çG°¼5ÌÖ+r"'+ˆÛ8mrC2‘=sûa­Kæ"9Û–Ä–ý= ïÀþãq\¹š„ QÖvgÃi­Ë«¦Ø´Ž™N‘[¾„!âå �N›<§yðk�z™�”Â?<5$¦lÞ=²(“¦ôö¾ÚÊtñ!?^?ØÇóú‘çÉÕ^§ÅnÇ‘>|æÇÉWÒ³÷^Þ—Â;èÖúÒóYª8œöúy|üëÃT¥›\ÊÏÝïÅ£Ë=øÍÿ•À©Ké7FŠhþâ+·ßïÆC9{º|5#¯r‰#>]jOâ ®š¸bnˆïeSB³ø^QäÅ<¶›>é¨mÖ†:›eüßÏî(ÚJD@D@D@D@Æž€Ä§±g¬3ˆ€ŒLÀþ-šÅ2§“‰Næz2‡µ9«{UQtZ³ ‚Ut:ÕUúxm+ץţŒHdÛŽ4Ìåäâ—îx?Rhz�ú_g€ø ¶Ö]îH¡gpÕ:ž×BóyŠf<€Âê5Ìvš ŸµÖ]"> P�tâIþú¡Ó}çhhb&z¦­&æ|ô~9ÛÇðpžÝ‘ÂoüÏ8.^Í~N_}!…?þ9?ìÑŽ7Ò˜YÉp¾Ëö�¸ý}4.¶ªÞ’™nœz){aë­çO·ÞÂE\õn-Îü>ƒÇãØ{¬GÏ$ÑRçÌ{ë¾CÏ8Ýy|/G#n,jâ'¯ùÐÞÑkÊU%ëÖÓ,�‚†ˆ4'=¥@IDAT€ˆ€ˆ€ˆÀÄ�ø4ñ÷@3�{™€e7-f=ÎZϲ|§AÑÉCgGUYkétZA§S=E§h˜¢Ó€ci4­u¶�‰g/'±óp�“å´�ø/òç«t9%3­u ‹ FJPP³E Ï«^†Pn ]N1¶Ö9ZØ”'_Tºð�NŸþQÒq~Ùs–çôÁ�ÅqiB�íw·Fq®Ý›>ÄÜhïêÇü‹‰�£?ºeG™sjý\7~²}dõé½ë¼øÚ‹×‹I% -//paû›CûáÙ$¾÷Zê®´Zð¸ÇAtÑ‚&´ŸÛ�ólñÜz ‡mtNœYÖî§ÛPåÇl–¿´Ãqa1% +Y&ænËú@ÚPD@D@D@D@Æ�€Ä§1„«C‹€Ü’×s> gD'sk°,ó&:Õ–‡°vE§9t:•{6§Ó(E';Ž%3wvõáÐɸ#8mc–Ó鋽Nk]WÏ�¸`ÂR¤pJîCAý}ˆ–ÌE0\·?Ä)sXõ9eó›êã£ï÷Q€r3T½Ïïb0^“…Á¯kuã¾ùüÃÁß³Öƒ-GÜ øúñ“m©;ž2÷Å\O¿ôˆ—âÓíCÀ—Ìp£¦Ä…ÿï‹CâS]© ÿU?I8b\rà%cc+òݵÁUCÌ Ë¯YãˆOW;û°uî_¡ëËÖϑÏe›XþYQC÷g…ñÆÞîLðxçy?kkèó ˜Ÿ&‚ºÎ)÷.�Ö²Þ5ðXÁGz^œœpGtª« è´0$^Ë åE' GöA;[§SÆåtêbÛ˜åôÚÞN¤Ëé2W¬³,§dj能/CNÙB”4Ý�|f:EòÒ«Öyœló´èäD˜s–St˜@1¼5ñ‹Ï¦ÐRÓ‡ý'&N—xÿ&/* ܘ]ëÆW6'ñ‹G›Ä6ïvá�þO?v‰ã|û�ßFÇ’½_4º±íðͯ1Æ6ºßx܇¿üjïuíyG¹‚Þá3ýN¨y8G„º³YÜn/¶Þq~þPž“#vfÏ—$ã§ãØy¨÷Q€MðxÈïÂ\®zW[áçû¼ÛNlBîÖçY§X" " " " "0¡,BCD@Æš€% ­c=9ðh¢“µ9ÃK‹RK]«æE±dvÕ%׋NY˜@Ë”›Î¨xo:Ëé•]ÝlcêÄ©ót9Ý�åär{+š�æ8å×­ANÉ<ˆWÀK!ÊÂÅÍå4FY¾ËqÙÊo£È2QÃhFa››È�ß|‡ù\%n+…¡O|£×�†Ïí]«<ØHWÔïÿs£Xµnø1î›ïƉÿ—ϼõº½3¿ñ_ƒxŠ«Ô™póÍ—“Ø;,óÉ‚í³:‡Ÿstß§ÿüv¶À¾|ç˜ýº±qY~óg œy I¤·>²Åœdm×úðÙï]Æ¿ý°ÍÞøô!Ö°¾ÀÒ� % çÓ„â×ÉE`Ú0§Ó*–‰NY׉N¿­�é ñ3CÎÊ]¡ÀèœNÔ›˜ÅäÂÕÎvNà…��Øy  ¸‚Ø5>—ʸœ\n„¢¥È¯Z†‚ºõÈ©XŠp^-§\¸=�i³jŽíNÖZ–àâu&þ˜5ÞcVµ y9 4ÿÓ/ôb�N»ŽõáϹJ\ïТz×MË2˜Š8þwÿ>€ýu݉ë^Îê‡gvöáçð¡–muÇÎÉ8&<ýõ¯øñ¯O'Ñæßmð Ș¥�~nH¤{áÉ.!<Œ–¡°a.}š!øq<Ú…Ç£Nˆøp‡Þ­.:se±� [BøÉ«~\¸â+å>÷±¾Íºƒô¬[�QÏ‹€ˆ€ˆ€ˆ€ˆÀè H|=3í!"02s5m`Y¦“‰O&:Y{�3Bæ5‡°~~”ËÄQRèuœæ8ɶ½ÎcùO4(�a`ø®X÷2E§ÇÙZ×ÎÖºî¡ ·/Èëæ¡°~#�N«â÷�p1Ä™åDAÊF:Ï)ó1ÞyjJ~i­uaÿ©þAQçÛÖþìK½Øu´oB„'ƒxör?òØEVÁo?ÿâ¼v ;WÙß3 ª½³ûe?þèó½8}it÷Ç$s4½kµýµ´ÊÕPüúc~ØÊ~Ÿ£ød+ØÙ]ùµo¡‚�ñ»À‚ǽþ(ò+—!Ê•ÛÏîÄy¾Ÿ-»i^-b£¶òcC¹­3Bxú5G|"u,bÍe½4ŠCiS¸ëÒK7ÝõÃê€" ÷(�(¯Û–yÿmÖ‡XËXU,ún�–̉á}æã]ks0wf�aÉø}Ö<”žœonóÅòœ’)3@ü{/và‹?¼Œg߸†'âh£Û)a«Ö9+Ö•¢d惨[üaT/þeÏx‘¢Y„ èt²ÅLÌÈÔmN8E^úð;½Ž°r¥£(@eÆ ®þ2õdž“Ç…œÇVx¸Ú\?ïQú=ÔA^Ù߇}†.´ìt§Á¹í>–Ò>òL˜Üw²?ÓR6¸Íí¾±yüúc><·3…¿ø%?޷ދ￞Â?<•žœ9¶°õïNœU·;oö¯9¶=^›=W�ãÊ©×�<2·× sæF­4»£Yë�—¿G]Ý}ØÂœ3º¦ì—Êþ¦ó¬YY‰[jˆ€ˆ€ˆ€ˆ€ˆÀ]& çÓ]ªÃ‰À=JÀœNkXO°Ö³ÊY1–3‚�æÒ‘±aa ›(¥Ó)ÀÊö�9§“f[ž“­Z·åh^ÚÞ…m;¹<}Òi·Ë´'Y^S¸°%õ÷£°ñ~Déx †Š§åŠu¶™GËOZ?·ÿº`ñÌkãõø;‰–sÕ:j'øòæ!÷™‰@w:~°%…Gú𡇽ø§ÿèÅW_H♩¬ƒÀÓåô7¿p¸ôP„Û7,ÛéNçt÷öK�û‚¹ÈgþØé�_D¼« §Ï÷`÷áT›–›ý°ß©–ú ê+Ø{„[@>k-ë3¬ã, ˜Ÿ&»N*Ó†@¯dë1Ö ›†‚Ä£a/a¬™qÚˆ¬½.È€gGt¢ fø lÜï-ÃDŒ~nl«ÔmÝÇ‹Û;°ûÍn´]M:«Öe\!n¯ye PÜô�“ça “/˜?àp2�‹«ŸM#ãÇŠ7æÖ¹ñ©ïµ‹½¼�G‹ÃœF5¾ùJ –=4Üyu7æb­{ÌÖ»†2޽ƋŸÝèÅ æ8m§(uúRöA÷R¿Óº™Ëf³Å̹ª+q£Œ­~{�÷9ï·�|*�Ët…Ýi€ùí®##¢߯BÖïchúkR¸Ò9ü•ë¿7YÎÅ̱hÉl®º¸Þü ®ðý¾å`Ö.Ã7à ¼~¯·þd¿ ÔgQÆß±Å-aì?ÚÍ߯~zÑÐÄ2êsoÝKψ€ˆ€ˆ€ˆ€ˆÀø�ø4>œu˜N¬�§’µ‰e¢Ó|–‰Nƒ6�pÐÃðã6.6Ñ)ˆB¶Ö :�²�ø)ÚZ´Ž_°ü›N¼Ê•ë�èÁ%¶ÕuÇ3½[Ì s©úêU(j|yU+ɯe–SÈÝiÁÉB¡¦Ù°àðß~ÒÇ•Ñ\xnW ûÙŠ–ã%<…GôŠ@ å.üág‡zú¶Ñ}µ�¡ïc5Þ<Û�?ÿr/|üË5»Æ�95.,jò8™R&jÚJ‡~Ê-³k<Ž(õ�?�;-‡¿û^®®×èÆ·)ŽÝÍaV…ôüÅÂntõôãÒÕþÁ¾?êÅ#K¼øÊfþéC"á[ÏŸDÊQP³—Ž=‹îž2¿ìع$škýC¡ùoÝùºgì�åûÂrÔžzÙ‡ —�{aÁãö»ú –‚Ç ACD@D@D@D`ü H|æ:£LUôr •õ0k#«…elÛœ‘ s›C©õ ¢©ÅÍAaE'!›Zå´× é$™]‡·ÖífžÓ+»º°�«Ö�¼Ð‹öŽâ‰!‰!ááÜJ5lDqýÈUÌG0RÆÖºÏÃrs9M#ÑÉ¸Ø m–OdÃV¬³°lçLŒ™ˆa÷ò‘¥ä„r]–÷yØ*yÛßìcÙÕ_/(™0õ—¿ä³ÌyêxÉZõ~‡ÔÝŸìž4U¸ñ83®êËÜ8ÓÖ�§ÞH9N'Ë»úî«)G ÛwrdÔ‚Ç}�(r«–"«D÷•ã¸ÐÆ øC=Žø4š{lÁãue>Ìn2 ÍŸ,xÜây,Ë~Ò�q' ñiÜ‘ë„"0å؇Wk©{k-«ŠeívÖÒãKѨ—KÇÙ&AkCÀURà�Óédÿ¾¸­µîv‰µ � ‹µÖmcPò‹;:™WÓM W­ëbHu*½·ËíåŠ`M(žù0Šë˜çT2>†‡{¼N–yZtºí™l¶SkÌopã×é ynW>û“!÷Ì×_º^pë«*`z— >׺Óg2‡Õ'¿Õ‹ íýã.< ¿ÖÕ³Ýxï:/þäó œçÊ~6lžÿþo¯w_Y`ÛU.»8Ë�÷Ž,¥�tû¯y3¶D f ¿b±#>]ëLa;ŧVD7Óí~‡2Ç5QÐÄʼ\:æÿ—½LçO¯6¹Ž�/³î€ÌIõ(" " " " Y�ø”$m"÷ ûÀj"“}`}ˆµ˜e!ây,{Í%ù>¶×E±z^Ð :.̵ qFì¸ú½41…'½Ê]fûá�~J¶Ôç.¥ð*[ë^ØÑ…Ãl­³ë†ZëøaÚD^éB®\gyNø½‰yNl­³ý¶úÙôý,mmd•En,� ŠOÃé�ß÷.òà×(€™kèžÀ6ïžxînnî£w.óâŸ84·›Ñùê‹I<¹ÚKñi‚ÐÍ4ð\.ŧæªÁ_'WªŽ¨9µnŠO£­õŽm¤¡Bä׬ƹßa»`GÏôàè©æSHÊ„êßfJÎKö;å�×QYâÑSÎ\,xÜd�mõ; WŸÆ·N&“ž€Ùˆ°`™ðÔÄ*f™ûÉ®\SÀÒ9¬˜FC…ù9^'‡Ç>Šóï«/å À�Nöéùé|²v½Áá¥ÕÉÜ)‡ù¡úÕÝ]l¯ëı³ 'dyxk](R‚ü:æ9ÕnbžÓ2ój¸”|Ì�¦[k�Á±6®5sÜ\ÉmHÔ±•Ùþà_ÌQznä8}sˆ«Å1B ÑÁæÊq:ñ §±9”廘ådòJz|áÙ$vëÃ�·�,ö¼DÇÓ/RF5ÁhxNVæXÙ>ZæV˜™W–õT’7$>Ùþ~¶¼Í¨táé X”íÓÛYë�ÇFné„òêÐqñ.SˆÝq8Ε"Óî¾l�hAý¥^¶Þ…(>±O“z«‘5—õc–†ˆ€ˆ€ˆ€ˆ€Œ+‰OãŠ['�IIÀ>A›«ÉÄ&�–²,ËÉÜNk¹ê–³êBXIÁÉV°«.õP�p;«qY»�S¶¡�tø’—~³™8ŸœMtŠó§=G{°yk¶2ÏéÌ…ÚÙ^”L¦s3™³©„«Ö7lD¨x‚¡bæ9…9½òœV_þüý˜YÅàjBzuÿ�Ø´åÐÐ÷÷‹ï+Ø:ö�NŸþQÒ¹Ÿvkû Wѻ͵‰&òü·¦ßŠúx}HLˆ:Mç\¶ã�þµŹi¶; ÛnY³ÿéÝ>¼~°�Vßÿ׋Otý±ýÎ sEYøø¨;Uƒžò+—8âÓ5¶�îáêŽW®Å�e‡´ßCˆcº°øÑ+þÞ9ŒLD^Æú +‹#�zöÚAD@D@D@D@nI@âÓ-Ñè˜öÌ‘ÔÌz'k‹Í]ŽË‰ ?C£€­tóÃX>/‚9õºOø™+jyèÔ±º!`hç;öÔ¹ýtú=.WOŸÛÏméÀ–½]8w¹×ÉsÊìërû�W>%3E!E' ¼Á|:nÒ‚ƒãtšæŸ—ŸÞ‘r˜Ž×Šu7Ü/çÇ�¾ß‡ Š'‡ÎôáyæLeÆD O6Ë–ŠtÕ•P<:{ùδ“cç™ÉĺÓqô\¿µ•Rbˆ9yì7hذŸó(•R,½øD©–ÿñ…ò‘ÇÏìùóšºqü\‡O&°t65ÜlÔ'ÎÇ®ÐGV=]‰åE>=íˆO¹|z!ËDå6–†ˆ€ˆ€ˆ€ˆ€Œ‰Oã†Z'�ICÀZpÌÝdâYµ¬B–Ÿå Ëcª¯ bɬ�$^_éCAŒ+×q9{sUÜFtrö7?ˆÇëruÅûüÛÇ{ŸÙÒز¿/'anŽÌðù£ü ½ÅM�  v-"ùõðør¦mk�]wˆô[îaë– Ÿ–Sd™Jß|yˆM†ÑX>Z8µÂgÆŸM¡¥†®žCÂSæµñz4qÇVÒÛÎVÃ#{lØûíÿùß ´]K?s1�éÑå^XkŸµ‰Ú8¥¿Lç• ¯z(-Œ¦_újó/ʱ߀ѧõÎBNÉ\D Ñ~v3ÐRØq¨ ›í×6ûa­wÅy>4U(> ¶ÞY­‰Ì/g$m)" " " " oŸ€Ä§·ÏPG�©BÀœëY�²V²¬ÕÎ\ƒþ�\®Z×:#Œ¥-!®ZDE±aºœ|>SœœÿÞÊéÄ䇇íu ¶×íx³Çõ£W®ù_ßÛÕg!â¶r]z0X9\€¢ºu\¹î:ž–#˜[IÑ)ê„.OÇ<§� wòÙ’õþû¼Ço¼”ÄåŽô«ÃE áÛ�Å÷–�ôK�xÑIMâc_í<Å�˜�ô£mƒ?NÈ7¶zÝûÖ3|O ò…¡¹�·ûê÷ßçÇì7¯~|çÕÌ{—ù êJ]l­»9Ç»3ñÉ9"[Oƒ¹µÈ«\îˆO�Ý)ì>܃‹¡Jé:LeñFqZïø[m­w³jxæu73¨úlRÖzg‹H|r`니€ˆ€ˆ€ˆÀx�ø4^¤u˜8¶Â•µÕ=ÎÊä91.9=ÌÉTÉñå³ÃX2;‚†* \Nò<’Ë)ssK%i˜Ù$޼։×vwp%»^�Nô‰pðD¡H1 7¡tÆcÈ©X„@¸œ«Ù†‰Ni§Kæ˜Óá1' GäI ˜‰N·õã_˜©tàTÿ ð4Þ×iÆ’n$èè±m¡&jdœt™óëå$E¾ÿÆ�à“ym,oœÇW6'Ñ6߃]Gßê³ü² ]€7>þU-`ãê�ǻٶo}n õ.˜‹|¶Þ�Þõ%ôƯâÔÅëE9Cij¥b¿·&„ÕWùa­³çÛœUþlµJŸø®D×[ϯgD@D@D@D@D`lH|®:ªL4ûdl­t±ž`-b•±ìC§3ìôŒšV1ËiqsÕå^Ä ç󌞅èd­[.;“ÀÓotaóöœ<ÇÕŽ��ÉŽèTŠ¢ÆûQÒü8r+ÓùTĶ<ªi§Óô�ìÚ_áÁÏÝïÅß}7‰l’ ¾¼yè{Ûn¬Gk-Wx£Ø•i»ÐüÙ—zae¢„'kùûÙ�^l˜çÆoüϺm¸Ò üÞ?9žÆš�µ×Ù=²�ð�~nè¼/ïëƒÕ�ÃD%Ëvòzì=Ën¶â]!ÛîL„J ný£µÞ¹½DKæ VÒ‚¶¯âÊÕ$vîfØÐµn½÷õ¯Øïxy¡�•�Œød¿ÿ-¬zÖîë·ÖO" " " " "0v$>�[Y&‚€}6ÑéaÖ»X Y&:…XÎ=\º=ŒU\µnþÌÊ ˜?dxr&@Ü>Sg¡™x`Ÿ„O]Lbó¶'Lܨ+×’9B."…ÌszeÍO ‡+xÂ\¹ÎcÑRýŽèäLh¹ÒÑï8dËß*RŒ×eø�^'»è}§ßb®Tf¼¸ç­ÂJæµñx´î±¹unºyÜXÞâÆ3;&f>½D²zóÌø×ÐVÕ³\§‘† P.ûr“áåïQnØ…3½½#ë­‡à>.¶ÞE«�_µÂŸØOçSœsK¡¢ˆî§,‚ÇÍùdÎÅܨ3Ùz÷ò®þÎõó§ÝÖÄh‰Oo…¯gD@D@D@D@ƈ€Ä§1«ÃŠÀ0ÑéAÖO³Lt²L§´½ˆßÄ¢:œ"X»�«Ö1Ï©(7 >šÖ:Æq^X®Ó%fÐ<·¥“n§k8r*�Ë�2Š}�(ŠÙ^W6ë= _IªÄ�ÌÕaN§é8Š™¨µd¦ß{mHày~wN|2>œ=×½•ÁÝëçö_,>ó0‡Q4ä‰ C‚̧¾ßK§°÷ÄÐsc=·Ú’ôJt­†ÝéÜ«#gû³žLÔ±ÊLå�ó5Q6Êß:kgÌäyݸÍH?s©H®ös[(‰î+8s1Ž'zQeâÓHxÝæbf[sM9/Ú;+V>_^Âú"kÀo6°ƒD@D@D@D@D`ŒH|#°:¬Œ#�îg=ɲL§ëD§<�fG±~a³ü(dþ‹µ™qÃ>œöe©ÙöÖÆsåZ /ïîÆ�_íÀþcÝhcKP2™q½ð˜Y­ã;?ñÔÒž8\¥w¶ðd‰NŸ%5Wv ¯¹x­]ªëì’žäߨw,³e{bÍ0q“O¤Æ²^O4ù4ðŽÐßê è è è è è è è C4ù4 IÔ‹Ð� �tÊV�eI¨;¤SH¦9“àé45~.–;žNÁ�NTr”ßèì!�Z¤¢ªCw»‡t§Ò)>_’ŠÖT:•‚tŠçdR¤“ŒÓ»?„‡Ò²©&ùÎO:åè%Y@ÅÓhKë–R%ãYÿŒ÷ç¯vÊ‘A Œ‘keT˜ÈW×Z$#Ñ ¿÷Ï�wH¬ÿã[5ÖȵÀµä‚4T`03G Û�?ì–ëµNå/ê¥<â”Ìcf¢QRãŒ2£Ð);@î…êf�kú@Ú9XÙËÿh>Or+/Ä,)r»)�µ`ZœÌf”ÞE¥NÃùÆQïêTéÝEŒ.™IòÉ�Åqݼ˜D†ebžM6ï3¡lVÍ™„�ç›…Étè è è è è è è è è —M>—7=—ÎÀHe€ýD*Ö$�Š’NwÊëèá4Fâ,¯£‘xt$¼mà1(éÄ‘ëºÁg\¬è”�Gšeω6©¼å"�h¨¬¤SLr™$?* yË$%@Òiü›‰WTÃ(»Ã(É1Ü-cßÙ*EF¨^:•jÇÝŠC]’‹×IBî ‹ÉsH:óT:�OÒi*|”Òâ òþ~�äí=vù£Ø5+›WnFûï6ø™@˜ DvŒF›&f¤Ê�*(…@ãqM>! :ttttttttF.š|¹Üê%ë ø“t ¥ éÄ»^¤;ÎI±V™[. ¦†Kq”NQÁ)�LT:¡s~¤ÓÇA:�lEG½S))¨šb˜LV‰ÉœÒi­$d/•И1¡ì‡Ã¾�WÒ‰ÛMÒé¯~Ç¢F0ûô”*~Jo%\ïFöo(´mkæ˜P®e�Ÿ|ä)[£wI°±ŒuóLòÅÕŒg—¿û�Ç»è쵡+�oÑŸ>cùd’¿£K)–ÜK8pÞ£kÃÈzñ><¤[ØîÔX#ÈT÷”½_y~QÕöø|L‡QúH4^Á(†\Æ@Aò‰ÇFa08…^XT@õ Ùߤƒ~Ž&Bm)QÉÓÄl “®Nœ·Õ�Ro¶„Vá¾x~s[£Â�29?D¶ì¿3ê Çïl¾Õ¡3 3 3 3 3 3 3 3 30„ hòiÉÓ³ê !ìSu@q–×ìªs’ÅôD›"œæAí”—a‘(x¶5zH'ªD8DûæƒMÁ®UùÆ4 |Çfk¨Äf.éô¨Äg/[T6¼fÂà3¾I'÷öÓ'èÃv¥šŒxpÏ3ܯ±0Ê~n©Yí«·vwK]³k î Èá^_ Ë#!·a‘Y®ÕxHž@æfZ–ÇE„PRê*_£‰ùÎvU2ÇÿЦ6§òÈâˆt� °,+ɨȠþæ Çzc„>Pï€è;rÉ¡üš|MOó…%Y®þˆ‰¨¬â6tzxÄþ&ðs’¾F³ %¯…•)Í5g¥¡ÅõS§L-ºc7à2Ü_òú‘�Ò»ìd›œ¹ÒÊ�9êÝ4 ¸ èÐÐÐÐÐÐÐÐБ hòiDÒªª3ÐoØc-èéô(@Ò‰åuè¦ºÔ $�NƒÒir„ä¥[$"Ô æ <�Lè“*¸r½J‡fùäh‹Ü¨éDy�‡tâHu$›’&¬‘¸Œ¹b‹Ì“¤Ø/¥tRK`ËÆO°Ôês™å×;»1b�‡Lù§·‡È˜"v· ú‰*ÆõÛNyus·œ«tÞ!ž\ߌîßYEFyx–Iþú—]wˆ“ê‘þ®ãN[GºE‘°3zf JIJŒrù éE�«]§²ódç�’»�ÚÑÒSq�U5�NY�í)Ų8‰]_A’kb&§ 5‰.Îë.ïsÏCÕ3K,’…ó ɨ¾ÁÏl zèÅ&ƒe}çõùÞ`!œ.ÑI%Š|jiùÓñv”à‘Pò'¨~-‰±&)É q“O¼È8ê�&ŸüI¤žFg@g@g@g@g@g@g@g ¨ ¨oPsê™ttÉ€›tz3} Úi@Ó_#;Ä9i!òè¢(yzEœ,™.Y) ƒ"ÃEa*?ƒÃªsžk(Ëyog“ü|c½ì9Ù3qtV{†‡·„ÆHÊ„G$Î×%}Úç$6}Žò•1™iÃXYâšæþü; &Ó«g™Õhd[�zȧÑÜšµsMòÝg­jô³‹7<¹>uÕ)7ë=ïG³Mîu}ëI‹LÎ5¡mNEü¸?w—fºß�Ô+Ë—”™ s¸c+|‹øŽÓcõ .B¬(�Jåá1vANƒ*#,îø ÔWÙI†^žJîïFê•þH<ÞY¢ÆR»¼´Þ#ÕYñ}q†A™�—ßrHW"5.—ùfé Ë+ç—•oTFBÿ¹çHu4 O‡ɪ#ò=(ÁÜ$ÏÎ •`B¿x’k?öÍ ójÃþ ±zŽ»¾Óô+6Áï)2±L¬¡±ÒÑR ®þT�’�b–@Žd ȧ¬4‹¤&ZåÒ5å¤ÏÒ»©@I'æ…A’éøn£ËÇçz­úxTÿPÑóïØT‰ß髹ÒC6QA3–Ä“P Ò)>Òeèr8ÊÂI.UWôbb©öšR?±ä¯o�4I�!øä\’Oܯ¤] æ�ËÞÕË÷H@MƒX$|Õ|ÏWFÊôž^l–}g²ïœTNéÀˆxm®ï}ýU$J‡'œ(¥5ФqtÊT¹}u7üÂr®¢C•÷Åb?òx,¸ýXŒ"º‹²¬²e¯× ·2 úi×`ËÐßë è è è è è è è è “M>“5=�Î€ï °÷Ì‘£H:­2%K`'6-Á&ÎŒ�…S#T©ÌPI§În‡ì=Ù!÷4ÈñsmR]ƒè.W§Ý•DlÖ¹È,I1ùÛ_u©el9BT·*Û”c�ð¸*šhÈž?ð(s$«H–³‹�Š\# Eÿ«»¦p!‘é�r–"ŸšZrær®eÔîO6¸hÄn”‚L›ì;ÙÌÕ0Ñô¤›hò IС3 3 3 3 3 3 3 30¼¸ûÎ~x—¯—¦30^3@7—UÀ·�çO,]1pÔ¹Òü0ùìª8yâÁ(™�mSj'vFÙñ $LX‡Y/¿Ñ)¯Ü ÿõa=†Ho‘ëÕ�=%v05ŽN—Œi¿#ù þH’ H<åÀLÜm6à iÜMû8”!þY«œ,§y´§,…âhf£$ ¼Õ)7Q*ÖŽ2¬ÿ÷A—´à4’í£yöÈÏg—˜eëQÑT‹<½ÃóÊQÊOl„È‹ËÍR ƒð£(«sÇÉr'FtH}U�û{÷«…O²QrSúÔÝa’?¡I®¡Å)o8>§B FúÖS5Òà6´…£Öqô<š�_¿í*÷£Âi UÛI§oY »ý|¥êît…CÎ^ó}L’˜¢¡¹» ’󔣒>ezrÆÏÝÁk�+îìh�ÛW>–®®ELOÌ •Ôs@„'ÛßÐâÀõ¤ Û¯ÚÈ?ÀÀw£Ý ѯ:::::::::f Àç².]O®30þ2ÀÞðtàY`5À2 ÆÖ äR*|�š‰Qì"PšƒÑ©lÕ‹ TéD‹�ÌÊê.ù£×í<Ø"ÕªÌÆM`ÙÂ$¹hµ¤”l�¨ä©b ‹Ç #lq›îÅà¨g$f›Ð¹÷”��f[ÿð WÛw~ÒÙ‹\¡âi,ƒÇÆ”�%@49×Þ«´m4ÛñGç˜óÚŽnx#¶všŸ“XZ ɦ¾ÁåsÿÓ·i0Â1!J¤d Ûs‹ç?|§K�˜wd“;8Þ¹J* HBeQ©I 1UvÁNdAâò{/Z•ìwÿÙ“’ODá*½ ‘¨¤2”ßI}å!”švÉÉKíRVà&œû›»÷ç�/3Ù"©(¿»xMÙú>q”N=ê]ïtéwã#ü­¦:™û,ŠÅÕ@n5ÀØü˜`Å:ttttt~[2 É§ß–=­·s¨`/2Ø<1€Š˜³,ÄvÍŽ’ —¯•�’N$°èëTSo—�Gšdëþ&¹\Ù!u( r/Ë-‰+$eâz”ßÌ[D"H'‹‹trúVL¸Ûy¿½Æ «�Ÿf”ƒç=Ûõæîn9tÁ޲«þ;é#½�m­­Ã(É(ÝË �7Õ7n}Œþå=x€�ÏðöTî6òØ& bq*•G‹£òËMŒr$¿ƒÙ;÷[ ÄÛJ½³XV— /­¾A…ËI@½»—£;ö�Âõ~ °—Wšå— À~ñ±g"oU˜÷œ<Çna;¶À´ž¤ý�¦c4<*”†3Ôhyèê27T‰Õ©Ê7?× Jï2%.s¾Ô_?$M-v9~±MV5E*O*‡Ÿ§�›ŽfÙÜä;ã¹@ °ÝÏÖèÉtîõ �>Îæüço7Îañ6É'ïoç::::::#”Ï”GhMz±:÷g hv&ð<ð-àQ  A¯Xáë4¾N/</Ï�ÄRP;…ðž6°;’Nf˜749äã#­ò³÷êA<5*⩥͡:õf[”N+%oÞ7Pf÷’ĤbÔ«Púšs}~ö8Ù°û$â¡Ãøñ×m‘È8:•) ¾V7¸þ�¿S󌊀8Ý“cªrÞÙk‡òÊóÙh´Å{óKŒò7/Y…* }g=ä‰ –��T°l�åt40ŸYd’Gg›ÁÃ’>oÕMÄ©2 &HbñÄK�7ø,½ã2-8_HB�‡ZÉM¾õ]KÛVÀ?©¢Ú)¼̾Óõ}O2‹$·§¾Ù õ•A"qÆ[-l•Ab‰ie�CyLÕBQå.±ãöí sBõâîû °[É'£k€‡�b€7¦¼)U�Îô$›¬˜)‹èë”h–”q¦€I'¨)Z;²çD»lÚÓß–6©­ï©ázèj0˜$6s¶¤•>- ùË1ÊU†˜,Jpâiø:ùÜ®±–5mXlš†{«xþÇϺ„$ÀXK¯>Äm$!‚)®vÇ÷è‘YfùÙ¶î;ù 9öþ¡S•» ×z[NI–AÖÍ3«ýÜ^L¡à;Xwj°áŒvð4T˜]¼á€Õ}wËýXwè‚Q¾û¬Eâ" j¼C<ÍPUr$i~½Ö¡TL«±Š3Œ~P¿��ï�=¤ØÝ[È'N¬^TáÉ›µHj.oƒi:ÊPáûT*D’ÝOù÷a ˆó¢¬�OÊ%Ÿãü¼îéx »EO{/d€?Å�>8¢ò)Ôl6Kff¦LŸ>]ÊÊÊ$99Y¬V«€x’O>ùD¶oß.µµµ¸ÊªADêñJâõ, Cg@g@g@g@g@g`3 É§aL¦^Ô}�önyÓʧŸÅŽeù.Ò‰o`Ì»hj„<o§‚ôÞ¾N�t»ééÔ�Ñ¥Ž^è�w7Ê�S-R]×�òW‡ÙÒ):}º¤LxÞNIhL¾"�øÔv¼‘NH«Š™P•¬œa–œd’O¨Wê‰Ñ$žHb|î!³üzgw/Ï?½=\¤�{«ý ŒîWeI°M‡”BE-„>K£Qa"õ‚Uy’õUþ„Z�hŸAvœ�;äØPÛE!I­ýç2d�U�‰½—Jò$3‘ÞOFyý“nEò”ßòO½§þÛÂú>9 %žÝ.뀡Áþð'X¾÷ÝŸzOþÌ3Ø44gntÚL ‰Ê�–º+r½¦SÎ]í‚GȧÁ€ï¹Mà°$2Â$sl²ã°Qìv;ïÉË“4ù„$è¸o2@âg¦| x úÉH¢iÑ¢EòÀH^^žDFF¢ÄÝuë Å“¤¥¥)ÔÆ�¥¡¡�#Öòà*ðÿ€Z@‡Î€Î€Î€Î€Î€ÎÀ0e·î:t~«3À»PŽ^÷»À$žøÔŸ†¤&v²“ã¬òм(yveœ,�.Y)ø:±�æêÀ©üøcRCØäÂÕNùÕ–ùåæ:9v® æâ4L¦šJ§ŒY’3ç÷%wöïK|ÔNÑéèìÓ˜1zDƒk}#÷—FâT¶¸ƒÕ¡ØÌÿ¨*÷§£û: >FTµ„AÉÓŸ!õhµ¨/¹ÓÒæ"²í¨=h¥¡¶�  ´8£„õŒ6è½<#Žm–E€âˆe’ÃÝà‘(â!±�ü|½ŸHB}pÀ¡ˆ9÷¨v¾¦êgô‚ªit™¬Ó} ’G*åè vª©áª-±Ñp~o©=#M·N)2)6Ê,S‹BüVe±]¤Ð:@†>Û&-PPõ|DåÇÀÃó:÷f8Rã:àëÀ &44Ô0sæLyöÙgñDÂöÔ©SràÀ9}ú´455)"ŠäTbb¢ÔÕÕIEEX;GÄ#qu8ŒÄ ŒÅ)ð(@)²©ÊÆ�ª�|J2~n°1:ttttÆ_´òiüíS½Eþe€ŒÎ<€O9ù”4POJñª:oi‰6™7%\–…KF°‹7*Sp*)±#‘@⩲¦[¶îk–�6Ieu§4ÀçIä1É¥’RºA’òWJHlT áè\Ñ¡Äb÷佯«éÁüýã§,EÌ(_üA‡Üêq•éÂmó¿~0z #ŽÖƲW<÷ê[AìðÝÇÇzöK07Äyh²þâCååô½ÿò°8;O:„­(J7(Øn(}ÞÞãÉÇkP…}>Ür×èoô‚J„§Qü�Ž{åt¨íåyvå…,ÅÌM6*ƒñ¾ËäºÓ Ê“éÊMG¿#ßõ�/Ø÷- Ùö¢<4)&äa ÅPê×_ôÿMsøû9ŽT\X¬aq(Í] Ugß•Öö9W+Œ”™@éÈ»´x‹Àûéf­âšØ±-HÂô·Ez:��1Ê@,Ö» â© °%%%ÉÒ¥KeåÊ•JvìØ!»ví’ªª*¡ÚɈ€ˆˆ)))QÓ”––ªW~ôèQ\QÔñÿ^/÷Ò9�‡ö,xï’�(ënŸo€ç¢�7:tttttî• hòé^Ùº£•š&-iUNªŸH¢(;5TN •9¥á’›f‘¨0# ¾Yòé„eöŒ`g—]GÛdÓ¾F¨žÚÕèR\;�‘q’2i½$>"qÄ1nI'æƒÑ…Ûbn?}sn5Œ¡âZ;‰@‘~Å*é0ÿÒ?u¡;ÃU.¶ùðØÞ³Sé3ÄÛ"*XSj÷¶û óɹ&û†^äG¬Ãèo}ƒçMSXþv£Ï §{6ŠÀNÀx~î;PPûøˆ¨±è µë¤A�lçc’aý¨,× Ï<`’fvûÆ(HL›¬áÓñ°˜\iª>-7«;äâµ.�qþ—Þ‘ˆ�‰2IYn¨ì9ÞÂÒ;|¢®‹ìàÞKï1ÊôoÝj¹ÿ39uÞa@IDAT™ËÙxa䨕5@ejñ:ÖÊ8þv“$ú 0¥é–œœY»v­<øàƒÒÖÖ&o¿ý¶lÙ²Ejjj¨jÂd®àû›7oJee¥š~ÆŒаºuë–ܸqúWõPê<^©€"¹3–Áí¤²ëi ˆx/à "7ŠO*s�Žc½oÐ:::::½3 É§ÞùÐïÆoø4@Òé  ¿ƒ #zÏEÙ¡²`Z˜ÌšˆÒº$³„ƒtb9OP¤|�Z:òÉÑV�NÍrúR«òubyy®°è4I†§SÊÄÇ$"±T,!1à¢ÆŸÒiFD ·ä —ô|Ô%ÿ¾‰$FOòGù…>RE�GÑxn|�]¨1мƒÜ ™y‰Ñ_¡ÿõz—\�3šÄÓD¨ÀN_õ�J{¡4úçwºîR�±�$ëxN�pòîg@EéÆžüzÜÿø„E–M5Éÿ}·Köžub¤=˜°ùøÕâyÊ‘ ¹þk5P°y6%¸2×±ËU6ÚÁî¯,c&”æfILúLE>5´ØåLy»Ì+c¿Ô¿`®XòZœk“DøEUA•‰ š„�ÙŸõ€ŽñŸºªMH<<�HF1Hr@÷§H¨›x= | ìª�ÑŽH¬ð1àw�¨™ÌEEEòä“OÊÂ… Ùôúë¯Ë¶mÛTI¦iö‡�X�·‹Z[[ Ož£š„Ïà5€Û>ÁýðE€*íl¶üü|!Ð~– š@ ™ èJÇ÷kª¡þ8 xØ6¼Ñ¡3 3 3 3 30Öðýy¬[¥×¯30|à�ØràëÀ—€ùoÒø4Y£L.“õËb€h™[¦Tôtbç:ÐN,ÍÄY*tüb§üìƒzy{G½œ½Ò.õMvå]c¶EJjÉZ)Xø'’Zú”DÄ‹êWŒp�¹g-£õB"ào_¶©ò¶wöyzá´«þíÈ·ÄjÆ(q³M’™`”KUžü’|z ådC m([ðÜR³|ë)+FÑsÊÉrOÛ*ª� .‡²äÀæý›ÏYåùe9xÞ.µ�žy/\wÞUÂÆV†Ùœ2-¤‡µ7ûÄóņî+=«9:K)‡$EJáÅÅÑë.`ä;–R•å+Ì(m%·Ë²¿á<¾r“ òùU!áD僯ûÏ;p\`xîî›»¾sÿYÏ'×Z8ÑÝz[j®l;L©ÂBL2«$LBAzŽ*w«î~å~£g·¢üF·\¾®>œ9ªÞ÷?¾{.ýÉ8Ë}ƒHnüQÏëD¼Bs¨Ð@Ó(ÖPq“d¥IªB€WRÃpÖc)ƒ•I¿L¥âi„ òÌ3ÏÈœ9säòåËò›ßüF•ÛqD;DðŸÀ€�O€S@”ÃáÈlll´�È)..V¦äP>QýÄ ·9¸T£eXá·–fr;gÍš%/¼ð‚,_¾\ø?GðKOO§Yº`;¬Øž LË{ûã 7:::::÷L4ùtÏì Ý�aÎŸŠ®¾|˜ �tâM+:ÎF™6!B6¬ˆ•Ç—DËŒ ¡’Ÿ”tØX€0é„ÎÙªK×:å5š‰oª“ãZ{™‰Çç.’Âùß�Œé_@©Ìd±Øx?Ïû[ºˆlõý·0RG�£oM—Gsä:w¦¸þo®·*5Î;{] ¿£qô½ K�rªÜÑ‹|‰v‘`ˆ 5¨ÚJ²ŒŠ0¡‘wøÓ8› ¹RÙS‚Ø_x^п,7Ũæé;�ä«Í3,Ç]ÎØwšþÞ³ÜpÉ“j‡{šrqÜog+]DXT¸AŠA@‘,é&üšÑ†»¢ÛQ3|çÕWóKLŠpr)æ\kù69Ï•dÿäÓ©3÷l½Áh‡½Cn—ï”ö–Z±áÚ6¥ £sšý¾Ž1�F”Ó‡îðÙvœ«N&˜¨>†/¡X˜Ž{*|úA…ϳ.$ Þ;’”IH>•|¤pi…O8ªò¾ ða’µ  @6lØ 999ªÄŽÄ¼›¤¹YÉk+0ÍO€§�&€¤ ÛÊïR@Øäƒ¤2Z­VEæ„……)Èng"@rímê¨E6Öôß�G�xxW—,YâüÌg>c(++“èèh WféÜþÌÌLfrûömPY˜çp¥G=X“������A2ÀV:ã)$�Vß^x3�(Ò)ÔU@i„<ýPœ<¶$R¦†Hb¬I¬=*Ž@I'Õißʚ.ywW“R;í?Õ,Uµ]P~ ¿†Rº¨ä ’;÷k’?û«�¹Hlá¼_çýóøéÏMÍ'Éc‘ ×½Êé6²+2a´ˆ'—ò©í  IèJýz—åXc—oªÀÖÍ3õ*?¼Yï”÷¡;|qdÛEõW^ªåkFyb�I”šGÑM”üÑÌûÍÝv¿½’P6…ƒÈâè€ô¦ò’\$ŸH[PÍåV yOãëÿXè.¾ÿy«”åÀ·é„ãΈ~<Ýǽ¸|®7ë÷f�_T=‘$rÏçkº�>£ÚÊ›œ¬BލD{{Ow/EÛ0äSv?äS+æ9bñܵ¡íßxpÔÐirywè6�Od™šo�T¥wý/'#Dг¬Jmy÷<>>A:Iè‘�¯Øùäõ¦³ù†Ô–ï@Žœ Ç„ažý .¼¦7ȵ›Ýr# ¨~áJ�,;Ò1¾2ÀßF8T<ÍÔo%^ÅŠ‡4Å3“dÑã¹R:?Y²'ÆJ^i¼L�—â‰R09^âSÃ¥£¥[Z;Åépò^2Ȩ*"I3Š›X,÷³I™x„<üðÃJõ³iÓ&ùä“OH¼ð¸†ïü#ð>pðu"’e½ $“Pzg©#“&MRdÉ'�ó,Šø«Bõ·o$# ç=Ìç€Jµ¯Ä“D› !/^ìþøã�GŽ�Õ•Ñ©(æßÉõë× Í’1ÿ%à,0Òj4¬B‡Î€Î€Î€Î€ÎÀàÐäÓà9ÒSÜÛ€NA–| Ò‰¤?—ȓ̟%Ï<#k@:•åÙ$#;±<ˆÙ`I§Æ‡l;Ü*?}¿N¶h’Ë•ÒÒæPw·–_§ü…߆¯ÓÓ_(& œ2|Ýÿº¾¹Ÿþr¤8–l¹ƒCÜ×69åw­8q/+Ø×™…&™ÔƒP9 c,ƒ¦Øôþb�¬iÇ3öÓWBrÅ[Uãšbdþ†¡+9†ïO,°ÈŒ“òcò^E T>ºX®xÎp›â V∅ŠûðZ0ß“|âÈ}$_úz?Í,4Ê_>o�Ò9IäŽPJ�Qã&¤ÜŸ{¿r½! Œ9sÜ7¸n¢¦Ñ0éÃýòÂr‹ò”ÚuÒ!Í^Çwßõð=Õ_S hŒ|â6-íNytŽY®¢ü�嫾›+FtH»»Û¥öÊÇÒÑÖ¨Jï¦O“h\ÿü¾ÆaA$Ô[±ÎgÛ°<ÕnÞ#°s¾ðÝ|¡ã¾Ë›¹=“T÷¨ˆŒ ‘K3dấv²áÁ�¥œÖPø¼…›¡ˆ²J\r¨¤A •’­P Õ8^ºÔ(‰qX‰œJà20œÇ Y^þÖów~BHHˆá�P¾G{÷î•íÛ·Ó€›¬ñAàÿ�,b™Ý@�_ ÕÎ"–«Ñ|œ*¢É“'+"‹dTT ñ9G–dNð'5f ¨Òþàe ¤’sÍš5]O=õ”eu´Ï°{÷nyõÕW� ŸŒÇŽ3r´¾ÂÂB‰‰‰– ²ý§OŸfÉ!ï�x•ÜT:tttttÆ<š|ó] dxì’húC€7м‘æ�›"�bÐéZ05J>‹òºGFHinˆÄFrôºÒ J©�ŽYC³CviEy]ƒlÚÝ *Ú¥#L±Ãl2[%1w©,ø¦¤O{ åvSÆ�¯S8´|Ù %�YÞEɘ›H¡*„j’£1(((E‰Ö�Ûž>À¥*JÈì²ùð(5Âdžgä»ÏZ…äœ÷$ X†æÎ—�Y‡õ£åÓŒòhGašQ¨P¢É;HH�,ü䔽—»÷4ýOb‰äË ilÝ7LF§"2®ÞrŠ·Ò‹ÓÑ_jí\3È#ö•GaÔw¾Þ»Ž/ƒä§$)æîõr�³DïØe§t€ôë/f€ci¬»œ�dá)„¯nîîU:ÚßüôÐb¹iäS ´$ßÎøݟ yùó0¡'qê>�ض÷÷Û1êà@Ç4ò€ò^ö‡›oCéÝy䥖(½ËKµ Hæy·‹¤�ÛKëÌåŒÎ©’ÇN77à Ö{zýÿ}�’DŸžXª~'ò&ÅÉÂÇr%³8ZwÈK=‡2� ÔQ1‰6IÎŒ;œþk«Ú¤«ÃÎ+ É'\¡U™Z%^‡+ò± —�PûYKKKeõêÕTùȇ~H¯#®çðàM€j'*› n]É©šÜÞÞJ%É':4/¯ªªâ2¢’8Ç€Á-Lpd`Žnc<ž (µsf”ZA€¸�¯½öš`„>J $šª««%**J¥caÛÏ�;§Úl·ÛYã i†_é1 >y+Vk�5w|?˜P¹NEÙXµ«Ö¡3 3 3 300�ÆJô:t†1ìe$œH<-2U2ÒiH§Ï¬Š“‡çGÈÄ›DƒtbG™7Ñ=÷Θܿ ¹2Q]ï��µÈÏ?¬—�ö4ÊY”¥p;v “ÄfÍ‘Ü9 9s~ÞÏ[îùz:„þ­éþ˜Šeb‹'¡¼ê“Ã(EªkývÇ£«ôã¯ÛdL ?@ÇÜ]ºÆ×±½Ž™`)G±‹FYɹ;·QLI„yámV„ãeqÅô ¶é6ˆ§­G»… ’$�†Rua9™‰¾G{S>$ —è¦�®‡÷Hƒ$ ÏW:ä?·`‡lT˜AJPNˆSó®à¹Îõ—C�wÝ‹œôž�ûèkë,bƒ.`ÿ9±ÃÑþH\ùlÃÌ"—y»¯é™Wš¸_Ä(}þIËy8¦ZœrÖË'Ê}|´ ®54[ooª”ºŠ],ƒ’˜(‹L-¹K™6ÐrXzÇ;kìrâ‚:0x½e–¯ìØë˜ŠÍx(îœE¶³Lœ�"¥s’$$lpÃz#Ž•ð‹*Áë„è¨æz PTÛðAϤ3‰�¡ ŒÇ€çØ;%ɪU«”ÒgãÆ�Š B©]¾{x t� yÕ=DÔEôN¢‰7E555ª” ä·‹'ó)à0œ‘�…}x Èée\¶l™áé§Ÿ6¦¦¦I2½ýöÛòÆo¨mEI×Í6´âÿPøS™ŠŠŠ”ù8ɧºº:E@A Æû"nÛ^ í(à ¿ ð~�¤ÓB`&0 à1Èÿç$¢¦d¼Éôi IС3 3 303Ч[27QoÓ8Éo�Ó��o«�<€7¥†’€S"åÙUð€€ÒiBvoÒ‰Ó쀱×v½ºK6îi–_|ˆòºýMÊ E‘NÓ¾˜Ô2N¿/y³¾*ñP=ÙÂSP3>|�Lèv>4¥Ð’y“:‡/ØåW;í 0ÉèðMË!ìIAaÄÓŒ‰)ŽÃE�daY_^2H6¡ÔNÖ­[G/+'<¬ªþóŸÛßÿ} Jì P3±�›€¿˜ÛR”ØÅ��#Åðí¯¶¶–mŽöl÷P÷áWàê¦TM‚×u@!@µÇòøà+ßGT˳*Ðnu®ö:ttttÆSø¡Cgà^Ïo�×ßž(ᎠÔ—Ì,‰�gWÇÊZx:• éT^Õ)ïcôºŸT#ñ&¹O'–שr�NÑ)“$gÖ•Ú)!o¥„ÄÀLܤÄWh–W�ïî×x&â_YcA ™Q>ò*�"ù3ZŠ’(/­Äx$±#×¹c'FDÛ~|ìˆ'¶ƒ¾E[@>õ&H¬x“ î6�Ä+‰ÁW [1Í$[ŽØ…û&3‘ãfõÚw�$5ört»OíÂÑö†ŠÔAdz0ÍClöqzI æ¡^hÎ;‡ÍôÝ�Ût”©õ7Ò=ÝHRuTš�cè!³ìÀ1ã>nFøóVõnýàï¨*#�Õ_ù_Ö±ïl7ŽÛÞËâè‹ß|Ò‚ÑMPŸyúV$€¬ ”xr- &†¿’¦›Ç¥©æ<¸q§d§†HA†ÿ£ÞqŸ±¤Ê„÷µ[]ÊËË'YÁ`G÷‚úOÿ¹Ÿ3ÀßSªP–ª §$ʲgò¥lA²D%†(µo H*^P$±n£ü®P¸h³L W$uÜÜ dy}¦%y²¡‘yyy²téR�Ë–-[åg$T¶ÿ<'Þ”úñ×4�O‘ÑÑÑ2qâD¥&ºvíš"  Šâ�|Àõ� j¤`/$Ö2ÓÓÓ�ÕŽå„(µsÞ¼y³æ•W^iÃ~‘P`Ñó‰íw€¿vW€Ùøœez¦©S§ª²;P—.]’ŠŠ s$xHÈ‘0-­òXן<Æx¼áÊ2h�äN&SîÇ €ûE‡Î€Î€Î€ÎÀ8É€û¦rœlŽÞŒq–�0lÏrà`.�(†‡Ë¢Ü0Y9;RfO ÅX(¡±¸hU„  –ÖñNçre§ìDyݧ'Z¥òVGOi�«“n4¢œ*mª$¯“„¼%,¶P̶(¤ŒèÔRýì=o -¹iÙñtwιN,m{o¿’ø�ÜŠX2ËšVÎ0ÃW‡~NìǸÂí‰ã~?¯$3Rà_Ôw´Ñl ×͑آ1º"THT=‘l)‚xß`Î*ªò”5}}˜úNëÏ{+·`XNÂ$ÞRTÊõ zµ´£mð…ê{|õ�Öß÷àE”²i ?'®‹¤Ð”<ƒ<0Ù$Y äOêí�ä&±ü]oß鸪—ú ^‡:|œ:- 9!óÅöXê7ôpªëË}c3çIõÅM¸v9äèù6”!‡*-ÖÁ}ÊíŠCîfM “ÝÇ›©~Â'ªSNµÌ6€e<:îß �Ìáo)•'b 5Kza´¤Dƒ<2+ÿ&~Hð¸1¡;gRŒL[’*õ5m(ÁkÆ/²R²ÌÆëYÀsdáP"arÞ$ÐP{úôéªÜnëÖ­nŸ§óøî5`/@…^°Áãú$pdNGº#�3þ|™0a‚ÐÔüÆ�<ã'õà^‡ò£‰ù×ω‰‰’N+V¬`]¡ª¥¶ýèGNŒà‚-÷<yþý=°`{‰ÓÀ¼óçÏDZ½ÉÉÉ!3fÌ�ýû÷KKK Ûü ð+à0”6cöAƒÇÖKÀ€Ä—R�¥åEIfaŒ„â#áI­½µKª¯µÈõ‹MÒÊ #.c˜<X s€Ÿ$û‚=~0«�����{%š|ºWö„n‡wx\.ž–¼™Q71ì¥'Ùd9H§ÅÓ"$3É,¡(½áK0�I’Xìm]½Ù)Û€t:Ú %K‡44uß­ÌlF _æ\I)~Tâ³–HhL¶˜0¢ÝÒÉ9Ò÷rhãÇãóM²&Ðßø×Ž;>N$6¾ýï£{¿G#qŽVçŽÚ% Ï;{G«ZÀ½fÏ+GU[9äJÙXN玭PÁwîeò�Ü<1ß,Yp›—õ?¼Ù¥ŒÌynä$dN± DÔÝKnnÃÈv ªè·4\ÑŒ2±ãW²tªSå§ïrÙ¦¨¢”•ùv-F¡ 6H:Å Ô­0Ý ÓòMŠÀhY0/Î0ɯvØAôØ…j¹á ÖÖ~Ay\tu³,Ñ öÕV zA} Êrô1ÒõmðI€›m ȧKhT†´5”˹òv©¨ê–¢l+Žÿsok8!Ï*EY¡rä¬KPÅ2(ßJ=ç=�îK‚¿~P,Ù$!5L¬!Æ ˆ'.ƒÁŸAŽŒW4#Q®]h”P]�ö |ÅRª�€«@ ‡¦Æüü|¡ÑøÕ«WåìÙ³|艕| lzÎ0ü\ð9�Tšƒ7ÛÁƒÕúèý”““Cò‰KÎØnS5L�Z <äƒ,2rä>O ¡Š'Ç[o½eعsgtϨu\ÇfàûÀ~€¤ƒ?Œ$fàó·k×.)..”îÝyŲ°_í%˜†$àN ŒTp»¨ª[„»WR8-Q–<™'i¹‘bI©îØ�m;j¨Ûš»¤â|½ÛySΩV„æãCÆ\àY  xx`)ž�����û8ü¡Ð¡3p¯dÝK™|øÀ'g$žTW:Ʀ«DËó0_45LRÌb…Úƒ5Yþw«°´žà°â·òÁ§Mòê{õê)EU‡´µ»Ês̶p(œ–JîܯJÎÌ/Klö ‰NǨvê�1–ÌZÝk¿·^IjL„G}g8jÝXÄ?e‘¯®µ(B‡AT�pÔ¸Á†½wM=2cQàù—ÏYe"F�ã¨cî¶0K£™)ú }ña‹ä¦ô&ãÜä §Éy&yJ±¾¤• ÕNyk¼—†XnÇ,G…¡÷Óå"|iЉSbÔVœŽ}ƒ†çôž¢Ï’·ñxßéú{OEcF,Ë1A½d”¥Sàeò)eoÉ*îŸ}çì½JîšÇßï¸�, ¥ªŠ$—¯àöÆGä‹«-èü¡æå2æž òÌ#q÷ôþ½²KgB¹�QZjÏKãÍ�88%)ΊÑ>m½T�ƒ-�¤¼Õb”f˜H…÷T ¼6“jcg›þ1£yècu:†1ÙXÖ2 �ËŒñT:'E’²p¡â^å™n†é¸Sn^i–¦úÞc’½$Ar4fb4¥0Ò6À„›ª Ù¾}»P™„àHn?HÈxN0¼ 2Hf±¤›$}SIDò‰ÄÓ… XƆ+’ð ×]$T¾ ,³Z­¶¹sçrT;K ¡xrÂ\Üùî»ïša$Îuuoÿà¹Ç6zŸ-—�é�¹¹¹‚ò=U~Ǽ‡ÂUHvµÀHE>ü߀ɀ¢æÓócdù3R0%Þ`åÔfŒbÙi 3IÊ51bbVqŒÄ%‡I[k·´4tÒ7Œm„–WR’}±À ⑊%èÐÐÐГ ðÆ@‡ÎÀXg€÷¬¹oƾ ,xƒl$2Ü$LéôHœ,Ÿ!Y)¥vâwìT4g Òîmò“wëdó¾&)¿Ñ!­$�°03TMIIþ¼¯Kæô—%&c¡Ø"R@:áþM­/ˆ•ÚÈœ>·séèÌ{+Œ®Üt*/ m^4#ØŸ‹ž3�åQ(sœrDÉX}”H.¸Ë7Û@„‘(à�÷£IÌ‘Ðñ&(H‘ôy£Äù2{'ѱñÅ>Jî¨b;r Š)�û2à$×ëšäÏ?cU†ïlÉ';°‰Y&�P<•H¥Ð©«þy±œ-¥„@øÍ†’‹¤ÓÂIf™Ò)¤ÍÌý îG*ŽN@�å&éü™o°iؾìd�OùÑ—©;¯K$ù6îV†ì,MŠ¿Ô`íqÏrʃí]ÍÊx#t IöiÅ¡†ÒG¿Ï*äÍŒë¤ ¨Ó—;ävû¿ê!wð.@+˜‘û32Ðì%€"ŸÒ0*ì¬D‰K ê÷´o x̘PŠ^uµYn E@SË€dM AåÌZàq ’ã .T£½íرƒ„  7€×Ã$°>ôš„’5‹ ì9�¼A JÛ8’Ï’"—’jêäÀ«¿‘€ Ÿž�™yLYY™¬_¿Þ0yòd–ÈÙ1zŸã�wÞ1ÁÓŠ„/‰¦ŸÿÜŠ'ü{'Ø^îÓIíííáô#§ú)!!�9’ãÇ�KCƒJO¦9\¸O†;xUþ ÀýÏ…GÆ„Èâõ¹R27 ʺž�xòÞòž,¦õÉÙQ’U#!¡i¬í�Q¸–r¹±@1�T·’i:ttttî³ ð¢®Cg`,3À› z:}Xð†]lª%Œ2gr”Nñò(F°+Ì´AeàRWC:ñi¾.VtÊ/65Èo¶ÔËY”¥ÐHœË3[B%±`…ÌÿºdLIbÒç€tJV£×±=ãáa[T3ÿü{6™^h„—“çÞ�t÷hi®mÙ¿2]fÑÞë /’cÃ=*¢ÛRˆv·'ÛÝ7\þZTš902d·œ¾ê{›ûÎ7ïéM“i¸q@Zê®A …ŒÇsÒ,~pœ‡ÇICŽîyòRIÞ/PÍp `'VÇý™�d4{1Àμ$¦‡KÑôD‰I"ù4ôã”ç?goV4˵ó ,­"¡sà1ãùÑÁ›A"ßoæ²,mñâÅJÍC“q€#ޝ\öÐŽ…ôI-.¯ÞO™$sXîWPP Êý¨$Bžx�Òœ¨ô7x-^ ¡t2€xŽÞ‡e¶ÂX¼í�7Þ0_¿~ÝŒ÷$š~ü€ëé�0bNI@ÍÁ<é·oß6 ìΑ��m$U^^.(!¤b‹’mý*•X=^‡;x\}˜ð:!3–fÈì•™§ž#ò£à %{T¬MÒàA–œ!¬¢ñv»*ÏÃŒ$#s€\à2Prý¯¾m—Íšeë¾f¹Zå"�¸ F‰ŠÉœ%™eÏJ\îR ‰Diˆ(†sø9© éùsþ7´:¥ºÁ©J¥Ü>4ÞÓŒôÿ“s�òן³ÊÍ:‡|þ�׳k‚¨å­üGž3G‚¼)†âF@„�U°çCRcRŽQ.ß¼6\É30ú[ÔB}ƒçÍíF»\¸Þ“è¾ ðž¦Ý“цÍð¶r ËOCÁDµœ;Zœ²ÿ¼]fÀ ž]¾‚~Ms¡n#äM:ª²:Ì“—j”�W9Pq[¢1½/bÇײûûÌ­ b©"�ùá ª‚Hòõg8Nò‰çY['”a�ê"†ÔHl£ž_QY’�³Dê+J TKûO·Ê¬I!>߯pgŠJ¶™0ÿø ˆ„›JtÁæJàmà¦_ ÓÝk �+�+”R j%ßâþ4øWõ ¥Uaá±X� ”‚™¥lü}÷¥Üéoe¼'ÈL4ÐnllTåvT�d©Ãç{ÏÅ o†!xÆî6…ðLJ8|ø°RM™2EŽ=*UUU¼wžðÞåàïvå`ÚG�2C†¥K—*â ê*;J í ž, ÖÌ=£ÚqÛ~ œ»ŠœÂ4Û€"xD%n۶͉‘ïºsssÍ?ü°*½ƒG–Dï¹ÞxîÞ9ðÿpI§B€ª0É(ˆ‘É‹R%&!ÄofPÝnáç#*¨‰³“$1#\o�’[*¤¾º•÷€<Ž–<†ÿ;@R.ð6̤Cg@g@g@g`l2`›Õêµþg€ÇoÚ¾ ü0HL|bšŸ*O¯ˆ• +bБ ‘Øh“ð¾8Ø’v;qk²çJìÞ«“­ûA‚ç¢wɦû3–*CðAÔOõ ª˜súR‘lZuÓ²©.•‰Iú;qti¾¢ž7,ѤR�ëí0™-èðÙ¥®| }!rÀŵ4ÇEäû{-åõ˜Ê1*P«PrzYõUÙéæ5œnvŠuÜ ÿÏ,`*`LÉŽ„ò)A"¡NŽc•Ç —Sy¡A®œªùÔ݉õ�HÙ ð£®2X>JÏ%*žàÃD"†ÄÓ¿<Gâ #™Ä¶€°)@ùš!++K) Øžƒ#‚+�:¨Â,HÊPÝý�+îO×÷ëý" á›0Üž”�2Á9f5Kب8ƒ½Š_ÁÓ´#í�D9�múre£ÐWðZÐŽ|ÒóŠÞWC�Òl è-*7Tgù æŠ>SǽLÆ}M7”Ïâ£ÐËCwöîýÂkŸI• ·Þ¾( 0çu-1Æãy XIB*Ž] /ž™PµJ*r0 Jô¼Af  óÍBâRÂ$¿,A¢‡¯ìޤ0Kî.Ÿ¸í&Ÿö`]$Ÿ¹Š` Oðj�ƒ�±Âψ¥cü–åvÿìÔxîàMÕU$˜èým³Ù„¾LáááÊw Û×38=ô<þó“ññKÀœœœÓš5kê$zHÉ|`ÀHuFl#/(gO¯^¿šx7p°½9@iwwwxSSS#ÚÛ…ÑólqqqFš¥ÓG ¹LÅ4¡‰›á*¿cžžHhZ'ÎJ–9«²@h’çZÐ+*)=¥{!r«¢K€•ÿ\6–|¸ èëÐÐÒ¬çÖÐе øy«?jíÑ+àÍT:À›®o«�\€O%*Â$Έ–`&¾lf„d$šÅÕCñ@ê?ÿÿ�sbg³²¶[ÞÝÑ(?ÛX'Ï´Hu]·ê³Ä.>{�.ø#IŸñ²D'O³÷M¼Õ¼ÏI'v½Éœò[‰… õk;º¥�.c�̆Y4¼{¬ öÀ¿è^ [T×´�˜ÙÖ�©±i×Kæ8ˆ *s¼ ÆiQöóä™&Ý}ƒ$Ö!Œ8�á5ÕW¿û¨E•’y+Áö!7Üow}×âRD±ýÑP”�L¢¢o�ô#a’_§"“!�ûÁßàñ]ÿ*n˧§JÅÇÑyÞO+€JÒÇ/š ëä|Wnö.÷ów�}§#y¶a1ÈqÓ<®}E º¡,/(ç¾æó÷3°ÿ JW㣌*}ç£ñ¸Ñ„Qöº[äö•�E�ƒÌ§ñx8ò­.w}gòñžû�eÐT?]¯é’‹×w@å3}¸êc6ýѽ�2ˆùÀl &4Ü*Yb$!�¢˜¡�’OgäȧÎv¥|"ñô)I@âå"p8€WÄÓOðº DñÂ5 šŠ¤_ùžäU¿ŽüŽ„N*›‰ s, qdÆŒØ>‡òRY„«�€V&ØðÚß�\ ¾Û<µ|ùraÉ]HHˆìÞ½[Þ{ï=Ay¾–rà_�_ÜÞ@W_µ-sðšrÌÖóq3(3ÔV†sçα|‘ŒPP�è à1¦öÉøø9 %„¦i¦Kþä8Ü[áâ; aÂ#ʸ”p5ÂÍò&imæ®QÄ ¯Cû€Z~ Cg@g@g@gàÞÏ€�[õ{¿Ñº…÷M¢ÑÒ'€?íy�ˆW>!3poš‰?3ñGFJ~ºEÂ`&ŽJ¸àI'toÕÛå£=MòÓêeב&åSÒq§Ä.C²g¡ÄnÞ7%6g‘ØBÐÞùÛä÷`Ð3çkë,jHwšˆóÆŸAÂàtÐG“xâ(zÞŠvøka2ý‹�]䟫e£û— ‘—2+ƒh’<îàÿÛ��ñT�f�¯®µ¨ýQå�;¶b„A–gK<±³—c”ÅPqùRâ4£kAÕOFßl °ç—Y$$Ô;{•ºÅݼ€^©~bi=³|Ÿsa.#ÖÅ@­Å¶$ ©Þº\¶c×I»ì<ác4�gÞhŒM,_ÛÏåƒ/Reƒ�Žzg¡»#ÒßÊ]®Æ|VÀ;�$Í×}ɧÃι¯ùüýŒª¯G¡ã¨�,_õ$ډƪCÒ\W¡&É Ðxœ3qQ…ÚÕm�ÃgÛ`Æïà^#ÅŽùÀs0ã�Ž{>Ü_IÀL ƒäbZ.”À(o2�bðx�G·”£äŽÊ§Î;A;’OŠ5ðs¼‘T8�èä2¶G;Ü ,àIà«À‹Àà!`0à4×_Ê%ê`ÙæB”¬e‚€’œœáuT,¡üÎbŠ$™»‹@%Ð7x¾,^&¸Ü@&˜Ÿ8qBàó$(·#¡Åuýxðµ|,Sž“èôÙb �ÇÅ’>ß�6¶ó~ –he'a´1Ðz¥(yb}´#·²ßÙªF${ñÓSËÕ–Ú½ù)ûcT=<Ë,ÍmNù5F –äêLÍ3—É5:Úpï#–«ÑtÜW°3Ø7¨tªð½�¥kÿ±¹K6Ú¾"ñTbfﻤÎ7C…ØwÍ®÷ƒõq¹š˜ßªwÊõÛNEþ\…’�dGÌóÞ‡$[o7:å|¥e‡H„�Céiq†Š+l7ã»ÏZàídRÄÓ‡=¹¹€û”ö¿UÞ*Äþ§üsMò£�žc·ÝÔßù»Ž^Doï%9A$˜$$*ƒ(,‘ºkû¤ÆãûNµÈ¬RF ôqPô^@¯wTxM̱ÊļÙw'53À  9 ãþÊ@šKÌniê2Ô\o•6Œúm êáOßMwvÃhf‹éŽ_‘ÔáA 9À“ŽÊ$âHð¾cð0 )Cŵ÷Á_€÷ù�g?$T½ƒÄI³7AædÃì<}ÇŽòì³Ï*åG¾;sæ —¹`¼„sñžm˜ŽÒ=cQQ‘äææÒ»J<¨(”rúO€_Wÿ/R˜Ø+@�«í˜‰×åÕÕÕað’’¤¤$Cii©¬^½Zjjjäý÷ß(£1 •[ÞùÀÛ "s‘€3Ø`4¯&#®Án„¯ðv�Ë�º$ Äæm¹z¾ åÀÎ8L;ØpÛuè è è è Üãè§»r�·Z7ï^Í»šì’=< dT:©§çî{ż(Y09 £Y¹Êëx×ÃÎc Á5 )ka„»ûx«|ŒQì.T€tjìÆz×-ŸúÇeÏ—Œ²Ï ¶±4�_0â…”:†@WyÏLŸ‹ÑÀعe'ßÿøV—Rv°³>A5MÍmV0�èà_‚Je¬‚ë'aáŽó0Ûþñ‡] D‚W¹—È+Õ=Þ 'z:Q¡óîÞ`ú`ý¯™çËÍòKò.GûÎÓeòýÿÒÑËlýµr¥ÿµ þ ÀYæ7»Ø)™ð´ò'¨n"‰‚ã§DÕ<Õ®2¹*ìKªçø}Ñb‘ª¦ù%é Ëè$ÁH<ÑÐüZ�Ýïö‡Ð!qå½¹l]®~uß5õ¼Çn¥T?Søýñ{Ü" $#YøöÏ>òVúZ¯s–ÐH‰Ë\(×cþKZë.ËéËír¹²[Jr­P¨yÎ_ó»?ã¾!Y˜k–Ùðã;¢ÔOvÞ;°Ó¾Ðä’pŸÕ.�Ö®ŽîðÚ-ÒTÛ.‘±ø}ôbÁm.H�veM AG½`€3˜“ [ðžc>ð,° b±À§-)IÒÓ1š-.–4¿~ýz(H¥Iøþ‹ ²ß}IŒz|ö.0 ÆãOcä;•O ,�Ç{L^{í5šySåME__¶Üî`=ð(‘““#³fÍŒt'§N�RÄÕT*�6Tx u\À2þ H€šjF¹³°¬�ë¤izLLŒÚ~|Ï�ãßE$öÔÆðH�O(åT†ké�JÏ�”ì‰qr«²ƒ)tá—O‹Ì3�i::::÷x4ùt�ï û¤yìaÒÄò©LÄ+ŸH©Gj‰0pz„,™!yi®ò:Þ˜�t æÞÄŒ'j ÍvÙ{¢M6ïo‘óå­ê©¾›tÂ#‰M›#ñ'$±`•„ÆäÁ{Àe¦z¿«�(3Ê·ž²Êá vù³W=÷ò£Iö°#¿|nÞkr²Ü³ÿöW�j´áR|ðø 4>¿Ê,ë ùÞ/»z•#½þÉPïçýo ‰žï½hÅHny *0÷ÈpmPƒý|ÛðOlO> YúUá;–�¹ƒÄ\+ʶX"éíïäþ~¨¯T-±lÿ9;ÖavuBúY(ËôHì\ª"ÙäTj'ªŠj0""I,.ËŸ Òî2J㨎¢ÂÉW° pŒÝ÷Ÿs(E•÷4$¬›oB9 Qþþ Ïyµó¤CvžÄÂû¯]Þê«>_«·$m‚ ?ÞÛýs”¬Î.âè�~&£×JÑL(†ÏÝb¹zû²TÕvÊÁÓ­Rœíƒ¡ë5_ï7Ü–Pø®”å‡INj³œ»ªúçìp.hŒÌr÷OHŒœnyµUø ½Ñ*)y‘CÞ’á-]Š|²»d*–¸ž ψ€š”…©7ô`^#I:‘t!Y4}útE@qÂHÞ|óM9tè�Ý|höpØx·•ÿ_ÞJPÊ6óÓO?*˜|ðAe‚NuQyy9‰'ž9À§À  ñ”NâkÉ’%2eÊ!áD¯'¨¦ø0Œ˜À€ê©¡dv üüÞ¦ìܹ“¾O2qâD9räˆÀ@�ë°¾/–ü6°ˆÅäê¢n3{õÄÑ;‹�-ÏçÔ¼îÚ°üœI±rrï ’Oœ®à~§ÕÝk|¨Cg@g@g@gàÞÉ€W—äÞi”nÉ}•’L«�g€i@ €îó…™d^Y¤<47OÚ-î*9bG&µ=VZ;`€|¼]6ím”“—Z¥¦¥(Ö\I§ÔÉ’ŒÑë’òWHHl�˜má蜳”w-ã è IJ#zаäp¸Ô�¤æáY&ùò#9ƒì?ú±ç^¯V=À dIÃ?í +$¿¨rÍp«�ègdÅU•Ç$=r8]9ö•bˆð¶‘(i±Br…äËPƒë¦ê©?ò‰j"šc»ãW(=dùas»û“áå¶ÑóhÎÉÕßè]ôî¾n5_m#F­ëô´³¿y|}ÎkJ5+–3¦}^Ü/y)™^`T£-z_ƒHÎ=¹Ð å•Ë ¿²¶çšâkeøŒû±­�×u©»k*’ëÌ{ ‘„®+MßÙ–?ûvç<x ôé´†%J|Þ2©:ûŽ4µÔÉ‘sm²bn„$ǘÅî/C†tðøJÀ3JB•ÊÔát²Ü¨ ˜ ¼xûôc˜2™€r ¯þV›\¿Ô(ùSã$eSTÍ %Z;ùÔ³˜j,‹Éà…í`Z‡ÿSA0ÑçH.\(óçÏWKQQQJõCò)55× £´¶¶R�ijuÀû˜kÀ9À;øC· Ø¢*ïèÑ£q›7o–õë׫ò;|&¯¿þ:ý”XÆVdÍ@TV1P™V­Z%+V¬¶aß¾}ràÀšc¹|œç›a è�™Åvü1Jì2Þzë-Ù²e‹*»ƒ‚‹mÛpÿÃjc¶^ŠwêbhÁ…ÖlÆÅbh‡P¯…{¿á±™?©˜„0©»Ù†{I'IpPŸÜO:ttttîá à6W‡Î@Pà#Rú)ð)ãl P²kz0M/Ž�Uó"ð"qÑ&Õùå�¨w‡Óû,¯ëF)Ý‘óòÁîF9|Ú5z]»KÒ�Ž=Œ†“J$¥t½$比°ØBËPZ)�0È8¯í±>5í$nCªn–á®ÌèíÝWÜæ~¤’ºF IQ~(!ÄŠ5Å0DË)ŠÐ%Ü\R3Ñô"õîÆñ�NÐ<ÑJy™wNvn°CÚ'l4Œ”Ñy¡ÎŸÔü«O,Ïy¬¹�8Þ|{‰þÑ#c%üȃHþI7.mÍ>º,×m0”j9}'YþÀvtÇ‹vðX­mÝWkES>%9ìôÆ‘°Ç¦ŒÊ´×߯†EÅ�/‘/—ǧ+i–o=8€O›åן«©MÝ¿½ÂFìcƒGç¶/õN�®ºBà“(?Gä'øÐI¦+ÆU°{TÓ¥ò‚ììl—Þ؃ÖQff¦•——Û;ï¼c'Ož´ôôtÇ\3fŒ-^¼ØN�:E ^–Ö],'&åòø×)'5ïù�9·¼úê«XUwÜq‡Û†¦F1Œ{÷î i{¹ª„—;dÈ›1c†c!0ûèØ±c bN5îÞ½;$ E¿ö�üyG'Л~%çý‚Úԛ㔑Fø�ò'ääÞå­?ÛlŒ%Ü ORsÑ¿øÔ[Žo’úWNï4+,ʰƒ»*í¹:\~<“VÄ/îö#àGÀ�€�ž|êYçãZh o»çËï—Ï–:ñ¶Ï½e:0ÝÏȶYÒuÐ;Åi1jè¤GÊ=Ïì:P+¦S•­ÞPcGU餿œF~n‡AË*(µ"�NŠgŒ褊=£x;v-ë:qx÷Ì »rô·Ïl¼"]«+�§»”Štṵ̂}û_/âáÌ�ïþ°£Ÿ“£ÛNöÄÕÿêáˆ{¶¥ê™§u“¨3€'À„^.ï+'´œ˜"d^*&M©˜6œ“s•`>ñÒæKKxQY­Ôic˜ÀØÙ¯”±¶0¡¶„€Jd¤‡5÷]¢å;jì'Òé.Ö‡,µ™xäè}9•öÖëøÛÛ¯YŸÔ½u»lñuTzûè‘À*=8àúÎÏߪ³'Þ¸Œ¾\&kœ¿–4¨èé1€_¢í¢?E5H€/ Pðý좪6\›£ß´çØOAKË.²^% ìÄžåNöÓõãÒÄI¤vÇò¥E)6et†½°ÒÝðÁ™$»…Uý¯z^`#½'¿I?—£ëNXïA™Fê”Äœ[Ýb®9‘€ì̉ Žù¤ à”xt†Ñ�§È¿.¿]ž£ @iáÂ…¦*okÛ³Ï>k†˜L¬1sÂ.ýŽå ÄŒjDI"à5lgƒüuy¬ñàÁüÜÿIJ@IDATgô|1RbÞ¥0‰ÐR‚Õ4gΜim°™õVE9ƒy5hÐ ËÈȰ´´´µ¥FŒ©z‰–gj_ܱÈß”ï“_ÍIémzÇäWW³£Zàïåer€9J/Ê-ß/Oþ¦§…[°Kwø€~�`›sbZ߃ZØCÓW¬¶CÇ.8�'öÇkµŒÜþÖwÔ]ÖoÌ�–U8ÖRÒò.ƒN×hŠ]Ž A¥r¤átbê} ©zßê­eºDÙ-Q‹m�°U[ö¡„º«ڴƺFøÔÌÝai¯�­Ùn{—HC4œt·æŒ*t°×zå쨴ŸÚkTÈ{o{½*Ô©ß Ldhq¾’CO´ õz Ι&Œ­ví±Ý­ÿ¹Ea.ÿüÍ:ûñoÝàÉ-ÖÑUÙ(@|HéÇyý¯³Ìü¡Vsr›mß^÷×z+‘_}+„Ç9Ö¼œ Í›á^Tž¹È sˆü9 ŽdÄZ̷΀á*yqõ™Ú´-ïµCslÔ´ÂhǦƒ·ÆÔ?jTœ8gg£z<'´:€@ÄÚš�%µì8-õ5¹žŠ‹‹iÁ‚VPP`b!9]§U«V9ÆéqžÁ€"åN@ÔE±“ÄDJ‘l¤©Z†þ¼M^î-ß4…Mû©DË}AlªBôžDÙܹs­´´ÔNª^§ëªÞ¥øÁŽ’5 ø:/€ë¬*ÍehßÜỾÕäú%kÖJôÍbùl9ר/ áÉwÈ/”>Ä'ð�ü ùkrö ØQÀ“6Õµ»¾ïÀ,KM¿ôã2X-è#gFKñèÚ†ú{ó#àGÀ�€��D@Á7?-E€ÁÅXùcòoÈçÊž" DŠ:Ýr}®}bI�Í›œia;)Íkís+ë ëƒä�kìGÏŸ²kªìàÑ bÛD‚#éùÖÜÝVzÃXј{Ä|Û)’ɪ²V>(GWêöÿwþBÕ '… â5Ï& z_ì¢GÄ,qÚ¡ö²iÚRïŠYôúz^úv��°‚È:€A¬@6úW0f®&üÜ–V{àÄì±aÇ¢¹alÈ1t42˜ð}BС•;cè m@¡ª*ÌG”8Ы&~€Nó'†lˆ@²D†öÔ^1¬¶:ÛH­ÐðÌ�Ñ•JK•ŠŽ-VwÊk‡ht£8¬lúZ{ FÒy ©I¯+-J¬ýX‡È9"ô¤ÞµÅBéŽèœM‘8¥PtþF¥^&Ž9÷¸™£BFÞ~°mmH¾Ýêdb?ág+w[åáuNex`¿T1XìÁVìžþÊ‹˜veÇêm¹3 ¢uz/ok ›Æ·k'0“è¤#ôó9�T¹zõÍÂþY–[˜ªYÑßòd‡¾Qqü‚mZUn‡v¡iî˜BOkº?Ùm´b¹-ûE9,ìüââb§ÁtÓM7YVV–©*�ýìg?³•+Wº´:U~cÓôÏ�rI–5f#ü­ô8Ò₹¹¹!À*Rºc96÷Mw⯨ƒò°¶Y¢md!^Nõº¸í‘ÖGªÀï¡C‡ìÍ7ß ¨*^à�7ÞHSê[óe€~ÿ"_+Ot£€e~·ü÷å¿#*"t,§}S|5ë è:)gYÒc¯¶¼i•Í×ÒÓä™}fÛ¨©½-#Ç�n­ÚH² t#j�ÃŽ5'íô)Z£�Vh}â¡_ßüøð#àG §FÀŸzê™éþv1’.çáîÛò›å<øPÇÄz奨b�N-ηyÓ2mp¿°e¤1ÀÑs@kò@±u­ýäÅ {æÍÓJ·;ïRìØ\(%Ýú_l¥×ÇLüŒe÷g)©°ÐiMv¨µzŠ4Ü£â'ÐnÕ–öëÿ´å¸bþû¯¥Ú”áAi9]F»`b¡ÉÓ�F™ù»g‡-_in/‰íÔÙFºÔä¡A»ezØæ‹ñã‰sÃÀ»³ŒþŸ+6 ÀÄA¥�5—†kj”˜R'ÎD[+? !íÄ·sHû¤¿ÐÑ™öÕ¥a{äöˆÒ 5(�–têL£ Ô)$ í¥�{ÛŸzÇ>9^Uzwlµ<Å%‘q.ÏK³i“Dó›‹s¢õ.ÍÓrp!^“*Þ*ÅÌ[­kÝ«ëGÝõ½zëåø£çôŒ´Ê¶J¬+Œ{+éwuç*íä¾åJ�º¨ûuÈ®�îÿÖ´�ØEtÌÄyÝösÕ#]å¬#šÂÈðíÚ‰�& 7�‘ õ�ù•b-�¯©s‚ÎPô�d~bY¬N…v|xÂ6®:bUÀÀN ìYM¥iGY®6ô€üóò"RÛîºë.'è�ˆ8ép{lÆ ^e7Ýaœ õ_kú9Ç\*ð(¿²²à)Hú)sªZ8Äöæ6ÉãS¹h™·M^¦eS”Ê—/6SÚ¾}ûìS‚äŒBcêÅ_t)bVlgâ²Rþ}ù›r€¡xË׌»äß•O—¦¦¦¦(u/ 6µOñ¤“¨�šÝ¥vƒöF;3 ‹²ø”Ù©à/8mçšF¥F¥ˆ×Uò�òDñÔlßüøð#àG 'D ñh¥'´ÌoCwE€�Äp9u€N·ÊGÊ3å®bÝ�Ssí3K ì¦éYV¬´ @'PÛ:éyU´÷€?Õ`O¯¬²ŸŠí´n{��<]ç*¹!Ë<] Ó·mðÔ/Yî€iI/ÐZ4³knÚQ‡L�¹ã¢/lXÏP¶^:5?Y^§”«ÛU«6tZû½yJÈŽVFAŠÖ0oZµ£$F“çDÌP¥Lì”S4þí¥º¶IìÓ[±ðYb¤Ü%°kriȱœ¼ï’™r ÀT«Õð¢Fé€UzÇLÓjùKhb$Ò`bð«ª@€ •Û'ýšþéш-“׫Ò(¢¥IgjÄ€ MRªY"$Ø+VQgƒO°Á¦¨ ë"!¤îì €Ä´ÓÉû¢iÊzØÎÃ�Ù¾¼^tnëÿçz¢ÿr.I%®ñ–"†óaÒµeŸ´]§â~JÅ[0Ö³ˆ÷kæ‡õ§Eܱ;‘ó1s�»ngþ …­¡¾Ö*ÊVK ú˜Ú´±¥õ 4¿a'n†õ»½å•͸>Zf]Ó7å Ú}»v"À`ý°œȰºÚ†œ“GjìÄÁ³îÕNNAºÓØvÙìo<}‚þ¼õÝãöÖS{ìȾ*õµFÀÈ_ÉéùÖ@{³ëå_”�—ˆwðÖ[oµ¥K—ºçÀ*Ï ì±ÚZ×7ù5yVþ·òWä{å‡ä…ò±JÅ‹�އ^úM°˜ÄfÒ�Öé#±ì6ùeäXš>ÿ+_-@è¨ö—++_¢âA�X® 0Ÿ`X) �_÷ò_ÈÿY¾J.˜ú#V¤9Ÿ’?"+À)‚hùÝwßí´¬ôÙŽ9‚vŒÃy¹œvt'è2EûŸ%ÏÎΣrZoËɇ@Ö9Æó&÷ÙmﳇªékôÝò5ònzŠêœcõ·êGÀ�€��[|ðéãvFÛ~<üxCå~Xþ-9 Óh¹£¥F¤ó1>˺¥—Ý6;ËJ¥ZVFÛA'm×�NgU¡êÍõ5öãç+íÍ÷Ï(•£Ö•©‡Ñ”žSdC¦}Ù†Íú=+(ž/Ô¾ªÜ$!ÔÆøç@¶vmØgoÛoI` Š€ÒÙ<#Õ­«£Ùf- ;‘nOc Ðä·ëêíåZ•ò嵿£¦ÿç‹ûÄü{w[ý%�s¶ HÐ&†J+ð3kTÀî�“â˜:‰€os´¥æ|ƒ7/ Ãe§*¨‘BµYlš `ÐïAüzýÞF÷y£„Å·é{ÄÑŸÐ�‚ñkìЄêt»uÌ€V±“@Àf­¶OÕcÇHR?ÏÈRJ½„ÈÃ\8t']DxPŸîS¶ã´­zN€Ë†“Võ0ª½£ŽæÁ°f¼»C~—ÒÛ²æÍ›gwÞy§KsƒñôÔSO¹ô74—d»åÿ.ìY''ecJ³GÉ‘z‡Pùĉ]ŠžLú=nàÙ‡åèÏòxc}Ž‹T6úýZùòZ÷¨tŸªå•¥¶kÞ‹òÿ”ÿ‡ü9 TÜÝ]s¢/þ¾¬é䥚€j<ð€M™2ÅŠ‹‹� z´@tŒ0 Šää‡äºÛv‹ Ö^o”uŸ6±—ôMwý£3ZC¿«Wµã­ï³ckŸØÍrâïƒO ‚o~üøè©à�Ñ·ÿÞ â´–iº@>DÎA=ašD•ƒ6ax¦ÍŸ–e×�J³>ùa½ñ޾m+Xëàì…{oó{íýÓ¶A•—ŽW\$}ƒ]JS$b½‡Ýd'Þò]o)b:é1W$}ßÚQ’ÛbÏùïe¥�1p è.»nØn›vƒò¿úµFËMÆ@¼»�¸ >�fOtlÐ5-BXœª;Tݯ9!j´¥Å&  vÒ©*¢(HTs¾ÑU$Ù¤Vé'€.xl—l"½n»�E*u?qhHŠ=JØM€&sLJnD÷G:¦g÷ÌEǨñ>³MÖiÞT÷1¶Í/˜Ô7™R"ùöÝ0öÖ¦ú+4‹¨„o0‡Сt£Ž)‘ÞŒpDEAâÚZãøçŒ :0éG¯Õ9•óÄ>ôJ\ùŽ}حذJsl­ÁjúP©Œ°¬Æ7¸~3RâéÕê¤ÜLa¯o¸|î¢sºãøgbÜ¥çYþÀV¾åWvFüú]çl¡¬0ÓZÀ-wKÓ¤•fw¹1=ƒà%rÚ‰ëší[��´Lþ£¦égÅ€ºA¬’¬*iêìÛRa}eÙ Qy6pX®¨Ì}fVÄ‚êµgëm÷Æ“öáòC¶Ë)xâ0så åoË+oýE¦• Ðy¾RÑLÌ'¡§íðTVVp¤»Ž"�^’1Ï3®NÀ¨÷å“kjjÒ¶mÛf0Œ¦M›f›7of;ºÓ9†Õ,M÷Ë›®hýu¥q\üz’³@(Ú˜%çά;…Á’"U`$¶úèLwq»NþUùRy¡€§ À鄤¸`ƒFT=ûi×®]ëXÍþ´œ6î‘w‡íÔNOɇVUžÝ_mÅcó--=tÅï_‡7Œ�Dæ{Â�¶ÃÑß ?~>nH<ø¸¥<‰" n…ÿº¦¿+Ÿ'/•‹cAô@¦�ɲûØ]7f €J³‚œ�K5iÍ EÛºdˆ‰×éñ`ÝÎ öÓ—+íé7*lËžó®ô7ƒtÞÌçôc¥3¿aC¦ÿ®åM‘˜¸šãY;ê¹õRs:õ�[§…ì‹KRlùúúK`0Yž“Ö i9]eAÌ.¾M;„™�~Ò/Tjþ´÷¸«Ó´âƒÀ:•ÎbEÄa¡<õ¶„ cÒ“:³i)÷Í ‰½²‘J_kzÆ¿´[@'bö¶…×7ÔÚ=°ÖÐ ¢í+'”.‹ @ö ñNt�€Ð�ÞpÐs&~Ÿ:ê;Àš¡E{^Œ"¯ÇÄ ÐÃ&šP¢Xªí‰Ìc>Ų”-×ܮ䚼tÑ¥7²}Ú•ªÁñ$¥O&ܧö‰ƒ”NO£*¾]WûLßä¢Ðgo¾N€¡†–ϼsùš¿Ú6:ã{úµ~Ån?ÔXXb镇ߓøx¹ë£CŠÒ¬¸(%a�]7þoÎ짪s ¶qçyÅ»‘�6ÏÛå F}»ö"8²_c©\žQ_×Pp¶ª6rêèY;¼ç´í^ʶpܶ~p̶¼}ÔÖ¿yØ6­>bå{ψ�¢tLADô›çR¡ ´ ]™Ž=«ª# `g®|ªÒå‚¶cÇ{ï½÷\š›Ø@ºòíùßÈŸ“#´íÝ*ôç%ƒyÔK>‘©ÒØ\¥º±cǺêuˆ�ë8ØÀQsì'}u…,±]€¦crb Å6€æµƒ»ß ù7å·Ë{©R_áôûï¿ßµ‰˜¢e…c¤R­oß¾}œsÍ ’“:Éuׯ‘Øfʇ‰…”’!`²dL¾¥‹-×W{®Þ6«:ãñ(󉸾&‡ùDü}ó#àGÀ�€�~´|ûïhÚ å<èð–íù9ó¹Ùa»aR¶=°(ßn››cJS­W®oŽ8'zrÒz-p¬1`[ö]°Ÿ¿Zi¿|­Ò6í:k'*Ñða‹¤Øõ·A“²aï5l‰¥fõ¥Qê5šbG¬¾yWŠ  p@ÀiY]m°A»#ž¤4?DÄ=�€&MwOÄ� vÿó“#†À ìÌK—Š~êüÿï�²O*Í�Êh ƒ.uÊÛ+ç°R)SM/}ÐàX>Û*ÕN@’ÆxË·fʺ=`›!ÆŸàÃù*Óê?^®kŒ‹‚OJu�0z"„Ø{D,�˜¹DË%š3ëOJqie¤zFú €�×§¼ùÍM£±¢]Àú¨ºc" j@Q£¾¹Aéj-Åö‘ÛÃö貈@¿†+*äíQE?4°»(Å�ÜWÆQ1Ðà5ŒXmu¹U|OU½K£š<2ÍÝã[³/ÓÅÍ>îí§N«¬¢ð>9ƒß7䊊o×`¸ŠN¶ÈÑ3bZ-p1½ö|}º€¨ð™“zitôœ�,¯Ñô¬ÕT×ZïÂ>¶dɼQE7'Þ­õèøn9ÀHG\ô+ ì!‡Š¤±DWéĉÒwôéõÝ÷å/Ê«äÍ74~y†ÉÇ| ¤?~¼edd8 KÛf?´�|«¼#Ú¯Í\a“ôéQ9ÀSŽ'ž¾lÙ2Çx’H¹Nûí·C·¼¼<“@ºóíÛ·»ãVx~+’o’”7ý¢ê¯®1úÌ@9ì­ìú‹ b>õ²ü¾i—[Ù À'Dñ7®†žZ"»(L�¤-‚ãùJ¹GX€í­4H$U]&ô‘â oÀŸmŠ5hÍi‹u¼›U).VØ<Ñòô¹\]—£‡>_–§\»_¤üÅöÓDÛd€Ü³Ânyô´<ó*zŸ»zJŸºSí‚5GõÀcºÎâ-N±Æ`ÈN—½mg«•&¥{ñ ¾©6¤•ì'À'ˆ°Ÿ*«ÄBØs¶‹zŠc?­×ô@ü¾ýÏ×LèÔ° [;Áí·5}Cþ¾ &]纷ªŒóó lΜ9vß}÷ÙÂ… ­¤¤Ä1‡Jšt—ò´<Ì€‘=Rs[g ‡ä€Y©jÇ �Ni°­dÛåÿ$JÎ>¯f€S´o¼¶“îÜ9Ç4B|œ´6˜EšÏ³Ó)ùFyG´_›¹d¥úëËò{å¹O‹ßvÛm\Ú¸q£ýò—¿´çž{Î1»Ö­[çØOÅÅÅÖ¯_?·„Õ4—Èyx"í¯BÞ•Fál®¼H e ÏÀ,ëWšëîÝ�€nÜÇÏÙÚ7»© `Õý\@HÿðÍ�€?~zh|𩇞˜j…òÛäß’N>]Þ_žÊàa@ïT»ùú\ûÔâ|�OY6|PŠåfi Ö4¼<¬ÒIšXjãŽÔÚSoœ±Ÿ)Åîý-Õvøx­ôQ¢[LI˶~#n³¡ªb7`â§-»ßKIå�&·e¯I6®cà�Pö�¾A±cܰÛ˱V¨ÔÖUVÒ7ZU,–Ñ´ãPƒýj•49bÈ]Õo?Tуåû‹%ÏÞ£PäòŸÒ×^¶oˆ�öŠªÄ‘.ż¢‚ ÓzêÃÆ�)´»¼Á1GÞØ¨¼-É2bZÛrÚ�Ï´´}ÿ²q &piCsó 0U"cÉT»˜£#çÄ3ÀÀ ½Z×îóD;°ÑŸÐŠ7Î÷Ž“G!ÞNÌÑáºQmÚ$ðÔ³}êG/ˆ- z5cŸTfCÛ)ËÁì]ƒ´Ô~êÙ¡öIŽHé«tIDÄÑë.7$àÚ]ÁЫɶJçêçJ©-;á͉�*ȉF§¤Û…³Ç­òЇ6ëø‡lÒˆ4#ݳU¦Åé7¤mØuÞªj”w­|Ç }…üò ±Uöî! sÃ$Ì(“îÀ,bþynvv¶Ýxã�6oÞ<ËÉÉQ¹³lÍòxà€cåèO`}fî—o“wDŸ M‡å;ä©ò¡rìiù�äGù�„éJvépÃ5û);ö,(4•ª««a?ªî’süuÁólö)ùgä}I¥CãiÑ¢E.n¿ùÍoìW¿ú•­_¿ÞŽ=jÒ¥¢-ˆ�SéÎhÇw ™€3]‰6XèxØ•6I>BL¤HXU5ŠGç[f.¡ëXƒMpûiÛ¸ºÜª+Ý?Ø^?“ï•wÔùéØFû[ó#àGÀ�€~¬|ûøE€@‰œ·iß–B>UΫ2�N+�n·ÍɵûåÙüë2Ý[oª×‘úÒÖ�6Ì Ò\Ÿ¬³çWVÛO_¬´·7U[ÙÑ àDŸ‘ ëSz“• t8åó–W4Ù"ךòkó™á¼µ»g‡�Þš@É0't°j Ðÿ⳩Žå´|ýåg{¥Ý-$>ihЮr"ܱþ:4IlìŽYÒOêe°ÀtY89ìªÏy›@8]§Ä8êŒØÁ&BŸ‰4-®5^ØÃÎ!E“ 7Ö9*%l§4…š3À'À•æ˜O0ŽBÑhj©o .›–~QÃi~†Íï½¹V}t¾w¬½•7\)‚€MñÛ‹6nRꌰ¿ùRĉ²¯¨[™À.c[Ä—T¿¡ýï“í Ðމù«Aã‹ÔÌEê#ïl»|]‘¦÷Ò‡õÝ <-š²ÿñ‰ˆÔ€tå.·�ª�ˆ ·d¡”TÝ«#VY.í§ªvQ÷°Aý¢ì§ÖÜÿ9‡Üó)Lq¼²Þ¶ísô@F›<[�²Eú–o�p`¤ÈP&×]ËFÖÖÖfdff: DZEº®ˆ €:}ú´c”Èx³D'|JÒ¢-w�“rP»å+å¿‘H]¾ ôá*ÆñäÊÇ‹=•ÈÓ·o_9r¤;vÌ¥º5±ŸT7Ê;‚ý`¶Tëi¸âtÂ>üñÇ�4»òòrS|‘Þ�Ã:ë£4¼LÀ¦””ƒ¡5tèPVJ©º̧b9`Ì^¹Cf4í c_%rž5³ÏW×Yÿa9Ö{@–Àí7û¶¶H›B�aÝ[\_ÂIJbKïÉ9÷þý†høæGÀ�€�|êÁ'§ MÁ+ÿ¼ü›ò;åå½å€¥ÒÁvç�€NùvÄ 8R,3�AYÛA'­êÒóŽW6Ø«ïUÛ tZ±¦Êö¹`çTŽ ¥D¬°øF6ë6ðº/YÞ€–ª”;»Æt�r2”†tƒèbÆxLzo‰!ó›ÕÝ<_¯ð^¿§Á•ug”Ж¡Gj˜`± '´x¨:†�xW`BÞ±ŒRØH[·'�ôÔ(h3]¬£XðÙ«6¯ÝÝ2X»N²÷ï°},UCöœØ;C$´eêp úÇÝ‘ùžôÍõ1zKñû‚1…P:•Ö×'Ø` ‘æ×œ¾ägœÆÀXg˜è#ñL/öó ›þ³]ºR,û�@³uê×Ä¢-†x£4çˆ)ŠÍús‡ÄŠÕ¶¢?ïþˆÆSÀrKñkn»�5@¦ÚÛJIALÞÝwÃ)™V[sLâã®—(»ØOmÕ~7Dt[¯bgÏ×ÓÕ›ÈÀ °5�Kþ0ü%»3z­áÒ›F °)°x …B–žžn0‡A¹È=EâxCFæZZ �õ#qúØ{û…ývdŸDîy°ø…ü y�Ü7?~üøèÁˆêôà–úM»ZøÁDþuùùhy¾<œ"1•1C3ìŽy�nÊ·YãÒ­ï°¥‹1ÁÀ´5oºµ½+ŒÁá™ê[¾ö¬c:-ÿŒí9tAƒÝhÚLPÚ"ùƒfXÉŒ¯[ñ´¯JÔàKÍìcÁ�tGx}ÕeÏEW4»Í¾'1ßÅSÃÒvŠæ½ UwÔ£´·Á¦¤Ú|õ¶£z™Ç0yVUôÐõéª'Íø&Raë?¾•j &†\j›§S䔘t»øõ:ú3"Ù+ÆÌ(‰™¿(°É3!±ZB´Ñ2,k09¸&`À Þ‘x1m„„ª•:PèÅÝ¡©#‚„ŠÝ_}L–õšÍÜ'`ãÅ~âzŽ7ÀÀe@µt*wÏV5KµPÇ3ô“`{uðÄ~<°m`oÞ4VËpOAÀÍ"úøÖ²¨¨·×ÎÖNÙ' 6Àµb¥¦6—Zƹ¡‚!¬¸X`™ªz¿YU×­©«3�>ªâïm¯¿ÄjTãšß´¯m}ö“( Ò~Zí´Ÿê¾ ˜fû´®ò}ŽÔƈÒl»h{uÿ—iãÎVèÿŽ`Š4mΟô�Ðé` ’O ‘î’Kó´ˆHÁkDZŸH“éÕÍ¥ô»Ýú»m—-]il‡N´~ù†å2WûDª©�Þp¿1b„ 6Ì¥¹‘BØêTj™ r–o«õÓŠŸ–ß#ϰC㠆ؓO>é˜Ob0±íò?‘ÿRN¼îŽÉÇÉû œ ‘Ž7xð`Ç€¢úúO:ü ”½&ß+¿|“ׇN2ÆŸ’ß'/”ëGTˆÞ™‹Ö·8Û ûw û‰{ ¿°ž6¬8d5g±«L³þE¾EÞÖó¯U}ó#àGÀ�€�®ˆ€>uE”;oœ¿iò¯Éa:-’—óÌHÓ›ìQYv÷ü\»gAžÍ�a}{…,­ƒ@§óª}wÓyûñ öòêÓ¶«ì¼�©ibÿ‚J©gC¦?b%3³^Å TÁ®Hcž‰°ŽzîŒn­«þG öºAüÝöµÛSlúÈ�]à´QéIžÁ éN#uìÌYª~µÌ²éÌvžªj´›”&söàC"KQ*@±@›É¥¡+@› ÝI·€@o‰A~[Œt¨‡‡­Zi|Dz4ÙòõõŽ)çOÌÎϸsšÇ̡퇟ZH™ã�¼—Ö‡9%ÒAB`°zò¥·ô½Rèe¥ŽyíèªîC\‚Æ«Š&|ˆ8ƒýø[.–¹·X«>r­T¨_¤¦D+ߥÇékÁ^„=xÃØ�ë/±Sè¥%înUÚ¹0zeS†…\úr[Á¦+›À(Ný%œjç«;í'˜_™é)6qxšRé®\újŸèƒ€z€ák·Ÿ#Å–žˆï—ÃHñíã^¹èJ¶Qf©2œeeeYii©c>‘Fú H“ø8½ `‚[ ì¡ãòžbÜåé¯cä#úôéãØOˆ¦Ã~»‹» ê9íoË-“ ¥ò/ȇäçç¨ˆÐø+¯¼bk×®%uN_Ù!ùÈ$ó€ÄßåòŠy_¥6†***ëlïÞ½¶sçN@,]…ö¼œ44–ï ãe'/>ljõ†9Y{^Z�z�2xDNTû©-‹i=Út‡v�¶7½Çc=±EÀ¹'å€s¾ùð#àGÀ�@�?¶¾]{У¾Í”óc�/�—Ê3å�¼œ°Íž˜ãRënŸ“cS†§[ïü�(äíg:1ˆåÝÓV•Ö~âåÓöäòJé|œsÕŽÜ _ Svá02õa�Nß°Þ¥K,-w�ÅÞ‹ðv>}hï]aYéæªaˆüvÝeôVÈ›J±ëJà °+VÃ& U¹žV[[�‘öÆÝ¢OÍk°ª×³bñx†.Ϋkº,=iˆÀ£/ßšâ4‘<}¦�.*Ä­R•Áæ€'ÚË€¹0W‚ãmDÚ¸ÂHS™�Xãm±¥ÓBb¥¸Êc±š<ñ !í|š5:ä*¯Åî‹ö—I_qöøõ¼å˜˜‚î ªDF%9öCê!i�…¿ZYïDà-ß™óˆ&¬4ÀI�Œ7ÚÙ ô ÀçjÕìâ×mî3`ýã� 0$¹ ðœê”\KÑtÕFxA'î«ïÔÜ6;k>·Ø^RÈ9 —£É ÷‹‘õŒ˜NôïŽ0"ø„€JEÙJ;w6Jæ€%[¨ß b–¬qÎømëºÙsè¢+.¡u¹é3¨]+Å·�Wè!°ÚúÉÇ‹å”à�2`Àw¤€Q¤ß¡GKGXÕGÎz0UzR¿Ð�ÁŠå“u©ˆèÃ|2dˆKû) À'Wߟ•o–Ÿ’·Ö¦h…/Ëg œ Ïœ9Ón¸áÛ°aƒ½ñƈ†³=bƒxöäåòØ+`é°œô²‰Æ Hµ#MoëÖ­¨6Ò¾¿—¿+wÔ M;Óøõü”|™<îܹ6f̧—Eêà™S,+'ÕúɶHj+Qí˜V‡ô#vâp�½þ‹=¶sÝqOë‰>ô·òMò6¾&ŠÙ‰ÿ§?~ützâ†\�¾?í�À(mâ›òoÉçÉ‹å‚',P˜Ÿj󧿨7Ø’Y™6¦$Í r‚Ê»g˜¡'˜ØG7'ùÿôiO½yÆ©ÂÖm?+‘Ù‹bˆ°á€eæ²A“>ã*Øõ~»eHÿAU•¢�NíØyòÍì°%L=¦4—AJ Z-#¶‚\‡íä*¢Û_|6â´œbÓǨ3£»€'š}ýè }~qŠþ ]äYs‰÷}GO¿ 6ÌWšà‚Úžµ:yËÐV˜0cœÖ‘7Ÿ)矴<¶»C ªX v¹Ø¿ãAB@4ƒ~üZ½ØO±K^ù7,“"éSÍ2ÄÃc –i`µ7wý2Ÿë¦Usï8ްe‹ª×mÜר©éu±Çÿ÷ß~%â¼?ÜYïÒࢀö•K1�Pˆt„q¾I­£¢ì<*î½"æ×Z±ôÞÙ¦”UõŸ×7DÁÓŽØ_[¶�&Ø_=q}�HÏ»w(-²£€§èvy!Ö_(bgOî´3Ƕ ¬mð±±%©WŒx½v´4¥F$<^sNºjÒ~RLž1`‰ìhi]ÿ»k6ÜÙ@FË“^‡ø8ì'¦¤¯‰ÝãX0¤®5¥ßñ’LðªcÅíÒ´§<÷ê�űŸœ c5iÒ$]w ¶gÏ«ªª<Ë“‘|8š’¦ÉX‘úŒüny6ÀÖ²eËÓéÅ_tââšÏE¿\þÏr•Ë?júÐdì³L>P>R@YZee¥®<±È^ùåûän†¦�iCµñGåãz÷îzà�lÆŒVVVfGޱ úÑ©8vÎr{¥µI|œçÎ�tžŽì«ð´Û6½}DiÂSƒÕõ}ùËònâ¡kϾùð#àGÀ�@«"Àƒ¡o×F «NþGò%ò9JJ¥‹ØM3rí‹óíæéª:3(Eõ�%^¬GBžEš´²n2ÆÛ슪{ùÝjûÉs¶j£Êý«'ú\“šÑËŒ¿×JgÇŠÆüŽ@§‘Ždê©G£‘.yöIæ(Z^†AŸžoœÖ K^PÑêgoÖ;æIËkwη°�î¿1,#àX<³§söÖòV³ÕÓ<})–ܯØä òüÑku–Õr ¢ßf¥]ÙXW€ ¿XQ瀕d¶» ×)k#0§¿^6ÀÀ Òæ’šøÓoÐûŠXT@óXj€&hpµ<±7RüÆK€æ)g±Æ5¶½¬Þ>ܽÖb¿‹ý›¶–Mš8•�eцbû¤‘�TŠYw,¯< ?×ìn°w±µˆ)Ç´Cº[ÝV®íÿ%Pwì� =/€ЉJzô…î¤r&€äª-õvŽáp'Z@LÕ`XOugíÔþ7­Vº30>ÏJ ¶îî­Ë'Ì@Q?ç¥+ìíä.Ū׼yó\ž�:ÆéŠT=ë¾ ÿ;ùÓòcòN¾ÃkQÐñQM'÷íÛ7åž{î±áÇ+ý6ìHÀ;ô¾ª«ª�8ø‘5¸ë,#'bYUÃA§PϬzÖ¼ì|è$FýñÕöÎólÕ3{mï¶Svá,ÝÌ�j?Ôô_åû䀘¾ùð#àGÀ�À5~´|빘¥¦ý¾ü+ò©rÖ‚Ù™a[$¦Ó§—Ø‚©™6¤(¬âúÁÖ½7(×rm6—£mí*«µÇ_®´_ÿVºN{ÏÛéêúèöõ¶<Àª vC¦Ír̰Hz¾öÇðƒaݵe€ þIk¡ºVwØgoÛoI±4 ØQ©°-ÖOçé‘e)6vpð `y›ÎºNèÓ–m·wDÄZ¨k^}M/ÏT[׋¼5Û6 Cì¥ÚÅ §¬òÀjU(«sŒƒÉ#Óu?rE«’ß°º0ý‹ëeã.W€‚N­Þiò•ò˪¾},"@wåü¢‡4N)jÙhQõ®¤¤D×6Äv…x7`„Ò×8p^¢‘š¹]^&ï Æ±Ð¸þrÇ~‚¹�¶oß>ÄǨ`HÑþÝrŽ¿9›¬/‘/TÒÆŽkwÜq‡‹Á3Ï<ã-m—ý®–ÿ›|£<™[HÌ!ù{ò—ä¯È7ÈÑ¢êªël©öõ ¼Ïœ9s7Ýt“é8�lNû *@;qgU�®|o•ØRiGöW[ÅQÝ#N�·Êçõ÷9;uä¼Cªl{¥­£ÜV>»ß¶¼ÌN–×XýEwH´¯”ÿ‡œ¸ßüøð#àGàŠ€>õÌ“ÅÄÇä¿'Ÿ+çA(ÖÛ ©c³ì³�–ÎÎvL§ �N<عG-Ô#Õ…m>YgÏ­8c?}±ÂÖl­±c1ºN%V<íKÒuú–”Üd©Yý4pIÑþ»êY§=Gh6¬ÀT*Û‡0¼§;ôœÐ-êN‘ác�ªf´×U m¯4~ºËÐp¡Šu±ì�Ýå ðn°u{:þÃÖø»]ì3.@R±JûÈ�y‡ ´òvúlÞ#¤NZE§�Õ(í'¥a‘âo€ °‰*„Ѿ?ûtª Wûb5y`«�ˆÙÓ¥f€#K§G�=~]ŽyÝžz£:ÞÕt�`1ÑÆóµŸÔ}`�%2X^°ŸÐ°‚�äA‰–mí<ô­buÈÐ)JÕ¾~½*±°9í$M‹¸ç%h/À Õ w¶ôì•0˜{0¬`[u6Û«51CD •Ê™%„Þ�Æ=< [åá÷5@�®pƒféwP§N�r”Rôt…»j7›äm„˜µfÇíàn>T^" )€‚ˆúøñ㈂ž‘ªÊ‘JÇ2yòÃrØFñ2Lõ¯Éï”g<Øî¼óN+,,4tžÖ¯_ï¥ÛíÑ÷O/Êa’%k´“ø±oÒ캌á¸զ뼦Þu×]6jÔ(ÇzÒ<÷,IÚå|àªðI�ÞÝK¨€wúäy;ràŒíÛrÊv®=n[0my÷¨ó­ï±­·=›OÚñƒÕŽí¤ç[ý:ðú¯5…Xé3žßüøð#p­EÀŸzÖ æ|^þ]ù­ò¹†tYœaJÓéÞ…¹6¶4Í¥×uè$†�F ‡OÕ+µ®Ú�N+×VYÙÑ ®´·Ú`‘´<0î^6ç»Öwä�–‘WìÊtóÝGŸ·¢s{Úÿ ŒþòóWÝìà‰†+*}y¬ŒÎn3ê[•jóÅ%)Tð@CØÏipÜ�ÀSiQÀþîk›Trmñê€ �Á�!Ðuïœ�ªž)01 0Õ¿ è@GÐuÆyâ8a¿¡ý44û‰~+ †ÊÛ[mä@‰Ð+]«½à `ÍT±ÊOQ%Ê8Ö¡ ²âËJèVM±Ö_Ââ_Yš¢ØlKL:ÛÚÝ ÏnpL-ØFôµDÖì'Òëþç'#®š\Y �`ɹKdôý¡_T¤çx øãülØ+Öì«ØpiwU*ÅÛ#À2àå^ºèRø®²z§|M?¿G}œªŒ¯®Uµº¦ÆqM½,�°®ž¨Pù1,g� Æí <ì§pº]<{Ô*¾¯ë¡^ RÈ&�H€˜àÄ´)-cꢪ ®Ûq^¿! ôD|¿|MK«úß]Ó€1ÔG>Ñc?I€Ú±ŸH ƒ9 àMSõ;Dº³Ú.9L–ž`\¡^*ÝHKaEE…KG$|ܸq†ùáÇT`o ort ItÇŠ¦îiúeù½ò§[o½Õ‰q¿óÎ;†Ö“€-}eÇåÿÕäÞ~™ßÓíz5ð3òÁS§N ,Y²ÄzõêåÎ3 ‡ñ¶}ûv{öÙg�˜ºÎÿ»š 3+CgÖé¾p^it5g.ZÍéZ«ŽñsÕÅÄtL{À4€I€¹�¯”w%³K»óÍ�€?~:2>øÔ‘Ñlû¶ µêò?’ß%çm™† æÞ>ß=?OÀSžM›n½r•¢¢Çx´`™¶š—^wXì^\]mO¼\a+ÖTÛÞÃT±(Ê âmx¯’y�~ÏLüœe÷«�bâXÓ(ª­ è‚õ`y�ZåU®k0 Ã(VSÈû¾³§œ·oÞ•bÃ5Ø>pìJ¬³÷}µí“ʆ`õ:›4hðxµ5Ú÷=©bˆ>/PÊ]"à�yÙJË‚qDç-¢-­Ô‚]4R M¶Dñ�CúíøþÓuŽ9ç�ñË&ó@b¨ÒÒî¼>Å÷a\~¥¡Ë´AÀ Uãû)é� ¼,}¬§ßÖz̪í­4³æ´Ÿ`?E{ö±ý`Çh? lö˜�c‡Á*LÖˆ'u㋃–ž€uæ±1‹a µd�ܶG—EÄÚkp½eI…l«&˜·�öL9_»-Å›{Ti¯LúaÝaô_î=ô@/@åX …ÅrÒýþtÙj;W}J׃ é—fCúÃl�]²å¿¹nùmÁwªuÅ)´†zœc¶,×–Œo¿xðð(Z©RïûièС—@ ^˜¡�„–Õã`HiY4‚ˆ]ºVO0®Žr9€Ò(DÆOž<éØ<°ŸÆŒãØ\ååågº–$Ÿ&_ ¿Y~»ü>ùøÔÖȵo=´–È¿+ÿŒü:y/y(Kbâ7^—cÝšo7ÏÈ´â~‘KŒ€Ö¼}Ö¶>b¼‰æÍ# ÓKJ¯{\šN+”^·¯¼Ö1�“C SNŸQâQ?l%3¾a…ÖXjö€kJ׉Ø ÅÍ´y®¦™ó‘`uÀŒ ÿŸ/Flˆªy½µ©i¨íQúX{Á‹ö6ïf¥z-™v,Ÿ·6^n[{·ÛÚõº)Å%ôËæÌ &¿ -šƒÈwôùd¤Ý�Ô»W´¦è7ñÆ2Â+kÄv¨ú\,¸¿lKŸI·›>2h·ÍPüfÅ[Íù(8ùÚº1yRœ£wEÚ¡gTÕLHd^lÐR¸Kdº¸caÙ‡’iû¿•jsÆ…”6Úp)Ü;ˆ][ŒuIkDxFX¼© ’@AUP«¾,x�>Ú�ª¹iÿå˜ìö‚´Û6ÇÌ‹ßVg¾nxôš,ðû͘ëê˜C@î²ç…ìïO1Òyc+%Âk®‚'=%Nµ€~h*®RyôÓŽ5:rpšõï�r)]0Ùcà÷Pw�„Ç«jêÝæµn¹FC×#ÙûËuDx5ˆ8Q*]¤K•ïHÁážA²²²3öÕñ´,/â`½l�4ô£�¦¡©4XîØ\P°·F�í4­Š‹‹ f¦ã x )µ0¤c Rù Vév¯ìÉ'Ÿ´•+Wº´=-~Jþ„ürös­çë~ù2Šù¤ÛMŸ>ÝŠ¬'Òñ‹_ØÆ�9n~H™l:/§ð:…ã?*?,/“hòƒš2Ÿ¸ëæß+ßüøð#𱉀†è¾uaøÑž%ÿ”|¡| \ïÉUj>-¤´º,[8-ÓÆ M³é ðÆÀ‰øö˜h‡�_´•ΊåTmû•ZwªJ¼¨þb0�úŽ·>£o·Þ%‹,£`„*Øé�JoÃy`ìé‚â34˜�e41þ³Ç/J§á ÖQô`»æÿýJ«ƒ]Búƒjèš½_¹—"1‡bµwžyG¨ƒìÙ¦é•KwÎ'>ybÍx ŒŒ'W]´OÎO‘æSËû„IÑ_ÝÖCÉ@IDATL@3ÒßÝÖqâÑÙfÿïç"ùú?×: p€ªaAÅÚL¤æM%Áq«$~¹æ>ŠÂHºir�_ÆÙ.1|ÞpUv\ý÷‚„ؼ%klVÒz1ü‰Yh–È`qMr,¡Õbâ%Ó?*_¹¹þ žh»­�Ç6©$H*騉Œ¶–Å«`gö??‘âc+77\ÒLâ>Ù3*Ñv;zÞNyžuç5O<雉ÀM¯}ñS~ Áˆeõ›`ƒgÛ¡�¿Pªk­½³ùœ�*Pª™~¿ï3Ç?@ ÕXýž’~ Œ«œß¿Þr—¾}ü"@7Ú"C>Eéjý¶lÙbh9¦âã0Ÿ&Ožl6l°ãÇ�S�ç ä¯Ë(/_HúÐ�˜ö��h Ú>žÊm¿ùÍo\“æÍ›gÒ;2@&@)=(ކ€Ç}äÈ·Î[o½åUúã‚xUþ+ù1·±kç¿"5u‘¼7"ìœGÀDXä0V­Zå€'*ÜñQ¾BÞ¨ØSÎ5mõÍ�€?~:9z<ô­‹"0Zûùºü[ò¹rèÙ)‘HȦ�ɶ‡n)°es²mTqšåf)íGOúOí1�éèô‚4�GÓIL§½J¯«FÓ):Úè4Ö†Lÿ²RìµÞ¥·xE>‚®£�v6¢=�äºè˜|îæ•co¼â-?`K2ê$wÓâb¤ÚÜsCXÀAÃ¥}’ò«è7«/‹ ·¸‘Nøðë!bÎ ;ý O°€bÓ¾ÎðNt°‰þêK©vݰ�½ªê^ž¡áT¬ïšK¹ò–c ["GŽHóIUAë#%’Š{lÿm ‰ÃLC蜴¥DnÒïpC§IÌHÒÐY¥êf·©²ßDik¨Å×cÕ¹FrõNw F©fTiƒéÔ#E‘㇖R1s¶Å±¡³„°ûq—~ È|y/hm=¼$ìÀSÚáÙ»Ûl…˜|É0¿8FØb˜cVFÿüÈÿ\§TØ´ˆ·:õWX;èIV‘öÁŽhÆÖ€ñÛnëçÞÂæ?µ ì„ç½*\ó¯HO ¡ø–Ž·­ûL´"ë·N K”ýòŽÔ^t�ÞÓ¹j�ô‚Êw Uú|ÿ[ªè¥Á£NýØÒt ÇZwLê_a]'ôé5ÛÎ龨ÈË..~Rov¶¦]þ²×Tt¸jqÃ5û  ¢ÿþºï¨cÈH_cþÞ½{I[c¦®(Ç~Ú¨)l™žb€m!`)ïôéÓN4–Ï Aƒ\ja~~¾õíÛ×}¦ªÝ�!CŒyˆn?ñĶzõjxÒ/ŽýVˆ4TÝÝ®)[¬ÖÞ¯óØwþüù6wî\>q¤VnÞ¼Ù±ž`µ T„Ýôwr(‡Diê›?~üü7Ž@‚ÇüÿÆÑèœC¨Í>,ÿ9©v%òTô0&ŽÈ´O,.°»äØ8U°ËtÒ`-v¨e[m!ô9ô€wHBâ/½­êu�V¡éÔ”^ç�N¹€NS¿hų¾n…C:å—HLœ�b}ÆP\W¯´€ÂZä8Îî²ïÞ—bó%–O*hlú_g‰â':N4åþî«uÕ·Öîª×ù»¼Tk¯ oÍ€Dǃ¡T«>¾ÉªOîѵÐ(&nÄÆ”¤z‹$5¥Ïñ¥¡!`›÷œ·S§Ý› ý¤üMy7ž½¤Á_¨í¨Ðªâ(Ú1b ˜@û‰5˜AèI¬Ú±‚öíÛÇ<³:�Ÿšö¤‡î\eMm*U[s˜9ñð:!ã—*ùQÍXƒñõË_þÒÖ¬Yã¥ÚÀ¼*ÿ¾|µüZdt‡¶¯ÊgJË++*r.qô�üqûðÃ\«\�Ù/å?•ÞùæGÀ�€?~ÌŸ:¯ôѦ”O~‡擆Í>8Ãî[”g÷-̵I#•b—#­=’·÷M¹�´}@¦WVÙ¯UÚÊM't‚é4X SɌǬ÷°[,S SÈ�Nja�zÞ£=—�Aÿ‚‰A»]ÌØžñ–ÿ9¥@Ų3¼ïºj �û‰r,¨ÑUûg? ö樌:@ìÏ6j þË•õJ»óætî”ñ²™zU¼0 ÁÛÛìgo^žhL&´±¨À•¬¥xB\útM£¡óÓšëæ^•¼ÿâ-)Nß)V“§F@’ú„,Á"Õ+pãD°u÷Ü%ak´ˆë‘öˆ5w|È¥À�Q:�Á®0À«b¯×7Ô+¥°c*ÐZ54F÷�fRsÐS(�«þˆ`ÒÎ"Ù°§þí¥º¤ÓÙ.�N#CJ- Ù¼ !›,–×pUÃÈÛ{4qå9bOšá1©¾ÐR@ÉTXàÜ�Ukè÷#�rœ—î2ÚáõÚp\@ìÒ¥)לŽRg´5ö…¾!°þž˜`§í5ØOT¾«¯=g§ÊVX­6 vÂðt�¨¤a'¹�HÞƒhLjGNн·×!�€ ´r…€Â·�g8Çœß"ùX4)Pˆ�; ‚4-Òµá†ýTYYÉ¥ŸÛ´^Oc?©Y®2ÛMy5P¬ö÷BP}ÿþý¶mÛ6ç°~H%lZ¾|¹½úê«¶cÇDit�ž–ÿ_ù;òf x}Ósm–šöyù`¥n¾ùfCP=¶ºÇ 0'\ûk9LG€(ßüøð#àGÀ�€>uB(Ð6Gþ‡òûäãåh]ú÷Iµ»æåÙ'oɳc3¬O�z:ça>Ùçymç#èÄfÊZ?ûÖûù«§íí�è:E…ÄÝ`AŠ|iy¸ôº™�Y¥×eDA§k%½.]Ö?ÿLDeäCJ¿©¿¤D@Z@|$€­˜‘¥w¹¤"Ý=;¤êU¡7b€Ý<Ñ €¹ß¿7" ': öÚëȤzó:súè²°Ý;'Å�6kT9ϳD¬À'*”µ|ÔA @å€À§ÖTkPz^€AK%ïa>yì§l]ñ(“* 0d[Ùå+ @«¡­ÆŠÑ…°ø‚I!C“¬_þG�,®MÒ©2øÃWël•4Œ:ê\±Î=iŠ€h€Í,)ªDrLôc€ Fɲ÷#‡�sÛô�Í• ùh�n€oRœg|ßÑ,nΆªï®nJ}$mv›4Ûöi°x– mͯ×Üö:b>L»ÇTòÎYa.{Û(#M³«€§aýöº¾ Ñóòl‹ªûñ¹#€'o›ÁPDì§°UÝ`5eN°aš^œD’ŸØ˜®R$Ï‹¶vÛy»PÛ@/ä‚Ú+_/÷íãÝE»m„¦Ï�;§¾ÓèÒÑúôéãþ†-“‘‘q‰ý¤4-�ý´Sëô4ö7 )º”Q€¤bO4žŽ;f°·vîÜi[·n5t®víÚåô¬`FÉŽÊ—“jG¿¿ÖOj²«HøMH³+séÒ¥®ê_$Ño}Àémïlª¶2‰»ž=YÓ)¿ßx�N_²!b:–.±Œ¼ktb@ŒNL 0€�ðŠMõ¶f—ôi¢³»ô€¢¤­Þ"ÍŸ¦ô¨.mD3;£‚Þxiü õâ¥'5³h§Î†u˜D;bX‰v 81©ô£iw\¤3X%Ò,H„yã �%Þ`9¡¶|}½ÊÆG¿e€ŽæTKÀKÂFbÙìôF‰`TŸ‰e`?6!2�ö )f°}nœ&•†l úJD,žæŒt3ÂÙ)[µòŽ2ØO°ºkOF´FbëIÑs½îZºOyl§ÙcÃÒ Ù$1�ì¸Vb P‹T¹}b?%²ï%bw^v‚æ ´Üq�ÔºÇr¬RlºË8ö¯Üš"ðP,�ƒ]6Å/ì´O«:daŽ H,qã×jãg½¬†Ó­î\…U–­ÖõS/å�]7"Ýé�%»Uú/F¸NwéeÈ¡cîBÕ]Ý H—kª^áÛÇ4 ¤¤XæËÇ)U-³ªªÊUŠ#ýÑqÒïÐ~¢à�ª¤q×€ý$h×6ÊcIõ©û�ËŽ»Ñù!9mí«ãˆp ¤ÚyÎg�0ÜÍ·Ê ÿO9€ZÞáµµ®³qÚÕWåÃGŒ\¶l™Ó¸@<|ø°ÓµxØØôOrÄÔ»ˆo­=ùæGÀ�€?×D|ð©cNÓ Ú  ÓÃò©òÞòpNVØæ]—ã@§E3²lHQÊ¥*Q- æ´n‹vèôæ{BšNïlª±ƒ�Î]ˆ‚NÁ`Èò\gÅS�~7FÓI#vg�:ti±ýÉ| cä/Är"U'ö-?:?¤îtUë´0x:.°Iˆ=CúØÕŒd޳­ËPõ Í™÷•jã1S`Á éªôCÄÌ2ÿì¢+!èð\ xâØ©8Eåé÷†q¥�8-Aé½�.% ¦S¼¹ô;i)!h¼_}"ž1ô‰ùaU– ¹*m‰ `g½*Ä�ƒͦx»Ä~Òxš6,Ò9Yr�4�†I¬\€Ç0Ó’18'½ € @€ãœz€YKë_í;úDµÒÙ.¨�ˆº':ŽØmШb1�XÀ…6±L3X@ùú» ;šÞÉqN)¥z_Èæˆí4¸}©5ä�O°›KSÌWºhž¶°Lßqì3�gí¹WÆ[²Ã0bŸ±)£ôŸÿZ^§v%»•ö/G?Š­PyR<’ƒª~ø¯Jƒ$6�m!—°ŠC«í\‚rÇU¹®¨P‚ä­¸s�„S‚V]Soëw^ÐuÚø0±V~@îÛÇ7º“9°f¨¦Ã•b€ „ 7âã)[°Ÿ¨z×$RÍ]Sð·Ó~Ú®i+z›–î`¡ï®‘ÃdòÀ¨Ãú{¿|·œï`ž^’VuÁ•«½t¼1Vø”|©ô¬rn½õV›9s¦Óì[Ížþy£’_SºÝkZð‰p�ûæGÀ�€?~.EÀŸ.…¢M ÓZ_—ÿž|¶¼HÎH×@lrŽÒë ì–YÙ6|PŠeeDSnÚ3�âí1o‘÷ÓI Óã/UØ»�`:9ÐI;)]¢`ð +žþ5+™ö5+z³c:…S® ÐI‡àŒ2÷wÍ»A€JwUÉþø“Ã&†g¤ uûÁkºW°j`üÄV¹ò¾ïŠ)#Rì ß¼?Z%®µûÔ˜.} @¾X9Y°ß6�ûâ ˤ ¸a•Òb�[}6ÑJ1UV‰¡Öc€íØOâ4Ž�8m�”"öß[)k0žú)% °²5‹‹ªs¤å -ˆRºš À§*Gñ Zk¶Í²0.Tm̈#zJ-që+à‰t½a:v4›F¨Ì:4ºÆË'–HÏIÀÓÌÑ!W¥Ž´ºæìì…€@¥¥¦Ö;1q4ÁHKܪ”1Ï`9Áè!…µ»ìwnÙ÷î�(ZõÕUYÏ3ô¸Îu!Gç�?•¢Jz)¶GÕ3©ìè}Úc‚zó:gªs€ñ§" •{ítù:·›^y¯â­2m*¬‹-©-ûœð8…g�còUò˨¾}ì"‹I°²�(�$À&ØOh>Á~â3 ì§“'OÒ?Äï3ݵû‰·žhúõµãòòäoÊ_‘¿Øä/kJÿ@ãX®å~^ªö?&­*~!„Æ©ò‡ˆ2säoÉÉÅ÷Hã¡` ÿ¸?|‹ä£”b™>}º;à ñõ×_w ¡PÖ]F‰úüÝT§!ô:/M�#-‹ô¿®²TEï/? tZWÞ~I�jÏyÊ“NÒ41Ÿ�°ºSƃÁF&ö Œœx€b.,%*~Q­£ öºI9ºò›c? ]-½®5íáº'Í�s_,`­—ÒÞ8ïè_qŒÉZZpoŠ«^GúëbѯajÁØê c¿÷58 0RÙ3G¬ý׫ê�ÖUW´!Ñ>& Š]v×·w%Áœ{æ�z[·»k®y~#N 9ö1ò Í6ÚÓ©;- ôm’œÏ~ßj*9iÄ 4Ô¯u©w\ dñ0®ÙqÎÎ�oàÙƒƒÛ!ßÜ�Çèï»K"8#(ÛUýí h�VPII‰åçç_Ò~¢%T�#Oû‰´=úG4ïSøÖå =ÂðŸ0`À€ð=÷ÜãDãa=QÙïé§Ÿv‚ñ”wk™¿–“†ØSÁB5Í7?~üøèÎøàSòÑ¿A‹þ¡üa9ºNTµ öÎ�زóì¡[òmƸtë•RŠ�ÝÛ9f@ÏÖÇŠugí?Ÿ;e¿}ÿŒí;Ô$$ÎŽa:5�NÅ3Ûi�¥f:‰ÒàöÝÎh]e ¶a÷P9Šô ®6ö°2E•ºžh¸bÀðÐ��Bµ4€‡wÕ»JdÝÑúâªöuH)@T#ë(sšOÃBh‰ß&:[»•v´I)}¤9„A °ç#¦yÄèŒ6 ØÛ›ª»}ôuêtȤ�åµ°4"}®VÛ`Ê}�öÓç®f,—%&ÚK°®HÅã¸îNFêú1AéP…�x8•1À€(Îg/i,!’žL[®ÖÖæ¾§½,ïn­wÀ ·,¨X=#o~WM9æ?}(Å&HýÐɆ+DÐ;²ï\íx]ÿü³).qùºz'Ï:ô“öþ†\mßñßsž¸_Á@Sê]@~þL™U|W«H,_qæ¥qÇo%ñgâíÒÆµþ¾ÃíÀ—‘çåëòn¾Ó&n·?·Ã" ; Ÿî£éX±dÒ  ��‘†WYYi{÷îµ .03[~P¾Eî÷¡Œ®÷J›«Ï‚ ìÆot¢ñTù{öÙgmÍš5œ+ÎïOå¿‘WÈ}ó#àGÀ�€? #àƒO ÃrÅÌÁúô ùwä7È‹äᬌ°-˜škŸ^Z` §eÚ€Þa‹ˆ­À`SÿÚlhÈ0L\³ý‚ýXL§çVž¶ûÏkPç!¾`à41�³ ‰÷*žgiÙ£ “Ûk{öÞæf'µbŽˆôŸ”ô´J'ŠÑPÚ©;„ˆ»x‚©›ÆtFiI°B^We´Ö°K’:ð$¢zÛ}sÀâÙÊÍõN С+ ÆÍ§tžH÷òâìûE¥Hqž:ÒÐ BG€%ÞXH¢° Îêøtõ�Dì']®*lôy’;�ß_sŸèè�Á~"…¨9¨bÿˆkï{-,-›å[4ØÎÃQЈtȘ�WØ Q‰Òû÷Š2¡h @Ç9b°÷bû ì™SÕ�ö£×ê.�GÖáX~*«uLŠ?Û†=ÖшqªªQ¥S§óˆ8~wi‘±À mÜ|}}Ãó;³�Üw諱 F@ú©Ø]woX`þ™×Öî¾|žèWé>Õ_¬²“{_·Ú çÔgƒvÝè U›ŒþÞ%/ÀÔ�úûé*1ËÄ~’=LvFšúO¾}¼# W¦;Ÿ��—(µÎ¥n¡ýTXXèØOTÀ“ µ}úDî¾ûn+--Õ³nÄ6nÜèXOG�Õý̱žþ¯–ƒ¥å›?~üøH�Nr$Üϵ8—ß‘ÿ±|™¼DžQÕžã³íÓ·æÛ­7dÛ°�)–‘®Ñ¡¬½…–kµyìv¬µ'^9m¿x¥"ª¯qæòÀ1§÷(�N�XÉÌo¨zÝB1�èažfbÝ5l‰î=™ÿä~Gi@Ã5€Èè�g�$ß{ ¢rðÁ+ô’{š4ÉKg,ó€Òþ�qz«‰©Â~º:Nò©ˆÍRzV£m?x¹_uF;¨f8JÕä†JÓ)ÞêD¨TAÇ~ˆJ–ÀÜ`@ 0³OúX) ïØKm€ su±7chD­–ÀùËÖ li´¸lÜÛèØ[Û$¨½J`+ú]‡O©Þ¼H€iÄ¡%Šï"ZŽêsè_•4U££êlX^€Eì§¼¼<Ç~JM�>Ëdgg¬ØOšòŒÊò'ä›ä¤áùÖuX¤]=$/š3gNছnrçëüùóöÔSOÙÚµkMsÀõô´Üg=)¾ùð#àGÀ�@óðÁ§Ä±™©Ù%L>Zît�& ϲ¯ÞShŸ¸9ÏFIu6„2Û:…õ&1ñ½‡jíÇ/TÚž>ak¶ÖØÉÓuE‡#YC­ôúoÚˆùf½‡Ý*ЩŸÒî”^ç¬;‡,MMhfÒ;7ª—ã¥� SDjÔOU²¼\ïî0˜_¸9ìtt8ïª�g¢c@ñbÃ÷{�6ØU}ûõʺvé(%ÚWsó5âÛQ!¶Ì…‹�öÊé'uò£>ÀK©*¼�o¤¯’nöŒ´®8O&0v`PPa/‘ÎÇ’«ô4•=å�N¯)~»mùÌ5¨Ã¾'‡4O¼³2¥&¦Ü�1Fê&íwÇ i�b ; �3@ ®b t±'[2B©(enˆ*וŠí qÚ¸QL«c ï’0¢§£iа€`m‘î‹ÞTK쮫mšãÜs¤Aý§ÞVlnT¡„î½G³O/ »Æ—z'ã®vLñ=À÷ÍJƒHEü½» °r¡RyaÆyV!܆=õö“åj\œQ¥.J± U‡ìÔ�Õ.~9™a›2*ͱ¸âoñ#ý Ãò“õ¶]Œ^ˆƒ`]{MÞÉwíÁ·îŽü]PÃä#1 ŠŠŠlàÀ�®m°j¤Ð}Ú·oŒ(*åÁ€Ú+ßéòÿëŠúÁøŸ ëéÁ´áÇ;Ö Ó“O>i°ždkåÍ ¡âûoó™§~lÿL~�Ð)Ð;/ÕZÚ˾#߯§:‚æ·Ëè¤QÑ�NO¼|Ú~ðÔI[·½Æ*•’à ŽÒ²ûXñ´/Ùˆn}†/µH¦d¦ w42@íÙ¿ñ÷Î Ùÿó`Dbéf±oùab0Ðé*›12( ç2ûƒré0Oþýeª´uU+®Ü§ðK·„í±;R –ƒu fÑ[”¶GÀ;º¥èÿ ô¨žPQ$€‚ jTŒ£:ì™É¥Aûêm)vÛô�Õˆ±ÓKŒÀX9TÑëlà‰V’fJÊÝD1Ñ b�Ï|cˆ46Œ43ÒÅ rT6©0±þ€Bæ€hA±_ìö“ù;OÞ±J ôœ8‚ù4PmŽo/ÛKQüÒ4¸?¤åÑÇjɸÎÿF8þ€ôuù›sEJÞÕŒýVÁ† ÛyXª¼RÐáš#NÉ€çy¿Ú°ß±±\;è“G2i�Þ~ˆ3}x�˜jÏ7 õW«_u¥qmÍŸt)´Þ}”ëœÔǾZ—”VVG´—¿ÙÒÜŠ §/nóí—+> ðtÄ>“ÝÆÿþBÄn›VJkÃE Ž�nf êgA±Ÿ.ÖØ‰}Ë­VéR¤ÏM™.Ñz ’·æsM U>{^i˜[ÏZ]]#=$n½|o3-ðg¼"<®WS6AžSUUåÒïHçÊÉÉlrÚO¼ØC|üÔ©Sê5ÖKΓÃ&ys=U_ùÖ�¸YÛzH^4oÞ<Çzâüx¬§õë×£õÄSÔ?Ë_‘ëÌ7?~üøð#Ðr4dñMà ϧå)¿MÞûÿgï=àã8¯sïƒ-¨@`¯ Á.öNŠb‘D5ªK–lÙr‰å—äæ&v|¯?—ëä¦ý’8ÕM×±cDzåHV£*IQ%Qlbï½° ã{þïrˆárì €"çH/;;å�3ïÌÎyæ9ÏQ“fÈfK×éËÛ¬ñyV�§€S_´ÔX×�¶î©²Ÿ/8i�ÿþ¸­ÓéD9�Qì)>3+ßz�zІÝô—ÖkäÖUÐÓén|@'Ï7×+u‹ÔÒÙ:¾voÔ>9/j§¤çäOHðŸŽèÁÚý3ÂÚ¦ô|”Œ@_0ghŸ èL²Éª&7QÓ eaWè¶1¥6¢XL«�«z6H•äHgƒQÔ¥SÈùç¬D/€OGÿm° ›D—' ;\5~™� �ÑÃ9yá±ßÑ/@ >%ŽÁ¿ŽÊ ÿĹ>"vOK¬XïÚòµ,�a{A,9Lh5Öâ‘oìÀF)%Ò{JŽy…�ÊvéXÙ8¾¥Àq.ñOsÆ>ܯcŽ9�0˜bSúé61Æ&*D¸e>)˜§$ü!‚HÆu`‹ À’ q/ê\¡›¶A€a[¤i6ç‹ÿ©´ÞÏŽŠaY/вá¼Q?[B6·_ÿ÷øæG_ÍrbïoKhݶ§S‹Ì¿ÏTþf|À\ª¾5 8]²ARB©zWgåÞµ3'v©¨F† è•ce½S¯z'\E}DnýÕFH|<Á~:qâ„m߾ݪ««…»êw»5]¯Œ9¡ ¶ZOӥǕýàƒÚ�!CŒÔÈÍ›7»”;4¹ô;·VËü‹ÚVµàœÈ �<x ð@Ó¸ÖÁ§ÎrÏÃj¡öQµjHùf î—kŸ½·Ä><¯Ðút‹º`+¥7¼Úˆg‡¤Ô ºÚ¼»Ê~ñÂIûé3ÇÓé¸4�<Ð)šÕÉz ¿Ë†Üø]ë;îÓ–Ûe Kw¸ÒA'R£nv‚¹Þ1{©Goø4V¼ïÚkJP]ÿ�-ÛTë‚ãöÚoü~ðî&¶Œ?%ÀVédëP´Ö_€}£KC6óº°kS†… 3J)bhlÁäa9@*§ÁŠb]l›’ Õäö4ë.6MH_Pz¾­b7iì$J»Ã/€LëwÕ*…­ÁKœW€˜HÅââ8â  €ã”ˆ;)ž¤•¥j÷�L« æ°oÀ'‚oÀºD %ØcQ�ATNô[Éì›´ÂÃ�HÅ#ެ[ªÝ%:¾DÛó@@9Rž¨sþK´lcó¸ÇÁ<$ài«ÄÑG·¨mÚ‹`z½c‘’9V&` B|³bK�‡¥Æ8o/ 'þ8^‡¹··æYüºéúŒ©$X¥— +å8M×ö“ÝÚgšq ,Î�gÜ{^ã29à)¶–K½ËˆØyU½#õŽó[Ð)"áñœ„ @o_‰¦¤®"²~øD�­Û&$Sx­€Äëj°b»ú={‰çÏjÝÐxªªªr©w=zôpà=âã´={öxâã°¥ÈÕ\¾—¦�µ�¦i³�©õ›1cFƼyó¬°°О}öY[¾|¹I0žköqµj€‰�<x ð@à�f=p­‚O~ÐéQyi°ozB]»dÙƒ7W~ö¾.‘1Côð£ RÏÙ-2‚z@§éÀ¬Ýªêu�þãÙc¶zó9;ètAÓ)3»ÀzŽ¸Ç†Îù¶õ�ð˜u*a¡(RÕ-Ý{‹ºœòJhÍüÛ—³lŠØ5ñoùÛ#m‹tϲ;§„í�M AÖ~±HžUúÁVGÙ1Žþæ±L—憎g¤;­µL½¢` —yãÅpƒV )Y�i5¶_Æ,¬›^E± tÙ™1¶K:úšhŸîÌ蟮ƒ±Ãx¿ÔЦ‰?‡5°pHo"�À'ÞH�+.œ‚�cÅ/ã}&uíS·DÜÕæŒÐæY,ñw?‹ˆ}Ÿ¯ª—UÈãÍ»îku}SíŽåS1Ž™>”‰�xJª*:=h15gìñò^Ò#e‘íøûÞÜúþï= �ë‹ÔYÀ 'NÕ¿=WãR"©yLà`]Kzÿ~“ù½/ÒEïšqïÞ:0ÝžK-]lBo»�MIË|dnÄ]s~¦€Ü+ª ÙQÀýí¢¾}ý¡¨ érú[€Š-6�ïKRï*¨T–ac‡äX—‚–¤ÞI M¤§•+Å&¼(<¾Cý[Óâ>+~�<À5Ê�ÝÕF‹A“ Ë ½'Òï‡=JšUñ|âã%Z–ãDwœÀÚÀ€ÁŸS›-À)— wÆ s¬'4¸ž|òIW�Pçg“–ù�Ó†/},ð@à�À�4æ�![c‹^ó¥cRûK5@'D/Ñu u.ˆÚí3ºHP¼ÈæLÈ­è’¯4 Åî-�-I½�°B×�‹åôŸ ŽÛûÛ:IÓÉÏÊ-²>×}HšNß±¾c?my%Ã:‰ªÁÚ+ŠÓÁ·ÆH_#åg§†y»NàÜÞ–£G¥ï}œjVa1 j�î�ׇŽb`xû‡qs³D†ICzWA;éMé2@•É›îT>]©a(.é0�EÓW¢Ö¤�XÖöP|_`g=&½+@BÀ àh€$ÒÆâ�ñ¸�fO¼‘ÖuZĉ€�¸lâ fÛ¤:"Ném‰lö˜°=<+ê¶+ijÆ.C¥PF½�Têbcì'Àt”Z’jŸ�*öÚH1×{–©jûtázãü4fø ª» vØaô�{QKì�ï�ÚWý÷½Û¦B[{�ˉú ÷¿>’©ôÒ�* êš÷õ-Ñòm5¯¬w†´Û2Pøû·k/^߉GY[õ"¶Ý.ú%ãšòî1g6Á|bI�Ò([»o®¯�ÀYi‚í]ngOzUïr$zŸbê�ºó °yçþ*ÛsÈýhèŒ4¨WÔ\.ž¦�]ÝЯŠ‰V ô;CÿIâÖ6`À�•ˆFuðàA§ÿ$À#WËê—϶©mW ,ý«M~Qmà¤I“2î¸ã+**r`à‚ ì­·Þr"ñúþ×jϨé—5°À�<�œÒª&·³\ŠJ)ªý…Ú'ÕxØt w)È´Û¦wVŠ]‘Ý:µ“u/ŽÀ�ºj½TC2²&o}tÒ£óÛëÏÛ�¥çô_�6ï>oåg„¥³;uµ>£U9dÎw¬ÏØOX^ÑàÓ‰ 4í&ß�6[F :J€þt1Ñöž+`üxºMØÂKÖÕJì¸ãJ–SÒý³·GmƒD…½T5‚AÄ——nH/ðT¬¹»§EìA¥Õ Ž?Òm G@ WUMéa¾´fˆþ�¢6¾,ìôƒ<¦H¦ÀXD¤Æ©h ‘¾ä�ooúqZéw°]z |"U0‘qM¢ƒÅø|by+~Qn4‹1¥FÓ¨9‚QT,8�¬xó|Gú×c´)ë$Ì™t1´‰<ÛqÐ}Z Ææ}µJo«·U¢Ð†"…—càØû‡ÁÆq„�:ÇXLÕ†© ! ,DúýÕÑRÝNk—<äóüÈX€ùP¸vgûA=è€y×6ÇDeAa(ö3�ÄÞ;Êîš¶o=’骉”óŒ¿�úÆ”7¿%SÀ'Ó¹[íä¾åî¸KºdÚ8±ŸR5|†hy¹®ßU›Î 0«÷î`+µ­½©n/Xþéê5¥QjT¾CïiàÀ�V\\¬q‘P|¼«–±\§–¦Ñ­-†ˆ >¡6////ÿ�°‘#G:Ö ¬'Xh:/‡´ÌÔ` µðÕ†Ö ,ð@à�À�®9\íà ÓjßWû”ÚPµ‹ Óí3b Ó-�zwèD §Ç!=û„$ˆZ—‘Q_£÷½ÞC±VMlz¤×Á.xG ÓŸ>nO¼|¶íQኆG^ç¾ÖoÜ'mÈœÿO‚âµÒvúøMŸ”’Å[þŽ°Éª^÷Är"µˆÔÏH @h»¼oÚoú™Û¢vè°;�TüòÌc"xŸ[;x"åè– a'zÍðiÎ^ EkˆñJ«SZ(ÛhŒM€ÒYúI0ˆÊ̠畬ªøY7ˆSï;VgÏ+5Ê“`AÀ^;ðò rô �&bÚÀ"€0BÏ*‘q EçИúô­{í½Zƒ‚qŽV²�$€§Ø±ã"P‚Í)ÞÐ]bî¥ >Ù¸Ï`mýP©«ÓÄ^C̉9<ÖÍ|†}¶÷(W…B¥&>§/œSÒ†‹òCî¼QU¯©Û̈~¡ïwi…6tŸžÑµþ¾O¼;þ8ÛúóÌ‘!ûþ'2ݱø‹†‘ZÛ^ö‰›#ögŠºâÞya߀‹~=·öê�?Œ�9bïq}ùõ�üË´öoÆ:cªúìQU½{Õj¤ÿ’“¶ #r,O÷ã”΄¶ƒn?¸k¶U©Ê«~jc—ËAMßhm_ƒõ?0¸ŒlÔ†‹Ù‚ý„Ø8éw¤á1îºtéb§N�râãÒ† íŠÂÀç[¯Æ6K�Jµ™/« ;vlhþüù„…öúë¯Û¢E‹ qx:O¿V„ ,ð@à�À�$í~įFãMÚ|µOªMR#ÝÎ�H…ùQ›=!ßn›ÖÉÊúdê�ލõ¥?(ão=ï c¬ZOûIadb°B0|Ùûçíéŧm¥*×�•£'"ÎZ]‡Z/¥×uz·§A–kœ§xžÖý;N¼‹›;¼oÆ%"âëvÖÛ~_mo¬¯í°nŸsðe¸‚äŽ6€?Xñ_‹k\•±ß½ÙvÏÂh9Ý!àiž€'¡D s®R`œ´®(=¦Q Cˆ€ Æ&C�Uz"Õˆ”Ë…yñÛl VwNᘛ¯`Èö¨<pôg?å%uÌÔ×ìð>Ŧ•êà €b~£/GGÃÈðû—a=¶ûû·«í!¥Î!œžÈHY*&ÕäX‚”­Ã§@ÂDë45_n;P'`�M~9ŽOßaF�¨¶^l¸Æ@H˜XC€h¤7•BÆí‚þã×c§ëÄj©±® ¥Dx×[¾¨d?‚'2X{ýé,W%n٦ʋìÿøN´^{Ìc #ˆßWàwGç‡s CmÕ¶öé û£aÞø�y:uxÈžz«áÀÛëìs?¨rÌÄØÒéÿ ž iæ• ±Ü¾V~d³í?Ra;÷V[בÙVwAÃ0™=3Ž„{•DmtY¶íÜçPß"­;]­›ÀB`W¿4œfÐóš’î5í'€ŽÒÒR›£6Mí"èTÐ)j³Æw²[§åÛ�~™zcK°cðôo<óëQ[¡ �Ó³O§xŒˆç ½¹Ý°½Ê~»ð¤½½æŒ‚r•cW%(Ï º�´>c±nCî´œÂ~ª\Gd­-³Hü½•®�é7?uõÿú�*Ç:ñºµ`ECÀãÍk«)©6sF‡KÆÛi$ü£ÊKʨ{ßµ×”t'€•U°ûÜ?V]¬ìµKeêúRÛO�Ån˜7>d·HX<𓈔,QRÿŽ tr '�3ˆÛ8y¬ÿð X³#Éc߬m£E Z¼@‘w»À¯C‹33/ªëÁ´Â_M /“ÂÆò§ÎÖ'ÕÎÕ8€Õäg“Åï÷¬À¶ {‰×øÄ:¤neVÞ¼¿ÖÎ #°÷û"~»M}f=„¶—I¿Šêo‰|–—MÚZ¬´=)%º#=p}Ä–À]ï«tøõǫܹjjþïØw¹@ÀUÛbrÏŠ4 @qÞú #†Vcà,¢¥j]j]ãgÕ߃¶ù›±3í·o4Üg`5~áŸ*5¶Û¯gTð,=§W%îÅ ¨¢×ê-—ê”ëæP�^™.3~¹·äç 4ßú²ïOK3�åßèéO±k�ê~’ö·ìü~VØc¼ŸN�©³õ;+Ä~B†'5ãlæw …=^]æ¥ w�25^=§صáýJØBµ‰jý”Ò•³yóf{å•W¬W¯^Ö¿C &Ôܹsmÿþý&ákÝÕl²Ú#jºó;J“ÀZá�­;O­{©€¿Ñ£G»jƒ°žV¯^m[¶l±ÊJG^®eh€P�<x ð@à�”+Î4Ý Ô*R€V·O [¾Ž/Þzf\̲ß,‰¥Î‘=ÃgÀ!d"Eì›?«²�J…l®HÑ~O¤Û”'°fàŽ§·ÃuHê% +´œ˜ö. ÙÍ ¨Á½ÂöáY:‡9ÒãÚXÛb¡|t°¨Ä·] ¨‘ªLo?€pýºÅô¦Vˆ'…õ›?#æŠ aKŒý¯“ûÓ™µV &ÚW‰Œ{©Yø &ÖÇoŒØ/^«q©†ÞòßûU ;ám Ó¿üT¦Ó©b,¼% Ç³ö¸Æ¼}ÁVû§/f*à%ݳòbJ稥Àã€k€‰ëŠ¿‹”Î=À©X­ ·ÞrVfëCÃ�âˆrsFùu¡Pãÿ¼ŒGÅØcÌï;cÂy}oÛ)½PQƒÜÎVØg’xÿwŒªíýívüt­)Ôcg%Ó®{ŽqPoÝç{gÛº­gY­»Ú,5˜ ¤>vU{`¿Žî)5´Ÿf+µÎV¬XáØO%%%–››ëPS¦L±={ö8ŽÒ¿x:áeã&µW „¯å„VØt­;R`Sö„ ¬wïÞ’¢ˆ¸tÇ·$2~ô¨ò½õ¨ ö¬Ú5n�<x ð@à�”< G¿¼õ×|CíÛj¼9x çdElΤûÜ}Å6f¾õíuô)ÿZªââãzòÉ"€C7çµgí¿>fKV•Û =t×\ˆ‘ º±AÓ¿fƒgýoë:ðfËÌ+Vô€‹½ðA^�6cDÈ&†Ñàj„ŽãKÜ·g÷ ”;UšJEjë>M"ö�v‚Þ†—ø±°F@�›Õ¦ÿ¸Žàó©y§ñãßÁ`ÓSKkì±Ò(1OIuRïR5§Ÿ¤c„Ñ„7 ‚ãñ–¥ë1köEºÜæGìã7ëDÉÄöŒêhÉö#¬Ô?ÒÃ¥�Á2„EzºO~3¯ Ûü)a»y\Ä&hìS ]�O�H–MÂØ&`L?1ª`V:Ó–JbÕËá ]§ÊwŒÙxãRXDÅCFT%ûùkµúâ—lÙgÀ=@?úAJX"ý)ÀHª-–™®ë� Œ÷âµ ç«e{OïZdnq�ˆ�ÙQBÈ¥`cº[ç�–I1ÌÑu‡?@©×8¯Œo®=î ý»‡Ý5 ˆ@ßț̱'³L†Òp¬¶ÚŽï^bçÏwU‡ôËq¿±É^ïÞ~®ØŽêΚ-º¸c/y”KÔŽ3#°kÂÅN?ˆ’‘j�aÙTTT8ö (,;;Ûé?„ìÞ½›—ˆH,èAË�![4e;�¥îüøµ=zôÈBhÆÕ×®]kÏ?ÿ¼>|˜­¾«ö¯j;Ô_Ë �<x ð@jÐSäÖàù?ªöwj·ªuUÓ‹=Ü�ηÏ?Pl÷Ì.°þ=3]ª�¾k‘é¹8 gÔé¹v㮪ȿý1ñã¶ïpåÅ»ÜÂ>6pê—$$þm+t«EóÄ^t’Hð•þûÌÛóÿ+¶�ÐKï60@ü)Z-r\ +ÁxdNÄy}öŒ [¤½t$ðôà̰}õÞLÇ*!åÆ3‚ýö ö`Güù‡3]pêíŸ)º?«¶×ٯרÜ|½«ä–jðçßȲÝ#•˜¡À˜à×o( ´V Ü‘Sõ6J)]‹×Ô¶˜ÆS,Œ� eaiLø÷Ö@¤?h}QåoÒа êréI0£Ô”R1(T„#͉Êe¤Æ¥j\+h¿�rÀ@üúkç•0‡oañ¥ xòö…þç ¬0ϧ›öÖÛóËjHv\Çù³Wj.¦az˶הªq�)}Œ¤-zFŠÝ’uí<Ö}垨—aéyàM…ÅT�'Ò:ÑF›+ñï;§èˆÒ†aš0õÖ½�xRfwŒ[À]®/Æb"àÒë�ÊrŒw¶HF5BRõ»óп|kÿ† ÖI¿¶Œ]^¤„T V=¶³Ç6ÙéCë\Z�µqÃZ@“Õ±pü5Ò_µ©ÂÎUÔr3xw«èvíxꥸ|ÖSí:KÄ­@H¹+((³®Îé?åääØÞ½{íÈ‘#Œ=p)4Æ€:¤i`©{`¼Vù¬Zÿn¸!cîܹ–ŸŸ¯ë²Æž}öY[µj)wܨÿCí%µ3j�<x ð@à�”=楼~G­0N;þ[µÏ©õWˆ²óì3÷–ØGæu¶�ˆ‰ó8Ò ã!1æ#§ê"¿xádí�ž:Y¿íœ�Uê\qJ4+×úJÓiøÍi݇ßk™¹Ý¥ëteƒN.È‘O¼0‹ ˜7í ×H'Ḩւ-q7 ”?‘†zB°wR øZ²ÏdסzL‘7ÄÄ €ï+”Æ Ø }Ë3R½~öJµmH[#�æUV#H.ÈÃÄÖ‹ICÐN•¶Ö¤Fq<\¯£JÃ.)þX2µ?Ø!CÄpê­€›À=¤Š_'™Ï@�.øW*Ç*ÜMÚa*Æ5è0H •ëâ P v$ãm«¶2Øj¤aí£œºA51Ž�ý?þrõÅë_£Ä´£ @õ«}[ÏIK ð¬#Œëêþëc"õ/®J×BãüQ €J”ãÅÆëßM••NSÉL:'ñ×Q wçVs¿OÚ/ iœ€¨NJÀ1¿Oé°”êû—ŸÌt ™—éªÞéåJmÅ U½{M€g�»Ç Îs+œò¾a>Ñv¬±]Ü� ö é=¯¨¥ùΖ¯ÛhCˆ/ëª× Ö´/àUî¨~WZZê€(Æ_QQ‘F¤ýdgÏžå9À @d�Zš8¥ÚÒµaú…°�«Ý,a÷N÷ÝwŸ :TÅx² ÿþ÷ÿ·úîÒ2?PÛ Ö�¿Ú{`�<ð�õÀ |â¡ô15€§)jùj¡®]²ì#·Ûc÷Ù¨²,—²@Øšço˜ ¤Ë¼ª»ø¯co¬*�œ<ÝÀèZ:Ë†ÞøÖoÂg-»³ÄÄCŠœµf¯6ÑF“éª�ô­�F]U­¾·ü°�`´ðÔU‰‘›ÞþH¥"¥í?¥Asàx|›�#Ý¢ÏÝóâÒr÷¤¶ðDšá}3bi:ï\й"¸DOF‹gŒoÉ­8éÝm Äì1 ÎéÜ” ¤~#ð%uÇÁ:—~çÿ®¥h‘ê×OA{¼š’Š˜Â¾“1Ž6"Û¬‰ÒÑØÛ<èZc��vˆ�x*Vªô½îž˜6Ö¿#JÑlLð;•}5¶,Ç Eÿ—Vˆ¹ƒT8\o‹ÄJ;¨ÔÂŽ2€C˜3Þ5OåERV¹¦]™�Œ/?;À´B¬´½XÓ",–þ–a·MŒØ]J…ý� ó Я=ŒñÆØF‡&+ŒDÈt€‹¤k΃‹Ô^Ø`ž…¤ åäÞ¥VQ~Xc^ûî–íŠyxçØ[¶¹©p'Ç,?_gïn<¯~×ó;�­VÛáþ þ¹V<À�—ü.žíF«å�;wÎ�µ~ýúY÷îÝÝß#P'Ož´;v HÎ HÒïöªmTk¬úX“è«oÑK1f̘ðí·ßî|Ë‹/¶7ßFðã–@IDAT|ÓΜqD§'5ë¿Õ:ð)�^x ð@à�Àd|�À'Þlý•Ú—Õz«E"zºŸ;¹Ð¾üP±ÍŸg…y!—¾�Zب-ùÌ¢z�ß}°Úþ])v¿\pÜö“b§rðX~×Á6ø†oØ ™î*þ„Tzúƒ�^G߇ôÉpZ/ò¯w�Ö ilßT Ù ½ßðòŒ`ùD¹ÿð®¨yŽˆ�âï›×Çö˜æéÿ íÖ9Šéʼ£kä^À û‡ªimÁcû}“îo¹»�¤P é H­>ï8ã÷ÙÜgnØh,­•^Œ¬×•ÆØ�è7àUc�€ðs'eíPjÚ¢Éé¢ß}4Ó±±êyg%ØGXöy•- õÐ.ÝFßo‘H<ýPÌEhù¦Zû훵NÓ*ÝûLv{�JÜüOÅlDl‹ïš'ý/Y'»¯¦–ƒÁóñ›"ö†Æƒ—ö`ã3Uæã&âܱ�Å1 §žE Omª¯-ù°‹b0ët`h²¥’LEÄ�Í�Øj¥òzÀ€áóËk^úcy`®ÑˆUžÞe'÷­³¯^ ¯°Mž#=ªÆ¯±ÆŽ‹ëkݶJ‰—ëÆ¢[�šxˆ® ZÃßvµ{Ö›îà(2\Œ›Pyy¹c?•••9FÀg§N�\jÕïÔtEjšÙ¢†€y`Éyà6-ö ÒKžÆ�ï´µ`œ=õÔSFåA�{¨�ÿ£Ú*5w�jXà�À�HÙ<à}l„:ùµÛÕ Ô2xËúÙ»Ú#ó ­w·¨{ËÜÚ'TØN<¬/xûŒØNGõöŒªùÄRì²r»Ø€IŸÛéûŸg‘l½˜#!z¹ &Çø²�í'ç‚”îPªÖ/µAôëí¤™)•�®v�Ñ{ r:ÊÖ~öª§Ñ#¯¨b\{�V€À@/HD*WÒÀÓKk/–Q'e‹xP†Ï6¦ö­Sk8ÏÞ÷­™"@ÿWª6Èùˆ›08ìúéß& )wˆ2§Ã8Vµ/ÎO²Æ¹‚¡ñ¾@„WWÕÆ‚e�«Ë¥%´u�K£ãÜž:[ïX)¤|5f¤GÀÃÆØ¼/9 ÑõëG†lýnØ&ÖÝ—éí‡s À�P½Ÿyã}ßÚ)•¿&m²²žö¬ÒØ<«Ô>Ûk,{ûŒŸæiŒO¶-ò'@iGÙ`UBì!€ázÿ}1Õþ Ôνÿú°Ý á{ª,Âtj)`ÊùáZª8 ‡Æýƒm€t@©¿Œo/}¯©þ2Îß°¯‡a¸&ËDúÖ#™C»ëÄÏôLÌéú…£Ò?oÇw.´ªJjrdØðÒë^IyÌq/´:t¢FÕóê+/;öÊšL‹¦NúÕù”F‘«–(N¥­U Òïœwšü'Oß~^mJß¾}³î½÷^'ðŽÎÖòåËíÅ_´cÇŽ±�Õ~©v��<x ð@à�–z …¯¥»hõz<|üDmªšx!6kB¡}í‘®6ux¶c´6œá��ßm{ªì_{Ü~óÊ ;t¬ê" Ð}ð<~ËßXïQµ¬N"`±Â,&Nàþïd)$|Ù[þ=i)š:»ýÄÖ¹Q¥åaxÆþ®®sJÞ¼öž"2ü·�eÙuYGÐÜ3@Øí¬ß,ß|OŒXþ °Ç_Ò]/y�fÌPÏÝTzF° c BÏå@[Áû¾5S¯û•þGлQZE“%ðU (Ã_é%…Ÿ`ùA¶ÆŽÀŽñô–Ò�`8<­Ý ØÑm‚ýÃ2œO@Æý a ê Îa­4�ÂT¨GrØRïþñ€0ÿWš€}�Ü?'vÈFͬ#E2~Û|‚Q¨ÐZ#X÷÷ �¢´G†ªÖ¦eû-íß°¾6O•Ý8žÑ7ЬØÒ0Ïû®-¦ø0øuÈHyüÝ[-÷·}*2Þ95âÄćHã ‘|æ7e\Ÿ\Ïœû½òº`œ;*T¢£´tC­QÌ]9ØŽ®¿¥yË7+ M)Ñ´÷¶ëÞ¤ŒgÆoS >€Sªâ DE„~¿€×DÆõì¦H5åzç\ÅÄÅ­åÍÓõ£TsPåß³³'vi@Jù¹K¦�.˾dlzk49UŸ~ºVn¨°Êª:¼JÛ£¶²Éuƒ/¯Fðà z€Úhµ0âãyyyN|œ) éw0£¶oßnÕÕÕ¤ßéÍ i@ÚfµÄƒ__æ<0Qÿ~Z­ÿ¬Y³2fΜé„ÝÏŸ?ïXOëÖ­3Ôý'µ¥jº›x ð@à�À�Zî=î]±V¢žý™Ú|µAj‘,Ñú¹µÈ˜Shˆ0óTáÀô1%#HAPüäÙ:{þ­Óö»WOÙ¡ã Uìr z[éÔ/ túˆEsÕVhíNSêaË&@Y¦t¼³ ¡w€ek¿û™LÇxO©F€çˬt@×Aÿâ`14h¥§—{ŪJ•­t¶ãgTWZ` K «vy“;ALzT饋ѽû«u]ºTÓŸZ'–Ô^\â>÷ƒ*Çš"ÖJ¢ëŒÀvEº ��s¨SDø�ÀØH'ƒE³vg­˜M±*o§ÎQé-Á fÑÿr-óîÖZ]ïõv[yØfеC0Þ¸ÌaŽÜ4®Þiç ªîÙܱ!éú„íÞéõö¯Ï5<Û?+í ØRgÀ#Ôoœ÷î].Ÿ¿\sŸï™¶gFìϯº¨·Å¹øÞ¯šp@sMÃ÷9‹€©ŒéeNü©«í™R CðëeºqòֆʋcÔ [r¨ŒÄîïžv 5ç—qÒ˜qæ>G5H@/˜‰ç4.`8‘z|T ÐË«ê(Jª&ãšsÈ”±½edTUâËû»ë\å¼FIÔ|PHUï÷€{ ÚisdžmëUÁóUqìV(ªÃü¨{¾ù³†1Cu?ZrVìüžV4`–Ýõ†RëlÍ–óvë´|+Ò}Žë9Yãxy4°—RŽdÙ²u®_T°½Qí7j0a»¶<°W‡ûšÚtµ‘"ï¼óŽ 6ÌfÏž­ñÇ«³ââbS…6>-[¶Œ«’–<7®QÛ¦Xbè.a7©õ‘Ðxévš*Õ>l»wï¶�7"æÎšÔÞUÓSK`�<x uHzµnƒiZ›ˆo¨=¦¦Ð˜"röé»KìÁ õ�š|*�Ö½ÌxÐ%Xºî¼ýúå¶vË9½õ�¥Ø…Tɧçð{¬tÚW­ ÛX-|á ?>"¸lËí?ƒØw©ôü äTŠóìÇÐM'0àm7Ù)oûI£-)_Ÿì~š[�‰ T/ëm¾§óÀñµVµ*õ¦¹ýú¿'= Ãî»>âÆZJ°AèÓçP™Sæ"Ât~¦c@ FÎÎC çß¿ÿæþþæÃ™6Bl�SJR ò˜g0&Р*Ì«W¿½¹ SìÓÒWJ—q,5ÒVC†c¼À-ß,†“Ò"’F§þ¢£”J�KZ#ÀU¥üIÿoTpžèؘ7°' “@B�^¼_/®ué™Ïˆio\oG¤Rs@ç)_újñ[¥›4­8©ô9~;=`‘HÊ×.lÀâ—k�Ïþc¡ââoߨqc¼=f˜>7ž¡YôæúZ§¯Õ?{Ûã2F€ÚNÐoðayÆÀî#uF±€Šêz»uBX©ÎT:Œý¶°Ì?>�ú9ã§ÿîÓx?rªÖ�Y{Ž„Ë ¶`"ã>3¨gȆ‹�¶tCƒƒÎj;°ó`Ï(Í�$¥Ì“HV'ëÜ{šåêEÍÙ“»mÏÁ Û¼»Ò¦�ÊQÎ\Ã>“ÙâÍœÀÖƒ=CŠdc~†‰RÚƒ”¯Ë·ÉuøãšhŠ¥åï š`¤‰jyF…A¶ñ²Ò ;ʆ \û†ØEźøSì¸þ¹îêµAgg«Bå7?µmJIóûh‰RØ`^µd|ø» ð4v`Èžžâ¯=oYÆÃÎÃuöâÊZû½ªc®Rª\g½6¹EUðH'ó§÷zë´t ; ¦`4ã©w±Òì0íos€ž°÷¼û0×Íxxü¥šVê�Áþ «…ììñÍV~x½‹N ;Emü0²ŸR4õ5B‡õÿý>Ÿ:ã@: >Ýil¡ZÇ ø%Xù°xþüù6vìX'4.ðΞ|òIWEP~¤òà?«Á" ®?9!°À�h�®Tæ“Bi÷ÀéŽ.3²çº®ê UçZrذ�Vm¬°_½|RUuÎÙ¹sµ Ú ëU"%»ÀúŒyÄúNü¬@§Áî¡:öž'ö}Kö×ëŒúÁ Ò$ž–vÈzÓßX@œÎ~Ä!!›/6Ú%@Û$ê½õÖ[.ýŽT1 PªG�6cÆ Û²e‹mÛ¶�-ñVmŽÚ5Á´�ù<@FÁ,µ®}úô±‘#G:à Bã;vì@?‹Å«­WÓ/[`�<x õ¸RÁ'Þt]|X)b/*T´“Ñ|ÀÖ˜K`<‘ÎóãßWŠÝY±&bÛ¢bO×A7ºJv�ûβp¦¢)Ì}ÝòýÅ6’Þ™q–þ×T]"PýŠôîñò­\< !êñbà aÓ¿¢×f?^P혭e\¾ÇäæÀÜyxVÄé±üÉ�¨V¼áÿÓŸ6|Nnk©/Ð3iÖ¨�Ý£4È\½ø/ÀrÄœÀHd„ŠñE¢å˜‡_ϰأ”ž~]/ƒØ�ç0±Q6ïml zm©ÇøYÒŠÁWTdCsª1£ÏhÆÜ$QtÄ‹ã팘C¤eÓ’”JR1|óöìç¯ÖرFHqë«:˜Àè€@º Œ¦ç—רܽ Ôóöƒ¯n•x? /ú×”Q± QsÒ$ïüæÆˆtÆš;OÞ:TèCœ  �Щ£l‚*g®›Ç3×ÿê7U AKo™tO·ƒTÍ�}{ö´XF¤°¦àqã_Hµ˜L<ÁÄ[¦ŠŠ0ñ>{{D XØVm¯ºÈ&âš}]âámelý2XVÃúÔÙl�¤ñÆo'×=b÷ma«!ýfæw¥—6¥V~d“ÒN«lãŽ*ëU’«]6œ«döÏÒ�;IWMàÓ«ËËí칪ŸÚ,µ|’®ACkèyµqj hŠ0¡ÿTZZêÇI¿‹D"6jÔ(›8q¢íÛ·Ï***`Î߬¶TM¯óy€tViJXÞèÑ£]AüwêÔ)>�8á$ÖNêûgÔö«x ð@à�À�Òâ�FÂâ´l»5’ÂwÌ*«jí¹7ôüá*Ìys“Ÿ8@ãÿîãGôP\!æD½c:õv‡�½÷'6ê®[qé-1à‰§_žêS|hN¾7-_’}X.èût”‘Æ6CoÒU¦Ñ¢ªoÒýŒ¬öîÖœ1aÑ/$=“ËÁ’¶êA*@Ê\íûs @ïW°J%5|Ã÷‰ æ ¬’5R¾¨˜å†gÜJìPÃxô-‰õÁ[”óó÷ÿ]í„Ä›žXžJYsÌRà�±ÖG¢ö©²í* ññ?ʲ?ýPô’í¢ª©mÑë·7…5FT: �ˆHØd‰üʾØçuÒÈ!ýÐïßDý@GÐèà‰ÄçVz;ñ‚ä%JaüÄ�ݯKTü[¿¨îPàéûŸˆÚw$$>að¥ƒyñZig5è¹#móß~úµ,ûÎÇ2çm0Rì;wÞrÉNÒ¹žgêðĹŠžØl§'ÄòDs‹{O°¹/¶§ÑR︗$2î„€sTÕk+“z”eö·.½'»]œ8]c+6�c/õ}r<¼(Ü;Ó÷½ˆÞkÃ7¨un«c¶{E{€Á½UíYµ�ôññ•+WÚûï¿ïtŸ<ñq*ßMž<ÙÊÊÊXŒÖµÕHà ,æü2G­·Ò3ÆŒãRÔƒõTYéˆN0ÎÞU;§Xà�À�H‹.Uš–Ͷz#€O_R»ø°¹ÿHµt$ò¬{qL¿'Ù=8BÑó?ü×Q{ó½ÓÒ½¨³îe7ÛÈ;~`}Æý�öoá¨ÈD¶éŠ`’í\Ë¡Ÿ4z`ÈÞbTŒ[´FbºmHxûjlZÚ=Æ¨ŠžTø9p¼Nº+‰ Æ¶Õšùåè`€O¿]£êRmß8ý»Á‹ØÍ"výˆPCéõæ ÀÆÍo–T;ö}OÆX.W•ÄÆ‹…’½t?œaªb#Õ»*_\¶?8*p(ÃUÜò¶O ڜީ:S††UN>”PKæ”Ø¯­Ž¥êqîS1´šæ�;ð Ý¢xð‚ã@(¡äx«­ËpçN:/Õ]Òê™<4äX$�oΰ.b—Ñ_À¦ÎFw¥‚!Noœ'4ºö‹U@ó¾¿KUÔ¼!j%>ð­g©ú×[/�SªBö. 9† i¶a¤RÅŽë�ê™^ñ€tö�‰Šv¤¦Â"b ƃIœØF«·×Ú“oÖºTXRàÖ©ªš{舵·eê^Hñ°ði5Þx:4ªÑãÇ cóš ü¼åýS*å­ÚT!�'÷ «eixLùševê®§\oIžm¯ ëªRØ?þJ–â°«`çi½�&t ùÍv²#B¸]æ�fÕK"ÌèÑx–©7ÕQµÍ{k›6¼uZ3�#‘áï"Ó¥¹ùµŠ`œ ‚Ý–› pä6¥a}J©Zã…]  SØ®ßʦÿO©’ascAzùÃbIy`Ç@µºW^<±Ä‘†ªÅ€ �›ëRÒ’ñoçÎ)aûªØ{ W׺j—|Ç9yEâ݈­;öX‚4Cü; FØqñ{t6fœ‡lc^.Ïv8‡Òhv禰ŒøùÏ_k¨Êû¦ýþåÜ Nº¤pÂ݈h‘–‰ÎŒ3?£vÑsËÛÎ?¤®Þ.�ð™ª"H m|Чw}u׋@B*û1ó¦±Omÿ/ 1ãÀf,­DÆ={醖¥È&Ú^¢yúMåfqúÀJ;jŸ4xê­sAÔF—e§Î!æÑæêj2ì]�Oçλ‹„gÒ€©µÏ@ÔŽ»¢< ;´’FjÚƒT»Ó§O»´»R¥ß‘6•��m‘SoÿþýMV¤vLm�Z¤¨@²üp¿DÚKî¸ã›0a‚åääØž={œÐ8Sùq—–ùµÍjîrú+°À�<ÐJ$~ZmåFÓ°:œ_4/±Åï–Ûº•è¸ä‹æ>è�äžYÖ¥ –qæØvÛÿþbïèy–hø {–¥jÓ2؈ˆ'h4wø-ù¾�R¶¾þPÔx@P쬙xö�¹®¿.r #Ê['ÝSØ=z&ía°?îýìíQ×nV�î±dÚ›34Æ`Ì<ùf�ýìåjéÖ$_ñÌÛ6C•*m€‰ŒŠWƒ{g¸Š�¤‹óèßTÚÏ^IÝ‚•Ãy¿kªÀY±>8n¿ÁðØs�$i35¡å­ó�¬»¥õ�´¸üFªTcFNZ:‰ŒÓMÚ[k®‰iÃCb¬…\ЦP°W^ë¨1@�ó<@"ñwLŽ8€Ì¿¾ÿoÀâ3ß*!þDh0[Ú[Ä"ôìœîxÿTÍ%LGï»öš(éΈÓN8ô ¦^{‚+3å›�HßàÒoËÑ?/]3ö•ƉUHÅÂxãø©2øøË5ö‚4Âþê7Õ—±öâ×i«Ï¤fþð+™öé[cþÉÕÏZ_¥>'2îhžSkK÷Ér ú[ñ€ÙŽ}rúl­½'àèЉ§ ˜Ê¾é3ìÀ~=£6ª ´3XÐÓÕÇ>ÿ^ƒ…|Síy5WÿóÈ‘#N||ëÖ­zÐE,€8p M�:ÕJJJ˜ÅÝìfµ©j‰/}q�釤!vGhœ”;À:€Q8ñ)mMm–ɨ1�eŽ7G ¤x£Ú ˜w”“Hë =2?HA:©jO¼^Ó,KÊÛ):7(Hxó™Ò#ØVËÌÖ4g¤LQiПfˆ€7ë/ô¥¶yÛA”™”BDõéC"Ã瀎Œ @ÀÆúQ£AX\è³ÅŸ'o»;åŸM{½+ΛÛ~SÎ{gœbŒXYÏëÚ‚1×^ÆØó�§�¢'íø—‹jT¥­}z‘“Yïîiò_ˆa/îÿìãŽ4»å›¤‰E„æSG×ÅH·{éÝZ7VoÓ½‰ûu¼ÁŒÚªtè×׉éׯadXÌ“ºº;¾k±UU”»ëµÏl(ý&ïÞß¿Æ>4Gu|ºÎßÝtÞjjê¹ AÛª½ÓØzÁü«Þz€sì¥�šh‚ýÔ¹sg§ó”••åÀ'˜O°yÄ|‚•¡åºhy˜SkÕÚ鮢=]y÷)µ>7ÝtSÕóóó�Ÿžxâ §÷$A÷£úþÕV©µñ]C{,ð@à�À�®)øàƒ+� WYz�ÈPOë$j³ÿh¥]70×úv�6Éöšö₈½ºâ¬,�Xg�ZQß©–_2R+÷û:CZA\©&�è›.6È·>uUµüÈÐÖ!Àö€ ø’�ùCŸ ?HIJgàú½�gÚÔáa;&àÃÏøIXi‰O©¬5BÇx×”ˆÍWC¿À)šÄ�Pxø¬t`HéZ·«Þ Q&zÁ~KúŹÈSšÍ¨R‰šÇ›€aì›”0ød Öeäï˜ÖqF�ži<ñFê€ßËÑâ|õ廣ö™Û¢.-Š>`,‡>Yséy±¥cÿÔtÇaâ�ËAŽïŒÀ¼÷¶×7[eo¨Ä×ÿþsY®ú¡ÿº"-³±”9Î ¬,¨¾J9,ŽKmôú ÈÚYËoÞ—8� ŸÂÃû†ç­Ë`•4ƒ~¹0qê¡Ù¶ú{î˜�}[âÝ'u^aäyFJån g·—}ú–ˆýɃQ{]âå#Ž1ÀÓ^ÀÇšŸ²©ÃB.¥6þØÆÞ”¨ù +jì| güú­ùÌõy‹X–\ÏÞ}˜Âè^ýÇ«µ.åŽ4Éé#³NaJ¢÷´J˧Ûé‹ñ«Â¨‹S?Ò°OÊ�¼ogŽnvýÍË ÛÄa9Íõñ}cÂ~"�{Ëž*;xÌ)Û òu)@ 5mÇôøÞŸ;Ð �ãj”R¥VˆÆ˜ëׯŸõêÕË�O€R€*|‡€¶*ýJ9ÔnMßWKÿ¡�^áÆÓË'ÕævéÒ%ïÞ{ïµÁƒ»tÅÅ‹Û믿î€<}ÿªÚ/Õ¨x ð@à�À�Òê=>^±&~HÌn˜ØÕ¾ñ#¬¤(ÛÎWÔÙ½|J Ä%½%šŸ’öTÚ'Ó&ç™E€ÞÐî_÷½ùo_à‰7ú~#0þ•ÞðïWB%:È`qô�@2Uìš3n€ ³ã�Ô4tnÌ[jñ)U¿T5©ç–©z’CíaøbìÀ�}âfÀ”ˆKÏòë[5ÕÒ‚Hµzjiµýó3ÕöŸ¯ÕØÒ�µÛ¦üœ‚ÇË]ÖÔæ.ûŽJqÿ÷“™N—g÷á˾v3ОBŠ µ)ó@§ûgĪôÍs,”x X À{�À'Ž#ÞY—ôÌ‘Úwk Ðæ¤ÂÊÆÒ„rŒÅ_C‰öG°»Œí¡Ó•¬ mëñèÆ*Öqßxåz™$�,‘q��ÆEú¢Ÿq�±M%Ò:Êè×éø²Äýo¯~uÒí†Z|%½öÚ¿·Ÿ®JF�Õ˜Èð`²µ·}둨}鮨Ý8öÒó•~‘9ap¸ÑTT€ß�{Ò+Ð�8g?Rêß_è~T("2:Äž£9%Ö¥ït§«xN¿ÕÛvWÚ¾#J½Ó ‹T�]‹"6ydžÖwçði˜ÚÌT·,Uy@M[¤ö–Z@ÓæÍ›íÍ7ß4Òð¨Ú†IÓÈÆ�çËÊÔîPc ]‹VªƒæÚébwM+AàIo ÈXã¿–íWÃç–ëØt\°Ÿ0*"Èìß>  ß*-©µ½±5Vi…~f�×/®w*+®“Ì3‚ß뜡Gå1SXQq@?øã­ÓÔ”u¯Sꕹfâ _Á@ëªq{Nl©CJÊ¿!€?ó:Ä»ë á>�eRñoSíW|’ýŒ€÷±züŒ&þ¦_¿Ó9k/4Œóë…ÄqÍPù°£ ÐôŸ¾˜å*xÄ ®Rh�˜ÃЋ_4íŸ#€˜oˆyÅó[,%8l7�S ^‚1J î&O ÷÷o+Õ¿¹¯Q}�8× Ò ¦¾¦RUï”zwþ”KaÐ;ÛëÅ�ÇÜŠ-™Ä¿:Q�ü¿fk¥�:ã^ejMøg¯ª9:T[ ¹ú<@êœ aÇ~êB¥¶³gÏZ�=¬ÿþî9P*//Ï=“ìܹӎ;‚Y¤vPm�Úµ6~îÑ1ß-À©èÎ;ï´Ñ£G»ÔÄ5kÖØ /¼`G�’mçüòïšîR»ô†Ã·�<x ð@à�VzàJŸÈO·ëʺش1ÅV Áð×—µ3ç«øÖÙÜ �܃i²>à—´¸0bKמ—þS�ÕT�³ÜüN$&T[ÛØAT‰ II�h”,xø¡ªèQ©í iJŽ`¼AO¥’A6Áàl'¿@‘ –J°ÁzˆyBÁ«h‡ÇBØ?ý$Ô;S ª ÍQu¸R¥ ‘F†¯âÁï8 ¼ö X ‚Ô‹œ^RpGð ëéð©z€´–åľ¦ Ùœœ í¢íÒoùéK1&ºHñl úÌâ”|ßâÓía>¾�;6b÷͈¸Šf€N0‰â�“ý‘®Pò[Uå[¾¹Þ¥gчY£Bö>‘e½$N ˆêÁ§¨zóZ:ÍRxIš#z_ñRgÏ(ô\%0VöÅ;£.5’1´Òb´Ð…ÍEú€@d¼�Ø/û„äè=tCX _½M|Ÿ]VëÒ/9oëölcP ` =Œ1þ“¯f9æ Æ)ïš×ÎãÁŒ¶ì þé‹™Ž è�iR3ý f[ö¡±m3N†*=°1àɹç:Cm»À2hil{-™“èÁ™1 É_ÁÖäÝc�+™@¸>Ñø„±»^¿7ž¿[Ò7î‡wN�Ýëý¿[ïê¤êeC…Qú!ðI/rÊ­±3Ƕhwª©ßÜñÕzׂ�s�E”î|äD­mØ)߀ÚV«íR ìÚôwØñ}ÕFª…Ÿ`ò”••Yaa¡Æa½¡ «gÛ¶mV]] O�ñ³Ym·Úµbª¡l_T›0hР̻ï¾Ûuò‡=óÌ3¶zõj«¬Óuév/iÚÆuƒÙU`�>Þ`A:Á|ò˜X0ŠH•k͘Žßi”¤ÂUTT8P¥´´ô"û áq„È÷ìÙc`y=¹9fˆ�_€ãõ×Õm¼Èý„ZŸ9sæ\—»=õÔS®Ê�Àº}úþŸÕÖ©5\èúXà�À�H—šµÓµ‹ogžÖœÎÚúäÛÌ %Žåtæ|�½±ò°ÞR‹�qZì§Iù—¤~5»7=ztíµÅï�³³ç”’SqÜ:—YçÞ“�T³ë'±imß}4Ó‰ ûßòxzl�$6ÓªEHµy`fıGüBÝ ¿°<Aº4~òCN‰ÀÌ3 € Òzöø‚;ï{¦ˆ £cRY8¼ï`„´•�8 EO�N°®sÀ vË™¯+—Lc¨nµHA!oúIð€á•NÀÉ¿Sú3¸WÈi]ùÓ¥¼e~aÝPM-DâXy&ßq€±Þ‰ÃS¶~xß°„•ci,ÞvMÙ,‚͹šFjgw“.`Ö¯£e%6E¢•Ó0�@�¦ eáË´«èÕ·Š�›P¡:d:�'¶K?`€�=_kCû$®&ÆrN°a–¬«±ÿ÷Jm›� öÕ”‘>ö¨Îso1ÆüUô`‰ÁRk/à m²Ïßu¦ÿœ¼(F#€m"Т©ãJçw`¤hö…€¾g\ãŒùQÅãÙœÞ2¤mS�m—ôÖŽˆáØ#U”û¦wÿà¾wRcè¿ß¬i6u•k}*€óÞ’À,þ&%ŽqœŠlû×!-»Ÿ^¤üvI­c|6¹-õ-C7 šÊr;¶ã5«®<'Ac1Ë”&߯G Rï´3„Ç3Hï•vÔŽ}Ž��öÏ.ËÔH¡ ìÚô#[¯G¬—Úµ(ì'¤ŸŠ‹‹û 0öÓùóç ö“¦ŒP;Ô6«]íÆµò¨ÚE¡qØa]˜K—.µ%K–Xy¹#:½¬ežPÓ.°À�<Ð6àGéJµ‹àÓÀ>vÃÄ8…õ`ñòÒà ‚kíèÉÐ3ˆôÏJ‰ýÔ9?lÇOÕÙš-ŠZE‡ª>ÌzŽ|PÅz`c·ÞQFôËp`•ßüò­ßzr[ ˆúŠ*�• Ààí·×˜é0XdˆS´´ÅÁÏš�‰Ó=‹Ÿ2,ì˜þ 9~éúL°FzAçl•RïÛ5䀿7e†”X‡‰ð{1�¨À“ ‹çϦÖOæ;€‹›ðÀ&‚™âç­1– 2ô·üÆq±]ØW7й€¿IÁJÆXŸeIɃuPœó'ä*[v¡ÛÃ>ÑÀ�ÑÃXH§á[Ø#ú!¨|yp ¸ˆËùH÷¾ã�PâL~P­TÀÆ@JaÿùšÒ.O¦Ùñjâ3áæG]šàÓI=ß´w�î™q o�ª1.QªŸg^¼Ïí1íªduF®'À•Ÿ,¨¶³Çhè`ÀŒÂDÆu�\•€"ô²Zz/½UiÏßQ¥AÆU0=ƒ©t8‰"ð°üØÆT]Ó‰Æ#@Ö{Ûëì÷KkšdŸzûõOžv ¬·T¥Òc_qÞ–Ü%Õ¸yóRïÄ`Ý·ÌΟÚã˜PÅ]2mÜ�ìÖœ—¨~cjt\+7�‡}¦9.uꈦo5ß§`‰«Ø0—`Â�PëMªÚh= 8ÐiÁˆ"�yb>™Ø>Z®XËë×ËÖ«Q=ïj¶þ:¸/© ;vløÖ[o5U»#Ñ^|ñE[¿~=UñÅãj\Oz ,ð@à�À�´�®dðéò»O�<›3¹«ŸºFm×þÓJ½;ëþ�œªµ¹;IƒH¥Ï“ô³%b?½¶â¬UTŠª}æ°•ô›fyÅð‰Ú‘‚MÒÃzÔ ûßòÃ4@ß%] Es]ê”K�ò–ƒýDµ¸C¼L³9€@9‚̤%ù�7Õè¨À¸ Ýë�ëÃN÷Æ[†ë�9è㴇ѿ/(m&   àESF°Š ôKJ¯#Í„Rå¤è¤tòö_˜kö½�g:v�º§ÃÅ÷Më|G0L:X¢*]1ÏŸHí×­™ƒö:”`Ê~Ø£ºˆ)ÖKZQœ÷ýÃN”&Ëiªù¥ñt²¿aS ã� ýˆÆ`][1åüûäø`�¡ûÓOý‰øàH%C(ßK#õ¯ßVS�ÍXg°ó"rš`m¡KÔØqÀ¸òëkÁ¸Ã~®j�þù�­ßVó¹/“.Æyñ)3ñÀ}`üæê#vÏøKdüÎìÂ&eL´ÄëI—¨ôë;%³­|z³F‡íŽÉ‰™xÜ`œþfIµí¡©{H¢ý‘b7R×5`ê†ÞŸ32ä áCçOí°{ßq©w™.õ.Ç:)í=Õ>áe~S"òý–=Õvð(q²Á^Á«¡ýصé†à`ì§l´‹Îœ9cÝ»w·>}ú8& ì'„É@Å«Ö�9·V-µ?­ð²[Õ×ûUñ¯äöÛowÕÿHE<|ø°=ûì³¶wï^=K×íÕ2?RÛ¬ÖðÆ@ <x ð@à�Àéô@#�ØéÜE‹·õQ­9’µ{wïd7NëæÀ'%ùU¶hù)¥o(8Uc=»fÙˆ�ɳŸ2Š Â¶çp�mÚ¥—<õŠÒ…Hôv—ŒSûÝ…±2}DØ¥P ÐÜöÈœˆýùÃQ÷6ž Ü3*lù?{óÓ5% è.ëáý.3E�r»„~ùž¨ fY'8ö ¡=Œ r–ØNwN‰¸ ±±}Âb àB¯ç91Ž=_+Í#ªF¥ XaüxÇO*&àÆ«ïÅö×XÿÍgYb�xy° ÀJŸ©,–­eðN‡y@T'Áh ‘šH„ŽýI‰t§\&ê µ{§s{º\›Šc«¨³n{ƒîS¢m´vû™3&æ7´¶HµÄ€y‚æºg’ïn�1ãü㻵ûnnýÇT5ó>µµbà Ëåiµ­Õøñ¶ÕÜ!êï>Ó&{N©¼€�€ šr <Ñ�1ƒº ,¤c¢ÔU–ñ×):CzÇäýßy{㟔Û÷“òFä È_�Ði‘±—W¥v8Ÿ)Áÿ»Å,ëª1H_âíxy¬º¬Àæ€P@ÃA=%æíûÍØqPiíëk]kü¶“þ¬~…„Ð’zw|§Rïª*ÜïcYŸlëß³e©w\‹Ý8ËUhä½Íçu�©çæ@Û©Få²À®]ÀÔ)Wë¯6X-öŒ§R¥ß1^ôÒ ì„ÈOœ8aÛ·oˆÒ`Üà\_®FÓkIû¬ÚÔÞ½{gÝsÏ=�#åŽ*w¯½öšc×÷¯ªýNí¨Z`�<x Í<ÀÃÛ•jãÔ±™tn̰.6KšOµµ¶5Ö£ðœ@�pD€}ø$•ïò,Ko”“ |a†äf‡íÕåån»Ub?u~�eæèeX oùyÓüÄë i.ííÐQx[¯æˆDûÒ8Úºøb\™RºâF’¾rŒ+„|ßU J0Äòía{�0`O/¥Œ‘v¬1V¼òéè9=¯šô’- V�êQ–à9Ùñ”ÌqÍK-0ÌÏú‚!Gš]ªF° 2¤7€Èåàà ¢ïˆ<%J�LuŸþåa)-¯¿*n¡QE¥º#CZ 6·®÷.ÏÃúî$@w´RQC`Gú™ŠñÛf™ùR–Z¨òƒ“+~�Æ>sŸ½AÀÓ}Ó¥W%¶c¢®„ò„aÄÓ›2Ò�ÿí³lâ�°¡Kèݛک”Ù:£ºßê¿SûW¸Ô;¶_�•ðx¶æ¶À´Å, U­ÙRi§Î8¢ 7SÝ ì• Ól8Xå*ð7@@àïajÝžNž³=ÆÇ×_LQ°^5ºæ¶5T�þ§æEm¥XgôƒEµF̳¡}c©~±¹ ÿò¸ ¨à¯Øðmzþbü J n‡´‚¸ÆaªSºÕ^�MhôÀî;.¡è¶žJìÑ¿þ×6]ó/®¬3Ø�íeTW+Wà¨�)£çׯ×èzkû^ÀbD“i¶ÒÎ~ÄiμÏP�ñ𾏲öb*&ç*Õ´LÆ_X—Ò± I3Md€J€ÚÜ+6 ¨nìÞÏ-�vB@6BëMUÿL´oE`ØÂxj x‚=¹N{¿ÑKR®›3ÄçaìîÒ¸& 1U?5½}î1Bˆ(¥}¿ßó–ÕŠ¥ P>zPŽu) 7곦¶Ëy ø;páÅ“–Eë‡ÀÁNµÀ®]<‘B'•7¥–Cú ¨’’ëÛ·¯Æ_ì7’ô;Òò`? x�”­¶Um›ÚÕf÷ê€nWš]çùóçÛˆ#œþÕéÓ§]Ê>¨­­å¸ÿ] 4óÐB�<x ð@à�–zàJŸÈãï¡6½ül­ÍšÔÝòóÂŽ Q§w§] ªTH©7[κÙƒÇjmŽ´Ÿ¨\ÖX0àw¿°ÙZöœÞó,]«èQVW}ÎzŽú�¶{Hq3;è-´Šú¨šÁ=o¤ÏýñW²lòа«ÔDÀ�‘^Ñ^©6±=zÿÆôO¼2óÞ\¦h°V¶îo_f´ˆ¨dwFUʨJÇw‚P—a}.Õë©«SB ÂB±žÒ­çDµ¶9 ’(<ƒù°z{­=¡ªQé2‚eĹ À€üƸá¸Ñü"­o‹tj/«P׈­r@Wi@Tï,ôñÒuBÚÀ…çuÿfý›sNjPOÃ=¥ uJ:P‡µÝæ®Ç¯(Ó&‰��n”ŸÅ“¥¨*ôõàoËì“t`ÆWï�ÚÂÕª€yáô°*¢<ù�ãa„§Û ¨ôöÇùú·?Ì”nWب/HÀ~³íeˆâýáL—Æç€Šç/o^º§Ü ¹ÇÜ8.â˜)ºÿ �(8BøŒ7Øwœ!RáY[Â"ôú ˆÈuÓWÌ DzcÞr°Ÿw=öç鋪à9R)È~@V#ºN-žè×ê|ê·O »gæÅcà©„Xý�*Œò{yL °gÜÐÃòÆ”7?]Ó°R{êj¥?¶s‘UUžqç¨g×L¦!Ü—S6;~—N²­ÜX¡ëO7p¢ÔH<]¤Ö’­jµÀ®pGd, P¢–ÈrîÜ9—jÖ­›^`êæ�••å˜PûöíƒÅÝÝ¥í­ÓÔw…èÓÛòÕýÏ©�0`@æ�wÞét°H?¤êbãè>É^V{Z­^!°»À<xàZöÀ• >ñ ©PØ©¨ª w+ʵ±Ã ì z¥?œQ¥·àõöÆêóvæ\­� ¿¸ ËÆ¨¢ŽÇžhîÄò _˜QêÝ1¨TüÜë6èfËé\ª‡”†«¹í¤û{€ ÞJDZN3¤ ©TY]ï‚íAª4 ³Vo¹[›ÚÔÒ~óÖŸ`t‡ØÊ„tlšqƒ.­¼„oi¼a_Ÿ„6JKúB¹òICB@òÖ§O«¶I(|y(HG°c Á^Ïj ÜH‰I'xÇqÿË—2•’qlt—<óë«xóZ3å¸8"*tdÆ[T饄dq°åvÊ?cf8!u´­H‰D¸ÖËÀ’búîÖzçÀ)ÀX ™„yÍdžT_�F|ü¨ñ,GzIøÝ3ª£j¤=z€*ß*”ª¤<€b¼‰ðè€=RàÒaŸ¸9bCûÄ„–SIÓJǾ›Ú  •#¹æýþij½tGzãä¡!—b¸IŒ³ö0€SÆ4L'*èM pâ;¿1òS°Ò`ò´ÆØcoLé¥÷4ÿ6e¹8??¤ž~þŽˆ{Y@•ÊdƒüÛôÿMU=¥÷Ï;0V!×R¼1¸<¡«—¼W©z°¦(ØäYõŽùØ©jœ¸ãþÁ7Ù Ê\à§éã_Ërb⯪² ÇáœÆ<ŒX eÒ$"mÇ3/˜ƒõ‹&�†î}¡R^[W«ÕPÍU@>º4ä|ã?|…Q&�´-‚s4a`dpNh¤ž<«ê†ð:,-ôsð ÂëÛĨ€}—'Šàßó]lë—ÿ‹NÁ.•øGÆÙòÉ·”9óº�˜X A°c„‰…¬Àr€�ÂqÅì,Ä‘I—LÕ87\Sþ1 Ðm¡ÆRGé‡$öÇF<#�€0Þ?Þ÷éžÎ’¶ÐßÕØ­uÚZl0pÐÏLK÷~½íNææ@IDAT¼ È>[•×îR¡€©Òk£Z#ãv]c†¶ ˜o{ƒï[¶©ù5:VX›e½2¬Dã¤1„ÜÝ(M5€]î;?ZPíX�­ÓÜ|®+€¦›\#¸?¼_øÀÜ¿¾ÓxÚXkO¾QëÒÿ¼ñ_ù”ë�üŸ¿VÛ"–Ÿ©ü�fVF8jµU§íØÎ…b,ééÔ ê�c}»GÝý1•í±,矪w'„ǹ9ìS[¡صíÜö«é.bèPáTqq± 0À �FDI÷‰êw©ºhY€˜õj©ÍÕÉ/]•‚ˆ¸'¢KzHv\ºÎ¼]»vÁŽÒÕcPW¤ß1ž>ȦX{Lm|ÿþý3ï¸ã—rkðÈ‘#öÌ3Ï8Ñuÿ2-ó54V <x ð@à�Àmî~p¯t;¦ÇÿGjêêsÊÏÖHû©Û…” ±Ÿ+dWZVfXéwg\À ûiÆøNÖ9/”ô›Õâ‚°½½®ÂŽ�¬¶êŠr+ì9Ú »�×öÛïù`„à€r€–‰ƒcZ&ÞÉÆØj+¤`\Pqí¶I»eU)#ÄÌF¿¯1àÇß'Æ&ÌËÒ¢Z*@Ücù—Iõo€W®ØOÜ�3ØyŒS®-�}ÙØ²MÍçÞ4óº°î·U1@+™íÆU ©Èù»7k\ª,@°(s�»E Z�v×'%<¿ýÖ~æ7�2 + þ^U x—eUz©sbÏR]oꤎkTYŽ ~´Px\÷^jçŽNƒ½±±µÇ¬Ux@¯œlÃ`Mû2!2^TTäÒï2335.CFúiy¤ß‰`Ã/Í&µ½jdƒõõ)µþÓ¦M»˜r‡ÞÓš5kláÂ…® ¾xZ¤>Õ�<x ð@à�¶ô@\H×–»jñ¶OZFý ጌÁ‡��·�ý ¬¬_'ùŠ Ä~$c}F¬ÝVmŽVÙÙóµ–«×Å“Fä\|(ojÏW¹Ù!;Y^g+6 mÕY�‘÷· ó‰ãÛ‹Úgn�8¦ A`–ã”ïÞ¥H€ùIJ¤?ŧ•5u|­ù® ×ìÏ%2 £‰t¤ÆÞœô!Ž/Mðˆ^Ú$^ ”J¿¿]Á) ,0Ø^j :8ì¿9cÖÑïÒ`Ÿò" ý n}?çc7°^eU½ý앱°šëEÛ|OZÚ÷” É!e)‘ð8ãöRk«ÃáGK½0�öÑd1D¾ËÞ3ÐÛ*ØP&€Œàd?èá-럒vŠÖPŽ4xüF ÓÄ/îìÿž¿Ñû°X<{ŽÖ9ó¸m *NyùŽžoýéLǘó_WøvƒÒ!éöÐ÷t[/�Nÿðù,— ‹F»w@É8i+à‰±¸4kTŒéÅ”bÜïa‡›Kt’ûÈq�ÁÅ9`±­Þ®ô^±,Óa;ãc�Ruaí5ÖŽ…{Òáu-º¶ÿH1„ñvëDÄõ)pù¨!nØ+°m@�¨ ãË3ÒiûFM‡1d¹á©0 çEÎñ�KôrG�•o{µFx\˽½ñw%Ýœ•ĪûyËqÌTæÝ+ÏØ&�Œ*‚Ðd PO¸{~ƒµEà�…®QcöѹûºÒZHëAÉ3?ƒÅ›ß^Ó ¥ Þ7#â`ˆwûAK¯T®ãØV)@÷ί÷]K¦Œ?@¨#b‹yiNŒáøsïß6c` &I¥Ë¢çDu=ÙÏ�RÁŒ‰gW‘v¹Yeî p³/ÞUšfÄ1%T÷¬¹t?o¹¶š2r†õÍ�¶OÈ Ò{©«mµ¿Æ¶ËuE5®Ýw¤ÔÔØol©ÌçüÔ£ˆ"Ø34EߎTÑd'ö¥ØÉŸè`=½´6&€.P¶&å-Ñqä«û—ïŽjü4Üw-—©û‡F°ÓFK¥rc1u®]~¸.¸§ù�ë ÷5U¦{JÇ˽Ÿ{Íô!ûî£Y®ÐÀ�ožq¿†!ÛHvçÔØµé~·.ì”TXú ð¤3ý¯—D¡¨�=ºÁÊ�ltç0'+d†çê¼7íÛÆŽ&0ì§]«m÷AwÓ|‚ý´Vm§Z`�xM¤»œ Vû‰ô;´ŸÊÊÊè„‹ Ý|ØOçÏŸW¹Ók Û¡¶Eíƒh\ �ªMíÕ«W6àSÏž=ð†ö)wkmmív-ó3µ]jü,x ð@à�À�ÚÜð 'Y|LHLα“U6¢4ÇJûtr@SH•ï¬öœõì¶M»b¢ç*jÅQu¤‘¹îA·9/Ðt)ˆØê-¶÷P•ÕVWX§’ÁVÔwš°'Efi4@o/`gÓèè<©7Ú¤Ý`€¤�rU—ÜLýHB0HÒšo{þém B¿ó±L¸¦xFå¯ÃIFô™·ó¤¡Å—(÷@D|שïM¥¦}垈]ö uSyŠ@ݱM½PwLúÛxáS–�Y1~Pƒžó øˆ/I#lJS‹cC“ÖÁº� >bíe„¤æPRÝó#ïëªbõ²ônРºNi;øÇo—œ#ØgéÊðÚ<#H§èÝ:'–LPÝ”Ñ7ØpÝ;Ç*ôz4–†0^ÛG„ÙoH€µˆ¡{Æyô�ƒ} Y�êc±@Ø[²ý¦Œ«$àÝO×¼°äc?”™x+ïîô\ßjxü–…ÔS·#ú�žN1“T·g0°Ríwµ åî2Eƒ¹>O˜p³F5.O=)¹2 èMLŸ-ÊÐÖÁ託+Ä´’Ö ÇLÃXt» #­-�í…›.U(‚Ñ+`–@# ='¬šÃèÙ/6@{î[ìø€7YA„1ýÂ÷µrå"À2÷€w?À7'€ƒ'Û`É7żZ­€ÌU2ºjî—H\aÅ‚–lC"6³Ÿïš¼o»þ—6ùM¹fkêÍQ[7ðC«) Š3âšÃ}.—= mÚ 4¿àÒG€y?àwú ™×p•ØøªÒÜáÁ°yEÙÜ!Èà÷¶âãôðD9›ÿ3)Ö­ì—2ÐÝõÑWèç}%O+(þçVE,{ÇIoƒNô×an>¬@¸–ºNvtp¢½îRŸÄ­Ž8s€Ò§ÔÐèÏ=%ô™ÿöÙˆ´q]sÂx@¦ïŠ'ô-²ÞÕé¹³;¸Ž+,î{ÛH1™îh³Lñ�p5„ æÓ8>× °FVÊ—¶F-H÷¥G"fDZ��¶C{b!Â=Gâ•­'¿Àví—ãò TýÉc Æt¶ jgÊyóÜS}û²}?(7bf”ŠhÒRÝlÚ!aÆì”HÐf«½xM‚†?)sš­Ò‹Ò¤$k@#­u)› WË~*//·™îÆ�g” NãpƒŸ`F)ó±�`Ð@„&ÇH2G…ýŒ\ W­ZefÏžm6\7oÞl¶lÙÓ‹.ôœtƒÀ6)ÉHÖ@²’5�¬�>©&jAxP ã£öúM�O³3LnN¦&Z‘ÖC5­4…MDëÌÉó5ŠñR/C"dMïû ̰Y³­ÂÀœª«¼f†•~ؤe�ÔD¹gQ]ˆ9´nw½ÍæŸÈs]~iÔB.qqf*~†øó‡@Ïd]5:ˆ·²ZÙôü 'ʶA«ë°gº*ƒ¬Ì(ÇÄ/\ÀeÆ`ÂÀ"ó`“ŸrT©Ò1ªöú€Ž‹›Ý4Õqƒœ|`Ä’ñ÷»ŽÊ±a0‚ýÂq²NÊ ª¬n4ÿò�T3_,§u»[2éQö¶â^ù�Õ›ïR`?aŒÇ‚*´'®VÉhéʃû ÍûG ŒÞR�î÷޼â•)ϱ¨“«2ÎaÐô\Õ½¤£lÄkŠùbÏ�á�Ûå…asÄ*ÐfJäš›I‘m.\—á1¹ª-}Q1Ó¨è}-öZølbßåcÅ ëÍ8J¾SÚ·þ1ƒ/NËå•rD¼¯ÜüÒÕNÈTHÒ‚%S[ãí§-¡-1~Àã¾®‘«Ùër){w_ƒ«`ûÀøô·�¶ŽÕÙï‰U‡+`¦yþ,ˆô)7èñ�Ú€úí×Õ/÷ÀoOŠu H ƒЩ-p`™€þÓ?'Nny tŸrP/ý!Ÿ^2ßüTŠÙ(àÒýÜ/‚Ÿ·<ñÔ ˆ¡”ë]uùYsãì6ÐO¼™Òµhä%éìuQ¿�O·çkçá*=[,û‰vEúng�—Üþž­ØOùRb?e+°¸©¬Ô|±°ÐŒ5Jí�X’!“——gƒp7ÏÖ¶ZÖ0G¥§¥ISaÌÊÊÊyôÑG͘1c4X_¯¿þº9pàïatý/é@×Ò½H–5YÉHÖ@²bj` €O› åg4‘Í®5eìp¥·/Uàñ0)4�•šÌËí'Wì§í·eÈ6šsb?-šži òDíogÎÎD:'SL—³µæè™jÓP_k2òFšÁcVvÉõŽ˜°Të `ΰ²Ž!‘Høãdö8[–Aä„ôÞ°ˆ«á\0Üoyœøç¯§Zcp÷ñzsNY“8w÷¹+¯”  ¬¿` Á0èâÚvÒz¹ØùÛ”ÿ 2ôˆ� Z² ÷žº:|N<{�D�âÒüÏgRL¡Œg?û ƒÛ1ñèg§°˜N‰½ÁY „Âu²-€Â‹ãV‹}È=w’/3`v ë  �6sübƒù±ÜÇÈZØ_‚ ,'ܯ |s(×WÀ÷–Óo<¶ Šjª4fÐŽ0âÊÖ[¯Ð$ Ð)hÃX@‹'€Ž´Y¯l‹š7UNØ—Œ“Œ0ØzÚµ`Ùïò€rúrƒù÷×£­Úåuç&�v<÷8¶áÚll�/Äeb<#ëÜSr3¤]kŽì}Œ1mÕÇAÂì§Èa‘2ê²XFݦñØÓ�¸¿í=KìA»ù;ˆ¶ʤ×iQýCÓX_'×»õ¦®¦BcC£�§™ £Rºt Ô#ã?φ½Çk”4D Éc?QÀ·¥Šnž”d Xæ”öbédiöL ØO€N.øxff¦9þ¼9wîœFR3DÊH¾W:P²Á˜ýŠtþèÑ£Syä3tèP C¼'\îN�:Åõî×6ß“ž•&%YÉHÖ@²’5Ðg5 ©ð€¨Á ÅÑŸJ‰ƒ²²îŸ'VS@4�OÁF­|*>Ó°ÁsæRÔ€TS#S<2KgtŒý„AÌ×n/·HC]…\ï>e!S;'ÌòVû™wÅ�Í�Oå¢Çê¹ õje÷Ù/ +F=Ð5MË)WO3y0Ö0žü1š(?Æ€O@.…ïìk´§·)[Õ~żrà“»ÎØWê#S€ØN¨|J†#†j{â µQÊ�ëÊ…!£â[ãÆ TW¾¶Ê@Y1Âigí]/uE°ãQÜ`Üì 1p G@½Xð�c"WTç�ÚÎ'–‡,kêM±RüQ채0TO(k1²ü`BµÅ|¡n`µÑnØž}y2YFɹ=Á�ò +@0ê¶“cdø·éË÷ËåJC…òŠõ‡pOŸ`¿‘3Q ¢Þ*l7˜•O(5±’ob…r¢Ô0ûe±q©;¦öBÐ|bS1ޏþ»w>ÿÍWS,(¶Snl~–í.^›àá{ÀÑb�m‰u-Ö£ë†LÕYc &.F…Ú­ë{míëÿžmk©G‚ø£�÷¸k3þÍ›l¾2@ÎÔñLJ±45ª+@ªž¨¯|%œ7<ЪnNÜ}gŸÇnô—µãï©Å¢UquŸ¹}íˆuo&høœIÓxöv^xàzwõF½Ù\�FÃE“žÑëN¾HJ²T.vàÓ0À&À˜üü|›ýŽLp¸ÝDE“ ÷;T9yÒÓÒƒÒ®4QíÖ§¢Á<#-�3gNhÙ²eÖÅf×Å´zã�7ÌåË—)ÐÛÒ—¤®^ø.)ÉHÖ@²’5�¬�^¯�8fA¯Ÿ³«'àÁ¯pÊæIpóv½¹oVºb:‰ET_-ðI” †=L§·¶WØÌu¯E>)ö“Q™˜Ê ™ ;+í*jMÅU3dì “‘_ª‰‰,ÊN1;0üž{;±‘žè�¬¤“z;Öå¨N.S¸ªµ—�÷Žßx,bA "ƒü±…2ź(PL¤«7[²ëávFY\¦*êcøÙõõ�0’TÛ +"€Ü3Gl<)ö… »é°îó‹›=fZ­îU_ ÀÅ·~;ÕŽ&Ë—K@»9#÷±¾’yŠ!ô_NQ› ´rÍ„Õèwûë«òpÚì X`þ˜FŒSÜ¿µr;&[®ˆÇÔ®4¸‡‰Æ±®–€uª€™>W1Xd@Ä…µ£B25b“þc¾1¾‘9àˆ˜Wþ±Û¿mwÞsLêšsJñœp±ÑXt` + ý”ø\uï —ã bÏsóüvźhŸi©btMJS}µ‹;Z?ìû鼂Ž;+”Lx”ºòq) AR’5@ ¨u[§×q€M°Ÿpµ+--µ¯0¢øL‘H>ë��„«D™|á}™@ª}¥®×XNqŠmÆÈư`à‰Í…QBÖ>–Ž Ç#æ Yïpqqâ 1 §ƒ ÜÉþøóó…‡"r‰ªobáx, w^)%pq®_þß;óCtŒÀ¦'•åkùtÏmÌ»vÏýŽk!.ñ’ ¢ˆåÕ]ì¡ÇsUãØ”ávU£¿·°šbÏIæGÚÁñ3zB0ˆqsâܰ²üÁãÝñ¹—´i‡iuD,±�\½z!ø2nZ”ð¬·3µ¹2žÂN›3N�Ž„Rö—»1¯È"‡û!.´]bŽÄ^\>ÕÐø…‡ÂÖ øºÆÜ=g+³'q¼œ0–×éy±Â¸‡€ª´ÓÞ”1 °þ_•‰‘¬r/+à;íéj=¨ƒ�b?iüÚˆ#´ßTõë�„¤ ÿ°”z[ìyõÜã\œs¢2†Ž…�]Yã�Q±e¤úâê°„ý}œ@ïÄ•LíYÁõNì§Pšz\5eg6 |x«ó”ŽJ3ECºÆ~r×ëkÇA-8iaJû‰ö¦4i`«’bíWU¸ÓM‘æ‹Ùcã"[�†E¿ÜÜ\ËŠ:vì˜CŠØ´§cRÍ»U¸®§¥óKJJl¼§!C†4—•,w»wïæº.éËïH�J»?áh>CòM²’5�¬�d $k ýð™ðío|l.€ݧ¤Á²òz3©$ÃŒ™ÒŠÕÔ¨ÇéÐAÅ€¨Uü§SYU¯Ï n­´Î¬^'X;ƒ•ú}Mb/\­5uµ·MVÁD“_´°K�Ç�«½ß0’ˆýAÐY¿Ã1l‹ãrerì•ßúHØ|ý‰ føã¼àþá¨Ú;gw~Ç û[ÅSùä}Jy/· L\DpÃñ Æ+öÄóÙ}¢ã™×¸wL a/h¥ß/0f¨/ØTm]o¬ÅP‚UCPëTíC ?Cƒ²Á((WÙ÷ËHÆh?nv+¦‡ÌG<¨;€ã<³È~_þüA¼;{ÎØí©�¡ª£Ø¸[lG]NVF-ÒÃ?ý`Ø‚_ï(«˜ÚÁñýF©û­;¯´[ŽÉ½˜Œ�D}Û ê½p©#“À†0à®Y€N½ \¸k$³à§ÔžµxÜÜ×ø ·Õ—ÕÆû x‚m󌀀 P—Ô ñɨÏþ’O¯ ›'ÔÎs6‘ý ×IÆ,¬:ׯnÉɃ~Õåµ.›ª'Ä6KÕ˜ôÓwë›â»ßºòŠë/íŽq$^6IwLÜ€‰e„Ë*‰èûi2 y¶pï`262¶s¼Ø>àŽÓ•Wê™… BM²VÁaG‘ð�vC_zRÁà?¢ûC°É åìM ER‹Q ×¹MZܹ®:h4i¢©Í™˜Öe–‹°ŸÎ\ª3§/¶b?íÕµœèÍëI{@Õ€Z¾¹!%�& |ÆÓ˜1cÌàÁƒíûÔÔT+éâÅ‹0 q ´­z­ >ÞCË1:ZÏJ¡÷Œ´tÞ¼y6Þ,.æLdº[³f�9|ø°ÀÞº}ÚæGÒ Ò¤$k YÉHÖ@²ú´øDå\”>,-ÂP­‹bÕ¼, ð£ lֿܱwÛ:×T=0?ÛNÌÛ³ÓX¹æ¸›öh_‹eõõ•fÄÔOØÀÖîø}õ 0ÂJöX¥èö ×€qµO±q�AŠû‚Á·_‘œúC0Zˆ‰óæ ®R™”‹LO~ÁàâþÀ†pšÿ÷¶ÞseZ¸Ò`h9ðáóE�“XI˧í6þº8|®Áü\Ì ˜F” oœâù�dŽG¹ø}�®¡3ìî®/+g„Ìã Ãf©ÜWF Z#Ó•Óÿ 3mƒ‚ørýŽ•áÿ½;ïêø¾xõ õDýcŸ€ùŸ?1cÅlê­8`þófÙÀpcòK¹úÝ»ª˜<0ãhG=]7þóµ÷FÚçÅ–üyM�±�ôøåÎ÷Û�Ìô²vî:Þ‚$ôµ/Íý°Ð²Òýp�8Óÿ‰÷6Zmß/€"Ä£½÷tÖ=Üëþàs)¶Íø]qëÌøâ/o¼÷´]iÆ4€œxBÿ¢ÏÕêÞÀ"¢íX}ëUÜ ë-@‡ÛáÛ{êN©�‹ý‰ë!n‚(ÆbwÅ–Aå,T¦=ب0!ID0­$dÁq@ÀÚºFó½5b°¤Ó'â…3,«¸ììV�ð€à£Ç¤›aƒ:›1¶¨ŒåÜ�ZëýƒUZT"îwk¥ýÐStÖ¤Ü�5xÄ :Aªy¤2jÞ¼©ð 6û]zzº ä¹f_û‰8I´%â?�•î—¶ Âúp—ÈL•ãSr³¾råJ3cÆ ë>ÈxÂõ‘éîÌ™3\Ó;ÚîUiÙ]Rîd1’5�¬�d Ô¥‚kÉ5_²37p ‚OPè±jçB/Ë¥nʸ -�ÜÁj*È›Í{«Íµ›u P5ãEíŸ8:õŽí8Ž_˜¸çd‡­Û^U�&è—xüA“ž7FvG_Ïa½ `±ñ{¬q#Cã¥Z5‚ëÍKŠcB¼¾��îÀƒÊèÇjº?e9Ì£Ÿ*åýe­-6hzB@äq1àuŒ1Š ÉoÌ&*?ÛœªÄ¦=4ˆ!õÿO©6/ÌFûR'ÄFÂõkº IÊã <¨J$ìÇ1Ù’TÈÌ•›$†7ß»cÅ£Re„ékÅ1Yb·éÎgÀ3¤x¨—1ËûÔò—ºBÈÊF ìgö•¸Æé²qÏðmÔ½yãýzóÒÖŽg÷ëéòÂPñ·E²õNþ`]´ÇY`‰Êáo«(ô§6EM…%v$Ú»w~\ýÏOEÌW>1/©_¹zbü¡-f"ÿÅC�a·~¼ÐWˆs5Úqª'Û=qà{qE|¯3 rO(7Á½e¾cŒÂ=úÄÅz ÂH¦;RgôSé»Ò¦[ï’’¬�d $k YÔÆ®ÖŒ÷C¤#¥£¥,VL‘Ε.—>"ý‚ôw¤Ÿ”^‘•2Æ&¥��91 åy•úÒ)öõ23W”}\c`C!jyYA³zQ–9|ªRì%¹¨¼[nVÎÍ´ÈU"3£ª¨ læMÉ0¯oº©ì<•æÂ�›üÑK½ƒ÷áßêZ!À8®\N5FÊ… ´-‡­!¨€}&K§ lŒ³WÌÖõÍõî PWbN‘B�¸U~×A~‡AÁj<Ùšˆ_ÕáÞ`ˆã2¶pRK}°oš vŒÐu»a©Dÿ©Ñsm�ŠQWäÚ Ç/°«f� ªìõq�H«iÊh1 `y(†)Ê3Åðj prÇxÙx Þ=†éÓB?ຶ�¥ Ðú,µÄ|¡ìëÅÀèKY29hö‰uAf¸ë2À)Æ01¯ûÊ”¼?ä« ›f‡ÌWÿ®¦h‚uõç?µ†lŸ‰`æ¿õ‘ˆíë¿ùÿ·„ªÁ…ëȹ&µOJrçI¨‹ɸ·ÑnÚŠOƘˆB_�O裓JÍÛ v×µûL?0†=äVÚÑójSzS\¿‚�Gì§¶çú ÑÔeþ„°ùΛu�#>˜_8–òaXö‰.”)˜þ¹z�±<»ô,ȼgìô@Z²Ýå(ì²Ø>í?v[ïåØ�ãú2î�!ÐwGƒuYHìMaÌ÷2z¦˜Ì‚i¦`ÌýæôŽï˜[õfûÁ sÿ‚L3z˜’ðÉî¤PçCÅœZ¬ì¶{�Â~j`a´ôCÒ÷¥­o€¾Hʶp½û…ðé)±ŸB˜Ìºuë,hpC<¨Aƒ™eË–™#GŽ˜;vð].}\zRzMz· ØDi6qž mæ>X](ì-b[I`}„_¼ù¤$k Y½\<ƒ7xô¶%üæ~wïÙaÒçž[|G?w¿é­÷°t¯|éŽÃ+û8ÕìÉ&P(Ð+ïõD¶¬`¸Ïg¤û¥LxÝöœK3>»Û:K‚ãòŸyuçseã3åfÐaÌq3 ŽË>ÕlÆhvcÁVžøÌ÷š)6ŸKo›ë‡÷\'F å¤~8¶«#W.WýÔ,“ó»2r=œ  ‰ß4û¶eÑÒ¢­#À'¾s¿³�;>Ç@Ý1(ÓW¤k¥Šl›”öjÀ5¤ö¶»Û~ç¡ÿ-é_R°š´¾³«Ò<¨‰+nNúºbN–À©æJY­Ùq¨B“Ò3G™u ú'€¬Us²Í›[n È’›È¡—ÌØ¥ÿŤdˆ¡áÚy¢#ôÌo¬´÷æÐYÅ­R?¿ÆÍ6­ô÷v‘TüçxgƒY%`†€Ô‰ƒ• Ú¸¿Ü?“~ß" °J–)3™ê:ê↻ڎãõfŽ‚û 0k|h¸ ½ù?½T×®»u �ìWÃò[— piü�±å\aÀâÂðƽÀ„x)0œR–: ·”}½ØNÄx‚õ€Ú[B}rm¸EÅ‹ý„á x¶QSQÇë­²¸ã~EÏ‹Âæ'¢æß߈Ú:àì>á1}¸'ý%ö€#sÆ…dŒ'n×½UF(¸ØÒ·I{� iI©€mÚ§ßuõï_¬ó æNÛ¥‚@ °Jÿð }”>´hRH€3Ù;w}_ÿú�T1\ÈnYkû/Ç芞³p;#>Sj„øa›‘m»#ŒiÇ/zAñïÓØÕ–àjN ×5MT,½©ê¿Có˜u^¨敆u<Îç¹(’‘ñÕ¸—q¤rE×xÂ=íêXñè|¹°*¾Ü?þ²Î¬ß«˜{™CLÁ¸‡ôlý…©­¼nÎ)VÓ{û«,øÔù«ñöüŸ¥ØŽ%E©æèieÐ%Jï—þ@zTš”d P <ZÏI'Hg‰Ùdr¿÷Þ{¼!ã2iÒ$³|ùrsîÜ9²ßáz÷˜t§ôEi?>±tö¡\¥™£G�¶Œ-羫€éæèÑ£–Ù¥ß�7©zsR’5�¬�nÖÀ“ÁÒQÒbéh)ŒÀ & m=¨Ý÷ e[÷€Å7X(¿¹}Ü*öU›ØmÜö“ …2¹ï9Â8¦™‡9Øôžm9¯€B((ÇAüe`;ÿg÷;eÔ€â•σsS'îÕ—cøU Çs×�pæݱýÛºr»ß¸w¯xï®Í¿O[﹞nÎ.Û:ô½÷=7} îYé¯KÇ3aÿñšfÑôt_Ç�$0˜–ÎÊ4?_[kj´Ìüò¦r >µwѬ¼Îœ˜jІ¥˜3´üúIsíÄ:S4ý³r õ¾àZöåGÂ2^êÅi4‹'«çº®¯Ó§k¢ Ó×7R{÷–<¶0d>¹ÅLû/ŸL± Éïþ››û˜�aˆ05Éd >Q|€#6ÜwÄ êŒ€°c_[ÂI�§þ 8_(vÀñ�Û ê{�v<íã�6K&LÆ+ƇeQ�'Œ ŒÍŒãÇåÚÚ ™±AßZÚ'ç<—¼gf»ÜøhÇsÇ{®¾d·‹íãñÊûã^‰Æ‹Bð5b­®á¾L[Ä}—ÅÞ“ÝkÀø=r$pzgö1@=÷¶e ˜br g›A£ÛÅ�2ÝŸ­û+µ`”iòÅöêìøHýrýEC#fáÔ sìL5¬æ8c¤÷K“àSgnؽ¿-˜uÒ©ÒQÒÁW¯^5Û·o·ñ’JKK-û‰P‹/¶ì'¹®á~7MÛ~DºOzDz7H± 1Zî‚)%%%6X:…€*++3§N�"k_Qfo[,ü’”d $k ½¡ ¾&…{�qc´t¨”ïkxæ`©yÖšËÆ† ¤Ë1oiîz|ð„ÉBë ‚û��Ý|ç¾oÚ±C/n·¿û³³&Æêt Ìȉ4Û°g¶…wûú÷iã8þMlÙ5“i%þcuä­vq*]P÷& y·ˆDM!M2 §�äävE�]0l*3¢Økí»â°3ÑIªhíÙ²Ÿþ„ Ø{´Ò¼º©Â||U¶\\_UƒQ£Y½(Û¼²ñ–©©©7w–›Só´ºNhôb@ Ê™¥3²Í³ŸˆõtaïÍð©OõY}Ì,èômƨN0¨p›¼¹T¦™}/É(¹÷ÁVÌøÞY&�€2óá¦Óûi¹°%bBÖ.z—¶q<†3@8a€ÀØ\01¤x&Ñ„÷˜}p39¦¬j§¯4X χW\[8±[8/™òpUñ€þíã½çÚÏèØÄVÚ&c&Ëí^rµsçÇûãϧXVÌ'Àµûg5Z�ÉmÃ+Û‘5°Tuxáz϶Žý€˜n‹äb÷G?h)aÑ|ñ¯j¬Që/K_¾Ÿ,pòOŸI± Ï¯ýMmsY�úR>±Ó�?½"dãC½®X`Nþæ…hÌ<Íû…ñ�} H^0Á‰;;rø ÅpÉ�¢çÃËb2ÆwU`¦Í˜;iniÛGáüŒkv~uÿ¾2"CÌ$@0âým>è�\”  ™:=Ï›Ø8zÞ1¼ƒqÞI£í"Â�ÓëªçX¡±çÊY·e=€ç3rÓfœGz8§dš!ã2WŽ¿%Ör•9.Àh×ásÿü Íâ:__ìA�Ï�œaÖl-Wì' œÑ×÷Ka¹Ü�&%Y®ä l^‘Η>FÖ»½{÷šÍ›7›áDzÅñïq¿#v’2ƱjO{Ú&=+µ;½ö§LÒÉó4=0jÔ(hœÂ·ŠŒ}€jÍxÈì–ÞËn!-�ÂdüÙׯ›%b?VÃn²U`EM“ff*(ùÖý妬­5 Çž€F½0Ús[²eè€[`¬ÑÈD,'bmÁ¨ê(èÄ1oV4üÒLOeܺ^†<Ùå48¶ÜÞ;/²ßÐ~�^Ÿ]µì\i0(–MmÝvØÖÇ´×gø¾»Âþ쪰­»ùê-ðæŽéÆÝW}úzHàí`.Uíªªg»r‡¯eƒb=¹¸ÑfhëðN½°! ÁÇ„ý…b[áÒŠÊ~é¯[€9ïÛŽÿ%ž1¼HSbÅÅg˜”�'cÅ^|hNX1ËÐ5 èÚ�þåæ<€Â fb—(³.¥šC´>[`ZŒ¨MSnº*_z$bÏN]1>Å&U.¦Ù{Š¿Ö“B½OÞ6ö“Z�„^›†U9^õF=Æ3˜W¸*ÚÉa7OÎøÇÄ�ã VBŽ!y ægïFí3ËO¨‹ù­T»Ý‘ó‹�S3ö9à‰ÏL¬C)é&¯h±P3Ìõ3[ä5÷T˜ÓÒì˜ÛÙ±‚rPÆbÅ�šQšáÀ'=5Œ–pÌLéziR’5àj€N¹Oú†tŽt™áÞyç3~üx³páB}…á¡ù‰²Ç-X°Àºß)8y‘¾þˆt—ô]i vÚwñžÊ2NÿBÈpWY‰G�h;(,¨ÂH‹ën†bi˜Ò‘ÒaÒARØ'¸A9w'ÀöA±w¨«˜'Cównbê^µi»B%3ó¦N©ß‹ÒÒCÒÒ#Ò«R™ªI¹j`œ®à‰X@V´Ôc”°PÀ 0ñÌm êP“�õÉT=;l8;zV5hjC# êí|tú˜T3|HHk3ÊÞª–E\ãzÙ±� í¶Þ!½“»³é\±�–Scó …½ÌkDÇL×âLfš6Ïj¯×6Ý6{�UèùÜhFfš’‘Fg·×’š¢EººË„fevîÉlÅupZ«ü±ïô×’Âô‘ýõ=€Û-Î*0…ݢ鰚íºé]RÖÀ@Ÿ¸0ú?—~Kã‚à þbÅc Üd�jOhG€KçT&€\þ`<Á!FކÚ;Ng'.Я=¶î0ÿøRËüæ%1;œÔ¦Éµðdƒuw‹Ð`;ŒSl+ê«;îfÙ åMØ?†æ·^­³€¬¯þâv}feØàRç2r¯¾þ�Vú°X‹&)ùÁÜ�ùÏÖ5ƒ|ÅÞ{úÏkz �ìh�H±xf� ©5*8vKŠ76vô˜¸máv‡«i[ì'€ú<Ì<@@^ç~Èy6 úẨu“kë¼ôOâ™=4'dݹi2D[lKhÿ°r«:>±Ÿœ}îí¨�ÌmÜ/À”Йýüç'ˆ<ìT€ªžls+ÄD¥n‰¡öo¯E-³ê¦ÜˆÏÉÔa¡€ØPÃòƒ61 €Q¸#2>vGk™¸Np¨8ͦJc³ŸÅXýöÞzo,my”Å=¥¦í&=·Xì§GLÙ¹íjõæÀÉJ³ïx–\ç”òž¥Ì.HžÜöfOJ7Þ/WùìX8\‡Y)Ý íÞ¯³%ån¯žZoHH?%¦S†Ó–-[, CðñÜÜ\³téR˜OfëÖ­LbJ?,=,½"í/Áž$µñž’X†ÔÖÖZ°¬ªÊ>˜�ë«3|Íow¹áÊT$-nRÞ£R€&@&LhF|”‹F¹7nÒæUDËg÷½6éQaLa°âŠRÇ£ç¥{¥›¥¥´¾OÊÀ¬€Oµ)æ³Xd‡±Å9•Òì<€l«®åñœd…F2¥F䮥ß1'9pß2€b�_†nªß6X€‡ÃИP|à°â}£/㉿e³c“Ø·î3禀:/›¼lΘ¤óEë£fôðLóÄJ%+P(c¸±F›ÞÀã€kâ{'o3üÊñÜiìï~g.�S&íKµ¦²ºÞ^,.æh~[„}ýÒê8þÜ{ÊÁ{þ4Õ•û©é—–�ö]ìb~ÖGÿ-çoy×ê0úš{¯¾-’óŠ;«µÍo¤ºÓ,‘–ÐÎ]‰š%Êv3(7Ô<ѧQ V°î ;+Ì-¥„»%öSiqº)•ÒÊð³K}P}¦Jª¦¡1í.]FhýûWbIÜ:m†Mø�‚¥Óçžkk^ÙÖg.Çq À˜1Ÿ4J±jÄ‚rÒTfkHÅÜuÛtô•`ÇÄ>"K†RG€wôø øp0µ`ùÅ®hTÆõéºÜSXÑ'Ã.%N1^ÙÞkÚ%÷„xQ±Çc°§ÎvŸPÆ;�7‘xãj£Í^G»Ž Ç'¶Í�c­¯¿¦²­Ý¥ ¥ú|òR½ŒAÍ@šÊØÑcvv;Œè/®›ÂAAóâ–úæ6ï?å„ €¡Êö~¡ý0|^“÷ºôôoÓÞ{bÚüO¹±Šió ñÁàã¾ëë×�/ ›g‡mûØ(æ�ÚM_Êï}2"OÈ‚+¸y:éërp^ú€�@GúÝÏ6ö,û�kƒ�Háµ3wFï•ÉýÀö3bÉýö“a˰¼N$…&�9ȸ+�Œm«äÚùÔRØQ! vÀnJ$¬^Ðúôú=Ñ6Ýýüûg¥ ¨TöÁÏ ÀdìqC Fê-ÙtÖ0¸â]#ÛÓ÷Ü�‹!¯]ŽÍ3&™ú±Úž·µ !ã"ÛQFÎãžÄÝ�1ÝËì߽ιc¯Ô5e§—x€ŸŸ-ËXýöž†f0:ÑšÄäpãì&¿féôiiŠc%ð¨­:Mt<~ãyÂÎNÖh…ÒVº`v :­×+î1IIÖ€¿˜uL”Žl¸1b„!€7F+ÿP9'Nœ €7À‡ esB Ó¥¿d‚Nü´Ê8jÅŠ�Ù³gËNµeæ“´@IDAT&ÃÝË/¿lNž< €ö–¶{Ug†Ù_E·`l%®a©ôIé¯J]úkÒ_‘>&].…™V*%"Í‘h”¶Ì&–eeÖôdÁDwDÿ5þôœ ¤ê¡“.öš&MO šLi†¨(YZHÈM ›<�?y©¼o[³õ[¦öaq2 `0õ��ò•² c lKÀ±aR€ÁÒÇ¥‹¤üvM ­e2 I¹«k{™¸+SÕ¶D- šûæe›ùÓ La�lÎü“'Fp^¶^s"&7+bòõyP®bfGLV†Ú‹ÚUº4Mm'Um.EL"’¡¤‡kõµî\–AÔT zŠYá9Ø®jK¶·ÚÞöÞaí±ûX�À!o´XàÓŒ ¹*Ÿ:’zP(X«]gÁ)»�šæ3ÌiP@œÏÍc›ÏO9ôAd/Å‘”ò�*e´exÕb÷è43¹$UǶäîÑm±û7í©´ ZÓEìÔëËRïBä•õ]¡Y-è‚©ò—R\‘k7jÍ÷_½i¾ùùÛøéßCFÝ??Ç|çWìçWß-—K]¦¥Ý5uœ:Ù%5jT„šH¡.ƒ¦ø �…ÓÒͤ1éfÿ±JS}û²9ýÞ?›É«ÿºKõ†‹YXQÁ �ü`mT¬ƒ–Nì¾w¯”‘•z,¬`ûשÉ2~Öìl�ÑѱgéÊŸ’aÎÊýþ¦óÿþv­eù�ßSïb0„`+ÁaprÂû¡bB,W ã\M'`«\¸N:öÚæ��ýý�E\a¡~YY4Öm9Ø~�ÜC ×»y¥¡„Ì ÎˆvHîl0±ÈÒ‡�G0^ ;�Áù|ç/X7ßã"µ[mÀ1(Üý§?®³`!Fg7S,�q�æÝ} Ö�1Þ1}wA÷€{6JõÍ Š+[¢}zë7€?xñ“w¢ÖàÿÙÆ6*§ ¸‘¥é¥?`ø·ßˆZp�²¿d¨ÖÇÿàs)š4(bæß·ô«xO,íiáá èqMÔë!¹­Ç,ÎEŸ'Ûå±9ËŤ—ÈÍõèùÄe�ù‰›. JÜxã;:‘,¢Ÿ;÷Âö®¹R'2Ê£Š$þÌìKü¶r«½YA<©ø}žú&6ßÅïãÜ�•!ºoôtŠ—¾LŒ²¦Cž½Úv]ñÌðhûb“ÊÌa 1€>ã/uHíŽÀœ°jYÀü|“·²Éñšž©:´ÌC“™_j Æ>hʯ2•¢çï=ZeŽ�­3“J´@ÔIö£/}p˜b|Íš˜föÇÆ³±9Æê•yÂ)¾HJ²|5Àâ]éëÒRM9¸«½ÿþûfÚ´iƱŸÒÒÒ¬ëÝ�Ìš5k‹¥^†¨e?íÑë1iH©Nš§Àè�‘#GZà‰BÀ~"ÞÓ¥K—L]]£™Úg«>�Þ–¹4^¯€IÓ¥¸ Ž�Âv¸al&+1#”7Æì7]ê�EÊ:Œ *ã8[F}ºöN×Þ©†ô•‘­/£YÕC‡{Üo–Æȉ82�•u9òN£gTâ¹ó½ v<'®iþw©ªÁœWâ„3Zä>;jʪBõ� €M( µ‘Ò¥¤/HŸ—ž”¶=�ëǤÜ5@GÀ·3bWò m”[�¾áÁ�å)¡1ªW†Þ{{è¯\ÅZ7g˜A)ÒR¹·-õ›(ɇp“@ý TѹX®Á^Ÿ¨—Wx߉s­LÛè2ˆ‰4$?bFȦ(ÑìN»°ßÔ—Üeåf„»=ïpÇêÏW毨O·’ÒÁ°ãp·½›7cÂðŠô &½k¶Ü0Ëf¦›Us35ù¦ç«Óëå¡ù™ægkËÄ~Šš‡n›ƒ'kgŒK­­­‡ådûƒ}ðiSÛ¦ØÍU6£�­Ì3OTi⯠ÿžgÍÈY_0ÙCgê³�ˆN.r_V¼Œ–7ÇÄ1b�•x‡db{<ÀÉ @ †ÿ˜Â€À)¸‚ññÑ%aå÷¿Ór ¸Lô†`¤LPjðIÒ¬t¤‰u�Á¨$ø5Ú+Û=wê?‘”‰%Kká¤�Ø-­·ˆ˜Q¢8ZZ…÷@¡Ö¿û?Áò">qǶ~@°&Œ0À?@'²WaÀöµwlÿyºóþw>±AßÿòùZ 4ºcmhÔžàˆk qŸbãÓ°¢� «Žl`‰„ø=�ÌS=šîºaÍàÆÖŸ,'î=À nˆ¿*—QÇ0ˆò»’%º¶žø 7¿ßýDIJyüÙ ûÓõÐ]×UÕîRZ¶  io í×;Ƭ•3⟉¶H|¢g××\Ù�Û&â'-U^,7Æ"�y±}¾­}) ×»Aî`dm ¨«1Ö� >Ï|òÏ àær¾ ǽtÃKZ0·´eLŽ-.pd&í øtUnÏN Ö�Û©+ÂvY×A¶@@kê·GbãÅL¢:uxÆ–o¿^×)À©åe?’‘g JV™ û~lx.)Pøöƒ•fR1�äÎ 5”¥gäŒñæÕÜÛæúMû`ª¯WI1ú´4ýš”b ÀFY+].]VSSc™Ž9b l}|¼¨¨È,Y²Ä~/³ÚÔféi/Í tä¶e‚~ÊÎÏÏ7………Íñž`kÁxºuKn3��Œ^G¤}Ýî]\¦Hg6½Ž×ëp©FEë6çÀ&}ôDL"±’»OL¤A ³0Xl^óô9[5ž/ÆÈ ÍEr4eÉV»¨ˆ„l‘$ëös‡�èNa_݈íFT÷¹e£;¿iùͽBðl™Jx$× M©¯+]éiÍOÞÐïµzsêVm°¢¶^¥¶L­…z�&ý˜ôR@¨óRW½MÊ]V€‡%Rk7Î )a�ÜèÊåZWc‚M O´¦qGñ-–yÇ·ý÷…¦‚–}åZyµ&Î�õÂÔw9³éÚͳã`•Ù*öÒÅ«bHi1ˆFJ8á¿&C`ÒÌÒtsÿÜ,3D >ØÈ~�… 8Ç9¨™ ÙÓœw W°�›%s§&;uˆ¾¶mc _[_•�±ú^™vÕ‰�<ƒ kçëg…À'¤Ñ0èƒrÃæØ¹Z­¨*€š¸…Ä)\633*†uºžu©Ú„†sÇ<œ†6bHÄì:Rc.]«3õµUù:áÃ:vû†¿vo–«šàÊñÓwêÛ †Ý¼SÓ®�UÀbô8¡À(n^ûÄ4ˆ'€?,àwجæÿà­Ä_¼cuæ;g0>¬ÀÁ•{ i¶‹Ÿ “£X!»ƒL‘Ó—©ùÄ‚AÅý%u;, ¿`d“ÅÀÈÅ"òÿûCñYbào�X+?•‹Ë1eîÃM  .fœ�Ý­G?S †ÛN�m'Ä ëŒPOÔ÷Ä"�Å»/uJwê¡-��ñÈܰu7<¢ÌuN:›vÝí×S¯ÄzD€*n^øÄ)ë¡�ÁÚƒn Èáïs}YÆ ² ârêÚ>ý·Þ¬‹¶beõf¹èдgŽ�Ï(d ÏSOÛ+¨&‹…1Â6ôKb˜?k¸ÜLý±ïbviþÈñˆ;ÐO´íb]âÖO>¼ dþP& Éœ\ј]ÁzgBZš|•wâ8CšÝ‹‰qû軉Ú,)(·¿O^>»^.ã–ÄÓFA:ø5}¥LîÂ0  p‡Q+›ÎÆÒãü�•ó×EÙAŸ‹_¯íðKq'”âæö•ýæöµÃª#̸ ˜KérG'¶TûG‰Ý‚1 †Ä =óO_´˜€ž‚V¶ë﹦÷É—d ¸ •ieS§ÏÒk .v°žJKK ¬'\ïÈ —““c3È?~œ,r¥ ¥¥})¸ý=-�5yò䔕+Wš¼¼<û¬Çmðµ×^3û÷ïÇ…�²}WzVÚ›ByJ¥H?'ý�&ý„^WH¡Š¤Ô@ „¤`žæéÅrOš>$Å,‘n.I3�‰õøa¹ç¬�bViÜ6³´¸4)?dJÄ8)Ô¸�¯ð YzÖZf“žy¸ 1Öj$¶®†kô23ì¬j—„{<ÎŹÚÇÈ7ùËJ²5†‰²PÙµgèÚr¢á}TQ×ÔÜ‘ë/”.•.�òô;#ÕòGRî«2}E Ș2&C®áib$©ˆ d‡/õ]Xö¸Eâyät­ž‘Õv^2Xî‚°…™[ñÛ•šw¼ySîe·ÍÕâð)Æcm]½ŸØ“°ÕÅúS,§³—µø|)j†‰5(§eA©»ãPµ)»¥É¨jiÁ” S4$Üæ\)nAïÂ/åi+¯›sõº;¯|<ž“Ê:LJ{5ÐÒJÚÛòîÿý²ŠÈ*ÔJŠz½¼Îä§jå3ͲVøŽLi¢y¼¥€ã ³×nևÉÍ †dpÓOâ ßLQzSô˜|{‡´¼úæ3lâc&%CãP'(2ÚuuõšaŽ#ÄïÑs®Yð¿Å`�•ãg/ñ@ü†b©|ý Rº·Äa[ ¬DLƒæƒwá FÌ衹ƄÍc Ãb&y€±™ kÆž8 `Œ( ÄX—¶Š!ÏHË(Öø£~R`ä$Êzäa,>xVK�¦2@K¿p˜°«Æÿ{O¾§Ü¸Þ/ðÀÏ”à:~¡¸N­—Ø2”µŸ† uE\¿Ñ{ \ É8×_e€€…å/Ã�Œ?R–¿‹e±¥î�Ï´ÓGÅ#f=BÛàøþ[b×4}çýÒ·Ÿ~ lÈÈ ¤^ô%` èÉùŠåNk)ž`07fal?¥oÎ'·.×+>qøÇ¾xÇà¡¿0æÑg`?⢛(ŽÝM�9ÎÚ‘¿ßÅ;¾ÿ;®0�ØgmÅRb\Á—ÙD"¿¸:bò¢ú�Ľê ã/§ÿ=Çlxb!×ëéxvp/xVr_Ú«gÚ;®•kw‘ò؆νWl-è(ºDõusíäzàYETJæT3ndJ—®– b¹‚°ï8dYË4@æ<ÌÞ•&%Y±5 Ç\ëþ…;X¡€%;W)))±YäŸÐŒ e„uúôisùòeµ4ài·Ô"�zí ©“|^:N™ø‚dç“û�Ú½çr÷ /Ø€ã*ómó²´§ŸŽºÅÒû¤OK¿!pzJºD:Q:TŠK]jJJJxÈ�ÁÁI“&™yÓ'™Õ³'˜�Ï+1�”o2Ë êÍœüzS*VIQ¦ÇvÊ\R ·Kê×:�eœ¸…22ÿÖPªØPS¤x›3 Âf®² 2#æV­$jÅ}\%¥Ýa¼^�vcDÕÞIééàÞ|NJ[6s&g™IFyÎ TáùxøL�9v¦Æ‚IÙ Á1G >šcE½´±Âì8PnêWsÚ´€2€`X2�q°ªªÚTk•ó†b)Ÿ¹TW?ª0¥NTØÎWÔöé¤; ¤¹¡D:ß‚©™¤â§�,õég•Èèbµ›Ÿh¤² Fžwë°t×T9•u¯ˆàó�Ò�K§�̾´á¦ytq–€#aÒj õrÁ›5!ÅL›nv®°�aý{•�Ï=’£·Å~2‹”Ù`üètsHÙxªo_1±±¾~ïß[æù_îKáÝ7]njc°Rœ׬¿å•mQ3BP@XK¹úºLôÿÏ #îÖ6•Àœñ!Vh{^æ» ÏÉ>ÉxA†6ØùBö÷XwÑØãð �xó�z¼ü¬úÇã{¿ÀÀ$Ëß_<_×̶­îWþ¬%˧ûDﺈ¥(<BëñÇíÇ52ž�I��ó¥­Q3g|P±îúæ¾Qöz–¸,y,^0þÎ�;^ÐfÀä93¯TÌRÛ–ë¢NO °‚áÇØÒÁ ¦d˜¼áóLF~±¹}õ¨VJÕnöWZúT-ØÉl'NÂöÚoêØ3rXªVwÁlŠöûôúÒÓ|‘”d øj€‘b—ô}é4µËÙí6mÚdŠ‹‹ ™äFŽ ð1§N�µ 6Äjééi_É�hH$ �5ÊOœð‰r]¿~�òRà=R�p="y:  Òâ&�ªW®_OBËæa”·!‹Œ‘p†™5{†yðÁ•fâÄ)fDáh3løpy¤Y׺ˆÜäRB׫¯™ª3Í•÷Ö™²=L´B”JÁLÝYtˆ~’ØrËî¶q¨`m�T¢†Eô˜}>Ŭ‘á±¼.EË©ÃÇ¥‹¤¯J¿+}Oj.½&¥k C§o‚šdSÉ®ä¹>�…òC\pד ;#(ÄtÿáZ¹Û•ÛX¶S¦Œ·ìOàzÌøÂ3·ÞóçÏÛ*€ uúBuð‡¯”•}ñ#ù‘¡ƒ#ùÚÈbs� Vá²àá<ÀëŽþœ/·KØŽŠvÉåJã2¥13N}“”V5ÐÚÂnõÓ€ü u}»²ù(¥¿Q^o¦+æÃ˜^V;šGš–Pj£óî.ØÕz+0àƒ ²õ€LÜè+YéA­Z7˜mû*ì¾õ57Íð©ŸRn !}$v`PÓÆ0‹ÍÌÆBGÀØÂUÄ îQ7?pÆv÷u�¾bT}µ˜ �/T `P#ä^K!ÞÊ«äWäKLŽ­{X�a?Q'¬Ö¯…súŹ“ÊÏóoC½Á\€ FLPÿYrò—›m0¶‚üøüÇéê{®å:çÎG¶(²}ÑözBlÛÑu”(ð1)×c÷(žîœÿ×S[§o‰Õ/ãXìþ}õË�›kwÕËm¨‡*§ …¿©X7‘^»»ÁfëÂ!º½ ýç#‹Cæk�EÌ ø eš­­‡äB)Ʊàˆ7„dÚÆ^“k)±–x?f˜Ve? ¦”·¸+wµ�K¦ÍCr·el ŽèŸœ#žÐþ™ ÂÆ\®¸N$Dô(Ð>±ñáb�kï²b�­SŸyqsÔf]tL§xý盟Ž(XyÈsõµ¡X�*ö ÀŒ±Ši!6Aû=°‰ý[Ë_´þYŸäëÏ8BÛ$[(ã Ç?®@ûÄB: ø@€SNkþæk)f¸@ËgþªFl"ïâýR̤Ncç^e½#À5îwñ·:~›8Ré²cúpìö”ðã=�NÛŽ(“�@'˜h±v Q²DâZößk™³wï=¦ñ=$”ç²@ZúÖ0Å+‰'Œqôu@5ƾ{­Î‚ƒ!ï/a\|úÁ°`xl1WŽ?y®¥®øŽøPg®*Óu�­ ‹²e¾åöêæ«:Z0”fr g›œ³ÍÕLye½âET˜“ç³û)¢çwK»ëÈÙè»0ê`?O›f6í²àû¹ÒyÒ·:rœä6¸8£+~A:Cºà ‘‚zÛäÎý„øJsæÌ1»ví2o¿ý¶¼IÙž á.éeio áXiúp¹±¹@ã€O×®]3.\ Ð8ç‡ñ$'¡€î–HI—I ¸^$ÕìÉ ®Wûð‡4_ C|´ÉJ)V|Ì‘¢<å陣nP a»™:žïáSßPo*«<ÐéÎ'�—=+Z§xx7¢fãÚfî’b³tädÉÌóÀ'�ü^7’QÄµš«…ˆ yifÏÅgõÞ%›�úŸ %–ÖjéϤÏIOJ½ Õ›¤ôI À¼Ê^QÒ�l½}rÚÞ= ,y'<×Ñ#çj´èTo²³³ À6c ðtãÆ ³wï^›EàiÊ”)6`7¿Ê×Ô4ß–wQ©²ÕR=1Eèé�Lwhü-§å§'vn!Bœ¦|¨>s‹~e}s+4äÝsBÓþ‘ôW¤ák7ëÌÖ}Uæc«²[M\\�i^XÃTÕÔË�î¶&·yš FÚ�PŠ,›™!ðÉ[0½vôuS»âº Ed Òû@8 àÁ»yï{ÆÛÏd¸Êó7”ž΃Q8MÌ„åb,M”  VòÛʇñzîZƒ9$6 w�È„Â`;p:`c,2Å ÇÆ}oóÁËÆˆýÝÿC† Ê$1°ü‚.F†ñÔ^Pm2[¬xÉÿQ0b¼Ø4ôú\àTgãsñä ‚u·ìKö1X=¼vG¸7´M2îz•@¦xÆ!à²7)&NÑ`�æÎËý8}¥ÁÖ£û®/_©ß¡XüÁø¿¯lŒŘñ×Yo—)‡Ç‡Ä†ÄýÇ_ÖÙϽíºJü¨AŠ ÐT�ãµ7A°™ìwúž{H™¨¯°ºM àÛºÝ{WÑù¿¥=1Æäih#X8îy³Ç‡lÿåžÀ¾„…FYZóñº€ªXap¡/ãúDZc…6 ›+ѳ›6 #ç=N¸ÒÂÒ‰:¹c“Õ�²À›ºu™ÿÜï=ùJ9ö‰Ñ¹xRÛ™ý—G¡.Œ€*êéκêÉ2µw¬bÝS}ÕÊôǽI$ÜÃxcJ¢}:û�ÇÓrFš‚±›ë§7k�§ÎfÒÙ´§ÂŒI¨™Î ½¢@€à¼Ééæ½2Èëùj„cnƒ´5Ò¦/’ò�¯PóMÒ—¤ÿƒµ¢oÞyçËÀ Á½ &ÔüùóÍ¡C‡ÌÅ‹5ZšÒµÒW¥½)€ChjQQQ«xOr47oÞ¤|\ÇaiÓ’€Þµ£íx)åE¹(‚ƒÃn‚²`'e!åI—+�ØMŠÓ”*°Iì¦41�"ÁÍ=#Úˆ9‡º½Ê‰±C›J¹ î|eüçQ½åez°ŒÍÔ¼š"6Jý¿sß�ü W‡p…J6fcAMÉO7;®¦˜×Bí¾\ªŽ6ЮfKK¥OHŸ•þXz^ê¡·I饠OP÷ºC 3B&O ÷B«lu jId°»t-*û¬ÑÚG ³AÔwO|_¸¯½{NÖ‹9Ñ:î å‡qÀ9ÞØ÷U±Xí÷Œao ÆK(0?~1v¯ö?ÿ­Ø!#åuõV�â¾´\OW�'ÊCùJu?¸6â8Áú¢ ジ^éb]æh«Ä™lu€ 'Ê(WÊb®w¼—å*ågµ´U=³ •ÿñùÛ>~ýïU˜&Á�ª§cl¹cÇ{]1=h~ë#ó†€Êz¹eañÝ^²îîmœØKÜú®¬•N‰‰°ã@&Ùíº£Å»¶î|GYi[™š‚ Wœ 3PĈý‡_Ô@[€±¶w¾='pßòâMµµ]¼ï=€«^ã‰2—ƒ5 8Ø`eÀýÛ¦1‡ØE±Ê~ÿ;µ:gëm½_{ö/}—]Æ´‘bHƀ͉Êê´íH4a]ÅÛ·'¾c,õgË$¾õÆkÿ‹VE5,†R³Ì Ñ÷™ì!¬kû-Åeܦ¤•s3•ý® ì']Xº@ùb,�‘jH"�5²T:AÊ\!)Ɉ­ØB¯IçKŸ�`ÅíÚµ¦°°Ð2p¿#îÓÌ™3Íûï¿O滀¶cÙê>évéUio ÀÑ �?@æ)ØXe"Ø8.1’2éA©ýÀ«eÒIq«p‚a£Ù„gO§(HxjÊPei­ùåh“.° vSšìF0©¦ñM/v&ß–)�>tGtP=ã¢HÀ¢ø ˆ»RÙ³&_&ìŠ"=g§™Í—RÌ¡]« ÕÖ70nÁÚœ(}Lú¿¤/IÛc¶i“¤t£²µ/ýIJ¹ÊĘ¡Àö“»qÝ8xîʼ’ùÂ¥ÝT¼dærKÄwŗ£G�Ú±E l˜Q—.]j`\T\¼Àرc º}ûv @�»5Jhim † aSÜ¢[»sÚÈ?�&E�5D‡m‘½mõEËOÉwþˆ1÷ý? è÷¬ò@O�ÉUì=ZiŸ®5ÓÆ¥¢ù#©zÌÞ¿ Ë‚O|³NÕÇïϱ_¢ç+¿ECÂfú¸tóŽ\ïêÌ…ýÏ |zØ··þ ÒÐçÜY8ÙµXÅ'“ßÃrIò‹‹—¨Û «;#j�ÜëÈE¼Ü|�N X¸èT—•tXNÄ`ÁxŒW¯€g0Έqƒ{•_œp-XqA°ý¿Ç¾4Á%ˆóQ~¡ÜSäÒ³aŸâÐhL$¸îPo0Çb]ӲĢÂ-hín ¢í'öÈž§µ“X× ØíÚû Àp4MÀ̱A[o¹�ráñâ8QÏãG4Zvܬ�6Ǻá!óÇxÈHzô­' YP¬Ò¿{nU\w"¡½²uõwâ’iQÄ2+¸çerí!S ' •Þî®Wô)2ÂG fñ™87`éÝ*Ô ã Ùƒ³=—HúÁú|®xñÊO»¼xÃØq�ØO´ãö×=Æ�­‡l-`GìFú9,½XùÍ'ÂfõܰùẨ�1çÄc¹O½÷J¿aq"QËIM ×ÒWB]ÿÕWRlÆÎ/ÿu�byygf,"ÅÝ$Ï4ÎŒ[mn]ÚgÁôÓ—ª@U[ð©³e¥ÝÑçp½Ÿ79Ã>U…QKë#}Pº¯³ÇLnÿ�¨:è)sÉÉÒ UUUfóæÍ–ýôðÃ[7ØO0�p¿Óê¿c?-ÓöoJß’ö–@ä�0  C‘xO‰I—‘ž”2b2†5óˆt¼ƒš•zk[FÂ9&3¥HYèÆêµX®uCĬ&eã65�jnpsC—{ÕAzJÂ)bÔ‹ùÓX-æV- ºî¤=u†»û8¶Jõ‡ª@óÍGÅÚŸ£µ€PkNטc7jµõ�Ð@—K‰ËÅýüWé6iß­€ëd �ù„ÚÙsmºO½Ðú´ZcA ’·c'óÏ�N·ºØØN€íŒ9bW6ºë58räH3}út ‚; ¼ªVÃŽº¯—O�Þ_ì«Êc^£+Òšù$ëå6`u±ÂeFܳò]Ùÿ!Í­®iPTaf*h©ú•(… Õè Tsùz�9ªÀãûŽÕ˜…SÓ,2Û´YÜX+ædꘞëÝeÅ}ª¸~X)¢KF¹3ÄݵÓ_æéÙÿ‡ŸK1ù2V¿$£Á¹=|û ¡Ê2^qMØq‚¡�A»Pî/lŠÆ}ܶñ^ÙVñvÈ6å5‰ŒE‚ÒT¼@'âžØ`µb:a<&:0ƒ—bÁ'ö\[¨W=„ÛJç k¦×óŠ™Äy ÌZ8©¥>8€Ù­[D¼=& e‚¥uðL½À§Ö]„ã�.�ø6¸æÅ“,=¢ž\¶´Õ®k1ìžSq@î õ� ÑâÉ!à}¸À@X2Øúz§í`Zq?Œãg8q?=PP˲Zá€:Jà^qí½-dÓ"#â;{š]ì~ç[5 .ßÛgo9þÐ\ÍÚæ…-P¡Ë·Cï‹]Ûã.«xˆî ñ½HP¢ øŽå;ðJswÿ… 5YÉ P?etƒXPÊü¡~œ\µì'�§À<^wWÌ8wBŒ*Ž K�1‚xe´á¶¶€,Çî/!CqáhO­ç$^‰èÃúŒÛ¯nïúXÐÙë£>÷G $wŠÇ~JIÏU,ÅÌÅ}?17N›²[ŠI¥,³$)Pzãxàc¢ëáj³5VΑ Àšm)æâUÑô„K�>'½ MJ²bk€†òºðé«2žrI-¾eËd·¤¤Ä2�``xM˜0&±Ÿ¦iûåÒ÷¥‚Ü{\0„�2qsaBa¤Z&üöÇþ¡a/Ÿ&×)½Þðyè“a W¿Û�;$FîJ“År pÂü÷˜²Û Ê0Õ~y$£æcKCä(VÀ:Y3¿�±÷ò¶zË®Áø£<~c,Þ¾±ß±=V®�ÀÊ~¡N8&™ìNû )· †,)ÌÉNG|)Œ^ BbÒÄfÌ‚áÓ¨@˜a”?‘Ê00¼75¿0 ¸- „ûÂv¸‰QF'¸Œ±‚÷Ý3bÓtG¸–1*>*&Õ#óC úÜt_˜�$% -ÜÇp«IÄIp˜ù‰6äo�Äd2ü…ÊÕÓAñ˜¶ä—J´ƒuÊê×[�¨ Æ?UíÐ75â;ô´Ðh‡ÄU+K졳rg%K}P÷Æ r÷"¿_æ¦ÜTkÔ^×hóŒ�ê•vŠëà¨!0{‚68{[ìÀXœÓ¦Æé£î¼¬“•i p�uo¥|ßüTŠ�u¶_¾cãš¹côæk–L˯+6ØgW†Í+>c4ALJåm¿�Wî=í÷`ˆÞT(Þ–]ûn±ÀéßøMl:À8÷,kËõ¹kgiÚK7–À>�7í«ýŽ;è>«aÅô½vÏ©íC¡TëÖ~íäZ*­¶“cŽssÑ%Vh÷8¾ h§¬X×(ƒãû‡ªÕ®¨{»š ø–Ô7ŠóSR’5`k€ÇOrqe­ëZ6.mY£G�6Æ ÓóµAm+"7Œ°MC®Tä´ø) À.i;3mÑ9™¤Í1†G,^¼ØdÞ‹F£æÍ7ß´Ù÷ª««)ƒ¢ÌY÷ºe© ä¤�5Csî3Ãr0yi3MZx¨Æü¦8Nt�~–zM¨æ..1‹fGLåÎLõÅS;¨þþ/[?W�==µ !Ð ÒÜ|š²1OÈ‹˜ZÍi/W6뵤cFI—KINKYj “Ò½À–üŒ¶l H‹ 3Æß#àÓŨÙß>e |Z<5C6¥Ûù«:q˜PXƒú®> ÖkÛÙnQ-BE5W‘KP@3рȃŠ.§¢sac°n°,ªìÏdkfвpoçÌ"–*‹röý•¦¦Vyr@/?“&çMÒÖ +÷²lÐÅ &0©Õr ‘[Ý„Ñ÷.™•ÔéãS”Â9Í:Ui®\«1ïî¹33^[ôðÂLóâú2SQ¥øKW™«Ç^7EÓÿ“�(·µO¢ïŸðó«Glîÿ÷-mƒ±-áZÈ4µEñ•`HÑ �` Î+ ë·:ë¶â¾÷¿Pn°R>Wî{0e0ŒÚ 'žî\Ö†©{7ã—:Œã Ew7-\ëp%üÕ‡Â6;žß}Íß…½Iy¾Wàp=œýµrbíp;‘P&bWíSœ™qÃ[oi]ït‚˜“½î3b`üÅóuæ�}Ö˜±ûË×zïŽ}â>r/`9ݧ̂\{,˜ïH´Œ~Ü/—5Ø ó‰Ü â£§¾�xú�©õëÿPÛÜï=~ÿ;-í»§Î×Öq†Èd _!úã–ó®UÖA´7„û‹p…îݲ©žû#í¸+B[ä�‡Û=Ø�ÄJ8«ÖèØDFIåhÛþÖôЀ”‡+ÂðàÆ^y€°ÒÆ*´ÿ •7^²Û ó‘5üˆw\ e¥ `û¹\~· <Š>)€Ñîã b µî£î4ôU„Ä\ƒa3Òe¤�ÿë+u–QÜR©ºŸ*—CÀòqb|ùƒxs�vjŒ\$æ( ¯xâ�Í!;n_½ÕtsâmØ�ﳨS'›ô, ü†½-À“û­{¯,FÐ`t3T䯯:­Sü¤¨¨ùŠ}hÅ] K¤¢`ˆIfŠ „#šj?– ½Vèm®ŸgéUïPÆñŸr g›üQ‹Ì¥Ã¯ª4˜cšÀî=Zm–*ã,,‰ÎÇfbRqª™\œf¶í×*�ˆ²Ò¹RïH“’¬�x5 ‘Ñf°[ª×§d`…`mÚ´Éf»ËÉÉQÛm´ï‰‡Bl”ëׯÒ¶Ë›ö۬מ”b,›8O¸¼¤¥ )ŽÜ¥KxÂ%¦I‚)ÊÄœ�V*°iº²Õ�ÑB�²ÔYŸú(Ý”nÔ¹®äŽÝ³¯*CH“†âñƒL°ò’‰Þ¼¬b1>PȤPî6Q#éJg‹?Fi\ß.ˆ˜_¯6§nÕ¥8­Ÿ¿&]$ý¶ôE©– ’Ò� Ê›'+´Êþ�V=¡Õ‡;{‰k+ ËÉ1|ò–XOd~ÏÉŠ˜‹²‰´që�2eŠu«#«çéÓ§-Ø>mÚ´fÆça "ãYñ$ iÁúP Ñ†EòŠ«3ð Ö¦L'¬ðÞõsû¾é{^Ü6¼×�¹,sÀ¡B€YGôUƒ¼Œkë,¢TÙP×XVU­Ô\¹úæ­ºZQ¯Ó¼8TWÛ�®iCP®SI'M;‡u„°À¨ˆÊâwʨÿÀÞþ0ÕpóèF}¨v i×Ûx»²®u )gRÚ­Íïi9¨«Cgr•ïì¨0O,'Æ¢'4bL«æeYð‰Ï¯mQf¼%ÊŒ§a†>Ò–�1oü¨T0Í4ÿ›½ó€“ë*Ïþ»;e{Ѫ÷Þ{·$ËE¶±1Û`Ll à8 ¡É—�ZH¾— =B0¡°q·ŠeY’UlõÞ»´ÚÞfgv¿çfïîÝÕÌjWÚ&iÞßž½3wn9÷ÜsÎ=ç¹Ïû¼«·”«EÄìÔö'lÈ´w'Ûå²ëŸ—f ‘Èü®H—ÝIð}“B�/šwñöaò?J ÉœqéöÂVµÖ6Sj©À“;æˆQ# 7­DF£ƒ¡²II"MÁ¢àœLˆÛ+£DÇJ¶ŽÉŒŽ×Ü!5mŒH/bç0ŒHü|¤4—žX“|bEÞ¶ˆpÓ°a’=.ŒšÌ_4‹ ˜Ç\ùøË†ü1AÇÕ‘ 1eôküàS²ëìÈzòŒõ2E4œ"±I@(îe2óÊ qD͹?çu¿Ïè¤{Ë87×�ëæ<›÷öÎ#›úK=§œˆ6æ�ÝU.€·“U7îY m.µ=€€™ËùDø�¶¨‹›)u°Lë`2ÐÂÐ".eËö,wxSƒnomXêmN‡Û&:bŸy8d¸ø~ôß„Z©‚i�:ø„¦À´_W®½kœ¥Þ¾KÀCC£¨÷�6ú¦ô¡`z°lk´1š;æ¤Û_>r�¾ök�4šìÐë­ëÎå8ésÑ_œb”ùW~Vï˜cžx·w~Êñ੘Üê®Þ{ëýK®©o&šíºiWhokr?üü"Š:Ïõü¯Ü]áq[vkb/ 8jˆÕ[mÕi«<·ËÊξaUçöêû)«¯–00F�-×á&·šÒ%VÌ̱`8ÏBùÈ,°pV‘…sXFÎ`}¨Ïý-˜ÑOaÕåV¥Õ?�ú«Q_FÞ(áñ ‡WY¬¾Ví"&í§[4Cá›$Åv¨W ƒ¶`zŽmÝ[­öãÞXŽÐ!îPzM©å":qÜÔ¦×} PÑKþRi: aï7ÞxñxûÏØG¸¥lÞ¼](zýyJ7+mSŠÓäõ¡ l”Ž‘…«¬Üí˜ø�9sÐ˱²2Â… ?K‘Óf(Úãm#€Š)“×ÝrE�k>]�í䇠ßÊÊ ÙˆQòJ¶X¤R¤Ài§?•|¿ñï¶QÁŠälñ6¹°O+ʶ§×ÛªuiuQ@õ›”¦)=¨ôC¥”®’‹¯#ܘ†ÞSó|i_æ‹ÉŒçŒkfMKÚf{–ìgÚ„KÚ™óùÏé½·z�™Ãw¶ÅÜñ¼<4}wàŽ— o;ýÆ1›¾ºýSê´ Š_\a¼Y/÷âPaéÉ5ìÙ³']SwDÙô®Í[?~LÚPÕ ê´Áý3�bŒ"kV§¼Öëk­N\+²¦Î�òQ÷©õJbá§Õ×7¦k8ž¯K¦ÔЫ®Š¥Ÿ/oH«ª–\AM4\UÓFÖŽ!ca˜ÌÚV²Ë auÅýt¨B�…Z¦ÇË‘ESïõž·cÞ÷K—dÕ• zåÃ÷™ñ² xeÎö2å$e)�æÆÔ‘�¯Ámİg”øôæþ*õnêX±Ÿ4�èð·ÉÕîÇ/”Xiy½í>Tm;GlÞäŒ8Íßm•ø_X€À]7åÛ+[ãn{ÅG_±ªó;-w�|bZ[â½/]ˤø£bˆtÖè,ŽIüš0ä÷-n½7ÀÅ‚Iib ¤9Ö¿d :}×¼€'òV"pƒÂ-Ðiýž˜¬erŒûFWá=Ÿ`m´�ŒÂz€et¶Äì_Ã(9ðD¾Èáßq ¼I®„~cR=~X@ëâì-ÿom?Ã:Y,õÆ Úž~ªÅˆ˜`÷¹zçfã×ViÙªsŸ¼I;l„“¹/ä7™þq�0-p3|M90º˜ü29îiƒa„û¤Ÿ©÷õ§ÄPQ9&ÓÇêŽ<ânD{ð\!q…(Ø-��»°áî•‹ä(�¤Y Y:h¸"Âþìæ¨£÷âÄܘ�®jKꮚÉë�0’oáÿý2Ë µmú@KŒÌÉ 1ç¶yºX\€P‰Qú÷Nüp…ˆv÷-Êõ7Úä^Ö²-u☄Áa Í—8¿”ean ë-àùÈÛCöÒ1ûªŽžíRdÍDÆ`@êU±�è#Úc?ÍR»E«îJûTt�Ôé3‰>ßu¦i*o`Ô�ÔVŸ³²ÓÄì}ÉJ�o”Ó±8ãI`T£!ªb6…÷¡é~5�‚�ŽŒFkD²ƒýwÕ+JŒ¨Pf®€)�R9ƒ¤�8Ü2û�²E»Ë)š`™£Å|ZjùƒgYɉ�rŸ�ÙæÝÕöâ^üdÊ�>Ðj@Þ‘ëÏÖËŒ™ãÂ6rH†> ¡Åú)-W¥tX)e©HT4þ—•æ*�Ö<'÷СC†ö ¼ˆí2[ †@iié@m{«Ò¥�J]aÔSò�Ïä·?Üý0ÄÆånç>÷ËšaCòV(Sa¼yÒ$iž^u[õ�0ò Ã6 Øê�´Xm³÷úý¾S2És­dF ec‚^ˆþî´ ›Ù?hO­³=êBŠŠ×_›Ü¥´H‰ú÷„ÒsJ0¡úhMPÎúžit� IÖpÇ­‹ñ®ß(PÆÞ0r"z#X§y I÷Á�ßèüÆWm.¶Pü˜µ°ØÅð­�R«¹�˜<î3^:úèÞï¸#°ŸvÆ=Nà n_qªéàäJÙsè ÇwDdÕò'kùȧ–ƒq~ïe5ÏQ,'Žé›c¯¾Y‘väȱ ´Ÿ ²‹ŠŠêÕ³N,OfV™r±K+//·cb<9|̪¤Ý0ndný]7 LÏÖ&Ž…¯ç»çVwú|mÚé b6ë<ñ¼ë'ŸK£ÿô™ßšË½Íoí}m¹ää[1�¡?Æÿž$ú‡éŽ9©X Þçr}dâ;�M €IÔ×§3¬¹Ié´.®�g�h§Í®ä¦^keÝy�ÒÝd|ÝUö¾{ ](IÚ6ÆÛþÛäÙ‹Ë]Ã[·­Ú>x_̹äy�2¾eëÿPýúåÉ=jv®ŸhÔgö„ÉgŽmt Fo}¢%¬Â¯4ùW>öÕ:×ÖØ òê�'XNz¹(–]¤ö‚•�X/Àé7“·¦ì”5Dk4p¾t"3*7'×25ÙBb1©áË]NÿÔ'‰/ª^L¦¨8öuiGH›·¾F¶W}g{~hzoÑØ®¦â”•Û •èAÅاO_@/gλ˄·®ñýCz‘¹x`À^=¶5'#v´,‚uñv¥ùJ+ý—ÒóJ©>O…ÐŽ ÑoÍ3¦c§k¿÷KžΕË�Áy<9 I=Ϩ8¨¤-¼ÓÎÁ»å§„çm»²õw/hsã@(Óî’MAa�­Ûz!pábE®^þ¤U ]Ú´iS…tæÒ$>>P}N¸¬¬ÌiCÁnZqÓ`»enÿð€¢°ƒœÀ�`qyómÊ&AŸÄ«sCFM£>é«[’Y"^œR8õ: >œ1ñŒí9Çô.°‰º^¢xt^I#<.qNwSµd{oŽá}ÖÇfã¸ä™snRbèš)ë@ 47¦l{­nB…`@éÀ§C§k¥ï±ù¢ì74¹Þ�òΙ”aÃ…íø™:…b®µ7÷Õ �ʶˆ×b’]½ªÝ-s²íg/¥;ÖTù™�V~êu+{—{Kœl·îX_ÛG“�…“â:AÞ9pç‚í4I®cÉ\ì¸LD€_–k bµ°�6zÂÐ6$¦Èó[$(+qáÛ4¼œñºO0¢ò²x»@?оÑás ”ÇT±/ün…Lúê|¸ûVÝöá€ÈñûÅtÈ#’áÓOÇÄkõ8;€.^¯íQç:ÔöóįäöÙü‰q&Ø\D?kϽ`€¨X¤�Ã$·¶­b:8ö†!Úþ®›öíg¢.º y@‹èƒšÒõ”j,P9~ûYï9Ÿˆðë.«çÕÕyd2»Pl:4’¨_m�ú±W÷!íqÒXkkìGû\49Ýi«]N“¬íþ‰¾Ã ó3âˆ|HýûÙ«�¯<´4¨cݵœP ‚yé6CzމŒkBxýæib $¨€gÔ_úÖÜ%2Ø>¸ï¡ñÔõýñ»¥u óÁŠ|Z‘â<»·8úOÚíq¹Ò÷&2Ør^kw¦Yq;Âãç5Uç÷ÙùCψ¹ûŒ•KÓ)Z+§hD}cKð–4W®E¦L·™óÙÔYsmø¨1–[P¨r¡kªî«²Äôª7¦‰p]�À²šj«ª¨T*³ŠÒR…�/±’âóvQnBe/ès±•–[¥„’kª*Ý@–ëCÈ<扙·¹`ê#üæai›ß“}e— Ü%Æ ´š26ÃÖos…™­íç(1)[™lßÔúT ¨˜°¼¤´Ti ‘ï`9Íš5Ë–.]ª6g?~—¼&í§Úö6%ØO¼EïˆÑ).Sú°Ò­J°W褥3Ü^<½'„�t9ð)-=,J�'¦ú~-Á †�*°@ýEk¨¸¨|«ïá’²N•·›R ë‘3¶ ÝFêùr��× „Zy"bGJ#aièB½E‰zù¼Ò·”˜@ÃîHÙ¥%@cj®Œz§×w~@âo‰ÞmâL—ïÌ"S< †ÏÜ@ Ö3Øå¡Ì¶|&±} ‰‡™7 f=ۺꠥF.b'K&3'”v+MWzL)�à2™šk5¦IÛr¬Pníw,Ê‘y޽°þLÚžƒe�µ559uµµ™`r…kÐ|MAjв—͘¶hf‘”®rM]�úÃpHQÜ5>€ý¤WMœwµÒa¥³Jws Pˆü“¸>¯¼È¿g”`׿߆ßýÛñóŽÿ߇ýH”�W–l×v[­ê°‘Ÿ”u¢nð‰â s%€ÖÓk;ªmáô¦³V‚ÄöË ØM3røÄDñ1¤nøt9‹Šr©P’ϲ�«8ÕÙ©]?µ¢qw\n×.ÿ� Ò¹oêöY-@ Ïo˜0Ÿ“$"O=¿%*7˜Fî0@ï c"Ž»,ƒWvÔÙQMÔ¾ÒE‘òŸVÈ1¶Æ‰ýôÆÁŽefì­ãšÜ¹ËoLú¦kÒüÒÖ¸K¡ÿ7˜aK¤…[б=öžÀMÑ¿•zruÒ€¸¾µgè„ âÍèäÅÚîÏ=8«Éù¯6è-ÿáø„&VOÝ›¶ùñ¾ÿÞ=A�g¸R™ýh¥÷œÃUÓÛ¢û—ª&‘lî#ZW~W¤®m:s´¯Át`Ó%a6ï�Úêíq1ñÛg§'Ÿ8§Ó$û wµÍr½R#Ÿz0d7 ÈzüŸêšµ®ÈË?=ÙrÏ®äøŒ¹ŸÖ©ÜqÉ{ëBù L´xýÇ¥Ž�VûÃÕ÷¤ÜÄ Ô­¾wEÐrÅòûÎsÒƒ’îÓ”‘þ=Z>g‰¥ Sój£Âµµåà–¿¾|ÿŨÚyš½,æçÕí½1úÔI#�~ 1sÜVŸÙs v‘�ïZt¬©7Õ/{ö9‰Š_Ž¡æmÛþ2ÎtЉYPzj«�Ýýs1�ž³ª’£M,'Æ~-Vhåñ§ØÒwÙâ[ï°‰S¦Z~ÿ Š ÙLãÉ�ùâÿ[öjÉé�§[²Ô ìò˜QQ‰™ÕéÁ©‘›Ÿ¨ûå¥íì©SvüðÛ¿{‡í۹ݎ9l‘ºÖs"»¼,ºifN§?‰>ó4 �õ©ٶewb¥¬®ÄKªµJ©Á¤ !e K€ ýºÒËJÓ6åZ ‰ˆPûi̘1¶`ÁÛ¿?"àýµí ¥W”^UºœÉAÚÞªô9¥qJjl––¢(Sb‰—FJ�e½'Mè$�)܆Ò$Þ/­•Äó1­îk¦¾2¨ êÐaºìʽ©Ö<”!­2e�.ŠÓ0À�Pc@�Pp¥e¡Öž%w¼#q&Ômòn¥EJ?Rú¾Ò1%ïú˜2•À6%À=�T©¥¸`PŘm`Õ=uÀŠ®À¸á!êC“QýZ΃—í‘Ø–ã±ÎKÜÿþ|÷îë½ßüëùìŸ%Cïœ^žkÝCJyz4ë ì"&´xK°¡¿M•mû�jܼ²ábI$P‰% ®—J1ËÉؘá96bpVZÿ‚ ^Di?ßYù8Tѳž±¢Z�U µêsJÌÉɃ—w–lŽyËø·–ÿ¬Oö[ËV©O}¾nð‰Ît½ÒÛ¹#ë·WÙÞ^h�6›Ô—ÍαŸ¯,qþ®„a>s¡ŸTÿœb¿DF+ÈÖøÖy9|b›³{ž¶ñ7¶ÌüÑj¼´­ž3´Ž6J« €FM{Æ$ÖÑ–˜ÀŸÑD²»]ìÜä\…æ•;ç‡�@Tªn7+£ÑŸ½|â: räÚ¤ þ›‡Ôût ûD1îª8!>o;Žƒj¬&�%Zö÷~g‰‹®5°bNÔDzpü¾°o2ã0©‡aT.¦ÉKoÄ]“:rÍÉŽy5ëDü“ÞÿYuì«ç$ŒÝ“ÆDÝs…‚ùð….POŠ™·½^îÑ'¹>ý/¿q¿Î ¤A§ìU¹Ñ�‡Ù¢¿=ljœv©°>ûdÁn[(pöÍ•¶Gê~®æGNWDµ×vó\ï:ãÚ¸{O t©·e:€m2$œ'¦ 8‰°©1Šýðe¹œ�æ:[·-ï80 èí-`mW‚OÜ·?y(ä€îÏý gÀ…móïìW¿ä>ï—kaM$±ëgÀu‘þÆ)ntD{Þ¶lXk?ùÎ7mûÖMñãè¿|½‘]˜o“F†Õö�¹yÓ„؃—3ÆeØ( �8Î U÷Vø-§)½ÉŠ”¥J I 0¹\©D}YŽÈ÷îÝ»íðáÃ|‚ý„Kܼyó(µnÝ:õd.òÝ­ZnWb’šÌÆë‡Ç•V«”ž.°¢ì9J‹¬¢n¿Ø¬gõ¢#j………|â|0 %ìÀ§p CíN ”›gê}Ü`IädØÀ¡Ù+=e±æö´ÒÖÏÔ>~}.{” F) Û³‘ pÇ»I:°+O„í¥µv¶²>K]èDmòÇJÔçPZ­ø‘²x ÐÖWi„Òi¥sJ €)bƒ–LüÉÛN«/yTú+9û¨58óöaÙ�vFw NãÍ´H�^N5ÖëEXµÆ£ÒŒ“+=ì—L›?¥ @fÜ#WX¦¥)P�sNË\ý�{„·É­ÞiÜÀ8€nÐùðÃvj¯ls„Ô×ë­ZÏȯ·«k¹ô/•øtD®wÛÔÙ²™YÒñˆ·k¢ L´ÄéC>_Ro¯ï®±û—ç]vpËDï–¹9ö£ç4™QļšÊÓvf×ÏmÜÒ?Ѿ=;A‡ýä"½Iƒ'Ñd�É,€Æy�èãlÕ›u"ƒáÊ–¨Óh)«ÿD¸ûÇÅšùï—£bxý«Ù7å¾åY™(„z™¨: ÊûAK´šÆ¼É Ç:̲©p„»Ïí³w³ 8P¤Yϼ-ä"ÿ}êu˜âu�SúÝ’ˆ‡ÞÍI¹ßµeP crÛŒzàîNcÅŠš£ý´Qc:1QåÚ·ÈÝ�HZƒ õŠT‚ïÝ}_¼<·]¢Aõ‡÷‡œ¨ú'¿Ñ2 Þ­¼í>ÖrÏÚî×Õß§�JsÑÆ¾÷|Ëy-{Ûh7€�' úÅþÑ0Pxn³D(›ÚàÑÛ‹òF=ŸªkFÿ‰úÐC  ‰{ã튨,¸lu—`ÛòÙM�6|€ê¹@�DØ:T6gËÅìù-1ûç'ë]œÒ.?§±lM´/ŒMÊbK‰js\”=í;Ügqí£?`oÏõ޲�íT¤·Ó%+…m 8ö¤O0ÿê󦥀§úº2;»÷I;¶é›Vvn·5ÔW«i©c™6aê4[~×=¶ôö·èóTËËÏ“&”&³T^U¯ÎôG-µÑwIW6 `«Ä¶ÊÏ�ÞDAM¦ëìÉÿþ~ó‚厞eËfeIïFCÙ+踀ÍaƒBbAgÛA=ó5�×Ñl¬Œ‚–‚Ñ—”¥JÀWÔ JÞâÏSÝÉ9räˆmÛ¶Í&OžìDÇ„FŽé´Ÿˆ|W\\ÜOÛÞ¢´Ré5¥¶¦Qƒs³û¨–+”ò%ž^�=Ùä,³œðxöVV»Su5*æaØ1ŸŠ1 ÿ.€h­èT<°×ýÚ·ÿá>[Ð/Ëú‰9;¡Hwõ??Kúö•ôÍÜy].%êÜñô¬&yŽÒ„úµ"ã­? TÕÇD;sõsŠ–?Vú†Òa¥+èaµ×õeŒV)ÑØ(’W¬úèŒïm×5ýÔ§ÅÊl­†šº†@�Ò¹Ìt�OB¡Ô ³2©?ÑG/Z^ë«‘+�~sÎ�Oñ/n3÷Q+œû¼«J¢” H ¡¸Ý:?§0 �de¥Û©ó1S¸Ø ¾Ž¥Û .Oëý-”ÛÞÑÓõ¶ÿMisÔœ·¡3RcÕ«ÝxKä�Ýn´ý‡o :à)&Ä�jϸî£çøóâÖ˜½y¸Ñ1XzÊ]j’XKwÍS$#ußk¶ÓÁ]j¸@ÂpAÏ—¿�ž×ˆ5±Mù.�ß"ÿÏ ?sÍL2®É¯ß˜Äx!Fwj’—Ì8÷±œ&*’ˆß8yÈÃ¥É , pºIÐÞº (1aÑ�5)GH¼iŒèßÝuÚ ¼Ð;xòµ˜ýt-BïrÏcÆÏÆjµS}‰êº>xWÈé-®»&è—»E�܆‹�Ih½÷ÆA´-„ûq9óÜý�¸_ÿ³JúWž “æ÷ ½±§6Ä]Óü×Hô�<±wÏjÿ�úÌ:Úm�ð¾‘Ý[¦6Ûø¿¢ñöw�gØDi¡Qæùñë=yë»zI«ÖÛ2Xh­‰ê9ç ÑÞòÃD{“}Xþ± “ÒMja9=·Yf;À„L¦�Äj=ãüvDZU”í}‹ƒöOL4ZƵ#Ñdœ9S™Ø0§ÄŒ`ßß(‚ú7|¾š9•—·Î.¹6˜2`Á¤yÏñûþKQ+¦õô€QV7K€¦™gèæ Üü]±žÈSoÙ' Úî 9 ÀÉ3„í¡ÐÀÂ=�1ÜìÖŠµ† vÛ6¸c`Ý£DPÃ60¤.Š¥Óžq~@±×¥EÔÁÞ(£ˆ®‰z;IüÉ"à“·½'fÄ'® 0B[™­úçoŸÞ5S'T-]ôJ€¿ÎÚÇïÚoë¾QîNžánÛöÞx¿uå’²¡~ÀfjÛ§yç�…æ“jzë¯nIß“®ˆsr_;ø¬í]õy'(­UEmb;ååØŠ{°�üé_Ú#¿ÿ!›µ`¡ �·¹è]]®joúÖªÊ{ùé_ÛÚŸu@õcä�L{hE¡  QÔ«Ì ãŒPš�U@‰}îÅ‘žSÚzU�Úùz/j¨±J³”‚D›Cói„ "ïe¸:‹ûÑ ˆ|'÷<½BqûìÔwêÚ¥Ï(=¦4Vu<”-ðhHþ­Ö?÷f¹K‰¢�¦NPí±¡1bkÞÐØíŒ Øßn¿ýv-i¯A;yò¤­^½})ËÉiYSõ ¹6À§˜Q3æ ·Åó2­zÛÓVwÔ꟮;eÝUÔª,�·Çæ§Û¬þ�8PZÞ�‰5: Vº¹)�>Ð'ê•VÊ®³ “؃Ý%™�칓³5çEË“G nöøÈ«T/¤.¯±N@“’ä¨ÒÔ'¥7tÒ÷t}¿Z¿Çâ¿©ßJ`^W[c›wWXE•Cñ~ïgZ¦MJã5|7ŠÑÀx“ù¨RP£–Ÿ'Êý´,PŒÇ‹Dûݺ§ÎN+,´ÞÆäë-ëM¾mØ.¡iß…!{c­ØSBut°†h… ™ö.5Üî{€Ð{4¢W¡âQ‘Õ^\¡·šà2éÃÈFXmõ;Žt_4;ßßüD†˜?7ÜAtºøù™( ít9Ü�-Ô–eäí‡ËÌ6éáttâƒg¤„ÍoJ IùЬٮòh/‚“TØID­PÐú~RžºO“ûÝ-3r—ÓèQ�êd·�‰(bÍ¿�[ ÑW‹ñ€ ÙYÍ {˽=hŸ”@5 !€˜g4A÷Ø"Þºî\þÍCФ²#g%ï 1{(hïÚæŸ1�óåïÒz ø‚.‘‹Ž(ÍRµÉDy¦ÞR7†IØ>Û‡ß5Ÿp@ ¬<¯®Ã–ú„ÀÀ/\J1Î# fPoOä�ü! Ž jI‰ê>ëØ=³}À=#ÿ¸©‘€·­±kéãö:k¸¾ä³~§“r¦£ð»cBÕ¹}"èlÚUcå•ÒsÔ»GmøÔ�‚ñœ¤þ÷ݸ‘À'îÂi¥ÅJùrîbL®w¹„…lžÜ1ùÁµkݶ8šSRÞ`+å:½!oȾm�fÇ 6MHÄš-ñ}kËOYÑÈ%–S4EÇ×,£‹�ÝÿïC -–¢Æž¡›tNÍš·èLC<ˆ‚áÅdÞÏ.ñ~ïŠ%“I&Öô^Lˆa®tÖpµš7áÒîä€ã¶y'çå¾á‚¨o[vÊæåá;å—c¢é+ËoXôæh¤3„•ýçöoˆÃùpùêÏëݤ“{Å´· ·Ÿ›±lƒÜ}`Æõ–цÐâÙ(ì´œÞ0îÑÝóö DŸ×‰½ä‘-=žÃwÛ3Ú�^ä¶küî˜tã“G‰£^ÁúÙ+öYY€ûÈm[6=èêѦ«ˆ†×næ®àGçøÝ°�Ѻ‚M’ÈhkºÚ¯WFô€µä6HÔÀD³”í`.%s&÷. ØoÝTdÁ–€ú”îÛ•¸±’¯ýqˆÕ%—Jµo\*;Ûfg ”ûÔ;C®ÏZ-@žk8©>çUi‚‘·ƒb„zå‘èú;¾Ž— ’!-§sž¶«¾h§wýÂêjŠ›¸ýŠì�G~Û>þ_´EËo–k]¡ž[PëûŽÑ‡ÖÕV‰ñô‚ýâßuz6¬7"˹»Ÿ (6re‹t¥ƒ C~òœ@à8ú¥£}§TR9éƒ%@=Qc#•f+ý& 짬¬,÷¼gyáÂÇ~@%¥HÅ1—P¹Ò”®2²ÂmpÁ-68÷v¹Ù�Ð8¢õð\µÔ" %V\µU/„Jm̘1¶lÙ2':¸…ÞÔ¦M› öUAö$Ë•FTz:8jß7 qÉ-cmò° «Üþ‚ÕW0?UƒOY�•¥�(ùèÜ4›;0dƒrÃVÒ䊧ûc�:~»ÒÍJT,æS€¯)»öK`¬.A@xZÎl1Ÿ†ëþó¼õÌIÎK˜–Úq�"E5ÇÙ" åÀ'‘ùu„'”RàSÇ‹òºÛ²õÓíº»¼K.ˆ þÝJüOs³C¶`j û‰ç]Q~ÈVm©vþ©•5Q;,Ó¦ŽÉèÐä`°èŠwÖZqY½ìÇ"eb?=à€˜Krs•+. 0¸[JNË�Nb¼m]6`Ø0!›5&à\x¼Ó1ØFx‘ì«�ðð6ÿ¡åAM:Óœ‹�wŽ75I|FlŒ+žp± kâ Ë­¿1‡ÝqTnnF‰l‰„Í?ûHÈ ¼m¥Ex×»¶ì h‰™@žÛcŽ�/Üèæj" CÈ3:i&©¤DèÄä=ž“r…ü�×÷(üúÕ–}¢sudÝ2¹µ}ð® Øq-ŒØi¿”æaá{Âp­¼oqÀ–L H¨(€µÇdÜ»o=‘—¶çàÞ~þ½qPwÛ¡˜r½mÚ ½m:²äÞÄà¦S(‘ guõŒ–{›Á£b\•V5ÚO^éj­D9h]H�oƒð‚Úõ1‘¡3A¿Ä=÷˜[ñíÒ¬Ÿ½3Òø=Þ1h÷ôÍ§Õæ“�Hlóçï ;Æä.¹^ “&¬Ñ{ÅÞ|ëBÕS±&ûg¨OÂuÑÎh ¡á¶Làîf†´3–€‡0.É'ewµ3‚:Uuñ ^ÿ;ôÚW­âÜ^¹Ýñ’šˆ4!›4m¦}øÿü…=ò{±!C–ă~é{F8sâ¸ýè[_·=;¶¹ æìÎEv—^¹7 ]”mθYZ¡È¨ûj ¨¼¤3Jk»è4©Ã\¿%À«ÆÒS”†×+R#‘ç† æP´ÉLE‰d=ì$i3±-ùiJé¡`AÖ$Vx·õËš«º˜—p¼èÀ§X±]¬~Cc½ 'l¾d‰^næ€c™mܸÑP‰šÂõ.MÚ+}ÞÔQFKîgc Î[åî—-Z!8 3e=^»¦E6IϹ¹ƒ‚ªKV¬—%‘‘ΡF(ݦt»R¡Ò9%ؾø(Q¶RÖ�˜ mÞ©v˜3wÊ¥àSöOº õ)*fñ&=[KJ5/ntHÿ«@˜Svƒ–À�>q›�+Á~š@Oyº8j·ÌË�?Î~br™Ÿ‹ðxÔvb ŠëKšNs A»$5¶ÍΌϒ^}3þB ¦ì¸ _`¹ý§éXš•]¡á6ö»÷„ì੹pÄP‚NȽIo <±ëG·�àHqí{4Àx¹c‚ö EDƒµðk‰+{o£Ûq.w>Ê‘‰7ѱÆ)b\[c’Y%—#BÑ{çóo3bº¢ÛðÀ‚1Ùç¸#"®ƒûŒ 1®yèåx.‚¾Ÿ›?r.:R¢ØáêØCÛæ×ë£*EÔ„&Ípÿ^2òÿç¿’{T@ZS­ÝÇ(Ÿž2—Ï¿7äXd/ÊõÐÓ™êÉA�ùøDß™²°nDð ˆÈw°Ÿ‚Õb?†mî¤öL˜\¹â½øz¥äâJx|þÔGEì¨2L”ÅMjh@y¢V_[bƒ§¾Ó¹ä]ixºcŽ5dñkò0QnÏ`ëj„‹g<Ó%,ç@,—ÎaÏ™úfDØÇI³¿û�°ëÛüý!÷ ñîÎ$@ú{¥}ö€€'\™NÇ}�¾Á3>gj]¶îº_‰ØUïôÖ™APmØÛR§¼ctõ’ &¡ÉÏíû•í[ùE+9¹©YÛ‰H[Sf̶ßÿ£?³÷äã6jÜõKáVýbWççj�GŸ=qÌ~ø�¯ÙŽ­›u8…a—öâ]7åÛŠy¹Lܯö—ì¸ûâàÉzE­uowqó¶+í¿d‡ÔŠT ´.è…Àà“”ÆI\ÜE¢=z´«[¸Æ�8qÂöíÛç˜Q¸Ù )¼ÝHT<èç¶i}ÈÖßç[Mýq×b3JûiöìÙ6gÎÇ|â\/¿ü²cVYcÈúeÏVß5HÇô tZ®O}Kú{óŠñ6,|Â*÷¬ø$Ãßñö©ÜÞ8™áѧa¸*òô4½„„Ê—By /Â" 0¡4º´�Js•Þ¦4O ;£ÔôšÜ}OýëÛ%0^ÙëðÉkÆ[÷ÕIê&ÂfÆ�•*»þa®ƒ¦¬ï—Àµñdêúr\©C®á°Lz^X_ae• ÍÌ&„ƧŽÉ´9“ãtæÚHƒ=¯mÿ2yaÕOÌ)¢ñðæ;h•]<ò’&NôÓWfO¬Ž*l{Ôþ÷òÓ�C¡¿Hƒè®ßй‚e�Ì=Æ¿­÷™‰Ù÷ÿ8C@Vüº¼õß|F,1_ô/oýÕ,jp­;$wµ¶F±¢½´`bÀ¾%aó/ ,×¥–­Z°ÒfWXLýŒ o/À‡rOÔË�v ½)Ä’�œis𦽘<±&jú݈ý˯껡æKíæ“'�HSù„íãïhý6• 1.‘|=ao™°ïýQ†ÓQòŸï§kc­€Tÿo=õ™Hqjæ€=m€0€;ÄàkÏЛ;€ª½­ºï·…’¼g¡ ýÍõöÿZw‰ë(€î­‰@/‡:ƒ ôfµÍÓ§T}ðå´ÜúÉã €‰òèLÿå�ß¿ŒæÞ¦ÁVºirÀZ¬Of”ý„x€ ~£�þáËõö�ç:×Wû�ÑÑÏL.£u•vjÇl¯Oåg·+B¹:)ÚN¾÷1ûò׿e¼ïýVÔ°aÒvjý(èè©zd;ʶ¶®Ê^_·Ö^}é9å•çrš�¶[ææ˜ÓCp^ÏÓÇgêEsÅdRµD©�ÚÐ ™IòZ,:q�Òg•˜T!.n[·nuZO›D½›8q¢sÇãw4�‚iyJÙñ±eÚe´!¢ÙZüÁ °ÌqIååå¸ó9×¾€DÆÓÓuL¬8&yé –Êá:§k(Ó}¡àº1Ü ’îŒe¨['mÓ÷N ÙeÛïÌȳÉý3y!Dÿ¨'³�Rz—Ò7”~ªôQ¥qJ©þS…p#õ‡—ñMƧ–oÞÚÔò†*�æQÖ uÕqDþ»ºf÷”;tBa é¦�g¼e¿ç¦\÷`gÝÚ7ªìĹzÇœñ¶I¶Œ ÑZ>7Û¦ŽÃ=ZW´ÖŽmú–&j¢{´œ"Ùî ×#NûïOGÝÄ.áIV0 “[ÀoŒ¯‡Ë­í¦)ïx㌻ ZL=aèEáb“h²Dt¹‰ÒË!´=ô ÅÆ¸œqÂÖïñ®ËÒyNWµ‡+ƒ�ðüºŠ8¤©94hb±xz¶�.!Ù…Òˆ­ÜTåÞºíüƒýT( ©oS!œìü¡•Vvbƒö�¯�Ý»ü'B”Ã( _~Ã}f±ÜŽF ¼´Àýe©„©ýöËõ1ûè×"öãÕÉ'‡þí¯ö3 ºNˆõ¶5À”áŠ.G”¿�=¢ ë¥Û´Ý‡ï0ÀvH3'QĬÂ…d÷¹'&ÚŸu•ŠvõŠÂ¶ÃptªP^ózÔ¾öëzç¾CŠ MOå�€7.Ožqß?ý­ˆ›¤·ʼmºz 3…Hq~[·»Á>õ�:áÏ¿¾§?ÿÍca§›vËŒÖõº7ÝÙ`øýZŒÆd@ŽWFEyâµË]´-[Èû½»–D?„ÉC´£Æ5±O2ãp[Ã}Ío´—Έp'3€:´àÐ�tî¬Áhttú“‡Böð-A:ÓnšºêËfì é¥m;¬óëØM¾ž4m@åå½í6m¿4ÒŽª°îŠæá7˜ouõDLJ�e\Øpƒ"2.�å¶JaÝ[ç3€‘õzÚ>óž�X=A~·Ï’üô”1±ÿö'3¤wPY´ŽtX,P¡·�zx�ý•DaìŠü~òÁ�­|3Ö,V]«pÆ´1¢©Q7Yü¥b\¿3QÖ+Ñ:!4å–ÏØ›‡Zÿ‡Å £nÃ먥õ4RÀðœñ—¶YŽÁ%Ò¯RGZG¼‹ ÿÓ/•2[:‰ŒßëF·¬£í>½.Íî_²wÝ´ÅSÔþ%¤ÚЉ¼Ð©ò§¯Æ\Ô½­Ò û±\¢/맇 à)V_×xZó7VS~Òu”¡pØf/¼É>õù/Ûò;îÛ)DZ�z([W}êþù3'í‰oöoÙèŽ×//hw.ηåsrt¯;^¯$3´&ÁezÎoÝ[£q€;•ø¢Ò*¥^èÙuÖ”]K%€Ï+Àæ( Cû‰4R‘%‡.€%¨>^zqGŽ(VûŒ „(7^‰ƒ_f.F´»êú£VQ{ȱè§OŸîDÇ6_³f�íܹÓiIæL³¼Œ‰zQÁü¿ïÍ:#+h·ß=ÁŠ"{¬rßk¨SŸìaØ÷/é†É!Oh:È,€{Í-æJjž4oûg‡­2&wÐÚ˜Ôe�7îý”¦*Ý£´T MZF†ÝÛ±ë)»l Œ×Ý¢ùÄ™q�ß}8bÇÏ6K5<©Õ‡•Z›l˜²¦ÏnŒË§Ã�wÜ~"ܼ,f“#Ž6]?ƒÝ;æXQ~ü!Ž{Þë»jZ¹ç%+*Ç~5õž¥- ÿÙ½O) ö> p~{Îx¸ã³v§@°6MÝÓ“/0Æ3ÜF6îkÐö±¹zûuå78¬TÑøn«YÅo¸àš}„˜ �±R2‰„Ö&†õO—‹Sâã¡/CÈõûoŠ3 p«�ùDä.Ê—ˆmmË·3ùºšmŸÞS¤1\–zï9¸óÜæ˜½º+–�Yv5××™}Ñpúý·í´ng/l�Ùç~P‰ jgŽ}µÛ.™š®(qéŠÆØ‚ûäÛ%ñmÜ$“cêúKÝaEb¬}ì¾ €™@+%ê3÷µ3Ƥ½VQq’aÌ)poÄ÷[¡îÛ‡î Ú;І'3XSSG¥Û@�Ò—3@§eÓεîS†íιÇô¤ïhOשíq½k¹ è•¸Õ¢ÓEÙ må�óm÷éŽïxŠFì¡gm?ÀSé1 Ý ài΢¥öé/üµ-^~‹X<™×𩯳›·Ø«+Ÿw@õdÈÀ°-™‘í׋èŽbuÇägãz7:lC4OÜ=×»ÑÝvâÔ�¯§˜¡‹yPiÅòðáöaÃ+..f• 4È&Ož,Vb¡XÓå ürT}l¹ §Ë÷íqÇÙøsÂc£Ñ¨]�%:£AXO8–ËLøÇu„Ô‡34®ŠT«;KÞ÷÷�즲à+j¢—¨½ÙÖLÒK�G'í ³ìÃsòmÖ LÝ_^“þw(ý�ÒÏ”þJi‰¿¥¬—K€›tùQUç3ɼ:Ož6®hø§#F¶ ‚;ÈÔ×x Üè7_1—l¡Òîc‰¢�ݾ0×½qg Ê‹Ï~¹ �+­§}GkÝdª¾>Ín_hycð<°0d«¶T[•¢êEë«-;¨õ}›°¢:ô 1ABSe¼Äu sïyÄýw)Ü£â/{%\°£ÁÖËåærî@Þqºrùèmû‹ß ;& î®6£¶œ‘w:³bTˆ€wÔ� !„ýü‰—Fäb’_% w?ÜýL/DŽë4©F`½Ö'5CþzÊ`jà*„vÑj1®€QÞÏ—Š}˜$ ×7ixº=r[Ð�Åhf¡;àD¿ÑQc(H˜-o¬_¾&‘üý ŽÕÑctÕvO ±z+>ú²íWT»Ê ûÔ76XPÂóæ-´O|îK6o‰Æñ ×Þ“}RW\÷äüéöÃo}ݶoÚ¨ü7J<`·Ï/p/€:qË®*;*b½€’KçY�ÔÇ�h ’ÆzHéÍ«:xjçë½p1ú´Ò»”ò¼‹‚ý4jÔ(ÃÝöSƒ:@©S§O‰ –gxˆù�Þ. —€SUõ‡¥wwX:Qu6uêTíŽã­]»ÖEºCg*?k¢Æ°£ÕO6½ÁKx´¾³’¾*¿ Ón¿gœeo¶ªƒ[­1ªAXg:ê¾s97|Nè0Ø 1öDy,¶IEaÇø+Ѹ9mà­ D¡uŸT‘L(½þN1bT=iãu²ÅÊÌ™;%ÛEvïÊæ‡ûüéâÛs¤F€»¸[£ó¡�ç›Iõäå¦ÎÕÛ%@?q#Ð)¹wûÇÏÕÚêÍÕNgÂ+â8ܽ8OƒxQmÙW¥A©„Ç“„÷öc‰ûÕ�éUÙÁô”=¹í ‹ÔÈÇŸQnø“OVm—»�4Kü1v®Ä'j²ÖŒI"ì†EңŠ5Ae¢šDh˜. ‡Žîƒg.6$t%‚ † ú—;d_ÿX†&°­§=?“» çÞ4˜!‹%?aXë¼õdžˆô…HóýÒÎé ƒ¤;òˆ>™_P½X.P_*j—�xOºú¯�Hƒßût†}Z ˜ßöŸlt ®Ÿ9îÐ Kf”ó(¹~Οpuít¹4¯¾û© »w¡賟¬‰Ùªm-´ï§N}¤w¡¿ñ€­d;–sŠ?º$í꟟¬weoVDɳ-]ÛcôÅ�À-Úk[ËSäJtÇp‘]>=½0ª³0†Ëáßÿ´Þþó…¨ËߤzÚâÀSÔO<•ŸÛ­1=«6eÆ,ûðŸ}Î,Á›áÚžÐzÚ²a½½úÂsnbÎÀwø€ á.$6Rë'V÷•>µ‰¨w3&dêEsû ÕË”xc›²T $*^`~\é�JyYá�ú7ZÏF¢Î™ÓdÚ²e‹]¼xÑ�M¸áMš4É �×Ö_°ªÈqÕ{ÀÎKû3w€æ—¾¨ÌòÌmA|�Y ‹ê. ]oHEK—+âåËṸ0›Ô<59¤Ž| Æè·ê¥ÚÍɲÏéåþ;'åÚy“ˆ¥G H;R -¨¿VÂë[J+ UººÁŽ�²•#¤4îÛåÆm:Z‚�òa÷»&ãÞ6?`½•©å�S©†­—ýºÝ¯sËy~ÿú•R«¬Vxç¦6“Ðôqa¥ø ¢ ÷¼Íî9Ì]Šš—•ogåçwÛùÏË-¢çDZD¡J\ü@IDAT:%7±=mXBhÐáÜ&­žŽF{¢¼ºÂSÞV!ïOüG�½&(&s®mD¶kk„m%7&X�±‹bK% qϤ'_“WÀDÄ ØèMÃ)�wDM÷µ§êíO¾]×£îcÃÚ¸6î’®ÔwŸ¯·?úf¤ÓnYÞµ´·L+Vu£½{ðð-ûæ'ÂöÖ6@Êó[âš<í�£;C# ð½µ1f.g0�i°ý ê¸_¢âúI´¸+5ÚûÏ×¹6Ó™ó¡�Ôžª;ý³‡Cöv©~ƒÍwB}îmIH6‡¢~Ðî§Œl)À9"*þžyï»=蘋WÒŸyn†ëwÇì¿WFÝ=©’k¤·ÞŸßîúL?ä�ºqà)bŇŸ·}/ÞJÏnsÌYã§L·ÿñgmÉm·ièxíO”wð̉ãö›Ÿ=a¥%Ŭ²üœ€-œž£ès!±½÷Œq&†“FeØÈ!ÍÏh¨Î3•†ôL.Rg¹ÆJ`„òû¸’c<ÁbRp§ Ë¿GŒ&~2«­­uQïöïßï€"\î`. 2DýJ­ØÖÇÄL¿ ¶ÐÒŸ¹þ‹·@'R[|êØqÚîÙ[ß-3;èPÄêªRnw½uºø¼ÔL/Á„ʸ8OZ��O ÛeÛGfçÛü!Š’—áÞ yºP“´Û{”¾¦ôK¥¿Wº[‰iÚ,eWPn æz�Ý.íU®àˆ¾]覲5¯ µ�6Rnw¾ò¹?vßìãÚ)M½j±ïxÙݬÖÖK$Üc61‡ÊÎTDHž­Þ\%6ŽÞ:w ô`M�aó¦Ä]õp·;¶õ{rÁºÁ £‡ŒS}á}!ûËGB¶M ‹¶:%0fi2:{lÏå ÷ªÿ�¢NyOl•§Zº?:.&£[$îë{Á×\r¸6!”ŒÛNG�P툆Ÿª­EtÏž’†Òc_­s.dmï©ïwÌCå�2œ›�ÿœ¸µþô”}äíAûæ†m�Üýö³µÝãæóí®yû³÷„�ûÜ'%Õ::,·+êG¡\G{ËИúà]A¹³¶ä€çc_¯³?ûnD"ð-ë“}Š×ñ¸+Z{  \o’`vG FàŠÙ­·…Eø™ïEìK?R&»Á¸–&±æ¤GÇmÀ÷×DF¤KtŸ`=&3tª<‘v‚¼sYÐþðþ8Û ö“°™y.•úªmQûîsõöÕ_Dìr¯tº�Öá“tbCòø„«MC¬Î.yÙö¾ü+;³ÝcQçÂ0nâdûƒ?ùŒÝòÖ{t­á¤@]'NÛã›ò\ª®­° LÞ¸f¥›LóvtÔÐ ¹Àçˆ Ñs¬'.žrç¹>¨_À¦�kFý©IÕ&³MÊR%à+v÷+=¤ÔÆÓ ‚›õaŽ^:Œ“ ÜÇ~$""ÝîÝ»]T:‹ãÇ�w‰6P9c5õ'¬!-þÂÍwüË~äXž�¹ÛXÌ¡¶Qñ.{�^Ü€6Î ÊUKù–î›Ð§^ÌMêÔÝQºÅÐài�8ùØüt»lºý¹¢ä}nQ®=<9W®y™j+î©MÇ Ø4WéCJßW‚õ·J0¤†)uâé®­SÖ‘pÛîj}žxaÖd°9þ¼-RË뺚kÂu}•—¿¸_h“ÝlÕ[ÖŸ¯,“`rc ûI³¤%3räB§™œìøÙZÛ°½cÂãlÏ„ñíËòšÝù.]k¿¬AnüxlÓÝÆ¾Dl&}0zÚ n3bw묠òîîüp|ĺ÷É †ƒßý&ѹѤ!ϰ"Ú Ó\1dqnéÛÚnÕú;Ê£b§l9Ðz°G®õÒ¾Ú/ñ«ÕÕi}ÆÎX!<©?Baç�rõ{œ’˜:®Š^w·QaYÝ#·)ÀIÜ«¦ˆÍò�Q¸C>"=0¿¡Ÿô;ÿ¯ÎþëEe°—ìñ»CöîåA{HQÔüÖY—?€—ÃgZ×Iÿ1ù k ð‰¨”íìͯ}׿p+†ûlðÚ]hŠMÙÎ)`aþùFì/%¾op°4±½|g)̸÷Ýpî�ÜtÚ:ËvˆÿéÚ¨ýß'êí?~³ß(ÂçK[zŒé4Hý.ZW� ÀôQÅ·²Ò“íÀª¿’«ÝNÇx‚©:VÀÓ‡þä³vç}÷kâ™qMOÞµž>rÌžýù�­²Bþ²²~ù¸ªçÛ„áa±/íï½ýºs™/åÜã2ñ¶ùžô×ùæ(Åß"uçÉSǾ–J`‘2‹«Ý¨p0?­îOs5vÌ”OI–冯XVh�»žÊÊJÛ·oŸ�>}Ú}¥ÒÓƒ™ý²gÚÀ¼›-”ŽGIÜõ--=`µÑóV9¥gÌí3fŒ�;Ö¡LI Díð¡Ã¤NêÅYHnzÃÔЬ1-þÌ÷Üçp¥kT}¬Ž¶ŠÚÃb�ÖÙ´iÓlöìÙ–——gÇ�wn}UUUÚ¿Ðò2'©ïmfîõé„[íÈñýlé’=ð’Õž9¢ürý¾ÁZŸ¾‚T殦˜á�•«1ͽlœ7(h ‡llaX.ÐÙ�j\m`3|ÿ+MSZ¡ô@Ór’–Ìá4*rÉ7BÓš”]®&k18Ó²çLζºênºÌ8VD�Ñ­{k¬¼J/M³• }\则C¥ìZ,T)c¤`öC¥Ç•¦á*÷³—KméìlCs÷Úá�¢‡þú•2«­‹Ù{ªl—¦³'d\"à­M[“™œ¬t{ðöBÛ~ ÚMÏZeÅÒ~<å‹E;à—Óêˆí™'Aâ/½?ì@¤×xÅ'3¸•Ä÷£#Ø{¢AŒ£˜ Cî?Ú@¹°6LŒ®²¥Óâ̤B½Çð³.:3Ñ+¯n´ rš5¶AÀÏ¢c²0LÌœû—5±ŒºíZ~�âºp�úö³Q7g  ÚQÔ‚:Ý{:Éž¶/Ià|xÿt±^-N`œgçʼOÝ¿$‚Ýß?\7ì‰Éå)~N\ÈH=a€*è€e Hð ÌÓÀ4‘X|×ÕKÿ9.÷vþ¸ÿè×"®_`€Ú/ÿO× ÈÖC ¶tZƒå[×qþp3$¤=¢À¼bÿ'$îšEÔóž4@ tʸW‰ŒüDbirý¥WMž9€ ´³Në~¤'2À­,†œ4@f¢z®Ýµ£ç5Z 6ÚyA �é‡:xª¤›á6yô\Ü]”�ˆØ÷ué¸m@èµ3ØMu•çìøÖïØ…C/9FÛ1ÊûØ'ížw=$pà)yù±}_·³ÇOØÊg~%Š9ƒX}ùA»u~® ÑËšX/]% °9¸(`ó4ßuÈ=³©€0ŸpÙ¥ÔÒÈô%e7d 0†‘‘Ÿj…Ù³,# < Ù^÷× —eyN÷)Èר¢ÄÎ�;§Èt¯Ú°clꔩ6~ÜX›?W‘_�{<[,wC(}ø€ðGq$Ô²©û~±Ü9ôî8w…[#¹?§—y£ó4gže§«$3¡1ΛÅÛQRUõ=÷@VI ½#”–+Qé�+½©ôºÒV¥ýJ•¼ÓècÊzºx”g„Ó-3C¢ãºÇ›‹”XmÜöÔ½ééÒΗŸZn‚¦"öJÿªíjl½\ëV,È!ç�ÓÆfÚœI9�ë·—§ÕÔ5Øs¯•Ûì‰Ùü²Æ@úæYY6sb¶½¹·Ê8ÞðÏV4n…¨ˆ¸Mt]ûC `i³B‚'zÎrªóe�Žq„èpŽ"ËyÆÄq’˜' '¥KÿäÊÇ×ýÔ­ø™°B ÄRxò5‡z{§ëÔ’|㪇ÓM0ü5R «·. ŠýTï&åþßaGŒ;êι>ñÇlâ÷¤q_ü·üL�»_ÏæÃÍ]ÏI¨»TŒ«ö¢®ù÷éêÏ<Óîøë-ŸÖ ”; wÈÞ2€4††Š¥6uTšÜ@»þ^Q'N«Ž£ë5fpz³ètÛk†¥Hä;Üï`Ë Êþ ˜sÆO¾k1üu¬í1ºúûø¡iö¡{Cb[Òï$×\ ¯�Œë]{FÞ‡ÊGÒ_…qN€ª§\äº:úô+ïÞ®8'~[P"ëAûÛŸDZéÉ=­>Í3ذÑH¥�Ýû¤�Úö#½œˆÓ0‹²ßûÛvß{Þ'võ <Ѧk%.üÆæMöƆuîÒž'ŒÊ²ÅÓð¢h¿nxeÕ]KÎŽöÜœI™öüư�9ïîÁ(­^¢´R‰INÊnÜàõÈT¥‰1–ò2G[NXÕpÈ×é¦5-+8D/S8ð)‰Øºu¯ÚÉS']´»ì¬,;pà€ë/ëcUb6�±�G¡`¡€&õ îAèk B àDRìÑ(/â¿4»ÝEc€¥µúMý°›Û±uß¶˜Ð ]€u8£PÒõ7ÙC3Ú@8ÇÂùý-kÐHË4ZK±Èò‹,=œaÑš+Þ¹ÞJw¼j1"ꥬϕ€¯–»Z‹["å¹…é6A/Fïu¡¶Ájî²³$j{D¯¬O«®‹…µ¯FŽ.r íòA%^·SòÀ¨-ú|P‰ à?�¾¦¬U ¸¦Õš«þ å|`l¨â×u,6÷媞:À5W)ð©å–Ñý�Ò(‰ýÔ`O®*³¥Œ˜´¨…D¤ÝyË’œÀÆY zè­ÙRe�Þ]hÃ/;‘áÍz®BM¾{E¡íû m©â£ëìü¾§lØŒG¯˜ý£èý+‚ö�?¯o%ÒýÙÿjŸ‰ÁDú &b°�ˆžå7¼WH?iŸ&}èýtÆ(«ÏJÔœI:ZÖpÅ‘8™›qÿÖ특>á‰Õqñdyëîõ°œj#�NË,ѹâãŠlwd¥ZÿÏVWÍK[�¯Ù9¶ä–ÛíáÇ>d™¹¹=.Q>»bÝEX Ï?cU•qŠea^PÚŠ¹Ò2Kï5Ö“w]Ô›€&´c††@eÛ³qð‰ Î¥YJ)ðÉ+¬ksÉ g¸÷r’R%â’²žE&©G•`º¡ Zªä¬‹!J…A±›²Õ.�ŽŒÉ¥Ï…p¨¿À§ÁV^{H€�^ ÔÕÙANG�q±˜À“¨‚4êSßP¢Ti!+l:�ÿx�bjöKKO‹3œÎŸ?àxQQ‘åää¸ãE«Õ~jtì{é³´éÀ}fÁ\´¦2b1]W +W¹Öƒ„³¢¼üëZšH*/‚¥gæYfÿa–;rŠŒŸi¹ãfX¨ÿ(‹¤ç‹°RÉg”•×[�‹ü~!÷胖ùÒØ™Õô+õ¦ÍM‚ûL1¤2â+­w# Uƒ<�9¡t¥Û7ËÕ¾\ã¤5™¶·DÌ(¹Fï/�ÙùêV¬(.z³•VâAø´Yi­#î“J½7!ÐÉos7T7wâx“Î×uP¢¿M•ÿ Q Z_d |j]Åúú¥dõV1”6ï®­»yNV�&LqÃËfæ„ÆJêàq½I)‹Øsë«ìwïW‡@Ée ö®|ó¦äÚÆ�š@DìȆ³�î•ÿ–{°^æ—üœ8–Q›¦ �‚ë.yÑÆJ«¬9$—ãJ éKÛ ÆŽÏ`ˆ¿£”î®2~LmÃg xr  U±íܹӞxâ ›*Ñòââb—8ng .â]ë‹ñ�ªO}LÈtúx©�[}Æâ­¾ø¤•xÓb‘åS·€N[e“ž‘c™…ƒ,oô+œ<ßòÆÍ±ô¢‘V͵“§Å(ÛVjû÷œµãG÷Yñ¹*«¨¬·¨ ŒGbU¾ûýsíí·½Ërnµò}]¿Ó§ "•™„%àoR¥Ç…eÊ“b€ÒLyAÔŒÚ9I)o°Ý%1ÛWµ“ ÖQ“c½è‡qQò~Z)o‘ÒcJ§”¶)mQÚ¡tH @*ÿiõµKŒ‘€£~FÝq¶ï8o]½´tk˜·¹üåèÿP%î�Fy)»ÑJ >µ¾ãt?Rú°Ò„ˆËSkËC‹gd!_’®‰zZ�ü�ï]–oÿúã¸ð8®w÷ßš'ok[¬í7&úc?|W¡½±¯J®^ vñÄ&;»ï×6bÖû¯ˆýô‹uêd%xü²„»;khªì•ùƽQEŠk]rÜÀª`Bù¢X9ÉŒ æ�|þæoê«¡‚±C7cB±¯ß£ÁXFÌÞ+æŒ `‚‰*6X�´qвõ–M‘€7mÀ& ×¶¯ü´ÞE5ë)à‰ŽŸ|ì>ÖR«·7HغþŠêMüJºæÿ_>°¿úQÄÝOÚHTz@m�ˆ†Läa´íò]GÛíºê;n«µ‘ •Éí«7 ÷9Ú.gÓGÇÛX¢|¨~/�û:�d¸Òö”y÷íïä>¶ÆÇ$äÞ<ªèsÉ34Šh�€A1Ú:Ì%@À±C’qþc5ÍUì¹ÍQü ƒÕÓ.v¸ÿ•tÜh{Üt«0ò‘xŠ_AuéQ;¸î+Vyñ€VÄ÷),`ïyü÷möÂ…zëß{"Üñ^ýjsyé{mÕ š$žuÌ—ÐÇü)YŠ(êµwm¯ŒzD´ÑÉ£3mªÒë» Â8׎ZNVZÏŠ”õé``ƒ6ÓCJ÷(�V‚:Äz?褯I� #%&­PzEé%ŽQ+ ''Ö¨@2jëÈ=]bú!/6ôx¸G^Cªê3*§Þ6ÜË`ïÉ¥Õ ÝÅŠKÛ‘WqÝw2Ú¥`Âd±üÞqSPÌAQô›ÞÁ ¶þ¾¨kþÞÓåDýtÙ¥ú ã –S"ä90MQÓ]½O´Mw¬Û àwüP1ç|·Š{T”'†š4ã’®v€±ˆ¤wÔÐ,¶Ði\Ý6«u¤Kÿ1˜sPfÛ�Äl½DÅßxçÝOÿvÝõÆ¥WèÝ=¹.¦>¨ÑEÒ¼Ü9Ñyª¯-·ã[¾kÅWjh/ŸP(lo{÷#vï»Öó!ìVë4qÓ&læé¾x«ûú2¦‰õчìՕϹI3õfpÿ°-žžíêyBH¯^yP(`L:T[dDÏxІÒ\%Þ˜·<øô%e}ªF(7ïQzD‰I&bbê1;mÜs^o‘˜´ŽTÈb’™ ›èsñWúIú>µï`Z®¥K”i±œ‹Ê5N¯¥t&Ð! ð{ ˱�\»ÆE¥Õ=£CçÌ™3gΜ™wÞïýºeäÍ/! âhÇ ¬ Ù ºëKûÎû6 .&VD¶û5‚PüåîD@1JËÈΖ™·,�è»Ä5c¢É‘*„!ÜM‹ÄÆÆˆ�6ïïˆCŒb?ÐØP+ŸlÛ ªTUG|¬Q¦Œ�•‘¦!©e‡¾­xl´¤%›åZ�š¸ŠM̤³ê""ÿ ¥à(f>ÒsH·!‘¹ÄÉŸ2®¾gffʨQ£„BÝÐJj7@lw¹Ìp…3PÈ› Nuu5ÀŠ ih]¹Ûð¤)‹Œv¶ Ó†g–ã#OÎc}¼›T× øÈ`QÉÍ]~Åž]ý„­ö�‘íø�¼7ë‰{ÑŹàUžd&¡O°îÃü*úRwÁ®ÁlŒ—Ô¸bDÝKWY1ËÅ86¾r¹Aª*åÃJD›Íš ³Ë……[':9¥pÁ—RO°‰5åÝX7m-BSÙ&S&d‰1†^?¾ööžÇ�ø-¯û:c…öb}üÜË‘ƒû“g¹ù ’ŹI,Üó²�Jpèþv³\iÁÜ… l€PçA®ðv§ò*8L¹é‘*Ã(HÊ�:_ô¡:M@ùòŦ'w›aÃñ¬Ñ€òë¹3²2Œ ¨k“Ÿ¼µÐžÇF> ËÐA Ãòúú{QD¤·"ÝÏÇoãn«<´±œÀ×ì¥2-ß € í»¡°­«ñC7¸Á¼5÷1¶%Ïæ”ˆ¾‚ žÆbó,�¡k ] 5ËH—¯ *$Ýü:�ãëÎY&DˆtG°»PåóölS�ž+Ðýéò[—ÀeÓ¤øäo>œ וï•óÿî!—v:³+—.Ê·>ÿ8&‹ ¥NÀ‰!Õ’’Á È”ô¬É;V&O+Q)gÔhìëî8YjÆwÛ…Ò2Ùüþ;è§Ü}eFŠIÇaQ®ëC¬Ì|ŸÐ-hd¦Yòs-øÄ—äL$Üq%`;ô*z¨Ýøð•‡¨Ýh¾†Ä{¤±Äd2©s÷ÝwŸÜqÇ2~üxõ,x2¡]ö˜Q�‰nmŒD·cÇÙ¸q£=zTš›Ñ)»�û«cì«\µnƒP¸U2æøÉÂO½ôq�­Ek4ÚVe«}@q¢@Ê #’æ._£ð]zÜ|I²L–¶ö+8o¾u‚ñ‹ÅCD{3åÜÉ‹iù1“ÀXdMÎ6Ô_T÷Xªë:Üá®ô›�û¾2ìè‚Ërs“M¢Ìqb0‘„ÂÊñ;‡¾Ï1„öpOð£ /æ¦íð*õWªÿ[+6z$£v„ǪŠ}!kLÛjÇ Õ-˪/ƒ‰×2±$XA�ô­#�i0©·»À„‚?\õ®a Zƒ­®š­ø�s:üŒvéeQù±Ž˜7Ù鬛+-è;ZFk'ïÞ’j·é�Hk‘t£P|\£Ç}2p ¼œ 낌´h/ÜmJeÏÎ-èç jÁ#™…¬z" !;Í —1gpì îE2\¼Ò*Ÿ\ºk¨ºè€8¹ÉÏ6Ëâ™ñ²f ¢t`ÀüÞG�²¤$N=Xì€z3KÌx½5YöAG†ž­¾â€\9úºŒžý•~i?õv¾¾~cy鮲áE};$,͸¢ž A¿åpw¡àï}óŒò«÷uƒmÇ0lW/3ʪ&ùÎoípõsW2_Šú¨qa(Æu§ˆ˜ñÝGÍJÏë£c;“L³pO<YA_»ß¬Ü|¶ET�Îu¢Šiå dkÁøm€Ijn1ò[MÚ ©ß­wHX* hl_¯ow*಺¢1P8˜ ÝÎÓpLÃ9·ŽR`£çï½}fÙ¾½Ê w‡ùûº�Âõ�i0�`Êçn5©d‚iö£·R�e�¯|Ê$S�ù2Šî“¡H7Æ�h?8b 8Õ�Ú}y‹C¹ÉUâú2ö™ˆ’YðÉ—5cBAvY�·J_Çhß³~øìÿl�;ªg†J[ÿF&ÌY^‚á¡6^ç̱=)dþ�×ìêÞõçü.èÅ´ÖAˆ¸•×CŠÛmm*uýZ~YΡ0tË3Bð"!Û3³seÖ¼…²üS÷ÉŒy˜œ&'á]â4w7ˆpÐim¬•�6¯—ÓÇ�¨’�†_TæS4¼–|·¯A,¶:5µ'çÇȱÒViiSÏçXü0iRµÚ)òß`×}ÍGú*Ò$¤®ñmzzº¬\¹Ržzê))**’¸¸8<; ”]ÿ¢Á×YYY2fÌY¸p¡<ù䓲k×.yë­·dÛ¶mŠÕy,úKô륪q'Þ¹×dDÒ2LnÇuþ<À6­01æÁ"º·|Ó€Š1gB*S�_]0mOµÿO­]_ø·=&¨îÓ{½C– /6'QO*²I02 ° aØ�ýlúý —ÛeDÜ[]–mF¹îã70ú+×Ú ¿·��‚w\<æ'‰h’Ñ?§¬Ië<ŸÁ…<ŸZ`B`i˜˜Òºnކb³ó,“6Ja3ˆAJ#§<ˆŒ³òz€=©-×C(©Âá…çõ±®Q%ø-J¹õm¸ä�«M-žuÀú�H/ }ŒÄ=5¤†’qTøÍ-]Š‚±}Ñ{�l´¡ÙJBqÕ‘<}Õ@×ËÙ×7ñ÷ì,N Má¤fÓî&¹mBÙâ vd\�ºk^¢PpÜfsÊþSMräl›”LŒ� ÷èÝœØg&ØOó§%È–½ní§²½¿�¬¢•bŽNUŠÞs¼Q¨{×I\}ºeê$ɘð“�òüúvY³«{bÜô�A º6Î�h@Y¯,)'é]®bX¿xìÞu ëûj¾‡¾ ÌíÐ9D‡ì;�É*¡¶xˆçH‡;ŸzŸà„|¹LÍ�’Ÿ>g2®èV§Ù6õ](¾Üé:FWÁ‚lŒ <Œ(‚Hº×³»åää(~ïÓÈH´€iÈ”�� ÜôV¬X!�7ß|SÖ¯_/ååå*ºÇ9]mRßr“ÖfÉN\&I±Sðls,Õß¾A+"G�´Îmçc¢=-Œ§™ÚCûAû2²í®5€µ£û ƒþ&§,é\\Êì~wû|q§Úþãļ0á‰'øP* Y@l²ãŒ*Ú\Æ|©©âRÅò™ÁØX;޳%öŸ|´×O×vkÊóÑž µíü@PªÛT­t=‚Þ¢ä»Ðä’íWÚeÇh7`!©çü�Ñô~…´‰‹a±àŒþo5.ÌÿÚ™G£�°�E,R=¯Huô¨vYHKùm­Õ fS¼¤%A—‚�)zÓ¬4³-µËåJ›8Ðá¸0©]:+¾«“åq½™=óûp_“:ÞÞR#qÉy’:jV�ûž¨÷–w~kÇ39V}ÌÔ£ƒàê€ «'ë÷¹¤7öCÎéë˜ ¬BL€p13šÑÕjë§ A¯}îm1Ø'ÿò³ÐQáï$&ÕLá`_ðš?5Ç(ÿ´!°¬ôâÍda„B×É[=3rcq¾Q�"úß9Qão ù!Äì5Ö!�Ÿ9Î{Ô4æO°”l%¶Y_FwÀF¸”j 0C½¡ßC‹'\‘}•�ðzðëÒµ0x:ä7kׇ¼FÚøÎ»È—YП°nŽ–QèÚ×^¾¿'pt÷l“rÛ Lap‚{æš$/Ã{ùxOK¯¸ä½=Î.�¾JCW6Þ/ÍèRÛ°ðÝÝÝŒ>í·pn3À0Kì°ÿlÏç®ÿe`}A/->zM6i¼zî!ݬ<÷h×½O×ß½EQÅØ¹vÔ9š§K›(S³µ ÔYÙ·c›T\¼ #rF‚•�>̈îî´ÿEîÇ‘Õ64TË;~Y>xç¯xW2R©An)NRÑb9a¤¢ùu50ñl]¨h—ó6­)`}馊ZäW……w§œî+HƒT€¤Æµ`vÜyç�®ï}ï{pµ3ddd(áiü°ñÙ¡Û^bb¢ÈâÅ‹eöìÙm €â–F~D»³î:Wáú¥ØIQQè̆tëVEþÿ¡ƒ™µ(_&æ¶HÓÑMÒn%…}ëð2b�¶’�è«jZ�îù ®]Í[úØ*–öáûšÌ۶.møÁе`}–c.t Ë‘j»|Àe[y»lʶƒiµëšC`aøx�KÎ�KS�¿<ðBƒ 4qQ6z¸ñlðù0â¹âß+CE«À.ö·¼3Üò�Î >„×x^žœ‹ž&”“¼ Þ`oï¬tÊø^; ÙTxU“SÕWg ÁÍV Ó÷°Ý‚T‹þINê§¥a¿'ÐϥϚE7sU÷~ìÏn¼Ïç,èÔ…V� ±ÇmGêÇhÕŸ3FöÊ5Ð9zÊEÔ²½…³ÿ-R<…ÇwŸ°uF½s—‰Ì“–$ÊžcVL”ü�UŽŸK�"ãõD¿½^ÙOÓÆÇÈâ’ùàcøípº°ç¿%»èA±Ä�ÀgÝìËkÁý’“½“XÈkµw(‹>wŠ3*'ï¡6Šÿ̺¬}á‡ÝÇ8Y¶ r ×ÒŽû<"ìTÃK›=:xû'aÚ“W72]Ž”…þžx+9X»—vÎç¢ì%²uúcdm‘…wnÆår(ÕÓ¨ûU�¶Çƒç¼ŸƒnjŒ`÷:Xzc?Ñe¶ �ž=¥ÏKû›®¢ó& Þ] ð÷/Ø{€ªÚþ½m Œ�kà$D ôeÖ”öõü*m0¸Fòé^«ÙѲ€já»±�Ý3רô÷åÏ=ÿãf µ’ tëÎÈ“*… ¿‹¨§÷‰õÊa0•¬Ð¤ “½éÜEÜZ3·ÄeJ|úX1XâÄÖ€�ë•G¤öâNiª9-»;Ü:ÝôÊ/–É›/½(‡öí–Õ_|Vî~ø‰‰�‡®TÐ ï÷Å3Âݹ“§d€'d´X¼Y�Åš¤¸¡ËzÒ_`f²QÆ!ðÈîã&h=ªk€J¢ÌCúé¸~ßÈßa«�18Ó3HO"q±P½0RRRä‘Géxî¹ç¢&Ožl {)¦±¡dÝzë­2qâD™9s¦<ÿüóRZZªNÑÕ‚OW>T,¨Ìøb6P\¼»¯ FY"yPèò¢€l$%#¢´½I\íx·°ôýÊ ó¡µ+¤ X$Y=)VöW™þ  Þ¿Õ é4@ˈ}q/F>øI$ºa�`JDJ@¶&æíäËYt#NJ›1ÔÓ­Ê Hbâ3ƒz Æ ñX £ÞR<˜Ò ø;'a‚î|‰ø=ß1Ñí�Ì#ÈâÙáC FþfÞît§ýªm$SÉÓŸ“î�tû¡ÆÏ`™#‘;Ñ~¼µ™–£mÁ}ÎS|ÜÛþúï8¶!xE h\®þ—î¿Ó0š1Ö ‡¼ó4F=›7É(—ªûz =� ýçsW: Þ¡4’4𩯳¼!ÓkîDØf¾ß׉Y/Ôóå’Æ÷ÿÏŸ‹=µ6ÅØÓίgóißõµMÆ9KpNºÅú²Z e÷£üÞî•þF³£k$WA3“)P®ÿ5|Soì©;ÍŠ�¶Bëš@½æjÜ’°�bõaØ“sçHr6¼¹T´+T·j4èÙŽQ×l÷˜H8‹ZÅÖT) å»åꉿJMÙ±·Y��M׌‘ûägÿþ/Rzæ¤<ùì×$+o$ÜÞ<ó îésc{«¯«–mÖÉ9”�Æw%ãeúÄh¬È‡¯,úrò7‹ƒIÒ„ÑÑ’—eÑÀ'>ˆÓ;/ÌKOÈY"ûXc±ÿW‘V#e"©hĈòÙÏ~ÖõÌ3ÏH~~¾�Œ¥`›B!áyòòòäÇ?þ±ìÛ·O�Jé´µ×Bê#ôy-’™°“ç üi"Á¾þä§ž_ &SSÑßX«Åic`ö;ªÉø“Å ³¯*ò%`JÏÏŽVìp2—j ¤} Œ�3ON×b¡ êV 'Ý/–¥þJû=lùÆ›X»#±…TйågNáœQ]À¾ìiøkšï‚($º¬iŸ ô¨ïy¾·àåo&üÍ(ʤ°S,¶‰øž@U*�©ÌI’0IC¿Ì¿¸>cõîS¯GV†ÓÊÂ’¨²ã€fÌmêQOWš]R °é^—]R�¹™ AFµcÞÇý=¬Ÿ·"½„´‰´: œ7ŒJD[ˆ"C.L¾3…é‚"§ñ¿¼Ïý?~¸ïIô‡ƒšÛy¡u ›Î/NÀŠ-\ïÐQ©�{3¤íû›Ôç+Õ™U/#ÒÝûð¸ÞŒ:ó+¿†ÂÅ6ìÚ!- e’5é1Ç Ï÷x3ô–W ¿=ºØ¨&X™X%ÙÒéEº-'~%ã p‹àëÁmbÈŒ:æS}³öíÀ·tÓ¡Î Ý èZ£Ù&DùÚqÌ…h.Ú7áß~ÿKY ‘cŠ$WÓŒ‡ð¶h§Q[2œ~÷­häP?Iâ芥wIìqP˜>°=b€“›fpëwêÎË;Ù5|NÈÌ ô…ÆÚ¦~Ô,°x”6¨.oþI÷2Þƒ£·æd¢èù6�îÁŽwЕè,ã kñLXêA¦“ˆöF6M ú`d™ñ9œ^à½Nx�¬+¨á¼n½;¦¾X#‰Š½eôÁôîúýüù›`ô4¸^>0ߨôؼCàfßè‘Äaÿ¢·[&T„CF7¤ñ÷c¸§/Â5²�óƒ0Y<^=°D¡õ8߯ä ›«{"„F£FŸÑh@cÀ²üÚý&IƒàõÉK¬ öÉ�‰ �µÁhÆ»"U2‹$}ÌR‰1Ymub³^Æ3¾ªCšäüé“R~©LÆN,’Œ¬L¸÷…§r]ÈN9$/üäR]U©JŸ—m‘Oß™&ù9fÕG„§$; 'LLp.W9¤ô² mUõ-P�“«H‘ȈXxj`2Nó-¤'�Ò‘øP(ˆ`RÄ£ŒÞ^Ü1H¦X11*ŠÞXD�¼víš\¼xmÚÝѹ\íÃTaTg‡ tÝ ” ¼wR�.û†Ë†ïºÔôX¹ë�‰Wù‘4žÙ+ít²¦F—6.n“A”À&� ÈÉ)I7Ê-Ù&™ }t"XÆ`%aÝ,v[&ç„©H%HS‘ª�¶#�F:„´ iÒHEziY>eH]8CàÈ�‘_”Âmlùì6Ý@æØCsí£{Ÿ ?´àËf|YÀª_^Cô¸+͹Ôèä�“upù»f—=Wmò\ •Û\ÿöÂåïd­KÊqöF,®Ø ƒâ€«ó¥ÛSKgjÀxã ØL§0çØ{ råvY{Ñ�,›¼SÖ&›/µÊþJ»œ¯wÈ5Ø DæC¢?¯¡ÓHþ:…ĺø7¤ß"±ŽÀSGøÉËx¿Wá�ˆ/'£³Bävm¬ç»Üîöàœ›�8ñ�ØMVÁ_~ø.é�’[€~oÜm•¢|ŽuÜÆè‚i±2ìáÓÍÒˆNòÍ- ØÇ?ös¡‹Éƒ+’eÛ«4b5¢¥æ¼”ú£Œ_ò¿‚Ê~â{Vš¼ý”pÿy:,šqòGÆõYÒùr�eD3†R/ƒ¯s°ŒÌ¢åÓ±Š�!¼žuÑC"Xçï-êKÅ`ªŸ”ö¶(~#�à ÛÙg�xa†c´12S47$¶¥?BDœzD·•\ß•$<¢nÙY�2´²Q©Qï(¤íiHÉÜ™‚ö¸z¹Iý=g‚S�)ھö)üÛÉ£¢ä»�YÔ=#IXú‘ÇÑíõÀÐÞØOSŸŠÈ‡GÑnR0×yx‘ ¡;®û¹ýòØ”Ø&ÇÃ-òáEJGßàÍx‚Êúè‹Ú~_¸Ã¤ÊööÇùõZŒ ;�ìÂpÚÊ/цþóõv¡ë¡f¿EÄÆðZçuë.Ÿ_ó'ñ °Üé¥ó™Ï0R]G§ÿˆ÷ŽI;([ž‡Ñ&—/_.t÷cd½5kÖ€uÈ98£#·JmóhÆÄIfâ¸ô ƒVóò œ<’…5PcDn²¤$BS±ý¡ƒóÝ�7 ÿÊ¢½t¯…˜pMƒF_‚^[;”ð¼Öf´ó×Áà–‰FÜ»n·_í·pnÙ¶ ð°"¤ (Åz:tP~ÖS XO´QpyìöÔŠõ¤Õ5Ÿ->weؽpµk®ÁÉÓ9¤CH\ñ�Xèj`"²þÒ£HœÀ*›4i’|ó›ßTÀõ˜0ùäÔ‰)lF÷>€^2uêTh¶µ+ ¨ÖVŽçÈèl‡»N»‰`@e¡`‘¡wØn Nä‹oîâ™ )€¦oŠ­ò"Z_Öam"á¼ä>ÏÅQº3ŌʄLBQªQf�0IRŒúP`ËÚ�FÔA¡qH+�è7z ‰+�‰/L‚ì ‰èqåïÕHåHì� ¬Ù†´ém¤W;ÓkØ2½�ôÒZ¤ÍH;‘"�@:‹„¦XX|;²�åyù©Iÿu3©P~°•Èžªe©N—ø]CØUøúéŠyÅã:1�Õáo®˜lBz é—H?Cú3¯å$Ò5$>䬃Ùx‘¢bfLŒ“Qh¾Æ—ý½HŽ×É>v®‹ùÄ{¼I­âô7ßÈq7f DÞ€}ß7vrìX¸ÊÕöSanŒLÎ�îšÈ±ÃÊÐtðŒM*kÚ1Iå–":ž¿ÆAmf*#ß5‹ ”S‡­A,±é’Q°<(‘ï¨á4n¤Q¹�õ劄ÅM/Äê�ÎõŽL®ò�¯„Ÿ. �?×Hw¡Zm–/ÃÅŽbÈÚDŠàµŒ xbÙ³0Aÿߟ6«I4˦�cÁ ü©mŸ%=y›YFe{Kþd@IDATFõ`£ ƒÇ$¤ ðUÅtÒëðÌ f …ÁÉDò4F1!U7Ð(|¼îÞ¢Þ±=²ý¬…;â‘2�aƒgABüyi±Aµï `kéÁÊ�' ¸`µ%^/�Ÿb€O¾4–ø;Sd/»À(œ Ü¥+Y0Œù@`üÓË ÛБÚqÞŒà6…Â߀ëÚL¸ñ~î6¸FêôÓ0L% F�7\–޵Ö9ã =\Ïÿä¤S6`W?xö½'Ìò¥»ÌÐö‚«‡ï�Fm7­¿Ô¾ë}Ëç ¯9FâÒ %)sÀ§ri©;¯k·Û¤ªâ²T]©�‰Å3$}DzH(Dç–†Ú*Yóç?Éæ÷×à=æ’„ç^4#Iî]˜ Úqï×1ô~å€<®ö•µh·— ƒ>#î 'Eœd¹6~±`×Àhdø,Òg�RµÌ§M›&÷w'�>ú¨b‘õ0XF7¿´´4�È¹Š„wêÔ)iks{•8]m3¶‚�‘Žñçñáë÷«>†ÄyQÍQˆÜ~ß$¸�]‘†ƒïK{#È*Áž]‰‹í_!øÄˆ¢žRÆÃÓ3Ìp5É”Û.¾á ô– ­@"CéÙ>¾Œ�›�#F,*ÊÁ)‚ jÀçW G$©¸2Âü2C:„´iÒ¤µHo!i@Õëø›.k�6#ØbÌ£BżêêXÏ„¯ôÆ2Dâù?A"ö;$M¿Bâyènx‰l/l<¯m¸ØÝ¸�x(¢§�‡ÛÜ2ƒýx|"Áâð™å-�óñoArw�ø#b7O ðA�Xß5P�]@Êä$’B¾·Îé<ó;†�ŽÆ Tc?]ARúÎæ�ðOÓ‚¬€ °Ÿ*ñpÒ'–ÝekãEɆö“)@í§d`^dóêѵò"êlà–&1I#%!}"¢æ•Ksm©ÊÖn·K%À§†º:™:k¶$$'Q»<¨FÑåãëé´žð¼æçÄÊê»R Úíß{1¨ BflשرÀt:#UµŠèÄÎÉ‚t‰“§ ×$rŒXªàóH_BÊDR/„3f(àiÕªU’””„6¦¾ÆÏƒg¿’““eôèÑRSS#'Ož'Wô0¦s¸ÿâ,9˜ÜƒŽ¿#Ú`¿Ÿd‘{*’Ô¦}b=º‚ã` �¶Ú+=ÔŠJƒKÞ´ D÷„¢7¤–äZ³“BÔ�øì-Dš�ÄÑày$,3õÛø0±ÏäC¼ةj`� ‚U`ÅeEdUñÜG‘ö ­Gzéíο ñ·“Hì“ù7#@ú‰ ÖËH¿îLÏcK�k ÒA¤‹Hd?qBÆò°|ÃÕnÃ…Ý‚‡"ºx|¬ŒÉ�擟N·jQ² nFŠ€OõUõr]ð©—ÊÑýÄŽ'éV~WÛè�™E 22³§¨xn¦YŽ”Úå Äð¨ƒÓ —“e³ãý~Çiì§Í�ì§ö¶‰IÌT"².ÿú÷)c¢äG_‰–"hᬋG3N>«Ømûiœ�Ec„šPz—·Ð3Þà Œ]²£[Ezñ“ˆªGß@£Ÿù8E¿¾føô~ÑŠPz"tq —}ý“|ûA³l…H¶V�dúP:\ÀÅ¢9áÍI‡Û(@2¾X†ñ#¡Õ4Ö ô–\ôedãð8‚Þ@"¶²Ÿ W¥EUì+O @ß7Ï(Œ G×5 ›{3Ž©CE3 Lô¶_0¿£›&1}Û¦ûhi…K^Cûµ±®# ÷ÈǾëÔüž@ßþRèø×utëë^÷,0˜èJW;_À�¯¬wÉ«Û�²¬F¶2çöžv" Ÿ5õuŠ�~Ïz™aº´H,¶%ÛìBhݱ�<ƒ¨žš‘ÆH£lóÁ3N' x�dI|*\𬗤¥öœÊž.xUåâ@Å̘3OÌÑ– =C$Ÿ¸YO/ɇkßA¾.IŠ7ÊÒYIr÷ÿ߉Á«‡àå¤ �_ª„k„jÉ,„I�B­Úð¦å¡ë£8é]…ô7H…HlÔR\\,ßþö·…ÀSB«è(2 RSSåÂ… RVV¦ ÇçÀáj„gl´Ä™s06$fÌç}èÔÁP) ]îrG'˧î+†sˆõÜh>áåŸ|Þ">`+Ïc$[° ²-ÿÆ®Íi@kÅèLF"-C⮇�8G —ñ�уUd!q6ÒˆT…ĦH�L­íLë:?oÄv'÷ãþW�Øoäb~5ñ7‹ià“¥x,˜OìǃcÒòj0ŸN·hàÓnTîf¤øt³´2ÝuFÀ']eôñg9~_�ï„s°4ÞEp«#c†Æ‰/éø‰q&Ù‚Èw�Òo d?Wy™ÙOWñ€ž(c_JöÓeÉ™¼RLÑ\ù1»f$ºOÍ1© Öˆçrâ×£ÛŽ ú2"2 O3vHf°QZÚ¢äÀ$o6²Aþõ³u,5“4kF—¬‰°–g [˦›¤¾©£‡¸p ù tÿ[& B¦•>Ú@óõçx²×òÎþ‰åf%Ö}{‰QfÂ)=´XpGÁ¼øð�Kè2æ�±Yra7 Œ;‚žÞŒàS,Ò‰‹.ˆ_{Û£çwÿçs¹k–I�5Ðâ™ –�·—!_hÔ! ˜À~¿ýf´Ü1Ó¨´œ4M>gd`…à çD!¦�H©?7ï1õ¡N_îéÂ¥ß'�¿yÝ  ‹ôYåê+}Ï~ŒÀÜóPŒÞ½ºë†§†Ü ê3÷˜H§¾>F›¦ÆÔ`O¬�Âì(ù¿­Dá߇˨Ö'² õ·¿öu/Üß³ÿ&5BâR ¤­¾TZê/©ŸZ[ZTºTèäM›îÏ+¦÷SuþêB(½£÷Ëï~ü}©­¾¦ž]²ž¿3Ur=müÊp(íÄw=˜ÎMÐE)…ë]C“zÇq,Åtª3 ¥ßèeY„ ø*Ò$õ‚™0a‚|ýë_W®v‰‰‰Còú@eggCÔ¬ØOÕÕÕªœŒ€çìh•hSôŸH$‰X(kÀ‰æ´¹y²x~’´zKZ+J1–ÆKÊÛ€"”¹ófŇÀ³1�I‰µH�­C¬n=(>x³‘<…€òU›b°Cº¨@$qz&~¯�LÜ?\CœjHÚ ”ê$KQaœä†|º‚¹í¡3ÍŠ9Œs‘ù´ )>¡n6‹€Oþßq¢êã‘fòj>,(Ž—ôd£b}ð;v_¹&9q¡].!Ž U3º¼å²ŸÒ@}¸§ ̈4·ÖK\êhIÍ[à—ö'~8Þý’�NdØ'Cˆpj~O@!nT‰pã„Ò[8w2ˆè†´ý¨S¹n¹†U …õ¿4¼éê§g8Qwè“SNY·&ãd“Ì=³ê X2ï}­"?˜EÁ,&¹`;}ì•…SŒpós‡OÆ ×h¸Y&‚n}ø|‡Ðe+c[c„Œâ£Ä#Ê�§#RšQžÈ€ëËZ0À¡›Ô‡på3T–�^L;žùòÜeU±«i×~ö–¢édý�UDáý®“…ÙÁî?ž²(à©·ñ3ï ÝÉŽðˆQ[jÙ4£<† Ù)¾ÅÅyŽz°ÐȨ#{o€•ÁzöÙ^>³Â ¦S” 0�ëè±õëd]²oÚ€÷4ôœÂSGxP¢Œ r�r¥©òˆØšé½ák£4"Þäé%’•›=`ý'¶ÉºšJyóÅß˶ kU¿ ±žîšÖÓ@+tO–2]P/ t4…Ç;ï/£7U"ÑeO@Ä‚PùÈãi¤û‘�xÏË“gžyFžxâ Å,âwCÕ<åææªÈwG�•.rg3°,ȘsÁ0!k+°÷íP½Þ¡X.¨ßÉ­÷M”¢œ:iÜû¶Øë¯¢/ì9¦Šå*ebMW¼DŒû‹oæ8Í.èÇZÀ¤£ƒ,¨éH5HÇ‘úDìÆ«û ‘b&Ä*ð‰cë`Š+ëœràÜîà¶Û�Ÿ‚YÉ7P^ðÉÿ›Å§…KW�#Y(4m’[¦Æu³Ÿðƒt2Ü ¶ìmóì'hBL ”ý”l‹¢]N_ �k…äLyXŒ&ÌÆý¤hlì< ÓÀ+ŠëN.è‚cÇk�1äo2+ (�ÑÂ�8'žJì8Äc*–….cŒÆpïdi¥'BüN’?„ûá¢)åúSCè°ÓôѤ´ïBµ�4 n�ÏDK1¼wÁÓ&š­X+",܆…+™=Þ(÷ÝbTQê´ó»ïiÚ4¨±5r<" jûùÚòºÈ´!{ŠâãÞÌÆ]ðŽÀeScž$ ISˆúÎYFå’¥GÑfLΫA„æ$o,À;‚f¾Œ÷”ùÓX¶G—˜ ìݓմŒÂ÷÷8xâõµá¹Ëƒ�îšlïtqòf|Ùó%¿ÿlGÉÛ~½}G7Ê{ÑVZh’ô$ƒÏs1�Z0ÔÞ‚ÛØËÐyúã¦î¶Þ[þÁú�ŒF­ÿažš¸ýoÖ¶wµµ`�+�|–L…=Ü|¯5tô`Ʊ ÑUëɳÿû2Rž{P¦èD©¿¼Kœí-x¹¤±±Q ‚Ï\°X,t¿sÁEüО=òÂϾ/õµµ* vA^¬<ÖS6&.á½æþ×VoG²'Š�1‚AëRÂã-ˆžÃÛP¹kœÄö<¿ˆØ€j€`ÓCH_@Áœ¨ëDÐéË_þ²b �'–«7‹��F૨¨P (>o䀒ýd1%� ÷;Ešë-—Èoý©�,%&[ä�G‹¡÷´WŽlg+Ðx"P °Æ(JN=¨â4“´¸ RÖàGG–ÃdRÒ¤N¾3þŠØ�R“PÐÛ‘bÇæÅȸõ§Boðc"àS`7°»ÏBâƒ*×ê�`5% ‚�A[ùT^Â`ŸºØ.Á~¢‹^Àì'LÒSM²µ£ì-5�¨E)#çúÅ~bÙ‚aœ$�éA�n²=zD¦éE]§¹—NÛw&¸“ÿçÃN²ÉС:µ­æO2ÊòéF¹u†Q�·Ï4É |&Kc!OÀUùÇŒ0H&hÃt%l„Ý–ÂeŒ0Fý$Fô£�°è…ëüÚyȾúÚýf¥½Ä‰ú40”<Í ä¹ÝØäZV¶¶™iùnrÏüyÿÈ©«Jc£ÄüÀK–�`S“—×5VÒ²Àóf|©Ñý�L¤@ͽå¥ÿn Ú£3ægõdÏ„³ýŒË�’o®4ƒMÕUg,ã'/è"9uMöš7c];œQ9\ üð¶�¯ïز½ð‘E&¹n¼dÄõ6^gôË×?rÈЙ»Rë+×Ð|ÿ�›åoî5)7Qºk¦9µï½¥k$û(®쀻ßàÀJ“Ebâ³ õÔ( `¾cµÀnkkcƒŒ5ZÆõ›ý„GQjk®Ê/>/¸Q±ž’ñ.»ã–$¤£ûE9ø51�àv*÷s<RVa—ò* ÂnãDìÖ]_ºŠü` �QñÒ\$ƒÉd’»îºKž{î9™8q"ÆÞßž#ä» KOOW奸xe%‡‘|WÚÑz¢ >ö“«e~,,ª#ÿù]. ú &eÊ=÷�×ÉwÄZzP:œÀFz{™ù�û͹#G±·M€×Gm{”\‚.¦9àòª¹– •Èw¤ï»±šÇH÷>¤øQYDs�Qcõ`^ÇéÕ˜3“ùÔ%– á HXF�ØÍV×Ï@o¶ìz9{àôæQ$CK«SrGÄHñØè.@C J1QLJ€ëÜ^«ŸªêÚù.^F ý”™j’2PúK/ƒÿt{óU°ŸRB•�y`{s2O–J&à4³Bï‚âØïÂuŒ,™× .Šm2uj4’î™k’û!BM½F¬ššoTîlÔ¿�‰2�)º‘¥Å-]#¨OEvŰgC×h4€+^ÝÊô®0Úu dK@ì[«ÌÊQÏ´¢ä~#�‚9)‹ç±³ÆåáÅd¯Pô¯CéyîÃÏd±þè¨0<]>™2ášå+ÙO÷íëdãPï†ú@¯lqªzóV&¶+–‰Œ-²Ü<�s_§.²èóŠÅ:»þ1J[&æ/ov0Ó﾿ ^<ºÄŒ:�’µ`[é�«�ÐöU×Ü—O,ï%�O�õ9š`«—›dI±Çê|†øü¿¸Ñ!;Ž9…Œ¾pÛ$<ÛcÐGœ‚;ç`F=ŒA_5£Ð-Ô¯Õu®J¯¸ä•­=ï�öûàl@Elj%6 îwpj,WÅhm�:ü9‹–JœûÓ?:Áz:²oŸ¼øó*ÖœãGÇȧïJ•ÌT�‹úà\xPÏÊ~ŒÚO•µ9{ÙŽÕ\õŒ�')„_ >¹ýƒzÖ›&3²ž@z ‰ÈŒL™2Ež}öYY¾|9¢ zyp§!jÊ@UUUÉ‘#G„Ñ& 6öÅ´Ÿ@Ñ=,bÁ­� –Ü1^æL�NÑîW¥­ò"^f¥óͱþÖkÏ @!Bw´B›Q øœÎG" ©)b7F <|)eäˆh™R£æÁ,:‘ëšÝàS«M½+� ÿõHð)˜}ƒäŸ¿QWpÈ]H¹|…Y›]rû-‰êAågex®²ÓMrÚOd?Qû‰ βYôí÷ÏUŽ+Æ› ý¤Žoª’¤¬©’œ]Vö' ŒÚGP¡'¦�Ðua8yº‘‘ñÀˆMÁžE‹€Ó²iyp¡Y¹ˆQCŠ“l2˜DDà#A°„eâD@ŸXËÚgþ®\ópYSS)Ô ñkjV“)s÷l“ÜZbRZ<;Õk0mô›u¯~)dѽ¸Á¡\&gÈaÝyëŒuC�pš{œç~¾>Óå“Î’BŠR_?À#‡L�Óå®. ,zÆŠgÞl[Ô£ûg FoÆ}ªêýÓ“òvüï0Éw5+1j­ÞØöÙÎà <�ÍqZé~Ø  ÷7k]ÂÔÚo,Iúïøœ�åø9‹°$ âË4íF»ß£MQ¤>˜Ï’¯sÎD´½ ‚ ™Ø–%ŽÑâËÈà{þ[n!z2øš;|l—ìgBaÔDÓÄÊËŸÓ\<ÿ1Ép‰3HíÅí`:ÙÅá€@|{»ä�ý4iZqÀì'6Áúºk²æÏ’í�ZO)d=ÍK’å3ðŽM=víÁÛ›—��P-HŸ½d—¸ Àø âm¯ÂzŸâëW ŒÇQO q2EQñÇ{LV¯^­\ïú•ã ‡1I”r½»té’* ÙOfc,D�G‰)¢ýÔ;DMñ˜‹<øÄtÉr•º}ï‹£Är"6à`-Æã½7 å vD‘µ*ŠÀÓt¤"$6ò«Hƒ;F"Ög àN*ð)37#:j긥ÑÚçQì`À¡¶Ñ%ûN´J«M-ÆÅák‘"àSõ8\võ2ý.—²ëà’;Ø;y†:ˆî1¢]>BSjî8bÓM&!ì§}`?aBí§Y“ãÝš~tÅØŽH7COÂZ¿M±Ÿœv«Ò~ ÷Ë“lj¨,†~ÿþ¢XQÓ©ã‚5Ÿàx€ú2óàJ·j�I˜oR¢å‹8Á&ØD°„ûõwìÀã˜ó f·gÖ¼¿“æœNݶÚùJ€5 þ¸ “¸A$:üß'ÍòÀ”íG¡åÒ @ñ>QƒK1SPÔe"�çÍq2ME "bÚ30ùÓmË›ñ>l: ×>ÛAÞ3‚’ÞÌ�… í�R¬%«9 ·½|·éZJÏi€©ƒaÿöy³|á³ì:Ág«»'q¼]A%‚ÔÓ �ª-wÑý—¼6¶$îœ!ËpΣÒàš0ÒwD;Þ³«�ßÜé”7w¸™�ÁÒ™ë.ùõQ?íß¿ˆ(qp¿$ð­µ5Ö�·ú¹>‡Ð}ò°}Úà† „èuî¡8ëêeFùÇO[ &ï=èƒ?ç¤û�)&IZjÏJSÍuˆÝfƒ.›Qæ.Y!1Ъñ÷ùäÁ #êØùÃÏ„zWl!Ðô#¿=U2Àz $/Ê?ö!èëÞt®Ü¦Üï:ËDÈ–ÀÝ DE,°à‹c1æ9Z�-û<*€>Õ48>µ|R“`²ã"àSu8œv�€Oý»›8ì1¤D€%„–©ýÔ£kųEöÓ‘³Ðƒ¸fW¬Ö›—”ÄÓ‹Î/#s$6Ú(›÷X³Èf½*é…Ë.{,ò¡C78Ñ¿gŽÛEBçæäj¢Ä½ ÷:²Z‰‡áUÂq…—½ç‰&¹½Ä(—&Ã…'ÏÁ+0?2{¾¨ S€§8IÿÁ—-òÜØÞÃ$XšbàÑ>ûu“C°A”Ü4ƒb.ywÔ ‚›�€`]äN"Rš^Èٟ⺠ÆÈyãáåmšÀÁ6�"FÕó›Y…cè2H–�·ö@ÀŒF½¡¾˜& Ç#€¢]£6ìw)WRí»po ¬±lGÊy»ožåáóÇç#Ý|�r<†m�.©�©·åiQpCÈBºµ>¸À¨\ùÒz3‚û<}å—Œ¥‡ÕËL’�þãÜÕîúÜ Í»õмb¤¿PÝ1Ñ�.«G˺ËÐyÁz2šbÀjm—Úó[Ýì't.—S&L™*ãÆÂmÜ¿ùL65ÖÊÚ7^—õk^Ç;Î×s£¬˜“,·òÝØãåè_ž7Â^¼nÀ—+  Eín×;®"ŸFÚƒ¤ƒ‘o„+eLB)V"Ý�c±Xäž{~XRRR†Dû[Š�[­Våz§i?)×;S*ØO£ñncÓ‰X0j€ïÇ÷N’Ù“Û¥qç+ÒVuƒÉ`äÉC_¬RºàMƘ3+Î,WÀúmhsšPý|Xç ÍC"»¥ )Æ£† |âœ6/oDèÀ§êF‚O­ÒÖ >½�s²mDì&«SŒ›¬¿\ÄÖRÈ>;V©�ˆÚ‚éñ’Ž(ut³ qCðÄb1ÈÖýM ¨©ûiΔÉÄ*ÝØü1®ï=nêFq’`Äjõˆ ÷„|zt±Qžº:3˜ìo9Ü]P,·v�þ”¿·}âÐ�æ „Dg´³¼¼bm�@‚7€¡·¼ý�ùÓ½,‘ñª‰Š:HþÙ_d�QWêÐ9ô£ü=2øûQ ‹bÝz7¤“оù+X)úïôgfùɈ¢û"£Èy«kºÐ�ýD¦ÔqP�Ûµ¯`y3æMÀ¶¬ ‹ŸõÎo$xOx�ÞŒàÅÏ¿jA»3º£v^¯³uc}³ýL8§/NB³ŠÑâ|Ý7oeãóHp©d¬QEô¶ë;÷Ú„çêÈùîºa9òRX�úN ¡£Fö!-oFÀy×I§¼fYT¡d±]ÿ#„Ä $ÒµW3²ùN\ oÐíÜÚv´ãž¹"ùxvÞÙåì‚U‚Õ/jçѶ©Àn(¶_¡‹@Y Ðkû—l {o”+Ö†±V––ú ꔸÞÅÆ%ÈÜÅnmãËÙ“ÇåÅŸýP®–_V}JþÈXÅzÊÎ^ZOÚ}á–ucƃU‹A5£Ó64©Ž‡OÐq¤HõH ¬Æaw®ÂÏDŠ9r¤<ú裲xñbÅÊ ,«¡µ7^È,¤ðø±cÇÐ~(Yà#;Âã£ÄÊ ~.I)ÑòðçJ$£y·ÔÂåÎÙŠa»·ÁNPÎxsg‚¡„p¸W€ˆ¸S0¿qD™äJ³3ÊîfAåáçH Ôt ‰Ò%� *q@ÄBZŸ>�4*/+ÚP<.ḐžàÓQœ/>…ô¶ÝÌ#àSÿî gCuH«‘Ì6¬v&Âùù–¢Ø.W-ÛltÄNÛ¤²¦ ÿÊa€*Nû2lc!hʉôŽCîÔ6ˆÃfMºO,qùú‘I_'ÁïžïcN~)ÐýN§˜¸Y´ '·Œ¸¶ áÛD¢–'о&½eŽ�µÉ’çuyæÃßãvÅÔèrIó؉÷¥Ðž¢‹^XšÂ$ž,0ê –M+0È¿~Î"E£ÝnHZ›"(à |ÑÊJ°…Œ&j ¥%rèp½Qg‰"ÜHjÙ°7ã½Óê�å ð”�õëD‘ؘYuŒHæ�qbO6Na¶QrÓ½——à ÏË(p¾˜Ct÷£p95ž;”Нë*…ûQG°WÈœÓîs�²y¸?�Šîû2Ö�]U7tx_æO6Êã`ðÜ¿÷|=3V¸ím‚–Ñ_¶9T�–ÓW¹|}?n�K§™Ô=ì(qd:é]s©ÃE½%²¿j¸ B#ðôÛoFË¢)Fåꬕƒm¦7�4ÿŠDñÜ%,Òno�Ú Ûñ »ÀÞ¡þS»͘%¹£Gö©ýÄ6cµÖÊ{¯¾*ëÞ|l)§$Åeɬ$D¹‹ödºÞÙ §wö¢M.W¡cÅc„t‰àS RÄ«�¹Ø}ÒHVRR¢XO………üxõŸèzwàÀiiq¯xP�<Î’ƒqPö }Cáœè §ÎÌ“OÝ“+íû_ëùC‘(wa¸1/§a¡kò“,R‹î°¶ÕaÄø oQ™€tÒD$øWFªjí†óP&ö›…™�À¦rbïOì± ÔFú |=*>¥B#™ô^|à#Ö¿¨Âa‹�Æòðª:§,… xb\·¶…™à۴퀛ýt¥Ö)óŠã%#ÅOöºãŒ³l?Ø¡oLTÛ›%&.]2 WExüñ¥Fù6X*Â}Œ¯'äüìkïÞ«ÿs‚K×) ÏÃä7“`,d¬×[ÂÇC‹ @Ù 0}èÂÅðóÛq‹bß;átQ^_¸æÄÛ›‘eEà‹ù�ò¢otYß~ТÜÈèR£Y Ø£}ê­'0@—²ž6á^�%æëPé?á}O‹õài<�9îK Æà@÷º¿{Ø hƒÐíH3 œs•w:îµg¹¹'lm˜ì?ë¿PuÜùNGy½åÉï>ñZ¡=Œ‚;ÚßÜkV®fÕh+šm<àTBâážôÀËÀvKð•QyßX¿1>·¼öiÞEä™7§¥ëǰï¡EFùÔ\£ŠG�‘eôeßÇ¢Þü{ åõ<�±‰yëcžàÉþçåA?Ÿçù{ûüôÝ&ùŸ�˜UÛÖ\�¹ÿ>´uýçÞòÈo|Føl] JFŸßnªœ4 ‘ÃŒ‹4”"6¶ ƒÑ¸âdÖÂ%X0髃†ÖÓÑ#ò»Ÿü§TV”«¶V�+«ïL•œŒn6pEºávMØÖ†wÂyD¨mjQ=å!\ÄV$8G,€à$ˆÔO!%0ª£ÛÝÿý7¼Ë�V¼¦ÆÆF9|ø°”——w~í»6Tžο#ÖïÀû4 +Q÷>V,S²k¤öã?‹­ºÂýìw¦‘ý­ 5kæ2,ê’fIÀ ¿‹W-íN3n #âQŒœ.µ"=¤Kd;®Fú"Òg‘BCBϱ×û]ºÝ�ÉËó ÜéNLs Ž#ò·Ws…#È-–Á#v³Õ@_£Ê›­>¹^"ìÙyFµ´bµ7Á$³&õd?q^™í§ý§à:·;|]M˜m-(Žó ¼àD/9Þ õXa?p ´ X«µ\r&?(¦h, p&øøR“ŒiT.¥ß¥Ñ¥‡áÃ9Évê�i¡/AêóP ‡n7ÖBð|=Ý :qbFw3²t.€™@vÜ9ïuž÷"êéx3‚Od@�º ½÷Bd×nÌg\^ÖxÒ»Huí¦?O…Ò§Í*l;Á Ͷ¡>(�ð¤K¦M+@·‘éЈòÁ&¢îX4ê‡õ ×HÒò °÷Ô�&Ésf ˜r Ç-�+ºU²~=�`ô@Õõèݪ<÷Óæþlîd ñ¼ÞŒ@ËÌÉ:£ãQLj®e[ᢤYh[¹v÷vi±Aþi5„8=êoç ®=8@Y0Yù|Q7Ê—”ËJu‚£!äO@Öˆ§Ϻ&ôÊV‡lÀ3ׂ!]oõõh„ÜmëT„à5ñy`÷¦]J¿·f'ƒYH�;ÔBôd9}ºwŒö©×-ûè¸K¶¡ý†x«K�Kh?Ù[«¥îÒ.ÔÀ'�;ìí`̑켟ì'¶ŸÆújYóÊŸdÚ7ñü»$ZO·ß’,·Íþ¬'6,ÖÖ¯ÚåðÙV.±sºŒô f½  HýY‰´ɘ––&<ð€ ÌæáÊpQ†ìÀ#GŽÈÑ£ô<áçÄd/õ|¸G“$η”*°ù�:u9#“äÑÏL•˜KHÝáÍâ²ãÙÛËnØ\ýй² (F>z’Řáâ]cëˆjmwñAŽCJCÊA�Tˆ4®s; [~?é$.ôGTB�÷D�O£³£�Ó>1Rr0M Ž#@×¾“Œv§Æã‡‘ÿ:¤Œ,ƒYòH^¡¨�ø4°Z½„ÃW å±g¬¨vÊ"Š'cT8yŠÃ2€3¿íd?©ý2ì'½F¾öi¬¤'åýŒöS[ƒÄ¦Œ”´Q b?Ñ}$“O½ nš­‡�ò1BʇÊ8™¢6'V·•˜”Àx_l'Ì{ +ã’-GÜŒ‹w?qÈV-t—"«¦ `u‹È@â¾dpÂÊ5g-ñ3™× éD¡åq`PxÙÓø’$6j„Q>»Â¨XSÚD�yqâ=˜ÀËK·jò°ô»‚x¯X?¬'lÞ4š8^Ó¾'ÀGíjdi ïÁe+¿YëPu­Õ-Û¿uJÖ†/w0Ö;Û¢¿®w<'ïG†-|>«üuG;®-J^Ü€²u‚¾Ž Õ÷s&dÑT“ª¯`Þ7Ïò6ã9 §77JÞKPÔÆâ¶7ãóD ª—6;d7À]¶“PÛÛïíA´/}”¿Pœ¯·<ó¡V`“@«f¢_¿Ï¥zÚw¡Ú.Ÿf”'Áƒ¨yïïAÅtšö¬iŸC±5š-PÌRö“½¥÷�à~—”’*³æ/Ä)ùL]o€½åÄÁƒ`=}_E¸#£qüèY}WšdB¯P{^äðù†ÏÛñþÓ­²ïx žõ.%ø´éÂð¹Ò°\É4œ… zãy¶±cÇʪU«T”;~.F íôéÓ²ÿ~,H¢ó†™�qŠùd1§ãSw¤~Œüçw tàa\pÛ8Yº Nš>þ“4_>ƒcùLzïÃüÎ8²cÀ5Àçp,Œõ’L£ÌÊ€fmb´48¢¤±Í�P'‘ç¡úÄï˜Ê�þŒq]F%„Ø0Z—Ç‘òÇäF§†|ªmt)ÁqÎcaG�"àkâ&´ø4°›ÎQ¹2«�û)(Æh?‘ù¡‡ÙfÙwªM®A8܆Á©èË‚iq~É6qŸ–h„8³CN–$î[c…dOyä\@è{ 2eL”üè+ÑJh�Î}Œ“½*“F+s°¶Ô–¹m�Í2 :RÔâ`Ý—ÑŒ µeèæÃ°åŒÒE�‚z'š.N 2ÍXøâ„ªÞ¼M¼ X$Ät ž °¬µn°ŒÑ'ŒôtCèV �©mÝÇÁ(ë†uNÖ Åǽ™Æ&š7É-L}µÖ%t‹ÒŒ÷Ç› W:È´™ àÑ›‘Ö˦pÑÓü�¨Çó° |òÅ~âý5á~²ŒœÄ‡ x"€IVÝ!5#hY õµ�ºÁí·�lù ‘5DÆë�º]ŒHpyXM1>+;O8åO›�rª´ó0.�ýô{€¥×s ¤ÄdÀÅ`Ž—öæk È~µÛmÐIqJÉüE’š™~Ý»J�ÇuUŠõ´ùý5øÝ%©I&¹k~²,eT×@:é@Š;Äö%àÖÜæ’ÝÇÛähi+ô²Ôó_‰bîD:;ÄŠ;”‹ÃñèR¤�ÈŠ�¹sçÊÊ•+%77—‡�|¢îÓÞ½{¥®Žò¡dϙПç!rXΰ¹Îp_eP£qíÁÏÎ�Q†R»ûmqX«1èØ;1Ü×1ÎÇ1 îì��L¨Ãl©¬2ð¹Ðà�fRÙ½Û|ýÒ" À[8b!®‚Od>ŒÎ øT£ÇI¢P÷ž´ÏµHæ*áf3Ls#6ÀxÇï@ZL�h펹wq•›1±pOB D¥Àuîá)òÏ·˜ê� Ÿ4ʽ e∽º«½ƒïÎû'ªãšZÒxí„\=þW3ûYq:úžÑe„lžh¶pèÖûéõ”ú‘/2^˜Í†éˆ ÂÞte‚œË`\é8mDöE°æ/Mm Èš^è²Q<�esáùî'íp3 .Pày.ÖM:Àºôô¡‹Ø10�ð‹O€�ñ/ž‹Æ Tä ?´u�2œë#zæ9�Ï5`…1|=õ™²¼ˆV³¼™+_ßDfŠ»Mûs>ÖùièhQO‹ ‰§±Îsàî7÷c ÀŒí„ÀÅÇÐôzh‘É+�Éòfˆ™;Ѩt¿¼cþœ+�}x¿~ý�h‰Çö‹ÿeëRÈ ¦`6�@%tóábGƒn�d™ÑÍÑ[=û{BÈúY·ÏöŸ €op£Ê-{ïó·›áÂæ{ÓiËPû<[^7ûF_ 2ÛÜëå|áv“r5üú/íêùçN¬ÿŸ®Œq¶›Éh‰K‘Œ±·ËÕSoIsmÞ+¹\v^ö~´M 'Œ‡cPOsb¦Wzê´l|÷-µ¯W�#KgÆ+€ŸÏêp7N¬Zœ²îã&Ù¶× Ý§®ZŒ¨Dv‡{óúš½I!M111Šù”——Ìs ‰¼ñŽ×EP­´´T•ÉálØ] ׆÷Z ¾óÿ];$.jÂ…N'oL†Œ/m‡÷Š­áJuýØc5èEง¬1³;7ÿÿW§Ç üB°© ¯ørèÔž„—±:»”Ö9¥¦µ]ÚðгanäѺ¹�é ¤�HdŽ6"uð!b7v °mêÚçõ±ûò"¥ "àS•åcW+¾ÿ1Ò|$S:Ùw¶5ɳ¥öØÝÀiÉŒ8™6>^žj’†Ævyucƒüã2ÕZ÷@ö8Nû@€jÂhD=š‘ ëvÖc€â�‹û~-9ECû)tï#}9ÏüÔ¦@Zž¡Ú’y‰ñ£K@³Ed1‚]¾Œ×M@c+Üë¨åD †`A_õá+?_ß3?æMC²SxZ,&ñF "&c7óÁsŸ�~&àB†ÑjD›Œ¨gŒZ‘Æ�¶Y3篺(• `Ê .ÔÆI/Yi_µÀ{—Àú"cå?^kW€Ž?e¢;ä¥j7KŠÌ;oF=¦™`› !æ��Ï�RÂ×¼Ÿ¾´ªØæX¿ãr ÊUÓŸ|²º„T¤(z �¿çåàrÌ“b0ˆ"ûDtj[óÓöã³A i;„ú7@½¼Æ-?Ðg�L0-:Ïõá!§ÒÓ ÷keç–íâ³p~côðÜiöÏ/¡Á†ÉAXe�5‘*¡•6ŒBlj“%½`9À§T‘jk«eïŽmr÷ƒ�I\b´ŸÜÏ(Û]}]µìØô�”�¥[‹Hj¢I—$HDf�\‰æF੮ɉ÷}£¼½­AE´Õ=3ìH½w¦Ã¼^py£q,ñ“Î-2qâD¡îÓp´‘#G “f—ýe´Ûà‚‡U(Ïé¹¶cdë³Øë•äHª©^j/‘Ž68&xzøÌãFû�—Gi;^#äÅ[°`ÆÖ…ôÚu¥::3á{€‰•lø½ Žg\r�•N"Â÷e+$Àžå˜ÞŽw‚—·ÂE¼é}¤�Ht±#¦ûÅŒ5à1M�€OÃã¶öë*"ƒ£~UÛu‘:HöÓR>5öS^fOöSB™ÛR@Ío5ß%îk�»$ÊœÉ{õƒýÄÉæªeɈœg œ7\=*Çþ"ùs¾êû‰î4¡6–q"ÜëV/ÇîVddø2ê5(…p8ÜO\êP Œ·—¥¯ãýžáÓp#â9©Ÿäi,+EÉCð|”¨íR2Öalw âÀ »e¢€ŠQ‰;ÿxÂÍ!ø°ç´Kn™@Ç‹0;� ²ŸfA@œ,-Y 5X»bD»"¸ÉyGØ^1�ì6œèË(àý?±È°gvŸrÊJ`™*/ØO¬×SÐ.ò·¼}�Ÿ¿“�¶r¾ :`ŒªØ=FúÁp© !~ÁHuQ'cŽõ kÆ`‘÷‡�_ Þ3ø¹[Mrß-FùƯì*˜ËÊ{@ðr°�î¿Ó �Ši¤ŸBU®hí‘áwõ«ÙŸÅï°ýah˜{b`ŠK“ô1Käê±7ÄÞÖ(m_zê„\8wF¦Ì,éwayál©|øþ;Ov(7×±y±²hzœŠ^Šùư6OUõyóC«¼÷&ºp#qé�'\<ÖAzJ‡uUjÇúš€4^ûbÔ¨QŠù4\„ƵëÒ¶×F�-±±±ÒÚÚŠ7,z¹�¬:�ô8í¼Ãuˉml¼Y¦ÎÈ‘ŽÚ£b«¼è^”õ6ð&•ÀK³C×ò£«ù¨Ü.�XÈÌŒ5ÊLè—΀÷Et\ð$êãëMÓ³Ûê®oûó;¾Ç]È�r�˜·TaìxÞŠÀ7õír¾îó`7Á9í¸C|Lk0íCZ‡ô!Òe$€Hf(8KÄ­<Ú”‚-­0‘j DÀ§àT?uŸÈ~ZˆdºVo—··Zå«�ô\±sbÕxÁ´X™Wœ h€ä’?­¯“âqÙŠªÚ×b1ÙOS ·¤$±‹ýta÷/${ÒJ±Äg� 5¸#~ xâÄ“ã¾&È\¡‹A'åbw3²oBa§&›‡Ì*²{ÈH¡¦Ô-pÉò,[I˜(R?'Ì^_"€ †•×€'~ǘBès”(�¸ãÑEs§¯›ƒ˜K×\²€ÎV¼Y=S!M·/Ö¥?F×; Š3jZ^†÷w 9ºB~‚s÷�’!u"ï'ÝïMíP.vÞÊÂòçG)…£ƒeóÐv> æÚEÔ×ÎãݬðPO,;…ûGôl·�^›y_=ò[Ô9 æ3HfAÕ¹¸¯oA»m0�Þ¤@3ê€q@®õÖ~ ö–çþ¯¯XÄŠ7ÄS?B¹Îª (ë/Ó/Øeò™ªÈ`Œ–„Ì"‰OŸ(öò=˜¼uHmõ59sì�|¢±¯°6ÔÉŽ7)`Šß¥AëiqIœŠìÊ÷Üp5^;ÙªÔ_|csƒ¬ÿ¸‘hÞ€ðÚ„‰S¿àu>õbÝ!Ø)6>š—H·4Š� Û+NJJRàSJJŠŸx¡v§š† ˜Úßg(T7”.wÙ¹©R˜/¶‡ÅÞTªS ™|é"~::o ØÁ™»ê‡ŒèŸvT@ûLT&3{ çlU|ÿ«­úÖ $y›{pÏfÈcO¡s‘f¸7£¯oiw¡ÍÂcï¶vd¤ŽëÌ»s÷^ÒA¤��¸P_ŠD¯N�oEü±H Djনï³Ì›âÒƒ~‘ë‘ãV¤[ÙA¯ÛÙ 4šFgéØOøžaëWß™ ×»¡vÓÞcM²e³Ü5/QÛ¼tÛÅ4;ä°§vFHç&h];-÷ÿF&,ùôàƒ×‡s2G— ‡¡Ãã xb½0êÝë¶<¸ ³`ê:yT•úøÈb“<¸Ð¤Mÿþª›™Bw-‚"tùò4 �§P­#Fð€u@Í/Oã¤&7Í},#€9GÈ5¹´ó“ô•{Ìò¢ Rô™`à‚" ¯__7,#ÄgO0|‚è‡‘ÉÆúÞsÚ ðÉ{wCÆY~¶A±£È¾ÒŒ,§G—˜ä_þÔ–�»Î8yÿ&Ø44êSQ�þöï–7'Ý€ë�ë_%ë]Ë9°-EòÉÒÓl3\7§DÉzè“…Ó(´Þ_P”íŽÚ[ Ÿw)–€LVJª‰Em7 �3_Í^� éZ€<ƒ%’ ÝŸ¶(fu¸ �F�ð� À»s¾þÖ1AÒJè^ÄcZiôú½ÿ›¨(°Uã²$){šÔ|¢5Y­röÔ)D¿sxBGŠÁÅsçÁzZo;€ô()+ Šãð;ÚõÝÛà_XJÀþ„ÀSi…]þ²¡^¶îmhëžL@ðâM`�!xB³ê)Úƒ¥ŒøägÕb¿âÎ:2S§NvBãúº £‹nwYYYråÊõuŸÚ��'àYÿˆù_|ÇLÊ”ä8Œ­+N‰Ë~sèsLÔ 0ˆãz$¥©tŠ:K`#éÍg×ìó‡ë»sÂK¬kâe(«�Ë+r iÒn¤ÃH… B)ÀÉ¿$vŽØð©�H�6|îå@¯Äûlp ¹ÞœÇkì§%¸|sMC»¼öÓ×ëÉ~b$œéã£å®ÉòúÆ%6þ*²¸“)à}‚ÜýfhGˆÒÉ)§»Þ_>@4"Pµ/î}^r&?$ Sp|Ï—M8nµKæ€ òÀ<£BÏÈ3ƒ¾£`Z¬ÙåPÚ8¤ìz¿Ö�•˜çÖØÌéÍ�51þë÷»Ž”á&ŒI˜èãi<>Þ‹8¶ç~�~~ò6“Ü3×(ÿëÅv„°ï@H÷ës x4£ñMƒ(ú''»'ò×ï¼o8`!ˆCíjà(áeEwÏñÞ5P÷©¤Ð Û�DõˆêÖ[‰(¤N�hq/,% „ÏFžÃ*Zç°„ZPÔûÔ£Šæy1{VÍ›dP®’ž¿ó3](g ¼;�#ê\?ØO_¼Ã}ß¾ñßö®ml·?z3xc'‚[FÞº_ÍtÅ: v—gP€–NÙi¸N€ëX_Ær²î�ðÄ%ܾ1Ñ ¼²ŽõÏI_yùú=?+J~òŒEEg#À£å9˜=, wdÒ•´ÁBiŒTG|²òÎ Àƒfßù�}ÀŸ–—?[‚$Ôhë‹Ex}^,3˜u–x0Ÿ&�fD�h‘­Í›ÎJc}£¤¤§`['oÙ(§Žq>�~«ë ¡g˜•ð¥—ÙˆÚùý�uÊKÛ{²U^ÃûzßÉfµ–“03vLO�±y1Xj’“çUß@D°ºŸnЫ[±YWS�&#©N�Œ§)S¦H|¼——ô‹åBÇxöìYÙ¼y³> †ŒÝ®H .”Y³f)àk€§ðëpêôx1bD×þNè=|’,°DDÇ»ê¥Ï?ð-™X4BÌÖËb«¾¤tQM³ÏƒoÜH2‡ÍËFÅȺ ˆ\ÝÜ®€!^ǺÁ��Ük=é+Gbtº=Hœ>lâo\1 Ï 'ŠØÐ¬®]éLõõºÏ‘?o¢ð>ü‰* È—ºùmFº“ƒR²Ÿî]˜ …y-ü²:�«Ãßš$Û4A¤Ô&§ÊZeÓîfypy¢Ø¼ Þ; 1Xe°HGnŽ�‚Þă·ÅÈöƒ-RQÕ*­Ö )Ýõ_2íÞ_»‡n8w¸ŒƒòO/3B{‡ãl†U½þÌõ 6€íD7»k ÁuïÑÎFÐè+w›dî$£<ýc[—öÙÿÏ+=9R„mŠev}ßÇëéM§J;_ ÛÔD€Z'�ŠR"Ç Á."‹Ho<7A˜Eˆ v,’`ë>QzþdC�¨yÔûùß°+Ý–¥žÚO`?ÍGù¼1ÃxGÂ}nSþ %¸ ä ¨Û|°”ÀP‡§0Û¥4šX °³È4òfÊ}ºKt£d�y3Öieó eE�&>—��UÖ5º.W{/G ùé÷å5Oƒ#Ùn“¡‰EÁ{º94Ø P�À)342 ™x Ïà�[ín&ô·x?ì²Ûà–U-ô*áqÀ:'ðD¶!YOœ8 ´ôeöü›`Vé•Ë»£hZ9Ìc=¬@=R —¸ýå»ný4  eÑî»Å¤\|é^ª/(³,�2O%û�YÎVtȾ޳ßó'®jÌ1Ÿ–/¦Ød±7×J;&ç•åRSU!©Éré|™l~÷õ½ ¬§±`=ÍŸ‹÷apŠÒ}ØPP—ÁÞÝÑqñz9_ÞÖ¥Ñc”e³’dåòd9v®Uj Õi|ȵf5¢]^P·D_f!�b®t¹+**’I“&ñcP­©©IÞ}÷]ùå/Ù<±Ï% é…^�+VÈÓO?-³gÏVåêɽdF†WjjwpšŽtrÍÆûÍ3ò£ðÞP<”_nžYÝÀŸ¹Ð’”#…ãRÅqm—Ø +Äàal¼Ä8L .4CãÉ(Gk /�÷XªPêB£úL×á>µ¨–³H\4ÇHD�äž•¥}Ö¶l`̈h_F¶7G DÀ§àÞgú/ÿiRt½µ]^ßÜ(ÿósê cÏMãDh ÜñV.M’_ýõ>wÈ«›êd!43Ò��«ÇÜÛ ."ÙI,§x—â9Å×ô¹ÎÍIeïøùËg£8`¹rôuÉ›ºZ2òoG˜S#ø¹ßÉQÊ=kÉT´#XÖï7´+wÄgï5)wÕW¶"Š XLtçzùC².Ü“cN oÃûG6uw¸ >˜ÃÈrz|©IÞþØ¡hyþíoíA;‡–g ÛEùæ*3´xÀ<åÖ¾`�Z‡È¼±, (¿¾½ €Ñ™}g[vûc¶%ºù |¡™GEÅ’�+± #øD¦HC]­T\.“¼‚\Ù·ã#9q”Q±Ýî€õ”�Žw\†&Æú#ØËwnù5‡¬Ûe•5[!,ÞèèºÎÌT3Ì)rÿ’D€Sˆðt¦MÈxî´óØ–"õÞ�i{ßÜÛ ¸|ºÜq¬¢Ü͘1Còòòø1hf³Ùä­·Þ’ïÿûrüøq¸‘vÝ+¥¹d…{é+¯¼"/^”ï|ç;rÛm·…€ŠŽŽ–˜˜5!cÞ·jâ»�€‡ƒvôóíh«Fõ¾à÷zsçˆË®cx_Az)èO6ˆw �ʘ83Ý(¶½gÅe#á¦g] bñBzj^eÆ�Ó 10%Õ À›Ü dü@m¦Ã5Ѳá¢]ŽVÛ¤�ƒ·á>½€íI$> ž£xoènvî~�™±#«‰/=æánrø#b7T x»×A¿º­sŽÕiœ`tÒ¾�loŠˆ€OÁ¿Í[�å:¤8–ؼ·Qî_œ$“ z²Ÿ8иwq²lÜÝ$¥—[¥¬¢MÖl±ÊS¤(ð©ë^.czòx¬`x<ŸÈ—€Õ� GDmÞ]%ÇÏÖ‹ÃÖ$çvþ@’sg�~œÊq×K&¨WHï±p­Ó&è¤*ëSæzÖÝ¢6"ŠÖ¶£Î.&R° 3Ñ£8ñÖ _“åÀɯތ÷Eó�÷Ü� šE)4ö¯þÆåFɾlQú2_‚À0™&´ª&w¹È.:FÏ’b£r�qïáþŸõIöAîÃ÷`CÝÏ�kïcn\ƒ¸#tû£œ7 ˆ“î‚ì(¹s–Qþ¸Éá×½åu”Ô¢ÈõüÉ|ç\o¼v2Œ6ŒR:Q×ïqý7dûœ­XvÎå5‚!�à$’À™BXôfV~ pŽšØÕ$g.µ¡ÎUÏ™/ÝNŽÝ—<ØE·T¹Û¡wsÛ¸qã”ÞA™`ÚÞ½{åå—_–cÇŽ�‰î~ ò^j ·-hçÛ¶mSL¨¸¸8Y¼xq0‹p]^tddzéËá ia‰OG6g5Â×_ÁbÞe¸f_Áû¡¢ÒÑb0Q¬�·‡¹Ç°æÍÆd‰3çIœ%û§*@ªc˜`£Œ4™W˜& –±V_�EϪèQ/Ãçƒû»‘#¾‰*i´¹$s”ÜŠÅÌ„½Û~Õ,ëÎÛ‘Ž€eýYïGšˆô¤7�. y ᇈ ûñÓ¡$Y |ÁºM-6h"Û›«"àSðï7W~†tRt"á¼µ­Aþ>?S½ µA‰Løj¯¾;Uþíù68½µµN–ÏŽ“¸1Ø$  ÓõÀSgy9±HI2˧ïΕÿó«&qà¬ÕwJù¡—$Î×ñ >û) ®c¿ùF´šÔ|á‡6ˆvs�]€LœüÐEIoŸŸsùNè�ëëo3ÿø¸YE…ãDK3Å�Y÷-¼_Þž×ám?_ßÑÝ…,™ó`8Ñ­ŠÚRžF †‘åÎÃ…Š 'O£öA2 Ž]|™+²먿òç-Ýc‰W·;xñÿ³÷€qçµð·½XÀ€½±ŠU”HI”d[²$ÛrlE¶;ñ³_ìç½8ÉKÞ‹ó~'Žc˱-ÉMÍ–eQ•")‰Mì`ïI�D%z¶þçÌâbï.v�°»ÈýÈÁ¶{çÎ�;wîÌ™ó�ÏûxÞŸY>ê#ÐñçΖöAžo ~²2N]±#ªŸÉ'SŽ�¤ oh¶q—Û»|ÞŸéÊyQðæÁm�¢Î¾,`µŸöœ… 0€o£Îuz®ßr(7; |òÞ®¯ŸÉd#ÐD¦Ý 3ÁŠ‹…{Á¨žŒ“`^Gºp±.詾úý8•eà~¯!ÂÕiï�ñDà‰î€ƒiŸ‚¶ üýË–.Fû! Ó‡Ãx,‚•Ôxº mu/"†}ïñ(€ýúCè ê" ^º9�FÁ}©û”,ñ©¹]§ÕÞÞ*׊ %!9UÎ`OKI4É’Yˆp—9üYO tBWÌE‰ë[¾ïT‹ì=Ù$7 .Þª±ÆêJ@󥳓äÑ5)2gR4tŸ°Àr´Ñm¤¼ºëYtÕs©†õ±k ¿ÎFÉ­Ìf³LŸ>]&Oî¢øõ€­¾¾^i<:tÈxÒ\@4Š¢Ôž={”Øù¨Q£‚^ýÉhà“û;BO®üÎÅXëÿÚl¥RÛr\Ú.b¼Õˆq§”—v2÷é>–på뺧U°€Pqæ ˆrO—´øyk�M¸ßàôa®ò ü¯ ÔÜÉbn­k]%ê„Ϩ®IîÀ0 rðÕë³èêìIo–ÙXÄúèz”ì.i7Ö¶ÙˆVÎCš„ô8ÒH›‘¸âø G춨��Þ0lŸÀÙUoÃç-Æ®áj0émQ‘“èC DÀ§>TV6Ý‹m?A"%»±rú™Õ)2='Œ ÷#ÂŽ»ï¬œî8œ$ùg¥‘)þ´£Q¾÷t†yz™YÚ€¢Ü=/]V-H“‡ª1jj–ëG_�“ÖKBÚ$ N‚;I$ „`Á Ú|" £«íŒF¦ &óœitwâw¥®ÏÁúKw¯z¬-À!S‰å鋸k#7Ù‡1¿XµtäãG¯¯Æg i�Y(fNF³ï ë¥'«C]ž¾jƒKU4Žž[òsf§7…¢YÞ¾X"Õ}åb$³÷1)Õ´£ú’OÜÙöaR=ì 6{ËH5j8ÑM® ÂνY;æfy£}OÚ¾té#¨E·I‚J��Ä+evÙ›°/ÒÝ� £q™ˆ¨7N�¯«~Þˆrñ†ûߣû˜ûc÷Lúð A§©±oþD؉Anj¼ýµòè]#Ý¿¿Û`ú§/F)ô™»@fæE õwÛ‚Û§ô§ŒOO2Èj¸…’yjc`ÞtuÔìWÚ}œ å`™ŒÔx¢¦W°ÍdŽ•ØäñÐqÛ¢ã–ö¹töŒÔTUISc½Šú6zD´,æ¬'öcfÜ“hF7-²ûx‹<Ý¢€¤vèÄíòÆÆ97Ü�l¸g!Ü{àÞR\fèÔ¨´k­úg{ ®ÇM¤>öÜÁ¾ŠÃ"¿”’nwê©›‘‘¡„ÆG�&(<»Œh�ùùùBJ3NzÐIûž¯d@mÛ¶MæÎ�«Üÿââ8O ¾)Ј�ËÃø� ”dTâãíŽj„µ/’Úæ“Òf­Æx‡r:ž÷<Ÿ½²˜Ô.`jÚ¡j­”ºÖs2"q!@¨…m¤¼Ãðl®ÀÞ$>!JròÒÄ^sV,MÀ|Y!ÝêÕ£’ïˆZ+a #¡R²Qž™-we™dëuh}Vt˜Úl,‰É¤iH_FÚ‡´é Glf±EÄn›èË<¡O'�Æ Ö£ãvÙwö“VwØk/ëïwXmïtÙYs”󒩃X²IVÍç½æ6>cÀ‚‘jRƒ^S¥·ì2sJºŒ•صÚêÞÃó÷7cV=v¤Yö«�[€ "°Íb‚’™·Ïßþ&ÈÐøóu˜…ÂôÀÂ>¸·|rÚ�Á�»,tC78ºãé�� 'Û§¯Qà[ÿKàï'crõ� QÊ]‹òhv6ƒ BaaÖA_-îNÓÆ»•—ùØ¡›CæÒq�’¿ü[nF$6³$dc½h¦Úg_¯\a7¢â¨O�òx[:iŽ�ÎìëMÄ™ }ýÖÁmŽî¯ï†åûaôÐ%ÄÂõ ‘Ø|�ãxmÉ㹜G$5_ׂÛè¿§Ž#ë‘9ÕSž¼Ö—ÕM¿oO§Áò4!ÐÃcú2Ö)ÛÝßÍ�‚êdBiÖ�¦¤íÚõÊ2°m=ލg�Þm¸à ¬+‚_¾Î·kGoªàª¹ý„K¤ßÇÏ!ûŠuI½/ºž-vÕ0Jœ�®¬¬ ÍÈäýÉ¡¶Y9ùé7bd:®©þxtÏ$c»Y3Ǩ¢eêuàØ/³ÔƒbA)ŽÇcZZ*¤úêv±Ûè>l—úÚj)-.–¶ÖIŒ7aá#YÖˆq©ÏåÈaË„çGö!ûƒ‹˜„mÜÑ ø°VŽœk�h¸ý©Ë…•iѲú®d糟ΰ¬œïÄê­i÷ñVyiS­äŸm–Æè@¹»žÃQ¤�‘"Ì'Ö†cO½ éÓHÜŒBã�=ö˜b?ñs0Œ.v;wî”wÞyGêêêβ¥¥E¨É4kÖ,!*F�©}ûöÉÉ“'ñ¬ƒ²'ÀޤظÆ�“&˹Yÿ.Üõ÷C»®i¶ñ¶“EEWŤ¤$!xGÁvM7‹`µÛ\ƶM÷íiî(‹ýžOi˜ƒðóð ÅÉ)O$(Fg'ˆOOsñi*:.N¼É#æQ¬”l¸ Ï%ãà=aq¥¶Ãa„+�ªßOGZ‡ôA)6 Žø±d¢P·£ü)7;+Æ4{Rl¯ìü¾VoG>oO\l“úf26´ÙˆÔÏYJ_KÙ~(Õ€ ]J%º}ʲ§² é~žÒî�²vQ¢¬‚8«EÏ~ÂûùSãäþe)òî'µÒÜj“×7—É´¼t r çÞþ�ƒÞ)ã¢åSpxiÓ-q`¢Pvö-3ós’2j1:”È6Ý~Y‚¨q-6ÃõËáë.wÕyxoÌSdD­�Š>R'ⲌŠ=³ÿ|ÿ&ŠŸ[eVA-^Þîx Ä-Šc0²p|Κø³wݧ;ä¤S32g*¼ æS_�×­çt®õæCØ› A’9Êö§SÄc>¹Ê$_€ô�ß±Ê~Fm �]®v�]‘}'_î�ÌŸŒººhT‘Ø´c²ü_ZkVçöW?‡^Jg}sÂüÜû6ùö§Ì,}tÉ~¢àva)t¯®¢¢0²»¨sC]©IpWôetgœ:Î$¯î°ÊFˆB¿D÷1Nd©C¶Qè¨iEà†í¿¿ãß肾d—"¸?†ÚÈ#Ш¡ÿù60�%/ÔG÷Ÿ?™u?ÿ+¸6aA7ß.]#´ËDô ‡”¸¢’]D UkÇá8¶v ²Lÿêá(%T¿zz·º®ù¤¶q0^ñÌQ¢ãñ™›&–¶q@Щ©¡ß»&t©ÉfY85‹'®e0Žeêµ1ÏÙ3_Ø®v¸Ö�•[M‡±Èw{øïë233SŒítW$Ø”’’¢"èñ•ù—––ʦM›äí·ß–¢¢¢.¡u2�ìŽv©k¹`«^Ƥ¬ð5 `2§½ <½Îc0?RßtôøT0ímb©¹½'?ƒ»Á,ä9¶vU¹`œW¼ûÀÎ^˜'gë¢å˜œgj¬Æêfk¶ã½™Š4 éQ$¸VÈ9¤SHg�®"U"@¾Æ2�XXk€Ndœ|¦¹¡h$A4Χ¢ AÇ…güÃ¡ØÆxªA L§|n} VQ[¤)Ž]¨“½Çj ÷¯ M _ ‚Æ�¯?À%ƒ¡¢æ ²ýPŒ”ÜBD‹¦ ¸ß=/³žðmM!q}d(®òÓ­lÓ!_ÇG¡uÆÉ!5Ž®UÚájäI¦£{Ìâ©F9^hhâF�½NÒÁÞaDµ`êÌ�™¤ixèNÃï[ºP}St£â$¸­sBN Šî7ý5 �Ó�j)€>#ÞF�¢¹Ÿöžu»ÎyoÃkFŒ¬3=øä½]>sb{HÔƒué´ÄîƒoŒm•˜÷²é˜˜a[m2ÌW²E ñúk #‚n Ž9Už¾ÊÅ<Ç!*ßC‹MjÛ@Üïø`ãvdÄøŸ˜of2FrŒ*ŠYn5ÂËgD#à´âÏÔè¶ÉcõÇX?uNÅxÚ~îN¸·Bi÷€Qó7�GK!DÛÿú÷ �n´ƒm¬²z‚‘¥×Ÿ EÙÈ ü,ØŒïBÛŠÂÝ4^_ÿYGXA8¶àØÖ‚' �w~&À3!:ž"Ñ #¤¥®¸ë�”’Ñ:ndŒL͉é¤vý<ŒŒŠl$Üy˜íµm„ 2r¤’âWA±ÚÚZÀ�ýÓW«¬¬”+W®YPd…ÊÑ F³XM�ˆJV…>Ç'ðäLLL´-\¸Pî¿ÿ~ãŠ+L¹¹¹’�� XZ/×t¤´ ‡=³>Jîs�`îó[Ü}N8Ù_d:~ó³Ðe‡» [�p±’(Nl4'ILBV·\ér7#/F2RLϱn�/8È%èdÃýÅçÈÎcͲçD³”c‘Æè´fa"ØÅËø,3Ç ¿Cÿu §�ó›åí]u†Ú†nl§ œæ‡H¯#Eâ¤+¼ ¦Fði’‡’©3nÜ8INÆ A�:Ot·s­æ÷-ãvDu¬©©QP¡Ÿ<Ëe—K ð“vŒöÜÏR–:++Ërß}÷YüqÀ§„ÔÔT;Š´÷d¤X§3gÎ4|ï{ß3µñü¯~õ«Iˆþ—JP�F7¼¶Ž*)­GSNuJJÌ\Œ5ñ@óÀ Ô¦Cëæ“ŒŸˆÕ±¦"è=Õº®s|êõ:iOYŽÀØG&ârOK5BÊ &DÉ�f‡œ«E@¥Þa¬k·Æ ­’©BC… GûìëØPù°ÒÞk¯<”"3ŠOq~Ö‹·>A‡ÆWô¾¦ýæñe/x<îˆM�Ü\'øôß�®#é˃�w¬ñª‰å_< ½Á«^FÉí¼=ÙÁDÀ§àUï°Ê©ç§Ö°:•!YXÞÌ?BZ�”G¶Í{ŸÔ˺Š’•†hdº;œ�ïN–�ò›¤+«×0H>R"Ÿ^;“PWlp´¡m£Òrb_áî7 ˜¬[” »ŽÆÉåâV±¶Õʵƒ?‘Ôì%ˆ\”@ŠÛû6vLÓ1Ù¿¥ÓÀñ½µïoézGPfí<§Ö¶b¾#0–\4ÙÅ¿‹õS21��GWD÷¥Ò¬µcôçU.é÷g�f ¼SÇ<Ü[~W1ž£ž•¥ß¯?ïYЏ3ªÜ Ô}g‡ì‘U:Ö„9!½w²_~3ZE‹ ÀBV� L¨€'­ ŒRw ÅÜ<§ä Ê—·p¡.ÔסÍuø²{ÁŸÀ¡/c™™�.}t«ôØÐ¥ïnD‰»Ñõ@·%�‘äN: éäÉÀÓÊáj�Uß%Õ#nÜ—@Ý WÌ2Á%Õ€ˆtÐs¡ü�Co¹³.ØÖOÙ%ÿ¢nƒN%Ïû9ØF–Ó¨ï~Íâ2ëOÁ>f ùÑ]qÜ|GãÞÿ‡WÜhS(�'^O}?° 'ˆë[»ôÙŽAÆ‚õ·pŠÈ+;Ù#Ûð¾…;�9F¹Ýy!%É,sò0éÅ}O½·¡h¼¶œP‘ét­Ì&{Nâyz¼šŠ.ÐI»¿ÈtÊÎŒA”Y€Nw%H@§h€Nd4Z ûtòb»¼¹£^N´Jk»]ß^HKÙ‚ôÝP¸lã^5Á‡ˆõZd#à ç2‚Ot#‹ŽÆMDknnºÞõÇèz×Ñ—_DÀ …Q‡‰šTš“�újÍX@Ô�í¢¢¢lkÖ¬iøö·¿m\´hQRZZšßAŽ ¼F uóÙÏ~6vñâÅòâ‹/Ê+¯¼"U"@#ØÕÞQ#e ;Ę í¨˜¡ï‚Çam üÇÆŒ…FjÕU±µ�²êê¿ÔIEþôZúQgÑX…bt¼t0>¯%Ç,­X$³¼ ž�v©lu,vS›Õi¢¾¨~.âu@-{íÕëç~} ¤á{Ï5‰rn!^z³¢O0WAÃø—#NvrN;n*>YÉÞ•8Ðò°Ëââ^§ià“ö9òzÕ€»ÜA'æS-Æñþ é'„³Ò‚ü¾4ù·—Û{ªæÆa)=õŠä.þ.zXÿì§W¶[áÖ·–NW×1úöW›D€Z í'½QP{ÆôŸÈbr�ÃÒipÓÂD[Qxþ?xÝ"Ôv 5ãƒ`AÜ}ÙKà&–%ƒègšQŸ)F—"2‹ðP'ÈÛÈÔ¡ûÚGÇDÈrÂøQUÉ{ó�|fÛ*­viMÀäÌߘW1µàªFöÓAZÓÇ9dÞDý¸À} <#›‘ýD ‹ûø3F•#sŽL²?ì²´ò¥�û0š °ŒàÛm FÝ�¹y&Y‡è~ÓÇÃo —î!Hj‚lßd6]†žEÕ¯âžàõ'Ðhy> nÃù“xå�…fy5 Qât‡îöÖÛ½–î½tÑ|ç@€¤[Ž�A6æ—î5CœÞ(ßzÌQW—$7ÑÆÿßnà+ðû·%Û7ûNÐŒnuÿûU‹œ¼êþNû-ܯFs´DÅgx–.wٙђ36ª‹‘ë±Á `�’¡JP¬ð¦U>àtðT‹”Á��L'>gh ö0:#ZîY”à)A1�c :™0íÇ6åµvD¡m‘Íû”+¼N§±»€ô*Òi$>5¹êï¿sÂ�óYD™º�&ºŽ1ÛÈ^bê�qQ�”';©?9ùÞÇjµ*`KŸˆnê�§É“';Ÿ~úiÛ“O>™ —DS@'ï#Ü�——ÿw÷wJHý¹çž“›79g#vH[{%¨m2Tbt¾í>.Q�?˜)KÖ¨dµpÙq¹Œ1m†ny‡@•õX}'ÆQÕRq‡&Gƒ¨{í&iCo×T¿댵Hõ�©Ç¢Iú×ö­x„¶‚jÚ‚qN´ :\LƒZWþZ ÷w�°ôƒ ÏcåO¬V~œd>©þŽÓž*»¯gü�¥×Ug3‹ØXð)ô�ÃÝ? =‹4ƒ‹ì«—–&ÊÈ Oö£v¬ÁêëÆ�±r½¬ ¦69„è;ë—$ªUØÞŠÊ›zå¼XÙ?/Ivk;"ß];ò¼¤ç¬’䬘d¹Á}^Õ�ôùÔ5;åX�?&%ΫýÆ>ŒnIK8øÂ³|ñ³S~ò®{²G6L8Œ@ÙU¾¬µÃ©4�Aì™@T¨Ý�ø|¼Ó…ëvY5»ûíH!kº¦‘Yô‹Ý }�×@¿#ë‹â{Ál‘â»îx j•Öp%·ç#„)©qȇ`™d�0H¦Ÿ< LƒÖÖŠ™hOùodf–Â}ìŒ]J^¼é„––ïr2OFg$³ª¦—0õt·$Pµ~�Q¼!ó©? A%«t=%Ë鵌0⃞.A½ÕWϵÙýW–q4Ú #7jöÆŽo—Ýgz¹8Ú!xå`ö{�GÉBD<üêO:ºtæèÚFva8Œ.Åtùd k ¢öÁ.Û¾àÕ$?ø£E±Þ´ü‰´©mÊWƒ1J¢b@Õ]ÑrGGCÿmh¹Ü)Ð ·;™N…×­.!qh:UPÓ _j÷ûôé1xN&ʺ% 21;Z¹×1ÊÄ 7àšwàL+\óÈ@¦¾Ÿ]Û—7Ía¤ß!}ŒDw;÷à "ÖçàÄO8—X�:ç ²‹úcdi:JýÙ¿·}zÆà&'?ùÉO `;ÅÀmÎà)LÞ[Î~'c* ɘžž._ÿú×ÓìG?ú‘ÕÒ^"å ÛelÚ#gÎö›Ù`ÿ@8#{BšÄGµJsíM¨QDnÉ`]÷È€2eâx4)Ï�ñÀ‰]# €=‹øžãYŽgèÔÑ�?  AUß—R})Ç~D5\ù{ŽÑ:R¿BdDmÇ­•áGþî:fçwºÕ™àO8¨›¯µIy³EÏT­Ä¦¯"‘­z©)bž5À "œdpW¡’]×ÇsƒòÌT»øÚ뀳�d0|j ûlwø”}8•´…}‰ (©¨²È¦}MòõGÓ< wvÜ™ÐÑx`i²¼øÎ-Å~Ú²¿  quÚÌÁ·(Iˆ3ÉS÷§Èù«mRUk‘Öºëreß¿ËìOÿƒ¨Ð Ä’¹AfÓe°9æåñQà6NÚé>¶çŒA�N÷Î3*Ö‡{‹ð¼ã¤œ`ΘtßÇ£¸ï [,p…óì%}oœo)<~¦Ø ¶Žëáî�k t°fN0È‘‚àƒÞÇò÷™m³àIOn6©t“ƒðø¹b£bsùËKûžãÄsЫ¢›Óç±Ï¨“FØÊYfäkUÔd9= ÷±ÿó«hÂØwþúE¸Ê¶F6‚ÞFfËÊhjþÀ'î—@lí\£¬žcVïY>Nrûb»ˆ)ªˆd�ÎŒR“�P²ô­Þ�”X‡…ˆÖÄèu{¡éTé :a£¬´hYЉL'Fˆ�Ãj¾îuÜ¿¶Ñ!; õñ�F¹yË÷#¸C¹ÝâI§Ø‹ô÷H‘øyð~›X·Þ”`O°�“)²—úcžèØ›®Ròæ>t dò6êKmذA–-[&v¥t=‘·<óÌ3JÓŠ (‘«¢Pª©­Hn™ö" Þýè¯É€zMÞQ¶1ŸÌmÕbk¨Æ3 cÚ�÷õ¹Ó>{_yÕ ñÇ… ÕZhWËb )•ZUUÜ_ÉÕjÛ©oƒó‡YrLg±dO9×J0÷íJ7¾Ú‡MþéGýC¢±ãmn¤‡*üV=ú¼/z0N>×?ÅŠäþˆ€Oá©sÞÆDzi'?¤ó?°,QÆCh\7ÈU® ÷.N”·vÖKM@�Ë-rîj‡,˜�»•™O›#Ÿ[—&¿€x9ÅÇ+ ·KÖÅ�2vÎW1ëý<�jbgO £ã…™F�~âÏ÷dQ˜úý|;X¾YX�g Ûp"ºÑå6ÛÛ8�¡púMB…a4‚WáVFíŸ YÝ{gº-Nm’Œ$‡ŠèÆ¢) Í ’ Ù¦C6ùóuQBö�·qÌG½šûàšv UZT@ïíôŸéJ—ÑQzƒbMéÓÞs`ÁzY=Ǥ\êÈ@Êi” Ðub0ok¼¸‚ƒgh\dòetûš-åó×=å9$#¾Ë²éfY3פæy®ú¶ì¹‡ïOœ˜Ó�nÇ)DŽ)E¬@F+Ó¾÷ ηtemn§f \y¡ª¢�.Áɽo¹ÐE‘S½ˆø‹[m €«ë>çê[ælM÷Þ¿}"JŽ‚‘ùÿý Òiçö†Ëئ˜ì|c�{LЕ̿p´‰~�+Êm0yÞèQ¸˜)ˆz‰ŸÕX§ìÁ¹:~ó–Uvm–O�íÕƒédi$™Nód-@§<2�àÊÌ}Ù¯tàžû¬eÿío+ÕÕ®�@N]ë)<ë3$3a% % wgT¬YÆMHgÓY±´Ô¹Š7Ø�SÈ®ÔÐɸ«‡ì¥HÚ¥P¯ø£}îe·€æs€ûŠ!ŽþNQ‡ì-k—º6»&˜ÍÉÎ+H?Cbß ~uÄz¨†uòñÒ1w#à;>Š#vÖ@| ßE§¯ñsH¿A2T×[ä­]�ò?žÊP²Ö™sÒ:.Ó,Ë1XÞ´+° o?Ô$ ¦2XC`fÄră¶Ž]€ÛÞÙF±YåÚ¡_Àýî>‰M@Šc¾Ð'½ˆ.�2ú?zKŽ7@gÅ„ˆ^иéÅÝI¿_0Þ<˜€òLƒ°7Ù9|hyÅ~©CE  \ö�OEÁ=Ì�EÎÛˆt¿%Yvº¥1j`UCè®�þœuð;�F)פoü—k‰îJ‡¡O3a¤]¸Ëµæ¥ß‡ï)Ø< Àã]ˆ¹­7#`I=­í'lʽ͗îó ›iÁD0e.åOp; Ñõ]p±óe¼‡jlT„ñ>1?F«ÛuÚUŽí�ßQŠÂÜ€§x9iæ}1›šW{ÏÙä˜-•õ.ÐI· ×—ìzÝ6ݧ–šÔuÑÜVy¬ï¿dA;îu÷�n@à矊Æ=å�oþ 6k:o!=xgædaÒÔ(ü‡Ûèr̈¢¼.lo[/¤¼ œ$!ƒ)ì S×3sq妄ìû•ïS^K‚µV°œZeû<ßÊà^9­N©û1jDŒ¬š¦˜Ã¹ÙQˆ M',¿³?%K÷ÌÕv¸§·Hþ™äe�öNÂ7¤€|ˆôÒ1$ÞM¾;ü±k€&ÅÅÝŽš4$úsÎCƒÔeŠº2ñzCwµþ‚ZžFŒ!ññ^‚o ¤7–wÚ´i‚¨tú¯Cúž.x4W‘ý6nÜØU&›½Cªš"Úoº¤ÆÎK�—r:QgO¡ëÔ”™/¶êëboSsglÉ"bC¡BÕRø0¡�¯¼´%¶·K1ëÛ cÐiÅxýO¤·�è"ÝõÞGÌw €: ’D)û(Ø•†åÅ4î<<�§îžÎ#/·w D.|ø®/ïã·‘žEZʉȶü¹wa¢Ì›ãb5�BÌï &"â%ÊGšÀ^@èu¦þÙƒi2zt6þÒ_7%É(O=�*¡ÕÐd•¦[—¥äÔïdòÊF‡@&ý¨º¶$�QÂÉåñB;À'ÏæÅ‰<) ýR<;\F7¤}š®"¡¶ E¼}Y"î�¹^&µfNp‚‰%pCt‚5VO²�*j [³sàzw9Ä«�è~ãp­ÒÀøÏE„; Ø 0öþsvU–ì >;<�ƒ‚L¸É-‡à7µt¨Õ›‘T~Á'ÿìrßÑï˜/¯ãŠ™FD³IE=Ë_Œº�2Ö÷VÔrÊeT€W ¢¸,@4ÆÅSÌŠ�ÅöÑЉ÷,ÛU4§Ž\¶£ tÂ=@VE¨Y-O¬4 Sî(»‡Xö`O¬õc`@x¢°<ë“À\(�¬ÆO/3ƒ]Df•ëH¬‡¯üg‡0šf¸Œm•=Œt±?ܸϮ@Öê0ƒî9g#€§¨¸41š Mع`Ás‹ŠâÙ…×´:5`ÂQ]g—ýŒ¶j”+7:¤UÇV"蔕-«$É}ˆþš3&Êå^ЉìxO^¾Ò!Û &ž®Yê¬Jˆ\»V8«z¤MH¿C:�Ä­9Ňˆù­Bõ•F#�GÊEšˆ”ƒD�‰Îî¸Kª‹êÁR…t¡:Ôeê¯6òñkd/õ×mnÔ¨Q¡o‰� |ñÏoA¼~à¹ÖÔÔH}=›œÛ‘ÎI½§1c@£�=Z¾ûÝïJYY™ìÚµ«K¤½ÃÚj¯Ä˜GHBTNKÔó¡ÈòÏ/ihqÖK%Ð8¥7lX«¬çF~ z ð9@¦ÎUÚeû�v¹Œ…ƒ&¸IsÅÆ—��þé8•Þ¡Ø(bÂQ¼”¡ÇÅä a~ê9Ž?�w)'|¹iƒ\×Ã!;Ot`8”xx—‘K\?F¢ ž¹¡Ù&¯n©•é9#Ö:JìÆ4|m‚H_»Ì˜l•Y“šåÄE¸ß�%µ÷x«<õ`²Þ%Ûö`è‚çLŒ‘ Ë“å�ÕˆÝÖðé55í1IÊœ…Æí‚ÒC.ÿ4}œA¾ÿyW´±yݪ„•WÍÂàÀ+‚£Ì‘Aarºq…ê.pÅž�ÏÐÛ8Y-,sÀ +teZ<•Qô ²]¼½¹Ï&Ltm› fŲ öx£«‘ùD׺çÛ¨ÇU�z¢(6�“±¾éÒTjäô«Ó ˆú ŽÏ¯6úižå�F˜^äyðB`ˆÙf)fç8d´€|A¡¹yˆº‚z »®'#�¬—µp�ó$± °.¿ºÞÕØê+Ó‰ Ý©[D×AÖ £R+T ]…4vÏÿý|\ ² ¯ƒi‹àNKÝ®½eíŠ`ɶ¢g<…º|t¯cDB^ƒ·uQó <Ý!õ¿xÐ,ï´+-3íœ_äè‚Z9zÅÊ$:K»Í"Í5¥¡ ãw6ôNã[+•cÃh¼W�X8hl²Kþù6ù‹2¯¶Â­×­ËÄm2R¢e4�Ö#˜Ç¤±Ñˆ‹›… IMۤZdßÉ&X� D®;5>/"½€ÄE"øðDÅQ=Á£L¤)H �f#l"øDŠ�+·á+“6ÙÀÛîÖÖÖÖxtÿµÿßP?‰®e}5²¥¦L™¢R_÷ dûŽ°Šªª¤±±Ñcs¸Ü9çÍ› ­'�ãxÐÎ÷;ßùŽTTTÈéÓ§1Þäó›nÜ¥RÛrTb’Òñ<%�-¼}€wYùÙ�›wĨ$‰5·K[C…8û)*ï+ïÈwC§8ƺy®U6#øÆIh ¶@ÓƒQ"5KNŒ’esåþ¥I23—šNìç:á)Hœì*„ÈwBˆ|�&DŽ ÁõNcc½‚ôÒF¤KHaäÉáhÃÇÐcJÒ4¤»�ÀÓ•©H£�°´£M܆0?­„íŒì^žÍÅì¶w¢é---JÿˆáAŠì†b€r5fŒŒ;Våɼ}ËBÓ»ýeeeÉÒ¥KeâDâiÁ72žJKK…ç­ÊáÌÍ͵çåå±~|?\µ�CðJ–تU«ä›ßü¦üË¿ü‹«£P€¼®õŒ$ÅL’”¸9¸¸ÝÇ(!(N�Y’?‘9*Y¢íMÒÜXƒ3nåpuN=–,òc0j€—’ㇺ~ÐtÊg$RD/n´H Ç[î>¼ÇÛ„ô[¤sH\äwÿŠ ¨Ôƒž=¤[ö0 ýވה(�ÆN„#ý®/´"¯· DÀ§ð_còH~„´ )–ƒè7·5Ȳùã% ÑwÄ@ú¨!£�²pfªLÍM•3ur¥¤]ö�n•G–'J‡näÜSñ9Η%Ÿ^“*ÿõF%&©¸ô¾dÏý¢¤e/G§Þ‰€ô”‰�ßâbD^l’�¬qm@7§o¿`銦U& E~—dòvs#jùL“œ¼|í§î1Ëã+Ì2@ʼmU®ZŒŒF­)_ –žeÝ �À‡n%ÜÇ™þ;Y}^(TÂ5Ë_Ä8º¨�ø´vžIyÞG£~]÷�s D}ðž­ûàF÷ÜÝè"ˆñ¼Êëˆ\h—)Ù¾�"‚I“³MÐUr(ÁíÞò¥ë™3§Ž %Û�/c[bxú¹éÖåÏXF2¹NÙ>q>ÔÝÔà¦��=2äȺúè¸]±ûZ;B :i¥æül"€² ð L"£Ìÿ¹kû„ê•.YcKŽÇys¯]®ìûõj£ÎÕÖ@hv]ðÆþ„)\Æö3úfì74£žÝÿd‘Ðûæ�Hµo®¾,LQvþ]i©»*k;ú0ÏëÉg £5†ÒX¯¼û9¾tÍ"[ÀtÚwªIê›l+ÜÇŽ‡Øð]3äA€Nó&ÇJ"X¥6¡‰™Ü¬²ÉŽÃM²ëX“”"ÂlA'÷e!ètéOHž@Et�P :ãø�`Ót$o°‰îsœ8°sååòèI£ð°MIŠ’éQ’=2V²GÅʘÌ‘%©IfIO‰’«ˆJõ‡MeròçŠð¿ƒ®5–‚ <1_‚O .”;v(—2~§7O]˜¬V+ÚF`ønñâŲfÍU&ýöÁzëÖ-)))QÇÔòD8srrî~õ©ýŽWŠ«?þøãröìYyå•W”9�k±6Kmë ‰� (4 ý'ó:†ÈĈ‘ bh¯[{îzö ƒVm^¥‹|ìo àÖS®u-è¡/TÙå`…MŽ#iU‹Ui:é€R?Dz éÙªì×#Ö¿ ßªÃ�9© )wÇŽ1pÛç5†|â¢Eä¦emÜaŸç‚ïÅaßEúùz+„Seê¤.& Éññ?^’ð©Vi=½ûI½¬Y�På`?¹Çà̯qílíÂxÙ~8ùVéh©–›Ç^”Ô1‹\·|€ùè@!j20¢Ìyýw_¯ãÎI:£}�¼b‡N�g3#”‡±Õ PïÁ](˜cFc›6Ö¨€2¬žXiË á’}ãŠ�t ÙÇ`aõĤџoïÉùóufùÍG6ÀiÛÿ`XOÆ:»qË¡êmæŽç=�¬±ñYFhD•›—ç¯�}bÙÈ ûÁ­*ú÷ªÆ#üéwè'f½fF6ÂE€0n8â½..ö“krîÍ â$Q7TQô¦fäýCvdÜ8“0™ô6æKàƒõèõäºI€îô5'¢ä�žïåþé�ooŸy¿•×8ÀŽsü³K5XjŒ&*ã9’ýE|Í^ÜjU.wסe5XFðë‡ÏDcò—ÅŸvt±½¨kôÁaO "Te䵸­+b¡A«>~úõhåúíç;ÀÄs_“} †¾¹A§ÖÚ+R~ñm¤w¥¹ªL§Ö.�qýyD㹓3&Vò £Š3ä½­îx¼)­²Ê°•¶i’2L<ô.rŸ3  Óò$Y85NérPËýéžWß�D,ÔlADÙB¸gt"xÛi¼PeHt­{‰®v¤ž„§ñâ@CØø NGš„4 ƒ™…”�äl2H˜4~t¼LΉǂY‚L°idŒdB+9ÑHê.a¶A*¦5ÑQF9~®I¶í¯Æg·ô ¶Q¯éž{Ê[o½å¡+¥�€“^oŠ‚ß`fϦ'ahŒ¬'&½�9Ò¡qtŸüŒXô[‡î}rr²<ýôÓrüøqÉÏÏï¬'4‹¤)SÁ.$öèî÷BW9ã°G¦¤ÆŠ³ bãXeQ‚ß||<òU°k€—�cB²Ùª±{  ÓžÒè9YÁr²K;']K#È´ é÷HÇ�È|R¬¼F¬ÿ5Àç Ó‚‡¥àÈÃA¿ŸØ½saÚÕï:yÙ)¦¹kQ wšq°±ð×;ÊŸ"=„”l³dËÞJǪEYe25`ɆUÞeóÒåõ-1RUÛð¨ z­òà݉+À=߉AwVªI>³:E~t½ ƒph²l“±7÷Kúøµ±úÎ~z÷ MÑeœK¥'£ÖÒ� N™—GAmÏþ…,ž%Ð~:Z`�¸èõÕ8†%SfB˜ë—ˆTÔ‰�ÕHù߯Y”6Ð×7€} ÀÁ2cþ´®&ÐîaÇÈ ?Á=v�|ψ6<øè:Ö0£ûô–Ñ=Ž®7HÈþê‹Õ@ñX=Œ¶ækNð»À|9A÷þ€eO‚a4àܺÙrÄ}ýô@P åeðúºd—YÃ|Õq<r<ÖøL#\à\õÀÆ—ÖšeÍ“üÕÏ;º\ò(öþ¯ºÐºÖ1RÞƒ‹|wO¼6tñZ ÷»ž^t§‹àC`êõÇxžÔ£:¦Ñž³v)ÆyÒús,mê'1 ⥛NùÛߺÇTšè»¶Ý`¼òþâ}á Û¹pUy($nCó!»’FWÕŸ½oUÞƒ<±Ô' ËÕ·õ½cá7‚N.×íV°›*.½#åÞ‘&‚NÖЉÛe‚©²`j¼Œ#é‰F™ž‹À ×-?ôØÏñé ÿè`£•txD°ãbÇıñÐ1L’åsã¡ñäb³*à šÑ?Ÿ¼Ô*[Ò=¯í “»œ¼@•H[�þˆt‰L'÷ê >ÜaFô€Ì¦IHs‘èFG–Óh¤$$N ‚1êz€ÓenDzŒL/3§$ÊL�SsãÁnŠ‘”D³’ ˆ¨®©¶—öŠŒ˜ÅãJÅ1k—µ··+4º¾i �öÛ@^™Á¤gŸ}V±xvîÜÙ4invÚ+�3~üxyæ™g䡇¹à!³X,rãÆ ¥­¤Ï>''Ç6yòdØ_îŠÑoÆ÷³fÍ’Ç{L®\¹ÒųÚÀ¦í,Üïò°‘é|ÂX&ý¡LX�KHŒ‡¬'+DZ¼Å=š~óÈûÖ€êgQ½©4ÀüØï3O#Þ´aLq£Ñ!‡+áZWÞ!¥MiÅü²|z+LJ��ÞD:‰T�Ô÷ vŠ˜Ï øä°c°ÕF¿kÂ{*¸ —kw–|Î z_ç.Nä]¸jÀ÷ì.\G¿³�ÃΓá/°>WÔlNFal’ )Á0L¼˜��^Ÿˆ]OÅ®7ê'Hà€±&IJ`tSŽeœÒÚڪķÉ@Š¢`e�Ñî–/_.?øÁdúôé²iÓ&þèÙNšæÌ™£@ªÏ|æ3’žNXh¬®®N ¥ºÚÍü‚»›}êÔ©ŽÜ\?BŠ¡)Šß\Yg¬‡mÛ¶©r0£5·_¥ã£tÜ¿žã:¿™ù‚f´¶=‡¥ y÷qD�yGgÇ{º‚!í¨f�% ãc> (ßÃ…¨Þ)îßÕßã ×ÚñÈ)mqÈ9h˜ž¨¶@@Ü&uGÚÖ�{Í@‘l©ã´‰}x–ÀîÈþ§Rãòž’à#ó‰×”×,؃¹«._v²ƒÓ‰ûÄ"ùõ©"àSŸª+¨½ù ÒcH1VmÙS)Kæà�ŽeAµ‡›Ÿƒ² +ã䣃ÑRU×!`/í:Ú"�®N Xû‰ì§”$ˆ¯J– WZb!ŠÙ•R_zXÒÆ®ôË~"s„ 'úSàUPŠõѪ$ÐM‰ÂÔÌGoI`CÍŸd’½iÈ¢éÉÒ1XE§¥è†ÄõA‚aìÌèªÄPëkæÁÌòèà<²f§ÚdŸã²§ÆäaÞfäÅü8©Ñ:G¾r{Á²™`$Yñd$°F�ðl€_Ñf§üØVdª�! ë“3ý ±Lå +°K6ÎÅÛXžL7 ¼]�[£V6ïíèÖøwŸ‹’[RÿûWØÔ\F¶Æé«Ú§�½òØÌŸêdjùb?‘ÂkO�$�©õë�\×­ÐO{"ÀCý mˆ øt†Ñ§þ•^’%ô~¾ð’m˜Œ¡m'R]íz:kžS@§SWh—v/¸¦!Ôu"�H½«¶X•x8ËF ó«?éèbóõTÞPþöø “|qm”¹l—ÿów¢›f¸ìtÈ3Jå`#y~ïñhÅ|ÜFž$€}Àp0Ð(Љ¥£©T*. eçþ(�ç}‚NÔä¹{@§E`³Lˆº¸Q¼›æ¯¯ékðJ²#ÖÐl—g:åt*nE´3jâuv¸Ø.9åö0´§æ@L“MöÏØÏ V"ßs¼Y.‚L¦“¶pÃ-`˜.I>Ò¯‘v"Ýi“,=Ȥ©Hô£+ßS œ¿ayI1›Ô%Á{ed6e¦ÅÈd°™æMO–3“ÀlØ0>Î w{>#]ì%m¾jíÃ}õô¿z¿ÀUF*€M¸àµwØ•Ø8u�BÁíÌ{‡&¸Ä(róþò—¿,gΜ‘‚‚©¬¬T 'O¨ø{\\Ú¨jh>®¯ ¨õDF#ÞiW7"Ý9222º?øµ�Âü:nÜ8Ù°aƒÒb™i¸å6w*ñq³~ØnˆQý¶?«a `P:p�µº°•í6:ÇZ§°öÛóíp‰³I@㑸wGƒ ;2Î$è*�°h‹¾™²µ®þÙ]ì€eH+úõz,®ÞÄq½Ù*×З"‚i#Ìœà­7!ùH‘v!‘µÊE÷* >D,¨5@_ ¯—6Vjî�™Å¡‘èÚH¾F«‰Ø�VCæ!w§U|çùÄk>€¦5ç=_'ç ªdîôL€.·+§½Ur² ˆt—,/oªRì§�;dåüxD–3ÎÄ@þKfÅÂm"^εˆµµNJÏüARÇ.ó[õì€èÞR©¿.?Ìãtk�jÜÐôFŸ}†¸§†#­ù3 ,ÿâ29<€²QhÌgÜëèR67Ï·¶>oÖ5�¯y]îß“icPµ¶¥ö ÝmÙÏeùVL¤SwN€-£cî)o_¿Q«ˆ®w+f:!0­ýe2A»‰F¸¦ùwY¤]YCt‘Ô„áݹçÁ6^Š•ÓÅÎÛQŽá© ¶.€Q¯�ã½½ö™BÞÇQ�SÇÚå/Öœ¶ Yn|Þ&2ÐüY3~£_:L2yb1Hò6>pk&¹ì€˜·]iø´�éʇ0ËÀ6KñýJ\/=³Gs#õ.g(?s@ g3m†[æl‡[Áä ‡Ñ½nÝ“0j�fl+_ý©E�œÚw¡~åý®M¤y,�;„’‘6\'–[ËÂB†µ¥JnmEÿ{©/;¥@' 4#��ÐiåÜ$¹ga‚Lψqè±�¶ª­m;�Wu×á� ËåMXñ>~©M¶h”3…Œ`Íè¶Íüi ÊÅnt�’З©n�´ºšNˆàºãˆË5¯½€g7nC¯$�^Cz©‰ëÛÙ8–ã*òx¤iH›f!å!ñ{²šÈ|bòè¨Ø7:ê5lš=-Q¦Lˆ—ÑY.½&>ïØFHSS×°¶õ÷>öÉØÏ0*aVF´¡>µµµ)÷®ÚÚÚ�€O, Ù½2IEí¹QÖ.×JZåýÝMò•O¥| ¬O&û) ŸÞ�,çàÖàDXÚÊ­’së¢$fÍ ˆãõîÖWÍ¢î9¸ÜÕ$Ü ±kïÈwH¼HW _{»¢‹q2Þ‚n‘«®z@€Ã´¹˜ í@ñ÷@¬7À)�mS¬*ê@y¯5Ý.§�™r´ÀÿITÉÂ#î=0¤*¥ïž¹f%܃ý &Üëîd‘]xº °ƒÑ¼x BaIpniâš^§ýq·Mi½µÁ2Î+¿x�Yî…‹Û7Ñ¡Ú˶ôw/ù¹)CPØ~%ZÆA¬¼–`¡˜¨£°„Ë´`/l±yDÎûɻ᫇�ž«‚�0°¶×HÍÕ�Rzú5©½yXl–fLÜý<'nŒF¶Ì¢{Átš4 ™Nxð°ÆƒYëlcÔÏkÁÊ÷ÉË­òQ¾ÎENÅbUtƤx¹I²,™'éÉFåÞA×,²¤aõ}Ë�¹tµ 4OÀ Eæ�ué}$ºi#±Gt7&|¸M Pº°Ç�‚D�i&ÒD¤ÑHüMšøDÔ=©@w‚æÆÈ12%'QM³áF7`Ó€MI#н”m¸e—©¶€?Ájìßc°@Y²Ÿªë, Ø »† Gnnn×±Cñ†  ÙMLá6ºÜ‘uEÍ'½3!áNéÛœ¯¬¬Lž{î9yï½÷„Ì1ºòü^zé%ùÖ·¾¥„ÓSS9ÇëŸMœ8Q–-[&çÏŸ—šb|nÖ€­R-qæl”¶û¥GŠì5k€ã·Ù` ç@ܽڳVPÓuZz�E¶õÚh{è;àÄ/t­ûi;Ò$²To÷œâ�22ËPçNgk»ÝÀ9c°a!ÕïÓË„(¥Ë’ðÒõAû2òzû×@€SõÛ¿"ñ ·âا�(ö)ùg›¤°¸E¦åZ0ˆpu×\) ÈëïO—{«O@ÞÞU§ØO1aжãþ=†5KgÅ©ˆE×JÛà†Q Ý�7dÚÈíq·�þHP‰QÜè¶7l#½‘C±h@Š®sŸ…»Ïk;m@Ê×YKÖö§ ø‚I&ù3XS)€’–w__9¹¢ .l£0†$+gëQ›b1ǫ̃…¾ÔˆySÏʰcÙÈúY×»#— òØ ³©Ò!Fþ*êM³p‰1À¡·?ãïF=&óþ¶ÕÏ:»~ Œ@¸}=¼ÄwWEf]éNè‹-Ä6ñ·¢•þ×_Yíˆ"i«A�aèÀg³û¸}?Bÿö`HøDB3˜¢Ñv#ó×þÕbï{qñrzt_ÆHq}Œ\…«ÜÙ«\ª±I³nÐå£ð+&ýÅ!³†`ûì¤Hd8]D"àÄÅ‚Û©ßÆé ãµarra‡×=ø°²St"û™ÁçšïÁ=~ˆØí[‘‹>ø×¶Eø5Ò/Y”FPZ·n”¹t…u'Š¿î>ž$ùg¥¦Á*/}P/ÿüµL5hÔ�9Ü;y½ã6#ÒL²vQ¢üà“ÃÞ!•ß“ñ þBb“³="yí:à�µ[ ˜—çÅ�“²†æÃµ®ÚÏ>hÆؤ€¦W Ž­™7ðĈgóáÎEàiX5CiìÁ²"Ж="JöÀ¥�ß}aþ°#0qì' k{�A­ª»g˜dë#% í½]8>·´™ M0FqüÜ‘pk@o£«øÛÜãûz·+ÄYN�›£{ °O‡ÞTÞh#4·ºƒ°ÎA} Dó“üTÔ»@¦j°�X‡¼'¨1Èýã>jßßQô}³ ¨‹±¸n7ûá±ïGõ½G€0jqéÁÉß~lƒ;©Mé–ùÞ+xßRÿI0Ù~¹Ù}�ó †~ %eß3q´ÁCL�®†©§àýð1öf±!Z]ý�ƒRròU©¾¶ S­ØmKº-51J–½î~€N3òôL§àƒNtË ŽGA±Ei:í;Õ„çô=tâQpéš Päþeɲ|Nôì:¡»ãlÅ� t½Â*›÷7Aç€Z½U/$Î T†D·º�H瑸rKjîêaoPR‘l$.J-AZ€”‹D°‰¿pâøÍ£ãåŠrJR”Œ �ð 2cr¢LË‹—ܱ±JD>1¡“Ùà‡{j;³ÂBÝ➆ƒfgÆÊ„1ñ¸æh«p»$ë‰àLSS“M¿ÈŽþk€­몒�È”c@\‚ÅâGr¢¤°Þ!ù•V9†TÖdXánÏ�¹±�&À´éR-F`J¿‰ï BñE†F¼äàµ`¢Û]H<&ØDÌ�]Û‰>±¯cŸ±;¬"àÓиàï ÿi"껎5Ëç×§@ôÓ„½«€tãñ`j<ýPªr›kHµïdƒl?'!ô´Wtßg…Ÿî5 à¶×€Á¼Ešëù¨`³ä,úoXnÝ‚Ý-.—8¤¬QXEÑ'Â3Ç” ùŸö�ñäìqJÀaÑ“|~ÍОôçEÖ 6/1)päý|›“º?£õ{¹ß3êÛA¸ïÍÉ5�¥ãþ^{çÒ­B¤?cÿõ œs…ÏÈ:##�FVÃVLÚÇ>HÖ—çµåïȪI Gý°¾],éÒGp̇ƒPæ½ Œ�›U¡û!…àwëß_„ µ©4cýS^† S¨Œî[w4�|Þ¿?xÝ*åÐvÒê-TÇî)_Š¿ÿß/E) ·ïþÊ])ýÕtëéXþ~£hô#¸'h¯#bœ>£¿}‚ý=ÁëŸ~#ZF¡í|âîd¾ÑØ–‹ùå*A_þtRc·A¬¾ô˜N�Š‚-bi®Âw$þ¸-!> Œ¢DNM’Ù“c$ ÏÞ;„œúvGºóôõŽyt²¢½•Xð,k‘½'𥲯‚vïÖf!K4 Ã½‹U._Œ`çj"Á®Ù!òyOƒÜhƒ µ{_·iÒkH§�: ÷É jMi3MÇë"¤¥H3‘²�0åSt°‰Ì $²�+}núDMÐtÌÐ4L§Ôd³Œç`Ÿ™ÑS¯x«®9þóÚó}1‚%i`¸M@y),_×hQ Ó… ”n;·› :|ø°Ò¶ÒŸtžÌ™0°Œº?@õêÞÈÚºu«bŠ9ø€ñaüþèÑ£rõêUÉÍÍíwÁ#FÈÈ‘#•.ÙV4 À'pCÀŽðq"Þ_¡!Û1A>ªLV/Ÿ" c¦J{åuq¢/T›÷ö‘Ϫöì;˜È’LÃøo!¼fÃ}÷á Ñr‚äÊ;är­UÚ<©ÓØ£ç!q7~É…‚#Hl@]á}ĆF ðštrñ›Ì§`³4uFJìÌ[[H ö¡"ù ñˆ€OCãÁ¹H­Þþ/§ ~Õ{N¶ÉçîKR«�Zí Ïž+Ÿ¹'U^Û\­§W6×Éü)ˆDƒ)zÁVmïWúñމBsdÓ¸ÿØÚýè 3ûóbŽNÆjœïAŒw>}ý̱E•Ï;>yî­@ø”3b�”‚R7ÂsK—KÛòF!Œ.zÓ‚m'8‰ÒÀ º~ôטA¢»&ddj”|pÈ&»À„bçÞ›¤ +â™kv¿ì'j!Í…øø�ªð<ËÉZùΣ˜ð€½ó�ÿr¹�±¾.@ þÌ5#ÊÙý¬x�V4ì�Q<š`wMFDÔ¥·1²!™s­&ùò}®ûÎut]?=ðä½o(>a yQ1ìòã·ÝšL¶Á6²Ã¨9Å{‘ Á–P#Uò˜šëi%Ü_Ø –ÚÌ`O<_ž7ÝûI�à%ÙNÃÇ\ “Ú. 姤üüŸ¤òÒÒÚxbâ¨hÞ���ÈDó! M¦Óüi±’‚Eìθ…{+mëþ¿²Ÿc? /)¼i•�G›åÀ©f©èÔ$J›X °dÝ’$Y3?Ì&Ä®{šû·`è{ª U>„&Ô‰‹-&·ëŸk„w#ýiWÎÃЂq”Ð{Ä1Hw!Ý�´)‰¨‹6(çåRfF¥¥ºÜçfN"«‰ dìèhIdz%‘§ø,5±Ã…\¬¾§Tׂy͵rõ÷•“–™î€#I�àÁMŒ{út“þlìÇs;uê”?~\é2é‹”””d=zt\ãô—M¿I·÷EEE Èjl¤·’£NSEE…ЬGºþÅØé¶G-)·u «áXmpZ•,¿ÓÇnȕҩ2mÑ#ÒT|V:n]w ÞÜ…Œ¼ R x_evL CI<& šö,&\Ââòþ °û*`/<ŠØ�MB‹ô(Ò1¤÷‘>F¢ë]h&È8b}®ÞÌꆶ±sV㈀»£€ÆÇ½Ì[挣ðØõŒ 8“Ȇþ"àÓи„ì×_GúK¤Þ÷—%(¶“6pçFƒ}bmŠªp!V„oV¶ËëÛ仟ÏÐnflÕ³Q—ˆƒÿpœ4Tœ•ª+;${æçvø�Ñ…ê4,+ ”í D¤`ÌE±n‚ Ú$Õ»Ô÷yÑÊÈna¤¹`O¬ïzL> Ë�öð=눓dÒC±îLÓx¬ôP8›n‚ü½/ÆIÁx¸ÆÑÝ(ûp¡¥{ˆÐƼ ôPd¤6¿ì§ÎzcÄ7²ËBmt¤‹_ô¥èJ§1f¦U÷0¦—'—ý1æ}­Â!çmÌ— "'¾éI¬Ôdç)»rsÔ€Ãþo û02Å»/ÀÝo0�î¨O ½½²ƒ+]%¡Ûã³Ïu„�}õ©¥&ùóuf¡[ß°ã4û0Lôx<¶�Õ³� ØÐPøù&« b õ¯ZÙ†î+A'<ÐA6Už•² ¥ââûÒZC�´¢«è ˜Ô/˜ž(ëàb=o @'Lxÿq<Ì^¢ tB»*¼a•�žî:qµ<‘ÍÖÞ•÷ñ$èš~rø‰ëƒdírášE6ík�#gá>qq éS.ã€øÒ¯‘¸zÎź GC¯®&cKðºiÒ($8«‰g÷®ŠÁ›¤ÄhÉ/óg$ÉÂÙI2ì¦ìQ1Q`RÄ�[ó:h¦¸lA¾ÎZÞÁ~eù'Žƒë]vDä]ôÃââb¹xñ¢ŠÖÖ_�¢`—3ùUVVÊ�„ ‘·Ü�ø¹�Ñø52š(Ðîrƒó¿ïè PÔÿ;Ÿ ˨�\Τÿòûû…㿚Ê6ÙüæÉý›e2jõ“RúáoÄÚ\ ) =Hæ/‡È÷©­5±ë1£vþ2h{·+mÉhkVÇJ~™EŠê-fˆ”Ó½ŠiÒ*¤¿@ÚŒDëE$öñüP]5&Ò.p0Ë„<Õ\€Ï~6׉öÌ ÅƒYúH^A¬�ÀŸtAêà`•-°ãº˜NL"›n]àô6Ò&i©…þŠèÄhus½lÃÝIŠé”oTlÞƒZŸØ1{ÞŠmŸ÷\š™N;Ž4Ë~€N·¼˜NÜŽÑÌ–Ïé7\sµ‰0E§kìÐ9l–-žJ«À”ÒiB¡Ô!àô+$ê:Q�¶ó âÝð0,_Èd$NºÖ ÍFÊD¢35W~»fÊÑ â1ݬ)›f%Ëü™I*]˜Mq`xj`öéB¨XÁ¼¶Ì;\Æv@}*º î;Z«Ãêëë…®wåååÂHk·‹�={VŽ9"šÛšþ¼ÈHЉ‰ñwô¿{¿§Ë݉'„uÕ›8bþtÓˆóÌc`ù ¤,Ú¾0)í¿&Ù’ä©§þLÆGÇJéÇ¿“¶ª›Ê= h½¶iä5D5 ïŒq9²r2Ò¹)YàülmŒìuªÚ*�m¶lÏYž3�žFÚŽô6Ò$�7”ýM�#°+êä>ñ ý1¥*#í©"àSOµÞß8;|é3H1ß|kg½ŠhGÁfýê<ÅÇWÎ�—»1 ßs¢"åvyãã:™™;RÝÔ� Dã�çƒKSäðÙfLšmRwó Ò~‘ó&gÁe?}v¹I¾rtœlòê»b°xƒOìŒÌðû’j× >ÙBdo¬œmRl©L0†¢ûÇWW’úAtá"Ètþ†]‰+õ~³RJ Ô› Pk‡S .ÂPðÇŠœp³Ë„,D�ƒþ]Â2ñ°íÍxžd  Çw£î}¸ü•»\‚èRVàåä;Ì]IïcЭ‰ Ñù묷ÞËཿ¿Ï�Þm’¯=ý$»üè-7¨S†˜·‘ –ŠóòeœìðhW�Ñô.Âeìh�]V¡=xó¾ m¨pï³ ‹L[åeÚÆÓ`\}S?�ë;ÜÀS(Ë— îÆRˆãtÌ] Ý/Ü×Fž ›v¢Œ¸a%"Î3ÐÜë:�“ò oKå夥æ*4�Z=DÄ@*fjnزɲtvœŠG°›m4�ç�¾¾zzÏþ‹”y‚ô—¯[d'4�ø�F@dÙìD¹ì«©�ô»z§óÉÂ;}©MÞù¤AŽ_h‘¶¨ªuWUNB>Azi Ýaµ:αÕX¤ÕHë‘èZ7‰@Ÿb¸:.£]ÏîØ´dn 4¹àŽ8:¦3ê¬sKÖ.g矮W&Ãô/Ç5)I&™61AF‚1qíf‹rI#;ˆ ¨Û|ª­­•ýû÷ #Ðù2O±±±^àŽ¯-]ß1?ÖQk+±Øž�ÀXU[¾r#ãÉxòµUø¿cdƒܦ?�‡¹]>ÿÔØŸ-{Þ”ÚS{¤£áúÊŽ›(D…ü©þ Ga—�çDz»{Ƙd1Þ\iŒ‘ür»¬è�ò&‹ãBº“ •�ÄyÏQ¤-Hì÷¯!¹ø±�×1LÊ´k©}Æ+ó4 ]¨EW†¡8L0ŠÉ#Ä5ŸB\Á}Ìþ¶ÿ‰±\o“=Ç[äS+“¤C[®Ç÷|KÊýçÖ§ÉQèb´¶Ù% Ò©Ë©²xf,"Šp?c“ùÓ¢e:"áœ)…ðÜ%'^“ôœ{\ÝOY°Œ�'�¯t…´o ã„Çà‚—×9½1BÜl€({Áö¡85Y%nv¢E÷ÉÍŽ“˜†€"‘Ò'VT�2iŒQ¹e¾ìPl'2qþæ7ԙЗ¢ç÷œÈqÒÄ:¦> EÁ/ݤkÀ<‹ÀÌê 〉çz7´«¨S´ã¤ ì³¼¶Ó¦B,. !Ó•�Û–:•`6´–¼�:HtY™jTÛxÿÞßÏÔßzl¹YŠ+{® –�n�¹ \û2Šæ×áz¼ë�¥#:[òfä?FC MÞ(÷±¸œÆo'‹z.gޭ߇IILéÝ ·Í†s‡ÍùÐ[_ï÷tÏü›Ïºt¸þâ97³‡BíÏCl=F øß„È1H2 Ð^5 'ðDÆàS÷˜åÿ½aíŠ(Èûû_uƒ§Z¹†îk'Ó ‹�g¤âÒ»=‚NS&ÄÉú%.fÅÉH©0¡¯ èÄ#A§óWÛ•�øAŽ!ýi™OÁ] A†!´ ä½é~¤UH�p‡ªÕ~ÕiqŸí¦“dñ¼dY<;YE¤ËL'+ מ*¶d]Ñ4ðÐ}G¹¾¿þòœÈ(ž86NÆÁ��à�ÂÜWV¯^-}qES;Á?ŒnG—;MŸÉæ`,‡Î‰×—.mL�5œ˜¬ÖÞû5Ooh=zƒOh©(®û9hÙƒ½q¥öV‹lÞx^Š ëä‘'¦Ê’Oÿ“d¯¿.u§?‘š3û¥µ¬P,Mu€3P_êÞ2aÌ7Ú]ìRÝÙùéû*²¡’1vš]×é`D­oB”¼XÙUÒ!7ë;ŒXggÿÈôÒj¤2¤#HŸ Bº†Ô{CÇFP h7ƒA�”•ÿ�yƒ›¼Ì¦Â±;¬"àÓкàôÕù)®qtczkgƒ¬‚0k=HBññ9“bdÍ]I²úPtUxoo\.HÝvXý�;—¤£rÏ8[Ø¢BæV]Û) %G$mì \ý£©,ˆšLÿ¶ÑÚ¤T@ÜøK?êèúL`…úJ 'k}�«”œÜO„ëÝ}pcš 6ÉÒi&%ŠÌó Ô1ªÞ0d Jœ ¢fЧ–eVŽepʶÁYPa’MU�kA!uº¦]„{܃‹Ìâ $ÒŸÇ<l¨a´j\-ànÈzѳF4�ƒÇ¡ûÒyhegtgýÐ%0 ±ES�²ùpÿÎ� ÝðG„3ïÄ+xü§ÜáÑîôç ½'ãfr¶Áï9wÀ­ñÚ몯FAõ¿-d>=óŸŠýô•{æ‚Ö @JOW²@Y¢$†Ê¦#ã?|>ZiOýƒÈ 6ØF÷1º«Ì¥û¥¦ÃÎrÑ­’À õÀx–ñ§6�à_}Ø�7XWÇu�NŒ^×PvB⥲èci«»Ñ�é ¦ÓD8[·4Y–tÊL‡k º5h âmÀ~Š"áíŽOt"Xtôb«ÔÖtÂ3G[é�æ%�é” “ÆBÆ@ ÎKùÐÅ®®Ñ!»O6á™Õ WK; EÓ•7+Gzé¤ëHlIA<ä£ûÜT$NžÖ!MCJEâ÷ªÃæÄ=€Ó¼ɲjaš,œ“$“ÆÅIj µ¯À*AE¡Š”©ÆŸápâ�EЋ](u¬ÆgCÐúxØoN©ªª’‚‚©««�Pþƒ½sCCƒìÝ»W‰�ÓÍ�m�®†d>_/Ó c‚QžbÞ=—ºººZ¹ïiî«=m�‘‘!LŸxœîÇb‹ÕZmO%Ão¨SVO-‘¢KÕ2yúYºjœ,^úeÉ[ùe‰j+“Ö’Bi¼vNšoH[ù5ÅŠ²·ìÄÀš@” Œb�±`Ö€Ö�±¥0òÄd<£øb%÷•ÇÈ.<n"ò¶ÝéÄHR�ôdDå"} ©é Ò>¤ýHH×›¶ipø˜ÐéòD¯+��x;Úµû\:MÓ‰¢ÝŠé„(§¡�ÚÀ=wÏ Ã-*ú\mƒM1�´{�€R&˜N+:­½+A&ý.ºS Œ¡nw\#ºéñ=~©U>Ø×$§.5CèÝ¡�äJß¡½H¿è|ÅŒpX¸\Œ@9W =Œt7R6Ýê8®R�tRB”Ìœœ,k—¥ËŠ)2%/NÒ@`ä:ƒÑ‘ŽõÙ�î‡þFP##Õ áq0t£TÔ»öövõŽ‚ÚÃ|¢ÖÓ¾}û�Æ«•’%Kç¥A.Á*ÅŸh¤¼™Eê?È  „õÄÝ麘žž®.?Ùõú5¯‘ LL2µÜö�úÀ¿C¡õºJÓÔØ&'�Ü” §+åý7âeÂÄT™6k¤L�¾XÆ-Z+ãÖ9� 7‹½¾Dšo�ºzZš®^�¶Êb±¶5¨sr¹éE€(÷µø;­…ð*E£j!o4ÌV!JÞÑ[±Ê¯LÚf‹�Ï~”‰ þ¤û�èz]„té$2dù�–5ÞFl5ÀK£n".„Ê0À³OsÁwÝn¡:V$ß¡[ðiè]²ŸžCz)‘.Ko﨓ÕÐxÊH1éì `šž#Ë1ðÿø`½´Àýn˾F™7-FÚÁß)ò÷ÈóˆÓ|r:¬RYð‘Œ_pJRF/Ä@£gö' XÛe4Í^ÞnS  eû3 “Ås:Kt§ÒÝwÒ¡¨‘eq¬Ð®X #Ï•øï.Ji Ñm�M´6œÊ¯? íä˜õÉòЬ Ñ’j“lXlîQ�œçKð†QÚÊàèϾ¨Ì¡DÅOUÏ�M™Ûï™k’7 õÓÓµgçOW-½ÆÕË;l*’Ù+}1²žè*9Œ_ƱjUƒC¹Zúú]ÿ�„'W›àvI�÷Ó�.S:-Å ë-R >ß¾¾§kÁÃM‡lˆHèÚ›×õ[Ï[úìõõø=m¯é§‘éõo~×,œl§1pý|ôn³Ò“Ú„¨�SN+K8^©söïÀM `àWqŸke`T?Fæ :•�Sn]Þêt"Óé>D)%Ó)+ žÞ¼Ï{º×ûRªWÁ2�Z¡v¦°U¶cáã8\»ë›m*úœv,ºàQ{Õ¼YÐiR¶tB¡�A§v°O´Ë¶C�rèòib>]ý;d®d¿Œ´©©ç‡6d#›i Òý�i:^5–“ê)ž §• Óå^€Ns¦AÏ(= ‹)z†“ Œïª dr§ŸÙñˆÎ89'^FgÅ(ð‰`ǵk×Tš?þ°­‚Dd=?~÷©ëjϘ”ˆ¶‘"ù'ë1Ær}×à‰•AàI˯§Ê!›jÑ¢E |êi»Þ~#ðD¡t=ød2 ú){CÌ´ºlï°Hi‰EÊKåX~‰ÄÄFIJJ¬Œ• ãÆ§Hî¤ÿŸ½÷€�㺮Æï6ÔEo$À6°W±W±I¬¢d«[¶¹$r‰“8ɶó%ñßq—l+VdJT§¨JJb¯`'ÁÞ‚è½,ú.ð?ç-;¶äÞ/»;;óæÍÌ+ç�{n” ¹T.[#I!ùK¦wî Û)•`HÙkÊœçç׊rëÖÚ<ö7�è#¢/ODÆ�¡ÒÁŒ=V [AƒdV"­ˆÂ(S1¢"ðÚ>þMø)ø6øçp²£\"¼ñ[·j@ ´~¾[{¸Á�8oÔi>ƒè}�È ÎÁÿuÏkÀ>õ¼=±Æ;s0þuîüj^­lØQ!ÏÜuÝr0A‡{„Cª¡9x¶RN_Ž@zí.d¾C/À±ÃüI!òÑ® ÉÌ©•ºªB°Ÿ^ø4…‡îІèøÇ-’‡P±Ÿ¯sµùLe~¨Ã_9¿`ÃFFËAh/µŸnðÓ–¯)`MFÌ&ˆ§]qH Þk‹rP1O‡/º@Œ–{øžÃäȶ¢˜øƒ`‰´Õ·Ò�`Çäa&Ùy‚¢çZ׬ßÂù7³¦žuÈÄ!`ß@ó«­QGjBïŽ\2"ä°ýóæuû€sdiýŸ×\×�¬ª´+m÷Øù{v" ‹[2©c–�ƳÐÄ¢6Ö�lÆ(0¯&›¥Á'b°NÓ®§öÞӯϮ±€a†U]œßÛ\€eweî.ëvˆ¿¯œa–óZ½e*õ™ Ïd6¡^d?ÄÄ5ÐÇ[eÑŽCöd5AØ#dRߪï@'P"›°²Pž›†ðº7%ÿ\ûL'%$ŽI9A§éc‚$ÁL'ÞçlMŒ�lhÒ.T˯ãk¹ àbƒS—†õK`j@B�,˜‚ 4€§ÁýÍ„el'Ó ×;RYðдœ¸T+Ÿ§VÊaˆ‰ƒ1¥Û/V>ü]øð³p²Ÿ¼wSã`7a¬žh8§»àÓá‰p<.–SLT�Ìœ)KçFã5B%ªÌ~¬Wî€Æ¾Áw*à 5pÂÇsž]÷ÿçdd(˜OÉIÁræè­°«W¯JZZš,Z´H"#‰ïõ=cù·oß.§YÁ„›59R&޲Ê~€OšñZi×Kû¬³WêCi KgÛ%''ËìÙ³ºpÞÞ}«««“ÊÊJÅ~Òöb2bàbè½Sí©kB³R¦e=:+XQY×ÊåäÑ„!"snh€ÄÄ…È äH?9A&O}D†ÎzXšòÏJ~êg¢¶ImI6Ú7<Á�ÑØµJñ¿v¹´v‰ÈÛ«XÀúш˛€ìÍk’-rÕ†ÅÖ‡œ(n�Ëó¶Õ6ð”€ÿ®2„²’yð©ð§áœ3}ßç"FoíKP´^kì¦TWÅkþÊÆ ¹×L]~í�ÿõö©�ÞÛsÜ>× ½3%*ð{ø*xA•�v”)-�¡Xa¶CcH3†×�†Aï„PÙqÈ™ùî“=2~xl—ØOÜ7'4Ë¡ò—°úAƼsŸHÒ„'%2qF‡ì'‚ ñÈîæ Er2‹´2uå•adªfŽnº©4ì"(`¼é°]ö!Tm²Í ëï£ÖŽûâÆFi¬íso¾²áNÀx�e´;ìòø"³X¡ÛÕžYÌé�©ÍðDÀ2×µm»-6f|;uµ Ùõ®ß'‘ [\ öE©uÕÖ ãQ¬d­aß]#ck1DáS ÏÕ‘aA�QõÛ‘½BA³�‡*càG©Þe®°Þôíú=v%pÏÌz¾´…Œ²lªYþïëH?ß|-vH¦�¾¼ž,ãWç›ä« Ìò‹wÔóªë­Þ«^Ÿã�*¼ŽÂûšýÇÛõêþiïÞÒ¶é]¯˜aÔEJ{UÉE€NïHΩ¤ª,áu5¸¦®:uf¯ ��¸3¼..’Ù1›Á WôèôX¯ø§ÊÄŒ©GÎÖÉVô!d<ñ}JÚ¡¨O3¨�Ü95 bâ!20ZE�Ø’¨­°#l¢Šç®6È*eÏ1ÄÄ¡!§¯p¸ øføËð}p¶.„oz‘Q{dœ:Nsácáœôp%^5zd9 ªÂê–ÎŽ‘q)!aQ ë—ÆgU«Gç'žùŸõÿ˜H£ªÖ¡V—ƒq�jà–ëÕÖﯱ#ÂdסÈ@l¬¡ýû÷Ë™3g€Ò«O �ÂQ¯jÛ¶m×±žΈB˜aXÚ®»âf€'ª_¿~Bì³Å¸³æ;®å3Y¹r¥Œ9R˜ñ®'Æs¡ÎPš™LAxÐ(õzC»««f¿kÄ3Rgo”:Äë—•ÔHúùÙ·#C¢cCdÔ˜8™³$Y¦-ÿgI\ø¨äïA–ÑýŸJ}Y¾j+Û©æ^_½¹€®§ÀÙ¨"j[€kÆ•HùêÁÉ©n”ó»žu®Ô.ÅÕ |~xSÓ‘’F1¢–à5¾ Î>æ0¼®?Þú­“Ð=)�lÕït„IOõ¥=Ü¥ÿç}¬üàSï½`§Q4ÐÌ"–T4È;›+ä_ž¼T¢æÇ} "%5­ "°9p¢‰Â• yW´Ÿ8i¸™‰6íû ,«ÚÊ|¹zè�~ÆÝlÚiºÉ„øçWêår.¶ÝÙò7Ô¬af»Ç��J?8àù¶5ŽÓŠ+�Û3¬†즥åß PšIßE:wͨõäk{r±YMÚ_ßÚ ÛÓep<…È;¨‘]2jà�™ZdTí8a—1ƒ!èË5 6Æ0ÈIÐÒºc8ôŸŽHñwÖ±Æ\¡@÷?"üfÆ›=tím€Ç{f"dós‡ ‚ U;•ш{¤õ ÂU�ûjÚ£<ýû:¥ãÄ£`ñ¦H4ëêkK 5ðòGÿëºÎC¨þ§o4£=]«�lµ!›£e ¾Ïº€ ÝœÅ#ÇÕï”ׄ3ïM‚ž°5¸Ïþf¹EŽ_v´bë1Ä®¯˜³m2JmE6XNHö©w¤2ÿ4„Ä:q&Ôl�RÀtZ ÐiæX†×yt*© V`­l=È>£F…nëÂâÚg�d„C0sÝ‚Nqf•�ÌÙ%à<Ël՚Ѐg"TbË2áUJna½ÔÖ»SØ„Ô�íð·à{›ß»:|ÐK ­‚ çDf|<œ´~ΉŽ2f«›>!Rîž#³ å”œ=8WXëÇÓÏ)ûL2ÈFs@´:¡ÞÇÏTÊ΃%rê¢ õäÁåýdÑŒH BF9ß<½Ívƒ_"Â"6!\6ï ÁyT(ÐìèÑ£Š94nÜ8•±í»éU_:tH¾üòK)+s2œ"ÂdÁôh™<:L�»=)ì˜1cdÊ”)råʱÙÔ Gj­Œáv<ð€ªZ}Ñ�7ùùùê<Ô�€™Œ#5à±èÅ̧ŽOÓYU|~œFøœ@”Cr³Ë%?Û&‡R¯Éб²håpY¸ø‡2râ"¹öÉ¥üxý¬×�µ�ø_ÝPl75#"ì¼…5&ªIî$¹¢Îˆ:RPf”‰fÀˆRí3Ûh¶Õ£á�ïÀ�ÁŒq ž 'åBPñÆo­j@ Z}áÎ7-�ž³Oíxbä΃ú÷Õ«jÀ>õªËѪ0ìå_€?Ê�ìÖNö'%õ:ö3ßMN ’)ЖHðT†P‰�vUÈØ¡q]c?aß0©X=?Bþô.XÐ~Ê;¿Iú]ú\ú¥Ü‹¾¶}zŒž…Ъä]|CÝNh§§4*±ë¶?#@U�Ž&ÓŠLï=anèqe—õAF ßï=ãP¬½¨yÛ}yû=ÅÏWÏ„H'ÊJÐìÀy2Û�Šž]êõFíš!ÈþA1q†ªud 7$8rÀÒܱí·Ù CZ kñ$£Ê¦ †’^ ú*ij»kÔ™!Ó‰¡„“r‘�Ñžñúä•6xƒ¢MWOЋ 6¾r_ûÏùfZD`eDÚ£Áe ëì20úÊX�òÖ2²¯nn@H™Q¶!ÔÎÆã�lTl=íxd£1$3‚ñ¾²Í›©e¶a©}ÍT¾7h†4TIá¥M’uâu)Ë>*özÚY׃¡„Ľ:—; ÁT­À¢sÕaD»ªëS,+† ‘ES­2{|ˆ$Æ1´–¡\ενÔäa%zçaèC*‡€r��t ¥¸f_À߀sÀ¥�Þ¦ëÄqÐ@øBøÝð)ð88Ößà¤N5$Ø,£†ZeÁŒY8=,�P‰ˉ¬0m.ªÕ~ç1S '´µõMj±è�P?èÈérdO«‘ ›“mFPª¬¼ç&™= $®^þø°gœ<Ú*3&DɹËUJF€áj_|ñ…̘1C–,Yâ±:u÷Ž333åã�?nÉpǧeʘ0¹ !™Ñè/‡†ZO,<<\¾ó�ïÙ)fΰ8½�1B~ô£ɤI“z”åNÛ'õ·šA.õ‘É 6U$N‹ßõ Zùzþª{†!naÃúä±l¹t¶Hönë'�>=AF?ñŸ’³á7Rr|‹45` ¦=ô=?¸íÔ€þ®bÛ@ ¹$,Â(ÃÛd1Bt3*B!»u>ÂËëч5²-§c4£B¥'àõ«pª¿À³à¡.7¿áU ùF#)ì¯ÎÂ}¿úˆBxÙØC¨Á¦ž•éö2pì€kÙüø°oí`áö#ûwØ‹j€©ßzo \CÑžƒÿžE¬ÂáÍÏKeÒˆ 5éט+l1Ȫ¾g~¸=çd?¥¦U@è5L¦Ž jTq?íi�K¦#tïpVÀ‘þ·‰ÏKÌàùb²X1épÿÈ•õ\hFQÇf(Ø'm� žß•<‘?ÚvŠAžYn–ÿ~¯bÞÎn‰Æ÷ÿÇ÷‹çaf�6¢œ®åI0~žüu�:g}3Üír® \®½ÚGo‰æ7k6ŽÈ&ëÌÈ~¢(÷„!F‡«yQ«Í¹¯I%Ú}1Ç¡´±ZmÐÍ7d Í‚.Óƒó-t†xt´«rhÇì�(öE€ƒcƒâ89ÍþúyƒüÏg˜‰rHà%K‚P6'lÅNI þ~Cƒ¡>¯�…ç+ãµú |œ'›P3†WžºêàÉŠiöK?T÷!Ùh«ˆšNÞž^G1󟬭o%öÞžsíºtåU�ìu¥Rœ¾E²ÓÞ�âÌýb¯«Dȇë“Y4âÔËf†)�'!ƳL'‚N©'«”�ø¹ôjLð[ƒNój˜N3Ç…@([:5?"4Ø(¯tÈž5òÙžr¹tµVªÁt"§Ùø”퀿 ß 'èä:q¼é†W¦ÁWÁçÁ‡ÀË„ÞÔ @`©|ˆÌ€NÏš…±J«§_l€Bzcl}yÆìËäèàÉpâs¾lªIÞÛÍqPß2'èdG}¥”\Ý)YÇ×tÚ­2'9® KöJ„»^·ÙâÊÚÝ@IDATÁNŠ,'Õ˜Q_ «›:.BÏŒð.CKX„Õ›¥u…Sn9küØF��:NìëO]¨’/ö”ÈÖ½ÅráªÍÉp˜NÀ©#‹Ž´àZ(P¹9bª£M{Åç¼Ó' ÞgÇ*ଯà|úé§2|øpùæ7¿ÙcñlOŸè� D¶�º` ¦Ç¨Í�“šÙ™^ˆ0MD¬í˜åÕÖÖªlr7S6ê8�;V~üã«z¡F?‹��Uí¢ÜaŠÁEÁqÍ‚ú‹Å¢W-5´SûòzU0¯«é¥òÊó‡$êg dÀŒ{¥:÷²Ô—`eTko©sÆÉ´ß571·4Þ«}Xý€F”Aâ1~ž�>µ ªQ.`A‘!yÐïåQ?ýÐÙ¼¨6¾“ÒÆã»%ðMðÛ |bÕªA ÇJ‡Ž¬¯plà7 ¸£8ó[ï®Þ nâjæÚ�%Èf„P9‹ô³Ÿà:,ÐPý•Å‘Mi«C+«ìr™ïv Ūºµkì'ìcÖø ™êû^„ï9lríÈK’0b¥XBbZi“`S·ÅË÷!‹ÛX„üpÒ[t˜A¦�4Ê�f:ù/Žø~B €![4ÄFàà\'È8aËÈcV>s»ZMÜW0ÆŠI±¼š7¶’fý+²ŸÈBjϘ‰n9«3òí×é.µ·}{Ÿ±ï!ë�¹fY`€ IgÆ0C‚lïí¶«Ì}Ç.5©Ì{!Þ�¬Ï¢‹4êl7nÿ. ¯•vÝÜ~€.î�൲˜¥Qc}¤üá_�º™Ñ×Å]u{3 ½ß�ëy×i'tšýf=W µwžå½�…y�eÅ#®Ýb—=§eÂ5û–1ƒ� mf�”f¦JöñµR˜¾áv%Ðura/â,œfE « K²H Î榺g½tâÄ(‚ß©i5²í�M.\«‘ Âu@Ú“bcÜÖëDô)1­™W-û c«i”³Wj¡éT%‡NÛÀdxWK¡IñØ_ ß §¶Fo¼S!o4ü~øJø8C3Ø¢ñ²H¸5P&A�çÎÑ2{r„ŒH–Èp3@8B›g·œ5~ì)#†09t¢RÞÛT(;I64«‘Õ– 3­,í?8È$c†…Ë“÷%Êãº¥ËØÞ~=ý1ÌŸ«ÅÉé 6ù|wÊÞ$999²víZéß¿¿ÜÿýŠáãé²tgÿ.\�×_]öíÛ×Âdš8:\î¿;^†&ªsá³I}0 Ó€²¼%«ˆ A¨  &ºh&tªÌdÇ0<²Ä˜ESÝÌ]ü}W6;räˆ\¾ °¥ÞI\4›$Ô’Œc±œÞxºRJnƒ¶�,µŒ+ŲgG¦xž›Á.¢®;/~ø¢sÐÚv{O½9 ˜NÏdoD1Tó‰_Õù„U¤?Ï¿]m‘;' Ås€A^Ùìb`y xbYÈ0dh[N1Á'×µñæà1!�?}Ì¢Ágÿì*æ+iûŽt2"”§9G•¦Sþ…MRgËÅñ«sxÌ'>2<@fO´ÊÝX …„!H+ÍÕEw òÔ$b0X.ħ÷èt¸B®d1ü· èpbrJ¨,™e•;R²„‚…�Ñ€zfQdî‹$ŸFì++ÈN×ÈÞã°2kÁ¸qÄmçÅ£˜ë_á\-΃»No|l¤0Ôâ!8A§Ap†apþ0Ý(Ã}63 ld«Álu`¡ás5ÑÂ6¼‚îºFû‰q�f‘*03(J~ñâE)..–¤¤¤›.§bÈy >8mݺUxnšôCÿÕmíߎڦ·Ô+£ì.ž.�ê{¦H`L¢Í�Ò¤غ÷-c‰Ù¾ñ¾Á:µd£M?_†¾·Ü.EX ¨ÅgXçVýÏÌ‚í8Âk ú‰ ŽU±p‘F|’Õ$ñŸ‡àvÀ:Šú�B0Ôï½s‹èoC‚»DƒÑ<C–">> }ÄñÓŠ *_Y§n¦³Óøû=x*1•½jáÅñбÕàË [�¼rXÿAnÇðƒO}ãªsù§p†ÞõçøsRbÏ�Òx×Lku�}ƒÁˆu“ ¢°†¯Ü&b‘]X'—®�²¾§RžZ©ƒŽØÆ`d@º_5Øc°»`8VÂGÙeΤڦ-û‹ \ÉÏ:öª$Œ¼W­ a?±‘#ûé ÄLJ'råEÑYl¸A¦Ž0*Ñq_¢™½mp<ô‹0Ð'°ƒö¹ËÆr3Ä� CGà$NƒLØ ÆÞžÍk”Üghà K=c—ç:'›ŠšTóÇ›ºÌcý“q¶YÖÖƒú'ØÕ™QT¼ :OÌ‚76ÙæJg[{ö»ïßkÁu2Êh&1ÌN3_„³±.õ÷ì†}v‰ß‚ôÞ2ÞúPê…�h—Ï»šzªŒè2— º9\õì'OÓ½ûE[ÉÑ{ï%—$çÔ[’sz½T—e(ö“þ¢‡[-2cœUîBˆÝ¸a` 0l…¹Ùôꕟ÷‹Âö[�¶.‡ÖO=ÀÖV:L˜ôšdÒH€NИºL'=èĉ$÷ÅU~2š.çÀ:Q-ûÀ¼ÉÌqf¯Ó‰’³�ʆ¿_ ¿g?Õ~Ã…/¼l¤e0¤îø28gôÁp8(³§DÉò±2sb¸ Lã„:Nª7T'¡nñ;¯AŠâ’zyy}®üõýld¬iwሺSɉ¡rÇøp™�sŸbØA@Ã,�èC8±lÛþxí$zp Þ@¼_ í§,h¸”‚a—Ên·ËÁƒå·¿ý­ /£9�ßÞ` y{÷ÝweݺuRTT¤Šd µÈŠ;ãä°¸¬!f<ñ ž_Òx%#”³| dçSæ AÈšböºî€Oê€øïäÉ“’ššÚ¢÷Ä–+,pÆ@ÑêþÒ·s8|¯Ú%Ûû’¢*hÛ�½†d>5‘¯ÚÞ^UÔ £Úwüò¤dB¬ûXaQev±a‡5µ`ç„HÙG9wÅßñÚ;ûg?üI� C/��ä!`‰FÛÓã›x ?ÀÂ% Ï1Sj!;Ó°sî·y×–µ»_è÷ËKƒfRÊê òåµùÌÝ[½~q—aâŒ*ù œ}¼Íq øËoþð×€GjÀ>y¤Z=²S®.ÿ'üy¸�+ϯo*kš6&$ <Ô`«É : ´¼ƒûÈ=wFÈ ïJ4!>Ù].ó&…€öm3-±!H5ü�ô‚å ÕÀÂÊZk †í«ï$OU¨Us’{úm:óÜÊ~¢ÆÉ2€g®FÆE‹'5©0/¬Å¨14 l�]'‘λPßµ´lâö?8¦%гûV››ÉcÿdmƒPLüf€'­pµèÒòJˆXµ?`fÇh�þO'Oå%ˆ‘CBBéCñzç#‹3ad8 è d/€ÐšYfZ¢ÂÕ}¢ªÍ+³íMO1Ê]¸.£:ÙNxtfÕ˜‰pëq;„á�² Ò¼iA¸…©3¥Ùë[í ÄLE(§¯Œ«„O,6+æØR§3êýÛkÞÛ<‰2¬™e’¿ûLËrÈûù…Ï€zÉxÿPHü Ø��hdöýë«5„wž%/½ÝÃØ84¥®"YA?”œ“oKEþi€NÕ¬»î¹PdG›:aϳÃdÂÐ „uqøî¾A7ëU˜ tª�ôk`øµÿàe‚& U–"Ô�áu̺I¢„Ö°í¡ž‘ á gÓkdû›=_-E`PÕˆÒ±fy‚9ð�p®�S ÆuâxãCÃú»Œ�?_'èL«à±�²zB÷-�—Éc­…É’©MX]ss�ŸøÈp-N^BöÀ}Å’1q=Û)3¹A‰!2kr”Ì›!“F…�ÝädÑQGŒ] þWÆk«]_�I·Ë6!ŒŠ–Å㬗W?Ȭ^…~íÝ»W~ýë_+àiáÂ…>g@Q“jÆ òâ‹/JFFê¼ ¡šFY„¬ˆOÜÛOTÙ£t7sÃSGlØ �faõ&9þ¼œ8qB¦OŸÞ+ )4N­­ôôt܃Ε¶À€€O#P÷|¤t'Ôí+݇~ˆ«ƒ8²»C!gä@�u =q½û\Õa€´Ø!Û³ Ì `·Æ!µ?#èÔ©©KÝþõ®€–A! ›sÅõÂ()°¤°’1¦,¦ð:‘C  Æ_>ί€+–‰Ï ϶JkwZ–|©®þcYjì8ß|‡l¸R'' ê¤ý¢î,ÎcW¿… /€ß¨°É-oªç㮫'÷ž´ÇvìÞbú÷æÙèdšëÙû÷~Ó5ÀÙâZ8Cïîâ¯‘ÉÆ´i¯Íôè²pýä@MHîšaEúë*9“^%èÞÝ\.ÿôD˜NhT@’ÂÿM˜´¸§Í£aàêï¨aa†¹“bdãžñÞµÑ×ýSKÌòÀ<3î»<‡PHͲ‘ݯ/Ø¥ªql¨.’‚‹ŸJöÉuR–}\ìÐÆkBØ�fAÐq™8š³–¬°“Òªe;Âë2Ètj:‘u…$² Ó„á�J4› K­ÝWŒF쇂ä‡ÎÕÈ€NgÓZgûɼãpކ&l€o†sàÎUb²Š7>4vƒà�‚…³£9Æ ‰ñÁ²ra¼¬Y+FYÅ q�Íé®ë‚c¹Åpy�ÓYLžx 8­^/ÓÆ‡)†S(Bä r{ÍzÛ¹håêÎ+ÉØý¡kù�ûÁÜtÈ›ç Ãbƒ0›Ü®]»0æq(ÆÐÒ¥Kö´ß÷uç¸7ój41Ìîù矗³gÏ*�†‹x3&FÉÓ%!|Њíõ>¯kb|€L@ö»m©R š¼¼<¥µhÑ"=zôÍÃ#Û2ÌqË–-*P;@X`Š[rƨUw4fÚŽûÀ+Ÿ³Fˆ"9³6b±¶ ¤^p^ì/ØJ\Óé“ô:ÙŸS+%ÌŽ‰á@;—�í9æ9Xà)³]Õ?\ü ?çgúÕ> M'™+F?)ã¶½Cz™AëD?$21‰ÀS4õÎBÅÀL‘)•„ö8‹Þ¡Xàâ*;(Q<Û´v�¥€5cîÎÅslËó*C4ÈùÒFÙ�W/G!SRŠóÕlRÊäWprô™áÎoNð�ךOÍ@`Guï¾Új¾ŠîÛ¡O}£ô�Jß(ñí]J®0ÿðyð`êå½·µDæNngõpЦe®û3סg؉ÔÌ §†É´ ¬ttþ¼³±·`ånå�1²7­¾:©,¹"Yi¯HÊüG‡àšhñx]5v‚úŽ„Œ�ICM²±™)Sް­#—2UF5ý~÷=m„Aœ3‚%žó¶ãD#Äw -éÞÝq4v¦Í ˆíîŽuC×VþÏÃÅà!ऑҀ'm'`+°Þf�iRa�ÚçúWÖ=P_�oVS&þ5fðó¬H‘5EŠSmR¦ÿ}{øúx¿C>Lu�címç©ÏxÞÉ Å” ÅÀ…a‘¾2о3$I»6|6Ÿû¨AJÎiŒ#O—�Bâ㌊A¨ëÝ]v¥Á•ž�ËGF]²™£�&=ÿÜzâµ vöº2)Jß"ÙÇ^G&Ðýb¯·a2âÂ^,8“aÅœp™3>Xb!Þ�ñ¶z¦õí^wËèœDð™Ó©¸Av­†�x…\EH\Íu S€LŠlzV;$@Âu�ohÁ CÂ.öŸètØ&!H^‡ý4€é¤»[Øç€¯‡ï€gà ¡w¯À=`Pô�ûàOÁ'Àñ$ ì¤\°¬^¦SœL@XZ0²�qµ�æŽkâÜ“{ÿg¹ÆA�ëÞ¥ý¤ º� -û «ÉÖ–ï©æSè|ræÞby}o¼ ¸GC¨ûÛPá@ï|ê öìÙ£˜P£–/_îu¶PUU•|øá‡ò»ßýNÒÒÒÆJš0*\¾…òΛÑŠ]¨¯@¶„!`#N!£ ÓEð‰a…û÷ïž×°aÚ‡•�=‚j äß´K˜D�Á�o@]#¡6¸þÃy³uD>Ó>QlëêÁvÚ“k—õ—kåJ)ú ŒSÚ\ºRœÌ øžæW¶ñØVˆ,eµ’�¶Nú�¹_ÂbÇDq1Mô¿íèä®)&yötÍ A%¦0ÿüŠkòF¶H€%²‹æ�Ã[gœx%Æ!ÖŒ¬qÝ {Óí®åO²B(NÍÌpzqfÛÚ wgÌ}‘²Ý™±Ñ×*3F™Z� íý–ûÍBHà–cùX&�Ú3Ö!³­14nH?WçÂA¿£wÅœl«F•™ìø wåW=Û†e›;Æ(‡²iúEÌ÷30æ˜]Ï—Yì¨�õì³lOk”ßmp=dñyË~ýñoTøá×[×Rd¸Q‹ËÆkÄðº%“LŠÉHŽFðô[Ϲžsç§½ÿ trd*ÉÜ)YÇ×IñÕ]ÒPSÚ t¢FÒ€ø =a²ðŽP,0”Ëù|¹£ýPÏ&ª‹š#E`(íN«’/÷UÈe ‰·:‘ét×ÌP7L'„×ñùÖŒ™ÛjÀPL»Z‹,xÈZw®Zr «ÓF�œW.þ9üC8Cë8AaËí½›»�q4þ7ðÅðp8ZtdL‹ Tz;�®ê§2Ø…@“D«Gw\ÃSÆ­(è§<Ž�­»ç9µuâcÌ ¬à¥äÓÜÛÏÁ]uÃsU!jƒäÙÇB?Æ o€ÒBð¨õ_ÿõ_Jà{Íš5 …¬¤¤Di<ýùÏVŒ'G40Æðt÷Üh±@w«³–· ƒ°ÑÃBeæ¤(I;W ¶aƒ\½zU…ºMš4I¦M›æ…3iÿÇŽ“�7¶b=E¥ˆ5`0P6níÿîVþT�2nH#ç轸ØÖ¡ÅÙ�Œ:Ù‘YƒŒoý¸Ÿ£¶³ðÏà›áàåpvÔÚ Fë9´W|Õb¤}qþHpŠí0' IðAðdøøPø@x\�JYeãê¸ñ "0€#SêB)î.c-Ü(VÄÍE�…,Þ`N�»…R° tî£ ‹$•`XUb¥F…†cá„ûFÕ€g‹ÇÒû®�ðà‡á<×6›à¿©�û¶O3îÚceöïØ­5àŸÜZ�^Ù‡_ÃWÀØH|‘Z!«â14)@ç ã Û>´$BN s]RZœ¼X…î’¦U "šj°Q'Æý±Ü°j~„ì9Ž4ÀÐ]¨.Ë–Œ–q+ÿèìn¢7Û(£Ìcj%ݶß‹Tëɦ֓ެÐ#š‚P¸çåôU÷Ì�¬XYaXWVÈâáD™æ‰v—Tû:² pv¤m�ŸÕ£Û×Àê(Ñ»b y;pÎ�l�†ë€»¶¿çq¸"Ö#Èsì²CÞÞé�+¹3îZñºs¨V¿ùþ½f ›åµ-ȵ˅vQË×F­2 ®óÚúʘÍï2ô¤4`ôÇûúA„×QìÎ o�ûþÚtçz¨@&èy8NWš±GrÒޔŒÒP]‚dŽa�¦˜51�²`ªUO •!‰°œáˬ wŸU§ÙˆROÖ ­¯”3Wª[ ‰s›«“é´dºUÆ�éÔt"@Æ,uÇÎ×!žMN@S¨¼’¡u#q5v|°®Á?‚§Î C8qÓaO=7Üá2þ5ø*x?¸Zq§°óüé1òä½ý!(!ÐtbýÀà5éM'�2·o,$ÊÌ̳a Ïˆ÷Œðé3åoÿ¬ºý©ªü—< Pþö‰� Á˜µfK~Q­b>?~\P„y䉉i½×íwðCŠ‚¿üòËJ\üÚµk-Ì ”!VùÎ#eÍ’8ªé/ ß�ñ±‹;rÑì(Ù¼TvFû–™Oü± 2Dbcc;øµç>¶ÙlòÚk¯)P­…õ@ÖÓx0¹@IÁ½Ù7$÷×Q"ÔÂB=VN•¾+£w`;¥"ÌþlŸÃuèGº[ñJ¼Î……L8N¦[áÓ ÅÆò–Z˜ÈÃë98A&�-EP*ž  Oiþ› YR\, x˜*›JQ g@Ê!yØ»sñÄYÏZmó\ø|ñru_üÝuÆEmÁ~þ.‚³?ó[û5ÀÚW¹P®ƒïÚß¾[ŸêF†¼¤šënÑníÖÿ£>T �îCåõÕY%x‰‚ÏãÛ: ÿ‘΂&;ºNøÊˆöñw1‘RTî�séõè�LR\joâ <( �ãñ�¡€°$*´+圴`Y�mmE–DôŸ(Ö¨Ñh¡œ«}mwÂl^ý¢0ab·ÔlûÙy¨sºfGûR÷J0£»�A¶µ¡ý0âÖ'Ì�…EÅÒ@Ý&7ü“sîGMzFÿä€ šÎj䆻¾áøMŒ6Êô‘Çi}jê·,WÉ©ßÔ�sc6·B¬çP ‰YçÜm ‹døß›ÛB½�¡åîã´·?žÛ¸dƒìç­0¶öÊApïkK SvÑ¥‡C&ß§¸öyIg*Ï×ã'pP€ë­Ùv<_;‘ÉN/¾®}ç‰WÞ¯a:’±¨™Òmn;ÂVÝÀhûöü+ÚÌ,JWvmŸ\ÞóKIßÿœ”åÛ© Í©óD•p5@§s#ä©{¢dØNýÀL!Hä.cÝšÕ@»b߉yùãRùdW©dB¿‚,%­n#¢°pj¸|}u´¬žoUI%‚±R¬J‚ÿ:U!s&�«W>-•·—Ê…Lh:a1‚a¢Íûá`ü"üøÁ߇_�³WS¼öã¤f,üYø¿Àï„svn À*ùÄÑò�ß"Ï>1@&ŒSéìÝwEpo ¯¹g»&oŸY·ŽÇª3ÉH„©™Ñ™BóR*qS »´´T˜™�Trr²G(ê;mß¾]~ñ‹_(ÖSAA�:6Ofôð0ùÞÉrÿ²8„¸šÕÄXͨop¦<'ŽÑª±xtæ²M��SYY)ƒ RÚO‹yÓÞyç®åææ¶6&tŠD‡LÃ"ñ„ÛÓ‹”4íý¢$iLß&Õ×N;µþ¼|}:«}[¥¬Þ�ízy cöKX4®%ªã4.\ÿ¿pOYp®¦¸£�çA¸v’¥hQ™´~ ~¾ Îã²YgYvÂÏÃ9§¡Œ"{UÝôÜ©0ñUTxÕ>ã÷:c?VgßÅý®…ÿþ üœß5ÂýÖq ¬ÄW“°ˆc™>6X-€t¼éÍÃG…cŽ£j% (®#ï¿·à¼Û\Λ߿ÿ}§ü̧¾s­ô%e#ÿükðD>±[Tȃ`9ÅÅÆã æ=@šÌAâ4Èê…f¤Ì®j*,j0\ή5î:\,÷- Ã$õúg]µøhŸ�– �6 ò²bv¸ì:^%—@Ý­¯*–ôÔ?HdÒL1YBÑ�´nËÇ6È¿? צÏòÅlv]µb°ŸÀ�ý JoL?>Ù¨PûÎÜ\Ÿ¹áQÏ,7Ë›;ìòá>×o)˜í #XÉ:;ÎöŒ¬'šb ko›Î>ãï.å4Êk›äI$cÁ6s‡±Ì²3ìðEUâ½6ùuÇþõû`È Ã3)~þËw9–pÙEó{ÕYiùäõÙ{,*lñ<êCÓ*cAŽy˘‰ð¾Ùf”à ÿòŠ«ŽºXv·Ì<ö?=h‘¬¢&ùoºÊ@í±¾g��6X )ûäëRp~£ÔTæ€ýı‘ó�åÀ)Å9ÃTXÛðÈ2ñT®ºëyà1ÈJ$Ÿv©F>ÛU)Î`R ÖR=À"͘I�šNËÐ6�F!qgX‚Vfp«„Æ1ˆˆ¶Ô °^+vAÀRg•øûücøNøU8'½W;´‘ð‡á«áCàœ¤˜81OLBV´þòØêž¬ô¬ð�Û® ÷åku©|R‚^uPV5 úA„üéú�e”ÿ}'SÒ³ª•^RVV–Ê8Gý¥Ç\é@ÅÇ“xÑ3#¸E¶ÓºuëèÄ¿ ÑxÿM!ßr�,[#¡`e)Æ@¯Ça[^>/FNž·É»s”Fç©S§ä½÷Þ“¹sçJBBBÏNà&~Íp;²º´¬}üih`,BÞqÛ³žØ¶%!–©(Ë“&Ò�{‰±ßà’ùòFyÿR�Ê«•2,ënÃK(êKp?×ࢼa\Óõ#¤B¼çà”ä:ÛwN\P O†§À‡ÁÁ#àüžÆSâ ƒ +"¤™Íž�WžÙMìÛ¸ ½÷\(ÆoÚˆJÕî\u/ø«å6«?øÔw/xŠþü‡<…âòùò@�<±ÆÁX~‚gº‰«ñìŒÁd©JÖ}ššº]6í)�;§%HhH0€�&n©6Gòp18eAà ý�ƒ£~1&ypQ”üêõZ0rRt5UrN¿-ƒ'+ÎAwA#{ˆñb-3ÝñX¬;fV{q“ââ&™ ͨöXVmËÕÞ{î+ij·AˈŒ#Ö5?ó¤1üññEf%‚þÙ»œºêº¾�vž,³Åé™Dol³#{�QöœöpEèNÊ‚ûE?Îýá¡ÿ`�ïÆT…åMJ ž×«»Ï¹î}ô§tjÄg+8+9gÞ•Ü3"¼8 n›�uì£#:M@x¼G PßfØÉ-eç1Hœâ=~1«A>ß_)»�y®° Ù½ ë¤Yp I&Ž •³Âdò¨ „ÛAÓ _jO ¢B àêtµ|²·RÒÎ_:qSο„¿? gh'Þ»©q°.[JNB…t W ^Zh‘»æÆÉ“÷%"2ØA –¦pê�ÿ¿[ªxó€Š�²È×îKPa•z#SÎ\ªP,$2†˜ �,¨7ß|Sî¾ûn0UIJJŠ„„Ük‡!gééé*îƒ>Pû¤ÈxK(ÒrÍ�-ß{| Ì½#R›�è–‡±‹5Ï jC iu/DñÏ]©”#§ÊU?fšÛ±c‡¬^½ú¦ËÞÅC·Ú¬°°P¨aEªÁ9ˆÄâc�ÄZgp„v�‹Öдúåmðçm»rÈÈX1WåI}I.Ú4—l¸}lªÈ\½;Ï!ï^¬‘‹×³�6¡ˆÏÃÙÖ”qu(xãã]ľFëoÐÙ*+Æÿð½pŒ¼”¦éµ6_«l–Ÿ3 þŽƒ :g=ÜÿÖö‹?ýÖk@×Gsø¢]×ÞXT™ ÞmBLñm˜N5ÔUâÚn½T&õ&úÇš!pk—kùu˜“aBT‘)±#–I@P$:a×ÑÈîùò¨â×=¢®EWBàjÔƒ"\gƒ¥”‡ásÜæ(í3 º¨ ¥£.u‘>E–=_A„ÁñÆIÔéayÒÕãå PDŠ Š$d² èzû®À¿üFÙvØ;Ðv¢¨8CËxmÝmw‚°¦E6�ÀËβ#—\÷•ó[ïýŸc�ÿûX€Ìif>ÔŒá†i¨oi*}ón³üýW,²å¸£å˜¼>©ñ£˜¸7Œƒ[ ‰pÒÀGžÿQ°œÖnE ãækç�²¸çÎð:¶[¶¢³ríè_äòÞÿ–|°�êlyH®@ÆyïE!¬mÑ´Ö¶|¶Uõ3K cÜdèDEV�]>ÞU!¯"<îà)›”A“ÉÞ2ˆ\ÕㆇÊ+bäá¥á2bâ!ÒiÚ>ø÷åìY·©\Þü¢TÎ_­ØO:0›+Å {øüø8�'\ÍV]ÞúÜP‚¯Ã _O„s"bd–°ùÓâäÇÏ ‘o}5QF A9 @ß5(–ß¼Y¼ÔA{R’CdèÀñÛ%§ À4ÌUWWKff¦¤¦¦Ê¦M›ÔkNNŽbH™‘Y‹nBè^Û�6þ¶¢¢B>,ýë_å¿ÿû¿eÆ „ª©©iëÄFÊWWô—¿ÿÆ`ŸáJ\\�7ïAÏñ±R…çõÌ¥*„ÊBâì*†¾Q|¼ÿþXDâ<Í3ÆsûÓŸþ$o½õ–©ƒpÜ6àÓ±Ãnë)"Û–èê­z`¬D×—²ÛÄQƒ7_Y²µÐwú4£^Ö�¯‘+eõ*»\s‘rðúü7ðphgôºvEjelqDÁN˜àÁ2öQ¦4g?Æ:Ž€¸ ·eÆ�}7Ÿ@üÒo¬�‡Ýq�íèùZÉ/V‘ ¼v$Q\…û¯*áv1®,ú­ïÖÀYý]øwx 95rôT…¬X�€Õr'ÀÂN“àÑÀø@™G„¼¿¹ M£|±·DM À Tó ?÷Ñžñë0d zpI¤ªµUÛ¥¢ð"²?ýURæÿ?ü¤5˜£e³ko_]ýŒ@µ}(Züäb¬¹µwEY)¬m”3™F9wÍpÿÜö¹ïª�½tdÏ;“éjÓ.çºþîjYº»Ãg!ÅüŸ?uÎÎ™Š½3&5X¼¸cÅ}P¼}=Ø1KN4É„²Å†#›H;�³úP´úày‡¤¥7B?ŠbÄèüiãâ¡ío‘ú3éâ¨cíÂûæÄ¸‚ù»¬G˜Ýf,4°Ô±ÃSQªßÁ·Ã Öø~P…BtÓnã;¯›5掟y²Ö=¹owœ»¯?øäñ*öè8[zþ<’z{ÁnZ2;N-È4�!Ô ÁˆIÌ"deúbŸY‰ZžË`šíYˆ �^K¤ÃÒ¢±˜˜@˜|¼©Æ‘õ)Y Ç<$ÖØ±¸qáÁ½fƒP.��Iq& m�>qÒ5¡G+¦™ /ådæhG'pµñ�à�Ñg Cëþá~‹D$£õñË�ÂÌzÉ4:2SZ¶½Ž¶¹™Ïyýyêj#U�‡~Vb´Y)šmV™ÑvA š€W!´r1D)àÔ€»Ê“ “v>ÝS¡BìôûÀµâªñøZ8'#\-æJcoµþ(Ø“ð§àÉpQ*»Ù”q‘òèªþ²hF”$Äà7κp×uqîÑÿ_ª> |.F–==Pâþø`s¡lÝ[,ÙÈÝÎ ³WêêꔓՔ��­˜Od=µe>x!ØD×@ÖYGC’BdÍ]ñr?|Ô�gfKv]nº¿UÚÀvl°‚] �ÃQ®²ù}øá‡ŠùôÃþP½ºûú0¤ð¹çžSºV¬+Zp@œÄ…Ý)Á–$@,8I7�£»Ëî­ýQž"ipÆ+uR]pEë}‹Ý3¼:¼Ÿ7.Ôɾ,è;aÁ¢ùqNð\c;‘ä7 tµØ¢ùÍ_¯?øäñ*öøNáá�:÷}êB)tªdìp+B68�à ºNM ’2™Ö R»õ`¹Ê˜´iO¥Ì¬ÂØ8ˆëÌøu 2Í­¹3\ö¥U�æ^/5˜¼];ö²ŒZúëÎ~ÚíïX¦ÜRg†µÁäÄ\oÔš!(õsœÜ¡�foí`L÷ž"|L*FÆò„`úDfÙX±Ðª™„?Ú1ž+‚3‘×�.òà<³ ¡ËxÀldœ¸R³HÉæ±¹bÆWº'Œì�»!”½~�kuŽÌ¶¿ýS½O³×ñ\Ÿ½ÇŒ²™eÝv;2ù¹î!½Þ”'êD¿Ï‘/ýÅ×$×ç»t l½ øð¾`xÝ”á&ùí.0ùdF£<óß‹½ëë«+;A'V©+¤äÚnÉ;ý¾eì’ºêBi„�¸>YCxÆ"|ë®á2mlÂMÀ0CP=]9X¶Q€êó9 °éS´¿û^W1q²i܆ìæM²BLÜ*)ÉNm:¸b¼“g«eÓ~›:}� 9!Ô#p.L|b¸Bo�4¶Ó÷PÎEpÀ° x\>8 Ú>‰²zqŒ$Å)ÖªÈcíví·>V|FyODXͲ`z„Lc•Çïé'»—Ê΃erò\…”VÔãž!«Øéõ]L踃�´jaœÜ³(NƦ„:³(â€ê‰uSÉçžc‡"h¼5Ù‚q/¥5iRU—%6›M…†……É·¾õ-q‡ˆºv‰RÈì}gΜQ€?°X%!üN �zõOX'‡¦ÄI@}‘”Sï QUcÍ/½h¼OŒ¸*g˲î\½E´C5߆¤c½ ~îÞÁ$vè·Û£x?ÑÙ®º©‰»=*Ζ]®ÏÒåªêµr¶üü!ôˆæò*PpS³ 2}#׬ –SV³šändGÚsܦÂòŽ]°! R„LÔ2ùéì,¹Š8")@VÎ —×>+R)ÉsN¯—þc�ÈÄ9Xatÿü†àNaòûå;@‹qôe$›'¡dƒÁžyw—½E;H¿�§ÿ=Ð ‡,hÌÈö—�.ðbÓaWߎlTã�}.>’ÍùõFÝjRå“›àF{™ ¬�)ðÜGö–pžr/éi§ò_OÈ�~Ð *k’�`[iFÊ×FfÏÄ¡FÉ-v•ËÛebñ³‘=.Sqw„®Þì9�­÷Ìr‹ÒXÛ �)†kj¦£ókõÚW�é䨯�âŒ�È^÷–”\Ý+ 5¥˜`—álµÙ(à=nxˆ,Ãh*¼cÂ[‡µiÛõäUMðØs-à<ÄÄ¿@ö¹ÝÇ®·"ƒÝ ˆš/GˆÝØ¡ÍiŽ�a¸Üµî(~är5¬69ð© L � 9œ øëpMG¡·¯|Ç¢¬O¿ Wl'p÷,Š—o<˜(ãRÀÁÂ�—ÎuõÔGþÿü5à¼'pcÌF„›¡Ã&“F[å1€PÓ«åð©J9x¢B.\±I™©©¤§sU¡A…rRÌ~Ô0+˜vѲxN”b:QОw!ÖøÜ~òù®®±KQ©ºTVd—› vV©OÅÞX#%%%Š�DÐì»ßýn�Pv»]ÞyçùÕ¯~%§OŸVZX¬ ŒÇ‡Í—Èà‰H€€GÑçÊãô%£®xHX€Œ-M%‡¡wZà¼þ¬/ï^�ýHóRÕŸ+Axµ+j¾üüMxÜÕyã�ßü5ÐÅpÞÕª“õò ÞÅú7»5jÓ ¿Ý5°ç@ñØ ÌŸ*•‚«©Ufµë·ºñ'4ñnnýî.²ëdÃ^v㽸‹Sпj³Ë7H‹K­«»¦˜„Z\ÿù¶‹ÙCM°¿ù½÷˜= ¯»®Y>ƒð½fI`‚,°Î4Áºxš]ÞŒ÷"ï�­ÇW†ùqÂA¶S_³¦SC¥”^Ù#Y'Ö)ðI�N:qž'—“G† 9T&Ž«Òs S#f«¹ ²ù MvµIn!B€b§z�P¿•óÂdZs¨‡}\Ïæ5bÇPس•ý|_¥ì;a“’ íÐîkn³ùPåÃ)&Nàé$œ*e¾}èQ€NŒc�±ðÀï…£…“ñ$cRÂ䙯”UH]ivÎ}×l X~ë+5 �aØ‚1Ø!šýb‘ˆ%Ìb;tœìXd¨—"P•Õk ‡ CÉD°ì’%&ÚÉû¬"§fÕÍZii©¼òÊ+òâ‹/Ê¥K—Z@8“)ÀÓ<‰ �)fc¨êœ'|³G¸µ¶g(bÒ€00XêÒNIƒ�’yÞ5Þ›�ß–mGF»jIGvkÝx—,§_Â?�Â=q‡b·~» j@ üTȱ֘Þ'í?Eï×€~ëû5@m��àØh–ÔÈ᳕rß<ÆZ¸&‘üËl�`?=kS™”ž©”³é˜üv‘ýñò8‹¬Y)Ï¿S 2ßå]üBúgl“¸¡+1¡jÍqc�² dÈ�µöŒánÌŠGö“§µq8¨�7Ö(»†iÅÉ,l’Ÿ¬mPöö€'†¦ Ünh?a¯7ž_1ÄÁõL“ë·êüƒì«Ñ­|æu-YÉÆõëõ. ¥ó½ôü[+O,†> Bfô¡[dÑ}iÀ=r§Y ÑOâPL5­<ÚµÔÞ{ò•l´ÓÌÐ�0Èï6¸®�7�'j8}o�EŽ ³â‹›\l=fÕë{FÐ×­”*)¿º_�NEéÛ¤¾ªBâ®öˆ×?&"@fŒ•S¬2&9¢ºø-@I>ƒtw�£žtü‘]Ô ÛÙdÛa›\#XOЩ¹Iæ328Ñ)&¾à§˜¸VîÀ ³äj>ØR�¶¸Ê/‚ ykЩefØõ[ðpr]7ÞôBÃÌV–ÀÿŽU •J[ -ß·´Ÿ|óÁ$„�‡ Ä•Àë‚ üæ¯�›©ý³l46I@¥è‹DCÌ{D2åð€© Öu;uÊPs�ÆÞêôà�È£•#»eYÙêV}¨1@úG,ñ‘ˆ¤ê4ÆõJ<}ýúõ’––&«V­’+Vȸqã”xz[ý*–¿­=zTeµcÀüü|´EÎÆ(ÀÚ <ÍÆq�k'Þv·á{Ž †��@}B¤sÎKS�«OñFupñ¡ÀÓ'éõòÑåÉÛU7^9ˆ2ü¾NT̃w)öî·[½8lb³ÀQÿÍt«_nß�Ÿ|ò]Ý»ûÈŸ~¡~ÈÎÕ²lFh‹nIËÁБM$£‡ÈihCUØe&6ã>qԕƆÙóÈØ|0DÎ¥WICm©dú‹D œ‡ C`ƒº–të²yÎ^kk¥Iú�pœíé£LŸ\iý6îúûßcš8FC½l?Ñ<‹ÄÎ)VÝ‘Qà{áD£Z‰mo›jè·ðÜz¢ïCà‚ì«h€?⼩W¤?'‚s‹�Y�öòP8örxŸ¾,Aä,(JesàC_ú¼A±H"é-c�h€�ùÞn@ƒ|¸Ï³÷jgçGAõ$dÒs4|Áó£Ìvö³^õ™NT®ƒBâ×öKΉ·¥àÊV€N…øŒgkƉdl´EæL “Ew„ʈÎìuj~…MôÕžœ ÷Ç6Ô€ -‚&Ç®cU±C»ìz:µˆ‰ãûþH«¾hZ¸,ž*!&ØFLœáC%�² Ó�ûÊ%=»™-å¼myb\áþ þ6üœ hz½Å „�Á©ï4n1„m§o?:@î»+N¢6Åzt×uÁ®üv×@«ûˆÏ(TgÅ»¬=0Õüq«ß¶·©›>ãqÊ*03ŠÙŒûeÇ�–IŠ\FV€ÛN ½®‘šš¥Ñ”žž.ëÖ­“ääd=z´¤¤¤È Aƒ$!!Aeõ T <à ‹ŠŠdçÎ�BqñóçÏ«}hà[`@¤$@\<:d€'ˆ3²!Ó*ÀMç×gwƒz0ƒ™:bTœ˜*³¤®8 —ósÖ‘Œ}sµÃ ï_ª—�-[¯¹¯æâ¢OlÿÉtõ›¿zZjPê­v¯§…õÿ¾ïÖ€|ê»×®mÉ)<~>—ˆõtTg¯Öˤ­MMø.* Yâ ÛÄmìŽ&ˆÛäbf¸Œ€Øÿ�:¸�¸(“|åÎùef5hÛÐ*€�oáÅO$qìcN]•¶¥»É÷£aB’h”�÷»˜œ¬g:äé»TÆ6ý.É"™�l”­Ç0ñ‹ÈS¶€S „Ã5@ãFlj†&ÕâI&d swÛÛ¾ëU©ç õà:Õö6kõÙðDƒ —ºÖ•f¿ÿ©¥¡ÄýyËx‘]¥…nãØÏ}Ô À4_O3Gå÷Z®é�?êyôzSž®#êl1«àô‘F%"®]_ê^ýâï‘S8Nž5Ú(û‘uQ™¨µõ¯¯6¨LˆÚgž®÷í°(BŠé”™*Ù'Þ‘Âôí� Z�N<ïØHŠw‡!kœt $³Á l¸k€…Ýa2‚�€(å•9pºV>`t¶M;7a<ó'‡É’é¡2úyA(ËAç÷d;Õáv=~¡ZÖoG»sU­²àáërøçð×àûá„wû脳S`A§§à‘pcp�IæO�•ï=9PfM  µ�XøÒoþp{ ôÒ{‹@ÔÔhbÈZ´ðy€9N#VˆŠ—¢ÊýÍ.R¡r"¯ªª’ÜÜ\9|ø°Êàg±X„¡x|¥Ó>1Û·åo4¶¿³%xZ(áÁãÄä×xb•´2.EDÉÀ¡‘b/L•úÊRçuáõñ°±?¨±d=€§Ï2õ’ á†bPíûø\î‹i¼¹jNðé:C§6{|° $—3kòÕ ØO)ƒ¸(ÝEÃ>æL – #¬rì\¥Øë*%ãÀŸ%zð��qÓM )mI}¤_"óíÀ¹Fˆp;§"8Î^ÃŒ @ÍšY­o]Šñö�6ÈødI=Ÿº0”où4“$@ \/"¾-Í![áœ,ÞÈâ8!zÔbùÚ3´žN\iTñÚû¾½Ï–L6Éï³ÈÁóùù:׸ƒ¢ÕÞ´Ç™åá&ùßÏíò4�4Û–¦ú/í­O^³š…»Áîñ•‘i5aôCp_RgêÐßÔËO³È´“üúýÖl=o²¿Üs AtŽ™êJ²öJvÚ`:mè„ɘŽéÄA{Âëæ@¼{É «Œ¨† >!]yv»Z^‹ SeU£=W#Ÿ§VÈñ‹UR…Ì•m3ØÍE»»§#ƒÂýB°šÎÒheá~ȘÊ)´Ë'È‚÷%öS\^¯4išËBþÁ¦áÛá˜õ Ð ÅT)³&àõŸ†¸žd@IDATà+áàgŠ ƒzpe’üí#‰’ =>©Z}ð{¿ùkàv¨Þ÷dE–Û¤®&íI�óYÐN�–Ù.ñ¡óÑn ’’ªƒRQ} už—&ih›ÞÖ´0<�á¤ÿÞd �hNqáó%È’„¶õê·òÿÝ„•Ü~¡f”ºË¥±ŽX?+ʳÆþ Œ§�¡ó÷ÙÕ=ðD†ë ðÿ…§Ã]/¼ñ›¿zX¼ŸT7¬F«þ6¡‡ÕéÿyG5ÐzßÑVþÏûJ �†ûCx?2šœ¨–ü¥v¬¶›ÕàF; ¶,d.-›.øD¶Ód_º‚·É‰`?á·72.Ê…ƒAõÀâÅ ªCþð²Ü4¹vì¯2|îO0­º¹>‘�­6ñ(A÷ú)Ę)äm«m]–ŠjªC§fÞ¸&¥Ý£/g”¡w#Mr Lu]ÏÖ ,σµBЈì+Mº«,f,›;Æ(Í3+�-}9µ¿y¾d m;ÁTëÚ§7~%èTj3ûT¼›¥<ŸÅ ¶ Yo\fOn‰…âeSMò.ÂÙ´ð6‚Oß…€·žæÉ2pß,GDnyM5ûÓ' 0JÌw}¦}ç­×=Ð'k𪘹{Ï� D´Kùhc޼(7K�-ï:Ð)Y‰f�w‚NÔt LÜW=n,”:U<>v®Z6"ƒÝ‰ U-"ÆÚ¡ÂB-2åY6;Lƶ)·á~ZÁ{äXNïl.—SÈfWS×"&Ζá"üUøzx¼9�õ~ FÂÿ>ÌsØ/T¾óØylu?…†àñðÝ‚RùÍ_>ª>ìÿËf[[æ’1èúgƒƒÁ"a�#$Äœ$5¡Ó¤²öÆHWBH}cÆx­ �í‚NF³„”Xü>³á‰à�Â- ˜ íM«–»fru«õp† žþ1f|&/}X Šo“l=X!«0YJŠ·t�ý„}Z�ò ØOGÏWKQi½T—fIzêïeü=/bbeA+ÖypfäL̰/=ø„·Z)t�ø˜5Ú„U¼Ö›ÅA�i>&à'2•þQëoÛÇ0¶g–›åÍvˆ@»0}(Yû¿¼þÓœÏÝw@k¶I1ž8ÁlÏÈt8}µU�ƒÍ3ɤa&Y9½Q UkûÒôƒ´÷ž|¥p÷OƒH3&ôd]Q]3_O,Çh�Íc’K¹¾�‘i ¥×c&êÍë£] ŠÍSçŠ$¡­ÈZGöM±õ\—LÛ¼w¿”�ô®b7åžyG²ÒÖ‰­ø¢Øë�t6ƒN<�H€Nd:-E7jp€ó™Ãç<]wž2Ÿc:¡M=v¾F6°ÉA€N¥ÈPU‡ vššŠ*ËgY>ƒ�IQt”…ÑÊÃ}á#u¯€õþ¶29qBµ-b² ­Ø  ¾Ή‡ õÅ›>` (ãßÀ¿ �‡›¨ï4wjŒüãÓÉ2!‘FQ7èð3¿ùkàÖ®@C`0�Í\Žçß$&h6µ4í�ºÖ�@÷9SUvº`°¡œí"“ÐöSØ„¶!w‚ö” ‹�§Œ/úMœŸúÿo®.ÖDÆK2õžòv{Eï‰ >Ó1¾}ïb­\.«'Ù—FJû‚×à~à •à7�Õ€s„ûÎß7{¬Žý;F øÁ§[ë6àå0ü"| …ÇO]®’ÌÜzqÛ¶bâ*3ÙT«|†÷Ü¢:¬À×Ë—`?=}¬»f´P#0é»wA@¬BŒ$ÿâ&‰?»A’Æ=�Γ+pNã¤kÜ`£œ0¤Ù¾3�òeï<é}´ï:zu†19u’¦ ç4ÎeyÚß(ÓSŒòåÑ®í“"ÝV(pÞ“z†ý­ša’Õ3ÌØŸ«Lmÿâ æJ^£|°«�`?é-ÉfÈlÒì�ív9~¥Q>=еsÑ~×ÓW=€R‹¡ÏÛ;íІÉÔ œ÷ô7û{j�=¹™Á JüË÷\ì"ŠÀÓ½eQyî…æØ»»í*4”Ç¥ýÓ¿¯kuí<]bà™âsN#[�*ÃVsJZßWÎ-úÂÿ˜$!4ÄÞP)ù—>—Ì#ÿ+eÙGèÔÔèÂ_­2L§»¡é4n˜˜N�Ž_¨èT)‡:W�éÔáp'ètÊs²‰F…abˆ¹ž�t—‚׬EÛiw£ÈŒÍg¢ž N/Â7À‹àœxô%c#: þ�ð‡àápC$RÜß·´Ÿ6دï„:ñ›¿T °M¨­m[ÁX®¦qX®k4:ª§¶›p@X»kÎæ×Ññ9Ûö÷�l~;~Õ„Õ¤ÄÁQG½§sçÅQÏ�k×3†õ)«7È`<�,„ÞŸKþâ}‘àÓU¸÷:ž9Mÿ^{w p¢ÑÄ9JSW5Fz÷ùøK×KkÀ>õÒ Óƒb•à· ½Ã}”•Ûeç±j•YÉ5uã7l\�n=Þ, §‡É›ëÔh3ØO I€NTW´Ÿ¸N²–CÓ$õdµœØÕP[ññ?HÔ`ˆY†%á8Î#ÿd”ïÿOBÍ\#Ÿ®‚D<–fÅÈh·ï¬CÆ%A!×>u¾Fšð)Ù½*¡É¢7³Á’ù šRšQCê{/ÔÉåÜÖÛjßwå5&Ü ØN˦šAmïøœŒ2lðý=¹ˆp;mu�¢Ôÿ‚°-j?üý‹®ùæÙÌ&9›é*kÇ{vÏ7£äÛ+-rìRc«Ð-e¾6ÖÕ‚ñ&€”Æu,%Äö½5¥-ÆÍu5Óƒ†Úgžz¥€ù·Wš[ðC�Øû»»|�ºwÎX�†ñÁeÙû$ãÐ_�=óKi¨+—F�–‰Ål”9È^·|V@§ Ó�S.>¹Ýz¯/1'„8”ÔâòžÂdà‹ý69pÊðÖ S „ÃÇ ‘»¡Ÿ7}l˜NH.ÐèÄÉ…^Ûé$´�j]ÚNl·9Éø+ü4œ3wžvçq<-“àÿ_”.’,ßüê@ùúWúIl6ÁYõµãyøÍ_žª�j44U5h›‚œ ¥îÈÿPu§Ö:ü T¶dXJœX åRšŸ!MÈè)ì‰ýMC£A6fÖKjn­Taa£ÙvâõOð ð–›¿ó¿økÀÝ5 Vu1ØÖ5Ý}€vö‡»ßo·[ ´™¶ßn§Kž/�áÏÀC¹z²ã�MVCLœ! mGK¦†Ê¦=è`‘õ.§°N¶ª–'–qÁºkF+!Ú$ß%ÿñr-Òú:¤<ï¬\;ú’¤,øyËD#-½QÂ0¡&RO§Ô?:ƒ°5†®q"®7²Ÿ'`R�¢ýç\#2‚Ï}'P •§ƒytÀŽf=žê÷ „Å—"«][ LÛ?_ žäBŒúí� *óW4+˜FÐÌŽÏbÀð!‹ÅÆ2‘míVg™}QsH‚AÕ™W4‚M¿ÛÐ ²›|<±d<1¬nïüç#chÝ€X1cñ°ëÀ'§‡Å„ çB]§šÒt¹–öšäœxGj*³¡!çÒÕ¦VÐÈäY5?\æN‘+²×¡á3åzŠ{PŒæŸrÀº­ètúJ˜ �ªRŒLT:¦S ´@Æ –»f„+Ý»¸€NhwTyÚˆå$Û)ÚN› íD¦i¡KÛ‰¡ÒGáœ`|‡rYŸ ±C‘…\ϹðŸÀgÀ™pä�0ùþ×˽‹b!þŽ mêÛùÍ_·} ”#|·Ò†6 bã-aq·}­ø°ÐN™Áf::^ •פ®,ý û{Ž]Ýoä«íÍsÈçµRX­.ç!.ãå9ø1¸‹êíüÎÿ¿¿Ù–¯Ÿ8ˆÄj}v!&õWk•(qi…ì‚P±†˜º9Ùú}q²JÑÑËP?hîÉy®d%U‚SpšQî`ªhÀÓ]]žÞSfY󯥬¬N=aÉ6z}›+”Ëù�çþç¤xæhc‹6�DЋÀÜK_د»WXÖí¨SNà6Š÷¸áéÛ¬a¤Ï’MûëÅ…¬MEÈ~Gï§Ïß›¥Öz¸Í�„½†äãŸ^’-ûNxžòñÚ«R¸ë™¼ü7Xùyp\6¨•×–ß Üœ, )eV¸x!p°� ¤ç??¶hôú&‚1 !~Ÿö¾ï—k’'�ÑŽY÷èAv=)¯ Ë›àMÚz,(_¹×*�€3h宀<·YD.–umßûoOÛdÚH‹üëk~xˆÅæ¼ Wìn¡G[î[̺KH Î0?†ø�hj*Ú•uúï¯¦Èø!fùîï|M¼õzÂuê˜È네~dw»ðž\>ð¼ÔíÆçúhˆ.Ë%™øÒÙÌ—%#ÚÐOiGK$ØÆÁAX‚AgŠUxݶÃ.)¯jêéDÐiò¨L¹œN³�á³ «åð:Ö�eªAÊ<]ÔˆŒ¢NÙv¸ž¥�Û‰¾|\Íþ)t ”ýub:%ÔÅ‚Ö!C¿ µd¤[déü>ò÷_&S‘ñæè½)ê~3 Iô&J�Ž �×d®vßÌvìè¹±m0Ù =+ÝžŒ#2´öÒÑ�ýb�0ýeIAøžNž“�òÂåÕJ¬0Ò¼ ¾ï\ðËiLÆòÄë PòþUC 1,ÐUà8¾!Å9¦ya&u^’øFÕU–2ŽÓ) àS§Ì×cw&¢ñ t/ôv>ÏÎ\öÊAæ.º-Cü‘¥½ö!ÄšOš* o³Ëšíµ $Z·³d¾™ ν6TO߯ù+ÉÇÇ¢†Æ¼¸²I¿”�Y+}Ï| '<Õ„|¼ù¾ý\áDF?„?MÚ”û‰=ZV†I–L5˯W�k%†ñtôPÑý8±”o’'[áÁtcà© ¡von €;¨ÂµÖî Ĉ ¡{Az` d0â…=¿®~3u„YæŽ3Ëoׯ.ÒÁó!yú|R��YWIü7ø˜Õ3øñžù€ËJÜc] ÆŸóþ³AÉFݘ–¾w/idâÁ`ƒT^܈°Ü祲p“4z›ò:¥ØÌ2{²CC?2ul*2Zjã“DƒNZ©&¹\Þ�¤zùà{I¹Oe¯Ó»H‚NSFgtrÈ,‰ç“Ó OMÖ¥¥úÈbˆ]yU@>ÞW/kfw¥ eÆBö*qW@ %�GÞá8ZbEž~€bG@-Ùv›<bñ¿ýÊ09+´Sb�i”ÖI ˜ðãb Ÿ>%e~9sÁ-6´¹ñ#3$/Ûª{^tò(Æîm±Ç X”«@H®×—-™ŸŒöÒË%w› À¡£ò%Ã\/uÕ—$äÇJ'®U"…×Þ4ÉûïÞ‡_/Ýn5Y‡—¡EPãvÐlbüï ¨A8çú¨kkåV³€>ݼWœn»¯@oç)’ØvÝÎz™?™†ðÐk>qJÅ<áx?m9àñeP.]õ‚@Ü+ËÚN´ýùGï„å ³d×�œ¾äC­\Üù3ɼ@R›x6°^�/|–u¥2$#ú7u“aµIlîE‚òDÏ�^(OÂã‰dç7òxªó„±² $ð°<±Ì÷�Ÿ£â]$䡺o=xLMHÄ×ì Êj¯·ãò&¼Æ©6‘ï=aS@!½¯â3!v%ð´h ˆðµ Ãë~ùa Û‹ðÌ®¶KÖƒœhñÙ W€œþ ‰7÷Xìªzuþ8äu²*0º¶x‡zAÊÏ~$~O¼-b1” •?"ütÙè§Ò$@[tó¾ª3õ¡�ñ§Ü�*1áû䀼NN)¼â茱Ñìuóàé4Ùëì×�X.½Hê½!pDy䃭N$_ð¢ß�–I� �5òsè(ûçÞê턪+2ñexý>tÔ’›m“'$ýå!óF|3šNbz]”nH§, ßŸžÜ¸G�^tËú�5òñ¶ 9{É� ¢yìÞ~òµ'ɰ׆çwêàÆÎ­Z€×ÃU]ƾL±f¤c[£Õ´j°®øæ·ÀåzèÈ<±zÊÄ_�0pÐF$}RÏ <‰6À3vS‘Oj‘í0"'ñúK(_£_F~3^ t…Ô�‹¡§|Ãg‡!†mLK ¹I-@×Ý5гÐ1D²žvɹË9˜à¥H@Kí=uNlùýŒ‰vٺߩy?!óÝÝs0 Â*i['€,‡äãŸùø_hPéÈ�¥G¤øÈó2zÁ÷1¬ŠMì£ïÄÖkù\ó5À‹¤Bd‘#¿Òû»@âØ‰1;à,�¥/@¦¼åó¬2žOä£iMx,rô¤\\`’™c´ì{­mŸÌïó&ùê}˜ü£N«ö¤2 À{¢;„ù¸(>Ü¥äÁb˜ä¹«ÝT!Ôƒ„ó¼Ï52|Uµ.ÿ7²¿I¾ûx VÀò^r.ÂÝVÚ§Þô_ót¢¤³d�”}œN«¤¡¾dâàψÛѰþér?ÂëÏÌ�~¹V-÷k'š¬^|ô•m˜$ØNWPvóÊ*„"Ÿ@äñ#Ü(o”F"qd¯»Ùôæ ¼.—žN‘þ¯¥þC•‰Ž†Þ ÁÙ±j»KöÇj9HcÑÇšñ�¬F0Ôã5¨ÌQhU´R½ó Z«Üý'èh¨%/;E>÷ð ùÛ/•pÿÀ¬ÒÄŒ”÷/ïųð~Þ¾·V>Ù]-O:¥¼¡ñG9à}¼n{¥Ìœœ-Cú¥*€6‘m¯˜¢GV�v¯EAyÞ„³áx§*=ò,{W¥ØÏ§¦Yeà@‡jOI£$�l ¸D‰ .ü¾Ê ¬ÁøUw£þœcˆÝ/ \¤ Ž!†ºÚÑA¸Ñÿwµéo­ãàÓÍ{½Ùw”Aß�þ=O³Î’ û\2qD>?^#éoY6Ç!;¹.¥ ^9rÆ's&§©Áë5;´ò1™…SÓeR¢²×©²VzYú�{Tì“áÁA\,qr\I\>HBñx¡·Ï=3¬r¥*¬2ÌÅÿÖ–÷)�FÂ£ŠœR3@ú< ™à(qÐØšpð¬vU< Ìæ…Øs:Ú§·¶[¾'�CÀ‚Ù(Á^‘y!ì¤OÚ/]ûÂP“|ë!›0¤î÷ 4×eåîHEõ/’üJ§ûá ïMT\–¯üØ×¥öá=h#8Èl~î^=ôŒ„×…°¢[¼WJ޽&eg×t*• Ÿ “6¬áù÷ËOSäOÿ®÷¼Æ@§ê¢Rrøu)?¿œ*5O§Èh†í+dâwÎtÈýk9Ø@_â/‘‡„®ˆ¦“ýà³sÊŽ£nEüí�$?`¨ßðé²  ÓÓÓeúŶz:>Û öÖËžãnE¬ó:e¦[eΤLydQ¶Œbƒ—•^u&Àà\ËyЗ¡1ׯÞs�ÑÊè?@gA­ŽL«<´¤ŸüÕÓC$ò™‚o é àVWž}lCÅàÛ/§Õ›*åÀ‰Zp ‘Ë 4‘™nó f¤Ydî´l™6Á®žsÆuln¡Äæõ €ç§è*@zgš¤Xs0^aVÈØó ñG5J¼¡Êöéçr@úªŠJ6ÑsfBHÎgËè!׆êaóV%ŒƒMž*÷ÎÉ’ë«�:Ý/%§ß—SžÿÓ�Xu�q½´ZH³ò"?ü²æÚ´ü@eÈ Ga=éý´õXH¦ 7!<Žs¤˜0œj ²•œú횀�‡©5ÉD6ÀÙcá6Ó*ci$æ0p"Ûa†¶—Öd÷鮞X?7<­:F^ªxð©-uOä6ê"Üq ® ï;Ê…Ò°üóË~9t!Ô­¶··P7‹œ½Ò}ƒ|½.0ËdJŒŸ4Kõ¶ÿät²D8�vKÑá—¥œN>r:©,AÚ À&”åH‘·e*Ðiú‡ôd¤„›…ºGZo–í2Û*{’Æ^¼Ê v.Ùt ^Êf¤Dô é—‡lz ¿õ†ô³Âûɤê¡ß¯ñU@öaxÝ!€N£Ì½'Ü™�§S„Lœ!{“ÆdÈ*d/]r�¬�’ï°Š#Ó‚ì�Aº ƒ„º ím2þ6t 4…€Å’Ûû(rñAýmðÔ�W“÷3�¥³<² €ÓêÍ•rîÂ?Á'D •Ïã–$7+UfLÎ’÷‘»ççʰAðö0Ä–L•ðï€3I=¼Ñ‹J}âqçŠÃše  ·rû ¤ç3Ý¥Y¼X4½ ð ^Úmÿ]ïh|†øA0¾ò²_¶^ixX#r ¯ää«Ñú"F1^ºÅ¼)µáîD>5pëwˉíÙ0À§ž}}Q;®°¿}šÂ�èªmµHaž!ÙvsScö4Ý1=SÞÙ˜*%>©F 36}牖Cõ°G«bNôØ]Y²ãH½\a)W9ÈÇŸ‘¬OÍTÄZ×êîê>°õqsµKäCd»�[Õd‰?"ù˜=nýA“<:ß|�‡C oCè‰·ßøÐœ¼9u%�8=‡¦Ž°`RÜ6/'½äOºT’?¬ (Òl=äMÿ=¯ ›=Ö"ëÄÆ+ÛO„äo~ã“ÓÅM퓌ã_¯Ìÿ÷tŠLA»ø~¶�²dßÙØûë퟈ߘê?±ÈªÈÌüN,ÔsóÑ�P»JxÓ{.þš|´?¨B27œë½Љ©ßà&ἺGŠöÿNJO"ñZQ1{óüsáé´hºF74ER‘¹OóˆO 0�ƒ?p½™fÛ(ïvËGÈÚɾ‡^Ÿz?B~¢Å³HŒà�Qðº¢7#� ôßã«Â2Á= ^(‘Ãg<²z{½ì?åV“z–IaÈÞd {œU nÌ~•¿°.ìgÒÒª›ŠBà˜„.ÙüÐË„€Ù— _€¦òœoŸ™'ßÿæH;" ½ìln¢êò~¯FøÎ›kÊå+®È…Ëõ*œ4>¬N?]fbÌÏI•©ã²dÑìY8 �#Ó%Ë® Ùº÷É¡×ôæåu«ªõK’¢sÄš RIÃúÝ~áÍx ôœ-V•4ÖU¢'øÄÞ¼ã¢ím’µ ÿàœW*<Ñ1[Jý/è6hûWd;^%cOÃ-Y@¸á!Àá –ãZÚ&ßEÛS²�€:E$Óø”LëöŒ²ù”ÛÝ ]ÊÁeaI¼Ÿ<ò©;âkæ[ÉßzrçL»¼±V›´m9„P½»³¥oK¡z×9GNè†ôµÊËräW+Ê0Á HÅ…õRqn� ÷8:·ÖŸµ“‡™–d“�‘}ŒauºüžK­Iµ+,œÔ÷Í1)Ï–æÛ‘ÿiñT‹\±5AŽ'ìðtb(ß]øž¼Nô¢×N{„@ÓÉ¢<žå^C$ÍH²Ð›ë—ßNUÀʹ’�ò*â!yýâAŽ$W£Õâ7 JÜÖ»“»ˆ6zp6¸4ðúò‘ „ÙuµðØ?ûFŠ"¨ÿ³güM¼õ>9‚Ò+EË^G çÕýrÙ뮞|Oüî*|”&"l_}rSeÑÌL¹Fc§ ¥» €Lëá?ú¾í}Åœ ³ZU»U[jåBqƒš„³MP7ª]¹3[&�JA˜ =�JµpXw+Êó¬?r®AVnq©ð9—;Í"4T‰´“ø}�÷ɵÀ•²¹R ~9Sú ¬xé�Urk”ÞšÐÌÅÎÍG—×pÍf¶­,(ïx*õDǰ,ügÐÕÐ. úoíä�ï (Ï;õ$h65L¨iøÌ2äÖ¶€>Ý׿§ù;èb¨Ey?mG&»Y™’𥉺:3Üï§1�«Ç M9Bõ¶öÊK® ÕCy׺–ß‹0¾õ»3�mǃ‡¹[.íû•ä�X"V›c­f~(1+œÁÉÁûxðéz㸭¤DŽ;‚4ɤaMQ$vxrMò0²Õ¥§eD?“òvÚ×O'“)®W~K¿5`®}ð|P^ßT|R]<±¼èñÄóiˆ9™´TŤ~G‚÷‡æX”½»6:¨’uׯqN%µ‘ÂÉÑ@RifУÔà®ve™ìBÝ<±¼NgÞ—÷™ü,d¨å·½U´ð:vÎR€N‡_’²“ï«ìu¡ �®Æ, Ôí“—&KgÙå^r: ²‰@OKi-yctÆlÓ‹]Þ0¿½ò>ú¬cç= TéZèu4uŒ]]”%³'¤IfþÖ<‰} Ëãäƒá³‡Î€H|W@'8Y•÷ëÊp³±ÃÒè42ÈÉs€0BÔ`M3�ú¬þE>Çus씚vL±­{â;Öu"ô/¡XÁ� âýó'†Ês³ �'¤H ¼§õöEÏ´¡3eþôY47OfLÈ”ÁýæŠ{—÷¸]QoÕšß³=à|nö*°¯auéŠWªªÓ$Õ ð Ž‘è!oöSïñçG�´ ¸¾Üò‘6• „W¬cB‚ñcµ!yÙP/¹�ÙNkoÈ Ð—¡åPC ô ð¾TÒ||¤ßÙ×Z’ÑéuÖ¨½p|ê…­U&*°ºz;'Iç.yd÷ñð�d\ãýD·1ÃRdú8»l=èTÞŸ KÞC ìŠ,º=ˆ8']}s-òé»sä¿^ðbp”êË»¥üÌJ<ùiåýÄÁðdEG c}Є�=ó^#£¢}a›N›pz6½µµQ êÓàL¼0{Ým£Ì2dzaÎÈ)†Ý´W8€¨¬ +Âjr+ÕÔsbÝÞRÚ¶}œÃS‹­R\’[cöx!~Ý- mûâR«šÐ¼·žmï¢öÜ#‰8‡àáôÕû¬ò*2 ¾½-f£õ‡bïqœë•ÁûxѳÊ4ÈðG]È3FP,Y÷‡~œä½2¼�¦¬+? ÐéRzü½A§|„´-AÆÌûÁ{¤@'9œxJ¤ÐÖl» ÷:xºAÞÝä”Ý ön@êx†ÀRèÙ4fX†< O'†Ã‘ƒ‰µh~PLtªÜ‘s„ë¹^‡d .ÍÓ)Rû°=ÃZx[–åËeË`ðD±ˆL&xÈV…õ�“Ä#®à$¼ˆ2Ÿ†Îƒšr³mòؽ䉅כÎ" †é)EòvŸ=Å.Ÿ[>Pv›äÚäÞ…2ï¶,:!®¢x©4�„Ÿ×®[/å\ÎÆa~©«Ë—œ”•eÐhSÝzYÔÁƒ¸ÄYÛì¹bNM…'kÏ¿ŽÕ‹ÀS‘[äÕÓ B¨öGŸM(í](yž.C�Ö#Ò#,»cï^±¸ñ�’Ä#%¼êF� ²€>%È�½ ÂÏCog]5ï''ÈÓ§Ió T*žšKggʶCujòx`Õ± ~x¤ŠišÛ# E¹sjš¬›)‡‘â<ÔØ E‡^”~c‹-C~ò5�Üû/ŸóÉ9ðèÏe¤×–W?&¤'‹5~¨/.!‘pÓ½è)AN§Ž'¶U�ö#l�¡e§‘e�Þ-Ííב²[Û§ 1wO·à2Ë;Ûc“ëÖ¶Oæ÷›èiEN Á¦ç‘±­„ï:ð¤ýÒµÿ¯Âã-½Ù€¼¦³ü®¬Åœ±fùîã)R"üÝlò¾ �£¬wŠ:™pÏ×—Ÿ’â£/ÉÕc+Ä[V^§µU$˜½n<�H¶=œNÌ"§@§$ �l¿œ©‘L|åÖ:Ù¸×%UðLÒ3yYpìaÈ`wÿ‡,EÈ_ßguO&õÆŒ<›"÷RÕ³M}ëÖ®í=é­k£›å̳z:‰ Êá3n9xÒ¯€4ñ5”Ý66M† LÃÉ+^_X6Yú´ß8V6²è=|G–Å1éýä,Þ¨MÒwô£røb@àÚ$ßR¢žÅ.x0ì>Dè^ËüOí= ‚-A(¾ äÙûÎäj�RÕÜ‹¢½å¶´ý�>&)ªˆõÇÇ Ã 2o”m §Ö½:ZÚ/Ùß=ˆðº¯ÜkU`Ó‡»cóç÷æØ•Âðº;&[de\žÉŸÿÌ¢é˜Ýº²N<ÖîÓ!Ù…{nçÉXÈWW×!1Çk:{UÊN¬@æ¤�ntº¼Gc@ÞÍŒqAz:%t"PdÁ¿¢òFY¿×-ëv×I12EÐwñªsB×· EîC8Ø=s3ehÍ#OÃÍn f,˃~íÀQ�¼¿Ù)‡N{à¡FÐ)jEÎÛ‹¡+ ¯@û¢¬ÅnOH®VZ³°MËÒìø-oÔ£¾%Ä7úMhk6bp¦|í©A2à¢>ó{CºÙ¸·®Ú°`”b…7ÞGo·è›n®£qø&`ŸtùªWJJmb3çØÀ ™ê¨šlf|è XÞîÛU$¿ýEšüÉ×ï—I;[Ê·üQʶ½#Þê+¸Vh`|€\Gø¬rLòúY¿ìǪ€VDNàõ? ‡¡‘%¼È/Æ‹a�ža�èÍÍÇGôCϨ›Q‹›Äøt“\È6žcË_‚þ�Û7 Õ+ÃUfLLáe³±z�ü,‹Ü�´èŸè°óˆG.—6"Ü„iµÛ7ª%˜5gbšŒCÌÉ‹ndwñHÉ‘7¤`ô}òÚ'&yqýµèXÇÎHèÏ“jᤎ—Bp©¤:~%OÇ‚RRs@É'~ç+2îYåŸ^òË�sÑK“P²ŽŸMçö¤ÇW¸±È•Õ]ÂAÝ3_O•‚l“\*GˆÔŘ�ºxZ0Ѭ ôV#8¥bmá__#ÆÛE»¦f‹MÂ@_\åGÐ>_—ÒS Sqƒ‘)-ÇÝ9޹k¶áuè%O脪¶>„D nY±¾\) ŠƒI?\6²u-ž™-!‰ÂØ¡6,1\¢y;eÝI$î‘øþS^ùp«Kö¯gÃë¢×�ï:½}JÀž™!hVB]–�m•¸m5C·uÇîÛ®ýèLV¡O^Š<~_Y2/Çðx¢AzšðÃ�¥î³¸›­§UÓ¨�6™£ç9"TUg€ï)XB#[rÍ4 Öõ`;ÂøvêÓröd•<øÔtYvÿßɤùË¥håsR¹o­„ýÞV(>c|A“¬8ç—�…à Ä8;"ex¥ÇÓN(ɤ 1,ÐÓ,ÀE'M¸Š‘$iV²ñÄJ’�{r±øÔ“¯NâëÆ™1Wñ¿EåÀ)¸R²d1Âïšx?¡;0áîX4=^V•Zœi�7ðÈŸ<�Ýþ¸”— ï§¥sì |R™ï.n–ºâ’3x><%ÿ,&ö@µfß~CrÒê„÷ÔNp÷¬CÆ=òH%tÒkx¥2¬ÈŽû!c_w 3Îo–vÅfä»N…䛿ð)Ч»êF°aÕÞ€Œhf7ì. 2ü!}ÌB®©ŸЛ0µûÌlÁjÈ+µÅ{åʱץüÔJñºÊ›x:ÑÖY™VY8Ý!ËAÞ=a2ÆŒ$� O'ÖÌoކx”!áÁ»ëäðY¤‘Ç*²:‘@yÖd°[œ OÍIƒçÛ.�§x‰�H$¾ vÇİq@:g EÐ7¡¯AOAyqÙ¨Ë祅åÛyÉyü8iú)î‡ò–�ÊS OB-©·›=-W¾ôÈIÅõ&Ï–!=ÐMoùXA£J´Cp«k±hQè·PÉKßS» lÃŽI·zhvÒ—ÎWÊo~ø‰¬ÿ �<þù©²è³?�{¾\Ýú†„¼ÈhÒ¬cçâ˜+­EŇœ ¨ìu ¯;�ìu;êd×q·"ļ7¹Wômè G¡4@tÉï)ì¤Ú%Ü�dµ ñ‹Ziú‡úJ¯§‡¡ƒY¿AýÒå ËÈPd-lì­Ž}<C ô ˜ð@).ñÊùKÉû€ºæW¨§Q“ CXi8}¸D~z®R*¾>GYöñ–]�ê£[pÝ8.Ñúvvñ>OçýòÁY¯Tz£cº ?}ÊçŒ!†zª"#(Dx4K%ªÂO“—3‚Ûr<”š¨²�rz� ð©÷\«DÕ”B†’< GPåèùzx4¹åÁùö¦ÞOØ kà÷ÌÍ’-\Ÿ�¸´AvŸðÊó2¯É’‡Í¯+ô*\`•%sòê*\›åêÉU2xÚ>É87áÞO^�=Ç׫É¡K@Z}ðœÆÙs®$[$tb=˜Áîßÿ“9cÇ fËÓjçÃäŽÚ�B[£÷“ÓÝ}5Éw˜ä±Û >…åííÈ—x縞œëÿóg)’�i’/ÿØ­ÁÁõ {ŸàÉ�Q29F}ÕR^ø�zàÓ ø=˜ 5½ù²Îvû4ˆÄ5ЉބlÇÉðt¢-A·Ü$'.úäƒÍu²ùP½Ô»£äíq&�Ê�"ƒÝ”tÉÍR4°× ”ôŽ·mú˜Dâõðòt+Î8Љ‡¬†®‚þºJÜðÂÒS¡­Þ V¸:XbOZ¶èEÕS…5 }jḬ̂ʂ9F¸]O½ZF½z•Søá¹yì¬[.•dH†µúbðt]ƒs÷ªÓºÉ+kR“e>‡Þå°Lœ|· �¾Lꋎ‹¿ºØž§¸°„Ú½ ާUçÝRoÝÈÜ�Ï>[~ ½MÒ”%bX óˆ.¸© ż[Ùi%Hˆ±›ÑXÈOŸèe�Qv"�’ ÊÅ$Õ±!qRcÞƒ,Àî¤Ê•˜Ÿ°^>x¬ØP+ó&e€œ„ÁüVvÓÆØdüˆ d�bÈKXÖïvÉ’Yê�ÛÞ;zÜ�ëã.)¯ñ‰ÏS!ŇŸ—¬�³p@ör¬^b¤ÞKo‡�Ì’ C1«m&LLéÍBï¦ã—ÂÈ´’êzð¹`¸� O'v¶º½Jk²f_â 9nV±.ü8(ß$_ºÛ*—áÑôê'\ÅÓ$ÞÓHÿ.Ù¯$wÔÑmt¡T#Z?/´îžx¾õ v`x3¬ `È:õNÁÃ}<öÅç-“г«åÊáW¥æÊ "û$Ã`uá}š—“"wLËTÀó„ôtÂuQ “¾Ub_É9G�€ËÈ`·Å2q—T;ýŠLœGâà~@ß4ypA6x¦2¥O®–Á®y;eÝ PyX>á‘·¹d?^5N§èµcGþ»ÕÐW¡{¡¸ón :a�yÑ>ÜøôÐjSP=U¨¼:Œì_�*Ë—ô“œl«øaSC 踸â_ŒÌg{�¯!}2úƒ íÊhZ7jíIoÜÒR—ìØ\$Û-é}‡‹¿¦|©aqáñùêi¿|Tè–jOᛡ?†B�« #Ò£-À� ºOÍHªÊ1Z À§ˆp,ÔÓ=Áõº¯ ´€>%И½¨(„> ½�¡v狼²z—K¾x/øœâbïØ e!­ö= &øÄé^O]Ì“©c˜õHõSتm ìð>6¹)Ù_]­{?­”ÁSÿD²ÍK¨÷Ó°¾&ùó¬˜x†eËÑ LŽ5Ftuåµ¥@æM`ŠYåBñ¼xÚ:ðѶ³iÛVÓG™å+ˬò.¼w6æxD“gWÆ&üúw]ýÊ,ƒ 'Y¤fXXÞØ ÒåXõº´*Ÿ^h‘Ïße•Ÿ¼Ó([‘QP—··ÝÐ Eß´Ó¯|(.šbV€ ÁH]þkE£Åšúï=û• �W‹øë¯Jé™÷äÊ¡WÅYzHñ9…‘yRn6° M–ÌvÈ¢Y™2j21‘C #YçNP‰`Q…3À©^VmuJ&gz;^“‚Ü€`ÙòÀí™2 ÉÀÍ«µÓØ%Rà'v�H$¾z»KöÃÏC"ñ膼±Š¡ ¯£÷'‰ÄéO3>´"-é o~€mÚ:ŸˆV¡•Ò{Î×}P•;¡æ´T‹LŸ%óÀñÅëaˆa÷;z]î;†ÌšÇ‘Ô<ã{r¯¦±çõ,€nðØÁq=:OÒú�ÏÅ#Rín�—NùdÃep&ÆÈÅùLy úŸÐóP£… éñà}«îÕøy`"kÍ1i8¶ƒ|B'¨ÆVülÈ-b|ºE.t §ÉØs®È¼53ûÊ{kåNp21›]t²�n(Œ™ÖÜ©é2`�ÆÕä…§Ô†}uŸ °kû…Dæ÷Ýn—u;]RAï'w¥îN¦ šŽ.=R‚ zËŒˆÐ1�I¾ó+Ÿd¦1µ Ò°RD&mRo•<¸³ú›eém–&àSü6]õ~Ì “œ�ãp:U–_~بBÿº xâ¹ÓÈœc£™›€O]eç¾Yùör›â¹úÛ߯ÜÑô�È®¬Kç�…‡;ݵBñ¹Š¤ôä;àW{MêJ�)>§0 Ý"Bðgø 4ð,ž‘ʪ Z—¬ð:‚7$g»­È`Ǭ›ç/{À¯8'2LwdÚTF½Gb7ìÇÄ»°» §äC ÿáuû^çÄRt\xA§«P‚NœtjSx¶Ó…‡ã@ GcÝñïæ›N¤â¬r7*¹ðvZ0=™î¬× bˆa�NX€àx!²tnÜY'ååC¤ s:0ô„\‘3¤WX€ÞÕe.<·L20 ¸@Wó‰ÙXä§?z¹ªø{èC à©W\Y£’ p1N�lèX �ÅiŽÙR1Ò §{äP¤!àCn! àÓ-t±›�*'_B?†.c'SZå—·?©“¿z2¿É¦üm& §gÊŠ�5¯„í‡Ýòä=9Ò/ßïYÐd¿Ö>(ï§¾6¹A–¼ôaÆ^�Hé¾RúOxTú�y ̆Öv½î÷ó'˜eï™P”¦ N?x­QŽ‚¿ g[ "q}ƘŒN••£÷Èäaf9r1:‘OŽ„Ð³6Ê&x_u§|÷q›,žj‘yůì¤×%žð\ÿ.™¯ ¯›6Ò,›�ÆlDþ¤ÓÅ!),SϽd¾Õ²I0¿tšEÖîïÞëÔjÛôA'¢4ðª>Ðém)9öG©«8¥e®‹›èXN�–!ËnwÈ‚©ià!ÃãC^�d�N<‚Hl�Ûy™ø¡3M3Ø¥ØÌ2j–<¶$[¦‘Ü<šQO3Ç,©p2ç�|èŒGV#Œ÷ÀI@Ì&žN<•2è;СG ì÷:r�yH‚3fŸ€_ÛÞ�p÷/Ù¨ámÐ\ž[Ÿ¼4™5_©”ËÝ×.{¼ÕŒ ¸�ØúÉ™¹u_µì9h“4Ë8I±°¹Åž�7(Âø¹X€�¿×Ûˆd9aqZsåEPÐ㩎OMtàéGøxjtœÃ/½Âœ|©N‰ýUÛÇ7í;7Æžq#"r>r‹YÀŸn± Þìtëðù  ¡™Dº×ﮓeó2ax\HŸfLϰˇ‹ñ"}lyµ_¶öÈ“K³:6“Cy-´ƒè¼^.#óK ¡N.nÿÉ<_RÒóHµo~ø÷Ÿ±É�S,òìÊFY½7¶ï~ tIVGª—Oàé—ßJò(}ó~)ªÔÆ YZ`£»…àÎÌ1fd‹ëö»¸RéXãøí_¦Ppmùå*HÞ)ôºêJà‰áu�#“Þ?¿ì§“f"÷»˜Ç“ömoù¯ƒNa©/?.W޽!å'ß“úš‹ZæºxÐ ¬ÞSFeÊ ´LqùÙhŒÕR’8TV.C¼Ÿ¾ä—ð²Ü²ß�¥`4Ô“œSFÛè4wRª8Ò‘Á•Š ›SnG$¬¬¬ ‚Ë ÙëÀ uä½ÌÚ¿N‡ž�@Ÿ‡î‡vt®JкÁ LÏ'4:,¨ÑSí¥ŽÚµÿrp¸™<³Ô‹Œš!c†¥5·k×ÖÈ8ša�$Z@T`ÿNÒ �@ùIôSk¶ÔKuÕXéŸ5­ GOÒñ’h²[¾èpÈ,…‹äõ½ûdÃ…Úxà‰·Ð Pxºåï’^kŽ“ÔP0YžO´ ïâÐ'0ŠÆ}â†Üô0À§›þ_÷‰ˆì„¾}š[Ö"\å��NùÞ—û4™[qî:€Ôô±™²ãH� ËÛ°×%!|Žž ‡i�°<†÷|îÞ\ùÑK ˜d¥ºä Ò½¿ #æýo,µ¬Ùz,(㆘áùÐΊ´§ÒBÈ�ë@IDAT7Ø– Óá Ìrb;¸”n$³<�I³êêo´uû~Ÿ7Þ¬@°··ÇìH‚ó�áaÔ]äÝ<’«oƵ"Ö�ãîù,*ò�ÙVérõö]Íëm­�N&ÜC®ò Q®žxG¼®«×€N6€NÓÇÙáqè�9wr2AÚ�¢Õí—Äfà '_UÎ�¬Úî”÷7;x­‡Åq 2jHº<¼([MO—|‡EÕ)¾]0‚�ÄŠÜÃûÜòÉ>—œ»Ü€0=€W±[œgA"q‚N¯@÷AÛÊé„Mo(„œ¨Šcê†[·¼�>ßmù×îû–äè$V�Y'�w¨Ð»h60İ@/°€ÞÈøÊP)ÎuØ4æwì(øüiÓH%�žj– h0Á&»ÎðT)‡�Ù%+m&_¤9Ib§‹Ò I´pa…±ÞsIþó¿_•’²CÈÄY¹Ò.&“WÀS¢Ín”וàxI‘Ñrü•à®0z¤\`?ÃóI·Ä-ôj€O·ÐÅnåT™åéYèrh'„Û×ÉñóÙ2utŠâ`Ñ÷KIÜ=óì²ó¨ `²ÃÁÝøÈy¿ÌŸœÖd;}û¾¢÷Y<+]¶ÌÂ1�jôÊå¿—>c—‹=oB®õBá$”ÜIcÀåô쇪�T‡Ùq2$»Oû’ä´tÌþõÀl‹€kRÖˆÍ~ÿ°.[´­Óž3Î,ã˜%üè�¬lÿø¤MÙ‚¡~Uôoƒ4¢^Ô®†×Ñ»ˆ™ôâmD¢õd=ÔZ:7.0÷É*áŒýÊÌ~ûà·ñpìÚÅ~í ï8‘Bc!›§ò <�^CxÝëâ©)ÖÂëâ&6$Žž1Þ..tÈÌq©H `VàN²A'Z‘!v~˜x'Bì^[Wƒ~Å­’ðúsRÖì–ƒÓéž¹*´—Ó1uE"ó2îÏébIE@>9è–�‘áâxJ¢ŸŠ#Aç© çµ¼} zÊÎ#Ñ76^jǼ‘Þm&&G¥»I—“ïi �ŸeÙøX»ò4ëÂ.ƒ‡6İÀ -À†¨”ÀºAKìO!J:»VÃ4`)$noHjUQ­òIemŸ*›fEe£\)k§»Q¦�Ë’?ýÌ ™5Ùž°çëHÙ¾¿FÖlj�Ɔ©’çCÀ´Ÿ�ÿ=Ü&ÐýqAÔé=$Wë6ˆÛÏŸh¬Ÿ¯Cÿô´Olmˆa�žc| kš¼•õ^,q•´a\Wªáù”8Óöš’ ð©×\ª¤U”7ð¾ý&�âÄ*Ý××Êø‘}›x†ƒFFfŽM“ '¾Pì2K­GØËœIiª#iï—ÞO ­yöŽœs‹Ë�úê"¹¼÷Y™°ìg¨ »§¦¥f€uåk÷[±Jizò\(�ýï)ÁóH¦�×é«÷Ù²§S0 ê0t«­ÂLn?ùóyk[@®ÅÙÚZŒtscÝû¬´&,ïï J)8¯ê-v“X{ìv«T:qŸÀãJ¯_WOýrLò¿„ i°Á×î�Ö�Y‹*�Mt…¡q&˜l™Â6E$^rìe)>øª^àMkŽ «Ì�â�ûF;eŒMìièî$«Æ‰Ù~Ï1ÄÎ)›bW�Ìs:`”eGÆË¹Yòè"‡Œ@V=„ìˆôês®�]è´no½lèTŒI"]Áõû[óT ¡ïBÿ= ílxŠH¬(ð©éM¯¬“Ø£tº4Ð ã¨hà¥6 o†Œ™;v?uúF†Úhö׺0Ì–À’þÊ[’‰ ÜðXr"ü¶ÚPž”e•>)oei9^A Pãl”€Nuðæ®«oWù ñBG£úõIª€2Ï]ôH6<þ† L“¾6€ø�¿÷Ù–Î!‘ÂÛ몤ðòPé›1}bΛöú©¯=θ÷<5†ê¤Ò½MÊêvâÞ«E-£÷Ÿ7/Bÿ zªn-¼bX 7Z€ƒH5ñ³£MÒÝLŠ5(×,„Y�!·š ðéV»â-Ÿ/Iæ~ ý ´ÃXèý´io¦,››)> ô”à%ü0wÍ´+ð‰ÞûNºå|q¶ŒÇ¥mݦÿN�*÷ÎËùp5V-}ÈÊõŽôŸøÉr—XÍ jbªƒ:.dE{a=“ ¿Ø…äÔä*bȘ.ûÏ…~dç‰PxÒkë+ ÑvGªwâÂãÚº?·cxÝWï³Ê· U}œÖï>êz{²ÖÅqÅï:’w·dø®ºk[à‹‚}D˜ë½ÂU~d¢ltJÙɤ ­³ôÈ5áuvL·ËCó³dÜ›¤#,–s5ŽHòéÓÖ £»Z”ÕÈf¹qä‡#hD±ÁÝz:¹ž\–#3Æ¤Š k^¼7ô¹¹Ò :ÑÓé£ÝõðtªåSûëÛ ¶ÄÓPæïA9èç O0ªÇ‰ÃÅj ©¬y=©ž¬SèV*#Í"ãGdÈ@$…ˆ iäO†H˜xÓQ¢žKè7ذ§ è©{.¹Ü!$]E?p©Ä'‹=r¹¸`´ÞL~PX¼ñ!Ñöá‚–jo‘O­Üó;u¤ëÿk€‹f­«‹jLÒyṸ=!Y½¹JvíÏGÊ4dtÍCǯóå%$×ôvâ…r7ž‡·ÓF,ä�…G]“Õ¼lÀ¨Ž�‹ÔÆøgˆa�^lŽà ¨Âó)L6‡¤Aù¸>Öð|JŠ•{v¡øÔ³¯OWÕŽ}Ì)èï ßãA½ ð}yuµLƒ§SAŽE#�å€ kö‹fdÊ;›jÕ€° «‹ít+ð‰ûuD¬¸ [œ%;�Aï*V/ýÞ*¹¸ã§rÿ?Í•o=œ®Ä_C˜”.îŽÍäôï’ùú™;,òÙ;­*KÜñK±Qã/>ˆÕ©£Çÿã–€üÛÓ)ÊS©#ž[ ÿ�g–›†¶u´>Ýï K¬ò©ùÞó~d­‹Ù¨+A0L$?{%,Wª´:p"òO/5"ä®I˜VGO³›öcˆÜþƒ©º´A w?+ç×Kaªaζ"’™n•Ó²üŽ,™Œ,q)¸7ôÉX²';œh™1 pÖ!û’|^'†Ç餕ü}@¿4y|q®Ü;?Cr홸î ^÷ñ^·¬C:òârÍÓ)tbƒ#èôkèj(üü.f|è‰Ò¬‚qã®Q[†ÜM†Žgmr²l2sr–d„ò7ÆÚ23İ@{-À›½9ÀÄö@.±=NWPy(•1m¾øªOŠKäjEƒTÖ0D®êWÉ ÈÀ¤<—Ð)0#§Þ´­NñÍ®é}Í´ßcG8äÎYyÒ7^O|ptRXæ¾ãµ·óˆÏ3Cú9Fh« qZ'aìž èÞN.©öî–r×N€›•x„6wžÅ¡ÿÊPïjhçobH�´fr¡W îYÃÄUʇ¢@…9v¥¦‰}sÓñ)}2pˆÄ]¿^S’qÑ{Í¥JzEÙéü º:—ã£Â« ®“¯=š}ìr2;´¿MÝf—÷6×(î•MêTæºaŸÑI„ÛS[–9e~ji®<ûf)&Ì©¸¸Q.œØ"¹Ÿ»O& ‰4¶§äÄlËøä „ùÍm‘ã—:8Å×êø�Ε„äîéùh“ÁMüfê=�¦é£ÌB�"]¶ Á Üßä;ý·®|%¸�‚Þdê3À§ëŸG²êõ¹Å °¿Ë*›Ásõ_+¸x£IïõvèW Ìé,?"Åû+%'Þ¿§FµýüRSÌ2oj–<ÐiêØTx:E@'ý6IôÈA?0^yݹŠå¬ÉŽcù`“SN\¯@ }þæ`ˆÝld±[œ-Ã"ĶÑtŒÚM� Èú=¯CoQ$¼.nŽÆFwú"”žN¥Pµ:‡×®”˜%;Þ%u|Ïä�)Ü1d4“æ~©2}bVB&àÉ«²QrO³ol‡6­²ás#ú®,dÕÕ“c©QJ0]õJᕆˆ÷Rƒ”ƒ‡©Ö凗Pㇸ„¾+Lp‰sz¼×»²kÏÙ^9“¤(µ§#´Ir²¬’—“"yQ³V|¶HnVŠâ1Ë@è1y¡|¨“ÉI�^Ñ3}ÔØi2vX@{lÓI,ÁŠŽ±áïm¨�³úInúDð§¥5Y,¸ö\ŒoºÛš·SHêýg¥Ìõ ((ÎI ÜÄÛ‰UÜýwè.èÍFàoYaö×/A¿Ý ý´ àÃM$ž_"a#z_ôÁa®ê&ølY¤!·¶ ðéÖ¾þñgÏî¥Z� Uȵ{y`�™ébÀCeî»Ý!÷Õ©,.äYX³£^¾ñ8:(°.›—![Ø‘:½^~�¼÷Â?‰½ÿ ¹PɹQ×H>ˆ©G0ƒ¼<6Ü}WP‘SŸ�GM2dÅÖ€üõc¶ë‚O\9þÕ_¤J_0³|û—~)Œ„r‚¿dë])$ @è¡.ïì3ve(¤~lýuíþ€,œd–ýg»üÒëÑùW t�¬idâ¯Ê•#¯‹×©“‰kGà¤k¨Lyâî™31“/p:á~hŸ7@Çj«ƒN.ð¨ì>î•÷?©“£çëá)£MY*'qó¦dÉcK²å6$/ 'ëG°Yq:ar© ž“»Ü²qo�òzÔ=¥"µ"ètú”¼N•P†Ü%§!¢à¶ÉM5rBÏ"C ‹xî™é™4Æ.#†¦!w4ˆ!­ZÀ‚ö ‡L€*ëÅV ÈWQÛ¨<—.‚’\GмøÜ.&Lð`rƒ÷My/a†ÉéF×ï³0 ¢gg.@¥G‡H—áƒSe^û¤H~ŽM²‘%“÷oFÀ($Yà>ÁØWñù©I|ÛE%ø‡¯ømo˜HEO<¡ åø¾nk¥lÚa“TóTI·õÃqÐñu¢ÜVÇØ­Mн�œRåÙo§]¿ DtÙUB éeè3ÐsP>Ÿ ¹9-°§õ]èP”]ħ A߀ ¹…ƒgåù@§ÌñZ2ú¬fÝ`|§|3ÚÔ8§,`€O-åýŠ÷ÂB(;X%ì Ê,qrøÕå9Ñ'mÝÓ¸á©rÇt‡¬ÚV«Üç׈Z6ß.#Ù¢ü.‘bÚô i>V(Ÿº7GÎ\‚›:ÝñË�ËÇïÿZF/ø?èÿ’ÿœ'ðôû¿JU®¦_þ±OÈ/EaF»dO,ÿÄå°ÔbX³`¢Y¶ƒCjD?“Ìc–I 5gæº\‡Iy³ðAÀLzß|ȪÀ0‚?çJšuã,0‰Òàׯ¿³mC©‡­ê±’ÜU²xªYî›e•ï¿äW6áq™Õ￈#æêªÊ$ì8 ¯3ƒéœ+NKÉñ×¥ôø �‰J(ŽLœ“©�È÷ÈâY6'C ÀÃFPy%ùDA'p™ì9á•·ÔÉÁ3õªC˜Lj†°Yš2&S…§Ó¼I©â@v=þÆ ¦�PÈÕÊ ¬'Ô„×qbÚ t¢W“:ÑÓ©ÚžNÚ ÅþÓºÊÂ\¹ëĈ©»Æ*“ whÑ2:šååa¿pF2"!w´‡!š˜MŽm—žM¼yÉY0é28˜Nƒ¨ûø¹z9…L–—j[Šp9ÈÀCœ¼¨v¯ùñ}kbAáäËv¤HŸ¼ˆÝÁýR¥Ÿ(]òlêûü\«ò`bH¨.±DrÚiŸî-©5Ríh|¯{Z¶8“ÒvÅVxÓ‹~Ööoï†>Q'+?q‰«v’ôÏBÓb‡¡W®½Û'Õôv"ÈTç?)¥ÎO0ûålá*ñsèûÐrh'ï”`HO´À`Tê[Ð/BûAãçÈX>>/£P6Þßl‰•,ø”ü3¼™í™|ëõÒ#Ä7¬^z Fµd»ò¡ì`£Â0ºµ˜ >ï§¾øéauôb ·Ì–ƒõ*KAª·¹ä;OtÜK‰ÔÜÉi²xfx¤j%ÔØ Ež—þã{Á d“ ,¼  Cbq†�u¥¼�Œw_Ð&_\F3­,$X�šú0óX~3‹«ºƒ L2u¸YþîÓ6•ÊþÝA•MN'eOf½+œH�x)¤²ó¥!¼KŸ’yÌ–Ê~xžUÆ 6ËR„+®ÙËÅšÞ,è$�¼Î‹RräU)9ú@§KMÈÄÙ@s>BrþåwØU¨*‡A]:a>¥q:!¼n×q�¬F[?‚ § q<è4vx†<Œ~aámi’g�€bЉØòÚ lÜï–AD~Í@'6ðÐW ätª‚öÐ ÕˆIsàI}†}øÊ v/›cöÅ™Ý µ2|rØÀ ™;͹‹]í[ëÛ(fz ñ=gØÌ,W ^&~Ó›éÄY·œ@Û?‹E¢„Ⱥ½ ûŽ„Ë)ÒïV¦å éLŃ57Û¦¼•†ô§÷Rî¹tÔ/E…{æçX•S<˜è9ɰ\¶+†æ²a±hÕ¾ð‘¢�JqŒ|¯~ŒûZ}î‚è*ªe%Â펟̗œô)°£•¾òÖõ2Ñ’4o'_°R*ÜÛ¥ª~/<Ö0läéÂoB =½•Âw†ô~  åÊÃÐÿ� …ÿ5BP¦ ÚۜלXÜ쨸¤½žÆõ÷c¢Þr<©!ýªÄ.žm%ê,Œr:cã¢wÆz7ß¾ñC7uvè1…1I€¿´,;ê¤{?݉¬Zô~â$r×Üï§±C;–ùŽcÅ4ð×<¾4^šƒd´¶Ë?—IòÙÏê%fD9ÎSàÚv<Ø$líß^oì*´_Ù—ÿ˜±îk÷[Að+Èz�KXWû÷?ÁŠ/¼ž~µ*Ûj›�r"ËÉ´÷ ,ðwp=ФÈÐ?s‡U~¿¶Q¶OÜ —áu�£Üƒä˜ÝO—y¥1 8èß%ó•“�,o<]ž(×öÙx¸7�" V^ê ¥ôÄ )>ôª¸ªÎt‡b0äd!ÈĹ+K&ŽHò�)—èØeÑM“ÐW:a6Z�Éç¶#^Y»Ý%ÇÁéˆót"h1fH†§5 )¡rƒú§É¨¡2tô~°i@›"ÿNÉ· 5ë–â¦k¼—8Çg+Ñç,�¶@ò `u âí>ì”×?¨‘ªÊIÈn7çLd­�HòMÕ�G è„ñ+–EœþÓR]¿Cj<§Ñ¸ª»F–”t_8x#j|?œ„&fÐÙ�gnºU ,Á/ÿ� UÞNlËÙ™ã.»T\ gÅã«Àí¡ð¦ütš€Ñ5Jé™Â‘¥ì+²q Öb-£ý£ÿ 3чè\؃µ¿Ä–Xå©e9òŸÏ{w”ªË»1QQ†Ïù”Ùv0„ýÛ÷?g“™£ÍògÏø¥ `…žA/|Ü=ó]òi<û­ðß TñPP¾´Ôª§ÃDÞBæ»ÏÞi†ÿµWxN?xµQ>øçT„íÙäû/7ªól©œqƒMŠ3édò£|å^«,›i‘o=ë“JÒ@HnþÓ÷ºÎF¼V‹¦hYôêˆñàqý¿ÿà—KÌŒ¤}×ûþãÄpÍMÀ|®bx:½)E‡^�§Óék<�R1y›5áuð(œ> S*30aäÂÛ¶m©­¶b_±rç‹ý²n�[6ïsÉU�âÂã¬p�˜φû‘ér¸Ù˜ €žNª�ãÚг"€2võÊkkkå(xaØoÄ ZxU?†>Ý å’sûotìÔ B×p’�Zü8§«ð¡4ïßx�–‚ÿŽ—UÈIU\Ùü™Ð¶Š=üŸ|ç«|z�EÞÜ¢�Kúž#û›@jn…g›Y~¸"fCz_‘sjÖX‹¬Ý×t}ßd¿2‹ß³­òÇ-yq} ôºXÖ1;$»¾7.71þÌ&›øª¤ôä;R´ÿwâ,;Ð ¶�­¨�ˆ×,3'8T댱)bG†8Þ»Éq¼p¶È/«wÖË'ðVª®ñƒ×%æý@âßéãír?ÀèÙÈ^—"qÖ�ÿÑ[ŠùÊ Kå½ÍuÈŽé@踺©!èôt ”Ÿcz°ðìFA¿ýT¡I<Š#Ã*c†¦ƒÛ`2ì¶÷x½"é,µïŒYA5ð‰Àj“\Ô‡¡DKAnŠÌŸ‘-/Fûv~oH÷X€àùjÀ�WÞn ÌëA g¤Ö>�}û¥ÞK •#Sî9.‘+±ÛùÁËF�<¶CÝ3/þlt€)×a“|d“£GÓPKäf„ls :‚ðt€àTµÀç3åVš´³Žý§hß »*eÕF<7ýsÅî@wÁ"}Dlkã]÷X€í§Qœ §¥!À!nÓñ�=m°äÛgœ:†pÔB<›â¼ztd}åÙ…N„ÿ;¼ ­ížºGM°–¢¼ÿ �ň—ã—TécŸ'}²î@B ‚ðŸ¿R‚NÜ;hàš<�ޏÇlåºb$}Ïï(ú+ß³7Еò=oD¾×Àïš‹^Ë×%ú>€QÔÙBÖ!"›±íq<ˆ˜×‘¸.æBÿ¸ëÎç¿68Á›fB ËZ~¿·>®&˜¤D½Á{Š%cñ„É"·å·Òë…÷f<"ÌÀ¿@•wxz9™Ò’ ÔÉ‘Ò~¸“aŒH ŽûL„~Z %@F’‚r¬/ëMÐŽí�Ëâú¤E·¡~t[6mÜØÁ�ži|ê™×¥;jÅN© êÆÄÊQ‹É#§ûç9øÄ 1ëÍú].¹}jºêi¸…ar Ln#&®—K�ýÆ‚÷“SfMHƒ>zV}Cmó6ýç¼Üÿ§îÍ–#È®CN©úêKùøý?Cìë®-xÆh¬Yà®ÞuJïÏE^„‡ÓïÖbvkÝ$}°Æ@o'zFT8Ãð0ÒúPfÖóF€'V�ÞKïí  ÄònÇ�Bž]�ŸüyŠT¡_0(Ãúšä K¬2~ˆœRY«“—cö{ `Ï[[Eºè!ð6À³üõ~ÁãÙlÅ@Ö+åVËÅÝ¿”êËÛAD�EÔf =�˜9r:A§t pòªÍÄ.OÂÍ�, `´ ácë÷ÕƒƯ<�ôÃ’ojÎd< 3eú˜T èå«›®0¨¸@o©}ùdO<‚|*Ä.RaÞä; ?‡®‡r0�áR¯v0¡l~:ÊA–|åg§ÊâÙvp]�ãfHФÁ ääðåTä"¼L< !pé€7¯œ´3,'"|ÃSw GÙ³Y Ÿ£†j!T éZ (o&ܪMu"˜á×"½i®\bV¹“çáÁTè‘"„¿WxrÕ" èkK|®¨~#ò°ÕÁQýL4eƒÇ‘àcÀÉ4yŒ]½WS>²Øf9˜ðÜL±`X-'ªf¹‘[7Þé…G¯~¨[ê•íúø9·¼ÿ±SÊÊF*ž'ªÀhF;ê97¯3'fà¾ÖçǘyÛ¯š)ùôT(i–~­Bß]‚ö0‡|õô ý)tôWÐ=ÐnEâè†tÔZþú÷ÐÁPõ ÎLí/àí”Ŭ”Úã]M-Lèô¼�W°�sz³Z­ù))^£;T°È-Èšà÷ûqß —DÛ×Çqš×�"n×ØØ¨”ÑRh½ÿuKÀ ¤I¯éÕ¯»ç|±Ódw5#~Ð †Àó�F§0<†~õ>S…‰ ^¯Ô† ý.T?½óä+ âE Eä˜í�;RùÇd¬£¾ǘ\Ü䨳úô04z0¼7¤X •§Ǫ̂BW[€ 0µjà²ÞTƒäyÞd‡¤ªI%ûÇ=XÙ?q!G¦ŽŠq:qœ50ß*ŸZ”#?}½L †�žwÉ–Cy׎z?Qðä‘©HÝž#/¯®~ï—’coK¿qKŸ‘à8ìcbBàâ_¿¤…³í=ã‹z^ÔCïf©v¿N³Æ˜å·ÈJÇ�¶ÖäÃ=Ayþo¬kB®ùH\kÛ¶ö='0ϼרì1{¬„äfÒG"óÿør ²—…åk?ãÃR+¡+=Â8±axÝü ù�7£O'9{%¬B#y?õ^!èص¶t¿\Úý x<}€ìpn`N±‹nr3ÀÎÃÍA'žxÏ_Mpq®TV¯ˆÀé¥Ãð:–C„lxBÜ> žNó²d›dÀë�¿ñéÎ7,c¹Xâ—‘ýnãþúæÞR¼« ¡ÏB_†rÕ*v¡ñ¡‡‹õ[ý&t)Tà¨ôï‚ôÙ»sdámtjb4IŸ\‹ WÁ'kêÀýä‡)~$ÀnÚÝÏ]Ž ‡ADzNŽL«L�‰Xž%Úð{CoµŒi�ÎwÁžµŠü@Ó™‹^9qœL…nµ�SYÓ ^˜Atèì«©l©­õ‘¼ÏÒ°h“  ©žÛ烟-C) ÁõOAû7¼õy¸*‹ ·(_ØxÕ¾ò¶å—†\câÉN€€«6UÈþcvÉN�žÌñŒp»klÕÝ_ÀoO 2gK ä—ï<2™H_ûâHƒG™(8Ò'È´Ÿç:M_B ²¯¦wƧ  ¡k¡¯CwAé‘aHï°Zþú4”ï•äÚ'Ê€¬û$Ã6Ÿq©õ¾ÀSÃwà î�€‹ $·Ýv›äæÒa›â>ÑA¤´´4õžÁ¤æ¿ ¢ðw˜âg¾ÀuÉãñHuuµ”——‹ÛíV –^6/p± *A.`T}–Õ\X6�G°‹uâ{ŸÏg‚ªï¸=÷g9ú1øYÏýy,Ö�ûêÛëåòU/—Ûq_};Ö“¿ëçæõzÕ1ù�¦ú“F««‚ïSÕAZÿÇ�ÆáЖžFú•ãÞúï|å£ì)èãÐc‘Ïx1¤'X »Á=ÁF4 °±ꨂe'Qï§éc3eáôLYñ±¶à‚;ÿ{Ÿ8eâÈ>ѾZ5wô¯w!ÃÓÚ�r g&]ïovÊxIe¦£3W#Zí@íùçyd‘CvóȹË$¯‘‹»~¢‘�Û2љŠ>x>$‡ÎåÀ9®.´ç(‰Ý–„á m£ÇÑæ£±ú�¸¬ÖŽeÏi½lù¸^˜š¡oŸ^`•߬‰-oÝò·ýsMòÈ|+Â%€ýÓŸ€ïÏEÚ…@S18”ìpÖ¹•Z.%9ß¼ø2ˆÕI¶>g\öˆÙ·]/–ã—0y�.KÑÁ¤êq•4�á.ô*˜¯ƒGgË<„°E=�xÖI � Å ] (ÊͲÉ=ó²åÉ»³¤/€&è·.®=ÃûÀ‹„B›6¢é‚óŠŒèÿÔ "�A�%»U˜Õg 4�µÈ†×ËT�!w´Fâ„›GôúÈ{ÏÔ \�÷ÒY�SŸÈtú‚G Kà ±:x÷2ÃÜõBåX;ô33l’‡p¸~Ì4G¦TŸi2¡rýòS¤atyàd£÷b*²²êéÃûcW£·{–{˜«OÆ¿X€×–¦Ü¶¿FVoôK°a*Âí†v¼�ݺëg†N¥ØúË œOaQÒƒgaš$@Þø¼˜ªAÆDd¸%_Êë·IUý>„Ÿ+Œ‰‹ô‚ý"ôaèèÐ P.ØroCz¦è½ö¯Ð{¡|ž«0»¾ŽùÒÇqÂìrpñpùô{¿óžhD¸�¯á*úÈ dçdËwÜ!ýû÷çîQᩳ¾œ2lØ0ÐèàU|¹:x¥oËÏúûøíZz¯�=ãiJ€ˆï¹¿^F|yúwñe5?Oý3�­ë 'ØE@�Ç¥644¨]X�K°‹Ûñ{‚T555RQAž-Ͷö¨õõõ&€s©®wÈ–~�/©' ×¯pK{ß%ÍÚH9iÅ÷2 p–ÌøZ4~ŸHD¼l®CÖív©Ì8 Û~Ä)GÏf«0!®ÜªíѬI@ÌIõ_ô¨ôi€P[{eùíð~Š„¨�Ûñ�\àUõÔ²\ù�?xá òñÂ]2)k�|ç+ËäÇïøä\I¬CúÇcýv&¡›ïg–£-$×øDïO<ÐðŒyt¾¥ÍDâïîÈo¾“*¯o `e¼íÕ+À:ÝS‹­rûD‹¬Û�­ÇÂ2ÿ;d¶õcüòÆ*§\."}SðŒgDZs‡J5vJªpm,¦T€̾E‰\«øK†mRl}ePör±§Žµt …X„ °å •IèƒÐ»¡G oCÚs Ú±•BìhHR,ÀëôÏЩP>ÓÄgãÚÞ'93U˜ûJÕYÇßø¥!P&^ðƒ´t8J ’è Mk ˆêÛÑÄ—Ã}õ°¾æß³î½¾ú¾{)¬§~Î|¥èŸùžÀQNNßFEߎ_€bú+*=|‘ïé=E`êìÙ³RUU¥>G ºþŽÐ8sÚÝ�Ì€ðÎ�a�ÄÞ‰=┌JtÂì‚5ð o<�°tÌйw¶CVlàüa» ð^³Ã)ÓÆð9ŽwLK“‰K9Ž,;>¬ô®Üê”;APžÑ ï'Uîmi2wr–l?ìoŽG†ØKÀc®©Ù6ùÙûÀ«I×¾#‰÷…ÒØÓ‹ì@ª'í�õwã‘]ŽžGñÛ]¯–N,¸m9TÞK¯l¼ñ˜&ÓÉ'YeÑT‹¬FØÞŸýÔ'O„Zz›$ša¹m¤YöÃ#ŒÂzt•Œb’¿~Ì&ôúz&.sÞÖc-ÌÞ»ªR ;&™p 6si£\ÜùŒT^܈; lt‚Ïã|LX˜--´Ë ©¼ŸÕ�»eV£ø‚èeEpxç!¯¼¶HÐHâÈqÓ”Ü>5KFf½©c"žN¸,\Ð""Ãý¹ma©_Öï§Ó¾:¤g×8�âÆW\^ ýt/”�1vããCAàŸ…>Õ9�"èbíÚ�‘)Ÿ^’-·O�'x�”íZ»uq±É§ Þ[àm–eâ%�qõ ði뙾'û¤|Jò ©æ&xU@®u4|þmuðj*­ØtÉ-ÇN»åÈ™zOõø®èÀ&´-´ ºÖ© +Ìñû0x2�Ef¹ #3e ž¥ôjêO¦,d$´°×n%L±2øVÝ–Ñ/#?ÆmÛÚx× Œ/­1É+ÖÊŽý·K» ^ƒÇ1Âí:cÖ.ÛW×;Ú� �vnú4ÉH ššsÈ�W(uÞsÒÐú‡pˆó&êè èW oA_…ž‡ö†çªyÓJÎŒ!ó߆€r8¯¶Á2(÷A„ZþöÎ0®ë:Óƒ2(ƒN€½‰M$Å"R¢HQ�ê]vǽ—Ä)»Ù”Ín²kÇÉ:î%î‘mYV—¬Buv±ˆ«Ø;H€Ñ{Ûï¿3€ €Q8—üñÞ¼zß­çþ÷œsݼK3éÔFYQ{9(8[*%\;(œÒsÃÃ…Î…_×Þ¾Úv�Ð ¿Æ;®cáûá×ôÆ~°/ ’HÞûu¬5ôM‚<‘JÒˆ±$ˆl*))‘v“;'3DiA‰tÒ1iNi_÷µ4šÉòW|¨þíÇ�¬ú­m¹ÌÑH赈�O½–ô}òŪ rìæÛJLç¢)%KY^ýM Ëñ·–uÞ°³ ß&©6n8K’zNj‘~3ð'q»�„´ŸŽ”c2Wew\—Øuí'ž›ì÷Ù£·¥ØVÐ,ýoßüg+¨l”ÝåâØD,|ë3qvÄÒ~ˆ?ª�ãpiŒ<÷nˆröÄhÓªv� Ï®­·ï}1Î9o�0JIdôŒsò[¯�¶·qØýùïW7™Ò=‡'­b'ß]³&4“O�‰Ã¥^[„¿­¡˜ªÿ×l±§�u©ÏíÝûé\™±Ñ:"åûíÄû?·ã;ÿ`5å-ü:Å3°_8+ÕÅLkòè8§áJ@wƒ5Àpí>RmÏa"»v 8ƒ_O“Iþ¦®eõºК}5¦"Uˆ˜ œŠ†t©¡Kÿà`¤S¹­ÛVfù¬¢¦é¤äÉ´ü¼ 4ËÔ²Ðs J¡�"œD$ˆËÜn”b”@»ªÎ’YÁ0"ž)EÚ2[UÆZÖ®<–[e{èßöc:w§àGX 6÷L%~€ê¨+A­&zM|PèÑzNJÈù÷Ø‘‰Îñ÷8VL5ÄïV˜“É\ 1ò“ò£ÕåÄV‡2Gåð¼N·'í§È•wFõº²Æg/Bæ¿‚+‚¸úk1�×<�½ò’dÀ~±Hª¸˜ ËŒ¾Î2æXu ߊ+wڹʭȠø6m¬SŸ!hââ€{ÁOÁ3@Α#áò§€úó÷°«fFò4’r—ÅLj‹¢77©º$,È<_��Oò÷¤œyXØE=¶{^ÛzSøñðý‹H؃="I‡Â÷½xh™ŠPa$âHd’G"yÄ’¶"“<¿Q"¡¼çé=áÏÓo‚H¦3à88öK'Á1 ‚Il¡dPA¢¶ÛØFBL�ùÔ3¥£¤Êê4Ÿ‡2¡ê€L߯C2-˜–äëܹLp6—Û„ÒDn’“¢%ðŽNǼí§×0ÓY4+Á î­ñæ;/¼§�ßôññø¤I¶××Ùé“'ìGÿñ÷6ç#ÓÌŸ<¬Å ÿÂOê¾³ú–£gl0þ_äcÉ#ŸÚzÃÔÑQöä*µ‰òÍ$ÿUwÍ�¶Öµ¼7€f•|BÝɹU;ê1¯«·¦FÛï´¤ähýߟ®5ù úò½˜ôpÐ |៭g¥A�d:UØhÿX�í9®Y�Ž@�?>D:A¤UµS»þ`'¶=Á*Œ‡ÑhÎ’) Òš:!ɽ9Í®›îÇ玜),í‘Ým Œdò“w¦Îþˆ#ð××—8Gà"‹½xÉùðƒ7á, ÅÔÄ éŸH)nuæy"�¶ìª²—×Û¦ÝVŽ�7ÝVo%l¿¯9¿¸jõré"Âå#@>�$¤ªRè8B•áƒ,Îæ_°%³“ÐÞŒ³dÒǵÁäÓe.èZÝè#¯+ªmN­­ÝVa+7;îÓ ¤UŒ0Ñ;ížâné ôÍr^‘­È$@´�Ï K„c«ÕWx�†“'eùñ35Ô�2[»¹Ð6}Pl‡!œJËkÑh sNE «+.õââ¢ñÍoW¡E7ÇîS!6'ŽN´!Ùq–éç|2Éû7D“Ëþh«_ÁªÊ—Ðæ Ï’ÿ|׊8V¾“枯,u_êÃÞÙXd¿á´•O¶¡ j#«Ûõx–ôÞ ÈW+™lòû†XvÌ`KO¼ÖJköÙ¹²í8/? ºZ]�\þÌ m°U±‰„žOå�LçÿLÊ&€˜éy%è»ÂCøoiy)ˆ äùn’¶’4”D ú-‚ID“§ÁämuNðžá‘Iznø¾~· µt¶¥ä�äJK"™ä,\8 €„mׇmÛÉQ®ˆ„>™ò©OfK¯FªIóI&;N�¦�’˜[¯Kµw6•2«+r¡Ñí߇”A©¾&­ Ye¦FÛí ’ù¤�íN«nߟÆÊyñÎ ¨«_ç�mtKÒ¯ÙVÊ ¸ÞJòØé}/ؘ9_ƒêîÙñ¯ö7]üÎp'â�½Ug?[¦™î Õ°L䔯í� O¯®³¯"Î^Ú€Ã>ÒRļ>Æî».ÚÖ쪷¯ü¸Ú­ˆ÷­ÏÆYó<³ÑpZ·GírsÈE#kxfËΦùl÷íýÇY% _S?z©Ö^Ãaºvëïý‚H'Ò¯1ƪJŽÚÉ]OYîö'¬´à¤y2±SŸ=<;ÞZ’f·ÌM²A)!¿N=Ì:)jZò»°¤Á­<÷Š"Ë9òÉD&¸xeÅÛ}�N·±(@VdÇ]‘5"Ëd´}•½´ºŸnhJQ¿<Ò*”�ž¦Óñû ’ºwí]C»ÈFx| L-H§¬t¿Ýˆ£õ;ðm7~dŒ#bTb[g›ä5'–‘àZÔæLq�m;Xm« œ>8\e¥e,›"úÒÐ�}u¾Î¤FÏÃúN�P.ò) (Å£ù4$SŽw#ÁK�pÒï"|3í>Paï¬+°—–Ÿ±V2¬¬!ë ÑÞ]ÞVÎÀclh–ß&� 8Gî3''C<±j,Çd~.S=×B«\�ð®¬é¯WN¼­÷ÈȶÇS@å_õ[Úf•hVoÃ?×úmEî÷d&´Ø@zJŒíØWj?x,ÏrŽ�³!ÉóÐfM2T‘<ëñ<êÕ¸ü frlL¦eD_ïV7,«= µÉŠ*ö#ŸUK ŠacÀ¿€÷@è'‰f¿ C‰ù_‚Oiõºn:É?ƦÝn)ñ"ˆãh^C•ô‚umöÚ“ŒSÄ}4Zbb’efföòÉÓLò¶|„ áãm=ó7ýA$ÒH[A“VÞÓ |ú-rIL2…“¦’îÕ} ­·î`Øñàï(&X|LtÅàŽ„EY2âœ?ÜmX±”ÓÖi Ê\•3gF§ �Œ©‘•.Ôm^0÷8 ý$"äS?ɨËMUì*ï]ÎÌF?8ª�Ø´ñ±6�Y[9OUÛ“—_mï¼Wn]šBÇ«[C�¦ÿÆ™h?-÷ÛɳbÇÑÂ(µÙS‚ƒœ°+½;:´•ÕÉcý6z€ÙÇb§m"`è”[lb&€kÈ:ô¬Î^4k¼Ïþæá8ˆžFÌç°W½ªLÆFéI,‹RÒ� []rìL£:Ù`wÌaå"V§ñ¤ý¾ùT�m?Òœ’?}U�ú¨§›�y�*'GEPàR„NÕ;ÚýÛ•h`�ÅÿUqùùqèþ·]Ž'’h”å(¸ŠjV­;µçIV±{ÜJÏîmA:)&ÉI±v;äŃKRlÌP¸ nu©4º@ÔB®J¡Ñ¸ßOÛö–¹FIšQËÞ-±›ç%YvšÔUƒ÷©o>(ÖnÂgÊ^QÓhïí.cyéTgÎâ­�zM§6ZþýîRí]üÐTU×[Ñé]–è1ý³õMb}§žÙÖÅŒ+š´¹t^κeÚ¶i¿–ÂnëŽö�‰ôÑ ?$³´agt¯L×¾pnß.÷@IDATW ïo°_¾Vk_¹�YØdäSó„Ú¡“–€+ÈÕD†�ÝA>©ÓY<݇9ŸÏ~þZ3›%ŸVë÷Öt:}Úøì>pH�{,t±�ÙûG;öÞZÑ©�N¤yHÓI‘” ùÓ“íÞÅ©6S+¡áX&vAÕ†žû ç?«! hUöì;ÅÎ[5Ë´{~�4ÓtÃÌT{äfV°$Vˆ–�²ëùtÚνo@ ¿»½ÜŠÐÚÑà:,ˆdzü ÈÌNíB �ˆ¦úåóáÓ@B©ŽlQÙ”æwmÓÒùɘ ‡H'eY‹Ïç‚®ç?Ú.��söÌòBV ¬td»®÷ê´È¬T­™“MÏ�3ÙßîªxîÁ½÷ ;hr§80-Ôjwá¤JïEíò¿Ù ñd°´OŸ­µ·Þ=gϽyƶ|PH�ÐlpKbQ³·ãF&ÙÜkRmþŒT›>)Ɇb>'ÁZ« ú0Ÿ‹‚�P!tW®´ßFùrDþ\¶P6(¯cèà%—œ-bt°ÂVo*¶-íµ…œóêvíª•3yTˆ�§˜+Û b›l¼‹.ÛD^ÔgR@í?ÿ¢}ñø„škI±#,¯ä-+,ÿ€þÁiAÍ ®ßßO€ˆ(¡›̯} |H“78™“lY) -3ézÌìR\þ¸¼m/SVÛXÈäÃ!ê~PÔ6l‹<Äö*ñä‘LÚŠ É$"©°°ÐŠ‹‹�V’¶¥¥¥Žp’Iœg Gº¸{ÚÚꘂG0i_m£$OÐJȃ3ãÐþJDÖ�Â÷n�¢�F·|š& YiÑ?¤R¼H(ä_õƒpQŽ˜ NÚë‰×ÿ9¿‰aí+/ÑŸäK%R$\b DȧKLÀv»šhĬ`cQ�Ãñ°q¶Õ#¹ÍŸ�T’íDÃBrWËF/{·Ì>}�|û…Zx6¬-{·Ø9g•Vù ™5™ÐM›p+´ÉßT3ön LÜt® ¿>[·WÙ«ÔËÍ{ñéTÔ苦êÿ2ð °ˆálþp~ôá FˆÚáH§l€JÙ2 g‹ñw'ú¤ÑAÒIõ±-ÒI×Kp’¹åÉ‚:{úÍbÚ²"üàÉ‚ÎC ×V‹“sòøº9m—6LíT÷ÃBØÂŽ^ž]i> Ö«$hqn qþM—'½û‘N�õÝGòªìµUöÌk§mçþb«®ÑŠ<ÍY$¢bèà»kQ–-Y�n3qÖŸ�Sp ÚjÔU€Ô¶óIÎ?�v”ßÍ�èÝ�½Bß®,pƒµ˜ì(¿¥¥˜{¦Ú6í(µU› móŽb;šWÎ ¾29Q¾·ŸX*+ÕµåV^�c5 … ¶†�Å‘Ln?Å®�3•ƒ8´l†§ÞG?°³¥›è“+Ô÷Œ_rJ."ê0¸t!•‡\Ááz¾ýÁ�@fŽ.¤àøhÊ­ðO¢ÆÇ6×ÍWQ´ö+vYE�¼46@¨°Äðá—ÍÙ¸>"\£I¤�ÌÞ<-¦‚‚+**j"�d'­%]çAÏ'“ô[A¾@%ƒHvt}—ù|�uüÆv#êt´Ï·±=ø~<Ì‚N‰È±ÿÀmYSXuõ‘[’‘ùchC¦˜XQ»êþ(]CšŸáI¬v2HEí7ýåw,²¨\E„B Û&9Í;Ùì`H ‘hJ5Ž|Rƒ!ßN®¦�p ]f:Rf•¬Ý¬ò#Ýi?­+¶ÛXÍNÚNžŸç¤gä g0é)rZ2ë¹—•ð&Œd…¼–ZMèÈN"ê»oH±�;åªÞŠó¶XÁÑ6xÒCijÉj°#�jóšA¬—‘e‹¦EC>5kö´yq–ÒÄ'3.¹ˆòµ„·³rÝGÇXN~ƒm=Xo¿z³ÎiýÙÍ1˜üÕØç¾Wme�øL_ U¢ºÔi‰ôð}ÃïÞ©sq8ŠYàÀtÃ|dÚD%hÓ�ØúKËÝõÌy+ØI£HšN÷߈ÖÃU�N ª#žÆQO¥…QRq>u®ÞÞ€pzeM &_ÕMõHçFã8úü:Ý4;Ñ2ÑŒSΈxRG_Ëv>�ž_‰–>�*Ñôò3g©<¿<ÒI3QÝSøC/èÁ�H§¥àSàÀ�ÍÂL2*à7ÌH¶»¦ØT´ÀP^q&‘ÍBW‡•w¥7r�mC;ìÉ7p0�æfx›ålj´´œÎ 8_vC0]“€'­·¶žÛ‡j‰4Ÿù‹9Ñ LÃRQ‰wBbX Ô] ÷X°bY£mÛSn/¾sÆ^_uÖ+s}—G:)Ç�‚Pœ•†?°4›9%ÉÕ/¿4C‰ã¶ÊlÊJk{ ¦__þ.eƒú)Ø�Ç ˜KÊŸ ÞkY¥w;Ûr¿~+>ñrYΛóu8»k£¾ªºJó3ÇÁ4@ÛÒè¯k(ÅGÍe$ßI’HhJ„^iÄ K¹ÃüÑiv3¼ªÚBÅ4ðy0üX." rE$´NM&}üœd+§âƒ’ç[Vò"´�déHè¤9,:«h=Û¹Š-ô…AAyĈ–••|^üU_ä‘Mz¼ˆ$9ð–F“ˆ&Aû2ŸtÞó·N6yQÓ$‰äS§‰Uã‹Êgˆvº(—Bx†i³3>‹.mhlÈ/«¬=ËX£<&ÆWRXXsIQNAꦈ~Ÿ ¾q_T<}^´Tæ ^[ém»Òï)î‰ñÄ•‰;ÉZüÊ£%éÍ�„+$"äÓ’ÑüL ]´?AYZfwÒäªbŸ S‚ë®ñ»¥Ú7í ú~:�ï§7Ö—ÛgïSÛbcÑ2H±ï—ZgY®ýµõeöç#CDó¥�ÚÓ€z&ÿi8ÝŠcкÚJËÛñËšx'M%ÍeSËxñÇÊ�Òø¡>Ûq$ظêŽ?®¯³}'0±k>vñ']øŠ“çpú=b#§ía¨»Kføì£7ÇZîÙû:ZWZÍî–Y1ÌÆ`ûôF�}ò6¾{¼ŸO�‹×0œ�Ët¯+aÆ8Ÿ}ùž[±½¾Åj}/®¿ÀqW^Ôk÷Ъ€7ú¬¢à å~ð;ËÛþ¤UšØ…âKG9}bÀ½%ÕfcR•Dç©bæ$º–´úb• ­¨V,gâ[Êì�«ŠíN��?6Þ«Î;;ÃowaŠzçõI6 Dƒ"•¢Ì6ÊöæÔØ+øtZ¹¹ŒAXФ$ìårìø:ø/°ˆÖ줙æ|ÝÁöOÁ| Ò©©OKb¶nÞÔ„7Úiµê ÔÉCyÆ…­ƒÒ’ÿ Êù$x‚ï­÷J­ ¸Öíá×Âiû—ɰñì.ûùÓžÖ›\Ñ齡 ½ÞJ_¥™f�D-Í�L4xâY�±+Bdè{úÅFB¾´IË+X´Äž|å”­ÜX`gðëSs¬ü‘fàè‘»ùº [º0Ãä(|0õI>}@FÒÕSþÈ%¨ÁÖˆÆB#>&k0ﯲø¥Ü¼«ÄrOU¡­ÔȪŸÕÎlN“eíNµ$Ô) Ñ+Áfpˆ”W½ù2�ß8¿§õ UT™H! ="!,¤yÅ¢Z]-&êm+­ÊAVp~ réxðcðkpDBÇR@éö?Áý›×`H‰aÙ©·âT|*•4Ôõ«qètÕ„‰©:N*¯ pâlòäÉ–”äÜHq¬Óô¢è¶­‰&‘Hžsoi0�={Öòóó�“oMò¿äL­Þ-f¬äƒÜ޳=–žá/žå¯ðUÅ¥Öê£ò•Vµú§›´×%ú pð³)¨›Ó5�ìçO¦]ZJ_*ÙC“_¡ ¡È'}Ï¥>>ôÈȦ¯§@“ Þ×#‰ßeK�&ý­€ÕºÍ•U[Jb4©h”3npªìol(að°¡ëAí'5Z8çwZomj?­ØRŠÖR²�Ž?�KÐ~JÅÿ”|«hÅ„Fœæ[eŹ›,}Ä� ¤´qñ�0ûù_`…Bgõ©o7kIK©;‰'ÅD¦sÓǠךÓ4|qÔ€wÑ4H'ÌüÎ!æ~ëÙ® ¶¿ZéN¼ÈòmÁ{žYSgº1ºÓäÓ4Þ+2­+AŽäG0ÿ1ÿjkA>uåY}ë�tжªâ£–·ë–»í ++Òrš:1Åî¿5ËîY<ÈÆâ8\~+”wÊ^G0+ÊÉëË÷UWÖ›4–DÂKÃSû•B$æž®°}‡Ëmûž2Û±¿Ô­°üîÊt’ŠçÚi®—ÜÒFö‰p: V�å` È Ôdx�µê�4œ¾±È'O;‚c‘I�)ì1pºœ0 -ÛL;]ú¶”ÉT•ú¨á@$Ê(ð-pDÂ…SàNÿ#ùËt±4ãlP`¶e§,Áñ¶kÜUò6*ºî¹ph´ª:™ÛE õ999Ž|ÊÎÎv~ŸDt{Aä‘‚Gyǽmk²IZK"•D4I›Id“öå«IÚNzž§Õä=ƒ­DÈ쀽 ¨�:d¥¢6J_\ŸŸ_Ù85¿Ò’µÆgžqǺšºÏ} ûÓ¥ôä íõ«rÙ` '¿“õ��q\*NM{7¿­�HD÷z Dȧ^Ï‚>�`«J´\ÃÚFôt�êμ*ɵŸ^G«é³÷¦Ñ|Óýú’¬Û÷¸è:»gaÂÑ~bYÍü‚·ò�´.%8ÿSSý6nD¼:Ž&HE‘ånÿ�¥�XÀc;Ö†Böì…”Ñà3ÀØe¬Ê×SaÛá{äÆ{zµ'Ïš]?ÙgvKŒ3‡Ó*uƒÓÐR ó1uøT£ýë“’�ƒaÕÎûÄ­±6qx”Èíx\çLôÙ;!Ë{V[[¥ƒ® 'Þ>8Úhÿüx�s¸ÞÖ=ýï˜H'>´Q¤Ó1;µûi;�Ö\éÙ}-V°SZd¦ÆÙíóƒ+Å�ÌŽuÅÊå^Ç“¾KÉ# Íп¿£Ê^XYd›1ùªÆn.$ï8MŒ¹S“íaà™WûMjÑtàn°¬{ KÐ0Ä4ou‘�À¿I+E¨W�f_7!Í…’}4HpŸÆõ_M¤“H­ÆyäöuÓâ!Ƀ¦‡Mä·Mšee ¶nG¹½„­Ý‡+œv„7p Ý#²NZ7Q6âXÕ%*óߎ™rõòIž?šetOÃp–-Ò²• ¦N÷ë á_æu5�µ›v—Û¯ŸÏµe+X>ºÿh¡I�$ü]-¸6Ý>´tˆ-º.Õ†eÅ5)Îö4¹Ü¯·#O³ëzoM"ƒU?UJ+œ™ñúú=‡Êq ^nû0ý?†¨óyG>×¹œä–‹FЫË"ßß'€:Zo Çn‹ hé©N6’Ö“Ìî¤!!s�Hˆ¤Àù)@qá¿?v~ rÛüâµ…”¥Æ$®ÿ È_"úCL4/kHãm__C€«l þAøvºrïZ´»ý®bvPäçí…(LÖñ˜ 8!‡Þ»ví²Ã‡›V¼“TJJŠC °ÄÄD‹��wÇ¥%å9÷ž.²©¼¼ÜMÒh:qâ„3£å‘L­ˆ+µ-2;±´ l@í•X1•]'´ÙÊ­ä„=£?—ô|W�õË%=ªí›}$³&\¾óUT$\A)!Ÿ® Ìîà§6u‚í à4Mb­ï[”ŠÙ[ÐWF âëJÑF Ø0|?UEÉ`¬Õ3C1yb¦-¸¦ÐÞy¯˜ÙÈF[¾¹ÔîÂéïèaøˆ :·æËˆÃ ´[ŠYßOžªdf“eÏ÷¿n£®Ýj)CçÐÀ·T.ÈÄØä‘…1Îaw8¹òŸ¨í–àš#ÖöžÈ§¿~( ac'!ak!põ­Ih Þ8'Ó>vÿP[<7ÍRS¹�:§ú —'T{„&�&~xDÓ&©ŽB,íG«iwˆh:Îïs%5A"žúT"›:[ à¶‘M+À>Àô“#�”õíµ?÷�Ï€¡º¨¶¾_>ùÈ  $ç\èvÝ Wl РÄD'ÙàÀKÀAýÉâ7¬¬ú„ˆK•«ûA6ø?`-è­~�W÷¹0‡ý#¸¨’¹¶"-0âé6KŒ㎸E]í+ºpííL÷§æb*¹ŽÉ˜ g'²H$’§Éäm£édä�\¤Ô�!C)¥UñD(éúp:™×y„SX =Ÿrj“<’é8û§�´,E6Ihï�Iït�šLÒÛ“£¸¦ËÁ±ˆüQûOZÆ(KJôÙ‘p¥¤@„|ºRrºcß©G�ž4‡£šZ 6îÕ…s§øíšIÛ‚5P§ð_^Sj_xh8gchpi\h]üqh#,f¶W4VT×F�F°\¶® Ÿ)²¹„@ãuÓ¬D{yU¼—o‡ò³h±é9¦Æ™½SË.]~|TŽ{2ˆtRy=zªÆÕŸ·e&' È$­ 2qd‚Ý·8ÍÍbYgœþ+J"5Üä•l?~�dš·³Öò –ˆo޳˜Mà?Á«Àp±Û§ƒ„ó…@ƒ¾Û%Ó‘&®tª]I ÄÙÜiIvëÜ$›Žy¯sœÍñöòK÷(½4ãVF| §WY©ó½�åÔIÒ,”Þ¼Gá(øx¥è d“ÒÓµkÚv$ˆÐP^…‚öš©(ïèåÙbhlô*i•¤§ÆÚðÁq®Œ_ž×÷Ü[4(�O§2L¯Ù"ŸN'må&­TëLÃÕ?%°BåÜkÒíÓ·[¤YZ*âÇ�pÝœ?=É+øÉT;×#7Mü®¥R”B®Ÿ)¨µ£Ç«l/šL{•Ùþ£åv“Wµ�5†jËøÖ¦u$%¥á™ö€U`%á¤AŸê_Gê Zæ[Á_�k�k©ÅPÊìN+b¹† 'Fg¼,F ˆ�PÑIM˜j±¾€å–,cáÌûk5 pø1øP_S ®ä ~þcà/À 9-ÖLìnÀÔniÈ ®n5*ÝÖncK�õ×à”¥–ìŸhEÕ;É£ƒX%@2£áÌCÅ$ä“Iær"LNŸ_¤¦@R"™Q¤M‹Èq*HËMÔ›ÁAàµGÁqWPÎàp¯†¦ˆ;ÙEÍÑi:Ø Q“‹|­‰?zô诠iv=éö‡Ž‚î|�‹„¾–ò©¯åHïÇGvÆÌbÜ ®�&@�R2ÚO,NÁ×BPû©–»^ßPa‹æÖÚ„1 �ñ¹ Ûq>eRFÃÜk�+7EËáç;›Kì´¤Æ�èºï'ÅA>¦îX�b¿x õ5–·û%>ýã6rÂuVTÖ<‘ôÆûõ6fp”½¼¡#2g÷f´1Qö1‰g0“€á‹OÝ‚|’fTGB-]”¢?Š ßw_pãàvoD7®•ó¾ú“ætÐÅê#O÷±"Z”=÷nsz¼DÚÈ‘x{ƒ÷v_ÔWOð¡è§XMU¡�Þ÷¼ålþ¥ŸÚÁ@òQ…‡ ´HK޳g%¹rtõ˜8Tä‘8Ýžéîú\™;Ƀ‰|3½±¡ÜÞZ_l§Ï5ûf’‹�Ù ·©v뜜�¶/WŽi1iÞœÃÄnÙ»¥öâòBœÊ7›q‰>P3il4»p�á‚>$lÞ> D:iÖÓiê°uù%ë7°Šæ­×%ÛU#c,}$¥‰#xÚh¯”Çðwœ�²Üü:Û¸«­²2Û{´ÊJËëšH>=Ÿ A«TÞ¿^J3=U}%ô†“Ã:NXð^1ùar¨ž%A³7‚ûñz±ü= ÉŠÇ¡v\gõ½ïvßéH'êIe5>�Ь}ìyH§ g1ÅÂIÅ>þà0ü:eÚ¾YÇ]žh'º=œe_æjã䣩L¦sù5˜ÉWØ^4šö �yðXG˜Î±‚3-¦"kàv¢Iíšl'ÀQ@î»6Bƒ»c Èqø kÎOËSÍDgÂ|.þ*¸øbc’cn“e©‰ÓBZOÁ~¤3�\{%¦@°Hð�±QéÛIßv®¼ÉÔDRäÿ�«À�@¸Ò‚ú×›�êÛb ¾Ê…dœŠN½ͤinÑuÇ´-®]Ó]ÖŠ³€ÿjV1žˆ¶Z‰UÖæYyõ1«¬;~–‰ Æ: •È�Ïô"˜¤Ùt‘ðç5‘µ¨-Rÿ/ôÕÆÃ‹[c-ªøZÁ× ^lº%ðɶñe’Í*++m÷îݦ݄çO4�„œªð‘I�ðð×°†Ÿh½ÏªôηÊuÓRÌi¦ÑòÏUÙ^+°¿û\¶Ó2ЀP-¬?.Æ÷ÀMƒmãÎRL"˜íDËãÝûÚ‡3[?¶S¿µ¸ÝÍh>¼¶.ÞNœFû©ìŒ}íþ»—aë~egŠ‚-¦H›½¤O»|áªQöqÌë§GÙ+êlÅŽçXüË£qòÛõx¼ò^½ý×_Ç8-¥‚ hª~åÞX{iC�µ¾f«ßý·‡Eúa°£#—�ã÷E&vÑ�‘µvæÈ+vtãO¬àØjçH\~:$»¤¤Ä¢9°»nL±«Xµ ­iÇIõ4ù&³ Èò B^ßPfo®/±“¬º¾‚]Vºßn_�jw_Ÿhò7¥rî‘+žO(™Ø=ýv±mÇÑ®|D¹Á´û:'à<Ï®”Ý@ª~Ý%:ð¨ "�4 üy@ímI:i¦l0dÉb‘„,4 “]?uHÊJ-–¸3$ØH«LÚ�ûOÔ@x—ÛÚmev’Õ9eªØJfC»ü¼4€mÝ`¨Ø¸¤5¼_ÚÄ»¼ón ò‡º©'Î)}G€Ñzx«5ŽC›.%@õõ’¡·¤Á&‚xëÞ ûåÓ'ì••øt±¾gÊ-M§™“Óì�Û²íÎE6v8¾jÃêQ�ŒêB ˆhRýtíûÌ-AêJ£©Æã£Iþ™ä§IMÇOB4á콚‹dŠzÓ9‰å HkigÙŠd’§W'Õ°«${[Ý+tµtOæÞ/€›A´?6­ˆ--q&ßš™íwmx—ŸÎC#á L&½âbÛð´�7Òílñz«©/£Ur‹@|�­ˆ¨2Çê“EDó’‚ê¯HÞ/�»€Ôšœtí·Ì¤9h<±r`·8çÉ ÁæB+ Dz6G¬/ÝRüS�­˜Ìh¬øƒÄì¶¾Qn �»ê iïŠ!¦JhËÄ—4(?!Òƒã¡Ðë”—j»B’vèhÜ CFáÊ*—W.HN’\ÙÕF´­OT?Q['?¥Á³!éÛM2ªÍŽ„+ .a|¤Î•ù‰j\³à©‘¶› 4Zrþ÷§ÚŽƒ˜® E€“'{wë9{k]�ݽ(‹:¨ý$q + Ý0#ÑÞÞXìÚ+XúýîÉ6¿:­Vâj÷•­O¨a‘cw/L±Ÿ=‡ö¾ŸªKraÔmêh?ä“.oÈDWãÏï�µ±C|v(¯Á¾ü#ÌBÃØßCBI*· Ôòv!j•t ¯o®·‡1©ûùk¡·zÎïŠq«|ÉÁ¹á 9qs½ÖÕ£qÓhEíLàCù}VŠYÝ‘M?Æ¡øsV[…Y(+"z!%)ÆÎJF£(ŦPö¤þ{9Ìë¤é¤�Ú©Âz{‡Õ–­-±ã¦餸¥bYÁ.`÷CˆMÙìoJŠZr \ã»ûH5ŽÈ‹mµLì*›}Bq»„Õõà{àM”†ØéÃABÇ<ðyp7ÐŒ§Ž¹ ²‘ƒ âRlɬÌÄ´ªŸV"ƒ^'�§íÄî%ª¹ãa&}ªøíÄüßuáÛ“8= dè²dêÀäqIn¥;¥S ê—$Àž>[‹yÝ)ûõs¹8ž®hòé”Bºåú,ûÐ�ƒíº™ËJ�sŸç¾²7R¾?%î⪶Ku˵cb›HPùz”FÓY46�åVÙLYw,µý˜ÐiµHÏt®DS.Q8>»ÀAph4§z©ÁÔ“99„çÜüÒvÊde­ŒÄy´+RÄì_õ…GB_J:óØèXêü@�*YaÕyôi j¨îCÁ?�Õ D°7°‚ŸÏéô1 ~?4õû) £,;y ÖSQ7¶ßŽf¾\UϽ'ô2šº(4ècˆ^Lc²ù¥FM€¦%9‘jêò-§ðGF…&¨Îpé:Ч4yŸ¢þå/&$çç•�,*o˜TPR3òðɺÁÙéuƒª§óe㈳¯F«†ª¥í†tW—!'˜t]¾¹ÂvabÝjÜ'‚NbµÌói‘à¥@„|òR"²U ¨‰ijj$h^,ˆÐ˜1ÁowÜ�jϼYÀÍuVEÓñÇ'lþŒŒ .ågUˆ{1!Z·£Ì*40Ký2>Wþj”]ìUmŸçýQ DnŸ—do¾—`Z çïþîoí»¿zÛ²¯ÿnð¤"yí³¢ÝŠqI,ñ~ÝÕÑvûì{e£äe˜¨ÈYø·?ÇÊJtg¿}§™éL_\Wg?ý ¿ýaeþjZÞùè�Ñv/þ­þôß«ìÚ >ûì1öÔ*üíÍòº�¬éä‹�h:gÇvó§à P4PëËA‚æLð9 A^:h>ÃI§[ç&ÚpÌkeô&®•/n µW"�ª Svª¶×Ѭ\éT„¦…7ƒç]ËV´«„Â߃·€Ìs”fÝÚX¨¾×Õˆ(kz¬*¡¯Ë4j¾Pš05M‰³I�OÍÑÒѾéDË% »ÌÄë‚Ä“ì�#e©E‚E~t>DXDEÅXzÂÌ8³íTÉÛVT±—ºS­1Ùð-ð?ÀJ0�ã |Ï-à` h1Ù”àϲAIs-ÄùÒ8MC¤vIu®·êÝyïåqòG¡–m,Üш•AÅ{´“§9§&ÎÉ"U.·À-rONê÷�l ¾? ŒKðG�OHÌ™œëU[W�5Jtý(‹ô!e989A®T¤IìeçºbpQÁ" ¶–›”Μ“¦‹Gåðëk`/hJ¼WD~ ¨ˆ�O*;»åc¼6ÕÍrv„€Š¦=„ï§�,Užƒão œ‡�Ûò÷ÎØ£K‡YM�–$¦ùB-uúø8´Ÿ’í­ EN •öƽ NË£ Þá�‘%•üáu8qûü…2±C†$.<¾Æ®ý–å^éÄLJF>ò�tíäd{ôæT›uu¼ÅÇqŠë{Ú¼N½w4ï..o@K©Ü^XUl‡¬©œ{ƒ~·òÖÌdH٠錗ˆ'M°iÀ�“_ aUjom,µ³øu «'ª«"š¿¼õuAU}Î4ðð�`DŽƒG:-EÓéÖy‰6L¤“'赬FÞ-®�AWI5Ú¶¿Ê^ƒ˜ØÈ vŽt"›´àJ¯·�„B‘O誵ºŒ#íÉb ÛªÈï0Í'UöÎWø½í‚I�¨+äiè ¿�â'Å.xsoŸtË2‰ýÿõ|ž=½ì¤åcª*61>GâiöÙGGØm7`&‘äs*ýõªÿ�ÉÕÞþÈËð~‘Jê‹UÏO»Y&×UôÓe8—Y\~a­åA2�F)m’ãÇÙ ä˜ø2f‹O=ŸWÜñY8ÚF¤=ÄdØJ;SòžÌºD¨�üðßÁÐ}¯í¶0˜'Ýþ\ÔIpÁ—fƒg[z`.šEÙj¡‚'ÔÓöÅ6¼UœÔ¦ž+ß`gK¶ Û5‰`‰ý/€´6»#(QD(‰ džÜÉM±lEà‰\ &€¡€ËAé,HÆRj:Ð~ÇT×ÔG)â|‹÷9jó´jŸüXW铬ê�åîN†`?e‡ójÑ@/eåÒ H¨6›øßóh•óæÁL'ß¹¼¥@Såï_юĶS Ó-�ò#ÇØ£·¤Ûwž8å„КÚ([¶ò¤-ž�f™i´{,Kì«/±JÜ=˜È­Ý&ßOõv Ž××—ÙWGf\Ú'Ñ,/¾6Ñ^Y›hà×UcÒ´éç–9z1äïW${(˜Ëù“Å1–�eÿúd³Œ°aoƒ m…ª³G!ˆþ÷Gãì_>k?y¹ÎN‡üSµu}[Çä,ü;Ÿ�³gÖÔabgöe|< ˈ²¿ùE�#žtÏ ´�êp°½fWÛñhë¹ýç˜Q±VUžg'¶üÂŽâP\>¿<;u|c†%Ú÷¤ÚʆVCS?ÚÓ¤“zw‘NÕh¼¼‹_¦çß)¶­8寕Ÿ“P6ÈÍ‚é˜þݘl3& 1�4@Ô`û\I=DJ™½º¦f̉Hi®�P˜nõº³U§M‰êÕ�¯¿`�@}5øø�0*ÁIÉåÂóР„t’¦Ó  θÏmþf]ÚDŒ‹ “Ië¶U¶Œ•67î.Çyqp庰۴{ ¼ [�éÎ:Ч W6’?r qÑ ’Q+v…ü)zgs#qÑ'tËJ{‘|£õ´¿ÏF K`µ;ü¢õñfAÚ7rZ�®ÖžóŒ=ö\¦]¥A;RSŽÓ'Ž ØMó3lPzŒ×±zN„”Ïq" <ÇãúveÀ•ɤ´£ŒzÄ�G0•–¡uŒ êiˆ¤ÜÓ5v-L!�6æ „žHÛ2Lè¥a&RÉ3Ivm'´m'èL9ÈûÁ`Whÿ[M*û*u½M4…ó‚Ì?fƒ¨DÿPËJ¾>¸¬»j~ûßÍÉHˆ¤@S€F8.&݆$ßI]M´SE«éëKÕfÏÿþì}¼µ&†-ƒ}ÃR°ŒHªÍ¤S|\&æ¬× é$ °!PNZT…ŠæÕ·~Pçç’êÝ–‡ùdãœPÈgû pt&ß|¹”Êv ƃ1@¿•¦:' 2•Ai*YJ‰RNÇ´õ~³Û|t "˜XeŽñÆ„¡ýŒŒ 1b„%&&Ú† ìĉ®­W{ß•lФoiE#–.å¶|S‰ës†Ãy<ïËÍÍE)A"kSè‹ýASä";ÝŸ*è‘I�Ö)àÚµ^ ,$eKæ&ØÛ›“lû¾r'´æœÂÄhåûÜ™ŽQ¦§¦¢ý4zÀVl*vƒ²h?Ý}C2DA¬›Éîè;Ã¯Ó jPZ´Ý‡Yß·¯pÄÙ£«ìì¡7mð¤‡xoÏj?-��â-—ÈŸ¼skª+˜ ùûÇjìÑ…Ñöý/ÆÙkøqzsº’¦þ+ü Ïß?UØh;�6ØÿüH¬Mæs¾eR™ $DYaY0ü®ÚÙ™¾ïü÷ô½#Òv‚HÂ=ÿðvøÝÿ°‚œw�Cq¯›LIе;®O±‡–$;‡ÝJ §mÔ±¬éò'ÇBM0fC§Ú^\YäVUÉêù'Šgà?ý÷/L¶k&ùñ™&SÄ HRi%*kwT8ÒjßÑòæy\¢iµåàg¡­J‹:î¾$�ŸÃ�7 父¡Ùñ¶t~ŠÝ†¦Óˆ,œ«s‡à¶“WŒ©Ý Z~dö¯µ—!çV£Î­As˜)"¯q2Ó¶/‚ÇÀv ‰Gqš �õ …Äï¶‚šCزIƒz~) :­�»HH§…Bõ®Ž¼ïB�îì9}ç  gãÑ6vT"¦�´heõÅ X±|n»�Eö³'OØš÷ Xƒf]^œEìí:Plû—8"*ÿNW�M¶k©c3&%Ûø1¬™‹6TŒ[äADŒòMõ±�NÃs:ß7SÁûʶ·*_J'L*�>ý!ÈT¢Š6§�ú�w¦mË*·ÂœL}s!˜N¡ÁTX\ƒ¿¸:H<õÉAR\í£Ê«Â&wž?*Ã… ûB8Àö8Ðl¿ˆV�ÔîÔŒË/{1þyp ðùcSqv<×9–YMGä²Ç8ò“2Óû¬¤ÅÔÇ;]¼Ž¾Ìi@-á#ÿüo°ôõ¦JĈúÖ»�â>ÈLäH°�b'ÉŸ é4›U#g8­B�tjô´ ûúWò r�QYŸg¹Å¯ÑÏpÄE\ƒ_+�×׋ aÒDÊš€††~k^îtÎÛWß­t“Ì"Qû^:z[5õ "–,W'Brr²KJJrûÚÆãY\Ä“È(‘PÑ8RÔ¾4žt\ÏéJÐmZçP.û¬Ä¼çHýmŒÍ˜y­Í�;×ÊËËmÙ²evîܹðÇ+mºöÂð§DöûM Dȧ~“U—-¢È:#_FYo/ÓÑv?æC;”;!¶¶–%ä×Ùͳý6aDpu5}…–F¿¹õ,w.õ}­Š£U¿¾ô°ÚÝ®`‹®MÀD)Éö2h¯«.³£ïýØ2Fßd1qÉÈ�ú´Ki(¾V#RˬMAft?üc­Ïoì0ñ¼S¾™ÌôÞÞZo�܈ñ¯ùí¥÷ö5ØŽ# N*|  †=;5ʦ�õÙÜI>›5{sº¤?ÿI &xÑ6{¢ÏÒ’¢\\¼w ¨- _ Õ%ÇíØæŸXÎÖßXMEdc0oÕéMŸ˜d½#ÝæL¦s¥…»<¤“´8?†³Õ%¶fk™±|¸G†Äb6ëê€=¸$Åf_-Ò)¨…¥A°z\ÙÄWARlÙVe/®*²M{XM…�µÊG(¨´­?o‘NØõÕ Ai4øhcÙz‚”,kõº¥×A:]\ÑO.n–­ù›¹¥ePY7*úñS¨qÓf¼µ±ÄN�­A`ró¥ÞÅ’Oƒ—ÀoÁû (©§‚ûÀ#@…æàG #ì´úK)ªC~I ~_0(""8Âê°Þ©¸\ΠtÏR×wZAÃÇ9r§/ ‘(ƒì=Za?*מã”ó2]T=Ø”¿7ƒhhBþ†JÊêìx^¥­Øp†:åÃì8Ö²01’gÃ(o#‡ÅÛèá 6†•ï†eû™°ˆ±¤Ähˉ½ÚciŠòT‚ò®·ƒŠ»Ø2ñJA’I…/ئ©}Ð"çð%'“¸cøa:|¢ -¦ ;�³ï“ù5¤[µÓ0Öw©-é$Á¤”P;#’Ié-Ré8�@ä®[ªµ*NÚ*éúBò�…á\õðˆ�‰Žg`<Ó Ž}Ϋpú”}oä¢>˜êÁ¢£â-+q!Z‡…VX¾™¢F}ŽÊ¥È›¯ƒ ÔB±×7‚êÏuà&0L"ZNòŸ–„6¡VŒLO˜Î vY4eÈAú§¿ŸµL�Xmc‘å¾beUh 5óëšäR} ŒšôÉrb%âIý° æÝ5ñlE.ѲŸdP#DR”È$‘KÒP¡$¢HA[KIÁß!d“&�T±œ¨ð^Gr‡ %Á7ÿ¶¾.üÜÅöy�“ƒ×í¬´W˜Ìg!ŠøÄ€-œ?ߦL™Â¤H•mÚ´ÉŠ‹‹éÓ˜xmŽ£*÷í{EäüI5l‘I�ðÐÀÈunjÓ$ðv4ˆü3$†ÁM4¾#ê\_rº Ê^Z]jõ‘ùA!NBð5bmÎÔ€­ÝŠöÇ囤ýÀ|¯ëÚOjû3S¢íA|ûüûcÛõv.g£åíø­�žû—4¶—Þgß~m´}ñî{nm½iå:/¬þ@2w×CA)¬Â²:ûÈç]åƒDж/޶ÌdTWí+ªñmâ�‚´`J¹\þ¤ìØéFûôwªí¿?Ë z>{ì­:ûÙkHÿ—•®D�ÞÉ€”X#e%ÿÈ«vpÍ7­(wkзï)—™g,IÇ¡xûÑÁÁV§…sNŸygà/ãàzÅ¥UàùeÒêXÒþÁ%i¶hfĠω(!&Ò©†÷þ®*û#>¡6혦Ÿ¦ú¸ü¼ Ê€ŽõÕ c,øø0H:r-‰ÑÙƒâíH§[!�Fiõ:¥“¿í·Â™œ_ToËpºþƆRç‡FmG³üâ †¥éô°(­4óºÜnc€È½QþJÀÏÁ…1wæä(’"_ã™3]è&ÅÈcÁ¦OÕ]zCtÁ—žwRi¯™W—"eäà>¥ó®íµªÃHE"-[]`ß{ì˜íÜWâ­b§¼:~~”¯w•/ååÈÐþPÊD¬$|ZX9>ŒNÑí>ÀÃùÍó£ÈA?i�–†™2„Ô„1‰6mbÀ&OHb’$²*3ffƒEHñPµ§n€ä¶­Q…#,´úÙ|&t"X)tXÃ04S}Ð*‰"˜*«Ð†ÅTî,~˜¤¹¤UäŽæ‚¼ ËÃS>Î[K!Ýd&ךd «zz[A¤«Ê¿êM8Úæ„¶§ØjJ_×èZ僠2¬mëàP¿  ~¨½ 9Ÿjƒ p0އ7(îWŸ‰lM1Ñ6$åV´e+�õöÓÔ©ÿ¼ ߯ɽԗÊôk4¸ÌóÀp sSº¦Œ-ã‡Kˆ„ï´ñ–’p5Ïc-.*‰FC—ôOÒIߥOl@©édÉ›VX±¤…H6‹ fµò©DצŽƒÁ ]G‰’’H#mu™g'ò²I¤S ç£ •b!ž¢Âµ–t½à=Ïíð§-r©­cÞõÚ꼞%­)ï™áçÛÛ×ëÕ_æ3²|SnUJœÿ@}ÓÂ… íª«®rO«V­²C‡9¿Œ“Fa%sú{‚4Â"á J5‘I�ðð„JG<Ѭq®cò¥Ýx´Åà‡Ã š‘^±¹Ôî\�l“ÇÆ5 Ê1?ºí§÷>(uö)|M¼�&Ãçèí§ öΔdž]bõµvø½¡ý´Ø’³g"œkâ¼ëáx¾ìóé}5‡ÑA¦x+w48èñ"ÿ¤i\ÅK&yÓFû쟌³!�öó×ëìi|>}í�X{s‹²n uƱøsʳ£›~l9[~i5å…t”Áï•mùòûcw¦Û4L:¥AãÈ�L &Q°­ÇÎÔÚ2T‹[;W¾ Çѽ¬¬w++1ÉÄb‹úábÌ6†û¥)µ_E/®,±wÝ �uMZD]=òQðSðÈž 7»}.HȺ h÷ šH' 'Yé~»en $s’�ÒL:]ˆ,•æZ#é|º€Õ·TØ›8?Œ†‡Ú•Vy\Äûþ~ 6Iƒ"\n�``Dé56NÇö/�„ù§@{•H aŒ²Nßâ™oq¬ýÀuA�»šÛP1Öí½£ýg]ÚÅ]pA HϾ$èF3ÐÏÁLìWOçÙož?a8×­5ï\?`» xõà¿ØW¹ÓÇH»Kƒ¢©@ƒ! &€ÁÔ»„5Rª9ä%£Š,(.«µ8›v:Á9B*{ôðD›!5q,f C,³½T´zµZ¦|LIÈv�„tå‡rX€ ‡ÔÔT¿ö¯WÆ)?�,« Ô�»+í�÷J™ ©r~8õÝ7Þx£Mš4©ñ‹õ “Äq˜ýï>\ëûšËPû/Žœ ) F#")ीZ×™©P›çš½v®…„$I``£‘ ä{âÙåÅö÷Ÿäž§A¸„æ™WÅb‚°õ;KœöÓ[4\wã g(+\I£¡K�çjµ£?½#Õöbk\‚YBŹ;°æ_mÆ¿F{†6îB*a/M‡‹_2#ڞDZ·öo´Ï}Ÿ�úuòîëêVéTȰ8¼SÙv˜ÕÓXéîýƒ οǮc�|'KˆLñÙºÝ.ûºúº>v%J#e¥Á±•¶Ÿ<,8¶ßNÁÎ^esH¦‡âévçõI˜}W¹ê`övé[E:ÉõdA½½Iy}mm‰åaò"M'•XÅi0f>wÌOµÛCš=râˆ.�ÆŒêÕQVÿÐêwË7µ4Ï EJÁgÀ�Á> Áv+wöl�ð9|ˆäZ�NiÉqøƒ ØÝ×'»U-E¼)=T¶Û ÊriŒ±ì¯íÏ©±�N«ß/Åéz•Kg—–Í7Š4ZDÒ­@+N‹Á‡ÀÒ{õ§½™5IPW�b¾Ô¦ó±rB¶;¡oP/ÔÖy~…¸–_ŽxjnP.ö€î;¯wÑ–†Q_ 2³“SðÕhÁ~÷—GYòœÕâÛIIG‘NOu+ái‡ÈëHF6.ߋٯ‘Q"³�Ê$l‚ó­¡}‘�#À`Ì^3(Œþ&³=ú‹§+lÝV¼y�¿J'ùa‹��fpÀJ@TÒSê©^krÆKJ•g§yÄ9ù£óÊiS‡vt\墎kTÆEB©ŒÔ«á⤪…#¯ô“ýúaÒÓUnERç‚cà8Ž€< vE�§{lh«ûô[AûWR¸ž�ý˜¢’ãÇZvÊbKŠ­Œ½òRƒOŽ„¾‘ò;‚UðÄ…pYÞÓù¶Îy×\®­â+*ß¶2JkŒ£¢]ÿ˜sªҩضì-µ ü•êÈ·Æ DMœ8ÑJKKMOGŽáL¾XÓmÞ”xV®¥ûöÊDɵ˕‘÷ô| DȧžOãþöµNmn:ö º1òÉŸll½»D$­Ù^l·íN±ë§ûñ—¤+i 0mÐó›ño#\«ï¬x¿Â>¶4å’œÙH¸Ÿ5)Þ¸)Ý~ûj>‚<+ûìÝr·ÿÖF]ûäû*/jÜ~ë³q64Ãçü'mÚïÉçvÙˆ'EîúÉ>ûÄm1ö|J‰dò¿?£qWsxju�ýÙÍ1�Oâ)Bi;Uœ¶[‰ï®ŸYUÙiò’ÑAålÁŒTû$ãU£5£Äà­9‹º=Ä3h�|³¯w6ã0ñÝb;–$C4�Ôû³¥Ù3/ÙîZ°ÑCqäˆÜ¥sS:Ò‰ûóòë�ÉØkëŠ1j6Ï EXËÀÏÁzà ÙísA}‡H§�ƒGÀP áÔ5J�TH§Å³’ìNV·¼zdœÅâë­�¶ =ÒÉ3e+FdÇÁj{‡RÞßS‰ï¬`:)-Âî�àW@dƒˆ5< Àƒ`)ÂÓh‘Ná�*Í24ˆKÌrrr$ðé¾)à¯�ˆ‰ï âþKp¼MP0 ?ÝÎ>‘ãÑõB–Ô6ãá½×�a’‡Û¼ør”™ü4=ýÚûþo�Ù1ü…|;‰TT¾þØ :Ú°©�TwTŸDÄìÊ;o$¤²+­¸ 0 ˆ|œTž'Be’Mq"¤¼Pê‘T®»%ðèæ§wê‰jøõ]g�%‘KÂp H“IuÁk;TÖåF0ü<Ô´ 9Љ ¢^í ´«D8‰ÜÑ¥w©½lÑòÅD£¥�CëèTH§‘–WçÒU@IDAT?Ámc¢ÒÐ`ÕåjߨDÞ]ªO N±N+Û}`yE¯3Ž N±�=ÚæÍ›×ÂT-\æðö½­Kœ6þ\ì|·të!É42”?¦S§NÑ3#âDª–¯i`EF_tÀù¼]ý~!®S ÐRf…ñ� 3lØ0¥GÔ¸q㬨¨ÈV®\éä,=ïVÜ-,ž©ÅN‚2H˜¥¾Ù+--_ù5 S ØJ ÈO‹|TS@‚j°›èdS Ë£c!•hXZ™<·¼m§l§¦éå\4ë*¿MÃׯVXsi�¬@Ãá|?ƒ«€µ~NGKCå‘›“Y‚½Òv°Ì}}M¹Zÿ]K±ó»Y €%›_8¼´¡Þ¦�i4­*×[aÌà(1ÈgKgÇ@>µ/[ˆûÔíh“�ó™4£úo`hÌÈXšÇÞ·ӷٮnZÉNƒ¿Aiqöá¥v/ÚN�$|;Q˜ZÝöùŒ�éTXÚàÊæËkJìf_*«"9UÒÓRâìf4{î¹!ÅÆãX_.Ndƒ#­øsZ¤ZN¯¢)uüT3iЍ ã›à'` ;ªž¿/j¸L?Îö� $ ºJÌ¿-¾6ÉnÇÔvâV[�(tfBa, ×7I¸[¦uõ˜V@î•:­ÅVâòš¦‹ƒöj~Kè~œz÷ð0¸�f$‚\j¸0§™¼ÌÌL2dˆ#ž¤/aH³”òAÀ¾ž1| Hÿ „]ã‚È›¦ÞÁö¶-›�–¿Ú»§'�“ÖŽ{ÅCB'Ih'1+ûÏ'Nدž=a%%5ªSJŸ@uAÄ¢ò÷Rꂞ'2J!¼¹U�Õ@Ñ!%Vr%Œ"$å,™vFå_r“®ïÎdT£­xª-�S 8 N†m•.ž™œâ.JߤôÑý‚¾·÷Ë‘èÃAfDwƒ¸øØLçã)Õ?…fˆl�¤^κ+,j48>_+/.€€µÜŠœ¨ Ö‡ƒ¿�€W�úÃ#@¬ˆ4€Õ6¨MQûкTKXíšü6-ó€Ú½$ 6NÏo j¯ãÑl øG£Õ4³ÀÁciÌÄ$`‡žÀuÍM¡s®;õÆÖoÕñ~´²]iõ^Ë)ü#Ä‹æ¦�<áOú¬p™£¿|¦òV¤“œ�ïٳǶmÛfgÏžE+·ŽöÐú uÌ¸Ž€pŒñì$¦á¯­9eÛöœsfãJ 9<¿úê«möìÙ–‘‘áH¬+V4O‹g§Ø�¬jœDqÑ„¬&gÃüf¶,Dý%ñ"ñìr Dȧ.'Ý€½±©Ëð¤ëŽö"ü˜(XÖºu�VÊ–}¥¶yoª-º&Þi?©JIô±ÚUò©Ì د´-,S «ÖUktßÅ gg¤EÛ§ïM·ÿõÓªfó»Õ˜ß=(ó;ƺèAä“p¹}€�ÉŽ²#8÷‹ëY QbùŽ‹Çãi´Ÿ>´(ºŸ’O|<.ª1ÖªŠ±’ÝÏìøöÇñí¤•ì‚cGùvšyUÀ>yOëƒÚNžIŠ—^ݵé$©¨¬ÁÖBˆ¼´²Øö+-M|‹VÉZ8#Åî[œbSÇ Ùã‘,”[GZq!ŽáWl)³—YùC¤U ¤UQ&áp3Ð@û%P‚ËN H5+úIpÈ:æ¤N•Ýì ¿Ý<'ÀìKÜ�E8 ‘NíÔc‘NZVóX>þœÞ+ƒœ 3­;¿jjP¾<–�B wÏ�‚;¢Fµ&�$I~äÈ‘–••åÈ&ù^�j¹ÅÉ“'»cû÷ï·êêj=oø ê›`7PPs¨ïõ)ÿÚð9¥kÎ Í5ù¼SWìG‡I*dX‹ŠµH¨¨˜x&ãlÓÞ{cí)gž^Z6++ÒéZ?~¼sš^VVæLíŽ?ŽüÞ`"žîE>@ÉóšØ8äÃ0òIåXe0®�ˆdö’Ñ�øÌ¦®C³û¡¦Ã·Ç0êNJR·Ô$DKp�Òª¯±"ؼ©~78W#¤òæMf ì!~§Rƒ¯9o¾áš„¦kšžÔÉqK³®Š·‡nN·Ç^™ßxƒÕï~o#g} ²Kýrß ȽßýBœ J‰²O粊ä€üímÞØ(x¬½¿«w6Ø'n�µ ÃX}-¯)Û»¼šØÕÕ¢î»û9;ºñÇVrfO‹•ì2püàMivÿâ€[ÑPJ4^'Ö�"ÒHb¡#�Ê�O§]‡+œY¨g.¦ÕçOOÆd4,aQ„²&"LUF>bJÑô[½£Ü^\Q‚m{KÒŠK”¡{ÁÏÁ3à,Ð@´/ ®ç�Ï�;�à:æ‚H§ÁøÝZé´t~²�Òü"-Ú#�<Ã�9ùµöúúr{gc &ˆ!¿Y-‹­ÚgÀëà)°¨f(­$<<ˆ5.D:55<Òh‡›Žk¿+Aïô²¤õ~Wž¹§í�¼«6LƒôѾ¨h&¿®¶ŒÄ¹´ùˆ(¢M¹Ðöý‘£‘èµ�¨¸˜t¸Ãù%+©Þce•‡­¢&Ÿ ‘zõÉB2ÂÛ~¶øíµ_"É›Gã|IÈ3ƒ!ºÆB:�…|rÞ|©§ÙÔBþòZ¯æ§  =­zZo•¬²&ŸïjpšB×^{­�3ÒZÉÙ?‚â*hòM$Ó±cÇlëÖ­–——ÇP�›� ÿ’ú:ŸÕE%£¥”Ș?§ïž¶õÛÎZi…ºE˜Oä&ù»š1c«Çbr‰Uaa¡­[·Î=[ÚåKæ¤8«€dhÿæ2ƒ¦‚ (õ(>"Ÿš ™ :"äÓ€ÎÞ.œëJºÒ¦jðž×Ô†HˆŒãœöÓžRÛu0Í®½*®I dpF f:{|k1¨ÛЍ½GÒlÆÄà5]þ n”jçCKd~WeÛ0í“ùÝ‘õß·ôÑ‹,�1™¤&ž{?T 91—#ãì4ü Tt¾7—‚ɳkëìËbìOöU.#<­éxè£Èó¼uvtÝ÷ìô�׬®–Ž-¤•æV²›šl¶4ݦ£í¤ütÖ[�OžðŸ·N:­ÙVn¯b^·÷XKÒI«sÌ#..Nµk&Åá\Sš=AâIŒ„Ò©ªªÑ6}Pi/à`˾ /3�´â®v¦\¿fû{� T»ùkx⥠²óÁg€lÞ )»|+õ|«ùÝ:/À vI6WÎÜð¤“K#„�üBü^m,³ek‹-×sÖÞ2ÔnìÏ�—Á ­ã¨,:ÒéÏÙ^!ž$¿8¡JKKËi̘1N’¹�çðS×´ÄäJ3vr*•s|èyâï“Á·Á“@ǬB[h°q¨O¥®ÒNå��J£Óໜ1V¢‰x*¯¬·Þ:kßùõ;˜Sîùw*àôo€ÒùP<ûZP¶,¥}-†‘ø\,pÁçÁ •äiƒ’®C[{0¿ÈÚHî^,ý"ç{9D@EáS)5~º¥ú§YM ÀJ*?°âª}VU{†h*¢ê�L[¯}Á2M×éš`þè4KÄçY'á‰q# ¸²ÑnR7«;T)Ô€+èçYOpP'Â%Ø5!W4Jn€\)a?9Â/¢¥¯�pRüäüðáÃvàÀçÛ©餉–M4ˆW³Z[߀¼àÃÌ®Ö^z'—±[±Uki;‚4ÉçÎ�kòí$ÒI²Ö¹sçìí·ßvTJ�f¦Ø],4hA<‹�”TÂB쓸÷S‡"aà§@„|øyÜÙ/lê^Ô`)t¸¯ uP‰ñ^OånÍãճJaÏ_Z]lÓ'6¯|'ÿ„7ÍN²—×YqI�»æõ º&K·\Z ¯ÈL�¶OÞ�fÿë¸Ìïj­ôÜ;ºá‡6õ®ðlŵÃ_xiq Ý­d]<݇í¾Ù¶CÍã¬ï¾PkeôoadE§ß÷ê{õvôtó3;ý€Ër  ÿ¨óV—ž°ã[e9[~mU¥r(ìØDn o�°’ÝíóYê¼gV²k›tBSI>�BÉËòê×bî'óº9“ýÀ¡¾fpD”M:Ý(:äFÛ²£Ê^b;9Ð×Òé: *`T‹pú ™ÒWI§â¶|Üäë&¸ §à#Y~þvl÷—ÌN°áY±6¯Ó�"¦*I£µï—ÛSoÙ�{ç8Ò÷^ ~Þò÷£¡””`"ÿÿ ܤ�Õ$¬H³iÔ¨Q6fÌ·LðÅH'îm¤%G™2É•Ÿ¯N§>Ží�48]Ž6ÏÞq¤Å[iëÒQ岚Tv/GP?íkDM¿Ú~ödž=öÜqÌQñïäRÓŽ‡ï�_¥±êJ$DR ;S@í„L†ÕvÜ|ñ,Ÿ˜�†Õ[r?¬Ô|G$\É)€ðçËÂ_ÙM–�O¨ºÈüÆ2­Š‡žâ²T}cþÕ�$Ul+í.MlL”4œ²,¢)6:?>It¦±œ k~ƒôU°E;|å%¹œD[zâ +­é™›6mrÚT"µfLJfµñ\d´A<é&B,Bx˜Ï'•Ú&yÓ]ù3 S B> èìí��KÀ)´£†lxhgååõöÔÛEvÍÄlT|ƒƒù8š�;PÏ\ñ~‰U20*(ª±•[*l«euGÐ*|.N†Ô*·£¹¬VVuó»ïY«ßEÇ$а¶h�»ã•í>c¾™n›Õà|9I¸2d_>”ÎÆ×à³’ÓÛíȆïÙ©=´:Ì Õ©)H;fúÄ$ûÈíé6wJ|p•4%NP6j7=;sB\ˆÌãÊ+ƒç‹�F»‹tjh"DüÒtš‚O§锌¦“bèbI\ˆ¦û–ù5ö¤ÕJV±+*­mM’Vr•|Øü¬MƒöûJ2<Â4¶šúi5MOÝL³…3ãm&²ú|W[.�/^:Ëáú²u%ø¾*¯SMë4á°ü'xT‘; zÍ0p7ÐÀqH:îEZ]eèСNå[ÂÖ¥P"±äÏáý÷ßw«¾ðL5BÓÁxŠ£#ž$¿iEË‘¦5”­PPÜ[¤¯w¢‡·*º*�Ò"‹“ YU}ñ¸_jœ$X–ÒÖ?÷æûÞcÇìÈñr/ÿUÞÿ(ÿ¯Hˆ¤@O¤€êîp�V'¦EC--a*é4$Ôƒž¯ zm$DR çRÀã°‚LOÓD8…¿Õ‘N® åh¨_ònó¶á×Gö›S€ôI�€Òªƒåñ º'äQ/±hýdh¥8Vέb“"V|KLMM�¿œZPž’"\QQÑxúôé(™ÖIÓIDYX\$c’¹~vÉ^AA<$ƒ9ù†# ®{Ž²Ñ£GÛÜ9smè°¡ÎÌŽë�¦÷ÊoÔŽ;œß¨ñ#ñÍšlY žTÔäÌx1êz\‚äËÀoÖ -±°ü.ÍæÊxÃR‘LýúõSÞN\6Ÿ½ŽÇDKHhéâ:ˆ×ë½.éHìIÜ;¤U”�Jy� ‹2õ¬tMÏ'}‹$ÿ�É%ë’²ÿóçyæ5ôºú‚¯A6Òû_€¤" GæËCÝ¡6dXÇ}ÕÛl3f¶°Z’%Ñ9]Íng6Á ª»^€î¸#MC†z‡PoðCn‰ë'©ˆ™•ª¼ö¬—ï‘RÄ„ (fýúõõÓ¦M«�>}º…³Â5#�ºt/:áo&?IŸœœ5ä-;;Û„YìL$�šÉQü~xÈZ²»Æbû�Ý6T�|sæÌ11¸xx8®ó~èÎ:æÁi‹UqQǦYaÝ·c,b7ÌE¨LmaÚ}†ô »�<èÎܦÎÖkuC„)ààf-+½"ãðgà“Àö‚ŸGÐáíÇ}òàB�\jÀ¹³Ðø9Ä.ç³}Ê[âý�^YˆAÌÙcß%Áù \ý(ˆŽðÆ`ïiþ )8³Z†Nÿ ºà»Ö Ïz´?fªÓ=œ˜×W·4ȉL¿l>Úµ´»tß=~2H'4ÞM`‘JóÀÓéix˜­–Új�Š�ÚG‘CìÆŽpÊ'W&È‚)6±ƒ„R±qºúŒÃî•.½˜KO.]­Ã°¯2Ù OºðáqÚ0?<®âeÞD«px/¯²(µŒYÔ€¸Nû2ªä/–ÉÁÓðâ ó–ÂἡcI§ÕYŠp/ü¼áB‡DÎW�;�&žD,·ýÐc5ªïšGÆ�ˆE Þ0]´óLâÐÌ£ŽN#®Ó̸íPJ_7 ‘ÆÎNà¿’süÝZÊ|Y.$(R%ôrBLE EÛÛI¿Fø’×`@M¸Ñ+·rÎ ÓQaû¶Y½Å{”®Ž¦Öéãy=f^UB°WA †<þ:�j '’xÊ»V‹avÙòÌë—ÕêÀuiüþ;ðÐqEâ$C D¨š ·ÿ,ˆ1[câ�üý<‹LvË |`öš³8iqq"LÕ8ÌЀ¡Cº_ñØ—$ÙfŠÛ:NÜ{%¿|«ÔÔ•qè[ì¾}ûüîÆaüœM—„ ÛUzÛJO*’¥N81 £óƒhªÍÊÊò_»vÍZZZjª««kž.mѽÀkÀ `;¬%¹ÐCÔJïrÚZ ÎT¾y 'æ['¡81 É'Ov+‰'Ìb>Ú†ýí›7<ÂŒ6@¬%X³c”¡†ô äSyÐ�»Íö+‘ëÒÅ)-x>ñ0&FÆ��tz@™j14gýÎr¹}†ClðzbC-)!¦ӷ׃|²³Ñv&³R¶©Ò†çÆmàÜN �fN°È\7ßv° ^8Õ’sôEé?þãgõ ­µ‡Û¾d².]OXà’k’/>YƒaƒÚñ$¢ò0L«o™G~Lb¤òÚYÉ9ò'É=þªTWHcØ»ÔD‹Ü·8Aî]à’þIbå°A-a˃žJŒ7ôÁ¾roèJAMpx‡…�J³Ë@¿e/ „¤Ê3ÈîD}‹ÊêA:ye-fbôVÔ‡{ñð”+ÀSIÕ< ·5ªY¿O¾pÈk"@"J ‰µ¡í î–% xÜ=Ží2è@•Øv =�øØÎ�tzoO¹"÷Š«­Ù0DêéÀwþ%€دë–öpá9$+~ üRßQYY©\¼9Žq™zBH@!€¨¤¥¥1žƒvIØ_¬G"©Ž¨Âfä“ÚÔy»†~MU>ù®UVc¦üc9çÎhƒ‹“xúå³Ùò§7‚ĉØ}‰€]@{χbh Ó@‘Ž]ŠRý]¼y -±ž˜$÷t ÝŸk²Æ¤¢¬³jA )–ýÀÈ®bhÀЀ¡�ŽkP~KcÍéç^&vÄ”Ë-{_*ª²9ìÍDÏ xB ‡­1>%;Ñ8QŠNâ�œj‹ŒÒI'�Yj&¹‹/ú9s¼±9³cN5ÏólX ¬Ž> µQ’>_¾ ̘õײÌ4|øp•OlS¢ç‘6QFF†òxbžâ0´àîEñ²pª]Ù�úñí-iZbÀT)EøI<Ñ6�¦IÒ^Œý7Pùt•«^šSχ Ëù¶gY®2€I¬3O!Øó.LQÇG]mµ¿ŠC¤–Îr8×í´Iv^µšÂ~5âó„Ïù];bRÝ»0^ö+W^,eW�IÑÅ�2hÂ';û©} $œ8¥8½Ÿ®E«I×¥[íÁ“q�ª®ÉÕ/IÖ�g¤¢.ÈŠtÒtaƒÞM�—GWÀ»f˜èP(¸+Šª¢7S â:í8ìCP{‹7DO¨!©v¹gI¼¬˜eWÁ³yiÌð<0_~F?|Æ'ZS*ÇÏj1‹xX@J°¤ûòï�“õQ¼ ¤Ö5Á¨ÚžÀòQ`À�»ÆsŸî”Uâ:²Mú%Ī8MŒ±u½£Ÿ¥-Á/(RŽe=ãR�lé´õH¥• ˜8Èä0%p•=m/Ï€Özݰë:¡ÁD²j4ðÀI#«  @MçËép¼'„=–œM½‹Zü'´[©+’tí =Œ®^ Ú}¬íëÞfBuæ½¶¶ýgii;òÆ®’xÊ’çÞÌÑ=žxÍÝÀ?ì�U×ÇÒCÝ¥�…"þTD‹íÖÔx;I‚s†w`RUütÛDy¹Ô·uW–Œt ¸å5¨R<¶ U’áµQŠ”¼60ƒ~“0r¹\jÆ8zTÓ®àÐ~��âw4œHÒ½»iwœ?^ «ƒ—“"´Â� èµ K~k9³ò&€¶W5p3…mº Á Hzû3 $—„ þÙ³g›,]?&¸dþx <®ã)†��t4X1×#K¦;ÔäQÁƒ#XA´ 8PûÒ>uFe�în…C òéVxŠÑ½¾üªÀl¡*eÝL‹ô2±qÁúƒ+¬TØÖ[`¬Ÿ~€(h”w¶{N³UÇÅšè�’‡™Æâå·¯W+Y>àù±UmhOì‚°�=et¦uÉ~û©Z®f¼&ýÇÝ�T™Õ¶ïu°,™l–¬|¿\tùድr­ü:O}÷-ºDì|‹åÚ¥äâÎ'åZÖV�t x‘1¦ÒÌb÷0†;ÎÆð6‡•Å£×ø¥bÙ‹ÂàD'3kTL¦í‡+TX·“àŽ“»@8Þ‡øaCûÇ¡³ω�.ôø´€âø˜2 øx:½³µLͺ¨§�£Ižlžv~·õqÇ!=*ÔBðEீAß?¾‡j6Á1Ã�ðøòÈB uLD`w o ½àî$�è1æƒ9süt5H'¯ìÍðIgù»žtâô½oÏô`"9×=±®ø>À)€ §ÑÅ@špgIÂXÝ-ìy¤§ ¨’’ÕK©ÊDXÙi),_—rkå\6m@%|>ƒMñÚ¶žøËœêp¥7À¥*XvVtâéòÕjùÏg2åå5WAl)ŽI'žhÜî ⩳J6΋T pà?£çàvk\bLŠ{.b<Í@½ÎÎ}zùÁ»:XêYò»Zú#Í–qœ¡C}E=aE<¨! �ˆÇ6m‚]â­¹(Gû�dc4©o' Q=ˆaY;wîܬƒsŠQÁ¼áÙäç z€‰ç´à!ÅNPz6m>NU€ÞÖÂj«röü 0°ƒóãÜòÉÄ!w- ó•——çß²e‹²Áè 5{’GVÌvbØjX‘ ŽeóÒ -hÕ0+iO¤§ÇÝü0ȧ›ÿFûØ0R�#6èC‡®amêùdÃÉáåŒ#½Fž&’:u¡"fF‚{Ù ›š%‹W_9Û!îu`Hb?Á“å�me²ìú ÌXÇ™ðº*Ä÷Y Ï�'ËU¢¢ì=Ržw\âÍFCœmåÖå‘E1òÄÊ8Ù{ºA~„Yìt)`ßC_ÆÏð•^�Ëû~#9bWëCã<׉dÅØa˜vÃÛn›nC´6Ä®=¢£#*T¤þä•ÔËÚíå �¼šN Œp;±üÄŠ™<Ê-pŸðÑ•üöq˜ž¯Ú/ÛWÊë(Îxd,wáJ6ÀxE/@o>Ä[èÐËéóÀ8 H:é_÷"¶Õ*¼W©‰"Ž; 28¸5ÑI§²ÊFÌX%ïïòÊÑ3•RUÓØü=¤Ž �·�ç�Ã_Ž®’$²Ø›G"ŠÁªGÑè¡GwvôT=‡ØÞ­BÊb±Â(dï$|(€öê!άH=©™åB¹£ç ­ž>B{öx?X4»¯sYщ§,O?ýý%ùË{ žq^#wcI�'ƒx¢F én ÌÇؘZi6ÇÆzc%Þ1ï+Ì�°Ê^óÑÃ_tTèëÝ�1#}C†ú˜ðq5›â$Á>ñ3ÇHEÝ)óǬx™ ¡Ê`?`º€iT\\Lb)–±“è…¡lµ§OŸn8yòdöÅ’´ ödÞ6çnãAêã‹e[B;ñÀöÜÅp˜ˆ/C �`Ò‡×a_P¸�ùܱc‡¹°°PÃØ¼wÎs‹Û¡…L Á 3ÚqpT´1a™‹èŠIÁ•�Cz‹ÂI�Þ’'#7N|ñÙhU“ÄÂc¥ÃäR`_«CT[G¥Ç-áÆ«ÀóÀr[5,›ö—Ë‚iVu=ĕԤXyøöxùùsUª¢ËͯÆÔöåò•‡yJ—…ÁÍg#¸yÚ@›\έ’:�&ùÖIüà¹í¦ýÁÁx>ÅÈ®“‘Ôõí&wS`2ã!ƒ9Ì;ýŠ\ØùßâÍ?o':i„eÿd« @x×<§ôC\'6t ¡ŠD×o9œÙ†!voaæÄ RÏ?/AâkÌP‡*C·a,ºÛÁ€æ*ËM.®ÏÐvÞ9ƧbgßÖ­[•ǽÏûÁ¾pY¼ JU¦f¤×or;E­v­'`ålHЀA>õ�‡ÜÁ[d¯<¿™Ðpê ‰h̰±EÒ õ+ÖNÍk(²ôô�`cr(Fl!¾N…\ʉa`ÑF8sñ4‡lÀ´ï‡N•«mî÷ʘ>}H\ó ÆH¦ƒ‚¼&#ÖÍ¢)NyäScc�\;ýž Ÿõ5‰³%!ï­·™¼h ý·¬÷û à¹˜M©.Ï•‹{~!ÙŸ“ºZ8z—m˜%mÉLÄuq86 ÃÛÈQ±\\ÿMë”òtR¤¼Ê�è|òΖ29zN#Ex–»ø02 ùÝ \ú%ǪFv8a¢§Q‡G̸Ekw nÑÁ )«¬ET0[l¬_~ü Nh/~Ü`qáúwИ’¼|éâ=�NnÄ6sËð�qˆÓ¤ÞG< ìlCx.½À*«hï!Ÿ¬Þâ•cç+1´î:Ò‰ºÈ^h�ø^w—ŽHjl¾ ü0ކRYY™š‰Ž½ƒ×�¢ 3”1.YÖÚ+Ò¬ÝN3fê4«Ùåy£~š×‡Ý™m¦Í¬òÉ«§Ïü3f—ºŸ÷.ðÓ|F2¯TÉOžÊ”7Þz<Ñå#@—Cº«, iC (�êÛ¡‡ïÂÒeŠuXûSçÉiM¿®dkï+k¸À,wŠ„2´hhÀЀ¡�nÔ€ªxà eF线ZJ} ï¡€1† äŠÔA q9{ölLyy9¬µ °cïM€{@5ÐQ¯{z;ÑNd8†@,†ù5r˜l&LL�™©¯«-q„û,}Û¶m*�úçA‹‡–xdÌšœíYA*™ÿÐgç\Ø¥Ý8�´!}@ùÔro‘5ŠjY :¬bˆ8žÃ$P-±"m^¡pöœ�ákbÇÔËŽcU2ä“4“â1 ÙÇ0Tè8É4~ ‹jU짯>ï'ä€ òSòöG1Ó Þ¢³Rœ½]Œy¤MòIË`ßûKo'¦§.ÎÚ$g>ú¡”äìÎb§±ûäªÌzáÀpÌ„†z؈‡.)L1˜ Eª@ŠìG€zÃ<|JóRÒ‰%‡-Áê=òð2|Ó,êù†_ôÈc³™CÈŽœ«Æìl^9x²JÊ*êš“™/~ œz“·‡m­hL,ø;h¬8l T§¹Ñ+呉#8ÌP&És`ȺF“¡؇¥ˆéÔT¿¸…†Ï àe€®ßY@¤.ß8´K¢{ÕðÞI@M!�‚i‡åرc*&ÂèÑ£[5¤ºteu²æUÇU\V ¿k3MÔzt!UñÈB’ Tr¡�=´¨’;5©|³0c<Ñã‰u3„ÄÓ‡À?çƒx‚ é6 °“ìà;À,1Û€ÆÔøÅ~·} Ú5,¥Úûn|h^Oܾ¿ 14`hÀÐ@7i€á)êJ$§dµ”TÇD;¡ÎkÎÇ–ªS‹qH4¹„Åj€v;ö|@p'Ö#¶ïïþ˜ ¸l6›òvš:uªÙív·i+Ñã‰ÄÓ¦M›Ô’Ä;5?�§©cl8·Ëæ;æ0ñ(ëbU!ÃUõº¶"6r+jÀ ŸnŧÚù{b-À2Áá¸h¼wÎ@Su‰ªOTFZ«¡Xû²�ÿYÀU–`ï Ÿ|âv�ò¸"iÀšvÖ«L«gŒ•�–Ëý‹Ý28µë±ŸØ€=4N&Œt€„(—†º*ÉÏxKú�¹U n€‚‚`†)'5•yðtzJ2ü^j*® ºxWœÜ O£‡—ºÔ r|nœÎ=ÂbDOœjÌÎuè†^n/•ý �jKG'�Ð|ÆxH§x™9Þ$¾ôï8‹1?pÙ…õ²õP¥òr:Ÿ]¥e7‹ÛCrc+ðk` Àßýàã”n6¶–_– X“(ž7Å#,òÈ”1V’÷I|-ö@1–QN~½¼‰ ëv•7÷Ã¥ÁtËg�w�B€ïpt4ŠPøLvìÅ#5—Fg^9qâ„" ÆŒ£zì°/j¢¼„:š4Cå„)ˆ«$ià*xó ß!V‹—0ÔîçOgÊkë‚Ä“N ~wuè-ïÌͧd#Ç‘hu_Ì#x³Ø¨šcŽ5»ìÃýý<·Áãi4¸^rñÚ[‡âv;ðWÀëIßl, 04Ð�@÷“Ôùd¼äm)ª<»9D<é—%±aÇm,Nì˜g=í…0¿"“I8ì›ÀCI�˜!C†½�Û‰ÄR[¢ÇxÚ¾};ƒŒ+;r0fŠ~“MOzrûQ}”L )g’4’¸I4Ðv ¼InÂÈfT5 È'¦¨í�HZ5RBç±âl©òdm{ج`C™Ã8.^©S�¡“„M7ƒßµÐ%1ôŽ éü¢Ù¼¿Rž¸'¾Ã¾§¸ÎuâÂ�˜¥Ó‘~ ðxá¥-âÍ=‚Àãs0´†mª¾+ðÇU¤Smu‘ä]x_2÷þŸ”æ–ÆzM/lˆNHwÊ÷&Éœ‰6¡çŒú„¶ô´;¨F6H:ÕÖ!pÌÉjY Rdß Œ—‡‡š>4.ÍŒI£0{\€çM²‰q�xi�øÒÓ(ñ6Ê{”½ÞR¹×jT h�˜ d WQñižÆr5à:êÚŒSºE,Hu ð%`Єt"ñ6CS€§ÓLÄ0sâ}Ѽrpd;¢ë§Â×(›"ÐúÆÉÊ­nîÆGÊž·§ºsø!õ…§ŒT:'¼þàóÀ/ê…�:ÅÀ�“'OF0Ë8nŽšh\tÇo[ç°ñ¾4`�nôÅQËT%¤êtdþLf•üøw™²vsž\œï ŸÅ÷z Ä”`H·i Rþ4ŠHxÿ¨˜›9É=Eúy–˜,1ýH�bw¨òmåþ¥×®Úox=)� è^ �xªGx¦+¥k¤¸2£Eâ 9(>7sPt¶c�öáÀ7€€•ñœÛI&Mš$Ngûü'W©­­•Ý»wc< îï�¿º#^F#”†20‘p4ÄšíŽÉ±ƒU«®£‘¸‘F¯Ö€A>õêÇsC2ÇnCU�\èŒp˜IعL¥µ”8~™AôVð:¾êxµød*f%Ó£€dö›ŒÃ¬i'/qø�³à•Ë�‹\’âÖ‚HëÇvx Ë”vèœÉ6ÒÏ&9Õ˜­­H®äÓ,$Çlw¼±Ùá|ô¢Løð` ä¨Q|%™ríâzèã5)½rP‘Nz,,’«æÇËgïM�Áˆ«¤<Õ¢¤*=øÑ³^Òiç±JñUÕ«85T{KÆ¥;äþEñ²`ªM]�Yô¸3�¦Áß÷¯’—חʉsB¦Yæqš0hãà`P\ß-…�7@øè*�F–Ü ¸� ›BâmÊh'b[iÄ[<ˆ76¹øt`­U!QX�ÂðTµü�Ö÷"Ð:ƒ‰«óµ³˜R>ððG è¬A„S£.¼ÝS�¬ÿîàW#çÏŸÇ½Ô ib†ºP]Âý]ÚÔ= è1§{Þµ•& ó Ñ©•MÖy¬co¬ /ZvÚω'œç}òƒÿ»(wè%‰IÎjø}à jõã‡!†¢¨¾3s€¯w¡@&Ƙm¦d×4Iõ,kL Ê3K´VªCe›ßp|ɱÁ ž”*Œ?† ô€H<5`´ÜÕÒuR\~´¥Îì ÈÆ«ãßžèåÔ•NÏ©8ÿ;ÀÝ@<¼›Léééôv’ÔÔTx+Áè‹@hã:tHƒŠñ¨R­òÈr·Œ óû¢)˜íN« µDIœ…ÿŽæ¥Œ´z™ ò©—=�^�yª–jR-D˜1ÖM*¶ÇòhC¯XÆZ+g¬h·e@<tÛ�TʃðdIp1f¶"½$� wÎw+ò‰é_ί’m|jíVq…pT§…Ué �'Ëf»äÏëªèNrO¯–´iOˆ»ÿt4{ Ñé[ŒàD˜å1±˜=ðr*ÍÝ+ùgÖHÑ¥ÍRY’#þ†Z|sØÎÄ—�udšC>¹*Q–Ïpˆ}a„E×jý�t:q±FÖ`vµm‡+¥¼².8¥=ãJ� y?†–- vÉñ˜EÉ©/W $>ùý:�U+o#9‡iVúêÉž ¬^èµÁ�>½izƒ�`š|xH‚ I§ #A:-rË|oN�xSO' ߪ¨™(A:eÖ©`âî.—ÒŠ&�Öy®N ÿ ëÔOo"�˜?]ø,Ïß|À'Õk—™™‰w·Q^Ñ  h�ÑÓ‡1’¯ÂÐ϶¤çð8ý<Ö­ñŸia[çvÃ>fV•Ö¡ Ñ"²#u�§@<ýïÙ¸³PYws6»¶Z�C DYì®PÃì°Œñ$ÉnOñ‹ñ¤mo­í¿zÄ'5Ÿ’fÒ`«!† è^ hO>É+]+…Þýh ѤRRŠ¿ìÔÛü ýBûS}›±ìŒ�´ù,ð·fZ0Y8s½¿‡.ˆóqšŽÇλãÇ�«Ž<›5Fî^è‘ñÃ-°ý»’Å–³@›_uni»y†ô ´F ô‘Û7n³™h³©æ;·³±ßQQ�œF\µE>é�Ç-¸Îl]Ìñ�0¨DP»±„m�ÈɆ·¶ÚÕмº:¿¬Ã0ªe³ðzéº÷“ 鯜ç’õH³°¤VjÊóåòá?Ê„;R†:ˆ~¥‹Do¼ 'Ä ^£±±J¼WJ§Â Ä›R'§ß;Ÿç`x‡Ý o§»æ;e`rÀÛ¨íöwD÷H/œFèù\v-b:ye fž+)鄆;%DæÈ4›Ü³(A–L³KjH'äG]:ðhô¸E¹ˆë´1‹Þdz,³dã? \¹<<°×‰7Ø[Í$˜æŸîš‘N&3Ü)÷ßæ‘…Sl’乞xÃ9­Š"� ã+ÐÏÆ}òÁn/<ýjÂõÃsI(d$�ÞèÖ[ôƒ¬´(,—€Hb0ÑóéòåË Xü2kÖ¬.{@1�†ªGÓ¯A²¶„õË_X\1V&‰Ààt[çFy3J=i¯L _íUkÊ(ÄMp¨ÝüöRsâiÒû.° èíeY4ä&Õß—Ç`P|CüæQ;g‰qú“ÜÓA>-0YcXMjï!=›¸Æ—ŒÂ¥Ö^2†Û)… èv ¨àâþ2x<­•kå‡@<Ãw°Ãéï�­×¹C}“±ì¬LʼnAo§””Ó”)S„¯Øíœ‹&raœ§«W¯Êž={3î©û'Ç)â‰MA­–�<½HŽ´ÄajˆPµÍŽW½úŽät㘛Xùt?¼nÊ:{•Ä!æNgu+]Hf­ »žàJ/–ZKïb¨ÕxÕ$éÃêP=÷KŠ•»xäw¯W)OERí�’÷ÒÑ/NîX//®Ã¨ ]®ž|G†L~\âÏ9üx´v7Õvmh�EêjŠ¥ s³ä{EŠ.o—º*/î|LØÔh²æ�Ç¥³ÜŠô”)›¶„úåDpÁawÚÁð`e@§§„¡<žè‘Å ’U¦öš‰ÞyÀàâ?{:SÖoÍ×I4*�CìèñdOÍôfüŒªÒ�‡ÿ50eÒd·`F;Ï‚s æCaã*¼ðúñyà›© _PƒxÒµa, è^ (⩱H²1«])b<…ÍjG²‰dìÔ«ˆB.ØNû  ¼�0¤Î‰VæÌ™#‰‰‰Êæ‰ä´¿Ù±FâÉëõÊ®]»¤  @mãù±0°Y‹²³·IUË�]Öܪ ÀÙn4Ó„¶°!}DùÔGt„·É*ÆÍcÙø€Çe§„U ®…~é[CK6f6÷°=”yµJ6î©D€;OhXòrûL‡¼·Ó¦‚"“¤Z³$Õ,z@»èýļàM¸{�S6íõÊU¥®©,„÷ÓÓ2ið,ìdöÃ�\žpŠú�X¤¶êšäŸ}W®}AJsÀ£ÃêÃÖxøilˆµå�…S�2~Xœ æM5�ôhÖ˜î°"X6èÍTXÖ öVȺíe˜i ^8`´øü¹`?»Ü ²ñ޹!áÅ'Àk딫Yðj0KâQŸ¼±©LŽŸgÜ"6ªy ÞÔ àÿ€·zƨ8–7Z0`Q–Ÿn\I'%$Þ8»ÈÐÁªyЉ7l 'Þôc›/©?ÎTY‡»çÆTÈs…¥š'u&$×Oû’NM�À†›@˜ghÿ ðÿî5cÆŒ¹ ãü Ð@#¼#íy†òY±<ÒK*Lt²ñ¿±íÀ¦°}ݽª2BZV i»�ææt§$)ÿçù˲úÃ<�xâÇ€ï;€Þò.!+†Üb�ûù¦˜ÌŸÁG!ÁlŠ5y죥_üm&‡u8ª¸X”b’MšèoXøov¨óÿëÛo1·chÀÐ@/Ñc¥Ö4äbV»ÕRâ;‡j+ØÇޱÞ*¢�]ÆýG@uVbX�‰ñ-éñÔQo'Ú5ŒÅX™ôxÊÉÉijç0³¨AÃÅılSÀDÚKˆòÿˉ¥µ;8¬Î‰`w –ÐÄaÈ¡ˆÍt/‚Lÿß_ªIÁÙñHR=NR!�N 2žï§{àeóÌÛ`þá”æÄ~Ú/ Cæ£B¾‰½Ÿð<Ì&‹Ô×ÁøÌ+’µÿi)»zÄÃb9AiI,8sœC]21Ý¢†·Ñ‹�mgÕNåÃí‚°�0òUûe‚ˆ¿ña©œÍò�#›Ò?Ù ²Åƒá}NŠçA†×'Lpœ%‡NWË››Ëdωr|<›ÇuÊÆiôây¸ -¬ßH!é´ø°`÷}Òi(¼½¨ƒå³ì28%¤�xÃñ- ß8ê·¢ªQŽ Xû©ObHe nV¸q(õ±x X0fÒ­@&°‡‘Ä¥ EÏ%in·â×µ#:ð70²:ƒ3*úªÕ[Ñj 4ìX—Õ_¯UP €_?^ÚN DA´zX½ÇªYÞb’ìˆ,©¨—WçÉKkrAb³v'�ÜÛ \W-¦fl44Ða ¤áŒ¯ÂlxâĘ;bÛM"ñ$ÖØ´.Ðb™ÔŠ3S׈&®iÂ=,æê޽S]÷��ÆÂЀ¡CQÔc<ùê2%§tµx}—P÷;sÏâ2´C6´±º"cüyàKÀP nðàÁ*¬@ZZššÝ—6GG„ÄíÎlwæÌ5Q Î/h§Ò6 U²øm¡}&hmÒW4`�O}åIGvŸ¬h<<”+ 6×±ª '¡ò£+eX¥Â꥽ Œ ™]À:àã¬?T|†b}þ¾x´r¹@Õ¤¼ŸvÙåRN•jØ‘¤Z’ªHªyH.BäW$–@IDATÁ%È—­šëD<›dcèV <„®œxäÓ$Â[è°6"¼x÷o\�GuríÒ’¹ç¤ðÒÖ&³ÖÑÃ!}ˆ]nŸÃauvÚ?NâP+ÐVçswöèJ.Y&‘èñs5òÚÆRÙu„gWC‚šMp[�â:yÔ¬AÒ+LåLƒG_¼R+o}ä•ÍÊɛ䬿8ƒÈÓÀi€$KX*øuc„ó%Àß· XÿÒlÄ`›šAp)†JÄ.”wõ "È= ¹»ŽTËêm¥rät…ŠIo—SBuððÀajkyKÉu‰§+W®¨>z@%'ÓŽë˜Ð5]—’ò9r¦J¦Œ²‡×uúnµdÙf÷|ÒÝÜqKódàÇ3ó À²Ú]Ò¤n­H‘xª©öþ–"ùÝ«—¥ 3�$KÁ£aвì3†¢¡¾ŒaòMÔó÷£öK´Äz$Ù3 3ÛΗ8s|àÚð:�>Õ‹µFI±\k[¸¦ ¹k:/�„±è´4âO?�ÚÕŸ�¾ÍXè; ñTÓ�'—KÞDÇ_ŒÍà7s´@�§}=Ì»"+p2½�æn+fú™4i’êLs¹4�ŽOº-ràÀÉÈÈPµ mÚÏ¿>Œºõõ†ÙªFÙà:ÖÿFe¢TqëÿA ÇCA ðÅW½PlVÔ­µR‚§\¿Â†°Æ«U$L3Ôj»þp} {~Ü 8¨÷½�¥²t†]Ò#>~Óû‰±Ÿ\/¿z¹J5̳AR­ÝQ._¸?§u"³8K6ô»Š3ëýámxW!ÀpÞéu2lÆßˆ«ß%ÝÙ6Ôs�%õo�~êàá´W.xF®žz1žÊƒÃëH:MHwÊÝ {NÆÌAˆ%ÄjŸážð?j~üšpXAq½¼³½\Ö" xqY­>ŒGl–Y4Ý#-óÈÄ_ŒQÄ!N!=�ÈŒA~óŠä}ÌÎÆazùÅM‚‰ó`~ÜI¦Ðƒn'À‡– ~Ý¡WÙË/÷M†×qèÖ¨4;‚¸ÇC6€òÍ&Òg ‚µƒÔ;y©Fހ؎ÃåðÈi÷CjJH2mž¶•À­F:á–‚¢P¼GmVöðª^>z@±×0R‰‹ÃÐS�GÅF`:e Šü;Ì*ó§8[L†õ q.)1`O“’’�$5�1†òQ§ßø<Þ,±ˆªð:¬ƒU=Ììh1Ÿš^ƒÆ(=ºöóʯžÍ’kÅä)•áï‹ÀsÀ­\fp{†Ü �Œ¿@¼6ÓL¼5qÖ¸IñÌ•d×<ÄqãëÎi)B¾®mÕÛI܃o ŸÅë�÷/tfO®1×È·ò¾"Æ/âÍ'¼ JEæÃJýâ›ex–Ý|ÕÈqT4@¼È·O*«s±$žÞCâßN]ùfÅù_> ¤ÀS)fÈ�!Št¢·Sx‡öwHèõtâÄ 9vì:œh>«èì [|Š |Ù¯¯jÕ®®ÿa;‘¶}@,úб¼õ5`�O·þ3îȲè¯N@…à¶™›˜‘&Ä5=9•H,.ÖÚì!à¸è¿bƒ-ïZ-¼d¼ò��§(vœÛüHi)â<­ßí”S—*UL•÷v•ɲ™N�TqФÂù�¤O¢cÙ,§¬Ù敼"Ä~ª(�œŒWd\vÈörAæ9{]CC¥gí�œc/JÁ¹÷¥ÆW¬‚¨3÷|,£@ücKeÑ4«$º5ï6Õ@VŒâç& ÂÖjðÙÝqÈ'/o(‘ó—1ÄÞ9”G9åÑ 2g¢MâIÂIŸ–žÇ0¯z0ñ͘ñ�­¥r C-Ê#I¦ÝÀÿ$ŸØˆZX¿Q–Ï8€žN)‰(%¼¯1C¦î‘E“µüø æ#ÐÉŠÀ¡-.p:<õ´`íká!È™‹Ó©™§“ËøNýØ�Qè+ž+$ ~°7q›ÊÊÊdÿþýª§oĈØÜ¾p bÌ$#ýû÷—Ü\™(—óêä¹µHÏbþäë (z홬¬,Ù·o_pf;ó;à€¤QþTÝô ùU;€ïh@hŸè�å­©eŒÞš·fÜU'4@’hÏ£G…ÓÙYòI#q×gšD$Bï'z®Ü $±!½å‚ŠOwÉ"L/_ï'ڠɘfþáñòÓ?ùTO}>H*z}üÃc ©p"Žê´0¾Ñ�Ô8Ä›rË+ëk¤3ßœ^-Cg|QìñÞC�¾@7œÈÙëH:ÕÖ �ø%Ì^wäÏríò©¯­ ’N´áú'Ûä�%ñr7â)¥è³¦QY]QX ÷CÒˆžUrëäÕJà!â•jÄdbc—û¤Úä¡¥ *˜xJ|ŒjVpŸ.<††cE•ñœ|*®ÓÉ‹$‘F(¯$˜N¿H¬”]éaÂéQ–õ�À¤aÉ!wJx_£0Ì‘3ø-�fמî7`w뇵ºTºÁŸ‚R-Xû{;¬�³×�Ô ©F­^E"^ÎÔMo å��OÏùÀO�¡4§***äðáÃ(“�2räHln_èÞÎeJKKÅçC݃Âx:«Zž~»Hyš-BpþpaYÕÉVngO#gÜC€PIOOºÎ“€fBžF¨Tú' —çt›¨J��µÂ¢ZùÓë¹²y÷5õ®b/Ë ËŸÔŸ!†¢­’ò |Ï “Ó:Dú',Aç×Dübçk¶±„jËõíT¤°Lðx R=à‘£Õ»Zþ”—“ž?E<é6~Àÿ2‹a5~õR!éo'åéÔÔãŒÙçm´+8�u ömà ì9úO‘€‹Áë6k¬Ø�€Ã"V[Œ8]V‰O´vñ$`=Á.ì§Ç(•†3µÞ\œ^š´iÔódÆ�‹UV!Vç• É<_,—/KQab]"ÿð¨¦vDùf²†ˆHÚ{o�IÄÑx¿5jV–9Û4•$œðMà+@2ì3ƒ‰s˜�ÃáPe_QBM5p¼>³Œ³#. oaùK€^ΞÀ6¼»x{Õ‹§o‰Þ’ÉÒž {'©À°ŸÑ»–‘RïÓ€A>õ¾gr#sÄž÷~̀ƀ¿Â=Q"Í?ñ$ÂV*‘-µcÀsÀßRîk�—@`LJï/N‡æÃê‰ñ‰æLpËîã^åí±SÈ/™î–ù“¬IÅ“;#¨Íx+VÎqÊ{»J¥Ì[/ÅÙ  Þ‘sÿ­÷`ïFgR�ê9&3�ìX©õå©Ùër޼(¥¹‡@˜5�½.%É"+f{äÞ….>Î7°åhvÇG…ÞN>øÖ|¸¯B^ù X®`;ÝÇa‹•ås<òñå /5æöh0ü‘œ©DÀì§«äÝ­˜�ØEµ�ØPåñ 6ÌŸž²�Þ0’圤ӣÀg€ ݈¹]yÔ¥õ·Ë½2ʸeý“ШÂõôö lEtÝ”V4ʶÕ²^`à¥RËá¨ÔHHè©ò6ðà@!‚+à¨[WèID�4°Ø“¨¤#Gލ€›$•Úm©©©2nÜ8åªÎ8R$M/^©‘?½C›M¬?D@±WŸÃØt1ã|O’Pt›'uôèQ)**"•†FÕ?b9 ‡0Ÿ¬ £%,‡ª,ò½g®ôœÑõ½õì[ ä¥w¯ßWr`>N†ŽUC tY,‹¬#¿Ð3”¤+ˆ§Áþþ Ë0³Ý8V�xÒ ­æw£­³ ëm"} ¶)o'~ÒíÄ“FШ¡hl£qhD£jØ( 6s¸�úÝíyÒ/Ú¹¥¦UÍÓI×°VSï ó>ù[½žX×a*DÚŒ´c-&Ø‘±âp[áñi‘¤~øî ôÈà¡ €[ òHR²äâL‚ˆ²Á挣»€t ñÄ_ ž¿©µÕõR�W)§NäËþ�ÙrpOŽäe—ÃÞÀì^ ¢Âï&”�à ´¢³òÐ,ó�’Šš+8ÆO;ð¿€¹À¯~?#m8ŒÃ±?VnÚ .T¶‚>ÄŽ|Pg…`´[èñ”——‡wU™†ì`ú@»ºIâÊ>ÅÆî’P3Q]¡Éµ»ëšFº½CùÔ;žCoÈ¿Çt·Lf…@¢ÀíÀtÆ�¨ØQ¥:«´»"ñÔ‘rV…ãŸÒY7fœ¯�uf÷ØJ�Ô 6d£Îã0Ë'cç} +ê1£W½¼´¾D&Žì'v=]©4[jÄ b!¹TÜ)C�\=ù– žö *Äž`n ˜Ðˆ5#ÎBUE®œyK²�¼ eyðr ›½Ïp`Š ÁØÝ² DÚðAq v"';:z{ø¦)ƒó|N�¼ø^‰l=ìEÀkôs¢üpˆÝØNù«;0<É.Vôz2®“N‰èÄJˆ•ý§ª s/‚93`v“옥bàMà)à@Ò©%gEOh'Ó[�¤Ó§�‰I'nW¶s*f¼k�Gîù7$ñ1ðlTùŒ éº)!·ç¸¤“WNœ‡f Óì^E uÁá‡õPôEO'Üv‹ÂzeðE€á<@ªªªäøñã\U^Mj¥�?$‹FŒ¡f…9uê”2äø.€€úíë…’_T‡˜qqÚͪŒsˆ¨.1xItò‰ÛèúÎa| €Îa€ô¨‚aéõ–#pÈ/€ Ÿm4%/ �l±“€AÑ·(•ßü9GÊÊÉU*¡§Ó Àû€QŽ”JŒ?QÒØ»v0Í,fì {:†Ú-—-ßš a~… /~¨¯ —� ŠÔ O=Bð€ä0¡= œÂ3wÝð4VøüÞõH¾4�tæo#ÚÇ~xkézÖ—¡§€-ü�û wÍ FÔolÀZ19M*È¥AÃâeèð„Æ!Ãeà`—y ¦dlw‚€rØaƒàÛsÃáà­ ½�`¢z¢-Ì�“˜ ™ +ï#Ù™¥�ß;/Þ=cξX¢<°Ôµ£}a#½>§Æy²Ç‘!‰Êï©ðe£Vhd[ê1` °x8?°Xo.waÃ�)° ¬ìÓ'G¡§_W…ÄÞU?ŒŸ>}Ú„˜“L²øwà  çCF ^qÜ ý»ž\à:Aªa·Æë‡_ûºÃ� ·Ž:B Ü:wmÜIK`å’¸¸â°›Ä §35‰z°„V$ã‘ /™ ü ø_@ÍâõÖæR™5Î&cÒ0¼L<¨¡GÙdÅ\�¼³¥X5Ä��/W± ]îîš÷²n‰ƒß,¼…6îó*Ï›²üãRš³[RGÞ ;²šÙêq1Å0°'¦t-Í‚'Öˆéô²x NÃÓ 4è¯#�èͳø° ±Ò wƒT#Þzð àS{¬‚¤ÖAÞÆÈâY¦¾Ä£Ê-Õ´6H9×I§J =ÜwÒ§¼ÀŸ­PCšžÏ5²'ÞJ�¶ ìî³B‡ ÝÙIÒ-‚�³Q£FqS›b·ÛeôèÑ$Š„�óÝÊ)@ ¨5År&«F»31@@…’bÌ'½÷RßÊßýúõ“™3gÊÉ“'%??i5ò»¼ 7Èpà è¬ðU#”У�Eˆ¸< ïÂ_<“)Y9Á�N>lÞ < °|bh ZHBB¬/¿Œbbcì’àš$ý<‹Ä‹ðg(™,£Á‹ƒ(4 ·iÇ�áÖžô,"ñ„7G'žÚÈvö"÷Ì&o¢— I'­«$D<µ”EÅŸ5àÙð낯_b†�M–É3Êä©dø¨$Iîïl°ÆÅ4ÄÄ�W‚K%ÿuÁÔR÷©Ioð!…Ù$éc’ÌŸKŸYµäöôÚÕ¯�plzÿl\É5ôGà>¢Ñ°¿®±Þ5ài>ZFÄ>.ù–ÍrÍ{Cñ«i޾<ìø-ß”zmàÄú—�oƒ1!‰™öÉ'Nt a‡½Ò�§z„°„ÿÒß„wp1_*o°51I5Þüë«cÒE Ü}x�ÞÅ�Óo" ÐÈ5ÄЀ®7VØ+)6öP±yÝ Q¦`¨Fa*$ :"$^–ÒèÉ-¨–?¬.•ûB fHÓ<›X/ C¸ö«Äìg^ëGì§R™7É.ƒáa¢÷êÈ…Õ±¸=S&Žˆ•ÑCí’q¡³CUKÁÙ5’2’�=+&Zr0°+‹ÎÃëU¹zâ/R^tA ¯ ’N0²&�tÉ=`=o¢U’K‰�€�Ëî �¨z4‘Üy¤J^ßX&ÇΕ«7|^Ü7mŒK>}O¢LcÅot«`»þ¹eL±úF“ìͨ’×>(“CðtjÁ›‡åàCài`3@Ö�½#7RX–‡Ÿ>Œh!ßz]çMvËý‹=Ð�U•W¿ŠÄa.D:qèaµ¬ÁÌ~Oaèáõ^`|´�?/y@¸�Ÿ†´ ’)ôšcã÷×Àr@PþÆ^|Kí5H{�Ç‘xB/¢"¢XîK³à‘€š:Ú&¹×Úçy­¨ ¢gΜ‘ÌÌLzV±<�þ…Ñ8ë¿r€¨ëEž]ðÉO~Ÿ)O”jÞxÚûÅá~$ÿó£r1#CšÒ°øÐ / þø¨™mq ~ÌhgJtΔ8³G}ØÒ —¦¿‚ŸÂ)H<¡D«õð3£¿Î¼ùMø‘|‚´ž7¾a�ë¨ ¤�Ý]I?«{QžNÚ]„ß‹ž{ÖijöY�Nqè=é×Ï%£Ç¥ÊŒù˜qkî I™,6;<±A¢³ÃUo´wÝ,2D"Êb‰µ��œdùÆÈ…õ3ç ©ñ©±§3 q Ý�qC tIxY,±©2Øó�x¬cåZùN)«º`jô7X‘.;’îîø}ý À6mÇB§VcAêÞNØ5aÇâKúA<ÅÑÛ Œp/å@¸ÐF¢áÂA&ÎØÛ]Â÷ÎxóºK»½;]ƒ|êÝϧ'sÇ:À¨¹Þ-ðH¡S”¤3)qˆÕ��é@<½=öe”ÉÛ[mòø�-Ö ¶¥#†ÑƒËä©7òQS‚¤Ê¯–7?òÊß>ÊÖ.´á�çÊBL£NòÉßP/×2·Iuù±¹�H`ýÜ�Bý㻄Úß[p\rO¼*ù§Þ’Ê’Ë*ºÎdÐà›:Ú¥b Í›€ �n‰‡ð_-»#‡$%ùÑ8{³~X ¯¥rñU5¨ Ë´áR-ðöI�û»„ÅùìtŒ��?s¯ÕË[[Ê„³½õ꘰¼Òcð'` @OŒîV8.ѦР <�t4!�ì �fOt˽‹Ü �,ââÐ+Ü{xܜӢÐ;�SÎz+5ÒiÝÎ29 �joæé„å*ð"ð>^e<¨óçÏKMM ã@õǾ¯`é@ÿðywMp-–³™Õòë²`¼P/£Ü|ø°0Ê”`HT40©°gÿq|»èã°!¾“{q¥ÄW’�¡w;eàøOÁHë..D#�ý5Rze—ä CìÖIuE�æé„+S¬³Lç–{º1¤f&¤ÂT,¡0嫃£ô‡d$ ’GkwxeýÎr¹Vbgµ€¬›æ–GWÄË„á�Lo§ÀõéýT�þ”í‡|ò2âs]Èö©g–=º"¯žöôtê.E#鈹–tà3À£À0€ïIð#ÉØh³&Âël�[¦ Ì9mÚ,‘ÍH#œÒT˜=ÄØ¸ �î=Q%›öWÈÉK(Ç×{:ñ©’tb�Ù ÉöNñtC:®¾.Ôá—€ß÷Bã,##C¼^¯ê�¤‡S[Âð¦N�* jæ:΢G!ï‰ÛXŸ2ÎSkBŠ„§Sfl(zA1=O 8çoºçÿ AÔÑÊ,òv)»Z~üÔEÙº§0ÜCôý1° ~ 14 Œ@"ßÄ âIA ¾Ó(_lrZ¸‹^º¬ÞtÑzÃI„èýâ\êÄ� Ð9dK Z±æZ÷ ‡Úá•O¼¬~ÕæyÓ3÷fE�áÈ!ÇÚº{ÒNøT¨øBÇñt=+U"¿¼±þ<�“¦ ®š½ ­tÚœ!ÕƒÓœ›Í’hÆ8ù(vJ†2Ò“k¸¿X#ã&¦Ê·ÿu©<åÚ-[Þ?�Žžzƒ€êÉçpË^‹o’3†;%Ñ6K\ÖIR]{IŠ«Žˆ×w6p lJÄÏÐ(jÁœ’’Ò8tèP3cJ’øe‡V4„O´!@<™8³] Ý7�6‡Ûå·r vfÒ�ñ76`ÐÑÉÍõWc›Ñt¡qÔº�¤e,o ú–xŒQ¹ Ú!Áò`¹AîI‘L^U½Mk+¦Ýñá¤ßs�û™d>¦íC¯|÷‰ºxÃ#‰ž61òèÊùéŸ/ÛJÊk1 ¬TÆ OUC;[�7"ít;Â!‡N–+ò§ðì:0ž£yKMoº$&³‡:)ÎÞ*9ÿ(ù6H]U™æé¸–.îsá]s÷"�L§Å•ÁUUK1ºÙ Þ ËI’‚’ù`o…¬El¦+©7®¹oÂ(—<¼,^Í6èD骯3ãù|XŒüUxJ}„™ «j''”_¯ÛpÔN€?uKXÞ(¡q0ø, {:I'Þ’M`v³»æyd<ž…ƒ1ÒpOŠ ÝŽl*Ô=Öªq—Ç/UËÖ>ÌÚX!yE˜„j3ÒŠ)‘tzÐI'êÇ � „. u›|øo€ÏYy0]¾|YyBÍž=[KÜÞš0.Ýåé¹DâêêÕ«A/¨ðspœ^Mí �á�>¦ËôÊË•W¼äÔ§`<–á|öX^i/�°ý¼O–UfjjäÔÄW; =4ßìÿðÐþXAdˆ¡�40Çüð(>ž˜›$:ß)~‰É;_QM6nBD“–fóßÜÊZWž¥ý mÓ÷E"žô«ë¤XèZMóÚ)à™…íÌì ’¶<�ô,ñ^ø-n¨kh°Ø-yËV�¼úÉÏÎðŒ—š€!u‰1±±Ï®¸° Ÿ|/é��6Ì#ßøÎBqã[þþ› û+kT'AÓ§yߤ‘õ§¼S¬×bÍVPãÅi-µ®BñVŸ’"ßathçÀÿP3ãh3L&ÄmwüŽJqÊ��y@?6–v-ÃŒ_™16äÙ´`ªMfOð _¦ÜÅ÷žðbv0·,›aïRðq—Õ„Ú4ò‰Cí®en—ÊkgÅ•2•ytÚh&ôs�7ÿ dí{Jòξ#µ>ôR„¥Ÿ€©Šçc ‰Ž‰é±[ñe€žÕ§‹µx7É=~ÇfË¡*yÃä.æhÞJ|¾Ü?l ]_1Ë®†Ø©n«ÄádUø”}¸¯B^Y_ Ò K¨ÁËÃ/Nô2À†õ�ötbY |x „H'Üs< ÕÅÓ]˜ÕÌ ‚Ó‚Ùû´ò®n»�gUª!‡ °~èLµlØí•Ãçª0Í}�ÒIØ;ƒKªG{Ë7�—€€A:A Q>1b_¨ï¯q4Ú dÇŽ2wî\á”Çm {yÌ¢E‹Ôy™™™ÊàÓÝÜI( 8PÛJ&¸�R#FŒPžR$ JJJØké„Aù5,ÇâÀÿ¶*€CðÄ–Wx�¬Gù®�ã! ê&9X'ñKâ‰eÌCÑÐÀT$ò|)@ é´Äº$É3KR\óÅ“Œ]Œ;¤ *Ç€hÛBôNèý¤¨<‰Bç„öDwMÑbðv¢Ç¥½¼éy æOmèþ|6¿k-¦ô‹æ­î3¦žvÕ×66zâ­µ·Ý7®â‘OOk7!y´Ãas¢NÃ×»Óf ~¹^½¤7jÿAnùÒ·çKB¢]Þxñ„”\CŸ'î<\O½ú&ŒÌõn ¨:ï!^'«y ¤‚t�wL—’Ê}RX¾žP¥âóùÌœñ1™$99¹2---ˆƒÍS ÖðXŠø>I<ˆó¤fó­­UŸõ,$ð=à,ÐÄh–0mpöx5¢ƒÙD/üîÚ»±xÿ8;¹zÙü‚V�²µ»ãrFš½LùÔËÈ ÎŽF±.à——è¤„U–]!žxuÖ|Ç�?¬81•i£l„÷ÌÔ±)ü©ˆ.âë|l…G8#X5¼j*«Y2CôH„ñ!êœHÿÐ }Þ»¼o‘’²ZÄ|Ê—¼3oÉèÔï#‰ºH“iù8è×l²bHÝÉ>ô4ðœTUäÁ›KK—êOI¶ª!„+0{ݘ´85 =Š£[º-§Þé­|ö$�Ê«eóq�N•ÉÉ‹œi &màšIÐǪyñòÀ§¤¥BÁÐSxžèÝÙ÷.æÖÉKï•Ȧƒ˜5±0‚…^môæù%p`oË�–$dàQàKÀ7¦§|ŠtÂpλ1Ôq,†}Z”Ÿ.Éà)ÚÆÈ¢. Ëd×Ñ*ù`O¹ZÇ댫ÑLøá? P7oçƒt‚ºYûà_êû?€DÖa¥¥¥tYWCë† ‚Ím I£Aƒ©âtw/..ÑS/¦ON¾n¶»¶Rc¬Æ€à’FdQQ (ι˜üð, �õÃJÂ!¬ù-ìgl½W�çƒx‚ ‰Š«ñŸOEjI–Ïé„wô/•‰DKù-MÞjétá›Kr$Œd fX¡tEX¾< m@ƒo†Oò ëe@J¬2¤HLc“EðHÙ¸CÕðûØù Ùu,^VÍé¼÷ïeHÿ8Ì^æ�÷w0€p�ä�x]Oy¢K�ÇÙ B%^X+ç·ÿTJ®’Æz¶ýXÍk¤Ós< xœ2AÕ9L«1œè親9n°Õ ™v�tZ�Àí‡Nc;�$:Áâ´ÇÊ’™nypq¼ŒÎ|ž5ôDaÞBÊ}~Ùo§×>,–œü&ÞN´æéÅÆój€ž�³±vc„=.«€¯·ü­>ô¼¯»mº¤†× ÓH'íY´ýôÀìW‹è9V!ö–Ë¥W éÉëB=ì^6�„­d¡Ï­´?YÀ“ÀH@y8p@ Ã9r$‚ì¶oòNDW„†$I/’ZÇ�—ÂÂBPLr(ð÷<°§²-!i5°Ù¬pö¿"!°š�nü44Тf`+‰§û›Ó6Púyc�‰ˆhC�ÕêMÖ­$ú¶Ð­`7?&t¬¶¦}q´³¢ý·Qy;i9Óó¡å¶õ¼1áCˆ1„4¯æhç­¥ô8ÄÎonPÚÔökzÕóCµÓëØ‚ÆÞ„)ƒdéÊQ ‹–�ˆ’–`q8â`’´_¯µtÝ[b°Ý'÷~|¼ â‘?>¹W޼ŠÎ6c&¼[âùö²›à7œuŠÓ:ZìqC$Éq^Š}ûÅ[uö6f×nh0‘ˆºpáBâ˜1cª€ˆï€¶=¥÷îÝ«bWâÄàŸ�wÅDaÙž¨ÆÚZ¦:pÙÝ%¬q8ô. l'†ô äSxÈ=z‹¨GØZÖ=d×îj…Bk5xø:Û^×gß™ùX*ȧÀEl`Ѹ-^ö«„wT½š)ì]LU¿`J×¼Ÿ,HwÕ\b•+¯*ïµ ’—ñŠŒ˜÷O°çÈ¥tL8‹]mÕ5¹´÷I¹¼ÿi¬—¢A©Ý…Û'+æ’ÜñȈA¹Câ‡dGw ÿ¡“ÃÁjäÍM¥²ûD9fÛ Í´f‰3cØŸG\¯¹[á*K�äœ.±ø’ÀKWž®–×7”Éž WuM¼�Ø@þ3ð+ ˆ¤‡u›°þ›�tzpÁ:Ñ…@â  ~ÿ"�Nê¨<è"x^GwþÜÂx|•Ë»Ë%'O‹‘Õì1ò¡Òóäàe`'@�0ê¥{8.`H‹ ŸÇ§�¨ �Œ�À^D΄Iì&ž !Å!{ FJ¨+W®Ð8eÒðï;0diÃ= ´F@±þŒÂ%?Hvò]4ÄÐ@W5€/¥,þXj2ÇZ=¶áŒï$nO,¦Z£«yå†*³™h}íM7jG©¿$†º1ˆ·\œ×'…ÿ!i=oú1¤¬èíÚ3µ¸îíÄ|…4«k‹ö+õ��ÐOù«©²xÅ(INqXIjGÀ¥ë·uË/ãâbdÎÂ!’O¨§½[vÄ™ðŒ@ä·üƒ¿Q7ÚŒ˜PÛ$xA�–FVx7b†¼ ´ êÙÑäÀ¬·V~ãi´%ÜOâ‰�Å·mÛ¦Çyb§Ò÷�¿­Ù-%«6ªîÀÅéúÔž?$s§gQ[‚öË2Ó ïdà>n£qbHßÓ@°¡Õ÷nݸãîÒ€ª„š&V5ÝÑ�_dâÿæs€�ðdû� ¹s®nüZ%ÆŠlâH+—|°«Tyëd\¨@¨xY9»óÞO$giÖx—ì8ÂàÕ"÷¬¤Ž{@œ £›Äfjó~@H˜ü±Rvu¿œÙüoríÒV¤Å¶.*`ÜÃÌIùôÊD '´ À·FàéGm¦Û…�4<Õð¸+uòÖæ25<®¼²�[-ÑXdlÆ—<´$÷� Ú˜É�y"ñ¤ .=³r1cÛ›HƒdKiEm0 ìÖ½�~†uö¾ð¦C àG îZ_žØ0·JH´ÍBP÷G@}ê‹ØH÷ÜÞ³PC ñ§¤¼1®ÊeͶ2¹ �X6驸Bo`I£à(@©ãL&N2$êàs8<ü'ð0 fÂã tˆÏ S¦LÎtד’””$Ó§OW3á]ºt Ã`ëhœ¦Áèü.–ÌÌ3@A ybywᦧ]ð×,�†èŠâd¶_@d4Z±ûé;z÷Ó±™EP+fM«Bl†4§sxLÛFƒne´¤º@þ�xòúõ;ž7^ gƒÓ¼Ž:pñJï*L©‡³®×*zŠtBVÒG'˪ûÆË÷�“ÁCâÅb5LÿÖT›gÌ„ùÖ÷–ˆÝ‰™ðÞ»€ÉAê42±µ“Œí†:«õêj³ãÕ6 cºŽJ�^]xN›1\¿]≗Ö=ž¶lÙ"œ0T´âÿx (:"¬¬ýèô®÷7˜0ðNlþF8¨@=£ˆí·€ŸUq”D-Öë1z¢ ¨A«�ñ%iÛm&qXcÔºª¯°‘î%Å�>¨ã Ôz·´`të�c[Þ…Èh‡3Þ8�–gW…UÔa`;pg;v¾\ŽœŽ—“mÁ â–X¿ÜO•�G*”÷S¼wÖ¼Ÿ,(íaœI‡òãDÅùàÒx9pJ‹)UQœ)—÷þFÆßA'j+¨ºÓ5ÁÛÉOÒêøsraÛÏÄW–�š]«uS-ò‰•IrÏB§Ä»Ìj¶³öˆŽ/Ò��|>œ¥®qˆÖìª�wL<¯X›m�ɘña˜ŒìxÏó'YÅí4«^Šæù"ñ‡É³d;’ÿùýb9—¥$Ë ¾¤ÊÛé7Xf7Úۉ㠾LH:©âNmÌ0§šµï6°ç=³¼4¿gßDx2‡VUûAtúä ÆÈÂ�ÏZÌ\׌tâ¿ÐÛ„1�ÎÔ‡V°bH¯Ñ�/>«/^àq –„OVV–" ¦N�Ún rœUq»Ý2yòdåyuîÜ9x'Ö�€ê{XÎÆÅ~ ЃŽù׿ ò°ËÇ25°1Ë—¾Ÿ†è¬ÐM¢f£ý–wñpû4{ìé ž–ƒxH7¼86¥s´&Œª‚Ç^ÿ-å1!"ǽžÂÏ œÞ……ŸU€žjÇó¦]\‹÷DÕD"ô\âýiwÉ3´ë·N^ñHdz tÚÔš®#N˜@)mX¢Üõàx¹ûþ 28M#�šÙf‘d°ÏCû‡3á}õïç+ÓnËzP5Õç Bݰ ÷5 y’SòŽTTçâ]nTžÎœì¤ÿþíæ‚1ž¼^¯òx"ñÄ8“�g�ß�ùÆsx«ó{Êb÷ž¬TN• 0hiÓr‡²m¹€tòWÕú×Ãqé:Î*®ê ­fBÝ„ŠÇÂ!vøÏóYÇÅà=«ªÎ|Í�aHЀA>õ�‡Ü�[d�  * ÍÒ7D¾¤7 òaô* ÛÖ™UVˆÏ+€‚НÛé•™¬ŠìR•"ŒÒ éVY0Õ‰ÙÄ´ØOÇAì=/˧wÍûi¼`–Ìpó^UðXÊ9úª$�¸]Œy†ÃRµ P†–Ê¢3raçÏ$ñ¢êëx,Üò¡§éc=òùeÊH¨*£ÁØÝ¢ÇuÚ~¤J^ÝP*§.!˜x€(¡a:j¨žNñ²x†M’\1êk H»PéÀ¬mh‰ãàKyõòÖ¦2Y�8[êFÔлi ðëÀ’¿ÃRÀ¯ž+.·ø[`9Àßxøƒ{îŸj“û0dóιN韤Ý3G*´—cxìé9|²ZÞé´7C#'ÃôÀK�\: ¼¼d$�zàiã*†tEE8ù»ÀeàÛ€‡Šª‘Ó ³Ò`sωÝn—±cDzgSΟ?¯{@ѳ‰CGéÝô€”.,É瀧€o|Ÿ>nä;‰Ërk y‡W ‰Dþd%´%âL Î1’¿X–áø¤±ŠÕ‰Þ)‹›N³ âU¿´ßêØÒôî �ÃØcÞy E]äº?Œ™$ôzÂRO[¿n¤yãq´CøÕWw$É®»œÚ ç©««m<�T”"Øüˆ¥¥¤öñ‡ús;þÓ4Èó5áìulô¥$;eÕýãäþG&KúÈ$±Úãšwê§ËÖ4ûf»/{âýÕÉîÍ™°“àG#ÉCQÒƒK�¿DrŠß‘2Ä|âp;›Í&óçÏ—qãÆ¡-Õ6‰ÍýôÆæÌ¼ì Oo {?Zò„Ž$ççqmTóåüs6f©Vªj´ß�¿ØÌ šÿÛͪ�ؾS±¦Ú8ÆØu‹hÀ Ÿn‘¥ÛÖ�ý¼2òN$V¤¢UÎÐÌ—�À~`�Jé‰túR‚LeQž&Ø.Vx?ݳ0^¶®«®Å~Z·Ý+ó&ÚÔp6‡�›Õ$ŸX/‡Ïø¤ ¸Vj«Käâö‹g†ÂxÒàÉĺ:$f³Eê¼r9ã5ÉÚõ¤x‹ða c·ÅÊCKä“«0 V|,m¨oÍ“Š²9|à*§ëѺ¾Y7N¹I4@r¾Þï“+¥k¤Äwå­.èñ4q"&hh‡xâP;’M .Žàäª# ·Îoü¿—­ÆJå]?øÞÌüñÙ´õ ²Uìeçð~þŽØYáZª¼é•ý_@!`HÐ@°ÖîÕ¸ÅÒ{†èN&¬x¢%»ü"0� –W6ÈÚ�e2adª2²XIb‚Äh²Ê¼)Nùh_™ò&:|¦\y?-›¢Çó;"†=zˆE»3Yž|5¤M£”äeHÖž_ËØU¬7yÏÈfŒæ*Ë; ¶ÿLòÏ®Go$êb$@ƒfø ‡|î¾dÌ 2 o`wg®8£DAqƒ¼½Å+k1 ±¤¼NÍ|Ãû·!þòY.ùÄí 2* � Ÿ†–Æ¡‚ç¹l¾ÔÇZL³ ¢ð4óXÒ.Ià±yrúr­¼» ¤Óá )ñ†t8�Ÿj/$ž2ƒt‚nbáÐ;–ílàG€ª***„�È9ü�½”4{J0ý²ò€¢ñIÃS ñ ˆÕ‘Œ±v:�–I³¿ö;°j, D¬~ËßVàKá4›¬¦xX»æŠË’Žw€N¥,n}ɯPH¸5|KóßÚyáGð\x!¶¾æM…Ÿm’;<>RÁ£†°iÄÿ†_9’¼iÇà,•?.ÃShž�xÒH¤æ{C¿µ|‘Ì¢]£ç1hgTß-x; š lªÜùàDIíçjî}JÖX‹XŠ€B©=.Åô×_›-eÿ±M.ž-V¥º­'ñŒû°è,Ô(囥¤â8ìÏZ5«-‡ÚMš4Iâ⪣ Ö‡í,¶AŽ9"'OžÔ; vA¡$ž.íU0mé¾;lR6tÁ¢ Íu}I�=ï<‡dƒœ³-@{ƒ`>È5¤öLØgØúûXß4íÁÇCnM °@bh@×m(Mºúemz~Ó_ú5:·då´àð©1œ:xû¡rY5ǃ€ØÖ ÷“öïýœùîh…T!¢]†è½»µLæbˆI”6êô6sÅîXàÀ¬pÙzÃúêÇé¿W’‡®ÀÇ ¦ŠIr2^�s[~(¾ÒpN$þ5’gå<�| ÞNÃûÇ ‡uâ ¶yÍ®ìdÇ :DeëaÄdz¯XÎd†b21®ÁÔÑ.yte‚Ì…Wg°SXÍ>Y4Àbqì¹ìZyéƒRÜ·�1L TZxƒ‡�_ïÕ@³T°¥ç„=,Œëô`"À¦*ƒ*®ÓP‡<„`â‹§ÚÅ�[|í€äR©¯«…õ²1²ÞßU&×JjÕpE¤.ü³çé·ÀA€¤Ó�Ô.oH”4Àr½ ¸ üxP.ï4þHþp&¼öz+yN´ÄétʨQ£0,¤JrrP×h› é p?Žº„ÞZ}‹±44™úã0–«Ï£:ÄZ­I’âšo§Ãj—Õ¬VÄ´¿ªÚ ’9¡=ÚöPaÔ~ãäVè*zóv¢Ïã™É³ÒÓ%Ï@ê!ž0N ©C÷7HfY2·õ9¦´¦¬º>jÂ9t5jo7VOœIOÇ•R—Tç÷|j‚ hƒ¥à,RcƆåc¿µDîùð<5:ˆXïº\ú\û› pD¡ÅÝ�÷Ï’‹gkä‰Gß–êh£u¿Óª±¿}ÔŒ7µŸ’ µ¯bž:•š®ûK–,QñžzÊŽ¸ÎŸ?/;wî”úz©ñ&Ý/øÁ3›cðl�aM#¦[–ØÊˆÖ@îFÈ#ZÍùUy3ÌÂ¥¦5ÉO�G€ë¤{çþZÙu "«Rf¾ó{crÿÍÙº7=öÓõó®.ö­dfOöȰžùÁ¯/)˦Šc›ä‚‰Ç.–Cÿˆ§j¥¾pÐ ’§D>tK¡”…µù|O®]*áUü0&gžxqGŠWÉÉsM �bMÝ…xX¯Ë¤Ñøº‚ëd0k1(y¬›ÞÜߤ\ìv¨Ít±»ŒÓ~|8ðž Ö£CW�åÀ—€ûZ|¨¶�u‰„=rÇò î,ÎÆ ®%UçJK=¶â{̶½ÐH'ÆkmM³øBîªÞ[±üO`-À‘¿âXÞ8‰êýo€÷›/ånºÞ:tHÅ` Å ¡¹Έï¦”ФÁ€ÿ X J°Ò' ”âlZ‘~¸�’«Àåw‚xºQ|£°[Ùç`©46«|àRÝ×H–�6ÑM®>Êóõ¹z;=Îᤅ)qŽJÌs³%Ì�ïV*c•©.£Þ毺.Žëuž’Ü£Ïå× –©ç8OŽä�ß½º»¯hŽÚ‹×Ú0è™;Œ|ñk+eÙÊÉ,Äw–lª†¶’Ð(5ϼÇ_àøð§Èñ£Õ²qbí5·Y*¡%»Ò; ÀÃ\ÑùÚMÒÐ|I:„³Ø.^¼XhÉÜ“�x¢»ÿ–-[¤¢¢ÂXH=�t¿4“ÕS&ö¸ÕÀ kÀ’Oƒ|†Øåóiørºûð]ÀQß·:Ä๮wà ”[]B_ÃØO ûiG2öÓžƒY™BRõçp¶·{Váò× ‡Þ¯Ç gƒyýÄkŒžWz,/vËW?1FnY„—PœŸIòôçºÝ¥á:ã÷øÚjÄ#ª‘�%¬òƒèÜiAùÌš¹þ¸â?¿+†.‰­#oÙׄøPQy „KÜSfáãh}=ð×_fiáÃññ`J+s¾=”$¢”x=.Yµ8 »°,˜æ¡¦ëÜù‡pP°LsȻǛP=*¯Áâ‰3ù¥è€ù“`z ¥Ó¯²�Ùüâ„ì¬ q œEùøµ‘ÏÿW7­�LðE‹õj0‰tY‘1cÆ(—¿}ûöɹsŒ«]ðø'Ð|x°b5Ð Ðe™Ä*ÝK˧» Òi9â;­PnvšTÒ±’È~èmœ Q�`¼kД�ÙÇ}Tÿê ³G'™“"ª‡IÛ“r°«Úê©«´¦$ú/�~å$­¦êef¤ëÆâ)ÒI»Îé®’ùéµÔ¼�–ÒËd®Í£üŸælvK®Ÿ(_þúM²èºñâñ²´2ÐÀG+Ʊ’ÒBǃŸ^ 'ŽTÈá—Õ}4÷h Ë`óÏ Ðꩪá-xlìǼU‘— .ÎH=ͤÈãlöîÝ+gÏžU1Ÿ ‘ÍÀß—ó_;¶#E–|)wºwõ4Ÿ{wöàžÅýç�½À"{ÖÉ¡é3ß1öÓ=pµÚú6gvë�Ä~ZûF­,Aì'’5úý¬ï‰�‚U\ Ÿ„ûÝÿùa£"yj+J]åaæ*°~øŽR¹}‰³¢a˜Ùùƒgß/ÚM cíôÜ›uò³*åÜå¦ÄÌkŰü¹ÿ–"Ì膇b—rIÌŒ5E]0Hüñ³­ò3ÄuzmW�rÓK!\8V> f¾‰@IDAT| x  O!‰¨Á>§S�Ï&t3B-@ÀÁjkጠ|ÁÄ—ã>ýNEõD:1˜8ø'.¶ÊÚ×kå¥mµR‰¸N)n†Ìžz8üx A«/+#S†€"ù€—Àßÿ}å‚wíµ×J0Ì™fÊËËÕTºý�:uÊPìçïH@}°ƒT(ÁÊ5ÀÏï°˜sü:ÉehòèSçð„eTä)A`q—3Œ]ÉN��¢Õ«U½Oo›½ÉóÌùf‰7{EÞÐŽ(~v7dŽIuUKe…”,QrMçšÜ6¥×�¿î%xJÚ‹ã$äøgÉ|3¯ÃÓ÷™mîÕñcró3ä‹¿¿Rf_3}]> Ùâ•ËãÆ çb‹—Œq|à¾Ùrñ&©¶îwy|KsZtOÍígåbÝf|ä¥Ñ´ÈäÉ“…äŒ÷$´z:qâ„8p@Mr‚ó’ 26¬X e Xòi(ß�Ü—M=jÀÃñÔ‘OîËÒ›+Và¤ÿñäÚ†vY·­F®™N-$ÎðÈusB²e/¬Ÿ@—ì€ Ù�ãY„ý-m™CA“²ç%S®Bü¨»Vɳ+12�ák0f�_ˆ2xå¾ aAƒ³ú‰ Á{Dk§C§ZP¼ V:Ik'’I7, Ë'ï,ÂìXEpÛ9KºØÕ5ÂMïÍZùÜôÎ^J‹ëÄUÀSÀ¿ïƒE¶p¤=ø@Òi� �Xßiüp¯‹È-×ù¥4¢ '¤hØê,´”SÁÄ+ðül¯•^¯‘3Ôž� u‘p£hí´ 2NÁ+#MçPá¿Øý1P ÊÁàœ�†Íê{úª‰tYÆ€¢ ’’€ŠÏ‚Çÿ“‡V¿ÐÞß>»P‚•4 LÅÖç¶±ñ„ÀÉ!~ß(^%ÿ"Ob€îT >LæqÒm…S•˜}'[6ž”6øççª}ðÊÙ ˆ`¼5•³Õk¥¾ †Ð†òcg·ëÍ*OÑhT¶mÛ&555,#£ŒÓâiÀ�_V¬òF–|Ê›[5àå('A½Ãc)1XêוÓdzÕ¯ŒºMDë'Î,öU`ŒšùnO½ÜwSXfMò$âzr÷ª°l·F $©6l¯‘3’$U·W¹ÒAÔÑ�â>³&"—@\:Õ(·/ ˧ïŽHÀçÐ³Ç à·’Fµp7|a H£—« \[;Q٣ʼò‰–È]7$T$X¦µ­¥HFí=Ò$?y�Ú>W$\’÷®YýøÀŽ.vX#äÞµ�t|àKÑ,€Ï*÷+—ÂÑ&¾fEDîZ�q%ˆe%(³¬d]xjš€«RøªÚyeg�<»9*'Î\1˜øz$&ù¶ ,=¤•ßn ) Кè»G…Œéã ûI \[@ËܹsñtæÌcžÿ_ù€MÄ÷K@A V”8\Ð2n5ZFX?ÅVÜ+‘™ÊÍ.à�‚l âÄ#CÖpi„k†x2„Rúy<ƒä ó2gÄS´µ.ò0þ’)±./÷ëÒ¤–•¥Óçë:ñWA•“å§p_W‚×K’\ 2IæËéº3Ûº ©%Ò�ÅG#°ø§>¿LÖ<0WJËXüJ—ìªv_V5€qƒßb£Æ…÷= ̤ª %�ܾ<$÷® ÉÔ±ñ`â8I�¹¼‚�xkBPö-x~ùJTÞ=Æ`âxYà•’›Û�ÿHrÒNÚ~a‚¬t©Æý¢%&ÿWþÃ#c3ФžEs„¼´´TMÛL˧”P!”‹Ëøà"�þÔc‡•¥�rÔö£À€y€|cßézX;-„um»“� É ­˜(f›{ôYfOú–Þ‹_ã®ÆÄê�7Z”Õf¹35`é)ɘm³LÖSÕ�ª¶ÔB¢nȲTâ‰T“¹Â•¯cŽ˜ër‹™:­T¾üÇ7ɪ›§J0äeQ­ ¶”�¨#¶òæÉŽ=ÛÏÈ3ÿÕ µõÍÖúi°ï˽>­ž[JEÝnŒ1i°¤“ƒÄ#ÒÁ�E´X懪LŠÄÁXŽT³Ú"õ€ÖÖüèeÅj ï4`ɧ¼»eV`Žx̧ÓúiÓÎZ�|‰[?áêE¬’‚Š|")t©²Aµå‘ÛCWÏ&€h �(™Fjg~H¶�4©ªé�çÞ¨‘§6TÉ%�mt+ã±±å>ùø]%rçõ~ ¡¾ídRÔÀ>yqZK]¨l—§^­‘—Þ¬‘Šê–„…‹Ð…蟾˜òeš/©¹*rÀÙ iíÄ â@)˜u�„(1£�Éu`—šxB‡–9µlzwú^í&¨÷ñW;"U·ÄºM\FÒs4{»_ÒÕnúôùÊŸÞ"+nš*þ@Â0½û„öè€k€ÿ8fÀìwrσs•ûÝ;»/`üaHÍ/‚½@^i–K0˜ï`°Ø9vì˜óäÉ“âõzeÚ´iÂIJÊÊÊL?­Î¤»'1Ùµk—462l£—ÿ–‡�dcÆ#V¬òD¹ç‰BFx1ù‚¯„1p:ÊÌÑî—1ʺ˜uŸºÏGÙøîžøåVªj[•+ÚœÉqë'Œü8ƽ3Ü�^ç• Íö“õ;êäî…â‡[^O¤óíVx�nO¸ºƒ$�š`™óÆÞFyb]µì?Z‡ çúŠ :zÛÒˆ|ꮈ̯­�hÝ•*œÅŽu|}o“<ö\¥?€$Oass³?~\�€Ìœ93§_ÈG�¥š å¡ßH’}à³nŸs(a„ÈhÔ“ÖNŸ�¢¬�ŽG¡o¼”…–JÈ?ÖNˆS¦F|,ºz44-“ÔÏI5t•FŸÍ™ßeœ,PÚ¯S.p¦\™å5cÖAŸ£í¸’ur*‹- &ºßtðqW»xmÓÊÁ æk®f¶©;}%¸è€xŠäw¾v£Üp£%ž:)p쀑 áØŒÙeŽ;ÖÌ’ÓÇ£RQÙ�Ó¶}¨Á¡ ›o¡gŠçIUý>iëÀ7s41´r"ø�ê�wÞºÈ3”#�xª¬¬”íÛ·›8O¼?ŠncŒÎë[±¸j XòéªU8¬2Pnw´,¡kWÚ8²OÕäÀMÞâÉ’£·>åÓë“ù9àÓE ½yO�‚¸KIÉUÆ¿ù1ð8p —r ¶¬X ô^tgc›ÄÀr|¦ÝõõõÊlÞï÷Ë„ rú’Âiœ),Cmm­ZÇ- ¾ÐÒ�ÿÿç+Ã[lWW¿Ü Ýípº BRR¸“4,¯k ºölþ °ª¶ iÂýɸEɦRïOn«dÈ%5÷1Š9_o ä/üf–+y}?ŠPB¹§).¤ƒtO¡�«ãæ`Kãj—¬•Yc.F¬}ºîÌ6��x**ñËß\,·Ü6M…üþbe(jÿ&0 tÈê53dÛ–÷eÛ¦S*6ݤ¬X $5Ð!nGXÆ}DÊ —KS{¥´¶\–Æö‹ÒÐ|cúJEB‘hÚ¸qc ýt VPN~0b€ñ‹/ªãÈï àû½¬X ä­,ù”··.ëgo�ù„@Ú^—÷_8äÊ¡p´ø.ð"ð1^ûRe‹<³¹Fþà‘¸õö‘È¡ëÝK°z©khC̸¯½•• }pgÃ04Ç…F‘®($ÿ 0€9y±MžÙT#/£Ì•°è¢[!%ˆéݰýàê�L…ÛØ—Û‰¤&`A0ñfÔ·Sõ™.vÔÙà�ç�:€/¡¹/.È— ¯·ÜîD:­Y–ùÓÝâU–NéuÅù�DŵÂüþå6Ùðf�¬G€yE:¥Tgº&àYà_��I§äÛ6¬X ôS§‘îß�ñÀý€‹³Ôð 'c@‘ÊÕK ¯Ãëq<^ŸTÜÏ�r}à`öG]L­ O LBµ>|˜¢ÃEk§�‚”…WHØ;�ø8¢ÄÐ%z$À_îÑbFé˪F�fަ¦Sû ÑÏmÀ*𷮯¥<âÈÄk¤‰''>T°~¦ŽºTzF;–ƒÊ­žÒÓr‹W è+©Õ”£�ä²�ÄS1ˆ§O-’�~úZ)´1žRô54WùqoôØ�Üyß9zಜ?› ÷‡f�m©El} ~)ðÌR_}b~쉵JkGµT7î“ËõÛ¤¡ dTCƒcëÖ­1ôÑרî:|ø°"4QhöÑ œÒ)ì°b5�O°äS>Ý­�-+G@´>QÃ%\Ѳ(YÍì å¢ÅΣÀ‡+H†—ߌÊÍ‹ƒ²dŽWÏâJaö/Üï e,€0Γ½‡êd뾈ܾdhX?q6ÆuºTÕ./mÇ l¯ÕÈÙ‹M 9Ž]¿0,�¬.’ų=ŠPãàÇtE©–R¿F\§7öÕ)¢­�¤ N‹ ‰&êŠÄ“q-‹ÊÙ‚Ÿsÿà‹yH´G$×n\ĘNÚÒ ³L«XZ=º×A(ñì%èo[­¬C\«³—`éÔ™t¢;Ý[I§ç€€V`V¬²©Æeø;€ÔR>N~Ýܳg�Šï0f̘œPŒ+Á ¦{÷îM% Â(Ûgó¿€U+ÃD´p#Áÿ%`œ>)*¼FÅvò¹ñx*RE÷ì°¹–Þq'-wpHKéSÛ™iô¹){ã®kš˜IÙÏJP7°$›èƒÏ5LX†«uˆSÕß;ñ¤÷¦•ŠiU¤'œ®Îí¦�) SV™P]³›”Ê⩼< ý̵òá�-Æ4ì¼mV†º8fã‡ËU·N’×_/•/APè¶œµëC]?¶|™ÀX<Þ88nñ8Fɨàj ûf˹̆W·ŸAÅ�o¿ý¶ú@@^�\þØXw;(ÁJ~k ñ²—ßÕ°¥Ï‚Øjò k!?¾f!Óxñ¦6{v‘‰ƒ­ÀÓÀ'x¼º¶M~þJµÌ›> ñ+ôÁcÍʈ¼±»–OíÒØÜË¢¨\?ß« E³Xi–¡·‚q±"�êê;dãžz�Ê‘÷¤ 8³¦ÊC·ÉM‹|(îTä™ nNK|Æ–S°ô¡¥Ô H^�b)/G+–�6´úÉu�QR™ ü6ð`@W%·SnX–n Ë¢™ñy𺒰'Ò‰úaœ²ÊšvÙ°³AžÝT-ïŸ×¤]†EŸ“À�_t�¢^¬X „ø¼íþø{`& ¨ŠŠ Ù½{·,\¸P0Õ²"„p,'2eÊcbÿþýRWGZ c­1>ƒ�oìÿ”�ç‚VQ®ØÖ~†Nð§‹ÁL¶}] ¬�–KiáR|À`·�n@‘/©“kÑ�I˜ÔmîÕ{ôq3g˜|ô¶Ù›L�SÍ“ ¸ ì ü˜4ªgJåà>–•$žL YâŽ8a¤ÉªžÊ««£É+•iüGëæÊºãitµ3.$ŸüÜRùÐà $�šQZjfv}Hj÷8)ò;î¼o–¼ûö9}¢*ñ$ ÉÛB ®t£/ƒÞð¹'ÊÄ¢1Ž÷ËåÚ·Ð&¤uÁôJàû:c4Ò´.-l[±È+ Xò)¯n×€–C�"u¬…1[Zš7fÂV1ã…_e›ƒ~ø'à`-›v½S+oî Ëêë´eIŒ3<²t^P^ßU¤Æ¾#u˜ù."\–{ë'ê‹ÁÄë@‚½¶»QžÞX#{ת˜D$ÂHJMí—ÝŒò]�ò"†Ä¬Æ»CZ�«@L£íõ²¤Óé IK)œJagõ2ð8°  žríbǪr6¥‡~�Ÿ �tâ~E¼Íž rmuDV"0<É5Þ«žH'&vAõM1ÙòvH»j9p¬^[º¥wϬïAà1à)à `ã:A V\$y_þø+` ¨ªª*E@µµµÉäÉ“sú¥œPœ9çСCÒÔÄâ)Y‚߯—´lj¬ä§JQì€/ ÌDÑîp»‚°vš\‡™ì¦ˆËI/gM½`¢IMÂèmýkö¨æZ5ÚºyåoOiRóÁÕà§ÝÜtZ͉tEvéJÄ{!–‚$ëC‰Ĕ®oOÄ“.?33&ëf\ûL^ÌQŸÅ_ôs¨”Ž*”G`ñô¡‡"Ðx"ú�ÎÖþy `æàxméŠ ²ô† rù<>n6�<àÍŠÕ@o4€�n|yÁÉ'ÈÅú­ÒÐxm…ê†i�üÀCÀw€'Žã­X ä¥,ù”—·m@ Í^RÙysÅŸ=Ë'f—«˜­4c?= ü@êAê<ë§¥p½3³Ú"0÷½7EdûþZÌס¬Ÿ~ ë§׸ć±xO„ó͆н®#–×1ƒÝÓp‘{ë@­4£<æú¥E¹q�î]U(“FÃ, caE:é‘«"­j;äåmuH_-'Ïu²ô¡yî3;«íÉ–\“N¸¤"5ïÅòóÀ I'õÉ™±­&”ûåÞ["rçò€”�\cõ ¹†Õ+ŠühK»CÞ~¯IcßÃæVŒ=%-O?~ œ,é%XÉ©8P|`E+¨Y  \ÑhTh^Ï äœ•.1 p]uP$ÀΞ=‹¯¬ü7Qr?~ÙVÐÊÆR*É«²IË€/w ü.§Ó·ŽÉR¾^BÞY0ø1G*©¤;ýKFcçÍ}f�^b‡êÖ»KÃ3µ0'“.±4ÇÏÌ…"œ`¥?š±„(É*ZƒuEZu*,jŸá.Yg­!­9ê0S؃NŸß%¸{ެùÐ5–xê¤×üØ¡e<*…˜åv߽㌜|“|`'õ"@*ñv‰õ\ ;È{€ßV$�P=(�„A®Ý–ûn Êä1nå¡TϺv#|4éqøT‹²ÛøV�ÔÔ· {Z"jëðð“øº%� +ƒ¦Æ#E_·o×.ÿ¦ e (l?‚×;w?^Mã�)¡®�„„r^‹}´‚µä“ÑÊÐ_²Ãž|ø0`[ëðp&»ðuR¼A<.pQ$VTg¢iýKr$s[Ÿ‰“q„Ç4y¢·ùÛS}uúÌüxdI¬�ʈ¯ôŠxBÔ yÉŽ‹k&+]Ãκã1ü?.X2Áªg« ÕCH¶(}ÔÇu¿,\2V-'N×JS³µ~ê£íéÐÛo\£ o‘"ÿµRÙ°SÎE7 GÛyŽ«¬õ”`%?5`ɧü¼oQj> $Ô É™¿OÛí­}þ@l§˜²~ZµÐ/åÅ.|åÇ*ŸS>|[ÖF0�nn—fÌ|÷«õU²±ŸÊÂ:žÓfS8°¥µÓåêvY»¥±™ªåBIS z]²rQH€‹]=œÙ /ŒŒyDaz7Ò_¨lÇ,}µòÌÆj©ˆ¶$H+œBúåMà{Ào€(0–N$1?|¸à×xE:a)^�®']ìæOóÀ‚KÚL=yNW‚ªƒ r`ÖºVY»µ^Öm‰ÊŪ–D0öx*³øðà=À’NP‚•!¡ú¸½| øKà&ÀE2ÈH¶ (C:1¾Ó‘#GäÔ©S‚©œAhëvÇ\7¾Äû0éy5þÍ8d7‡¨&¢\�ŸB 9§?å÷ ñûÆHYèz)ö/ÂG † ¡ý ﻡƒ:ßèäS� â¢÷õ/ ³09%óÆNåÞ¿À�X ”iìC¡”•k©µ›¬±É2Sw15™01,wß7Wæ/—$¾úpY{êÓn èq¬¼y²ì|㔜9M<ûC¬¤¶8C\ìŸéú[à ¡¯ÆÐ>}€ÌYñ7ƒ!^[<«�.4�¿C•±»®J$”->¿à¸ñ’ßßqØU•";‰iéó#€_€—ñ‹Á§ŸÙT+¿ûáb04´ÀTk³zGDv¾Û Õ-ŠÌyþ�(^ª™ÖZÚÌ 9ôS8ü¤µÓ©‹mòãµU ^£,­È+q 2mœ_º£XD|ûSɦmF9^G0í_�Û{¸¤âB%‹Æé§À?Ç.¹~R§¥Óç€[�N¤Ó™A¹÷æ°\?Ï+‘B=“"‰§î„ºc0ñº†Ù¼·AžÞ•C'» &Î:oþ ›!u·+VCU|>wü°d‘ëÌ™3Štš?¾”––ö‹€2¤ãI�8qBO´tº‚˜·e.«�o¯‰‘.Ö­ - ”£8w �˰„FL±nW!Ú×9BÒ)à™„¾Ü§B4á”J"Â)õ_’õ¶®0»³Ç3Ks$¹ÝuîM½–9_PøÒ¥‹®çí/j…ÙóbøRÂ~‹õÕºc…’ûTÝq€±ž®]2 ±žfKi¹¶HãyVò[Ó90~‹•–:_?^öî:‡¸z Ÿì­Íï›ãÒ“xj‹5Èùšµr1º1PMD W8^xàÇV+Vy©�ü§òRíC²Ð”Š£ �%xéø'�…Öt={¸‰õ¸ ­'_®‘?ý,_ê4É3s¢G>²ºH¾÷ÔEž"• ¡ž@¦Y“Ë•®FŒÍD‚eýÎyô¹ 9y¶)ábWòÈš#˜Å.ˆ€Ûô’À¹ü‰ëÜÄu:x²%ª ®�)Ä_I¸üðÀŽ(×wŒ–rk€ÏÔqéDâlî´ ÜSî„~)éÄB+Ω‡’òùkC0ñ]û›ä—ë«e;Ü#>¥þÈI¹¾‹åwZkÐÝn0,¾pY+V}Öÿvß¾,$uúôi´½1™7ož”——÷š€J%�Nž<©H'ºÚu!ü¤;.¿ ÅÁ¶rÐe"ì·2¸`ÿ| ðí­#¸ÈY8á1 L–r¸ØPœAkuK‹&Ц ¢» }DS#Ü“¾­Ó0mêéçô&Mj&'îÓeÀ›:ߨcè,ó^`µ¥wp6?U;Þ}´vµîbør4z\VO3eîX¥Yf"ïï|fxK—Þ0^Ö={P¢ÕMê)Ðw?óL»m5�®œZc˜¤ú9©¨}ïtäPÂþú/€ôn°b5�·°äSÞÞº¬œý"¶„x“'€áø2“çÂ/ùtEã×ac+½±/*ï +—;Z61˜÷½«‚²îlû�Õ)²h;xoÙ”;–”ÕQtà†ÅÎùŠv¸ØU ÝÄê›àìuÒÅnÅ¢°|âÎ"ïHÏÆâªfy 0r9WÑ&Ï#.Ôo6GåRe2.Îä‹ãaà?€'€Ë@®ã:‘t¢¥_‚n¸�hK ÀœÍšê—{V†å&�N¥‘ø v8ÉÔ“«] ]ì8?q®U~K§WvÖ"˜x«Š�‘r>up x øp õ“«�|Ó€! þ7 þÇÜ„cZ@µµµ)j̘1ÊïJc;ÝÒÒ¢f®£{É«††N†KlaØNÐTÿ°xØp ›÷�=ê0\…ýó\à·��qŠtR¬�#æ÷”u”„®u;Ü®Rž‹NÂÐBæÆv¦}Ô‰<’yóõvvÒ0ÿ+] ÆB l2¯Îy* Ѷ…ÙJÛ?iý* ª  eñÒñ²ôúÉk%ºÍ<­°-v¦H<Ñ2}ê¬2™rñÄ‘JijBÓËV¬ºÑ‰§–Ž‹rªò×RÕðÞÃÚ $û_ÀO¾×X±Èk Øž/¯o_Ö Ï^_QÅÏþÑçvŠÏ£]£²v…ÁɈ/[|É"îeêáÂõÊ[5² ãø‘ùè#òÍï7À¯Cš;ä©�5²|žOüŒ¿Ô‡±1ãeQ^ßÛ$�=W)*¶H.*xt™¤S©Üy½_Bˆ÷À˜N&oêÝ#ß°³^žß\¦1 ÉYгÀ÷�§�DÏ„õ\ˆ!éôEàf ÃÒÉ)s§ÊÝ+BrãŸ&� UÇtHýÐÅ®º¶CÖm«“§^Å—Ÿ‹:®a.4Qû ðCà(@ô�;ΰb50t5@2u-À% ¨ëI@]¸p!ŠAÈ *SHPÕÔÔÈñãÇ…ÖN]�NÌ“ÿ#´ ÜüØœH|YÚ�â1váo×óë‹ Î뾩Ãïžärp6Ew°¿a‹j„Ícæ¶9f–¹JÃë™kÑâ‰Û©eãvž ƒ�CøE÷üÉî‰}þ¨q…²ü†I2qrqžWÔ¿+ Ðó² ¸ÏWàXxÝXÙòÊqilªnOyWU·û®BND=il?âéWm8жƒ¯/J8ÖÿSàY€ÖOV¬ò^–|Êû[˜• p´Tø¹€{”"Ÿ’c¦¬\d�2¡�ô£À]@Aˆ 7?é#·¶Ê¤±nXèJ^�Yî–Ì É›°Œ¢k×þ#uˆ3–{nè½õSÈ“(È“Ÿ¯‹ÊS›ª¤¶®M/ÊÚiqDþÛ=Eˆ7åF§‚·Ì8ëD}3]]c‡¼º«ÁÄ£rŒÁÄQ®”Ât©c qÆu¢›Y® |«•Û�/Å—i¤‰_3#(kV†ä†k¼R‚¥“!�øêÛƒh÷D‡ìxÁØ_ŒÊ*þVJý™C=ðkàÛcåP½ÈgY±ú »( (Ž8ÿX…÷· BÎY!wÑBk§ææf¡…g°»|ù²Ú§êKl7Î[€§�×�K€•¡­7Š7 ¸ ñ´@0qṴ́÷ˆaÖÓ€‡HYp•Ëë‡ýl õ1¬`Í<ºÓÇØÛ˜íÎçô=�Ž¥‰.“/—é×é\“ŽG:ªÜ;„3ÕÆÙ5Um“™³ËeÎ5c¤ù¬ O ð‚ä‚kÇȘ !¹|©cAMEÏÛZõ_|Z\RÛòžœŽ>�§'ÑJ'¾ B¾¼4ôÿ6¥ÕÀÐÒ€%Ÿ†Öý¬ÒpT ¨qdØ‹é=‡Ï“Á—¹7€½ÀuŸ¿Ü,?_•¯‚3JaŽ�¡€SîEl¢�j!ÕŒøB´>ºnc>|kŽsEHÝY”Õ>wí;Ò$ß¶Zv¨UÍ9//õÊÇ?P,kVJ¤ŒšE�…€ÐÒ‰1¡vhR„ÕŽw‘.=˜8{ ¾8þ3@¾Læ’pá›î À—¾Ñ-3ñd8Qgv$�–ƒ¼+BÀtVM°¥¤~\ÐÁ…Ê6ùf"\ûZ–O-J'8d„$ÓV€��×t€OôÌX·b50\4Àçúe€n¬ Ð^a<ã‚7sæL¡TgÎZwìØ1eíÔØH~=!̃ƒÔSÀ+ÀSÀÀÆq‚†¸ðÐrà>à`@" í0[Ëܶ˜%t²”†–"¶Ó ló;€qïâ9éT�NÇ_M}è£&·xGtUixMŠ^vuÕW×çéšÄÓÑôɃ‡‡� RF5¨õÞ� ã…ˆõ8áX™<ÍZ= ›[ÝEEðAÍÁžã'G”ëÝ‘°JÅP†ƒE+Vq �t"ÑTÙø¦œ«Z' ­Œ¢‘<ïÆ‰'¾$?aÝŠÕ@Þk ñ"™÷5±¸ °G,gìCÁaÌ¢vûj²M¤ì—.'ß¾ 8ûiý¶(“B5Ëg“£µÓ’9™;µPöaF9n@ ¨=‡‹ä¦…¾+Æ~bpöÆ–˜<³µ³ÙUÈ¥ MžÐÚéÄvúìÝÅ2g*Þ £O‚ �CŽ�A\#X:mØY#uõm©¤ {Ÿ·ºØÑb¡ HØàb} …d$]<è^÷ À‘2_‚”°ì‹få¾›"ÊÒÉÌ^§ºÌ^¾HЀ£5Ú¼‹ÖNUÊ=1cvAfwà=û)PäR¸œ«�œk€Ïø‹@ø#`(×ùóçUL'Æ ‡ÃréÒ%¹xñ"Ú)õ_‡ÓÔ+<­Ï´|°ƒV(a ‰ÆÙÀ] þy@@ ©Í‚œN·xÝ¥öOñ4[Íbçr¨†Ý*\cå„Õ.ÄœÅeRr—†×4¤WòúÃ{M{Þ¥v† ß@ —Ž Å¦Ï%Á‚jZÖpà«&ã§.¸v¬¼¶î(B>´phÅj@iÀ�æ½µ½RÎ×n�KµoaüÏî[ Žþ å­¢­X + XòiXÝÎ~W†}"¼j�X�=ý5/¡%‘3C-ƒÝç²ñþp'ð‹Tר.Obµ%s¼`\'ì û]rû² "ŸxNskL^EÀëˆ_Ä ¤%¹MË¥“Úä±ßTÊ+ÛkÔll<§´È#�| D³µI½hm»<‡`â¿ñt¾¢91’²G€žHšÑò'WÂjÍ> | ÀîK I§Ó1{Ý­Y÷º¢>Ì^—ÈWPÅ϶Ê/`}¶aG�Ô7Â=1ñ­Î¤•ÆÀ¿ì|í 4”`eÄh€¦L$�iýô`&ছã:u!lßxàà'I'KÔB CPH*•‹€›€%À|`4ZFŽÇ@üǽÉ%w‘}“Ð/�pòN‘gÚN$G'C #ºté>)Iíèmþ²)Oí³ôvr_îÒðšæê™åÓGÌQž9<ÄÜÖÆÜ#®G¾æ’RZ«)ëF.­ S pœC™3¿\F� ÉÅóõÖõn˜Þë¾VKOQy¿êI©n8Œç"mˆËW/öß·°?O3oƶ«�¼Ö€%Ÿòúöe­ðì% ™ûK?Üîh�“EÉnný+X5’ý_àF L[6Õ#ÎP3fµó+˦ û—_ã“Q%^¹X©I¡·Þ«—ãgŠdú·r¥ã¥uŒ"D1ßÙ �"¨øÉ³�Š@b<àkg…äs÷—È¢™¥CcíD )ºî½ùN“ü–>{Õ©üQÇLõ¬u�cù]à�kÒi*®ùàãÀd€¤“ºo|fN)”nŽÈM×ú¥îuì9©GÖØê^˜‘ (^×!¶×É/7TÉ™ÎÅÙáÒâëïZo°GN§¥°ÃŠÕÀÐ@-êH‹?ºÐý>°HXb�Âÿ�(ð&ð=àe€Ä­•¡¥޳Æ×–“¾X�Œ"/Ü…É>JáN7Y‚�ip�ÇŽb|òá°nha£«úèxÓ¬H(}D5ÕªÁNm’¹7I„˜s̳mrÇÉ�ì§1¹š¼Õeâ?,-Ý]º³I=”§ë1ºñ{f\±§-Rê¿0f|˜÷{BžVÏ»—àXšOÁØ a™2³T¾{Qšð¡-þÜË\ìiÃSNil=#5�'3‰'V—ýÅ]û öç{€Ÿü¸Ä÷+Vy¯K>åý-ÌZèæ¡„äÓÕ ;Ýѣܔƒ°Êµ}ÀÀïñútóz}O�ܺD}‰T¯rãKݲba¡<³Q‰¸\Õ*/﨓ٓJ$†!#ç.·ÃU¬ZÖn©–†¦v3ª0P ¾µX¾#$e‘õ…‹d )'½¾„K�¬Û•Z¸Ø¥XúÐÖ–Vt/Û ðÂêÞ�Þ—‰Àg�OS€éĺNã—ûA:}`Y@ÊŠèŸÞ7Ò §+ 1ºØíÜ×(OÀÚi÷{�Š3Û à‡Àw€3­9¬X Œd �€úÀ¯ž�€2�3Û‰CÀÏžs°244À6´˜ ÐÂéF`9€¶ÖáГ`JN‡N)ôŒ‡…Ó,X8ME0ñ"ìçÐLÙ7¡ÍmÇš^ç>vl0õ—šÞÈ<ǤOž‘ë4©ÖUÚÍO—ÛÐ1f‰ctÏœ¥bXkIBMë[ëÖä.©œ<µøÌè±áQâš¶=k�Ï_ ³æ–ÉæõiùÄÿ[+#]1åJíóÁò¿m_OÒ„š~y¸X<|àZŒ¨­X ä¯,ù”¿÷.›%ga†$WŽ€ƒ® *ý-_ØèÎö9 @«¤Ý‡ëåÄÙ"™:3ßa›Jt½[÷fÓã¶«}ë·Õ ”_&�rÊûÚåñç+åðÉe¹D« Y° úÜ}¥rÃ/˜ –8˜FÏ» •íò›u^iÕœ°žÂõi8´øÇø’eSÆDXæBørôià À /Ez\Ä›Å@éw¯ŒÈÝ”>aš ìTA×»¸¹8½KÁ$xHã�w�7˳›jdãîÚÌØVLG ¯M­�^rI¾árV¬†´8ÈÜ < 0öƒRóf#ðïÀ€ÿ3Vr¯¾ðž�L˜LflO'ÜO‹b޳Ð3(—:XÎza]Œ¸?¾ÉRø 0ó§T 'ýý�„ ×øoœÕvr]Ó;<#óœÌíÁHÃRë#³|¦4,¥ƒVB)&ÀL•¿BbP¿Hê;¯ úA·×}rúŒâËn™š¿õ³%ï�æ,%%婪hTÿiÏF2´iòZü àq–ˤ¢‡¥Æ÷Ž´Å@@¡ äþÖ¶Z¼wD¥©­ ëüîcÿAÐjð?z4V¬òR| ­X €&Pq(Ô¶8\2^…bú@R\ÅUúš”äý§÷7°ˆ•­²qWƒL¯¸7E°Ìžâ‘Å3ƒ²u_-:„9s¡Yþÿÿ8-¡ÂEHÕ#^‰Ÿ·@î¹±H>þÁ°Œ-s)k&œ®,}/jÃ[õòó—ªåÈ)MTÅÇ×¼ìà_�ÿhF›Ë¯üŸÿ ðu`%@Ò‰÷_Ýû2�Nw, +ÒiÊX·r1TCi=žæi= Ýù:tül‹üæ�ZY¿£V*£­jÁ”ÄÌñ8ðmà'@%�K=àrV¬òBçQÊoÛ�·9øäÿ�•Üh€í$É¥YÀìø’$ÂX ˆ»Ð9Ø–Ò‡LOý©&\Ç—³¦–Ã¥nª„³Äï ² ÆÆ0‚b`b6¾™¤;ŠTIn'_]õ>Cí0�tIn^–È\=Yž”r‚˜IÖ e^®¢†°âb=SëŒ×ÊŽ€×ùþŒ9£kP׸©u^Vк/ÀCÀgaÊ´"™8¥DN©’¶V CùuÒJŽ4p5ºî²ÅÊZ¹žÉj ý” •Àåb0ú y•Ô·“Ëu;¥¾é,öwpì>øà� €«�¼Ó€%Ÿòî– H�iÞÉ´ê‹C Ÿ¶Í�Jô2Sº¹ñÅížOk§-{ëä¡Õ!|…ætȘf ÈW/ !>Sƒ"Ÿ¨ŠÆæ€t£ÃÛfÅûôš¹3á¹ñM›é¸Ÿ³Ü>Ý*?E\§MoÕHsK‡:†dÌæ2ÀãûÀq@gˆ•¿¼/èrx?¸OIY±Gî¸>"k`é¤H§x�”µ“9©‡%ëÏ ä*ÚeíÖZYûF Ö; î�¬|ŠÔ`ý ¸ƒ€µÜ€¬X t£�*c»EXÉžH…Z”±$)Ž–L‘òeXNæ×$�h1Êv“`Z‚çÇ…-è*.W@¼žR Áº)è›&~¸Ö€prÐ¥lŒ®f¼\<µqž39q7[NCÌdnó¼Þ¦Ñyê g7sáÌ|ÍvöÒè’šßÔ:qT¥zG]:îÉ_QuÉ(¾ª^LêýϹñBöeœb7‡©xïÛÁ5…"~™:½Hvn.��OÃáYz·Œ-%5 �fµdKC"˜ílwbF§�ïŠÎ‘M½>ÆUc…¥^g¾&=×û*H«²æ®†…]�(p†ñ‘b²„}‹ärýër)ºUZ;Øß°_ú]`=p¸š ¹«�ÜkÀ’O¹×ùP¼"¿ÚÒ}f‡„ñ�¶C±¤W_&Æâ ÜE$WN `øÁ“­²|žq :¤Ý ˧y!™<¾VNœŽ¢7@�gãÊŒ|ÍŠ‚oʘÒw¥È%ºØÕ6t T­ü³èÑÅŽÄV\j±¤»ãÑòŠdKâ ÖRØYñ¥éKÀÃ@)À—,%…~·Ü¾<¨‚‰Ï˜K'’Nè«SbR™S¯¸To`¨M}L^C ­§^­–£ï7*à Ó¸ ý2cÇI=ô42¸âuí«««�~h€oS€G€¥ÀD`4Àý¦]FÉHßʤƒq¬„¦.N/ð]g:Ôωæ´ÀU7ë�x ŠÔ,uÞ‚RX:��«NAt!ˆ—ÇœüÁ ‘Zb™hz)õU&u�¡—’”‘>“¯E½O£¯„Ë'Òd曹ͪŠW�Fçs¥:™2±Яz~Âu�D⳪ÿÊÔ<ù_JaƒNÑÛjNátxñq9„06ÁU.(hç `èêpúж“(*@*ý*­ó7yr+¹®óïâל’8¤ËBãYÂ[PŒ‰(Fãz¸Fr´Ì÷5Ùñž(‘Ø®X ä…,ù”·i@ ÉÆ‹V0üú‹/µXaàÔ©AäÑÞËU&ïý…ú~&›ï£ÀàLÞÔ“Í{keÙ<^3‚ÒáŒH)ˆ¥U‹Ë@>ÕŹ§v)ô»ä«�Œ’Û–ð�_´PI,¸±ûP“ühmTv½[£™Çõ׆ƒ$Yè2ó�K²…÷uðyà·€ ;+%´ÐZ¾0,]]„ú<âvÓê ]x²s3§v»,éÔ ý½õv#H§¨ì|³ø%­½LZ~ ’ø]à9 ×®†¸¤«««¥¶‹t;fÛÈ1ÛJ¬á.ödº7+pùA0…(SA ^ JÐnã…/&ÎB|©&ÉÄYN™%;¤So1Xźú†ÁU_�´˜×³‡ÛúXrOú6óÒ%Jž1”Ó°žW.Ÿ>JJ=ԕϳÞᮀT4wÖÜ5õhuÄNNž©ÀûìÔ˜$§•¢þßS¦N+–¢RŸœ?‡pØ6ω:h® ó_Äö”íIrMmÒÖ�‰kàšÖÔz3Ç]Àò€Ãí®­£nw§¤¦á]‰6‚^½IÌån€ž}±3©«�Á×€%Ÿÿ v Ø ’|Raƽˆc¤åÓÕ²Oƒ]«î¯Ï@}/Š|j‡[Øk»êåÞUE2mr�>'"ê�›–•ËÚͤ:Š/'èôÜn§ŒS(O~û-øÒ(5µò䫵òô+UR]Û*íº+àï{À?´xª`|�3)Ç•>ü6À%^@õvt�›7=ˆ™ùŠà2èE+§*3ƒ¤÷E× ½ªì9Ô,¿ÞX-[÷ÖcÖŽ6S“ëL=ü'ð+€�%­Ÿ¬X X X –lIÅÎ`»ØYЮ1(¸nnwP½T0@xÀ3–L%øàÀk_.4‡�l9I<˜-º{`[½¸èK˜#æ‚z›/5Iá¾ÌíäÑø»ÎÈ<'s{(¥aYº+_jYuðñÔ³S�æÇº¹Ïéµp4—�*d¬'ºmZ�(Ìt(‡ß«°qŸ÷_ÿ—è�ë\ÓûH21w{¬ FKõÒÜQ¥,ššÑD²©BçVDÆë<ß´�‰ì¯rEý/Çÿ¡“ëÂ6à#3¿¡ÆËKRŠùGrŠ–P.xP¸Ñ�8á~í)ˆ`Ûïâip…ýcËò!ë¬Öö&XpUIc[%\6QwC¤©³ÕO~¿ÐߊÕ@^jÀ’OyyÛ²^hºÝa4  S”€Y0¨¬_ihdHKœµÀW�‰¬ë¥ÊùÑóQùÆÆ£³`'“Éc<˜åÎ'[ö�|rI�_205ªÀ ·££EÞÆLy�>{Yv¿k'� ;†ÇÒ>ä’l!éôð9`>À—+õ¹…ï@SÇ@:Eä–%~) !@:&=±Ñ a>n0X§+ÚäטÁîEÄuªª¡¹s¢þÌ…ç€Ç€§ê!í$l[±°°ȵàK-û€ÕæÂhÓ‹‚3_¯}îrôƒ%Š„bü œ'³C¨_tØ‚ªMlǨ=üÉÜÖûøÚ‘”Ìs2·2M²z�ÄYOeËFšÎuꬻÌëäÓ6ïaçûsÆ:Â_!Ž„RµœO5³e½: „ár7f\·$´uDÆ}2¤‹v•Ó­hþ[hÅÔ€15B5`Ö·VÌôÖ b§L3¦öö:,á>Ã9$iˆhêûÝÕÿëü忼Yš¦Œ+ߤÚTSïŒ+˜†@%LÓí!wfЧÐü鯀׀\¾[è«Û_«�,iÀ’OYRdgÃ&�îXФ(ÀáæSÑe»—ǵL/:kwx øs\LÞØS#O­?{äî‰Z¹`°äˆ‘§¢tÀ×Û…À±Ì^×(O®;-[v]’êšcíC;_º”ÑÚ‰.}t±Ë•#¸ÖƒÀ€…@’tÂF9L½ï½1"w¯,”q¥Œ?7Ãêcéת¾ q­vÔË“/Wˉs:®²K•Zl< |Ø XÒ J°b5`50d4p%ùp p;KE÷ˆ¢ÀB‰«¯Ïêí£²ÄQ/šhœ­Nž£ Ó�r™ë㡬g˜­š&óa‡Ä/#ß~”ÒÙ°¢ºUæ¼ÌžP. °ò©ªaßE‰IeEƒ<ñüqe%g^H4‘púGà�«N�=ûjà+ÀíI'îSR„Ùœo]”{V†eÖdÎÄ„Ï>¨m_ƒ‰+;¸ ^¨l—§áb÷Ük9UQ*@IDATÕÊÅ.×Ê\Žì-½èføÀÓ( «V¬¬¬†œH–¿ ðKòßvt´…ªêÃý£YÆÝ&Aï,ÕÄkÊI—½»>�ÇØ¡¤Ÿc,£túÌß‘’†õÖ$L¦̶&ùÄÿV&ªûóMº¡´äÝ'´¤= ¨ƒ5—zÑÇ Í9v9ò40–O‘"Ÿœ;Åðú™íE~ëCÏÎæ‚{\=€¿/UMû$ÚpHZZª”Õ“ŽkÄZ÷K˜�îÒ³“\"H6NÕÇ�<Ï,±šá8ŸD¯Cb‰MwêÒÄr#1E‚* ÐBªà>.¹Ï|6�ËÊuŽ¡ ¾?4UÀQ€ïÇ^ÛœƒU+Vù¯K>åÿ=´5è¿8Ú}ø[àÿŸ\9U8^'O¼ì•¥sýR]gxÎ@�ð‡jÓÉÏV/ß6ì0Ø‘ ´`ð*KZ:=p ›øºåÖ%A¸Ø…eö;qD÷Á¾’NÈ®—ilŽÉÆÝ ò_/VËá“õj?‹ ;Í _Þ~ \ØAZ±°°È ð…e-0ï_‰ÅZ\µ�GaÑZ'c"·H¤ðZXãÐM™Ál“/Š\ç;ƒ!Hô6÷%©'½Ïœ¡ß0r™Æ”¥/e¨4©š1ºë|­xI…n.ÏÜïTqã–r¬¯©ŸZ:bm˜¬¤fìØH^Ðù¢je„j ´, %¥˜°æäí~&ÛŒüT Û8mèÓŠMÑæý3¿-µ˜¥�Á²0¼ÂÑ5?^²]æx’DÓû ˜ãÀIà@7:flH¦\Œ½Ù@]]‹e&AÄ2R «qÅ$÷™›Í|2%u×Y?¢«ëe¦µÛVy§�Ä‹kÞ•ÜxhkÀ4³C»”,‰£G�;�Õ|Ñh…òô«•²ë€_ÚÚLÛ¯úž‹—•Žïc¹à¶¢£°Ha‡Æø$Œéô P ¸%^¯Sn\–L|Á4Z:‡Š¤SjfÎî~YŠ–MœÅî—¢òÆÛ5Ò wÄŒ¬H21®ÝVöübÓ÷‹!‘«««�AÔÀ)\›®ÂøBûd ]Có%9S¹^¾- Þ€xP𸀛ˆvm©��Þ&E1¿qkžÄöà¦QEK”¥weË^šT½t¥§FS]¹/Ÿ„å×Ï€~6t}XÄGnõy êKJ‚ìÇéÂce„j «§Q゘¼Æ‰±%ÚÝ\ä¥6èZGr©±íŒT7î‘ʆ}Ò„¶³CÅIÕÿW¨ã‘X: œ�¯Ÿˆ¯óƒæe€çÐ:• /33DŒ�c×�–‘ªåRʲ…±°ä“}¨6˜ª·P¦?#O'üjñ×­Š"¬~m}»¼ ¨¸°ãÛü°È%é4×ûð0H,u!8×’ùayð¶ˆ,�㟗–Nè¥3˜"¤éQ׉ӂ>Õ"¿ÞX#¯îª•šºV|½JKÊçä€z ùD 0ÛÙB V¬¬òRì÷ŽlÓÆ«Ñ‚:8ËÒ¹Ê͘ڻJÊ#7‹Ï5/U$´”&J´õ“ê8Õ[¤&u4Å3t(½DÎ]l³Ûeúl§Ñݹq4%éþ:ÙOÃëja-�RKcêγÔzžY<Å«—¸�ê£*æèœŸƒc kùd”6—�K÷³±¡UÏ_�‡z ñÔÔvV.Õ¿!UuïÀ*¾ÿ¿Wü[‹*8†Þ_'éD7ºLr‰ÿBXµb5`505`ɧáxWû^'ölðUgH"Ë¢òÎržÙÌŽà€–<i2‘ÃróëÌ·�Ç�KÀ{XË–ð é|à¿´tâK-�Ô�a@ø¹ÓƒòX:­Zè“P!¢U¡¤ýq¯sâJ¸ß§.·Éo6×Ê‹[£rAÖãÁÔqÉ„Taí‡uAkëb%X±°Èk ¸Pú"€¤ãˆÜ„ÆTüm˜úûRt7bÿ�“²È2̆·Xœœ¦c³sPÍqü7Nž Ц]4ᢷÕî–†uÖ]¿¡¡´Æ’1Û9.ñ¶z+ÌÇØy%¯ÖÛÔY8O ËgO‘ËãsŽjij÷âJ½¯TŠe³z5:(þ GýOÄ›¡WÈ+”ˆO ­'åLÕ³˜ÁîÎJþÇ“�Tâ8ñQà%€.t3Z² J°b5`5 5�²Á*3¯5ÀÞƒƒêŸ@ ¸e7øj¤uÏ7€ØaÒ§ºãäÈ{:ðEà£@'ÒiÚ„€¬Y–Õ×dT }í5[عïÇ�„ÁÄ›Zc² ÁÄþrTÞƒ{a+I§ôqÉÈ7r/$ç¸ÏŠÕ€Õ€Õ@>h€ÖL“’L ãK¶³ãÎFD2Šc ¶¿\WRPP ^¯.ÇíÒÔ¤­Ú;š¤ªþ€Ô6���¿”¯ 5S œ…JÎH�íÈ$I ‡;“'�¤Zódnó¼�L£Ë¡Ë§¯£¯h~»*[öÒ˜«hE÷|-v·Ië'vKIÍêR™_D#Ä*ÎpÆI@¬ªÈ°žJ½æü�]òšœBž%¦è»Œ8äN_À5ª¥¥äÓ•j¢SØßá¯�b‡|â„Ù9]yóKbRÝôÆ�*w*û>ìäÇÚg’N]šDa¿««�®K>�ð ^}-ŠX »NëaÓˆTN#j}èÔ³�6ø%þ·€ß¦üò®F¨´N"ét÷ʰÜÒit)>šb_,��§²tb¥Þ9Ú,O"˜øk»ãÁÄ9~O ·Þ¾< D;ˆ€¬X X i �lšÐzti3°,8Ö¡Õ I¦Ñ„uõ eôèÑ2fÌ)++n×××Ë¡C‡äĉRWÇïpGn@Œ“ý°†:òiŠ”„®•�o†¸A´Ëšaãm:C´hBÂÐKIúÇìOîaZ‰¹d' 2ReJ^'3ßÌm¦ÈN�Ï•ëD’ˆu6µÕ·[`m¹W¼bAqæÁTB‰R]«Sùj(Ã{�óABåFÔ…Õ¥2ëƒm—ËU0¦¥%ý¹ËM¹ìU†šB¯„‹½hwAŽƒm<Õù#ñÖ-íŸN•~~ÿ8ð}ŠՀՀÕÀ5`ɧ+ªfÄ`7ÂÙÊT,#ZÀ¨x?d>:w0½VJFwš±ÙëlëÄ«¨y¯‹Ì¡[€ÿÜø¥'ªžîuw¯ŒÈ-×údL)þM±O}$ãX¥�¸NNdzò|«<óZ�¬ßV+U5�â:±ÎÇ�ï?hSÍçŠՀՀÕÀPÔÛÐÑÀµÀ*à`6@BŸÇ8¾!û�èÏ0H(’ÒÒR)))Q(**’p8,` ÔÄ H£Ž�;VæÍ›'ÇŽ“#GŽHMM bëaú²¶º8 uä“&¡ ½ÓÐÎ2iü‚lRõ¥ iB F7Eâ9©{†c]¿ôZ¦ëÁh#y»@H1þ“²lÂBQ°iŠ[4â)™3×’ºSj¨)¯dî¦aÉ»«�k’HŸ©¬•@6uÒ˜"£8ß H%µÞ9_}þÆ-©˜OÎfÐK’K,}²Î1˜>9ý´ã²b5àö8%RPc3º“ÏÉÐ× Þ$P0EÆFm¿T³Ü¡Ô|�ä86Wf†C_Q¶„VVÝjÀ’OݪgĤÕSGÌœ1-Fö©ŸÂ”. 朒-)Š\InŽØ5º…| ø0 à “’HÐ-kn,’Ý” åø·D7®Üëú9^%éÔ‚û¸ù­FùÙKUrðD}Wq�xߟþØð«Uÿo>[±°°È¢Øw”sZ6­¿iÀñ �wzé!±D˦‰'ÊäɓպÏçSVM©äÒ¦OÜΞO‚ÊXJM�:Uöïß/Œ»ãÑU�|½ –Slâ)l¸Óú@l')ž¡›ÚÔsØô¦nësz¦§ú“†y§JoÊ–z>×û“¦s:ãp§êi,›H¦TËy1ºÚ©.*SW©Ý–^'A•;·;Ö‹�¡‰ù”Rx”D¥·­¥Ÿ�9³¶2l4@+ôPÈ�¶"õɯêú¦‹Ï]®,@ñt³"wOõùU[Z««�ÁЀ%ŸCëCëšfÔ¦C aÐwÜ“ª<Ä—Þ±rƶ‘,•Ò5„.v÷t±S/L.�t×ÍÉgî,–…³<�`hÍ;ÒÏq*Æ5Â<�ŸméT-¯î¬‘ÆævE*"W#Á¿ü À©p9`à>+VVVƒ©’IÅÀL€q›H81†Ó p̶³Ó›É%Z6M˜0A�.uÜÇÀ¾†p2K¤ï—�„¢­ ªªªä“ß[*áÀlq;‹I5Äó6]+‹'D°Ôd’9Æeò¸9/uŸ&^2ÏÉÜæ%“ûzNÃóÓ¯=piº¿õÁkkÍÀ®‰–JÎd,'ÖJ׌gè¼Ls$¹LÖI�Ÿ¯�«�ûÑµà•’kÔ1KÝÖÒæhmá·+#]NŒ�…°º„Û]~J¦`"æÝT¸Þ�FÛª<íèö¼x ž«««�+jÀ’OWT͈:ÀÎBÅ÷a̧VÌ„ÆAvr Ü{]¨�"^ðáÙw�äçŒ/R¿|("Žê[ï(–»–$rª@ï*f-Nê�p»ÚÆyéÍ:ùź*9{©YÇïJfÆ·¢Cg°û%@w;;P€¬X X ä\|û �©À<€VM´râ>P2dS§75ºÄ1NSqq±r‹£[‰!Z=¥ºÒ]-á„2¤ c>E£Q©­­Uû]N�„ý3%è�š�Åd3›¤˜Ø¦n«M×{IN˜£\&)!³—ǵäg–ÝPBW®“¦iÛ)®Ue]c®&×ÌzRWF/$}ÌQó¸ðXjZæ50’¼OúŠº,º”íxf+VÔ@(ì·›<{¾ \}ó¥²`7f¾SäÝîvœ ÏŠÕ€Õ€ÕÀ50’I�+*e`ïÑÀz“|jùÔoAR7,o|¾´Ž•–>#M¨€[€o7t±S£`Ÿ·@>¸",¯Ë´±n’BMz‚ú#.Œ³ùª³÷H“üø…¨lßW_|¼Ô¤ßÆJäýCà?�÷E6biÅjÀjÀj  #À`àÓZ3]Ð"t8a»Éóˆ4a0p 'ÁÄYéH61P8÷ (ád BR‹³à�:uJY>q?ÝO‚Þ™°8%�–Úèj[“6s©i‰Ljdø¥a½5—©�ä6µ–Nu¯¦¼ršxNq¾äUz-YƒÌ²uÀœ¼ýjMʺø6ÿœi ôŠÛ“6FÎÙµ³q!Zw¼“$䟦â>uÄÔ7Ì{‘÷ãÀÀšùeCÑ6«�aªK> ÓÛÇj±£PŸqÛÚ:¤´„2|êc&<�ƒ.’!>UŒ GdI;(³wø.YßÑÀW€ßJ5Ê`¬ÙÓ åSw—ÈÊk|â� ”öuÄýæÇØNg+ÚäÙ͵òܦ(f±kQT)ÙñÞnþØ �häm²b5`5`50�`[HFf@:b0HµjJ{ £›­— %‰(ë&. 3+]&Ù„ü®u\H9sæŒ"ŸØW:> â,à¥Q+««­[t›¤\LƒË3(f;•rÉf}•¼²¾.ué®\6s†É·wiX–ôz÷.ÝÕ¤I½&×s"ñjiý™Òk]µãYiÇ!+VÔ€?P€Ùî0³fÞª#†™'W/°D¢�‡¥¥µš5)öj–V¬¬¬:iÀ’O�T2"wpÄeÍÛa.ÓÔŒ@�W¡Tô{Òr`¬Ž‘ ´ðzøÀ—¬D@ñ¢�Gî¿¥H>Œ€â£K\Štê¯>‰A’NµõòÊ[õò« ÕˆñÔ¨¬ÖpM#éžþ ø PظNP‚««�Ñ}¶õ´dš¬ˆc:–$¡H2‰/Æš‰Äz“\â:g£#ùDŠîu”TW:ngÛ�Žyv%æº\ÒÕîäÉ“R]Íw«ñûÊ%ä£ÕS}&›WÝ?Ém’qv"~–ŽÄ+|^¥óu’{Si–F—5»iLn™×âþκá^-Z;<'s;SŸñRôœHd ä2^Фþô>ìuõ­°˜ãw+Vø8ëwãã£~>’Oq~iFY?ùfHØ7M*Úö¢=nc…îÞìxJ°b5`5ÐY–|ꬓ‘¸‡äݲÔ¯³²ènQíéÛOMªå—v£KÕ‹¹5§µ§—TzfùtN:µþí) ®‡øQüs0€y.„�püRiõÁFsc‹4Ô5+”Ϸ•‘­¿ß%ˆù¤Úº¼UEL\1¯K´á�´¶×±&S€‡µK+VVViî¤@ZeíÆ5ÀñÜeåø©®,®b|Dw0ôªÌÎÈp}ÎXɱÀ> ˜é¿•úÊJ½òÐêb¹oU¡…\p‡Ã·"í•�S{/T%-�‹kç�fyzcµl§Û˜(=?níþø5ФŸ�V¬¬¬ú©¶y´bº¸`<;Z9ÑåÂ�M4öPÝãhÍ4zôh5j”²nb�p’M´z2/â†àA:õ‚ÎåPNRYY)555ªn>÷h)ôN—£G‡"mÔÜ�%†~1ûIÁP’ÛÉõá—†5åÐÂè#YW³Ö•T’FºêkMòúɼtÞñËÒ’®c�’$$¯ÄýíêØŠþšŠ8HÇZÑðø=âñÆÉ'5ËŒùOÈ/µ°Ý+ôMG;8îwÇÐv·³"Œýô3 Ð V¬X X X  WRÀÔÏ.{§vÊò‰+õõíjÕ»¤]ŸwöTIßJ=’¿ë´n¢û×¾|%\ì|$yËÒ�ÔÆš«««�¾k€�–&t'¾¸˜ø~LH|P ¡äõz•ÝøñãáDW:¿ßŸWdS¦V&Q‹'ë‰P^wq G�y �Ú€:ˆ$© ]ÖR·q8å}$wix%S>]¶Ôm®'ËbÊ–½4=]‹WO¿~ævçòõ6 Îs`Î TÊ�Ùïb1yNÞ–,;Âò'5–V~\®ŸøÜäÙš½Ø\ºÔŸÇ�x »¼ØÀï f‹§n«4¶�kŠâçv``É'(ÁŠÕ€Õ@º†)�^3»Õ pÔDY5|j…¥ÍU :ÕŒ˜O:bìUe:è‰9T kÉ—€ßèb§ê¥ÀÅî÷É=p±+ »Ô—V8{+Ì£q²HTqöº-{dÃözyïx=‰c¦œÎ·„÷ë7À·�;ùÎga§«««�4À&ˆ–L³€•À-'M pœ@�xWB+&gܦ &(—:NŒé”JÚ •—mC,™òwU®Ì}™ÛçÏŸgÌ'dŸ{ȧ‰°€r£Ñ5_ØÞ+;›8 Á3µËW’ŒHÝfir•Æ\I—„åì¹lÙI£k™Zo>jÉmCiMèßôò%µj´Û÷4¸¤²‚•ˆ€Òµbmµ$ëÃk²oÇî´b5 ò‰®w>×X¸ÞM”¦Ö*<çœ`Yõ#GûÔS#V¬¬°äSB#~¥Áh Eõf«ïKœɀãÌ ßŸ3’Lt±£9±`5aÝä’[áb÷±;àb7§áõ¬œ“Ê„¤u¾ïh³¼²³N¶¼]/ç/7#€#ºõÎtR#.ûðŸÀkI'óöƒU+VVV½Ò­—ø‚° ¸  [ÝT °ÍæqÕΑ¼¡%Sqq±Šß4nÜ8,< %b7²Æ,‘v@ÅJ¼^êzWíªLL“ŠÔt©çsîvíG�•ÆÆF—ËI—»±âu•¨·*C„$ß±ÌM?0ßä¥ÎÄöÈH£5Ð�´VRÏKÕ÷SÒu×·4:‡!wò ¨lK,…MH/‰6Cúeûª6¿|Õ@ç¡]¾Ö„ÿS {gIUý¸Þ©ºe/N£Z±°°Hh ßI�DEìÊUi€#½åtÕŸ)0òR&AWU¤!‘˜_úÙ�ÒÅŽä]NÔ×UŸ »�ÝY,«$]ìúb{Dë°!Ýþn‹ü?ö¾0²âÊövV+§™‘4I“393€Ád 6Îpü»ý÷;í÷®½û7Ù^{ÁÙÖ�µq “0q“³4š‘F9´ZRw«ûŸSÕÕýºÕÊš…ºÒí÷^½ªzU÷½Wá¼{oýñ©.yv{/œ½Ç`Z‡�êЛ@³H‚Nw€ŸÓ™xêžaß’•€•€•Àh଻ L é ðÅàU`6ÙlÛR³r: §6SUU•МŽû›hbGÍ'’iÌV& äŒgÎ;Ï™óΰ\ù™´fëŒÃ}'�dÊ—+.âѨD"¡'nqœHôöBÓ4u!ÌÅ8Ì“ç±Â�»¹¹YÕ×ï+…ÖÓB˜F³;ÐSHÝ\ˆI_•ai" 3鳿ød¥z]S.ns×gbi˜ßHrÐ×ËÎ;ó˜q²IëN¥C³�Ógœ{¬úWjAÁ o*‰uÔrÓÛÑê<•×¶yY œ\ $¤0¸æÈÅàÐËàé�ÆÖ‚O'÷æØ«[ L; XðiÚÝ’“V ”§'ç i¢¥ñú2r™‰ÏY1êþ!ð§À Á)<­¢Ô/oº¤Ln¸¸@*K`b‡“ã1±£?¬Á¸K^Þ‹•ëí’g^ë‘p_\�NÈÊIÌúø0Wy LŸNt‚,Y X Œ*6Ä…`~‰>L-'šÓÑŸ'l›5 @)??_­HW]]-dšÕååå)í¦l°éF$gü숹Î9Ü@”Ië—L˜I‹Å ˆ‡vR  ÒÂ<�üØw�)�3Lzzz3œÇÈÇ…s.“Ÿ3^לsa©²Âà2)Ì«Eât|¢� ð€Ý$eô�JûŠÜÜ4,mº|ÔÌÉ<ÎUŸì8ÙÇÃ¥¡8†¿sJ™yAorir§6yOl›®ŸÎ=}ÌüôùóùñŒ&V›j&H F? ãQ‘Ÿæ•¢é�Ï]!ùåû"mhOÕu3Š] ¶¦wÓüþÙâY œh ÌDPàDËh®\/eº•ü¨=©zûÓàGaœäÌâDìLð߃/³ìj$éõ¹åâÓŠå�W”ʺeXÅ1ÕøaŒcY:çDæàѨÜýH—<üb·ô„èD|HœÑ¼þ5˜~�‚ :¥îö-Y X X ä’Û0ú§c;v)˜>œV‚ ¨°‰q¨DßM\™ŽÚM•••RXX8å¾› ˜d$^Û„qŸd€:fØ“ àÃp'µ”‹ÔJ"CSI…S[‰ÎÀ¹Eà 0å#)ÓPRù0/¯c®e¶úÌè¿ÔÇñ¸¡ù_OܧÁ‰!U7uÉ4ü�Î_Ã'«´N� ±xé#ªÃt¨Ñé™ê4Ì}¼×™HÖhøtZŽéóºLÎ4éRÙM. ïYÆ#Á‹Mž’UHKTï1cŽc¸³p˜¼Àæj"1žK¤ÚâY cz·Âiz·ã‡®ÄÌñ«%+++% >ÙÁH@Â5G“ØÂ­²¦åÈŠ�™@,çÍàÿ ¦¶“z?hb·bi�¼ûÊ2¹è´<ÉÏsCs‰IÄÌó":¿ÿéLìºåX;|:a0šEô»õ0øNðc`~1¢FÚ¯„˜–¬¬æ¢ØàV€Ï_¾¼Lðœ*:)s:�Ç#¥¥¥J³iÉ’%ʇ“ñÝ”KÒ`ÒŽHD¢©›Ù7ùpKðˆL #£�DàˆÚJ ç–áÐXJ�IØOðòSæoL‹0Ã�gN %^‹çPØT]G,øÐ“lkiÞÜf[ܙ䥨nDˆIOßAÉìÃòâ«`¾*EA]z%–è#Ú…~€TЃ/7À*g`eŠÆbÑ€’U Èb µ¨¨*öLLÃ2³§35æ6Ýó™PÇçÒÅbN$güi´’Ÿ‘¶Îmjuíô/KÊ¿tmÓ{S{U›ÛL’€ ‹Ëˆ'.Sl÷9 D�¯LéW½» ü8Ø‚OÓàþØ"X L ¨Éõt)Œ-ÇI“ÇD8¸åØyr„‘WÀŸŸ83 éª¹ÃÂò+Íÿ¿œf¹¥0ß'×_R*o{]‘TUx”�‡j*1ê¼D¼—t…âòÈ‹!ù-´�5ö)Ð)KÆ4’ÿ#øûà-`ëÏ B°d%`%0¢h L�œæt—€Ï¯³ý"Êa�壉Méjkk…éáD Š”nÔ~®*eLÐNRà�£P(¤´�¸%¸dLÚ’I*ŒáÔbâõ˜–Ä}CfÛT’GµË&þ·¼�%Jàæ$·`KnJr¶ÇÀŒÃøœ0±_¸ œ¢Þþ#ÒÐöñ{K´08‘¨ëE…j@®n¶>ñx}0G™/…çJa`òa¨Í”ìpS9sÇh9e¦fb~4¸‡7(óÆŽ,æ9‘4Lw"ÈY6î[²È�€z(ÜÎÇ$ãôL< é]À½mÝé�´+ õ øôm°5½›‰7Õ–ÙJà8IÀ‚OÇI°30[³jš7Ç kã®N~05”ä¿€p¢4Á'NÔnSÛi˜å„Y…ÈZ8¿ù årΆ@$žC…1Œ$ :ù:…úòØÖ°2±Û¾/„íøež¹§ˆòx |+˜Ot‚,Y X +úoZ >|˜ŽÃ«Áìˉ$i4 ;ŠŠ‹‹•f“1«ã1‰"ØC`É0ÙÎeh'X2LPÉiò‡U\gZæg޳÷y< "rÅ>‹€5•B`Np µ‚�Ö’9æ– ·Ôn"°Ä<ÌG³5­<·ì hªH€ÏAÐsŠö(Nf6ìÌLâ\˜s‰ßS  / d‹K¦c³{Ô¤ÃÒ0�>Nƒ0ãIc œáÓ˜¦KcL]–©NÃÚ™Zê¼�ßµF¿NòÚéJjáOá¯ÎÚ”DËWù|ÂÀÊù.Lá%mV3LМGC ÍŠgXÑG(n�V½Ë[#�½; ø´ øq¤Ìñ­%+++mVdå`% ˜Á8@m 0a©`ÜU˜çÁ$†ŽZÕPŒxj?M§Î‡_Ö7€?æJv¡Ôˆ1/Ï+×o.…™&nÐvR¾!Õl1F :õEò̶>ùÝ£Ýòâ.NRèh4#!�^ó‹ÐÝ`N†”‡Fl-Y X X 8%@sàSÁW�_&øT&ŠÄvŒ¬È¬PG 'úpZ°`�Òpâ u†Ì˜šGÜ7ÚKÆ$ŽZL���ÒÕÕ•2‡#°ÄóÜÒLÎÓ6a“ØŒ'˜Df›H&`D ÉJÜR[©=Îsžˆôðží«iqÙqŸ['ãpTbE‚Ÿ³�à5¨…ðåO¡2o^—çX~^ƒÄ.•èRh@ýÕâw—¥N²£a/«:œÔ¯éwÓ¡&3f8™4Lo cê§ÃL¾æÈ›+›²˜²éxº,ãKÃØ¹Ò1\çn®•¢I£ãð×Ôb"ix•Ô«¢3›ò_}O�õᇬÌEú±’-œŽ[²èïʚʄxV ƒÀzQÞ ÉóWàã+›Ä„?WƒïO§ñ?ŠcÉJÀJàdI ý ôd•À^w:H€#MÅêg2ã#d@?Åznéí䈒_ë‹Àü2=ˆ‡÷�ÿ ¼¬´�­Xœ/¸®B6÷“oÇX,ìÒ S\žÛ‘?<Ñ)ÏïI?®Dñÿüs0'2ý,Y X X 8%À¾yø 0��3Áeà í&j,q…ºòòrY´hQj…:†“:š¹µ··ÓgRà‘‹À’ÃA·ÒVJúTR&q£è[‰ä–¸?AbfÔR¢†%ö� Ó Žm!·TbòÂdÓšrkö͹ y GÌs/ø‚&ȵ Ì2±O#øÄ8ËÔL+yL„ã]`¦«ñx‚€‰žÛ•‡Èt8®(†˜0í!Hk;é i¨H‡#b ‚2{ÜæŽÃ3&8�t]ª©LãÔâJ×É”×”�eJ—‹uZ'�“–”‘×øÓ0—¤ÖW �ò‰Î#]N}õÉÿf–Í¥œ�‡û"�¤�ÛÉ_Åæ0S%ÐÙ ¿7†÷S¿3µÙåfûæs—ããó2ø}:¦L‘ç"ðrp'Xw,رd%`%0w%`Á§¹{ï³kÎNA}°‹Ñ™¶µfÇÛ1z%/à5àS >�lâó~%˜“‚Íà´¶ÊzÍ%òh;-žçE§‰Ù�™Þ b.JƒN yvÛ€Üód§¼°3$}�2»XJ“­'ù¶fR…]KVVVJ-£r¸l´œj±Op\õÕ›‚Á Ì›7Oùmâ–¾œ¨ÙäóùXD ©©©I™Çµµµ©ý$ødv«xÈ3µÍÞçñÄöŒíWo’ Ê,âäÂh*Drj)1œÌxjLûgZJ(1o2ÉlõÑÉùeùƒ�&/¯ûÉ´¶™³ŒfO2\F3»| >Ä,ø„~$‚$&0û`1Pˆ ׺4éx3'�©¡“xdêdö̱³NŒGÉdËaÊÒ`E”W qˆ2%ÀV�QæX—b<¿Lig}>�§ž®é [ði<2�­q››z¤¯w@-ZCt6Ü©Kqp­´õ¼,qøÃÑlùlðv0�zKVVs\|šã€£úQì«‘q$ª0(Ç©ñïæÁçQ~žK9Ø@j‚OüR|²ˆÝ;5¨étzYÚ7 UâWÕÈM×”ËæSp"‹o£f‰H¹( :94�:õ÷ÑtbrNÀî¼L €Q®€–¬¬æŠ¨A³üðuàõ`š+°NMMè‹ Nñ5kÖ¸6¹¨ÑT__¯´˜hGЉKÔ\2«É!½˜6FbÛd´”¨¡D‰L_IGÀaÈÔR"ØDm&N(¨¥Ä>„éɼ s‡IäE‡óx¦ë‘�Œ$ÐUˆ¿ ôzƒR„Š· •g6šôÓ`‡îu ä2TH35 klj™–€SΦޣÉa’i@©"h�‹úʬ¸bJ«"Œã‡¯ªÉ'�³£û˜Zá½T“ñqäi£Î6 ðÃnKS/Ì0�c§“YTÍ8÷ÅÊô.ÖÂ{¦|[�ƒ þlÁ§Yt§mU¬&* >MTr³/GE˜<$ ŽßìQâ8êˤ4Y øS=+Ÿ³“¡ùÄ,üð<0µ•ùä:øvzsr%;Öy¤9Z t‚§vÒ¼®KžÝÞ3èDM§ß‚ ~Ì ÝHœ¶d%`%0G$Àvh ø|ðõà ÀlŸØV¦œ†c?E�à‡ÉµuëVÁ%CÆ4nŒfqQQû¨L‰`ÒAð!p¸Ìö‹à' ìج­3Ãf˜aìZ‚x_O@ÄÂ%’ç›'W‚¢øtŸhzF Ïà Å0‡1¦"Mf>c»ÎT¥I×fø:MÕµœ²ÊÌ“¥È®·� xNiBqà"•Â|Õ©±ÿðú¼næµ™-Á†HÄÆ.ËÙ“OE?|57bš(ÛƒÙGÊôÃý 4>{û´–¡ÈFÔ´LíWŠÁ’•€•À–€ŸæðÍwT��'ô5.ýè©ýc†QŽxcÚe:XÀÁªòLí§E¼'rïß &EíE~ŸZNÅò–×—ÈÆ~µ’ÝHÚN)Ð Ççw ȽOvËs;z$LM§Ìñåx |øgàí` :A–¬¬TDgá—ƒ/S;¦ L-'N©û9 ÚM.j8å ¶=lé‰DM%j\-¥6ìd" ÄÁ?ãÐTŽÌ}‚Plɘ‡Ùrß0v-�QÕˆw:¸Ú…N0?¯U$ÿx{�¦ EKÒáÆ'�Ì�©J£oæø®35i†ÖÒÔ‰�‘ƒö5e~3åÀ£L¹½(¦žÒ4Јâ—7�/K>R‰tÚt©’%Dž}ašÝå|wÇqu&K€O~¨»_š›{e19¶œ�ä“_µ´q"�PÏéjïC]qÕÙ«ò2n©Í•æ™h<‚ùtD�±Ý³ö9H`…Ïrñ{ ñžSÁ6Áñÿ 0?IÓ? %++�9,�ã ÌaÑÎȪ«!× ÕÞÄëÀ�——ªFšxȯüǃhGNÐé#à! Ó‚ò<¹ö¢b¹æ¼©©ðŠrþÉR S?/7,L#/î�ß>ŸNÛ`^×7Ä‘8Ssbø+ð�Á»Àt‚,Y X ä”ÍÛ‚ÙF9‰q¶%ÆDŽq¨É´\¦ �Ñ¢´„1 ±�¡vm)˜še4ñ ó˜"Øÿ�Ù_T€©v7øðdh)ß~/˜“+^ú<^Oó0ùâåÙ]�²¡Ž xçylâ2>éx¦q^¬×™Hփ鰘”ºû¶É±ŽÇ¡y¼X\ùœ‹æ"Ê!}­¡PØñJCxl2”}ÿt^›Â½Qik ÃïÓ V§´CïÉHy&¦5OsC]§ôö°ÙŸ½D¿OnW!\Zâ-æÇ^v]² <Ü ?{…akf%`%0D¶"’9`úÇ!CàñHE ¡úäMû|bò©6»ã׿ëÀó«³™`¨!keE@®< Óù²´Ú§4±”:Rx0âäqw@§G»å±­=Ò‹e‘cªÏDºüKðOÁœ š‰!v-Y X X ä”ÀA„þ=˜`Ç0µ–êÀ;Á‡À™`³ÅaSex˜ 1æ&±�↶lÕ`>ëÀ«ÁËÀ4}£l>˜q –À}C £I"}n±ÿ8/ñúW€? >›kaÕÔb ªÑ¯ä£/å­ÔZMi0Éã”*¦ó6sŸÅ5q 0dŽgZ–—upK_´1ÑÞአöJ1dãq±w’©;ÃÒûFF¯ˆ[- }FËk*ÒÀ倒=µ·Ç»òKÅr±L¼çé²¹`Æ×‡Õî:ÛÃÒ¿O|⽚{ÔÓ5 ‡> €œíäuå¡,ŸàSBÕ·užêyÀl£­Ÿ•À¬”€Ÿfåm=ù•Ò>Ÿ8øJQö(3ubœ;ü²¼üIðÕ`ú¦†zó:½þ, :ÕÖøÄƒ3´®ÎÂN•? m1¬^×#>Ý%­�Q€Nø¦ˆ�~&èDÍN9´d%`%`%0švl³í0³R¶+lÊhp>ÓˆÀ ÇfË:²]æ1Û~N:ØV´¡ÿ°Ïx¦³0rà1™ R¸0ÉØ2-µ›æ'Ãx]“¯gòÂî°D«L°j<àËs!øfðe`úòâµ3(à«À*w,Oi ‚…2•3ELC(ºÈ&Ž92Ç:sj`sœ ÓL·4¦ìƒ‰°t…wIO=TÃâè›ý˜˜òÖ®a�4xÃøÄ1RÒ!üÕ”]osÌ\¦&�Ë…{†ÌôI5ž•ïTtMtYÒe‹ÂŒ¿»³OÂሔ”ñU°4·$O4 ©ïöF³×âNÝT¾n¥ùéÐ%d{KUÐ&°;+9Ù+�¹) >ÍÍû~ÜkÍ!—Ãgõ(lâWæ¤b-˜ ÓÛÀìÄÔóËŒ•¦ÓÙÅr4�j¡é¤@'toÃùtdú¤ê ÅåO Éï딆cý°Oç�1E<àªQ�nï[Ð B°d%`%0n °=¡¦ät&6�„²è!XD€…`™í.� Ξ (1.ã1>ÃxL`‡¨ ™ûŸNf†ñ:†±;,1ÉÄe?@â±ÙWãüéFü§Á»Ç˜Ž×;| ø�`N¤X?(̺$//Oùò@Áèï©\|Ð~b¢ŒdžÌ9nÓ¤�‹ôqæÞLLÃLꨓîð.W|0 �°çWÚE äQqœuYŒI¹ŽGvãM“€¶þÇEúþ(-�”šOüÖÝ= ½0¿³4'%0ÐÞjíh髌'âlg5q!¶ƒ4BN6‚4w&"Ï0|šÕwßVÎJ`d XðidùÌ¥³f¥†Z™ƒºñ‹�r@â„c"Ä¢pÒs3øÃàÅ`Nf•ûäò³Kä†Í…R»ptЉ‰´_§„<±µO~ùP§lß’@'øuRþü=ð6°� KVV3Zìó©Id´‡è©:ÉTØÖR3‰qè‰@'JLǶØ>¦‹àÖ0v™sÙÇÙáæü¤·^¯WŠ‹K¥´¬RJJˤ¢r¾”•WJ~a1Ú{˜OA»5Ô ~O?&ìáÄgø»àðhDpíRð?‚7€ x&ùùù²jÕ*µÝ¿¿4·4ãzùp¶[AÑ¡êNÅü„!¥»š´Ht˜‰aâ¤A˜ñ¤1°ÌðiLŒôuLÈÔ§qK$Þ)�}Û±RìQUw— }5+,k’”F¶LiNDùÔ-qÜ)s� j@‘à,2}gtP®ß�J¦«¢¢yÆ¡MÝÑÞ+]�á\ImØ,—@"îN´µõ—„û#¾A ‘Y�ɬ«=Û>Ÿ§õ4]†êS¢¢|é-;ë�•ÀØ%`Á§±Ëj¶ÇäI�´hŠ6Ùž‘Yø}ÝëDôÌ9 z3ø£`úçà—s•iAÐ+ŸQ(oº¤DÖÖú1àGáQƒá4��Nù}ò rŽF:uÉ#/t)gâYi2Ý þø05ìWÁ’•€•À´–ÛF#ŽØv’ °ÄA?™'j3T!�ÏÉÓ’¹O2ÇÜN”̼Ûä¡ú·[]ÂÀ(ZPPÆ•<áÞpÐ�å•óbD$º:;ܱXÔµpɲD<•cÇ]K–.—â’ÒÄ®�¯¹̯–s/¸L‚ùA9¸�ìÞùš|ì¯>/—\v�øüè|n,:§/�o!rðài8|ˆàËÁvžNàMsÕ‘‰—‚?~?˜rS3)j:-]ºT6lØ ,��;wB£¥W�4¹ ú±Ê“=3r^H›Qàª2ÇÇ;�º¬ºÑ¦$º¼® 1eI‡¤ãèôéã¡i(.:îéÛ#=½{ÑGë9§ÇÍE­ù„ tîæZCëÍkdæ~¢ÒÀ5 Ôõi‚Ç=Céò²l†tÔvêì”ûž�‰Ý£]ÒØ:�í׉¾Wh†ñŸàÀt¬¼$bkÉJÀJÀJàdK€¨ A|‚K%`š1ÐgÑ"óØh/eƒKlCÉl� cwTrÌû]1Ú`,¨Èóû¼^ß`"÷öõõç/¨‰D£Q×À@_àÜó/�{ðUà¥ç·¸+*«\7¾ýýñ j¤££U~þão¹–®XëùÌþ=ÐÜ\ïþÖÿû7wd ×ýÅþ–7:Ðãþîm_—†úòw_ú†kÇöWäŽïMÞõÞ�ÉÚõ§¸¾ô…Oʺõ§Égÿá+�öÈ]wÞ){vm“’’R©YX#|.PAR••…�—Ä£œëWGø1€�se÷:ðÿ_&Hç@&UUUrÊ)§È²eË$ J(B�:¤¿¿ýžWò‹$ÏOëÂIt_­}éc­É¤ªÏpŸeÔ[c²5¹4&·ñ\gjÓðÊxÔP±pÿ!iïyYú£�#A€éee’cÀ-#SîÑÒ¿:®Ù?¾iâxžX‚AQ¼.ÊFM¨„ÆiÕó…0MÜòÀ€ßt(â»ÒÚÒ+»·7Ë—„¡�ÇGÌÒ\‘@<‘ð´ë“þ�¹¢ôCͧ"¼çTœå›À7B-¶aç�”„%+�9,ÛÌá›ï¨:{Oªwà‡i~¥K:¢�cÉ òÌÐKõ<œ0�FŒs=˜šNg� :©¿`Ÿ²ªPn¼´DÎß� [NžF"‚N¨»?�4±Û;úur˜Ø±ÞûÀ�îÓ #¶d%`%`%0 °dKÀˆ#pðÜÈà–áÆè*ÃöŽÌcžç •`<5•6Ñ\ΘÅ1?¦1€ÓñšNÆáØ)3²’’2é âøåœó^—˜·`~bßž=²w÷6×»nú°,_µÊõÓ;¾ç æå»?ûůøó‚yƒýñ÷ž_Þù=ÏÛÞóá`sãyñù§äãý�¸£ò¥Ï–ÅÐZzÇ»?ìñçyeÛ«[%�W Å…EÞêE �]Å¥¼¢RêuIQQ±ÛSZÍ¥<øäóI~q Új,Û�N©¸´DŠËŠ¥°°DÚ` ìñûƒ€ò%‹I¨§[�ju¹¬n�íýàà £0(ÊŠ²Ë&žã×ù�€oSsŒqZZ²víZÙ¸q£”••%ûHQOÝÝÝ*/´y|nL¸p{w!³3¿ìQ³�ÓçjèÙq²�gBO ˜Ù’æ®Çád¼Žu£@¸uÓç“ÇÅÇ[×™·K×’çI¤ã^:\ï™ã“‘F_WFÝèJQ ˆâY}õ ço/© ÏlLv¼Ö$ö¶ZðÉ)ž9°âJw‡R  Ÿõ¤µý d¦é5 AVóiÖßy[A+�Ñ%`Á§Ñe4Wb°gˆ©á¿òq'9¶šˆ˜>?�s"EÌ�¦áˆ±kÁ_Î�Ö/+”ë/.–ͧæIi!;1L$F)5¯Xí©�Ê]î�Ç^ì‘>túYRmÈê§àï€ëÀ°%+++�±H€ý§Ñ@¢ª ͲŒæµ�Œãd"�DÀƒéÈÜgÛH&™­Ù7Ç&T³oÎ1î˜H;ÆÂ/R…”–—KÌĺº:åÊko”… —Èý÷þ Ð<ùÀ‡>-ÿõ“[¥€Êçþá+®¢"¿ë§?ºCŽ4’õ§žî]·n¥üî¿K \K—­@[0O  %e¥Ð.À•Po@ÝF¡¨ÔNÅüžHœ= Ð ¨Ká¦>¿•´¥°}@ t �ƒ`"GÈ‚¾› ‚šÞÁoN›ôöôHp~%Lï ÔÓÓÅl‡!\àÓ Ê•Úü@IDAT$Ê>|"ÂþçÓàËÀ•¶Á¦ .¸@/^,�@@•I• ÚÛÛ!Ç.F•ATn Ö*±À;Ï|`,o•.Xú¦9 JÀÇêŸášùë$}Ì_g.úØ„œü4,1Kƒ•ÝúwɱÎ'$ÔWÇ{ [‰VœX�Ó•nhCh�ˆá$“qr×É\‡Ût#Ë�1MŒÉ¤1¹èé5Ëç†o(½*Ê ˆ k™¥J¥Ë¯ÇT|ío“�Ûšä”Óâ²CpÞ•¹@ÍͽÒx´˜sG¡Þ Gj?© …~æs|oÉJÀJ`KÀö|søægU�]ƒêÔ¸)ëäx >å§/ŽÄ8ùÊ&þ¯ÿð%`þÕWfšvlZQ ×n.–ó7¤¼È£¾#«O§ºCÔ¡Ä q».˜Øýáé�üöÑNin‹d›Øqrø›àçÀ0ÔÐuÇÖ’•€•€•%Àæ„m’Ñ<"°ÄÁ3¿ÞÖ‚—€‚©•Äö� ž Rm˜™d¶úh 1±MPs)/Ps´>W /(gŸ{±Ì¯ª‘#õuòÚk/Êû?ø)¹ê 7pÉ=¿ý•üáî;åš7¼Y–-_$/½ð Àù¸ÀtNŠŠË¤½­ ”@]Ð,Š,€>O ‹WYKE¢ÄDʃö–�3+Fm©ÒÒr‰€êhkÐU‚‰¹e‡ú,nÅ#J#*¿ þƒ\Ò (ëãBJºÄ€bƒQÈE�O,*ï�ŸxÌ{ú!ð-É}ÕyhZ½zµ2³›7�X"ê�D¸$„ÃainnÆ*fÝÉs1éêÝ¥Ê]¨QæZ@ÐPo€ðE­(:$w»½�ƒÒ`¿©@‹Æ�âxÜϧ”ÀìèÈ,žùÍì¨xFC Î8¹Òd†¯4|ü#»ú^“c]OÂ䯉×ð€|E¥yè)¬ ëîæŠwªnº4¦†Ó­NÙ²Ê>&Ú„Gïp}PÏ9ëÃg¦³s@vm?&M"–.§"£¥¹ �†º.éê@;†w}èc2 EÀ6Í ¿OlÏtk†Jò#4-ôk1 km«d%`%0ºRèÀèQmŒ9 Œž0*Çôi²=5Òi³;fËIœÉ–ÿ ÀŸ_ æ9õ,ú¼n9}]‘¼áÂ"9km@J’šNª`?�@f»-¯öËÏÿÔ!¯í…‰]Ô lUB~r"ØôŸà{Á}à¹ó •µd%`%0DŒ¨•Db)xE’¹O°Éh0ÑÌ�mÛ/ç–ûäãJ~8Ѧ–ž0Ìâ ‹ŠeÍúS‡í wÝò‘OËúM§I¸·×õ“þ'ÌкäsÿU)«(’»ïúoÙ³gœd/—å+VbÔ-E%%dø@ÊåöÔñK7L×Ü>� vï|E: U”Cq µ£ƒd¯ÇS7Ÿø47•Þp�Ònò‚Oh¸¤ °HiõBóÉð‚ƒÒÙÞŠ¸!Ƀ�$¨©É�.¶Î�W¥‰F"0§k“%µKø‡ãÒp'¿ íxDº;Úqm¿”@sëàþÝX9¬]–,­•Â:þ€Ò⌡9Gþ@<Ò÷‚eGBp+J‡PšxÙçPë–}Ñß‚/§´�6�qƲbÅ xÐ q”¦·�Z[¡éD�NQB¢ñ°´õ¼"í¡W“aé 'a \Ê×;Z>6,+À&ø‹ úȼ’ó¥8o­ Cu^OÞL�(5g'vÎ�\iôUtLd‰ôS�†€Mk: McO®½¸Ö­¸àC࿸ñúø²y\=I——µÓST;ËÇ#ç±®+SN—4zU<”‘EW¥Òµ2%LÕ÷;‹Cû©Îï;>q.®1¡¥Y*6G÷¶aÅMåsµœ+÷܃ö�ï9»XEžø¡†vì­Db¬æž,ø4÷îùp5æ8ŽŒ±;Å8PGÃE=Ü£Ö*{ZÓûðë'¡7�ùÙO=ƒtN~æz€NË™küRŸNì™Æ:ñ2^LŒ¸ŠÝ¯ê”G`b׎9¿‚³&ûÁ4¯û9¸ ¬>�ckÉJÀJ`öK€mÕý9ø¥¦¥ÅàeàÕIfÛD9¶IŒo@&¶]<d ¯"6«Åð£T °(܆†N'@“å² j¡äASi ¯_¶o{I**æË™çl†ÆP«¼ôâY¸h©\vÅptȃ÷ß-«×lR+ºu„ùÞ­ÿ*%¥eò‰OÙõÃoý›®Û'^r…kùªåÒPwH p­ö¶‰ÂÔÌã J>@+¶ëtŽ�€Ö“ÇÚMœÒwt´(0Ä ¤8@”&^;ê‘ûvËJhþ¨z >ÔX¢FÕüy5ð[³K9¯œ?O*ç/PZSuu{eŪ�ÈÏàÀÌé6l:C9O ,$-Ȥ8Ñ2û°:ÝâňÃ�€UPªkÁÄ¥Ù›‡ýW¢ŸÃG @3ÉóÁü²¬ú"jV-_¾\Î>ûl!EÐÉ |XZZZL¶è±’ýf®þS�Jžw$JîRC¬¾IQ`9À™|d¥ô¢Ôy0šL&„ÇFªzKx†db¤ • ™ê4xêêßOOxj"ðTy| Åø˜Zƒìï}Þ¼p6îÁëèŠ{`CgÞšL¹�åKžÊª“ŽÉsÓ)�¹7¦üCËFÍ¿cM=rø`‡D/X `“m„¥Ù,�€Nö´Ã¬8–|Zgsm�u#$�xæ“í"?ò|J¿¾ÎèvßJÀJ`2àdz+Àg€Ÿ?6_ư;}È‚OÓç^œì’p´¤F€FóiŠ ÄÎæJð?‚O+»o?@§ó6Ë`^wÚjÞÄ& bÆq8Ž|0ùõÇå~˜ØÝõP‡4¶ YÅ® i&ð´[²°˜]`ûBÍ$ª\¢&j-` F÷9æ9Æá ˜ýg~d¦ÈD�‚€ A�jøLZ¾r�4©ÇŠVÍòÖw¾_V­Ù(¯l}Aþt߯åùkI×Ê=¿ùoùõ]·ËÍÐRºáÍï„¶@ó½Ûä_¾üY€Q5ð±ô²{×+rôÿÔÉÆMgÉG?õiÙ·wœt¿ˆIªÔil:€Í'ÔKó Ì/€#íÀh0a®À®*·gç«ÒÞÚ¤üCÛÈ“ŸVÊ»ŠåCC‰@ÍÕ<œh¾® a�†(Ÿ 0;t`/i dPk),�e+V£œ¯*0Ç'Û›N=[Þwó§dá’Z¥ÝTZœiJ+ªäCÿ ü9õÃÏÔ|_i>QS ZWƒ6]pñ²rÕzLU¨g‘\}Ý[°²Ý©²nãépL^"ÿoÃê©pR -©Ë¯|“\|éu¨{@ Dm,/Â=0Œ)3>}+Ó�A jmÑ©ù’Ú•rðÀnÜj<þ¶ËÀ|xÿ¥r¢Cq2Œç��áœPy½^Åö†©ŸçŸ¬>î$ó *j€é8)ðTX‚Âà¹JÎÖÔÉÔ�ÑW2ézš�¡Û\iTu‡FM…Œ% ¯­óI@µ,Ô·Wšáã)ÜßYÈ1Tô¨ÜÏ©L9+Ó{ž ú|rÑêÏ?D’£¦£•�iøD:)óÈyÆìŸ¸4F2æÊé²ñYìîè“ý{[4÷â™§_4K³QªíÁ­o¨ë–8�ÑßSúQ˜�UΨßPŸ'Õ¼ò­ø�'÷ưd%`%0 \ˆDü�v5˜ê†=à÷€›¯;Ø�dÁ§éq¦C)8’äºÐ˜hàgj;Hv4g‚ïsˆñ·K΀yÝ[/+…yÌ8:¡jÎ’ŒBË«rn?‘Ÿý±Cžyµ["™«ØñeãK÷uð`ê;�!gIJd%`%0�%ÀÖ‰Lµà àõàU`j.lâl.ÛDŽmÓ9‡¹‰ �¦\Ô¢!8P»|€‹X­ªOvlY6_t…\ûÆwÀ ÷aùù·Ê¥W]GÝ—ŸþðûòèŸï‘˯¾ÀÉ:¬„–‡ðBƒf��æ×,D+„UÀàX; Ñ VN(.)—òÊyÒrì(´œ¹µ+"Nÿð¯”,Âêj0ï¢o¡Nœ'àá—Hÿü-ù¥ªz¡¼ðÜ“pf{ Ði(wPY}}}Òt¤AÎ8ó<µ"-½ZàŸˆ×¤&Á•N4E+(,•³Ï»X\E¥-Z,_ú×ïÀ�8Ý]0Á/$G*/P,×^ÿN¹€µ‘"@€ªªÉMü¸2» …zå¿ò™?¿ šTn¥a¥Ì‘PojZù>¥=E‡äô…åòàd¼šakUD'ÝU5‹µöæ(<&0¦:”†@S@åÌeò`ŸàYõ ÈœÝÐÓ§RQaòå#¢ˆ >;|.€´hÑ"9ýôÓQ÷Eêx8à‰ñù|°kÖ¬‘êêjåû©«ïL2àã��L Š€%Ïó¸¡á°¼úê6h�u(?P•ÅgIeÑù˜¬•¢ÄCY‹l¸DçÉ|5s4sÌíXÓ8óšH¦ã?ÜPŽu?)½ý ¼mèÉoÇÍü"´²D Î@ùNâùÅ XXéŽf†ª¬Ð^K¸YW Â1ÎPè+³|Ù÷wú¥qÊ6³>|,¢!îo—#‡»,øÄ›7K Mcž$\`r×ÖÖ§L“Õøz–Ö7WµÜðqGý§$ñ£3?±�³d%`%0y Ô"‹O€ß VÚÅØ’ø®QÑã10çÃÓŠ,ø4­nÇI/ŒÓqp”9tšX¹’co&fvìp¸ãšW�÷\U.W�“� AtÒãlF‘˜§Îe[:åž§BòûÇ;¥…NÓ¯G°ü´ýMð]`~uMŸÅ�%++�#¶üZJ„ÚK™6ƒO¯hâÈ–ƒYÆå>·c"T/8DS³�456ÈÛßy‹œqÎyòì_ž–î¹K>ñ?ÿN.»òyêñ'äkÿüYY·éTyýWÉ–§ž�@çÑ.hüB›`|éÕÏ¡¦O Z9nE4­£Ó즣G ©ƒF¥ešÅ‹–ÁÌikiBh†)ŠÃ„ŒFW>h7Á!÷áú9B’ ¥઱±^­Þ¶dé é…£î×^yA.½ü ðçìZˆÉ}BššŽ`«}8�yöER -`9s˺ §Ëç¾ü Y0¿ZJ7¼K®¼æ-Js‰N?ý”]৤[i'Ñ9xõ@áà“©XùŒb^œZSä�¤’|LþÖ¯?EiuÑ”¢ä†w&ßR0lko†¿©´�J”v•ŽBØ„ zÚÎ�É@�RÇ áÍ.(D?ðêî[WW€· ³?P¹PÛd Ò¯ä‹$†pÛP¤Ý´iʼ^r<9ðds„«|˜N’Œ6”:ågÙ÷íÛ‡ûÙ‹˜. ª¥$¸}[%ŽØ…±vIY(I8d¡òÖÇjWý0¾3ŽkLŒ4•ité(¿þèiéy šO)ƒ.ô ð÷ÁM`sã>%5Ÿð¾€JOHùìDË.R$ÉÔŒñ˜¥ŽŸ®³®#›0SÛ´NvÞ ]~–Ó-IhÃ|:í¬ExY/K³Mhv\ðÇ'vµI¸gî)Ýó™÷bÅ;¶¿l™ íÜs¶=ì¶>'Zü’övðÍà•`j;9‰~þž–ó_Û8o•Ýט‚q�fæ£úŸ5Ë äoÞ9O6,ó©a"W‰Q;c�=A§þh\ßÚ'¿|°SvêÍv(Þ…lîÓÏD=xîõö¨´%+�,~­9|6˜à;Ø ð<0¿êp¦O É0v³9Ÿ&q0S#èSp¡véŠDaqY¢»«ÃÇuéå×Ég_ {vm—G¼G>ò‰¿•«ßð&¬þökùÙ¿)ëN9>”6crxTiªP;‡¾ŽÚ�Ä`í5ìp«6ÐPªÄ5£ÒÖL«#8Ò†vÁ¦^øOâqYy¥^êî“Îîv)‡F“Ï›'ÐŒ¢iZ{Û1©Y¼`Ožtt¶É ´yè\­ ‡|{¡UQ¾D.®•ûwÁ‡H¯œvæ9rÍõï�… —²8ú: 0j9Ö¿O Yºlµ|æï¿GÏ^4·lt�ÚÐ:çœ q¸ ý�—ÎÄ™ óa,:êv#¼ °qâÒp‡ÍºÊ�‘rCõ©Ü烋ªáS꜆=r€ØÂ °(G–#UT·™ÞÛåÈÑC’‡{äðë„û…òÃŽ¼£µ âݲõEŽÅ4t\¼x±œyæ™�ÝBuŸÇ :9ã ·o®“kK_QÄ=ÇýÅRä¥Áµp6^Ù껣»N U¤¥hBMsœ¼WêB'* ž €š‘X³4w?-�½{ wz]wý³Ì (ìÓE×À“ŸÜ.¼›0»s’ ÚO¼Wq¦ª|€°ŸÎB×U§É®·9¦ô�,•qzÏ„2DÇ99iLÑ.··…¥n›ôtà]d³ç,¯‰i·3Ux„x¦]]Ðx:xþžúÕ3>Së3±rcA µ¸€ßédu)ò²sω Ô¦šÛ Æö&ðuIæ™g³;�Cû,˜~Ÿ,ø!Xš¾àJ‘¾š£‰o±ZvŠ8°\¹¤@>÷Þy²z±_b\r8âG~‰ßy("¿èôäÖn•t•Áør=þ÷äÖšØA–¬f˜8»ü=05šØ¡íqnq¨‰@P!´†æÃWÒ¢Eµ²@Õ0×Z°`!ü U(ÿK?ùÑ7匳.”ÿõ…Cƒ®?Ýû¹ý{_—K_µ\}à òÐ}Ê–'TZF%p NS1Œ–¡EsÚ80íRø&h3©ù0-LŠs�æn^¥}ØVµ47!ü/AÃH•4·ÃÖ�òÕÈFøGzeë_dÏöWàëè2€dHWZ®lsu¹�§n’ó7_Žë¡YƒVUftÕ5K¡‘ç䱈—Ëßò^9õ´sdÑ’eÐÜ)‘¿ýü¿«¯ËÅ\»èàœÅ;aÒE0Ì‹²æé&—é&˜¢Õ¤B“çL·˜G•@;‰æbÑ&CÌ>?¿DÖ¬Ý$O?þ'ܣÓš�ñ>•É›ßy³2yóÃTÒ€An|¬À�“m¯l•;¾ÿuùó¿‡ó0®çR¾�Ö­[§|;Qó‰iLºÉÔo¸´¼&óç–+äxjkƒuí‚àR) ®‚BLPÕãž;'Þ-Þ§ô]c¼$`ÃÝt\ÒàÅì–¶ÐsÒÚNà‰W~: �U€6Þ\–€•§ÏRjú_>¼Ì�°ôÏÀ®2›FÀß�·‚§­†m²o›=ž à•ðÓs9Þ š,©Î“Ͻož¬Zà‰½²êƒF¿”—ÅCqùÝ–¹ûáii§CñT:æ²ümð�à°ckÉJÀJ`fI€�);Vj9)¢o"¿Ÿý/̵òòÔ oÕÕKdÅêu0;CV­^CK¤¸´¦c>`5loh²–�çž}Z9£.ƒóëJ€B½0ñ¢?%jðhÏ@~ СF�ncÝ4äCM$Ÿ47Áiò œkçÁ_Ú1šG �u÷ã8ŽUãØó+=85"ÀC³ºb‚>�¸†G/©•K^�,HD°¼¢²Z>gã»ád|lÇà§ŽþЏr}µv´!�…rËÿø[Lßa²€UéhÖwÕÞ í<ø�ZÃ'«°Üê5ô‘„ †OÉHkĸÑÞäK ´ª¸R^4AÙèÀÚLô•8ÇüC³A/œ{Âóxæ}“!‚O~_P.¹ì:©]¦ýhEi~8)Òþ—(?Ê‚:ø ô îÜ M¶Ûo…sç]�u”>—Ë–-„o'Ï‚ €Óaµ5ê8’žx ú„ª««S«äQžù�R^xªäùèçH=eº0ºTüÕãËt)õ1cé0ý¦�Ç’ÆäjògšDT:Ã;¥#ôúã0/½SíO`?ÝCóŒÖr øÄ/´xßðL+‡ãæÚ %¡^éJ&ƒX×t`z/_ÇJÅ0’Ññø«CÒéLŒt®&䄦!€ �Ä:¬xW_×!«ÖYð)y+gÍÆ |^r»[މ9>æyó�»Cègù"¸œÝ‰|2XKVS+�ä˜/Ä„ _Ÿ9,*ðJm &~cžØG{ñÙèµýrÇ=òÂŽžl;Ú³Þ Æ€WPÓá�ZáÚܬf­¨úÁ7Eù0[»òšåø#â nEjJ$XT¾‘Ø' 1¡úÜàaÛÁ‰¨;�Ù.1 '9øÅShOez �’€Q)4† abvðà^˜IЦ `‰û}@»XåǪk]�]êZKáˆü–Z¸%ȰzÍ&ùÂ?~SJ`Ò†ù¥,Xô7ŸýplàÊlË׬x¶“ |(çßXÑ�ÀVÛ±cðãã}˜Ý±„,' ’¤æzåÐæÂòõ`]žIO¡Ul¦PÄ•ñòá�ˆ`Q ÚRÈ"5gLdëF™kQ�ëo|—¬Ä ~¨Æäe)XQydÈ{“Yö gŽ|xï©Ps÷ïŽï~Mîýý¯àWªG]ƒ+Ù�rÊ)q¬d炟&ÉOÙµ‡)´xâ~KK‹òõDí'¯'(e§Hq`5î$Í!õ=W7+}ËxëHúYéÐÔt.+�N1ZKçkRŒž†À^¤QºûwA™ß{¤úâÁ?b?W?LhN69xÆ=‚F!ÞµÑI×Õèu±®NÒﲑCæã­CÓaécæ1=ÒPC’1»w4Ë9ÔÂ�µC,Í  �DK-®È@LvnkÁ‡��ÙP­q×�ï¨>Ÿ¼.*j˜·Pù5¾'Û›Œ»L6�•À4“MéNoS³i#Ø€Mì(9ÐK½<ØÏE|�nÿ_0çÆÓž,ø4íoÑ -`æèn’—†"¾ÚcHŠ×b``_0!áäi䌙¦?*ò»'zä¿îo—æ68OwQ4©ûø6ð‹`öê£äˆ–¬¬¦»¨µxÀYHšy= ŸLq4ïýÐ'á»h# —ÒÂ!Ф)÷ëÏv†ÀMº×ÆP�dæÇIt14ŽV®Ú¨L÷h"Q�•ÎÞüŽ[`á‡ãîM0mûì¿&µð™”„¹LÜè+©β£ÑˆÝøö›8ÄF™R®ÓÎ8ÅÒ~”ø¥›¾¢ñÚÜŸŽXF€Z%ÐÎ"ðu´±Aù~ò�Z$•†•Qd¶ÉÃa6:èkŠõäwÊ`l)33dŽ|–-_-ýäg‘�àXJð™‘ÇqÄêH›X©r_b„ÈbòâóÏËw¾ñOò—-�âEÐy”O§³Ï>›>ž°€¡^Á0w.Sš ͈Ût ™õÀOüº|7òüP¸õ¹±œv+@%´Ÿ§ìw*ë4³kj”þ¾]þül—J«û+Õø?�è_ó +A§i­VˆòY²°»Øqþ+xøàó8�ïêl—ûîù•<÷—'äMo¯¼÷ýŸ�ùÕUk2 GbÀKbBÓ³%µ+äÜó^‡ÝËàLÛ%+Wn�øç[a¶P޹‹áOé-ïøbÃ�8̃~Ù|ñå8Ò`R~AžÒBj‡o¦€±@EEàÇ)MzL�nFUÛ•9P0QÕ–çi&WM®ÒŠyÒÞŠ|{º¥ZKtù4Q¢ ýõbu¼h$Š�ÿDsÒ²ct=‰u# wɃü½üè;ÿ!ûöî“Ì׬Y#gœqœÁ—¥ÀÇã]'ðdLûèdüÀíd<˜W%e…§ÁÉxuBáh“7Éèù¤GŸ:t§÷Ol”æv]áíÒÖ³}z/ŸÐñ®üÛCªðøÉA¬ÇšêEÑeæø:7%2¹˜µiUü¤?(zpÖáÚp63‡¡²3’b*ß7³¯rÈÛÄ0ñŽWõŒˆÞ·»Uöîj–µª”š«êÒÙß™'�x‚:¯ k‘—Ÿ;ŠEºññýÉœ¼µ|'1À¢ zN­î'�'jv°=à§ãAì¬L›ÃûAf£Ãkçê›,A.hB.—%·,£ñ«Ã´l�4ú��É“£‚îÐþ”ð±$S%”6ê½àŸÓ-Íq PÉ‹é\~x˜Ï¢œ°›&jÚWä{eu©WN«ðI/ž¸?êSÓ±ÔsùUÿxr>™žˆ] >�)ÏŒk¤ºFNø¦‚¨ÁDÕrR Z4…I]$ëSÒÌîÕ}rÛ]m²ã@¯J“ŒÖ†íwÀß³q?^²¶d%`%p’$À†‡ƒ¸ƒï¿ü p ý=RSªÿÒ/È{où+¹ ý3Ño’ bcˆ 4›Ô� ›4À§³Ï¹XN=ý\ñÁ¬- š§••ÏW „þ,‹¡2|:é1*µ¤¨M‘$dF¿S¥0�k8|HiGU΃¯–Qð/“|¤­«ÌåçÀ9-ò ÷H¥kÁHÑG<ǺD»ú†·Kãázhcbò“ªÅˆigÚIj;±�i8\'?ÿÉ·å7¿¼þ¶ÚÔý¬€iA'‚Oðõ¤ïñ ¬ A'šöuÁŸØ‘#GdûöíИëÀ 1¸F ËQ>kúÒzqša1³ï˜>æ/ŸjM'*�¾æ tõï”æž-0»SšýÏ¢ì“_�ô¨×qtÁñ>¦k€Ðœdj�º1ïSæúZJ¿‘ƒ•&”–€Î"�¯Im²N§¯¬ÃNn>»­-aÙµ½«k†dÞ‚B9]FS~»�À3¥†ÏÔz õ ÈË/…?A~'%ÍÕû ¿�n˜¡ÓÔV¿tœp/³ñ›,dªSsd ¸\&˜Ä—‰çI�pW”v ¯ÏsÁä1ÃysÈÎ}ª°tóÁ�Lâ9'³$ÐÔ&èD@€ó—£à}àƒà½à0Á*‚W–f¯`Ò¤îðU`ú4uj8áÐ�KŠ©)òÊÚ2ŸœRá–5¥Ð�†ÇŸå�=!ié�9ÇlX¾þxFO¬±Ÿ(K”]:ž�(zS2Wq4É4›s8 Ï�8'œ0Ýÿl¯|ÿîV93»¤I ; pÿü˜/sµd%`%0{%À÷üø›à-àÏ€Ùy»úúzeËãÉžÛäZ€+ï¼é#pܽÚGÚqR¤†úDµ9ÙåÚ –àÌóèAª1M{*•#F²ð÷T GÞýðÕÝÕ¡óuœŸè.ó­®Y"½ÐzÊËcù&š“®ZylæŠyjÌ�ñ÷}P˜x©¦6%ï'ìç$ÜÂj…Ë�·ß&/<÷´áè\Ý‹Õ Íì.\¨.c»N: ˜õôï—æÎ-ðÖÄÇé† ?Áœî1�ýôhdŠ?J<–Ì™ÊÀÿ¤&”ÀOš‚‹ g7€á8 <<Þ:�(Ù�xœ¤_ º}íXù±; >�""{zÚJ€ã\à‰ª8´¿Sâ¾F#s×äNß(øVô|RSŒÔ­«Åž†R�cÜáä}ø2ðæä>¾©üøºÔâ–œ‹F:—+þD¨åÂ2±%³¡7L`ª\&µ¼Ì1�* ”‚f(ñÞóù|øõàÓÁÔ Õp¢ë‡…ÔnòË©Y]æ’E…n)Å›áCC²§+!ßÜÕ/ÏKý˜¦év¿þ/pxÆ‘ŸfÜ-;nfƒ­:ƒH„ŽXuË�ñ¸�óÒêc%Ú]ÕòÐb€œ§sõÁÌ®³'.¿|°K~óH»„ÂÆéªš~„Kþ+¸ì‘޳$6º•€•À ”UÖ :ïßþkðRN⛎‘Ÿÿì;ò—§•7¿ýpHþ6©ªª†Fz`’nkL‹£¶“b¼p ^ZZ�cZ,-SbJA ½¤¸RÞ÷Á¿’¾�>)ÊytN>Òõå›]¼©ýdrœ>iù±"”m¯¾,wÞq«<úð}Ê4“ÏEÔoذ�ŽÅ±ê`1âMNŽ£ÕÚN·¤µµUêë륡¡�ûn†ñœ~äàÿ “°²‚M0·«IöŒì §è~’½nfïaf g†Œ%�~ Æw\ý5'�}ÑÃÒÚó´„êY—F¨›Ý.ñ¼ßâã~ßh2÷yVħ–å5¿4Å£E“2jÂõG§ýJŠ÷Ù)9�µÄÉ‘#/äŒsrÒPƇcÕ;ø}ÚxZ DËRZšiH®fçœQÑk/5JKSH™É̽Uîœw/³»Rh|r¥kvéŠjñ«æúpÔ_¾Ônº|5ø,0µ—ü`žKJ{$•‘CdG--Õ¾@ Ú•à ôáÅoóˆ…yŒêQqÎ�U;#ñ¬:ú ] ß´‰ÄÀy˜ £¥AdåØ�%ÒZ^J;DŸ@¿åà‹Ál¼¢`jJµƒ9ß©7�ÀÔœ"`EpŠñfW§Ž Íp¢¶Ý&0ïç%`‚OA0`úÞc‡DÀ©ºØ+›Êüræ�¬…vÓ,Îå÷`ucö·à£°±ûc}T€™]+|<)å~�œ¿¯‚ùAöq0�ÌIŒ%+J > âI×)B'Úı�V€“.ßœ XÕ’yôòž~¹ãÞNyi'V³Óo¯HT÷ËàŸ€ùrM´HjÉJÀJ`K€ s ø»à-àÿ ~FwÞ~8pÞ¹ýeùÆW¿(ºÿnyÇ»?,¯¿òz8/†6�ƪµ¶I.ÿ0Èe¼„Vˆ&yùùEЀÂòÑ$LÑD«´´BJ‘å‰ÐÒ™ªrŸè|81Ë£þQ¾{Û¿ÈÞ=;$�*m'8WfvK–,QÇÇ xâ}'èd§öövj7)&øÔß�eÕÑÙeÞG®¬X åE§IIp&2ðé•áÔ‹S»:½—ÉÚó À±Lþ†¾ý<}ê•9q)4CzERU·=\XÉ/À)Nà k/ ÄZÐ^î–y�ÃRˆ p a¡¥PÛ8´W «ÚFùXpÎe€ jsñŧ½ýZ0)2cs0CmpjDq,D@Š&|{’\‡-åÈóLcéøJ€÷¬¼ Lôlð&ðBpÌgSw\ØÑä–yÐpÚTî—óª=²® €Sž Ïž>Ë¡¤ÏSË@B:S SCwÀ¦I¯¶<º üeð~0ËK9_à[[ð‰J€ !_·jéðˆ«’¡$6òôód|�(ð ™3Kj;µv ÊÝ�wËë’Žžâ© ±‘}üyðÓ`«z !X²°jX¼þ˜mÄGÁË9Á§ƒîŸ}JöïÙŽ•ñþ ï~ßÇäÌs7Ë ˜ã}àß–Úe+О±e#Oœ˜WÀ»è²«d ò\½vVS›\ž¦4:üNMv&ÛY³åàŒ€OOO»Ü}×ÏäßþŠ´6àP‚pξiÓ¦´�\EXm�÷:ø™1 $Ñ´¯­­Mi8tpʼ®žøà€„#‡$à›¯&dtj�!("²g4÷_¯|—Ní|(8ñIOrÇöÀäJ3Jç�DZª]{ï r¬k žó^÷nÂm�ýeãzgÁÒźNjq|‘¼èH×°­­/€+b‡š$^Lk9éËò—Z<£÷±; eÊŽ‘G*‹Îlbi²sþ:|¶#‘˜¼ M™=;š-ø4Ê=œ®§�wxû+ÇdïÎV¼71ÓµÄ'¦\ªõqåÃÌ8_½ËI³ÚE¸z¸ }å!´ !oMò:l ΰ¡Ì ¶©Aÿ< ª%ÏS…vµ“ø"¬®„Üù�±Eê]ç/[¶)\uS·-º�ÑZ�úÜg;Œ–š•Ü'°EÒ­ ÷˜ŽP7â.Ìkò|Ëdõ¼*yãʧe~~?4½\ø¨—ð@\Ú𱬵»G{¢R>Ú—f Sa,Èäè¯t�Ò /D*Óú0gK†)».0?Ø”:>Þ > fXxê5T‘é!‚‚|^ׂiBwZrŸÏ/ŸIâ(d½éX¡Ã×—ûäìù>9½Ò%5ù€6q‡QõYØ¡¶S+ ÅÇ� Ê}‡ÂRß~;åyÕcÿkàŸ‚ 2f�FÈ # >Ͱv‹ËF�Œ†�?Ü›ÑÊN™Ú%³áWk†=¹µOî| Cvì…ÓßÔ…h·ÊAí×ÁT1ÅëgÉJÀJÀJ %¸ø…ï6ðãà��o—„hok•‡ õÒ OËW½QÞú®[äíï¾ M™G¨Í9Ybn Vçϯ–ªùUh ´öËdóµéG–ÇütÌÜxô°ÜùãoÉ]wþ@º»éoË% ,Hœyæ™ñ+V¸éëÉ1ˆ9Ó1žU_Ò“ŽÃ 8lª««£?'å×i¨†“ʘŸ÷9øç u%ã,˜åEÚ¥9ò,& [•Óq®ð•€çÁož2Mñâ뻇_ß]Aõ¬é M@Ðyœ”“ LÒ&fÓ” —džåÐWM3ÆÊÎ4ˆŸˆHGï+ÒÒý,úhv͉tÉžäŒxb±8®àXS�/Ì$0÷Ék³„¬³ƒ†—¦XþÌáãf×)ûØ‘[j7;Nöq*¢c';Nö±ŽšQúQËF`uÿžyâ‘}²rM¥TÕ#›Ì<E°»ÓHls 0ÁbÅ¢ƒòÜ–ikîUciç¹iTìZjù¼t:Î>S½»4;[Þ v‚Ol/ß ~;¸LÓ%Õn`«Hi£Í,¢ Åyk±ªv —´—I³8K·g|7‡%Çë¥ã9ã&÷],ó"1ÌÙN2UòxÖëŽÉyU‡¤¦ ¢ `ËïuCÛÕ- ËŠ±:.V=�Å ¹]øpÕΓ£aØØ…â£àNÜÞ�~áncýñ>YÝ °(òÀ1�)jâ@Š (dNl«9ŸÚÞ ¦É5¦ÈÃR–&TZ>L ‰àg-˜�2û1Ó—éÇ)Âó] Ài§3*½²±€S�[òM1²¹“ˆ†›ˆ•Ýûò@§?×õI=´$s€Nš~ ¾¼Ö&÷>Ù G±p¾ª/ÄFò)ðWÁ�€ûÁÇ£ÈÖ’•€•À,�†kJû‰ª{À_öÆàôéXã¹ëç?”§žxHn¸ñ]ò¦·½O–,]"‚áÙ“w¤©† ?tsl›©qnQU‡„¥çãƒ8ÚN_…³ù•¿­<¬:¸zõj9ýôÓåååJ%i*€'3Q4+ÕÑ„®¹¹Y:$û÷ï‡æUž#šN é¢è‡cøA0û±fð'À+ÁIâT%®Ì3è$”Pž$ü¡ƒ¤‰5¡<^LÔàKÄ“¶>€Ty‹¥È¿ U òâ3œýü±<:L—ÌL’ô´J`li¨]ÔÓ·WZCÏaU;~4'ð¤¿?–“™!•GØHÄûÃA=\ßFKkäN„rš+ÐÁ“q›¢Â(-ÔŸ+gePÙyi0…Î0×–©˜1Ï¥%x<Ò¤&ª9®Ãë `Âùü–z9ãœÅrUUî½.“*˜ý™¶0m†)à¾Ýmòòs §£x§Mè\Þ²-‚Ƈ§\m“’`{@3%ÎA9¡æþûÀïsâŸÎ��úâàJ)ÉÛ(ù�¥h#éÄœÉÙšfÂ48ÚF«x©ŸtÔT�sÇ´F SŸc¨n/Ò­FòÀø’’YUÖ„ûOZoè+hôïâ—w¤sÅ£ 9 àp~À%óazµ¾œ§Ü0±ò*ð!Pª!8ÕŽÙPK U\Z0gê€YV7Â{àÄ~Sƒz<ÃB‘y'A%K˜;åy˜‚"šÖÞ~ü˜`=xÖ¨ËXˆ&r•àE`j5lÚ^6æ�ìhÈÙ²E/x±ß#U^YÀiV¨[]â–øpÂÂuꦘçDm‘ Ûúúž„ …¡%i…/©F˜î�sê,ÔÔÓ¾^ô<�ý1é…³ ¤Ös`%È$öC¥ƒ7ƒY Ž£v�ÿ~ü˜šQ¸ÚŒ'ÖµL�© ¼ׂ̺—€�yŽÏ¡‘o–º=ØfAÄ’<�,†ÿ¦å%œà,¼¶È%U0§Ã!>鄿s«ö‘›7³>”�ê:5hGâ9@'Ž)/¹%è4I|Ê”Ç\>â˦^¸É æ‡`?ÃÃM} ØBÚ(ÿümð0_8KVVVã•'ú `¶%‚ß~xÛ±¾0ù¾ò¼¢{è>¹éæOȹ¼Ú%^˜âÅÍÒt“€ÚNð+$Û·¿*?ùÁ7`Jù[h„@Dgâçž{®ÔÔÔ¨bOE_E-'j3Q«‰fuûöíSà};åœø¼?æóÆ/ÇÆ„�”wbWþ~ÌÁ/Áàà20gPT&¨Ò¸ì Ô°bòÿKLdâørN×Sª£NÅfŒÌ�Ô)ìð sËŒ‘# l"±Vi½�¬:b0t¡ŸVàSK2lÆM’ëÉË �§ÌÒŒ;GÖ•R“{lun€  )•m’çÌ{Lrp&Àþ‰JÉæ üd>¿¥N­zWU],~ÚíXš1xæñ:yìOûЖÀÑødñSë±4!w%&çèwÓÝîyHù-ðå`šá€Di åÕJEÁYRÓº€›M&Löø6¹òÅ$WBË ðÇ£4¬Ì…qYÕ(è04@ªÈß+ ÚPvT„íô ´M‡âæLvñÕU’'ÕuPa¸“‚+ $à?M¹˜5Á)äIpÊ'Àœ”æT'4£Ú`º×Ø¢ hÕ‘îAiTšSQ¬VªüKñ”µ‘7µÎªÁ�YPög£¶�÷ƒƒ��ùñ¡Üæœ-}'qp‰ÀŸj+±µàeàå`N çyJ�ufädÊ#ч…ÃŒnQ¡G–a…º%.YZ× ùE‘•SMbs?¹5ûl|ˆÔóºêéH<,�!­é”uAÊóQð�À7ÌZÐ uSd{6# »å;ÄR¿8æí™Œ\2óˆ¡!åv'˜ŽÓ÷ƒ3c!À’•€•€•À8$À6„mÉvð?�þ0øM`øƒŠKgg»<öð½²íµ—äúß)ï¼é£R»l94ZÐÍ2-(5rÎ|°ÏÃÔ@IE€d %Ï™Ã\ÛT#�ÚÉŠ…p5Å–f^‹½ ·Ù–ŽÌB?Ür°Î^@MJ�IwO§ü龻姷~pváE$(3;øw˜Ù)P©&Lœ\…B!9räˆ2«£¶SWW— Ï2Ïd‘9èþ3˜Ã'Áõ` Fñ|.â¹f0û=UelY[2é,0'^¤QóJM(h#š$úIáD¬ _ÿ½nj=8Òd.œyÌPbΛc¦2a&�ÎÉ� Ô€t÷í„ÉÝÈ7‚DîãîÝŠó‡ÉtôñýòR†“)3¯>¾ìLläa*crU2”:©aôÔ¤UÅI_×$5!ú˜¿:Äœ7ÇLnÂŽO¾/ð‚Yã–Çö˦Ój””*¶ý™öh¨ë’ßÜùª©§¶KpwÚ×àx0¡|>ù=…ÐìdSªÞ¤ ’;U&hþäÕHeÑyRšwÚ»EÅV&¸&)¶'’”¶J¡ ‚&�L<0÷Ù“«:©)îÆ>øurC“u"¤.1BBÕö$#%ÐÞ±�…4Ët¢ù0ùr#òŠ”ŠÄ}¼CR á„ì”}ພAi�ÃóÑ«L0jŽkÁW€y%vFœxã:Á|ÀCIæ>à – €9#yC¢âñ<�‡ùð<óä�ÁT×lY³Ï-�Ù_« xD?ŠÔTZ–d–u˜ S98f\ÓÏrË<ÈÃúØ|hœ•½2/æ“E^©-v+­¦ê8ǹ —ãâX ¹˜2Cî;�yž«¹3f+jJGâ÷×…¥ŽÄ¡™Q)—ÇÀ·ƒ9¾ Œ8n˜õdÁ§Y‹Ç\Aó’/8›¨ùûÀ/‚Ù͉ õ´d%`%pb$À1ÛªŽïÿüqð¥à¤?(8­¾ã6Ùúü3òþÿµ\våÄï HlkAq°ã‚¶�Ì�(A@ÄÔሽ?Ü °�ô‚cÐæ‰Å賈LPŠÚa}0ok•�p?«ôfÅAè¸lµ£ZdäŧW#)R1cëõú¤ ¿@ò ‹ÅëóJ@�¶¶htJyE%V ÄJGJ+å„yÆýÒÕÑ&�MÀ6PÞ §œ‰x~ùéÿSî»çWFKKKéÛIÖ­['ôõ” ¥Š3ÜËL É;4¡£Ãð(ЉfuÆ�S–&É4ï?~ÌÁ¢8cwLÄç’LÂ]Qt~¿~=XM¾*++eãÆ�RPP LþèØ¼··u+ÕdŒ:f¡ïÁ“1UèÐc’; Ó1aÿÀ1é ï„£[¨m¸=wÃÙÖwq¦lÊ̘!Ž-pÓqõÌh€m"�œF×�þSôjV��š$ÒD‘ddeä�¾)<›L�’gú˜ò;it¾ס|¼mk“<ûÔAYµvÞ=ŠÎÒt–@ž‚ÿËíòÚÖFÕ¾â6ZrH€fÂnWü×àM¢›P¤b|ERQx6´�΃¿œùÉp¼ ”%_òÉ$ô—†X”t±èßg@Ö‚†V OÐzгë8>4’L Uöï(Mù*`lWÿR«¡¹“¨†iù OÚá?Šf`»;²«#*»c£bì_™ŒØ€ ðSfÖ†±›ÚwËœ7[Îõø¡†LÁ�¹Ï‡À¤3[)2Ç, ûÔ@�OÔ .³Qd¸“Mõœ‹8NÈ5²"8d" Tõ¥EE`LUíæÁ1|1zcàOè“÷Ø”DI3]açÔ…ñC-'L{!Ó'£òÔÑ~i è„4•�NH`î^ðOÁ4wä¸bN͉�êniŽK@}(T—¬7e äÂÀôídÉJÀJÀJàxI€“eú1`çN°ûmà�€×\è ‡ÕŠx‡ë÷ËÖç¶È»oþ¸Ô._‰UŠ0@ b3ƒˆ“Ö©³½Cöí~ N±wÉÞÝÛ¥ Åà`LB=!ého†æW›„E%@§8 W@ ÒÂI{ްÌÔ<»úz`Å_…dŸV€— ¾<|þ€äçcImQáþ�ô÷ÒQ “g€1Žä˜ÖD\v1”%Pæ�|*,…?®`~¡ÔÚ¯´�˜nñâ¥ôï”X´h‘*ÆX�'8qkÌê¨ÕÔÐР‡755I–¾f~Y€‹F¿M�ƒ ~ LÍ%”ÕŒ ÛÉË—�?¾Œ•–]BsBju-^¼Aø„ ¿S4¤\ó Á‹ÊñvÚÕ½–¦º+êÞqª¡»íôsl@ªô¢¦'øêìÄêv/I¨¯‰ÿY¾ïãZ{qÁ©x!XpŽ5qy^‘"0%Áî”òÖW×Ò¦xZCÁ)}Y†hÉ1‰’G²<ú8]R–˜dbë­I£c�?�.*ó6áóÐÖ–GØ+—_»N/¥Åˆ¥é$sŸM™žzô�<|ÿ^éÆDS5sênš³vK äXñ.%˜’‚•RUôz)¬Dë�T„2/…=íoP&¶4¹+ ôÈo£Bâ†É}Ò� ñªÉ“+Í÷j`:F>>ÆDƒypl­¨nQÔŒêˆI3Ž;ûb†_T©%z™ß1@IDAT+ô�É'C¦ˆf;Ö¼ÌuÍv˜t`*°Tâ÷bå9‚Jla*ð­zQ¥@ãJ %F §±(¸“È9ã¶!ØÒl�eA˜ÆÀ‰â9Óºmmƒ²¥)*¯4H�ÈáÓ‰cÔÌÿx+˜š`S1®@63‹,ø4³î×ñ,­f¾€S{ÅQŽ©½˜ÍÍJÀJ`NK€_’xü$˜ZPoÆ¡tìX£üâÎïÉÖ­ÏÊ{où¤\qõ›$/Å¡F®á‚§±1e)Ø-·þÇ—ä)®7@?Ez56U€iPi€% 8Ç:´·s8Îëñ"êG�®ÆrÉ0üsQ;‰€µ 4¸iÓ&wqq±k, “œx-æCâjuÔrâJuõõõá:•,räG“�àû’¼ [†ñÒÁÎ$‰³ªkÀŸŸ ö«­­•³Î:Kª««U¹YÆ#GŽ*­'Ÿ·+Ýé•�ˆ™{Î-))íäöÿ³÷€Q]WÚgFÓÔ‘„èE4SŒƒÁÝNÜÇ-v\ã;q'Ο²ÉfwÿÍfK²Ú¦nzœîØq/€mŒÓLï¡Þ»¦Ïüßw߼ѓ ‰‘4’î�O¯Ì}÷Ýw^¹÷~÷œs¹m JÇvÇz§c@ ÿ{ÜÓ+以Þ/vTN}wzšMGºDäÑ‘›^ÓÐÐèµøâèÒ6àkÀZàKÀdH¼ÞvÙ½ã})=yLÞ߸VD@òÙóð,ÏêՄ”É*øZÓ�îÐ�}²nõ �lß ²œcÝA‰ÁÄIÆL�:ÕŽÙìNK�xšØ322T +Xv ,»°‹ aÌZ’ŒäËî°§I†{Šx£Q¨bêã&˜·Ã¬`»nó¢¬ûŒuÆ]iôî—š¦ÍâÂÜJ¢/€x¢å-¾)|xÿy‘ª£©\ïXŒ�ŠÚâãm>º\ÆD•ň¥ö`›eŒÂJËÚW0»œæaF^&±Ôýõéá žºpo•¼ø·]2zLºŒŸÈàËZKêî²·“öÖ€üõ·;eãê ñéS?uün¦ÓKSˆ»uHnÚ¥ì|v2özûª� îþbŠäõ ð�7¾Êv�Ômc¤¨e–,ËÛÏ~zÏAWÕǯ?¿©¯¶ºWü*òIúX…×?z2I ªL};A^©Ö24[U]ÏkÍÏÌËäÝ-L1FHdæÝ‘^�DmšyšËŽ4k,‚¿|,(Eõ°GâI™–mÔàÆŒÆ ZÍ`˪0PÙ–joXÚÁ´Ñº© 'ž€í¡ÀËÀ à(À8Wšt‚L±6.Í}z925À§ŸmýF¼`M°§ “ÆÓ¼\gÕ�ú>#•j»©Ùød‡F‹Ö€Ö€ÖÀ`i€�€]­ ÖO‹t |r°p�üð»ß�õkÞ”ûù¬\vå5˜EÆ�ØEø0ž�áñ-,ŽÄËü –È—þñ?å7?ÿžìÙµEÏî¦,$}Ø z I(ä ÚŠlã™í<¬*)ãviZò§X;T­ª?lC²Qe6¬˜'a¶-ͼ¹ä~D[P.gÔ{ H—ììlóhöìÙjf»3F*½Õ­®³Ô1xøñãÇÕlu Þ�[]8%ÅÑœ™™ O<ßhŸÏËëc�W�,ë/!ñr'ðy@Oùùù*€úÌ™3;]+ɧÖÖ©®®Qî‚Y©31óSÄ¢²éNõQŒN�Ñùá¶Ù 2÷ª6»GLAáÑñ_P1ûƒÕF€ñ`Z¼ô‡.8~Nàüf‡³»G‹)úQ”Eò§Œ?†RÌuî6U¬ÖÙyBwJu�ÕA*�qLMZ¯ÃXWÖSxŒ¬Œt<_‡þ¹Õùžq[�Ì”†e†Í_=(3aýtë]ó%3ËàðTbýg@5`>fpÅ# •Du=užÔ4ùàõ·ÈÜó—Èê·_‘W_~FŠöí�\òbÂÏðhà^àf€�¤�À›Àf èoa&Ÿ‰­;iµ4qâDåzÆ Û”îˆ'vÄI8ñ7Æqâ u N׺ÚÚZu­ÝY9á¸À¨œ¼ÖK®¸¦þ–Ûï ú|þ±ßù�/;*+Êx*6à&s¥Ÿ„DÛ­‰¶y(¿�ÅéRÈkæµ[¯•寫«—ú†zÄüñ€xš âs,es˜.cfmjÖÉæn¿uìé¼m}fm žèn×Ô¾Æ�³ ‡ð;‰§½€™9V&$àEäØmX5-vŠžf½ôê ™ˆ³CÃæÈu®òÂÒ¬ÚÉÅþŽî'á¶q-‰±jØXmŒüø—÷ÓÛ�gÿ´C fäȲK ؟σ‘ÆÌI/Naø-ù <ó»] ŠÙ¿4îÓÀ•`œ©Wï`r]¯úÆFa±eëo¡õS½?[^*¹A|ݲ {?Ü·0‰,.‡ð¥öJñCñ:[á*‹É©Ä‹íew—ÖÒ¶¡ÖÛ¶+Ùð2¬&Dh=}ðÀ¥M €Ï´(r¢É§!wËú­ÀñÑIZ;UŸÕfSƒ•}>!c¾rúÅ4ÆÜÐK­­­�AÖ-_öÿ ¬¾°‚·s¸j$þo¿“�ëWɇo½Wn»ó™>c¶êR²’,BÊŽÎü<òi¹áCwÊû›VË›+^”ïoQSâòCÌáæ\`°ø8Àë_¼‰n4!KåÆw–Ôï’26ÓÍŽd̨Q£:1ø]uòM—º6ÌÔÇ8N NÒ‰3ב\ëŽpⱩiéÁE^¼ñ#w—]z•gÊÔSSaû;+ß²{ÛÛØN¦>XÁMX7%ú†2ï;€¯ ßÉNK'ºÒòɰjéh®sÛp¹«Ç …-âtd‹Ç‰8?ªˆéÈvXi ƒýˆ×±8UwÒa«£.›1WÚöH}ËXôµ·À|îU‰¸ß†gf¨»£°�íLÕÖ$ñEK"ƒ$³^WÎÒŸY˜VS<Çi‹�û`ùÍ'©Œclè Z~V¥5:²°uR·°ë¯H‚ý$]‹�6È3¿ß.ã'dËôY£Õ±üÃwi=ß©WúMÅÇä•gÈŠ—‹¤ñžHJžííë·ÂèŒM6�OœEÓZmðý®÷gÊ‹'¯“âœÉrù˜­2Æ]­ž�nÞìA+»>±YkFå®'§§ËѦbS.ú^L8ãeõîŇÝ$™^Þ0p£È&Ö�<(·Úôbh‚Ù-ó/.2¶W(3€!Ëá Ù‚+Õë?‰ÔÙZB5hèzw.Âݼ,‡äd:¤>²1976ËÌE/µ´´£6hùCSi6*îP±cö–€_Š�‘ßýâûòÎÛ¯Êmw< 7ß~�Lœ4®hm$IPrÕâ}‚y`dÌø rëí÷Âê#r¨pŸ¬]½\Ö­Y!Ç�Ÿ—ÞwªñBˆDÔÀRà `ðG€Ö`ñ�6Öû*l_Ì> |`¯ÙÁÎ4 ˜E‹©€Û�§“›§�pâLu'NœP„Sss³r)<áäp8£p_®¸ê†èµ7Ýf_xá2OffzšÑQÀ >>/Ì·E äeû�ALtÿ‘äŸ#Z<ÍÉ–2wî\u½999Šd³Z<™–4 RQQŽr%7cœ²zb(lƒ:BNJºÕøÝ sÌ4�驎Ëã±iö’šÖ-â Ôò±Y‹áÞçîŠ#¶ý%Ô1�«áñþv½þ:œ××¥Â@æQ;Õ@ž“?2�©SüG 7C¸ÅûJËŽA¼MëNÊê%1û]ºŒbÄ]ˆ•ß2ŽÒûCõuí œÊëÏ�GêAÚ2¸¸I<™w¬?άóLf X¿´üÓåÖvËúÚ…r¸u²Ü6qµœ§Üð:Å“ùšFLÙð žžm“¯]è–æ€[Bçµ×cF¿å'ò±¬AÒOi±M“ó~ÌOlCvùâcÏé…�iÛDã�i@0˜ pP, ÅsFÃ+1yK’aCRxAZ†¯X+ò!þ ÀŽÆ¯�u@WáKC+õ s4­Í‡�eo^¥®9b^z†–nô¢wi h $�8rÅFÄ�€UÀãÀ]@.‰Ÿ¯³Ê푟�8&o¯xYn¿û!¹á¦ÛdÌØq˜] -ËÌ 8fÐD}²a;E_?#q”–]. _$÷?ü¤îß)[7¯•Mëß‘ÃÀÒF‘0lа'[ðšoh BB‘qlTõEßïcÀSÀ,€�-‰¦9sæ("†ÖNêŽNZÿ�p:räˆ"�hádÆp²6*1u:]щ“§ÈÂÅ—Ù.¿âZÛ¢%—Ø&Lœls9]h�È™–Zݸ]ž¦±gƒ‘×Íú1Ñ2~2†‰iiiöùóçË‚˜Õ)3SO]OÈ뢻ŠÖ]Žf¹› î”l\ï¨Ùűv`XtkÍucŸ±·ë1ø ÿ½þ2©kÞ"í¾rcòø–;kfü-‘Âv¦jk’L±+†ei‚@¶lT�1â‚´“)6Ì®ÅlM{Ì_Œ%C„áò÷¿ì�Ç-¹s¾ŒÊñ¨|4ÕYW‰ÞÚµ¥Lþôk|;ן”6¸@*²XY½œîn%º:¿dÔ€�3⪪Ä,ªcU}¥ñ~Wzó䕲käW³LôTš‰ô2I4À �o°1³ e¼ÏS2m2/Ç.{&gÊŠâ�l«òaÀ†ÍC%¬ÇÎh‘ô0ÀÑGÒ…¤SII‰"ahõt 'NNÿä©3—]y�\~Õõî9s:òÆäÛ<.'ŒxG �öîÕ $1ÁTõQ§Ó�¤°"FŠë\&B¦ “Ï�£A®Ù.¼ðBE¶‘të†k€ï¦i�hfRYÖ"Ë_*’WŸÛ/e'›�û‚[Å÷�µŒt ¤¨w6 w;CÌg"ö,E1;šw´l­]$£'¬�= žœ‘®µdº~³ž4ïœ*v2¬ÞÒ|»,ÈuÁ%Ï!;0'Ç®š C<äzo¿FY§Q8pGB‰m>ÌÒÌ«�„§1Á6×Oóá¶I: ÁwÉ4Ÿ¯x^l—ýПÖÊñ“õ׊&ŸúK³ƒ“/æ©GœïælÁ²ÅG™ ü `¹°J§—Æ8wò‰…Ñ¢5 5 50Ä4ÀÚ¾`Ç|ð€$ÔU€‹¤HKK“l{ÿ=9T´WÞ^ù2b-}V.¾ìâr8%È yŠü@ê$ÕByü4DÔøI“äî{Ey¯�׋²ü•gaµË,)?Û$ h){9°`}±ø° hº“tì¼øG€ñ \ìÐeeeɼyó cZ;q?ÝÌ8E '-œ¼p 4­€p¬)!¸á²GåfÍ9?´ø¢+ìK–]éš=w¾;/7<”ÇÀ ©;&ÇPWl_Ââ&êò¤Š€R»I<ñZº? ~d�VÎCª/÷Yyyy¶%K–gï#Ñv:â‰9ó7’oŸ-—c”¸y°rá7à ËZ—²°ÛØÂñ!Õýe�ĈD½Òؾ3Ùâ* Å;h+¿„¬šX†~¶3U[S¹ÝÙFz³w¯»[…çØŽ Ƨt5b7‡ÖO$V}� fY+”Z»~äÓKeñ% ^š>L?ßØá’½I<àfS|´^Þ{焼»òê$s½1Þ¹Ž7o¸\»¾Ž¾kÀuðë Ò˜omç7—3¿í‡Z§ÊÁ,ÌlZÛ÷é#ûUÝ}Žù�& 57×.ss¢rÇ4�”µº¥°!*{Br¼1$5Þ 4ûU>ÒÇ0%àÛ�î´IŽÇ!3SdRº] ²ìÒ€¡¾—�zÅ uKùJ¡ˆ/œ¤óׯJ|æ#½�x�^ŽcqêO÷Ó2³]_v*nþ|ؘÀ GýÕ³¡)¬¦7> f’Þ-ñÝíÚÈ2I°Þe¤Sk h h ¼hÂÑ%vÒ×·�K{AŸêdͪ×eï®mò¡›ï’»xLfÏ™¯:‰É e�‹jÄ É©® fÉcOü¹þ¦�Ê;+_’·àNx¨h·"�b°þð´†b̦«Zƒý8Sr°r?@âi<�Bb¨  @Ù?~¼²,`<'’LG�•Ý»w“p±u±pŠ #Ø–™™];ï‚ÅþÅK¯ð,\´4}ÆÌ¹©ycƦ§¥:Xm3,œ¢ œp&kÓŒ›gÕuÄa±$ì l:Còžþ4 YŸÒÒ+Í$žÎ;ï¼³Oìôúý~eõEŽ #6U°mCpµj—PÄ�ç EÆÍSåÇ_ô˜bOEþi’‚‰Aì¶ ,ÝHÂTŠ‘’ùqµÝ‹ íí‡�·ªâiÙ÷g P�–ý)lgmMWeãi-eìϳ¥¼Ñ‡�ŠpSx�[Óñ𣻭§�fû¦R9v¸^>pãL¹ó¾ù2cÎhA\û¡tµIQVo;,ÕË®­e².v…{«¥¾º ï ?”|F�·J?¯Iq»’¯à”½"žÓ&•…4ßÛ¶°G|a $`Ÿþâ%ßí;]‰Œû‡{¦Vl’†Þë,Ĉš;§OuIKÈ%U˜»¤¼=*¥m©m�Hc "­XÎO‡y¼u= ¤¡žëJ‘œT›ä{ì26 Á�ÜvÉÃvÎáÆïïWGåù#íRÛÚ‰xªCY9ÀµèokåÓ©%aû�A²Ó ‚Øè`l�é=8?I©+�W�~Pø0·q…/ *ò¥é˜¬Ž¿ôNx<Ý÷,2ä_˵èU­­�‘¡’,åÀ/�’ Ÿˆù’ªÊRùãÓ?VAÉ?vßcòÑ{ÁÌT$„#I®$›¨¯2Fì6—L›1K>ýù¯É½~FvlÛk¨—dËÆÕR^^¢\âbeçÀÅ8à“À�.^Þ8pñ@â)�ÔÔTåbGëÄ=R: {gªÛ¾}»ZvÕ ‰˜‚iç…>ûÅi»æú[ݰ˜£!1¨9B¨Ph†n´ê:Õ+LÁRrò˜üôþ]ÞyëU¸â=)×Þ„xP£²áº�FŃby)ü(Gñ�æ·:±?xý‡äêÞ ÕÕÕ²Ïvyó�ä½µ+¥¦ºR¥ÇÖ£�×_Š�«Æ?�ììlY¶l™ ²Í`áÌ‹¤­�ÊËË­„““q¡‹c�š=*ǵhñÒqy¹Y KHì%ޱ£�èñ¤Š'5ÍÌ”åU÷˾Èù8ˆÄÓ]°òrÍš5KO£G�ƽ¦›c¼îë6oówZÒŒg¾«1"=è“­ÞXÌJühHÜ{8{ÃÀ8&éÿjò)éoÑ)ÌÆž€'�nI'Ϊ3}út™+ûvoU3Òñ:!$hùCÀåÇ©êZ;±ÞÙ·oŸ>|X¹”1€x!á´x à�ßE/qZkk³Ta dڌىÕ+54¤¥g:@p…ËK‹±C•Ÿƒ8}‘Å8蟀[].—sîܹ²téRߪ«E×é27-+rssà Ǝíî# �út8R§à*UÑÚÚZxñ¦­dŽË‘�tz¼ólv|X\¼� Ä�PñFN “Õ—%l[°ðäBCÛ hò‰º8»À�G…¥Ø&<ÀFÿ‡Æo¿Ê&îvQôhV-?$÷×Èý�-–›ïœ#Ù˜o$ ­ Šp›o”Ùí/;Ù$ï¬8*+_.’#…Õ*¬D H'íª8’ž�þ»V|¶•� aùÄÜÝùmUÉôŸaª�ø':vßù\Ъ‰$¿O4hjA;�nz¥pÙ;Þ–=uA9P ¥ºàVÍìÅÆç€ @ÏeM1D×5ù4tn;6 "þ%`awÅæˆóŒ3¤   >­3Â}fã•îhèÊ®]»¬q=8Ñ·6 »c¼ íþ[F%3 o�õmêîÄÝíÃa>ø¿;L™Ë)=�îÕû´´´†€h=²ø4@7&ZżÞvX ½);·o”˯¾Qî{èÓ²ì’+Õ·8hÚgã€d5¢‡QT B2sÖ9oö¹í®‡díêå‘ßýò{Áý{w’PÀWÞ�ŒŒ ™?¾šÑîøñã²jÕ*PÜü=¶d˪ áô`'@:n VA¸ž555tdŒ!¬|l茂Ìq¦§gš-<öKûÒ;¿Çý3p=¢O¬[X½§ÄŽUÂ^r~~¾ýÚk¯µ ©#‘„âÒçó)"¯±±Ñ†ú¼S�Ìî5ÉÛVɸ0uµ¸`;\>š¤=P˶Vüd߈ñ¥÷qbóúc¥è×É'¶-ŒÁ`”•åäƒÓé"úµC=s+ét†k�¦].‡”—4Éþs­lÛ\"�>¹TæÎ#ŽX,(>o&éy†œ†ÔO†+®Í ôI8¡—gxÖŸ§#Eµ²â¥ƒ žËÉã ŠûOA€_Üë´h $JÊí˜ÂïëRGJP\€ñÅ‹W™f2½d ðŽð{Á%�%úZ9ª;‹?t©ã7–÷Þ�Ç¡ÞE ò¨Cå“`�JÚ` â©¶=²I=%§ÓÀ+ø�›Ç&V¢É§¡q;¯B1¿\Ó]q9Ê ÜäJZ[[à¾ö¼lZÿ‚{ß&÷~ü3²àÂ¥˜uæøßG3yR-Ù€¢ëªºñDƒÁ`¨®sÖ,ñ²2höÁƒÕÀ‰‹°¨¶+€U@!`ŠjóaCä‡ÕX]mU¿µ´Ø3u¹Üf»We¸ š…9Ë’@¾,õxïÀ êð�ZyäÉ‹ä†�œ'™ÙnõLñ�æ<l÷_9ú+g³ü(:=†ÑÒTV&6 BŒ âdE{käõ Õ¬uUÍø–dè¾°¿Š¦óÕˆ=�Æ“H Ô ‡W2-j?W-I¤~ ø 9PoÄ^š•m— •°¿l•Î[ƽU_‘Ø”¤�Ú›1”V k¦“-a9Ü’#˜¯¤5$ ^ÌbÚ%Okþ]Öi¦ü£Zºü6l6ÍFذ¹ av!ìÀ0¦GÖIuZ1qF7eCØ´rê”ȲÁŠ˜„©¶/¿ürÙ²e‹5ÖD:’Jøžt}áÌßz²äñlà¨8–SêU­­­�~×ÙþCƒnÿ ©4‰Š @I3,z^|î²îÝ•rÛ�Ê=<÷²ó”…Qo-fÌ<bIâ©©±Nþòû_Ø~ó‹ïºÚZ[ 0ËÉIŠ44�ƒë$üúŸ¾ü°6–!LCë'U7A>Õ×Õ¢.‹ýšÀ‹ iì.7ç“QbZ>ñ§Î5U,�e‘†õϼ¯ ¢¾`Á¹ð Õ`N"îŸÙॵõÉ8Y{÷îU±IBY¤ë¯¼ŽÛàZ—ŽúpœǸ5$®Áziö„Ë'ɉ–�ª:�êz …Û™1j›°ÈÒÒÏÀM+¨²âFùî7ÖÈ�Ý•òà'/’)3FñPa´Í6Œ·ÃF"*YÅx/þ¯hì-5ÈY�gginòËÞ°t*’M능®¦ Öƒ° dquÕ�Óë-­�DiÀœDÕŒöDâ Ã621µT›zúÎVÉ$ª,:ŸjõäsGBòçÂ�£ŽÌËsÉU]2#Ë.n|7̆�þÎf­E² ŽAÒÏ :MÕ0oª‚%SekXjðCc{yõºÃNo¿ö½ÎÇ ÑäSòÞª[P´oçw-"-�fÏžÝcÒ©ëñl(3ùe—]&7n´P]’žÃ§o­zÿ:gÑÙ«ËÙô¦Ö€Ö€ÖÀ×-x6»€«�'�k7 Èï~úWÿC6¹ÿá'åÖ;îEPòcr²öI$$žZ›ä¹gž–_ýì¿a-Û~¦Ò™…7»²\ÿ°>{x¨¬Âv�jÛ±n ѺGåÄÃÍ,­Éû¸ŽìHìxÜ˜ÓØö]s.Ï40’�ß?ü�Këâ… *Њ¸/Ä;Ï&Ù„<•p¥ªªJ‘NŒ—ÕÞ~оIpþx x°E"A¸¸×Àµ®YRYÐuÆÉ>0ÛˆUÕ†-Ã/0àÂûJýªû«˜Žx3~ÀË2âNÈXP!ôª^øË^Ù·«Jx|±\sÓLÉÈI 6F â� Ã]-% (ãsÈ÷‚3sbi¼"ñûØPç•âc r¨°Vîå$ UR|´^¼íAE8ÑÝP“Nqué•~Ò€úâbr€჊xbö�ÌÉ:·;V/LÕåî8@¯ °ø9i†wΪbŸx†wgOµO�““ÐÏë]c:åž§>NÜêµp$‰#B%@À¸Nl/î8°Ô§LqÜ�M>%ßíš�"}øÐéþp´uΜ9ÊÅÎlôvu¯ëéå°ÁÌ™ð.¾øbÙ°aÃ)�ÜÞ® ^L£AÜûwA�Sá°.})ë×¹§EÕé´´´†šÚPàåÀàÃÝñ.”H³1>¸_¾óÿ ëV¿!�~ê+rñ¥Wa"°äqÅ#ñäó¶É›+^‘_ÿìÿ�–xâ rç_°X–]ú�(\æl«ß~Mêkk`õª>÷lÂÑ‚÷&à€ÖC¿þ4¦QzáF8‚1 V9lñõ¾êa§ºž;]Šd’"œeϰwÐ�ä`çCÀ¿¹ŒëDk'Æ·âl²‰ ž +› ž“8p@ ÷ÊTM¼H¥X#y÷;€£¢´RŽ[ …#íÐ[‡W;gV ‚x †”Õ>»Ç�r` …÷–zV÷—DÝŸ´ œhhæÄ´x‡ˆü¿¾þެ[uTî 5á8q¹q[pKÂ[M¾X¬¤�+ÛÙÎãc‘ V$`ÊZšýRZÜ„YêªeçÖR)Ü]#åˆkÖÇU„“ "Ž™ë´h œ8®nVZU>WF{dJZ)f®ÃÛñ0\±ô™N¯Ü.÷ Y)Æw…M¦°íÂfH„æà¬{÷ 7p(XŸ“h:]»? oéDn ïKMú«»%|`GeŒµ´lœ(3ÿQ£F©o_I'k¾l8�?^.½ôRyï½÷:M�‹<Ç—¯âIõF¬eÐëZZZÃXdžÞh=Còå@‰äλ«Þ�=»¶ÉípÅ»ïá'¤`úLÄ‚¢åèà}.Qå ÖSXvmß"¿þßïÀíŽa›:Ä ¢±cPw\y½Üøá;ä"RÏÉe÷ùƒòøg¿*Û·¬—·–¿(Û·®—æ&XßB²d1ð}àVà�µ@¼¦¡5;‘]ê$IŒðºL #äˆ-Eàœ®”‡ßþÈ>Wâ‰çU×»8“tjmmUÁÄ9;`]]]×ûNˆVNOUAŸ°¤ÎÈ6áIÁ�OÁp º?ÜmCCº]¹Ûq?¶qó¢lô²!<ÐB N>*§Úµ ´hÆÿÛ¯’Ý[+ä£\ wÜ?_ÆŽÏä(?âñã)ÁËû¡Šh¾‹|wºŠÙ_ëæ§®I{µÝÞ�Úêv©¬h•r¸ž8©ƒ•S£Tc_[›æZ`­AÖãSÄxtêeîÕItb­�„iÀxPsÅŸCºÜMK/•l'â=Ám«ã—„�Tgtà·Ë�•Ïœï–\—]6TøàFÇêÔüª�1s&²~öH"qÀ±8 Ð’é}€u6‰¦Ž‘!lhébY£2h˜�3¿ p„¸“p;Æ–`\'ŽÚ&‚t²ž€ºà]pÁ²cÇÕøàï´À¶¾YÖcôºÖ€Ö€Ö€Ö@¯4ÀQ®_o�ŸÆJdû¿ý¡¼·î-ùø#OÊÍ·Ý W¼QˆÛƒ6ŽÙû3À’͆ºJY�@éÇ�ŒŸ‘¤Ó¤IrëG�[î¸_ ³Ê� ¾ô”ó#Þ�Á¤§MŸëÜYróí÷Èþ];eõªWdÝš·äpÑ^“X¡ÕY>ìx‚ ¿‡Å�€å\¢Â㮄‹¥sÍ*Ž'éîD¬‹Iþ�Á˜ŠK—bæ0ÌlÇ™c{K šÄòRbÎ`wôèQåbGW».u{¾ÐÒ‰:òV¡{'Ÿ)š6å„Âíp³kÆ£„g›äe &ü¨ƒ5”â¦H`•jË�Ý”h�Ÿæ|´‚b,¨ºÚvùõ7«¸H÷>²H®º~ºdd’îæVu³Ëš=Œ¢!tØJÞ$¨Ì¥5]wëADémn HUe‹Tœl–’�rôp�=T+•¥ ™ZüBB›Ÿ@e3‡`á´lr8q6RšZ´’A —(|UH3qÍeÊ̬“â´�Xãª$©…nÇÑùò"—Ü=Ë);k"òú ¯®œ)@8ëÑ €Óvàp `8 ôh¢ :8«œnÄï¬ê ÕÀdäÖ‰xbl Æuš7ož0Ʀ½mðö¦„t磩ÿ‘#G:;K££#á©küü²ï`i„pzZ´´´F¤hÊÄFÊ¿+T= …»d�|û›_’wßzUyâËrÉ¥tÅK”Yñ|~ŸTW‘·€y:\ëfÍ>_®¹áV¹éæ»dÖœ¹*”P¶êFߌ ;‰œ�­3—„Í¥—Ë2Ä|èñ/Ê›¯ÿ]^øÛÓr°h�Y—¥"Ùå1¨ÂÐAkk3òŠÃEo8V‰t” b«#KØMœÒãž„}¼7´DvÓÝ}Ñ¢Erþù竘Q½©‡MÒÉŒïd/))Q3rtêœÐLŒÏƯ€ÍÀéFL©t6vk€)á°_Åxu3#¬ Z%K(e"¶2¤!CØŠ ¹giM$öžÆE õs’À��ìÙV!Ꮇøâ‰rÓ­³eÉe“dÜ„Lʼe†Xnœ¹+¾äo*`¹õöÆí¼B¢©©ns'›äØÁ:9t DSƒT”6I#b7µ·Ô·ƒ¯¼²hBãQ¹ ‚,;S:ŸEoi ¼ ©ã¼Ñ¨]òRëerj9ž]mõÔ¡™ä[#ÅvÆd�PÓ2Spu§•�ßÇ–#â7š§æÈ(‹gdd BfS¾…磕•)>Dð¯n Ëy¤Åú º±Ð¥éC´´F‚hÅò°¸øq†³QËßú[lh(d¥¦¨·£×çŠ5P¼>6ôù~)áW˜q*´h h h h àw‘Â�åÀ—€+%ʱ’þûß¿,+_{Vxäsò�ë>,ép `pÀÊî›Ç$jIJ¹Ð%¨ýÌš€$”Íæ�Å]"ßúþoå]ÌŒ÷Æ«“½{¶©òN—ŒÊÎ…¥…uO¼îP-15[ uÂ:4Åoö°¦¢o£Ç̾<¨x[œ –nï”®3jg7Ì:šKZt�t:|ø°ìß¿¿»`âÅÈâOÀï�£@o¥°Q‹cm‹ó)né”'þp=–ªºÅŸGcý½Í<Áéc­‚窳Kœp‡èŽ—³>Š`ô°ª¼E*KšEQÝ]_=¤W7•ø¼«…±Ó$©Tl¦Ä•Pç¤5�tˆÚÉ õ|EèfÇ÷¥%˜Š%Lú†§á ®kx ›àÏ!QÉD ŽHr~.¬ŸqOƒa©¨T€�:Ü•uA)lIYKõ®:ˆò“ÈvñQ€ÂGÄ$žŒÇŰ¼Ž7JT*ã-«Fê3kÙ?,V»»àaqaCô"Ö¡Ü7?5¯�³àp´vñâŪAÛÓ†°y|O—l0›âÆÌ(i˜Þ–¯G_ǵû‰R½k*6~ÕPl_²ÓÇh h h c Ðú•–/ŒÀo?G½¦Jü>¯¼¿i­ìÛ»C®üÀ�òÀÃOÊE_+BøØž#)cžg –,jY¨þÑ{Bpõ{äø±Ã²×רX'‚kž$T˜¦³1Á!¨LM1˜Ì}}YÒzÃåŠgÁ �VO$ûØ8¼™u ÝÝ9,c.²®ím}KÒ‰3Ø1~"I§ÚÚZ«µN£â4½‚%­�vçBïáøƒ¨fÂíÎÆ ãn§aùåt`éDÿ>ên0·NõŸTÂÀÑZ†€p›ø¾trJÅÖEÔ( D`�Â>¿hüÀñ�xöˆi�,-�tÉsÃTYË�ÖÛ,œûÅã~g»šÀm“y6¹½À#ð̃ETDv׆e7ȨM!©Çìy–>0磂#Ï*¬³_ÞÎ¥}pÖ VM> –æO^} Yói3Yaa¡rÅãŒ;îMÐS3�³-ÍØR|;Òaõ”�Ñ»�òG&­íq˜?‘æ0€­­­­�î5PŽÝßÞþp�(ikm‘•¯?/ï¯_�Á÷È}~ZæžO·l['²ÆLŸ¬K¶ãhRNOjÜÛ8ØÁ‰î¬Ä¯¤P1b¨VX©ô¹±#‚q˧ó�ßãH<�3FOÓ§OïñÄc ¿ß/ÅÅŲ{÷n)//ïJ:ÑÍò-à7À& ƒ1¥Èç´Ù‚ ãY¾@%®�Çã^vlG°!ÛÁäac…õ>Û™lV¨†¸aÀ--ZZZCXøª©.ÁXò/c™E¤Æ—'¥Þñ’ãjÂ6I*3å¾^]t¥ÅCá�•�¢uÔâÑ6Y’ï„å±Sªáù³¿>"ÛªCr´)(uÞˆx¶€ëê)QqUNV­r0éÏÛ˜êÔ‰Æö°M>%ç­ä(å>™Ÿ1‹È‘T6n/¹äIM…I'q$@Ì‘]¯—®¨x1ðfdg¤H¨¾Z>‘)nóvzox-‰)°*¥þ£5 5 50,5À¡RNBÁÁ‡ç�ÏWñúº¡±^žýó/eýš•r×½�Ë�÷=,ã'L�xP(GB…uÅÙÜûã „“#†˜ÕÝfƒ?8«“Þ g›KMÅ´6BÓö4îŸ4i’\†™ù&L˜Ð•4êHÝÍ�åŒu$�öîÝ+eee]g°#ôðà] Î aý\…sû€À‚¶@)· æǰ”Ð5�çë›ÂŒ<Îå/‰B4Ë�x�Ñ(§°,#¬s¹ }¬Ö€Ö€ÖÀé5`ýÀ’\ð…ÝrÖOs²Žˆä“–á­�ë(��¸Ôñ°©žŒ˜Q×OrK{È-Mþ(\1Á&!aµÏ&¿;Ð.Å >kÅÌ©Ç�BÀú8asøI¼1;ü.mÈ_; Bˆ+GÀ•pjfŸÏ'W\q…deeõª‘læÑuÉ[Z=µ´mb’OyÙ)âva¥��|ÆÃmhíÄ5Ñt�×¢Ek@k@k@kàì ±ð2°¸ à@Ä…€>”œ<.?ûá¿#p÷kòÐcOɵ7Þ*é鈅$ý”!ÿðÔC²~Ý»hø Õû¹|ÄãgüUùÁ·µR ,uãuaoKfG0åôôL¨Åè 83«§Ä“y ÏɸNííí²cÇyã�7”ÅS≤I§»ºQöñ„¬•ÕÓ,«8 b( 뢛JH<±,ƒ%4sbäs5ôŽz%ò©¯ƒZƒuú¼ƒ¡RΘ†ŽZ´’WFudÄ~â_n“Œ K­?Wj9j˨q’÷*tÉúOl±ð©`èì—…AYu¢U¹ßÅθËÇ€C<ñº5ùD-$·�ÁùW€$­¡”Ô××Ëš5kT0Ó¾PlL›íx®»Ýn3{4`�ª<�ïíá ¥iaKùÄù¬uœ ‡YédZZZZªíR=|¸ø>PÄ¥­­EÞZþ¢<õÄ]òͯ?)û÷í’ÌZšBjXë+¸ßň£¾\I#3·!ö%##C.¸àÉÏÏ?£Å“YWš]ìÞ~ûmÙ°aƒ44�Œ É– ­Ô¾ìñ‚e ÛlÀî7š¸l2°þŽ’ô9tzN°=�²qÐIµ]¯ŠGeÄŽ×ݱ�¼Cë\|6Ââ •#NJžf¾VZ´’O$H)Ê:7Þaâà}TÚB©ù‰²¾‰õ©Tjýg$iÍ0t€mòÌÑ�¼|¸0ñ«?„µÇ.GÔ¢‡âÏ@Ò¯lF Ë€ÆPPñŸÔ”KÙÙÙq"‰¿õD̆´¹¤EUee¥:4Íí�«§K*¢ù÷vœ™ÍNþÖæV)¯QmNîÊŒá uýGk@k@k@k ·`³¥X ¬²€i€ª²4„@IDAT°ÎŒW¸—¬[½BZ[šerÁ4Ìà6 `|†{û1g†É$ñÄú„b.�­üåxt]M•lXÿ¶Ò\&Ož¬ÜíÌ�k6fÝÈ}$®š››e×®]²yófUWZâ.²áÈä�o4£W•–! *>X ˜ÏB9Ö_6ƒÕ°e¯kp)�NW�s¬d¸  OviÑ誾Öa©n]+'ë_�š– èÈÛ$Õ9ÏŒùhw=Fo ôú³�Ô—fSãꨖ-—eQô7N‘ié%25£©Xu[%õUéÂ%Bl®¸Á²´mò‡¢ üµ¨®xñª¸çx Õr•ˆ�<4ù4n’¥ˆ»°~¸PVDÁ`PJKKùÄ)¢»k@[Žï´j6¬Í%§„®¨¨Piš1EdN–KŸç±²´�Ž?Ý_¸ ȧ•›[¤ SNÆ„ÏÚ\€/ÜŽØ>½ÐÐÐÐè½hMS¼ ÀâEƓպe=ÐÒÜ$;¶m”÷7­�µ�G fHZš1w�jh‹ºF\‚¹ìÑÕ0±Ýaß±å=©®ª�Ç£È'Z>u­;Y/šû¸~ôèQY¿~½|X6nÜŸ”#–ž„Ï»­�Ö~`0…eøð À‹ú3ð>0˜ÂÆã=*+0ê4„¸O‘H@�7P‹Ö@W ÃÍŒ´ã7ž�{*,GÐ>åS­š®êÛ$eý;¥¶y³¸\£e\æµè¤g‰²Ÿ½�4ð4N>³Æíl´ eÈh`9Jz;ð'`KÍò¦M›¸ÚcŠ A«`ö¼\ ìt%à •’b¾^ÖT=[7\<ºM›‹½?8Jφò@º&àtZ´´´†�èŠ÷sà5àaà@ ¤½­UÞ^ù’²„ºõÎäþŸ�i3ÎSVP‘!h …ª«×•k;t ã>QXZ\çâû¸BªººZvîÜ©È'Ö±1aV´6£µÓß�* „u)ÛM¥~’ÅÆ�¤\œ˜‹D=ßÄOZ´:4@’B͈‰¿op¹›K¹4$âcݹÝÚq¤^KV ÐâÉ®”²†åÒîÇçt�s´ä¦]*6¸3ÛI}Ðé~ÎbæÁ')¶®È�øVÏÐõ93ó=õð(­žð³•d õešá ‰Û‹®9Zsbî§þÛcY¨Uüáò”uk†z=¡0î�MJÛ¢â Fa� “%Ü.+Û"RÜ’c�!9²©ÁƽQw§kŽbÇW�W�K¢4šc¬µq¥äÂÚÀ ŒG J†Á%Û¤ÅXüÁ&\ =-ì*†žØéªÆm|²à¢fôzÒé0ÒtÖ‘Ÿ±‡„,Mðì�à‡áêDKKβ „C´ºô! ë:žK @D�±mìãºñüÊ�Yê$˜ó"Þ1âl¡Î x,IRGJžW‡Ú·»j—T5¶#UG�Èø@ã¬XÁaâ1å‚ñݵT§ËôŸ/…ûq§Ã&¤AM©N›¤#¡ûÜøÝ…}LËÒ¨«¡:±n:Ÿð<ÜÖrÀ�zæHH^<Ô*-Üi(T=1T,|vY‰$_Š€î[|¬6‡¯hòihßÛ}(þGÆu˜ÇK1 (ºÞM›6­[<õ‘ìæeq:�vJ(ÂqQÙ}Ø+�-IóØâ1ž£/€èéééÂé1aKâq€ßÕ/š€‚´h h h œ£h2°àlk/Æ–×b©êûp8$‡í—ïüçWäÍ7ž—ýœ\}í‡$=- E Õ0&¡TW�z‡Óhú�x²º©s𥩠±²vì�}ûö) ¡P§ËZín´é”ÐCiF:ö:•�x EQÝwÓ1ÓèåÈÖ@4Òáªb³¥ Îæ"z׺ =$ 9Þ`9^y£oíqçIškJüž*± ìœ9.Þ�ç×ZQ;F:l’ôQiA0‘\Š„}°]êbEëôíÀn  µò8àF`ð ð €.ýÃZ4ù4ôo/YÔ;�Ngã!5{ölu…]Gw»^6OMM•ÌÌLñz9R€�fq»¼¾±E¸!#½ûÔX¿q$»8«ÐÅ_¬F’OžÐz) ë¥`Ä�ÏDrLÝÝ s0ãlƒþÝ{îû —0 øAPñÃ{z‰½gX¤ HÒŠ  p)2Ê ¤H8±Mb FV’f* „L*@÷?ºf€ÐJG�.>€t$ñ•FË+¬c�ã ë+žC ¾ý¬XðÕ6Ý�“ç/Ë—Ž¸]O-ðÈŠ’åv—ŠëMSGë²qét‡yŠëb7¹ VRÕ@ykXŽ4…¤¤%$­ŒF®®²Óu™š0w‚Òšy{ÑäÓð¹Å$ î~ \ÄË"ÙtàÀ5²»dÉ5­4?†Ý}¹�.$Ÿ뢵µU½&Uuùûê&yêc¹‹`¶=¦ìššåáÔÖ´€âùºX@‘€¢kÃíÒ%hÑÐÐH�ØÆ; |x Ñ �(inn”Wžÿ£¬Yõº\꾇>½àÂ¥¶t8ÚªZˆfâ!¼t¹SeÌX0FÜ'¿ß/………Q†ÔÔÔØb.xÔU)ð4Àú´ÐÒw �Í£‹-›3Y÷B @\òÉ ûžµ>Rk@k Ù5`¸Ê±”F¯ „XLi•fï.©kÚ)m�¸È%dÜ™=üV€ÖªDy ä`8C"œß!¦caØÙç8heÈÃ>1;ÿ\ZûÇLËz�à±\ƒËzúQ0vebPc4¾unüF·ãƒg93É.yn‚yùö{n³<,ëç, #¶äz.@ šï2ž£¹d,Ý^Jì°ã»Ì £œ[Ì ±H`y@ÎxÀ:¥‚´¢û_¬®F�‰Ê…àh¸ŽM³©õ<¬g*" J§F ¬'HF©â•2˜Â²L‡öŸšïRe¢±´q3Ù§6JÆ…Ú‡¹ŒDÒrKì5 ?^��J^ã Áú7ŠçÞÔxüÊÞÅÚà”â)†ÉŠõå&—4¢/c/®žî?>LMð>vì˜" .½ôRwÉã‚iÈÒ«äÝî¦OŸ.{öìáOÄ òêš™7Í#7,K­�U�Äa�Š›ð Ì›ç$ùÄuºà-[¶,ŠíhiiiìS£>ø�!9]Eþ:Ã(¬­­­�! ¶+7¬+n>\°±«¤©±^^xî÷²öÝÑ›o»?|Ï�ÛfÍž—B‰ph°›€f)û¸DÝÄA—Ë£ê=ÖKÍÍÍ6À̰+/?vš;õòœ4ÀÎ^)@Ýf2§PÌ•&Öµà.-Z]4`tíºìÔ›CV±¾b Ö4m—¦ö"ÄgjE¿€cÎìð~÷ a\?ë1Iü®œŽ‡cË“X’l"Ù3àýösèÊ=BrŠäV6�Œ&Ç0ËIÙ}’U$­˜6^Ïc½ŸÄ �° `&Ýæ32Y°Šé”sª\¸ŽÏpÈD˜LMÌ´ËX�†«`bÓŠŠWè@*JYHáQèÖÇàHÒõ\0Ë!Ê=ÚŸ�m—�LucÐÅ-åèåþ|¿O¶–Á²¯#;¥ÿ °žö¢É§áu‹ùŸ¾| P„}oذA.»ì²hFF†9ÂËŸO’O'Nœ`£\ýÖÚ–Ÿ<[-YéãåâyR˜+¢ã…9åxþdÓíQ_ ãgº6$ž(iii6¸àÙÖ¯_/•••F"cÄásØà—ûÀ°gÍ ×K­­­�ÔæÏ«X<\Ä¥¶¦ÊþÇßþÈööŠçƒw|ìáÀ]÷~Â1¹`š3‚¯r�Ê!-ìçpè²CØDÞ |X °G¤%1`=~8La–Œáâ‡õSAƒÑýÀž34(x€–‘¥�¸_ÎȺì‘qµ àFçƒÕi‡tÛÔgÖSŒÇNI¥cI¦£@ P$Äd ù 5aEÐÒ« ØX…t ­¡HN‘€¢•T@«)’U´˜¢E˜ŽVV\òƒÌ`|·]±uòó%ñ•�k üèSÖ��9Ü@OwC쨟3`À�ãI‘É™)25Ó!3@àLÍH‘Ѱ˜ÂB¹ññS¡ X…ÉÖ2!W¥H+�F¾0fÍ;ä“íå�ˆ'v¶¿l’íP¤Ä‹&Ÿ¯Ódȑ맀 àŸ_N’<1JY8qÔ×ôMF%L—••% ,�M›6)‹%¾Ó•µù¿¿(“{oÈ“�}0 3#a:jÆ9�¨q KÛžçâ,zuæ:ÏÃÙï`%ëÖ­“ÆFb(á‡ï+k£o#âEÄujÑÐÐh °ñþ+à5€$Ô'€€’h4b+/+qýâ'ߎ¬xíùà}:pë÷9F�c¡ÙËQÞ!'hÔ:RˆÏÀZJIþ> üÀŽ–Äkà0²Ü\¸|Ø(‡û]Ü2ƪö@âO©sÔÐH Ð a«QK§ £`&ñ¿»JZ€TìÇÔ¬£H° ÁÊ¥$¡F�¥ÊB ¨––óx~ྠ°ì?0wê¥Ö€Ö€Ö€Ö@Â5Àï2ü?^fJð­¶;Zäþî~-ºü•g#÷=ôÙèu7ÝbË•-A V‚¤2“&ýRu„P9Åê<¼ø ‰§þ»{Œ¿ÂÎe%0…mN½î –Âí‚ñZ´´†«@÷#Æ\�ñ¯£Ï­®v7þ’ô©LJIò‡„A9ßAöóH\‘¤ÊrZ[M¦Sc‡%]Ibõ€�ˆb–¿°BI3‚#‘¢„8ì;„Ô8`J&ÎÊ1•eǶ[*ÄÉêZ!a1`L&ƺT÷�µOír´Áó�bóoðà†óFŽàvhÆàGd;À†ß5€2•äÌ>õõõ2vìXIMMU£ŽfÜ'¤Q�rZ(åççÓw9Š´qˆ/mYu@ÖíhÅT§v™1É%ðËåþø …ÔU~oW›/3Lk™‚™G²³³ílxšçá:Ü Eˬ`0þþñC´ ûEs}-ZZZZý«4éä}€®gl|NØxTÊVYQj_¿öMÛÞÝÛ$3+W&MžŠø~˜µ(^˜©“oɆ`(�C…ûeÝ»+`…«ÌwI:qÔ±>ùJ#¼§m¡ãÒê+A?Aqüüø ° ˆ7ü±®exh€7šmpÐá° X ¼ üøClÉúw À� ¦¥5…ÖYI)Z9µ"RÕ’CpÝÛZå—U%D@V—e{uX޵Dð "CôE9Ÿ%*Œ:Q¢ÿ zÃŒ�x°#6yåxH~´»EÊZ:=æt÷y ø#Ðél{ÑäÓ°¿ÅŠàåèBp-À—YÚÛÛ9»�"˜IY@Y­ŸH ‘0?~<—¶††å.Çc)>¼è; Ûdk¡OR—ï�t°Ìœ®“ù(öËò -Rßd¼SÜ7qâD{NNŽ"»˜‡y>ž‹®~$¡***¬ç¡Ô"€£"ìiÑÐÐÐè_ Ј.l$®ØQ˜¤JBð¹+>~DÖ¾ó†?rPrrÇÈXÔn'I(6»’“‰2ȧ ,Ú‡€êËY×° tI`c˜×¬¥ÿ4ÀÁ¯À<€·äÓxÉpOņj–`�–‘®E>aö³fß‘ù”¢É§!þPÐå.®Áìv‡Ñþ`Èÿ`Á�Ž×ñŽ]ÿH_°îe�'’S%À`5ðw€„ÌŸbëï`I#º`òYa¿°G.| zÞ·½’–�ì©U�5e!Ù[‘– 1û^&âJ™3ì!ß> ë3VjÌË Ëj’N»ë£ò³½>yñp¬µØ¬ŠËI¬=¼Ä_ˆø¯#`E“O#à&ãùÔóåå ~' à†§Üï`‘'…ð{\H<�7NF�­�“´2…_ŽÚÆ ¬ßÙ"Û ýÒÔ•ú–¨¼²®Eþ÷¹)¯1¬ž˜žÓZ3�¹õ<&ùdæÇß0E©08zÌ:Šï3Í5išùÐéíŶ­­­­�þÑG.9 ɯ߀&ôS�8Sà÷û¤¨p�¬zóe�PE’•=ZÆM˜ .�P–˜8$9„�à ˆ³C…ûdÝjZ>)ò©¥{ÐäSÿÞ&ŽôæPÊ’h±·RA@M—ƒaAØ¢Ð2Ò5 ¬d‚'¤Å{ D¶Olö•:±Á`ù„u-CO¼§¡h‹4´ïG½@¾n"EÀF ££€ -ZÐÛˆ�¤Œ&`¹ )EBê`@²Šu6+¶MHJ�UH�„Ò¦Š€¬­Êñf¸‚‚,Ê •Ž™÷œ˜,+Û��>,H%üt*bi9°ÁÄO4EeUYXž>à“¿ DÍñ¦@ךm3 ù `-Àë‘rVs¶©•áyÑdŒÿ �eýÀÖž ôÍxK^x¡Ìš5KY#™q ø{ŒRPŒÏTTT$¿e¦ v2kS0ê”Î�H’Lyyy2f̘xŒ)æmž‡éf̘¡\:dþÌÑÒ»€íÀÍ�z©5 5 5 50  é<JÛ€Ÿ‹-ã$TSc½¼ô÷?Êê·_“ko¸Mî}àS²ð¢‹ñMǘÉ&©ÕST5ãõš•Z@lƒÐ ›�‰‰Ô¾7P‰áR ÐtGË^‹Ö4`L¨n¾Ÿ �¬{ÎÆß³_àŸ*öâ:É–-[”+Þ\ „¸lï×1B,n·[-ZD÷9Ù¿¿”••Y]ä�¥ã8c/-¬žfÏž­Žg>$™ºž‡®~(ƒÔÕÕ)ÄÒy°üàðzlŸ^h h h h œ“ßßõÀÀ“À .M� òâs¿G<¥•rËí÷É=~JfÌš#ŒG' ÅI2"X‰›+š€ê¤Ž~Û8ˆœwWž@¨QÚü%’í™ +¨Qh>$Ë3Òoׯ3î‘:¿œÝµ+{”�N”$ˆ¢� ò) A€êÐKP÷w: —Ô&I!u1†¦Èfî��nlZA‘x"ERŠÖ¶tù¦7M'aßó$,”ˆÓK÷ýÖ|›ø°o¾°ýD�/Ú†uä=lÝѬˆ/Ã…Àx@Y81Üê"Dns:AýÆÄJñ%el¦)S¦(W<’ItųZK™Çq™››+ .”‚‚‚¸÷3OæÕ��äâL|]È-Æaƒ•PÅݧ÷i h h h ô»h E –×€€nÑD\ÚÛ[eïî­²aíÛ°’ ÈÔ‚i’5г«²Zéþ»?¸WPíÀí. Eû÷€ [nÖ[å8%c>Õôã©uÖ†¼X°SÀÎÀhvBSP:–OnwÞ³�“kI nwÇ¥ÅwO~5 ™·»4ZÇÙôxyÜ¢>ÁŽ{×ê?Œ`òÕxËÉLŸ�ñoÒ'…êƒÎ¤�0~lÏ‘îyotÙ{!¶Íg/ˆÇ±Äz¢…çæóý à›À^@�®@ M>ziÙÂ㋱˜� Vd‹ÛmŒñäñxº%ˆLÒˆnx˜ÁN¹ä‘,"iÄc¸äosæÌQî|ŒeÃóœM˜–ù9ÿ)–ž½–,€‰³ @‹Ö€Ö€Ö€ÖÀàh€#Ž[€W€b€qŠßñ††ZÙºy­l{½¤ºÓe2H¨T�{ÐfÆ#ùäà�OkVÂÐFµ5ù„7€Â†ÿùÀ\ž“ƒË9JÒ�˜õN“ TɈ–SÈ'¸îf¥Îù4Q?CøÉ°aÒ²öP,‹Ñ 7 ¬SÞÅ’ƒájwjÑè' °²gŒ¨ÀßCdžv�Ùí9Q4™âàgë[ |øWà÷@@¯#- èa‹2FØ* (ŽZ"¶ü–ÊÝ®´´T¼^¯,[¶LÅi¢uSwbºÐåççÇã9ÑŠûéjGòÈÜîîø³í›9s¦´µµ)¿XZPÓ�_·'-ZZZZƒ£Ö#ø)ÀQÅû€O³%ÄܱuƒD`ò+^¿Q>þ蓲ô’+Õ,©¡A‹ÅbwÖ-ZF‡q ]Œ …ÛaårD²Ü³%ÝÝÙBz`Š£Ï’làìhf 0Æ{ŠF´÷”w6ÙŠ­Ës �Tô8Çà¾ÆmØéŸ¸ÿÕ?i $Zü˜˜®z?Äú €ž@sZDñÙT#SXRØ &�D’É[ç’pÕ@P[g-gÑ@ü+p–túçá«~ôßh¢x9À—N‘Oœu.==]rrr¸ë´ÂnÓ²‰ît$ž(æ¾Óx–ÿ‰ÄV °Æb'�VZd®õ‹%hÑÐÐd °¡%Ô[ë•™cz( â;~ôðYóÎRY^"'H>&¡`èÎs­+b§8ëB¹Ý�Þò‰�H-ý¯Ƽh8�ÄÆ¾-ñŠÓ‘ëmý}Œh!IˆÔH³÷°„ñ\P2 MÞ½а߮„Ö"oÆ�6öé¿Z©Ó"jNº GÐkû—&¸o%ð6Àþò:€(ÛZ;‘xjº·ÔÀZ:k@“O�õ1R·øÂ°Óp • H0Tq—H(Ñ �¤Ò@ux~ ωTÒÒÒ"MMMÆN#8ì4lx€UæN½ÔÐÐÐT pD‘¦ík�÷€ €$C¼×èó¶Ëþ½;d㺷a•3añ’ž: ®xš|Â�Há3Âvc?eG¢Aå~çqæ‰Ûɱ%-#UvXÆÂu )‚¤hWjHw�ù4ñÁÜ#U-Cþº9jL«§fß „ØOgU�]†Ûv7´h h Œ hòidÜçž\%Ù_2¸dsãå6WUU¥,¡Æ`”�Èœ€¢û- 8ÝðbÂg— Wº|ìŠíÓ ­­­­�Á×4JŽjsD‘õÉ$€� U‡44ÔÉÖ÷×Iá¾]2fÜ™8iª .ÜŸ&ùT„˜OïaF¾¨1»Z9Šô* -ŸxsFØÞh €ù€-†áœ-*©® ˜ùŽœ¥êœb©ediS˜G[¥ÉW(¡0øe9³á–y#û3>ðÈÒò`\­Ýæ”öÀI o·òj⋾(´ÕÈ`Ü}N­�AЀ&ŸAéI|J¶öÊšNhë(4H}}½²€JMMPŠ�—Ë¥Üÿ***”ËqËZméøOP‚­­­�$ÒÝ¢4_§iúT nÚ‚uíñc‡dýÚ·¤µ¥YfÌš-Ù9Yô G•xòÁ ŸüRˆÙîÞcÀqƒ|â†&Ÿ „Z;ð&3ðø8Æô †…³b¥�€²++—Ä?|�út½ÔÝî¢6?ÜîbfÊFu´3%]2Sg‹Ó®Œò{™£Nž,°Ã6(MÊ¥2¥÷­²ˆå ÷v@‡Ð F´h Œ hòiÜä>\"ýÛVt• ¹c”ë[MM�äææJFFÆ€PA (T>‰?Îb»H� CŒ4Š–OiÎqØ¥›¨Pˆh¤p³¯H|¡z\{Dlˆÿ™å™#.GL'ILkšÀØ�UÛXµ±JPÂA ÆÒñ›ú¯Ö€ÖÀp×€®Ù‡ûîûõùqè»@ À8Pi€r¿£^vv¶BºHð|Vá¹F�¥vUV²¿ „-‘ÿßÞyÀÉu–çþìl_­š­jI«]¹Ë7l\dÙ@H�$$�—n„KIn.$ä¦Ü$$$„PB'¦l¹É’U,YÕ²šÕ{YIÛûîÜçÿÍœÑìhwµ’¥ÕÎîóê÷hfgΜ9ßÿœ)ß3ïûžIÒÒ2ÉAp˜€ ˜À0#€ÙÀlr‘D¶*Ps$ÍHTs¡³¤Ø¿;z^IûöìŽfÍRCòiç®!y¦ì.“ù̧8óé0ÛáR|Ï€;;ú)ÑÕݪ^? *µš¨þOSt“c´(�KÜÔ¾3jë<¤9»ƒÝ4¶üR�-mª®‡·‹Ñ†d„Œ7%*¢öm×1�)”Þa:aþÓÊa&0 Ø|;ùU ‘O†õÒJ sçb)jש³1ÆŽJá†Ò€Š›Ÿ·µµ…2@¶G�Å—×yýŸ0Ì&`&`Ã�õ;¥Ç%ú-qV¼ðÙ¢K}¾´E›6®�–-~ZEYÑ’Wœ›†ä˜OL~l>±†>˜…2ñ¼TšÍÓwv7èLgMQYÑd�o"79FšŽ·ví“I±O�è;ô6ÐU–T©Ø Ÿñ.Ï�ƒ„ºet&ë¢Æ¶2CéÝEÒ‰Ï÷}ÊóýëÍ7�Á°ù4J£{~Þ-='Ý"Í�™ð.”•P 6gßkjRSÊ“gÀ‹3 Ðæ½$ñAæ00žøÅ{µ´PâÌ¥”âÑÇ/”t‡†äËE[6­�¦]R͘Q¥‰ç«Ë‚À|ú©žÖæð/LPzÃ�]d?1ÕÏêtC§ ‡ij@>V·ðUÄ1pV´ŽîÚ`Pt÷´ñ†•ëŒwcKjÒ½ÀF…‘9F2×zTaW×ú²ÊªC›'Ú{ÐÜk±¤�í0él>�ô=|nÆÇ·>ÊÙž•n–ª¤¨««+d@•––F_œùáš»Î{Ѐ|êÔ©}Pãõäó%ú‹`š9LÀLÀ†' LŸg¤ Ò¬´t‘êÏ´sû–hÉsOD-:ÓiÍe—«Üûì’ÇæÓ¦ ëÔäü‰`réi\vh_Ðÿ8öH”÷‡þOdTwv×ë geêÿ4#*Й²£ƒ™O�ISoU fê Ç¥E¢Ê²Ë£ÂDùè€0BGɯÄ…êéµ)êèjŒG‰»ÌI)È‚t˜€ Œp6ŸFø>ÇÃãì4 ¥^g £nÊ”)áò?gŸ«ã‹iqqq4}úôPÈ™øÒÁgÛ8é.i©ÄÄÂa&`&0| ÄgÅû™6‘Ï™+%ÞÇCp&¼5/.�V¯\ª¼qQUuMTVV¢Ò,ÞùÔ¡²¾ Vw?¿p�¥� É|Ê4ÔuÇÐ î€D£§k¥DO’Þô=QYÉT5›æ®Áïk-ìÈ[Qw²5�] aÅ…>ã]ÞîÏì OF…eêùt jéPO¯T¥Í\ùÁx«jñ²áë&`#‹€Í§‘µ?‡b4¤ÇªGør8‡'ìéé‰hBN ¥ÅóŠmàL|é`FB£¥“Êë&ä‚à00�aN€ŸÂ_�øá·�~PD¡!ùÁý{¢ÅÊXÚ¾ecÏE“.éš9sF²¤4‘èÁ„Ò§‹TæS{Ïú5+:—,z’õ">–üC… \à ó�Ó`]!‘'¢%4)®(™% J¸É1 PšE£ñƶ-Q{_9“é3Þ]•’¯xŽ|%PÀ‰´ÝQ}˦ÐÓKãà}Ó‰_0¡&`#˜€Í§¼sÏãÐêµî'%ÊïèÑÊ0È€¢ŽË¡ŠÂÂÂðœ”ÖÖÖÆOËÄgÁÀÊÜ/àK00�aG€¦³{%&"û¥K%ÞËCtt´G[·lˆäÁ¶-›7˜1£fÿ´éÓK‹‹ ʺ)Þ BæSGkrÍê•�Ë—<Ã÷&=üjñ˜Dß!Ç…'@Z¥t“4¦G&DRóÒr�ù®´˜$:F�DæŒw‡ƒE†Ìز92Ÿ¦#j40©cäËy¡Îz×Ô±-êèL™‹ºiªDù5Ù�§y'×0�¼%À—/‡ œ �&=è)‰ ¾$f (²‘È€ʳàÑ„œçìã,xlPÏK™Ô(]w˜€ ˜€ _ü¾F"Ó–”² J%¢ ³³½ä•Í*úá·Ú·n|iÓåWÝÐ8iòÅ'tžöžž¾³ 0ŸÚ;ÚzÖ®ZÑýÂÒgsͧ½©Uûÿ L€Z;ö=û›òK•W¶F”]U”Ìrö@FA$ ŠtÆ»ý:ãÝþÔïdBV¨éø�õ.‘p\~”Þ•G�='¢æöÝÁ\Ôxè÷†ñLæk»ä0¡l>�Ð;DÃâÌ ¥éÒ�RÆ€ª¨¨g¤J*΀jVcÚº:~M Á�,Pô€Z"¹O&`&�øœ øEœž d@UIñw—®®Î ¯lyyÆ£}·»¡®îXÍ¥—O˜0¡”ìÛÜÏŸ�ùÔÞšÄ|Z±la®ù´Gëu ôýâ¬wü°UI –Ò©•ý¤ÞO!û©osqxlº·â\àŒw]Ɇ¨±u{0YgqÑe?]æ¦ãçð^û7¡ª…†¶�QW7^súü="e¾À§nöÿ&`#‰@ün$�ÉcZüB±HºBºš§¦ÿåošèÌDãO™°Ìù ²®ú9 MLçIL`(åp˜€ ˜€ ä²a^‘•¶I3¥K¤8 ÛZ[Ư~qéø§Ÿx¸½³³«cÖì9EãÇ�M$“'M¨”ùÔ­]½²+Ë|¢$ûgÒ®xe¾¼à(½Dd>ñÝBÙ/mj:>^ÙO>ó“L$Š fΪ.¨[¡E4]-Hê쨭Éu«Wô¬Xö\œù›O;ãõørX¨×V�U}³TÞ“ìR¹UQT.ó©¤h‚nrö“ ŒØÀ\¢ô޲¬¶Î£ÚÛ=RG(½,/¦ïSшûhXBUÔ=‰ö¨±e«Ìe~_=ø¸|BâÄ0�HÀæÓÜ©hHMzÞåÒ}Rè ÚÞÞÌŸK.¹$*..2ŠR‹ÒÒÒ�ՇŷÖyÒ iŸä00È/�Ú\>oÈXâ:?zŒ—Bôôt9t ±dÑ‚‚µ«_ˆ*+'DUUÕQIYq¤ ©híª+–/ä dó)…m¸ýÏl”æ>dT³S�ÇK&GeÅ—hDZë#—@2ô÷êHÖÊ€Ú—îûÔ#ãq¬ú>Õ¨ô®lä}”ŒŒWpqbLÔб9êìâm<Ê´ÉxVâûyH‡Ò¥ÃL`°ù4‚væ0 }6H¿$Ñ<0jjjŠZZZB%q¹=8Xæ|ÏCÔ´iÓÂóçô€b’r‡ô”Ä©�&`&`ùE€™Êq‰¬[~)ï�ª¥J)¸{÷ìˆ?ûx´kç+Ñ´é3¢ 'lX·:¹|é³Ì}Ÿ�K;$Çð"@öÃé5RQRÙÅ…2J«ÂÙ²œý4¼vÖ¹Þú% :Õ÷i[ÔÕÃ‚ž¨’Ò»Ä8�)"yýaÁíÛúìÆãås‰¥R{^Îo&Ð'›O}bñ�gI€Éý”K?/…㫾^,jŽ4ÔP<¥­­­Ñ‰|ž…`Âq±t�ô°D)‡ÃLÀL ÿðë8%x %~1/–ª¥LjD{{[´eÓúèùEOEõÇO4(+jÏÆ—×ÐÜ–Ú̧½¤Ë�ˆÉ¤¦ñøEIeFp¦³ e>•QEÏWÇH%ÀµÂ‚⨩sgÔÑy\{»GPí*½¼DÍç]z—¿û=!ãPÓõôJªµ[qa™�oQãñL¥Ý ��8Ù„_äù»£½å&Ð'›O}bñ�¯‚�M)ó÷I|ˆ0 È>¢%qC•Ås“q5eÊ”ÜP Ý5KâŒ:”nøN&`&�§hPÍ�I”ä‘á:[ÂŒ ÑP_©)y$ã‰Ï%2¤øÀ|b¢cóI†Yð¹ÌÉBè'YŶ%…¡éx¹ (ÇH'�”ùTu&�+3fVé]eT9@é]2Ñ¥Œ©ôW:½Ò]¢9|ŽL§îdkt¼eyt îgÑ‘¦ç´owꌆM2Ÿ2¿óÞ·òpöÓðÙ}Þ8'l>�Œ^I&ôTâøºK ý—È>€ºPMÈ�;²°´MÛw­Ô%±½l·ÃLÀL  ð~N ÝcÒKÒ4 ã"|é’l§1ÆÁ¯ë�H;ùÃ1ìà2ñ=‚ò;•Û‡ž?%3m*d„Gœ!ÓØ¶-êìN•Þ(ª²üÒ¨¨°2J&0™8™€²¢jJ®ËT« åÉÉ€Ò¹.uwl?Åog�í)(PæN_y®áŒ÷Õ�ù\�°@o½í=G£½'~ª_¬FòGÔë©A—Çd<‘äØ+xÏæG²ZÓNb¯ûý‡ ˜@ž°ù”§;.6#g‰Ô!Ý-…c�ò; 2‘†Ê€*Ð�D"z@ÑêÀ�QwwÆgb"Â[N‹Ç¯å00�ü'À/æ%ÎŒGÍõ\i¬&6ß•”2?»ëºcø áøë¥YlRqaE4NÆCyñ,›Oá�u’((‰š;wEí2)Bé�¾VŽ)�••LÕ}|…ÓR2�¸C(Ûj P! ÃXgkÆð¸‚¨CæI[Çž¨+Ù”ë»%‰•çÂI­Ÿ-|õ}åãÆ€“Ï.Ãìl¶3˜mÁpc«Î~œ¬§£§6Ú}ìûQ}ËU?d¾ƒ÷7\Ê¢ù^þ‚äì§þ(ùvÈC6Ÿòp§åÑ&óé‚¡Ãü{%Î\ú/ÕÖÖžw à axíܹ3Z»vm´cÇ�j»ÏÏ1¾µ0 q˜€ ˜€ ŒÍÊ*ée ŠL(‚4ŠH—2ÍFtÝ1|0³Ÿ/ý’Äd4*)žM(»FÆÃtþtŒxÙ¥wñYïºÕ÷ib4¶lŽ %"2Y°EÈrŠ�§l,)ω%è5D¤þWõËwEµÍK£='~jXo^µuŽJ‹/ Íϵš>Ê6ŠøÊœÊ¬:[£'MJâohÛj|2ªm\µvŒJ ÇEE‰Ì¹úÜ’Þ7²]‰¨½ûhÔÚuP×»•u¨„Ñ”ƒ×{ÑÓþ•¥vûê~$ãió`Œ§x�×èÊZi—tZ·JË8LÀò€€Í§<ØIy¾‰|`¬‘vH|‰äLÁ€"jêÔ©ç< Él'zLmÚ´)Z½zu´}ûöÐ󩳓VT§7>$=}Ê=¾ÁLÀL ß PŠ·SZ-UKôâséŸ%>›Ófá{¤Û¥àT–VE*®WÔÝ„¡p.‚‰v‘²h˜ø‡B­s±ÒW±¶'5ù+1ÅÁóhl߮һF�+ Ê~š­Ò;*h1ŸRÇÔ¢°ÙŸdû°,ûT÷§3 Â"ávÝuÚkŒŽµ,U�¢'CöÏדìŠZ;F­�{£²âIQqÑEÚFžoð‘2Šº¢ú¶—e=nPÿ£Îí¡´”ã;UÚ7øõ¥ÆÚn\í«{Dg Ü)ƒìXÔÔ¶3jéÜ•jKµ�0ë‰jÕ�i÷‰µ]‹¢­«5j5{/ž™Î6üv1Σ- £# ËCß®ø‘ãÇ��n¿ýöhæÌ™¡/l? sÒˆë¤ç%Ê£³_ð©ƒ@7:LÀò‹€Í§üÚ_ùºµdm–6I¤ÏWH™3Ð�«�…žRe…“e@ 4]cô)3ëxó™b©¾¦|GÆ(Ã܉O²ƒÕÞ}XÇÓ4PßÙ×{dˆ=¡ãPcî§ÍR‹Œ¸Da�Î:Y2óNbúžh[¡õ-Ó±˜ÊhÂðºå–[BÆSü>~GëÓ×%ˆH) #{©“×ÉØi×™Åö)ãä`ý“*ASPË:Y{dfŒ×zÈÌ*ˆz)C%µ>p‡¥Ì—ZeÀüPÆØ 2Ìv#«Gã¨(¾DFØé�#ÖQ×¾^ëø©¿KX[Ô©,!ÌJÀB³î°-'Mº“£ˆ¯1R�eNY=í]G”•³_fR½ö�x)‹ª²¬Z& ý¿´”6¿MË4´¨Qé»û¸`»;{Žà # �;vltç�wF555Ñ´iÓ¢¢¢¢ðÝ3.£$s±¢ä5!_msÖÎH2×Dûë¤ûGeyA×¾/áÀWˆ ¨Ž®£Qyéô>Œ¢Ìã´Nqn[­l¹ç´üÉr»Y³fEóçÏ�***B…AœQD)]gO]8c`ab¼Ÿ ÖÓÒµKÇÌÓ:.3‰¡|‡æ[êìTXœ ´’â±QEÑLRÎtsï`œ=ÇÃŽNN6šrûئ;î¸#ôzíýˆÔ_Ó§k¬:+5=ac®YËݨëlØZé”ú¼¬å|ÕL`°ù4ŒwÎÞ4>…vJë¤{%ò”Õ„¼°°0jhhˆÈtZµjUø€êÇtâÛM ?'}Bú®ÄsúK&`&`&0LÌÐv|XÂxºM*—21¦tF4uÜ½ÑØÒ+tøÔ$>˜HÊv!ãe`ÅÍÄ)uëÖÄ»>dÐjx*:ִ┲'Œ™1Å34韥gJ}Mæ¹ôGȬ9Ô¸@}už åMdÄ𽄠>™|!CiLi•Œ²)zHêŒadýª_(Ãá¸ÆÀW Tð\L¶éyÃ�o³gÏŽ®¹æšLf †AR¥ye%Sµ ô‡Jý‹×qò’Û Õ´z[´·î!�YlcÆ8a™ö®ãQ“JûÈ€*-¡ìŠ1É€’‰§ñ¥Ö\¨ °z$�j›2ë ƒ†¬PTÐxZ}”ú Êýš:·FûÕ7¨E�¹s£]&IsÇ.8åÊ왚Π9É%^~uêc_Ë\i¿8 ©»»U&á”`RZ˜Ê|:,cï•Ø|Ò “Uj½�ê¡UQ2M�·ã狟åä%Ï×­Œ±ƒ ?S[i:;1ÛIDATVÛz�=õûdl<]~ùåaóö™ö%±±ÓÚqD¶X‹¶iÆ)&û¦±cs(ã#£-+VéúG¥¯K¸G˜,¤`uG2üJfi}§ž­Žu¶RX÷³¨µý�‘ëĉƒÉƒÙƒQF3oZSÄí(Ú;�‰L§²—f¦�D $e=é y -;µ–´1™jIñ[ºóEén‰´®ÌÒÐl]<ËtœëÀép<Ú¼8:ÑôRæø)--�î¾ûîp¢¡^ gýÁëŠÌ2ª"ø¾Ïq—yÑë¤ N ø´ý5´ŒÃL`°ù4ŒvÆ(Û>MvK+¤ùRø %…™ò¸ ¹nÁ±sçÎè…^ˆh$ÞOyHJ¤ì^Z)qz‡ ˜€ ˜€ ˜Àð"ÀgÿïK”&÷Þ´Mâ'ESÆÝ�/¿&Lˆ»UqÓÕÓ$ƒ I&Rƒ®ÇRÙS·2:TÆÔÙ]§L.OHÇ”ñ³O™J[BO¦#:£Ø!evÔª\®YÍ�ÉjÁ4ÂüarL¶ß7È^¡¤«@}m0dèËt¬iY´¿þ§ê#$C&dÒè—3�±ë¦›nŠ®½öÚˆï/'NPÞV¦ÇÎQ™×4A»T^õ3=v�ž«#L®12®¿þúèæ›oŽ^óš×D×]w]¸ ÀõîÞ½;jn¦üNM²UzWY:[ÛZ¶N½çû˜RIõŒZ­L£Ÿ¨�õýuj6U— ›æŽ2}ÊÔû3‹†æ*N“•úšÅü¾K%rO++ŒŒ°Ü §¤  CÊz™ ~DÓú,»J"ûe<=,“o�Öwêv°ý]Ý-º_å]Z×T•Ï)›*aÜËøTö×}PÙ3ê¹ÆÃׯŒÁV‹§Œ»2Jï*µ-Zß6eV‘ù~g$Kæ!‰4­ñ2­ R ³«Bi\o~Z"MFµ-χ3³u©Ì�àØ ãéÊ+¯ ÙNáFýÇqC»Lö{üCh«ø0& ºÂ”�úGuíVÿ£G´�{õèÌ8^Ö“('c£ù›í¥Évp›Ú•Q•Ç$†_vé%=•Ú”©D™Ü+áXÖcÂqÌYä.½ôÒ°�dhñ�º©©)œ:ÞÎöÎ#aûÊ‹f„ÒŶîý:Vè5“ÉzÂ�ú¬´\b»¸ó‡í ŒÛÕïŒ^lÅ %k¥÷û­­û�Öõ˜ Ïz qõÕW‡c³v Àl¢\°¦¦&|l/¯ƒôvSs{½ôv‰mai(å*Ap˜@>ø FàmÌg|úêg´�Bûsº ´q¨òòòð¡Ï'š«W¯g±‹kì³ÎzøiíkÒ‡¤/I;¥ÌO7ºî000^æjsÞ)Ý�»Y©� B)åqôfª•è�t¤iiTÛ¸,\•)tTf†RF*‡«mz!­Uzö² ™Ý2Nj5in ÆÏG“ã+®¸"˜@d¯ðãWj¢?#HôjîØ©L§G”²TeM©3vaT1¹¿çž{B¦ÙKeXdà”Mp2RRý¤z‚QqÛm·…ìÌ*&טôºäño~Xc‚Ž¡Áö0éÆ k§L™>¤ë n ËÉ\Òd¿  K,žFW›²Z²b«®“fC/­bnïééTÖe?]¤, IÁäÁ€"Øöz5=?$“®3m`„1^²fÂö©ßR»Êà*B9ØE<*<6<^ÛBÉÚþz²¦^Ñò™Ä ‚o¥œ¬Ë0ÿ`[šÚvj¿PiÙX•N6“rÅ‚èx«ö]óË2ûò2°d•ª?W¥šiˆjë—Êl¬ �×:øáñ/¥]ÒµÒX2®NöÐê�¹…iÒÎl÷TÈÓòaܯ}ík£«®ºJ=¦Š³³pÂuöͲÉЩ¯¯Ïü(ÚJ¶—2‹È€*–1ÖÖsXOëX8Ù?J«ç{êÇ¥g¤Tó¨”SG[Šé2)ld[×a±'C“¬­°E'¡žJ+SFYÚ0â5ƒ‰‰ØgûŒëed?ÅÙDd/±^za•é8¨m~A¬7‰|æ«ó =ü¯¥ø€Z§ëd>Ý(…•s\¶«Ùú˜Ò™§îÒ¡À~;Ò¼P&íf­+µÿ9Æ1ðÈÈL°Í¼x}\vÙeÑÌ™yÊê“ •.Ç+ÒzæHo•Þ QAqHâš:˜uÅa&0üØ|~ûd´mû¤íTø@£¿úÑˉ/„Od;ñ�”ü±SúéÃÒw%>|&`&`&`ß“F20N 2“˜à"2eèDV ¦M™)Áb}Š”mCæÙ1ÙÁä<6 0È!ûˆ²9¾cð�ƒeÆÈ4¨(­R¯¢�ÑÞ`l ÏÅ}”[aHÐ8CbÛ¶m¡ÀÞ½{ÃĘí¢<­¾uKhvMæ ¥twÝuW4gΜ`x±MÁÈ‘ÑÄeÎw›0ÑfÝZü Ç81ÅÆ”Í’y¢ì'eÝ`Ï0ÏîQª#:;e}Ýø-!:õÿפH_”HaJeÓh=]ÝíÊüÚ¥uÊ€+™¬æßœ.uÆ´ZW«²ÂX7Û@�²~0˜ü4D§|Óádƒm¶I™8 OªÜj½ £ØO 3ŸÑÃø®¶@Â|ª–R`˜5´nTÓîz™PêK•˜ D'£‘ÙØÒ~ ŒR‹õm{OOW0O4¯S™Ümwl<…l«£zß Ÿ’.—.•JÚÔG©´x¢ —“™[©,«ÃÊLz,œÑ�±cvÜxã�½Œ=¾W°ßø¡có có�ã.”(Ê,)'ƒèõÝêUI–þ'¥G¤Ô“k܉ Ÿ*©�cª]ÙDeÅS‚aH_±¶îÑAe*Ñ ží%Ȩ»õÖ[Cæ\¸!ýÛÉ1NÖÝ‘#ê�¥cŠ ßÙƒd�‘éÖú3¥îÒÿ--“8–žäE –(<¦M½¸8JÊ#ÃK¦+¯Ù80[çÎ�2±âÛs K2Ì&L˜ÌÚšššÀ›íÏú!zºÖõz #ê*‰Á%ã|êºÃL`˜°ù4LvÄ(ß ¾%l“0¡�ÂO€|X’ñÄB̨œà×�’Þ/ñá͹ÃLÀLÀL ðÙ}\¢>‰²£#ÁßÔ€ IdU`�ÅD†G¶¸�Ì&®L‚1�(s#£‚I-&Ù}ûö…™¤2—Æ…ÓÒ®^ÆF*K Êì%žã¥—^Š–,Y½üò˽O3G��1²b0ªx>&þÁ˜Ðw›ÓßXžß8¹Jg§Ì‡®cÁ£$�$&2T ”ýTÛ¸XÆÓMö3ÆæFÏ_I»%¾@=/ñ=ë IæO2�ñÐÔª¬#²jŠ*d4UÊ yIÙ/2Ždòd…Ýpà ¡ÛĶÄ� S}ƒÚ”‘%ªpŒÌ+¥È´(­aiö¶°š/K_‘Ø·dÑ<+a \-UJ!ºe4R^×оIƕʬ”¸tBYOœIn Àxd,’)$Ãw—nø‘ĸ1sn’fÊÈKtöœHõå åbL…:tæÁgT¶(ƒ(]RI¶ ûšãg € Ç ûšlµÆÆÆ”¡¨=ÔÚq jhÛ®³�Y±^×ÿM¢.±¯€Ê-f]AhØ®&Þ4³/R6gI¬k¥'/9y:&Ù^¶Ã&7ØN²Ø8¦âvY†Ò¸¦¶iã)˜vܼVâøIüÜ’ ±R‚å,)Ì#É(kQù¢’pǦ¶ýº+µ. [ž—ãN¼ÞØ–3‰xyŒÜªªª`â²NzY¥ÌÙ°>vÔk¤·Ió¥1ÛÏ|áÌžPp˜€ œ6ŸÎW¯õÌ ð)õ²´YºCâ×о‚|à%ÒïI|™áCÅa&`&`&�øì? ñÙ�ËÀg?îÊX ?#LZ™pb"Ñ?‘™‚™D™ÙE˜K±ø›¬¦8ë‚29š3�¥œŸ -brÌ$6Î|bžÚ&£§¥mŸ²BZS™Pš4WWW‡ÉóæÍ›Ã O0«0­â‰qfCu…É?Y(”ñ¼l;ÆÓ`ƒÇ³ÞÔp´}4§Lêˆ2·&†ò+²_8Sg9£ßUz~�©óÿ¤”0/²ƘP0ž-•1#oS“ìz$ 22ê[6Ëì!q¤'˜˜dzÁs…Ì'J·â¾AmjœÝSЦí3u†½£ÊÄyR†Kìj5©¬£Ïë’ìö8Út…íØ*UKS¥Ì|„¾T�mÛƒiÓ©3ÛeÅKºÎc&HeY·÷wu£îø©„�0N0s&vv5éàê’‘SÎ"X×ö’L3ÎwòùØ_˜–”Š1þ�‚}Åq#2 2”öY§²ÄÈ\Ë ¾ï>*‘ªÕ_ìÐ<ð)|'fû8£^w�z�ißgŸÝŽì´ìr»þVŠáJ†V]]]æ˜L�ѯ—?óE=þ)ålõ^Û é5¯Õ°ï(I=Ѳ>½ÿ{똖dr‰…ãzü Î£™×òÔ©SÃmüH�n¨^¤r|ÿ¼ô«ÒeÎ,¯‡Sv„ns˜€ !�Ì›ý>§ŸÊú#À§_,ÖHo’øÕ">ù‚úÒǤ-’ÃLÀLÀL ¿ðÝsšt�ô^éÏ¥�H¿,‘ “1ž˜ 2©ÇÀ¡17YD˜J4åfÒIV ÙO˜I”ˆ!þŽÅß?“Ö¾2�0ÈÁL¢$)5Á=Y²Çýˆ¬Jë0bó%¬8ç?²­ØFŒ§K.an>øàyØ^L§¥K—“«©‰ysÊ ÌŒ¦ê4bïN¶¨Ün‘ÊÒj›ÃdŸ…¾.ý­DêI_� ³IâG¾ZoH‘!k¨CFO*ã)e�å…¡AF L`yÑEÓ"·¼Œ>Oõ*Qlnß§eñ¿Bð=í“¥Z¹“~¶•ûŸ”08j¤Ì~×u­'÷!Ñwt3Ù8d¸`(”JÅRݹ@ªK/´]—3¥«¤²ö®ÚÐgª0Q¬WϨøÉl–'à ƒC ³„}3PÀˆåXžÇ±¹­ŸX«ÛÙ¶ãýÜߌá—k¤ð�˜¾eMmÛd<5ÅËS–RöÏé¶“ýÉr”QÆ&YfE©+ûtñY ý à˜îƒïuLO;Ÿä5Ãsnß¾=°¡ �×6Çûœ´êSƒåy-óºÇÅ„"#Šub$g™Â˜v·Jo—x¿Á˜:(5K0� @à´o`›ü”£›t|ðñ¥ä^‰]¾ÉüLúm‰_±Ú%‡ ˜€ ˜€ ˜@~(ÖfVI¿(a4}Z"ƒ™Ïyn§Ì.Ìî™<“�ÁÄ™ä0œÈ^â”ñ˜JñÄ36’Îtâªç tŒ-D0 ÇX"3£¯`â܇áÔ£eùÎ’q%0È¢Ìމ5Û8˜ˆM'L°;v„r¾­[·fJÜ2ë(PCo•×qV7ú*µ´c–eLšÿÖr˜;3ËŸz…ÿ®Ä|㘼÷•�Â$ž1�ù›pÆX#s!Û\iU}›²¶“ë ™Ný©FÏH %êæ02*¥ S]'NH_’–I‹%¾^.qÜôðÀ !•‹à»ä.éfi– »D{÷QõxÚ-ž{´¯NýjIIÂèdì§ a@aî`ÐÁ¨Ÿc`‰Öõ¬t2ժs1ª0koÈøJ›�ú3u,“ᇃAxº`³Ë³÷cú±_Õå�¥ÖÓ¬ ê9ébéJ)÷É_ÑmKÌ5Y&¼ØÈN:tèP0¡0t1ÃØŽÅ³‰˜/F4g‘¤Q9ãÌ:KÛ6Gz‹Ä{ÛC&Æ$¯a‡ ˜À°ù4D ý4gD€ok|hñ‹Ìß“þ�´_r˜€ ˜€ ˜€ L6gIo–0">%½[ºQš(e¾ƒ’ýÀ¤½ºº:”ÒÅ�À)­aÒÏD26›ô¸³ŠØàÁlaÌÄ—, Nh²jÕªèàÁƒýÙχA‚¹ó‚Döã(fÝLxiÎMÆÐ`²9²·'>ÉÊŠ+¶`î0ætPÇöoÒÍ“g貜 %ÎÚ—š7‡åžÐŸ”6KY d�_&`ZÄ�Ó1!0¿0ø(gdŸkf°Mì'Ä6Æ ÈûxÂoê¶oKƒ Œ~dŒÍª*]�M(ø é»ëƒûb Cêr‰}�kVíÕm0ƒß)ãàñ˜*”ß]D‰_{çqõMb·†À¨âù2Ç&YLT.�pGÎ0Â!ë c…ã�,ªóòq=l‰4˜ œ6-·Zª‘.•J¤LPJJ“qÊ³Ž™Ìý}]‰÷#�¡ÿSÖ~ܨå?*èëq}ÜÆwôÇ$^R±Ä~yDb=_‘Øo¤éÒ4)°åX#Ó�r¼Ã‡Ã)©×zAÌLË�Q0&Ä>ŠÏ’7{öì°x}‘•ŽIºœ'½UºJj’J˜“0�óL ÷Íú#ý®DLðÙ.½_ºF Ç-,ÈÀ£§Çí`‚}Œè‘µ`Á‚pÜ¥9ñ<—¾"�̺ÒË\©Ë/IwI˜%~9YN¬²EÂøÀyPÚ ±�¹�ÁÂ6`bl’È29]°ýÿ"ýŠTAvɽ÷ÞšcŸî�Ù÷Çc!“dݺuaŸÕ3¨UËþékÒñìÇ Óë”0þ–t§ëÿ”¶Kñ¾¯Ñõÿ+aÚ#•rD2 âRPÝ>``¢`4>ûì³áXL/ܤË÷K?”Øçg³õ€�Jo“&å>Ó† -L²Øú;.ãDZO11Ÿ(AÍ2gŸÖ2�¶H1“øaçê’ã˜qü†„y]$õ Þ?8^1Öxÿ ¯÷Ó�«×JÒ0Vö ¯=ÌhúªÑc�ã9ç}h§ò�´lBõÓ·™ÀYH}zŸåƒý00000�QE€L�k%Œ 2�®”J¤LP¦Dóíêêꈾ+d;Å6§ËªÉ¬$ë “F"6›˜ “Å@™¥tMô âLt˜Mwî–ÈŽY(­�02ªtÿH¿#Mf[h~N™]MMMئœ‰«S*‡–CLt)«[¿~}(÷Ë1�xÞ—¥Ç%&û˜_Ù™NúóœÄ;µ–ÏJ5ì‡yóæ…É<ñÁì™ð3zSa åìË/i]Ÿ—ö v�y°Ü¥ÚÆ¿‘~Nª  ŒŒ1Œ�Á4Ȇ/ûc‡,¼t`f¼WzNêJßv¦¼Þ0k¦I·HoOÿ]¬ËpÜaøbŽÎ™3'69ûŠÅ2Ávb"’¡…Y–µì³Zˆcÿé|Pl¥ºdõÝ—ÖõºŒ3Òt5õÚç=…CÆÄuLlŽÉ35¢x]r<óºå=ŠLDÞGrÖµMOýeé;ÒAé|2Ðê&0ò ¤>ÍGþ8=B0000�³'0U�/‘¥@‰S¯¬ &tñ§˜ bÐ�¥ÀíY“Y=lpÁãb1I$s³‰žMd81a>ͺi¢tTÚ =Ÿ×k¥¤tº`ü1éW¥r &¾4éfrOôe<1±e»ØÎ 6„ÉmŽ)†ÁÄÄþ¿$LˆÒù zE1�~ƒTB#ñ{î¹'dÅ æ ÙŒódíÚµ™[Y ªYc¡T‰2¶ÝÒ`¸j±¼‰«µ¥k¯“Š8¦ïºë®A›wË–- YbYûŸýMæÓFé\Ål­sô=ÒL)Ìï0•h|Ž U]] àsE‹¦"6 .\š€g½®žÐP»¤¡Ø·˜Û7H˜Û°PÊD\¾Ëû ÙPd{aªž�ű�âÌD^¯”Ãf�ŸçÝ$ñZý�´K² %8áÍélèǘ€ ˜€ ˜€ ˜€ Œh”Á\.a¾üšÄD¼TÊ“>Œ&&‚d9QVÇdމ`®1ƒ‘ApnÄ÷q;�¥ŒŽ¬ DVå19™C¹«!³‰  ¦¥UÒKÒ!©Cl0Ù½OúSiž” ÔêꫯŽnºé¦Pr××$žq1fÊý0iȦÀ ËŠ]_(a-’2é0º~¾£ƒqÌd ÷ß0ÐúÚ¹ïGš5ÇgÌš”3_(a:='‘Å5Rã]Øg¤ˆÙ1oÞ¼Ðÿ)û¸å¾8¸�c˜’»W^y%»œí_µÌ_Iç#Cìf­÷%L› R2«««ƒ ES|Œ¦¾Ž_nÇXd›9 ]Ö¾~P+úcé@j�Cö?ÆéÏKo“î�*¥^AYï?d!Ò�‹÷Æ¿ÿä¾õzpÖì/Æ�I¸k×®`bBåpÚ«‡üHú¦´^ÂÜv˜€ œ�‚3XÖ‹š€ ˜€ ˜€ ˜€ Œ|Lòn“˜ô1ù#›"LÔÈrbB‹éÄéÞã>NLöâ ËÅâ6šk3¹C\ÇHâöx¢Èd�É/�Á)§ã’Ûœ�]Ó‹fÓ‰l§nél¢\Âlû˜DæS+ý~®½öÚˆÉnö„4Ëa–qF-c@Åt¦Ø2éߥǥzi(¢ZOòé^©ˆí¿ãŽ;"ÊÇ Æ„ñ„ÙG �7†2ǬÇìÑu²�¾*ɺ}¤^-ÑÀþTÂț 1;î¾ûî`DñwnÀ�c™3ÝQª˜6r8>(}O:_Æ#Û:O„š/e ²¶®¹æšÐЦäÙDZ– �C–ÛÓO?L˜,Šãµ©%‡ôÆD6Ô›¥_�®•B‰¡.3Áø0¢0¡ÈøbŒ¼^SöûLæ}\áØgyÊz·oßÊ&é•ÊLE^Ç_—IìW‡ ˜À Ø|$/b&`&`&`£€ÀT�ñ ÒoJwJã¥LPvFÿ&J·˜|÷•å›1\bÅ¥rq_&&äOômÊ™Ðežg€+­ºo§´RZ,­–èÙÄDþ\”‘-ò[Y5R8å;evŒ9žÄr{ùd(AË:ž¿¨e>%�—½—ãôœ7KŒí~i®”›®‡ û‰cž÷+ )ÊdÉX#û/>ÆyífÄñCÃelBñ~EO(2)ùÍbÁrÿ˜Oÿ)ýL"³Ña&0›OÀñ]&`&`&`&0 �Ap™ôËk² J¥L0a£· gÐâÌSüMÄ7&jLè0)Èj"ë‡lDÓi²—2ÏÓÇÊZ0lÖHôlZ*m’È<8f“V“‰Ktí¤÷IS%J·Ýv[33^.“PšœSR…r2�Xéné[Ò×¥mÒP“rÊûî�˜$˜%d‡Äû-{ƒSl˜ÐÛ‰Þ7ddÅ]Ç|øºtT�SÜ-�?>”1òÚ€]v`àЗŒ&Þ”�¦™?£e> mÌ^ö<_Ÿ¬õ¿KâØž#J!#ˆL8úA1ŽS%˜Rdü<ñÄá8Oo?¯¹ÿ�>)–.tŒÕ\'½IÂ4çz¹tJ`œ“­‰ Åë..ÑcaÆßßë‚}Ék�÷3 f.1г.¼7a2?,aÎ�ë÷'­ÒaùOÀæSþïC�ÀLÀLÀLÀΔÀT=à‰þ0ó¤iRæ{!f™4Øæì^LÚÈ& ˜¤ÅÙ˜M”›‘Ù÷fâïz31)#c Ij–p80™å+�†Ói­ôRúï.]ž¯`Òúé­R%c#+ã‰I*ÓØœaÒÉX)¯£,'§§Ûw@ú±ô5i�t>·[«ï30>-ý¾4‰I6½ž˜t3ŽÜ`r�qHo§~²�Õc¾ ½(õšuç®küý�ñ/¥Æ:wîÜPÊÈk%;`ŠIAùÆd:0'>+aä u\¯'ä‹4>~rŒ3² 0•1h²M(Æ@ÿ#ÆÀk:Ëœùo=ž²ÔÝÒp1YÆh[xóžv§ÄxgJ©7-]ɲÕ&Mš²¢x]ðþF9jÌ€±f�7¼nàÁûïsôs##ŠÌ¨ìåô¼æ¿'ñ°M:ßnz ‡ ä�S?�ògÛ½¥&`&`&`&`ƒ'ÀíFéÍÒ/H—K%R&˜`qs²œ.»ì²PªÂm¥rd11=räH(Ɉ¡ì,' ³>&‘%±ZZ)m�˜|“0 0œ˜ õ¤/¹>TZ2¼^/}\bš`òI‰Ý­·Þ&§º-L<É| |ŠÌ‡½{÷† /îË Æôé›͈/¤IóZ=ÿ—¤d60–›o¾9d»dO”cC�ý·fÍš0¶œl§½ZÇ?Kiµ’#ÕCéïâíÒXîÏ›7ßñšáXY²dIx½hYŽë?•0 NH"*ô¤ï”0¡xí'¤p\ðzçÁ¨Ì6^& MÈs ¨Ezè'$^ӼƇ[�ñu•t«Äk›÷½ÙR‘tJ�E‰'M L�~QTÑ1�øµßFæ#ûxëÖ­¹lX?ïy %ÞK%Þã&0ª Ø|ջ߃700á˜`VIo”h¤Mÿ— R¯ˆÏZwÕUW…l'29˜laF�¹A ¢ŒŽIèfë%‹i¿ô¼ô¸´DÚ' §I*“ÓwK(…,Ê ã3Ú1 ' „æË»”ýA¦9]Œg«ôCéÒféB�±LÛðw&Ãx2:æÏŸ2;ôw&0 gŒ'JIJ²^0JØo-a.�©æ8Ià]Å”{�T@ƒk (LÛ80(V®\¶“£8*½O‚ë…æ‰!ƒöiŒ‚ò;’ó€ù›.+dq-Z´(˜Î± £aN~Vú¶Ô" çàõNÙ$FÔ<é&‰Æûc¯Àt‚¯�É“'CŽ¿ÉŒ"û36Ÿ0oaA,^GQ}”ß²î=Ô£ÒB cÊF” 8F›O£oŸ{Ä&`&`&`#Ÿ¿ð_#aB`:UK…R&˜D1©â×~²œ8C™?˜K-dú`8�&³‰õ1‘:.‘Õ´\ÂtZ+’02†[0 ý�ôR(AÂlŠÏh‡Ç$’^NL*ÉpÈjºÍX˜h¯’¾#="a¬ —øm™9W`¼îu¯ g7‹K&¹ “‰ý‹éD©]Ž‘¸K�ý¢ô ÉÙN‚ÐG`X|Bú 4¦qóqŽ�Ø”X¼xqhTMiªb�ô»éË¡Êìãyû‹‹tÇoKï—ª¥Œ Ãk‘ÄxYŽPY Ôõ°`4K—˜P»¥|0Ux$ óð^éné ©\:%;½Ò`A©¦F#†u¼ÏyŸä=ƒ’ƒr½ÊÊÊPª‡ Iï(L*LlL}Œ¨œ¾Y¬à ³÷‡Ò÷¥�ÒpÌÕf9LàÕè÷ôêWí5˜€ ˜€ ˜€ ˜€ 1� =߇¥�Iã^Ås7é±[¤eÒ"i•´_ºÐýj´ gLÿDúMi,Y@”r&?.Éøê£‰8“B&‚?’0�0Û†sFæÇ¥Lµ{ï½7L†™ôb:1ÆœžU´ì×¥¯H»%2Úƒ'@Æ ¦YC•dÞwß}!£�^i ,ÌÓFß_¥—¥ßÏp�mØí¤R)dø`ÔÒŠ´„†ê_Y%fd>~Aú{©Wj]fEùw¥\›çÓ˜¾˜ü±…ÙM /†$™Q9Íýµšˆ×#&÷·¥¥R‡ä0�E Ïˈ¡c&`&`&`£‹Àë4\²˜@2ql�õ¯ð ¤g¥—%ÊCò9.ÕÆÓ\™¬ ¤� ‚Ì�œò!&|›¤HJÛ¤|0eþ@ÛùgÒLÊ�0A0ÈP¡oUºï�îѬÿé;óOÒjÉ“\A8˸W�ûg‰L™`<ÝsÏ=!ó ƒF™A™ì›/KÇ¥á˜Nó¤÷K¼‡ôÊ„¢çÑõ×_L(†FÞºuë²�M^/ÿ.}Z:"�Äà d–4WºI”Â�"kª/ý‚×eviˆdEåô\cY < ÿoJKùþ¬!8L EÀæ“�000y.Ò�.“¦Kôr™"M–ÆKL.‹$¾¶KG¥Í%u¯H˜#%~Sù”DÖÂ@A–Æ é»Ù¥|‰mèJwKEô°âl…û÷ï�ššš²Ë¢0ȨÀtz\bÌŽWGCósÒïHãrGÊÓ.\Oëv^c�¾'åsÆözéƒ&ï!È$£ç–[n‰ªªªB¨¥K—†ã-^F—ß‘>*ñZ€éÁ{îé6 ^·K˜Q”5ö ú¯Q’GV\ŽùÝk9ýÁëô�¥|1Ás·ß›€ ˜€ ˜€ ˜€ ˜€ ˜À¨ ð‹%MÑ™üæŠ2ºíÒ¿Io�0æò-0?.Åü¤zy厓¿_’0@0!ç–ÀÍZÇX·”¬®®NÞÿýIe¹Äûá˜n«ÔgFŒnîQ¡ üué9 #-WRgQLÎ�;7ùž÷¼'ù–·¼%)Ó-)c*s¿–Å€ºD�1Mƒ~£ôÒÒ)#ºÌftºë¨åÙ000000�aJ`Œ¶ëÍÒW¥™ß—>/ýŠDfBBÊ× Ôçy©Kêk»C·Jª–òyœÚüad¶|R:"%•Ñ’TVPRg•Œ÷Ç>ÝþsR±”Ï1Nÿn‰ AŒÛx|I•x&Uê (•å%•Ù“¹OËQ>6]ÍÁk÷Idƒñ´Nª•z¤l^Ù×�ê>Ž�Éa&`&`&`&`&`&`„Àûô¬»¥ì +×1<þFš+Qbé8¿.×ꟕ‚)““ýÃþ¹_)ûa’Æò'¥`½2yjjj’wÝuWrÊ”)¹ÔiÙÑn@ A¯À¿Tš'½Wú´ô/ÒW¥•þ·Dé^¾›–‚ÃLÀLÀLÀLÀLÀL Ÿ üOm|¶ùD¦e„4Av¶„ a¼CϵCÊ5÷ê¶×K#Å|ÒPB\¡ÿ1Iê¥Ì˜ÉøŠ3¿rL¸¯i9—} ‚ÃLÀLÀLÀLÀLÀLÀò‰“ùÏK‹¤/J¯•òµ·�6=¯³ï3R(¿ÓelÈìÓuzÿŒÔ ÊÂKR<æP~˜ýwúúßë2{«i³&`&`&`&`&`&`&0º �US0º ‹Ñc¬ü­D“ñ؈¡Ù;åS#yÿPŠG™Ø~i FT‘*%‡ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜ÀYÀXù�„éDI$ý‘.–FCܪAþPj•bó-÷ò„îãìy¥’ÃLÀLÀLÀLÀLÀLÀLÀLà, P9M©åvýa¡ìó]Ò*©×YñôwlDÑë.i¤õÁÒ�&`&`&`&`&`&`&`&`CA`²žä ×û*Å{N·Ï–Fr9¢†ç000000008ŸnÖÊ,µIqæ—Rô‰+9LÀLÀLÀLÀLÀLÀLÀLÀLଠTè‘”â=-µK± µ^׫%‡ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ¼j˜P“ŽKPß’8SžÃL`p�í(ØÉ¢ ˜€ ˜€ ˜€ ˜€ ˜€ Ì?çK4c'ê°„å00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000�áOàÿ¤DÝO�˜sæIEND®B`‚math-comp-hierarchy-builder-4d8a939/examples/000077500000000000000000000000001521677141400211745ustar00rootroot00000000000000math-comp-hierarchy-builder-4d8a939/examples/GReTA_talk/000077500000000000000000000000001521677141400231115ustar00rootroot00000000000000math-comp-hierarchy-builder-4d8a939/examples/GReTA_talk/V1.v000066400000000000000000000007621521677141400235730ustar00rootroot00000000000000Require Import ZArith ssreflect ssrfun. From HB Require Import structures. HB.mixin Record is_monoid (M : Type) := { zero : M; add : M -> M -> M; addrA : associative add; (* add is associative. *) add0r : forall x, add zero x = x; (* zero is neutral *) addr0 : forall x, add x zero = x; (* wrt add. *) }. HB.structure Definition Monoid := { M of is_monoid M }. HB.instance Definition Z_is_monoid : is_monoid Z := is_monoid.Build Z 0%Z Z.add Z.add_assoc Z.add_0_l Z.add_0_r.math-comp-hierarchy-builder-4d8a939/examples/GReTA_talk/V2.v000066400000000000000000000012641521677141400235720ustar00rootroot00000000000000Require Import ZArith ssreflect ssrfun. From HB Require Import structures. HB.mixin Record is_semigroup (S : Type) := { add : S -> S -> S; addrA : associative add; }. HB.structure Definition SemiGroup := { S of is_semigroup S }. HB.mixin Record semigroup_is_monoid M & is_semigroup M := { zero : M; add0r : forall x, add zero x = x; addr0 : forall x, add x zero = x; }. HB.structure Definition Monoid := { M of is_semigroup M & semigroup_is_monoid M }. (* is_monoid does not exist anymore *) Fail Check is_monoid. HB.instance Definition Z_is_monoid : is_monoid Z := is_monoid.Build Z 0%Z Z.add Z.add_assoc Z.add_0_l Z.add_0_r. HB.mixin Record xxxx P A := { F : bool }. math-comp-hierarchy-builder-4d8a939/examples/GReTA_talk/V3.v000066400000000000000000000017401521677141400235720ustar00rootroot00000000000000Require Import ZArith ssreflect ssrfun. From HB Require Import structures. HB.mixin Record is_semigroup (S : Type) := { add : S -> S -> S; addrA : associative add; }. HB.structure Definition SemiGroup := { S & is_semigroup S }. HB.mixin Record semigroup_is_monoid M & is_semigroup M := { zero : M; add0r : forall x, add zero x = x; addr0 : forall x, add x zero = x; }. HB.factory Record is_monoid (M : Type) := { zero : M; add : M -> M -> M; addrA : associative add; add0r : forall x, add zero x = x; addr0 : forall x, add x zero = x; }. HB.builders Context (M : Type) (f : is_monoid M). HB.instance Definition _ : is_semigroup M := is_semigroup.Build M add addrA. HB.instance Definition _ : semigroup_is_monoid M := semigroup_is_monoid.Build M zero add0r addr0. HB.end. HB.structure Definition Monoid := { M & is_monoid M }. HB.instance Definition Z_is_monoid : is_monoid Z := is_monoid.Build Z 0%Z Z.add Z.add_assoc Z.add_0_l Z.add_0_r. math-comp-hierarchy-builder-4d8a939/examples/GReTA_talk/V4.v000066400000000000000000000032751521677141400236000ustar00rootroot00000000000000Require Import ZArith ssreflect ssrfun. From HB Require Import structures. HB.mixin Record is_semigroup (S : Type) := { add : S -> S -> S; addrA : associative add; }. HB.structure Definition SemiGroup := { S & is_semigroup S }. HB.mixin Record semigroup_is_monoid M & is_semigroup M := { zero : M; add0r : forall x, add zero x = x; addr0 : forall x, add x zero = x; }. HB.factory Record is_monoid M := { zero : M; add : M -> M -> M; addrA : associative add; add0r : forall x, add zero x = x; addr0 : forall x, add x zero = x; }. HB.builders Context (M : Type) & is_monoid M. HB.instance Definition _ := is_semigroup.Build M add addrA. HB.instance Definition _ := semigroup_is_monoid.Build M zero add0r addr0. HB.end. HB.structure Definition Monoid := { M & is_monoid M }. HB.mixin Record monoid_is_group G & is_monoid G := { opp : G -> G; subrr : forall x, add x (opp x) = zero; addNr : forall x, add (opp x) x = zero; }. HB.factory Record is_group G := { zero : G; add : G -> G -> G; opp : G -> G; addrA : associative add; add0r : forall x, add zero x = x; (* addr0 : forall x, add x zero = x; (* spurious *) *) subrr : forall x, add x (opp x) = zero; addNr : forall x, add (opp x) x = zero; }. HB.builders Context G & is_group G. Let addr0 : forall x, add x zero = x. Proof. by move=> x; rewrite -(addNr x) addrA subrr add0r. Qed. HB.instance Definition _ := is_monoid.Build G zero add addrA add0r addr0. HB.instance Definition _ := monoid_is_group.Build G opp subrr addNr. HB.end. HB.instance Definition Z_is_group : is_group Z := is_group.Build Z 0%Z Z.add Z.opp Z.add_assoc Z.add_0_l (* Z.add_0_r (*spurious *) *) Z.sub_diag Z.add_opp_diag_l. math-comp-hierarchy-builder-4d8a939/examples/cat/000077500000000000000000000000001521677141400217435ustar00rootroot00000000000000math-comp-hierarchy-builder-4d8a939/examples/cat/cat.v000066400000000000000000001157601521677141400227130ustar00rootroot00000000000000Require Import ssreflect ssrfun. From HB Require Import structures. Set Implicit Arguments. Unset Strict Implicit. Unset Printing Implicit Defensive. Add Search Blacklist "__canonical__". Declare Scope algebra_scope. Delimit Scope algebra_scope with A. Local Open Scope algebra_scope. Declare Scope cat_scope. Delimit Scope cat_scope with cat. Local Open Scope cat_scope. (* we assume a few axioms to make life easier *) Axiom funext : forall {T : Type} {U : T -> Type} [f g : forall t, U t], (forall t, f t = g t) -> f = g. Axiom propext : forall P Q : Prop, P <-> Q -> P = Q. Axiom Prop_irrelevance : forall (P : Prop) (x y : P), x = y. (* Shortcut *) Notation U := Type. (* Base definition : raw categories = quivers *) HB.mixin Record IsQuiver C := { hom : C -> C -> U }. Unset Universe Checking. #[short(type="quiver")] HB.structure Definition Quiver : Set := { C of IsQuiver C }. Set Universe Checking. Bind Scope cat_scope with quiver. Bind Scope cat_scope with hom. Arguments hom {C} : rename. Notation homs T := (@hom T _ _). Notation "a ~> b" := (hom a b) (at level 99, b at level 200, format "a ~> b") : cat_scope. Notation "a ~>_ C b" := (@hom C a b) (at level 99, C at level 0, only parsing) : cat_scope. (* precategories are quivers + id and comp *) HB.mixin Record Quiver_IsPreCat C & Quiver C := { idmap : forall (a : C), a ~> a; comp : forall (a b c : C), (a ~> b) -> (b ~> c) -> (a ~> c); }. HB.factory Record IsPreCat C := { hom : C -> C -> U; idmap : forall (a : C), hom a a; comp : forall (a b c : C), hom a b -> hom b c -> hom a c; }. HB.builders Context C & IsPreCat C. HB.instance Definition _ := IsQuiver.Build C hom. HB.instance Definition _ := Quiver_IsPreCat.Build C idmap comp. HB.end. Unset Universe Checking. #[short(type="precat")] HB.structure Definition PreCat : Set := { C of IsPreCat C }. Set Universe Checking. Bind Scope cat_scope with precat. Arguments idmap {C} {a} : rename. Arguments comp {C} {a b c} : rename. Notation "f \o g" := (comp g f) : cat_scope. Notation "f \; g :> T" := (@comp T _ _ _ f g) (at level 60, g, T at level 60, format "f \; g :> T", only parsing) : cat_scope. Notation "f \; g" := (comp f g) : cat_scope. Notation "\idmap_ a" := (@idmap _ a) (only parsing, at level 0) : cat_scope. (* categories are precategories + laws *) HB.mixin Record PreCat_IsCat C & PreCat C := { comp1o : forall (a b : C) (f : a ~> b), idmap \; f = f; compo1 : forall (a b : C) (f : a ~> b), f \; idmap = f; compoA : forall (a b c d : C) (f : a ~> b) (g : b ~> c) (h : c ~> d), f \; (g \; h) = (f \; g) \; h }. Unset Universe Checking. #[short(type="cat")] HB.structure Definition Cat : Set := { C of PreCat_IsCat C & IsPreCat C }. Set Universe Checking. Bind Scope cat_scope with cat. Arguments compo1 {C a b} : rename. Arguments comp1o {C a b} : rename. Arguments compoA {C a b c d} : rename. (* the discrete category on a type cannot be the default, we make an alias *) Definition discrete (T : U) := T. HB.instance Definition _ T := @IsPreCat.Build (discrete T) (fun x y => x = y) (fun=> erefl) (@etrans _). Lemma etransA T (a b c d : discrete T) (f : a ~> b) (g : b ~> c) (h : c ~> d) : f \; (g \; h) = (f \; g) \; h. Proof. by rewrite /idmap/comp/=; case: _ / h; case: _ / g. Qed. HB.instance Definition _ T := PreCat_IsCat.Build (discrete T) (@etrans_id _) (fun _ _ _ => erefl) (@etransA _). (* the category of the unit type is the discrete one *) HB.instance Definition _ := Cat.copy unit (discrete unit). HB.instance Definition _ := @IsPreCat.Build U (fun A B => A -> B) (fun a => idfun) (fun a b c (f : a -> b) (g : b -> c) => (g \o f)%function). HB.instance Definition _ := PreCat_IsCat.Build U (fun _ _ _ => erefl) (fun _ _ _ => erefl) (fun _ _ _ _ _ _ _ => erefl). Lemma Ucomp (X Y Z : U) (f : X ~> Y) (g : Y ~> Z) : f \; g = (g \o f)%function. Proof. by []. Qed. Lemma Ucompx (X Y Z : U) (f : X ~> Y) (g : Y ~> Z) x : (f \; g) x = g (f x). Proof. by []. Qed. Lemma U1 (X : U) : \idmap_X = idfun. Proof. by []. Qed. Lemma U1x (X : U) x : \idmap_X x = x. Proof. by []. Qed. (* a prefunctor is a functor without laws *) HB.mixin Record IsPreFunctor (C D : quiver) (F : C -> D) := { Fhom : forall (a b : C), (a ~> b) -> (F a ~> F b) }. Unset Universe Checking. HB.structure Definition PreFunctor (C D : quiver) : Set := { F of IsPreFunctor C D F }. Set Universe Checking. HB.instance Definition _ := IsQuiver.Build quiver PreFunctor.type. Notation "F ^$" := (@Fhom _ _ F _ _) (at level 1, format "F ^$") : cat_scope. Notation "F <$> f" := (@Fhom _ _ F _ _ f) (at level 58, format "F <$> f", right associativity) : cat_scope. (* prefunctors are equal if their object and hom part are respectively equal *) Lemma prefunctorP (C D : quiver) (F G : C ~> D) (eqFG : F =1 G) : let homF a b F := F a ~> F b in (forall a b f, eq_rect _ (homF a b) (F <$> f) _ (funext eqFG) = G <$> f) -> F = G. Proof. move: F G => [F [[/= Fhom]]] [G [[/= Ghom]]] in eqFG *. case: _ / (funext eqFG) => /= in Ghom * => eqFGhom. congr PreFunctor.Pack; congr PreFunctor.Class; congr IsPreFunctor.Axioms_. by do 3!apply: funext=> ?. Qed. (* a functor is a prefunctor + laws for id and comp *) HB.mixin Record PreFunctor_IsFunctor (C D : precat) (F : C -> D) & @PreFunctor C D F := { F1 : forall (a : C), F <$> \idmap_a = idmap; Fcomp : forall (a b c : C) (f : a ~> b) (g : b ~> c), F <$> (f \; g) = F <$> f \; F <$> g; }. Unset Universe Checking. (* precat and cat have a quiver structure *) HB.structure Definition Functor (C D : precat) : Set := { F of IsPreFunctor C D F & PreFunctor_IsFunctor C D F }. Set Universe Checking. HB.instance Definition _ := IsQuiver.Build precat Functor.type. HB.instance Definition _ := IsQuiver.Build cat Functor.type. (* functor equality is the same as prefunctor because of PI *) Lemma functorP (C D : precat) (F G : C ~> D) (eqFG : F =1 G) : let homF a b F := F a ~> F b in (forall a b f, eq_rect _ (homF a b) (F^$ f) _ (funext eqFG) = G^$ f) -> F = G. Proof. move=> /= /prefunctorP {eqFG}. case: F G => [F [/= Fm Fm']] [G [/= Gm Gm']]//=. move=> [_] eqFG; have /= := eq_sigT_rect_existT _ _ eqFG; apply => {}eqFG. case: _ / eqFG => /= in Gm Gm' * => eqFG. case: _ / eqFG in Gm' *. congr Functor.Pack; congr Functor.Class. case: Fm' Gm' => [F1 Fc] [G1 Gc]. by congr PreFunctor_IsFunctor.Axioms_; apply: Prop_irrelevance. Qed. (* the identity function is a functor *) HB.instance Definition _ (C : quiver) := IsPreFunctor.Build C C idfun (fun a b => idfun). HB.instance Definition _ (C : precat) := PreFunctor_IsFunctor.Build C C idfun (fun=> erefl) (fun _ _ _ _ _ => erefl). (* the composition of prefunctors *) Section comp_prefunctor. Context {C D E : quiver} {F : C ~> D} {G : D ~> E}. HB.instance Definition _ := IsPreFunctor.Build C E (G \o F)%function (fun a b f => G <$> F <$> f). Lemma comp_Fun (a b : C) (f : a ~> b) : (G \o F)%function <$> f = G <$> (F <$> f). Proof. by []. Qed. End comp_prefunctor. Section comp_functor. Context {C D E : precat} {F : C ~> D} {G : D ~> E}. Lemma comp_F1 (a : C) : (G \o F)%function <$> \idmap_a = idmap. Proof. by rewrite !comp_Fun !F1. Qed. Lemma comp_Fcomp (a b c : C) (f : a ~> b) (g : b ~> c) : (G \o F)%function <$> (f \; g) = (G \o F)%function <$> f \; (G \o F)%function <$> g. Proof. by rewrite !comp_Fun !Fcomp. Qed. HB.instance Definition _ := PreFunctor_IsFunctor.Build C E (G \o F)%function comp_F1 comp_Fcomp. End comp_functor. (* precat and cat have a precategory structure *) HB.instance Definition _ := Quiver_IsPreCat.Build precat (fun=> idfun) (fun C D E (F : C ~> D) (G : D ~> E) => (G \o F)%function). HB.instance Definition _ := Quiver_IsPreCat.Build cat (fun=> idfun) (fun C D E (F : C ~> D) (G : D ~> E) => (G \o F)%function). Lemma funext_frefl A B (f : A -> B) : funext (frefl f) = erefl. Proof. exact: Prop_irrelevance. Qed. (* precategories and categories form a category *) Definition precat_cat : PreCat_IsCat precat. Proof. by split=> [C D F|C D F|C D C' D' F G H]; apply/functorP => a b f /=; rewrite funext_frefl. Qed. HB.instance Definition _ := precat_cat. Definition cat_cat : PreCat_IsCat cat. Proof. by split=> [C D F|C D F|C D C' D' F G H]; apply/functorP => a b f /=; rewrite funext_frefl. Qed. HB.instance Definition _ := cat_cat. Check (cat : cat). (* concrete categories *) HB.mixin Record Quiver_IsPreConcrete T & Quiver T := { concrete : T -> U; concrete_fun : forall (a b : T), (a ~> b) -> concrete a -> concrete b; }. Unset Universe Checking. #[short(type="preconcrete_quiver")] HB.structure Definition PreConcreteQuiver : Set := { C of Quiver_IsPreConcrete C & IsQuiver C }. Set Universe Checking. Coercion concrete : PreConcreteQuiver.sort >-> Sortclass. HB.mixin Record PreConcrete_IsConcrete T & PreConcreteQuiver T := { concrete_fun_inj : forall (a b : T), injective (concrete_fun a b) }. Unset Universe Checking. #[short(type="concrete_quiver")] HB.structure Definition ConcreteQuiver : Set := { C of PreConcreteQuiver C & PreConcrete_IsConcrete C }. Set Universe Checking. HB.instance Definition _ (C : ConcreteQuiver.type) := IsPreFunctor.Build _ _ (concrete : C -> U) concrete_fun. HB.mixin Record PreCat_IsConcrete T & ConcreteQuiver T & PreCat T := { concrete1 : forall (a : T), concrete <$> \idmap_a = idfun; concrete_comp : forall (a b c : T) (f : a ~> b) (g : b ~> c), concrete <$> (f \; g) = ((concrete <$> g) \o (concrete <$> f))%function; }. Unset Universe Checking. #[short(type="concrete_precat")] HB.structure Definition ConcretePreCat : Set := { C of PreCat C & ConcreteQuiver C & PreCat_IsConcrete C }. #[short(type="concrete_cat")] HB.structure Definition ConcreteCat : Set := { C of Cat C & ConcreteQuiver C & PreCat_IsConcrete C }. Set Universe Checking. HB.instance Definition _ (C : concrete_precat) := PreFunctor_IsFunctor.Build C U concrete (@concrete1 _) (@concrete_comp _). HB.instance Definition _ (C : ConcreteCat.type) := PreFunctor_IsFunctor.Build C U concrete (@concrete1 _) (@concrete_comp _). HB.instance Definition _ := Quiver_IsPreConcrete.Build U (fun _ _ => id). HB.instance Definition _ := PreConcrete_IsConcrete.Build U (fun _ _ _ _ => id). HB.instance Definition _ := PreCat_IsConcrete.Build U (fun=> erefl) (fun _ _ _ _ _ => erefl). Unset Universe Checking. HB.instance Definition _ := Quiver_IsPreConcrete.Build quiver (fun _ _ => id). HB.instance Definition _ := Quiver_IsPreConcrete.Build precat (fun _ _ => id). HB.instance Definition _ := Quiver_IsPreConcrete.Build cat (fun _ _ => id). Set Universe Checking. Lemma quiver_concrete_subproof : PreConcrete_IsConcrete quiver. Proof. constructor=> C D F G FG; apply: prefunctorP. by move=> x; congr (_ x); apply: FG. by move=> *; admit. Admitted. HB.instance Definition _ := quiver_concrete_subproof. Lemma precat_concrete_subproof : PreConcrete_IsConcrete precat. Proof. constructor=> C D F G FG; apply: functorP. by move=> x; congr (_ x); apply: FG. by move=> *; admit. Admitted. HB.instance Definition _ := precat_concrete_subproof. Lemma cat_concrete_subproof : PreConcrete_IsConcrete cat. Proof. constructor=> C D F G FG; apply: functorP. by move=> x; congr (_ x); apply: FG. by move=> *; admit. Admitted. HB.instance Definition _ := cat_concrete_subproof. HB.instance Definition _ := PreCat_IsConcrete.Build precat (fun=> erefl) (fun _ _ _ _ _ => erefl). HB.instance Definition _ := PreCat_IsConcrete.Build cat (fun=> erefl) (fun _ _ _ _ _ => erefl). (* constant functor *) Definition cst (C D : quiver) (c : C) := fun & D => c. Arguments cst {C} D c. HB.instance Definition _ {C D : precat} (c : C) := IsPreFunctor.Build D C (cst D c) (fun _ _ _ => idmap). HB.instance Definition _ {C D : cat} (c : C) := PreFunctor_IsFunctor.Build D C (cst D c) (fun=> erefl) (fun _ _ _ _ _ => esym (compo1 idmap)). (* opposite category *) Definition catop (C : U) : U := C. Notation "C ^op" := (catop C) (at level 2, format "C ^op") : cat_scope. HB.instance Definition _ (C : quiver) := IsQuiver.Build C^op (fun a b => hom b a). HB.instance Definition _ (C : precat) := Quiver_IsPreCat.Build (C^op) (fun=> idmap) (fun _ _ _ f g => g \; f). HB.instance Definition _ (C : cat) := PreCat_IsCat.Build (C^op) (fun _ _ _ => compo1 _) (fun _ _ _ => comp1o _) (fun _ _ _ _ _ _ _ => esym (compoA _ _ _)). HB.instance Definition _ {C : precat} {c : C} := IsPreFunctor.Build C _ (hom c) (fun a b f g => g \; f). Lemma hom_Fhom_subproof (C : cat) (x : C) : PreFunctor_IsFunctor _ _ (hom x). Proof. by split=> *; apply/funext => h; [apply: compo1 | apply: compoA]. Qed. HB.instance Definition _ {C : cat} {c : C} := hom_Fhom_subproof c. Check fun (C : cat) (x : C) => hom x : C ~>_cat U. Lemma hom_op {C : quiver} (c : C^op) : hom c = (@hom C)^~ c. Proof. reflexivity. Qed. Lemma homFhomx {C : precat} (a b c : C) (f : a ~> b) (g : c ~> a) : (hom c <$> f) g = g \; f. Proof. reflexivity. Qed. (* nary product of categories *) Definition dprod {I : U} (C : I -> U) := forall i, C i. Section hom_dprod. Context {I : U} (C : I -> quiver). Definition dprod_hom_subdef (a b : dprod C) := forall i, a i ~> b i. HB.instance Definition _ := IsQuiver.Build (dprod C) dprod_hom_subdef. End hom_dprod. Arguments dprod_hom_subdef /. Section precat_dprod. Context {I : U} (C : I -> precat). Definition dprod_idmap_subdef (a : dprod C) : a ~> a := fun=> idmap. Definition dprod_comp_subdef (a b c : dprod C) (f : a ~> b) (g : b ~> c) : a ~> c := fun i => f i \; g i. HB.instance Definition _ := IsPreCat.Build (dprod C) dprod_idmap_subdef dprod_comp_subdef. End precat_dprod. Arguments dprod_idmap_subdef /. Arguments dprod_comp_subdef /. Section cat_dprod. Context {I : U} (C : I -> cat). Local Notation type := (dprod C). Lemma dprod_is_cat : PreCat_IsCat type. Proof. split=> [a b f|a b f|a b c d f g h]; apply/funext => i; [exact: comp1o | exact: compo1 | exact: compoA]. Qed. HB.instance Definition _ := dprod_is_cat. End cat_dprod. (* binary product *) Section hom_prod. Context {C D : quiver}. Definition prod_hom_subdef (a b : C * D) := ((a.1 ~> b.1) * (a.2 ~> b.2))%type. HB.instance Definition _ := IsQuiver.Build (C * D)%type prod_hom_subdef. End hom_prod. Section precat_prod. Context {C D : precat}. HB.instance Definition _ := IsPreCat.Build (C * D)%type (fun=> (idmap, idmap)) (fun a b c (f : a ~> b) (g : b ~> c) => (f.1 \; g.1, f.2 \; g.2)). End precat_prod. Section cat_prod. Context {C D : cat}. Local Notation type := (C * D)%type. Lemma prod_is_cat : PreCat_IsCat type. Proof. split=> [[a1 a2] [b1 b2] [f1 f2]|[a1 a2] [b1 b2] [f1 f2]| [a1 a2] [b1 b2] [c1 c2] [d1 d2] [f1 f2] [g1 g2] [h1 h2]]; congr (_, _) => //=; by [exact: comp1o | exact: compo1 | exact: compoA]. Qed. HB.instance Definition _ := prod_is_cat. End cat_prod. HB.instance Definition _ (C : U) (D : quiver) := IsQuiver.Build (C -> D) (fun f g => forall c, f c ~> g c). (* naturality *) HB.mixin Record IsNatural (C : quiver) (D : precat) (F G : C ~>_quiver D) (n : forall c, F c ~> G c) := { natural : forall (a b : C) (f : a ~> b), F <$> f \; n b = n a \; G <$> f }. Unset Universe Checking. HB.structure Definition Natural (C : quiver) (D : precat) (F G : C ~>_quiver D) : Set := { n of @IsNatural C D F G n }. Set Universe Checking. HB.instance Definition _ (C : quiver) (D : precat) := IsQuiver.Build (PreFunctor.type C D) (@Natural.type C D). HB.instance Definition _ (C D : precat) := IsQuiver.Build (Functor.type C D) (@Natural.type C D). Arguments natural {C D F G} n [a b] f : rename. Check fun (C D : cat) (F G : C ~> D) => F ~>_(C ~>_cat D) G. Lemma naturalx (C : precat) (D : concrete_precat) (F G : C ~>_quiver D) (n : F ~> G) (a b : C) (f : a ~> b) g : (concrete <$> n b) ((concrete <$> F <$> f) g) = (concrete <$> G <$> f) ((concrete <$> n a) g). Proof. have /(congr1 (fun h => (concrete <$> h) g)) := natural n f. by rewrite !Fcomp. Qed. Arguments naturalx {C D F G} n [a b] f. Lemma naturalU (C : precat) (F G : C ~>_quiver U) (n : F ~> G) (a b : C) (f : a ~> b) g : n b (F^$ f g) = G^$ f (n a g). Proof. exact: (naturalx n). Qed. Lemma natP (C D : precat) (F G : C ~>_quiver D) (n m : F ~> G) : Natural.sort n = Natural.sort m -> n = m. Proof. case: n m => [/= n nP] [/= m mP] enm. elim: _ / enm in mP *; congr Natural.Pack. case: nP mP => [[?]] [[?]]; congr Natural.Class. congr IsNatural.Axioms_. exact: Prop_irrelevance. Qed. Notation "F ~~> G" := (F ~>_(homs quiver) G) (at level 99, G at level 200, format "F ~~> G"). Notation "F ~~> G :> C ~> D" := (F ~> G :> (C ~>_quiver D)) (at level 99, G at level 200, C, D at level 0, format "F ~~> G :> C ~> D"). Definition natural_id {C D : precat} (F : C ~>_quiver D) (a : C) := \idmap_(F a). Definition natural_id_natural (C D : cat) (F : C ~>_quiver D) : IsNatural C D F F (natural_id F). Proof. by constructor=> a b f; rewrite /natural_id/= compo1 comp1o. Qed. HB.instance Definition _ C D F := @natural_id_natural C D F. Check fun {C D : cat} (F : C ~>_quiver D) => natural_id F : F ~> F. Definition natural_comp {C D : precat} (F G H : C ~>_quiver D) (m : F ~> G) (n : G ~> H) (a : C) := m a \; n a. Definition natural_comp_natural (C D : cat) (F G H : C ~>_quiver D) m n : IsNatural C D F H (@natural_comp C D F G H m n). Proof. constructor=> a b f; rewrite /natural_comp/=. by rewrite compoA natural -compoA natural compoA. Qed. HB.instance Definition _ C D F G H m n := @natural_comp_natural C D F G H m n. HB.instance Definition _ {C D : cat} := Quiver_IsPreCat.Build (PreFunctor.type C D) natural_id natural_comp. HB.instance Definition _ {C D : cat} := Quiver_IsPreCat.Build (Functor.type C D) natural_id natural_comp. Lemma prefunctor_cat {C D : cat} : PreCat_IsCat (PreFunctor.type C D). Proof. constructor => [F G f|F G f|F G H J f g h]. - by apply/natP/funext => a; rewrite /= /natural_comp comp1o. - by apply/natP/funext => a; rewrite /= /natural_comp compo1. - by apply/natP/funext => a; rewrite /= /natural_comp compoA. Qed. HB.instance Definition _ C D := @prefunctor_cat C D. Lemma functor_cat {C D : cat} : PreCat_IsCat (Functor.type C D). Proof. constructor => [F G f|F G f|F G H J f g h]. - by apply/natP/funext => a; rewrite /= /natural_comp comp1o. - by apply/natP/funext => a; rewrite /= /natural_comp compo1. - by apply/natP/funext => a; rewrite /= /natural_comp compoA. Qed. HB.instance Definition _ C D := @functor_cat C D. Lemma idFmap (C : cat) (a b : C) (f : a ~> b) : idfun <$> f = f. Proof. by []. Qed. Lemma compFmap (C D E : cat) (F : C ~> D) (G : D ~> E) (a b : C) (f : a ~> b) : (G \o F) <$> f = G <$> F <$> f. Proof. by []. Qed. Section left_whiskering. Context {C D E : precat} {F G : C ~> D}. Definition whiskerl_fun (eta : forall c, F c ~> G c) (H : D ~> E) : forall c, (F \; H) c ~> (G \; H) c := fun c => H <$> eta c. Lemma whiskerl_is_nat (eta : F ~> G) (H : D ~> E) : IsNatural _ _ _ _ (whiskerl_fun eta H). Proof. by constructor=> a b f; rewrite /whiskerl_fun/= -!Fcomp natural. Qed. HB.instance Definition _ (eta : F ~> G) (H : D ~> E) := whiskerl_is_nat eta H. Definition whiskerl (eta : F ~> G) (H : D ~> E) : (F \; H) ~> (G \; H) := whiskerl_fun eta H : Natural.type _ _. End left_whiskering. Notation "F n" := (whiskerl F n) (at level 58, format "F n", right associativity) : cat_scope. Section right_whiskering. Context {C D E : precat} {F G : D ~> E}. Definition whiskerr_fun (H : C ~> D) (eta : forall d, F d ~> G d) (c : C) : (H \; F) c ~> (H \; G) c := eta (H c). Lemma whiskerr_is_nat (H : C ~> D) (eta : F ~> G) : IsNatural _ _ _ _ (whiskerr_fun H eta). Proof. by constructor=> a b f; rewrite /whiskerr_fun/= natural. Qed. HB.instance Definition _ (H : C ~> D) (eta : F ~> G) := whiskerr_is_nat H eta. Definition whiskerr (H : C ~> D) (eta : F ~> G) : (H \; F) ~> (H \; G) := whiskerr_fun H eta : Natural.type _ _. End right_whiskering. Notation "F <$o> n" := (whiskerr F n) (at level 58, format "F <$o> n", right associativity) : cat_scope. Definition whisker {C : cat} {D : precat} {E : cat} {F G : C ~>_precat D} {H K : D ~> E} (eta : F ~> G) (mu : H ~> K) : (F \; H) ~> (G \; K) := (eta H) \; (G <$o> mu). Notation "eta mu" := (whisker eta mu) (at level 58, format "eta mu", right associativity) : cat_scope. Lemma whiskern1 {C D E : cat} {F G : C ~>_precat D} (eta : F ~> G) (H : D ~> E) : eta \idmap_H = eta H. Proof. by apply/natP/funext=> c /=; apply: compo1. Qed. Lemma whisker1n {C D E : cat} {F G : D ~> E} (H : C ~> D) (eta : F ~> G) : \idmap_H eta = H <$o> eta. Proof. apply/natP/funext=> c /=; rewrite /natural_comp/=. by rewrite [X in X \; _]F1 comp1o. Qed. Definition delta (C D : cat) : C -> (D ~> C) := cst D. Arguments delta C D : clear implicits. Definition map_delta {C D : cat} (a b : C) (f : a ~> b) : delta C D a ~> delta C D b. Proof. apply: (@Natural.Pack _ _ (cst D a) (cst D b) (fun x => f)). apply: Natural.Class; apply: (IsNatural.Build _ _ _ _ _). by move=> a' b' ?; rewrite compo1 comp1o. Defined. HB.instance Definition _ {C D : cat} := IsPreFunctor.Build C (D ~> C) (delta C D) (@map_delta C D). Lemma delta_functor {C D : cat} : PreFunctor_IsFunctor _ _ (delta C D). Proof. by constructor=> [a|a b c f g]; exact/natP. Qed. HB.instance Definition _ C D := @delta_functor C D. HB.mixin Record IsMonad (C : precat) (M : C -> C) & @PreFunctor C C M := { unit : idfun ~~> M; join : (M \o M)%function ~~> M; bind : forall (a b : C), (a ~> M b) -> (M a ~> M b); bindE : forall a b (f : a ~> M b), bind a b f = M <$> f \; join b; unit_join : forall a, (M <$> unit a) \; join _ = idmap; join_unit : forall a, join _ \; (M <$> unit a) = idmap; join_square : forall a, M <$> join a \; join _ = join _ \; join _ }. #[short(type="premonad")] HB.structure Definition PreMonad (C : precat) := {M of @PreFunctor C C M & IsMonad C M}. #[short(type="monad")] HB.structure Definition Monad (C : precat) := {M of @Functor C C M & IsMonad C M}. HB.factory Record IsJoinMonad (C : precat) (M : C -> C) & @PreFunctor C C M := { unit : idfun ~~> M; join : (M \o M)%function ~~> M; unit_join : forall a, (M <$> unit a) \; join _ = idmap; join_unit : forall a, join _ \; (M <$> unit a) = idmap; join_square : forall a, M <$> join a \; join _ = join _ \; join _ }. HB.builders Context C M & IsJoinMonad C M. HB.instance Definition _ := IsMonad.Build C M (fun a b f => erefl) unit_join join_unit join_square. HB.end. HB.mixin Record IsCoMonad (C : precat) (M : C -> C) & @IsPreFunctor C C M := { counit : M ~~> idfun; cojoin : M ~~> (M \o M)%function; cobind : forall (a b : C), (M a ~> b) -> (M a ~> M b); cobindE : forall a b (f : M a ~> b), cobind a b f = cojoin _ \; M <$> f; unit_cojoin : forall a, (M <$> counit a) \; cojoin _ = idmap; join_counit : forall a, cojoin _ \; (M <$> counit a) = idmap; cojoin_square : forall a, cojoin _ \; M <$> cojoin a = cojoin _ \; cojoin _ }. #[short(type="precomonad")] HB.structure Definition PreCoMonad (C : precat) := {M of @PreFunctor C C M & IsCoMonad C M}. #[short(type="comonad")] HB.structure Definition CoMonad (C : precat) := {M of @Functor C C M & IsCoMonad C M}. HB.factory Record IsJoinCoMonad (C : precat) (M : C -> C) & @IsPreFunctor C C M := { counit : M ~~> idfun; cojoin : M ~~> (M \o M)%function; unit_cojoin : forall a, (M <$> counit a) \; cojoin _ = idmap; join_counit : forall a, cojoin _ \; (M <$> counit a) = idmap; cojoin_square : forall a, cojoin _ \; M <$> cojoin a = cojoin _ \; cojoin _ }. HB.builders Context C M & IsJoinCoMonad C M. HB.instance Definition _ := IsCoMonad.Build C M (fun a b f => erefl) unit_cojoin join_counit cojoin_square. HB.end. (* yoneda *) Section hom_repr. Context {C : cat} (F : C ~>_cat U). Definition homF : C -> U := fun c => hom c ~~> F. Section nat. Context (x y : C) (xy : x ~> y). (* Goal hom x ~~> F -> hom y ~~> F *) Context (n : hom x ~~> F). Definition homFhom c : hom y c ~> F c := fun g => n _ (xy \; g). Lemma homFhom_natural_subdef : IsNatural C U (hom y) F homFhom. Proof. by split=> a b f /=; apply/funext => g /=; rewrite /homFhom !Ucompx/= !naturalU/= Fcomp. Qed. HB.instance Definition _ := homFhom_natural_subdef. End nat. Arguments homFhom / : clear implicits. Check homFhom : forall x y : C, (x ~> y) -> (homF x -> homF y). HB.instance Definition _ := IsPreFunctor.Build _ _ homF homFhom. Lemma homF_functor_subproof : PreFunctor_IsFunctor _ _ homF. Proof. split=> [a|a b c f g]. apply/funext => -[/= f natf]. apply: natP => //=; apply: funext => b; apply: funext => g/=. by rewrite comp1o. apply/funext => -[/= h natf]. apply: natP => //=; apply: funext => d; apply: funext => k/=. by rewrite compoA. Qed. HB.instance Definition _ := homF_functor_subproof. Section pointed. Context (c : C). Definition hom_repr : homF c ~> F c := fun f => f _ idmap. Arguments hom_repr /. Definition repr_hom (fc : F c) a : hom c a ~> F a := fun f => F^$ f fc. Arguments repr_hom / : clear implicits. Lemma repr_hom_subdef (fc : F c) : IsNatural _ _ _ _ (repr_hom fc). Proof. by split=> a b f /=; apply/funext=> x; rewrite !Ucompx/= Fcomp. Qed. HB.instance Definition _ {fc : F c} := repr_hom_subdef fc. Definition repr_hom_nat : F c ~> homF c := repr_hom. Lemma hom_reprK : cancel hom_repr repr_hom_nat. Proof. move=> f; apply/natP; apply/funext => a; apply/funext => g /=. by rewrite -naturalU/=; congr (f _ _); apply: comp1o. Qed. Lemma repr_homK : cancel (repr_hom : F c ~> homF c) hom_repr. Proof. by move=> fc; rewrite /= F1. Qed. End pointed. Arguments hom_repr /. Arguments repr_hom /. Lemma hom_repr_natural_subproof : IsNatural _ _ _ _ hom_repr. Proof. split=> a b f /=; apply/funext => n /=; rewrite !Ucompx/= compo1/=. by rewrite -naturalU/=; congr (n _ _); apply/esym/comp1o. Qed. HB.instance Definition _ := hom_repr_natural_subproof. (* show this from the previous proof *) Lemma hom_natural_repr_subproof : IsNatural _ _ _ _ repr_hom_nat. Proof. split=> a b f /=; apply: funext => fa /=; rewrite !Ucompx/=. apply: natP; apply: funext => c /=; apply: funext => d /=. by rewrite Fcomp Ucompx/=. Qed. HB.instance Definition _ := hom_natural_repr_subproof. Definition hom_repr_nat : homF ~~> F := hom_repr. Definition repr_hom_nat_nat : F ~~> homF := repr_hom_nat. End hom_repr. (* comma categories *) Module comma. Section homcomma. Context {C D E : precat} (F : C ~> E) (G : D ~> E). Definition type := { x : C * D & F x.1 ~> G x.2 }. Definition hom_subdef (a b : type) := { f : tag a ~> tag b & F <$> f.1 \; tagged b = tagged a \; G <$> f.2 }. HB.instance Definition _ := IsQuiver.Build type hom_subdef. End homcomma. Arguments hom_subdef /. Section comma. Context {C D E : cat} (F : C ~> E) (G : D ~> E). Notation type := (type F G). Program Definition idmap_subdef (a : type) : a ~> a := @Tagged _ idmap _ _. Next Obligation. by move=> ? /=; rewrite /tagged/= !F1 comp1o compo1. Qed. Program Definition comp_subdef (a b c : type) (f : a ~> b) (g : b ~> c) : a ~> c := @Tagged _ (tag f \; tag g) _ _. Next Obligation. move=> a b c f g; rewrite /tagged/= !Fcomp -compoA /=. by rewrite (tagged g) compoA (tagged f) compoA. Qed. HB.instance Definition _ := IsPreCat.Build type idmap_subdef comp_subdef. Arguments idmap_subdef /. Arguments comp_subdef /. Lemma comma_homeqP (a b : type) (f g : a ~> b) : projT1 f = projT1 g -> f = g. Proof. case: f g => [f fP] [g +]/= eqfg; case: _ / eqfg => gP. by congr existT; apply: Prop_irrelevance. Qed. Lemma comma_is_cat : PreCat_IsCat type. Proof. by split=> [[a fa] [b fb] [*]|[a fa] [b fb] [*]|*]; apply/comma_homeqP; rewrite /= ?(comp1o, compo1, compoA). Qed. HB.instance Definition _ := comma_is_cat. End comma. End comma. Notation "F `/` G" := (@comma.type _ _ _ F G) (at level 40, G at level 40, format "F `/` G") : cat_scope. Notation "a /` G" := (cst unit a `/` G) (at level 40, G at level 40, format "a /` G") : cat_scope. Notation "F `/ b" := (F `/` cst unit b) (at level 40, b at level 40, format "F `/ b") : cat_scope. Notation "a / b" := (cst unit a `/ b) : cat_scope. Definition obj (C : quiver) : Type := C. HB.mixin Record IsInitial {C : quiver} (i : obj C) := { to : forall c, i ~> c; to_unique : forall c (f : i ~> c), f = to c }. #[short(type="initial")] HB.structure Definition Initial {C : quiver} := {i of IsInitial C i}. HB.mixin Record IsTerminal {C : quiver} (t : obj C) := { from : forall c, c ~> t; from_unique : forall c (f : c ~> t), f = from c }. #[short(type="terminal")] HB.structure Definition Terminal {C : quiver} := {t of IsTerminal C t}. HB.mixin Record IsMono {C : precat} (b c : C) (f : hom b c) := { monoP : forall (a : C) (g1 g2 : a ~> b), g1 \; f = g2 \; f -> g1 = g2 }. #[short(type="mono")] HB.structure Definition Mono {C : precat} (a b : C) := {m of IsMono C a b m}. Notation "a >~> b" := (mono a b) (at level 99, b at level 200, format "a >~> b") : cat_scope. Notation "C >~>_ T D" := (@mono T C D) (at level 99, T at level 0, only parsing) : cat_scope. HB.mixin Record IsEpi {C : precat} (a b : C) (f : hom a b) := { epiP : forall (c : C) (g1 g2 : b ~> c), g1 \o f = g2 \o f -> g1 = g2 }. #[short(type="epi")] HB.structure Definition Epi {C : precat} (a b : C) := {e of IsEpi C a b e}. Notation "a ~>> b" := (epi a b) (at level 99, b at level 200, format "a ~>> b") : cat_scope. Notation "C ~>>_ T D" := (@epi T C D) (at level 99, T at level 0, only parsing) : cat_scope. #[short(type="iso")] HB.structure Definition Iso {C : precat} (a b : C) := {i of @Mono C a b i & @Epi C a b i}. Notation "a <~> b" := (epi a b) (at level 99, b at level 200, format "a <~> b") : cat_scope. Notation "C <~>_ T D" := (@epi T C D) (at level 99, T at level 0, only parsing) : cat_scope. Definition comp1F {C D : cat} (F : C ~> D) : idmap \; F = F. Proof. by apply/functorP=> a b f; rewrite funext_frefl/= compFmap. Qed. Definition compF1 {C D : cat} (F : C ~> D) : F \; idmap = F. Proof. by apply/functorP=> a b f; rewrite funext_frefl/= compFmap. Qed. Definition feq {C : precat} {a b : C} : a = b -> a ~> b. Proof. by move<-; exact idmap. Defined. Definition feqsym {C : precat} {a b : C} : a = b -> b ~> a. Proof. by move<-; exact idmap. Defined. HB.mixin Record IsLeftAdjointOf (C D : cat) (R : D ~> C) L & @Functor C D L := { Lphi : forall c d, (L c ~> d) -> (c ~> R d); Lpsi : forall c d, (c ~> R d) -> (L c ~> d); (* there should be a monad and comonad structure wrappers instead *) Lunit : (idmap : C ~> C) ~> R \o (L : Functor.type C D); Lcounit : (L : Functor.type C D) \o R ~~> idmap :> D ~> D; LphiE : forall c d (g : L c ~> d), Lphi c d g = Lunit c \; (R <$> g); LpsiE : forall c d (f : c ~> R d), Lpsi c d f = (L <$> f) \; Lcounit d; Lwhiskerlr : let L : C ~> D := L : Functor.type C D in (feqsym (comp1F _) \; Lunit L) \; (L <$o> Lcounit \; feq (compF1 _)) = idmap; Lwhiskerrl : let L : C ~> D := L : Functor.type C D in (feqsym (compF1 _) \; R <$o> Lunit) \; (Lcounit R \; feq (comp1F _)) = idmap; }. #[short(type="left_adjoint_of")] HB.structure Definition LeftAdjointOf (C D : cat) (R : D ~> C) := { L of @Functor C D L & IsLeftAdjointOf C D R L}. Arguments Lphi {C D R s} {c d}. Arguments Lpsi {C D R s} {c d}. Arguments Lunit {C D R s}. Arguments Lcounit {C D R s}. (* Section LeftAdjointOf_Theory. *) (* Variables (C D : cat) (R : D ~> C) (L : LeftAdjointOf.type R). *) (* Lemma Lphi_psi (c : C) (d : D) : *) (* (@Lphi _ _ R L c d \o @Lpsi _ _ R L c d)%function = @id (c ~> R d). *) (* Proof. *) (* apply/funext => f /=; rewrite LphiE LpsiE. *) (* Admitted. *) (* Lemma Lpsi_phi (c : C) (d : D) : *) (* (@Lpsi _ _ R L c d \o @Lphi _ _ R L c d)%function = @id (L c ~> d). *) (* Proof. *) (* Admitted. *) (* End LeftAdjointOf_Theory. *) HB.mixin Record IsRightAdjoint (D C : cat) (R : D -> C) & @Functor D C R := { (* we should have a wrapper instead *) left_adjoint : C ~> D; LLphi : forall c d, (left_adjoint c ~> d) -> (c ~> R d); LLpsi : forall c d, (c ~> R d) -> (left_adjoint c ~> d); LLunit : (idmap : C ~> C) ~~> (R : Functor.type D C) \o left_adjoint; LLcounit : left_adjoint \o (R : Functor.type D C) ~~> idmap :> D ~> D; LLphiE : forall c d (g : left_adjoint c ~> d), LLphi c d g = LLunit c \; (R <$> g); LLpsiE : forall c d (f : c ~> R d), LLpsi c d f = (left_adjoint <$> f) \; LLcounit d; LLwhiskerlr : (feqsym (comp1F _) \; LLunit left_adjoint) \; (left_adjoint <$o> LLcounit \; feq (compF1 _)) = idmap; LLwhiskerrl : (feqsym (compF1 _) \; (R : Functor.type D C) <$o> LLunit) \; (LLcounit (R : Functor.type D C) \; feq (comp1F _)) = idmap; }. #[short(type="right_adjoint")] HB.structure Definition RightAdjoint (D C : cat) := { R of @Functor D C R & IsRightAdjoint D C R }. Arguments left_adjoint {_ _}. Arguments LLphi {D C s} {c d}. Arguments LLpsi {D C s} {c d}. Arguments LLunit {D C s}. Arguments LLcounit {D C s}. HB.mixin Record PreCat_IsMonoidal C & PreCat C := { onec : C; prod : (C * C)%type ~>_precat C; }. #[short(type="premonoidal")] HB.structure Definition PreMonoidal := { C of PreCat C & PreCat_IsMonoidal C }. Notation premonoidal := premonoidal. Arguments prod {C} : rename. Notation "a * b" := (prod (a, b)) : cat_scope. Reserved Notation "f <*> g" (at level 40, g at level 40, format "f <*> g"). Notation "f <*> g" := (prod^$ (f, g)) (only printing) : cat_scope. Notation "f <*> g" := (prod^$ ((f, g) : (_, _) ~> (_, _))) (only parsing) : cat_scope. Notation "1" := onec : cat_scope. Definition hom_cast {C : quiver} {a a' : C} (eqa : a = a') {b b' : C} (eqb : b = b') : (a ~> b) -> (a' ~> b'). Proof. now elim: _ / eqa; elim: _ / eqb. Defined. HB.mixin Record PreFunctor_IsMonoidal (C D : premonoidal) F & @PreFunctor C D F := { fun_one : F 1 = 1; fun_prod : forall (x y : C), F (x * y) = F x * F y; }. #[short(type="monoidal_prefunctor")] HB.structure Definition MonoidalPreFunctor C D := { F of @PreFunctor_IsMonoidal C D F }. Arguments fun_prod {C D F x y} : rename. (* Arguments fun_prodF {C D F x x'} f {y y'} g : rename. *) Unset Universe Checking. HB.instance Definition _ := IsQuiver.Build premonoidal MonoidalPreFunctor.type. Set Universe Checking. HB.instance Definition _ (C : quiver) := IsPreFunctor.Build (C * C)%type C fst (fun (a b : C * C) (f : a ~> b) => f.1). HB.instance Definition _ (C : quiver) := IsPreFunctor.Build (C * C)%type C snd (fun (a b : C * C) (f : a ~> b) => f.2). Definition prod3l {C : premonoidal} (x : C * C * C) : C := (x.1.1 * x.1.2) * x.2. HB.instance Definition _ {C : premonoidal} := IsPreFunctor.Build _ C prod3l (fun a b (f : a ~> b) => (f.1.1 <*> f.1.2) <*> f.2). Definition prod3r {C : premonoidal} (x : C * C * C) : C := x.1.1 * (x.1.2 * x.2). HB.instance Definition _ {C : premonoidal} := IsPreFunctor.Build _ C prod3r (fun a b (f : a ~> b) => f.1.1 <*> (f.1.2 <*> f.2)). Definition prod1r {C : premonoidal} (x : C) : C := 1 * x. HB.instance Definition _ {C : premonoidal} := IsPreFunctor.Build C C prod1r (fun (a b : C) (f : a ~> b) => \idmap_1 <*> f). Definition prod1l {C : premonoidal} (x : C) : C := x * 1. HB.instance Definition _ {C : premonoidal} := IsPreFunctor.Build C C prod1l (fun (a b : C) (f : a ~> b) => f <*> \idmap_1). HB.mixin Record PreMonoidal_IsMonoidal C & PreMonoidal C := { prodA : prod3l ~~> prod3r; prod1c : prod1r ~~> idfun; prodc1 : prod1l ~~> idfun; prodc1c : forall (x y : C), prodA (x, 1, y) \; \idmap_x <*> prod1c y = prodc1 x <*> \idmap_y; prodA4 : forall (w x y z : C), prodA (w * x, y, z) \; prodA (w, x, y * z) = prodA (w, x, y) <*> \idmap_z \; prodA (w, x * y, z) \; \idmap_w <*> prodA (x, y, z); }. Unset Universe Checking. #[short(type="monoidal")] HB.structure Definition Monoidal : Set := { C of PreMonoidal_IsMonoidal C & PreMonoidal C }. Set Universe Checking. HB.mixin Record IsRing A := { zero : A; one : A; add : A -> A -> A; opp : A -> A; mul : A -> A -> A; addrA : associative add; addrC : commutative add; add0r : left_id zero add; addNr : left_inverse zero opp add; mulrA : associative mul; mul1r : left_id one mul; mulr1 : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; }. #[short(type="ring")] HB.structure Definition Ring := { A of IsRing A }. Bind Scope algebra_scope with Ring.sort. Notation "0" := zero : algebra_scope. Notation "1" := one : algebra_scope. Infix "+" := (@add _) : algebra_scope. Notation "- x" := (@opp _ x) : algebra_scope. Infix "*" := (@mul _) : algebra_scope. Notation "x - y" := (x + - y) : algebra_scope. Lemma addr0 (R : ring) : right_id (@zero R) add. Proof. by move=> x; rewrite addrC add0r. Qed. Lemma addrN (R : ring) : right_inverse (@zero R) opp add. Proof. by move=> x; rewrite addrC addNr. Qed. Lemma addKr (R : ring) (x : R) : cancel (add x) (add (- x)). Proof. by move=> y; rewrite addrA addNr add0r. Qed. Lemma addrI (R : ring) (x : R) : injective (add x). Proof. exact: can_inj (addKr _). Qed. Lemma opprK (R : ring) : involutive (@opp R). Proof. by move=> x; apply: (@addrI _ (- x)); rewrite addNr addrN. Qed. HB.mixin Record IsRingHom (A B : ring) (f : A -> B) := { hom1_subproof : f 1%A = 1%A; homB_subproof : {morph f : x y / x - y}; homM_subproof : {morph f : x y / (x * y)%A}; }. HB.structure Definition RingHom A B := { f of IsRingHom A B f }. Lemma id_IsRingHom A : IsRingHom A A idfun. Proof. by []. Defined. HB.instance Definition _ A := id_IsRingHom A. Lemma comp_IsRingHom (A B C : ring) (f : RingHom.type A B) (g : RingHom.type B C) : IsRingHom A C (g \o f)%function. Proof. by constructor => [|x y|x y]; rewrite /comp/= ?hom1_subproof ?homB_subproof ?homM_subproof. Qed. HB.instance Definition _ A B C f g := @comp_IsRingHom A B C f g. HB.instance Definition _ := IsQuiver.Build ring RingHom.type. HB.instance Definition _ := Quiver_IsPreCat.Build ring (fun a => @idfun a : RingHom.type a a) (fun a b c (f : a ~> b) (g : b ~> c) => (g \o f)%function : RingHom.type _ _). HB.instance Definition _ := Quiver_IsPreConcrete.Build ring (fun _ _ => id). Lemma ring_precat : PreConcrete_IsConcrete ring. Proof. constructor => A B [f cf] [g cg]//=; rewrite -[_ = _]/(f = g) => fg. case: _ / fg in cg *; congr {|RingHom.sort := _ ; RingHom.class := _|}. case: cf cg => [[? ? ?]] [[? ? ?]]. by congr RingHom.Class; congr IsRingHom.phant_Build => //=; apply: Prop_irrelevance. Qed. HB.instance Definition _ := ring_precat. Lemma ring_IsCat : PreCat_IsCat ring. Proof. by constructor=> [A B f|A B f|A B C D f g h]; exact: concrete_fun_inj. Qed. HB.instance Definition _ := ring_IsCat. Lemma hom1 (R S : ring) (f : R ~> S) : f 1%A = 1%A. Proof. exact: hom1_subproof. Qed. Lemma homB (R S : ring) (f : R ~> S) : {morph f : x y / x - y}. Proof. exact: homB_subproof. Qed. Lemma homM (R S : ring) (f : R ~> S) : {morph f : x y / (x * y)%A}. Proof. exact: homM_subproof. Qed. Lemma hom0 (R S : ring) (f : R ~> S) : f 0%A = 0%A. Proof. by rewrite -(addrN 1%A) homB addrN. Qed. Lemma homN (R S : ring) (f : R ~> S) : {morph f : x / - x}. Proof. by move=> x; rewrite -[- x]add0r homB hom0 add0r. Qed. Lemma homD (R S : ring) (f : R ~> S) : {morph f : x y / x + y}. Proof. by move=> x y; rewrite -[y]opprK !homB !homN. Qed. HB.mixin Record IsIdeal (R : ring) (I : R -> Prop) := { ideal0 : I 0; idealD : forall x y, I x -> I y -> I (x + y); idealM : forall x y, I y -> I (x * y)%A; }. HB.structure Definition Ideal (R : ring) := { I of IsIdeal R I }. HB.mixin Record Ideal_IsPrime (R : ring) (I : R -> Prop) & IsIdeal R I := { ideal_prime : forall x y : R, I (x * y)%A -> I x \/ I y }. #[short(type="spectrum")] HB.structure Definition PrimeIdeal (R : ring) := { I of Ideal_IsPrime R I & Ideal R I }. math-comp-hierarchy-builder-4d8a939/examples/demo3/000077500000000000000000000000001521677141400222035ustar00rootroot00000000000000math-comp-hierarchy-builder-4d8a939/examples/demo3/hierarchy_0.v000066400000000000000000000013341521677141400245700ustar00rootroot00000000000000From HB Require Import structures. From Corelib Require Import ssreflect ssrfun. HB.mixin Record MulMonoid_of_Type A := { one : A; mul : A -> A -> A; mulrA : associative mul; mul1r : left_id one mul; mulr1 : right_id one mul; }. HB.structure Definition MulMonoid := { A of MulMonoid_of_Type A }. HB.mixin Record Ring_of_MulMonoid A & MulMonoid A := { zero : A; add : A -> A -> A; addrA : associative add; add0r : left_id zero add; addr0 : right_id zero add; opp : A -> A; addrC : commutative (add : A -> A -> A); addNr : left_inverse zero opp add; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; }. HB.structure Definition Ring := { A of MulMonoid A & Ring_of_MulMonoid A }. math-comp-hierarchy-builder-4d8a939/examples/demo3/hierarchy_1.v000066400000000000000000000030151521677141400245670ustar00rootroot00000000000000From Corelib Require Import ssreflect ssrfun. From HB Require Import structures. HB.mixin Record MulMonoid_of_Type A := { one : A; mul : A -> A -> A; mulrA : associative mul; mul1r : left_id one mul; mulr1 : right_id one mul; }. HB.structure Definition MulMonoid := { A of MulMonoid_of_Type A }. HB.mixin Record AddMonoid_of_Type A := { zero : A; add : A -> A -> A; addrA : associative add; add0r : left_id zero add; addr0 : right_id zero add; }. HB.structure Definition AddMonoid := { A of AddMonoid_of_Type A }. HB.mixin Record Ring_of_AddMulMonoid A & MulMonoid A & AddMonoid A := { opp : A -> A; addrC : commutative (add : A -> A -> A); addNr : left_inverse zero opp add; mulrDl : left_distributive mul (add : A -> A -> A); mulrDr : right_distributive mul (add : A -> A -> A); }. HB.structure Definition Ring := { A of MulMonoid A & AddMonoid A & Ring_of_AddMulMonoid A }. HB.factory Record Ring_of_MulMonoid A & MulMonoid A := { zero : A; add : A -> A -> A; addrA : associative add; add0r : left_id zero add; addr0 : right_id zero add; opp : A -> A; addrC : commutative (add : A -> A -> A); addNr : left_inverse zero opp add; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; }. HB.builders Context A (a : Ring_of_MulMonoid A). HB.instance Definition to_AddMonoid_of_Type := AddMonoid_of_Type.Build A zero add addrA add0r addr0. HB.instance Definition to_Ring_of_AddMulMonoid := Ring_of_AddMulMonoid.Build A opp addrC addNr mulrDl mulrDr. HB.end. math-comp-hierarchy-builder-4d8a939/examples/demo3/hierarchy_2.v000066400000000000000000000044731521677141400246010ustar00rootroot00000000000000From Corelib Require Import ssreflect ssrfun. From HB Require Import structures. HB.mixin Record MulMonoid_of_Type A := { one : A; mul : A -> A -> A; mulrA : associative mul; mul1r : left_id one mul; mulr1 : right_id one mul; }. HB.structure Definition MulMonoid := { A of MulMonoid_of_Type A }. HB.mixin Record AddMonoid_of_Type A := { zero : A; add : A -> A -> A; addrA : associative add; add0r : left_id zero add; addr0 : right_id zero add; }. HB.structure Definition AddMonoid := { A of AddMonoid_of_Type A }. HB.mixin Record AbGroup_of_AddMonoid A & AddMonoid A := { opp : A -> A; addrC : commutative (add : A -> A -> A); addNr : left_inverse zero opp add; }. HB.structure Definition AbGroup := { A of AddMonoid A & AbGroup_of_AddMonoid A }. HB.mixin Record Ring_of_AbGroupMulMonoid A & MulMonoid A & AbGroup A := { mulrDl : left_distributive mul (add : A -> A -> A); mulrDr : right_distributive mul (add : A -> A -> A); }. HB.structure Definition Ring := { A of MulMonoid A & AbGroup A & Ring_of_AbGroupMulMonoid A }. HB.factory Record Ring_of_AddMulMonoid A & MulMonoid A & AddMonoid A := { opp : A -> A; addrC : commutative (add : A -> A -> A); addNr : left_inverse zero opp add; mulrDl : left_distributive mul (add : A -> A -> A); mulrDr : right_distributive mul (add : A -> A -> A); }. HB.builders Context A (a : Ring_of_AddMulMonoid A). HB.instance Definition to_AbGroup_of_AddMonoid := AbGroup_of_AddMonoid.Build A opp addrC addNr. HB.instance Definition to_Ring_of_AbGroupMulMonoid := Ring_of_AbGroupMulMonoid.Build A mulrDl mulrDr. HB.end. HB.factory Record Ring_of_MulMonoid A & MulMonoid A := { zero : A; add : A -> A -> A; addrA : associative add; add0r : left_id zero add; addr0 : right_id zero add; opp : A -> A; addrC : commutative (add : A -> A -> A); addNr : left_inverse zero opp add; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; }. HB.builders Context A (a : Ring_of_MulMonoid A). HB.instance Definition to_AddMonoid_of_Type := AddMonoid_of_Type.Build A zero add addrA add0r addr0. HB.instance Definition to_AbGroup_of_AddMonoid := AbGroup_of_AddMonoid.Build A opp addrC addNr. HB.instance Definition to_Ring_of_AddMulMonoid := Ring_of_AddMulMonoid.Build A opp addrC addNr mulrDl mulrDr. HB.end. math-comp-hierarchy-builder-4d8a939/examples/demo3/test_0_0.v000066400000000000000000000035031521677141400240100ustar00rootroot00000000000000From Corelib Require Import ssreflect ssrfun. From Corelib Require Import BinNums IntDef. From HB Require Import structures. From HB Require Import demo3.hierarchy_0. Declare Scope hb_scope. Delimit Scope hb_scope with G. Local Open Scope hb_scope. Notation "0" := zero : hb_scope. Notation "1" := one : hb_scope. Infix "+" := (@add _) : hb_scope. Notation "- x" := (@opp _ x) : hb_scope. Infix "*" := (@mul _) : hb_scope. Notation "x - y" := (x + - y) : hb_scope. (* Theory *) Section Theory. Variable R : Ring.type. Implicit Type (x : R). (* Lemma addr0 : right_id (@zero R) add. Proof. by move=> x; rewrite addrC add0r. Qed. *) Lemma addrN : right_inverse (@zero R) opp add. Proof. by move=> x; rewrite addrC addNr. Qed. Lemma subrr x : x - x = 0. Proof. by rewrite addrN. Qed. Lemma addrNK x y : x + y - y = x. Proof. by rewrite -addrA subrr addr0. Qed. End Theory. (* Instance *) Axiom Z_mul_assoc : forall x y z, Z.mul x (Z.mul y z) = Z.mul (Z.mul x y) z. Axiom Z_mul_1_l : forall x, Z.mul (Zpos xH) x = x. Axiom Z_mul_1_r : forall x, Z.mul x (Zpos xH) = x. HB.instance Definition Z_mulmonoid_axioms := MulMonoid_of_Type.Build Z (Zpos xH) Z.mul Z_mul_assoc Z_mul_1_l Z_mul_1_r. Axiom Z_add_assoc : forall x y z, Z.add x (Z.add y z) = Z.add (Z.add x y) z. Axiom Z_add_comm : forall x y, Z.add x y = Z.add y x. Axiom Z_add_0_l : forall x, Z.add Z0 x = x. Axiom Z_add_0_r : forall x, Z.add x Z0 = x. Axiom Z_add_opp_diag_l : forall x, Z.add (Z.opp x) x = Z0. Axiom Z_mul_add_distr_l : forall x y z, Z.mul x (Z.add y z) = Z.add (Z.mul x y) (Z.mul x z). Axiom Z_mul_add_distr_r : forall x y z, Z.mul (Z.add x y) z = Z.add (Z.mul x z) (Z.mul y z). HB.instance Definition Z_ring_axioms := Ring_of_MulMonoid.Build Z Z0 Z.add Z_add_assoc Z_add_0_l Z_add_0_r Z.opp Z_add_comm Z_add_opp_diag_l Z_mul_add_distr_r Z_mul_add_distr_l. math-comp-hierarchy-builder-4d8a939/examples/demo3/test_1_0.v000066400000000000000000000035031521677141400240110ustar00rootroot00000000000000From Corelib Require Import ssreflect ssrfun. From Corelib Require Import BinNums IntDef. From HB Require Import structures. From HB Require Import demo3.hierarchy_1. Declare Scope hb_scope. Delimit Scope hb_scope with G. Local Open Scope hb_scope. Notation "0" := zero : hb_scope. Notation "1" := one : hb_scope. Infix "+" := (@add _) : hb_scope. Notation "- x" := (@opp _ x) : hb_scope. Infix "*" := (@mul _) : hb_scope. Notation "x - y" := (x + - y) : hb_scope. (* Theory *) Section Theory. Variable R : Ring.type. Implicit Type (x : R). (* Lemma addr0 : right_id (@zero R) add. Proof. by move=> x; rewrite addrC add0r. Qed. *) Lemma addrN : right_inverse (@zero R) opp add. Proof. by move=> x; rewrite addrC addNr. Qed. Lemma subrr x : x - x = 0. Proof. by rewrite addrN. Qed. Lemma addrNK x y : x + y - y = x. Proof. by rewrite -addrA subrr addr0. Qed. End Theory. (* Instance *) Axiom Z_mul_assoc : forall x y z, Z.mul x (Z.mul y z) = Z.mul (Z.mul x y) z. Axiom Z_mul_1_l : forall x, Z.mul (Zpos xH) x = x. Axiom Z_mul_1_r : forall x, Z.mul x (Zpos xH) = x. HB.instance Definition Z_mulmonoid_axioms := MulMonoid_of_Type.Build Z (Zpos xH) Z.mul Z_mul_assoc Z_mul_1_l Z_mul_1_r. Axiom Z_add_assoc : forall x y z, Z.add x (Z.add y z) = Z.add (Z.add x y) z. Axiom Z_add_comm : forall x y, Z.add x y = Z.add y x. Axiom Z_add_0_l : forall x, Z.add Z0 x = x. Axiom Z_add_0_r : forall x, Z.add x Z0 = x. Axiom Z_add_opp_diag_l : forall x, Z.add (Z.opp x) x = Z0. Axiom Z_mul_add_distr_l : forall x y z, Z.mul x (Z.add y z) = Z.add (Z.mul x y) (Z.mul x z). Axiom Z_mul_add_distr_r : forall x y z, Z.mul (Z.add x y) z = Z.add (Z.mul x z) (Z.mul y z). HB.instance Definition Z_ring_axioms := Ring_of_MulMonoid.Build Z Z0 Z.add Z_add_assoc Z_add_0_l Z_add_0_r Z.opp Z_add_comm Z_add_opp_diag_l Z_mul_add_distr_r Z_mul_add_distr_l. math-comp-hierarchy-builder-4d8a939/examples/demo3/test_2_0.v000066400000000000000000000035031521677141400240120ustar00rootroot00000000000000From Corelib Require Import ssreflect ssrfun. From Corelib Require Import BinNums IntDef. From HB Require Import structures. From HB Require Import demo3.hierarchy_2. Declare Scope hb_scope. Delimit Scope hb_scope with G. Local Open Scope hb_scope. Notation "0" := zero : hb_scope. Notation "1" := one : hb_scope. Infix "+" := (@add _) : hb_scope. Notation "- x" := (@opp _ x) : hb_scope. Infix "*" := (@mul _) : hb_scope. Notation "x - y" := (x + - y) : hb_scope. (* Theory *) Section Theory. Variable R : Ring.type. Implicit Type (x : R). (* Lemma addr0 : right_id (@zero R) add. Proof. by move=> x; rewrite addrC add0r. Qed. *) Lemma addrN : right_inverse (@zero R) opp add. Proof. by move=> x; rewrite addrC addNr. Qed. Lemma subrr x : x - x = 0. Proof. by rewrite addrN. Qed. Lemma addrNK x y : x + y - y = x. Proof. by rewrite -addrA subrr addr0. Qed. End Theory. (* Instance *) Axiom Z_mul_assoc : forall x y z, Z.mul x (Z.mul y z) = Z.mul (Z.mul x y) z. Axiom Z_mul_1_l : forall x, Z.mul (Zpos xH) x = x. Axiom Z_mul_1_r : forall x, Z.mul x (Zpos xH) = x. HB.instance Definition Z_mulmonoid_axioms := MulMonoid_of_Type.Build Z (Zpos xH) Z.mul Z_mul_assoc Z_mul_1_l Z_mul_1_r. Axiom Z_add_assoc : forall x y z, Z.add x (Z.add y z) = Z.add (Z.add x y) z. Axiom Z_add_comm : forall x y, Z.add x y = Z.add y x. Axiom Z_add_0_l : forall x, Z.add Z0 x = x. Axiom Z_add_0_r : forall x, Z.add x Z0 = x. Axiom Z_add_opp_diag_l : forall x, Z.add (Z.opp x) x = Z0. Axiom Z_mul_add_distr_l : forall x y z, Z.mul x (Z.add y z) = Z.add (Z.mul x y) (Z.mul x z). Axiom Z_mul_add_distr_r : forall x y z, Z.mul (Z.add x y) z = Z.add (Z.mul x z) (Z.mul y z). HB.instance Definition Z_ring_axioms := Ring_of_MulMonoid.Build Z Z0 Z.add Z_add_assoc Z_add_0_l Z_add_0_r Z.opp Z_add_comm Z_add_opp_diag_l Z_mul_add_distr_r Z_mul_add_distr_l. math-comp-hierarchy-builder-4d8a939/examples/demo3/user_0.v000066400000000000000000000022661521677141400235750ustar00rootroot00000000000000From Coq Require Import ZArith ssreflect ssrfun. From HB Require Import structures. From @@DEMO@@ Require Import @@HIERARCHY@@. Declare Scope hb_scope. Delimit Scope hb_scope with G. Local Open Scope hb_scope. Notation "0" := zero : hb_scope. Notation "1" := one : hb_scope. Infix "+" := (@add _) : hb_scope. Notation "- x" := (@opp _ x) : hb_scope. Infix "*" := (@mul _) : hb_scope. Notation "x - y" := (x + - y) : hb_scope. (* Theory *) Section Theory. Variable R : Ring.type. Implicit Type (x : R). (* Lemma addr0 : right_id (@zero R) add. Proof. by move=> x; rewrite addrC add0r. Qed. *) Lemma addrN : right_inverse (@zero R) opp add. Proof. by move=> x; rewrite addrC addNr. Qed. Lemma subrr x : x - x = 0. Proof. by rewrite addrN. Qed. Lemma addrNK x y : x + y - y = x. Proof. by rewrite -addrA subrr addr0. Qed. End Theory. (* Instance *) Definition Z_mulmonoid_axioms := MulMonoid_of_Type.Build Z 1%Z Z.mul Z.mul_assoc Z.mul_1_l Z.mul_1_r. HB.instance Z Z_mulmonoid_axioms. Definition Z_ring_axioms := Ring_of_MulMonoid.Build Z 0%Z Z.add Z.add_assoc Z.add_0_l Z.add_0_r Z.opp Z.add_comm Z.add_opp_diag_l Z.mul_add_distr_r Z.mul_add_distr_l. HB.instance Z Z_ring_axioms.math-comp-hierarchy-builder-4d8a939/examples/demo4/000077500000000000000000000000001521677141400222045ustar00rootroot00000000000000math-comp-hierarchy-builder-4d8a939/examples/demo4/hierarchy_0.v000066400000000000000000000013271521677141400245730ustar00rootroot00000000000000From HB Require Import structures. #[key="A"] HB.mixin Record m1 (T : Type) (A : Type) := { inhab : A; inhab_param : T; }. HB.structure Definition s1 T := { A of m1 T A }. Check inhab. (* inhab : forall (T : Type) (A : s1.type T), s1.sort A *) HB.instance Definition nat_m1 := m1.Build bool nat 7 false. Check (refl_equal _ : @inhab _ _ = 7). HB.instance Definition list_m1 A := m1.Build (option A) (list nat) (cons 7 nil) None. Check (refl_equal _ : @inhab _ _ = (cons 7 nil)). HB.mixin Record m2 (T : Type) (A : Type) & m1 T A := { inj : T -> A; }. HB.structure Definition s2 T := { A of m1 T A & m2 T A }. Check fun X : s2.type nat => inhab : X. Check fun X : s2.type nat => inj : nat -> X. About s2_to_s1. math-comp-hierarchy-builder-4d8a939/examples/demo5/000077500000000000000000000000001521677141400222055ustar00rootroot00000000000000math-comp-hierarchy-builder-4d8a939/examples/demo5/hierarchy_0.v000066400000000000000000000117241521677141400245760ustar00rootroot00000000000000From Corelib Require Import ssreflect ssrfun. From HB Require Import structures. HB.mixin Record AddComoid_of_TYPE A := { zero : A; add : A -> A -> A; addrA : associative add; addrC : commutative add; add0r : left_id zero add; }. HB.structure Definition AddComoid := { A of AddComoid_of_TYPE A }. (* Begin change *) HB.mixin Record AddAG_of_AddComoid A & AddComoid A := { opp : A -> A; addNr : left_inverse zero opp add; }. HB.factory Record AddAG_of_TYPE A := { zero : A; add : A -> A -> A; opp : A -> A; addrA : associative add; addrC : commutative add; add0r : left_id zero add; addNr : left_inverse zero opp add; }. HB.builders Context A (a : AddAG_of_TYPE A). HB.instance Definition to_AddComoid_of_TYPE := AddComoid_of_TYPE.Build A zero add addrA addrC add0r. HB.instance Definition to_AddAG_of_AddComoid := AddAG_of_AddComoid.Build A _ addNr. HB.end. HB.structure Definition AddAG := { A of AddAG_of_TYPE A }. HB.mixin Record Ring_of_AddAG A & AddAG A := { one : A; mul : A -> A -> A; mulrA : associative mul; mul1r : left_id one mul; mulr1 : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; }. HB.factory Record Ring_of_AddComoid A & AddComoid A := { opp : A -> A; one : A; mul : A -> A -> A; addNr : left_inverse zero opp add; mulrA : associative mul; mul1r : left_id one mul; mulr1 : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; }. HB.builders Context A (a : Ring_of_AddComoid A). HB.instance Definition to_AddAG_of_AddComoid := AddAG_of_AddComoid.Build A _ addNr. HB.instance Definition to_Ring_of_AddAG := Ring_of_AddAG.Build A _ _ mulrA mul1r mulr1 mulrDl mulrDr. HB.end. (* End change *) HB.factory Record Ring_of_TYPE A := { zero : A; one : A; add : A -> A -> A; opp : A -> A; mul : A -> A -> A; addrA : associative add; addrC : commutative add; add0r : left_id zero add; addNr : left_inverse zero opp add; mulrA : associative mul; mul1r : left_id one mul; mulr1 : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; }. HB.builders Context A (a : Ring_of_TYPE A). HB.instance Definition to_AddComoid_of_TYPE := AddComoid_of_TYPE.Build A zero add addrA addrC add0r. HB.instance Definition to_Ring_of_AddComoid := Ring_of_AddComoid.Build A _ _ _ addNr mulrA mul1r mulr1 mulrDl mulrDr. HB.end. HB.structure Definition Ring := { A of Ring_of_TYPE A }. (* Notations *) Declare Scope hb_scope. Delimit Scope hb_scope with G. Local Open Scope hb_scope. Notation "0" := zero : hb_scope. Notation "1" := one : hb_scope. Infix "+" := (@add _) : hb_scope. Notation "- x" := (@opp _ x) : hb_scope. Infix "*" := (@mul _) : hb_scope. Notation "x - y" := (x + - y) : hb_scope. (* Theory *) Section Theory. Variable R : Ring.type. Implicit Type (x : R). Lemma addr0 : right_id (@zero R) add. Proof. by move=> x; rewrite addrC add0r. Qed. Lemma addrN : right_inverse (@zero R) opp add. Proof. by move=> x; rewrite addrC addNr. Qed. Lemma subrr x : x - x = 0. Proof. by rewrite addrN. Qed. Lemma addrNK x y : x + y - y = x. Proof. by rewrite -addrA subrr addr0. Qed. End Theory. HB.mixin Record LModule_of_AG (R : Ring.type) (M : Type) & AddAG M := { scale : Ring.sort R -> M -> M; (* TODO: insert coercions automatically *) scaleDl : forall v, {morph scale^~ v: a b / a + b}; scaleDr : right_distributive scale add; scaleA : forall a b v, scale a (scale b v) = scale (a * b) v; scale1r : forall m, scale 1 m = m; }. HB.structure Definition LModule (R : Ring.type) := { M of LModule_of_AG R M & }. Infix "*:" := (@scale _ _) (at level 30) : hb_scope. Definition regular (R : Type) := R. HB.instance Definition regular_AG (R : AddAG.type) := AddAG_of_TYPE.Build (regular (AddAG.sort R)) zero add opp addrA addrC add0r addNr. HB.instance Definition regular_LModule (R : Ring.type) := LModule_of_AG.Build R (regular (Ring.sort R)) mul (fun _ _ _ => mulrDl _ _ _) mulrDr mulrA mul1r. From Corelib Require Import BinNums IntDef. Axiom Z_add_assoc : forall x y z, Z.add x (Z.add y z) = Z.add (Z.add x y) z. Axiom Z_add_comm : forall x y, Z.add x y = Z.add y x. Axiom Z_add_0_l : forall x, Z.add Z0 x = x. Axiom Z_add_0_r : forall x, Z.add x Z0 = x. Axiom Z_add_opp_diag_l : forall x, Z.add (Z.opp x) x = Z0. Axiom Z_mul_add_distr_l : forall x y z, Z.mul x (Z.add y z) = Z.add (Z.mul x y) (Z.mul x z). Axiom Z_mul_add_distr_r : forall x y z, Z.mul (Z.add x y) z = Z.add (Z.mul x z) (Z.mul y z). Axiom Z_mul_assoc : forall x y z, Z.mul x (Z.mul y z) = Z.mul (Z.mul x y) z. Axiom Z_mul_1_l : forall x, Z.mul (Zpos xH) x = x. Axiom Z_mul_1_r : forall x, Z.mul x (Zpos xH) = x. HB.instance Definition Z_ring_axioms := Ring_of_TYPE.Build Z Z0 (Zpos xH) Z.add Z.opp Z.mul Z_add_assoc Z_add_comm Z_add_0_l Z_add_opp_diag_l Z_mul_assoc Z_mul_1_l Z_mul_1_r Z_mul_add_distr_r Z_mul_add_distr_l. Lemma test (m : Z) (n : regular Z) : m *: n = m * n. Proof. by []. Qed. math-comp-hierarchy-builder-4d8a939/examples/hulk.v000066400000000000000000000245141521677141400223340ustar00rootroot00000000000000 From HB Require Import structures. Require Import ssreflect ssrfun ssrbool. (* ******************************************************************* *) (* *********************** Hierarchy design ************************** *) (* ******************************************************************* *) Module BadInheritance. HB.mixin Record HasMul T := { mul : T -> T -> T; }. HB.structure Definition Mul := { T of HasMul T }. HB.mixin Record HasSq T := { sq : T -> T; }. HB.structure Definition Sq := { T of HasSq T }. (* We need a functorial construction (a container) which preserves both structures. The simplest one is the option type. *) Definition option_mul {T : Mul.type} (o1 o2 : option T) : option T := match o1, o2 with | Some n, Some m => Some (mul n m) | _, _ => None end. HB.instance Definition _ (T : Mul.type) := HasMul.Build (option T) option_mul. Definition option_square {T : Sq.type} (o : option T) : option T := match o with | Some n => Some (sq n) | None => None end. HB.instance Definition _ (T : Sq.type) := HasSq.Build (option T) option_square. (* Now we mix the two unrelated structures by building Sq out of Mul. *** This breaks Non Forgetful Inheritance *** https://math-comp.github.io/competing-inheritance-paths-in-dependent-type-theory/ *) #[non_forgetful_inheritance] HB.instance Definition _ (T : Mul.type) := HasSq.Build T (fun x => mul x x). (* As we expect we can proved this (by reflexivity) *) Lemma sq_mul (V : Mul.type) (v : V) : sq v = mul v v. Proof. by reflexivity. Qed. Lemma problem (W : Mul.type) (w : option W) : sq w = mul w w. Proof. Fail reflexivity. (* What? It used to work! *) Fail rewrite sq_mul. (* Lemmas don't cross the container either! *) (* Let's investigate *) rewrite /mul/= /sq/=. (* As we expect, we are on the option type. In the LHS it is the Sq built using the NFI instance option_square w = option_mul w w *) rewrite /option_mul/=. rewrite /option_square/sq/=. congr (match w with Some n => _ | None => None end). (* The branches for Some differ, since w is a variable, they don't compare as equal (fun n : W => Some (mul n n)) = (fun n : W => match w with | Some m => Some (mul n m) | None => None end) *) Abort. End BadInheritance. Module GoodInheritance. HB.mixin Record HasMul T := { mul : T -> T -> T; }. HB.structure Definition Mul := { T of HasMul T }. HB.mixin Record HasSq T & Mul T := { sq : T -> T; sq_mul : forall x, sq x = mul x x; }. HB.structure Definition Sq := { T of HasSq T & Mul T }. Definition option_mul {T : Mul.type} (o1 o2 : option T) : option T := match o1, o2 with | Some n, Some m => Some (mul n m) | _, _ => None end. HB.instance Definition _ (T : Mul.type) := HasMul.Build (option T) option_mul. Definition option_square {T : Sq.type} (o : option T) : option T := match o with | Some n => Some (sq n) | None => None end. Lemma option_sq_mul {T : Sq.type} (o : option T) : option_square o = mul o o. Proof. by rewrite /option_square; case: o => [x|//]; rewrite sq_mul. Qed. HB.instance Definition _ (T : Sq.type) := HasSq.Build (option T) option_square option_sq_mul. Lemma problem (W : Sq.type) (w : option W) : sq w = mul w w. Proof. by rewrite sq_mul. Qed. End GoodInheritance. (* ******************************************************************* *) (* ********************** Feather factories *********************** *) (* ******************************************************************* *) (* HB comes with a concept of factory, a virtual interface that is compiled down to the real ones. When the contents of a factory are just one lemma, the following trick may come handy. We define a type "link" which is convertible to a new type T but carries, as a dummy argument, a proof that T is linked to some known type xT. We can then use "link" to transfer (copy) structure instances across the link. *) Module Feather. (* We need a hierarchy with a few structure, here we Equality -> Singleton *) HB.mixin Record HasEqDec T := { eqtest : T -> T -> bool; eqOK : forall x y, reflect (x = y) (eqtest x y); }. HB.structure Definition Equality := { T of HasEqDec T }. HB.mixin Record IsContractible T & HasEqDec T := { def : T; all_def : forall x, eqtest x def = true; }. HB.structure Definition Singleton := { T of IsContractible T }. (* This is the type which is used as a feather factory. - xT plays the role of a rich type, - T is a new type linked to xT by some lemma. In this case a very strong cancellation lemma canfg *) Definition link {xT T : Type} {f : xT -> T} {g : T -> xT} (canfg : forall x, f (g x) = x) := T. (* (link canfg) is convertible to T *) (* We explain HB how to transfer Equality over link *) Section TransferEQ. Context {eT : Equality.type} {T : Type} {f : eT -> T} {g : T -> eT}. Context (canfg : forall x, f (g x) = x). Definition link_eqtest (x y : T) : bool := eqtest (g x) (g y). Lemma link_eqOK (x y : T) : reflect (x = y) (link_eqtest x y). Proof. rewrite /link_eqtest; case: (eqOK (g x) (g y)) => [E|abs]. by constructor; rewrite -[x]canfg -[y]canfg E canfg. by constructor=> /(f_equal g)/abs. Qed. (* (link canfg) is now an Equality instance *) HB.instance Definition link_HasEqDec := HasEqDec.Build (link canfg) link_eqtest link_eqOK. End TransferEQ. (* We explain HB how to transfer Singleton over link *) Section TransferSingleton. Context {eT : Singleton.type} {T : Type} {f : eT -> T} {g : T -> eT}. Context (canfg : forall x, f (g x) = x). Definition link_def : link canfg := f def. Lemma link_all_def x : eqtest x link_def = true. Proof. rewrite /link_def; have /eqOK <- := all_def (g x). by rewrite canfg; case: (eqOK x x). Qed. (* (link canfg) is now a Signleton instance *) HB.instance Definition _ := IsContractible.Build (link canfg) link_def link_all_def. End TransferSingleton. (* We assume a known type B which is both an Equality and a Singleton *) Axiom B : Type. Axiom testB : B -> B -> bool. Axiom testOKB : forall x y, reflect (x = y) (testB x y). HB.instance Definition _ := HasEqDec.Build B testB testOKB. Axiom defB : B. Axiom all_defB : forall x, eqtest x defB = true. HB.instance Definition _ := IsContractible.Build B defB all_defB. (* Now we copy all instances from B to A via link *) Axiom A : Type. Axiom f : B -> A. Axiom g : A -> B. Axiom canfg : forall x, f (g x) = x. (* We take all the instances up to Singleton on (link canfg) and we copy them on A. Recall (link canfg) is convertible to A *) HB.instance Definition _ := Singleton.copy A (link canfg). HB.about A. (* both Equality and Singleton have been copied *) End Feather. (* ******************************************************************* *) (* ********************** Abstraction barriers *********************** *) (* ******************************************************************* *) Notation "n ^ m" := (Nat.pow n m) : nat_scope. Module SlowFailure. (* When building a library it is natural to stack definitions up and reuse things you already have as much as possible. More often that not we want to set up abstraction barriers. For example one may define a mathematical concept using, say, lists and their operations, provide a few lemmas about the new concept, and then expect the user to never unfold the concept and work with lists directly. Abstraction barriers are not only good for clients, which are granted to work at the right abstraction level, but also for Coq itself, since it may be tricked into unfolding definitions and manipulate huge terms. HB.lock is a tool to easily impose abstraction barriers. It uses modules and module signatures to seal the body of a definition, keeping access to it via an equation. *) (* not a very clever construction, but a large one. Bare with us. *) Definition new_concept := 999999. Lemma test x : new_concept ^ x ^ new_concept = x ^ new_concept ^ new_concept. Proof. (* this goal is not trivial, and maybe even false, but you may call some automation on it anyway *) Time Fail reflexivity. (* takes 7s, note that both by and // call reflexivity *) Abort. End SlowFailure. Module FastFailure. HB.lock Definition new_concept := 999999. Lemma test x : new_concept ^ x ^ new_concept = x ^ new_concept ^ new_concept. Time Fail reflexivity. (* takes 0s *) rewrite new_concept.unlock. Time Fail reflexivity. (* takes 7s, the original body is restored *) Abort. Print Module Type new_concept_Locked. Print Module new_concept. (* Module Type new_conceptLocked = Sig Parameter body : nat. Parameter unlock : body = 999999 End Module new_concept : new_conceptLocked := ... *) Print new_concept. (* Notation new_concept := new_concept.body *) Canonical unlock_new_concept := Unlockable new_concept.unlock. End FastFailure. (* ******************************************************************* *) (* ******************************* Joins ***************************** *) (* ******************************************************************* *) (* All structures which are not leaves must be joinable *) Module MissingJoin. HB.mixin Record isTop M := { }. HB.structure Definition Top := {M of isTop M}. HB.mixin Record isA1 M & Top M := { }. HB.structure Definition A1 := {M of isA1 M & isTop M}. HB.mixin Record isA2 M & Top M := { }. HB.structure Definition A2 := {M of isA2 M & isTop M}. HB.mixin Record isB1 M & A1 M := { }. HB.structure Definition B1 := {M of isB1 M & }. HB.mixin Record isB2 M & A2 M := { }. HB.structure Definition B2 := {M of isB2 M & isA2 M }. HB.structure Definition B2A1 := {M of B2 M & A1 M }. Fail HB.structure Definition A2B1 := {M of A2 M & B1 M }. HB.graph "missing_join.dot". End MissingJoin. Module GoodJoin. HB.mixin Record isTop M := { }. HB.structure Definition Top := {M of isTop M}. HB.mixin Record isA1 M & Top M := { }. HB.structure Definition A1 := {M of isA1 M & isTop M}. HB.mixin Record isA2 M & Top M := { }. HB.structure Definition A2 := {M of isA2 M & isTop M}. HB.mixin Record isB1 M & A1 M := { }. HB.structure Definition B1 := {M of isB1 M & }. HB.mixin Record isB2 M & A2 M := { }. HB.structure Definition B2 := {M of isB2 M & isA2 M }. HB.structure Definition join := {M of A1 M & A2 M }. HB.structure Definition B2A1 := {M of B2 M & A1 M }. HB.structure Definition A2B1 := {M of A2 M & B1 M }. HB.graph "good_join.dot". End GoodJoin. math-comp-hierarchy-builder-4d8a939/examples/readme.v000066400000000000000000000030551521677141400226230ustar00rootroot00000000000000From HB Require Import structures. From Corelib Require Import ssreflect BinNums IntDef. #[verbose, log] HB.mixin Record AddComoid_of_Type A := { zero : A; add : A -> A -> A; addrA : forall x y z, add x (add y z) = add (add x y) z; addrC : forall x y, add x y = add y x; add0r : forall x, add zero x = x; }. #[verbose, log(raw)] HB.structure Definition AddComoid := { A of AddComoid_of_Type A }. Notation "0" := zero. Infix "+" := add. Check forall (M : AddComoid.type) (x : M), x + x = 0. HB.mixin Record AbelianGrp_of_AddComoid A & AddComoid_of_Type A := { opp : A -> A; addNr : forall x, opp x + x = 0; }. HB.structure Definition AbelianGrp := { A of AbelianGrp_of_AddComoid A & }. Notation "- x" := (opp x). Lemma example (G : AbelianGrp.type) (x : G) : x + (- x) = - 0. Proof. by rewrite addrC addNr -[LHS](addNr zero) addrC add0r. Qed. Axiom Z_add_assoc : forall x y z, Z.add x (Z.add y z) = Z.add (Z.add x y) z. Axiom Z_add_comm : forall x y, Z.add x y = Z.add y x. Axiom Z_add_0_l : forall x, Z.add Z0 x = x. Axiom Z_add_opp_diag_l : forall x, Z.add (Z.opp x) x = Z0. HB.instance Definition Z_CoMoid := AddComoid_of_Type.Build Z Z0 Z.add Z_add_assoc Z_add_comm Z_add_0_l. HB.instance Definition Z_AbGrp := AbelianGrp_of_AddComoid.Build Z Z.opp Z_add_opp_diag_l. Lemma example2 (x : Z) : x + (- x) = - 0. Proof. by rewrite example. Qed. Check AbelianGrp.on Z. HB.graph "readme.dot". HB.about Z. Section Test. HB.declare Context (T : Type) (p : AddComoid_of_Type T) (q : AbelianGrp_of_AddComoid T). Goal forall x : T, x + -x = 0. Abort. End Test. math-comp-hierarchy-builder-4d8a939/examples_stdlib/000077500000000000000000000000001521677141400225355ustar00rootroot00000000000000math-comp-hierarchy-builder-4d8a939/examples_stdlib/Coq2020_material/000077500000000000000000000000001521677141400254415ustar00rootroot00000000000000math-comp-hierarchy-builder-4d8a939/examples_stdlib/Coq2020_material/CoqWS_abstract.v000066400000000000000000000054131521677141400305120ustar00rootroot00000000000000(* Accompanying material to Coq workshop presentation *) From Coq Require Import ssreflect ssrfun ZArith. From HB Require Import structures. HB.mixin Record CMonoid_of_Type A := { (* The set of axioms making A a commutative monoid. *) zero : A; add : A -> A -> A; addrA : associative add; (* `add` is associative *) addrC : commutative add; (* `add` is commutative *) add0r : left_id zero add; (* `zero` is a neutral element *) }. HB.structure Definition CMonoid := { A of CMonoid_of_Type A }. (* The structure thereof. *) Notation "0" := zero. Infix "+" := add. (* The type of the operations and axioms depend on a CMonoid.type structure. *) Check addrC. (* ?M : CMonoid.type |- commutative (@add ?M) *) HB.mixin Record AbelianGrp_of_CMonoid A & CMonoid A := { opp : A -> A; (* We can write `add` here since A is a CMonoid *) addNr : left_inverse zero opp add; (* `opp` is the additive inverse *) }. HB.structure Definition AbelianGrp := { A of AbelianGrp_of_CMonoid A }. Notation "- x" := (opp x). Notation "x - y" := (add x (opp y)). HB.mixin Record SemiRing_of_CMonoid A & CMonoid A := { one : A; mul : A -> A -> A; mulrA : associative mul; (* `mul` is associative *) mul1r : left_id one mul; (* `one` is left neutral *) mulr1 : right_id one mul; (* `one` is right neutral *) mulrDl : left_distributive mul add; (* `mul` distributes over *) mulrDr : right_distributive mul add; (* `add` on both sides *) mul0r : left_zero zero mul; (* `zero` is absorbing `mul` *) mulr0 : right_zero zero mul; (* on both sides *) }. HB.structure Definition SemiRing := { A of SemiRing_of_CMonoid A }. Notation "1" := one. Infix "*" := mul. (* We need no additional mixin to declare the Ring structure. *) HB.structure Definition Ring := { A of SemiRing_of_CMonoid A & AbelianGrp_of_CMonoid A }. (* An example statement in the signature of an Abelian group G, combining 0 and -. *) Check forall G : AbelianGrp.type, forall x : G, x - x = 0. (* An example statement in the signature of a Semiring S, combining 0, +, and *. *) Check forall S : SemiRing.type, forall x : S, x * 1 + 0 = x. (* An example statement in the signature of a Ring R, combining -, 1 and *. *) Check forall R : Ring.type, forall x y : R, x * - (1 * y) = - x * y. HB.instance Definition Z_CMonoid := CMonoid_of_Type.Build Z 0%Z Z.add Z.add_assoc Z.add_comm Z.add_0_l. HB.instance Definition Z_AbelianGrp := AbelianGrp_of_CMonoid.Build Z Z.opp Z.add_opp_diag_l. HB.instance Definition Z_SemiRing := SemiRing_of_CMonoid.Build Z 1%Z Z.mul Z.mul_assoc Z.mul_1_l Z.mul_1_r Z.mul_add_distr_r Z.mul_add_distr_l Z.mul_0_l Z.mul_0_r. (* An example statement in the signature of the Z ring, combining Z, 0, +, -, 1 and * *) Check forall x : Z, x * - (1 + x) = 0 + 1. math-comp-hierarchy-builder-4d8a939/examples_stdlib/Coq2020_material/CoqWS_demo.v000066400000000000000000000145441521677141400276400ustar00rootroot00000000000000(* Accompanying material to Coq workshop presentation *) From Coq Require Import ssreflect ssrfun ZArith. From HB Require Import structures. Set Warnings "-redundant-canonical-projection". (* ****************************************************** *) (* ******** 1. Building the hierarchy ********** *) (* ****************************************************** *) (* ******************************************************** The set of axioms that turn a naked type A into a Commutative Monoid. This would be the puzzle piece. *) HB.mixin (* an HB command *) Record CMonoid_of_Type A := { (* and its argument *) zero : A; add : A -> A -> A; addrA : associative add; addrC : commutative add; add0r : left_id zero add; }. (* ******************************************************** The structure of Commutative Monoids This would be the blue dotted box Note: { A of ... } is just a notation for a sigma type *) HB.structure Definition CMonoid := { A of CMonoid_of_Type A }. (* ******************************************************** Monoid playground *) (* Operations are now available *) Check add. (* Axioms are also there *) Check addrC. (* We can develop the abstract theory of CMonoid *) Notation "0" := zero. Infix "+" := add. Lemma silly : forall (M : CMonoid.type) (x : M), x + 0 = 0 + x. Proof. by move=> M x; rewrite addrC. Qed. (* ******************************************************** The puzzle piece on the right and the AbelianGrp str. Note: it requires A to be a monoid, indeed the property talk about both add and opp *) HB.mixin Record AbelianGrp_of_CMonoid A & CMonoid A := { opp : A -> A; addNr : left_inverse zero opp add; }. HB.structure Definition AbelianGrp := { A of AbelianGrp_of_CMonoid A }. Notation "- x" := (opp x). Notation "x - y" := (add x (opp y)). (* Quick check that - and + and 0 are compatible *) Check forall x y, x - (y + 0) = x. (* ******************************************************** The puzzle piece on the left and the SemiRing str. *) HB.mixin Record SemiRing_of_CMonoid A & CMonoid A := { one : A; mul : A -> A -> A; mulrA : associative mul; mul1r : left_id one mul; mulr1 : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; mul0r : left_zero zero mul; mulr0 : right_zero zero mul; }. HB.structure Definition SemiRing := { A of SemiRing_of_CMonoid A & }. Notation "1" := one. Infix "*" := mul. (* Quick check that + and 1 and * are compatible *) Check forall x y, 1 + x = y * x. (* ******************************************************** Can I mix * and - in the same expression? *) Fail Check forall x y, 1 * x = y - x. (* ******************************************************** The missing structure, no puzzle piece is missing *) HB.structure Definition Ring := { A of SemiRing A & AbelianGrp A }. Check forall (R : Ring.type) (x y : R), 1 * x = y - x. Check forall x y, 1 * x = y - x. (* ****************************************************** *) (* ******** 2. Declaring instances ******** *) (* ****************************************************** *) (* ****************************************************** Inhabiting the puzzle pieces with Z *) Module Z_instances. HB.instance Definition Z_CMonoid := CMonoid_of_Type.Build Z 0%Z Z.add Z.add_assoc Z.add_comm Z.add_0_l. HB.instance Definition Z_AbelianGrp := AbelianGrp_of_CMonoid.Build Z Z.opp Z.add_opp_diag_l. HB.instance Definition Z_SemiRing := SemiRing_of_CMonoid.Build Z 1%Z Z.mul Z.mul_assoc Z.mul_1_l Z.mul_1_r Z.mul_add_distr_r Z.mul_add_distr_l Z.mul_0_l Z.mul_0_r. (* Now Z is recognized as a Ring *) Check forall x : Z, x * - (1 + x) = 0 + 1. End Z_instances. (* ****************************************************** *) (* ********** 3. Being nice with users ******** *) (* ****************************************************** *) (* ******************************************************** Crafting special builders We provide an API to build a ring directly. A factory is a ''virtual'' puzzle piece that can be ''compiled'' to other puzzle pieces. *) HB.factory Record Ring_of_Type A := { zero : A; add : A -> A -> A; opp : A -> A; one : A; mul : A -> A -> A; addrA : associative add; (*addrC : commutative add; *) add0r : left_id zero add; addr0 : right_id zero add; (* new *) addNr : left_inverse zero opp add; addrN : right_inverse zero opp add; (* new *) mulrA : associative mul; mul1r : left_id one mul; mulr1 : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; mul0r : left_zero zero mul; mulr0 : right_zero zero mul; }. (* The ''compilation'' of a factory *) HB.builders Context A & Ring_of_Type A. (* We are in a Context with a type A that with operations and properties, but which is not yet known to be a Ring *) Check add. Local Infix "+" := add. (* We prove commutativity as per Hankel 1867 *) Lemma addrC : commutative add. Proof. have innerC (a b : A) : a + b + (a + b) = a + a + (b + b). by rewrite -[a + b]mul1r -mulrDl mulrDr !mulrDl !mul1r. have addKl (a b c : A) : a + b = a + c -> b = c. apply: can_inj (add a) (add (opp a)) _ _ _. by move=> x; rewrite addrA addNr add0r. have addKr (a b c : A) : b + a = c + a -> b = c. apply: can_inj (add ^~ a) (add ^~ (opp a)) _ _ _. by move=> x; rewrite /= -addrA addrN addr0. move=> x y; apply: addKl (x) _ _ _; apply: addKr (y) _ _ _. by rewrite -!addrA [in RHS]addrA innerC !addrA. Qed. HB.instance Definition A_CMonoid := CMonoid_of_Type.Build A zero add addrA addrC add0r. HB.instance Definition A_AbelianGrp := AbelianGrp_of_CMonoid.Build A opp addNr. HB.instance Definition A_SemiRing := SemiRing_of_CMonoid.Build A one mul mulrA mul1r mulr1 mulrDl mulrDr mul0r mulr0. HB.end. (* Let's use the new builder *) Module Z_instances_again. HB.instance Definition Z_Ring := Ring_of_Type.Build Z 0%Z Z.add Z.opp 1%Z Z.mul Z.add_assoc (* Z.add_comm *) Z.add_0_l Z.add_0_r Z.add_opp_diag_l Z.add_opp_diag_r Z.mul_assoc Z.mul_1_l Z.mul_1_r Z.mul_add_distr_r Z.mul_add_distr_l Z.mul_0_l Z.mul_0_r. Check forall x : Z, x * - (1 + x) = 0 + 1. End Z_instances_again. math-comp-hierarchy-builder-4d8a939/examples_stdlib/Coq2020_material/CoqWS_expansion/000077500000000000000000000000001521677141400305215ustar00rootroot00000000000000math-comp-hierarchy-builder-4d8a939/examples_stdlib/Coq2020_material/CoqWS_expansion/withHB.v000066400000000000000000000011671521677141400321020ustar00rootroot00000000000000(* Accompanying material to Coq workshop presentation *) From Coq Require Import ssreflect ssrfun ZArith. From HB Require Import structures. Set Warnings "-redundant-canonical-projection". HB.mixin Record CMonoid_of_Type A := { zero : A; add : A -> A -> A; addrA : associative add; addrC : commutative add; add0r : left_id zero add; }. HB.structure Definition CMonoid := { A of CMonoid_of_Type A }. HB.mixin Record AbelianGrp_of_CMonoid A & CMonoid A := { opp : A -> A; addNr : left_inverse zero opp add; }. HB.structure Definition AbelianGrp := { A of AbelianGrp_of_CMonoid A & }. math-comp-hierarchy-builder-4d8a939/examples_stdlib/Coq2020_material/CoqWS_expansion/withoutHB.v000066400000000000000000000076531521677141400326400ustar00rootroot00000000000000(* Accompanying material to Coq workshop presentation *) From Coq Require Import ssreflect ssrfun ZArith. From HB Require Import structures. Set Warnings "-redundant-canonical-projection". (* Helpers *) Notation "[unify t1 'with' t2 ]" := (unify _ _ t1 t2 _) (at level 0, format "[unify t1 'with' t2 ]", only printing). Notation "[unify t1 'with' t2 ]" := (unify _ _ t1 t2 NoMsg) (at level 0, format "[unify t1 'with' t2 ]", only parsing). Module CMonoid_of_Type. Section CMonoid_of_Type. Variable (A : Type). Record axioms_ : Type := Axioms_ { zero : A; add : A -> A -> A; addrA : associative add; addrC : commutative add; add0r : left_id zero add }. Definition phant_Build (zero : A) (add : A -> A -> A) (addrA : associative add) (addrC : commutative add) := [eta CMonoid_of_Type.Axioms_ zero add addrA addrC]. Definition phant_axioms := CMonoid_of_Type.axioms_. End CMonoid_of_Type. Notation Build A := (phant_Build A). Notation axioms A := (phant_axioms A). Module Exports. Notation CMonoid_of_Type A := (axioms A). End Exports. End CMonoid_of_Type. Export CMonoid_of_Type.Exports. Module CMonoid. Record axioms (A : Type) : Type := Class { CMonoid_of_Type_mixin : CMonoid_of_Type.axioms_ A }. Record type : Type := Pack { sort : Type; class : axioms sort }. Module Exports. Coercion sort : type >-> Sortclass. Definition zero {s : type} := CMonoid_of_Type.zero _ (CMonoid_of_Type_mixin _ (class s)). Definition add {s : type} (x y : s) : s := CMonoid_of_Type.add _ (CMonoid_of_Type_mixin _ (class s)) x y. Definition addrA {s : type} : associative add := CMonoid_of_Type.addrA _ (CMonoid_of_Type_mixin _ (class s)). Definition addrC {s : type} : commutative add := CMonoid_of_Type.addrC _ (CMonoid_of_Type_mixin _ (class s)). Definition add0r {s : type} : left_id zero add := CMonoid_of_Type.add0r _ (CMonoid_of_Type_mixin _ (class s)). End Exports. End CMonoid. Export CMonoid.Exports. Module AbelianGrp_of_CMonoid. Section AbelianGrp_of_CMonoid. Variable (A : Type). Notation M m := (CMonoid.Pack A (CMonoid.Class A m)). Record axioms_ (m : CMonoid_of_Type.axioms_ A) := Axioms_ { opp : A -> A; addNr : left_inverse (@zero (M m)) opp (@add (M m)) }. Definition phant_Build := fun (s : CMonoid.type) & [unify A with CMonoid.sort s] => fun (c : CMonoid.axioms A) & [unify s with CMonoid.Pack A c] => fun (m : CMonoid_of_Type.axioms_ A) & [unify c with CMonoid.Class A m] => fun (opp : A -> A) (addNr : left_inverse (@zero (M m)) opp (@add (M m))) => Axioms_ m opp addNr. Definition phant_axioms := fun (s : CMonoid.type) & [unify A with CMonoid.sort s] => fun (c : CMonoid.axioms A) & [unify s with CMonoid.Pack A c] => fun (m : CMonoid_of_Type.axioms_ A) & [unify c with CMonoid.Class A m] => axioms_ m. End AbelianGrp_of_CMonoid. Notation Build A := (phant_Build A _ id_phant _ id_phant _ id_phant). Notation axioms A := (phant_axioms A _ id_phant _ id_phant _ id_phant). Module Exports. Notation AbelianGrp_of_CMonoid A := (axioms A). End Exports. End AbelianGrp_of_CMonoid. Export AbelianGrp_of_CMonoid.Exports. Module AbelianGrp. Record axioms (A : Type) : Type := Class { CMonoid_of_Type_mixin : CMonoid_of_Type.axioms_ A; AbelianGrp_of_CMonoid_mixin : AbelianGrp_of_CMonoid.axioms_ A CMonoid_of_Type_mixin }. Record type : Type := Pack { sort : Type; class : axioms sort }. Module Exports. Coercion sort : type >-> Sortclass. Coercion AbelianGrp_class_to_CMonoid_class (A : Type) (c : axioms A) := CMonoid.Class A (CMonoid_of_Type_mixin A c). Coercion AbelianGrp_to_CMonoid (A : AbelianGrp.type) := CMonoid.Pack A (class A). Canonical AbelianGrp_to_CMonoid. Definition opp {s : type} (x : s) : s := AbelianGrp_of_CMonoid.opp _ _ (AbelianGrp_of_CMonoid_mixin _ (class s)) x. Definition addNr {s : type} : left_inverse (@zero s) opp (@add s) := AbelianGrp_of_CMonoid.addNr _ _ (AbelianGrp_of_CMonoid_mixin _ (class s)). End Exports. End AbelianGrp. Export AbelianGrp.Exports. math-comp-hierarchy-builder-4d8a939/examples_stdlib/Coq2020_material/diagram.pdf000066400000000000000000001200731521677141400275430ustar00rootroot00000000000000%PDF-1.5 %µí®û 4 0 obj << /Length 5 0 R /Filter /FlateDecode >> stream xœì½Í®%=®%6�§Øcç8¤�Š©' x`{ØðÀ8vöãäà¶ýúÖZ‹¤{ïü*³ê¢Ñƒ[…ª<äV臢(Š"©ôØÇ?Òø¿cÏŸù:ööøú¹ýÛ6ðŸûÙË‘Ê#=þ÷ÿùñ?þ_ûã?ÿ[úÜ÷½�ÿ:Jü/ãÿïöŸŽËãß”[ú?Guÿ÷Vÿëã߉-èÿGÅ)íŸU–ô™Zyü|¦îóø~üõ¦Ðÿñøß~Ùοij‚�|¤z~îµ>®òY®<¾ÿHåúÌ-;­¼–ú×[1L-{ý§šy&˜U嵈`cfCн”ú£F¬k ÷ÞÑÅ´Ÿç~m¼úך„&æ_o!íý³æãk曘”¬L:MìŸ×qô«¦þO�ÒgoçÙOoîcTVÏZŠ âìb`�ÞË •u£÷1 w|¶kô¢ŸŸù<�ÈŸíl�^?¯QœðÑú£—ϳ|ÕãñõèãËÚ7ÕQ à´³†òÙk\ÆpÜ¡º¾è™�žŸGb�×E¸�qÖíÑÛg.§ \}¬q£íß�Ö¹ŒÛ†ú‘æ"}81ÞžG —ÖÚ9&bô¯�J3²ýºˆ¨¥a� S…�Ò1†Œ±Ö1%E¸3]B´«DùÜ�*Äèì@ÔÁ2+b‘68§i™÷4jѯCM×Ú‰Hí°qO!öûÜ58縰êêà©nÜ%Ì ùYCrÝK‘¿XÉ�¡ûgmíÊþ?!`%Xêg?Ú㪟µ‡øÚ{`L®<•BS¿W›a 5Žãï«{#Žð‰—†¨¸¸Zãâè^êmeÖ‚Õe߆Bá¹ÐïUî÷kzîz5VSKK¯~ñá`ÂtûÎ(sûnð@Ny/ƒ$Sòyµ±þL˜èÂ$‹ãSrk‰!Ms\Cz�±¤Î†��>„ÆõècAÔKpëú ˜1›PÇ‘çø²tÁc]Þó¥*ëXð_�sü�Ôjm ð’¼ÁËk|ÑÔ­±D÷¬F )PˆííD·r>TâÝ€(HYpɾ—õðo$åǸ>uNÇAÑ!$ õLÿôm"³õû·âŧoïÓq›ÿã&íÆþ Òt�®»´Ûσæ*&ƒ[¹$ƒ“A¥RüË”NÉ�[×^M Ž]eøI…¬e3{/.éνÕ‹àYÚ¯A’¶©Ö¹À+ÞÎ~�Ä´b‚ä»@øn’úbH¿w³òÂäwž^¹|®´×Rª÷,×øÏÛzóèÙ`ʱ9sõ>aR›ÖeL™’ðÖÆ™¢ï¬ð¿üçÇ"s�:6­ëíªµ–¹ÞZ7F]Ý µÌïØrSï¢åq�Ñ�ERÈ•Vä{)2¶ÂŒµýõ¦¦ÿéxåø'Q=jj£ì”ÔÇ96Î~ûÏe~!õ_ª2ÄM濯ëÑ Ï7Ä*ð£Ìß é#qb§¸7Ä"££ÈoÕã°ˆõÛÕ<5?}ôçïäüò•Èqûê�¤üGbôÀ:½>�†T™˜D6ú}ÿ^C”`õŸû8,„nùEÌÐ7¢ áÆûlù$\j~C<5Ö˜¯$‘2¤;êÞÇêg#uÔš…¸òA™b»Í>T¯~XC­e¡:ÄÜèÚY qRÑÍÔ¶‰Ècá íî {›»E^�½§é‹zl0÷Ńÿšœs܇.>(”$剨�fªè~~Ž£ñÏ¡�yœi.½mçØ)?©¸p¥Çï�ê/N!ƒ†cCº2‹ã 2„JÚ°ýžs”1?ú¸b·G²Ëj{Ày Ä! ��ç øYÔØØCú`Ð�¬ Ò_z®§—2ïçâ?fñ¿Ý,Ú8×á¦Êò#¤pPïc‘ÕoÊiN~¯FG-ÜñËÿý8íå4¦gMŽXjz.ó›Àg›À/¦b(z8C¿Õ^ÊLq²ªÿçM×ùù€Î8ÓT~Þ~–Gß�õ+5rÿê6©ë<~¼Aã ”p«CE<`!b�gœOŽœq²ª£_5¶q|:ÏA¼‹`©˜ž³qùoÀä!ZÌcM•Î{VQ¿Â )1Òf´—3?QzLé8ƒ��KÅIaÀµ±ústkÌZq|vBUåÏרu@ ‚i€GÏ¿³‘Ø‚›ów_�ë¢|3¯‚%æ"0¬ì¥ÔïÖ˜Ø]~]Û¯ìç“:lˆ›ýãüÖôÔE¾âxw< ì—R¿_�cViý‹êžÆi±> ^úõ\âo«qAyÿh­æ¿…Êom÷ÝÛ^zóğ韛éuËÒùL›'øÕÜÛþu5o6jc¸�þœù9¶7Åþ Â@-ýûe�ÿ!�ÿ;Èw¶\Ì«“OŸ‹˜ å~õg&ò´ÚË“ÌÿîÞjL^iÔY$&ωˆ[«µÌí¾çµÀ{•ÁþñUXšõ?—ø—ª78ýýŸªþ�v­ >büN¤�…JoÊý{´ä(�ÿÙ–^6Z}õütr†ÓþRê_m%0F¾¦•eFŸ ¹füëˆI¯—2ÿT F¢¥…4WÈs™?já¾"´þó}‰<ù³Üë›k<½®ñiÆðû …žKü3ÕÇüõ—)~.ñ�8õÙ «QwgA_m}®†—2ÿj†°™ý'šxÏEå™‹Ê ݤÆb€ÿ½KÏýäýA›>.+~êŠëG™Æñ\îW÷žï*tTŠÄ?¨ðÍ ¾ñâƒGå¹Ü1d÷—R¿¨Lm]¸ÃhvÛ�ï ¡ªžÊünMB8ñþ¤ª[0ÀÄkúèÔûÏŽ¡�Çú™èrûì�l!£Ýsç�Jù¬'ôbhÀ }èkP7�{ësŒ•W˜¸vÁ f¾à‚° sæúÈXx]_¤¡Lq¬—àkÇ[Æ]›Úlµ³€nt -mT¹« C£ o`š<7†"“Ñäeð1º�Nö¤/z:ëÒÓfíɨõvµk¢~yé¹:ܾ=íõöíšQkÃk^)Ÿ\HD�¦ Â~¬²þ]É_ž§ßU:q“ƒ~]é¿#?>WeMΪ q«ê¹Ðì!ÿ�ì!¿˜‚ÞÜCë�nñTæ­ù¥ï7m‰ÎGp¿™êÓûÏ´R—ÏÔÊý³?3Ûtú�Ã\ã]ÄOCd«­°« ºÃã0¥!6Ƥž§¹á¤Ên3„æ& .éÎúÙxÍ�+fä/8*l Sy“ǣɒY@-À³°n@\ϦêÉ 6xeô p^“ÜXÐÃÓ¾‡…é7æÑÜœÇû \å›yüx�È�-1%�áYç¥Ôo×¶?ï?¿®íWܺ?iÕ†¸që¾Dx,W†ñè|ÔAF7W¥V[vs•€±uGÊåv�ÚÇ�E¶à/zÑÛ(Å!¤åÀØ‘á©T¨þÕ¶ 3Ä!ü¾þ¹Æf;7ùŠ ½.06ÍíÏ¥þ™¦ÔÍ+�;ÚpÖâÍç½È¿G+‚}²~ÕÊï8þ¾Û¼�Ï£š‡ÀX°®4]p g›÷KÉ¿÷aÿÍÆ&n§ÏÀß5ö7cü•Ç*‚Žl`!Öæ^ ½دZÈCbQ×QÙÏ£¶½œ6_Oe~wž¶Ÿ!iSc5eYø¹z¼cI )5t"þQØÇóæva‰ ³rï‡|O†HkDÁ9èc_®•±Ï½á Ÿ.ö*+}ìOú²G“‡¹øŽ­ä̼(:è÷¯ÝgüïÚÓl�!;ã�µƒí ®+iS%ÐéOx@IC:=¨ÄOòþyÒ5Ÿ o0\c¯@¥TnòÐŽ¡�V/*L9“¢ÿзþ°ß˜øº0Ÿ1ÚÊ{VâOãã…3bÝüT}£¥—"ÿ˜9žZ(¦ î\�ŽÒâ°…ôR柤Z†æ‘­í›8M öµ–ø“Û«uº†nÄ8Ú�¥ÙaÔþ\âOjµõÁÈWºªvÀƒ­ql#‘žJüsÅNOaô´)ðaO\¤†‰íõVê—æÄ×Ú„Á_úûڞǯ/¼0kA9‚x.ó¶&kX²¯ öyZKüV5;½~»ž{ódÇèÎû�( ã£Åí›?:ù!H ŸÚ,3·*`.z=AfWó �¢0"8ÒC®]8Q|=Ê�‡»\¦ lˆ]"Ô!àÉ� ÜQ®‡¿€à}2OÊCÒ¢@r·§r<è�/pœF7ÕÊu*¦“Í7\¹†³>zGi?>©¹ÿžÑPÓôa¤“ÛÇa~mLfAWþ¥øíþåŸú]žch¸TG]nxOØ¡+u™·#´BÜt·î: ‚Å¢&3%í×�Â�8þ+—K!γ?Ìåòd½ã€í^˜1hü\+¶¾z��í–°ó~Ìbîîé™qÀlCšð2 £@ðÌ�ó2~0Q¹~Çbxgäe‘ÏEõ\äWæ#[|S|´ì~zSf¼)÷'5jvð—5> õÆ?ijw/eþ®¦)Šî_-ý·iÖ¢{Ö�­ö©ÄßV“ŒŠÖ¶Ák5é7è<«¹µýëj^ÀDõGŒ>¦zÚk©ß¯Î1Kß~UݳŽ�Ö}•ên‡Šêûìû�dÁ™©ÙÛGds:`]ÖF pâ@ 6dæ8,_ˆ¹½†¢g€‰Þ¸mlПǹ÷Hp˜cl0°ìqŸ² >gˆÒª¬­0†7©ÔÌ�·è÷,ßßtÝÛW:ÿŒêËiGB¡Fû‡v¦k4�Î!N [Þþ6Üîýr ¶1º­üùTB5þ:¤ ¾L8gÑ5˜&»;bœ'*j‰ªÞ9†Ï€Á⇠Íî/ùîÑ\ÏÁ\)}2Cv�†²›“Ð ‡C.ÇqÜ©4ó¡ÌEŒ—©¼¥øÞ¨J?WeÑ\cƒúC}¾%%hÏÃÁ2ˆ˜”}á¥Ì©ô/ tYs ñ¯70h“UVâO˜Pq‚tx.óOŒà:ìýwŠ"RýØŒaøÛþ¿”ù£qzë J®¦}·úŸŠüá©ÊNd¶Þ÷“UÚ©êVâ÷Òw½ñà ða1¯7CQä2Þ†Z^ þÑqúµ�LOJÖPx+9DÚÁ}%SaüƒËGX\Âàö–¹•Á²™’áJûÛ1$x>idÌvZYda‰Ç­e­ú}ïŒÄÀ-åY6VR¡ "€›W'c<{c�ÎOC¬íÚ¥vŠTÚvÉÇ#oº-í×úO[[l…ŒíZr,"[1ËŠ¿Ë%¯ •’¦�àn0°†n%4‘½�#±‰4A%¹¦¿i =>å}c²,cŠh žÌñ¼@Á†;ÕA«>€?N€�ø-ûï¢G5Z<ð9íO@c'ósý©u1Xܘ>-æÅ8^\_¼ õóì¸  ïõÉÛSjU�žÊGÒ©Î�å�ÛV,ˆAíáÙɸ`Z Y4?òPËrQECÊØä.Õþšjßæî¿8"-`lÛÈ «·s3Ä¿¼h8Æ"M¸<‘�Æém�b@cim_€i~Ît;À®Þø%³÷4]³ úzð°-¿î0Wd\ë�Kl”çO\HVÂTnª:ŽÃ ›KVQƒ\(âËA‘6ЯjlE5 wEy1߯qº�KöñIjòî*¨ÄÃxôsâ•Ë€;yÎß�‚{aCr!À¼°ö/Àp>2út1™ ¼Ä‘qÈ Æk¸¯†2Ÿ˜˜`¨³à{(XÛÉ1m_šÀò6‡‘äBÀãÉÞ�Dr#íŒÿZ?¯Q 1È‚¡b«9E+Œ•žºw�¼èÇFQapxlß,\Ø{\q n47 ïG"õÕ'¦§a/*Í™=Î��æóØ–À-RÔ×Xéø ±-²� qÖ>¯Ë¨M߈AÀëÜž¹šXÇÜ9h‰[ºxpLËEÞÆ¾{URõëÁh‹“…±ütèç±ØÑÙ+ó·�i8@틼©õ�‘ž…¬sök ²µT4d$RtÖDú6rl;ó!Å0â*85T-%Å(¿8û]®|Aß¿ šÛØÙa5¸$Ô‰b°")ƦmÉs&<˜¾!LÇ&¿ÎsÃ͉œÇpÊ,+÷%)”3Y§ÌÁÒYZŽA_€{Àüž“Økð劘–‰_èÍŠ bq‚¹È•…&s²G\G[ N:Z|/ÅOÕŒ-_èEZWÖ}4vé*èÒèá\¿èÿÞçêfHO¬ý%�Rn­±(¸kcŒÐ8s�V@¶VÐ$2¿.êíøð�8¼X)5ø’+ “1ÎwâL:Ær_}Gg±uÄ‘ÑÖc¿2 kJµ¤¨<$^œ€—ˆóGánpç0Šg,C†!9\H~´T8n¡çÞ„½z¥œ"÷iË.‘Üà}ƒ8Øë(ñ«Ø_‚ ¹£`¢7F†x�}Ð að¶òÁÏ Œúûnc�ȼnþ¤kSSÛcU¼!rá" Ö�“�gæn9v^^á:ø@�üN=ÍÏØ²4§åH¬ÑÍî`V:2ï5¡ÎžôøDˆÌLk–Ú]Œ¾rø¤ úF;$ámAŽp…ëÁnj—ÅòC+›ß;6eˆ&¨"ÌA¿³+g‡H Èÿù+$¾«�ŽÆØÅÈ*íO0×펃‡J?:( ½®5 !©L`Ù¡âQ7ÕŽÕHÑÏ;5WòމŠN›Ü$�×ó×Öƒ×dó¯¥0&Ê–>É—_†CNÝ——áÓ¢û±E[6øó1N³\Õ6^ƒÇ‹ë=Ý®Àãv>ÿÂ-�gS.½¼Ã¯5Œ>]R…Rä'’(]ºª(�Æ’-£ rŽ]„¤M ˜ž¡ÿl-eÑØÀ[âfuI÷<~?{Zkëq*i’µ�£)Nà‡Ôª½: ÜAUóPt,3Fˆ|Õ1€#MŽ„…à*=i¾ Þ`($CnÑʼn_Z5‚9�S×ㆉåqAÖ‹bCyÙxôu‚Hš¯6øÉ¡Ãô‰ CWÁ4OÐè�¼åÄÖiúÚ¹´©!ý“M[á'÷gú�yäú(TÇæ¾¤É öápÿÐOÅt΄õÄö®Áüæî�5Ò@tK/mñeæÞäõfRõ+šÍŒNö.qÞßl íË çØÈW’wjçáÊs0˜ÓJÏ•ç_7þ…¯<‡}¥yù¹òžk}ºÐ;Ûâ~> Œ>ôPån°ï®U÷0~àîû8æ‡Ô¢Úñ4O—¤�òHKzÄŽ0{ ÑÊŸá­4Þ8ˆnÑ&¤£¢Ãp€Ý¼óŒŒ�h—òB²�ëqÉ"‡éÃñý’�øßìNWü–´ð.ªÅÕ6ÁËfg«ºñÆÍ¡ÜK Ç]äÊJ´Ìø»ÛñÕKuªá¨`Ô¿Ñ †U ÷âvºCFtÊŒªŒ¾ÓX6Bj\ƒØïqfÜâ烉|Qo?I÷DHgÐã$á°;¥e´ñ°(V‰ŸqHúæÇœ~XjPóqÉÅš²´+±Äº0ÏHå�C#òœfœ sQèO`I1öa$#®ÇfÆž/ÀfqÂÞ?£œeÑI«<$[³¹ñîM°a’/N:Y�$P¼¿.n4š�F«I*'„‹1'“ô]£à!F9\^Ó,ôµ (>�É |]?6\¬VÚ‰*»¢ëXaš‰h^¾ŽòÀ0/E.,«h%m 67ÄË0Šƒ7LÓØ0%ÃrQT)íµY»¦Ã_¼ƒ¡M˜�(¬¬YI²…?À€ H˜ ZƦáQ0úÕ�«f‘KYͽ ä¹/K#˜l™S½5édÅrU|(ÍÁF #’i_i¡ê´ÑI«Î�Ar$˜å •M Ìê Ç$ic6OE=áO¨4 fÞø,pß½YÿŒ“h>©ê³+Ó¼ Èáͪ@âúd^p›hâ�ú¸:kMCÁ® ˜ÁØðé;óÏIrÌiA¬AüÕólœœÀ^ .†ê½°bÕ5 �›Í‘¸ÉK%Û)‘m%£|Mj"l ×¢öFÄYÏ+‰Ë—Õ…×(XY3•&Õ… ƒ™Šûu�FR|°QŽ2ËlŒGAÚ‚å3Ç`‚!ˆÏØØ+ħ,VDÓ&¨1ý>šÇõÖŠ9™ôÇ? ĬWÃÚÔ_oÆ:Æ�T›Ü=›�4ó)°~·U¥»ßÏà¤‹Û &pÆ|ŒƒmÇŒþ&|ùRq ÜG bH,Ck£î¾,Ô,W°Ÿ÷ËËØ`à<Ûͧµà5œÏ œŸÕ;@¨ÙïìÁí6+�1öÿp—`Õ/4²öIÃÍ;¸Pø6äTGµOzPÆ–nÔÈ®Ù[ã„:«@Þò\‹„-o�ë¼Z×� ÏQ¦îºÁQ¢SAUÞÊBjëD‡nÝtq4çÆä¦ò\&ÿ¨K…úÙÚDY{AYÀ­—ÛDÜLªU¤°FjUÛM‚ èç$÷:ïæçÃ/Î,úÚÎ혹(KŽ�è ƒ¯`ÃØn¨ªÔݽj0¸³2øF…H:0ðJ wQ$Á¤�yÚ5RÒå�Á_ÄЧf)¡?tõ†°7\–‘^0æÕ²:Ë`úø8‰¾ü6Ð1‹¨£!v{E±e=Ó2+z‡�'L»’fKü ªséÓô»Ä€“à¾ë­‰jN߯„ü¦c]‡Ñ”+Óæ¿Pd…üWÊ`ã¸Â<ë[trå†üÇnôÂ1?6ñß¾?¥_e Ä@[gLKÎâelnI ¿Ø©ÍËrÀ±^c�,òØ›˜òÒûàÕûè×G1Wq9e&[‹\i©¡¿´Ñ­ “Ê\§ur›ð2 ǘTö\.{ ©ÎOç#ÒR~“Ô÷ÉФ9Î%3´Û29¥óhr¤˜Gõ5X!µ-‚¹ÈWi.%‡çÀ ã‚YU,‚Ù[Yèmýp¹j½t±»L�K‘f³EjˆrÕ (ˆµ�ºvã�€~œ„dvÄ2ÇøXk�i7ÅŒ�,äb7ɬŽN‚ßæãí�eÍ©¶�*z%£aLÎ8fJ'ÿÊ1ôr�ªªy7ͪª»’¦Af/59â]=èf3Mú4¬‰™uŸ¾HÛüf{Ei¹Iƒ¬vòÃyÅãéE£—k�©Õ˜~yuXéo•7öÁ1ã8Û®yù"Í͇î™ÅT…ˆlÇó �Õ)õ€É~8^ ,žÚì“ÓÖw³"¬Lu-�€©ÌSE7EqRU?·`*Iì>TÿÝ(áû‰ËvœíkÒ{GhôÆž�“îÓT“qa[¨SUþù „ÞaôÃ<ˆêᢺg'¸˜yN�WÆ´c,Ožd¦t4_k‰ª�^5lI;ÖFt•4;áÌå�ô¡Å²Žô=È«à•g˜2�󽮓x7!£;•ûj�™|¬†1b,UˆXK‡d½>ÞÍû„¼Ÿ¤ "½x5‹;nEnÃò ÄÕã™–lÛ$n:3A(z_D gãõ)ͼüä%°¾†Ú�¹I}é4:ªaêõt =a<_¦Ú˜Îþ�¼G¦‚Ÿéí•iƒ'„­—̇¬òŒÃa‘Gï&3"`�7Ú‰ ”é§!C|ODtH×_‚·qX& Ô »Ê‚�je ‰^Tð2Í�ôì©W7 ÂÍ ¦ðHrѧä¨× ^’2ŽPÄ1“gpkän�@–_�ʃA²´þ9�´Üf KC“CQ/UaD‚ª½ y"äHg£É¾k–°]d~5KX2¨÷8E¡Æ.S298GL}˜0´ø¼(Û­W_Hï¯ui�Óx¬ó›Ão‡ ÛÂN–ÀtŠ¿Nœ0C|O„³Šað_³ŽLf^êÈÎÝŽ88¢¥G¼©�;yw†¬Š }Áü¾€í³µ˜÷Cgz¬I“cG“›š<1uÀDJ„¬'ïrò«‡îÏnv„…öÌ穚…�W¾dWÞŠ‘œadîJ¹‰ ž+Ö1´ãiäÛ4mó‹9q† Ëòz©²©ººÿù©žP?rŒo'gà”&Ÿ�ÜHå§ïãrP&�ýš?Ë/‡43Â1 sô8K˜Áåô¾Å¼ê6êiÞušb…LÄ 8-A š�Fu“†ÕiY8:`Fj±#ç��˜S¦òšÀl§ç«¤³2%®~Åõ{éñåA§¤m©›™Ú®hû¸xCä=sP=ÿZ°zlñyWJ~Õÿ°üA_³ýnÂÖ¹n[´õ�àfCÅÐüwÝ@Æ×F˜¨Ý g­Y7ëÝÝ¥Ïgíw�_LEö PzŸ¬ËÈM&óœ«áwøáßrÞTA j2ð�FN½½c ¦"×øŽcÙ„Ð<´óÂ7MÆôC÷@p]^¼&@[§&fWå»4'Gì¼õøöèˇ(Ö‡öv*lo?”ï¬[aòÜN!s즬"F¿mk,pXމ»'j£&šx… ks�™Qp:çÔÇ_9B~ÀßDÀ•U}êÍUK„7¼#ù÷0ÓÁ;«Š±Îê[��Æ cJ“X›V€\½¨]ÒµÛnćó%Ÿ»–MìyœÆ÷¦ëÇ4*fñy•¾æÕW§”7_x¨¶®Å­›õ<„—̤—ÛDŸ“¥øÆ.²A¸a¢Vñ”‰LÎuB2ûêáýf ý  îQ Aþ~Eít9¹ù(,ÕwˆÊÇ…ƒß††�:„Щ²º{5÷f¨ñ5ß;‚¾à@V…ÉümA$õl~³»gµoº2Ôvš}.u ÏÁÅÙvùÓËS`•Kla(-¹Ë»E‡Vs„ËÒ€ª9¾e ½‚ƒ÷ß;�hñu×SV³þ�9Òl¿vh½wì»'¢Rpnñ¹b\¬~Þ”óñËh¿Ù ªõ®Ù�ÑzßtâùšÃ³}|îÔ‰ê�zÖ¼h»y÷žˆ¯ƒ’ @3õS�WO¯"@¥K$�âêY!AÙºGŸ&z›o„é´�í´zÉA úG·+û½™Wc–I°éå ÌÕ¥?0U³�u°‰üp% žë)b‹ž{,Á.§ŸÀ¼™O,¹“zäóÜ;%S;äz»"èê%  ü0õ|`H=xŸjZåÞÏxŸL�îò�R%µÊ½ÞÀ/"JïÛZàWó¢£5ŠÞKRê‹ú¯šM±Y`ac4@9Ð(gû—cHy† Ç'à Xß¡™"[4SÉ|À›ý94¯äÒÊmßgÙ FO�:ÿ]�n¨q-€)´„Q>{D 0¤}µÑX¸þ¾!ö>+HÊׄ¹¾dKÃÊö÷s.ªâ¿Û`¶u=ZšÿØäÆe¡á­ÉX–º…°¯ÿ'g)~ä‰Ñ(^Æô�$b`l ìÄÚ,üï�öÒj¸¼Úàyx’Ç;›�—ºÔT1@j.̱T¿øµØ¶*ìå(Fª¦�„ªŸÍiˆ7{½ãoÇ‚¥Õ%´%MUäÿòÿà÷s×îœý¥õ3}Ö€¿Ž5î,›¨£vÏwiß„08q¹,u8âMèZ•Ïᆄj‘ËÚa@P²Ì  E�žÔ¤;Z­7ÆWd¤BåÃáÂnô5z®’ïZŒh=d £_"m4ÇÈ�&áƒi» zZ—uJ늟+ÕO—FgH—ÄÔ~£¨‡‚ÒÍ áz—[þc©mÁœ—Ó³I:8þ|bN¤}ô‚hJjÇ^삼:«ûfr»`Ö’¶ì&HÛ[rl6§Â]èœðk–çŸI¥S~ÇQ@ÆtöG3d»‘-íóÐko#ÌZ‰ R ¨úN;üù 5ŒÌr´í¤^[0K„íž&/ µ Ìü¢M‰™ôNÒq…ØWWb*ü‹´”:fP#ƒ)¦¤íÀG—ò’÷³¹RJ ;Fî‹5k]g”ì¡{RÖü­‹�Ï\ŸQCq.Y´0ÏD“hgÈkú[ÅM\ã`ZUêXÈM¢[\d¦Y«ïrhøEãÆõói(v"@^…]îñFo91c‡j„h0ÂfœO‡9zí¾Ž˜ë¾?�ÝYy¼¿ç7sW0ÄÁ+R!`jÀ4ÁÅŒiO”ˆ¸q<;î%¦ZŽ*(Yù$ö��þôª‹Г§Èt´@ÖFa䘽¤Ÿmñ„‡ÿC}ë—ØV�³o†ögŽ“ÈFû�#�ä^< Ù÷Š8H  �K;¸aŸ\ a‘ý4‰wÜÙPlrúz÷˜1Œ„ÁýºŽ�˜%muãR´7jYSÊöº"BÝ.]Ó ù¥ƒuóãeG6CÊQNÌ¡m¹êÖÑÁ⛬b]h¾öuæ–ëu'’ç+›5éÊE1�«Aó%c}j7¯Óƒÿlwº(ˆ¦qãòàï‹ý…kÎ4®šÉ%~׉*¾®‘¯Âë¯]ßë€÷.@Ÿ C¸qÕ?7릥(™ÖOo߬£Þ;;zï§qÕ‡çB ës£Î¬Þ¨çÍ“¶Ó¸z'þÛùø±fþŽ|“Kæï—Ìè™]cÌÍ'wDʺ°®¸¼!=”^”»Üï'ž¬·Ä“‘€zl'žý�ŠÉ|ýòX!‰ÝØç©”aó;½D-K”ÇÇ)MËÞ~¾×b)'�q³+ ¾`WR~ÁFšµÑÇZh|iZ£§ç ù�AÜGýñÕ {¯º8.~•ù¡} ÄÐõº¬dù�æÐe†%HýͬG™.ÓÁ¡¦›zâà(­tQñ;õ22„wâØ*="zÑ¥4û•öRf¿Ò%ªªC¾ >ÃVá 0{ñBw!…Ev]…„Ð+ûéuõ¥qeaøÒý ËnÜmö&)$4@}:ä㲋]¼$¤‹òqSXìÄs2t±ZU“¥ ´@Ì<J2†®MÄ™£ìU¾Éräö¢ë{Cà5ùÜ(ĵó L(©4l$¬{ìKvPÈi9È�ìÊÉ‹“ÀÈùïz?1éç`¶, ]ç2­Xï*.]��Óe!!(³â¯7{ßÌŸq†`u�à³3[ÓÌkã#eÇÔ@A>Õ9Xô0&Žº<๙ò8q•½ ï�,ñÒ¼jžNS¸ÅïœL>AÛa=p­]œÉo2¦!˜|Q9$ÈW¨ïàm¦s‰Ý”ÁªSËèJ@I¾oRLî׊À!_­9X—: ãW§I¸38ªtÝH„}G@š Üçɤ!2C5Á\€±Š³l*€èeÊ�F·ƒ» ÒaþExý@®�TŒâô’^�ÉyHéOˆS<Ÿ¨î¾•àX¥Î¨ ç×/ (ó,ê§K±ÆýâT8ø5†}Qßw̵sj bå KÈ ãMÐP¹s®È°ˆV¼熽áZDi×Ó‰ê»Ú] ½®^¾žÑvÏVûE{@ÈŠKŽ SX\âpÿ½+Ž…Õ'+}>ŽŒW�þö3ˆ åàa ¸·‰� ¿î‚*ë¦Ëf÷-A§IòóPÁ1/Ü{N�Hº,Uk¨{Žq‰ÉÏOºœVýNë­m� ‹)MFên X ìxíÖàÅë4ª(BÈ{ô’Ó—k¦uÊ6«çnhúʦ}‰SqØâ鮨̤üe²Ç~gêÿ¶ËÒ8+'±ô;ß9&öì¼b XÏßæÇÆü†#ÇOËgióÁKŒCÔ¼1IB齃ÍU³ ÖeSÑ” jNU£Ê¶ü~Ùö^ýâ€E�Ãòpè×á $óñR…JW[0z8ñj š~ÆèŠˆ@(gãÒ$WZ² c¬(]÷ôlS!{HŸ| ->_ C‹Omþ^%M)�þ¼B¢³¸O;„Àd ¦\¼HÑ/GlËèÊ3ʤ�†[‚‚=[:!¼ÂaÀ2½Q[’Ì*1#ò�¹®eK<0 ÓØWŽ¡#hTeKtÖdë|­ZëzmÞWúK=£—içöhó¨ÚK—”Jî &öªm¢¸9¬v¸gp.’±çE"ò•…î§}NÚ|‡B¶ön‡y nÙ{ؼDΧoYq o{–¦^wF¾kéi®Øµô]ÚË@Úµ½¢n“hÕ¼ ºOΊˎ÷ºØU3£0X #ië™�cm)ö.ÀmÙ­Óuin_|Ù¤�K‘ˆ'ó^‹tžU¾8ÕÉæ,ãt?™¡ëêöÎdôg~ v>¸ìÁŒà £t˜TîÌw’ËÜ]('h#y‹¹L‡�B¥Uãa,’²;f‰l2�i?Rf¼àÚFŠñ³IŸ½‹V#N¢±>[BÏø¼Èó>(RÑ¿fpJ„8ó.êT¹ÍQÄ13Æi£ÃR…QjiÄòTÍ~LZ«Ÿ÷ÙФ<è¸Ël9�IÊ»”,6 9pÅ– cqJö‹Ùnæ ˆƒGÚL3ß>ê¶)¢‘j– =N©E�¤ß-D4¾Ô æXÀ쪓ë7%íæˆ¹|RDÔq,¶å^D£NsF˜¨Í&P‡,vËÜ�“8àØ­ÛÜ¢ -¬�o[°Id°+ˆ{3a6¯œ$ž÷ë 6}(0´‘QÃH‡E$ȪÆv®bG›3ÚF–<",Ñ¢Š¡ðŠÂÅÙ[r½ L\ÚR"EϲM‰sä8³n6‡ÿ’é@åîì¾­­dÖ'«ÁÊçÒʲޭ&"£Ÿ.í|$nwøòÑ.EŒ.S�^Sê:E].‹â[œ8æâêˆþ¾²ónýAjV³á@J<à[ºS“£(ï*S¼ýdþ®Öó‹�å0V”Â;&‹ÝboUà-´+À’Û$†C¦X ޵oe�-^·„Ž/H@¡ïä·E ÁSÈxl¼“f5œSäfE`öd’«ôYEºL;�FðRÊb Å#ÜÝn”0Å «9ƆêUÄâ·F–Å)kä¤ç:¼è}Ÿ‘÷³¤D�2:¸"½ t$ÉÅ,n â°Û³Sa1I:dI9ïö.ƒ¹â÷²[^äF¸ªt�[àÃ$è‚2)‚8²_`tÒù^¾êºæYPS]Å v¯ô„Y*ʲ ±-˜Ùºô»ÔCg7<ÚAå™)À•ä‘vlœm«ÓJw'»ê1?œŒš œ1ú·)Ĭšñå½(e>?UbQý�9Yý71¾^¹Q¶úìÉŸƒz‰-(4É:q4ÅJ+{¹ß¡Nv®×%+bÙ› m`”0P&Ds±g$œ _Äøv$®¿â¸œ'¼ÙJòOŠÄ™BaÊqÆízv«ò5{A�s›Ý´­*bð×êRBvš]›f«ì¾¯!»Z/“Úô �¶ù(»[\“h]¶+H7Ç)U±¤I{=/X.Ÿ $Õ†iÓ˜û±/²íPô×"þ�ui!¢I¾ŸYÑ^h²˜<†©ç–²B\qEÎÁ}IâIƒå Gbx+GD‚[7p¿Æ8Xë¥ÝèÅ8o>EG¿!-`eBƧ–]!~Mz��äÖÒeòÓ"RüýóÂÂb;xØt ×Oæ X1ßʪpéÖR�ÀôbWš,³)�ኚ˜)ÉÌ¢ócÄûž)Êîb � ¶~ÃÞ…ÆW5Ï‘-Ö××Ñ"Á®óÆÔÜÊþÙæ RD»â†ƒ\º�„i*n–ç?tš61º`¨©Ó›¶ÙÄÔ¬"ÜÙt/ë£ko>ˆ¹Ïó"Ó.íU$)¡LÔ�d;™M$= R"Â/§÷q»!l &YÌõµ˜­…I§¤›�II%CZ)½N…Ò8.t7T³ê ÍžB·ä°‰˜6‚m樋ê†ã©¦¨Ð¼ŽŒ×ÞT…kMÛlåFð똚—÷ÒeSÌPH¯Â‡†¶[Þ�x&”–6`/i*oÇT祿9âÆj®œq¬^…ÓÂYȵÛk0AQ½ˆ4 ~Ÿ’÷Ó„•%ˆiªtÄ\ÿ|Ú ¾Ã,¦Ê@uψ ß0U2Ͱ�H“W§õܲãp:M•L|3U–jw^Â… Ì[Åõšiª,…P˜*KùÌ ™ S¥!–�âZ`{Á¬*›Wò‚pCe)vï†ÊRìfÀÄeÞzÙÖ^Š_ ëm¼:ÏØIðx¯±Ø)‹¼2g‘ff§,-n&ÍNYš¹Ä¸�28Áì”wÎ=1 øç21?%óeÇ6=\y²§¢=ÎUät(S4#ac]NÕ ì+b$šYÃ"š­‰EnZ'B°Z'CðÚ0Qa)Z×"¦å);ànžhÑF•g•Ëfä„kÑÉ톰q,ŽÔk0Bx“R¨j•ÍWÜ‹Ô÷ÉМ]±»l¾Ì=Éx¥îóÒ«eh¼Ù‰ü¥‚HȈ·/ë€çÐ ãÂÙ%˜ÂÙ[™÷~„t¶~†è½Bp錛´´JgK^UH!\§õŒ£4¥32⥺HgG,Üægµ=kºÓKÝX¥3;º,Ïû¤¼Ÿ(d&Évq×]Èð˜&æ{b¦Œò¯n×]Q•ŸÒ£&¿îZª¶ë®¥ù¸îz®G¹:Cù:-Ug¹Ý¤U{Fò±tº)gÏ *–œ0ÙL¾¼`¨ÍòÄW:R² Ë®U«íÏ–¥ù)'¿ •bZ�À�ÇÅ�Ê*QìÅ’Ó(•b ƒñS#KíJ•xšbÈk}‡ÅQ›}ršzÊÌ6^Vúlbn}êÅÃýÁ¬—Û²†m sGÐ@—ßO_ógž”ƒªOFKß–œÖn¦½Ï²òšžì}­( 1eW§ý§Q5shõ.Z×6÷7dFœj´µé9Lÿ5›?’è\õVÂõaæàâ(üXl­´°€ªÁU˘¦Ür6äk^u~™Ì$-Œ›vÌó>ž$Þú(y°Ía,µ†·+·QbVa´Z1·¥“ôɲ™®Sñ~zn¡å8á.Âø Lp×üœå@øÑô¢ÉÏGÎò*pŒ^÷¥ÞY¿¬”´÷/qRÊØûþ«^5Gt@>á |ÌWÎqÞìµTS"ßášPõãœzì0r5 æÊU˜ª0ùykÉBD$ª3M˜“Í@k�•%ë;¼ž”…»pªbú®L—*¿J檗7ˆÅûÁ¼Ézzæ$LF¿>tZ¯ú°g´hdš³dYèr&jÕNãŸAå@Af¿)§Ùû­'JLñ·5>…˜XorRRßG,u½”y[“58K9b©é¥Ìû>Ù¡oöIx9âûŸY8^†rûìÎ×ÁËé‰Ç-ò¨"\—ŒŠ4"É2CáFü©kW6¨bðÁÄæC<]ˆÌ7ä7àÈ`‡ü¼™{ì²�Ê¡}ò(—Ú³ º´'¡˜âeȉ¸³U.㞺Í«‡%WZá+Þ-M†8”©\ö w•&þÅdÀ�‚’>Íä¹Ì=«äÙ ¯�­ô<{㥵!¾õ^[¿R+·¯n³ºNäÇ;i…̪ ÓÁuønBY¸òÒ÷VºU"úÙ„8:Û~d%< ®ñ+¤õ|Aäe%Keµ•i™€j©Yãø˜yVÛ&Ìy&V ¿ˆDZ&4EÔ¡Ö1�ì ÔÁ‡õ—Ì€h;%½øGSë«1¦íiy®+öÍÔ~¼™[;sšƒÊ^Ký~m†‰=ê×µýŠ�UzŠCÜØËx¿>n¬8ˆ‹”¤¯Û 6ʆa(yŸ ý~]D`ó*õïªz >°²c|<ûÈÑ=x[‹µÁ©Hèò+Cð ¸ç2¿W“#ŒV¿_ÓSFŸªÒEŸÞfWKó3QäöÕŸíxljBŸ÷žÌuD–6.üêa‰‘ñý�%|�w‡§BL˜y˜;BXùÕa"_u!rMª·6O�¼ïY­�íÊà†ˆ˜Î» ½ÏòÁ‹B»«Ó»ïDÕ¢<Çw*Hœ®�{)o%ÆóÊô9ühn�¼”,Í¿Ò:!•2×o|Gf¼}ö‡*'.ý¨MâÆ�Iw W…KTq�TN©‚µû–Û.W“éœ ÎMÄÁ¨ù¡Ë£ìZå!ÌÅùŽB)úllÅä opYKÔÎa»vÝ¡ôK&ó—îÀ}�Y¦+PQ…;:¥ž{Eç{…ó™ño|>%Á\wÏ%~¥e6=m7ö¦�—Ð[å6( ¨×rR££J‰gß~YãóP͉Ó>c5ÄÒ»—2[Ó!WÞYÓÒ«—2ïkªv5b­é¹Ìß÷©(pâ©ý[—¬ÈßÖ“®5{dˆµ¢(ó›5ÝÚÿ›ŠÞavžv?&æ¬/#|Sîjœ¨èà/+|Ö8mV|hÌ™íð¯ôÔ#Ó:º|Å–o_ý¡ž:6H%¡phýùª u$銥)“á­Ö¸>•›ž 6éœC‡&ÁãH mˆ~\DTH9žÖ²TN/ˆB˜g%¢áåbÚ©¯v(ª0>èyo4U¡˜uP½Eº Gu–‹Ì÷R¯ß:ƒÜ¹ö§ÓôÆÆÏen ,oÒ1Á&ø3×®'ºÞA¼tI×íD„I^Œÿ=õcº¸_ „à�ð¼»tïˆÐbìëWÄÏÛ« þ»šXõ®ì|ZéÚÍ,Ôå“ ˆ{Ƭ—Œ®fs™5ÄÆìBcàñùÁ›¿¨þ0WêhÿPô¥÷NÑÝêýðמÐÈKÐä0§î Ù¡€XÒS xƹ3È}xH¨#ŠG›Ÿ–þ¤Ðˇyº2AØÿní:¤[\ĨÕKÁðUàÅ<TÁ ä,ðõ$!Hv^{"žð$Yù˜ ¢ã²E³Ã˃nL5 ML©àÀ.c±Á‰W>ñá®�{Åz˜à+œ³÷«_Jìï×'f6#r9Ò£/3¦Ý6bz²" wOÏë€�ìÏKãǦ0t5Â@¸~Ýß‘�é�š‚™ä+ zù\JEÐ÷í±›ƒ¢Ë/q­òl•¯ ¦1Ç?é¡ð¨NH þzc‹™?ó’ùOåoí�¸œw,Œ½èÂ$m ƒ/Œؘ+ëdê¾íuÉÙ~©Î¬<�öu²ü@ª}ÓBÚ=è–ÍËË1:'Ìè|1½Ky£ Áˆ`Ë�uÕ%+PÔÞôÀ³7ßô”™wÎÁü©×DVÎõÓ¤Gîµi¬q£œw�tÝO„·ˆQ¡˜®sÑ^âg÷�Ž—‹ ¯Á²Us.ªò�Ï®¦Ã6 Èlן‘…ìTÚWúô݈«æ#ov!tõu.$u.ù„Ôñ´Âþ¹ä—ê 7¯h¿(#¢÷ÎÁ˜Œ‰ààükº×´ñÖ�vêܤ½“þílü`Ì ƒN xÂB@¯ý=FÁ# �sT²°4%�Pº®8R�"@wº^‘™à­ºÓûpÓ«ûà€O&îâ2!v){  VœÇì ¤†I.9u'¨ä‡ë±0™ÄcÁìæòß¼ äÀI:»ø,,É…Cd÷Ëœ= ïPíÌì¬ÐŸ+P#Ël’ |$o)A“‡e·ÄD2±%³TpÙ}ýÖeª“¥ï¿3ƒÇ„Þø,S$–]¾22÷˜…âN9Áðß«.r„‘¸û¹…¤QPô‚h…›ó aépUƒ ºmiÄEáì†dåì¦ÖgŒÃ—+÷ûv+ )ñ ìÝ÷¥‰j<&qËØÔ½ÜDŒc"4Ð\*Bx“VEÁS“œ…)2ƒÚ·éФßHµÎ�h¦µžÞê^ƒû—´ÔÄÐ{¶�>@DÂÈzÝà˜’nVƒ ¿m¶1Éí��øœ�”¼]æÇ~öÃ|Y¢ÄY5äÏëÞDÖûžêAÐgtr[1Œ‰Ð8½§ƒ51)Å>l - 0i}›Œ·óƒEÕ”=×dÉOÜ2›uH—‰™‚Ø¿2Œ­ ÙõØÖR•a¾o•Û³‡Kˆy_b¾Ò¢?±zÇÌêSbj„7˜ÙÓYQ '0ZpÂà$ʃ\æÓ®ç1•S`³kái�M˜ò¡¾µ/,s™º7¹JïÓÄ®Dr¥@QË|\e<Ò'W%m‹˜Ãù ÞV®òYÑ„Qƒ"½f¾ÙE've$ž½t®òqĆ#µA m(“V3p׉™Bëó§I×^–G—£úù˜¥{PŸ%/jÁܤSöðn>MÄ>5 ¦¼qADsGÀ6¡õ¸•p WxIïÿ,­`,çìÆÂUìfÀ>;Bh¾�\3*PÊðÙBr—èDÒ)':iªðÇ”>RÛJ.U±¢‘s›ýX&€Ý¼OÈÛ9Âzµ¤ú—<ž#‹ÒÉÌ<ËvžÎЬØÓdÆÛ~Òj¿íP©Y‚ ßÄRËù&·ÀFqGØn®–Ý<‰­Ö{a{qtÒöêFÈþÔíAâ(Òi|˜Ute'YÚè·Ãƒü®èæ¶ b ¡‘z N oc«ËáiÒSOº®ä^'D±ïŽ‹=é她ڻÉW—Ãí€éRhMleIF‡ØêØçÛÒUò¥G#+Ñ]ÌsGŽnšø]¦ÉcpqH;—M�¼p-U´°íx#M¡c¾«§æKህß¡¡z N ocR«)4|ôT�Vü>%ï§é³Ýfñ±írÁø#Éz˜òŽQžtaKmv�¬8X·¯ìœ}Gß­›íëÐî×bH ÌÔÄð>é±`¶5Éy2ÂîfVdÍßTº—>ÙcÉfnõèÒݲÔëáÉtì–;÷uØšÏ#tžË¸êeÊÝ È•¤÷S*pæ7:8³Qe™A åÄ:ÏÀ¦ô­²’³QÕ‘½WÜLuW-RTg( dבÁ”Ü'Û‘Â"‚»�È,bRÝ`‘ɔ‡qœí%ß O”›eÙëˆ-‡¾Q^á‡×rìüù˜'ÖqèµÐWÄl�ßl¯¨Ç4OÀ‡À÷ò$Nå^@õ×äß&i­¦QÅ’†Ûà�ªS'=Ä.K�è­EðOO«‘‡,?B/>ôîXèÍ Œ7�¾ŒéÞö½iæQèîêÂ#´{öpÙ}b ±AÅ(½„SÁNA¨¢Hñ¯…Ž:¥•íó4ÁŠCm�©X@%ïð»SíýîEO´'«M“܈È}Q5{Ïuîn|»ÞJv¬å®r{[|i¥0åéì‡Âû9ápsñQ&$¸˜5˜^~øåW(îÑ ;D7M÷×@¶Çr<ˆ±z'†Wáä:ž¼L ,Èà,jÛÙ`NÃˬ(,ÖÍå–$jÁô=Y„¯ß c]"3 ]Ç�ÃÞZî&¹�xf»‹ÿcÌȚ졌ˆq) �Æ:ï Âèt© #U·J¤Qb«�b�8;›Ñ€ÈpÚjÖׂ)žCP‰ùSÄèê^O¡—~ïo)ŸÖͪ¨àšçiœ�™}ª‹¢Ä¹ëÕs¡2|â¦2#¢g�7+=€#²?W½`ȧg] �f™bªûÙÌ%Y�½V¢î²�fÊÂK‰¼DQŽ^ X¼÷„Ÿóî�³ëº7ùÃÔb¶¤Ké'vô˜Ód×Sð|‹F›ø´Þá9Ä_ú<ŠOT¢\‹m7Æ5e‰2¡ÌýÓÀñý6™{6ÑÃ0-Ru?m3Ä$–‹§íz7ªÈNÊHÙÅP­®ÇEáîJÞô”Þÿ…O˜ã*é¶�/ bȼadòýÔ¸îx�ÍÄêÑ,.UÛéíɪ‚Ù(æ7–=oºÂ|ã‡Õ£ÈÎ@èM 2_'ȇ^i£d—MÊ\‘Ó!Ý7ÖE0ß~ÛquçS>3�!p]²ÍbÒ2LW¢Qo½k¡z߬3£´#p°²¯7Àˆ1ŒúݾfûJá½kzbÍ:ßÌ…RcÛÖß5v}í¤ñʃrj|!4“.Ü–ÎÿµE÷SËpR@Pq’qý?ÒŸàR&X$ãj‡QO cù¹wýž,{72W¨üà9ÏßS´Î{ÖD…SEQ‚-Øcטp.ÆUèÃYC)Úæçz†Õ‹”\ŸÑzóTãê›òJDßãûœ ØÐ ¦ »Íé¡ÇŒ( Œ%Š¢¿“'{1ç¢ø�/‹Ÿ”¤›IïæØ³ž5°î"cö!n-m�”rÝÀ¢ø2(Y\ø¶ê¢ËJ‘†+é`H¹/3)ðn"+SŽx�ª(Ð$V¸ªâ’Óa†/M=—^Áåƒ‹è ¾{b1»�W“…Ê!}SÁ—«ë“Tcœc›-tnðè ̦xU‘¹a]ÈÏ™;HQZÿ]*y| žÝÖêü€HJFÎÜãè\=ç (–óÍx~löì¤/¿�”U4ŠØ9%#]ï¯ËØç0ÃP |‰Ç'sÿ T²ùªDæ f©ÅojQÚp--¥èúÉ+?&G3 ®Ä™0ÓÚ&½‹‘d+ÑEûáJoÜ÷dË¿ZBì ÷æwó. ¨îr‹à¢(MwóErÏrCíIÉŠ“òfòÛÙm[wuÞmîy»AØ‘„”¥ª>Ó"8˜gú´­Ó²l§.ê´š·Âo®&&�•*ÝX§æ3pžëœÎïÞaŠy™X¶üd§~¦½¾b7á€lk“b�!×#v#æIßÉó’M š„OdªÂtæóV‚I!“^N¢Ÿ…é&ã´¶™/††:øfØ&•W°F.ó‰)rŽé»ñ ßäÛõØ/E‡‚ÞÁ¦‘™ë†Ñ“ä=›šZ´�®Ó "ß7ŒÙ ­`»rÂ&¾ÈÊ«n±Ëቿ�™Þl¯FÞ)_”T|Âê7ß!F||ºH:Jøœx•6TÃt€‡{‘D~P¦Ô2K]ï´g¹>¦õ¨ýŸ6ü=iG‚rf3h‰'ÓaWkSã ®+`#ñ8(Þ(•ùråî’òˆ»<{‰©Výí€óFùe�X–À—UñÔ•ç#É7åçcbæº9ŸÎS”r[1J¸*a D?Žœ»|ç|oû"¿p\JÍ’”Øn „”šyÝÛ”^y)±ÛÌ{&|·ýí0¶õM¶Ø]zåû±dZX ¸›tÌm� Ð µl2ó³wK�Î0‘©ýì°m zt ¿-†l-.ý¦c®cУ"—3ɧwrÓiÛ‰g"v;-Tój9õê±zZ+S�Ìw/=ó�n†O;(É÷/Å‚<™Ã8_¿ÀxV9ýDM ôWC0á%÷e¹ÐíHG7A¦·SNÇ”MuÑsآϩS®7±�+yòì`Â+x-ÑÈr÷`5!lÙûS5—EeQ,Â_ªI¼g_¨„Ò‰Ì{cÁÛÈöÀWt"›¹(z™ìÚ†‘\ÎSY~ÏÊ‹˜D#f)cÒöìÙ¡OµÇm#eÛšô1“E“µ²gÊ Ìá—D)+] Ñ^›r B~#³Y{XÚ†6GOk�²\%9ªžat`²FîN)óëÑ&{Øu&ü[R�3�È~}Ú*è+¸L�)TtAÑç?­Yýb05=hª?zH–�Chž‰Z¹õsí¸NZfmöÔ½..;²YÊöjšŠšÓRÛlñéúøi=b‰6¥§Œ“+0®.Såá1Êd,§«…qá<í&»ø6Õ!µØ^ýö<[fæMzÉ}–P8¼ub#B§ö¸V�úw£„þÕøV‰U&\-ŽÆ07!�É<®·˜ÒQÑf{,r›göcŠmôwÛI�ì.b;U3öòB3qiB9é%òElƒ¬«ØNí³8hÓ’mw4]šN%0šÉcê”�Ö‡ð(xžyì\v>Ǫ–ÇŽ0=ÜíÜnùŠ1ÂmËg“–ã¤ìvŠpRv%> RÒ)z»ÑRïÂù™²ê }ÎIy™ùÁ7ÉtE7è"ƒ¼ì·s=0®¾ðb0ï¶*d3x5êÍ"Ò0f2ƒÍFZ‹ iYß–.ê(äCð“P 1~vs=5BÑHÕÉ”5ÉØä‹zÌ-›~˜1a L£×‡MÍYµ}0XÙr9ꫪ]ë–�¥™Hß®­øDÃi¶7`deŠCтϻø;jh´"ÀÝÈN‰fE8ŠEÒ Ì?ÌôL&0 8æ§Ä ΜœB?Þë¶´V„èE¶§<¼—f%ˆq¤eèÌȺ-òB©.3NË,럈M˜„ëö|þz³ž°Æ.ӽܭ�., æ›Ià%ë’ã[–E+£œÝ7Ô‚ !V°Â_áìön¥£�3ÿ÷L÷?ʱ~䘨6ÆÔp"¿Íç�*µ{7+³én¥™›ƒ)Åçíð¤í2Š…2‚´í¹-ºòŒæÂÜåÇ^º`¨»©ŠÇÔÝ¢•Ы¢¦yE7M1‹�Ä_ðPöµènQüz›Uœfßž�œŸv DÝ­œ‘ŒNºÛ‚ð‘8ÆÇj58)¼‰I­S™çƒžgê�Üë„xJuÇ™î†ZM­Ú9™Ò¶øÒ]Ù¦�Es+ÝLE¦Í˜x�>šø�QÄjFìtn·"š¯BÙ:ÖFÚt‹KJ@{˜ƒDô‚ð‘8ƇڦObéK#“XU±�AΪ÷ăÚ÷ùмMœÉhÔ’±�víØA±‚¼åvï\›«e&›ª«`§ý=uNɬϦPŒŠÛÌ%ßâ4EÉ}3Á½ÙŒÙ\͆d3ªŠ¢7ƒ–é<ì„ìý8L}ó~N˜9Ï¿”òˆC¶à�L•Æ¢b™×�"ó}"ÞOÎæUvG(ùô6`3Ž™ÒÙ¿2ŒžMpdÐãÃòÉ1îÉ3¿2ÌûªFO[^40V˜¨¾e™^Ñs}³½¢b¹ “ÌfFCnËá„GCo›þ:ò>FÛ§‹[2³œñMK¦ÉgµÝìr^‚�Ï9g%"ÜaÆŒÚõ ΢ٻ^FL3‹/pp–£Ì¸U˜ñ=‰Pýx„_ý\8+†;B v–p]{JPëˆSeÔ¶¥ ¸íZOsMîm»Ý†å|ÁTŒîIÌÐ;àj\ê=E*›}š‹Û® ÜœÜÒ§ŸmšÒçâ‰Å±”øœLi†PoÁ¯½>ïã„M†MŽ4ËzTa–wo#,óÞ ³þ·p‰áµdŒ!„E Ò·¨°T°‡åÕ[ %·¥Njïã}2ÞOÐX´ Î<u™Ÿ�¦ÌœùpÚ÷£(ãî°Pãüv( ’ ìxƒÿõÒÜÂ)'À©ûH\ÁÂkµ$/0n¨ÜÒY”'eçœg1�%EvœzJ÷ÛtöKçaIFt‹|ô®¾,±•�_Ë-?3Îê<ìÑ•…U+ÕŸò— ÷Æ]ápg¡c]g”Î)5ÿËAÑI_†W8ñöõ;êZau£1ØB6µS¹Ï»RÜŸJ¿|)—Å€0ä 7“@§3¥sDR1tÕ~Mz¢ò´ËHjÞ5?m¨§'°Y,öŒïm–u«ó4ñƒNéùUõ•‰èò‘¯ÚOÁS¢Ðá�mgÓAQ½éªwÞ{:õ´“§žC£|`-7“¬¤Cä©ÄoØÊ4|Þmúç´@9óM=ùö³õî:\¤@Ý79z¨£U© „ LUþ{‰ñèU=½ßÄî+½@‘[DÚÅò D<‹ÎI¯<<¿Î�-ëÁI2f‡ÿc Vøý@ >YöqPº}Û'Û F+¾‚†tÈXåòLIÄ÷HYÍy£>„Lî½™,BÎd#;§9åÊpȤþkU²;ñϘŽdÁ`Y¶x2à ˆ~\§^�°òbæk"š= ì_+{JÔ~Ò‹æk6¯Õè›VVt� �TC³>ðNÇ÷ L·lÁA¹SÝ]7ÀÔRïÓ‰9ÏrÌñý|,#–ÙiÏ3UÅQ“8‡W,J#“³ 4[Ôu00Ù8Žù»9ókö½œ^7ŸcfãÞ{õlB6ް±Ì×)¶Yýilá�Ÿö –uíd,–÷œÐר©@0µ}Z£°jvšÙ»NPë×�àÛûI+Oƒ¯ö¸€cue\xE4 yGhK#ýzt„�Q– » Õ��ˆöëKqÆ»x €Ò0XùRH®!ìŠÖ‰ÂGJB~†¤uôÊnR¹r+X)G¾&ÂLJW{LËXÚ‡L�ôo^'·_"š!š:™1ÕÌáŠLgœ<ÇxÙÎHËKùjtÉ7Ê,Mn‹=Ö38ö4ñ~’/¾€ nÛþ2å ©8eo3 Ÿ\®¿Ñpö‚ø±Y!¼F¤Ÿ�ÃÜ{'Õ&â‚JxX Á©|t^`{Á¬dÍʬñŠ�`%9™ðqS îéë辞œ¨¢ÈžÙý¡îwenjΪÀö‚Y{«ç½ß ¼ûEžjkÿgÏ¢ÿÏ�ý±•¬˜S¸w¬uqÉ+ðb)SCO]RKKµéXÝÕ§±®`ÎïSM-–F)ÔTÜ$uÓ-Ó£œ¦õJ5+So45•765ª7M2—N]£V=7ÕÇ%5mŸ¶(¬š�fÒQƒ Ö¯Á·÷“0ÖÜ¥sel€Íu@_?�ð�6>qÄ_³í™K-nµ „›ã“i|©åžÙd´pl¶ B{k3ïÁÁ“ºm¶xDu± µ,Ó_l¶Mã´Í¶)ÖÐ7˜V̾›mS÷R@B”›mÓ¹s³mt"óͶÕ8Ÿp³mÕößl„6Ûå >ïXe¶ÍÍåu³EoÒÜl[ù\Ö|³ÜN±×â•Ø4MBxö2‰kN³œ…1ö¦ð¾×ÂÖ]ç^ ïµ†Ø|¯mII‹l¯Å=õZ…Ð~¾b³mÏ!IÚ¹x† Åæ9m«¦óh³mÕt$ßl›]ΚYHL4ÍBO\öeOçìëöÔ,E–í¶Í °Ý¶¹yÍwÛ&ëüæ¶æVbÃ4KI"«¦Çï> ì¶-[Mí·F­}Ú…ÀôeÚ…Zþ,÷íöeMa=%|èÏÊÕ?ä¡C±Ù8BA×ñma€[Ôí7-Ѷn*г>mô|Zÿ4{À§e;=•yáL­�íÐïLZ¢£Âìw_X*Ïëb¬_æ.´ ´éœJ¡rCÐ÷Ùv!t®·¹ ¡ò+-Û”QCà}´b —±X1í-¶¡³(y™PÞۆΪæØ†Ð«£Å>c„�¢¸¡�fBÑ>´ ´-_`:«­íCh/µõn¤ŒoDèí>w[Å“Oó 3ÄvÚíµ±â™ívɇf=1c;Ñ¥Íj' Ð^_øšíDø¼ö/ç4ek':�UmØ.²9¿e)wnÄVŠ#V€.°�.íÆ|Ú‰ÐÇT\’§ÉIÚ‰ž8�ìX™TaJîÓÍ Ú‰Ny¤ÛFtV›:߈tS§>[�.xÏy8’`6i¿1ð7(b{‚© ÕžcÛÛ½è)ÒjâçFô2œ[O±|“2…•?ún ,‡ÂV[¢¨~€8ˆo¶áŠÕÒ7Û”ž—Â�}PW|nƒ¾¦.R!£»òK ¾1ÿ~RÕò ¾ pÊÂ<ÀÃî~ÉÝd°Í׊g,|ÝÌ‘ VÛv¯C…u�®ßÑ5Éô*3ÁiÉ–A>­Ë ŒëeêÑ�iÞÈA+ ¶ê»iU&±/PZ µq+ LF¬ $˜Dø“†´f–¬˜‡â·ùºª}ÚÄÀe*IŸCÙ™ýØ t»‘Õ~Â�Ǻßõ¬þ´Y³íòô‹ÄÓ({ÊqÄÄÜ÷ÃÄ›ÉÁ‡Õ+)y±9Óô1_›M�m‰ëÔððvNC�rv�®_mc¯;^´Û­ç~@ƤY�!yú×`°±w¨°Ã Qw}Ÿ'žƒ«#K¾²¦�ó2SL£‡ILBÕk6 Bðah0¨`ÈhÉ@x…‚¶¹9·‘Æç«{#Í�»Ó ÕìSb,øs1IaÛèÊ ˌÞ$ÆœØÁÎ\§!ŠÏ+n®v›r ÷]Ž#öî6unY} ¦ÇOƒŸD³>K­|6ð°l¿ô¢&³pžr�ÆË„æ#ƒc]o¶OÓÔôàC…p Ý\Ôà�I“ƒ8•XgyGXõ|&à”±GÕkÈÿ#Ú?)¢w=Þ£àv§#<$ËåßîBuòt1*$4lv„ÀSsšÕ611¼|£À‚ðñæ !Ç›ÃyŒãM¦¬Äp“m­6Ü$çO2îæ9‰½Àn:¾�w·òá2v…§ }Æü¸Æñn¿±yžÓððbù��pÛ�>Ù^0êT³çBý%&uM+Åžþu µ1OééæÁ±„‘$6Ü_Ä vO«¨mª0w_9VÖAe ˜­þE’ÊÅ«ãi¡2oâóÚeÞÄÓì*2g^}º™��&ñO¦93PnˆŒ�Üœ·^Æ'ÓœùR‹^ýó[õ�™»„ jD¾,71†Ï#ÞàÛ—…¬'×´û4s„ÔK†ë¸\™ÕØs(§²»³ˆRÑu,‰Þ “Í8VìþÝ)k‘¿ÞŒ cµ4�ËXÍOo©Ü1³“5‡6Ö¿–ªœ”óCŸ‘‰ ÔøÊ0ï«R /™¦jcˆû�ÚCCo0&]¶‰1oÔ”ÂóH\Ù‹)Ó!«!Q•?ileÓ •)—®)S”£©/n©|k/!f˜N«4—3J×ãnŽ¨á¡´3DÍ»¨™˜9/]áú/¨Ûtúgï0’7‘Œ‡™?¯p!¢°Ù§¹Gz‡œÜW¬+X•Œo!¸àáÓc«÷jšb¬t󓻯fÅ�±›ž1Ìî/åÁzçO4uçešºì¼,¥pbü,«lD*C߉¤\S~še*©l¶îni³à1PB¦4U!*ÌHÍ´xê‹=s@¹Ÿ0Ÿj*áEl)ÖJ°.­™©˜‰E‡Zƒe·(W¶O¼Ó¦é™;ÖT—ì\ „,öÕh —ÔäôKìòaG óYMÕÜ›ülËŒR—ÙG%{â«vÀåƒS~Z'§°SòY`xÙÚ�WKrÂ$Ôׂ²Û2|·C.µs¢OO3ó¦¢Ìƒ•ò<È2»Özõ±/1ÇÜë•ÅÊ^¬?í• }žðhã° Õip±«*£÷D8ãÁEßNÄTôPeqg�K­š�PÖ'Mšß+×eÎtCÉ�]qÖ”ùõØi ÁÌŽ¹‹Õwýªc/yý<½K¢d7Ë^Ë lGßÁãIo.àzM­Ù͉“9Þ°›Én¹›½egÓ"Ÿ] ·Ûy%åïHæxkç_Òì0÷QÊ¢Ã<î윒ûwš ópZ4Àðc‚WŒÒ]á¹tZ —�ì̵gÛ£¸¼§3š. »OK›^ IÉí:Íž‹‹[ßâO·¿NZ&Qii¾ :Kµú"ý ý²ÅÏ\zïn̾•9Šö_�ÜwíÛtîÈ»o=vòc–1™§•É[Ý–QÀ~²\1—¿n¦*ÌâªFóð½ÐávvÒ|.5 ôÊÏËs¬WÈ««”SŠ�¬Zâ’oÖ§ŽØj¶fÝñv³õœ¹â&lc ŒÌVÃâ}¶r,Ÿ¨²DÌ~&kä6k>½ÏSùcÛ°E%°çþø/ÿgrÄCuÅhýä!·xF$Ó$Áø]q½)‰}o�Ý•—;Ó2�‡ OÝ€i…iJLÝO‹ÃÃÃ"h®Û‹ÖÌ‚¨–äu”T”c·@Ó®Ô¼] ƒ-â‰�ª<ʽY¶y<1Ò4�ʪhz2žKA¿øl ëköpQ ¢K‡…¾?aÂìí–gwE0é¡!0*$£é ÜdÊ„&ø§éç ¦n9…{¡KW€Õ² bg†îÎÆ²ïôFõ còÚ—hö¦eR1 ²À<@»‹Ó Ø‹O •23'ň 0íYWÀ%mA„”³+ç z š’@„Z[­Ü/��QJ_*ª^±¿d§†Õuñ‡º¥‘tÏ‘lðÛÁþØ:®7Ù ‚}»Þ7uÄ÷DKØÿu(y©Ã“O¢([°`àk ã´lù„»‚kiüÂÛµG‘Þ £¡™á»™â‹S3wY�e÷¤D°Á41Ž÷0º4ýï¼ŨPƒiD`ÖƒY€YÌxñMJ2j±7`˜v·Û+—µ$oª¸ƒJ“ˆ_}…«’j~Ï/|î„&} É å²�Oò_•Ù¨j„Ù¬$‡èÁbïÈ�7i’bZI=ILû=뎃•Ñ …aR5˜Ôv#v},Ó�|ÛO³O‹Ê3Cð‰¦òëzÇ„O¼8‚�¬ØQX¨Cs½”ÀÕä>­’>ÿ̇£fµùN‡¬žÑBÊpŒù3ŸÁðÙ.ÊA©Ú7Y$5bk½(͈÷m‚ÊC…GØ×àóœÕwå ‹Ö;ÅkôMÙ`½ëÝÄŠF¶Íß}äöµÆën±ï e§©õË“=¯÷‚¡ýIUîÈ�tϽèñzF²�ŒÖäG÷äê»™f‘b»…W¡ŒÖFŠRª2U÷îÝÜn‰c|¬^…Ó™äb7¶… ‡ž ‚ß§Ä_ùp8KÓt-[)6nÈ,Ã)£`xî¼SqZ”‡ ÏÁMŒ^Ò)JaÚÍEo¶2©^‚»½Y¢nv�—yºÌà›åº3‹d%§�*,eÇÒˆ½%Ðû|léèÞÏí†ð¡8ÆëU81¼‘I¯,ÃFP4‡.‚ß§äý4ýØì!ŽÇTL'¦Øi€«˜6;1LSgÀ{9¥Šë1˜f»y‰§*,%Z/ÿe_’+9®l9×*î2 ‰�¨ÔøW-á�D jTÛ/�ÆŒt÷Èüï#€À5s‰bk4Zs¨û‚úŠx4Ÿ$óm¿''ľñOŒÞíƒø¤×£8gù#_i>ãþ�aty'êa†ü³/Œ¦KfâÔrú™Ç–~%^a÷€î<æ pJMZƒù>pLÄfþ“4…G¤|Å9ö·,UãúšGÝÉ©óÖÉýWÆK·òþ�?1ò�c麬ޫ"ë=aš±ñŸÅÖ{õ/½§q±I3�aE™®S±¡Å“p-÷nKnÀ§)6¯ôEӢѱ�Éù59¼öqs§<™œè¥«ƒfW䢃<¯¯¼lõ®qSD—¹Ã4K[\*:lª½U‚ALjmëNÕ=ŇL–ëT¶Ñ>è¶ŸÆšÞ­ƒJ}áU­Lùw BeÊ¿ã<”òŸO³b4Fžº%¿Çy¦®AÐy:)¹Ë£•ô• ˆ ‹þ–,bП�jú• ‡�™ªä²Ýd;rGÊ–Î'ÔÃóÑWœ9aÕTw9¿²»‡ÒFÞFZÐã‡'±6©ß_“Ó™N€ªï>{õg‰Îʯ6'0”ãô·¡J<´uojhʪkÊ4tº½bØá� )g›µÈ¦¨’IæV;ç㥈’,�ÛÉüÄÈ¥µà�Zë]ÑŽáÌl¨ƒ&ÕK G®Òœ› MŒJ,�_ßh5ãOä»3¤ðœÔy çí ž³]GÖdÑÊÀ6z†ÙUZÖ÷ §KÐèÍû!äÿáZŒÖt)DóÙOZ êe÷˜s÷´ØÂä<—c5lY>R¤†X?<þœúáYÒ²Aýðônyù>ÊIÇ…fè¤Ì÷뱈¥âô\„$XE[ �E¢¯zû™Â±1Xb>Ñt­æàõ­ê©°þÎôÔ"Œ‹ëÜchÙÛ\Ôœ�}¯çÝ “#IßÒjÄ$Œ3|͗͜Ͱà#.ÁQ¤Ü”*³q!VÓ³>qŒ%ls‚ç7~Èc{£¤™M77Ä‚éË�ïM“¦ïר2xôã½=_ýßÿë!®ý†Eäÿmÿ÷kÿúëÎAkõ™¼;ÿ}ÿÞþ:o¥“ìtâþþJ†nWÅ®ýñÌÿùú/”¸vD�~ϯ0ÌÿI£¸÷'P#bzSUÿRae™!Öæ…å;uÝCó×RîçSªçRÜäœôòÿsy¸Žô:�5=ÞÚ^}†Xéï¯`,¥~<£BË]ë#âþ­ÐF]s:”óRh<óѧ(Ð=ÀROxŸ•�üý¼¬Ã`pPîçSúÿ¾´àx þ­´·#‹ÙOÿþrÁ@QÏü±¤vñT’ã×nÀÞÇŒùóÇw�îÆ+HÁ¯ï`±•þhQœ«Ë¿xÛ-zd’Ñ3@¦©×óRùoAs�UÅÂ9ˆ=7AГò.º ë 5ˆ\!¯B§:u—„^‚ÚÀ l†J-Â|:�œVĺa’Ã3z ®jH·óâš&Gx>øVyDï_/-°/`(¼éh6QÌ ïöŸ,âçmˆÚeÕ5�f½,â�§þ<²z3Öï¯ddI�ükA^LKAsÉ~<óï%iÍ’–uúñÌ¿–”“Û}².€�gþÃ’^+ð?(éµ ¿¿ÞV Sû_Ÿùa1„¿ŠÞï1%Ï?½¨û?Ö‰„÷úâëú|Y“ñÇ2+�Ø’g5êæLK±ºXlj‰ÞÄ€YéË.ÉÝœÚè§z˜‚º!³œXVHz}ô rzkâ”~¨ð“ákäõ}ˆ7Îs«êE)v,|ÜbŒÖã{¥ó= vU«÷Kœ:±ê¾ûÅ‹~"öÒ[P‡p[Ï&£G@Çб'±l'Tì'Ýu¨X3:^ð“èØY…„Ž=‘8_î ;K6ì'�<„$7ÐÌ`dÖï£iÚÞ¥#Ð#Î: šq æCÇбógi�]qÈÒëYô,/¬DŽèXÔ ‰`<Õõb°1“Ñ eK}ÐMGë@Ž}¥U O˜Æ=�cOW#Ç‚ê÷‚ z›È± ˜Áâ«L&vlþ.ðXÆ€&_DõÐ÷½ Ç²f ©ó@Qòu ôØ9ö‰ ÖàÞ� °&zì+ºP3`ø0zìÙå[4z,Hto¢ÇžÝ`F‚�Ésš,IA>ûžácóÁÇ’< ˲§j‡moÄ’§3Ê0ácA;ú6B8ø5ßp€¤àcA2¶Ðð±œ,E`×ÒÝ�”Dº"…x0ÁÇ™ð±ù»ácYüžð±Ùø€�e}y×�Þ½ú’©  …+øXÎyD7 >ãÏKÁÇr-y蹞È^=6'›ác—Ù(SxüÞ½hÝ&Yž°¼§V ’PÖy¥,ˆ—i6WÁA?&€,ß@˜°d9›��eù͸ÁTœ$X@–5âeºôÆdÈæïÕíq6�½mÝ}$€,Û¸@ö €‘ªa�œ³Ïæ@ñ¾ÁÀz¥¦p;ødäñhø¾¯c–bÆ|©ÐöóÉø·R~xó’´�<ý üVZØÍøÆá•‡xÚ_ÄÁ<êò€/é¡�ïèr¡”­P�×-ëïÏïþÜÊ!¯m²Š@n–#·¾xe,ËíYJ ò,%6È,e<ÕëSÎ2<·(Ä46µ"Ù@’‘{Aq÷Á}iE£Ì —Н¼&’ŸGe�ßÀ�äy)~oй°”/M&­rÌÔRs¥@tá‚7øZºîÕXHD OFv%S1·ÎÚýñÎ#6EÜ#çF2šÕäN~06·žCml÷ð¾È6JLJØ_.rs^m} Z–á4Šq¹Ã›·ÑgMs°ü)v¾Æòðîô÷çð>#>¸”0/ %Œè€ºgûÞ'G÷—_Ù>8磬 …$—áV5Úö˰2”à0¸ô®ë¹Ê�­Ú›a¹uTî�Y¥fÜN1^F:ÞIÆ�iÚŒbð×® “$@ADoßDÞÀž,BFòo5ö;éì�ž›)ï 'gÙùJï™@÷1P?·zè’­ÎT¨ŠÎ‘:ä%üdTç÷‰A•ß,¿zÊ×›µÐ*å”� ¤M]¹Ê) žÿ7SÏÃeê2¯Wï‚ö¨JW`ÑÔ�k•{¨+±§Va³KŸ•-š¤²B’‘ k©a¾1òH‘ïÄHFãIÆá'/‡Zž"OÖ™s“ ÅËé1�ž ³:œÆ @b­{KAªrflèni×� ½Þ,z`¼Œc}/qv_/C¯àû*äsË�ßà™V gåë¿…Æ:’�«»^è2õ²’([¾Žp‡8µ¾éXf Õ ¬¼00sª!§ ¾Vp¿å®û-ìWµÖø*@eL!t�0R‚$\©û‡?ßS9‡^ª7õá‡qYa†‹õ!êݾ¾�X´ßÛÊÙ‹m9¾‹ª×`2rNÅKŒœd·ã—»ÂŸQOŸÙ°Ã¢—gEQ#ï˜d�`ºmjÝ€Îåu?s’>Pª K» O{›<Õáý‡¥,i÷Mõ–ʵç‰bÐaŸ†Ëâ]©ÖÑ�A<¤'Òó’wFúV …�½à¯C±D&¿g?‰ñë…q" ª¾©3ÌÍ`¸ ¤ÓWEfJS©ìÆÃªt‰:<;Bi®Ã “X‡Êƒ&îÄìç\�D·R¶þ(*ðµû�Pá“qpnþâ Cò ¨::Žô~ y×⬓Y'ÑC9,е´1+úT*4y5ð~Àþb°Ç¯"dõ´NÛ.ÿ‘2�9«OeB½Mûï?­„Ÿ[“‚êä*v“ck*æÁHm¾9¤÷ƒ±¨÷°z#œ{–bÆ|ižŸ^ÿVÊÏ�Z¦·(”c¸+x`Ħ£W¶ÎWh\dŒèûJÔJä †òØ…%båqècléO|¨Œaí±mÆIûå±üî;ät&œhËxPîùõ‚T vhˆÌ k` NÆS×m¾Ýë‘…[È�wáOFÕ$™²êÞ ¿gÛü@´\‚/{Ær1;Nb3»µ+uüm4ß’SVí!^gñŽÎâ"bSòäX�qð€ã»_�Â%úqCo*Á3§¥Î¢Â¼K«ì¡%”YeW'ÈìþÉÀÎ7›®ÛêÞë4üE©[Yí”YÝØH³9dl³µ~½åó.=zJ¸vKDzb/ý¼ý¹ïŸõv)ä ”×¤sé úPþÀåU )¯}jP^ûHåTÊ+#»f'& <Ë“µ3Âm[æ®c‘D_»�ê�‡”ÎÚëåÛ­½ÂÓ­jI|‰þšÚk2¢eס¤ÄOFj¯ùNšr÷Ô•¤X ~ÚëC†Ùàd��óXµW4±¹Àv‚f®¾Û6¡P,àd˜«“X ²mJ{5žêÔ^û5`ïst©½¾Œ½gÈm«ÚT_?X?·ë´Í2Ì'—Ò´–ž Û/B3úP“@• ;yã¬]{ú„ÿÁ�4ùExK/d1Í3 %§0b>*ûÔÿ²Œ Ö8”¾šõOFÔÈ �µÕÛg­®27þÀˆú±¾ÔÿÊ­!ëÿ^ÙŸÛ8¥CÿÓ?B™ {2¤î0»W†ÀÚ¼‰qšØ17Mì#,P2±ßrc³ò¸lÜLû¸löÇ4šØÇ²# *k9s1ZJ¥Ó…ÀSoxâr+™ØRvm3¶0²ãu;¸ Öõšºƒó÷ÂÈ>ºå‡+Ò®÷c5²�8Zú!d†•ÝaÙÓÊ>¦þÞʱ}-3 'Ó·‰ö­äUéèa—£Ø0ÿLVÄ‘î:`@„ž­øÜ^™üd# äã˜{<ô²Ç3Ý»Íß›l+;æíY¾+;PÕÂK½ËH,[ÙGø†¦™ý£=?7äV�sÿþJF¨¤·/'þd„€Ñ+Ûçkê¨È½³§ Þ=•J'ŸñÒ³ÔQ‘Zg1Q”'XæÉã^Ž%È¿’Øño—íÁVOïKAÃ1ÅîËú5ÕÓ{X ‘zšdèG ƒêi¾-õ4 ÷Ÿ—zšUÓâºs�1ã­¥š?¶´ô+és·´­Nx E—õŒÎ´fú6†NÜdÐwjGÉ(ÙOT´ ñwÝ¡±;¥-üÈÐLï9ïôÅã†l6ËåïRƒ¸Û0ÙõˆÂ�ê'i[f½]§ ³û'â"ß´zše‡™ŸV³bRJ³â¡£ºa[>ÐÓdÌ×{>ïâ¯<œ@!Yº˜µ»ÁžÕÿÃ(<ëí¶?v@€ŸIŒÅ39±ÙæKÓ_¬ô´ä[鰙儃&Ë™›�r�NÓ#fÁ^í`¤{?Ózºplž§_sõZÛHÔ²iÔžíÝñÀáÚÞË�eßeŽÞž›� Ū]hóŒäÝÞ› BéßÞãÀh7qضØ}I�±Zô&']Ü»b¥ÃŽËÝàx›éwÓɽWk9örïÕÑ~ì½Úµ�Žî§évÆ#gêÆtuïaéM_÷ñ vvïNKÐ^¼½0ìeNŽ]Þ(â¸s;æGê˜ÂR0�ökÓí�!»Ö Œb›ÖŒÂdÅ|"¶üC·ô€»ZT«Q{ï÷2ý”Fø2¿ §§H‘tƒS{nÌÊ‘î]—KNø^¬7ÏB›9‰w‰)^zìÐÑ�V9èGöâÞs‹æªé×ËýÙ8„í> Þ¥'G±B¿È¹"àç^]Ø# Vu0}à 6 Ø>­ ¨Í�ÂZµ»è²tÁ-ϽMžÚK{»ydv¿1r;`Ðþ.¼lÊ|âî‘^Åæ|¤zZŽëšñ‘· g5š‘G£ž!'¢!sõܹw(§nŸ @�ÍÎj‰·¶§õ_pxÑßMWØäˆ´@%Ûó‹}t¢.ììc÷ŒêBSÄW­Í·¨&1wº/�CµK]åÄ­ˆE” ‹Äƒ¸S’\J4XÅêeÅØ€~Ìjµ«5Ò2MÏ!§dìÙ‹Fè¶üJĦÍz(º‹õ,« ¸m0N·5[Ûis즒oÚƒôña#ÛÀ™Ñƒ?öEØÇ·…¤¸®÷Å¥¤L-ÜÜ““[ÞqÚÑÿ¹–ஃ°ÎË&ˆ(£úÞu«äÞ�jÕ/&fµ9‡Ë0~󑦬$ï‚ÞY÷ÀCó5÷Àƒ8tË&xDx@n‚ÉÉMP/Í]ðh^?±  2¦²ÇbºKšWÓ:$ô/ÁD-SWè‚Ëì>|MsÌÝãœs'˜žé¶×”8cÄßÛºûçÜùŽ3£HÔÓ¦~İ,ç ¬¥æ\¬–ä¹ó ür>0ƒ4ó%4ÍmÝø28Ïß2é„¶ø: 5Y ª³ì|GK·w¾cº@¸óEÎîÜù00¥,;Ff9ˆ²mçKø×Þõx¢äqN[ßQ¢’[z°-!`X¡æ.Ž Ë­ï½q?™í·;’á�JÇÜ}©¼Ž‘¹¢Þª‰(‰¼Äˆ&¹ Ô§ÀÁÜùÎÝËL;’�sißJ[#2u#n}Çðê?�¸8)sœí1x=+Úw'¥yÂß9$át”Ç|Ĉ‰áJ/Ô�„øè­N¬¸ÃŠiÈ· ДºXNÇ»ø["ìÙ˜„v³‚(&Ó¹KªŽÆbFg—RIœÏó°6\Áœt@Ön+«;øpÌGfú:†tŽâ8c[fù±Ê…ˆž¢cP½˜O ›Z¼q3²®YŠh|äòxÆÞ¬›µ´{ó…`´˜w‡qQ¦$i»bøê‹1Rg s—Ý$l™•ŒÛbåö¼‡Y¹a}vÂ÷á߯ÌÂ-­EµeN;6FùÛ“–Ï~r*룰Ã'Éi›j¾" é«(�ÛΣ/Ž1ÒáÇctYÕ›H•Õ¦Z!Šel8@‚=ì˜ëƒ 1\t G%–÷Ï+W®"öVSp�ˇFÉa|Ó›ô± “‚�C�pXHˆö›“•ý·òÝByQ2ú £cÿ�pº6hX7›×Ýô§·s[J¾È}~•†��—,Î�°RJ}VTý®›9ZBB/ƒnV£º’` ­¸¥ìbŠ«Žy ôBç§ãÜãÅêó^ØþøF³Ö"rI£–:ŽfÀ˳¼Áe¥¬êŽ7¿taÔÙ~8V†ØAgsAÜÉŽ‡h/ûÐÔÊfwV¶j2ÔQ~Y‡´YúW|å÷]õ•ÕÛýF×�àÛh=Xž§)'8(‡æÓ£„?påDð[ƒ+è)¶}©OÙ—µG2 Òüºx)îŽç¥–ä·l-¦Ê‘QðïœLÌ—ÌØ&'SbN¡}ü‰3‹ig›¬üz¾ö'Žuòä(¼ô©u¥% †Îu»ïçRˆ5ôl™ãñ˜‘ц©ýD lµ¹-Bãµ+£ß(ߊÎOwàf{{1Žð²†ü¸Œ�›dÈ­žûQ‚�dŒÅâG|:¶,/Å}¤ 9ÐDˆ=§”ôayWzšFD¿ùHM7‘©KMç¸eZgaCªÄ…« W†·¥…ñràY�T”P2r2å[Ÿœpl£z„cuÄ«[e §JŒæø\-€íRg =_(ëif#ãí$Ž~^8 Ã‡Ê›Üú4í%r €Ž˜â•,´¶“!È¥§ÄÈ6ÂÖ¶�¡�,öOM§¯¡ã¼¥üIjTï[Dç¾Û’µvg‘Cy2|_1r¢¼,ì\ëçq´XhQÄÒ�ÖÖ x)ž>©€£Ç˼X3ÂéØÛ6ˆÍ¥“#êœ8Õð¾§r:^îL�0YSÇ—ì’¤ô@ÿ…§jWÿ©¥Uǵ#¥ðð0—•f΋öPª'Fb›ba›b~$mŠY�°)–E5gßÓŸ¤W²±~"ºÂ6Et•¼MV3³/mQ̾¶E1G#,ŠÉH‹b¾âSKÝÓúÇSM ƒXšQ©Î 5ãc9\¡]3ŒÎ]=1zyx»W’ "À G¡rYÎØ¤¸Ð1BWJ"I„+‚RlR̯¤I1ëa“b‰ÓT¬£ÛáðÓ¤XÃÎëGÐÎÌ£žÎ1Z´tôgh<·úÓÚÅ·5Ä¥ö±®°ÖŠÕÛȵ˜œT^j³ÊöÉ™ÚT¾–ªRr"3fr|}8Ò œçÉ}¤–ÈWLE¹–Kr ÈÐxj­4c³bVÍ×z®µÍ�7_›œbó”8 �™"sT8i6z”ë9 Öœâg¥´…ŠL™ÉÉÔ È=^ÔËäÌ®Ž×>9»î4¢úñ1ŽÛñ"ä0¶—`�BìÕ+CO°!²}�@s5¢Ü5 ‚{Û/>é\, ‡ª¼^—8ÛóÛ*ÏêeU3Fø² /„Õx^ßäÔkYÖ` /jqçˆ�ÜyT=nÇE=I¿Hæ|¤Èn�Eñò#³¯Fš+!�·Àû÷áÐ’\‚ÝøŽÌN! Œ%;½’*Ö�ªífU°ù·]`ÛY¸O'élÜÂá•4*âËæêmùÊìõ¨‡…kÖ3’ £%3KúÒm(ó‘}¨"|ÁÅò+¶š×æ| àʈa ŽÛZSá`Wä'²·jEF‡^™!«’?Ó³ºZM‡±o·jº'í×­zë` )È#$¤¬–GѳL"}è"`î.¯:èpÜ*‹œ°šÇat.ÔRÚ™áÛÖJš¬øÒÁÒ²þ)•t¥m™gÍ(<Úñ’A¸rR.eAop=ŠÚXclªÌpÅö †lhpÄ¥ð”ØâÌ)îuuo¨S�%*kv»ÒJ9*mX¾b"‘•ó®M'ŠÆ-â÷"»ôsð1!Ú�2›�ùÐë!:¤gÚ]t£_š4Ášf—xkFÐd9 å,(!ïå%¿Q–�CãµÑ`ÌÚ"ÛmÏØ�Ø_„°/Ê€«š‰�éJ¤íZë�~Ÿeò|ó6!…¹pø$0A$„Nœ G¸EbÏ“YÀH fq%bŒö%FÙP‘ôVcÆfD¦Ÿð ò$bŽG�îÝçŒ"ž’ÚÈ›Ãý>³ 'ñÞ4¬Éžqñö$&'=‰6ÿ¤'±Ïl&zørÞ¥N�Ȧ­nÙ<˜jêË�׺Ð<ðÚ�žDLµ%Á ¯”Ìà·—ô=j%$Azóy¹é|¥#ûzµ™çt¥ŽH\¢#±WíH„gȱš^lÐñÆ´(üRïLG"4øð#òxêà mÉÝ�çö#öîxû“ž~Ä…E•£÷©ÀBqì‘KÖ—¡™™³Uc3Ö(;~m ½fÆtó·Ãf„æ×cùHñhúDŽp*…»ºÌÜ'Ϻþ—¨eÆ3yððaËA¯3�‰Ñ ?b¯>ú¦Å¶7Ï*l{ûá�(ºí+\܈ø¥ŽÅ�Ø[ó5 'mûerìFì-ãaäFìÍâ6݈²m¤±7e™Ù‰”>DüÐÉ#]eÎ>D¯ù´±÷På ÁaPù1"±°‰&�>Ä…C"ÖÑ>ð¡UòâCÄçº-ƒ°p•¯2½Ú�;¥~Kˆè¿14D—39c‡ô½FáCÄÔwrf÷ªJ­ô!~ÈAÈF]78}ˆÝ™b —oÙµÕ�f󕞯0iÛEbdoÃ3�ùÆíü z×Z*h2ªÎ3³„øZ,Qûþ²‚v F ä<ÔRu+§?±‡f'$^:'eŸ'^;%ñ™8YóJÎþ%»B“^š :SUBˆ÷mùHèâY ;l³–v辎–õmÂK ^˜' žc§w1ÚØ!<‰'tÞ 5|F‘³æ…ÌG ˜g*ôâ“ Ÿ×¸É&x^”%l¼WªÑTÄ#ÒwS´@Ì«º»Çpy¾+U`yÜ÷d^„r, Ù|ú*W‘òª‘à…�§»- �Pé™ãŸÍxç$¢¾—®ò}!Ù!_ÆÀ[ÿ®Fà^aÚ¥°ðà,ø²[Œ–O¼/ç¨@ˆIúOÄwàù7Áß%¡ ýîKy‹ß}Wéeð T_e¼ Ðz#–�w nKÀ;ÁÒ'ÜÝJ"Ŝѷ‚ºûÒ)›�îd”ú˜»‹ªžAî.Ù ”Æ$‹ƒæ ÿƺ T#Ê1N·°í.ߟª4Z…bwQÚ~9´®ÓN ïF´SfªñìFÜ¡!0;cÁÊN(î²Û¾Ó]8vþ±�ñ ÇŽ3:'»‹ŠŒëx·èf‚;²ž#Å;˜\§ûf [Wø½ï@­“õW˜u[LBÖÍÉC¼:ÿ$´º"7™°êJ|YHu5.PæèÛ¸µÎŒ ê¦äéD¨«Æ!„’!·—Áét�Žjä-â¦�!_T¯tÄ õŠñ÷o‚¤“ûÒ€t5JhtÕ– �ÑÕxí¶æ[ËÞëüs;{Î}Ž ÷)Õ÷� YeRÂêô­d�V§thK«Ó(1òŠKá‘–^equêÂzýRhñ”¼z‚½X`�²ðHb� ”•Ì2RË$+�ùŽ»9�¼�iiå‡_©�^§NŹé:jR€�Ò¹B€�:4H‚tž“’T¥m!¦!®¨9GO^ñdPG]‰"ì”*\í(µøÊÑÂP.C÷ŒãÅÃañ�.Ú°{Ùz4È¿ã]öA¼¢°Box~pî¯oþÜŠ+„g’’–ˆ+9Ê YCx¥æ[x–ƒ]³hŸ•ð,º½S"þÿ^R¾Ð#Þço\[žð§_)<á³n!<‹lžˆƒ¨SxšLáég%d§#{$RŠ“·$�Þ²³@ˆŸtÙ­Dg9¸¸Ct¢Î¢S²‹Î¢+h§ì|­3q%ôr¢"˜Ù•S,W‘Î3(Ÿ‹¯)#äßs–„×wP"<ãÅØ‰â‹w‹çdü†P ‰ÀrÑ-lEW³ú¾Ï¢Ûæš>ï1•êmÓ â¯¤åFrÄdˆÇ¢ ­ �¹�eYh}ª Ú®¥û~ÖóeqIY({¢çïOÊ™æy?©×øÿð¬âZã“\X\ E÷NfËxTŠeÇßïÃD @œXåðù ÜC(Æ"Opc�1ká<Š�;I’u¼åJ’áUÔ¶}=8(]°�á­FYö´½î4R\¾2¦*¶ñ’‘¾ùÊBèP«ó4Ad;Ìaÿ¦“í¥1?SXÕ2nëÄíªJÅëÒDèÖÁïI^C6þ*»Y£dÿýe2¦…#/ß2‹¯h-wI:ž1Á° ª�(NØîC° V­CI½ºû9IDô;Î-‰·`+¤êáF‰ËÍ@ÄÊNùxq .(ÊÂDçÁsûžôÙ…YO‹Ë‡À$n¾VÝc¬�R03(ƒ¼¼™Zúð @V’;/4YU&€ãÿ�ìš­zΣ�ÆÓìi¢8˜MQ†Î9îàï¢Âͳ钾”ŸÙÕH`¼1níù›k!EEjó"Ê',𢘄_ò”a¨¹è¥º[?Á(<„û©ÙH‰4Û3cáOÊT©WE«¤á'jÓÐŒs-³1�×ùù¬á‹ŠR,jƒÍIöÂóOí²·^ÑaWÂ+vË^„ {NòÕp|!{‚pÄo³dC+OB!yá7¾®�¼•bV‚7þ漑+Hºób–Ïn¯d Ýj8W�‚vªúºµ»«%t«¼JEnÀ†Ì­—÷&Ø¥e¿©»x Ð™ ò’’€ÉÇk­,t=Sè¾�ÏÏ­ÚÄ|1Œ(ž~� ”ªÕ` ôàùû¤‚¡KášS¤Â´� Gëp|m®™¦ô¯™›#Y;RjI‘Ñ áœ…±!YÏñIŒ=�3oh«E%⥮]âÖÅU�ïøœ’®ˆT8W2ô97À¿ÉvqèÝîËê’ºDÇx÷•†ÉݨñürX5ÇñÆ#7ùÔ0çX>uU­í¶Ûö?SSº’doSNðPf�ACNv³ÆA¿êšìhZÒ¶1qóð´Z`!"¶µ[9Ð~C×øº0ý�µªQ4YÑŸç–5ûºSZtŸ˜FÒùšW‘ªÊ>¢a Â—³NRB6¾LÚŸ¼ßˆª‚Ž]&c·þbI4§f“UN‡¦cNÍ­[=å©ùZdkÜÊÙ­M»Þ7(`tlúIί™j]ZÇfE)øØì�›MèØ¼}�Õ§ëì•ò©ÐO¾RPÛ—ƒ dôCm$¡ø7å«ÎÌ­1¿JƒÒ蹊±kPo–qíÀÖ�ÂPÕ¡¹É‡æ¦Í_bÚƒSu;üËÈ} ÎrÊŸ[×™sø–7ø‚ŸÝ\"p÷¯›#];ðMïÇ7H^þK� lÌ�–Ë“$Ý»ïWÄ•OõúWÐÂeú…Ç_)zD7)A7Cð™õQc'ÐðÛ3U¶Gõ úSg0†­qEÕiÑý�Ïç �î}†·OMpA:éaF•wýŠƒ°!…âé¿ßûï'°èd¾Õµk@,Avù¸¥ªôá ÄyÑ/Ûk±Î»­ÎÊ•²ÃdçTðk�;©K ‰ld'JdÂð])’]É�[ðÂìçüí¦)  ðnY$ 1ÒúÞÅ‹BUýu ŠòîI{¯Ês£7Ër{ëfW­ÝhØ¿içemã >AÕPñ€;œÖÄë kZ);4q(ŽØXIÌ“’?ØïÈâ â¢§ü%Jÿ-*¡�Á m+õ°oôk±oô‹¢*;§Æ{óçz瓪ˆ‰y‘ª¾^sÃ\dÑåîßñ=uˆk¢®zéÆ?ôëÏíP‰­[¦N_À|Ù“>IfV�¼tí¤ Ip“"¢BâýrÞ‡¦Š!Þ¹3&áá*Öʵ¾®F“Ë/iÝï�O¿�é«Qjúɇ�ÃxÐvè—ƒô—ãéò´/I.GÒôtóçëà!“ b …|²‘²k/…ÀZ ¿uûÏmR]+CÍEÉîOGÄvU^æ: ÜL3 ®ÁT�PuŽk—ê8Ö#ÕPnp¬“¡{D^HúuÏ\r¬U¡K|ƒæ9‰Úâu{›Å$OB×¶&‰Ã(Þ¢Á †Îë–'¼ùFØëælWÙ¥°)Ýô:d)h^Sc§„h¶ÄáÞo:ÅŽ´oTƒ/êü3NÞÚ)Ɔ‚?q?FþÉNØ‚¾ØD¼tУ€ð°¯èØƒî ª•èVR²’ƒÞ»iædsBD ¡´ACãD—”žÚèCbXâ5~ÐtÏcîe3¶ûŠÔ剀‹M¸(@æ‘èïÔ¤ÙÁ1}ö°Œ*¨oüÍÆ`çOˆ5ÒóiðÞ´+@kBûivÀ‚a¥Á”0Ñm¬HºÊf@çÁ £G|X[…0Wigâæ½3 Ë #�h÷ÍȨ?÷¼�y4ëBMD/aãA÷Œiå¸ìæÅ~O´T¸„ç`‚©—ßÛ$xr ˆ‡Þº©”g¿žÔ½±O¬*úØ…bÍI ß0�”tôÂÝRIçb¦~q²», ‘/½ ¢>¾ˆG`T]ŽLåê÷—É`•ü %üòaËFÓrŒ&©›¹‡tl)�£Ò�~IŠ ™¯¥:ŒªHq9 1ž_dV'DµN¢²‡~Tß1“â(4d_:ŒÂò4͇27/žÔMt)—ßAgûOko¤;+~!¥´@ |ëz¢ÛÂÛv€!X*�nc9d¦yþn< XLÝá.l.õâéöæR3 ®§3—¿ [Ýpnmëi¨—ujUz_¶Ô$ÁÅa*û¼Û ùB¦‰ÜOg—ˆÌø‡‹ ’µâ ç¢HqšÈÇ Ê`÷t^”æ Êh ý¦nƒ¹ýY�i#aØãòºm-á$ШLsÍÛ0ýÜîpÎáðúûËd´òV2ø©ØÒ…db÷C5 jŒÉ­ãöåÃéCÞ\ À=%a˽OG0tÚ�oxòÊ?2šðKF¾›™^˜Ûè›[‹ soº5‰å¤Hâд7�-¨?®w*FÜ�¾‘4�m¢15î¨VîøµIEq¦l¤±ëø¦¿ƒ‘‡9’Pã^ÇUp¯�vĹó¼s~|p* ¬Åá­°RA� �žH>Û2Rr0æÇÚ`X†ªZVæø•ÞBG‰ÖL½í€ÁK¸†Óó´¾8©Þý¨laÙ«kE2-9æ~á�­‘ßf«„²‰œF˜ú1(¬6÷Q)ŽlT/V ôx‡50P3’x“é›�� í‘””Î3ºV®RkbPhH£Ìà€µOa´ëbDwñ £MÚ�³‡®}¡aËÓZ#”æ©h0aoB“ÏXZ`qJC0í¡$ GÌÝÁ Ž8E(æa'›àÔdßm‚ÀÓ.Ø&øåÄ6›L ·ö°ÉÉÞ°}'ƒ‘a_¿òq‡Õ"Žô®W{\Þϯyt kåÚ"îöÊàZ„ݶ{®MD…^#­ÖF^‹(ãhëFŠÂ•C¦»Fpl*Cl“æ6Æ8ÑÓŸ™4zŽ8Úöe=�Ã$“ψÛÃ0‚…ÕM‰Ž¹=.»ÑtË8g¸ÇÏ0²eª¦„éÌè1¶öˆÀÛCYF ÛÜ3ôÞ5w£<ÙzS8éKôí[ €nwZG–õ"è0p‚î 7€…Ê’‰”"RAöML=ŸÞ‘4ua°¹…·'9áFž»O@ú5ì2´{/Qaü#+e„âMHÆn[gÖ‚dàMÀ*ÊÚIÔÅ^ÒÚIˆÀ}ØÜ)€ÀÃöN¢jR»ÇG6µ­1ôÞ©çÉÌ_™´@AÑ&êâËÞ%Nm ]šÝqjÓ€ÝsþÝ"Z†O¾ÈÈSÈPòßó°³in›*ÙÝw¬["®;¬1\Gvu}(ôì¤ÂÔŠ˜¬wž8…�©ˆSâ;ßvé¹ M‡”O•%µn^ÆÅC‚£ä©…•8ÂHÝ/‹'«�M'ì¡`HæÆÏR¹ÊÑGâÓ½-ŸL¢ ”vyê� ›h’-õæa£(Ç—¹µE€š¾âÁ�—ì‰ÞÃ({WÜÙ2*xJn?”_ˆ“¢WñîaÅ·ìS,F-Rö°&-7›Û pv§#Mðž:J¼Ö•:íìo:ó‹€g{��™“½Õ™žì­-?�¹£cîpœ[&\¶”R^P&MõU¼ ñUàüÜþkûÿpX:ô endstream endobj 5 0 obj 39965 endobj 3 0 obj << /ExtGState << /a0 << /CA 1 /ca 1 >> >> >> endobj 2 0 obj << /Type /Page % 1 /Parent 1 0 R /MediaBox [ 0 0 200.204224 302.29306 ] /Contents 4 0 R /Group << /Type /Group /S /Transparency /I true /CS /DeviceRGB >> /Resources 3 0 R >> endobj 1 0 obj << /Type /Pages /Kids [ 2 0 R ] /Count 1 >> endobj 6 0 obj << /Producer (cairo 1.15.10 (http://cairographics.org)) /Creator /CreationDate (D:20200702143407+02'00) >> endobj 7 0 obj << /Type /Catalog /Pages 1 0 R >> endobj xref 0 8 0000000000 65535 f 0000040384 00000 n 0000040153 00000 n 0000040081 00000 n 0000000015 00000 n 0000040057 00000 n 0000040449 00000 n 0000040724 00000 n trailer << /Size 8 /Root 7 0 R /Info 6 0 R >> startxref 40776 %%EOF math-comp-hierarchy-builder-4d8a939/examples_stdlib/Coq2020_material/diagram.svg000066400000000000000000014363761521677141400276120ustar00rootroot00000000000000 image/svg+xml Structure Mixin Factory Packager Builder V1 Monoid Ring V2 Monoid Ring AbGroup V3 to_AbGroup_of_Monoid Monoid Ring AbGroup to_Ring_of_AbGroup SemiRing CMonoid Ring AbelianGrp SemiRing_of_CMonoid CMonoid_of_Type AbelianGrp_of_CMonoid The puzzle pieces (mixins) Ring_of_Type The "virtual" puzzle pieces (factories) The hierarchy of structures math-comp-hierarchy-builder-4d8a939/examples_stdlib/FSCD2020_material/000077500000000000000000000000001521677141400254365ustar00rootroot00000000000000math-comp-hierarchy-builder-4d8a939/examples_stdlib/FSCD2020_material/V1.v000066400000000000000000000047601521677141400261220ustar00rootroot00000000000000(* Accompanying material to https://hal.inria.fr/hal-02478907 *) From Coq Require Import ssreflect ssrfun ZArith. From HB Require Import structures. Declare Scope hb_scope. Delimit Scope hb_scope with G. Open Scope hb_scope. (* Bottom mixin in Fig. 1. *) HB.mixin Record Monoid_of_Type M := { zero : M; add : M -> M -> M; addrA : associative add; add0r : left_id zero add; addr0 : right_id zero add; }. HB.structure Definition Monoid := { M of Monoid_of_Type M }. Notation "0" := zero : hb_scope. Infix "+" := (@add _) : hb_scope. (* Left mixin in Fig. 1. *) HB.mixin Record Ring_of_Monoid R & Monoid R := { one : R; opp : R -> R; mul : R -> R -> R; addNr : left_inverse zero opp add; addrN : right_inverse zero opp add; mulrA : associative mul; mul1r : left_id one mul; mulr1 : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; }. HB.structure Definition Ring := { R of Monoid R & Ring_of_Monoid R }. Notation "1" := one : hb_scope. Notation "- x" := (@opp _ x) : hb_scope. Notation "x - y" := (x + - y) : hb_scope. Infix "*" := (@mul _) : hb_scope. (********) (* TEST *) (********) Print Monoid.type. (* Monoid.type := { sort : Type; ... } *) Check @add. (* add : forall M : Monoid.type, M -> M -> M *) Check @addNr. (* addNr : forall R : Ring.type, left_inverse zero opp add *) (* https://math.stackexchange.com/questions/346375/commutative-property-of-ring-addition/346682 *) Lemma addrC {R : Ring.type} : commutative (@add R). Proof. have innerC (a b : R) : a + b + (a + b) = a + a + (b + b). by rewrite -[a+b]mul1r -mulrDl mulrDr !mulrDl !mul1r. have addKl (a b c : R) : a + b = a + c -> b = c. apply: can_inj (add a) (add (opp a)) _ _ _. by move=> x; rewrite addrA addNr add0r. have addKr (a b c : R) : b + a = c + a -> b = c. apply: can_inj (add ^~ a) (add ^~ (opp a)) _ _ _. by move=> x; rewrite /= -addrA addrN addr0. move=> x y; apply: addKl (x) _ _ _; apply: addKr (y) _ _ _. by rewrite -!addrA [in RHS]addrA innerC !addrA. Qed. HB.instance Definition Z_Monoid_axioms : Monoid_of_Type Z := Monoid_of_Type.Build Z 0%Z Z.add Z.add_assoc Z.add_0_l Z.add_0_r. HB.instance Definition Z_Ring_axioms : Ring_of_Monoid Z := Ring_of_Monoid.Build Z 1%Z Z.opp Z.mul Z.add_opp_diag_l Z.add_opp_diag_r Z.mul_assoc Z.mul_1_l Z.mul_1_r Z.mul_add_distr_r Z.mul_add_distr_l. Lemma exercise (m n : Z) : (n + m) - n * 1 = m. Proof. by rewrite mulr1 (addrC n) -(addrA m) addrN addr0. Qed. math-comp-hierarchy-builder-4d8a939/examples_stdlib/FSCD2020_material/V2.v000066400000000000000000000045551521677141400261250ustar00rootroot00000000000000(* Accompanying material to https://hal.inria.fr/hal-02478907 *) From Coq Require Import ssreflect ssrfun ZArith. From HB Require Import structures. Declare Scope hb_scope. Delimit Scope hb_scope with G. Open Scope hb_scope. (* Bottom mixin in Fig. 1. *) HB.mixin Record Monoid_of_Type M := { zero : M; add : M -> M -> M; addrA : associative add; add0r : left_id zero add; addr0 : right_id zero add; }. HB.structure Definition Monoid := { M of Monoid_of_Type M }. Notation "0" := zero : hb_scope. Infix "+" := (@add _) : hb_scope. (* Bottom right mixin in Fig. 1. *) HB.mixin Record AbelianGroup_of_Monoid A & Monoid A := { opp : A -> A; addrC : commutative (add : A -> A -> A); addNr : left_inverse zero opp add; }. HB.structure Definition AbelianGroup := { A of Monoid A & AbelianGroup_of_Monoid A }. Notation "- x" := (@opp _ x) : hb_scope. Notation "x - y" := (x + - y) : hb_scope. (* Top right mixin in Fig. 1. *) HB.mixin Record Ring_of_AbelianGroup R & AbelianGroup R := { one : R; mul : R -> R -> R; mulrA : associative mul; mul1r : left_id one mul; mulr1 : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; }. HB.structure Definition Ring := { R of AbelianGroup R & Ring_of_AbelianGroup R }. Notation "1" := one : hb_scope. Infix "*" := (@mul _) : hb_scope. Lemma addrN {R : AbelianGroup.type} : right_inverse (zero : R) opp add. Proof. by move=> x; rewrite addrC addNr. Qed. (********) (* TEST *) (********) Print Monoid.type. (* Monoid.type := { sort : Type; ... } *) Check @add. (* add : forall M : Monoid.type, M -> M -> M *) Check @addNr. (* addNr : forall R : Ring.type, left_inverse zero opp add *) Check @addrC. (* is now an axiom of abelian groups *) (* addrC : forall R : AbelianGroup.type, commutative add *) HB.instance Definition Z_Monoid_axioms : Monoid_of_Type Z := Monoid_of_Type.Build Z 0%Z Z.add Z.add_assoc Z.add_0_l Z.add_0_r. (********************************************************) (* This test from V1 FAILS in V2, and is repaired in V3 *) (********************************************************) Fail Definition Z_Ring_axioms : Ring_of_Monoid Z := Ring_of_Monoid.Build Z 1%Z Z.opp Z.mul Z.add_opp_diag_l Z.add_opp_diag_r Z.mul_assoc Z.mul_1_l Z.mul_1_r Z.mul_add_distr_r Z.mul_add_distr_l. math-comp-hierarchy-builder-4d8a939/examples_stdlib/FSCD2020_material/V3.v000066400000000000000000000072161521677141400261230ustar00rootroot00000000000000(* Accompanying material to https://hal.inria.fr/hal-02478907 *) From Coq Require Import ssreflect ssrfun ZArith. From HB Require Import structures. Declare Scope hb_scope. Delimit Scope hb_scope with G. Open Scope hb_scope. (* Bottom mixin in Fig. 1. *) HB.mixin Record Monoid_of_Type M := { zero : M; add : M -> M -> M; addrA : associative add; add0r : left_id zero add; addr0 : right_id zero add; }. HB.structure Definition Monoid := { M of Monoid_of_Type M }. Notation "0" := zero : hb_scope. Infix "+" := (@add _) : hb_scope. (* Bottom right mixin in Fig. 1. *) HB.mixin Record AbelianGroup_of_Monoid A & Monoid A := { opp : A -> A; addrC : commutative (add : A -> A -> A); addNr : left_inverse zero opp add; }. HB.structure Definition AbelianGroup := { A of Monoid A & AbelianGroup_of_Monoid A }. Notation "- x" := (@opp _ x) : hb_scope. Notation "x - y" := (x + - y) : hb_scope. (* Top right mixin in Fig. 1. *) HB.mixin Record Ring_of_AbelianGroup R & AbelianGroup R := { one : R; mul : R -> R -> R; mulrA : associative mul; mul1r : left_id one mul; mulr1 : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; }. HB.structure Definition Ring := { R of AbelianGroup R & Ring_of_AbelianGroup R }. Notation "1" := one : hb_scope. Infix "*" := (@mul _) : hb_scope. Lemma addrN {R : AbelianGroup.type} : right_inverse (zero : R) opp add. Proof. by move=> x; rewrite addrC addNr. Qed. (* Left factory in Fig. 1. *) HB.factory Record Ring_of_Monoid R & Monoid R := { one : R; opp : R -> R; mul : R -> R -> R; addNr : left_inverse zero opp add; addrN : right_inverse zero opp add; mulrA : associative mul; mul1r : left_id one mul; mulr1 : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; }. HB.builders Context (R : Type) (f : Ring_of_Monoid R). Lemma addrC : commutative (add : R -> R -> R). Proof. have innerC (a b : R) : a + b + (a + b) = a + a + (b + b). by rewrite -[a+b]mul1r -mulrDl mulrDr !mulrDl !mul1r. have addKl (a b c : R) : a + b = a + c -> b = c. apply: can_inj (add a) (add (opp a)) _ _ _. by move=> x; rewrite addrA addNr add0r. have addKr (a b c : R) : b + a = c + a -> b = c. apply: can_inj (add ^~ a) (add ^~ (opp a)) _ _ _. by move=> x; rewrite /= -addrA addrN addr0. move=> x y; apply: addKl (x) _ _ _; apply: addKr (y) _ _ _. by rewrite -!addrA [in RHS]addrA innerC !addrA. Qed. (* Builder to the bottom right mixin. *) HB.instance Definition to_AbelianGroup_of_Monoid := AbelianGroup_of_Monoid.Build R opp addrC addNr. (* Builder to the top right mixin. *) HB.instance Definition to_Ring_of_AbelianGroup := Ring_of_AbelianGroup.Build R one mul mulrA mul1r mulr1 mulrDl mulrDr. HB.end. (********) (* TEST *) (********) Print Monoid.type. (* Monoid.type := { sort : Type; ... } *) Check @add. (* add : forall M : Monoid.type, M -> M -> M *) Check @addNr. (* addNr : forall R : AbelianGroup.type, left_inverse 0 opp add *) Check @addrC. (* is still an axiom of abelian groups *) (* addrC : forall R : AbelianGroup.type, commutative add *) HB.instance Definition Z_Monoid_axioms : Monoid_of_Type Z := Monoid_of_Type.Build Z 0%Z Z.add Z.add_assoc Z.add_0_l Z.add_0_r. HB.instance Definition Z_Ring_axioms : Ring_of_Monoid Z := Ring_of_Monoid.Build Z 1%Z Z.opp Z.mul Z.add_opp_diag_l Z.add_opp_diag_r Z.mul_assoc Z.mul_1_l Z.mul_1_r Z.mul_add_distr_r Z.mul_add_distr_l. Lemma exercise (m n : Z) : (n + m) - n * 1 = m. Proof. by rewrite mulr1 (addrC n) -(addrA m) addrN addr0. Qed. math-comp-hierarchy-builder-4d8a939/examples_stdlib/FSCD2020_material/V4.v000066400000000000000000000122131521677141400261150ustar00rootroot00000000000000(* Accompanying material to https://hal.inria.fr/hal-02478907 *) From Coq Require Import ssreflect ssrfun ZArith. From HB Require Import structures. Declare Scope hb_scope. Delimit Scope hb_scope with G. Open Scope hb_scope. (* Bottom mixin in Fig. 2. *) HB.mixin Record Monoid_of_Type M := { zero : M; add : M -> M -> M; addrA : associative add; add0r : left_id zero add; addr0 : right_id zero add; }. HB.structure Definition Monoid := { M of Monoid_of_Type M }. Notation "0" := zero : hb_scope. Infix "+" := (@add _) : hb_scope. (* Bottom right mixin in Fig. 2. *) HB.mixin Record AbelianGroup_of_Monoid A & Monoid A := { opp : A -> A; addrC : commutative (add : A -> A -> A); addNr : left_inverse zero opp add; }. HB.structure Definition AbelianGroup := { A of Monoid A & AbelianGroup_of_Monoid A }. Notation "- x" := (@opp _ x) : hb_scope. Notation "x - y" := (x + - y) : hb_scope. (* Bottom left mixin in Fig. 2. *) HB.mixin Record SemiRing_of_Monoid S & Monoid S := { one : S; mul : S -> S -> S; mulrA : associative mul; mul1r : left_id one mul; mulr1 : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; mul0r : left_zero zero mul; mulr0 : right_zero zero mul; }. HB.structure Definition SemiRing := { S of Monoid S & SemiRing_of_Monoid S }. Notation "1" := one : hb_scope. Infix "*" := (@mul _) : hb_scope. Lemma addrN {A : AbelianGroup.type} : right_inverse (zero : A) opp add. Proof. by move=> x; rewrite addrC addNr. Qed. (* Top right factory in Fig. 2. *) HB.factory Record Ring_of_AbelianGroup R & AbelianGroup R := { one : R; mul : R -> R -> R; mulrA : associative mul; mul1r : left_id one mul; mulr1 : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; }. (* Builder arrow from top right to bottom left in Fig. 2. *) HB.builders Context (R : Type) (f : Ring_of_AbelianGroup R). Fact mul0r : left_zero zero mul. Proof. move=> x; rewrite -[LHS]add0r addrC. rewrite -{2}(addNr (mul x x)) (addrC (opp _)) addrA. by rewrite -mulrDl add0r addrC addNr. Qed. Fact mulr0 : right_zero zero mul. Proof. move=> x; rewrite -[LHS]add0r addrC. rewrite -{2}(addNr (mul x x)) (addrC (opp _)) addrA. by rewrite -mulrDr add0r addrC addNr. Qed. HB.instance Definition to_SemiRing_of_Monoid := SemiRing_of_Monoid.Build R _ mul mulrA mul1r mulr1 mulrDl mulrDr mul0r mulr0. HB.end. HB.structure Definition Ring := { R of AbelianGroup R & Ring_of_AbelianGroup R }. (* Top left factory in Fig. 2. *) (* It is an exact copy of the bottom right mixin. *) HB.factory Definition Ring_of_SemiRing R & SemiRing R := AbelianGroup_of_Monoid R. (* The corresponding builder is the identity. *) HB.builders Context (R : Type) (f : Ring_of_SemiRing R). HB.instance Definition to_AbelianGroup_of_Monoid : AbelianGroup_of_Monoid R := f. HB.end. (* Right-most factory in Fig. 2. *) HB.factory Record Ring_of_Monoid R & Monoid R := { one : R; opp : R -> R; mul : R -> R -> R; addNr : left_inverse zero opp add; addrN : right_inverse zero opp add; mulrA : associative mul; mul1r : left_id one mul; mulr1 : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; }. HB.builders Context (R : Type) (f : Ring_of_Monoid R). Lemma addrC : commutative (add : R -> R -> R). Proof. (* Exactly the same as in Appendix B. *) have innerC (a b : R) : a + b + (a + b) = a + a + (b + b). by rewrite -[a+b]mul1r -mulrDl mulrDr !mulrDl !mul1r. have addKl (a b c : R) : a + b = a + c -> b = c. apply: can_inj (add a) (add (opp a)) _ _ _. by move=> x; rewrite addrA addNr add0r. have addKr (a b c : R) : b + a = c + a -> b = c. apply: can_inj (add ^~ a) (add ^~ (opp a)) _ _ _. by move=> x; rewrite /= -addrA addrN addr0. move=> x y; apply: addKl (x) _ _ _; apply: addKr (y) _ _ _. by rewrite -!addrA [in RHS]addrA innerC !addrA. Qed. (* Builder to the bottom right mixin. *) HB.instance Definition to_AbelianGroup_of_Monoid := AbelianGroup_of_Monoid.Build R opp addrC addNr. (* Builder to the top right factory, which is compiled to the bottom left mixin. *) HB.instance Definition to_Ring_of_AbelianGroup := Ring_of_AbelianGroup.Build R one mul mulrA mul1r mulr1 mulrDl mulrDr. HB.end. (********) (* TEST *) (********) Print Monoid.type. (* Monoid.type := { sort : Type; ... } *) Check @add. (* add : forall M : Monoid.type, M -> M -> M *) Check @addNr. (* addNr : forall R : AbelianGroup.type, left_inverse 0 opp add *) Check @addrC. (* is still an axiom of abelian groups *) (* addrC : forall R : AbelianGroup.type, commutative add *) HB.instance Definition Z_Monoid_axioms : Monoid_of_Type Z := Monoid_of_Type.Build Z 0%Z Z.add Z.add_assoc Z.add_0_l Z.add_0_r. HB.instance Definition Z_Ring_axioms : Ring_of_Monoid Z := Ring_of_Monoid.Build Z 1%Z Z.opp Z.mul Z.add_opp_diag_l Z.add_opp_diag_r Z.mul_assoc Z.mul_1_l Z.mul_1_r Z.mul_add_distr_r Z.mul_add_distr_l. Lemma exercise (m n : Z) : (n + m) - n * 1 = m. Proof. by rewrite mulr1 (addrC n) -(addrA m) addrN addr0. Qed. math-comp-hierarchy-builder-4d8a939/examples_stdlib/FSCD2020_talk/000077500000000000000000000000001521677141400245735ustar00rootroot00000000000000math-comp-hierarchy-builder-4d8a939/examples_stdlib/FSCD2020_talk/V1.v000066400000000000000000000007611521677141400252540ustar00rootroot00000000000000Require Import ZArith ssreflect ssrfun. From HB Require Import structures. HB.mixin Record is_monoid (M : Type) := { zero : M; add : M -> M -> M; addrA : associative add; (* add is associative. *) add0r : left_id zero add; (* zero is the neutral *) addr0 : right_id zero add; (* element wrt add. *) }. HB.structure Definition Monoid := { M & is_monoid M }. HB.instance Definition Z_is_monoid : is_monoid Z := is_monoid.Build Z 0%Z Z.add Z.add_assoc Z.add_0_l Z.add_0_r. math-comp-hierarchy-builder-4d8a939/examples_stdlib/FSCD2020_talk/V2.v000066400000000000000000000010531521677141400252500ustar00rootroot00000000000000Require Import ZArith ssreflect ssrfun. From HB Require Import structures. HB.mixin Record is_semigroup (S : Type) := { add : S -> S -> S; addrA : associative add; }. HB.structure Definition SemiGroup := { S & is_semigroup S }. HB.mixin Record monoid_of_semigroup (M : Type) & is_semigroup M := { zero : M; add0r : left_id zero add; addr0 : right_id zero add; }. HB.structure Definition Monoid := { M & monoid_of_semigroup M }. (* is_monoid does not exist anymore *) Fail Check is_monoid. HB.mixin Record xxxx P A := { F : bool }. math-comp-hierarchy-builder-4d8a939/examples_stdlib/FSCD2020_talk/V3.v000066400000000000000000000017601521677141400252560ustar00rootroot00000000000000Require Import ZArith ssreflect ssrfun. From HB Require Import structures. HB.mixin Record is_semigroup (S : Type) := { add : S -> S -> S; addrA : associative add; }. HB.structure Definition SemiGroup := { S & is_semigroup S }. HB.mixin Record monoid_of_semigroup (M : Type) & is_semigroup M := { zero : M; add0r : left_id zero add; addr0 : right_id zero add; }. HB.factory Record is_monoid (M : Type) := { zero : M; add : M -> M -> M; addrA : associative add; add0r : left_id zero add; addr0 : right_id zero add; }. HB.builders Context (M : Type) (f : is_monoid M). HB.instance Definition is_monoid_semigroup : is_semigroup M := is_semigroup.Build M add addrA. HB.instance Definition is_monoid_monoid : monoid_of_semigroup M := monoid_of_semigroup.Build M zero add0r addr0. HB.end. HB.structure Definition Monoid := { M & is_monoid M }. HB.instance Definition Z_is_monoid : is_monoid Z := is_monoid.Build Z 0%Z Z.add Z.add_assoc Z.add_0_l Z.add_0_r. math-comp-hierarchy-builder-4d8a939/examples_stdlib/demo1/000077500000000000000000000000001521677141400235425ustar00rootroot00000000000000math-comp-hierarchy-builder-4d8a939/examples_stdlib/demo1/README.md000066400000000000000000000010721521677141400250210ustar00rootroot00000000000000 # Demo1 The files `hierarchy_$N.v` describes a hierarchy that born with just one structure, the one of `Ring`, and evolves to the following one in five steps. ``` AddMonoid ---> AddComoid ----> AddAG ----> Ring \ \ / -> BiNearRing -> SemiRing - ``` The file `user_0.v` describes an early adopter of the hierarchy, the version described in `hierarchy_0.v`. That code works with all version of the hierarchy. The file `user_3.v` describes a user that adopted the `hierarchy_3.v` and that code works up to `hierarchy_5.v`math-comp-hierarchy-builder-4d8a939/examples_stdlib/demo1/hierarchy_0.v000066400000000000000000000027231521677141400261320ustar00rootroot00000000000000From Corelib Require Import ssreflect ssrfun. From HB Require Import structures. (**************************************************************************) (* Stage 0: +Ring+ *) (**************************************************************************) HB.mixin Record Ring_of_TYPE A := { zero : A; one : A; add : A -> A -> A; opp : A -> A; mul : A -> A -> A; addrA : associative add; addrC : commutative add; add0r : left_id zero add; addNr : left_inverse zero opp add; mulrA : associative mul; mul1r : left_id one mul; mulr1 : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; }. HB.structure Definition Ring := { A of Ring_of_TYPE A }. (* Notations *) Declare Scope hb_scope. Delimit Scope hb_scope with G. Local Open Scope hb_scope. Notation "0" := zero : hb_scope. Notation "1" := one : hb_scope. Infix "+" := (@add _) : hb_scope. Notation "- x" := (@opp _ x) : hb_scope. Infix "*" := (@mul _) : hb_scope. Notation "x - y" := (x + - y) : hb_scope. (* Theory *) Section Theory. Variable R : Ring.type. Implicit Type (x : R). Lemma addr0 : right_id (@zero R) add. Proof. by move=> x; rewrite addrC add0r. Qed. Lemma addrN : right_inverse (@zero R) opp add. Proof. by move=> x; rewrite addrC addNr. Qed. Lemma subrr x : x - x = 0. Proof. by rewrite addrN. Qed. Lemma addrNK x y : x + y - y = x. Proof. by rewrite -addrA subrr addr0. Qed. End Theory. math-comp-hierarchy-builder-4d8a939/examples_stdlib/demo1/hierarchy_1.v000066400000000000000000000044641521677141400261370ustar00rootroot00000000000000From Corelib Require Import ssreflect ssrfun. From HB Require Import structures. (**************************************************************************) (* Stage 1: +AddComoid+ -> Ring *) (**************************************************************************) (* Begin change *) HB.mixin Record AddComoid_of_TYPE A := { zero : A; add : A -> A -> A; addrA : associative add; addrC : commutative add; add0r : left_id zero add; }. HB.structure Definition AddComoid := { A of AddComoid_of_TYPE A }. HB.mixin Record Ring_of_AddComoid A & AddComoid A := { opp : A -> A; one : A; mul : A -> A -> A; addNr : left_inverse zero opp add; mulrA : associative mul; mul1r : left_id one mul; mulr1 : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; }. HB.factory Record Ring_of_TYPE A := { zero : A; one : A; add : A -> A -> A; opp : A -> A; mul : A -> A -> A; addrA : associative add; addrC : commutative add; add0r : left_id zero add; addNr : left_inverse zero opp add; mulrA : associative mul; mul1r : left_id one mul; mulr1 : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; }. #[verbose] HB.builders Context A (a : Ring_of_TYPE A). HB.instance Definition to_AddComoid_of_TYPE := AddComoid_of_TYPE.Build A zero add addrA addrC add0r. HB.instance Definition to_Ring_of_AddComoid := Ring_of_AddComoid.Build A _ _ _ addNr mulrA mul1r mulr1 mulrDl mulrDr. HB.end. (* End change *) HB.structure Definition Ring := { A of Ring_of_TYPE A }. (* Notations *) Declare Scope hb_scope. Delimit Scope hb_scope with G. Local Open Scope hb_scope. Notation "0" := zero : hb_scope. Notation "1" := one : hb_scope. Infix "+" := (@add _) : hb_scope. Notation "- x" := (@opp _ x) : hb_scope. Infix "*" := (@mul _) : hb_scope. Notation "x - y" := (x + - y) : hb_scope. (* Theory *) Section Theory. Variable R : Ring.type. Implicit Type (x : R). Lemma addr0 : right_id (@zero R) add. Proof. by move=> x; rewrite addrC add0r. Qed. Lemma addrN : right_inverse (@zero R) opp add. Proof. by move=> x; rewrite addrC addNr. Qed. Lemma subrr x : x - x = 0. Proof. by rewrite addrN. Qed. Lemma addrNK x y : x + y - y = x. Proof. by rewrite -addrA subrr addr0. Qed. End Theory. math-comp-hierarchy-builder-4d8a939/examples_stdlib/demo1/hierarchy_2.v000066400000000000000000000066711521677141400261420ustar00rootroot00000000000000From Corelib Require Import ssreflect ssrfun. From HB Require Import structures. (**************************************************************************) (* Stage 2: AddComoid -> +AddAG+ -> Ring *) (**************************************************************************) HB.mixin Record AddComoid_of_TYPE A := { zero : A; add : A -> A -> A; addrA : associative add; addrC : commutative add; add0r : left_id zero add; }. HB.structure Definition AddComoid := { A of AddComoid_of_TYPE A }. (* Begin change *) HB.mixin Record AddAG_of_AddComoid A & AddComoid A := { opp : A -> A; addNr : left_inverse zero opp add; }. HB.factory Record AddAG_of_TYPE A := { zero : A; add : A -> A -> A; opp : A -> A; addrA : associative add; addrC : commutative add; add0r : left_id zero add; addNr : left_inverse zero opp add; }. HB.builders Context A (a : AddAG_of_TYPE A). HB.instance Definition to_AddComoid_of_TYPE := AddComoid_of_TYPE.Build A zero add addrA addrC add0r. HB.instance Definition to_AddAG_of_AddComoid := AddAG_of_AddComoid.Build A _ addNr. HB.end. HB.structure Definition AddAG := { A of AddAG_of_TYPE A }. HB.mixin Record Ring_of_AddAG A & AddAG A := { one : A; mul : A -> A -> A; mulrA : associative mul; mulr1 : left_id one mul; mul1r : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; }. HB.structure Definition Ring := { A of Ring_of_AddAG A }. HB.factory Record Ring_of_AddComoid A & AddComoid A := { opp : A -> A; one : A; mul : A -> A -> A; addNr : left_inverse zero opp add; mulrA : associative mul; mul1r : left_id one mul; mulr1 : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; }. HB.builders Context A (a : Ring_of_AddComoid A). HB.instance Definition to_AddAG_of_AddComoid := AddAG_of_AddComoid.Build A _ addNr. HB.instance Definition to_Ring_of_AddAG := Ring_of_AddAG.Build A _ _ mulrA mul1r mulr1 mulrDl mulrDr. #[verbose] HB.end. (* End change *) HB.factory Record Ring_of_TYPE A := { zero : A; one : A; add : A -> A -> A; opp : A -> A; mul : A -> A -> A; addrA : associative add; addrC : commutative add; add0r : left_id zero add; addNr : left_inverse zero opp add; mulrA : associative mul; mul1r : left_id one mul; mulr1 : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; }. HB.builders Context A (a : Ring_of_TYPE A). HB.instance Definition to_AddComoid_of_TYPE := AddComoid_of_TYPE.Build A zero add addrA addrC add0r. HB.instance Definition to_Ring_of_AddComoid := Ring_of_AddComoid.Build A _ _ _ addNr mulrA mul1r mulr1 mulrDl mulrDr. HB.end. (* Notations *) Declare Scope hb_scope. Delimit Scope hb_scope with G. Local Open Scope hb_scope. Notation "0" := zero : hb_scope. Notation "1" := one : hb_scope. Infix "+" := (@add _) : hb_scope. Notation "- x" := (@opp _ x) : hb_scope. Infix "*" := (@mul _) : hb_scope. Notation "x - y" := (x + - y) : hb_scope. (* Theory *) Section Theory. Variable R : Ring.type. Implicit Type (x : R). Lemma addr0 : right_id (@zero R) add. Proof. by move=> x; rewrite addrC add0r. Qed. Lemma addrN : right_inverse (@zero R) opp add. Proof. by move=> x; rewrite addrC addNr. Qed. Lemma subrr x : x - x = 0. Proof. by rewrite addrN. Qed. Lemma addrNK x y : x + y - y = x. Proof. by rewrite -addrA subrr addr0. Qed. End Theory. math-comp-hierarchy-builder-4d8a939/examples_stdlib/demo1/hierarchy_3.v000066400000000000000000000110361521677141400261320ustar00rootroot00000000000000From Corelib Require Import ssreflect ssrfun. From HB Require Import structures. (**************************************************************************) (* Stage 3: AddComoid ----> AddAG -----> Ring *) (* \ / *) (* -> +SemiRing+ - *) (**************************************************************************) HB.mixin Record AddComoid_of_TYPE A := { zero : A; add : A -> A -> A; addrA : associative add; addrC : commutative add; add0r : left_id zero add; }. HB.structure Definition AddComoid := { A of AddComoid_of_TYPE A }. HB.mixin Record AddAG_of_AddComoid A & AddComoid A := { opp : A -> A; addNr : left_inverse zero opp add; }. HB.factory Record AddAG_of_TYPE A := { zero : A; add : A -> A -> A; opp : A -> A; addrA : associative add; addrC : commutative add; add0r : left_id zero add; addNr : left_inverse zero opp add; }. HB.builders Context A (a : AddAG_of_TYPE A). HB.instance Definition to_AddComoid_of_TYPE := AddComoid_of_TYPE.Build A zero add addrA addrC add0r. HB.instance Definition to_AddAG_of_AddComoid := AddAG_of_AddComoid.Build A _ addNr. HB.end. HB.structure Definition AddAG := { A of AddAG_of_TYPE A }. (* Begin change *) HB.mixin Record SemiRing_of_AddComoid A & AddComoid A := { one : A; mul : A -> A -> A; mulrA : associative mul; mul1r : left_id one mul; mulr1 : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; mul0r : left_zero zero mul; mulr0 : right_zero zero mul; }. HB.structure Definition SemiRing := { A of AddComoid A & SemiRing_of_AddComoid A }. HB.factory Record Ring_of_AddAG A & AddAG A := { one : A; mul : A -> A -> A; mulrA : associative mul; mulr1 : left_id one mul; mul1r : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; }. HB.builders Context A (a : Ring_of_AddAG A). Fact mul0r : left_zero zero mul. Proof. move=> x; rewrite -[LHS]add0r addrC. rewrite -{2}(addNr (mul x x)) (addrC (opp _)) addrA. by rewrite -mulrDl add0r addrC addNr. Qed. Fact mulr0 : right_zero zero mul. Proof. move=> x; rewrite -[LHS]add0r addrC. rewrite -{2}(addNr (mul x x)) (addrC (opp _)) addrA. by rewrite -mulrDr add0r addrC addNr. Qed. HB.instance Definition to_SemiRing_of_AddComoid := SemiRing_of_AddComoid.Build A _ mul mulrA mulr1 mul1r mulrDl mulrDr mul0r mulr0. HB.end. (* End change *) HB.factory Record Ring_of_AddComoid A & AddComoid A := { opp : A -> A; one : A; mul : A -> A -> A; addNr : left_inverse zero opp add; mulrA : associative mul; mul1r : left_id one mul; mulr1 : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; }. HB.builders Context A (a : Ring_of_AddComoid A). HB.instance Definition to_AddAG_of_AddComoid := AddAG_of_AddComoid.Build A _ addNr. HB.instance Definition to_Ring_of_AddAG := Ring_of_AddAG.Build A _ _ mulrA mul1r mulr1 mulrDl mulrDr. HB.end. (* End change *) HB.factory Record Ring_of_TYPE A := { zero : A; one : A; add : A -> A -> A; opp : A -> A; mul : A -> A -> A; addrA : associative add; addrC : commutative add; add0r : left_id zero add; addNr : left_inverse zero opp add; mulrA : associative mul; mul1r : left_id one mul; mulr1 : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; }. HB.builders Context A (a : Ring_of_TYPE A). HB.instance Definition to_AddComoid_of_TYPE := AddComoid_of_TYPE.Build A zero add addrA addrC add0r. HB.instance Definition to_Ring_of_AddComoid := Ring_of_AddComoid.Build A _ _ _ addNr mulrA mul1r mulr1 mulrDl mulrDr. HB.end. HB.structure Definition Ring := { A of Ring_of_TYPE A }. (* Notations *) Declare Scope hb_scope. Delimit Scope hb_scope with G. Local Open Scope hb_scope. Notation "0" := zero : hb_scope. Notation "1" := one : hb_scope. Infix "+" := (@add _) : hb_scope. Notation "- x" := (@opp _ x) : hb_scope. Infix "*" := (@mul _) : hb_scope. Notation "x - y" := (x + - y) : hb_scope. (* Theory *) Section Theory. Variable R : Ring.type. Implicit Type (x : R). Lemma addr0 : right_id (@zero R) add. Proof. by move=> x; rewrite addrC add0r. Qed. Lemma addrN : right_inverse (@zero R) opp add. Proof. by move=> x; rewrite addrC addNr. Qed. Lemma subrr x : x - x = 0. Proof. by rewrite addrN. Qed. Lemma addrNK x y : x + y - y = x. Proof. by rewrite -addrA subrr addr0. Qed. End Theory. math-comp-hierarchy-builder-4d8a939/examples_stdlib/demo1/hierarchy_4.v000066400000000000000000000124561521677141400261420ustar00rootroot00000000000000From Corelib Require Import ssreflect ssrfun. From HB Require Import structures. (**************************************************************************) (* Stage 4: +AddMonoid+ -> AddComoid ---> AddAG ----> Ring *) (* \ / *) (* -> SemiRing - *) (**************************************************************************) (* Begin change *) HB.mixin Record AddMonoid_of_TYPE S := { zero : S; add : S -> S -> S; addrA : associative add; add0r : left_id zero add; addr0 : right_id zero add; }. HB.structure Definition AddMonoid := { A of AddMonoid_of_TYPE A }. HB.mixin Record AddComoid_of_AddMonoid A & AddMonoid A := { addrC : commutative (add : A -> A -> A); }. HB.factory Record AddComoid_of_TYPE A := { zero : A; add : A -> A -> A; addrA : associative add; addrC : commutative add; add0r : left_id zero add; }. HB.builders Context A (a : AddComoid_of_TYPE A). Fact addr0 : right_id zero add. Proof. by move=> x; rewrite addrC add0r. Qed. HB.instance Definition to_AddMonoid_of_TYPE := AddMonoid_of_TYPE.Build A zero add addrA add0r addr0. HB.instance Definition to_AddComoid_of_AddMonoid := AddComoid_of_AddMonoid.Build A addrC. HB.end. HB.structure Definition AddComoid := { A of AddComoid_of_TYPE A }. (* End change *) HB.mixin Record AddAG_of_AddComoid A & AddComoid A := { opp : A -> A; addNr : left_inverse zero opp add; }. HB.factory Record AddAG_of_TYPE A := { zero : A; add : A -> A -> A; opp : A -> A; addrA : associative add; addrC : commutative add; add0r : left_id zero add; addNr : left_inverse zero opp add; }. HB.builders Context A (a : AddAG_of_TYPE A). HB.instance Definition to_AddComoid_of_TYPE := AddComoid_of_TYPE.Build A zero add addrA addrC add0r. HB.instance Definition to_AddAG_of_AddComoid := AddAG_of_AddComoid.Build A _ addNr. HB.end. HB.structure Definition AddAG := { A of AddAG_of_TYPE A }. HB.mixin Record SemiRing_of_AddComoid A & AddComoid A := { one : A; mul : A -> A -> A; mulrA : associative mul; mul1r : left_id one mul; mulr1 : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; mul0r : left_zero zero mul; mulr0 : right_zero zero mul; }. HB.structure Definition SemiRing := { A of AddComoid A & SemiRing_of_AddComoid A }. HB.factory Record Ring_of_AddAG A & AddAG A := { one : A; mul : A -> A -> A; mulrA : associative mul; mulr1 : left_id one mul; mul1r : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; }. HB.builders Context A (a : Ring_of_AddAG A). Fact mul0r : left_zero zero mul. Proof. move=> x; rewrite -[LHS]add0r addrC. rewrite -{2}(addNr (mul x x)) (addrC (opp _)) addrA. by rewrite -mulrDl add0r addrC addNr. Qed. Fact mulr0 : right_zero zero mul. Proof. move=> x; rewrite -[LHS]add0r addrC. rewrite -{2}(addNr (mul x x)) (addrC (opp _)) addrA. by rewrite -mulrDr add0r addrC addNr. Qed. HB.instance Definition to_SemiRing_of_AddComoid := SemiRing_of_AddComoid.Build A _ mul mulrA mulr1 mul1r mulrDl mulrDr (mul0r) (mulr0). HB.end. (* End change *) HB.factory Record Ring_of_AddComoid A & AddComoid A := { opp : A -> A; one : A; mul : A -> A -> A; addNr : left_inverse zero opp add; mulrA : associative mul; mul1r : left_id one mul; mulr1 : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; }. HB.builders Context A (a : Ring_of_AddComoid A). HB.instance Definition to_AddAG_of_AddComoid := AddAG_of_AddComoid.Build A _ addNr. HB.instance Definition to_Ring_of_AddAG := Ring_of_AddAG.Build A _ _ mulrA mul1r mulr1 mulrDl mulrDr. HB.end. (* End change *) HB.factory Record Ring_of_TYPE A := { zero : A; one : A; add : A -> A -> A; opp : A -> A; mul : A -> A -> A; addrA : associative add; addrC : commutative add; add0r : left_id zero add; addNr : left_inverse zero opp add; mulrA : associative mul; mul1r : left_id one mul; mulr1 : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; }. HB.builders Context A (a : Ring_of_TYPE A). HB.instance Definition to_AddComoid_of_TYPE := AddComoid_of_TYPE.Build A zero add addrA addrC add0r. HB.instance Definition to_Ring_of_AddComoid := Ring_of_AddComoid.Build A _ _ _ addNr mulrA mul1r mulr1 mulrDl mulrDr. HB.end. HB.structure Definition Ring := { A of Ring_of_TYPE A }. (* Notations *) Declare Scope hb_scope. Delimit Scope hb_scope with G. Local Open Scope hb_scope. Notation "0" := zero : hb_scope. Notation "1" := one : hb_scope. Infix "+" := (@add _) : hb_scope. Notation "- x" := (@opp _ x) : hb_scope. Infix "*" := (@mul _) : hb_scope. Notation "x - y" := (x + - y) : hb_scope. (* Theory *) Section Theory. Variable R : Ring.type. Implicit Type (x : R). (* Not general enough anymore, subsumed by Monoid addr0 *) (* Lemma addr0 : right_id (@zero R) add. Proof. by move=> x; rewrite addrC add0r. Qed. *) Lemma addrN : right_inverse (@zero R) opp add. Proof. by move=> x; rewrite addrC addNr. Qed. Lemma subrr x : x - x = 0. Proof. by rewrite addrN. Qed. Lemma addrNK x y : x + y - y = x. Proof. by rewrite -addrA subrr addr0. Qed. End Theory. math-comp-hierarchy-builder-4d8a939/examples_stdlib/demo1/hierarchy_5.v000066400000000000000000000150171521677141400261370ustar00rootroot00000000000000From Corelib Require Import ssreflect ssrfun. From HB Require Import structures. (**************************************************************************) (* Stage 5: AddMonoid ---> AddComoid ----> AddAG ----> Ring *) (* \ \ / *) (* -> +BiNearRing+ -> SemiRing - *) (**************************************************************************) HB.mixin Record AddMonoid_of_TYPE S := { zero : S; add : S -> S -> S; addrA : associative add; add0r : left_id zero add; addr0 : right_id zero add; }. HB.structure Definition AddMonoid := { A of AddMonoid_of_TYPE A }. HB.mixin Record AddComoid_of_AddMonoid A & AddMonoid A := { addrC : commutative (add : A -> A -> A); }. HB.factory Record AddComoid_of_TYPE A := { zero : A; add : A -> A -> A; addrA : associative add; addrC : commutative add; add0r : left_id zero add; }. HB.builders Context A (a : AddComoid_of_TYPE A). Fact addr0 : right_id zero add. Proof. by move=> x; rewrite addrC add0r. Qed. HB.instance Definition to_AddMonoid_of_TYPE := AddMonoid_of_TYPE.Build A zero add addrA add0r addr0. HB.instance Definition to_AddComoid_of_AddMonoid := AddComoid_of_AddMonoid.Build A addrC. HB.end. HB.structure Definition AddComoid := { A of AddComoid_of_TYPE A }. (* End change *) HB.mixin Record AddAG_of_AddComoid A & AddComoid A := { opp : A -> A; addNr : left_inverse zero opp add; }. HB.factory Record AddAG_of_TYPE A := { zero : A; add : A -> A -> A; opp : A -> A; addrA : associative add; addrC : commutative add; add0r : left_id zero add; addNr : left_inverse zero opp add; }. HB.builders Context A (a : AddAG_of_TYPE A). HB.instance Definition to_AddComoid_of_TYPE := AddComoid_of_TYPE.Build A zero add addrA addrC add0r. HB.instance Definition to_AddAG_of_AddComoid := AddAG_of_AddComoid.Build A _ addNr. HB.end. HB.structure Definition AddAG := { A of AddAG_of_TYPE A }. (* Begin changes *) HB.mixin Record BiNearRing_of_AddMonoid A & AddMonoid A := { one : A; mul : A -> A -> A; mulrA : associative mul; mul1r : left_id one mul; mulr1 : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; mul0r : left_zero zero mul; mulr0 : right_zero zero mul; }. HB.structure Definition BiNearRing := { A of AddMonoid A & BiNearRing_of_AddMonoid A }. (* this factory is accidentally a duplicate of BiNearRing_of_AddMonoid *) (* we alias it for backward compatilibity and uniformity purposes *) HB.factory Definition SemiRing_of_AddComoid A & AddComoid A := BiNearRing_of_AddMonoid A. HB.builders Context A (a : SemiRing_of_AddComoid A). HB.instance Definition to_BiNearRing_of_AddMonoid : BiNearRing_of_AddMonoid A := a. HB.end. (* End changes *) HB.structure Definition SemiRing := { A of AddComoid A & SemiRing_of_AddComoid A }. Set Implicit Arguments. (* The factory builder will have implicit arguments *) #[doc="Builds a Ring from an Abelian Group: the absorbing properties mul0r and mul0r are derived from addrC and the other ring axioms, following a proof of Hankel (Gerhard Betsch. On the beginnings and development of near-ring theory. In Near-rings and near-fields. Proceedings of the conference held in Fredericton, New Brunswick, July 18-24, 1993, pages 1–11. Mathematics and its Applications, 336. Kluwer Academic Publishers Group, Dordrecht, 1995)."] HB.factory Record Ring_of_AddAG A & AddAG A := { one : A; mul : A -> A -> A; mulrA : associative mul; mulr1 : left_id one mul; mul1r : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; }. Unset Implicit Arguments. HB.builders Context A (a : Ring_of_AddAG A). Fact mul0r : left_zero zero mul. Proof. move=> x; rewrite -[LHS]add0r addrC. rewrite -{2}(addNr (mul x x)) (addrC (opp _)) addrA. by rewrite -mulrDl add0r addrC addNr. Qed. Fact mulr0 : right_zero zero mul. Proof. move=> x; rewrite -[LHS]add0r addrC. rewrite -{2}(addNr (mul x x)) (addrC (opp _)) addrA. by rewrite -mulrDr add0r addrC addNr. Qed. HB.instance Definition to_SemiRing_of_AddComoid := SemiRing_of_AddComoid.Build A _ mul mulrA mulr1 mul1r mulrDl mulrDr mul0r mulr0. HB.end. HB.factory Record Ring_of_AddComoid A & AddComoid A := { opp : A -> A; one : A; mul : A -> A -> A; addNr : left_inverse zero opp add; mulrA : associative mul; mul1r : left_id one mul; mulr1 : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; }. HB.builders Context A (a :Ring_of_AddComoid A). HB.instance Definition to_AddAG_of_AddComoid := AddAG_of_AddComoid.Build A _ addNr. HB.instance Definition to_Ring_of_AddAG := Ring_of_AddAG.Build A mulrA mul1r mulr1 mulrDl mulrDr. HB.end. HB.factory Record Ring_of_TYPE A := { zero : A; one : A; add : A -> A -> A; opp : A -> A; mul : A -> A -> A; addrA : associative add; addrC : commutative add; add0r : left_id zero add; addNr : left_inverse zero opp add; mulrA : associative mul; mul1r : left_id one mul; mulr1 : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; }. HB.builders Context A (a : Ring_of_TYPE A). HB.instance Definition to_AddComoid_of_TYPE := AddComoid_of_TYPE.Build A zero add addrA addrC add0r. HB.instance Definition to_Ring_of_AddComoid := Ring_of_AddComoid.Build A _ _ _ addNr mulrA mul1r mulr1 mulrDl mulrDr. HB.end. HB.structure Definition Ring := { A of Ring_of_TYPE A }. (* Notations *) Declare Scope hb_scope. Delimit Scope hb_scope with G. Local Open Scope hb_scope. Notation "0" := zero : hb_scope. Notation "1" := one : hb_scope. Infix "+" := (@add _) : hb_scope. Notation "- x" := (@opp _ x) : hb_scope. Infix "*" := (@mul _) : hb_scope. Notation "x - y" := (x + - y) : hb_scope. (* Theory *) Section Theory. Variable R : Ring.type. Implicit Type (x : R). (* Not general enough anymore, subsumed by Monoid addr0 *) (* Lemma addr0 : right_id (@zero R) add. Proof. by move=> x; rewrite addrC add0r. Qed. *) Lemma addrN : right_inverse (@zero R) opp add. Proof. by move=> x; rewrite addrC addNr. Qed. Lemma subrr x : x - x = 0. Proof. by rewrite addrN. Qed. Lemma addrNK x y : x + y - y = x. Proof. by rewrite -addrA subrr addr0. Qed. End Theory. HB.graph "hierarchy_5.dot". (* we check the alias factory is abstracted over the whole section *) HB.check (SemiRing_of_AddComoid.axioms_ : forall A, forall m : AddMonoid_of_TYPE.axioms_ A, AddComoid_of_AddMonoid.axioms_ A m -> Type). math-comp-hierarchy-builder-4d8a939/examples_stdlib/demo1/test_0_0.v000066400000000000000000000007411521677141400253500ustar00rootroot00000000000000From Corelib Require Import ssreflect. From Stdlib Require Import ZArith. From HB Require Import structures. From HB Require Import demo1.hierarchy_0. HB.instance Definition Z_ring_axioms := Ring_of_TYPE.Build Z 0%Z 1%Z Z.add Z.opp Z.mul Z.add_assoc Z.add_comm Z.add_0_l Z.add_opp_diag_l Z.mul_assoc Z.mul_1_l Z.mul_1_r Z.mul_add_distr_r Z.mul_add_distr_l. Open Scope hb_scope. Example test1 (m n : Z) : (m + n) - n + 0 = m. Proof. by rewrite addrNK addr0. Qed. math-comp-hierarchy-builder-4d8a939/examples_stdlib/demo1/test_1_0.v000066400000000000000000000006761521677141400253600ustar00rootroot00000000000000From Coq Require Import ZArith ssreflect. From HB Require Import structures. From HB Require Import demo1.hierarchy_1. HB.instance Definition Z_ring_axioms := Ring_of_TYPE.Build Z 0%Z 1%Z Z.add Z.opp Z.mul Z.add_assoc Z.add_comm Z.add_0_l Z.add_opp_diag_l Z.mul_assoc Z.mul_1_l Z.mul_1_r Z.mul_add_distr_r Z.mul_add_distr_l. Open Scope hb_scope. Example test1 (m n : Z) : (m + n) - n + 0 = m. Proof. by rewrite addrNK addr0. Qed.math-comp-hierarchy-builder-4d8a939/examples_stdlib/demo1/test_2_0.v000066400000000000000000000006761521677141400253610ustar00rootroot00000000000000From Coq Require Import ZArith ssreflect. From HB Require Import structures. From HB Require Import demo1.hierarchy_2. HB.instance Definition Z_ring_axioms := Ring_of_TYPE.Build Z 0%Z 1%Z Z.add Z.opp Z.mul Z.add_assoc Z.add_comm Z.add_0_l Z.add_opp_diag_l Z.mul_assoc Z.mul_1_l Z.mul_1_r Z.mul_add_distr_r Z.mul_add_distr_l. Open Scope hb_scope. Example test1 (m n : Z) : (m + n) - n + 0 = m. Proof. by rewrite addrNK addr0. Qed.math-comp-hierarchy-builder-4d8a939/examples_stdlib/demo1/test_3_0.v000066400000000000000000000006761521677141400253620ustar00rootroot00000000000000From Coq Require Import ZArith ssreflect. From HB Require Import structures. From HB Require Import demo1.hierarchy_3. HB.instance Definition Z_ring_axioms := Ring_of_TYPE.Build Z 0%Z 1%Z Z.add Z.opp Z.mul Z.add_assoc Z.add_comm Z.add_0_l Z.add_opp_diag_l Z.mul_assoc Z.mul_1_l Z.mul_1_r Z.mul_add_distr_r Z.mul_add_distr_l. Open Scope hb_scope. Example test1 (m n : Z) : (m + n) - n + 0 = m. Proof. by rewrite addrNK addr0. Qed.math-comp-hierarchy-builder-4d8a939/examples_stdlib/demo1/test_3_3.v000066400000000000000000000010141521677141400253500ustar00rootroot00000000000000From Coq Require Import ZArith ssreflect. From HB Require Import structures. From HB Require Import demo1.hierarchy_3. HB.instance Definition Z_AddComoid := AddComoid_of_TYPE.Build Z 0%Z Z.add Z.add_assoc Z.add_comm Z.add_0_l. HB.instance Definition Z_SemiRing := SemiRing_of_AddComoid.Build Z 1%Z Z.mul Z.mul_assoc Z.mul_1_l Z.mul_1_r Z.mul_add_distr_r Z.mul_add_distr_l Z.mul_0_l Z.mul_0_r. Open Scope hb_scope. Example test1 (m n : Z) : m + n * 0 * 0 = m. Proof. by rewrite -mulrA !mulr0 addrC add0r. Qed.math-comp-hierarchy-builder-4d8a939/examples_stdlib/demo1/test_4_0.v000066400000000000000000000007001521677141400253470ustar00rootroot00000000000000From Coq Require Import ZArith ssreflect. From HB Require Import structures. From HB Require Import demo1.hierarchy_4. HB.instance Definition Z_ring_axioms := Ring_of_TYPE.Build Z 0%Z 1%Z Z.add Z.opp Z.mul Z.add_assoc Z.add_comm Z.add_0_l Z.add_opp_diag_l Z.mul_assoc Z.mul_1_l Z.mul_1_r Z.mul_add_distr_r Z.mul_add_distr_l. Open Scope hb_scope. Example test1 (m n : Z) : (m + n) - n + 0 = m. Proof. by rewrite addrNK addr0. Qed.math-comp-hierarchy-builder-4d8a939/examples_stdlib/demo1/test_4_3.v000066400000000000000000000010141521677141400253510ustar00rootroot00000000000000From Coq Require Import ZArith ssreflect. From HB Require Import structures. From HB Require Import demo1.hierarchy_4. HB.instance Definition Z_AddComoid := AddComoid_of_TYPE.Build Z 0%Z Z.add Z.add_assoc Z.add_comm Z.add_0_l. HB.instance Definition Z_SemiRing := SemiRing_of_AddComoid.Build Z 1%Z Z.mul Z.mul_assoc Z.mul_1_l Z.mul_1_r Z.mul_add_distr_r Z.mul_add_distr_l Z.mul_0_l Z.mul_0_r. Open Scope hb_scope. Example test1 (m n : Z) : m + n * 0 * 0 = m. Proof. by rewrite -mulrA !mulr0 addrC add0r. Qed.math-comp-hierarchy-builder-4d8a939/examples_stdlib/demo1/test_5_0.v000066400000000000000000000006761521677141400253640ustar00rootroot00000000000000From Coq Require Import ZArith ssreflect. From HB Require Import structures. From HB Require Import demo1.hierarchy_5. HB.instance Definition Z_ring_axioms := Ring_of_TYPE.Build Z 0%Z 1%Z Z.add Z.opp Z.mul Z.add_assoc Z.add_comm Z.add_0_l Z.add_opp_diag_l Z.mul_assoc Z.mul_1_l Z.mul_1_r Z.mul_add_distr_r Z.mul_add_distr_l. Open Scope hb_scope. Example test1 (m n : Z) : (m + n) - n + 0 = m. Proof. by rewrite addrNK addr0. Qed.math-comp-hierarchy-builder-4d8a939/examples_stdlib/demo1/test_5_3.v000066400000000000000000000010141521677141400253520ustar00rootroot00000000000000From Coq Require Import ZArith ssreflect. From HB Require Import structures. From HB Require Import demo1.hierarchy_5. HB.instance Definition Z_AddComoid := AddComoid_of_TYPE.Build Z 0%Z Z.add Z.add_assoc Z.add_comm Z.add_0_l. HB.instance Definition Z_SemiRing := SemiRing_of_AddComoid.Build Z 1%Z Z.mul Z.mul_assoc Z.mul_1_l Z.mul_1_r Z.mul_add_distr_r Z.mul_add_distr_l Z.mul_0_l Z.mul_0_r. Open Scope hb_scope. Example test1 (m n : Z) : m + n * 0 * 0 = m. Proof. by rewrite -mulrA !mulr0 addrC add0r. Qed.math-comp-hierarchy-builder-4d8a939/examples_stdlib/demo1/user_0.v000066400000000000000000000007041521677141400251270ustar00rootroot00000000000000From Coq Require Import ZArith ssreflect. From HB Require Import structures. From @@DEMO@@ Require Import @@HIERARCHY@@. Definition Z_ring_axioms := Ring_of_TYPE.Build Z 0%Z 1%Z Z.add Z.opp Z.mul Z.add_assoc Z.add_comm Z.add_0_l Z.add_opp_diag_l Z.mul_assoc Z.mul_1_l Z.mul_1_r Z.mul_add_distr_r Z.mul_add_distr_l. HB.instance Z Z_ring_axioms. Open Scope hb_scope. Example test1 (m n : Z) : (m + n) - n + 0 = m. Proof. by rewrite addrNK addr0. Qed.math-comp-hierarchy-builder-4d8a939/examples_stdlib/demo1/user_3.v000066400000000000000000000010551521677141400251320ustar00rootroot00000000000000From Coq Require Import ZArith ssreflect. From HB Require Import structures. From @@DEMO@@ Require Import @@HIERARCHY@@. Definition Z_AddComoid := AddComoid_of_TYPE.Build Z 0%Z Z.add Z.add_assoc Z.add_comm Z.add_0_l. HB.instance Z Z_AddComoid. Definition Z_SemiRing := SemiRing_of_AddComoid.Build Z 1%Z Z.mul Z.mul_assoc Z.mul_1_l Z.mul_1_r Z.mul_add_distr_r Z.mul_add_distr_l Z.mul_0_l Z.mul_0_r. HB.instance Z Z_SemiRing. Open Scope hb_scope. Example test1 (m n : Z) : m + n * 0 * 0 = m. Proof. by rewrite -mulrA !mulr0 addrC add0r. Qed.math-comp-hierarchy-builder-4d8a939/examples_stdlib/demo2/000077500000000000000000000000001521677141400235435ustar00rootroot00000000000000math-comp-hierarchy-builder-4d8a939/examples_stdlib/demo2/classical.v000066400000000000000000001411641521677141400256770ustar00rootroot00000000000000Require Import ssreflect ssrfun ssrbool ssrfun ssrbool. (******************************************************************************) (* This file develops a basic theory of sets under classical axiomatization *) (* and is imported from math-comp/analysis *) (* *) (* --> A decidable equality is defined for any type. It is thus possible to *) (* define an eqType structure for any type using the mixin gen_eqMixin. *) (* --> This file adds the possibility to define a choiceType structure for *) (* any type thanks to an axiom gen_choiceMixin giving a choice mixin. *) (* --> We chose to have generic mixins and no global instances of the eqType *) (* and choiceType structures to let the user choose which definition of *) (* equality to use and to avoid conflict with already declared instances. *) (* *) (* * Sets: *) (* set A == type of sets on A. *) (* (x \in P) == boolean membership predicate from ssrbool *) (* for set P, available thanks to a canonical *) (* predType T structure on sets on T. *) (* [set x : T | P] == set of points x : T such that P holds. *) (* [set x | P] == same as before with T left implicit. *) (* [set E | x in A] == set defined by the expression E for x in *) (* set A. *) (* [set E | x in A & y in B] == same as before for E depending on 2 *) (* variables x and y in sets A and B. *) (* setT == full set. *) (* set0 == empty set. *) (* [set of F] == set defined by the expression F x for any *) (* x. *) (* [set a] == set containing only a. *) (* [set a : T] == same as before with the type of a made *) (* explicit. *) (* A `|` B == union of A and B. *) (* a |` A == A extended with a. *) (* [set a1; a2; ..; an] == set containing only the n elements ai. *) (* A `&` B == intersection of A and B. *) (* A `*` B == product of A and B, i.e. set of pairs (a,b) *) (* such that A a and B b. *) (* A.`1 == set of points a such that there exists b so *) (* that A (a, b). *) (* A.`2 == set of points a such that there exists b so *) (* that A (b, a). *) (* ~` A == complement of A. *) (* [set ~ a] == complement of [set a]. *) (* A `\` B == complement of B in A. *) (* A `\ a == A deprived of a. *) (* \bigcup_(i in P) F == union of the elements of the family F whose *) (* index satisfies P. *) (* \bigcup_(i : T) F == union of the family F indexed on T. *) (* \bigcup_i F == same as before with T left implicit. *) (* \bigcap_(i in P) F == intersection of the elements of the family *) (* F whose index satisfies P. *) (* \bigcap_(i : T) F == union of the family F indexed on T. *) (* \bigcap_i F == same as before with T left implicit. *) (* A `<=` B <-> A is included in B. *) (* A `<=>` B <-> double inclusion A `<=` B and B `<=` A. *) (* f @^-1` A == preimage of A by f. *) (* f @` A == image of A by f. *) (* A !=set0 := exists x, A x. *) (* is_singleton X <-> X contains only 1 element. *) (* is_fun f <-> for each a, f a contains only 1 element. *) (* is_total f <-> for each a, f a is non empty. *) (* is_totalfun f <-> conjunction of is_fun and is_total. *) (* xget x0 P == point x in P if it exists, x0 otherwise; *) (* P must be a set on a choiceType. *) (* fun_of_graph f0 f == function that maps x to an element of f x *) (* if there is one, to f0 x otherwise. *) (* *) (* --> Thanks to this basic set theory, we proved Zorn's Lemma, which states *) (* that any ordered set such that every totally ordered subset admits an *) (* upper bound has a maximal element. We also proved an analogous version *) (* for preorders, where maximal is replaced with premaximal: t is *) (* premaximal if whenever t < s we also have s < t. *) (******************************************************************************) (* -------------------------------------------------------------------- *) Set Implicit Arguments. Unset Strict Implicit. Unset Printing Implicit Defensive. Declare Scope box_scope. Declare Scope quant_scope. (* Copy of the ssrbool shim to ensure compatibility with MathComp v1.8.0. *) Definition PredType : forall T pT, (pT -> pred T) -> predType T. exact PredType || exact mkPredType. Defined. Arguments PredType [T pT] toP. Local Notation predOfType T := (pred_of_simpl (@pred_of_argType T)). (* -------------------------------------------------------------------- *) Axiom functional_extensionality_dep : forall (A : Type) (B : A -> Type) (f g : forall x : A, B x), (forall x : A, f x = g x) -> f = g. Axiom propositional_extensionality : forall P Q : Prop, P <-> Q -> P = Q. Axiom constructive_indefinite_description : forall (A : Type) (P : A -> Prop), (exists x : A, P x) -> {x : A | P x}. Notation cid := constructive_indefinite_description. (* -------------------------------------------------------------------- *) Record mextentionality := { _ : forall (P Q : Prop), (P <-> Q) -> (P = Q); _ : forall {T U : Type} (f g : T -> U), (forall x, f x = g x) -> f = g; }. Fact extentionality : mextentionality. Proof. split. - exact: propositional_extensionality. - by move=> T U f g; apply: functional_extensionality_dep. Qed. Lemma propext (P Q : Prop) : (P <-> Q) -> (P = Q). Proof. by have [propext _] := extentionality; apply: propext. Qed. Lemma funext {T U : Type} (f g : T -> U) : (f =1 g) -> f = g. Proof. by case: extentionality=> _; apply. Qed. Lemma propeqE (P Q : Prop) : (P = Q) = (P <-> Q). Proof. by apply: propext; split=> [->|/propext]. Qed. Lemma funeqE {T U : Type} (f g : T -> U) : (f = g) = (f =1 g). Proof. by rewrite propeqE; split=> [->//|/funext]. Qed. Lemma funeq2E {T U V : Type} (f g : T -> U -> V) : (f = g) = (f =2 g). Proof. by rewrite propeqE; split=> [->//|?]; rewrite funeqE=> x; rewrite funeqE. Qed. Lemma funeq3E {T U V W : Type} (f g : T -> U -> V -> W) : (f = g) = (forall x y z, f x y z = g x y z). Proof. by rewrite propeqE; split=> [->//|?]; rewrite funeq2E=> x y; rewrite funeqE. Qed. Lemma predeqE {T} (P Q : T -> Prop) : (P = Q) = (forall x, P x <-> Q x). Proof. by rewrite propeqE; split=> [->//|?]; rewrite funeqE=> x; rewrite propeqE. Qed. Lemma predeq2E {T U} (P Q : T -> U -> Prop) : (P = Q) = (forall x y, P x y <-> Q x y). Proof. by rewrite propeqE; split=> [->//|?]; rewrite funeq2E=> ??; rewrite propeqE. Qed. Lemma predeq3E {T U V} (P Q : T -> U -> V -> Prop) : (P = Q) = (forall x y z, P x y z <-> Q x y z). Proof. by rewrite propeqE; split=> [->//|?]; rewrite funeq3E=> ???; rewrite propeqE. Qed. Lemma propT (P : Prop) : P -> P = True. Proof. by move=> p; rewrite propeqE; tauto. Qed. Lemma Prop_irrelevance (P : Prop) (x y : P) : x = y. Proof. by move: x (x) y => /propT-> [] []. Qed. Lemma choice X Y (P : X -> Y -> Prop) : (forall x, exists y, P x y) -> {f & forall x, P x (f x)}. Proof. by move=> /(_ _)/constructive_indefinite_description -/all_tag. Qed. (* Diaconescu Theorem *) Theorem EM P : P \/ ~ P. Proof. pose U val := fun Q : bool => Q = val \/ P. have Uex val : exists b, U val b by exists val; left. pose f val := projT1 (cid (Uex val)). pose Uf val : U val (f val) := projT2 (cid (Uex val)). have : f true <> f false \/ P. have [] := (Uf true, Uf false); rewrite /U. by move=> [->|?] [->|?] ; do ?[by right]; left. move=> [fTFN|]; [right=> p|by left]; apply: fTFN. have UTF : U true = U false by rewrite predeqE /U => b; split=> _; right. rewrite /f; move: (Uex true) (Uex false); rewrite UTF => p1 p2. by congr (projT1 (cid _)); apply: Prop_irrelevance. Qed. Lemma pselect (P : Prop): {P} + {~P}. Proof. have : exists b, if b then P else ~ P. by case: (EM P); [exists true|exists false]. by move=> /cid [[]]; [left|right]. Qed. Lemma pdegen (P : Prop): P = True \/ P = False. Proof. by have [p|Np] := pselect P; [left|right]; rewrite propeqE. Qed. Lemma lem (P : Prop): P \/ ~P. Proof. by case: (pselect P); tauto. Qed. (* -------------------------------------------------------------------- *) Lemma trueE : true = True :> Prop. Proof. by rewrite propeqE; split. Qed. Lemma falseE : false = False :> Prop. Proof. by rewrite propeqE; split. Qed. Lemma propF (P : Prop) : ~ P -> P = False. Proof. by move=> p; rewrite propeqE; tauto. Qed. Lemma eq_forall T (U V : T -> Prop) : (forall x : T, U x = V x) -> (forall x, U x) = (forall x, V x). Proof. by move=> e; rewrite propeqE; split=> ??; rewrite (e,=^~e). Qed. Lemma eq_exists T (U V : T -> Prop) : (forall x : T, U x = V x) -> (exists x, U x) = (exists x, V x). Proof. by move=> e; rewrite propeqE; split=> - [] x ?; exists x; rewrite (e,=^~e). Qed. Lemma reflect_eq (P : Prop) (b : bool) : reflect P b -> P = b. Proof. by rewrite propeqE; exact: rwP. Qed. Definition asbool (P : Prop) := if pselect P then true else false. Notation "`[< P >]" := (asbool P) : bool_scope. Lemma asboolE (P : Prop) : `[

] = P :> Prop. Proof. by rewrite propeqE /asbool; case: pselect; split. Qed. Lemma asboolP (P : Prop) : reflect P `[

]. Proof. by apply: (equivP idP); rewrite asboolE. Qed. Lemma asboolPn (P : Prop) : reflect (~ P) (~~ `[

]). Proof. by rewrite /asbool; case: pselect=> h; constructor. Qed. Lemma asboolW (P : Prop) : `[

] -> P. Proof. by case: asboolP. Qed. (* Shall this be a coercion ?*) Lemma asboolT (P : Prop) : P -> `[

]. Proof. by case: asboolP. Qed. Lemma asboolF (P : Prop) : ~ P -> `[

] = false. Proof. by apply/introF/asboolP. Qed. Lemma is_true_inj : injective is_true. Proof. by move=> [] []; rewrite ?(trueE, falseE) ?propeqE; tauto. Qed. (* -------------------------------------------------------------------- *) Lemma asbool_equiv_eq {P Q : Prop} : (P <-> Q) -> `[

] = `[]. Proof. by rewrite -propeqE => ->. Qed. Lemma asbool_equiv_eqP {P Q : Prop} QQ : reflect Q QQ -> (P <-> Q) -> `[

] = QQ. Proof. move=> Q_QQ [hPQ hQP]; apply/idP/Q_QQ=> [/asboolP//|]. by move=> hQ; apply/asboolP/hQP. Qed. Lemma asbool_equiv {P Q : Prop} : (P <-> Q) -> (`[

] <-> `[]). Proof. by move/asbool_equiv_eq->. Qed. Lemma asbool_eq_equiv {P Q : Prop} : `[

] = `[] -> (P <-> Q). Proof. by move=> eq; split=> /asboolP; rewrite (eq, =^~ eq) => /asboolP. Qed. (* -------------------------------------------------------------------- *) Lemma and_asboolP (P Q : Prop) : reflect (P /\ Q) (`[

] && `[]). Proof. apply: (iffP idP); first by case/andP=> /asboolP hP /asboolP hQ. by case=> /asboolP-> /asboolP->. Qed. Lemma or_asboolP (P Q : Prop) : reflect (P \/ Q) (`[

] || `[]). Proof. apply: (iffP idP); first by case/orP=> /asboolP; [left | right]. by case=> /asboolP-> //=; rewrite orbT. Qed. Lemma asbool_neg {P : Prop} : `[<~ P>] = ~~ `[

]. Proof. by apply/idP/asboolPn=> [/asboolP|/asboolT]. Qed. Lemma asbool_or {P Q : Prop} : `[

] = `[

] || `[]. Proof. exact: (asbool_equiv_eqP (or_asboolP _ _)). Qed. Lemma asbool_and {P Q : Prop} : `[

] = `[

] && `[]. Proof. exact: (asbool_equiv_eqP (and_asboolP _ _)). Qed. (* -------------------------------------------------------------------- *) Lemma imply_asboolP {P Q : Prop} : reflect (P -> Q) (`[

] ==> `[]). Proof. apply: (iffP implyP)=> [PQb /asboolP/PQb/asboolW //|]. by move=> PQ /asboolP/PQ/asboolT. Qed. Lemma asbool_imply {P Q : Prop} : `[

Q>] = `[

] ==> `[]. Proof. exact: (asbool_equiv_eqP imply_asboolP). Qed. Lemma imply_asboolPn (P Q : Prop) : reflect (P /\ ~ Q) (~~ `[

Q>]). Proof. apply: (iffP idP). by rewrite asbool_imply negb_imply -asbool_neg => /and_asboolP. by move/and_asboolP; rewrite asbool_neg -negb_imply asbool_imply. Qed. (* -------------------------------------------------------------------- *) Lemma forall_asboolP {T : Type} (P : T -> Prop) : reflect (forall x, `[

]) (`[]). Proof. apply: (iffP idP); first by move/asboolP=> Px x; apply/asboolP. by move=> Px; apply/asboolP=> x; apply/asboolP. Qed. Lemma exists_asboolP {T : Type} (P : T -> Prop) : reflect (exists x, `[

]) (`[]). Proof. apply: (iffP idP); first by case/asboolP=> x Px; exists x; apply/asboolP. by case=> x bPx; apply/asboolP; exists x; apply/asboolP. Qed. (* -------------------------------------------------------------------- *) Lemma contrap (Q P : Prop) : (Q -> P) -> ~ P -> ~ Q. Proof. move=> cb /asboolPn nb; apply/asboolPn. by apply: contra nb => /asboolP /cb /asboolP. Qed. Definition contrapNN := contra. Lemma contrapL (Q P : Prop) : (Q -> ~ P) -> P -> ~ Q. Proof. move=> cb /asboolP hb; apply/asboolPn. by apply: contraL hb => /asboolP /cb /asboolPn. Qed. Definition contrapTN := contrapL. Lemma contrapR (Q P : Prop) : (~ Q -> P) -> ~ P -> Q. Proof. move=> cb /asboolPn nb; apply/asboolP. by apply: contraR nb => /asboolP /cb /asboolP. Qed. Definition contrapNT := contrapR. Lemma contrapLR (Q P : Prop) : (~ Q -> ~ P) -> P -> Q. Proof. move=> cb /asboolP hb; apply/asboolP. by apply: contraLR hb => /asboolP /cb /asboolPn. Qed. Definition contrapTT := contrapLR. Lemma contrapT P : ~ ~ P -> P. Proof. by move/asboolPn=> nnb; apply/asboolP; apply: contraR nnb => /asboolPn /asboolP. Qed. Lemma wlog_neg P : (~ P -> P) -> P. Proof. by move=> ?; case: (pselect P). Qed. Lemma notT (P : Prop) : P = False -> ~ P. Proof. by move->. Qed. Lemma notTE (P : Prop) : (~ P) -> P = False. Proof. by case: (pdegen P)=> ->. Qed. Lemma notFE (P : Prop) : (~ P) = False -> P. Proof. move/notT; exact: contrapT. Qed. Lemma notK : involutive not. Proof. move=> P; case: (pdegen P)=> ->; last by apply: notTE; intuition. by rewrite [~ True]notTE //; case: (pdegen (~ False)) => // /notFE. Qed. Lemma not_inj : injective not. Proof. exact: can_inj notK. Qed. Lemma notLR P Q : (P = ~ Q) -> (~ P) = Q. Proof. exact: canLR notK. Qed. Lemma notRL P Q : (~ P) = Q -> P = ~ Q. Proof. exact: canRL notK. Qed. (* -------------------------------------------------------------------- *) (* assia : let's see if we need the simplpred machinery. In any case, we sould first try definitions + appropriate Arguments setting to see whether these can replace the canonical structures machinery. *) Definition predp T := T -> Prop. Identity Coercion fun_of_pred : predp >-> Funclass. Definition relp T := T -> predp T. Identity Coercion fun_of_rel : rel >-> Funclass. Notation xpredp0 := (fun _ => False). Notation xpredpT := (fun _ => True). Notation xpredpI := (fun (p1 p2 : predp _) x => p1 x /\ p2 x). Notation xpredpU := (fun (p1 p2 : predp _) x => p1 x \/ p2 x). Notation xpredpC := (fun (p : predp _) x => ~ p x). Notation xpredpD := (fun (p1 p2 : predp _) x => ~ p2 x /\ p1 x). Notation xpreimp := (fun f (p : predp _) x => p (f x)). Notation xrelpU := (fun (r1 r2 : relp _) x y => r1 x y \/ r2 x y). (* -------------------------------------------------------------------- *) Definition pred0p (T : Type) (P : predp T) : bool := `[

]. Prenex Implicits pred0p. Lemma pred0pP (T : Type) (P : predp T) : reflect (P =1 xpredp0) (pred0p P). Proof. by apply: (iffP (asboolP _)). Qed. (* -------------------------------------------------------------------- *) Module BoolQuant. Inductive box := Box & bool. Bind Scope box_scope with box. Delimit Scope box_scope with P. Definition idbox {T : Type} (B : box) := fun (x : T) => B. Definition unbox {T : Type} (B : T -> box) : bool := asbool (forall x : T, let: Box b := B x in b). Notation "F ^*" := (Box F) (at level 2). Notation "F ^~" := (~~ F) (at level 2). Section Definitions. Variable T : Type. Implicit Types (B : box) (x y : T). Definition quant0p Bp := pred0p (fun x : T => let: F^* := Bp x x in F). (* The first redundant argument protects the notation from Coq's K-term *) (* display kludge; the second protects it from simpl and /=. *) Definition ex B x y := B. (* Binding the predicate value rather than projecting it prevents spurious *) (* unfolding of the boolean connectives by unification. *) Definition all B x y := let: F^* := B in F^~^*. Definition all_in C B x y := let: F^* := B in (C ==> F)^~^*. Definition ex_in C B x y := let: F^* := B in (C && F)^*. End Definitions. Notation "`[ x | B ]" := (quant0p (fun x => B x)) (at level 0, x name). Notation "`[ x : T | B ]" := (quant0p (fun x : T => B x)) (at level 0, x name). Module Exports. Delimit Scope quant_scope with Q. (* Bogus, only used to declare scope. *) Bind Scope quant_scope with box. Notation ", F" := F^* (at level 200, format ", '/ ' F") : quant_scope. Notation "`[ 'forall' x B ]" := `[x | all B] (at level 0, x at level 99, B at level 200, format "`[ '[hv' 'forall' x B ] ']'") : bool_scope. Notation "`[ 'forall' x : T B ]" := `[x : T | all B] (at level 0, x at level 99, B at level 200, only parsing) : bool_scope. Notation "`[ 'forall' ( x | C ) B ]" := `[x | all_in C B] (at level 0, x at level 99, B at level 200, format "`[ '[hv' '[' 'forall' ( x '/ ' | C ) ']' B ] ']'") : bool_scope. Notation "`[ 'forall' ( x : T | C ) B ]" := `[x : T | all_in C B] (at level 0, x at level 99, B at level 200, only parsing) : bool_scope. Notation "`[ 'forall' x 'in' A B ]" := `[x | all_in (x \in A) B] (at level 0, x at level 99, B at level 200, format "`[ '[hv' '[' 'forall' x '/ ' 'in' A ']' B ] ']'") : bool_scope. Notation "`[ 'forall' x : T 'in' A B ]" := `[x : T | all_in (x \in A) B] (at level 0, x at level 99, B at level 200, only parsing) : bool_scope. Notation ", 'forall' x B" := `[x | all B]^* (at level 200, x at level 99, B at level 200, format ", '/ ' 'forall' x B") : quant_scope. Notation ", 'forall' x : T B" := `[x : T | all B]^* (at level 200, x at level 99, B at level 200, only parsing) : quant_scope. Notation ", 'forall' ( x | C ) B" := `[x | all_in C B]^* (at level 200, x at level 99, B at level 200, format ", '/ ' '[' 'forall' ( x '/ ' | C ) ']' B") : quant_scope. Notation ", 'forall' ( x : T | C ) B" := `[x : T | all_in C B]^* (at level 200, x at level 99, B at level 200, only parsing) : quant_scope. Notation ", 'forall' x 'in' A B" := `[x | all_in (x \in A) B]^* (at level 200, x at level 99, B at level 200, format ", '/ ' '[' 'forall' x '/ ' 'in' A ']' B") : bool_scope. Notation ", 'forall' x : T 'in' A B" := `[x : T | all_in (x \in A) B]^* (at level 200, x at level 99, B at level 200, only parsing) : bool_scope. Notation "`[ 'exists' x B ]" := `[x | ex B]^~ (at level 0, x at level 99, B at level 200, format "`[ '[hv' 'exists' x B ] ']'") : bool_scope. Notation "`[ 'exists' x : T B ]" := `[x : T | ex B]^~ (at level 0, x at level 99, B at level 200, only parsing) : bool_scope. Notation "`[ 'exists' ( x | C ) B ]" := `[x | ex_in C B]^~ (at level 0, x at level 99, B at level 200, format "`[ '[hv' '[' 'exists' ( x '/ ' | C ) ']' B ] ']'") : bool_scope. Notation "`[ 'exists' ( x : T | C ) B ]" := `[x : T | ex_in C B]^~ (at level 0, x at level 99, B at level 200, only parsing) : bool_scope. Notation "`[ 'exists' x 'in' A B ]" := `[x | ex_in (x \in A) B]^~ (at level 0, x at level 99, B at level 200, format "`[ '[hv' '[' 'exists' x '/ ' 'in' A ']' B ] ']'") : bool_scope. Notation "`[ 'exists' x : T 'in' A B ]" := `[x : T | ex_in (x \in A) B]^~ (at level 0, x at level 99, B at level 200, only parsing) : bool_scope. Notation ", 'exists' x B" := `[x | ex B]^~^* (at level 200, x at level 99, B at level 200, format ", '/ ' 'exists' x B") : quant_scope. Notation ", 'exists' x : T B" := `[x : T | ex B]^~^* (at level 200, x at level 99, B at level 200, only parsing) : quant_scope. Notation ", 'exists' ( x | C ) B" := `[x | ex_in C B]^~^* (at level 200, x at level 99, B at level 200, format ", '/ ' '[' 'exists' ( x '/ ' | C ) ']' B") : quant_scope. Notation ", 'exists' ( x : T | C ) B" := `[x : T | ex_in C B]^~^* (at level 200, x at level 99, B at level 200, only parsing) : quant_scope. Notation ", 'exists' x 'in' A B" := `[x | ex_in (x \in A) B]^~^* (at level 200, x at level 99, B at level 200, format ", '/ ' '[' 'exists' x '/ ' 'in' A ']' B") : bool_scope. Notation ", 'exists' x : T 'in' A B" := `[x : T | ex_in (x \in A) B]^~^* (at level 200, x at level 99, B at level 200, only parsing) : bool_scope. End Exports. End BoolQuant. Export BoolQuant.Exports. Open Scope quant_scope. (* -------------------------------------------------------------------- *) Section QuantifierCombinators. Variables (T : Type) (P : pred T) (PP : predp T). Hypothesis viewP : forall x, reflect (PP x) (P x). Lemma existsPP : reflect (exists x, PP x) `[exists x, P x]. Proof. apply: (iffP idP). move/asboolP; (* oops notation! *) apply: contrapR => nh x /=; apply: notTE. by apply: contrap nh => /viewP Px; exists x. case=> x PPx; apply/asboolP=> /(_ x) /notT /=; rewrite -/(not (~ P x)) notK. exact/viewP. Qed. Lemma forallPP : reflect (forall x, PP x) `[forall x, P x]. Proof. apply: (iffP idP). by move/asboolP=> h x; move/notT: (h x)=> /= /negP; rewrite negbK => /viewP. move=> h; apply/asboolP=> x; apply/notTE/negP; rewrite negbK; exact/viewP. Qed. End QuantifierCombinators. Section PredQuantifierCombinators. Variables (T : Type) (P : pred T). Lemma existsbP : reflect (exists x, P x) `[exists x, P x]. Proof. exact: existsPP (fun x => @idP (P x)). Qed. Lemma existsbE : `[exists x, P x] = `[]. Proof. apply/esym/is_true_inj; rewrite asboolE propeqE; apply: rwP; exact: existsbP. Qed. Lemma forallbP : reflect (forall x, P x) `[forall x, P x]. Proof. exact: forallPP (fun x => @idP (P x)). Qed. Lemma forallbE : `[forall x, P x] = `[]. Proof. apply/esym/is_true_inj; rewrite asboolE propeqE; apply: rwP; exact: forallbP. Qed. End PredQuantifierCombinators. (* -------------------------------------------------------------------- *) Lemma existsp_asboolP {T} {P : T -> Prop} : reflect (exists x : T, P x) `[exists x : T, `[

]]. Proof. exact: existsPP (fun x => @asboolP (P x)). Qed. Lemma forallp_asboolP {T} {P : T -> Prop} : reflect (forall x : T, P x) `[forall x : T, `[

]]. Proof. exact: forallPP (fun x => @asboolP (P x)). Qed. Lemma forallp_asboolPn {T} {P : T -> Prop} : reflect (forall x : T, ~ P x) (~~ `[]). Proof. apply: (iffP idP)=> [/asboolPn NP x Px|NP]. by apply/NP; exists x. by apply/asboolP=> -[x]; apply/NP. Qed. Lemma existsp_asboolPn {T} {P : T -> Prop} : reflect (exists x : T, ~ P x) (~~ `[]). Proof. apply: (iffP idP); last by case=> x NPx; apply/asboolPn=> /(_ x). move/asboolPn=> NP; apply/asboolP/negbNE/asboolPn=> h. by apply/NP=> x; apply/asboolP/negbNE/asboolPn=> NPx; apply/h; exists x. Qed. Lemma asbool_forallNb {T : Type} (P : pred T) : `[< forall x : T, ~~ (P x) >] = ~~ `[< exists x : T, P x >]. Proof. apply: (asbool_equiv_eqP forallp_asboolPn); by split=> h x; apply/negP/h. Qed. Lemma asbool_existsNb {T : Type} (P : pred T) : `[< exists x : T, ~~ (P x) >] = ~~ `[< forall x : T, P x >]. Proof. apply: (asbool_equiv_eqP existsp_asboolPn); by split=> -[x h]; exists x; apply/negP. Qed. Reserved Notation "[ 'set' x : T | P ]" (at level 0, x at level 99). Reserved Notation "[ 'set' x | P ]" (at level 0, x, P at level 99, format "[ 'set' x | P ]"). Reserved Notation "[ 'set' E | x 'in' A ]" (at level 0, E, x at level 99, format "[ '[hv' 'set' E '/ ' | x 'in' A ] ']'"). Reserved Notation "[ 'set' E | x 'in' A & y 'in' B ]" (at level 0, E, x at level 99, format "[ '[hv' 'set' E '/ ' | x 'in' A & y 'in' B ] ']'"). Reserved Notation "[ 'set' 'of' F ]" (at level 0, format "[ 'set' 'of' F ]"). Reserved Notation "[ 'set' a ]" (at level 0, a at level 99, format "[ 'set' a ]"). Reserved Notation "[ 'set' a : T ]" (at level 0, a at level 99, format "[ 'set' a : T ]"). Reserved Notation "A `|` B" (at level 52, left associativity). Reserved Notation "a |` A" (at level 52, left associativity). Reserved Notation "[ 'set' a1 ; a2 ; .. ; an ]" (at level 0, a1 at level 99, format "[ 'set' a1 ; a2 ; .. ; an ]"). Reserved Notation "A `&` B" (at level 48, left associativity). Reserved Notation "A `*` B" (at level 46, left associativity). Reserved Notation "A .`1" (at level 2, left associativity, format "A .`1"). Reserved Notation "A .`2" (at level 2, left associativity, format "A .`2"). Reserved Notation "~` A" (at level 35, right associativity). Reserved Notation "[ 'set' ~ a ]" (at level 0, format "[ 'set' ~ a ]"). Reserved Notation "A `\` B" (at level 50, left associativity). Reserved Notation "A `\ b" (at level 50, left associativity). (* Reserved Notation "A `+` B" (at level 54, left associativity). Reserved Notation "A +` B" (at level 54, left associativity). *) Reserved Notation "\bigcup_ ( i 'in' P ) F" (at level 41, F at level 41, i, P at level 50, format "'[' \bigcup_ ( i 'in' P ) '/ ' F ']'"). Reserved Notation "\bigcup_ ( i : T ) F" (at level 41, F at level 41, i at level 50, format "'[' \bigcup_ ( i : T ) '/ ' F ']'"). Reserved Notation "\bigcup_ i F" (at level 41, F at level 41, i at level 0, format "'[' \bigcup_ i '/ ' F ']'"). Reserved Notation "\bigcap_ ( i 'in' P ) F" (at level 41, F at level 41, i, P at level 50, format "'[' \bigcap_ ( i 'in' P ) '/ ' F ']'"). Reserved Notation "\bigcap_ ( i : T ) F" (at level 41, F at level 41, i at level 50, format "'[' \bigcap_ ( i : T ) '/ ' F ']'"). Reserved Notation "\bigcap_ i F" (at level 41, F at level 41, i at level 0, format "'[' \bigcap_ i '/ ' F ']'"). Reserved Notation "A `<=` B" (at level 70, no associativity). Reserved Notation "A `<=>` B" (at level 70, no associativity). Reserved Notation "f @^-1` A" (at level 24). Reserved Notation "f @` A" (at level 24). Reserved Notation "A !=set0" (at level 80). Definition set A := A -> Prop. Definition in_set T (P : set T) : pred T := [pred x | `[

]]. Canonical set_predType T := @PredType T (set T) (@in_set T). Lemma in_setE T (P : set T) x : x \in P = P x :> Prop. Proof. by rewrite propeqE; split => [] /asboolP. Qed. Declare Scope classical_set_scope. Bind Scope classical_set_scope with set. Local Open Scope classical_set_scope. Delimit Scope classical_set_scope with classic. Definition mkset {T} (A : T -> Prop) : set T := A. Notation "[ 'set' x : T | P ]" := (mkset (fun x : T => P)) : classical_set_scope. Notation "[ 'set' x | P ]" := [set x : _ | P] : classical_set_scope. Notation "[ 'set' E | x 'in' A ]" := [set y | exists2 x, A x & E = y] : classical_set_scope. Notation "[ 'set' E | x 'in' A & y 'in' B ]" := [set z | exists2 x, A x & exists2 y, B y & E = z] : classical_set_scope. Definition image {A B} (f : A -> B) (X : set A) : set B := [set f a | a in X]. Definition preimage {A B} (f : A -> B) (X : set B) : set A := [set a | X (f a)]. Arguments preimage A B f X / a. Definition setT {A} := [set _ : A | True]. Definition set0 {A} := [set _ : A | False]. Definition set1 {A} (x : A) := [set a : A | x = a]. Definition setI {A} (X Y : set A) := [set a | X a /\ Y a]. Definition setU {A} (X Y : set A) := [set a | X a \/ Y a]. Definition setV {A B} (X : set A) (Y : set B) := [set a : A + B | sum_rect _ X Y a]. Definition settt : set unit := setT. Definition nonempty {A} (X : set A) := exists x, X x. Definition setC {A} (X : set A) := [set a | ~ X a]. Definition setD {A} (X Y : set A) := [set a | X a /\ ~ Y a]. Definition setM {A B} (X : set A) (Y : set B) := [set x | X x.1 /\ Y x.2]. Definition fst_set {A B} (X : set (A * B)) := [set x | exists y, X (x, y)]. Definition snd_set {A B} (X : set (A * B)) := [set y | exists x, X (x, y)]. Notation "[ 'set' 'of' F ]" := [set F i | i in setT] : classical_set_scope. Notation "[ 'set' a ]" := (set1 a) : classical_set_scope. Notation "[ 'set' a : T ]" := [set (a : T)] : classical_set_scope. Notation "A `|` B" := (setU A B) : classical_set_scope. Notation "a |` A" := ([set a] `|` A) : classical_set_scope. Notation "[ 'set' a1 ; a2 ; .. ; an ]" := (setU .. (a1 |` [set a2]) .. [set an]) : classical_set_scope. Notation "A `&` B" := (setI A B) : classical_set_scope. Notation "A `*` B" := (setM A B) : classical_set_scope. Notation "A .`1" := (fst_set A) : classical_set_scope. Notation "A .`2" := (snd_set A) : classical_set_scope. Notation "~` A" := (setC A) : classical_set_scope. Notation "[ 'set' ~ a ]" := (~` [set a]) : classical_set_scope. Notation "A `\` B" := (setD A B) : classical_set_scope. Notation "A `\ a" := (A `\` [set a]) : classical_set_scope. Definition bigsetI A I (P : set I) (X : I -> set A) := [set a | forall i, P i -> X i a]. Definition bigsetU A I (P : set I) (X : I -> set A) := [set a | exists2 i, P i & X i a]. Notation "\bigcup_ ( i 'in' P ) F" := (bigsetU P (fun i => F)) : classical_set_scope. Notation "\bigcup_ ( i : T ) F" := (\bigcup_(i in @setT T) F) : classical_set_scope. Notation "\bigcup_ i F" := (\bigcup_(i : _) F) : classical_set_scope. Notation "\bigcap_ ( i 'in' P ) F" := (bigsetI P (fun i => F)) : classical_set_scope. Notation "\bigcap_ ( i : T ) F" := (\bigcap_(i in @setT T) F) : classical_set_scope. Notation "\bigcap_ i F" := (\bigcap_(i : _) F) : classical_set_scope. Definition subset {A} (X Y : set A) := forall a, X a -> Y a. Notation "A `<=` B" := (subset A B) : classical_set_scope. Notation "A `<=>` B" := ((A `<=` B) /\ (B `<=` A)) : classical_set_scope. Notation "f @^-1` A" := (preimage f A) : classical_set_scope. Notation "f @` A" := (image f A) : classical_set_scope. Notation "A !=set0" := (nonempty A) : classical_set_scope. Definition graph_sym {T T'} (A : set (T * T')) : set (T' * T) := [set xy | A (xy.2, xy.1)]. Definition graph_comp {T' T T''} (A : set (T * T')) (B : set (T' * T'')) : set (T * T'') := [set xz | exists2 y, A (xz.1, y) & B (y, xz.2)]. Lemma eqEsubset T (F G : set T) : F `<=` G -> G `<=` F -> F = G. Proof. by move=> H K; rewrite funeqE=> s; rewrite propeqE; split=> [/H|/K]. Qed. Lemma sub0set T (X : set T) : set0 `<=` X. Proof. by []. Qed. Lemma subset0 T (X : set T) : (X `<=` set0) = (X = set0). Proof. rewrite propeqE; split => [?|-> //]; exact/eqEsubset. Qed. Lemma set0P T (X : set T) : (X <> set0) <-> (X !=set0). Proof. split=> [X_neq0|[t tX] X_eq0]; last by rewrite X_eq0 in tX. apply: contrapT => /asboolPn/forallp_asboolPn X0. by apply/X_neq0/eqEsubset. Qed. Lemma imageP {A B} (f : A -> B) (X : set A) a : X a -> (f @` X) (f a). Proof. by exists a. Qed. Lemma sub_image_setI {A B} (f : A -> B) (X Y : set A) : f @` (X `&` Y) `<=` f @` X `&` f @` Y. Proof. by move=> b [x [Xa Ya <-]]; split; apply: imageP. Qed. Arguments sub_image_setI {A B f X Y} a _. Lemma nonempty_image {A B} (f : A -> B) (X : set A) : f @` X !=set0 -> X !=set0. Proof. by case=> b [a]; exists a. Qed. Lemma nonempty_preimage {A B} (f : A -> B) (X : set B) : f @^-1` X !=set0 -> X !=set0. Proof. by case=> [a ?]; exists (f a). Qed. Lemma preimage_image A B (f : A -> B) (X : set A) : X `<=` f@^-1` (f @` X). Proof. by move=> a Xa; exists a. Qed. Lemma image_preimage A B (f : A -> B) (X : set B) : f @` setT = setT -> f @` (f @^-1` X) = X. Proof. move=> fsurj; rewrite predeqE => x; split; first by move=> [?? <-]. move=> Xx; have : setT x by []; rewrite -fsurj => -[y _ fy_eqx]. by exists y => //; rewrite /preimage/mkset fy_eqx. Qed. Lemma preimage_setC A B (f : A -> B) (X : set B) : ~` (f @^-1` X) = f @^-1` (~` X). Proof. by rewrite predeqE => a; split=> nXfa ?; apply: nXfa. Qed. Lemma subset_empty {A} (X Y : set A) : X `<=` Y -> X !=set0 -> Y !=set0. Proof. by move=> sXY [x Xx]; exists x; apply: sXY. Qed. Lemma subset_trans {A} (Y X Z : set A) : X `<=` Y -> Y `<=` Z -> X `<=` Z. Proof. by move=> sXY sYZ ? ?; apply/sYZ/sXY. Qed. Lemma nonempty_preimage_setI {A B} (f : A -> B) (X Y : set B) : (f @^-1` (X `&` Y)) !=set0 <-> (f @^-1` X `&` f @^-1` Y) !=set0. Proof. by split; case=> x ?; exists x. Qed. Lemma subsetC {A} (X Y : set A) : X `<=` Y -> ~` Y `<=` ~` X. Proof. by move=> sXY ? nYa ?; apply/nYa/sXY. Qed. Lemma subsetU {A} (X Y Z : set A) : X `<=` Z -> Y `<=` Z -> X `|` Y `<=` Z. Proof. by move=> sXZ sYZ a; apply: or_ind; [apply: sXZ|apply: sYZ]. Qed. Lemma subUset T (X Y Z : set T) : (Y `|` Z `<=` X) = ((Y `<=` X) /\ (Z `<=` X)). Proof. rewrite propeqE; split => [|[YX ZX] x]; last by case; [exact: YX | exact: ZX]. by move=> sYZ_X; split=> x ?; apply sYZ_X; [left | right]. Qed. Lemma subsetI A (X Y Z : set A) : (X `<=` Y `&` Z) = ((X `<=` Y) /\ (X `<=` Z)). Proof. rewrite propeqE; split=> [H|[y z ??]]; split; by [move=> ?/H[]|apply y|apply z]. Qed. Lemma subIset {A} (X Y Z : set A) : X `<=` Z \/ Y `<=` Z -> X `&` Y `<=` Z. Proof. case => H a; by [move=> [/H] | move=> [_ /H]]. Qed. Lemma setD_eq0 A (X Y : set A) : (X `\` Y = set0) = (X `<=` Y). Proof. rewrite propeqE; split=> [XDY0 a|sXY]. by apply: contrapTT => nYa xA; rewrite -[False]/(set0 a) -XDY0. by rewrite predeqE => ?; split=> // - [?]; apply; apply: sXY. Qed. Lemma setDE {A} (X Y : set A) : X `\` Y = X `&` ~` Y. Proof. by []. Qed. Lemma setIid {A} (X : set A) : X `&` X = X. Proof. by rewrite predeqE => ?; split=> [[]|]. Qed. Lemma setIC {A} (X Y : set A) : X `&` Y = Y `&` X. Proof. by rewrite predeqE => ?; split=> [[]|[]]. Qed. Lemma setIT {A} (X : set A) : X `&` setT = X. Proof. by rewrite predeqE => ?; split=> [[]|]. Qed. Lemma setI0 {A} (X : set A) : X `&` set0 = set0. Proof. by rewrite predeqE => ?; split=> [[]|]. Qed. Lemma set0I A (Y : set A) : set0 `&` Y = set0. Proof. by rewrite setIC setI0. Qed. Lemma setIA {A} (X Y Z : set A) : X `&` (Y `&` Z) = X `&` Y `&` Z. Proof. by rewrite predeqE => ?; split=> [[? []]|[[]]]. Qed. Lemma setICA {A} (X Y Z : set A) : X `&` (Y `&` Z) = Y `&` (X `&` Z). Proof. by rewrite setIA [X `&` _]setIC -setIA. Qed. Lemma setIAC {A} (X Y Z : set A) : X `&` Y `&` Z = X `&` Z `&` Y. Proof. by rewrite setIC setICA setIA. Qed. Lemma setIACA {A} (X Y Z T : set A) : X `&` Y `&` (Z `&` T) = X `&` Z `&` (Y `&` T). Proof. by rewrite -setIA [Y `&` _]setICA setIA. Qed. Lemma setUA A : associative (@setU A). Proof. by move=> p q r; rewrite /setU /mkset predeqE => a; tauto. Qed. Lemma setUid A : idempotent (@setU A). Proof. move=> p; rewrite /setU predeqE /mkset => a; tauto. Qed. Lemma setUC A : commutative (@setU A). Proof. move=> p q; rewrite /setU predeqE /mkset => a; tauto. Qed. Lemma set0U T (X : set T) : set0 `|` X = X. Proof. by rewrite funeqE => t; rewrite propeqE; split; [case|right]. Qed. Lemma setU0 T (X : set T) : X `|` set0 = X. Proof. by rewrite funeqE => t; rewrite propeqE; split; [case|left]. Qed. Lemma setU_eq0 T (X Y : set T) : (X `|` Y = set0) = ((X = set0) /\ (Y = set0)). Proof. by rewrite -!subset0 subUset. Qed. Lemma setI_bigcapr A I (D : set I) (f : I -> set A) (X : set A) : X `&` \bigcap_(i in D) f i = \bigcap_(i in setV settt D) sum_rect (fun=> set A) (fun=> X) f i. Proof. rewrite predeqE => a; split; first by move=> [Xa IDfa] [[]|i]//= /IDfa. move=> IXDfa; split; first by apply: (IXDfa (inl tt)). by move=> i Di; apply: (IXDfa (inr i)). Qed. Lemma setI_bigcupl A I (D : set I) (f : I -> set A) (X : set A) : \bigcup_(i in D) f i `&` X = \bigcup_(i in D) (f i `&` X). Proof. rewrite predeqE => a; split => [[[i Di] fia] Xa|[i Di [fia Xa]]]. by exists i. by split=> //; exists i. Qed. Lemma setI_bigcupr A I (D : set I) (f : I -> set A) (X : set A) : X `&` \bigcup_(i in D) f i = \bigcup_(i in D) (X `&` f i). Proof. rewrite setIC setI_bigcupl; congr bigsetU. by rewrite funeqE => i; rewrite setIC. Qed. Lemma setU_bigcapl A I (D : set I) (f : I -> set A) (X : set A) : \bigcap_(i in D) f i `|` X = \bigcap_(i in D) (f i `|` X). Proof. rewrite predeqE => a; split => [|fI]. by move=> [fI|] i Di; [left; apply: fI|right]. by have [Xa|Xna] := asboolP (X a); [right |left => i /fI[]]. Qed. Lemma setU_bigcapr A I (D : set I) (f : I -> set A) (X : set A) : X `|` \bigcap_(i in D) f i = \bigcap_(i in D) (X `|` f i). Proof. rewrite setUC setU_bigcapl; congr bigsetI. by rewrite funeqE => i; rewrite setUC. Qed. Lemma bigcup_set1 {A I} (D : set I) (f : I -> set A) : \bigcup_(i in D) [set f i] = [set f i | i in D]. Proof. by []. Qed. Lemma bigcup_map {A I J} (D : set I) (h : I -> J) (f : J -> set A) : \bigcup_(i in D) f (h i) = \bigcup_(j in [set h i | i in D]) f j. Proof. rewrite predeqE => a; split=> [[i Di]|[_ [i Di <-]]] fhia; last by exists i. by exists (h i) => //; exists i. Qed. Lemma bigcup_bigcup {A I J} (DI : set I) (DJ : I -> set J) (f : J -> set A) : \bigcup_(j in \bigcup_(i in DI) DJ i) f j = \bigcup_(i in DI) \bigcup_(j in DJ i) f j. Proof. rewrite predeqE=> a; split => [[j [i Di Dij fja]]|[i Di [j Dij fja]]]. by exists i => //; exists j. by exists j => //; exists i. Qed. Lemma bigcap_bigcup {A I J} (DI : set I) (DJ : I -> set J) (f : J -> set A) : \bigcap_(j in \bigcup_(i in DI) DJ i) f j = \bigcap_(i in DI) \bigcap_(j in DJ i) f j. Proof. rewrite predeqE=> a; split=> [UUfa i Di j Dij|UUfa j [i Di Dij]]. by apply: UUfa; exists i. exact: UUfa Dij. Qed. Lemma bigcupM {I J A} (DI : set I) (DJ : set J) (f : I -> J -> set A) : \bigcup_(i in DI `*` DJ) f i.1 i.2 = \bigcup_(i in DI) \bigcup_(j in DJ) f i j. Proof. rewrite predeqE => i /=. split=> [[[a b] [/=Da Db] fabj]|[a Da [b Db fabi]]]; last by exists (a, b). by exists a => //; exists b => //. Qed. Definition is_singleton {A} (X : set A) := forall x y, X x -> X y -> x = y. Definition is_fun {A B} (f : A -> B -> Prop) := all (is_singleton \o f). Definition is_total {A B} (f : A -> B -> Prop) := all (nonempty \o f). Definition is_totalfun {A B} (f : A -> B -> Prop) := forall x, nonempty (f x) /\ is_singleton (f x). Record is_filter {T} (F : set (set T)) := IsFilter { filterT : F setT ; filterI : forall P Q : set T, F P -> F Q -> F (setI P Q) ; filterS : forall P Q : set T, P `<=` Q -> F P -> F Q; filter_not_empty : not (F (fun _ => False)) ; }. Definition xget {T} x0 (P : set T) : T := if pselect (exists x : T, `[

]) isn't left exP then x0 else projT1 (cid exP). Unset Auto Template Polymorphism. CoInductive xget_spec {T} x0 (P : set T) : T -> Prop -> Type := | XGetSome x of x = xget x0 P & P x : xget_spec x0 P x True | XGetNone of (forall x, ~ P x) : xget_spec x0 P x0 False. Lemma xgetP {T} x0 (P : set T) : xget_spec x0 P (xget x0 P) (P (xget x0 P)). Proof. move: (erefl (xget x0 P)); set y := {2}(xget x0 P). rewrite /xget; case: pselect => /= [?|neqP _]. by case: cid => x /= /asboolP Px; rewrite [P x]propT //; constructor. suff NP x : ~ P x by rewrite [P x0]propF //; constructor. by apply: contrap neqP => Px; exists x; apply/asboolP. Qed. Lemma xgetPex {T} x0 (P : set T) : (exists x, P x) -> P (xget x0 P). Proof. by case: xgetP=> // NP [x /NP]. Qed. Lemma xgetI {T} x0 (P : set T) (x : T): P x -> P (xget x0 P). Proof. by move=> Px; apply: xgetPex; exists x. Qed. Lemma xget_prop {T : nonPropType} x0 (P : set T) (x : T) : P x -> is_singleton P -> xget x0 P = x. Proof. by move=> Px /(_ _ _ (xgetI x0 Px) Px). Qed. Lemma xget_unique {T} x0 (P : set T) (x : T) : P x -> (forall y, P y -> y = x) -> xget x0 P = x. Proof. by move=> /xget_prop gPx eqx; apply: gPx=> y z /eqx-> /eqx. Qed. Lemma xgetPN {T} x0 (P : set T) : (forall x, ~ P x) -> xget x0 P = x0. Proof. by case: xgetP => // x _ Px /(_ x). Qed. Definition fun_of_graph {A} {B} (f0 : A -> B) (f : A -> B -> Prop) := fun x => xget (f0 x) (f x). Lemma fun_of_graphP {A} {B } (f : A -> B -> Prop) (f0 : A -> B) a : nonempty (f a) -> f a (fun_of_graph f0 f a). Proof. by move=> [b fab]; rewrite /fun_of_graph; apply: xgetI fab. Qed. Lemma fun_of_graph_uniq {A} {B } (f : A -> B -> Prop) (f0 : A -> B) a : is_singleton (f a) -> forall b, f a b -> fun_of_graph f0 f a = b. Proof. by move=> fa_prop b /xget_prop xgeteq; rewrite /fun_of_graph xgeteq. Qed. Definition total_on T (A : set T) (R : T -> T -> Prop) := forall s t, A s -> A t -> R s t \/ R t s. Section ZL. Variable (T : Type) (t0 : T) (R : T -> T -> Prop). Hypothesis (Rrefl : forall t, R t t). Hypothesis (Rtrans : forall r s t, R r s -> R s t -> R r t). Hypothesis (Rantisym : forall s t, R s t -> R t s -> s = t). Hypothesis (tot_lub : forall A : set T, total_on A R -> exists t, (forall s, A s -> R s t) /\ forall r, (forall s, A s -> R s r) -> R t r). Hypothesis (Rsucc : forall s, exists t, R s t /\ s <> t /\ forall r, R s r -> R r t -> r = s \/ r = t). Notation get := (xget t0). Notation getPex := (xgetPex t0). Let lub := fun A : {A : set T | total_on A R} => get (fun t : T => (forall s, sval A s -> R s t) /\ forall r, (forall s, sval A s -> R s r) -> R t r). Let succ := fun s => get (fun t : T => R s t /\ s <> t /\ forall r, R s r -> R r t -> r = s \/ r = t). Inductive tower : set T := | Lub : forall A, sval A `<=` tower -> tower (lub A) | Succ : forall t, tower t -> tower (succ t). Lemma ZL' : False. Proof. have lub_ub (A : {A : set T | total_on A R}) : forall s, sval A s -> R s (lub A). suff /getPex [] : exists t : T, (forall s, sval A s -> R s t) /\ forall r, (forall s, sval A s -> R s r) -> R t r by []. by apply: tot_lub; apply: (svalP A). have lub_lub (A : {A : set T | total_on A R}) : forall t, (forall s, sval A s -> R s t) -> R (lub A) t. suff /getPex [] : exists t : T, (forall s, sval A s -> R s t) /\ forall r, (forall s, sval A s -> R s r) -> R t r by []. by apply: tot_lub; apply: (svalP A). have RS s : R s (succ s) /\ s <> succ s. by have /getPex [? []] : exists t : T, R s t /\ s <> t /\ forall r, R s r -> R r t -> r = s \/ r = t by apply: Rsucc. have succS s : forall t, R s t -> R t (succ s) -> t = s \/ t = succ s. by have /getPex [? []] : exists t : T, R s t /\ s <> t /\ forall r, R s r -> R r t -> r = s \/ r = t by apply: Rsucc. suff Twtot : total_on tower R. have [R_S] := RS (lub (exist _ tower Twtot)); apply. by apply/Rantisym => //; apply/lub_ub/Succ/Lub. move=> s t Tws; elim: Tws t => {s} [A sATw ihA|s Tws ihs] t Twt. case: (pselect (forall s, sval A s -> R s t)). by move=> ?; left; apply: lub_lub. move/asboolP; rewrite asbool_neg => /existsp_asboolPn [s /asboolP]. rewrite asbool_neg => /imply_asboolPn [As nRst]; right. by have /lub_ub := As; apply: Rtrans; have [] := ihA _ As _ Twt. suff /(_ _ Twt) [Rts|RSst] : forall r, tower r -> R r s \/ R (succ s) r. by right; apply: Rtrans Rts _; have [] := RS s. by left. move=> r; elim=> {r} [A sATw ihA|r Twr ihr]. case: (pselect (forall r, sval A r -> R r s)). by move=> ?; left; apply: lub_lub. move/asboolP; rewrite asbool_neg => /existsp_asboolPn [r /asboolP]. rewrite asbool_neg => /imply_asboolPn [Ar nRrs]; right. by have /lub_ub := Ar; apply: Rtrans; have /ihA [] := Ar. have [Rrs|RSsr] := ihr; last by right; apply: Rtrans RSsr _; have [] := RS r. have : tower (succ r) by apply: Succ. move=> /ihs [RsSr|]; last by left. by have [->| ->] := succS _ _ Rrs RsSr; [right|left]; apply: Rrefl. Qed. End ZL. Lemma exist_congr T (P : T -> Prop) (s t : T) (p : P s) (q : P t) : s = t -> exist P s p = exist P t q. Proof. by move=> st; case: _ / st in q *; apply/congr1/Prop_irrelevance. Qed. Lemma Zorn T (R : T -> T -> Prop) : (forall t, R t t) -> (forall r s t, R r s -> R s t -> R r t) -> (forall s t, R s t -> R t s -> s = t) -> (forall A : set T, total_on A R -> exists t, forall s, A s -> R s t) -> exists t, forall s, R t s -> s = t. Proof. move=> Rrefl Rtrans Rantisym Rtot_max. set totR := ({A : set T | total_on A R}). set R' := fun A B : totR => sval A `<=` sval B. have R'refl A : R' A A by []. have R'trans A B C : R' A B -> R' B C -> R' A C by apply: subset_trans. have R'antisym A B : R' A B -> R' B A -> A = B. rewrite /R'; case: A; case: B => /= B totB A totA sAB sBA. by apply: exist_congr; rewrite predeqE=> ?; split=> [/sAB|/sBA]. have R'tot_lub A : total_on A R' -> exists t, (forall s, A s -> R' s t) /\ forall r, (forall s, A s -> R' s r) -> R' t r. move=> Atot. have AUtot : total_on (\bigcup_(B in A) (sval B)) R. move=> s t [B AB Bs] [C AC Ct]. have [/(_ _ Bs) Cs|/(_ _ Ct) Bt] := Atot _ _ AB AC. by have /(_ _ _ Cs Ct) := svalP C. by have /(_ _ _ Bs Bt) := svalP B. exists (exist _ (\bigcup_(B in A) sval B) AUtot); split. by move=> B ???; exists B. by move=> B Bub ? /= [? /Bub]; apply. apply: contrapT => nomax. have {}nomax t : exists s, R t s /\ s <> t. have /asboolP := nomax; rewrite asbool_neg => /forallp_asboolPn /(_ t). move=> /asboolP; rewrite asbool_neg => /existsp_asboolPn [s]. by move=> /asboolP; rewrite asbool_neg => /imply_asboolPn []; exists s. have tot0 : total_on set0 R by []. apply: (ZL' (exist _ set0 tot0)) R'tot_lub _ => // A. have /Rtot_max [t tub] := svalP A; have [s [Rts snet]] := nomax t. have Astot : total_on (sval A `|` [set s]) R. move=> u v [Au|<-]; last first. by move=> [/tub Rvt| ->]; right=> //; apply: Rtrans Rts. move=> [Av|<-]; [apply: (svalP A)|left] => //. by apply: Rtrans Rts; apply: tub. exists (exist _ (sval A `|` [set s]) Astot); split; first by move=> ??; left. split=> [AeAs|[B Btot] sAB sBAs]. case: (pselect (sval A s)); first by move=> /tub Rst; apply/snet/Rantisym. by rewrite AeAs /=; apply; right. case: (pselect (B s)) => [Bs|nBs]. by right; apply: exist_congr; rewrite predeqE => r; split=> [/sBAs|[/sAB| <-]]. left; case: A tub Astot sBAs sAB => A Atot /= tub Astot sBAs sAB. apply: exist_congr; rewrite predeqE => r; split=> [Br|/sAB] //. by have /sBAs [|ser] // := Br; rewrite -ser in Br. Qed. Definition premaximal T (R : T -> T -> Prop) (t : T) := forall s, R t s -> R s t. Lemma ZL_preorder T (t0 : T) (R : T -> T -> Prop) : (forall t, R t t) -> (forall r s t, R r s -> R s t -> R r t) -> (forall A : set T, total_on A R -> exists t, forall s, A s -> R s t) -> exists t, premaximal R t. Proof. move=> Rrefl Rtrans tot_max. set eqR := fun s t => R s t /\ R t s; set ceqR := fun s => [set t | eqR s t]. have eqR_trans r s t : eqR r s -> eqR s t -> eqR r t. by move=> [Rrs Rsr] [Rst Rts]; split; [apply: Rtrans Rst|apply: Rtrans Rsr]. have ceqR_uniq s t : eqR s t -> ceqR s = ceqR t. by rewrite predeqE => - [Rst Rts] r; split=> [[Rr rR] | [Rr rR]]; split; try exact: Rtrans Rr; exact: Rtrans rR _. set ceqRs := ceqR @` setT; set quotR := sig ceqRs. have ceqRP t : ceqRs (ceqR t) by exists t. set lift := fun t => exist _ (ceqR t) (ceqRP t). have lift_surj (A : quotR) : exists t : T, lift t = A. case: A => A [t Tt ctA]; exists t; rewrite /lift; case : _ / ctA. exact/congr1/Prop_irrelevance. have lift_inj s t : eqR s t -> lift s = lift t. by move=> eqRst; apply/exist_congr/ceqR_uniq. have lift_eqR s t : lift s = lift t -> eqR s t. move=> cst; have ceqst : ceqR s = ceqR t by have := congr1 sval cst. by rewrite [_ s]ceqst; split; apply: Rrefl. set repr := fun A : quotR => xget t0 [set t : T | lift t = A]. have repr_liftE t : eqR t (repr (lift t)) by apply: lift_eqR; have -> := xgetPex t0 (lift_surj (lift t)). set R' := fun A B : quotR => R (repr A) (repr B). have R'refl A : R' A A by apply: Rrefl. have R'trans A B C : R' A B -> R' B C -> R' A C by apply: Rtrans. have R'antisym A B : R' A B -> R' B A -> A = B. move=> RAB RBA; have [t tA] := lift_surj A; have [s sB] := lift_surj B. rewrite -tA -sB; apply: lift_inj; apply (eqR_trans _ _ _ (repr_liftE t)). have eAB : eqR (repr A) (repr B) by []. rewrite tA; apply: eqR_trans eAB _; rewrite -sB. by have [] := repr_liftE s. have [A Atot|A Amax] := Zorn R'refl R'trans R'antisym. have /tot_max [t tmax] : total_on [set repr B | B in A] R. by move=> ?? [B AB <-] [C AC <-]; apply: Atot. exists (lift t) => B AB; have [Rt _] := repr_liftE t. by apply: Rtrans Rt; apply: tmax; exists B. exists (repr A) => t RAt. have /Amax <- : R' A (lift t). by have [Rt _] := repr_liftE t; apply: Rtrans Rt. by have [] := repr_liftE t. Qed. math-comp-hierarchy-builder-4d8a939/examples_stdlib/demo2/stage10.v000066400000000000000000000165131521677141400252040ustar00rootroot00000000000000From Coq Require Import ssreflect ssrfun ssrbool ZArith QArith Qcanon. From HB Require Import structures. Require Import classical. Declare Scope hb_scope. Delimit Scope hb_scope with G. Local Open Scope classical_set_scope. Local Open Scope hb_scope. Module Stage10. HB.mixin Record AddAG_of_TYPE A := { zero : A; add : A -> A -> A; opp : A -> A; addrA : associative add; addrC : commutative add; add0r : left_id zero add; addNr : left_inverse zero opp add; }. HB.structure Definition AddAG := { A of AddAG_of_TYPE A }. Notation "0" := zero : hb_scope. Infix "+" := (@add _) : hb_scope. Notation "- x" := (@opp _ x) : hb_scope. Notation "x - y" := (x + - y) : hb_scope. (* Theory *) Section AddAGTheory. Variable A : AddAG.type. Implicit Type (x : A). Lemma addr0 : right_id (@zero A) add. Proof. by move=> x; rewrite addrC add0r. Qed. Lemma addrN : right_inverse (@zero A) opp add. Proof. by move=> x; rewrite addrC addNr. Qed. Lemma subrr x : x - x = 0. Proof. by rewrite addrN. Qed. Lemma addrK : right_loop (@opp A) (@add A). Proof. by move=> x y; rewrite -addrA subrr addr0. Qed. Lemma addKr : left_loop (@opp A) (@add A). Proof. by move=> x y; rewrite addrA addNr add0r. Qed. Lemma addrNK : rev_right_loop (@opp A) (@add A). Proof. by move=> y x; rewrite -addrA addNr addr0. Qed. Lemma addNKr : rev_left_loop (@opp A) (@add A). Proof. by move=> x y; rewrite addrA subrr add0r. Qed. Lemma addrAC : right_commutative (@add A). Proof. by move=> x y z; rewrite -!addrA [y + z]addrC. Qed. Lemma addrCA : left_commutative (@add A). Proof. by move=> x y z; rewrite !addrA [x + y]addrC. Qed. Lemma addrACA : interchange (@add A) add. Proof. by move=> x y z t; rewrite !addrA [x + y + z]addrAC. Qed. Lemma opprK : involutive (@opp A). Proof. by move=> x; apply: (can_inj (addrK (- x))); rewrite addNr addrN. Qed. Lemma opprD x y : - (x + y) = - x - y. Proof. apply: (can_inj (addKr (x + y))). by rewrite subrr addrACA !subrr addr0. Qed. Lemma opprB x y : - (x - y) = y - x. Proof. by rewrite opprD opprK addrC. Qed. End AddAGTheory. HB.mixin Record Ring_of_AddAG A & AddAG A := { one : A; mul : A -> A -> A; mulrA : associative mul; mulr1 : left_id one mul; mul1r : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; }. HB.factory Record Ring_of_TYPE A := { zero : A; one : A; add : A -> A -> A; opp : A -> A; mul : A -> A -> A; addrA : associative add; addrC : commutative add; add0r : left_id zero add; addNr : left_inverse zero opp add; mulrA : associative mul; mul1r : left_id one mul; mulr1 : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; }. HB.builders Context A (a : Ring_of_TYPE A). HB.instance Definition to_AddAG_of_TYPE := AddAG_of_TYPE.Build A _ _ _ addrA addrC add0r addNr. HB.instance Definition to_Ring_of_AddAG := Ring_of_AddAG.Build A _ _ mulrA mul1r mulr1 mulrDl mulrDr. HB.end. HB.structure Definition Ring := { A of Ring_of_TYPE A }. Notation "1" := one : hb_scope. Infix "*" := (@mul _) : hb_scope. HB.mixin Record Topological T := { open : (T -> Prop) -> Prop; open_setT : open setT; open_bigcup : forall {I} (D : set I) (F : I -> set T), (forall i, D i -> open (F i)) -> open (\bigcup_(i in D) F i); open_setI : forall X Y : set T, open X -> open Y -> open (setI X Y); }. HB.structure Definition TopologicalSpace := { A of Topological A }. #[export] Hint Extern 0 (open setT) => now apply: open_setT : core. HB.factory Record TopologicalBase T := { open_base : set (set T); open_base_covers : setT `<=` \bigcup_(X in open_base) X; open_base_cup : forall X Y : set T, open_base X -> open_base Y -> forall z, (X `&` Y) z -> exists2 Z, open_base Z & Z z /\ Z `<=` X `&` Y }. HB.builders Context T (a : TopologicalBase T). Definition open_of : (T -> Prop) -> Prop := [set A | exists2 D, D `<=` open_base & A = \bigcup_(X in D) X]. Lemma open_of_setT : open_of setT. Proof. exists open_base; rewrite // predeqE => x; split=> // _. by apply: open_base_covers. Qed. Lemma open_of_bigcup {I} (D : set I) (F : I -> set T) : (forall i, D i -> open_of (F i)) -> open_of (\bigcup_(i in D) F i). Proof. Admitted. Lemma open_of_cap X Y : open_of X -> open_of Y -> open_of (X `&` Y). Proof. Admitted. HB.instance Definition to_Topological := Topological.Build T _ open_of_setT (@open_of_bigcup) open_of_cap. HB.end. Section ProductTopology. Variables (T1 T2 : TopologicalSpace.type). Definition prod_open_base := [set A | exists (A1 : set T1) (A2 : set T2), open A1 /\ open A2 /\ A = setM A1 A2]. Lemma prod_open_base_covers : setT `<=` \bigcup_(X in prod_open_base) X. Proof. move=> X _; exists setT => //; exists setT, setT; do ?split. - exact: open_setT. - exact: open_setT. - by rewrite predeqE. Qed. Lemma prod_open_base_setU X Y : prod_open_base X -> prod_open_base Y -> forall z, (X `&` Y) z -> exists2 Z, prod_open_base Z & Z z /\ Z `<=` X `&` Y. Proof. move=> [A1 [A2 [A1open [A2open ->]]]] [B1 [B2 [B1open [B2open ->]]]]. move=> [z1 z2] [[/=Az1 Az2] [/= Bz1 Bz2]]. exists ((A1 `&` B1) `*` (A2 `&` B2)). by eexists _, _; do ?[split; last first]; apply: open_setI. by split => // [[x1 x2] [[/=Ax1 Bx1] [/=Ax2 Bx2]]]. Qed. HB.instance Definition prod_topology := TopologicalBase.Build (T1 * T2)%type _ prod_open_base_covers prod_open_base_setU. End ProductTopology. Definition continuous {T T' : TopologicalSpace.type} (f : T -> T') := forall B : set T', open B -> open (f@^-1` B). Definition continuous2 {T T' T'': TopologicalSpace.type} (f : T -> T' -> T'') := continuous (fun xy => f xy.1 xy.2). HB.mixin Record JoinTAddAG T & AddAG_of_TYPE T & Topological T := { add_continuous : continuous2 (add : T -> T -> T); opp_continuous : continuous (opp : T -> T) }. HB.structure Definition TAddAG := { A of Topological A & AddAG_of_TYPE A & JoinTAddAG A }. (* Instance *) HB.instance Definition Z_ring_axioms := Ring_of_TYPE.Build Z 0%Z 1%Z Z.add Z.opp Z.mul Z.add_assoc Z.add_comm Z.add_0_l Z.add_opp_diag_l Z.mul_assoc Z.mul_1_l Z.mul_1_r Z.mul_add_distr_r Z.mul_add_distr_l. Example test1 (m n : Z) : (m + n) - n + 0 = m. Proof. by rewrite addrK addr0. Qed. Import Qcanon. Search _ Qc "plus" "opp". Lemma Qcplus_opp_l q : - q + q = 0. Proof. by rewrite Qcplus_comm Qcplus_opp_r. Qed. HB.instance Definition Qc_ring_axioms := Ring_of_TYPE.Build Qc 0%Qc 1%Qc Qcplus Qcopp Qcmult Qcplus_assoc Qcplus_comm Qcplus_0_l Qcplus_opp_l Qcmult_assoc Qcmult_1_l Qcmult_1_r Qcmult_plus_distr_l Qcmult_plus_distr_r. Obligation Tactic := idtac. Definition Qcopen_base : set (set Qc) := [set A | exists a b : Qc, forall z, A z <-> a < z /\ z < b]. Program Definition QcTopological := TopologicalBase.Build Qc Qcopen_base _ _. Next Obligation. move=> x _; exists [set y | x - 1 < y < x + 1]. by exists (x - 1), (x + 1). split; rewrite Qclt_minus_iff. by rewrite -[_ + _]/(x - (x - 1))%G opprB addrCA subrr. by rewrite -[_ + _]/(x + 1 - x)%G addrAC subrr. Qed. Next Obligation. move=> X Y [aX [bX Xeq]] [aY [bY Yeq]] z [/Xeq [aXz zbX] /Yeq [aYz zbY]]. Admitted. HB.instance Definition _ : TopologicalBase Qc := QcTopological. Program Definition QcJoinTAddAG := JoinTAddAG.Build Qc _ _. Next Obligation. Admitted. Next Obligation. Admitted. HB.instance Definition _ : JoinTAddAG Qc := QcJoinTAddAG. End Stage10. math-comp-hierarchy-builder-4d8a939/examples_stdlib/demo2/stage11.v000066400000000000000000000300611521677141400251770ustar00rootroot00000000000000From Coq Require Import ssreflect ssrfun ssrbool ZArith QArith Qcanon. From HB Require Import structures. Require Import classical. Declare Scope hb_scope. Delimit Scope hb_scope with G. Local Open Scope classical_set_scope. Local Open Scope hb_scope. Module Stage11. HB.mixin Record AddAG_of_TYPE A := { zero : A; add : A -> A -> A; opp : A -> A; addrA : associative add; addrC : commutative add; add0r : left_id zero add; addNr : left_inverse zero opp add; }. HB.structure Definition AddAG := { A of AddAG_of_TYPE A }. (* TODO: command hb.module_export which creates a module, exports it immediatly and remembers that it should be added to the final Theory module created at file closure *) Notation "0" := zero : hb_scope. Infix "+" := (@add _) : hb_scope. Notation "- x" := (@opp _ x) : hb_scope. Notation "x - y" := (x + - y) : hb_scope. (* Theory *) Section AddAGTheory. Variable A : AddAG.type. Implicit Type (x : A). Lemma addr0 : right_id (@zero A) add. Proof. by move=> x; rewrite addrC add0r. Qed. Lemma addrN : right_inverse (@zero A) opp add. Proof. by move=> x; rewrite addrC addNr. Qed. Lemma subrr x : x - x = 0. Proof. by rewrite addrN. Qed. Lemma addrK : right_loop (@opp A) (@add A). Proof. by move=> x y; rewrite -addrA subrr addr0. Qed. Lemma addKr : left_loop (@opp A) (@add A). Proof. by move=> x y; rewrite addrA addNr add0r. Qed. Lemma addrNK : rev_right_loop (@opp A) (@add A). Proof. by move=> y x; rewrite -addrA addNr addr0. Qed. Lemma addNKr : rev_left_loop (@opp A) (@add A). Proof. by move=> x y; rewrite addrA subrr add0r. Qed. Lemma addrAC : right_commutative (@add A). Proof. by move=> x y z; rewrite -!addrA [y + z]addrC. Qed. Lemma addrCA : left_commutative (@add A). Proof. by move=> x y z; rewrite !addrA [x + y]addrC. Qed. Lemma addrACA : interchange (@add A) add. Proof. by move=> x y z t; rewrite !addrA [x + y + z]addrAC. Qed. Lemma opprK : involutive (@opp A). Proof. by move=> x; apply: (can_inj (addrK (- x))); rewrite addNr addrN. Qed. Lemma opprD x y : - (x + y) = - x - y. Proof. apply: (can_inj (addKr (x + y))). by rewrite subrr addrACA !subrr addr0. Qed. Lemma opprB x y : - (x - y) = y - x. Proof. by rewrite opprD opprK addrC. Qed. End AddAGTheory. HB.mixin Record Ring_of_AddAG A & AddAG A := { one : A; mul : A -> A -> A; mulrA : associative mul; mulr1 : left_id one mul; mul1r : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; }. HB.factory Record Ring_of_TYPE A := { zero : A; one : A; add : A -> A -> A; opp : A -> A; mul : A -> A -> A; addrA : associative add; addrC : commutative add; add0r : left_id zero add; addNr : left_inverse zero opp add; mulrA : associative mul; mul1r : left_id one mul; mulr1 : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; }. HB.builders Context A (a : Ring_of_TYPE A). HB.instance Definition to_AddAG := AddAG_of_TYPE.Build A _ _ _ addrA addrC add0r addNr. HB.instance Definition to_Ring := Ring_of_AddAG.Build A _ _ mulrA mul1r mulr1 mulrDl mulrDr. HB.end. HB.structure Definition Ring := { A of Ring_of_TYPE A }. Notation "1" := one : hb_scope. Infix "*" := (@mul _) : hb_scope. HB.mixin Record Topological T := { open : (T -> Prop) -> Prop; open_setT : open setT; open_bigcup : forall {I} (D : set I) (F : I -> set T), (forall i, D i -> open (F i)) -> open (\bigcup_(i in D) F i); open_setI : forall X Y : set T, open X -> open Y -> open (setI X Y); }. HB.structure Definition TopologicalSpace := { A of Topological A }. #[export] Hint Extern 0 (open setT) => now apply: open_setT : core. HB.factory Record TopologicalBase T := { open_base : set (set T); open_base_covers : setT `<=` \bigcup_(X in open_base) X; open_base_cup : forall X Y : set T, open_base X -> open_base Y -> forall z, (X `&` Y) z -> exists2 Z, open_base Z & Z z /\ Z `<=` X `&` Y }. HB.builders Context T (a : TopologicalBase T). Definition open_of := [set A | exists2 D, D `<=` open_base & A = \bigcup_(X in D) X]. Lemma open_of_setT : open_of setT. Proof. exists open_base; rewrite // predeqE => x; split=> // _. by apply: open_base_covers. Qed. Lemma open_of_bigcup {I} (D : set I) (F : I -> set T) : (forall i, D i -> open_of (F i)) -> open_of (\bigcup_(i in D) F i). Proof. Admitted. Lemma open_of_cap X Y : open_of X -> open_of Y -> open_of (X `&` Y). Proof. Admitted. HB.instance Definition to_Topological := Topological.Build T _ open_of_setT (@open_of_bigcup) open_of_cap. HB.end. Section ProductTopology. Variables (T1 T2 : TopologicalSpace.type). Definition prod_open_base := [set A | exists (A1 : set T1) (A2 : set T2), open A1 /\ open A2 /\ A = setM A1 A2]. Lemma prod_open_base_covers : setT `<=` \bigcup_(X in prod_open_base) X. Proof. move=> X _; exists setT => //; exists setT, setT; do ?split. - exact: open_setT. - exact: open_setT. - by rewrite predeqE. Qed. Lemma prod_open_base_setU X Y : prod_open_base X -> prod_open_base Y -> forall z, (X `&` Y) z -> exists2 Z, prod_open_base Z & Z z /\ Z `<=` X `&` Y. Proof. move=> [A1 [A2 [A1open [A2open ->]]]] [B1 [B2 [B1open [B2open ->]]]]. move=> [z1 z2] [[/=Az1 Az2] [/= Bz1 Bz2]]. exists ((A1 `&` B1) `*` (A2 `&` B2)). by eexists _, _; do ?[split; last first]; apply: open_setI. by split => // [[x1 x2] [[/=Ax1 Bx1] [/=Ax2 Bx2]]]. Qed. HB.instance Definition prod_topology := TopologicalBase.Build (T1 * T2)%type _ prod_open_base_covers prod_open_base_setU. End ProductTopology. (* TODO: infer continuous as a morphism of Topology *) Definition continuous {T T' : TopologicalSpace.type} (f : T -> T') := forall B : set T', open B -> open (f@^-1` B). Definition continuous2 {T T' T'': TopologicalSpace.type} (f : T -> T' -> T'') := continuous (fun xy => f xy.1 xy.2). HB.mixin Record JoinTAddAG_wo_Uniform T & AddAG_of_TYPE T & Topological T := { add_continuous : continuous2 (add : T -> T -> T); opp_continuous : continuous (opp : T -> T) }. HB.structure Definition TAddAG_wo_Uniform := { A of Topological A & AddAG_of_TYPE A & JoinTAddAG_wo_Uniform A }. HB.mixin Record Uniform_wo_Topology U := { entourage : set (set (U * U)) ; filter_entourage : is_filter entourage ; entourage_sub : forall A, entourage A -> [set xy | xy.1 = xy.2] `<=` A; entourage_sym : forall A, entourage A -> entourage (graph_sym A) ; entourage_split : forall A, entourage A -> exists2 B, entourage B & graph_comp B B `<=` A ; }. HB.structure Definition UniformSpace_wo_Topology := { A of Uniform_wo_Topology A }. (* TODO: have a command hb.typealias which register "typealias factories" which turn a typealias into factories *) Definition uniform T : Type := T. Section Uniform_Topology. Variable U : UniformSpace_wo_Topology.type. Definition uniform_open : set (set (uniform U)). Admitted. Lemma uniform_open_setT : uniform_open setT. Admitted. Lemma uniform_open_bigcup : forall {I} (D : set I) (F : I -> set U), (forall i, D i -> uniform_open (F i)) -> uniform_open (\bigcup_(i in D) F i). Admitted. Lemma uniform_open_setI : forall X Y : set U, uniform_open X -> uniform_open Y -> uniform_open (setI X Y). Admitted. HB.instance Definition uniform_topology := Topological.Build (uniform U) _ uniform_open_setT (@uniform_open_bigcup) uniform_open_setI. End Uniform_Topology. HB.mixin Record Join_Uniform_Topology U & Topological U & Uniform_wo_Topology U := { openE : open = (uniform_open _ : set (set (uniform U))) }. (* TODO: this factory should be replaced by type alias uniform *) HB.factory Record Uniform_Topology U & Uniform_wo_Topology U := { }. HB.builders Context U (f : Uniform_Topology U). HB.instance Definition to_Topological : Topological U := (uniform_topology _). HB.end. HB.structure Definition UniformSpace := { A of Uniform_Topology A (* should be replaced by typealias uniform *) & Uniform_wo_Topology A }. (* TODO: should be ommited *) (* TODO: this is another typealias *) Definition tAddAG (T : Type) := T. Section TAddAGUniform. Variable T : TAddAG_wo_Uniform.type. Notation TT := (tAddAG T). Definition TAddAG_entourage : set (set (TT * TT)). Admitted. Lemma filter_TAddAG_entourage : is_filter TAddAG_entourage. Admitted. Lemma TAddAG_entourage_sub : forall A, TAddAG_entourage A -> [set xy | xy.1 = xy.2] `<=` A. Admitted. Lemma TAddAG_entourage_sym : forall A, TAddAG_entourage A -> TAddAG_entourage (graph_sym A). Admitted. Lemma TAddAG_entourage_split : forall A, TAddAG_entourage A -> exists2 B, TAddAG_entourage B & graph_comp B B `<=` A. Admitted. HB.instance Definition TAddAG_uniform := Uniform_wo_Topology.Build (tAddAG T) _ filter_TAddAG_entourage TAddAG_entourage_sub TAddAG_entourage_sym TAddAG_entourage_split. Lemma TAddAG_uniform_topologyE : open = (uniform_open _ : set (set (uniform TT))). Admitted. HB.instance Definition TAddAG_Join_Uniform_Topology := Join_Uniform_Topology.Build TT TAddAG_uniform_topologyE. Lemma TAddAG_entourageE : entourage = (TAddAG_entourage : set (set (TT * TT))). Admitted. End TAddAGUniform. HB.structure Definition Uniform_TAddAG_unjoined := { A of TAddAG_wo_Uniform A & Uniform_wo_Topology A }. (* should be created automatically *) HB.mixin Record Join_TAddAG_Uniform T & Uniform_TAddAG_unjoined T := { entourageE : entourage = (TAddAG_entourage _ : set (set (tAddAG T * tAddAG T))) }. (* TODO: should be subsumed by the type alias TAddAG *) HB.factory Record TAddAG_Uniform U & TAddAG_wo_Uniform U := { }. HB.builders Context U (a : TAddAG_Uniform U). HB.instance Definition to_Uniform_wo_Topology : Uniform_wo_Topology U := TAddAG_uniform _. HB.instance Definition to_Join_Uniform_Topology : Join_Uniform_Topology U := TAddAG_Join_Uniform_Topology _. HB.instance Definition to_Join_TAddAG_Uniform : Join_TAddAG_Uniform U := Join_TAddAG_Uniform.Build U (TAddAG_entourageE _). HB.end. HB.structure Definition TAddAG := { A of TAddAG_Uniform A (* TODO: should be replaced by type alias TAddAG *) & TAddAG_wo_Uniform A }. (* TODO: should be omitted *) HB.factory Definition JoinTAddAG T & AddAG_of_TYPE T & Topological T := (JoinTAddAG_wo_Uniform T). HB.builders Context T (a : JoinTAddAG T). HB.instance Definition to_JoinTAddAG_wo_Uniform : JoinTAddAG_wo_Uniform T := a. (* TODO: Nice error message when factory builders do not depend on the source factory 'a'*) HB.instance Definition to_Uniform : TAddAG_Uniform T := let _ : JoinTAddAG T := a in TAddAG_Uniform.Build T. HB.end. (* Instance *) HB.instance Definition Z_ring_axioms := Ring_of_TYPE.Build Z 0%Z 1%Z Z.add Z.opp Z.mul Z.add_assoc Z.add_comm Z.add_0_l Z.add_opp_diag_l Z.mul_assoc Z.mul_1_l Z.mul_1_r Z.mul_add_distr_r Z.mul_add_distr_l. Example test1 (m n : Z) : (m + n) - n + 0 = m. Proof. by rewrite addrK addr0. Qed. Import Qcanon. Lemma Qcplus_opp_l q : - q + q = 0. Proof. by rewrite Qcplus_comm Qcplus_opp_r. Qed. HB.instance Definition Qc_ring_axioms := Ring_of_TYPE.Build Qc 0%Qc 1%Qc Qcplus Qcopp Qcmult Qcplus_assoc Qcplus_comm Qcplus_0_l Qcplus_opp_l Qcmult_assoc Qcmult_1_l Qcmult_1_r Qcmult_plus_distr_l Qcmult_plus_distr_r. Obligation Tactic := idtac. Definition Qcopen_base : set (set Qc) := [set A | exists a b : Qc, forall z, A z <-> a < z /\ z < b]. Program Definition QcTopological := TopologicalBase.Build Qc Qcopen_base _ _. Next Obligation. move=> x _; exists [set y | x - 1 < y < x + 1]. by exists (x - 1), (x + 1). split; rewrite Qclt_minus_iff. by rewrite -[_ + _]/(x - (x - 1))%G opprB addrCA subrr. by rewrite -[_ + _]/(x + 1 - x)%G addrAC subrr. Qed. Next Obligation. move=> X Y [aX [bX Xeq]] [aY [bY Yeq]] z [/Xeq [aXz zbX] /Yeq [aYz zbY]]. Admitted. HB.instance Definition _ : TopologicalBase Qc := QcTopological. Program Definition QcJoinTAddAG := JoinTAddAG.Build Qc _ _. Next Obligation. Admitted. Next Obligation. Admitted. #[verbose] HB.instance Definition _ : JoinTAddAG Qc := QcJoinTAddAG. Check (entourage : set (set (Qc * Qc))). (* TODO fix spill-factory-param-factories *) End Stage11. math-comp-hierarchy-builder-4d8a939/rocq-hierarchy-builder.opam000066400000000000000000000024001521677141400245740ustar00rootroot00000000000000opam-version: "2.0" name: "coq-hierarchy-builder" version: "dev" maintainer: "Enrico Tassi " authors: [ "Cyril Cohen" "Kazuhiko Sakaguchi" "Enrico Tassi" ] license: "MIT" homepage: "https://github.com/math-comp/hierarchy-builder" bug-reports: "https://github.com/math-comp/hierarchy-builder/issues" dev-repo: "git+https://github.com/math-comp/hierarchy-builder" build: [ [ make "build"] [ make "test-suite" ] {with-test & rocq-core:installed} ] install: [ make "install" ] depends: [ "rocq-core" {(>= "9.0" & < "9.3~") | = "dev"} & "rocq-elpi" {>= "3" | = "dev"} ] conflicts: [ "coq-hierarchy-builder" {< "1.9~"} "coq-hierarchy-builder-shim" ] depexts: [ [ "wdiff" ] {os-family = "debian" & with-test} ] synopsis: "High level commands to declare and evolve a hierarchy based on packed classes" description: """ Hierarchy Builder is a high level language to build hierarchies of algebraic structures and make these hierarchies evolve without breaking user code. The key concepts are the ones of factory, builder and abbreviation that let the hierarchy developer describe an actual interface for their library. Behind that interface the developer can provide appropriate code to ensure retro compatibility. """ tags: [ "logpath:HB" ] math-comp-hierarchy-builder-4d8a939/shim/000077500000000000000000000000001521677141400203165ustar00rootroot00000000000000math-comp-hierarchy-builder-4d8a939/shim/Makefile000066400000000000000000000003051521677141400217540ustar00rootroot00000000000000COQMAKEFILE?=$(COQBIN)coq_makefile build: $(COQMAKEFILE) -f _CoqProject -o Makefile.coq $(MAKE) -f Makefile.coq install: $(MAKE) -f Makefile.coq install clean: $(MAKE) -f Makefile.coq clean math-comp-hierarchy-builder-4d8a939/shim/_CoqProject000066400000000000000000000000251521677141400224460ustar00rootroot00000000000000-R . HB structures.vmath-comp-hierarchy-builder-4d8a939/shim/structures.v000066400000000000000000000007041521677141400227310ustar00rootroot00000000000000From Coq Require Import String ssreflect ssrfun. Export String.StringSyntax. Variant error_msg := NoMsg | IsNotCanonicallyA (x : Type). Definition unify T1 T2 (t1 : T1) (t2 : T2) (s : error_msg) := phantom T1 t1 -> phantom T2 t2. Definition id_phant {T} {t : T} (x : phantom T t) := x. Definition nomsg : error_msg := NoMsg. Definition is_not_canonically_a x := IsNotCanonicallyA x. Definition new {T} (x : T) := x. Definition eta {T} (x : T) := x. math-comp-hierarchy-builder-4d8a939/tests/000077500000000000000000000000001521677141400205205ustar00rootroot00000000000000math-comp-hierarchy-builder-4d8a939/tests/about.v.out000066400000000000000000000130161521677141400226300ustar00rootroot00000000000000Toplevel input, character 0: > From Coq Require Import ZArith ssrfun ssreflect. > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Warning: "From Coq" has been replaced by "From Stdlib". [deprecated-from-Coq,deprecated-since-9.0,deprecated,default] HB: AddMonoid_of_TYPE is a factory (from "./examples/demo1/hierarchy_5.v", line 10) HB: AddMonoid_of_TYPE operations and axioms are: - zero - add - addrA - add0r - addr0 HB: AddMonoid_of_TYPE requires the following mixins: HB: AddMonoid_of_TYPE provides the following mixins: - AddMonoid_of_TYPE HB: AddMonoid_of_TYPE.Build is a factory constructor (from "./examples/demo1/hierarchy_5.v", line 10) HB: AddMonoid_of_TYPE.Build requires its subject to be already equipped with: HB: AddMonoid_of_TYPE.Build provides the following mixins: - AddMonoid_of_TYPE HB: arguments: AddMonoid_of_TYPE.Build S zero add addrA add0r addr0 - S : Type - zero : AddMonoid.sort S - add : S -> S -> S - addrA : associative add - add0r : left_id 0%G add - addr0 : right_id 0%G add HB: AddAG.type is a structure (from "./examples/demo1/hierarchy_5.v", line 73) HB: AddAG.type characterizing operations and axioms are: - addNr - opp HB: AddAG is a factory for the following mixins: - AddMonoid_of_TYPE - AddComoid_of_AddMonoid - AddAG_of_AddComoid (* new, not from inheritance *) HB: AddAG inherits from: - AddMonoid - AddComoid HB: AddAG is inherited by: - Ring HB: AddMonoid.type is a structure (from "./examples/demo1/hierarchy_5.v", line 17) HB: AddMonoid.type characterizing operations and axioms are: - addr0 - add0r - addrA - add - zero HB: AddMonoid is a factory for the following mixins: - AddMonoid_of_TYPE (* new, not from inheritance *) HB: AddMonoid inherits from: HB: AddMonoid is inherited by: - AddComoid - AddAG - BiNearRing - SemiRing - Ring HB: Ring_of_AddAG is a factory (from "./examples/demo1/hierarchy_5.v", line 108) HB: Ring_of_AddAG operations and axioms are: - one - mul - mulrA - mulr1 - mul1r - mulrDl - mulrDr HB: Ring_of_AddAG requires the following mixins: - AddMonoid_of_TYPE - AddComoid_of_AddMonoid - AddAG_of_AddComoid HB: Ring_of_AddAG provides the following mixins: - BiNearRing_of_AddMonoid Doc: Builds a Ring from an Abelian Group: the absorbing properties mul0r and mul0r are derived from addrC and the other ring axioms, following a proof of Hankel (Gerhard Betsch. On the beginnings and development of near-ring theory. In Near-rings and near-fields. Proceedings of the conference held in Fredericton, New Brunswick, July 18-24, 1993, pages 1–11. Mathematics and its Applications, 336. Kluwer Academic Publishers Group, Dordrecht, 1995). HB: Ring_of_AddAG.Build is a factory constructor (from "./examples/demo1/hierarchy_5.v", line 108) HB: Ring_of_AddAG.Build requires its subject to be already equipped with: - AddMonoid_of_TYPE - AddComoid_of_AddMonoid - AddAG_of_AddComoid HB: Ring_of_AddAG.Build provides the following mixins: - BiNearRing_of_AddMonoid HB: arguments: Ring_of_AddAG.Build A [one] [mul] mulrA mulr1 mul1r mulrDl mulrDr - A : Type - one : A - mul : A -> A -> A - mulrA : associative mul - mulr1 : left_id one mul - mul1r : right_id one mul - mulrDl : left_distributive mul add - mulrDr : right_distributive mul add Doc: Builds a Ring from an Abelian Group: the absorbing properties mul0r and mul0r are derived from addrC and the other ring axioms, following a proof of Hankel (Gerhard Betsch. On the beginnings and development of near-ring theory. In Near-rings and near-fields. Proceedings of the conference held in Fredericton, New Brunswick, July 18-24, 1993, pages 1–11. Mathematics and its Applications, 336. Kluwer Academic Publishers Group, Dordrecht, 1995). HB: add is an operation of structure AddMonoid (from "./examples/demo1/hierarchy_5.v", line 17) HB: add comes from mixin AddMonoid_of_TYPE (from "./examples/demo1/hierarchy_5.v", line 10) HB: AddAG.sort is a canonical projection (from "./examples/demo1/hierarchy_5.v", line 73) HB: AddAG.sort has the following canonical values: - Ring.sort (from "./examples/demo1/hierarchy_5.v", line 196) - Z HB: AddAG.sort is a coercion from AddAG to Sortclass (from "./examples/demo1/hierarchy_5.v", line 73) HB: Z is canonically equipped with structures: - AddMonoid AddComoid AddAG (from "(stdin)", line 5) - BiNearRing SemiRing Ring (from "(stdin)", line 10) HB: hierarchy_5_Ring_class__to__hierarchy_5_SemiRing_class is a coercion from Ring to SemiRing (from "./examples/demo1/hierarchy_5.v", line 196) HB: hierarchy_5_Ring__to__hierarchy_5_SemiRing is a coercion from Ring to SemiRing (from "./examples/demo1/hierarchy_5.v", line 196) Toplevel input, character 15: > HB.about Builders_40.hierarchy_5_Ring_of_AddAG__to__hierarchy_5_BiNearRing_of_AddMonoid. > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Error: HB: unable to locate Builders_40.hierarchy_5_Ring_of_AddAG__to__hierarchy_5_BiNearRing_of_AddMonoid HB: synthesized in file File "(stdin)", line 5, column 0, character 127: Interactive Module hierarchy_5 started Interactive Module AddComoid started HB: Z is canonically equipped with structures: - AddMonoid demo1.hierarchy_5.AddComoid AddAG (from "(stdin)", line 5) - BiNearRing SemiRing Ring (from "(stdin)", line 10) math-comp-hierarchy-builder-4d8a939/tests/about.v.out.18000066400000000000000000000124251521677141400230620ustar00rootroot00000000000000HB: AddMonoid_of_TYPE is a factory (from "./examples/demo1/hierarchy_5.v", line 10) HB: AddMonoid_of_TYPE operations and axioms are: - zero - add - addrA - add0r - addr0 HB: AddMonoid_of_TYPE requires the following mixins: HB: AddMonoid_of_TYPE provides the following mixins: - AddMonoid_of_TYPE HB: AddMonoid_of_TYPE.Build is a factory constructor (from "./examples/demo1/hierarchy_5.v", line 10) HB: AddMonoid_of_TYPE.Build requires its subject to be already equipped with: HB: AddMonoid_of_TYPE.Build provides the following mixins: - AddMonoid_of_TYPE HB: arguments: AddMonoid_of_TYPE.Build S zero add addrA add0r addr0 - S : Type - zero : AddMonoid.sort S - add : S -> S -> S - addrA : associative add - add0r : left_id 0%G add - addr0 : right_id 0%G add HB: AddAG.type is a structure (from "./examples/demo1/hierarchy_5.v", line 73) HB: AddAG.type characterizing operations and axioms are: - addNr - opp HB: AddAG is a factory for the following mixins: - AddMonoid_of_TYPE - AddComoid_of_AddMonoid - AddAG_of_AddComoid (* new, not from inheritance *) HB: AddAG inherits from: - AddMonoid - AddComoid HB: AddAG is inherited by: - Ring HB: AddMonoid.type is a structure (from "./examples/demo1/hierarchy_5.v", line 17) HB: AddMonoid.type characterizing operations and axioms are: - addr0 - add0r - addrA - add - zero HB: AddMonoid is a factory for the following mixins: - AddMonoid_of_TYPE (* new, not from inheritance *) HB: AddMonoid inherits from: HB: AddMonoid is inherited by: - AddComoid - AddAG - BiNearRing - SemiRing - Ring HB: Ring_of_AddAG is a factory (from "./examples/demo1/hierarchy_5.v", line 108) HB: Ring_of_AddAG operations and axioms are: - one - mul - mulrA - mulr1 - mul1r - mulrDl - mulrDr HB: Ring_of_AddAG requires the following mixins: - AddMonoid_of_TYPE - AddComoid_of_AddMonoid - AddAG_of_AddComoid HB: Ring_of_AddAG provides the following mixins: - BiNearRing_of_AddMonoid Doc: Builds a Ring from an Abelian Group: the absorbing properties mul0r and mul0r are derived from addrC and the other ring axioms, following a proof of Hankel (Gerhard Betsch. On the beginnings and development of near-ring theory. In Near-rings and near-fields. Proceedings of the conference held in Fredericton, New Brunswick, July 18-24, 1993, pages 1–11. Mathematics and its Applications, 336. Kluwer Academic Publishers Group, Dordrecht, 1995). HB: Ring_of_AddAG.Build is a factory constructor (from "./examples/demo1/hierarchy_5.v", line 108) HB: Ring_of_AddAG.Build requires its subject to be already equipped with: - AddMonoid_of_TYPE - AddComoid_of_AddMonoid - AddAG_of_AddComoid HB: Ring_of_AddAG.Build provides the following mixins: - BiNearRing_of_AddMonoid HB: arguments: Ring_of_AddAG.Build A [one] [mul] mulrA mulr1 mul1r mulrDl mulrDr - A : Type - one : A - mul : A -> A -> A - mulrA : associative mul - mulr1 : left_id one mul - mul1r : right_id one mul - mulrDl : left_distributive mul add - mulrDr : right_distributive mul add Doc: Builds a Ring from an Abelian Group: the absorbing properties mul0r and mul0r are derived from addrC and the other ring axioms, following a proof of Hankel (Gerhard Betsch. On the beginnings and development of near-ring theory. In Near-rings and near-fields. Proceedings of the conference held in Fredericton, New Brunswick, July 18-24, 1993, pages 1–11. Mathematics and its Applications, 336. Kluwer Academic Publishers Group, Dordrecht, 1995). HB: add is an operation of structure AddMonoid (from "./examples/demo1/hierarchy_5.v", line 17) HB: add comes from mixin AddMonoid_of_TYPE (from "./examples/demo1/hierarchy_5.v", line 10) HB: AddAG.sort is a canonical projection (from "./examples/demo1/hierarchy_5.v", line 73) HB: AddAG.sort has the following canonical values: - Ring.sort (from "./examples/demo1/hierarchy_5.v", line 196) - Z HB: AddAG.sort is a coercion from AddAG to Sortclass (from "./examples/demo1/hierarchy_5.v", line 73) HB: Z is canonically equipped with structures: - AddMonoid AddComoid AddAG (from "(stdin)", line 5) - BiNearRing SemiRing Ring (from "(stdin)", line 10) HB: hierarchy_5_Ring_class__to__hierarchy_5_SemiRing_class is a coercion from Ring to SemiRing (from "./examples/demo1/hierarchy_5.v", line 196) HB: hierarchy_5_Ring__to__hierarchy_5_SemiRing is a coercion from Ring to SemiRing (from "./examples/demo1/hierarchy_5.v", line 196) Toplevel input, character 15: > HB.about Builders_40.hierarchy_5_Ring_of_AddAG__to__hierarchy_5_BiNearRing_of_AddMonoid. > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Error: HB: unable to locate Builders_40.hierarchy_5_Ring_of_AddAG__to__hierarchy_5_BiNearRing_of_AddMonoid HB: synthesized in file File "(stdin)", line 5, column 0, character 127: Interactive Module hierarchy_5 started Interactive Module AddComoid started HB: Z is canonically equipped with structures: - AddMonoid demo1.hierarchy_5.AddComoid AddAG (from "(stdin)", line 5) - BiNearRing SemiRing Ring (from "(stdin)", line 10) math-comp-hierarchy-builder-4d8a939/tests/about.v.out.19000066400000000000000000000124251521677141400230630ustar00rootroot00000000000000HB: AddMonoid_of_TYPE is a factory (from "./examples/demo1/hierarchy_5.v", line 10) HB: AddMonoid_of_TYPE operations and axioms are: - zero - add - addrA - add0r - addr0 HB: AddMonoid_of_TYPE requires the following mixins: HB: AddMonoid_of_TYPE provides the following mixins: - AddMonoid_of_TYPE HB: AddMonoid_of_TYPE.Build is a factory constructor (from "./examples/demo1/hierarchy_5.v", line 10) HB: AddMonoid_of_TYPE.Build requires its subject to be already equipped with: HB: AddMonoid_of_TYPE.Build provides the following mixins: - AddMonoid_of_TYPE HB: arguments: AddMonoid_of_TYPE.Build S zero add addrA add0r addr0 - S : Type - zero : AddMonoid.sort S - add : S -> S -> S - addrA : associative add - add0r : left_id 0%G add - addr0 : right_id 0%G add HB: AddAG.type is a structure (from "./examples/demo1/hierarchy_5.v", line 73) HB: AddAG.type characterizing operations and axioms are: - addNr - opp HB: AddAG is a factory for the following mixins: - AddMonoid_of_TYPE - AddComoid_of_AddMonoid - AddAG_of_AddComoid (* new, not from inheritance *) HB: AddAG inherits from: - AddMonoid - AddComoid HB: AddAG is inherited by: - Ring HB: AddMonoid.type is a structure (from "./examples/demo1/hierarchy_5.v", line 17) HB: AddMonoid.type characterizing operations and axioms are: - addr0 - add0r - addrA - add - zero HB: AddMonoid is a factory for the following mixins: - AddMonoid_of_TYPE (* new, not from inheritance *) HB: AddMonoid inherits from: HB: AddMonoid is inherited by: - AddComoid - AddAG - BiNearRing - SemiRing - Ring HB: Ring_of_AddAG is a factory (from "./examples/demo1/hierarchy_5.v", line 108) HB: Ring_of_AddAG operations and axioms are: - one - mul - mulrA - mulr1 - mul1r - mulrDl - mulrDr HB: Ring_of_AddAG requires the following mixins: - AddMonoid_of_TYPE - AddComoid_of_AddMonoid - AddAG_of_AddComoid HB: Ring_of_AddAG provides the following mixins: - BiNearRing_of_AddMonoid Doc: Builds a Ring from an Abelian Group: the absorbing properties mul0r and mul0r are derived from addrC and the other ring axioms, following a proof of Hankel (Gerhard Betsch. On the beginnings and development of near-ring theory. In Near-rings and near-fields. Proceedings of the conference held in Fredericton, New Brunswick, July 18-24, 1993, pages 1–11. Mathematics and its Applications, 336. Kluwer Academic Publishers Group, Dordrecht, 1995). HB: Ring_of_AddAG.Build is a factory constructor (from "./examples/demo1/hierarchy_5.v", line 108) HB: Ring_of_AddAG.Build requires its subject to be already equipped with: - AddMonoid_of_TYPE - AddComoid_of_AddMonoid - AddAG_of_AddComoid HB: Ring_of_AddAG.Build provides the following mixins: - BiNearRing_of_AddMonoid HB: arguments: Ring_of_AddAG.Build A [one] [mul] mulrA mulr1 mul1r mulrDl mulrDr - A : Type - one : A - mul : A -> A -> A - mulrA : associative mul - mulr1 : left_id one mul - mul1r : right_id one mul - mulrDl : left_distributive mul add - mulrDr : right_distributive mul add Doc: Builds a Ring from an Abelian Group: the absorbing properties mul0r and mul0r are derived from addrC and the other ring axioms, following a proof of Hankel (Gerhard Betsch. On the beginnings and development of near-ring theory. In Near-rings and near-fields. Proceedings of the conference held in Fredericton, New Brunswick, July 18-24, 1993, pages 1–11. Mathematics and its Applications, 336. Kluwer Academic Publishers Group, Dordrecht, 1995). HB: add is an operation of structure AddMonoid (from "./examples/demo1/hierarchy_5.v", line 17) HB: add comes from mixin AddMonoid_of_TYPE (from "./examples/demo1/hierarchy_5.v", line 10) HB: AddAG.sort is a canonical projection (from "./examples/demo1/hierarchy_5.v", line 73) HB: AddAG.sort has the following canonical values: - Ring.sort (from "./examples/demo1/hierarchy_5.v", line 196) - Z HB: AddAG.sort is a coercion from AddAG to Sortclass (from "./examples/demo1/hierarchy_5.v", line 73) HB: Z is canonically equipped with structures: - AddMonoid AddComoid AddAG (from "(stdin)", line 5) - BiNearRing SemiRing Ring (from "(stdin)", line 10) HB: hierarchy_5_Ring_class__to__hierarchy_5_SemiRing_class is a coercion from Ring to SemiRing (from "./examples/demo1/hierarchy_5.v", line 196) HB: hierarchy_5_Ring__to__hierarchy_5_SemiRing is a coercion from Ring to SemiRing (from "./examples/demo1/hierarchy_5.v", line 196) Toplevel input, character 15: > HB.about Builders_40.hierarchy_5_Ring_of_AddAG__to__hierarchy_5_BiNearRing_of_AddMonoid. > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Error: HB: unable to locate Builders_40.hierarchy_5_Ring_of_AddAG__to__hierarchy_5_BiNearRing_of_AddMonoid HB: synthesized in file File "(stdin)", line 5, column 0, character 127: Interactive Module hierarchy_5 started Interactive Module AddComoid started HB: Z is canonically equipped with structures: - AddMonoid demo1.hierarchy_5.AddComoid AddAG (from "(stdin)", line 5) - BiNearRing SemiRing Ring (from "(stdin)", line 10) math-comp-hierarchy-builder-4d8a939/tests/about.v.out.20000066400000000000000000000124251521677141400230530ustar00rootroot00000000000000HB: AddMonoid_of_TYPE is a factory (from "./examples/demo1/hierarchy_5.v", line 10) HB: AddMonoid_of_TYPE operations and axioms are: - zero - add - addrA - add0r - addr0 HB: AddMonoid_of_TYPE requires the following mixins: HB: AddMonoid_of_TYPE provides the following mixins: - AddMonoid_of_TYPE HB: AddMonoid_of_TYPE.Build is a factory constructor (from "./examples/demo1/hierarchy_5.v", line 10) HB: AddMonoid_of_TYPE.Build requires its subject to be already equipped with: HB: AddMonoid_of_TYPE.Build provides the following mixins: - AddMonoid_of_TYPE HB: arguments: AddMonoid_of_TYPE.Build S zero add addrA add0r addr0 - S : Type - zero : AddMonoid.sort S - add : S -> S -> S - addrA : associative add - add0r : left_id 0%G add - addr0 : right_id 0%G add HB: AddAG.type is a structure (from "./examples/demo1/hierarchy_5.v", line 73) HB: AddAG.type characterizing operations and axioms are: - addNr - opp HB: AddAG is a factory for the following mixins: - AddMonoid_of_TYPE - AddComoid_of_AddMonoid - AddAG_of_AddComoid (* new, not from inheritance *) HB: AddAG inherits from: - AddMonoid - AddComoid HB: AddAG is inherited by: - Ring HB: AddMonoid.type is a structure (from "./examples/demo1/hierarchy_5.v", line 17) HB: AddMonoid.type characterizing operations and axioms are: - addr0 - add0r - addrA - add - zero HB: AddMonoid is a factory for the following mixins: - AddMonoid_of_TYPE (* new, not from inheritance *) HB: AddMonoid inherits from: HB: AddMonoid is inherited by: - AddComoid - AddAG - BiNearRing - SemiRing - Ring HB: Ring_of_AddAG is a factory (from "./examples/demo1/hierarchy_5.v", line 108) HB: Ring_of_AddAG operations and axioms are: - one - mul - mulrA - mulr1 - mul1r - mulrDl - mulrDr HB: Ring_of_AddAG requires the following mixins: - AddMonoid_of_TYPE - AddComoid_of_AddMonoid - AddAG_of_AddComoid HB: Ring_of_AddAG provides the following mixins: - BiNearRing_of_AddMonoid Doc: Builds a Ring from an Abelian Group: the absorbing properties mul0r and mul0r are derived from addrC and the other ring axioms, following a proof of Hankel (Gerhard Betsch. On the beginnings and development of near-ring theory. In Near-rings and near-fields. Proceedings of the conference held in Fredericton, New Brunswick, July 18-24, 1993, pages 1–11. Mathematics and its Applications, 336. Kluwer Academic Publishers Group, Dordrecht, 1995). HB: Ring_of_AddAG.Build is a factory constructor (from "./examples/demo1/hierarchy_5.v", line 108) HB: Ring_of_AddAG.Build requires its subject to be already equipped with: - AddMonoid_of_TYPE - AddComoid_of_AddMonoid - AddAG_of_AddComoid HB: Ring_of_AddAG.Build provides the following mixins: - BiNearRing_of_AddMonoid HB: arguments: Ring_of_AddAG.Build A [one] [mul] mulrA mulr1 mul1r mulrDl mulrDr - A : Type - one : A - mul : A -> A -> A - mulrA : associative mul - mulr1 : left_id one mul - mul1r : right_id one mul - mulrDl : left_distributive mul add - mulrDr : right_distributive mul add Doc: Builds a Ring from an Abelian Group: the absorbing properties mul0r and mul0r are derived from addrC and the other ring axioms, following a proof of Hankel (Gerhard Betsch. On the beginnings and development of near-ring theory. In Near-rings and near-fields. Proceedings of the conference held in Fredericton, New Brunswick, July 18-24, 1993, pages 1–11. Mathematics and its Applications, 336. Kluwer Academic Publishers Group, Dordrecht, 1995). HB: add is an operation of structure AddMonoid (from "./examples/demo1/hierarchy_5.v", line 17) HB: add comes from mixin AddMonoid_of_TYPE (from "./examples/demo1/hierarchy_5.v", line 10) HB: AddAG.sort is a canonical projection (from "./examples/demo1/hierarchy_5.v", line 73) HB: AddAG.sort has the following canonical values: - Ring.sort (from "./examples/demo1/hierarchy_5.v", line 196) - Z HB: AddAG.sort is a coercion from AddAG to Sortclass (from "./examples/demo1/hierarchy_5.v", line 73) HB: Z is canonically equipped with structures: - AddMonoid AddComoid AddAG (from "(stdin)", line 5) - BiNearRing SemiRing Ring (from "(stdin)", line 10) HB: hierarchy_5_Ring_class__to__hierarchy_5_SemiRing_class is a coercion from Ring to SemiRing (from "./examples/demo1/hierarchy_5.v", line 196) HB: hierarchy_5_Ring__to__hierarchy_5_SemiRing is a coercion from Ring to SemiRing (from "./examples/demo1/hierarchy_5.v", line 196) Toplevel input, character 15: > HB.about Builders_40.hierarchy_5_Ring_of_AddAG__to__hierarchy_5_BiNearRing_of_AddMonoid. > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Error: HB: unable to locate Builders_40.hierarchy_5_Ring_of_AddAG__to__hierarchy_5_BiNearRing_of_AddMonoid HB: synthesized in file File "(stdin)", line 5, column 0, character 127: Interactive Module hierarchy_5 started Interactive Module AddComoid started HB: Z is canonically equipped with structures: - AddMonoid demo1.hierarchy_5.AddComoid AddAG (from "(stdin)", line 5) - BiNearRing SemiRing Ring (from "(stdin)", line 10) math-comp-hierarchy-builder-4d8a939/tests/bug_435.v000066400000000000000000000015161521677141400220620ustar00rootroot00000000000000From HB Require Import structures. HB.mixin Record M T := { m : bool }. HB.structure Definition S := {T of M T}. HB.mixin Record A1 X T := { a1 : bool }. HB.structure Definition B1 X := {T of A1 X T}. HB.instance Definition _ (X : Type) := A1.Build X unit true. HB.mixin Record A2 (X : Type) T := { a2 : bool }. HB.structure Definition B2 (X : Type) := {T of A2 X T}. (* This should work but fails. *) Module should_work_but_fails. HB.structure Definition B (X : S.type) := {T of A1 X T & A2 X T}. #[verbose] HB.instance Definition _ (X : Type) := A2.Build X unit true. HB.saturate unit. Check unit : B.type _. End should_work_but_fails. Module workaround. HB.instance Definition _ (X : Type) := A2.Build X unit true. HB.structure Definition B (X : S.type) := {T of A1 X T & A2 X T}. HB.saturate unit. Check unit : B.type _. End workaround.math-comp-hierarchy-builder-4d8a939/tests/bug_447.v000066400000000000000000000016061521677141400220650ustar00rootroot00000000000000From HB Require Import structures. Variant testTy := A | B. HB.mixin Record Stack1 T := { prop1 : unit }. HB.structure Definition JustStack1 := { T of Stack1 T }. HB.mixin Record Stack1Param R T := { prop2 : unit }. HB.structure Definition JustStack1Param R := { T of Stack1Param R T }. HB.mixin Record Stack2 T := { prop3 : unit }. HB.structure Definition JustStack2 := { T of Stack2 T }. HB.mixin Record Mixed T & Stack1 T & Stack2 T := { prop4 : unit }. HB.structure Definition JustMixed := { T of Mixed T & Stack1 T & Stack2 T}. HB.structure Definition JustMixedParam R := { T of Mixed T & Stack1 T & Stack1Param R T & Stack2 T}. HB.instance Definition _ := @Stack1.Build testTy tt. HB.instance Definition _ := @Stack2.Build testTy tt. HB.instance Definition _ {R} := @Stack1Param.Build R testTy tt. HB.instance Definition _ := @Mixed.Build testTy tt. Check testTy : JustMixedParam.type _. math-comp-hierarchy-builder-4d8a939/tests/class_for.v000066400000000000000000000015371521677141400226700ustar00rootroot00000000000000From Coq Require Import ssreflect ssrfun ssrbool. From HB Require Import structures. (* without params *) HB.mixin Record isInhab T := { x : T }. HB.structure Definition Inhab := { T of isInhab T }. Definition unit' := unit. HB.instance Definition _ := isInhab.Build unit' tt. Check Inhab.of unit'. Fail Check Inhab.of unit. HB.instance Definition _ := Inhab.copy unit unit'. Check Inhab.of unit. (* with params *) HB.mixin Record isInhabIf (b : bool) (T : Type) := { y : forall ph : phant T, (match b with true => T | false => unit end) }. HB.structure Definition InhabIf b := { T of isInhabIf b T }. Definition bool' := bool. HB.instance Definition _ := isInhabIf.Build true bool' (fun=> false). Check InhabIf.of bool'. Fail Check InhabIf.of bool. HB.instance Definition _ := InhabIf.copy bool bool'. Check InhabIf.of bool. Check (y (Phant bool) : bool). math-comp-hierarchy-builder-4d8a939/tests/compress_coe.v000066400000000000000000000017651521677141400234010ustar00rootroot00000000000000From Corelib Require Import ssreflect ssrfun. From HB Require Import structures. HB.mixin Record hasA T := { a : T }. HB.structure Definition A := {T of hasA T}. HB.mixin Record hasB (p : unit) T & A T := { b : T }. HB.structure Definition B p := {T of A T & hasB p T}. HB.mixin Record hasC (p q : unit) T & B p T := { c : T }. HB.structure Definition C p q := {T of B p T & hasC p q T}. HB.mixin Record hasD T & C tt tt T := { d : T }. HB.structure Definition D := {T of C tt tt T & hasD T}. #[compress_coercions] HB.instance Definition prodA (A A' : A.type) := hasA.Build (A * A')%type (a, a). #[compress_coercions] HB.instance Definition prodB p (B B' : B.type p) := hasB.Build p (B * B')%type (b, b). #[compress_coercions] HB.instance Definition prodC p q (C C' : C.type p q) := hasC.Build p q (C * C')%type (c, c). #[compress_coercions] HB.instance Definition prodD (D D' : D.type) := hasD.Build (D * D')%type (d, d). Set Printing Coercions. Print Datatypes_prod__canonical__compress_coe_D. math-comp-hierarchy-builder-4d8a939/tests/compress_coe.v.out000066400000000000000000000012671521677141400242040ustar00rootroot00000000000000Datatypes_prod__canonical__compress_coe_D = fun D D' : D.type => {| D.sort := D.sort D * D.sort D'; D.class := {| D.compress_coe_hasA_mixin := prodA (compress_coe_D__to__compress_coe_A D) (compress_coe_D__to__compress_coe_A D'); D.compress_coe_hasB_mixin := prodB tt (compress_coe_D__to__compress_coe_B D) (compress_coe_D__to__compress_coe_B D'); D.compress_coe_hasC_mixin := prodC tt tt (compress_coe_D__to__compress_coe_C D) (compress_coe_D__to__compress_coe_C D'); D.compress_coe_hasD_mixin := prodD D D' |} |} : D.type -> D.type -> D.type Arguments Datatypes_prod__canonical__compress_coe_D D D' math-comp-hierarchy-builder-4d8a939/tests/compress_coe.v.out.18000066400000000000000000000012671521677141400244330ustar00rootroot00000000000000Datatypes_prod__canonical__compress_coe_D = fun D D' : D.type => {| D.sort := D.sort D * D.sort D'; D.class := {| D.compress_coe_hasA_mixin := prodA (compress_coe_D__to__compress_coe_A D) (compress_coe_D__to__compress_coe_A D'); D.compress_coe_hasB_mixin := prodB tt (compress_coe_D__to__compress_coe_B D) (compress_coe_D__to__compress_coe_B D'); D.compress_coe_hasC_mixin := prodC tt tt (compress_coe_D__to__compress_coe_C D) (compress_coe_D__to__compress_coe_C D'); D.compress_coe_hasD_mixin := prodD D D' |} |} : D.type -> D.type -> D.type Arguments Datatypes_prod__canonical__compress_coe_D D D' math-comp-hierarchy-builder-4d8a939/tests/compress_coe.v.out.19000066400000000000000000000012671521677141400244340ustar00rootroot00000000000000Datatypes_prod__canonical__compress_coe_D = fun D D' : D.type => {| D.sort := D.sort D * D.sort D'; D.class := {| D.compress_coe_hasA_mixin := prodA (compress_coe_D__to__compress_coe_A D) (compress_coe_D__to__compress_coe_A D'); D.compress_coe_hasB_mixin := prodB tt (compress_coe_D__to__compress_coe_B D) (compress_coe_D__to__compress_coe_B D'); D.compress_coe_hasC_mixin := prodC tt tt (compress_coe_D__to__compress_coe_C D) (compress_coe_D__to__compress_coe_C D'); D.compress_coe_hasD_mixin := prodD D D' |} |} : D.type -> D.type -> D.type Arguments Datatypes_prod__canonical__compress_coe_D D D' math-comp-hierarchy-builder-4d8a939/tests/compress_coe.v.out.20000066400000000000000000000012671521677141400244240ustar00rootroot00000000000000Datatypes_prod__canonical__compress_coe_D = fun D D' : D.type => {| D.sort := D.sort D * D.sort D'; D.class := {| D.compress_coe_hasA_mixin := prodA (compress_coe_D__to__compress_coe_A D) (compress_coe_D__to__compress_coe_A D'); D.compress_coe_hasB_mixin := prodB tt (compress_coe_D__to__compress_coe_B D) (compress_coe_D__to__compress_coe_B D'); D.compress_coe_hasC_mixin := prodC tt tt (compress_coe_D__to__compress_coe_C D) (compress_coe_D__to__compress_coe_C D'); D.compress_coe_hasD_mixin := prodD D D' |} |} : D.type -> D.type -> D.type Arguments Datatypes_prod__canonical__compress_coe_D D D' math-comp-hierarchy-builder-4d8a939/tests/declare.v000066400000000000000000000020501521677141400223030ustar00rootroot00000000000000From Corelib Require Import ssreflect ssrfun. From HB Require Import structures. HB.mixin Record hasA T := { a : T }. HB.structure Definition A := {T of hasA T}. HB.mixin Record hasB (p : unit) T & A T := { b : T }. HB.structure Definition B p := {T of A T & hasB p T}. HB.mixin Record hasC (p q : unit) T & B p T := { c : T }. HB.structure Definition C p q := {T of B p T & hasC p q T}. Section test. HB.declare Context p q T & hasA T & hasB p T & hasC p q T. Definition test := [the C.type _ _ of T]. End test. HB.factory Record hasABC (p q : unit) T := { a : T; b : T; c : T}. HB.builders Context p q T & hasABC p q T. HB.instance Definition _ := hasA.Build T a. HB.instance Definition _ := hasB.Build p T b. HB.instance Definition _ := hasC.Build p q T c. HB.end. Section test2. HB.declare Context p q T & hasABC p q T. Definition test2 := [the C.type _ _ of T]. End test2. (* broken *) (* Section test3. Definition copy : Type -> Type := id. HB.declare Context p T of hasABC p tt (copy T). Definition test3 := [the C.type _ _ of copy T]. End test3. *) math-comp-hierarchy-builder-4d8a939/tests/display.v000066400000000000000000000001641521677141400223550ustar00rootroot00000000000000From HB Require Import structures. #[key="T"] HB.mixin Record m (d : unit) (T : Type) := { op : T -> T -> T; }. math-comp-hierarchy-builder-4d8a939/tests/duplicate_structure.v000066400000000000000000000003721521677141400250030ustar00rootroot00000000000000From HB Require Import structures. Definition comb A op := forall x : A, op (op x) = x. HB.mixin Record Foo A := { op : A -> A; ax : comb A op }. HB.structure Definition S1 := { A of Foo A }. Fail HB.structure Definition S2 := { A of Foo A }. math-comp-hierarchy-builder-4d8a939/tests/err_bad_mix.v000066400000000000000000000007021521677141400231610ustar00rootroot00000000000000From HB Require Import structures. Module Test. HB.mixin Record Mixin T := { zero: T; }. HB.structure Definition Struct := { T of Mixin T }. HB.instance Definition struct_bool := Mixin.Build bool true. Module Exports. HB.reexport. End Exports. End Test. (** Uncommenting any of these two prevents the issue *) (* Export Test.Exports. *) (* HB.export Test. *) Fail HB.instance Definition struct_nat := Test.Mixin.Build nat 0. math-comp-hierarchy-builder-4d8a939/tests/err_bad_mix.v.out000066400000000000000000000003351521677141400237710ustar00rootroot00000000000000Interactive Module Test started Interactive Module Exports started The command has indeed failed with message: HB: Test.Mixin.axioms_ is not a factory or its library (HB.tests.err_bad_mix.Test) was not correctly imported math-comp-hierarchy-builder-4d8a939/tests/err_instance_nop.v000066400000000000000000000003131521677141400242340ustar00rootroot00000000000000From HB Require Import structures. HB.mixin Record M T := {}. HB.structure Definition S := { x of M x }. HB.instance Definition _ : M nat := M.Build nat. HB.instance Definition _ : M nat := M.Build nat.math-comp-hierarchy-builder-4d8a939/tests/err_instance_nop.v.out000066400000000000000000000003221521677141400250420ustar00rootroot00000000000000Toplevel input, character 0: > HB.instance Definition _ : M nat := M.Build nat. > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Warning: HB: no new instance is generated [HB.no-new-instance,HB,elpi,default] math-comp-hierarchy-builder-4d8a939/tests/err_instance_nop.v.out.18000066400000000000000000000001561521677141400252760ustar00rootroot00000000000000Toplevel input, character 155: Warning: HB: no new instance is generated [HB.no-new-instance,HB,elpi,default] math-comp-hierarchy-builder-4d8a939/tests/err_instance_nop.v.out.19000066400000000000000000000001561521677141400252770ustar00rootroot00000000000000Toplevel input, character 155: Warning: HB: no new instance is generated [HB.no-new-instance,HB,elpi,default] math-comp-hierarchy-builder-4d8a939/tests/err_instance_nop.v.out.20000066400000000000000000000001561521677141400252670ustar00rootroot00000000000000Toplevel input, character 155: Warning: HB: no new instance is generated [HB.no-new-instance,HB,elpi,default] math-comp-hierarchy-builder-4d8a939/tests/err_miss_dep.v000066400000000000000000000005041521677141400233610ustar00rootroot00000000000000From HB Require Import structures. HB.mixin Record IsAddComoid A := {}. HB.structure Definition AddComoid := { A of IsAddComoid A }. HB.mixin Record IsAbelianGrp A & IsAddComoid A := {}. HB.structure Definition AbelianGrp := { A of IsAbelianGrp A }. Fail HB.mixin Record IsRing K & IsAbelianGrp K (*& IsAddComoid K*) := {}. math-comp-hierarchy-builder-4d8a939/tests/err_miss_dep.v.out000066400000000000000000000006541521677141400241750ustar00rootroot00000000000000Toplevel input, character 0: > HB.structure Definition AbelianGrp := { A of IsAbelianGrp A }. > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Warning: pulling in dependencies: [err_miss_dep_IsAddComoid] Please list them or end the declaration with '&' [HB.implicit-structure-dependency,HB,elpi,default] The command has indeed failed with message: HB: Unable to find mixin err_miss_dep_IsAddComoid on subject K math-comp-hierarchy-builder-4d8a939/tests/err_miss_key.v000066400000000000000000000001241521677141400233770ustar00rootroot00000000000000From HB Require Import structures. Fail #[key="Tmiss"] HB.mixin Record Foo T := {}.math-comp-hierarchy-builder-4d8a939/tests/err_miss_key.v.out000066400000000000000000000001631521677141400242100ustar00rootroot00000000000000The command has indeed failed with message: HB: The #[key="Tmiss"] attribute does not match the selected subject T math-comp-hierarchy-builder-4d8a939/tests/err_missin_subject.v000066400000000000000000000003701521677141400246000ustar00rootroot00000000000000From HB Require Import structures. HB.mixin Record M X := {}. HB.structure Definition S := { X of M X}. HB.instance Definition _ : M nat := M.Build _. HB.instance Definition _ : M _ := M.Build bool. Fail HB.instance Definition _ : M _ := M.Build _.math-comp-hierarchy-builder-4d8a939/tests/err_missin_subject.v.out000066400000000000000000000003101521677141400254000ustar00rootroot00000000000000The command has indeed failed with message: HB: The instance subject must be explicitly given. Use: HB.instance Definition _ : M := ... HB.instance Definition _ := M.Build ... math-comp-hierarchy-builder-4d8a939/tests/factory_sort.v000066400000000000000000000016071521677141400234310ustar00rootroot00000000000000Require Import ssreflect ssrfun ssrbool. From HB Require Import structures. #[verbose] HB.mixin Record hasA T := { a : T }. About hasA.type. HB.structure Definition A := {T of hasA T}. HB.mixin Record hasB T := { b : T }. About hasB.type. HB.structure Definition B := {T of hasB T}. HB.structure Definition AB := {T of hasA T & hasB T}. HB.factory Record hasAB T := { a : T; b : T }. HB.builders Context T & hasAB T. HB.instance Definition _ := AB.copy T (AB.pack T (hasB.Build (hasA.Build T a) b)). HB.end. About hasAB.type. HB.factory Definition hasA' T := hasA T. About hasA'.type. Section test. Variables (G : Prop) (P : AB.type -> G). Goal forall T (a b : T), G. Proof. move=> T a b. pose Ta := hasA.Build _ a. pose Tab := hasB.Build Ta b. exact: P (AB.pack T Tab). Qed. Goal forall T (a b : T), G. Proof. move=> T a b. exact: P [the AB.type of hasAB.Build T a b : Type]. Qed. End test. math-comp-hierarchy-builder-4d8a939/tests/factory_when_notation.v000066400000000000000000000003321521677141400253100ustar00rootroot00000000000000From HB Require Import structures. Notation x := (fun x : nat => true). HB.mixin Record m T := {x : T}. HB.factory Record f T := { x : T }. HB.builders Context T & f T. HB.instance Definition _ := m.Build T x. HB.end. math-comp-hierarchy-builder-4d8a939/tests/fix_loop.v000066400000000000000000000001621521677141400225250ustar00rootroot00000000000000From HB Require Import structures. HB.mixin Record M A := { x: nat }. HB.structure Definition S := { A of M A }. math-comp-hierarchy-builder-4d8a939/tests/fun_instance.v000066400000000000000000000005411521677141400233630ustar00rootroot00000000000000From Corelib Require Import ssreflect ssrfun ssrbool. From HB Require Import structures. HB.mixin Record HasA T := { a : T }. HB.structure Definition A := { T of HasA T }. HB.instance Definition _ T (T' : A.type) := HasA.Build (T -> T') (fun=> a). HB.instance Definition _ := HasA.Build Prop True. HB.instance Definition _ := HasA.Build Type nat. math-comp-hierarchy-builder-4d8a939/tests/grefclass.v000066400000000000000000000003751521677141400226650ustar00rootroot00000000000000From HB Require Import structures. Definition pred T := T -> bool. HB.mixin Record isPredNat (f : pred nat) := {}. HB.structure Definition PredNat := {f of isPredNat f}. Section TestSort. Variable p : PredNat.type. Check p : pred nat. End TestSort. math-comp-hierarchy-builder-4d8a939/tests/hb_pack.v000066400000000000000000000053631521677141400223050ustar00rootroot00000000000000Require Import ssreflect ssrfun ssrbool. From elpi Require Import elpi. From HB Require Import structures. #[verbose] HB.mixin Record hasA T := { a : T }. About hasA.type. HB.structure Definition A := {T of hasA T}. HB.mixin Record hasB T := { b : T * T }. About hasB.type. HB.structure Definition B := {T of hasB T}. #[short(pack="AB.pack")] HB.structure Definition AB := {T of hasA T & hasB T}. HB.factory Record hasAB T := { a : T; b : T * T }. HB.builders Context T & hasAB T. Definition xxx := HB.pack_for AB.type T (hasB.Build T b) (hasA.Build T a). HB.instance Definition _ := AB.copy T xxx. HB.end. About hasAB.type. HB.factory Definition hasA' T := hasA T. About hasA'.type. Section test. Variables (G : Prop) (P : AB.type -> G). (* problem with planB Goal forall T (a b : T), G. Proof. move=> T a b. pose Ta := hasA.Build _ a. pose A := ltac:(elpi HB.pack_for (A.type) (T) (Ta)). pose Tab := hasB.Build A (b,b). pose AB : AB.type := ltac:(elpi HB.pack (A) (Tab)). exact: P AB. Qed. *) Goal forall T (a b : T), G. Proof. move=> T a b. pose Ta := hasA.Build _ a. pose A := HB.pack_for A.type T Ta. pose Tab := hasB.Build A (b,b). pose AB := HB.pack_for AB.type A Tab. exact: P AB. Qed. Goal forall T (a b : T), G. Proof. move=> T a b. pose Ta := hasA.Build _ a. pose A : A.type := HB.pack T Ta. pose Tab := hasB.Build A (b,b). pose AB : AB.type := HB.pack A Tab. exact: P AB. Qed. Check forall T : AB.type, let x := AB.pack T in x. Goal forall T (a b : T), G. Proof. move=> T a b. unshelve epose (A := HB.pack_for A.type T (_ : hasA T)). by exact: (hasA.Build _ a). Check A : A.type. unshelve epose (A1 := HB.pack_for A.type T (hasA.Build T _)). by exact: a. Check A : A.type. pose AB1 := AB.pack A (_ : hasB _). Check AB1 : hasB A -> AB.type. have [:Bm] @AB2 := AB.pack A (Bm : hasB A). by exact: (hasB.Build _ (b,b)). Check Bm : hasB A. Check AB2 : AB.type. have [:pB] @AB3 := AB.pack A (hasB.Build A pB). by exact: (b,b). Check pB : T * T. Check AB3 : AB.type. have [:pA pB'] @AB4 := AB.pack T (hasAB.Build A pA pB'). by exact: a. by exact: (b,b). exact: P AB4. Qed. End test. HB.mixin Record HasFoo (A : Type) (P : A -> Prop) T := { foo : forall x, P x -> T; }. #[short(pack="Foo.pack")] HB.structure Definition Foo A P := { T of HasFoo A P T }. Section test2. Variable A : Type. Variable P : A -> Prop. Goal forall T, (forall x, P x -> T) -> True. intros T H. pose X := Foo.pack T (HasFoo.Build A P T H). Check X : Foo.type A P. Abort. End test2. HB.mixin Record isID T (F : T -> T) := { p : forall x : T, F x = x }. HB.structure Definition Fun T := { F of isID T F }. Goal forall f : nat -> nat, forall p : (forall x, f x = x ), True. intros f p. pose F := isID.Build nat f p. pose T : Fun.type nat := HB.pack f F. Check T : Fun.type nat. Abort. math-comp-hierarchy-builder-4d8a939/tests/hnf.v000066400000000000000000000007351521677141400214670ustar00rootroot00000000000000From HB Require Import structures. HB.mixin Record M A := { x: nat }. HB.structure Definition S := { X of M X}. HB.factory Record f A := { y : nat }. HB.builders Context T & f T. HB.instance Definition _ := M.Build T (y + 1). HB.end. #[hnf] HB.instance Definition _ := f.Build nat (3 + 2). Print Datatypes_nat__canonical__hnf_S. Print HB_unnamed_mixin_8. HB.instance Definition _ := f.Build bool (3 + 2). Print Datatypes_bool__canonical__hnf_S. Print HB_unnamed_mixin_12. math-comp-hierarchy-builder-4d8a939/tests/hnf.v.out000066400000000000000000000006651521677141400222770ustar00rootroot00000000000000Datatypes_nat__canonical__hnf_S = {| S.sort := nat; S.class := {| S.hnf_M_mixin := HB_unnamed_mixin_8 |} |} : S.type HB_unnamed_mixin_8 = {| M.x := f.y nat HB_unnamed_factory_6 + 1 |} : M.axioms_ nat Datatypes_bool__canonical__hnf_S = {| S.sort := bool; S.class := {| S.hnf_M_mixin := HB_unnamed_mixin_12 |} |} : S.type HB_unnamed_mixin_12 = Builders_1.HB_unnamed_factory_3 bool HB_unnamed_factory_9 : M.axioms_ bool math-comp-hierarchy-builder-4d8a939/tests/hnf.v.out.16000066400000000000000000000006711521677141400225210ustar00rootroot00000000000000Datatypes_nat__canonical__hnf_S = {| S.sort := nat; S.class := {| S.hnf_M_mixin := HB_unnamed_mixin_8 |} |} : S.type HB_unnamed_mixin_8 = {| M.x := f.y nat HB_unnamed_factory_6 + 1 |} : M.axioms_ nat Datatypes_bool__canonical__hnf_S = {| S.sort := bool; S.class := {| S.hnf_M_mixin := HB_unnamed_mixin_12 |} |} : S.type HB_unnamed_mixin_12 = Builders_2.HB_unnamed_factory_4 bool HB_unnamed_factory_9 : M.axioms_ bool math-comp-hierarchy-builder-4d8a939/tests/howto.v.out000066400000000000000000000070261521677141400226620ustar00rootroot00000000000000Toplevel input, character 0: > From Coq Require Import ZArith ssrfun ssreflect. > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Warning: "From Coq" has been replaced by "From Stdlib". [deprecated-from-Coq,deprecated-since-9.0,deprecated,default] HB: solutions (use 'HB.about F.Build' to see the arguments of each factory F): - Ring_of_TYPE - AddAG_of_TYPE; BiNearRing_of_AddMonoid - AddAG_of_TYPE; Ring_of_AddAG - AddAG_of_TYPE; SemiRing_of_AddComoid - AddComoid_of_TYPE; Ring_of_AddComoid - AddComoid_of_TYPE; AddAG_of_AddComoid; BiNearRing_of_AddMonoid - AddComoid_of_TYPE; AddAG_of_AddComoid; Ring_of_AddAG - AddComoid_of_TYPE; AddAG_of_AddComoid; SemiRing_of_AddComoid - AddMonoid_of_TYPE; AddComoid_of_AddMonoid; Ring_of_AddComoid For a guide on declaring MathComp instances please refer to the following link: https://github.com/math-comp/math-comp/wiki/How-to-declare-MathComp-instances HB: solutions (use 'HB.about F.Build' to see the arguments of each factory F): - Ring_of_TYPE - AddAG_of_TYPE; BiNearRing_of_AddMonoid - AddAG_of_TYPE; Ring_of_AddAG - AddAG_of_TYPE; SemiRing_of_AddComoid - AddComoid_of_TYPE; Ring_of_AddComoid For a guide on declaring MathComp instances please refer to the following link: https://github.com/math-comp/math-comp/wiki/How-to-declare-MathComp-instances HB: solutions (use 'HB.about F.Build' to see the arguments of each factory F): - Ring_of_TYPE - AddAG_of_TYPE; BiNearRing_of_AddMonoid - AddAG_of_TYPE; Ring_of_AddAG - AddAG_of_TYPE; SemiRing_of_AddComoid - AddComoid_of_TYPE; Ring_of_AddComoid - AddComoid_of_TYPE; AddAG_of_AddComoid; BiNearRing_of_AddMonoid - AddComoid_of_TYPE; AddAG_of_AddComoid; Ring_of_AddAG - AddComoid_of_TYPE; AddAG_of_AddComoid; SemiRing_of_AddComoid - AddMonoid_of_TYPE; AddComoid_of_AddMonoid; Ring_of_AddComoid For a guide on declaring MathComp instances please refer to the following link: https://github.com/math-comp/math-comp/wiki/How-to-declare-MathComp-instances HB: solutions (use 'HB.about F.Build' to see the arguments of each factory F): - Ring_of_TYPE - AddAG_of_TYPE; BiNearRing_of_AddMonoid - AddAG_of_TYPE; Ring_of_AddAG - AddAG_of_TYPE; SemiRing_of_AddComoid - AddComoid_of_TYPE; Ring_of_AddComoid For a guide on declaring MathComp instances please refer to the following link: https://github.com/math-comp/math-comp/wiki/How-to-declare-MathComp-instances The command has indeed failed with message: HB: no solution found, try to increase search depth. HB: solutions (use 'HB.about F.Build' to see the arguments of each factory F): - Ring_of_AddComoid - AddAG_of_AddComoid; BiNearRing_of_AddMonoid - AddAG_of_AddComoid; Ring_of_AddAG - AddAG_of_AddComoid; SemiRing_of_AddComoid For a guide on declaring MathComp instances please refer to the following link: https://github.com/math-comp/math-comp/wiki/How-to-declare-MathComp-instances HB: solutions (use 'HB.about F.Build' to see the arguments of each factory F): - BiNearRing_of_AddMonoid - Ring_of_AddAG - SemiRing_of_AddComoid For a guide on declaring MathComp instances please refer to the following link: https://github.com/math-comp/math-comp/wiki/How-to-declare-MathComp-instances HB: solutions (use 'HB.about F.Build' to see the arguments of each factory F): - BiNearRing_of_AddMonoid - Ring_of_AddAG - SemiRing_of_AddComoid For a guide on declaring MathComp instances please refer to the following link: https://github.com/math-comp/math-comp/wiki/How-to-declare-MathComp-instances HB: nothing to do. math-comp-hierarchy-builder-4d8a939/tests/howto.v.out.18000066400000000000000000000064351521677141400231140ustar00rootroot00000000000000HB: solutions (use 'HB.about F.Build' to see the arguments of each factory F): - Ring_of_TYPE - AddAG_of_TYPE; BiNearRing_of_AddMonoid - AddAG_of_TYPE; Ring_of_AddAG - AddAG_of_TYPE; SemiRing_of_AddComoid - AddComoid_of_TYPE; Ring_of_AddComoid - AddComoid_of_TYPE; AddAG_of_AddComoid; BiNearRing_of_AddMonoid - AddComoid_of_TYPE; AddAG_of_AddComoid; Ring_of_AddAG - AddComoid_of_TYPE; AddAG_of_AddComoid; SemiRing_of_AddComoid - AddMonoid_of_TYPE; AddComoid_of_AddMonoid; Ring_of_AddComoid For a guide on declaring MathComp instances please refer to the following link: https://github.com/math-comp/math-comp/wiki/How-to-declare-MathComp-instances HB: solutions (use 'HB.about F.Build' to see the arguments of each factory F): - Ring_of_TYPE - AddAG_of_TYPE; BiNearRing_of_AddMonoid - AddAG_of_TYPE; Ring_of_AddAG - AddAG_of_TYPE; SemiRing_of_AddComoid - AddComoid_of_TYPE; Ring_of_AddComoid For a guide on declaring MathComp instances please refer to the following link: https://github.com/math-comp/math-comp/wiki/How-to-declare-MathComp-instances HB: solutions (use 'HB.about F.Build' to see the arguments of each factory F): - Ring_of_TYPE - AddAG_of_TYPE; BiNearRing_of_AddMonoid - AddAG_of_TYPE; Ring_of_AddAG - AddAG_of_TYPE; SemiRing_of_AddComoid - AddComoid_of_TYPE; Ring_of_AddComoid - AddComoid_of_TYPE; AddAG_of_AddComoid; BiNearRing_of_AddMonoid - AddComoid_of_TYPE; AddAG_of_AddComoid; Ring_of_AddAG - AddComoid_of_TYPE; AddAG_of_AddComoid; SemiRing_of_AddComoid - AddMonoid_of_TYPE; AddComoid_of_AddMonoid; Ring_of_AddComoid For a guide on declaring MathComp instances please refer to the following link: https://github.com/math-comp/math-comp/wiki/How-to-declare-MathComp-instances HB: solutions (use 'HB.about F.Build' to see the arguments of each factory F): - Ring_of_TYPE - AddAG_of_TYPE; BiNearRing_of_AddMonoid - AddAG_of_TYPE; Ring_of_AddAG - AddAG_of_TYPE; SemiRing_of_AddComoid - AddComoid_of_TYPE; Ring_of_AddComoid For a guide on declaring MathComp instances please refer to the following link: https://github.com/math-comp/math-comp/wiki/How-to-declare-MathComp-instances The command has indeed failed with message: HB: no solution found, try to increase search depth. HB: solutions (use 'HB.about F.Build' to see the arguments of each factory F): - Ring_of_AddComoid - AddAG_of_AddComoid; BiNearRing_of_AddMonoid - AddAG_of_AddComoid; Ring_of_AddAG - AddAG_of_AddComoid; SemiRing_of_AddComoid For a guide on declaring MathComp instances please refer to the following link: https://github.com/math-comp/math-comp/wiki/How-to-declare-MathComp-instances HB: solutions (use 'HB.about F.Build' to see the arguments of each factory F): - BiNearRing_of_AddMonoid - Ring_of_AddAG - SemiRing_of_AddComoid For a guide on declaring MathComp instances please refer to the following link: https://github.com/math-comp/math-comp/wiki/How-to-declare-MathComp-instances HB: solutions (use 'HB.about F.Build' to see the arguments of each factory F): - BiNearRing_of_AddMonoid - Ring_of_AddAG - SemiRing_of_AddComoid For a guide on declaring MathComp instances please refer to the following link: https://github.com/math-comp/math-comp/wiki/How-to-declare-MathComp-instances HB: nothing to do. math-comp-hierarchy-builder-4d8a939/tests/howto.v.out.19000066400000000000000000000064351521677141400231150ustar00rootroot00000000000000HB: solutions (use 'HB.about F.Build' to see the arguments of each factory F): - Ring_of_TYPE - AddAG_of_TYPE; BiNearRing_of_AddMonoid - AddAG_of_TYPE; Ring_of_AddAG - AddAG_of_TYPE; SemiRing_of_AddComoid - AddComoid_of_TYPE; Ring_of_AddComoid - AddComoid_of_TYPE; AddAG_of_AddComoid; BiNearRing_of_AddMonoid - AddComoid_of_TYPE; AddAG_of_AddComoid; Ring_of_AddAG - AddComoid_of_TYPE; AddAG_of_AddComoid; SemiRing_of_AddComoid - AddMonoid_of_TYPE; AddComoid_of_AddMonoid; Ring_of_AddComoid For a guide on declaring MathComp instances please refer to the following link: https://github.com/math-comp/math-comp/wiki/How-to-declare-MathComp-instances HB: solutions (use 'HB.about F.Build' to see the arguments of each factory F): - Ring_of_TYPE - AddAG_of_TYPE; BiNearRing_of_AddMonoid - AddAG_of_TYPE; Ring_of_AddAG - AddAG_of_TYPE; SemiRing_of_AddComoid - AddComoid_of_TYPE; Ring_of_AddComoid For a guide on declaring MathComp instances please refer to the following link: https://github.com/math-comp/math-comp/wiki/How-to-declare-MathComp-instances HB: solutions (use 'HB.about F.Build' to see the arguments of each factory F): - Ring_of_TYPE - AddAG_of_TYPE; BiNearRing_of_AddMonoid - AddAG_of_TYPE; Ring_of_AddAG - AddAG_of_TYPE; SemiRing_of_AddComoid - AddComoid_of_TYPE; Ring_of_AddComoid - AddComoid_of_TYPE; AddAG_of_AddComoid; BiNearRing_of_AddMonoid - AddComoid_of_TYPE; AddAG_of_AddComoid; Ring_of_AddAG - AddComoid_of_TYPE; AddAG_of_AddComoid; SemiRing_of_AddComoid - AddMonoid_of_TYPE; AddComoid_of_AddMonoid; Ring_of_AddComoid For a guide on declaring MathComp instances please refer to the following link: https://github.com/math-comp/math-comp/wiki/How-to-declare-MathComp-instances HB: solutions (use 'HB.about F.Build' to see the arguments of each factory F): - Ring_of_TYPE - AddAG_of_TYPE; BiNearRing_of_AddMonoid - AddAG_of_TYPE; Ring_of_AddAG - AddAG_of_TYPE; SemiRing_of_AddComoid - AddComoid_of_TYPE; Ring_of_AddComoid For a guide on declaring MathComp instances please refer to the following link: https://github.com/math-comp/math-comp/wiki/How-to-declare-MathComp-instances The command has indeed failed with message: HB: no solution found, try to increase search depth. HB: solutions (use 'HB.about F.Build' to see the arguments of each factory F): - Ring_of_AddComoid - AddAG_of_AddComoid; BiNearRing_of_AddMonoid - AddAG_of_AddComoid; Ring_of_AddAG - AddAG_of_AddComoid; SemiRing_of_AddComoid For a guide on declaring MathComp instances please refer to the following link: https://github.com/math-comp/math-comp/wiki/How-to-declare-MathComp-instances HB: solutions (use 'HB.about F.Build' to see the arguments of each factory F): - BiNearRing_of_AddMonoid - Ring_of_AddAG - SemiRing_of_AddComoid For a guide on declaring MathComp instances please refer to the following link: https://github.com/math-comp/math-comp/wiki/How-to-declare-MathComp-instances HB: solutions (use 'HB.about F.Build' to see the arguments of each factory F): - BiNearRing_of_AddMonoid - Ring_of_AddAG - SemiRing_of_AddComoid For a guide on declaring MathComp instances please refer to the following link: https://github.com/math-comp/math-comp/wiki/How-to-declare-MathComp-instances HB: nothing to do. math-comp-hierarchy-builder-4d8a939/tests/howto.v.out.20000066400000000000000000000064351521677141400231050ustar00rootroot00000000000000HB: solutions (use 'HB.about F.Build' to see the arguments of each factory F): - Ring_of_TYPE - AddAG_of_TYPE; BiNearRing_of_AddMonoid - AddAG_of_TYPE; Ring_of_AddAG - AddAG_of_TYPE; SemiRing_of_AddComoid - AddComoid_of_TYPE; Ring_of_AddComoid - AddComoid_of_TYPE; AddAG_of_AddComoid; BiNearRing_of_AddMonoid - AddComoid_of_TYPE; AddAG_of_AddComoid; Ring_of_AddAG - AddComoid_of_TYPE; AddAG_of_AddComoid; SemiRing_of_AddComoid - AddMonoid_of_TYPE; AddComoid_of_AddMonoid; Ring_of_AddComoid For a guide on declaring MathComp instances please refer to the following link: https://github.com/math-comp/math-comp/wiki/How-to-declare-MathComp-instances HB: solutions (use 'HB.about F.Build' to see the arguments of each factory F): - Ring_of_TYPE - AddAG_of_TYPE; BiNearRing_of_AddMonoid - AddAG_of_TYPE; Ring_of_AddAG - AddAG_of_TYPE; SemiRing_of_AddComoid - AddComoid_of_TYPE; Ring_of_AddComoid For a guide on declaring MathComp instances please refer to the following link: https://github.com/math-comp/math-comp/wiki/How-to-declare-MathComp-instances HB: solutions (use 'HB.about F.Build' to see the arguments of each factory F): - Ring_of_TYPE - AddAG_of_TYPE; BiNearRing_of_AddMonoid - AddAG_of_TYPE; Ring_of_AddAG - AddAG_of_TYPE; SemiRing_of_AddComoid - AddComoid_of_TYPE; Ring_of_AddComoid - AddComoid_of_TYPE; AddAG_of_AddComoid; BiNearRing_of_AddMonoid - AddComoid_of_TYPE; AddAG_of_AddComoid; Ring_of_AddAG - AddComoid_of_TYPE; AddAG_of_AddComoid; SemiRing_of_AddComoid - AddMonoid_of_TYPE; AddComoid_of_AddMonoid; Ring_of_AddComoid For a guide on declaring MathComp instances please refer to the following link: https://github.com/math-comp/math-comp/wiki/How-to-declare-MathComp-instances HB: solutions (use 'HB.about F.Build' to see the arguments of each factory F): - Ring_of_TYPE - AddAG_of_TYPE; BiNearRing_of_AddMonoid - AddAG_of_TYPE; Ring_of_AddAG - AddAG_of_TYPE; SemiRing_of_AddComoid - AddComoid_of_TYPE; Ring_of_AddComoid For a guide on declaring MathComp instances please refer to the following link: https://github.com/math-comp/math-comp/wiki/How-to-declare-MathComp-instances The command has indeed failed with message: HB: no solution found, try to increase search depth. HB: solutions (use 'HB.about F.Build' to see the arguments of each factory F): - Ring_of_AddComoid - AddAG_of_AddComoid; BiNearRing_of_AddMonoid - AddAG_of_AddComoid; Ring_of_AddAG - AddAG_of_AddComoid; SemiRing_of_AddComoid For a guide on declaring MathComp instances please refer to the following link: https://github.com/math-comp/math-comp/wiki/How-to-declare-MathComp-instances HB: solutions (use 'HB.about F.Build' to see the arguments of each factory F): - BiNearRing_of_AddMonoid - Ring_of_AddAG - SemiRing_of_AddComoid For a guide on declaring MathComp instances please refer to the following link: https://github.com/math-comp/math-comp/wiki/How-to-declare-MathComp-instances HB: solutions (use 'HB.about F.Build' to see the arguments of each factory F): - BiNearRing_of_AddMonoid - Ring_of_AddAG - SemiRing_of_AddComoid For a guide on declaring MathComp instances please refer to the following link: https://github.com/math-comp/math-comp/wiki/How-to-declare-MathComp-instances HB: nothing to do. math-comp-hierarchy-builder-4d8a939/tests/instance_before_structure.v000066400000000000000000000013761521677141400261640ustar00rootroot00000000000000From HB Require Import structures. HB.mixin Record m1 T := { default1 : T }. HB.mixin Record m2 T := { default2 : T }. HB.mixin Record m3 T := { default3 : T }. HB.structure Definition s1 := { T of m1 T }. HB.instance Definition _ : m1 nat := m1.Build nat 1. HB.about nat. (* too early *) HB.instance Definition _ : m2 nat := m2.Build nat 2. HB.about nat. (* only s1 on nat *) HB.instance Definition _ : m3 nat := m3.Build nat 3. HB.structure Definition s2 := { T of m1 T & m2 T }. HB.about nat. (* s2 is not there yet *) HB.structure Definition s3 := { T of m3 T }. HB.about nat. (* s2 has been instanciated but not s3 *) (* here it works *) HB.saturate. HB.about nat. (* all there *) Check @default1 nat. Check @default2 nat. Check @default3 nat. math-comp-hierarchy-builder-4d8a939/tests/instance_merge.v000066400000000000000000000000001521677141400236600ustar00rootroot00000000000000math-comp-hierarchy-builder-4d8a939/tests/instance_merge_with_distinct_param.v000066400000000000000000000031151521677141400300060ustar00rootroot00000000000000From HB Require Import structures. HB.mixin Record m1 T := { default1 : T }. HB.mixin Record m2 T := { default2 : T }. (* since s1 only requires m1 there is a 1:1 correspondence between the structure s1 and the mixin m1 *) HB.structure Definition s1 := { T of m1 T }. HB.structure Definition s2 := { T of m2 T }. HB.instance Definition nat_m1 := m1.Build nat 0. HB.instance Definition nat_m2 := m2.Build nat 1. (* with the following example we want to show that list preserves the s1 structure ie. if x:s1.type then (list x):s1.type, in practice we can use this for the type of polynomials *) HB.instance Definition list_m1 (X : s1.type) : m1 (list X) := m1.Build (list X) (cons default1 nil). (* similarly list preserves s2 structure *) HB.instance Definition list_m2 (X : s2.type) : m2 (list X) := m2.Build (list X) (cons default2 nil). HB.structure Definition s3 := { T of m1 T & m2 T }. (* since we can preserve m1 and m2 with list, we can preserve s3 as well ! *) (* if we have a file A with definitions of S1 and S2, file B importing Awith definitions of instance nat_m1 and nat_m2 file C importing A with the definition of s3 in a file D that imports B and C if we call saturate_instance, we create the instance for s3. this example shows the need for a separate command *) Fail Check nat : s3.type. HB.saturate. Check nat : s3.type. (* since nat satisfies s3.type, so does list nat *) Check list nat : s3.type. Check list (list nat) : s3.type. Fail Check fun t : s1.type => (list t : s3.type). Fail Check fun t : s2.type => (list t : s3.type). Check fun t : s3.type => (list t : s3.type). math-comp-hierarchy-builder-4d8a939/tests/instance_merge_with_param.v000066400000000000000000000014451521677141400261110ustar00rootroot00000000000000From HB Require Import structures. HB.mixin Record m1 T := { default1 : T }. HB.mixin Record m2 T := { default2 : T }. HB.structure Definition s1 := { T of m1 T }. HB.structure Definition s2 := { T of m2 T }. HB.instance Definition _ (X : s1.type) : m1 (list X) := m1.Build (list X) (cons default1 nil). HB.instance Definition list_m2 (X : s1.type) : m2 (list X) := m2.Build (list X) nil. HB.structure Definition s3 := { T of m1 T & m2 T }. HB.about list. (* should have s3 *) (* The s3 instance on list should be synthetized automatically, *) (* But since it's defined afterwards, it's not taken into account. *) (* The subtelty now is that there is a parameter, but it's always the same *) (* A simple recall suffices: *) HB.instance Definition _ (X : s1.type) := list_m2 X. HB.about list. math-comp-hierarchy-builder-4d8a939/tests/instance_params_no_type.v000066400000000000000000000020511521677141400256110ustar00rootroot00000000000000From HB Require Import structures. HB.mixin Record is_foo P A := { op : P -> A -> A }. HB.instance Definition nat_foo P := is_foo.Build P nat (fun _ x => x). HB.instance Definition list_foo P := is_foo.Build P (list P) (fun _ x => x). HB.instance Definition list_foo' P A:= is_foo.Build P (list A) (fun _ x => x). About list_foo'. HB.structure Definition foo P := { A of is_foo P A }. (* .... list A .... (fun A => {| foo.sort := list..; foo.class := {| foo.instance_params_no_type_is_foo_mixin := list_foo A |} |} ). HB.about foo. *) (* Elpi Trace Browser. *) Check nat_foo. Check list_foo. HB.mixin Record is_b A:= { default : A }. Check foo.type. Print foo.type. Print Module foo. Print foo.axioms_. (*Elpi Trace Browser. *) HB.structure Definition b := { A of is_b A}. HB.instance Definition nat_b := is_b.Build nat 0. HB.mixin Record is_bar (P : b.type) A := { test : P -> A -> A }. HB.structure Definition bar P := { A of is_bar P A}. HB.instance Definition list_bar P := is_bar.Build P (list P) (fun _ x => x). Check list_bar. math-comp-hierarchy-builder-4d8a939/tests/interleave_context.v000066400000000000000000000016541521677141400246170ustar00rootroot00000000000000From Corelib Require Import ssreflect ssrfun ssrbool. From HB Require Import structures. HB.mixin Record HasA (n : nat) T := { a : T }. HB.structure Definition A n := { T of HasA n T }. HB.mixin Record HasB (X : A.type 0) (T : Type) := { b : X -> T }. HB.structure Definition B (X : A.type 0) := { T of HasB X T }. (* Since `B` expects an argument of type `A.type 0` (and not just just the naked type `T`) we pass `A.clone 0 T _` (of type `A.type 0`) and inference uses the first parameter `A` to elaborate it. *) HB.mixin Record IsSelfA T & A 0 T & B (A.clone 0 T _) T := {}. HB.structure Definition SelfA := { T of IsSelfA T }. HB.factory Record IsSelfA' T := { a : T ; b : T -> T}. HB.builders Context T & IsSelfA' T. HB.instance Definition _ := HasA.Build 0 T a. HB.instance Definition _ := HasB.Build _ T b. HB.instance Definition _ := IsSelfA.Build T. HB.end. HB.instance Definition _ := IsSelfA'.Build nat 0 id. math-comp-hierarchy-builder-4d8a939/tests/issue284.v000066400000000000000000000010071521677141400222730ustar00rootroot00000000000000From HB Require Import structures. HB.mixin Record X_of_Type Ω := {}. HB.structure Definition X := {Ω of X_of_Type Ω}. HB.instance Definition XProp := X_of_Type.Build Prop. Definition prop := Prop. HB.instance Definition Xprop := X_of_Type.Build prop. HB.instance Definition XSet := X_of_Type.Build Set. Definition set := Set. HB.instance Definition Xset := X_of_Type.Build set. HB.instance Definition XType := X_of_Type.Build Type. Definition type := Type. HB.instance Definition Xtype := X_of_Type.Build type. math-comp-hierarchy-builder-4d8a939/tests/issue287.v000066400000000000000000000007611521677141400223040ustar00rootroot00000000000000From HB Require Import structures. HB.mixin Record InhMixin T := { point : T; }. HB.structure Definition Inh := { T of InhMixin T }. HB.instance Definition nat_inh := InhMixin.Build nat 0. Section ProdInh. Variables (T S : Inh.type). (* This works fine *) HB.instance Definition prod_inh := InhMixin.Build (T * S)%type (point, point). End ProdInh. Section FunInh. Variables (T S : Inh.type). HB.instance Definition fun_inh := InhMixin.Build (T -> S) (fun _ => point). End FunInh. math-comp-hierarchy-builder-4d8a939/tests/local_instance.v000066400000000000000000000004361521677141400236700ustar00rootroot00000000000000From HB Require Import structures. HB.mixin Record def A := { default : A }. HB.structure Definition nonempty := { T of def T }. Section Box. #[local] HB.instance Definition def_nat := def.Build nat 1. Check default : nat. End Box. #[fail, skip="8.11"] HB.check (default : nat). math-comp-hierarchy-builder-4d8a939/tests/lock.v000066400000000000000000000005421521677141400216400ustar00rootroot00000000000000From HB Require Import structures. HB.lock Definition foo := 3. Definition nat1 := nat. HB.lock Definition bar : nat1 := 3. HB.lock Definition baz n : nat := 3 + n. Module Import X. Axiom bigbody : Type -> Type -> Type. Axiom bigop : forall R I : Type, R -> list I -> (I -> bigbody R I) -> R. HB.lock Definition big := bigop. End X. About big. math-comp-hierarchy-builder-4d8a939/tests/log_impargs_record.v000066400000000000000000000003741521677141400245540ustar00rootroot00000000000000From HB Require Import structures. Set Implicit Arguments. #[log] HB.mixin Record A T := { a : T; f : T -> T; p : forall x : T, f x = x -> True; q : forall h : f a = a, p _ h = p _ h; }. HB.structure Definition S := { T of A T }. About A.p.math-comp-hierarchy-builder-4d8a939/tests/missing_join_error.v000066400000000000000000000011301521677141400246030ustar00rootroot00000000000000From HB Require Import structures. HB.mixin Record isTop M := { }. HB.structure Definition Top := {M of isTop M}. HB.mixin Record isA1 M & Top M := { }. HB.structure Definition A1 := {M of isA1 M & isTop M}. HB.mixin Record isA2 M & Top M := { }. HB.structure Definition A2 := {M of isA2 M & isTop M}. HB.mixin Record isB1 M & A1 M := { }. HB.structure Definition B1 := {M of isB1 M & }. HB.mixin Record isB2 M & A2 M := { }. HB.structure Definition B2 := {M of isB2 M & isA2 M }. HB.structure Definition B2A1 := {M of B2 M & A1 M }. Fail HB.structure Definition A2B1 := {M of A2 M & B1 M }. math-comp-hierarchy-builder-4d8a939/tests/missing_join_error.v.out000066400000000000000000000011601521677141400254140ustar00rootroot00000000000000Toplevel input, character 0: > HB.structure Definition B2 := {M of isB2 M & isA2 M }. > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Warning: pulling in dependencies: [missing_join_error_isTop] Please list them or end the declaration with '&' [HB.implicit-structure-dependency,HB,elpi,default] The command has indeed failed with message: You must declare the hierarchy bottom-up or add a missing join. There are two ways out: - declare structure A2B1 before structure B2A1 if B2A1 inherits from it; - declare an additional structure that inherits from both A1 and A2 and from which A2B1 and/or B2A1 inherit. math-comp-hierarchy-builder-4d8a939/tests/non_forgetful_inheritance.v000066400000000000000000000044441521677141400261350ustar00rootroot00000000000000From HB Require Import structures. Require Import ssreflect ssrfun ssrbool. HB.mixin Record HasMul T := { mul : T -> T -> T; }. HB.structure Definition Mul := { T of HasMul T }. HB.mixin Record HasSq T := { sq : T -> T; }. HB.structure Definition Sq := { T of HasSq T }. (* We need a functorial construction (a container) which preserves both structures. The simplest one is the option type. *) Definition option_mul {T : Mul.type} (o1 o2 : option T) : option T := match o1, o2 with | Some n, Some m => Some (mul n m) | _, _ => None end. HB.instance Definition _ (T : Mul.type) := HasMul.Build (option T) option_mul. Definition option_square {T : Sq.type} (o : option T) : option T := match o with | Some n => Some (sq n) | None => None end. HB.instance Definition _ (T : Sq.type) := HasSq.Build (option T) option_square. (* Now we mix the two unrelated structures by building Sq out of Mul. *** This breaks Forgetful Inheritance *** https://math-comp.github.io/competing-inheritance-paths-in-dependent-type-theory/ hence, HB prevents us from using it without care. *) Set Warnings "+HB.non-forgetful-inheritance". Fail HB.instance Definition _ (T : Mul.type) := HasSq.Build T (fun x => mul x x). (* As advised by the error message, we contain the problem in a module *) Module MulSq. #[non_forgetful_inheritance] HB.instance Definition _ (T : Mul.type) := HasSq.Build T (fun x => mul x x). (* As we expect we can proved this (by reflexivity) *) Lemma sq_mul (V : Mul.type) (v : V) : sq v = mul v v. Proof. by reflexivity. Qed. Lemma problem (W : Mul.type) (w : option W) : sq w = mul w w. Proof. Fail reflexivity. (* What? It used to work! *) Fail rewrite sq_mul. (* Lemmas don't cross the container either! *) (* Let's investigate *) rewrite /mul/= /sq/=. (* As we expect, we are on the option type. In the LHS it is the Sq built using the NFI instance option_square w = option_mul w w *) rewrite /option_mul/=. rewrite /option_square/sq/=. congr (match w with Some n => _ | None => None end). (* The branches for Some differ, since w is a variable, they don't compare as equal (fun n : W => Some (mul n n)) = (fun n : W => match w with | Some m => Some (mul n m) | None => None end) *) Abort. End MulSq.math-comp-hierarchy-builder-4d8a939/tests/not_same_key.v000066400000000000000000000003011521677141400233560ustar00rootroot00000000000000From HB Require Import structures. HB.mixin Record A T := { a : T }. #[key="T"] HB.mixin Record B T1 (T : Type) := { b : T -> T1 }. Fail HB.structure Definition sAB T1 := {T of A T & B T T1}.math-comp-hierarchy-builder-4d8a939/tests/not_same_key.v.out000066400000000000000000000001221521677141400241650ustar00rootroot00000000000000The command has indeed failed with message: HB: all mixins must have the same key math-comp-hierarchy-builder-4d8a939/tests/packable.v000066400000000000000000000025421521677141400224540ustar00rootroot00000000000000From Coq Require Import ssreflect ssrfun. From HB Require Import structures. HB.mixin Record AddComoid_of_TYPE A := { zero : A; add : A -> A -> A; addrA : associative add; addrC : commutative add; add0r : left_id zero add; }. HB.structure Definition AddComoid := { A of AddComoid_of_TYPE A }. HB.mixin Record Ring_of_AddComoid A & AddComoid A := { opp : A -> A; one : A; mul : A -> A -> A; addNr : left_inverse zero opp add; mulrA : associative mul; mul1r : left_id one mul; mulr1 : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; }. HB.factory Record Ring_of_TYPE A := { zero : A; one : A; add : A -> A -> A; opp : A -> A; mul : A -> A -> A; addrA : associative add; addrC : commutative add; add0r : left_id zero add; addNr : left_inverse zero opp add; mulrA : associative mul; mul1r : left_id one mul; mulr1 : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; }. #[verbose] HB.builders Context A (a : Ring_of_TYPE A). HB.instance Definition to_AddComoid_of_TYPE := AddComoid_of_TYPE.Build A zero add addrA addrC add0r. HB.instance Definition to_Ring_of_AddComoid := Ring_of_AddComoid.Build A _ _ _ addNr mulrA mul1r mulr1 mulrDl mulrDr. HB.end. (* End change *) HB.structure Definition Ring := { A of Ring_of_TYPE A }. math-comp-hierarchy-builder-4d8a939/tests/primitive_records.v000066400000000000000000000020121521677141400244330ustar00rootroot00000000000000From Corelib Require Import ssreflect ssrfun. From elpi Require Import elpi. From HB Require Import structures. Elpi Command HB.test. #[primitive] HB.mixin Record hasA T := { a : T }. Elpi Query lp:{{ coq.locate "hasA.axioms_" (indt Ind), std.assert! (coq.env.record? Ind tt) "not primitive" }}. #[primitive] HB.structure Definition A := {T of hasA T}. Elpi Query lp:{{ coq.locate "A.axioms_" (indt Ind), std.assert! (coq.env.record? Ind tt) "not primitive" }}. Elpi Query lp:{{ coq.locate "A.type" (indt Ind), std.assert! (coq.env.record? Ind tt) "not primitive" }}. (* Issue #248 *) #[primitive] HB.mixin Record HasMul T := { mul : T -> T -> T; mulC: forall x y : T, mul x y = mul y x; mulA: associative mul; }. #[primitive] HB.structure Definition Mul := { T of HasMul T }. #[primitive] HB.mixin Record HasSq T & Mul T := { sq : T -> T; pmul : forall x y, sq (mul x y) = mul (sq x) (sq y); }. #[primitive] HB.structure Definition Sq := { T of HasSq T & Mul T }. Check erefl : Sq.sort _ = Mul.sort _. math-comp-hierarchy-builder-4d8a939/tests/saturate_export.v000066400000000000000000000013351521677141400241420ustar00rootroot00000000000000From HB Require Import structures. HB.mixin Record HasPoint T := { default : T }. HB.instance Definition _ : HasPoint nat := HasPoint.Build nat 0. HB.instance Definition _ : HasPoint bool := HasPoint.Build bool false. HB.instance Definition _ A : HasPoint (list A) := HasPoint.Build (list A) nil. HB.instance Definition _ A : HasPoint Type := HasPoint.Build Type nat. HB.structure Definition Pointed := { T of HasPoint T }. Fail Check (list unit : Pointed.type). Module Foo. HB.saturate (list _). Module E. HB.reexport. End E. End Foo. Import Foo.E. Fail Check (list unit : Pointed.type). Module Bar. #[export] HB.saturate (list _). Module E. HB.reexport. End E. End Bar. Import Bar.E. Check (list unit : Pointed.type). math-comp-hierarchy-builder-4d8a939/tests/saturate_on.v000066400000000000000000000011071521677141400232320ustar00rootroot00000000000000From HB Require Import structures. HB.mixin Record HasPoint T := { default : T }. HB.instance Definition _ : HasPoint nat := HasPoint.Build nat 0. HB.instance Definition _ : HasPoint bool := HasPoint.Build bool false. HB.instance Definition _ A : HasPoint (list A) := HasPoint.Build (list A) nil. HB.instance Definition _ A : HasPoint Type := HasPoint.Build Type nat. HB.structure Definition Pointed := { T of HasPoint T }. HB.saturate (list _). Fail Check nat : Pointed.type. Fail Check bool : Pointed.type. Check (list unit : Pointed.type). Fail Check Type : Pointed.type. math-comp-hierarchy-builder-4d8a939/tests/short.v000066400000000000000000000016261521677141400220530ustar00rootroot00000000000000From Corelib Require Import ssreflect ssrfun. From HB Require Import structures. HB.mixin Record hasA T := { a : T }. #[short(type="aType", pack="AType")] HB.structure Definition A := {T of hasA T}. Check aType. HB.mixin Record hasB T := { b : T }. About hasB.type. #[short(type="bType", pack="BType")] HB.structure Definition B := {T of hasB T}. #[short(type="abType", pack="ABType")] HB.structure Definition AB := {T of hasA T & hasB T}. HB.factory Record hasAB T := { a : T; b : T }. HB.builders Context T & hasAB T. Definition xxx := ABType T (hasB.Build T b) (hasA.Build T a). HB.instance Definition _ := AB.copy T xxx. HB.end. About hasAB.type. HB.factory Definition hasA' T := hasA T. About hasA'.type. Section test. Variables (G : Prop) (P : AB.type -> G). Goal forall T (a b : T), G. Proof. move=> T a b. pose Ta := hasA.Build T a. pose Tb := hasB.Build T b. exact: P (ABType T Ta Tb). Qed. End test. math-comp-hierarchy-builder-4d8a939/tests/subtype.v000066400000000000000000000023051521677141400224020ustar00rootroot00000000000000From HB Require Import structures. HB.mixin Record is_inhab T := { default : T }. HB.structure Definition Inhab := { T of is_inhab T }. HB.mixin Record is_nontrivial T := { twodiff : forall x : T, exists y : T, ~~ (x = y) }. HB.structure Definition Nontrivial1 := { T of is_nontrivial T }. HB.structure Definition Nontrivial := { T of is_inhab T & is_nontrivial T }. Definition pred T := T -> Prop. #[key="sub_sort"] HB.mixin Record is_SUB (T : Type) (P : pred T) (sub_sort : Type) := SubType { val : sub_sort -> T; Sub : forall x, P x -> sub_sort; Sub_rect : forall K (_ : forall x Px, K (@Sub x Px)) u, K u; SubK : forall x Px, val (@Sub x Px) = x }. HB.structure Definition SUB (T : Type) (P : pred T) := { S of is_SUB T P S }. #[verbose] HB.structure Definition SubInhab (T : Type) P := { sT of is_inhab sT & is_SUB T P sT }. HB.structure Definition SubNontrivial T P := { sT of is_nontrivial sT & is_SUB T P sT }. #[key="sT"] HB.factory Record InhabForSub (T : Inhab.type) P (sT : Type) & SubNontrivial T P sT := {}. HB.builders Context (T : Inhab.type) P sT & InhabForSub T P sT. Axiom xxx : P (default : T). HB.instance Definition SubInhabMix := is_inhab.Build sT (Sub (default : T) xxx). HB.end. math-comp-hierarchy-builder-4d8a939/tests/test_CS_db_filtering.v000066400000000000000000000014311521677141400247620ustar00rootroot00000000000000From HB Require Import structures. HB.mixin Record base_m T := { A : T }. HB.structure Definition base := { T of base_m T }. HB.mixin Record child1_m T := { C1 : T }. HB.structure Definition child1 := { T of base T & child1_m T }. HB.mixin Record child2_m T := { C2 : T }. HB.structure Definition child2 := { T of base T & child2_m T }. Axiom ix : Type. Definition vec T := ix -> T. Section b. Variable T : base.type. HB.instance Definition v_base_m : base_m (vec T) := base_m.Build _ (fun _ => A). End b. Section c1. Variable T : child1.type. HB.instance Definition v_child1_m : child1_m (vec T) := child1_m.Build _ (fun _ => C1). End c1. Section c2. Variable T : child2.type. HB.instance Definition v_child2_m : child2_m (vec T) := child2_m.Build _ (fun _ => C2). End c2. math-comp-hierarchy-builder-4d8a939/tests/test_howto.v000066400000000000000000000003241521677141400231050ustar00rootroot00000000000000From HB Require Import structures. HB.mixin Record hasB T := Mixin { b : unit; }. HB.mixin Record hasA T := Mixin { a : bool; }. HB.structure Definition A := { T of hasA T}. HB.howto A.type. (* runs forever *)math-comp-hierarchy-builder-4d8a939/tests/test_synthesis_params.v000066400000000000000000000021101521677141400253340ustar00rootroot00000000000000From HB Require Import structures. HB.mixin Record IsDualPOrdered (d : unit) T := { le : T -> T -> bool; ge : T -> T -> bool }. HB.structure Definition POrder d := { T of IsDualPOrdered d T }. HB.factory Record IsPOrdered (d : unit) T := { le : T -> T -> bool }. HB.builders Context d T & IsPOrdered d T. HB.instance Definition _ := IsDualPOrdered.Build d T le le. HB.end. HB.mixin Record HasBottom d T & IsDualPOrdered d T := { bottom : T }. HB.structure Definition BPOrder d := { T of HasBottom d T & IsDualPOrdered d T }. HB.mixin Record HasTop d T & IsDualPOrdered d T := { top : T }. HB.structure Definition TPOrder d := { T of HasTop d T & IsDualPOrdered d T }. Definition dual (T : Type) := T. Definition dd (d:unit) : unit. exact d. Qed. HB.instance Definition _ d (T : POrder.type d) := IsDualPOrdered.Build (dd d) (dual T) (fun x y => @le d T y x) (fun x y => @le d T y x). HB.instance Definition _ d (T : TPOrder.type d) := HasBottom.Build (dd d) (dual T) (@top _ T). HB.instance Definition _ d (T : BPOrder.type d) := HasTop.Build (dd d) (dual T) (@bottom _ T). math-comp-hierarchy-builder-4d8a939/tests/two_hier.v000066400000000000000000000054611521677141400225350ustar00rootroot00000000000000From HB Require Import structures. HB.mixin Record m1 T := { default1 : T }. HB.mixin Record m2 T := { default2 : T }. (* since s1 only requires m1 there is a 1:1 correspondence between the structure s1 and the mixin m1 *) HB.structure Definition s1 := { T of m1 T }. HB.structure Definition s2 := { T of m2 T }. HB.instance Definition nat_m1 := m1.Build nat 0. HB.instance Definition nat_m2 := m2.Build nat 1. (* with the following example we want to show that list preserves the s1 structure ie. if x:s1.type then (list x):s1.type, in practice we can use this for the type of polynomials *) HB.instance Definition list_m1 (X : s1.type) : m1 (list X) := m1.Build (list X) (cons default1 nil). (* similarly list preserves s2 structure *) HB.instance Definition list_m2 (X : s2.type) : m2 (list X) := m2.Build (list X) (cons default2 nil). HB.structure Definition s3 := { T of m1 T & m2 T }. (* since we can preserve m1 and m2 with list, we can preserve s3 as well ! *) (* if we have a file A with definitions of S1 and S2, file B importing Awith definitions of instance nat_m1 and nat_m2 file C importing A with the definition of s3 in a file D that imports B and C if we call saturate_instance, we create the instance for s3. this example shows the need for a separate command *) Fail Check nat : s3.type. HB.saturate. Check nat : s3.type. (* since nat satisfies s3.type, so does list nat *) Check list nat : s3.type. Check list (list nat) : s3.type. Fail Check fun t : s1.type => (list t : s3.type). Fail Check fun t : s2.type => (list t : s3.type). Check fun t : s3.type => (list t : s3.type). HB.mixin Record m1' (P : s1.type) T := { f1 : P -> T }. HB.mixin Record m2' (P : s2.type) T := { f2 : P -> T }. (* since s1 only requires m1 there is a 1:1 correspondence between the structure s1 and the mixin m1 *) HB.structure Definition s1' P := { T of m1' P T }. HB.structure Definition s2' P := { T of m2' P T }. HB.instance Definition nat_m1' := m1'.Build nat nat (fun _ => 0). HB.instance Definition nat_m2' := m2'.Build nat nat (fun _ => 1). (* with the following example we want to show that list preserves the s1 structure ie. if x:s1.type then (list x):s1.type, in practice we can use this for the type of polynomials *) HB.instance Definition list_m1' (P : s1.type) (X : s1'.type P) : m1' P (list X) := m1'.Build P (list X) (fun x => cons (f1 x) nil). (* similarly list preserves s2 structure *) HB.instance Definition list_m2' (P : s2.type) (X : s2'.type P) : m2' P (list X) := m2'.Build P (list X) (fun x => cons (f2 x) nil). HB.structure Definition s3' (P : s3.type) := { T of m1' P T & m2' P T }. Fail Check nat : s3'.type _. HB.saturate. Check nat : s3'.type _. (* since nat satisfies s3'.type, so does list nat *) Check list nat : s3'.type _. Check Datatypes_list__canonical__two_hier_s3'. Check list (list nat) : s3'.type _.math-comp-hierarchy-builder-4d8a939/tests/type_of_exported_ops.v000066400000000000000000000015431521677141400251520ustar00rootroot00000000000000From HB Require Import structures. Definition comb A op := forall x : A, op (op x) = x. HB.mixin Record Foo A := { op : A -> A; ax : comb A op }. HB.structure Definition S := { A of Foo A }. Set Printing All. Lemma test1 : True. Proof. pose proof @ax as H. match goal with | H : forall x : S.type, comb (S.sort x) op |- _ => trivial | H : ?T |- _ => fail "type of ax not as nice as expected:" T end. Qed. HB.mixin Record HasMul T := { mul : T -> T -> T; mulC: forall x y : T, mul x y = mul y x; mulA: forall x y z : T, mul x (mul y z) = mul (mul x y) z; }. HB.structure Definition Mul := { T of HasMul T }. Lemma test2 : True. Proof. pose proof @mulA as H. match goal with | H : forall s : Mul.type, forall x y z : Mul.sort s, mul x (mul y z) = mul (mul x y) z |- _ => trivial | H : ?T |- _ => fail "type of mulA not as nice as expected:" T end. Qed. math-comp-hierarchy-builder-4d8a939/tests/unimported_irrelevant_class.v000066400000000000000000000006411521677141400265160ustar00rootroot00000000000000From HB Require Import structures. Module A. HB.mixin Record isA T := {}. HB.structure Definition A := {T of isA T}. End A. HB.mixin Record isB T := {}. HB.structure Definition B := {T of isB T}. Module Export C. Import A. HB.mixin Record isC T & A T & B T := {}. HB.structure Definition C := {T of isB T & isA T & isC T}. End C. (* Should not fail: A is irrelevant *) HB.instance Definition _ := isB.Build unit. math-comp-hierarchy-builder-4d8a939/tests/unimported_relevant_class.v000066400000000000000000000005531521677141400261650ustar00rootroot00000000000000From HB Require Import structures. Module A. HB.mixin Record isA T := {}. HB.structure Definition A := {T of isA T}. End A. Module Export B. Import A. HB.factory Record isB T := {}. HB.builders Context T & isB T. HB.instance Definition _ := isA.Build T. HB.end. End B. (* legitimate failure: A is relevant *) Fail HB.instance Definition _ := isB.Build unit. math-comp-hierarchy-builder-4d8a939/tests/unit/000077500000000000000000000000001521677141400214775ustar00rootroot00000000000000math-comp-hierarchy-builder-4d8a939/tests/unit/close_hole_term.v000066400000000000000000000016421521677141400250340ustar00rootroot00000000000000From HB Require Import structures. From elpi Require Import elpi. From Corelib Require Export Setoid. Elpi Query HB.instance lp:{{ X = app [{{list}}, Y_], % X needs to be typechecked here to get rid of the hole for the type of Y coq.typecheck X _ ok, abstract-holes.main X Z, std.assert! (Z = {{fun x => list x}}) "term badly closed" }}. Elpi Query HB.instance lp:{{ abstract-holes.main {{nat}} Z, std.assert! (Z = {{nat}}) "term badly closed" }}. Class Inj {A B} (R : relation A) (S : relation B) (f : A -> B) : Prop := inj x y : S (f x) (f y) -> R x y. Elpi Query HB.structure lp:{{ Y = {{Inj}}, %Inj has 5 implicit arguments saturate-type-constructor Y X, % X needs to be typechecked here to get rid of the holes of the types of its arguments coq.typecheck X _ ok, abstract-holes.main X Z, std.assert! (Z = {{ fun a b c d e => @Inj a b c d e }}) "term badly closed" }}. math-comp-hierarchy-builder-4d8a939/tests/unit/enrich_type.v000066400000000000000000000015561521677141400242060ustar00rootroot00000000000000From HB Require Import structures. From elpi Require Import elpi. From Corelib Require Export Setoid. Elpi Query HB.structure lp:{{ saturate-type-constructor {{nat}} X, std.assert! (X = {{nat}}) "wrong enriched type" }}. Elpi Query HB.structure lp:{{ saturate-type-constructor {{list}} X, std.assert! (X = app [{{list}}, Y_]) "wrong enriched type" }}. Elpi Query HB.structure lp:{{ Y = (x \ (y \ {{(prod (list lp:x) (list lp:y))}})), saturate-type-constructor (Y _ _) X, std.assert! (X = (app [{{prod}}, (app[{{list}},X1_]), app[{{list}},C_]])) "wrong enriched type" }}. Class Inj {A B} (R : relation A) (S : relation B) (f : A -> B) : Prop := inj x y : S (f x) (f y) -> R x y. Elpi Query HB.structure lp:{{ saturate-type-constructor {{Inj}} X, std.assert! (X = app [(global (const Inj_)), A_, B_, R_, S_, F_]) "wrong enriched type" }}. math-comp-hierarchy-builder-4d8a939/tests/unit/mixin_src_has_mixin_instance.v000066400000000000000000000015131521677141400276040ustar00rootroot00000000000000From HB Require Import structures. From elpi Require Import elpi. HB.mixin Record m1 T := { default1 : T }. HB.mixin Record m2 T := { default2 : T }. HB.structure Definition s1 := { T of m1 T }. HB.instance Definition i1 (X : s1.type) : m1 (list X) := m1.Build (list X) (cons default1 nil). HB.instance Definition nat_m1 : m1 nat := m1.Build nat 1. HB.instance Definition nat_m2 : m2 nat := m2.Build nat 1. Elpi Query HB.instance lp:{{ mixin-src->has-mixin-instance (mixin-src {{nat}} M1_ {{nat_m1}}) Y, Y = has-mixin-instance (cs-gref {{:gref nat}}) {{:gref m1.phant_axioms}} {{:gref nat_m1}}. }}. Section Test. Variable X:s1.type. Elpi Query HB.instance lp:{{ mixin-src->has-mixin-instance (mixin-src {{list X}} M1_ {{i1 X}}) Y, Y = has-mixin-instance (cs-gref {{:gref list}}) {{:gref m1.phant_axioms}} {{:gref i1}}. }}. End Test. math-comp-hierarchy-builder-4d8a939/tests/unit/mk_src_map.v000066400000000000000000000016551521677141400240100ustar00rootroot00000000000000From HB Require Import structures. HB.mixin Record is_foo P A := { op : P -> A -> A }. HB.mixin Record is_foo' P A := { op : P -> A -> A }. HB.instance Definition list_foo P := is_foo.Build P (list P) (fun _ x => x). HB.instance Definition list_foo' P A := is_foo.Build P (list A) (fun _ x => x). Check list_foo'. Check list_foo. Elpi Query HB.structure lp:{{ has-mixin-instance->mixin-src (has-mixin-instance (cs-gref{{:gref list}}) {{:gref is_foo.axioms_}} {{:gref list_foo}}) MS, MS = (pi a b \ mixin-src (app [{{list}}, b]) ({{:gref is_foo.axioms_}}) (app [{{list_foo}}, a]) :- [coq.unify-eq a b ok]) }}. Elpi Query HB.structure lp:{{ has-mixin-instance->mixin-src (has-mixin-instance (cs-gref{{:gref list}}) {{:gref is_foo.axioms_}} {{:gref list_foo'}}) MS', MS' = (pi p a b \ mixin-src (app [{{list}}, b]) {{:gref is_foo.axioms_}} (app [{{list_foo'}}, p,a]) :- [coq.unify-eq a b ok]). }}.math-comp-hierarchy-builder-4d8a939/tests/unit/struct.v000066400000000000000000000023341521677141400232140ustar00rootroot00000000000000From HB Require Import structures. HB.mixin Record m1 T := { default1 : T }. HB.mixin Record m2 T := { default2 : T }. HB.mixin Record is_foo P A := { op : P -> A -> A }. HB.structure Definition foo P := { A of is_foo P A}. HB.structure Definition foo1 := { A of is_foo (option nat) A & m1 A}. Elpi Query HB.structure lp:{{ std.findall (has-mixin-instance _ _ _) H_ }}. (* here we don't have any declared instances but a clause is still created by the system : has-mixin-instance (cs-gref (const «eta»)) (indt «is_foo.axioms_») (const «struct_foo1__to__struct_is_foo») struct_foo1__to__struct_is_foo is an instance created by the system upon structure declaration to allow coercions from foo1 to other structures with the mixin is_foo. *) Print struct_foo1__to__struct_foo. (* its type is forall A : foo1.type, is_foo.axioms_ (option nat) (eta A)) which means it can't serve as a coercion for foo2 or foo3, however foo3 can still be declared because it has another mixin, while foo2 can't because it has the exact same mixins than foo *) Fail HB.structure Definition foo2 := { A of is_foo bool A}. HB.structure Definition foo3 := { A of is_foo bool A & m2 A}. Fail HB.structure Definition fooj := { A of foo1 A & foo3 A}. math-comp-hierarchy-builder-4d8a939/tests_stdlib/000077500000000000000000000000001521677141400220615ustar00rootroot00000000000000math-comp-hierarchy-builder-4d8a939/tests_stdlib/about.v000066400000000000000000000023521521677141400233640ustar00rootroot00000000000000From Coq Require Import ZArith ssrfun ssreflect. From HB Require Import structures. From HB Require Import demo1.hierarchy_5. HB.instance Definition _ := AddAG_of_TYPE.Build Z 0%Z Z.add Z.opp Z.add_assoc Z.add_comm Z.add_0_l Z.add_opp_diag_l. HB.instance Definition _ := Ring_of_TYPE.Build Z 0%Z 1%Z Z.add Z.opp Z.mul Z.add_assoc Z.add_comm Z.add_0_l Z.add_opp_diag_l Z.mul_assoc Z.mul_1_l Z.mul_1_r Z.mul_add_distr_r Z.mul_add_distr_l. (* mixin *) HB.about AddMonoid_of_TYPE. (* mixin constructor *) HB.about AddMonoid_of_TYPE.Build. (* structure *) HB.about AddAG.type. (* class *) HB.about AddMonoid. (* factory *) HB.about Ring_of_AddAG. (* factory constructor *) HB.about Ring_of_AddAG.Build. (* operation *) HB.about add. (* canonical proj/value *) HB.about AddAG.sort. (* canonical value *) HB.about Z. (* coercion *) HB.about hierarchy_5_Ring_class__to__hierarchy_5_SemiRing_class. HB.about hierarchy_5_Ring__to__hierarchy_5_SemiRing. (* builder *) HB.about Builders_40.hierarchy_5_Ring_of_AddAG__to__hierarchy_5_BiNearRing_of_AddMonoid. HB.locate BinNums_Z__canonical__hierarchy_5_AddAG. (* Test minimally qualified names *) Module Import hierarchy_5. Module AddComoid. End AddComoid. End hierarchy_5. HB.about Z. math-comp-hierarchy-builder-4d8a939/tests_stdlib/exports.v000066400000000000000000000055361521677141400237650ustar00rootroot00000000000000From Coq Require Import ssreflect ssrfun ZArith. From HB Require Import structures. Module Enclosing. (**************************************************************************) (* Stage 0: +Ring+ *) (**************************************************************************) HB.mixin Record Ring_of_TYPE A := { zero : A; one : A; add : A -> A -> A; opp : A -> A; mul : A -> A -> A; addrA : associative add; addrC : commutative add; add0r : left_id zero add; addNr : left_inverse zero opp add; mulrA : associative mul; mul1r : left_id one mul; mulr1 : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; }. #[mathcomp] HB.structure Definition Ring := { A of Ring_of_TYPE A }. (* Notations *) Module RingExports. Declare Scope hb_scope. Delimit Scope hb_scope with G. Local Open Scope hb_scope. Notation "0" := zero : hb_scope. Notation "1" := one : hb_scope. Infix "+" := (@add _) : hb_scope. Notation "- x" := (@opp _ x) : hb_scope. Infix "*" := (@mul _) : hb_scope. Notation "x - y" := (x + - y) : hb_scope. End RingExports. HB.export RingExports. (* Theory *) Section Theory. Local Open Scope hb_scope. Variable R : Ring.type. Implicit Type (x : R). Lemma addr0 : right_id (@zero R) add. Proof. by move=> x; rewrite addrC add0r. Qed. HB.export addr0. Lemma addrN : right_inverse (@zero R) opp add. Proof. by move=> x; rewrite addrC addNr. Qed. Lemma subrr x : x - x = 0. Proof. by rewrite addrN. Qed. Lemma addrNK x y : x + y - y = x. Proof. by rewrite -addrA subrr addr0. Qed. End Theory. HB.mixin Record Dummy T := { u : unit }. HB.structure Definition URing := { R of Ring R & Dummy R }. HB.factory Record dummy R & Ring R := {}. HB.builders Context T & dummy T. HB.instance Definition _ := Dummy.Build T tt. Definition addrNK := addrNK. HB.export addrNK. HB.end. Module Import Instances. #[export] HB.instance Definition Z_ring_axioms := Ring_of_TYPE.Build Z 0%Z 1%Z Z.add Z.opp Z.mul Z.add_assoc Z.add_comm Z.add_0_l Z.add_opp_diag_l Z.mul_assoc Z.mul_1_l Z.mul_1_r Z.mul_add_distr_r Z.mul_add_distr_l. Module Exports. HB.reexport Instances. End Exports. End Instances. Module Exports. #[verbose] HB.reexport. End Exports. Module ExportsOnlyInstance. Export Instances.Exports. End ExportsOnlyInstance. End Enclosing. Module Test1. (* We miss the coercions, canonical and elpi metadata *) Fail Check forall (R : Enclosing.Ring.type) (x : R), x = x. Fail Check 0%G. Fail Check addr0. Export Enclosing.Exports. Check forall (R : Enclosing.Ring.type) (x : R), x = x. Check 0%G. Example test1 (m n : Z) : ((m + n) - n + 0 = m)%G. Proof. by rewrite addrNK addr0. Qed. End Test1. Module Test2. Fail Check Enclosing.zero : Z. Export Enclosing.ExportsOnlyInstance. Check Enclosing.zero : Z. Fail Check 0%G. (* notation not there *) End Test2. math-comp-hierarchy-builder-4d8a939/tests_stdlib/exports2.v000066400000000000000000000001741521677141400240400ustar00rootroot00000000000000From HB Require Import structures. From HB Require tests_stdlib.exports. Import exports.Enclosing. #[verbose] HB.reexport. math-comp-hierarchy-builder-4d8a939/tests_stdlib/funclass.v000066400000000000000000000027661521677141400241010ustar00rootroot00000000000000From HB Require Import structures. HB.mixin Record has_assoc T (F : T -> T -> T) := { assoc : forall x y z : T , F x (F y z) = F (F x y) z; }. HB.structure Definition Magma T := { F of has_assoc T F }. HB.mixin Record has_neutral T (F : T -> T -> T) := { id : T; idl : forall x : T , F id x = x; idr : forall x : T , F x id = x; }. HB.structure Definition Monoid T := { F of Magma T F & has_neutral T F }. About id. Require Import Arith ssreflect. HB.instance Definition x1 := has_assoc.Build nat plus Nat.add_assoc. Lemma plus_O_r x : x + 0 = x. Proof. by rewrite -plus_n_O. Qed. HB.instance Definition x2 := has_neutral.Build nat plus 0 plus_O_n plus_O_r. Check Monoid.on plus. Lemma test x : x + 0 = x. Proof. by rewrite idr. Qed. HB.factory Record MOT T (F : T -> T -> T) := { assoc : forall x y z : T , F x (F y z) = F (F x y) z; id : T; idl : forall x : T , F id x = x; commid : forall x : T , F x id = F id x; }. HB.builders Context T F & MOT T F. HB.instance Definition x3 := has_assoc.Build T F assoc. Lemma myidr x : F x id = x. Proof. by rewrite commid idl. Qed. HB.instance Definition x4 := has_neutral.Build T F id idl myidr. HB.end. HB.instance Definition x5 := MOT.Build nat mult Nat.mul_assoc 1 Nat.mul_1_l (fun x => Nat.mul_comm x 1). Check Monoid.on mult. HB.mixin Record silly (T1 : Type) (F : Monoid.type T1) (T : Type) := { xx : T }. HB.structure Definition wp T (F : Monoid.type T) := { A of silly T F A }. #[skip="8.11"] HB.check (forall w : wp.type _ mult, w = w). math-comp-hierarchy-builder-4d8a939/tests_stdlib/howto.v000066400000000000000000000012731521677141400234130ustar00rootroot00000000000000From Coq Require Import ZArith ssrfun ssreflect. From HB Require Import structures. From HB Require Import demo1.hierarchy_5. HB.howto Ring.type. HB.howto Ring.type 2. HB.howto Z Ring.type. HB.howto Z Ring.type 2. Fail HB.howto Z Ring.type 0. HB.howto AddComoid.type Ring.type. HB.instance Definition _ := AddAG_of_TYPE.Build Z 0%Z Z.add Z.opp Z.add_assoc Z.add_comm Z.add_0_l Z.add_opp_diag_l. HB.howto Z Ring.type. HB.howto AddAG.type Ring.type. HB.instance Definition _ := Ring_of_TYPE.Build Z 0%Z 1%Z Z.add Z.opp Z.mul Z.add_assoc Z.add_comm Z.add_0_l Z.add_opp_diag_l Z.mul_assoc Z.mul_1_l Z.mul_1_r Z.mul_add_distr_r Z.mul_add_distr_l. HB.howto Z Ring.type.