bat-0.19.0/.cargo_vcs_info.json0000644000000001360000000000100116710ustar { "git": { "sha1": "59a8f58be780ba9ba04eb4791b6bf5ca14e99e99" }, "path_in_vcs": "" }bat-0.19.0/.github/.codecov.yml000064400000000000000000000000170072674642500142720ustar 00000000000000comment: false bat-0.19.0/.github/FUNDING.yml000064400000000000000000000000470072674642500136670ustar 00000000000000github: [sharkdp, keith-hall, Enselic] bat-0.19.0/.github/ISSUE_TEMPLATE/bug_report.md000064400000000000000000000020710072674642500167260ustar 00000000000000--- name: Bug Report about: Report a bug. title: "" labels: bug assignees: '' --- **Describe the bug you encountered:** ... **What did you expect to happen instead?** ... **How did you install `bat`?** --- **bat version and environment** bat-0.19.0/.github/ISSUE_TEMPLATE/config.yml000064400000000000000000000000330072674642500162200ustar 00000000000000blank_issues_enabled: true bat-0.19.0/.github/ISSUE_TEMPLATE/feature_request.md000064400000000000000000000001710072674642500177600ustar 00000000000000--- name: Feature Request about: Suggest an idea for this project. title: '' labels: feature-request assignees: '' --- bat-0.19.0/.github/ISSUE_TEMPLATE/question.md000064400000000000000000000001450072674642500164250ustar 00000000000000--- name: Question about: Ask a question about 'bat'. title: '' labels: question assignees: '' --- bat-0.19.0/.github/ISSUE_TEMPLATE/syntax_request.md000064400000000000000000000012270072674642500176560ustar 00000000000000--- name: Syntax Request about: Request adding a new syntax to bat. title: "" labels: syntax-request assignees: '' --- **Syntax:** [Name or description of the syntax/language here] **Guideline Criteria:** [packagecontro.io link here] bat-0.19.0/.github/dependabot.yml000064400000000000000000000005230072674642500147010ustar 00000000000000version: 2 updates: - package-ecosystem: cargo directory: "/" schedule: interval: monthly time: "04:00" timezone: Europe/Berlin ignore: - dependency-name: git2 versions: - 0.13.17 - package-ecosystem: gitsubmodule directory: "/" schedule: interval: monthly time: "04:00" timezone: Europe/Berlin bat-0.19.0/.github/workflows/CICD.yml000064400000000000000000000440470072674642500153440ustar 00000000000000name: CICD env: MIN_SUPPORTED_RUST_VERSION: "1.51.0" CICD_INTERMEDIATES_DIR: "_cicd-intermediates" on: workflow_dispatch: pull_request: push: branches: - master tags: - '*' jobs: ensure_cargo_fmt: name: Ensure 'cargo fmt' has been run runs-on: ubuntu-20.04 steps: - uses: actions-rs/toolchain@v1 with: toolchain: stable default: true profile: minimal components: rustfmt - uses: actions/checkout@v2 - run: cargo fmt -- --check license_checks: name: License checks runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v2 with: submodules: true # we especially want to perform license checks on submodules - run: tests/scripts/license-checks.sh min_version: name: Minimum supported rust version runs-on: ubuntu-20.04 steps: - name: Checkout source code uses: actions/checkout@v2 - name: Install rust toolchain (v${{ env.MIN_SUPPORTED_RUST_VERSION }}) uses: actions-rs/toolchain@v1 with: toolchain: ${{ env.MIN_SUPPORTED_RUST_VERSION }} default: true profile: minimal # minimal component installation (ie, no documentation) components: clippy - name: Run clippy (on minimum supported rust version to prevent warnings we can't fix) uses: actions-rs/cargo@v1 with: command: clippy args: --locked --all-targets --all-features - name: Run tests uses: actions-rs/cargo@v1 with: command: test args: --locked test_with_new_syntaxes_and_themes: name: Run tests with updated syntaxes and themes runs-on: ubuntu-20.04 steps: - name: Git checkout uses: actions/checkout@v2 with: submodules: true # we need all syntax and theme submodules - name: Install Rust toolchain uses: actions-rs/toolchain@v1 with: toolchain: stable default: true profile: minimal - name: Build and install bat uses: actions-rs/cargo@v1 with: command: install args: --locked --path . - name: Rebuild binary assets (syntaxes and themes) run: bash assets/create.sh - name: Build and install bat with updated assets uses: actions-rs/cargo@v1 with: command: install args: --locked --path . - name: Run unit tests with new syntaxes and themes uses: actions-rs/cargo@v1 with: command: test args: --locked --release - name: Run ignored-by-default unit tests with new syntaxes and themes uses: actions-rs/cargo@v1 with: command: test args: --locked --release -- --ignored - name: Syntax highlighting regression test run: tests/syntax-tests/regression_test.sh - name: List of languages run: bat --list-languages - name: List of themes run: bat --list-themes - name: Test custom assets run: tests/syntax-tests/test_custom_assets.sh documentation: name: Documentation runs-on: ubuntu-20.04 steps: - name: Git checkout uses: actions/checkout@v2 - name: Install Rust toolchain uses: actions-rs/toolchain@v1 with: toolchain: stable default: true profile: minimal - name: Check documentation env: RUSTDOCFLAGS: -D warnings uses: actions-rs/cargo@v1 with: command: doc args: --locked --no-deps --document-private-items --all-features build: name: ${{ matrix.job.target }} (${{ matrix.job.os }}) runs-on: ${{ matrix.job.os }} strategy: fail-fast: false matrix: job: - { target: aarch64-unknown-linux-gnu , os: ubuntu-20.04, use-cross: true } - { target: arm-unknown-linux-gnueabihf , os: ubuntu-20.04, use-cross: true } - { target: arm-unknown-linux-musleabihf, os: ubuntu-20.04, use-cross: true } - { target: i686-pc-windows-msvc , os: windows-2019 } - { target: i686-unknown-linux-gnu , os: ubuntu-20.04, use-cross: true } - { target: i686-unknown-linux-musl , os: ubuntu-20.04, use-cross: true } - { target: x86_64-apple-darwin , os: macos-10.15 } - { target: x86_64-pc-windows-gnu , os: windows-2019 } - { target: x86_64-pc-windows-msvc , os: windows-2019 } - { target: x86_64-unknown-linux-gnu , os: ubuntu-20.04 } - { target: x86_64-unknown-linux-musl , os: ubuntu-20.04, use-cross: true } steps: - name: Checkout source code uses: actions/checkout@v2 - name: Install prerequisites shell: bash run: | case ${{ matrix.job.target }} in arm-unknown-linux-*) sudo apt-get -y update ; sudo apt-get -y install gcc-arm-linux-gnueabihf ;; aarch64-unknown-linux-gnu) sudo apt-get -y update ; sudo apt-get -y install gcc-aarch64-linux-gnu ;; esac - name: Extract crate information shell: bash run: | echo "PROJECT_NAME=$(sed -n 's/^name = "\(.*\)"/\1/p' Cargo.toml | head -n1)" >> $GITHUB_ENV echo "PROJECT_VERSION=$(sed -n 's/^version = "\(.*\)"/\1/p' Cargo.toml | head -n1)" >> $GITHUB_ENV echo "PROJECT_MAINTAINER=$(sed -n 's/^authors = \["\(.*\)"\]/\1/p' Cargo.toml)" >> $GITHUB_ENV echo "PROJECT_HOMEPAGE=$(sed -n 's/^homepage = "\(.*\)"/\1/p' Cargo.toml)" >> $GITHUB_ENV - name: Install Rust toolchain uses: actions-rs/toolchain@v1 with: toolchain: stable target: ${{ matrix.job.target }} override: true profile: minimal # minimal component installation (ie, no documentation) - name: Show version information (Rust, cargo, GCC) shell: bash run: | gcc --version || true rustup -V rustup toolchain list rustup default cargo -V rustc -V - name: Build uses: actions-rs/cargo@v1 with: use-cross: ${{ matrix.job.use-cross }} command: build args: --locked --release --target=${{ matrix.job.target }} - name: Strip debug information from executable id: strip shell: bash run: | # Figure out suffix of binary EXE_suffix="" case ${{ matrix.job.target }} in *-pc-windows-*) EXE_suffix=".exe" ;; esac; # Figure out what strip tool to use if any STRIP="strip" case ${{ matrix.job.target }} in arm-unknown-linux-*) STRIP="arm-linux-gnueabihf-strip" ;; aarch64-unknown-linux-gnu) STRIP="aarch64-linux-gnu-strip" ;; *-pc-windows-msvc) STRIP="" ;; esac; # Setup paths BIN_DIR="${{ env.CICD_INTERMEDIATES_DIR }}/stripped-release-bin/" mkdir -p "${BIN_DIR}" BIN_NAME="${{ env.PROJECT_NAME }}${EXE_suffix}" BIN_PATH="${BIN_DIR}/${BIN_NAME}" # Copy the release build binary to the result location cp "target/${{ matrix.job.target }}/release/${BIN_NAME}" "${BIN_DIR}" # Also strip if possible if [ -n "${STRIP}" ]; then "${STRIP}" "${BIN_PATH}" fi # Let subsequent steps know where to find the (stripped) bin echo ::set-output name=BIN_PATH::${BIN_PATH} echo ::set-output name=BIN_NAME::${BIN_NAME} - name: Set testing options id: test-options shell: bash run: | # test only library unit tests and binary for arm-type targets unset CARGO_TEST_OPTIONS unset CARGO_TEST_OPTIONS ; case ${{ matrix.job.target }} in arm-* | aarch64-*) CARGO_TEST_OPTIONS="--lib --bin ${PROJECT_NAME}" ;; esac; echo ::set-output name=CARGO_TEST_OPTIONS::${CARGO_TEST_OPTIONS} - name: Run tests uses: actions-rs/cargo@v1 with: use-cross: ${{ matrix.job.use-cross }} command: test args: --locked --target=${{ matrix.job.target }} ${{ steps.test-options.outputs.CARGO_TEST_OPTIONS}} - name: Run bat uses: actions-rs/cargo@v1 with: use-cross: ${{ matrix.job.use-cross }} command: run args: --locked --target=${{ matrix.job.target }} -- --paging=never --color=always --theme=ansi Cargo.toml src/config.rs - name: Show diagnostics (bat --diagnostic) uses: actions-rs/cargo@v1 with: use-cross: ${{ matrix.job.use-cross }} command: run args: --locked --target=${{ matrix.job.target }} -- --paging=never --color=always --theme=ansi Cargo.toml src/config.rs --diagnostic - name: "Feature check: regex-onig" uses: actions-rs/cargo@v1 with: use-cross: ${{ matrix.job.use-cross }} command: check args: --locked --target=${{ matrix.job.target }} --verbose --lib --no-default-features --features regex-onig - name: "Feature check: regex-onig,git" uses: actions-rs/cargo@v1 with: use-cross: ${{ matrix.job.use-cross }} command: check args: --locked --target=${{ matrix.job.target }} --verbose --lib --no-default-features --features regex-onig,git - name: "Feature check: regex-onig,paging" uses: actions-rs/cargo@v1 with: use-cross: ${{ matrix.job.use-cross }} command: check args: --locked --target=${{ matrix.job.target }} --verbose --lib --no-default-features --features regex-onig,paging - name: "Feature check: regex-onig,git,paging" uses: actions-rs/cargo@v1 with: use-cross: ${{ matrix.job.use-cross }} command: check args: --locked --target=${{ matrix.job.target }} --verbose --lib --no-default-features --features regex-onig,git,paging - name: "Feature check: minimal-application" uses: actions-rs/cargo@v1 with: use-cross: ${{ matrix.job.use-cross }} command: check args: --locked --target=${{ matrix.job.target }} --verbose --no-default-features --features minimal-application - name: Create tarball id: package shell: bash run: | PKG_suffix=".tar.gz" ; case ${{ matrix.job.target }} in *-pc-windows-*) PKG_suffix=".zip" ;; esac; PKG_BASENAME=${PROJECT_NAME}-v${PROJECT_VERSION}-${{ matrix.job.target }} PKG_NAME=${PKG_BASENAME}${PKG_suffix} echo ::set-output name=PKG_NAME::${PKG_NAME} PKG_STAGING="${{ env.CICD_INTERMEDIATES_DIR }}/package" ARCHIVE_DIR="${PKG_STAGING}/${PKG_BASENAME}/" mkdir -p "${ARCHIVE_DIR}" mkdir -p "${ARCHIVE_DIR}/autocomplete" # Binary cp "${{ steps.strip.outputs.BIN_PATH }}" "$ARCHIVE_DIR" # Man page cp 'target/${{ matrix.job.target }}/release/build/${{ env.PROJECT_NAME }}'-*/out/assets/manual/bat.1 "$ARCHIVE_DIR" # README, LICENSE and CHANGELOG files cp "README.md" "LICENSE-MIT" "LICENSE-APACHE" "CHANGELOG.md" "$ARCHIVE_DIR" # Autocompletion files cp 'target/${{ matrix.job.target }}/release/build/${{ env.PROJECT_NAME }}'-*/out/assets/completions/bat.bash "$ARCHIVE_DIR/autocomplete/${{ env.PROJECT_NAME }}.bash" cp 'target/${{ matrix.job.target }}/release/build/${{ env.PROJECT_NAME }}'-*/out/assets/completions/bat.fish "$ARCHIVE_DIR/autocomplete/${{ env.PROJECT_NAME }}.fish" cp 'target/${{ matrix.job.target }}/release/build/${{ env.PROJECT_NAME }}'-*/out/assets/completions/_bat.ps1 "$ARCHIVE_DIR/autocomplete/_${{ env.PROJECT_NAME }}.ps1" cp 'target/${{ matrix.job.target }}/release/build/${{ env.PROJECT_NAME }}'-*/out/assets/completions/bat.zsh "$ARCHIVE_DIR/autocomplete/${{ env.PROJECT_NAME }}.zsh" # base compressed package pushd "${PKG_STAGING}/" >/dev/null case ${{ matrix.job.target }} in *-pc-windows-*) 7z -y a "${PKG_NAME}" "${PKG_BASENAME}"/* | tail -2 ;; *) tar czf "${PKG_NAME}" "${PKG_BASENAME}"/* ;; esac; popd >/dev/null # Let subsequent steps know where to find the compressed package echo ::set-output name=PKG_PATH::"${PKG_STAGING}/${PKG_NAME}" - name: Create Debian package id: debian-package shell: bash if: startsWith(matrix.job.os, 'ubuntu') run: | COPYRIGHT_YEARS="2018 - "$(date "+%Y") DPKG_STAGING="${{ env.CICD_INTERMEDIATES_DIR }}/debian-package" DPKG_DIR="${DPKG_STAGING}/dpkg" mkdir -p "${DPKG_DIR}" DPKG_BASENAME=${PROJECT_NAME} DPKG_CONFLICTS=${PROJECT_NAME}-musl case ${{ matrix.job.target }} in *-musl) DPKG_BASENAME=${PROJECT_NAME}-musl ; DPKG_CONFLICTS=${PROJECT_NAME} ;; esac; DPKG_VERSION=${PROJECT_VERSION} unset DPKG_ARCH case ${{ matrix.job.target }} in aarch64-*-linux-*) DPKG_ARCH=arm64 ;; arm-*-linux-*hf) DPKG_ARCH=armhf ;; i686-*-linux-*) DPKG_ARCH=i686 ;; x86_64-*-linux-*) DPKG_ARCH=amd64 ;; *) DPKG_ARCH=notset ;; esac; DPKG_NAME="${DPKG_BASENAME}_${DPKG_VERSION}_${DPKG_ARCH}.deb" echo ::set-output name=DPKG_NAME::${DPKG_NAME} # Binary install -Dm755 "${{ steps.strip.outputs.BIN_PATH }}" "${DPKG_DIR}/usr/bin/${{ steps.strip.outputs.BIN_NAME }}" # Man page install -Dm644 'target/${{ matrix.job.target }}/release/build/${{ env.PROJECT_NAME }}'-*/out/assets/manual/bat.1 "${DPKG_DIR}/usr/share/man/man1/${{ env.PROJECT_NAME }}.1" gzip -n --best "${DPKG_DIR}/usr/share/man/man1/${{ env.PROJECT_NAME }}.1" # Autocompletion files install -Dm644 'target/${{ matrix.job.target }}/release/build/${{ env.PROJECT_NAME }}'-*/out/assets/completions/bat.bash "${DPKG_DIR}/usr/share/bash-completion/completions/${{ env.PROJECT_NAME }}" install -Dm644 'target/${{ matrix.job.target }}/release/build/${{ env.PROJECT_NAME }}'-*/out/assets/completions/bat.fish "${DPKG_DIR}/usr/share/fish/vendor_completions.d/${{ env.PROJECT_NAME }}.fish" install -Dm644 'target/${{ matrix.job.target }}/release/build/${{ env.PROJECT_NAME }}'-*/out/assets/completions/bat.zsh "${DPKG_DIR}/usr/share/zsh/vendor-completions/_${{ env.PROJECT_NAME }}" # README and LICENSE install -Dm644 "README.md" "${DPKG_DIR}/usr/share/doc/${DPKG_BASENAME}/README.md" install -Dm644 "LICENSE-MIT" "${DPKG_DIR}/usr/share/doc/${DPKG_BASENAME}/LICENSE-MIT" install -Dm644 "LICENSE-APACHE" "${DPKG_DIR}/usr/share/doc/${DPKG_BASENAME}/LICENSE-APACHE" install -Dm644 "CHANGELOG.md" "${DPKG_DIR}/usr/share/doc/${DPKG_BASENAME}/changelog" gzip -n --best "${DPKG_DIR}/usr/share/doc/${DPKG_BASENAME}/changelog" cat > "${DPKG_DIR}/usr/share/doc/${DPKG_BASENAME}/copyright" < "${DPKG_DIR}/DEBIAN/control" <…` option to overwrite the displayed filename(s) in the header. This is useful when piping input into `bat`. See #654 and #892 (@neuronull). - Added a new `--generate-config-file` option to create an initial configuration file at the right place. See #870 (@jmick414) ## Bugfixes - Performance problems with C# source code have been fixed, see #677 (@keith-hall) - Performance problems with Makefiles have been fixed, see #750 (@keith-hall) - Fix bug when highlighting Ruby files with unindented heredocs, see #914 (@keith-hall) - A highlighting problem with Rust source code has been fixed, see #924 (@keith-hall) - Windows: short files that do not require paging are displayed and then lost, see #887 - `--highlight-line` did not work correctly in combination with `--tabs=0` and `--wrap=never`, see #937 ## Other - When saving/reading user-provided syntaxes or themes, `bat` will now maintain a `metadata.yaml` file which includes information about the `bat` version which was used to create the cached files. When loading cached files, we now print an error if they have been created with an incompatible version. See #882 - Updated `liquid` dependency to 0.20, see #880 (@ignatenkobrain) ## `bat` as a library - A completely new "high level" API has been added that is much more convenient to use. See the `examples` folder for the updated code. The older "low level" API is still available (basically everything that is not in the root `bat` module), but has been refactored quite a bit. It is recommended to only use the new "high level" API, if possible. This will be much easier to keep stable. Note that this should still be considered a "beta" release of `bat`-as-a-library. For more details and some screenshots of the example programs, see #936. - Stripped out a lot of binary-only dependencies, see #895 and #899 (@dtolnay) This introduces a `features = ["application"]` which is enabled by default and pulls in everything required by `bat` the application. When depending on bat as a library, downstream `Cargo.toml` should disable this feature to cut out inapplicable heavy dependencies: ``` toml [dependencies] bat = { version = "0.14", default-features = false } ``` Other optional functionality has also been put behind features: `paging` and `git` support. - Allow using the library with older syntect, see #896 and #898 (@dtolnay) ## New syntaxes - Rego, see #872 (@patrick-east) - Stylo, see #917 # v0.13.0 ## `bat` as a library Beginning with this release, `bat` can be used as a library (#423). This was a huge effort and I want to thank all people who made this possible: @DrSensor, @mitsuhiko, @mre, @eth-p! - Initial attempt in #469 (@mitsuhiko) - Second attempt, complete restructuring of the `bat` crate, see #679 (@DrSensor) - Updates to example, public API, error handling, further refactoring: #693 #873 #875 (@sharkdp) I want to stress that this is the very first release of the library. Things are very likely to change. A lot of things are still missing (including the documentation). That being said, you can start using it! See the example programs in [`examples/`](https://github.com/sharkdp/bat/tree/master/examples). You can see the API documentation here: https://docs.rs/bat/ ## Features - (**Breaking change**) Glob-based syntax mapping, see #877 and #592. With this change, users need to update their bat config files (`bat --config-file`), if they have any `--map-syntax` settings present. The option now works like this: ```bash --map-syntax : ``` For more information, see the `--help` text, the man page or the README. This new feature allows us to properly highlight files like: * `/etc/profile` * `~/.ssh/config` - `--highlight-line` now accepts line ranges, see #809 (@lkalir) - Proper wrapping support for output with wide Unicode characters, see #811 #787 and #815 (@Kogia-sima) - A lot of updates to existing syntaxes via #644 (@benwaffle, @keith-hall) - `BAT_CACHE_PATH` can be used to place cached `bat` assets in a non-standard path, see #829 (@neuronull) - Support combination of multiple styles at the same time, see #857 (@aslpavel) ## Bugfixes - Do not pass '--no-init' on newer less versions, see #749 and #786 (@sharkdp) - 'bat cache' still takes precedence over existing files, see #666 (@sharkdp) - `.sc` files should be treated as scala files, see #443 (@benwaffle) - Allow underscores and dashes in page names, see #670 (@LunarLambda) - Keep empty lines empty, see #601 (@mbarbar) - Wrapping does not work when piping, see #758 (@fusillicode, @allevo, @gildo) - Allow for non-unicode filenames, see #225 (@sharkdp) - Empty file without header produces incomplete grid, see #798 (@eth-p) - Files named `build` don't respect shebang lines, see #685 (@sharkdp) ## Other - Parametrizable names for man page and shell completion files, see #659 #673 #656 (@eth-p) - Enabled LTO, making `bat` about 10% faster, see #719 (@bolinfest, @sharkdp) - Suggestions non how to configure `bat` for MacOS dark mode, see README (@jerguslejko) - Extended ["Integration with other tools"](https://github.com/sharkdp/bat#integration-with-other-tools) section (@eth-p) - Updated [instrutions on how to use `bat` as a `man`-pager](https://github.com/sharkdp/bat#man), see #652, see #667 (@sharkdp) - Add section concerning file encodings, see #688 and #568 (@sharkdp) - Updated sort order of command-line options in `--help` text and manpage, see #653 and #700 (@hrlmartins) - Updates to the man page syntax, see #718 (@sharkdp) - Japanese documentation updates, see #863 (@k-ta-yamada, @sorairolake and @wt-l00) - Accept "default" as a theme, see #757 (@fvictorio) - Updated Windows installation instructions, see #852 (@sorenbug) - Updated man page, see #573 (@sharkdp) ## New syntaxes - Jinja2, see #648 (@Martin819) - SaltStack SLS, see #658 (@Martin819) - `/etc/fstab`, see #696 (@flopp and @eth-p) - `/etc/group` and `/etc/passwd`, see #698 (@argentite) - `/proc/cpuinfo` and `/proc/meminfo`, see #593 (@sharkdp) - Nim, see #542 (@sharkdp) - Vue, see #826 (@chaaaaarlotte) - CoffeScript, see #833 (@sharkdp) ## New themes - Dracula, see #687 (@clarfon) - Nord, see #760 (@crabique) - Solarized light and dark, see #768 (@hakamadare) ## Packaging - `bat` is now in the official Ubuntu and Debian repositories, see #323 and #705 (@MarcoFalke) - `bat` can now be installed via MacPorts, see #675 (@bn3t) - Install fish completions into 'vendor_completions.d', see #651 (@sharkdp) ## Thanks - To @eth-p for joining me as a maintainer! I'm very grateful for all the work you put into managing and responding to issues, improving our deployment, adding PR/issue templates (#837) as well as fixing bugs and implementing new features. # v0.12.1 ## Bugfixes - Fixes a bug for older Windows versions (*"The procedure entry point `CreateFile2` could not be located"*), see #643 (@rivy) # v0.12.0 ## Features - Binary file content can now be viewed with `bat -A`, see #623, #640 (@pjsier and @sharkdp) - `bat` can now be used as a man pager. Take a look at the README and #523 for more details. - Add new style component to separate multiple `--line-range`s, see #570 (@eth-p) - Added `-L` as an alias for `--list-languages` ## Bugfixes - Output looks unbalanced when using '--style=grid,numbers' without 'header', see #571 (@eth-p) - issues with filenames starting with "cache", see #584 - Can't build cache with new theme without creating cache dir, see #576 (@frm) - `--terminal-width -10` is parsed incorrectly, see #611 ## Other - Added fish completions to DEB package, see #554 ## New syntaxes - Emacs Org mode, see #36 (@bricewge) - `requirements.txt` - DotENV `.env` - SSH config syntax (`-l ssh_config`), see #582 (@issmirnov) - `/etc/hosts`, see #583 (@issmirnov) - GraphQL, see #625 (@dandavison) - Verilog, see #616 - SCSS and Sass, see #637 - `strace` syntax, see #599 ## Packaging - `bat` is now in the official Gentoo repositories, see #588 (@toku-sa-n) - `bat` is now in the official Alpine Linux repositories, see #586 (@5paceToast) - `bat` is in the official Fedora repositories, see #610 (@ignatenkobrain) # v0.11.0 ## Features - Three new special color themes are available: `ansi-light`, `ansi-dark` and `base16`. These are useful for people that often switch from dark to light themes in their terminal emulator or for people that want the colors to match their terminal theme colors. For more details, see #543 and #490 (@mk12, implementation idea by @trishume) - Hand-written auto completion script for Fish shell, see #524 and #555 (@ev-dev and @eth-p) - The `-p`/`--plain` option can now be used twice (typically `-pp`). The first `-p` switches the `--style` to "plain". The second `-p` disables the pager. See #560 and #552 (@eth-p) ## Bugfixes - Do not replace arguments to `less` when using `--pager`, see #509 - Binary files will now be indicated by a warning in interactive mode, see #530 #466 #550 (@maxfilov) - Empty files are (once again) printed with a single header line, see #504 and #566 (@reidwagner and @sharkdp) - `--terminal-width=0` is now disallowed, see #559 (@eth-p) - Accidental printing of files named `cache`, see #557 ## Other - New integration tests, see #500 and #502 (@reidwagner and @sharkdp) - New ["Integration with other tools"](https://github.com/sharkdp/bat#integration-with-other-tools) section in the README. - Migrated to Rust 2018 (@expobrain) ## New syntaxes - F# syntax has been updated, see #531 (@stroborobo) - Fish shell, see #548 (@sanga) ## Packaging - `bat` is now available on Chocolatey, see #541 (@rasmuskriest) # v0.10.0 ## Features - Added new `--highlight-line ` option, see #453, #346 and #175 (@tskinn and @sharkdp) ## Changes - **Change the default configuration directory on macOS** to `~/.config/bat`, see #442 (@lavifb). If you are on macOS, you need to copy your configuration directory from the previous place (`~/Library/Preferences/bat`) to the new place (`~/.config/bat`). - Completely disabled the generation of shell completion files, see #372 - Properly set arguments to `less` if `PAGER` environment variable contains something like `less -F` (which is missing the `-R` option), see #430 (@majecty) - Report the name of missing files, see #444 (@ufuji1984) - Don't start pager if file doesn't exist, see #387 - Rename `bat cache --init` to `bat cache --build`, see #498 - Move the `--config-dir` and `--cache-dir` options from `bat cache` to `bat` and hide them from the help text. ## Bugfixes - Blank line at the end of output when using `--style=plain`, see #379 - EOF must be sent twice on stdin if no other input is sent, see #477 (@reidwagner) ## New syntaxes - Twig (@ahmedelgabri) - `.desktop` files (@jleclanche) - AsciiDoc (@markusthoemmes) - Assembly (x86_64 and ARM) - Log files (@caos21) - Protobuf and ProtobufText (@caos21) - Terraform (@caos21) - Jsonnet (@hfm) - Varlink (@haraldh) ## Other - Added Japanese version of README (@sh-tech and @object1037) - Code improvements (@barskern) # v0.9.0 ## Features - A new `-A`/`--show-all` option has been added to show and highlight non-printable characters (in analogy to GNU `cat`s option): ![](https://camo.githubusercontent.com/c3e769482ef3184f6be6adaa34bdc8d19c378254/68747470733a2f2f692e696d6775722e636f6d2f324b54486859542e706e67) see #395 and #381 for more details. - Added `--pager` option (to configure the pager from the configuration file), see #362 (@majecty) - Added `BAT_CONFIG_PATH` environment variable to set a non-default path for `bat`s configuration file, see #375 (@deg4uss3r) - Allow for multiple occurrences of `--style` to allow for the configuration of styles from the config file, see #367 (@sindreij) - Allow for multiple `--line-range` arguments, see #23 - The `--terminal-width` option can now also accept offsets, see #376 ## Changes - Use of italics is now *disabled by default* (see #389 for details). They can be re-enabled by adding `--italic-text=always` to your configuration file. - The default tab-width has been set to 4. - Added new "Sublime Snazzy" theme. - Shell completions are currently *not* shipped anymore, see #372 for details. ## Bugfixes - Avoid endless recursion when `PAGER="bat"`, see #383 (@rodorgas) ## Other - `bat` is now available on openSUSE, see #405 (@dmarcoux) - Added section about the new configuration file in the README (@deg4uss3r) - Chinese translation of README (@chinanf-boy) - Re-written tests for `--tabs` (@choznerol) - Speed up integration tests, see #394 # v0.8.0 ## Features - Support for a configuration file with the following simple format: ```bash --tabs=4 --theme="Sublime Snazzy" # A line-comment --map-syntax .ignore:.gitignore --map-syntax PKGBUILD:bash --map-syntax Podfile:ruby # Flags and options can also be on a single line: --wrap=never --paging=never ``` The configuration file path can be accessed via `bat --config-file`. On Linux, it is stored in `~/.config/bat/config`. - Support for the `BAT_OPTS` environment variable with the same format as specified above (in a single line). This takes precedence over the configuration file. See also #310. - Support for custom syntax mappings via the `-m`/`--max-syntax` option. This allows users to (re)map certain file extensions or file names to an existing syntax: ``` bash bat --map-syntax .config:json ... ``` The option can be use multiple times. Note that you can easily make these mappings permanent by using bats new configuration file. See #169 - Support pager command-line arguments in `PAGER` and `BAT_PAGER`, see #352 (@Foxboron) - Add support for wildcards in Windows CMD, see #309 (@zxey) - First-line syntax detection for all input types, see #205 - Encoding support for UTF-16LE and UTF-16BE, see #285 - New syntaxes: Robot framework (@sanga) ## Changes - Binary files are now detected and not displayed when the output goes to an interactive terminal, see #205 ## Bugfixes - JavaDoc comments break syntax highlighting in .java files, see #81 - Bat Panics on Haskell Source Code, see #314 ## Other - Better `-h` and `--help` texts. - Updated documentation on how to configure `bat`s pager - Updated documentation for light backgrounds, see #328 (@russtaylor) - Generate shell completions during build, see #115 (@davideGiovannini) - A lot of new tests have been written - `bat` is now available via [Termux](https://termux.com/), see #341 (@fornwall) - `bat` is now available via [nix](https://nixos.org/nix), see #344 (@mgttlinger) - `bat` is now available via [Docker](https://hub.docker.com/r/danlynn/bat/), see #331 (@danlynn) # v0.7.1 ## Features - Use the `ansi_colours` package by @mina86 for better true-color approximation on 8 bit color terminals, see #319 and #202. ## Bugfixes - Bat Panics on Haskell Source Code, see #314 - Disable wrapping when `--style=plain`/`-p` is used, see #289 ## Other - Added Ansible install instructions (@aeimer) - Added section about Cygwin to the README (@eth-p) # v0.7.0 ## Features - Tabs are now (optionally) expanded to spaces. This can be controlled with the new `--tabs` command-line option or the `BAT_TABS` environment variable. The new feature also closes two bugs #166 and #184. For more information, see #302 (@eth-p). - Added support for the `BAT_STYLE` environment variable, see #208 (@ms2300) - Added `OneHalf` theme for terminals with a light-gray background, see #256 - Added new syntaxes for CSV, JSX in JavaScript and TypeScript, Cabal, Dart, F#, PureScript, Swift, Crystal, PowerShell (Many Thanks to @tobenna and @mimadrid) ## Changes - Query `git diff` only when needed, see #303 (@ShikChen) - Disable wrapping when `--plain` is used, see #289 (@eth-p) ## Bugfixes - Can read files named `cache`, see #275 (@BK1603) - A lot of bugfixes for Windows, see #252, #264 - Detect `less` reliably and in a portable way, see #271 and #290 (@Aankhen) - last decoration line is not formatted properly with `--wrap never`, see #299 (@Rogach) - Do not show file header for directories, see #292 ## Other - Enabled a new `aarch64` build target, see #258 (@rachitchokshi) - Provide Debian packages for `armhf`, see #280 (@rachitchokshi) - Added README section about "`bat` on Windows" (@Aankhen) - Windows installation via scoop (@meltinglava) # v0.6.1 ## Bugfixes - Fixed panic when running `bat --list-languages | head`, see #232 (@mchlrhw) - Respect `--color` settings for `--list-themes` and `--list-languages`, see #233 - Git modifications now work on Windows ## Other - There will be auto-generated Windows releases, starting with this version (@anykao) # v0.6.0 ## Features - The `--list-themes` option now shows a preview for each highlighting theme (@ms2300) - Added `-p`/`--plain` as an alias for `--style=plain`, see #212 (@ms2300) - Major refactorings, enabling some progress on #150. In non-interactive mode, `bat` will now copy input bytes 1:1. - New languages: Elm, Kotlin, Puppet, TypeScript, see #215 #216 #217 #218 - New syntax highlighting theme: zenburn (@colindean) ## Changes - New themes in `$BAT_CONFIG_DIR/themes` are now loaded *in addition* to the default themes (they may also override), see #172 - The `Default.tmTheme` symlink is not necessary anymore. ## Bugfixes * Using `bat cache --init` leads to duplicated syntaxes, see #206 ## Other * Extended and cleaned-up `--help` text. * Added initial version of a man page, see #52 * New README sections: *Development* and *Troubleshooting*, see #220 # v0.5.0 ## Features - Added `--line-range n:m` option to print a range of lines, see #159 (@tskinn) - The syntax highlighting theme can now be controlled by the `BAT_THEME` environment variable, see [README](https://github.com/sharkdp/bat#highlighting-theme) and #177 (@mandx) - The `PAGER` and `BAT_PAGER` environment variables can be used to control the pager that `bat` uses, see #158 and the [new README section](https://github.com/sharkdp/bat#using-a-different-pager) - Added syntax highlighting for Nix, see #180 - Added syntax highlighting for AWK (Gert Hulselmans) ## Changes - The customization of syntax sets and theme sets is now separated. Syntax definitions are now loaded *in addition* to the ones that are stored in the `bat` binary by default. Please refer to these new sections in the README: [Adding new syntaxes](https://github.com/sharkdp/bat#adding-new-syntaxes--language-definitions), [Adding new themes](https://github.com/sharkdp/bat#adding-new-themes), also see #172 - The color for the filename is now the default foreground color. The colors for the grid and the line numbers is now determined from the syntax highlighting theme, which now also works for light backgrounds, see #178. ## Bugfixes - Escape Sequences get partially stripped, see #182 (@eth-p) - Use separate Git repository for snapshot testing, see #165 and #161 - Markdown breaking on JavaScript, see #183 ## Other - Binaries for armv7 are now provided, see #196 - `bat` is now in the official [Arch package repositories](https://www.archlinux.org/packages/community/x86_64/bat/). - Optimizations in the RGB => 8-bit conversion (@mina86) # v0.4.1 (this is just a small bugfix release, see 0.4.0 for all features and changes) ## Bugfixes - Fix problem with `cargo test` when `bat` is not checked out in a Git repository, see #161 # v0.4.0 ## Features * Support for line-wrapping, see #54 and #102 (@eth-p) * New and updated `--style` parameter, see #74 and README (@pitkley) * Added `--theme` and `--list-themes` options, see #89 (@rleungx) * Added syntax highlighting for: Julia (@iamed2), Dockerfiles, VimL, CMake, INI, Less * Added a few popular Sublime Text highlighting themes, see #133 * Support for bold, italic and underline font styles, see #96 * Support for 32bit systems is now available, see #84 * Added `-u` and `-n` options, see #134 * ANSI color support on Windows 10 ## Changes * The customization folder for own syntaxes has been renamed from `syntax` to `syntaxes`, see README. * Changed Markdown syntax to the default Sublime Text syntax, see #157 * Sorted language listing (@rleungx) * Command line arguments like `--theme` or `--color` can now override themselves. * Improved `--help` text. ## Bugfixes - Fixed crash for (really) small terminal sizes, see #117 (@eth-p) - Syntax detection for `.bashrc`, `CMakeLists.txt` etc., see #100 - Properly handle lines with invalid UTF-8, see #7 (@BrainMaestro) - Better error handling, see #17 (@rleungx and @sharkdp) - Proper handling of UTF-8 characters in `less`, see #98 (@ghuls) - Build fix on nightly, see #148 (@tathanhdinh) ## Other - [Comparison with alternative projects](https://github.com/sharkdp/bat/blob/master/doc/alternatives.md). - New "bat" logo in the README, see #119 (@jraulhernandezi) - Output test cases (@BrainMaestro) - Lots of great refactoring work (@BrainMaestro) # v0.3.0 ## Features * Automatic paging by integrating with `less`, see #29 (@BrainMaestro) * Added support for reading from standard input, see #2 * Added support for writing to non-interactive terminals (pipes, files, ..); new `--color=auto/always/never` option, see #26 (@BrainMaestro) * Added `--list-languages` option to print all available syntaxes, see #69 (@connorkuehl) * New option to specify the syntax via `-l`/`--language`, see #19 (@BrainMaestro) * New option to control the output style (`--style`), see #5 (@nakulcg) * Added syntax highlighting support for TOML files, see #37 ## Changes * The `init-cache` sub-command has been removed. The cache can now be controlled via `bat cache`. See `bat cache -h` for all available commands. ## Bug fixes * Get git repository from file path instead of current directory, see #22 (@nakulcg) * Process substitution can now be used with bat (`bat <(echo a) <(echo b)`), see #80 ## Thanks I'd like to say a big THANK YOU to all contributors and everyone that has given us some form of feedback. Special thanks go to @BrainMaestro for his huge support with new features, bug reports and code reviews! # v0.2.3 - Added a new statically linked version of bat (`..-musl-..`) # v0.2.2 - Remove openssl dependency completely, see #30. # v0.2.1 - Added Elixir syntax, see #25. - Use libcurl-openssl instead of libcurl-gnutls, see #30. # v0.2.0 - Support for custom syntaxes, add 'Markdown extended' theme - Bugfix: Git modifications not shown from child folder # v0.1.0 Initial release bat-0.19.0/CONTRIBUTING.md000064400000000000000000000030660072674642500127470ustar 00000000000000# Contributing Thank you for considering to contribute to `bat`! ## Add an entry to the changelog If your contribution changes the behavior of `bat` (as opposed to a typo-fix in the documentation), please update the [`CHANGELOG.md`](CHANGELOG.md) file and describe your changes. This makes the release process much easier and therefore helps to get your changes into a new `bat` release faster. The top of the `CHANGELOG` contains a *"unreleased"* section with a few subsections (Features, Bugfixes, …). Please add your entry to the subsection that best describes your change. Entries follow this format: ``` - Short description of what has been changed, see #123 (@user) ``` Here, `#123` is the number of the original issue and/or your pull request. Please replace `@user` by your GitHub username. ## Development Please check out the [Development](https://github.com/sharkdp/bat#development) section in the README. ## Adding a new feature Please consider opening a [feature request ticket](https://github.com/sharkdp/bat/issues/new?assignees=&labels=feature-request&template=feature_request.md) first in order to give us a chance to discuss the feature first. ## Adding new syntaxes/languages or themes Before you make a pull request that adds a new syntax or theme, please read the [Customization](https://github.com/sharkdp/bat#customization) section in the README first. If you really think that a particular syntax or theme should be added for all users, please read the corresponding [documentation](https://github.com/sharkdp/bat/blob/master/doc/assets.md) first. bat-0.19.0/Cargo.lock0000644000001016360000000000100076530ustar # This file is automatically @generated by Cargo. # It is not intended for manual editing. version = 3 [[package]] name = "adler" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "aho-corasick" version = "0.7.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" dependencies = [ "memchr", ] [[package]] name = "ansi_colours" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60e2fb6138a49ad9f1cb3c6d8f8ccbdd5e62b4dab317c1b435a47ecd7da1d28f" dependencies = [ "cc", ] [[package]] name = "ansi_term" version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" dependencies = [ "winapi", ] [[package]] name = "assert_cmd" version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e996dc7940838b7ef1096b882e29ec30a3149a3a443cdc8dba19ed382eca1fe2" dependencies = [ "bstr", "doc-comment", "predicates", "predicates-core", "predicates-tree", "wait-timeout", ] [[package]] name = "atty" version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ "hermit-abi", "libc", "winapi", ] [[package]] name = "autocfg" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" [[package]] name = "base64" version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" [[package]] name = "bat" version = "0.19.0" dependencies = [ "ansi_colours", "ansi_term", "assert_cmd", "atty", "bincode", "bugreport", "clap", "clircle", "console", "content_inspector", "dirs-next", "encoding", "flate2", "git2", "globset", "grep-cli", "nix", "once_cell", "path_abs", "predicates", "regex", "semver", "serde", "serde_yaml", "serial_test", "shell-words", "syntect", "tempfile", "thiserror", "unicode-width", "wait-timeout", "walkdir", "wild", ] [[package]] name = "bincode" version = "1.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" dependencies = [ "serde", ] [[package]] name = "bit-set" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e11e16035ea35e4e5997b393eacbf6f63983188f7a2ad25bfb13465f5ad59de" dependencies = [ "bit-vec", ] [[package]] name = "bit-vec" version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" [[package]] name = "bitflags" version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bstr" version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223" dependencies = [ "lazy_static", "memchr", "regex-automata", ] [[package]] name = "bugreport" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0014b4b2b4f63bfe69c3838470121290cc437fdc79785d408a761a21e8b2404c" dependencies = [ "git-version", "shell-escape", "sys-info", ] [[package]] name = "cc" version = "1.0.72" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee" dependencies = [ "jobserver", ] [[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" version = "2.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" dependencies = [ "ansi_term", "atty", "bitflags", "strsim", "term_size", "textwrap", "unicode-width", "vec_map", ] [[package]] name = "clircle" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e68bbd985a63de680ab4d1ad77b6306611a8f961b282c8b5ab513e6de934e396" dependencies = [ "cfg-if", "libc", "serde", "winapi", ] [[package]] name = "console" version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a28b32d32ca44b70c3e4acd7db1babf555fa026e385fb95f18028f88848b3c31" dependencies = [ "encode_unicode", "libc", "once_cell", "regex", "terminal_size", "unicode-width", "winapi", ] [[package]] name = "content_inspector" version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7bda66e858c683005a53a9a60c69a4aca7eeaa45d124526e389f7aec8e62f38" dependencies = [ "memchr", ] [[package]] name = "crc32fast" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "738c290dfaea84fc1ca15ad9c168d083b05a714e1efddd8edaab678dc28d2836" dependencies = [ "cfg-if", ] [[package]] name = "difflib" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8" [[package]] name = "dirs-next" version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" dependencies = [ "cfg-if", "dirs-sys-next", ] [[package]] name = "dirs-sys-next" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" dependencies = [ "libc", "redox_users", "winapi", ] [[package]] name = "doc-comment" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" [[package]] name = "either" version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" [[package]] name = "encode_unicode" version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" [[package]] name = "encoding" version = "0.2.33" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6b0d943856b990d12d3b55b359144ff341533e516d94098b1d3fc1ac666d36ec" dependencies = [ "encoding-index-japanese", "encoding-index-korean", "encoding-index-simpchinese", "encoding-index-singlebyte", "encoding-index-tradchinese", ] [[package]] name = "encoding-index-japanese" version = "1.20141219.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04e8b2ff42e9a05335dbf8b5c6f7567e5591d0d916ccef4e0b1710d32a0d0c91" dependencies = [ "encoding_index_tests", ] [[package]] name = "encoding-index-korean" version = "1.20141219.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4dc33fb8e6bcba213fe2f14275f0963fd16f0a02c878e3095ecfdf5bee529d81" dependencies = [ "encoding_index_tests", ] [[package]] name = "encoding-index-simpchinese" version = "1.20141219.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d87a7194909b9118fc707194baa434a4e3b0fb6a5a757c73c3adb07aa25031f7" dependencies = [ "encoding_index_tests", ] [[package]] name = "encoding-index-singlebyte" version = "1.20141219.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3351d5acffb224af9ca265f435b859c7c01537c0849754d3db3fdf2bfe2ae84a" dependencies = [ "encoding_index_tests", ] [[package]] name = "encoding-index-tradchinese" version = "1.20141219.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd0e20d5688ce3cab59eb3ef3a2083a5c77bf496cb798dc6fcdb75f323890c18" dependencies = [ "encoding_index_tests", ] [[package]] name = "encoding_index_tests" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a246d82be1c9d791c5dfde9a2bd045fc3cbba3fa2b11ad558f27d01712f00569" [[package]] name = "fancy-regex" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d6b8560a05112eb52f04b00e5d3790c0dd75d9d980eb8a122fb23b92a623ccf" dependencies = [ "bit-set", "regex", ] [[package]] name = "flate2" version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e6988e897c1c9c485f43b47a529cef42fde0547f9d8d41a7062518f1d8fc53f" dependencies = [ "cfg-if", "crc32fast", "libc", "miniz_oxide", ] [[package]] name = "float-cmp" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4" dependencies = [ "num-traits", ] [[package]] name = "fnv" version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "form_urlencoded" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" dependencies = [ "matches", "percent-encoding", ] [[package]] name = "getrandom" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" dependencies = [ "cfg-if", "libc", "wasi", ] [[package]] name = "git-version" version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f6b0decc02f4636b9ccad390dcbe77b722a77efedfa393caf8379a51d5c61899" dependencies = [ "git-version-macro", "proc-macro-hack", ] [[package]] name = "git-version-macro" version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fe69f1cbdb6e28af2bac214e943b99ce8a0a06b447d15d3e61161b0423139f3f" dependencies = [ "proc-macro-hack", "proc-macro2", "quote", "syn", ] [[package]] name = "git2" version = "0.13.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f29229cc1b24c0e6062f6e742aa3e256492a5323365e5ed3413599f8a5eff7d6" dependencies = [ "bitflags", "libc", "libgit2-sys", "log", "url", ] [[package]] name = "glob" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" [[package]] name = "globset" version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "10463d9ff00a2a068db14231982f5132edebad0d7660cd956a1c30292dbcbfbd" dependencies = [ "aho-corasick", "bstr", "fnv", "log", "regex", ] [[package]] name = "grep-cli" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dd110c34bb4460d0de5062413b773e385cbf8a85a63fc535590110a09e79e8a" dependencies = [ "atty", "bstr", "globset", "lazy_static", "log", "regex", "same-file", "termcolor", "winapi-util", ] [[package]] name = "hashbrown" version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" [[package]] name = "hermit-abi" version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" dependencies = [ "libc", ] [[package]] name = "idna" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" dependencies = [ "matches", "unicode-bidi", "unicode-normalization", ] [[package]] name = "indexmap" version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5" dependencies = [ "autocfg", "hashbrown", ] [[package]] name = "instant" version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" dependencies = [ "cfg-if", ] [[package]] name = "itertools" version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3" dependencies = [ "either", ] [[package]] name = "itoa" version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" [[package]] name = "itoa" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" [[package]] name = "jobserver" version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af25a77299a7f711a01975c35a6a424eb6862092cc2d6c72c4ed6cbc56dfc1fa" dependencies = [ "libc", ] [[package]] name = "lazy_static" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "lazycell" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" version = "0.2.112" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125" [[package]] name = "libgit2-sys" version = "0.12.26+1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19e1c899248e606fbfe68dcb31d8b0176ebab833b103824af31bddf4b7457494" dependencies = [ "cc", "libc", "libz-sys", "pkg-config", ] [[package]] name = "libz-sys" version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de5435b8549c16d423ed0c03dbaafe57cf6c3344744f1242520d59c9d8ecec66" dependencies = [ "cc", "libc", "pkg-config", "vcpkg", ] [[package]] name = "line-wrap" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f30344350a2a51da54c1d53be93fade8a237e545dbcc4bdbe635413f2117cab9" dependencies = [ "safemem", ] [[package]] name = "linked-hash-map" version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3" [[package]] name = "lock_api" version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712a4d093c9976e24e7dbca41db895dabcbac38eb5f4045393d17a95bdfb1109" dependencies = [ "scopeguard", ] [[package]] name = "log" version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" dependencies = [ "cfg-if", ] [[package]] name = "matches" version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" [[package]] name = "memchr" version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" [[package]] name = "memoffset" version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" dependencies = [ "autocfg", ] [[package]] name = "miniz_oxide" version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b" dependencies = [ "adler", "autocfg", ] [[package]] name = "nix" version = "0.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9f866317acbd3a240710c63f065ffb1e4fd466259045ccb504130b7f668f35c6" dependencies = [ "bitflags", "cc", "cfg-if", "libc", "memoffset", ] [[package]] name = "normalize-line-endings" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" [[package]] name = "num-traits" version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" dependencies = [ "autocfg", ] [[package]] name = "once_cell" version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5" [[package]] name = "onig" version = "6.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67ddfe2c93bb389eea6e6d713306880c7f6dcc99a75b659ce145d962c861b225" dependencies = [ "bitflags", "lazy_static", "libc", "onig_sys", ] [[package]] name = "onig_sys" version = "69.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5dd3eee045c84695b53b20255bb7317063df090b68e18bfac0abb6c39cf7f33e" dependencies = [ "cc", "pkg-config", ] [[package]] name = "parking_lot" version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" dependencies = [ "instant", "lock_api", "parking_lot_core", ] [[package]] name = "parking_lot_core" version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" dependencies = [ "cfg-if", "instant", "libc", "redox_syscall", "smallvec", "winapi", ] [[package]] name = "path_abs" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05ef02f6342ac01d8a93b65f96db53fe68a92a15f41144f97fb00a9e669633c3" dependencies = [ "std_prelude", ] [[package]] name = "percent-encoding" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" [[package]] name = "pkg-config" version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "58893f751c9b0412871a09abd62ecd2a00298c6c83befa223ef98c52aef40cbe" [[package]] name = "plist" version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd39bc6cdc9355ad1dc5eeedefee696bb35c34caf21768741e81826c0bbd7225" dependencies = [ "base64", "indexmap", "line-wrap", "serde", "time", "xml-rs", ] [[package]] name = "ppv-lite86" version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" [[package]] name = "predicates" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95e5a7689e456ab905c22c2b48225bb921aba7c8dfa58440d68ba13f6222a715" dependencies = [ "difflib", "float-cmp", "itertools", "normalize-line-endings", "predicates-core", "regex", ] [[package]] name = "predicates-core" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57e35a3326b75e49aa85f5dc6ec15b41108cf5aee58eabb1f274dd18b73c2451" [[package]] name = "predicates-tree" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "338c7be2905b732ae3984a2f40032b5e94fd8f52505b186c7d4d68d193445df7" dependencies = [ "predicates-core", "termtree", ] [[package]] name = "proc-macro-hack" version = "0.5.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" [[package]] name = "proc-macro2" version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" dependencies = [ "unicode-xid", ] [[package]] name = "quote" version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "47aa80447ce4daf1717500037052af176af5d38cc3e571d9ec1c7353fc10c87d" dependencies = [ "proc-macro2", ] [[package]] name = "rand" version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" dependencies = [ "libc", "rand_chacha", "rand_core", "rand_hc", ] [[package]] name = "rand_chacha" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", "rand_core", ] [[package]] name = "rand_core" version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" dependencies = [ "getrandom", ] [[package]] name = "rand_hc" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" dependencies = [ "rand_core", ] [[package]] name = "redox_syscall" version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" dependencies = [ "bitflags", ] [[package]] name = "redox_users" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64" dependencies = [ "getrandom", "redox_syscall", ] [[package]] name = "regex" version = "1.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" dependencies = [ "aho-corasick", "memchr", "regex-syntax", ] [[package]] name = "regex-automata" version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" [[package]] name = "regex-syntax" version = "0.6.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" [[package]] name = "remove_dir_all" version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" dependencies = [ "winapi", ] [[package]] name = "ryu" version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" [[package]] name = "safemem" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072" [[package]] name = "same-file" version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" dependencies = [ "winapi-util", ] [[package]] name = "scopeguard" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "semver" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "568a8e6258aa33c13358f81fd834adb854c6f7c9468520910a9b1e8fac068012" [[package]] name = "serde" version = "1.0.133" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97565067517b60e2d1ea8b268e59ce036de907ac523ad83a0475da04e818989a" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" version = "1.0.133" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed201699328568d8d08208fdd080e3ff594e6c422e438b6705905da01005d537" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "serde_json" version = "1.0.74" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee2bb9cd061c5865d345bb02ca49fcef1391741b672b54a0bf7b679badec3142" dependencies = [ "itoa 1.0.1", "ryu", "serde", ] [[package]] name = "serde_yaml" version = "0.8.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4a521f2940385c165a24ee286aa8599633d162077a54bdcae2a6fd5a7bfa7a0" dependencies = [ "indexmap", "ryu", "serde", "yaml-rust", ] [[package]] name = "serial_test" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e0bccbcf40c8938196944a3da0e133e031a33f4d6b72db3bda3cc556e361905d" dependencies = [ "lazy_static", "parking_lot", "serial_test_derive", ] [[package]] name = "serial_test_derive" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b2acd6defeddb41eb60bb468f8825d0cfd0c2a76bc03bfd235b6a1dc4f6a1ad5" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "shell-escape" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "45bb67a18fa91266cc7807181f62f9178a6873bfad7dc788c42e6430db40184f" [[package]] name = "shell-words" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6fa3938c99da4914afedd13bf3d79bcb6c277d1b2c398d23257a304d9e1b074" [[package]] name = "smallvec" version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309" [[package]] name = "std_prelude" version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8207e78455ffdf55661170876f88daf85356e4edd54e0a3dbc79586ca1e50cbe" [[package]] name = "strsim" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" [[package]] name = "syn" version = "1.0.85" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a684ac3dcd8913827e18cd09a68384ee66c1de24157e3c556c9ab16d85695fb7" dependencies = [ "proc-macro2", "quote", "unicode-xid", ] [[package]] name = "syntect" version = "4.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b20815bbe80ee0be06e6957450a841185fcf690fe0178f14d77a05ce2caa031" dependencies = [ "bincode", "bitflags", "fancy-regex", "flate2", "fnv", "lazy_static", "lazycell", "onig", "plist", "regex-syntax", "serde", "serde_derive", "serde_json", "walkdir", "yaml-rust", ] [[package]] name = "sys-info" version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b3a0d0aba8bf96a0e1ddfdc352fc53b3df7f39318c71854910c3c4b024ae52c" dependencies = [ "cc", "libc", ] [[package]] name = "tempfile" version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22" dependencies = [ "cfg-if", "libc", "rand", "redox_syscall", "remove_dir_all", "winapi", ] [[package]] name = "term_size" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e4129646ca0ed8f45d09b929036bafad5377103edd06e50bf574b353d2b08d9" dependencies = [ "libc", "winapi", ] [[package]] name = "termcolor" version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4" dependencies = [ "winapi-util", ] [[package]] name = "terminal_size" version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "633c1a546cee861a1a6d0dc69ebeca693bf4296661ba7852b9d21d159e0506df" dependencies = [ "libc", "winapi", ] [[package]] name = "termtree" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13a4ec180a2de59b57434704ccfad967f789b12737738798fa08798cd5824c16" [[package]] name = "textwrap" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" dependencies = [ "term_size", "unicode-width", ] [[package]] name = "thiserror" version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "time" version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41effe7cfa8af36f439fac33861b66b049edc6f9a32331e2312660529c1c24ad" dependencies = [ "itoa 0.4.8", "libc", ] [[package]] name = "tinyvec" version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c1c1d5a42b6245520c249549ec267180beaffcc0615401ac8e31853d4b6d8d2" dependencies = [ "tinyvec_macros", ] [[package]] name = "tinyvec_macros" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "unicode-bidi" version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a01404663e3db436ed2746d9fefef640d868edae3cceb81c3b8d5732fda678f" [[package]] name = "unicode-normalization" version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9" dependencies = [ "tinyvec", ] [[package]] name = "unicode-width" version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" [[package]] name = "unicode-xid" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" [[package]] name = "url" version = "2.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" dependencies = [ "form_urlencoded", "idna", "matches", "percent-encoding", ] [[package]] name = "vcpkg" version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" [[package]] name = "vec_map" version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" [[package]] name = "wait-timeout" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" dependencies = [ "libc", ] [[package]] name = "walkdir" version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" dependencies = [ "same-file", "winapi", "winapi-util", ] [[package]] name = "wasi" version = "0.10.2+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" [[package]] name = "wild" version = "2.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "035793abb854745033f01a07647a79831eba29ec0be377205f2a25b0aa830020" dependencies = [ "glob", ] [[package]] name = "winapi" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" dependencies = [ "winapi-i686-pc-windows-gnu", "winapi-x86_64-pc-windows-gnu", ] [[package]] name = "winapi-i686-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" dependencies = [ "winapi", ] [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "xml-rs" version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2d7d3948613f75c98fd9328cfdcc45acc4d360655289d0a7d4ec931392200a3" [[package]] name = "yaml-rust" version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" dependencies = [ "linked-hash-map", ] bat-0.19.0/Cargo.toml0000644000000061030000000000100076670ustar # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g., crates.io) dependencies. # # If you are reading this file be aware that the original Cargo.toml # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. [package] edition = "2018" name = "bat" version = "0.19.0" authors = ["David Peter "] build = "build.rs" exclude = ["assets/syntaxes/*", "assets/themes/*"] description = "A cat(1) clone with wings." homepage = "https://github.com/sharkdp/bat" categories = ["command-line-utilities"] license = "MIT/Apache-2.0" repository = "https://github.com/sharkdp/bat" [profile.release] lto = true codegen-units = 1 [dependencies.ansi_colours] version = "^1.0" [dependencies.ansi_term] version = "^0.12.1" [dependencies.atty] version = "0.2.14" optional = true [dependencies.bincode] version = "1.0" [dependencies.bugreport] version = "0.4" optional = true [dependencies.clap] version = "2.34" features = ["suggestions", "color", "wrap_help"] optional = true default-features = false [dependencies.clircle] version = "0.3" [dependencies.console] version = "0.15.0" [dependencies.content_inspector] version = "0.2.4" [dependencies.dirs-next] version = "2.0.0" optional = true [dependencies.encoding] version = "0.2" [dependencies.flate2] version = "1.0" [dependencies.git2] version = "0.13" optional = true default-features = false [dependencies.globset] version = "0.4" [dependencies.grep-cli] version = "0.1.6" optional = true [dependencies.once_cell] version = "1.9" [dependencies.path_abs] version = "0.5" default-features = false [dependencies.regex] version = "1.0" optional = true [dependencies.semver] version = "1.0" [dependencies.serde] version = "1.0" features = ["derive"] [dependencies.serde_yaml] version = "0.8" [dependencies.shell-words] version = "1.0.0" optional = true [dependencies.syntect] version = "4.6.0" features = ["parsing"] default-features = false [dependencies.thiserror] version = "1.0" [dependencies.unicode-width] version = "0.1.9" [dependencies.walkdir] version = "2.0" optional = true [dependencies.wild] version = "2.0" optional = true [dev-dependencies.assert_cmd] version = "2.0.2" [dev-dependencies.predicates] version = "2.1.0" [dev-dependencies.serial_test] version = "0.5.1" [dev-dependencies.tempfile] version = "3.2.0" [dev-dependencies.wait-timeout] version = "0.2.0" [build-dependencies.clap] version = "2.34" optional = true [features] application = ["bugreport", "build-assets", "git", "minimal-application"] build-assets = ["syntect/yaml-load", "syntect/dump-create", "regex", "walkdir"] default = ["application"] git = ["git2"] minimal-application = ["atty", "clap", "dirs-next", "paging", "regex-onig", "wild"] paging = ["shell-words", "grep-cli"] regex-fancy = ["syntect/regex-fancy"] regex-onig = ["syntect/regex-onig"] [target."cfg(unix)".dev-dependencies.nix] version = "0.23.1" bat-0.19.0/Cargo.toml.orig0000644000000052420000000000100106310ustar [package] authors = ["David Peter "] categories = ["command-line-utilities"] description = "A cat(1) clone with wings." homepage = "https://github.com/sharkdp/bat" license = "MIT/Apache-2.0" name = "bat" repository = "https://github.com/sharkdp/bat" version = "0.19.0" exclude = ["assets/syntaxes/*", "assets/themes/*"] build = "build.rs" edition = '2018' [features] default = ["application"] # Feature required for bat the application. Should be disabled when depending on # bat as a library. application = [ "bugreport", "build-assets", "git", "minimal-application", ] # Mainly for developers that want to iterate quickly # Be aware that the included features might change in the future minimal-application = [ "atty", "clap", "dirs-next", "paging", "regex-onig", "wild", ] git = ["git2"] # Support indicating git modifications paging = ["shell-words", "grep-cli"] # Support applying a pager on the output # Add "syntect/plist-load" when https://github.com/trishume/syntect/pull/345 reaches us build-assets = ["syntect/yaml-load", "syntect/dump-create", "regex", "walkdir"] # You need to use one of these if you depend on bat as a library: regex-onig = ["syntect/regex-onig"] # Use the "oniguruma" regex engine regex-fancy = ["syntect/regex-fancy"] # Use the rust-only "fancy-regex" engine [dependencies] atty = { version = "0.2.14", optional = true } ansi_term = "^0.12.1" ansi_colours = "^1.0" bincode = "1.0" console = "0.15.0" flate2 = "1.0" once_cell = "1.9" thiserror = "1.0" wild = { version = "2.0", optional = true } content_inspector = "0.2.4" encoding = "0.2" shell-words = { version = "1.0.0", optional = true } unicode-width = "0.1.9" globset = "0.4" serde = { version = "1.0", features = ["derive"] } serde_yaml = "0.8" semver = "1.0" path_abs = { version = "0.5", default-features = false } clircle = "0.3" bugreport = { version = "0.4", optional = true } dirs-next = { version = "2.0.0", optional = true } grep-cli = { version = "0.1.6", optional = true } regex = { version = "1.0", optional = true } walkdir = { version = "2.0", optional = true } [dependencies.git2] version = "0.13" optional = true default-features = false [dependencies.syntect] version = "4.6.0" default-features = false features = ["parsing"] [dependencies.clap] version = "2.34" optional = true default-features = false features = ["suggestions", "color", "wrap_help"] [dev-dependencies] assert_cmd = "2.0.2" serial_test = "0.5.1" predicates = "2.1.0" wait-timeout = "0.2.0" tempfile = "3.2.0" [target.'cfg(unix)'.dev-dependencies] nix = "0.23.1" [build-dependencies] clap = { version = "2.34", optional = true } [profile.release] lto = true codegen-units = 1 bat-0.19.0/Cargo.toml.orig000064400000000000000000000052420072674642500134030ustar 00000000000000[package] authors = ["David Peter "] categories = ["command-line-utilities"] description = "A cat(1) clone with wings." homepage = "https://github.com/sharkdp/bat" license = "MIT/Apache-2.0" name = "bat" repository = "https://github.com/sharkdp/bat" version = "0.19.0" exclude = ["assets/syntaxes/*", "assets/themes/*"] build = "build.rs" edition = '2018' [features] default = ["application"] # Feature required for bat the application. Should be disabled when depending on # bat as a library. application = [ "bugreport", "build-assets", "git", "minimal-application", ] # Mainly for developers that want to iterate quickly # Be aware that the included features might change in the future minimal-application = [ "atty", "clap", "dirs-next", "paging", "regex-onig", "wild", ] git = ["git2"] # Support indicating git modifications paging = ["shell-words", "grep-cli"] # Support applying a pager on the output # Add "syntect/plist-load" when https://github.com/trishume/syntect/pull/345 reaches us build-assets = ["syntect/yaml-load", "syntect/dump-create", "regex", "walkdir"] # You need to use one of these if you depend on bat as a library: regex-onig = ["syntect/regex-onig"] # Use the "oniguruma" regex engine regex-fancy = ["syntect/regex-fancy"] # Use the rust-only "fancy-regex" engine [dependencies] atty = { version = "0.2.14", optional = true } ansi_term = "^0.12.1" ansi_colours = "^1.0" bincode = "1.0" console = "0.15.0" flate2 = "1.0" once_cell = "1.9" thiserror = "1.0" wild = { version = "2.0", optional = true } content_inspector = "0.2.4" encoding = "0.2" shell-words = { version = "1.0.0", optional = true } unicode-width = "0.1.9" globset = "0.4" serde = { version = "1.0", features = ["derive"] } serde_yaml = "0.8" semver = "1.0" path_abs = { version = "0.5", default-features = false } clircle = "0.3" bugreport = { version = "0.4", optional = true } dirs-next = { version = "2.0.0", optional = true } grep-cli = { version = "0.1.6", optional = true } regex = { version = "1.0", optional = true } walkdir = { version = "2.0", optional = true } [dependencies.git2] version = "0.13" optional = true default-features = false [dependencies.syntect] version = "4.6.0" default-features = false features = ["parsing"] [dependencies.clap] version = "2.34" optional = true default-features = false features = ["suggestions", "color", "wrap_help"] [dev-dependencies] assert_cmd = "2.0.2" serial_test = "0.5.1" predicates = "2.1.0" wait-timeout = "0.2.0" tempfile = "3.2.0" [target.'cfg(unix)'.dev-dependencies] nix = "0.23.1" [build-dependencies] clap = { version = "2.34", optional = true } [profile.release] lto = true codegen-units = 1 bat-0.19.0/LICENSE-APACHE000064400000000000000000000261350072674642500124440ustar 00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. bat-0.19.0/LICENSE-MIT000064400000000000000000000021110072674642500121400ustar 00000000000000Copyright (c) 2018-2021 bat-developers (https://github.com/sharkdp/bat). Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. bat-0.19.0/NOTICE000064400000000000000000000003700072674642500114150ustar 00000000000000Copyright (c) 2018-2021 bat-developers (https://github.com/sharkdp/bat). bat is made available under the terms of either the MIT License or the Apache License 2.0, at your option. See the LICENSE-APACHE and LICENSE-MIT files for license details. bat-0.19.0/README.md000064400000000000000000000642440072674642500120020ustar 00000000000000

bat - a cat clone with wings
Build Status license Version info
A cat(1) clone with syntax highlighting and Git integration.

Key FeaturesHow To UseInstallationCustomizationProject goals, alternatives
[English] [中文] [日本語] [한국어] [Русский]

### Syntax highlighting `bat` supports syntax highlighting for a large number of programming and markup languages: ![Syntax highlighting example](https://imgur.com/rGsdnDe.png) ### Git integration `bat` communicates with `git` to show modifications with respect to the index (see left side bar): ![Git integration example](https://i.imgur.com/2lSW4RE.png) ### Show non-printable characters You can use the `-A`/`--show-all` option to show and highlight non-printable characters: ![Non-printable character example](https://i.imgur.com/WndGp9H.png) ### Automatic paging By default, `bat` pipes its own output to a pager (e.g. `less`) if the output is too large for one screen. If you would rather `bat` work like `cat` all the time (never page output), you can set `--paging=never` as an option, either on the command line or in your configuration file. If you intend to alias `cat` to `bat` in your shell configuration, you can use `alias cat='bat --paging=never'` to preserve the default behavior. #### File concatenation Even with a pager set, you can still use `bat` to concatenate files :wink:. Whenever `bat` detects a non-interactive terminal (i.e. when you pipe into another process or into a file), `bat` will act as a drop-in replacement for `cat` and fall back to printing the plain file contents, regardless of the `--pager` option's value. ## How to use Display a single file on the terminal ```bash > bat README.md ``` Display multiple files at once ```bash > bat src/*.rs ``` Read from stdin, determine the syntax automatically (note, highlighting will only work if the syntax can be determined from the first line of the file, usually through a shebang such as `#!/bin/sh`) ```bash > curl -s https://sh.rustup.rs | bat ``` Read from stdin, specify the language explicitly ```bash > yaml2json .travis.yml | json_pp | bat -l json ``` Show and highlight non-printable characters: ```bash > bat -A /etc/hosts ``` Use it as a `cat` replacement: ```bash bat > note.md # quickly create a new file bat header.md content.md footer.md > document.md bat -n main.rs # show line numbers (only) bat f - g # output 'f', then stdin, then 'g'. ``` ### Integration with other tools #### `fzf` You can use `bat` as a previewer for [`fzf`](https://github.com/junegunn/fzf). To do this, use `bat`s `--color=always` option to force colorized output. You can also use `--line-range` option to restrict the load times for long files: ```bash fzf --preview 'bat --color=always --style=numbers --line-range=:500 {}' ``` For more information, see [`fzf`'s `README`](https://github.com/junegunn/fzf#preview-window). #### `find` or `fd` You can use the `-exec` option of `find` to preview all search results with `bat`: ```bash find … -exec bat {} + ``` If you happen to use [`fd`](https://github.com/sharkdp/fd), you can use the `-X`/`--exec-batch` option to do the same: ```bash fd … -X bat ``` #### `ripgrep` With [`batgrep`](https://github.com/eth-p/bat-extras/blob/master/doc/batgrep.md), `bat` can be used as the printer for [`ripgrep`](https://github.com/BurntSushi/ripgrep) search results. ```bash batgrep needle src/ ``` #### `tail -f` `bat` can be combined with `tail -f` to continuously monitor a given file with syntax highlighting. ```bash tail -f /var/log/pacman.log | bat --paging=never -l log ``` Note that we have to switch off paging in order for this to work. We have also specified the syntax explicitly (`-l log`), as it can not be auto-detected in this case. #### `git` You can combine `bat` with `git show` to view an older version of a given file with proper syntax highlighting: ```bash git show v0.6.0:src/main.rs | bat -l rs ``` #### `git diff` You can combine `bat` with `git diff` to view lines around code changes with proper syntax highlighting: ```bash batdiff() { git diff --name-only --diff-filter=d | xargs bat --diff } ``` If you prefer to use this as a separate tool, check out `batdiff` in [`bat-extras`](https://github.com/eth-p/bat-extras). If you are looking for more support for git and diff operations, check out [`delta`](https://github.com/dandavison/delta). #### `xclip` The line numbers and Git modification markers in the output of `bat` can make it hard to copy the contents of a file. To prevent this, you can call `bat` with the `-p`/`--plain` option or simply pipe the output into `xclip`: ```bash bat main.cpp | xclip ``` `bat` will detect that the output is being redirected and print the plain file contents. #### `man` `bat` can be used as a colorizing pager for `man`, by setting the `MANPAGER` environment variable: ```bash export MANPAGER="sh -c 'col -bx | bat -l man -p'" man 2 select ``` (replace `bat` with `batcat` if you are on Debian or Ubuntu) It might also be necessary to set `MANROFFOPT="-c"` if you experience formatting problems. If you prefer to have this bundled in a new command, you can also use [`batman`](https://github.com/eth-p/bat-extras/blob/master/doc/batman.md). Note that the [Manpage syntax](assets/syntaxes/02_Extra/Manpage.sublime-syntax) is developed in this repository and still needs some work. Also, note that this will [not work](https://github.com/sharkdp/bat/issues/1145) with Mandocs `man` implementation. #### `prettier` / `shfmt` / `rustfmt` The [`prettybat`](https://github.com/eth-p/bat-extras/blob/master/doc/prettybat.md) script is a wrapper that will format code and print it with `bat`. ## Installation [![Packaging status](https://repology.org/badge/vertical-allrepos/bat-cat.svg)](https://repology.org/project/bat-cat/versions) ### On Ubuntu (using `apt`) *... and other Debian-based Linux distributions.* `bat` is available on [Ubuntu since 20.04 ("Focal")](https://packages.ubuntu.com/search?keywords=bat&exact=1) and [Debian since August 2021 (Debian 11 - "Bullseye")](https://packages.debian.org/bullseye/bat). If your Ubuntu/Debian installation is new enough you can simply run: ```bash sudo apt install bat ``` **Important**: If you install `bat` this way, please note that the executable may be installed as `batcat` instead of `bat` (due to [a name clash with another package](https://github.com/sharkdp/bat/issues/982)). You can set up a `bat -> batcat` symlink or alias to prevent any issues that may come up because of this and to be consistent with other distributions: ``` bash mkdir -p ~/.local/bin ln -s /usr/bin/batcat ~/.local/bin/bat ``` ### On Ubuntu (using most recent `.deb` packages) *... and other Debian-based Linux distributions.* If the package has not yet been promoted to your Ubuntu/Debian installation, or you want the most recent release of `bat`, download the latest `.deb` package from the [release page](https://github.com/sharkdp/bat/releases) and install it via: ```bash sudo dpkg -i bat_0.18.3_amd64.deb # adapt version number and architecture ``` ### On Alpine Linux You can install [the `bat` package](https://pkgs.alpinelinux.org/packages?name=bat) from the official sources, provided you have the appropriate repository enabled: ```bash apk add bat ``` ### On Arch Linux You can install [the `bat` package](https://www.archlinux.org/packages/community/x86_64/bat/) from the official sources: ```bash pacman -S bat ``` ### On Fedora You can install [the `bat` package](https://koji.fedoraproject.org/koji/packageinfo?packageID=27506) from the official [Fedora Modular](https://docs.fedoraproject.org/en-US/modularity/using-modules/) repository. ```bash dnf install bat ``` ### On Funtoo Linux You can install [the `bat` package](https://github.com/funtoo/dev-kit/tree/1.4-release/sys-apps/bat) from dev-kit. ```bash emerge sys-apps/bat ``` ### On Gentoo Linux You can install [the `bat` package](https://packages.gentoo.org/packages/sys-apps/bat) from the official sources: ```bash emerge sys-apps/bat ``` ### On Void Linux You can install `bat` via xbps-install: ```bash xbps-install -S bat ``` ### On Termux You can install `bat` via pkg: ```bash pkg install bat ``` ### On FreeBSD You can install a precompiled [`bat` package](https://www.freshports.org/textproc/bat) with pkg: ```bash pkg install bat ``` or build it on your own from the FreeBSD ports: ```bash cd /usr/ports/textproc/bat make install ``` ### On OpenBSD You can install `bat` package using [`pkg_add(1)`](https://man.openbsd.org/pkg_add.1): ```bash pkg_add bat ``` ### Via nix You can install `bat` using the [nix package manager](https://nixos.org/nix): ```bash nix-env -i bat ``` ### On openSUSE You can install `bat` with zypper: ```bash zypper install bat ``` ### Via snap package There is currently no recommended snap package available. Existing packages may be available, but are not officially supported and may contain [issues](https://github.com/sharkdp/bat/issues/1519). ### On macOS (or Linux) via Homebrew You can install `bat` with [Homebrew on MacOS](https://formulae.brew.sh/formula/bat) or [Homebrew on Linux](https://formulae.brew.sh/formula-linux/bat): ```bash brew install bat ``` ### On macOS via MacPorts Or install `bat` with [MacPorts](https://ports.macports.org/port/bat/summary): ```bash port install bat ``` ### On Windows There are a few options to install `bat` on Windows. Once you have installed `bat`, take a look at the ["Using `bat` on Windows"](#using-bat-on-windows) section. #### Prerequisites You will need to install the [Visual C++ Redistributable](https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads) package. #### With Chocolatey You can install `bat` via [Chocolatey](https://chocolatey.org/packages/Bat): ```bash choco install bat ``` #### With Scoop You can install `bat` via [scoop](https://scoop.sh/): ```bash scoop install bat ``` #### From prebuilt binaries: You can download prebuilt binaries from the [Release page](https://github.com/sharkdp/bat/releases), You will need to install the [Visual C++ Redistributable](https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads) package. ### From binaries Check out the [Release page](https://github.com/sharkdp/bat/releases) for prebuilt versions of `bat` for many different architectures. Statically-linked binaries are also available: look for archives with `musl` in the file name. ### From source If you want to build `bat` from source, you need Rust 1.51 or higher. You can then use `cargo` to build everything: ```bash cargo install --locked bat ``` Note that additional files like the man page or shell completion files can not be installed in this way. They will be generated by `cargo` and should be available in the cargo target folder (under `build`). ## Customization ### Highlighting theme Use `bat --list-themes` to get a list of all available themes for syntax highlighting. To select the `TwoDark` theme, call `bat` with the `--theme=TwoDark` option or set the `BAT_THEME` environment variable to `TwoDark`. Use `export BAT_THEME="TwoDark"` in your shell's startup file to make the change permanent. Alternatively, use `bat`s [configuration file](https://github.com/sharkdp/bat#configuration-file). If you want to preview the different themes on a custom file, you can use the following command (you need [`fzf`](https://github.com/junegunn/fzf) for this): ```bash bat --list-themes | fzf --preview="bat --theme={} --color=always /path/to/file" ``` `bat` looks good on a dark background by default. However, if your terminal uses a light background, some themes like `GitHub` or `OneHalfLight` will work better for you. You can also use a custom theme by following the ['Adding new themes' section below](https://github.com/sharkdp/bat#adding-new-themes). ### 8-bit themes `bat` has three themes that always use [8-bit colors](https://en.wikipedia.org/wiki/ANSI_escape_code#Colors), even when truecolor support is available: - `ansi` looks decent on any terminal. It uses 3-bit colors: black, red, green, yellow, blue, magenta, cyan, and white. - `base16` is designed for [base16](https://github.com/chriskempson/base16) terminal themes. It uses 4-bit colors (3-bit colors plus bright variants) in accordance with the [base16 styling guidelines](https://github.com/chriskempson/base16/blob/master/styling.md). - `base16-256` is designed for [base16-shell](https://github.com/chriskempson/base16-shell). It replaces certain bright colors with 8-bit colors from 16 to 21. **Do not** use this simply because you have a 256-color terminal but are not using base16-shell. Although these themes are more restricted, they have three advantages over truecolor themes. They: - Enjoy maximum compatibility. Some terminal utilities do not support more than 3-bit colors. - Adapt to terminal theme changes. Even for already printed output. - Visually harmonize better with other terminal software. ### Output style You can use the `--style` option to control the appearance of `bat`s output. You can use `--style=numbers,changes`, for example, to show only Git changes and line numbers but no grid and no file header. Set the `BAT_STYLE` environment variable to make these changes permanent or use `bat`s [configuration file](https://github.com/sharkdp/bat#configuration-file). ### Adding new syntaxes / language definitions Should you find that a particular syntax is not available within `bat`, you can follow these instructions to easily add new syntaxes to your current `bat` installation. `bat` uses the excellent [`syntect`](https://github.com/trishume/syntect/) library for syntax highlighting. `syntect` can read any [Sublime Text `.sublime-syntax` file](https://www.sublimetext.com/docs/3/syntax.html) and theme. A good resource for finding Sublime Syntax packages is [Package Control](https://packagecontrol.io/). Once you found a syntax: 1. Create a folder with syntax definition files: ```bash mkdir -p "$(bat --config-dir)/syntaxes" cd "$(bat --config-dir)/syntaxes" # Put new '.sublime-syntax' language definition files # in this folder (or its subdirectories), for example: git clone https://github.com/tellnobody1/sublime-purescript-syntax ``` 2. Now use the following command to parse these files into a binary cache: ```bash bat cache --build ``` 3. Finally, use `bat --list-languages` to check if the new languages are available. If you ever want to go back to the default settings, call: ```bash bat cache --clear ``` 4. If you think that a specific syntax should be included in `bat` by default, please consider opening a "syntax request" ticket after reading the policies and instructions [here](doc/assets.md): [Open Syntax Request](https://github.com/sharkdp/bat/issues/new?labels=syntax-request&template=syntax_request.md). ### Adding new themes This works very similar to how we add new syntax definitions. First, create a folder with the new syntax highlighting themes: ```bash mkdir -p "$(bat --config-dir)/themes" cd "$(bat --config-dir)/themes" # Download a theme in '.tmTheme' format, for example: git clone https://github.com/greggb/sublime-snazzy # Update the binary cache bat cache --build ``` Finally, use `bat --list-themes` to check if the new themes are available. ### Adding or changing file type associations You can add new (or change existing) file name patterns using the `--map-syntax` command line option. The option takes an argument of the form `pattern:syntax` where `pattern` is a glob pattern that is matched against the file name and the absolute file path. The `syntax` part is the full name of a supported language (use `bat --list-languages` for an overview). Note: You probably want to use this option as an entry in `bat`s configuration file instead of passing it on the command line (see below). Example: To use "INI" syntax highlighting for all files with a `.conf` file extension, use ```bash --map-syntax='*.conf:INI' ``` Example: To open all files called `.ignore` (exact match) with the "Git Ignore" syntax, use: ```bash --map-syntax='.ignore:Git Ignore' ``` Example: To open all `.conf` files in subfolders of `/etc/apache2` with the "Apache Conf" syntax, use (this mapping is already built in): ```bash --map-syntax='/etc/apache2/**/*.conf:Apache Conf' ``` ### Using a different pager `bat` uses the pager that is specified in the `PAGER` environment variable. If this variable is not set, `less` is used by default. If you want to use a different pager, you can either modify the `PAGER` variable or set the `BAT_PAGER` environment variable to override what is specified in `PAGER`. **Note**: If `PAGER` is `more` or `most`, `bat` will silently use `less` instead to ensure support for colors. If you want to pass command-line arguments to the pager, you can also set them via the `PAGER`/`BAT_PAGER` variables: ```bash export BAT_PAGER="less -RF" ``` Instead of using environment variables, you can also use `bat`s [configuration file](https://github.com/sharkdp/bat#configuration-file) to configure the pager (`--pager` option). **Note**: By default, if the pager is set to `less` (and no command-line options are specified), `bat` will pass the following command line options to the pager: `-R`/`--RAW-CONTROL-CHARS`, `-F`/`--quit-if-one-screen` and `-X`/`--no-init`. The last option (`-X`) is only used for `less` versions older than 530. The `-R` option is needed to interpret ANSI colors correctly. The second option (`-F`) instructs less to exit immediately if the output size is smaller than the vertical size of the terminal. This is convenient for small files because you do not have to press `q` to quit the pager. The third option (`-X`) is needed to fix a bug with the `--quit-if-one-screen` feature in old versions of `less`. Unfortunately, it also breaks mouse-wheel support in `less`. If you want to enable mouse-wheel scrolling on older versions of `less`, you can pass just `-R` (as in the example above, this will disable the quit-if-one-screen feature). For less 530 or newer, it should work out of the box. ### Indentation `bat` expands tabs to 4 spaces by itself, not relying on the pager. To change this, simply add the `--tabs` argument with the number of spaces you want to be displayed. **Note**: Defining tab stops for the pager (via the `--pager` argument by `bat`, or via the `LESS` environment variable for `less`) won't be taken into account because the pager will already get expanded spaces instead of tabs. This behaviour is added to avoid indentation issues caused by the sidebar. Calling `bat` with `--tabs=0` will override it and let tabs be consumed by the pager. ### Dark mode If you make use of the dark mode feature in macOS, you might want to configure `bat` to use a different theme based on the OS theme. The following snippet uses the `default` theme when in the _dark mode_ and the `GitHub` theme when in the _light mode_. ```bash alias cat="bat --theme=\$(defaults read -globalDomain AppleInterfaceStyle &> /dev/null && echo default || echo GitHub)" ``` ## Configuration file `bat` can also be customized with a configuration file. The location of the file is dependent on your operating system. To get the default path for your system, call ```bash bat --config-file ``` Alternatively, you can use the `BAT_CONFIG_PATH` environment variable to point `bat` to a non-default location of the configuration file: ```bash export BAT_CONFIG_PATH="/path/to/bat.conf" ``` A default configuration file can be created with the `--generate-config-file` option. ```bash bat --generate-config-file ``` ### Format The configuration file is a simple list of command line arguments. Use `bat --help` to see a full list of possible options and values. In addition, you can add comments by prepending a line with the `#` character. Example configuration file: ```bash # Set the theme to "TwoDark" --theme="TwoDark" # Show line numbers, Git modifications and file header (but no grid) --style="numbers,changes,header" # Use italic text on the terminal (not supported on all terminals) --italic-text=always # Use C++ syntax for Arduino .ino files --map-syntax "*.ino:C++" ``` ## Using `bat` on Windows `bat` mostly works out-of-the-box on Windows, but a few features may need extra configuration. ### Prerequisites You will need to install the [Visual C++ Redistributable](https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads) package. ### Paging Windows only includes a very limited pager in the form of `more`. You can download a Windows binary for `less` [from its homepage](http://www.greenwoodsoftware.com/less/download.html) or [through Chocolatey](https://chocolatey.org/packages/Less). To use it, place the binary in a directory in your `PATH` or [define an environment variable](#using-a-different-pager). The [Chocolatey package](#on-windows) installs `less` automatically. ### Colors Windows 10 natively supports colors in both `conhost.exe` (Command Prompt) and PowerShell since [v1511](https://en.wikipedia.org/wiki/Windows_10_version_history#Version_1511_(November_Update)), as well as in newer versions of bash. On earlier versions of Windows, you can use [Cmder](http://cmder.net/), which includes [ConEmu](https://conemu.github.io/). **Note:** The Git and MSYS versions of `less` do not correctly interpret colors on Windows. If you don’t have any other pagers installed, you can disable paging entirely by passing `--paging=never` or by setting `BAT_PAGER` to an empty string. ### Cygwin `bat` on Windows does not natively support Cygwin's unix-style paths (`/cygdrive/*`). When passed an absolute cygwin path as an argument, `bat` will encounter the following error: `The system cannot find the path specified. (os error 3)` This can be solved by creating a wrapper or adding the following function to your `.bash_profile` file: ```bash bat() { local index local args=("$@") for index in $(seq 0 ${#args[@]}) ; do case "${args[index]}" in -*) continue;; *) [ -e "${args[index]}" ] && args[index]="$(cygpath --windows "${args[index]}")";; esac done command bat "${args[@]}" } ``` ## Troubleshooting ### Garbled output If an input file contains color codes or other ANSI escape sequences or control characters, `bat` will have problems performing syntax highlighting and text wrapping, and thus the output can become garbled. When displaying such files it is recommended to disable both syntax highlighting and wrapping by passing the `--color=never --wrap=never` options to `bat`. ### Terminals & colors `bat` handles terminals *with* and *without* truecolor support. However, the colors in most syntax highlighting themes are not optimized for 8-bit colors. It is therefore strongly recommended that you use a terminal with 24-bit truecolor support (`terminator`, `konsole`, `iTerm2`, ...), or use one of the basic [8-bit themes](#8-bit-themes) designed for a restricted set of colors. See [this article](https://gist.github.com/XVilka/8346728) for more details and a full list of terminals with truecolor support. Make sure that your truecolor terminal sets the `COLORTERM` variable to either `truecolor` or `24bit`. Otherwise, `bat` will not be able to determine whether or not 24-bit escape sequences are supported (and fall back to 8-bit colors). ### Line numbers and grid are hardly visible Please try a different theme (see `bat --list-themes` for a list). The `OneHalfDark` and `OneHalfLight` themes provide grid and line colors that are brighter. ### File encodings `bat` natively supports UTF-8 as well as UTF-16. For every other file encoding, you may need to convert to UTF-8 first because the encodings can typically not be auto-detected. You can `iconv` to do so. Example: if you have a PHP file in Latin-1 (ISO-8859-1) encoding, you can call: ``` bash iconv -f ISO-8859-1 -t UTF-8 my-file.php | bat ``` Note: you might have to use the `-l`/`--language` option if the syntax can not be auto-detected by `bat`. ## Development ```bash # Recursive clone to retrieve all submodules git clone --recursive https://github.com/sharkdp/bat # Build (debug version) cd bat cargo build --bins # Run unit tests and integration tests cargo test # Install (release version) cargo install --path . --locked # Build a bat binary with modified syntaxes and themes bash assets/create.sh cargo install --path . --locked --force ``` If you want to build an application that uses `bat`s pretty-printing features as a library, check out the [the API documentation](https://docs.rs/bat/). Note that you have to use either `regex-onig` or `regex-fancy` as a feature when you depend on `bat` as a library. ## Contributing Take a look at the [`CONTRIBUTING.md`](CONTRIBUTING.md) guide. ## Maintainers - [sharkdp](https://github.com/sharkdp) - [eth-p](https://github.com/eth-p) - [keith-hall](https://github.com/keith-hall) - [Enselic](https://github.com/Enselic) ## Security vulnerabilities Please contact [David Peter](https://david-peter.de/) via email if you want to report a vulnerability in `bat`. ## Project goals and alternatives `bat` tries to achieve the following goals: - Provide beautiful, advanced syntax highlighting - Integrate with Git to show file modifications - Be a drop-in replacement for (POSIX) `cat` - Offer a user-friendly command-line interface There are a lot of alternatives, if you are looking for similar programs. See [this document](doc/alternatives.md) for a comparison. ## License Copyright (c) 2018-2021 [bat-developers](https://github.com/sharkdp/bat). `bat` is made available under the terms of either the MIT License or the Apache License 2.0, at your option. See the [LICENSE-APACHE](LICENSE-APACHE) and [LICENSE-MIT](LICENSE-MIT) files for license details. bat-0.19.0/assets/.gitattributes000064400000000000000000000000240072674642500147020ustar 00000000000000* linguist-vendored bat-0.19.0/assets/.ignore000064400000000000000000000000240072674642500132730ustar 00000000000000syntaxes/* themes/* bat-0.19.0/assets/acknowledgements.bin000064400000000000000000000226650072674642500160520ustar 00000000000000x]{sFUsںZim嵛dSHئM AY^]mD T}3 HJփw7R$0c * g\ѳ>5i6ҋ){`|򧺕F~;)<2'cAˉ+) 5r̤+ƱH6x!AqD @kLL 4 ˒q@{bqT q{~c: r˜`~W@ۤE*< ؆+x9 _'h`8NW,I84e1lIMKx d9B(i38%4$y$̜iХw& zIs&Q\I< qF׎3Qr)i.$!,U?CGIM07L'> "LRo}\C`FbxxAm^Ӈ\q <1hDhމ7^ޏEtNNZݳvR{>HNvx>6v Zqsa|8mY9gӾAmh@/މ6WNxojvؕ<p|?}7|5ݶ_{0qS]ZfIGoщW~5ְ4Zp0|{h:>Š:HNxO{=OG3+mم`yzۀ{y#~] .kLU `4AiW{7IZEH ;6v2T[7-6v5>; b] $ld|i`y.zL|;WWW`)y#SDN"|}Wo :(FuE 'gch|@&wZ΅Z6Yeejo1\>z&/}gdvĤi5ʔȰ°°°+ X!C됬 p(8 $R.&hWĊ*?&WAȧF7A#"c}xֈ`a2G,ؗAlz99뛓xlw>hsr7'ɹisٜ6=B(lf4^<,c]vȒ{?[E3 YXgad]ۡŋ0+q\9vmՔԙf$EOfQ;x3FLi;LG08Ydq0[,dq 06Ebrg9z4L$ E_.E_Ď(0"v/b"v/bG"~{|yykhN !0`M"6$ZGi2>(> 'l -ĶBjxëpvpK0x+B(i)P2d(2AqP:W$-z6"S' BAEK#Q'3@b<;3g-ͼI5˛'kO,<>q)'c'*qR<>qщb'NK܎鯃@HFA 3 r՝(#\\\\N\o4:N):qp9qp9;qp9xKTW?yWUg>ppRn9m.}F4s)hՖT7D[NL<֯%h!*ٍ fG M)@חcsh?M\DTJҍU\Š0=_t=i)m?fr@Q(bIS+f'Q)0D]D:D4hRSn,Q6 ,e5C{t+{4؝jr%St*Иϴ]a^D@;fb<h.io@m۔ FB˓%4 9mclzgy@%Ԅ7 9:yVLHRCnZwI']ث!M(T00[e|AiTNe,(~]ؖffr2CڇK2!/O="j}7j}QD$d-$Z1pEᓁa(&NaC͹ 6֦G! T 5pB3TM6- DZ>Oҋ P/i*-8F4JPӺ`edĀ@RPšdքVhu0y,n 5r px  AE6Z@EՐ :`ig[R40ʬBQkU-<-0+=!-%r1Fˉ@$5U[tceY~nDB3pD[| NMk:4QzH%DK %NA4@ח =fѩn4&Z{dIԍA!ud2Ve%@+. SWP Kq`c5!hMĴ([Mw-:2 vA{F M!# ZaV[w [QATG9Ev{WiOn&.(s "(6eE(Sn "g[Q]v_5&g\etfniTlr{n!q PO~UVJ]&kH ,j#5YdS KFU[6D#L%[")2E^LvdT.JZz@@ز5<6'ީ`F TFIH0??v;NjF?DGTkP霕KhVXŎOm5f,1QY.),՜F`rR@~}*D]#NCZ fS(_ D˄7vsS,:,.K =c"02 Vn Ymk+h AŤ,oe;'lQ @vi09r"KPDbj<BR)0%hEYk3ffHFWyǭ!E'*#vQ\%Z*R#6uK܌Az,HCi c,$zGðQ^atWf׿2@*rQpk@NՆUieD08)PRS݂(ʊ0ǩFr6;k:*p'gԮڱBU+3- T9ѨLՒb Jg*;^ J4WRW((|iCUp j^hnhIPmΊfhV+B5Ym7 Xk!e~cWbt){5)"h٪oi⿍!}Cۨsd7*vE%ȩ" X=B\&3CNճIU4:OЎWhg].DZh^ ngR뚛BO ".B:nyq ~}uM׆. ?w* vT~l `lPjʘa0!ӮβeS j j"4.tNt%f6"W*i: 30chmUy*u `^c2[(N+-sV퀛'IzK[4]R T C\s`0b!0Bse!~mZoR)]:0VԇeK0kr?~Nޱ9j ]S.*gȞBdnba`QYuL#'a0 sSb+*Vr+`e-6a]r!j5-w_T3V(n[͔ +Eî-o^5hUm.nUJQ-SZ*k@mA cĪV!t*\4yuB4E+@R7VZ̲X7*M{\w/ׯKif(0-7.V >(2zSC vFn#4cr"U Zj'rK~edAflA<oI+:%@Q@2EK$R3 갆4mx&h%K?4nufjY mJ M[:-)l#c^@OHY7lsu:*֢mFn+L~V uNJNu~ݗ=^M!fSS~:-]TWX6 9 3 chvDyD*ZadƿNC:PdFYuvKeb#UkK1*ЉpÌ<]EI䍵Ƭ?7 x: P\6ૈ0F-Wd (k,2\G: et ҆2fɢ:Z`>|| @bB (.tFwub渋{5F ]fQbLZL Wm1q3*/Q ;KpF!y\3:cX8)(TF/JMpI P uGntnb`oh" y%iA^YmԖPQuzpB$Q^Ptւsm* OhT2&TnP~+;hISd!i/Tf5#ȍ0m_Y-ƫ -!eJ#zZ W-qdECJ[EȉF `KNEYl}h3S(Jމ6Ӓ6sEd˒nvq-H #zKn_Tq5b%BW]Ww>acI;w:l|gËМm,&P3΁|ƨT]$`\nCy νF<j5G58rvq> !ԈAsLx|^ݠƹ%EJ[A^@NXdSZL`?TLGQ5bF끋LBpۮhuۿkec yRk\qmRBO NDk 1c ߚ÷fmbf?->'>'>'8bĉjĉjĉe?9RzeB{}NHगt~V7U_[ NUNPyb>ҕxQݙ؛F%OkhudC\ uooYZJO~h>!^i3O?&< 1vR@M|wzl/dIL:zPxaaO6 {7PX.N0}% UdtaхuMtIIIG}:p} $|xCaNCa.CaήCaΎCac#CanCanCaΎBao $ϗOp%^</0 "?5[w$Zhd E7K!9=r9=[ǸC] _<*T,HFA>gUJaY.e˻{&[I(] KS1000lU8}ғ vH^dv_}s!gX1O}BCWA"Y<|6_l|6_l|6_l|6_l|6_l|6_l|6_l|6_l|6_l|6_lmyz t~-7UKuw|(ZԤ`粼 M25A0J)3~u2R3wa&BUmYtC췓yKFMq Z'358Tr2j۶b(+ Q8/FOjPU|\2H\؄V {08r\#^Q|/8L`kʙk鞩A:cĺhE"\⎵+) F=79!)pf)pfHPpk嗔 % ׂcTaTaTD'N}'N}'N}'N}'N}'N}'N}'N}'N}'N}'N}'N}'N}'N}'N}'N}'N}'N}'N}'N}ԧԧ_VW ףrB'D=2߷k] ]ADކ'2p"'2p":!Iyi-|Ec _- g`w ^өx\Ɩ2e<9yy2 [&blahZIbRqǀ2_,FzXa0b#j ^uCw/u 000A w-@@@{X>wEI^W2]9 I Xn`!͖/sc!cpapapap!pf" <׹'$FW6).hpm~p5ڼl"W@rhR9MtT^ZS% ?OfqjLI[Pn :կ9 ø1v'!7kY{ oJ5j$۝X~j`x]W^=Ks ! yHvgCODgq}E(&u MoҬz),9P؄W۴$?=`;$V(74cfE{z-%`vTwe]!~BN~h6!^ir7{ʫ +k6rVӃ~KSG\]Qetc Ta̺WHNe~u~9eqMdxbkbat-0.19.0/assets/completions/_bat.ps1.in000064400000000000000000000227250072674642500163160ustar 00000000000000 using namespace System.Management.Automation using namespace System.Management.Automation.Language Register-ArgumentCompleter -Native -CommandName '{{PROJECT_EXECUTABLE}}' -ScriptBlock { param($wordToComplete, $commandAst, $cursorPosition) $commandElements = $commandAst.CommandElements $command = @( '{{PROJECT_EXECUTABLE}}' for ($i = 1; $i -lt $commandElements.Count; $i++) { $element = $commandElements[$i] if ($element -isnot [StringConstantExpressionAst] -or $element.StringConstantType -ne [StringConstantType]::BareWord -or $element.Value.StartsWith('-')) { break } $element.Value }) -join ';' $completions = @(switch ($command) { '{{PROJECT_EXECUTABLE}}' { [CompletionResult]::new('-l', 'l', [CompletionResultType]::ParameterName, 'Set the language for syntax highlighting.') [CompletionResult]::new('--language', 'language', [CompletionResultType]::ParameterName, 'Set the language for syntax highlighting.') [CompletionResult]::new('-H', 'H', [CompletionResultType]::ParameterName, 'Highlight lines N through M.') [CompletionResult]::new('--highlight-line', 'highlight-line', [CompletionResultType]::ParameterName, 'Highlight lines N through M.') [CompletionResult]::new('--file-name', 'file-name', [CompletionResultType]::ParameterName, 'Specify the name to display for a file.') [CompletionResult]::new('--diff-context', 'diff-context', [CompletionResultType]::ParameterName, 'diff-context') [CompletionResult]::new('--tabs', 'tabs', [CompletionResultType]::ParameterName, 'Set the tab width to T spaces.') [CompletionResult]::new('--wrap', 'wrap', [CompletionResultType]::ParameterName, 'Specify the text-wrapping mode (*auto*, never, character).') [CompletionResult]::new('--terminal-width', 'terminal-width', [CompletionResultType]::ParameterName, 'Explicitly set the width of the terminal instead of determining it automatically. If prefixed with ''+'' or ''-'', the value will be treated as an offset to the actual terminal width. See also: ''--wrap''.') [CompletionResult]::new('--color', 'color', [CompletionResultType]::ParameterName, 'When to use colors (*auto*, never, always).') [CompletionResult]::new('--italic-text', 'italic-text', [CompletionResultType]::ParameterName, 'Use italics in output (always, *never*)') [CompletionResult]::new('--decorations', 'decorations', [CompletionResultType]::ParameterName, 'When to show the decorations (*auto*, never, always).') [CompletionResult]::new('--paging', 'paging', [CompletionResultType]::ParameterName, 'Specify when to use the pager, or use `-P` to disable (*auto*, never, always).') [CompletionResult]::new('--pager', 'pager', [CompletionResultType]::ParameterName, 'Determine which pager to use.') [CompletionResult]::new('-m', 'm', [CompletionResultType]::ParameterName, 'Use the specified syntax for files matching the glob pattern (''*.cpp:C++'').') [CompletionResult]::new('--map-syntax', 'map-syntax', [CompletionResultType]::ParameterName, 'Use the specified syntax for files matching the glob pattern (''*.cpp:C++'').') [CompletionResult]::new('--theme', 'theme', [CompletionResultType]::ParameterName, 'Set the color theme for syntax highlighting.') [CompletionResult]::new('--style', 'style', [CompletionResultType]::ParameterName, 'Comma-separated list of style elements to display (*auto*, full, plain, changes, header, grid, rule, numbers, snip).') [CompletionResult]::new('-r', 'r', [CompletionResultType]::ParameterName, 'Only print the lines from N to M.') [CompletionResult]::new('--line-range', 'line-range', [CompletionResultType]::ParameterName, 'Only print the lines from N to M.') [CompletionResult]::new('-A', 'A', [CompletionResultType]::ParameterName, 'Show non-printable characters (space, tab, newline, ..).') [CompletionResult]::new('--show-all', 'show-all', [CompletionResultType]::ParameterName, 'Show non-printable characters (space, tab, newline, ..).') [CompletionResult]::new('-p', 'p', [CompletionResultType]::ParameterName, 'Show plain style (alias for ''--style=plain'').') [CompletionResult]::new('--plain', 'plain', [CompletionResultType]::ParameterName, 'Show plain style (alias for ''--style=plain'').') [CompletionResult]::new('-d', 'd', [CompletionResultType]::ParameterName, 'Only show lines that have been added/removed/modified.') [CompletionResult]::new('--diff', 'diff', [CompletionResultType]::ParameterName, 'Only show lines that have been added/removed/modified.') [CompletionResult]::new('-n', 'n', [CompletionResultType]::ParameterName, 'Show line numbers (alias for ''--style=numbers'').') [CompletionResult]::new('--number', 'number', [CompletionResultType]::ParameterName, 'Show line numbers (alias for ''--style=numbers'').') [CompletionResult]::new('-f', 'f', [CompletionResultType]::ParameterName, 'f') [CompletionResult]::new('--force-colorization', 'force-colorization', [CompletionResultType]::ParameterName, 'force-colorization') [CompletionResult]::new('-P', 'P', [CompletionResultType]::ParameterName, 'Alias for ''--paging=never''') [CompletionResult]::new('--no-paging', 'no-paging', [CompletionResultType]::ParameterName, 'Alias for ''--paging=never''') [CompletionResult]::new('--list-themes', 'list-themes', [CompletionResultType]::ParameterName, 'Display all supported highlighting themes.') [CompletionResult]::new('-L', 'L', [CompletionResultType]::ParameterName, 'Display all supported languages.') [CompletionResult]::new('--list-languages', 'list-languages', [CompletionResultType]::ParameterName, 'Display all supported languages.') [CompletionResult]::new('-u', 'u', [CompletionResultType]::ParameterName, 'u') [CompletionResult]::new('--unbuffered', 'unbuffered', [CompletionResultType]::ParameterName, 'unbuffered') [CompletionResult]::new('--no-config', 'no-config', [CompletionResultType]::ParameterName, 'Do not use the configuration file') [CompletionResult]::new('--no-custom-assets', 'no-custom-assets', [CompletionResultType]::ParameterName, 'Do not load custom assets') [CompletionResult]::new('--config-file', 'config-file', [CompletionResultType]::ParameterName, 'Show path to the configuration file.') [CompletionResult]::new('--generate-config-file', 'generate-config-file', [CompletionResultType]::ParameterName, 'Generates a default configuration file.') [CompletionResult]::new('--config-dir', 'config-dir', [CompletionResultType]::ParameterName, 'Show bat''s configuration directory.') [CompletionResult]::new('--cache-dir', 'cache-dir', [CompletionResultType]::ParameterName, 'Show bat''s cache directory.') [CompletionResult]::new('--diagnostic', 'diagnostic', [CompletionResultType]::ParameterName, 'Show diagnostic information for bug reports.') [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print this help message.') [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print this help message.') [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Show version information.') [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Show version information.') [CompletionResult]::new('cache', 'cache', [CompletionResultType]::ParameterValue, 'Modify the syntax-definition and theme cache') break } '{{PROJECT_EXECUTABLE}};cache' { [CompletionResult]::new('--source', 'source', [CompletionResultType]::ParameterName, 'Use a different directory to load syntaxes and themes from.') [CompletionResult]::new('--target', 'target', [CompletionResultType]::ParameterName, 'Use a different directory to store the cached syntax and theme set.') [CompletionResult]::new('-b', 'b', [CompletionResultType]::ParameterName, 'Initialize (or update) the syntax/theme cache.') [CompletionResult]::new('--build', 'build', [CompletionResultType]::ParameterName, 'Initialize (or update) the syntax/theme cache.') [CompletionResult]::new('-c', 'c', [CompletionResultType]::ParameterName, 'Remove the cached syntax definitions and themes.') [CompletionResult]::new('--clear', 'clear', [CompletionResultType]::ParameterName, 'Remove the cached syntax definitions and themes.') [CompletionResult]::new('--blank', 'blank', [CompletionResultType]::ParameterName, 'Create completely new syntax and theme sets (instead of appending to the default sets).') [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Prints help information') [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Prints help information') [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Prints version information') [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Prints version information') break } }) $completions.Where{ $_.CompletionText -like "$wordToComplete*" } | Sort-Object -Property ListItemText } bat-0.19.0/assets/completions/bat.bash.in000064400000000000000000000041210072674642500163570ustar 00000000000000# shellcheck disable=SC2207 # Requires https://github.com/scop/bash-completion _bat() { local cur prev words cword split _init_completion -s || return 0 if [[ ${words[1]-} == cache ]]; then case $prev in --source | --target) _filedir -d return 0 ;; esac COMPREPLY=($(compgen -W " --build --clear --source --target --blank --help " -- "$cur")) return 0 fi case $prev in -l | --language) local IFS=$'\n' COMPREPLY=($(compgen -W "$( "$1" --list-languages | while IFS=: read -r lang _; do printf "%s\n" "$lang" done )" -- "$cur")) compopt -o filenames # for escaping return 0 ;; -H | --highlight-line | --diff-context | --tabs | --terminal-width | \ -m | --map-syntax | --style | --line-range | -h | --help | -V | \ --version | --diagnostic | --config-file | --config-dir | \ --cache-dir | --generate-config-file) # argument required but no completion available, or option # causes an exit return 0 ;; --file-name) _filedir return 0 ;; --wrap) COMPREPLY=($(compgen -W "auto never character" -- "$cur")) return 0 ;; --color | --decorations | --paging) COMPREPLY=($(compgen -W "auto never always" -- "$cur")) return 0 ;; --italic-text) COMPREPLY=($(compgen -W "always never" -- "$cur")) return 0 ;; --pager) COMPREPLY=($(compgen -c -- "$cur")) return 0 ;; --theme) local IFS=$'\n' COMPREPLY=($(compgen -W "$("$1" --list-themes)" -- "$cur")) compopt -o filenames # for escaping return 0 ;; esac $split && return 0 if [[ $cur == -* ]]; then COMPREPLY=($(compgen -W " --show-all --plain --language --highlight-line --file-name --diff --diff-context --tabs --wrap --terminal-width --number --color --italic-text --decorations --paging --pager --map-syntax --theme --list-themes --style --line-range --list-languages --help --version --force-colorization --unbuffered --diagnostic --config-file --config-dir --cache-dir --generate-config-file " -- "$cur")) return 0 fi _filedir ((cword == 1)) && COMPREPLY+=($(compgen -W cache -- "$cur")) } && complete -F _bat {{PROJECT_EXECUTABLE}} bat-0.19.0/assets/completions/bat.fish.in000064400000000000000000000121600072674642500163750ustar 00000000000000# Fish Shell Completions # Place or symlink to $XDG_CONFIG_HOME/fish/completions/{{PROJECT_EXECUTABLE}}.fish ($XDG_CONFIG_HOME is usually set to ~/.config) # Helper function: function __{{PROJECT_EXECUTABLE}}_autocomplete_languages --description "A helper function used by "(status filename) {{PROJECT_EXECUTABLE}} --list-languages | awk -F':' ' { lang=$1 split($2, exts, ",") for (i in exts) { ext=exts[i] if (ext !~ /[A-Z].*/ && ext !~ /^\..*rc$/) { print ext"\t"lang } } } ' | sort end # Completions: complete -c {{PROJECT_EXECUTABLE}} -l color -xka "auto never always" -d "Specify when to use colored output (default: auto)" -n "not __fish_seen_subcommand_from cache" complete -c {{PROJECT_EXECUTABLE}} -l config-dir -d "Display location of '{{PROJECT_EXECUTABLE}}' configuration directory" -n "not __fish_seen_subcommand_from cache" complete -c {{PROJECT_EXECUTABLE}} -l config-file -d "Display location of '{{PROJECT_EXECUTABLE}}' configuration file" -n "not __fish_seen_subcommand_from cache" complete -c {{PROJECT_EXECUTABLE}} -l decorations -xka "auto never always" -d "Specify when to use the decorations specified with '--style' (default: auto)" -n "not __fish_seen_subcommand_from cache" complete -c {{PROJECT_EXECUTABLE}} -s h -l help -d "Print help message" -n "not __fish_seen_subcommand_from cache" complete -c {{PROJECT_EXECUTABLE}} -s H -l highlight-line -x -d " Highlight the N-th line with a different background color" -n "not __fish_seen_subcommand_from cache" complete -c {{PROJECT_EXECUTABLE}} -l italic-text -xka "always never" -d "Specify when to use ANSI sequences for italic text (default: never)" -n "not __fish_seen_subcommand_from cache" complete -c {{PROJECT_EXECUTABLE}} -s l -l language -d "Set the language for syntax highlighting" -n "not __fish_seen_subcommand_from cache" -xa "(__{{PROJECT_EXECUTABLE}}_autocomplete_languages)" complete -c {{PROJECT_EXECUTABLE}} -s r -l line-range -x -d " Only print the specified range of lines for each file" -n "not __fish_seen_subcommand_from cache" complete -c {{PROJECT_EXECUTABLE}} -l list-languages -d "Display list of supported languages for syntax highlighting" -n "not __fish_seen_subcommand_from cache" complete -c {{PROJECT_EXECUTABLE}} -l list-themes -d "Display a list of supported themes for syntax highlighting" -n "not __fish_seen_subcommand_from cache" complete -c {{PROJECT_EXECUTABLE}} -s m -l map-syntax -x -d " Map a file extension or file name to an existing syntax" -n "not __fish_seen_subcommand_from cache" complete -c {{PROJECT_EXECUTABLE}} -s n -l number -d "Only show line numbers, no other decorations. Alias for '--style=numbers'" -n "not __fish_seen_subcommand_from cache" complete -c {{PROJECT_EXECUTABLE}} -l pager -x -d " Specify which pager program to use (default: less)" -n "not __fish_seen_subcommand_from cache" complete -c {{PROJECT_EXECUTABLE}} -l paging -xka "auto never always" -d "Specify when to use the pager (default: auto)" -n "not __fish_seen_subcommand_from cache" complete -c {{PROJECT_EXECUTABLE}} -s p -l plain -d "Only show plain style, no decorations. Alias for '--style=plain'" -n "not __fish_seen_subcommand_from cache" complete -c {{PROJECT_EXECUTABLE}} -s P -d "Disable paging. Alias for '--paging=never'" -n "not __fish_seen_subcommand_from cache" complete -c {{PROJECT_EXECUTABLE}} -s A -l show-all -d "Show non-printable characters like space/tab/newline" -n "not __fish_seen_subcommand_from cache" complete -c {{PROJECT_EXECUTABLE}} -l style -xka "auto full plain changes header grid rule numbers snip" -d "Comma-separated list of style elements or presets to display with file contents" -n "not __fish_seen_subcommand_from cache" complete -c {{PROJECT_EXECUTABLE}} -l tabs -x -d " Set the tab width to T spaces (width of 0 passes tabs through directly)" -n "not __fish_seen_subcommand_from cache" complete -c {{PROJECT_EXECUTABLE}} -l terminal-width -x -d " Explicitly set terminal width; Prefix with '+' or '-' to offset (default width is auto determined)" -n "not __fish_seen_subcommand_from cache" complete -c {{PROJECT_EXECUTABLE}} -l theme -xka "({{PROJECT_EXECUTABLE}} --list-themes | cat)" -d "Set the theme for syntax highlighting" -n "not __fish_seen_subcommand_from cache" complete -c {{PROJECT_EXECUTABLE}} -s u -l unbuffered -d "POSIX-compliant unbuffered output. Option is ignored" -n "not __fish_seen_subcommand_from cache" complete -c {{PROJECT_EXECUTABLE}} -s V -l version -d "Show version information" -n "not __fish_seen_subcommand_from cache" complete -c {{PROJECT_EXECUTABLE}} -l wrap -xka "auto never character" -d " Specify the text-wrapping mode (default: auto)" -n "not __fish_seen_subcommand_from cache" # Sub-command 'cache' completions complete -c {{PROJECT_EXECUTABLE}} -a "cache" -d "Modify the syntax/language definition cache" -n "not __fish_seen_subcommand_from cache" complete -c {{PROJECT_EXECUTABLE}} -l build -f -d "Parse syntaxes/language definitions into cache" -n "__fish_seen_subcommand_from cache" complete -c {{PROJECT_EXECUTABLE}} -l clear -f -d "Reset syntaxes/language definitions to default settings" -n "__fish_seen_subcommand_from cache" bat-0.19.0/assets/completions/bat.zsh.in000064400000000000000000000111710072674642500162510ustar 00000000000000#compdef {{PROJECT_EXECUTABLE}} local context state state_descr line typeset -A opt_args (( $+functions[_{{PROJECT_EXECUTABLE}}_cache_subcommand] )) || _{{PROJECT_EXECUTABLE}}_cache_subcommand() { local -a args args=( '(-b --build -c --clear)'{-b,--build}'[Initialize or update the syntax/theme cache]' '(-b --build -c --clear)'{-c,--clear}'[Remove the cached syntax definitions and themes]' '(--source)'--source='[Use a different directory to load syntaxes and themes from]:directory:_files -/' '(--target)'--target='[Use a different directory to store the cached syntax and theme set]:directory:_files -/' '(--blank)'--blank'[Create completely new syntax and theme sets]' '(: -)'{-h,--help}'[Prints help information]' '*: :' ) _arguments -S -s $args } (( $+functions[_{{PROJECT_EXECUTABLE}}_main] )) || _{{PROJECT_EXECUTABLE}}_main() { local -a args args=( '(-A --show-all)'{-A,--show-all}'[Show non-printable characters (space, tab, newline, ..)]' '*'{-p,--plain}'[Show plain style (alias for `--style=plain`), repeat twice to disable disable automatic paging (alias for `--paging=never`)]' '(-l --language)'{-l+,--language=}'[Set the language for syntax highlighting]::->language' '(-H --highlight-line)'{-H,--highlight-line}'[Highlight lines N through M]:...' '(--file-name)'--file-name'[Specify the name to display for a file]:...:_files' '(-d --diff)'--diff'[Only show lines that have been added/removed/modified]' '(--diff-context)'--diff-context'[Include N lines of context around added/removed/modified lines when using `--diff`]: (lines):()' '(--tabs)'--tabs'[Set the tab width to T spaces]: (tab width):()' '(--wrap)'--wrap='[Specify the text-wrapping mode]::(auto never character)' '(--terminal-width)'--terminal-width'[Explicitly set the width of the terminal instead of determining it automatically]:' '(-n --number)'{-n,--number}'[Show line numbers]' '(--color)'--color='[When to use colors]::(auto never always)' '(--italic-text)'--italic-text='[Use italics in output]::(always never)' '(--decorations)'--decorations='[When to show the decorations]::(auto never always)' '(--paging)'--paging='[Specify when to use the pager]::(auto never always)' '(-m --map-syntax)'{-m+,--map-syntax=}'[Use the specified syntax for files matching the glob pattern]:...' '(--theme)'--theme='[Set the color theme for syntax highlighting]::->theme' '(: --list-themes --list-languages -L)'--list-themes'[Display all supported highlighting themes]' '(--style)'--style='[Comma-separated list of style elements to display]::->style' '(-r --line-range)'{-r+,--line-range=}'[Only print the lines from N to M]:...' '(: --list-themes --list-languages -L)'{-L,--list-languages}'[Display all supported languages]' '(: --no-config)'--no-config'[Do not use the configuration file]' '(: --no-custom-assets)'--no-custom-assets'[Do not load custom assets]' '(: --config-dir)'--config-dir'[Show bat'"'"'s configuration directory]' '(: --config-file)'--config-file'[Show path to the configuration file]' '(: --generate-config-file)'--generate-config-file'[Generates a default configuration file]' '(: --cache-dir)'--cache-dir'[Show bat'"'"'s cache directory]' '(: -)'{-h,--help}'[Print this help message]' '(: -)'{-V,--version}'[Show version information]' '*: :_files' ) _arguments -S -s $args case "$state" in language) local IFS=$'\n' local -a languages languages=( $({{PROJECT_EXECUTABLE}} --list-languages | awk -F':|,' '{ for (i = 1; i <= NF; ++i) printf("%s:%s\n", $i, $1) }') ) _describe 'language' languages ;; theme) local IFS=$'\n' local -a themes themes=( $({{PROJECT_EXECUTABLE}} --list-themes | sort) ) _values 'theme' $themes ;; style) _values -s , 'style' auto full plain changes header grid rule numbers snip ;; esac } # first positional argument if (( ${#words} == 2 )); then local -a subcommands subcommands=('cache:Modify the syntax-definition and theme cache') _describe subcommand subcommands _{{PROJECT_EXECUTABLE}}_main else case $words[2] in cache) _{{PROJECT_EXECUTABLE}}_cache_subcommand ;; *) _{{PROJECT_EXECUTABLE}}_main ;; esac fi bat-0.19.0/assets/create.sh000075500000000000000000000034610072674642500136210ustar 00000000000000#!/usr/bin/env bash set -euo pipefail ASSET_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" REPO_DIR="$ASSET_DIR/.." # Ensure submodules are initialized. update_submodules() { local submodule local submodule_prompt=unspecified local submodule_path { while { read -r submodule && read -r submodule_path; } <&3; do if ! [[ -d "${REPO_DIR}/.git/modules/${submodule}" ]] && [[ -d "${REPO_DIR}/${submodule_path}" ]]; then if [[ "$submodule_prompt" = "unspecified" ]]; then echo "One or more submodules were found to be uninitialized." printf "Initialize and update them? [Y/n] " read -r submodule_prompt fi case "$submodule_prompt" in y|yes|'') { git -C "$REPO_DIR" submodule update --init "$submodule_path" };; n|no) { return };; *) { echo "Unknown answer. Not updating submodules." };; esac fi done } 3< <(git config --file "${REPO_DIR}/.gitmodules" --null --get-regexp path | xargs -0 printf "%s\n" | sed 's/^submodule.//;s/.path$//') } if [ -t 0 ]; then update_submodules fi # Always remove the local cache to avoid any confusion bat cache --clear # TODO: # - Remove the JavaDoc patch once https://github.com/trishume/syntect/issues/222 has been fixed # - Remove the C# patch once https://github.com/sublimehq/Packages/pull/2331 has been merged # Apply patches ( cd "$ASSET_DIR" for patch in patches/*.patch; do patch --strip=0 < "$patch" done ) reverse_patches() { ( cd "$ASSET_DIR" for patch in patches/*.patch; do patch --strip=0 --reverse <"$patch" done ) } # Make sure to always reverse patches, even if the `bat cache` command fails or aborts trap reverse_patches EXIT bat cache --build --blank --acknowledgements --source="$ASSET_DIR" --target="$ASSET_DIR" bat-0.19.0/assets/manual/bat.1.in000064400000000000000000000237630072674642500145400ustar 00000000000000.TH {{PROJECT_EXECUTABLE_UPPERCASE}} "1" .SH NAME {{PROJECT_EXECUTABLE}} \- a cat(1) clone with syntax highlighting and Git integration. .SH "USAGE" .IP "{{PROJECT_EXECUTABLE}} [OPTIONS] [FILE]..." .IP "{{PROJECT_EXECUTABLE}} cache [CACHE-OPTIONS] [--build|--clear] .SH DESCRIPTION {{PROJECT_EXECUTABLE}} prints the syntax-highlighted content of a collection of FILEs to the terminal. If no FILE is specified, or when FILE is '-', it reads from standard input. {{PROJECT_EXECUTABLE}} supports a large number of programming and markup languages. It also communicates with git(1) to show modifications with respect to the git index. {{PROJECT_EXECUTABLE}} automatically pipes its output through a pager (by default: less). Whenever the output of {{PROJECT_EXECUTABLE}} goes to a non-interactive terminal, i.e. when the output is piped into another process or into a file, {{PROJECT_EXECUTABLE}} will act as a drop-in replacement for cat(1) and fall back to printing the plain file contents. .SH "OPTIONS" General remarks: Command-line options like '-l'/'--language' that take values can be specified as either '--language value', '--language=value', '-l value' or '-lvalue'. .HP \fB\-A\fR, \fB\-\-show\-all\fR .IP Show non\-printable characters like space, tab or newline. Use '\-\-tabs' to control the width of the tab\-placeholders. .HP \fB\-p\fR, \fB\-\-plain\fR .IP Only show plain style, no decorations. This is an alias for \&'\-\-style=plain'. When '\-p' is used twice ('\-pp'), it also disables automatic paging (alias for '\-\-style=plain \fB\-\-pager\fR=\fI\,never\/\fR'). .HP \fB\-l\fR, \fB\-\-language\fR .IP Explicitly set the language for syntax highlighting. The language can be specified as a name (like 'C++' or 'LaTeX') or possible file extension (like 'cpp', 'hpp' or 'md'). Use '\-\-list\-languages' to show all supported language names and file extensions. .HP \fB\-H\fR, \fB\-\-highlight\-line\fR ... .IP Highlight the specified line ranges with a different background color. For example: .RS .IP "\-\-highlight\-line 40" highlights line 40 .IP "\-\-highlight\-line 30:40" highlights lines 30 to 40 .IP "\-\-highlight\-line :40" highlights lines 1 to 40 .IP "\-\-highlight\-line 40:" highlights lines 40 to the end of the file .IP "\-\-highlight\-line 30:+10" highlights lines 30 to 40 .RE .HP \fB\-\-file\-name\fR ... .IP Specify the name to display for a file. Useful when piping data to {{PROJECT_EXECUTABLE}} from STDIN when {{PROJECT_EXECUTABLE}} does not otherwise know the filename. Note that the provided file name is also used for syntax detection. .HP \fB\-d\fR, \fB\-\-diff\fR .IP Only show lines that have been added/removed/modified with respect to the Git index. Use '\-\-diff\-context=N' to control how much context you want to see. .HP \fB\-\-diff\-context\fR ... .IP Include N lines of context around added/removed/modified lines when using '\-\-diff'. .HP \fB\-\-tabs\fR .IP Set the tab width to T spaces. Use a width of 0 to pass tabs through directly .HP \fB\-\-wrap\fR .IP Specify the text\-wrapping mode (*auto*, never, character). The '\-\-terminal\-width' option can be used in addition to control the output width. .HP \fB\-\-terminal\-width\fR .IP Explicitly set the width of the terminal instead of determining it automatically. If prefixed with '+' or '\-', the value will be treated as an offset to the actual terminal width. See also: '\-\-wrap'. .HP \fB\-n\fR, \fB\-\-number\fR .IP Only show line numbers, no other decorations. This is an alias for '\-\-style=numbers' .HP \fB\-\-color\fR .IP Specify when to use colored output. The automatic mode only enables colors if an interactive terminal is detected. Possible values: *auto*, never, always. .HP \fB\-\-italic\-text\fR .IP Specify when to use ANSI sequences for italic text in the output. Possible values: always, *never*. .HP \fB\-\-decorations\fR .IP Specify when to use the decorations that have been specified via '\-\-style'. The automatic mode only enables decorations if an interactive terminal is detected. Possible values: *auto*, never, always. .HP \fB\-f\fR, \fB\-\-force\-colorization\fR .IP Alias for '--decorations=always --color=always'. This is useful \ if the output of {{PROJECT_EXECUTABLE}} is piped to another program, but you want \ to keep the colorization/decorations. .HP \fB\-\-paging\fR .IP Specify when to use the pager. To disable the pager, use \&'\-\-paging=never' or its alias, \fB-P\fR. To disable the pager permanently, set BAT_PAGER to an empty string. To control which pager is used, see the '\-\-pager' option. Possible values: *auto*, never, always. .HP \fB\-\-pager\fR .IP Determine which pager is used. This option will override the PAGER and BAT_PAGER environment variables. The default pager is 'less'. To control when the pager is used, see the '\-\-paging' option. Example: '\-\-pager "less \fB\-RF\fR"'. Note: By default, if the pager is set to 'less' (and no command-line options are specified), 'bat' will pass the following command line options to the pager: '-R'/'--RAW-CONTROL-CHARS', '-F'/'--quit-if-one-screen' and '-X'/'--no-init'. The last option ('-X') is only used for 'less' versions older than 530. The '-R' option is needed to interpret ANSI colors correctly. The second option ('-F') instructs less to exit immediately if the output size is smaller than the vertical size of the terminal. This is convenient for small files because you do not have to press 'q' to quit the pager. The third option ('-X') is needed to fix a bug with the '--quit-if-one-screen' feature in old versions of 'less'. Unfortunately, it also breaks mouse-wheel support in 'less'. If you want to enable mouse-wheel scrolling on older versions of 'less', you can pass just '-R' (as in the example above, this will disable the quit-if-one-screen feature). For less 530 or newer, it should work out of the box. .HP \fB\-m\fR, \fB\-\-map\-syntax\fR ... .IP Map a glob pattern to an existing syntax name. The glob pattern is matched on the full path and the filename. For example, to highlight *.build files with the Python syntax, use -m '*.build:Python'. To highlight files named '.myignore' with the Git Ignore syntax, use -m '.myignore:Git Ignore'. Note that the right-hand side is the *name* of the syntax, not a file extension. .HP \fB\-\-theme\fR .IP Set the theme for syntax highlighting. Use '\-\-list\-themes' to see all available themes. To set a default theme, add the '\-\-theme="..."' option to the configuration file or export the BAT_THEME environment variable (e.g.: export BAT_THEME="..."). .HP \fB\-\-list\-themes\fR .IP Display a list of supported themes for syntax highlighting. .HP \fB\-\-style\fR .IP Configure which elements (line numbers, file headers, grid borders, Git modifications, \&..) to display in addition to the file contents. The argument is a comma\-separated list of components to display (e.g. 'numbers,changes,grid') or a pre\-defined style ('full'). To set a default style, add the '\-\-style=".."' option to the configuration file or export the BAT_STYLE environment variable (e.g.: export BAT_STYLE=".."). Possible values: *full*, auto, plain, changes, header, grid, rule, numbers, snip. .HP \fB\-r\fR, \fB\-\-line\-range\fR ... .IP Only print the specified range of lines for each file. For example: .RS .IP "\-\-line\-range 30:40" prints lines 30 to 40 .IP "\-\-line\-range :40" prints lines 1 to 40 .IP "\-\-line\-range 40:" prints lines 40 to the end of the file .IP "\-\-line\-range 30:+10" prints lines 30 to 40 .RE .HP \fB\-L\fR, \fB\-\-list\-languages\fR .IP Display a list of supported languages for syntax highlighting. .HP \fB\-u\fR, \fB\-\-unbuffered\fR .IP This option exists for POSIX\-compliance reasons ('u' is for 'unbuffered'). The output is always unbuffered \- this option is simply ignored. .HP \fB\-h\fR, \fB\-\-help\fR .IP Print this help message. .HP \fB\-V\fR, \fB\-\-version\fR .IP Show version information. .SH "POSITIONAL ARGUMENTS" .HP \fB...\fR .IP Files to print and concatenate. Use a dash ('\-') or no argument at all to read from standard input. .SH "SUBCOMMANDS" .HP \fBcache\fR - Modify the syntax\-definition and theme cache. .SH "FILES" {{PROJECT_EXECUTABLE}} can also be customized with a configuration file. The location of the file is dependent on your operating system. To get the default path for your system, call: \fB{{PROJECT_EXECUTABLE}} --config-file\fR Alternatively, you can use the BAT_CONFIG_PATH environment variable to point {{PROJECT_EXECUTABLE}} to a non-default location of the configuration file. To generate a default configuration file, call: \fB{{PROJECT_EXECUTABLE}} --generate-config-file\fR .SH "ADDING CUSTOM LANGUAGES" {{PROJECT_EXECUTABLE}} supports Sublime Text \fB.sublime-syntax\fR language files, and can be customized to add additional languages to your local installation. To do this, add the \fB.sublime-syntax\fR language files to `\fB$({{PROJECT_EXECUTABLE}} --config-dir)/syntaxes\fR` and run `\fB{{PROJECT_EXECUTABLE}} cache --build\fR`. \fBExample:\fR .RS 0.5i mkdir -p "$({{PROJECT_EXECUTABLE}} --config-dir)/syntaxes" .br cd "$({{PROJECT_EXECUTABLE}} --config-dir)/syntaxes" # Put new '.sublime-syntax' language definition files .br # in this folder (or its subdirectories), for example: .br git clone https://github.com/tellnobody1/sublime-purescript-syntax # And then build the cache. .br {{PROJECT_EXECUTABLE}} cache --build .RE Once the cache is built, the new language will be visible in `\fB{{PROJECT_EXECUTABLE}} --list-languages\fR`. .br If you ever want to remove the custom languages, you can clear the cache with `\fB{{PROJECT_EXECUTABLE}} cache --clear\fR`. .SH "ADDING CUSTOM THEMES" Similarly to custom languages, {{PROJECT_EXECUTABLE}} supports Sublime Text \fB.tmTheme\fR themes. These can be installed to `\fB$({{PROJECT_EXECUTABLE}} --config-dir)/themes\fR`, and are added to the cache with `\fB{{PROJECT_EXECUTABLE}} cache --build`. .SH "MORE INFORMATION" For more information and up-to-date documentation, visit the {{PROJECT_EXECUTABLE}} repo: .br \fBhttps://github.com/sharkdp/bat\fR bat-0.19.0/assets/patches/C#.sublime-syntax.patch000064400000000000000000000011060072674642500176710ustar 00000000000000diff --git syntaxes/01_Packages/C#/C#.sublime-syntax syntaxes/01_Packages/C#/C#.sublime-syntax index ed494f8b..01b710e8 100644 --- syntaxes/01_Packages/C#/C#.sublime-syntax +++ syntaxes/01_Packages/C#/C#.sublime-syntax @@ -1312,7 +1312,7 @@ contexts: 2: punctuation.separator.cs 3: punctuation.section.brackets.end.cs 4: keyword.operator.pointer.cs - - match: \((?=(?:[^,)(]*|\([^\)]*\))*,) + - match: \((?=(?:[^,)(]|\([^\)]*\))*,) scope: punctuation.section.group.begin.cs push: - meta_scope: meta.group.tuple.cs bat-0.19.0/assets/patches/Groff.sublime-syntax.patch000064400000000000000000000011010072674642500205020ustar 00000000000000diff --git syntaxes/02_Extra/Groff/Man Page/Man Page.sublime-syntax syntaxes/02_Extra/Groff/Man Page/Man Page.sublime-syntax index 57834af..6648664 100644 --- syntaxes/02_Extra/Groff/Man Page/Man Page.sublime-syntax +++ syntaxes/02_Extra/Groff/Man Page/Man Page.sublime-syntax @@ -4,9 +4,9 @@ # - man-pages(7) # - groff(7) --- -name: Man Page (groff/troff) +name: Groff/troff scope: text.groff -file_extensions: [man, groff, troff, '1', '2', '3', '4', '5', '6', '7'] +file_extensions: [groff, troff, '1', '2', '3', '4', '5', '6', '7', '8', '9'] contexts: main: bat-0.19.0/assets/patches/JavaDoc.sublime-syntax.patch000064400000000000000000000010350072674642500207540ustar 00000000000000diff --git syntaxes/01_Packages/Java/JavaDoc.sublime-syntax syntaxes/01_Packages/Java/JavaDoc.sublime-syntax index 422a6a9..40a741e 100644 --- syntaxes/01_Packages/Java/JavaDoc.sublime-syntax +++ syntaxes/01_Packages/Java/JavaDoc.sublime-syntax @@ -13,7 +13,7 @@ variables: contexts: prototype: # https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#leadingasterisks - - match: ^\s*(\*)\s*(?!\s*@) + - match: ^\s*(\*)(?!/)\s*(?!\s*@) captures: 1: punctuation.definition.comment.javadoc bat-0.19.0/assets/patches/Makefile.sublime-syntax.patch000064400000000000000000000064530072674642500211730ustar 00000000000000diff --git syntaxes/01_Packages/Makefile/Makefile.sublime-syntax syntaxes/01_Packages/Makefile/Makefile.sublime-syntax index 3cc3a97e..0c7a3f24 100644 --- syntaxes/01_Packages/Makefile/Makefile.sublime-syntax +++ syntaxes/01_Packages/Makefile/Makefile.sublime-syntax @@ -44,64 +44,50 @@ variables: # variable substitutions anywhere. We try to remedy this by hacking in a # regex that matches up to four levels of nested parentheses, and ignores # whatever's inside the parentheses. - nps: '[^()]*' - open: '(?:\(' - close: '\))?' # ignore this invalid.illegal + nps_unnested: '[^()]*' + nps: '[^()]*(?=[()])' + open: '(?:{{nps}}\(' + close: '\){{nps_unnested}})?' # ignore this invalid.illegal just_eat: | # WARNING: INSANITY FOLLOWS! - (?x) # ignore whitespace in this regex - {{nps}} # level 0 + (?x)(?: # ignore whitespace in this regex {{open}} # start level 1 __ - {{nps}} # level 1 _______ /*_>-< {{open}} # start level 2 ___/ _____ \__/ / - {{nps}} # level 2 <____/ \____/ {{open}} # start level 3 is like snek... (by Valerie Haecky) - {{nps}} # level 3 {{open}} # start level 4 {{nps}} # level 4 {{close}} # end level 4 - {{nps}} # level 3 {{close}} # end level 3 - {{nps}} # level 2 {{open}} # start level 3 - {{nps}} # level 3 {{open}} # start level 4 {{nps}} # level 4 {{close}} # end level 4 - {{nps}} # level 3 {{close}} # end level 3 - {{nps}} # level 2 + {{nps}} {{close}} # end level 2 - {{nps}} # level 1 {{open}} # start level 2 - {{nps}} # level 2 {{open}} # start level 3 - {{nps}} # level 3 {{open}} # start level 4 {{nps}} # level 4 {{close}} # end level 4 - {{nps}} # level 3 + {{nps}} {{close}} # end level 3 - {{nps}} # level 2 {{open}} # start level 3 - {{nps}} # level 3 {{open}} # start level 4 {{nps}} # level 4 {{close}} # end level 4 - {{nps}} # level 3 + {{nps}} {{close}} # end level 3 - {{nps}} # level 2 {{open}} # start level 3 - {{nps}} # level 3 {{open}} # start level 4 {{nps}} # level 4 {{close}} # end level 4 - {{nps}} # level 3 + {{nps}} {{close}} # end level 3 - {{nps}} # level 2 + {{nps}} {{close}} # end level 2 - {{nps}} # level 1 + {{nps}} {{close}} # end level 1 - {{nps}} # level 0 + |{{nps_unnested}}) rule_lookahead: '{{just_eat}}{{ruleassign}}{{just_eat}}' var_lookahead_base: '{{just_eat}}({{varassign}}|{{shellassign}}){{just_eat}}' bat-0.19.0/assets/patches/Markdown.sublime-syntax.patch000064400000000000000000000163710072674642500212400ustar 00000000000000diff --git syntaxes/01_Packages/Markdown/Markdown.sublime-syntax syntaxes/01_Packages/Markdown/Markdown.sublime-syntax index 19dc685d..44440c7f 100644 --- syntaxes/01_Packages/Markdown/Markdown.sublime-syntax +++ syntaxes/01_Packages/Markdown/Markdown.sublime-syntax @@ -24,7 +24,6 @@ variables: ) [ \t]*$ # followed by any number of tabs or spaces, followed by the end of the line ) - setext_escape: ^(?=\s{0,3}(?:---+|===+)\s*$) block_quote: (?:[ ]{,3}>(?:.|$)) # between 0 and 3 spaces, followed by a greater than sign, followed by any character or the end of the line atx_heading: (?:[#]{1,6}\s*) # between 1 and 6 hashes, followed by any amount of whitespace indented_code_block: (?:[ ]{4}|\t) # 4 spaces or a tab @@ -277,69 +276,40 @@ contexts: 8: markup.underline.link.markdown push: [link-ref-def, after-link-title, link-title] - match: '^(?=\S)(?![=-]{3,}\s*$)' - branch_point: heading2-branch - branch: - - not-heading2 - - heading2 - - not-paragraph: - - match: |- - (?x) # pop out of this context when one of the following conditions are met: - ^(?: - \s*$ # the line is blank (or only contains whitespace) - | (?= - {{block_quote}} # a block quote begins the line - | [ ]{,3}[*+-][ ] # an unordered list item begins the line - | [ ]{,3}1[.][ ] # an ordered list item with number "1" begins the line - | \# # an ATX heading begins the line - | [ ]{,3}<( # all types of HTML blocks except type 7 may interrupt a paragraph - {{html_tag_block_end_at_close_tag}} # 1 - | !-- # 2 - | \? # 3 - | ![A-Z] # 4 - | !\[CDATA\[ # 5 - | {{html_tag_block_end_at_blank_line}} # 6 + push: + - meta_scope: meta.paragraph.markdown + - match: |- + (?x) # pop out of this context when one of the following conditions are met: + ^(?: + \s*$ # the line is blank (or only contains whitespace) + | (?= + {{block_quote}} # a block quote begins the line + | [ ]{,3}[*+-][ ] # an unordered list item begins the line + | [ ]{,3}1[.][ ] # an ordered list item with number "1" begins the line + | \# # an ATX heading begins the line + | [ ]{,3}<( # all types of HTML blocks except type 7 may interrupt a paragraph + {{html_tag_block_end_at_close_tag}} # 1 + | !-- # 2 + | \? # 3 + | ![A-Z] # 4 + | !\[CDATA\[ # 5 + | {{html_tag_block_end_at_blank_line}} # 6 + ) ) ) - ) - pop: true - - not-heading2: - - include: not-paragraph - - match: (?=\S) - branch_point: heading1-branch - branch: - - paragraph - - heading1 - - match: '' - pop: true - - paragraph: - - meta_scope: meta.paragraph.markdown - - match: ^\s{0,3}===+\s*$ - fail: heading1-branch - - match: ^\s{0,3}---+\s*$ - fail: heading2-branch - - include: not-paragraph - - include: inline-bold-italic-linebreak - - include: scope:text.html.basic - - heading1: - - meta_scope: markup.heading.1.markdown - - include: inline-bold-italic-linebreak - - match: '^[ \t]{0,3}(={3,})(?=[ \t]*$)' - captures: - 1: markup.heading.1.setext.markdown punctuation.definition.heading.setext.markdown - pop: true - - heading2: - - meta_scope: markup.heading.2.markdown - - include: inline-bold-italic-linebreak - - match: '^[ \t]{0,3}(-{3,})(?=[ \t]*$)' - captures: - 1: markup.heading.2.setext.markdown punctuation.definition.heading.setext.markdown - pop: true - + pop: true + - include: inline-bold-italic-linebreak + - include: scope:text.html.basic + - match: '^(={3,})(?=[ \t]*$)' + scope: markup.heading.1.setext.markdown + captures: + 1: punctuation.definition.heading.setext.markdown + pop: true + - match: '^(-{3,})(?=[ \t]*$)' + scope: markup.heading.2.setext.markdown + captures: + 1: punctuation.definition.heading.setext.markdown + pop: true link-ref-def: - meta_scope: meta.link.reference.def.markdown - match: '' @@ -430,8 +400,6 @@ contexts: push: - meta_scope: markup.bold.markdown - meta_content_scope: markup.italic.markdown - - match: '{{setext_escape}}' - pop: true - match: |- (?x) [ \t]*\*{4,} # if there are more than 3 its not applicable to be bold or italic @@ -446,8 +414,6 @@ contexts: scope: punctuation.definition.bold.end.markdown set: - meta_content_scope: markup.italic.markdown - - match: '{{setext_escape}}' - pop: true - match: |- (?x) [ \t]*\*{3,} # if there are more than 3 its not applicable to be bold or italic @@ -463,8 +429,6 @@ contexts: scope: punctuation.definition.italic.end.markdown set: - meta_content_scope: markup.bold.markdown - - match: '{{setext_escape}}' - pop: true - match: |- (?x) [ \t]*\*{3,} # if there are more than 3 its not applicable to be bold or italic @@ -727,8 +691,6 @@ contexts: scope: punctuation.definition.italic.begin.markdown push: - meta_scope: markup.italic.markdown - - match: '{{setext_escape}}' - pop: true - match: |- (?x) [ \t]*\*{4,} # if there are more than 3 its not applicable to be bold or italic @@ -745,8 +707,6 @@ contexts: scope: punctuation.definition.italic.begin.markdown push: - meta_scope: markup.italic.markdown - - match: '{{setext_escape}}' - pop: true - match: |- (?x) [ \t]*_{4,} # if there are more than 3 its not applicable to be bold or italic @@ -773,8 +733,6 @@ contexts: - include: bold-italic-trailing bold-italic-trailing: - include: scope:text.html.basic - - match: '{{setext_escape}}' - pop: true - match: ^\s*$\n? scope: invalid.illegal.non-terminated.bold-italic.markdown pop: true @@ -1152,7 +1110,7 @@ contexts: - match: |- (?x) {{fenced_code_block_start}} - ((?i:rust)) + ((?i:rust|rs)) {{fenced_code_block_trailing_infostring_characters}} captures: 0: meta.code-fence.definition.begin.rust.markdown-gfm bat-0.19.0/assets/patches/MediaWiki.sublime-syntax.patch000064400000000000000000000007200072674642500213100ustar 00000000000000diff --git syntaxes/02_Extra/MediaWiki/MediawikiNG.sublime-syntax syntaxes/02_Extra/MediaWiki/MediawikiNG.sublime-syntax index f542c9e..8eaf020 100644 --- syntaxes/02_Extra/MediaWiki/MediawikiNG.sublime-syntax +++ syntaxes/02_Extra/MediaWiki/MediawikiNG.sublime-syntax @@ -1,7 +1,7 @@ %YAML 1.2 --- # http://www.sublimetext.com/docs/3/syntax.html -name: Mediawiki NG +name: MediaWiki file_extensions: [mediawiki, wikipedia, wiki] scope: text.html.mediawiki bat-0.19.0/assets/patches/Monokai-Extended.tmTheme.patch000064400000000000000000000024140072674642500212210ustar 00000000000000diff --git themes/sublime-monokai-extended/Monokai\ Extended.tmTheme themes/sublime-monokai-extended/Monokai\ Extended.tmTheme index 9c2aa3e..180cbbf 100644 --- themes/sublime-monokai-extended/Monokai Extended.tmTheme +++ themes/sublime-monokai-extended/Monokai Extended.tmTheme @@ -810,11 +810,11 @@ name JSON String scope - meta.structure.dictionary.json string.quoted.double.json + meta.mapping.key.json string.quoted.double.json, punctuation.separator.sequence.csv settings foreground - #cfcfc2 + #fd971f @@ -1027,7 +1027,7 @@ name Invalid scope - invalid + invalid, markup.error settings background @@ -1042,7 +1042,7 @@ name Invalid deprecated scope - invalid.deprecated + invalid.deprecated, markup.warning settings background bat-0.19.0/assets/patches/Python.sublime-syntax.patch000064400000000000000000000012340072674642500207270ustar 00000000000000diff --git syntaxes/01_Packages/Python/Python.sublime-syntax syntaxes/01_Packages/Python/Python.sublime-syntax index 2acd86d8..86257f7b 100644 --- syntaxes/01_Packages/Python/Python.sublime-syntax +++ syntaxes/01_Packages/Python/Python.sublime-syntax @@ -988,10 +988,6 @@ contexts: - match: \} scope: punctuation.section.mapping-or-set.end.python set: after-expression - - match: (?={{simple_expression}}:|\s*\*\*) - set: inside-dictionary - - match: (?={{simple_expression}}[,}]|\s*\*) - set: inside-set - match: ',' scope: punctuation.separator.set.python set: inside-set bat-0.19.0/assets/patches/Rust.sublime-syntax.patch000064400000000000000000000007010072674642500204010ustar 00000000000000diff --git syntaxes/01_Packages/Rust/Rust.sublime-syntax syntaxes/01_Packages/Rust/Rust.sublime-syntax index 3c354486..24727a4e 100644 --- syntaxes/01_Packages/Rust/Rust.sublime-syntax +++ syntaxes/01_Packages/Rust/Rust.sublime-syntax @@ -907,6 +907,8 @@ contexts: - include: type-any-identifier - match: ':' scope: punctuation.separator.rust + - match: (?=;) + pop: true fn-body: - meta_scope: meta.function.rust bat-0.19.0/assets/patches/ShellScript.sublime-syntax.patch000064400000000000000000000013000072674642500216740ustar 00000000000000diff --git syntaxes/01_Packages/ShellScript/Bash.sublime-syntax syntaxes/01_Packages/ShellScript/Bash.sublime-syntax index e973e319..07c170a7 100644 --- syntaxes/01_Packages/ShellScript/Bash.sublime-syntax +++ syntaxes/01_Packages/ShellScript/Bash.sublime-syntax @@ -30,12 +30,12 @@ file_extensions: - .zshenv - .zshrc - PKGBUILD # https://jlk.fjfi.cvut.cz/arch/manpages/man/PKGBUILD.5 - - .ebuild - - .eclass + - ebuild + - eclass first_line_match: | (?x) - ^\#! .* \b(bash|zsh|sh|tcsh|ash)\b + ^\#! .* \b(bash|zsh|sh|tcsh|ash|dash)\b | ^\# \s* -\*- [^*]* mode: \s* shell-script [^*]* -\*- #------------------------------------------------------------------------------- bat-0.19.0/assets/patches/XML.sublime-syntax.patch000064400000000000000000000005300072674642500201040ustar 00000000000000diff --git syntaxes/01_Packages/XML/XML.sublime-syntax syntaxes/01_Packages/XML/XML.sublime-syntax index ad7d9c87..af4a00f0 100644 --- syntaxes/01_Packages/XML/XML.sublime-syntax +++ syntaxes/01_Packages/XML/XML.sublime-syntax @@ -12,6 +12,7 @@ file_extensions: - rss - opml - svg + - xaml first_line_match: |- (?x: ^(?: bat-0.19.0/assets/syntaxes.bin000064400000000000000000026065020072674642500143760ustar 00000000000000x?ic{mOgJøBNeO;-B+w 齓;IH$$!BzOH)VE${h,ϒENl/QG&+aMkf6nn7=4dvP5юSk; \<hߠvcYsVqr{:l:h:[=] zҨ'{aޖ2>8GN[^db@$XmƝ9ilLy[i;V͹v4 9)srMxi֍ h{G_uptocGZ5njcmշv;C۝vvjMU%i8kv _WB[XA1-JwkOQ&W| -˿]gWj%nm9i<{Ϥ׶뛭]c:-}0 o(^e7}^_TC:uX|粹r![` ;nDjL ang}iFɗJ1W[r'p]vIVhׁMVl]>v"3m[.k&Kt% i$L& X :ș10ءթnc(G@ cAH?|^Ӎ^n]l71o< OZߴX W- g߂7;cc -zU | BOal5mAmpVR ([SL6sg>C6bUv{ (9|mW FӾҝ/X>#:L汚n4o4:Ԥ Ac4Gн_Bo@lVe)C}o˩'@x4:z .ӂƱ;C2j{6Bv0,UW*@Ya[N1,J*vX7--i6VT{!pbOnB狾^ϬqC~wi\Ǹ4#"PQ.Ym]GNsr9DX7=R: οl_.҈Wj}/ېfOؓV[dۮb-8[!jb TYRZV@ ,o/ɍ_{ԡ*!Meڍ鎡Ԡf͑RT퉫e  WS]ҷ(;xo}G G-hS`? T6Xu _Tʍ<neTi6SS:S<Ӳ6-Fj{ˎP[Ydn+ JͨlNFhT ,՘jΰm߂R}o FU;`rХB2Kg]MP4{]ЃuU t*  8A>c7؅*_,*/*W&\_K^3k.vS;E>牿 52mvխ f@ؔ4/OE=3|<ݐۧ[4RӜIA9Vs/8uǜxqx~znO4[pՖixIњ[>`%c1S1S1a#z2ƐpCT\3/s4IIXc}$g3V^u\mEk0γ,s2wy3AR_A7vb0hQd.DSi/Y"{b{SJR?G1ƪ3| atjQ<0Ƴ1KrqAcΔA\J)EL<9!63Jf%3 4" q-79PDE6\ Kݥ"Y9Ri>0jBdrg9阠#53Z;/LҞj.'(f쮬H[vW!pj5{-Co%IV4&vų -81Сkӫ EXnci.Y/ǤzZ5֠}~mߨ/PJu>G5MzlIA {W~,W~RWpŶQ]ץy#hI ƣDvǡ 4xA=`7v D|"z>VgMيc^mkc}iyӂr?ihxfD#p0M3j}ZRH#uQDyQW*zRnDP~4jgGäO`K~2Bx EѪfr5xY!hZ4M+ЛV9o̲  pEL8,$*Kq2vŁ~}:aQ%{şg6: ;0xd1fQL~<Ȩ&$c7&c$cVԒ1+ɘUdj7Ė)hb;hC(4G:gJ+L'nN[1%gpmÅ1![!$BYD'BV=AN@Ɠ⨅'QOOωP,qHJ z6 ,찥=-xz*X`gjGgGg`%oq$F{8Z|yɛd &OL GҌeK9"4|SZKUq^yxf&/#r\mL`*Cm ZcdRjUr^ۯ%TRfHzlq>#0^O9,Bom.W3,jQ-SFNF1eP3ckA. k*~k3#3B 3"I(Kaelxa]v$+;gì 0!sySDž<-x[׭7lI; 9//̿%+=}] NӴj]7̿Q%k؇jA7T tܛT[[酷Gu>HiwEߕ9p{ZwE|OZjG1wI0V)#J:qޯmY5 n|0^PcPY@jRGQa;p!-sʍmm23|? XAs&$ǶV6wH}xA=@ k8ArS [?5} Axrһ,HW.sm JF jyP'R҉?AW؊Mc6kBYr15:`Q9KRH#+0)P2'/jaZpzDdmT: 5m}W(2~- : =T޾XkCaK+ؾ Ýf>q);bV-bwۮN]pFpow< >}0h:ʁ·%9=hZ0,""ق &oCxlX#7|϶jU QƯ0IĽˀPvخC>^AbOVv5fzciۢz9Vdk:b[[4f|E熔ǂI _MCI[` UӃ"R6;(Ŭ @'ɨsoW$\SN19NiOʕmc\+uܨG%o|#4NVk#?M?#ƨ#cuX?0$@S_~X%<O7/ >`}c- gGqc\DFa1{S`6[b ["Hw)@ A QF1 a) Q̏"PUxXw <a]H -/a ¿÷VTӍgR:nBp8CYtxzxzxqWΞSL>Zz'ĒcɅ9t f>.rFIcn20/Su٬3T\;M\KZT6\1iU(tתD n 3afxcpfCnظR3@lݔ16k!!i"`QV""6_-ҏ(AƼ\CA #qqM"CDH8{٩}NJ!ҫfҏ$/nA6è]eNc evr4 YL%B9uD<{GM2쇉TKD*nTF#^i7ЗAgh°`V0/&\2dBGcXSˉ[wtu$2Fj9df" jH:iDAqHb]Ȏp$")HM崼MdDL;A"duH/ԓ# R*ߛ$2=/|lp#^*wf?$ w ٴddi6ULY}k*ĄD:Y2E*aզJ\ W,9FY5$GKder\ffQr£V O ѥٞ\R8N=0:F5WEm2p= 2)}P!<4x!w`CX#>Q'ni#2 rd?Z6-[PyPo:2{E bq a+0+qjP1[~rsgwGW tad(b`=CD,2:dMtU |-7ttcXR$eg+fݭDx,R_CKwVI g'X,j/QP*~~92<֪1Gš1״D ӔOJ}th oxvdI)˂J,9| mI)xT~4P 5G!y fz1X]jfzz\R5`at$U{Bt͡tM7TM}|FYfđ3m6e,-L6_Mѩj9k;ͦ߇ײé,e9"XyѶ z5 x2GxzͰcd(щ!֯[[kck0WMUjK'0EqZAg±FMT|(xpI-jOS--K )c}?+Ešى7/mmDnϤo ͹}%np/l"mzݺ ]K/㮖 AtK/ F Xgc)C`bYcRr  QFf"].6]|3g8EձVD>gS$+&sҨߥ wY0/^NDT"]D,+3>63|6Ͽ7'DNٙdI-y'SuK6ы/RuK4q=8C)la" )@iSBUj /tX&+xnkFKLSif>l+83 ֆԩiM+-wm^ܙGg/`-|[/Ēƒ r\K8h” wRC(9æ󧱙#3s螇ysqA9n ER%o 'Es" 'EEBodC]з v`r9N=Z7A*fBLX8C$̥M>G#Hlu gFBbp|#83(wn;)#^:KWh݌w\ti?mvQBZug3"UTz).M6 xzR)fuKl Eu܂W䦎SgJ->Z7q`\Xh(yV<%d\NV:픥:}Ps⹺ ^FyEyTC TsptJMҘz&^ȂTGG UOj~a7dI$ҳV$GҰG6~/zb%W7dFqELSGN^I8d(7V6 $Y./ ڶНGEm4]EZ>S&!QDg~qOx@V䇉 rNzvS/y':$q'IΠI0RO" yID'{7¼CEnX%,Kr' ɯ)Ί#>uȷz =aE磉*".rw0Dm!9pv'NNbY=7M@RD:%7i,ୖ{B%X'}Qnh1Ljɧb}琁G׍DS_F*N5*"8^b|t[ĦGډza"X2ȄqDm}Hp.AbP?sjIdpg>Das0^Zx'8%u5{:Sȗ4gLzz'=>$fuYq1:4$7Qz0Oҋv/­\-/%ti0V-r[QpHF[ TVWsV^E 2c;_M* Q$7eH6!4Kt\_f[f32G\sAvﭑۈ"؈7w>z?$"\2"\`s*vgwwQdcm'.Vc%[,+w6V-!dDkU`%Mvj-ߕ&?{Hnfٖ'?dn̓R9:фhN4) p,"o l,ȫBoj[1_DK[9GnDVrZ{iTCpqhۖ{w_oܻk]ǖ;+߻ߴq+7nziwc]wo _vonsWo w倿u{7nڴe;پ޸s-Wnۻcݽo-{6nڂw^?o7^i= M-7_y|yl>zǖn箝v]y ݾʍPw킔 *m܉/}ĖwmBԎ-;wڼݹm/fh-{gWmvoٳo;lUcn(GW_^wnAa??@'0 >e7jf&-v/5~/,&ڸ{Z`nR-_`M{kwaCyn}˼}scDRR$뇤db 1ao dj(!)UCR\ )bmȊ<$<=9=Y=y=ĸ68;X;$x;$; mm#5t϶vn٬~)zn(Оmb__f/ g>c_P}JTJ'OkȾNJ퓵'O5uEX<}߳loEٲm {QT,&%^P;V9U7^5Q3Q1Q/^VAddνK{y:*Bm]ZN3ue uΤ7h~cӠO4LN=q|8 ÍoƷ~H[r$I|}G#oڑƷ~0[qBc ;`hz^$p!n*GCs[3.~H$N):Ƶn;&j|/fh5qhDxx$;X}I',]u&T A܋m5΋?޹2ξUZG[!/9-j<XUطu |_P> V*AdmT0cy &B3W$Br&؅Y+4+^)B9clI&cW_O7 *C耎GG4Q|J`$;z5DcHH:r(xd Pa7ߊ8Sa]{RZi}iƵi"J>-rţ"WE*EI\?ec̔Y7EVZda4-XNE"WEO\]M\l),EB=-Hp"W4"WޔK\N٘YE" iɴȁ"WLd ?%ptJ[RW?&%pc4xˡqa*Ckk*7vpLx~f/ԬH3 VxV*X٩`I[TK[T/H[B}W2EtAr=X=*_jD[Š!_ fL;U/O3nK+"tWíxu:פízv(%!ץEO,!-FT a1|Sf[9 'ޒiUۡ"wI][q8̿# xV $){*yv™۵Q ݩ`{%Eeޫcӳ;7'6Қ;ҠAޟU@ӠV|( jiP؉f> f|DN:#6T}4 ʸ; 4ǵ~?2Q>wFܚG[Gn)u< C4-2+_1qaW痱]Hrj11MN.W3 cMtA?. Ee=*em\ ~,TϰR13"poبTc1( \|m3bW.i=RJK4@N|?KWt0 | iasDth1,&bX!]á,W8{ '#9bj[%r "v4G/Ӑi备226i5hS Py fz><&u,Y //V2_?x5zYۓ7/g߳lߛĐy4Ko%-#k{f\_}gzZCxï`q: ƗTEBg/D7~0kȖFshG)syhBY?pwڭL*r6!{ Ms] a6 C:&_ţjթT'xz$,N_gײcm- Qa#':#~B:a?^a9~!:X\f{Uw` 'NYjyc3aϩ5U-~AjE>ML|-~i_~dZvink>r$Zw&?b9R>g̀ >Oe?XXQT 7cHxEhrKTY<kdFjoxR)o5Z#D:U:d`VOJ\5191latD , ᱭ#Uej݀5DyabnٮaPTKLW +/crbi/) e~9;mc :P0 CO#@UA.*Y12v<μȌL^Hˎƣ7!=b*x"ye >d.o5аc؆眣k 9Mhr `Czf3ĸui6Xp; N׬'}g}ݯ!5ar5$a5q"=)]qº87:2;|^vkqısp+ۼq/Gnٵݻmeލ;دkܼk{L^n]ՐS)}Xd[RsaGVSw>pZr%) yqù\K1Q@ATϒ67urFY|lMJ>tFق;:`57;'V'vGZ&%>ٯ}>{T^˦zS E+U}P B߃?6Nȿ!D-*"WDYr2[1\ai@04`n6( J]٪Fb1$7Oyk S\"j pk⦑MS٨+*^F/C. Y0lu=\ٝMB4iy,{5 L|Q( 5t8IMtqcZ̯h8~Lݎ8w$YVQr(ʯIkudBD&1nDA f~PS`YZ mF@ւf~c¸R ."tg6c zXV" Bq}^VDl2yi8< *LWl=3LP-Ei"$hʼnf)'[ke۵yf~>{( )ƮPJ` )VM &rN mG_` s7{pu,]HiC%?0 0l\'`?T*"">fzmO &TP\ޣOAdlwx;) ru2>aq: /3o T`S#MjG73~Y& 2 *ږg ƘVOL $DIB ܘXq XUOBn$!ָXGbrYojeOoޔ0Z|mX!ip 0: AmIVw H 5&SC 7 Aq/h!1N!a>,apfq1DZ3XOIZxb c+C\yk qScC\t('mSWa3 e JddY5gğCR$JMGIݜd6a \ڄ6⹿Xe{Lb4)KۙG40^FgJ9V;(mDJNC"w}X\_" 2QRƐs^R.}D>8(a ?wQ_#9 n_'Vpqbta ¸('OߤoAxzMS |LU% qƹO܅Z|l!1Uԕ# 6 1.U ~B7{;:R?IrIF"qLbq=)都XEg?'џ뮥f/zq6%jA<_ўv=DlqSֺ-PbQT~ӫTd ¿#'ZI yCnaR+l|5;"Qނh+K. M7+ N?2xfՕq71E+[21O?ŝVd.lY:w[e` T*lP\Qףbzmxhl[qo͚ĿV&^)rz pl*!i3V:dn[-(4ܖc8xk=D@ߒt0le_$U~?nFyw O=:v8=Ǡ;gl6N(Wժjů:X6fD!ye)(z +p=VY=c˾a4A}AɆ2k&Dp](j}f =Pe'`Ҧ|ߚNE7yJU`mU1[G)G9J*.?ehek8'&cw,BVEጱ/ J0})ʒz,˝}"[Q/k~ȂT`,dք_LO þtú |E5E e_yG0n,T=QÃC\ƙԬZ^|`av Z&f &(76mW$bݖ} *kJYϊz4;q@-a^jF$[k)>5|_x8^ZTt?M/lx[  %" ݠ۽+U91;=sH|g {OH)%ǿPPzo:T2>b^+ v*ۈ Fg}U6 t:ːSE~TovjCU(]Jm휞5k~Iƨj[΍;B6޶z_ ܳwWaq7]w2woپe-]Ř-CGGJ0#4{ vvrt_^q˕:5:Vm9KfY]-lWR)'4`67ƄiXBkQxր;`*j>e6*F * .1KX; kf;Nja+Q oHz=@nE>NL0 |Q)V1N2{1ck\F0L5k`v;fq# .eE03z6t9tppíJQUq] i]M.ٵx,!l?$BٞĔEmW$3s%{(O*UAub<Ѫ޿x|_YT5=Og]j/H]򗼥k]/;5w]_>Dw:+{EAZ҈A't̿) xsT-Z]vsڽ56[zbߖe= 4;cQwAAޝU| FցE{S;R K+?lAJ*ܙU+%gAN2>UhTn8'QH́ôUPZ$ kO$]fO*be>}:|~dY&1K7ϥO*|!E&1C)R"r"DH^F@p}Scj_O*|#oiurl; v瀈awB,<Ox |_;TXڹJ9Uw<~,36eg^`g/dFOgZ OZBGڦW@1]3sߔ` c~}V*2]9t]9D,ѿ%݉=T;OPEOzDDkV;5p A%m##5;tY+$-}Ism8ܻ\!Mo KƬ㣜]㣜c'Rc^F}@ ʷ|7!g@( G1e{t%Ow]^t);W: p NܜhZꙤmի-^+qQ5ԍ\<" )NY'sa_@1u}Klr/&]#%o0=GrvH"8w!-_qضkIlK.#ElvXDQ^, HG>D(#+^r|tDf><)6Ҕ5H @x2"i{HvնVT`*"j2j5D#ג *rRbEh@|Dc' fAƒdD^HܳI_ &(v3abԅEP/RC0 p*Q,d@֣"܅zM*wd>G'[y;B;v~ A~H2{v僆p_džGQ^ۣ(v]u&DgEX&V&7c !yMtAI7RJ%X%21rW%^p_P9>lb#;IB/_ԍD>iyi_@ǦUW‚Y.U9$ H=_ L·7w&o/Y4YWvȪr"ݵj`(d閺g6榈臨n'D)[toUvcD {. 鲠Ǔ=šyQMrDbvu#0' &L:D/)QޭDu§@FX>W6 ̼z>96+4yäuSaOYM&U!*.5Jc6DΡƛHgMt#>L'YJ|*)_@>) \3Ucle;dYʲt'mK=9 m"-W_Kޏ{o=ޏ̽߳{oِ} yAT͝q{}FӾ-b3_x˚.i㟇_o/~O-_[[Cq;.]0{?|6xv:|oו9xϫwT_?pO{I#=.̈ a4޼h@;Ѹzf|~vÎr;㙶Q\4S4nzpd:S._B(Ak%F ~l= >C7$᫮^xH^{'nB}ǧV?V-}?~o|>,Gm"*#yj4_ u8-oƃ}o.3nNgA$9~ϫq5q^%xёW" !X{Bu?,) z )rA0Jhw2:|QT @#Рv:ޯb{ŅS6|R6ȡ3<]9!{!h:jtiTYBJ~wi@LVZaLi0zˏ)gDfzHa2Wq_>&|Q.iO cg;>܏ xWc#vۭLXv^*<[w !U`7qtg_ߣub7npEzu>]Zo~B"\D q}8rd5?DIdwS{aAS#BQ&wkZJqsq6?>!yt$uv{[muׯ,3ccv|X[֡KCcv`O[L*sU\|Ws% 8OKA Pگ5sl4&Sа/ I;ĝ2~FF \c 4HS@X#EKԾ^G}~Qa? GdmHA90U?>G "@=Hx.]/"A,Ӄu<<]n\[ew.''&O3" rmiLQ`/\Νvq`⡞NVj뇇`(sɳ) N2;USgGËr#g$w|y$mg͎vUIgYGub- ea_[}Ѣ*Yy3> 4ٺ;_p^)ÅFhv=s1d0pVhReu|v/8 Tlsi8o,&ϪQ<!XK_(/)&@h ~ԁ/e|Y_~^52Uį:# xvDbxwZ@;loGTU'9UTEf˸ aui 9w}8@ jͪva:~zl۲P#0gm9gЫײQ/udzӋ{}ao cV7]ɰ5YKc*??|KpV,;b/O(xp)@#R~/Jc+>`9F2:}~H4<<8`\lCgQIߠ%%c(\t.ZrҋS "|6 B'3z~ qY͞hIqpuh#tG>=x.?DwfV{B -Wㇱ?@% uvqpdC;m,cEwA׎@怍 FBQ]. ^Yf~EjR@Ϗ2ʯJ4VE֤@#W֦EE֥E y1H'f~CJ18Ld.R1 ER:kB7 D‹4 KDY6 p_ hԚ]w% jL|IŊ\n毚4b1WR s10GĒŽXrq'qd>]Ic( Qx _nXe~ݳuD=ZMthZ[:2Kl5&E4qdr=M1L) VK,]"9RH4=Gm=fh -Lct/$< ,M^`݄]$;6wEZŚ r7r^" Cxbb5뽔hVˈW0oIV@D}b9"$T_E@1;jBc _y,ZG=8u@@@sm'&i04 X7j*4҉)ެi=.A5rd ߢyy1D`rV|hl,N]Neޡy51) U-Y=ܜۼkoV.ȿWzTmW H8nfл1xxz nF}3 )@ Qj'eO$`ֻHp5u)G|eaL ?FJtUuNeq%@ᅱnpn W -Yqk04|xN=7 4EYE9sk/: {4nme׿]  zGN8]1.,䗤 FBu7e2۹'^#maB|:\7s#K֊1FWmm'fxR\Y/n^-n$:,h2F|kIoO" kے`{\e=d'BYI>BsHk4Ə{g^jl32! 9"auI :$Iv91ͨrETJX"Ex 08kRU~CKr5;tAbS'306Ԯ?t`?J#Df&&P>"j/^ٿ.O- w 2U ?)_տ82_-r|7igtF6KUxߥ61?"jXQsʳQ]7M{RR:+;uĢ="qH9CoVc/ފQk;=9H3F7 ٪Tp6[MrgIe{_/]>Wj~9 v R叹."]?=ȸjՂ_-¯yp ߰ 5Ì1~],#CVW.t<*jy 5v>'uXp=r"+;@\n=fLy,+WMݎ6xiٜԏ8NpjWY:S[xh$EzhuNqQ+,θ)pT7vrj_kq߮,^>N}X`Y[j=? udq3#䷚~ /褏s?*«(+1&AxQ[xGHmt: "?41_- Tg~"AGpƺ  iy[ Of@y.,a*.׭,O$A˃2+DsϲjS3k{¦ "7p"rn9OUgR 7E'FhDuA]Hnxʠ;1IlLl$EF7xQqyi=0~ QHlC~" IOx_1iƱizӊ M[qBo{VM[}E*[1IΡN"8>Y@AB!JJqjJ`&"/Mw1q 1^>PϊÊĞ}Btv xҶ~sƹ yfe{!m e,KgUE"DܣAgd /*&00Aa / v%n9Z\6$Ƣ'),I.JT7 ߓ\ d 3LP0Aq Q7#.?!~ļx,'lh6V X E2zhmBfc$]Ӄ*A6V;֐WO֞ .N#vޏH(n;<]!hgEiQ廑h0I+p%ihIb _#yV ډQ]Ey WWw{&0wcD!>YVkr~oHƛX!c"vSkr dcIgLGSta^?d/i- ciHFku/$guR$2QjIwf&V~%ԥe,Bb;HVD$3ђ ["0%@gj?%ܓ¸Ccgl34*F([vvHص[UE*E|;ZMoRDRWe 6:g !Ԗ ֯$eحv+3k ekFJb 0GQ_3:fD}M̈ژu1#cF7ČoQߤ7e- y+U(GSdszUtu ۧbLMCv 7NezրJ˲H+A -5w4|6/ Ε矜~X{jiI>T *H PFB9'SSQ>zI==MF9+ZRuTJ;A'PaZ}'bKmgJ}KY<<V6HN[a~m5] ^XUj8rH`%Jšd X l_õWAɒH8; 8.v׉:xSê`EAI|oQs3ܮ=Q[U: 킢HuX qDn.XcMk`)mBG!nlȱks[};u%1.لEf3YC`;Rǣ۵*AU1Kvj8_pL3~m-<%qd|H+ ,K^mԮEHT0Gg})ѲLGKsϼ;`|,P,,7aM(lPz30݄xj?o|v}柚V)F )pW6{Y^Uo?g|>t 3_n*em!h{UvݲTmjR_*a5mPoފ77kBFPrm)M|8X#h6_{j|'5]m!2Pe2O 4~X &%bwc}trQ8`0~h5PV?yg&-n%jBQ!?8vK4Wqzt N&K0k1:I + ߒ UߑfNJ{ X@oXf*Z&. ڈ 73ܿ^ӳJ!#o]y0^NjLCA3En&'/2XoڊX[/.yRxk\GȻ T ǜ-LpDZ2/BVqd:uNZ "]*KOh_&t[' =1>Ĩi61bhK<;Ĩʈ3O91jU\u8 SI#^槓681j^KdPX I$ "Y̹#}bToHE#'i.5"Qu.aZy'FGNjoɼ' , NjL) 2 NĨ6HbYIfBp ikBz91E$R2lr UDfκ~r,7]Fy@EDvFb;PjUN Ct-J#Z?_x8_Btlᥤt #|OFTOyNE81jN[ =+t, JhvIF$R5ZEzV'F^ &kH֛xkXIE5uDbÒ9䌆, huOq|H_Ux \IP6m&^`Xn!uVH=ejj2 6"p=&3rV=/a0ND@|ؖ}Sik0k6Kl!"Bq3GveFu&2 "aƛ|/-1w'},kIh#g"Ү2'^/@r2%d V rb-_}\%׿f&1"3@H)*xN>vԃ)7jլF\"L=x FxzoX?r``ݠdP7`gP|nxeқfF'H4f~t.7 Jg"?sc$WeqVר+\X'mp]Du<(d5ɀ&<4"'*jLHǒ1k:H] 2jz6hIBfa'C-<3x`ZR0Dr'ޗ)m(3ӍiߢNCEi|<h@Li*Ќ2FodA]/_K} K~-*oic 4Z -Րl1͎B8 9NOJ}gJL?U0GHj8o#TI?8EG cQ {e$ =j4 /+ FmFnV B/)-1Lf/Yҿ /C|鲵#s>mw,>jX+FX $'$IcBvR|Xj{CWm!̸$֣2ڢrrt :QJRIa+^ 6bN@g6=q 3XF^`d#xj3&QZO\SF\QiK.=T.]+]x<̿c`ZL3A=t=3Aw&w}3AzLЫ?0Π Aօ3Aw]Lŏ=љW=ʏ3ALkA?9f^W~fUxf^tۗ/\ / XbӲ˙. djK֕ p.J"xb6 _ӮV|]Z 2LI0EM (NžC=2ֿK! ۦߣa` E''9Y-? al*CW1G$S `p(H&OTqbI,SR/(:i1:T&>_ %1*.!ml2>L+r _ BM jB w="s,"x}Ю?Ό?YUm@bu3mJ_h"\^џ"-ۊg`A)Q]-hҜÃ2(pAmD'ۍ^rR7ÖpWT1:@܈̀+">̏PW 2 N_ՋAݩQNڬ4qɖN"eC\KLw tLA2R fW\A.6h]˕D梐[$gu!B#f26/[$zJUd, BZ+,)6bV{t_?lFqN+h$g0I5.ҸB6DG.H2J?#nw*2XK,I ^}D(7_+@v]"M)Pm-{̙4Phb`ÄIBgjTeisd}Ii D1`[>. kT!VbemH8UyU;:$7TiHX<,{<*|J5eQNFt! bHv gYrI Kg~5--2@GG, .̕_ u@;{~,= Jq"UIΜLT_udzRS NU`.NGcccV=6)ml{\R~BxEnEp6dyZ֬ZkGFC]#HV-< f&g¥1h6k"fX}5[rmq_]@*:2IFo -NF&;y3:h˷_EuFORk ~ߣ?izvuNO޴{ӊMxgoڊw7mջ擁{ޓ'5M3եM2Њ~XF@>H*|HkBBITv %BprXBj8aT{5+c>gg!K3ׂ Qt\8#Nr#z}TÞ׀hR.D.k(]{(3~lN 4'ҠA |2 jŧҠV~: jgҠV؅d &os0'.n6Q1_HB_LBDz@6C4C,C,G.S5n|mnk#x0]$m'оve505lx)qI:۶[ۉ;wESJb1(u[*H+ QW]?M3~! ?!Ce qůb+!z815ͽo{',C4~C,!Xc qO1!K q_cC\+wb1D_1¿cC\! :Y1UGWC\sI=7p\cbb⊓b+yi+OM[uJoS{֜v*@:I㌓:ȟ1JNI Yq^"dU$BV_YsQ 'eR_12DHqA"d`a"dť%BV-J^Yӗb6)b?b,I&BDDȊ剐D*#YSL@R&ce"*R\XY6DȪuI[> rCb`bI5tu`\!xe<O/lhKtu$qA&~cՉc&c<"S؞)H LƬؕY9Ydɘ5{71B~_2Ƹ6S.S|T2fd̊G'cV'cV1G1k'6EL̦!cXɘh2XN T1+dʱd̪dj"DȊ!+$BV!뉐5 VWj7n4酛ŖvLPUF; Q$!5첸jBУVS6 fܜ VJ+`ө`+nI[52ij^7SX.JGs}R5dR"% 0 ~ק _MO'ϥA¡vIX*dӺb|^xD%E|RkewB"VaHqo!K^$22//eFmDSDJ*q.*\߯& Lאjtk3YEt28 |#Jj7dȏfAPWQ4sSαuط \jo#HR缃$׬{I\NqYdXF^i|ֵ)V E U۵czdUZK&K{Z >~OV U>Xh{zkOqR$SKqu&COJ^|&F~V sDQE&vǓqѪGcTݴީHz|#k^S`jv;1N]Nm vn )j̊mUOi~LJqlJ`ḔsusF/rl:!oLtFg]gӣS#l<7:SF]zxijx(Rr|9IΚՃQlRtq."H-0.?7s]1 6腽%wҋs4.!D#ɐvM5?&H*oDY'aZhi|v(BJ? q]+2x[Ff/~2 tLh1g|NVzt۔`hzfw@JsL-|6&*ݨeLySS j<{`pr1'O=`]PRJ.,ꛜ{AL|)5ˡXn4m{Re"dcV`zz:L(v(j6e4Ei) i.̔9y8i4aѡ5zװ,[,7:֪\m94A^ќ%f7ELM1Y"g\J0)=垉(b tov9r@ᷛS}*g8s8V' WN7Dd _V9>_Xиՠ5*6'oR~Ŷ(<1جu1*M"'R4(K_KKkwk͊sc@d*SX)I %ufY'BuDHqC"d`0Dʍdu9Aп+cM鱅-[cW\j%5I;6NǪrV nLڝ"Ңѡ>iQ~&ͷ?^<˽:Pq5$(a8 ȁ[Ïnײj^[&q"{d\fR4Q+)pdXr|l<>xc%:050 ^%,%0e!cFa ~f( YdTK3cn 5Y%^+ 'ޖθ ; ;[~t͠VJ30 .sjk2L7_tT5:?HB(GҰ{.328.5{9;\Mީ~v, `pGp)t%=`y=xs1NyC(reXdspmW2rqƪțcU(E04u`-6d>'{|W&}[p~seSӨIJ -#*xfۂiQqfenN5 ̬@1%6pF~( ᶣW4U1ԷUW GmoQl-+[FoIx=O{hHc`O++Q@Н`s3/6'vrj܀xy.7̅6( JlO@YK L=QK3eΩPM ]v/5]W*~nCx~űj8iR+m݉e\_;-bv (u?\5j_]WWb OUqŔ7OaxIQ~:7\  WkZ_?57_mƐvocv3AA~;,QJ|pCvNؖca8 Wg͖-Q;2Uf<=k+$u{R5BFH 9*ܸgӶm087̷)FB=*,n[18N{hMXĀ.>7ɞK+G>gKdu\(QxPVvLaUdAXL1`\Tt1f#4fU$,͘jkUf;uZΪs r[4噓4W$F,%o;E뉴 #s6܃+;]57 ۓb|qyp+K3f/ͬ[vxY<Hb%h E"YFg1 Neصՙ /_]q;޽ D߽@N,b~7ب!0q72e2EmiV!l/,k^YRZ/ɍdK> zjwiRc0u7,ِ InΚE_0N3E hς[]?e(tA[1VjFҿsw(x.g =dDLQqR&XFf ;H)|bᩩG2`& ks0ݡX1]6'䒲,j]UXoD4 ϴ]peǚřh2Zy0~87"Ra~˙HDե9e CN^@ATH#f?.J?- RQ0hQpQLRHʠ%@9iD|wk}kCu.,Z~ bG{"'c&A%B Ym某dC)L \}WJk#֝:1< ȌGg/ܭ-u31Y1m`DոG.l.|r&hS3A>M5hVh-N XYL@"[?5vW$7 @Bb%F-v:W+Za̳ӚiP}iPA54ڮRoM+|7޴]bώuO+*CK|_1?!?!~C,88p 4(iPQUc3v3ʃ(?'a\ބ=x~I34')fUU{Qj2 qjGʿ&9C6N78W 1/!yqo^;a!޹_ޛ6p[oڊW|eoڪW~uoښhe0M +d v ;Ȏ`ץO+!F2ڑ9ߤ9n !&% oOߑxg`Ż+oOzw`{w0W#T'}8ΖlF(a C_ݝG:]DN ~aU#Q!w>HiyIfw zi*<+ d?Z6N[k91X57:GA&8H@!LS~f?N Vj5gimIuKޏr0)vvK/"* 2!C[,ׂKIn>T*\3pUaFRğ:Q=jR_>ҿ!$;x !TOJPҡ%Vّ%lv)NPeofO#UHGMMI$wD^4=ͮ'ςB]szZ^qT8FģnxFZfZ;b 4nhpb-X|^Cw2nk O!K +]C"'@8u?{Vp[3 rbuu볧V˒<c=Ft !|0,WJЍ̡SMA7ZTXV[@rI`Ԟ ~u&tg1O.vV!9|'׆ˏ:OHp+hTJ*Np/ O^2 #>~>\[~߰>-K?堻6}Y6,`BQzf1 uTFVk[uCM:ӫl߇efjCQk̉ tJ>@֢f<$, h`7[YaK ]޿2h܈N^&ўvzlS lX!,a9m_.2~^MUvr%n >QzGshl ՁQWu< ^`ͧ7p=J7dJ!Ak$k@8,6)%sJ`/ 1x, ȉa,i `0bf&$t߁ ЦSŦ ҅W^Ab"h"?$L!U>f"Y16YpczcNy錸46 ~Y')m9"Y&U23Ʊ3x=[䔝YNftK9'[M|i眜[ҌI"]WM2N6) ώYyLS4Etb>l/9S|:.31Yɘɘ9ɘs1+KƬG VT0TB䨓&=?b,H 4j\G-,Q+4!zP--?#DB .;R@)œynK݇esXvX +Y1X b -n]n[LS3MQX1ŕ3M1J;uc53j{/⨅q8xy#^glL+\W$pѕyH0Ɩ@a6jxҷ<*BoȄ3W۴m"y}x+}GqP.9HQи0=v#(iC.mKE`#HlGpHl$$^ح#= e wR+ΰ/]al#aG;AXo<ƁO[.E i%.RJgC$qb!̻tO/$X02d[ZW=PP.d,OIAb6E'cD, buy'nYUĴLד!Qzr@̀7G𛈽VJtAJ=0"oo%}/6#rpK+nH٢|'>PK<=;vۉ@t^~Gz{M\|w6h|?azSb9Mtx!"dbr')/Y1*f!sxg {M,S~T\6\nz|([MZȏc26IO~IFF{jb {vleX$4A>EzK4]w>M.EL\DTg㚼GI s"J-d E<]+KqŠ./'ʕWĎ{t-g^j.~-U:ӿdM &ߦ}+Nj|nsP=୽vkoe0`yX(rZY8ܷi/*w}(M0\>ԭNf]iW^>|Ncn٭m)h O }FTwHj\ٮ1肸U e6ީyە+X 7v19͠!#} 疌u2#ؒ񦣢6{$d\@㡔ZGxk;wӅ0soI606D&t"y>MDqq0gLx&-]c}x;6?)}2GI>N 9]o ?{-ms]ǦǝcdD@3L`6OcjfB$09fnZ1/-prZds4¹"Ê9A"a\xaE3KW?Êv#Xx.NLeXti EڙT3Ɋo;؎ZFNYf^n:T*R:zY:zE:MƇcƭդ:ziizHN~ =VkqM^h!2I!4q)$W JΕr/N^hӉwu0NaŽJ H*RIb&L|6gSqT3STk:;"Ҥ[G@_G, XGçdLЕ Faz"=xȐ+fO&T)dfscAldltiOn{GjliWЗJ}RƦ ogaƗے'lپe^=[v m޸wŸM[oܴ߸}ݰΣT[=|9$ &! KBxv/J+8 ̿T/#O~y<ݸ-^xE'e~WJ}׮U S]yw'֨m} oݷp)+ֶ ՊӂOxCrխ7>5-m)ҸriM« }eayLE\VꃾǻK0¯Yx~H|AV}Nm}mY&x3叕vsjvp. 6KyؗsatS ldH[㸬[6%fweY#ywl H ^KLzス2H><;{{ne k90f+ J| W4+3>Gx+fE*eF̣/WrJ:ߡ80'\/؋ByC2_*-bAq8x/A{P͡s, \ŞU;W@yo,A@1ޔ|*VƝaJBGح\,HVCP;]H&䷂5*-cOC6c7| Ta\\ٴo?ˆBt gkְt?P赂Waa⯸lb/, iJ pne#PJ,^Z~X1%{^Ms{0wh-VY\~ ufI<\<|d8Œlbyoy5m ɢ`y Pw4V͢ڶ&PSNc~0 E-X~Pf[ޫ{YfW_X~e+^(-Yz唺,5PkViZ@(k֮^ۋ]: ؗd;HyrƥPK._6{/]׳X 9EkW ZU\5pWF|+؊%R6sTW~t6n݃f_7؛Gm~sNe.'wO2IYx~̧,q_ʍB&!šY韝GO&>h0m2Ũm`/ C9ܨߎ ç<=&7+c ϖl fD7;?&eQ쾁*ΐaOxcP^ /za)]lO%vxQ\Uڱcz(x޵8?ڼڶnc7چ f+f0;G\6eZL6iej]aznZ;f3E*1qi7K &[Z}-擜oXTve@*e8q2aCY~z\8Ndok oW֐]˲C&RM"􆶳5~mkuדY<5WIUxJܤd2':77 oQs"n 7:fJ>$HΦ բf4Tw3ƖY~o3H7"F G:E{/Wv4A4_`h[]{8P"σ*[1@uSN8WO8>Dl10Y]EY 2 ~Ljݖ(e"̂~tdՐO~.)S$jip~zԹzT,((Fυ|.[$X[Ƌd˧^.~9?N'B R/|YITk[`C$~_^g> UJ1X$'H19BǰX>IJK?Ez ;G~!2>|YP=Q#G?P\@5 Q_!.-_% 351^Y~4n = )'@&EX~0mAwB쯺%k{bCd)PW?ɒWMbIq֍~Dj\J@82H;9]&Btue/IMHM*L1BM(\~KTߑuO=)FߨD جoK. vs#Q_ [ F=0G?%lX_ORޒ/F\@"\^_ҽ2I*"K,8c&89 &G%yH4 5ЇxCQ,# R΃,>2`zT4Ga!cNǪpNq#繡OY*0<hDZa#8=I'@k>ؠ6)${LQB}*IgҭL=68-b)ZH$.Xe~a!cp%mƱAf:\*ܥcr:у9K9*^%8C\ u\/&[dCc6xɾdUR:Cp /7rVH+ʆR֬sf8ef*;35'--L },ln(W]$ O~bb w\*Mp}fO_|v­[y18d g[,l;c Ŋi(|Pĵ͎/˰9-5}atm-[/Q536sJj/fۆt_Ԇ<: QVMl1mi\:|9m s*ɏ,3ΪO񜅊EP 0*f6DmBL ,L\6tAd^r& 5V6'B(7cǁ9 = 9U޺6n˗TVlߚ8gO E8=L6nTy{<6ÕVi [f*ƌmQ6łQ@~0WDK{*-7ع|0M[,cte냪1h$Wrf>{&3ڠ@}t&2!\R춐 *9g*@Jͱ6u6: S9uqA]U2{3׹s-n+U_dm݊e3>^bې016Ky^p]K A\˄ՙE#ف.pyyeoX[llv/[pލ'GV7x{ghgN?9\l%= =Qbfs8=.19\rvssuěu8z (d]$'Hr2InO rةw~vR5rjH%].Cʛ%jKɚ$PO7- 0}[xu:;t窃+eܛ$k4B$'DTBs7T{mx:&sD j6ڢV}[XBpy<6LGR+VӣvA@B jer&CjX82:>#hE=$CMAonmm\4}Bf.j/nH\BF6fh*FQ-]ISD$9!n(n&lh)[whw1CK7 0܂g,6zZm0CrL*"}!$SN7MMJ X|I^PUO, )sWKMfA mAc_m.Y-zЫĺ`h5 HC>7Cmً>ֲ-{InmKݲte/]ok˼Z+Z|G>٪+[yU>nǼkZ1RqV :so>cV}.W?J>F֫H;'r9uI;å|֬|zӂ= ϒGDH('0>O_ l"))tI8N9W8I ~,?@%ǣJxVE_T˔B3ICIy Rɕo@nh"\]ۤ]31q_G]Rɏ )>U}Ru? :"U6{tdKaɡ?!֕?%CgD~Fd1baI\)A—`/IqWc<֯ QCot-ˆ;"8AvH'e2>P֊" 8y V C8dRC'_;D7UAᓂr(Ծ~Ĥ #{ey$)IAAn;:24u,),ILl_>=Iڣu< uciRHBaU*sTiGM3P˧M4)(saNO %ӒbC0Ő4dIOW6Rkpq){ )=v*i䟡NtEf7YOkZeATJ\)CIʽtoκ˧ӕ>H:~[MχYe}.}Y Rtb]_lhgNR?C;+MǑ'cJl֤`Z$Ɲ\?gRP"paxv|R LGimHKwF@I44]IvW%"zR(ՍcRg%uwY]:Fݨy8dLFO”,M;=wRPhTy ngI겫[-$i{@"Y ,!u$b)6ɇѣ@^zmmڶ +2mRnU䚐 Us:spOJ)q |{{IZؚvЖ"P` 77s=Z`G_LϋR^J ׭\,-w{T+~H7٢y|AX y xp>/BEJ)_]uj798{czK턒erIF 3{tPGVV^n_"rVh@"GYA%].ZH0w D/3Gdƌ`D EhRKAVnT&uIDnAQEқhKB/ тa0!ko;e(_TA'577KT%ppp[u47n.WVJ~M}BfNe }z R2&*z("B]DPD:T!Tz/6I3 T q#[٥n蒵v_yM?[*tFԸ=sYv|^X݃B9Gen\;)~oa<`e _p=̒X)s٩+i2Ży{455U?k<éa;cZ:yr ŬK! 'if}?=TvVlaj\ ۖ l񕓢U&wtH'NxZE}\e mYuiVx4lZ;I85Rϗ0@2 2a$ Yo$Gq=D:ALOs%ھt+)CQh~SyI+bff9&Z EJj~ Cx5Nen"|$Q!ߏKJPT{"1H"kO- ."U0 i7}%' ]YeG$r-Ź{\Uu'ӪD0U_t&#2'EP=Q(jr_}!zX-!`L(qCt9deN>qc:LHZlV6Y~S9n OLdrdDd4BR3}NUoAOtYGYnM@[qv MH&}t眡 +sfh?Q4ej(!*'B&_b~\ѺCExz/ _ Ը&ClxP@zpd#?EL{2Ɨ_wiU(F@3r@Mi0BBp'1qX/Ҍ9QITI'PZtXX%N&89PP芙{݊ 4 ΃ W@:xX Î J:I?.2Hq_9Bx85ʃl)ZQQ;/"IO}>FPY;r!$3Tw\_#80w VGQDN)UvRHmTɤ>%_Q)!BO3M ):O"B.l )ݠd”ԏbzH2ӌ dDu @E~VHrtH:O"!l`q $ufˀsJo*cqҟ 5縠"=.qA-?t譓Nn$ l_/HVvズ %#חv_v fps/NgPfqAgԯrtx.)!yD'6.i`c뤀_ZH:% Zo e(R hVy-9.:Hr&I-#Ecv( P4a?o ((n%cAPReGjkTU%o V֒4c^ςqGsI#H)MO_B sx 4.%B=$>쓜)X$[ú !GK@/-YѶUWd9(ǸfphR0M֬j/nӪ/!c`j^%9ޚvŮښ}}JŨ'=]K:S}~/1gSYl9;yVUrѤtgN;LعvxOܴkPj@Rdp6+',50sI`" k$ddV>LڱO>[%zzǔYJ&?N4ii$ѻ8C}S P,{/3bTb*?#賤ɉS|>fH<0q߽_ ܍_$R%R^2PSJJң?W Cl(2;\v?Tt5H/ ݈N6 XNtP.{3jg8N͈y)Xcww1#w}K-n(O$`R}\Co6+G mV :H'{{+%{vvsC=y_+]@ j50qRp#SX,A8AEMcc .ޏe-r8Tx7uxa>Qx>φv! qȑc&ع*,XT14wi>UNXI1q1c'4ƴ11$e8R=,`u P@ C)M)r0S[S['NKO$mJvyb4mĢ.h Oofv6ah3ZgO>yIנZ g OzUxJR8!ײDV"\n[&'f{kw&.}z m^^-{ItڹJv'΋$ "ɉ#Ʌ7D;E;+;^T3}Rڀi3z~CQ~=(~A+ąJ*U,W* 0Ď{iI&G7Z)a'C[% A ՂNqrk(U{ww5>bM(tzkMz] < 9p ckܛ:){ H[`qWVQ Q$T>DS7}#D z?tQ2􍥽cD㤉2'H $E2?EFkHz?M 7~tr,I-[åZ>0E)SM1A<@0 xLKL+Ja߽ r)+JA7!aٴ 8z7xt^$wx9_NU ݝ_‹\&Ļ.gi8 ~P<疃}^ktW,ua_L'wsX GcY xw150V9"G C{I=Kltͳ)藕phx&!@2UL W pCa!k?\,!hhz;H<|,o V.P 5't҃KCfu!R\KoxK^@dKEQ#دѯ'&당)A@Aw>1qED؈q tIx0T8!O\:21:G@}3DP1%c 0EsRAɪ L); ZpĶ~S`@GER\1+?!:i n <Ab c_"O7H$ڀǣDBYҚHC3%>]^Cѕ& %^|1"6FWh3"+C" Å,fCRIXz$\8F䄭mʸAF͌2$Dk7p6(灷6 ,E6(%ۣ WD AnCf:}K!+3"vUt C*"::D.gڶњv{h Zh!h9.:Znq}!:ZhoqvShyD7G'Qb![E Gڭь]Hq鐈hv%$vGt0ZμBEi%33C%vdjF>O ѯ`ȹKtn2))m+\bj45|-lgzXf]7*!fX>[a;);[gnhܖBpVȞa̭&NX!L5? +dD#bS~fI/Ea10<,vnEX}_&BX~:4ܠP`mhҀ̤П¼ ȟÚ3%̷E56qg{Xu  K0p+4x0;4xiOhܐ߰ђ ;I*" Cםr~6j>#}Ca%g1V1Yug yŠKg+w}NXAu<4x ^ZXeѫVپ!s",P9V lV ȸ#䈸3,b,N1Єc9qgwxR81=/q a! ݿ , [$Ve,u+W\ws,󁻆 W 9L~O#x0?en'8^JR+F=-;1H"M!$Ē'tm1OT15w7ٱ.ph!0r3m2c)P-*+L!UpĚi *;]FgNת%&..TaR: Q *?^V1I!RT= ]3Y;Goac٬iE^mmG56U ;ڃm07TZYYb =ك5lkm-{(_`y8@j3x lX(|nÏem3 ƁPufC& xt =eD fc-XCuva\%ɻJ9˛R%d 2+Vӣ6*7A4^Pcm+ nM6ڽAs1#A<0 _yg[%4yvťJ} Bye߬u\5sKT\wuƀbp2>vC*/ūx "X l&Z9em1ȝjDzɉu#ַu8jEP[zYRCZ E"n}$H~3~4bR݊B A"`G`[K+!PRye;icu"GɘA\ݥ|,<|죱<4<=JO*꓈p2F{魄=dY Rz~" OCxi/#FPbC4o06:.?>H`MC$39$0,Q'9H?J@La4B>N1t( >)TDU)&AʍO1 9 λt2m,퍘 y9S(fmAK$m8ٶPΎ-t]V1/T bM0%_x w|4-5,uLYXi  T !xJt"Ky5l x:/(SD9XZm u(s"]TӅrqYk qWzo/$cf.ſ^h%{_V+0S=֮2\1Kj[̻ܗԕ[_|vBUi2n919=@<@WV(^ ,>:2Bl8 3oղCY=&\x&VW٫pm܂WN +mR7p+S&R `yA $JtȻshFykR֣K9X;/Ȩ؊w ?U~ h}R%or7txgƢ3`–.~Nb< Jtuit6=&"!aT`TCwlnhK,WHڷ`Nl`c30.KE ,5%hd:~{vys8nY}ƙo]Lc <1Ӹ@eb17Ze(ۣ},&hSPv>n}wOgq(G0WVR91<U ~3c~aJ!ǡ1Դ1w?k{yes앪0Z2aKoֹPXTեÂy=9NKhA)_Ag[wT;)*&i1TǛv& H/sxK:~y*>ܹ pւ39ouX{`ntU=;Θei}L V2=K&sc\#p]VrO/3*qI(/ ~/],s` !W8Bc/FIֿ|mWI@eDW0 /5_oH||^Ѧ}Sx85k|qINme0%A}G9I=kfw~W CdC}$0y_h>nsEuXU8Xʚ?RR~~L~ 4?#s.C$!5 FVl5/IC`L~E_0oT,ߪ"C|{be?b? 8ފ!OY4=  /  )d'nX/ 3l𿈑fo[< r2UVʥxoG,D Ψgy>ڿKp\8ghQ Of* \KEFJ~@5:A SV0y 8Y%^l;r8C&+ɡ t`sW3 'No$4YiG㈻2dJ:pv&w3!;9(g"0%8R\sp&R%N$VL P9irP .amI8({lq .ĕ! W4{ -Zף/XzG_M`2AC(|#!x,V46.-'vNVS|1erP,2Rm&{R%FMip.K'-|vIHG/'ĂfS'4# x 9Ƌ C25HM mZ `MH˚Ϙ) 3"(g hX,݀|zEXa[($l@w򊉙2(3(Qdhh2J[9>grPCȠ0ahCÆ6GɁ*!U֕XɪN |+a@JHBM&MHZҺ:Ht @`V&e,1Y0O7n%Q4sIgyJO/!}>ٽf ٜL JDHk拕i{ )}E^*  U\9`()޼#Y^[6#W|`4+I)QFRcRn*'+H5ޭ$E(Ilc WVDRxymM($Ttu-gb: ^P= iEDbq/j]B8T'ߢ*Rv|rJ $rx2O` It kѽᲛf22\:6+Kx`@ؕC$>I?Ldl˘"bbS1 "ERS5ZS%4}IsYve"2 1Vʡ%_zZU&V*Јyr(MV8-Y i[i#ᴮpڼ1rpZ9تh6GYm3Gu1)7UV[m;\1s'X>#w-.Ǒ&ly+gL[,ydc W<ʇtmq -͎㝵@͚@r?PA ֌ v=-ln(W$0 ϼro#2A/_`ҷuBPB J۵⭍۔!D!$񎆐;BگlUɫ!گiѹkG#ļD`c7=7!qc7=tҢ[[u0)9FV]5yO);Nˈ ]Ɨ~׫[ȗLiݏf띭"p%=e^2qߧ^eh|_H}d Rj{$"ɉݑjrڃJjZ[7}d@[?R\y47gZ}M#d,?Ub$XIEflU%M{ T|-ϒυz,מ',V+/H֡'^$"1/5lG,6c;H=ޗ˵Jd V_CYx<M6N|0~8 .d0Hh %#--AZ *~EM~*[ >dflsnɥ?GL)>χKBhEfAl)~^q6dq& iT* AE H}J>jZ_'q? !7-36ftN+]9]xIdҕ!cb}br"BeHHE<0){iQ㬨t o]yWO*N))QcdqpuD s9k_կe~M2(אKwG☒tf=5F%ȗRHNqʟQ3 u_I▬Lo2ۖ]hf.{I_sdb=oeYm3"}B\q2!5wԌثwE';K)}I!>9̻ĸ'nh;lfl2al>)rRP Xah̃ n89`+ ,ghJvD8M? xܠEՏ>)3j1+?5c!c:X[hhBuvDeO k'FatvjMO-S"e^ѝMקh8-rID,/ dtyJ#ZF LLWR}p+/Eqps<9b ʂp𡺾%D C6 6EǢˣɭQv;1E|kmQyoο" wDxյwFQ+ɫDQ;EQ;GQvDQ팢ο6 ExMhGQɛ7GQ;nvE-:(;" 2ygפ(~W5qw5yOQԎDQ;v7:(Ed^۵]QT}w5@5`}Ocos_kuCQGd#^;GQGǢǣODQ;v>Ez::(g# QT(j(j(jQԎWv_u?Q]ڥ}$4X5(j'v~*(DQ6 }." Ad)^DŽGY@&]< UZ0+Fpql"C' PVqR)eǻ+rj7gVKuaD ~_y, ˌ~-Ӵ86Pq@py=oflo-gԖ,OdA1؜|8T5DJ_`0:iG0I Jh.0@Di- Q`|%Q-@ҥ^Z=IV6 ho%}ۈ\!vҒ$\A犛JY3gv y'iFnGq%](s <"ɾjŸquFJ[F:%'1vl};HdIdWZ[jrDgIV7~ds7L37t!n" jf"+8N.j³~+ A\EHTF7, x'NH仈h IR]D[9qM.MsNe{H%iHz7arGEiq$)jK"4ٖPO0{:JTM#}@N @lˬ c U!{HųwEPAd}&Պr}~"j0q9 *@p((rmNq5و흵^$SKK+axH"Kw!:-6'Zf/*>G/J]R4^6<;h71@cVrVx$):@n>mάwuIr[p7 c@w6|nh/bpZS#>1وϝ*+l5|%Ϙ35rx_!B^QM_UH_'IV7VI]R-lM٥ks.o+drdOД^Zwwfҕq6aPw"}/)}?) vkNQa1bD;~AYy eUDŽb" v!bן"Aq׈ "#D +b"]Z!1a.cv`Q?(x}1ypxz: uN:,6ob8m|\dyC;B&Grvd%`aZ%?fhGR~|EnAC;`gYttJaաwJpf jrCDv2O#1SNQSNQ6WS,/w>ԌW>z4M;%>=#\.d&3H)LR~><+V9[Ӑgf `b,lUI:'X4l2TRzRw4'qrJ&WȍՄאorjݫ$٪ANדED.-U{V]t7yʢk{j%Ι17,l1`BBCc99ereDPr\36Ǡk5=W3A6Bf#DbPaCC4}8ȅӒi훔X<;3 iQ+C/#QjG,|I^i&8] S0®EBtlV#"Q(/&64Tnl(ű2྅f{S`,R}q{Ì9+U-K>}6Z[-An]S7:-^"d5}Tvp V*NcbV`^99&Q4+ax%jh?i )Xgʵ0Z+ a7_D_ y.~ Zu+o>~T]ؾC]Qrg&n CseQYr58!BVKn)J4:P>XFxNrd˱O:dԻLo=H6b ׳T<TBu!>pJ%]M39hJH_?%\=xJj2%ح0.?9룦{I`'N z>WŻ@R1%Kʻ/e9$&ED1 9b`F*,VGjIS,a]7%(z%|sTJ=W{FT0HnSzB;[zl:!\g9~J(M?!81Nk?iJ:# uN<WAs0g*k$YD(Jm64r19=WIS*;gJ v*357u:=W 7|-XC{E@iApv&Je9*Ϟd'=Ǚ G't֭Ƿf) l ?JJ/-sq0bMsK,Xn1oXtR^W3ͬnf/t]/vy1-fɿܬj l91H&q|Aty[:9Q< wm~V}l݊qCHmm_8a Ze5[t6xlKgǛV 4Ō"5 y ?,ِ`Hفyn}~b6'1'lkl:*].2 ih0h1Q'кu]uvn <&̏:2 ؕNv>1LBa GpMp)uZ%/VjKZ)*]C`,1+\FHA9Ou=_H#P((7AlTEcV_1%8@ R 4UJl55-~ `͂(d`*p#~/ pJz\:\,<;4Ei|Xc4Kȫش|)i[(4(b *ƸxReQ3BIcco.Nj8Ҡ#er8n~Q(Y&@[4r7f+(YR&ZLaȠ$ 6L/ )q3 y͑L5.G=]&B牌uoHQE^6]Z/ˠu^GA  TSz™/C+);2|J5] UiY`f@Q@YBWB)ԪYX}UAVGܳla/=[ZiCrEc-z踼E[ xT,RWVn"FJ3[ J}LΦMCW5 M^T &f6͸GNe2Tfu ]]LAn$7F7E7+["mAb&>kh+~ ߽rrǗ1 N`]]3UtNwSH}OsG0&}׳8kK&4o7d>R}D$ IyohB$^@Ze6=HߠC:{Iz~zqa!(&+~hobi ?#D{(vюԓdPY}hҾ&u..Zϐsb6?ֶxǴ>붙9k8FO@Gam˞elC# "5M28<ǦrZLg}[r5>o~NmHmX(].I75"]Pe} y2żaT1ȒںQ%T6F=:"Հ>gz}IcF9W6sc@q{Vtף)>lY>>_EbBC(s].)Ì(hٛ[+*8ɭ ;>֭Z4[|(Ne{:K:ΎymMXHJ?,^cg[gdbYܒ씖s+;s^h$0R87| >p!k5yOkkfGZT9j}u?[D~lOZt~u?]mϼϵg[fZ&}u?Zr~_i_mKZt~e/]l˼oenj/;п۪Z~>@f"|Xa ďZ''-;~J`gjۀ~g7nyOzUǽ*o_NUX՝غ}r~''yr~O9U6?(\ҪSUZymj^ZMWV}$Z>Ugsz>fcޙq\C;!D5$g5n8G@Yb|ĨśsM>O&Z÷'[wh yjE֥T 䤗7>JyF' m@穻+>aX s* Д(7,$o7b R, ?^L Mg9&cꥤ=8^&]8@&Q; @ty(((k7 ҡ>fg vV,"%d';҉$Vf:9Z? `ǻ{ /uG@Q+fu=k Gi %E/%Mʽ 1>2 y"d(}.-SaOx-L6o < 'Xl/,_FlNU\>ooC; )e nl,7jfX./ܥ]]u:X׺f[b.ƊKL?˰/+}VY< ^! x+;&dbl{!E/Sd%1)*\7>>էf'ŰmDp?̳<>LVp)kDo[ѳ ]:& ÞoZjic*h Utxa5l3p#io@$5ҧ1_BͰ/Y"6X౉-vby>VNl&U/(!S1;[)As6g{sUP82ȞH̅ c LWo12oG\1~2UZ=Cb!^@j*;55Zױn)0NRݛ;_rW TX n>Tݍ̻.Legc9.v_ c"(9 ݏl4 +rգʝ۱I x^O rS]x㳕y dlX[0  ƨ1ґo6 [m"@Ygg۩1wu0!;2} H ,pEKM eR)%KV\{u=W`E+=V;. Cؔ݉@0ږ^xE3ޚ=K._*_*U\!8Ng”FNW$˵i~?0dUpIvM)Sy8yIy c@<] =6>"b* 2e _ "'L#;^6pw?u6V^g,GY|FwO X;;+KU~':R%ZEMom, l `R~5V(gj:=ɚCùbbUk[FF.7f6OνJ%vs~GrYJm&mn#3W[X8189tX &@MrRAeh6KMie7ᐶj5 oo _FZeH;^tY"\L+Ud*6pqǸ}j;]mk oo ءT"*>ք½J2\O1|apt'rU{r#5`Wb8%B,x$qw#ڭ\]@^eb`ΔXYw;R 1x]uA=lwSX&ba=!ޭ@MߗrΌe>,^9FebwiLJ:{$@?fk˜~Cn/f47>$:lrY$.uaK}>Ocẹ>D9_k}O9y$<'9r)>JD/X$8f$4mU'sw4OҴ;ˆh[xPcg4M/ar7t-#ω;Ah'vQ2j@A4ȕHHc7#w=ˤI x5㼢T&Bgx_3P6$5U!"Xär Нf*%!|I>L!ge|i~R$9 +EԌ$zy$ Xs>)҉?M4G@U>K/rK>wY9stN9<)/4;&DVJ0d.˄:W=*=fVtC ג5Ҿ`V_'%KA:RAtZү~0)(8D> Hm Z%ڎ+<)Yr{K7؂yN\P/Z/ZSqĜOi?#pmkM $ dJkH ;;@e&/)%er t9L $VPpAЃ ܝ&,RLM7-R3JrJ%=ULq9"dֻE/VuS9bv=Ty <ңv!Ws@s3KX$ (n4G D|1`TAjvV-NXe J]CVoP0W)e.2(qBP-19| 9G_AdnO AJ3&+Y_"_o!Z:kxG+̵g34ıHDmߑ1ZA謊QGP0`fcĚ+d!"AБ:Zql (tԈ"Pu}4 萨ZBA>T?gM R(GQvN RQteByLpS|K#\ȩʆd3 -SuԠ.".'ɲSnjw`0o'L ւrTȃIML3A8A*c*|AT&OpuNuN& kSrTF4ej0>X cLAZP>Akt%Zxi#|m5MmgLj VUX޹m=r5@YÇx<2-f@TI!TNE2w;<DdClZ0ˊncnnSEP fmͶ\:}|Mn)bvTʋWIV^a\[L_"/i{|w||&FHaI?,釵a~X bؾ=M/?2@&d@^ 4.dRYx"qEL?-kAt17DEhH\zqmpЬ7敽xo.Ri:s 4* ˪{)sJSVc}=B+R]9eUeNQ6saթ\X*k v03|Ҫ*Z}KFK*Z}J.ݚtk[/-ZH֔[ )ZtqNj`{?;~`|Ϳ1K\h3^ipXRj_Čbtw^i&dAíU3MylRMO utw?M>+5ڼ}̗*{|z L.iA-&iVLQtxൾ"qyslނ|\LvE׾/BΨ YW*Bc\); FLs^zr|٭Ja*+_iK_ꖫ )K2.oe4Iqn]ŭ'7 c3`>|Η\P)އynuͨldG X\v_) 1{Oޥ>4 0>h>ĬMfI&DBY@O`{['/0g`|ڌ8l`7og6 WN^x X[+id4@jb|Y;5'&IA-wV,.N>`B9䗁0r%$H6)+TBެt|&OxS dDF -%ϮaL,n&mo}*lMeB:p@W i(ʦ9 ?++Ri I`,>G9-d(_}{~Ƅ~h"/'!ҋV¥MUp QJ Qeb!h fm׍Dxyp< JW( -RxUc]E{!<^M~+kTCU mkE dd°tgTڨ6@E5_8 RE.o$K G7EȑQ\B4F'Xcۢn~{Tэ:Nbj ,r `wn %U&ݲ{#{H T7K&9h]o19/#tRW\)xRݿ0  gapo~wj[2=VxfK]V݄ۺuTiv~IEr||At/_eO`6./ \+^1!(%6|/Y̼^"gم;%0} vSy}irCmHn%gޗKXDZ^2/W4(q CC;q3&<$PDi{)d&LI_&)vh@&Ǖ(^~h ?c y)4}0 L3?\1|1BbKJX$cW&>ARC t]F%?B Kx~ b}c{1fLI=ܙ bDM.1QTT41MR\1}VNt;t3SsHD~p܏gb _ ~s0Jy6A¿HlTDc_&IW Y^Ĵ7 Hn jڭٯte7H:7MP FIZ;wmeUwI0#((YIu6$vTdO^ɘs `-〟 [BѨDjd/H=^P) έS:0UCn.KB$K|/K̓/,toOQ*vЕ">hk:ѵDm4=hzw1h?GEqHrJfP?0&@5jw4o.GhNSb~8P >6EC;(>88<$~iXU&Oa4)5O RhAeiIܳ8EuQ E|iAI*;cO r&&4q>F Z G yUuy(]J.;YœH1f:fR|[m溑PLnq eA W 9pp] .6>ʝrZ(M?ԹM EGmiMNKNuN<+uv8mpaaVF?KR0g+p^8MsTRFa@ lВSMs0 Mo'%laK ]Bd\5ev/[# h5n5.s:/<+ik` 4 0sj wRsm<y /TvoPED0ͲYs1ָsD!ؗ$7e36 HTB5&Ј},\7 1>Ei, "|Md% 4UDJ XH#X#hG+hЎL1R維u(ZzUwa0F>.VU6UT^w[TTk)7~UD@U&&|5Ik\j$lb׵=|u K] MՒ{G׮1sT`nHƜᡊ'K٨\QKT[ҽ̔6s1AKs;[X^7Z:=%M-alR֬sffA،TqQG#x-ۀNj V`KPKRYpϘ#2nM7)L WyVJqc6tX Jązaj 䧕eb˥XT)f"MlF)n5KT%kMڷXZSzG`cWM%b_6I/$'FZAMɲʼnnڸIa|RE j+JV{$!LBHMi[U*Bx: OV;[A'TQ1W7J\(M)p\<6Z߮E Žڎ}R<Z{*3u%n ݨ"3pS$wHvs3(H6 6[#QDhkh7h3[7j ߥLw% VJ{)vRYձ<~ nI`&6 lO)Z֕;ާ߯Uw,ݤtC /@֤:E= 7fw/Q3 J~B5.K|x1r{k&B=BuIIGTxuIO'H[kN& JZAm듍r§BB!5#Dg`6|p6χU1_I`1bH*oH_2M+!UNT) &_' Am}P7$Jg!2p 1`MJiɲe-!D7sō鄻Zv0m8gc+<ʾ\#;--a!n; omgOƮ(!ϡ 5p|n >! 퇧5@?jH"F6Bt,|Qyd/"^1+~kuofxOo#ibYP mla!#I8o" hEJwd\4&zBvfWQ6?/Y(UdoTtKLx.?,'xc-K@_ld()DTfb6nqz`/8lKQәLP: K{dq*{0ʰG=!NRW`5 crVtif#˞h`gOt+f NYLāYhN=]LHxPrC6R!ËdY<>{fX#ljas|A.IW^d 8f팙 M3ZeA3'thdU2x4f :B 4'8!|ɂѱC3l0$g^ /p_ R˷lCKō1 xIER-¸1<991 ˟txܬ;nW.gue4|j<ͨMv4,Ys(QIgO*!;Q̓j"ʚ[pѭ RMKmٕUs(5XmlX\5Gtxj͚tkLZ.ׂnp 88F5[PyY+ك&&-^Y o- Z6&cg/%l>-~7ݙ 4VHw#~C^b g3Wf @̟,2cP A,R>g kV ya_Aߨ=To>X3S@T[膓,x)O9e? NSaU Ç[zF91ģ6{ \ =  ^35l<5%? bfb˲ĐP 96@b<{C ][C͚w z_ZkAoV) ؗf$W[ZoX6Z_&do?EBP`@.7o #* bBK쇁q_rAdP[_,S2*HM9ad 6xs,,ՃŎUbS6aΤP.o,ف2K"\IO%WaD~7Wr|#:ūŲ" ^rYR/*{TYnة[e6t [/4Y'|e ' r8tK] xHyl6Cա Z`IلpSgM;),ʎ<Y+?x/7C"+<d=>L^Eo\q屙Ⳓ|4l5;QccyƮI НiX墔YLY4|p,l&U #⇹,` Wg.0md%(t*zJSQ(E֕cӊon/p5E/XE޴E _|RʰKËvi<2Rx0k?4Tͯr?VK^ѝahc_O`])^X ށei1L"~J`@6+&T~):(xe`D)`!Ђc|]5| _.C3_ܨd }|Z侀Yq]_".|րk9(c{z0!/ bɷMLpqi2͂jU&ZzTHMbBt{ Vf) bʘ]a!L3 ƍw|A~>Oß|Sa?5kY&V–ٖ ~&qFlk&eװGh; I4|1A^ayzY`c ҊPclLeA.CŠِP}LUbET,&3h&J(7$.\!I|V2&D>/Tj+1&.o9 . ̐5ŏe 5Uc8"eQx@7fL"/kxUTӛ [h`f@}x5ıeLǬ䲐 +-͆E[@>lə#6t,#9< 4[E8G[`=%鐼.a 4q qLJyr V81; l[p'\q`8&"|-aBrcgxp/^k 6eWW񗕫nR~a <^hs9~+jCDQA82`i'a(Po u^)iS&- ;y":,oĉPƿ>,ލ(}r }u93%ϔ?SL3%ϔ?SL3%ϔ?SL3%ϔ?SL3%ϔ?S7L1{i1à%_ n>܎QbbRba5f_U}a>vf,A xm,-۽a ob"7!310%>z62:K8X6HG2Zd^=.x|WX"})6\]Ae( m,yr|ah6 ],fr`1:;<@O mLDR./R`NXE*c|Dʆ' p'H)r,?((̬8Zę=ḺpŹ!XxY^Q" o"A/.k1@xHg4cCA+..g#u'}bd/hK(F7+%ڋox+27nZRcT‚/~k2vWad%jUݺ ?˱OŒO|%SVYAm)^28"BZ uǥ`WQݭ`Uo)H&vJ4QUa)J@kfi N!W$o аVփ .ePlh-ha^/fW5f`/ϲ<0pك{q (6Orh y2xBɜ+^>qzmM&lې BN+@rq+{lQ+ _/bjm*$0^ iZ]\:+jfo$`F7׋ F._8ۭӅ[ok͸az,eK kW5ҟ8^ a,+PoEXIs%c׵b5Q,ex R+0^>^rpVb+Y5!*D|X?E<Xm@b& j] +,qNͭCLJ'A\&!7bbGd_3c[S}s}az09rCAl2f|\J=Gr=k.³fiO?xA>g.g>\}sշ:W\}s{w~knpٹV'kvyƹYkwyE皗k^vyŹ)ާ{as}޹{_r}ٹg۝]W8zJgUή]8uv]uFgMή[]9nwvng{]:}jg5m7:ovv}.g8uvٽAgg^g>g~gCݏ:><УC;=<O9=<гC9=<ЋC/9<۝p~;tyxv;+{~g}:llllqcΎ+;mv:gngζgm;^pl{~+W9ۯv_lllll~zg7;oql~gw9rlng{:w?lپپپ}g:s?l)gg:۟s?l%g;$g۝W8;qccgǍΎ7;;qvuv| <|gΗ/;;9nwy;^}g:{s>})gg:{s>}%gW}ow]{ξ+}W9v]wzg ξ}79nvwvgξ;}rwξ8uw}ξ}}}8tqusw={ξG}9w={ig3ξg}9w{eg+;pNgW;qosowpt_g7;oqgw9q?}Ύ9;nwvqmm>lv v`/8;wv< ΞmΞ9{wrv[qH['6C;)W2^By[mihsZmGBkGRoG{B8CK6ۛ&:&;Ƕw57i6xHLx/ #f#j8L|lxILkxZ'o?5|B?-?R>>mhc>F`|B{(F^{P&7rZ/WH$@n)(N?HJ<ڲ9}xSG'oL'Ro`[h-)f.ug v`o]]Q{F1ئ}pMZL~0u9qﭳcU>¬kJh{b*mij!.d#[R#yM 2! `p"܄w(,@tKʎej; "pΣUJtk C<0mUV02.gv8T(k5"RMrP _X;܀YW)p vW!2?޽Uaf[Q_H/S[5mqx?=Ja/}}6g/K;/'ܗݗ IJe~&Iv- w-c>3wxYpO.ZY"M,Crt澴+l钀e}2ztMzĎVց+S3٢OU=f#12mVf-)65q+ʇe,w y7&+m*6Lc;b'Ύn36;*0,1fv&{ U{ ? lnۆjU<;%.nI[×gpۆg3; =9 عGt\޲E<x;U[d6 6RsE?= T{H&fTbG@WO~{W`Aⶭt7Z.D["LEUx|Xbq7U-tǶU'TmeUŒf_,`շ*V]۠ٸdSYa3\y nFM X/2ӕ WE%?VOܼ6;Q }\2:,N?M|@xC~lQiCc\%ɲ==XZw l9о'U< N6pPOf;{= ,.Rd4!+g/lKegL͉춭[e '.dvsg@;-yO*aăWlV5<K} /7]xyy-IΥE ,T' xv,4ȬzACdxW֭v|!~Y6Q%G ֽ{:Ç苧F:a'v PMnqx{~Q-%I ݗ*o]1ǪpZ{ǹ5p46< C6%@9)EAԲpŪ.sT n ߁\Q_Zi@O>3feʤ>Ć(+j ~ hg̏+x;+sixLŒ1yFYYy) ]E)c} lılTw=V7βm;d˗ f-(HxR[>7hkNM)7T,\9ߦ`&>D<b®q>ZI&;QUh_ Q^Cu?W;gv9W Fyd^/pQ䗄f)aa\Q_. QfAF̓2egҝI|(]w?X9\l7/ƚwcvӨ$[PyYr.'c6ȝ̮' D[x&e "79앍;%9rxP:䱥"d@MGTX=ő;éؒ#0ydy` X~c8F7 wedYmH\IZUx-jR]b$/Рւh$nx8'EH:vܭ#hh-9(+;NmKgߐL&>ҵj_="{2s  {۩ZTy6C~a<Ŏe0DuYi1 O/j@⸀B0$3c aGٮ*Ynك#|z%J>|flx,Mk| #0k Szȳ"<1|e&X%zYhC*(sm0͒;;6' a16媱xl!35 &RRawH0+C]:@tq,&9@4l◇ [,tJ8rQN ɖK{-^4h4`y `:?5 /zs3x"/;ƭQ~G9gg˙<ʣYL"v8GѿPNbٛ^#DQ 2bo[dՒ1P CG+WNyt# GcH|,x4OF;?Mt4}g?ܠ tڊC١.>[ k27ҿ(EAPUڮo-_VfUԾ,RjךE&,";,[",rwEn^A&7,24LYdEvYdOEvY伟5&+3&LjlYd"ifkf]h9"lsAkiYdo"ofl:$M$pΗ[4_All-f[5~`kAᓯo ~pkCZw&NV}zDS0Ȧ`{ 7aԎprd;h-i85S:F7+VKE#-cffffffffffxUqmbi4]MUç%9=l홉֝l(p"H@"^ӹ&| :ي`f4 +<^Yݹ'H.=A POujd㙫_,'ϥ̐__ +^%~׮~]?,S@H`(䠗%g I7K7O7VHv8f+n#I!I! cI!Jp+f]zmkmH \BP@7]M@U19Ht}7L~so–0[M0ݦe%U7YqS1=`x+#׫@w&*- IFvI)h2q1[_xղf1' T~V[-X30I߯K{  Fo1vc/wNp)w1w@;HWL%OkCnJRXjIF$P3IJI֖@3@hC2,_`a N`zo֒`PD? "_QI``00vK5Ӫ&?'a#,5(n7LV pHe\ZE#d>̖iu򶸧9> K?伐Ufdm8ŃKx?;LT{ p^g(N y.Ap*d Y HP2GrDlFňUy#Cfg;de;2RD)wR/SUT/,\nn=j鉬I,ɬ\Db< Ny.x][uTO!2__,S_^_ʺ񗱜 ғR\2Ηx_>t;f_Ûr^^3Tzeaz$7v%+#ϛXj.!a7XMDʲYsml {z;kiR`3(ȼ],{Px7k֜(O%Fv][zyj56W_'d0{S:})~͜oi4k+dBhe"Vb Rj8UClH9$=tȇqH*aN,:q݀5P'}Yw>OӬAA~FH`e0ϱi1 |}_bm`ˬ]֜9A1-YIMO4dfHJ17\>405Ss?N-snyQ~`tSVų)C?t "\)H(^[~ʉ_j& k;7 "[VnǮkB\q [=h((|61n:05}=g$2(N*")sSz򕙩K..]*2-ӆ6?3N-Ywĥ*SWSrőW\ ߴΗ,[C@kS:>*sxqhk: 9O W*bVuܖ,]c,ײesXV@q]´CX]fcOw\^}r`OX^R}잸<H!p2dpkGK~ma+KT\!>\~C2H716%[{dpƓߜh؆$*n85\~[2dp;\ ntg2%[{u2uߝhF$*n$7Qq]lD`&\^C` s_ p}/zA b X; bݴX8Lns7#_!@P+JnU<Ȏ*: Dr=I9fObI*1{j~Ŋۯ,O%ƥkqzNcG1$b:11;ImsImIm Im FnM4z(Иh@hA1,{$X(nQ/>=fvՃ:-Qf ?)CY'8|L0"=@Bq>HQ ;EJEK1cuʃ)r <[u}ಧ'amw6*nuLxq&oxJ&'I)4}b0PMCtObd8Ҭ%_vN;u"'`O[vb3bόI,<+&q1#ωI}nLb>?&q b׿0{Eg,^ILb1/IyyL+b^U1^5~mtbI,!&q1#oI}sL[b׾5&qb׿={#8{gLb]1w$'&q1I{t7G?6贵N[lGR 2ׯ>Ь>d?o᧗W=V}[VXѹ 03\|&fAl܂q /ư/0/LWchk14F M~SKWշYAn{;.xX %~yb ^ |_۹;CM~5 v͂.ZOwX^:mBut>cY9FlYIBO~ppu O>G-KV*)dI! *$ xwa1dp%+9?$11hOAt/AGtoA=1HY369/^)_pk{fɭ[&R!0#]m3A@OJዹ$PZpdw<|W[;!1hĠt:^|T 8X%vhsɜ%Ή1UEW=Hd-$A/!DD-g'fy g%aTj憆ó098]Y";wnUQ̝2<1iU;GR *eB- *.@'j&Ȥ|*2<2ixEdȤKݠx :U.iau7Pj T X16Z >ɹm?|0.5Y\j!:<:&.u4'SçBsɯm +aV[Xa*Ze+{=YZ6^Ԭp&_'N#z9e,_e60R!_QZ`61c֜Y 61L-oڸL=K8cDдyEXc؋ba>JJ#`R]/Q誨:dMonl-M"\&ILKB^\wh{ڼGuk^6e}QZʍժgnjQ`Z'eRGt|uzt=ˀ6ԑd@ZL L˹;^*bEbE%jI2I:Z?].JT-bݚ5N^+FlNYZi2QHj$+1٘jLiFji贱FtZ;:m]3:m-ZᠥF,TV۬(È&HLyFy8eEބ Kҧ:U[wŅyvke k*tۭ{ϫjjfev}fkrrmbT+ oak`{{_.܊_+J|]kMHqLV i[S5ypCV1|a1l1l1l1lQ1lZ8cۧΌ/:s!N=a~X˵({Or''(lpS$mgi%穌iLd&Ƨ3MV7639` TL#J'9=[u yXw41lΙ5fݔǟ2S@z#} u9~^,ٜIC@fj%:;dElzډfXs/2HFY[Ŧ,^UT,Vみm?Y:]̽RtSU115lUNkrՊpvôA:maԳtCP̽A[;KQ;^jW_̽I,o.EN[b-x oMο-Vv}*MbZN=}o7J*z#I$2Gzk3M`Qٞ-?FPa"\@4!Gxl|4_>g8MZc?D΍OI "SlSidvM,J&~;"L,?tl964K?ϤY1u_;qBYb_%d2/z<9M5׿trMo5Zfj8fTuKX4E7ú!Ywʃ4/ߞ_^Sm7LfyB;b@ss[gNڧ@Ky󺩖6-Lo05f3AΜ5 w PP̹^-xȹS!\ fm |Xbjj1Sis^a[q2b20*ͨ\LLylP{F/4M aL[)vLO ]+Vz;bcf&<6f&<.f?>f$=ASػ-|v9%a _zZ3߇IcԁSt&d(Cuq> M~0ެ8Pe><:$O,^X3aWJu`yha؍0==*Pvec1*fzM?'<=g(<z<sz=X_ (^ ~i}yWX^`1=Ƨ.>}k^:{> )'۵ n$N }zA ^1^1^k? b݇$D;n?>>KsǸ&TRYl O2 &x4Bɧ˧ϰvJtw@k%Νl=efQ\TwujͶ,ʨr"`8 *.x?tDн%ܔ-Q 4Ý{&:#.WtNE+A>t?QAy\ '+3er'd,3fSɨedJ5*SFM2"| ۝9oSw2K&Ojl*/l c6$r(lőro]&tI,Yn͊vn-zl;X5a,){jA #kx7MLW&: `=|Ge43m ^c'Al4UN/}VU kb A'ڤ/Tŋٖi~Oֲ, 6h%g(h4F 억4t, 1R c*6-pxhu A۠YCi[3f[:rwᡷKdžcCPD3KWVD:/΢٢6Z8m^{xD7u~lֱۭ,ax۵m~{[xx;]ޮ%loBv@mK[n.n!ImEK+zAIlQ{un`ӘL9txçikq&Tkee(cCh /;:-q ֝gͧZ5pkZvc2h0.5Xk)[;I]3e {k%WB3vn%1g8EΔnG ͶNӕ{]T rel_۰j[4ܲՂF͞9 mWv5.]ds8Jcrc 2USڥ[u'Wc.\qխV]k .,QvϞm5V/+˕w.Tשe{u\u E. ۥUu:3Xo(rn֥3&n( @뢏&W1ﶫ?"/S6fjh8n\s@;DR[Y}Q6+tptkrHMP!جfť;qć!рu9-nӮ-2bel6``jML6X6!0XFi(MTy =5*6Mgf 7؆s7[*Nj̺wwcA'௺=xխ[2((qVAw@g<>}̿.w(lOeDuWLDx}a.VDCk6pBc}äp,Qu<Fve –΁ĔlQqsDg `dy!rqT^ LY7k~ ᮀn F-Agk%!~P950B JZ|NCs["BD١& /WVl@޳ f,H*CV"Fn5dQd$ ,=]3{cL:kCY<%sn8`!W(E@!Z.t24Em/ 7nLV㕳 4 S6yf-hijqoIͪ,h$@:&jhYh]x珔:,UA$r0ykDUR9"S߀z%$uAX]KbjC%% {9IEs#~W 0@_!E;%'vDU&qeB.$Ag@*_# V Mn Dp3v<)t }pynu k4ZT XQdE\ :XCh*RLr%vnYCK5;Cdļa^ɒ6J2YS!0$`|zP,c&h5SE7"CFJL D@5JUP5I&&rREyR2dK=RZU5WCbBR`S;bE*~⠙1<[^ %D":#$,]`Ǝ~6Y/hz2 撴RZ[& `^t^as /\i@ئf =eY;˖ d%0fonQZ Q#0보;rՔjSC. 2˴VY ԜԬhഖ)JB\-P!@w0qH_dAf o0|@[ i 7 _l6roY8QW/$y F+!+]µ_j D Y|[jBC խ즊`TqR%/CjQ1ФzO_.I=gIȂJ7p8=-X-MDIILmȧ.ůB%^6I4a5=aC&֣}+|ysΈxH4p0~J26l~K}b3-``me^7KaV= T]lW_kJN6M0T:d˨`&BAP()p %V]TC 0UQG`) \@R֒:,"G 0=*`ay1j×Ơ 侦81g drYlpVyw9i[=\UU\UU˽\UU\UU\UU\UU۽\UU\UU\UU\UUǽ\U=WBީn4i;! cj%Z= TP%h߃?X[UzHC={X/{A b=ZxTGyL{\ =?Q5jy0'k#<6=%1hښ猠iaO Sx x|Bhw䎞i"߻ӣLj콇{Yktrܟbc"u1gwX` >(Sx>Ě+Rۚ|5&Ym()UR7>+c%8+\̟`87dSm&@b=o:>͛r>?3Tt9Q* Yf&+Y~$%րeF2W$ Adܯo&7R"1>зuبwxbMC?jg噞lkl !cĝJ` ÿ Gl|/b/5W ؽ߸k*lfyQU֊ѷ6bjcXZuV6L]f!e2H3Y% f?$+sZLyY/sڿCˮ%hKtZdC-&1?b8%ǖ$=&&qݲǮ^;D1:m贱֞' %SVYo0x6tS1wjlޢbU:(kU:qUZq%8VCbփ`$f=Ybփ1U:%bPbnvhCf =AKf)EФsWBF B'\])Sˁ^mҮ w3q֎kvڽ {&vfck|ݯmb94Aw2&di$]͊ Ͱ]{3k7áwSNaSӃ8{$rF g c|jLs4龶ZFa%u^)z(0 q"Үޝ$&6w >co Nq! x:DӌL d=d3BO5 bخƖ\ (.5l-S (r>qc0W1[fZFk-:?:A0^>05?54=x#8_fa޴\`! pv1cmv17,5{*E}j&nuL< nSefGA3(=-cí..[m(貐9ۮbV)N Om(*9Py j[T 7*;5rFat=hJA|Y/rY-!*Pں&HVm9q:\P󳊘G 9*w͠s(g0;);p4od+xYgT5o৖SN]N^a0T=K ~dc;u;*j%Ц),mikMM^{vBb`?h#L@=.^CQzluˁor0 -waҙ6E(5X( -Ef`M+{?DX'd7)B Q/ͬ]AB/U>-Q nxsy^gA<@_9Lj s 'Mq@bt%_q:V `2D! =D?F)L&bD ˱+2kߘ.$ҭc,mW%޲떃-`SDewC.}Rxw t,Aa&iMݴtO7cM !I`t |>6\ovW#xjTݤ [=4M}gܾ>M yT,hWHXD._wf!;P`#l͊1;ɺ@b1k 0h/$ˬb'wjǎbUD'vLܡ8Ե* z9nXXA]4.-є3ŠH:~u79v6,O0)Ji{`ݓ \=-̞)e(އuM/@ r{G~Sr=wAWx ^W& =Ǩ2,G 6dcn<,Rp6!v]LrA}x$5n>T}6S2DzAbEwqdzwCd=!N9Ĩ"0+IL/rbD;Oa_ߚ3*a Y!B;^Oc N$t yIOHψjX|٫g1f x[@l`cSrQMg꾐Hb,/fsCQKX>^ʵ^ZG36ʋ`Cc,*Ռ}z3\^um^ل`#I~dYE RVDOO7ztfnq͕wQw崈6f)>^芃+GC(=fy539Uv#nuԭUtrd&݆:՟!pD;ײLUaA/W,,k@n[xКnk%{ D"]NlEkڇ!zg7.x}6x}>x=^w«Vx=^ rU0fysw ;t;nu㶼k)Vb5Ji)iޗoa_V7zq9pfȼčɃב~'>IܻFwv|}f axɥeYgc. eqޡ?;םÓ*wRϝg}f(g0r>3V g?|V#g?zNcם;_VLZҘŅDwA /.f I$a.eaREjPgȯPX%a.M;Z^}3z pYG]X?_?9F |d/ѵ} |m |I0sE_I@2W|??-m~m~ȡpU_;[_W>/_/{%p)|YuMr~=·s&$ʒXMjRI{ÓE1wmp}d:ݤ̐ a̰+R(@GW/Β;K&墮,VM~`DT̅!_3CgaSf;T[x2+_{{Pi^eRYnu&-~O VJ>d:u s2AsV#" MLN0Ms~`uYEk^Xu y6kX#m΋oӥHUs2`7Y':/Jܭ< PPt<e#T7(ܓuA YѽxϹ"ތt aB2zu5r}4pi']v(a Ƀz!iȗmLx@(<#kyPF9:9\-Bxd}AQ2`' =QF8x J'?y,k6"%3:$@͂ZONFDƲIhhM(dF% 2 dT]Lx|t 3 (db^-|/ݰg'qzK,$lMg蒀D/AK ; tN腚E,(E3^S}R z$:2 QqH5D^yVZB5rZ_݁zpu:5( ڍ?c`;BܛvbIo o oc'Yfkjފv6C`kWeu.Ļ ɣwI/݌XyWI!{/1 0̴ؐFZVgAw>:قYk5Jx~Ga ^fu#Ln+NȪm *cLx LMUhO}Yx~јv~6]Jtݴ-lCNaMϲ9FQ3l_`PE |8_fjZ~(q]W"x%}MVyk7Sp.|K6#φUSdʾ >1>tD 8~Xly/X @'3Ub2?a$D`/O>jn4̟-8ܦ-(mY` F;yKEEMqkU`Ϳr%z [6|Lj OU:F)j΋;W"Tb5'ZGʊ!]?=phE'I&ݥk. C+?zs 7"r*R 7&$5Iy4'H=A=q-s0K,\pbn*%z, ?ful ?.:p;F7  "j%'ɟpXu1wI'$sjDO ?}uF옷sw& -5#uB.ԶBŜ9knSGΎOϟZwYP̝E!T/'ub8t50b.!RnK9|85m腀Ŧix*+zÇSCt萂s2ol0|mөSSMPl*Oɗ p|J()75} D7 ^B˦;Bi + 򊒁0ч+2ШՊLx«W?gTn?M<1y)ʧ`ʋX)^<E\MhOSRݳa !VΡb9D7"AL$ef ZVPWNgS]3 hRhT+MtG'CՈ{5`O8ޛԼ `1Љ1 Fw>jOox>IS ]  cc $, ,n`Jryt.$ 6#C]xwmyAbgku17.7"P| FC @ڞJ[2ǜqvY k+KfYV Q֪L]XWnzj:)nP MCl6f7-".ZMK#9;E6CYӮu~AT@Xր07ۋ- C\oe{}Qyaow^ :HvOVpŚs{RIڃq[=/  7;vc2 EOhly S%Weh9*Z΄i^UUxi4ZSST'=U= #h )҅'y9MqET#VN;޴K>́`U ؆bvzZ.KQ]h\tpeb :V apRP,2fdZ0bynX@nӞ[ þ֍a{`&5ħ*Y3( L~+20 -LG/.C!bb-7a.z_-ES4e a 2 c4_pgJfT z^yVB!D1Ьۼ,!:Lsn*6R <ڭz҃nۦȔmH0@m[l9©)U<ذgn&l2AjUEꄦW]uj4UMzFg~ly 8sI? &@_$i-:bZK{VOT5٥bdنM?\&~x [E" [b*04쥨?V7 +%2(q"=^+?A?<''1Oom~2P&2 _Ӻl*`zzv]6L9pg1!ƣg3LI*~y>Q #13@=_/KilNyYyGT/fFDy }/eXSeQ ܗ3sts lf2_DIH.cWgw J;c$D]W_+>'!D7sӲ=mbZӸ@|V͒bIobv K&q%[z,XoOϿMk@s1; T6連;W}dpkPF$x=ZrҀȖrծ|bM.|@>6l|zsßOB| /%9\+ʌޝ﹘ZR׵c Ƽ6sHfr·br[㰘N|zS}/P ?H4C-k~Dlpq>;! T$P4prSh@c'Z{@H̴'"vgllQy-G~>Ѱrj+3\3A v ‹ ŲkyQ(+; <[1w L_8sBx"EiBFVb|J&ڝJ-*"$BZ$ɇ@dJZ:uKPNZ\~nK'g &LfMn C k$*=^vGd}&ᩭ͙o BZ'(bn8 ŌX?Ѕi|g%˯r_;AKr*VWu5U$K2} I_gW] _dbn iݦŋGVmߪ m=AۣI$_ّ*U4U|V~V`VDxFwFa5]ZsTrg;>='>7>}x_|53J(7D.QpĠpPqQ k[ފ[oa[fR> _+N*M1N46V2dT݌Iy!=6jt 3l]%^(yX*3$СU3Tx»VrV&s|UW&g:em7b0lr YqSW|V 6!7J5%|n)0-u[Öͺa5y[s2yL=PѩEEϺt+#Ge9([M\u@:}'ū;[+Kf;;ߛڇه|C-sχN{1ǹ/.Yׅ? *7,d$>X8b0kCؤ=\ߗ~Ζr lNG$@(F֌GKFǰhe8 :k-v(< bl^D9ź50=GmE?iuڑ"xZu`j?b ԣہ_ZKЁ]I;K%@cet~l_2:r`C?;f( 8 "BF7=|'ŧNO>%>}2Y~z2H7|~VR29a&-{KFN1 /LT(ZDSZNu`_XȄ0KzVi S~iRLX 3C>Eց}@s`}:_ l&,G8et2^p`ifg!kiV  bZȼLuA//gwG$|V17ŀSjT¤W$_̭%[_\ .J&b\痾1)dʤMQ8ppW88,-Z)-GzkƱܶ$5x[;0c*#NZ-P@w'*IЬ@\ht@k'6 bl8|^}7jŇwQ(?p0uDڍI+[܁vR B&$K2Q7R -}xg\U՞ yK񁃛>pp0\ PO7H7bk ;pL%P%:pL8hǷIKG+bVp:pt~­L=,j ?ppXKr ./Dy}x.|1g?H-C$h *h õseقЁGi9ħ>ǧ>A;<1\IZU柒TjPiaOϐoفg2-;p,I$V2d{s2=>IjacGV_fB^I^ Z5Kx/>wY(_FIMQn|DW1IQt_{ȍ^/S4 -)X#|of8[em{oeȌ9E6^}.#Hgp;pňfɗx}/=CW8}W,M_c˛u[=7d2/alЦQZ2Loipۖ|gq;Rߍ ǖ'i}>c]CCM֮7DV^c6^Z{O"c I-f?B'M~*_0)_2t~b} ZoV2z 47Y"N^GFrq?I>N9R@K|#B2_u4{3a)l1 Y'ɘeĿ*`qqg֬ 9JFcp\钅#wemX5-WٳYwıZUuCˑΔݚ7 [0PG0 tuM {j6_r[EPI`79@ӠKe7fk g`smx?ϴߊ+lVbocnXMgÚ54Jeiў[kVee. %@ 1Y/M\T72"/pS//O7GN8p -?]Fu$PIs7M93yd>Ǡ۰ )+׬^bڅ^,2|`ݽo{``XSDKrļX$$TcGnN>6RNG5iioSErk%;A m&IZjd\m,C ~KOXX`: +>jQ5^0ZJ w%As {%wbБ$obб%]{ĠtUőB4>S\C`ٙi%=PxdDsG%?iڻ`YA{\btAGtɉAǞtS{ZbOO:g$-{fbt9I{5ܤ#K 9c/H I!׽()%1̄3&Ϳi߲1+Zq=o}fȿ"29֪^gPxu_ô~P ;AW/^w똁b+x}?7DvYEWo3CM}f( oapv6o <6V~wW )<>G^>}n<`,>UD(5hsǙu2Lo}mobڟb!Oi^3ll?b_P97~;t1؍3 e`&wMX4;/s@`}:'5#&ovB(P-6]vobȪ[.I_0 pSwo[ftbP;u N~iF~iXD~iB:KСc~N#ZkM_aaܣ C\Xm!0lV#"!SI3LE\2 f9$ZKRSxI11[|Ÿ|עbœKK M cdݚ[Y3,WX/T- #86>=\|zQ t@lm;~0< F2>A[h,-N sX9)69rlrAPuV:MV 4c, ?FNaK .IpbߠQP","lFx:(a畍Z(vN%;]$!uexrlvph%Eb,42ծ@XzAjq34b]|z~}L 7;h "XEf +̐(3R2+{7IZT-wM=[͖ݶ@~lײz6|c8wBr ڇmPAS\ͅ`:.&nvvG#R: 9TPؽ&0 &,z-oj]́(lTaqsߨ t<8<%`j٭)FKb![i\)nb<(ٵ\'xFžF0ؤѠjF\ UC<3YW A5p]a; %JgYHfŒ^U֚N&7<"ly?oPl_\C՜M(y8\~z=&ogaE郌{0SqZ.%Ziyf:ˆ9ʖ&V!ܑs}]eVkjy"6;KT,xWaJx.8hAEFvnY梣e^$/Vzu<_"KW0 حC1-@ L4|@#N4z@cM~ _;r=G ihzCl_|(W0ƨnU0ѼbRsz*}T {m (2SS>6}Z?JG31Qx,Cؾ5LR]8ա´]|(pÕn޶cRӃ}w^7>-u)Czk4 LĚ r{ E4f^Tsl`@С[͖]lSC@'/X`T?|_6r8s(wYu 夼 >ו޹onDIX[HABpP _SQ Bod+lh0}iZ57gm0aC~}a(7TNFg/P-ƩUu9l_БëĻ[ƕ)ʳauv5G/WT4ɂڨqb`ԭvLi$la,, c8:UB.I6 ƨ<,)XwFpX[Ũ_EUQQɰp)$VpjF Մ+IycQѨ_QT`YE=CbCLTXUc=*#ݐ SYQc7v7d26 zxN,pYEbJ|m+\ؼezxO5Ӄ1l rNvO;S|/KN{\BsOl "Z)uLvYV$i8Oc∮+Og ."\0Kٶ}l8f#UanQ,@ÖRW#h℠3) E߭f^mɊ{Nc/8G|%9ډ5,3\JV *o2  @򳠗lWη3A,myxn-U 7[JvzEf8knc!n'H)Rn}XGBrP@ @n[5h'Xv_ֺp.LHژycqj;};Y-Vt[Z&ED2CnTA,uG@$e qY !cno}$m3-f Cb3C19#Uk zL75llpcǷOL"sn3_v'-ZFh!wIk$ =0˩fNbt˜3 pݍ>i-W z3($B[N3[uz~j =d&J#ueSd uyUi"ul2,Am$L .Zڻ߄׻0bߜ(D߿F늁?1rv&@f b$5}\k :݆sAp@ uf0ښuwbhgFɪYmb []mMpuP/P}[qhb_'@,`U </T0vp ECE Ebt%Fy(w<6J?HQaҏn`~pj刟刟GH޿62+ IFzNmPB2ɬdFC.?s5EE+uh+Y(6$!z.oR}e$`keWGtZZz\~ An9¦8/ ~J6J3ZVkSSM}ay)Mԁp>P$Vt@F \A TKAuLex姧ԏpBf0sb{tw˴weYLN,L( /4~e-.BrY~`S"|weKK21`4 q-G˂/T2i>!!<ƃ}bD[:C  dSfқ.hыݿ[~SH;y][F FCv"FR]v|Mֆ vW͋̔3ٔyzj~:@f嫮t3C0U7mvS o+3ƥ<Я#z:2 ̊ Cl s_5 :uRsvx?.4"y(^,3AT.X ^;2ԁe ԃG-SoΤ2ց8ZCt1gVIsZJK a4!v xNǰvizB,]]-~T*59!0C4baC͐cc'(&'~P戸1 M:`IXbMJҨOPC 'SC)jM=tŕ;S1NpH j: @ڦb;}I`֩`;%`4nҏ%6f)7ƢQ®cI$a=Ft_܎ Wb2mʬAdQl3ߢ#(*5Dq@[}*V-XFe{̱ܽ 1G,/4nS]Bx8;P\#*6wrh t=K(N⠠e :r[7p( f%fs2mPh@ ]ֻ?GбoP'ت<9 ڕ$;/I:GQB3zMD{lP$TG8Ih8ݩ S N׍~X˅ B-UE4z%m(_$oL:],2S7F5"6wВf˧1*MwQR-m띟oC^F+ys)xL$c$)@ ?.2k-aT;5F^ae \j5R5 X7HiXV1G%K\6L1LMAkSߍQȆ  (@'>&ȋf&[ӝnҢ]|gM {9 GԩնT25z '4f:,5kw+Hn;EYݶ|옎x,7dӒ[x@\xcNgVu4"rw3yapv /k[ѳk7fDnR{~m~ӤD |/scN #[IT h,UY@,#jE&*FAq46`Q`p#zÍV^ mn- gYxE< Y,غXD`x 'Sko  ӁlN P/ bPì"vi{E0H!TͰ |F,[YC~ ]F Ht\}U45m &n}[ Ǽvei\v\^<3YxBEaoG,mJBMm3JGs>ԘAޘ۱ZJ;#H3}B.a leMoG`GuDy {K85Tݼ]N\) ?cM*YTx#4+$eejugCMg;FmbNM/zםhZ;/&R31:%A"%r&Ƣ-Ao`FmvG3yKo;߼pTbYgWa\vǝ;n[hcn!o:SÃ:w.-vCvL(20b.eZ =3I0P2xZt9fvFtmxwۂ-4yO<?4"Es+?`Ʌ~0tn'rx W U03ܝf^}7\v ^;;NGNH`'\ǽm5\:ek3F6vw.eVЉ>w9ewd˪>94YT Exbs75ovlvcZw?4c?5fO֘Ecl(aq&X@CM"b^&&0-|֬;qK O#OtBLw&; .~HGA>xΙz굄k"& <!\dr(74Zyu.WkM:2EY1db:(Ӱ$fb^!T-YRɕkڂ뭻}ǁeRw[O wRɥaYq!qE0n dDBݽtE;iÌt&::¬ކfC& lA˄.ob4p|^!$!ـoSC7|47-"b>l١{ AWs_'7dF 'Ue6y=.BJ4}m=F Olb'?5#؈ )ٵ9GMχB.я,|WQH}wҜ^Z4E:NUܞR2 NEl[fæ0 K,*݄@ VG(Q߰۵-OF[};L\RxǍqG@x'5aƑ.ؚ=62$-GeAg?y޾Ǝ;%g؈.{IA[!J }ڹ ԖaN@uXjd﷎B,3GBu҆Xfh(dM@S:zg]l 쫻7 4Qߐ $c#Xo/}#a 'NChZ / u7};t/#€y3؎daCc1=H ]euy{R{qvhK8zP[ڒ-l24G=͉# #<^IGE^lmZ wծ}د.նYd]8u |%Knl\7.I+qy >ʝ(+2}0MLfqM@bREm]&MLܻgbr|rk|ώkwlLodt :FVX8-!ߚ3u5Kt 7_S)+V!>1Ob X#Wʆob!]|'<2z搟P!rZroNqj`25ԇb;܏e?dX߈ "(%ך5=3o@[wP#T-)ǷDH|KN,y(MlV4TǝO)GlƽP֟0HA/[F^lݭwO7NzFٲo߽!{WzFs tAWEfds]keFӻƜ~e\&6}Փk;n[jV3^*5ӍNzU-#-ՠ bw|̀2qv5nN ?EAS'2D8YπŚ9Q5gx \θ mY%黛q#cB+Hk] Պor;3ܟl5g:أ5 ]4mΨv|(wy Dz kw[ Vqgl;wH Xhw2 zB TAaI~4^\of;9#=:ݭi{Q1qZ۠uhN-UwCY2#r|ѝ - >/m7m6z4nVjf>h,WYm00l j: =C}uw@صNP" `IS;\$^;.^gĎ:a5jXrNRk۵61V݄LAz Kl4l YdI`@D:NU¶[oŐJ[@gؐ4y쎗:^-]830ӁL:m9hjгP,̵4tΘ5hx܂KR f ]FS!Mm̷׌Yg9[ @5Lkd܀1~c1&֟``N*4 q\f.>2:#a_6J.tp"abd3n Hn ݤopvFuJ&] q.ܭ@T~iy};qxLc%OnjȿwƢh4]$l.@ְ iT)4pY4`9䦟޼Um*5̠@i%e'l"%J4`́4 tJCـdB4fvK ZGrZ*yE0l:(uZ@ v֯yh.9oT4Ǻ5bW|ˁ5;u{rX$)WmT6,XWX0 Dŋ=^6qy$߲ (㎭DD8 YyMD 8]3dE#Zjz\^{ϝ ,lz W4GOa6< XeW oQAd(E*ɈuI-  1)E'A;o4M<-3' _u8(qiG,l43GM8kfΆ8VITVl>L~@rKo1[@Hޒ{0mP ޥ2r8w1}9Dj1,lg>ENi8;M$"A/Q`{Dv$ -$PBn&NN˞;4pCrV$( 0ua*cDžD. _c)8CqiO;Vف1Qvޣ.VO(=X+*%io6M,b1b'y4:a؀lAozO6G.ZqbQ!$}jqIH@Al i1Hn'AMpl,P`9Vp$DBq1< !mi Pi`CZ)G?>"nX$ EDP3-&4Iߵt/@`r3J^ic; f ("A{?Ir4NHŐ7t B@= eC5A x|-bo d+/!տZɓ}gIK>3ʅ髀ɕE:SfDj5)nBn ͠r3@*VYX[h+\`͊*8tCR H˙6h#3l@naHA^ta,{4z9F;,=A`_k^M,]ژ>Q2i]TfΚ̓E +xԶѫlo%b]pG,:5sxI18(bV딁@!)Tm h)kga (R89v`*3h6*)IJ %Ģh'ӆ٦pto1l" ~@^p4#wq9n\@/#M4L4t,ZJA;!M a7#`lz=jXlFvܓt[I2BgAݞF(d:JX}=-,jΦIs0L7QG@ j)@"E55#|`Cqf aҽxzM4]t ڎ+EٔdMhtD\u$A8'X MVƃWפJʸ+L>pnj(^AJFȏr_$@K- l ᒌ %M֐:v.7yaz򽖽XOC}[Z2@ lN`E޴i1eQvb-#L,QC@EI5jljA6:mbiM  !( &>8Nu2Dq)i iؽ9EZРbkP'͋ĺ@d` hWvi@7c\fZ0k:1CF ;O}hN7ouCTXuW ^@-T8颵(EαebB{~ U0$rǝVn4p Eb*ľ.LK`XPAH28HP° P~BneźNH#E[iAR OAͬí=KjKZl 0·*FQ d8M6"`nʺ@.,:Iv9mQr؃"9j6`lK<'IF /P+~EL+_i+Va&6a!QXһwMRdi,f.!^6tY($BM9L=j`!0'$z&tnI62Md5-%Mmܻ<--t8:a\*@XS4Q ka{K|!\hm/qFc㚛Q]fDjb\cVR*EL#)SRz%\0$h$Sp5UDPpJ.4 @DV31양J=,vO*yf;ב0p0KU- gnHѲfQd,aBsd#س }EG*6Y'xG`Qmw hG&ȹt+JBΠTijvquM{?l"äDẾǘee!le1ֵEE%e*XA&N'Mr`Pj"2"&0q/[kf-~gP]yF5ll;u R݂tH*!@Cz%g I+6 tBOy5()ơ}HtoT[J#^S jbƬHiI'vC0)d`.:BtCP3QhC"~W n3S TN.9Ntr36Q2,6NK⵨OĒ"Tn\qt'΀fn$v@0ieV?;h3t}-atEW.{rp-4!fˑmչYe[ɥMHPΣbf.5 JQVp]CY~R d0 Ng0OtpU{o+ Ơ9ê atq>$ttp^%`ƺb:6l qm{OR&Z(+ڹۚoF-6va'lx֛.XcLE۶B`2q-PWuleQ4n_]--\x\),a6;o3ٹU`/ŀt ܼ(K"T vi3,7jHdys{:`obt<;kDۅ^۔N: wA]([҅(=`Eluٗȵ&s^lnVH#d)oN!}Djp(ټشI4FzОT_ɼ/  >.ȼ"n13(Q-[Eì3,=;'1R aST!IZa. -;$yk@vk7ňW26YB !^Fuȹy-RԎU娦y1i[!kkIpOMr'ɧ/U9&< T&,CP%MTq A^]0: ܪ&ë 7u-<#l1>mŝ{ܳsFr2طc+~\ݷݷwbgdWM ]pwzZ35ppP^5k2C*,h(#g\NŒon0:]ҁk6m*!>nj 7HM+3* gjt2AWc#qcJÖ14ݸ5tn Sx$%u[Ozu,$͋3[a`ywj(1MZ`M͙W'nȜD?N JI,,1Ry4ɮhw.Eҏ\kNktIA6/6/UaSs4MG8 uO*1 E(G8Ҵ{!)> ˮLDp]Uvn^,fM@uhW"ЮX(^[_\C Vrtghp(xfrہ(vaw}amo4dshXEW$ 2=zb_oŮK/oƅ͐#߃LGnWl. s.hJHIwiK9(T!:]=!aW;}\GSl5f1S5P(:Pg 49ywng]yohȵ`D@Vk7 \[cy+It#:`+'xtLiG 7S b+rFhh9Az6KބZ]U :tzɝjLc6QEްHL" -+4]طQ_ȱG{uwF<4NΗq/cUJŦ(' g$sQ<7]gK]mͅ18jנRdWgvـ)2:T=_sXoU-2+Tv迠eq@;hn| d4 s@{RA@/e(aHЀ;nuY,nEٱ@g,MFiLMZF7{雖 5-lP`(߳^_'̓ILɰ^kq܁iĕ.c)~[OCzFzB3$c_R' "eR+OpLSh [i? Zt2EN<p{ʹlԡt#<WdRJ5J)ƈP:Wũ j-R >cWћ6Z:wA w5y&7Ԥ#0't{~KbxI鱗O);ki/h"e"_͈\ր C5P=XYՈm3*F#`d{fbBr a/hPMF4 VHŘ]48ka`R7tm&ooYzxn,#к1m=vڇ!#1)d@x_ЕF=g[?`.N7fr Ѣuadal09al S"[Q&(Fm{I̐Z nRwj{}ornD)(^C!Q5%C^^/pğwػ]DX.@wÀl͹uwܴ862+ -FxS)^.ӎ+^P|G4 mu!k^QqnAC=!T^闾o8b\QUq m>[~ W%6TMQ,f,m3TW a Ks,|/RwKmnQ0c\l.jO‚¸V>k?i_P!.zU+gAׁ%9uXHjvi F[C]‘%2eOQA G4 AG7bA^Rr cztDŽTZ ZkUcH0( a6`RTCsNE!\tDHIB^D& b1HVU/Fcˁ#A\ranHD>W_4 E3҅@4>'tKIGN(e@]!O8WQԗ&),!-;+",l!"ƮaER:O ᴓdY %(={_Jz+9k ~yx{(;L'q(#Zp`@pooCG䥱JY R)h%|/F (4KC !ybt#8u yW϶&ֈlҜ =WgFxL٩{Hk6՜k*Qk` Œ] &:z"茋!,p([AJ 5r sF *IqGw K6R%@( Kh QwH!EK\"3u[f:UScZD𭼼Ѕy^QǩwЮݑEmoIկH!n},>1܂ft(XĖ;iשHm{ >Sz+.?fOw%=_KJ1X 2Vb[k; Ƶ%]++ٞ./V C31(l#ח6o, -i]By٧F_x=>,9D\4rKLH k ]*96]Za=[[:Qz {D A"K" *?TpG\ͱRx9Q dЂ;6ӬBVӍq`[c)3/ch)Yi^o[tH)>gmX%FeH[;"tz Hi32a=mM Rgxۍr@8$>hհs0骼[|E0vV}*7"WDrj J wju{XtRe;`ӽxiNFԲ FbqFjyYܭ]aEVJ%.B(dWFʠe@xʞ@u1Z#f퓁vnwT. P~scUYy԰5쎺zM 5dǷ6`ڀ0-xdnGe v=ī~xjoz3q0ҽNs4 gժ{}Y&U&QjWelX([V{@\CdžYd\hV"pt_ېҠbfsPX3mRƹnnrF^|OG䩁o jZ*Y NWn^=R y>ȗHlV*mkwG S3Z0b#]p-jڼgRM$壢oA ^w/Վ qEz~ AUe+!вya&!\Xir(Xk*xޠmR&5g))NM @NXHwkrO!Q 76T/61i& Yo)A uaW"jvma#@`Vo)`^)##X"TcMm9S>i6á Jua&S6 b􌧱Ei˽Q~?~"%Rbf MmmۮAʉPyP!՝i\/ *%7 sC SYE;jihbQkIi&P?`\&KPJ4c^0̣ @e@S^xM/Qz@9OSTҠtżoɄ͘5^E⵼6瀭*&cϛ25VEӨm6T E&Vmx (.oLq)PӂYNטJVK9:*te+=)RR,s'ձ=ZL0(a3wJ ҈V>IxࠕʳNjG>W._AiW1;@K1!qNh (@hU %,(O`U$r7b8ݘ=JTU>nUgH-V)g,Th)cÈctp-h<" K~M!9Q㊓ HJs +^~E~EN!,`WQvRHhHvƩds(CΤ })MI$UzDkRfƔȘ S``L@ˆ{DvoXg,o9K6%PB꿫9.lb[яiiJ>'S64Y9^-%ϔQӒ  )4Z;;ЮQf*&Jy¢L7=|+)1ΤA>EoO1' )nO)`dH >fXvi 2 ,7V8Ve<y\W<;Q^bb̈\(I KnjˎOoNHgb$ߑX)לpo̟aj%uX eY%ݠ([$PAq/aJm ga O̎.a=Y91 4R&1@GyQ@,p?Ύ%l"Z%\Y-N.-UvEL>S`n}2$jd6Nw3E4-+VH3)cX!"e[ wɠp31nDx%N&x"5\ "jb=`U&^ 9 MtEͶz[3 F%)Qk Z6iˇAO ^TbRHڸ᣽FZ+]6LH.$:a6b<"ނ P .OHG)Ȕ!)F6EChmV^,LX+]LnP+;t#7d> w{E~ &Bt)|qbX[Bܵfڇ;v(ZYQmF;( wZ5W;ǁh|$qtQ_| *?0YQ_~MW /p"DВM7K&^#+ ] TBpkF⒄,Hҟs6=fdp%^^9|yyM+vAeI#avIϿ ‖ŭf};ħQ/)ϗ$Q e=[2(Zy'u{#UoXT+2n: 1Dr(/)%0z _U/f OrZqF&|p> s7/M Է08vDҾe3#=GUndFծjwĞd5UWۈƷ.IhWYfӤy2iq{N9̘2y$(A$Z$5KQncw̻‖r]v$NOPokbۤRCs‘1ch#%RڝHMIs'hÿoQ<Ջ8NG{iӋft{6㽡Nef5x2}1тG0#0Jr] ]Ӷ+U#l0`3[_<.Ufh`r4J5-7TE{˼;Y3~4xF |:-|3JَhW"Cլb1x>"O&V@0"PБzi74]B$@!ب J8_.AC+Xig:YiU=pJ`+l.v%"91 m.S\r˂Ee}o(;6?6G1<'F,ׄKfRNȦSHcbv#ؙsPPfasSHF^P`'7JɭL9y:>ZF]g+9 `P]U`*xݠF Ϧ8۔n-_wvh٭&}Uiw%hْAתhUYײy"g z\aLZؚhŝq Z٪}* rRT5`eh:~ٕ[kZفH K`|ͺ[?DR? zAe w9Yzsf,7.Cہ8bۘi%y;;&~P1? DUX:Va o㓃 JY0|e_N> QkcL"0T85FfhKHA>,PWv @܆-yB@m@x cm&5m8WK6qeNkνEP{qd01]w1 1,X$@pif3ӳ$N`wer-[,Ke%K$۲-I`AI>+_UuuWUWuWO]$f{^zի QuLETHL1|;;`27k k8G82T9G-{U| W 3"] ^{=E85\:r ί_#v!|P4V:zP}ǣiiZҙnB>ԌM`zM|V Zk]OA`Ӻ}:ݱ5J-^pN1㨋mZe<@`ŒǥNã۽lpAljhJ®a!2;@"~]W\c#^óxj6H$ oKwI" 3ZBG|3Owh?hp-a̺WS&&|k@kL#uru7/KiYv[IJbAAiZn {DY0Sg3h ̰i)af@9ۘY ML13 VI|يH8(xBu(YGo+IKW!lV ʍ/1CbWW%Wp&sT+=/ vJn7Y =Z\NҬiI|me|"TV|QIb[#lʂ D_`}oF(Lh%@ԗiV 7'%l yS̐mmcؔeߒ9, PD|M0mm#6ON3K{22K`-5%2Zɗ`6mYoYj\7c^]l؏Hž*[[KXI);ZĴ1}vqoT1V@J K`jɇ0; '~*no/eD3uVcPu`h)0֢E3cܛrcuw$rQI6sd5ϔqL7 89i\gLLd5ʼnmf(92 iȠP!;.X\nN_Н, ^dz0ޟe)Σ=DUNa[V!6b >if*%BYnNȳ[*9ӀC'L~ɤ>?YK'uqx44}U tVIхyjo?h؀ t&"hDBȸ-.B 6u8*EƲ'Af#l 蕱}:\Mtƌ &B9YA ! UIO.S$L*؈ 'f{P7BDX#IwIxvx'vZGm`^%͒HdC8\cLB1ેCye3 Ć* dcT]#Qͮy.|UACD gB | )l~G=QoA=װQ~< L+zgoB2\pN@V gn7`/`Ht#Ź FsƤ7&M%=;0SB^GB]7O$H4ÑOvK5qcn"nW66m垀dP%a+M[,mty˲6!SjԆGǧ&&B}udD;&zwVe DkUN%7LV_fa첕- ڳtd.U<% ?R,'BMRz`zJd MM- S-*ǥ_I.yF#̙ح6 Mڧ܁܍ 5PZbUbtYk_>"?///GUzH *,+]SC?%ѪRx0ixrdt}3e!-S%PH# $]jURUS$U2hBNWqf/jߝHn*VLD]T[҇!,`P~_mq/jȕ$uf0)m,ŴBdn͜t28Id#a+1At ΀ t|(:;ewq.4]a9H2Ni.1T2ho9L{\FbfZ?`WkYe!CUDɈN%YMS"lASUBiC@a yI5TYۡқ2hiNHO&870:;2>lQ#=I"ԵVe߁0FZ0_ɷŒ$@s{DbXLk&}g{z3I(ړ0ß CCU6$s{T ">{=}sI޼DڡLq*^r#;ܩyMXRHJN:sA&qr͸yĪ loJe !̂l578-h v:QdʸTN&o|>^7e!O^#,~9UZ]N0hv!*ի=uQ8 :H:C&JbmOygpwL7+YT2 Ÿ }U{T-+[o)t!ɜ"dVZ݅U t%U{on"D\Ot U0GՅ:6 "F]e1us$&,(kJcVjDljCYLEbpocۧ%ͲO 1H`; KoT Va^B޶VhȰ}APاfz vH=zdtkr^-gl4/"I׮ls MWCJ<"n5N"VxmΎYe6C4:/zc1鍽^cb)1ѿE 8cK1M:n٭N )ChiRW5M#Oe&G"U9#Qʧ`oiBe\i6Ĝv˚%5RC2rC/ؽa;ǫ ,6<ڽii7w۱i廕Wk+L8OVIȕm#׸AE.jDV'Ѳ-lSM$`LGeBk4;9}hhI0va!AY+K(6KȖBBs\h"Ac0ɔp\V; O 8t1I \ O/cC04cZlzxfo8*\SN7JUs3%S!y0\LiZ֖&ɐL'&dۉN̈́hV q̕:5 Nb#=XMrK)>Jth+I`]m@5#®쾰P(AkߤQ#Hɲe

ҍUK#6j}x iɍNZ[e7-V4ϥQϥ؆nڭ^-z6&iCMBѱc mܦtvÔ{h6U gyjP R6ИSX_,nxʅ; ^;%I6blX{/(S""g-\K,+Ԣdd$1vtm6&<]M]b 2 fZ&qB/ha?m[U3 aYIdA &eC8;b|=#R xuxf:H?$>9cz.SsS`]_zŪnt7ҒmB|fg I锑02<}s Qu]@.?qw9XrQԨPS)0nsr# p>o2C~yB"La1fSc6ICtutίs"xOmZgȐ:m _czh[r?urĺ4G,鲁':*.Pcp%80=zn~"Kb~lv!˴X4Nҧ0]_em(?/o&Z 2Nn L) 4^ e~yY(yĹ>/E ϐM }kZxWxڬՉzm4909@ERxIԟ\BLX˕["͔gf;8$={nM5^*H9L_g%ulkuT8er٦L!{sMa˽'̷ضk2IՇ6MpI|x xyT=R9ȠC ]a)_r^`_I0,< CZ Nq0<2)4StQV)WGF> _go!L5\ ˋ^Gmw( Uͪns*xUљ^ X=ʵ6v'z+ Gp<8񇏙(sm2aLȮ`9pu[ rNm+29pgA\LHI?p @ьbW^NNQ7'L~no-v[k2T"m5eql=n//8P86UP C*10m$ 'U#ay~J_mL5T5yK{Hp"}@%CY\rA.fJdk0'߄Ҭ )o)#pyYN;TCrdp寕!#Zv\>GrI͜IŤPЏnqWau(g̘C |ö{`.GC59 neʐy VM&DTGGS)˖2u"L|B{Ҭѽ7.x&AvLB#Bs}_3E[;lvHOuCsl_4U:t8;i8B򻯕bwDb"^,V{BMf$V8bo)nJ8lQ%^ߗ\'аȁρQJ:GmjkP/x}yp1[aI˳|e~d k8.L8 /03U(=S+/XuzUʼnx|J^nO%DVdB!maR^۽P(")0\XTW\R$#<9>㿝Q ѠNN'Ԣ% 52qBsY6Hɒsb7g2YdJbbyL\3O~hMvә !p.>XMz0$*Mc>h_dk%3ګ: gq6r c%HKZ ,E\d'" SLoF)%a]LY'Gg']K `sBi3>?/0U>1r`oi"?0iPɡJJD-ppsdԬr 4@pĊ+tmuݢ *w)n5/M}@%(jomǼ; Nm|0]6qZ:*$Jl'T"OQw` 30,s 1<-M;A4[͍F4"٘m&rn^YS. :KNyO7 [50"KtZ nDTXp09H8@߲dtTlV[D?͠74w,,ۦޑBWqwH.l4]turB2_Nu"< b]:]]ٻ8qc\zDqt+!吺F߯_&Dz,[QΖjWثJ+RN\}/7pM|ffU}omF#@,j|7DNr5xJGN?UBٌJr]rG-%g %E*SHTgKK,OrDfpoHGϽQX$;2"$D r2Lw|WqD)ܚ<BH#-Ng>0%bh),xNɭ+l䳲&v D .Q@:FSL58M4ل߂t4jKo>R;j/c+Qa99&=13CetLcr(Jń:fcb܆ Sa cu)W[ZgxAxgs8xw|=4#sF>V՛q G7xYNa&94IwR=͖Y].fw*9YzL9_u~m ܧ&A@U#Gsn{xwzv׎Ia#/w˂3:p$qaP&Ekrp_ªs1O( ``nLzcTkVĸ5gbѶ%l!eowjEk625˘ioK̐ SnL j6xcxlVfOE |t f.d#H~O߷cLc 1 lecj.d̝}[˒{3.}z'88S=7Y8F rbQjK[p n74jݢ_vL]XK{ / vіAok IK" Er}yI"N'pj86NQ(]!w/D+t(Z:,!\Bpf` %y ;%qq9-4 ـŮ}K& ON Ī qUɖ^VׅT/D'_̛B3l,AlU v[%G(WnODٜ2VbLz [ ",lC^"Knɲ}' u1?ݹӦ:a !(n[mO nw<6i,/Dמ ln|;S) ANDSxs|J)%җyPж1o1  i'Ji[%>6/#5$v?qX*ޕ_H>.XG@q,ټ,ZJqT۹54˺xy.!!YeD6IfYskٺT;rs4XDžg[R^۽D8zx˝*^?gn6T'<HZȫ ߣRa7^biEnW(8UVwYo)Bm]M6!yHYj/vn, ~QH#.U CăxBXYJ QN7[X=MP!%i< H ("OHLMiY ҚPJRKGr w5C8{7Q*#QCRWH9^ ޭvcBO*Er4,m}qtD2rgw?8 ܒŭB8 ]d3 ,fʉ*S;kH}./9Yhװ7}[' F ug6[P#^@ԅp)epf|*[^ V.ᣂ?ȱ6etel>V6)N8oT/[I2$s`'F~*Qcb,/*.vKR]ߴCu@bf29{Q7?M&;^oSW=IZlx cA(')D5^>=r\I.7!\)nS5?`o -=::eՒUx{E0B0u~V'eaf]ؠ* ȨԅF 2&lRSF{eoxc1v{*uenR1pN|j*@&I34"//--;?] ꘠=r^N $SZ7d.Sdzis׬Tc}LuEo_wR?q xmO㑌h`֦CsIFYR')~q<qs˾i0idC燼6 6͟K2QOrO*,%K~v(^$Tͩ5k$*wywqS4 s8C\ٻH $c3b}E)461IuZuuxfG{eæcR# xU{VHhaN(z4isҵb= D{BI(A(*Fu@qjd<95+CQcxu`ʄ3FZ*i2ҨP2E>Pn{a>O; ~hb}jh٢ɝtA~i8d!{ |:<F`?00g*~T ɤ+Ġ~ht;Ty 8^8 Xw.itlA{)ot/Qț:Whᘜ e9DRJ``/qگ(c!Df) 3i)ЯIl4omUGi3(\/\GcdxĔd#CbJnpdQkoFrxw937ܯ՞WQ< 03 N:7?bAPjU6$yr,}سFuس[J8LĀ|V:y1ɐ~rZ=7BM cPqENn}Լ<&(peW~+{o̟iJ;nEjwO, IJUBA`vec\543fV &{2ѶG|[blMir)i lp0 rt09)㙲3 ?Rr$C:ٴ\WMlBH\4acvW\NcF2`AFoUDf4٭ĵW''*-UAf"ΒEEow~(43@k簋,9 2`t4?3HK!Ie@x I f R2 ǥ;3,ϛŦm1_s̃exIYLs4G:#0}D8:e~v`2xI]{nʹŕ4|K;oۗEçP{yՖMhDPWr K8rj>?ѿ09Npت|Ԅ bO5  2\Q/p=X tEPM&iy;ڜSIм2#1 s\}x1Ti1Ď #~T uD_O10OWӖ~8nLQ]Tt<Ԏ&R"p WY\ AÆbAC*8#HNM6SgKu*_)[ug+lE-W.BHS>Ò~+^d dHWFG_ȡ o7QnV^9*?qF)(ljlqy K3i”b:D*QRB3HA% )1Uwvh8"{!pׄȎ8 &7\hx]ϣ , %,ӄJD,U՘:+4q~>Q2fEoݤ#7ň9WhǞ%ʉFMO&8gc3 rs 6␩!}6@(ÂG-ɓ`yhKr䗍m v9o'R(va$N jHFCuLFQ< Cg.୰I|5 r N R8RK`ÐjNCw,?/Moz_ѵo `=zv `Gr2֘qE k8?gw`X S y3|E!iKRU"OΧAffzwɆQp(`c1M=C%;&Jrg Rt?Jח`#봤|jZOx*ApZwD|Sâfڿ ?TH&cI㻐QJLu1Sc F'&}zdd2[QqmYUA%~3t(lґͨ-7nbx䔽:$<"(¹.Z1ʹwz=UҼ־\1AMBWj1D0 @K>#[ 9 4Z(\?QVs1+,Hg iS,b+׍w"֍ K2Wq|RP4L!omjܚMH[3F%.ﹶ!EF֪k޴3C/~Y]ņ("4̞R_PXJS]5颊cȽ ]847 ] Bt4>S}c{ ]HtԽ7݀edj8VA60{dN}KvnY^JnmSM?7$4q a %,q7ap;;uv8*"D=T;n+L:ܲF:cGد!ӛgJᄰ`_m"{o[wwWQ4.~T@ X Qh=k:i꾊p]i5wRSU r^2j:8Er|uE>٢a0k]$PB|0hN-Uwgy1j' "%!p#Zڵs4~=&3wo֬G\3 \dzh*vIP+,鴕z0KZA(io`*heng ~~Cu{egj!{j7!m6i1>_$@?)TVDr[H@Qܼ*"g=x4AayZ6WNgCF$O^,_˜c5N`=S/ 'Ӡ3)%/=ucpƏ0u+}sWZ:r4ugù0q4@ClŞ®'QkqDm8Bc_Hf E.+w,W|v"e0~$pʝ'P{<2^bX|,&ncr. NU!Im3R ,(eݬ1*noDRSI$)PYc2i%"5xf@a^b%c@n j2 [cIq!νfHztžbB!1xzSp#Ҋ6[~+ڛg+pfš0oZ8iz rЯR oT.KGU1#5*5oaLyķ; =bL㋊PQ[f y2ZeXBf_S&| ݸ*'!mtIC_+I:}oȰM=Av#ߔrK+ufy8eixxLc"ܓMјiԘ4wT&jڗimBcf4?ΥSgJAt2R#٨ћv L1edzQh&/CS MED",l=\h Gӧ&^!IKzD! HIݬv/f,*]Ҋ+,\F c!Xشh"bO4ʩ>-yD$x|n2i=ʜc] >`޼=)T)z\6Q9W[Vu2vAt*"d*ƪ)iFvVSI-?eI}ky=O:izH^C1+e*DӸ{"NxT LeN)ߑV_K(+XJh1!#5msÅ|q{1>0bZR{TCFZ|D|.ƨ%3KoI_7/x}'Xw,` )"5V*6a\XG Gd^sZɧ!0/=Jn? A3ݏ >:öl2{Vmu֜N%Wq$ho3|4x8Za|*isSJE)Bi=y~}Tde |,y`0 'u˲ײĵ4VdiL"h jCrgΛsOLRqεw:OUDT¶b?B,QIXے#K]e<͞{t,ޓ0shbZJ}t_SF< YV7P;Zl]cuZ͖^v]W~ P6 2$;h_iuzx-Iv )(鲼4;Ã`_xHWk_ M!ӶHwhv5z5TlٓrIAG44bM8օejqY6e3nqm:/@u;9*zo6zQꦠ+/ 66 @R&N}uٽO VLj=!a_.>5P0?q$GVz8TAg=JKt/2L :<:X{1]ϖeJ~qC *鱫YU1X{)f@!GԿa"/[GJ#S󫒎 ;]!RU"J%S,׶T$5]&,Mˮ 8p~O3ggO. b.yA)5xp~3\L|8b닷c/9.{Vb"9[F5+#Gk.R¢-@t7Y<*Q`IG&yԗA T?;"!ɾ^?( zi~;W4ga>TPCRf Oi2cU"\ؼ{Xc!C)z}PZY,#SN/J'Heҽ+t/I y@^}QWYS` r6rgOb I ҽq"ݯHE龥UGR ,_}sR`!uFa9&O7 R 9L,2<,۔U+&fx]0um@}N!ˋՙ'h/>F+5g2|^E_D M3*B]:d &7T7y9/\_׋Og2tKXD2jk9fEL Vݞh &knU#PXU1b ~4I):XvN& &K w8Itw; w/y44?]18{ ue,@aNۗg_|LBs-4}vbn/_v%)߭1}l){8S&NÓ5xۍk~dJ"s)p'|ˣ (w*JGw_c+hv'coA64ٱA_|O+W 6}~N-˝ƃɎ2 RiMVsoi]2Y0;A/SčHyI"2i0S̐ӷR'@>;7Sg6݌pZ;BG ϥ/׉iԽWqhŃL` !z9MBl&}` 8&̳xE*+l2 ):eZk+;:-z!}JϊS򬘞PJ&tђLmXCD2=ZNcd 8Rt'![ͯ+MdEX%PCp&r_I\!Ie;З0,2V}S3Cn/M]ob ׅ }*iVEv0Cʂ.Ç33{f-ڏ?+G*{J/ϰgªgyde !!h5)4-8Džg#To(`K٧D` +2vnrqXwE$V&#`8;+3eI6=3ڴ<[ ܧH*Lë6ބd`O kM _6YIA:t[59vJo0G֎hDa110bYonlMwL!üJvSq /cEa"xfi¥;FF|y>k[ T|&^@ZZE#DPF0`:cuQX\[8gM"X[gLjY2A'VsM-ql2ѶT'O;6|J-JLHbK{.Eq8Z InjY|oʠu'[y2cq(6d36(bؾu*ens-D_jXJ쨭9{8[rbAEdnEUA!QuY(4Y] EkmV#Z\19Nayk@Q"\9jSg^v\,mCDPMnkizU#D$H*Tv!k뽊 .A;Zlw3s2cKă'l(aAӚ&Tfڕd(!&ǑogNG{psnv<0Fc8Ow d~1X%U o2{;,8i[gVD1Gz>ta4_*ZQKlxTW(+' qYqLT;wsO8|BY5zc:[M}M؆o~㺆 o0j(+uQJq!XGa;d*?P< i^[BHXP5 AO`PP#ɄL9?صqp8fha.1ۯRNNKBo3\vQH"ncJ2)@mJ*Qܡq\b.Y y޶cTFJb?ڧMJ`I,o(́a\'KsnB#oa==Ua!pRÐ0=bvzĘ%\4[bڋAkj*U?0n^ϫd8xG䑚L>zYJ|vj8^\^*P8gAtK Gof+)"kTWGDߩ^ 0.Bw#U*]9UHӨg&w%͟(vQҝٳxѥTcM>n0nnt@yHZ4@*5w mh qPT*EBx*!TU/o̞C9ƴי[0:,FY?DY;'$ʒ)ǔvSSFi?y&/CR IC1Rq#j̝yR ;7P61l63:U,ĺUq(LL,3"n)y*<&OMg;wG:0 tV7|lp Yu[>rOz 6] }7S 6s,U7PʄhLj^CZwVVrZŞUPc9a9{~-Wq1&V1!6H}aG\txJ ̟hV7 s4i- 07*ײuA]YK {'RX-L)Wj~@Dy}A WKE~ Tw`8$l,<:]hu +b&z1f`=xzsiv++WVg΀sQK.DxRG|N9I¹|Β3ϞĉK1`"-G Wr{<%Fwfst ظN]=ϵ1}t4'5qڱ뀮ݤ]`R^ I/. IQ* K3=g"M~[JAkC)e綇k0V(+g\}:Sǀ@|lzX^vSߝ B(7$ )<F£ReqY)TDl%7%!-£u=畣Px45GWw|~L;e6DX`Ѥ8I).y@cee2`&Ьb0@BD(l2&TaK6fLݫI@ab{j 1T`DK &:Oo@SJ* JBjk:6xG rye$m$n WmDam^OrMI嶤~;'c̳Or{_xPyvZLҠ^N%'݌nnwMc2SIw ~'BoQ()oK w#?[-J)Kj07[oHƠ=/J_(PH11@= %ap+f~#QO5R)QCw!_G|dܛRgY2>&5I~&ɬB&mډG%J;at"1Ct #I5єF 'SW\M k2b̝MQtkhި QR )Ncsgki0nv"6!]4g0UwJn]o;ٸL:Uò(U4`mic6M|U(% Y:lQnɏ6s4[+ti;H1@.MaB-='q& vg2_n [l Vfag;w=E[A EVnG竧@LZ/j4 o ~AӀxx4`sn 4Y,liBߎL+25rK]!8_HSZ4 e6 š)9IOI#̤[ĖĿY;ʐ/FB}41$.r;67_Guka%Kfhfǔ|a _a>^+q(|9RXsE%Ouzۭ( Z޽o! #v Él!=+}Až1Q!@@z g=zͤ ׆3d-X5lNgCA$bGT;y"~1|IMvk8đoaΎ٣~iuY-*O4+99)N_9<GtYu:pR?e;Dw& ԡ2UT1EҎ--w haʘY<:$O͛ʟ 9Z򯕑{ošc<Ɂ :>њ W;#T_EVmc,f̢ɑx@9]RZ̤yР|&%5Mj_goFʔa2oQ$ru?-,[y)݌粵v5^.2izV3Tx o`sj0rpXfBq.3$zz^قKvˤ\P+7$֚izU#<0$ b^5T4A WVjL2\B,yq44uF= !QG)y4m~vnj~sn;aAO.JѰm(LX}-c8,+GLQa^igFtjͫtk% TUfZ| 4\VC5T:zuћ t]kut :_Ǟ: Z7 HB8_rtE+^.'V_q/_ͧ6Ԁ㶂A'N ׮~5wa*6 꽀z貽lN?f˕`d;-9iRݷy%%J^H ' Im YomY:e^JV?C+lj::qx@+tl޳*k836u+. Rh?2B`жz+ i<9.b_NY1aw}VpvwZnXW.5WpWfrՂOX4~o]?2m٪VWpUM5`+2ްޅ5GzbX'wU*^o*V mU\Km^x gůAOIv݊' i1:~iܳi$@b{v;K>]:zܹ3䱳^:;sc?D?Ν9wSpq%t.gΝ}^t^gѩ3]B;~:s걳'ΜD|k_EV.?v$>!y4.'ÿ'Ot .N^|^8u0|scɫAP?|Bō~G~>s8~뵓g/#ΝLϞ9KWϟ.x 4v|szc t 1O@|;qqO3\80GxAP]8|/ 9a>sy Jh ( 1QfVG4u>"3:O|HQ d D>OQ}<2CԞp{>@sP(^<ٓ'gك]<+;M\DqCr\wtrا˴S^]u9eڑQ.Gzuur!!Ar}Jf)t>~rᯤ{QH¾Ѯ= :v+U)'֥gar]8_0]x>.nH>LMrsDqż_a:MF%[=չj' EH\CNlSδVS?bh賋)st3| 6DCot[ɒ|称H ϷHn0//>Nz D K+ziV@=u/4$^./8.^:5|m狞*+sg{8) H'uE,R$D"sx PxM=B6(ڌeQ_\S!I>h@+L˴˴ˤM#}S 7>, ֜m  Sp$<փ"H0NrҩCQ.zivJI,+3OU)yop z ]Q~PeyZ|wsΎP}UJ ?=W֍[YaGvˣ ApE0C .`_5܊+&)Նەٝ˲1Hkqx+}?!UVG$CdTDA<>ip$O4Jm.z]++jjǏvC3z*5j@S عԎ H?pPr;eʭ^7r֛0'ؒ+ ={2; "ڥk@fIkpbj|TZWf6NM"AXxti'm#F)rpQoe|*)bBDi:_$AXN-[/u u\jߙ.qf.)h魛ץfAZ2Lh̎q}$p5a]&nd"p?'߶Àkods,%JP0%o)-á|CAdh;wg3x˞X?DD ?w#?Sjq pJZѶQnTB @YLk?럄br uF^[#g=@zN(˨S6WF?Gw&WJОBzqu7iSz&w$ AIs{gֹ-RV߸Ip츛ʊ?Ip츘$Ў7ۄSc)sઐW_K6M,θz=q_u6aћdʛf tG7 .V`ћz[0rzdM@00?`'L{<^^Dv\~Ͳַ<خin?G,̊\*d:nLg8nj5W:,6!A(h{$TIy1,AgLDPWO$Dʛ @]cmQ[uQyݭvQg`W9V؝=7B04MtWy͊WuiMiem:uNԪЧeSD^~j. \:f,ׂ5׹6u,(N7NUq9Mg+Gqsd$*3n3xBjq5Ն.hmuV)ױG.;F׼4tr^Uspv檭4|53RUt*:W|YkgQju\9^=}NgE0rO*QrUv$FÔy`JY=oq{MӿlTy =M1,^+ i1./NሟDY a3Lrc{jhJ2X'c!},Q+SuQ{eLPDFC"8 ]/9OKh4_?I0opF3[$ 36AK)"rYpK7lnn m͂/vwuVKQm6Hϑ@}2,_G7+-ѷ tLgƸ-u?)ڛ_dF@~I Lă0C0;߄y^s›=lM- NiR7 W݃cK_ tr.q_ ԍ^1!.!;.nu-M#ebovjbHXRmv>[ dqK"^>lc2Ο!KO9&$@ZmMr[f>oIKogǛ!Mh?YnlΊ[ `F$[μsHڽbr0i$r4UF,Z@:g֝\d& swrp (V"mQƤ  ˖3F\NiX̠=DR8h%/RcA$۱JcEq:q "ZD،="QCkf5J!`u6oЧ%ԁgWnRF)N p7[u&`eo{|!vrXJȈ`>z&Wwuۍ@͐AVDE#EGCQWF7%N"ȡ']Au.N5u~G{e:W;%`&a&WUpiH(wBE9CBiB?t~PG3 -i!%PL~aujǘMEH>N`.fZ'˕n.̃P(7BkPwh- `ϸBz$p!@U)؟Lm?*mܹ]iF[ s 7t{PKË<>RFԄ/w0ba/?Hr'Ϗ#' ^O?<)3zySSOC9\?s*xA sЀN _P~5Z:D(Dq VTUج/LNSȦ$9/rHF(56C-5Vl Eo$^-U@|Xuuw uoΐld3L@[Mj(4pf:k 0mEeph@6}F[F bPo` o,-^RM_z=ȿJPPB yu1]`8/..*дvzu[X8-D@cx}!+ngd4 o@s"laC?/U"鼂߈&S(9o|ڢߤ .Â9|MJ }&VPWQ 'ݫ$\&<%bPYiEdr6({c"n1*Ш,.8٪,[U>sߚ'ȚWI*>@Oߐ V&_v;{B>3rcBS!;vc`="e9tM]B󟄭m"1бT.ITuV)`HB߷hPF#ӂ*|Y87?8ƍ7??:)OMs9'e~녽$b?Sm\cԼ{?0QLzvl?-V\(~omDIb VZp$, :Q#߹mVT";vճOZA$P{lz.לh6 %aO;`b 8,>Gȴ6h kGзN}eh0ǒ>},FbL Btva9'yq9 d(̕bĢ2].܂Ͻx{RuQ`5x tQc&o+[X׵@L%5Т~dDeӖʖ?=~q6QsijZ$qbR נPOޤō8+6& (CJu|\Z88$c]8u"f|O0ě/ sE9fXm7o;5$Y-9˃w h er6XMh[2%E+lw_e#X7z͔sU{aNg#hulp:-Mjձcc+euu1^=jဓ kfkSJ<-u3,܊So@s_Zߠi u0ZT%3n>Z"6 ;t_70q;^nNAEdUD0{pE]9W=rś3sDv0$\hxhOK/]'*E6rB@FgmnКҭjG`F~DWjuZh*ዼI jpQqKpĝW-]ku6EdݹF _f@. PXOK<*->8TC' Ɔ^wFM88-xpY}MyPS7SR^4DoyNoBې68߈(S*;Ӏ+8pV=-J l@J)݆]ZD/"p]Li;4цmS{*v@Z% e dc,oPim8t |Ri0>p\ͦؠGF>t=c8\G<ukC 5-9k5o(0`HU~.e]<9-v!QtpZز0S`8{n$q9:%?VgtҎ2y , g d/PDdA $9⓾Fڪ3waYn]s[" )feIoܾ 5xz)|QL-&ƉM2KxUM r~wf"4ջзw(efK0΃?\PE@Jq.VM)>F 4 mX_upTJ@:fNAU=o {,sJ{k85X7W߼l #ٞǻIޚ=#W*1Y\Q6f/SjX-t󛽯`ڬm=ܶ1-#>^b2?Ǹ%@i~oL:ێwINOI9)ud_M1YMHJU sŌ: 1ܩ~#tmy7o;6ť޳joa!D=&8:(AkkZ ]e|8atZ ¡m]FuTld14,]=S]|[擳ieUM+>vW!vK}b@ s (N :Á@7zA >,Qjlۮ _S4a~T QY*-"XU5+ գ if |EH,Wrzv j&oJd+${4C_N2+>eLK{TKSx{όםWIHhf8X>׭E8K4*yƯkU©'Ar 8 }7a i6[A|vl=3dƘ-8$;mP UsU X4ʑ*TPAn(8jν*9u;*LPr9m KG>NF@G%/Y*_r\1V?x|5vcpby}hҚ Y Nc/= R>ɘ翱Xf (8/E+`i" I`(-X G{Sa23be.jكyG2T) x׹8`XeL׎緭N?xj ߷j(XXdMRFh z;{:A0 %;#$Uoj\9> N_L&l$3bYhE#Lavli'0E7( !^%2ddz4#a)xŋD9 r2AGi G{uY gЋi GAW]clNgwwVX$cff.vx] agk ?56X]x'\ Oa8}'"eށF0oilI,,l ,uب4{Ќ3ѪK&.!piy,`]9s B9(e4IYl Ue8N„i{ `k0 `]i"YfJC[tCJ e[0KGCnxCc<:x@*pMܵ@{#wVc23YH0x9'@ ΀hdf"hMYYY ?`(!C-jLr>"B,%adhH$?JO <Oh5` KJTFF$ kg@]w@QY<Ә_ ^Ѫvc3 5 u8C/R3DIl[}$A=$s }К˯o^DgAg;-$+V KiLŻjbr`0'k2lKƣӭ#(3` h9J;JwaVw YPS+ FaEw-d²TXAdFvj GxtaW 0#;JHv4!.8^4Dq^Ia|c0kXH֙pDB9a7XO_LWpt2 .$0pB&MF|0M5#ѽ燰c6œ9qP5%$ۙ >I]-{P?D MhN'Be=X)햀 NV,.fb:gaHN0DBIn'r[mR̘{s\v5|YsAEk:pyV`a+ZUO`BQ N!W]*_{/k@b iثGG_w4OYdo@HqQot8 "ã*+Ɔ' "yN ,yA)5OĔTF| 6:{j #Vra O EؠX?V-cGbq٘02WEPڢ U9*yr=I@换?HOw{/HtOJBzxzNcAdV!|-*±p>Scsk ?:0'lw5 v=n)A+̏`|M$3 ЪAp=:Nk2LI#dvw&k8u^$A lc=5&Dg9~⡙ip`]yfq y@7v^&!Aȃ"Ac[Ht35(%~$1 iFd8f(bUFV#KQ@4"H ȧkI䦓" aHA qFmѿ66xcBP]nG{f"Is._ Txy&JJ>n[%[e2홽 oaCY\bg)#`qan] Ʀ!5e%S=,xI\!~ 8sSFCBgXz^~bR&1Q͛w>rg <g=D0\^rY9;>fX$;Qµ!b*BΣ1R@5j]n<}!VȌ$vYإV̂qKrERj%s~1=l\VxQmٹl{$Cϳh%Pg 'uv>u^3 1Oc !Sw#ɗoFoN3dK Rȉ١SQz"|vLdi@w=fXs4Jm?\ v!_(^Q^*\)%'X#6d;0rO;]((2t,V~PFy EC+tf~rV"fUr`ٳ|ti-ܷCE{O޼~O&ȬID=`N$ ]6"ДcVlh:404S$8P`Լ!j67z&i[jVTK-2FQ 8y H~b[᧯#)pΞJęH?sq@iK|L ygֶPx8,$/'CP J p)5=+}Q%a_%VطmRBeϾ$)-(O8.g4ezGݰA~TeFv| ħ6ڝݡ!B5]mW중 o0LOWe->,W5_'x~փZeu*V@ۢQ,UG~.T ?>J*ΌhdTl0 ʝnPnnPnHX0ud: `D#onV`ԃFQc`cݠ v F8n0,Ayn8%I/0d(&6(T>!˒vQ 0QĂ+ՇXE!NHyU{E +8[Z< 4J<ể1Ta7Qgn֪4'F`X6k >5;gOE(^u+^@4['erY3d/ |em6ΊwJlVmnx4ߩo"X~ 2AgLs|#]f2I]_0aENq㎬ >"72Wt*JLUX(,X˳Ӛ kd'=F)s4u)hbS-P`'0Qa4>wvd_M~$j"uG T&PaC+-,wSGo$S3+.NaR;%N}-*h*p>RIJ<7gބPZZ)c)?#9=S ۶Or(jy]7+Md8CŲdarb|XI5_WI GWM; c3{@o/c>gLr 슉i4ӭ-TVˮcbK%%頚?eM'$KZ7LKZC։0|~[s8;8M;z(cb~c6mIؑ)Dc_+9PnBJ7<^*l6˹ls_oQmq̴08pDG: T=(& ?slrS0xd7Il.o6,_<L Ŵ/G\ҨPr)௝ZM\_/*tRL i¹~D2|+ @:7Sn'V[dM[ }hRN7S~WDVد%(@8֕Øvk'PR&Enţoi]darſ[FI6jHˇ<#}[Ģ-\)qM?I7 VCa\]î0VRo#u]rABz1w:䳾:Pgqat9&ơ<OpDQƭG MxӃ&? 5uxB.S0D S\&*':l ,yժ"PgBRa|k5 kҽH@JfUG hLPVNT&DeFe{Uu c[o5Wkx z_7zk-ZJ|7{u>3'WVũgά?vUs'.9}6xN;Kn_8yGg']o\czmӈn g_Qv3 LnޏiSVbDpmnbdnTœa!MfJUzJIVܨ 423eD΢<|LC.dx~$#ʯbTKC zeX9(Je?Gwm 1D:0~P ـ7zc҅.YtJ&C %@~> 9s+pm,Y7-@E8,}& NٔA OEiE{J6ͦW0dDhCt/FyJM| #,]%&Y3 &҄D;8?PSQ򁡥8Fٻdz߳& yt@֚.R+s1^ss`EgcAwrclljϝۯkBGI4na$ŏ } ")F1 /:(N2bMI2H 4zC3ٟ<.?5usxxa6_b(׆/&~֌W$Zxt`i@)Z306:|Ԙ#V0ȗ582coM2 0O! {S!Q,\CC@]&+ 8m/T34,sBe䫧=[fJ b ^Nt6 7*YhX^.Ypk'kfaigfT3+ 9ph?p)8<> =Ƕ$m,h+hT.ԍ -3Vw iuf`ZN͝kPlaqL؞aC!?D:xㄨB_`S('M`;D6"CؔQ79޹=vmkepZP9MrDNcsDc }:,i;D+A7#TN K/<k! vO:R&csQh'LpQj&EFR&ԝxƩ'$a&]s;$w7?dsΟJσx mQ$LN)do6]!ܟa|Pڳ=N3JKoC0Umfo޸)t8g:aۿX6K|z xwRLc~X/b8 L#A'IGӪ,qujzdePs_"K1_|GJo0 !stWTOjuWQ}Հ-{YN8jTbD?W:Z'k>kU';wGZbN?W]I.ӥ=m'zp3 jx n:%UYs @^nVuͽQ'{e}?iG69j3OYB^hLPG2ɋh|Mѐ=\l6{om!M0ipߊ}tD[N1HbduŞ݆!%$ 8ƐN?<{mx{Z!C͉G- ޢ 0Z;lDK(0hr E: >*8jrmJ8,X?G1a~yݙ|r3(`Ə1]wMz~7!Euri(o.XJ7JB4DIT u"'"[XDbA#~ ZlɺY[i.yU 0!ne:5WAbKUB_2/q<=pTXBOՀ<2&+NX|Z! .ES: 2ƦȚ]NDC$cyo;J^ڎbP[bP:EH PNꃆ">|ugaY:haYh)kUW2e]Fg6|W}޳Be`JR udюlFMG׫WLTNhT&,RB+r^Dz!{a?2!fc ;rUZ*,| fa:?*Co(iCK)HVV;H?5HR,ZHo2f疐QJ!U[EDfF> 0<]m;w.??ßܦ g̞ A%dX}<ػߕ<` vrX^` Bq mX0fE-&RvRjY8JSջ}? Rć䴡6J"'&jd ==|3tO| % ˻#|pK2;J;2.!*hlf^vۜ=nWodtY8#¦LhIJ05 _?A!}G>!bV< }/ |p( DuĀ=4 q:Uy;-|Qh9< 4r[鮅xxG_g!$80 [jr 0"Dnga*K@hv.`8i57 k pqř "mV]ku٫@UϏSϜ\Ya.9rإWɣΝzg_:},9K8vy)}k'Ëv}..nU߄x]I:kaJ S[қ=s$&!ڋ Pa9EGG*̡P oGPԑ%tt --#GoiO*G"ye0u2ڏQI jZ: "% /2Z v>X+hw).{ʯ'pU_Ŕ 0h=d@:¶´j"[tFۀ`efLˡe_Ool8Am)HgovsŵmkB?/Ъj@DˋK'L'\UH fB\B6@ -5DºOMIwsqP3՟.js"BGeB{ǶsIeZFf}%a*y;J.PŪta0zc4: ۋڃ}dY ZUYY֪WVI=̑Vj%nj sIMENt`o B`¹8P%ȵ~f񢊦=N~B,U3e %Whzrj2dK$l_XWL"gk7-E'oLYNIKm~rŌP mԭ=555̤$ z }@?p!AMyk0'DJTσ:W}f]h\RUUq0;27؟}Ff޶}hQR8"9*@)iw6[uQ8q^Sa43/o@VC~V2x9N`5wܸͩбYxߙ~vk?kNn aOIPf&E6R϶_VWN x_6]szs/8+;J>꛾k mu+*[G4uG^Z!n(ʆ_U'lm%pyE4 \j+84sT@ ZjeG5N16[qAJJ Ô*9TAf!#I@ҏINgBBYJhjЗu ~.fJ~fDƧS;7CF`QnU)2>9aiA}Xi ߙ[:: 0FD%C;ϗ{[Hl}44pG&I&Eptfaoo8ܐ*hq lV q/h'6Oӝ^(UĞ7cg&ÊgA-AT]i(:E,LNjpDX'(B0|4tUdm+E6e!6׹߶ү~&ogsNLg( o̩9jy#l-wh d_/(Sap|Ѱr˭e7|(ŵv0b:j}lghRϫWV`Un`T9WK򀱭kan.Xqҷx{q&lLs:!Ww43eG{M7GӲrW~4yiul8$С籘ﺸC%r<R*jHq+^|:QԎwOH2Va ߹ܰJ沼t%>pwiHZ][ÞTAe{cw?oKluN]b?j 1Kca~|9z+7^fUB1 ^5AZAr]qnq8qpU 60?/C Çsmml> ZA_Dlw[~ F8F=üq 0gSFgr3vhp 5שEU;FtxMh!ֲk· R8B|3VPdm9e iA&D<Oro:/cV#IQt˄,mDj\c2M#L'!*5@٨[ 5 Я[I^OS#zsjJpQ}a rSѨK_9ݬXe:J'6<<{7i0™2(G09*P~B9h*tF=; iɢSn'.NڏE4rIy!Qv1gON0Ǫ:z4{8:p } ǡ3OJ~XcNBbdy& º85ERͻhvJB^ }5ib#?GuurBH_%.('G skY{RfT 7OH`kKxw 6>wׄOs=K}Ӱ)cӗ|!4{ 4- +@.RS|yQs^k 5#waU4l}zTX}rx_i??RE Y|:Pg/w6&x;WB _?YW: -zCDk$Fµ+m۔S؛Z=I J(a^5Jj5zCܷ$ =IݷH)Y 7J֒p_Ҹ}1I5vW+]i.<閡*JOC}ҲPatV{xgF~c'K!H}WXv7+5kRʭL Ci>gm8w{}C Z3q1eш,F?}+}KjT9_kn 6Z8¦؇xXN37 + hXRySفFRe|ێLgUI]u}.u#)Pf 1qWl%|HhmB#:8LUsH|/m(7SIie7J; ,;^͢{59!}?an?_+kToSыƯ C6CIjؑNA}ȂAPusil C,N'61JVl3<&# 'd_o61j3~=DXN>w֩ #eǶ߰9[Ŷj(cC0ڣ zz'X'`kiJC7$ۂwp ]_Jei1odn9qܬa11 Bo~ߩSy>NP?챞7,{kO{AKıT$$k(KQ6uڋ I{w&X޼CiWo羏֢f8w=a.6ð{@Rܦ|: |LOjQhS1}"-"GVh`çkv24a36E]%bіr1a-/2-.C}X?{>}p{/,S<@x]%7ឿK¤V; A#98!!Ӎ£`e`dd|w=)7W&a`/ 07b+uLV=^ɢn[٥${t  MQc?;\.ꃚidY|O710q߆u xN.ش2QqqO;e!?C[ϓOsgLig'EV&8Ɛ`^asPw2@`;=UHM*7paVN>%҈ii1)cȻ6.偡fI7շ4M$<4'37{K:EC#7v1,-3j{!:qf4fK!dNyW 63qF㐐]zLt}%3@5Bcͫ Lx(UeG$ bвxFIZ6A. G3@(r|v KUfGea$aꘌfR“*5վdHc1d +,i#q -S)hmS\eïe- X|yh +4F!صWeW$8Rq* O y*!yU)WMь1I*9RbBhC8#ņ7t"4G׷*b~W +ƱAck+E},KУf^+[Ŭ!N1S Dx7?sc=j.Ԯ?1x AU[RETn3-0!n.\]Vm<`̀M C~SRG̨LD N9NgMj"@)ϟgia>p/}jryՄ\e.o'CxGo\HjR7eAvhڭ[k`|-ePZMj1Q VG:^,$4ʁN $ 7Q4ĨjԓT recCD aanV\rUom(F `Α]p |s]r׸l(L$=TsWG4Jvyw~?z6~W}ҽuҟFv ޗA9W뇲:PqBekrW2z,]WΚƃϖx{19,O=BlL1nsqڕeˇRdEWED *÷a&Ճx_Q K&xRJ343Vl'Bڝ ^h)Nj{SO܎|zF[gl=9*;=9ZT:f S71F~U ym =˅2oOm.T 9, YY}ts2S1{ E92L1~oƅ0b)fũ-DfI*@+*]ԪV64 zH2Ex\ ݲi›;! IzDU bIMdr9'eˡDxY /P|Ѷ3/klN(`/>3ڹϜD.=~+gpG}g ϾЩP'kǎ]:r䙓.݄)8ێ>SuDӜ5=xERbC!J&d%%iǍ#G2{aXCKtA9&AN}@<͞Y%ѿ)o~y?*d%A1qE6yUކ'jWu>)AL@ϨF)˭^ʭdi}z=|]u;Mh.B{j|s jUJeWHLwVGm~^ylkbu7m57 ޗq\겎}]ͮ$;#ke1ecىh3ӻL{FkB!䓐 I@Br8`w 1G}9V+iLWOwի^z{BTG/B TmZ8kX}n5(* }/4݅M>;k:R.U`LEiŘOP, ,͎&X4DsckQY,+o.{+cF0MHox; ~߻>miċY=T:l-SjUȍB6zƋ/7^޸xqx%፽{XE1JwGoekJ۷C{/bC#C{wۍCF_nۇJa8T6JˢawJGnqEJFCJn|Pa/Ca/C[^vn*={yPJn\8Tz,rP離a/qF,NvmFx8 9b ۝b-'-63:{Zih9#` R cip)bc@lMb2/k.黆]å}pY5\w /컆+ʾkkھkﻆƾkn[w [ak5l뻆}װv]îk(]!ՠUCuLo@TU]y~,_r8bBXOq%tۃw;F'^ص8 UCT+MڼEf۾b5ۃpk1A4zj54Vf(2ҝ| [9jXд90tsg XdrbMD ?4}J 7cTct+}Ut?46:Qc˓=_A3Ɂəlw@^Xnb*$O;[Ň6}c'5^Q 㮿?cF% 79S.,IʫYa\S,=?ٳ8>j-Q=\nI32 BpTw *wy󠗇^{I4AK]h"Gr2鳡JO?Fn9aehhg] ᦧfOԙ7LԴSvBX$U$LD@/omfw11|x"^cj x"{Jm1#%3;j͐f -80SQ Rb81%QH)/GRl8Iɍř]=PLE,5qx rYGSJ̣S>/h8.b) x|r(!]zTHE~sD{^MHĐ4D smy [%bbC~LȆ⼘tĒgZWl(iޚ&|KЭPEZh:lM0ڈ ))úaϘkTl.!?KϏID*rS*ʯ_ߦ8x+rPOI$[e_%I6rINuTT>%H'M?Y޽:- @%)GS&TYR$IӐ] df}K4v=2Δ+T8½1c,L% fŖqWiy`tƄֲfFFRb;3>2vݺ}X-d@it`2;3+2+:=NvpZa/ߧ Q-pY;H밃1OYVSwKfnk&MbF`3ְj'g`X[A1B0 g0y5@ vKIm3;lԭ չ8l8̐-(Ybs5gM.7hjD޲vx}|<<H M`kr : = +Rn:3*ް&Aw?('m{\:i-6Xmj';JuXmPlvPvaT}L1gqswxt/v65nϘM_`ΆoV5bllKG*!/vmu%̟{kDt`? lLC*r@3is:I$a!*α;窡= 1t15NR׬CH..(xX #2OZvrAhŬ q]<~cRy2Zoٞ/%A7*Cu=#GfwIާA *Y&xVՋ##) <3cwW>9yGFOF;YdLi'wD;_yKi'j ޾^)'vHѺY?]'@ E΃*䰲Bv iXO@nqݚ ^Ң<#m 3le0YUYpSI$8-.`ފtLP)eq9o"Ģkɑɺ=;[ZMp}DŞIM\En3h8ld+$Uj6GՀnJGp*ER%?䲨ݡ*~^_ %Xuca%͠ /7[5f) pFm==Y|e_pV>H61U (>'C/#؆חI0gj8A&CR~@*nU`mK勼pxTxrLт҂ɕSGcGy40=^m hYkߓ\{${h#U1O(!$*AQR8@ܴo^&9ծZ w_Z!T +/̓9: +Ġf`!6K&\h'3WTV,]]!̠27qhawTRäFOKTTTT58Lw @m"?'s|]o}&tsAv}!Smݩ{np8}I5n>2]VNR և$sYhp&hDRC*t 9z=~g}?9t)4Mug wӧw&{|>Ư[37~⋯?z9r,==!4g׿kh9>Ld=aA:% Q]B3+}5ZZֱ ĵN?Zkȳ~i4kw,]X]pٱlSمWj .o麧\ZYx؞47<g:_̇姿FϽ#ϽۿO#oh-ǡwPPݧ ~)|5_| 0v :fG\P,4l5g:|v؃ Vw.@!|=Ww=wG^ @5bw%w_c/w=O]NZ8s{ ´@8} /~˳O[P|3 UcX1"E݂ 3b %oKF!PB,ȘxT9+ '_ F_}{)>HdSΜDg`hG&/u%zBјt>-ԤN2JաTmg._xS_|5s5;$3?HOt>__靺עz>Y~PY>~?FϽ 8@,C_7>AobSfBm!;똎] ܊`Ը41_^eZ: "@T; ϿO.t`:Cշ|ȔV:Hg1#ۭ_l:3ۭKi3Ja_va_4(|Ύ_|3Q`?+;vGS3H4qq'W?m_;1w~v &Գ 8l 7_&(SN_~[/鯾 _};_' A@ }>%&>,JNp/=3 {^6,YABq+_i:kICHt3|~ tb: ;,?TmNqq3ƞ0k+ZcKu lx8OF"6M_n=<+Lʼnn;Xh9~(8I-K8@E K,Q@mUB %b؂$\VV.FE7ňrDՈd1"w-DHY$-S*JOBߙt"I\I}A0h$L<DD;˥E~1ͳ];L_|s#a6Q >Xiu񱕪u(?u'\fwzTx{=o ^oX5𴄍Va:x T=Z$_u&7ci0őL9`:0oN$FN۾C<~nD E`р~M"Yk_Yhuod@u[鴁BIExû#B_=>^zx/ NAaFNy{ ܣfP:3w ǑJ7B+UYg$2p]zCQjd&zQ_l@8.I}O)̮;U/ba ͷiJRvXScqd \D7`McZ+)`À,lzD?6Ր~!!:THSF'T?4nZYf]eRK=c=֬Yu(x1VG&;|rW"߹gjzbX}"BrEHP$r۴ ugxI_ ~[AɢLڽOKtm Hp)]Q>@ 1Qa&Mr NژfM-iBbr2ڑ#NPGRXBa䄡m0dtAGNBrUJ.LH΅`#/]b<&qY^%t|<\l-+9(4[Ɉ%JkV5yoT7 _,:/vhu@)]7bKK._`Ty#ѷa8Ӿ5-kZf%3F(frũxFp*2'q^aKQ)˘*͂c l,ȅ.j̑N!#|XJ]&Yͮe"HVˌ g^=0uqǽ*y1+1'w8s4E n.WL_2 6 u1h8̸h <8Ep h3LQ}2;AfkZ@3L^4MRqQn*S$ؿAmR *n1jy2`u4EɴQ+ qXE&kv1;̛%ݿU7F/e_.% I:UGI2Hd(2wUFR?]֪<l6M 1UtmѤKi0k'\̫P}<^fU>BLh/jpMoO#UKJ-A>qpU'S3K)T FS24~@F.Z9a_!j|AU[,0 +s/ M?64*B Nv`0KOXRY'~ޤ#Ʌ u, }yRy|}^R4ճIP&ka&]!à׽a0{ɇ3{NMn}'jZKF?v^qɼ[[yW]A5]5+Om% ?J b"^Ȫyy+%'V!pZ!^+"8E JF?u<.{{C36HTsī̛A$70󖲩2/kAt,aS 7nPrE{S41t{P47y+̈[ҍmQJnT|Y)]oik~,8HC(GB_׵=˷~<#]3p^LQГI\LV.KC:qxoI) 4D(]&u'vNwVsJjy*%Ɣ7(t 1ݴaUT~ׂD)I: ȧO. bbNG&h}OeJyagIg!_"ykx[KL!E+ tG:GN[2(rQ~}|J D e] /m/h$ ר7 2'|k:8\r®%[^?hƿ\0`kU\Qeab*Az"PsRD%iZFj|EA4d%!& #=P.J0quQcNE$( QΨ=d5X2E_-*GؙClɤY^IWu<)4S`\9?^muwNN0(ꛕȤ(ѱWl} v,Uj;PM snqF8&vcO0éS*ϏE1t^7*HU~L0wUFwDn4)$aL :M+YKAzⵜx#ip]oеhe2C=H1qN5rluUb4HeI0Bs`[eāme26'NU-@aH#Ń hc@zVe`^8%S[`H8j![2d*))@NCTd9]iCvjЖqoHxH.D&81aO "/1MR՝Ԧ>#գUdphTڗ2sȸHlP 48ӹi_zFRˉF <Z~KXHlhkDYF$tHD"oeR1KrE'S^Xjsts% ƒTϒ%Nm\"{QG,xEjjeat=2ySk6cqrgf*>Aa r hOV2ap5aCYvsvѰL$_ 7pu2F=Dθ4dA N* %tW9%br,A::!;7hF#Qˣ!wذNޒ9W8{jؚ䫠q4Y./w] _< w=+oŗCqT/BrEA %/ub"~)3e(<\I6rȅ]@BwwEI!"enx_8?#v'*Ո]FJ$Hw~U+cOUic/I_ԓb:L0*cf#3pJ`Q!/WEDn%I@hZEl<}XуɢʫBN% *w ` JY3e@~?Yuע5[P *#b2Ԭ=eh|t*{je|kd }M糤HC+5y]FW\v jsq [x`R^<Y&h4#͕x2߷!4UNPeZf+Ay@v1cjiK\g=*%6BiR:V X=I zWTS#5YU]LDkFbxAWp2^Oۖ7;Üq8cͧg;AA1+zfthY85x&3RyAю 3ۜk2F0Jv8̾80ɸC=`6p-r&"ƮB,T%jʄp贚 A6Ȑ'|Դ" j~ү^ɮ-"IjZhpH56 9ڵ;.QK$7>DUZIJ21fQ ]ݻuuz+1FGhq>Q'vc$J?wHJ3XWCU>%C@tzJ?07׬2ƗAiC6[ Zxmj;yqMܺ~xzw/Ɵ#|O^gO$KZuɃ]d>ڥv/τa䈣.E k q{4Vo):^9]P&P$a [Qg4G儕P9M'9:q%E7ccIZz®|WEyzC#+zygҹglE%55T]X1zKFX#Sv1ZrQ^$,7 `-D`/ڠu M3ݮWct gV2%A0=35g/!`Z+fvLo1TS"U Lؓ'mφAi`9q}v@R$^7y%e`sa(~?Z:c2cfmM65]?D|AahZL#U]@pmU4枲O&V\Bp "FZc2JW,l0saDY u32I] 3l[\ )8m ~SVIiاT&&r:6W`c<*Tkn&D #NAܛ٩-ݏԆg.Ruh0aaYc8ou2]LMɿS(wc zSb&f+O!QE0 ^x,XHc /t(c >ւ' c&Ym_0pOMmc("_ nnK,y]B~Kk߲T[Y+DawfTZ;^>PSe`0/dž(xtFe!s#tkP(UYf1;Jƭu9/d\!um{z"YFPJ.I*?Պ I_1k\W-) ,ӱ7ȕ,8: uÄ*61&& A+C/|d lr``ݛ-o(ՍV|iX1 QpUBo&9/ݞ=õmuJ8#xV m+H"y* Ŵ *Z'37@Ξ$Y?wjpwwcH"LYD˕] T+$BHfBr0P^$dE֏Q7$ O=u5~ؖ4'Iܔ-HeW*RٓʾTHT>%T^OIRI3RUR8;+[sR;z=3$|q~Ct*3lkAX=;J/NB2aK [&~W%mo'xLbFÖ|Ep0wGm닽.DD\|tvXP 0]*tiЗz~ًNi޸ zCׁd~}=8)z 9#(N `Dm4(FN|km_wM{pζNd%,m^$H:vJܴBm1Mjh#w 'cJT~T~T~Tʯ̻] e9Gw30vw,"]'vUF.i*wgNg| K~·HȌsݡ1I pfu9*L/I6Bf<}y|̙pMz\ZxOZd;|FՒ*M*}ͺB|$- d%$6}Cю^vDq0rhsy!n)6J\ڱ&˻!zGhr̊L0c0%iXý C8Enƾ1 ʽdD$)\t Q~eu!D#ׅc"#yI8&ۍ KEԲZ2־97WL //l!+Ii0 6iha:u`6\64SZ"$0:3~_Z% >d|˓Q!Cf lݚHJfh:/S^(gvjr0gk| ׮<~\*֫[謝-):d8/N}7H^FOmC#Z?R VK$3㡍q*̊v&cN8Z%7\mĹawVh܉tx_H)&|WjcSkջ$BpֲۅGo~C^YܷkbL ڸ\jP+$[6>1E[ 3l(2>=&QqM]Ŷl׭8Nm^Sai|#?D:ܶNqU2f`(g Ӝ3D'}~<x+?/?YSrr~B%U"_u&ʄVI_ZU yhxfo&hZ:*Ϟ:o},=u=̔I0xS?P1`O:x"aZXnԖ[gm˯oMjp3>C۴Ez ĨL:e6#.sHM!p=|4\֕Nϭ,O+̘7E{9(UfPHZ 8n0A2t;4 `$ X$Z[(Y(X$S%2'$0gI4S4dLD],a =RV`hYKa)-̶4TPҼšW̬3kh_fL!{(ʉ`玩K(A)P}li|Et8dIQ5z*+Cte!X`S^%Cuk"e~*W hbBvJo!F[*?Hg1Zt9kܠ ! y-ѺN95*:N%syz#am,ԔvP*a^Dr^5;VKYKbqN{m77/%jGnq\e6gZ ɫfѠwQw 9L\3B\iVqxqW#x=w7٫G于:uhP=GឝKawQ#gF fH C$#J"ݢ N'2M`+ud *ŠDXV5)Z ĥߋ|* Ų)du0j[O]j51Vd"6CN㥸V70h?.Mzo1MO$uT  sXOCuP7(y#p0g!ةYB@8LT?/%0vXl˽澸>5 t= l<ؽ# eͳ<#SA5n?(r½`,j ,s3QQAk׮scDԮgeժdtjNsOYT,Dc?~ݛEȡzl!0 }`mXI>B28WWV -X oƞ U*m k98=񏱓 i.R9±mR>@~C>2p#[0sz\ۃZuS3] `R OYV5p짬:2flXf7g-7{mx {IfHFċh#%v*~CM0r)vm_iMcE.KAEKd_iw4~.Rxs|,#$ "XvU';DXIʼn c|4QuR6s-<a6ͬAcF<ĈdΈI2>{ɇV, Gj:`9Ҥ r:#r'ߟJ:jt,u='5 u._/WR_K79_kV+XnYh[k "Clrb;kfybRSQA~P>g)}5%M@f_eV,3+3qE& ԁWzJ%v]BV߈J R {kvJlE%*ס1jJc<~2V#q(L[>[t54َ߰g{d9u ~RSraS+N!;D|:z)+z x aq]S/®ifp}:dC Q@3iR~Eɠ}eK?J[_ɀ$@ WSAϔtRk@ _ˌ ]&,-X<+4GY,b¨m&%9ㅹxήbaڽ^AޏM\|B4ϝn |{ '&*cFV}^8d䰷NJ ɖ97̎tY=GTo,>JC *L*WQUl'Q$<{Xe;<L-_T:KU>>NU.@f[1z5ozb+}ߴ}")6!zVزW_|6iTg][++{ߤ}?uU$!4@?tNؓ5܌nsV@_ʒ1IR_J志բ[Jz?$ $ NIYʳcqA&'%oݏZhf(8 p9oL!X5ÿg;{:E1Ga?(D>a^*z~mLvӴ^޻DAG3iCض@`p]EՎwQgw:۴6LzF]hy&4& Cϊr8}ۙ>eQU8SVOF!N*TRÒ4lYHkmC4>ϵ㵺 EEۆDu_|R);+I4qų/ w$X- w` <]ujئjKA~J9!!}F~51%`AJ[ 4%KÅ,-J~[`DLǏNd46ؼYfжgr.pQNńWʍb#=7V8A΢RK_#WOYUW= Ɨm;?ep_;i_!SClؕJפSh/0>ƌt1#]P%V%U~2Icy$>җ^0VR㎵@~IUwf]דϻrO.Oc/ȳ <$M'cBԵZ3]A50m!KXb q7+kϘlJatZFiu*0rhs2&2u J'oFιrL|4&H/PU#/]=b!c`&ߊz$q|YE}qkw4և>$LF1 U$zO[О9GD۵X&6&OSNF]=I2R[IRU At#(X@7i[d Zœ`=mp*'yzʨ,M1n~J~Awn^xbc; yȫ.FZ0aحڱ U7cܛkc6fz3W˰G/ {dDBv [2˩SIlSjid51^|+?F D- T_+Hm!F1drFH$c4Ռ:~_7mTs]ySӷzX5v~bvIjVbaȌUKPs ߷uB߾$m1uv صLbunB&wЬ=W3A9ͺ.~r#y7>Ը5nCƋ R9>n9)V^nQ T4m 2ܬ!CS'E ث;}Y/ &u -~m5Z9LU5u[0H,ݺ*"8;m9oLXG[A`t>:0̦;I d#5] ƍNViI28I:|BX@b#maD^ynu$7; AKk"jA~t69=|jUׂ?,0Mrvu:N:rEUod9qO爍GN)8b<jU,,aՃHX;s H'۞;G$o5</agadi&c[b<)ʞ=y ֓LHxQ:us4<;gEoI|s6tTP'8|#gyXR%j5[:>xP-|%;OJb&+lLwmy'.N2ɮ\eqQM<ۢA{ܨ';l\unz l0b^}T!=C=@^КHꏶEAOL@={vvoya&(%T)8ȂD'0&Bo!2 KB&?ܴOY=##vمo5┷R2w}Bѽ>lnRЕx}{A b]x*: @$_]*Kr=fl^v]]km09MBŃ\be8;Tsa&}Q{dmC$ ,7]!~{Tx~4L=[o#ֿܿoB=v=p.{%,H= ݳ'xQc,gܙE4߀d /`ݦI⦆{jbmSp)7`v\f[ 繰;]r$Zw[ vb vU18}w#9sG^!yI*P^ZkOԫMP3pEoo+hZ)\|?m~:AyUGP%$}uۂ-Luwėmw taXu\b)-[RK 7l 6S9h|7,+j8-Q-)ãG~».gVWnpa`ac 0wAc]'f Wrmv[yaF|xI}tW%}Od9Гu]᮵0yaʍam:pVÔ Agy]4]WWHl ,/uufOm(* }2dǐ!;[Ma$)WqR $IL1Gɍ8-Hqn-CG?~Mÿ2 kǔ*֙Vb!X3ti_d"v|:,7 (Ѥ:t1@tJ-ˑξa*`ߘL(5c'qHtirN|0[LPBl1/C%z'ZW HpnG n]f U/ 2MǨ-&x Z0߼Jw ,0'YTQ.j:Β7GU?5v@G1A۬L o;ȓAXzf =l4':ͻ.MQOߘBb΃  )>#1&I™] vyTU{M%Bt.0AN0H\2XD/o[ P*<*FCwRGƙ2QihLpt㙕Ok慀} @i4O#f/ޔCF[3-Ħ7Ζ##߃#Ǿ:2tKAE/=? O{?9¿бC/Cǿs7:|@9~==>=?uN&]坑_p~GKa=+c\^YRGgVZł8O`V<]@NTdfv"l̷ ߤK8Gb+.6wep?>j(?:#'5=;LM 5L5uxψ#&Jj2Zch5 %>t)- T[T_A7m[ x.T*v2W)]$TqJ$ոF㻓 u5^M5CPXxl()uw<r\{6\[@QZб{=tC30zšw^zC=p߱8t?zCx:<`pqG> z!>tqG=w\/eG3W /nWb-uƬbj8j ,̛rgdG:yq RP*e 5L49$a$ ne`'F$Qc;) b/t~)(ʚUȝm54c18s`ƕbX}.Ԧ@jXtgV}ixU\Eju۶ seK`BΔA4o{A[JEWhC(]-S 8&E@L#.>9"wvc͓0BnOa/Q Wi$Xw=:j"y$+"Օc8nyܠW֑ S>f.u%+luy_R-fg}bnpr9Ŕ_jKRn! x [ o  <;DS3mdtϏ)-p~V&\Zժ-&nhTOE[@zjek MKA@xlw)<].FPzUp7U8 F#\[3> u4u:ba}p`3Rz LоHfH5v9CSa:kL#V&[9P{P $j4k^/ITٶLq\"3҆e^AK'LUџqL,V0jlܦhKWQyZF|žiiE00ԫ0ȀC%c1<7{Ax=)}lgVO]*Q }!OΤ4CV]dI)Ϥ,_*C_RMRuӇ{ Bkzk9$%pL}9Ka~AWetȨ`ǭ4`T)WB(߱, mժX}f$u*..Ry4#a = "`jDWYN+k >{rZf[L/7e,VW=^AÛ' ﹲ7 mL|&e⠱4q/U*Gsg Lz7ڍ> Sl I0<%ר$n29SE- zC؄rvwr!ۦ Ow`IN1| ZwW D$Y' 5iV/VYH*3% C17hy =L߰Q5@mω c|4PF' 辐#l);vSoЎ|k_y$|@9NkagD6@-6OnZR#G8&wz}2DvOB@{B$8@;K%czdejؙ!Ƈ2P=~g(tOwǎEI^vD9r[24߯4qW~mJ}BCA]dEs?$;nhGd1%gk@El^-O=3MrjdlAgd !/u|pQ/쯘1 ́2d:c^#3fB 3Oʌ 扐4#VNN>cT4յ#nfh0IGdS2"C U;D0l$EjAn<:vmnRr7N'?ޓLl&p J|Z?Fe7Ng`Wu&kn!Kp'*Ò ڝ"רFpGP#I6$rA.iPhq nY$yLU Q7P86M/;p>G$bk|p>8yw5pRT 5^-A.q tęh7M$H9%=^wbBMNyF+Ta(6daa֢z,xY tm›ME۴LU!| X6#^ qDPu7]7@8_jԕ!ؑp-oa'|]VnZ^1矣.~=1O*#)KO?H﬑4W/K+P".?cQEuYׇ(붲-^]3j>QgɣA_h'XHF"51IĨ|2\J=?M$%UONGv(dw>cFxZ[;zxgclᝑ3/Kzx=sijp#qPȪ04#B >Di)(/:{NOI19&*XdT(N=ZakAzX%o'* 1&("HRP?wWFrGŲr,kzY9[/VA9 Y];E]$Twݠ ޳x/N7uÜUУk4|4Uuԝܵ*[+B44u&9RgG"ݖ_˓`VHȆ٨^t6p=:j9:-{zB@u. (O1|sh1y0Sbԡ8 O[1..xtzd45pVq1 80w\5MN%z]ڸgdTHe-\xgsvLLG)7Rr4|KY1:%6CARG&P0\gUvf 2ok'Ck*:~m;]3`/V$e|SȭզbN~0j#;7Vv"#:dՏRuCUM ATKuQg'oI<+∆tt8if<}X'R8pGƎg"=?:Y`c;[MOz0vef U 'UTt6H|nZQ=r' IlH*WBJtP֧TlZ ,SrPCf͞=e>tP3)ִ8ะ>0-k$7ElYfGf&Y$sG[ wS7S,\Ypf=(ˀBv/&r6sE00O$#Jns vq1򬺩MEzk{WڄjrLnNj?+Qoڞ{ mްǣy!iKany<%H*FV,'N4G4P0~h !}z|{DЉa:񕧍.<t۷ 1EEʟȼ \AϿ_NPME7nm:ƍ1 ^;M'sHBI;V&O= M$ŠLuX>QHzaiR+)Nqq_6YhL4IܪM藙ƒ^iOZgvJ7k:&(E`od\Gޚ ݾⓋL3moBk(UwȗNK1/W%8"/z ~sUF4~v\)iz->Vj,KsL9DRV\h,6eJeiV&{^3anN^>GhFebxJhNƚk3贚rt@x۪vRߏV1;1eUX;ի6%ɲ_ / 3%oxZ±Rzk9ΜD\QpY^ɚ&*/r^5"t Ut&YFK*hZ47K̫|$Jrm\mCDkKAUkO[EA"i$P"5IӄadnG^$Dvn|zf{.wY Cppzߞ={T{g'T>]na+*967:8@ E /|thyB?%")s8߹˔;rhz$=ij'JwoZx ܞ5l EGA$xT񛨊#]jwnBwӺՄ<AP=% bDY1a=hIdC! ܆k-P hDRM}.xd_G$ hl`Hn D(J|9b iiȋ.!XwEOt)XEw^̿Qf$!_+^Ṅ(vcPT*$ "ӥщLD';w+?'6:IBCkG$2R('|67Sl T|%$?5ԭਁvݕt#:S=*ʟrΜ 9?;|ygW9ry_;)r~y鞧A y_r^s"9ߒ9sSJ*v 7%3{JmƢ[CuwW$u߭{@)!FUkvU ȣs&FXT˲f_GfWh|tjBGl<8 dvSP窺c/qew+%+Lsk{$Nl};)׫so_P0C@ƽ=(|sQs޴~" <"<%Y:pAHlkq#П4aS a8'2u܉*OdתXMwήلږɃ#5?)Yɂ1cw FqKMkߪ\OG'<=R.H&}"(y|O3>.`);z:s]3ׁګvg߰  ?yYv 0qFaөB"$ӟ]c1gQta`r]TU!;ٴ;B[r==З!YNEHm2h2XO8w";$w/$>]eOw݄YCZP?=Ƅqnw )1~U$uh8Ikb'K Va%6Xbk𝚦069Zg4Ȥlʿ߉yfY,Xzc,qĩ#,Gt⤁3[d)A%[#"h b~Cehݬa࣑.p x sVĉ C[Ѵ>%_+C:qHcB w l?ۦ{b,M>N٤ʄx(OGdƨ8 @&yOH(tܹk CX(O -KRFьiF0xG8Q"mS+-QH{}/Ӟ2n9&/T!;]oqV}.nD^O4+ΐQs[V'ZqԬI}LrlyK Q;j7,!sj~}nJYDqc|:dG~êy@yZ2;hga"ʆPdnN9S7W};wQUwVЦaӦD#k8Ws&o:Fg[x3]A8@f&x9[>KZʼK)XXO<7k :::+ݡrKoϪzϛd?hQd~2 L?*sZ*}ZT@ÈUmZ&ޮ%2’RV Ca/s uZq"\Yts&`?loMGJJC/v{7)Ge=Υ9yIއS9tW̴ {.;G(sC_S>Ak!:Lwgbt$]D,KILuOSM{ͤY!{?\1@9Ya#,Mm?:A/Ѻ &FXYfBW9RrrzM6M9#6xaعV x y!9eRM'L;P~)/8E}=,-%YQ' U8Ej7}ƎD+5:anA{ TiQSݍ\Tn̈`Zi8?,eeVV!]{kӸlU/ks; NZt^9<ɟt.oxh")k2t#wm!UDǸQ'UaJ4o`zy-dmHbp늜Kkue;se;L&ŕ!&zI!0.cʆ/sSθ|bs;.KKea!zí8qx Ɠ'>f ?WH|&42C2$,Goя"Y+ )qSthK؁zCcOu2n2ϾN.ӝTɜbi2\.SB ԡi:\F5\>(z+~5>YlRT:4)`L?A _wiC#MbX1IйPOJD1 KU]+lٴviGu, v qk wg{NiyWY"^7q򸺪GQ%=X egpۥ3 lu=Tg&sfɋ+'{ھDqb>\+q.FA]O9~ m>fJ 8|s=f~/ϲ`Z<%ڡ&Y#* ]+xW+x{8{$1 N,z!S OT'*`bt(H sy=uyʜ2'0'– tWwہO%q8|w a%&.P?ݛYݥiV•9-ZyT8vTMo/UP  A5lBGWBt@ípU﹦[5,t7h01:tU_*GA!d!ǖ/\۔">|3K 4ɦ k`#riM;j'@p^{+1,Mql1zߗV_`XG~cZ_st3GȰ V;%VU"ߴ*П:jA{K/L)d2jQG *al߆ޘ"Y! m m<m5b,yX iȌf jT>ߋf=5i q! cn,X@`G%ðg1]n͋4\JWZ03P>%2 j(&8DÓO<8n_"Def"b]" mMPLW$_FQ'T9` rXdZlqNwl"s_JK.֘LAA%U*k C6{9nR SL?֭Q󆢞Su\1YkGXA< [ZN]]g&(.z"$* YOYynV$B[G $@5j;uٍɗ()Y(T ]٪N^^8Xi2E x LW\⇅U|+LڤpTUɵfrB6MNqGl+ҕh+jZ??nGCs+{`<#}ʻݛK󶇧#|R .ʛ3eړUR>eNHcA&cwIdE=oQXbr;d)sU_A;zWTAG`CP*/` z&)zD*.kjwm_ceH5Ѹv١睊B8P8ќF`q \>t+tEs5=9A:.DSbpA6]Y`f`ffۯw^]?d" QhfعAFuOv 5}R$"$<>ݠDk7;v h/sa:ud`:3g!]>G=BM׬#CB~M'-z !?j;cs/vǝG@MB>r ',h7Jޞ]<7:#<ڨ3G}ݻw=t:?wf޷ e//[̚K?0Xl'G|CA5nZ[@ئ^ mV rf&{>2&Pxs}{! k IhB@Ω<9g:~CzlGf;ȑ{9k{GqH&z r~n/:Ts}L@-_L۳0M?e!:ܚ:ܢXEzv&pJي=~|Uu.}xܧ,ƂD%u #~|edៃz <4 j,A _:L>Ny1fϵHl{j7HAo[5,vL!n6)+r<{۪.C1% f P&T.,3J>l6zdU-5-;~^ ,0Xvo*% BN%ŷ!VHI|mGw/F wj[uvyZH9Co]X~*L&vAGY6zؚ;Ɂ^a'-}g "uQwvzx$&Nuz#y-lp;O0/`Y%:1 \&NzԡiZָ $dtfֶ#Jgݴ'_B33`#왙ЬعE ԉM@b>-/%L'h~d!NT)x##]'L^_ĝ/tDhAFawbgNh^$BK&.OGL! ]C 1zcW @J=,ّ| YV2%gm晳-3CLNvZoaQFZ8VPNAi(' |з^Zs2C<%[S߶Fd-FxRCofy\N` PEV^: ZmTTsao&=y vɝ=yDϠHzvDg&S_ EN&`mY'8vY^Ug/O@,&=#}-Om"D@ 5:9硡oX !SO H|O0 4_,Tst5Gg@Iah rı%jNǖ:TZbbVBm`LF4~6cW;N$tsN++ha\7KJG+A]87ȫ#Po4ʧOT*X6\{x$̉^ v\F#V5* !װVa[2>hW.LWؠ$4nKaW6ƲkDG$.vv ȸ0e8j-y#&ջa@ib| chXkG@%Q;,{eTgLyMxs2Q<`Sg38(:,1&00KYq[!X4 FLq MD4n?T1I331*o@g"jPs2]ƻХ0έη%c;VKl;gXd߮ETwQxߗ5*n|Qq@(3Oyz&M!N0'uBoͧ"WY[:֜)M<-aFX4|n!h#}Y$RRW34YXQqhKw2Q,J q%հC7eL[yZS S'QFLS[ѣH ƺ2?>#j|Z_?i](LFY\H?*?(? X*_*P5;J5ePUF*)ٰkɮ ..TmKLWՌ[䙯I7I=o{cpqq=! OuOY[Z7;%6ejW;B.Av"Δrhۥȏ-WgGVk¸}5.u8:eaiU+$x0F/{#,MJ?v8mjITLd1ʻΓ]\fVR'F4ⷹ}q*4NLE/ijD֛dKȰhkJ+%&K勢JPlfTOk,:.6p6#>oyӝǧ( 5t%Ҧl"!m5F"<3cRDW4،պo` w(_-ذ7uDAwFm13Yq|tb|<ޮ|a>\% *fBZuD091LsFse (79![u38{}|4z.5v<Īrr}thOcĖK U2͢URv鳷Md+Rl;7ig&@Jr5Pq3F( tϢZڏ2>%9k/,uXS7O'<<Q 邨c*QQ$MBd@9X$pmVcP,a01TPڛݖ#Kd $Xw*۩ZgVolݰQ͢D~T~.

~;ߵ9uK+N#kMӳ:vCL~tL uN+$C= S励}Z%1,}b2m5ߝ7=[F2 ICx+?Q.ȺP?9VBr7*kuݎiZ)k6/^ÃWv3&; O0Lդ*_F$rJnFz\o|6Re/OSFGO`NU۔ k;fnyfa - dxЈJG\j^YQnVrgEM_^BFW1A5Am.5mjOȊ {L)nSYGB" 3J$z=H&*:<}S+5Orm ]Qoy;KX+Ν^-UԉSWZ-K׭ vMl5*_ mDԚ^E҅.hjXɇ SmS? wf6c+]5q/Rq ]9]/]W.ͺA;9i:s+]Ľ#+6pĽ'-a2WW]n<]tv$Ċ@^3G:+t]t};yujA.s-Oq^;h^2?pt=]+Jr'?rdz1Gɺ'[}g֭H2V,˝K9" OD"XB+G#i'_[1a,w;G׿j'vcEZd/xv!^4\W̉?q/z!GWؓV̉#'j׭ N5]︂Zx 7^ /s (UMZğ:[[DoaqNO^X!'&O_͑uD;.+t]ty^퉨[tO[Uc5 K☭Rnv[z2P*h)ve YOA~{*W }%1I>{IEgW W~ $T(p^wWpn$֡I"Im+?lהO~X!@ؙccb4) > r K+I]m%]~S_~Z!BDHzJ;Os@9uV'Md>|H Ήiv8B¡9V6sb9BGmQB> 6*w DTO휀s oЋIHC_]ɮsBV 6F ɲvIxsIx8"# 9BD I$!m<^#)v!gR!itt%$)؅C]WjZBU~WWkFs !Ե<~#Fu(!zFb.GhtvN#]HGA-.8vDO[9j蹁G:Rͅ/;j_.&DN٥Na ?E?BQpbH.q"y*b$ I%IBDqmͻ`3,G+~"4VDh0u.:"ܮ. ܡ;yT O_ٯ;~g v 5R:.f r:V>M79i]ĚjRTv ]S˲:|.eٿ]V}<[䈁%=Gs據˲>y09>}dos;Hɽcc6d"gC+pL")evtk'#SML:0PvFù30Žk2 﫥EDWkTTcʙ1cbNvZiN.p?\fYw\C(Rn,jmL I@ m_ }\~6Mܝ?k/P5sqosH{yˬbPnxsF2P7Y_tM%=n@~GȺJpA0DD4Y&MG;|_3Tk>=bD(gAjP0,묭 &׍ "C.Gs9@ C~Ns3Ct_ 0TDx C)#g Cȃva)H#g8 ڣ/OA>>9T^;XHN.o|e iIr zC;$wmK4P|\w>ܮ2vJmpVuGj)#waؐu$g ڬ@\Q 9HOnm\/C6 琙}hngg᭧>@97z:z9debYf [nZ۔4gg<ϯƤ%oī:/&jPfrRumcrP7+6kyAl}듲$ L*y=x#߱IvDNfI%=On91S1AX% wpޤgZԖe450K3J}PTsn` pM.M(6S ?~) A.Lϔ$9NdŢOxu5W*zƸ`I:-UuYi()3#|3yC5-Ұ V$w5R_RePGAR8&,`XU݅Vّ&Yg:%mL)UY׳ DȔeOdhJOYVKБgFi-'F5;7OU3K9q5r9ߎe,Z~^M-{-KOك_z܅),Ym XH8v{eG1_2#?T5b!:LqO%)+Y(*([%|??:UM^! ao&jl~@Z6 uu-*2;d_8(\^icɀu`@L-# ZHƫ9OC:;uo7E &<'E &b :~Zf+ehaj5UDٴr|T+O&\<;1"հB݋XBvRI:U! lSRwD7g/_aKSXaT7FTXBǗZօk>vGV:sq--%<+ p&?A꫃(M{ã^Nn[v6OnPԚݺ5]L# Ma_`A0uG4=n/T<,ݺ&ir\^Zd3f}ndR0 )R[*g[jWHv|rPht:-\s;zs9tle<ן NX NsU5BpzVa4 ];V U\J" Uix?eyhH{ )b>\D%6ؙ"KJ0~5QS~"nh2=T>Eu&k[&_zymr7Kf;g;))3܎"M;Sbu|:&>F; aZl+uoMLEJI\] `R5 f^S`6`썰Ѥ5a(_+ 05PWcy°a}RITj@RLשӘYxl%xgIz7)"=4أJhE8&^^"cg[R:?}9zvaU=K1w= dbdJ¿Lak  jcg; JW|B`_ᛙb5jStvR m+%lnDޟ\ڳBFZƺ~03c!D:歖i;%F|piY{=KQ4J< Rj'-ġ'9k(zrV4^eߤ=r9Wg-s9tr;g%o2VVUC>űl*W}#,\C#$!)*ʲˏIo뉰Sy`eӠG@%>S0S \QsIeL=F>Fpv8=1vAJэeW~MTMPq?\D”k)7dݕ0XW'r(n-˫M)݋rDc&ã's'+  Ein2'd\3!/'0{w4ck=k>1>Js#)W,bn 5Q(ZMB6z] ٳŚ 7j$|e Y,5# vrIX5t:+'UGȏ\L+4V\7v0h;RTx04o,#-9ڕvâ]%m@uʙqDz~u];X,f!t=\de`HfGxLBE4~&y ? l&@sfeՄkMAdOg?~{L4[պZ]hFm? ^W˷Zz1n.r[֜%mC{4}?m1=d㤦GZWWį$=FͤϿQT,d,ιW%s|47 c<֨HJSe 6hV Bs-d*k]/1?yMS?Gyi)I3RY-@fo1ß|,SeNJꏾ-b<)l8 Rg$@tfcR$_ݣ[0_q_M[BE$oyV9Ymȑ"z4s9)`Qlc#&_Gh d ="e u=p=+{]̾>|6.[>J8\>2JI}N[RJ?ʿ#W*i^&zE)_60fa6:§"nJU|eʨ!'dB$1)jޗ_Woq6_OYp"(µ .=cl(Q;( <,bǢhuӫl`6MU, 햠wnxXl7,ݘ%f|k Xӗ:R! vH"]VzfL11L⧬TK.4 f?P~[˞ĎɎ =u}-Pu|j*&+ig۞:a񿀧a'*ﭦE47|”T`{VZ"ŕπ!jg2`v\'PN PbQK_H6,-e@3H1*ٙwK a#e!# /,mu?5a#ZD S O%_a 3۞Z qu[0vfr_lU&_;@'V p5_C;m00 pbςw  VVGs<'(n'E‹{(udR Jbמ=w 31{MkVS~]x;B}IR0O ?Z >n  0HU9YVp#O& ϡ͞EodY.Yxëavw\QF00\P'A"| ȇ$J7"'69YiX ~r)P&ZKo7O3" t[$?(q J L—AKq,'z *|5HzIv'Yf*W>n:2fXz=X6uH Tn+>OôpCW` @ dBզ/@ l[TtP$}Vko%4(ջ8wA|c" k S 2 :u"K>LmNa4ئpO$/0rn5$^ۤtІɞ"|D~gҳ v  +r2EDLkd5OQ 6oSv"K5|#{Q4;(8 PF'@HYl` A"cpx"S6ʍ݄zo&-Mv a߅)dBJ¹rx0᳁mY')mF"A&DQX"JJ 0F%ЍP^nkQ 8؂Ok ؓ r0ƚ`{X c]@JY)ވ;Ǯ$Dw(h@p&-vOl#*ApUź%O.N\oZ|0z|aD9ȊmHSD-\SC8w*Y`H,t@"Hd, d7mi@ `qoFI T 7ġVXt:_f%=jy՝;x+Mp9Ѳ?K _0c,x9&&*>-'e+?- KxO(urmTm@L;K.f qzNo]W_a*^Sq/!)ʉD )PJo6߂"睌Z\ ;KOKZȯ&uʪ5l)'fDE5঴/h3ge"Y!hӝؘY†Zbe:X3o׫ o̜ "KlM nԀaZ? z5 &t|&hr@ԐklX'wF'hB/*0eHTF*Ƣ>%z5k-"5ӶzY&9جuOFVX9<{LR!.Cɖ3``źEv,ލ5 ‘"؂K*k`d9 /l İ{SQ ;́\eϢ Ⴀ& @7 D[ٺ{P%VA1W[PVOmĹDz:xņ* &rYvp. 0s;G<ՍjwDٙv5̬DQLpeYoݶN!:,YeY%Z[}X%lKGdFfe4@&#+32Gď?.y+f4 $J1'5+b dD[,Ҕ΄ :$J%G#)wL)nZoȓ@)%Iظ+ġޡ˶'H&R ` 9zbXO2qG UWA@F;C +\&3o :IyI͂*y"CEQ蔴LN$ u<[#9B)H򡩲j@9 WA@CrEPJdJb # fY**x8Dk2(K-GTZ/ ߧ?xtu:#]s] & )!0\T/&3 Y D}e!rk:0*I2;\Gol'3]*4ݑu+7 B߇\eD ˼3H8vl`@9 vDXr44e~QhuÊY()jՕEq3$yքJSq$l>ɍe% !ͬHY;2Z:@1kV@h?cwWPaF{2c r{4̳H FTbrfp JYWRAy/!KX7DuXEba)QRo)Ye"YjWX\qAGa˔)j~6oU:úe\36zHbtZŸ,?嚆^27\Ώ73#a .b|W?eԑ9>T!U,)(YQɔJJBdjO:E]¬/yxEk>_}rGq#( mwL߬/7xޱ(V4`QFW4Zܟ’bzQ]xC gU(YhRYsk INM'&bB% #r_ѐaFOY` t9uda9LdH)&^lUs,>^!mV]嬀z i$.?"1DJ0|MJM8Nл]+v4y]9:ui#ئ+rjΝ,s7.VLjIK BAΞ0]R{>[mriGEMM变&Ċ&[*c3h_:~(! hdFYԸ~٪:2knU>?XaP>tfJl2EvI@4 >N?WD %&nsC8mi9Hg> 4.<:PX@-cBeΠ~oF?ΰÎt;bɵvPC`kh"Ilb]#'2a_ѥg l=?ң({ܧIТLsAglݨ } ;'X0 zpH#ݙ3fkDV1cB1|MMo_j)pb-c2q}=$j}ZQ4?PއL+W^r>k;J=Euvxv1%μ1WfW$B*lXDJh>4r(]`oLtXP=0L+.ݪ>QOiM'*n :sʒU2wwiG >Ew[-jI3/nCtxn#s(UbJxRE29/VGf],0oFBch":g- -ځgM'_*tr ^ T QJUhp/j'8,x7c L PW|Ֆ♺\XөCZiORPe}Tiw6 ֎L\H\[\|aw9ZΧ*K{弶̛3q/7*Ul\:͔=뎗N.:O?&I'L u'Kx]-b3Jo>L2k՚E-){ cMO)g@rHhpۆC$&wiiDۇU"WcmE@ oj w<1SavCd4Yw[" 1M_>OҧUؿj^?gJ0ѱ~(JCؖؿjEޱ/p}uH~hK1P~^k_lܟk<3v_76}S2#-u^&ѽ/2/}X-ThȚE'МY2y<>j̢,Òg_h0Yx~VTOTV%JCsX"g Y߬FEi?Q5D8W:j7+A#UL|tAUAYë+Vu;5brt!iʝz/Z[5砿;j"m}h맍!rڀ?oiRdVb< 4`AƟ]f40;X&%[SHD: N[ϔ]H/E{1_{0bO;u8yxO#U&եՏWJ2=unq}4we\.Oc 7%s7w5Ҽ]}3d;͍g#ǥU>rzvjt+/nj$=CMm撵Mo/<'1\X ׫2bfX ?xbRsdcUNtӞ]ZRΫ]Ȼ}gUX͸Rc7L[cr Ngx҅ݑi`1߾No tFL;F8M=UM)wjw1^G^*?ڨ,2=2Nxڏ5vQЊmeM'ְ􄝆U,=wW]wjxse( WG}SS-ޣ{5n{l=;~Ǵ㿟~tVtX+mu?w.MU-řHv;6:qGQF ?uV+=8Q@ D~_U,,z]7E+!n? /Ŀ{|Lz08k=LB ~bTyv~~Ćռ/}\X`|ejxԶgLh! KJˮk66'-WʤK~2,m04Xan?ܭ&o>PZ. (y}K/߭l.a$JTJ;CQ{i.'B/o-:`m-34̛?׿7}[Z'&K fd9KM RrBɎW8a)6፲x⎭CQ3%U> oD-6 wx[#+rXF8$fsje:nXf z~1\ T)B;f3vT{;=Y]ʻ袔X('Z#?OՍE2'fIĕOe:rlI[%VDՙsjf;u<5ؚC:oCO(7lA,ϸ9F07~Fq}YTY誝>U:L 4 ?ӳfYpzff/DeeRWT6R[EM }k;-~l9;\͡o3]8~7H`/VK#ו~g}gmw3#|im۬`hZ- b:;!]L 2?_+pmk^ ԌCpnWvnwvI{mNxIqviMU)/|79-J)q&ޞh{ƞkuN:[.E҃W}ߑ;M#kG.w@Cʟ:=VJT3ք_=q|JQ7?Sr0\?GH'NJZS+qje2mZ-CK[*{t -o}K[ض@K~oK[ ٶ]B3{&-o~K[ضѧ2yLο]%]Z"ٶݴ-oiKֽ[hQw>keG7N˞O͔wmI:?%[[+xz(UHY\P3(~營}c3حveM( uQ꽺?}qdg?y廻361;&.etJn^n^M'[cr`$i 7 F5݂2fO-VOWAnΖ}8u}n╍onuw)z}y4{?켰LIKQ=w>CsC?LO>M|3Vz_웈.{9ʻaPv{FN 2jO4Fai]c՜΄%tqݵƿ'nzڳkiD9YεO #ߏ\gQEC26M+w`VP]t]+u׬5Jfɥ",p5V^)7Pz_ΫlU٨V .WYk&zeL L&zYL\KeL\20qɘnjf}\(*SKDFLQ;y'B7!u\%$bX/vtsSQĐ۴ԯ~-kb]cmK6(`~LpbsԸlL,w[7 :-UozK[-k_KZ7n2m١myK[zm_KZRw73ެmzK[m_KZײo{9NZlr+lޒ–%K7ѵǝĮ^^FnĆ]wBLS DӁ?ߵT(};_+qLCU.>"=]>[sD9stUOBVJLSKMN6OQn@hص#Zr%O6}dn'Oԣ\# y>cӵ>WL/-}^2wS;F=t.}Թn"k9f=cug_̞;t97;/t/=aquZdw95N-H]'@q*ӻG#:><쳟}v>Jd^7._|[RJi^wjsֹ9#i8l ݃7_ڡv\ ,O+V`ww4ax f0Z/΂OݑqzGOY-㕷VaZmn]F:ݝw;tf\{v$:7?WqNlN:WyfkcO}mIҼpXdNqt6"P56`ҕ4]PAWuPŋ傾(47gnuh.HpXH U=atRz/ 몧 LG{72${o̸K`7 4K ͽyh~{8W +pi9e.uv~ Rz㾝3KR ͢^E 2l{9s0b%\b*}0^)Ґ%G"2ςEe únw,YGo5}f^Lg~?E>\R)fcm KU<Ōd"="o?&xjekv S/= yj>`6!Y/a>,gdK)cF*hGaZaKJDyc'uMD[Nk<) I͑E%m9o smcVV)E g͆ e|ݍ7|^^,VRi*'6h9LfIeּp\4p wߧ)ZmmQkhaõjLܜc|;{)"^gGo }y)m;~1~ $$x;$Jћ;NNa~1k~YY,=YCg̚_n̚K0fͯh>kF$Od#Ȱ--/<3&пfL|̘@9>N1if#8u^ywæWg8E3Fm 2Fqv'?z3%'kڥ}Ɠ w0Θ7Θ7~7F/}gM;bp}LӘ>/2Pv@dO3K竦mΞODGo<EYkΚlgÑ x@%oweSs<cD[vF._{5#(AXzJ7)S>lLR/SaMfS*gw|gLИdC$Iv=[wh(|)c'\^x#(^Z#YiSc N3?3gڙP =d95A;c&c:Sk?lc̏p `1}6vA[ա͕1m v|~obPt1*` o#~pUX坟,|0|\.9MP%jxx܎'HMLٓKe*AnQl6Sxu:޿LE_:Kmԥxm^".{HK[^ 5hÇ0,ێhdMEϽԆVny5hbk ©Sb.z;RΣh .$kY6$iqC~fzYsߒ-o,p/̺=el;[' 9vFB]G8z}_fퟳ'p>}Aʱ_V?VΥ 8޹qww6 ̓$ <8Wm?g]~[գ=].17%PCe7yKݟ[5WŜznO;[QtC2q1PVU"5Jl% ߮~?_OUt%JgS5X5uSjb~tyJCu6J:Sx?{K&A;7w7EO]vMzNE&?}A(,խC,omֳz[V ZR¶mCTxו-b1g 7_|Wd!56}CzYSMmYv%=ul܄0>lvزM-ԲMF(x-k7UõdV|;&c&-lڲt>}=q|V7;70>֮9)s04]0j?>Q>uvL+ƑTFv`!Hkd0[}+iw%ôrxѐ܏f̒c<ĞD)5'1\Zr*J1D(Q\p]A(&cF`zQq;B4҃?rֽaW>?]|Vu&s3{y sGש>?Z~Y:[Z8?vo^@N6e6?RKO9{?ǸDJƉ.s4+63WF287.]|.a7$6ygw+kk7\wMtNwWw2l]*f!(d}~j ح|tġ:j ѽ+R$J$WU']4DDEJU2"V"W2h:^eZpj_KZNt?|SofOVXږmizK[r-GRԯh,XFDZ-UozK[~-k_ӾywMmnvZn-=oyK[n~-k_K)l K{BZ%-QozK[~-k_ҾYڛlK{?el g{@eW8Lgm)>3?G2&Rkחv}iחv}iԯ~-k▦4-Gr-k_KZ=-UozK[i[R="mgQ$IH JF/F}gsթ6TC?_SFτ8{?]jm$v;sN4,~|5$_l] OTTᙷ%YRE; ˔]UJn!qbb3y6-$sl`%rFaqiFw6dxT̎|t9N温Ix(~fC08lE(nA6 irKٸ/gصc? ̓|wDZ{fNBk? #DFM+MIM K\I4m7K-GYj RFHd)jc5K?1Wt(jβ?(Q&Ϥë T " 1qcć^|DFo|{c7v[Y-̘ ӭ;Ff Xң-Tx+h..YMyƬה9ioG]&KZrl][ױյi*v}w~S~Qi6;_146U:yOE[ﭔFccc[nwfO_ \k,}ŻؼeJsI+>Ur2+mU2,AI^A(<>v`1&Wi:EfC Rw,onJݷQߠ*'6(7=pݐekR( 8//FW==&n_g{1Ƈ}s7;4jF"1qeRT7JU0bzOjU|VRԯ~֐-MoizѶmKZRm'-+RJl~mN0?t@ֵ{Xg+3OAc$wt\NR,GdTsͺrKHVӴkמ~w3 rׯj\Cjly,&zKFxpծsgj?rX?K(4 :m%潔„yQ9wd$M,/%Q 7n)pvdќY}ZK k׼lR<VE6a'ϵb)Ezw)yv:V25K.YP+T*DEU aVeZPUPt*7ͪܬT%\xŕ%b"!˘A\YY{m : k=z5/H<`e`9*fݟw~e?X"NꠡM]ϫTQiaJN-; SZܚP]!ϝ]LϜ=Q5aH9 c'={>9k_{FjmJ9bGoW_.45 </ @@[7)gt5h\>xOvp;=5eՕ:49ʵȣ'kΫ6ysU6Vn=#UBm΄/`ZgO[g |w O#i5oO2ĢJo,vt)O,1QٺOߦccc^T:o*!y lJdi_{*ĠoKTd0,͊j<ΌR>72ϼ?KVVn'1y[(2YoƎ>$tʰ4(n3շ}4Z,MחMbLsc0Pi|2Auc\@: çk *t Rh ۢ^s̷ a}Q/,).0cvk/&]l'^nNYN$^ݗ`B8n}3%k%4bjOf(Z;ͨQnzhEkcGS \Qvcryw۴T}LmξN4!qS#A$no(|)G_+=  { N &ӁDJutѡhB]_zZqoKQmنfw5ׅ}7wZfv5=7F7pd/dWR _ykU=[Bڇr @*R˕A3*sJ[+TT%JgV/W߬_n%Z%JW?J~WJf%z%?JޮJޭ䇕W^%߫JޯJ>'J>J>䧕~%PVGsCu'+4gEJT?UoW+W߭~%6oy;Ä\ Eqi5M",4/0KJie2/b1ַ2wdVR2^ۭUx!i*w'V5uo ݬ6t 5`idWlӅ bsӐ-1,^z д~NQOԮ엛,cFFe}u\<"@I|d?Ҍ(y9&[0,/ƞo`>Yi*Gj-Ʃb2;0ǙSwN\+ )iS2۷=AWo2 lH8:9=BR^#G6h8bs>mϜJi >ƛS9”'i:Mp'DHң `w05h[T 5 Y> 4>, 4s邺Y괄C%ct2&\ȸq6~6v _k 8y1h~8 QF(#̏=?ɤGUff{hV@T15~4w!sTfF|MH!ahY>W>Hic)".u';ħ"B!ib+y"!krdkQR:> !.}Κ)W#Pjp iB}L'z?PAt4q: ÌW/c"l'+% L:cn|[T}bNԤ`jSigűuY6 S\qM70mZzpqJ7<!V@YJE@Lu8|WLcgBUJTzDij mN}&= 4b- 'ٸByD)Mޛd A( {C/#";cQ`ZJD~;AIH8ϟf^@H@Sf\mTzY` K{ּl̷w̧>' QG#,_'p pQ$v!)h@1TclM&d3A,t:3B0D, .y|Bc8MJHߥK9'IwY*d/ʋG$s!Y@Ѐ(Ӻ+=J;TFkZLG+CJ=\1%I;fIR;ӌHM_Z?[HK4q ߋf<'6{;̠/ݎb g={tIo]L k/N(BjQ; _ySH{'Þ 3-^Ix!a1ê‹ )SJx -UFCt=A D2ã <|"|3pH&TL1$IRGQ(ҒjI/VM=t S QGV H@m$1Mc^-yL#"^zU%2 $MzM86<4q&Lj ՁDFcC A] fgsye z 3t%{x"ܢ$`eN=xK O\/b4`(LF$//- SG5 Dd> P{-c_D/Ұ+͌nGѕSm~{<5Wa=8#[6,3 2 "k{ QSG-Z>B1pa ^B3FI4e2nd7,K[$B%jAw.S)!37 8zW4/i 1?mQQ,K4&0BPp74 a6PbP)I<̫M-7 XC@^4:I~Jg$19v(>+G}LSڱJ(uyq~4brust%g'TR;}{o4蟹*7N*_вF\@TlwOT QSFM&R>^}=|Ԃ'Z)K3Kl9z=8y5uC$ ȅ#L)okzT~,V۝D:RRˍd_n8mN}ЍH /TiHk6XġC~`x+@J+*W"1Lhd$a3.1wh0eL%p䅱XaRyHLx )aHkM 9W2My#^9) f9\BK$m}b)Y,8_).B%qIsU+}i;,z {;{ٽKġ//_0FBlUFV9#^$+ۆg=`fp4\F+-h i\R./TZYA?ʍhʾ#nTGAH"$MUA LR*'_a5Ix@D] $Su: *,WIХq˙PSF,?=ǧŻTsخadqC\Hf@YĻ-H#A#l<JВ7-60 _u)‚|`MJ3UE*8~!VeJ`kPϳt4I) CN 0*2ֳe2*h *£r{N-TT2f>p L1`eHOy:ݹ\6.7e껇X>|G; bckM2xe]o-\O R[+%^QU櫴mQXL cĴwHi {$fU[QnHE1 mm/@!D`tLhL$AT"d=ǖ7{2XRCR1G,+@ꩱxK [=צu 쌇Y *᷈3)=:%_~ ZQ:=5ae:MMĆl*t܀/e=n:gBzTa^]KBjvE{C /0mj)d̐Ahm+?11(f_nuA}Z'?bꠋ!вm JJy SH~>fا UAF:7Z! O*54oঔ=/&am_{xL_]t:3^\Z~gg UPF}[֮F~rpXP,K'BPh4La1@+3h8[Q%C1qCʠ66\haoR+!љ(25L(kR{[[]tx@)\mZ(#N 1?0-*83@yHpO(+E.f<ZC0j;{Į ~悀Т ltIrN;؅DO [ǀbƲ5i7A!!@'VKB 2=!+g$H/WPGL ;J~3غӜg Q2n#%f Up6Z 4>qUgnmQˠ|vHDM áaTFԠP|HGS2](F"jL}J,+0hߡ5  q$R,!n VaCa ِ&u"\p(jH9&>'tz(eu4;(r5+uyX@#,E fG.2Alz"Fc{@qiZQœTTuܓG<+Ph<)ϰ@J, 15ff5 ãP xS(+?RߵzrgPh5X3{pb!=aBOX*Þ(tRM%Ģ%{6JpVaW~FTBF{k*E| v>J!LQcB tQǡYL"TWAPO8wF5StH N|,q28!"Y!_H/F.uȷ$f4L=| 2~~$KbJEUQ {0tkH$顪%Ayy?o?Ypqj^W/r_KN*U7'AW ɍ3NN Y@X&KOh䐈!G ֞mOr܀0ёOvS^P W=,0řX1x ) )>`:alka=qK*6bT.I#0 fPua:HiK)O'== r&+e}x];$` Z 5=MIez|bRKy6Gn7n<)Ț?K)3!ѹ7U*RHp3gBI[,Zhp ,I׾z78M>J20h -,0 $r^}ΔZ{8L7-,TqX/w9+<:!%]zd1 jFZl:+ޙ1LivUO|&,%y/<0M]ْ3}280IDKV:Iz)|M]`cJ,N*4XE gc*=&kΠqFdN>dyͶ؋ 0hGz`u1G8E2(Mn<{A>2 MشxO8ZIPB9> oȆ..oVRD,?p!au5v88Hap#)i,0L=)XN&2xxnQCȡjR(_\ G)!%(b@tº[( a ǐ#RfGEor]oǬ>H{wHx=kЎ?szDd{6dlHA@ {xD%1 oH3 bpsSޅ|xA=qFs ,&l{ҕ+R=S >-8 {؋HjÔk̰Od$pHN" L";]1Ola" 8$ !ȹJfQXə#_]~څ=Ù_8 G 7dB8&~A;l#녚@44 jvi]M>"A,:h P LJxRjHDc `RjH<7#UDF8zHuOI Ez:wO 6ϵ-[)(Wҝr%x@Tݣ:AFuh s6-(ǀ)ssh U :g3\NUJ\m*quXgAYUQ3$eL (劌U}@Y.R\2޹TE"OPȪC ]oJȤۙ4 [|HAz Pu|9ͦ0z\7 nGb4@UKm33~c#ce3gd|6sffR)KSb˱&wJ3hhޠmA+*ҭtҍn)瘹JI$_'yg2dPÊZ#_)xIJ~dޯJ9q=>GE֚rsn^7 O/*cTlt]fcӋ_r%r_TkDm+q&[Nq|Tu򕗿3j  _L앗崩8*l^yaxPk,ɟ{["Mv`#V7a߅jJYmݩ6Vi2t/5E5+ߥPx5M|Q mmtFs:E83_${!pOH"\ oO*$aȝ^$l:;pn+x%?-ҔmFD0:J#TdBo&#H(hܹ1?|̐V>g}cc@ѣdsz(9uB7b>W C* x+6ۈi?΄= sf< [5y*vNv|O~´WY7`PXK8g{Xф&1Il'H^dG(2~%{ !/S89*۱m<X8--f׃[#;J7ؖ#R ⌒ȁG6N($E Kdd.{a j^&8+4P!2drjK$!%b60L)X4#X|[8D١8w wl).ar{$Ly|`"M{~n" [c`;lPES>"1ƨz6 ,qQce{FMFGGpMWC*[&MpR>|MѐGa GR#"0JGl(bgsp3&EQ\JK {,ڊۈW&ĺvGTbX!ŰB>v z0*P~ (ͺ:s Fʶ$CN#iN,&8:`Om!v/Lr Y|(T$4Cc @'y)*cs 'vl=qU7ٯ R^a9_{1@( n?mW{8gzAKi^c6ooo,":xs(TA _>ɬM2=B1q^^TB+ BG1'Hh#NkG;~,rx!QE B}⟘9!8{򈧖{$kg 8kL:pd. ){_S?OlA8xfD?U[xB[7OC$E:fa>YCG3s+0r=3ʱŋK(w؆!a^G- aUȹ'FΦYC9akxW}@|oO#ANh*924R"J9T~!@I.2@I=d}@#W\@0g d|Hɇ>K:3P|t%D{Sq+ K]GA$@ z 8^k93D՞$9\ņ 9N8}`cr| hNΟ%'CO [z|΂|Yhƕ~J\Pe[-K IC9OusєJѺ;eV9̊"Y/0j%j"'>8N5  5*F*]@*@T@TPƞ8i#3i#3R bLb [R Q =`_Zzr֒'OJDr9lS fيkI5|`4cÿ\*7[KQIC~{(.Ž/pP[XiFE#+. “.u4 pD/" 8ɽDlv$M`*&q~Sćv_kqȇ0lRt^^ *ho0"V.d;]uأ|Cs?όB>](RߎO;\ $'>Oi~)0RY-=+G9mxNh|']Õ%e3ܱ$8rd e<'oRrMc^z6`p%7닣}q_ỳ:@k;zb¯$QG 23#qŒ"JęQոia_E& =v9y4#\5n~´߰܍*{c,XvX&dhXNgL1(wv[-,CTV]!04]ݽa錃8{Ɖ\I:E n"U*XU\(Q~PQm+5BibDyakɁ(IH-{+V˭,^mS H9Ix=r@WZ93|FS_&9DTɦ_M,fqpSM$G 9JG#\V0яj$R[֘|/grY=^F4@|z w*(/m=1zO@''FB4`{\OЭh:%XsWcԯtx>>]1. K d׾ "ą>/0ܖuo<"M\&L@Ru!H?L_%lKj UHx -6p"W/)ĜC!ݠD(uaoPW  H*Pg7,6QQب(0 N{{ .!?0 V=srE$ ֐(ǑJgO]J~$?E9MG#5Dr&LCH)aR8FZ"}DutXZ7->˽ŧ ױG3ѝڬT a3JHWvg*0)8.,pS F`B/Zp43 1J{/BPiO>Rah62D p[)zq$ $qg,.6 0BÛ {|v1YL#@7dG4kvY_ q %!>=0-‘*t:s3vKLhߍCmfYqIk(45Aݘ\6z xqm$~q6DYLڃ o;!B8Sk+6IGk 6P:,OUSr:Ę28}eT57}U<[^ĕR^Q'rΏ=7aT/P:'T(wH#^d D:vi'ICTr^]" ]#{"UN9a3U929cHyǞrx&#Y0)/t5#U5[:[02=2/#^< dZ;;$u8}#% {DtM?Zƀp)Cg+Ih2X2˼Z|MWcG6j^wegERY9S{M)$)$#Cu|xi%"8cTᢃYbcqNIy`G5cs'IG8)I,2f(N{ S:>t]$Q%$=GR9O)֏M<J9Cs?*ڛ$<vY<ésN2D7#׵ :䯶k 9 Ǫ~I5uNƺ㬲fLv)ٯ>SҲbM2=hНj(C8Fz @ޥ/? u'`4o:+rӃ'81@CާA6.rrNN,!e?4T ܞE3aaf,tG"4TGE dS4E>Սӑ$=I.IB[X$!a5a$PMMH>)+oNrx$żsV?r,ER&Z/(xVY_ d"|4qա$1`a0׊qàrM8{[UޗN9+}X~&$BF 8~9%u2(2؇0cPYzyIL,4QXŒ`dYVcaaS LqwdRb&Ia kWT`?!LU "=iqﱎ:+$&'AT@Ύ頣{{{L{2@@͊5ƞ_`)$s`;y=eIF R"}jqT& d"~:DM4 ~2옆mCD|d z6#*㕻kZh7ՠۼW5L REcRQG8bK{q`l&=e+-nH(~!^::==AH7{8A˝^[&D !S4 7lmǜr%څ$vu*]%IHnQ;C3Pha"t_ESA$ʾ{!_YZ̔9PL.)B0;XG-2D x;j!6q`J[BT Ajb*Qn*I ¢a'ALUL  "d$Q˳lsGzґ{\( A9(,-rȖHybJ$;S2 -.6U *Ǿ A ByҖ8go6"|AkL<5 N&p(fk; 5nM,K@0`:%RR&aV_#>Wa Ճt ]o~ 8 ,]~.D/J}Gj:$hV7̸i<%9T|/Eұ%[ Q6XBiʖPU`wX8˯J =^Ih{yw3lB #5)@_2k;͢ 7eS}M=oEN!5ѷAYbOH翂G9%k [nVW0x|͙b~φ 6BQ}92r e-Uy-'ϰhCL0zLJ;To&Τԣj:'樖dw}W_״;2oxژ*2sf(Eq/h7<%2l w L!5r=rh5xF<~1Cu2,ǯaTi!\K|V(hA!9T}k3+/F%RVH9,c`i_E^RЯF/E쫤 ]Q"3Q j {V‹O=yG9V b# |W[` wK؅ ߴTx5 t&Q.9gXAp$MpU(U\('Hn|O,E߼/Quu:!#1 T1_^YMӏ AcMb{I 7Tbp ӑsIDC  @>R$$d  87;,X~'=YaP:t8$vhӊq+#Pg ߢ08` _C ,ʙ K^ H!_&v5Dj5,b@r;QG,)6 YBI!Lߖg(GrHO@JiMq9$* 9hOr)bŨH;8K*`GR\.IT!;h˱RCw0@D= MxX %Pp~aM#L%yt5XR IRIDR0i{xꁱRI0 ͢/CKȶ㜲8ci!==%AC20aW|siЈ<;Ԑ'&Ќ.k+V^Ij1prP-F8`*q)HDܮG!esզ)uN9py,kRLl^DJ^ 8Xf,  MeFHyAP~#Ρ= ?zI)+j#ZC%M,4lqW"1 a1BtAֱX/d6?F"Xhr_epRƈ{bшW +~ITNթR;!3R+A*a}Z:F$Ma'1w`F fULET@Ja>E͒b1LnwXɿ^# < y9ss`[|o(<7,@&|cO @~Ǜ\a x?1:wxqMSDݱ< ńG#RC;CG]}+/CϹm1x0UH5j#$ |6av3lYe-b4˸7Oߐ(p|W.{`{!+dxN9Mf)BeMUé N#ǪFEtc\:RBT$19(E P>"{teaI'({`a< [h)R~6gyq q.Mb"~֊(V싻gSCG)g"iU$͊$j% q1% N[b 2q˔8AqbJMJH_/%.\S!#"BP8rHR1(o8 1-l 9&x]a؃N\=`pI΃=A bm9V@J_Kl;f!q8&)ZM3D{G%6Ȧpu4T\!! Am|-wzH)sbHLh ͮZ-3&O< aP1gX3#+qف w0BP=qÆ)>aq/ԐS p|j w_WUe?Dd" q,.~ćZ?EqYOb 7cXDn=_]Z#< /a 2ĀDvv;,v3?P5?omVWcr(~ZLZb g<۷E3~873(MiP2O m4>b@ނ1ĴX^ao1s.vVDŽq㣉xh"''TBb~ c4NxDI)qXN= {OIƇ{nEs=Z ,Ăq bvx^2 zPyFU\03䣢l|4rc$HAQ(&*:sAJeFzY$敇ØTNhJ4 m'%8O *8z#q$teWy$J|h=,,mI H <˷}CQ/a WR* ") PIJY)"%1!%+WF yéc%upB I'`/xጉgG$P,{:(Ei JR=JP%xWLP&S| [>Hx8sx 8b1DA2Iw7tαaSN8&FTuH6qibC' {R"mĀp! * 0\@>L qj2!|(b݊t*7ewD+82H2Ēr*Ř xk `OG\{Jz"sɰh"mu@+QA  `B0 B$O#EiN} ~0K-b )XF:T:M7AoT7xؖ>Ic0Ō=XB2 rW ƭ~4='j,J/~*]#a~,wQ2. jڳ1ǐƚJ%Vp[ M@j\bE,d$x6\%L1JtUн {+,#ƤsGM-ĺ,%vKHq uKєc'psl2%=DT_cKdP2 B>^0JWg h܇6vnFїCR1Ha$dc†{C<|U <LRi'*Xo4U(H?Խrl,JfrGpFҜW$/199=]Ӝv$'j5>;8Yи*پPP*5b; VtV?48zzkXC'B؅k[G$r%X=ivdA%?9h*6HvpN?ܮgNݮP`YV/f `u;/vOvJظ`UNT*f|򁁭&YRߓlw}z>nE>zRE!_-Dg>:[\w)RzWlq̟dZw7h5n; |&>7KT4>lH3MWkpĠxj֏߶M~΍kZεNF\Irh }v j$i: Gj(*q6ҰKʓlZWzSk X 9!,22M/:c@_INQ| UvB]yM6旟=1~ģx &>P,4Qh0.D*mDŽغV/. MJG ͍ v% 5hpswcxO5,K/(BVoW/ikk/BG¿Tbh^L}F3#BZSK̷Tげjs~q:>eWSmjd-6ZDYhwu9SY ,؃2| ٕx-irŭuHZwfJ~3j;|F Ri?^3XzP  ؓfh?n Fq7ٓɚjÍɂ0_Iîsg0:hu->5iä"CRl9RTUms[0o̒K &麿]Ϛ]~c:w~zve}Εk9mmdܚ\3۩"&iؗpǂ.ͼ.9Zj,.~S 颦嗩ZbpBtنR:Rcg:|^}쎮ymb5>a`-z0ր7tו/5rWtR\kBNNvc2lZl V BD]iR%H<{bz<5sw'q~Hݕ0ʳKHӳRGJ{U@HS.5 XMSvR(*HK.bί~R ʊ߮%_+`J~"j:{iB@vuXVIۧ̚ 5AqJ_;Q=ٓ3b?2na 摳/_ݢQ$Un_Τ7^~E1O>}UK% ݐ@BK<=kMfjX.ժl٦\k uzPssknX$V&؅҃|%[z\~=G_XeV(gƹf̽{F%gE2#C EXbn:oWy-kAB9@i\]^߇t{2'wFR}ǨRrDu#m_c1PMS( OFTo< ([k< AJu^uJQ.k/! vz`4H"#XX,-5m7bY^z,U`,=-P]#YT8k0f@|T*2d|e KU}yFI=FلRc6/6IP0!Jw-׺E%bj-j)Mw.Ezc6?=PCj%m-#jXƽLW_-cX Pu:?iٱ=v^Js9olҿNrc?SLңqˍֺvn7v3sppڼ뷯Pܥ ]7 Ǜ\Zv lc ui%V Be>WtNqa=n6F$˵™M}[٪;΅fOTT*uk7;?N0N j X#9:nnoƯ;\I%lg̚W=a,abAΒ bk^u߬55}b./5=KfH+,~xtS5xAXĊ}xO/XNDj6j8 oT,}nWp};9 xxr#;m1^h-a|UExZLEh. ϫ ;[Y̥0y.hNvʛȒ;yu꠿jvu|oF6K\I]1Hj ftqjMwU}W҉%ysщ oeK*\ [0@ fɫa4?VZ6bAJ?4Q__' Yݹѡwl\?#ʴ~,q\ts&_{vtkUY"{Ѥ)vō@&UgjUŅuTF  =zb_8[GT .'/륗 LWZm?O!>Zgv0 ?/$ O7zSvٿ;g]g<"!"VThvYE@Gx.klu.yW62 btW!wL PF9\EX_]wql6j>AЃхY%P*8VUemŪ'G$5I6I!;۳gWs X;_DhgșWoW/k:م^"Y6ؖ/Ю˷DrareWv3R&v'S/l;A037~#`o*jrno";^|ܘߥh483LSPJbf_jU2yJPϼXxs>qڼ_T®=݉$TH_\0vWhZ |}*;7;;7fu'ŋlk%[*lb+X1+~|sng|XI: `XE/)IU]ZCmoVjoڠKA4Vd|ͭg\v}o-fwyOC;Rǝvݙѩ@}EAtJJ.qnh%8x4е[s0]T/-QsFU~j4zWEK؝k.nňI(= "dEfj'=AF7\aoF P]sXGƇ>рw~ь$#`x|i漅J v;b19u+sl YUZ R4`aa?]kDTqUbU4ݟC[fOTFa黇fg;P{'s}v)現cڗQ.lz^ /}rP '.ZfM@l/p Sf1galÐ1Ļi1}qV̓LⱅATjr*5E.6ؼ0ZLe1ؼ/ÍwZ#okVQEb}O,Tk0ӞRaBJU I(+L+i̎ǟYkDO@]^9F0qvח!/k2hzջAԷznAU]hH7VZ]݄/QI9S906dkkݷ45x{^~_Q̆1C.1+.Zrơe*.:_\6];y)ڵzNw9ݱXM;@ѝm"r&[ L:Wh|-M8XA~tnG51s^_C4W=KJߚ;:oךL0j rZF 3 +< ~Nz;+ z.ͧ6`>eoJ(*Yr^4] M܉[P!Yɬ-a-]+FCn41kAՕ_e E|Cۋ-x-7.垭 i(H̑J#%7vɀ6Nu]ٔafKcqrwq&ᩛo}[Z=l۬~вLl=_V8Ry] Jk*Lў9ԒT- i^Wgǟj:%SZݕ״϶~d{4GTko,Rܚ>,Uu~iWFaWE[x,pӮɈTxVLZiM-r9Jnṧg>l1|Y f8v-GsM"{s꫹X_x(w:&KY=4|e JTw-2ޞ7ѫƛ|my]š&CP~ЀT_J~.U+ f\}Z>&{Qj_npnnr7_--[`'cRGgp v3^LN|* Riǔ醮&侵]xi^EJLTnTg{~ްw G.sJM+R+UAsUwi{q`r&40B74hOk69'-nւsM6iգM\ل=RÊtkr[i@hm7^yzY\;2u5J5m_Fll}#ZLՄUYІ}^OC࿇|©|*u|x;@I̻5Zn^\0YJs̺7o%yO_~܉_c"Q eWu[r3D_N?5AYXͥ +/^^:su!~h~fXTek&[$t`ݲau;BG{t>KIts+eVW(a b6ĉU)sLqʉLH03F&Vlf-l8e2#fFJ8=UY+tyًvӊ@s-[[7rCvλ-{s!g?0J^+ޫnQR~Us=uυVY'*h #͝䍗ܕ.ߺ%n•biܷUO}BmcXͽU&ݪ50K%"G?'ͣF?J͕o2 7<,)7@IӮM߳ / g9`h?Rԋ[}ҋ*eI*ե%ŸHUUWV/3_WDPS0,1| 1+6? f  rċ̬ҕݪxr{ι^" #WcJCV2rs瑔7A$$;(iұ JE@'Tf̅yK֥p:82w'fU}s)Ĭʝ?@` X]?H 8 6 !ݐWJwD2kcAǷJԃ<^NKbYuCmȻHpV T.bЇF/y{ xѺ.Kg 63?i: j(N{Y/K^]J"#ŞzO<޾>27)ă!Ͻ^V}:-Exr_+l`nz;箑Rn/cs鱍]fe7GmWP3"p0k.LANo݈^-%in=c o^`. &GSS4z8U1պvcB_Tۮע&Zr) 2۬}"'cJ5S=Rw]٣N>K;d"Z wxҏ1+mV*VC|.6Oy@L}C+g)7RJ|usgO?|W^3{Oů>WW^yu1~5穧-_un\2k[g)0a GYyw_yU E H^1݅'u&Gs2QO0\ݴHg:#Jf#2I=EHOq59;x-QGmFlxc4;cF|*URJ9c (3n51VIEiٹp|-C'utp<'ne ]IY[Ek*#3G `_X1.oey%ce!nÞw~愦۳ɥHuw3ȝ~\b ; yѕM1SUQ%cgOlƌNqoz$NYs=gnd#yNyf}%e3ogŎ֪H^?E܋d3-NyZR3cGbu^D:Kfk$?B YD˫VV_~rOA& %u QP-@۔PkbK{"lr/r(Lּ%. }X|$o :iI凗_\lf̺.K+b*Nj0NXeN4_>Ot9c t**".^ߎ%y|<ѩ3rS-Woq˹!^Ua ZC ݰ#7C1'tͽ5f8tzgYf=z ;}sOOxLta4 k~a?1^&{ޞ w%>J;;e# b ix966W)J`ͽOa'h:1~-ace :i-&+e4t%rBst|ŕrd!8-|̫!pv$dX%jcPy2,- ;ѣD#DL4;@ x2 /d0곬uU %KOf*A] w0dD]uP6w&5YpZWXNNwӎa)'9seJnMI,2kVA*VBN#A{e?ontf^'"JtOsN=<{vl[rm,|^%Jgts}vy΍˟_v&м]@/N`O{~Qψ<#7qJkIOv'i,w<4Vዷqaqo閞wyClo/ht r)]\ ~PpJdva6 %G Zvb"ت%/ICydJW} &"qv`5Z7ׯ-? gn5#8aΥ.6,l;C1_bq^З>Or$w}>n=x$s4c~?`$5 ޼w\'&ɵ#_rH'&mGr,GI"A sia8,eIDGt;#{8y@{a};:ݚ?Dʝǩ=NM.is<`5cs:>gP)r|9G9VTd⠈2t,*ο;G0֕xhGCg|.>W9-vw/n9Lv)͌y6E:n;>X(Ϲs91@g6"I~#%K653R\4L6-{!9+c-d+|U0[7J"O}nLrn^yn`~ݐR? IWtI^PqT-8+D *viI黧~9orVi9ujԚ w7^}y|GfFFXeU&Î3ł8L-t a>\H7}ؙ Yy>{r#Կf_".!hWjʒx)R"ŜHK3ps_<&bA!68xa*ߘ+=H}w`d83/Q !yrK޷tƽϼ|Unk,go\|]ͳNt!;҃<&r8Ot=+&ӂ!~>Ϥ ~,^g-pN.4Sȍw}XHi?YS ?Ýx]*#w/rb:2b<ظGNq|a\3Nj¿JQߍW |׸+״baR@lo;0T:d6 Ъjɪ0sYFǤyN'm%7s]Ͱ\Y }骐qUDp156(+Ocf kh5;튋owM9wηIkUdJֈ6:Iw\_7p"]0<-?"Lg'ל/:'/;?Fۯ!"T08[|_[d_v;bR ,`N&32X;tCG,"""mw{}0E^v.o?]U&1Z#ks1OUmQbV+<ϯP~9mБ*R$z:Ё.v@t ÂV)ަbn og :?s4gP uQHx^$*ӿ-!eT}h՘,^L:߽N8C>rkfp:}/ֵ;y;se}䨓w{!衲h^T%#Q6ŊVaӼ 8I\H7J;g=*d7R_dSz<2C8=mgf?h|H~-aeĉ_aHwYC#ּ΢5apO־l-99^ϪkW_D`ws:A(ǔ֐wǁyvuv;"|$C(ۖ/Kjړ?&үY(g'~TQALdqw?W`k{%v}Guh}Gڇ;@t{[%ph'=Bs9:y,HRW? :lYߌO-, XV9nk/r3Efro=YlN̈י5Mй>JN:qb3 nvǂP9ө؛ެطI&?ۉPnL.b/X=ߋg`Eϳz(_, tv' f2yMn!oR~*0,<鍢^g E7Qn'SZ Z>'P&#}w"M[ëXpj2P,,e{=/d{f Vn:{Ξv4b^L={>h>{Ky?|PE6^1cТͱA*.^ϐv3oV'nI`}ԝwtWBN] ,-7^~fIy}Ćjά?Y)%$e V|HŒsq=2';{"П:^H ~(Ws/4eN"2_w/EՒe uڝgSKM)_wx1BQ o! {Sv>Hh&Aϊs"50}7Y->tp[g?RTqm8{ZnDxci@`/ v tTt%cܽ[&NθE˽㙇?w q*m UҙپMU\y' O0{4 nß? G< N' 3iȹG|}o5y:NY:qs'fXP ݎ9)LEu.q'z<$[csmw︴#ld&L+R_\Lh54~זu?qWsz}px\f%4黋?egu3A Ctjh@t6ܗ-[LWz<9c,اL‘%_ʾIeNw:L*ָ =,bU]TuGn}Iqltݐ.h" J>]|ֳg @ѬuԤVܳKH%IsHTfʁᑴ2_(HGfLkUk&&DŽč^aL|&gs Pؽ Q7?9,r+JgWTX`8r+(7Tz >;}3NÎ/a))3 /u}2z;9))M j۴*kz'͍q,Lb3ğ8>a|K!57&ꂂi I:@@#LV3ipjH agn ;.!q^U.BqTҭ*ݦ!BIKs蛳μm77+Sr1]5g!LJ$׵)8_+ɝԛi#[ /@52U"p*LaQ&38,3eUM1)oAWsQ0&Y#&0j}ΩÔwXNrFg51n>|w,;dU{<|+S .+pq۾ҽdO9Zl{_(>J#m7:Jb|,559$`> ]TLh/"Ke w]t?^dhJ*A0ҢlTDpwhmf-1RM( rv&wl K>I'2(^氾v3i?1xxם'2v~>0]pj.3[5[?yЇ87D^D-oC Ǚ.z^a M$ߕԻim nIQQn3Aݓd&gHsf8tw=tɛ+K8:gƽnΰJty[-]Lu,rBެPdEt2(өHXkX8ERVTթ:dQTVppi0.:(*{De=YψMgTbBTݰ#7CP#iЛZ%Cj.^ubØg>Fp f/{>ߧC􍌂n<܂! od!4Cq70k)m Nx[c+auvl+C'@Y^)iUԇ Iys$M')a s7VC ՙ pY<$?߷!ڠ8^qbh=w)Iq>1XF\j͠臻`z0mdtrv-kkqv=n+PWRJTVNKͨ%&QjjlVfZ^kbjlkeY4Հrk2Ը\Z3^\R[ᇥJjRתW&M_-&O;Ld[{AgwFC*?<,NtA&,bְ˶vӯd6 d!RD#8p& XI:rt'?F-uGz١R* fga{v/&Q!|= -Ih>Ghn9^>}sy>HK~>}+WOgdM07mÒVyAjg#7qZQI>r7IHmRsӾjO|к4r%v^[Lat>CfTX@'0zW8=0A4( C0 n p;b:tyi?oRCEck 7\`L9Ζ|-+A4{%L(?Zӻ?5:{S2`xL:x w1#zoFн x9.Jq vg弉0jd:M'qƥsJO›tqHw x=F~K.Q{WaR\+?|@}?;|nJDZjS.~qT[xӋqU:zMoy;@ΰvz+>Z7Ĉ ,]nGd@?J(y07yBBArk/{r*)qI̠M"#4{SzAKf6 m$\M#[oP;^ꩴo9ЬM+8U|,Ј8uXjX({cn +M =^9uwu"3K-9W>8*d\Z?r"ipe"rNn-$狸pɖՓߵFϫsjn}fpceAZOL"v"SvynR9dUoHI@Ar,~ufi07y~w׻t>#LU`މ"tkfܦLID;*;3ɁI %oi30y x^ȧx]XQ`'no0yTꚣZ42!ȼ\`,oRx="V04U~A+NW_3ݤ/'9>cr3-`lE\?U|DyݥbcU2YD -o1^G wY!!I=2%CTˮ I.YIVEzTZyoA*tDʰsC>Y~*V]4'UQ{q~^n؋?/{+uUQ߯l4p &oyCǓxsVx5;='h۬WssKE[ZD;=w ~<[ Rۧ괈y. /.%qcM2Ǟ:J1r^o>ȂOqmA8>(, zw]^IRN7&]^/NM@ěng7rّe$tEql? w-^{F~uH`D6_FPW)oG+qo@+Q^1UT`mcV^LVI #C=D#VBo5[Rqypqdm@$YT{<^&ixGS `/Up8iԀRM\Qxgm[+r?W(iTtFR-OZ0B<ʧr~ؑkp3ĘEb0q'l mAdPTeD *QT.'^(p gA={0!įmKx0F_:̹5cR6iF/=9>BCj9w .py@#N0& ICNzsNQ+@vSq(g򓎾7D7 uyEeؚCWo#VZdlE&y}$~|k~'}טT-w=UR8Ftv;uHT񁢜E2;N_oiUɁ|'6ĥ1EQUchCfbpRLWXƝ>u=2?=BX\5p;#ޛ!ʚ^9B(_'G@ ޞ^X8Rʌׂ>{UjJs @L"j'?AP#Vưӣ ( K㝃%7d K--v0j(4%Ch.\xҨ ={t_Y a}4RFv[Z5A5u # ;ݽh\ ;=ZKzF 6W"(MGJ)Mc\Ea;c=[SW2@$5O^d[ߚ"iz4zGHI]%wü̬9}<7x=?cu=2b,[WA"qqGa-X2$ݎoi`;7"}ŏ〤ZP v_%yˠ<ѷa- :^R6`e {tng\ Q_:Eb)B~_3sF1Ȑߘ.89͍^F`/o, J][I@*SZ`8ʄubdt㯮 2^1+Dw%-J`o\21;K:тzʾhrAXFR8:3}tlaO&_-~n-b(s}Ś>x$3[&BY<+|0] ,<і @&Rx.YU#"ZѯaG }hsT1Kqf%5X1 eUT t?Yw10b$Bu{ƯM♙4 K(@B`y:2x]ھ-(ʑO'xDȷ:#kUG!h\cB,*CxH b$|nw$-!1& imn,B88'{AwG9àZ!c_#WtE=V/ %Z`lMnQU4Tô;싖q x0ee": pah@u`%3m}ЦQ줼^5 t c#<(q/zrJ|mC[{Ml+^K"*#e>q ; ŗ = { G&ahZ4iP%,88#k0:}6~OlVZ=j8XL:)Kr0ĝ}cR yޮvpc̥^b$2Mbb,q`K°s~ Os*oswh,2 g0IV'oQ7N6PCU\:=aݠStUIB5P Cߙ Q^\+p4 +LO&8D@Λ*~r0pK 1? %Yt{4rD"JMzIi8#yKkeb[ j,;S B/Tb@6%qciD(72` Oԁ.vPC,5}c`vB$^ZDu!$$,/\8RJRmWŞ<Wc,?tO3)0* `L|ŀx7*٘cHw&ޞr`Ҹ/4"? ,_+Qq L0Q.Bi=%+|" Z+ HϗD0/bI3HuT{6xwq7i  6%YbXCq-B%1WdKe*qG :x /nl=L62~# 4[b(A śBE{b(F @b <| #cUS8{ڨ'Q7Lܻ9 utq=ŊPV@.lD 8H=<L-"/d.ƈ@@k;UR}KRgx *mꂏwa KX>F{ )8.`Fh)Ud#)od;V0O<^EɲSs- G$cPP% f"bu $O$1Ad5-_ " Ш i@s(;JX(EZyś+MQX4 ,xl@MR_A4>+ρ㡐I҆^1`^LV[h(hhmC=JcĆNnƺK2 ,:m gAjH@`^v&ָ>c*x7 @BvTx3g6ml 6Rq끿o#\ȶ+؊wXD6EwB\a&JUy݈`M?" *(TFp $!qX(f~k @C,<-EmW5V"L&chauٟYc5+N(HbH+Wk.C)i'z`@'zībso ˭!w_d<|d^%Ir3 <񅨏ߦavjcH!ᡔ A_ߒQ}C`JuI]oկTj!VLHcP&PtM svz:bX# AoA`&c[pF#>cGCFH\ AtWuN=]&.T"WxٛlƾchJ|q&#lt=vMt=Tm]oM+k!{*jtnkL7MG1 D?^‡40x8޽NIJ#=k8#)<.vA9JJ,p58J{&Pgp~zFĕ mG\*ȉ+dq6uY=m~_ ]j*r.TX/CE¢ CtX:P/Lh(['TDk G=$(a2  p-L#RQ{ Y7c *O Q=#}؇*)pB#)˯w.#Tb6F dъ!Z">sctaG"m;3$kA@]-t3EqgՀR[ŔfsHuh'? 4怰f7TlC5rط8#}+VTδBRylWZq+/r}acZDܕsXm6Vadhb/F5=:Cn_|H6#dHV,YrcZb<Pw@kt"EgR/p1DCrraN<ۺhÄq9@%M@STI+ Sc%6gt^9t{tj# zy#2t$h_Κ2 %ci !i`"k MVD)B񀓔^mi|ffryŐ$4`R:LN ` 6:=o#a?Rir#±%t.U)"0`@ۈ3\ 6A0EtzU%] xPLyegz}@)E}g(w2;N!t< o(8lzy [H㶴Sj* ցI>h7+-cdXЂ^ǰ HD1xnWRɻX֯_mwɮc0fO "[#mW z X N3`OlHoH윉 *r>Ӌrx[*q3=JaQ-䌷lB oz04)!"L`dq,L#wuL x#/ï]7(7]ri0:ڤD_Ɏ'>D‡hI 5Vv\x[CS^y`iH!P &6cLζR7H>˕`_w@:]#s<9z9f~NNf])/Fd#R1{>FaV*J`YG$5 FLZuP{ vsB[Yu<<<jǚW7 't͜TnffBBxqsòg3`E4Kyc@Gв2.;cFNU@Q K€x-b\=cMd #2RxX˜Z*ЈN8Pްu<0FH@|r'_uoY}s@'xV԰_bz@xSlPul#WU ;>9(OH=`".W[5EQ?Vҩ^-.@OwЯLDvҩ;[ IJ^P )a4Hhzxcx?&tM1Ĉ|/bėJ XvC|sBȬ舡*Qlfl[.64)\&]$1v2p]Y2l{(jZt4hk.p  4k_ Z=i:P/Hh)ɋw< bޗ,'u)X*aWpPh{r7Yr:mfI˵dL%^>vnGQW@'S}gG6Xw d{91M,n>TB[.ylc<_=%+!qDc㙝6Vx8~vO"N"#Xx?Y _6;;XR,tCx&n˱K.c'Hm`:jjޑ#a4tΐ⦀>~"EWtbc˂$x˖6]״nX`M0֑|5'B#:>KH\.~3,s3=awx ̜0(D]a6zBa1=qj ?N6ܸp@~aEVjhSJ˩H'ir1 u݄62[/9y\lboxx斂:-9H=\D֜g1 !phBwQ8`" XA: fG `=D'b:cX5Բ@ B(w<$,ސ(K~ A@4ES0*T{6y2My;@ q^[NkJmE~˛#zQ@.bh$v6 (d RlAW}8 43Fؙ{(ߙB6C*AxhTmʉ^P, C O2ɮh4$"ߒJt&xӦ|aZ =}I;Fmw&7& m$(9`$71N.K3G MB")>BLWE'`kdxbokwZm5o\Lɞʔ{{^2Kf3m3F93M/Z-le*WUtE:T;$ ]M;+"Gx.V9UkAg:`%=\ Etr8OGFuj!xHEFY$wM{g''J}dzkZC32iwp#2$JWc_$ 5`soH]SpHj[1P䚘ζh#J"(-pIRyk[Q9.,V+;5a(]9!킚P[#+.iSEբQxeE1" d]bl;yQ=Q2S0`,(C{M"÷=طRpjnUr*f{Vֈwp ״DSk3}^=b|UH]1{6k5Ļ!8wvɬBpa7FKؚ{7q{ttl 4/%}>l_;Ȉ1aa$GIR([!x(UKABŧM!Jjc_t=Ay<{uȸ/H*tю:h@z YI(z(9JGCR`ŰtQx1}8bmE/aqÈa]B*p iaM8!P1oH("a#҉>0s^c;*6$ $&#t+b=%x0`'*d-/`@>ۤCO6oćY/. (IP.|R-{m0X/=f_5So~Kͺ]4|jV ad:]-`^_6n·I5Z9AU$0LV#h}=0)zͽ`g"@& Pr[k9jS,H"6 gJ%r_4i ljt432n·gev$!rU^^mcrذԈ%3 c}p|W!~!Bmȅbf/ژ&LGr? 5uuB-a~OԷ rEe(9Ožc[4о"bK@bF4N[(Q8;d R0 GPf4nM̻'"]xg0Q0q`cKM=E (܊@)oD9R}b.J"31/]9GRtc*hG-iAE[+!+ ʉ:t\"kQOc 9(R3 1~!IPtb7kL IQƘ5hа&*htm&Hj#zCU68 DSL7Ba`G`$وkt~I#C~ Ā¢ Nь Uq/r{K!(mW iK~+I(qG:Ż?d騥mi٨A F3ND<bcG'WgiO1)s^ rP=,I}bPNi0hVuEP,x~ )uq zX/1^ F.4ogIWVU&LP?F%:"Ep|b `ta-& Ȧ&,rw]5}<,$Rx90=qaX %GJE;ZMEI:w0 2 [cls(G>9Ll!s@)DOK,h{ Dzp4FYnM\&_~L:% MˇW 8JPlїD$j+^y&TF47>`01UX(50X5 @U46aل9?ak󅂁44۳/b1]a|R,g!Olځᾋ h}G*r/w`2ʛa.VĎChv}>8mk]"v+ 6Bi}eݧQT[tX\;HzJ6t^/H12ʌm^juz ƒ>0[284pNaEVon m'pnM[~Bztw<,*c JjY4B^Awyk^g 80(NX8y鞹$ ד;$@ƍOI9sGTUF}E?pĂSv(m -|qFSpzƛlF:18Ɨ?q*?m~IWOgmQ` ^RHʭR[|K[9w7A,d`@$2_wJVoNJCcbYvr3ch,/{)2QF!vX})1?= (b4iA8qT9w"l}==v\>4w-f35fި1v{$r׬ʽp`*v`ŋpT߻.Y^G|B4+}nw`w>B(Ŋӳөh{Gxڸ߰侟4G'r8s1;'.JbD4|Д/ejUl߇YJYwLGΓλo;Bo1T4J&9y˩麓es(HX&w»ƁvAeOMDyGLtB.*Rd̐=ƧӨ[8RU==d,u'Cp9O륋K~ygU9|}ơ ,)M<ǧI#8dik( ;'~F* zFmh}Ne,w.s/\Rt {3gs 3y2/b1V+B'o';P;WIL!E}o{g6R[ժOaBC<]u.ǂQEc>_9?Vt8E?|]@8DZ$ ǣqpSqpqp qt}/X>X8qR^#];}/-iZ#{ -Z&id&Yaʪ:#E]ӑgM䞵q:ۮ@87{|MlEsSwk q8> A}kDdvqtpgәvc9?RQϺ)TFS731ga|_U~٪ߋEi=+͸VkA?RҤV~g;ŞC&@5^/yagtHŕ1jzI~oQkW6ڥ.k+k>Vj+"e4KH4kNrũO-إ$K 6x.4& ;Q,?s-ɛRd/M@#q #)&v.V/wBOpoµ=h#~㼅Gn{uk{658 E\]ZquI__fe-z`>{l}#擸ET]gEI2qwX8qbIE\S4IoԧWtNŠmUɨ+orP+̬ӌ:+˞/봂文fNtOy \U5+b0,=~ x DD qIr kSCMEEI)H:O~+'4/ytoĊ4lVE̎> ; )ivwKs$[ţzF+;qr|2ay4ʎ)KqKsdOLZwi6672P*_|}'j)@cG+)v-]CJ{NQFnm-z9>,[ٹoBj]wDNvWWwY+J^'s5h|#{3.cb;WwdroqgάTV˛kvRio[g*.7kvѨ7,r&kد4F\nUV()ބ+ZU]xh\(/Y57[r7[*۔4Jjխj7޸JJ֪ԚzRmH`lj$F{ZӉzmztr|*S D%W'- kۀ% JYi5߭HZ܂.YF?"zjT՚)+ϨpV_.`lF4FlUj PAzS=Wյ2lIK! hdC~DZmT*fEDQr\^[mԯʛh}e% fy*/&Uݔ&Ffc(_Z`ExllM+w6+F|^18DEHWarԯ6@#+rFcӨ2W7W+HEdpiGTVnwVF%Fn͍47zyEl L.7s.7*e` y~}טW>V7_Mhnyiz* |f.,a*ᠼk>4fZrfE5T^B(lV+,`gZ*#%6768qf 0[z*H&Z :VVuBMrHʶ t@Znm5Ţ,S+妑\\[(_2߿T"j~s D@ց*fA)  @1gڼ5Uz}깉2M7YfQ/ђ&H(|^ׯT+2Um_sdcu^&լ_xȿ҅ F^3_s*E|L2Je C J pnzzRY:J{u- 䬲LT/yTDVfEN4o[BT2L Jf]6i% A  HS buU(@g+U\ aM[֓HrrzQ}yڪR)p6jmߺh6=<ِK eR{ڨxmeN\ɲF+%Dj7ˍ*J\dU5^«8&P * lJLʺH5e/jfPխeQ5<,[ńXql@tS ޜ@ElwFT[OiFO ٺl\E>^'Qm_Ejo_PDH;ʥ2 mDzV5&2 /A5f{ FFF$DMS~ d37v_Dy*qfC_Ki#_<5\K{T`@[o4\\T!…o#,eb ʍoffGf[])_#v)M͚+^6g|ij KVDzX 7!6CC3 [PJA4㡑2K0a+-MWu} 3M' ъɦU6Bt@MT:9 9`g^6k n6 e0!H/W7.'w&n/Ukdlqiu37*P&Taq(mU`%6Z:akXf 5f &^Hۭr] _CmHNNǁBHkM`Viu~Ydi&ĵ, aXݨ i)2;mD;&wZG%&^hVHir%ܻ s K(/Mf|7 kHsr %ojb&6SsR04e$ h$>AoSYI Iu ֬1':XL:f\Q$ :=уuI@Z.FE; x "Z auͯS92f$Wj# a\!p,# lB fiׄ$3t٩Z 2 |H 3"803 rֺ PRk*sN6PV_*kFvJZpGbG"@6UU,UQk'/;=sb5k֮ %t^6鼁}bd^CZYj0֋,g"Sp =hN[]H. Cf^K0) OQ !3`W*I7}؞MU >V]ڈy5KVӆr`@i,R}4][_Q-U6ɔh4nnM^LV+k+MH > f-y FP6uyqh`Δb"Ѣa ߆ő~J}e%R::/(&ރ۩[f}%Hy;tv $c=wĈacU'2xBsE(`,N&%ߴi;9,\gd̐Zƍ(FS`vc+eꪎ@nd]ެ8аY+N0Uլ PTK L[̝9JU `-ֆ ,ׅ~u Js~IZ-ͥVjݵNcM$=  I_ZQ9ƾNr*N2 lZr\TԶ|Qڄ~3Tkگ@鉶O@QT~-" w0% I]_zU\l)!F&n[eVezu2lU[--ڒ7'W1K38pl> ;,C.SB1Ѻ@QLsn֘7Bcc$R5oy%1][_C_2S[8?Ixk7I@hw4@Ky~2 H[<'X]Z@IV]ie3U@b4A'b&/px;XB^޼dt0хkb>|fv)F=h'9> 2Q /9>!!NB?]@L)f)"]PĬW+#o ,zKfUYv!z$e3e`F3 fSz7j+ʚ=  )PkP8lX_/:MG` %oS@Y*> ubyj&+ _kY2|J/7_%-Iωط&ip‹Gogte}Ŭ[@b͐.wϛ j]R^zLq*UV%) 0|ruqdz;kUX@A3pF=(}L֗@;ZUE;U_>6fLN&Z]IB;Vs9N 9 WQX=IJ>lr2=MR`%)WFftÁ/}]* p2ґ.ˬn#溕pQ~!L^[oկTjYҚR@9 <@,+H9YbH!^iZ15VpDxO$hXQd衼&2$MllevlNTeP&e `:j +*r֗%AXJU+Sa&@tꬩb,Hᑢ3j}iKhXMZg?׊M鯘3Nf^qHriSMZuJa. D7]%nC\) x&NG6fMP?h6nBөAA_-2uB ^Ak)D[N6GNurgbKm  빇+fO!Zo7TʧjKá5y2P@rxXZAAVxWa&efƙ3N(Is_ =P/ 8wn n>IaZ#o0i$J]j5fkj-dJȢ6>LvY! @hAcDh@V,ЃhњA`Ԥi5%e .-Aqnrq)crUWӿִQHSykǨ?& 9kQo9I ԉ u" $a(&O f&`'$MO eS07 [e Hhar H^7DzPX #0 o_KcٗZ̾y¾P^^oWGxɠ~/[UʹaF.ɹs0NϾVG^(r޼PQ} ٻ[5; iϽ/哺Ru3ފ&Nm{[ w@ӆ~ܽ[Fnu9uo|̃-w1y;Tg C_ǥ[ar7:SZnWNu/l'ϕRvI}͹)-q* vL5]s{˾w_H_.^,=-vEaPhA/eyMg# s/K|p<>QX7љu[eq3]xÉ~펺9qGJ6)tƻX^g<2wuUV;./z#?BV{T5ÛF~dY+iMǾP>SXaWňϋszC9kh$q1>h*{doW[üFKٗU㼷Ng`VpcVNN}0QYqu+6Dg};ZU֦\fކ'5 ^a &T gnqLu6'cPL>f;Q|s˟t[N/AsEnOwÝx*}q51Y:b?&kVlL71EY6 =ZGx{azqppdlݝ'sMi/-C#hX}q鵻N)K4% n#?mRdA4FSb  I% i[C_ՑA9HiEd?]~'M NR^cKYw2Ȱt_q}<WKf_/5P};߱/;o}aS*]_QFrsQhoI3%}gOGS)B0bC_6O}秱ߏ1e8gXn6߷g$oϳts*)D6*r yv3&?O9l_p=ON2\H=r1ˤ?Daq=MT 1](!(&dEFNǠHOMڭ~v0?hU ٫NYdd\b+dȬkq}.lw t=wy<`၏z>ZW[*kbF&+} (z,~N|RGvf}׎gɾ#c3r}6~jӲ"<'zmȜùurwK3gNI-|#hUd=ںFY !z ;COw4Ad8,@ƞŶU|< ٚJyjTjJKmg<͢/h hl[Δ|,n,p:l;[$1wjWN@Q,ҙ't&՝˛5we&x.L?ϫwJx!Riq0Vgߗ4;@ U¡(3碔2ѡL*?Πҿqz6iҧֆ~(1 徯`q@Q]I5Jur:$n ,8"fBe?Aи- ;؁|X uCK y7K0E Jo ˑ{׍t;9[`h.֙,CBo:yWtZ rQ$7;7.,&(w+:a d/9`%nw>ü8ng^sZW6d r@ԯY`:-^ȵq֬4Z1_T0gaFBe Zʛ[)~NxWP!ygrSߋƁ ڸG Z Wp̃Xl;*Զ΃4!Êz!yGyh-=ebQ~1>f'J;iSFɈRU[?v9,_ XYRi.TU3{G+}M+vhŴweQܓԻ۾HS7YK8 ,AiUKq<@;ߚNma_AH{܆BGDLIdI<ԂhG[ ǃd3 h4蕅?9DywLE 3x# MtHWZ~ݮpBh`Sx) Q.O{A>Ǔ HG\Ě?ܝ^CѭۡB?bˤ`z=w) GeW,!q"@l$ =_=H0L`DAv"R F/z4 j9@>O`*kZj# BRm& %X ~%X]z9,n2@-S ~x|g1dn| bq h,k!qi%0Hm]UFbV̔5Dg&Ƀрeƾ]؎6XFQ4\*h7 , dImH]ʜ@~u &K{s$uKv^eM*?f4^Roe37ioCC@U%iu$Dd듄\BT8lV)Vhak$K:Vm"Q 4qdY[ߐ’gO0Pt9ֱ݉|pnOwPDrjRC6߿AZ PjL̯`ȗxxwXt!@!VYovia_6/xO+hU`Tw8P z="=A#:"u32IOsxDY*,t#*iED s2lOa3\0UhtbÚrhbW1G54bL J!o:1R|Ƭ<-~]RZ~sҮny]mo)ܔ3K (SExՈN3Һ Dtgniҳ[goG83{;7bzU~VuY  r"[w[>Jm(jmԹϪ  ;FOCɿ=o-Kے15ؠk W|`mS0)+ -h"Iwf)xG/-2KrO[e; 3Tԃ MsR^[9,6-]` hrR7iBsٍmuC+vU[ﱊˉ "]aQ2јvĆP~_)!AȰwH|5L$rTG}P>RksGOi\ЅZ%qT!~"}u9 5 _qOdoasfWf֚p>YvOsOk4"tɕɶںyТ5Z"7cMof^Z|85^HMctsx[Rjmq$n/^9ql#zj|,o̓Vܡ}Daq110~N,Oe4AN,6tE1)+veGFxcE埱I+e )T~;|3+wR⭳8^k+[cLK (!)y=* *fEoldKF!$HO~@k=un{%h_H8[Z؂a=^w(1V.RXʕE?όGhd@@?D}Hi4.8#ꫯƏZL¤_k -1_2X)Fa/>gy!DŽܟL:@6ɚEWS!zuvo6]?!;94v+W+~W{Dqp)ݸPNp,Bdsf5w,&hΧGON]d1)YTD%riXJ:ѳ".ꗴ9)R-Ɋ?y;[+iÕ8Sl7/?[ VG g,z?dm b y%A-8v_/Tk7g65wp:DŽAsreÇN0E΍i[(pk:1M,^{V'2O܁x,2bq8e͗*OН:^܋戾ܼc[-3O0 KH 叚_]1+s.G#߻$mb_(z#՘~k*/h ;z%姵_H'sbyԺs7X?zlZc+ bǏX?q:{ _/aa଴J5v\aʎ%!k};-%>,4AfK?RպӺ̛dMk֍uywI'dkvya_H.x,vQ9}bO< Fp<ғ[:rz4O?xW_[mOB#^w:w9+]oqi[ۂ2ߣ&>;34' fll8֓9^gJgn_"f\j+o^eZvx˿[tM.Z>hQ GaIRϤu<"wi/,Ջ\f,Mzlh7NE2Hp>wc{& %sߌ\26q8{^g?茫Jds 5vl^JSYMŶmbuӍ(8giwL':οx&9Oʙ=xJ[S2-KL-n&~X"Sڡׅ:q{\ g.~2']ǚTHގ9%{th cGma.̙Փl%#f|V9Y9C !YyR*sR*gny9Y":.,wpWF)K*3$aG. ]D4oo2Eq3_`qggw_(-:x7`R'ҍw~P^.(xs.7X0Fh8pg| TS$@?Πc.K\z?]۠vŷJWQR|xiQTŠG]&FJ"K #1q>KA"EiYȜo|go=\x?V=-k{:kµ}UvWc`7x3-ט8yzؑLro7T-(ݛRK3A $='iACK";3**slq( 0췥%R?D#,3ͪ^lu`̖#;1ہ\u?@8 Mm}f+$|:Sa:6EUpҾq"-ꎕh|k l5Y0-@qJ` m"F*Ad$C9]k4uXMnw}ene,PrDAF<9%n7M)d'ƝjËfcV:9c7":`"D{1^hԢIB1 P;D)୩o$E7Tj߲p_:6+NO)/I,Uև Ng|꣐1~8jB)tgYq0D9Sّz&b&"զ "{D11_۝m(ˆ@<7l * dvz2b#sܜ3 4'}ԞH& [175Uvt0t9Q(:HF,wڬTqNGQKF.Ńag7@6Ů !=z@Sz'kz{ F)u./]9zwr/ẘ8,8E؃/e6;F -#^ 8+뽙a((|=E~3/(8fPeE0R[Zpi򃉹V ./ EA}ߢz88+? H1틄qZHv h 8)!$d߉{MDh~o~P!&Tb!pJf @FvAM NRjG_ 2rE6 A"(Ǘo*># !Q/ts,w&j/@!T_pSblsj;'ݨb,Nn Kf".g%'̇J}w; /̥>;+#qSZv(% iH1 4McjUdNWܢd0<1ARC%HN @p/lj:BB.&=m?jY!Vpa7ART~?(&.v ~W:Y} %>  XQ )(pPd&P 춏`[ dAۥ&{)G9'ȐMA*Jj䆌D-Fӵ%6CBA\`qБIgw VNM][8- ޫ&Igj. 85'T^g"j)c.i?n13;| wdzGv|+9Nsm4ERݴͅufj)G9 >R#MQ pA%!Dm'v;({"RcQ82dޙw\ r "Jʫ!8+'W3Hdra O$Xִ/?-#[owaN<2(s$ @/C|g}WAG[+(Ft,' Tx͏ EPs(Q)0ѐn"(Q=N$Li z<2y@tn'մGdI Uю{ DB{M@;{YC6 ? m|L* HYEA.$GN1ᗖZ&4FTP{mK&t"H Z&d$ӠiD66 +6IM'=fKU&:LYJ*FS(:i`ƭNn=o:0GgE=zݡ0 ~@Ժ2 ɬSWHvAvz"'= t(|$6;`"MD;ԁݞ~=^U$Sbď۪Rt@qk -b%VV|)uA֓O."ƾHJ=Oe3OPV7G>a¢UmwTL pmVĖ9yOCppf. u3 .BF]r桄Y:3R)w  HuU񥥅VD]ix,!Na;dzҲHf(Iϰ$Pj!K k=;oPNdC2W^F#sXڳaN8Pw@ W,hou#چW)5d哑@D4`͝:L La֖5"MC$$@bPr4R3%Wl- ~#;ΞX?'&P6x#@\0ADyL|GZC03@,+Ƶ*kBE/kp IBW&3&haQZ> T=en3E|$}:O!ZT^KNnTQ:%`fh.4a}K@BB/|BoOZхUab;MlXK 覛ń!\rge}ێc>'@ \d>OU0Vv\У$EșXIZG"cζ:I,L8`y6Ұ+43"*٩ًPÇtb+ճ8vy۫^:ds@O=eҏH9~ LR2S)@[9,A pAǨH~. " 0 F/Q"p˜o(Qe J) w'6پ H|̄ z=ap_ 7 `oc!C=#+Mw`[c4 :T1Qy`·I"GZ#ц݆$E ~OlRP:1 3-8wc(F FT[CW0&:SG 7§.X*gc&M*)*&hҥYzj!9u I>MOXn:ra%^/o$ ֥‹hhw`1 o趝+ M*`8yDT죄\eX [*DK}kB;vZc<2gm9ª'M_Q~(1pr2Zɗ }y#0zf5/VxM$(Tj: Q ,1(>P:A([BLOR]ܑNħ7Ү1e K3QA$l@Km4tY?=10k=4@+P<Zx LA9NN @oo;0a1AJ0>9 ށab]=*7AKN5!N=[8akVi<{VD:INv4 G?TkL<AōD2r730k4vI8'h0~}@^  JiEbpV5cXS, \RV3T$v.|- ħ\VHٽ~a[МGTZd|&7C1h5I (6ϛf_Xw을GY튲>pzO r.+0L?,vptOy [歿 2L B́"Tk9DyZMu 31Y}H lnhQϧN}+< ;?>" aI[!*x:Q7`{K|4Qב" A@59P:ttW3nV&$| HB Q-99\e8lM3HJlJ*IJcbzh+񘜖3jdZܪ`ϙH@$# =a(a=$੟(`|@r3m'[OzvzDt`OV(b=rcM`7G#R1`F40:l}dɔ8Knsֈ(QZ#"`% esrs6e$Ĩd~0ź)pf^iΧhxfz)Ivk\v<v}E)e٢>WRƩ&yΨK6&z|nM,wKPrHJY\$1,J[Ysoxa3з $jPhOĖ5 06`׺-6@׉LV/).H DEq mLPj@`Gg$bRjr 0B! e'a"Jgc*D}T($rQLsҪ)2N @HH4b! Lߛ`OOuV@" Ya5يD6LOi D4Gs!:F\AA g @҅Ї/:Ed8; pXb ◭'R"p`O' PQ&l'%އP@=;xi v= µBkN8yS!N.sw$TL zHdGiGB 95,,ɢ1 .8܉B%<lN+x e`=ޭΰcC%cՕ+KYxVmoTǍ`i/8dY$Gɑ S[eZsp e,x3C*%C*:2 Q7[FRAJ豷LӉh.f )TB ExM"ف3 %6%B}NHTDU>ÄIq'T?aiIi8=?+Ԣ_²R֋f1aLdZ'JYtEBmnf8PPtζm 9Hȓ}5Dj(<En̢ Й?2!C}d7H{V>՗R2+;vmGn!60:@t\4;+Y`5u3P Ar׶*&;I*0l^xg"U}w+\60Bwbz,$Vr lrB.{abD|I-UZN%IPA%`Ъ]Ua⩟ mmXp׵$/=Y>jݭNTں43_21|pSBdZXTՓrCR$rc)Y0a 5adCt`}2DFlédT4`b 7 "dA1A0#%0JJ3?$6c2I7Nq$MHYk H^b'JX'e hG.=Lp OfI"fR$Iz)A`(l*=j[:SSv> <'h*w`6.\)h ˂A+Qts69é6CѨ x1B#x9WF} H\5!UE!gRj|C7I؈qL -dr i<d^da6A16қ@J&9l ltN&$X!JJef2w2DdvGRV+#ew:}3^J2!AV`O#UqG#Bamara +K`n^E1y5 h'#pG Re/S"/Y a0[2G$!hOX+kn6*R<`ȥm4Z]uk#i%ui7moJ@sO4୾<$!QmMesXh8AEXK(N[uKÔcY'$,'X Kc;)'22 l!@y8Od^q')A} &y)f;e&잘p M uvQ[ڤKrg0{W3RQ FǙIqMټ6o[*&Օ%Dy}s=3p܎Ԛ0CpQ&/(Ȁs-JFrhL3peMAi˂/ ; n` .,h}Qak?{ Ǖ%!0,w@3!1H;n ;ըV9Y9KSVN,˖,tN:˶,,/\gX_O>-fJ u BJ2?>S@]UqWF#q=FvtI{}>;#vk}ޫ3Z{&2"~-G^iwHjX0B'ZA{91vt."eAűwņv.p* PV})7"͢[SNz+nu`4pjkݥjO3u4 Y1rq =b-hE=߭P& R.(BB#RŘ`$*wQ>40& O#.D;5D- 5([3Й9 [}b( 5@667%0БVRc@:%ee9.wus /26X+#Q-C¨>p8hVLjFkIm%/o0Xw<$Ezz.w bY]vTՏZ? `Xj9d1;qqUgPZ&+@N2A ВN>苵~6XV |$ (K!%xcm'RkC%Vھ"mڵ5$BՐ%Bf=QAZ ƾ-T slFm g fPfQ6 h8hҭAnj>(XA|:J vLyq1C&[g-d&lہIn8-*G #Ǣ@npDlXs1ܰ?E\/EҾg;E>Ԡһ*eWČJpmioM7!ʬ@5J$spe"XU5w'>Lx##S4VއAz:7o#\~;&,º&AR)]yZҞ(yKG&}x4$ ԫI d8"GWa0fwjśp}#IOPgn? ۑRV]H2Z SrRV_"n_AN1| }j_9U޸@l!}ewdS2T93˜.X^ooa_2RE̪(2P')UfF—24Hvp87Gvj1?M(BeA-G*&5ãp_Ul0k\W@E֕U4.{+J1AkFD|Vo]t=*+VjjO:MF; nF-PY J`6b^d ]Xʮ.Ǥ! Qy gvp fh~ M*=X޶N@%:њ:i%v^gzug(gW2 jilsagx1//fFAO虙=}ZE[[//xHC+v?"@0( b*qX/`8.^~$*vZ(8صj_ӯN dйM;$N^_M8)Dhf-sDIE(qZ Sr J9X`WUqLacQXAd!`u QA sE :pn@Mbg|DP߶^/C=jlwEȰ1'OL  yNCjt0q&h5=A>1,u[q^ X 7f A (1Փ dHé`*L.F"eܲOaL 0Yh@H`K [ZN=Aŗp K@ 2n[ӕA[A(A̝su3*t5@+\AڈuAezQ&"o"`v"P(pʧ{ {L㌯?XlM1苞 zLHfRhudz[fV)i'M-ĞI`E6roX( TĭPQDmtV.jw}k  nݩoML C:1 ~ R9k MdaPa&_Aj5n@4@™"8VB+j- mҚc 4 ̷_z]k!*iA/2!R='ة[ަShoөx(5kHd`~Sm? EoK 8ڹjtwnw[5r hωGvt`5 Y+]qSfSC5N&#m/&"H(&NY.3^@~/&pyOy򫠻;$2V;9/~ H !Zdk @#42IŦ :">aƔܱ._%oWG$.Kt*׸5]Xmx#F}QOhGУߗ7 JkuOAx>d=6j9'&UBLt=Q>$ɁҘb,D) rv 0,-(E|X`P\g/rF/AXЕA,,t%|k@q尾#A_c(э^fHlքFxK 1n | f^#$Zh7Q1ŽCS'cQ=FR4*T؛"{/V` XpJ%y{(מ@xbDoHwbVHۤp۶YB(\R>rf.@սSM\iQii`$@#aZR}4"RrT롈PrD{fד5ۋr`^1tI&)?N~rLt;rpwS8N7 _/^7yu3QFF aobCV,2ΗD%fz[ҹ_Ka']W RU% _̷)~tT8*)X;U)ǒDM>&T"fxZ5b̊RI8 M<-p .`asT5N)<0.E0$ r>XωR+tMr M8.dPVZeand_R 6\ qg|}5q^lg6|y|_5 :>b ج6wѡ_]mkW]ݡ`T`6),`nx5!zhI]^ΰt} oz~w,JNa}8fX!N5X5jHo䢛. p~Mذ^g5k| ׼S3^݊wt.u>{ۃ*Hp nf^AV^8@GO -JG7~ %l&z%KӁ.S ^SK{lFI)":^hJaQoުmtYa-ܱ n9ƢnC&' .r[8%*$Μ>_mxQ mp~['auWt ív++qHV)/M3Z#bedtX0".r* ;-⍩q^Hk8@6 7fm -uu*LID&;;l|C'tz%iD q +]#[`> t3H]N=vz!F+ ąHhNڧU> WA"_I ^q7 6J@J!Q'dj,rv-:_D~[4Ǵ>@wtؿaQ9vce\Q:9jCwMP4 B_#ZCA%#f76\A t0#fh./6ƻѴnNmu=K'm˰f^H5y~ϳn;v/'.h֞ 0&|)ba*׺LCu|Hť ^%aTk J|эli؆Z-I 75(W):q*!b $o)!Ϗb2 J|!c}E 2LVsf$i&s譜uX]T/u 퉂q%Ǖ!Oj$QE1ӻ5 $s&T5/՛BӴkzҿ04K􈟭$ް>lG7J~a/Vwg%(|"S;ёoyfEԫkˁHKdv@0SDA˶*o:~"&DNT$&D7/-/]^X\_t#^\ͅJ\q©PvШz6 MiǬVyڹKJy XZtjRq=o N[EܑFé˺ba%38ЇR'`y@O:ݟA4GKg`:g ]<[[sP׹[_͙! PfuSf*1}Ɯߩ\)!1Lu!(d9V<꽩ޯ쮄/;=7vVW~ DmYC8W\Jv7FFpn뭑ig4@ѷ+M6 `A{mHk<79Q\L|B*sWWHg3Ye1v7.٤UY%-V JCCz7d~-h7Pl#e̖DS`mΙVb=Lg8rcgw~1=t-fpA y[芃3f%xTT '<^1SOqPWqBoⵠjEOO xeyQLg7X\oc7lx+}qR2AZn+ad ֚0OÓ` r)bZM%heEHJ6l#Y;:7t9z_Ƅa?EkL1}!uNb7KsM*,oVPcPZXe&TY*"ً'ʜR;/xߌ/ƫ1@ʜ&ϸ38ZJetkTcA)-dap*e 13J6hʕ)s饐NWSwfRvп$ LϧJlz~gD!E-ZP-4//lQZce Zz(M0cIcj\ ٍ=VϙeȥY^&oa-{_"jD\fiP4EYB ]}yIH]^3{#h4&eZlL^-p˴b,$7~_ߨ:CxHM@{F=~KF=Hx? #"0 &ϧOit`Z-x(EouF-z+뗍‹FUjT+dV͝-Kkv԰m\MDac_XmçQLmd3,!iDl3X%}N畚]F~4}&>cb?c [uNq3c2=zxAHS !f8"Ҟɗ\T܍!Z~rp.\%}Ar*@PZ۵Dx! spnfEK<ڔH]4r^۰.Y"f:6y噂uIш-G ۾K{b?|F'cE- 9ŒOgnܺA(Dzs&g_W'jG@7qFo9}?Lb,lԸ\=@Mn^y6ҲŤin]t?.pbCN!cZz!t VtQtѱ!]DMN8^s؛S9-AW qFΕGqDS;(i%cNӺ;!b-*G̗;Ċ82<QiJi2Mg6QM:q2zwgp6ʸxP\=yiV[=C;˷N#AʜL]9>Ў6)Xl٦oV{ NlG4l_U]}0sZQaWʯU˝߂A]kzamTp;_*I33u|]_vS_z0M}лjzv] eAi`>[|\??| q`YFSڿg*?)r}#9o\i=Vve象.an23P{ f fK$enRܯ>d~N?mE4` ;wvRK;c$-sG 7윏9<#< 5bSh{U y$)D&2yt':K#- =SYջL{8Ynl_:$,8^sᩌO!Ex$L*d7ҿzwtz.[̒k蚎d|hvx%X_dGGӔHyN" FCRkL?u?odgzPy>-vˣE.9)L(*G*BG]?^gk>ǜ_+Vy}8:YiCwБ\<4[v-{l&ЉG~\;3(NsC9]=&7>nK'5Tsm:1!hJkU=mIjzU U U*k鵽T/e83ʮWb~1>"c^˻"ZuxgU}?Kz$ݠMݖرvz-Tg.^;(+_tىӬ(7+Z*`e: W/oӕ/KW9Bt\ee%' |7ߎҍ tFC•-?`L|f[aP,c^ [m~޶6Rwd|j)fUܟM? z=cz5ku| ŻZJwD Nd1TўtR1'_ tI:C Wv@ZCᔲo)5H昲 w?@#XcxIa긃cuOjir\|LV [i3YYep]auݪaeX ׽5Zj%b]WVѠVJ*꜒7*ʹ!U\)Mpdm:G~ON}ZBG/b񛩖㩳oG>kUnܘYYO:,l Ȱ !!-ĺ^_% o@ VcoަvC^2#r݋W&7 ^.tL?ty}JO@Ňdcj:FEL4bݏCZSPD&mPC =GB?Aa@CFj0( pCL"@t1^gu>C4]>Lpyŷv;n7U?1tZ=Fe: bzb6 SŝHoh 3ast>Α?Fz4{~ϋ{@=T@*ԓ~Wc: Xu1iC?'>hD6(Ѓ*#az8%ʅv0շcK[ݦhiR?D^[ l5<$F#E]ȠȠHI;>=Kc6\!~ 9Hq&0 : 3݁᛺<ZP:FB'z;qF1\g7{hG3۝WHjkл3COeu9cZJG4|\;E_) 0=&F7pkZJFD!j>Nfvg^3eыَhfG/y9dScD!ETwz=˷ըZ֪gk1Q,gv2+BU(xN3J {%*@P!GK/p*#^r.+7.1-~w+C5a+uJ6P)/Kyipc%6̏4WŰ 2S;q0IbjBjZ߉pqEۖ8=KmWRT*Cت@ōN|'Vip!>DvJjawwfcru3DxH78Hna 銔I$-x j(alke'㔣rMDA9M)FCsaR^)H1t1˻-H$*RaqKb^)hTJ_?p+*s`DsHE`ъ{"0hE\0R (*E@f"0A"7@i1IF 6A@+:AC7$E 8h¤[!`ј;IE;C)F+ E 1u%J_\2\rͿM% 4,|8KZni~[ni~4 6Rz!=ۻQ?Xt7Goqo#۷?}<}QxcUZ;Wӣ]qgȚ?N1!cп%yhnTmMV_/-ϣ G).-9iѥ|.$ƠE_Fy T%R. \Gʜ:^~ZGK׃soaڛ~7֋7ޭ_KY_:9XIxK=F^u "o=M9M6~)%_ۢ֟t69W'73|_x>[9{Y;yvEC4VQ{=w_)tDA-pG{Qo؟3?/ E k;n~Q!=c\`&Vi<;НS$}7'vXo*2)hٙsj9:λ׼j[j@ko2epWy+?t4 owfk1QYd,9= 6o6f3gl|v6>3/9[RrT%KtG {j\^gՆ6/z{ݾ4cjrcxvhcQu:55W'sE:s&3LnlbׅdITrN5KY`P=F˙z^X 056HDHְWU ( Uɰsz]mk{F2wnۂLZoì@}ԕtCK➆ 'uܹ1IW6t:OjN~>^q~~,%}]rxN}I% oƂoh%Uhms)i: IlOBKUjE]A_ * +Ɇy`H+CioN߿N757?j_Y􎞗 3n{HLK;ֿLv2UMbIv$j\foGNu#Lnvȉs'Ow~/N? ;m_vizceU+ H1[jC9PP-&OY_a6w(Jpӿr kJYU㹘I& 320‚r\];S?F>FLӥUGj#5~^#Z2wSdv\ iLV&WĴZbykӻ?ʼn_2{z0bYKݫ2a9F~1K E_\Kr q,^8Z=~ŗgtAG?_p{SE1lt}~7/uþ:?X`8X> 57N=9cKm-%6k/3ǗE.~v* .b"U;soęCW"i%3<+XDk:ﶥu/=K]ޚ`VrW7>R 2 l c"#\M8}>v;<qN{ܘH&^Nǜ Ct(ckh&28ҷ['Fۻ!Os g+^}~<MKcFϥ0KZO'Z-O\U8V_%"- Aڲ/?~}L\z/ !ש=I=F WXt13*-]eY15ړz{V7 2PyA qN~~KF'~m)pGAJho0I<ζL}ZbYbT{FAQpm)ſxߖ-/vhZۍ:#utFijgqazble {;.|S^F/ ݅%-hp`r]3ɗ,\GU\›Z8tҍ&bA Tۇ0괕^7O7n1!Fbw5~x_̨VGAzw'(ŃNƟ2`Z괖 q 37a44 j?s |TUq:u4{67*hRpnu>Skw3og.N=wZZ,iG#y3[C?}p$5J7o\|mB|aadLeHb nWW?cYUqc]oSc1Cri4R6}y{qްv#o%߇.>tK[%}Sky^ǰ|{gW1]].g.;rw7'ϖ{x 4'8 cueɣIsvTY:%Z|jkɊ{4S|7C.r޸Xϟy7Ͽ]/-ܸte9._XYX\]~o7dp^Xys+.tsia oշcx&Fߞ,l=pƥkWV-@+o֍x݅7o̟ruj Xu-\X$_xe >..,\*rnqa+ߚ_?caq)6^.\^xÆ\_sȇ a|rs ׮'KW_?poT Y\ɅP1DKK+Vpy Y7Hp X\xs+]X7T⥛8_@U4gru1vq)86 #8-Qcݼ7ޒ.¤&d\8_^tt}qk :eM{d5_DT `:x-\o•H/^h9`phcS%fnMQ i$<ٮJeDu[{ԀĝI̶\jeT$+1XU+IޕRw"DӽmؚZ%Oݠ%dsAIi rRK0(B޺LL1/n\+Cv)'㎅lK/MЗ&huUI+j&Y3EUNj~r" 5$"ҹ[¡t,4=)<Dz Htղ9hXz"u"vvgZbQ=DT "7zEK,  _C A};~wzPTpڢ pWSbKѥa$jG'CzmsqSGµ]ZWv(\rHkAmv=F(Njp Bnr%ՄYIv^~Bd4[pw&i'rwa%(Zsѩ{ُ\0&>,^)~2gSQ)t!_8}pO3&n0f8 BH\I.Jy-/͊JCb3z&}sM%G?|dA6,w+;L?*`6^l&d9;ft=䵦X2| f 유>'*grd}g'VM]SJxv=y]90Mҙ>o|gleՇ#^i'ud(wG_+\7>rh:oxƌ5_ gҒ},ٜ)Ac1(j]Mv((k(>fԾ9doGZ$O4ӕS!AzL|P3UPfS9wrH|wX~;Urf6V>eU~.UnuϺ'Ӛ4IX`{]N}M y<4$M}:[.qV4*cƥȒQ%9p9;}&y_ۧnAI[i0yϙ|{,ڿ0F/èR5wWL5*969Nu#Etz*yMQÊ{“frϲqJf` լ"ȔRc&)''aPv{_WʦL4 J.i c>n$؄Db~^wf7 ~iP=2r-iBP8`Odn5c x9k=(Ԛ\DOfKrhbR9sgHCD3p~a`w-ރ`utu K ߈/]]ZX߼~aB|8u_s[֭i.~QY~7,bͺ;9iy7>P?gڝ"9r6;a8?Gf8?pYKryc~!GI&/<8+cuh"KyJ;f42A}RpMQUqF`<(K7 tV͚i WK EE|M1\0D2Dq+H66h;!=[w1V=} >q'+BkAm;voYְHֿsda  z,c= } }jdiKc~!GIshfIMmac70dS<1 Id306QiXçeS"cfs*ovO:YӠ~أ)T3q̴\t?(\vZV;#7#I#z͡X)Hqq:Of_O [͇~3'Pf<߇Xcs>i.]υm{tyŭac y]Ky0ŋ g+sµBw`C`jп b;\w׮ /J40S̥hBaAA/Kݖa[7r+^W/t. Sq|m)^H!Ob! Q ݾ9/V=lK$#o x m@nz9hۘfo-G|Ǎލp |o_Y`3Ǻx"Q._!2wA#!\Az@C|nEwarՁ-Hb :Mz(+z1~SRF?ס0(wc5}?n]#kfP,!{f7/o:~n+~|EuAꆖzK $ bXSϱ(^Gz{Roj< AUD v|ck{ݸŰʁ[qqЄ=XO*^d;[.1Z&zقG/ :9aFDoMEN = 5~@kW3e@?"%=%4Y775aXߦzG*ނT"GBw.4я:[6|o3[o9`N8ʶ/ +4 Tsa*׼ԽU-xv/7g PJq%!}fL_.Q8vT*RRR̕Xtգs%h ÿ8i}_JwGǔG[O[>.9q.ɩڜ XV|oŴzImm}k]R B J7T0AV/a4zXm[TKG)5g7fquwei|&V4Znu޺teZ2]~ˢ{{qįf/f@ZtQtibo;Xh^GܼB7R|~U='mrO~ ©QYyίă8#Gb8-L$!=Jqk=u?Kʉ"%/kTMu~}|rꫵ{N.j7oԆ_T%Eh ʋ!MvZU.4@y75I1Dn5 reIJY-vٕWOޚ˜Go¾]c2@ed59xzo>uw~ۥڤqF&>~B2}+S ?Mrųz[Y^6aOyw IktEuߜ(׋Y-a/8yr9yƉpYZöf7?~=)ԥS:|wrx r4%&o9&n5w+/Πz9jAv/ΣKjy|yإJ2n4}/[\'"}׺$Saseǧ.ɪgJE`욺GڝAwgZ8w' nauq]"& v+ T{ׂy{hV2  f@9 Zmn%+(5ѦLt¨|H@ŝH޶og0w܀\i[21n6)&։s ȉXHccvkPjEF*գqڔ9~*!|.V5{8'R6_*#:]mv|rD-{Bx цJkBo?V86 ϚjTuEz"HW;`j:o=1)OC3<ŧ @Mdk&#DBSkxUjoU9K{;Fof)9;!yNN%q)V}36fKS?4ꥯKkq r.[UюuI֕ªE]4Zq\;Y+g:LÄ/&м@PPɿH-_?wO0*MHt_M "a8;Tmog-5fŬ43in_@4E\dn V|H ~0_>$"%gifK)&{&su GW=Y nП/Z= GloW8)6G?(&ch2wh|1ZXh4h,:1W>QzѪPatfzA؍vL'b׊qmbh^ȝ$|_k;y!F %gK;ynNuTL?IN ho)R8]D툇&2jWΜh2N8i& 2:}<2I|LS'OI lI5Gs7vfڟ5Y5??3~Y[5y c~riGDƩO/,9rl4ymzN??;dy ! 954z%~E7'$2k]i%.Lθ඼q|6f#菑dhOoySFgc4yVvQLǃFu2HyO ϴĘoh1Ur6Y+,[7XY^i! ( Hstx&.uf^T$Hy;]Abyp@a"6?s{$ S'>Mӣ~)ː"zMwGѸ4~Gm99سdOh*;Iه$ȳPPAfyRbl<'*< 9"k]/` e?Ġmet 3.r w׊q +bSȽ;v{S⾹ 7-  vAF|RG9 ERV;t!7q3 iPPuY5Smj $΃GårZoMdɌԿWaJK's7pɚڢsNs6ʤi.q2;Ke+y9m/䛩gP/we> Z:' TF:ٺY` o,8t~~Zr:Ӱ V p:N?zk1l+'>`vQZvcum6㐡Ѡ[?B*%42a}ʅzjmR KBQv E!|R DBC(+ZO*zl1E>c>c(2}YDg &Ew'^~ BmBO&eۧiAԐ0# ݠG #ewixJX*U?*EA T==vuu%-%pBS:fAXl'D Sj{HH/8֙Ȫy9{ 쪿B= l)Ѹi4IrP6+:a }/:PYYV4MdndAN+h"'GxbBToB#@$ԱDYjW`x_w}G1ۛ NK;z;5 "b(JRigxn"S_gw88;2j<5P%-5 wJ=@iٗ솜)Leg(w K 8 zA,k'723EUGMFIJDG|V8X?-,Ч aK=e8~2%H)ӹKWݴmڦ+S`AL+kvɱa69?.IܬɝAt§N@jxjyȩexʢWՑyhaT2Æ= 5Clsjs= C[|pUmk~WDUJ. Bmyj6羭Q5iYDL9W)/Zvӭ]YRvɨ嵂$fD*R,l<8W[d?}<#|2d؀yrǯKoZ?1#7#!TH ӭV/[,i"g,ܙٓ_1FWXY}~5GQ1^‘G)/wh$HG&L{Z?yBa_r8Y}9_?$JԪNm5&h*̲uQTbR$?s2⡜,(T7߉ZߪJK zLk싏W\UX%KN\nęˮVwƪͺ-񛏙[rrW&'P06 ^Ȧ ۰{hK5)55 ?sYODH= yz!‰,%9/MN6W/g,Cw@1(Qb3qwNMZե!\h9&-'(gٿ܉[Ib:Ց` 1d{}\;?mX݈vDusR1˕"[B_6 Rg+139s8LWLyt1ɝg =U_ 99ӆ7i'97u_{dH`%[9yOdJc$T1aP]"IGnͤ[w-9H{BZ!g*4j8gg*tiH0Arn0fLt,3_p /;Kδ?>Z-dgS.gJ *[]ջ,#;7(J(SE^G"-IaΖ\2LNEhP^3=$ Y|rZb2_k]rNׇ Yo@A> ߼abxyڷ=(Bq-D}?)Tj!EUfCp_D^.o$_U&9olnhNun_)fnF)J\ie}2|{fov֬V}ʕ %%AJġ7'\/LLE~DWzDV.&6|IG!WU.e͘ze| x2Geic&>YTlmysj!USM+|pL79ks{9uURu]*54{M:SQiF)—Todi 7iG8xr9-rCh e2._ә+Yz(nv,Y|dnZŪe˶\. NYu8nAI1/{E+Ŭ+y Ehކ7'U+f?qպ:7 ~%^q b:#4zȚ@y ? 譞''x ,JAnuoLVƅՋ ~mһGa}OBmwakӎUA ./^&FcJbooUV|)`<rsDzގõK6Rm!@ n6cZ/Y +_C7dž޷V 4Yof?%$ M+2P@a/68]\:Ej99E*_X5jOfaր .c?.X ƶw݀$XTkA%r~*83b6H % OaU'Pc5zFQD&jlE4kVrgc|,)V*>6GI.S/<*74q~I3za/AS 5,@ C2@e X%F\c}۫"iY.M bTVJK3$ԮQۭQ;QvJHPm*璋jrN#.*HL^T*e`|Ц3EQGb ZoydAҮ:)0Q  bnF8&n~յr)l^3+Q&U l⵶>[_1)rY(ԑ25)zn eR%K>9x;DZ1dZh`c >D\*0`rOL:* 4LaԆcFpN9nG0l~78ܖœiWN ,|- UoԾV`;:֙z^ nTqj1(tA} Ѹ^J6 .#`ɓ|tx?+b?E`5ŎMsP(o((ɈX_\9EWZchЍPD,H@`ݥyL_2PoTYS|iI)r x(=xmQ3#wŸWao,\H`1OʈmLNmwdyH\ȵ}dW)+bĠː hzE^~,w*p᜷5誇6) Bf;COXV,RKim ڸ\ZBXjwmFYqubt\ I ]i/z4A⮔Xb\J%XdX]:Wr.^{'S;tR1xabMx]4`&k$lr(\F#?,)\tÿG)zBbSaF@9tMP]m,CsZnBm@ 슇Ao47ocSU;`l2ЩVPYb<PIqU'9tZ GăQ1G ~t:"u~h\ Xя5DRo aI?RYc*3pAm!Ka@6H|E K 2ʶ"DBuy6rۥsh@8sZۧYb1N**N`6"\o!ZPo 9&2Gž~̗a_hlGP>Z' ܻ̜r\G4`5f *&;4nMKB2a.I1"a x߶'v`%d9q_,Fa_tÿ$)iʰ"C6J , R?@+h[\N1yZ&TXg)1@C_ =?vUV Q_\JF]&%ᒿȸZ"/~ & -AV!ő۪Lk5j4 u]6ލWY 6݄ n= ܼq{!D*To U뀋nշu@1F-@~t`l~K շ`Fo:a= *FF[a!n/(' Bjl?B\oZ(Q[Հ=G%+,"Lha^T"b1XNfTg47-޸[Ei¹j➛J9L3L/O u j=s:si -Qa 3h շ( ͻAeJ1ya?uoގF=BӰM n%a^ֲ6~OY%ds)kѴO1lYAHf ?hH)BPW/&{u;5C,crvWU@3=;Z(lCִ}څ.ui'TJ̉(V#X i(4ਁ @gh DevH7:a Q%y64uT|qQUD% U+UvZ51aBBTR<ގ›0m lPhQCW5q+hװB$+.I+nA(Hd4.Ab-(!K̕Ť̴X8^e^A#SrU䠻JrWɌ 9 2}71$&aaC)ڦ(>ܼD` 0 1wqm0I3d`j@GL< @lLb7:=qt?x=nVzU8 ulݹP|W@֢`9V{[ U_=݀N]ތD ]d[Ar]Iaov>z_gueQ&!SE}spD#{ txu-`|bRü%V aE)|+4u)l6Sbysz>%%QC7+BpErQ~ڒ48QSci%)&Q) 4D*4hzP|h. :=*OįA? gDdb--Xi^v2H¬Ԇ1dPPvj;o^x/B%S׺dHO܇B,GE<|b!g񆶶 ) 1b|!Kۇ2oqߺzWҠux̓AerãkLloî\, ۹z4 ?uV P[d e>E1sDtfA,As) f [c_+*daК|L0 S>DdC{ZqOH*v񉃜zdAmTI?}a^Ѝoyu7# 8i 3\ITF. 3ph≴)7lT;pK有ɏ&o63"^`Skr8":J}wuFBTKuT_QH=*oE1q1JR_pg @OfL10,ۆab\2AT|88iUUMlc)jSfWxnV a6$F/WhN!saQB &g&@glx/AlVIB7@b`oqq %{%aun:{`,| mV-שepݤ]%OM $)yLaX]b:1/NaSD\!9^.}Y~:Mc'G{yhˢOT#߇%9*Ș8D#Q\܌ #'פYwdOuE5Dq&8H#O&N O!.MD1,u*10 AHyTfh &= E^7lb.@)lcd^zq.pGj. /IV6r kDN_#dVAVS^(;=Hml{Z#B*$O32d32k R4mySPt1ѯXnQ_Q}d>/x⸈tWn[|g8P31\@U`ՅE<)L誤1 uH@qX7UxXI `Ɯ'զx~`~Z0oM޳9oy}z&!nIU7 ?UD7ZhJm7G ɑp֏׺컶.&n ^$qQ'͎m,t9s|3&AGfa<5ywEˆt4>lɜ6WpOu&Ppsݰ%') z =:Br#/1`0f "o`RbCg:?U$lqaI1q#K*)57>ȪOxi+ȯT sް |J6 // `=lo@h[ m1POElz Q馂eS n/dH:T$L&89l(Ut)h1dF8 m=n5:5 ;2 G>ܝ .@ mnw&7Ps3.WmuvLS 1+ұb]ڛۂ]+ZU t$32*c\&HVѨ%|yhn|x~?RՉwtֲ 2u/78~9JhBQSC-l#PF 70L;Mo-v ]2tQ ":( /-]P~؇)q}tz-UɈ;Ѯ=aAS&QK-t^Z0%0Wh:k~I#Ξ#bޖ:#H2,ŽCB7h?-+`m]E[P9yi8!P(':Csr< 1CDF]1]Ḉ"ijCF2+QbE3mdo@,^u y.}SgKa5iu9& tl FT?m@ ߈z`_ ^M`BMz4.xrVcm@֊wm' ͧT{Ԉ1 BKHL6 oi`P?njxUv"81!zrT_DATDpsh 09O*d (ϊb J  _] OltTSHj!JQ RIH[yaL5CD9¦RUd%d :ŧmv\.ӯre?\-cHz2l4Y 5$OXb$VH#YuiAF$l-`!P`f_x↍k$uO DwM6N *(9VOn?ZhvhD_4˨aDa}^:.ݗ17ՉU1%}8w#$1Iو0!jX~ی.QK&rÍ4S e 3n& A AD-- ӽ6 Xo<*+nV s) )Hכx߲KUC f:P+P? 6w12d)ݶ r&3@JKl.lÌb؉76dxT kҾ*seD?DL1 0q/V \؃ݬKNG&y迆t 'MGEjmqoo~lMtXiX?` vE=^"#쯷qO(z*0huݮq-ye( j`7BBHn&cd1EAٞ#m&D\%tli'r {^ˆYM`_yA *6*Bmo-1z%}Qg1EtH inF:. t"=FLL΄1]. *H@~(NVlqQ20 pe"վUR$e;eQb=BQ*.HBM:DQJM,+jEy&# A醧z%X`[LXz*`?IHR% +f<_$R8iAdn ' 1(dZ@PX,I/L@vPqAD &%V+#&fvmiT:^}1)R)='9t@ɲdT! JAEr$fJO1(%Q 1j##$851nbx}[/xJrH >a-B0.} st[xfHۓܞP!OWwxqGwXŝwH'MGDty"9"ĆP3dtK-ѴD s k@@ =(% PD\8 =vj(fʤl+=Zm,Vd鐙!0&37M;Y.f =n,)@j2D!SnȔ2jC&48TJ?:$SG"<hJ %YY}W!sx=aUᢣ|\ThlG#!{%TS H^e=r/K<xW!)|rc'n@[֭x ;6Ȳqa$b@G9d6KEm,V〥.}\.YuӸ`KyRbF :P;~6&&0pkshD`?eN仍t/HxaZ<;D5ɀSO=|$DLtYhWfv LE<+x:mu"PmKt~S4I)Xz+W}nTWf1Jo D_,Y\TPRE 7dD+z[qR#W+&fj(>"|}P剶 Az ؟ +! ѯ9˗2f9 P .p5EU2Ƌ(VסyJAC +|Ȋ$9vܼNblps$Xn(nXwPҙa9E| uƈsxƺRtч%2˃7@Kg~c .DnB0 J|"NDA9P5`BD47l.NO[T|z XE3S-$"P4GPݣwcaLZb- 0" NM׏LF\?B:-lC@lՅl(;mFi\} G7q2p@Zce}#!˛n*FcV6YANn GC4OsXRIk>Fuq5n7ak$/Sfw5f9~8mQAO"9af1u `V,!+J$s~#]R]Rռ`jX"N EX?Utrbs[l4uលIF;v,NT'*;gU`$ʳl|vqdo*_qѐ ffw;a OvSt;ŌW!!iw^+Nh7ݤ2uyh0OVqd,~]JAdܧ aiF\3`0b{,ұ5η] ĭa}s'd}.z7o}d -̏'9~:uoyw u+#4؞Y߻g;!/e J 43 [GQj!-ehb ~P"Rҗr49ky-<TZYWll9U/*B5k^YKl}[f-Ԧ\]Wk`ZAʶPa` e)]m3i\CK>⶘3Ϝgzџuphg)'vŜcQoގhEN,!\Լ92j:)daqD[##F1{<=j5pbVRբXu?d}N:N>jeNơ[~?:9Omv;x7,,N8^BR!+eU`Z3,tHqo*^_a䩝"37~/$S2=\27,3Aʧ]^Ew>h(Bܢe WF Sd5ӲhZtr$mrJš 4ɂ\4/<ȸ3 gM-XuFBX μMwvԖ(OD "#FTȢ2;`L\E4J^z *Z=U*UT%us:YD<21h\Wx*NZ%rus6-ʻ~}m.Y%'y|&#f E=s1Ĵ_ͩd㚅2gS+ͺ/_˳M4@l}v1{K.3p2Z/}x̟M[-XڸFEN^0G lZbmgL%ZxZȊ[AKR5^&qedW5y/bvhlJstZjIn;cu3f,Y?J6W.߯,ȁ̚N&:Y2+P$nÇjMk[MA{2k>d5Е;sJCK-}nJlZs] /%PVQC+ovXKKEK_rX SLmRaheBfI_2[Ƨ2޴ƭJ ԸjuzE^Ԭ<>n!l/X` PXR`e,5CUҳe$w7["/ .mUTJ@JY\kU0[t {__3is@t[dѽ̳ k]߆n :COxËu"\rLJfaF ]B蒢.H&qJQs୬A⃰.;8Bb)ޒxR2+e )4"/BЇ-N5VW6OUFL{ 5 gPTmyLeJ}0.Vi4UDR…!&Q|) :1jںF\دY$[yX<:\>?V*s(gLeb ,Rq,uUAw-R[ zw[E@W{NY^re-DFeu"<ѣ$..G7Wo; qqSq粕uI8{-AjI(;zQxǴ 6t$p@ >&7K%: ,6p4 /ta|O#MW/&P</IԨ`Ν$tN6|@'Q7JVeRSd/)S iV&js ϫ %e sm]ZgN 6rgRߠj/|odU~0UP~913S ; +( :_DEWhe83>K;;1Xu"['\G,:)X\ȏdfW ;"MBa(Kٺ{V^3w_#WHScmӻo3clܳcmGv߸ظ#={>gSS_?] ]]1ҟ<^-W'o^]yz|㭅kW\_t9ϟ?pFEO/e0)75R%";,gyv 2;svŴ##Þleƙٯ.:##MuWR;R[o3q:l{#Jm//CP:bM8] *T JM[V_s ۟F:LV-;EK-PjIW"ikMm}fjhݱJ%iK?3\Bj6yZ*5Edɋ[Ez*;ZTZJKaSIcPQ2kz(9W><{gp%RT#TyTut^QrnDe x AP}\IV?)ʇu\vz|Q/-3T7,3`^r*s]w,5gEYq/LYD3=ucIVD#WdCMoƃ_4pv/DPTPTnտ0Eu_;QO9HUNwsAР۩0ﱫDV'çhڃm\4Y mp$KSدT^xIHVE @eP=X=" R.ڥAquБ$]fѬb.u;T kez7gea^vqdɤfG/l,o Ͼ 8ѷ}ctI:6d" SM!Vח &|oT+bx.0շx.l%'VXRe9M>?ise4[?ǭ?kBW@0myfR)YN#;N277DC%ĩ|]?LHn ,{S]Y[ßS_N& SIYx:f≅0~OZc:}8)F7ͺCic:zxjW1♱ -&.%)Հ⪸ęj'a5ݠ1ώ)d5`j L\H2N]@啄:=$$.~⾸lOݟKlp׽z+M1oz-Y%UMbo&s7Zk>YDsw Z[tb(LK_>8`2B.4 ݷaCepXŨEIŖiU@#¿*PP{򫱬j&*zf]MWFMO*]R>%fE EcV[p?F3" | Z/vh64_= E%]΋kw36s)~!}/ȭ?^>Ⱦ:26ΎF]edW$52+DU׋'=8ʖf$Ll}Ěr2k ,^ќ7ȒNl&YݰlrߗF|#7 8;cgj 9SCTW}; l&Ʊo|Kj% %ܒŇ֒%ߒt7pS%Ϥ՜iB1%uJhp5;5UƒÀjSJPpְA#л3!%h4)QSt~_\ڄZ|o裲뵅:ϜVl!bd"}mkwPT, YWM$LIiTd"_+>JYv <'1Dr'jfkbȤ]m/:wmsW~Tʹ7 ?ۼƨP4 j=3X jؽ½+jк7s oA.&OƱL=3ԒZQLz3-q8Vx_Q!oN{Ui/=8>ltZ:hG 2Q~9Q'O?<q)GS:QNŜRSOFm')t|1wFcopūvUƊWܽ.e dRgRxB|Յxk.]}N^viF2N.o[Ý${H$ySzۉ[E.97Q ,eH{h"-'k9]=@(P: RS68Wc9W#2vUؙۚ9P*VT:Z::@).4CHP̶.*s"ph}I(D٧ ?]$*:W:U✷r[tF)N%Vm>YO~UN}ޞKOfZF^]WCnoM%eṮFSfMG_O"Vkx)@9̹#㒨Ӽ 2~DbZƏf[ƫjT;C%Se̸y|)Ct1b(K?dVV^XYvGt1^䔸T1O;d{Y'=N?_qr5'>uO9gėkWr:sfy;#;w Wj+KKz!g/d zi9@i|׮vWxZu?Ԫ~<%]ȬgUu~2{Y0kFQ!uO:vY7κR7..W}Up~֍+<9,wlʬ|pBf}?^?57NXt ۡ^j8Y1==B,dUe(;=AK7ߞ_:x#/fЉ|旬ɬt>'|ʿ5?7N)d r6GUsx#BVUOH# StnV0UWZN|^LnfzF=N3h &9M4  & 6j%iիW^W('{6yA%l8ݝݳJaa,ʦ lDM=].zo܁yVWO%nWOCӏz:> %[n)aEu.M[wMQt>ks. %jrK;+a֒ |38 >4?%5WC)YhzTxgq&7fN'bp7vN뻽3=؏vZZ߭{s\e-:$TC»}\(_(?/ eM(? h=3s.^K O O10c#ĺ\7AdLcMn}opq]w'aO3t)_>hƣpӃfh>\BH#)<+'Vɀ ;py2Wհdh'5:iX0E4+w .GIO`^{eMlթ-IF>aĚrMݝ"aLlmw3 ~ҳ~AE^ $}/H2 Zf/ř=D#Sΐ۝F; DRܓ'c#[ݢZO3K9~̂_}Z{J:޶̝oVuG= U:7.!ws> s QRyNP;C&CU% KǙ5?IjU۷X? DԍI}уx2ݝRpBxV{k8b5`/*2T2^a xYiX^~ݜk[|8U?weZK/{ -^,`w':γi5N_FEBed+i_mJ|FCø@w8M-jS 7)}@ɣ}Rl=ft]kOvH\(C,wzQ<\xRF#@I }DhЊc$ڏD>ݡw2tǰ>Mh-Hߋ2A{Prhηp(cQ0?z8w飚^IxbrSXqa{DzqԀ|NS uFt=69`LxQ?aoDAuë/ŃXbNiz4r 0!oh9KYZ-=-OFz52 lsYvk\# s 4)!?c.U`=i-)D? * tٯErL|Ce-m&V6!ziMS?&gdyЌQx^+ w)*WEם2DGu;,ZԠ"'+V +Yt{50aby'+VL[ O!aoZv\/ڭuw˻nle /,t[].\`] kvL ж@/ {.`8 |h'dYAe6K ֖u`QCu <6Fimۦ7i{`6j MOW皭`v𯃇:+- 3!#n6!?Xqvg\Lh xe^E-聀כ7'@2/Z6W-olSSq Cu_RyYp58/Ϳ^X'Y4ha9Q7Z6jУ[GR XQX?^)DBS' /D^f=B|0;΍M4I-:-]kq W%0} %Sr 'fN2/ jqh lK@^a Vȣ,x@T"o`\HݮbKT7&Z\<:aU5[n4]V ^[+r$JGlE /z?8^@Fk Mz4 d"\<ˎW.) {$vyeeoA! _ZW"5#i4—;B#>Z:E(7BhJXdL @dK.8DZVӲ-PUo!l2ܓH/F]'KL|İHpXqɆ ʸq,{RSȟt:0 eXGKk!xQʹw oI9|1IOI "w(\'^ ޶.&sCт>1;#Iؽ0-DDGHa@Vxr .UH<T$wt^2ӲeC&2i~kdѧ)Y-n#sg$@X_ bgjJTU 8T8wMb3 _-(kN(KqYDw9r4RZTM.8 bsZjs 1aYv˺8)bW#DfXw&,'0" ¤k[sD/DHm6ډ~XR# b6rΩ"mrH<Od+yp23=u"|B ȏp! 6u8n,7Jy[ʞw29K:)eF+i}2Oy~z!orlFYXK{0+)Q~@׫H׋ҭ#ChΠR88&|y~|Z!dCo_ St9#KwzԴ;ѡrII΋ t'}ene[bW>z)xܘK/:._4`O.z@v⍉mǒ΁lS'gy~M1P~)!tN趥7@hp)- j*k T\~TnF+6q_X3Krl:`\  q%3?uOd\l׶m]G~zn l7ά !ծ5\@!3d|E&/S>AnckJ$C BFg{%lMLsEHs%Hw1U`h9Eh*<-d/eEB78>0S(*CRA4ʲ #)$dL[Ŵg`2b10Գ]i"|tmp'0=D~ uLDܬyML ki@f o/tAVDAH]B+Rӥ7c7\d٨Y7j-"ǓN:4A ;! kjFxu81yJp(|'L[%Jb =v$5w%1h >P{"$g v@ iZ<9iDȒ> BU]Vz"s+uSmfP2IxT"n_ͻg~{toq*SX RQ~FQ@qbѕ!$e(w7u*LZrW6V/|J4+rx9'o-ks%u}7}n?;L?)N(2ei;K_ߔ$!vgӫwBΏkIVg}0c6K>8e v&ѐ}:q~єȜ s 5R^\L2ZhܒB7̛&#b[i! NN뢂rsL`oXzr Cx{8\`%azws짪Jnf1A*Z5&U699n|C uv&Ֆrgh7mg%DA.M7[J\5|z}B徨[g듆ӱ6=k׉ Q&I#B7d.]Ҭnp\x<&Ê>eK.(ep-]G[٫C\580N:p@4~$b [i|wSͨ?Dӊ\8h˂={u %>n<[ ?=9V\~[*gfEUy|5WUgERg^jY.vzZ%\V_ |+: t큫=p Wo՛Xt1z]_9)\F%;D(r>=;'J5It I $|MK  g5g:!>ub+enoe) %_ [^$4<=II8&zgX\EDO;Neg o|۰lDQ=ۺ3IUD :HnX$f%m ׄj9ÑP%!`Cp-sw L)RZ 9(cSp,|7B,X$.t_cChMhH:A0,EIAvhcH?!}@6 F<-FmFû r,Dj *e-[.og(+cSZ5 zq |A WB54Pj8ǩxlBafIC J8j"2PSLk~rjiCi-B- `r-$봟BըG V "}twpְM;uzpsv^M%6atY6Z^YI5C}*p^p^! dCs ~ e\]̶Π!׌{ {ق?m QW,>d\D8W,o nvzNݷ,%fih({7bQhw}"mA(bś)&C팍Ods"ӥ\u>·rpgu+c{2>0/'}lٲʮ$t8&5W6gnl Mb.߇~9fx w $y``e8&`5e]%ԥmruAy A-'Pe>N z1 Pa  xFx  d#!1] H-+ǦA+<^z$4*Z A.޷`uD%o-! %2 ~iHOʲًvk;^PAg3(7|PlXk.aYQDQzUa:Xa%c 䢚魘&~dG$A`}\k \LI堜?/t8{{7>@Ik4"Yie7N!^Eh %%%ܤܹM=Xm*$L_S0&y;TȠ^F>kV!%XWRթ2a..CIש| uPShYX\EX׹l$\!LK+49Ox&L P$cOT˳ tPR$c_'tJHDJn[*~ʡ ˃IsGׯ^tmxԵ9tŹSLx}~s/_Bo_-Ѱ0؞X[1[?Wљ˯_..8G3"SB'/_:ݻz ]kW_z]z/ׯ\M]P`ZSa3KA\|2ܠg>ąE.<Fkr|N28Nң1n5th,C{RdY&wSZ|\̽kҘ}N:h 39"TĤ)Y[xW81$s|\t(bsĐ(I(*CA  w氪 i{UoJG㿕_ÈX,|IưA' dsʏ䭜z[Z8\c<JwHeE'weeW|^˪o(a6%@xDG!zA1w#;$DV>7tE_u|_+:ϑ{9ӄJfwN5ޒ4NJUcat&n=1=]*lV!JOt-HJx·FtoFh(Cۇ6"rgE乑"c쉊Xj[@l +|5JDYm "A8\AgmvF]Y(3ORS `;'4 '28jI4R~4 J|J2#!A* 6N֘)qPi}qA7׀tz1+jh(ĕiقB^vVۃ  :gbMUfʌV*K&~tuzseoڻI676W=]yJ o;maߝH:!s9V h]c:1\:ME۶$~Xإ1<!Ht+250*zVn3TmO'Cs~ yNf~nf|UZ E1KH6&jub&<7,TLx$[F0dcww=@/~I$o;q9k'!N/wiš";|4 }]䟙valt p ﱂ}[cc4B쐭y̔&tX=}TM(OtDw&2֥[~%ږ- V<;\nNf'oV>.1a@W'gٸ6NkU>jХż&c=s(' lwX5u8v)= ߢbֳ~Teplݕ3rg4hG A-)mJ5 i\wuOE҉[}o|qYAÌÌ*#p)3F䦅)uû87w5h#6hCh}02Q:[L1Mh %~QJny j`r4/IDS4xUa֟w+a̖6Qjh3 *B ,M0;(uQ~;"aol+Y`؆$`gyi{" ݐ~jf`9BjaWN:`< ':=  pvm6 i~XLw='GzH#=o=T|@ Jlr4Y95@NOkS3{xV?ălj\0P,nUPtȑnٴ,!>CmBo#)b$E*:5yiWZf#XF<ǰ<ԩ^qʒ2D[imYux]"Y6j Z?Pj Mw'#P;2qqȡ9gOOaI]8{ oG"N?.GvC.NiŊesb7IJ  e#2)#r7eTņ"Aٶ8C Z4I fzM˛Rvg~cU%iY/(CEJwӊ},]kz '>t"b鄱"R:"cRlΛ"OWM1$t>86{Q ? >Bz8Y(w^}g næKNF6 jzmsٽVnX PHv08slkt xKNg%  todYVC^/G]_Nn8^7kF(*Xbݛw Q2q{ 9Ts #x|z, u,;ȧ:ƂojE5fIQ_ 2쪰Yod}}vU!_jk.^Z^*+K0S_~f&ؚkko._}ݏ-2μVa^=Wo^/ҋ g4_5N Й]ՏPksl(| E>(ų{zO5 '*6-MWOO==Tӧ=S2a5W&?j~ð`9 ,Zx QЬ0ԧBxe-kDn?P-zB@^w\hXɝ _V3Rmɉ=~ؓZv6|#}er+?@ғ})sb|5}]ls7:޿K2 A9rg s2mKS!3|$6151~#Ȣ>,E=Iɴ3'?{]{?*#nV^н~1 }/T5ZCm[|`(6 * tE@.\RBFzɁծDr+A IԇsݷznRdk%7 cYp ei\&?xZպٕF*=V6N'o Xh/KQVg ?ylHR^ﴻ@Yx[hqUL~Ksهm(9)5"  .YM9h??-8*#2*#2$x ݉gqgq!qZGkh^ǵ;/qOx;N68sWfJYH&+zJ+~+4:S?fUK.\@T$NMӧBpbU+jZB8RF fPȮ^ e_͕7=+W6Z~}ĹtDD1W7t  Gfwq׾͆MH鮵kٝf`)e;K`&|&`@;ig3KpbaбN̕qUXmz,|Ƕ7ɠ)xxlNI&('('H$$JX5΅LrQia}3&ub/KTNMvL!}\vfLݩfVro/ސwzwz#T66F2Hic Lric묍}y66D/C@^BCr ?TYa E{W1obVP^1PQ˙͘HԖ] Uv\KjÖ{,W_9\)1 Ȕ72卄)odKX5R|gQ(OD.fCw%2jD'qYD$Q͗Ls0 ,L. #khY6Xt /qMl!K}CW=F!a$O #CB!+ې@K,<:_(ѐ~ ܐ|Qf^$ J0䳂4e: P_`&_ "M ldMy?Чٓ1@nً7^RUԊЏH5S-0>V_ОHRNZߔU3M<6'ace3{GNΈ8XgoE8+u֑x}CvmQtb߇ITB3Zg7 H1쳺^Tz=yb)DA=`D\aeɝ7W;Ζ-i poc_eH7o+r$):.n$ϛ@=_9n<i3W^ 5ۼOlF-#ޑDm3L)_^ߣB}Cpfo*QQ]rIUTN99U 0 g]??L<&I{0s&&U^:Y+U0݌kRq1TLEL ,4sR^E]#XCz0Z/FŦY/֎!E B Q'gH+ߞٛW#еx4FhVJ@lu@%m "Em0pM*7r'6@8)]|O 1mGe.=["毖$0LdK iߢ!>դPtƹT&NVzu8f8Ա=Srvf3ΥC7 s:- < Dc:K71DjޢK=NI4mW5[g!B^aeSɜt"퉡UXhkMZC,쏋LT*teoUًbMœ@;BXBQK~^Q &v@ͪK㺻1,k{KU䛾j@ʈaVd`Umb:mFﻳ$dc?KMٵ.!խL={<~q~^xӓj̶'2 U5,rW4Ė\Hzq4$2vF2p7Co΢NJ!@waܥ10I M\WӷQK᙮Q םڝTw6 z`YՃx;[Zcg ^f:%bQUh*!X]H6hy$b7x- V$hIO22R:]WcU3i ^bkخ`-$JQތ#؆@֘uGX8[-x&b#ql%E=n<#HdtfopΊ7sZ 7 nA[Rps[D,F!ĭ~1\ຽHUt=64 Ew"2N׀CL3Jir\$P޿`:'fNzI*'k]WYf2/UG6>CZkM@(/%} v 0&q1[`PwLVGQ?t X5,|9Pj[E ԵdQ( ;S\Ogz5(vGPM긎s1axEH7\* @# 5-ۃ6%shumdi AeOܗSbDdk,u+ҩ{;R+⮴vT6C~<g~ԁaDUmWfoǮl鹿,Gf0W4T٥9TM)G4Q)Rx"b3\l"P"Ł\L3Wr:cCړX)SuquWt;0Wr٭Uz,]Af"\`(a)gȶ,rN&]/VZv{UT9TzzѪFQz;2ϋ RvFi525?ƌ#Cx (e tDAI-lem< 6b݅$+p~1E9PYӤ^*Wx#V1!;gb<}\آFcc3DbWe7"-cߓV12J0,laz,ܙ?t5}t`b6!C=MNzE蜚Ğ-LIcL]Z>]Z"!P6gU股{55q)~0d2f8̲)P|iJLDHeA C5;s2߶l%rs=WHT@xؑNe AW?mI%.7"fX~#ԱW(?'?(ʜ)gRk!I%IXwnL:r,^ۥNa@B}*f K,by,U>ȱT=35@T#탫=@Mǰ|l5%BQ`ٲ{rHAOkuٯ`$Y_WVFfk]6ß0?"#GD]2-Cct$i!\VNe7rr+I,^Fou~1Of]94}%1%P-~3b%b|MkP+lM+foƺ;'^sz[ԑщ7lRsN87:~ax;1#aTgV:;:#`r8'Dz;]QÁo|\xYj羑MZ nNgf4'rm}kG!Zޓ"?3$?Ԍ'*b}=Z _Vm<ؗ,!!X!lN@@d,HhojL<蛹s,֚}ZoHcuKߗ=N-1i;TN%}|rLӚm*S7{Fx48Mlep>mL١fU2߾!yA]j461 l*{O3Q^ r;1\% x s\Wp )w c.Pczq=R6c;*awBsYgÝw{ݓ儍ÿ(}K!xWFuz'ߣ v=_͢rTqfJxVgIIaIb#%eC}JTf33*.&%i 3RTA8œ!+͛=khv,Ӽ?*I7)8UYrk$7GHt$=x73*LUXN$ SIǾOUV?^ͨSC) fBvk_:yɇJ:P̾d&,"hp E>jp7_Gxĉ>i+'IJz N I; j̞XuߏC\XA4]ZMV,7>%jeVN0Pb$d _y@hT *K0C;:̛ťv^oyeW/\|u:2ܦNڬ9 luwEe@(G5>  ,& 녯$ǹC^ys]t93hfY<5/a>€|""(y_;)a6ڄ ɸ̑|C7Z +ʆn> өqW5DQ^1mC g)-R߳wk ŝ|>`=h}X_FO85B'{,$ً AɂdM#8SG>*8A9*1kȋ9i;Mו%EnԸ`$<' ze-bW/= 0D( w8C9ifaWze2~/+k-"?q.a^V$ghQO-AҊ)N@^aDݫ%s}#85=< tH; vҀݘg/sx놹19SxfnmNȯquݺ]JloU;vU+37fGCvY , RKIQ6N?'(<ˏ&9TܢղZD]Iv3cql6 IM> ;q3U3d9s]tg 7$7?g u+çIis3pn] w6y~hΝ:(; O_I)ˏ=(`>2M:t/\6M:_!h} $g2yI_<|Z盔tD eç1*|UMJ_u6Nz $~Gҍz˫̽vC_9|WUï6)~M5&Mw?1گ> MjW~߰I'п͠6#?߼I'74*uNoɠӚ?߱I8&o4}eߤ\ǥڼQcht+˫D_o(⻆O߳I)⻥ ;6#A? o C?mҡ 1Mڨޤ&}MR!j)8ґMsqOӊăff1zs\V Z gT`3Im۴Z`=-=tAhz@:AԞ?}\4{JX*Ov'Ƃ3@'aVpF:5Yh~`{o[/UgJqkYm['g03^po3@nS k܉I`]'-y`JmyJֺ:nT[\ z΀6NzNkL dr3Fcf=\/14:\Jicc_y~Jc9TbYk+ۃr_6ZEPu~W*e7׋5p-d 4~`򕲾Yq3qԧiB6:YJbX׬t2թ:\[p,{"\utBMg&_y~ԳڦN;dE߳ey%=t/K ]P{\w235)U~%3@wܰZ%`3Zα l86ppa |\1`\13@blnWZlE-UM*M*xצvM*M*8)]]ݤ]G7M*ػ]?I]I]67M*M*ص]kS >]oRWmBWlbWmRWomFWoRWAy mRWOnbWoZWĦv|hS ~e JU&u<]OlZWئuW G<p\(.0x֔ٮ٘Z-nf Z}ᚁDShٰV4ed F`8u:WI| oyݠY- /{.xxZ7~zò^äŮQ煭:z-|Ӓ\mZ` kC NP0 %k%sKQ6`ɔ<Ç =ǯfiMbt YܡiviɅ JߠX_uI'5_8ǿlv6 T0g3tVples|5ښEl{X d`Pp$uw9p XB|axFKEIcM^왮-[qښhN/9f yP ˁ^j,]  ouE"^w˪9_d:|ܛ-";y?3MZ;hH5mùJnWgU]Z&vh_؀!۰ \t"IrfM^  M~$tZ  '6*h.S L 0' x>^>Ext kҭc:N0rv;ER+l$w!NFrHp,4 ݡ7VLFL4]mv uβKG|] JPY\ZǒEܖizqT0-0HxAp=.^1K-c[|b6GhN-|mmukm:q%.Pݵ}Zf9FϦo.b:\p0-@hЋ7.7iL82^MmhsF'Y2[-K9qj0["Hfmd՟ݽ%G )%m )56nQz뽬Gh/'xJ ~V0_'BQ8,`GY85|N E)c֫UTlM6t\I&%%\#Hy-,,LZ{EH8b{?O׫)S7܉i~'T$\ʱ[^VܝꩱMsA -jQNW0Ӂ5/`mgH,d'w?i5ADVM].`,`Nm_:'Uxo+f$fP"})},N4_V@|i""aOAM2_jf#!€_&WdIk,A# hթ?P1 (3YD0 Eou,QiRi"BI-.M2-,S6@z b6n.⮇s nPA.Ȳ33u;X)~AV " 63VY|)  "n aMA궀`)^ zyB0Eu}! .x8}xzP#w봉@0a]D.XWZ^q부 Z :26`kQT-;^X[}Ĺ[ܢͤI8~Y/]T4 |-LɺXn&@:M:dhKL T O0):M-;]ratr%AIÓOKU>TY' S0%+\ޣ~gzUh(Q(79!@ۻNb#0)LSvDeS#S gtHN챱 $n[PUm9'We*p$cA(ήq2,mXku"=Pf%J۲AS`E3-vyl0Ju0uq,RF׌˻yd֬$c=/LG͎< }6)I$rPchꏎ%6nԥRg ivGGϿe2KrL4ysEpq }ss!qVX ܪ!flEc{lqCz':%ըF&7_iXiL5:=\? =bd5_5lx]QVrY+}|Fkq@Elek$Eo*XNJ/a<ΖP5I-Ohϧ>FdXNxv{kJ49xd GLz 1GȠ^Իp1TSG`5m7􆓩bV$5ߒwz xV&>qΞW_"{ϱiq쯶䍑qxZ$9^J3ΌtO<5}f ,.k[YSu☵9p Du-I2ܳL>GָHHC: `٣ʟd/q}3gCƭF$KPz6B+d G xk6H37q;B9+Ek.eD3'{;?G M05ػ!"Rov9Y\%C"&|[:w0c:V} Ӌ#y:V9t:*T^^ca~̭>|ZUO)!Ač_yglbzd!E&MPmDTRvFa HJ.Z> ̫6Ě-D,z[tY;ܲ>;vBlTV U8RpC] j`ҤR`c'xCVV4mm:Ec_ңdnRΛIE,壪jd'U }[#:ۜ&u,XoM*cd|l: GC& 8_mR^ܖH8jX|O>* 4iee -&ЌGEq O^Xם30i`VN0K$Ns-s]< l,nv:<-n#N&,0,:FwIÎ 00S+^+Oa"heL Ff?!&THqVܥrA @e,嘤X V I56,I\>7v*0,QYIGe+~&HcZ:XUSu}bRE!xsbT$ PQҴ*qt0A Pr0ӊUm#<3^޲~`G`} ?\R[lgp|]'YkWdYfARk5l6n^-XM *OaDp_XbU+i{zւ\O*$V3FXAn:vIu~=AQuždY[ 2G-cpd2Zp{vg0ٲF3 k,+GI~ONǑxNv$P`DBAR*tHDb^)h(ݮ d$uGˠiM*_cRvU& J"}(FSn4蔻N  ҧ12ׯ^ب)dl)6|0|019]0C,"V~$> YqNn>ʦd?32ӄ=Uӱ٨}EToLU PSCӟ[M|<W:`Olib_VEk>*!8}Qe gH \JYSf\ 9):RД6#I4j Q>I;]'>:t(C>_OZ q` H_ !-A)q@ L>B'#PA> 9jgT-x!|9f `) іr?d 4E6Я!O; &;}&{_pSpӘ+y(w:EQoK$~A)ή/U^f)?"Ԃ#dPcpfWpʙ['Bn{p?;[iHh~@ӐPQP(EDvD4|:R"'8 yF"!^E|3k֪0"p:>vaj@Al OxVO@ŭc3XNIo0m6^*Hl Yu`NE1SZZ.vi]uz94.:XLyh` 䖄0@K:&]]XJԭ΢Ur}m[w Ț2QLB:3.0 0=n5pp%[~Bwb\8ckFdPgu:nsBv@@|E9PvP}>Po)::z*6yZ.б.&҈ZF"~"F19?@FȃO<ઢ̭x|Lh3gO]; 7~@4q<+0Yo催T@>@"BffPj;>V*" psND㡁=xko\nE%MXz>a:W%CTHBDv /`"23Tz [2z<oi _[n/TosT:1L!nNFAc"T>_rjmsp }P/R%CJRe;ĆM!!u˜ls@aIh8+1N34 #Au f(- 1 }_& )P6f'fQ6uz% mLQ&eJ1(ta)g+޽lW +QU$$qvGB8eIg?uf<1 q6bi[.S(C/ܺޜ$N{ſb),7NKXvnmSY9|ȯLq6a=G0Js*TahH3!UT(ZJׅ r>-D[Rj􌜞8(3S€W5]sr7+ߒLJӷCZ;"GLEV/Sl|]3,AZq͙!08NOKY+j$cNeYj~lBlba[BbԭD}҂xcr]K;;l@=d4KԢ6+eb{LAi'y:F`3yEX|$ k4@.pqH}nzG~oQ?ȼ3M;0JOѦIA]Ѧ$9M)BiR 1:(΃쬠o&G#?OtTHVGr|s5'ҝdKcmtX\3Xa ˲&`,3 8ψpmd8"kQP!(ǪxgwFw' ~!ɂ>& 3b3͝2Ծ7P(ԥA u{|:q`ϾoV*`ǫ|s l˰wz.C‡\sX)U,XL9M dݐ2@)ioeQ'ÈC%,h@);b'hEn\ X6ߎg[GncT7~l2 TXg؏  Vy2S_\'nRnb]*B+/dFx-3}%4MRvf=ud2"thS_BcA(]f$ϴsdwϲ'۪xHgYeŝ^ 3]']Q}_#ɢ1aOߚҞ'HC)0RRI'd*ϲG)iq˖ձU‰@Q(\_"W;FzxrKEf~2-Z] Ң)&FEjjU N!uKڇ]~YmK cA~C`d(fxgί Iⵢ RPH|!aqle2kJߚ 5Z` & +!=RbX[N6ϐJkiH䆔cnx;Ai :A)ReQ`ea `mv}qKIٳ`N'Zv"IgLzv&DF59 s.PDsv ,Z.4^bb o:$ԷJǠ%s~{TXj$`jԘ_6 &p8T\1wx'WuKUT9nE~lMttG3h-x䮹ٖ%l%aoZ-:kfUJD"8$鷴`Sn2b9}F*R3R~TOdrALQkڎ<6 l)5D?"A\ʏ'{. 9 0\a9Bx:Ƚx,eڋr-˃d!Ds(Kl`w\#ײKz6nyI:] *LfM 7Df<|gv6B^,$nB/jQ`*'з50PhE K=l~aa h2§kۿ|W&tz.--g_KWae+sGgQKX|UgQ긶P Zn@.4kfi2&].$*Љh61]R 4#?Xl#;3T ƭ(@rV6Erc7-%:he 2d’8j"{g9,u>&t8.` YuDzA?ޢ.kz{RH>EVhdry5K.Ρs9t*|53._GW%2^?r@>\Qܥz:\^}khsWsq0t88_:^t;?wΟ<:WΜCWejz1##:f>(6++0m:e jR.<0ckǀrA=zpuqbpug5g^@Hn^(P"k.^5(_tT"9 #cJ*pnN{$9?r!:3P^}5`U8wi_ A tL˂Yˎmi߾h9&y:3sV87@Fwk$H9~5bArצ?]cL{&&yxs x6TZb_=rvBچbn]ޫxR'l-¹ȃY:AIgj$ѫ@=}1Ye/^螑Aר#{g;Jޥ<2w:v giwyt#.S|p,xyNR5lPs+wO%x}f aâ״it𗳦cr "wFUs@f׌.S.UL27ۯ;ωVJq 5ZDkDrO7X Ͼ f . Tj xA {k,fPUQ6QDR'WJt&BiluTB0+ vl% Z^?sR. 5@j+-_ Nze$7 g|'{7usp=0)7 ,Ag"8V}'IZ` 5<5X |2*_ aUEKLyRkFZ tJE_6X@&I9AsXF,HB6FPJX':{iR fex:a\߰uK3Z4:+~D_I@&aw؜V V y& 7*6&DJ`G"7^7p5Z &2`ukZ~f#dX!oX6VUtEY$QO(y6Ƃ= _&_~ou->9{~F޴PԚVHUA"(<9`5HXhXY?Clz fU8fI-pqAQo@:u¢Eb%#}qR?5MFnS"JiYQB$̬6+lTk>l'MܝfcA?myX1o6SWΟvƵ$xGz&X,݈I;Nkv/ӰM,ݟ#寥ȑ w?:CtA_V ƵkBh- }pr7Vp7و.py/)עN858 FdhӾ@ Ԓsva|Jug!`b| 7 {cEBt=l" pQ"ioe9-ce3㈁ \Kt 2^ρvL"n-[JhUB)@~ɿ69[8-Ppom!# ysVk1r`D8[*}Df-Y"QS%z43WMl^u|g ɳ?ݺZ\x 𩺾ca?pc4d)/F]( \׻,Ė0]fgW\%?9g._4waBN@20k$>rr뜇hɭE-ZXrptOH#WD_0Mf }̤9+?j]߫PD qD]/2AkqU?cQ2`(|K3Ns^1)zc5 1\/t /|zglcG &o_0xуѽUJډn}\ |r+#BϬ+K]b{TWפB{n ne4baBX𽫰>wB2.&%\1d˔A!?F * c;WMf5ʹIp֓+nXs:N$` "(đ\c=!=KX\wIBW=`5\P{_.uHx5W`\$b~g Rb\A~9 ݞ @ѹ~͔ QܧҊ׮]ՅS]HܹsW™˗?|~ο>wN]=;w/vy>xc!_=uܕkN={^7+z},G^pqkϢ3W_nѹrk /౫o,_zҫpWg^-\|?zK@ kz3/sss o̝_]/^:|c)Vwks A޿~|x6S@EvY~pk0) 1|\PY *nR=:Gn+vkXm,{k%=Ů["Nzؖ?lVWad=5&M7ϧ&5G(nQh֊zURv%bEC>P[e0x[F.f1=0_ nqxݶy 9>,;q.Bf_&ɼ݉x\e))h$Q67xӷd9}T|j-ɉsm+{qaKPP*E4!Z`CqF74׍^FVbZl=6 }uݺ]Rw s矌E;ۂ9IWZtv"̓c&ep&OkbSui(fPbwEuvf,NV.J߾T>_p,ȕ5Z2YeEhYS^T/!R4`}uZʅ9AV J;qL'2*%_)~xeXp+b3D*fAql(~^Ƙq 󁅏ŸCx;~!74 :D6 "hb̈멨)##7-U4Eu1gE哞C,h 2 u|LiA[-N;cILJ km`Z"C(7,|AUrj-s]G\kƒoTaS$2gSJ#cq6Ew>QABbʳ+R.10*4(c`:X^ 3t "q<:xj(yd6ϖ#,:ԿMe}=a1U&ُ'r_gR!O cB`?y»E|Y(ׄ' 7rW("?"d=Ꙉb`kzcP~̆qǝ8{v%ՉИ8k EQ J~1 ~/vżB#akS~|ަޟ;y{ `( \wؑq-?uL#Zn#k,`S](ͧHn9 7*6 fB95VnƶK]?1YE|#KV[`b4i|i+Ib4'.BrԔO!LаT6,5e’(ٜYeGSOƤgD\bQ_y '%bb~LA=vl[Vi렦E8M)ݮYk`SXizفl /H_{&x):|W:vk n$lP$-#( Ce _bz K$)DۉHY+\ _b_~=N?>)&$Try^2CBtWA"x̾v0![˲pv q?E6&?L 6"jzbsM N"C#\:Ws|P`Wrݙ8fl$J}Pl ja{541#J;m=9,)$Dfs$ lcljb蹅nv\sYNm!=e23pmo&#{ndJ$k&dQu} oK|5j-E蕺jJThSC_)Q!?PK/.䡙<49%YV}l,bexF: k˫UTQpٕ4ͧ}s:jle`eik%;./@ ^7 j8%;q|0Mh_OLE%c &޸)BN׬{z5g& ;Nwc#?4b㺆hE.!wt]I@5V1fMk: bX3EQb(YX&DK 5%;ks,v6v,%Thp\; @KrF8:OR>4AlAi P!VVXHm;8͘LMg^nLl\fe卍kYw,fG&&pfTF 0Tx}JFF Qx{ ,+8]\ßHLJW $NAKc}]LoOG>pu)}Ż|^Bv#hզk6~5"Fx9[p]?>v\+?}8xk~r t< n!J*JeB ͸ q>B-ьT UXiTH:]S7](bp"ьorмGh+ĠOL˫vб:[vJOLOiP& o|>BqWU TTUFBb ʢq=!`#ۉŁIYvȞjϾE >wOȪ<|\/;ѨFDEYK7enITϊ ׆۞2p*DVC;VI,00A9_ ^y8Xaw'1jhMQ7q |hEl, invb8-Q}a AL!3Nr!8p$$,jF\2=Z> =*`rI+hZ gƽҭ&MF ˇ2|,~96xdKx-t#}8|ؾj6YU>!kVRҬ Cڝ$KȵbY39Iq.\x}dT\b8vK7/AE"fe*$dH՜gte!UVWxR%>^Y=Vv*[quSwPũwK/VkrB-+U䶐[EvA:r5Pʨ[GQ= #(\"WШmsno @:uev}XX.Y] FH.v3E :=E0Z kF @inY4j""  2Z֢jtL?MԳ_T%rj;^ j7=o' u L,/i"RUr0bv&>,et]F/xeW6/B2*ad_^R@j+%OvMuV3mND 4qvp ɨ 6P!Y¬ͶUnk[HIքY`ڃPkQ..@엋:2 ^ڝe96a-vڎMMw00L{+ P?ï+]tj.W,T˯ rѬD.rU-K'y.!+p :s=zF!Yu^ImPm.j|OǛ%2KC.kt>xhO5\s>=w .\j 4Wᗴn ZhPF21ីhE:juPB]ZF-L!|cK3,xոm8?U*7( b!_iZFV@ `8*|7\\_m؂3.nB(€8Es>FBM+Ҋ5:p ؏V" Jb *^s *(;GT1]j@xۀd@"9PMi]~&h _YcƬC`:V`8= b06S.>W8u) XHi1M{%灺)Gx0/L0؝pܻ] *fZ s2zeJZ;Uz slӊpi{PP.V~-X~ifaX4}=C8Ԏrz#^ W^ZxTu1Q6QrΪ5w(|3{r5?n/?T뢺(P dX{'B oPѝmU xKLIgKgG/`xdyCT+/.QBĵHZZ-zXt5z9,C ,"}ŠeТ"|1oIowrxVuA=e;+6zt1z-.۳LߊI4cFa-|{D``'tJ鸉WڌH=^υ_dYtg ?6/`6Wz ~ zDLO혭&) qK]"kβ4[hJJ '˰]. 㴉:V4vs4%pjs 5.HPMh$Z^JKnl"aUXe[\ʛ'QݲAQ[-soi곡QCՄNس  =L99]fhn]xZlzmXϲ^Xו .iȤ֝E@;_Ġ}{Z1b%Wgo.w W}9>~)\ax2WGr O7n,ئm:ඣq=,AZgX>v,>IבJ iCPX #i$E;}nß#D[V .W >gP aVasEe GwTQ&\:.IcTlZVP <~O$$d"c~{O LZI? Ŷ4d(ELxb4mvZ-k4Q1T!K,4#H Sq%vAl %370z0oB5pPPItƬdws׳l;e9emF]f㱳ޜ"mn4Xݤ,8`I&ze2-?b9e*ٞMQ왣POH1&Fɭpcw" DPPgHKƢѣ6R 7`>%欄P dGcZ;Q4azNZX6NY8NE|ϋCő/KwЗp-+ )c+.F:ӫ&3㑖;eR^:(pux 'N#Zc AE΢hpx>MHWy&Fxѹ魽]Eȭ4nVZl-1]RÏg7"\\ܤ ۷zͲɦ#dPP剎z(X hz/X}%b0&Ni`y# dYcfK$qt %iFJ7ѐ;Sa1[8U5 kg-)Djf[ˉB!`־N<>!=0H$z]u\[X@ N_<;wn~UP^xӧ.,\>7-\;uB[ i<ļCñhp²e,qɰ.l,`%4<09:6a|G  _WgV;#?8qXM. ^ҌPNAfBk}t`C0XҸ}3\"'p( ?IUuC i^jHh3BPB 862H~e4h VgL'QQ]TAHeis#:>(%^!rR}Kp 1f" ~~F%VmT"]\DB&#u@ g1CiiE?;rfd;M&UԺ-|i8SS!͌}M@@eEu9U9uP[|(B־~T۔(9bMQ@=<0)|Ie+%E:YքTU]2`* p/y|w-) ˼5_#O(PcJ(PSB6mI-mB ?,D(PwB[?.Y(POB{Q(gBDŽOo?w< Gq7;!: Vr%WK_"w u~uW"N%8הcz1!0АNJarڗ^(,2%ߌftEi׵bp=Xvp uvu`ٛ ThҁFr虮7Zp$`c:,5㕜,^s:F<|䕨:dƀ^-cW3buYjiQ&t {@.WwږunbZUs*VpE,\00L,%ȭ՗bn.6_qG\)Aµrkď+x"?YM P/IBwWi$sXiTakmݎ[az:6FyYş a72Z-wR},Zu.McUEmO^/ťj-i0nܨC^WC7qg@ P8"`lp}B$7V ӳan:@0C|8aLKw],}4s"۫ Z/]+VpJaH Ew,-[>$ 3kbPqxv8b0Ffi+8`nˋomxDK Zr"WHwFg"hKY<+3Oz|?!6 (.SL3J UܷZ qóAm`C 8`^(xI6cAaAрO(gxf1A[.X\BOźLA Yba|VhS^i=<0hm&|Q1֗jj4-h^jwcpۇ/k4ʃQ_2{P)&Ä]z9[_"vo6#>z9|9z8!`k`AdOţ6ҕ).JBtE#5n0ʄXd×4/?;SvCm8əX ;0Smƺ$鞳MSGq/wˋi%ڲ_.L9J'G׬E%WE52k7J@gی:aEnYCRC`PC7. b󢢠uAqDE\W=,@~(;5õ>`|A e"/61L b oEbYXj#erXت$dAj?8,W`_] >td}pvaqb\(FoZG*W^YXE!ZZ>#2i0EP1M;pP*uߦ i,H X5g}9SCa[^3Ld. XtV Q"oZ+̀;nRɔZCPN3Xp@&(p 6ɿx8 pmZ##/RE//" scX?!]#`8Ґe%~i11Gprg`~`7[p? D D$:R+߼G|23遡Mw('d)մV{]Ƨl`:.6l0>LFixtl&^Rmфʶ}$6H% 'EaEh/&* Zv L15nbG v₳5?F@ĥ\ 9Ŷ +W>rVB[d~-޷6>LԱFIbs{HT-x7ə7S;A/ :ב6粫|Q%f› lR`8v7Óө8rE @I04'ƂM,V+K+/byK5Q6￯Po#!n°C5j8"hY"V+֝l:$T"12vъ45#,_|,nz9Aʃ|hO>?+e xqeb#ƺwD7;8VĶߜz0rB/Xf.u+5pvmNV8\<,̞3 _V7[.HqU5aj9{x/<;|@5>ڏ(RDSW^s[+ dVia"b*(* ̆ȭՐU.lscmQ7/ȝ7 5 m6k ar A X|!Gl9.sE]+p@N!w+b1XXu1-K'r96>ɃSKV0s+M̐N @u.[ȩ!#a=~Eo y+[A譊Tշ^E #ZmuAv Y'Zu$ħ[/sCSD,PD5|,hcgtZ ."JQ؋D*U,QV&)R2%^©4"Y|Jh}q !IkA-ëv{ Yo"(m˭Ni/+[AlpSE ZnB@7K6.V= Jt"^}Xq\-iVֶr B(ozeOVsWA/}"&I`XLXP zI DέFv `,e֔s[8t(5GWsTZ`Y.hԫ aTAW{Pnv=ov`&أ,D)%xJK:lc@[Z]>ҏS5_4{V4u`mt),Һ/Vvn/pͫ6/ ||C]7{X\~. 64PnGĠ8OҐEFR+|oX&! 1% ѪF>Rp%v[߈nڧ?Xt ">)$Pde!\j Xw E|0F(Od1O ^]b5؂Є[jˏs#7^Uvlo-x, N76k;v]E<{׻Io.ibJk [7ZĽ4oOj $w*ȃB&~ *p5k“szp eh鬘Y65 D+P/1|16n\t1銡e J^I5\r]]?2]:BK$XL<6L,bB9-b0{m.f-MN<ٳA(,}8\ZV au5QqͿV`(֊gb4DL Xl$I&7bJ͝pD;D^P ,P TFt-"[8TBEk!/ض'r%-cuAv}$+8~좻p_Ĉ\[*>&(\&AY$3cg&8.cbY 5yD<=A1m!xRD.pjae#kpИdC'6`+MM뛬+,ZN;&,]{0\VXE8ؑtC+M&`ZȪ}kՐw.{3>VuzkGrh `7v7zv;&XVl-w␄J^CL'pE# YƄ_$VS}׆5\Dݓ?"8m?)acId$R$c^fHHӎ7`Y< uܸsl|#f j2E~v#\@ byϦ6Ί2Wo깠]5o=ԈCDЬ~f-$U0-n#;o:#pVA Ry?-8**VS.Bi2EkQqAr&IX+}ئX`k+sX f< Ȳe؋8YzEzSu؆QHЉևSdoʩ3 9AfÏ3,˪69QHxKb PXuk b8 m:ބ3FQV:*gK:t?m G $al~S>Ix 8DZ:izI4Is9ڴMӦIzM4g4ij>Ig}ow>a wgfgggggggɩxS !J#Fiowɠ&'#yRsp"A>K0L~]Y>6E:pbwGC({ޓ&qAeI/;Ox1cJ0c>* d p4PjҊ?{wN=]i$d#`=Jܞh'=A/ @W)rvD"afzydgIZ{CRD"OPocQ9o<q7ާ |D"~"^iA7ӢN1o r" ;nHP5Z4j>kXSk@Np :⽫=4M%gLzN\Jr!ӯ sY6sb@adgRnr f[\KRģc/xp`T{ʪf)DhD +ԇmN}֎ $1 pv/l(7#䖳"H#ƷZq{JJ\j4%5h"u:; O] 2SprI=͕fP-(u)Ҋ9g_Iwd*X9*W?W) %|PeO L6DŽy'#gZ1`ai)ֽ:r$̋`Uw,^It&~*LtEuעikCIe$CD.hFv؋25vZtmmJx"B$ 'Jjm  f $HzZ϶Ĵ2m]4 qNā5ZnWۣȫS-uFYr{"bPYBF$+⟷+A}Q*&MHTWe^*臄x]4X-.[C Ъ{=}Z7*[lL",},}C!|e}tp[ 5J(_C2<>_b(:>x)op8=k1¤Х=RMdB D42&9BH0R ~ RE )RMFȌSMs2)gE8bǑZx1#(by'K|4CIMdq})A.`ϡٓgQzJ1$]̠*Eح,n~0|+g2WKLiuLA:&6:n /fE'Z8/"e)rV:j8 =9Oڗڇi^O_!uoȁSȹ=G X/xL.w ~,-F}Q쑂/M|e\߯ TmfLIEpPPHvj̹%)N˽/Ax㣠eYJ6K24./.|+|֪Fa;sՇk{b(sikZ7:N=uEb@p_9jHb:-%n[I& \NVހvd_,1o+|0Jʗ Tnk|T Y 8I"uTY2L!#*eIV٢+fxPdOY< z#&ԇԄb8 -9N4efc:GLԁ2 ҕ*؆`KfFvܝ.( /;Oyzu-}%%&BW֊<0ɜ !`ۭtzlXZ-52Dǘ?wr854ir5 ]orϟ]A%=6Nܴd.߬^;m>S슾5ssRi.V[(Qb|o tu,,Kims<.a&r&om럖H]wo(F[,ĵKQ GioUjv ɚ.pJZ\es3*Υp ]x _k wP㋙\nf; kkS_\XqJ^Ź닯/7R /3sٙ+@p3]ק_MjՙK3KhK٫ צA <tl;&'CJvBX aA7Zi?}}ږ #bqW:Oho$wϧY=Mϣa`ВWbg3EP>ݭjT[KJi?U6G)L[bjcQ<2r }12"{0న3C€Rt*p<Tq5UvGo=xX^J4:Ծy\dsmuY2aAɋ ޤ{(Q\ea = D$iLDCCNqhgfvFP+Th tK zq<~_ufx{7v/_._￱NjœNj]#OɅȞ\ߜ>У_\Q>=Єš k)d >~kSMˏi0}NMѰI,Ħ(iju)"J4@³VGwaNTwyE |4r4;An ف̊䏡KV ؽ;|MK!KV䢜j;M2XPKΫ^3p3_=Ýx;حy}~D`xGA\Zz͊Te;5gVw *(?-/>ܫȀu_r\U}fn)075!iusҰF@Og t1@׉%KofEq>W4tcmY &\ &sa )qXfҰFS3k!y1q/ ;.A.nmi@uMCv}6+K?T.\>-e|s羥v>Vj6M<,T\9Pjڕ(?C 4IReۿ{&Awr Kgjz n9 lIϛ$AD=D0!Z혻k2+n!X?E 2&1 O3a !0"P! 0W[$"aq  fy G3$A`K?ڶ1ǟ"f&TrhYLp7UCoFRE4iLu } mJ Gkt2܅oMLTgwpJD$Jd"=/=-AL =<3ˇyT+UPpxUCmk'Bx7, tMDzX9Rd>MI3qT<(SV*oZRAaBYa1>r^yO&3 ^N vw& ?3I=Nԙd~vfqi1|FG@YJ]k"05j-̆Qnt'p~f yz3?Yu,JJ++PydN\X]ko+8g͚sZ1ǯ#BWVׇ'51\Teu"!Қ}gu :IQ M72]'+Txx?(4~ ;1>9a0>YD*Ӯmo[9c,Kwm#>,ZРNLC|ZܴxԊ}'LJaTX{寤̥] xo.M}l"-rn~)D z+WWKQ(55w XP:+U'B^vL ^@>?;3vrxni WSK!pRKaPz7C3ٹԛkSsᄩr\,G(]fg^7ZK!`./XJ{s*!OoH JΦMUn ZJ-,xa|A Oq%+ 8ɛK,C""˄O \bMWa'DCH\>NҠ{KRQR8?BG{OGwbʅx2 0H<$aPI*=~ūaэdݎѻ95z3C=t6%Їm(_lf]*8=BEj,o.eߘZ<NlHI*!+"Mֽs^u@,Ca.!.: =RZH BjnIрي])0ۢPH'ӕxfqEdƃ#ѡ6m{Xœwݣ6{ZeFԎs"ZN;lt@$ZV-({D7dܾ}} G<፫.DBk.l3EX_HE 5#={\ GQ5!N=I=e@SadQ*kdr]1϶y5*Yo{u-3ؕ,KMډmfFGp*~XFh5RME@R,+s\q{%5²$ 5A16:?׏bmhx"gxӄN[rxnbxqwxi [ Nj#vꎿn/>mxW[_-^g/_lwSxv_˻ŋ/?^ŗ/v;Fug/xٻŋ?^|nmx Nj-^|gy)ŷ/`xNj/-^ >[_[;Nj/-^|oKwxeŋ?^|n Sb:cxNj-^pvxջoVwHu/Ukw?ſ?^|n/axKbtu7Vlo/mvſ?^|w;}uǷ/~xmŋ_?^|n7߱[Nj[?b~!O:nI?^|nߵ[wݱ[Nj?^,/wv;ş/-^Yž#}Njw-^|Pŋ&nu {xh"[x_byxEvm_w-^|x-^|x-^<(//ŋbNqvS?^/?^/kŋEimVwn"[?^wgŋEex1/6nuEmx|ŋNjnNjVw_w4wNjnnJbM#bYE7*E*7/H@GW+nB0 ztRp?sާfm@%\@ײ7󓨆Bf_-]zzh_7Tgw{vݽvo޺xG-Z`~et1DiLF79f( \PwJdjaf2;%CSxRɆuўݚZXz[XZja hFzu'fRWW O5T^1;+P⠗:vLkz'?no\ u]c,oI<|WV#nk{!ay V׬* <3O}:-ny-ぞ.S׌d`b$Uni>&*=EIZۀ,KouG#[?(KQ-5̓+PhwؗXq.#-hp@aE(̳hběE"ye{Odsbxyt"2})c04|>?+|0/\^{HwئROs,kD1;}KTzaDy^]4\E5~ٙk3f~RRZ-(OsYSCj8ڔ9 \P;]8;o&s 1M`/qi 3O-ps¢ٚο]|VfqBXHssq koE5[ ϡ(JSlhdO-f@^ܯƐ~@9CZsQve9~J3ha;S3jf}kvhi^4mסgR SKf́Ńdk43`Pg/"e5} %gNhṥ5>~g4ڝq61BL3RV283'zҬ/rqE`f+ SdTC| if`/jFC쵩׸w*ڕ, WjF?,^emguޫZ)vf%lFG;>IM-q+WoL-Eg;Ǽ7c^Oʈw`FHؘ3?k=xՙ Os546lUXPNw:u>{%uu oƵ3['*1N(๠#;`N:xQ^\J]4~ZWdxib*j-{ufJva~%+{yް5qFeca^3`vOg>C^՛ƞ6{xOjhrmzkjDJ0•CÌfqzԜaff1ǹEu;Y1 )2rElLu1[G۝'pq~{m?ϷZC#`KUdCZ6fxY'5xTh;8#g%[F{=3tә{:s.M(5PF3sBЖƷ}-u _-{Ƨd42sԩ^ZLt.-q#+N-̿0u,v-Kd3"Afų;`c$CwBݡ{#y"ɡ;Rf'ʽ{ } iW2kN]]J-1Kj3=DN1Ӊcbt$Q#߾j^1cv2i٩%`}˴>.}ӫS?yP60wHPCWV=94.cO+)L$f3-35:=#ɮ0R*Zj u*:_ߍ˳3!:_[C"ڌh؛?9^^i/z}O3J2Eį5L />s=ȸ+eR]qbL(S#):f{IC9-యbtG pITi3YZ}ziBɷVzjYZ/t_ZVSϕWv0y^e]κ˼H]ۛ`s紃]nbvb8_k9ؔ-d)&ڋ/q23Қ^+7Jg^x8rPK{D_mzD"MSWo>e,+x$>)j 7wd Tk7l )P]_U|Tn*. 5:]ē%,NJ#FV֛>F%>gı4hV׳^’)GUR`m& 2uxa>[tVJ:L #5Rt*H* g9O:NRA Oa,\Nx>J+p}a=O|Tw *PS7iki46.9,y,lڪ}#Jj ?aÎuX1Nr~a Ⰿ@ V`/S&R#Vm4;-UV Bq<+g4zk=[wiA BĊ G3 `"l8Y _ @l"\* o~В l|X JiUw+%#WP`;C74%V{{XZQAANfJ+paf0 58kf9 6x V^kKdZ"ۿ֜- p`1<8dk ԡ i,*RmZ`(HXjfB2? ד?,$ɲ Q˟X8Z ?5wX}p.p]{,W?=/k&6:SZW4:׮*:+kp8Z{\S ںpX-* V9XE4rjʥ 䂯4.kΆg:TG5-al䚅5@ܨcËT! LbR1ifSSfZHIIy.{|缐:`NZoRo]_0:} ʇY*d5KSK7͒Ր6oN-qGcj`^Y9K/dC@5*R+QZթYS^Bj~U{ԫ)`~iͨӌ 9+%r^/AoG7fzg4ɹߜ2b&9Pgg`r'Τ̒{O^ҽa^m?geZ=ݰGNQ9A˕i!٩,^y3uD 6\MRIFF{!I7snXn6٩iShl3H5#Hf &`Mޣ)3 -il%M+Zh7xSh^ر7.֊ƎKk$n$jj.VV0^>`&^YdH^]HM-JWV`: qI_i-1b6dze0y'=A ۵+vrSM78uצ.\d#E#`=1_ú1]PTLaAQbdYczʲ2XE“Mq. w<{Qdc.X1HԦav5]> XC+iSSSُߘ_2p͛]yצ.!Mºav1^Jr2@R^8 +x]7gFX2iӑݦ3WRsK3WgyV.TKo^pCvCAruξp/ݳúu-F0rKX3rCv=﬿05Rw8e $USK"3)axy){~ rRl[=Wb{KHu{㮫nWWTՆڈ\Q#Y15DBOEUP{3< !7=Nq8]'hi➹:;etLyMD7[5yB `++!hOݩT6~1|L%D)B2 E*ҹD i^iMeĘ\E9q]G•,SBXXzKgTGV3hƕ)TҪg:zk)5'c>,)J+Rv> zcƜGސx^5q{/荒tی4[.¼`Rc+/_sq]`Sc: Kq)G tmީۣ~Hʼn| C|ʬ.(Tq^Js=P/sgZ/ 3f%#St6oI!<*!^wZզS-V[%>҇'Ds2Z"4 `.ahl%6{@. eNA& h;.+<Pq$ &ɱfB5\;iٕeeR)A RB^1=E;g 5wZNtCYGW"r$BJD(ŀ֡:8z"s\A['vCS#Gx=2|KONdF`O#U8 rYd[5LęSQ4{NHh %P$}ˌBDdxeIHrQVKTzu2`swb1YvcD%%R„aeB(z$@8I`*5ż颕rn;й%BE%NU팧g٘ j9l*2}m-CMNH >:@.4_qdHOv\c{Tx-3oj /ڵՕa<('BCH,b%(>}v|^{a %.d3x>/$J_%5`nqDHQg=:g倽ɴA wE ǥ] J)V >>44ԛ^% ؃2bOHEr%PӥkX'?WU|'5)?88!1X +Ql_ \+p O#chR6h -5h޽.=wdRHrW RIĹrFiBPӠ*E e(8coe`MMdia2mx%AVxw ϿПrqg=_-75iBpjES=#mM^mdw>Ic/(VDMl5ti=  M1Sܖ3>`V|Т+ D7:UrRܼSOQ_;ҝf& _K'3er[]+lIFKJ\|Fef؉Jږ.Ŗoa2I"kD"3iRt-s6ZiC")PdW 7F`Gqwئ0)=\q%oP5jZvqc6o('7XcGdpoW\:>0h[>#hKQkV#J6Opᑻ[ 4* ;s6]Z] K\aٮqܦu( 0Of8ABy,FvTi9)7-;hZG ropA@LPA͵zu5Iժ 6k%puj*Vae|@bSݨҩaEG UznMUZ@:ep/#, +i'Ѥ#=41&&wlOq4 NQ{\DV?@dҏ[g'Щ 4c/{JQ)GXq/9ހ+MK*ѩ30|#d6*'܀=6fseX4~];>: ]O5iY ',f⍵]sҩisP-ON:nne0}*9ǥʚJTS%^&'.$1ڳ-vk`0!¯b|A}.y_$ JM`0:MqxkO2Jp,>IThK1aFMSw` 9ZAw`;oDvqW̿>_à%1OP䰶r+NG"0Ȏ*rY% \Ť5PyZV$qX>y:i物J-xpIl)f= Cco* LpYWR>rsﱭ^pWa3 Yh`Y eQbb͘Xe]"LJtXGP™t ]4id7ص򶾞6*vS0Jb57L^GNQ;l%N+WwEO{+$1|u3cNGsU7fnFph $}$c(-^?e?߃Xuc{6,xU7~EEݡtǠ–پ}vjKB MZ}$p%Xƹ/Ppד <1\m{6ve]tGKA'%C"H>u 3) % ܌݈s,ZrTI >2f}%lÒɩת\3`>aip);2]d][ |FYhˍ:Fg+(3|cVv#`~~l)W&v`E FfǦd\w~ZLe(mir{qTš^'{E{kOܽ o=#=w=Eu*l9%́/MǨPݛ| i{EK Ht 2^ ~=hb=hb1iio1z&e[ܲ]>iRDq=*';C?mq a9FzϏd7=?2;ďL71{~l?]oS\%snmv";WޠVΕ*!LRJi`7A;#y}Vb^%_"G2'Kcki|GFQblq#x7|A.Ńϗ/(wPxV0ؖ'8x'Ę#,c]Kl/Ñ|[ Oϝ{;qD$wD,S>)GgK}&;rtC1n~"%޼d{=[xNx2̣I"ҰѲ/ƳCz⑊sX n9d UIx^F)g ycGEC^~2g$Ο6v;?\br嵹F$I{cD٪_՝.An޲;@:_QWk;^&ڡNq_h G"v3TN''S4S<$>)%p(r5ϸ]Na]bW˶59\2+FwUbH^ƈ}ң9cݗm%ʤG ^؍Qߡ&2b<>I[4K>h)bPSgX QqOU+\l"zyWC aNP,n%1 U,nnLCB%kK'2AhjSŭH'>ICj#~Nx Ir!dHI|l FŽTn?`wMI(FҳAWsQWy@ k.&.%> mPG5@>]RSkzQ5ۦ$( )V='_[d$SH"SW7$LQGM؍VϚc3fGD+zG$%KBUt+5H*4Į~s*zt_O{)uKĖ]5t =26Ƚ6V!irܻn;<|[Vha)r)_GEǻ~s!};cj(M<_Әߖ6fRWUzF7?o|Mȶ2GI,IZ~'C'P"}.WZ)na4JxYzxj NGR n@hY"צ YC\GX4+`t2>I5UbһKcjl)bjZVr252;Hү]lиTy I7󑜄@fm<}1!x.6A$LODh<=OyFpM$CH$v6&`[I+fa\Ck;J3@)֜F[QHls2]ġ;G6 b}*Gwow?capXHml-ӱ8"G;3 L¾#Uwd*ɠp$HS鏿tӰ#bGzvDQEzóGxħ㝍Ffg(y: vdT;";(#'OT3fǬmo Ra NjLH҈Kyc+#cŢo#:|vL֑΀NQ^p+kaZoQQcĭS)USQ4zՋ$҉f9NY9J*ÍI|X: #{$ז͂>#O8bz?v(^\9-ʮ_9Gٳ]& VQ?>6%ksA=;G>΅iE2q5ZjvvhnA DzҞx_#ǻDJ+fhB4i&'A'(N}JƗLxAzFn<:}bmn#x_/|_F= ̜B).)Wr8?A=N#В:kEr\Ot֞ܙgD=49R/QIΘH\U`.a0w0Gg <'ɻ9ǿURK`6N"S6]^K 2Kl Ĝ ~qN}EۧnyLǴCU}wWU}}j{G}EG'ۧ&;j+j+jyHM\4 ]7p]26pOK:l'N `=H-2+8̃,C4OYNZ=xh2N.7QЏF:'93 @"0wϹڻ32O7Yq]YyEqZ 1xYϩ.P$Fi6/FR7o /%EM݀ˑCD`*d텱pmLa# XnRaSwvhSIe/K ?Հ^sm]'Nⶹ*2^y#CCC|yGm.ۼ6GQn{ï4T4Fa??Th)*&AV |E2DzCc}$.qdt}'e}UiB5Fu% >YL_Hj' YTʔ!jŮӳC%dIҒ3j␹$%f 8O ӦނA{]pָ |hg*7 k%s&~!/=k[{xTI8[ԻZ]2T͑:'qV  h;i)~& zp(P!sMsK}CM,Xn;n!dh$MθHrdT RPOtm5Dq&Ui.aC㰷>-v{G,"Asͨ,5ae"a֌$P"|8.dGGO$ & D1>{*A{L{G RF ;;H,i*:- k P=ro U٧vѽMcgP/ =t^-VJN=ڬNݮF1(YxL%$N,=ð'ngY-z)Kz fo C+ʥ<@O hƪ+T,MQevQN ׄI|ExCH:+ủm8eF'$w䚇AVѢ|Z(X9fqf"hlV]o67BejTJ\\:NYe:T/ȫ谼F.e[uuj #RWx D qAIͩRXz^@ϼT!<[q{Ucqs<8N|\dX~_ES'Uq,JqǩJNx^‹ }-;"fJQ;A6(L^䄶4VRZIKXD*,n־kN\+9[;eTox)<5lՂ$]-pX;sD}ZnMS !\I`f\I#9?;mӸOEjv/J>GpNEtyO0: sb$R E>p&"$&> =!Ŧʋ>~`fBs|h.)0-=D3K,STXI"'{%3U71HJ]TtY?spJKN#duG#y:giG.q2J&ZR{w]Y.DakOY!Nw!>ԛ!+PqOL7$yVTY,n3 ):}aq0m`pI.n!t̉mS2Şma֍1-mv[tcYr=+2-Y?aE:}>aeY:B.Lلl7n{d#]h yS5Yrq!}v)B1HЋIrqHl{hǣg0Win$'TWBx10G&=aETٖOɉ{~p s r&|@c~0~TvFPZo/mW u!ҫ''IRrqT 3.?dǣz8sX4昒}=jVD8Z ̲7ɘSg$DD_CfWuFO+!>r/ ӰK6= Jl|CJ vN/&=:ONovz tjjro]ߒˋNen8+6_Z-T 6BۍV"2o~!-ԥ4 %7~T~\)]m#Ϻ;mR_ǵ\ZD։Ш3s&Ïe~u.];$Ne*/TKp韠MU͏܈`w,'AZflԣ.5ĸ߉tt^QyOE?cζwpliډ`]"p䑥q  ޥT TS[@:+"m<ϖnKDhq.Δ1!iLqxbr|vYVt2sHWO },xN[\xRt!ZHEɑ:dH3K[wJt}DN 3 Wizp/^md&DnTt!pR' oȁ}}0TڷQo5IYiGc2>NSjSaٝd?+tʏ`œ`!P]nuBs3;ܟk:UG۰`˩6 16:J v̺WmX\fe:vv˲BuBe`@ܺ]/;! }BrC]Dp]F. 9]Dr.j9.ZE .vQAjE뭸F/Kre|66NDoT}G;NύpK:qk/mKCcFeLjcDنoOs+^"/X\tau=fܳR4z#d E{rot,oo vtaUh]m6_Ac3m,6NjcF\}`lwC; ou(>N eˊoz/+eſlYmiɐrUHx=t)k ru 뀙B辎OhANSed4ޟ%?KxVwv:|W陸twz?O'߫N:v ޻~]s_K/~}fg~}Ncݵ1nZwR_JءƂvZC;rY?+XzWA!-z]ԍȝl.vؕHl}+rkN˩3ߪIJ)ҝ/ 4IAx*Y<<fX)18I2pSG?aOAx,1!6>`Z#pS{aZh |*}s߻gYZ{w|BjplܭRt*LOƏzTGj+W/BgD@KrHzӽKY\-+r ms?=($ٻ9Xf1'25 Tc&flɧ"@AaW|J>#2VbP fS{]rc6,X٬GuEܖưxxRHVUkW8wNMYus&NPA2 _?| &bcoRȎ =֖#rRjA4 eFǠn8XD՞=Nt |}br2mneqWpI<Pei%=nO$o㓓Fc@C8o?R{hE6c ڣI_@I8}:y:I.HIdJw-t i;epnqoDw{ie9π>QF>+ӓF(%l҄S|ʘS΋ TY^)>Ɩ13ɳa='#ˆ_a Nm;M%+\ 7R?ԃ˛צ3>m;"r3q3}skCDQrju1H@6{|EI_CN*@g[<NH2Z+_Ȝ1磢h6ngP˞z6ݹ4F󕸷atVX-{Iujh_jh.(G'9Pՠ2C5NHQɵCju3?v–x:9Z$Ycٛ8N$jdvEdRzo0Mm"4޽3/lmRҩkUJjQZ{Cp'.xCJ, '?Dʏ =*Ĺ+[˶K]Nq;_iq Eu>ffXKyjz":_Yzq@ '&K,(kzuNV\Ѯ:*M!qWT+H": + +(~+nYGkETv*5[D@z&qT .lRDrƌ| Nd3)bbHCWWnK{U{޹a_@ '2I eB)"_V&Ra4D {ԺGZmi wQEHpC.MJ NLF[rwN)r;_L.y8NrTn Iatm!<"A@mkއZfĖЕ9zo&Y0:O;A.RvöE/sqRtb$~}z(1a{:I1ÜnIѰTƒ17a$f5ɒFGmHDO\TkDwt%951y4,\I`Nlp[FIo+!~ުWrsl\ Ld&PzHIŬ<t|lX0jH0?JjoH;CHrl&~(Zy" s# ˺=<& uFtmAU; Q38}!8T/idgı"ՔG'Ʌ#:"oSg U } ܏7ss{+L~HWO8@xI5j Ԗާ w#@ Sk\6-oĶەr;=wѵJܩv7R9!M eJ"Z/5}mջѴ4~彅 |UTOMB,7=A\_Ov|8(Y|k7[<3ȹɆjfFF`Һ#/jJ5 Rbl{j#xaqV,TTI}S LBsn6Pm ACBk)~UɥiO *QySc wTV/*No/?H(n&a>WJp O.ȇs&8'Sחk3K, ϱd@N=S"B_:9?3\Zxzo̶ܧq—I-Cn̥3ױx,leĕ䟴bCT)0O߱xqJmcpL\O@f!!]mezA.n5̝DCxr?}F\(sxXmL?79LO dD#`ͩHj//*kVx,H/[)4O[dTiw Bi=`6:qAV54d_ hKF /erNЧ(WPBRs5DK&"TF Bhp&)oE;=5M$!d@GG+UUnT,JM:nD N{̒K[cp:$ojz{;x W*;7Q*5Q Gv}:/(:r> bpktx /*mQZv ?bթ>5ZQNqmHO^L}g 6m)5 R =uȓ os݅,v!̸+3h*܁@9U(q>.~"9??qcƂqU̴zթfvr:ZM\^FUXB{rOH7ֵj|N\w0YsPoᙑx[`}¢EAK 0ബ;^زm;60{:>a7,u >3%,YZFFB"Ԭ3WyȔS:ǩ㬷R >FJӫ80_odd]2r X$nD?r@?i˷MmlwIwږX~b;kdrUN7tWa0.}: Av*rh#ygĽEOoQS&Hldgh@f/.Ea:ψpji2;2z^.VJ/=NIܵp$yt-ݻX XtNrʉk0۬KYS]ScF7ѼKUw髎QVDԁmC85)l+J- .S 9gRofDoL![eGE Aa6 .4n,]})nL_G W >Ņ,}oL_Iٙk3KYrtni583?gMXlӭ-Jʩ4J>J@̈́saZ~O g*C++Wv#t&K^QZ) 1Y Ze;4<6W" 8Tޓhi\-QT- Q*mUYmfMq|{Il#hc'iKL+yu1D"sZʷُN<$Q.t5"**9b.& \t Mav+kN3)\|T.&1VSieކA {q$}(X-X )v+L,lɲV4L^_~2ozU` PB5Ą^nbݢt9~q)0cBoyaD?sR a -cw/mIzOx"qg0]1(W3P\VcPI7=|+$k 1vG4Ryy8HaW\Ft @HBSFSi@PN(*i c6Yjw9>kP%p?c`rĂ`z\*͕Rɒfl^]Lcr?]˘Fq&CVz,CB _YXlKcfnM'h | ??,8D__+EBZvRp ޗQVi$3UHRuPQxHHptlx>l03 wdg58߼{5u~B2)tپR~FZ/(#?.v¤l~9&iޜЛ7]UCoN}XWEx:wLb 7@.n P]qB۵rgYp&xF_UVfM d yɊ.#Q49>KxڊckV}̖L^%"8wʭ-'x kVe\k!B1t ? +4QvnOJ+ TSn8,'0!@PPY{')v$rаNr5'@QAxkN:{4#i;VlL .Bl X(@m #ۉ%VԘ>E Gh[ Ӯ@5R஥"c KTFkw[@StcNfxc8`TQ3,!Ǭ8p@OIucrJjY6e,f!βh^#{c8cA;D.ח f+.2b b|ϷWOr R{Ht}: ]؛ն*ˀH@ R^vg[sJr;.Uqe2U,)\n?" C8,mMĤFš ҳ\]A)kW p1Q ${F,qAHRTZMЛ;rWޣmt> 6 LzZ"[DL$rI-9HD'&I{ zڽuxޣ[яG J[/f?>q2sɧWGmؒeeXtNNtጟ!fL:5U9%rd)K9r6CFd_ؚ@dpqkJ#2RIЅiOzdIL*B ;Pzfs9Dr,eA]*Tt\ M^ZT,ZᔙfdJ<徟˭cbAp1MnS|N0eAgXq$<ϳ?Lvrsl-鄋^`$yEs Lqa'孭J%Q ϟGF87 o C7쒅8=.㑹 nQC!m(/sS{o%m>-`,aV2ݻ9؆473LZw &X$2;)p8 {|?높_KPp͵ ZxK j]쵷M=׆3u@g8^W ا{cxvp\kG:cnoT_?6 \۶/7̱O6]4(4ͧzM*bw-vWc'29H't+h!v}9/ۣ&>L5mҋ9RBDWEoEWh7-^zl{vCKP pq_=a=dU٭;|\(C 6p<NhV+n$CxNJ܁r>a8ѫ:Z\(+;U)9؆&Hsyܥ9I۹)4qHظ$׸ XvNezď8ml5K44Zf"қoeRIXJܵם;35sa%AsVS xiƼgkmnQWL`Ɖ im3R3IG(爀gURTGYZw6NjN},WAW*𯌦ZhѩBUo+N1CJA엛Y5]D`">4[,^PIo:_ɶ[VRI՚{_a3j?si+H- X} j?Hޢ̧<ةA% Bǂ4+? .#:.jɐx tq qkU@`2j;=aPVi|=m/N1_yt\t)2O!m.X>ǽBΝ;?V̿4vq F/^p 8}{Zqb;ljz3/n0v.=?&#HIa.?–Abt"xaK FP\@rQRG$  $R.x41DGz ӘFD1NT/D #;fGA9xy-̲ИeI)h=ά o Gȴi|ЧǏ=䯩潩yojޛ潩۟khgnjCRuKg ]ĮPcN]d7#b{rQ3YEg) E0 %p+6H0uMaI|I@< Җ̑w9 ? ы3qe oM%)殆It8QK\^Q\j9MZjsMتK5"^~p6 <|kji΄ZGm_G]5>m짺gg֚Z#9-cF6]oQ*4Ƀ%7":ЧVIZ7!K4S@򷑱>h'vޅr9k>Zu4Cl.D RM.do\Z^m5 d4msjiĊdǻIo?h@ bP k@406扭V~C<8P'qtWZ;@PHI *;[O~ >9;A[6NAy_V4t8dY&\ ʒ{F>rII^'I/jr lו@!j!- faƲQZ mMkdv$51o_Αm:+'${0ʣ7a2ALj- Qz6^. >ڨy}5JǷC&j7]|s:O6+yދ0z.Țˮ׸hCdQ_t#[KHEoLʲ:E,,#mymWQ I2墛7cޏ7ozuڸO*4r5~`%4~&o`s&N-idPӶO_E3 C^Ҏ2M|x"A}fj?Bxr' ;X݀\;}Q,ٶͽw@`D<2]I8$ʂO¼ %9SÄ!5j;+Nl6ɧh#*Q֤g>q0]kQkOd: k0z Lao>1L#3Omh4lg6\q3o #<-7 _#<fg?L0[ܥ6JΜmF,ͨ KxMvE~ANb3(a9w$lxܽ4i&6?ve"~l~HP0z]=N<,  | +Vx7ΐ>?`;u-zZt;tRʨxBt{vBq)$K_m$lˁG^ɚFB`?uy&| X*쮡J;y.RZAz㧈3G/)׻ k^"^8%D(֝SGGT&~J qAx2f ]S7=ʦ c}"I,*_ %IU)$7jUc҆Cgﮟ8ѫFd{wVaOQyWcMCJ2.jZwl72J3_Ϡʹ͌q|Ix~ik{"D^SL3Aɨq°1,D,{vٙ}SE-%t5ԨG2ӫ_-Ɓt"")w~0ݳd2KYy޴K6VaQQ!X5f`povh`3noR3 xm1ݸ ,Jl{ƝJ5wP^]/55nܝK Usj2'ϾKQYKK/ؐm'GYzyL"WcF(b?ac`T6enn0#8 v#͘( K=;:=EfQ2>&hu?|V/!m 0SN-Z7@ v#m@ MF%Ae2 1}kQe󦻝`r78$'؈Y Hy^X&3l4 ŪwEwWK]F{WD+mżO .em qMOIrRqOg*)t\]}t,S[)-u_f +7 "~(VךhR+!3[FKupۉ4'9߷8F>3d3iƹN*&rVC?brX$&zb_1hxEc]ivSg+9=&TqJ BU.#rtZ*264mu>ʲӌy&3?!sWg͈-ïki-T"40/ROj3]@v:9T=K# u## ra3!tז"@7/CYU*U$K \U<&-1 jPTxO>lz8__ 46$!;p$@]e=j" G:}#KM Ő_;IΡJpDu<{|\+#/ *<qGygG~.m&aM=q{Dӯ0cQXZ̝@2?"[ip ㉣8T$,X$egq<~9`$>iـW pIߒZQIT K=p\{Q0CL/vX_逾?G^=|vq7y,@V`6&"t¿n,ɧ%a.9CMh}\AWRhyT@ K+{[Z,` $r a!3ڨ9!*j'68)Ubfy|- Qatcd|1Gd_ҁKu4˶W,0{/81Gj/S{p[jTӖΙN5튵i*AG9gb6.$jӟN/|y;&vB]^EWƊ0x>YhNx#GRZ!a+Z<SV^i<Y_c^IoR/vV`lQI4LN&;n(NFOk a%3ZogWLBpHu:8L ϓ)hT0^9Ox'@2>iC$@z9PXD<ddIAsZk0xv'3k*A~bȆۮD.tzL"T N{G$>)zpomGL8 EɕUlg'(2IծjO\ƲXF[lu}Y#mTke/~P Ph`젮X?]]tPrĒA/t^i8kXѾ{S u{M+J1[2ÖbUϗ?yS]D[I5+l8ia _o/Ꞁ l)ͬQj9֌K^~,s^1&KTXl;1l M1ȰZԂ\}opk#T̝7d[]䦓۫BENO0viqV_Z_C5yR>Yh #MOuyd'Ќ'Ώ;+l,'|eq- 1>K='GvcŚAl9SC(;C㰘L hߐe?_=&Ccoh;i cm SB>$׌#Hkw. ytژ Dq# QnF2g`cள4N2Xt0>U !>rR-F덒JtM]}i*ܚvdy4s Pc:QU U×`,8h$ks)Mپ//)`jifz0b!V[tĜMI<%mz©4vJ}qJ"LiXJ1hkE|-Pl*z5#l)t[5MK&+d5/ȹXu[1x)XM>hT[Mի`i{?LV9h60 }-_"l_8c&.{2#.ʅ:"o:era#~R;.:.oSP<=֥tm\sd}X[T.:rio>ӓ }zvF%LZﭫUフ%k|BKkiBKD9:#EA$ΉOijMݔbC'4-١9:NLJNTr{'>^ӂ1 C { X#h?bo4neV{Ke3  /DfA<3LIӧe>]st]8 w 97QMx9;*}*A 䲠DžYZN%#UYZ@:s=V0{1E4!~ 7>ΥOs ~ֻ'GԔC& i))ҙy0||" 3pܸ%-=9,Gb9_/6pH",lP.JM۝x7ЕDҟ8E D!,Y>>9ϗw1ӗ:`-ߧd2!.ݩw1o.O- `Y+ϴx-XxW Pz 8F 03P9“؛h,$6ꥦ3 u<ᴱFH\eQjyE5$;nwsM^km JO8Pzq!{+<|FocKoݭрfnRAzaqv1`P_!mF1CVA$(ݿ NCv k9|c,APr5GsoL~NlAcTOɎuROAY܅'82LuMgּ# 4;.V ꉍ5w9Y֠:@w$`1 i Mj@pȲ(%%#N]P-u'jtos`L4Z4pE]<q02 CnEmDNtrLFvH( tݏV{W }XLo`.Rk +XU/wzc͑d7RX~Lgsm#32V/DŽC'`[rTAIUl:?A(aBg(i@gq*HzYZw.9G> XQWq>v?3Iɸˈ$1 fwuNQpM7J+hZGnp$ݠ.exӧ|i;]rm'ͳaUIKzւW$%c$`(tZB$~(BG0 A4Ձ!AarҞ1o3:a٥RGƺ3eם-Ti94[8b;2v_1fa&3Q OǛ?I2_hR1n6HI@H}uCm 'bPRIqoH\#aJ62,q,k461sҹ!"H$TgP˚bq@ jr3s67֬~[KAmny6`@Ăo|a$@nq/ח |!ۢص8t!vbTFiq ŧəJSq6Hz'ϧ)9w0ڮ͜>=lP6N;9D+`:S8P9я!g'ext4Qi^Y3-7r\xmpHPf004щ%lCK&\Rs,Ul\p8!qu> uBB{N)F0^n9">>GA% Apf K\[y0z}J+RaZa⪝Yڣv tS5]0g>jH- G8c|MlidN?GwQ-xJ N>l.`8BO d$;HB ( έ [i~(#(:LB1xY;lRW؎vB񴺩ca=ۑ HTOތk1֡bI،p yPLM"85|?|`E'"Vvgb,,Pty>"B`GÙ[`DΜqwleYayV.wۍʲhw.rT|ȗa{/ts cyF݀iBE>CӤ./eE7$<(rNiUdJ>ϛ!NJ޼;iuwNuNO e!\Sޗͷ2XO%+\rp."~>B_oZH'm+.;X?S?(7 5G$j"}f脝ْ K/T]?UϦy;${R?2 (!eEWJNqZ_O[n]⏜7paIb\ަj<7iޫ4A*Lv%m@TC%F]49 vx',=7k&q;ΔCJFR6Kcq^Xt)lf,x~G%'ĭyZҎu#jsT)[hQ8[3.:[.Ӆɫrg%6A_tumIF{ qAP/B-M_hCXnXE\cVK ;Jvbf Sop%hEZw@kW@%6-=WVmTJكBݏafxH\0F 7ȆSw4{A_"< =_CX_܃;$RE]R&',i8 OwʲUƄ耘g7ư7@Ӊ]GS̐x\d6w 0V- FD !g݇a}:h渡yDrVf#>sss4UdzVA^se|ȯVv6WKs.A`㲄M$0Y5%۷ +]hR%v*RDcOp2R—5QLD9jf#=4 3جf=6ˇje abͳWLm|"- KXXlS:zvA!t2N]̩ا("U`S>,.Wj7:XP]U4U=NU|لwC:FۜypX~Ź=!(ھ 9i谲!5hHANgxR0RP}jRqz-JPn5sǓ!(g`;78B&h =Lb?}LO?5m5r8ὂ?!(q/Sz o TWhҭ#+\GS`n0ԍz Ps?=:kqDB!bxZ*&\υk\량jm)R\W\=ہ/Sز#$abmVJ:R k^8Xxڬ{٣+9 VI';OF3a`t]wfaց[TgK +V̎\`>\EElSĦZm"p 0)Ox:/J,8%؄\K zqP4 Vk`ְw;Ro 5ީ7.ֺCۖ6ph\F}։ܿw~ T`2a)Cw˸jNL0.prNw>!tI<^Ti Y, ; biȩ5JeسYkAPimY<,}犥Mx@iXv$Kl 7dpz%rRPc ~v@1J}/`cZ4Vzw0d$]>Lܟ'W\ql0V0aL ~iOݡL,Z<4[]2W5WN>Ž?( zw@eET Vr58:j_7 NnKw(k%N$#Vmt r]X@;h,P4B KEwp#GK|s9՗PN#6~ݑ%fmt[3Eܧ#7#3/Z0߀a12dŽ#`F 탽hNa7yZ2c@>MKKn4Asư,q*dW 3Hƌ<'pzPSIbl$*pqO=vLcVrjɬ<(qyӈEąp&gYͱ."ܖBI-W\RE?-aSD b?ʎ9vnŃ KIA8fے"W-"L 㠶$Y>ЉNN\j4eI ŎTA"4$D^Ir].SIY2tNeюeWdX%NFĜ^? z'fv~1Cdg1L>k65G OUXcKWsKٙkgSRsK+BPDޓZp!p>3wED @ a#o'H jt zA[I{c3\}WfPY\^ˮ`A9R#HwD{ H1GbTxejF(o*ZE il]o>.k I & K(煮]f* d]!IGp x Ah/G€SԻRO ywp:],"f{kPۑR"BcȎ+frYR.4IX^v}_,!^q 59r+5)8OetvKj[S9I9.u;X2ꂙi 8 MT.B6`#l(@1X[wj 37r~]M0EMd}gP.`] ٭lNDwP\jF*CU i)&8L=X4n 6M3sJ3 NR":| #sJV$DPUzUJ|q~8}@&qȫϣa1 ۭHsqKBglcO8(e4e0vۦqlc2=BG£ܨd7YDt I^p*Zp-U޾[jH +ƻmA`k;QB`Zl _E?IXDb: ƿM?vStKsCtvU}z5P7fkp50רC3޲;|7. #@^/<+< էFrrq%e4D9J8D82S.yB+;^N]kSQ|( k2g,!?sLѠC>EВ,D-*DԌGXi;Pwh`Ko~Jvp"x'EkC9E*w0}U_EZ/^W, Tiv03;R.C/5qq-ZPص_8Qr)!|qR\'u6hYXlKOGA=v)+ʾC{hj9`.rʖaBޤQ1ުbò& I /MxixgA:ܯ0q.Td5Gc'kz'}ҏG%3*1q5֠4NSU4zs=dGaGEwnWjAW<ǓqՈWZfHFsH1VzT2 3ٌ-D \iMpX̱ 9HjEN7a iL",uDb?)y‰<\mU[ Z7=ȭ|٫ ;MrGWu[[PQ?sR?E/?Ұܿܿ%Ğ-asOJ{)C b5cd%Le9/P `U!_ Z 3*# p bZ r>Ap& A7p_0|C R4aiHpCbxPt2Ԍ皅XsoVVbŖkV[J:1c ,pz>a` NTJbjg4Dj ZLXEcuHz_* yPQXDw8}H\oyE)uTV,I=]m+2:o# **)J RErrإ)G Bp+XxN g8/UVcL ء@%`s.PHcfæ/9b0l"%xN3T^Šȁy9SY.ӑQE/|-īq4dOP- 8Gpli=-^ wGy#ꀣHg*l }٧0ҩ< Z6Ef5y1B9K8d+N0Q9RpGcҗ \' F=8HE SmaDʇ8pn_NNYلW !1\Mşk1'J%OV̎K C:xBJak1:!4ذXʋюdFĵI.n,[x"q6e&ucmK}w}Zx< Ͽ,<+<=caC!Vne0Wj {NkvcWn']/l -Y6'#4)00M2D?E;ȥkB5vVm +W oYVs$dɷ$J, mU0`VU/d.{bl$%X P2,KwzqL$Β,^ZV)5;mt 8 FQ&@R#tW$ο/^/\"|_xIbIDyè?&Ag@%w54wy"'J6ا+̟*VG j'>Xix~bSj/MI~"j;׬zf. Ԑ=ݚhR`瓦Rw-thql`er8κe"}ri?rIʱ :,BV}dtve\MI L(PGA t< !a? c9XJM'VSA4bR%".:Z4 XJ%:1`pB{gjw˽CU{U{ZbOKG/?/P X*9&5!0WL]'mc\PtVVJU^Tka5s{cλٓ۱KX́*4'YmќW^@:!6E#kٙ'eV(h^=#}oݛ~=#}OKi=-qG;.hERHUleɩhQ\gu#?P.HT'DtBUtX|^Q}<.r/ˑ]#+:9C_VO{GWv%v6^SsY2\.^Y{SZ]٬e,&h+GT(:BT 5߈6\ PwqOuL<8Sʔe[`DsOIb##}_Zs#W!x8HmjRV1Y4C$L&i<}\^U8 9rD_mxgj6䙍ۘJ x$J{EIIztP|ş3ΏQ}UN1Nd'"UxIIsٕ|̕RCJWpsdc>Qg{٣+9.d2ΒˀfA&oOXB'W%V2ֈ#]2a!DL^ɃII ל줗seIcW+)~IJYBSSgkKB*v{? .x@oQLiRVjWWWoq'6^g_RrX!wAtmU.Ȩ%ڥ;1#Üuߕ^q}7gZla- }xgQyN;i^Y'`&9Whl쳛]LAi]fz!7#O Zi>dՙ.԰<*K!O=Ju]u5GY|<̀e>:ZBeP键1tBH =k A #?M%bg5AE3-D:nX'V3iߺj˅jtj@|]I A4WO\E]Z-\w,o ϝR[U"MAu];rQm'21\VLZN(I Ei=-%(?l$ůޘ^fo,̥|p$P٦i`uЁ*.[=7ST{3՞=%Ğسgw͞eݜv,Ā5e|2ثiB*jUPy;x4[ dt b2E\Wq97&Ӝ[Z!߮3y R0Kzt Ni.b|;0nP1Z K竔sw"FgFi;.B0 _(<% _%<5 _'74tbӶ3ADH$YyI"6s CHrs*`-C3h! U% 7K0MH!&u(a.,jnHV{^X8Sx_&kjOLkD>,f`6uJ)0-̊8Ys/bۨxjeW۹w{Ny HSD)U%Nz#Hg+#eRUF 'Z<#Ev@=\{M~nr=|W A] Rx+}[G꫰5WZCmtSp|T.W LXWh#G{ )V ^ʂ<Ǒ *Jm2}#@sVy, e{6Jh  B;h2@swޛ[4h 'jQ) Fwivpp.dZos:2[Rz8jFHuTHuwA@0 > _bvt(N\76x̙.ka7+q",~CfXb U݋cl0g|!r+W /ʭt,^K1ڊd~S=F4.uh]&N1DX ,15?(2Z3CxrtA.T KL+u`X+eK3N8$3:骢dHJ}kSE.1S>z}ߥx?kȉ_ZjKgߤO*r`FHOr`[H<}#RVޥfhCbouSO\e]Jq FNz\S GɃ o^ SbP`ddI Y6fkFhb̺W 2K HH\oWWK[#E&2<"ՕWG 0ܫ%\W PF f\'\;!x9673c*dX'P;2M݌G5?QS:jt$*tIi|'!9,^:D, St?Ao'b1!󞮵O&Mmď$90̑߳F=YkOt靐{g'hXf+ ,+9/߰:k`'t FQɟ:./db;f]+v;/€&byA1.5(Љȑ}+8pоGw0xgw{;΃'|#Gc>p豃ı?|p߁ҭ+8a(67 `I%L \i,΢)ŶѧQ;թ.RoyΩg*ېXy,`0w!_'v V%TŽ2k,ҽy˃&a 6 E u`gT8]ˣ[m8l짯W5 ,;Ƒ7f\<됸╲I6Cwfԛ$H Jn@!B]U&Ά4p{Sik.󗏧V_/Soe FMLE/>~G#D&(&_Tޑ%cĎtg}`Qn)R!0txj9$|Lf3'􁚞>g Uwʑ(xqpo<'߱]ȹit Yf\żx>3ZX*ZSL&SkWbT+Yl&LRrYݘ1&GNb>PD;Hڔ(IC,Us{.S,a_f#\S #dty*ܳΚ4~"_*^t%6P+358 >M*/UHj}*B%#%h/l( 1YhD|o%XpO. JIT7\+26$prXJ8(&,O4j֦v褜)1$D֐1f 5 Khp1`BæʕEFi+C+ε xcd )aOxo 0viJn)]>>A{Sf_ZݱCF'ԱR,N h]E;yR:yuI$Jwa7MN̔: bqУ"X} ,4YpuʲJlu<ſ"2' K^0 [oTUqݪ7S\%ͬEϲ(-;`$s9 uM a|ʵi29 .?ZuI:ԒE)‚gSקq=m|4yv|% oA)4ZPib֔iD:DkP[Yue+2o/I汈9mo-#R{z2gA 7-ع |98,~ 8F'p'XɚsEvuyYE~rA Z1\}h6쀕Lh J耍]bpg-J{?&"HkIܹs8,&!Ж!`}hexa#^i4+ܴye˽_o`Twݮ<<{]G?@-g~-q;@xlx.q #D"vQG|Bz2)_;gu1z;7"[,,1B[+yX)eVY3Wϗ m n&d2e#d` pfīۜMEU; }C#q1]f@0}*/ڜУUCvۉB T#~Ǵmζȯ1af1g4 ; ;)9(@\ LG}rTxi}"o^t%Dwrl< ?{ OaBQ4#%nKksH#!4X-bDM`:U_霔qF1S;^ ;f[{Gw)$k۝^۝r#Lm'\<C֮R͐ɏE?&[y5y\=raɭg_t5 [֕CE3&&eDX%-VێKޱ~.m=yHϨ\h&|}%mm'U^qv|Ħ8׃2484Ljh=SeZ^u3F ůp =Bߌ~ytf:𴏜e<6} LT<'X#?}R7wƺMF@J[R8dWuAf[U(ZPMHPIīF{X_;'H Rexg}ȧM/nK!c~y]Osc|p6W?3;t"it:bh}C [h!Q#fbEvHAV0z PfzYPѕpBZnxvh`sGByƳJL=rN^.O7rKJ$][?+;J˓wTުU*@H őNeW&1:1"S#\tr\£J͉riyh̓v>EЯd *'MX?α:R'Wo+ۆ7~{cϞ*?"LJ' .|k]Z'\–IBvP54Am& 8y/[l ?s==vc{@ꦨݤ)f&U]C Lm'“fH4Ĵm͙afĢ5[4a9y7g 4  a/T/趄fG0V&1&_!,ksSʋ^Rsc]_x* /4]BhJFljH1_,P]x п0 oT?3Np띩}L]y*lV2?U!7Ʉg4KljtuZv,v6⦵$gN2w?!HfOnsһ_PVZH:yRo^ETE8+H~W4{In*oS+f*Is@w/23gZzGf?T,/)WMƄtedl͟;a{-t,4\8kճV,؇k7)  $]5gӏLFo]߃ #ueWr&0Y 7V\ѼAEV>@N%$ ;\ QDa s CzmAN!l!VTLHp$>Vo!zЙVnOUd)mуu;bf}A"dCy╎^8X7#`x厂+BQ؈%|H6}^2 >#S_-lGmE>ZxlWk-e3Z k'wG{5R& ܕm͓w;]QN;K|.Xp}p{f~wtg$>yg;cO{ؓwŞ 'wU;$ ̟<%zbLNG[( OeO-4nXH4*zxV)(k_dOdar AGH8>FP&HLy4LO#k@SG\9m~BV4v&ەMn7nvan7ݮnvf`n]Ie'ZL~ s"`&nf|[ ୣ:# YǴ|L}B7fMৃ :Ra|T* ʇL pE3EEL (JϞ`O@KЙ\mqHG蝬~L/:\-6T?-)j:q#33 wU$isw?i ҟs&0?:d6?1Hx'd 3J#*i|C!4 pXA,pH|A2@^i &$hND1jkkV)Ǩ,vףo[sB93s=a% Z:/YV:C O͐gf#֣+|/ ׿A_ L8[ L-R%̗VE2@&Ұ?7PFέ~iH8%ЖȄE 3M0&QL1/_BUBsE,q(ʜTl.初!% mAYJw}97uO&cWt%;RQ^.-n(zgݞϨB T7[Z-~Ȁ˧%/Y6$oedryW~=3yT*b=2` w]qhoOfy>n5?T;J.S=je{t(*Z(w2;|G;vG;¡ >pā?p}96K׾#&c5{mȕ~<>;y #N5\r(Pbk"aJ1wmiwcLJvY@T%ˤ! g佋c:?.h2v)z^dc\ ܒ`He} GxY|*儼$yD_m뿛3d1b/%ܞc L&ZXǒ@k`/{A_YRo. Ĥحw[8-K͵_!\{CצH_E{:#[l4}b'XJ0tcp"v/DЬJY֥ Sm\ !i˹q-o%m̚f>hL^!s(eLSuS=_mE߬XP^~\Vᠨ<2ۭt ^ng⛏iyі{湋9C^C9Hx30ipOc B5 :#,fjn>Dɀ_:<$=&2,!7vDC@e@oLH|B" sԨDEeTCfLhȷLŦ{%z!LCBҵ"rmfr\Hyw㠽wݙ_3FRckr]|rNK'.*YWrבn? Lu=Q, S ,ON9q\%eA)T^ʅzh V4CoT9]OV\cLlkHi f-lbxMr)a1f"{/f0&~xR&sy9M(~i~kLR6VPq)w:Z'MXkIi{!RbaaUr\el[*XakYro7w A7_F~paD2Q:vvf|tV"[Ӏ(ٔIgztZ9`Y)A΍ q 7(ϫEܯ9B yM:ڜ@ bs9"=D<$! 7?Rz54DhGCԭyIoZzs#:.a.7\0ؤ߹J4wX ws4J͙A9c+^a)WC# S֙3e] ЫŗܛFI9_`)b|[sb#BS&Nḥb  ll]9KN;n."i q( vpKS=IkKA1wIsqT<6{shՆU`]aբxAQJI UF-ǩBKPױпVg߰aQ?Lb{ZS Zj7ʊiX"OurJx=|~"{'۷OU)yy`WMsy`Z8rȉ=;H+6dn…cpNKM;4%l7}/_#kf]h>|a6/#_v/coWo"-csp 4FzG˷l^c/:h ZCj_1L ejWT'W>ptȪ~5)M7cn$*CKZG5-/'QUۆeq>}spҁRoli?U-69Y$Ktxm:B&cwM:.a4zm/Z<+n1Rv߳ܘg'I5NQykV@fG6;'E q=[rrs.nb_VTV(:̺!ܧpk֫s&r-Riӣ0br"V]=Ruw7ʇrEsۘ?{ilV΂2$NysnUJG3 ^ ڸb }dC 2cηM{+.WߔݷKR.o6Urix'}N)X7&#Ou4NOnTZ&\q +C@N2E=3* M,O\DofӊCS' fTdRl26K"|w5*Anv*;u`2:^,ڻ}jeX= I9v{o*\=J@>ݚ]B7d~͓7utD!0(ju+8vMF` D_b5Xo%z7z#^rXiNL"gނQ­p*늙/R+#,k7T}h)bldtrDN-SNt6Vh-&n# 8U& @Ft{6I:&ƱD SMw*1mJY=ñ @T=( *O 26rqh8FYMx 2MWŨ<#ܒְC]. K >H<ʜᵂF"o'̅V*cOEvoXVIݩ^xvBȿLIi}ؼpmaԛ3E_"`þ7g%[A|;RT~D*ʿ--RaT>*߱!;>$#zl\͒GjuR=(9j#&&tyפToypM'W(drDPh~B{h_%P+Eo 2{m*b{<6w R,9{IΩWƜz˄.0+wSfrf!m|%W.i<]IHz1H]&or \ggٻlVqbxAԱ1ʆ9pt,󪔪l_њ\A歖]%6`sj ߖ\V.Mj'UCCAɖ{/Js_HtOv6\\kHSe..TezBY^ɐ^/1/_dBc5-WGK<,N47g3˴Nܖ8x\9b(0O OIiD=SNA S@/ePȎlt,2Xrˍ\ ٹslD0Wz2$M k-?RKoŽH7&wVAfzpy)my}V5tucINɞ wgLCw/̣ Ħ!d[7A%c ]0,nBoaZ2L{^!6q娅7OsG22̠s_1N8i<&;A xkW,+U%@z" vѐ|2N% ټL1GV,]hvX?YפU\2:,e%j4%pr׎;O$4W o [Ӈw$r44;HӶ;5  J :,tyZsق)IͱrhU&Ϙ.2p qF0@K-X'H XC0!E⸕[HF6a^aYI@(GPmAB<1\ 0:$y/4jDخXlB`t,]=/_qܚKkk%0J}V6 "Ί`a,b9zJܺnЭyduUky9hԀԻG~[Pm忛*֖A|,t1MUC:Mm]?/6*"_>DLXjZ]WMIf*3ͧ3̲B5?jQYeM˰In)Ϟ6q`n{Kgm})ՅH7IKyJli9B`^1ǻ 1ƽh 8zmǶhoh$4 J!A5'!aL#?wJXf^`d0ݰ8YmEdآT%`xЖ"͙r}-'¾]rԪ$]Kv\%* Nj(ʺ)/ƴb4?tイÊ0K8urԸ4rzOo:~R =Gڼ%y$X':JӘC{ Jq۫)Ry ʄ9qfcsHNDY20clQ6b 9ۓ<#z0ߏxU]]_]B;Ե.?dc1$#k(,i(+0WUKu%t´ni*_E174l.lAb4AeRUjU`BIBaTKՅpVi 6ܙ\zu*kLt/ΆY;lxJ89ļ6dA6jg 2fb 䉽xTKG@^2F" wL& eT\S ^:8/mٔi-YEkgC*Â=>/,,+<+*(⽜<o3+GdNYRx}bOf iHTRYv ߗʿE*i_ʿ'#TRK?+TR/H?cӝ*:%=BcD P+~lCq*ɐ/'vusw^>іǑ5‹Pɰ6|󌟴ౘռ9Q->C/$7̉k=m;[9L@t2á<!ӬRm~EƼr Y&ٗBWfdWjpP 庌 5>96AOe2[%W*4FdNl0m4ͽ-DHZ62RcRu6y@mO;fyGMe\VVKj7ޛ)ٝcC9_T]ŏ\ZDrdqټ:G;2=ٷ*1. n c}]RTb@:+SU~,ˏ{l:_4V mlx*Iɖjk|,Uwj[=i)Fn'`IS1\k|DC=55{%ϖrYKc_ >\lK+W ƲҴ憎2fHTk'&&1kq_fױ_l&ֱa/69&Qd^$\Z])ؔ,'!CSY Eqkȅ"ķ\\KDP}+ >r8 B/ttբKr3Wݖ+-|nQ5~1]r)\T(zYJ,esa{y+#. c,}gf\޻9KZS;꛶Sd x>@tpB;tb8 Š^z00YuK{ʌ'juGwW 덹S/k ^_hl|?Ax=d_%ZHpc9|Ő?#''k.$ \sבL</,TYV`WN3]/m5SzfrVEl3e3E-G}-f~vfjy]T嘜iQ 7.niN'@-9 B3e4Oїm%k33N6K̵ S'Rҫ.Ń)-VMv t5ӨV$ǘQNBWAKSkGGwugVΫtc^쬒3TD}UKSP%f"wb@YcZ v1=ʀ76 5N֊D`TS8Q(QhfΚXB3)zf u-n$]3]*Iv;kfxf 7e,⃅kuuYV|0^!]$'NP?։:O$9ZO9eZJ)t6 Rc*δbaPj2Lu ^608-g~dguxt:n dR[T=!Ժ3Wx,YYj鰕27t$0oX>IIٝ9Z^ Kx:G[: fs3r>< }u^2ajGSM JuQ7Iw&hLR90Z|-a[b;֌6za=ѳyuHɧT|4~˞^>j7gzg2ϩSzԽM<)B {zI$$>9Nnjl%u{zzP_usV鞬,$d6-p া*X7yܒZ+Tzѣ?db C#0}Ͱym'1k9ƹʟo}:̟G8goܺ+*nTE DVŸ?916sRUx ;=Lh3ڏ[ЉCSJNl0r_n<]?ee[-[=WK=%u%%20y?SӦ %{I5#R0Nk[+-uѻf&,5r{'{8ل5N#Bd+AK* %hm|8IvJ]hma 5ĪV]U}`ahKlV@`۔5PW8g=p!-aq˃MSd@Yk݃t #6L/=.V4 C݂+v]KbsNVD;IKnjnw=ptgs1/9ʵ],=;! 4}ۑw8'8j9Lv磩TLvAe :hj -ijWoA+M5Rȿ7Q P #sc?"˖ݐ5# AƪCdvz" fqPӘ9ZxlVwpicqG_}Ak'Ӻ7 5W]r ~〴,<#KiTua.`M^A 8`s~KW%蕈J+;B ҋ&E Vs J'<\zs{$ӾB.vd kB49IJ5 =ЀWelţpŎ|8<$ul7;P TMm R@^م o !O+ Υ4ސNN2ً6Ɨ_VjB{8z. ?O4;!/$gػkԌM9]LjNa25nBYURM*@p>& 8&+dISsgsgs}?)ܧs}?%ܗs_=Y7sϝ]Ͻ{?;s?_w}E(G?_Os_/W_z>A/=i3Kg>>~?5?i?MOӿ?ISӧggO?1'ӟO?igӟO?y_O?e7O?~?}?}? о~?-O?=?O?#?O?3ӿO? @?>3|?Og>w33/ggg~Og?/g~?U3~?u7gg}?ٗ~??B+??3?+,3g>s{?97/_Ͽ?-?=??#??3?+ /߿ /|ؿ)3>_O>_>_/_/|ſU3/|Ϳu7 _xο‹ /|ۿw /|߿ ?/ؿO ?/ܿ / /} _>a'_x _> O/| _>//' ?_og>g/O??? 43?}?iiYsy_%oF??O?sk@:sgK/g~?5 |Y0Ca^}?)iYG~77s?S?~?9O~S?]٧gOϞ=?)Y`s}?q's}?sxsϝ}???SeLdMJ6)٤dM+I6MMeW (%RJ (%dMJ6)٤dM'L [ʉe:Z_Z;P+slQ\.y~rc.9b4C`1%:9icTLJ0sKێ(ǵWo x6) nVjR Z(@J6)٤dMJ6)d͌_SМېn^<|@Fb~E͹^V>ZNbirҟA%bcpH4A( BiJP֭MJ6)٤dMJ6-:o6n/+o^4,N|x;#'S,nm/bbbRc1C{b{ wuǞzT(yKA mMn ~EzG :o=ᚸgc7> wbۭgg˫Uw]1eH*aJX+a I%lRI&%lZ!9|KkHQJX+aʐTI&%lRIɦ0$'VjROPk^Z f9ѹѾDd mT&Rڠ6(AJ6)٤dMJ6)4vmb?wNo իw_|v^O4qoyU|iuT{' e(-CiJPMJ6)٤dMJ6>eC ٰ}0㩙Jci[nF7VUrM#khM%9^-na(ckz˸ٸZ5fͮ)h۱:$G񿞈u;%r~N ^M7ϋV zPXN*ң(G)=JJ6)٤dMJ6)*w9o%BOfǃwbVa\8?5-ZIj@ۓruj7.nm\W]8-ji04utmxƬN @ߡTil9S=jF MM(iMC&22L{7JMmslP#yTzJa7R~?ܐZd a5y 9]R|GHe4i|\k)2N?gyrMOUk" k3&nQӰQۮN5tw)rbeD6-ZZ[(qso5] w0`)11ZsoY .L濷ue2t@s[;Tӽ9Qr5tJv :<9fgug2uCCw&B*!oPͰ4g7Ͼ9Yi&>:?Ymhʡ^2Aq }ڐkݵk~W:ѭDy_ٵ_/Y:XmS!fnk CȮwΐ Ԝ+Rw²=Fʲ,Vr/EL8NZi4i.@}t G6Z@ns7~}9l5܅O pwo;Jx#G.I<{;yO:| 9zƯ烏#<> 垛5զB]㗻E~ {v8͛\'f͌Es)8wjSeZi9To77`sgu-ԙ[<ٵ-;]ZT N2vCuwfx֦̎)|4P+H= @,-Vo-Z)ɦ$lJ)ɦ$lRI&%lRI-Y)PJ@)'%lRI&%l̒Uu#ש]VJ)ɦ$lJ)K&%lRI&%P8F<51UO;UXJI֜.&ercyVKpnܮTr[m%Vr[meS*٤dMJ6)٤dSϕaͰ7߳c`ײyef;d/iğJ)ğ2͔lRI&%lRiFx88 ÿ*dl'cd|/a,*!۶=cd\%{Ν:R!:[dW2P@% T2P(ApSoH'OM>φJ?+'蕫Ξ-*J +1İMdMJ6)٤dM*PJ@)PxRI&%lRIɦ=װߞvn'w[^6/o6@ݧ:ִKnh^hz55O.7ҏl~EN?n4 2M ?xjM\C[ v<2,uÀON?uoՠxcNx!hOx siXx9gSVeTWomxe;I?,R7zmM/›P; 7LĴ]hoښO V:e^ua*MA&ձs Oטg R%&):c'lKw'ta 6t+C£t3H &p C}ΐw( }z5ԑٷKpiPC@ لi Sp NP\x=M0̦8van ѡe(F{~8Dows @nu۸JMw\;Hi}V3M>3^w'kk85a`7 lq.fՃOxa.L ?=}aLFMq=zejr{|t^t}*Oۅ8Mf}A 4.̐&b6&KBȐ! eӮioL떻І/m:Nݚe;m ײ]V rc4藃@A&-ͥÀ-ᫍѻ -wS]m"t-UÇEZg@FS!/i^%Fצ ʰf- kݪ/ҥ]O HR``bJ 8`E|w1f^!_ bz=T73pUEY|O`fe99&~V|X%ǘ6Y栋d3L*Mm&fy x3 Lʚ5 54^M3; LgH[;656ltpEKn$q|oX)Ѵ>ʌ@coMxAk h=S=Cٞ`_>ʹc7+$mm 4۞%AA2eEJ((2x&~UoT\(0Aځ`CAlPT&y$4:A7:l:: ||ͬ=B3Pp"I_$jce|P$! .(k;:b l%>t 覣CM6K!F%7(G H`z @UEv@QpiZx6=PtCGٶ=#fTp[P%:X\L2D?~5h?ݠ·ՠ~;TdZ29~Ff ̾+$tc/\~5C/}B'~P*uP)m+UE2[0/ASvt4C7xCxS_"ZuPf =oH@Ўze~9'΁s u:\]s@ grC,0F)ޡ,]jRcDKԀ+4`UR{$ 7uF4=H]sҤbTiPcH4HIsU NNMvᣪ:~+ ?PrgϠq,%1^2U gw6jaP\~쪃А胠OT^`RG9~(7V2g[s L EjMwGEjj\@@ip7E Zb} sh:5P`KI6R+@߈9j59BgN322`D`DuDEDqڳ6ZF?=PFL>-Lu}Ƌ̏a{X.amu~f>vR_GD܎N;HVаXp0:y0aX6Oqvh,벥m a,F9M:/.c|Ner?0|4anD3'Ӡb xHA0Ad= Z.v!aFl~[tabE`OO+,05jR#Hч/Gsg̮!k:$KRQ= w(mɱ3Aۨm}ڊ&:/P FKpmoNx B1>dy $¾F9 ȠAWnBaNfj#naĶ#.ƭ0X8a6SmRjZVjZVU$MJ6)٤dMJ6;U)_SP*JBP( BT( RP*JBP( BT( RP*JB2Bȥ කQljMu6Φb@lRI&%lRaZ]h|aEXSv3盂qM<)үֆ$UB< ؉6]1mm0tJ|"]|ݜVZP yRB_ }%WB_ }e*٤dMJ6)٤dSA: {fi .c'L{Ɇ7*٨dJ6*٨d۔lRI&%lRBb{YtRhȳ6l/~ű׮J[-t~!dJV+YdʎTI&%lRIɦ^v$WZ(%R"J(%dMJ6)٤dMprutZ*\RJI+%RJI+eI)٤dMJ6)٤dZR"J(%R"JOJ6)٤dMJ6)4(aJRJI+%RJYRJ6)٤dMJ6)ےCT sNL6\UY/Uw$|zog9i6#BB~+߃joMK1jXxZhT]j?kaJ%P^z%ꕨW^J6)٤dMJ6)٤!R"J(%R擒MJ6)٤dMJ6-cbC*%RJ*eF)٤dMJ6)٤dZR"J(%R"JOJ6)٤dMJ6)4U(C*%RJ*eF)٤dMJ6)٤dRSr0)$xtYBēcl ;M2t:K1hM6daZ u+Ծxk4 I(MBiJPVMJ6)٤dMJ6rX[fo g5j>{qks 0͵ o˲ W˹0BOV%[lUUV%[ݧdMJ6)٤dMv_aO6niW Lmާ>%X`UU V%XѧdMJ6)٤dM7VKE>[bo +T;U"TP%BU杒MJ6)٤dMJ6țf*PJ@)'%lRI&%l*|v[j֛bYV{D5%֔XSbM5er)٤dMJ6)٤dZRJ (%RJOJ6)٤dMJ6)4S2WN^+DyJ)D2ǔlRI&%lRIe)PJ@)'%lRI&%lޫ-aJJ*2ΔlRI&%lRi1 -F-6BCb7OuO-1||*Uw%SO?%idMJ6)٤dM]]kCmR۴z]w]m{jM0fmNBNJ2+ɬ$J2+Q&%lRI&%V5%RJ (%dMJ6)٤dMުtq(UZq̿5YkbkiG8dolh,yvxؔ|rڝdJ+dGlRI&%lRi1(7z̳b}^*RC%8TPCe)٤dMJ6)٤dS_VK0g;Q;g;nԢuA9f]J0ڄeF4-QY2.ߒg^!,k%zVN]O=q:\nt'Ǝi޶]S'n[GtAx}$Ӧ]LbmSvncǻGEhaM }͐[gX]4lN?&if i;@Z)"F]ʱD˯Zth1\m5NxuvN)yJSJR򔒧r^9ߚz=A4:][z}v4Zw>;]'u\Bm;}V3G 5E]hi۳aࢉ%Ӱtb  bj5=rw4!^"anGi<hv[q [`@v]k3:hY2ks%sc5R mH b`M" fnSߜB&׆,SY1p,wܶW DĻﺈ~VJU*RiJT%lRI&%lh$ vS^R㦬Mʴ"$ EH+u1u!Z10,T>"T-~lJe[*IǤ#RRmR!-Vş=&GRGW7xXY5u۴-7qqݪ0gLJ{ʽevkgۘ\%z{yeUьd.UG'g:2N*:OnyW(*J+!TI&%lRIɦ~eIFb,i*PtSSAsҸDz愒\#e{֍A;j&;S9g [1l$5}?2Jy/G"z(By?4La* SidMJ6)٤dM}y?Y1S'vtǻUs)A@EzsI͋MQ3İs{#8G`±a D2 Ep( y5KYʐTZ k%VZJ6)٤dMJ6)ԟ!Fѐ 7zؑCivdJsȔ6X)^PVJR+I$ʊTI&%lRIɦE/GR,VC)=_d92|K2oj- r>}5v%oO{:l;.9b~k-,%QOVwk9p~yһnc;Jؽzp~ǯ:/9@xiK,NX8`=vLCEvjQUǘkִѻGݰeHS?/7d86A;s; y1̀~HHB+>6k5\V~uqpw艁5]C[ }>V4pپkIAxo4Oi'j7ZLlnwLl}uwxy.i<9 Ħ|O^ew). w炚hv w<[N/py R7ܶ[xDžY9`a6 .nUǶh}0Kl6C(r7`~ZS"f5|Xo9 _L{W@Ѻ&>B`#Qo䰥i3WXk[ '>'uvY4Do 9n; VNG ?|A ! v w#& ރ>8;0X!]>s !iw=!!dž4'CCށhyX;t< A\A{D?bg0~J#ݏէWi]#uӖ GΤF{G=^-\7XׂB0 A)UQ٣щɾ(tkAe /Юkm1͝!ǐˉc0s7:G\$G~#aG&N `S[L`U;0B Z%a4I$_BQNKx\s 頩(ީ;ȉ }t54^FA;^={Num}_/I藄J+ٮdJ+~1d;'$DB PM ԢZ4Pj@-m%lRI&%l굠M #2Nd'7N8:N'{?qm47lFcp;wHu^2>oMo_@% T2P@%/ }/IN'aMu\bۂgAhSsޥ~MdGg47 1S\ 朆qYfpi>:7^gVnj]71(92@7ߋq PR"!)GMJ6)٤dMJ6y6oe~xhJ *)J *),4%lRI&%li*XiXrho iuӺO"uq}ֺۭ_63*Wk]yo̮ܣ D%VBX a%dMJ6)٤dM}'OaUZq*!wrՁ}vGl `Ŗ'JuSs]b10HSQpyǶ0؞iXk{\6Rܘ,'siج2_xzcbji˿db"^Nd&gBc oHc$ 0^WunDI$lR=,ق׹7o,8,OX]u2MYhG .7,4/;BaYU tzK6UtEސL<-K:8fYlz-h+M#͛7'V'>2 uj$T.Ip%q{,OY1qA^P<15OOjZ[O&wbTn]ky,l/=P0IS1m_F ^NƣQ+2VۉX+d#M![?Q0^z8|?.%dՕ["ZC3ȥP4Һ."-RdV3mp),b^u"d%:]F_ M/. ̋dg9A ڼi.]JE UYkw>[ i;3Mczme.lq'h[/ǭ Gb qDOt޹<:jMd'IUAhMt je,OwC/N&%4JSpfMwq,+tGivy[Js_0p7M UeRI'˥'Ps<At mf#&U3P 9F NBj _9QYׯPbAp?ҩVg ˷O|Vz,F6p_"  ІH,Gp=ƴ]x?ȶXXUƃUwd0ݑ'z<5oMf.ejp`N:1 тSH!pW^j-y`nֺfY6;]س^C- Ay4t:s~n2!`f jnG؄h`h,1+amb(_ uz`jI8ɻ[dl垨It0s-i=mXpONj`=M0$,idk|ku>%QPiTiRŲʲ&UMÖ`,4"c(p0"Bpi:vL%ZSܖ';WFDhFJūJ* V5Uaz$Lpͮ.xdT՝31xBA2Q}}wxd-G}Z#  c"4bF]3sDExwdYaN[Di3}cx=ʊqAd0T@ {خ8v5اW"_]sj >ӯN"kRς^ZKM--寧Eh PQ#8+]ɶͫ9hxH(ϽÓ7wuO]ؑGLNvhQz} `^4cu[Za6Y:A gYA`WGpX&]SC ^ mLÇ=c&KoL` ݯu聅w=LƟKza `0d7cqEP=|S*U.QϛU7fXUuat7ݢy BL]LU=1>Y=yT^kRy$B…_4GP~b(~}MepivVDxxsgKH\JT!^^\bjdB$nLN= 5}g;ʂ51(d_TbxnY|v i6uȰuq5{.v7 HI>ܑbH-m.mΧͰ<32Y:BR8&FdP*RiaIr{׬J! F׋hBkM*Z*R*H*:tsZ+XNL_v\r&xP- |+u\=ěxa#W;ݖb2un/Ωu8"Q|;TMdd (̫&^՟8. ׆j_Z7c T&GNq?8mqͭtTv}jrUjsjTښ*a5yBO35fJPqغ@wS2b oQŚ RY:g 5H3<-Ok)21-u%_Qux9&,{<&D"ʊߕ?A&ψX8p||,A5wsxB8o_7 cLoc[P.]BΑ>zq\x D7i2h p3%m7* 2';itF,2taP틞OKً#_OgJqMC{Ogrj%o+ͧLowLqw//}Q*eۿ?n]n~K*e~q}_˸]+@ȞL\!/\qV~2ݿX ʩ #W+pey ?O7R9b }AR ǽ0WF#;.^.zſ J_~2Xg mрYXt*NJta8AxU8IV e$xmкyH ;oy YqLաӅE. mw/ߺL,<L (п͒gwcLFC^δ}2h*c4\>u4KwJvbh3ei ^yڌX-=o;fUZތ*n?e}ScX49S5C JѨӎτ%m͢UAQkִm: c#-hw*Tn []>fw- G3j[X&+ݍUWFPnX%2]EB"3=\ y9N0S.Y`dih k֗x־RO\pKj//He٤ZWo8Ca$wof9W XCWR ,mmA kR9J?5)eQG=*#D!FJQar.Fz@}I J0qoMc^,7*@"ٴL ]`.}ihUߚˁOW+NW_\^\]?*TtzW\~ek咣^.{UOut\jMd %m&ܬR}dn /D(S\Nq;?\pc_ܸcqjc{P<;T8`^whf%Gu%S-+{6)N۬k$]tuL2$[!%#'6 34XC5Ʋ$i΀߭Uv 6׽>%ZTXt0$[3,*,#6+f!,|I/ԏT4`>Y:YWK%ZEU " ^CXơ̝\~c xB3wv|!lU% 5/n6 2Ifk\yc2,r>d+e^d_ m۲-n]b=[m1ĭkpuA8utWJo%ywgS80$ќ%ۇjMxj%l tutHgzy+>N7*4FʥeP3.E^?&JRe0. 0u4=7catOc|,.ˁ xϩToIƷL9džV=0g_Wu,ʲvdP9Iϋ_TPTAaf(\WMl+nfrbȌ Oӧ8Pg`G1_FgA4AшrlshS'60{{;^7Ԑ4R{Ii9oP.Ffg5MOW,e5kwe3j+pѿuٌKcr岌ˀkqdmj 2uۈ;^-ߠ@ ݪ% -7t#pÒݫOCm.e,v̎C Iq|W5jI3z9_$5UI^^OSh acWf4,,|9kxeI*)*&L1 { 5)G{ۧ&QcV]=FDfsCϤq:6 2<| V7Og^qZbjKUIC^EFl-K1 9Y rf4.҈kV&?+.ʽ*kWJ'..e'Ӽ#qePkwz_zU?Y'r-D8C2p1O)}Xu$|td(K{t]l cOiGkutdC5M[b;HB8uԿdYDbzbeG}]ݺ-!">: eMWQn,ҏ']ƈzKs\#XЃH&+M z&a/kj^ET)&)ir~@w? = A` A\e\P`iX'e2ˌ,tܲœFǚ $YAG8_iOh&A^ֻg+4pT5 c\/φ]YZ9w{;l v^ &bES{D ?^g 5qߕ;! S>NQb,gC/dӈ5:4#aʥr1S@ |ϦZ$\?$?"?%?'?/ %xo~{maj(,\Sb O7e5j;zBejj1:&fhlj˫rZ29z t"54H<5C4߂VZKXox T'&ZZfjz5sCrP`M77rPZz3%j:2&\ve85mb{us!?A^rʘ,_ƨ +D0V^5w+K yTvp?%>܎`A]MhƼz54\]iuP؁.-/65:t/40Y!V[-4\d=^rCsvzJve&c*zca]G'5pk `zKohf >k&+{y1a Rqs6@&L`q{NwؓPd̐c]@[}Atjil-] +vk n:5`TeejqtۥeE6Z ! J چ˞ pNǰf;j2ڬƷt^5X!41Бuc@Mkl&-*>(ZV£,Xy1k; !0 +欀urOذKIzn"+6epIa|pX)(+#yufpH[YJma}v+SBbHAAQ2ѰB]k,p:6`kP=f3jdc:ƍV 8[-ZU"`:ZG[РZ6hv m=HY8@{AcjB4…ۂ.[FGF>tׂqQ@>w:n۞ V%p{sm}IĹv;6dO8@ BijU@^xROhayS>>ėڱP}Yq=iIbgzs  (do9& 2m@S]y0\QhFH ^pvYiDv@7nVe\pvQqXd!Da=7g<1D&-vּGÝsasyJ%ߝ9)o|hR)S6ϲMV0t['7(qB/<xKpPCwsP0b<ܿ7wzKA8o{?p(Ϯ;^8x\(,_,i$ ၐJcSPMGChMX$4NZ?=\2]Ckl!P6x6hYeTcC.b/|e5.`mFfl̑ jqb敋}*bCe!&$dJr$(fkP?-Q[z}|3܌Mkol4\ Votg;-vEJ2N!3SK6MN}'ͮ <}Vf ׀jҜG>׍iQ\a a7J7iim ?lw߂;(T;Z9]epjg'`fș?S]>`d;YQ0 W(sM8cUG %p^Ia5]i=bm1W(Fbt$FCI4wq相 1?{,f-JSN1WVEp8b1Fp ᎥwZ-.)+;VJrBPg !_%+i0Q0P# &6U^+sM1"E©|* O1ƹXsJUrM[7 67fXESF/ ^ؔZ3H#A~'܁MPan(0GV%mzh ,q, [7fshX3^VWhew9gQ^D~D&K. <ʹ'۟GbGJEG{k$϶cebXӕkNsm/>go| kXXf s1{ Z6nJskJIʩM'˦eW eZRxA rF@9C|Q8Г#S}x/&WpK{,WB"{˥ej sr Ō2^qE59FuBݚAa  fcߗ}_<'1J߾AܢAR`ƀGp芹~ou(U<~v_vӣ C i!_s.< PZ4=kǞ#s1#hYiv}6mƴLybvۚ ^ִ" V:ML҄tx!W ?& f4d˚,!;<s:/Z,dub+:ffm6uSʁ"DJCJaYTMWUVYi=R ` 7xoI7cõ>4؋4R-7p~;]/h{wP3`@ 5K:OZ:_;Kk'm,iz=G"p]Xfwu>b%qk|5#A׍pS,BFTZ08\YlwyPbp} dazQ`5a+ =up`?ꎁJ$hnꚃ^Jn<49ZGS]Ez[0C}mS븺8hXB#x &džokDF pхaZ%9Go!RNС# 3ϟӱ -vaTU|cSioW`a!ͅJ0Jq*:RAi?{HQl6LLKp d>YehSoQ䰗;֩jSCK iT96RBCG(Hu6x>kEzJMyO'M!kpKǻByl p!&;S/NZMt%ش\A|H\ vntKn7Jh"-'Bf<´ 9ΊP:-v+!YQcxWFh,Nv뭊5͉dyGMüdRLvZgd 5:(Ha9ڤ q :w>8Y b2 khjf-RM2XpZ3\m.3BI|=z< O7<T&6@n8r g) w&l '6,"Hp3z%b̧ݕ+R"d-Cu .HY:5n;Jݴf* 𾣃V +cQn s,¼zenn i@i:OO)riGza~@q k3ә keLf2$ݱ8&Xm tC98hNxqZUq5 (܃QZP}ƕ ƋmK&4EI¼:xwB k0E |J9F(,vF 'B~-$6.@`uxx%iN#X8xMiIͪxz[!@>-E2BQLP:V1tzNe$nGts4@s`aJ'%NZ( {6*_qV\8-+X)J Z׳~ Mv (/",0BȖfYl=C'Djn`6\tgFGž`<"F ̶0Xvp@Z &+# FB}@!n_|?C4]"ax_s5C}p:]=;¢%sօ[.m.n[1鑡U B2w?TtY5lq{^DVo~`(̓2}6VMgOWHKoH?"?&?*C@oI%\/##x`~ I.\s4Хu.k { 'ٱ <`zj 0$2֤7TX6[$ Fj(8>-Q旇߽ZzgWϥCAs&/C tJkWKy5k8N3QfL ρ剑R%J̪1b\CěZTjuSnMV7ZTjuSnMV7Z|En.??{6iH2K 6Yצh{ .vȚ"o8 wAuts g" r5T@7.:?i 4,;0 @5p9_cf DA\XC5Fh&BChc RxqRZx|Ns0Lpڞ5Ut$5ޅ=Mj6ЏL"^n`Qy?WĝCx&\zC*wYtީh5r CHaǼ6;/)]LIk@hZp% ~)SF&ӹ1Š]+ hx@1sZM&{<Cv1A5t{-JjMF>A} s'CXP9enWȒQԺYnLs*cZ*DkA"$a65./\=7X*c𢰃e>܄8B]*]#nceܳ;uK-J4҃ዲLtMcJan,Sh`M,=05\K`ThQ#~(\]LI-uÒ[s&_w@'X뜧삮e,HPaÞAoh/ zaq҄i-}ˆZz$%*f _%%&HLhB 1ŝ3)H;0 k6(p!8/6fAc+tԹ;!(x@PM`;G;:g,7j<%X5`cZ%2WpYe*F[TxL7^FTp f!t#vtdB״y3@]w;;ۇK/|Mor@c33(S1J&=R#(tY0LdORZ+U&^DQ rX 3xb*O0 H!OǞE+&+qS2U y>NDCL E9Cf1lSk2N)ĉODw..u Dj9x4ڈ@'@}i|7+t~GF-1 {̢kJr 19@I -n0vƘ\9y.`1*1%E7@ҁǻS)!Sa<%ig*3(ǵ3Lu"Tz랰"rH^b+?Ÿed%|8*nkVB͈Mhh4 ڌ 4*e;e ȕgG:u2hCD40"\$;&-AK=w~ޜq 1e1f;&_cd?U nF %hSЌ.1!$u(`0n0bI>c_|k~^T~N*B*>-#ʽ='cٸuJ;X%Z(׈7n𘺌cYa۰+,nlj'SLjl2*2 >r 0`.0ѯz_VN@: ] QxHjv fv1E-(mV=3=;MLg@p8NbʼnDsىۉC-v8>rr{fg@!]]իWWFmNG-WS"dJkGoz@@ZNU輛M}2GdWk*ct0,݌6`Jn;ky{y]( [o 47ʔRu lN1hJqTdx$"B3 ФX/RKuo בL7s6U En])''ɞ 蹤ѫwOov;v&Br"Wof&wS*ܜ 6YqCO+ߺ]rݰfTfuf./rPꛨd*~".Vvk$@=V:lE;p4P5<lۘuSnBRx A7 J#PyOftɾG:X@_cI_b  tz"l隽nA \ǤG6Q JS !5$Emrw!l MR=]]Bcj0À} Ohz]7Nu=LDg[5$.Lu  ̉E!1Ӛƀi>4 c<'1Pslb`Aq̽AA#o5k"/lctJ"t11&a0Wx7]L[(;Qqb pj1eqohuMK`PvBL/nNɮߧ( 66dQ0OH$AzVR4C(n6}fR61P7FxI^gP{>0%W=_]-3K5&J%U/-PADc$ nb́'7̴?,|c׫EEfhS8Y"k~T3WtR**~OA)_?]Ru%9Kr{TNkM#/ :hasyK$ Rq5 iHjB|w$OAWtx7vQ06{"l d+EH_jRfՈUCq^]UV 䩪aKO#Q>iߧF)]LFbcʆ9t~s@5"ISem5 Xˑk>< #(',)?Zdc<҂XӰze{>=dݰW X]?g;~JHu.r(Ppb?gM"0r/tB&?!e⊕*r^| C3z߀׀ҐޱI={:#HV0_n^ٮYH_'{2̋p'_˨CILQ2ZdnY`\#Grş hZХ 11 i"^[YZ9URG9ػ}%b ,&UD) OKFpp) AHиlsƙ ޓܸF@4i.FXݡ'\ShU^)^qOߒ"6? b `}ӆ((A c;!_:[wM"O>3iQm/DOaـv4J#YA(pkaHY(6yC Bh@|{Ӭ;4;IF;q 0h߯|eЃ|`r#[nBNDpk g0tRZnL-x j,X K\Drہ *Qȯy w\rVt8uz8]Bk'V =\,,J3.${Tq?ϰԇw> _ut0{n(bSA<.eG-8RIDDaۙ>oW-t`a@%ɒrѤ^nd吊JRH5rUKǛ%cr&;eѓNF%B58b*TCمo7~x uZ `tjyܡ+Ojc iN"Aғu@Dg@HFV̈́al ~A Ø'/jv4KVпX Q_ŝVttnv NUw7P·rxZ|!neǗS{6BS;Up+n\֐ E.fKOǬSjn;٢H]|sL~f-tw I7܀:[o8 Cd\//CIb]!(%?nW*ZR*+JĚ?%D%Iox~if)wSq4ExD1 HPT 2ƭUN$.n3 0=4 /j[N32pVY0p_>h Εhi 3`a,ݩR),G=jBq^} wLInBg1+x%hv\pO c д;?6Ӯ[iôߕ%ai8tFXIƦijop()٢o)ӵ2'_*`Q.jE~M29 Ĺ-ۦJO& \U\r UQ650,_A?ʪC F(_4P mF^`tM^D]`YD3䙧K1v\f|.mnKf:BU Xxw򪫫]rC Q8<)xD,퟾FaK.Պȋ5.9S9^fulaU.*xgRRܶ0&kGԵʨHRJ>HGJ,#'1}Zr׻+1"x'%j d2n$OaC jO=LdU*t) VT)X,h"mk;T=cFI*]jLSd*d Z_bBMby|ȺrTuOoo4r~* + Ut , y?eԠ倀5#Ӭ.fi\Cw'CyTHam$ KaoZf?R0,IaHM`0q@fe ;~_UH򉄐p0ګx@] 808]m)n]3pgi^QJ`d8-Pq_ Πa[ߡbN373+n?,1yIt#D iߥ25B#d BVZ"ÿ-(OO"Ä!Z[=(V=qfd>0DL-mr`t@ӴMe%D@81Zz4U:Ϣ,㠜)Q aP"~QA|L /jgKtm }Zǟ1jXس{-*F RZV#ެX_-L? lj#.b<>;4[*s[j>']@ΖԖq\wGt [.dCƃ}`J-t.Rڂܪ'4܉7qL|V2~i͡r=-h 憠G5Y~X6:Y}+H?!- h:zϴiU0GԦAoU}d0 XX õBr #8tKt=Aܣ驴piWGBuޘ@2de~Voo+)U{n%7սBV1FwFIwzjH=ŕO^ʹOFV9_p4gU_K___jzY;"I)7Wws>7!Օ/-2bmJFƼf"Wlw #'ÇcЖ^Y sX52=x&ƠuTV'?sx,²"c3uzF&@Se'}}UZ"WV2Q9pޙgvK4(!ird/jC$ [t(jO9^?iqT\v 7`j-2&% _!%7~w

h>'<+(QU,Q cuԗ!$wG'kd6덋VWGX.WbTWD͍,򖋫ұFxWeI"S/VA0Ga dS xf @BsgUK!+v2 b(!#R9vVw4dПizB ;uF -Em4XY Z̮hRozG< g R,}vEpiUh ;='FVAƒGT׀ez~DD 3tRӓ&^u)<=(n${bBnP"%Cy7q(6>Z|l 7_75Ճ _*xRA1ipJev sM'z=xYqE 1]g,h+ uI[P @;م=bDG։ҩlsnЃf)iWʫY~Too5f4߫<9M>]f&e]6Ȁc(i<>^bIdj>( my%80(L6W6d[EŮT\,;\gޑBk{]*zV)SL/%emb&[}٠F纄*EI, 2>ۄqƉfEuU5Ё d)WnY-:0uE6`zN`Lk Ea#;HELbQ"e/s|ιL=lC^c4Ye ZFkkP|bGX6|Z/=J:{g,=9nGwx] 1=w6}P|}C &:)҃䮚v! jK >-bd1 LM_U+ xOk8jq+H{iћMs]i1=FWlEdhEvtVt̙~{P-Ttڥlye"VvZ^TK)8w=X)Qd|qi]̔*TG}d[ R@ڐ#*<)Ec!lXgP"IY Q5mYE$~FB{TI`hMkw|rEB^1*j]|Oߗnx.' ߑ`^ZKAe={z{};8Ώh ? {]Q|">؞_Яw>zj櫉 |YO(jY=젵I %+NxB9=D]CdQ=Cڵ\MB!>]O/1zeSb|(a<:`Pg{ ;έ宷h Ӧ^Z#*އ>=2{dhuzXg5μ@]SP{1Ow:ROp38e鏓=R3 d4RsdM}Ȅ&0? 4(0 z1*qȥxbTx@#u'ό6b 3{$^ HkmAxD:z`2Q2@ҽR4G)8_}R6]2u20{G cUϓJb d FvV{o~B`\5 ٘ ~@:(hG >0*W}#WfN?0$ K59굇Fp4r8m2FB@ޑlilӈmm2c;[zަ()sd G-ISdkr2 ~*-f<Р\xn2xQeQ(VRF5 {mtu^D^So/b*71b~Q9cJ?G{E~ 3S.v`cNʞ^P=GL/ f>1yϨt!YDHc3(\`isR9;yYTOm;Y3oN{{ZK :fLWl,UN.NkۗN`O${x3 .@f}tfm;R$U̒$dǯ\vx~o..sp{%i첒auoxt%Ͽ]qK?WsϨY OⳈխ'ϔQ{v2v<1>\Z3& LJx0o :.x# "M <xy@}4&uO.;bNzz2^tF^kTR|ۤ? W \PoA ExwMYdn:YÁiz>3 5R@i bswq|0pm[Cv5X"#p{8k>Z`*& |;wgT#ȣ7ߩ91vBgרw Eq (әWNbZӚcvW$Uo^sIydzCu9)I|c@3& tk$;JHO1E.)Cڲx"(>w)cⅦu չRʉ0` 8;wBg~Ci*ɑګ 㦮ẋ+pMH'&ߺ|˷4 6cwS2&f\iyaտ)LnhN@@ ӹ\ynzЂxxjB=V-ݛ{E 'fijףuBM&C={x˛C]=1kFnxXz9 o>*wo~jID堿ֲ~G7#T6 nn Ҭo>`]ޫ]sX7η5E|[P_6m*Bo~g mkzPn&g4H]X9[O8 pw\9Uap 8kVgW^,.TIo`%zj s 裧9p|nmwg1o^4PC:Qath' (`Dz)ej չ\X,,:Hu*Sk7z6F3 Aҙ:24= 2Da&w! &18OhN>hdWnDBSQ$KH#టrL$.3O^ Vcɀ?24 w@iK)/}\t-.v "4jֲ'FOrD(iadى~ t:=LE&UڙM4*yҥ ?| _xG݅//' ^Z ~K/OR<]_P,V|\|F}by3+OJxy zź_i+-0Y/N м,L(r2}meǗ/_s^>}|ʙK^iO_W! x /zX@^s/.VʹO-iʥY?|J_{ܥOBљ+gNxK+п3+Ph: `eRoOR DžD6BP*Lg+?.|/\tY'3//t'cr՗_Xt,ETtwsg gωw/}';Uŗ]n_±!F KؿtW}|>yaEzZyE1_ g_=ePxev/2JB\%Op{Ey@)d`;֟Ũ Ě&`:pvH6]Fn"[["wV"mdp.Z㿦ˠMF/ +h݆A .4, ct.|M],&ul(d9Ul1 5bcx}2AٮT1z׺"-$LqXU<84R(S_8,qZ?a|h5JVxg(.8ih$h"C^GW Vxy[K|-{~WԿbn\M3 7n2)ys0i ȍ wh(_~֛|QQ5jzqAmڢHXX6#zT)MJM4 *_8X!\ifpBÿ"+A_JA_o\*>a&u*OIxO6Ou㓍jZ*1R( OB{gu%xRW} exO>_ۻ{(ά3[f4չ)in?,p&\p5M 0rHquNXٹ$OU ]ǤhߍUrз Օ4DI>(KPiUiFIU{'JD!16W˓.~!]~);̮ߛxag1 Cv:IdAI5XHTmw i1 bĂH^ ~J8v9b>qbrr(@%CW-xpY*V2 Aݗθ=6jr?a3 B=Xjɔ9]9#Cy );4Y]p@a)PvE3E`r0߃c_ș/c*Oe9YI,I񡎏#{rM4,+t)HkWr/ԁM{ =Ȧ_uUic7a}Z50iFLhI Q;>CD:ȶ,uD&eOL7AA Y*{5/hS0 h̗t=J:{‘?ZYzrXbtB=>Hbc%&mI=7oW}կQ煋/!g/^:EȅO]((x˗>I>r1 p=%Z`r4\._xkPȾ3Y Ý~s/ԙGbYȐ?dQy=9+ugڞc H xX0-p%`&Vmu"i <['5M&&m@RJ?";D)SX7ި(. l#8v= wʀnE[>Rrָa%SN@yZ[ԃi{v4a" 'ݘK1~J0g8)3ІuNWG?K6=|v8}Amo݊#Q1 ZG+81.鼳!a_*aoNnWm'_߸krۻuϼ%/5R[%iFO?:`m}Qn[oвl؋F;p#vIz=sbKk 3_Q4T#!H,a⊵tN7z2ǃt4cσ'jD·Ua SCvr?pX0_9j^HntnӛRg/Uɨo Rwl"e.Jya^Jy*L<{Z4Qk4Iwn=ן*-iZj1t39}s_mnn=^첯v{X7;F:?´$uq s*sGRD,!7Z 3pk9:wmn[r[9Gk5#3XFsDɩ;n\Ҷ5]̱;cjKGfr}"4Eakd 66{&A˚Q;#J/T Tp\٩3ƹ?\G0#&øz: pU+2Ku0o݈ 1y|$֛1$0~6TEZmRhZ&7J fڤ{R3q|QW+gVj0JI7ME^q*;==%.yu;rdnZ$UUu?Ɣ=o5luӽFNm\``}_k{<Y_]Äդc,| 5Au|'%ЧP\ &]ݷxYw=_:/idZQB`=ƶ{Vɪe{`/X֮ם^3!Zi[!aM& z^+owٚBgDpkI!^{?mo?(kvG3 ^gT/$aˮGkt:ow&GS#.ԼV[knFd?0j6hҏH4Rޠ0)#EycozأanzmVN!K#!"pXu. UHt\u`"@Z(%mN%N]o9EX(- ?И4(`֘(F7nx"(0 Ԇ >1: +@iA%́2Th-P{^6-fw`Pf)-^K[kA$0Sm _U~Ƹ `TE*<U t#t >@8Z~v"hrY4Ś1e1}HS֚!&ͦ<u mfEdm`X[ѿNȠmnė8}J5y[]TJ>+ARRu~:#¸30@0U :[|o2~Fbh !=+VKpK"7A9wT?2mߎB=M1 $ADUA(_7 {}] FL g t *%TrZʗXV[b oTƖhmlNc c`VcoB P=P 򺞂.hk\Jipҍ <-2 _@RvJ^85ڌIwkG<9V'ox;^*777毻=Eo[kf\"7p6ܓJpִAφIFAU Pه]xk/u07$w'r<:Awoiwh)7<T$CD\ JH#ID B9oq($ݸu[tH7WŨe֩BL(&eܯIqzlR v="A|T4S!c4qcWߖ|*dF#[WO?e+ZD9lڌ4R6Ƅ+E#gEYJz|"*] / t:2LoUy/EmbIE97.dIQz,} a-&b Z "-& k-hEzKRB*(/2A>,Q+c9"7Ag%:y_ a*b@2~XIh-@2I_S.w!6?H XX J ,zp͵Vv@c:]kn[. ')[GDN(:56 14Ð 3ZH]*{ׁem6H }*G|p[$fy Ι(\kEa80_)VNN[ViobJș0vR*9(lAj p DPx3Al(/*v i! 4@-:[Q(PB"hA AAH 'P-?m>A$:Al v 2ڨ 9ڜϺm9HڣؐbA"VK =#HG+i߫{mvd% d-" J"OƉUCw{)S 4$GrA'818/si|5v]h^Eok[wdO>xl| /J,K;ub匶khE8%{lIe| "xK(k+/V[_+,`,?ܟ.,$t2>#P"-sr;BNJ.,Kp:^$v~ʻ*h9cVmaHs=h0̧D̈́Е&(VQsԸ)>膲=ܟ65js^ eT筣Al-X󈥉Ɣ|_Z(DD 'B` UT#Om[ $< ۥ =㐆eŨ,? Q;b=D~KPY*At=p{\;[œU g9Civ_y׸>~ueabuд8w訴?!i/-nhqajOg6,mZ{"LV%ZƤ+g9`f}|2J=WU1Oςbڰ\u CLc ePZI(7Yk_E^֏h UB TXq,* ,խuWa5vN+ x WJtha}[Y^݊*r'b., L:chfްL2Oh3vA՗VzycrrZf5`n|Y۪5o+hKJWS'3O'-md> m/yֲ?pյzV\u ^E%ǟ!HĒfB+07d䴶y @P?Dd .X#/VG lXF-/OCs0  Pl%nInG?f[X4]Rr$^.nV5] 03_gB80x5xv) ްMaŎa;nȢppg:,`"N`F wFoNM;)@9SL@`'?(aIĖ8ymVul uF]u$WloN:iQ\&:z/z}$A |-[hZ0@{T0g"V%%b͓2Qr" y"Ī },]P׿|N%MEv*mm:߶Fm쬑3QU¶wd&" > #yk 9fúehI֩5lB#@Ysd(A*&|*џf|`C"/ctz#TL`imS@e 1 A}7. KZzl>8E: G1r$Sp&T-)] eR¯:ZӬCAZ3C _ۃu<̛}"VI2[t;:mЇ{C&%-X拰˗*4I|AĦ} 7kRhi`8e!|Da8m_?/Կ`@)U>"|Ū4{΋UHt0Q5|OC/ac:&9!6'[+%T,!gMzL@AtS3V 6D\w\\Aԭ H&D_=ԊNh*\DH=ҀI0h ؓy 6$Ԥzv3оST̩Kk ysbbh"D4mF04Ѹ5)( ؼ'B/T()m+E17ob\ v`?~lhl`K&7s,!!W'2X0rj|p8 .lc7)(O'!V5mY2F%gʰSؼ=8Į^1s#1bfs#QXnArտ`+>ôOP;ㆬJkn&#7)?|jF~ٙHI퉸1.nF6q&o#I"q42?"GoD@EFiPiH5 \\3nICwc{=7eģ8|5Œ-A61]C^U0 SNDޣ'k^ WZwXxi{V[wk-^Yb`]KIa/$hbHtsjF3|dR1^瘰jwIal๛G&M\^0i4yYG5)Ǝ`iY2/U/'ٌ~P݌F?&6IxG20$r5#u!0|XYGm<҆dn.VhLHop;hq5RUǕ5rN?/xj<D0㤵u O'EH Q蕹*?Bd\!ʱiXU v`_x?Fgai!eٽkf*?΍vEDg{mgoU45 [+on~nj fܛ6a E7Ήqh/ 8!+n_nGcnAl0TvP)W(KIjKwǕٮfH yU&mS#|I@ B+ǔTM9N%wr*9q6)] q6xn->߂AFc4i>i p9&[\Aomnu.F;i0n40C3W~<؝vVE_8[96$7m%CSiU@33zwTsf2ԭ)fU !)qLz|a;p"u(øM7\2mQK7B, l:lS\'NmMIZK/ߴxg %l.Ж#*S= {+ZG $ab NTcWb-67z:oӣN]Gh9}EiKڌ~IpIgDՍ!x>262'%=Jc@@U4poNͯf%q/8˾4p9ׅ䞦I8;9==,KL j6p/:@_;<55D"1niTyRG9沷VXG9_fY /7"JΞ{e«/aFlXI LU af=l1*N ;hk*}O˞'9Ca5k$!Wp` ~6H /6Itkif<’Tu=`& Oidԩ1)h,q>4 O WS1Ά߿_R?gXcX։}3y0ׅ#O&bJQtޑxb7"U9y5a zګdB7L8{sWm7]is .({v.q9.1o±Zs]-x"w%Ő:J͘h591*,O4W͝;4c0isY^;U"n8M%ĤK7x Y'sofGؽIqxx?L4_LP BbrCG%}LHZ߰QFDWa&E, Qn4 .z/8s[^\[t$0thHظϼCFnzx`Ԭ#2)tR[{!M8gh“<-Kπ 5/ 5m5af)\pS)pB~E{H9OzT;|2f9U{& &\J&rz%8jM?iF}E5愽펇 ^38';s)ِ*K}ɞ\< ֕EN>80cq z.1)ps`NM6x3hy䖐R&a̢WG.|~r?w?%VCI-Pۺ)Gg0a %0=bsoؖO 21TٔAޜ8hPO.]! GKGW tt_TQ%p^9Mϥ4 2H6`ꕵZJx:O}$((~fZLSyTn`khwj@dZwVUU+Cѣ{5S|mmeVDmV#~@g+ Q IM{"ʯ I mSZ6Ls'Ȕ~rҁ+EknT?6 hP=x֪7N.U‡B9{Zf3v^EzUlyI8Bh7( Q$ARKHN{YF(?ơKCJly8(#%$)O+t\Uxzf4L`JFo 2^cvJ]ri=ntSj kCx p:ܠV5U`ǘ~,tdEhUxKsʪus4^ՀQÑ9&i|~Lqc?qhnDcrGH |>+Bu@E<iO;m<4$Kj[|E& ȺBDz^@ D8}VxTY<܉-onɰND={wj6moxRy;ngP'R)[?oz,yz;E)sDZ[6o8v =.m579!}_?L9 Kci+pLBK "GK5iem&z޿KpSi4 & J b/UQ{z/&W]ZT2&Fh>(qTƲC?ֆ|2?!Ѷ`P_ 4UK`&?@cgc |:1-ҡDh>_v }MHYڝ^.Zn_g nNȹSS+BG*:Ѳ▊NALv@A7#1 B v>fR=#[Qqt؉A_Wn)2Kotwz`qntvVdypۍ71xt$.HMe2cso_w{[,̩A3X9/-FECM~] "r>{(cL۱}9ov\P~wE} ςa__ષE^tju^ۃ/79PA:YߗQG$˛X'~aޱ@w>y H%  kpHJ}@!סUskU| w;PyDˎ /;>Pw rtO.$Wyi{7h7=;.Tp _% бo 8_/6_^>Jol=~ \_8  r푕^:BYA 2z lu2sj? x v^ qj} 4 M|%0_kҫIC ɥU  뭲W{@-h?}qxGՏ%;cz*E^Ͻ^Bh4l3_~ ɋ+g./< },8}Os^y 9GɅWW/ӢKO^ʹR)a7uJll@U#=bJ$g Fq./_4}d+K8}EgϜK$O_zi//+/7C.- g/zagrxwq &f'̰O[E-&S1ktfwGrSLߟ^14~&}s7UP|ҜAU5>"iAWO =)-7#;CnAL 0:RcTXuM+f6]<@sĦ6n*spLhnrT?LiNk$ m9rw(f _EAkC><3{Zq_LAwbMd qaRG5=V f$й~D'S)r$9 _,BV)XK&'ȹxFF)Y*+]+*_ư#'x?!`!⃺=覲'MiuӁr5W_1(堖RQjе?Mt }X,f.Zþ+0$k׬|I09*4;t_QlElBMj`}JQ3[%ľ8#6#qPuje'5IPA 3p>?BSl=*u5<tթ ~X2 -0>h`'UQ,hoIK*VX*T1jMvqb-/\*ˇ2MvB!N+McW[.T4%E=S@mA6PTJ t!(}-F^.Rh _SkFVz-zw ml6Qam<~` ڳB4v *6nLgn`yvKL´18>"{F.hMnFKlS eagIHeb蝼dyzs|8mWKm}wEZ6v>_nߞ=ҳUԙuvȴ)SQ L"?;S.F Qs>ܤupǏahqn?69VO?7.4hѨUԔn8B9?F%_J "y & gs.KN?uS%02xc43ue0Xǩ3>9}/?rEJ.peöԾXb{$U0$> sM MGƇ 5RQAǂ}lB\5^TKFN4*Yd!RNVRhCцry;cᐗQuF@ՙk+[޹"'& ޠx% cv 0XŇspDr[1᫯^hP%{:IheÕ>']nh HLJQ1}f[T>Wma+sZPt>LZ-lst`pL_;קּn[nөom3a 끣< ]sytNcJ^/#J%gCsT \[RaϮ`Lnݣ1@y"3F ,wl'taYNhImͯljg? kD?.Ҵ8Z/P p|e5ゝr 2liوmA#)# Q4h=Y,L Cl49Fٿc;2iphŸOWK9>oԁS)tGKMD[cRbJN&Sg[N8 3G?%sj]eqb氾Iv5]vX n65*L TOoM(7Ac0rm"UnrDݱc9E6!,1X)4qk]!J16=\zHL^Q)9 9(5YSRN!;Yh<1KGҏ9#΍=5eAHQ~csJ.Py!lU/e"_P@m7|Nɘ㥬Z1sN3zBdikdzWg!:֨^M52 Q@?cMHA!=°jyu<-.иQLVuu |*]MBQS#jQv*&s ۜ~E|/r?$ٵ8]؛>*;>yS98u0/䁙O Zxmϩ!XZo9`E}t.g*AafC+H?*P7go;?1caN\{;sy1OKqf YFPmof.\pC;B6 Meh+3q~#Nx~ӎeB*&?Z^Ĺb!"? }O \EdPZ̅:7n|OyR_zWfJRc,5ƛ9rO+ybL_iL]HqM0sP hK[eh.*(.M&`qTu)@4ٳ*R3/{Mytҝ [Ey{UǔSYC1A lYzð$JjwrxDUh (rXNke-rv4dό;O0ȗ2+9T_dL)>y^Yk[ ۔T$;epTqS'3OW Ts,>E"cYc>'ZcgK۱7H& |j׳v&lY{ƖS Qqmdg)ŤM=t;_>Sf@$ >FSNqqel5 :-uK}'blJ$Ĕ, oZI?4j&rߦZ~gX@sM{1p$&1$Gu| `A>ʨiKC⪩#ȃ+'aoy:FX-}Bu-; E4YKbԭb]#,c4ee?zZƓ˱*Uɳ>|hgMT`ʶgv6'"KxM83NڐGkw ~/MzJbfZCIb+_+=,v$8bLX8WgoVYT0Cw2.^ ^.4~̰PZ02vjXdX<Q+x\+/$QcEsjcyrʧ>e YåRfMNkFO;$A5-Sj֋ۚXQFOT Mlzmy@6ivY/(WV κ^twNf 6WXxr-<3jV3scw_\/C ʼ{o35La+u$}cdTM (?g&lJnhN>H4i0e.)2OLZgTЎmZ`vwԊHGjTP94<mYGiNd)y>AA)_ 2` ޣy#A+\sr,8(.HC=d,`Qڪ[9Kڐeҩl _(cxهVcw$>{R0[hxPy[gqMhj*6pbxj-f0").1)4)c׶w'$[ǀcsEc(HzBt3ӤHxo-x'\pJNTAm9>Jg(zdhB\= mR3+rF,HnJr!jFQgDR$1 &޼[cBBI,31Y;lbaN*JEFCEbxP 0k|=P_\,ͩeKLr8lpә铪/?cP@xڰ-5/plU tiڼ&=ܮY?̱9.trm2&DQ\9{WG6Ziು/7S*KLhg޾ԙSy@3xQIgJSXGۃaܝjFKăSSǕR48k{TY;tJ5=*G*D.CegAĚĝ܂5)SO/qo@WᙰIU:`V| Q7?"wv*!{ro@4Ƞ x^2fCke{U> uj}'H+Aba dv)<e>J*M:2-9&lia.~\\h27Њ/& v2P:⣍Yܷ!a1#5{w+_f5gOyU`llncP6Iőf!m'*1>bG$Hr_QY/r(xEQ{KP67N^J1a>ߠN U]&.F}|):^<)ͺ ˦ۄe;II2 ϴ%:]QfdJi2f8S)-Rc;)?!R[$EY`I-\s6p+\b6qjf&ΩҜMI<3%,B1M'G'A'lߡ}ITb*cRY5b@kMit z8>s1*;]tu{0v۽zu"[Pl#NG6XuARhDjCQMk!*sJW3+k=|JD*ݯ\?6eI#TcbR&8cv* 3Bs iFrݧ0fK?Q&L5˛ͦuJ`5՘" %ɏjĽE}OrM_0;ތe](#}yhI'.~ 1/E=waںCI'DZ\O6zh1o;SC1Ə pdf9LY;c .qp, T!DG抹F9I;0&PknN) /^ |6\46tj<"|%gUqeexnK/rL)|aEǢ=~$q8_Kq"`U"j5އg0MS>nT16RMH+thB;@",/%SˈuuGݿa#DnV$@}]%7R B>ŭlnIDITaqDf$D lXn6A1↍͡藃2u?T;>䮷DpFbNbZ〈!S!=EC1MѠ-ڪ`9Һn#a1/4u<ߖoԄj'QƭB`&sȜgN)WɋkAJW+:2 cR"i_tDWg[N(1Õ: $<&guD4 m:I4|PjxVh5*5,4Y(#HLCĂIFT;sH N7aÆv.@e'YŚNzaq8!WMN`Fd(I*ikg*&3>86d-⪳\]/W+Tas[MʣU2}l3`B\:yeU92 5PR=1e堘zƫeN@,Qlf Κ5{|IrYUr 5U;"_e Gc# ;T=ƒGjU$:u'0Owu&.ҟV)E^ק'9.&!a/İi )~@HO4jWwfgd6 ohma]fKY_6?u1AE~ѻB.DO jy,G_~/W/xh/\.1 P,vtDXt5f[÷3[Uu7E0hɦ&%hy |kNNdw^'Ƨl-%!SQc+^r֝ښOBφluR1 ybJ:J]YJ`M%*/yW~K{txD 7vbH9_ϋ@Fj8+.q|{ui$Y!  ,}^}7 2)1&N `kX9Jjȋf5r D`8*sa m;׏oGtFJƥb92ȋc_w{交#`f7NCREf>v;|P'Cҩ.pC9!nWN{Pֈx$c~0W垘}eby3DG S%DK k `Oޝ#=(:#r-=Z 64:18qefS{8%­ JeS̶shiP>YVlEka}H71):7 ó\1HRBXWX3`ɇ4(jL6Z^Zݓv[%<)^av%b$(|kWU!Ec VYo| 4 uC87a9!ʆ ߜ[+~x,G͇ FxG<)ɬB5rӢ}L~rY"dkP#1DQT(E.w/n/V7qE^_~ES^y $;$vHhq?+%BY#R^^WhlX,fuu:,Cwww}pNJ>ڠ)WP,9)SP'~Vڐ&Ok8qL` 0W ;Or =٤u 0tt:x_xjˢ4{8,:hطbF-:/n\y0' 6\r Z53s-L]ɿEt 9Gfj*D:47ZhrD0` 2a3`bI%98K]>F xK3PҨϫQTLu.x4ڈd\0 Lӕo;d Cݯ^/J`V4NdʲE?HBH!r:YG4_~DmH"Kd :U~GGD/5p z>}UXW#PGnee-e\浺2{m=O1ӰXj׶ݩ5l\a(麍^';u&,~Q:.3\ŠVB2y Ff0K?ې^BJUXy1RferOUTQ\04^VlR f?dJ[ {qֲT:{4ZxDFa=6wQ?(<<}:(΁Bљ=5NjX`%\XXhz6U<X Nk@r B DW+mF6 M B,4uM%AL= [8 R4CxpbTJ/+WML=?V*kyƇ֚©ΦI^i~`sʢ la#7GRӺ*kmt76joR&6Î6(/*ǽ&^)RKWb.>-cPry̿cf^ѓڅyƸ)<&WTOu̶Vc&ڂl#r U,DЀ51 jPsE6pL8 +nzPpV?Z ]Hiv`e!>k%9ENL9r%!OEkI nƝ?!,>G]q4N?L?r?wJ/bzs|NuR39-8N൯MM +D|E^ ?! GflBdB ܃Unnǿlc}: / `N]P٤ J'U1 Wenx}0jP{}C-~ ;g{\BF-TLp41A)*Z| 0b(CNZ|ٍ |V{48u6ylлm.WemHwLDc{+''g{{5\sU n8\)uiNer4u'̴KtZ70a-sj1GrLYrpҮhRu<ݻBb_i4Ajmcur +tOTZ=duVBj;shjzMޕE9^)Zs7yjP)e== ФJ"VpGg.eNh"YWBhʋKĪVDR^P9A>F`lX۟~zAmܫz@Vk#ahx]_i~0"n&(_ 9| hFn"]1p_dPհ˗AN;>Ǜ zƮyTa ReP34~~aBep)U(Y+ LBK5X>т?6D.T Z!/qQ`]o-ʪ7o:(@=SܚHSDDbtI])pYϷt|r3)?r }՟YW?:% m)GjXuSW*h<\~+6:SŽV)\UG}qo5$ڠEޠ*QZJ˪}ڌYYTXIf/d+IȪX.)ek#V^?+L!{+vPw*|XV VgW VZjV&=åժJLWhkJ:ƪ'\2AΈ)C޿{P7KK9Odc4z$qq`*~ T3QG]yDdF.3r߅xձ3Ex:a}{ek2v 1$"K%r, g`I69Ѝ-0hvϩe|V>+-Q3 M1O:J0!ySջ "s#]~'xԸDNjiA̋2E}\s?e|֐¤9>Ł.r:3pEuB*7;AdY$kr,^t5k"'I`^RStqI VVDDL{`t^4ʡ+b^],Q7 &A]% _|TkgE‡AMG3TU迡*Ck@i߈û%.`Z{y$cxu,'4 7oU*]罺)s 90 )\t|5׉C`4`us{mp-d@)'ʦ}9EEV9A'% >jr5ŦO]I)ub߻{{`r7;FzK"x:| Gu@V^CP(f-F skZ `ⴣ%@:iY4Ls.8 ф$_2~)e2jO+F+U#N!,Zs'ZOPd <=aSߝCx{ꖄ֯"*-!⾐#{9FU4Y]\jL ((-TJ06LJVTGٿIO6VUqWLM9W 1_}0'M-f  MA~ JS<1{7l˲irb/EVE3Zp0@@E<o dVX:ɩCs ,]2 ~Ax%Os092z|nm[cX :\+S(gY&#K59O;oܩ5:鿤<-k*&6iA͕6?ޅIxN$m~-:|G >:헛 l39=(Ith抻Nt.ٍ7`HT9xA)k(I@]doKM&52Εgn~*uIէxTaL|!%ˈqzSAHҜq&8,u|- '8Ѝ<<,2.[ jg)& -Gvy43_V'P/bIR1iJ}? c/Ka"6h ߶l1\ (džIq{3hxa]~q;b /x8װq'wƱ|{fL0C$RZB^v'F yڗo>y2j_C뢞~B {^I O/(Kq9/s# k|Pkq:5/iFi7; u6$_=W[Ms"q""Lsm0cUvP-3)d[wڪ8QxwMS4)E,:.=?Ǝ]Ǩ-wiڀS>SOxĢnk4 }#2 r"apT (PP@"08R.Fu25ּr^.YR̄`}2- 5ܧWnFm箳-|"솾z 6%&lK}LP5 xз buK ;6^o;i6Hv:F/"d/RS+omX1D1E7&EkD)PqU"& PZoF)v蠇_;Q=I>bF_ŗz,+;pm2q' mns61b djO,)6pp d6\1F[9%$o--TG@XfAۅcIOcsb){!e|Xm QeͷeaS1#xB% mr2gvbYc0A">P5hJw"R~uj䭋bj)$8 vn\@]5rm"-'Bׁ .Ԟ!FA<kxYȊr%̴. ]8q{zlzi3@Mbg(EJ2izoАɮ; !ná0c!'11'X2A%hjya KN2fv&R"$cq0x}׌yw30%ǥQa <.HMl5Կ2x¢\ ‰ }BZU1G6uj/!k4h,Wu܀] $,cXFǎR7킉1..g@D494Pi|A_ =Y=-*םv;WoMw)SRH QtXdτ1m=)_;`M̫ә k)`L&ī)mw9&Xu@7l|_ @# N*v#$ e0q9JV{L<KmXDӬz⼑ϲeM69l.,|X ͐nJ >ˆ8=36@_| 0:Q#Xen6ӦU9\X"Mr#[E2BJLP:! hImE|M\ 6f uCQDD +> }6 ,55 M[gƎ"eV kL-wȰ Ğ#e0xs5((y÷`[^!¹@2 n3nS -]p\(K( bvŷRwCQm썭.&7.!xEV&H~F(UfܼMTAFB%AEtB/ 2UrSEkX,DS M$L+T'G" $!S(D$IRXV(NCh:cchN@0 "آEnKgމPMT&̿BDʅT(L/ E $t"F%tfH,X"PD4I#,™iNN+RK^Xawp2dkO|K"`lXш~"Xۨ|M%IJHԵk39z9|͏J)"*U]]6w5+d鰄HCYf*OXCElVbKjs$fECb7\Ԟ3# E%\n {E^v.k֡i9'CZd%Y(:(FH&.ɶ؊wH 4]͈O25RةIz}y`Cq2,yv'uu.ݒDͱ6Djߙ%*J)I( 㖠 F7FG WITX /C,rR|fm˄.ҲD /3Q݇kx$c0KZ\,x݈; I!X4a!e8SE:sv))VP6C[-I' ĉj߯=L9ң8[*ۤ9ۥN$N58ިHP8mP I}@Ulwʻ A q|^Q@y6AP/N@TSaV❝65Z9M akyQCCaioŖF>,ע[g3оݣܣƾ~Ȝ-?t%b>q%&:2CؗN9 Bt(D}pb}m?xhp7q;S.:lzND7` rEa$5<*!yn>Io4N}&#~ H'>r\uŞK=A{yuClqG |@:]2, m)nwx)m9<)~)w~߄E^ߠp]˻Ur}]p\{ޮ}[}J_wnnj˻n:wFS:];n919k$RD7ڤ<2#sU{pL+ׯs;GUa>VXrkN9\ێMs_w|p]{0c : FZ~z/90 4^^-ׇv-v:SƌJШ2ZU۵6Wx^:aګ2fmC)o mopݣw񨲂uqFwF :v7ٶZ{mVGgvleu÷+[)TVi`}-GրkuyfFrTf.+gw%~(g2FR<{t@4qY%F ͓57mi]Ï1lFBܮLJwt,a J1~cKd\zbZM25LdR<J@ ]~`xܵަւڪ~&bβ,:kͳQ[6&r т!Kp7h7,ֺ`SÚ.oo$y ,oﰸ]#nA\ޮ#@튻[_~΀K01=p_V&ڰ6 g*9zQ ඔ M:U-kѻ]vquoQ7!$jt}=`c7fsoQ?{~oS:4Zկ܎k͙]UW0q5rFr=t-4A O9jA2Ẕ&"nroe >&Pp n|g^iVU5${JT}ǜ3u0tSW˻dVrr7@"xbJG),6sK{Fݹ[V?z "Ƌo}S h< `g:.\jŧ臇])ch >Qe{#kۑħQlaoh~'|WN{S`82|X0I5-iJ927/PDՉr24{L;=QDd*hgU\K>01oMY4ru_`4PgXς,?0M(q ݗH-;MIt۲z7-4V->*';7<{瞏IS1w v!Ou2q},ڕ8 >u84"l)Xףߌ sͺwݜ )<$<7DGǧݛ"yCWW&T<ʠE2߻QMi3:2326>oHCV*ll 79uĔ n_2b>Is*a*Zx@=zĚ&u?\4jҞeHeoھi \.ת#%.0kɣW|]=۝1D=hyD%uI)⣫m`O!:J,Jz^owh4RX튔H9,;'>'>DrZYB5Sӊx8Nm4"ݟxc"zWsUъfCՔ,{fGj{*% UL9P=VλfB}?P 6[VUyxsk߄$8OQcRލWy!"!2Ḱ7I#v/6]݊}Ekn`\ * 7楒"h8^i쾴?ԴW%#\5wPuuh~@'σּoو1~c4PiUW)m/QHft6+YrV>瓍vlIaDIvoCiM6k'oJ@Gz}6k4#,41X;XNmLzh w "=l`{IϛlX셉a?J,pHԎv 6DtlMߏe* u (ntORbn=h8+@)Uݗϩy0%`n20,";kP 6*Z´8|${abSg%Hf DhC` ΋W2̀ԟ9I,LmU':J޲h ~[sgG޼?Yq&4࿒p=PJNҡD=fChY"0+UZQBW)k@G'u%Zu,58Lg˯ =t|}NG;+ ԔZzZ Nʆm8{'x/K|Vna~=Ix+R_V8&aE&FW7mpyRo&Y1[Uw[ -L]`ض%VQ z0),Yl,u֭3Q[BnD_Gӳ b"n\? XJx2PLqL*ȏИv׌gqXxyЯK|J\vܿq:!uP$o ̮dJ.Rlk~r_`g≌pdD[6;T+Ѐ1 +z Wi-~KkBAi1S6Hmh䉃[KRpx~+ME3f6o}mKjmZ;ŧx?Rc4'iIm} nO\u6ރV͌R ?E`١9kc";M,x[jA}Ht8r͹g}4v=h`Ach&ag?h==cz ~ ޝAI2-G=i1{ fmkZ𝞓XfnXZ^Ĭmն<+,AtNIbt0w84Ⱥ8]Rkb{-yIfs4ZJk}lQQ:A`UmׯҫՠQnj8;od{m؄~rimc)U4d蓠.)Tvͪ"/U@zͮSG%L s imvq[;)l՝A#&(lVѧ }f[qp[R[8=qD{T_Li ٳ߿ 2{RfUIg~c`3˖ \C0%vX}w׾E6J@]wHoژTF}IW4d )oc؄\'zq@T oin;Cf[Kaagn.|Tsxҭx`|ׯ^铚mDplOxŊ.ꀥ۷5pejq;eEU6zAޅ@Zsdzn*nmNw0i?6b`9AnRP|@T_IFVـ>ǫu<0DmL؏ZЂn89 ^ag8*-"+6eXHWذk>8.(GՁ*#@: 9qf +ːMMbxQPxM!1{F;88э y;v ^n.Q@6ng,۵ma!=Pczw ݳlh M ^{!=o2qV[ޖ"J1ÅEhvm=Fl<]^1%{`Hpn@c =xW9WU ڟf,v=Wgem@g B 1=!9V0sv[nG O삞#|iq cRխ;5]W:a(U](jɴn.åJPxOSBPy~pH?Btbc6{Zk|1RpDcYe~? ;'Ѹts`ca:0!v1c$H{14%0)(ch|nNm!kp)sSܱgvM#Տ\M9Db'pn'gڔ])P)8<@+ם[|Hxmf ^8_^RoNW>J'Dx Ҵ$kSnw@/nn0XMXH7-$y-F.I)F׾폷9:3ֶ?=ݵPrvy=?'>˔`1H1Q7+fwP-KvRiӭN;zfC-CoӪr::tPl26GZ8o,mbCvr\hUБn[*d'rE?3I8Θ]];O˫!LI;)1;4.iMif rې*CMXuJKmk-r 07YaC:0cVY'Mw-\Cs.iD18o18zҪ:5tf7V˭D-Ω̄ۮ?35}洯=887Mr/rz~mU(ZǔUGg#bggs#b߭Fit/1[G[ CY :ỲEgSW%5Vr+g73]/l?_}H;bf2XO1 [<ФP @5XDTy{C鴎6.K"E==CD˕v/p1D9+Q`QZV6XBHm0x]e̗pQ;'^ ^;Q=I>bF_ŗzKq̺ct0`z}&Hp< U`3têu?x(vRbD"V)Dx H&=а7ߢa/%1}WnAm>r`] 85^esb){aJb,vM˄{L]?*把!iDbY'ɤpDКMylgv}e-sFI1RlZ@<:' ۍ ȠֽS WD]ȓN/LS{~[V<,GdER3Žlc8qVff6P8eq0/ـiɮ; !ná0c!qϘ M4SY%d b]pd_}$>E5I']P:|͈'}?Q"{\1 !zRnѠ: f),p)ذN*û"FȦTfD Z>zu܀] $,cXFǎR7L..g@Dt-V7$ CګuJ{WՙS3]gko!]I:kfsމY0B l |`l  / >{qdFDfdFVUw*3+3ŋ/ō1'Vkoyu82Oa4 l6>U)SR"â~&+LCc0^(blR,gj0Ѱ7E SdSy= Wd5o J{@|4_ ڴDS<sLJ`5EyHդwsn#Q$,j! D:KmX<%BKF?5) _нK |pg202.J ˆz*sF8flpgvH l\X 0#%iNq#X8Peʳ6Nj<0s(ah#4)Sb|]1VFh"/Ω?q$[tzENu.&tS9L\$0)QA9s zT;`s~3Uxu~vRB- MNR{{+=[c12} `ס u$ F<}\ʱ8W %%O}>emz}(Dp.#>X%`za(a~W}[ԋ )ɿFo\`G0\$0I9%P͐դjv˃xzj?GHlC&*,}YY!T,5OFؖV'mvm4LmJJs)DZ9)?8E?~ ҏ,8KX2ah{~!n,U~6AyE6>l i&#񈄗0۾gs@zB!M"Ɖh/Q#ƪ&f>#"\E6]"aX_kZO=?`]fcb\Ql)G4ݲ}ShqnK+n+vOmc[t0_ت;mC3q 3̠93h 3̠93h 3̠93h 3̠93h 3̠kWer'"8vk]=em0ª[fDnD,G'RCR ELҡ~%j}" Ց82VZcU0-q{PٸiDXDCiP9A'w%2 (B%:,Fd`% }$9lH Ys`jIJ!. G9aIIܗ[{d"J˒df#L~1{sb> f')h f!D2RkP|/po:a;,'Q6ZS;VXP~ =̤tWMm%)7eY,XG} 0vl beQOILtP~շLmm Є.Ҫ?EJ13 DY&>0xZY9&C<_B/$˒p'X&¬xB$ ,lqv !ܺ))5HvR6SB$z}{VԃE\ۤ95U-.H+;:ٞ]R% d~6};ueU[o Aa,q xxʅ6EZ'tqI(LTlcS gVfOY8um]n|i ,GAÎs #0}܎39g;=E @(\-3Ri AM3;#r>YD)ݾZ4N&a2t l9}&Kqs\y٩JR{V@vpLٳ#bC;1U._3Q we߾#C<J¥!ѰL@!GhɎ*u5S`Tyt4:C#nºh4ð0W`m-طa( SJY/`ЅqvpD1z-Ae^ TPXLDqH8{pwr ?F%].j#$o"U_ 9ՀGϲOg7 W;7?x4sF8)3'$v]q qgA~k ˳ɋx* XD5?ܦ k|Gk=9Ad5LwGgUMZBB}ŗNPjmRvA_Q2Y ]l؝ hYǠ F'MSB7؁auۃVj,Xt%[刲dB'13.nx-{,]Bځi1@{;@B-g13Y㘭zlNH W{DSnOx~ 67&@E<57-jEPKR:Te W-nbFҖ!_Fu }ȷ1Lhx Z#Ao+l>EDQXPGoscu&(œDw PnXQA(G7r3Uʥ1" @p(Or ݃Y; r(01Ð=4qv0 fp3- m!1?~{jB 9#␯tV0 )bؼ,A8嚟D#wC#J\CL?DCA7'a:j8M'sUׇmШ *:4,$*&2G6E{@{~`gvV9XآXgC3S_'+2՟340mHL\Fצ2Iǯ6\2Sdagq HėC*E85 =Xp1'\**~0>'8=eK'̧`&0AOVN;9x=/E%Juǿ'<ԍ\W׷*[vi(rAlVC.(pBV|𡰉,`O@D|Qk8[j34E0/x7~FET1jX}j!MjWpfзCez ~@>tk=`+4b:xf5ԁWAoۗ.I- (!|z4/˭ x.&1\ w(5IW|UZ0,RaiUY2 7P:.A8j nB]XߨD\X Sa.~SU[ѫ#P(G{ֈ ?V+8rtUq=bl?;cwݹp7UJ7RƖ$sb~>'3!D' BMhʏXԈYTcu*q׽v5AD4Z7%H*�AHY], 8j}K-b|V+NLCjOwg Nr آn3c`rf i{~JdnCGaJ!YT3I]WqkrW;~5PuPw#ZoռҋfAm=9j?[C1q?Z;i翨vKkr}.gQ4Xw.54 w+,caȋ9ޞQz#5|o7#VA~;4,t0U|ZsI7_)?kV/؍ڑIGjBjӃ>DQzVN&*''.N$Y:U9"sf1Q3B]帧sk +O7FAF)ץy?+Az U,J%#^JfˎL4^KAVl,4ތg"ЄEc9;)RW,Mʢ|O҆5)H}ݙܯ[h.ꇤovࣿ;+XP9[nG0'f;}0iu%Cvm=>L2k3IK昵K c1P vn&MCR#z+Ԣ~A)b}Y!Mc٫2u2s3mx(QG'€?v>UcS=6,23H. R 7S?\h#\ 4Bc:L<5h cbavY l5| TA~oBg<۷Xnpq{lb:́ˇm}( `uplcbO1jQ9Tώ|8Fyx`B@ϽH0r3!dc

`4Ņǹ#r g,<+B78*&5WL[3-XdLF26JnIeK ;).L ^o?e- Hou%X?bIe8~I3K%`~x_iPBEU*% VDpͻ4"5y\X#_ONăWVɩ5UijSkwo@`q&jǻL0k> (N3splQ&WF+~WqW<\Tgg.ixfN ~`ݚq^?0rjOƝU0D?5)G8y2 c;&;c^%]gu-h7 #>`vivoq?o+HDhx})#c%RZKܺ3-&FfY^[{C9ג(P|5RAw=ܚo~ %S~dznOm<| s J aKz H/-Vڜu;:4ZƲwF{3X\7QED/I3괍"Yc_-ǜPnv凒Y-gcO>O>O~ϾG>,y#z yrz<܉v#,8lEaZj4g Z2Uz)m vyBMmĂ.Ѯ(TBkO ʠ;xeRbz:Cz`b C7G#]9h toX &5vӶl}ӃWE6 {; IiR z BsX#t)\ccp"rTo?uôޡ3VMxzTE$w}0&k !s/8J i߭ M`xŜ0cyCuqyF0WU:# ,qvhT@^LZPmnدɦN 7`az[9-}o"&^ ׋dދ?{"Řk^!xwxStL?5$QXSdqZ=&8p/{9CΠ0Ql-Vi>^{cW&,'9j-rtWgQb<7ybT If4N!n:{;B~EL8\(r[Sۃ2ȉ\'^aG_*  D^ s ݐzl|ݡpQM6O*CAޙLJy+.KZE>$⮵$mX_alwhnݚ`=]GX sZN S_"'6.w?Y}5bYq'L|Ĕ. 8:o#z~dנF1;r5->6kryaG?_dpUzlJNE,S ep@^Ԧ-8|p PoERk O{AU*HBj)(F%t;4E5, e0n?3uPIRd@9E@ 02*Q$K!yS3- d0lc"N$FCQ`c=#w)X&ҎLddB!*ǻc|H|WKV/xfmn~i´bSEGȂ7j0{5nS&z|y*B"nɵ6!*ʕG&_|my+ߣߥK;h&D:Tl2P[以TYC :z>Pqh^׺ҩi{LSNTk^k-_I4,aNd3m`IMjeg(  ,:7bC۔p(SB FI$l@a#ah5+7 WfSi'Jw*wh˞ ,W TdKuaNYDǍ~ 6~AIp8nmdN⽡Yα|_WP65o2`[,cFN 2%^qX@Lح2CNw]{;'B$P|8n+֜Uk AtP/{4lŨ|RZNg"7mISy:_'hʽFlg_ m 0 thbJ1fnb:{cT;O d*v6mkײdsLI=GdA5Pזk낤0$I)&I,6"CUݰC\i4cyxV c=`Ϩ1%*6sVoV.7J*,yĦdk /S%&%Ie3$2Y5u@ ɚpYj~Μw,/xǯdMZW7'gLɦ2v >yLV):A+dx.Vo\=_Qb,tzѪЭGMc0sj/ݡz WD~PVha8#+X3gzOZyŎωI:i~^7߿lKh^[ѰmƏھ`Lj ǠƼ)rꅼAk\MD(f8zu!wӭĥV 8?u4,5stxުr"bnTvYc{_'s';A-M^Ջ Sy *J21WG> j^f7G(校oЃ_#6B:A)^Z$ Xg^v1^nv$ fڝGUͩ6{pRA\ xyiBgd9tn'kR~}pڙA0 cDjrmUDC8t XfA5…+W`,7Ep*'oTiEլS\3?WDcp|w@M. kgًc47^ R v@cw1J/lz6G#Y4VX,|Ck`h cz5}O[mv6~ *ZYX浀4il3*&\b}aTAD^XE~8b-bL|Z0艋I͸&ș!,' ʈ䋬|%@@ZYl:I eX&swG{pVЃX%4z'v'!p.| -WAoۏOvocQW!9W+1ʺ 1bvaZ85,E?J?C)tp7+hnпtCAЧ+nm#kTSnzmQ&VAv d=gǨ<]mXd>?I=ۃAAkڨC:rG1tvh~c^UoN|W$DMxw w[hX<l RO_A"GuBT +Suhx݅?+("|]qDq=mD~7aD']H# V: ";&KMlI(~-G@FUמ voبX*;CG.Z^9bJ1cF.옑 =H.\Y"^qy1iL^rabQQeWkHXv@gwuO_+2?v(̔6y/o \8@yS- }Bo.o( Z8z f:UuAk٠J˜YkyX2g'W?89 T~j i+0O @Yb3~&0a088΀5EUHh؆B+!:vJRJ{$Xآ9 `"ەN ePsfÑ|Mol`kBr|9F@n(WzͯWi[B*T:.2,ɄM%F*2$s/ L*+tev[@LͲL* K0`nF<>M1CԒ*AdoW!JcC+^EnIMXYh֗GՌk`hƸ!ӡrDVXk.BLdIzTmzI6A{Uom;Un,3GvV=]+^50چ2 >-JRBTo2mkX ΁ҎiEi{JL@8*9*YSMd>ZAL8e_*yQ2%(*={T+HDOh HЉpQNҖ?+mH=J\TAߠbA?@Bj ?D>#=-Q* 6$@|?N_z;(^2@6\A @RN5x6 ?cM v{aUv-Bw-~pss#^h?\>>J;N]%p' ~GxOGiChr;‡*1mLDf#tpN*($R'^bx?؅ѠlM#hrK+ǧѠ@u4n_JR۸*e9UhGTNZ)W+7rl%MUDWhy0Qi븙t-aZX\:nE/}M~)nQP [7ÖK`ǵy5T 섴Zd^(~̪,vxlN fpvwDma iMPO;65: G=Cmsl7dݶ/71FmwN@,b:c2׽Eo(tG<i Bn%ΘBoN6P$LZG|⸺R"°_FК$H,\" r9.`oD兤nٓSo(9Qy*`rj4O{B4a=F%CX%&)>,KKnTj/Y]m+!حۛg*,5A0 P]jrwS uQE#&]& HH3 hX8zixXwG~eNaU|\Sƛ#U1tbnd=-|q?c9Q8k'*Զ+ XdA9a_ L<0ԋ5|s;h^F3S) Ρlmj$IfUe,pL W] R0 c?TAl0v'e)%s'.5SX>+ Q-rw;uݢ iBCȒb1[Ya#Etnmon]ُ0AGu`;ƁضXjOqt z﷎*W%:}J^s1CE]WX$ӄ Vm;Nҏ@fWb9ԦTt~+ji˺>W!.r0W|૾b/;JۤbTӿEXg^\d[FƔLg]|o*iNё򓻓_͑W}x?$m,(c(0o< N"ݥ|ڕ[BNQr뤈mrD>1"dOмZ%$Ǐv-RYP)&#YͲO"Lg̩1*ќ~[V &`tƜK8e#2:} y Mt0^N \z-n٪ "~V"ry!OQr?kߣKEZY>Z lT%PR 7>(oux\iȟV l3D*(mq۬҂lmsEdb_U͆E3n6yPuwCq( /v8ժҭhgA(=<& mW0< 2FbIKȁƨիRDi36:ƛTQBj FWѦZ9{Paw Nx';au栝ɁI&qLtCؕsb`.BOT E1: ԛii E x;KN>@+0#|B3+|Τ;1qھƣo[@\]6OIȢ[G*b /PnSr ӕڣAY+]̍Ơ=lZf:LYpSɍ ^Y~J˘ˠnIR*%|W2$. l/eҀi2aD,S^:쌁qV&o[qu@]-T.;ג,%KD)K*FunfyމyW3{sqO]:taL{Q\lE&aռ"׈7zfj4GZŨW#L,Vz'<o r,3E❚ԟ,mXfZDOF a;ZDMKuogͦ$3Q~!j)@Vo1sgyPX UnweX؀3,Aa;e V? zpeˏZ_1Rg.N9?XxA !ؙ= L`/tp}{1|CMK 43G&Q~`H}9x/iajPA?'93lewz"%@D -*Q X5>?+3uKU,޸%G6q#4*X&yʙψuXskĻykěch&e.5 7h!fQ5"4acyWHu7f-~-Z~4}CjU/$Jt{G& tlp D;KxԻJlR hW`+Ptų5Pi)КipMß)=b-kَ~jjn*E܆sON44X(دͤ)jNޞ|IO|o7mYzTnlX,zp*{{K|/a5V9JNj-jk] 0#n`ZA*h' 5#RUKn+"XF V  Ad -94dc I,7 fe>bimhh~pf<:Vui^nNbIU1{U A?Ao:1$tF,v6Y4+ 'm:(x&+Mk@\<~¶ ԡ ,9\ dLP)nah︲$P(Hߓ`J;>Wb/?~&~:8%)PHQ|]wK%FB˄-- '3ˌ[oR(목lx/ԽDaEq EgƋ{yf%vMHl;ҫ2ޣjzW5K8wS$e#Yc3䊱IYtm L^2#D9VbœL?#rRx"+h~OBz:FAP ??ݶ2Xt}_*n]EXGxU6CD ڸvgt÷uNc ֧Lٺn<_&[<@XK)fg]11?76fiۘE |wғ̖>7,rn; A$!ȡU1F۱QVy.\bdVce-!w}  U l.BmAɜFuC>ݖٛq[gߨ>ߖٛo[gXķ+Ez?8ԲE(Uo^2霞Xf=yᲆ<}&f5J/D߱[gfiTάAMˋ5vZD>Z/?_VϦՆ8?nE*I[Z_0㟰rbjVMy^nIb hU}~D:z޸I%|?؜OLL'Hc\|խ9*gx2 `w [amߪGޠ3O~I B~'%xS]RίZ6C~4u}$`+A{(^xK'LJ)|~K?J ?_ݫ=4~Z}htjgKAM V3Lޝ"B{@CjYA9G&bHw)@KXFlܖá2GIJyI È/"Q0\;ӥaOU4'NxPg5 2HlDzWP՗~4KnHbq*?5nytopZ{UgbSm]2 1mxQw{ -Sح2u; h ׏лԏ\M\(˭^_ɩT$kWG %\Xq >š p08K`xNS%Ӵ{9ƴG^paˠZjF=4ԚOM|o/EP?GnEx%R$S[hf+SOjt-UCGLDBAhAuUGHku PA 6ڨT&s?oD_5wfqM%+61+Of[GO'Hl7l^ ˾Kؗk`4)C ră:ԇNP>mX u@X&A[Ro((vާqa00Id4 24ܼypNӺ|l]C귛wԻRmZ3[0߻iu96Ɍ(d#ƗKtwӁ!ۣ608YT0-X f~r qiQi0ph9*ZucývP?Xi& >uxȩqxȧL>=I=nOa/J#inkmPy&3:7Ogugo>0f;#MׇfuZ 'ojs79k,Gq1ۗiWhr*ݡ;h7{4S, ѷyPf}lQY^۬Jm= *8>] J(3B̥@ll*;8٭)$=^tL cb>c`A̱<Xy@Mҫ»׬h0}]@Q* c8d%yS1t9rhP Eds(OQ?B|f"%¼:4a)5Dup/23$I^_ɛTIL3b) 2Q2Fj*DxDZAcE䦈<=QL (*(09U94IXͅ0\VT2>*[:* MjЎL-nt帡+X6m#e(Nd.~t2yod_%(YylVIds0ޡDeL, yk[5u5kҤbYw%e[:Hǽ+قLFyRuY7[=]^ <[ӿwA𱧞/~~HYd6Mm«:f("14>"T4Dgq6+닺Eu^rλؗt̓l>é] *2XK֓A'Rǀ4<}&˽:]ثأx:nT wda:HʛLUݤ8 W4V'//%xn 2'3 կ+ՉZr).*L֥u[Q{ f/;3vwDazoqWj^kl~әXgB>nЬdr~C!_:WXD)|E+45fY1IEZ!|WH Cn5>v᝛Η}F90~ll?JHBv#X@F_!{Mzm'ak9n0-&{$"V7GZ$]Zr_F ׁWaE4Z >HLC2"W|GvDyQeM"@&!ꏆ7`d I?I=Fz[-C`m%1J>Œs?*OFt恂RzTO ?6 G{&{[Jԁc'2 ;F &Z͊Dvg&Szퟔ^}%<6.E],dO)ksP6Ca@Xq.Ҏ1 Rvs4xm7Iz.'(I!n yBq ZL [ $B2-?NmK9x\r%en1e 2* AoFn9m*`IB[,;@ZSAjDY 90?ʉ۳P΢RCtd7YuQ$wYg a{ƙy;On*";@6E>k \f%OBlhueUͻr;pgk7Z9f:U]gT%E&E,]&XO],aΚC!k,'~wi^Wg5b^MO8sGUmU0f1mlWͮ-y@*3ȉR"?&\Ծh&%~Y\#7kgT/n(9i $J Ȩ qpNTP(icժt4P&HF/@woÉb] LC"4KbNMD ԰ww<8|QK6U4. e GEM ɑb9C[G.iP;?aRkЙiqd|ZßnF=֮$5Zer}vfIK>t>Ǖߖq\zEC|B9j:&Lפ䶻^6@Ht"~9?aVB5h4v 60+%2foٳO=~9<[gU3gǯ?^_돜<3ǟ=0^g<ǯrqާ4=+_p<{i3='sYϱKx)4P DɄTy{ke|uh> {""S9 6x4# o{H p=荶Is̽a4۽(wmvS kl1(}ӽ4xA;wZ#t0hh?i_6{@m<!Eb pاp0vocC"OȀzে nz#%q~lApF$$z*83|-= =ܝ6G${;$QapB0q¨ߢa-@:6ru08疓tv,,7He!cBǬd!Vc$1"S/΂ih.L,UYJc\&7JdSP;)Gs+#)绤?zQ-І evCdZº}V# qoՔdjE"1D^#l% "3{yoмEjp^edgײҾEM/"Q8I[`di6M@M~tsuάt 8;H]^KѬc4;% 7"L'܏[Gpef[5&YR kU 'A 9qfpVmU]ZfrӃ[!,*+k^ui~ԅĻru%UHܲq:PNf)ޜIc]BqhFC$Q۔M&-5?m=.9E.\ $!sqxxٴեBJޕoUwNTklx;Vsk練k/{OS\s'ordXAqiY>-9tg:xx+$닳|ʾP@HHȔ 8ǃ& nÝ0 J-֣Cb#FsZ3%Lm8doGQ/^]ۙ,ekd{k(MmOZ= ̤ΞRo-5\pX~W ֟  P~nm"wd-I(GC;Ea}`:kd][ ߯Lɋ!TRn/Hdva4'K[l h͟9$ifTh&EqUOKKA^zk&]EHc.$SK@Fg^44Q kYh8YB#|wcm J䅑>06'R@:o뺵M;-~(-M2vAqF\onJ(¼d O{5وd(h\z&zyK[esdퟷ= R}e[s6gK^^JJH`E)6A4+٦bJ픺f'׋ISq-!D,eK 5g:15>ZzU\ N}U6[aBxv>-9s/Z*J^/@[n@cRR5dtV$`a)tG 86,)p 6MgbKk].s{ɾpo+?5.{*Y+&Kn@cʊ6buej5-||n944kqy5jga9%"Hh(XXsq,pqL\y,k [$ޗ~A&㸨?d+za}?EhHU|7;݇D~H_,j_}T%jsG&%I7it4jB;)_i@;+5JX5ŭcX20E u;b5 ӣQO=tTw"Ԍ4hh+sNG~As]ֻp@h:'8;%jS6= wkp#jW> !aD4DA{[NQ9^r!9@$ V5|Ɖv9$ *eVɸ]Ur4UN ­m xI$;&(3GvkV(ZTcȘvo+ldP$C2{([5yaZv״KkQ;gokvXo1 i,)aȼY`IWvoujY;/߳ىb&/Q䔞es=24gpړ2Ce gwZuLf3k"Dh89ZZk<Gz%AyZք yH"R/(X es.cffȩF}#:}hRu݉t̓ 3_)-zfMLяKZՅٸytE#jz>A3X]0,h[e,R/6gD)F4%lK.E!;SRJ-A &eYt&h:84M_K[Fd8S0,' oE`UӼǸڗo2U m-4! ژh㷩Aȕp"yLdH.hm(ZqC?1ylfb=[#]E=awvy˓8dPU:*3y\3GJ璲p)H4%/%qτi ^ ?775L!5V"g"eun*ommҪr tea} t$v-2dkYsSx#8lq\Ǧpv0`rZJ_\IrN5 f (8Y͚1ΡQ|NOmߗ[jHb!-K{u7a0r&=;a,@Jb S <*Ȥvw@Wvo;{IL1E`˩,PMh?mn`FvLYE=e3;zF:Mf%g{&a9}OiyṑrEf!EL*@Ic+GKD Z7)KY<\z*Sy_^}l^D>Dp;b nN$~o۽v+'7 -'7`!`p&Xa ͅ6w>4蕏O:|Ac'6O7ʒ(0 aX zd0\ VT*[b(MOYd`ȉ,Z{Xrg\<,L?M7pFN`2ōᅵv&gRܰąK;nd9}CYav{^ruED5YWͱ-d*6SXt %ae . uvePP{qOI`)2֝ZNwU&i=u>?HOfW$.FH6H1N8Dbq%_nT%8f5qEPOȰ:edX}ZD$JFQ5 9C-}&Xpii~T]K^yo1KXv[S:36 4 ۙ'9`:+dIOK'[0$If lE$INMeL <O\1w2yb X@׭4v]dq;lvRҿKe#Xcի%X"W6~7ϋӳD5pN[g!U2.E>?k{ m&Ⱳl,`hf{ . 6viKAxG B 4~ӈ1eK6!XX"8(NmTz 2– h+Y6]SSyDDe/:Ou$9BsY4giVJ<h#jCEjH$\rz2-㎎eHAOPIeE}GBX&Fl/bEXvڰ(,QosHxm>X:h>^ƽE$s Q;A[^OZ+0fijb/HXI\΋+,ϖud4ł䦰 2cHEA)O+ŭaRֱ7K)Tp'ތax@A,p|1:L>@~^tEh\P tsE1hF%H^y|$ލƌ˱%ciq&Vq+C`"^ΖնEm7ij&aEc~@>+>q^l`A0],xG;ikۨAx܊"֡0 }DR/G] Y졿8 L+'5f0CBwXW% # CxLkXڕ-k <47x(,ZMYW9,Slfb ZrȢ&,klsvPMYg0T%p 1o9;m״C 25ܭPݴ:n2E#K1a,SAuJNdpPY)M3pdV,HF=B7CmXtM6h׆?#254>7-{RKkѩZ>r:i~N2wԯs[SO]`[;M[v@0 p~7VjlBPQM59$6 vU},cq:Nw˂;f=)vaTNY`(Tҏ\OIhViBu1q 1-Sv ҁ [~ƭA#]"21ڄkC77Ξ?6fDC8/#OZ4 ir՘,7ӿDK$uԘ,~-)Tp2EMlR=iɼJe:E3f0EeNnJ)+HeK,rݪHInSl)L=[ exR\=̹8'Lbv0^qNqÌ~b{ ýtY7, 9N#e ER{=P B(cڄ2|}Y$4%IEV 5YTO}n/zQ,zŢ2!ـU9 ȳO5ñ c2hs 6&.vrC۴H yc B,|$P8a&H:y\c\5K"7Ɲf=Mj˷3R6u~u=wNXJ.2`ŚK iok6Ǝm2=: 0q7ٞ51Z:D+ 7 ͺ/ب}cE.gmy\X#I<^fsj"&_R3egM'ktV [?xU-ox+ afrbyr4TcYh!ll{$z \ pؽ,~x7N ŁUr+QVc5Z zlQ ;ҷW}RjmojFL Ĥh[-L+o[ LKS/g6`qAdV/x^[z;EE+~p$}+e e4 l7Y.gmHT࠮$|E! q)4Ib4M¶EU_rcfbM)"q$OḺ/P|w:v}k:ۼQ8_q^w+vуLí('YQaJ')F+[0 op> Fw@Z # DE5R@2u2CYDa8RDIպ~&W 2ߦ,(16>虪?_TA İO .Y_R 9M^oBcz)ZRf/ |td pP'?,HbP\ߺD *SAπ#$@x%oJPq9 ȧqpcidfKbp-L65UI~ teEXMO嶸Iӻ{ 3'mNi2J8K:GLbSwK/ߥ UEAtyl>Cwl覰\ﻧݓ칾U{Nւ\cL7Kuͱ*0ҿD[Fl;:^ߣ;}S-k'eL7E* MAQK/֌9S Ɠ$J$ťdzxCvWd1SM'~B?A ;㭞@X}CIɗk[tiF[2Jvøج"="*0dX,c3kW{JŠ4C])Sg:B?&3\8jpmW=h0?jY]f3òsn7dSYV--8C<`̟YUj)fnvtsײVrD:ș9.Eޮ`tUbW70|X1 : `FCy$Έrߎy Q1ĖbV:Db9Z?mڶHT*v_"BA7K3+5vc[[qRqK>Eû.;n-[+ۨ's ON7uwQŎxo] 2ZP:mIL7\ķ+b  k}N k"r |Q !eNazĚ |n[>hi0*?Y_LxAPq:"AuM.UV1 uD'mD[I$lduIJ FY,*(,/"_}LBeNRtjڕi-3Mwu&TЊ{/cӓ,e=*EgiR%WJ\d fBtF3(VDX8mݭuM4v5ޢOdEԿV1hU4+tA=i|8`whvoj[y[;o.d ǕRVRT g`UZd+TϺk*dog[ː+>'W.#@dR+IRw.‰]`Q``InUi}>Bf}DM\x($aML/$PЗe C].S8Tyܚ 7 jtrzE$SWWr2L5]s9?#lX_IIiYj")evS: 2CW.2'0\K:#wN='66pac[rL\rοx8Ldy8,W%{!m_&|O7Iљ%bYJbd7WLsG74Aq*W%\Uw`J|8BZ9/^Z'WDzܐgd\y,ILxΖ-ܐ+|AxF,7SDp,hˆlU\r#zGI9CxP.f-CvηmXqHK3K*e(HLE;1_% P슉a S y u[_'`]oy-7Tr#I^j^WP xR1Y+$Tᩙs_etd=/f~B$oH#-y(6qem| wv ~̭ %v+ehDi2^ݳKc$TY\3#ޙ ~&s:` `#Ɍ#,X&Ys^ *!puDWdS ύi f2{ކH]'~K2Wڱh";XSF B+lpoLdߦPY6f^'(w_}Z}LJYL>zf,8J ˜بNl[,4sD6ZhF{DYE]ɕ v2$0)^cT HzgtߌLG"=wcm>"׵|󩌻O+3[\/c?kƭQ׃2;ʂEY}I0ݢ;IT_PvgMJF*?!G.B.4,Dˋ7H7)UH| uFjfw tk]ѵlc:Jj' p o*c; *} `vR'׈^kJ?VlPTGJ}gG'\>2]R'/x `ٮ]tQdҢ" ?I>4HM&|ܫnbV񹚑S@c'#FkYMF˭I]k%1Ζ[oذ"i+pFW {4[~j߮ ο[;!W@6eLg4o+t:y]%:ZB91%Yam!m7" Bi"t@lvhQ4{>sȿ0w-L Jnovo> q`C>l\!!`HmD@؉xϨWi͞1(܍ݦO~؍H ~ aځ aХ0ԈpvG},6 -1 c"=%1 *Cp E;Ih~Qy-K0Yc IЕN>Ҍ;'[G6?;m;0}z  },o66v=o ?7qV~},9yäVM/tZs ^~1|2m#.~hǕGI3l {H-p ?L {^ _0[|>ن68-Lw (gBIIgS4SJQbBylbO_ze|&.՚;P|4Nvˠ`0֘s`D^cneKJꢱgCK :AVV&AKݓM^2z=/ǵ?Qi,;LǷjL;6݋ 1 ;Kf-BtՑ"{=d9)ـI|g:𫁝Ѝ  u BoTX4&֐KdF2;{YO;I5y&u ﯵɥPIWz_V*LG.KvyɜvxN-H<=k9ֽIX1`%k:Z:5iKN"YnC#5m~:ͬOF&{6㱝g ձbtA/Irv*ni,HЦxLM.Ly]=  О Fz^HH&^o1%{(lxi41c%;^GA~v0>boצ?~@ pf:k!{rؑEAD*qhe^9Π52;D/;,}89DO9a.PVPuWOk G"D Sr<^r1gںKq]pѥjV6< =[djL#YܓdxۯhVv OZphڢJ,⊡m)lנ!j|gԱJNņBeP澑% 0sCUSiq\Ab:EƝYC@ G3XEJAԨra] '8wZլt.RN6.l)^`ѩ#sd]XKn}ouqTiYysj3ٹ:`3Om~Um#+{őPIS =cYY}ܛdD XY/cv-q"7Q{Xm :U] A *Et5]ݶa?;d>_~%وX)$mbRQ>̮hӧꅳVYK`?\ra H˴1&e{'iFu@)9x.Lj.(s_Z%Ajf j#݈Q2||aE.6M'0 q5oë aNX6D79+1 ,T򚒜܌cxr#~l9 ;M:_ `mKsz6:,\Q/7A?@&9 nŇQЀJ?Sp>* MrE=vf}WaK 4?ǞvP ]>f\*7W7^VW-*,ڪН>:NU*q8`k+$Wǡ[ǡ_v ///+/TjFE{r_hM8wz$Q;ZyZ^66k"*eK:"m+` u[i4K;qdXnxc^í-÷D'0 ، ™|yB^ @Gޟ-,vt̍*).|dk>s59p~{.\]RVtSM 評 v=ugYyd4&qbIN~Ѻuѿ1&N/1_RHx p`<$ 9'ŗŗ^D> l!]rj{L?Ck$S17~ӱRo=/X't'ݭ;jJ_mެFio +xhxȱt9 .h+VЍv;Q$kx4kH_G\$Z.^uV(8+4k@b譸5.Ot̽nHY̦#)Jf[9d'0CuI #r= %_nRc'|$js <#OoMx+]YME\nܳK[}Z@-' =U !#DpzfDܳsfO kƄ|td0X܄NԌW9yzɭ9kdUGr,p cIߏ=(2 #@Œjp-(75{AJhCXogItF$rxLy0 K1` :}zC~,ft+8 (/sLg #= XjQAcZL5_1eGgZ|L稼Ř(RK-dViLm 2>Shג[[YHۓ743MkZt\[/=ŋqaqYpfeYfefÙ:l83pf6 pD4}rw)PBc7Kdow%v$/.Eev͗h*<+ݒҦ繩0ˡrڄ xOz"=`eApCZ\̋Z6T z~ N^%{{oQ,C-'.wHi6 18{*^aҐHǛX2`AxpOhP/x 4 iXHPEJJ5E 7-ٻCC~$r0~]hj+ַo[B;'QbWs13.?3.?MWJi)k;7X<^#Ǵ+ٿd%OBt*5f\އFS Df2†EEFI0VXJŸļg˭X/(&/H+pmž1 ޏ&v7` :ś4ij)] ;P0CոfãEM lXt[VV؉F{%4s kOV?۞NbJ8O jɎTGS?Uz PMϛ@1 ohmz:rr K"@`(zѲAϰH_rJ%?$g/Z$;^kɜCCci# ,u3$Zl+.if f_yc P9uS#Ёwy-Mܙv+ƹx\HIJhpauCRB#O$)3p>`f I68iIQ U.S4I,_8f,UNՀjX eDr{莒GBoZDS ` RG¢]D= CEsR3d"Ɇk\2D{mOMc9Od;%D2" u'3X'ڴ5Iw92ՅfNIOSJ-y!GnPڦ{ N(.w+ɘK8r-gc65e7-Q0/9"OÒ̀ò70-Wٶٶ,i[\l JZ%q)ϰG{ϒ*.VtsAUm@@9k2\sߛ*SJLpʖ5ZW¼P^N0?3l3,H 펥TZI~XuC~d J"2S?ʩIm[^T?2b洬d|NT%~6b\'a^ܣb,L[V 2 o.GJ<{ j&F$Dc{gk3{Mj,-N$w(KÆ#Zcl w'Cr M4PÊ9#uJכCYZkOwZ v 9gT̟dwJMWI^Knv[^ԁ%f_1JT4MO*a:,P !(!5`WC(CFFCGU TJ (d<5i~]n2y׌>NMoK󺨼~vtk7ء U#ZY8P7~7nϔ[XKX?<Ӫx"g셹= p%XoX4}dJr 3?z1믗:B9^IVA)`4G]tW?Y}ίn֯>|^&%dTG:ysKv]P6Yj@ؼV2%ljHxP`nEAaotapl\o['Yfɩ[#Sw$/X%.h.ظz:YY1@74(7KQ$lb>p:g?LHs&U1RጷPeh'6@À #.5;u([~v~ hkPLs}+=:XJMQ||6ߥ:{kB.VyiQ@xsv- BGpI9f6'\OGQ pZ`a>pddjǤ3JmBS"}I$qU܍Ǧ1jG# ]\l0ȋĐr~1+"20I6&:ccZ֭mI.YҿYҿYҿRҿ oGH ZUy 8Z~8bT)JZ@, j-/*E"/8=Ʌ˅ wfgn.,F m!;[-Vw}`^}G6Vu 7d%}'kT僗FaJj0#EQ#ev9Y:VHJv`|:㦢؀WFZwZ&F3yJ{`N0ĎkI+#宺 x?p#`--kJ]/\JQllx!eQBm|n]ѢieT[/Wvp0B/ׄf#m㿪pro\KR.}!8^z6MȞ7AODgsj3KA[RH}!̽'M !οI;fg ʤB59}qCM+Ҙ ~~_gVk/!,]nֲjjP-:ۊlH}b虯~>/~<_%<ň ׻?yk&ܥM֔8%Ƣ?j&+`VQZeam2|rwveUYuʎ a6q6??r n\Pbs"͘e EƘm7팕JT8mjMMީvaYLfR 8"ƺkț*8y^nh`p1@nhOaJ·Cofq>G>SwEJqp,SMV46Ye W7&*ϬIi,:f<0n5U^4)$1q7%|X[? kGѠ?yD^7jd8vQa&Qa0fR{#q==ޒDU9g`4vfE.Y~/A]8vҿÌvE uv J7Ǯ>3/v1w-f$6Cscs{#oyމJLĔg֡ yP(c{v59e֒ eKOHn}u+xNϹ [XuzK[ZcU D۽a"\ p^ J[;5"f?qIXM-bpBXigN dYu+u;QqU.Κ J"0Sx+ U//)l{Q3 {VBTŦN8D$fojۇɣUͱۙ}%w9A$9./US~<&ںs iӏސ0E83FVO0@!ι9 EEZ77\GE$)n&|¤1dA1kyhTLiAq! Zh uK h`]뫩UV#< Gr=`~vW6v<<Ͽq(Zk>LhT쏗loGe!;^m537;^5ކl0(+cUQ)F4-sZM:ta m־|Ka'KŚwLpr`ŞxUb+Ku8j.lJ/<ӤD4W:{H-m}Uj2. z.YXY!3t|?}9Bzብ(NO- ZW^p=D<)9d@DKV(I%@6.\beSH/5?i=?_3x@PjL8SˀҺ7jxk+;/+ T#CxpiXWo3-m +'$L5T:=Ȣg4IwNf`mH[ RHQuJzxNxv8dr1@l$X8Gc-0*?7ެAO_.W?ln@W9*}oPO9 l=\̾i%zg^AyI&F@Gq@`VU'iƐ:2JtL#O+is d'<)spEISNͲP>h[aI/,Eؖ 20dp6ʃ `0),5ioh_vN??_g?pL+igJ=QH(B+>)FV͑iّlILi6}x߆}׺0ӿP77h[kqGԩ2Np'?FP|+%rGtݧ20yg {ovwcmo_C ' l iU[A kpGOf?Ae6nʕj;l OASpm)GyS՘Vv94f3"Cם9%,D~nM- +QitgRŞ* ?iO(V^yT8p7`ċOxхŕ: w]szF0di.s4G^pi0`uu@XS"u@^Ve6CϠm4^^PC!m@r@06ǽ@ȭЁg6%]n " :Jكؤ0JI䖛DI/K0. c7Az?8?Vq(] "+#G`<|23tADڿ=ݛCG{Fɡ6S 왲| ^[QmD~F1D_z׌O^酭J-ߠ_T;?oG .! 201rgcP91y̮ ,FQPsoGmZ^Q߭ jBU'kO@&fЃ~jBy oBdDPemZExę1GWQG`{JdD W֟OV?W_t.%υhXkVn, M~&ˌF&^۔dtPmLP=ⷄYҏ ;;M@XsO+4A*b l7By 8 k;M*2'I2d|ݜKZRVm?o`AIӏ`0ܣ|P{)=~#ul:ΡꈠB-كܗ\j$i21[G" 41)sY6vv=bhjK GDNT 'n1ȅB$I6iK`$ɓ8`02A¦2EA$s/&| 0YҁcbT^{5@u0+ l; AX&^NRiOiA[< P )u+e͹:QY|Nҙqc(kKv΍A3YX\ 7cƨ0Dl||i*pK_A2j{pk{X+7L— 0 #/ ÜՅ+TO֚J׍hKM0"0;,*TxrJ@.SvwnLOk]^0lç} C7iASh"bJFslFswP~̻9,p#V\ -nk~NE`se 8K9f!^{@S%VyIeXs6ZQ] `BKBx]F?ثHBWTi%&.2@BB 9O}*+BPG(!Ŗmc-r(2Zsp});_ϧbu[&XcK ;ʏF4j扻\_odв_1/mky?{1BΘ 4|]6 XTOF˷ >` 3~%2!T _!BȇOɸf0m-MB3b"{&!gx Hx[*L{qg6 F,_}vs6TzH~קOZdxܺT %KJ4r( J]`Ϗs$ \^, s'8b^K^WY.Y3+5uV^x!o,C,Cތgffnp<^藑^ Mj0U *~ŬjZ|32ي1ӴO!x:nuhvaqYpfeYfefÙ:l83pf6 pcJ$h- G9z).l0#)hO&p{8Y0wxsLY(n)M8M6"y ܡzB2`j2!K)t৕OnL!Զ2"y+XT2?_0d*r'ch{H3.+|V/I_L+<QȱI]AT<6 9.^k d`~4`{AS)Voe\ ~( a*`۳\5ҽq*X uܨ16?:tnܾ.(J^mA+꣠5㮬Sk[5肩Q)wtF]NCȅ kd}GVohÝP/+$_ÿB$͡ژ^[[#~Y$ꀈF=w@: m?+w -͋|+ktwB|,YK6) )I,`MY5l*Q$^"5V&b$qBcdR^x&U7 ݂J:Raa77 axdTIҔ@Im}D./{SK&B6' pF^ZbuI)^᥵"6>pKܮQAb :5DWEUƢf]]o{5;DKzYE^)o F^4w%'OMy{T^ʯ%H㼐*L9j5i ȮMߙūӓ*wnSr`~o)%qJY,# ` ;j%V K [" [D,/'111, ֝3P?gVL4[Jb7[f>.v4 .́vg=y_ .7T,Og;r"|znD4;-k~<Ƭ5Z1-OGQ__׺_wGvɬb\qXnH1£{%IGe LwԁeA4f~X5"^#iBakP^sHKqn13}&*10:ov!`{yY^Eٷm[zmc=u01|ۛzۛ|[z['dQ| #|pI=fßEW0RIx䭙>[gzuWsvvY}ZĮ!Qf 8\-h7P5?g!ּzWjhVmmjVݪ!^㕠a{G(c{YEh9ꡢD޷ mzԧnCQ܋v0ф%K1o Ĵ:FkS>]ذ1`26}ulEx.Msh,H1\ ۷Z_Er5f1)(dD!xV }o5oìܦCGk t[|tRp5KW{؊??UtucZ?~k=9H&0Ӵf4i%qmp/ p gYfeYf63̆3# gfÙpP$[̟BUHZKAT=zT}! {x ܌xI(KInk3K8ۜ;ۜ{SKa)Q[w[lP.k ,z#`U&i[瘁H<^6dcD݆Nz y~F,y];U;vu/Y Uٿ})%ʦ,^ +` #ppgcB<8?x/=eM؄M³7YLSut =[amXvB ;X(p]_r=A)+x#L޾CV?!߈\} 4A 7o/UYI)DSM]ȓ^'lFp!zF8X(zf< v ϵ{-sL< jQ}v8:X|ț6'a/'/ z6l='/%QAKK3%j( /u6(0AC -Ox|a_F%,ˣ il Vk5Fa{jş<{o#j@^r LNv.$؋tkς}LW|ya|:!gwoO"&A$}4%@Grtf}#GʙIͅs($>; (ճCEQ8Ѓed!-b ;{0"%394!?Hꚁ@ 4B_7898>;qlpd:ڍαfsuvۉsعWUׯW7^Uzz8|*ctc8Bp=s[Ѭx̬:L$asdՊ볪eXus ߢڲ1heuX]V'Kkv^;{>yAϺ6sNi1&ƕb A #4€clĮ\\;Ǯ\t~[b7W>G!ɗ01lh1&IEey<kXInV+br?;䲄aȍuc\h9`aլJjˈH1R2U%Sw#n,?2%}P|@w@`ۦۉC6%DY8KׯU+W{QŇm ± >+5r -ܣKz?< g. 4Vݎoh}`/sp?$p@nhg-gdXZi>Rx@aYD}dZ|5vu۫n/_[[Bo_Į._~ӵKkoO-}ݸ) }}Uժ,o~.LBWlͩy}u-A;4UwܶbWu-öl]I+z`AЫَT6UV-.c:ЄO\=c<pO9 {e,ںD]`evoSa*4®o 5*j]鵬1^CnmYXeㄷd+ޡUMY| Үݶt& ~c_1M,*߱P>Mզe9xנrJZΖ]rA]³mM /OթY80b-&\U >d۲}?,MTA|-݄)Zh9f+ 8s֖bPHäpfݮovBmNQe\@&vE^d4X"%H9A&Rǚiuc0"k zuDj5[S]cx PlV O-sFgڲ*vEOA!yAaT V#3NEsD ֜^p_g|.vLT8LD %>a!H49ʧ$<'k.Sjr$ b{AڤcB L ^Xp$m^DY"PZ+˗̶5kBQSsKrTSeЁ,c׮^'1~cȵL9G*\XLXjީFZiBM-Y _}iG1RásђHBbF}p 5mj9-$i]Ÿ"-_e=$ R[j~"ύ t=?*P+ˑY"\hWΦ2ix8RDO#GJ>Z ژRO pnS/lG \+uH"-~Vݍ4jހ8H HI׌Lܑא[0QPʭV/ep_e"aʳ +P*H9:.Ɓ#،4ySG͎iMfT n4qF;/,\U[|Tލafe]LYӲevv0V }G:C; qz^ٮY`^@I6nV9o7xCZš.x]`m`(4& i#| Y%ITZ̚k7Aw1]! teW`;j)ܲ./.ϓ3Fi BT-oz'` r®\\}S7Wm SUTb 3ڠ'YbtE/߲**ׄ|pxFlE*!n!T@|l”;sL8o %\IW#<#_d5Q$eՈY2TR+@F_|}iZ_uO_"tx-7c{ Q{xI:<1k @?* +.2Ƌ6Гc"? jW{4$${f@%ֲ,岪)UP0khGTޓRb6- 5zx VEd"X43. c]t*HWX%)3} Ya藃0;2T:Uw_+ʈWgӶRi6no; (VC k(.&?uH0Jd^ɓOBXfYHجFy"$`Hq@/՚"?Q=g6Xͩor.P->hBB~9Ie-qk?|CuCJA7X# I$l.%Wa[|hXݥ4~^뮮(㱦]Qɚdw )tMY$U< Út܏5 |ݥ{kǀZ@0@IXo^F>UP"J\A6[hAcԪ< 9H:vL R<ԉڵul ~.n&&}Oć"`[42V&*&t(Cbs hjlw8 9&RSYamo:5ֆՉPz ƞTYoL.K J/L⩋jWZ'Q|vˈ0@RH`AC2^LSv:zU8ÀDqz7#d9&P`;.'|&d_ n1G&v%E6&2$઻⡗YޱZw7ٳ OKKcHn ڲ$O} T8$L$OCDe#zh=( ]P_u#sCz4r)%$+~ІZtmdCi 3OҔ$N BA}$"+5\(Z*fN$qTy(\2<2zc2wxtg=k]I&ǿpyi8/1LaBdI Z1$ @er'S2 &ԚQ z\a>yh 1рC^!myn\7;<葑 xmq'Vg d:bX}"âpx)2측_^G>o`KA]( UIPlkl8mظ=[&7fA ^*/Q_xLǒYs\i!O=" ~ ADs(l@V o %u0FLY"f3^:2?>?Z|>g\0 5doÂ)}[N{!cS|z Q"9= ,6XG40 fj0i!'H (B_%i$-m/[ѥ%\\lՋ %TeSb&#&Hw,MB:6M0dI{AշHf0@kh lee̙dU\ "Tl fx g u-`ԫ7~ X`hF^"X,D!X4zM,D1#+R[&k9]`VQܤatg*yr9-~!m֚m\U#b0)7n%, >[5 ά9Yܐq'i7%|W!!e{7)R/ `=ɕF)C3}d6f, ؛9RܿCòFoA(<)EԚ~\=ص%6Mr[őqAl`$:(xbg׽6^|1i7]z􃱏5,K!N+jv6fr& 2xU3-yt纐 r)p L8(p42\;+GrW )UCj)gB*J#CJ#2w`:b1e a)Mg]_ѽ]+AVE tlaM4!M=Ъi<|iUlyQyVp<PB9`XؘX$SiS">a 'xbu@A4Eġ(湮KF=s7Xve!I!90B.RFbf*_/x *Hܷr2f]AZN!sFhqbG2tZFٛKx\xype|y|o.= +퉌.wVn X93^`9a~4,]PJIw0z7y(E(zt2R:+*)$gFbC?QgsC~X'K $Pw.s_ K~tw2$|:VjhwL -{??\K-cZj -ա5 ،r]XAE\k潆mw}t\Ꭳq*Zl+M&gjCCPa~@ѧz6/[,WrA}/D ;~~17% .G>! ;k.EˊLwk/yfg?:{5y)]ĭyby!ICLmw"<$d{:ɮ EMyUIJ '瓙r\pC;)==<`U$Pt~'>n3DQ.e6۷}1xngnPuMHi(]76saAtT&7s3SJ |fEO'ئbB>{s .6nۙ!C^xپKsc!τr{q`^6ƕet>жcJ<tk̈́Ja|oȄroP}b8Ui/9&/'?ٚ緂b&t)}@*J}d4mhVRB}or7C $95XyDV27pINs=`@] P|qp(Ǖ{6l.fHs1s%|R*4IQ1)C;wNzRtT7-^*"vRHVFOi3uZ<8=^̓O2G0vtZ<DAQuPrcNr8~!+vTDz"T3˶4Tx`4Vt͠:*BUW(# <ʫ =S{~17ބxƸ~Ԥy6}bL7;w3PeR9 UPc*E1=6- hV&;F;fUB', 10%uFn-N_+1c R5U2o7,gn{M|@0rM Nis826FY[/s]64 op e~P=ӤcP!7!>O}O\_7L ¸~`4 𞪂t,Gff WJF#2Z u۱ U*#DZRt ơh )i/i𝙓 هVa H𛆞AzrˁbKj+tCZ))Ϫ_@Ϡ¶7q#H75~*뻸[+ZPT4ʧż77k-`ߌDʑH9)Gv$RDRDʑH9)r0r #Ik0r QeQgnG:g#H3<:9,FIDVh1ߌ.=\hߏgoߌLw}sht޾<.2?®-st()AfQ83@'aņRuO o$RGKJQGxl薍W]cLŝ BA|gD>97r:d<M10άQC J4vy ?l7V[Ea XAF`|RP-\< ->:^ ڲ|1sʋFۍ<)pdk1#%{5gǣSH$ }X$=F,jI%JjP:2 ]yZ4PI?>))U;.b-n?h=5>P`0hR<tB𧌘YƮLD~Q@3Z?Oj-;?Jđ|x<'&_[8}1].'6VOtBɨ"<_bSA,pi c#e|J-xRݜ;̟q )I@avQ)$GEĬT%NҝY1wBh.:=㒘݁OjFn!xJٱITT{%SS# ѱt(AIX5 O@N50=KHp,\0ic7Ϭj?NN}*xO@9"bo *%rBQm%M+)*d.K:V[᝞A 'Ӛƕ|M)$J>=PʁC)SE]~EqH"]Cȭ_:_c{EYߵ>[]U;yy%Šu˵:ϙZfuN {a=@tF \F_R_ j#z"Hw eMb xgtf8]G.klJNK8?WПoxyO j$8/!>*4?iv-y4գc R GREE$ciФ[`6G9371鹠V0;G/H8, ag2̗a:Da&* ~=tE/c>k*|* |W|rʕ\oq=xm}b;c-VG$P;X1ocb ƪ6/\tdt ]ɤo[Mٝ)ǁN (@ݓ@A7Ì1xKuǙ>l6T2[=+^m5հv ,;mf2n S05|)(`v_ܬ8r2HG eH3Ч|8sǒDAAکO%JTFSUxzAk/Y(od;Ϟ>QG<*C<q"&'L1Ʃ-EDmg>KpnL*.Gd!0悚ǞHHRiX"4XUaGs0~i@#{vmnMAE;Q ÇډbxLdBnl PS/R^#Τo+bQe>:zY*T}<2B=q(J~#NYר7 G%\ŽZ&N7nL`>X!=ɦ53+jE7^$( mHw 7u&e ?I᪣D^PlTkX`m/&^8( IV>Z)H#Sq(I ě(OyS3)IJOstWi,>\ M@v4ժmR(r@`ga#Ф03/|F ݴ6ĩUx,p6I]7װi Ha@5n-mO6"Q٥kJ};* +0ъ!_(gyzv6zg'F'}tba phGXƌ'8둓 6HH(DGȘ+ΰie-tl5bD~>1B&+ X8:<:<:\9:ܼ?'87R%A>tkfvc@Dc<999Q+obő8bFH\5GH\|j)Vܓ[.r%/`ǝeyR<# }cuSQk׋zW!"wyy'}m]5rnRϊn)Rgq!4oCGecODF^IY$"a^~"2(i1W |10:[3F"L6[.9.Ac!W%rJ| l4:p$LISHH<&LɌh?hoRJR8s^.}_T4v;sײ׵)mky"-dJUv :}BpDD(1 zWOpھ|%{D9?d,˟D݉SM@~ˀ `V>K/ÈHy@ RHS)0#\d~3K3Q[zOkO>0F`y?Rs:?ky=[=|:kY}@[^ Ǹx{%m顅?mGpzw!֎1ip!KB EoGuGu>Ⱥ9||Pb>Df,NF$h6"qg7V|!7pl9e6 ?Jԡvb :yגwpܦ8CB?o~}8yH󔰟Uc(!3Ci(YЕGcQT,0v*~^M&w6OiLS)f07AF,82UbtJcgH槉ҘFՈ y@k v햃3؇4fX’%h,zr J#JY{y5X CDyk‚ yĒ fnnd6uYfK;MlG3X_ƙÚujIIW[?m3n:LJG?0@j;z_pw3db wY|-t jup{S <7Ft/#D(;(Gِ9/3Mk3lxzxӼ\~-5;jDrj%,Y~ Gx#{K+vIUHKKR}{_Gʦru}QZ.q2Fk^DuȠG]uL®Ī6H9^s'?l1HiIIf<ψCH1: ɂ(LgWVWf)zG_V4U)Ɖ|F:eSN@6 y&O#٫=hVz?7{`+IVx5n,7S}-.@8v+C>MLlw:qe!L \IK%Dv0܂^aNjPsIw V eB\2Қ>3<F92li-QJ ڕ$4ٽJ F,r`sV[Ixp?RFZh1x.{]T?N>Ɇr2։qC Iey0^AQhkN(^sөyyK}u+鋴u"=9Af ]q3f?d,K8UZvu]{ :@ZTwM`~~›H~g`\Q`ί6Ð)ucCZ&ъ'ws3 y΀ E,gдy7N;i'SR4ŤrWNRNi1 NGR`ŭͪQf@D7}јsla@z},(9-!#JO}x"vK>f+==NJcep(j?;.̊2Rg;h+?oƎFU%h*gfONZׇ\i.ë^K19G Be+a. S' yrҞ r\7Ctc4?p`~SUB_3[++nnp-z+ӞU+;ukd&idhr8ڦ87:qd. PR4,P=[}&Ь&C{z]-;/Q#T@#OѣC+K'3Z[Vӏ#ZN+&UG5ZYKHyK AP#G<(%XD䗳 `^Wv^!%D=#rp6pI|[T"U= CSk@i*uRw*RY~~DyJyMOR(oۦ+[YڵVg^|ovS/+[dIuIvdsTaa7ż`4zy=G7S8l0?u޿߀0j=Ru:?FdR9?*W;\RU*=1&f=$ewes93b{043ƯzU_ -S녙قNcm7b0a%#ǪƱqHLQPw/iF4oKh5l@ТAzrq$Xh'2![3{|!* /tϳ0|P+ /WƑ#)O `Gx RS xvZ R׶ >{: P6h"6^L7 \ iF/I(91L~w?az%g8}>艃Mwy2yDpKs W`[w7)2n>5KtG!%xȁK&]$?Q_~Zio~Qh??ĺ'w{ր,p siY&,T7nAA; ՚&.K/pLJ?I^_Kjw-sZE_T;c3國0DgSx,w`y6Fي3 QXxݺp?avYz"{xU|:σ]~OGbw$ܰ;̹}vmUq`2ᯉ[sĘZvT{.e0B(&X) Բ+ ufGS\6=.q`:c GxޮZ<]0`Ɗ-6\ NҽEjNUǻsfl|*QWU6P+zV({gǧ6qc*2a;V  J:LϢe0XO>%>;MW16-x#hj^KBjv =X.}&}imWM㫼S#uf-@#`װvTy/c>%m Ӆ);Q Hi߰I#a+ij&UhiilbѤOţ6t !)".tHIXc :^P}J٘V;8;TnbAH҇4k?'b7Y}nE:4&TH1&Goy.uĐ!m mFGa9dh~DZѲM{ >LU,1m'quD gBb@mu<%Y~j MөI8Ih8a03u`Ĥzԋ3a('߽F8/~#bFBp4=˘H[l 6DS6J#:FzK,EחG#b98Jݑģ;# \ ']E  ] WY (]PcJ0x4Gd-Dy4n7NSDRUڍ_<.7M&h_A1SCtj6tXP;]K|!~QOߞn.$< >0Ėmms)AS%6SF˩Maڍ^Ij &܁):$, -^f /)w1)[Jal䎫jp8U2EvGxU^M&pL4lܽ&B_>~.ZkrYy gg( p UnnAa"&ligR$a[ t2s ZRDGz6#69^4w T>c7,<<[(M12IQx:nq&F}X)2/:TW@rNy& Ӌ z|4=4Eǒ'XU%q0b4e@$=A՛]COEgbCRxǼw3)Qv|>[>3O!5r?˚?r #ue>ս Wo|&M#F!U>J6EYN#\]f1PBZf?l7 77Ϗ?Lxc+d;A;xupfi3#Ei bN-&6^ϵ_f 3a^D} LZxyܛ+s?{} ;{ΩtN}ߤWwn(`'+\N BU45u+<=9ՆC4r뷸tӠ<:'pkd#N &"͓D hLͰgXyfdŤZP<:MoͰg,2ѣjbvCc/Lz]ڤo ; +KAst,8bafYk BQ|T!W>|0-aW9$:?;o֮FHR>ޤ:Wh8ʾ H eVAЙݩc(2ԬkT!EG7_ɇ<ΦXu.Ij+.ї6]5!>l6 K&ia?c)w|B{2\}t}ZI?~Lic-_O-osZ{Ox(M^:GWpxzqaogJ_4Kō0y{cd=Waٌཱི'vlCgJa?,N+ACG>Qژ{jT:;=29Ay6wdoX;.nu@e\klP|PV_?~ZxyZ 909Ŕ[9pȊ6 Z1<` PH?'ESgvnt( 2M%PYfj8{:Xg˧a;N: f?R0 6-0%3GC?ЏE{s)$EOM`|>0V")75֡}A DYKu #tTy8Sj ?a%82Ϫ"4NX^~λ?lWa \+ 0AȅE)yd݂~$>7!&g7cXbOj!_m)cE[ͻʡ@#+D t 5߇<{.W()Ml pK+3T҆jЋ“b5cL\Ժ_7>$׳B+ʓ<^:E nѱѱѱc'c'c'IgEUqňUbGJ3dRf!|`HФe40F($ܫ 3ђzcenmi7aHPs͔+vf{Lܺ?v.S[yHTRI}Gh? vޣxk=M;b7ܦﻟӔH&(#O\*IX>,X@]iOFJT6rRft)^FDLgZ+nuR9n?7 DDN&?H<&oHA6Ix<;2RG;<v 76&e|݅\%.J:s6cKwU.l+[%^!8| s I:՞M\-FGv}wBr|za!k=_6$G-̠%p'>ڰ):E`T\{Pб٘M$;Tt.'J.:v.[-a /<[ÜruЇL1e?1=?9= Y3_zCM{G97a_7@$>),q9>a GrŜ^V2@<i@γ kլZRi!ز"7ƀtn`N4H/{LX4emyqr /L w,Ss)V/$3()veSx~;!'9Cd{Qȱ'1a04lΈ 7.->ZO'S^W3m; |d8SՇ/Ɗ 0x V*tx~znfv80C? vo2&#ϋo~u}nQy-#iUo 2=0g`6AF'ǎA5Qp=`!4F)_+[fYO#(N>]| k3Lh/EՊwHQ:I՚2VEܨPT.|V^{W߫0`tZ}4l%݃_!g~h5 k忠ǵ??2\Nh: Zh*%VLdH ^0X}&ei3Dtq;7^9:=k?/NA7io$yD8op5wg*sGq=r>ύ9<@_> +Tۜc4:2#'F: ge zNFqFq˾=ex˂1GcCN'.g˭q#?gF[hmyabF |{'LgLf@z-;KAzw#iDծ`ps,$˽*R c;6^5rf=tj+{}IN gui퐞4i^E0rU7y;:}V/q0nĉ*q>?dP*DZ0b Gc=Im;ұLPkm'loI8!LJka{r>0kO kol>4\{ 7nk)b6k9g9sw-wqbw@>-*,_dc$Ï6 _dߝEC[Z9-?^|(bDF`Dr pA? QVhŏV_ ծ diQ8q͕BM^=눷ݩٝFk =v&{V56ů.u0"MfDgr@eBuċ?*~!gt65"#pL@8Ig[Cy:*)zʮÜ%p~t,x\? ݇R˹OoSZ7~wUq=k57$~i7NCs%Zg$[8.맑qYbP;~0'BCd%>Wx/NMWqL'b'=@Ð~lqr%> >cs5 #wp}BnڢvIYߋ; 2cN6MrK<©k5BiN5ISy{lUQusXOͿ|isfZk09꒧: xr5W5a뫘MƢ_6Ogr+HRa:&vu_6 G? Pm:׹ucɵku#tJ;# 8rm4cd(C5P`N8[7*˒. M1ˍDd۹bQy9ȾxnJ)ϫ |to n9flcnu1X d*Uzpj2Sx#5脰! ~E5禑NO,Ղ=Fr̨ y^8%,yY x"c׍b$; 7 HseTW!3!dD~,ry؀X'XקINv[kSfl90%GI %~IAϯIiUXr}@Z/ t(NMQiTa4ј->AP/n FR84=?L'.UzB%:԰OjE.-Z??a~kF2G4XA{#ZsyWlLy/z K@A {ngN/AU^0^zM$_n dں 12ίx-Q95]^gn(x:@Oho4$xN>Nܗ d )y% x2il'^Qzw? /$Bo|L6?PyB ]׫/!wVM|Ӷ1a-_:G|Afbd0}?IQ%&[ez߆]'{?:;ފUoavj,t*hsWaUY5W* n皀(@zde[-D{N4PGBouڃ#SqilVa, .B/;Cd7W%PĻ}@~:H @|}pa6L?5o USHôf- 7՚XXb N@3 X='q!=۵дWZ!%qH \5S4+3h2ӳ;I}6Yj-Vmy÷%l >gY$XNƚ]gvb-Ξ.~cmfPﳮ\SslVBxC 0b+.+נ+α+/=_؍e啵9N%f2},76 mOeI ;LxdHȞH`|ش!쐋$7qE XԃU*.#bHe?VzVgENA4Cݲ7|XAEimn'/ϋDD(^< p/^{fZ2Ϸ{by>>|KOBom匪kxQshQ]-,!k i/T>k;+_&I^rGJ!}PXxV۫4в: ɂ ۔}[+Ñ9gȔ!Oȴtcuk۷W/.^tii ޜrs]]kKזğ.._[^ q}u9R,o#"v3RJK _5JJ!|1 Vq&J^յsM3v d)U@yCf;RW[kX;̢>q|T,l <#.Qݫft*.`Hl%L p/ Sav}KVWU#JeznB,L(% umYv671 ,_ije1 iʬ6-?ϑœSjvL :u]nhbx ~bLdWNtn-46cZm%ݖaWB rrMY|nΝ,рU5>j(2wit-j qlW4. htIհh,.0rZ?#L\KH`UawExFnDe$δKT@^D;|JRso)FL x0jK˯6y-Q>H!MI\ =&]'-L/&E// %p |l[]&/|u"2!"Euj &^ C`{<ݩ#HCMynn2+z:䬤9˩D nE ,#EbqnbKk P$ 94 !+,Kp%o[n _t9]\_2'8{'%l)WoX,u @ߖ܂L+{*Eajj@#nJ>V͗0ۢl@ rC@D/ #Č`GX: ?[1n YQ9u cB$=[}Ҽj1i &Bd;C)/D8.؆SMo&}R%:%GL)F++VWנ7!]ESo\jȶzʕl}g3+>ЀZ<< \\{nnm&l1?A5dx(|pUBgy|"ڴ,&΀)qJti.yU5;So5cH3Lء]c Ri_x_0_yݼDqaT ⋧V''ڋ0#MJe/UMaVYC=ޤJ%𞴖{ULliЌkMPy*'"!Jh<K.%KPG* ]I0%nG?EA: S]aFD8%:Hi?u{ V匀PGYC}7(@|揅y>P"J~2U2 5@f5>D';D#ք 9>8jN ~gtſ=@jA*raǴOJcl;qX;]uDJAXF I$n.%Wa[|hXݥ4~^뮮(㱦]Qɚdy )M$U<*Út*5,|ݥ{kǀZ@0@I\ofFNUP"J\A6)[hCcԪ< 9HZvL  Rn &&}Oć"*a[4:V&*&t(Cbs $ijlw8 9&RSYUamo:5ֆՉPz ƞToL>K J/L⁌2jWZ'Q|vˈ0@RHaaA2^LWv:z U<ÀDz7c#Td9&P`;.'|&d_ n1G&v%U6&2$ૻ⡧YޱZw7ٳ OKKcJ~ ڲ$} $9dL$OCDegzh=( ]R_u#sCz4r)e$+~ІZtmeCy 3OҔ$N BA$"5+5\Z*fN$qTy(^2<2zc2wxtg]k]I&ǿpyi8/1LaBdI Z1* @er'Sd3 &ԛQz^a>hzh 1рÓ^1myn\7;@<葙 xmq&vId6PaX%-I?˶nDWyVWW7B;4yjscu#7BxBC^}Dp!&-RLI:4mZYqEKr%m pYȯ۲PwX +1Nwc]`⿧tą( ÷ U_1,H>#Ȣp3m2 04_GHotAg'(UIPlkl8mظGp[&7Lg A z^l+9!_xLǓPYs@O񼘹({.Py'TȉP&$ʁWKHaPyEL%-n&ud|bO:>$6H.]~akdn߆Kr>XX>1;HW=FĭN R<2 h*(LZRgy ` Wtܫ9Ua OY9A=k/.T!N{tgAZ0oB  ,Ż*%eR= ev&y] )@etBm`ɬPQtd\D9郃)jLM>'j [ bJA,h醠tduRJ 2hi >vø V6/;7_kS3latkkk(6ma<;"i(vob %v2W[+J?ߴH[sK=j v pWꁸMErjѢ/bn*6ȪNg &*d_{%&(,͵|"/sL'eDJtU^ - s< ͍ x'jMM9$.,Ұ>\>O:kPQUtz@NqU"T_H{e"7n/KW!w`/]]}ovIyțLASm& >2T KB;{j6-ߔ6^?{m{ǷL B "_Yفؔ.GS EAD֕> ߡw0vGt83AbBf mU۔XI=+i7P f n^8pu.@W qsZłt,m`kYbs~EU@+ob®Hۂ٪2kF] x*~##V,xx9"+h8((QV49H-s 7`H;ԞI[N|-v7i8"]`JxN _HrC#f&D;&lUq('B4T jIA ٠`+`3k|7$@DDAM8BIni2U{H:7 y|ʅL4X"0wbrQЬ&a$٣*˃%&BB@8%##-ɿ\? JQ*h'(`q_(Oi@w~A9xW+CH@0 ʮCq,Fa% ?Zh6x*"rRl¾`.0VȧB^9PNj"Na5V/-i&ЀYX9:Pe"YC.cu<)'II;d RJRѻ[G7ӟzC^-Nn]*HrS}.)E{%K-B_5ҁ>::%8 ;7 (xSu"$12 xS2xxve(l5ĬJLTQ9D_3IA+ty7cˍZQ2j{+"֠w;F͠Ns) ١xNt8,˄&8}znf`J U,ABe.ȿӽO Fܖ23ޡi)c!*τ#rM5ُ4>-,} TQ?uXk(T k"3Z56d y+eI39g֥'gf(4J>`IOwu%\ xN~r/&轨^ sbic TX}$U=D UPn8Wnޯ;#(Y}"6d]\R 5MKUߞxmk=s:*Jt/mo`<9J&`q[`(3Og_(>cyP];̓ϕ2Q0vtn+K,_ ,ν۩^֯(@Ax~O}Og /(a{#i a\o05@Ozaf`{P\0!(p(ƞco,Mʈqeq(Gw~ĝ10 X8ㅢ1- j `Ug4 :OeB hfvc@/ڄ`9-B0&USe)l~<,3"#PI" p\Aj{y%y 8HE||{\dpЦؿ)?^vhq},$R#B5!+TMIex >ORsAj&H@LLjDT0Ȫ_k۾n?~n$;A #&0LxD8 51GH\:GH\:GH\T4=ZP?MrߴxDzQ~wĨ$F~~p~OߑU>6iF"ԑH3iF"ԑH3iF"M.fdYFlI#qqH\#qqH\#q1vx,^|~+4Y7bu:X+{rV'qд/}a5H_4__+Ϥ[V5Q=^I99Îġ0w3 K7)ϾHc TH8T\:3[kFYZ9U>H?ߛcC6,<BÃs|6Ysz10kX&F:u`@#@F<h޹lV1Unm׸9>tQ:"SWl!F }^ zf# IAʝuH$Sk^SHwH_ 2P-<l 6rn̗޹!gJ_q*zg#BIʀ}Īx)g\W;9wjyniHuN 0ҧ@.tZ[6QpfǓ63~}dlO?Ao)%0 Cfw*M. iQ d̪5SC٠ZUI? o͑,xŮwU\.~zb!{u=]e -U۬؁;V8`ٮ-bTbN) Z5EWBS.k,Z ~sHx?"(EZ5eO 䖎sTAj1L 0:e]mWW[{l̤<CDkd9vg_ +aeli# 0|jJw4#fBP=Jx ϱfCB (ͤx˴X TLE"-x#ډ: }MTtd{@s~+?%vq(&ԁ"yA,1V8|Ӂemn\K@9q# h f}n '8FNrMáW W3Ԑ %H+S%dň2D)xqYQCR5YѫEXނ:x 3l>l@'5B/텂2xD^.+{1Ro՘J?$+=NdeSYĪX*;6ib){@y60r cxv?uV7u?~c\*"n%~m3;s_wl9l퓲)o/d̎\bGn3ZDRy.g0ȗl >~ǤA`)2\yXPSy#KdCs Yvޘ&Laň{iDG{ʶ`ܴLKڛ{өl S5G(L>d.w97JTޞѥ(?tk܍3e.8N+r#D[C>l 6{k5HgJ!d 0o}꠾N!o)S&.[E˯h7M-e-忬ohZW󆗗yfGf95vi ,9d3X,[+woW˝q(d؆1~L|E/oI/OOo4y*I鳑II[ݳdtI̩!a [r*f w@ Hv|TNqj5|y{mv,VX2<Ǭ6oY-6ƩT5?I%#~mPf ՖƜg. ^~am_o \_q7,5͜oO0K o[onLoJ$lR'($?%g=ojWZ P~g:V?[)Q|ʑ'TJw_tNiUf#iCږn^ :lC"+m'ZG`Pup##%珂X*9}i@mڤ hG+f$ZJ[ZX_̏>~F(cٲ]GW溴ŀwbK5MfA66bzn96EoP}Zs( D?,{?8$V""3w4) Y+!=Bo7-f9xr>'%8gAv)诞PIā=RK!>9esӦto>=Zd!zps۔ւdtϯ |;K5)΃òߥ_PvߝJzpq}6_A}\A?mG=$3n2+/*3](3~,Ah?ӣ"AU~ S"}0j=| *ǒ"SlZ&r8< ڑp`Х#ҩ0Ѥ]{ p0(eT(2~]ҟHQ=,D{C9a88v[gG$86@_T$w̚LgǽV;C\ "A%!V;vÇ!):^_΃hoM4@~ٶڭ'@[#*睛 ;A|8ȑZw8 z߹$IrZ&?x/#ԁ87hl'EI~=} Ҝ buDfPR{H~ Y@ ([cff;gΔ;gb}ȱBEOd@)D0Lw @gG9Şi~;n9oԮ9>61e] ZHsFq>bzLoK x*H#x(Lx3 l'%w蠇#zߋb0:SsXz@Uoot Ns ӬSҎA_"6r%ȡuolBGyq]>S*h>Rj\W޲G;[qji5oC+%NVM'HOޓ{P0k5a|cDc}tVȻȟ[LwNDεx?ҋKJexBg olUXGR oTMM=&ѽjpj4Z/0[NY0bXM@.v/`6k۬Xp ;Mw %^ADGDe]?{].gL<̃r=fڛ ˈ3W6EwIgV7Ë-(8l=8 @-Id]Nקh|Y Y-RR#ĐE#THUbcuA\]zU{i~ט?F>}ƔQHcA%5{,E*zݮ%,@^3>6I p&ƯQ!u%@6H}d;x[P Ϝf{7Q _Ni>aKa APC?]A z@ (⬑B򾋮2Ph+r)z$?pWq>5|ܐC a9Эv %:~-(W$L(&ku wӀDᚉP~_*٩Sm)(5 Ogʧ1:%G8**̟S.rx:sKKWlK}Kir[Vù*{Яr a9 'ԂtQㅦw驩6ձIori ҄ޅPGdWilI1w04Ŭj4+CSa}g˓`|eCM8\5cFzd{K^QJOKg OF!e=׺Qh8\ũ] Bj-)$0/NcTIܷ }k[s uID!C" 䦕@@I :z!F&6,F]^ ~Jg-j{1SЉB9Ї^wie$JuKבv?L79p2TCNw,F^ZGܷhOc:v:zo+gh)w2E2:.TAs*y6T _`E_$^ɪM`H-_=:HWڳJ?TsVhMBۧD2,J9[7ӥ{.͝m<0;w.HvT 0 UCHYAy2~Jr)vd {-4HMjaE]r ǖ>IB_GӾc7~iհLk:YXC6]^ Z^F N+rZloۄeiy7 yyGA޳'b=ȏO #Ǔ艄4<0u|a#*;P?Z%nUKHه0 ><}E|xbB~<ڵqX=j>F?\ojq:VG虈*E5Z)O)sA ?ӱM${M ˳<̷0D[TEߝAcJ ?( E}@%NnWnt ԍwRmkdz 2 )MaZ NMV;鿲W'E Wr5C.gYu0o/;t(#ڍ]Jq^.O'?dd yɃߊLȵ|80ؖh)nHG=FvjH\ᥑx|3ݳxV|G|fӔ|_H81((3t31h>#Ԡ|a귥3ހ<|&şШ%!JhD8#x4ggECCqT0 Yjr׌/LIj*7n>b7:bē7g_z:cgFh"1 )xm4Ih{/$. F#.|+A?-o(ڠ9Oͅqr-b؃ӱ`sgY]qE{P!sas珖'1zvCa>yHz];հs3!N_̪_m39ՌS33g?U`ǓPyV<)O=[K 9Ms}|6 z1}oi8:Quֻ76T8NÑ<:+L-׌pg-o"f8+l.Pe[n:);/UEjP$m!lۛHh8b'aD:DyCQs8r~vilagv *Z&^۝Fil3s-=yׁ'A(DQx iۑ?utb>: !Q~:F Kg9Y0w^C?[sls//?p~U+M)h8iZMAqfTG,;oWMi>d2a!C('$p Vݾb/,;3le\-cn4d=)j`suJ"'(F%v#jZGWǿb۶g%0<^gYVDi2qMO~I$&h9_L\ m|βuqV_>A,*|@}\UQZ0b[afgWbB1mA:+ 4vo\`M@, US8WYsˬ~I+Ʃn6ګ&n=0˿Z r"+!#C#PUoc/]vmpBi6 ;C <[߯ԁhs}PXçjU0C't<'Xǩh%gI?(euzA8n&D#dEBSx&aԷPXIDlMyjT} E-dcq"vZD7}2t49䪠bNdFkLE" e,PB#s zE5^X"ο$@5׻LO) N oq=VhQqvdU~KewYr\xݰ$a`k^ZeV u0\ (ִk5&P%9x]]׿8(b9m)@m. koW|mv0{a^˷qLS1P[L\ʺm rOuArYE KWm/)F\@c-k zl_So⶟-f;]Zl١]٥;) veNP$_ ޓoɗw+x?*wl[W"/mQQM|ȊΡmؐ RanHS.s^ ZTk`kʵHߣϦx{:m pD+W(uu嵥JͯoW/,(yuȕ +7Ģn5"!(VjQ&EhU eI8f(]M z JC}>gU,3y?w){U-2buWE} U'(u& fLĻ(_eo&g05ɠ )JzE8ԻXfaiДķ, G 3阷g8]},hTn] vC D%Ň-eYFӗ!N-wڲG }v*H^V=#םÂtwf*n|lZy+9ab0uİmǽN[e 4 s:±Tk4+gkLf=]ex)+kuaڐjӹ} gj(SU%™3x$kh`%WϽ4O/^9sKkGFz϶- VmVogvvf;Hr(6b}Ulڴu+m֭^aZu1X*>ч'>amSæC'WeVSmWPgN58aWMq۠}u6;vm˰(9%pkQ3_b2 A .EI^Si`=C`$!ioS^8#+UW*NS3]a=Ol1 UlL\1E<ܱiX-^>~1:xj ޲ @`7 *aQ0;0t'.Twv,)ԋ% tq_ĵnq.z僂҇ ЄZ3(oY@k3E܎I\-YNED8h\, yκptJxƇ j#@QU0>?6|0:!B/ ÏZS#] еG^hYpQIPw< ^ab<* 1tmnZbvG e,T*D;OK/F&6fgyv~d'Oir1Ž 1WF&>>.TnⴼI؏@ f~D)+auN^5$`3խrymTFtX/lkw_Y 26ºsU_ԟAxQu[RiBj в=ӰiFG5}bGL5.hvJ䜆w\;! &B3WmiMV=v1Kaз~d{qcBbȯ2xa\#] 6Hdk&l^Y<o/%o%F8x}|qa&wL+l#bKBʩ`)7"9+O[,N1w[Wۺۖl=6^.uC=:"#ߍdTi9냱ÿO&T\.(ӟ_cTư^3^HzvdTOVWR#!t×"*mc[ӈ <K CxVa !Ϊ82@[lEg-Ѹr: K0*{sL\ >aA誮 z@dh6ԝ=l':eVh&*(q.//W؍klq[~~cmU2n̯-\6$@[J<4IĜrYpۻ ]v܉ĩ RwA6@ߜٮU= ζ@Hê:Uk]\$s0# HZH?7?u7 mʳ~u }\!9sN9yA +-e$Z$6:~\31b&:Nk"[عf0(/O^M*f',&<5sל~q"O&4q8ax^HU8f':^N~<ᅭ~9b+P' A n˜OmWB+P_*a&$5S(Z/nbr{IA_á|GmJ2ܻFQ&# stA}b"WjxiX 9P,BBy@8";s}V3O5w(ZgO|o r`.9`j݌O)T}__/{7e0V! lMHD7G\e`NDh\N4셧@(z^ >ωrE>gkxWa<RjLS 5 7sgJ_LSI(1$$`%ĽhV8kʀР^Ӹ_`8Ts9F#ӕd|3؟ JͻgNw](6UJt)3~+}9}9}9f$k W*fOMlë%iT-:q&GZjdj:ةԓ쟞}1bw|ڴ8[[w,3;FܜTHuu[SmO@ghoMuACZW$azđT@C?kX?m*'ԁjEYX,cֳ:˫}S)M;Bn /yZ/ߒÓ'Ƌ:%MWtg}sl}cؙ[`*{/{ʿ眂8w3n>8A5 vg_y_m9OJ$Mgq:Boj'w2b~LL3Pw|K]|6 ѸTZl7ꯇ.lG:ڤ|ڽMڽ[mdzͺҀ5>;$݉+*ar9/`'⮿n j| cJfoCS525~iXZ-Z٢gsWiޙ~i[0F]+¥ ld/ ,ivG>e^i>美lfk\H(GLcSõ:=iC(3(dLP7hxo-ro}Wn5J *dd4t}Π0mUݴI8о xC{Q}J2>{ 6~ȹV9kpCAnv?qbsk 8WOjVRv;r^/!6ݡ|[_9v!N9ARpɂߔ&F`}%U:Nz*0>R>{c@Fz̪1iwz&y7خUXv}7W-/20Kc0Bs:Rr~{z+q X^?TGM˚?iV=H"w]t4.SfE&s!>F}E=dԱt֣Ӌ{j/+htmwa`hK ȃeDzwd?{wLCu;CSUu\.[[GgD욣`G'\IbK>-VgvʯE,v!{`ta@aJq}ie0vNC` 1b*dD,|A".R#ǭYMA'эWucDO$aDՁL"v~Y0P|!jHebqIcȾWGKi8{')h0$^g9K K7ז ߸1^1dGt\~ԡz-|Jӂ=_;s$gN5*Z{]f W~~U-vyvӉC?*ij%#nZug2^/}hdxy՘3DQ4c a3D {٤-x"B$ GU";-ѻ\7^ lmr[[Tv}Sg9IJ?ۼv+y^`T FPܳW/'=Gߣ,kwwq~Kt&rÖO+g(6ȷd8g(sl0~kB)t[4q0}a! rf9増iI_Gg~).zVW bv-wpWw>!lfAc8m}QI+/߹{M6m@kMhF^6Q5RF3/7RLB0Z3/g4J|C†Iz%WSIk/W3#̝6W5=-Zĭ^Ǧ #:¾Д1Іl̟;cy펣q;v8]!ng7R(eɜzP}{i6Ѧ=ڴGh~46m> [Fԍ˕oZ |tq9shŁx:6X$2,qFߞL*QcrE<ҹ7lb Q;gXX0ຕf6ϣ_kaO׽vap v-jÖ>Q6o~Mر@E<yۍ8gԿw$&ʫ}]3PaQTkbIMoS1^q zW=}"Z 7IԂGk ї?:&Eq'%D|݁乤 m@6D#J:ycyU/*D6[l C1t2?{oVr`T$ e\^I^Ap_;(w%qY:QhW"%%ZEkek%;$! %)z非i4i;Glگڦ_k>w 0aŬ[>{3opqc|H4Gm"gs̠L9/'^?Ͽ=dOo#R2\?m֨ o!6^+b~^i5ܑ~(-fYکowr3C^UwU6uP0X Η79r2v5 5VN܁q 8=p/̶K%Y;v D˦- { ,Iݦ^9eI,G]Lג )m!oE|U6t2Yi-oF1zjٮ՝~xrf J,,^`FWe,\]_mu/:dن q4&6{ +/a[T. H%ѢU1[A4>%&MG-jZz;/T7Gh%,fX*iAjgP&b7wAItepS&B2Rx^H;376I45IP 3%IK+VDOzG1tZ0}iV[V&y5O{a<s $NJK9Wձ8++܆.6>#^t.``'e4fX;;()4 ߂oG7fEѵhӠjTh7=%<R1ϤeWu `EY|S6X1ɟÆO # QUZ!0Y;: Nl׉))2ր{ަI=܇՟0:7F#H=/>^0m$ut:yuX>?h꺛Pb:vϯB N#BfRUXZGbGd"Wv<]n?h-§RqmsVq큞}!wP#SH R!Mљzw'U!XH=.9umˤMfn1 Vƿ2֫})h2vÀqAz!#$`ќi^lpӋd];#HIHCC</zeq_IRfFQF}PL]enO5~(w`BL[ЪPpoZl, ΐMƷ?¿¿G@λ\K眃N9cfM,@cUTܠ{Ikm!#q;P7oUEaMmG:/G+$:w4,S&ϷRl+{w03㓬7P'#|aRuɉZmČ$ %2Ѱl)9F;4(ݵ 0JA L=a2hͩ kx7$qz8XSMԠ ;ilXW}XbXq-d7"+X;Py<OhzZʭM;x{qԉ闱u3N bs#¬A5Jc, dysVyƣ0^V|!J(KlfZheABD4~nkRTXijvl~'b#ΏE ǭONM%#'onfon>ߚ<.aAN$#''%PHdd)<{nh-(1x#gZZFjk=<3Ǘ_wkc9!aL0Jv +! ~v0sk:F #-t,B/aE}0-C !+BrM+^:FPTlXh{Ć3QwCo->;F v.D<+*ԯ-J) ZۨkEHGM_XI'+ 1%,`-(å|Xd2VZȅ)&}ofTJqxJ*)e H `1 2"k#aIU7Bk}>E:*ᄤc/q/,PT{ Dzɠ7r;VKCT5 At Lᢡ{4tXba OCR1L[ g|$c0v *))'HtX,DVgIYt*,D\aο{ݜ;J5JGK[f=G±jej4i[m,[.sAqezOPWDzǒiVFXC_[_Z}, XtaK۴vpFn1˺]e2h:u ei]Ǵ6a3d὘W .hb5嘏R~ DVM.J ڦ]Y_w;/Wb+2-%^l28ZAn.ݗ>~i yZ!L3,z}/== K}OTؼgѤOVL93>hٿp] =?.PSl _e^g6[Xn2ci}œ-yxb:y[{L +yJ͌/m}yZM+?\Cj2*}8&{D>/E:;@wL7Sbw%O6,e*X=iʧV~riLjLר%1&BO>)>NYh6/FEO)^YL|'-)ُ2F_?KŽJθg"Kb+> |;hjNY%%2-gS۶A[]0)Sif5#[* Ge l7yԲAKMKw=~T`g}ڇÜUvGb5qYNhK%3w2ȏo-r3V߰qnuw3uƝ.t3>QNoBBVǜN݄e'bIR1ͫجä5l/GrjMD \KzQ 0[DsټD*tpyWF2eel!g("g*UܰucVύ!T<@.V:nȳsuvAxަscњ"8?0hpkcyi,.=2:_riXskO:QSa[Ʃ`T|DvU.TshSѰpaݡl1e0ȼhuJ rY?KU.z{sx¾[U.ږ ~=қ @vA*ɳEL"x>ƺ dP#t^Z>i+P!7K9SCZ+3i!ClY }XUUZQpKU{=CDHtaDVF0pM>2Y3FZU۷ͮçA: |Dp삀T1K!أe} 07><1uVm7j$"1]#ʄ_] ~xI1Tmӿ"̈́R2zWo`3*}\{FL)VdVsBy@gcU%\`OpWU`J`m{R WundJTwa6 p~jC\^WʺUj2p9jhyZUd0Zy2)諹x l]S8:)D]:UYԻ0Kh91o ,H̫W|iUju46AD k=?%o4.5DE gU vA;^ lzH=ɀL/vIU|jt憦R#3y0}b+. b whcdXiZ\zA47=ˏRIXe(!a$zsɗ!u[).c}4WHB>;˥9zZ/kR8K&]}#p%WCJ`lLNۚϪ@Ws!$ ^˥6dEKΙ|xz=1s Z_'-u%ATiwwiw7Q sNqI.Ih5=~Xb\Ws;sF*7=~ {X|UХfw#Wg0U/J6oaRݎ+á#RŤ߆8Ww+Xȅmv{|/EP gs=PJ`߰u6Y`&]FsҨMm9v.ch?RtPH Ok1-stsMcl.cCrGI/Ns2;J̻- B5E(`~R9/[ ]rf"*`k$}RJSꈞp}AQ7Mg#./eg }2E~AjC…56J/Vj@9VE/%V|c~R7_;K8 !/W~KK~0amT\QîR"l'WH 1I1 n׀LUo܏{]t*ƅEDkʆlK_da"nn "uJ;_[.PA18ߨd\7 EEߤ$=Zp%6#oV+R+KK&ҾUX۠&oSs#mudbەxY;o ߠ܁Ew8 KIجZu Ji5x1zi YIiKC߭ĴZiߢa=oU20 AߣĻ5;7ǚ{S,hR8)I2LR>2!KJ[5qr>Dv%O7xAN[NKߩHi sPXifaضVB1C ૊d;v~=4F:y``WTr&|\2RR?6%aخ1S x؈tc w+F6݅X07]]鮣 i`XDJ8,SVg-;%mG`q͢Qxt.[ք|@id ag|dv=z'XeHIe $4Kå PP)Ӭ`ê0'ǔ|xǕtH E|Ǖ3BAbat-0.19.0/assets/theme_preview.rs000064400000000000000000000002540072674642500152250ustar 00000000000000 // Output the square of a number. fn print_square(num: f64) { let result = f64::powf(num, 2.0); println!("The square of {:.2} is {:.2}.", num, result); } bat-0.19.0/assets/themes.bin000064400000000000000000001170740072674642500140040ustar 000000000000001337xڵkAo4cnPRX")F&{s{CvgلkA?`!]`ƨ($s;sw[drw{o{-űKڡ5HgO_AzMk>璘(611/_Ӣq4e!’-}2Bԓ,E\ ijz2o(7!1{U&9R vq +61Tp*T|\qlʚmQm,wo@2o}EjX>XZ9ǫSJ m&^b֮u馇\٬U< q@UF' 1\ 2 G'=u(<'JPAs 1"CTmaD_Zd0$`pCcB@6RgsZ+%#8G\P Aaᚂ0\L=G۸M^YR@+[m05X[8s (4l5 gu@{Lxm)7GKd$P(2dSJU1avɵ&7g8iZ )4Sjh4w:͍ʊ"`Q!4-{Ee@Z핷Rasj2{B\-9&@27_QY.up0lsFaq<^ՠ>[LTljUq"!XɬVuM?)c.t౿7 Coldark-ColdExڭY47 dMv7&0!!dh*:]KW\[2ex&=%%Pd9[stt~tÝ|R:p~ EO]9g?]}߫ ~}Y^+:(?ט.$g4 ,{t/rP6g "lLz"aJްۡ~}Ya*jBQCԃETx9%k`{yRH&8 !MLzsp bb=&˃a./h, ( %D 8riSE%0`+K`B_Dc9ѧ#Z"ԗmwM¤eg/s_-pPOC )9|G6 xr) jm!IV(%'B$.Ig M祿>8 3[(U9쩟1W9gme;(Y23L/ C ,Y7ݬ.,:͛ oK6/}S7QSz8ZNg P/{䠚nɸAY6}g7\x|Pϖԯrϵwfw`w}Uy}/ḀY |5 Y`ɨ4 ̳aY{zc9qÖthxPSnwHPpOq`=Rh~L"+xZh@WS?zp)]AUCC(AFM[z[`ԅ$Xzn"b!E1`wN9ኣeړ@]X;sNSj20[Xkį$XIU6ꖦ:$qݧI>K [08ĔRߞ7A>q`tYAc:.Tmޙ;+OU)%PT%'$zҩ"%1GP(W! Nܽ ML6],oˑ  Coldark-DarkTxڭYM4l[mCl~mUZJXT~{f:qn$9 *^+UcqڝC2y6&Ku_fW BI3y}y珞O:ayD;Ou雾PƬMOT߫Br'Q=Ub9*-:"|.k&=3r_8k Q}NʄrHۑ}!s,@>ټ%O=>>+R̗K7އ3謁20C+$%OX((n"Kd%a@xF2LO?wOg )3-NW?~صPa!p)sVzNC6-l͞= 08}N~ BHHIxn- N) )j]!IVyi!q\Ƣ RcFG`Ate02FCԕHbYFP."ىJ_m~}㑠ASQ 욨Zpc0Ԥ:k1{j0R q#V{=Np0c4_ a X;<zagq܌/Ȉ瀷PSnOP@qж)4?hH]=rE։!E1`W{F9`2X`mJKN9)MzS [_W5% RU i:pN9..0.=Iu5pVx>` ziYߞ鏥 9ocِfuvT 3Szݕ[IUĂ3=j "7 GP8W! |߿ NTX7':)o h0DarkNeonxڥXMlD,6 QEUk Xqq  ڳPc6+PH#UH(PT . A{!qpHC3{g챽J}g޼f1<ų/"[1X]]t|0-ygM<t* aQE4L:؜ 3-3JܶyND!#4͍FTӇ20@<ο;MFQXB)tri^cS0m5ń2XpS\}'{mK3C[»tcD"Ȱ)IMF^þ;:umFEd(廯/Bỳ]9ЕB%:MG6XtQ vn~?Є#jb_’00b {*'AP۫qwbS7Cd%#ȶ bܸQ%SMa>!9h#&cS5.ZZL, -'VlJ3iՊh i3 GQElv#ou{ѡ$w79]I9M흭g&RV yAE[K1g=Ġ)U@P3ϲW>vtih07q8LiT-CsuNjOmb3T8'W^ HRoJY_[[9^aǠVquL;n6Mڜ\Fݚ^ UFȄ^L[9QP]kfztiG..b/a-u(uais!W8a*LT +bw!lw?}HƜi!굯$f٠Nm7|FLq!>^aW`KRiLJ4Oh*`>Mґ${;;n \tR.u&?eguFū"Z|bU- FIhBDd/i?@Չ:v4_Xy3Uxq/axnv- D7;* Ϟ)C*ù˼`2f`Dc2O\[5F},@{wr\ƿV|vɇuk.ǹ^f|&o8=) |p:Y$ӡg]mXY *_!R&J,7@|&DraculaxڵX5Y6 N܅'Bu B& zfg<Ǔ*ttSPЦF \6o<;\{<}ʓ2鿫W*R|!꧁zCGVpm㧕`Z31<߯` UϚZ]F`U0Em6` 1%t}mw,ODM_썯U3o3[Ȍ suSeӨN;a3=%8b£bWAQHSA `Qb਩hNd.( Zw,,z*O@ bB#_:|-C6o?O?;;+ST$A)pjU4dpxe&8)mvM,oJ%0  ѹ3G0y,uzכ0@ű"5 ʄ"]H"83l1x KTBݮEGʕ)H*f_GT \ ЪiTM{L<;Q# y^ظ/5rGC(kDwkrk9RNɝ;Y)Kx!.!Bp}1fuRNIUGkuMe31HO6 Gg]C>k'ɠv>M8Ƈ^){}Bf$@8.}GڶJMZ',kЖA5^tƑBWtJ;a!Ei4[d&ppa(ne 6h )7`%&IjJ!02SZpE}e[bޚ!4CU"6S MxUv(YC*򑂔$$7(Tɪ  "ZxLAN7z`2wS֕`lhL=Ko1'(R?tŋ+VwmFiU1|r]Q!ϚZsDžs QsMHZ U:L,e[t3/ "4 ĢMVXl0 CQQjAPp!NRiD&cEȯ"#x ˎbIA#a IˠlrE&PqExZb-@?IʤEac"Yz /XR=(BȊh8LF٩)ʵ,GeѾjFNuj:)CϷERgܕ)XɻqxeOOO*BBP0PF#ߋ".;O("@.5qUgjFP;cԯsG2 ]ސ&se5,~ cG*XWd1$SVt|4+9 ]1 Tft1t`%oRA#8L)iBZcXCYьAKr]>VcEGrG^2exW᭞Dˍʹ{2dl9a!~*U_S ɞUf}4!=d1 ֙l+`j$2ddKKHr󧥇r6mgmy&\YXv%$y}!#gCC 1 } 6Oeθbۜ^U)ig&Oi9&$*[D%"Un$bJojjO'ˉkHbT7,Yf '|8ar]co)V-\Xl޲lvCYxטP> ;t3]M h,U2 Q A -8 }`xCDwW+J(%\*UE);ֵ];I .ũ6;V^N5tg3jjm,vYބFP-VaC)iwG Ǎv%Z Irh}&Q {x@1Ӭ 7̪6c 5 tD|(GΏp #c_5uLjtg 3kin@mЍd<# iǔ]>jo鹆4T,f@&&.*wLt */M v|˜0^C+MPG_)HG0 xXv,B"4V C -\q$ 餏ERmv +0*qvgX>%QN,B0Ζidigwֽ2yq]rS;BM?ȹd$pU'G,q^fi.b6Z8\="5a(-K$+7zSȀ%vp :4RZqHjdjc>E%gh8l鼍>(Ǣ>x#ݡCIw::::{榧$> RZTUf. lޢ"g!sŠ%ɼ1T#k$n0n@saT(OOe])@k/}K|LMqO)`ܿ C #q,DW)57-Bk~[aҌVyᨀ @s&cjJi.? -\29}H=7awZ,cZjrrá{`hJ3߭g$z{LC?g&Ϊ(\~Wצr! >gPo?l a2'Q>[k#0*g(/N')a#鷞폘 /j`]긤x&(M3KݓϠ+h5pk[M1$C5+e]s^J}YӾJ4 }j tB'?h5WmO{sН\VIiᷕPң.a?s}va,؟+<|ˀ)(4e8)r'OX0y[o^bʊ Pͅ0O)ZMonokai Extended BrightxڭY=D^p!.EJBDB(@ 2" Ѭ=;qrWD"%- ] J"!@A @Ό=ڳ3c^X7ޛތ~p4h5 scj_ F;N\Ff,/>,;~ LԺBfefֳ2֭[対fRo V+W7 Ci:NGׄ_R 0upBJk_)𡄷52\ IOxJFDtt I45t*viCY76`-O%gY)bZcڂ{?ΉG9y|Ӝ2,itUWXk W(;!Zf,?7 , ,yw`8ہFpru l][nX@Y&e 3o&ݚ^nE)IDxQKiĴʛr_pJ;Oֵyh4iɂN2d2żS[hNZ͹KR6د-0cTb|ac9Ѽrh X' 3 ;}ϳgb>Ԙr w:/824Y35ҶQzw32A_IPY"'YL'FâZ D}<Y?_,OW zqK9} A,o0핲e5g=&xRrmЕ4w˙4n^Q&S.!=e^- r'9[N4LhîAxhbwtϷ*9 vYW˶LKJEv|rx67j,[,O3g۷`qͩ' >3oA8 ;2WR]#zOiܐRhTDLT\qןl$Uoy~PT?۳KI}Ok??ѼmRηzk&ݷ t*+q R`ԍ hķe$&U8E 8  G,s8Yyh0f<%Kx К"`])Y@:}g`q7J#NZ׊=-xQdnxda ( ˲8x::Pf\ey&ahqV޶xQnZx&VhÉn\Q$$GC 纖6˪(r7Y Y~`sFw,yIy.a-^# Fk/# Z{@&`^tym[!kV@^66*{` 3ޮvBDH]y}PN$~0OOc k ޣZy&;irNe)}~bn 6IR!9p4o}Jڜ$m7^7*'%y4cF~w֠і2BzBc1B(,atNvqDT'm)qj4f`+=&"غ\^#"^‡XIkx7L* &Z4<Nt"施nNM ̌{\8u!2<,C=fTj.fcii~L,N(Db.$Ⓥ6.N[bC$04%QP <CT% C(OگEX hdGey0"{#YU0Xd՚V@x=i\N4XkK`)b#Ɂx< g(C*r)u|8FQ*·ģ>΄u;-ݶ YOgϸR)87LGͣw@Pryi()Ҫ J[#^\slسxp700n] Ѭ* 5ߑaV^/MM '\߰?}N<ݰmQ^6Osm;kϜ:v$(L$z}yۦLטUy,M88x:l۔kf9XFl[KʺH펝Лi.idv}ܻ:4RZe& Yg>#$L}D0Lîa=5wnrp7-ґlwyM⽞ka; 3W9 ^*3Ώ3 ]S]͍/qWi`w8"ȬC 5N;NGJ"\3z`TQt>f-yx)Bkf(>Mn~M>M^M>6 &H})Qt}[O%y f#Ϻ\-[,4ia=l^.o`6 H'Z]V֍3WϙDo_"GԕejcE$*؏%9juٰ_#4F3aZ .*|V7@\ _~ZO\FRt3{ͨMHG"bm>-!wWFW$ &_$3mk^ d9JIBD2(l'BVW0&y^Xt!?%yU߻¦X59'^W’ԉe&vuyXGR'`N`eƌ%\e#?-ZΈX" J} i6n>eu =cgQNo_Ci me~Z%[, We8H'U0A@CM  œ2EVN-쾧|% l YF=Kv5eFx0*fd~9ϗh/V˹ 8(n@/08DP뺂q%R C+k#Axo}I$\U{*%ب*ѐ¹}Yuo]@ K^xnIĵdpp8> bt8Ӑ ^E a P#! v񣬢Jt;ʯ Qn7,-(8_0g6v&U9H&FX,pYiOάuo#fYJm97iʏq NX%#01N!NcB2R#U Л_lHB,yO$GA#{a%a_v`e7e-BP> ɒ_<U(&_РQhRӑLGkϡmr7~t4E$>ÛUQ3PP@Tu Ѻ ;'Y"N1$UҾ(%kкm aa5š?rii]n9좨p(&x^-M9o db\3kjL*ږXj Oa/ƅi6~R]gO+DO F6b'CT@'&8e*Ӈ(6UQ6! 7vц)9@umO2,{S{D&m:|ζu).|Vg(WV}t́Ln^Mxf-TOhI0m7|X4)LOQ[I^1!\A-/!`ΡҎ(Ub=EIXO:\+3+f1UbǜpC+c ;pt"|ri=v;kMӟo7J3"!~!UЏ@}sL@O@?_tI$h+?&lӯ|NUْ+\B6bB绖+'6a}[nL\h&4W8b-/GuxN֭3ϛD_v }^ clcp`0O,UK[Yš1-E>{.qY勒›>XxjeڦU= K*:AIponu4p\BULQ,?\#H wѮHܼd/(1.#ieS-l2R|pd;uJ; (׌&vuY4_MܧpM0_Eׁ2o9LD:\--Z}#,&*z0W&WYrWjOVN}h &U?˓Íq[9J 5,*PIfDs=|Е% 1g uO-J!`KmfNorde x[;#Iq>cwAp?(uiuuW<lL, x؜q&>8CVWu^-1jI_feeefeaVD{wCcREq6q5 |=}h'tŸ>gW= ͣT//ҡA=.h k-8%ð]WiH*D, "<Ӹ~T(jEmy%A) j8lgS+4~ c>\.CpןZp8YF/$…'-P;ڌ[\)Z LPY[kKRT!:jzRW- }1`eᰏekdrfGq cIFݴF1AY Fud's\{開+rQCcUDi 8+{02N% 1wծ1=Jq$oSrAC r>Vs8v0-q!_G8"q|!GL=%XedOYrq}n]AD@a2+<c J1RhZf2Yqo9 YfQPsh7恖F6H$Uʈ`}9c{Aeݖ'T9=NkUNsnJwk{(`UDR:kai0/H $Ҝg|Y~L:E8`33| ]&Jx:@S0RcUE'=^,*LƩ;G`a(#i^d,?m;F*,<>>62 ~|!/a0մ{-4x]ٓ jV4碲#G(3,KpxKfVցYPVɿT@O-*8 fnDxIkj?p`wjѦeSs]P!:yfo^] m^y)7c;feN&#h nө|ӓn6t=:M'!Nk^"‡vsJ+5BIQ8L0pdK%0ȋh#U/rC-Ȣ^FOcm2/|8R+GLvjtX^kЏZb,ۮ^ בC-d=LoZB~Aڐڱ'~J+z[V߷zgyzڈ1"k&R+wEPY_H0w@ XmdgzLIOqG]\8.zWbD- OneHalfDarkExWn1&$B(TP @B9ۛS!QP Q#xPon׷$yox[>9PNïц,fkCbN7U7طiQ]VYl NHCA{ͻ̯k%f%ZR٨d&<@3r&u{0u3i(h㥱n/g~DWD-'!wtIT$4]:6DEٲ;PL_.6-Z@v'jH-K*ϵDd- K_TeyM$^+zXgҪI}: 'sp ɝ_[k [s_ςL:3fSF4$jálxMu aM:>~nze ژ唏4 R e;| BӞd0O 'wŮ OneHalfLightKxW=OA (P11ƨ&& 773[&jL,hM,9vmfovy9g> cڹml)Zl#%(΄yG]x49R%ɥX"Jr',)cdCnQ\iGi.q jfBAj^JH%aF N31ӈ]ĭ鳩heA-%k %:s4KIՒ^A68[#k(GҵkNۊe 3iZ]tȶ9RNsfjrU]_1$%aɌ,E,f%CQrI'ujf;>UV hl/~'D#{|&zXd*|2`U\ %Ws'M\x"MIomSic:j%Q.4UHiMҷSc!K6}^iɻ x9g߹ &n9W 4.&x0eLzWg}nV ۛ"j根 ]rNk]3^=D(ɱi*we~(ptܴtb[d٭Solarized (dark)xڵZKoE&QKiڦi6ͣ-ҦV*R%\ᆐ8w'mvgM 7*#1o n|N|3y9u~8X4OiX%>;z4^Y0x,΂փ==HO>/I}E\(y}F41e3 c|1RJͦYV,%IO 2 F *ƈ,e m謩tҨ_}Q6wX`XxXHR/g$5Jfk s#<9,g9eKҼ2RےѬ%bBXQ! @i5ϰowǰ$.y[eOi(yF/g Ee&ĖPVc0VZt\آœaYS DnsjPKZMBr/I+i={Zx()TAL-[ZMAV8E/R/8־0Ƈ)I|в.teR}Q 0.K<żTeE5RV9) >6ڴ󺪬v"[*TuM(Qbm|qg&#U,xLfݭLhx)1~I-wmUbZq-MF I MReeC1=Iu4%PΌ+`9)hk!CaJ,d5{ӽgw*磍9D60RPa㷦~;k4R@G9l[@ I% XKisBmPbl-! _Z VJ|)ITQtT*E83rTqO43\ ]Y}cQ׊!殊nꫂJ[` Q᳻9k"7Ȉ+y/9^LvwYp?2G YGf\0 {eCtHXu۶ *,5t]z5:,&vuYSe+-L2:5hʧ*-{( ~R2(-r3zrvEW э;iʻ>ɤ?Lg|4{߹?I6i{^YS3YI3,[o>3\ a2[@%p,Jwy 0 F2G,Erjm\R%a.}| vEtXpXPRO{SD ų}ߺSu?=j%ISVmvh1vPgطnVUM}\ڼ[eOi*)YF/f EEĖP#0LH2:ku-+.ʏMi qQP)e ,+NMbVTVNaLqզUeu5ߴ1RԤEk˧' ,5q~ 8!jdc2+Ck*TrioV:!G d8ׄ+%ˎ\8LP:ȓTHɬ B)ƽ2BV7{vR'ϾȆƐUzQz8j(fߪb8}O_(>MĞ6 q)(!OZB):ŭ`tۗDšMщjLGBԏ#)n1S*Ch7ݍ@<#eؕ96kubXO銾*Ua1&p>S-bS^ykh/PCQ蕢!N!kw ]skudCбw_>MNjX<mRMg٥'X| mhW5UV쾂m܂8CPvXhOQ|ҲXOr'!<(F85?۪'7mQtC  yӞH;M#IqDPt@H4HtTӳu8{?~͜s>wu6\PǷOX>uĹs$q6_{3/w)_ϛsq<n8nъ%UX$IK@EBVAQdS`p9r:csW#Q>Fd!tyK*!7+ӡ-׫@TnN#Y0X@0G_x,_o7Y.jFvdj_4P kAFBfӋ Ri3- Ł-ٷ;1"WfBps;4Mw>W{n#@lcѐꍙcYbcB%;5hz*k3m˕bAh-_+h"` riρߵr җW-hi-Gu1]Aoޫ鄨KV eHκt $Xnk!tږ-)|mùT8 a?Ȼs䧳9D> Ac+UC@؃ +jWu>TA5{?Ld.&*6_O''i,%x`8}IҊB>R )χڅ\ׄH.GDY#sܝѵZ Lqp iFR/,N3tElRpDc4=?{.fFQ< w$% <UN8 +JJXJ"mKjvu.A(]8GLf:k/ʻ ۞e4m2tdGZ׼54-츄 Th. յt[,jc17?#*%y0ćlx<[mIGNt}b%zPs{(ZCS{#<-6O†kjRBS00UIFLىm1ى:dώm*W=mceC2͕nB9̩f7S cԁah()F9~-\MU y@2 gf5_6zlvuAYgް#v%=$J3xΦYzy#v3 ~Ե[_GgNX'DznQ^ۑӧU3VBjX^La8olmtP]4r:>lv*l+@3NGHv]si^;a,cJynq\;~H dVisual Studio Dark+HxڽX=o$5΄"\`u|>$@+$ 83ڃ%4pM4@C(N]tW¯OI4F >IS.mLj.]TXL+EuWGoe^հx>ӵUansixڵV]o0m6P%j !xJ=N㤉<_ޓDY}|u=lo~C^0[&Z0J]An\1VAFO3|ѮĮszE]bMG)K{` B~9jPCpL욃HCI%^UE!nm#wkc H]Dp ݸ܉$aXFozW8d4ś>H $R$tBn^z ,u*)O}zWsݤcf!3@*σl27f@l#%>ߏbm4pλbAb&"pFxso_4ܔ3 BowzT\_&4 }L*|O]h4S^0GvM\3-6ֳ[6v`>*=)6/O[; B"b<Y![;Ll&d_͇RP!pZ+FGb ')@rܶ@"XG~AeŸ"uo8&P .fڃ_gB+?#(>7 pON/A1H?pKԽbase16.xڵWMs04gB Rʕi=p '{h"K$#Dzk+04ʮCoI ƃ $~|21I)(z}!%g7&?O_f(9xlCpp[Nf4#3a T(EpVA&a41cē8]1ͭg;c'-u0oL*A{?\KW$~XwȌ3 95WO\!OQ'|҄Ww=-g;عuI fe/l̑5 |ȈpQ~2KS.Te;97H)̐VLH" Y}mμ7-J-TM񠾰MxeWZh})Fv\V sY}yc/7ʩ/*fRSedib a/Q5Wy+?m&o$gvVPQ^e"l2w5+&{m)$M0ڳ(bTN|@,4\ ĺ:fk9^*٘UdOByNuwO-4]^ܧ[VM\0)YVJju0JYC zkG8Cs_eis6lu~tQs52 ٿ>W.I,kIz˰xt_c- up 8Zcߓ๵8?}rsľD e)Zv\-v78FGr c?aZPsx>nTS< GE 2"ET_% []+ ș%R jԙIH!V_3'M @m9Sܭ/lx^'JCte./U sY}Gyc'7ʩ*f&4Wqihb aH”Shh{K WRqⱋB YcVQ][0BQL]F #J[ig}x gruvbox-dark"xڵ\͏G٘8q$f<$DIX8 \#53E D8D$NH Eą ꫧ^U:ln_zo׼t8z0::}0~MEgo8IVEU-˃Gq/G0 !#`}lw:o78ޥIkQʯ&E^g4̓8|m,uGQ&SR 9؍$^EH(_UEq4yc\9.,6i\HT.k$Ӎ^q~{%RŵzAN"%΋lP R"[>sby $ϛm5j:-A!̺qCN*bglW#i\th: y($V8Ɯ)4uPCЧ6d7:4RT {{R/0]Y~DQ,`C˥OZJ2B? IEh|a~A'l<3m_`,XL&tD#I@ї46b!JH <jjt5F9mhF+@k|Q_Ȃ,dϳ!eX%_#L˖dx4z <++4yMi֋M.×tUv\Tq![l74m Jm,$㶉i5 r?{0qh[I U;$eۢq H,rCIҀD\~H2g-s)JrW|p Ҩ$e--=[/^^ `UYU7Kdҋ*.$1Nr6ꗮOMdBiiY/yQy3Ti\.9Ͻ+95r&2oD .J}5<j[Ve=1Ig២N,tq&uD =6RjJo6Fq Q[yV+]6J-5nWctZMI#ԬmOȉK+ti.S wԓ5qՉF ]dBid%gY hϾgsZ7* X#nitBh0 yD$`z`ͧ ,IE`So:nȖ=~D 9( ,K\Oڇ_ՇkSh5[KM*WH0P?\F0vl(&~aU\.EşKuYDŽ<ʰr pj;T=i:Β(ۅBDUUVy]-vjMl.ŇXmu ٯ9kKbaFicAvY<pݴ:x{WObLRzmx*W\e7BUT94t`F|=u@}pmu4ǿus<. LEwfPSrdƬٵ L6lmcTX c|`UUn˾:$˝|S@ko8\[iv:(^@P:&\Ƞ v3˔R4|"I✂9$q&NfI2 T9?88Q47f4\!$CQƒc&x=3P`oTbbE:n!<pEdk0t0ޱm%|$+[%rea(L XgQ+Eқ8u=Cf.e}s140ʷEvEOթFw(E $ pӂ,I1lmqyǼ]HA2AIarMe B) qFy"UG|7: #{"g?;xm;5W5M1hA1v\h`F' 82sE[J1;# ߾y].q/~ .pk*'"LTsPޡz06;vYFDaBzױIs#ZOJrN93G| D`.c;MCG'u\bofmlffi;~79<`:"1496o=~\iʘ*֮6BKrIOmR="jۼU\^%a̅e]Dֽk: 0`oy@,mzl?T6F&ҺR D4~m{%Fs@a-0jRmM6,qBiqvg>z!T qoL`#RR Md֠xC^oa+7v=$qMUH`OxsRrˤ`M X5=~xI6Z8ᖑX_M)wSM3b-׵&{v5t"0$dmѺ$hۮ|JNp՚8hXrkmאLT->s;x3=e!Ad\%^?o a$p rpeBƎ1Nj9OMPyf}nQppQl>' ^6{yLYv4I ]7E:M ӷ^WeM }[3z'Gy mT. K38r(:0+S#um;sqTA$aO jcK*̼h+E멂8;m=H„?!3E}ڞ􄖯RnJjIG6,`8`xٶjCl۲"%7𓃻E |ޣENRD6ճN)mdm">& :FZv gruvbox-light!xڵ\͏GY;q8]g& i;Qb )$zkfj?BCܐ@sCp'WOWuuQvֻ~W{9_>ǣoټ7&i>>,hMh,G{ZOxd`xGy&_F0:y(O 'dNl T}E4=Xk ;,(}`la61aq*aoAj9Fzw+SQ#¤hZ.BPJlw4@YD(0ók8dmNViB18TIН"F_0FDi1"#ѽV+B a6Rm+KRXacMF}! . ̲\>OQAOFe-Ɉip <+4 YY֋M— lSvBT4`-1?^;-aX yĸylژgAZP4'>( &-~")]3FQcr( t;4Ca?I:!qLbE8EIN4*HQKK>'+eګ*< I~t4^[zN'x…Bbw1F|F,h~9ٸAv)TBbU0eɤ2ٵȁ|^˙a4a>{#V\Qjq?Q\Գ<&Mt1:AG(cdx푱JS*80KiZ*DAL\>xR+SnڕZi܎"_!r,aOiXo>Y1c#V$}b'k#F +s/dj2(=Ȗ+#Ю{ 洮ۡe:ɓSbws` rU. Wpdŕ iJ(L1157‘ĝ= 6M#Z ٢`ozH BϹe!nxXUb$~=9HxVbԖvnUȳ.5 $B5/gӇ@i7 B] 1Aࣳ.Gdgtšikj±PQ(j;KcX2n -[ V$"t'jQWNāQb{ 79#Om},s,ȭp]+X'V}Q'<ҿ͖Sd+KbFpu1)P*Y*xb:o0cLem j|þjheudUÜ/dJ:3SAѓE <`K}̚5aw݆-_;b:a=XU˦rg3W_}p(Z&h!ݴ;HLW"("fdPqnъcgu(X"ueoyNJ h,5$H1lP>O&@1ޖjC]'ʒƼƐ"~q>Jzpg쭀Q:,l~/2 PMOAfP]J>س+m1V1GUʳ,_r׶udqȽzs<]>vr" }x.݆f Vhn~1:u6Ԋvd0XKbBŸ RQ!?CTR0.o۷ ")H>(+ui@N@M, ЌuLTqY^6"z΂6Ƞϰ[n,3jZDcМq7Rc10_PX$ 82r?=ZJ1m7#߾΅mkxv@t0~Q]9)#ik:Ճ i߱ (0p' ;]L@Cz*TBcS8i3e4 0ΏVqwuj ;y:Vc/]L.dci,mzc7*U].BGrA"&cѶE+wm:ڲojgɲq+s!wYu5]̇6`oy@,mzll0Lu5:s \1׉izNJ}K沅.Zj!(F!>alxCW\Cvg>v!N:<7&pjyghz|Y3(:Q7z+v=$dLUHy'58uM6qCA~kgz:u !&8I6Z8᎑X_(SSMǩ7b-W#%˻n5rt"0$deѦ$XۮzJ՚8hXr c7״v#!-<ĭ^|v2{8Ck)>ssw8r1=XU[6>ll;=s{xht ^k&߲J1.G~m7p4G2˦=x/O)+35sIaVZ)a]cx=]uhOr>6څ8`)UwOab*adM?]jI]APcj:|EJ|I'J $+`©9.4*YODu,F˽<0pY2S|0f3#:v㨬' MIŸ(.TuY]V2Spvzڑ2 ;Bf y&WʜRtAGPb@0,($mD .9fr1 M{99 F7ʩ8'urV`Ԉ`ٻ:w15Xu|_, m[=/. em{GyQ_v'.=thRZka :DDcPx:n9՛ "goQf"^)^zJ̤T6oi2̶g hNƼI:1<{zenburnpxڭXMoD^"4)- i .^`G悈hNn؞j8(R 7 JA%퉈# ]f^x3v{d>~<:}>BI(ֲoB l{ՃC g[qz롏6Xža`_JHutt4VVV`0ZÆ|}uXݖc0a;Cԋ%e d8$C-LpoDQDCqHs߿܀x:[^7YQu"/t\!f4ϙR,#`H~`͹yrÄr=h!0@,Th^ ˪ p &InTʙGb nR貉5 ~tF1iz $d= v )Ҁ[df|k8FI(ұ[bW"e3k81EU=ɺ}AIU)U"yR eD,׺PE\E1)nl^d=Nxv`n V^("u)/K*^U2̈́&Gʓb@QhT3Ԛ! K06bXB+H'_Zx]nF!?]Lg5+|}a `Ug75Mƶ4>cPJ{"S:#MN-I4W5Bb򚩽̽FĈ6Cj3x4FW.V,ڮIYN)מm)FYH?x:kx¶{L%dY`(͋Kj$ژaY sƒټ1e5%Ic8zmnNVQe?;nh/͟z+Ų5 jAp~.83yv Xx#b&Hz,w!Og1Ac`qhSz.g.v[ ^׺. M>6Ia c&'hYQ5ȟ/g0T O* 7' 5)^LkF/=/sS<]P0 ݦc6)g}Pkp/h4[X*?JE X|IO[ I/%CU^M" x/*H tC>B}E'Qy6'vjh/H(&EЅ}dDzO|T@AKf-ufѤˉ!.x]R,ڢP(XŽeS*SBT|KzWcs| _jY_uފ @턉-RTDc u&bat-0.19.0/build.rs000064400000000000000000000065000072674642500121570ustar 00000000000000// TODO: Re-enable generation of shell completion files (below) when clap 3 is out. // For more details, see https://github.com/sharkdp/bat/issues/372 // For bat-as-a-library, no build script is required. The build script is for // the manpage and completions, which are only relevant to the bat application. #[cfg(not(feature = "application"))] fn main() {} #[cfg(feature = "application")] fn main() -> Result<(), Box> { use std::collections::HashMap; use std::error::Error; use std::fs; use std::path::Path; // Read environment variables. let project_name = option_env!("PROJECT_NAME").unwrap_or("bat"); let executable_name = option_env!("PROJECT_EXECUTABLE").unwrap_or(project_name); let executable_name_uppercase = executable_name.to_uppercase(); static PROJECT_VERSION: &str = env!("CARGO_PKG_VERSION"); /// Generates a file from a template. fn template( variables: &HashMap<&str, &str>, in_file: &str, out_file: impl AsRef, ) -> Result<(), Box> { let mut content = fs::read_to_string(in_file)?; for (variable_name, value) in variables { // Replace {{variable_name}} by the value let pattern = format!("{{{{{variable_name}}}}}", variable_name = variable_name); content = content.replace(&pattern, value); } fs::write(out_file, content)?; Ok(()) } let mut variables = HashMap::new(); variables.insert("PROJECT_NAME", project_name); variables.insert("PROJECT_EXECUTABLE", executable_name); variables.insert("PROJECT_EXECUTABLE_UPPERCASE", &executable_name_uppercase); variables.insert("PROJECT_VERSION", PROJECT_VERSION); let out_dir_env = std::env::var_os("OUT_DIR").expect("OUT_DIR to be set in build.rs"); let out_dir = Path::new(&out_dir_env); fs::create_dir_all(out_dir.join("assets/manual")).unwrap(); fs::create_dir_all(out_dir.join("assets/completions")).unwrap(); template( &variables, "assets/manual/bat.1.in", out_dir.join("assets/manual/bat.1"), )?; template( &variables, "assets/completions/bat.bash.in", out_dir.join("assets/completions/bat.bash"), )?; template( &variables, "assets/completions/bat.fish.in", out_dir.join("assets/completions/bat.fish"), )?; template( &variables, "assets/completions/_bat.ps1.in", out_dir.join("assets/completions/_bat.ps1"), )?; template( &variables, "assets/completions/bat.zsh.in", out_dir.join("assets/completions/bat.zsh"), )?; Ok(()) } // #[macro_use] // extern crate clap; // use clap::Shell; // use std::fs; // include!("src/clap_app.rs"); // const BIN_NAME: &str = "bat"; // fn main() { // let outdir = std::env::var_os("SHELL_COMPLETIONS_DIR").or(std::env::var_os("OUT_DIR")); // let outdir = match outdir { // None => return, // Some(outdir) => outdir, // }; // fs::create_dir_all(&outdir).unwrap(); // let mut app = build_app(true); // app.gen_completions(BIN_NAME, Shell::Bash, &outdir); // app.gen_completions(BIN_NAME, Shell::Fish, &outdir); // app.gen_completions(BIN_NAME, Shell::Zsh, &outdir); // app.gen_completions(BIN_NAME, Shell::PowerShell, &outdir); // } bat-0.19.0/diagnostics/.gitattributes000064400000000000000000000000240072674642500157070ustar 00000000000000* linguist-vendored bat-0.19.0/diagnostics/info.sh000075500000000000000000000142340072674642500143160ustar 00000000000000#!/usr/bin/env bash _modules=('system' 'bat' 'bat_config' 'bat_wrapper' 'bat_wrapper_function' 'tool') _modules_consented=() set -o pipefail export LC_ALL=C export LANG=C BAT="bat" if ! command -v bat &>/dev/null; then if command -v batcat &> /dev/null; then BAT="batcat" else tput setaf 1 printf "%s\n%s\n" \ "Unable to find a bat executable on your PATH." \ "Please ensure that 'bat' exists and is not named something else." tput sgr0 exit 1 fi fi # ----------------------------------------------------------------------------- # Modules: # ----------------------------------------------------------------------------- _bat_:description() { _collects "Version information for 'bat'." _collects "Custom syntaxes and themes for 'bat'." } _bat_config_:description() { _collects "The environment variables used by 'bat'." _collects "The 'bat' configuration file." } _bat_wrapper_:description() { _collects "Any wrapper script used by 'bat'." } _bat_wrapper_function_:description() { _collects "The wrapper function surrounding 'bat' (if applicable)." } _system_:description() { _collects "Operating system name." _collects "Operating system version." } _tool_:description() { _collects "Version information for 'less'." } # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - _bat_:run() { _out "$BAT" --version _out env | grep '^BAT_\|^PAGER=' local cache_dir cache_dir="$($BAT --cache-dir)" if [[ -f "${cache_dir}/syntaxes.bin" ]]; then _print_command "$BAT" "--list-languages" echo "Found custom syntax set." fi if [[ -f "${cache_dir}/themes.bin" ]]; then _print_command "$BAT" "--list-themes" echo "Found custom theme set." fi } _bat_config_:run() { if [[ -f "$("$BAT" --config-file)" ]]; then _out_fence cat "$("$BAT" --config-file)" fi } _bat_wrapper_:run() { _bat_wrapper_:detect_wrapper() { local bat="$1" if file "$(command -v "${bat}")" | grep "text executable" &> /dev/null; then _out_fence cat "$(command -v "${bat}")" return fi printf "\nNo wrapper script for '%s'.\n" "${bat}" } _bat_wrapper_:detect_wrapper bat if [[ "$BAT" != "bat" ]]; then _bat_wrapper_:detect_wrapper "$BAT" fi } _bat_wrapper_function_:run() { _bat_wrapper_function_:detect_wrapper() { local command="$1" case "$("$SHELL" --version | head -n 1)" in *fish*) if "$SHELL" --login -i -c "type ${command}" 2>&1 | grep 'function' &> /dev/null; then _out_fence "$SHELL" --login -i -c "functions ${command}" return fi ;; *bash* | *zsh*) local type type="$("$SHELL" --login -i -c "type ${command}" 2>&1)" if grep 'function' <<< "$type" &> /dev/null; then _out_fence "$SHELL" --login -i -c "declare -f ${command}" return elif grep 'alias' <<< "$type" &> /dev/null; then _out_fence "$SHELL" --login -i -c "type ${command}" return fi ;; *) echo "Unable to determine if a wrapper function for '${command}' is set." return ;; esac printf "\nNo wrapper function for '%s'.\n" "${command}" } _bat_wrapper_function_:detect_wrapper bat _bat_wrapper_function_:detect_wrapper cat if [[ "$BAT" != "bat" ]]; then _bat_wrapper_function_:detect_wrapper "$BAT" fi } _system_:run() { _out uname -srm if command -v "sw_vers" &> /dev/null; then _out sw_vers; fi if command -v "lsb_release" &> /dev/null; then _out lsb_release -a; fi } _tool_:run() { _out less --version | head -n1 } # ----------------------------------------------------------------------------- # Functions: # ----------------------------------------------------------------------------- _print_command() { printf '\n**$' 1>&2 printf ' %s' "$@" 1>&2 printf '**\n' 1>&2 } _out() { _print_command "$@" "$@" 2>&1 | sed 's/$/ /' } _out_fence() { _print_command "$@" printf '```\n' 1>&2 "$@" 2>&1 printf '```\n' 1>&2 } _tput() { tput "$@" 1>&2 2> /dev/null } _collects() { printf " - %s\n" "$1" 1>&2 } _ask_module() { _tput clear _tput cup 0 0 cat 1>&2 << EOF -------------------------------------------------------------------------------- This script runs some harmless commands to collect information about your system and bat configuration. It will give you a small preview of the commands that will be run, and ask consent before running them. Once completed, it will output a small report that you can review and copy into the issue description. -------------------------------------------------------------------------------- EOF # Print description. _tput setaf 3 printf "The following data will be collected:\n" 1>&2 _tput sgr0 "_$1_:description" _tput sgr0 # Print preview. _tput setaf 3 printf "\nThe following commands will be run:\n" 1>&2 _tput sgr0 declare -f "_$1_:run" \ | sed 's/^ *//; s/;$//' \ | grep '^_out[^ ]* ' \ | sed 's/^_out[^ ]* //' \ | sed "s/\"\$BAT\"/$BAT/" 1>&2 # Prompt printf "\n" 1>&2 local response while true; do _tput cup "$(($( tput lines || echo 22) - 2))" _tput el read -er -p "Collect $(sed 's/_/ /' <<< "$1") data? [Y/n] " response case "$response" in Y | y | yes | '') return 0 ;; N | n | no) return 1 ;; *) continue ;; esac done } _run_module() { local module="$1" printf "%s\n%s\n" "$module" "$(printf "%${#module}s" | tr ' ' '-')" "_$1_:run" } # ----------------------------------------------------------------------------- # Functions: # ----------------------------------------------------------------------------- # Tell the user if their executable isn't named "bat". if [[ "$BAT" != "bat" ]] && [[ "$1" != '-y' ]]; then trap '_tput rmcup; exit 1' INT _tput smcup _tput clear _tput cup 0 0 _tput setaf 1 printf "The %s executable on your system is named '%s'.\n%s\n" "bat" "$BAT" \ "If your issue is related to installation, please check that this isn't the issue." _tput sgr0 printf "Press any key to continue...\n" read -rsn1 _tput rmcup fi # Ask for consent. if [[ "$1" == '-y' ]]; then _modules_consented=("${_modules[@]}") else trap '_tput rmcup; exit 1' INT _tput smcup for _module in "${_modules[@]}"; do if _ask_module "$_module"; then _modules_consented+=("$_module") fi done _tput rmcup fi # Collect information. for _module in "${_modules_consented[@]}"; do _run_module "$_module" 2>&1 printf "\n" done bat-0.19.0/doc/README-ja.md000064400000000000000000000624420072674642500131350ustar 00000000000000

bat - a cat clone with wings
Build Status license Version info
シンタックスハイライトとGitとの連携機能付きの cat(1) クローン。

特徴使い方インストールカスタマイズプロジェクトの目標と既存の類似したOSS
[English] [中文] [日本語] [한국어] [Русский]

### シンタックスハイライト `bat` は多くのプログラミング言語やマークアップ言語の シンタックスハイライトに対応しています: ![Syntax highlighting example](https://imgur.com/rGsdnDe.png) ### Gitの統合 `bat` は `git` とも連携しており、差分を表現する記号が表示されます (図の左端): ![Git integration example](https://i.imgur.com/2lSW4RE.png) ### 印刷できない文字の表示 `-A`/`--show-all` オプションをつけることで 印刷できない文字を可視化できます: ![Non-printable character example](https://i.imgur.com/WndGp9H.png) ### 自動ページング 出力が1つの画面に対して大きすぎる場合、`bat` は自身の出力をページャー(例えば `less`) にパイプで繋げます。 ### ファイルの連結 あなたはさらにファイルを連結させるために使うことも可能です:wink:。 `bat` は非対話型のターミナルを検出すると(すなわち他のプロセスにパイプしたりファイル出力していると)、 `bat` は `cat` の完全互換として振る舞い、 プレーンなファイルを表示します。 ## 使い方 単一のファイルを表示させたい場合 ```bash > bat README.md ``` 複数のファイルを一度に表示させたい場合 ```bash > bat src/*.rs ``` 標準入力から自動的に構文を決定させたい場合(ハイライトされるのは、 たいていは `#!/bin/sh` のようなシバンを利用して、 ファイルの一行目から構文を決定できる場合のみです) ```bash > curl -s https://sh.rustup.rs | bat ``` 標準入力から明示的に言語を指定したい場合 ```bash > yaml2json .travis.yml | json_pp | bat -l json ``` 空白文字を可視化させたい場合: ```bash > bat -A /etc/hosts ``` `cat` の代わりに `bat` を使用する際の例: ```bash bat > note.md # quickly create a new file bat header.md content.md footer.md > document.md bat -n main.rs # show line numbers (only) bat f - g # output 'f', then stdin, then 'g'. ``` ### 他のツールとの統合 #### `fzf` [`fzf`](https://github.com/junegunn/fzf) のプレビューウィンドウに `bat` を使用できます。 その場合、`bat` の `--color=always` オプションを用いてカラー出力を強制しなければなりません。 また、`--line-range` オプションを用いることで巨大なファイルの読み込み時間を制限できます: ```bash fzf --preview 'bat --color=always --style=numbers --line-range=:500 {}' ``` 詳しくは [`fzf` の `README`](https://github.com/junegunn/fzf#preview-window) を参照してください。 #### `find` or `fd` `find` の `-exec` オプションを使用して、`bat` ですべての検索結果をプレビューできます: ```bash find … -exec bat {} + ``` [`fd`](https://github.com/sharkdp/fd) を使用している場合は、`-X` /`-exec-batch` オプションを使用して同じことを行うことができます: ```bash fd … -X bat ``` #### `ripgrep` [`batgrep`](https://github.com/eth-p/bat-extras/blob/master/doc/batgrep.md) では、[`ripgrep`](https://github.com/BurntSushi/ripgrep) 検索結果のプリンターとして `bat` を使用できます。 ```bash batgrep needle src/ ``` #### `tail -f` `bat` を `tail -f` と組み合わせて、構文強調表示を使用して特定のファイルを継続的に監視できます。 ```bash tail -f /var/log/pacman.log | bat --paging=never -l log ``` 注意事項:`tail -f`と組み合わせるには、ページングをオフにしなければなりません。また、この場合は構文が自動検出されないため、明示的に指定(`-l log`)しています。 #### `git` `bat` を `git show` と組み合わせて、 適切な構文強調表示を使用して特定のファイルの古いバージョンを表示できます: ```bash git show v0.6.0:src/main.rs | bat -l rs ``` 差分内の構文強調表示は現在サポートされていないことに注意してください。 これを探しているなら、[`delta`](https://github.com/dandavison/delta) をチェックしてください。 #### `xclip` `bat` の出力の行番号と Git 変更マーカーにより、ファイルの内容をコピーするのが難しくなる場合があります。 これを防ぐには、`-p` / `-plain` オプションを使用して `bat` を呼び出すか、 単に出力を `xclip` にパイプします: ```bash bat main.cpp | xclip ``` `bat` は出力がリダイレクトされていることを検出し、プレーンファイルの内容を出力します。 #### `man` `bat` は `MANPAGER` 環境変数を設定することにより、 `man` の色付けページャーとして使用できます: ```bash export MANPAGER="sh -c 'col -bx | bat -l man -p'" man 2 select ``` フォーマットの問題が発生した場合は `MANROFFOPT="-c"` を設定する必要もあります。 これを新しいコマンドにバンドルしたい場合は [`batman`](https://github.com/eth-p/bat-extras/blob/master/doc/batman.md) も使用できます。 [Manpage syntax](assets/syntaxes/Manpage.sublime-syntax) はこのリポジトリで開発されており、まだ作業が必要であることに注意してください。 #### `prettier` / `shfmt` / `rustfmt` [`prettybat`](https://github.com/eth-p/bat-extras/blob/master/doc/prettybat.md) スクリプトは、コードをフォーマットし、`bat` で印刷するラッパーです。 ## インストール [![Packaging status](https://repology.org/badge/vertical-allrepos/bat.svg)](https://repology.org/project/bat/versions) ### On Ubuntu (`apt` を使用) *... や他のDebianベースのLinuxディストリビューション* Ubuntu Eoan 19.10 または Debian 不安定版 sid 以降の [the Ubuntu `bat` package](https://packages.ubuntu.com/eoan/bat) または [the Debian `bat` package](https://packages.debian.org/sid/bat) からインストールできます: ```bash apt install bat ``` `apt` を使用して `bat` をインストールした場合、実行可能ファイルの名前が `bat` ではなく `batcat` になることがあります([他のパッケージとの名前衝突のため](https://github.com/sharkdp/bat/issues/982))。`bat -> batcat` のシンボリックリンクまたはエイリアスを設定することで、実行可能ファイル名が異なることによる問題の発生を防ぎ、他のディストリビューションと一貫性を保てます。 ``` bash mkdir -p ~/.local/bin ln -s /usr/bin/batcat ~/.local/bin/bat ``` ### On Ubuntu (最新の `.deb` パッケージを使用) *... や他のDebianベースのLinuxディストリビューション batの最新リリースを実行する場合、または Ubuntu/Debian の古いバージョンを使用している場合は、[release page](https://github.com/sharkdp/bat/releases) から最新の `.deb` パッケージをダウンロードし、 次の方法でインストールします: ```bash sudo dpkg -i bat_0.18.3_amd64.deb # adapt version number and architecture ``` ### On Alpine Linux 適切なリポジトリが有効になっている場合は、 公式のソースから [`bat` package](https://pkgs.alpinelinux.org/packages?name=bat) をインストールできます: ```bash apk add bat ``` ### On Arch Linux [Arch Linuxの公式リソース](https://www.archlinux.org/packages/community/x86_64/bat/) からインストールできます。 ```bash pacman -S bat ``` ### On Fedora 公式の [Fedora Modular](https://docs.fedoraproject.org/en-US/modularity/using-modules/) リポジトリから [the `bat` package](https://koji.fedoraproject.org/koji/packageinfo?packageID=27506) をインストールできます。 ```bash dnf install bat ``` ### On Gentoo Linux 公式ソースから [the `bat` package](https://packages.gentoo.org/packages/sys-apps/bat) をインストールできます。 ```bash emerge sys-apps/bat ``` ### On Void Linux xbps-install経由で `bat` をインストールできます。 ``` xbps-install -S bat ``` ### On FreeBSD pkg を使用してプリコンパイルされた [`bat` package](https://www.freshports.org/textproc/bat) をインストールできます: ```bash pkg install bat ``` または FreeBSD ポートから自分でビルドすることもできます: ```bash cd /usr/ports/textproc/bat make install ``` ### Via nix `bat` を [nix package manager](https://nixos.org/nix) 経由でインストールすることができます: ```bash nix-env -i bat ``` ### On openSUSE `bat` をzypperでインストールすることができます: ```bash zypper install bat ``` ### On macOS [Homebrew](http://braumeister.org/formula/bat)で `bat` をインストールできます: ```bash brew install bat ``` または [MacPorts](https://ports.macports.org/port/bat/summary) で `bat` をインストールします: ```bash port install bat ``` ### On Windows Windowsにbatをインストールするいくつかのオプションがあります。 batをインストールしたら [Windowsでのbatの使用](#windows-での-bat-の利用) セクションをご覧ください。 #### With Chocolatey [Chocolatey](https://chocolatey.org/packages/Bat) から `bat` をインストールできます: ```bash choco install bat ``` #### With Scoop [scoop](https://scoop.sh/) から `bat` をインストールできます: ```bash scoop install bat ``` [Visual C ++再頒布可能](https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads) パッケージをインストールする必要があります。 #### From prebuilt binaries: [リリースページ](https://github.com/sharkdp/bat/releases) からビルド済みのバイナリをダウンロードできます。 [Visual C ++再頒布可能](https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads) パッケージをインストールする必要があります。 ### Via Docker コンテナ内で `bat` を使いたい方のために [Docker image](https://hub.docker.com/r/danlynn/bat/) が用意されています: ```bash docker pull danlynn/bat alias bat='docker run -it --rm -e BAT_THEME -e BAT_STYLE -e BAT_TABS -v "$(pwd):/myapp" danlynn/bat' ``` ### Via Ansible [Ansible](https://www.ansible.com/) でインストールすることができます: ```bash # Install role on local machine ansible-galaxy install aeimer.install_bat ``` ```yaml --- # Playbook to install bat - host: all roles: - aeimer.install_bat ``` - [Ansible Galaxy](https://galaxy.ansible.com/aeimer/install_bat) - [GitHub](https://github.com/aeimer/ansible-install-bat) これは以下のディストリビューションで動作するはずです: - Debian/Ubuntu - ARM (eg. Raspberry PI) - Arch Linux - Void Linux - FreeBSD - MacOS ### From binaries 多くの異なるアーキテクチャのためのプレビルドバージョンを[リリースページ](https://github.com/sharkdp/bat/releases)からチェックしてみてください。静的にリンクされている多くのバイナリも利用できます: ファイル名に `musl` を含むアーカイブを探してみてください。 ### From source `bat` をソースからビルドしたいならば、Rust 1.51 以上の環境が必要です。 `cargo` を使用してビルドすることができます: ```bash cargo install --locked bat ``` 一部のプラットフォームでは `llvm` および/または `libclang-dev` のインストールが必要になる場合があります。 ## カスタマイズ ### ハイライト テーマ `bat --list-themes` を使うと現在利用可能なシンタックスハイライトのテーマを入手できます。 `TwoDark` テーマを選ぶためには `--theme=TwoDark` オプションをつけるか `BAT_THEME` という環境変数に `TwoDark` を代入する必要があります。 シェルの起動ファイルに `export BAT_THEME="TwoDark"` と定義すればその設定が変わることはないでしょう。あるいは、 `bat` の [設定ファイル](#設定ファイル)を利用してください。 カスタムファイルでさまざまなテーマをプレビューする場合は、 次のコマンドを使用できます(これには [`fzf`](https://github.com/junegunn/fzf) が必要です)。 ``` bash bat --list-themes | fzf --preview="bat --theme={} --color=always /path/to/file" ``` `bat` はデフォルトだと黒い背景色のターミナルに適しています。 しかし、`GitHub` や `OneHalfLight` のような白い背景色のテーマでもいい感じにすることができます。 ['新しいテーマの追加' セクションに従って](#新しいテーマの追加) カスタムテーマを使用することもできます。 ### 出力のスタイル `--style` を使うことで `bat` の表示の見た目を変更することができます。 例えば、 `--style=numbers,changes` と入力します。 すると、Gitの差分と行番号だけが表示され、グリッド線とファイルヘッダーは表示されません。 環境変数に `BAT_STYLE` を定義するとこれらの設定を永続的に使用することができます。 [設定ファイル](#設定ファイル) を参考にしても良いでしょう。 ### 新しい構文の追加 / 言語の定義 `bat` はシンタックスハイライトのための [`syntect`](https://github.com/trishume/syntect/) という素晴らしいライブラリを使用しています。`syntect` は、 [Sublime Text の `.sublime-syntax` ファイル](https://www.sublimetext.com/docs/3/syntax.html) とテーマを読み取ることができます。新しい構文を定義するために以下の手順を行います。 構文定義ファイルを入れておくためのフォルダを作ります: ```bash mkdir -p "$(bat --config-dir)/syntaxes" cd "$(bat --config-dir)/syntaxes" # Put new '.sublime-syntax' language definition files # in this folder (or its subdirectories), for example: git clone https://github.com/tellnobody1/sublime-purescript-syntax ``` 次のコマンドを使用して、これらのファイルをバイナリキャッシュに解析します: ```bash bat cache --build ``` 最後に `bat --list-languages` と入力すると新しい言語が利用可能かどうかチェックします。 デフォルトの設定に戻したいときは以下のコマンドを実行します: ```bash bat cache --clear ``` ### 新しいテーマの追加 これは構文を新しく定義するやり方と非常に似ています。 まず、新しいシンタックスハイライトのテーマのフォルダを作ります: ```bash mkdir -p "$(bat --config-dir)/themes" cd "$(bat --config-dir)/themes" # Download a theme in '.tmTheme' format, for example: git clone https://github.com/greggb/sublime-snazzy # Update the binary cache bat cache --build ``` 最後に、 `bat --list-themes` で新しいテーマが利用可能かチェックします ### 異なるページャーの使用 `bat` は環境変数 `PAGER` に使用するページャーを明記します。 この環境変数が定義されていない場合、デフォルトで `less` が使用されます。 もし、異なるページャーを使用したい場合は、`PAGER` を修正してください。 または、`PAGER` を上書きする環境変数として `BAT_PAGER` を定義することも可能です。 もし、ページャーにコマンドライン引数を渡したい場合は、 `PAGER`/`BAT_PAGER` 環境変数を定義してください: ```bash export BAT_PAGER="less -RF" ``` 環境変数を利用する代わりに、 `bat` の [設定ファイル](#設定ファイル) を使用して設定も可能です(`--pager` オプション) **注意**: デフォルトにより、ページャーが `less` にセットされているならば `bat` はページャーの以下のコマンドラインオプション を受け付けるでしょう: `-R`/`--RAW-CONTROL-CHARS`, `-F`/`--quit-if-one-screen` そして `-X`/`--no-init`。 最後のオプション(-X)は、530 より古いバージョンにのみ使用されます。 `-R` オプションは、ANSIカラーを正しく解釈するために必要です。 2番目のオプション(`-F`)は、出力サイズが端末の垂直サイズよりも小さい場合、すぐに終了するようにlessに指示します。 これは、ページャーを終了するために `q` を押す必要がないため、小さなファイルに便利です。 3番目のオプション(`-X`)は、`less` の古いバージョンの `--quit-if-one-screen` 機能のバグを修正するために必要です。 残念ながら、`less` のマウスホイールのサポートも少なくなります。 `less` の古いバージョンでマウスホイールのスクロールを有効にしたい場合は、 `-R` だけを渡すことができます(上記の例のように、これは1画面終了機能を無効にします)。 530以下の場合は、そのまま使用できます。 ### Dark mode macOSでダークモード機能を使用する場合、OSテーマに基づいて異なるテーマを使用するように `bat` を構成することができます。 次のスニペットは、ライトモードの場合は `デフォルト` のテーマを使用し、 ダークモードの場合は `GitHub` テーマを使用します。 ```bash alias cat="bat --theme=\$(defaults read -globalDomain AppleInterfaceStyle &> /dev/null && echo default || echo GitHub)" ``` ## 設定ファイル `bat` は設定ファイルでカスタマイズすることが可能です。ファイルの場所はOSに依存します。 使用しているOSのデフォルトパスを調べるには以下のコマンドを実行してください: ``` bat --config-file ``` または、`BAT_CONFIG_PATH` 環境変数を使用して、`bat` が 構成ファイルのデフォルト以外の場所を指すようにすることができます: ```bash export BAT_CONFIG_PATH="/path/to/bat.conf" ``` ### フォーマット この設定ファイルはコマンドライン引数の単純なリストです。 `bat --help` を利用すると、利用可能なオプションとその値を閲覧することができます。さらに、`#` でコメント文を加えることができます。 設定ファイルの例: ```bash # Set the theme to "TwoDark" --theme="TwoDark" # Show line numbers, Git modifications and file header (but no grid) --style="numbers,changes,header" # Use italic text on the terminal (not supported on all terminals) --italic-text=always # Use C++ syntax for Arduino .ino files --map-syntax "*.ino:C++" # Use ".gitignore"-style highlighting for ".ignore" files --map-syntax ".ignore:Git Ignore" ``` ## Windows での `bat` の利用 Windows 上で `bat` はほとんど動作しますが、いくつかの機能は設定を必要をする場合があります。 ### ページング Windowsには、`more` 形式の非常に限られたページャーしか含まれていません。 `less` 用のWindowsバイナリは、[ホームページ](http://www.greenwoodsoftware.com/less/download.html) または [Chocolatey](https://chocolatey.org/packages/Less) からダウンロードできます。 これを使用するには、バイナリを `PATH` のディレクトリに配置するか、環境変数を定義します。[Chocolateyパッケージ](#on-windows) は `less` を自動的にインストールします。 ### 色 Windows 10では、`conhost.exe` (コマンドプロンプト)と [v1511](https://en.wikipedia.org/wiki/Windows_10_version_history#Version_1511_(November_Update)) 以降の PowerShell の両方、 およびbashの新しいバージョンの色がネイティブにサポートされています。 以前のバージョンのWindowsでは、 [ConEmu](https://conemu.github.io/) を含む [Cmder](http://cmder.net/) を使用できます。 **注意:** Git と MSYS の `less` はWindows上で色を正しく解釈しません。 もし、あなたが他のページャーをインストールしていないのであれば、 `--paging=never` オプションを付け加えるか `BAT_PAGER` に空文字を設定することでページングを完全に無効にできます。 ### Cygwin Windows上の `bat` は Cygwin のunix風のpath(`/cygdrive/*`)をネイティブサポートしていません。絶対的なcygwinパスを引数として受けたときに、 `bat` は以下のエラーを返すでしょう: `The system cannot find the path specified. (os error 3)` wrapperを作成するか、以下の関数を `.bash_profile` に追記することで、この問題を解決することができます: ```bash bat() { local index local args=("$@") for index in $(seq 0 ${#args[@]}) ; do case "${args[index]}" in -*) continue;; *) [ -e "${args[index]}" ] && args[index]="$(cygpath --windows "${args[index]}")";; esac done command bat "${args[@]}" } ``` ## トラブルシューティング ### ターミナルと色 `bat` はターミナルがトゥルーカラーをサポートしている/していないに関係なくサポートします。 しかし、シンタックスハイライトのテーマの色が8-bitカラーに最適化されていない場合、 24-bitであるトゥルーカラーをサポートしているターミナルを使用することを強く推奨します(`terminator`, `konsole`, `iTerm2`, ...)。 この [記事](https://gist.github.com/XVilka/8346728) には 24-bitカラーがサポートされているターミナルの一覧が掲載されています。 本当の色をターミナルにセットするために、環境変数 `COLORTERM` に `truecolor` か `24bit` のどちらかを代入してください。さもなければ、`bat` はどの色を使うのか決定することができません。または、24-bit エスケープシーケンスがサポートされません (そして、8-bit colorに戻ります)。 ### 行番号とグリッド線がほとんど見えない 異なるテーマを試してみてください(`bat --list-themes` でテーマを閲覧できます)。 `OneHalfDark` と `OneHalfLight` テーマはグリッド線と線の色を明るくします。 ### ファイルエンコーディング `bat` は UTF-16 と同様に UTF-8 をネイティブにサポートします。 他のすべてのファイルエンコーディングでは、エンコーディングは通常自動検出できないため、最初に UTF-8 に変換する必要があります。 これを行うには `iconv` を使用できます。 例: Latin-1(ISO-8859-1)エンコーディングの PHP ファイルがある場合、次のように呼び出すことができます: ``` bash iconv -f ISO-8859-1 -t UTF-8 my-file.php | bat ``` 注: `bat` が構文を自動検出できない場合は `-l` / `-language` オプションを使用する必要がある場合があります。 ## 開発 ```bash # Recursive clone to retrieve all submodules git clone --recursive https://github.com/sharkdp/bat # Build (debug version) cd bat cargo build --bins # Run unit tests and integration tests cargo test # Install (release version) cargo install --locked # Build a bat binary with modified syntaxes and themes bash assets/create.sh cargo install --locked --force ``` ## Maintainers - [sharkdp](https://github.com/sharkdp) - [eth-p](https://github.com/eth-p) ## プロジェクトの目標と既存の類似したOSS `bat` は以下の目標を達成しようと試みています: - 美しく高度なシンタックスハイライトの提供 - ファイルの差分を表示するためのGitとの連携 - (POSIX) `cat` との完全互換 - ユーザーフレンドリーなコマンドラインインターフェースの提供 あなたが同様のプログラムを探しているなら、多くの選択肢があります。 比較については [このドキュメント](alternatives.md) を参照してください。 ## ライセンス Copyright (c) 2018-2021 [bat-developers](https://github.com/sharkdp/bat). `bat` は MIT License 及び Apache License 2.0 の両方の条件の下で配布されています。 ライセンスの詳細については [LICENSE-APACHE](../LICENSE-APACHE) 及び [LICENSE-MIT](../LICENSE-MIT) ファイルを参照して下さい。 bat-0.19.0/doc/README-ko.md000064400000000000000000000715740072674642500131620ustar 00000000000000

bat - a cat clone with wings
Build Status license Version info
문법 강조와 Git 통합 기능의 cat(1) 클론

주요 기능들사용법설치사용자화프로젝트 목표와 대안들
[English] [中文] [日本語] [한국어] [Русский]

### 문법 강조 `bat`은 다양한 프로그래밍 및 마크업 언어의 문법 강조(syntax highlighting) 기능을 지원합니다: ![Syntax highlighting example](https://imgur.com/rGsdnDe.png) ### Git 통합 `bat`은 `git`을 통해 인덱스와 함께 변경분을 표시합니다 (왼쪽 사이드바를 확인하세요): ![Git integration example](https://i.imgur.com/2lSW4RE.png) ### 비인쇄 문자 처리 `-A`/`--show-all` 옵션을 사용하여 비인쇄 문자를 표시 및 강조할 수 있습니다: ![Non-printable character example](https://i.imgur.com/WndGp9H.png) ### 자동 페이징 `bat`은 기본적으로 한 화면에 비해 출력이 큰 경우 `less`와 같은 페이저(pager)로 출력을 연결(pipe)합니다. 만약 `bat`을 언제나 `cat`처럼 작동하게 하려면 (출력을 페이지하지 않기), `--paging=never` 옵션을 커맨드 라인이나 설정 파일에 넣을 수 있습니다. 셸(shell) 설정에서 `cat`을 `bat`의 alias로 사용하려면, `alias cat='bat --paging=never'`를 써서 기본 행동을 유지할 수 있습니다. ### 파일 연결(concatenation) 페이저(pager)를 사용하더라도 `bat`은 파일들을 연결(concatenate)할 수 있습니다 :wink:. `bat`이 비대화형(non-interactive) 터미널(예를 들어, 다른 프로세스나 파일에 연결(pipe)한 경우)을 감지하면, `bat`은 `--pager` 옵션의 값과 상관없이 `cat`과 동일하게 파일 내용을 그대로 출력합니다. ## 사용법 터미널에 하나의 파일 표시하기 ```bash > bat README.md ``` 여러 파일 한 번에 보여주기 ```bash > bat src/*.rs ``` stdin에서 읽고, 자동으로 맞는 문법 결정하기 (참고로, 문법 강조는 파일의 첫 줄만으로 문법이 결정될 수 있을 때만 작동합니다. 이는 보통 `#!/bin/sh`와 같은 셔뱅(shebang)으로 판단합니다.) ```bash > curl -s https://sh.rustup.rs | bat ``` stdin에서 읽고, 명시적으로 언어 지정하기 ```bash > yaml2json .travis.yml | json_pp | bat -l json ``` 비인쇄 문자 표시 및 강조하기 ```bash > bat -A /etc/hosts ``` `cat` 대신 사용하기: ```bash bat > note.md # quickly create a new file bat header.md content.md footer.md > document.md bat -n main.rs # show line numbers (only) bat f - g # output 'f', then stdin, then 'g'. ``` ### 다른 도구들과 통합하기 #### `fzf` `bat`을 [`fzf`](https://github.com/junegunn/fzf)의 프리뷰로 쓸 수 있습니다. 이를 위해서는 `bat`의 `--color=always` 옵션으로 항상 컬러 출력이 나오게 해야 합니다. 또한 `--line-range` 옵션으로 긴 파일의 로드 시간을 제한할 수 있습니다: ```bash fzf --preview 'bat --color=always --style=numbers --line-range=:500 {}' ``` 더 많은 정보는 [`fzf`의 `README`](https://github.com/junegunn/fzf#preview-window)를 참고하세요. #### `find`와 `fd` `find`의 `-exec` 옵션을 사용하여 모든 검색 결과를 `bat`로 미리 볼 수 있습니다: ```bash find … -exec bat {} + ``` [`fd`](https://github.com/sharkdp/fd)를 사용하는 경우, `-X`/`--exec-batch` 옵션을 이용하여 동일하게 사용할 수 있습니다: ```bash fd … -X bat ``` #### `ripgrep` [`batgrep`](https://github.com/eth-p/bat-extras/blob/master/doc/batgrep.md)을 통해 `bat`로 [`ripgrep`](https://github.com/BurntSushi/ripgrep)의 검색 결과를 출력할 수 있습니다. ```bash batgrep needle src/ ``` #### `tail -f` `bat`와 `tail -f`를 함께 사용하여 주어진 파일을 문법 강조하며 지속적으로 모니터할 수 있습니다. ```bash tail -f /var/log/pacman.log | bat --paging=never -l log ``` 참고로 이 작업을 하려면 페이징 기능을 꺼야 합니다. 또한 이 경우 문법을 자동 감지할 수 없기 때문에, 적용할 문법을 직접 지정해야 합니다 (`-l log`). #### `git` `bat`과 `git show`를 함께 사용하여 주어진 파일의 이전 버전을 올바른 문법 강조로 볼 수 있습니다: ```bash git show v0.6.0:src/main.rs | bat -l rs ``` #### `git diff` `bat`과 `git diff`를 함께 사용하여 수정된 코드 주위의 줄들을 올바른 문법 강조로 볼 수 있습니다: ```bash batdiff() { git diff --name-only --diff-filter=d | xargs bat --diff } ``` 이것을 별도의 도구로 쓰고 싶다면 [`bat-extras`](https://github.com/eth-p/bat-extras)의 `batdiff`를 확인해 보세요. Git과 diff의 더 많은 지원을 원한다면 [`delta`](https://github.com/dandavison/delta)를 확인해 보세요. #### `xclip` `bat` 출력에 줄 번호와 Git 수정 내역이 포함되어서 파일의 내용을 복사하기 어려울 수 있습니다. 이 경우에는 `bat`의 `-p`/`--plain` 옵션을 사용하거나 간단히 `xclip`으로 출력을 연결(pipe)하면 됩니다: ```bash bat main.cpp | xclip ``` `bat`는 출력이 우회되고 있다는 것을 감지하여 파일 내용 그대로를 출력합니다. #### `man` `MANPAGER` 환경 변수 설정을 통해 `bat`을 `man`의 컬러 페이저(pager)로 쓸 수 있습니다. ```bash export MANPAGER="sh -c 'col -bx | bat -l man -p'" man 2 select ``` (Debian이나 Ubuntu를 사용한다면 `bat`을 `batcat`으로 치환하세요.) 포팻 문제가 발생한다면, `MANROFFOPT="-c"`을 써야 할 수 있습니다. 이 기능을 포함한 새로운 명령어를 선호한다면, [`batman`](https://github.com/eth-p/bat-extras/blob/master/doc/batman.md)을 쓸 수도 있습니다. 참고로 [Manpage 문법](../assets/syntaxes/Manpage.sublime-syntax)은 본 저장소에서 개발 중에 있으며, 아직 더 손봐야 합니다. 또한, 이는 Mandoc의 `man` 구현에서 [작동하지 않습니다](https://github.com/sharkdp/bat/issues/1145). #### `prettier` / `shfmt` / `rustfmt` [`prettybat`](https://github.com/eth-p/bat-extras/blob/master/doc/prettybat.md) 스크립트는 코드를 포맷하고 `bat`으로 출력하는 래퍼(wrapper)입니다. ## 설치 [![Packaging status](https://repology.org/badge/vertical-allrepos/bat-cat.svg)](https://repology.org/project/bat-cat/versions) ### Ubuntu에서 (`apt` 사용) *... 그리고 다른 Debian 기반의 Linux 배포판들에서.* `bat`은 [Ubuntu](https://packages.ubuntu.com/eoan/bat)와 [Debian](https://packages.debian.org/sid/bat) 패키지 배포 과정에 도입되는 중이며, Eoan 19.10 버전의 Ubuntu에서부터 제공됩니다. 현재 Debain에서는 불안정한 "Sid" 브랜치에서만 `bat`이 제공됩니다. 만약 충분히 최신 버전의 Ubuntu/Debian이 설치되어 있다면 간단히 다음을 실행하세요: ```bash apt install bat ``` **중요**: 만약 `bat`을 이와 같이 설치한다면, ([다른 패키지와의 이름 충돌](https://github.com/sharkdp/bat/issues/982)로 인하여) `bat` 대신에 `batcat`이라는 이름의 실행 파일로 설치될 수 있음을 참고하세요. 이에 따른 문제들과 다른 배포판들과의 일관성을 위하여 `bat -> batcat` symlink 혹은 alias를 설정할 수 있습니다: ``` bash mkdir -p ~/.local/bin ln -s /usr/bin/batcat ~/.local/bin/bat ``` ### Ubuntu에서 (가장 최신 `.deb` 패키지들 사용) *... 그리고 다른 Debian 기반의 Linux 배포판들에서.* 만약 여러분이 설치한 Ubuntu/Debian에 패키지가 배포되지 않거나 가장 최신 릴리즈된 `bat`을 원한다면, [릴리즈 페이지](https://github.com/sharkdp/bat/releases)에서 다음과 같이 `.deb` 패키지를 받아 설치하세요: ```bash sudo dpkg -i bat_0.18.3_amd64.deb # adapt version number and architecture ``` ### Alpine Linux에서 적절한 저장소가 활성화되어 있다면, 공식 소스를 통해 [`bat` 패키지](https://pkgs.alpinelinux.org/packages?name=bat)를 설치할 수 있습니다: ```bash apk add bat ``` ### Arch Linux에서 공식 소스를 통해 [`bat` 패키지](https://www.archlinux.org/packages/community/x86_64/bat/)를 설치할 수 있습니다: ```bash pacman -S bat ``` ### Fedora에서 공식 [Fedora 모듈](https://docs.fedoraproject.org/en-US/modularity/using-modules/) 저장소에서 [`bat` 패키지](https://koji.fedoraproject.org/koji/packageinfo?packageID=27506)를 설치할 수 있습니다: ```bash dnf install bat ``` ### Funtoo Linux에서 dev-kit을 통해 [`bat` 패키지](https://github.com/funtoo/dev-kit/tree/1.4-release/sys-apps/bat)를 설치할 수 있습니다: ```bash emerge sys-apps/bat ``` ### Gentoo Linux에서 공식 소스를 통해 [`bat` 패키지](https://packages.gentoo.org/packages/sys-apps/bat)를 설치할 수 있습니다: ```bash emerge sys-apps/bat ``` ### Void Linux에서 xbps-install을 이용해 `bat`을 설치할 수 있습니다: ```bash xbps-install -S bat ``` ### Termux에서 pkg를 이용해 `bat`을 설치할 수 있습니다: ```bash pkg install bat ``` ### FreeBSD에서 pkg를 이용하여 미리 컴파일된 [`bat` 패키지](https://www.freshports.org/textproc/bat)를 설치할 수 있습니다: ```bash pkg install bat ``` 또는 FreeBSD 포트에서 직접 빌드할 수도 있습니다: ```bash cd /usr/ports/textproc/bat make install ``` ### nix를 써서 [nix package manager](https://nixos.org/nix)를 이용해 `bat`을 설치할 수 있습니다: ```bash nix-env -i bat ``` ### openSUSE에서 zypper를 이용해 `bat`을 설치할 수 있습니다: ```bash zypper install bat ``` ### snap 패키지를 써서 지금으로서는 추천하는 snap 패키지가 없습니다. 제공되는 패키지들이 존재할 수는 있지만, 공식적으로 지원되지 않으며 [문제](https://github.com/sharkdp/bat/issues/1519)가 있을 수 있습니다. ### macOS (또는 Linux)에서 Homebrew를 써서 [macOS의 Homebrew](https://formulae.brew.sh/formula/bat) 또는 [Linux의 Homebrew](https://formulae.brew.sh/formula-linux/bat)를 이용하여 `bat`을 설치할 수 있습니다. ```bash brew install bat ``` ### macOS에서 MacPorts를 써서 [MacPorts](https://ports.macports.org/port/bat/summary)를 이용하여 `bat`을 설치할 수 있습니다: ```bash port install bat ``` ### Windows에서 Windows에서 `bat`을 설치할 수 있는 몇 가지 옵션들이 있습니다. 먼저 `bat`을 설치한 후, ["Windows에서 `bat` 사용하기"](#windows에서-bat-사용하기) 섹션을 살펴보세요. #### 전제 조건 [Visual C++ 재배포 가능](https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads) 패키지를 설치해야 합니다. #### Chocolatey를 써서 [Chocolatey](https://chocolatey.org/packages/Bat)를 이용해 `bat`을 설치할 수 있습니다: ```bash choco install bat ``` #### Scoop을 써서 [scoop](https://scoop.sh/)을 이용해 `bat`을 설치할 수 있습니다: ```bash scoop install bat ``` #### 사전 빌드된 바이너리들로 [릴리즈 페이지](https://github.com/sharkdp/bat/releases)에서 사전 빌드된 바이너리를 다운받을 수 있습니다. [Visual C++ 재배포 가능](https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads) 패키지를 설치해야 합니다. ### 바이너리들로 [릴리즈 페이지](https://github.com/sharkdp/bat/releases)에서 다양한 아키텍처를 위해 사전 빌드된 버전들을 확인할 수 있습니다. 정적 링크 바이너리들은 파일 이름에 `musl` 이 포함된 아카이브들을 확인하세요. ### 소스에서 `bat`의 소스를 빌드하기 위해서는, Rust 1.51 이상이 필요합니다. `cargo`를 이용해 전부 빌드할 수 있습니다: ```bash cargo install --locked bat ``` 참고로 man 페이지나 셸 자동 완성 파일과 같은 부가 파일들은 이 방법으로 설치될 수 없습니다. 이것들은 `cargo`에 의해 생성이 되고 (`build` 밑의) cargo 타켓 폴더에서 찾을 수 있습니다. ## 사용자화 ### 문법 강조 테마 `bat --list-themes`을 사용하여 사용 가능한 문법 강조 테마들의 목록을 확인할 수 있습니다. `TwoDark` 테마를 선택하려면, `--theme=TwoDark` 옵션과 함께 `bat`을 사용하거나 `BAT_THEME` 환경 변수를 `TwoDark`로 설정하세요. 셸 시작 파일에 `export BAT_THEME="TwoDark"` 를 정의해 영구적으로 설정할 수 있습니다. 이 밖에 `bat`의 [설정 파일](#설정-파일)을 이용할 수 있습니다. 만약 다른 테마들을 사용하여 특정 파일을 보고 싶다면, 다음 명령어를 쓸 수 있습니다(이 경우 [`fzf`](https://github.com/junegunn/fzf)가 필요합니다.) ```bash bat --list-themes | fzf --preview="bat --theme={} --color=always /path/to/file" ``` `bat`은 기본적으로 어두운 배경에 적합합니다. 그러나 밝은 배경의 터미널을 사용한다면 `GitHub`이나 `OneHalfLight`과 같은 테마가 더 잘 어울립니다. 아래 [새로운 테마 추가하기](#새로운-테마-추가하기) 섹션에 따라 커스텀 테마를 사용할 수도 있습니다. ### 8비트 테마 `bat`은 트루컬러 지원이 되더라도 항상 [8비트 색상](https://en.wikipedia.org/wiki/ANSI_escape_code#Colors)을 사용하는 세 개의 테마가 있습니다. - `ansi`는 어떤 터미널에서도 무난하게 보입니다. 이는 3비트 색상을 사용합니다: 검정, 빨강, 녹색, 노랑, 파랑, 마젠타, 시안, 하양. - `base16`은 [base16](https://github.com/chriskempson/base16) 터미널 테마를 위해 디자인되었습니다. 이는 [base16 스타일 가이드라인](https://github.com/chriskempson/base16/blob/master/styling.md)에 따라 4비트 색상(3비트 색상에 밝은 변형 추가)을 사용합니다. - `base16-256`는 [base16-shell](https://github.com/chriskempson/base16-shell)을 위해 디자인되었습니다. 이는 16부터 21의 일부 밝은 색상을 8비트 색상으로 대치합니다. 단지 256-색상 터미널을 쓰지만 base16-shell을 쓰지 않는다고 해서 이것을 사용하지 **마십시오**. 이들 테마는 더 제한적이지만, 트루컬러 테마에 비해 두 장점이 있습니다: - 이들은 3비트 혹은 4비트 색상을 쓰는 다른 터미널 소프트웨어와 더 잘 어울립니다. - 만약 터미널 테마를 바꾼다면, 이미 화면 상의 `bat`의 출력도 이에 맞추어 업데이트됩니다. ### 출력 스타일 `--style` 옵션을 이용하면 `bat`의 출력 모양을 조절할 수 있습니다. 예를 들어, `--style=numbers,changes`를 통해 Git 변경분과 줄 번호는 출력하지만 격자와 파일 헤더는 출력하지 않을 수 있습니다. `BAT_STYLE` 환경 변수를 정의하여 이러한 수정을 영구적으로 하거나 `bat`의 [설정 파일](#설정-파일)을 사용하세요. ### 새로운 문법 / 언어 정의 추가하기 만약 `bat`에서 특정 문법이 지원되지 않을 경우, 다음의 절차를 통해 현재 `bat` 설치본에 새로운 문법을 쉽게 추가할 수 있습니다. `bat`은 문법 강조를 위해 훌륭한 [`syntect`](https://github.com/trishume/syntect/) 라이브러리를 사용합니다. `syntect`는 임의의 [Sublime Text의 `.sublime-syntax` 파일](https://www.sublimetext.com/docs/3/syntax.html)과 테마를 읽을 수 있습니다. [Package Control](https://packagecontrol.io/)에 Sublime 문법 패키지를 찾는 방법이 잘 정리되어 있습니다. 일단 문법을 찾았다면: 1. 문법 정의 파일들을 넣을 폴더를 만듭니다: ```bash mkdir -p "$(bat --config-dir)/syntaxes" cd "$(bat --config-dir)/syntaxes" # Put new '.sublime-syntax' language definition files # in this folder (or its subdirectories), for example: git clone https://github.com/tellnobody1/sublime-purescript-syntax ``` 2. 이제 다음 명령어를 통해 파일들을 파싱(parse)하여 바이너리 캐시를 만듭니다. ```bash bat cache --build ``` 3. 마지막으로, `bat --list-languages`로 새로 추가한 언어가 사용 가능한지 확인합니다. 만약 기본 설정으로 돌아갈 일이 생긴다면, 다음 명령어를 이용합니다: ```bash bat cache --clear ``` 4. 만약 특정 문법이 `bat`에 기본적으로 포함되어 있어야 한다고 생각한다면, 방침과 절차를 [여기](../doc/assets.md)서 읽은 후 "문법 요청(syntax request)"을 열어 주세요: [문법 요청하기](https://github.com/sharkdp/bat/issues/new?labels=syntax-request&template=syntax_request.md). ### 새로운 테마 추가하기 이 과정은 새로운 문법 정의 추가 방식과 매우 비슷합니다. 먼저, 새로운 문법 강조 테마 폴더를 만듭니다. ```bash mkdir -p "$(bat --config-dir)/themes" cd "$(bat --config-dir)/themes" # Download a theme in '.tmTheme' format, for example: git clone https://github.com/greggb/sublime-snazzy # Update the binary cache bat cache --build ``` 마지막으로 `bat --list-themes`을 통해 새로 추가한 테마들이 사용 가능한지 확인합니다. ### 파일 타입 설정을 추가하거나 변경하기 새로운 파일 이름 패턴을 추가하려면 (혹은 이미 존재하는 것을 변경하려면) `--map-syntax` 커맨드 라인 옵션을 사용하세요. 이 옵션은 `pattern:syntax` 꼴의 인자를 받습니다. 이때 `pattern`은 파일 이름과 절대 파일 경로를 매치할 글로브(glob) 패턴입니다. `syntax` 부분은 지원되는 언어의 전체 이름입니다 (`bat --list-languages`를 통해 개요를 확인하세요). 참고: 이 옵션은 커맨드 라인에 넘겨 주는 것보다는 `bat`의 설정 파일에 넣는 것이 좋을 것입니다 (아래를 보세요). 예시: "INI" 문법 강조를 `.conf` 파일 확장자의 모든 파일에 적용하려면, 다음을 사용하세요: ```bash --map-syntax='*.conf:INI' ``` 예시: `.ignore`(완전 일치)이라는 이름의 모든 파일을 "Git Ignore" 문법으로 열려면, 다음을 사용하세요: ```bash --map-syntax='.ignore:Git Ignore' ``` 예시: `/etc/apache2`의 하위 폴더들에 있는 모든 `.conf` 파일들을 "Apache Conf" 문법으로 열려면, 다음을 사용하세요 (이 대응(mapping)은 이미 내장되어 있습니다): ```bash --map-syntax='/etc/apache2/**/*.conf:Apache Conf' ``` ### 다른 페이저 사용하기 `bat`은 환경 변수 `PAGER`에 명시된 페이저를 사용합니다. 이 변수가 정의되어 있지 않다면, `less`가 기본으로 사용됩니다. 만약 다른 페이저를 사용하고 싶다면, `PAGER` 변수를 수정하거나 `BAT_PAGER` 환경 변수를 설정하여 `PAGER`의 설정을 오버라이드(override)할 수 있습니다. 만약 커맨드라인 인수들을 페이저에게 넘겨 주려면, `PAGER`/`BAT_PAGER` 변수로 설정할 수 있습니다: ```bash export BAT_PAGER="less -RF" ``` 환경 변수를 사용하는 대신, `bat`의 [설정 파일](#설정-파일)로 페이저를 설정할 수도 있습니다 (`--pager` 옵션). **참고**: 기본적으로, 페이저가 `less`로 설정되어 있다면 (그리고 커맨드 라인 옵션이 지정되어 있지 않다면), `bat`은 다음 옵션들을 페이저로 넘겨줍니다: `-R`/`--RAW-CONTROL-CHARS`, `-F`/`--quit-if-one-screen` 그리고 `-X`/`--no-init`. 마지막 옵션(`-X`)은 530 이전 버전의 `less`에만 사용됩니다. `-R` 옵션은 ANSI 색상을 올바르게 해석하기 위해 필요합니다. 두 번째 옵션(`-F`)은 출력 크기가 터미널의 세로 크기보다 작을 경우 less가 즉시 종료되도록 합니다. 이는 작은 파일을 다룰 때 페이저를 종료하기 위해 `q`를 누를 필요 없어서 편리합니다. 세 번째 옵션(`-X`)는 예전 버전의 `less`에 있는 `--quit-if-one-screen` 기능의 버그를 고치기 위해 필요합니다. 안타깝게도, 이는 `less`의 마우스 휠 지원과 호환되지 않습니다. `less`의 예전 버전에서 마우스 휠 기능을 활성화하려면, `-R` 옵션을 넘겨주세요 (위의 예제처럼, 이 옵션은 quit-if-one-screen 기능을 비활성화합니다). less 530과 이후 버전에서는 그대로 사용할 수 있습니다. ### 들여쓰기 `bat`은 페이저에 의존하지 않고 탭을 4 스페이스로 확장합니다. 이를 변경하려면 간단히 `--tabs` 인자에 표시되기를 원하는 스페이스 개수를 추가하세요. **참고**: (`bat`의 `--pager` 인자 혹은 `less`의 `LESS` 환경 변수를 통해) 페이저의 탭 길이를 지정하는 것은 효과가 없을 것인데, 이는 페이저가 이미 스페이스로 확장된 탭을 받기 때문입니다. 이 기능은 사이드바에 의한 들여쓰기 문제를 회피하기 위해 추가되었습니다. `bat`을 `--tabs=0`과 함께 호출하면 이를 오버라이드하여 페이저가 탭을 처리하게 합니다. ### 다크 모드 macOS에서 다크 모드를 사용하고 있다면, `bat`가 OS 테마에 따라 다른 테마를 사용하도록 구성할 수 있습니다. 아래 스니펫은 _다크 모드_에서는 `default` 테마를, _라이트 모드_에서는 `GitHub` 테마를 사용하는 방법입니다. ```bash alias cat="bat --theme=\$(defaults read -globalDomain AppleInterfaceStyle &> /dev/null && echo default || echo GitHub)" ``` ## 설정 파일 `bat`는 설정 파일로도 사용자화 할 수 있습니다. 설정 파일의 위치는 운영 체제에 따라 다릅니다. 아래 커맨드를 통해 시스템의 기본 경로를 확인할 수 있습니다. ``` bat --config-file ``` 또는, `BAT_CONFIG_PATH` 환경 변수를 사용하여 `bat`가 설정 파일의 기본 경로 이외의 위치를 사용하도록 할 수 있습니다. ```bash export BAT_CONFIG_PATH="/path/to/bat.conf" ``` 기본 설정 파일은 `--generate-config-file` 옵션으로 생성할 수 있습니다. ```bash bat --generate-config-file ``` ### 포맷 설정 파일은 단순히 커맨드 라인 인자들의 리스트입니다. `bat --help`로 가능한 모든 옵션과 값들을 확인하세요. 추가적으로, 줄 앞에 `#` 문자를 추가해 주석을 넣을 수 있습니다. 설정 파일 예시: ```bash # "TwoDark" 테마 설정하기 --theme="TwoDark" # 줄 번호, Git 변경 내용, 파일 헤더 보이기 (격자 없이) --style="numbers,changes,header" # 터미널에서 이탤릭체 쓰기 (일부 터미널에서 미지원) --italic-text=always # Arduino .ino 파일에 C++ 문법 쓰기 --map-syntax "*.ino:C++" ``` ## Windows에서 `bat` 사용하기 `bat`는 대부분의 경우 Windows에서 기본적으로 잘 작동하지만, 일부 기능은 추가적인 구성이 필요할 수 있습니다. #### 전제 조건 [Visual C++ 재배포 가능](https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads) 패키지를 설치해야 합니다. ### 페이징 Windows는 `more` 형식의 매우 제한된 페이저만 포함합니다. Windows용 `less` 바이너리는 [공식 홈페이지](http://www.greenwoodsoftware.com/less/download.html)나 [Chocolatey](https://chocolatey.org/packages/Less)를 통해 다운로드 받을 수 있습니다. 이를 사용하려면 디렉터리 안의 바이너리를 `PATH`에 넣거나 [환경 변수로 정의](#using-a-different-pager)하세요. [Chocolatey 패키지](#on-windows)는 `less`를 자동으로 설치합니다. ### 색상 Windows 10은 [v1511](https://en.wikipedia.org/wiki/Windows_10_version_history#Version_1511_(November_Update))부터 기본적으로 `conhost.exe`(Command Prompt)와 PowerShell에서 색상을 지원하며, 최신 버전의 bash에서도 색상을 지원합니다. 이전 버전의 Windows에서는, [ConEmu](https://conemu.github.io/)가 포함된 [Cmder](http://cmder.net/)를 사용할 수 있습니다. **참고:** Git과 MSYS 버전의 `less`는 Windows에서 색상을 올바르게 해석하지 않습니다. 다른 페이저가 설치되어 있지 않은 경우, `--paging=never`을 넘겨주거나 `BAT_PAGER`을 빈 문자열로 설정하여 페이징을 완전히 비활성화 할 수 있습니다. ### Cygwin Windows에서의 `bat`은 기본적으로 Cygwin의 unix 스타일 경로(`/cygdrive/*`)를 지원하지 않습니다. Cygwin 절대 경로를 인자로 받았을 때, `bat`은 다음과 같은 오류를 반환합니다: `The system cannot find the path specified. (os error 3)` 이는 wrapper를 만들거나 다음 함수를 `.bash_profile`에 추가하여 해결할 수 있습니다: ```bash bat() { local index local args=("$@") for index in $(seq 0 ${#args[@]}) ; do case "${args[index]}" in -*) continue;; *) [ -e "${args[index]}" ] && args[index]="$(cygpath --windows "${args[index]}")";; esac done command bat "${args[@]}" } ``` ## 문제 해결 ### 터미널과 색상 `bat`은 터미널의 트루컬러 지원 여부와 상관 없이 동작합니다. 그러나 대부분 문법 강조 테마의 색상은 8비트 색상에 최적화되어 있지 않습니다. 따라서 24비트 트루컬러 지원이 되는 터미널(`terminator`, `konsole`, `iTerm2`, ...)을 사용하는 것을 적극 권장합니다. 트루컬러를 지원하는 터미널들과 더 자세한 정보는 [이 글](https://gist.github.com/XVilka/8346728)에서 찾아보실 수 있습니다. 사용하고 있는 트루컬러 터미널에서 `COLORTERM` 변수를 `truecolor` 혹은 `24bit`로 설정되어 있는지 확인하세요. 그렇지 않을 경우, `bat`은 24비트 확장열(escape sequence)이 지원되는지 여부를 판단할 수 없습니다 (그리고 8비트 색상을 사용합니다). ### 줄 번호와 격자가 잘 보이지 않는 경우 다른 테마를 사용해 보세요 (`bat --list-themes`에서 목록을 볼 수 있습니다). `OneHalfDark`와 `OneHalfLight` 테마는 더 밝은 눈금과 선의 색상을 사용합니다. ### 파일 인코딩 `bat`은 기본적으로 UTF-8과 UTF-16을 지원합니다. 다른 모든 종류의 파일 인코딩에 대해서는, 일반적으로 인코딩을 자동으로 판별하는 방법이 없기 때문에 먼저 UTF-8으로 변환해야 할 수 있습니다. 이를 위해 `iconv`를 사용할 수 있습니다. 예시: Latin-1(ISO-8859-1)로 인코딩된 PHP 파일은 다음과 같이 처리할 수 있습니다: ``` bash iconv -f ISO-8859-1 -t UTF-8 my-file.php | bat ``` 참고: `bat`으로 문법 자동 감지가 되지 않는 경우에는 `-l`/`--language` 옵션을 사용할 수 있습니다. ## 개발 ```bash # 모든 서브모듈을 받기 위해 재귀적으로 복제하기 git clone --recursive https://github.com/sharkdp/bat # (디버그 버전) 빌드 cd bat cargo build --bins # 단위 테스트와 통합 테스트 실행 cargo test # (배포 버전) 설치 cargo install --locked # 수정된 문법과 테마가 적용된 bat 바이너리 빌드 bash assets/create.sh cargo install --locked --force ``` `bat`의 pretty-printing 기능을 라이브러리로 사용하는 애플리케이션을 만들고 싶다면, [API 문서](https://docs.rs/bat/)를 살펴보세요. 참고로 `bat`에 라이브러리로써 의존한다면, `regex-onig`나 `regex-fancy`를 기능으로 사용해야 합니다. ## 기여하기 [`CONTRIBUTING.md`](../CONTRIBUTING.md) 가이드를 살펴보세요. ## 메인테이너들 - [sharkdp](https://github.com/sharkdp) - [eth-p](https://github.com/eth-p) - [keith-hall](https://github.com/keith-hall) - [Enselic](https://github.com/Enselic) ## 보안 취약점 만약 `bat`의 취약점을 발견하였다면, [David Peter](https://david-peter.de/)에게 메일로 연락주시기 바랍니다. ## 프로젝트 목표와 대안들 `bat`은 다음과 같은 목표를 달성하려고 합니다: - 아름답고 발전된 문법 강조 기능 제공 - Git과의 연동을 통한 파일 변경 내용 확인 - (POSIX) `cat`의 대체제 - 사용자 친화적인 커맨드 라인 인터페이스 제공 비슷한 프로그램들을 찾고 있다면 많은 대안들이 있습니다. 비교는 [이 문서](../doc/alternatives.md)를 참조해 주세요. ## 라이센스 Copyright (c) 2018-2021 [bat-developers](https://github.com/sharkdp/bat). `bat`는 여러분의 선택에 따라 MIT 라이센스 또는 Apache 라이센스 2.0의 조건에 따라 배포됩니다. 라이센스의 세부사항은 [LICENSE-APACHE](../LICENSE-APACHE)와 [LICENSE-MIT](../LICENSE-MIT)를 참조하세요. bat-0.19.0/doc/README-ru.md000064400000000000000000000702630072674642500131710ustar 00000000000000

bat - a cat clone with wings
Build Status license Version info
Клон утилиты cat(1) с поддержкой выделения синтаксиса и Git

Ключевые возможностиИспользованиеУстановкаКастомизацияЦели и альтернативы
[English] [中文] [日本語] [한국어] [Русский]

### Выделение синтаксиса `bat` поддерживает выделение синтаксиса для огромного количества языков программирования и разметки: ![Пример выделения синтаксиса](https://i.imgur.com/3FGy5tW.png) ### Интеграция с Git `bat` использует `git`, чтобы показать изменения в коде (смотрите на левый сайдбар): ![Пример интеграции с Git](https://i.imgur.com/azUAzdx.png) ### Показать непечатаемые символы Вы можете использовать `-A` / `--show-all` флаг, чтобы показать символы, которые невозможно напечатать: ![Строка с неотображемыми символами](https://i.imgur.com/X0orYY9.png) ### Автоматическое разделение текста `bat` умеет перенаправлять вывод в `less`, если вывод не помещается на экране полностью. ### Объединение файлов О... Вы также можете объединять файлы :wink:. Когда `bat` обнаружит неинтерактивный терминал (например, когда вы перенаправляете вывод в файл или процесс), он будет работать как утилита `cat` и выведет содержимое файлов как обычный текст (без подсветки синтаксиса). ## Как использовать Вывести единственный файл в терминале ```bash > bat README.md ``` Отобразить сразу несколько файлов в терминале ```bash > bat src/*.rs ``` Читаем из stdin и определяем синтаксис автоматически (внимание: это делается по заглавной строке файла, например, `#!/bin/sh`) ```bash > curl -s https://sh.rustup.rs | bat ``` Прочитать из stdin с явным указанием языка ```bash > yaml2json .travis.yml | json_pp | bat -l json ``` Вывести и выделить неотображаемые символы ```bash > bat -A /etc/hosts ``` Использование в качестве замены `cat` ```bash bat > note.md # мгновенно создаем новый файл bat header.md content.md footer.md > document.md bat -n main.rs # показываем только количество строк bat f - g # выводит 'f' в stdin, а потом 'g'. ``` ### Интеграция с другими утилитами #### `find` или `fd` Вы можете использовать флаг `-exec` в `find`, чтобы посмотреть превью всех файлов в `bat` ```bash find … -exec bat {} + ``` Если вы используете [`fd`](https://github.com/sharkdp/fd), применяйте для этого флаг `-X`/`--exec-batch`: ```bash fd … -X bat ``` #### `ripgrep` С помощью [`batgrep`](https://github.com/eth-p/bat-extras/blob/master/doc/batgrep.md), `bat` может быть использован для вывода результата запроса [`ripgrep`](https://github.com/BurntSushi/ripgrep) ```bash batgrep needle src/ ``` #### `tail -f` `bat` может быть использован вместе с `tail -f`, чтобы выводить содержимое файла с подсветкой синтаксиса в реальном времени. ```bash tail -f /var/log/pacman.log | bat --paging=never -l log ``` Заметьте, что мы должны отключить пэйджинг, чтобы это заработало. Мы также явно указали синтаксис (`-l log`), так как он не может быть автоматически определен в данном случае. #### `git` Вы можете использовать `bat` с `git show`, чтобы просмотреть старую версию файла с выделением синтаксиса: ```bash git show v0.6.0:src/main.rs | bat -l rs ``` Обратите внимание, что выделение синтаксиса не работает в `git diff` на данный момент. Если вам это нужно, посмотрите [`delta`](https://github.com/dandavison/delta). #### `xclip` Нумерация стро и отображение изменений затрудняет копирование содержимого файлов в буфер обмена. Чтобы спроваиться с этим, используйте флаг `-p`/`--plain` или просто перенаправьте стандартный вывод в `xclip`: ```bash bat main.cpp | xclip ``` `bat` обнаружит перенаправление вывода и выведет обычный текст без выделения синтаксиса. #### `man` `bat` может быть использован в виде выделения цвета для `man`, для этого установите переменную окружения `MANPAGER`: ```bash export MANPAGER="sh -c 'col -bx | bat -l man -p'" man 2 select ``` Возможно вам понадобится также установить `MANROFFOPT="-c"`, если у вас есть проблемы с форматированием. Если вы хотите сделать этой одной командой, вы можете использовать [`batman`](https://github.com/eth-p/bat-extras/blob/master/doc/batman.md). Обратите внимание, что [синтаксис manpage](assets/syntaxes/02_Extra/Manpage.sublime-syntax) разрабатывается в этом репозитории и все еще находится в разработке. #### `prettier` / `shfmt` / `rustfmt` [`Prettybat`](https://github.com/eth-p/bat-extras/blob/master/doc/prettybat.md) — скрипт, который форматирует код и выводит его с помощью `bat`. ## Установка [![Packaging status](https://repology.org/badge/vertical-allrepos/bat.svg)](https://repology.org/project/bat/versions) ### Ubuntu (с помощью `apt`) *... и другие дистрибутивы основанные на Debian.* `bat` есть в репозиториях [Ubuntu](https://packages.ubuntu.com/eoan/bat) и [Debian](https://packages.debian.org/sid/bat) и доступен начиная с Ubuntu Eoan 19.10. На Debian `bat` пока что доступен только с нестабильной веткой "Sid". Если ваша версия Ubuntu/Debian достаточно новая, вы можете установить `bat` так: ```bash apt install bat ``` Если вы установили `bat` таким образом, то бинарный файл может быть установлен как `batcat` вместо `bat` (из-за [конфликта имени с другим пакетом](https://github.com/sharkdp/bat/issues/982)). Вы можете сделать симлинк или алиас `bat -> batcat`, чтобы предотвратить подобные проблемы и в других дистрибутивах. ``` bash mkdir -p ~/.local/bin ln -s /usr/bin/batcat ~/.local/bin/bat ``` ### Ubuntu (С помощью самого нового `.deb` пакета) *... и другие дистрибутивы Linux основанные на Debian* Если пакет еще недоступен в вашем Ubuntu/Debian дистрибутиве или вы хотите установить самую последнюю версию `bat`, то вы можете скачать самый последний `deb`-пакет отсюда: [release page](https://github.com/sharkdp/bat/releases) и установить так: ```bash sudo dpkg -i bat_0.18.3_amd64.deb # измените архитектуру и версию ``` ### Alpine Linux Вы можете установить [`bat`](https://pkgs.alpinelinux.org/packages?name=bat) из официальных источников: ```bash apk add bat ``` ### Arch Linux Вы можете установить [`bat`](https://www.archlinux.org/packages/community/x86_64/bat/) из официального источника: ```bash pacman -S bat ``` ### Fedora Вы можете установить [`bat`](https://koji.fedoraproject.org/koji/packageinfo?packageID=27506) из официального репозитория [Fedora Modular](https://docs.fedoraproject.org/en-US/modularity/using-modules/). ```bash dnf install bat ``` ### Gentoo Linux Вы можете установить [`bat`](https://packages.gentoo.org/packages/sys-apps/bat) из официальных источников: ```bash emerge sys-apps/bat ``` ### Void Linux Вы можете установить `bat` с помощью `xbps-install`: ```bash xbps-install -S bat ``` ### FreeBSD Вы можете установить [`bat`](https://www.freshports.org/textproc/bat) с помощью `pkg`: ```bash pkg install bat ``` или самому скомпилировать его: ```bash cd /usr/ports/textproc/bat make install ``` ### С помощью nix Вы можете установить `bat`, используя [nix package manager](https://nixos.org/nix): ```bash nix-env -i bat ``` ### openSUSE Вы можете установить `bat` с помощью `zypper`: ```bash zypper install bat ``` ### macOS Вы можете установить `bat` с помощью [Homebrew](http://braumeister.org/formula/bat): ```bash brew install bat ``` Или же установить его с помощью [MacPorts](https://ports.macports.org/port/bat/summary): ```bash port install bat ``` ### Windows Есть несколько способов установить `bat`. Как только вы установили его, посмотрите на секцию ["Использование `bat` в Windows"](#using-bat-on-windows). #### С помощью Chocolatey Вы можете установить `bat` с помощью [Chocolatey](https://chocolatey.org/packages/Bat): ```bash choco install bat ``` #### С помощью Scoop Вы можете установить `bat` с помощью [scoop](https://scoop.sh/): ```bash scoop install bat ``` Для этого у вас должен быть установлен [Visual C++ Redistributable](https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads). #### Из заранее скомпилированных файлов: Их вы можете скачать на [странице релизов](https://github.com/sharkdp/bat/releases). Для этого у вас должен быть установлен [Visual C++ Redistributable](https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads). ### С помощью Docker Вы можете использовать [Docker image](https://hub.docker.com/r/danlynn/bat/), чтобы запустить `bat` в контейнере: ```bash docker pull danlynn/bat alias bat='docker run -it --rm -e BAT_THEME -e BAT_STYLE -e BAT_TABS -v "$(pwd):/myapp" danlynn/bat' ``` ### С помощью Ansible Вы можете установить `bat` с [Ansible](https://www.ansible.com/): ```bash # Устанавливаем роль на устройстве ansible-galaxy install aeimer.install_bat ``` ```yaml --- # Playbook для установки bat - host: all roles: - aeimer.install_bat ``` - [Ansible Galaxy](https://galaxy.ansible.com/aeimer/install_bat) - [GitHub](https://github.com/aeimer/ansible-install-bat) Этот способ должен сработать со следующими дистрибутивами: - Debian/Ubuntu - ARM (например Raspberry PI) - Arch Linux - Void Linux - FreeBSD - macOS ### Из скомпилированных файлов Перейдите на [страницу релизов](https://github.com/sharkdp/bat/releases) для скомпилированных файлов `bat` для различных платформ. Бинарные файлы со статической связкой так же доступны: выбирайте архив с `musl` в имени. ### Из исходников Если вы желаете установить `bat` из исходников, вам понадобится Rust 1.51 или выше. После этого используйте `cargo`, чтобы все скомпилировать: ```bash cargo install --locked bat ``` ## Кастомизация ### Темы для выделения текста Используйте `bat --list-themes`, чтобы вывести список всех доступных тем. Для выбора темы `TwoDark` используйте `bat` с флагом `--theme=TwoDark` или выставьте переменную окружения `BAT_THEME` в `TwoDark`. Используйте `export BAT_THEME="TwoDark"` в конфигурационном файле вашей оболочки, чтобы изменить ее навсегда. Или же используйте [конфигурационный файл](https://github.com/sharkdp/bat#configuration-file) `bat`. Если вы хотите просто просмотреть темы, используйте следующую команду (для этого вам понадобится [`fzf`](https://github.com/junegunn/fzf)): ```bash bat --list-themes | fzf --preview="bat --theme={} --color=always /путь/к/файлу" ``` `bat` отлично смотрится на темном фоне. Однако если ваш терминал использует светлую тему, то такие темы как `GitHub` или `OneHalfLight` будут смотреться куда лучше! Вы также можете использовать новую тему, для этого перейдите [в раздел добавления тем](https://github.com/sharkdp/bat#добавление-новых-тем). ### Изменение внешнего вывода Вы можете использовать флаг `--style`, чтобы изменять внешний вид вывода в `bat`. Например, вы можете использовать `--style=numbers,changes`, чтобы показать только количество строк и изменений в Git. Установите переменную окружения `BAT_STYLE` чтобы изменить это навсегда, или используйте [конфиг файл](https://github.com/sharkdp/bat#configuration-file) `bat`. ### Добавление новых синтаксисов `bat` использует [`syntect`](https://github.com/trishume/syntect/) для выделения синтаксиса. `syntect` может читать [файл `.sublime-syntax`](https://www.sublimetext.com/docs/3/syntax.html) и темы. Чтобы добавить новый синтаксис, сделайте следующее: Создайте каталог с синтаксисом: ```bash mkdir -p "$(bat --config-dir)/syntaxes" cd "$(bat --config-dir)/syntaxes" # Разместите файлы '.sublime-syntax' # в каталоге (или субкаталогах), например: git clone https://github.com/tellnobody1/sublime-purescript-syntax ``` Теперь используйте следующую команду, чтобы превратить эти файлы в бинарный кеш: ```bash bat cache --build ``` Теперь вы можете использовать `bat --list-languages`, чтобы проверить, доступны ли новые языки. Если когда-нибудь вы заходите вернуться к настройкам по умолчанию, введите ```bash bat cache --clear ``` ### Добавление новых тем Это работает похожим образом, так же как и добавление новых тем выделения синтаксиса Во-первых, создайте каталог с новыми темами для синтаксиса: ```bash mkdir -p "$(bat --config-dir)/themes" cd "$(bat --config-dir)/themes" # Загрузите тему в формате '.tmTheme': git clone https://github.com/greggb/sublime-snazzy # Обновите кеш bat cache --build ``` Теперь используйте `bat --list-themes`, чтобы проверить доступность новых тем. ### Использование другого пейджера. `bat` использует пейджер, указанный в переменной окружения `PAGER`. Если она не задана, то используется `less`. Если вы желаете использовать другой пейджер, вы можете либо изменить переменную `PAGER`, либо `BAT_PAGER` чтобы перезаписать то, что указано в `PAGER`. Чтобы передать дополнительные аргументы вашему пейджеру, перечислите их в этой переменной: ```bash export BAT_PAGER="less -RF" ``` Так же вы можете использовать [файл конфигурации](https://github.com/sharkdp/bat#configuration-file) `bat` (флаг `--pager`). **Внимание**: По умолчанию пейджером является`less` (без каких-либо аргументов), `bat` задаст следующие флаги для пейджера: `-R`/`--RAW-CONTROL-CHARS`, `-F`/`--quit-if-one-screen` и `-X`/`--no-init`. Последний флаг(`-X`) используется только для `less`, чья версия раньше 530. Флаг `-R` нужен чтобы корректно воспроизвести ANSI цвета. Второй флаг (`-F`) говорит `less` чтобы тот сразу же завершился, если размер вывода меньше чем вертикальный размер терминала. Это удобно для небольших файлов, так как вам не надо каждый раз нажимать `q`, чтобы выйти из пейджера. Третий флаг (`-X`) нужен для того, чтобы исправить баг с `--quit-if-one-screen` в старых версиях `less`. К сожалению, это блокирует возможность использования колеса мышки. Если вы хотите все же его включить, вы можете добавить флаг `-R`. Для `less` новее чем 530 оно должно работать из коробки. ### Темная тема Если вы используете темный режим в macOS, возможно вы захотите чтобы `bat` использовал другую тему, основанную на теме вашей ОС. Следующий сниппет использует тему `default`, когда у вас включен темный режим, и тему `GitHub`, когда включен светлый. ```bash alias cat="bat --theme=\$(defaults read -globalDomain AppleInterfaceStyle &> /dev/null && echo default || echo GitHub)" ``` ## Файл конфигурации `bat` также может быть кастомизирован с помощью файла конфигурации. Его местоположение зависит от вашей ОС: чтобы посмотреть его путь, введите ``` bat --config-file ``` Также вы можете установить переменную окружения `BAT_CONFIG_PATH`, чтобы изменить путь к файлу конфигурации. ```bash export BAT_CONFIG_PATH="/path/to/bat.conf" ``` Файл конфигурации «по умолчанию» может быть создан с помощью флага `--generate-config-file`. ```bash bat --generate-config-file ``` ### Формат Файл конфигурации - это всего лишь набор аргументов. Введите `bat --help`, чтобы просмотреть список всех возможных флагов и аргументов. Также вы можете закомментировать строку с помощью `#`. Пример файла конфигурации: ```bash # Установить тему "TwoDark" --theme="TwoDark" # Показывать количество строк, изменений в Git и заголовок файла --style="numbers,changes,header" # Использовать курсив (поддерживается не всеми терминалами) --italic-text=always # Использовать синтаксис C++ для всех Arduino .ino файлов --map-syntax "*.ino:C++" # Использовать синтаксик Git Ignore для всех файлов .ignore --map-syntax ".ignore:Git Ignore" ``` ## Использование `bat` в Windows `bat` полностью работоспособен "из коробки", но для некоторых возможностей могут понадобиться дополнительные настройки. ### Пейджинг Windows поддерживает только очень простой пейджер `more`. Вы можете скачать установщик для `less` [с его сайта](http://www.greenwoodsoftware.com/less/download.html) или [через Chocolatey](https://chocolatey.org/packages/Less). Чтобы его использовать, скопируйте исполняемый файл в ваш `PATH` или [используйте переменную окружения](#Использование-другого-пейджера). [Пакет из Chocolatey](#windows) установит все автоматически. ### Цвета Windows 10 поддерживает цвета и в `conhost.exe` (Command Prompt), и в PowerShell начиная с версии Windows [v1511](https://ru.wikipedia.org/wiki/Windows_10#Обновления и поддержка), так же как и в bash. На ранних версиях Windows вы можете использовать [Cmder](http://cmder.net/), в котором есть [ConEmu](https://conemu.github.io/). **Внимание:** Версия `less` в Git и MSYS2 воспроизводит цвета некорректно. Если у вас нет других пейджеров, мы можете отключить использование пейджеров с помощью флага `--paging=never` или установить `BAT_PAGER` равным пустой строке. ### Cygwin Из коробки `bat` не поддерживает пути в стиле Unix (`/cygdrive/*`). Когда указан абсолютный путь cygwin, `bat` выдаст следующую ошибку: `The system cannot find the path specified. (os error 3)` Она может быть решена добавлением следующей функции в `.bash_profile`: ```bash bat() { local index local args=("$@") for index in $(seq 0 ${#args[@]}) ; do case "${args[index]}" in -*) continue;; *) [ -e "${args[index]}" ] && args[index]="$(cygpath --windows "${args[index]}")";; esac done command bat "${args[@]}" } ``` ## Проблемы и их решение ### Терминалы и цвета `bat` поддерживает терминалы *с* и *без* поддержки truecolor. Однако подсветка синтаксиса не оптимизирована для терминалов с 8-битными цветами, и рекомендуется использовать терминалы с поддержкой 24-битных цветов (`terminator`, `konsole`, `iTerm2`, ...). Смотрите [эту статью](https://gist.github.com/XVilka/8346728) для полного списка терминалов. Удостовертесь, что переменная `COLORTERM` равна `truecolor` или `24bit`. Иначе `bat` не сможет определить поддержку 24-битных цветов (и будет использовать 8-битные). ### Текст и номера строк плохо видны Используйте другую тему (`bat --list-themes` выведет список всех установленных тем). Темы `OneHalfDark` и `OneHalfLight` имеют более яркие номера строк и тексты. ### Кодировки файлов `bat` поддерживает UTF-8 и UTF-16. Файлы в других кодировках, возможно, придётся перекодировать, так как кодировка может быть распознана неверно. Используйте `iconv`. Пример: у вас есть PHP файл в кодировке Latin-1 (ISO-8859-1): ``` bash iconv -f ISO-8859-1 -t UTF-8 my-file.php | bat ``` Внимание: вам может понадобится флаг `-l`/`--language`, если `bat` не сможет автоматически определить синтаксис. ## Разработка ```bash # Рекурсивно клонирует все модули git clone --recursive https://github.com/sharkdp/bat # Компиляции в режиме разработки cd bat cargo build --bins # Запуск тестов cargo test # Установка (релизная версия) cargo install --locked # Компилирование исполняего файла bat с другим синтаксисом и темами bash assets/create.sh cargo install --locked --force ``` ## Разработчики - [sharkdp](https://github.com/sharkdp) - [eth-p](https://github.com/eth-p) ## Цели и альтернативы Цели проекта `bat`: - Красивая и продвинутая подсветка синтаксиса. - Интеграция с Git. - Полноценная замена `cat`. - Дружелюбный интерфейс и аргументы. Есть очень много альтернатив `bat`. Смотрите [этот документ](doc/alternatives.md) для сравнения. ## Лицензия Copyright (c) 2018-2021 [Разработчики bat](https://github.com/sharkdp/bat). `bat` распостраняется под лицензями MIT License и Apache License 2.0 (на выбор пользователя). Смотрите [LICENSE-APACHE](LICENSE-APACHE) и [LICENSE-MIT](LICENSE-MIT) для более подробного ознакомления. bat-0.19.0/doc/README-zh.md000064400000000000000000000542220072674642500131610ustar 00000000000000

bat - a cat clone with wings
Build Status license Version info
类似 cat(1),但带有 git 集成和语法高亮.

主要功能使用方法安装自定义项目目标和替代方案
[English] [中文] [日本語] [한국어] [Русский]

### 语法高亮 `bat` 对大部分编程语言和标记语言提供语法高亮: ![Syntax highlighting example](https://imgur.com/rGsdnDe.png) ### Git 集成 `bat` 能从 git 中获取文件的修改并展示在边栏(见下图): ![Git integration example](https://i.imgur.com/2lSW4RE.png) ### 不可打印(non-printable)字符可视化 添加`-A`/`--show-all`参数可以文件文件中的不可打印字符: ![Non-printable character example](https://i.imgur.com/WndGp9H.png) ### 自动分页 `bat`会在一般情况下将大于屏幕可显示范围的内容输出到分页器(pager, e.g. `less`)。 你可以在调用时添加`--paging=never`参数来使`bat`不使用分页器(就像`cat`一样)。如果你想要用为`cat`使用`bat`别名,可以在 shell 配置文件(shell configuration)中添加`alias cat='bat --paging=never'`。 #### 智能输出 `bat`能够在设置了分页器选项的同时进行管道:wink:。 当`bat`检测到当前环境为非可交互终端或管道时(例如使用`bat`并将内容用管道输出到文件),`bat`会像`cat`一样,一次输出文件内容为纯文本且无视`--paging`参数。 ## 如何使用 在终端中查看一个文件 ```bash > bat README.md ``` 一次性展示多个文件 ```bash > bat src/*.rs ``` 从`stdin`读入流,自动为内容添加语法高亮(前提是输入内容的语言可以被正确识别,通常根据内容第一行的 shebang 标记,形如`#!bin/sh`) ```bash > curl -s https://sh.rustup.rs | bat ``` 显式指定`stdin`输入的语言 ```bash > yaml2json .travis.yml | json_pp | bat -l json ``` 显示不可打印字符 ```bash > bat -A /etc/hosts ``` 与`cat`的兼容性 ```bash bat > note.md # 创建一个空文件 bat header.md content.md footer.md > document.md bat -n main.rs # 只显示行号 bat f - g # 输出 f,接着是标准输入流,最后 g ``` ### 第三方工具交互 #### `fzf` 你可以使用`bat`作为`fzf`的预览器。这需要在`bat`后添加`--color=always`选项,以及`--line-range` 选项来限制大文件的加载次数。 ```bash fzf --preview 'bat --color=always --style=numbers --line-range=:500 {}' ``` 更多信息请参阅[`fzf`的说明](https://github.com/junegunn/fzf#preview-window)。 #### `find` 或 `fd` 你可以使用`find`的`-exec`选项来用`bat`预览搜索结果: ```bash find … -exec bat {} + ``` 亦或者在用`fd`时添加`-X`/`--exec-batch`选项: ```bash fd … -X bat ``` #### `ripgrep` `bat`也能用`batgrep`来显示`ripgrep`的搜索结果。 ```bash batgrep needle src/ ``` #### `tail -f` 当与`tail -f`一起使用,`bat`可以持续监视文件内容并为其添加语法高亮。 ```bash tail -f /var/log/pacman.log | bat --paging=never -l log ``` 注意:这项功能需要在关闭分页时使用,同时要手动指定输入的内容语法(通过`-l log`)。 #### `git` `bat`也能直接接受来自`git show`的输出并为其添加语法高亮(当然也需要手动指定语法): ```bash git show v0.6.0:src/main.rs | bat -l rs ``` #### `git diff` `bat`也可以和`git diff`一起使用: ```bash batdiff() { git diff --name-only --diff-filter=d | xargs bat --diff } ``` 该功能也作为一个独立工具提供,你可以在[`bat-extras`](https://github.com/eth-p/bat-extras)中找到`batdiff`。 如果你想了解更多 git 和 diff 的信息,参阅[`delta`](https://github.com/dandavison/delta)。 #### `xclip` 当需要拷贝文件内容时,行号以及 git 标记会影响输出,此时可以使用`-p`/`--plain`参数来把纯文本传递给`xclip`。 ```bash bat main.cpp | xclip ``` `bat`会检测输出是否是管道重定向来决定是否使用纯文本输出。 #### `man` `bat`也能给`man`的输出上色。这需要设置`MANPAGER`环境变量: ```bash export MANPAGER="sh -c 'col -bx | bat -l man -p'" man 2 select ``` (如果你使用的是 Debian 或者 Ubuntu,使用`batcat`替换`bat`) 如果你遇到格式化问题,设置`MANROFFOPT="-c"`也许会有帮助。 `batman`能提供类似功能——作为一个独立的命令。 注意:[man page 语法](assets/syntaxes/02_Extra/Manpage.sublime-syntax) 还需要完善。在使用特定的`man`实现时该功能[无法正常工作](https://github.com/sharkdp/bat/issues/1145)。 #### `prettier` / `shfmt` / `rustfmt` `prettybat`脚本能够格式化代码并用`bat`输出。 ## 安装 [![Packaging status](https://repology.org/badge/vertical-allrepos/bat-cat.svg)](https://repology.org/project/bat-cat/versions) ### Ubuntu (使用 `apt`) *... 以及其他基于 Debian的发行版.* `bat` 要求的版本: [Ubuntu 高于 20.04 ("Focal")](https://packages.ubuntu.com/search?keywords=bat&exact=1) 和 [Debian 高于 August 2021 (Debian 11 - "Bullseye")](https://packages.debian.org/bullseye/bat). 当你的发行版满足条件那么直接在终端运执行: ```bash sudo apt install bat ``` 重要:如果你通过这种方法安装`bat`,请留意你所安装的可执行文件是否为`batcat`(由[其他包的可执行文件名冲突](https://github.com/sharkdp/bat/issues/982)造成)。你可以创建一个`bat -> batcat`的符号链接(symlink)或别名来避免因为可执行文件不同带来的问题并与其他发行版保持一致性。 ```bash mkdir -p ~/.local/bin ln -s /usr/bin/batcat ~/.local/bin/bat ``` ### Ubuntu (使用`.deb`包) *... 以及其他基于 Debian的发行版.* 如果你无法使用上一种方法安装,或需要用最新版的`bat`,你可以从[release 页面](https://github.com/sharkdp/bat/releases)下载最新的`.deb`包并通过下述方法安装: ```bash sudo dpkg -i bat_0.18.3_amd64.deb # adapt version number and architecture ``` ### Alpine Linux 你可以用下面下列命令从官方源中安装[`bat 包`](https://pkgs.alpinelinux.org/packages?name=bat): ```bash apk add bat ``` ### Arch Linux 你可以用下面下列命令从官方源中安装[`bat`包](https://www.archlinux.org/packages/community/x86_64/bat/): ```bash pacman -S bat ``` ### Fedora 你可以使用下列命令从官方[Fedora Modular](https://docs.fedoraproject.org/en-US/modularity/using-modules/)仓库安装[`bat` 包](https://koji.fedoraproject.org/koji/packageinfo?packageID=27506): ```bash dnf install bat ``` ### Funtoo Linux 你可以从 dev-kit 中安装[`bat` 包](https://github.com/funtoo/dev-kit/tree/1.4-release/sys-apps/bat): ```bash emerge sys-apps/bat ``` ### Gentoo Linux 你可以使用下列命令从官方源中安装 [`bat` 包](https://packages.gentoo.org/packages/sys-apps/bat): ```bash emerge sys-apps/bat ``` ### Void Linux 你可以用 xbps-install 安装`bat`: ```bash xbps-install -S bat ``` ### Termux: 你可以用 pkg 安装`bat: ```bash pkg install bat ``` ### FreeBSD 你可以用 pkg 来安装一份预编译的[`bat` 包](https://www.freshports.org/textproc/bat): ```bash pkg install bat ``` 或从 FreeBSD ports 自己编译一份: ```bash cd /usr/ports/textproc/bat make install ``` ### OpenBSD 你可以用`pkg——add`安装`bat`包 ```bash pkg_add bat ``` ### 通过 nix 你可以用[nix 包管理器](https://nixos.org/nix)安装`bat`: ```bash nix-env -i bat ``` ### openSUSE 你可以用 zypper 安装`bat`: ```bash zypper install bat ``` ### 通过 snap 目前还没有推荐的 snap 包可用。可以使用其他现存的包但不会受到官方支持且可能会遇到[问题](https://github.com/sharkdp/bat/issues/1519)。 ### macOS (或 Linux) 通过 Homebrew 你可以用 [Homebrew on MacOS](https://formulae.brew.sh/formula/bat) 或者 [Homebrew on Linux](https://formulae.brew.sh/formula-linux/bat) 安装`bat`: ```bash brew install bat ``` ### macOS 通过 MacPorts 或用 [MacPorts](https://ports.macports.org/port/bat/summary) 安装`bat`: ```bash port install bat ``` ### Windows 在 Windows 上具有多种安装`bat`的方法。若你已完成安装,记得看看 ["在 Windows 上使用`bat`"](#在-Windows-中使用-bat) 。 #### 前置条件 你必须已安装 [Visual C++ Redistributable](https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads) 包。 #### 使用 Chocolatey 你可以用[Chocolatey](https://chocolatey.org/packages/Bat) 安装`bat`: ```bash choco install bat ``` #### 使用 Scoop 你可以用 [scoop](https://scoop.sh/) 安装`bat`: ```bash scoop install bat ``` #### 使用预编译二进制版本 直接从 [Release 发布页](https://github.com/sharkdp/bat/releases) 下载已经编译好的二进制包,前提是你安装了 [Visual C++ Redistributable](https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads) 包。 ### 使用二进制版本 在 [Release 发布页](https://github.com/sharkdp/bat/releases) 中可以找到为多种架构构建的`bat`版本和静态编译的二进制文件(文件名带有`musl`)。 ### 从源码编译 如果你想要自己构建`bat`,那么你需要安装有高于1.51版本的 Rust。 使用以下命令编译。 ```bash cargo install --locked bat ``` 注意:man page或 shell 自动补全所需要的额外文件无法通过该方法安装。但你可以在`cargo`的生成目录找到这些文件(`build`目录下)。 ## 自定义 ### 语法高亮主题 使用 `bat --list-themes` 一份语法高亮主题的清单,然后用`--theme=TwoDark`来指定主题为`TwoDark`,也可以通过设置`BAT_THEME`环境变量来选定主题。把`export BAT_THEME="TwoDark"`添加到 shell 的启动脚本(shell startup file)来取得永久效果。或者使用`bat`的[配置文件](#c配置文件) 若想要查看所有主题在一个文件上的显示效果可以用一下命令(需要安装`fzf`): ```bash bat --list-themes | fzf --preview="bat --theme={} --color=always /path/to/file" ``` `bat`在默认情况下能够在黑色主题背景下获得较好的效果,如果你的终端使用亮色背景,可以试试`GitHub`或`OneHalfLight`。想要添加自定义主题可以参考[添加主题](#添加主题)。 ### 8-bit 主题 `bat` 自带三个 [8-bit 色彩](https://en.wikipedia.org/wiki/ANSI_escape_code#Colors) 主题: - `ansi` 适应于大部分终端。它使用 3-bit 色彩:黑红绿黄蓝洋红靛青白。 - `base16`专为 [base16](https://github.com/chriskempson/base16) 终端设计。它使用 4-bit 色彩(带有亮度的 3-bit 色彩)。根据 [base16 styling guidelines](https://github.com/chriskempson/base16/blob/master/styling.md) 制作。 - `base16-25`专为 [base16-shell](https://github.com/chriskempson/base16-shell) 设计。它把部分亮色替换为 8-bit 色彩。请不要直接使用该主题,除非你清楚你的256色终端是否使用 base16-shell。 尽管这些主题具有诸多限制,但具有一些 truecolor 主题不具有的三个优点: - 享有最佳兼容性。并不是所有终端工具都支持高于 3-bit 的色彩。 - 适应终端主题。 - 视觉上和其他的终端工具更协调。 ### 输出样式 你可以用`--style`参数来控制`bat`输出的样式。使用`--style=numbers,chanegs`可以只开启 Git 修改和行号显示而不添加其他内容。`BAT_STYLE`环境变量具有相同功能。 ### 添加新的语言和语法 当现有的`bat`不支持某个语言或语法时你可以自己添加。 `bat`使用`syntect`库来支持语法高亮,该库使用 [Sublime Text `.sublime-syntax` 语法文件](https://www.sublimetext.com/docs/3/syntax.html)和主题。而后者中的大部分可以在 [Package Control](https://packagecontrol.io/) 找到。 当你找到一份语法文件,按照下列方法: 1. 创建包含语法描述文件的目录: ```bash mkdir -p "$(bat --config-dir)/syntaxes" cd "$(bat --config-dir)/syntaxes" # Put new '.sublime-syntax' language definition files # in this folder (or its subdirectories), for example: git clone https://github.com/tellnobody1/sublime-purescript-syntax ``` 2. 调用下面指令把文件转换为二进制缓存: ```bash bat cache --build ``` 3. 最后用`bat --list-languages`来检查新的语法是否被成功导入。如果想要回滚到最初状态,执行: ```bash bat cache --clear ``` 4. 如果你觉得`bat`有必要自带该语法支持,请在阅读[指导](doc/assets.md)后向仓库提交 [Syntax Request](https://github.com/sharkdp/bat/issues/new?labels=syntax-request&template=syntax_request.md)。 ### 添加主题 类似添加语法支持,第一步也是创建一个带有语法高亮的目录 ```bash mkdir -p "$(bat --config-dir)/themes" cd "$(bat --config-dir)/themes" # 下载一个主题 git clone https://github.com/greggb/sublime-snazzy # 更新二进制缓存 bat cache --build ``` 然后用`bat --list-themes`检查添加是否成功。 ### 添加或修改文件关联 你可以用`--map-syntax`参数添加或修改文件名模板。它需要一个类似`pattern:syntax`的参数来指定,其中`pattern`是 glob 文件匹配模板,`syntax`则是支持的语法的完整名(使用`bat --list-languages`来查看获取一份清单)。 注意:方便起见,你可能需要把参数添加到配置文件,而不是每次都在命令行中传递该参数。 以下展示了把“INI”关联到具有`.conf`扩展名的文件 ```bash --map-syntax='*.conf:INI' ``` 把`.ignore`文件与“Git Ignore”关联 ```bash --map-syntax='.ignore:Git Ignore' ``` 把`/etc/apache2`内的`.conf`文件关联到“Apache Conf”语法(`bat`已默认绑定) ```bash --map-syntax='/etc/apache2/**/*.conf:Apache Conf' ``` ### 使用自定义分页器 `bat`默认使用`PAGER`环境变量定义的分页器,如果没有定义则使用`less`。`bat`提供了`BAT_PAGER`环境变量来专为`bat`选择分页器(优先级高于`PAGER`)。 注意:当`PAGER`设置为`more`或`most`时,`bat`会使用`less`来代替以确保能提供色彩支持。 ```bash export BAT_PAGER="less -RF" ``` 除了使用环境变量来改变`bat`使用的的分页器,也可以在配置文件中提供`--pager`参数。 注意:`bat`会把部分命令行参数直接传递给分页器:`-R`/`--RAW-CONTROL-CHARS`,`-F`/`--quit-if-one-screen`以及`-X`/`--no-init`(该参数仅适用于高于530版本的`less`)。其中`-R` 参数需要在解释 ANSI 标准颜色时起作用。`-F`则指示`less`在输出内容的垂直尺寸小于终端尺寸时立即退出。当文件内容可以在一个屏幕里完全显示时,就不需要按`q`键退出阅读模式,很方便就是了。`-X`则能修复`-F`在`less`的老版本中的一些bug(代价是不支持鼠标滚轮,但可以用`-R`来取消`quit-if-one-screen`功能。)。 ### 缩进 `bat` 使用四个空格宽的制表符,而不受分页器影响,同时也可以用`--tabs`参数来自定义。 注意:通过其他方法针对分页器的制表符设置不会生效(例如通过`bat`的`--pager`参数传递或`less`使用的`LESS`环境变量)。因为在输出提交给分页器之前,内容中的制表符就已经被`bat`替换为了特定长度的空格以避免由于边栏导致的缩进问题。你可以用给`bat`传递`--tabs=0`参数来取消该设定并让分页器自己处理制表符。 ### 暗色模式 如果你用的 macOS 处于暗色模式,你可以为`bat`启用基于系统主题的主题。如下所示操作会让`bat`在系统处于亮色模式时加载`GitHub`主题和暗色模式时加载`default`主题。 ```bash alias cat="bat --theme=\$(defaults read -globalDomain AppleInterfaceStyle &> /dev/null && echo default || echo GitHub)" ``` ## 配置文件 ```bash bat --config-file ``` 你也可以用`BAT_CONFIG_PATH`来为`bat`指定自定义位置的配置文件: ```bash export BAT_CONFIG_PATH="/path/to/bat.conf" ``` 使用`--generate-config-file`参数调用`bat`会在指定位置生成一份默认的`bat`配置文件: ```bash bat --generate-config-file ``` ### 格式 配置文件其实是一份按行分割的命令行参数列表。你可以用`bat --help`来查看所有可用的参数和适用的值。配置文件中`#`打头的行会被视为注释而不生效。 以下是一份示例: ```bash # 设置主题为 TwoDark --theme="TwoDark" # 显示行号和 Git 修改信息, 但没有边框 --style="numbers,changes,header" # 在终端中以斜体输出文本(不是所有终端都支持) --italic-text=always # 使用 C++ 语法来给 Ardiuno 的 .ino 文件提供高亮 --map-syntax "*.ino:C++" ``` ## 在 Windows 中使用 `bat` `bat` 在 Windows 上开箱即用,除了部分功能需要额外配置。 ### 前置条件 你需要先安装 [Visual C++ Redistributable](https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads) 包。 ### 分页 Windows 只有一个提供有限功能的分页器,你可以从[这里下载](http://www.greenwoodsoftware.com/less/download.html)或用 [Chocolatey 安装](https://chocolatey.org/packages/Less) Windows 版本的`less`。第一种方法需要你把它所在目录加入`PATH`环境变量或[定义分页器变量](#使用自定义分页器) ### 色彩 Windows 10 从 [v1511](https://en.wikipedia.org/wiki/Windows_10_version_history#Version_1511_(November_Update)) 开始 shell(`conhost.exe`,命令提示符或 Powershell)原生支持色彩。在早些版本的 Windows 中你可以用第三方终端如 [Cmder](http://cmder.net/) (使用[ConEmu](https://conemu.github.io/))。 注意:Git 和 MSYS 版本的 `less` 没法正确在 Windows 表达色彩。如果你没有安装其他分页器,你可以直接用`--paging=never`或设置`BAT_PAGER`为空字符串来关闭分页功能。 ### Cygwin Windows 上的`bat`原生不支持 Cygwin' unix-style 路径(`/cygdrive/*`)。当传递一个绝对 cygwin 路径作为参数值时,`bat`会产生`The system cannot find the path specified. (os error 3)`的错误。你可以`.bash_profile`文件中添加以下函数来解决这个问题。 ```bash bat() { local index local args=("$@") for index in $(seq 0 ${#args[@]}) ; do case "${args[index]}" in -*) continue;; *) [ -e "${args[index]}" ] && args[index]="$(cygpath --windows "${args[index]}")";; esac done command bat "${args[@]}" } ``` ## 疑难解答 ### 输出内容含糊不清 当输入文件包含颜色代码和其他 ANSI 转义符号时,`bat`会产生错误的语法高亮和文本,导致输出看起来令人无法理解。当你需要输出该文件时,请使用`--color=never --wrap=never`参数来关闭上色和文字包裹。 ### 终端与色彩 `bat`会区分支持 truecolor 和不支持 truecolor 的终端。但是大部分语法高亮主题都是用了没有为 8-bit 色彩支持的颜色,因此强烈推荐使用一个支持 24-bit 色彩的终端(`terminator`,`konsole`,`iTerm2`...),或使用一个 [8-bit 主题](#8-bit-主题)来限制一些颜色。查看[这篇文章使用自定义分页器](https://gist.github.com/XVilka/8346728)了解更多支持 truecolor 的终端。你需要定义`COLORTERM`变量为`truecolor`或`24bit`来确保`bat`能够识别终端的对颜色的支持,否则会使用 8 bit 模式。 ### 行号和边框很难看清 试试其他主题,说不定能有所改善(用`bat --list-themes`查看主题列表)。 ### 文件编码 `bat`原生支持 UTF-8 和 UTF-16。至于其他文件你可能需要在使用`bat`之前先把编码转换到UTF-8。 这里展示了使用`iconv`来把 Latin-1(ISO-8859-1) 编码的 PHP 文件转换到 UTF-8: ```bash iconv -f ISO-8859-1 -t UTF-8 my-file.php | bat ``` 注意: 当`bat`无法识别语言时你可能会需要`-l`/`--language`参数。 ## Development ```bash # Recursive clone to retrieve all submodules git clone --recursive https://github.com/sharkdp/bat # Build (debug version) cd bat cargo build --bins # Run unit tests and integration tests cargo test # Install (release version) cargo install --path . --locked # Build a bat binary with modified syntaxes and themes bash assets/create.sh cargo install --path . --locked --force ``` If you want to build an application that uses `bat`s pretty-printing features as a library, check out the [the API documentation](https://docs.rs/bat/). Note that you have to use either `regex-onig` or `regex-fancy` as a feature when you depend on `bat` as a library. ## Contributing Take a look at the [`CONTRIBUTING.md`](CONTRIBUTING.md) guide. ## Maintainers - [sharkdp](https://github.com/sharkdp) - [eth-p](https://github.com/eth-p) - [keith-hall](https://github.com/keith-hall) - [Enselic](https://github.com/Enselic) ## Security vulnerabilities Please contact [David Peter](https://david-peter.de/) via email if you want to report a vulnerability in `bat`. ## Project goals and alternatives `bat` tries to achieve the following goals: - Provide beautiful, advanced syntax highlighting - Integrate with Git to show file modifications - Be a drop-in replacement for (POSIX) `cat` - Offer a user-friendly command-line interface There are a lot of alternatives, if you are looking for similar programs. See [this document](doc/alternatives.md) for a comparison. ## License Copyright (c) 2018-2021 [bat-developers](https://github.com/sharkdp/bat). `bat` is made available under the terms of either the MIT License or the Apache License 2.0, at your option. See the [LICENSE-APACHE](LICENSE-APACHE) and [LICENSE-MIT](LICENSE-MIT) files for license details. bat-0.19.0/doc/alternatives.md000064400000000000000000000156100072674642500143040ustar 00000000000000# Alternatives The following table tries to give an overview *from `bat`s perspective*, i.e. we only compare categories which are relevant for `bat`. Some of these projects have completely different goals and if you are not looking for a program like `bat`, this comparison might not be for you. | | bat | [pygments](http://pygments.org/) | [highlight](http://www.andre-simon.de/doku/highlight/highlight.php) | [ccat](https://github.com/jingweno/ccat) | [source-highlight](https://www.gnu.org/software/src-highlite/) | [hicat](https://github.com/rstacruz/hicat) | [coderay](https://github.com/rubychan/coderay) | [rouge](https://github.com/jneen/rouge) | |----------------------------------------------|---------------------------------------------------------------------|----------------------------------|---------------------------------------------------------------------|------------------------------------------|----------------------------------------------------------------|-----------------------------------------------------|-----------------------------------------------------|-----------------------------------------------------| | Drop-in `cat` replacement | :heavy_check_mark: [*](https://github.com/sharkdp/bat/issues/134) | :x: | :x: | (:heavy_check_mark:) | :x: | :x: [*](https://github.com/rstacruz/hicat/issues/6) | :x: | :x: | | Git integration | :heavy_check_mark: | :x: | :x: | :x: | :x: | :x: | :x: | :x: | | Automatic paging | :heavy_check_mark: | :x: | :x: | :x: | :x: | :heavy_check_mark: | :x: | :x: | | Languages (circa) | 150 | 300 | 200 | 7 | 80 | 130 | 30 | 130 | | Extensible (languages, themes) | :heavy_check_mark: | (:heavy_check_mark:) | (:heavy_check_mark:) | :x: | (:heavy_check_mark:) | :x: | :x: | :x: | | Advanced highlighting (e.g. nested syntaxes) | :heavy_check_mark: | :heavy_check_mark: | (:heavy_check_mark:) ? | :x: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | Execution time [ms] (`jquery-3.3.1.js`) | 624 | 789 | 400 | 80 | 300 | 316 | 157 | 695 | | Execution time [ms] (`miniz.c`) | 66 | 656 | 26 | 8 | 53 | 141 | 75 | 254 | | Execution time [ms] (370 kB XML file) | 238 | 487 | 129 | 111 | 110 | 339 | 147 | 359 | If you think that some entries in this table are outdated or wrong, please open a ticket or pull request. Some other alternatives that are also related, but not yet included in the table: - [lesspipe](https://github.com/wofr06/lesspipe) - [vimpager](https://github.com/rkitover/vimpager) ## Benchmarks The benchmarks above have been created with this script: ```bash #!/usr/bin/env bash cd "$(dirname "${BASH_SOURCE[0]}")" || exit if ! command -v hyperfine > /dev/null 2>&1; then echo "'hyperfine' does not seem to be installed." echo "You can get it here: https://github.com/sharkdp/hyperfine" exit 1 fi SRC="test-src/jquery-3.3.1.js" cmd_bat="bat --style=full --color=always --paging=never '$SRC'" cmd_bat_simple="bat --plain --wrap=never --tabs=0 --color=always --paging=never '$SRC'" cmd_pygmentize="pygmentize -g '$SRC'" cmd_highlight="highlight -O truecolor '$SRC'" cmd_ccat="ccat --color=always '$SRC'" cmd_source_highlight="source-highlight --failsafe --infer-lang -f esc -i '$SRC'" cmd_hicat="hicat '$SRC'" cmd_coderay="coderay '$SRC'" cmd_rouge="rougify '$SRC'" hyperfine --warmup 3 \ "$cmd_bat" \ "$cmd_bat_simple" \ "$cmd_pygmentize" \ "$cmd_highlight" \ "$cmd_ccat" \ "$cmd_source_highlight" \ "$cmd_hicat" \ "$cmd_coderay" \ "$cmd_rouge" \ ``` bat-0.19.0/doc/assets.md000064400000000000000000000140600072674642500131030ustar 00000000000000## Adding new builtin languages for syntax highlighting Should you find that a particular syntax is not available within `bat` and think it should be included in `bat` by default, you can follow the instructions outlined below. `bat` uses the excellent [syntect](https://github.com/trishume/syntect) library to highlight source code. As a basis, syntect uses [Sublime Text](https://www.sublimetext.com/) syntax definitions in the `.sublime-syntax` format. **Important:** Before proceeding, verify that the syntax you wish to add meets the [criteria for inclusion](#Criteria-for-inclusion-of-new-syntaxes). 1. Find a Sublime Text syntax for the given language, preferably in a separate Git repository which can be included as a submodule (under `assets/syntaxes`) using `git submodule add ./assets/syntaxes/02_Extra/`, replacing the contents of the angle brackets as appropriate. 2. If the Sublime Text syntax is only available as a `.tmLanguage` file, open the file in Sublime Text and convert it to a `.sublime-syntax` file via *Tools* -> *Developer* -> *New Syntax from XXX.tmLanguage...*. Save the new file in the `assets/syntaxes` folder. 3. Run the `assets/create.sh` script. It calls `bat cache --build` to parse all available `.sublime-syntax` files and serialize them to a `syntaxes.bin` file. 4. Re-compile `bat`. At compilation time, the `syntaxes.bin` file will be stored inside the `bat` binary. 5. Use `bat --list-languages` to check if the new languages are available. 6. Add a syntax test for the new language. See [below](#Syntax-tests) for details. 7. If you send a pull request with your changes, please do *not* include the changed `syntaxes.bin` file. A new binary cache file will be created once before every new release of `bat`. This avoids bloating the repository size unnecessarily. ### Syntax tests `bat` has a set of syntax highlighting regression tests in `tests/syntax-tests`. The main idea is make sure that we do not run into issues we had in the past where either (1) syntax highlighting for some language is suddenly not working anymore or (2) `bat` suddenly crashes for some input (due to `regex` incompatibilities between `syntect` and Sublime Text). In order to add a new test file, please follow these steps (let's take "Ruby" as an example): 1. Make sure that you are running the **latest version of `bat`** and that `bat` is available on the path. If you are creating a syntax test for a new builtin syntax (see above), make sure that your version of `bat` already has the new syntax builtin. 2. Find an example Ruby source file or write one yourself. If possible, the file should aim to be "comprehensive" (i.e. include a lot of the possible syntax), but this is not strictly necessary. A simple file is better than none at all. Also, the files shouldn't be gigantic. 3. Save the file in `tests/syntax-tests/source/Ruby` (adapt for your language). The file name could be `test.rb` (adapt extension) but can also be adapted if that is necessary in order for `bat` to highlight it correctly (e.g. `Makefile`). 4. If you have copied the file from somewhere else, please make sure that the file *may* be copied under the respective license and that the license is compatible with `bat`s license. If it requires attribution, please add a `LICENSE.md` in the same folder with a text like this: ``` The `test.rb` file has been added from [enter source here] under the following license: [add license text here] ``` 5. Go to `tests/syntax-tests` and run the `update.sh` Bash script. A new file should be generated in the `highlighted` folder (e.g. `highlighted/Ruby/test.rb`). 6. Use `cat` or `bat --language=txt` to display the content of this file and make sure that the syntax highlighting looks correct. 7. `git add` the new files in the `source` folder as well as the autogenerated files in the `highlighted` folder. ### Troubleshooting Make sure that the local cache does not interfere with the internally stored syntaxes and themes (`bat cache --clear`). ## Criteria for inclusion of new syntaxes * More than 10,000 downloads at [Package Control](https://packagecontrol.io) ### Manual modifications The following files have been manually modified after converting from a `.tmLanguage` file: * `Apache.sublime_syntax`=> removed `.conf` and `.CONF` file types. * `Dart.sublime-syntax` => removed `#regex.dart` include. * `INI.sublime-syntax` => added `.hgrc`, `hgrc`, and `desktop` file types and support for comments after section headers * `Org mode.sublime-syntax` => removed `task` file type. * `SML.sublime_syntax` => removed `ml` file type. * `Robot.sublime_syntax` => changed name to "Robot Framework", added `.resource` extension ### Non-submodule additions * `Assembly (x86_64)` has been manually added from https://github.com/13xforever/x86-assembly-textmate-bundle due to `git clone` recursion problems * `Nim.sublime-syntax` has been added manually from https://github.com/getzola/zola/blob/master/sublime_syntaxes/Nim.sublime-syntax as there was no suitable Git repository for it. The original syntax seems to originate from https://github.com/Varriount/NimLime * `Rego.sublime-syntax` has been added manually from https://github.com/open-policy-agent/opa/blob/master/misc/syntax/sublime/rego.sublime-syntax as it is not kept in a standalone repository. The file is generated from https://github.com/open-policy-agent/opa/blob/master/misc/syntax/textmate/Rego.tmLanguage * `SML.sublime_syntax` has been added manually from https://github.com/seanjames777/SML-Language-Definitiona as it is not kept in a standalone repository. The file generated is from https://github.com/seanjames777/SML-Language-Definition/blob/master/sml.tmLanguage * `Cabal.sublime_syntax` has been added manually from https://github.com/SublimeHaskell/SublimeHaskell/ - we don't want to include the whole submodule because it includes other syntaxes ("Haskell improved") as well. * `Lean.sublime-syntax` has been added manually from https://github.com/leanprover/vscode-lean/blob/master/syntaxes/lean.json via conversion. bat-0.19.0/doc/logo-header.svg000064400000000000000000000566030072674642500141770ustar 00000000000000 image/svg+xml bat-0.19.0/doc/release-checklist.md000064400000000000000000000052360072674642500151750ustar 00000000000000# Release checklist ## Dependencies See this page for a good overview: https://deps.rs/repo/github/sharkdp/bat - [ ] Optional: update dependencies with `cargo update`. This is also done by dependabot, so it is not strictly necessary. - [ ] Install [cargo-outdated](https://crates.io/crates/cargo-outdated). Check for outdated dependencies with `cargo outdated --root-deps-only` and decide for each of them whether we want to (manually) upgrade. This will require changes to `Cargo.toml`. ## Version bump - [ ] Update version in `Cargo.toml`. Run `cargo build` to update `Cargo.lock`. Make sure to `git add` the `Cargo.lock` changes as well. - [ ] Find the current min. supported Rust version by running `grep '^\s*MIN_SUPPORTED_RUST_VERSION' .github/workflows/CICD.yml`. - [ ] Update the version and the min. supported Rust version in `README.md` and `doc/README-*.md`. Check with `git grep -i 'rust.*1\.'` and `git grep -i '1\..*rust'`. - [ ] Update `CHANGELOG.md`. Introduce a section for the new release. ## Update syntaxes and themes (build assets) - [ ] Install the latest master version (`cargo install -f --path .`) and make sure that it is available on the `PATH` (`bat --version` should show the new version). - [ ] Run `assets/create.sh` and check in the binary asset files. ## Documentation - [ ] Review the `-h` and `--help` texts - [ ] Review the `man` page ## Pre-release checks - [ ] Push all changes and wait for CI to succeed (before continuing with the next section). - [ ] Optional: manually test the new features and command-line options. To do this, install the latest `bat` version again (to include the new syntaxes and themes). - [ ] Run `cargo publish --dry-run --allow-dirty` to make sure that it will succeed later (after creating the GitHub release). ## Release - [ ] Create a tag and push it: `git tag vX.Y.Z; git push origin tag vX.Y.Z`. This will trigger the deployment via GitHub Actions. - [ ] Go to https://github.com/sharkdp/bat/releases/new to create the new release. Select the new tag and also use it as the release title. For the release notes, copy the corresponding section from `CHANGELOG.md` and possibly add additional remarks for package maintainers. Publish the release. - [ ] Check if the binary deployment works (archives and Debian packages should appear when the CI run for the Git tag has finished). - [ ] Publish to crates.io by running `cargo publish` in a *clean* repository. The safest way to do this is to clone a fresh copy. ## Post-release - [ ] Prepare a new (empty) "unreleased" section at the top of `CHANGELOG.md`. bat-0.19.0/examples/advanced.rs000064400000000000000000000010410072674642500144360ustar 00000000000000/// A program that prints its own source code using the bat library use bat::{PagingMode, PrettyPrinter, WrappingMode}; fn main() { PrettyPrinter::new() .header(true) .grid(true) .line_numbers(true) .use_italics(true) // The following line will be highlighted in the output: .highlight(line!() as usize) .theme("1337") .wrapping_mode(WrappingMode::Character) .paging_mode(PagingMode::QuitIfOneScreen) .input_file(file!()) .print() .unwrap(); } bat-0.19.0/examples/cat.rs000064400000000000000000000005250072674642500134460ustar 00000000000000/// A very simple colorized `cat` clone, using `bat` as a library. /// See `src/bin/bat` for the full `bat` application. use bat::PrettyPrinter; fn main() { PrettyPrinter::new() .header(true) .grid(true) .line_numbers(true) .input_files(std::env::args_os().skip(1)) .print() .unwrap(); } bat-0.19.0/examples/inputs.rs000064400000000000000000000011620072674642500142170ustar 00000000000000/// A small demonstration of the Input API. /// This prints embedded bytes with a custom header and then reads from STDIN. use bat::{Input, PrettyPrinter}; fn main() { PrettyPrinter::new() .header(true) .grid(true) .line_numbers(true) .inputs(vec![ Input::from_bytes(b"echo 'Hello World!'") .name("embedded.sh") // Dummy name provided to detect the syntax. .kind("Embedded") .title("An embedded shell script."), Input::from_stdin().title("Standard Input").kind("FD"), ]) .print() .unwrap(); } bat-0.19.0/examples/list_syntaxes_and_themes.rs000064400000000000000000000006500072674642500177760ustar 00000000000000/// A simple program that prints its own source code using the bat library use bat::PrettyPrinter; fn main() { let printer = PrettyPrinter::new(); println!("Syntaxes:"); for syntax in printer.syntaxes() { println!("- {} ({})", syntax.name, syntax.file_extensions.join(", ")); } println!(); println!("Themes:"); for theme in printer.themes() { println!("- {}", theme); } } bat-0.19.0/examples/simple.rs000064400000000000000000000002610072674642500141650ustar 00000000000000/// A simple program that prints its own source code using the bat library use bat::PrettyPrinter; fn main() { PrettyPrinter::new().input_file(file!()).print().unwrap(); } bat-0.19.0/examples/yaml.rs000064400000000000000000000015410072674642500136400ustar 00000000000000/// A program that serializes a Rust structure to YAML and pretty-prints the result use bat::{Input, PrettyPrinter}; use serde::Serialize; #[derive(Serialize)] struct Person { name: String, height: f64, adult: bool, children: Vec, } fn main() { let person = Person { name: String::from("Anne Mustermann"), height: 1.76f64, adult: true, children: vec![Person { name: String::from("Max Mustermann"), height: 1.32f64, adult: false, children: vec![], }], }; let bytes = serde_yaml::to_vec(&person).unwrap(); PrettyPrinter::new() .language("yaml") .line_numbers(true) .grid(true) .header(true) .input(Input::from_bytes(&bytes).name("person.yaml").kind("File")) .print() .unwrap(); } bat-0.19.0/src/assets/assets_metadata.rs000064400000000000000000000054100072674642500163120ustar 00000000000000use std::fs::File; use std::path::Path; use std::time::SystemTime; use semver::Version; use serde::{Deserialize, Serialize}; use crate::error::*; #[derive(Debug, PartialEq, Default, Serialize, Deserialize)] pub struct AssetsMetadata { bat_version: Option, creation_time: Option, } const FILENAME: &str = "metadata.yaml"; impl AssetsMetadata { #[cfg(feature = "build-assets")] pub(crate) fn new(current_version: &str) -> AssetsMetadata { AssetsMetadata { bat_version: Some(current_version.to_owned()), creation_time: Some(SystemTime::now()), } } #[cfg(feature = "build-assets")] pub(crate) fn save_to_folder(&self, path: &Path) -> Result<()> { let file = File::create(path.join(FILENAME))?; serde_yaml::to_writer(file, self)?; Ok(()) } fn try_load_from_folder(path: &Path) -> Result { let file = File::open(path.join(FILENAME))?; Ok(serde_yaml::from_reader(file)?) } /// Load metadata about the stored cache file from the given folder. /// /// There are several possibilities: /// - We find a metadata.yaml file and are able to parse it /// => return the contained information /// - We find a metadata.yaml file and but are not able to parse it /// => return a SerdeYamlError /// - We do not find a metadata.yaml file but a syntaxes.bin or themes.bin file /// => assume that these were created by an old version of bat and return /// AssetsMetadata::default() without version information /// - We do not find a metadata.yaml file and no cached assets /// => no user provided assets are available, return None pub fn load_from_folder(path: &Path) -> Result> { match Self::try_load_from_folder(path) { Ok(metadata) => Ok(Some(metadata)), Err(e) => { if let Error::SerdeYamlError(_) = e { Err(e) } else if path.join("syntaxes.bin").exists() || path.join("themes.bin").exists() { Ok(Some(Self::default())) } else { Ok(None) } } } } pub fn is_compatible_with(&self, current_version: &str) -> bool { let current_version = Version::parse(current_version).expect("bat follows semantic versioning"); let stored_version = self .bat_version .as_ref() .and_then(|ver| Version::parse(ver).ok()); if let Some(stored_version) = stored_version { current_version.major == stored_version.major && current_version.minor == stored_version.minor } else { false } } } bat-0.19.0/src/assets/build_assets/acknowledgements.rs000064400000000000000000000144320072674642500211670ustar 00000000000000use std::fs::read_to_string; use std::path::{Path, PathBuf}; use walkdir::DirEntry; use crate::error::*; struct PathAndStem { path: PathBuf, stem: String, relative_path: String, } /// Looks for LICENSE and NOTICE files in `source_dir`, does some rudimentary /// analysis, and compiles them together in a single string that is meant to be /// used in the output to `--acknowledgements` pub fn build_acknowledgements( source_dir: &Path, include_acknowledgements: bool, ) -> Result> { if !include_acknowledgements { return Ok(None); } let mut acknowledgements = format!("{}\n\n", include_str!("../../../NOTICE")); // Sort entries so the order is stable over time let entries = walkdir::WalkDir::new(source_dir).sort_by(|a, b| a.path().cmp(b.path())); for path_and_stem in entries .into_iter() .flatten() .flat_map(|entry| to_path_and_stem(source_dir, entry)) { if let Some(license_text) = handle_file(&path_and_stem)? { append_to_acknowledgements( &mut acknowledgements, &path_and_stem.relative_path, &license_text, ) } } Ok(Some(acknowledgements)) } fn to_path_and_stem(source_dir: &Path, entry: DirEntry) -> Option { let path = entry.path(); Some(PathAndStem { path: path.to_owned(), stem: path.file_stem().map(|s| s.to_string_lossy().to_string())?, relative_path: path .strip_prefix(source_dir) .map(|p| p.to_string_lossy().to_string()) .ok()?, }) } fn handle_file(path_and_stem: &PathAndStem) -> Result> { if path_and_stem.stem == "NOTICE" { handle_notice(&path_and_stem.path) } else if path_and_stem.stem.to_ascii_uppercase() == "LICENSE" { handle_license(&path_and_stem.path) } else { Ok(None) } } fn handle_notice(path: &Path) -> Result> { // Assume NOTICE as defined by Apache License 2.0. These must be part of acknowledgements. Ok(Some(read_to_string(path)?)) } fn handle_license(path: &Path) -> Result> { let license_text = read_to_string(path)?; if include_license_in_acknowledgments(&license_text) { Ok(Some(license_text)) } else if license_not_needed_in_acknowledgements(&license_text) { Ok(None) } else { Err(format!("ERROR: License is of unknown type: {:?}", path).into()) } } fn include_license_in_acknowledgments(license_text: &str) -> bool { let markers = vec![ // MIT "The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.", // BSD "Redistributions in binary form must reproduce the above copyright notice,", // Apache 2.0 "Apache License Version 2.0, January 2004 http://www.apache.org/licenses/", "Licensed under the Apache License, Version 2.0 (the \"License\");", ]; license_contains_marker(license_text, &markers) } fn license_not_needed_in_acknowledgements(license_text: &str) -> bool { let markers = vec![ // Public domain "This is free and unencumbered software released into the public domain.", // Special license of assets/syntaxes/01_Packages/LICENSE "Permission to copy, use, modify, sell and distribute this software is granted. This software is provided \"as is\" without express or implied warranty, and with no claim as to its suitability for any purpose." ]; license_contains_marker(license_text, &markers) } fn license_contains_marker(license_text: &str, markers: &[&str]) -> bool { let normalized_license_text = normalize_license_text(license_text); markers.iter().any(|m| normalized_license_text.contains(m)) } fn append_to_acknowledgements( acknowledgements: &mut String, relative_path: &str, license_text: &str, ) { acknowledgements.push_str(&format!("## {}\n\n{}", relative_path, license_text)); // Make sure the last char is a newline to not mess up formatting later if acknowledgements .chars() .last() .expect("acknowledgements is not the empty string") != '\n' { acknowledgements.push('\n'); } // Add two more newlines to make it easy to distinguish where this text ends // and the next starts acknowledgements.push_str("\n\n"); } /// Replaces newlines with a space character, and replaces multiple spaces with one space. /// This makes the text easier to analyze. fn normalize_license_text(license_text: &str) -> String { use regex::Regex; let whitespace_and_newlines = Regex::new(r"\s").unwrap(); let as_single_line = whitespace_and_newlines.replace_all(license_text, " "); let many_spaces = Regex::new(" +").unwrap(); many_spaces.replace_all(&as_single_line, " ").to_string() } #[cfg(test)] mod tests { #[cfg(test)] use super::*; #[test] fn test_normalize_license_text() { let license_text = "This is a license text with these terms: * Complicated multi-line term with indentation"; assert_eq!( "This is a license text with these terms: * Complicated multi-line term with indentation".to_owned(), normalize_license_text(license_text), ); } #[test] fn test_normalize_license_text_with_windows_line_endings() { let license_text = "This license text includes windows line endings\r and we need to handle that."; assert_eq!( "This license text includes windows line endings and we need to handle that." .to_owned(), normalize_license_text(license_text), ); } #[test] fn test_append_to_acknowledgements_adds_newline_if_missing() { let mut acknowledgements = "preamble\n\n\n".to_owned(); append_to_acknowledgements(&mut acknowledgements, "some/path", "line without newline"); assert_eq!( "preamble ## some/path line without newline ", acknowledgements ); append_to_acknowledgements(&mut acknowledgements, "another/path", "line with newline\n"); assert_eq!( "preamble ## some/path line without newline ## another/path line with newline ", acknowledgements ); } } bat-0.19.0/src/assets/build_assets.rs000064400000000000000000000113030072674642500156270ustar 00000000000000use std::convert::TryInto; use std::path::Path; use syntect::highlighting::ThemeSet; use syntect::parsing::{SyntaxSet, SyntaxSetBuilder}; use crate::assets::*; use acknowledgements::build_acknowledgements; mod acknowledgements; pub fn build( source_dir: &Path, include_integrated_assets: bool, include_acknowledgements: bool, target_dir: &Path, current_version: &str, ) -> Result<()> { let theme_set = build_theme_set(source_dir, include_integrated_assets)?; let syntax_set_builder = build_syntax_set_builder(source_dir, include_integrated_assets)?; let syntax_set = syntax_set_builder.build(); let acknowledgements = build_acknowledgements(source_dir, include_acknowledgements)?; print_unlinked_contexts(&syntax_set); write_assets( &theme_set, &syntax_set, &acknowledgements, target_dir, current_version, ) } fn build_theme_set(source_dir: &Path, include_integrated_assets: bool) -> Result { let mut theme_set = if include_integrated_assets { crate::assets::get_integrated_themeset().try_into()? } else { ThemeSet::new() }; let theme_dir = source_dir.join("themes"); if theme_dir.exists() { let res = theme_set.add_from_folder(&theme_dir); if let Err(err) = res { println!( "Failed to load one or more themes from '{}' (reason: '{}')", theme_dir.to_string_lossy(), err, ); } } else { println!( "No themes were found in '{}', using the default set", theme_dir.to_string_lossy() ); } theme_set.try_into() } fn build_syntax_set_builder( source_dir: &Path, include_integrated_assets: bool, ) -> Result { let mut syntax_set_builder = if !include_integrated_assets { let mut builder = syntect::parsing::SyntaxSetBuilder::new(); builder.add_plain_text_syntax(); builder } else { from_binary::(get_serialized_integrated_syntaxset(), COMPRESS_SYNTAXES) .into_builder() }; let syntax_dir = source_dir.join("syntaxes"); if syntax_dir.exists() { syntax_set_builder.add_from_folder(syntax_dir, true)?; } else { println!( "No syntaxes were found in '{}', using the default set.", syntax_dir.to_string_lossy() ); } Ok(syntax_set_builder) } fn print_unlinked_contexts(syntax_set: &SyntaxSet) { let missing_contexts = syntax_set.find_unlinked_contexts(); if !missing_contexts.is_empty() { println!("Some referenced contexts could not be found!"); for context in missing_contexts { println!("- {}", context); } } } fn write_assets( theme_set: &LazyThemeSet, syntax_set: &SyntaxSet, acknowledgements: &Option, target_dir: &Path, current_version: &str, ) -> Result<()> { let _ = std::fs::create_dir_all(target_dir); asset_to_cache( theme_set, &target_dir.join("themes.bin"), "theme set", COMPRESS_THEMES, )?; asset_to_cache( syntax_set, &target_dir.join("syntaxes.bin"), "syntax set", COMPRESS_SYNTAXES, )?; if let Some(acknowledgements) = acknowledgements { asset_to_cache( acknowledgements, &target_dir.join("acknowledgements.bin"), "acknowledgements", COMPRESS_ACKNOWLEDGEMENTS, )?; } print!( "Writing metadata to folder {} ... ", target_dir.to_string_lossy() ); crate::assets_metadata::AssetsMetadata::new(current_version).save_to_folder(target_dir)?; println!("okay"); Ok(()) } pub(crate) fn asset_to_contents( asset: &T, description: &str, compressed: bool, ) -> Result> { let mut contents = vec![]; if compressed { bincode::serialize_into( flate2::write::ZlibEncoder::new(&mut contents, flate2::Compression::best()), asset, ) } else { bincode::serialize_into(&mut contents, asset) } .map_err(|_| format!("Could not serialize {}", description))?; Ok(contents) } fn asset_to_cache( asset: &T, path: &Path, description: &str, compressed: bool, ) -> Result<()> { print!("Writing {} to {} ... ", description, path.to_string_lossy()); let contents = asset_to_contents(asset, description, compressed)?; std::fs::write(path, &contents[..]).map_err(|_| { format!( "Could not save {} to {}", description, path.to_string_lossy() ) })?; println!("okay"); Ok(()) } bat-0.19.0/src/assets/lazy_theme_set.rs000064400000000000000000000061470072674642500161740ustar 00000000000000use super::*; use std::collections::BTreeMap; use std::convert::TryFrom; use serde::Deserialize; use serde::Serialize; use once_cell::unsync::OnceCell; use syntect::highlighting::{Theme, ThemeSet}; /// Same structure as a [`syntect::highlighting::ThemeSet`] but with themes /// stored in raw serialized form, and deserialized on demand. #[derive(Debug, Default, Serialize, Deserialize)] pub struct LazyThemeSet { /// This is a [`BTreeMap`] because that's what [`syntect::highlighting::ThemeSet`] uses themes: BTreeMap, } /// Stores raw serialized data for a theme with methods to lazily deserialize /// (load) the theme. #[derive(Debug, Serialize, Deserialize)] struct LazyTheme { serialized: Vec, #[serde(skip, default = "OnceCell::new")] deserialized: OnceCell, } impl LazyThemeSet { /// Lazily load the given theme pub fn get(&self, name: &str) -> Option<&Theme> { self.themes.get(name).and_then(|lazy_theme| { lazy_theme .deserialized .get_or_try_init(|| lazy_theme.deserialize()) .ok() }) } /// Returns the name of all themes. pub fn themes(&self) -> impl Iterator { self.themes.keys().map(|name| name.as_ref()) } } impl LazyTheme { fn deserialize(&self) -> Result { asset_from_contents( &self.serialized[..], "lazy-loaded theme", COMPRESS_LAZY_THEMES, ) } } impl TryFrom for ThemeSet { type Error = Error; /// Since the user might want to add custom themes to bat, we need a way to /// convert from a `LazyThemeSet` to a regular [`ThemeSet`] so that more /// themes can be added. This function does that pretty straight-forward /// conversion. fn try_from(lazy_theme_set: LazyThemeSet) -> Result { let mut theme_set = ThemeSet::default(); for (name, lazy_theme) in lazy_theme_set.themes { theme_set.themes.insert(name, lazy_theme.deserialize()?); } Ok(theme_set) } } #[cfg(feature = "build-assets")] impl TryFrom for LazyThemeSet { type Error = Error; /// To collect themes, a [`ThemeSet`] is needed. Once all desired themes /// have been added, we need a way to convert that into [`LazyThemeSet`] so /// that themes can be lazy-loaded later. This function does that /// conversion. fn try_from(theme_set: ThemeSet) -> Result { let mut lazy_theme_set = LazyThemeSet::default(); for (name, theme) in theme_set.themes { // All we have to do is to serialize the theme let lazy_theme = LazyTheme { serialized: crate::assets::build_assets::asset_to_contents( &theme, &format!("theme {}", name), COMPRESS_LAZY_THEMES, )?, deserialized: OnceCell::new(), }; // Ok done, now we can add it lazy_theme_set.themes.insert(name, lazy_theme); } Ok(lazy_theme_set) } } bat-0.19.0/src/assets/serialized_syntax_set.rs000064400000000000000000000014230072674642500175640ustar 00000000000000use std::path::PathBuf; use syntect::parsing::SyntaxSet; use super::*; /// A SyntaxSet in serialized form, i.e. bincoded and flate2 compressed. /// We keep it in this format since we want to load it lazily. #[derive(Debug)] pub enum SerializedSyntaxSet { /// The data comes from a user-generated cache file. FromFile(PathBuf), /// The data to use is embedded into the bat binary. FromBinary(&'static [u8]), } impl SerializedSyntaxSet { pub fn deserialize(&self) -> Result { match self { SerializedSyntaxSet::FromBinary(data) => Ok(from_binary(data, COMPRESS_SYNTAXES)), SerializedSyntaxSet::FromFile(ref path) => { asset_from_cache(path, "syntax set", COMPRESS_SYNTAXES) } } } } bat-0.19.0/src/assets.rs000064400000000000000000000523740072674642500131630ustar 00000000000000use std::ffi::OsStr; use std::fs; use std::path::Path; use once_cell::unsync::OnceCell; use syntect::highlighting::Theme; use syntect::parsing::{SyntaxReference, SyntaxSet}; use path_abs::PathAbs; use crate::error::*; use crate::input::{InputReader, OpenedInput}; use crate::syntax_mapping::ignored_suffixes::IgnoredSuffixes; use crate::syntax_mapping::MappingTarget; use crate::{bat_warning, SyntaxMapping}; use lazy_theme_set::LazyThemeSet; use serialized_syntax_set::*; #[cfg(feature = "build-assets")] pub use crate::assets::build_assets::*; pub(crate) mod assets_metadata; #[cfg(feature = "build-assets")] mod build_assets; mod lazy_theme_set; mod serialized_syntax_set; #[derive(Debug)] pub struct HighlightingAssets { syntax_set_cell: OnceCell, serialized_syntax_set: SerializedSyntaxSet, theme_set: LazyThemeSet, fallback_theme: Option<&'static str>, } #[derive(Debug)] pub struct SyntaxReferenceInSet<'a> { pub syntax: &'a SyntaxReference, pub syntax_set: &'a SyntaxSet, } /// Compress for size of ~700 kB instead of ~4600 kB at the cost of ~30% longer deserialization time pub(crate) const COMPRESS_SYNTAXES: bool = true; /// We don't want to compress our [LazyThemeSet] since the lazy-loaded themes /// within it are already compressed, and compressing another time just makes /// performance suffer pub(crate) const COMPRESS_THEMES: bool = false; /// Compress for size of ~40 kB instead of ~200 kB without much difference in /// performance due to lazy-loading pub(crate) const COMPRESS_LAZY_THEMES: bool = true; /// Compress for size of ~10 kB instead of ~120 kB pub(crate) const COMPRESS_ACKNOWLEDGEMENTS: bool = true; impl HighlightingAssets { fn new(serialized_syntax_set: SerializedSyntaxSet, theme_set: LazyThemeSet) -> Self { HighlightingAssets { syntax_set_cell: OnceCell::new(), serialized_syntax_set, theme_set, fallback_theme: None, } } pub fn default_theme() -> &'static str { "Monokai Extended" } pub fn from_cache(cache_path: &Path) -> Result { Ok(HighlightingAssets::new( SerializedSyntaxSet::FromFile(cache_path.join("syntaxes.bin")), asset_from_cache(&cache_path.join("themes.bin"), "theme set", COMPRESS_THEMES)?, )) } pub fn from_binary() -> Self { HighlightingAssets::new( SerializedSyntaxSet::FromBinary(get_serialized_integrated_syntaxset()), get_integrated_themeset(), ) } pub fn set_fallback_theme(&mut self, theme: &'static str) { self.fallback_theme = Some(theme); } fn get_syntax_set(&self) -> Result<&SyntaxSet> { self.syntax_set_cell .get_or_try_init(|| self.serialized_syntax_set.deserialize()) } /// Use [Self::get_syntaxes] instead #[deprecated] pub fn syntaxes(&self) -> &[SyntaxReference] { self.get_syntax_set() .expect(".syntaxes() is deprecated, use .get_syntaxes() instead") .syntaxes() } pub fn get_syntaxes(&self) -> Result<&[SyntaxReference]> { Ok(self.get_syntax_set()?.syntaxes()) } fn get_theme_set(&self) -> &LazyThemeSet { &self.theme_set } pub fn themes(&self) -> impl Iterator { self.get_theme_set().themes() } /// Use [Self::get_syntax_for_path] instead #[deprecated] pub fn syntax_for_file_name( &self, file_name: impl AsRef, mapping: &SyntaxMapping, ) -> Option<&SyntaxReference> { self.get_syntax_for_path(file_name, mapping) .ok() .map(|syntax_in_set| syntax_in_set.syntax) } /// Detect the syntax based on, in order: /// 1. Syntax mappings with [MappingTarget::MapTo] and [MappingTarget::MapToUnknown] /// (e.g. `/etc/profile` -> `Bourne Again Shell (bash)`) /// 2. The file name (e.g. `Dockerfile`) /// 3. Syntax mappings with [MappingTarget::MapExtensionToUnknown] /// (e.g. `*.conf`) /// 4. The file name extension (e.g. `.rs`) /// /// When detecting syntax based on syntax mappings, the full path is taken /// into account. When detecting syntax based on file name, no regard is /// taken to the path of the file. Only the file name itself matters. When /// detecting syntax based on file name extension, only the file name /// extension itself matters. /// /// Returns [Error::UndetectedSyntax] if it was not possible detect syntax /// based on path/file name/extension (or if the path was mapped to /// [MappingTarget::MapToUnknown] or [MappingTarget::MapExtensionToUnknown]). /// In this case it is appropriate to fall back to other methods to detect /// syntax. Such as using the contents of the first line of the file. /// /// Returns [Error::UnknownSyntax] if a syntax mapping exist, but the mapped /// syntax does not exist. pub fn get_syntax_for_path( &self, path: impl AsRef, mapping: &SyntaxMapping, ) -> Result { let path = path.as_ref(); let syntax_match = mapping.get_syntax_for(path); if let Some(MappingTarget::MapToUnknown) = syntax_match { return Err(Error::UndetectedSyntax(path.to_string_lossy().into())); } if let Some(MappingTarget::MapTo(syntax_name)) = syntax_match { return self .find_syntax_by_name(syntax_name)? .ok_or_else(|| Error::UnknownSyntax(syntax_name.to_owned())); } let file_name = path.file_name().unwrap_or_default(); match ( self.get_syntax_for_file_name(file_name, &mapping.ignored_suffixes)?, syntax_match, ) { (Some(syntax), _) => Ok(syntax), (_, Some(MappingTarget::MapExtensionToUnknown)) => { Err(Error::UndetectedSyntax(path.to_string_lossy().into())) } _ => self .get_syntax_for_file_extension(file_name, &mapping.ignored_suffixes)? .ok_or_else(|| Error::UndetectedSyntax(path.to_string_lossy().into())), } } pub(crate) fn get_theme(&self, theme: &str) -> &Theme { match self.get_theme_set().get(theme) { Some(theme) => theme, None => { if theme == "ansi-light" || theme == "ansi-dark" { bat_warning!("Theme '{}' is deprecated, using 'ansi' instead.", theme); return self.get_theme("ansi"); } if !theme.is_empty() { bat_warning!("Unknown theme '{}', using default.", theme) } self.get_theme_set() .get(self.fallback_theme.unwrap_or_else(Self::default_theme)) .expect("something is very wrong if the default theme is missing") } } } pub(crate) fn get_syntax( &self, language: Option<&str>, input: &mut OpenedInput, mapping: &SyntaxMapping, ) -> Result { if let Some(language) = language { let syntax_set = self.get_syntax_set()?; return syntax_set .find_syntax_by_token(language) .map(|syntax| SyntaxReferenceInSet { syntax, syntax_set }) .ok_or_else(|| Error::UnknownSyntax(language.to_owned())); } let path = input.path(); let path_syntax = if let Some(path) = path { self.get_syntax_for_path( PathAbs::new(path).map_or_else(|_| path.to_owned(), |p| p.as_path().to_path_buf()), mapping, ) } else { Err(Error::UndetectedSyntax("[unknown]".into())) }; match path_syntax { // If a path wasn't provided, or if path based syntax detection // above failed, we fall back to first-line syntax detection. Err(Error::UndetectedSyntax(path)) => self .get_first_line_syntax(&mut input.reader)? .ok_or(Error::UndetectedSyntax(path)), _ => path_syntax, } } pub(crate) fn find_syntax_by_name( &self, syntax_name: &str, ) -> Result> { let syntax_set = self.get_syntax_set()?; Ok(syntax_set .find_syntax_by_name(syntax_name) .map(|syntax| SyntaxReferenceInSet { syntax, syntax_set })) } fn find_syntax_by_extension(&self, e: Option<&OsStr>) -> Result> { let syntax_set = self.get_syntax_set()?; let extension = e.and_then(|x| x.to_str()).unwrap_or_default(); Ok(syntax_set .find_syntax_by_extension(extension) .map(|syntax| SyntaxReferenceInSet { syntax, syntax_set })) } fn get_syntax_for_file_name( &self, file_name: &OsStr, ignored_suffixes: &IgnoredSuffixes, ) -> Result> { let mut syntax = self.find_syntax_by_extension(Some(file_name))?; if syntax.is_none() { syntax = ignored_suffixes.try_with_stripped_suffix(file_name, |stripped_file_name| { // Note: recursion self.get_syntax_for_file_name(stripped_file_name, ignored_suffixes) })?; } Ok(syntax) } fn get_syntax_for_file_extension( &self, file_name: &OsStr, ignored_suffixes: &IgnoredSuffixes, ) -> Result> { let mut syntax = self.find_syntax_by_extension(Path::new(file_name).extension())?; if syntax.is_none() { syntax = ignored_suffixes.try_with_stripped_suffix(file_name, |stripped_file_name| { // Note: recursion self.get_syntax_for_file_extension(stripped_file_name, ignored_suffixes) })?; } Ok(syntax) } fn get_first_line_syntax( &self, reader: &mut InputReader, ) -> Result> { let syntax_set = self.get_syntax_set()?; Ok(String::from_utf8(reader.first_line.clone()) .ok() .and_then(|l| syntax_set.find_syntax_by_first_line(&l)) .map(|syntax| SyntaxReferenceInSet { syntax, syntax_set })) } } pub(crate) fn get_serialized_integrated_syntaxset() -> &'static [u8] { include_bytes!("../assets/syntaxes.bin") } pub(crate) fn get_integrated_themeset() -> LazyThemeSet { from_binary(include_bytes!("../assets/themes.bin"), COMPRESS_THEMES) } pub fn get_acknowledgements() -> String { from_binary( include_bytes!("../assets/acknowledgements.bin"), COMPRESS_ACKNOWLEDGEMENTS, ) } pub(crate) fn from_binary(v: &[u8], compressed: bool) -> T { asset_from_contents(v, "n/a", compressed) .expect("data integrated in binary is never faulty, but make sure `compressed` is in sync!") } fn asset_from_contents( contents: &[u8], description: &str, compressed: bool, ) -> Result { if compressed { bincode::deserialize_from(flate2::read::ZlibDecoder::new(contents)) } else { bincode::deserialize_from(contents) } .map_err(|_| format!("Could not parse {}", description).into()) } fn asset_from_cache( path: &Path, description: &str, compressed: bool, ) -> Result { let contents = fs::read(path).map_err(|_| { format!( "Could not load cached {} '{}'", description, path.to_string_lossy() ) })?; asset_from_contents(&contents[..], description, compressed) .map_err(|_| format!("Could not parse cached {}", description).into()) } #[cfg(test)] mod tests { use super::*; use std::ffi::OsStr; use std::fs::File; use std::io::{BufReader, Write}; use tempfile::TempDir; use crate::input::Input; struct SyntaxDetectionTest<'a> { assets: HighlightingAssets, pub syntax_mapping: SyntaxMapping<'a>, pub temp_dir: TempDir, } impl<'a> SyntaxDetectionTest<'a> { fn new() -> Self { SyntaxDetectionTest { assets: HighlightingAssets::from_binary(), syntax_mapping: SyntaxMapping::builtin(), temp_dir: TempDir::new().expect("creation of temporary directory"), } } fn get_syntax_name( &self, language: Option<&str>, input: &mut OpenedInput, mapping: &SyntaxMapping, ) -> String { self.assets .get_syntax(language, input, mapping) .map(|syntax_in_set| syntax_in_set.syntax.name.clone()) .unwrap_or_else(|_| "!no syntax!".to_owned()) } fn syntax_for_real_file_with_content_os( &self, file_name: &OsStr, first_line: &str, ) -> String { let file_path = self.temp_dir.path().join(file_name); { let mut temp_file = File::create(&file_path).unwrap(); writeln!(temp_file, "{}", first_line).unwrap(); } let input = Input::ordinary_file(&file_path); let dummy_stdin: &[u8] = &[]; let mut opened_input = input.open(dummy_stdin, None).unwrap(); self.get_syntax_name(None, &mut opened_input, &self.syntax_mapping) } fn syntax_for_file_with_content_os(&self, file_name: &OsStr, first_line: &str) -> String { let file_path = self.temp_dir.path().join(file_name); let input = Input::from_reader(Box::new(BufReader::new(first_line.as_bytes()))) .with_name(Some(&file_path)); let dummy_stdin: &[u8] = &[]; let mut opened_input = input.open(dummy_stdin, None).unwrap(); self.get_syntax_name(None, &mut opened_input, &self.syntax_mapping) } #[cfg(unix)] fn syntax_for_file_os(&self, file_name: &OsStr) -> String { self.syntax_for_file_with_content_os(file_name, "") } fn syntax_for_file_with_content(&self, file_name: &str, first_line: &str) -> String { self.syntax_for_file_with_content_os(OsStr::new(file_name), first_line) } fn syntax_for_file(&self, file_name: &str) -> String { self.syntax_for_file_with_content(file_name, "") } fn syntax_for_stdin_with_content(&self, file_name: &str, content: &[u8]) -> String { let input = Input::stdin().with_name(Some(file_name)); let mut opened_input = input.open(content, None).unwrap(); self.get_syntax_name(None, &mut opened_input, &self.syntax_mapping) } fn syntax_is_same_for_inputkinds(&self, file_name: &str, content: &str) -> bool { let as_file = self.syntax_for_real_file_with_content_os(file_name.as_ref(), content); let as_reader = self.syntax_for_file_with_content_os(file_name.as_ref(), content); let consistent = as_file == as_reader; // TODO: Compare StdIn somehow? if !consistent { eprintln!( "Inconsistent syntax detection:\nFor File: {}\nFor Reader: {}", as_file, as_reader ) } consistent } } #[test] fn syntax_detection_basic() { let test = SyntaxDetectionTest::new(); assert_eq!(test.syntax_for_file("test.rs"), "Rust"); assert_eq!(test.syntax_for_file("test.cpp"), "C++"); assert_eq!(test.syntax_for_file("test.build"), "NAnt Build File"); assert_eq!( test.syntax_for_file("PKGBUILD"), "Bourne Again Shell (bash)" ); assert_eq!(test.syntax_for_file(".bashrc"), "Bourne Again Shell (bash)"); assert_eq!(test.syntax_for_file("Makefile"), "Makefile"); } #[cfg(unix)] #[test] fn syntax_detection_invalid_utf8() { use std::os::unix::ffi::OsStrExt; let test = SyntaxDetectionTest::new(); assert_eq!( test.syntax_for_file_os(OsStr::from_bytes(b"invalid_\xFEutf8_filename.rs")), "Rust" ); } #[test] fn syntax_detection_same_for_inputkinds() { let mut test = SyntaxDetectionTest::new(); test.syntax_mapping .insert("*.myext", MappingTarget::MapTo("C")) .ok(); test.syntax_mapping .insert("MY_FILE", MappingTarget::MapTo("Markdown")) .ok(); assert!(test.syntax_is_same_for_inputkinds("Test.md", "")); assert!(test.syntax_is_same_for_inputkinds("Test.txt", "#!/bin/bash")); assert!(test.syntax_is_same_for_inputkinds(".bashrc", "")); assert!(test.syntax_is_same_for_inputkinds("test.h", "")); assert!(test.syntax_is_same_for_inputkinds("test.js", "#!/bin/bash")); assert!(test.syntax_is_same_for_inputkinds("test.myext", "")); assert!(test.syntax_is_same_for_inputkinds("MY_FILE", "")); assert!(test.syntax_is_same_for_inputkinds("MY_FILE", " bool { env::var("COLORTERM") .map(|colorterm| colorterm == "truecolor" || colorterm == "24bit") .unwrap_or(false) } pub struct App { pub matches: ArgMatches<'static>, interactive_output: bool, } impl App { pub fn new() -> Result { #[cfg(windows)] let _ = ansi_term::enable_ansi_support(); let interactive_output = atty::is(Stream::Stdout); Ok(App { matches: Self::matches(interactive_output)?, interactive_output, }) } fn matches(interactive_output: bool) -> Result> { let args = if wild::args_os().nth(1) == Some("cache".into()) || wild::args_os().any(|arg| arg == "--no-config") { // Skip the arguments in bats config file wild::args_os().collect::>() } else { let mut cli_args = wild::args_os(); // Read arguments from bats config file let mut args = get_args_from_env_var() .unwrap_or_else(get_args_from_config_file) .map_err(|_| "Could not parse configuration file")?; // Put the zero-th CLI argument (program name) first args.insert(0, cli_args.next().unwrap()); // .. and the rest at the end cli_args.for_each(|a| args.push(a)); args }; Ok(clap_app::build_app(interactive_output).get_matches_from(args)) } pub fn config(&self, inputs: &[Input]) -> Result { let style_components = self.style_components()?; let paging_mode = match self.matches.value_of("paging") { Some("always") => PagingMode::Always, Some("never") => PagingMode::Never, Some("auto") | None => { // If we have -pp as an option when in auto mode, the pager should be disabled. let extra_plain = self.matches.occurrences_of("plain") > 1; if extra_plain || self.matches.is_present("no-paging") { PagingMode::Never } else if inputs.iter().any(Input::is_stdin) { // If we are reading from stdin, only enable paging if we write to an // interactive terminal and if we do not *read* from an interactive // terminal. if self.interactive_output && !atty::is(Stream::Stdin) { PagingMode::QuitIfOneScreen } else { PagingMode::Never } } else if self.interactive_output { PagingMode::QuitIfOneScreen } else { PagingMode::Never } } _ => unreachable!("other values for --paging are not allowed"), }; let mut syntax_mapping = SyntaxMapping::builtin(); if let Some(values) = self.matches.values_of("ignored-suffix") { for suffix in values { syntax_mapping.insert_ignored_suffix(suffix); } } if let Some(values) = self.matches.values_of("map-syntax") { for from_to in values { let parts: Vec<_> = from_to.split(':').collect(); if parts.len() != 2 { return Err("Invalid syntax mapping. The format of the -m/--map-syntax option is ':'. For example: '*.cpp:C++'.".into()); } syntax_mapping.insert(parts[0], MappingTarget::MapTo(parts[1]))?; } } let maybe_term_width = self.matches.value_of("terminal-width").and_then(|w| { if w.starts_with('+') || w.starts_with('-') { // Treat argument as a delta to the current terminal width w.parse().ok().map(|delta: i16| { let old_width: u16 = Term::stdout().size().1; let new_width: i32 = i32::from(old_width) + i32::from(delta); if new_width <= 0 { old_width as usize } else { new_width as usize } }) } else { w.parse().ok() } }); Ok(Config { true_color: is_truecolor_terminal(), language: self.matches.value_of("language").or_else(|| { if self.matches.is_present("show-all") { Some("show-nonprintable") } else { None } }), show_nonprintable: self.matches.is_present("show-all"), wrapping_mode: if self.interactive_output || maybe_term_width.is_some() { match self.matches.value_of("wrap") { Some("character") => WrappingMode::Character, Some("never") => WrappingMode::NoWrapping(true), Some("auto") | None => { if style_components.plain() { WrappingMode::NoWrapping(false) } else { WrappingMode::Character } } _ => unreachable!("other values for --wrap are not allowed"), } } else { // We don't have the tty width when piping to another program. // There's no point in wrapping when this is the case. WrappingMode::NoWrapping(false) }, colored_output: self.matches.is_present("force-colorization") || match self.matches.value_of("color") { Some("always") => true, Some("never") => false, Some("auto") => env::var_os("NO_COLOR").is_none() && self.interactive_output, _ => unreachable!("other values for --color are not allowed"), }, paging_mode, term_width: maybe_term_width.unwrap_or(Term::stdout().size().1 as usize), loop_through: !(self.interactive_output || self.matches.value_of("color") == Some("always") || self.matches.value_of("decorations") == Some("always") || self.matches.is_present("force-colorization")), tab_width: self .matches .value_of("tabs") .map(String::from) .or_else(|| env::var("BAT_TABS").ok()) .and_then(|t| t.parse().ok()) .unwrap_or( if style_components.plain() && paging_mode == PagingMode::Never { 0 } else { 4 }, ), theme: self .matches .value_of("theme") .map(String::from) .or_else(|| env::var("BAT_THEME").ok()) .map(|s| { if s == "default" { String::from(HighlightingAssets::default_theme()) } else { s } }) .unwrap_or_else(|| String::from(HighlightingAssets::default_theme())), visible_lines: match self.matches.is_present("diff") { #[cfg(feature = "git")] true => VisibleLines::DiffContext( self.matches .value_of("diff-context") .and_then(|t| t.parse().ok()) .unwrap_or(2), ), _ => VisibleLines::Ranges( self.matches .values_of("line-range") .map(|vs| vs.map(LineRange::from).collect()) .transpose()? .map(LineRanges::from) .unwrap_or_default(), ), }, style_components, syntax_mapping, pager: self.matches.value_of("pager"), use_italic_text: self.matches.value_of("italic-text") == Some("always"), highlighted_lines: self .matches .values_of("highlight-line") .map(|ws| ws.map(LineRange::from).collect()) .transpose()? .map(LineRanges::from) .map(HighlightedLineRanges) .unwrap_or_default(), use_custom_assets: !self.matches.is_present("no-custom-assets"), }) } pub fn inputs(&self) -> Result> { // verify equal length of file-names and input FILEs match self.matches.values_of("file-name") { Some(ref filenames) if self.matches.values_of_os("FILE").is_some() && filenames.len() != self.matches.values_of_os("FILE").unwrap().len() => { return Err("Must be one file name per input type.".into()); } _ => {} } let filenames: Option> = self .matches .values_of_os("file-name") .map(|values| values.map(Path::new).collect()); let mut filenames_or_none: Box>> = match filenames { Some(filenames) => Box::new(filenames.into_iter().map(Some)), None => Box::new(std::iter::repeat(None)), }; let files: Option> = self .matches .values_of_os("FILE") .map(|vs| vs.map(Path::new).collect()); if files.is_none() { return Ok(vec![new_stdin_input( filenames_or_none.next().unwrap_or(None), )]); } let files_or_none: Box> = match files { Some(ref files) => Box::new(files.iter().map(|name| Some(*name))), None => Box::new(std::iter::repeat(None)), }; let mut file_input = Vec::new(); for (filepath, provided_name) in files_or_none.zip(filenames_or_none) { if let Some(filepath) = filepath { if filepath.to_str().unwrap_or_default() == "-" { file_input.push(new_stdin_input(provided_name)); } else { file_input.push(new_file_input(filepath, provided_name)); } } } Ok(file_input) } fn style_components(&self) -> Result { let matches = &self.matches; let mut styled_components = StyleComponents(if matches.value_of("decorations") == Some("never") { HashSet::new() } else if matches.is_present("number") { [StyleComponent::LineNumbers].iter().cloned().collect() } else if matches.is_present("plain") { [StyleComponent::Plain].iter().cloned().collect() } else { let env_style_components: Option> = env::var("BAT_STYLE") .ok() .map(|style_str| { style_str .split(',') .map(StyleComponent::from_str) .collect::>>() }) .transpose()?; matches .value_of("style") .map(|styles| { styles .split(',') .map(|style| style.parse::()) .filter_map(|style| style.ok()) .collect::>() }) .or(env_style_components) .unwrap_or_else(|| vec![StyleComponent::Full]) .into_iter() .map(|style| style.components(self.interactive_output)) .fold(HashSet::new(), |mut acc, components| { acc.extend(components.iter().cloned()); acc }) }); // If `grid` is set, remove `rule` as it is a subset of `grid`, and print a warning. if styled_components.grid() && styled_components.0.remove(&StyleComponent::Rule) { bat_warning!("Style 'rule' is a subset of style 'grid', 'rule' will not be visible."); } Ok(styled_components) } } bat-0.19.0/src/bin/bat/assets.rs000064400000000000000000000041370072674642500144730ustar 00000000000000use std::borrow::Cow; use std::fs; use std::io; use clap::crate_version; use crate::directories::PROJECT_DIRS; use bat::assets::HighlightingAssets; use bat::assets_metadata::AssetsMetadata; use bat::error::*; pub fn config_dir() -> Cow<'static, str> { PROJECT_DIRS.config_dir().to_string_lossy() } pub fn cache_dir() -> Cow<'static, str> { PROJECT_DIRS.cache_dir().to_string_lossy() } pub fn clear_assets() { clear_asset("themes.bin", "theme set cache"); clear_asset("syntaxes.bin", "syntax set cache"); clear_asset("metadata.yaml", "metadata file"); } pub fn assets_from_cache_or_binary(use_custom_assets: bool) -> Result { let cache_dir = PROJECT_DIRS.cache_dir(); if let Some(metadata) = AssetsMetadata::load_from_folder(cache_dir)? { if !metadata.is_compatible_with(crate_version!()) { return Err(format!( "The binary caches for the user-customized syntaxes and themes \ in '{}' are not compatible with this version of bat ({}). To solve this, \ either rebuild the cache (bat cache --build) or remove \ the custom syntaxes/themes (bat cache --clear).\n\ For more information, see:\n\n \ https://github.com/sharkdp/bat#adding-new-syntaxes--language-definitions", cache_dir.to_string_lossy(), crate_version!() ) .into()); } } let custom_assets = if use_custom_assets { HighlightingAssets::from_cache(cache_dir).ok() } else { None }; Ok(custom_assets.unwrap_or_else(HighlightingAssets::from_binary)) } fn clear_asset(filename: &str, description: &str) { print!("Clearing {} ... ", description); let path = PROJECT_DIRS.cache_dir().join(filename); match fs::remove_file(&path) { Err(err) if err.kind() == io::ErrorKind::NotFound => { println!("skipped (not present)"); } Err(err) => { println!("could not remove the cache file {:?}: {}", &path, err); } Ok(_) => println!("okay"), } } bat-0.19.0/src/bin/bat/clap_app.rs000064400000000000000000000624130072674642500147510ustar 00000000000000use clap::{crate_name, crate_version, App as ClapApp, AppSettings, Arg, ArgGroup, SubCommand}; use once_cell::sync::Lazy; use std::env; use std::path::Path; static VERSION: Lazy = Lazy::new(|| { #[cfg(feature = "bugreport")] let git_version = bugreport::git_version!(fallback = ""); #[cfg(not(feature = "bugreport"))] let git_version = ""; if git_version.is_empty() { crate_version!().to_string() } else { format!("{} ({})", crate_version!(), git_version) } }); pub fn build_app(interactive_output: bool) -> ClapApp<'static, 'static> { let clap_color_setting = if interactive_output && env::var_os("NO_COLOR").is_none() { AppSettings::ColoredHelp } else { AppSettings::ColorNever }; let mut app = ClapApp::new(crate_name!()) .version(VERSION.as_str()) .global_setting(clap_color_setting) .global_setting(AppSettings::DeriveDisplayOrder) .global_setting(AppSettings::UnifiedHelpMessage) .global_setting(AppSettings::HidePossibleValuesInHelp) .setting(AppSettings::ArgsNegateSubcommands) .setting(AppSettings::AllowExternalSubcommands) .setting(AppSettings::DisableHelpSubcommand) .setting(AppSettings::VersionlessSubcommands) .max_term_width(100) .about( "A cat(1) clone with wings.\n\n\ Use '--help' instead of '-h' to see a more detailed version of the help text.", ) .after_help( "Note: `bat -h` prints a short and concise overview while `bat --help` gives all \ details.", ) .long_about("A cat(1) clone with syntax highlighting and Git integration.") .arg( Arg::with_name("FILE") .help("File(s) to print / concatenate. Use '-' for standard input.") .long_help( "File(s) to print / concatenate. Use a dash ('-') or no argument at all \ to read from standard input.", ) .multiple(true) .empty_values(false), ) .arg( Arg::with_name("show-all") .long("show-all") .alias("show-nonprintable") .short("A") .conflicts_with("language") .help("Show non-printable characters (space, tab, newline, ..).") .long_help( "Show non-printable characters like space, tab or newline. \ This option can also be used to print binary files. \ Use '--tabs' to control the width of the tab-placeholders.", ), ) .arg( Arg::with_name("plain") .overrides_with("plain") .overrides_with("number") .short("p") .long("plain") .multiple(true) .help("Show plain style (alias for '--style=plain').") .long_help( "Only show plain style, no decorations. This is an alias for \ '--style=plain'. When '-p' is used twice ('-pp'), it also disables \ automatic paging (alias for '--style=plain --pager=never').", ), ) .arg( Arg::with_name("language") .short("l") .long("language") .overrides_with("language") .help("Set the language for syntax highlighting.") .long_help( "Explicitly set the language for syntax highlighting. The language can be \ specified as a name (like 'C++' or 'LaTeX') or possible file extension \ (like 'cpp', 'hpp' or 'md'). Use '--list-languages' to show all supported \ language names and file extensions.", ) .takes_value(true), ) .arg( Arg::with_name("highlight-line") .long("highlight-line") .short("H") .takes_value(true) .number_of_values(1) .multiple(true) .value_name("N:M") .help("Highlight lines N through M.") .long_help( "Highlight the specified line ranges with a different background color \ For example:\n \ '--highlight-line 40' highlights line 40\n \ '--highlight-line 30:40' highlights lines 30 to 40\n \ '--highlight-line :40' highlights lines 1 to 40\n \ '--highlight-line 40:' highlights lines 40 to the end of the file\n \ '--highlight-line 30:+10' highlights lines 30 to 40", ), ) .arg( Arg::with_name("file-name") .long("file-name") .takes_value(true) .number_of_values(1) .multiple(true) .value_name("name") .help("Specify the name to display for a file.") .long_help( "Specify the name to display for a file. Useful when piping \ data to bat from STDIN when bat does not otherwise know \ the filename. Note that the provided file name is also \ used for syntax detection.", ), ); #[cfg(feature = "git")] { app = app .arg( Arg::with_name("diff") .long("diff") .short("d") .help("Only show lines that have been added/removed/modified.") .long_help( "Only show lines that have been added/removed/modified with respect \ to the Git index. Use --diff-context=N to control how much context you want to see.", ), ) .arg( Arg::with_name("diff-context") .long("diff-context") .overrides_with("diff-context") .takes_value(true) .value_name("N") .validator( |n| { n.parse::() .map_err(|_| "must be a number") .map(|_| ()) // Convert to Result<(), &str> .map_err(|e| e.to_string()) }, // Convert to Result<(), String> ) .hidden_short_help(true) .long_help( "Include N lines of context around added/removed/modified lines when using '--diff'.", ), ) } app = app.arg( Arg::with_name("tabs") .long("tabs") .overrides_with("tabs") .takes_value(true) .value_name("T") .validator( |t| { t.parse::() .map_err(|_t| "must be a number") .map(|_t| ()) // Convert to Result<(), &str> .map_err(|e| e.to_string()) }, // Convert to Result<(), String> ) .help("Set the tab width to T spaces.") .long_help( "Set the tab width to T spaces. Use a width of 0 to pass tabs through \ directly", ), ) .arg( Arg::with_name("wrap") .long("wrap") .overrides_with("wrap") .takes_value(true) .value_name("mode") .possible_values(&["auto", "never", "character"]) .default_value("auto") .hide_default_value(true) .help("Specify the text-wrapping mode (*auto*, never, character).") .long_help("Specify the text-wrapping mode (*auto*, never, character). \ The '--terminal-width' option can be used in addition to \ control the output width."), ) .arg( Arg::with_name("terminal-width") .long("terminal-width") .takes_value(true) .value_name("width") .hidden_short_help(true) .allow_hyphen_values(true) .validator( |t| { let is_offset = t.starts_with('+') || t.starts_with('-'); t.parse::() .map_err(|_e| "must be an offset or number") .and_then(|v| if v == 0 && !is_offset { Err("terminal width cannot be zero") } else { Ok(()) }) .map_err(|e| e.to_string()) }) .help( "Explicitly set the width of the terminal instead of determining it \ automatically. If prefixed with '+' or '-', the value will be treated \ as an offset to the actual terminal width. See also: '--wrap'.", ), ) .arg( Arg::with_name("number") .long("number") .overrides_with("number") .short("n") .help("Show line numbers (alias for '--style=numbers').") .long_help( "Only show line numbers, no other decorations. This is an alias for \ '--style=numbers'", ), ) .arg( Arg::with_name("color") .long("color") .overrides_with("color") .takes_value(true) .value_name("when") .possible_values(&["auto", "never", "always"]) .hide_default_value(true) .default_value("auto") .help("When to use colors (*auto*, never, always).") .long_help( "Specify when to use colored output. The automatic mode \ only enables colors if an interactive terminal is detected - \ colors are automatically disabled if the output goes to a pipe.\n\ Possible values: *auto*, never, always.", ), ) .arg( Arg::with_name("italic-text") .long("italic-text") .takes_value(true) .value_name("when") .possible_values(&["always", "never"]) .default_value("never") .hide_default_value(true) .help("Use italics in output (always, *never*)") .long_help("Specify when to use ANSI sequences for italic text in the output. Possible values: always, *never*."), ) .arg( Arg::with_name("decorations") .long("decorations") .overrides_with("decorations") .takes_value(true) .value_name("when") .possible_values(&["auto", "never", "always"]) .default_value("auto") .hide_default_value(true) .help("When to show the decorations (*auto*, never, always).") .long_help( "Specify when to use the decorations that have been specified \ via '--style'. The automatic mode only enables decorations if \ an interactive terminal is detected. Possible values: *auto*, never, always.", ), ) .arg( Arg::with_name("force-colorization") .long("force-colorization") .short("f") .conflicts_with("color") .conflicts_with("decorations") .overrides_with("force-colorization") .hidden_short_help(true) .long_help("Alias for '--decorations=always --color=always'. This is useful \ if the output of bat is piped to another program, but you want \ to keep the colorization/decorations.") ) .arg( Arg::with_name("paging") .long("paging") .overrides_with("paging") .takes_value(true) .value_name("when") .possible_values(&["auto", "never", "always"]) .default_value("auto") .hide_default_value(true) .help("Specify when to use the pager, or use `-P` to disable (*auto*, never, always).") .long_help( "Specify when to use the pager. To disable the pager, use \ --paging=never' or its alias,'-P'. To disable the pager permanently, \ set BAT_PAGER to an empty string. To control which pager is used, see the \ '--pager' option. Possible values: *auto*, never, always." ), ) .arg( Arg::with_name("no-paging") .short("P") .long("no-paging") .alias("no-pager") .overrides_with("no-paging") .hidden(true) .hidden_short_help(true) .help("Alias for '--paging=never'") ) .arg( Arg::with_name("pager") .long("pager") .overrides_with("pager") .takes_value(true) .value_name("command") .hidden_short_help(true) .help("Determine which pager to use.") .long_help( "Determine which pager is used. This option will override the \ PAGER and BAT_PAGER environment variables. The default pager is 'less'. \ To control when the pager is used, see the '--paging' option. \ Example: '--pager \"less -RF\"'." ), ) .arg( Arg::with_name("map-syntax") .short("m") .long("map-syntax") .multiple(true) .takes_value(true) .number_of_values(1) .value_name("glob:syntax") .help("Use the specified syntax for files matching the glob pattern ('*.cpp:C++').") .long_help( "Map a glob pattern to an existing syntax name. The glob pattern is matched \ on the full path and the filename. For example, to highlight *.build files \ with the Python syntax, use -m '*.build:Python'. To highlight files named \ '.myignore' with the Git Ignore syntax, use -m '.myignore:Git Ignore'. Note \ that the right-hand side is the *name* of the syntax, not a file extension.", ) .takes_value(true), ) .arg( Arg::with_name("ignored-suffix") .number_of_values(1) .multiple(true) .takes_value(true) .long("ignored-suffix") .hidden_short_help(true) .help( "Ignore extension. For example:\n \ 'bat --ignored-suffix \".dev\" my_file.json.dev' will use JSON syntax, and ignore '.dev'" ) ) .arg( Arg::with_name("theme") .long("theme") .overrides_with("theme") .takes_value(true) .help("Set the color theme for syntax highlighting.") .long_help( "Set the theme for syntax highlighting. Use '--list-themes' to \ see all available themes. To set a default theme, add the \ '--theme=\"...\"' option to the configuration file or export the \ BAT_THEME environment variable (e.g.: export \ BAT_THEME=\"...\").", ), ) .arg( Arg::with_name("list-themes") .long("list-themes") .help("Display all supported highlighting themes.") .long_help("Display a list of supported themes for syntax highlighting."), ) .arg( Arg::with_name("style") .long("style") .value_name("components") // Need to turn this off for overrides_with to work as we want. See the bottom most // example at https://docs.rs/clap/2.32.0/clap/struct.Arg.html#method.overrides_with .use_delimiter(false) .takes_value(true) .overrides_with("style") .overrides_with("plain") .overrides_with("number") // Cannot use claps built in validation because we have to turn off clap's delimiters .validator(|val| { let mut invalid_vals = val.split(',').filter(|style| { !&[ "auto", "full", "plain", "header", "grid", "rule", "numbers", "snip", #[cfg(feature = "git")] "changes", ] .contains(style) }); if let Some(invalid) = invalid_vals.next() { Err(format!("Unknown style, '{}'", invalid)) } else { Ok(()) } }) .help( "Comma-separated list of style elements to display \ (*auto*, full, plain, changes, header, grid, rule, numbers, snip).", ) .long_help( "Configure which elements (line numbers, file headers, grid \ borders, Git modifications, ..) to display in addition to the \ file contents. The argument is a comma-separated list of \ components to display (e.g. 'numbers,changes,grid') or a \ pre-defined style ('full'). To set a default style, add the \ '--style=\"..\"' option to the configuration file or export the \ BAT_STYLE environment variable (e.g.: export BAT_STYLE=\"..\").\n\n\ Possible values:\n\n \ * full: enables all available components (default).\n \ * auto: same as 'full', unless the output is piped.\n \ * plain: disables all available components.\n \ * changes: show Git modification markers.\n \ * header: show filenames before the content.\n \ * grid: vertical/horizontal lines to separate side bar\n \ and the header from the content.\n \ * rule: horizontal lines to delimit files.\n \ * numbers: show line numbers in the side bar.\n \ * snip: draw separation lines between distinct line ranges.", ), ) .arg( Arg::with_name("line-range") .long("line-range") .short("r") .multiple(true) .takes_value(true) .number_of_values(1) .value_name("N:M") .conflicts_with("diff") .help("Only print the lines from N to M.") .long_help( "Only print the specified range of lines for each file. \ For example:\n \ '--line-range 30:40' prints lines 30 to 40\n \ '--line-range :40' prints lines 1 to 40\n \ '--line-range 40:' prints lines 40 to the end of the file\n \ '--line-range 40' only prints line 40\n \ '--line-range 30:+10' prints lines 30 to 40", ), ) .arg( Arg::with_name("list-languages") .long("list-languages") .short("L") .conflicts_with("list-themes") .help("Display all supported languages.") .long_help("Display a list of supported languages for syntax highlighting."), ) .arg( Arg::with_name("unbuffered") .short("u") .long("unbuffered") .hidden_short_help(true) .long_help( "This option exists for POSIX-compliance reasons ('u' is for \ 'unbuffered'). The output is always unbuffered - this option \ is simply ignored.", ), ) .arg( Arg::with_name("no-config") .long("no-config") .hidden(true) .help("Do not use the configuration file"), ) .arg( Arg::with_name("no-custom-assets") .long("no-custom-assets") .hidden(true) .help("Do not load custom assets"), ) .arg( Arg::with_name("config-file") .long("config-file") .conflicts_with("list-languages") .conflicts_with("list-themes") .hidden(true) .help("Show path to the configuration file."), ) .arg( Arg::with_name("generate-config-file") .long("generate-config-file") .conflicts_with("list-languages") .conflicts_with("list-themes") .hidden(true) .help("Generates a default configuration file."), ) .arg( Arg::with_name("config-dir") .long("config-dir") .hidden(true) .help("Show bat's configuration directory."), ) .arg( Arg::with_name("cache-dir") .long("cache-dir") .hidden(true) .help("Show bat's cache directory."), ) .arg( Arg::with_name("diagnostic") .long("diagnostic") .alias("diagnostics") .hidden_short_help(true) .help("Show diagnostic information for bug reports.") ) .arg( Arg::with_name("acknowledgements") .long("acknowledgements") .hidden_short_help(true) .help("Show acknowledgements."), ) .help_message("Print this help message.") .version_message("Show version information."); // Check if the current directory contains a file name cache. Otherwise, // enable the 'bat cache' subcommand. if Path::new("cache").exists() { app } else { app.subcommand( SubCommand::with_name("cache") .about("Modify the syntax-definition and theme cache") .arg( Arg::with_name("build") .long("build") .short("b") .help("Initialize (or update) the syntax/theme cache.") .long_help( "Initialize (or update) the syntax/theme cache by loading from \ the source directory (default: the configuration directory).", ), ) .arg( Arg::with_name("clear") .long("clear") .short("c") .help("Remove the cached syntax definitions and themes."), ) .group( ArgGroup::with_name("cache-actions") .args(&["build", "clear"]) .required(true), ) .arg( Arg::with_name("source") .long("source") .requires("build") .takes_value(true) .value_name("dir") .help("Use a different directory to load syntaxes and themes from."), ) .arg( Arg::with_name("target") .long("target") .requires("build") .takes_value(true) .value_name("dir") .help( "Use a different directory to store the cached syntax and theme set.", ), ) .arg( Arg::with_name("blank") .long("blank") .requires("build") .help( "Create completely new syntax and theme sets \ (instead of appending to the default sets).", ), ) .arg( Arg::with_name("acknowledgements") .long("acknowledgements") .requires("build") .help("Build acknowledgements.bin."), ), ) } } bat-0.19.0/src/bin/bat/config.rs000064400000000000000000000110230072674642500144260ustar 00000000000000use std::env; use std::ffi::OsString; use std::fs; use std::io::{self, Write}; use std::path::PathBuf; use crate::directories::PROJECT_DIRS; pub fn config_file() -> PathBuf { env::var("BAT_CONFIG_PATH") .ok() .map(PathBuf::from) .unwrap_or_else(|| PROJECT_DIRS.config_dir().join("config")) } pub fn generate_config_file() -> bat::error::Result<()> { let config_file = config_file(); if config_file.is_file() { println!( "A config file already exists at: {}", config_file.to_string_lossy() ); print!("Overwrite? (y/N): "); io::stdout().flush()?; let mut decision = String::new(); io::stdin().read_line(&mut decision)?; if !decision.trim().eq_ignore_ascii_case("Y") { return Ok(()); } } else { let config_dir = config_file.parent(); match config_dir { Some(path) => fs::create_dir_all(path)?, None => { return Err(format!( "Unable to write config file to: {}", config_file.to_string_lossy() ) .into()); } } } let default_config = r#"# This is `bat`s configuration file. Each line either contains a comment or # a command-line option that you want to pass to `bat` by default. You can # run `bat --help` to get a list of all possible configuration options. # Specify desired highlighting theme (e.g. "TwoDark"). Run `bat --list-themes` # for a list of all available themes #--theme="TwoDark" # Enable this to use italic text on the terminal. This is not supported on all # terminal emulators (like tmux, by default): #--italic-text=always # Uncomment the following line to disable automatic paging: #--paging=never # Uncomment the following line if you are using less version >= 551 and want to # enable mouse scrolling support in `bat` when running inside tmux. This might # disable text selection, unless you press shift. #--pager="less --RAW-CONTROL-CHARS --quit-if-one-screen --mouse" # Syntax mappings: map a certain filename pattern to a language. # Example 1: use the C++ syntax for Arduino .ino files # Example 2: Use ".gitignore"-style highlighting for ".ignore" files #--map-syntax "*.ino:C++" #--map-syntax ".ignore:Git Ignore" "#; fs::write(&config_file, default_config).map_err(|e| { format!( "Failed to create config file at '{}': {}", config_file.to_string_lossy(), e ) })?; println!( "Success! Config file written to {}", config_file.to_string_lossy() ); Ok(()) } pub fn get_args_from_config_file() -> Result, shell_words::ParseError> { Ok(fs::read_to_string(config_file()) .ok() .map(|content| get_args_from_str(&content)) .transpose()? .unwrap_or_else(Vec::new)) } pub fn get_args_from_env_var() -> Option, shell_words::ParseError>> { env::var("BAT_OPTS").ok().map(|s| get_args_from_str(&s)) } fn get_args_from_str(content: &str) -> Result, shell_words::ParseError> { let args_per_line = content .split('\n') .map(|line| line.trim()) .filter(|line| !line.is_empty()) .filter(|line| !line.starts_with('#')) .map(shell_words::split) .collect::, _>>()?; Ok(args_per_line .iter() .flatten() .map(|line| line.into()) .collect()) } #[test] fn empty() { let args = get_args_from_str("").unwrap(); assert!(args.is_empty()); } #[test] fn single() { assert_eq!(vec!["--plain"], get_args_from_str("--plain").unwrap()); } #[test] fn multiple() { assert_eq!( vec!["--plain", "--language=cpp"], get_args_from_str("--plain --language=cpp").unwrap() ); } #[test] fn quotes() { assert_eq!( vec!["--theme", "Sublime Snazzy"], get_args_from_str("--theme \"Sublime Snazzy\"").unwrap() ); } #[test] fn multi_line() { let config = " -p --style numbers,changes --color=always "; assert_eq!( vec!["-p", "--style", "numbers,changes", "--color=always"], get_args_from_str(config).unwrap() ); } #[test] fn comments() { let config = " # plain style -p # show line numbers and Git modifications --style numbers,changes # Always show ANSI colors --color=always "; assert_eq!( vec!["-p", "--style", "numbers,changes", "--color=always"], get_args_from_str(config).unwrap() ); } bat-0.19.0/src/bin/bat/directories.rs000064400000000000000000000045260072674642500155070ustar 00000000000000use std::env; use std::path::{Path, PathBuf}; use once_cell::sync::Lazy; /// Wrapper for 'dirs' that treats MacOS more like Linux, by following the XDG specification. /// The `XDG_CACHE_HOME` environment variable is checked first. `BAT_CONFIG_DIR` /// is then checked before the `XDG_CONFIG_HOME` environment variable. /// The fallback directories are `~/.cache/bat` and `~/.config/bat`, respectively. pub struct BatProjectDirs { cache_dir: PathBuf, config_dir: PathBuf, } impl BatProjectDirs { fn new() -> Option { let cache_dir = BatProjectDirs::get_cache_dir()?; // Checks whether or not $BAT_CONFIG_DIR exists. If it doesn't, set our config dir // to our system's default configuration home. let config_dir = if let Some(config_dir_op) = env::var_os("BAT_CONFIG_DIR").map(PathBuf::from) { config_dir_op } else { #[cfg(target_os = "macos")] let config_dir_op = env::var_os("XDG_CONFIG_HOME") .map(PathBuf::from) .filter(|p| p.is_absolute()) .or_else(|| dirs_next::home_dir().map(|d| d.join(".config"))); #[cfg(not(target_os = "macos"))] let config_dir_op = dirs_next::config_dir(); config_dir_op.map(|d| d.join("bat"))? }; Some(BatProjectDirs { cache_dir, config_dir, }) } fn get_cache_dir() -> Option { // on all OS prefer BAT_CACHE_PATH if set let cache_dir_op = env::var_os("BAT_CACHE_PATH").map(PathBuf::from); if cache_dir_op.is_some() { return cache_dir_op; } #[cfg(target_os = "macos")] let cache_dir_op = env::var_os("XDG_CACHE_HOME") .map(PathBuf::from) .filter(|p| p.is_absolute()) .or_else(|| dirs_next::home_dir().map(|d| d.join(".cache"))); #[cfg(not(target_os = "macos"))] let cache_dir_op = dirs_next::cache_dir(); cache_dir_op.map(|d| d.join("bat")) } pub fn cache_dir(&self) -> &Path { &self.cache_dir } pub fn config_dir(&self) -> &Path { &self.config_dir } } pub static PROJECT_DIRS: Lazy = Lazy::new(|| BatProjectDirs::new().expect("Could not get home directory")); bat-0.19.0/src/bin/bat/input.rs000064400000000000000000000010630072674642500143230ustar 00000000000000use bat::input::Input; use std::path::Path; pub fn new_file_input<'a>(file: &'a Path, name: Option<&'a Path>) -> Input<'a> { named(Input::ordinary_file(file), name.or(Some(file))) } pub fn new_stdin_input(name: Option<&Path>) -> Input { named(Input::stdin(), name) } fn named<'a>(input: Input<'a>, name: Option<&Path>) -> Input<'a> { if let Some(provided_name) = name { let mut input = input.with_name(Some(provided_name)); input.description_mut().set_kind(Some("File".to_owned())); input } else { input } } bat-0.19.0/src/bin/bat/main.rs000064400000000000000000000267460072674642500141270ustar 00000000000000#![deny(unsafe_code)] mod app; mod assets; mod clap_app; mod config; mod directories; mod input; use std::collections::{HashMap, HashSet}; use std::io; use std::io::{BufReader, Write}; use std::path::Path; use std::process; use ansi_term::Colour::Green; use ansi_term::Style; use crate::{ app::App, config::{config_file, generate_config_file}, }; use assets::{assets_from_cache_or_binary, cache_dir, clear_assets, config_dir}; use directories::PROJECT_DIRS; use globset::GlobMatcher; use bat::{ config::Config, controller::Controller, error::*, input::Input, style::{StyleComponent, StyleComponents}, MappingTarget, PagingMode, }; const THEME_PREVIEW_DATA: &[u8] = include_bytes!("../../../assets/theme_preview.rs"); #[cfg(feature = "build-assets")] fn build_assets(matches: &clap::ArgMatches) -> Result<()> { let source_dir = matches .value_of("source") .map(Path::new) .unwrap_or_else(|| PROJECT_DIRS.config_dir()); let target_dir = matches .value_of("target") .map(Path::new) .unwrap_or_else(|| PROJECT_DIRS.cache_dir()); bat::assets::build( source_dir, !matches.is_present("blank"), matches.is_present("acknowledgements"), target_dir, clap::crate_version!(), ) } fn run_cache_subcommand(matches: &clap::ArgMatches) -> Result<()> { if matches.is_present("build") { #[cfg(feature = "build-assets")] build_assets(matches)?; #[cfg(not(feature = "build-assets"))] println!("bat has been built without the 'build-assets' feature. The 'cache --build' option is not available."); } else if matches.is_present("clear") { clear_assets(); } Ok(()) } fn get_syntax_mapping_to_paths<'a>( mappings: &[(GlobMatcher, MappingTarget<'a>)], ) -> HashMap<&'a str, Vec> { let mut map = HashMap::new(); for mapping in mappings { if let (matcher, MappingTarget::MapTo(s)) = mapping { let globs = map.entry(*s).or_insert_with(Vec::new); globs.push(matcher.glob().glob().into()); } } map } pub fn get_languages(config: &Config) -> Result { let mut result: String = String::new(); let assets = assets_from_cache_or_binary(config.use_custom_assets)?; let mut languages = assets .get_syntaxes()? .iter() .filter(|syntax| !syntax.hidden && !syntax.file_extensions.is_empty()) .cloned() .collect::>(); // Handling of file-extension conflicts, see issue #1076 for lang in &mut languages { let lang_name = lang.name.clone(); lang.file_extensions.retain(|extension| { // The 'extension' variable is not certainly a real extension. // // Skip if 'extension' starts with '.', likely a hidden file like '.vimrc' // Also skip if the 'extension' contains another real extension, likely // that is a full match file name like 'CMakeLists.txt' and 'Cargo.lock' if extension.starts_with('.') || Path::new(extension).extension().is_some() { return true; } let test_file = Path::new("test").with_extension(extension); let syntax_in_set = assets.get_syntax_for_path(test_file, &config.syntax_mapping); matches!(syntax_in_set, Ok(syntax_in_set) if syntax_in_set.syntax.name == lang_name) }); } languages.sort_by_key(|lang| lang.name.to_uppercase()); let configured_languages = get_syntax_mapping_to_paths(config.syntax_mapping.mappings()); for lang in &mut languages { if let Some(additional_paths) = configured_languages.get(lang.name.as_str()) { lang.file_extensions .extend(additional_paths.iter().cloned()); } } if config.loop_through { for lang in languages { result += &format!("{}:{}\n", lang.name, lang.file_extensions.join(",")); } } else { let longest = languages .iter() .map(|syntax| syntax.name.len()) .max() .unwrap_or(32); // Fallback width if they have no language definitions. let comma_separator = ", "; let separator = " "; // Line-wrapping for the possible file extension overflow. let desired_width = config.term_width - longest - separator.len(); let style = if config.colored_output { Green.normal() } else { Style::default() }; for lang in languages { result += &format!("{:width$}{}", lang.name, separator, width = longest); // Number of characters on this line so far, wrap before `desired_width` let mut num_chars = 0; let mut extension = lang.file_extensions.iter().peekable(); while let Some(word) = extension.next() { // If we can't fit this word in, then create a line break and align it in. let new_chars = word.len() + comma_separator.len(); if num_chars + new_chars >= desired_width { num_chars = 0; result += &format!("\n{:width$}{}", "", separator, width = longest); } num_chars += new_chars; result += &format!("{}", style.paint(&word[..])); if extension.peek().is_some() { result += comma_separator; } } result += "\n"; } } Ok(result) } fn theme_preview_file<'a>() -> Input<'a> { Input::from_reader(Box::new(BufReader::new(THEME_PREVIEW_DATA))) } pub fn list_themes(cfg: &Config) -> Result<()> { let assets = assets_from_cache_or_binary(cfg.use_custom_assets)?; let mut config = cfg.clone(); let mut style = HashSet::new(); style.insert(StyleComponent::Plain); config.language = Some("Rust"); config.style_components = StyleComponents(style); let stdout = io::stdout(); let mut stdout = stdout.lock(); if config.colored_output { for theme in assets.themes() { writeln!( stdout, "Theme: {}\n", Style::new().bold().paint(theme.to_string()) )?; config.theme = theme.to_string(); Controller::new(&config, &assets) .run(vec![theme_preview_file()]) .ok(); writeln!(stdout)?; } writeln!( stdout, "Further themes can be installed to '{}', \ and are added to the cache with `bat cache --build`. \ For more information, see:\n\n \ https://github.com/sharkdp/bat#adding-new-themes", PROJECT_DIRS.config_dir().join("themes").to_string_lossy() )?; } else { for theme in assets.themes() { writeln!(stdout, "{}", theme)?; } } Ok(()) } fn run_controller(inputs: Vec, config: &Config) -> Result { let assets = assets_from_cache_or_binary(config.use_custom_assets)?; let controller = Controller::new(config, &assets); controller.run(inputs) } #[cfg(feature = "bugreport")] fn invoke_bugreport(app: &App) { use bugreport::{bugreport, collector::*, format::Markdown}; let pager = bat::config::get_pager_executable(app.matches.value_of("pager")) .unwrap_or_else(|| "less".to_owned()); // FIXME: Avoid non-canonical path to "less". let mut report = bugreport!() .info(SoftwareVersion::default()) .info(OperatingSystem::default()) .info(CommandLine::default()) .info(EnvironmentVariables::list(&[ "SHELL", "PAGER", "LESS", "LANG", "LC_ALL", "BAT_PAGER", "BAT_CACHE_PATH", "BAT_CONFIG_PATH", "BAT_OPTS", "BAT_STYLE", "BAT_TABS", "BAT_THEME", "XDG_CONFIG_HOME", "XDG_CACHE_HOME", "COLORTERM", "NO_COLOR", "MANPAGER", ])) .info(FileContent::new("Config file", config_file())) .info(CompileTimeInformation::default()); #[cfg(feature = "paging")] if let Ok(resolved_path) = grep_cli::resolve_binary(pager) { report = report.info(CommandOutput::new( "Less version", resolved_path, &["--version"], )) }; report.print::(); } /// Returns `Err(..)` upon fatal errors. Otherwise, returns `Ok(true)` on full success and /// `Ok(false)` if any intermediate errors occurred (were printed). fn run() -> Result { let app = App::new()?; if app.matches.is_present("diagnostic") { #[cfg(feature = "bugreport")] invoke_bugreport(&app); #[cfg(not(feature = "bugreport"))] println!("bat has been built without the 'bugreport' feature. The '--diagnostic' option is not available."); return Ok(true); } match app.matches.subcommand() { ("cache", Some(cache_matches)) => { // If there is a file named 'cache' in the current working directory, // arguments for subcommand 'cache' are not mandatory. // If there are non-zero arguments, execute the subcommand cache, else, open the file cache. if !cache_matches.args.is_empty() { run_cache_subcommand(cache_matches)?; Ok(true) } else { let inputs = vec![Input::ordinary_file("cache")]; let config = app.config(&inputs)?; run_controller(inputs, &config) } } _ => { let inputs = app.inputs()?; let config = app.config(&inputs)?; if app.matches.is_present("list-languages") { let languages: String = get_languages(&config)?; let inputs: Vec = vec![Input::from_reader(Box::new(languages.as_bytes()))]; let plain_config = Config { style_components: StyleComponents::new(StyleComponent::Plain.components(false)), paging_mode: PagingMode::QuitIfOneScreen, ..Default::default() }; run_controller(inputs, &plain_config) } else if app.matches.is_present("list-themes") { list_themes(&config)?; Ok(true) } else if app.matches.is_present("config-file") { println!("{}", config_file().to_string_lossy()); Ok(true) } else if app.matches.is_present("generate-config-file") { generate_config_file()?; Ok(true) } else if app.matches.is_present("config-dir") { writeln!(io::stdout(), "{}", config_dir())?; Ok(true) } else if app.matches.is_present("cache-dir") { writeln!(io::stdout(), "{}", cache_dir())?; Ok(true) } else if app.matches.is_present("acknowledgements") { writeln!(io::stdout(), "{}", bat::assets::get_acknowledgements())?; Ok(true) } else { run_controller(inputs, &config) } } } } fn main() { let result = run(); match result { Err(error) => { let stderr = std::io::stderr(); default_error_handler(&error, &mut stderr.lock()); process::exit(1); } Ok(false) => { process::exit(1); } Ok(true) => { process::exit(0); } } } bat-0.19.0/src/config.rs000064400000000000000000000062310072674642500131150ustar 00000000000000use crate::line_range::{HighlightedLineRanges, LineRanges}; #[cfg(feature = "paging")] use crate::paging::PagingMode; use crate::style::StyleComponents; use crate::syntax_mapping::SyntaxMapping; use crate::wrapping::WrappingMode; #[derive(Debug, Clone)] pub enum VisibleLines { /// Show all lines which are included in the line ranges Ranges(LineRanges), #[cfg(feature = "git")] /// Only show lines surrounding added/deleted/modified lines DiffContext(usize), } impl VisibleLines { pub fn diff_mode(&self) -> bool { match self { Self::Ranges(_) => false, #[cfg(feature = "git")] Self::DiffContext(_) => true, } } } impl Default for VisibleLines { fn default() -> Self { VisibleLines::Ranges(LineRanges::default()) } } #[derive(Debug, Clone, Default)] pub struct Config<'a> { /// The explicitly configured language, if any pub language: Option<&'a str>, /// Whether or not to show/replace non-printable characters like space, tab and newline. pub show_nonprintable: bool, /// The character width of the terminal pub term_width: usize, /// The width of tab characters. /// Currently, a value of 0 will cause tabs to be passed through without expanding them. pub tab_width: usize, /// Whether or not to simply loop through all input (`cat` mode) pub loop_through: bool, /// Whether or not the output should be colorized pub colored_output: bool, /// Whether or not the output terminal supports true color pub true_color: bool, /// Style elements (grid, line numbers, ...) pub style_components: StyleComponents, /// If and how text should be wrapped pub wrapping_mode: WrappingMode, /// Pager or STDOUT #[cfg(feature = "paging")] pub paging_mode: PagingMode, /// Specifies which lines should be printed pub visible_lines: VisibleLines, /// The syntax highlighting theme pub theme: String, /// File extension/name mappings pub syntax_mapping: SyntaxMapping<'a>, /// Command to start the pager pub pager: Option<&'a str>, /// Whether or not to use ANSI italics pub use_italic_text: bool, /// Ranges of lines which should be highlighted with a special background color pub highlighted_lines: HighlightedLineRanges, /// Whether or not to allow custom assets. If this is false or if custom assets (a.k.a. /// cached assets) are not available, assets from the binary will be used instead. pub use_custom_assets: bool, } #[cfg(all(feature = "minimal-application", feature = "paging"))] pub fn get_pager_executable(config_pager: Option<&str>) -> Option { crate::pager::get_pager(config_pager) .ok() .flatten() .map(|pager| pager.bin) } #[test] fn default_config_should_include_all_lines() { use crate::line_range::RangeCheckResult; assert_eq!(LineRanges::default().check(17), RangeCheckResult::InRange); } #[test] fn default_config_should_highlight_no_lines() { use crate::line_range::RangeCheckResult; assert_ne!( Config::default().highlighted_lines.0.check(17), RangeCheckResult::InRange ); } bat-0.19.0/src/controller.rs000064400000000000000000000200560072674642500140340ustar 00000000000000use std::io::{self, BufRead, Write}; use crate::assets::HighlightingAssets; use crate::config::{Config, VisibleLines}; #[cfg(feature = "git")] use crate::diff::{get_git_diff, LineChanges}; use crate::error::*; use crate::input::{Input, InputReader, OpenedInput}; #[cfg(feature = "git")] use crate::line_range::LineRange; use crate::line_range::{LineRanges, RangeCheckResult}; use crate::output::OutputType; #[cfg(feature = "paging")] use crate::paging::PagingMode; use crate::printer::{InteractivePrinter, Printer, SimplePrinter}; use clircle::{Clircle, Identifier}; pub struct Controller<'a> { config: &'a Config<'a>, assets: &'a HighlightingAssets, } impl<'b> Controller<'b> { pub fn new<'a>(config: &'a Config, assets: &'a HighlightingAssets) -> Controller<'a> { Controller { config, assets } } pub fn run(&self, inputs: Vec) -> Result { self.run_with_error_handler(inputs, default_error_handler) } pub fn run_with_error_handler( &self, inputs: Vec, handle_error: impl Fn(&Error, &mut dyn Write), ) -> Result { let mut output_type; #[cfg(feature = "paging")] { use crate::input::InputKind; use std::path::Path; // Do not launch the pager if NONE of the input files exist let mut paging_mode = self.config.paging_mode; if self.config.paging_mode != PagingMode::Never { let call_pager = inputs.iter().any(|input| { if let InputKind::OrdinaryFile(ref path) = input.kind { Path::new(path).exists() } else { true } }); if !call_pager { paging_mode = PagingMode::Never; } } let wrapping_mode = self.config.wrapping_mode; output_type = OutputType::from_mode(paging_mode, wrapping_mode, self.config.pager)?; } #[cfg(not(feature = "paging"))] { output_type = OutputType::stdout(); } let attached_to_pager = output_type.is_pager(); let stdout_identifier = if cfg!(windows) || attached_to_pager { None } else { clircle::Identifier::stdout() }; let writer = output_type.handle()?; let mut no_errors: bool = true; let stderr = io::stderr(); for (index, input) in inputs.into_iter().enumerate() { let identifier = stdout_identifier.as_ref(); let is_first = index == 0; let result = if input.is_stdin() { self.print_input(input, writer, io::stdin().lock(), identifier, is_first) } else { // Use dummy stdin since stdin is actually not used (#1902) self.print_input(input, writer, io::empty(), identifier, is_first) }; if let Err(error) = result { if attached_to_pager { handle_error(&error, writer); } else { handle_error(&error, &mut stderr.lock()); } no_errors = false; } } Ok(no_errors) } fn print_input( &self, input: Input, writer: &mut dyn Write, stdin: R, stdout_identifier: Option<&Identifier>, is_first: bool, ) -> Result<()> { let mut opened_input = input.open(stdin, stdout_identifier)?; #[cfg(feature = "git")] let line_changes = if self.config.visible_lines.diff_mode() || (!self.config.loop_through && self.config.style_components.changes()) { match opened_input.kind { crate::input::OpenedInputKind::OrdinaryFile(ref path) => { let diff = get_git_diff(path); // Skip files without Git modifications if self.config.visible_lines.diff_mode() && diff .as_ref() .map(|changes| changes.is_empty()) .unwrap_or(false) { return Ok(()); } diff } _ if self.config.visible_lines.diff_mode() => { // Skip non-file inputs in diff mode return Ok(()); } _ => None, } } else { None }; let mut printer: Box = if self.config.loop_through { Box::new(SimplePrinter::new(self.config)) } else { Box::new(InteractivePrinter::new( self.config, self.assets, &mut opened_input, #[cfg(feature = "git")] &line_changes, )?) }; self.print_file( &mut *printer, writer, &mut opened_input, !is_first, #[cfg(feature = "git")] &line_changes, ) } fn print_file( &self, printer: &mut dyn Printer, writer: &mut dyn Write, input: &mut OpenedInput, add_header_padding: bool, #[cfg(feature = "git")] line_changes: &Option, ) -> Result<()> { if !input.reader.first_line.is_empty() || self.config.style_components.header() { printer.print_header(writer, input, add_header_padding)?; } if !input.reader.first_line.is_empty() { let line_ranges = match self.config.visible_lines { VisibleLines::Ranges(ref line_ranges) => line_ranges.clone(), #[cfg(feature = "git")] VisibleLines::DiffContext(context) => { let mut line_ranges: Vec = vec![]; if let Some(line_changes) = line_changes { for &line in line_changes.keys() { let line = line as usize; line_ranges .push(LineRange::new(line.saturating_sub(context), line + context)); } } LineRanges::from(line_ranges) } }; self.print_file_ranges(printer, writer, &mut input.reader, &line_ranges)?; } printer.print_footer(writer, input)?; Ok(()) } fn print_file_ranges( &self, printer: &mut dyn Printer, writer: &mut dyn Write, reader: &mut InputReader, line_ranges: &LineRanges, ) -> Result<()> { let mut line_buffer = Vec::new(); let mut line_number: usize = 1; let mut first_range: bool = true; let mut mid_range: bool = false; let style_snip = self.config.style_components.snip(); while reader.read_line(&mut line_buffer)? { match line_ranges.check(line_number) { RangeCheckResult::BeforeOrBetweenRanges => { // Call the printer in case we need to call the syntax highlighter // for this line. However, set `out_of_range` to `true`. printer.print_line(true, writer, line_number, &line_buffer)?; mid_range = false; } RangeCheckResult::InRange => { if style_snip { if first_range { first_range = false; mid_range = true; } else if !mid_range { mid_range = true; printer.print_snip(writer)?; } } printer.print_line(false, writer, line_number, &line_buffer)?; } RangeCheckResult::AfterLastRange => { break; } } line_number += 1; line_buffer.clear(); } Ok(()) } } bat-0.19.0/src/decorations.rs000064400000000000000000000104100072674642500141540ustar 00000000000000#[cfg(feature = "git")] use crate::diff::LineChange; use crate::printer::{Colors, InteractivePrinter}; use ansi_term::Style; #[derive(Debug, Clone)] pub(crate) struct DecorationText { pub width: usize, pub text: String, } pub(crate) trait Decoration { fn generate( &self, line_number: usize, continuation: bool, printer: &InteractivePrinter, ) -> DecorationText; fn width(&self) -> usize; } pub(crate) struct LineNumberDecoration { color: Style, cached_wrap: DecorationText, cached_wrap_invalid_at: usize, } impl LineNumberDecoration { pub(crate) fn new(colors: &Colors) -> Self { LineNumberDecoration { color: colors.line_number, cached_wrap_invalid_at: 10000, cached_wrap: DecorationText { text: colors.line_number.paint(" ".repeat(4)).to_string(), width: 4, }, } } } impl Decoration for LineNumberDecoration { fn generate( &self, line_number: usize, continuation: bool, _printer: &InteractivePrinter, ) -> DecorationText { if continuation { if line_number > self.cached_wrap_invalid_at { let new_width = self.cached_wrap.width + 1; return DecorationText { text: self.color.paint(" ".repeat(new_width)).to_string(), width: new_width, }; } self.cached_wrap.clone() } else { let plain: String = format!("{:4}", line_number); DecorationText { width: plain.len(), text: self.color.paint(plain).to_string(), } } } fn width(&self) -> usize { 4 } } #[cfg(feature = "git")] pub(crate) struct LineChangesDecoration { cached_none: DecorationText, cached_added: DecorationText, cached_removed_above: DecorationText, cached_removed_below: DecorationText, cached_modified: DecorationText, } #[cfg(feature = "git")] impl LineChangesDecoration { #[inline] fn generate_cached(style: Style, text: &str) -> DecorationText { DecorationText { text: style.paint(text).to_string(), width: text.chars().count(), } } pub(crate) fn new(colors: &Colors) -> Self { LineChangesDecoration { cached_none: Self::generate_cached(Style::default(), " "), cached_added: Self::generate_cached(colors.git_added, "+"), cached_removed_above: Self::generate_cached(colors.git_removed, "‾"), cached_removed_below: Self::generate_cached(colors.git_removed, "_"), cached_modified: Self::generate_cached(colors.git_modified, "~"), } } } #[cfg(feature = "git")] impl Decoration for LineChangesDecoration { fn generate( &self, line_number: usize, continuation: bool, printer: &InteractivePrinter, ) -> DecorationText { if !continuation { if let Some(ref changes) = printer.line_changes { return match changes.get(&(line_number as u32)) { Some(&LineChange::Added) => self.cached_added.clone(), Some(&LineChange::RemovedAbove) => self.cached_removed_above.clone(), Some(&LineChange::RemovedBelow) => self.cached_removed_below.clone(), Some(&LineChange::Modified) => self.cached_modified.clone(), _ => self.cached_none.clone(), }; } } self.cached_none.clone() } fn width(&self) -> usize { self.cached_none.width } } pub(crate) struct GridBorderDecoration { cached: DecorationText, } impl GridBorderDecoration { pub(crate) fn new(colors: &Colors) -> Self { GridBorderDecoration { cached: DecorationText { text: colors.grid.paint("│").to_string(), width: 1, }, } } } impl Decoration for GridBorderDecoration { fn generate( &self, _line_number: usize, _continuation: bool, _printer: &InteractivePrinter, ) -> DecorationText { self.cached.clone() } fn width(&self) -> usize { self.cached.width } } bat-0.19.0/src/diff.rs000064400000000000000000000047000072674642500125570ustar 00000000000000#![cfg(feature = "git")] use std::collections::HashMap; use std::fs; use std::path::Path; use git2::{DiffOptions, IntoCString, Repository}; #[derive(Copy, Clone, Debug)] pub enum LineChange { Added, RemovedAbove, RemovedBelow, Modified, } pub type LineChanges = HashMap; pub fn get_git_diff(filename: &Path) -> Option { let repo = Repository::discover(&filename).ok()?; let repo_path_absolute = fs::canonicalize(repo.workdir()?).ok()?; let filepath_absolute = fs::canonicalize(&filename).ok()?; let filepath_relative_to_repo = filepath_absolute.strip_prefix(&repo_path_absolute).ok()?; let mut diff_options = DiffOptions::new(); let pathspec = filepath_relative_to_repo.into_c_string().ok()?; diff_options.pathspec(pathspec); diff_options.context_lines(0); let diff = repo .diff_index_to_workdir(None, Some(&mut diff_options)) .ok()?; let mut line_changes: LineChanges = HashMap::new(); let mark_section = |line_changes: &mut LineChanges, start: u32, end: i32, change: LineChange| { for line in start..=end as u32 { line_changes.insert(line, change); } }; let _ = diff.foreach( &mut |_, _| true, None, Some(&mut |delta, hunk| { let path = delta.new_file().path().unwrap_or_else(|| Path::new("")); if filepath_relative_to_repo != path { return false; } let old_lines = hunk.old_lines(); let new_start = hunk.new_start(); let new_lines = hunk.new_lines(); let new_end = (new_start + new_lines) as i32 - 1; if old_lines == 0 && new_lines > 0 { mark_section(&mut line_changes, new_start, new_end, LineChange::Added); } else if new_lines == 0 && old_lines > 0 { if new_start == 0 { mark_section(&mut line_changes, 1, 1, LineChange::RemovedAbove); } else { mark_section( &mut line_changes, new_start, new_start as i32, LineChange::RemovedBelow, ); } } else { mark_section(&mut line_changes, new_start, new_end, LineChange::Modified); } true }), None, ); Some(line_changes) } bat-0.19.0/src/error.rs000064400000000000000000000032600072674642500130000ustar 00000000000000use std::io::Write; use thiserror::Error; #[derive(Error, Debug)] pub enum Error { #[error(transparent)] Io(#[from] ::std::io::Error), #[error(transparent)] SyntectError(#[from] ::syntect::LoadingError), #[error(transparent)] ParseIntError(#[from] ::std::num::ParseIntError), #[error(transparent)] GlobParsingError(#[from] ::globset::Error), #[error(transparent)] SerdeYamlError(#[from] ::serde_yaml::Error), #[error("unable to detect syntax for {0}")] UndetectedSyntax(String), #[error("unknown syntax: '{0}'")] UnknownSyntax(String), #[error("Unknown style '{0}'")] UnknownStyle(String), #[error("Use of bat as a pager is disallowed in order to avoid infinite recursion problems")] InvalidPagerValueBat, #[error("{0}")] Msg(String), } impl From<&'static str> for Error { fn from(s: &'static str) -> Self { Error::Msg(s.to_owned()) } } impl From for Error { fn from(s: String) -> Self { Error::Msg(s) } } pub type Result = std::result::Result; pub fn default_error_handler(error: &Error, output: &mut dyn Write) { use ansi_term::Colour::Red; match error { Error::Io(ref io_error) if io_error.kind() == ::std::io::ErrorKind::BrokenPipe => { ::std::process::exit(0); } Error::SerdeYamlError(_) => { writeln!( output, "{}: Error while parsing metadata.yaml file: {}", Red.paint("[bat error]"), error ) .ok(); } _ => { writeln!(output, "{}: {}", Red.paint("[bat error]"), error).ok(); } }; } bat-0.19.0/src/input.rs000064400000000000000000000235660072674642500130210ustar 00000000000000use std::convert::TryFrom; use std::fs::File; use std::io::{self, BufRead, BufReader, Read}; use std::path::{Path, PathBuf}; use clircle::{Clircle, Identifier}; use content_inspector::{self, ContentType}; use crate::error::*; /// A description of an Input source. /// This tells bat how to refer to the input. #[derive(Clone)] pub struct InputDescription { pub(crate) name: String, /// The input title. /// This replaces the name if provided. title: Option, /// The input kind. kind: Option, /// A summary description of the input. /// Defaults to "{kind} '{name}'" summary: Option, } impl InputDescription { /// Creates a description for an input. pub fn new(name: impl Into) -> Self { InputDescription { name: name.into(), title: None, kind: None, summary: None, } } pub fn set_kind(&mut self, kind: Option) { self.kind = kind; } pub fn set_summary(&mut self, summary: Option) { self.summary = summary; } pub fn set_title(&mut self, title: Option) { self.title = title; } pub fn title(&self) -> &String { match &self.title { Some(title) => title, None => &self.name, } } pub fn kind(&self) -> Option<&String> { self.kind.as_ref() } pub fn summary(&self) -> String { self.summary.clone().unwrap_or_else(|| match &self.kind { None => self.name.clone(), Some(kind) => format!("{} '{}'", kind.to_lowercase(), self.name), }) } } pub(crate) enum InputKind<'a> { OrdinaryFile(PathBuf), StdIn, CustomReader(Box), } impl<'a> InputKind<'a> { pub fn description(&self) -> InputDescription { match self { InputKind::OrdinaryFile(ref path) => InputDescription::new(path.to_string_lossy()), InputKind::StdIn => InputDescription::new("STDIN"), InputKind::CustomReader(_) => InputDescription::new("READER"), } } } #[derive(Clone, Default)] pub(crate) struct InputMetadata { pub(crate) user_provided_name: Option, } pub struct Input<'a> { pub(crate) kind: InputKind<'a>, pub(crate) metadata: InputMetadata, pub(crate) description: InputDescription, } pub(crate) enum OpenedInputKind { OrdinaryFile(PathBuf), StdIn, CustomReader, } pub(crate) struct OpenedInput<'a> { pub(crate) kind: OpenedInputKind, pub(crate) metadata: InputMetadata, pub(crate) reader: InputReader<'a>, pub(crate) description: InputDescription, } impl OpenedInput<'_> { /// Get the path of the file: /// If this was set by the metadata, that will take priority. /// If it wasn't, it will use the real file path (if available). pub(crate) fn path(&self) -> Option<&PathBuf> { self.metadata .user_provided_name .as_ref() .or_else(|| match self.kind { OpenedInputKind::OrdinaryFile(ref path) => Some(path), _ => None, }) } } impl<'a> Input<'a> { pub fn ordinary_file(path: impl AsRef) -> Self { Self::_ordinary_file(path.as_ref()) } fn _ordinary_file(path: &Path) -> Self { let kind = InputKind::OrdinaryFile(path.to_path_buf()); Input { description: kind.description(), metadata: InputMetadata::default(), kind, } } pub fn stdin() -> Self { let kind = InputKind::StdIn; Input { description: kind.description(), metadata: InputMetadata::default(), kind, } } pub fn from_reader(reader: Box) -> Self { let kind = InputKind::CustomReader(reader); Input { description: kind.description(), metadata: InputMetadata::default(), kind, } } pub fn is_stdin(&self) -> bool { matches!(self.kind, InputKind::StdIn) } pub fn with_name(self, provided_name: Option>) -> Self { self._with_name(provided_name.as_ref().map(|it| it.as_ref())) } fn _with_name(mut self, provided_name: Option<&Path>) -> Self { if let Some(name) = provided_name { self.description.name = name.to_string_lossy().to_string() } self.metadata.user_provided_name = provided_name.map(|n| n.to_owned()); self } pub fn description(&self) -> &InputDescription { &self.description } pub fn description_mut(&mut self) -> &mut InputDescription { &mut self.description } pub(crate) fn open( self, stdin: R, stdout_identifier: Option<&Identifier>, ) -> Result> { let description = self.description().clone(); match self.kind { InputKind::StdIn => { if let Some(stdout) = stdout_identifier { let input_identifier = Identifier::try_from(clircle::Stdio::Stdin) .map_err(|e| format!("Stdin: Error identifying file: {}", e))?; if stdout.surely_conflicts_with(&input_identifier) { return Err("IO circle detected. The input from stdin is also an output. Aborting to avoid infinite loop.".into()); } } Ok(OpenedInput { kind: OpenedInputKind::StdIn, description, metadata: self.metadata, reader: InputReader::new(stdin), }) } InputKind::OrdinaryFile(path) => Ok(OpenedInput { kind: OpenedInputKind::OrdinaryFile(path.clone()), description, metadata: self.metadata, reader: { let mut file = File::open(&path) .map_err(|e| format!("'{}': {}", path.to_string_lossy(), e))?; if file.metadata()?.is_dir() { return Err(format!("'{}' is a directory.", path.to_string_lossy()).into()); } if let Some(stdout) = stdout_identifier { let input_identifier = Identifier::try_from(file).map_err(|e| { format!("{}: Error identifying file: {}", path.to_string_lossy(), e) })?; if stdout.surely_conflicts_with(&input_identifier) { return Err(format!( "IO circle detected. The input from '{}' is also an output. Aborting to avoid infinite loop.", path.to_string_lossy() ) .into()); } file = input_identifier.into_inner().expect("The file was lost in the clircle::Identifier, this should not have happened..."); } InputReader::new(BufReader::new(file)) }, }), InputKind::CustomReader(reader) => Ok(OpenedInput { description, kind: OpenedInputKind::CustomReader, metadata: self.metadata, reader: InputReader::new(BufReader::new(reader)), }), } } } pub(crate) struct InputReader<'a> { inner: Box, pub(crate) first_line: Vec, pub(crate) content_type: Option, } impl<'a> InputReader<'a> { fn new(mut reader: R) -> InputReader<'a> { let mut first_line = vec![]; reader.read_until(b'\n', &mut first_line).ok(); let content_type = if first_line.is_empty() { None } else { Some(content_inspector::inspect(&first_line[..])) }; if content_type == Some(ContentType::UTF_16LE) { reader.read_until(0x00, &mut first_line).ok(); } InputReader { inner: Box::new(reader), first_line, content_type, } } pub(crate) fn read_line(&mut self, buf: &mut Vec) -> io::Result { if !self.first_line.is_empty() { buf.append(&mut self.first_line); return Ok(true); } let res = self.inner.read_until(b'\n', buf).map(|size| size > 0)?; if self.content_type == Some(ContentType::UTF_16LE) { let _ = self.inner.read_until(0x00, buf); } Ok(res) } } #[test] fn basic() { let content = b"#!/bin/bash\necho hello"; let mut reader = InputReader::new(&content[..]); assert_eq!(b"#!/bin/bash\n", &reader.first_line[..]); let mut buffer = vec![]; let res = reader.read_line(&mut buffer); assert!(res.is_ok()); assert!(res.unwrap()); assert_eq!(b"#!/bin/bash\n", &buffer[..]); buffer.clear(); let res = reader.read_line(&mut buffer); assert!(res.is_ok()); assert!(res.unwrap()); assert_eq!(b"echo hello", &buffer[..]); buffer.clear(); let res = reader.read_line(&mut buffer); assert!(res.is_ok()); assert!(!res.unwrap()); assert!(buffer.is_empty()); } #[test] fn utf16le() { let content = b"\xFF\xFE\x73\x00\x0A\x00\x64\x00"; let mut reader = InputReader::new(&content[..]); assert_eq!(b"\xFF\xFE\x73\x00\x0A\x00", &reader.first_line[..]); let mut buffer = vec![]; let res = reader.read_line(&mut buffer); assert!(res.is_ok()); assert!(res.unwrap()); assert_eq!(b"\xFF\xFE\x73\x00\x0A\x00", &buffer[..]); buffer.clear(); let res = reader.read_line(&mut buffer); assert!(res.is_ok()); assert!(res.unwrap()); assert_eq!(b"\x64\x00", &buffer[..]); buffer.clear(); let res = reader.read_line(&mut buffer); assert!(res.is_ok()); assert!(!res.unwrap()); assert!(buffer.is_empty()); } bat-0.19.0/src/less.rs000064400000000000000000000046070072674642500126230ustar 00000000000000#![cfg(feature = "paging")] use std::ffi::OsStr; use std::process::Command; pub fn retrieve_less_version(less_path: &dyn AsRef) -> Option { let resolved_path = grep_cli::resolve_binary(less_path.as_ref()).ok()?; let cmd = Command::new(resolved_path).arg("--version").output().ok()?; parse_less_version(&cmd.stdout) } fn parse_less_version(output: &[u8]) -> Option { if !output.starts_with(b"less ") { return None; } let version = std::str::from_utf8(&output[5..]).ok()?; let end = version.find(|c: char| !c.is_ascii_digit())?; version[..end].parse::().ok() } #[test] fn test_parse_less_version_487() { let output = b"less 487 (GNU regular expressions) Copyright (C) 1984-2016 Mark Nudelman less comes with NO WARRANTY, to the extent permitted by law. For information about the terms of redistribution, see the file named README in the less distribution. Homepage: http://www.greenwoodsoftware.com/less"; assert_eq!(Some(487), parse_less_version(output)); } #[test] fn test_parse_less_version_529() { let output = b"less 529 (Spencer V8 regular expressions) Copyright (C) 1984-2017 Mark Nudelman less comes with NO WARRANTY, to the extent permitted by law. For information about the terms of redistribution, see the file named README in the less distribution. Homepage: http://www.greenwoodsoftware.com/less"; assert_eq!(Some(529), parse_less_version(output)); } #[test] fn test_parse_less_version_551() { let output = b"less 551 (PCRE regular expressions) Copyright (C) 1984-2019 Mark Nudelman less comes with NO WARRANTY, to the extent permitted by law. For information about the terms of redistribution, see the file named README in the less distribution. Home page: http://www.greenwoodsoftware.com/less"; assert_eq!(Some(551), parse_less_version(output)); } #[test] fn test_parse_less_version_581_2() { let output = b"less 581.2 (PCRE2 regular expressions) Copyright (C) 1984-2021 Mark Nudelman less comes with NO WARRANTY, to the extent permitted by law. For information about the terms of redistribution, see the file named README in the less distribution. Home page: https://greenwoodsoftware.com/less"; assert_eq!(Some(581), parse_less_version(output)); } #[test] fn test_parse_less_version_wrong_program() { let output = b"more from util-linux 2.34"; assert_eq!(None, parse_less_version(output)); } bat-0.19.0/src/lib.rs000064400000000000000000000026020072674642500124140ustar 00000000000000//! `bat` is a library to print syntax highlighted content. //! //! The main struct of this crate is `PrettyPrinter` which can be used to //! configure and run the syntax highlighting. //! //! If you need more control, you can also use the structs in the submodules //! (start with `controller::Controller`), but note that the API of these //! internal modules is much more likely to change. Some or all of these //! modules might be removed in the future. //! //! "Hello world" example: //! ``` //! use bat::PrettyPrinter; //! //! PrettyPrinter::new() //! .input_from_bytes(b"Hello world!\n") //! .language("html") //! .print() //! .unwrap(); //! ``` #![deny(unsafe_code)] mod macros; pub mod assets; pub mod assets_metadata { pub use super::assets::assets_metadata::*; } pub mod config; pub mod controller; mod decorations; mod diff; pub mod error; pub mod input; mod less; pub mod line_range; mod output; #[cfg(feature = "paging")] mod pager; #[cfg(feature = "paging")] pub(crate) mod paging; mod preprocessor; mod pretty_printer; pub(crate) mod printer; pub mod style; pub(crate) mod syntax_mapping; mod terminal; mod vscreen; pub(crate) mod wrapping; pub use pretty_printer::{Input, PrettyPrinter}; pub use syntax_mapping::{MappingTarget, SyntaxMapping}; pub use wrapping::WrappingMode; #[cfg(feature = "paging")] pub use paging::PagingMode; bat-0.19.0/src/line_range.rs000064400000000000000000000205540072674642500137570ustar 00000000000000use crate::error::*; #[derive(Debug, Clone)] pub struct LineRange { lower: usize, upper: usize, } impl Default for LineRange { fn default() -> LineRange { LineRange { lower: usize::min_value(), upper: usize::max_value(), } } } impl LineRange { pub fn new(from: usize, to: usize) -> Self { LineRange { lower: from, upper: to, } } pub fn from(range_raw: &str) -> Result { LineRange::parse_range(range_raw) } fn parse_range(range_raw: &str) -> Result { let mut new_range = LineRange::default(); if range_raw.bytes().next().ok_or("Empty line range")? == b':' { new_range.upper = range_raw[1..].parse()?; return Ok(new_range); } else if range_raw.bytes().last().ok_or("Empty line range")? == b':' { new_range.lower = range_raw[..range_raw.len() - 1].parse()?; return Ok(new_range); } let line_numbers: Vec<&str> = range_raw.split(':').collect(); match line_numbers.len() { 1 => { new_range.lower = line_numbers[0].parse()?; new_range.upper = new_range.lower; Ok(new_range) } 2 => { new_range.lower = line_numbers[0].parse()?; let first_byte = line_numbers[1].bytes().next(); new_range.upper = if first_byte == Some(b'+') { let more_lines = &line_numbers[1][1..] .parse() .map_err(|_| "Invalid character after +")?; new_range.lower + more_lines } else if first_byte == Some(b'-') { // this will prevent values like "-+5" even though "+5" is valid integer if line_numbers[1][1..].bytes().next() == Some(b'+') { return Err("Invalid character after -".into()); } let prior_lines = &line_numbers[1][1..] .parse() .map_err(|_| "Invalid character after -")?; let prev_lower = new_range.lower; new_range.lower = new_range.lower.saturating_sub(*prior_lines); prev_lower } else { line_numbers[1].parse()? }; Ok(new_range) } _ => Err( "Line range contained more than one ':' character. Expected format: 'N' or 'N:M'" .into(), ), } } pub(crate) fn is_inside(&self, line: usize) -> bool { line >= self.lower && line <= self.upper } } #[test] fn test_parse_full() { let range = LineRange::from("40:50").expect("Shouldn't fail on test!"); assert_eq!(40, range.lower); assert_eq!(50, range.upper); } #[test] fn test_parse_partial_min() { let range = LineRange::from(":50").expect("Shouldn't fail on test!"); assert_eq!(usize::min_value(), range.lower); assert_eq!(50, range.upper); } #[test] fn test_parse_partial_max() { let range = LineRange::from("40:").expect("Shouldn't fail on test!"); assert_eq!(40, range.lower); assert_eq!(usize::max_value(), range.upper); } #[test] fn test_parse_single() { let range = LineRange::from("40").expect("Shouldn't fail on test!"); assert_eq!(40, range.lower); assert_eq!(40, range.upper); } #[test] fn test_parse_fail() { let range = LineRange::from("40:50:80"); assert!(range.is_err()); let range = LineRange::from("40::80"); assert!(range.is_err()); let range = LineRange::from(":40:"); assert!(range.is_err()); } #[test] fn test_parse_plus() { let range = LineRange::from("40:+10").expect("Shouldn't fail on test!"); assert_eq!(40, range.lower); assert_eq!(50, range.upper); } #[test] fn test_parse_plus_fail() { let range = LineRange::from("40:+z"); assert!(range.is_err()); let range = LineRange::from("40:+-10"); assert!(range.is_err()); let range = LineRange::from("40:+"); assert!(range.is_err()); } #[test] fn test_parse_minus_success() { let range = LineRange::from("40:-10").expect("Shouldn't fail on test!"); assert_eq!(30, range.lower); assert_eq!(40, range.upper); } #[test] fn test_parse_minus_edge_cases_success() { let range = LineRange::from("5:-4").expect("Shouldn't fail on test!"); assert_eq!(1, range.lower); assert_eq!(5, range.upper); let range = LineRange::from("5:-5").expect("Shouldn't fail on test!"); assert_eq!(0, range.lower); assert_eq!(5, range.upper); let range = LineRange::from("5:-100").expect("Shouldn't fail on test!"); assert_eq!(0, range.lower); assert_eq!(5, range.upper); } #[test] fn test_parse_minus_fail() { let range = LineRange::from("40:-z"); assert!(range.is_err()); let range = LineRange::from("40:-+10"); assert!(range.is_err()); let range = LineRange::from("40:-"); assert!(range.is_err()); } #[derive(Copy, Clone, Debug, PartialEq)] pub enum RangeCheckResult { // Within one of the given ranges InRange, // Before the first range or within two ranges BeforeOrBetweenRanges, // Line number is outside of all ranges and larger than the last range. AfterLastRange, } #[derive(Debug, Clone)] pub struct LineRanges { ranges: Vec, largest_upper_bound: usize, } impl LineRanges { pub fn none() -> LineRanges { LineRanges::from(vec![]) } pub fn all() -> LineRanges { LineRanges::from(vec![LineRange::default()]) } pub fn from(ranges: Vec) -> LineRanges { let largest_upper_bound = ranges .iter() .map(|r| r.upper) .max() .unwrap_or(usize::max_value()); LineRanges { ranges, largest_upper_bound, } } pub(crate) fn check(&self, line: usize) -> RangeCheckResult { if self.ranges.iter().any(|r| r.is_inside(line)) { RangeCheckResult::InRange } else if line < self.largest_upper_bound { RangeCheckResult::BeforeOrBetweenRanges } else { RangeCheckResult::AfterLastRange } } } impl Default for LineRanges { fn default() -> Self { Self::all() } } #[derive(Debug, Clone)] pub struct HighlightedLineRanges(pub LineRanges); impl Default for HighlightedLineRanges { fn default() -> Self { HighlightedLineRanges(LineRanges::none()) } } #[cfg(test)] fn ranges(rs: &[&str]) -> LineRanges { LineRanges::from(rs.iter().map(|r| LineRange::from(r).unwrap()).collect()) } #[test] fn test_ranges_simple() { let ranges = ranges(&["3:8"]); assert_eq!(RangeCheckResult::BeforeOrBetweenRanges, ranges.check(2)); assert_eq!(RangeCheckResult::InRange, ranges.check(5)); assert_eq!(RangeCheckResult::AfterLastRange, ranges.check(9)); } #[test] fn test_ranges_advanced() { let ranges = ranges(&["3:8", "11:20", "25:30"]); assert_eq!(RangeCheckResult::BeforeOrBetweenRanges, ranges.check(2)); assert_eq!(RangeCheckResult::InRange, ranges.check(5)); assert_eq!(RangeCheckResult::BeforeOrBetweenRanges, ranges.check(9)); assert_eq!(RangeCheckResult::InRange, ranges.check(11)); assert_eq!(RangeCheckResult::BeforeOrBetweenRanges, ranges.check(22)); assert_eq!(RangeCheckResult::InRange, ranges.check(28)); assert_eq!(RangeCheckResult::AfterLastRange, ranges.check(31)); } #[test] fn test_ranges_open_low() { let ranges = ranges(&["3:8", ":5"]); assert_eq!(RangeCheckResult::InRange, ranges.check(1)); assert_eq!(RangeCheckResult::InRange, ranges.check(3)); assert_eq!(RangeCheckResult::InRange, ranges.check(7)); assert_eq!(RangeCheckResult::AfterLastRange, ranges.check(9)); } #[test] fn test_ranges_open_high() { let ranges = ranges(&["3:", "2:5"]); assert_eq!(RangeCheckResult::BeforeOrBetweenRanges, ranges.check(1)); assert_eq!(RangeCheckResult::InRange, ranges.check(3)); assert_eq!(RangeCheckResult::InRange, ranges.check(5)); assert_eq!(RangeCheckResult::InRange, ranges.check(9)); } #[test] fn test_ranges_all() { let ranges = LineRanges::all(); assert_eq!(RangeCheckResult::InRange, ranges.check(1)); } #[test] fn test_ranges_none() { let ranges = LineRanges::none(); assert_ne!(RangeCheckResult::InRange, ranges.check(1)); } bat-0.19.0/src/macros.rs000064400000000000000000000003020072674642500131250ustar 00000000000000#[macro_export] macro_rules! bat_warning { ($($arg:tt)*) => ({ use ansi_term::Colour::Yellow; eprintln!("{}: {}", Yellow.paint("[bat warning]"), format!($($arg)*)); }) } bat-0.19.0/src/output.rs000064400000000000000000000115710072674642500132130ustar 00000000000000use std::io::{self, Write}; #[cfg(feature = "paging")] use std::process::Child; use crate::error::*; #[cfg(feature = "paging")] use crate::less::retrieve_less_version; #[cfg(feature = "paging")] use crate::paging::PagingMode; #[cfg(feature = "paging")] use crate::wrapping::WrappingMode; #[cfg(feature = "paging")] #[derive(Debug, PartialEq)] enum SingleScreenAction { Quit, Nothing, } #[derive(Debug)] pub enum OutputType { #[cfg(feature = "paging")] Pager(Child), Stdout(io::Stdout), } impl OutputType { #[cfg(feature = "paging")] pub fn from_mode( paging_mode: PagingMode, wrapping_mode: WrappingMode, pager: Option<&str>, ) -> Result { use self::PagingMode::*; Ok(match paging_mode { Always => OutputType::try_pager(SingleScreenAction::Nothing, wrapping_mode, pager)?, QuitIfOneScreen => { OutputType::try_pager(SingleScreenAction::Quit, wrapping_mode, pager)? } _ => OutputType::stdout(), }) } /// Try to launch the pager. Fall back to stdout in case of errors. #[cfg(feature = "paging")] fn try_pager( single_screen_action: SingleScreenAction, wrapping_mode: WrappingMode, pager_from_config: Option<&str>, ) -> Result { use crate::pager::{self, PagerKind, PagerSource}; use std::process::{Command, Stdio}; let pager_opt = pager::get_pager(pager_from_config).map_err(|_| "Could not parse pager command.")?; let pager = match pager_opt { Some(pager) => pager, None => return Ok(OutputType::stdout()), }; if pager.kind == PagerKind::Bat { return Err(Error::InvalidPagerValueBat); } let resolved_path = match grep_cli::resolve_binary(&pager.bin) { Ok(path) => path, Err(_) => { return Ok(OutputType::stdout()); } }; let mut p = Command::new(resolved_path); let args = pager.args; if pager.kind == PagerKind::Less { // less needs to be called with the '-R' option in order to properly interpret the // ANSI color sequences printed by bat. If someone has set PAGER="less -F", we // therefore need to overwrite the arguments and add '-R'. // // We only do this for PAGER (as it is not specific to 'bat'), not for BAT_PAGER // or bats '--pager' command line option. let replace_arguments_to_less = pager.source == PagerSource::EnvVarPager; if args.is_empty() || replace_arguments_to_less { p.arg("--RAW-CONTROL-CHARS"); if single_screen_action == SingleScreenAction::Quit { p.arg("--quit-if-one-screen"); } if wrapping_mode == WrappingMode::NoWrapping(true) { p.arg("--chop-long-lines"); } // Passing '--no-init' fixes a bug with '--quit-if-one-screen' in older // versions of 'less'. Unfortunately, it also breaks mouse-wheel support. // // See: http://www.greenwoodsoftware.com/less/news.530.html // // For newer versions (530 or 558 on Windows), we omit '--no-init' as it // is not needed anymore. match retrieve_less_version(&pager.bin) { None => { p.arg("--no-init"); } Some(version) if (version < 530 || (cfg!(windows) && version < 558)) => { p.arg("--no-init"); } _ => {} } } else { p.args(args); } p.env("LESSCHARSET", "UTF-8"); } else { p.args(args); }; Ok(p.stdin(Stdio::piped()) .spawn() .map(OutputType::Pager) .unwrap_or_else(|_| OutputType::stdout())) } pub(crate) fn stdout() -> Self { OutputType::Stdout(io::stdout()) } #[cfg(feature = "paging")] pub(crate) fn is_pager(&self) -> bool { matches!(self, OutputType::Pager(_)) } #[cfg(not(feature = "paging"))] pub(crate) fn is_pager(&self) -> bool { false } pub fn handle(&mut self) -> Result<&mut dyn Write> { Ok(match *self { #[cfg(feature = "paging")] OutputType::Pager(ref mut command) => command .stdin .as_mut() .ok_or("Could not open stdin for pager")?, OutputType::Stdout(ref mut handle) => handle, }) } } #[cfg(feature = "paging")] impl Drop for OutputType { fn drop(&mut self) { if let OutputType::Pager(ref mut command) = *self { let _ = command.wait(); } } } bat-0.19.0/src/pager.rs000064400000000000000000000065230072674642500127520ustar 00000000000000use shell_words::ParseError; use std::env; /// If we use a pager, this enum tells us from where we were told to use it. #[derive(Debug, PartialEq)] pub(crate) enum PagerSource { /// From --config Config, /// From the env var BAT_PAGER EnvVarBatPager, /// From the env var PAGER EnvVarPager, /// No pager was specified, default is used Default, } /// We know about some pagers, for example 'less'. This is a list of all pagers we know about #[derive(Debug, PartialEq)] pub(crate) enum PagerKind { /// bat Bat, /// less Less, /// more More, /// most Most, /// A pager we don't know about Unknown, } impl PagerKind { fn from_bin(bin: &str) -> PagerKind { use std::path::Path; match Path::new(bin) .file_stem() .map(|s| s.to_string_lossy()) .as_deref() { Some("bat") => PagerKind::Bat, Some("less") => PagerKind::Less, Some("more") => PagerKind::More, Some("most") => PagerKind::Most, _ => PagerKind::Unknown, } } } /// A pager such as 'less', and from where we got it. #[derive(Debug)] pub(crate) struct Pager { /// The pager binary pub bin: String, /// The pager binary arguments (that we might tweak) pub args: Vec, /// What pager this is pub kind: PagerKind, /// From where this pager comes pub source: PagerSource, } impl Pager { fn new(bin: &str, args: &[String], kind: PagerKind, source: PagerSource) -> Pager { Pager { bin: String::from(bin), args: args.to_vec(), kind, source, } } } /// Returns what pager to use, after looking at both config and environment variables. pub(crate) fn get_pager(config_pager: Option<&str>) -> Result, ParseError> { let bat_pager = env::var("BAT_PAGER"); let pager = env::var("PAGER"); let (cmd, source) = match (config_pager, &bat_pager, &pager) { (Some(config_pager), _, _) => (config_pager, PagerSource::Config), (_, Ok(bat_pager), _) => (bat_pager.as_str(), PagerSource::EnvVarBatPager), (_, _, Ok(pager)) => (pager.as_str(), PagerSource::EnvVarPager), _ => ("less", PagerSource::Default), }; let parts = shell_words::split(cmd)?; match parts.split_first() { Some((bin, args)) => { let kind = PagerKind::from_bin(bin); let use_less_instead = if source == PagerSource::EnvVarPager { // 'more' and 'most' do not supports colors; automatically use // 'less' instead if the problematic pager came from the // generic PAGER env var. // If PAGER=bat, silently use 'less' instead to prevent // recursion. // Never silently use 'less' if BAT_PAGER or --pager has been // specified. matches!(kind, PagerKind::More | PagerKind::Most | PagerKind::Bat) } else { false }; Ok(Some(if use_less_instead { let no_args = vec![]; Pager::new("less", &no_args, PagerKind::Less, PagerSource::EnvVarPager) } else { Pager::new(bin, args, kind, source) })) } None => Ok(None), } } bat-0.19.0/src/paging.rs000064400000000000000000000003110072674642500131060ustar 00000000000000#[derive(Debug, Clone, Copy, PartialEq)] pub enum PagingMode { Always, QuitIfOneScreen, Never, } impl Default for PagingMode { fn default() -> Self { PagingMode::Never } } bat-0.19.0/src/preprocessor.rs000064400000000000000000000113470072674642500144020ustar 00000000000000use console::AnsiCodeIterator; /// Expand tabs like an ANSI-enabled expand(1). pub fn expand_tabs(line: &str, width: usize, cursor: &mut usize) -> String { let mut buffer = String::with_capacity(line.len() * 2); for chunk in AnsiCodeIterator::new(line) { match chunk { (text, true) => buffer.push_str(text), (mut text, false) => { while let Some(index) = text.find('\t') { // Add previous text. if index > 0 { *cursor += index; buffer.push_str(&text[0..index]); } // Add tab. let spaces = width - (*cursor % width); *cursor += spaces; buffer.push_str(&*" ".repeat(spaces)); // Next. text = &text[index + 1..text.len()]; } *cursor += text.len(); buffer.push_str(text); } } } buffer } fn try_parse_utf8_char(input: &[u8]) -> Option<(char, usize)> { let str_from_utf8 = |seq| std::str::from_utf8(seq).ok(); let decoded = input .get(0..1) .and_then(str_from_utf8) .map(|c| (c, 1)) .or_else(|| input.get(0..2).and_then(str_from_utf8).map(|c| (c, 2))) .or_else(|| input.get(0..3).and_then(str_from_utf8).map(|c| (c, 3))) .or_else(|| input.get(0..4).and_then(str_from_utf8).map(|c| (c, 4))); decoded.map(|(seq, n)| (seq.chars().next().unwrap(), n)) } pub fn replace_nonprintable(input: &[u8], tab_width: usize) -> String { let mut output = String::new(); let tab_width = if tab_width == 0 { 4 } else { tab_width }; let mut idx = 0; let len = input.len(); while idx < len { if let Some((chr, skip_ahead)) = try_parse_utf8_char(&input[idx..]) { idx += skip_ahead; match chr { // space ' ' => output.push('·'), // tab '\t' => { if tab_width == 1 { output.push('↹'); } else { output.push('├'); output.push_str(&"─".repeat(tab_width - 2)); output.push('┤'); } } // line feed '\x0A' => output.push_str("␊\x0A"), // carriage return '\x0D' => output.push('␍'), // null '\x00' => output.push('␀'), // bell '\x07' => output.push('␇'), // backspace '\x08' => output.push('␈'), // escape '\x1B' => output.push('␛'), // printable ASCII c if c.is_ascii_alphanumeric() || c.is_ascii_punctuation() || c.is_ascii_graphic() => { output.push(c) } // everything else c => output.push_str(&c.escape_unicode().collect::()), } } else { output.push_str(&format!("\\x{:02X}", input[idx])); idx += 1; } } output } #[test] fn test_try_parse_utf8_char() { assert_eq!(try_parse_utf8_char(&[0x20]), Some((' ', 1))); assert_eq!(try_parse_utf8_char(&[0x20, 0x20]), Some((' ', 1))); assert_eq!(try_parse_utf8_char(&[0x20, 0xef]), Some((' ', 1))); assert_eq!(try_parse_utf8_char(&[0x00]), Some(('\x00', 1))); assert_eq!(try_parse_utf8_char(&[0x1b]), Some(('\x1b', 1))); assert_eq!(try_parse_utf8_char(&[0xc3, 0xa4]), Some(('ä', 2))); assert_eq!(try_parse_utf8_char(&[0xc3, 0xa4, 0xef]), Some(('ä', 2))); assert_eq!(try_parse_utf8_char(&[0xc3, 0xa4, 0x20]), Some(('ä', 2))); assert_eq!(try_parse_utf8_char(&[0xe2, 0x82, 0xac]), Some(('€', 3))); assert_eq!( try_parse_utf8_char(&[0xe2, 0x82, 0xac, 0xef]), Some(('€', 3)) ); assert_eq!( try_parse_utf8_char(&[0xe2, 0x82, 0xac, 0x20]), Some(('€', 3)) ); assert_eq!(try_parse_utf8_char(&[0xe2, 0x88, 0xb0]), Some(('∰', 3))); assert_eq!( try_parse_utf8_char(&[0xf0, 0x9f, 0x8c, 0x82]), Some(('🌂', 4)) ); assert_eq!( try_parse_utf8_char(&[0xf0, 0x9f, 0x8c, 0x82, 0xef]), Some(('🌂', 4)) ); assert_eq!( try_parse_utf8_char(&[0xf0, 0x9f, 0x8c, 0x82, 0x20]), Some(('🌂', 4)) ); assert_eq!(try_parse_utf8_char(&[]), None); assert_eq!(try_parse_utf8_char(&[0xef]), None); assert_eq!(try_parse_utf8_char(&[0xef, 0x20]), None); assert_eq!(try_parse_utf8_char(&[0xf0, 0xf0]), None); } bat-0.19.0/src/pretty_printer.rs000064400000000000000000000252000072674642500147370ustar 00000000000000use std::io::Read; use std::path::Path; use console::Term; use syntect::parsing::SyntaxReference; use crate::{ assets::HighlightingAssets, config::{Config, VisibleLines}, controller::Controller, error::Result, input, line_range::{HighlightedLineRanges, LineRange, LineRanges}, style::{StyleComponent, StyleComponents}, SyntaxMapping, WrappingMode, }; #[cfg(feature = "paging")] use crate::paging::PagingMode; #[derive(Default)] struct ActiveStyleComponents { header: bool, vcs_modification_markers: bool, grid: bool, rule: bool, line_numbers: bool, snip: bool, } pub struct PrettyPrinter<'a> { inputs: Vec>, config: Config<'a>, assets: HighlightingAssets, highlighted_lines: Vec, term_width: Option, active_style_components: ActiveStyleComponents, } impl<'a> PrettyPrinter<'a> { pub fn new() -> Self { let config = Config { colored_output: true, true_color: true, ..Default::default() }; PrettyPrinter { inputs: vec![], config, assets: HighlightingAssets::from_binary(), highlighted_lines: vec![], term_width: None, active_style_components: ActiveStyleComponents::default(), } } /// Add an input which should be pretty-printed pub fn input(&mut self, input: Input<'a>) -> &mut Self { self.inputs.push(input); self } /// Adds multiple inputs which should be pretty-printed pub fn inputs(&mut self, inputs: impl IntoIterator>) -> &mut Self { for input in inputs { self.inputs.push(input); } self } /// Add a file which should be pretty-printed pub fn input_file(&mut self, path: impl AsRef) -> &mut Self { self.input(Input::from_file(path).kind("File")) } /// Add multiple files which should be pretty-printed pub fn input_files(&mut self, paths: I) -> &mut Self where I: IntoIterator, P: AsRef, { self.inputs(paths.into_iter().map(Input::from_file)) } /// Add STDIN as an input pub fn input_stdin(&mut self) -> &mut Self { self.inputs.push(Input::from_stdin()); self } /// Add a byte string as an input pub fn input_from_bytes(&mut self, content: &'a [u8]) -> &mut Self { self.input_from_reader(content) } /// Add a custom reader as an input pub fn input_from_reader(&mut self, reader: R) -> &mut Self { self.inputs.push(Input::from_reader(reader)); self } /// Specify the syntax file which should be used (default: auto-detect) pub fn language(&mut self, language: &'a str) -> &mut Self { self.config.language = Some(language); self } /// The character width of the terminal (default: autodetect) pub fn term_width(&mut self, width: usize) -> &mut Self { self.term_width = Some(width); self } /// The width of tab characters (default: None - do not turn tabs to spaces) pub fn tab_width(&mut self, tab_width: Option) -> &mut Self { self.config.tab_width = tab_width.unwrap_or(0); self } /// Whether or not the output should be colorized (default: true) pub fn colored_output(&mut self, yes: bool) -> &mut Self { self.config.colored_output = yes; self } /// Whether or not to output 24bit colors (default: true) pub fn true_color(&mut self, yes: bool) -> &mut Self { self.config.true_color = yes; self } /// Whether to show a header with the file name pub fn header(&mut self, yes: bool) -> &mut Self { self.active_style_components.header = yes; self } /// Whether to show line numbers pub fn line_numbers(&mut self, yes: bool) -> &mut Self { self.active_style_components.line_numbers = yes; self } /// Whether to paint a grid, separating line numbers, git changes and the code pub fn grid(&mut self, yes: bool) -> &mut Self { self.active_style_components.grid = yes; self } /// Whether to paint a horizontal rule to delimit files pub fn rule(&mut self, yes: bool) -> &mut Self { self.active_style_components.rule = yes; self } /// Whether to show modification markers for VCS changes. This has no effect if /// the `git` feature is not activated. #[cfg(feature = "git")] pub fn vcs_modification_markers(&mut self, yes: bool) -> &mut Self { self.active_style_components.vcs_modification_markers = yes; self } /// Whether to show "snip" markers between visible line ranges (default: no) pub fn snip(&mut self, yes: bool) -> &mut Self { self.active_style_components.snip = yes; self } /// Text wrapping mode (default: do not wrap) pub fn wrapping_mode(&mut self, mode: WrappingMode) -> &mut Self { self.config.wrapping_mode = mode; self } /// Whether or not to use ANSI italics (default: off) pub fn use_italics(&mut self, yes: bool) -> &mut Self { self.config.use_italic_text = yes; self } /// If and how to use a pager (default: no paging) #[cfg(feature = "paging")] pub fn paging_mode(&mut self, mode: PagingMode) -> &mut Self { self.config.paging_mode = mode; self } /// Specify the command to start the pager (default: use "less") #[cfg(feature = "paging")] pub fn pager(&mut self, cmd: &'a str) -> &mut Self { self.config.pager = Some(cmd); self } /// Specify the lines that should be printed (default: all) pub fn line_ranges(&mut self, ranges: LineRanges) -> &mut Self { self.config.visible_lines = VisibleLines::Ranges(ranges); self } /// Specify a line that should be highlighted (default: none). /// This can be called multiple times to highlight more than one /// line. See also: highlight_range. pub fn highlight(&mut self, line: usize) -> &mut Self { self.highlighted_lines.push(LineRange::new(line, line)); self } /// Specify a range of lines that should be highlighted (default: none). /// This can be called multiple times to highlight more than one range /// of lines. pub fn highlight_range(&mut self, from: usize, to: usize) -> &mut Self { self.highlighted_lines.push(LineRange::new(from, to)); self } /// Specify the highlighting theme pub fn theme(&mut self, theme: impl AsRef) -> &mut Self { self.config.theme = theme.as_ref().to_owned(); self } /// Specify custom file extension / file name to syntax mappings pub fn syntax_mapping(&mut self, mapping: SyntaxMapping<'a>) -> &mut Self { self.config.syntax_mapping = mapping; self } pub fn themes(&self) -> impl Iterator { self.assets.themes() } pub fn syntaxes(&self) -> impl Iterator { // We always use assets from the binary, which are guaranteed to always // be valid, so get_syntaxes() can never fail here self.assets.get_syntaxes().unwrap().iter() } /// Pretty-print all specified inputs. This method will "use" all stored inputs. /// If you want to call 'print' multiple times, you have to call the appropriate /// input_* methods again. pub fn print(&mut self) -> Result { self.config.highlighted_lines = HighlightedLineRanges(LineRanges::from(self.highlighted_lines.clone())); self.config.term_width = self .term_width .unwrap_or_else(|| Term::stdout().size().1 as usize); let mut style_components = vec![]; if self.active_style_components.grid { style_components.push(StyleComponent::Grid); } if self.active_style_components.rule { style_components.push(StyleComponent::Rule); } if self.active_style_components.header { style_components.push(StyleComponent::Header); } if self.active_style_components.line_numbers { style_components.push(StyleComponent::LineNumbers); } if self.active_style_components.snip { style_components.push(StyleComponent::Snip); } if self.active_style_components.vcs_modification_markers { #[cfg(feature = "git")] style_components.push(StyleComponent::Changes); } self.config.style_components = StyleComponents::new(&style_components); // Collect the inputs to print let mut inputs: Vec = vec![]; std::mem::swap(&mut inputs, &mut self.inputs); // Run the controller let controller = Controller::new(&self.config, &self.assets); controller.run(inputs.into_iter().map(|i| i.into()).collect()) } } impl Default for PrettyPrinter<'_> { fn default() -> Self { Self::new() } } /// An input source for the pretty printer. pub struct Input<'a> { input: input::Input<'a>, } impl<'a> Input<'a> { /// A new input from a reader. pub fn from_reader(reader: R) -> Self { input::Input::from_reader(Box::new(reader)).into() } /// A new input from a file. pub fn from_file(path: impl AsRef) -> Self { input::Input::ordinary_file(path).into() } /// A new input from bytes. pub fn from_bytes(bytes: &'a [u8]) -> Self { Input::from_reader(bytes) } /// A new input from STDIN. pub fn from_stdin() -> Self { input::Input::stdin().into() } /// The filename of the input. /// This affects syntax detection and changes the default header title. pub fn name(mut self, name: impl AsRef) -> Self { self.input = self.input.with_name(Some(name)); self } /// The description for the type of input (e.g. "File") pub fn kind(mut self, kind: impl Into) -> Self { let kind = kind.into(); self.input .description_mut() .set_kind(if kind.is_empty() { None } else { Some(kind) }); self } /// The title for the input (e.g. "Descriptive title") /// This defaults to the file name. pub fn title(mut self, title: impl Into) -> Self { self.input.description_mut().set_title(Some(title.into())); self } } impl<'a> From> for Input<'a> { fn from(input: input::Input<'a>) -> Self { Self { input } } } impl<'a> From> for input::Input<'a> { fn from(Input { input }: Input<'a>) -> Self { input } } bat-0.19.0/src/printer.rs000064400000000000000000000551450072674642500133430ustar 00000000000000use std::io::Write; use std::vec::Vec; use ansi_term::Colour::{Fixed, Green, Red, Yellow}; use ansi_term::Style; use console::AnsiCodeIterator; use syntect::easy::HighlightLines; use syntect::highlighting::Color; use syntect::highlighting::Theme; use syntect::parsing::SyntaxSet; use content_inspector::ContentType; use encoding::all::{UTF_16BE, UTF_16LE}; use encoding::{DecoderTrap, Encoding}; use unicode_width::UnicodeWidthChar; use crate::assets::{HighlightingAssets, SyntaxReferenceInSet}; use crate::config::Config; #[cfg(feature = "git")] use crate::decorations::LineChangesDecoration; use crate::decorations::{Decoration, GridBorderDecoration, LineNumberDecoration}; #[cfg(feature = "git")] use crate::diff::LineChanges; use crate::error::*; use crate::input::OpenedInput; use crate::line_range::RangeCheckResult; use crate::preprocessor::{expand_tabs, replace_nonprintable}; use crate::terminal::{as_terminal_escaped, to_ansi_color}; use crate::vscreen::AnsiStyle; use crate::wrapping::WrappingMode; pub(crate) trait Printer { fn print_header( &mut self, handle: &mut dyn Write, input: &OpenedInput, add_header_padding: bool, ) -> Result<()>; fn print_footer(&mut self, handle: &mut dyn Write, input: &OpenedInput) -> Result<()>; fn print_snip(&mut self, handle: &mut dyn Write) -> Result<()>; fn print_line( &mut self, out_of_range: bool, handle: &mut dyn Write, line_number: usize, line_buffer: &[u8], ) -> Result<()>; } pub struct SimplePrinter<'a> { config: &'a Config<'a>, } impl<'a> SimplePrinter<'a> { pub fn new(config: &'a Config) -> Self { SimplePrinter { config } } } impl<'a> Printer for SimplePrinter<'a> { fn print_header( &mut self, _handle: &mut dyn Write, _input: &OpenedInput, _add_header_padding: bool, ) -> Result<()> { Ok(()) } fn print_footer(&mut self, _handle: &mut dyn Write, _input: &OpenedInput) -> Result<()> { Ok(()) } fn print_snip(&mut self, _handle: &mut dyn Write) -> Result<()> { Ok(()) } fn print_line( &mut self, out_of_range: bool, handle: &mut dyn Write, _line_number: usize, line_buffer: &[u8], ) -> Result<()> { if !out_of_range { if self.config.show_nonprintable { let line = replace_nonprintable(line_buffer, self.config.tab_width); write!(handle, "{}", line)?; } else { handle.write_all(line_buffer)? }; } Ok(()) } } struct HighlighterFromSet<'a> { highlighter: HighlightLines<'a>, syntax_set: &'a SyntaxSet, } impl<'a> HighlighterFromSet<'a> { fn new(syntax_in_set: SyntaxReferenceInSet<'a>, theme: &'a Theme) -> Self { Self { highlighter: HighlightLines::new(syntax_in_set.syntax, theme), syntax_set: syntax_in_set.syntax_set, } } } pub(crate) struct InteractivePrinter<'a> { colors: Colors, config: &'a Config<'a>, decorations: Vec>, panel_width: usize, ansi_style: AnsiStyle, content_type: Option, #[cfg(feature = "git")] pub line_changes: &'a Option, highlighter_from_set: Option>, background_color_highlight: Option, } impl<'a> InteractivePrinter<'a> { pub(crate) fn new( config: &'a Config, assets: &'a HighlightingAssets, input: &mut OpenedInput, #[cfg(feature = "git")] line_changes: &'a Option, ) -> Result { let theme = assets.get_theme(&config.theme); let background_color_highlight = theme.settings.line_highlight; let colors = if config.colored_output { Colors::colored(theme, config.true_color) } else { Colors::plain() }; // Create decorations. let mut decorations: Vec> = Vec::new(); if config.style_components.numbers() { decorations.push(Box::new(LineNumberDecoration::new(&colors))); } #[cfg(feature = "git")] { if config.style_components.changes() { decorations.push(Box::new(LineChangesDecoration::new(&colors))); } } let mut panel_width: usize = decorations.len() + decorations.iter().fold(0, |a, x| a + x.width()); // The grid border decoration isn't added until after the panel_width calculation, since the // print_horizontal_line, print_header, and print_footer functions all assume the panel // width is without the grid border. if config.style_components.grid() && !decorations.is_empty() { decorations.push(Box::new(GridBorderDecoration::new(&colors))); } // Disable the panel if the terminal is too small (i.e. can't fit 5 characters with the // panel showing). if config.term_width < (decorations.len() + decorations.iter().fold(0, |a, x| a + x.width())) + 5 { decorations.clear(); panel_width = 0; } let highlighter_from_set = if input .reader .content_type .map_or(false, |c| c.is_binary() && !config.show_nonprintable) { None } else { // Determine the type of syntax for highlighting let syntax_in_set = match assets.get_syntax(config.language, input, &config.syntax_mapping) { Ok(syntax_in_set) => syntax_in_set, Err(Error::UndetectedSyntax(_)) => assets .find_syntax_by_name("Plain Text")? .expect("A plain text syntax is available"), Err(e) => return Err(e), }; Some(HighlighterFromSet::new(syntax_in_set, theme)) }; Ok(InteractivePrinter { panel_width, colors, config, decorations, content_type: input.reader.content_type, ansi_style: AnsiStyle::new(), #[cfg(feature = "git")] line_changes, highlighter_from_set, background_color_highlight, }) } fn print_horizontal_line_term(&mut self, handle: &mut dyn Write, style: Style) -> Result<()> { writeln!( handle, "{}", style.paint("─".repeat(self.config.term_width)) )?; Ok(()) } fn print_horizontal_line(&mut self, handle: &mut dyn Write, grid_char: char) -> Result<()> { if self.panel_width == 0 { self.print_horizontal_line_term(handle, self.colors.grid)?; } else { let hline = "─".repeat(self.config.term_width - (self.panel_width + 1)); let hline = format!("{}{}{}", "─".repeat(self.panel_width), grid_char, hline); writeln!(handle, "{}", self.colors.grid.paint(hline))?; } Ok(()) } fn create_fake_panel(&self, text: &str) -> String { if self.panel_width == 0 { return "".to_string(); } let text_truncated: String = text.chars().take(self.panel_width - 1).collect(); let text_filled: String = format!( "{}{}", text_truncated, " ".repeat(self.panel_width - 1 - text_truncated.len()) ); if self.config.style_components.grid() { format!("{} │ ", text_filled) } else { text_filled } } fn preprocess(&self, text: &str, cursor: &mut usize) -> String { if self.config.tab_width > 0 { return expand_tabs(text, self.config.tab_width, cursor); } *cursor += text.len(); text.to_string() } } impl<'a> Printer for InteractivePrinter<'a> { fn print_header( &mut self, handle: &mut dyn Write, input: &OpenedInput, add_header_padding: bool, ) -> Result<()> { if add_header_padding && self.config.style_components.rule() { self.print_horizontal_line_term(handle, self.colors.rule)?; } if !self.config.style_components.header() { if Some(ContentType::BINARY) == self.content_type && !self.config.show_nonprintable { writeln!( handle, "{}: Binary content from {} will not be printed to the terminal \ (but will be present if the output of 'bat' is piped). You can use 'bat -A' \ to show the binary file contents.", Yellow.paint("[bat warning]"), input.description.summary(), )?; } else if self.config.style_components.grid() { self.print_horizontal_line(handle, '┬')?; } return Ok(()); } if self.config.style_components.grid() { self.print_horizontal_line(handle, '┬')?; write!( handle, "{}{}", " ".repeat(self.panel_width), self.colors .grid .paint(if self.panel_width > 0 { "│ " } else { "" }), )?; } else { // Only pad space between files, if we haven't already drawn a horizontal rule if add_header_padding && !self.config.style_components.rule() { writeln!(handle)?; } write!(handle, "{}", " ".repeat(self.panel_width))?; } let mode = match self.content_type { Some(ContentType::BINARY) => " ", Some(ContentType::UTF_16LE) => " ", Some(ContentType::UTF_16BE) => " ", None => " ", _ => "", }; let description = &input.description; writeln!( handle, "{}{}{}", description .kind() .map(|kind| format!("{}: ", kind)) .unwrap_or_else(|| "".into()), self.colors.filename.paint(description.title()), mode )?; if self.config.style_components.grid() { if self.content_type.map_or(false, |c| c.is_text()) || self.config.show_nonprintable { self.print_horizontal_line(handle, '┼')?; } else { self.print_horizontal_line(handle, '┴')?; } } Ok(()) } fn print_footer(&mut self, handle: &mut dyn Write, _input: &OpenedInput) -> Result<()> { if self.config.style_components.grid() && (self.content_type.map_or(false, |c| c.is_text()) || self.config.show_nonprintable) { self.print_horizontal_line(handle, '┴') } else { Ok(()) } } fn print_snip(&mut self, handle: &mut dyn Write) -> Result<()> { let panel = self.create_fake_panel(" ..."); let panel_count = panel.chars().count(); let title = "8<"; let title_count = title.chars().count(); let snip_left = "─ ".repeat((self.config.term_width - panel_count - (title_count / 2)) / 4); let snip_left_count = snip_left.chars().count(); // Can't use .len() with Unicode. let snip_right = " ─".repeat((self.config.term_width - panel_count - snip_left_count - title_count) / 2); writeln!( handle, "{}", self.colors .grid .paint(format!("{}{}{}{}", panel, snip_left, title, snip_right)) )?; Ok(()) } fn print_line( &mut self, out_of_range: bool, handle: &mut dyn Write, line_number: usize, line_buffer: &[u8], ) -> Result<()> { let line = if self.config.show_nonprintable { replace_nonprintable(line_buffer, self.config.tab_width) } else { match self.content_type { Some(ContentType::BINARY) | None => { return Ok(()); } Some(ContentType::UTF_16LE) => UTF_16LE .decode(line_buffer, DecoderTrap::Replace) .map_err(|_| "Invalid UTF-16LE")?, Some(ContentType::UTF_16BE) => UTF_16BE .decode(line_buffer, DecoderTrap::Replace) .map_err(|_| "Invalid UTF-16BE")?, _ => String::from_utf8_lossy(line_buffer).to_string(), } }; let regions = { let highlighter_from_set = match self.highlighter_from_set { Some(ref mut highlighter_from_set) => highlighter_from_set, _ => { return Ok(()); } }; highlighter_from_set .highlighter .highlight(&line, highlighter_from_set.syntax_set) }; if out_of_range { return Ok(()); } let mut cursor: usize = 0; let mut cursor_max: usize = self.config.term_width; let mut cursor_total: usize = 0; let mut panel_wrap: Option = None; // Line highlighting let highlight_this_line = self.config.highlighted_lines.0.check(line_number) == RangeCheckResult::InRange; let background_color = self .background_color_highlight .filter(|_| highlight_this_line); // Line decorations. if self.panel_width > 0 { let decorations = self .decorations .iter() .map(|d| d.generate(line_number, false, self)); for deco in decorations { write!(handle, "{} ", deco.text)?; cursor_max -= deco.width + 1; } } // Line contents. if matches!(self.config.wrapping_mode, WrappingMode::NoWrapping(_)) { let true_color = self.config.true_color; let colored_output = self.config.colored_output; let italics = self.config.use_italic_text; for &(style, region) in ®ions { let ansi_iterator = AnsiCodeIterator::new(region); for chunk in ansi_iterator { match chunk { // ANSI escape passthrough. (ansi, true) => { self.ansi_style.update(ansi); write!(handle, "{}", ansi)?; } // Regular text. (text, false) => { let text = &*self.preprocess(text, &mut cursor_total); let text_trimmed = text.trim_end_matches(|c| c == '\r' || c == '\n'); write!( handle, "{}", as_terminal_escaped( style, &format!("{}{}", self.ansi_style, text_trimmed), true_color, colored_output, italics, background_color ) )?; if text.len() != text_trimmed.len() { if let Some(background_color) = background_color { let ansi_style = Style { background: to_ansi_color(background_color, true_color), ..Default::default() }; let width = if cursor_total <= cursor_max { cursor_max - cursor_total + 1 } else { 0 }; write!(handle, "{}", ansi_style.paint(" ".repeat(width)))?; } write!(handle, "{}", &text[text_trimmed.len()..])?; } } } } } if !self.config.style_components.plain() && line.bytes().next_back() != Some(b'\n') { writeln!(handle)?; } } else { for &(style, region) in ®ions { let ansi_iterator = AnsiCodeIterator::new(region); for chunk in ansi_iterator { match chunk { // ANSI escape passthrough. (ansi, true) => { self.ansi_style.update(ansi); write!(handle, "{}", ansi)?; } // Regular text. (text, false) => { let text = self.preprocess( text.trim_end_matches(|c| c == '\r' || c == '\n'), &mut cursor_total, ); let mut max_width = cursor_max - cursor; // line buffer (avoid calling write! for every character) let mut line_buf = String::with_capacity(max_width * 4); // Displayed width of line_buf let mut current_width = 0; for c in text.chars() { // calculate the displayed width for next character let cw = c.width().unwrap_or(0); current_width += cw; // if next character cannot be printed on this line, // flush the buffer. if current_width > max_width { // Generate wrap padding if not already generated. if panel_wrap.is_none() { panel_wrap = if self.panel_width > 0 { Some(format!( "{} ", self.decorations .iter() .map(|d| d .generate(line_number, true, self) .text) .collect::>() .join(" ") )) } else { Some("".to_string()) } } // It wraps. write!( handle, "{}\n{}", as_terminal_escaped( style, &*format!("{}{}", self.ansi_style, line_buf), self.config.true_color, self.config.colored_output, self.config.use_italic_text, background_color ), panel_wrap.clone().unwrap() )?; cursor = 0; max_width = cursor_max; line_buf.clear(); current_width = cw; } line_buf.push(c); } // flush the buffer cursor += current_width; write!( handle, "{}", as_terminal_escaped( style, &*format!("{}{}", self.ansi_style, line_buf), self.config.true_color, self.config.colored_output, self.config.use_italic_text, background_color ) )?; } } } } if let Some(background_color) = background_color { let ansi_style = Style { background: to_ansi_color(background_color, self.config.true_color), ..Default::default() }; write!( handle, "{}", ansi_style.paint(" ".repeat(cursor_max - cursor)) )?; } writeln!(handle)?; } Ok(()) } } const DEFAULT_GUTTER_COLOR: u8 = 238; #[derive(Debug, Default)] pub struct Colors { pub grid: Style, pub rule: Style, pub filename: Style, pub git_added: Style, pub git_removed: Style, pub git_modified: Style, pub line_number: Style, } impl Colors { fn plain() -> Self { Colors::default() } fn colored(theme: &Theme, true_color: bool) -> Self { let gutter_style = Style { foreground: match theme.settings.gutter_foreground { // If the theme provides a gutter foreground color, use it. // Note: It might be the special value #00000001, in which case // to_ansi_color returns None and we use an empty Style // (resulting in the terminal's default foreground color). Some(c) => to_ansi_color(c, true_color), // Otherwise, use a specific fallback color. None => Some(Fixed(DEFAULT_GUTTER_COLOR)), }, ..Style::default() }; Colors { grid: gutter_style, rule: gutter_style, filename: Style::new().bold(), git_added: Green.normal(), git_removed: Red.normal(), git_modified: Yellow.normal(), line_number: gutter_style, } } } bat-0.19.0/src/style.rs000064400000000000000000000060320072674642500130070ustar 00000000000000use std::collections::HashSet; use std::str::FromStr; use crate::error::*; #[derive(Debug, Eq, PartialEq, Copy, Clone, Hash)] pub enum StyleComponent { Auto, #[cfg(feature = "git")] Changes, Grid, Rule, Header, LineNumbers, Snip, Full, Plain, } impl StyleComponent { pub fn components(self, interactive_terminal: bool) -> &'static [StyleComponent] { match self { StyleComponent::Auto => { if interactive_terminal { StyleComponent::Full.components(interactive_terminal) } else { StyleComponent::Plain.components(interactive_terminal) } } #[cfg(feature = "git")] StyleComponent::Changes => &[StyleComponent::Changes], StyleComponent::Grid => &[StyleComponent::Grid], StyleComponent::Rule => &[StyleComponent::Rule], StyleComponent::Header => &[StyleComponent::Header], StyleComponent::LineNumbers => &[StyleComponent::LineNumbers], StyleComponent::Snip => &[StyleComponent::Snip], StyleComponent::Full => &[ #[cfg(feature = "git")] StyleComponent::Changes, StyleComponent::Grid, StyleComponent::Header, StyleComponent::LineNumbers, StyleComponent::Snip, ], StyleComponent::Plain => &[], } } } impl FromStr for StyleComponent { type Err = Error; fn from_str(s: &str) -> Result { match s { "auto" => Ok(StyleComponent::Auto), #[cfg(feature = "git")] "changes" => Ok(StyleComponent::Changes), "grid" => Ok(StyleComponent::Grid), "rule" => Ok(StyleComponent::Rule), "header" => Ok(StyleComponent::Header), "numbers" => Ok(StyleComponent::LineNumbers), "snip" => Ok(StyleComponent::Snip), "full" => Ok(StyleComponent::Full), "plain" => Ok(StyleComponent::Plain), _ => Err(format!("Unknown style '{}'", s).into()), } } } #[derive(Debug, Clone, Default)] pub struct StyleComponents(pub HashSet); impl StyleComponents { pub fn new(components: &[StyleComponent]) -> StyleComponents { StyleComponents(components.iter().cloned().collect()) } #[cfg(feature = "git")] pub fn changes(&self) -> bool { self.0.contains(&StyleComponent::Changes) } pub fn grid(&self) -> bool { self.0.contains(&StyleComponent::Grid) } pub fn rule(&self) -> bool { self.0.contains(&StyleComponent::Rule) } pub fn header(&self) -> bool { self.0.contains(&StyleComponent::Header) } pub fn numbers(&self) -> bool { self.0.contains(&StyleComponent::LineNumbers) } pub fn snip(&self) -> bool { self.0.contains(&StyleComponent::Snip) } pub fn plain(&self) -> bool { self.0.iter().all(|c| c == &StyleComponent::Plain) } } bat-0.19.0/src/syntax_mapping/ignored_suffixes.rs000064400000000000000000000062130072674642500202540ustar 00000000000000use std::ffi::OsStr; use std::fmt::Debug; use std::path::Path; use crate::error::*; #[derive(Debug, Clone)] pub struct IgnoredSuffixes<'a> { values: Vec<&'a str>, } impl Default for IgnoredSuffixes<'_> { fn default() -> Self { Self { values: vec![ // Editor etc backups "~", ".bak", ".old", ".orig", // Debian and derivatives apt/dpkg/ucf backups ".dpkg-dist", ".dpkg-old", ".ucf-dist", ".ucf-new", ".ucf-old", // Red Hat and derivatives rpm backups ".rpmnew", ".rpmorig", ".rpmsave", // Build system input/template files ".in", ], } } } impl<'a> IgnoredSuffixes<'a> { pub fn add_suffix(&mut self, suffix: &'a str) { self.values.push(suffix) } pub fn strip_suffix(&self, file_name: &'a str) -> Option<&'a str> { for suffix in self.values.iter() { if let Some(stripped_file_name) = file_name.strip_suffix(suffix) { return Some(stripped_file_name); } } None } /// If we find an ignored suffix on the file name, e.g. '~', we strip it and /// then try again without it. pub fn try_with_stripped_suffix(&self, file_name: &'a OsStr, func: F) -> Result> where F: Fn(&'a OsStr) -> Result>, { if let Some(file_str) = Path::new(file_name).to_str() { if let Some(stripped_file_name) = self.strip_suffix(file_str) { return func(OsStr::new(stripped_file_name)); } } Ok(None) } } #[test] fn internal_suffixes() { let ignored_suffixes = IgnoredSuffixes::default(); let file_names = ignored_suffixes .values .iter() .map(|suffix| format!("test.json{}", suffix)); for file_name_str in file_names { let file_name = OsStr::new(&file_name_str); let expected_stripped_file_name = OsStr::new("test.json"); let stripped_file_name = ignored_suffixes .try_with_stripped_suffix(file_name, |stripped_file_name| Ok(Some(stripped_file_name))); assert_eq!( expected_stripped_file_name, stripped_file_name.unwrap().unwrap() ); } } #[test] fn external_suffixes() { let mut ignored_suffixes = IgnoredSuffixes::default(); ignored_suffixes.add_suffix(".development"); ignored_suffixes.add_suffix(".production"); let file_names = ignored_suffixes .values .iter() .map(|suffix| format!("test.json{}", suffix)); for file_name_str in file_names { let file_name = OsStr::new(&file_name_str); let expected_stripped_file_name = OsStr::new("test.json"); let stripped_file_name = ignored_suffixes .try_with_stripped_suffix(file_name, |stripped_file_name| Ok(Some(stripped_file_name))); assert_eq!( expected_stripped_file_name, stripped_file_name.unwrap().unwrap() ); } } bat-0.19.0/src/syntax_mapping.rs000064400000000000000000000152320072674642500147120ustar 00000000000000use std::path::Path; use crate::error::Result; use ignored_suffixes::IgnoredSuffixes; use globset::{Candidate, GlobBuilder, GlobMatcher}; pub mod ignored_suffixes; #[derive(Debug, Clone, Copy, PartialEq)] #[non_exhaustive] pub enum MappingTarget<'a> { /// For mapping a path to a specific syntax. MapTo(&'a str), /// For mapping a path (typically an extension-less file name) to an unknown /// syntax. This typically means later using the contents of the first line /// of the file to determine what syntax to use. MapToUnknown, /// For mapping a file extension (e.g. `*.conf`) to an unknown syntax. This /// typically means later using the contents of the first line of the file /// to determine what syntax to use. However, if a syntax handles a file /// name that happens to have the given file extension (e.g. `resolv.conf`), /// then that association will have higher precedence, and the mapping will /// be ignored. MapExtensionToUnknown, } #[derive(Debug, Clone, Default)] pub struct SyntaxMapping<'a> { mappings: Vec<(GlobMatcher, MappingTarget<'a>)>, pub(crate) ignored_suffixes: IgnoredSuffixes<'a>, } impl<'a> SyntaxMapping<'a> { pub fn empty() -> SyntaxMapping<'a> { Default::default() } pub fn builtin() -> SyntaxMapping<'a> { let mut mapping = Self::empty(); mapping.insert("*.h", MappingTarget::MapTo("C++")).unwrap(); mapping.insert("*.fs", MappingTarget::MapTo("F#")).unwrap(); mapping .insert("build", MappingTarget::MapToUnknown) .unwrap(); mapping .insert("**/.ssh/config", MappingTarget::MapTo("SSH Config")) .unwrap(); mapping .insert( "**/bat/config", MappingTarget::MapTo("Bourne Again Shell (bash)"), ) .unwrap(); mapping .insert( "/etc/profile", MappingTarget::MapTo("Bourne Again Shell (bash)"), ) .unwrap(); mapping .insert("*.pac", MappingTarget::MapTo("JavaScript (Babel)")) .unwrap(); // See #1008 mapping .insert("rails", MappingTarget::MapToUnknown) .unwrap(); // Nginx and Apache syntax files both want to style all ".conf" files // see #1131 and #1137 mapping .insert("*.conf", MappingTarget::MapExtensionToUnknown) .unwrap(); for glob in &[ "/etc/nginx/**/*.conf", "/etc/nginx/sites-*/**/*", "nginx.conf", "mime.types", ] { mapping.insert(glob, MappingTarget::MapTo("nginx")).unwrap(); } for glob in &[ "/etc/apache2/**/*.conf", "/etc/apache2/sites-*/**/*", "httpd.conf", ] { mapping .insert(glob, MappingTarget::MapTo("Apache Conf")) .unwrap(); } for glob in &[ "**/systemd/**/*.conf", "**/systemd/**/*.example", "*.automount", "*.device", "*.dnssd", "*.link", "*.mount", "*.netdev", "*.network", "*.nspawn", "*.path", "*.service", "*.scope", "*.slice", "*.socket", "*.swap", "*.target", "*.timer", ] { mapping.insert(glob, MappingTarget::MapTo("INI")).unwrap(); } // pacman hooks mapping .insert("*.hook", MappingTarget::MapTo("INI")) .unwrap(); if let Some(xdg_config_home) = std::env::var_os("XDG_CONFIG_HOME") { let git_config_path = Path::new(&xdg_config_home).join("git"); mapping .insert( &git_config_path.join("config").to_string_lossy(), MappingTarget::MapTo("Git Config"), ) .ok(); mapping .insert( &git_config_path.join("ignore").to_string_lossy(), MappingTarget::MapTo("Git Ignore"), ) .ok(); mapping .insert( &git_config_path.join("attributes").to_string_lossy(), MappingTarget::MapTo("Git Attributes"), ) .ok(); } mapping } pub fn insert(&mut self, from: &str, to: MappingTarget<'a>) -> Result<()> { let glob = GlobBuilder::new(from) .case_insensitive(false) .literal_separator(true) .build()?; self.mappings.push((glob.compile_matcher(), to)); Ok(()) } pub fn mappings(&self) -> &[(GlobMatcher, MappingTarget<'a>)] { &self.mappings } pub(crate) fn get_syntax_for(&self, path: impl AsRef) -> Option> { let candidate = Candidate::new(&path); let candidate_filename = path.as_ref().file_name().map(Candidate::new); for (ref glob, ref syntax) in self.mappings.iter().rev() { if glob.is_match_candidate(&candidate) || candidate_filename .as_ref() .map_or(false, |filename| glob.is_match_candidate(filename)) { return Some(*syntax); } } None } pub fn insert_ignored_suffix(&mut self, suffix: &'a str) { self.ignored_suffixes.add_suffix(suffix); } } #[test] fn basic() { let mut map = SyntaxMapping::empty(); map.insert("/path/to/Cargo.lock", MappingTarget::MapTo("TOML")) .ok(); map.insert("/path/to/.ignore", MappingTarget::MapTo("Git Ignore")) .ok(); assert_eq!( map.get_syntax_for("/path/to/Cargo.lock"), Some(MappingTarget::MapTo("TOML")) ); assert_eq!(map.get_syntax_for("/path/to/other.lock"), None); assert_eq!( map.get_syntax_for("/path/to/.ignore"), Some(MappingTarget::MapTo("Git Ignore")) ); } #[test] fn user_can_override_builtin_mappings() { let mut map = SyntaxMapping::builtin(); assert_eq!( map.get_syntax_for("/etc/profile"), Some(MappingTarget::MapTo("Bourne Again Shell (bash)")) ); map.insert("/etc/profile", MappingTarget::MapTo("My Syntax")) .ok(); assert_eq!( map.get_syntax_for("/etc/profile"), Some(MappingTarget::MapTo("My Syntax")) ); } #[test] fn builtin_mappings() { let map = SyntaxMapping::builtin(); assert_eq!( map.get_syntax_for("/path/to/build"), Some(MappingTarget::MapToUnknown) ); } bat-0.19.0/src/terminal.rs000064400000000000000000000057700072674642500134720ustar 00000000000000use ansi_term::Color::{self, Fixed, RGB}; use ansi_term::{self, Style}; use syntect::highlighting::{self, FontStyle}; pub fn to_ansi_color(color: highlighting::Color, true_color: bool) -> Option { if color.a == 0 { // Themes can specify one of the user-configurable terminal colors by // encoding them as #RRGGBBAA with AA set to 00 (transparent) and RR set // to the 8-bit color palette number. The built-in themes ansi, base16, // and base16-256 use this. Some(match color.r { // For the first 8 colors, use the Color enum to produce ANSI escape // sequences using codes 30-37 (foreground) and 40-47 (background). // For example, red foreground is \x1b[31m. This works on terminals // without 256-color support. 0x00 => Color::Black, 0x01 => Color::Red, 0x02 => Color::Green, 0x03 => Color::Yellow, 0x04 => Color::Blue, 0x05 => Color::Purple, 0x06 => Color::Cyan, 0x07 => Color::White, // For all other colors, use Fixed to produce escape sequences using // codes 38;5 (foreground) and 48;5 (background). For example, // bright red foreground is \x1b[38;5;9m. This only works on // terminals with 256-color support. // // TODO: When ansi_term adds support for bright variants using codes // 90-97 (foreground) and 100-107 (background), we should use those // for values 0x08 to 0x0f and only use Fixed for 0x10 to 0xff. n => Fixed(n), }) } else if color.a == 1 { // Themes can specify the terminal's default foreground/background color // (i.e. no escape sequence) using the encoding #RRGGBBAA with AA set to // 01. The built-in theme ansi uses this. None } else if true_color { Some(RGB(color.r, color.g, color.b)) } else { Some(Fixed(ansi_colours::ansi256_from_rgb(( color.r, color.g, color.b, )))) } } pub fn as_terminal_escaped( style: highlighting::Style, text: &str, true_color: bool, colored: bool, italics: bool, background_color: Option, ) -> String { if text.is_empty() { return text.to_string(); } let mut style = if !colored { Style::default() } else { let mut color = Style { foreground: to_ansi_color(style.foreground, true_color), ..Style::default() }; if style.font_style.contains(FontStyle::BOLD) { color = color.bold(); } if style.font_style.contains(FontStyle::UNDERLINE) { color = color.underline(); } if italics && style.font_style.contains(FontStyle::ITALIC) { color = color.italic(); } color }; style.background = background_color.and_then(|c| to_ansi_color(c, true_color)); style.paint(text).to_string() } bat-0.19.0/src/vscreen.rs000064400000000000000000000140650072674642500133210ustar 00000000000000use std::fmt::{Display, Formatter}; // Wrapper to avoid unnecessary branching when input doesn't have ANSI escape sequences. pub struct AnsiStyle { attributes: Option, } impl AnsiStyle { pub fn new() -> Self { AnsiStyle { attributes: None } } pub fn update(&mut self, sequence: &str) -> bool { match &mut self.attributes { Some(a) => a.update(sequence), None => { self.attributes = Some(Attributes::new()); self.attributes.as_mut().unwrap().update(sequence) } } } } impl Display for AnsiStyle { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { match self.attributes { Some(ref a) => a.fmt(f), None => Ok(()), } } } struct Attributes { foreground: String, background: String, underlined: String, /// The character set to use. /// REGEX: `\^[()][AB0-3]` charset: String, /// A buffer for unknown sequences. unknown_buffer: String, /// ON: ^[1m /// OFF: ^[22m bold: String, /// ON: ^[2m /// OFF: ^[22m dim: String, /// ON: ^[4m /// OFF: ^[24m underline: String, /// ON: ^[3m /// OFF: ^[23m italic: String, /// ON: ^[9m /// OFF: ^[29m strike: String, } impl Attributes { pub fn new() -> Self { Attributes { foreground: "".to_owned(), background: "".to_owned(), underlined: "".to_owned(), charset: "".to_owned(), unknown_buffer: "".to_owned(), bold: "".to_owned(), dim: "".to_owned(), underline: "".to_owned(), italic: "".to_owned(), strike: "".to_owned(), } } /// Update the attributes with an escape sequence. /// Returns `false` if the sequence is unsupported. pub fn update(&mut self, sequence: &str) -> bool { let mut chars = sequence.char_indices().skip(1); if let Some((_, t)) = chars.next() { match t { '(' => self.update_with_charset('(', chars.map(|(_, c)| c)), ')' => self.update_with_charset(')', chars.map(|(_, c)| c)), '[' => { if let Some((i, last)) = chars.last() { // SAFETY: Always starts with ^[ and ends with m. self.update_with_csi(last, &sequence[2..i]) } else { false } } _ => self.update_with_unsupported(sequence), } } else { false } } fn sgr_reset(&mut self) { self.foreground.clear(); self.background.clear(); self.underlined.clear(); self.bold.clear(); self.dim.clear(); self.underline.clear(); self.italic.clear(); self.strike.clear(); } fn update_with_sgr(&mut self, parameters: &str) -> bool { let mut iter = parameters .split(';') .map(|p| if p.is_empty() { "0" } else { p }) .map(|p| p.parse::()) .map(|p| p.unwrap_or(0)); // Treat errors as 0. while let Some(p) = iter.next() { match p { 0 => self.sgr_reset(), 1 => self.bold = format!("\x1B[{}m", parameters), 2 => self.dim = format!("\x1B[{}m", parameters), 3 => self.italic = format!("\x1B[{}m", parameters), 4 => self.underline = format!("\x1B[{}m", parameters), 23 => self.italic.clear(), 24 => self.underline.clear(), 22 => { self.bold.clear(); self.dim.clear(); } 30..=39 => self.foreground = Self::parse_color(p, &mut iter), 40..=49 => self.background = Self::parse_color(p, &mut iter), 58..=59 => self.underlined = Self::parse_color(p, &mut iter), 90..=97 => self.foreground = Self::parse_color(p, &mut iter), 100..=107 => self.foreground = Self::parse_color(p, &mut iter), _ => { // Unsupported SGR sequence. // Be compatible and pretend one just wasn't was provided. } } } true } fn update_with_csi(&mut self, finalizer: char, sequence: &str) -> bool { if finalizer == 'm' { self.update_with_sgr(sequence) } else { false } } fn update_with_unsupported(&mut self, sequence: &str) -> bool { self.unknown_buffer.push_str(sequence); false } fn update_with_charset(&mut self, kind: char, set: impl Iterator) -> bool { self.charset = format!("\x1B{}{}", kind, set.take(1).collect::()); true } fn parse_color(color: u16, parameters: &mut dyn Iterator) -> String { match color % 10 { 8 => match parameters.next() { Some(5) /* 256-color */ => format!("\x1B[{};5;{}m", color, join(";", 1, parameters)), Some(2) /* 24-bit color */ => format!("\x1B[{};2;{}m", color, join(";", 3, parameters)), Some(c) => format!("\x1B[{};{}m", color, c), _ => "".to_owned(), }, 9 => "".to_owned(), _ => format!("\x1B[{}m", color), } } } impl Display for Attributes { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { write!( f, "{}{}{}{}{}{}{}{}{}", self.foreground, self.background, self.underlined, self.charset, self.bold, self.dim, self.underline, self.italic, self.strike, ) } } fn join( delimiter: &str, limit: usize, iterator: &mut dyn Iterator, ) -> String { iterator .take(limit) .map(|i| i.to_string()) .collect::>() .join(delimiter) } bat-0.19.0/src/wrapping.rs000064400000000000000000000004750072674642500135030ustar 00000000000000#[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum WrappingMode { Character, // The bool specifies whether wrapping has been explicitly disabled by the user via --wrap=never NoWrapping(bool), } impl Default for WrappingMode { fn default() -> Self { WrappingMode::NoWrapping(false) } } bat-0.19.0/tests/.gitattributes000064400000000000000000000005740072674642500145540ustar 00000000000000# force LF EOLs for test fixtures examples/** text=auto eol=lf snapshots/** text=auto eol=lf syntax-tests/source/** text=auto eol=lf syntax-tests/highlighted/** text=auto eol=lf # Linguist overrides benchmarks/** linguist-vendored examples/** linguist-vendored snapshots/** linguist-vendored syntax-tests/highlighted/** linguist-vendored syntax-tests/source/** linguist-vendored bat-0.19.0/tests/assets.rs000064400000000000000000000021520072674642500135230ustar 00000000000000use bat::assets::HighlightingAssets; /// This test ensures that we are not accidentally removing themes due to submodule updates. /// It is 'ignore'd by default because it requires themes.bin to be up-to-date. #[test] #[ignore] fn all_themes_are_present() { let assets = HighlightingAssets::from_binary(); let mut themes: Vec<_> = assets.themes().collect(); themes.sort_unstable(); assert_eq!( themes, vec![ "1337", "Coldark-Cold", "Coldark-Dark", "DarkNeon", "Dracula", "GitHub", "Monokai Extended", "Monokai Extended Bright", "Monokai Extended Light", "Monokai Extended Origin", "Nord", "OneHalfDark", "OneHalfLight", "Solarized (dark)", "Solarized (light)", "Sublime Snazzy", "TwoDark", "Visual Studio Dark+", "ansi", "base16", "base16-256", "gruvbox-dark", "gruvbox-light", "zenburn" ] ); } bat-0.19.0/tests/benchmarks/.gitignore000064400000000000000000000000230072674642500157530ustar 00000000000000/benchmark-results bat-0.19.0/tests/benchmarks/.ignore000064400000000000000000000000130072674642500152460ustar 00000000000000test-src/* bat-0.19.0/tests/benchmarks/highlighting-speed-src/grep-output-ansi-sequences.txt000064400000000000000000016631710072674642500263140ustar 00000000000000.github/ISSUE_TEMPLATE/syntax_request.md:3:about: Request adding a new syntax to bat. .github/ISSUE_TEMPLATE/syntax_request.md:14:Bat supports locally-installed language definitions. See the link below: .github/ISSUE_TEMPLATE/syntax_request.md:16:https://github.com/sharkdp/bat#adding-new-syntaxes--language-definitions .github/ISSUE_TEMPLATE/question.md:3:about: Ask a question about 'bat'. .github/ISSUE_TEMPLATE/bug_report.md:21:**How did you install `bat`?** .github/ISSUE_TEMPLATE/bug_report.md:27:**bat version and environment** .github/ISSUE_TEMPLATE/bug_report.md:31:in which you're running bat. To do this, run the full `bat` command that demonstrates .github/ISSUE_TEMPLATE/bug_report.md:34: bat [other options and arguments…] --diagnostic .github/ISSUE_TEMPLATE/bug_report.md:40:If you are running bat 0.17.1 or older (where --diagnostic is not available), please .github/ISSUE_TEMPLATE/bug_report.md:43: https://github.com/sharkdp/bat/blob/master/diagnostics/info.sh .github/ISSUE_TEMPLATE/bug_report.md:46:are on Windows, please let us know your bat version and your Windows version. .github/workflows/CICD.yml:69: - name: Build and install bat .github/workflows/CICD.yml:76: - name: Build and install bat with updated assets .github/workflows/CICD.yml:94: run: bat --list-languages .github/workflows/CICD.yml:96: run: bat --list-themes .github/workflows/CICD.yml:235: - name: Run bat .github/workflows/CICD.yml:242: - name: Show diagnostics (bat --diagnostic) .github/workflows/CICD.yml:302: cp 'target/${{ matrix.job.target }}/release/build/${{ env.PROJECT_NAME }}'-*/out/assets/manual/bat.1 "$ARCHIVE_DIR" .github/workflows/CICD.yml:308: cp 'target/${{ matrix.job.target }}/release/build/${{ env.PROJECT_NAME }}'-*/out/assets/completions/bat.bash "$ARCHIVE_DIR/autocomplete/${{ env.PROJECT_NAME }}.bash" .github/workflows/CICD.yml:309: cp 'target/${{ matrix.job.target }}/release/build/${{ env.PROJECT_NAME }}'-*/out/assets/completions/bat.fish "$ARCHIVE_DIR/autocomplete/${{ env.PROJECT_NAME }}.fish" .github/workflows/CICD.yml:310: cp 'target/${{ matrix.job.target }}/release/build/${{ env.PROJECT_NAME }}'-*/out/assets/completions/_bat.ps1 "$ARCHIVE_DIR/autocomplete/_${{ env.PROJECT_NAME }}.ps1" .github/workflows/CICD.yml:311: cp 'target/${{ matrix.job.target }}/release/build/${{ env.PROJECT_NAME }}'-*/out/assets/completions/bat.zsh "$ARCHIVE_DIR/autocomplete/${{ env.PROJECT_NAME }}.zsh" .github/workflows/CICD.yml:355: install -Dm644 'target/${{ matrix.job.target }}/release/build/${{ env.PROJECT_NAME }}'-*/out/assets/manual/bat.1 "${DPKG_DIR}/usr/share/man/man1/${{ env.PROJECT_NAME }}.1" .github/workflows/CICD.yml:359: install -Dm644 'target/${{ matrix.job.target }}/release/build/${{ env.PROJECT_NAME }}'-*/out/assets/completions/bat.bash "${DPKG_DIR}/usr/share/bash-completion/completions/${{ env.PROJECT_NAME }}" .github/workflows/CICD.yml:360: install -Dm644 'target/${{ matrix.job.target }}/release/build/${{ env.PROJECT_NAME }}'-*/out/assets/completions/bat.fish "${DPKG_DIR}/usr/share/fish/vendor_completions.d/${{ env.PROJECT_NAME }}.fish" .github/workflows/CICD.yml:361: install -Dm644 'target/${{ matrix.job.target }}/release/build/${{ env.PROJECT_NAME }}'-*/out/assets/completions/bat.zsh "${DPKG_DIR}/usr/share/zsh/vendor-completions/_${{ env.PROJECT_NAME }}" README.md:2: bat - a cat clone with wings
README.md:3: Build Status README.md:4: license README.md:5: Version info
README.md:16: [中文] README.md:24:`bat` supports syntax highlighting for a large number of programming and markup README.md:31:`bat` communicates with `git` to show modifications with respect to the index README.md:45:By default, `bat` pipes its own output to a pager (e.g. `less`) if the output is too large for one screen. README.md:46:If you would rather `bat` work like `cat` all the time (never page output), you can set `--paging=never` as an option, either on the command line or in your configuration file. README.md:47:If you intend to alias `cat` to `bat` in your shell configuration, you can use `alias cat='bat --paging=never'` to preserve the default behavior. README.md:51:Even with a pager set, you can still use `bat` to concatenate files :wink:. README.md:52:Whenever `bat` detects a non-interactive terminal (i.e. when you pipe into another process or into a file), `bat` will act as a drop-in replacement for `cat` and fall back to printing the plain file contents, regardless of the `--pager` option's value. README.md:59:> bat README.md README.md:65:> bat src/*.rs README.md:73:> curl -s https://sh.rustup.rs | bat README.md:79:> yaml2json .travis.yml | json_pp | bat -l json README.md:84:> bat -A /etc/hosts README.md:90:bat > note.md # quickly create a new file README.md:92:bat header.md content.md footer.md > document.md README.md:94:bat -n main.rs # show line numbers (only) README.md:96:bat f - g # output 'f', then stdin, then 'g'. README.md:103:You can use `bat` as a previewer for [`fzf`](https://github.com/junegunn/fzf). To do this, README.md:104:use `bat`s `--color=always` option to force colorized output. You can also use `--line-range` README.md:108:fzf --preview 'bat --color=always --style=numbers --line-range=:500 {}' README.md:115:You can use the `-exec` option of `find` to preview all search results with `bat`: README.md:118:find … -exec bat {} + README.md:121:If you happen to use [`fd`](https://github.com/sharkdp/fd), you can use the `-X`/`--exec-batch` option to do the same: README.md:124:fd … -X bat README.md:129:With [`batgrep`](https://github.com/eth-p/bat-extras/blob/master/doc/batgrep.md), `bat` can be used as the printer for [`ripgrep`](https://github.com/BurntSushi/ripgrep) search results. README.md:132:batgrep needle src/ README.md:137:`bat` can be combined with `tail -f` to continuously monitor a given file with syntax highlighting. README.md:140:tail -f /var/log/pacman.log | bat --paging=never -l log README.md:148:You can combine `bat` with `git show` to view an older version of a given file with proper syntax README.md:152:git show v0.6.0:src/main.rs | bat -l rs README.md:157:You can combine `bat` with `git diff` to view lines around code changes with proper syntax README.md:160:batdiff() { README.md:161: git diff --name-only --diff-filter=d | xargs bat --diff README.md:164:If you prefer to use this as a separate tool, check out `batdiff` in [`bat-extras`](https://github.com/eth-p/bat-extras). README.md:170:The line numbers and Git modification markers in the output of `bat` can make it hard to copy README.md:171:the contents of a file. To prevent this, you can call `bat` with the `-p`/`--plain` option or README.md:174:bat main.cpp | xclip README.md:176:`bat` will detect that the output is being redirected and print the plain file contents. README.md:180:`bat` can be used as a colorizing pager for `man`, by setting the README.md:184:export MANPAGER="sh -c 'col -bx | bat -l man -p'" README.md:187:(replace `bat` with `batcat` if you are on Debian or Ubuntu) README.md:192:If you prefer to have this bundled in a new command, you can also use [`batman`](https://github.com/eth-p/bat-extras/blob/master/doc/batman.md). README.md:196:Also, note that this will [not work](https://github.com/sharkdp/bat/issues/1145) with Mandocs `man` implementation. README.md:200:The [`prettybat`](https://github.com/eth-p/bat-extras/blob/master/doc/prettybat.md) script is a wrapper that will format code and print it with `bat`. README.md:205:[![Packaging status](https://repology.org/badge/vertical-allrepos/bat-cat.svg)](https://repology.org/project/bat-cat/versions) README.md:210:`bat` is available on [Ubuntu since 20.04 ("Focal")](https://packages.ubuntu.com/search?keywords=bat&exact=1) and [Debian since August 2021 (Debian 11 - "Bullseye")](https://packages.debian.org/bullseye/bat). README.md:215:sudo apt install bat README.md:218:**Important**: If you install `bat` this way, please note that the executable may be installed as `batcat` instead of `bat` (due to [a name README.md:219:clash with another package](https://github.com/sharkdp/bat/issues/982)). You can set up a `bat -> batcat` symlink or alias to prevent any issues that may come up because of this and to be consistent with other distributions: README.md:222:ln -s /usr/bin/batcat ~/.local/bin/bat README.md:229:the most recent release of `bat`, download the latest `.deb` package from the README.md:230:[release page](https://github.com/sharkdp/bat/releases) and install it via: README.md:233:sudo dpkg -i bat_0.18.3_amd64.deb # adapt version number and architecture README.md:238:You can install [the `bat` package](https://pkgs.alpinelinux.org/packages?name=bat) README.md:242:apk add bat README.md:247:You can install [the `bat` package](https://www.archlinux.org/packages/community/x86_64/bat/) README.md:251:pacman -S bat README.md:256:You can install [the `bat` package](https://koji.fedoraproject.org/koji/packageinfo?packageID=27506) from the official [Fedora Modular](https://docs.fedoraproject.org/en-US/modularity/using-modules/) repository. README.md:259:dnf install bat README.md:264:You can install [the `bat` package](https://github.com/funtoo/dev-kit/tree/1.4-release/sys-apps/bat) from dev-kit. README.md:267:emerge sys-apps/bat README.md:272:You can install [the `bat` package](https://packages.gentoo.org/packages/sys-apps/bat) README.md:276:emerge sys-apps/bat README.md:281:You can install `bat` via xbps-install: README.md:283:xbps-install -S bat README.md:288:You can install `bat` via pkg: README.md:290:pkg install bat README.md:295:You can install a precompiled [`bat` package](https://www.freshports.org/textproc/bat) with pkg: README.md:298:pkg install bat README.md:304:cd /usr/ports/textproc/bat README.md:310:You can install `bat` package using [`pkg_add(1)`](https://man.openbsd.org/pkg_add.1): README.md:313:pkg_add bat README.md:318:You can install `bat` using the [nix package manager](https://nixos.org/nix): README.md:321:nix-env -i bat README.md:326:You can install `bat` with zypper: README.md:329:zypper install bat README.md:335:Existing packages may be available, but are not officially supported and may contain [issues](https://github.com/sharkdp/bat/issues/1519). README.md:339:You can install `bat` with [Homebrew on MacOS](https://formulae.brew.sh/formula/bat) or [Homebrew on Linux](https://formulae.brew.sh/formula-linux/bat): README.md:342:brew install bat README.md:347:Or install `bat` with [MacPorts](https://ports.macports.org/port/bat/summary): README.md:350:port install bat README.md:355:There are a few options to install `bat` on Windows. Once you have installed `bat`, README.md:356:take a look at the ["Using `bat` on Windows"](#using-bat-on-windows) section. README.md:364:You can install `bat` via [Chocolatey](https://chocolatey.org/packages/Bat): README.md:366:choco install bat README.md:371:You can install `bat` via [scoop](https://scoop.sh/): README.md:373:scoop install bat README.md:378:You can download prebuilt binaries from the [Release page](https://github.com/sharkdp/bat/releases), README.md:384:Check out the [Release page](https://github.com/sharkdp/bat/releases) for README.md:385:prebuilt versions of `bat` for many different architectures. Statically-linked README.md:390:If you want to build `bat` from source, you need Rust 1.46 or README.md:394:cargo install --locked bat README.md:404:Use `bat --list-themes` to get a list of all available themes for syntax README.md:405:highlighting. To select the `TwoDark` theme, call `bat` with the README.md:406:`--theme=TwoDark` option or set the `BAT_THEME` environment variable to README.md:407:`TwoDark`. Use `export BAT_THEME="TwoDark"` in your shell's startup file to README.md:408:make the change permanent. Alternatively, use `bat`s README.md:409:[configuration file](https://github.com/sharkdp/bat#configuration-file). README.md:414:bat --list-themes | fzf --preview="bat --theme={} --color=always /path/to/file" README.md:417:`bat` looks good on a dark background by default. However, if your terminal uses a README.md:420:['Adding new themes' section below](https://github.com/sharkdp/bat#adding-new-themes). README.md:424:`bat` has three themes that always use [8-bit colors](https://en.wikipedia.org/wiki/ANSI_escape_code#Colors), README.md:444:You can use the `--style` option to control the appearance of `bat`s output. README.md:446:and line numbers but no grid and no file header. Set the `BAT_STYLE` environment README.md:447:variable to make these changes permanent or use `bat`s README.md:448:[configuration file](https://github.com/sharkdp/bat#configuration-file). README.md:452:Should you find that a particular syntax is not available within `bat`, you can follow these README.md:453:instructions to easily add new syntaxes to your current `bat` installation. README.md:455:`bat` uses the excellent [`syntect`](https://github.com/trishume/syntect/) README.md:466: mkdir -p "$(bat --config-dir)/syntaxes" README.md:467: cd "$(bat --config-dir)/syntaxes" README.md:477: bat cache --build README.md:480:3. Finally, use `bat --list-languages` to check if the new languages are available. README.md:485: bat cache --clear README.md:488:4. If you think that a specific syntax should be included in `bat` by default, please README.md:490: instructions [here](doc/assets.md): [Open Syntax Request](https://github.com/sharkdp/bat/issues/new?labels=syntax-request&template=syntax_request.md). README.md:498:mkdir -p "$(bat --config-dir)/themes" README.md:499:cd "$(bat --config-dir)/themes" README.md:505:bat cache --build README.md:508:Finally, use `bat --list-themes` to check if the new themes are available. README.md:516:(use `bat --list-languages` for an overview). README.md:518:Note: You probably want to use this option as an entry in `bat`s configuration file instead README.md:539:`bat` uses the pager that is specified in the `PAGER` environment variable. If this variable is not README.md:541:`PAGER` variable or set the `BAT_PAGER` environment variable to override what is specified in README.md:544:**Note**: If `PAGER` is `more` or `most`, `bat` will silently use `less` instead to ensure support for colors. README.md:547:`PAGER`/`BAT_PAGER` variables: README.md:550:export BAT_PAGER="less -RF" README.md:553:Instead of using environment variables, you can also use `bat`s [configuration file](https://github.com/sharkdp/bat#configuration-file) to configure the pager (`--pager` option). README.md:556:`bat` will pass the following command line options to the pager: `-R`/`--RAW-CONTROL-CHARS`, README.md:572:`bat` expands tabs to 4 spaces by itself, not relying on the pager. To change this, simply add the README.md:575:**Note**: Defining tab stops for the pager (via the `--pager` argument by `bat`, or via the `LESS` README.md:578:sidebar. Calling `bat` with `--tabs=0` will override it and let tabs be consumed by the pager. README.md:582:If you make use of the dark mode feature in macOS, you might want to configure `bat` to use a different README.md:587:alias cat="bat --theme=\$(defaults read -globalDomain AppleInterfaceStyle &> /dev/null && echo default || echo GitHub)" README.md:593:`bat` can also be customized with a configuration file. The location of the file is dependent README.md:596:bat --config-file README.md:599:Alternatively, you can use the `BAT_CONFIG_PATH` environment variable to point `bat` to a README.md:602:export BAT_CONFIG_PATH="/path/to/bat.conf" README.md:607:bat --generate-config-file README.md:612:The configuration file is a simple list of command line arguments. Use `bat --help` to see a full list of possible options and values. In addition, you can add comments by prepending a line with the `#` character. README.md:629:## Using `bat` on Windows README.md:631:`bat` mostly works out-of-the-box on Windows, but a few features may need extra configuration. README.md:653:or by setting `BAT_PAGER` to an empty string. README.md:657:`bat` on Windows does not natively support Cygwin's unix-style paths (`/cygdrive/*`). When passed an absolute cygwin path as an argument, `bat` will encounter the following error: `The system cannot find the path specified. (os error 3)` README.md:662:bat() { README.md:671: command bat "${args[@]}" README.md:679:If an input file contains color codes or other ANSI escape sequences, `bat` will have problems README.md:682:passing the `--color=never --wrap=never` options to `bat`. README.md:686:`bat` handles terminals *with* and *without* truecolor support. However, the colors in most syntax README.md:694:`24bit`. Otherwise, `bat` will not be able to determine whether or not 24-bit escape sequences README.md:699:Please try a different theme (see `bat --list-themes` for a list). The `OneHalfDark` and README.md:704:`bat` natively supports UTF-8 as well as UTF-16. For every other file encoding, you may need to README.md:709:iconv -f ISO-8859-1 -t UTF-8 my-file.php | bat README.md:712:by `bat`. README.md:718:git clone --recursive https://github.com/sharkdp/bat README.md:721:cd bat README.md:730:# Build a bat binary with modified syntaxes and themes README.md:735:If you want to build an application that uses `bat`s pretty-printing README.md:736:features as a library, check out the [the API documentation](https://docs.rs/bat/). README.md:738:when you depend on `bat` as a library. README.md:753:Please contact [David Peter](https://david-peter.de/) via email if you want to report a vulnerability in `bat`. README.md:757:`bat` tries to achieve the following goals: README.md:768:Copyright (c) 2018-2021 [bat-developers](https://github.com/sharkdp/bat). README.md:770:`bat` is made available under the terms of either the MIT License or the Apache License 2.0, at your option. .gitmodules:198: url = https://github.com/ArmandPhilippot/coldark-bat.git .gitmodules:202: branch = bat-source examples/list_syntaxes_and_themes.rs:1:/// A simple program that prints its own source code using the bat library examples/list_syntaxes_and_themes.rs:2:use bat::PrettyPrinter; examples/inputs.rs:3:use bat::{Input, PrettyPrinter}; examples/yaml.rs:2:use bat::{Input, PrettyPrinter}; examples/advanced.rs:1:/// A program that prints its own source code using the bat library examples/advanced.rs:2:use bat::{PagingMode, PrettyPrinter, WrappingMode}; examples/cat.rs:1:/// A very simple colorized `cat` clone, using `bat` as a library. examples/cat.rs:2:/// See `src/bin/bat` for the full `bat` application. examples/cat.rs:3:use bat::PrettyPrinter; examples/simple.rs:1:/// A simple program that prints its own source code using the bat library examples/simple.rs:2:use bat::PrettyPrinter; .gitignore:5:/assets/completions/bat.bash .gitignore:6:/assets/completions/bat.fish .gitignore:7:/assets/completions/bat.zsh .gitignore:8:/assets/manual/bat.1 src/input.rs:12:/// This tells bat how to refer to the input. src/error.rs:22: #[error("Use of bat as a pager is disallowed in order to avoid infinite recursion problems")] src/error.rs:23: InvalidPagerValueBat, src/error.rs:53: Red.paint("[bat error]"), src/error.rs:59: writeln!(output, "{}: {}", Red.paint("[bat error]"), error).ok(); src/lib.rs:1://! `bat` is a library to print syntax highlighted content. src/lib.rs:13://! use bat::PrettyPrinter; src/macros.rs:2:macro_rules! bat_warning { src/macros.rs:5: eprintln!("{}: {}", Yellow.paint("[bat warning]"), format!($($arg)*)); src/syntax_mapping.rs:52: "**/bat/config", src/pager.rs:10: /// From the env var BAT_PAGER src/pager.rs:11: EnvVarBatPager, src/pager.rs:23: /// bat src/pager.rs:24: Bat, src/pager.rs:48: Some("bat") => PagerKind::Bat, src/pager.rs:86: let bat_pager = env::var("BAT_PAGER"); src/pager.rs:89: let (cmd, source) = match (config_pager, &bat_pager, &pager) { src/pager.rs:91: (_, Ok(bat_pager), _) => (bat_pager.as_str(), PagerSource::EnvVarBatPager), src/pager.rs:105: // If PAGER=bat, silently use 'less' instead to prevent src/pager.rs:107: // Never silently use 'less' if BAT_PAGER or --pager has been src/pager.rs:109: matches!(kind, PagerKind::More | PagerKind::Most | PagerKind::Bat) src/assets.rs:16:use crate::{bat_warning, SyntaxMapping}; src/assets.rs:218: bat_warning!("Theme '{}' is deprecated, using 'ansi' instead.", theme); src/assets.rs:222: bat_warning!("Unknown theme '{}', using default.", theme) src/printer.rs:278: (but will be present if the output of 'bat' is piped). You can use 'bat -A' \ src/printer.rs:280: Yellow.paint("[bat warning]"), src/output.rs:62: if pager.kind == PagerKind::Bat { src/output.rs:63: return Err(Error::InvalidPagerValueBat); src/output.rs:78: // ANSI color sequences printed by bat. If someone has set PAGER="less -F", we src/output.rs:81: // We only do this for PAGER (as it is not specific to 'bat'), not for BAT_PAGER src/output.rs:82: // or bats '--pager' command line option. src/bin/bat/input.rs:1:use bat::input::Input; src/bin/bat/config.rs:10: env::var("BAT_CONFIG_PATH") src/bin/bat/config.rs:16:pub fn generate_config_file() -> bat::error::Result<()> { src/bin/bat/config.rs:46: let default_config = r#"# This is `bat`s configuration file. Each line either contains a comment or src/bin/bat/config.rs:47:# a command-line option that you want to pass to `bat` by default. You can src/bin/bat/config.rs:48:# run `bat --help` to get a list of all possible configuration options. src/bin/bat/config.rs:50:# Specify desired highlighting theme (e.g. "TwoDark"). Run `bat --list-themes` src/bin/bat/config.rs:62:# enable mouse scrolling support in `bat` when running inside tmux. This might src/bin/bat/config.rs:98: env::var("BAT_OPTS").ok().map(|s| get_args_from_str(&s)) src/bin/bat/directories.rs:7:/// The `XDG_CACHE_HOME` environment variable is checked first. `BAT_CONFIG_DIR` src/bin/bat/directories.rs:9:/// The fallback directories are `~/.cache/bat` and `~/.config/bat`, respectively. src/bin/bat/directories.rs:10:pub struct BatProjectDirs { src/bin/bat/directories.rs:15:impl BatProjectDirs { src/bin/bat/directories.rs:16: fn new() -> Option<BatProjectDirs> { src/bin/bat/directories.rs:17: let cache_dir = BatProjectDirs::get_cache_dir()?; src/bin/bat/directories.rs:19: // Checks whether or not $BAT_CONFIG_DIR exists. If it doesn't, set our config dir src/bin/bat/directories.rs:22: if let Some(config_dir_op) = env::var_os("BAT_CONFIG_DIR").map(PathBuf::from) { src/bin/bat/directories.rs:34: config_dir_op.map(|d| d.join("bat"))? src/bin/bat/directories.rs:37: Some(BatProjectDirs { src/bin/bat/directories.rs:44: // on all OS prefer BAT_CACHE_PATH if set src/bin/bat/directories.rs:45: let cache_dir_op = env::var_os("BAT_CACHE_PATH").map(PathBuf::from); src/bin/bat/directories.rs:59: cache_dir_op.map(|d| d.join("bat")) src/bin/bat/directories.rs:72: pub static ref PROJECT_DIRS: BatProjectDirs = src/bin/bat/directories.rs:73: BatProjectDirs::new().expect("Could not get home directory"); src/bin/bat/app.rs:17:use bat::{ src/bin/bat/app.rs:19: bat_warning, src/bin/bat/app.rs:56: // Skip the arguments in bats config file src/bin/bat/app.rs:62: // Read arguments from bats config file src/bin/bat/app.rs:191: .or_else(|| env::var("BAT_TABS").ok()) src/bin/bat/app.rs:204: .or_else(|| env::var("BAT_THEME").ok()) src/bin/bat/app.rs:305: let env_style_components: Option> = env::var("BAT_STYLE") src/bin/bat/app.rs:336: bat_warning!("Style 'rule' is a subset of style 'grid', 'rule' will not be visible."); src/bin/bat/assets.rs:9:use bat::assets::HighlightingAssets; src/bin/bat/assets.rs:10:use bat::assets_metadata::AssetsMetadata; src/bin/bat/assets.rs:11:use bat::error::*; src/bin/bat/assets.rs:34: in '{}' are not compatible with this version of bat ({}). To solve this, \ src/bin/bat/assets.rs:35: either rebuild the cache (bat cache --build) or remove \ src/bin/bat/assets.rs:36: the custom syntaxes/themes (bat cache --clear).\n\ src/bin/bat/assets.rs:38: https://github.com/sharkdp/bat#adding-new-syntaxes--language-definitions", src/bin/bat/main.rs:28:use bat::{ src/bin/bat/main.rs:52: bat::assets::build(source_dir, !blank, target_dir, clap::crate_version!()) src/bin/bat/main.rs:60: println!("bat has been built without the 'build-assets' feature. The 'cache --build' option is not available."); src/bin/bat/main.rs:207: and are added to the cache with `bat cache --build`. \ src/bin/bat/main.rs:209: https://github.com/sharkdp/bat#adding-new-themes", src/bin/bat/main.rs:230: let pager = bat::config::get_pager_executable(app.matches.value_of("pager")) src/bin/bat/main.rs:243: "BAT_PAGER", src/bin/bat/main.rs:244: "BAT_CACHE_PATH", src/bin/bat/main.rs:245: "BAT_CONFIG_PATH", src/bin/bat/main.rs:246: "BAT_OPTS", src/bin/bat/main.rs:247: "BAT_STYLE", src/bin/bat/main.rs:248: "BAT_TABS", src/bin/bat/main.rs:249: "BAT_THEME", src/bin/bat/main.rs:280: println!("bat has been built without the 'bugreport' feature. The '--diagnostic' option is not available."); src/bin/bat/clap_app.rs:43: "Note: `bat -h` prints a short and concise overview while `bat --help` gives all \ src/bin/bat/clap_app.rs:127: data to bat from STDIN when bat does not otherwise know \ src/bin/bat/clap_app.rs:290: if the output of bat is piped to another program, but you want \ src/bin/bat/clap_app.rs:306: set BAT_PAGER to an empty string. To control which pager is used, see the \ src/bin/bat/clap_app.rs:330: PAGER and BAT_PAGER environment variables. The default pager is 'less'. \ src/bin/bat/clap_app.rs:363: BAT_THEME environment variable (e.g.: export \ src/bin/bat/clap_app.rs:364: BAT_THEME=\"...\").", src/bin/bat/clap_app.rs:412: BAT_STYLE environment variable (e.g.: export BAT_STYLE=\"..\").\n\n\ src/bin/bat/clap_app.rs:497: .help("Show bat's configuration directory."), src/bin/bat/clap_app.rs:503: .help("Show bat's cache directory."), src/bin/bat/clap_app.rs:521: 'bat --ignored-suffix \".dev\" my_file.json.dev' will use JSON syntax, and ignore '.dev'" src/bin/bat/clap_app.rs:528: // enable the 'bat cache' subcommand. src/assets/serialized_syntax_set.rs:14: /// The data to use is embedded into the bat binary. src/assets/build_assets.rs:246: if std::env::var("BAT_PRINT_SYNTAX_DEPENDENCIES").is_ok() { src/assets/build_assets.rs:248: // BAT_PRINT_SYNTAX_DEPENDENCIES=1 cargo run -- cache --build --source assets --blank --target /tmp src/assets/build_assets.rs:342:/// BAT_SYNTAX_DEPENDENCIES_TO_GRAPHVIZ_DOT_FILE=/tmp/bat-syntax-dependencies.dot cargo run -- cache --build --source assets --blank --target /tmp src/assets/build_assets.rs:343:/// dot /tmp/bat-syntax-dependencies.dot -Tpng -o /tmp/bat-syntax-dependencies.png src/assets/build_assets.rs:344:/// open /tmp/bat-syntax-dependencies.png src/assets/build_assets.rs:350: if let Ok(dot_file_path) = std::env::var("BAT_SYNTAX_DEPENDENCIES_TO_GRAPHVIZ_DOT_FILE") { src/assets/build_assets.rs:424: if std::env::var("BAT_INCLUDE_SYNTAX_DEPENDENTS").is_ok() { src/assets/assets_metadata.rs:12: bat_version: Option, src/assets/assets_metadata.rs:22: bat_version: Some(current_version.to_owned()), src/assets/assets_metadata.rs:48: /// => assume that these were created by an old version of bat and return src/assets/assets_metadata.rs:69: Version::parse(current_version).expect("bat follows semantic versioning"); src/assets/assets_metadata.rs:71: .bat_version src/assets/build_assets/graphviz_utils.rs:30: writeln!(dot_file, "digraph BatSyntaxDependencies {{")?; build.rs:2:// For more details, see https://github.com/sharkdp/bat/issues/372 build.rs:4:// For bat-as-a-library, no build script is required. The build script is for build.rs:5:// the manpage and completions, which are only relevant to the bat application. build.rs:17: let project_name = option_env!("PROJECT_NAME").unwrap_or("bat"); build.rs:54: "assets/manual/bat.1.in", build.rs:55: out_dir.join("assets/manual/bat.1"), build.rs:59: "assets/completions/bat.bash.in", build.rs:60: out_dir.join("assets/completions/bat.bash"), build.rs:64: "assets/completions/bat.fish.in", build.rs:65: out_dir.join("assets/completions/bat.fish"), build.rs:69: "assets/completions/_bat.ps1.in", build.rs:70: out_dir.join("assets/completions/_bat.ps1"), build.rs:74: "assets/completions/bat.zsh.in", build.rs:75: out_dir.join("assets/completions/bat.zsh"), build.rs:89:// const BIN_NAME: &str = "bat"; .git/info/refs:21:b41fb0df6cf831081754c27a4c33227c166eee69 refs/heads/bat-0.16-updates .git/info/refs:22:b5a40d0866e6a190fbee095ac104fdc6ec168d0a refs/heads/bat-0.18.2-release .git/info/refs:23:fa0d448cd3e652ffd3c5caa4caa4bdbe2973241c refs/heads/bat-config-file .git/info/refs:24:27516c6f26dc1319dc2516e7caf1aafbe8d30aa0 refs/heads/bat-diagnostic-option .git/info/refs:25:cd501edcbded4dc344e0a0478472b0a4819c2251 refs/heads/bat-diff .git/info/refs:26:d77742b2e425cd76e2ca90a75efba4205e280859 refs/heads/bat-diff-fixes .git/info/refs:215:f1f8807a38052c8138c6f8d1b3bf125e30588712 refs/remotes/origin/bat-v0.18.3-candidate .git/FETCH_HEAD:1:619cf6e6d6641dbb913dddd56907a54c6a9f6ce6 branch 'master' of https://github.com/sharkdp/bat .git/FETCH_HEAD:2:8244eb8ef88cc1b64d27991d6a5c7c69586b8a13 not-for-merge branch 'ci-experiment' of https://github.com/sharkdp/bat .git/FETCH_HEAD:3:271842d87c816cb80dc0a1c48eefee99c9439db6 not-for-merge branch 'create_highlighted_versions-wrong-path-repro' of https://github.com/sharkdp/bat .git/FETCH_HEAD:4:c42ec074ea6accdc38b8d9278bc3810343e2d1a3 not-for-merge branch 'dependabot/submodules/assets/syntaxes/02_Extra/PowerShell-742f0b5' of https://github.com/sharkdp/bat .git/FETCH_HEAD:5:fb9c30b1f7ff648d8aa8fb35a8ff669513c8e91f not-for-merge branch 'dependabot/submodules/assets/syntaxes/02_Extra/SCSS_Sass-d3d9404' of https://github.com/sharkdp/bat .git/FETCH_HEAD:6:179d905bb92eee7272cf6fbb38db88f9294df94a not-for-merge branch 'dependabot/submodules/assets/syntaxes/02_Extra/TypeScript-ba45efd' of https://github.com/sharkdp/bat .git/FETCH_HEAD:7:b146958ecbb8c8c926159509ca7fb32a8573f897 not-for-merge branch 'release-v0.18.3' of https://github.com/sharkdp/bat .git/logs/HEAD:14:a946f3ae23e7d6d9aa6361c034e9b62859b4dbff e92e13cd4332196617df7a07bc6c55d1fd4834bb David Peter 1631038809 +0200 rebase (continue) (pick): Use BAT_CONFIG_DIR and BAT_CACHE_PATH .git/modules/assets/themes/Coldark/FETCH_HEAD:1:e44750b2a9629dd12d8ed3ad9fd50c77232170b9 not-for-merge branch 'master' of https://github.com/ArmandPhilippot/coldark-bat .git/modules/assets/themes/Coldark/logs/refs/heads/master:1:0000000000000000000000000000000000000000 b4a1c74d8d5bdd136ec530e5905b810272472545 sharkdp 1603543180 +0200 clone: from https://github.com/ArmandPhilippot/coldark-bat.git .git/modules/assets/themes/Coldark/logs/refs/remotes/origin/HEAD:1:0000000000000000000000000000000000000000 b4a1c74d8d5bdd136ec530e5905b810272472545 sharkdp 1603543180 +0200 clone: from https://github.com/ArmandPhilippot/coldark-bat.git .git/modules/assets/themes/Coldark/logs/HEAD:1:0000000000000000000000000000000000000000 b4a1c74d8d5bdd136ec530e5905b810272472545 sharkdp 1603543180 +0200 clone: from https://github.com/ArmandPhilippot/coldark-bat.git .git/modules/assets/themes/Coldark/config:8: url = https://github.com/ArmandPhilippot/coldark-bat.git .git/modules/assets/themes/gruvbox/FETCH_HEAD:1:64c47250e54298b91e2cf8d401320009aba9f991 not-for-merge branch 'bat-source' of https://github.com/subnut/gruvbox-tmTheme .git/packed-refs:22:b41fb0df6cf831081754c27a4c33227c166eee69 refs/heads/bat-0.16-updates .git/packed-refs:23:b5a40d0866e6a190fbee095ac104fdc6ec168d0a refs/heads/bat-0.18.2-release .git/packed-refs:24:fa0d448cd3e652ffd3c5caa4caa4bdbe2973241c refs/heads/bat-config-file .git/packed-refs:25:27516c6f26dc1319dc2516e7caf1aafbe8d30aa0 refs/heads/bat-diagnostic-option .git/packed-refs:26:cd501edcbded4dc344e0a0478472b0a4819c2251 refs/heads/bat-diff .git/packed-refs:27:d77742b2e425cd76e2ca90a75efba4205e280859 refs/heads/bat-diff-fixes .git/packed-refs:216:f1f8807a38052c8138c6f8d1b3bf125e30588712 refs/remotes/origin/bat-v0.18.3-candidate .git/config:7: url = https://github.com/sharkdp/bat.git .git/config:13: slug = sharkdp/bat .git/config:143:[branch "bat-config-file"] .git/config:145: merge = refs/heads/bat-config-file .git/config:176:[branch "bat-diff"] .git/config:178: merge = refs/heads/bat-diff .git/config:228: remote = git@github.com:lavifb/bat.git .git/config:231: url = https://github.com/lavifb/bat .git/config:234: remote = git@github.com:majecty/bat.git .git/config:237: url = https://github.com/majecty/bat .git/config:246: remote = git@github.com:reidwagner/bat.git .git/config:315: remote = git@github.com:hrlmartins/bat.git .git/config:369: remote = git@github.com:fvictorio/bat.git .git/config:378: remote = git@github.com:eth-p/bat.git .git/config:387: remote = git@github.com:Kogia-sima/bat.git .git/config:426: remote = git@github.com:neuronull/bat.git .git/config:429: remote = git@github.com:jmick414/bat.git .git/config:435: remote = git@github.com:dtolnay/bat.git .git/config:441: remote = git@github.com:eth-p/bat.git .git/config:444: remote = git@github.com:neuronull/bat.git .git/config:482:[branch "bat-diff-fixes"] .git/config:484: merge = refs/heads/bat-diff-fixes .git/config:486: remote = git@github.com:lzutao/bat.git .git/config:507: remote = git@github.com:eth-p/bat.git .git/config:510: remote = git@github.com:eth-p/bat.git .git/config:513: remote = git@github.com:kopecs/bat.git .git/config:516: remote = git@github.com:eth-p/bat.git .git/config:540: remote = git@github.com:rxt1077/bat.git .git/config:558: remote = git@github.com:alexnovak/bat.git .git/config:561: remote = git@github.com:guidocella/bat.git .git/config:564: remote = git@github.com:gsomix/bat.git .git/config:567: remote = git@github.com:caioalonso/bat.git .git/config:579: remote = git@github.com:mk12/bat.git .git/config:585: remote = git@github.com:kjmph/bat.git .git/config:591: remote = git@github.com:Kienyew/bat.git .git/config:603: remote = git@github.com:alexanderkarlis/bat.git .git/config:609: remote = git@github.com:ahmedelgabri/bat.git .git/config:615: remote = git@github.com:Kienyew/bat.git .git/config:618: remote = git@github.com:eth-p/bat.git .git/config:620:[branch "bat-0.16-updates"] .git/config:622: merge = refs/heads/bat-0.16-updates .git/config:624: remote = git@github.com:henil/bat.git .git/config:627: remote = git@github.com:AkshatGadhwal/bat.git .git/config:633: remote = git@github.com:loganintech/bat.git .git/config:639: remote = git@github.com:mzegar/bat.git .git/config:642: remote = git@github.com:AkshatGadhwal/bat.git .git/config:645: remote = git@github.com:AkshatGadhwal/bat.git .git/config:651: remote = git@github.com:jacobmischka/bat.git .git/config:657: url = https://github.com/forkeith/bat.git .git/config:660: remote = git@github.com:ArmandPhilippot/bat.git .git/config:664: url = https://github.com/ArmandPhilippot/coldark-bat.git .git/config:666: remote = git@github.com:adrian-rivera/bat.git .git/config:669: remote = git@github.com:eth-p/bat.git .git/config:681: remote = git@github.com:MarcoIeni/bat.git .git/config:690: remote = git@github.com:Enselic/bat.git .git/config:696: remote = git@github.com:stku1985/bat.git .git/config:699: remote = git@github.com:mk12/bat.git .git/config:702: remote = git@github.com:j0hnmeow/bat.git .git/config:708: remote = git@github.com:Enselic/bat.git .git/config:713:[branch "bat-diagnostic-option"] .git/config:715: merge = refs/heads/bat-diagnostic-option .git/config:717: url = https://github.com/niklasmohrin/bat.git .git/config:723: remote = git@github.com:paulsmith/bat.git .git/config:735: remote = git@github.com:Enselic/bat.git .git/config:762: remote = git@github.com:Enselic/bat.git .git/config:771: remote = git@github.com:brightly-salty/bat.git .git/config:774: remote = git@github.com:eth-p/bat.git .git/config:804: remote = git@github.com:matklad/bat.git .git/config:827:[branch "bat-0.18.2-release"] .git/config:829: merge = refs/heads/bat-0.18.2-release .git/config:831: remote = git@github.com:Enselic/bat.git .git/config:834: remote = git@github.com:steffahn/bat.git .git/config:837: remote = git@github.com:SarveshMD/bat.git .git/config:840: remote = git@github.com:Enselic/bat.git .git/config:852: remote = git@github.com:Enselic/bat.git .git/config:861: remote = git@github.com:bojan88/bat.git .git/config:870: remote = git@github.com:Enselic/bat.git .git/config:882: remote = git@github.com:Enselic/bat.git CHANGELOG.md:6:- `$BAT_CONFIG_DIR` is now a recognized environment variable. It has precedence over `$XDG_CONFIG_HOME`, see #1727 (@billrisher) CHANGELOG.md:25:- Include git hash in `bat -V` and `bat --version` output if present. See #1921 (@Enselic) CHANGELOG.md:42:## `bat` as a library CHANGELOG.md:45:- Remove `HighlightingAssets::from_files` and `HighlightingAssets::save_to_cache`. Instead of calling the former and then the latter you now make a single call to `bat::assets::build`. See #1802 (@Enselic) CHANGELOG.md:67:- Fix for a security vulnerability on Windows. Prior to this release, `bat` would execute programs called `less`/`less.exe` from the current working directory (instead of the one from `PATH`) with priority. An attacker might be able to use this by placing a malicious program in a shared directory where the user would execute `bat`. `bat` users on Windows are advised to upgrade to this version. See #1724 and #1472 (@Ry0taK). CHANGELOG.md:92:- The `LESS` environment variable is now included in `bat --diagnostic`, see #1589 (@Enselic) CHANGELOG.md:98:- Replaced "Advanced CSV" with a custom CSV syntax definition written especially for `bat`; see #1574 (@keith-hall) CHANGELOG.md:112:- Use a pager when `bat --list-languages` is called, see #1394 (@stku1985) CHANGELOG.md:117:- Only print themes hint in interactive mode (`bat --list-themes`), see #1439 (@rsteube) CHANGELOG.md:122:- If `PAGER` (but not `BAT_PAGER` or `--pager`) is `more` or `most`, silently use `less` instead to ensure support for colors, see #1063 (@Enselic) CHANGELOG.md:123:- If `PAGER` is `bat`, silently use `less` to prevent recursion. For `BAT_PAGER` or `--pager`, exit with error, see #1413 (@Enselic) CHANGELOG.md:125:- `BAT_CONFIG_PATH` ignored by `bat` if non-existent, see #1550 (@sharkdp) CHANGELOG.md:147:## `bat` as a library CHANGELOG.md:160:- Running `bat` without arguments fails ("output file is also an input"), see #1396 CHANGELOG.md:168:- Pass `-S` ("chop long lines") to `less` if `--wrap=never` is set in `bat`, see #1255 (@gahag) CHANGELOG.md:173:- Throw an error when `bat` is being used as `pager`, see #1343 (@adrian-rivera) CHANGELOG.md:225:## `bat` as a library CHANGELOG.md:246:- Cannot run `bat` with relative paths, see #1022 CHANGELOG.md:247:- bat mishighlights Users that start with digits in SSH config, see #984 CHANGELOG.md:268:- bat now prints an error if an invalid syntax is specified via `-l` or `--map-syntax`, see #1004 (@eth-p) CHANGELOG.md:270:## `bat` as a library CHANGELOG.md:276:- Compilation problems with `onig_sys` on various platforms have been resolved by upgrading to `syntect 4.2`, which includes a new `onig` version that allows to build `onig_sys` without the `bindgen` dependency. This removes the need for `libclang(-dev)` to be installed to compile `bat`. Package maintainers might want to remove `clang` as a build dependency. See #650 for more details. CHANGELOG.md:284: Users suffering from #865 ("no color for bat in ssh from a Windows client") can use the `ansi-dark` and `ansi-light` themes from now on. CHANGELOG.md:303:- Performance improvements when using custom caches (via `bat cache --build`): the `bat` startup time should now be twice as fast (@lzutao). CHANGELOG.md:309:## `bat` as a library CHANGELOG.md:320: in the header. This is useful when piping input into `bat`. See #654 and #892 (@neuronull). CHANGELOG.md:336:- When saving/reading user-provided syntaxes or themes, `bat` will now maintain a CHANGELOG.md:337: `metadata.yaml` file which includes information about the `bat` version which was CHANGELOG.md:342:## `bat` as a library CHANGELOG.md:346: API is still available (basically everything that is not in the root `bat` CHANGELOG.md:349: Note that this should still be considered a "beta" release of `bat`-as-a-library. CHANGELOG.md:354: everything required by `bat` the application. When depending on bat as a library, downstream CHANGELOG.md:358: bat = { version = "0.14", default-features = false } CHANGELOG.md:371:## `bat` as a library CHANGELOG.md:373:Beginning with this release, `bat` can be used as a library (#423). CHANGELOG.md:378:- Second attempt, complete restructuring of the `bat` crate, see #679 (@DrSensor) CHANGELOG.md:383:That being said, you can start using it! See the example programs in [`examples/`](https://github.com/sharkdp/bat/tree/master/examples). CHANGELOG.md:385:You can see the API documentation here: https://docs.rs/bat/ CHANGELOG.md:390: users need to update their bat config files (`bat --config-file`), if they have any `--map-syntax` settings CHANGELOG.md:407:- `BAT_CACHE_PATH` can be used to place cached `bat` assets in a non-standard path, see #829 (@neuronull) CHANGELOG.md:413:- 'bat cache' still takes precedence over existing files, see #666 (@sharkdp) CHANGELOG.md:425:- Enabled LTO, making `bat` about 10% faster, see #719 (@bolinfest, @sharkdp) CHANGELOG.md:426:- Suggestions non how to configure `bat` for MacOS dark mode, see README (@jerguslejko) CHANGELOG.md:427:- Extended ["Integration with other tools"](https://github.com/sharkdp/bat#integration-with-other-tools) section (@eth-p) CHANGELOG.md:428:- Updated [instrutions on how to use `bat` as a `man`-pager](https://github.com/sharkdp/bat#man), see #652, see #667 (@sharkdp) CHANGELOG.md:456:- `bat` is now in the official Ubuntu and Debian repositories, see #323 and #705 (@MarcoFalke) CHANGELOG.md:457:- `bat` can now be installed via MacPorts, see #675 (@bn3t) CHANGELOG.md:476:- Binary file content can now be viewed with `bat -A`, see #623, #640 (@pjsier and @sharkdp) CHANGELOG.md:477:- `bat` can now be used as a man pager. Take a look at the README and #523 for more details. CHANGELOG.md:506:- `bat` is now in the official Gentoo repositories, see #588 (@toku-sa-n) CHANGELOG.md:507:- `bat` is now in the official Alpine Linux repositories, see #586 (@5paceToast) CHANGELOG.md:508:- `bat` is in the official Fedora repositories, see #610 (@ignatenkobrain) CHANGELOG.md:534:- New ["Integration with other tools"](https://github.com/sharkdp/bat#integration-with-other-tools) section in the README. CHANGELOG.md:544:- `bat` is now available on Chocolatey, see #541 (@rasmuskriest) CHANGELOG.md:554:- **Change the default configuration directory on macOS** to `~/.config/bat`, see #442 (@lavifb). If you are on macOS, you need to copy your configuration directory from the previous place (`~/Library/Preferences/bat`) to the new place (`~/.config/bat`). CHANGELOG.md:559:- Rename `bat cache --init` to `bat cache --build`, see #498 CHANGELOG.md:560:- Move the `--config-dir` and `--cache-dir` options from `bat cache` to `bat` and hide them from the help text. CHANGELOG.md:596:- Added `BAT_CONFIG_PATH` environment variable to set a non-default path for `bat`s configuration file, see #375 (@deg4uss3r) CHANGELOG.md:618:- Avoid endless recursion when `PAGER="bat"`, see #383 (@rodorgas) CHANGELOG.md:622:- `bat` is now available on openSUSE, see #405 (@dmarcoux) CHANGELOG.md:651: The configuration file path can be accessed via `bat --config-file`. On Linux, CHANGELOG.md:652: it is stored in `~/.config/bat/config`. CHANGELOG.md:654:- Support for the `BAT_OPTS` environment variable with the same format as specified CHANGELOG.md:664: bat --map-syntax .config:json ... CHANGELOG.md:667: The option can be use multiple times. Note that you can easily make these mappings permanent by using bats new configuration file. CHANGELOG.md:671:- Support pager command-line arguments in `PAGER` and `BAT_PAGER`, see #352 (@Foxboron) CHANGELOG.md:689:- Bat Panics on Haskell Source Code, see #314 CHANGELOG.md:695:- Updated documentation on how to configure `bat`s pager CHANGELOG.md:703:- `bat` is now available via [Termux](https://termux.com/), see #341 (@fornwall) CHANGELOG.md:705:- `bat` is now available via [nix](https://nixos.org/nix), see #344 (@mgttlinger) CHANGELOG.md:707:- `bat` is now available via [Docker](https://hub.docker.com/r/danlynn/bat/), see #331 (@danlynn) CHANGELOG.md:717:- Bat Panics on Haskell Source Code, see #314 CHANGELOG.md:730: `--tabs` command-line option or the `BAT_TABS` environment variable. The CHANGELOG.md:733:- Added support for the `BAT_STYLE` environment variable, see #208 (@ms2300) CHANGELOG.md:764:- Added README section about "`bat` on Windows" (@Aankhen) CHANGELOG.md:772:- Fixed panic when running `bat --list-languages | head`, see #232 (@mchlrhw) CHANGELOG.md:786:- Major refactorings, enabling some progress on #150. In non-interactive mode, `bat` will now copy input bytes 1:1. CHANGELOG.md:792:- New themes in `$BAT_CONFIG_DIR/themes` are now loaded *in addition* to CHANGELOG.md:798:* Using `bat cache --init` leads to duplicated syntaxes, see #206 CHANGELOG.md:811:- The syntax highlighting theme can now be controlled by the `BAT_THEME` environment variable, see [README](https://github.com/sharkdp/bat#highlighting-theme) and #177 (@mandx) CHANGELOG.md:812:- The `PAGER` and `BAT_PAGER` environment variables can be used to control the pager that `bat` uses, see #158 and the [new README section](https://github.com/sharkdp/bat#using-a-different-pager) CHANGELOG.md:818:- The customization of syntax sets and theme sets is now separated. Syntax definitions are now loaded *in addition* to the ones that are stored in the `bat` binary by default. Please refer to these new sections in the README: [Adding new syntaxes](https://github.com/sharkdp/bat#adding-new-syntaxes--language-definitions), [Adding new themes](https://github.com/sharkdp/bat#adding-new-themes), also see #172 CHANGELOG.md:830:- `bat` is now in the official [Arch package repositories](https://www.archlinux.org/packages/community/x86_64/bat/). CHANGELOG.md:839:- Fix problem with `cargo test` when `bat` is not checked out in a Git repository, see #161 CHANGELOG.md:874:- [Comparison with alternative projects](https://github.com/sharkdp/bat/blob/master/doc/alternatives.md). CHANGELOG.md:875:- New "bat" logo in the README, see #119 (@jraulhernandezi) CHANGELOG.md:895: `bat cache`. See `bat cache -h` for all available commands. CHANGELOG.md:900:* Process substitution can now be used with bat (`bat <(echo a) <(echo b)`), see #80 CHANGELOG.md:912:- Added a new statically linked version of bat (`..-musl-..`) CONTRIBUTING.md:3:Thank you for considering to contribute to `bat`! CONTRIBUTING.md:9:If your contribution changes the behavior of `bat` (as opposed to a typo-fix CONTRIBUTING.md:12:therefore helps to get your changes into a new `bat` release faster. CONTRIBUTING.md:28:Please check out the [Development](https://github.com/sharkdp/bat#development) CONTRIBUTING.md:35:[feature request ticket](https://github.com/sharkdp/bat/issues/new?assignees=&labels=feature-request&template=feature_request.md) CONTRIBUTING.md:42:the [Customization](https://github.com/sharkdp/bat#customization) section CONTRIBUTING.md:47:[documentation](https://github.com/sharkdp/bat/blob/master/doc/assets.md) Cargo.toml:5:homepage = "https://github.com/sharkdp/bat" Cargo.toml:7:name = "bat" Cargo.toml:8:repository = "https://github.com/sharkdp/bat" Cargo.toml:16:# Feature required for bat the application. Should be disabled when depending on Cargo.toml:17:# bat as a library. Cargo.toml:40:# You need to use one of these if you depend on bat as a library: doc/fzf-preview.sh:6: bat \ doc/preview.sh:47:bat --color always \ doc/assets.md:3:Should you find that a particular syntax is not available within `bat` and think it should be included in `bat` by default, you can follow the instructions outlined below. doc/assets.md:5:`bat` uses the excellent [syntect](https://github.com/trishume/syntect) library to highlight source doc/assets.md:20:3. Run the `assets/create.sh` script. It calls `bat cache --build` to parse all available doc/assets.md:23:4. Re-compile `bat`. At compilation time, the `syntaxes.bin` file will be stored inside the doc/assets.md:24: `bat` binary. doc/assets.md:26:5. Use `bat --list-languages` to check if the new languages are available. doc/assets.md:31: file. A new binary cache file will be created once before every new release of `bat`. This doc/assets.md:36:`bat` has a set of syntax highlighting regression tests in `tests/syntax-tests`. The main idea is doc/assets.md:38:for some language is suddenly not working anymore or (2) `bat` suddenly crashes for some input (due doc/assets.md:43:1. Make sure that you are running the **latest version of `bat`** and that `bat` is available on doc/assets.md:45: your version of `bat` already has the new syntax builtin. doc/assets.md:50: be `test.rb` (adapt extension) but can also be adapted if that is necessary in order for `bat` to doc/assets.md:53: under the respective license and that the license is compatible with `bat`s license. If it doc/assets.md:62:6. Use `cat` or `bat --language=txt` to display the content of this file and make sure that the doc/assets.md:70:themes (`bat cache --clear`). doc/README-ja.md:2: bat - a cat clone with wings
doc/README-ja.md:3: Build Status doc/README-ja.md:4: license doc/README-ja.md:5: Version info
doc/README-ja.md:16: [中文] doc/README-ja.md:24:`bat` は多くのプログラミング言語やマークアップ言語の doc/README-ja.md:31:`bat` は `git` とも連携しており、差分を表現する記号が表示されます doc/README-ja.md:45:出力が1つの画面に対して大きすぎる場合、`bat` は自身の出力をページャー(例えば `less`) にパイプで繋げます。 doc/README-ja.md:50:`bat` は非対話型のターミナルを検出すると(すなわち他のプロセスにパイプしたりファイル出力していると)、 doc/README-ja.md:51:`bat` は `cat` の完全互換として振る舞い、 doc/README-ja.md:59:> bat README.md doc/README-ja.md:65:> bat src/*.rs doc/README-ja.md:73:> curl -s https://sh.rustup.rs | bat doc/README-ja.md:79:> yaml2json .travis.yml | json_pp | bat -l json doc/README-ja.md:84:> bat -A /etc/hosts doc/README-ja.md:87:`cat` の代わりに `bat` を使用する際の例: doc/README-ja.md:90:bat > note.md # quickly create a new file doc/README-ja.md:92:bat header.md content.md footer.md > document.md doc/README-ja.md:94:bat -n main.rs # show line numbers (only) doc/README-ja.md:96:bat f - g # output 'f', then stdin, then 'g'. doc/README-ja.md:103:[`fzf`](https://github.com/junegunn/fzf) のプレビューウィンドウに `bat` を使用できます。 doc/README-ja.md:104:その場合、`bat` の `--color=always` オプションを用いてカラー出力を強制しなければなりません。 doc/README-ja.md:107:fzf --preview 'bat --color=always --style=numbers --line-range=:500 {}' doc/README-ja.md:114:`find` の `-exec` オプションを使用して、`bat` ですべての検索結果をプレビューできます: doc/README-ja.md:116:find … -exec bat {} + doc/README-ja.md:119:[`fd`](https://github.com/sharkdp/fd) を使用している場合は、`-X` /`-exec-batch` オプションを使用して同じことを行うことができます: doc/README-ja.md:121:fd … -X bat doc/README-ja.md:126:[`batgrep`](https://github.com/eth-p/bat-extras/blob/master/doc/batgrep.md) では、[`ripgrep`](https://github.com/BurntSushi/ripgrep) 検索結果のプリンターとして `bat` を使用できます。 doc/README-ja.md:129:batgrep needle src/ doc/README-ja.md:134:`bat` を `tail -f` と組み合わせて、構文強調表示を使用して特定のファイルを継続的に監視できます。 doc/README-ja.md:136:tail -f /var/log/pacman.log | bat --paging=never -l log doc/README-ja.md:142:`bat` を `git show` と組み合わせて、 doc/README-ja.md:145:git show v0.6.0:src/main.rs | bat -l rs doc/README-ja.md:152:`bat` の出力の行番号と Git 変更マーカーにより、ファイルの内容をコピーするのが難しくなる場合があります。 doc/README-ja.md:153:これを防ぐには、`-p` / `-plain` オプションを使用して `bat` を呼び出すか、 doc/README-ja.md:156:bat main.cpp | xclip doc/README-ja.md:158:`bat` は出力がリダイレクトされていることを検出し、プレーンファイルの内容を出力します。 doc/README-ja.md:162:`bat` は `MANPAGER` 環境変数を設定することにより、 doc/README-ja.md:166:export MANPAGER="sh -c 'col -bx | bat -l man -p'" doc/README-ja.md:173:これを新しいコマンドにバンドルしたい場合は [`batman`](https://github.com/eth-p/bat-extras/blob/master/doc/batman.md) も使用できます。 doc/README-ja.md:179:[`prettybat`](https://github.com/eth-p/bat-extras/blob/master/doc/prettybat.md) スクリプトは、コードをフォーマットし、`bat` で印刷するラッパーです。 doc/README-ja.md:184:[![Packaging status](https://repology.org/badge/vertical-allrepos/bat.svg)](https://repology.org/project/bat/versions) doc/README-ja.md:189:Ubuntu Eoan 19.10 または Debian 不安定版 sid 以降の [the Ubuntu `bat` package](https://packages.ubuntu.com/eoan/bat) または [the Debian `bat` package](https://packages.debian.org/sid/bat) からインストールできます: doc/README-ja.md:192:apt install bat doc/README-ja.md:195:`apt` を使用して `bat` をインストールした場合、実行可能ファイルの名前が `bat` ではなく `batcat` になることがあります([他のパッケージとの名前衝突のため](https://github.com/sharkdp/bat/issues/982))。`bat -> batcat` のシンボリックリンクまたはエイリアスを設定することで、実行可能ファイル名が異なることによる問題の発生を防ぎ、他のディストリビューションと一貫性を保てます。 doc/README-ja.md:199:ln -s /usr/bin/batcat ~/.local/bin/bat doc/README-ja.md:205:batの最新リリースを実行する場合、または Ubuntu/Debian の古いバージョンを使用している場合は、[release page](https://github.com/sharkdp/bat/releases) から最新の `.deb` パッケージをダウンロードし、 doc/README-ja.md:208:sudo dpkg -i bat_0.18.3_amd64.deb # adapt version number and architecture doc/README-ja.md:214:公式のソースから [`bat` package](https://pkgs.alpinelinux.org/packages?name=bat) をインストールできます: doc/README-ja.md:217:apk add bat doc/README-ja.md:222:[Arch Linuxの公式リソース](https://www.archlinux.org/packages/community/x86_64/bat/) doc/README-ja.md:226:pacman -S bat doc/README-ja.md:231:公式の [Fedora Modular](https://docs.fedoraproject.org/en-US/modularity/using-modules/) リポジトリから [the `bat` package](https://koji.fedoraproject.org/koji/packageinfo?packageID=27506) をインストールできます。 doc/README-ja.md:234:dnf install bat doc/README-ja.md:240:[the `bat` package](https://packages.gentoo.org/packages/sys-apps/bat) をインストールできます。 doc/README-ja.md:243:emerge sys-apps/bat doc/README-ja.md:248:xbps-install経由で `bat` をインストールできます。 doc/README-ja.md:250:xbps-install -S bat doc/README-ja.md:255:pkg を使用してプリコンパイルされた [`bat` package](https://www.freshports.org/textproc/bat) をインストールできます: doc/README-ja.md:258:pkg install bat doc/README-ja.md:264:cd /usr/ports/textproc/bat doc/README-ja.md:270:`bat` を [nix package manager](https://nixos.org/nix) 経由でインストールすることができます: doc/README-ja.md:273:nix-env -i bat doc/README-ja.md:278:`bat` をzypperでインストールすることができます: doc/README-ja.md:281:zypper install bat doc/README-ja.md:286:[Homebrew](http://braumeister.org/formula/bat)で `bat` をインストールできます: doc/README-ja.md:289:brew install bat doc/README-ja.md:292:または [MacPorts](https://ports.macports.org/port/bat/summary) で `bat` をインストールします: doc/README-ja.md:295:port install bat doc/README-ja.md:300:Windowsにbatをインストールするいくつかのオプションがあります。 doc/README-ja.md:301:batをインストールしたら [Windowsでのbatの使用](#windows-での-bat-の利用) セクションをご覧ください。 doc/README-ja.md:305:[Chocolatey](https://chocolatey.org/packages/Bat) から `bat` をインストールできます: doc/README-ja.md:307:choco install bat doc/README-ja.md:312:[scoop](https://scoop.sh/) から `bat` をインストールできます: doc/README-ja.md:314:scoop install bat doc/README-ja.md:321:[リリースページ](https://github.com/sharkdp/bat/releases) からビルド済みのバイナリをダウンロードできます。 doc/README-ja.md:327:コンテナ内で `bat` を使いたい方のために [Docker image](https://hub.docker.com/r/danlynn/bat/) が用意されています: doc/README-ja.md:329:docker pull danlynn/bat doc/README-ja.md:330:alias bat='docker run -it --rm -e BAT_THEME -e BAT_STYLE -e BAT_TABS -v "$(pwd):/myapp" danlynn/bat' doc/README-ja.md:339:ansible-galaxy install aeimer.install_bat doc/README-ja.md:344:# Playbook to install bat doc/README-ja.md:347: - aeimer.install_bat doc/README-ja.md:350:- [Ansible Galaxy](https://galaxy.ansible.com/aeimer/install_bat) doc/README-ja.md:351:- [GitHub](https://github.com/aeimer/ansible-install-bat) doc/README-ja.md:364:多くの異なるアーキテクチャのためのプレビルドバージョンを[リリースページ](https://github.com/sharkdp/bat/releases)からチェックしてみてください。静的にリンクされている多くのバイナリも利用できます: ファイル名に `musl` を含むアーカイブを探してみてください。 doc/README-ja.md:369:`bat` をソースからビルドしたいならば、Rust 1.36 以上の環境が必要です。 doc/README-ja.md:373:cargo install --locked bat doc/README-ja.md:382:`bat --list-themes` を使うと現在利用可能なシンタックスハイライトのテーマを入手できます。 doc/README-ja.md:384:`--theme=TwoDark` オプションをつけるか `BAT_THEME` という環境変数に doc/README-ja.md:385:`TwoDark` を代入する必要があります。 シェルの起動ファイルに `export BAT_THEME="TwoDark"` doc/README-ja.md:386:と定義すればその設定が変わることはないでしょう。あるいは、 `bat` の doc/README-ja.md:392:bat --list-themes | fzf --preview="bat --theme={} --color=always /path/to/file" doc/README-ja.md:395:`bat` はデフォルトだと黒い背景色のターミナルに適しています。 doc/README-ja.md:402:`--style` を使うことで `bat` の表示の見た目を変更することができます。 doc/README-ja.md:405:環境変数に `BAT_STYLE` を定義するとこれらの設定を永続的に使用することができます。 doc/README-ja.md:410:`bat` はシンタックスハイライトのための [`syntect`](https://github.com/trishume/syntect/) doc/README-ja.md:418:mkdir -p "$(bat --config-dir)/syntaxes" doc/README-ja.md:419:cd "$(bat --config-dir)/syntaxes" doc/README-ja.md:429:bat cache --build doc/README-ja.md:432:最後に `bat --list-languages` と入力すると新しい言語が利用可能かどうかチェックします。 doc/README-ja.md:437:bat cache --clear doc/README-ja.md:446:mkdir -p "$(bat --config-dir)/themes" doc/README-ja.md:447:cd "$(bat --config-dir)/themes" doc/README-ja.md:453:bat cache --build doc/README-ja.md:456:最後に、 `bat --list-themes` で新しいテーマが利用可能かチェックします doc/README-ja.md:460:`bat` は環境変数 `PAGER` に使用するページャーを明記します。 doc/README-ja.md:463:または、`PAGER` を上書きする環境変数として `BAT_PAGER` を定義することも可能です。 doc/README-ja.md:466:`PAGER`/`BAT_PAGER` 環境変数を定義してください: doc/README-ja.md:469:export BAT_PAGER="less -RF" doc/README-ja.md:472:環境変数を利用する代わりに、 `bat` の [設定ファイル](#設定ファイル) を使用して設定も可能です(`--pager` オプション) doc/README-ja.md:475:`bat` はページャーの以下のコマンドラインオプション を受け付けるでしょう: doc/README-ja.md:491:macOSでダークモード機能を使用する場合、OSテーマに基づいて異なるテーマを使用するように `bat` を構成することができます。 doc/README-ja.md:496:alias cat="bat --theme=\$(defaults read -globalDomain AppleInterfaceStyle &> /dev/null && echo default || echo GitHub)" doc/README-ja.md:501:`bat` は設定ファイルでカスタマイズすることが可能です。ファイルの場所はOSに依存します。 doc/README-ja.md:504:bat --config-file doc/README-ja.md:507:または、`BAT_CONFIG_PATH` 環境変数を使用して、`bat` が doc/README-ja.md:510:export BAT_CONFIG_PATH="/path/to/bat.conf" doc/README-ja.md:515:この設定ファイルはコマンドライン引数の単純なリストです。 `bat --help` を利用すると、利用可能なオプションとその値を閲覧することができます。さらに、`#` でコメント文を加えることができます。 doc/README-ja.md:535:## Windows での `bat` の利用 doc/README-ja.md:537:Windows 上で `bat` はほとんど動作しますが、いくつかの機能は設定を必要をする場合があります。 doc/README-ja.md:555:`BAT_PAGER` に空文字を設定することでページングを完全に無効にできます。 doc/README-ja.md:559:Windows上の `bat` は Cygwin のunix風のpath(`/cygdrive/*`)をネイティブサポートしていません。絶対的なcygwinパスを引数として受けたときに、 `bat` は以下のエラーを返すでしょう: `The system cannot find the path specified. (os error 3)` doc/README-ja.md:564:bat() { doc/README-ja.md:573: command bat "${args[@]}" doc/README-ja.md:581:`bat` はターミナルがトゥルーカラーをサポートしている/していないに関係なくサポートします。 doc/README-ja.md:588:`24bit` のどちらかを代入してください。さもなければ、`bat` はどの色を使うのか決定することができません。または、24-bit エスケープシーケンスがサポートされません doc/README-ja.md:593:異なるテーマを試してみてください(`bat --list-themes` でテーマを閲覧できます)。 doc/README-ja.md:598:`bat` は UTF-16 と同様に UTF-8 をネイティブにサポートします。 doc/README-ja.md:603:iconv -f ISO-8859-1 -t UTF-8 my-file.php | bat doc/README-ja.md:605:注: `bat` が構文を自動検出できない場合は doc/README-ja.md:612:git clone --recursive https://github.com/sharkdp/bat doc/README-ja.md:615:cd bat doc/README-ja.md:624:# Build a bat binary with modified syntaxes and themes doc/README-ja.md:636:`bat` は以下の目標を達成しようと試みています: doc/README-ja.md:647:Copyright (c) 2018-2021 [bat-developers](https://github.com/sharkdp/bat). doc/README-ja.md:649:`bat` は MIT License 及び Apache License 2.0 の両方の条件の下で配布されています。 doc/README-ko.md:2: bat - a cat clone with wings
doc/README-ko.md:3: Build Status doc/README-ko.md:4: license doc/README-ko.md:5: Version info
doc/README-ko.md:16: [中文] doc/README-ko.md:24:`bat`은 다양한 프로그래밍 및 마크업 언어의 문법 강조(syntax highlighting) 기능을 doc/README-ko.md:31:`bat`은 `git`을 통해 인덱스와 함께 변경분을 표시합니다 doc/README-ko.md:44:`bat`은 기본적으로 한 화면에 비해 출력이 큰 경우 `less`와 같은 페이저(pager)로 doc/README-ko.md:46:만약 `bat`을 언제나 `cat`처럼 작동하게 하려면 (출력을 페이지하지 않기), doc/README-ko.md:48:셸(shell) 설정에서 `cat`을 `bat`의 alias로 사용하려면, doc/README-ko.md:49:`alias cat='bat --paging=never'`를 써서 기본 행동을 유지할 수 있습니다. doc/README-ko.md:53:페이저(pager)를 사용하더라도 `bat`은 파일들을 연결(concatenate)할 수 있습니다 doc/README-ko.md:55:`bat`이 비대화형(non-interactive) 터미널(예를 들어, 다른 프로세스나 파일에 doc/README-ko.md:56:연결(pipe)한 경우)을 감지하면, `bat`은 `--pager` 옵션의 값과 상관없이 `cat`과 doc/README-ko.md:64:> bat README.md doc/README-ko.md:70:> bat src/*.rs doc/README-ko.md:78:> curl -s https://sh.rustup.rs | bat doc/README-ko.md:84:> yaml2json .travis.yml | json_pp | bat -l json doc/README-ko.md:89:> bat -A /etc/hosts doc/README-ko.md:95:bat > note.md # quickly create a new file doc/README-ko.md:97:bat header.md content.md footer.md > document.md doc/README-ko.md:99:bat -n main.rs # show line numbers (only) doc/README-ko.md:101:bat f - g # output 'f', then stdin, then 'g'. doc/README-ko.md:108:`bat`을 [`fzf`](https://github.com/junegunn/fzf)의 프리뷰로 쓸 수 있습니다. doc/README-ko.md:109:이를 위해서는 `bat`의 `--color=always` 옵션으로 항상 컬러 출력이 나오게 해야 doc/README-ko.md:113:fzf --preview 'bat --color=always --style=numbers --line-range=:500 {}' doc/README-ko.md:120:`find`의 `-exec` 옵션을 사용하여 모든 검색 결과를 `bat`로 미리 볼 수 있습니다: doc/README-ko.md:122:find … -exec bat {} + doc/README-ko.md:125:[`fd`](https://github.com/sharkdp/fd)를 사용하는 경우, `-X`/`--exec-batch` doc/README-ko.md:128:fd … -X bat doc/README-ko.md:133:[`batgrep`](https://github.com/eth-p/bat-extras/blob/master/doc/batgrep.md)을 doc/README-ko.md:134:통해 `bat`로 [`ripgrep`](https://github.com/BurntSushi/ripgrep)의 검색 결과를 doc/README-ko.md:138:batgrep needle src/ doc/README-ko.md:143:`bat`와 `tail -f`를 함께 사용하여 주어진 파일을 문법 강조하며 지속적으로 doc/README-ko.md:146:tail -f /var/log/pacman.log | bat --paging=never -l log doc/README-ko.md:154:`bat`과 `git show`를 함께 사용하여 주어진 파일의 이전 버전을 올바른 문법 강조로 doc/README-ko.md:157:git show v0.6.0:src/main.rs | bat -l rs doc/README-ko.md:162:`bat`과 `git diff`를 함께 사용하여 수정된 코드 주위의 줄들을 올바른 문법 강조로 doc/README-ko.md:165:batdiff() { doc/README-ko.md:166: git diff --name-only --diff-filter=d | xargs bat --diff doc/README-ko.md:170:[`bat-extras`](https://github.com/eth-p/bat-extras)의 `batdiff`를 확인해 보세요. doc/README-ko.md:177:`bat` 출력에 줄 번호와 Git 수정 내역이 포함되어서 파일의 내용을 복사하기 doc/README-ko.md:179:이 경우에는 `bat`의 `-p`/`--plain` 옵션을 사용하거나 간단히 `xclip`으로 출력을 doc/README-ko.md:182:bat main.cpp | xclip doc/README-ko.md:184:`bat`는 출력이 우회되고 있다는 것을 감지하여 파일 내용 그대로를 출력합니다. doc/README-ko.md:188:`MANPAGER` 환경 변수 설정을 통해 `bat`을 `man`의 컬러 페이저(pager)로 쓸 수 doc/README-ko.md:192:export MANPAGER="sh -c 'col -bx | bat -l man -p'" doc/README-ko.md:195:(Debian이나 Ubuntu를 사용한다면 `bat`을 `batcat`으로 치환하세요.) doc/README-ko.md:200:[`batman`](https://github.com/eth-p/bat-extras/blob/master/doc/batman.md)을 쓸 doc/README-ko.md:207:[작동하지 않습니다](https://github.com/sharkdp/bat/issues/1145). doc/README-ko.md:211:[`prettybat`](https://github.com/eth-p/bat-extras/blob/master/doc/prettybat.md) doc/README-ko.md:212:스크립트는 코드를 포맷하고 `bat`으로 출력하는 래퍼(wrapper)입니다. doc/README-ko.md:217:[![Packaging status](https://repology.org/badge/vertical-allrepos/bat-cat.svg)](https://repology.org/project/bat-cat/versions) doc/README-ko.md:222:`bat`은 [Ubuntu](https://packages.ubuntu.com/eoan/bat)와 doc/README-ko.md:223:[Debian](https://packages.debian.org/sid/bat) 패키지 배포 과정에 도입되는 중이며, doc/README-ko.md:225:현재 Debain에서는 불안정한 "Sid" 브랜치에서만 `bat`이 제공됩니다. doc/README-ko.md:230:apt install bat doc/README-ko.md:233:**중요**: 만약 `bat`을 이와 같이 설치한다면, ([다른 패키지와의 이름 doc/README-ko.md:234:충돌](https://github.com/sharkdp/bat/issues/982)로 인하여) `bat` 대신에 doc/README-ko.md:235:`batcat`이라는 이름의 실행 파일로 설치될 수 있음을 참고하세요. doc/README-ko.md:236:이에 따른 문제들과 다른 배포판들과의 일관성을 위하여 `bat -> batcat` symlink doc/README-ko.md:240:ln -s /usr/bin/batcat ~/.local/bin/bat doc/README-ko.md:247:`bat`을 원한다면, [릴리즈 페이지](https://github.com/sharkdp/bat/releases)에서 doc/README-ko.md:251:sudo dpkg -i bat_0.18.3_amd64.deb # adapt version number and architecture doc/README-ko.md:257:[`bat` 패키지](https://pkgs.alpinelinux.org/packages?name=bat)를 설치할 수 doc/README-ko.md:261:apk add bat doc/README-ko.md:267:[`bat` 패키지](https://www.archlinux.org/packages/community/x86_64/bat/)를 doc/README-ko.md:271:pacman -S bat doc/README-ko.md:279:[`bat` 패키지](https://koji.fedoraproject.org/koji/packageinfo?packageID=27506)를 doc/README-ko.md:283:dnf install bat doc/README-ko.md:288:dev-kit을 통해 [`bat` 패키지](https://github.com/funtoo/dev-kit/tree/1.4-release/sys-apps/bat)를 설치할 수 있습니다: doc/README-ko.md:291:emerge sys-apps/bat doc/README-ko.md:297:[`bat` 패키지](https://packages.gentoo.org/packages/sys-apps/bat)를 설치할 수 doc/README-ko.md:301:emerge sys-apps/bat doc/README-ko.md:306:xbps-install을 이용해 `bat`을 설치할 수 있습니다: doc/README-ko.md:308:xbps-install -S bat doc/README-ko.md:313:pkg를 이용해 `bat`을 설치할 수 있습니다: doc/README-ko.md:315:pkg install bat doc/README-ko.md:321:[`bat` 패키지](https://www.freshports.org/textproc/bat)를 설치할 수 있습니다: doc/README-ko.md:324:pkg install bat doc/README-ko.md:330:cd /usr/ports/textproc/bat doc/README-ko.md:336:[nix package manager](https://nixos.org/nix)를 이용해 `bat`을 설치할 수 doc/README-ko.md:340:nix-env -i bat doc/README-ko.md:345:zypper를 이용해 `bat`을 설치할 수 있습니다: doc/README-ko.md:348:zypper install bat doc/README-ko.md:355:[문제](https://github.com/sharkdp/bat/issues/1519)가 있을 수 있습니다. doc/README-ko.md:360:[macOS의 Homebrew](https://formulae.brew.sh/formula/bat) 또는 doc/README-ko.md:361:[Linux의 Homebrew](https://formulae.brew.sh/formula-linux/bat)를 이용하여 doc/README-ko.md:362:`bat`을 설치할 수 있습니다. doc/README-ko.md:365:brew install bat doc/README-ko.md:370:[MacPorts](https://ports.macports.org/port/bat/summary)를 이용하여 `bat`을 doc/README-ko.md:374:port install bat doc/README-ko.md:379:Windows에서 `bat`을 설치할 수 있는 몇 가지 옵션들이 있습니다. doc/README-ko.md:380:먼저 `bat`을 설치한 후, doc/README-ko.md:381:["Windows에서 `bat` 사용하기"](#windows에서-bat-사용하기) 섹션을 살펴보세요. doc/README-ko.md:390:[Chocolatey](https://chocolatey.org/packages/Bat)를 이용해 `bat`을 설치할 수 doc/README-ko.md:393:choco install bat doc/README-ko.md:398:[scoop](https://scoop.sh/)을 이용해 `bat`을 설치할 수 있습니다: doc/README-ko.md:400:scoop install bat doc/README-ko.md:405:[릴리즈 페이지](https://github.com/sharkdp/bat/releases)에서 사전 빌드된 doc/README-ko.md:413:[릴리즈 페이지](https://github.com/sharkdp/bat/releases)에서 다양한 아키텍처를 doc/README-ko.md:419:`bat`의 소스를 빌드하기 위해서는, Rust 1.46 이상이 필요합니다. doc/README-ko.md:423:cargo install --locked bat doc/README-ko.md:435:`bat --list-themes`을 사용하여 사용 가능한 문법 강조 테마들의 목록을 확인할 수 doc/README-ko.md:437:`TwoDark` 테마를 선택하려면, `--theme=TwoDark` 옵션과 함께 `bat`을 사용하거나 doc/README-ko.md:438:`BAT_THEME` 환경 변수를 `TwoDark`로 설정하세요. doc/README-ko.md:439:셸 시작 파일에 `export BAT_THEME="TwoDark"` 를 정의해 영구적으로 설정할 수 doc/README-ko.md:441:이 밖에 `bat`의 [설정 파일](#설정-파일)을 이용할 수 있습니다. doc/README-ko.md:447:bat --list-themes | fzf --preview="bat --theme={} --color=always /path/to/file" doc/README-ko.md:450:`bat`은 기본적으로 어두운 배경에 적합합니다. doc/README-ko.md:458:`bat`은 트루컬러 지원이 되더라도 항상 doc/README-ko.md:478:- 만약 터미널 테마를 바꾼다면, 이미 화면 상의 `bat`의 출력도 이에 맞추어 doc/README-ko.md:483:`--style` 옵션을 이용하면 `bat`의 출력 모양을 조절할 수 있습니다. doc/README-ko.md:486:`BAT_STYLE` 환경 변수를 정의하여 이러한 수정을 영구적으로 하거나 `bat`의 doc/README-ko.md:491:만약 `bat`에서 특정 문법이 지원되지 않을 경우, 다음의 절차를 통해 현재 `bat` doc/README-ko.md:494:`bat`은 문법 강조를 위해 훌륭한 doc/README-ko.md:506: mkdir -p "$(bat --config-dir)/syntaxes" doc/README-ko.md:507: cd "$(bat --config-dir)/syntaxes" doc/README-ko.md:517: bat cache --build doc/README-ko.md:520:3. 마지막으로, `bat --list-languages`로 새로 추가한 언어가 사용 가능한지 doc/README-ko.md:526: bat cache --clear doc/README-ko.md:529:4. 만약 특정 문법이 `bat`에 기본적으로 포함되어 있어야 한다고 생각한다면, 방침과 doc/README-ko.md:531: 주세요: [문법 요청하기](https://github.com/sharkdp/bat/issues/new?labels=syntax-request&template=syntax_request.md). doc/README-ko.md:539:mkdir -p "$(bat --config-dir)/themes" doc/README-ko.md:540:cd "$(bat --config-dir)/themes" doc/README-ko.md:546:bat cache --build doc/README-ko.md:549:마지막으로 `bat --list-themes`을 통해 새로 추가한 테마들이 사용 가능한지 doc/README-ko.md:559:(`bat --list-languages`를 통해 개요를 확인하세요). doc/README-ko.md:561:참고: 이 옵션은 커맨드 라인에 넘겨 주는 것보다는 `bat`의 설정 파일에 넣는 것이 doc/README-ko.md:584:`bat`은 환경 변수 `PAGER`에 명시된 페이저를 사용합니다. doc/README-ko.md:586:만약 다른 페이저를 사용하고 싶다면, `PAGER` 변수를 수정하거나 `BAT_PAGER` 환경 doc/README-ko.md:589:만약 커맨드라인 인수들을 페이저에게 넘겨 주려면, `PAGER`/`BAT_PAGER` 변수로 doc/README-ko.md:593:export BAT_PAGER="less -RF" doc/README-ko.md:596:환경 변수를 사용하는 대신, `bat`의 [설정 파일](#설정-파일)로 페이저를 설정할 doc/README-ko.md:600:옵션이 지정되어 있지 않다면), `bat`은 다음 옵션들을 페이저로 넘겨줍니다: doc/README-ko.md:619:`bat`은 페이저에 의존하지 않고 탭을 4 스페이스로 확장합니다. doc/README-ko.md:623:**참고**: (`bat`의 `--pager` 인자 혹은 `less`의 `LESS` 환경 변수를 통해) doc/README-ko.md:627:`bat`을 `--tabs=0`과 함께 호출하면 이를 오버라이드하여 페이저가 탭을 처리하게 doc/README-ko.md:632:macOS에서 다크 모드를 사용하고 있다면, `bat`가 OS 테마에 따라 다른 테마를 doc/README-ko.md:638:alias cat="bat --theme=\$(defaults read -globalDomain AppleInterfaceStyle &> /dev/null && echo default || echo GitHub)" doc/README-ko.md:643:`bat`는 설정 파일로도 사용자화 할 수 있습니다. doc/README-ko.md:647:bat --config-file doc/README-ko.md:650:또는, `BAT_CONFIG_PATH` 환경 변수를 사용하여 `bat`가 설정 파일의 기본 경로 doc/README-ko.md:653:export BAT_CONFIG_PATH="/path/to/bat.conf" doc/README-ko.md:658:bat --generate-config-file doc/README-ko.md:664:`bat --help`로 가능한 모든 옵션과 값들을 확인하세요. doc/README-ko.md:682:## Windows에서 `bat` 사용하기 doc/README-ko.md:684:`bat`는 대부분의 경우 Windows에서 기본적으로 잘 작동하지만, 일부 기능은 추가적인 doc/README-ko.md:715:`BAT_PAGER`을 빈 문자열로 설정하여 페이징을 완전히 비활성화 할 수 있습니다. doc/README-ko.md:719:Windows에서의 `bat`은 기본적으로 Cygwin의 unix 스타일 경로(`/cygdrive/*`)를 doc/README-ko.md:721:Cygwin 절대 경로를 인자로 받았을 때, `bat`은 다음과 같은 오류를 반환합니다: doc/README-ko.md:728:bat() { doc/README-ko.md:737: command bat "${args[@]}" doc/README-ko.md:745:`bat`은 터미널의 트루컬러 지원 여부와 상관 없이 동작합니다. doc/README-ko.md:754:그렇지 않을 경우, `bat`은 24비트 확장열(escape sequence)이 지원되는지 여부를 doc/README-ko.md:759:다른 테마를 사용해 보세요 (`bat --list-themes`에서 목록을 볼 수 있습니다). doc/README-ko.md:764:`bat`은 기본적으로 UTF-8과 UTF-16을 지원합니다. doc/README-ko.md:770:iconv -f ISO-8859-1 -t UTF-8 my-file.php | bat doc/README-ko.md:772:참고: `bat`으로 문법 자동 감지가 되지 않는 경우에는 `-l`/`--language` 옵션을 doc/README-ko.md:779:git clone --recursive https://github.com/sharkdp/bat doc/README-ko.md:782:cd bat doc/README-ko.md:791:# 수정된 문법과 테마가 적용된 bat 바이너리 빌드 doc/README-ko.md:796:`bat`의 pretty-printing 기능을 라이브러리로 사용하는 애플리케이션을 만들고 doc/README-ko.md:797:싶다면, [API 문서](https://docs.rs/bat/)를 살펴보세요. doc/README-ko.md:798:참고로 `bat`에 라이브러리로써 의존한다면, `regex-onig`나 `regex-fancy`를 doc/README-ko.md:814:만약 `bat`의 취약점을 발견하였다면, [David Peter](https://david-peter.de/)에게 메일로 연락주시기 바랍니다. doc/README-ko.md:818:`bat`은 다음과 같은 목표를 달성하려고 합니다: doc/README-ko.md:829:Copyright (c) 2018-2021 [bat-developers](https://github.com/sharkdp/bat). doc/README-ko.md:831:`bat`는 여러분의 선택에 따라 MIT 라이센스 또는 Apache 라이센스 2.0의 조건에 따라 doc/alternatives.md:3:The following table tries to give an overview *from `bat`s perspective*, i.e. we only compare doc/alternatives.md:4:categories which are relevant for `bat`. Some of these projects have completely different goals and doc/alternatives.md:5:if you are not looking for a program like `bat`, this comparison might not be for you. doc/alternatives.md:7:| | bat | [pygments](http://pygments.org/) | [highlight](http://www.andre-simon.de/doku/highlight/highlight.php) | [ccat](https://github.com/jingweno/ccat) | [source-highlight](https://www.gnu.org/software/src-highlite/) | [hicat](https://github.com/rstacruz/hicat) | [coderay](https://github.com/rubychan/coderay) | [rouge](https://github.com/jneen/rouge) | doc/alternatives.md:9:| Drop-in `cat` replacement | :heavy_check_mark: [*](https://github.com/sharkdp/bat/issues/134) | :x: | :x: | (:heavy_check_mark:) | :x: | :x: [*](https://github.com/rstacruz/hicat/issues/6) | :x: | :x: | doc/alternatives.md:43:cmd_bat="bat --style=full --color=always --paging=never '$SRC'" doc/alternatives.md:44:cmd_bat_simple="bat --plain --wrap=never --tabs=0 --color=always --paging=never '$SRC'" doc/alternatives.md:54: "$cmd_bat" \ doc/alternatives.md:55: "$cmd_bat_simple" \ doc/README-ru.md:2: bat - a cat clone with wings
doc/README-ru.md:3: Build Status doc/README-ru.md:4: license doc/README-ru.md:5: Version info
doc/README-ru.md:16: [中文] doc/README-ru.md:24:`bat` поддерживает выделение синтаксиса для огромного количества языков программирования и разметки: doc/README-ru.md:29:`bat` использует `git`, чтобы показать изменения в коде doc/README-ru.md:42:`bat` умеет перенаправлять вывод в `less`, если вывод не помещается на экране полностью. doc/README-ru.md:47:`bat` обнаружит неинтерактивный терминал (например, когда вы перенаправляете вывод в файл или процесс), он будет работать как утилита `cat` и выведет содержимое файлов как обычный текст (без подсветки синтаксиса). doc/README-ru.md:54:> bat README.md doc/README-ru.md:60:> bat src/*.rs doc/README-ru.md:66:> curl -s https://sh.rustup.rs | bat doc/README-ru.md:72:> yaml2json .travis.yml | json_pp | bat -l json doc/README-ru.md:77:> bat -A /etc/hosts doc/README-ru.md:83:bat > note.md # мгновенно создаем новый файл doc/README-ru.md:85:bat header.md content.md footer.md > document.md doc/README-ru.md:87:bat -n main.rs # показываем только количество строк doc/README-ru.md:89:bat f - g # выводит 'f' в stdin, а потом 'g'. doc/README-ru.md:96:Вы можете использовать флаг `-exec` в `find`, чтобы посмотреть превью всех файлов в `bat` doc/README-ru.md:98:find … -exec bat {} + doc/README-ru.md:101:Если вы используете [`fd`](https://github.com/sharkdp/fd), применяйте для этого флаг `-X`/`--exec-batch`: doc/README-ru.md:103:fd … -X bat doc/README-ru.md:108:С помощью [`batgrep`](https://github.com/eth-p/bat-extras/blob/master/doc/batgrep.md), `bat` может быть использован для вывода результата запроса [`ripgrep`](https://github.com/BurntSushi/ripgrep) doc/README-ru.md:111:batgrep needle src/ doc/README-ru.md:116:`bat` может быть использован вместе с `tail -f`, чтобы выводить содержимое файла с подсветкой синтаксиса в реальном времени. doc/README-ru.md:118:tail -f /var/log/pacman.log | bat --paging=never -l log doc/README-ru.md:124:Вы можете использовать `bat` с `git show`, чтобы просмотреть старую версию файла с выделением синтаксиса: doc/README-ru.md:126:git show v0.6.0:src/main.rs | bat -l rs doc/README-ru.md:136:bat main.cpp | xclip doc/README-ru.md:138:`bat` обнаружит перенаправление вывода и выведет обычный текст без выделения синтаксиса. doc/README-ru.md:142:`bat` может быть использован в виде выделения цвета для `man`, для этого установите переменную окружения doc/README-ru.md:146:export MANPAGER="sh -c 'col -bx | bat -l man -p'" doc/README-ru.md:152:Если вы хотите сделать этой одной командой, вы можете использовать [`batman`](https://github.com/eth-p/bat-extras/blob/master/doc/batman.md). doc/README-ru.md:158:[`Prettybat`](https://github.com/eth-p/bat-extras/blob/master/doc/prettybat.md) — скрипт, который форматирует код и выводит его с помощью `bat`. doc/README-ru.md:163:[![Packaging status](https://repology.org/badge/vertical-allrepos/bat.svg)](https://repology.org/project/bat/versions) doc/README-ru.md:168:`bat` есть в репозиториях [Ubuntu](https://packages.ubuntu.com/eoan/bat) и doc/README-ru.md:169:[Debian](https://packages.debian.org/sid/bat) и доступен начиная с Ubuntu Eoan 19.10. На Debian `bat` пока что доступен только с нестабильной веткой "Sid". doc/README-ru.md:171:Если ваша версия Ubuntu/Debian достаточно новая, вы можете установить `bat` так: doc/README-ru.md:174:apt install bat doc/README-ru.md:177:Если вы установили `bat` таким образом, то бинарный файл может быть установлен как `batcat` вместо `bat` (из-за [конфликта имени с другим пакетом](https://github.com/sharkdp/bat/issues/982)). Вы можете сделать симлинк или алиас `bat -> batcat`, чтобы предотвратить подобные проблемы и в других дистрибутивах. doc/README-ru.md:181:ln -s /usr/bin/batcat ~/.local/bin/bat doc/README-ru.md:187:Если пакет еще недоступен в вашем Ubuntu/Debian дистрибутиве или вы хотите установить самую последнюю версию `bat`, то вы можете скачать самый последний `deb`-пакет отсюда: doc/README-ru.md:188:[release page](https://github.com/sharkdp/bat/releases) и установить так: doc/README-ru.md:191:sudo dpkg -i bat_0.18.3_amd64.deb # измените архитектуру и версию doc/README-ru.md:196:Вы можете установить [`bat`](https://pkgs.alpinelinux.org/packages?name=bat) из официальных источников: doc/README-ru.md:199:apk add bat doc/README-ru.md:204:Вы можете установить [`bat`](https://www.archlinux.org/packages/community/x86_64/bat/) из официального источника: doc/README-ru.md:207:pacman -S bat doc/README-ru.md:212:Вы можете установить [`bat`](https://koji.fedoraproject.org/koji/packageinfo?packageID=27506) из официального репозитория [Fedora Modular](https://docs.fedoraproject.org/en-US/modularity/using-modules/). doc/README-ru.md:215:dnf install bat doc/README-ru.md:220:Вы можете установить [`bat`](https://packages.gentoo.org/packages/sys-apps/bat) из официальных источников: doc/README-ru.md:223:emerge sys-apps/bat doc/README-ru.md:228:Вы можете установить `bat` с помощью `xbps-install`: doc/README-ru.md:230:xbps-install -S bat doc/README-ru.md:235:Вы можете установить [`bat`](https://www.freshports.org/textproc/bat) с помощью `pkg`: doc/README-ru.md:238:pkg install bat doc/README-ru.md:244:cd /usr/ports/textproc/bat doc/README-ru.md:250:Вы можете установить `bat`, используя [nix package manager](https://nixos.org/nix): doc/README-ru.md:253:nix-env -i bat doc/README-ru.md:258:Вы можете установить `bat` с помощью `zypper`: doc/README-ru.md:261:zypper install bat doc/README-ru.md:266:Вы можете установить `bat` с помощью [Homebrew](http://braumeister.org/formula/bat): doc/README-ru.md:269:brew install bat doc/README-ru.md:272:Или же установить его с помощью [MacPorts](https://ports.macports.org/port/bat/summary): doc/README-ru.md:275:port install bat doc/README-ru.md:280:Есть несколько способов установить `bat`. Как только вы установили его, посмотрите на секцию ["Использование `bat` в Windows"](#using-bat-on-windows). doc/README-ru.md:284:Вы можете установить `bat` с помощью [Chocolatey](https://chocolatey.org/packages/Bat): doc/README-ru.md:286:choco install bat doc/README-ru.md:291:Вы можете установить `bat` с помощью [scoop](https://scoop.sh/): doc/README-ru.md:293:scoop install bat doc/README-ru.md:300:Их вы можете скачать на [странице релизов](https://github.com/sharkdp/bat/releases). doc/README-ru.md:306:Вы можете использовать [Docker image](https://hub.docker.com/r/danlynn/bat/), чтобы запустить `bat` в контейнере: doc/README-ru.md:308:docker pull danlynn/bat doc/README-ru.md:309:alias bat='docker run -it --rm -e BAT_THEME -e BAT_STYLE -e BAT_TABS -v "$(pwd):/myapp" danlynn/bat' doc/README-ru.md:314:Вы можете установить `bat` с [Ansible](https://www.ansible.com/): doc/README-ru.md:318:ansible-galaxy install aeimer.install_bat doc/README-ru.md:323:# Playbook для установки bat doc/README-ru.md:326: - aeimer.install_bat doc/README-ru.md:329:- [Ansible Galaxy](https://galaxy.ansible.com/aeimer/install_bat) doc/README-ru.md:330:- [GitHub](https://github.com/aeimer/ansible-install-bat) doc/README-ru.md:342:Перейдите на [страницу релизов](https://github.com/sharkdp/bat/releases) для doc/README-ru.md:343:скомпилированных файлов `bat` для различных платформ. Бинарные файлы со статической связкой так же доступны: выбирайте архив с `musl` в имени. doc/README-ru.md:347:Если вы желаете установить `bat` из исходников, вам понадобится Rust 1.46 или выше. После этого используйте `cargo`, чтобы все скомпилировать: doc/README-ru.md:350:cargo install --locked bat doc/README-ru.md:357:Используйте `bat --list-themes`, чтобы вывести список всех доступных тем. Для выбора темы `TwoDark` используйте `bat` с флагом doc/README-ru.md:358:`--theme=TwoDark` или выставьте переменную окружения `BAT_THEME` в `TwoDark`. Используйте `export BAT_THEME="TwoDark"` в конфигурационном файле вашей оболочки, чтобы изменить ее навсегда. Или же используйте [конфигурационный файл](https://github.com/sharkdp/bat#configuration-file) `bat`. doc/README-ru.md:362:bat --list-themes | fzf --preview="bat --theme={} --color=always /путь/к/файлу" doc/README-ru.md:365:`bat` отлично смотрится на темном фоне. Однако если ваш терминал использует светлую тему, то такие темы как `GitHub` или `OneHalfLight` будут смотреться куда лучше! doc/README-ru.md:366:Вы также можете использовать новую тему, для этого перейдите [в раздел добавления тем](https://github.com/sharkdp/bat#добавление-новых-тем). doc/README-ru.md:370:Вы можете использовать флаг `--style`, чтобы изменять внешний вид вывода в `bat`. doc/README-ru.md:371:Например, вы можете использовать `--style=numbers,changes`, чтобы показать только количество строк и изменений в Git. Установите переменную окружения `BAT_STYLE` чтобы изменить это навсегда, или используйте [конфиг файл](https://github.com/sharkdp/bat#configuration-file) `bat`. doc/README-ru.md:375:`bat` использует [`syntect`](https://github.com/trishume/syntect/) для выделения синтаксиса. `syntect` может читать doc/README-ru.md:382:mkdir -p "$(bat --config-dir)/syntaxes" doc/README-ru.md:383:cd "$(bat --config-dir)/syntaxes" doc/README-ru.md:393:bat cache --build doc/README-ru.md:396:Теперь вы можете использовать `bat --list-languages`, чтобы проверить, доступны ли новые языки. doc/README-ru.md:401:bat cache --clear doc/README-ru.md:410:mkdir -p "$(bat --config-dir)/themes" doc/README-ru.md:411:cd "$(bat --config-dir)/themes" doc/README-ru.md:417:bat cache --build doc/README-ru.md:420:Теперь используйте `bat --list-themes`, чтобы проверить доступность новых тем. doc/README-ru.md:424:`bat` использует пейджер, указанный в переменной окружения `PAGER`. Если она не задана, то используется `less`. doc/README-ru.md:425:Если вы желаете использовать другой пейджер, вы можете либо изменить переменную `PAGER`, либо `BAT_PAGER` чтобы перезаписать то, что указано в `PAGER`. doc/README-ru.md:430:export BAT_PAGER="less -RF" doc/README-ru.md:433:Так же вы можете использовать [файл конфигурации](https://github.com/sharkdp/bat#configuration-file) `bat` (флаг `--pager`). doc/README-ru.md:436:`bat` задаст следующие флаги для пейджера: doc/README-ru.md:449:Если вы используете темный режим в macOS, возможно вы захотите чтобы `bat` использовал другую тему, основанную на теме вашей ОС. Следующий сниппет использует тему `default`, когда у вас включен темный режим, и тему `GitHub`, когда включен светлый. doc/README-ru.md:452:alias cat="bat --theme=\$(defaults read -globalDomain AppleInterfaceStyle &> /dev/null && echo default || echo GitHub)" doc/README-ru.md:457:`bat` также может быть кастомизирован с помощью файла конфигурации. Его местоположение зависит от вашей ОС: чтобы посмотреть его путь, введите doc/README-ru.md:459:bat --config-file doc/README-ru.md:462:Также вы можете установить переменную окружения `BAT_CONFIG_PATH`, чтобы изменить путь к файлу конфигурации. doc/README-ru.md:464:export BAT_CONFIG_PATH="/path/to/bat.conf" doc/README-ru.md:469:bat --generate-config-file doc/README-ru.md:474:Файл конфигурации - это всего лишь набор аргументов. Введите `bat --help`, чтобы просмотреть список всех возможных флагов и аргументов. Также вы можете закомментировать строку с помощью `#`. doc/README-ru.md:494:## Использование `bat` в Windows doc/README-ru.md:496:`bat` полностью работоспособен "из коробки", но для некоторых возможностей могут понадобиться дополнительные настройки. doc/README-ru.md:509:или установить `BAT_PAGER` равным пустой строке. doc/README-ru.md:513:Из коробки `bat` не поддерживает пути в стиле Unix (`/cygdrive/*`). Когда указан абсолютный путь cygwin, `bat` выдаст следующую ошибку: `The system cannot find the path specified. (os error 3)` doc/README-ru.md:518:bat() { doc/README-ru.md:527: command bat "${args[@]}" doc/README-ru.md:535:`bat` поддерживает терминалы *с* и *без* поддержки truecolor. Однако подсветка синтаксиса не оптимизирована для терминалов с 8-битными цветами, и рекомендуется использовать терминалы с поддержкой 24-битных цветов (`terminator`, `konsole`, `iTerm2`, ...). doc/README-ru.md:539:`24bit`. Иначе `bat` не сможет определить поддержку 24-битных цветов (и будет использовать 8-битные). doc/README-ru.md:543:Используйте другую тему (`bat --list-themes` выведет список всех установленных тем). Темы `OneHalfDark` и doc/README-ru.md:548:`bat` поддерживает UTF-8 и UTF-16. Файлы в других кодировках, возможно, придётся перекодировать, так как кодировка может быть распознана неверно. Используйте `iconv`. doc/README-ru.md:551:iconv -f ISO-8859-1 -t UTF-8 my-file.php | bat doc/README-ru.md:553:Внимание: вам может понадобится флаг `-l`/`--language`, если `bat` не сможет автоматически определить синтаксис. doc/README-ru.md:559:git clone --recursive https://github.com/sharkdp/bat doc/README-ru.md:562:cd bat doc/README-ru.md:571:# Компилирование исполняего файла bat с другим синтаксисом и темами doc/README-ru.md:583:Цели проекта `bat`: doc/README-ru.md:590:Есть очень много альтернатив `bat`. Смотрите [этот документ](doc/alternatives.md) для сравнения. doc/README-ru.md:593:Copyright (c) 2018-2021 [Разработчики bat](https://github.com/sharkdp/bat). doc/README-ru.md:595:`bat` распостраняется под лицензями MIT License и Apache License 2.0 (на выбор пользователя). doc/release-checklist.md:5:See this page for a good overview: https://deps.rs/repo/github/sharkdp/bat doc/release-checklist.md:27: sure that it is available on the `PATH` (`bat --version` should show the doc/release-checklist.md:41: this, install the latest `bat` version again (to include the new synaxes doc/release-checklist.md:50:- [ ] Go to https://github.com/sharkdp/bat/releases/new to create the new Cargo.lock:85:name = "bat" LICENSE-MIT:1:Copyright (c) 2018-2021 bat-developers (https://github.com/sharkdp/bat). assets/themes/Coldark/README.md:5:# Coldark - Bat assets/themes/Coldark/README.md:7:![GitHub License](https://img.shields.io/github/license/ArmandPhilippot/coldark-bat?colorA=111b27&color=d0dae7&logo=Github&logoColor=e3eaf2&style=for-the-badge) ![GitHub package.json version](https://img.shields.io/github/package-json/v/ArmandPhilippot/coldark-bat?colorA=111b27&color=d0dae7&logo=Github&logoColor=e3eaf2&style=for-the-badge) assets/themes/Coldark/README.md:15:This Coldark version is designed for [bat](https://github.com/sharkdp/bat) command. assets/themes/Coldark/README.md:21:The `bat` version uses almost the same colors as [VS code version](https://github.com/ArmandPhilippot/coldark-vscode). The scopes seems a little different and a little less complete, hence the difference. assets/themes/Coldark/README.md:69:1. Install `bat` (on Manjaro: `pacman -S bat`) assets/themes/Coldark/README.md:70:2. Create themes folder: `mkdir -p "$(bat --config-dir)/themes"` assets/themes/Coldark/README.md:71:3. Go inside this new folder: `cd "$(bat --config-dir)/themes"` assets/themes/Coldark/README.md:72:4. Clone this repo: `git clone https://github.com/ArmandPhilippot/coldark-bat` assets/themes/Coldark/README.md:73:5. Update the binary cache: `bat cache --build` assets/themes/Coldark/README.md:75:Then, if you use `bat --list-themes`, you should see the themes. assets/themes/Coldark/README.md:77:Coldark Bat is now present in [bat repo](https://github.com/sharkdp/bat). It may be present in the list of themes in a future version without having to install it manually. assets/themes/Coldark/README.md:81:To select one of the Coldark themes, call `bat` with the `--theme=Coldark-Cold` (or `--theme=Coldark-Dark`) option or set the `BAT_THEME` environment variable to `Coldark-Cold` (or `Coldark-Dark`). Use `export BAT_THEME="Coldark-Cold"` (or `export BAT_THEME="Coldark-Dark"`) in your shell's startup file to make the change permanent. assets/themes/Coldark/README.md:91:| [![Coldark Cold PHP](./assets/coldark-cold-bat-php.jpg)](./assets/coldark-cold-bat-php.jpg) | [![Coldark Cold Markdown](./assets/coldark-cold-bat-markdown.jpg)](./assets/coldark-cold-bat-markdown.jpg) | assets/themes/Coldark/README.md:97:| [![Coldark Dark PHP](./assets/coldark-dark-bat-php.jpg)](./assets/coldark-dark-bat-php.jpg) | [![Coldark Dark Markdown](./assets/coldark-dark-bat-markdown.jpg)](./assets/coldark-dark-bat-markdown.jpg) | assets/themes/Coldark/README.md:101:This project is open source and available under the [MIT License](https://github.com/ArmandPhilippot/coldark-bat/blob/master/LICENSE). assets/themes/Coldark/Coldark-Cold.tmTheme:6: Project: Coldark Bat assets/themes/Coldark/Coldark-Cold.tmTheme:7: Repository: https://github.com/ArmandPhilippot/coldark-bat assets/themes/Coldark/package.json:2: "name": "coldark-bat", assets/themes/Coldark/package.json:15: "homepage": "https://github.com/ArmandPhilippot/coldark-bat#readme", assets/themes/Coldark/package.json:18: "url": "https://github.com/ArmandPhilippot/coldark-bat" assets/themes/Coldark/package.json:21: "url": "https://github.com/ArmandPhilippot/coldark-bat/issues" assets/themes/Coldark/CHANGELOG.md:10:## [v1.0.5](https://github.com/ArmandPhilippot/coldark-bat/compare/v1.0.4...v1.0.5) assets/themes/Coldark/CHANGELOG.md:19:- fix: change red color for both versions [`93ee1f3`](https://github.com/ArmandPhilippot/coldark-bat/commit/93ee1f3fb5e08ecf66baee03dd3900c0abcdc1e9) assets/themes/Coldark/CHANGELOG.md:21:## [v1.0.4](https://github.com/ArmandPhilippot/coldark-bat/compare/v1.0.3...v1.0.4) - 2020-10-28 assets/themes/Coldark/CHANGELOG.md:25:- Update Coldark Colors / Complete Markdown syntax highlighting [`a355b1d`](https://github.com/ArmandPhilippot/coldark-bat/commit/a355b1d75611d12d322dd47f2ea7799b663a7738) assets/themes/Coldark/CHANGELOG.md:26:- Update colors, logo, banner & add some screenshots [`0b13521`](https://github.com/ArmandPhilippot/coldark-bat/commit/0b13521b6018c04d00304121bcf47fe04fa266ee) assets/themes/Coldark/CHANGELOG.md:27:- build: update auto-changelog command [`2cd0f6e`](https://github.com/ArmandPhilippot/coldark-bat/commit/2cd0f6ea22280c892b564348aab72a45f7b28223) assets/themes/Coldark/CHANGELOG.md:29:## [v1.0.3](https://github.com/ArmandPhilippot/coldark-bat/compare/v1.0.2...v1.0.3) - 2020-10-19 assets/themes/Coldark/CHANGELOG.md:33:- fix: color for pseudo-class/element in CSS [`1fada34`](https://github.com/ArmandPhilippot/coldark-bat/commit/1fada3494ae545fd186b1cb6c7d98c5860bcbcfe) assets/themes/Coldark/CHANGELOG.md:35:## [v1.0.2](https://github.com/ArmandPhilippot/coldark-bat/compare/v1.0.1...v1.0.2) - 2020-10-18 assets/themes/Coldark/CHANGELOG.md:39:- fix: update scopes to be up to date with VS Code theme [`e92f6a7`](https://github.com/ArmandPhilippot/coldark-bat/commit/e92f6a7d7832d269cdec0754a198a589a4567a00) assets/themes/Coldark/CHANGELOG.md:41:## [v1.0.1](https://github.com/ArmandPhilippot/coldark-bat/compare/v1.0.0...v1.0.1) - 2020-10-17 assets/themes/Coldark/CHANGELOG.md:45:- docs: fix export command [`0439c73`](https://github.com/ArmandPhilippot/coldark-bat/commit/0439c73d4af9c6a3254467dc7c6a758796f78267) assets/themes/Coldark/CHANGELOG.md:51:- feat: Coldark for bat command [`18fa11d`](https://github.com/ArmandPhilippot/coldark-bat/commit/18fa11d259bd4c1b5d3278b1ef91dbf8a13e5ee1) assets/themes/Coldark/CHANGELOG.md:52:- Initial commit [`80b7c34`](https://github.com/ArmandPhilippot/coldark-bat/commit/80b7c34079e11ae69fdd94d5839305fedd9fe847) assets/themes/Coldark/CHANGELOG.md:53:- docs: add README [`e904c4d`](https://github.com/ArmandPhilippot/coldark-bat/commit/e904c4d78e3ff7653b25a6215441ad643408aedf) assets/themes/Coldark/Coldark-Dark.tmTheme:6: Project: Coldark Bat assets/themes/Coldark/Coldark-Dark.tmTheme:7: Repository: https://github.com/ArmandPhilippot/coldark-bat assets/themes/Solarized/samples/test.md:26: a verbatim or "code" block assets/themes/onehalf/README.md:43: - [x] [bat](https://github.com/sharkdp/bat) assets/themes/base16.tmTheme:8: the bat theme base16-256 instead. assets/themes/ansi.tmTheme:26: Explicitly set the gutter color since bat falls back to a assets/themes/DarkNeon/Mou/Dark Neon Eighties.txt:77:VERBATIM assets/themes/DarkNeon/Mou/Dark Neon.txt:77:VERBATIM assets/themes/DarkNeon/Mou/Dark Neon Light.txt:77:VERBATIM assets/themes/TwoDark/icons/Prefs/icon_script.tmPreferences:6: source.dosbatch, source.shell assets/themes/TwoDark/src/svg/gfx_quick-panel-row-selected.svg:60:pQxTwpjGFbAti4KEppoxavUgB0Kt5geqNtU3yigwdL9zPN5DHw0QItval6DB1kZEzQTiJdJEmU3x assets/themes/gruvbox/README.md:4:This branch is being used as a submodule in [bat](https://github.com/sharkdp/bat) for the _gruvbox_ family of themes assets/themes/gruvbox/gruvbox-dark.tmTheme:259: entity.name.val.declaration, entity.name.variable, meta.definition.variable, storage.type.variable, support.type.custom-property, support.type.variable-name, variable, variable.interpolation variable, variable.other.interpolation variable, variable.parameter.dosbatch, variable.parameter.output.function.matlab, variable.parameter.sass assets/themes/gruvbox/gruvbox-light.tmTheme:259: entity.name.val.declaration, entity.name.variable, meta.definition.variable, storage.type.variable, support.type.custom-property, support.type.variable-name, variable, variable.interpolation variable, variable.other.interpolation variable, variable.parameter.dosbatch, variable.parameter.output.function.matlab, variable.parameter.sass assets/syntaxes/02_Extra/Slim/Demo/demo.slim:152:/ Verbatim assets/syntaxes/02_Extra/Slim/Demo/demo.slim:163: 'Verbatim text with space after assets/syntaxes/02_Extra/Slim/Syntaxes/Ruby Slim.YAML-tmLanguage:130: comment: Verbatim text (can include HTML tags and copied lines) assets/syntaxes/02_Extra/Slim/Syntaxes/Ruby Slim.tmLanguage:326: Verbatim text (can include HTML tags and copied lines) assets/syntaxes/02_Extra/LLVM/README.md:2:LLVM syntax highlighting definitions based on [LLVM.tmBundle](https://github.com/whitequark/LLVM.tmBundle) created by [whitequark](https://github.com/whitequark) for [bat](https://github.com/sharkdp/bat). assets/syntaxes/02_Extra/Puppet/Puppet.sublime-build:8: "cmd": ["puppet.bat", "parser", "validate", "--color=false", "$file" ] assets/syntaxes/02_Extra/Slim.sublime-syntax:117: comment: Verbatim text (can include HTML tags and copied lines) assets/syntaxes/02_Extra/Assembly (x86_64).sublime-syntax:463: - match: '(?i)\bat\b' assets/syntaxes/02_Extra/HTML (Twig).sublime-syntax:377: - match: '(?<=(?:[a-zA-Z0-9_\x{7f}-\x{ff}\]\)\''\"]\|)|\{%\sfilter\s)(batch|convert_encoding|date|date_modify|default|e(?:scape)?|format|join|merge|number_format|replace|round|slice|split|trim)(\()' assets/syntaxes/02_Extra/HTML (Twig).sublime-syntax:479: - match: (?<=\s)((?:end)?(?:autoescape|block|embed|filter|for|if|macro|raw|sandbox|set|spaceless|trans|verbatim)|as|do|else|elseif|extends|flush|from|ignore missing|import|include|only|use|with)(?=\s) assets/syntaxes/02_Extra/TypsecriptReact.sublime-syntax:2325: |AudioNode|AudioParam|BatteryManager|BeforeUnloadEvent|BiquadFilterNode|Blob|BufferSource|ByteString|CSS|CSSConditionRule assets/syntaxes/02_Extra/TypeScript/tsserver/typingsInstaller.js:3584: // The advantage of this approach is its simplicity. For the case of batch compilation, assets/syntaxes/02_Extra/TypeScript/tsserver/typingsInstaller.js:37221: // Literal files are always included verbatim. An "include" or "exclude" specification cannot assets/syntaxes/02_Extra/TypeScript/tsserver/typingsInstaller.js:48035: var verbatimTargetName = ts.unescapeLeadingUnderscores(target.escapedName); assets/syntaxes/02_Extra/TypeScript/tsserver/typingsInstaller.js:48036: if (verbatimTargetName === "export=" /* ExportEquals */ && (compilerOptions.esModuleInterop || compilerOptions.allowSyntheticDefaultImports)) { assets/syntaxes/02_Extra/TypeScript/tsserver/typingsInstaller.js:48038: verbatimTargetName = "default" /* Default */; assets/syntaxes/02_Extra/TypeScript/tsserver/typingsInstaller.js:48040: var targetName = getInternalSymbolName(target, verbatimTargetName); assets/syntaxes/02_Extra/TypeScript/tsserver/typingsInstaller.js:48085: ts.factory.createImportSpecifier(localName !== verbatimTargetName ? ts.factory.createIdentifier(verbatimTargetName) : undefined, ts.factory.createIdentifier(localName)) assets/syntaxes/02_Extra/TypeScript/tsserver/typingsInstaller.js:48094: serializeExportSpecifier(ts.unescapeLeadingUnderscores(symbol.escapedName), specifier ? verbatimTargetName : targetName, specifier && ts.isStringLiteralLike(specifier) ? ts.factory.createStringLiteral(specifier.text) : undefined); assets/syntaxes/02_Extra/TypeScript/tsserver/typingsInstaller.js:98916: // If he number will be printed verbatim and it doesn't already contain a dot, add one assets/syntaxes/02_Extra/TypeScript/tsserver/typingsInstaller.js:101096: * If `optimistic` is set, the first instance will use 'baseName' verbatim instead of 'baseName_1' assets/syntaxes/02_Extra/TypeScript/tsserver/typingsInstaller.js:105964: // Get next batch of affected files assets/syntaxes/02_Extra/TypeScript/tsserver/typingsInstaller.js:108618: // Upon detecting a file change, wait for 250ms and then perform a recompilation. This gives batch assets/syntaxes/02_Extra/TypeScript/tsserver/tsc.js:39425: var verbatimTargetName = ts.unescapeLeadingUnderscores(target.escapedName); assets/syntaxes/02_Extra/TypeScript/tsserver/tsc.js:39426: if (verbatimTargetName === "export=" && (compilerOptions.esModuleInterop || compilerOptions.allowSyntheticDefaultImports)) { assets/syntaxes/02_Extra/TypeScript/tsserver/tsc.js:39427: verbatimTargetName = "default"; assets/syntaxes/02_Extra/TypeScript/tsserver/tsc.js:39429: var targetName = getInternalSymbolName(target, verbatimTargetName); assets/syntaxes/02_Extra/TypeScript/tsserver/tsc.js:39452: ts.factory.createImportSpecifier(localName !== verbatimTargetName ? ts.factory.createIdentifier(verbatimTargetName) : undefined, ts.factory.createIdentifier(localName)) assets/syntaxes/02_Extra/TypeScript/tsserver/tsc.js:39457: serializeExportSpecifier(ts.unescapeLeadingUnderscores(symbol.escapedName), specifier ? verbatimTargetName : targetName, specifier && ts.isStringLiteralLike(specifier) ? ts.factory.createStringLiteral(specifier.text) : undefined); assets/syntaxes/02_Extra/TypeScript/tsserver/tsserver.js:3595: // The advantage of this approach is its simplicity. For the case of batch compilation, assets/syntaxes/02_Extra/TypeScript/tsserver/tsserver.js:37232: // Literal files are always included verbatim. An "include" or "exclude" specification cannot assets/syntaxes/02_Extra/TypeScript/tsserver/tsserver.js:48046: var verbatimTargetName = ts.unescapeLeadingUnderscores(target.escapedName); assets/syntaxes/02_Extra/TypeScript/tsserver/tsserver.js:48047: if (verbatimTargetName === "export=" /* ExportEquals */ && (compilerOptions.esModuleInterop || compilerOptions.allowSyntheticDefaultImports)) { assets/syntaxes/02_Extra/TypeScript/tsserver/tsserver.js:48049: verbatimTargetName = "default" /* Default */; assets/syntaxes/02_Extra/TypeScript/tsserver/tsserver.js:48051: var targetName = getInternalSymbolName(target, verbatimTargetName); assets/syntaxes/02_Extra/TypeScript/tsserver/tsserver.js:48096: ts.factory.createImportSpecifier(localName !== verbatimTargetName ? ts.factory.createIdentifier(verbatimTargetName) : undefined, ts.factory.createIdentifier(localName)) assets/syntaxes/02_Extra/TypeScript/tsserver/tsserver.js:48105: serializeExportSpecifier(ts.unescapeLeadingUnderscores(symbol.escapedName), specifier ? verbatimTargetName : targetName, specifier && ts.isStringLiteralLike(specifier) ? ts.factory.createStringLiteral(specifier.text) : undefined); assets/syntaxes/02_Extra/TypeScript/tsserver/tsserver.js:98927: // If he number will be printed verbatim and it doesn't already contain a dot, add one assets/syntaxes/02_Extra/TypeScript/tsserver/tsserver.js:101107: * If `optimistic` is set, the first instance will use 'baseName' verbatim instead of 'baseName_1' assets/syntaxes/02_Extra/TypeScript/tsserver/tsserver.js:105975: // Get next batch of affected files assets/syntaxes/02_Extra/TypeScript/tsserver/tsserver.js:108629: // Upon detecting a file change, wait for 250ms and then perform a recompilation. This gives batch assets/syntaxes/02_Extra/TypeScript/tsserver/typescriptServices.js:3789: // The advantage of this approach is its simplicity. For the case of batch compilation, assets/syntaxes/02_Extra/TypeScript/tsserver/typescriptServices.js:37426: // Literal files are always included verbatim. An "include" or "exclude" specification cannot assets/syntaxes/02_Extra/TypeScript/tsserver/typescriptServices.js:48240: var verbatimTargetName = ts.unescapeLeadingUnderscores(target.escapedName); assets/syntaxes/02_Extra/TypeScript/tsserver/typescriptServices.js:48241: if (verbatimTargetName === "export=" /* ExportEquals */ && (compilerOptions.esModuleInterop || compilerOptions.allowSyntheticDefaultImports)) { assets/syntaxes/02_Extra/TypeScript/tsserver/typescriptServices.js:48243: verbatimTargetName = "default" /* Default */; assets/syntaxes/02_Extra/TypeScript/tsserver/typescriptServices.js:48245: var targetName = getInternalSymbolName(target, verbatimTargetName); assets/syntaxes/02_Extra/TypeScript/tsserver/typescriptServices.js:48290: ts.factory.createImportSpecifier(localName !== verbatimTargetName ? ts.factory.createIdentifier(verbatimTargetName) : undefined, ts.factory.createIdentifier(localName)) assets/syntaxes/02_Extra/TypeScript/tsserver/typescriptServices.js:48299: serializeExportSpecifier(ts.unescapeLeadingUnderscores(symbol.escapedName), specifier ? verbatimTargetName : targetName, specifier && ts.isStringLiteralLike(specifier) ? ts.factory.createStringLiteral(specifier.text) : undefined); assets/syntaxes/02_Extra/TypeScript/tsserver/typescriptServices.js:99121: // If he number will be printed verbatim and it doesn't already contain a dot, add one assets/syntaxes/02_Extra/TypeScript/tsserver/typescriptServices.js:101301: * If `optimistic` is set, the first instance will use 'baseName' verbatim instead of 'baseName_1' assets/syntaxes/02_Extra/TypeScript/tsserver/typescriptServices.js:106169: // Get next batch of affected files assets/syntaxes/02_Extra/TypeScript/tsserver/typescriptServices.js:108823: // Upon detecting a file change, wait for 250ms and then perform a recompilation. This gives batch assets/syntaxes/02_Extra/TypeScript/tsserver/tsserverlibrary.js:3789: // The advantage of this approach is its simplicity. For the case of batch compilation, assets/syntaxes/02_Extra/TypeScript/tsserver/tsserverlibrary.js:37426: // Literal files are always included verbatim. An "include" or "exclude" specification cannot assets/syntaxes/02_Extra/TypeScript/tsserver/tsserverlibrary.js:48240: var verbatimTargetName = ts.unescapeLeadingUnderscores(target.escapedName); assets/syntaxes/02_Extra/TypeScript/tsserver/tsserverlibrary.js:48241: if (verbatimTargetName === "export=" /* ExportEquals */ && (compilerOptions.esModuleInterop || compilerOptions.allowSyntheticDefaultImports)) { assets/syntaxes/02_Extra/TypeScript/tsserver/tsserverlibrary.js:48243: verbatimTargetName = "default" /* Default */; assets/syntaxes/02_Extra/TypeScript/tsserver/tsserverlibrary.js:48245: var targetName = getInternalSymbolName(target, verbatimTargetName); assets/syntaxes/02_Extra/TypeScript/tsserver/tsserverlibrary.js:48290: ts.factory.createImportSpecifier(localName !== verbatimTargetName ? ts.factory.createIdentifier(verbatimTargetName) : undefined, ts.factory.createIdentifier(localName)) assets/syntaxes/02_Extra/TypeScript/tsserver/tsserverlibrary.js:48299: serializeExportSpecifier(ts.unescapeLeadingUnderscores(symbol.escapedName), specifier ? verbatimTargetName : targetName, specifier && ts.isStringLiteralLike(specifier) ? ts.factory.createStringLiteral(specifier.text) : undefined); assets/syntaxes/02_Extra/TypeScript/tsserver/tsserverlibrary.js:99121: // If he number will be printed verbatim and it doesn't already contain a dot, add one assets/syntaxes/02_Extra/TypeScript/tsserver/tsserverlibrary.js:101301: * If `optimistic` is set, the first instance will use 'baseName' verbatim instead of 'baseName_1' assets/syntaxes/02_Extra/TypeScript/tsserver/tsserverlibrary.js:106169: // Get next batch of affected files assets/syntaxes/02_Extra/TypeScript/tsserver/tsserverlibrary.js:108823: // Upon detecting a file change, wait for 250ms and then perform a recompilation. This gives batch assets/syntaxes/02_Extra/TypeScript/tsserver/typescript.js:3789: // The advantage of this approach is its simplicity. For the case of batch compilation, assets/syntaxes/02_Extra/TypeScript/tsserver/typescript.js:37426: // Literal files are always included verbatim. An "include" or "exclude" specification cannot assets/syntaxes/02_Extra/TypeScript/tsserver/typescript.js:48240: var verbatimTargetName = ts.unescapeLeadingUnderscores(target.escapedName); assets/syntaxes/02_Extra/TypeScript/tsserver/typescript.js:48241: if (verbatimTargetName === "export=" /* ExportEquals */ && (compilerOptions.esModuleInterop || compilerOptions.allowSyntheticDefaultImports)) { assets/syntaxes/02_Extra/TypeScript/tsserver/typescript.js:48243: verbatimTargetName = "default" /* Default */; assets/syntaxes/02_Extra/TypeScript/tsserver/typescript.js:48245: var targetName = getInternalSymbolName(target, verbatimTargetName); assets/syntaxes/02_Extra/TypeScript/tsserver/typescript.js:48290: ts.factory.createImportSpecifier(localName !== verbatimTargetName ? ts.factory.createIdentifier(verbatimTargetName) : undefined, ts.factory.createIdentifier(localName)) assets/syntaxes/02_Extra/TypeScript/tsserver/typescript.js:48299: serializeExportSpecifier(ts.unescapeLeadingUnderscores(symbol.escapedName), specifier ? verbatimTargetName : targetName, specifier && ts.isStringLiteralLike(specifier) ? ts.factory.createStringLiteral(specifier.text) : undefined); assets/syntaxes/02_Extra/TypeScript/tsserver/typescript.js:99121: // If he number will be printed verbatim and it doesn't already contain a dot, add one assets/syntaxes/02_Extra/TypeScript/tsserver/typescript.js:101301: * If `optimistic` is set, the first instance will use 'baseName' verbatim instead of 'baseName_1' assets/syntaxes/02_Extra/TypeScript/tsserver/typescript.js:106169: // Get next batch of affected files assets/syntaxes/02_Extra/TypeScript/tsserver/typescript.js:108823: // Upon detecting a file change, wait for 250ms and then perform a recompilation. This gives batch assets/syntaxes/02_Extra/TypeScript/tsserver/lib.scripthost.d.ts:161: * Gets/sets the script mode - interactive(true) or batch(false). assets/syntaxes/02_Extra/TypeScript/TypeScript.tmLanguage:6080: |AudioNode|AudioParam|BatteryManager|BeforeUnloadEvent|BiquadFilterNode|Blob|BufferSource|ByteString|CSS|CSSConditionRule assets/syntaxes/02_Extra/TypeScript/TypeScriptReact.tmLanguage:6026: |AudioNode|AudioParam|BatteryManager|BeforeUnloadEvent|BiquadFilterNode|Blob|BufferSource|ByteString|CSS|CSSConditionRule assets/syntaxes/02_Extra/Org mode/README.org:25:- [X] =Verbatim= assets/syntaxes/02_Extra/PowerShell/examples/test.ps1:281:a.bat assets/syntaxes/02_Extra/PowerShell/examples/test.ps1:282:aa.bat assets/syntaxes/02_Extra/PowerShell/examples/test.ps1:283:aaa.bat assets/syntaxes/02_Extra/PowerShell/examples/test.ps1:284:aaaa.bat assets/syntaxes/02_Extra/PowerShell/PowerShellSyntax.tmLanguage:255: (\b(([A-Za-z0-9\-_\.]+)\.(?i:exe|com|cmd|bat))\b) assets/syntaxes/02_Extra/PowerShell/PowerShellSyntax.tmLanguage:503: (?:(\p{L}|\d|_|-|\\|\:)*\\)?\b(?i:Add|Approve|Assert|Backup|Block|Build|Checkpoint|Clear|Close|Compare|Complete|Compress|Confirm|Connect|Convert|ConvertFrom|ConvertTo|Copy|Debug|Deny|Deploy|Disable|Disconnect|Dismount|Edit|Enable|Enter|Exit|Expand|Export|Find|Format|Get|Grant|Group|Hide|Import|Initialize|Install|Invoke|Join|Limit|Lock|Measure|Merge|Mount|Move|New|Open|Optimize|Out|Ping|Pop|Protect|Publish|Push|Read|Receive|Redo|Register|Remove|Rename|Repair|Request|Reset|Resize|Resolve|Restart|Restore|Resume|Revoke|Save|Search|Select|Send|Set|Show|Skip|Split|Start|Step|Stop|Submit|Suspend|Switch|Sync|Test|Trace|Unblock|Undo|Uninstall|Unlock|Unprotect|Unpublish|Unregister|Update|Use|Wait|Watch|Write)\-.+?(?:\.(?i:exe|cmd|bat|ps1))?\b assets/syntaxes/02_Extra/ssh-config/src/options.yaml:54: BatchMode: assets/syntaxes/02_Extra/ssh-config/SSH Config.sublime-syntax:215: BatchMode|CanonicalizeFallbackLocal|CheckHostIP|Compression| assets/syntaxes/02_Extra/ssh-config/Support/SSH Config.sublime-completions:41: "trigger": "BatchMode", assets/syntaxes/02_Extra/ssh-config/Support/SSH Config.sublime-completions:42: "contents": "BatchMode", assets/syntaxes/02_Extra/ssh-config/Support/SSH Config.sublime-completions:47: "trigger": "batchmode", assets/syntaxes/02_Extra/ssh-config/Support/SSH Config.sublime-completions:48: "contents": "BatchMode ${0:{ yes | no \\}}", assets/syntaxes/02_Extra/http-request-response/README.md:3:It was originally designed for use in https://github.com/sharkdp/bat, so it is not using any Sublime Text 4 features, as https://github.com/trishume/syntect does not support them yet. So this package should work in Sublime Text 3 also. assets/syntaxes/02_Extra/http-request-response/docs/CONTRIBUTING.md:9:If you are not a Sublime Text user, and are contributing to improve a tool that uses the `syntect` Rust library, such as `bat`, assets/syntaxes/02_Extra/Crystal/Crystal.tmLanguage:353: \b(initialize|new|loop|include|extend|raise|getter|setter|property|class_getter|class_setter|class_property|describe|context|it|with|delegate|def_hash|def_equals|def_equals_and_hash|forward_missing_to|record|assert_responds_to|spawn|annotation|verbatim)\b[!?]? assets/syntaxes/02_Extra/Lean/README.md:22:* Batch file execution assets/syntaxes/02_Extra/Lean/README.md:178:* `lean.batchExecute` (Lean: Batch Execute File): execute the current file using Lean (bound to ctrl+shift+r by default) assets/syntaxes/02_Extra/Lean/README.md:287:* Properly set working directory when executing in batch mode. assets/syntaxes/02_Extra/Lean/src/batch.ts:6:let batchOutputChannel: OutputChannel; assets/syntaxes/02_Extra/Lean/src/batch.ts:8:export function batchExecuteFile( assets/syntaxes/02_Extra/Lean/src/batch.ts:13: batchOutputChannel = batchOutputChannel || assets/syntaxes/02_Extra/Lean/src/batch.ts:14: window.createOutputChannel('Lean: Batch File Output'); assets/syntaxes/02_Extra/Lean/src/batch.ts:23: batchOutputChannel.clear(); assets/syntaxes/02_Extra/Lean/src/batch.ts:26: batchOutputChannel.appendLine(line); assets/syntaxes/02_Extra/Lean/src/batch.ts:30: batchOutputChannel.appendLine(line); assets/syntaxes/02_Extra/Lean/src/batch.ts:37: batchOutputChannel.show(true); assets/syntaxes/02_Extra/Lean/src/extension.ts:3:import { batchExecuteFile } from './batch'; assets/syntaxes/02_Extra/Lean/src/extension.ts:67: commands.registerTextEditorCommand('lean.batchExecute', assets/syntaxes/02_Extra/Lean/src/extension.ts:68: (editor, edit, args) => { batchExecuteFile(server, editor, edit, args); }), assets/syntaxes/02_Extra/Lean/package.json:281: "command": "lean.batchExecute", assets/syntaxes/02_Extra/Lean/package.json:283: "title": "Batch Execute File", assets/syntaxes/02_Extra/Lean/package.json:350: "command": "lean.batchExecute", assets/syntaxes/02_Extra/Lean/package.json:373: "command": "lean.batchExecute", assets/syntaxes/02_Extra/Lean/syntaxes/lean-markdown.json:571: "fenced_code_block_dosbatch": { assets/syntaxes/02_Extra/Lean/syntaxes/lean-markdown.json:572: "begin": "(^)(\\s*)(`{3,}|~{3,})\\s*(?i:(bat|batch)((\\s+|:|\\{)[^`~]*)?$)", assets/syntaxes/02_Extra/Lean/syntaxes/lean-markdown.json:595: "contentName": "meta.embedded.block.dosbatch", assets/syntaxes/02_Extra/Lean/syntaxes/lean-markdown.json:598: "include": "source.batchfile" assets/syntaxes/02_Extra/Lean/syntaxes/lean-markdown.json:1774: "include": "#fenced_code_block_dosbatch" assets/syntaxes/02_Extra/Lean/syntaxes/lean.json:21: { "match": "\\battribute\\b\\s*\\[[^\\]]*\\]", "name": "storage.modifier.lean" }, assets/syntaxes/02_Extra/Lean/package-lock.json:1946: "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", assets/syntaxes/02_Extra/Lean/package-lock.json:4288: "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", assets/syntaxes/02_Extra/Lean/package-lock.json:7099: "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", assets/syntaxes/02_Extra/Lean/package-lock.json:9705: "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", assets/syntaxes/02_Extra/Lean/package-lock.json:11662: "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", assets/syntaxes/02_Extra/Lean/package-lock.json:14054: "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", assets/syntaxes/02_Extra/CMake/CMakeCommands.yml:4:add_custom_command: [OUTPUT, COMMAND, ARGS, MAIN_DEPENDENCY, DEPENDS, BYPRODUCTS, IMPLICIT_DEPENDS, WORKING_DIRECTORY, COMMENT, DEPFILE, VERBATIM, APPEND, USES_TERMINAL COMMAND_EXPAND_LISTS, TARGET, PRE_BUILD, PRE_LINK, POST_BUILD] assets/syntaxes/02_Extra/CMake/CMakeCommands.yml:5:add_custom_target: [ALL, COMMAND, DEPENDS, BYPRODUCTS, WORKING_DIRECTORY, COMMENT, VERBATIM, USES_TERMINAL, COMMAND_EXPAND_LISTS, SOURCES] assets/syntaxes/02_Extra/CMake/CMakeVariables.sublime-completions:1:{"completions":[{"contents":"ANDROID","trigger":"ANDROID\tbuiltin variable"},{"contents":"APPLE","trigger":"APPLE\tbuiltin variable"},{"contents":"BORLAND","trigger":"BORLAND\tbuiltin variable"},{"contents":"BUILD_SHARED_LIBS","trigger":"BUILD_SHARED_LIBS\tbuiltin variable"},{"contents":"CACHE","trigger":"CACHE\tbuiltin variable"},{"contents":"CMAKE_ABSOLUTE_DESTINATION_FILES","trigger":"CMAKE_ABSOLUTE_DESTINATION_FILES\tbuiltin variable"},{"contents":"CMAKE_AIX_EXPORT_ALL_SYMBOLS","trigger":"CMAKE_AIX_EXPORT_ALL_SYMBOLS\tbuiltin variable"},{"contents":"CMAKE_ANDROID_ANT_ADDITIONAL_OPTIONS","trigger":"CMAKE_ANDROID_ANT_ADDITIONAL_OPTIONS\tbuiltin variable"},{"contents":"CMAKE_ANDROID_API","trigger":"CMAKE_ANDROID_API\tbuiltin variable"},{"contents":"CMAKE_ANDROID_API_MIN","trigger":"CMAKE_ANDROID_API_MIN\tbuiltin variable"},{"contents":"CMAKE_ANDROID_ARCH","trigger":"CMAKE_ANDROID_ARCH\tbuiltin variable"},{"contents":"CMAKE_ANDROID_ARCH_ABI","trigger":"CMAKE_ANDROID_ARCH_ABI\tbuiltin variable"},{"contents":"CMAKE_ANDROID_ARM_MODE","trigger":"CMAKE_ANDROID_ARM_MODE\tbuiltin variable"},{"contents":"CMAKE_ANDROID_ARM_NEON","trigger":"CMAKE_ANDROID_ARM_NEON\tbuiltin variable"},{"contents":"CMAKE_ANDROID_ASSETS_DIRECTORIES","trigger":"CMAKE_ANDROID_ASSETS_DIRECTORIES\tbuiltin variable"},{"contents":"CMAKE_ANDROID_GUI","trigger":"CMAKE_ANDROID_GUI\tbuiltin variable"},{"contents":"CMAKE_ANDROID_JAR_DEPENDENCIES","trigger":"CMAKE_ANDROID_JAR_DEPENDENCIES\tbuiltin variable"},{"contents":"CMAKE_ANDROID_JAR_DIRECTORIES","trigger":"CMAKE_ANDROID_JAR_DIRECTORIES\tbuiltin variable"},{"contents":"CMAKE_ANDROID_JAVA_SOURCE_DIR","trigger":"CMAKE_ANDROID_JAVA_SOURCE_DIR\tbuiltin variable"},{"contents":"CMAKE_ANDROID_NATIVE_LIB_DEPENDENCIES","trigger":"CMAKE_ANDROID_NATIVE_LIB_DEPENDENCIES\tbuiltin variable"},{"contents":"CMAKE_ANDROID_NATIVE_LIB_DIRECTORIES","trigger":"CMAKE_ANDROID_NATIVE_LIB_DIRECTORIES\tbuiltin variable"},{"contents":"CMAKE_ANDROID_NDK","trigger":"CMAKE_ANDROID_NDK\tbuiltin variable"},{"contents":"CMAKE_ANDROID_NDK_DEPRECATED_HEADERS","trigger":"CMAKE_ANDROID_NDK_DEPRECATED_HEADERS\tbuiltin variable"},{"contents":"CMAKE_ANDROID_NDK_TOOLCHAIN_HOST_TAG","trigger":"CMAKE_ANDROID_NDK_TOOLCHAIN_HOST_TAG\tbuiltin variable"},{"contents":"CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION","trigger":"CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION\tbuiltin variable"},{"contents":"CMAKE_ANDROID_PROCESS_MAX","trigger":"CMAKE_ANDROID_PROCESS_MAX\tbuiltin variable"},{"contents":"CMAKE_ANDROID_PROGUARD","trigger":"CMAKE_ANDROID_PROGUARD\tbuiltin variable"},{"contents":"CMAKE_ANDROID_PROGUARD_CONFIG_PATH","trigger":"CMAKE_ANDROID_PROGUARD_CONFIG_PATH\tbuiltin variable"},{"contents":"CMAKE_ANDROID_SECURE_PROPS_PATH","trigger":"CMAKE_ANDROID_SECURE_PROPS_PATH\tbuiltin variable"},{"contents":"CMAKE_ANDROID_SKIP_ANT_STEP","trigger":"CMAKE_ANDROID_SKIP_ANT_STEP\tbuiltin variable"},{"contents":"CMAKE_ANDROID_STANDALONE_TOOLCHAIN","trigger":"CMAKE_ANDROID_STANDALONE_TOOLCHAIN\tbuiltin variable"},{"contents":"CMAKE_ANDROID_STL_TYPE","trigger":"CMAKE_ANDROID_STL_TYPE\tbuiltin variable"},{"contents":"CMAKE_APPBUNDLE_PATH","trigger":"CMAKE_APPBUNDLE_PATH\tbuiltin variable"},{"contents":"CMAKE_APPLE_SILICON_PROCESSOR","trigger":"CMAKE_APPLE_SILICON_PROCESSOR\tbuiltin variable"},{"contents":"CMAKE_AR","trigger":"CMAKE_AR\tbuiltin variable"},{"contents":"CMAKE_ARCHIVE_OUTPUT_DIRECTORY","trigger":"CMAKE_ARCHIVE_OUTPUT_DIRECTORY\tbuiltin variable"},{"contents":"CMAKE_ARGC","trigger":"CMAKE_ARGC\tbuiltin variable"},{"contents":"CMAKE_ARGV0","trigger":"CMAKE_ARGV0\tbuiltin variable"},{"contents":"CMAKE_AUTOGEN_ORIGIN_DEPENDS","trigger":"CMAKE_AUTOGEN_ORIGIN_DEPENDS\tbuiltin variable"},{"contents":"CMAKE_AUTOGEN_PARALLEL","trigger":"CMAKE_AUTOGEN_PARALLEL\tbuiltin variable"},{"contents":"CMAKE_AUTOGEN_VERBOSE","trigger":"CMAKE_AUTOGEN_VERBOSE\tbuiltin variable"},{"contents":"CMAKE_AUTOMOC","trigger":"CMAKE_AUTOMOC\tbuiltin variable"},{"contents":"CMAKE_AUTOMOC_COMPILER_PREDEFINES","trigger":"CMAKE_AUTOMOC_COMPILER_PREDEFINES\tbuiltin variable"},{"contents":"CMAKE_AUTOMOC_DEPEND_FILTERS","trigger":"CMAKE_AUTOMOC_DEPEND_FILTERS\tbuiltin variable"},{"contents":"CMAKE_AUTOMOC_MACRO_NAMES","trigger":"CMAKE_AUTOMOC_MACRO_NAMES\tbuiltin variable"},{"contents":"CMAKE_AUTOMOC_MOC_OPTIONS","trigger":"CMAKE_AUTOMOC_MOC_OPTIONS\tbuiltin variable"},{"contents":"CMAKE_AUTOMOC_PATH_PREFIX","trigger":"CMAKE_AUTOMOC_PATH_PREFIX\tbuiltin variable"},{"contents":"CMAKE_AUTOMOC_RELAXED_MODE","trigger":"CMAKE_AUTOMOC_RELAXED_MODE\tbuiltin variable"},{"contents":"CMAKE_AUTORCC","trigger":"CMAKE_AUTORCC\tbuiltin variable"},{"contents":"CMAKE_AUTORCC_OPTIONS","trigger":"CMAKE_AUTORCC_OPTIONS\tbuiltin variable"},{"contents":"CMAKE_AUTOUIC","trigger":"CMAKE_AUTOUIC\tbuiltin variable"},{"contents":"CMAKE_AUTOUIC_OPTIONS","trigger":"CMAKE_AUTOUIC_OPTIONS\tbuiltin variable"},{"contents":"CMAKE_AUTOUIC_SEARCH_PATHS","trigger":"CMAKE_AUTOUIC_SEARCH_PATHS\tbuiltin variable"},{"contents":"CMAKE_BACKWARDS_COMPATIBILITY","trigger":"CMAKE_BACKWARDS_COMPATIBILITY\tbuiltin variable"},{"contents":"CMAKE_BINARY_DIR","trigger":"CMAKE_BINARY_DIR\tbuiltin variable"},{"contents":"CMAKE_BUILD_RPATH","trigger":"CMAKE_BUILD_RPATH\tbuiltin variable"},{"contents":"CMAKE_BUILD_RPATH_USE_ORIGIN","trigger":"CMAKE_BUILD_RPATH_USE_ORIGIN\tbuiltin variable"},{"contents":"CMAKE_BUILD_TOOL","trigger":"CMAKE_BUILD_TOOL\tbuiltin variable"},{"contents":"CMAKE_BUILD_TYPE","trigger":"CMAKE_BUILD_TYPE\tbuiltin variable"},{"contents":"CMAKE_BUILD_WITH_INSTALL_NAME_DIR","trigger":"CMAKE_BUILD_WITH_INSTALL_NAME_DIR\tbuiltin variable"},{"contents":"CMAKE_BUILD_WITH_INSTALL_RPATH","trigger":"CMAKE_BUILD_WITH_INSTALL_RPATH\tbuiltin variable"},{"contents":"CMAKE_CACHEFILE_DIR","trigger":"CMAKE_CACHEFILE_DIR\tbuiltin variable"},{"contents":"CMAKE_CACHE_MAJOR_VERSION","trigger":"CMAKE_CACHE_MAJOR_VERSION\tbuiltin variable"},{"contents":"CMAKE_CACHE_MINOR_VERSION","trigger":"CMAKE_CACHE_MINOR_VERSION\tbuiltin variable"},{"contents":"CMAKE_CACHE_PATCH_VERSION","trigger":"CMAKE_CACHE_PATCH_VERSION\tbuiltin variable"},{"contents":"CMAKE_CFG_INTDIR","trigger":"CMAKE_CFG_INTDIR\tbuiltin variable"},{"contents":"CMAKE_CLANG_VFS_OVERLAY","trigger":"CMAKE_CLANG_VFS_OVERLAY\tbuiltin variable"},{"contents":"CMAKE_CL_64","trigger":"CMAKE_CL_64\tbuiltin variable"},{"contents":"CMAKE_CODEBLOCKS_COMPILER_ID","trigger":"CMAKE_CODEBLOCKS_COMPILER_ID\tbuiltin variable"},{"contents":"CMAKE_CODEBLOCKS_EXCLUDE_EXTERNAL_FILES","trigger":"CMAKE_CODEBLOCKS_EXCLUDE_EXTERNAL_FILES\tbuiltin variable"},{"contents":"CMAKE_CODELITE_USE_TARGETS","trigger":"CMAKE_CODELITE_USE_TARGETS\tbuiltin variable"},{"contents":"CMAKE_COLOR_MAKEFILE","trigger":"CMAKE_COLOR_MAKEFILE\tbuiltin variable"},{"contents":"CMAKE_COMMAND","trigger":"CMAKE_COMMAND\tbuiltin variable"},{"contents":"CMAKE_COMPILER_2005","trigger":"CMAKE_COMPILER_2005\tbuiltin variable"},{"contents":"CMAKE_COMPILER_IS_GNUCC","trigger":"CMAKE_COMPILER_IS_GNUCC\tbuiltin variable"},{"contents":"CMAKE_COMPILER_IS_GNUCXX","trigger":"CMAKE_COMPILER_IS_GNUCXX\tbuiltin variable"},{"contents":"CMAKE_COMPILER_IS_GNUG77","trigger":"CMAKE_COMPILER_IS_GNUG77\tbuiltin variable"},{"contents":"CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY","trigger":"CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY\tbuiltin variable"},{"contents":"CMAKE_CONFIGURATION_TYPES","trigger":"CMAKE_CONFIGURATION_TYPES\tbuiltin variable"},{"contents":"CMAKE_CPACK_COMMAND","trigger":"CMAKE_CPACK_COMMAND\tbuiltin variable"},{"contents":"CMAKE_CROSSCOMPILING","trigger":"CMAKE_CROSSCOMPILING\tbuiltin variable"},{"contents":"CMAKE_CROSSCOMPILING_EMULATOR","trigger":"CMAKE_CROSSCOMPILING_EMULATOR\tbuiltin variable"},{"contents":"CMAKE_CROSS_CONFIGS","trigger":"CMAKE_CROSS_CONFIGS\tbuiltin variable"},{"contents":"CMAKE_CTEST_ARGUMENTS","trigger":"CMAKE_CTEST_ARGUMENTS\tbuiltin variable"},{"contents":"CMAKE_CTEST_COMMAND","trigger":"CMAKE_CTEST_COMMAND\tbuiltin variable"},{"contents":"CMAKE_CUDA_ARCHITECTURES","trigger":"CMAKE_CUDA_ARCHITECTURES\tbuiltin variable"},{"contents":"CMAKE_CUDA_COMPILE_FEATURES","trigger":"CMAKE_CUDA_COMPILE_FEATURES\tbuiltin variable"},{"contents":"CMAKE_CUDA_EXTENSIONS","trigger":"CMAKE_CUDA_EXTENSIONS\tbuiltin variable"},{"contents":"CMAKE_CUDA_HOST_COMPILER","trigger":"CMAKE_CUDA_HOST_COMPILER\tbuiltin variable"},{"contents":"CMAKE_CUDA_RESOLVE_DEVICE_SYMBOLS","trigger":"CMAKE_CUDA_RESOLVE_DEVICE_SYMBOLS\tbuiltin variable"},{"contents":"CMAKE_CUDA_RUNTIME_LIBRARY","trigger":"CMAKE_CUDA_RUNTIME_LIBRARY\tbuiltin variable"},{"contents":"CMAKE_CUDA_SEPARABLE_COMPILATION","trigger":"CMAKE_CUDA_SEPARABLE_COMPILATION\tbuiltin variable"},{"contents":"CMAKE_CUDA_STANDARD","trigger":"CMAKE_CUDA_STANDARD\tbuiltin variable"},{"contents":"CMAKE_CUDA_STANDARD_REQUIRED","trigger":"CMAKE_CUDA_STANDARD_REQUIRED\tbuiltin variable"},{"contents":"CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES","trigger":"CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES\tbuiltin variable"},{"contents":"CMAKE_CURRENT_BINARY_DIR","trigger":"CMAKE_CURRENT_BINARY_DIR\tbuiltin variable"},{"contents":"CMAKE_CURRENT_FUNCTION","trigger":"CMAKE_CURRENT_FUNCTION\tbuiltin variable"},{"contents":"CMAKE_CURRENT_FUNCTION_LIST_DIR","trigger":"CMAKE_CURRENT_FUNCTION_LIST_DIR\tbuiltin variable"},{"contents":"CMAKE_CURRENT_FUNCTION_LIST_FILE","trigger":"CMAKE_CURRENT_FUNCTION_LIST_FILE\tbuiltin variable"},{"contents":"CMAKE_CURRENT_FUNCTION_LIST_LINE","trigger":"CMAKE_CURRENT_FUNCTION_LIST_LINE\tbuiltin variable"},{"contents":"CMAKE_CURRENT_LIST_DIR","trigger":"CMAKE_CURRENT_LIST_DIR\tbuiltin variable"},{"contents":"CMAKE_CURRENT_LIST_FILE","trigger":"CMAKE_CURRENT_LIST_FILE\tbuiltin variable"},{"contents":"CMAKE_CURRENT_LIST_LINE","trigger":"CMAKE_CURRENT_LIST_LINE\tbuiltin variable"},{"contents":"CMAKE_CURRENT_SOURCE_DIR","trigger":"CMAKE_CURRENT_SOURCE_DIR\tbuiltin variable"},{"contents":"CMAKE_CXX_COMPILE_FEATURES","trigger":"CMAKE_CXX_COMPILE_FEATURES\tbuiltin variable"},{"contents":"CMAKE_CXX_EXTENSIONS","trigger":"CMAKE_CXX_EXTENSIONS\tbuiltin variable"},{"contents":"CMAKE_CXX_STANDARD","trigger":"CMAKE_CXX_STANDARD\tbuiltin variable"},{"contents":"CMAKE_CXX_STANDARD_REQUIRED","trigger":"CMAKE_CXX_STANDARD_REQUIRED\tbuiltin variable"},{"contents":"CMAKE_C_COMPILE_FEATURES","trigger":"CMAKE_C_COMPILE_FEATURES\tbuiltin variable"},{"contents":"CMAKE_C_EXTENSIONS","trigger":"CMAKE_C_EXTENSIONS\tbuiltin variable"},{"contents":"CMAKE_C_STANDARD","trigger":"CMAKE_C_STANDARD\tbuiltin variable"},{"contents":"CMAKE_C_STANDARD_REQUIRED","trigger":"CMAKE_C_STANDARD_REQUIRED\tbuiltin variable"},{"contents":"CMAKE_DEBUG_POSTFIX","trigger":"CMAKE_DEBUG_POSTFIX\tbuiltin variable"},{"contents":"CMAKE_DEBUG_TARGET_PROPERTIES","trigger":"CMAKE_DEBUG_TARGET_PROPERTIES\tbuiltin variable"},{"contents":"CMAKE_DEFAULT_BUILD_TYPE","trigger":"CMAKE_DEFAULT_BUILD_TYPE\tbuiltin variable"},{"contents":"CMAKE_DEFAULT_CONFIGS","trigger":"CMAKE_DEFAULT_CONFIGS\tbuiltin variable"},{"contents":"CMAKE_DEPENDS_IN_PROJECT_ONLY","trigger":"CMAKE_DEPENDS_IN_PROJECT_ONLY\tbuiltin variable"},{"contents":"CMAKE_DIRECTORY_LABELS","trigger":"CMAKE_DIRECTORY_LABELS\tbuiltin variable"},{"contents":"CMAKE_DISABLE_PRECOMPILE_HEADERS","trigger":"CMAKE_DISABLE_PRECOMPILE_HEADERS\tbuiltin variable"},{"contents":"CMAKE_DL_LIBS","trigger":"CMAKE_DL_LIBS\tbuiltin variable"},{"contents":"CMAKE_DOTNET_TARGET_FRAMEWORK","trigger":"CMAKE_DOTNET_TARGET_FRAMEWORK\tbuiltin variable"},{"contents":"CMAKE_DOTNET_TARGET_FRAMEWORK_VERSION","trigger":"CMAKE_DOTNET_TARGET_FRAMEWORK_VERSION\tbuiltin variable"},{"contents":"CMAKE_ECLIPSE_GENERATE_LINKED_RESOURCES","trigger":"CMAKE_ECLIPSE_GENERATE_LINKED_RESOURCES\tbuiltin variable"},{"contents":"CMAKE_ECLIPSE_GENERATE_SOURCE_PROJECT","trigger":"CMAKE_ECLIPSE_GENERATE_SOURCE_PROJECT\tbuiltin variable"},{"contents":"CMAKE_ECLIPSE_MAKE_ARGUMENTS","trigger":"CMAKE_ECLIPSE_MAKE_ARGUMENTS\tbuiltin variable"},{"contents":"CMAKE_ECLIPSE_RESOURCE_ENCODING","trigger":"CMAKE_ECLIPSE_RESOURCE_ENCODING\tbuiltin variable"},{"contents":"CMAKE_ECLIPSE_VERSION","trigger":"CMAKE_ECLIPSE_VERSION\tbuiltin variable"},{"contents":"CMAKE_EDIT_COMMAND","trigger":"CMAKE_EDIT_COMMAND\tbuiltin variable"},{"contents":"CMAKE_ENABLE_EXPORTS","trigger":"CMAKE_ENABLE_EXPORTS\tbuiltin variable"},{"contents":"CMAKE_ERROR_DEPRECATED","trigger":"CMAKE_ERROR_DEPRECATED\tbuiltin variable"},{"contents":"CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION","trigger":"CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION\tbuiltin variable"},{"contents":"CMAKE_EXECUTABLE_SUFFIX","trigger":"CMAKE_EXECUTABLE_SUFFIX\tbuiltin variable"},{"contents":"CMAKE_EXECUTE_PROCESS_COMMAND_ECHO","trigger":"CMAKE_EXECUTE_PROCESS_COMMAND_ECHO\tbuiltin variable"},{"contents":"CMAKE_EXE_LINKER_FLAGS","trigger":"CMAKE_EXE_LINKER_FLAGS\tbuiltin variable"},{"contents":"CMAKE_EXE_LINKER_FLAGS_INIT","trigger":"CMAKE_EXE_LINKER_FLAGS_INIT\tbuiltin variable"},{"contents":"CMAKE_EXPORT_COMPILE_COMMANDS","trigger":"CMAKE_EXPORT_COMPILE_COMMANDS\tbuiltin variable"},{"contents":"CMAKE_EXPORT_NO_PACKAGE_REGISTRY","trigger":"CMAKE_EXPORT_NO_PACKAGE_REGISTRY\tbuiltin variable"},{"contents":"CMAKE_EXPORT_PACKAGE_REGISTRY","trigger":"CMAKE_EXPORT_PACKAGE_REGISTRY\tbuiltin variable"},{"contents":"CMAKE_EXTRA_GENERATOR","trigger":"CMAKE_EXTRA_GENERATOR\tbuiltin variable"},{"contents":"CMAKE_EXTRA_SHARED_LIBRARY_SUFFIXES","trigger":"CMAKE_EXTRA_SHARED_LIBRARY_SUFFIXES\tbuiltin variable"},{"contents":"CMAKE_FIND_APPBUNDLE","trigger":"CMAKE_FIND_APPBUNDLE\tbuiltin variable"},{"contents":"CMAKE_FIND_DEBUG_MODE","trigger":"CMAKE_FIND_DEBUG_MODE\tbuiltin variable"},{"contents":"CMAKE_FIND_FRAMEWORK","trigger":"CMAKE_FIND_FRAMEWORK\tbuiltin variable"},{"contents":"CMAKE_FIND_LIBRARY_CUSTOM_LIB_SUFFIX","trigger":"CMAKE_FIND_LIBRARY_CUSTOM_LIB_SUFFIX\tbuiltin variable"},{"contents":"CMAKE_FIND_LIBRARY_PREFIXES","trigger":"CMAKE_FIND_LIBRARY_PREFIXES\tbuiltin variable"},{"contents":"CMAKE_FIND_LIBRARY_SUFFIXES","trigger":"CMAKE_FIND_LIBRARY_SUFFIXES\tbuiltin variable"},{"contents":"CMAKE_FIND_NO_INSTALL_PREFIX","trigger":"CMAKE_FIND_NO_INSTALL_PREFIX\tbuiltin variable"},{"contents":"CMAKE_FIND_PACKAGE_NAME","trigger":"CMAKE_FIND_PACKAGE_NAME\tbuiltin variable"},{"contents":"CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY","trigger":"CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY\tbuiltin variable"},{"contents":"CMAKE_FIND_PACKAGE_NO_SYSTEM_PACKAGE_REGISTRY","trigger":"CMAKE_FIND_PACKAGE_NO_SYSTEM_PACKAGE_REGISTRY\tbuiltin variable"},{"contents":"CMAKE_FIND_PACKAGE_PREFER_CONFIG","trigger":"CMAKE_FIND_PACKAGE_PREFER_CONFIG\tbuiltin variable"},{"contents":"CMAKE_FIND_PACKAGE_RESOLVE_SYMLINKS","trigger":"CMAKE_FIND_PACKAGE_RESOLVE_SYMLINKS\tbuiltin variable"},{"contents":"CMAKE_FIND_PACKAGE_SORT_DIRECTION","trigger":"CMAKE_FIND_PACKAGE_SORT_DIRECTION\tbuiltin variable"},{"contents":"CMAKE_FIND_PACKAGE_SORT_ORDER","trigger":"CMAKE_FIND_PACKAGE_SORT_ORDER\tbuiltin variable"},{"contents":"CMAKE_FIND_PACKAGE_WARN_NO_MODULE","trigger":"CMAKE_FIND_PACKAGE_WARN_NO_MODULE\tbuiltin variable"},{"contents":"CMAKE_FIND_ROOT_PATH","trigger":"CMAKE_FIND_ROOT_PATH\tbuiltin variable"},{"contents":"CMAKE_FIND_ROOT_PATH_MODE_INCLUDE","trigger":"CMAKE_FIND_ROOT_PATH_MODE_INCLUDE\tbuiltin variable"},{"contents":"CMAKE_FIND_ROOT_PATH_MODE_LIBRARY","trigger":"CMAKE_FIND_ROOT_PATH_MODE_LIBRARY\tbuiltin variable"},{"contents":"CMAKE_FIND_ROOT_PATH_MODE_PACKAGE","trigger":"CMAKE_FIND_ROOT_PATH_MODE_PACKAGE\tbuiltin variable"},{"contents":"CMAKE_FIND_ROOT_PATH_MODE_PROGRAM","trigger":"CMAKE_FIND_ROOT_PATH_MODE_PROGRAM\tbuiltin variable"},{"contents":"CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH","trigger":"CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH\tbuiltin variable"},{"contents":"CMAKE_FIND_USE_CMAKE_PATH","trigger":"CMAKE_FIND_USE_CMAKE_PATH\tbuiltin variable"},{"contents":"CMAKE_FIND_USE_CMAKE_SYSTEM_PATH","trigger":"CMAKE_FIND_USE_CMAKE_SYSTEM_PATH\tbuiltin variable"},{"contents":"CMAKE_FIND_USE_PACKAGE_REGISTRY","trigger":"CMAKE_FIND_USE_PACKAGE_REGISTRY\tbuiltin variable"},{"contents":"CMAKE_FIND_USE_PACKAGE_ROOT_PATH","trigger":"CMAKE_FIND_USE_PACKAGE_ROOT_PATH\tbuiltin variable"},{"contents":"CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH","trigger":"CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH\tbuiltin variable"},{"contents":"CMAKE_FIND_USE_SYSTEM_PACKAGE_REGISTRY","trigger":"CMAKE_FIND_USE_SYSTEM_PACKAGE_REGISTRY\tbuiltin variable"},{"contents":"CMAKE_FOLDER","trigger":"CMAKE_FOLDER\tbuiltin variable"},{"contents":"CMAKE_FRAMEWORK","trigger":"CMAKE_FRAMEWORK\tbuiltin variable"},{"contents":"CMAKE_FRAMEWORK_PATH","trigger":"CMAKE_FRAMEWORK_PATH\tbuiltin variable"},{"contents":"CMAKE_Fortran_FORMAT","trigger":"CMAKE_Fortran_FORMAT\tbuiltin variable"},{"contents":"CMAKE_Fortran_MODDIR_DEFAULT","trigger":"CMAKE_Fortran_MODDIR_DEFAULT\tbuiltin variable"},{"contents":"CMAKE_Fortran_MODDIR_FLAG","trigger":"CMAKE_Fortran_MODDIR_FLAG\tbuiltin variable"},{"contents":"CMAKE_Fortran_MODOUT_FLAG","trigger":"CMAKE_Fortran_MODOUT_FLAG\tbuiltin variable"},{"contents":"CMAKE_Fortran_MODULE_DIRECTORY","trigger":"CMAKE_Fortran_MODULE_DIRECTORY\tbuiltin variable"},{"contents":"CMAKE_Fortran_PREPROCESS","trigger":"CMAKE_Fortran_PREPROCESS\tbuiltin variable"},{"contents":"CMAKE_GENERATOR","trigger":"CMAKE_GENERATOR\tbuiltin variable"},{"contents":"CMAKE_GENERATOR_INSTANCE","trigger":"CMAKE_GENERATOR_INSTANCE\tbuiltin variable"},{"contents":"CMAKE_GENERATOR_PLATFORM","trigger":"CMAKE_GENERATOR_PLATFORM\tbuiltin variable"},{"contents":"CMAKE_GENERATOR_TOOLSET","trigger":"CMAKE_GENERATOR_TOOLSET\tbuiltin variable"},{"contents":"CMAKE_GHS_NO_SOURCE_GROUP_FILE","trigger":"CMAKE_GHS_NO_SOURCE_GROUP_FILE\tbuiltin variable"},{"contents":"CMAKE_GLOBAL_AUTOGEN_TARGET","trigger":"CMAKE_GLOBAL_AUTOGEN_TARGET\tbuiltin variable"},{"contents":"CMAKE_GLOBAL_AUTOGEN_TARGET_NAME","trigger":"CMAKE_GLOBAL_AUTOGEN_TARGET_NAME\tbuiltin variable"},{"contents":"CMAKE_GLOBAL_AUTORCC_TARGET","trigger":"CMAKE_GLOBAL_AUTORCC_TARGET\tbuiltin variable"},{"contents":"CMAKE_GLOBAL_AUTORCC_TARGET_NAME","trigger":"CMAKE_GLOBAL_AUTORCC_TARGET_NAME\tbuiltin variable"},{"contents":"CMAKE_GNUtoMS","trigger":"CMAKE_GNUtoMS\tbuiltin variable"},{"contents":"CMAKE_HOME_DIRECTORY","trigger":"CMAKE_HOME_DIRECTORY\tbuiltin variable"},{"contents":"CMAKE_HOST_APPLE","trigger":"CMAKE_HOST_APPLE\tbuiltin variable"},{"contents":"CMAKE_HOST_SOLARIS","trigger":"CMAKE_HOST_SOLARIS\tbuiltin variable"},{"contents":"CMAKE_HOST_SYSTEM","trigger":"CMAKE_HOST_SYSTEM\tbuiltin variable"},{"contents":"CMAKE_HOST_SYSTEM_NAME","trigger":"CMAKE_HOST_SYSTEM_NAME\tbuiltin variable"},{"contents":"CMAKE_HOST_SYSTEM_PROCESSOR","trigger":"CMAKE_HOST_SYSTEM_PROCESSOR\tbuiltin variable"},{"contents":"CMAKE_HOST_SYSTEM_VERSION","trigger":"CMAKE_HOST_SYSTEM_VERSION\tbuiltin variable"},{"contents":"CMAKE_HOST_UNIX","trigger":"CMAKE_HOST_UNIX\tbuiltin variable"},{"contents":"CMAKE_HOST_WIN32","trigger":"CMAKE_HOST_WIN32\tbuiltin variable"},{"contents":"CMAKE_IGNORE_PATH","trigger":"CMAKE_IGNORE_PATH\tbuiltin variable"},{"contents":"CMAKE_IMPORT_LIBRARY_PREFIX","trigger":"CMAKE_IMPORT_LIBRARY_PREFIX\tbuiltin variable"},{"contents":"CMAKE_IMPORT_LIBRARY_SUFFIX","trigger":"CMAKE_IMPORT_LIBRARY_SUFFIX\tbuiltin variable"},{"contents":"CMAKE_INCLUDE_CURRENT_DIR","trigger":"CMAKE_INCLUDE_CURRENT_DIR\tbuiltin variable"},{"contents":"CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE","trigger":"CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE\tbuiltin variable"},{"contents":"CMAKE_INCLUDE_DIRECTORIES_BEFORE","trigger":"CMAKE_INCLUDE_DIRECTORIES_BEFORE\tbuiltin variable"},{"contents":"CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE","trigger":"CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE\tbuiltin variable"},{"contents":"CMAKE_INCLUDE_PATH","trigger":"CMAKE_INCLUDE_PATH\tbuiltin variable"},{"contents":"CMAKE_INSTALL_DEFAULT_COMPONENT_NAME","trigger":"CMAKE_INSTALL_DEFAULT_COMPONENT_NAME\tbuiltin variable"},{"contents":"CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS","trigger":"CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS\tbuiltin variable"},{"contents":"CMAKE_INSTALL_MESSAGE","trigger":"CMAKE_INSTALL_MESSAGE\tbuiltin variable"},{"contents":"CMAKE_INSTALL_NAME_DIR","trigger":"CMAKE_INSTALL_NAME_DIR\tbuiltin variable"},{"contents":"CMAKE_INSTALL_PREFIX","trigger":"CMAKE_INSTALL_PREFIX\tbuiltin variable"},{"contents":"CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT","trigger":"CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT\tbuiltin variable"},{"contents":"CMAKE_INSTALL_REMOVE_ENVIRONMENT_RPATH","trigger":"CMAKE_INSTALL_REMOVE_ENVIRONMENT_RPATH\tbuiltin variable"},{"contents":"CMAKE_INSTALL_RPATH","trigger":"CMAKE_INSTALL_RPATH\tbuiltin variable"},{"contents":"CMAKE_INSTALL_RPATH_USE_LINK_PATH","trigger":"CMAKE_INSTALL_RPATH_USE_LINK_PATH\tbuiltin variable"},{"contents":"CMAKE_INTERNAL_PLATFORM_ABI","trigger":"CMAKE_INTERNAL_PLATFORM_ABI\tbuiltin variable"},{"contents":"CMAKE_INTERPROCEDURAL_OPTIMIZATION","trigger":"CMAKE_INTERPROCEDURAL_OPTIMIZATION\tbuiltin variable"},{"contents":"CMAKE_IOS_INSTALL_COMBINED","trigger":"CMAKE_IOS_INSTALL_COMBINED\tbuiltin variable"},{"contents":"CMAKE_ISPC_HEADER_DIRECTORY","trigger":"CMAKE_ISPC_HEADER_DIRECTORY\tbuiltin variable"},{"contents":"CMAKE_ISPC_HEADER_SUFFIX","trigger":"CMAKE_ISPC_HEADER_SUFFIX\tbuiltin variable"},{"contents":"CMAKE_ISPC_INSTRUCTION_SETS","trigger":"CMAKE_ISPC_INSTRUCTION_SETS\tbuiltin variable"},{"contents":"CMAKE_JOB_POOLS","trigger":"CMAKE_JOB_POOLS\tbuiltin variable"},{"contents":"CMAKE_JOB_POOL_COMPILE","trigger":"CMAKE_JOB_POOL_COMPILE\tbuiltin variable"},{"contents":"CMAKE_JOB_POOL_LINK","trigger":"CMAKE_JOB_POOL_LINK\tbuiltin variable"},{"contents":"CMAKE_JOB_POOL_PRECOMPILE_HEADER","trigger":"CMAKE_JOB_POOL_PRECOMPILE_HEADER\tbuiltin variable"},{"contents":"CMAKE_LIBRARY_ARCHITECTURE","trigger":"CMAKE_LIBRARY_ARCHITECTURE\tbuiltin variable"},{"contents":"CMAKE_LIBRARY_ARCHITECTURE_REGEX","trigger":"CMAKE_LIBRARY_ARCHITECTURE_REGEX\tbuiltin variable"},{"contents":"CMAKE_LIBRARY_OUTPUT_DIRECTORY","trigger":"CMAKE_LIBRARY_OUTPUT_DIRECTORY\tbuiltin variable"},{"contents":"CMAKE_LIBRARY_PATH","trigger":"CMAKE_LIBRARY_PATH\tbuiltin variable"},{"contents":"CMAKE_LIBRARY_PATH_FLAG","trigger":"CMAKE_LIBRARY_PATH_FLAG\tbuiltin variable"},{"contents":"CMAKE_LINK_DEF_FILE_FLAG","trigger":"CMAKE_LINK_DEF_FILE_FLAG\tbuiltin variable"},{"contents":"CMAKE_LINK_DEPENDS_NO_SHARED","trigger":"CMAKE_LINK_DEPENDS_NO_SHARED\tbuiltin variable"},{"contents":"CMAKE_LINK_DIRECTORIES_BEFORE","trigger":"CMAKE_LINK_DIRECTORIES_BEFORE\tbuiltin variable"},{"contents":"CMAKE_LINK_INTERFACE_LIBRARIES","trigger":"CMAKE_LINK_INTERFACE_LIBRARIES\tbuiltin variable"},{"contents":"CMAKE_LINK_LIBRARY_FILE_FLAG","trigger":"CMAKE_LINK_LIBRARY_FILE_FLAG\tbuiltin variable"},{"contents":"CMAKE_LINK_LIBRARY_FLAG","trigger":"CMAKE_LINK_LIBRARY_FLAG\tbuiltin variable"},{"contents":"CMAKE_LINK_LIBRARY_SUFFIX","trigger":"CMAKE_LINK_LIBRARY_SUFFIX\tbuiltin variable"},{"contents":"CMAKE_LINK_SEARCH_END_STATIC","trigger":"CMAKE_LINK_SEARCH_END_STATIC\tbuiltin variable"},{"contents":"CMAKE_LINK_SEARCH_START_STATIC","trigger":"CMAKE_LINK_SEARCH_START_STATIC\tbuiltin variable"},{"contents":"CMAKE_LINK_WHAT_YOU_USE","trigger":"CMAKE_LINK_WHAT_YOU_USE\tbuiltin variable"},{"contents":"CMAKE_MACOSX_BUNDLE","trigger":"CMAKE_MACOSX_BUNDLE\tbuiltin variable"},{"contents":"CMAKE_MACOSX_RPATH","trigger":"CMAKE_MACOSX_RPATH\tbuiltin variable"},{"contents":"CMAKE_MAJOR_VERSION","trigger":"CMAKE_MAJOR_VERSION\tbuiltin variable"},{"contents":"CMAKE_MAKE_PROGRAM","trigger":"CMAKE_MAKE_PROGRAM\tbuiltin variable"},{"contents":"CMAKE_MATCH_COUNT","trigger":"CMAKE_MATCH_COUNT\tbuiltin variable"},{"contents":"CMAKE_MAXIMUM_RECURSION_DEPTH","trigger":"CMAKE_MAXIMUM_RECURSION_DEPTH\tbuiltin variable"},{"contents":"CMAKE_MESSAGE_CONTEXT","trigger":"CMAKE_MESSAGE_CONTEXT\tbuiltin variable"},{"contents":"CMAKE_MESSAGE_CONTEXT_SHOW","trigger":"CMAKE_MESSAGE_CONTEXT_SHOW\tbuiltin variable"},{"contents":"CMAKE_MESSAGE_INDENT","trigger":"CMAKE_MESSAGE_INDENT\tbuiltin variable"},{"contents":"CMAKE_MESSAGE_LOG_LEVEL","trigger":"CMAKE_MESSAGE_LOG_LEVEL\tbuiltin variable"},{"contents":"CMAKE_MFC_FLAG","trigger":"CMAKE_MFC_FLAG\tbuiltin variable"},{"contents":"CMAKE_MINIMUM_REQUIRED_VERSION","trigger":"CMAKE_MINIMUM_REQUIRED_VERSION\tbuiltin variable"},{"contents":"CMAKE_MINOR_VERSION","trigger":"CMAKE_MINOR_VERSION\tbuiltin variable"},{"contents":"CMAKE_MODULE_LINKER_FLAGS","trigger":"CMAKE_MODULE_LINKER_FLAGS\tbuiltin variable"},{"contents":"CMAKE_MODULE_LINKER_FLAGS_INIT","trigger":"CMAKE_MODULE_LINKER_FLAGS_INIT\tbuiltin variable"},{"contents":"CMAKE_MODULE_PATH","trigger":"CMAKE_MODULE_PATH\tbuiltin variable"},{"contents":"CMAKE_MSVCIDE_RUN_PATH","trigger":"CMAKE_MSVCIDE_RUN_PATH\tbuiltin variable"},{"contents":"CMAKE_MSVC_RUNTIME_LIBRARY","trigger":"CMAKE_MSVC_RUNTIME_LIBRARY\tbuiltin variable"},{"contents":"CMAKE_NETRC","trigger":"CMAKE_NETRC\tbuiltin variable"},{"contents":"CMAKE_NETRC_FILE","trigger":"CMAKE_NETRC_FILE\tbuiltin variable"},{"contents":"CMAKE_NINJA_OUTPUT_PATH_PREFIX","trigger":"CMAKE_NINJA_OUTPUT_PATH_PREFIX\tbuiltin variable"},{"contents":"CMAKE_NOT_USING_CONFIG_FLAGS","trigger":"CMAKE_NOT_USING_CONFIG_FLAGS\tbuiltin variable"},{"contents":"CMAKE_NO_BUILTIN_CHRPATH","trigger":"CMAKE_NO_BUILTIN_CHRPATH\tbuiltin variable"},{"contents":"CMAKE_NO_SYSTEM_FROM_IMPORTED","trigger":"CMAKE_NO_SYSTEM_FROM_IMPORTED\tbuiltin variable"},{"contents":"CMAKE_OBJCXX_EXTENSIONS","trigger":"CMAKE_OBJCXX_EXTENSIONS\tbuiltin variable"},{"contents":"CMAKE_OBJCXX_STANDARD","trigger":"CMAKE_OBJCXX_STANDARD\tbuiltin variable"},{"contents":"CMAKE_OBJCXX_STANDARD_REQUIRED","trigger":"CMAKE_OBJCXX_STANDARD_REQUIRED\tbuiltin variable"},{"contents":"CMAKE_OBJC_EXTENSIONS","trigger":"CMAKE_OBJC_EXTENSIONS\tbuiltin variable"},{"contents":"CMAKE_OBJC_STANDARD","trigger":"CMAKE_OBJC_STANDARD\tbuiltin variable"},{"contents":"CMAKE_OBJC_STANDARD_REQUIRED","trigger":"CMAKE_OBJC_STANDARD_REQUIRED\tbuiltin variable"},{"contents":"CMAKE_OBJECT_PATH_MAX","trigger":"CMAKE_OBJECT_PATH_MAX\tbuiltin variable"},{"contents":"CMAKE_OPTIMIZE_DEPENDENCIES","trigger":"CMAKE_OPTIMIZE_DEPENDENCIES\tbuiltin variable"},{"contents":"CMAKE_OSX_ARCHITECTURES","trigger":"CMAKE_OSX_ARCHITECTURES\tbuiltin variable"},{"contents":"CMAKE_OSX_DEPLOYMENT_TARGET","trigger":"CMAKE_OSX_DEPLOYMENT_TARGET\tbuiltin variable"},{"contents":"CMAKE_OSX_SYSROOT","trigger":"CMAKE_OSX_SYSROOT\tbuiltin variable"},{"contents":"CMAKE_PARENT_LIST_FILE","trigger":"CMAKE_PARENT_LIST_FILE\tbuiltin variable"},{"contents":"CMAKE_PATCH_VERSION","trigger":"CMAKE_PATCH_VERSION\tbuiltin variable"},{"contents":"CMAKE_PCH_INSTANTIATE_TEMPLATES","trigger":"CMAKE_PCH_INSTANTIATE_TEMPLATES\tbuiltin variable"},{"contents":"CMAKE_PCH_WARN_INVALID","trigger":"CMAKE_PCH_WARN_INVALID\tbuiltin variable"},{"contents":"CMAKE_PDB_OUTPUT_DIRECTORY","trigger":"CMAKE_PDB_OUTPUT_DIRECTORY\tbuiltin variable"},{"contents":"CMAKE_POSITION_INDEPENDENT_CODE","trigger":"CMAKE_POSITION_INDEPENDENT_CODE\tbuiltin variable"},{"contents":"CMAKE_PREFIX_PATH","trigger":"CMAKE_PREFIX_PATH\tbuiltin variable"},{"contents":"CMAKE_PROGRAM_PATH","trigger":"CMAKE_PROGRAM_PATH\tbuiltin variable"},{"contents":"CMAKE_PROJECT_DESCRIPTION","trigger":"CMAKE_PROJECT_DESCRIPTION\tbuiltin variable"},{"contents":"CMAKE_PROJECT_HOMEPAGE_URL","trigger":"CMAKE_PROJECT_HOMEPAGE_URL\tbuiltin variable"},{"contents":"CMAKE_PROJECT_INCLUDE","trigger":"CMAKE_PROJECT_INCLUDE\tbuiltin variable"},{"contents":"CMAKE_PROJECT_INCLUDE_BEFORE","trigger":"CMAKE_PROJECT_INCLUDE_BEFORE\tbuiltin variable"},{"contents":"CMAKE_PROJECT_NAME","trigger":"CMAKE_PROJECT_NAME\tbuiltin variable"},{"contents":"CMAKE_PROJECT_VERSION","trigger":"CMAKE_PROJECT_VERSION\tbuiltin variable"},{"contents":"CMAKE_PROJECT_VERSION_MAJOR","trigger":"CMAKE_PROJECT_VERSION_MAJOR\tbuiltin variable"},{"contents":"CMAKE_PROJECT_VERSION_MINOR","trigger":"CMAKE_PROJECT_VERSION_MINOR\tbuiltin variable"},{"contents":"CMAKE_PROJECT_VERSION_PATCH","trigger":"CMAKE_PROJECT_VERSION_PATCH\tbuiltin variable"},{"contents":"CMAKE_PROJECT_VERSION_TWEAK","trigger":"CMAKE_PROJECT_VERSION_TWEAK\tbuiltin variable"},{"contents":"CMAKE_RANLIB","trigger":"CMAKE_RANLIB\tbuiltin variable"},{"contents":"CMAKE_ROOT","trigger":"CMAKE_ROOT\tbuiltin variable"},{"contents":"CMAKE_RULE_MESSAGES","trigger":"CMAKE_RULE_MESSAGES\tbuiltin variable"},{"contents":"CMAKE_RUNTIME_OUTPUT_DIRECTORY","trigger":"CMAKE_RUNTIME_OUTPUT_DIRECTORY\tbuiltin variable"},{"contents":"CMAKE_SCRIPT_MODE_FILE","trigger":"CMAKE_SCRIPT_MODE_FILE\tbuiltin variable"},{"contents":"CMAKE_SHARED_LIBRARY_PREFIX","trigger":"CMAKE_SHARED_LIBRARY_PREFIX\tbuiltin variable"},{"contents":"CMAKE_SHARED_LIBRARY_SUFFIX","trigger":"CMAKE_SHARED_LIBRARY_SUFFIX\tbuiltin variable"},{"contents":"CMAKE_SHARED_LINKER_FLAGS","trigger":"CMAKE_SHARED_LINKER_FLAGS\tbuiltin variable"},{"contents":"CMAKE_SHARED_LINKER_FLAGS_INIT","trigger":"CMAKE_SHARED_LINKER_FLAGS_INIT\tbuiltin variable"},{"contents":"CMAKE_SHARED_MODULE_PREFIX","trigger":"CMAKE_SHARED_MODULE_PREFIX\tbuiltin variable"},{"contents":"CMAKE_SHARED_MODULE_SUFFIX","trigger":"CMAKE_SHARED_MODULE_SUFFIX\tbuiltin variable"},{"contents":"CMAKE_SIZEOF_VOID_P","trigger":"CMAKE_SIZEOF_VOID_P\tbuiltin variable"},{"contents":"CMAKE_SKIP_BUILD_RPATH","trigger":"CMAKE_SKIP_BUILD_RPATH\tbuiltin variable"},{"contents":"CMAKE_SKIP_INSTALL_ALL_DEPENDENCY","trigger":"CMAKE_SKIP_INSTALL_ALL_DEPENDENCY\tbuiltin variable"},{"contents":"CMAKE_SKIP_INSTALL_RPATH","trigger":"CMAKE_SKIP_INSTALL_RPATH\tbuiltin variable"},{"contents":"CMAKE_SKIP_INSTALL_RULES","trigger":"CMAKE_SKIP_INSTALL_RULES\tbuiltin variable"},{"contents":"CMAKE_SKIP_RPATH","trigger":"CMAKE_SKIP_RPATH\tbuiltin variable"},{"contents":"CMAKE_SOURCE_DIR","trigger":"CMAKE_SOURCE_DIR\tbuiltin variable"},{"contents":"CMAKE_STAGING_PREFIX","trigger":"CMAKE_STAGING_PREFIX\tbuiltin variable"},{"contents":"CMAKE_STATIC_LIBRARY_PREFIX","trigger":"CMAKE_STATIC_LIBRARY_PREFIX\tbuiltin variable"},{"contents":"CMAKE_STATIC_LIBRARY_SUFFIX","trigger":"CMAKE_STATIC_LIBRARY_SUFFIX\tbuiltin variable"},{"contents":"CMAKE_STATIC_LINKER_FLAGS","trigger":"CMAKE_STATIC_LINKER_FLAGS\tbuiltin variable"},{"contents":"CMAKE_STATIC_LINKER_FLAGS_INIT","trigger":"CMAKE_STATIC_LINKER_FLAGS_INIT\tbuiltin variable"},{"contents":"CMAKE_SUBLIME_TEXT_2_ENV_SETTINGS","trigger":"CMAKE_SUBLIME_TEXT_2_ENV_SETTINGS\tbuiltin variable"},{"contents":"CMAKE_SUBLIME_TEXT_2_EXCLUDE_BUILD_TREE","trigger":"CMAKE_SUBLIME_TEXT_2_EXCLUDE_BUILD_TREE\tbuiltin variable"},{"contents":"CMAKE_SUPPRESS_REGENERATION","trigger":"CMAKE_SUPPRESS_REGENERATION\tbuiltin variable"},{"contents":"CMAKE_SYSROOT","trigger":"CMAKE_SYSROOT\tbuiltin variable"},{"contents":"CMAKE_SYSROOT_COMPILE","trigger":"CMAKE_SYSROOT_COMPILE\tbuiltin variable"},{"contents":"CMAKE_SYSROOT_LINK","trigger":"CMAKE_SYSROOT_LINK\tbuiltin variable"},{"contents":"CMAKE_SYSTEM","trigger":"CMAKE_SYSTEM\tbuiltin variable"},{"contents":"CMAKE_SYSTEM_APPBUNDLE_PATH","trigger":"CMAKE_SYSTEM_APPBUNDLE_PATH\tbuiltin variable"},{"contents":"CMAKE_SYSTEM_FRAMEWORK_PATH","trigger":"CMAKE_SYSTEM_FRAMEWORK_PATH\tbuiltin variable"},{"contents":"CMAKE_SYSTEM_IGNORE_PATH","trigger":"CMAKE_SYSTEM_IGNORE_PATH\tbuiltin variable"},{"contents":"CMAKE_SYSTEM_INCLUDE_PATH","trigger":"CMAKE_SYSTEM_INCLUDE_PATH\tbuiltin variable"},{"contents":"CMAKE_SYSTEM_LIBRARY_PATH","trigger":"CMAKE_SYSTEM_LIBRARY_PATH\tbuiltin variable"},{"contents":"CMAKE_SYSTEM_NAME","trigger":"CMAKE_SYSTEM_NAME\tbuiltin variable"},{"contents":"CMAKE_SYSTEM_PREFIX_PATH","trigger":"CMAKE_SYSTEM_PREFIX_PATH\tbuiltin variable"},{"contents":"CMAKE_SYSTEM_PROCESSOR","trigger":"CMAKE_SYSTEM_PROCESSOR\tbuiltin variable"},{"contents":"CMAKE_SYSTEM_PROGRAM_PATH","trigger":"CMAKE_SYSTEM_PROGRAM_PATH\tbuiltin variable"},{"contents":"CMAKE_SYSTEM_VERSION","trigger":"CMAKE_SYSTEM_VERSION\tbuiltin variable"},{"contents":"CMAKE_Swift_LANGUAGE_VERSION","trigger":"CMAKE_Swift_LANGUAGE_VERSION\tbuiltin variable"},{"contents":"CMAKE_Swift_MODULE_DIRECTORY","trigger":"CMAKE_Swift_MODULE_DIRECTORY\tbuiltin variable"},{"contents":"CMAKE_Swift_NUM_THREADS","trigger":"CMAKE_Swift_NUM_THREADS\tbuiltin variable"},{"contents":"CMAKE_TOOLCHAIN_FILE","trigger":"CMAKE_TOOLCHAIN_FILE\tbuiltin variable"},{"contents":"CMAKE_TRY_COMPILE_CONFIGURATION","trigger":"CMAKE_TRY_COMPILE_CONFIGURATION\tbuiltin variable"},{"contents":"CMAKE_TRY_COMPILE_PLATFORM_VARIABLES","trigger":"CMAKE_TRY_COMPILE_PLATFORM_VARIABLES\tbuiltin variable"},{"contents":"CMAKE_TRY_COMPILE_TARGET_TYPE","trigger":"CMAKE_TRY_COMPILE_TARGET_TYPE\tbuiltin variable"},{"contents":"CMAKE_TWEAK_VERSION","trigger":"CMAKE_TWEAK_VERSION\tbuiltin variable"},{"contents":"CMAKE_UNITY_BUILD","trigger":"CMAKE_UNITY_BUILD\tbuiltin variable"},{"contents":"CMAKE_UNITY_BUILD_BATCH_SIZE","trigger":"CMAKE_UNITY_BUILD_BATCH_SIZE\tbuiltin variable"},{"contents":"CMAKE_USER_MAKE_RULES_OVERRIDE","trigger":"CMAKE_USER_MAKE_RULES_OVERRIDE\tbuiltin variable"},{"contents":"CMAKE_USE_RELATIVE_PATHS","trigger":"CMAKE_USE_RELATIVE_PATHS\tbuiltin variable"},{"contents":"CMAKE_VERBOSE_MAKEFILE","trigger":"CMAKE_VERBOSE_MAKEFILE\tbuiltin variable"},{"contents":"CMAKE_VERSION","trigger":"CMAKE_VERSION\tbuiltin variable"},{"contents":"CMAKE_VISIBILITY_INLINES_HIDDEN","trigger":"CMAKE_VISIBILITY_INLINES_HIDDEN\tbuiltin variable"},{"contents":"CMAKE_VS_DEVENV_COMMAND","trigger":"CMAKE_VS_DEVENV_COMMAND\tbuiltin variable"},{"contents":"CMAKE_VS_GLOBALS","trigger":"CMAKE_VS_GLOBALS\tbuiltin variable"},{"contents":"CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD","trigger":"CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD\tbuiltin variable"},{"contents":"CMAKE_VS_INCLUDE_PACKAGE_TO_DEFAULT_BUILD","trigger":"CMAKE_VS_INCLUDE_PACKAGE_TO_DEFAULT_BUILD\tbuiltin variable"},{"contents":"CMAKE_VS_INTEL_Fortran_PROJECT_VERSION","trigger":"CMAKE_VS_INTEL_Fortran_PROJECT_VERSION\tbuiltin variable"},{"contents":"CMAKE_VS_JUST_MY_CODE_DEBUGGING","trigger":"CMAKE_VS_JUST_MY_CODE_DEBUGGING\tbuiltin variable"},{"contents":"CMAKE_VS_MSBUILD_COMMAND","trigger":"CMAKE_VS_MSBUILD_COMMAND\tbuiltin variable"},{"contents":"CMAKE_VS_NsightTegra_VERSION","trigger":"CMAKE_VS_NsightTegra_VERSION\tbuiltin variable"},{"contents":"CMAKE_VS_PLATFORM_NAME","trigger":"CMAKE_VS_PLATFORM_NAME\tbuiltin variable"},{"contents":"CMAKE_VS_PLATFORM_NAME_DEFAULT","trigger":"CMAKE_VS_PLATFORM_NAME_DEFAULT\tbuiltin variable"},{"contents":"CMAKE_VS_PLATFORM_TOOLSET","trigger":"CMAKE_VS_PLATFORM_TOOLSET\tbuiltin variable"},{"contents":"CMAKE_VS_PLATFORM_TOOLSET_CUDA","trigger":"CMAKE_VS_PLATFORM_TOOLSET_CUDA\tbuiltin variable"},{"contents":"CMAKE_VS_PLATFORM_TOOLSET_CUDA_CUSTOM_DIR","trigger":"CMAKE_VS_PLATFORM_TOOLSET_CUDA_CUSTOM_DIR\tbuiltin variable"},{"contents":"CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE","trigger":"CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE\tbuiltin variable"},{"contents":"CMAKE_VS_PLATFORM_TOOLSET_VERSION","trigger":"CMAKE_VS_PLATFORM_TOOLSET_VERSION\tbuiltin variable"},{"contents":"CMAKE_VS_SDK_EXCLUDE_DIRECTORIES","trigger":"CMAKE_VS_SDK_EXCLUDE_DIRECTORIES\tbuiltin variable"},{"contents":"CMAKE_VS_SDK_EXECUTABLE_DIRECTORIES","trigger":"CMAKE_VS_SDK_EXECUTABLE_DIRECTORIES\tbuiltin variable"},{"contents":"CMAKE_VS_SDK_INCLUDE_DIRECTORIES","trigger":"CMAKE_VS_SDK_INCLUDE_DIRECTORIES\tbuiltin variable"},{"contents":"CMAKE_VS_SDK_LIBRARY_DIRECTORIES","trigger":"CMAKE_VS_SDK_LIBRARY_DIRECTORIES\tbuiltin variable"},{"contents":"CMAKE_VS_SDK_LIBRARY_WINRT_DIRECTORIES","trigger":"CMAKE_VS_SDK_LIBRARY_WINRT_DIRECTORIES\tbuiltin variable"},{"contents":"CMAKE_VS_SDK_REFERENCE_DIRECTORIES","trigger":"CMAKE_VS_SDK_REFERENCE_DIRECTORIES\tbuiltin variable"},{"contents":"CMAKE_VS_SDK_SOURCE_DIRECTORIES","trigger":"CMAKE_VS_SDK_SOURCE_DIRECTORIES\tbuiltin variable"},{"contents":"CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION","trigger":"CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION\tbuiltin variable"},{"contents":"CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION_MAXIMUM","trigger":"CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION_MAXIMUM\tbuiltin variable"},{"contents":"CMAKE_VS_WINRT_BY_DEFAULT","trigger":"CMAKE_VS_WINRT_BY_DEFAULT\tbuiltin variable"},{"contents":"CMAKE_WARN_DEPRECATED","trigger":"CMAKE_WARN_DEPRECATED\tbuiltin variable"},{"contents":"CMAKE_WARN_ON_ABSOLUTE_INSTALL_DESTINATION","trigger":"CMAKE_WARN_ON_ABSOLUTE_INSTALL_DESTINATION\tbuiltin variable"},{"contents":"CMAKE_WIN32_EXECUTABLE","trigger":"CMAKE_WIN32_EXECUTABLE\tbuiltin variable"},{"contents":"CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS","trigger":"CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS\tbuiltin variable"},{"contents":"CMAKE_XCODE_BUILD_SYSTEM","trigger":"CMAKE_XCODE_BUILD_SYSTEM\tbuiltin variable"},{"contents":"CMAKE_XCODE_GENERATE_SCHEME","trigger":"CMAKE_XCODE_GENERATE_SCHEME\tbuiltin variable"},{"contents":"CMAKE_XCODE_GENERATE_TOP_LEVEL_PROJECT_ONLY","trigger":"CMAKE_XCODE_GENERATE_TOP_LEVEL_PROJECT_ONLY\tbuiltin variable"},{"contents":"CMAKE_XCODE_LINK_BUILD_PHASE_MODE","trigger":"CMAKE_XCODE_LINK_BUILD_PHASE_MODE\tbuiltin variable"},{"contents":"CMAKE_XCODE_PLATFORM_TOOLSET","trigger":"CMAKE_XCODE_PLATFORM_TOOLSET\tbuiltin variable"},{"contents":"CMAKE_XCODE_SCHEME_ADDRESS_SANITIZER","trigger":"CMAKE_XCODE_SCHEME_ADDRESS_SANITIZER\tbuiltin variable"},{"contents":"CMAKE_XCODE_SCHEME_ADDRESS_SANITIZER_USE_AFTER_RETURN","trigger":"CMAKE_XCODE_SCHEME_ADDRESS_SANITIZER_USE_AFTER_RETURN\tbuiltin variable"},{"contents":"CMAKE_XCODE_SCHEME_DEBUG_DOCUMENT_VERSIONING","trigger":"CMAKE_XCODE_SCHEME_DEBUG_DOCUMENT_VERSIONING\tbuiltin variable"},{"contents":"CMAKE_XCODE_SCHEME_DISABLE_MAIN_THREAD_CHECKER","trigger":"CMAKE_XCODE_SCHEME_DISABLE_MAIN_THREAD_CHECKER\tbuiltin variable"},{"contents":"CMAKE_XCODE_SCHEME_DYNAMIC_LIBRARY_LOADS","trigger":"CMAKE_XCODE_SCHEME_DYNAMIC_LIBRARY_LOADS\tbuiltin variable"},{"contents":"CMAKE_XCODE_SCHEME_DYNAMIC_LINKER_API_USAGE","trigger":"CMAKE_XCODE_SCHEME_DYNAMIC_LINKER_API_USAGE\tbuiltin variable"},{"contents":"CMAKE_XCODE_SCHEME_ENVIRONMENT","trigger":"CMAKE_XCODE_SCHEME_ENVIRONMENT\tbuiltin variable"},{"contents":"CMAKE_XCODE_SCHEME_GUARD_MALLOC","trigger":"CMAKE_XCODE_SCHEME_GUARD_MALLOC\tbuiltin variable"},{"contents":"CMAKE_XCODE_SCHEME_MAIN_THREAD_CHECKER_STOP","trigger":"CMAKE_XCODE_SCHEME_MAIN_THREAD_CHECKER_STOP\tbuiltin variable"},{"contents":"CMAKE_XCODE_SCHEME_MALLOC_GUARD_EDGES","trigger":"CMAKE_XCODE_SCHEME_MALLOC_GUARD_EDGES\tbuiltin variable"},{"contents":"CMAKE_XCODE_SCHEME_MALLOC_SCRIBBLE","trigger":"CMAKE_XCODE_SCHEME_MALLOC_SCRIBBLE\tbuiltin variable"},{"contents":"CMAKE_XCODE_SCHEME_MALLOC_STACK","trigger":"CMAKE_XCODE_SCHEME_MALLOC_STACK\tbuiltin variable"},{"contents":"CMAKE_XCODE_SCHEME_THREAD_SANITIZER","trigger":"CMAKE_XCODE_SCHEME_THREAD_SANITIZER\tbuiltin variable"},{"contents":"CMAKE_XCODE_SCHEME_THREAD_SANITIZER_STOP","trigger":"CMAKE_XCODE_SCHEME_THREAD_SANITIZER_STOP\tbuiltin variable"},{"contents":"CMAKE_XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER","trigger":"CMAKE_XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER\tbuiltin variable"},{"contents":"CMAKE_XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER_STOP","trigger":"CMAKE_XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER_STOP\tbuiltin variable"},{"contents":"CMAKE_XCODE_SCHEME_WORKING_DIRECTORY","trigger":"CMAKE_XCODE_SCHEME_WORKING_DIRECTORY\tbuiltin variable"},{"contents":"CMAKE_XCODE_SCHEME_ZOMBIE_OBJECTS","trigger":"CMAKE_XCODE_SCHEME_ZOMBIE_OBJECTS\tbuiltin variable"},{"contents":"CPACK_ABSOLUTE_DESTINATION_FILES","trigger":"CPACK_ABSOLUTE_DESTINATION_FILES\tbuiltin variable"},{"contents":"CPACK_COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY","trigger":"CPACK_COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY\tbuiltin variable"},{"contents":"CPACK_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION","trigger":"CPACK_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION\tbuiltin variable"},{"contents":"CPACK_INCLUDE_TOPLEVEL_DIRECTORY","trigger":"CPACK_INCLUDE_TOPLEVEL_DIRECTORY\tbuiltin variable"},{"contents":"CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS","trigger":"CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS\tbuiltin variable"},{"contents":"CPACK_PACKAGING_INSTALL_PREFIX","trigger":"CPACK_PACKAGING_INSTALL_PREFIX\tbuiltin variable"},{"contents":"CPACK_SET_DESTDIR","trigger":"CPACK_SET_DESTDIR\tbuiltin variable"},{"contents":"CPACK_WARN_ON_ABSOLUTE_INSTALL_DESTINATION","trigger":"CPACK_WARN_ON_ABSOLUTE_INSTALL_DESTINATION\tbuiltin variable"},{"contents":"CTEST_BINARY_DIRECTORY","trigger":"CTEST_BINARY_DIRECTORY\tbuiltin variable"},{"contents":"CTEST_BUILD_COMMAND","trigger":"CTEST_BUILD_COMMAND\tbuiltin variable"},{"contents":"CTEST_BUILD_NAME","trigger":"CTEST_BUILD_NAME\tbuiltin variable"},{"contents":"CTEST_BZR_COMMAND","trigger":"CTEST_BZR_COMMAND\tbuiltin variable"},{"contents":"CTEST_BZR_UPDATE_OPTIONS","trigger":"CTEST_BZR_UPDATE_OPTIONS\tbuiltin variable"},{"contents":"CTEST_CHANGE_ID","trigger":"CTEST_CHANGE_ID\tbuiltin variable"},{"contents":"CTEST_CHECKOUT_COMMAND","trigger":"CTEST_CHECKOUT_COMMAND\tbuiltin variable"},{"contents":"CTEST_CONFIGURATION_TYPE","trigger":"CTEST_CONFIGURATION_TYPE\tbuiltin variable"},{"contents":"CTEST_CONFIGURE_COMMAND","trigger":"CTEST_CONFIGURE_COMMAND\tbuiltin variable"},{"contents":"CTEST_COVERAGE_COMMAND","trigger":"CTEST_COVERAGE_COMMAND\tbuiltin variable"},{"contents":"CTEST_COVERAGE_EXTRA_FLAGS","trigger":"CTEST_COVERAGE_EXTRA_FLAGS\tbuiltin variable"},{"contents":"CTEST_CURL_OPTIONS","trigger":"CTEST_CURL_OPTIONS\tbuiltin variable"},{"contents":"CTEST_CUSTOM_COVERAGE_EXCLUDE","trigger":"CTEST_CUSTOM_COVERAGE_EXCLUDE\tbuiltin variable"},{"contents":"CTEST_CUSTOM_ERROR_EXCEPTION","trigger":"CTEST_CUSTOM_ERROR_EXCEPTION\tbuiltin variable"},{"contents":"CTEST_CUSTOM_ERROR_MATCH","trigger":"CTEST_CUSTOM_ERROR_MATCH\tbuiltin variable"},{"contents":"CTEST_CUSTOM_ERROR_POST_CONTEXT","trigger":"CTEST_CUSTOM_ERROR_POST_CONTEXT\tbuiltin variable"},{"contents":"CTEST_CUSTOM_ERROR_PRE_CONTEXT","trigger":"CTEST_CUSTOM_ERROR_PRE_CONTEXT\tbuiltin variable"},{"contents":"CTEST_CUSTOM_MAXIMUM_FAILED_TEST_OUTPUT_SIZE","trigger":"CTEST_CUSTOM_MAXIMUM_FAILED_TEST_OUTPUT_SIZE\tbuiltin variable"},{"contents":"CTEST_CUSTOM_MAXIMUM_NUMBER_OF_ERRORS","trigger":"CTEST_CUSTOM_MAXIMUM_NUMBER_OF_ERRORS\tbuiltin variable"},{"contents":"CTEST_CUSTOM_MAXIMUM_NUMBER_OF_WARNINGS","trigger":"CTEST_CUSTOM_MAXIMUM_NUMBER_OF_WARNINGS\tbuiltin variable"},{"contents":"CTEST_CUSTOM_MAXIMUM_PASSED_TEST_OUTPUT_SIZE","trigger":"CTEST_CUSTOM_MAXIMUM_PASSED_TEST_OUTPUT_SIZE\tbuiltin variable"},{"contents":"CTEST_CUSTOM_MEMCHECK_IGNORE","trigger":"CTEST_CUSTOM_MEMCHECK_IGNORE\tbuiltin variable"},{"contents":"CTEST_CUSTOM_POST_MEMCHECK","trigger":"CTEST_CUSTOM_POST_MEMCHECK\tbuiltin variable"},{"contents":"CTEST_CUSTOM_POST_TEST","trigger":"CTEST_CUSTOM_POST_TEST\tbuiltin variable"},{"contents":"CTEST_CUSTOM_PRE_MEMCHECK","trigger":"CTEST_CUSTOM_PRE_MEMCHECK\tbuiltin variable"},{"contents":"CTEST_CUSTOM_PRE_TEST","trigger":"CTEST_CUSTOM_PRE_TEST\tbuiltin variable"},{"contents":"CTEST_CUSTOM_TESTS_IGNORE","trigger":"CTEST_CUSTOM_TESTS_IGNORE\tbuiltin variable"},{"contents":"CTEST_CUSTOM_WARNING_EXCEPTION","trigger":"CTEST_CUSTOM_WARNING_EXCEPTION\tbuiltin variable"},{"contents":"CTEST_CUSTOM_WARNING_MATCH","trigger":"CTEST_CUSTOM_WARNING_MATCH\tbuiltin variable"},{"contents":"CTEST_CVS_CHECKOUT","trigger":"CTEST_CVS_CHECKOUT\tbuiltin variable"},{"contents":"CTEST_CVS_COMMAND","trigger":"CTEST_CVS_COMMAND\tbuiltin variable"},{"contents":"CTEST_CVS_UPDATE_OPTIONS","trigger":"CTEST_CVS_UPDATE_OPTIONS\tbuiltin variable"},{"contents":"CTEST_DROP_LOCATION","trigger":"CTEST_DROP_LOCATION\tbuiltin variable"},{"contents":"CTEST_DROP_METHOD","trigger":"CTEST_DROP_METHOD\tbuiltin variable"},{"contents":"CTEST_DROP_SITE","trigger":"CTEST_DROP_SITE\tbuiltin variable"},{"contents":"CTEST_DROP_SITE_CDASH","trigger":"CTEST_DROP_SITE_CDASH\tbuiltin variable"},{"contents":"CTEST_DROP_SITE_PASSWORD","trigger":"CTEST_DROP_SITE_PASSWORD\tbuiltin variable"},{"contents":"CTEST_DROP_SITE_USER","trigger":"CTEST_DROP_SITE_USER\tbuiltin variable"},{"contents":"CTEST_EXTRA_COVERAGE_GLOB","trigger":"CTEST_EXTRA_COVERAGE_GLOB\tbuiltin variable"},{"contents":"CTEST_GIT_COMMAND","trigger":"CTEST_GIT_COMMAND\tbuiltin variable"},{"contents":"CTEST_GIT_INIT_SUBMODULES","trigger":"CTEST_GIT_INIT_SUBMODULES\tbuiltin variable"},{"contents":"CTEST_GIT_UPDATE_CUSTOM","trigger":"CTEST_GIT_UPDATE_CUSTOM\tbuiltin variable"},{"contents":"CTEST_GIT_UPDATE_OPTIONS","trigger":"CTEST_GIT_UPDATE_OPTIONS\tbuiltin variable"},{"contents":"CTEST_HG_COMMAND","trigger":"CTEST_HG_COMMAND\tbuiltin variable"},{"contents":"CTEST_HG_UPDATE_OPTIONS","trigger":"CTEST_HG_UPDATE_OPTIONS\tbuiltin variable"},{"contents":"CTEST_LABELS_FOR_SUBPROJECTS","trigger":"CTEST_LABELS_FOR_SUBPROJECTS\tbuiltin variable"},{"contents":"CTEST_MEMORYCHECK_COMMAND","trigger":"CTEST_MEMORYCHECK_COMMAND\tbuiltin variable"},{"contents":"CTEST_MEMORYCHECK_COMMAND_OPTIONS","trigger":"CTEST_MEMORYCHECK_COMMAND_OPTIONS\tbuiltin variable"},{"contents":"CTEST_MEMORYCHECK_SANITIZER_OPTIONS","trigger":"CTEST_MEMORYCHECK_SANITIZER_OPTIONS\tbuiltin variable"},{"contents":"CTEST_MEMORYCHECK_SUPPRESSIONS_FILE","trigger":"CTEST_MEMORYCHECK_SUPPRESSIONS_FILE\tbuiltin variable"},{"contents":"CTEST_MEMORYCHECK_TYPE","trigger":"CTEST_MEMORYCHECK_TYPE\tbuiltin variable"},{"contents":"CTEST_NIGHTLY_START_TIME","trigger":"CTEST_NIGHTLY_START_TIME\tbuiltin variable"},{"contents":"CTEST_P4_CLIENT","trigger":"CTEST_P4_CLIENT\tbuiltin variable"},{"contents":"CTEST_P4_COMMAND","trigger":"CTEST_P4_COMMAND\tbuiltin variable"},{"contents":"CTEST_P4_OPTIONS","trigger":"CTEST_P4_OPTIONS\tbuiltin variable"},{"contents":"CTEST_P4_UPDATE_OPTIONS","trigger":"CTEST_P4_UPDATE_OPTIONS\tbuiltin variable"},{"contents":"CTEST_RESOURCE_SPEC_FILE","trigger":"CTEST_RESOURCE_SPEC_FILE\tbuiltin variable"},{"contents":"CTEST_RUN_CURRENT_SCRIPT","trigger":"CTEST_RUN_CURRENT_SCRIPT\tbuiltin variable"},{"contents":"CTEST_SCP_COMMAND","trigger":"CTEST_SCP_COMMAND\tbuiltin variable"},{"contents":"CTEST_SITE","trigger":"CTEST_SITE\tbuiltin variable"},{"contents":"CTEST_SOURCE_DIRECTORY","trigger":"CTEST_SOURCE_DIRECTORY\tbuiltin variable"},{"contents":"CTEST_SUBMIT_URL","trigger":"CTEST_SUBMIT_URL\tbuiltin variable"},{"contents":"CTEST_SVN_COMMAND","trigger":"CTEST_SVN_COMMAND\tbuiltin variable"},{"contents":"CTEST_SVN_OPTIONS","trigger":"CTEST_SVN_OPTIONS\tbuiltin variable"},{"contents":"CTEST_SVN_UPDATE_OPTIONS","trigger":"CTEST_SVN_UPDATE_OPTIONS\tbuiltin variable"},{"contents":"CTEST_TEST_LOAD","trigger":"CTEST_TEST_LOAD\tbuiltin variable"},{"contents":"CTEST_TEST_TIMEOUT","trigger":"CTEST_TEST_TIMEOUT\tbuiltin variable"},{"contents":"CTEST_TRIGGER_SITE","trigger":"CTEST_TRIGGER_SITE\tbuiltin variable"},{"contents":"CTEST_UPDATE_COMMAND","trigger":"CTEST_UPDATE_COMMAND\tbuiltin variable"},{"contents":"CTEST_UPDATE_OPTIONS","trigger":"CTEST_UPDATE_OPTIONS\tbuiltin variable"},{"contents":"CTEST_UPDATE_VERSION_ONLY","trigger":"CTEST_UPDATE_VERSION_ONLY\tbuiltin variable"},{"contents":"CTEST_UPDATE_VERSION_OVERRIDE","trigger":"CTEST_UPDATE_VERSION_OVERRIDE\tbuiltin variable"},{"contents":"CTEST_USE_LAUNCHERS","trigger":"CTEST_USE_LAUNCHERS\tbuiltin variable"},{"contents":"CYGWIN","trigger":"CYGWIN\tbuiltin variable"},{"contents":"ENV","trigger":"ENV\tbuiltin variable"},{"contents":"EXECUTABLE_OUTPUT_PATH","trigger":"EXECUTABLE_OUTPUT_PATH\tbuiltin variable"},{"contents":"GHS-MULTI","trigger":"GHS-MULTI\tbuiltin variable"},{"contents":"IOS","trigger":"IOS\tbuiltin variable"},{"contents":"LIBRARY_OUTPUT_PATH","trigger":"LIBRARY_OUTPUT_PATH\tbuiltin variable"},{"contents":"MINGW","trigger":"MINGW\tbuiltin variable"},{"contents":"MSVC","trigger":"MSVC\tbuiltin variable"},{"contents":"MSVC10","trigger":"MSVC10\tbuiltin variable"},{"contents":"MSVC11","trigger":"MSVC11\tbuiltin variable"},{"contents":"MSVC12","trigger":"MSVC12\tbuiltin variable"},{"contents":"MSVC14","trigger":"MSVC14\tbuiltin variable"},{"contents":"MSVC60","trigger":"MSVC60\tbuiltin variable"},{"contents":"MSVC70","trigger":"MSVC70\tbuiltin variable"},{"contents":"MSVC71","trigger":"MSVC71\tbuiltin variable"},{"contents":"MSVC80","trigger":"MSVC80\tbuiltin variable"},{"contents":"MSVC90","trigger":"MSVC90\tbuiltin variable"},{"contents":"MSVC_IDE","trigger":"MSVC_IDE\tbuiltin variable"},{"contents":"MSVC_TOOLSET_VERSION","trigger":"MSVC_TOOLSET_VERSION\tbuiltin variable"},{"contents":"MSVC_VERSION","trigger":"MSVC_VERSION\tbuiltin variable"},{"contents":"MSYS","trigger":"MSYS\tbuiltin variable"},{"contents":"PROJECT_BINARY_DIR","trigger":"PROJECT_BINARY_DIR\tbuiltin variable"},{"contents":"PROJECT_DESCRIPTION","trigger":"PROJECT_DESCRIPTION\tbuiltin variable"},{"contents":"PROJECT_HOMEPAGE_URL","trigger":"PROJECT_HOMEPAGE_URL\tbuiltin variable"},{"contents":"PROJECT_NAME","trigger":"PROJECT_NAME\tbuiltin variable"},{"contents":"PROJECT_SOURCE_DIR","trigger":"PROJECT_SOURCE_DIR\tbuiltin variable"},{"contents":"PROJECT_VERSION","trigger":"PROJECT_VERSION\tbuiltin variable"},{"contents":"PROJECT_VERSION_MAJOR","trigger":"PROJECT_VERSION_MAJOR\tbuiltin variable"},{"contents":"PROJECT_VERSION_MINOR","trigger":"PROJECT_VERSION_MINOR\tbuiltin variable"},{"contents":"PROJECT_VERSION_PATCH","trigger":"PROJECT_VERSION_PATCH\tbuiltin variable"},{"contents":"PROJECT_VERSION_TWEAK","trigger":"PROJECT_VERSION_TWEAK\tbuiltin variable"},{"contents":"UNIX","trigger":"UNIX\tbuiltin variable"},{"contents":"WIN32","trigger":"WIN32\tbuiltin variable"},{"contents":"WINCE","trigger":"WINCE\tbuiltin variable"},{"contents":"WINDOWS_PHONE","trigger":"WINDOWS_PHONE\tbuiltin variable"},{"contents":"WINDOWS_STORE","trigger":"WINDOWS_STORE\tbuiltin variable"},{"contents":"XCODE","trigger":"XCODE\tbuiltin variable"},{"contents":"XCODE_VERSION","trigger":"XCODE_VERSION\tbuiltin variable"}],"scope":"variable.other.readwrite.cmake"} assets/syntaxes/02_Extra/CMake/CMakeCommands.sublime-syntax:30: - match: \bVERBATIM\b assets/syntaxes/02_Extra/CMake/CMakeCommands.sublime-syntax:31: scope: variable.parameter.VERBATIM.cmake assets/syntaxes/02_Extra/CMake/CMakeCommands.sublime-syntax:59: - match: \bVERBATIM\b assets/syntaxes/02_Extra/CMake/CMakeCommands.sublime-syntax:60: scope: variable.parameter.VERBATIM.cmake assets/syntaxes/02_Extra/SCSS_Sass/Syntaxes/Sass.sublime-syntax:1830: - match: '\bat\b' assets/syntaxes/02_Extra/Elixir/builds/Elixir - mix format $file.sublime-build:6: "cmd": ["mix.bat", "format", "$file", "--dot-formatter", "$folder/.formatter.exs"], assets/syntaxes/02_Extra/Elixir/builds/Elixir - elixir $file.sublime-build:6: "cmd": ["elixir.bat", "$file_name"] assets/syntaxes/02_Extra/Lean.sublime-syntax:23: - match: '\battribute\b\s*\[[^\]]*\]' assets/syntaxes/02_Extra/PowerShell.sublime-syntax:86: - match: '(\b(([A-Za-z0-9\-_\.]+)\.(?i:exe|com|cmd|bat))\b)' assets/syntaxes/02_Extra/PowerShell.sublime-syntax:174: - match: '(?:(\p{L}|\d|_|-|\\|\:)*\\)?\b(?i:Add|Approve|Assert|Backup|Block|Build|Checkpoint|Clear|Close|Compare|Complete|Compress|Confirm|Connect|Convert|ConvertFrom|ConvertTo|Copy|Debug|Deny|Deploy|Disable|Disconnect|Dismount|Edit|Enable|Enter|Exit|Expand|Export|Find|Format|Get|Grant|Group|Hide|Import|Initialize|Install|Invoke|Join|Limit|Lock|Measure|Merge|Mount|Move|New|Open|Optimize|Out|Ping|Pop|Protect|Publish|Push|Read|Receive|Redo|Register|Remove|Rename|Repair|Request|Reset|Resize|Resolve|Restart|Restore|Resume|Revoke|Save|Search|Select|Send|Set|Show|Skip|Split|Start|Step|Stop|Submit|Suspend|Switch|Sync|Test|Trace|Unblock|Undo|Uninstall|Unlock|Unprotect|Unpublish|Unregister|Update|Use|Wait|Watch|Write)\-.+?(?:\.(?i:exe|cmd|bat|ps1))?\b' assets/syntaxes/02_Extra/MediaWiki/MediawikiNG.sublime-syntax:129: - meta_content_scope: meta.environment.embedded.dosbatch.mediawiki source.dosbatch.embedded assets/syntaxes/02_Extra/MediaWiki/MediawikiNG.sublime-syntax:132: - include: scope:source.dosbatch assets/syntaxes/02_Extra/MediaWiki/lib/Crypto.lin.x64/Crypto/Util/RFC1751.py:125: "BAN", "BAR", "BAT", "BAY", "BE", "BED", "BEE", "BEG", "BEN", "BET", assets/syntaxes/02_Extra/MediaWiki/lib/Crypto.lin.x64/Crypto/Util/RFC1751.py:189: "BARN", "BARR", "BASE", "BASH", "BASK", "BASS", "BATE", "BATH", assets/syntaxes/02_Extra/MediaWiki/lib/Crypto.lin.x64/Crypto/SelfTest/Signature/test_vectors/wycheproof/ecdsa_test.json:12177: "keyPem" : "-----BEGIN PUBLIC KEY-----\nMGowFAYHKoZIzj0CAQYJKyQDAwIIAQEJA1IABHJlM+Jnc6xyChFbAt6JrBWWZnfi\nObfFd6HBW4ECex/rc+ZzYB4hGqkqzLWFvAbMJ0thyeYUdG7dJI0czPjYsatLwVzF\njN8RYGXOl2fyoyI9\n-----END PUBLIC KEY-----", assets/syntaxes/02_Extra/MediaWiki/lib/Crypto.lin.x64/Crypto/SelfTest/Signature/test_vectors/wycheproof/ecdsa_test.json:13141: "keyPem" : "-----BEGIN PUBLIC KEY-----\nMHowFAYHKoZIzj0CAQYJKyQDAwIIAQELA2IABATZ1KYtbrAgc+c4seQ5zs1UQAMZ\nEfRRkOtgYqM1NfxSabz8JdSvwdrg662UjXcy2AKa836Jo86n3ziwIPYkkG/KbZRO\nFIaFP+jlupz7otdKhS7Fh9Rv5JkXw2RBjvfspQ==\n-----END PUBLIC KEY-----", assets/syntaxes/02_Extra/MediaWiki/lib/Crypto.lin.x64/Crypto/SelfTest/Signature/test_vectors/wycheproof/ecdsa_secp256r1_sha256_test.json:2410: "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE3q0Rx6WzloYvIZdNxHUvre/5lO/p\nu9BatBN2XqgLbh8d4/BkDorG7c+Jz/U8QOJlu5QHijQ3Nt8HqgMY/H/h/w==\n-----END PUBLIC KEY-----", assets/syntaxes/02_Extra/MediaWiki/lib/Crypto.lin.x64/Crypto/SelfTest/PublicKey/test_import_RSA.py:444:MIIEcjCCAlqgAwIBAgIBATANBgkqhkiG9w0BAQsFADBhMQswCQYDVQQGEwJVUzEL assets/syntaxes/02_Extra/MediaWiki/lib/Crypto.win.x64/Crypto/Util/RFC1751.py:125: "BAN", "BAR", "BAT", "BAY", "BE", "BED", "BEE", "BEG", "BEN", "BET", assets/syntaxes/02_Extra/MediaWiki/lib/Crypto.win.x64/Crypto/Util/RFC1751.py:189: "BARN", "BARR", "BASE", "BASH", "BASK", "BASS", "BATE", "BATH", assets/syntaxes/02_Extra/MediaWiki/lib/Crypto.win.x64/Crypto/SelfTest/Signature/test_vectors/wycheproof/ecdsa_test.json:12177: "keyPem" : "-----BEGIN PUBLIC KEY-----\nMGowFAYHKoZIzj0CAQYJKyQDAwIIAQEJA1IABHJlM+Jnc6xyChFbAt6JrBWWZnfi\nObfFd6HBW4ECex/rc+ZzYB4hGqkqzLWFvAbMJ0thyeYUdG7dJI0czPjYsatLwVzF\njN8RYGXOl2fyoyI9\n-----END PUBLIC KEY-----", assets/syntaxes/02_Extra/MediaWiki/lib/Crypto.win.x64/Crypto/SelfTest/Signature/test_vectors/wycheproof/ecdsa_test.json:13141: "keyPem" : "-----BEGIN PUBLIC KEY-----\nMHowFAYHKoZIzj0CAQYJKyQDAwIIAQELA2IABATZ1KYtbrAgc+c4seQ5zs1UQAMZ\nEfRRkOtgYqM1NfxSabz8JdSvwdrg662UjXcy2AKa836Jo86n3ziwIPYkkG/KbZRO\nFIaFP+jlupz7otdKhS7Fh9Rv5JkXw2RBjvfspQ==\n-----END PUBLIC KEY-----", assets/syntaxes/02_Extra/MediaWiki/lib/Crypto.win.x64/Crypto/SelfTest/Signature/test_vectors/wycheproof/ecdsa_secp256r1_sha256_test.json:2410: "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE3q0Rx6WzloYvIZdNxHUvre/5lO/p\nu9BatBN2XqgLbh8d4/BkDorG7c+Jz/U8QOJlu5QHijQ3Nt8HqgMY/H/h/w==\n-----END PUBLIC KEY-----", assets/syntaxes/02_Extra/MediaWiki/lib/Crypto.win.x64/Crypto/SelfTest/PublicKey/test_import_RSA.py:444:MIIEcjCCAlqgAwIBAgIBATANBgkqhkiG9w0BAQsFADBhMQswCQYDVQQGEwJVUzEL assets/syntaxes/02_Extra/MediaWiki/lib/Crypto.osx.x64/Crypto/Util/RFC1751.py:125: "BAN", "BAR", "BAT", "BAY", "BE", "BED", "BEE", "BEG", "BEN", "BET", assets/syntaxes/02_Extra/MediaWiki/lib/Crypto.osx.x64/Crypto/Util/RFC1751.py:189: "BARN", "BARR", "BASE", "BASH", "BASK", "BASS", "BATE", "BATH", assets/syntaxes/02_Extra/MediaWiki/lib/Crypto.osx.x64/Crypto/SelfTest/Signature/test_vectors/wycheproof/ecdsa_test.json:12177: "keyPem" : "-----BEGIN PUBLIC KEY-----\nMGowFAYHKoZIzj0CAQYJKyQDAwIIAQEJA1IABHJlM+Jnc6xyChFbAt6JrBWWZnfi\nObfFd6HBW4ECex/rc+ZzYB4hGqkqzLWFvAbMJ0thyeYUdG7dJI0czPjYsatLwVzF\njN8RYGXOl2fyoyI9\n-----END PUBLIC KEY-----", assets/syntaxes/02_Extra/MediaWiki/lib/Crypto.osx.x64/Crypto/SelfTest/Signature/test_vectors/wycheproof/ecdsa_test.json:13141: "keyPem" : "-----BEGIN PUBLIC KEY-----\nMHowFAYHKoZIzj0CAQYJKyQDAwIIAQELA2IABATZ1KYtbrAgc+c4seQ5zs1UQAMZ\nEfRRkOtgYqM1NfxSabz8JdSvwdrg662UjXcy2AKa836Jo86n3ziwIPYkkG/KbZRO\nFIaFP+jlupz7otdKhS7Fh9Rv5JkXw2RBjvfspQ==\n-----END PUBLIC KEY-----", assets/syntaxes/02_Extra/MediaWiki/lib/Crypto.osx.x64/Crypto/SelfTest/Signature/test_vectors/wycheproof/ecdsa_secp256r1_sha256_test.json:2410: "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE3q0Rx6WzloYvIZdNxHUvre/5lO/p\nu9BatBN2XqgLbh8d4/BkDorG7c+Jz/U8QOJlu5QHijQ3Nt8HqgMY/H/h/w==\n-----END PUBLIC KEY-----", assets/syntaxes/02_Extra/MediaWiki/lib/Crypto.osx.x64/Crypto/SelfTest/PublicKey/test_import_RSA.py:444:MIIEcjCCAlqgAwIBAgIBATANBgkqhkiG9w0BAQsFADBhMQswCQYDVQQGEwJVUzEL assets/syntaxes/02_Extra/Julia/julia_unicode/emoji_symbols.py:69: ("\\:battery:", u"🔋"), assets/syntaxes/02_Extra/Julia/julia_unicode/emoji_symbols.py:576: ("\\:tanabata_tree:", u"🎋"), assets/syntaxes/02_Extra/Julia/julia_unicode/emoji_symbols.py:729: ("\\:bath:", u"🛀"), assets/syntaxes/02_Extra/Julia/julia_unicode/emoji_symbols.py:804: ("\\:bathtub:", u"🛁"), assets/syntaxes/02_Extra/Crystal.sublime-syntax:136: - match: '\b(initialize|new|loop|include|extend|raise|getter|setter|property|class_getter|class_setter|class_property|describe|context|it|with|delegate|def_hash|def_equals|def_equals_and_hash|forward_missing_to|record|assert_responds_to|spawn|annotation|verbatim)\b[!?]?' assets/syntaxes/02_Extra/Dart/docgen.py:30: cmd = ["docgen.bat", "--no-include-sdk", path] assets/syntaxes/02_Extra/Dart/docgen.py:58: cmd = ["docgen.bat", "--no-include-sdk", "--serve", path] assets/syntaxes/02_Extra/Dart/lib/sdk.py:177: return self.get_bin_tool('pub', '.bat') assets/syntaxes/02_Extra/Dart/lib/sdk.py:183: return self.get_bin_tool('dart2js', '.bat') assets/syntaxes/02_Extra/Dart/lib/sdk.py:189: return self.get_bin_tool('dartanalyzer', '.bat') assets/syntaxes/02_Extra/Dart/lib/sdk.py:195: return self.get_bin_tool('docgen', '.bat') assets/syntaxes/02_Extra/Dart/lib/sdk.py:247: self.path = SDK().get_bin_tool('dartfmt', '.bat') assets/syntaxes/02_Extra/Dart/sublime_plugin_lib/path.py:142: Useful to add .exe to @original, .bat, etc if ST is running on Windows. assets/syntaxes/02_Extra/Dart/sublime_plugin_lib/path.py:186: """ Useful to add .exe, .bat, etc. to @original if ST is running on assets/syntaxes/02_Extra/Dart/Support/Dart.sublime-build:19: "cmd": ["dart2js.bat", "--minify", "-o$file.js", "$file"] assets/syntaxes/02_Extra/Dart/Support/Dart - Pubspec.sublime-build:21: "cmd": ["pub.bat", "upgrade"] assets/syntaxes/02_Extra/Dart/Support/Dart - Pubspec.sublime-build:36: "cmd": ["pub.bat", "version"] assets/syntaxes/02_Extra/LESS/Syntaxes/LESS.sublime-syntax:1709: - match: '\bat\b' assets/syntaxes/02_Extra/Email/README.md:15::mouse: Using [bat](https://github.com/sharkdp/bat) *(bat is a cat clone with syntax highlighting and Git integration)* assets/syntaxes/02_Extra/Email/README.md:16:![bat](https://raw.githubusercontent.com/mariozaizar/email.sublime-syntax/master/demo/bat.png) assets/syntaxes/02_Extra/Email/link_bat.sh:3:# We use bat to verify the sintax. bat is a cat clone with syntax highlighting assets/syntaxes/02_Extra/Email/link_bat.sh:4:# and Git integration. bat uses syntect library for syntax highlighting which assets/syntaxes/02_Extra/Email/link_bat.sh:7:# https://github.com/sharkdp/bat assets/syntaxes/02_Extra/Email/link_bat.sh:9:bat --version || brew install bat # Mac OS only assets/syntaxes/02_Extra/Email/link_bat.sh:11:BAT_PATH=$(bat --config-dir) assets/syntaxes/02_Extra/Email/link_bat.sh:13:mkdir -p "$BAT_PATH/syntaxes" assets/syntaxes/02_Extra/Email/link_bat.sh:14:mkdir -p "$BAT_PATH/themes" assets/syntaxes/02_Extra/Email/link_bat.sh:16:INSTALL_PATH=${BAT_PATH}/syntaxes assets/syntaxes/02_Extra/Email/link_bat.sh:19:bat cache --build assets/syntaxes/02_Extra/Email/link_bat.sh:20:bat --list-languages | grep "Email" assets/syntaxes/02_Extra/Email/link_bat.sh:22:bat demo/email.eml assets/syntaxes/02_Extra/TypeScript.sublime-syntax:2446: |AudioNode|AudioParam|BatteryManager|BeforeUnloadEvent|BiquadFilterNode|Blob|BufferSource|ByteString|CSS|CSSConditionRule assets/syntaxes/02_Extra/HTML (Twig)/Preferences/Indentation.tmPreferences:22: ^\s*\{%-?\s(end(?:autoescape|block|embed|filter|for|if|macro|raw|sandbox|set|spaceless|trans|verbatim)|(else))(?:(?!%\}).)*\s-?%\} assets/syntaxes/02_Extra/HTML (Twig)/Preferences/Indentation.tmPreferences:36: ^\s*\{%-?\s(autoescape|block|embed|filter|for|if|else|macro|raw|sandbox|set|spaceless|trans|verbatim)(?:(?!%\}).)*\s-?%\}(?!.*\{%-?\send\1) assets/syntaxes/02_Extra/HTML (Twig)/Preferences/Folding.tmPreferences:16: |\{%\s+(autoescape|block|embed|filter|for|if|macro|raw|sandbox|set|spaceless|trans|verbatim) assets/syntaxes/02_Extra/HTML (Twig)/Preferences/Folding.tmPreferences:23: |\{%\s+end(autoescape|block|embed|filter|for|if|macro|raw|sandbox|set|spaceless|trans|verbatim) assets/syntaxes/02_Extra/HTML (Twig)/Snippets/verbatim.tmSnippet:6: {% verbatim %} assets/syntaxes/02_Extra/HTML (Twig)/Snippets/verbatim.tmSnippet:8:{% endverbatim %} assets/syntaxes/02_Extra/HTML (Twig)/Snippets/verbatim.tmSnippet:10: verbatim assets/syntaxes/02_Extra/HTML (Twig)/Snippets/verbatim.tmSnippet:14: verbatim assets/syntaxes/02_Extra/HTML (Twig)/Syntaxes/HTML (Twig).tmLanguage:1374: (?<=\s)((?:end)?(?:autoescape|block|embed|filter|for|if|macro|raw|sandbox|set|spaceless|trans|verbatim)|as|do|else|elseif|extends|flush|from|ignore missing|import|include|only|use|with)(?=\s) assets/syntaxes/02_Extra/HTML (Twig)/Syntaxes/HTML (Twig).tmLanguage:1590: (?<=(?:[a-zA-Z0-9_\x{7f}-\x{ff}\]\)\'\"]\|)|\{%\sfilter\s)(batch|convert_encoding|date|date_modify|default|e(?:scape)?|format|join|merge|number_format|replace|round|slice|split|trim)(\() assets/syntaxes/02_Extra/requirementstxt/LICENSE:5: Everyone is permitted to copy and distribute verbatim copies assets/syntaxes/02_Extra/requirementstxt/LICENSE:195: 4. Conveying Verbatim Copies. assets/syntaxes/02_Extra/requirementstxt/LICENSE:197: You may convey verbatim copies of the Program's source code as you assets/syntaxes/01_Packages/Batch File/Symbol List.tmPreferences:7: source.dosbatch entity.name.label - meta.function-call assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:4:name: Batch File assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:6: - bat assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:8:scope: source.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:31: scope: keyword.control.statement.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:34: 1: keyword.control.statement.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:35: 2: punctuation.separator.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:36: 3: keyword.control.flow.return.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:37: 4: meta.function-call.dosbatch variable.function.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:40: 1: keyword.control.conditional.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:41: 2: keyword.operator.logical.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:42: 3: keyword.other.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:44: scope: keyword.control.conditional.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:46: scope: keyword.control.repeat.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:50: scope: keyword.command.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:60: scope: keyword.command.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:64: scope: keyword.command.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:74: 1: punctuation.definition.string.begin.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:75: 2: variable.other.readwrite.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:76: 3: keyword.operator.assignment.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:78: - meta_scope: string.quoted.double.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:80: scope: punctuation.definition.string.end.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:88: 1: variable.other.readwrite.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:89: 2: keyword.operator.assignment.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:91: - meta_content_scope: string.unquoted.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:96: scope: punctuation.definition.string.begin.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:98: - meta_scope: string.quoted.double.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:101: scope: punctuation.definition.string.end.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:108: scope: variable.other.readwrite.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:112: - meta_content_scope: meta.expression.set.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:120: 1: variable.other.readwrite.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:121: 2: keyword.operator.assignment.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:123: - meta_scope: meta.prompt.set.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:132: scope: comment.line.ignored.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:135: - meta_content_scope: string.unquoted.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:145: scope: punctuation.section.group.begin.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:148: scope: punctuation.definition.string.begin.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:153: - meta_scope: meta.group.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:155: scope: punctuation.section.group.end.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:158: scope: punctuation.definition.string.begin.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:164: scope: keyword.operator.assignment.augmented.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:167: 1: constant.character.escape.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:168: 2: keyword.operator.assignment.augmented.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:170: scope: keyword.operator.arithmetic.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:173: 1: constant.character.escape.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:174: 2: keyword.operator.arithmetic.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:176: scope: keyword.operator.assignment.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:180: scope: keyword.operator.assignment.augmented.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:182: scope: keyword.operator.arithmetic.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:186: - meta_scope: string.quoted.double.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:190: scope: punctuation.definition.string.end.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:193: scope: punctuation.section.group.begin.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:195: - meta_scope: meta.group.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:202: - meta_scope: meta.group.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:204: scope: punctuation.section.group.end.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:207: scope: punctuation.definition.string.end.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:214: - meta_scope: string.quoted.double.dosbatch meta.group.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:216: scope: punctuation.section.group.begin.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:219: scope: punctuation.section.group.end.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:227: scope: keyword.operator.logical.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:233: scope: variable.other.readwrite.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:238: scope: variable.parameter.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:240: 1: punctuation.definition.variable.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:242: scope: variable.language.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:244: 1: punctuation.definition.variable.begin.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:245: 2: punctuation.definition.variable.end.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:252: scope: punctuation.definition.variable.begin.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:254: - meta_scope: variable.other.readwrite.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:257: 1: punctuation.definition.variable.end.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:261: scope: punctuation.separator.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:263: - meta_content_scope: meta.variable.substring.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:269: scope: punctuation.separator.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:271: - meta_content_scope: meta.variable.substitution.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:276: scope: punctuation.separator.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:282: scope: string.unquoted.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:287: scope: punctuation.definition.variable.begin.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:289: - meta_scope: variable.other.readwrite.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:292: 1: punctuation.definition.variable.end.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:296: scope: punctuation.separator.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:298: - meta_content_scope: meta.variable.substring.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:304: scope: punctuation.separator.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:306: - meta_content_scope: meta.variable.substitution.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:312: scope: punctuation.separator.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:318: scope: string.unquoted.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:322: scope: string.unquoted.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:326: scope: constant.numeric.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:331: scope: punctuation.separator.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:335: scope: constant.numeric.integer.hexadecimal.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:337: 1: punctuation.definition.numeric.hexadecimal.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:339: scope: constant.numeric.integer.octal.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:341: 1: punctuation.definition.numeric.octal.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:343: scope: constant.numeric.integer.decimal.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:347: scope: constant.language.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:351: scope: keyword.operator.at.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:353: scope: keyword.operator.comparison.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:355: scope: keyword.operator.logical.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:357: scope: keyword.operator.conditional.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:359: scope: keyword.operator.pipe.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:361: scope: keyword.operator.redirection.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:366: 1: punctuation.separator.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:367: 2: entity.name.label.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:372: 1: keyword.operator.conditional.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:375: scope: comment.line.rem.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:378: scope: punctuation.definition.comment.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:380: - meta_scope: comment.line.colon.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:386: scope: keyword.command.rem.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:390: - meta_content_scope: comment.line.rem.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:392: scope: comment.line.rem.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:395: scope: invalid.illegal.unexpected-character.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:399: scope: punctuation.definition.string.begin.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:401: - meta_scope: string.quoted.double.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:404: 1: punctuation.definition.string.end.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:405: 2: invalid.illegal.newline.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:412: scope: punctuation.section.group.begin.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:414: - meta_scope: meta.group.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:416: scope: punctuation.section.group.end.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:419: scope: punctuation.separator.dosbatch assets/syntaxes/01_Packages/Batch File/Batch File.sublime-syntax:424: scope: constant.character.escape.dosbatch assets/syntaxes/01_Packages/Batch File/Comments.tmPreferences:7: source.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:1::: SYNTAX TEST "Packages/Batch File/Batch File.sublime-syntax" assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:4::: ^^^ keyword.command.rem.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:5::: ^^^^^^^^^^^^^^^^ comment.line.rem.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:6::: ^ invalid.illegal.unexpected-character.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:7::: ^ invalid.illegal.unexpected-character.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:8::: ^ invalid.illegal.unexpected-character.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:12::: ^^^^^^^^^^^^^ - comment.line.rem.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:19::: ^^ punctuation.definition.comment.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:20::: ^^^^^^^^^^ comment.line.colon.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:23::: ^^ punctuation.definition.comment.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:26::: ^^ punctuation.definition.comment.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:29::: ^^ punctuation.definition.comment.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:32::: ^^ punctuation.definition.comment.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:35::: ^^ punctuation.definition.comment.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:46::: ^ keyword.operator.conditional.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:47::: ^^ punctuation.definition.comment.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:48::: ^^^^^^^^^^^^ comment.line.colon.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:51:::^^ punctuation.definition.comment.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:52:::^^^^^^^^^^^^^^^^^^^^^^ comment.line.colon.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:55::: ^ punctuation.definition.string.begin.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:56::: ^^^^^ string.quoted.double.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:57::: ^ punctuation.definition.string.end.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:60::: ^ invalid.illegal.newline.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:63::: ^ keyword.operator.at.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:66::: ^ - keyword.operator.at.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:69::: ^^^^ keyword.control.statement.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:70::: ^ punctuation.separator.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:71::: ^^^ keyword.control.flow.return.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:74::: ^^^^ keyword.control.statement.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:75::: ^ punctuation.separator.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:76::: ^^^ meta.function-call.dosbatch variable.function.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:79::: ^^^^ keyword.control.statement.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:80::: ^ punctuation.separator.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:81::: ^^^ meta.function-call.dosbatch variable.function.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:85::: ^^^^ keyword.command.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:86::: ^ keyword.operator.redirection.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:89::: ^^ keyword.operator.redirection.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:93::: ^ keyword.operator.redirection.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:94::: ^^ keyword.operator.redirection.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:97::: ^^ keyword.operator.conditional.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:98::: ^^ keyword.operator.conditional.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:99::: ^ keyword.operator.conditional.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:103::: ^^ keyword.control.conditional.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:104::: ^^^ keyword.operator.comparison.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:107::: ^^ keyword.control.conditional.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:108::: ^^^ keyword.operator.logical.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:109::: ^^^ keyword.operator.comparison.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:113::: ^^ keyword.control.conditional.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:114::: ^^^^^^^^^^^^ variable.language.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:115::: ^ punctuation.definition.variable.begin.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:116::: ^ variable.language.dosbatch punctuation.definition.variable.end.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:119::: ^^ keyword.control.conditional.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:120::: ^^ keyword.operator.comparison.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:123::: ^^^ keyword.control.repeat.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:124::: ^ constant.numeric.integer.decimal.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:127::: ^ keyword.operator.pipe.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:130:::^ punctuation.separator.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:131::: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ entity.name.label.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:134:::^ punctuation.separator.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:135::: ^^^ entity.name.label.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:138::: ^ punctuation.definition.variable.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:139::: ^^ variable.parameter.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:140::: ^ punctuation.definition.variable.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:141::: ^^ variable.parameter.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:142::: ^ punctuation.definition.variable.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:143::: ^^^^^^^^^^^ variable.parameter.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:144::: ^ punctuation.definition.variable.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:145::: ^^^ variable.parameter.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:148::: ^ punctuation.definition.variable.begin.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:149::: ^^^^^^^^^^ variable.other.readwrite.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:150::: ^ punctuation.definition.variable.end.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:151::: ^ punctuation.definition.variable.begin.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:152::: ^^^^^^^^^^ variable.other.readwrite.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:153::: ^ punctuation.definition.variable.end.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:156::: ^^^^^^^^^^^^^^^ variable.other.readwrite.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:157::: ^ punctuation.definition.variable.begin.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:158::: ^ punctuation.separator.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:159::: ^^^^^^^^^ meta.variable.substitution.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:160::: ^^^^ string.unquoted.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:161::: ^ punctuation.separator.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:162::: ^^^^ string.unquoted.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:163::: ^ punctuation.definition.variable.end.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:164::: ^^^^^^^^^^^^^^^ variable.other.readwrite.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:165::: ^ punctuation.definition.variable.begin.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:166::: ^ punctuation.separator.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:167::: ^^^^^^^^^ meta.variable.substitution.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:168::: ^^^^ string.unquoted.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:169::: ^ punctuation.separator.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:170::: ^^^^ string.unquoted.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:171::: ^ punctuation.definition.variable.end.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:175::: ^^^^^^^^^^^^^^ variable.other.readwrite.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:176::: ^ punctuation.definition.variable.begin.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:177::: ^^ punctuation.separator.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:178::: ^^^^ meta.variable.substring.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:179::: ^ constant.numeric.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:180::: ^ punctuation.separator.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:181::: ^^ constant.numeric.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:182::: ^ punctuation.definition.variable.end.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:183::: ^^^^^^^^^^^^^^ variable.other.readwrite.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:184::: ^ punctuation.definition.variable.begin.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:185::: ^^ punctuation.separator.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:186::: ^^^^ meta.variable.substring.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:187::: ^ constant.numeric.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:188::: ^ punctuation.separator.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:189::: ^^ constant.numeric.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:190::: ^ punctuation.definition.variable.end.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:193::: ^^^^^^^ variable.other.readwrite.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:194::: ^ punctuation.definition.variable.begin.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:195::: ^^ punctuation.separator.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:196::: ^^ meta.variable.substring.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:197::: ^^ constant.numeric.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:198::: ^ punctuation.definition.variable.end.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:199::: ^^^^^^^ variable.other.readwrite.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:200::: ^ punctuation.definition.variable.begin.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:201::: ^^ punctuation.separator.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:202::: ^^ meta.variable.substring.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:203::: ^^ constant.numeric.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:204::: ^ punctuation.definition.variable.end.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:207::: ^^^^^^^^^^^^^^^^^^^^^ variable.other.readwrite.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:208::: ^ punctuation.definition.variable.begin.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:209::: ^^^^^ meta.variable.substitution.dosbatch variable.other.readwrite.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:210::: ^ meta.variable.substitution.dosbatch punctuation.definition.variable.begin.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:211::: ^ meta.variable.substitution.dosbatch punctuation.definition.variable.end.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:212::: ^ meta.variable.substitution.dosbatch punctuation.definition.variable.begin.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:213::: ^^^^^^^^^^^ meta.variable.substitution.dosbatch variable.other.readwrite.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:214::: ^^^^ meta.variable.substitution.dosbatch meta.variable.substring.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:215::: ^ meta.variable.substitution.dosbatch punctuation.definition.variable.end.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:216::: ^^ meta.variable.substitution.dosbatch constant.numeric.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:217::: ^ punctuation.definition.variable.end.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:220::: ^^^^^^^^^^^^^^^^^^^ variable.other.readwrite.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:221::: ^ punctuation.definition.variable.begin.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:222::: ^ meta.variable.substitution.dosbatch punctuation.definition.variable.begin.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:223::: ^^^^^^^^^^^ meta.variable.substitution.dosbatch variable.other.readwrite.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:224::: ^^^^ meta.variable.substitution.dosbatch meta.variable.substring.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:225::: ^ meta.variable.substitution.dosbatch punctuation.definition.variable.end.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:226::: ^^ meta.variable.substitution.dosbatch constant.numeric.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:227::: ^ punctuation.definition.variable.end.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:230::: ^^^^^^^^^^^^ - variable.other.readwrite.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:231::: ^^^ - keyword.operator.logical.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:234::: ^^^^^^^^^^^^ - variable.other.readwrite.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:235::: ^^^ - keyword.operator.logical.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:239::: ^^^ constant.numeric.integer.octal.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:240::: ^ punctuation.definition.numeric.octal.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:241::: ^^^^ constant.numeric.integer.hexadecimal.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:242::: ^^ punctuation.definition.numeric.hexadecimal.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:243::: ^^ constant.numeric.integer.decimal.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:247::: ^^ constant.character.escape.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:248::: ^^^ constant.character.escape.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:249::: ^^ constant.character.escape.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:253::: ^^^^^^^^^ meta.expression.set.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:254::: ^^^ keyword.operator.assignment.augmented.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:257::: ^^ keyword.operator.assignment.augmented.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:260::: ^^ keyword.operator.assignment.augmented.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:263::: ^^ keyword.operator.assignment.augmented.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:266::: ^^ keyword.operator.assignment.augmented.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:269::: ^^ keyword.operator.assignment.augmented.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:272::: ^^^ keyword.operator.assignment.augmented.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:275::: ^ keyword.operator.assignment.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:276::: ^ keyword.operator.logical.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:279::: ^^^^^ meta.group.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:280::: ^ punctuation.section.group.begin.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:281::: ^ punctuation.section.group.end.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:282::: ^ keyword.operator.assignment.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:283::: ^ keyword.operator.arithmetic.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:284::: ^ keyword.operator.arithmetic.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:287::: ^ keyword.operator.assignment.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:288::: ^ punctuation.separator.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:289::: ^ keyword.operator.assignment.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:290::: ^ keyword.operator.arithmetic.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:293::: ^ keyword.operator.assignment.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:294::: ^^ keyword.operator.arithmetic.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:297::: ^ keyword.operator.assignment.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:298::: ^^ keyword.operator.arithmetic.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:301::: ^ keyword.operator.assignment.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:302::: ^^ keyword.operator.arithmetic.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:305::: ^ keyword.operator.assignment.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:306::: ^ keyword.operator.arithmetic.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:309::: ^ keyword.operator.assignment.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:310::: ^ keyword.operator.arithmetic.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:313::: ^ keyword.operator.assignment.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:314::: ^ keyword.operator.arithmetic.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:317::: ^^ keyword.operator.assignment.augmented.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:320::: ^ keyword.operator.assignment.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:321::: ^ keyword.operator.arithmetic.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:324::: ^ keyword.operator.assignment.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:325::: ^ keyword.operator.arithmetic.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:328::: ^ keyword.operator.assignment.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:329::: ^ keyword.operator.arithmetic.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:332::: ^ keyword.operator.assignment.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:333::: ^ keyword.operator.arithmetic.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:336::: ^ keyword.operator.assignment.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:337::: ^ keyword.operator.arithmetic.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:340::: ^^^ keyword.operator.assignment.augmented.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:343::: ^^ keyword.operator.assignment.augmented.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:346::: ^ keyword.operator.assignment.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:347::: ^ keyword.operator.arithmetic.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:348::: ^ punctuation.separator.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:349::: ^ keyword.operator.assignment.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:350::: ^ keyword.operator.arithmetic.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:436::: ^^^^^^^^^^^ variable.other.readwrite.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:444::: ^^^^^^^^^^^ string.quoted.double.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:445::: ^^ constant.character.escape.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:446::: ^ - constant.character.escape.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:447::: ^^ constant.character.escape.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:448::: ^ - constant.character.escape.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:449::: ^^ constant.character.escape.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:450::: ^ - constant.character.escape.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:454::: ^^^^ - variable.other.readwrite.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:455::: ^^^^^ variable.other.readwrite.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:456::: ^ keyword.operator.assignment.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:457::: ^ keyword.operator.redirection.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:459::: ^ punctuation.definition.variable.begin.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:460::: ^^^^^^^ variable.other.readwrite.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:461::: ^ punctuation.definition.variable.end.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:464::: ^^^^ - variable.other.readwrite.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:465::: ^^^^^ variable.other.readwrite.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:466::: ^ keyword.operator.assignment.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:467::: ^^^^^^^^^^^^^ meta.prompt.set.dosbatch string.unquoted - variable.other.readwrite.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:468::: ^ - meta.prompt.set.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:470::: ^^^^ - variable.other.readwrite.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:471::: ^^^^^ variable.other.readwrite.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:472::: ^ keyword.operator.assignment.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:473::: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.prompt.set.dosbatch string.unquoted - variable.other.readwrite.dosbatch - comment assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:474::: ^ - meta.prompt.set.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:476::: ^^^^ - variable.other.readwrite.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:477::: ^^^^^ variable.other.readwrite.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:478::: ^ keyword.operator.assignment.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:479::: ^ - meta.prompt.set.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:493::: ^^^^^^ variable.other.readwrite.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:494::: ^^^^^^ variable.other.readwrite.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:498::: ^^^^ variable.other.readwrite.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:499::: ^ keyword.operator.assignment.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:500::: ^ punctuation.definition.string.begin.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:501::: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ string.quoted.double.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:502::: ^^^^^^^^^ variable.other.readwrite.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:503::: ^^ constant.character.escape.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:504::: ^ punctuation.definition.string.end.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:505::: ^^^ string.unquoted.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:508:::^^^^^^ keyword.command.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:510::: ^^^^ - variable.other.readwrite.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:511::: ^^^^^^^ variable.other.readwrite.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:512::: ^ keyword.operator.assignment.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:513::: ^ punctuation.definition.string.begin.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:514::: ^^^^^^^^^^^^^^^^^^^^^^^^^ meta.prompt.set.dosbatch string.quoted assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:515::: ^ punctuation.definition.string.end.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:516::: ^ keyword.operator.conditional.dosbatch - meta.prompt.set.dosbatch - string assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:517::: ^^^^ keyword.command.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:518::: ^^^^^^^^^ variable.other.readwrite.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:520:::^^^^^^ keyword.command.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:542::: ^^^^ - variable.other.readwrite.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:543::: ^^^^^ variable.other.readwrite.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:544::: ^ keyword.operator.assignment.dosbatch - variable.other.readwrite.dosbatch assets/syntaxes/01_Packages/Batch File/syntax_test_batch_file.bat:545::: ^^^^^^^^^^^^^^^^ meta.prompt.set.dosbatch string.quoted - variable.other.readwrite.dosbatch - comment assets/syntaxes/01_Packages/CSS/CSS.sublime-syntax:1257: - match: '\bat\b' assets/syntaxes/01_Packages/C#/tests/syntax_test_Strings.cs:35:var verbatim_singleline = @"foo"; assets/syntaxes/01_Packages/C#/tests/syntax_test_Strings.cs:37:var verbatim_singleline_interpolated_none = $@"foo bar"; assets/syntaxes/01_Packages/C#/tests/syntax_test_Strings.cs:39:var verbatim_singleline_interpolated_yes = $@"foo {bar} foo"; assets/syntaxes/01_Packages/C#/tests/syntax_test_Strings.cs:42:var verbatim_multiline = @"foo bar assets/syntaxes/01_Packages/C#/tests/syntax_test_Strings.cs:45:var verbatim_multiline_interpolated_none = $@"foo bar assets/syntaxes/01_Packages/C#/tests/syntax_test_Strings.cs:48:var verbatim_multiline_interpolated_yes = $@"foo {bar} assets/syntaxes/01_Packages/C#/tests/syntax_test_GeneralStructure.cs:344: case BLBodyBattleLibrary.ContextType.TapUp: assets/syntaxes/01_Packages/C#/tests/syntax_test_Generics.cs:57:string verbatim = @"This is a test "" of a verbatim string literal - C:\User"; assets/syntaxes/01_Packages/C#/tests/syntax_test_c#.cs:35:string verbatim = @"This is a test "" of a verbatim string literal - C:\User"; assets/syntaxes/01_Packages/PHP/PHP.sublime-completions:2082: { "trigger": "mssql_fetch_batch", "contents": "mssql_fetch_batch(${1:result})" }, assets/syntaxes/01_Packages/PHP/PHP Source.sublime-syntax:407: # verbatim and the indexer should find the name in the original source assets/syntaxes/01_Packages/PHP/PHP Source.sublime-syntax:447: # verbatim and the indexer should find the name in the original source assets/syntaxes/01_Packages/PHP/PHP Source.sublime-syntax:2082: mssql_bind | mssql_close | mssql_connect | mssql_data_seek | mssql_execute | mssql_fetch_array | mssql_fetch_assoc | mssql_fetch_batch | assets/syntaxes/01_Packages/LaTeX/LaTeX.sublime-syntax:29: - include: verbatim assets/syntaxes/01_Packages/LaTeX/LaTeX.sublime-syntax:311: verbatim: assets/syntaxes/01_Packages/LaTeX/LaTeX.sublime-syntax:312: - match: '((\\)begin)(\{)\s*((?:[vV]erbatim|alltt)\*?)\s*(\})' assets/syntaxes/01_Packages/LaTeX/LaTeX.sublime-syntax:321: - meta_scope: meta.environment.verbatim.verbatim.latex assets/syntaxes/01_Packages/LaTeX/LaTeX.sublime-syntax:322: - meta_content_scope: markup.raw.verbatim.latex assets/syntaxes/01_Packages/LaTeX/LaTeX.sublime-syntax:541: - meta_scope: meta.environment.verbatim.verb.latex assets/syntaxes/01_Packages/LaTeX/LaTeX.sublime-syntax:777: - meta_scope: meta.environment.verbatim.lstinline.latex assets/syntaxes/01_Packages/LaTeX/LaTeX.sublime-syntax:784: - meta_content_scope: meta.environment.verbatim.lstinline.latex markup.raw.verb.latex assets/syntaxes/01_Packages/LaTeX/LaTeX.sublime-syntax:786: scope: meta.environment.verbatim.lstinline.latex punctuation.definition.group.brace.end.latex assets/syntaxes/01_Packages/LaTeX/LaTeX.sublime-syntax:792: - meta_content_scope: meta.environment.verbatim.lstinline.latex markup.raw.verb.latex assets/syntaxes/01_Packages/LaTeX/LaTeX.sublime-syntax:794: scope: meta.environment.verbatim.lstinline.latex punctuation.definition.verb.latex assets/syntaxes/01_Packages/LaTeX/LaTeX.sublime-syntax:806: - meta_scope: meta.environment.verbatim.lstlisting.latex assets/syntaxes/01_Packages/LaTeX/LaTeX.sublime-syntax:938: - meta_scope: meta.environment.verbatim.minted.latex assets/syntaxes/01_Packages/LaTeX/LaTeX.sublime-syntax:1146: - meta_scope: meta.environment.verbatim.minted.latex assets/syntaxes/01_Packages/LaTeX/LaTeX.sublime-syntax:1149: scope: meta.environment.verbatim.minted.latex assets/syntaxes/01_Packages/LaTeX/LaTeX.sublime-syntax:1157: embed_scope: meta.environment.verbatim.minted.latex meta.environment.embedded.c.latex source.c.embedded assets/syntaxes/01_Packages/LaTeX/LaTeX.sublime-syntax:1163: scope: meta.environment.verbatim.minted.latex assets/syntaxes/01_Packages/LaTeX/LaTeX.sublime-syntax:1171: embed_scope: meta.environment.verbatim.minted.latex meta.environment.embedded.c++.latex source.c++.embedded assets/syntaxes/01_Packages/LaTeX/LaTeX.sublime-syntax:1177: scope: meta.environment.verbatim.minted.latex assets/syntaxes/01_Packages/LaTeX/LaTeX.sublime-syntax:1185: embed_scope: meta.environment.verbatim.minted.latex meta.environment.embedded.diff.latex source.diff.embedded assets/syntaxes/01_Packages/LaTeX/LaTeX.sublime-syntax:1191: scope: meta.environment.verbatim.minted.latex assets/syntaxes/01_Packages/LaTeX/LaTeX.sublime-syntax:1199: embed_scope: meta.environment.verbatim.minted.latex meta.environment.embedded.go.latex source.go.embedded assets/syntaxes/01_Packages/LaTeX/LaTeX.sublime-syntax:1205: scope: meta.environment.verbatim.minted.latex assets/syntaxes/01_Packages/LaTeX/LaTeX.sublime-syntax:1213: embed_scope: meta.environment.verbatim.minted.latex meta.environment.embedded.haskell.latex source.haskell.embedded assets/syntaxes/01_Packages/LaTeX/LaTeX.sublime-syntax:1219: scope: meta.environment.verbatim.minted.latex assets/syntaxes/01_Packages/LaTeX/LaTeX.sublime-syntax:1227: embed_scope: meta.environment.verbatim.minted.latex meta.environment.embedded.html.latex text.html.embedded assets/syntaxes/01_Packages/LaTeX/LaTeX.sublime-syntax:1233: scope: meta.environment.verbatim.minted.latex assets/syntaxes/01_Packages/LaTeX/LaTeX.sublime-syntax:1241: embed_scope: meta.environment.verbatim.minted.latex meta.environment.embedded.java.latex source.java.embedded assets/syntaxes/01_Packages/LaTeX/LaTeX.sublime-syntax:1247: scope: meta.environment.verbatim.minted.latex assets/syntaxes/01_Packages/LaTeX/LaTeX.sublime-syntax:1255: embed_scope: meta.environment.verbatim.minted.latex meta.environment.embedded.js.latex source.js.embedded assets/syntaxes/01_Packages/LaTeX/LaTeX.sublime-syntax:1261: scope: meta.environment.verbatim.minted.latex assets/syntaxes/01_Packages/LaTeX/LaTeX.sublime-syntax:1269: embed_scope: meta.environment.verbatim.minted.latex meta.environment.embedded.json.latex source.json.embedded assets/syntaxes/01_Packages/LaTeX/LaTeX.sublime-syntax:1275: scope: meta.environment.verbatim.minted.latex assets/syntaxes/01_Packages/LaTeX/LaTeX.sublime-syntax:1283: embed_scope: meta.environment.verbatim.minted.latex meta.environment.embedded.latex.latex text.tex.latex.embedded assets/syntaxes/01_Packages/LaTeX/LaTeX.sublime-syntax:1289: scope: meta.environment.verbatim.minted.latex assets/syntaxes/01_Packages/LaTeX/LaTeX.sublime-syntax:1297: embed_scope: meta.environment.verbatim.minted.latex meta.environment.embedded.lisp.latex source.lisp.embedded assets/syntaxes/01_Packages/LaTeX/LaTeX.sublime-syntax:1303: scope: meta.environment.verbatim.minted.latex assets/syntaxes/01_Packages/LaTeX/LaTeX.sublime-syntax:1311: embed_scope: meta.environment.verbatim.minted.latex meta.environment.embedded.lua.latex source.lua.embedded assets/syntaxes/01_Packages/LaTeX/LaTeX.sublime-syntax:1317: scope: meta.environment.verbatim.minted.latex assets/syntaxes/01_Packages/LaTeX/LaTeX.sublime-syntax:1325: embed_scope: meta.environment.verbatim.minted.latex meta.environment.embedded.objc.latex source.objc.embedded assets/syntaxes/01_Packages/LaTeX/LaTeX.sublime-syntax:1331: scope: meta.environment.verbatim.minted.latex assets/syntaxes/01_Packages/LaTeX/LaTeX.sublime-syntax:1339: embed_scope: meta.environment.verbatim.minted.latex meta.environment.embedded.objc++.latex source.objc++.embedded assets/syntaxes/01_Packages/LaTeX/LaTeX.sublime-syntax:1345: scope: meta.environment.verbatim.minted.latex assets/syntaxes/01_Packages/LaTeX/LaTeX.sublime-syntax:1353: embed_scope: meta.environment.verbatim.minted.latex meta.environment.embedded.perl.latex source.perl.embedded assets/syntaxes/01_Packages/LaTeX/LaTeX.sublime-syntax:1359: scope: meta.environment.verbatim.minted.latex assets/syntaxes/01_Packages/LaTeX/LaTeX.sublime-syntax:1367: embed_scope: meta.environment.verbatim.minted.latex meta.environment.embedded.php.latex source.php.embedded assets/syntaxes/01_Packages/LaTeX/LaTeX.sublime-syntax:1373: scope: meta.environment.verbatim.minted.latex assets/syntaxes/01_Packages/LaTeX/LaTeX.sublime-syntax:1381: embed_scope: meta.environment.verbatim.minted.latex meta.environment.embedded.python.latex source.python.embedded assets/syntaxes/01_Packages/LaTeX/LaTeX.sublime-syntax:1387: scope: meta.environment.verbatim.minted.latex assets/syntaxes/01_Packages/LaTeX/LaTeX.sublime-syntax:1395: embed_scope: meta.environment.verbatim.minted.latex meta.environment.embedded.r.latex source.r.embedded assets/syntaxes/01_Packages/LaTeX/LaTeX.sublime-syntax:1401: scope: meta.environment.verbatim.minted.latex assets/syntaxes/01_Packages/LaTeX/LaTeX.sublime-syntax:1409: embed_scope: meta.environment.verbatim.minted.latex meta.environment.embedded.ruby.latex source.ruby.embedded assets/syntaxes/01_Packages/LaTeX/LaTeX.sublime-syntax:1415: scope: meta.environment.verbatim.minted.latex assets/syntaxes/01_Packages/LaTeX/LaTeX.sublime-syntax:1423: embed_scope: meta.environment.verbatim.minted.latex meta.environment.embedded.shell.latex source.shell.embedded assets/syntaxes/01_Packages/LaTeX/LaTeX.sublime-syntax:1429: scope: meta.environment.verbatim.minted.latex assets/syntaxes/01_Packages/LaTeX/LaTeX.sublime-syntax:1437: embed_scope: meta.environment.verbatim.minted.latex meta.environment.embedded.sql.latex source.sql.embedded assets/syntaxes/01_Packages/LaTeX/LaTeX.sublime-syntax:1443: scope: meta.environment.verbatim.minted.latex assets/syntaxes/01_Packages/LaTeX/LaTeX.sublime-syntax:1451: embed_scope: meta.environment.verbatim.minted.latex meta.environment.embedded.xml.latex text.xml.embedded assets/syntaxes/01_Packages/LaTeX/LaTeX.sublime-syntax:1457: scope: meta.environment.verbatim.minted.latex assets/syntaxes/01_Packages/LaTeX/LaTeX.sublime-syntax:1465: embed_scope: meta.environment.verbatim.minted.latex meta.environment.embedded.yaml.latex source.yaml.embedded assets/syntaxes/01_Packages/LaTeX/syntax_test_latex.tex:261:% VERBATIM assets/syntaxes/01_Packages/LaTeX/syntax_test_latex.tex:267:% ^ meta.environment.verbatim.verb.latex assets/syntaxes/01_Packages/LaTeX/syntax_test_latex.tex:271:% ^ meta.environment.verbatim.verb.latex assets/syntaxes/01_Packages/LaTeX/syntax_test_latex.tex:274:% ^^^^^^^^^^^^^^ meta.environment.verbatim.verb.latex assets/syntaxes/01_Packages/LaTeX/syntax_test_latex.tex:277:% <- - meta.environment.verbatim.verb.latex assets/syntaxes/01_Packages/LaTeX/syntax_test_latex.tex:279:\begin{verbatim} assets/syntaxes/01_Packages/LaTeX/syntax_test_latex.tex:282:The \emph{verbatim} environment sets everything in verbatim. assets/syntaxes/01_Packages/LaTeX/syntax_test_latex.tex:283:% <- meta.environment.verbatim.verbatim.latex assets/syntaxes/01_Packages/LaTeX/syntax_test_latex.tex:284:% ^ markup.raw.verbatim.latex assets/syntaxes/01_Packages/LaTeX/syntax_test_latex.tex:290:\end{verbatim} assets/syntaxes/01_Packages/LaTeX/syntax_test_latex.tex:397:% <- meta.environment.verbatim.lstlisting.latex assets/syntaxes/01_Packages/LaTeX/syntax_test_latex.tex:407:% <- meta.environment.verbatim.lstlisting.latex assets/syntaxes/01_Packages/LaTeX/syntax_test_latex.tex:415:% <- meta.environment.verbatim.lstlisting.latex assets/syntaxes/01_Packages/LaTeX/syntax_test_latex.tex:423:% ^^^^^^^^^^^^^^^^^^^^^ meta.environment.verbatim.lstinline.latex assets/syntaxes/01_Packages/LaTeX/syntax_test_latex.tex:428:% ^ - meta.environment.verbatim.lstinline.latex assets/syntaxes/01_Packages/LaTeX/syntax_test_latex.tex:431:% ^^^^^^^^^^^^^^^^^^^^^ meta.environment.verbatim.lstinline.latex assets/syntaxes/01_Packages/LaTeX/syntax_test_latex.tex:433:% ^ - meta.environment.verbatim.lstinline.latex assets/syntaxes/01_Packages/LaTeX/syntax_test_latex.tex:443:% <- meta.environment.verbatim.minted.latex assets/syntaxes/01_Packages/LaTeX/syntax_test_latex.tex:451:% ^ meta.environment.verbatim.minted.latex assets/syntaxes/01_Packages/LaTeX/syntax_test_latex.tex:459:% ^ meta.environment.verbatim.minted.latex assets/syntaxes/01_Packages/LaTeX/syntax_test_latex.tex:464:% ^ meta.environment.verbatim.minted.latex assets/syntaxes/01_Packages/Java/Ant.sublime-build:10: "cmd": ["ant.bat"] assets/syntaxes/01_Packages/Matlab/Matlab.sublime-syntax:325: - match: \b(zerom|zero22pi|zdatam-ui|zdatam|wrapToPi|wrapTo360|wrapTo2Pi|wrapTo180|worldmap|worldfilewrite|worldfileread|westof|vmap0ui|vmap0rhead|vmap0read|vmap0data|vinvtran|viewshed|vfwdtran|vec2mtx|utmzoneui|utmzone|utmgeoid|usgsdems|usgsdem|usgs24kdem|usamap|updategeostruct|unwrapMultipart|unitstr|unitsratio|undotrim|undoclip|uimaptbx|trimdata|trimcart|trackui|trackg|track2|track1|track|toRadians|toDegrees|tissot|timezone|timedim|time2str|tightmap|tigerp|tigermif|tgrline|textm|tbase|tagm-ui|tagm|symbolm|surfm|surflsrm|surflm|surfdist|surfacem|str2angle|stem3m|stdm|stdist|spzerom|spcread|smoothlong|sm2rad|sm2nm|sm2km|sm2deg|sizem|showm-ui|showm|showaxes|shapewrite|shaperead|shapeinfo|shaderel|setpostn|setm|setltln|seedm|sectorg|sec2hr|sec2hms|sec2hm|sdtsinfo|sdtsdemread|scxsc|scirclui|scircleg|scircle2|scircle1|scatterm|scaleruler|satbath|rsphere|roundn|rotatetext|rotatem|rootlayr|rhxrh|restack|resizem|removeExtraNanSeparators|refvec2mat|refmat2vec|reducem|reckon|readmtx|readfk5|readfields|rcurve|rad2sm|rad2nm|rad2km|rad2dms|rad2dm|rad2deg|quiverm|quiver3m|qrydata|putpole|projlist|projinv|projfwd|project|previewmap|polyxpoly|polysplit|polymerge|polyjoin|polycut|polybool|poly2fv|poly2cw|poly2ccw|polcmap|plotm|plot3m|plabel|pixcenters|pix2map|pix2latlon|pcolorm|patchm|patchesm|parallelui|paperscale|panzoom|originui|org2pol|onem|npi2pi|northarrow|nm2sm|nm2rad|nm2km|nm2deg|newpole|neworig|navfix|nanm|nanclip|namem|n2ecc|mobjects|mlayers|mlabelzero22pi|mlabel|minvtran|minaxis|mfwdtran|meshm|meshlsrm|meshgrat|meridianfwd|meridianarc|meanm|mdistort|mat2hms|mat2dms|mapview|maptrims|maptrimp|maptriml|maptrim|maptool|mapshow|maps|mapprofile|mapoutline|maplist|mapbbox|map2pix|makesymbolspec|makerefmat|makemapped|makedbfspec|makeattribspec|majaxis|lv2ecef|ltln2val|los2|linem|linecirc|limitm|lightmui|lightm|legs|lcolorbar|latlon2pix|kmlwrite|km2sm|km2rad|km2nm|km2deg|ispolycw|ismapped|ismap|isShapeMultipart|intrplon|intrplat|interpm|inputm|ind2rgb8|imbedm|hr2sec|hr2hms|hr2hm|hms2sec|hms2mat|hms2hr|hms2hm|histr|hista|hidem-ui|hidem|handlem-ui|handlem|gtopo30s|gtopo30|gtextm|gshhs|grn2eqa|gridm|grid2image|grepfields|gradientm|globedems|globedem|getworldfilename|getseeds|getm|geotiffread|geotiffinfo|geotiff2mstruct|geoshow|geoloc2grid|geodetic2geocentricLat|geodetic2ecef|geocentric2geodeticLat|gcxsc|gcxgc|gcwaypts|gcpmap|gcm|gc2sc|fromRadians|fromDegrees|framem|flatearthpoly|flat2ecc|fipsname|findm|filterm|fillm|fill3m|extractm|extractfield|etopo5|etopo|eqa2grn|epsm|encodem|ellipse1|elevation|egm96geoid|ecef2lv|ecef2geodetic|ecc2n|ecc2flat|eastof|dteds|dted|driftvel|driftcorr|dreckon|dms2rad|dms2mat|dms2dm|dms2degrees|dms2deg|dm2degrees|distortcalc|distdim|distance|dist2str|displaym|departure|demdataui|demcmap|degrees2dms|degrees2dm|deg2sm|deg2rad|deg2nm|deg2km|deg2dms|deg2dm|defaultm|dcwrhead|dcwread|dcwgaz|dcwdata|daspectm|crossfix|convertlat|contourm|contourfm|contourcmap|contour3m|cometm|comet3m|combntns|colorui|colorm|cmapui|clrmenu|closePolygonParts|clmo-ui|clmo|clma|clipdata|clegendm|clabelm|circcirc|changem|cart2grn|camupm|camtargm|camposm|bufferm|azimuth|axesscale|axesmui|axesm|axes2ecc|avhrrlambert|avhrrgoode|areaquad|areamat|areaint|arcgridread|antipode|angledim|angl2str|almanac)\b assets/syntaxes/01_Packages/RestructuredText/reStructuredText.sublime-syntax:41: comment: verbatim blocks assets/syntaxes/01_Packages/RestructuredText/syntax_test_restructuredtext.rst:95:Verbatim tests assets/syntaxes/01_Packages/RestructuredText/syntax_test_restructuredtext.rst:100: Verbatim assets/syntaxes/01_Packages/RestructuredText/syntax_test_restructuredtext.rst:105: Verbatim assets/syntaxes/01_Packages/RestructuredText/syntax_test_restructuredtext.rst:112: Verbatim assets/syntaxes/01_Packages/RestructuredText/syntax_test_restructuredtext.rst:114: Also Verbatim assets/syntaxes/01_Packages/RestructuredText/syntax_test_restructuredtext.rst:119: Verbatim assets/syntaxes/01_Packages/RestructuredText/syntax_test_restructuredtext.rst:121: Also Verbatim assets/syntaxes/01_Packages/RestructuredText/syntax_test_restructuredtext.rst:127: Verbatim assets/syntaxes/01_Packages/RestructuredText/syntax_test_restructuredtext.rst:129:Not verbatim assets/syntaxes/01_Packages/Go/Indents/GoIndent.tmPreferences:4:batch-reindent real-world code without wrecking it. As such, these rules are assets/syntaxes/01_Packages/Go/Indents/GoIndent.tmPreferences:5:optimized for convenience while typing, not for batch reindentation. assets/syntaxes/01_Packages/YAML/YAML.sublime-syntax:64: c_ns_tag_property: |- # c-verbatim-tag | c-ns-shorthand-tag | c-non-specific-tag assets/manual/bat.1.in:113:\fB-P\fR. To disable the pager permanently, set BAT_PAGER to an empty string. To control assets/manual/bat.1.in:118:Determine which pager is used. This option will override the PAGER and BAT_PAGER assets/manual/bat.1.in:134:export the BAT_THEME environment variable (e.g.: export BAT_THEME="..."). assets/manual/bat.1.in:146:export the BAT_STYLE environment variable (e.g.: export BAT_STYLE=".."). Possible assets/manual/bat.1.in:194:Alternatively, you can use the BAT_CONFIG_PATH environment variable to point {{PROJECT_EXECUTABLE}} to a non-default assets/manual/bat.1.in:235:\fBhttps://github.com/sharkdp/bat\fR assets/completions/bat.bash.in:5:_bat() { assets/completions/bat.bash.in:88:} && complete -F _bat {{PROJECT_EXECUTABLE}} assets/completions/_bat.ps1.in:64: [CompletionResult]::new('--config-dir', 'config-dir', [CompletionResultType]::ParameterName, 'Show bat''s configuration directory.') assets/completions/_bat.ps1.in:65: [CompletionResult]::new('--cache-dir', 'cache-dir', [CompletionResultType]::ParameterName, 'Show bat''s cache directory.') assets/completions/bat.zsh.in:49: '(: --config-dir)'--config-dir'[Show bat'"'"'s configuration directory]' assets/completions/bat.zsh.in:52: '(: --cache-dir)'--cache-dir'[Show bat'"'"'s cache directory]' assets/create.sh:43:bat cache --clear assets/create.sh:56:bat cache --build --blank --source="$ASSET_DIR" --target="$ASSET_DIR" assets/metadata.yaml:2:bat_version: 0.18.3 tests/integration_tests.rs:34:fn bat_raw_command_with_config() -> Command { tests/integration_tests.rs:35: let mut cmd = Command::cargo_bin("bat").unwrap(); tests/integration_tests.rs:37: cmd.env_remove("BAT_CACHE_PATH"); tests/integration_tests.rs:38: cmd.env_remove("BAT_CONFIG_DIR"); tests/integration_tests.rs:39: cmd.env_remove("BAT_CONFIG_PATH"); tests/integration_tests.rs:40: cmd.env_remove("BAT_OPTS"); tests/integration_tests.rs:41: cmd.env_remove("BAT_PAGER"); tests/integration_tests.rs:42: cmd.env_remove("BAT_STYLE"); tests/integration_tests.rs:43: cmd.env_remove("BAT_TABS"); tests/integration_tests.rs:44: cmd.env_remove("BAT_THEME"); tests/integration_tests.rs:51:fn bat_raw_command() -> Command { tests/integration_tests.rs:52: let mut cmd = bat_raw_command_with_config(); tests/integration_tests.rs:57:fn bat_with_config() -> assert_cmd::Command { tests/integration_tests.rs:58: assert_cmd::Command::from_std(bat_raw_command_with_config()) tests/integration_tests.rs:61:fn bat() -> assert_cmd::Command { tests/integration_tests.rs:62: assert_cmd::Command::from_std(bat_raw_command()) tests/integration_tests.rs:67: bat() tests/integration_tests.rs:77: bat() tests/integration_tests.rs:86: bat() tests/integration_tests.rs:96: bat() tests/integration_tests.rs:108: bat() tests/integration_tests.rs:118: bat() tests/integration_tests.rs:128: bat() tests/integration_tests.rs:138: bat() tests/integration_tests.rs:149: bat() tests/integration_tests.rs:160: bat() tests/integration_tests.rs:170: bat() tests/integration_tests.rs:181: bat() tests/integration_tests.rs:192: bat() tests/integration_tests.rs:202: bat() tests/integration_tests.rs:212: bat() tests/integration_tests.rs:222: bat() tests/integration_tests.rs:245: let res = bat_raw_command() tests/integration_tests.rs:261: let res = bat_raw_command() tests/integration_tests.rs:277: let res = bat_raw_command() tests/integration_tests.rs:293: let res = bat_raw_command() tests/integration_tests.rs:307: // To simulate bat getting started from the shell, a process is created with stdin and stdout tests/integration_tests.rs:308: // as the slave end of a pseudo terminal. Although both point to the same "file", bat should tests/integration_tests.rs:316: let mut child = bat_raw_command() tests/integration_tests.rs:349: bat() tests/integration_tests.rs:372: bat() tests/integration_tests.rs:395: bat() tests/integration_tests.rs:418: bat() tests/integration_tests.rs:441: bat() tests/integration_tests.rs:464: bat() tests/integration_tests.rs:487: bat() tests/integration_tests.rs:510: bat().arg("non-existing-file").assert().failure(); tests/integration_tests.rs:515: bat().arg("sub_directory").assert().failure(); tests/integration_tests.rs:520: bat() tests/integration_tests.rs:530: bat() tests/integration_tests.rs:541: bat() tests/integration_tests.rs:543: .env("BAT_PAGER", "echo pager-output") tests/integration_tests.rs:553: bat() tests/integration_tests.rs:555: .env("BAT_PAGER", "") tests/integration_tests.rs:564:fn env_var_pager_value_bat() { tests/integration_tests.rs:565: bat() tests/integration_tests.rs:566: .env("PAGER", "bat") tests/integration_tests.rs:575:fn env_var_bat_pager_value_bat() { tests/integration_tests.rs:576: bat() tests/integration_tests.rs:577: .env("BAT_PAGER", "bat") tests/integration_tests.rs:582: .stderr(predicate::str::contains("bat as a pager is disallowed")); tests/integration_tests.rs:586:fn pager_value_bat() { tests/integration_tests.rs:587: bat() tests/integration_tests.rs:588: .arg("--pager=bat") tests/integration_tests.rs:593: .stderr(predicate::str::contains("bat as a pager is disallowed")); tests/integration_tests.rs:603: bat() tests/integration_tests.rs:613:/// If the bat-specific BAT_PAGER is used, obey the wish of the user tests/integration_tests.rs:617:fn pager_most_from_bat_pager_env_var() { tests/integration_tests.rs:619: bat() tests/integration_tests.rs:620: .env("BAT_PAGER", mocked_pagers::from("most")) tests/integration_tests.rs:629:/// Same reasoning with --pager as with BAT_PAGER tests/integration_tests.rs:634: bat() tests/integration_tests.rs:649: bat() tests/integration_tests.rs:664: bat() tests/integration_tests.rs:676: bat() tests/integration_tests.rs:687: bat() tests/integration_tests.rs:699: bat() tests/integration_tests.rs:700: .env("BAT_PAGER", "mismatched-quotes 'a") tests/integration_tests.rs:710: bat() tests/integration_tests.rs:714: .stdout(predicate::str::contains("BAT_PAGER=")) tests/integration_tests.rs:720: bat_with_config() tests/integration_tests.rs:721: .env("BAT_CONFIG_PATH", "bat.conf") tests/integration_tests.rs:725: .stdout("bat.conf\n"); tests/integration_tests.rs:727: bat_with_config() tests/integration_tests.rs:728: .env("BAT_CONFIG_PATH", "not-existing.conf") tests/integration_tests.rs:740: // Create the file with bat tests/integration_tests.rs:741: bat_with_config() tests/integration_tests.rs:742: .env("BAT_CONFIG_PATH", tmp_config_path.to_str().unwrap()) tests/integration_tests.rs:756:fn config_location_from_bat_config_dir_variable() { tests/integration_tests.rs:757: bat_with_config() tests/integration_tests.rs:758: .env("BAT_CONFIG_DIR", "conf/") tests/integration_tests.rs:767: bat_with_config() tests/integration_tests.rs:768: .env("BAT_CONFIG_PATH", "bat.conf") tests/integration_tests.rs:778: bat() tests/integration_tests.rs:789: bat_with_config() tests/integration_tests.rs:799: bat_with_config() tests/integration_tests.rs:810: bat_with_config() tests/integration_tests.rs:820: bat_with_config().arg("cach").assert().failure(); tests/integration_tests.rs:827: bat() tests/integration_tests.rs:836: bat_with_config() tests/integration_tests.rs:878: bat() tests/integration_tests.rs:898: bat() tests/integration_tests.rs:910: bat() tests/integration_tests.rs:922: bat() tests/integration_tests.rs:936: bat() tests/integration_tests.rs:950: bat() tests/integration_tests.rs:966: bat_with_config() tests/integration_tests.rs:979: bat() tests/integration_tests.rs:995: bat() tests/integration_tests.rs:1008: bat() tests/integration_tests.rs:1020: bat() tests/integration_tests.rs:1040: bat() tests/integration_tests.rs:1057: .stderr("\x1b[33m[bat warning]\x1b[0m: Style 'rule' is a subset of style 'grid', 'rule' will not be visible.\n"); tests/integration_tests.rs:1077: bat() tests/integration_tests.rs:1093: bat() tests/integration_tests.rs:1105: let cmd_for_file = bat() tests/integration_tests.rs:1114: let cmd_for_stdin = bat() tests/integration_tests.rs:1134: bat() tests/integration_tests.rs:1147: bat() tests/integration_tests.rs:1157: bat() tests/integration_tests.rs:1169: bat() tests/integration_tests.rs:1181: bat() tests/integration_tests.rs:1193: bat() tests/integration_tests.rs:1204:// Regression test for https://github.com/sharkdp/bat/issues/299 tests/integration_tests.rs:1207: bat() tests/integration_tests.rs:1231: bat() tests/integration_tests.rs:1240: bat() tests/integration_tests.rs:1250: bat() tests/examples/regression_tests/issue_985.js:3:# bat --map-syntax '*.js:Markdown' --file-name 'issue_985.js' < issue_985.js tests/examples/regression_tests/issue_985.js:4:# bat --map-syntax '*.js:Markdown' --file-name 'issue_985.js' issue_985.js tests/utils/mocked_pagers.rs:16:/// On Windows: 'most' -> 'most.bat' tests/utils/mocked_pagers.rs:19: format!("{}.bat", base) tests/benchmarks/benchmark-results/syntax-highlighting-speed-miniz.c.md:3:| `bat … miniz.c` | 96.2 ± 1.9 | 92.6 | 99.6 | 1.00 | tests/benchmarks/benchmark-results/syntax-highlighting-speed-jquery.js.md:3:| `bat … jquery.js` | 692.4 ± 5.6 | 684.2 | 701.8 | 1.00 | tests/benchmarks/benchmark-results/syntax-highlighting-speed-test_multiarray.py.json:4: "command": "bat … test_multiarray.py", tests/benchmarks/benchmark-results/syntax-highlighting-speed-jquery.js.json:4: "command": "bat … jquery.js", tests/benchmarks/benchmark-results/plain-text-speed.json:4: "command": "bat … --language=txt test_multiarray.py", tests/benchmarks/benchmark-results/syntax-highlighting-speed-test_multiarray.ansi-sequences.txt.md:3:| `bat … test_multiarray.ansi-sequences.txt` | 125.3 ± 5.6 | 119.3 | 140.4 | 1.00 | tests/benchmarks/benchmark-results/syntax-highlighting-speed-test_multiarray.py.md:3:| `bat … test_multiarray.py` | 924.7 ± 4.4 | 917.1 | 932.3 | 1.00 | tests/benchmarks/benchmark-results/report.md:1:## `bat` benchmark results tests/benchmarks/benchmark-results/report.md:7:| `bat` | 6.9 ± 0.6 | 5.6 | 9.2 | 1.00 | tests/benchmarks/benchmark-results/report.md:13:| `bat … --language=txt test_multiarray.py` | 10.4 ± 0.6 | 9.0 | 12.1 | 1.00 | tests/benchmarks/benchmark-results/report.md:19:| `bat … jquery.js` | 692.4 ± 5.6 | 684.2 | 701.8 | 1.00 | tests/benchmarks/benchmark-results/report.md:25:| `bat … miniz.c` | 96.2 ± 1.9 | 92.6 | 99.6 | 1.00 | tests/benchmarks/benchmark-results/report.md:31:| `bat … test_multiarray.ansi-sequences.txt` | 125.3 ± 5.6 | 119.3 | 140.4 | 1.00 | tests/benchmarks/benchmark-results/report.md:37:| `bat … test_multiarray.py` | 924.7 ± 4.4 | 917.1 | 932.3 | 1.00 | tests/benchmarks/benchmark-results/startup-time.md:3:| `bat` | 6.9 ± 0.6 | 5.6 | 9.2 | 1.00 | tests/benchmarks/benchmark-results/syntax-highlighting-speed-miniz.c.json:4: "command": "bat … miniz.c", tests/benchmarks/benchmark-results/plain-text-speed.md:3:| `bat … --language=txt test_multiarray.py` | 10.4 ± 0.6 | 9.0 | 12.1 | 1.00 | tests/benchmarks/benchmark-results/syntax-highlighting-speed-jquery-3.3.1.js.json:4: "command": "/home/shark/.cargo-target/release/bat --style=full --color=always --paging=never test-src/jquery-3.3.1.js", tests/benchmarks/benchmark-results/syntax-highlighting-speed-test_multiarray.highlighted.txt.json:4: "command": "bat … test_multiarray.highlighted.txt", tests/benchmarks/benchmark-results/syntax-highlighting-speed-test_multiarray.ansi-sequences.txt.json:4: "command": "bat … test_multiarray.ansi-sequences.txt", tests/benchmarks/benchmark-results/syntax-highlighting-speed-jquery-3.3.1.min.js.json:4: "command": "/home/shark/.cargo-target/release/bat --style=full --color=always --paging=never test-src/jquery-3.3.1.min.js", tests/benchmarks/benchmark-results/ansi-sequence-forwarding.json:4: "command": "bat … test_multiarray.highlighted.txt", tests/benchmarks/benchmark-results/startup-time.json:4: "command": "bat", tests/benchmarks/run-benchmarks.sh:33:unset BAT_CACHE_PATH tests/benchmarks/run-benchmarks.sh:34:unset BAT_CONFIG_DIR tests/benchmarks/run-benchmarks.sh:35:unset BAT_CONFIG_PATH tests/benchmarks/run-benchmarks.sh:36:unset BAT_OPTS tests/benchmarks/run-benchmarks.sh:37:unset BAT_PAGER tests/benchmarks/run-benchmarks.sh:38:unset BAT_STYLE tests/benchmarks/run-benchmarks.sh:39:unset BAT_TABS tests/benchmarks/run-benchmarks.sh:40:unset BAT_THEME tests/benchmarks/run-benchmarks.sh:50:TARGET_RELEASE="${TARGET_DIR}/release/bat" tests/benchmarks/run-benchmarks.sh:55:BAT='' tests/benchmarks/run-benchmarks.sh:58: --system) BAT="bat" ;; tests/benchmarks/run-benchmarks.sh:59: --release) BAT="$TARGET_RELEASE" ;; tests/benchmarks/run-benchmarks.sh:60: --bat=*) BAT="${arg:6}" ;; tests/benchmarks/run-benchmarks.sh:64:if [[ -z "$BAT" ]]; then tests/benchmarks/run-benchmarks.sh:65: echo "A build of 'bat' must be specified for benchmarking." tests/benchmarks/run-benchmarks.sh:66: echo "You can use '--system', '--release' or '--bat=path/to/bat'." tests/benchmarks/run-benchmarks.sh:70:if ! command -v "$BAT" &>/dev/null; then tests/benchmarks/run-benchmarks.sh:71: echo "Could not find the build of bat to benchmark ($BAT)." tests/benchmarks/run-benchmarks.sh:72: case "$BAT" in tests/benchmarks/run-benchmarks.sh:73: "bat") echo "Make you sure to symlink 'batcat' as 'bat'." ;; tests/benchmarks/run-benchmarks.sh:83:echo "## \`bat\` benchmark results" >> "$REPORT" tests/benchmarks/run-benchmarks.sh:88: "$(printf "%q" "$BAT") --no-config" \ tests/benchmarks/run-benchmarks.sh:89: --command-name "bat" \ tests/benchmarks/run-benchmarks.sh:98: "$(printf "%q" "$BAT") --no-config --language=txt --style=plain test-src/test_multiarray.py" \ tests/benchmarks/run-benchmarks.sh:99: --command-name 'bat … --language=txt test_multiarray.py' \ tests/benchmarks/run-benchmarks.sh:111: "$(printf "%q" "$BAT") --no-config --style=full --color=always '$SRC'" \ tests/benchmarks/run-benchmarks.sh:112: --command-name "bat … ${filename}" \ tests/snapshots/generate_snapshots.py:35:def build_bat(): tests/snapshots/generate_snapshots.py:36: print("building bat") tests/snapshots/generate_snapshots.py:55:build_bat() tests/syntax-tests/create_highlighted_versions.py:11:BAT_OPTIONS = [ tests/syntax-tests/create_highlighted_versions.py:23: "bat_options", tests/syntax-tests/create_highlighted_versions.py:28: options = BAT_OPTIONS.copy() tests/syntax-tests/create_highlighted_versions.py:31: options_file = path.join(source_dirpath, "bat_options") tests/syntax-tests/create_highlighted_versions.py:44: env.pop("BAT_CACHE_PATH", None) tests/syntax-tests/create_highlighted_versions.py:45: env.pop("BAT_CONFIG_DIR", None) tests/syntax-tests/create_highlighted_versions.py:46: env.pop("BAT_CONFIG_PATH", None) tests/syntax-tests/create_highlighted_versions.py:47: env.pop("BAT_OPTS", None) tests/syntax-tests/create_highlighted_versions.py:48: env.pop("BAT_PAGER", None) tests/syntax-tests/create_highlighted_versions.py:49: env.pop("BAT_STYLE", None) tests/syntax-tests/create_highlighted_versions.py:50: env.pop("BAT_TABS", None) tests/syntax-tests/create_highlighted_versions.py:51: env.pop("BAT_THEME", None) tests/syntax-tests/create_highlighted_versions.py:62: bat_output = subprocess.check_output( tests/syntax-tests/create_highlighted_versions.py:63: ["bat"] + get_options(source) + [source], tests/syntax-tests/create_highlighted_versions.py:74: output_file.write(bat_output) tests/syntax-tests/create_highlighted_versions.py:98: "=== bat stdout:\n{}".format(err.stdout.decode("utf-8")), tests/syntax-tests/create_highlighted_versions.py:102: "=== bat stderr:\n{}".format(err.stderr.decode("utf-8")), tests/syntax-tests/create_highlighted_versions.py:108: "Error: Could not execute 'bat'. Please make sure that the executable " tests/syntax-tests/BatTestCustomAssets.sublime-syntax:4:name: BatTestCustomAssets tests/syntax-tests/BatTestCustomAssets.sublime-syntax:6: - battestcustomassets tests/syntax-tests/BatTestCustomAssets.sublime-syntax:7:scope: source.battestcustomassets tests/syntax-tests/BatTestCustomAssets.sublime-syntax:9:# This syntax is used to test if custom assets work with bat. tests/syntax-tests/BatTestCustomAssets.sublime-syntax:20: 1: keyword.other.battestcustomassets-key tests/syntax-tests/BatTestCustomAssets.sublime-syntax:21: 2: string.other.battestcustomassets-value tests/syntax-tests/highlighted/C/test.c:21: /* This C program was written to help bat tests/syntax-tests/highlighted/QML/BatSyntaxTest.qml:19: service: "org.bat.service" tests/syntax-tests/highlighted/QML/BatSyntaxTest.qml:41: text: qsTr("Install Bat.") tests/syntax-tests/highlighted/Diff/82e7786e747b1fcfac1f963ae6415a22ec9caae1.diff:16: ## `bat` as a library tests/syntax-tests/highlighted/Diff/82e7786e747b1fcfac1f963ae6415a22ec9caae1.diff:17:diff --git a/src/bin/bat/app.rs b/src/bin/bat/app.rs tests/syntax-tests/highlighted/Diff/82e7786e747b1fcfac1f963ae6415a22ec9caae1.diff:19:--- a/src/bin/bat/app.rs tests/syntax-tests/highlighted/Diff/82e7786e747b1fcfac1f963ae6415a22ec9caae1.diff:20:+++ b/src/bin/bat/app.rs tests/syntax-tests/highlighted/Diff/82e7786e747b1fcfac1f963ae6415a22ec9caae1.diff:23: use bat::{ tests/syntax-tests/highlighted/Diff/82e7786e747b1fcfac1f963ae6415a22ec9caae1.diff:61:diff --git a/src/bin/bat/clap_app.rs b/src/bin/bat/clap_app.rs tests/syntax-tests/highlighted/Diff/82e7786e747b1fcfac1f963ae6415a22ec9caae1.diff:63:--- a/src/bin/bat/clap_app.rs tests/syntax-tests/highlighted/Diff/82e7786e747b1fcfac1f963ae6415a22ec9caae1.diff:64:+++ b/src/bin/bat/clap_app.rs tests/syntax-tests/highlighted/Diff/82e7786e747b1fcfac1f963ae6415a22ec9caae1.diff:66: data to bat from STDIN when bat does not otherwise know \ tests/syntax-tests/highlighted/Git Attributes/example.gitattributes:10:*.bat text eol=crlf tests/syntax-tests/highlighted/SSH Config/ssh_config:8: BatchMode no tests/syntax-tests/highlighted/Manpage/bat-0.16.man:1:BAT(1) General Commands Manual BAT(1) tests/syntax-tests/highlighted/Manpage/bat-0.16.man:4: bat - a cat(1) clone with syntax highlighting and Git integration. tests/syntax-tests/highlighted/Manpage/bat-0.16.man:7: bat [OPTIONS] [FILE]... tests/syntax-tests/highlighted/Manpage/bat-0.16.man:9: bat cache [CACHE-OPTIONS] [--build|--clear] tests/syntax-tests/highlighted/Manpage/bat-0.16.man:12: bat prints the syntax-highlighted content of a collection of FILEs to tests/syntax-tests/highlighted/Manpage/bat-0.16.man:16: bat supports a large number of programming and markup languages. It tests/syntax-tests/highlighted/Manpage/bat-0.16.man:18: git index. bat automatically pipes its output through a pager (by de‐ tests/syntax-tests/highlighted/Manpage/bat-0.16.man:21: Whenever the output of bat goes to a non-interactive terminal, i.e. tests/syntax-tests/highlighted/Manpage/bat-0.16.man:22: when the output is piped into another process or into a file, bat will tests/syntax-tests/highlighted/Manpage/bat-0.16.man:112: if the output of bat is piped to another program, but you want tests/syntax-tests/highlighted/Manpage/bat-0.16.man:119: set BAT_PAGER to an empty string. To control which pager is tests/syntax-tests/highlighted/Manpage/bat-0.16.man:126: PAGER and BAT_PAGER environment variables. The default pager is tests/syntax-tests/highlighted/Manpage/bat-0.16.man:143: BAT_THEME environment variable (e.g.: export BAT_THEME="..."). tests/syntax-tests/highlighted/Manpage/bat-0.16.man:156: to the configuration file or export the BAT_STYLE environment tests/syntax-tests/highlighted/Manpage/bat-0.16.man:157: variable (e.g.: export BAT_STYLE=".."). Possible values: *auto*, tests/syntax-tests/highlighted/Manpage/bat-0.16.man:202: bat can also be customized with a configuration file. The location of tests/syntax-tests/highlighted/Manpage/bat-0.16.man:206: bat --config-file tests/syntax-tests/highlighted/Manpage/bat-0.16.man:208: Alternatively, you can use the BAT_CONFIG_PATH environment variable to tests/syntax-tests/highlighted/Manpage/bat-0.16.man:209: point bat to a non-default location of the configuration file. tests/syntax-tests/highlighted/Manpage/bat-0.16.man:212: bat supports Sublime Text .sublime-syntax language files, and can be tests/syntax-tests/highlighted/Manpage/bat-0.16.man:214: do this, add the .sublime-snytax language files to `$(bat --config- tests/syntax-tests/highlighted/Manpage/bat-0.16.man:215: dir)/syntaxes` and run `bat cache --build`. tests/syntax-tests/highlighted/Manpage/bat-0.16.man:219: mkdir -p "$(bat --config-dir)/syntaxes" tests/syntax-tests/highlighted/Manpage/bat-0.16.man:220: cd "$(bat --config-dir)/syntaxes" tests/syntax-tests/highlighted/Manpage/bat-0.16.man:227: bat cache --build tests/syntax-tests/highlighted/Manpage/bat-0.16.man:229: Once the cache is built, the new language will be visible in `bat tests/syntax-tests/highlighted/Manpage/bat-0.16.man:232: cache with `bat cache --clear`. tests/syntax-tests/highlighted/Manpage/bat-0.16.man:235: Similarly to custom languages, bat supports Sublime Text .tmTheme tests/syntax-tests/highlighted/Manpage/bat-0.16.man:236: themes. These can be installed to `$(bat --config-dir)/themes`, and tests/syntax-tests/highlighted/Manpage/bat-0.16.man:237: are added to the cache with `bat cache --build`. tests/syntax-tests/highlighted/Manpage/bat-0.16.man:240: For more information and up-to-date documentation, visit the bat repo: tests/syntax-tests/highlighted/Manpage/bat-0.16.man:241: https://github.com/sharkdp/bat tests/syntax-tests/highlighted/Manpage/bat-0.16.man:243: BAT(1) tests/syntax-tests/highlighted/Svelte/App.svelte:30: // This block is a regression test for a bat panic when a LiveScript syntax definition is missing tests/syntax-tests/highlighted/VimL/source.vim:77:" Error case from issue #1604 (https://github.com/sharkdp/bat/issues/1064) tests/syntax-tests/highlighted/Java/test.java:3:/* This Java program was submiited to help bat tests/syntax-tests/highlighted/Sass/example.sass:46: background-image: url("https://github.com/sharkdp/bat/raw/master/doc/logo-header.svg") tests/syntax-tests/highlighted/HTML/test.html:5: <title>Bat Syntax Test tests/syntax-tests/highlighted/Cpp/test.cpp:6:/* This C program was submitted to help bat tests/syntax-tests/highlighted/Crystal/test.cr:1:# An example file to test Crystal syntax highlighting in bat tests/syntax-tests/highlighted/Crystal/test.cr:58:greeter = Greeter.new("bat") tests/syntax-tests/highlighted/GLSL/test.glsl:38: // This GLSL code serves the purpose of bat syntax highlighting tests tests/syntax-tests/highlighted/CMake/CMakeLists.txt:3:project(hello-bat VERSION 0.0.1 LANGUAGES C) tests/syntax-tests/highlighted/CMake/CMakeLists.txt:8:add_executable(hello-bat SOURCES) tests/syntax-tests/highlighted/CMake/CMakeLists.txt:11:target_link_libraries(hello-bat assimp) tests/syntax-tests/highlighted/SCSS/example.scss:48: background-image: url("https://github.com/sharkdp/bat/raw/master/doc/logo-header.svg"); tests/syntax-tests/highlighted/TOML/Cargo.toml:5:homepage = "https://github.com/sharkdp/bat" tests/syntax-tests/highlighted/TOML/Cargo.toml:7:name = "bat" tests/syntax-tests/highlighted/TOML/Cargo.toml:9:repository = "https://github.com/sharkdp/bat" tests/syntax-tests/highlighted/TOML/Cargo.toml:20:# Feature required for bat the application. Should be disabled when depending on tests/syntax-tests/highlighted/TOML/Cargo.toml:21:# bat as a library. tests/syntax-tests/highlighted/Erlang/bat_erlang.erl:1:-module(bat_erlang). tests/syntax-tests/highlighted/Bash/batgrep.sh:3:# bat-extras | Copyright (C) 2020 eth-p and contributors | MIT License tests/syntax-tests/highlighted/Bash/batgrep.sh:5:# Repository: https://github.com/eth-p/bat-extras tests/syntax-tests/highlighted/Bash/batgrep.sh:6:# Issues: https://github.com/eth-p/bat-extras/issues tests/syntax-tests/highlighted/Bash/batgrep.sh:37:printc "%{YELLOW}[%s warning]%{CLEAR}: $1%{CLEAR}\n" "batgrep" "${@:2}" 1>&2 tests/syntax-tests/highlighted/Bash/batgrep.sh:40:printc "%{RED}[%s error]%{CLEAR}: $1%{CLEAR}\n" "batgrep" "${@:2}" 1>&2 tests/syntax-tests/highlighted/Bash/batgrep.sh:116:if [[ -n ${BAT_PAGER+x} ]];then tests/syntax-tests/highlighted/Bash/batgrep.sh:117:SCRIPT_PAGER_CMD=($BAT_PAGER) tests/syntax-tests/highlighted/Bash/batgrep.sh:169:printc "%{RED}%s: '%s' requires a value%{CLEAR}\n" "batgrep" "$ARG" tests/syntax-tests/highlighted/Bash/batgrep.sh:185:*)printc "%{RED}%s: '--color' expects value of 'auto', 'always', or 'never'%{CLEAR}\n" "batgrep" tests/syntax-tests/highlighted/Bash/batgrep.sh:217:*)printc "%{RED}%s: '--paging' expects value of 'auto', 'always', or 'never'%{CLEAR}\n" "batgrep" tests/syntax-tests/highlighted/Bash/batgrep.sh:238:"batgrep" \ tests/syntax-tests/highlighted/Bash/batgrep.sh:241:"https://github.com/eth-p/bat-extras" tests/syntax-tests/highlighted/Bash/batgrep.sh:269:bat_version(){ tests/syntax-tests/highlighted/Bash/batgrep.sh:270:"bat" --version|cut -d ' ' -f 2 tests/syntax-tests/highlighted/Bash/batgrep.sh:319:BAT_ARGS=() tests/syntax-tests/highlighted/Bash/batgrep.sh:330:BAT_STYLE="header,numbers" tests/syntax-tests/highlighted/Bash/batgrep.sh:331:if version_compare "$(bat_version)" -gt "0.12";then tests/syntax-tests/highlighted/Bash/batgrep.sh:419:printc "%{RED}%s: unknown option '%s'%{CLEAR}\n" "batgrep" "$OPT" 1>&2 tests/syntax-tests/highlighted/Bash/batgrep.sh:444:BAT_ARGS+=("--color=always") tests/syntax-tests/highlighted/Bash/batgrep.sh:446:BAT_ARGS+=("--color=never") tests/syntax-tests/highlighted/Bash/batgrep.sh:462:'the pager was explicitly disabled by $BAT_PAGER or the' \ tests/syntax-tests/highlighted/Bash/batgrep.sh:482:"bat" "${BAT_ARGS[@]}" \ tests/syntax-tests/highlighted/Bash/batgrep.sh:485:--style="$BAT_STYLE$OPT_SNIP" \ tests/syntax-tests/highlighted/Bash/simple.sh:15: | cat | bat - | cat tests/syntax-tests/highlighted/Bash/simple.sh:20:if command -v bat &> /dev/null; then tests/syntax-tests/highlighted/Rust/output.rs:39: let pager_from_env = match (env::var("BAT_PAGER"), env::var("PAGER")) { tests/syntax-tests/highlighted/Rust/output.rs:40: (Ok(bat_pager), _) => Some(bat_pager), tests/syntax-tests/highlighted/Rust/output.rs:43: // ANSI color sequences printed by bat. If someone has set PAGER="less -F", we tests/syntax-tests/highlighted/Rust/output.rs:46: // We only do this for PAGER (as it is not specific to 'bat'), not for BAT_PAGER tests/syntax-tests/highlighted/Rust/output.rs:47: // or bats '--pager' command line option. tests/syntax-tests/highlighted/Rust/output.rs:71: if pager_path.file_stem() == Some(&OsString::from("bat")) { tests/syntax-tests/source/C/test.c:21: /* This C program was written to help bat tests/syntax-tests/source/QML/BatSyntaxTest.qml:19: service: "org.bat.service" tests/syntax-tests/source/QML/BatSyntaxTest.qml:41: text: qsTr("Install Bat.") tests/syntax-tests/source/Diff/82e7786e747b1fcfac1f963ae6415a22ec9caae1.diff:16: ## `bat` as a library tests/syntax-tests/source/Diff/82e7786e747b1fcfac1f963ae6415a22ec9caae1.diff:17:diff --git a/src/bin/bat/app.rs b/src/bin/bat/app.rs tests/syntax-tests/source/Diff/82e7786e747b1fcfac1f963ae6415a22ec9caae1.diff:19:--- a/src/bin/bat/app.rs tests/syntax-tests/source/Diff/82e7786e747b1fcfac1f963ae6415a22ec9caae1.diff:20:+++ b/src/bin/bat/app.rs tests/syntax-tests/source/Diff/82e7786e747b1fcfac1f963ae6415a22ec9caae1.diff:23: use bat::{ tests/syntax-tests/source/Diff/82e7786e747b1fcfac1f963ae6415a22ec9caae1.diff:61:diff --git a/src/bin/bat/clap_app.rs b/src/bin/bat/clap_app.rs tests/syntax-tests/source/Diff/82e7786e747b1fcfac1f963ae6415a22ec9caae1.diff:63:--- a/src/bin/bat/clap_app.rs tests/syntax-tests/source/Diff/82e7786e747b1fcfac1f963ae6415a22ec9caae1.diff:64:+++ b/src/bin/bat/clap_app.rs tests/syntax-tests/source/Diff/82e7786e747b1fcfac1f963ae6415a22ec9caae1.diff:66: data to bat from STDIN when bat does not otherwise know \ tests/syntax-tests/source/Git Attributes/example.gitattributes:10:*.bat text eol=crlf tests/syntax-tests/source/SSH Config/ssh_config:8: BatchMode no tests/syntax-tests/source/Manpage/bat-0.16.man:1:BAT(1) General Commands Manual BAT(1) tests/syntax-tests/source/Manpage/bat-0.16.man:4: bat - a cat(1) clone with syntax highlighting and Git integration. tests/syntax-tests/source/Manpage/bat-0.16.man:7: bat [OPTIONS] [FILE]... tests/syntax-tests/source/Manpage/bat-0.16.man:9: bat cache [CACHE-OPTIONS] [--build|--clear] tests/syntax-tests/source/Manpage/bat-0.16.man:12: bat prints the syntax-highlighted content of a collection of FILEs to tests/syntax-tests/source/Manpage/bat-0.16.man:16: bat supports a large number of programming and markup languages. It tests/syntax-tests/source/Manpage/bat-0.16.man:18: git index. bat automatically pipes its output through a pager (by de‐ tests/syntax-tests/source/Manpage/bat-0.16.man:21: Whenever the output of bat goes to a non-interactive terminal, i.e. tests/syntax-tests/source/Manpage/bat-0.16.man:22: when the output is piped into another process or into a file, bat will tests/syntax-tests/source/Manpage/bat-0.16.man:112: if the output of bat is piped to another program, but you want tests/syntax-tests/source/Manpage/bat-0.16.man:119: set BAT_PAGER to an empty string. To control which pager is tests/syntax-tests/source/Manpage/bat-0.16.man:126: PAGER and BAT_PAGER environment variables. The default pager is tests/syntax-tests/source/Manpage/bat-0.16.man:143: BAT_THEME environment variable (e.g.: export BAT_THEME="..."). tests/syntax-tests/source/Manpage/bat-0.16.man:156: to the configuration file or export the BAT_STYLE environment tests/syntax-tests/source/Manpage/bat-0.16.man:157: variable (e.g.: export BAT_STYLE=".."). Possible values: *auto*, tests/syntax-tests/source/Manpage/bat-0.16.man:202: bat can also be customized with a configuration file. The location of tests/syntax-tests/source/Manpage/bat-0.16.man:206: bat --config-file tests/syntax-tests/source/Manpage/bat-0.16.man:208: Alternatively, you can use the BAT_CONFIG_PATH environment variable to tests/syntax-tests/source/Manpage/bat-0.16.man:209: point bat to a non-default location of the configuration file. tests/syntax-tests/source/Manpage/bat-0.16.man:212: bat supports Sublime Text .sublime-syntax language files, and can be tests/syntax-tests/source/Manpage/bat-0.16.man:214: do this, add the .sublime-snytax language files to `$(bat --config- tests/syntax-tests/source/Manpage/bat-0.16.man:215: dir)/syntaxes` and run `bat cache --build`. tests/syntax-tests/source/Manpage/bat-0.16.man:219: mkdir -p "$(bat --config-dir)/syntaxes" tests/syntax-tests/source/Manpage/bat-0.16.man:220: cd "$(bat --config-dir)/syntaxes" tests/syntax-tests/source/Manpage/bat-0.16.man:227: bat cache --build tests/syntax-tests/source/Manpage/bat-0.16.man:229: Once the cache is built, the new language will be visible in `bat tests/syntax-tests/source/Manpage/bat-0.16.man:232: cache with `bat cache --clear`. tests/syntax-tests/source/Manpage/bat-0.16.man:235: Similarly to custom languages, bat supports Sublime Text .tmTheme tests/syntax-tests/source/Manpage/bat-0.16.man:236: themes. These can be installed to `$(bat --config-dir)/themes`, and tests/syntax-tests/source/Manpage/bat-0.16.man:237: are added to the cache with `bat cache --build`. tests/syntax-tests/source/Manpage/bat-0.16.man:240: For more information and up-to-date documentation, visit the bat repo: tests/syntax-tests/source/Manpage/bat-0.16.man:241: https://github.com/sharkdp/bat tests/syntax-tests/source/Manpage/bat-0.16.man:243: BAT(1) tests/syntax-tests/source/Svelte/App.svelte:30: // This block is a regression test for a bat panic when a LiveScript syntax definition is missing tests/syntax-tests/source/VimL/source.vim:77:" Error case from issue #1604 (https://github.com/sharkdp/bat/issues/1064) tests/syntax-tests/source/Git Config/LICENSE.md:1:The `test.gitconfig` file has been added from https://github.com/sharkdp/bat/pull/1336#issuecomment-715905807. Its "free to use". tests/syntax-tests/source/Java/test.java:3:/* This Java program was submiited to help bat tests/syntax-tests/source/Sass/example.sass:46: background-image: url("https://github.com/sharkdp/bat/raw/master/doc/logo-header.svg") tests/syntax-tests/source/HTML/test.html:5: Bat Syntax Test tests/syntax-tests/source/Cpp/test.cpp:6:/* This C program was submitted to help bat tests/syntax-tests/source/Crystal/test.cr:1:# An example file to test Crystal syntax highlighting in bat tests/syntax-tests/source/Crystal/test.cr:58:greeter = Greeter.new("bat") tests/syntax-tests/source/GLSL/test.glsl:38: // This GLSL code serves the purpose of bat syntax highlighting tests tests/syntax-tests/source/Java Server Page (JSP)/LICENSE.md:216:For the Eclipse JDT Core Batch Compiler (ecj-x.x.x.jar) component and the tests/syntax-tests/source/Java Server Page (JSP)/NOTICE:23:JDT Core Batch Compiler component, which is open source software. tests/syntax-tests/source/CMake/CMakeLists.txt:3:project(hello-bat VERSION 0.0.1 LANGUAGES C) tests/syntax-tests/source/CMake/CMakeLists.txt:8:add_executable(hello-bat SOURCES) tests/syntax-tests/source/CMake/CMakeLists.txt:11:target_link_libraries(hello-bat assimp) tests/syntax-tests/source/SCSS/example.scss:48: background-image: url("https://github.com/sharkdp/bat/raw/master/doc/logo-header.svg"); tests/syntax-tests/source/TOML/Cargo.toml:5:homepage = "https://github.com/sharkdp/bat" tests/syntax-tests/source/TOML/Cargo.toml:7:name = "bat" tests/syntax-tests/source/TOML/Cargo.toml:9:repository = "https://github.com/sharkdp/bat" tests/syntax-tests/source/TOML/Cargo.toml:20:# Feature required for bat the application. Should be disabled when depending on tests/syntax-tests/source/TOML/Cargo.toml:21:# bat as a library. tests/syntax-tests/source/Erlang/bat_erlang.erl:1:-module(bat_erlang). tests/syntax-tests/source/Batch/LICENSE.md:1:The `build.bat` file has been added from https://github.com/Leandros/ClangOnWindows/blob/master/build.bat under the following license: tests/syntax-tests/source/Bash/batgrep.sh:3:# bat-extras | Copyright (C) 2020 eth-p and contributors | MIT License tests/syntax-tests/source/Bash/batgrep.sh:5:# Repository: https://github.com/eth-p/bat-extras tests/syntax-tests/source/Bash/batgrep.sh:6:# Issues: https://github.com/eth-p/bat-extras/issues tests/syntax-tests/source/Bash/batgrep.sh:37:printc "%{YELLOW}[%s warning]%{CLEAR}: $1%{CLEAR}\n" "batgrep" "${@:2}" 1>&2 tests/syntax-tests/source/Bash/batgrep.sh:40:printc "%{RED}[%s error]%{CLEAR}: $1%{CLEAR}\n" "batgrep" "${@:2}" 1>&2 tests/syntax-tests/source/Bash/batgrep.sh:116:if [[ -n ${BAT_PAGER+x} ]];then tests/syntax-tests/source/Bash/batgrep.sh:117:SCRIPT_PAGER_CMD=($BAT_PAGER) tests/syntax-tests/source/Bash/batgrep.sh:169:printc "%{RED}%s: '%s' requires a value%{CLEAR}\n" "batgrep" "$ARG" tests/syntax-tests/source/Bash/batgrep.sh:185:*)printc "%{RED}%s: '--color' expects value of 'auto', 'always', or 'never'%{CLEAR}\n" "batgrep" tests/syntax-tests/source/Bash/batgrep.sh:217:*)printc "%{RED}%s: '--paging' expects value of 'auto', 'always', or 'never'%{CLEAR}\n" "batgrep" tests/syntax-tests/source/Bash/batgrep.sh:238:"batgrep" \ tests/syntax-tests/source/Bash/batgrep.sh:241:"https://github.com/eth-p/bat-extras" tests/syntax-tests/source/Bash/batgrep.sh:269:bat_version(){ tests/syntax-tests/source/Bash/batgrep.sh:270:"bat" --version|cut -d ' ' -f 2 tests/syntax-tests/source/Bash/batgrep.sh:319:BAT_ARGS=() tests/syntax-tests/source/Bash/batgrep.sh:330:BAT_STYLE="header,numbers" tests/syntax-tests/source/Bash/batgrep.sh:331:if version_compare "$(bat_version)" -gt "0.12";then tests/syntax-tests/source/Bash/batgrep.sh:419:printc "%{RED}%s: unknown option '%s'%{CLEAR}\n" "batgrep" "$OPT" 1>&2 tests/syntax-tests/source/Bash/batgrep.sh:444:BAT_ARGS+=("--color=always") tests/syntax-tests/source/Bash/batgrep.sh:446:BAT_ARGS+=("--color=never") tests/syntax-tests/source/Bash/batgrep.sh:462:'the pager was explicitly disabled by $BAT_PAGER or the' \ tests/syntax-tests/source/Bash/batgrep.sh:482:"bat" "${BAT_ARGS[@]}" \ tests/syntax-tests/source/Bash/batgrep.sh:485:--style="$BAT_STYLE$OPT_SNIP" \ tests/syntax-tests/source/Bash/simple.sh:15: | cat | bat - | cat tests/syntax-tests/source/Bash/simple.sh:20:if command -v bat &> /dev/null; then tests/syntax-tests/source/Rust/output.rs:39: let pager_from_env = match (env::var("BAT_PAGER"), env::var("PAGER")) { tests/syntax-tests/source/Rust/output.rs:40: (Ok(bat_pager), _) => Some(bat_pager), tests/syntax-tests/source/Rust/output.rs:43: // ANSI color sequences printed by bat. If someone has set PAGER="less -F", we tests/syntax-tests/source/Rust/output.rs:46: // We only do this for PAGER (as it is not specific to 'bat'), not for BAT_PAGER tests/syntax-tests/source/Rust/output.rs:47: // or bats '--pager' command line option. tests/syntax-tests/source/Rust/output.rs:71: if pager_path.file_stem() == Some(&OsString::from("bat")) { tests/syntax-tests/test_custom_assets.sh:6:BAT_CONFIG_DIR=$(mktemp -d) tests/syntax-tests/test_custom_assets.sh:7:export BAT_CONFIG_DIR tests/syntax-tests/test_custom_assets.sh:9:BAT_CACHE_PATH=$(mktemp -d) tests/syntax-tests/test_custom_assets.sh:10:export BAT_CACHE_PATH tests/syntax-tests/test_custom_assets.sh:13:BAT_CONFIG_DIR = ${BAT_CONFIG_DIR} tests/syntax-tests/test_custom_assets.sh:14:BAT_CACHE_PATH = ${BAT_CACHE_PATH} tests/syntax-tests/test_custom_assets.sh:20: "--language=BatTestCustomAssets" tests/syntax-tests/test_custom_assets.sh:21: "tests/syntax-tests/source/BatTestCustomAssets/NoColorsUnlessCustomAssetsAreUsed.battestcustomassets" tests/syntax-tests/test_custom_assets.sh:42:echo_step "TEST: Make sure 'BatTestCustomAssets' is not part of integrated syntaxes" tests/syntax-tests/test_custom_assets.sh:43:bat -f "${custom_syntax_args[@]}" && tests/syntax-tests/test_custom_assets.sh:46:echo_step "PREPARE: Install custom syntax 'BatTestCustomAssets'" tests/syntax-tests/test_custom_assets.sh:47:custom_syntaxes_dir="$(bat --config-dir)/syntaxes" tests/syntax-tests/test_custom_assets.sh:49:cp -v "tests/syntax-tests/BatTestCustomAssets.sublime-syntax" \ tests/syntax-tests/test_custom_assets.sh:50: "${custom_syntaxes_dir}/BatTestCustomAssets.sublime-syntax" tests/syntax-tests/test_custom_assets.sh:52:echo_step "PREPARE: Build custom assets to enable 'BatTestCustomAssets' syntax" tests/syntax-tests/test_custom_assets.sh:53:bat cache --build tests/syntax-tests/test_custom_assets.sh:55:echo_step "TEST: 'BatTestCustomAssets' is a known syntax" tests/syntax-tests/test_custom_assets.sh:56:bat -f "${custom_syntax_args[@]}" || tests/syntax-tests/test_custom_assets.sh:60:bat -f "${integrated_syntax_args[@]}" || tests/syntax-tests/test_custom_assets.sh:63:echo_step "TEST: 'BatTestCustomAssets' is an unknown syntax with --no-custom-assets" tests/syntax-tests/test_custom_assets.sh:64:bat -f --no-custom-assets "${custom_syntax_args[@]}" && tests/syntax-tests/test_custom_assets.sh:67:echo_step "TEST: 'bat cache --clear' removes all files" tests/syntax-tests/test_custom_assets.sh:68:bat cache --clear tests/syntax-tests/test_custom_assets.sh:69:remaining_files=$(ls -A "${BAT_CACHE_PATH}") tests/syntax-tests/test_custom_assets.sh:74:rm -rv "${BAT_CONFIG_DIR}" "${BAT_CACHE_PATH}" tests/assets.rs:1:use bat::assets::HighlightingAssets; tests/no_duplicate_extensions.rs:3:use bat::assets::HighlightingAssets; tests/scripts/find-slow-to-highlight-files.py:3:# This script goes through all languages that are supported by 'bat'. For each tests/scripts/find-slow-to-highlight-files.py:5:# given folder for matching files. It calls 'bat' for each of these files and tests/scripts/find-slow-to-highlight-files.py:8:# execution of 'bat'. tests/scripts/find-slow-to-highlight-files.py:11:# - bat (in the $PATH) tests/scripts/find-slow-to-highlight-files.py:24:# Maximum time we allow `bat` to run tests/scripts/find-slow-to-highlight-files.py:25:BAT_TIMEOUT_SEC = 10 tests/scripts/find-slow-to-highlight-files.py:62: sp.check_output(["bat", "--color=always", path], timeout=BAT_TIMEOUT_SEC) tests/scripts/find-slow-to-highlight-files.py:77: if num_chars < THRESHOLD_SPEED * BAT_TIMEOUT_SEC: tests/scripts/find-slow-to-highlight-files.py:78: print(f" Error: bat timed out on file '{path.decode()}'.") tests/scripts/find-slow-to-highlight-files.py:81: f" Warning: bat timed out on file '{path.decode()} (but the file is large)." tests/scripts/find-slow-to-highlight-files.py:85:def measure_bat_startup_speed(): tests/scripts/find-slow-to-highlight-files.py:90: ["bat", "--color=always", "--language=py"], stdin=sp.PIPE, stdout=sp.PIPE tests/scripts/find-slow-to-highlight-files.py:102: output = sp.check_output(["bat", "--list-languages"]).decode() tests/scripts/find-slow-to-highlight-files.py:113: print("Measuring 'bat' startup speed ... ", flush=True, end="") tests/scripts/find-slow-to-highlight-files.py:114: startup_time = measure_bat_startup_speed() tests/tester.rs:13:pub struct BatTester { tests/tester.rs:17: /// Path to the *bat* executable tests/tester.rs:21:impl BatTester { tests/tester.rs:35: .expect("bat failed"); tests/tester.rs:52:impl Default for BatTester { tests/tester.rs:61: .expect("bat executable directory") tests/tester.rs:64: let exe_name = if cfg!(windows) { "bat.exe" } else { "bat" }; tests/tester.rs:67: BatTester { temp_dir, exe } tests/tester.rs:86: let signature = Signature::now("bat test runner", "bat@test.runner")?; tests/snapshot_tests.rs:3:use crate::tester::BatTester; tests/snapshot_tests.rs:10: let bat_tester = BatTester::default(); tests/snapshot_tests.rs:11: bat_tester.test_snapshot(stringify!($test_name), $style); diagnostics/info.sh:2:_modules=('system' 'bat' 'bat_config' 'bat_wrapper' 'bat_wrapper_function' 'tool') diagnostics/info.sh:10:BAT="bat" diagnostics/info.sh:11:if ! command -v bat &>/dev/null; then diagnostics/info.sh:12: if command -v batcat &> /dev/null; then diagnostics/info.sh:13: BAT="batcat" diagnostics/info.sh:17: "Unable to find a bat executable on your PATH." \ diagnostics/info.sh:18: "Please ensure that 'bat' exists and is not named something else." diagnostics/info.sh:28:_bat_:description() { diagnostics/info.sh:29: _collects "Version information for 'bat'." diagnostics/info.sh:30: _collects "Custom syntaxes and themes for 'bat'." diagnostics/info.sh:33:_bat_config_:description() { diagnostics/info.sh:34: _collects "The environment variables used by 'bat'." diagnostics/info.sh:35: _collects "The 'bat' configuration file." diagnostics/info.sh:38:_bat_wrapper_:description() { diagnostics/info.sh:39: _collects "Any wrapper script used by 'bat'." diagnostics/info.sh:42:_bat_wrapper_function_:description() { diagnostics/info.sh:43: _collects "The wrapper function surrounding 'bat' (if applicable)." diagnostics/info.sh:57:_bat_:run() { diagnostics/info.sh:58: _out "$BAT" --version diagnostics/info.sh:59: _out env | grep '^BAT_\|^PAGER=' diagnostics/info.sh:62: cache_dir="$($BAT --cache-dir)" diagnostics/info.sh:64: _print_command "$BAT" "--list-languages" diagnostics/info.sh:69: _print_command "$BAT" "--list-themes" diagnostics/info.sh:74:_bat_config_:run() { diagnostics/info.sh:75: if [[ -f "$("$BAT" --config-file)" ]]; then diagnostics/info.sh:76: _out_fence cat "$("$BAT" --config-file)" diagnostics/info.sh:80:_bat_wrapper_:run() { diagnostics/info.sh:81: _bat_wrapper_:detect_wrapper() { diagnostics/info.sh:82: local bat="$1" diagnostics/info.sh:83: if file "$(command -v "${bat}")" | grep "text executable" &> /dev/null; then diagnostics/info.sh:84: _out_fence cat "$(command -v "${bat}")" diagnostics/info.sh:88: printf "\nNo wrapper script for '%s'.\n" "${bat}" diagnostics/info.sh:91: _bat_wrapper_:detect_wrapper bat diagnostics/info.sh:92: if [[ "$BAT" != "bat" ]]; then diagnostics/info.sh:93: _bat_wrapper_:detect_wrapper "$BAT" diagnostics/info.sh:97:_bat_wrapper_function_:run() { diagnostics/info.sh:98: _bat_wrapper_function_:detect_wrapper() { diagnostics/info.sh:125: _bat_wrapper_function_:detect_wrapper bat diagnostics/info.sh:126: _bat_wrapper_function_:detect_wrapper cat diagnostics/info.sh:127: if [[ "$BAT" != "bat" ]]; then diagnostics/info.sh:128: _bat_wrapper_function_:detect_wrapper "$BAT" diagnostics/info.sh:180:system and bat configuration. It will give you a small preview of the commands diagnostics/info.sh:201: | sed "s/\"\$BAT\"/$BAT/" 1>&2 diagnostics/info.sh:228:# Tell the user if their executable isn't named "bat". diagnostics/info.sh:229:if [[ "$BAT" != "bat" ]] && [[ "$1" != '-y' ]]; then diagnostics/info.sh:235: printf "The %s executable on your system is named '%s'.\n%s\n" "bat" "$BAT" \ bat-0.19.0/tests/benchmarks/highlighting-speed-src/jquery.js000064400000000000000000010226070072674642500222050ustar 00000000000000/*! * jQuery JavaScript Library v3.3.1 * https://jquery.com/ * * Includes Sizzle.js * https://sizzlejs.com/ * * Copyright JS Foundation and other contributors * Released under the MIT license * https://jquery.org/license * * Date: 2018-01-20T17:24Z */ ( function( global, factory ) { "use strict"; if ( typeof module === "object" && typeof module.exports === "object" ) { // For CommonJS and CommonJS-like environments where a proper `window` // is present, execute the factory and get jQuery. // For environments that do not have a `window` with a `document` // (such as Node.js), expose a factory as module.exports. // This accentuates the need for the creation of a real `window`. // e.g. var jQuery = require("jquery")(window); // See ticket #14549 for more info. module.exports = global.document ? factory( global, true ) : function( w ) { if ( !w.document ) { throw new Error( "jQuery requires a window with a document" ); } return factory( w ); }; } else { factory( global ); } // Pass this if window is not defined yet } )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) { // Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1 // throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode // arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common // enough that all such attempts are guarded in a try block. "use strict"; var arr = []; var document = window.document; var getProto = Object.getPrototypeOf; var slice = arr.slice; var concat = arr.concat; var push = arr.push; var indexOf = arr.indexOf; var class2type = {}; var toString = class2type.toString; var hasOwn = class2type.hasOwnProperty; var fnToString = hasOwn.toString; var ObjectFunctionString = fnToString.call( Object ); var support = {}; var isFunction = function isFunction( obj ) { // Support: Chrome <=57, Firefox <=52 // In some browsers, typeof returns "function" for HTML elements // (i.e., `typeof document.createElement( "object" ) === "function"`). // We don't want to classify *any* DOM node as a function. return typeof obj === "function" && typeof obj.nodeType !== "number"; }; var isWindow = function isWindow( obj ) { return obj != null && obj === obj.window; }; var preservedScriptAttributes = { type: true, src: true, noModule: true }; function DOMEval( code, doc, node ) { doc = doc || document; var i, script = doc.createElement( "script" ); script.text = code; if ( node ) { for ( i in preservedScriptAttributes ) { if ( node[ i ] ) { script[ i ] = node[ i ]; } } } doc.head.appendChild( script ).parentNode.removeChild( script ); } function toType( obj ) { if ( obj == null ) { return obj + ""; } // Support: Android <=2.3 only (functionish RegExp) return typeof obj === "object" || typeof obj === "function" ? class2type[ toString.call( obj ) ] || "object" : typeof obj; } /* global Symbol */ // Defining this global in .eslintrc.json would create a danger of using the global // unguarded in another place, it seems safer to define global only for this module var version = "3.3.1", // Define a local copy of jQuery jQuery = function( selector, context ) { // The jQuery object is actually just the init constructor 'enhanced' // Need init if jQuery is called (just allow error to be thrown if not included) return new jQuery.fn.init( selector, context ); }, // Support: Android <=4.0 only // Make sure we trim BOM and NBSP rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g; jQuery.fn = jQuery.prototype = { // The current version of jQuery being used jquery: version, constructor: jQuery, // The default length of a jQuery object is 0 length: 0, toArray: function() { return slice.call( this ); }, // Get the Nth element in the matched element set OR // Get the whole matched element set as a clean array get: function( num ) { // Return all the elements in a clean array if ( num == null ) { return slice.call( this ); } // Return just the one element from the set return num < 0 ? this[ num + this.length ] : this[ num ]; }, // Take an array of elements and push it onto the stack // (returning the new matched element set) pushStack: function( elems ) { // Build a new jQuery matched element set var ret = jQuery.merge( this.constructor(), elems ); // Add the old object onto the stack (as a reference) ret.prevObject = this; // Return the newly-formed element set return ret; }, // Execute a callback for every element in the matched set. each: function( callback ) { return jQuery.each( this, callback ); }, map: function( callback ) { return this.pushStack( jQuery.map( this, function( elem, i ) { return callback.call( elem, i, elem ); } ) ); }, slice: function() { return this.pushStack( slice.apply( this, arguments ) ); }, first: function() { return this.eq( 0 ); }, last: function() { return this.eq( -1 ); }, eq: function( i ) { var len = this.length, j = +i + ( i < 0 ? len : 0 ); return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); }, end: function() { return this.prevObject || this.constructor(); }, // For internal use only. // Behaves like an Array's method, not like a jQuery method. push: push, sort: arr.sort, splice: arr.splice }; jQuery.extend = jQuery.fn.extend = function() { var options, name, src, copy, copyIsArray, clone, target = arguments[ 0 ] || {}, i = 1, length = arguments.length, deep = false; // Handle a deep copy situation if ( typeof target === "boolean" ) { deep = target; // Skip the boolean and the target target = arguments[ i ] || {}; i++; } // Handle case when target is a string or something (possible in deep copy) if ( typeof target !== "object" && !isFunction( target ) ) { target = {}; } // Extend jQuery itself if only one argument is passed if ( i === length ) { target = this; i--; } for ( ; i < length; i++ ) { // Only deal with non-null/undefined values if ( ( options = arguments[ i ] ) != null ) { // Extend the base object for ( name in options ) { src = target[ name ]; copy = options[ name ]; // Prevent never-ending loop if ( target === copy ) { continue; } // Recurse if we're merging plain objects or arrays if ( deep && copy && ( jQuery.isPlainObject( copy ) || ( copyIsArray = Array.isArray( copy ) ) ) ) { if ( copyIsArray ) { copyIsArray = false; clone = src && Array.isArray( src ) ? src : []; } else { clone = src && jQuery.isPlainObject( src ) ? src : {}; } // Never move original objects, clone them target[ name ] = jQuery.extend( deep, clone, copy ); // Don't bring in undefined values } else if ( copy !== undefined ) { target[ name ] = copy; } } } } // Return the modified object return target; }; jQuery.extend( { // Unique for each copy of jQuery on the page expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), // Assume jQuery is ready without the ready module isReady: true, error: function( msg ) { throw new Error( msg ); }, noop: function() {}, isPlainObject: function( obj ) { var proto, Ctor; // Detect obvious negatives // Use toString instead of jQuery.type to catch host objects if ( !obj || toString.call( obj ) !== "[object Object]" ) { return false; } proto = getProto( obj ); // Objects with no prototype (e.g., `Object.create( null )`) are plain if ( !proto ) { return true; } // Objects with prototype are plain iff they were constructed by a global Object function Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor; return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString; }, isEmptyObject: function( obj ) { /* eslint-disable no-unused-vars */ // See https://github.com/eslint/eslint/issues/6125 var name; for ( name in obj ) { return false; } return true; }, // Evaluates a script in a global context globalEval: function( code ) { DOMEval( code ); }, each: function( obj, callback ) { var length, i = 0; if ( isArrayLike( obj ) ) { length = obj.length; for ( ; i < length; i++ ) { if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { break; } } } else { for ( i in obj ) { if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { break; } } } return obj; }, // Support: Android <=4.0 only trim: function( text ) { return text == null ? "" : ( text + "" ).replace( rtrim, "" ); }, // results is for internal usage only makeArray: function( arr, results ) { var ret = results || []; if ( arr != null ) { if ( isArrayLike( Object( arr ) ) ) { jQuery.merge( ret, typeof arr === "string" ? [ arr ] : arr ); } else { push.call( ret, arr ); } } return ret; }, inArray: function( elem, arr, i ) { return arr == null ? -1 : indexOf.call( arr, elem, i ); }, // Support: Android <=4.0 only, PhantomJS 1 only // push.apply(_, arraylike) throws on ancient WebKit merge: function( first, second ) { var len = +second.length, j = 0, i = first.length; for ( ; j < len; j++ ) { first[ i++ ] = second[ j ]; } first.length = i; return first; }, grep: function( elems, callback, invert ) { var callbackInverse, matches = [], i = 0, length = elems.length, callbackExpect = !invert; // Go through the array, only saving the items // that pass the validator function for ( ; i < length; i++ ) { callbackInverse = !callback( elems[ i ], i ); if ( callbackInverse !== callbackExpect ) { matches.push( elems[ i ] ); } } return matches; }, // arg is for internal usage only map: function( elems, callback, arg ) { var length, value, i = 0, ret = []; // Go through the array, translating each of the items to their new values if ( isArrayLike( elems ) ) { length = elems.length; for ( ; i < length; i++ ) { value = callback( elems[ i ], i, arg ); if ( value != null ) { ret.push( value ); } } // Go through every key on the object, } else { for ( i in elems ) { value = callback( elems[ i ], i, arg ); if ( value != null ) { ret.push( value ); } } } // Flatten any nested arrays return concat.apply( [], ret ); }, // A global GUID counter for objects guid: 1, // jQuery.support is not used in Core but other projects attach their // properties to it so it needs to exist. support: support } ); if ( typeof Symbol === "function" ) { jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ]; } // Populate the class2type map jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), function( i, name ) { class2type[ "[object " + name + "]" ] = name.toLowerCase(); } ); function isArrayLike( obj ) { // Support: real iOS 8.2 only (not reproducible in simulator) // `in` check used to prevent JIT error (gh-2145) // hasOwn isn't used here due to false negatives // regarding Nodelist length in IE var length = !!obj && "length" in obj && obj.length, type = toType( obj ); if ( isFunction( obj ) || isWindow( obj ) ) { return false; } return type === "array" || length === 0 || typeof length === "number" && length > 0 && ( length - 1 ) in obj; } var Sizzle = /*! * Sizzle CSS Selector Engine v2.3.3 * https://sizzlejs.com/ * * Copyright jQuery Foundation and other contributors * Released under the MIT license * http://jquery.org/license * * Date: 2016-08-08 */ (function( window ) { var i, support, Expr, getText, isXML, tokenize, compile, select, outermostContext, sortInput, hasDuplicate, // Local document vars setDocument, document, docElem, documentIsHTML, rbuggyQSA, rbuggyMatches, matches, contains, // Instance-specific data expando = "sizzle" + 1 * new Date(), preferredDoc = window.document, dirruns = 0, done = 0, classCache = createCache(), tokenCache = createCache(), compilerCache = createCache(), sortOrder = function( a, b ) { if ( a === b ) { hasDuplicate = true; } return 0; }, // Instance methods hasOwn = ({}).hasOwnProperty, arr = [], pop = arr.pop, push_native = arr.push, push = arr.push, slice = arr.slice, // Use a stripped-down indexOf as it's faster than native // https://jsperf.com/thor-indexof-vs-for/5 indexOf = function( list, elem ) { var i = 0, len = list.length; for ( ; i < len; i++ ) { if ( list[i] === elem ) { return i; } } return -1; }, booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", // Regular expressions // http://www.w3.org/TR/css3-selectors/#whitespace whitespace = "[\\x20\\t\\r\\n\\f]", // http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier identifier = "(?:\\\\.|[\\w-]|[^\0-\\xa0])+", // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + // Operator (capture 2) "*([*^$|!~]?=)" + whitespace + // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + "*\\]", pseudos = ":(" + identifier + ")(?:\\((" + // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: // 1. quoted (capture 3; capture 4 or capture 5) "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + // 2. simple (capture 6) "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + // 3. anything else (capture 2) ".*" + ")\\)|)", // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter rwhitespace = new RegExp( whitespace + "+", "g" ), rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ), rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ), rpseudo = new RegExp( pseudos ), ridentifier = new RegExp( "^" + identifier + "$" ), matchExpr = { "ID": new RegExp( "^#(" + identifier + ")" ), "CLASS": new RegExp( "^\\.(" + identifier + ")" ), "TAG": new RegExp( "^(" + identifier + "|[*])" ), "ATTR": new RegExp( "^" + attributes ), "PSEUDO": new RegExp( "^" + pseudos ), "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), // For use in libraries implementing .is() // We use this for POS matching in `select` "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) }, rinputs = /^(?:input|select|textarea|button)$/i, rheader = /^h\d$/i, rnative = /^[^{]+\{\s*\[native \w/, // Easily-parseable/retrievable ID or TAG or CLASS selectors rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, rsibling = /[+~]/, // CSS escapes // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ), funescape = function( _, escaped, escapedWhitespace ) { var high = "0x" + escaped - 0x10000; // NaN means non-codepoint // Support: Firefox<24 // Workaround erroneous numeric interpretation of +"0x" return high !== high || escapedWhitespace ? escaped : high < 0 ? // BMP codepoint String.fromCharCode( high + 0x10000 ) : // Supplemental Plane codepoint (surrogate pair) String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); }, // CSS string/identifier serialization // https://drafts.csswg.org/cssom/#common-serializing-idioms rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g, fcssescape = function( ch, asCodePoint ) { if ( asCodePoint ) { // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER if ( ch === "\0" ) { return "\uFFFD"; } // Control characters and (dependent upon position) numbers get escaped as code points return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; } // Other potentially-special ASCII characters get backslash-escaped return "\\" + ch; }, // Used for iframes // See setDocument() // Removing the function wrapper causes a "Permission Denied" // error in IE unloadHandler = function() { setDocument(); }, disabledAncestor = addCombinator( function( elem ) { return elem.disabled === true && ("form" in elem || "label" in elem); }, { dir: "parentNode", next: "legend" } ); // Optimize for push.apply( _, NodeList ) try { push.apply( (arr = slice.call( preferredDoc.childNodes )), preferredDoc.childNodes ); // Support: Android<4.0 // Detect silently failing push.apply arr[ preferredDoc.childNodes.length ].nodeType; } catch ( e ) { push = { apply: arr.length ? // Leverage slice if possible function( target, els ) { push_native.apply( target, slice.call(els) ); } : // Support: IE<9 // Otherwise append directly function( target, els ) { var j = target.length, i = 0; // Can't trust NodeList.length while ( (target[j++] = els[i++]) ) {} target.length = j - 1; } }; } function Sizzle( selector, context, results, seed ) { var m, i, elem, nid, match, groups, newSelector, newContext = context && context.ownerDocument, // nodeType defaults to 9, since context defaults to document nodeType = context ? context.nodeType : 9; results = results || []; // Return early from calls with invalid selector or context if ( typeof selector !== "string" || !selector || nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { return results; } // Try to shortcut find operations (as opposed to filters) in HTML documents if ( !seed ) { if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { setDocument( context ); } context = context || document; if ( documentIsHTML ) { // If the selector is sufficiently simple, try using a "get*By*" DOM method // (excepting DocumentFragment context, where the methods don't exist) if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) { // ID selector if ( (m = match[1]) ) { // Document context if ( nodeType === 9 ) { if ( (elem = context.getElementById( m )) ) { // Support: IE, Opera, Webkit // TODO: identify versions // getElementById can match elements by name instead of ID if ( elem.id === m ) { results.push( elem ); return results; } } else { return results; } // Element context } else { // Support: IE, Opera, Webkit // TODO: identify versions // getElementById can match elements by name instead of ID if ( newContext && (elem = newContext.getElementById( m )) && contains( context, elem ) && elem.id === m ) { results.push( elem ); return results; } } // Type selector } else if ( match[2] ) { push.apply( results, context.getElementsByTagName( selector ) ); return results; // Class selector } else if ( (m = match[3]) && support.getElementsByClassName && context.getElementsByClassName ) { push.apply( results, context.getElementsByClassName( m ) ); return results; } } // Take advantage of querySelectorAll if ( support.qsa && !compilerCache[ selector + " " ] && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { if ( nodeType !== 1 ) { newContext = context; newSelector = selector; // qSA looks outside Element context, which is not what we want // Thanks to Andrew Dupont for this workaround technique // Support: IE <=8 // Exclude object elements } else if ( context.nodeName.toLowerCase() !== "object" ) { // Capture the context ID, setting it first if necessary if ( (nid = context.getAttribute( "id" )) ) { nid = nid.replace( rcssescape, fcssescape ); } else { context.setAttribute( "id", (nid = expando) ); } // Prefix every selector in the list groups = tokenize( selector ); i = groups.length; while ( i-- ) { groups[i] = "#" + nid + " " + toSelector( groups[i] ); } newSelector = groups.join( "," ); // Expand context for sibling selectors newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context; } if ( newSelector ) { try { push.apply( results, newContext.querySelectorAll( newSelector ) ); return results; } catch ( qsaError ) { } finally { if ( nid === expando ) { context.removeAttribute( "id" ); } } } } } } // All others return select( selector.replace( rtrim, "$1" ), context, results, seed ); } /** * Create key-value caches of limited size * @returns {function(string, object)} Returns the Object data after storing it on itself with * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) * deleting the oldest entry */ function createCache() { var keys = []; function cache( key, value ) { // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) if ( keys.push( key + " " ) > Expr.cacheLength ) { // Only keep the most recent entries delete cache[ keys.shift() ]; } return (cache[ key + " " ] = value); } return cache; } /** * Mark a function for special use by Sizzle * @param {Function} fn The function to mark */ function markFunction( fn ) { fn[ expando ] = true; return fn; } /** * Support testing using an element * @param {Function} fn Passed the created element and returns a boolean result */ function assert( fn ) { var el = document.createElement("fieldset"); try { return !!fn( el ); } catch (e) { return false; } finally { // Remove from its parent by default if ( el.parentNode ) { el.parentNode.removeChild( el ); } // release memory in IE el = null; } } /** * Adds the same handler for all of the specified attrs * @param {String} attrs Pipe-separated list of attributes * @param {Function} handler The method that will be applied */ function addHandle( attrs, handler ) { var arr = attrs.split("|"), i = arr.length; while ( i-- ) { Expr.attrHandle[ arr[i] ] = handler; } } /** * Checks document order of two siblings * @param {Element} a * @param {Element} b * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b */ function siblingCheck( a, b ) { var cur = b && a, diff = cur && a.nodeType === 1 && b.nodeType === 1 && a.sourceIndex - b.sourceIndex; // Use IE sourceIndex if available on both nodes if ( diff ) { return diff; } // Check if b follows a if ( cur ) { while ( (cur = cur.nextSibling) ) { if ( cur === b ) { return -1; } } } return a ? 1 : -1; } /** * Returns a function to use in pseudos for input types * @param {String} type */ function createInputPseudo( type ) { return function( elem ) { var name = elem.nodeName.toLowerCase(); return name === "input" && elem.type === type; }; } /** * Returns a function to use in pseudos for buttons * @param {String} type */ function createButtonPseudo( type ) { return function( elem ) { var name = elem.nodeName.toLowerCase(); return (name === "input" || name === "button") && elem.type === type; }; } /** * Returns a function to use in pseudos for :enabled/:disabled * @param {Boolean} disabled true for :disabled; false for :enabled */ function createDisabledPseudo( disabled ) { // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable return function( elem ) { // Only certain elements can match :enabled or :disabled // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled if ( "form" in elem ) { // Check for inherited disabledness on relevant non-disabled elements: // * listed form-associated elements in a disabled fieldset // https://html.spec.whatwg.org/multipage/forms.html#category-listed // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled // * option elements in a disabled optgroup // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled // All such elements have a "form" property. if ( elem.parentNode && elem.disabled === false ) { // Option elements defer to a parent optgroup if present if ( "label" in elem ) { if ( "label" in elem.parentNode ) { return elem.parentNode.disabled === disabled; } else { return elem.disabled === disabled; } } // Support: IE 6 - 11 // Use the isDisabled shortcut property to check for disabled fieldset ancestors return elem.isDisabled === disabled || // Where there is no isDisabled, check manually /* jshint -W018 */ elem.isDisabled !== !disabled && disabledAncestor( elem ) === disabled; } return elem.disabled === disabled; // Try to winnow out elements that can't be disabled before trusting the disabled property. // Some victims get caught in our net (label, legend, menu, track), but it shouldn't // even exist on them, let alone have a boolean value. } else if ( "label" in elem ) { return elem.disabled === disabled; } // Remaining elements are neither :enabled nor :disabled return false; }; } /** * Returns a function to use in pseudos for positionals * @param {Function} fn */ function createPositionalPseudo( fn ) { return markFunction(function( argument ) { argument = +argument; return markFunction(function( seed, matches ) { var j, matchIndexes = fn( [], seed.length, argument ), i = matchIndexes.length; // Match elements found at the specified indexes while ( i-- ) { if ( seed[ (j = matchIndexes[i]) ] ) { seed[j] = !(matches[j] = seed[j]); } } }); }); } /** * Checks a node for validity as a Sizzle context * @param {Element|Object=} context * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value */ function testContext( context ) { return context && typeof context.getElementsByTagName !== "undefined" && context; } // Expose support vars for convenience support = Sizzle.support = {}; /** * Detects XML nodes * @param {Element|Object} elem An element or a document * @returns {Boolean} True iff elem is a non-HTML XML node */ isXML = Sizzle.isXML = function( elem ) { // documentElement is verified for cases where it doesn't yet exist // (such as loading iframes in IE - #4833) var documentElement = elem && (elem.ownerDocument || elem).documentElement; return documentElement ? documentElement.nodeName !== "HTML" : false; }; /** * Sets document-related variables once based on the current document * @param {Element|Object} [doc] An element or document object to use to set the document * @returns {Object} Returns the current document */ setDocument = Sizzle.setDocument = function( node ) { var hasCompare, subWindow, doc = node ? node.ownerDocument || node : preferredDoc; // Return early if doc is invalid or already selected if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { return document; } // Update global variables document = doc; docElem = document.documentElement; documentIsHTML = !isXML( document ); // Support: IE 9-11, Edge // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) if ( preferredDoc !== document && (subWindow = document.defaultView) && subWindow.top !== subWindow ) { // Support: IE 11, Edge if ( subWindow.addEventListener ) { subWindow.addEventListener( "unload", unloadHandler, false ); // Support: IE 9 - 10 only } else if ( subWindow.attachEvent ) { subWindow.attachEvent( "onunload", unloadHandler ); } } /* Attributes ---------------------------------------------------------------------- */ // Support: IE<8 // Verify that getAttribute really returns attributes and not properties // (excepting IE8 booleans) support.attributes = assert(function( el ) { el.className = "i"; return !el.getAttribute("className"); }); /* getElement(s)By* ---------------------------------------------------------------------- */ // Check if getElementsByTagName("*") returns only elements support.getElementsByTagName = assert(function( el ) { el.appendChild( document.createComment("") ); return !el.getElementsByTagName("*").length; }); // Support: IE<9 support.getElementsByClassName = rnative.test( document.getElementsByClassName ); // Support: IE<10 // Check if getElementById returns elements by name // The broken getElementById methods don't pick up programmatically-set names, // so use a roundabout getElementsByName test support.getById = assert(function( el ) { docElem.appendChild( el ).id = expando; return !document.getElementsByName || !document.getElementsByName( expando ).length; }); // ID filter and find if ( support.getById ) { Expr.filter["ID"] = function( id ) { var attrId = id.replace( runescape, funescape ); return function( elem ) { return elem.getAttribute("id") === attrId; }; }; Expr.find["ID"] = function( id, context ) { if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { var elem = context.getElementById( id ); return elem ? [ elem ] : []; } }; } else { Expr.filter["ID"] = function( id ) { var attrId = id.replace( runescape, funescape ); return function( elem ) { var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id"); return node && node.value === attrId; }; }; // Support: IE 6 - 7 only // getElementById is not reliable as a find shortcut Expr.find["ID"] = function( id, context ) { if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { var node, i, elems, elem = context.getElementById( id ); if ( elem ) { // Verify the id attribute node = elem.getAttributeNode("id"); if ( node && node.value === id ) { return [ elem ]; } // Fall back on getElementsByName elems = context.getElementsByName( id ); i = 0; while ( (elem = elems[i++]) ) { node = elem.getAttributeNode("id"); if ( node && node.value === id ) { return [ elem ]; } } } return []; } }; } // Tag Expr.find["TAG"] = support.getElementsByTagName ? function( tag, context ) { if ( typeof context.getElementsByTagName !== "undefined" ) { return context.getElementsByTagName( tag ); // DocumentFragment nodes don't have gEBTN } else if ( support.qsa ) { return context.querySelectorAll( tag ); } } : function( tag, context ) { var elem, tmp = [], i = 0, // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too results = context.getElementsByTagName( tag ); // Filter out possible comments if ( tag === "*" ) { while ( (elem = results[i++]) ) { if ( elem.nodeType === 1 ) { tmp.push( elem ); } } return tmp; } return results; }; // Class Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) { if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) { return context.getElementsByClassName( className ); } }; /* QSA/matchesSelector ---------------------------------------------------------------------- */ // QSA and matchesSelector support // matchesSelector(:active) reports false when true (IE9/Opera 11.5) rbuggyMatches = []; // qSa(:focus) reports false when true (Chrome 21) // We allow this because of a bug in IE8/9 that throws an error // whenever `document.activeElement` is accessed on an iframe // So, we allow :focus to pass through QSA all the time to avoid the IE error // See https://bugs.jquery.com/ticket/13378 rbuggyQSA = []; if ( (support.qsa = rnative.test( document.querySelectorAll )) ) { // Build QSA regex // Regex strategy adopted from Diego Perini assert(function( el ) { // Select is set to empty string on purpose // This is to test IE's treatment of not explicitly // setting a boolean content attribute, // since its presence should be enough // https://bugs.jquery.com/ticket/12359 docElem.appendChild( el ).innerHTML = "" + ""; // Support: IE8, Opera 11-12.16 // Nothing should be selected when empty strings follow ^= or $= or *= // The test attribute must be unknown in Opera but "safe" for WinRT // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section if ( el.querySelectorAll("[msallowcapture^='']").length ) { rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); } // Support: IE8 // Boolean attributes and "value" are not treated correctly if ( !el.querySelectorAll("[selected]").length ) { rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); } // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+ if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) { rbuggyQSA.push("~="); } // Webkit/Opera - :checked should return selected option elements // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked // IE8 throws error here and will not see later tests if ( !el.querySelectorAll(":checked").length ) { rbuggyQSA.push(":checked"); } // Support: Safari 8+, iOS 8+ // https://bugs.webkit.org/show_bug.cgi?id=136851 // In-page `selector#id sibling-combinator selector` fails if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) { rbuggyQSA.push(".#.+[+~]"); } }); assert(function( el ) { el.innerHTML = "" + ""; // Support: Windows 8 Native Apps // The type and name attributes are restricted during .innerHTML assignment var input = document.createElement("input"); input.setAttribute( "type", "hidden" ); el.appendChild( input ).setAttribute( "name", "D" ); // Support: IE8 // Enforce case-sensitivity of name attribute if ( el.querySelectorAll("[name=d]").length ) { rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); } // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) // IE8 throws error here and will not see later tests if ( el.querySelectorAll(":enabled").length !== 2 ) { rbuggyQSA.push( ":enabled", ":disabled" ); } // Support: IE9-11+ // IE's :disabled selector does not pick up the children of disabled fieldsets docElem.appendChild( el ).disabled = true; if ( el.querySelectorAll(":disabled").length !== 2 ) { rbuggyQSA.push( ":enabled", ":disabled" ); } // Opera 10-11 does not throw on post-comma invalid pseudos el.querySelectorAll("*,:x"); rbuggyQSA.push(",.*:"); }); } if ( (support.matchesSelector = rnative.test( (matches = docElem.matches || docElem.webkitMatchesSelector || docElem.mozMatchesSelector || docElem.oMatchesSelector || docElem.msMatchesSelector) )) ) { assert(function( el ) { // Check to see if it's possible to do matchesSelector // on a disconnected node (IE 9) support.disconnectedMatch = matches.call( el, "*" ); // This should fail with an exception // Gecko does not error, returns false instead matches.call( el, "[s!='']:x" ); rbuggyMatches.push( "!=", pseudos ); }); } rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") ); rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") ); /* Contains ---------------------------------------------------------------------- */ hasCompare = rnative.test( docElem.compareDocumentPosition ); // Element contains another // Purposefully self-exclusive // As in, an element does not contain itself contains = hasCompare || rnative.test( docElem.contains ) ? function( a, b ) { var adown = a.nodeType === 9 ? a.documentElement : a, bup = b && b.parentNode; return a === bup || !!( bup && bup.nodeType === 1 && ( adown.contains ? adown.contains( bup ) : a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 )); } : function( a, b ) { if ( b ) { while ( (b = b.parentNode) ) { if ( b === a ) { return true; } } } return false; }; /* Sorting ---------------------------------------------------------------------- */ // Document order sorting sortOrder = hasCompare ? function( a, b ) { // Flag for duplicate removal if ( a === b ) { hasDuplicate = true; return 0; } // Sort on method existence if only one input has compareDocumentPosition var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; if ( compare ) { return compare; } // Calculate position if both inputs belong to the same document compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ? a.compareDocumentPosition( b ) : // Otherwise we know they are disconnected 1; // Disconnected nodes if ( compare & 1 || (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) { // Choose the first element that is related to our preferred document if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) { return -1; } if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) { return 1; } // Maintain original order return sortInput ? ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : 0; } return compare & 4 ? -1 : 1; } : function( a, b ) { // Exit early if the nodes are identical if ( a === b ) { hasDuplicate = true; return 0; } var cur, i = 0, aup = a.parentNode, bup = b.parentNode, ap = [ a ], bp = [ b ]; // Parentless nodes are either documents or disconnected if ( !aup || !bup ) { return a === document ? -1 : b === document ? 1 : aup ? -1 : bup ? 1 : sortInput ? ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : 0; // If the nodes are siblings, we can do a quick check } else if ( aup === bup ) { return siblingCheck( a, b ); } // Otherwise we need full lists of their ancestors for comparison cur = a; while ( (cur = cur.parentNode) ) { ap.unshift( cur ); } cur = b; while ( (cur = cur.parentNode) ) { bp.unshift( cur ); } // Walk down the tree looking for a discrepancy while ( ap[i] === bp[i] ) { i++; } return i ? // Do a sibling check if the nodes have a common ancestor siblingCheck( ap[i], bp[i] ) : // Otherwise nodes in our document sort first ap[i] === preferredDoc ? -1 : bp[i] === preferredDoc ? 1 : 0; }; return document; }; Sizzle.matches = function( expr, elements ) { return Sizzle( expr, null, null, elements ); }; Sizzle.matchesSelector = function( elem, expr ) { // Set document vars if needed if ( ( elem.ownerDocument || elem ) !== document ) { setDocument( elem ); } // Make sure that attribute selectors are quoted expr = expr.replace( rattributeQuotes, "='$1']" ); if ( support.matchesSelector && documentIsHTML && !compilerCache[ expr + " " ] && ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { try { var ret = matches.call( elem, expr ); // IE 9's matchesSelector returns false on disconnected nodes if ( ret || support.disconnectedMatch || // As well, disconnected nodes are said to be in a document // fragment in IE 9 elem.document && elem.document.nodeType !== 11 ) { return ret; } } catch (e) {} } return Sizzle( expr, document, null, [ elem ] ).length > 0; }; Sizzle.contains = function( context, elem ) { // Set document vars if needed if ( ( context.ownerDocument || context ) !== document ) { setDocument( context ); } return contains( context, elem ); }; Sizzle.attr = function( elem, name ) { // Set document vars if needed if ( ( elem.ownerDocument || elem ) !== document ) { setDocument( elem ); } var fn = Expr.attrHandle[ name.toLowerCase() ], // Don't get fooled by Object.prototype properties (jQuery #13807) val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? fn( elem, name, !documentIsHTML ) : undefined; return val !== undefined ? val : support.attributes || !documentIsHTML ? elem.getAttribute( name ) : (val = elem.getAttributeNode(name)) && val.specified ? val.value : null; }; Sizzle.escape = function( sel ) { return (sel + "").replace( rcssescape, fcssescape ); }; Sizzle.error = function( msg ) { throw new Error( "Syntax error, unrecognized expression: " + msg ); }; /** * Document sorting and removing duplicates * @param {ArrayLike} results */ Sizzle.uniqueSort = function( results ) { var elem, duplicates = [], j = 0, i = 0; // Unless we *know* we can detect duplicates, assume their presence hasDuplicate = !support.detectDuplicates; sortInput = !support.sortStable && results.slice( 0 ); results.sort( sortOrder ); if ( hasDuplicate ) { while ( (elem = results[i++]) ) { if ( elem === results[ i ] ) { j = duplicates.push( i ); } } while ( j-- ) { results.splice( duplicates[ j ], 1 ); } } // Clear input after sorting to release objects // See https://github.com/jquery/sizzle/pull/225 sortInput = null; return results; }; /** * Utility function for retrieving the text value of an array of DOM nodes * @param {Array|Element} elem */ getText = Sizzle.getText = function( elem ) { var node, ret = "", i = 0, nodeType = elem.nodeType; if ( !nodeType ) { // If no nodeType, this is expected to be an array while ( (node = elem[i++]) ) { // Do not traverse comment nodes ret += getText( node ); } } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { // Use textContent for elements // innerText usage removed for consistency of new lines (jQuery #11153) if ( typeof elem.textContent === "string" ) { return elem.textContent; } else { // Traverse its children for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { ret += getText( elem ); } } } else if ( nodeType === 3 || nodeType === 4 ) { return elem.nodeValue; } // Do not include comment or processing instruction nodes return ret; }; Expr = Sizzle.selectors = { // Can be adjusted by the user cacheLength: 50, createPseudo: markFunction, match: matchExpr, attrHandle: {}, find: {}, relative: { ">": { dir: "parentNode", first: true }, " ": { dir: "parentNode" }, "+": { dir: "previousSibling", first: true }, "~": { dir: "previousSibling" } }, preFilter: { "ATTR": function( match ) { match[1] = match[1].replace( runescape, funescape ); // Move the given value to match[3] whether quoted or unquoted match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape ); if ( match[2] === "~=" ) { match[3] = " " + match[3] + " "; } return match.slice( 0, 4 ); }, "CHILD": function( match ) { /* matches from matchExpr["CHILD"] 1 type (only|nth|...) 2 what (child|of-type) 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) 4 xn-component of xn+y argument ([+-]?\d*n|) 5 sign of xn-component 6 x of xn-component 7 sign of y-component 8 y of y-component */ match[1] = match[1].toLowerCase(); if ( match[1].slice( 0, 3 ) === "nth" ) { // nth-* requires argument if ( !match[3] ) { Sizzle.error( match[0] ); } // numeric x and y parameters for Expr.filter.CHILD // remember that false/true cast respectively to 0/1 match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) ); match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" ); // other types prohibit arguments } else if ( match[3] ) { Sizzle.error( match[0] ); } return match; }, "PSEUDO": function( match ) { var excess, unquoted = !match[6] && match[2]; if ( matchExpr["CHILD"].test( match[0] ) ) { return null; } // Accept quoted arguments as-is if ( match[3] ) { match[2] = match[4] || match[5] || ""; // Strip excess characters from unquoted arguments } else if ( unquoted && rpseudo.test( unquoted ) && // Get excess from tokenize (recursively) (excess = tokenize( unquoted, true )) && // advance to the next closing parenthesis (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { // excess is a negative index match[0] = match[0].slice( 0, excess ); match[2] = unquoted.slice( 0, excess ); } // Return only captures needed by the pseudo filter method (type and argument) return match.slice( 0, 3 ); } }, filter: { "TAG": function( nodeNameSelector ) { var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); return nodeNameSelector === "*" ? function() { return true; } : function( elem ) { return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; }; }, "CLASS": function( className ) { var pattern = classCache[ className + " " ]; return pattern || (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && classCache( className, function( elem ) { return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" ); }); }, "ATTR": function( name, operator, check ) { return function( elem ) { var result = Sizzle.attr( elem, name ); if ( result == null ) { return operator === "!="; } if ( !operator ) { return true; } result += ""; return operator === "=" ? result === check : operator === "!=" ? result !== check : operator === "^=" ? check && result.indexOf( check ) === 0 : operator === "*=" ? check && result.indexOf( check ) > -1 : operator === "$=" ? check && result.slice( -check.length ) === check : operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 : operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : false; }; }, "CHILD": function( type, what, argument, first, last ) { var simple = type.slice( 0, 3 ) !== "nth", forward = type.slice( -4 ) !== "last", ofType = what === "of-type"; return first === 1 && last === 0 ? // Shortcut for :nth-*(n) function( elem ) { return !!elem.parentNode; } : function( elem, context, xml ) { var cache, uniqueCache, outerCache, node, nodeIndex, start, dir = simple !== forward ? "nextSibling" : "previousSibling", parent = elem.parentNode, name = ofType && elem.nodeName.toLowerCase(), useCache = !xml && !ofType, diff = false; if ( parent ) { // :(first|last|only)-(child|of-type) if ( simple ) { while ( dir ) { node = elem; while ( (node = node[ dir ]) ) { if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) { return false; } } // Reverse direction for :only-* (if we haven't yet done so) start = dir = type === "only" && !start && "nextSibling"; } return true; } start = [ forward ? parent.firstChild : parent.lastChild ]; // non-xml :nth-child(...) stores cache data on `parent` if ( forward && useCache ) { // Seek `elem` from a previously-cached index // ...in a gzip-friendly way node = parent; outerCache = node[ expando ] || (node[ expando ] = {}); // Support: IE <9 only // Defend against cloned attroperties (jQuery gh-1709) uniqueCache = outerCache[ node.uniqueID ] || (outerCache[ node.uniqueID ] = {}); cache = uniqueCache[ type ] || []; nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; diff = nodeIndex && cache[ 2 ]; node = nodeIndex && parent.childNodes[ nodeIndex ]; while ( (node = ++nodeIndex && node && node[ dir ] || // Fallback to seeking `elem` from the start (diff = nodeIndex = 0) || start.pop()) ) { // When found, cache indexes on `parent` and break if ( node.nodeType === 1 && ++diff && node === elem ) { uniqueCache[ type ] = [ dirruns, nodeIndex, diff ]; break; } } } else { // Use previously-cached element index if available if ( useCache ) { // ...in a gzip-friendly way node = elem; outerCache = node[ expando ] || (node[ expando ] = {}); // Support: IE <9 only // Defend against cloned attroperties (jQuery gh-1709) uniqueCache = outerCache[ node.uniqueID ] || (outerCache[ node.uniqueID ] = {}); cache = uniqueCache[ type ] || []; nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; diff = nodeIndex; } // xml :nth-child(...) // or :nth-last-child(...) or :nth(-last)?-of-type(...) if ( diff === false ) { // Use the same loop as above to seek `elem` from the start while ( (node = ++nodeIndex && node && node[ dir ] || (diff = nodeIndex = 0) || start.pop()) ) { if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) { // Cache the index of each encountered element if ( useCache ) { outerCache = node[ expando ] || (node[ expando ] = {}); // Support: IE <9 only // Defend against cloned attroperties (jQuery gh-1709) uniqueCache = outerCache[ node.uniqueID ] || (outerCache[ node.uniqueID ] = {}); uniqueCache[ type ] = [ dirruns, diff ]; } if ( node === elem ) { break; } } } } } // Incorporate the offset, then check against cycle size diff -= last; return diff === first || ( diff % first === 0 && diff / first >= 0 ); } }; }, "PSEUDO": function( pseudo, argument ) { // pseudo-class names are case-insensitive // http://www.w3.org/TR/selectors/#pseudo-classes // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters // Remember that setFilters inherits from pseudos var args, fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || Sizzle.error( "unsupported pseudo: " + pseudo ); // The user may use createPseudo to indicate that // arguments are needed to create the filter function // just as Sizzle does if ( fn[ expando ] ) { return fn( argument ); } // But maintain support for old signatures if ( fn.length > 1 ) { args = [ pseudo, pseudo, "", argument ]; return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? markFunction(function( seed, matches ) { var idx, matched = fn( seed, argument ), i = matched.length; while ( i-- ) { idx = indexOf( seed, matched[i] ); seed[ idx ] = !( matches[ idx ] = matched[i] ); } }) : function( elem ) { return fn( elem, 0, args ); }; } return fn; } }, pseudos: { // Potentially complex pseudos "not": markFunction(function( selector ) { // Trim the selector passed to compile // to avoid treating leading and trailing // spaces as combinators var input = [], results = [], matcher = compile( selector.replace( rtrim, "$1" ) ); return matcher[ expando ] ? markFunction(function( seed, matches, context, xml ) { var elem, unmatched = matcher( seed, null, xml, [] ), i = seed.length; // Match elements unmatched by `matcher` while ( i-- ) { if ( (elem = unmatched[i]) ) { seed[i] = !(matches[i] = elem); } } }) : function( elem, context, xml ) { input[0] = elem; matcher( input, null, xml, results ); // Don't keep the element (issue #299) input[0] = null; return !results.pop(); }; }), "has": markFunction(function( selector ) { return function( elem ) { return Sizzle( selector, elem ).length > 0; }; }), "contains": markFunction(function( text ) { text = text.replace( runescape, funescape ); return function( elem ) { return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; }; }), // "Whether an element is represented by a :lang() selector // is based solely on the element's language value // being equal to the identifier C, // or beginning with the identifier C immediately followed by "-". // The matching of C against the element's language value is performed case-insensitively. // The identifier C does not have to be a valid language name." // http://www.w3.org/TR/selectors/#lang-pseudo "lang": markFunction( function( lang ) { // lang value must be a valid identifier if ( !ridentifier.test(lang || "") ) { Sizzle.error( "unsupported lang: " + lang ); } lang = lang.replace( runescape, funescape ).toLowerCase(); return function( elem ) { var elemLang; do { if ( (elemLang = documentIsHTML ? elem.lang : elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) { elemLang = elemLang.toLowerCase(); return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; } } while ( (elem = elem.parentNode) && elem.nodeType === 1 ); return false; }; }), // Miscellaneous "target": function( elem ) { var hash = window.location && window.location.hash; return hash && hash.slice( 1 ) === elem.id; }, "root": function( elem ) { return elem === docElem; }, "focus": function( elem ) { return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); }, // Boolean properties "enabled": createDisabledPseudo( false ), "disabled": createDisabledPseudo( true ), "checked": function( elem ) { // In CSS3, :checked should return both checked and selected elements // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked var nodeName = elem.nodeName.toLowerCase(); return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); }, "selected": function( elem ) { // Accessing this property makes selected-by-default // options in Safari work properly if ( elem.parentNode ) { elem.parentNode.selectedIndex; } return elem.selected === true; }, // Contents "empty": function( elem ) { // http://www.w3.org/TR/selectors/#empty-pseudo // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), // but not by others (comment: 8; processing instruction: 7; etc.) // nodeType < 6 works because attributes (2) do not appear as children for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { if ( elem.nodeType < 6 ) { return false; } } return true; }, "parent": function( elem ) { return !Expr.pseudos["empty"]( elem ); }, // Element/input types "header": function( elem ) { return rheader.test( elem.nodeName ); }, "input": function( elem ) { return rinputs.test( elem.nodeName ); }, "button": function( elem ) { var name = elem.nodeName.toLowerCase(); return name === "input" && elem.type === "button" || name === "button"; }, "text": function( elem ) { var attr; return elem.nodeName.toLowerCase() === "input" && elem.type === "text" && // Support: IE<8 // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" ); }, // Position-in-collection "first": createPositionalPseudo(function() { return [ 0 ]; }), "last": createPositionalPseudo(function( matchIndexes, length ) { return [ length - 1 ]; }), "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { return [ argument < 0 ? argument + length : argument ]; }), "even": createPositionalPseudo(function( matchIndexes, length ) { var i = 0; for ( ; i < length; i += 2 ) { matchIndexes.push( i ); } return matchIndexes; }), "odd": createPositionalPseudo(function( matchIndexes, length ) { var i = 1; for ( ; i < length; i += 2 ) { matchIndexes.push( i ); } return matchIndexes; }), "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { var i = argument < 0 ? argument + length : argument; for ( ; --i >= 0; ) { matchIndexes.push( i ); } return matchIndexes; }), "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { var i = argument < 0 ? argument + length : argument; for ( ; ++i < length; ) { matchIndexes.push( i ); } return matchIndexes; }) } }; Expr.pseudos["nth"] = Expr.pseudos["eq"]; // Add button/input type pseudos for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { Expr.pseudos[ i ] = createInputPseudo( i ); } for ( i in { submit: true, reset: true } ) { Expr.pseudos[ i ] = createButtonPseudo( i ); } // Easy API for creating new setFilters function setFilters() {} setFilters.prototype = Expr.filters = Expr.pseudos; Expr.setFilters = new setFilters(); tokenize = Sizzle.tokenize = function( selector, parseOnly ) { var matched, match, tokens, type, soFar, groups, preFilters, cached = tokenCache[ selector + " " ]; if ( cached ) { return parseOnly ? 0 : cached.slice( 0 ); } soFar = selector; groups = []; preFilters = Expr.preFilter; while ( soFar ) { // Comma and first run if ( !matched || (match = rcomma.exec( soFar )) ) { if ( match ) { // Don't consume trailing commas as valid soFar = soFar.slice( match[0].length ) || soFar; } groups.push( (tokens = []) ); } matched = false; // Combinators if ( (match = rcombinators.exec( soFar )) ) { matched = match.shift(); tokens.push({ value: matched, // Cast descendant combinators to space type: match[0].replace( rtrim, " " ) }); soFar = soFar.slice( matched.length ); } // Filters for ( type in Expr.filter ) { if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || (match = preFilters[ type ]( match ))) ) { matched = match.shift(); tokens.push({ value: matched, type: type, matches: match }); soFar = soFar.slice( matched.length ); } } if ( !matched ) { break; } } // Return the length of the invalid excess // if we're just parsing // Otherwise, throw an error or return tokens return parseOnly ? soFar.length : soFar ? Sizzle.error( selector ) : // Cache the tokens tokenCache( selector, groups ).slice( 0 ); }; function toSelector( tokens ) { var i = 0, len = tokens.length, selector = ""; for ( ; i < len; i++ ) { selector += tokens[i].value; } return selector; } function addCombinator( matcher, combinator, base ) { var dir = combinator.dir, skip = combinator.next, key = skip || dir, checkNonElements = base && key === "parentNode", doneName = done++; return combinator.first ? // Check against closest ancestor/preceding element function( elem, context, xml ) { while ( (elem = elem[ dir ]) ) { if ( elem.nodeType === 1 || checkNonElements ) { return matcher( elem, context, xml ); } } return false; } : // Check against all ancestor/preceding elements function( elem, context, xml ) { var oldCache, uniqueCache, outerCache, newCache = [ dirruns, doneName ]; // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching if ( xml ) { while ( (elem = elem[ dir ]) ) { if ( elem.nodeType === 1 || checkNonElements ) { if ( matcher( elem, context, xml ) ) { return true; } } } } else { while ( (elem = elem[ dir ]) ) { if ( elem.nodeType === 1 || checkNonElements ) { outerCache = elem[ expando ] || (elem[ expando ] = {}); // Support: IE <9 only // Defend against cloned attroperties (jQuery gh-1709) uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {}); if ( skip && skip === elem.nodeName.toLowerCase() ) { elem = elem[ dir ] || elem; } else if ( (oldCache = uniqueCache[ key ]) && oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { // Assign to newCache so results back-propagate to previous elements return (newCache[ 2 ] = oldCache[ 2 ]); } else { // Reuse newcache so results back-propagate to previous elements uniqueCache[ key ] = newCache; // A match means we're done; a fail means we have to keep checking if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) { return true; } } } } } return false; }; } function elementMatcher( matchers ) { return matchers.length > 1 ? function( elem, context, xml ) { var i = matchers.length; while ( i-- ) { if ( !matchers[i]( elem, context, xml ) ) { return false; } } return true; } : matchers[0]; } function multipleContexts( selector, contexts, results ) { var i = 0, len = contexts.length; for ( ; i < len; i++ ) { Sizzle( selector, contexts[i], results ); } return results; } function condense( unmatched, map, filter, context, xml ) { var elem, newUnmatched = [], i = 0, len = unmatched.length, mapped = map != null; for ( ; i < len; i++ ) { if ( (elem = unmatched[i]) ) { if ( !filter || filter( elem, context, xml ) ) { newUnmatched.push( elem ); if ( mapped ) { map.push( i ); } } } } return newUnmatched; } function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { if ( postFilter && !postFilter[ expando ] ) { postFilter = setMatcher( postFilter ); } if ( postFinder && !postFinder[ expando ] ) { postFinder = setMatcher( postFinder, postSelector ); } return markFunction(function( seed, results, context, xml ) { var temp, i, elem, preMap = [], postMap = [], preexisting = results.length, // Get initial elements from seed or context elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), // Prefilter to get matcher input, preserving a map for seed-results synchronization matcherIn = preFilter && ( seed || !selector ) ? condense( elems, preMap, preFilter, context, xml ) : elems, matcherOut = matcher ? // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, postFinder || ( seed ? preFilter : preexisting || postFilter ) ? // ...intermediate processing is necessary [] : // ...otherwise use results directly results : matcherIn; // Find primary matches if ( matcher ) { matcher( matcherIn, matcherOut, context, xml ); } // Apply postFilter if ( postFilter ) { temp = condense( matcherOut, postMap ); postFilter( temp, [], context, xml ); // Un-match failing elements by moving them back to matcherIn i = temp.length; while ( i-- ) { if ( (elem = temp[i]) ) { matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); } } } if ( seed ) { if ( postFinder || preFilter ) { if ( postFinder ) { // Get the final matcherOut by condensing this intermediate into postFinder contexts temp = []; i = matcherOut.length; while ( i-- ) { if ( (elem = matcherOut[i]) ) { // Restore matcherIn since elem is not yet a final match temp.push( (matcherIn[i] = elem) ); } } postFinder( null, (matcherOut = []), temp, xml ); } // Move matched elements from seed to results to keep them synchronized i = matcherOut.length; while ( i-- ) { if ( (elem = matcherOut[i]) && (temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) { seed[temp] = !(results[temp] = elem); } } } // Add elements to results, through postFinder if defined } else { matcherOut = condense( matcherOut === results ? matcherOut.splice( preexisting, matcherOut.length ) : matcherOut ); if ( postFinder ) { postFinder( null, results, matcherOut, xml ); } else { push.apply( results, matcherOut ); } } }); } function matcherFromTokens( tokens ) { var checkContext, matcher, j, len = tokens.length, leadingRelative = Expr.relative[ tokens[0].type ], implicitRelative = leadingRelative || Expr.relative[" "], i = leadingRelative ? 1 : 0, // The foundational matcher ensures that elements are reachable from top-level context(s) matchContext = addCombinator( function( elem ) { return elem === checkContext; }, implicitRelative, true ), matchAnyContext = addCombinator( function( elem ) { return indexOf( checkContext, elem ) > -1; }, implicitRelative, true ), matchers = [ function( elem, context, xml ) { var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( (checkContext = context).nodeType ? matchContext( elem, context, xml ) : matchAnyContext( elem, context, xml ) ); // Avoid hanging onto element (issue #299) checkContext = null; return ret; } ]; for ( ; i < len; i++ ) { if ( (matcher = Expr.relative[ tokens[i].type ]) ) { matchers = [ addCombinator(elementMatcher( matchers ), matcher) ]; } else { matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); // Return special upon seeing a positional matcher if ( matcher[ expando ] ) { // Find the next relative operator (if any) for proper handling j = ++i; for ( ; j < len; j++ ) { if ( Expr.relative[ tokens[j].type ] ) { break; } } return setMatcher( i > 1 && elementMatcher( matchers ), i > 1 && toSelector( // If the preceding token was a descendant combinator, insert an implicit any-element `*` tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" }) ).replace( rtrim, "$1" ), matcher, i < j && matcherFromTokens( tokens.slice( i, j ) ), j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), j < len && toSelector( tokens ) ); } matchers.push( matcher ); } } return elementMatcher( matchers ); } function matcherFromGroupMatchers( elementMatchers, setMatchers ) { var bySet = setMatchers.length > 0, byElement = elementMatchers.length > 0, superMatcher = function( seed, context, xml, results, outermost ) { var elem, j, matcher, matchedCount = 0, i = "0", unmatched = seed && [], setMatched = [], contextBackup = outermostContext, // We must always have either seed elements or outermost context elems = seed || byElement && Expr.find["TAG"]( "*", outermost ), // Use integer dirruns iff this is the outermost matcher dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1), len = elems.length; if ( outermost ) { outermostContext = context === document || context || outermost; } // Add elements passing elementMatchers directly to results // Support: IE<9, Safari // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id for ( ; i !== len && (elem = elems[i]) != null; i++ ) { if ( byElement && elem ) { j = 0; if ( !context && elem.ownerDocument !== document ) { setDocument( elem ); xml = !documentIsHTML; } while ( (matcher = elementMatchers[j++]) ) { if ( matcher( elem, context || document, xml) ) { results.push( elem ); break; } } if ( outermost ) { dirruns = dirrunsUnique; } } // Track unmatched elements for set filters if ( bySet ) { // They will have gone through all possible matchers if ( (elem = !matcher && elem) ) { matchedCount--; } // Lengthen the array for every element, matched or not if ( seed ) { unmatched.push( elem ); } } } // `i` is now the count of elements visited above, and adding it to `matchedCount` // makes the latter nonnegative. matchedCount += i; // Apply set filters to unmatched elements // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount` // equals `i`), unless we didn't visit _any_ elements in the above loop because we have // no element matchers and no seed. // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that // case, which will result in a "00" `matchedCount` that differs from `i` but is also // numerically zero. if ( bySet && i !== matchedCount ) { j = 0; while ( (matcher = setMatchers[j++]) ) { matcher( unmatched, setMatched, context, xml ); } if ( seed ) { // Reintegrate element matches to eliminate the need for sorting if ( matchedCount > 0 ) { while ( i-- ) { if ( !(unmatched[i] || setMatched[i]) ) { setMatched[i] = pop.call( results ); } } } // Discard index placeholder values to get only actual matches setMatched = condense( setMatched ); } // Add matches to results push.apply( results, setMatched ); // Seedless set matches succeeding multiple successful matchers stipulate sorting if ( outermost && !seed && setMatched.length > 0 && ( matchedCount + setMatchers.length ) > 1 ) { Sizzle.uniqueSort( results ); } } // Override manipulation of globals by nested matchers if ( outermost ) { dirruns = dirrunsUnique; outermostContext = contextBackup; } return unmatched; }; return bySet ? markFunction( superMatcher ) : superMatcher; } compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { var i, setMatchers = [], elementMatchers = [], cached = compilerCache[ selector + " " ]; if ( !cached ) { // Generate a function of recursive functions that can be used to check each element if ( !match ) { match = tokenize( selector ); } i = match.length; while ( i-- ) { cached = matcherFromTokens( match[i] ); if ( cached[ expando ] ) { setMatchers.push( cached ); } else { elementMatchers.push( cached ); } } // Cache the compiled function cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); // Save selector and tokenization cached.selector = selector; } return cached; }; /** * A low-level selection function that works with Sizzle's compiled * selector functions * @param {String|Function} selector A selector or a pre-compiled * selector function built with Sizzle.compile * @param {Element} context * @param {Array} [results] * @param {Array} [seed] A set of elements to match against */ select = Sizzle.select = function( selector, context, results, seed ) { var i, tokens, token, type, find, compiled = typeof selector === "function" && selector, match = !seed && tokenize( (selector = compiled.selector || selector) ); results = results || []; // Try to minimize operations if there is only one selector in the list and no seed // (the latter of which guarantees us context) if ( match.length === 1 ) { // Reduce context if the leading compound selector is an ID tokens = match[0] = match[0].slice( 0 ); if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[1].type ] ) { context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0]; if ( !context ) { return results; // Precompiled matchers will still verify ancestry, so step up a level } else if ( compiled ) { context = context.parentNode; } selector = selector.slice( tokens.shift().value.length ); } // Fetch a seed set for right-to-left matching i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length; while ( i-- ) { token = tokens[i]; // Abort if we hit a combinator if ( Expr.relative[ (type = token.type) ] ) { break; } if ( (find = Expr.find[ type ]) ) { // Search, expanding context for leading sibling combinators if ( (seed = find( token.matches[0].replace( runescape, funescape ), rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context )) ) { // If seed is empty or no tokens remain, we can return early tokens.splice( i, 1 ); selector = seed.length && toSelector( tokens ); if ( !selector ) { push.apply( results, seed ); return results; } break; } } } } // Compile and execute a filtering function if one is not provided // Provide `match` to avoid retokenization if we modified the selector above ( compiled || compile( selector, match ) )( seed, context, !documentIsHTML, results, !context || rsibling.test( selector ) && testContext( context.parentNode ) || context ); return results; }; // One-time assignments // Sort stability support.sortStable = expando.split("").sort( sortOrder ).join("") === expando; // Support: Chrome 14-35+ // Always assume duplicates if they aren't passed to the comparison function support.detectDuplicates = !!hasDuplicate; // Initialize against the default document setDocument(); // Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) // Detached nodes confoundingly follow *each other* support.sortDetached = assert(function( el ) { // Should return 1, but returns 4 (following) return el.compareDocumentPosition( document.createElement("fieldset") ) & 1; }); // Support: IE<8 // Prevent attribute/property "interpolation" // https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx if ( !assert(function( el ) { el.innerHTML = ""; return el.firstChild.getAttribute("href") === "#" ; }) ) { addHandle( "type|href|height|width", function( elem, name, isXML ) { if ( !isXML ) { return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); } }); } // Support: IE<9 // Use defaultValue in place of getAttribute("value") if ( !support.attributes || !assert(function( el ) { el.innerHTML = ""; el.firstChild.setAttribute( "value", "" ); return el.firstChild.getAttribute( "value" ) === ""; }) ) { addHandle( "value", function( elem, name, isXML ) { if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { return elem.defaultValue; } }); } // Support: IE<9 // Use getAttributeNode to fetch booleans when getAttribute lies if ( !assert(function( el ) { return el.getAttribute("disabled") == null; }) ) { addHandle( booleans, function( elem, name, isXML ) { var val; if ( !isXML ) { return elem[ name ] === true ? name.toLowerCase() : (val = elem.getAttributeNode( name )) && val.specified ? val.value : null; } }); } return Sizzle; })( window ); jQuery.find = Sizzle; jQuery.expr = Sizzle.selectors; // Deprecated jQuery.expr[ ":" ] = jQuery.expr.pseudos; jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort; jQuery.text = Sizzle.getText; jQuery.isXMLDoc = Sizzle.isXML; jQuery.contains = Sizzle.contains; jQuery.escapeSelector = Sizzle.escape; var dir = function( elem, dir, until ) { var matched = [], truncate = until !== undefined; while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) { if ( elem.nodeType === 1 ) { if ( truncate && jQuery( elem ).is( until ) ) { break; } matched.push( elem ); } } return matched; }; var siblings = function( n, elem ) { var matched = []; for ( ; n; n = n.nextSibling ) { if ( n.nodeType === 1 && n !== elem ) { matched.push( n ); } } return matched; }; var rneedsContext = jQuery.expr.match.needsContext; function nodeName( elem, name ) { return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); }; var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i ); // Implement the identical functionality for filter and not function winnow( elements, qualifier, not ) { if ( isFunction( qualifier ) ) { return jQuery.grep( elements, function( elem, i ) { return !!qualifier.call( elem, i, elem ) !== not; } ); } // Single element if ( qualifier.nodeType ) { return jQuery.grep( elements, function( elem ) { return ( elem === qualifier ) !== not; } ); } // Arraylike of elements (jQuery, arguments, Array) if ( typeof qualifier !== "string" ) { return jQuery.grep( elements, function( elem ) { return ( indexOf.call( qualifier, elem ) > -1 ) !== not; } ); } // Filtered directly for both simple and complex selectors return jQuery.filter( qualifier, elements, not ); } jQuery.filter = function( expr, elems, not ) { var elem = elems[ 0 ]; if ( not ) { expr = ":not(" + expr + ")"; } if ( elems.length === 1 && elem.nodeType === 1 ) { return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : []; } return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { return elem.nodeType === 1; } ) ); }; jQuery.fn.extend( { find: function( selector ) { var i, ret, len = this.length, self = this; if ( typeof selector !== "string" ) { return this.pushStack( jQuery( selector ).filter( function() { for ( i = 0; i < len; i++ ) { if ( jQuery.contains( self[ i ], this ) ) { return true; } } } ) ); } ret = this.pushStack( [] ); for ( i = 0; i < len; i++ ) { jQuery.find( selector, self[ i ], ret ); } return len > 1 ? jQuery.uniqueSort( ret ) : ret; }, filter: function( selector ) { return this.pushStack( winnow( this, selector || [], false ) ); }, not: function( selector ) { return this.pushStack( winnow( this, selector || [], true ) ); }, is: function( selector ) { return !!winnow( this, // If this is a positional/relative selector, check membership in the returned set // so $("p:first").is("p:last") won't return true for a doc with two "p". typeof selector === "string" && rneedsContext.test( selector ) ? jQuery( selector ) : selector || [], false ).length; } } ); // Initialize a jQuery object // A central reference to the root jQuery(document) var rootjQuery, // A simple way to check for HTML strings // Prioritize #id over to avoid XSS via location.hash (#9521) // Strict HTML recognition (#11290: must start with <) // Shortcut simple #id case for speed rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/, init = jQuery.fn.init = function( selector, context, root ) { var match, elem; // HANDLE: $(""), $(null), $(undefined), $(false) if ( !selector ) { return this; } // Method init() accepts an alternate rootjQuery // so migrate can support jQuery.sub (gh-2101) root = root || rootjQuery; // Handle HTML strings if ( typeof selector === "string" ) { if ( selector[ 0 ] === "<" && selector[ selector.length - 1 ] === ">" && selector.length >= 3 ) { // Assume that strings that start and end with <> are HTML and skip the regex check match = [ null, selector, null ]; } else { match = rquickExpr.exec( selector ); } // Match html or make sure no context is specified for #id if ( match && ( match[ 1 ] || !context ) ) { // HANDLE: $(html) -> $(array) if ( match[ 1 ] ) { context = context instanceof jQuery ? context[ 0 ] : context; // Option to run scripts is true for back-compat // Intentionally let the error be thrown if parseHTML is not present jQuery.merge( this, jQuery.parseHTML( match[ 1 ], context && context.nodeType ? context.ownerDocument || context : document, true ) ); // HANDLE: $(html, props) if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) { for ( match in context ) { // Properties of context are called as methods if possible if ( isFunction( this[ match ] ) ) { this[ match ]( context[ match ] ); // ...and otherwise set as attributes } else { this.attr( match, context[ match ] ); } } } return this; // HANDLE: $(#id) } else { elem = document.getElementById( match[ 2 ] ); if ( elem ) { // Inject the element directly into the jQuery object this[ 0 ] = elem; this.length = 1; } return this; } // HANDLE: $(expr, $(...)) } else if ( !context || context.jquery ) { return ( context || root ).find( selector ); // HANDLE: $(expr, context) // (which is just equivalent to: $(context).find(expr) } else { return this.constructor( context ).find( selector ); } // HANDLE: $(DOMElement) } else if ( selector.nodeType ) { this[ 0 ] = selector; this.length = 1; return this; // HANDLE: $(function) // Shortcut for document ready } else if ( isFunction( selector ) ) { return root.ready !== undefined ? root.ready( selector ) : // Execute immediately if ready is not present selector( jQuery ); } return jQuery.makeArray( selector, this ); }; // Give the init function the jQuery prototype for later instantiation init.prototype = jQuery.fn; // Initialize central reference rootjQuery = jQuery( document ); var rparentsprev = /^(?:parents|prev(?:Until|All))/, // Methods guaranteed to produce a unique set when starting from a unique set guaranteedUnique = { children: true, contents: true, next: true, prev: true }; jQuery.fn.extend( { has: function( target ) { var targets = jQuery( target, this ), l = targets.length; return this.filter( function() { var i = 0; for ( ; i < l; i++ ) { if ( jQuery.contains( this, targets[ i ] ) ) { return true; } } } ); }, closest: function( selectors, context ) { var cur, i = 0, l = this.length, matched = [], targets = typeof selectors !== "string" && jQuery( selectors ); // Positional selectors never match, since there's no _selection_ context if ( !rneedsContext.test( selectors ) ) { for ( ; i < l; i++ ) { for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) { // Always skip document fragments if ( cur.nodeType < 11 && ( targets ? targets.index( cur ) > -1 : // Don't pass non-elements to Sizzle cur.nodeType === 1 && jQuery.find.matchesSelector( cur, selectors ) ) ) { matched.push( cur ); break; } } } } return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched ); }, // Determine the position of an element within the set index: function( elem ) { // No argument, return index in parent if ( !elem ) { return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; } // Index in selector if ( typeof elem === "string" ) { return indexOf.call( jQuery( elem ), this[ 0 ] ); } // Locate the position of the desired element return indexOf.call( this, // If it receives a jQuery object, the first element is used elem.jquery ? elem[ 0 ] : elem ); }, add: function( selector, context ) { return this.pushStack( jQuery.uniqueSort( jQuery.merge( this.get(), jQuery( selector, context ) ) ) ); }, addBack: function( selector ) { return this.add( selector == null ? this.prevObject : this.prevObject.filter( selector ) ); } } ); function sibling( cur, dir ) { while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {} return cur; } jQuery.each( { parent: function( elem ) { var parent = elem.parentNode; return parent && parent.nodeType !== 11 ? parent : null; }, parents: function( elem ) { return dir( elem, "parentNode" ); }, parentsUntil: function( elem, i, until ) { return dir( elem, "parentNode", until ); }, next: function( elem ) { return sibling( elem, "nextSibling" ); }, prev: function( elem ) { return sibling( elem, "previousSibling" ); }, nextAll: function( elem ) { return dir( elem, "nextSibling" ); }, prevAll: function( elem ) { return dir( elem, "previousSibling" ); }, nextUntil: function( elem, i, until ) { return dir( elem, "nextSibling", until ); }, prevUntil: function( elem, i, until ) { return dir( elem, "previousSibling", until ); }, siblings: function( elem ) { return siblings( ( elem.parentNode || {} ).firstChild, elem ); }, children: function( elem ) { return siblings( elem.firstChild ); }, contents: function( elem ) { if ( nodeName( elem, "iframe" ) ) { return elem.contentDocument; } // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only // Treat the template element as a regular one in browsers that // don't support it. if ( nodeName( elem, "template" ) ) { elem = elem.content || elem; } return jQuery.merge( [], elem.childNodes ); } }, function( name, fn ) { jQuery.fn[ name ] = function( until, selector ) { var matched = jQuery.map( this, fn, until ); if ( name.slice( -5 ) !== "Until" ) { selector = until; } if ( selector && typeof selector === "string" ) { matched = jQuery.filter( selector, matched ); } if ( this.length > 1 ) { // Remove duplicates if ( !guaranteedUnique[ name ] ) { jQuery.uniqueSort( matched ); } // Reverse order for parents* and prev-derivatives if ( rparentsprev.test( name ) ) { matched.reverse(); } } return this.pushStack( matched ); }; } ); var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g ); // Convert String-formatted options into Object-formatted ones function createOptions( options ) { var object = {}; jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) { object[ flag ] = true; } ); return object; } /* * Create a callback list using the following parameters: * * options: an optional list of space-separated options that will change how * the callback list behaves or a more traditional option object * * By default a callback list will act like an event callback list and can be * "fired" multiple times. * * Possible options: * * once: will ensure the callback list can only be fired once (like a Deferred) * * memory: will keep track of previous values and will call any callback added * after the list has been fired right away with the latest "memorized" * values (like a Deferred) * * unique: will ensure a callback can only be added once (no duplicate in the list) * * stopOnFalse: interrupt callings when a callback returns false * */ jQuery.Callbacks = function( options ) { // Convert options from String-formatted to Object-formatted if needed // (we check in cache first) options = typeof options === "string" ? createOptions( options ) : jQuery.extend( {}, options ); var // Flag to know if list is currently firing firing, // Last fire value for non-forgettable lists memory, // Flag to know if list was already fired fired, // Flag to prevent firing locked, // Actual callback list list = [], // Queue of execution data for repeatable lists queue = [], // Index of currently firing callback (modified by add/remove as needed) firingIndex = -1, // Fire callbacks fire = function() { // Enforce single-firing locked = locked || options.once; // Execute callbacks for all pending executions, // respecting firingIndex overrides and runtime changes fired = firing = true; for ( ; queue.length; firingIndex = -1 ) { memory = queue.shift(); while ( ++firingIndex < list.length ) { // Run callback and check for early termination if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false && options.stopOnFalse ) { // Jump to end and forget the data so .add doesn't re-fire firingIndex = list.length; memory = false; } } } // Forget the data if we're done with it if ( !options.memory ) { memory = false; } firing = false; // Clean up if we're done firing for good if ( locked ) { // Keep an empty list if we have data for future add calls if ( memory ) { list = []; // Otherwise, this object is spent } else { list = ""; } } }, // Actual Callbacks object self = { // Add a callback or a collection of callbacks to the list add: function() { if ( list ) { // If we have memory from a past run, we should fire after adding if ( memory && !firing ) { firingIndex = list.length - 1; queue.push( memory ); } ( function add( args ) { jQuery.each( args, function( _, arg ) { if ( isFunction( arg ) ) { if ( !options.unique || !self.has( arg ) ) { list.push( arg ); } } else if ( arg && arg.length && toType( arg ) !== "string" ) { // Inspect recursively add( arg ); } } ); } )( arguments ); if ( memory && !firing ) { fire(); } } return this; }, // Remove a callback from the list remove: function() { jQuery.each( arguments, function( _, arg ) { var index; while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { list.splice( index, 1 ); // Handle firing indexes if ( index <= firingIndex ) { firingIndex--; } } } ); return this; }, // Check if a given callback is in the list. // If no argument is given, return whether or not list has callbacks attached. has: function( fn ) { return fn ? jQuery.inArray( fn, list ) > -1 : list.length > 0; }, // Remove all callbacks from the list empty: function() { if ( list ) { list = []; } return this; }, // Disable .fire and .add // Abort any current/pending executions // Clear all callbacks and values disable: function() { locked = queue = []; list = memory = ""; return this; }, disabled: function() { return !list; }, // Disable .fire // Also disable .add unless we have memory (since it would have no effect) // Abort any pending executions lock: function() { locked = queue = []; if ( !memory && !firing ) { list = memory = ""; } return this; }, locked: function() { return !!locked; }, // Call all callbacks with the given context and arguments fireWith: function( context, args ) { if ( !locked ) { args = args || []; args = [ context, args.slice ? args.slice() : args ]; queue.push( args ); if ( !firing ) { fire(); } } return this; }, // Call all the callbacks with the given arguments fire: function() { self.fireWith( this, arguments ); return this; }, // To know if the callbacks have already been called at least once fired: function() { return !!fired; } }; return self; }; function Identity( v ) { return v; } function Thrower( ex ) { throw ex; } function adoptValue( value, resolve, reject, noValue ) { var method; try { // Check for promise aspect first to privilege synchronous behavior if ( value && isFunction( ( method = value.promise ) ) ) { method.call( value ).done( resolve ).fail( reject ); // Other thenables } else if ( value && isFunction( ( method = value.then ) ) ) { method.call( value, resolve, reject ); // Other non-thenables } else { // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer: // * false: [ value ].slice( 0 ) => resolve( value ) // * true: [ value ].slice( 1 ) => resolve() resolve.apply( undefined, [ value ].slice( noValue ) ); } // For Promises/A+, convert exceptions into rejections // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in // Deferred#then to conditionally suppress rejection. } catch ( value ) { // Support: Android 4.0 only // Strict mode functions invoked without .call/.apply get global-object context reject.apply( undefined, [ value ] ); } } jQuery.extend( { Deferred: function( func ) { var tuples = [ // action, add listener, callbacks, // ... .then handlers, argument index, [final state] [ "notify", "progress", jQuery.Callbacks( "memory" ), jQuery.Callbacks( "memory" ), 2 ], [ "resolve", "done", jQuery.Callbacks( "once memory" ), jQuery.Callbacks( "once memory" ), 0, "resolved" ], [ "reject", "fail", jQuery.Callbacks( "once memory" ), jQuery.Callbacks( "once memory" ), 1, "rejected" ] ], state = "pending", promise = { state: function() { return state; }, always: function() { deferred.done( arguments ).fail( arguments ); return this; }, "catch": function( fn ) { return promise.then( null, fn ); }, // Keep pipe for back-compat pipe: function( /* fnDone, fnFail, fnProgress */ ) { var fns = arguments; return jQuery.Deferred( function( newDefer ) { jQuery.each( tuples, function( i, tuple ) { // Map tuples (progress, done, fail) to arguments (done, fail, progress) var fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ]; // deferred.progress(function() { bind to newDefer or newDefer.notify }) // deferred.done(function() { bind to newDefer or newDefer.resolve }) // deferred.fail(function() { bind to newDefer or newDefer.reject }) deferred[ tuple[ 1 ] ]( function() { var returned = fn && fn.apply( this, arguments ); if ( returned && isFunction( returned.promise ) ) { returned.promise() .progress( newDefer.notify ) .done( newDefer.resolve ) .fail( newDefer.reject ); } else { newDefer[ tuple[ 0 ] + "With" ]( this, fn ? [ returned ] : arguments ); } } ); } ); fns = null; } ).promise(); }, then: function( onFulfilled, onRejected, onProgress ) { var maxDepth = 0; function resolve( depth, deferred, handler, special ) { return function() { var that = this, args = arguments, mightThrow = function() { var returned, then; // Support: Promises/A+ section 2.3.3.3.3 // https://promisesaplus.com/#point-59 // Ignore double-resolution attempts if ( depth < maxDepth ) { return; } returned = handler.apply( that, args ); // Support: Promises/A+ section 2.3.1 // https://promisesaplus.com/#point-48 if ( returned === deferred.promise() ) { throw new TypeError( "Thenable self-resolution" ); } // Support: Promises/A+ sections 2.3.3.1, 3.5 // https://promisesaplus.com/#point-54 // https://promisesaplus.com/#point-75 // Retrieve `then` only once then = returned && // Support: Promises/A+ section 2.3.4 // https://promisesaplus.com/#point-64 // Only check objects and functions for thenability ( typeof returned === "object" || typeof returned === "function" ) && returned.then; // Handle a returned thenable if ( isFunction( then ) ) { // Special processors (notify) just wait for resolution if ( special ) { then.call( returned, resolve( maxDepth, deferred, Identity, special ), resolve( maxDepth, deferred, Thrower, special ) ); // Normal processors (resolve) also hook into progress } else { // ...and disregard older resolution values maxDepth++; then.call( returned, resolve( maxDepth, deferred, Identity, special ), resolve( maxDepth, deferred, Thrower, special ), resolve( maxDepth, deferred, Identity, deferred.notifyWith ) ); } // Handle all other returned values } else { // Only substitute handlers pass on context // and multiple values (non-spec behavior) if ( handler !== Identity ) { that = undefined; args = [ returned ]; } // Process the value(s) // Default process is resolve ( special || deferred.resolveWith )( that, args ); } }, // Only normal processors (resolve) catch and reject exceptions process = special ? mightThrow : function() { try { mightThrow(); } catch ( e ) { if ( jQuery.Deferred.exceptionHook ) { jQuery.Deferred.exceptionHook( e, process.stackTrace ); } // Support: Promises/A+ section 2.3.3.3.4.1 // https://promisesaplus.com/#point-61 // Ignore post-resolution exceptions if ( depth + 1 >= maxDepth ) { // Only substitute handlers pass on context // and multiple values (non-spec behavior) if ( handler !== Thrower ) { that = undefined; args = [ e ]; } deferred.rejectWith( that, args ); } } }; // Support: Promises/A+ section 2.3.3.3.1 // https://promisesaplus.com/#point-57 // Re-resolve promises immediately to dodge false rejection from // subsequent errors if ( depth ) { process(); } else { // Call an optional hook to record the stack, in case of exception // since it's otherwise lost when execution goes async if ( jQuery.Deferred.getStackHook ) { process.stackTrace = jQuery.Deferred.getStackHook(); } window.setTimeout( process ); } }; } return jQuery.Deferred( function( newDefer ) { // progress_handlers.add( ... ) tuples[ 0 ][ 3 ].add( resolve( 0, newDefer, isFunction( onProgress ) ? onProgress : Identity, newDefer.notifyWith ) ); // fulfilled_handlers.add( ... ) tuples[ 1 ][ 3 ].add( resolve( 0, newDefer, isFunction( onFulfilled ) ? onFulfilled : Identity ) ); // rejected_handlers.add( ... ) tuples[ 2 ][ 3 ].add( resolve( 0, newDefer, isFunction( onRejected ) ? onRejected : Thrower ) ); } ).promise(); }, // Get a promise for this deferred // If obj is provided, the promise aspect is added to the object promise: function( obj ) { return obj != null ? jQuery.extend( obj, promise ) : promise; } }, deferred = {}; // Add list-specific methods jQuery.each( tuples, function( i, tuple ) { var list = tuple[ 2 ], stateString = tuple[ 5 ]; // promise.progress = list.add // promise.done = list.add // promise.fail = list.add promise[ tuple[ 1 ] ] = list.add; // Handle state if ( stateString ) { list.add( function() { // state = "resolved" (i.e., fulfilled) // state = "rejected" state = stateString; }, // rejected_callbacks.disable // fulfilled_callbacks.disable tuples[ 3 - i ][ 2 ].disable, // rejected_handlers.disable // fulfilled_handlers.disable tuples[ 3 - i ][ 3 ].disable, // progress_callbacks.lock tuples[ 0 ][ 2 ].lock, // progress_handlers.lock tuples[ 0 ][ 3 ].lock ); } // progress_handlers.fire // fulfilled_handlers.fire // rejected_handlers.fire list.add( tuple[ 3 ].fire ); // deferred.notify = function() { deferred.notifyWith(...) } // deferred.resolve = function() { deferred.resolveWith(...) } // deferred.reject = function() { deferred.rejectWith(...) } deferred[ tuple[ 0 ] ] = function() { deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments ); return this; }; // deferred.notifyWith = list.fireWith // deferred.resolveWith = list.fireWith // deferred.rejectWith = list.fireWith deferred[ tuple[ 0 ] + "With" ] = list.fireWith; } ); // Make the deferred a promise promise.promise( deferred ); // Call given func if any if ( func ) { func.call( deferred, deferred ); } // All done! return deferred; }, // Deferred helper when: function( singleValue ) { var // count of uncompleted subordinates remaining = arguments.length, // count of unprocessed arguments i = remaining, // subordinate fulfillment data resolveContexts = Array( i ), resolveValues = slice.call( arguments ), // the master Deferred master = jQuery.Deferred(), // subordinate callback factory updateFunc = function( i ) { return function( value ) { resolveContexts[ i ] = this; resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; if ( !( --remaining ) ) { master.resolveWith( resolveContexts, resolveValues ); } }; }; // Single- and empty arguments are adopted like Promise.resolve if ( remaining <= 1 ) { adoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject, !remaining ); // Use .then() to unwrap secondary thenables (cf. gh-3000) if ( master.state() === "pending" || isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) { return master.then(); } } // Multiple arguments are aggregated like Promise.all array elements while ( i-- ) { adoptValue( resolveValues[ i ], updateFunc( i ), master.reject ); } return master.promise(); } } ); // These usually indicate a programmer mistake during development, // warn about them ASAP rather than swallowing them by default. var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/; jQuery.Deferred.exceptionHook = function( error, stack ) { // Support: IE 8 - 9 only // Console exists when dev tools are open, which can happen at any time if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) { window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack ); } }; jQuery.readyException = function( error ) { window.setTimeout( function() { throw error; } ); }; // The deferred used on DOM ready var readyList = jQuery.Deferred(); jQuery.fn.ready = function( fn ) { readyList .then( fn ) // Wrap jQuery.readyException in a function so that the lookup // happens at the time of error handling instead of callback // registration. .catch( function( error ) { jQuery.readyException( error ); } ); return this; }; jQuery.extend( { // Is the DOM ready to be used? Set to true once it occurs. isReady: false, // A counter to track how many items to wait for before // the ready event fires. See #6781 readyWait: 1, // Handle when the DOM is ready ready: function( wait ) { // Abort if there are pending holds or we're already ready if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { return; } // Remember that the DOM is ready jQuery.isReady = true; // If a normal DOM Ready event fired, decrement, and wait if need be if ( wait !== true && --jQuery.readyWait > 0 ) { return; } // If there are functions bound, to execute readyList.resolveWith( document, [ jQuery ] ); } } ); jQuery.ready.then = readyList.then; // The ready event handler and self cleanup method function completed() { document.removeEventListener( "DOMContentLoaded", completed ); window.removeEventListener( "load", completed ); jQuery.ready(); } // Catch cases where $(document).ready() is called // after the browser event has already occurred. // Support: IE <=9 - 10 only // Older IE sometimes signals "interactive" too soon if ( document.readyState === "complete" || ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) { // Handle it asynchronously to allow scripts the opportunity to delay ready window.setTimeout( jQuery.ready ); } else { // Use the handy event callback document.addEventListener( "DOMContentLoaded", completed ); // A fallback to window.onload, that will always work window.addEventListener( "load", completed ); } // Multifunctional method to get and set values of a collection // The value/s can optionally be executed if it's a function var access = function( elems, fn, key, value, chainable, emptyGet, raw ) { var i = 0, len = elems.length, bulk = key == null; // Sets many values if ( toType( key ) === "object" ) { chainable = true; for ( i in key ) { access( elems, fn, i, key[ i ], true, emptyGet, raw ); } // Sets one value } else if ( value !== undefined ) { chainable = true; if ( !isFunction( value ) ) { raw = true; } if ( bulk ) { // Bulk operations run against the entire set if ( raw ) { fn.call( elems, value ); fn = null; // ...except when executing function values } else { bulk = fn; fn = function( elem, key, value ) { return bulk.call( jQuery( elem ), value ); }; } } if ( fn ) { for ( ; i < len; i++ ) { fn( elems[ i ], key, raw ? value : value.call( elems[ i ], i, fn( elems[ i ], key ) ) ); } } } if ( chainable ) { return elems; } // Gets if ( bulk ) { return fn.call( elems ); } return len ? fn( elems[ 0 ], key ) : emptyGet; }; // Matches dashed string for camelizing var rmsPrefix = /^-ms-/, rdashAlpha = /-([a-z])/g; // Used by camelCase as callback to replace() function fcamelCase( all, letter ) { return letter.toUpperCase(); } // Convert dashed to camelCase; used by the css and data modules // Support: IE <=9 - 11, Edge 12 - 15 // Microsoft forgot to hump their vendor prefix (#9572) function camelCase( string ) { return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); } var acceptData = function( owner ) { // Accepts only: // - Node // - Node.ELEMENT_NODE // - Node.DOCUMENT_NODE // - Object // - Any return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType ); }; function Data() { this.expando = jQuery.expando + Data.uid++; } Data.uid = 1; Data.prototype = { cache: function( owner ) { // Check if the owner object already has a cache var value = owner[ this.expando ]; // If not, create one if ( !value ) { value = {}; // We can accept data for non-element nodes in modern browsers, // but we should not, see #8335. // Always return an empty object. if ( acceptData( owner ) ) { // If it is a node unlikely to be stringify-ed or looped over // use plain assignment if ( owner.nodeType ) { owner[ this.expando ] = value; // Otherwise secure it in a non-enumerable property // configurable must be true to allow the property to be // deleted when data is removed } else { Object.defineProperty( owner, this.expando, { value: value, configurable: true } ); } } } return value; }, set: function( owner, data, value ) { var prop, cache = this.cache( owner ); // Handle: [ owner, key, value ] args // Always use camelCase key (gh-2257) if ( typeof data === "string" ) { cache[ camelCase( data ) ] = value; // Handle: [ owner, { properties } ] args } else { // Copy the properties one-by-one to the cache object for ( prop in data ) { cache[ camelCase( prop ) ] = data[ prop ]; } } return cache; }, get: function( owner, key ) { return key === undefined ? this.cache( owner ) : // Always use camelCase key (gh-2257) owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ]; }, access: function( owner, key, value ) { // In cases where either: // // 1. No key was specified // 2. A string key was specified, but no value provided // // Take the "read" path and allow the get method to determine // which value to return, respectively either: // // 1. The entire cache object // 2. The data stored at the key // if ( key === undefined || ( ( key && typeof key === "string" ) && value === undefined ) ) { return this.get( owner, key ); } // When the key is not a string, or both a key and value // are specified, set or extend (existing objects) with either: // // 1. An object of properties // 2. A key and value // this.set( owner, key, value ); // Since the "set" path can have two possible entry points // return the expected data based on which path was taken[*] return value !== undefined ? value : key; }, remove: function( owner, key ) { var i, cache = owner[ this.expando ]; if ( cache === undefined ) { return; } if ( key !== undefined ) { // Support array or space separated string of keys if ( Array.isArray( key ) ) { // If key is an array of keys... // We always set camelCase keys, so remove that. key = key.map( camelCase ); } else { key = camelCase( key ); // If a key with the spaces exists, use it. // Otherwise, create an array by matching non-whitespace key = key in cache ? [ key ] : ( key.match( rnothtmlwhite ) || [] ); } i = key.length; while ( i-- ) { delete cache[ key[ i ] ]; } } // Remove the expando if there's no more data if ( key === undefined || jQuery.isEmptyObject( cache ) ) { // Support: Chrome <=35 - 45 // Webkit & Blink performance suffers when deleting properties // from DOM nodes, so set to undefined instead // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted) if ( owner.nodeType ) { owner[ this.expando ] = undefined; } else { delete owner[ this.expando ]; } } }, hasData: function( owner ) { var cache = owner[ this.expando ]; return cache !== undefined && !jQuery.isEmptyObject( cache ); } }; var dataPriv = new Data(); var dataUser = new Data(); // Implementation Summary // // 1. Enforce API surface and semantic compatibility with 1.9.x branch // 2. Improve the module's maintainability by reducing the storage // paths to a single mechanism. // 3. Use the same single mechanism to support "private" and "user" data. // 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) // 5. Avoid exposing implementation details on user objects (eg. expando properties) // 6. Provide a clear path for implementation upgrade to WeakMap in 2014 var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, rmultiDash = /[A-Z]/g; function getData( data ) { if ( data === "true" ) { return true; } if ( data === "false" ) { return false; } if ( data === "null" ) { return null; } // Only convert to a number if it doesn't change the string if ( data === +data + "" ) { return +data; } if ( rbrace.test( data ) ) { return JSON.parse( data ); } return data; } function dataAttr( elem, key, data ) { var name; // If nothing was found internally, try to fetch any // data from the HTML5 data-* attribute if ( data === undefined && elem.nodeType === 1 ) { name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase(); data = elem.getAttribute( name ); if ( typeof data === "string" ) { try { data = getData( data ); } catch ( e ) {} // Make sure we set the data so it isn't changed later dataUser.set( elem, key, data ); } else { data = undefined; } } return data; } jQuery.extend( { hasData: function( elem ) { return dataUser.hasData( elem ) || dataPriv.hasData( elem ); }, data: function( elem, name, data ) { return dataUser.access( elem, name, data ); }, removeData: function( elem, name ) { dataUser.remove( elem, name ); }, // TODO: Now that all calls to _data and _removeData have been replaced // with direct calls to dataPriv methods, these can be deprecated. _data: function( elem, name, data ) { return dataPriv.access( elem, name, data ); }, _removeData: function( elem, name ) { dataPriv.remove( elem, name ); } } ); jQuery.fn.extend( { data: function( key, value ) { var i, name, data, elem = this[ 0 ], attrs = elem && elem.attributes; // Gets all values if ( key === undefined ) { if ( this.length ) { data = dataUser.get( elem ); if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) { i = attrs.length; while ( i-- ) { // Support: IE 11 only // The attrs elements can be null (#14894) if ( attrs[ i ] ) { name = attrs[ i ].name; if ( name.indexOf( "data-" ) === 0 ) { name = camelCase( name.slice( 5 ) ); dataAttr( elem, name, data[ name ] ); } } } dataPriv.set( elem, "hasDataAttrs", true ); } } return data; } // Sets multiple values if ( typeof key === "object" ) { return this.each( function() { dataUser.set( this, key ); } ); } return access( this, function( value ) { var data; // The calling jQuery object (element matches) is not empty // (and therefore has an element appears at this[ 0 ]) and the // `value` parameter was not undefined. An empty jQuery object // will result in `undefined` for elem = this[ 0 ] which will // throw an exception if an attempt to read a data cache is made. if ( elem && value === undefined ) { // Attempt to get data from the cache // The key will always be camelCased in Data data = dataUser.get( elem, key ); if ( data !== undefined ) { return data; } // Attempt to "discover" the data in // HTML5 custom data-* attrs data = dataAttr( elem, key ); if ( data !== undefined ) { return data; } // We tried really hard, but the data doesn't exist. return; } // Set the data... this.each( function() { // We always store the camelCased key dataUser.set( this, key, value ); } ); }, null, value, arguments.length > 1, null, true ); }, removeData: function( key ) { return this.each( function() { dataUser.remove( this, key ); } ); } } ); jQuery.extend( { queue: function( elem, type, data ) { var queue; if ( elem ) { type = ( type || "fx" ) + "queue"; queue = dataPriv.get( elem, type ); // Speed up dequeue by getting out quickly if this is just a lookup if ( data ) { if ( !queue || Array.isArray( data ) ) { queue = dataPriv.access( elem, type, jQuery.makeArray( data ) ); } else { queue.push( data ); } } return queue || []; } }, dequeue: function( elem, type ) { type = type || "fx"; var queue = jQuery.queue( elem, type ), startLength = queue.length, fn = queue.shift(), hooks = jQuery._queueHooks( elem, type ), next = function() { jQuery.dequeue( elem, type ); }; // If the fx queue is dequeued, always remove the progress sentinel if ( fn === "inprogress" ) { fn = queue.shift(); startLength--; } if ( fn ) { // Add a progress sentinel to prevent the fx queue from being // automatically dequeued if ( type === "fx" ) { queue.unshift( "inprogress" ); } // Clear up the last queue stop function delete hooks.stop; fn.call( elem, next, hooks ); } if ( !startLength && hooks ) { hooks.empty.fire(); } }, // Not public - generate a queueHooks object, or return the current one _queueHooks: function( elem, type ) { var key = type + "queueHooks"; return dataPriv.get( elem, key ) || dataPriv.access( elem, key, { empty: jQuery.Callbacks( "once memory" ).add( function() { dataPriv.remove( elem, [ type + "queue", key ] ); } ) } ); } } ); jQuery.fn.extend( { queue: function( type, data ) { var setter = 2; if ( typeof type !== "string" ) { data = type; type = "fx"; setter--; } if ( arguments.length < setter ) { return jQuery.queue( this[ 0 ], type ); } return data === undefined ? this : this.each( function() { var queue = jQuery.queue( this, type, data ); // Ensure a hooks for this queue jQuery._queueHooks( this, type ); if ( type === "fx" && queue[ 0 ] !== "inprogress" ) { jQuery.dequeue( this, type ); } } ); }, dequeue: function( type ) { return this.each( function() { jQuery.dequeue( this, type ); } ); }, clearQueue: function( type ) { return this.queue( type || "fx", [] ); }, // Get a promise resolved when queues of a certain type // are emptied (fx is the type by default) promise: function( type, obj ) { var tmp, count = 1, defer = jQuery.Deferred(), elements = this, i = this.length, resolve = function() { if ( !( --count ) ) { defer.resolveWith( elements, [ elements ] ); } }; if ( typeof type !== "string" ) { obj = type; type = undefined; } type = type || "fx"; while ( i-- ) { tmp = dataPriv.get( elements[ i ], type + "queueHooks" ); if ( tmp && tmp.empty ) { count++; tmp.empty.add( resolve ); } } resolve(); return defer.promise( obj ); } } ); var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source; var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ); var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; var isHiddenWithinTree = function( elem, el ) { // isHiddenWithinTree might be called from jQuery#filter function; // in that case, element will be second argument elem = el || elem; // Inline style trumps all return elem.style.display === "none" || elem.style.display === "" && // Otherwise, check computed style // Support: Firefox <=43 - 45 // Disconnected elements can have computed display: none, so first confirm that elem is // in the document. jQuery.contains( elem.ownerDocument, elem ) && jQuery.css( elem, "display" ) === "none"; }; var swap = function( elem, options, callback, args ) { var ret, name, old = {}; // Remember the old values, and insert the new ones for ( name in options ) { old[ name ] = elem.style[ name ]; elem.style[ name ] = options[ name ]; } ret = callback.apply( elem, args || [] ); // Revert the old values for ( name in options ) { elem.style[ name ] = old[ name ]; } return ret; }; function adjustCSS( elem, prop, valueParts, tween ) { var adjusted, scale, maxIterations = 20, currentValue = tween ? function() { return tween.cur(); } : function() { return jQuery.css( elem, prop, "" ); }, initial = currentValue(), unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ), // Starting value computation is required for potential unit mismatches initialInUnit = ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) && rcssNum.exec( jQuery.css( elem, prop ) ); if ( initialInUnit && initialInUnit[ 3 ] !== unit ) { // Support: Firefox <=54 // Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144) initial = initial / 2; // Trust units reported by jQuery.css unit = unit || initialInUnit[ 3 ]; // Iteratively approximate from a nonzero starting point initialInUnit = +initial || 1; while ( maxIterations-- ) { // Evaluate and update our best guess (doubling guesses that zero out). // Finish if the scale equals or crosses 1 (making the old*new product non-positive). jQuery.style( elem, prop, initialInUnit + unit ); if ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) { maxIterations = 0; } initialInUnit = initialInUnit / scale; } initialInUnit = initialInUnit * 2; jQuery.style( elem, prop, initialInUnit + unit ); // Make sure we update the tween properties later on valueParts = valueParts || []; } if ( valueParts ) { initialInUnit = +initialInUnit || +initial || 0; // Apply relative offset (+=/-=) if specified adjusted = valueParts[ 1 ] ? initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] : +valueParts[ 2 ]; if ( tween ) { tween.unit = unit; tween.start = initialInUnit; tween.end = adjusted; } } return adjusted; } var defaultDisplayMap = {}; function getDefaultDisplay( elem ) { var temp, doc = elem.ownerDocument, nodeName = elem.nodeName, display = defaultDisplayMap[ nodeName ]; if ( display ) { return display; } temp = doc.body.appendChild( doc.createElement( nodeName ) ); display = jQuery.css( temp, "display" ); temp.parentNode.removeChild( temp ); if ( display === "none" ) { display = "block"; } defaultDisplayMap[ nodeName ] = display; return display; } function showHide( elements, show ) { var display, elem, values = [], index = 0, length = elements.length; // Determine new display value for elements that need to change for ( ; index < length; index++ ) { elem = elements[ index ]; if ( !elem.style ) { continue; } display = elem.style.display; if ( show ) { // Since we force visibility upon cascade-hidden elements, an immediate (and slow) // check is required in this first loop unless we have a nonempty display value (either // inline or about-to-be-restored) if ( display === "none" ) { values[ index ] = dataPriv.get( elem, "display" ) || null; if ( !values[ index ] ) { elem.style.display = ""; } } if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) { values[ index ] = getDefaultDisplay( elem ); } } else { if ( display !== "none" ) { values[ index ] = "none"; // Remember what we're overwriting dataPriv.set( elem, "display", display ); } } } // Set the display of the elements in a second loop to avoid constant reflow for ( index = 0; index < length; index++ ) { if ( values[ index ] != null ) { elements[ index ].style.display = values[ index ]; } } return elements; } jQuery.fn.extend( { show: function() { return showHide( this, true ); }, hide: function() { return showHide( this ); }, toggle: function( state ) { if ( typeof state === "boolean" ) { return state ? this.show() : this.hide(); } return this.each( function() { if ( isHiddenWithinTree( this ) ) { jQuery( this ).show(); } else { jQuery( this ).hide(); } } ); } } ); var rcheckableType = ( /^(?:checkbox|radio)$/i ); var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]+)/i ); var rscriptType = ( /^$|^module$|\/(?:java|ecma)script/i ); // We have to close these tags to support XHTML (#13200) var wrapMap = { // Support: IE <=9 only option: [ 1, "" ], // XHTML parsers do not magically insert elements in the // same way that tag soup parsers do. So we cannot shorten // this by omitting or other required elements. thead: [ 1, "", "
" ], col: [ 2, "", "
" ], tr: [ 2, "", "
" ], td: [ 3, "", "
" ], _default: [ 0, "", "" ] }; // Support: IE <=9 only wrapMap.optgroup = wrapMap.option; wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; wrapMap.th = wrapMap.td; function getAll( context, tag ) { // Support: IE <=9 - 11 only // Use typeof to avoid zero-argument method invocation on host objects (#15151) var ret; if ( typeof context.getElementsByTagName !== "undefined" ) { ret = context.getElementsByTagName( tag || "*" ); } else if ( typeof context.querySelectorAll !== "undefined" ) { ret = context.querySelectorAll( tag || "*" ); } else { ret = []; } if ( tag === undefined || tag && nodeName( context, tag ) ) { return jQuery.merge( [ context ], ret ); } return ret; } // Mark scripts as having already been evaluated function setGlobalEval( elems, refElements ) { var i = 0, l = elems.length; for ( ; i < l; i++ ) { dataPriv.set( elems[ i ], "globalEval", !refElements || dataPriv.get( refElements[ i ], "globalEval" ) ); } } var rhtml = /<|&#?\w+;/; function buildFragment( elems, context, scripts, selection, ignored ) { var elem, tmp, tag, wrap, contains, j, fragment = context.createDocumentFragment(), nodes = [], i = 0, l = elems.length; for ( ; i < l; i++ ) { elem = elems[ i ]; if ( elem || elem === 0 ) { // Add nodes directly if ( toType( elem ) === "object" ) { // Support: Android <=4.0 only, PhantomJS 1 only // push.apply(_, arraylike) throws on ancient WebKit jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); // Convert non-html into a text node } else if ( !rhtml.test( elem ) ) { nodes.push( context.createTextNode( elem ) ); // Convert html into DOM nodes } else { tmp = tmp || fragment.appendChild( context.createElement( "div" ) ); // Deserialize a standard representation tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); wrap = wrapMap[ tag ] || wrapMap._default; tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ]; // Descend through wrappers to the right content j = wrap[ 0 ]; while ( j-- ) { tmp = tmp.lastChild; } // Support: Android <=4.0 only, PhantomJS 1 only // push.apply(_, arraylike) throws on ancient WebKit jQuery.merge( nodes, tmp.childNodes ); // Remember the top-level container tmp = fragment.firstChild; // Ensure the created nodes are orphaned (#12392) tmp.textContent = ""; } } } // Remove wrapper from fragment fragment.textContent = ""; i = 0; while ( ( elem = nodes[ i++ ] ) ) { // Skip elements already in the context collection (trac-4087) if ( selection && jQuery.inArray( elem, selection ) > -1 ) { if ( ignored ) { ignored.push( elem ); } continue; } contains = jQuery.contains( elem.ownerDocument, elem ); // Append to fragment tmp = getAll( fragment.appendChild( elem ), "script" ); // Preserve script evaluation history if ( contains ) { setGlobalEval( tmp ); } // Capture executables if ( scripts ) { j = 0; while ( ( elem = tmp[ j++ ] ) ) { if ( rscriptType.test( elem.type || "" ) ) { scripts.push( elem ); } } } } return fragment; } ( function() { var fragment = document.createDocumentFragment(), div = fragment.appendChild( document.createElement( "div" ) ), input = document.createElement( "input" ); // Support: Android 4.0 - 4.3 only // Check state lost if the name is set (#11217) // Support: Windows Web Apps (WWA) // `name` and `type` must use .setAttribute for WWA (#14901) input.setAttribute( "type", "radio" ); input.setAttribute( "checked", "checked" ); input.setAttribute( "name", "t" ); div.appendChild( input ); // Support: Android <=4.1 only // Older WebKit doesn't clone checked state correctly in fragments support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; // Support: IE <=11 only // Make sure textarea (and checkbox) defaultValue is properly cloned div.innerHTML = ""; support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; } )(); var documentElement = document.documentElement; var rkeyEvent = /^key/, rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/, rtypenamespace = /^([^.]*)(?:\.(.+)|)/; function returnTrue() { return true; } function returnFalse() { return false; } // Support: IE <=9 only // See #13393 for more info function safeActiveElement() { try { return document.activeElement; } catch ( err ) { } } function on( elem, types, selector, data, fn, one ) { var origFn, type; // Types can be a map of types/handlers if ( typeof types === "object" ) { // ( types-Object, selector, data ) if ( typeof selector !== "string" ) { // ( types-Object, data ) data = data || selector; selector = undefined; } for ( type in types ) { on( elem, type, selector, data, types[ type ], one ); } return elem; } if ( data == null && fn == null ) { // ( types, fn ) fn = selector; data = selector = undefined; } else if ( fn == null ) { if ( typeof selector === "string" ) { // ( types, selector, fn ) fn = data; data = undefined; } else { // ( types, data, fn ) fn = data; data = selector; selector = undefined; } } if ( fn === false ) { fn = returnFalse; } else if ( !fn ) { return elem; } if ( one === 1 ) { origFn = fn; fn = function( event ) { // Can use an empty set, since event contains the info jQuery().off( event ); return origFn.apply( this, arguments ); }; // Use same guid so caller can remove using origFn fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); } return elem.each( function() { jQuery.event.add( this, types, fn, data, selector ); } ); } /* * Helper functions for managing events -- not part of the public interface. * Props to Dean Edwards' addEvent library for many of the ideas. */ jQuery.event = { global: {}, add: function( elem, types, handler, data, selector ) { var handleObjIn, eventHandle, tmp, events, t, handleObj, special, handlers, type, namespaces, origType, elemData = dataPriv.get( elem ); // Don't attach events to noData or text/comment nodes (but allow plain objects) if ( !elemData ) { return; } // Caller can pass in an object of custom data in lieu of the handler if ( handler.handler ) { handleObjIn = handler; handler = handleObjIn.handler; selector = handleObjIn.selector; } // Ensure that invalid selectors throw exceptions at attach time // Evaluate against documentElement in case elem is a non-element node (e.g., document) if ( selector ) { jQuery.find.matchesSelector( documentElement, selector ); } // Make sure that the handler has a unique ID, used to find/remove it later if ( !handler.guid ) { handler.guid = jQuery.guid++; } // Init the element's event structure and main handler, if this is the first if ( !( events = elemData.events ) ) { events = elemData.events = {}; } if ( !( eventHandle = elemData.handle ) ) { eventHandle = elemData.handle = function( e ) { // Discard the second event of a jQuery.event.trigger() and // when an event is called after a page has unloaded return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? jQuery.event.dispatch.apply( elem, arguments ) : undefined; }; } // Handle multiple events separated by a space types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; t = types.length; while ( t-- ) { tmp = rtypenamespace.exec( types[ t ] ) || []; type = origType = tmp[ 1 ]; namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); // There *must* be a type, no attaching namespace-only handlers if ( !type ) { continue; } // If event changes its type, use the special event handlers for the changed type special = jQuery.event.special[ type ] || {}; // If selector defined, determine special event api type, otherwise given type type = ( selector ? special.delegateType : special.bindType ) || type; // Update special based on newly reset type special = jQuery.event.special[ type ] || {}; // handleObj is passed to all event handlers handleObj = jQuery.extend( { type: type, origType: origType, data: data, handler: handler, guid: handler.guid, selector: selector, needsContext: selector && jQuery.expr.match.needsContext.test( selector ), namespace: namespaces.join( "." ) }, handleObjIn ); // Init the event handler queue if we're the first if ( !( handlers = events[ type ] ) ) { handlers = events[ type ] = []; handlers.delegateCount = 0; // Only use addEventListener if the special events handler returns false if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { if ( elem.addEventListener ) { elem.addEventListener( type, eventHandle ); } } } if ( special.add ) { special.add.call( elem, handleObj ); if ( !handleObj.handler.guid ) { handleObj.handler.guid = handler.guid; } } // Add to the element's handler list, delegates in front if ( selector ) { handlers.splice( handlers.delegateCount++, 0, handleObj ); } else { handlers.push( handleObj ); } // Keep track of which events have ever been used, for event optimization jQuery.event.global[ type ] = true; } }, // Detach an event or set of events from an element remove: function( elem, types, handler, selector, mappedTypes ) { var j, origCount, tmp, events, t, handleObj, special, handlers, type, namespaces, origType, elemData = dataPriv.hasData( elem ) && dataPriv.get( elem ); if ( !elemData || !( events = elemData.events ) ) { return; } // Once for each type.namespace in types; type may be omitted types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; t = types.length; while ( t-- ) { tmp = rtypenamespace.exec( types[ t ] ) || []; type = origType = tmp[ 1 ]; namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); // Unbind all events (on this namespace, if provided) for the element if ( !type ) { for ( type in events ) { jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); } continue; } special = jQuery.event.special[ type ] || {}; type = ( selector ? special.delegateType : special.bindType ) || type; handlers = events[ type ] || []; tmp = tmp[ 2 ] && new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ); // Remove matching events origCount = j = handlers.length; while ( j-- ) { handleObj = handlers[ j ]; if ( ( mappedTypes || origType === handleObj.origType ) && ( !handler || handler.guid === handleObj.guid ) && ( !tmp || tmp.test( handleObj.namespace ) ) && ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { handlers.splice( j, 1 ); if ( handleObj.selector ) { handlers.delegateCount--; } if ( special.remove ) { special.remove.call( elem, handleObj ); } } } // Remove generic event handler if we removed something and no more handlers exist // (avoids potential for endless recursion during removal of special event handlers) if ( origCount && !handlers.length ) { if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) { jQuery.removeEvent( elem, type, elemData.handle ); } delete events[ type ]; } } // Remove data and the expando if it's no longer used if ( jQuery.isEmptyObject( events ) ) { dataPriv.remove( elem, "handle events" ); } }, dispatch: function( nativeEvent ) { // Make a writable jQuery.Event from the native event object var event = jQuery.event.fix( nativeEvent ); var i, j, ret, matched, handleObj, handlerQueue, args = new Array( arguments.length ), handlers = ( dataPriv.get( this, "events" ) || {} )[ event.type ] || [], special = jQuery.event.special[ event.type ] || {}; // Use the fix-ed jQuery.Event rather than the (read-only) native event args[ 0 ] = event; for ( i = 1; i < arguments.length; i++ ) { args[ i ] = arguments[ i ]; } event.delegateTarget = this; // Call the preDispatch hook for the mapped type, and let it bail if desired if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { return; } // Determine handlers handlerQueue = jQuery.event.handlers.call( this, event, handlers ); // Run delegates first; they may want to stop propagation beneath us i = 0; while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) { event.currentTarget = matched.elem; j = 0; while ( ( handleObj = matched.handlers[ j++ ] ) && !event.isImmediatePropagationStopped() ) { // Triggered event must either 1) have no namespace, or 2) have namespace(s) // a subset or equal to those in the bound event (both can have no namespace). if ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) { event.handleObj = handleObj; event.data = handleObj.data; ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle || handleObj.handler ).apply( matched.elem, args ); if ( ret !== undefined ) { if ( ( event.result = ret ) === false ) { event.preventDefault(); event.stopPropagation(); } } } } } // Call the postDispatch hook for the mapped type if ( special.postDispatch ) { special.postDispatch.call( this, event ); } return event.result; }, handlers: function( event, handlers ) { var i, handleObj, sel, matchedHandlers, matchedSelectors, handlerQueue = [], delegateCount = handlers.delegateCount, cur = event.target; // Find delegate handlers if ( delegateCount && // Support: IE <=9 // Black-hole SVG instance trees (trac-13180) cur.nodeType && // Support: Firefox <=42 // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861) // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click // Support: IE 11 only // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343) !( event.type === "click" && event.button >= 1 ) ) { for ( ; cur !== this; cur = cur.parentNode || this ) { // Don't check non-elements (#13208) // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) { matchedHandlers = []; matchedSelectors = {}; for ( i = 0; i < delegateCount; i++ ) { handleObj = handlers[ i ]; // Don't conflict with Object.prototype properties (#13203) sel = handleObj.selector + " "; if ( matchedSelectors[ sel ] === undefined ) { matchedSelectors[ sel ] = handleObj.needsContext ? jQuery( sel, this ).index( cur ) > -1 : jQuery.find( sel, this, null, [ cur ] ).length; } if ( matchedSelectors[ sel ] ) { matchedHandlers.push( handleObj ); } } if ( matchedHandlers.length ) { handlerQueue.push( { elem: cur, handlers: matchedHandlers } ); } } } } // Add the remaining (directly-bound) handlers cur = this; if ( delegateCount < handlers.length ) { handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } ); } return handlerQueue; }, addProp: function( name, hook ) { Object.defineProperty( jQuery.Event.prototype, name, { enumerable: true, configurable: true, get: isFunction( hook ) ? function() { if ( this.originalEvent ) { return hook( this.originalEvent ); } } : function() { if ( this.originalEvent ) { return this.originalEvent[ name ]; } }, set: function( value ) { Object.defineProperty( this, name, { enumerable: true, configurable: true, writable: true, value: value } ); } } ); }, fix: function( originalEvent ) { return originalEvent[ jQuery.expando ] ? originalEvent : new jQuery.Event( originalEvent ); }, special: { load: { // Prevent triggered image.load events from bubbling to window.load noBubble: true }, focus: { // Fire native event if possible so blur/focus sequence is correct trigger: function() { if ( this !== safeActiveElement() && this.focus ) { this.focus(); return false; } }, delegateType: "focusin" }, blur: { trigger: function() { if ( this === safeActiveElement() && this.blur ) { this.blur(); return false; } }, delegateType: "focusout" }, click: { // For checkbox, fire native event so checked state will be right trigger: function() { if ( this.type === "checkbox" && this.click && nodeName( this, "input" ) ) { this.click(); return false; } }, // For cross-browser consistency, don't fire native .click() on links _default: function( event ) { return nodeName( event.target, "a" ); } }, beforeunload: { postDispatch: function( event ) { // Support: Firefox 20+ // Firefox doesn't alert if the returnValue field is not set. if ( event.result !== undefined && event.originalEvent ) { event.originalEvent.returnValue = event.result; } } } } }; jQuery.removeEvent = function( elem, type, handle ) { // This "if" is needed for plain objects if ( elem.removeEventListener ) { elem.removeEventListener( type, handle ); } }; jQuery.Event = function( src, props ) { // Allow instantiation without the 'new' keyword if ( !( this instanceof jQuery.Event ) ) { return new jQuery.Event( src, props ); } // Event object if ( src && src.type ) { this.originalEvent = src; this.type = src.type; // Events bubbling up the document may have been marked as prevented // by a handler lower down the tree; reflect the correct value. this.isDefaultPrevented = src.defaultPrevented || src.defaultPrevented === undefined && // Support: Android <=2.3 only src.returnValue === false ? returnTrue : returnFalse; // Create target properties // Support: Safari <=6 - 7 only // Target should not be a text node (#504, #13143) this.target = ( src.target && src.target.nodeType === 3 ) ? src.target.parentNode : src.target; this.currentTarget = src.currentTarget; this.relatedTarget = src.relatedTarget; // Event type } else { this.type = src; } // Put explicitly provided properties onto the event object if ( props ) { jQuery.extend( this, props ); } // Create a timestamp if incoming event doesn't have one this.timeStamp = src && src.timeStamp || Date.now(); // Mark it as fixed this[ jQuery.expando ] = true; }; // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding // https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html jQuery.Event.prototype = { constructor: jQuery.Event, isDefaultPrevented: returnFalse, isPropagationStopped: returnFalse, isImmediatePropagationStopped: returnFalse, isSimulated: false, preventDefault: function() { var e = this.originalEvent; this.isDefaultPrevented = returnTrue; if ( e && !this.isSimulated ) { e.preventDefault(); } }, stopPropagation: function() { var e = this.originalEvent; this.isPropagationStopped = returnTrue; if ( e && !this.isSimulated ) { e.stopPropagation(); } }, stopImmediatePropagation: function() { var e = this.originalEvent; this.isImmediatePropagationStopped = returnTrue; if ( e && !this.isSimulated ) { e.stopImmediatePropagation(); } this.stopPropagation(); } }; // Includes all common event props including KeyEvent and MouseEvent specific props jQuery.each( { altKey: true, bubbles: true, cancelable: true, changedTouches: true, ctrlKey: true, detail: true, eventPhase: true, metaKey: true, pageX: true, pageY: true, shiftKey: true, view: true, "char": true, charCode: true, key: true, keyCode: true, button: true, buttons: true, clientX: true, clientY: true, offsetX: true, offsetY: true, pointerId: true, pointerType: true, screenX: true, screenY: true, targetTouches: true, toElement: true, touches: true, which: function( event ) { var button = event.button; // Add which for key events if ( event.which == null && rkeyEvent.test( event.type ) ) { return event.charCode != null ? event.charCode : event.keyCode; } // Add which for click: 1 === left; 2 === middle; 3 === right if ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) { if ( button & 1 ) { return 1; } if ( button & 2 ) { return 3; } if ( button & 4 ) { return 2; } return 0; } return event.which; } }, jQuery.event.addProp ); // Create mouseenter/leave events using mouseover/out and event-time checks // so that event delegation works in jQuery. // Do the same for pointerenter/pointerleave and pointerover/pointerout // // Support: Safari 7 only // Safari sends mouseenter too often; see: // https://bugs.chromium.org/p/chromium/issues/detail?id=470258 // for the description of the bug (it existed in older Chrome versions as well). jQuery.each( { mouseenter: "mouseover", mouseleave: "mouseout", pointerenter: "pointerover", pointerleave: "pointerout" }, function( orig, fix ) { jQuery.event.special[ orig ] = { delegateType: fix, bindType: fix, handle: function( event ) { var ret, target = this, related = event.relatedTarget, handleObj = event.handleObj; // For mouseenter/leave call the handler if related is outside the target. // NB: No relatedTarget if the mouse left/entered the browser window if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) { event.type = handleObj.origType; ret = handleObj.handler.apply( this, arguments ); event.type = fix; } return ret; } }; } ); jQuery.fn.extend( { on: function( types, selector, data, fn ) { return on( this, types, selector, data, fn ); }, one: function( types, selector, data, fn ) { return on( this, types, selector, data, fn, 1 ); }, off: function( types, selector, fn ) { var handleObj, type; if ( types && types.preventDefault && types.handleObj ) { // ( event ) dispatched jQuery.Event handleObj = types.handleObj; jQuery( types.delegateTarget ).off( handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, handleObj.selector, handleObj.handler ); return this; } if ( typeof types === "object" ) { // ( types-object [, selector] ) for ( type in types ) { this.off( type, selector, types[ type ] ); } return this; } if ( selector === false || typeof selector === "function" ) { // ( types [, fn] ) fn = selector; selector = undefined; } if ( fn === false ) { fn = returnFalse; } return this.each( function() { jQuery.event.remove( this, types, fn, selector ); } ); } } ); var /* eslint-disable max-len */ // See https://github.com/eslint/eslint/issues/3229 rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi, /* eslint-enable */ // Support: IE <=10 - 11, Edge 12 - 13 only // In IE/Edge using regex groups here causes severe slowdowns. // See https://connect.microsoft.com/IE/feedback/details/1736512/ rnoInnerhtml = /\s*$/g; // Prefer a tbody over its parent table for containing new rows function manipulationTarget( elem, content ) { if ( nodeName( elem, "table" ) && nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) { return jQuery( elem ).children( "tbody" )[ 0 ] || elem; } return elem; } // Replace/restore the type attribute of script elements for safe DOM manipulation function disableScript( elem ) { elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type; return elem; } function restoreScript( elem ) { if ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) { elem.type = elem.type.slice( 5 ); } else { elem.removeAttribute( "type" ); } return elem; } function cloneCopyEvent( src, dest ) { var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events; if ( dest.nodeType !== 1 ) { return; } // 1. Copy private data: events, handlers, etc. if ( dataPriv.hasData( src ) ) { pdataOld = dataPriv.access( src ); pdataCur = dataPriv.set( dest, pdataOld ); events = pdataOld.events; if ( events ) { delete pdataCur.handle; pdataCur.events = {}; for ( type in events ) { for ( i = 0, l = events[ type ].length; i < l; i++ ) { jQuery.event.add( dest, type, events[ type ][ i ] ); } } } } // 2. Copy user data if ( dataUser.hasData( src ) ) { udataOld = dataUser.access( src ); udataCur = jQuery.extend( {}, udataOld ); dataUser.set( dest, udataCur ); } } // Fix IE bugs, see support tests function fixInput( src, dest ) { var nodeName = dest.nodeName.toLowerCase(); // Fails to persist the checked state of a cloned checkbox or radio button. if ( nodeName === "input" && rcheckableType.test( src.type ) ) { dest.checked = src.checked; // Fails to return the selected option to the default selected state when cloning options } else if ( nodeName === "input" || nodeName === "textarea" ) { dest.defaultValue = src.defaultValue; } } function domManip( collection, args, callback, ignored ) { // Flatten any nested arrays args = concat.apply( [], args ); var fragment, first, scripts, hasScripts, node, doc, i = 0, l = collection.length, iNoClone = l - 1, value = args[ 0 ], valueIsFunction = isFunction( value ); // We can't cloneNode fragments that contain checked, in WebKit if ( valueIsFunction || ( l > 1 && typeof value === "string" && !support.checkClone && rchecked.test( value ) ) ) { return collection.each( function( index ) { var self = collection.eq( index ); if ( valueIsFunction ) { args[ 0 ] = value.call( this, index, self.html() ); } domManip( self, args, callback, ignored ); } ); } if ( l ) { fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored ); first = fragment.firstChild; if ( fragment.childNodes.length === 1 ) { fragment = first; } // Require either new content or an interest in ignored elements to invoke the callback if ( first || ignored ) { scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); hasScripts = scripts.length; // Use the original fragment for the last item // instead of the first because it can end up // being emptied incorrectly in certain situations (#8070). for ( ; i < l; i++ ) { node = fragment; if ( i !== iNoClone ) { node = jQuery.clone( node, true, true ); // Keep references to cloned scripts for later restoration if ( hasScripts ) { // Support: Android <=4.0 only, PhantomJS 1 only // push.apply(_, arraylike) throws on ancient WebKit jQuery.merge( scripts, getAll( node, "script" ) ); } } callback.call( collection[ i ], node, i ); } if ( hasScripts ) { doc = scripts[ scripts.length - 1 ].ownerDocument; // Reenable scripts jQuery.map( scripts, restoreScript ); // Evaluate executable scripts on first document insertion for ( i = 0; i < hasScripts; i++ ) { node = scripts[ i ]; if ( rscriptType.test( node.type || "" ) && !dataPriv.access( node, "globalEval" ) && jQuery.contains( doc, node ) ) { if ( node.src && ( node.type || "" ).toLowerCase() !== "module" ) { // Optional AJAX dependency, but won't run scripts if not present if ( jQuery._evalUrl ) { jQuery._evalUrl( node.src ); } } else { DOMEval( node.textContent.replace( rcleanScript, "" ), doc, node ); } } } } } } return collection; } function remove( elem, selector, keepData ) { var node, nodes = selector ? jQuery.filter( selector, elem ) : elem, i = 0; for ( ; ( node = nodes[ i ] ) != null; i++ ) { if ( !keepData && node.nodeType === 1 ) { jQuery.cleanData( getAll( node ) ); } if ( node.parentNode ) { if ( keepData && jQuery.contains( node.ownerDocument, node ) ) { setGlobalEval( getAll( node, "script" ) ); } node.parentNode.removeChild( node ); } } return elem; } jQuery.extend( { htmlPrefilter: function( html ) { return html.replace( rxhtmlTag, "<$1>" ); }, clone: function( elem, dataAndEvents, deepDataAndEvents ) { var i, l, srcElements, destElements, clone = elem.cloneNode( true ), inPage = jQuery.contains( elem.ownerDocument, elem ); // Fix IE cloning issues if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && !jQuery.isXMLDoc( elem ) ) { // We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2 destElements = getAll( clone ); srcElements = getAll( elem ); for ( i = 0, l = srcElements.length; i < l; i++ ) { fixInput( srcElements[ i ], destElements[ i ] ); } } // Copy the events from the original to the clone if ( dataAndEvents ) { if ( deepDataAndEvents ) { srcElements = srcElements || getAll( elem ); destElements = destElements || getAll( clone ); for ( i = 0, l = srcElements.length; i < l; i++ ) { cloneCopyEvent( srcElements[ i ], destElements[ i ] ); } } else { cloneCopyEvent( elem, clone ); } } // Preserve script evaluation history destElements = getAll( clone, "script" ); if ( destElements.length > 0 ) { setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); } // Return the cloned set return clone; }, cleanData: function( elems ) { var data, elem, type, special = jQuery.event.special, i = 0; for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) { if ( acceptData( elem ) ) { if ( ( data = elem[ dataPriv.expando ] ) ) { if ( data.events ) { for ( type in data.events ) { if ( special[ type ] ) { jQuery.event.remove( elem, type ); // This is a shortcut to avoid jQuery.event.remove's overhead } else { jQuery.removeEvent( elem, type, data.handle ); } } } // Support: Chrome <=35 - 45+ // Assign undefined instead of using delete, see Data#remove elem[ dataPriv.expando ] = undefined; } if ( elem[ dataUser.expando ] ) { // Support: Chrome <=35 - 45+ // Assign undefined instead of using delete, see Data#remove elem[ dataUser.expando ] = undefined; } } } } } ); jQuery.fn.extend( { detach: function( selector ) { return remove( this, selector, true ); }, remove: function( selector ) { return remove( this, selector ); }, text: function( value ) { return access( this, function( value ) { return value === undefined ? jQuery.text( this ) : this.empty().each( function() { if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { this.textContent = value; } } ); }, null, value, arguments.length ); }, append: function() { return domManip( this, arguments, function( elem ) { if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { var target = manipulationTarget( this, elem ); target.appendChild( elem ); } } ); }, prepend: function() { return domManip( this, arguments, function( elem ) { if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { var target = manipulationTarget( this, elem ); target.insertBefore( elem, target.firstChild ); } } ); }, before: function() { return domManip( this, arguments, function( elem ) { if ( this.parentNode ) { this.parentNode.insertBefore( elem, this ); } } ); }, after: function() { return domManip( this, arguments, function( elem ) { if ( this.parentNode ) { this.parentNode.insertBefore( elem, this.nextSibling ); } } ); }, empty: function() { var elem, i = 0; for ( ; ( elem = this[ i ] ) != null; i++ ) { if ( elem.nodeType === 1 ) { // Prevent memory leaks jQuery.cleanData( getAll( elem, false ) ); // Remove any remaining nodes elem.textContent = ""; } } return this; }, clone: function( dataAndEvents, deepDataAndEvents ) { dataAndEvents = dataAndEvents == null ? false : dataAndEvents; deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; return this.map( function() { return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); } ); }, html: function( value ) { return access( this, function( value ) { var elem = this[ 0 ] || {}, i = 0, l = this.length; if ( value === undefined && elem.nodeType === 1 ) { return elem.innerHTML; } // See if we can take a shortcut and just use innerHTML if ( typeof value === "string" && !rnoInnerhtml.test( value ) && !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { value = jQuery.htmlPrefilter( value ); try { for ( ; i < l; i++ ) { elem = this[ i ] || {}; // Remove element nodes and prevent memory leaks if ( elem.nodeType === 1 ) { jQuery.cleanData( getAll( elem, false ) ); elem.innerHTML = value; } } elem = 0; // If using innerHTML throws an exception, use the fallback method } catch ( e ) {} } if ( elem ) { this.empty().append( value ); } }, null, value, arguments.length ); }, replaceWith: function() { var ignored = []; // Make the changes, replacing each non-ignored context element with the new content return domManip( this, arguments, function( elem ) { var parent = this.parentNode; if ( jQuery.inArray( this, ignored ) < 0 ) { jQuery.cleanData( getAll( this ) ); if ( parent ) { parent.replaceChild( elem, this ); } } // Force callback invocation }, ignored ); } } ); jQuery.each( { appendTo: "append", prependTo: "prepend", insertBefore: "before", insertAfter: "after", replaceAll: "replaceWith" }, function( name, original ) { jQuery.fn[ name ] = function( selector ) { var elems, ret = [], insert = jQuery( selector ), last = insert.length - 1, i = 0; for ( ; i <= last; i++ ) { elems = i === last ? this : this.clone( true ); jQuery( insert[ i ] )[ original ]( elems ); // Support: Android <=4.0 only, PhantomJS 1 only // .get() because push.apply(_, arraylike) throws on ancient WebKit push.apply( ret, elems.get() ); } return this.pushStack( ret ); }; } ); var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ); var getStyles = function( elem ) { // Support: IE <=11 only, Firefox <=30 (#15098, #14150) // IE throws on elements created in popups // FF meanwhile throws on frame elements through "defaultView.getComputedStyle" var view = elem.ownerDocument.defaultView; if ( !view || !view.opener ) { view = window; } return view.getComputedStyle( elem ); }; var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" ); ( function() { // Executing both pixelPosition & boxSizingReliable tests require only one layout // so they're executed at the same time to save the second computation. function computeStyleTests() { // This is a singleton, we need to execute it only once if ( !div ) { return; } container.style.cssText = "position:absolute;left:-11111px;width:60px;" + "margin-top:1px;padding:0;border:0"; div.style.cssText = "position:relative;display:block;box-sizing:border-box;overflow:scroll;" + "margin:auto;border:1px;padding:1px;" + "width:60%;top:1%"; documentElement.appendChild( container ).appendChild( div ); var divStyle = window.getComputedStyle( div ); pixelPositionVal = divStyle.top !== "1%"; // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44 reliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12; // Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3 // Some styles come back with percentage values, even though they shouldn't div.style.right = "60%"; pixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36; // Support: IE 9 - 11 only // Detect misreporting of content dimensions for box-sizing:border-box elements boxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36; // Support: IE 9 only // Detect overflow:scroll screwiness (gh-3699) div.style.position = "absolute"; scrollboxSizeVal = div.offsetWidth === 36 || "absolute"; documentElement.removeChild( container ); // Nullify the div so it wouldn't be stored in the memory and // it will also be a sign that checks already performed div = null; } function roundPixelMeasures( measure ) { return Math.round( parseFloat( measure ) ); } var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal, reliableMarginLeftVal, container = document.createElement( "div" ), div = document.createElement( "div" ); // Finish early in limited (non-browser) environments if ( !div.style ) { return; } // Support: IE <=9 - 11 only // Style of cloned element affects source element cloned (#8908) div.style.backgroundClip = "content-box"; div.cloneNode( true ).style.backgroundClip = ""; support.clearCloneStyle = div.style.backgroundClip === "content-box"; jQuery.extend( support, { boxSizingReliable: function() { computeStyleTests(); return boxSizingReliableVal; }, pixelBoxStyles: function() { computeStyleTests(); return pixelBoxStylesVal; }, pixelPosition: function() { computeStyleTests(); return pixelPositionVal; }, reliableMarginLeft: function() { computeStyleTests(); return reliableMarginLeftVal; }, scrollboxSize: function() { computeStyleTests(); return scrollboxSizeVal; } } ); } )(); function curCSS( elem, name, computed ) { var width, minWidth, maxWidth, ret, // Support: Firefox 51+ // Retrieving style before computed somehow // fixes an issue with getting wrong values // on detached elements style = elem.style; computed = computed || getStyles( elem ); // getPropertyValue is needed for: // .css('filter') (IE 9 only, #12537) // .css('--customProperty) (#3144) if ( computed ) { ret = computed.getPropertyValue( name ) || computed[ name ]; if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) { ret = jQuery.style( elem, name ); } // A tribute to the "awesome hack by Dean Edwards" // Android Browser returns percentage for some values, // but width seems to be reliably pixels. // This is against the CSSOM draft spec: // https://drafts.csswg.org/cssom/#resolved-values if ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) { // Remember the original values width = style.width; minWidth = style.minWidth; maxWidth = style.maxWidth; // Put in the new values to get a computed value out style.minWidth = style.maxWidth = style.width = ret; ret = computed.width; // Revert the changed values style.width = width; style.minWidth = minWidth; style.maxWidth = maxWidth; } } return ret !== undefined ? // Support: IE <=9 - 11 only // IE returns zIndex value as an integer. ret + "" : ret; } function addGetHookIf( conditionFn, hookFn ) { // Define the hook, we'll check on the first run if it's really needed. return { get: function() { if ( conditionFn() ) { // Hook not needed (or it's not possible to use it due // to missing dependency), remove it. delete this.get; return; } // Hook needed; redefine it so that the support test is not executed again. return ( this.get = hookFn ).apply( this, arguments ); } }; } var // Swappable if display is none or starts with table // except "table", "table-cell", or "table-caption" // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display rdisplayswap = /^(none|table(?!-c[ea]).+)/, rcustomProp = /^--/, cssShow = { position: "absolute", visibility: "hidden", display: "block" }, cssNormalTransform = { letterSpacing: "0", fontWeight: "400" }, cssPrefixes = [ "Webkit", "Moz", "ms" ], emptyStyle = document.createElement( "div" ).style; // Return a css property mapped to a potentially vendor prefixed property function vendorPropName( name ) { // Shortcut for names that are not vendor prefixed if ( name in emptyStyle ) { return name; } // Check for vendor prefixed names var capName = name[ 0 ].toUpperCase() + name.slice( 1 ), i = cssPrefixes.length; while ( i-- ) { name = cssPrefixes[ i ] + capName; if ( name in emptyStyle ) { return name; } } } // Return a property mapped along what jQuery.cssProps suggests or to // a vendor prefixed property. function finalPropName( name ) { var ret = jQuery.cssProps[ name ]; if ( !ret ) { ret = jQuery.cssProps[ name ] = vendorPropName( name ) || name; } return ret; } function setPositiveNumber( elem, value, subtract ) { // Any relative (+/-) values have already been // normalized at this point var matches = rcssNum.exec( value ); return matches ? // Guard against undefined "subtract", e.g., when used as in cssHooks Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) : value; } function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) { var i = dimension === "width" ? 1 : 0, extra = 0, delta = 0; // Adjustment may not be necessary if ( box === ( isBorderBox ? "border" : "content" ) ) { return 0; } for ( ; i < 4; i += 2 ) { // Both box models exclude margin if ( box === "margin" ) { delta += jQuery.css( elem, box + cssExpand[ i ], true, styles ); } // If we get here with a content-box, we're seeking "padding" or "border" or "margin" if ( !isBorderBox ) { // Add padding delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); // For "border" or "margin", add border if ( box !== "padding" ) { delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); // But still keep track of it otherwise } else { extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); } // If we get here with a border-box (content + padding + border), we're seeking "content" or // "padding" or "margin" } else { // For "content", subtract padding if ( box === "content" ) { delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); } // For "content" or "padding", subtract border if ( box !== "margin" ) { delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); } } } // Account for positive content-box scroll gutter when requested by providing computedVal if ( !isBorderBox && computedVal >= 0 ) { // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border // Assuming integer scroll gutter, subtract the rest and round down delta += Math.max( 0, Math.ceil( elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - computedVal - delta - extra - 0.5 ) ); } return delta; } function getWidthOrHeight( elem, dimension, extra ) { // Start with computed style var styles = getStyles( elem ), val = curCSS( elem, dimension, styles ), isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box", valueIsBorderBox = isBorderBox; // Support: Firefox <=54 // Return a confounding non-pixel value or feign ignorance, as appropriate. if ( rnumnonpx.test( val ) ) { if ( !extra ) { return val; } val = "auto"; } // Check for style in case a browser which returns unreliable values // for getComputedStyle silently falls back to the reliable elem.style valueIsBorderBox = valueIsBorderBox && ( support.boxSizingReliable() || val === elem.style[ dimension ] ); // Fall back to offsetWidth/offsetHeight when value is "auto" // This happens for inline elements with no explicit setting (gh-3571) // Support: Android <=4.1 - 4.3 only // Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602) if ( val === "auto" || !parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) { val = elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ]; // offsetWidth/offsetHeight provide border-box values valueIsBorderBox = true; } // Normalize "" and auto val = parseFloat( val ) || 0; // Adjust for the element's box model return ( val + boxModelAdjustment( elem, dimension, extra || ( isBorderBox ? "border" : "content" ), valueIsBorderBox, styles, // Provide the current computed size to request scroll gutter calculation (gh-3589) val ) ) + "px"; } jQuery.extend( { // Add in style property hooks for overriding the default // behavior of getting and setting a style property cssHooks: { opacity: { get: function( elem, computed ) { if ( computed ) { // We should always get a number back from opacity var ret = curCSS( elem, "opacity" ); return ret === "" ? "1" : ret; } } } }, // Don't automatically add "px" to these possibly-unitless properties cssNumber: { "animationIterationCount": true, "columnCount": true, "fillOpacity": true, "flexGrow": true, "flexShrink": true, "fontWeight": true, "lineHeight": true, "opacity": true, "order": true, "orphans": true, "widows": true, "zIndex": true, "zoom": true }, // Add in properties whose names you wish to fix before // setting or getting the value cssProps: {}, // Get and set the style property on a DOM Node style: function( elem, name, value, extra ) { // Don't set styles on text and comment nodes if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { return; } // Make sure that we're working with the right name var ret, type, hooks, origName = camelCase( name ), isCustomProp = rcustomProp.test( name ), style = elem.style; // Make sure that we're working with the right name. We don't // want to query the value if it is a CSS custom property // since they are user-defined. if ( !isCustomProp ) { name = finalPropName( origName ); } // Gets hook for the prefixed version, then unprefixed version hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; // Check if we're setting a value if ( value !== undefined ) { type = typeof value; // Convert "+=" or "-=" to relative numbers (#7345) if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) { value = adjustCSS( elem, name, ret ); // Fixes bug #9237 type = "number"; } // Make sure that null and NaN values aren't set (#7116) if ( value == null || value !== value ) { return; } // If a number was passed in, add the unit (except for certain CSS properties) if ( type === "number" ) { value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" ); } // background-* props affect original clone's values if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) { style[ name ] = "inherit"; } // If a hook was provided, use that value, otherwise just set the specified value if ( !hooks || !( "set" in hooks ) || ( value = hooks.set( elem, value, extra ) ) !== undefined ) { if ( isCustomProp ) { style.setProperty( name, value ); } else { style[ name ] = value; } } } else { // If a hook was provided get the non-computed value from there if ( hooks && "get" in hooks && ( ret = hooks.get( elem, false, extra ) ) !== undefined ) { return ret; } // Otherwise just get the value from the style object return style[ name ]; } }, css: function( elem, name, extra, styles ) { var val, num, hooks, origName = camelCase( name ), isCustomProp = rcustomProp.test( name ); // Make sure that we're working with the right name. We don't // want to modify the value if it is a CSS custom property // since they are user-defined. if ( !isCustomProp ) { name = finalPropName( origName ); } // Try prefixed name followed by the unprefixed name hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; // If a hook was provided get the computed value from there if ( hooks && "get" in hooks ) { val = hooks.get( elem, true, extra ); } // Otherwise, if a way to get the computed value exists, use that if ( val === undefined ) { val = curCSS( elem, name, styles ); } // Convert "normal" to computed value if ( val === "normal" && name in cssNormalTransform ) { val = cssNormalTransform[ name ]; } // Make numeric if forced or a qualifier was provided and val looks numeric if ( extra === "" || extra ) { num = parseFloat( val ); return extra === true || isFinite( num ) ? num || 0 : val; } return val; } } ); jQuery.each( [ "height", "width" ], function( i, dimension ) { jQuery.cssHooks[ dimension ] = { get: function( elem, computed, extra ) { if ( computed ) { // Certain elements can have dimension info if we invisibly show them // but it must have a current display style that would benefit return rdisplayswap.test( jQuery.css( elem, "display" ) ) && // Support: Safari 8+ // Table columns in Safari have non-zero offsetWidth & zero // getBoundingClientRect().width unless display is changed. // Support: IE <=11 only // Running getBoundingClientRect on a disconnected node // in IE throws an error. ( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ? swap( elem, cssShow, function() { return getWidthOrHeight( elem, dimension, extra ); } ) : getWidthOrHeight( elem, dimension, extra ); } }, set: function( elem, value, extra ) { var matches, styles = getStyles( elem ), isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box", subtract = extra && boxModelAdjustment( elem, dimension, extra, isBorderBox, styles ); // Account for unreliable border-box dimensions by comparing offset* to computed and // faking a content-box to get border and padding (gh-3699) if ( isBorderBox && support.scrollboxSize() === styles.position ) { subtract -= Math.ceil( elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - parseFloat( styles[ dimension ] ) - boxModelAdjustment( elem, dimension, "border", false, styles ) - 0.5 ); } // Convert to pixels if value adjustment is needed if ( subtract && ( matches = rcssNum.exec( value ) ) && ( matches[ 3 ] || "px" ) !== "px" ) { elem.style[ dimension ] = value; value = jQuery.css( elem, dimension ); } return setPositiveNumber( elem, value, subtract ); } }; } ); jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft, function( elem, computed ) { if ( computed ) { return ( parseFloat( curCSS( elem, "marginLeft" ) ) || elem.getBoundingClientRect().left - swap( elem, { marginLeft: 0 }, function() { return elem.getBoundingClientRect().left; } ) ) + "px"; } } ); // These hooks are used by animate to expand properties jQuery.each( { margin: "", padding: "", border: "Width" }, function( prefix, suffix ) { jQuery.cssHooks[ prefix + suffix ] = { expand: function( value ) { var i = 0, expanded = {}, // Assumes a single number if not a string parts = typeof value === "string" ? value.split( " " ) : [ value ]; for ( ; i < 4; i++ ) { expanded[ prefix + cssExpand[ i ] + suffix ] = parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; } return expanded; } }; if ( prefix !== "margin" ) { jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; } } ); jQuery.fn.extend( { css: function( name, value ) { return access( this, function( elem, name, value ) { var styles, len, map = {}, i = 0; if ( Array.isArray( name ) ) { styles = getStyles( elem ); len = name.length; for ( ; i < len; i++ ) { map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); } return map; } return value !== undefined ? jQuery.style( elem, name, value ) : jQuery.css( elem, name ); }, name, value, arguments.length > 1 ); } } ); function Tween( elem, options, prop, end, easing ) { return new Tween.prototype.init( elem, options, prop, end, easing ); } jQuery.Tween = Tween; Tween.prototype = { constructor: Tween, init: function( elem, options, prop, end, easing, unit ) { this.elem = elem; this.prop = prop; this.easing = easing || jQuery.easing._default; this.options = options; this.start = this.now = this.cur(); this.end = end; this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); }, cur: function() { var hooks = Tween.propHooks[ this.prop ]; return hooks && hooks.get ? hooks.get( this ) : Tween.propHooks._default.get( this ); }, run: function( percent ) { var eased, hooks = Tween.propHooks[ this.prop ]; if ( this.options.duration ) { this.pos = eased = jQuery.easing[ this.easing ]( percent, this.options.duration * percent, 0, 1, this.options.duration ); } else { this.pos = eased = percent; } this.now = ( this.end - this.start ) * eased + this.start; if ( this.options.step ) { this.options.step.call( this.elem, this.now, this ); } if ( hooks && hooks.set ) { hooks.set( this ); } else { Tween.propHooks._default.set( this ); } return this; } }; Tween.prototype.init.prototype = Tween.prototype; Tween.propHooks = { _default: { get: function( tween ) { var result; // Use a property on the element directly when it is not a DOM element, // or when there is no matching style property that exists. if ( tween.elem.nodeType !== 1 || tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) { return tween.elem[ tween.prop ]; } // Passing an empty string as a 3rd parameter to .css will automatically // attempt a parseFloat and fallback to a string if the parse fails. // Simple values such as "10px" are parsed to Float; // complex values such as "rotate(1rad)" are returned as-is. result = jQuery.css( tween.elem, tween.prop, "" ); // Empty strings, null, undefined and "auto" are converted to 0. return !result || result === "auto" ? 0 : result; }, set: function( tween ) { // Use step hook for back compat. // Use cssHook if its there. // Use .style if available and use plain properties where available. if ( jQuery.fx.step[ tween.prop ] ) { jQuery.fx.step[ tween.prop ]( tween ); } else if ( tween.elem.nodeType === 1 && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) { jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); } else { tween.elem[ tween.prop ] = tween.now; } } } }; // Support: IE <=9 only // Panic based approach to setting things on disconnected nodes Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { set: function( tween ) { if ( tween.elem.nodeType && tween.elem.parentNode ) { tween.elem[ tween.prop ] = tween.now; } } }; jQuery.easing = { linear: function( p ) { return p; }, swing: function( p ) { return 0.5 - Math.cos( p * Math.PI ) / 2; }, _default: "swing" }; jQuery.fx = Tween.prototype.init; // Back compat <1.8 extension point jQuery.fx.step = {}; var fxNow, inProgress, rfxtypes = /^(?:toggle|show|hide)$/, rrun = /queueHooks$/; function schedule() { if ( inProgress ) { if ( document.hidden === false && window.requestAnimationFrame ) { window.requestAnimationFrame( schedule ); } else { window.setTimeout( schedule, jQuery.fx.interval ); } jQuery.fx.tick(); } } // Animations created synchronously will run synchronously function createFxNow() { window.setTimeout( function() { fxNow = undefined; } ); return ( fxNow = Date.now() ); } // Generate parameters to create a standard animation function genFx( type, includeWidth ) { var which, i = 0, attrs = { height: type }; // If we include width, step value is 1 to do all cssExpand values, // otherwise step value is 2 to skip over Left and Right includeWidth = includeWidth ? 1 : 0; for ( ; i < 4; i += 2 - includeWidth ) { which = cssExpand[ i ]; attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; } if ( includeWidth ) { attrs.opacity = attrs.width = type; } return attrs; } function createTween( value, prop, animation ) { var tween, collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ), index = 0, length = collection.length; for ( ; index < length; index++ ) { if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) { // We're done with this property return tween; } } } function defaultPrefilter( elem, props, opts ) { var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display, isBox = "width" in props || "height" in props, anim = this, orig = {}, style = elem.style, hidden = elem.nodeType && isHiddenWithinTree( elem ), dataShow = dataPriv.get( elem, "fxshow" ); // Queue-skipping animations hijack the fx hooks if ( !opts.queue ) { hooks = jQuery._queueHooks( elem, "fx" ); if ( hooks.unqueued == null ) { hooks.unqueued = 0; oldfire = hooks.empty.fire; hooks.empty.fire = function() { if ( !hooks.unqueued ) { oldfire(); } }; } hooks.unqueued++; anim.always( function() { // Ensure the complete handler is called before this completes anim.always( function() { hooks.unqueued--; if ( !jQuery.queue( elem, "fx" ).length ) { hooks.empty.fire(); } } ); } ); } // Detect show/hide animations for ( prop in props ) { value = props[ prop ]; if ( rfxtypes.test( value ) ) { delete props[ prop ]; toggle = toggle || value === "toggle"; if ( value === ( hidden ? "hide" : "show" ) ) { // Pretend to be hidden if this is a "show" and // there is still data from a stopped show/hide if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) { hidden = true; // Ignore all other no-op show/hide data } else { continue; } } orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop ); } } // Bail out if this is a no-op like .hide().hide() propTween = !jQuery.isEmptyObject( props ); if ( !propTween && jQuery.isEmptyObject( orig ) ) { return; } // Restrict "overflow" and "display" styles during box animations if ( isBox && elem.nodeType === 1 ) { // Support: IE <=9 - 11, Edge 12 - 15 // Record all 3 overflow attributes because IE does not infer the shorthand // from identically-valued overflowX and overflowY and Edge just mirrors // the overflowX value there. opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; // Identify a display type, preferring old show/hide data over the CSS cascade restoreDisplay = dataShow && dataShow.display; if ( restoreDisplay == null ) { restoreDisplay = dataPriv.get( elem, "display" ); } display = jQuery.css( elem, "display" ); if ( display === "none" ) { if ( restoreDisplay ) { display = restoreDisplay; } else { // Get nonempty value(s) by temporarily forcing visibility showHide( [ elem ], true ); restoreDisplay = elem.style.display || restoreDisplay; display = jQuery.css( elem, "display" ); showHide( [ elem ] ); } } // Animate inline elements as inline-block if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) { if ( jQuery.css( elem, "float" ) === "none" ) { // Restore the original display value at the end of pure show/hide animations if ( !propTween ) { anim.done( function() { style.display = restoreDisplay; } ); if ( restoreDisplay == null ) { display = style.display; restoreDisplay = display === "none" ? "" : display; } } style.display = "inline-block"; } } } if ( opts.overflow ) { style.overflow = "hidden"; anim.always( function() { style.overflow = opts.overflow[ 0 ]; style.overflowX = opts.overflow[ 1 ]; style.overflowY = opts.overflow[ 2 ]; } ); } // Implement show/hide animations propTween = false; for ( prop in orig ) { // General show/hide setup for this element animation if ( !propTween ) { if ( dataShow ) { if ( "hidden" in dataShow ) { hidden = dataShow.hidden; } } else { dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } ); } // Store hidden/visible for toggle so `.stop().toggle()` "reverses" if ( toggle ) { dataShow.hidden = !hidden; } // Show elements before animating them if ( hidden ) { showHide( [ elem ], true ); } /* eslint-disable no-loop-func */ anim.done( function() { /* eslint-enable no-loop-func */ // The final step of a "hide" animation is actually hiding the element if ( !hidden ) { showHide( [ elem ] ); } dataPriv.remove( elem, "fxshow" ); for ( prop in orig ) { jQuery.style( elem, prop, orig[ prop ] ); } } ); } // Per-property setup propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim ); if ( !( prop in dataShow ) ) { dataShow[ prop ] = propTween.start; if ( hidden ) { propTween.end = propTween.start; propTween.start = 0; } } } } function propFilter( props, specialEasing ) { var index, name, easing, value, hooks; // camelCase, specialEasing and expand cssHook pass for ( index in props ) { name = camelCase( index ); easing = specialEasing[ name ]; value = props[ index ]; if ( Array.isArray( value ) ) { easing = value[ 1 ]; value = props[ index ] = value[ 0 ]; } if ( index !== name ) { props[ name ] = value; delete props[ index ]; } hooks = jQuery.cssHooks[ name ]; if ( hooks && "expand" in hooks ) { value = hooks.expand( value ); delete props[ name ]; // Not quite $.extend, this won't overwrite existing keys. // Reusing 'index' because we have the correct "name" for ( index in value ) { if ( !( index in props ) ) { props[ index ] = value[ index ]; specialEasing[ index ] = easing; } } } else { specialEasing[ name ] = easing; } } } function Animation( elem, properties, options ) { var result, stopped, index = 0, length = Animation.prefilters.length, deferred = jQuery.Deferred().always( function() { // Don't match elem in the :animated selector delete tick.elem; } ), tick = function() { if ( stopped ) { return false; } var currentTime = fxNow || createFxNow(), remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), // Support: Android 2.3 only // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497) temp = remaining / animation.duration || 0, percent = 1 - temp, index = 0, length = animation.tweens.length; for ( ; index < length; index++ ) { animation.tweens[ index ].run( percent ); } deferred.notifyWith( elem, [ animation, percent, remaining ] ); // If there's more to do, yield if ( percent < 1 && length ) { return remaining; } // If this was an empty animation, synthesize a final progress notification if ( !length ) { deferred.notifyWith( elem, [ animation, 1, 0 ] ); } // Resolve the animation and report its conclusion deferred.resolveWith( elem, [ animation ] ); return false; }, animation = deferred.promise( { elem: elem, props: jQuery.extend( {}, properties ), opts: jQuery.extend( true, { specialEasing: {}, easing: jQuery.easing._default }, options ), originalProperties: properties, originalOptions: options, startTime: fxNow || createFxNow(), duration: options.duration, tweens: [], createTween: function( prop, end ) { var tween = jQuery.Tween( elem, animation.opts, prop, end, animation.opts.specialEasing[ prop ] || animation.opts.easing ); animation.tweens.push( tween ); return tween; }, stop: function( gotoEnd ) { var index = 0, // If we are going to the end, we want to run all the tweens // otherwise we skip this part length = gotoEnd ? animation.tweens.length : 0; if ( stopped ) { return this; } stopped = true; for ( ; index < length; index++ ) { animation.tweens[ index ].run( 1 ); } // Resolve when we played the last frame; otherwise, reject if ( gotoEnd ) { deferred.notifyWith( elem, [ animation, 1, 0 ] ); deferred.resolveWith( elem, [ animation, gotoEnd ] ); } else { deferred.rejectWith( elem, [ animation, gotoEnd ] ); } return this; } } ), props = animation.props; propFilter( props, animation.opts.specialEasing ); for ( ; index < length; index++ ) { result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts ); if ( result ) { if ( isFunction( result.stop ) ) { jQuery._queueHooks( animation.elem, animation.opts.queue ).stop = result.stop.bind( result ); } return result; } } jQuery.map( props, createTween, animation ); if ( isFunction( animation.opts.start ) ) { animation.opts.start.call( elem, animation ); } // Attach callbacks from options animation .progress( animation.opts.progress ) .done( animation.opts.done, animation.opts.complete ) .fail( animation.opts.fail ) .always( animation.opts.always ); jQuery.fx.timer( jQuery.extend( tick, { elem: elem, anim: animation, queue: animation.opts.queue } ) ); return animation; } jQuery.Animation = jQuery.extend( Animation, { tweeners: { "*": [ function( prop, value ) { var tween = this.createTween( prop, value ); adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween ); return tween; } ] }, tweener: function( props, callback ) { if ( isFunction( props ) ) { callback = props; props = [ "*" ]; } else { props = props.match( rnothtmlwhite ); } var prop, index = 0, length = props.length; for ( ; index < length; index++ ) { prop = props[ index ]; Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || []; Animation.tweeners[ prop ].unshift( callback ); } }, prefilters: [ defaultPrefilter ], prefilter: function( callback, prepend ) { if ( prepend ) { Animation.prefilters.unshift( callback ); } else { Animation.prefilters.push( callback ); } } } ); jQuery.speed = function( speed, easing, fn ) { var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { complete: fn || !fn && easing || isFunction( speed ) && speed, duration: speed, easing: fn && easing || easing && !isFunction( easing ) && easing }; // Go to the end state if fx are off if ( jQuery.fx.off ) { opt.duration = 0; } else { if ( typeof opt.duration !== "number" ) { if ( opt.duration in jQuery.fx.speeds ) { opt.duration = jQuery.fx.speeds[ opt.duration ]; } else { opt.duration = jQuery.fx.speeds._default; } } } // Normalize opt.queue - true/undefined/null -> "fx" if ( opt.queue == null || opt.queue === true ) { opt.queue = "fx"; } // Queueing opt.old = opt.complete; opt.complete = function() { if ( isFunction( opt.old ) ) { opt.old.call( this ); } if ( opt.queue ) { jQuery.dequeue( this, opt.queue ); } }; return opt; }; jQuery.fn.extend( { fadeTo: function( speed, to, easing, callback ) { // Show any hidden elements after setting opacity to 0 return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show() // Animate to the value specified .end().animate( { opacity: to }, speed, easing, callback ); }, animate: function( prop, speed, easing, callback ) { var empty = jQuery.isEmptyObject( prop ), optall = jQuery.speed( speed, easing, callback ), doAnimation = function() { // Operate on a copy of prop so per-property easing won't be lost var anim = Animation( this, jQuery.extend( {}, prop ), optall ); // Empty animations, or finishing resolves immediately if ( empty || dataPriv.get( this, "finish" ) ) { anim.stop( true ); } }; doAnimation.finish = doAnimation; return empty || optall.queue === false ? this.each( doAnimation ) : this.queue( optall.queue, doAnimation ); }, stop: function( type, clearQueue, gotoEnd ) { var stopQueue = function( hooks ) { var stop = hooks.stop; delete hooks.stop; stop( gotoEnd ); }; if ( typeof type !== "string" ) { gotoEnd = clearQueue; clearQueue = type; type = undefined; } if ( clearQueue && type !== false ) { this.queue( type || "fx", [] ); } return this.each( function() { var dequeue = true, index = type != null && type + "queueHooks", timers = jQuery.timers, data = dataPriv.get( this ); if ( index ) { if ( data[ index ] && data[ index ].stop ) { stopQueue( data[ index ] ); } } else { for ( index in data ) { if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { stopQueue( data[ index ] ); } } } for ( index = timers.length; index--; ) { if ( timers[ index ].elem === this && ( type == null || timers[ index ].queue === type ) ) { timers[ index ].anim.stop( gotoEnd ); dequeue = false; timers.splice( index, 1 ); } } // Start the next in the queue if the last step wasn't forced. // Timers currently will call their complete callbacks, which // will dequeue but only if they were gotoEnd. if ( dequeue || !gotoEnd ) { jQuery.dequeue( this, type ); } } ); }, finish: function( type ) { if ( type !== false ) { type = type || "fx"; } return this.each( function() { var index, data = dataPriv.get( this ), queue = data[ type + "queue" ], hooks = data[ type + "queueHooks" ], timers = jQuery.timers, length = queue ? queue.length : 0; // Enable finishing flag on private data data.finish = true; // Empty the queue first jQuery.queue( this, type, [] ); if ( hooks && hooks.stop ) { hooks.stop.call( this, true ); } // Look for any active animations, and finish them for ( index = timers.length; index--; ) { if ( timers[ index ].elem === this && timers[ index ].queue === type ) { timers[ index ].anim.stop( true ); timers.splice( index, 1 ); } } // Look for any animations in the old queue and finish them for ( index = 0; index < length; index++ ) { if ( queue[ index ] && queue[ index ].finish ) { queue[ index ].finish.call( this ); } } // Turn off finishing flag delete data.finish; } ); } } ); jQuery.each( [ "toggle", "show", "hide" ], function( i, name ) { var cssFn = jQuery.fn[ name ]; jQuery.fn[ name ] = function( speed, easing, callback ) { return speed == null || typeof speed === "boolean" ? cssFn.apply( this, arguments ) : this.animate( genFx( name, true ), speed, easing, callback ); }; } ); // Generate shortcuts for custom animations jQuery.each( { slideDown: genFx( "show" ), slideUp: genFx( "hide" ), slideToggle: genFx( "toggle" ), fadeIn: { opacity: "show" }, fadeOut: { opacity: "hide" }, fadeToggle: { opacity: "toggle" } }, function( name, props ) { jQuery.fn[ name ] = function( speed, easing, callback ) { return this.animate( props, speed, easing, callback ); }; } ); jQuery.timers = []; jQuery.fx.tick = function() { var timer, i = 0, timers = jQuery.timers; fxNow = Date.now(); for ( ; i < timers.length; i++ ) { timer = timers[ i ]; // Run the timer and safely remove it when done (allowing for external removal) if ( !timer() && timers[ i ] === timer ) { timers.splice( i--, 1 ); } } if ( !timers.length ) { jQuery.fx.stop(); } fxNow = undefined; }; jQuery.fx.timer = function( timer ) { jQuery.timers.push( timer ); jQuery.fx.start(); }; jQuery.fx.interval = 13; jQuery.fx.start = function() { if ( inProgress ) { return; } inProgress = true; schedule(); }; jQuery.fx.stop = function() { inProgress = null; }; jQuery.fx.speeds = { slow: 600, fast: 200, // Default speed _default: 400 }; // Based off of the plugin by Clint Helfers, with permission. // https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/ jQuery.fn.delay = function( time, type ) { time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; type = type || "fx"; return this.queue( type, function( next, hooks ) { var timeout = window.setTimeout( next, time ); hooks.stop = function() { window.clearTimeout( timeout ); }; } ); }; ( function() { var input = document.createElement( "input" ), select = document.createElement( "select" ), opt = select.appendChild( document.createElement( "option" ) ); input.type = "checkbox"; // Support: Android <=4.3 only // Default value for a checkbox should be "on" support.checkOn = input.value !== ""; // Support: IE <=11 only // Must access selectedIndex to make default options select support.optSelected = opt.selected; // Support: IE <=11 only // An input loses its value after becoming a radio input = document.createElement( "input" ); input.value = "t"; input.type = "radio"; support.radioValue = input.value === "t"; } )(); var boolHook, attrHandle = jQuery.expr.attrHandle; jQuery.fn.extend( { attr: function( name, value ) { return access( this, jQuery.attr, name, value, arguments.length > 1 ); }, removeAttr: function( name ) { return this.each( function() { jQuery.removeAttr( this, name ); } ); } } ); jQuery.extend( { attr: function( elem, name, value ) { var ret, hooks, nType = elem.nodeType; // Don't get/set attributes on text, comment and attribute nodes if ( nType === 3 || nType === 8 || nType === 2 ) { return; } // Fallback to prop when attributes are not supported if ( typeof elem.getAttribute === "undefined" ) { return jQuery.prop( elem, name, value ); } // Attribute hooks are determined by the lowercase version // Grab necessary hook if one is defined if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { hooks = jQuery.attrHooks[ name.toLowerCase() ] || ( jQuery.expr.match.bool.test( name ) ? boolHook : undefined ); } if ( value !== undefined ) { if ( value === null ) { jQuery.removeAttr( elem, name ); return; } if ( hooks && "set" in hooks && ( ret = hooks.set( elem, value, name ) ) !== undefined ) { return ret; } elem.setAttribute( name, value + "" ); return value; } if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { return ret; } ret = jQuery.find.attr( elem, name ); // Non-existent attributes return null, we normalize to undefined return ret == null ? undefined : ret; }, attrHooks: { type: { set: function( elem, value ) { if ( !support.radioValue && value === "radio" && nodeName( elem, "input" ) ) { var val = elem.value; elem.setAttribute( "type", value ); if ( val ) { elem.value = val; } return value; } } } }, removeAttr: function( elem, value ) { var name, i = 0, // Attribute names can contain non-HTML whitespace characters // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2 attrNames = value && value.match( rnothtmlwhite ); if ( attrNames && elem.nodeType === 1 ) { while ( ( name = attrNames[ i++ ] ) ) { elem.removeAttribute( name ); } } } } ); // Hooks for boolean attributes boolHook = { set: function( elem, value, name ) { if ( value === false ) { // Remove boolean attributes when set to false jQuery.removeAttr( elem, name ); } else { elem.setAttribute( name, name ); } return name; } }; jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) { var getter = attrHandle[ name ] || jQuery.find.attr; attrHandle[ name ] = function( elem, name, isXML ) { var ret, handle, lowercaseName = name.toLowerCase(); if ( !isXML ) { // Avoid an infinite loop by temporarily removing this function from the getter handle = attrHandle[ lowercaseName ]; attrHandle[ lowercaseName ] = ret; ret = getter( elem, name, isXML ) != null ? lowercaseName : null; attrHandle[ lowercaseName ] = handle; } return ret; }; } ); var rfocusable = /^(?:input|select|textarea|button)$/i, rclickable = /^(?:a|area)$/i; jQuery.fn.extend( { prop: function( name, value ) { return access( this, jQuery.prop, name, value, arguments.length > 1 ); }, removeProp: function( name ) { return this.each( function() { delete this[ jQuery.propFix[ name ] || name ]; } ); } } ); jQuery.extend( { prop: function( elem, name, value ) { var ret, hooks, nType = elem.nodeType; // Don't get/set properties on text, comment and attribute nodes if ( nType === 3 || nType === 8 || nType === 2 ) { return; } if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { // Fix name and attach hooks name = jQuery.propFix[ name ] || name; hooks = jQuery.propHooks[ name ]; } if ( value !== undefined ) { if ( hooks && "set" in hooks && ( ret = hooks.set( elem, value, name ) ) !== undefined ) { return ret; } return ( elem[ name ] = value ); } if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { return ret; } return elem[ name ]; }, propHooks: { tabIndex: { get: function( elem ) { // Support: IE <=9 - 11 only // elem.tabIndex doesn't always return the // correct value when it hasn't been explicitly set // https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ // Use proper attribute retrieval(#12072) var tabindex = jQuery.find.attr( elem, "tabindex" ); if ( tabindex ) { return parseInt( tabindex, 10 ); } if ( rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ) { return 0; } return -1; } } }, propFix: { "for": "htmlFor", "class": "className" } } ); // Support: IE <=11 only // Accessing the selectedIndex property // forces the browser to respect setting selected // on the option // The getter ensures a default option is selected // when in an optgroup // eslint rule "no-unused-expressions" is disabled for this code // since it considers such accessions noop if ( !support.optSelected ) { jQuery.propHooks.selected = { get: function( elem ) { /* eslint no-unused-expressions: "off" */ var parent = elem.parentNode; if ( parent && parent.parentNode ) { parent.parentNode.selectedIndex; } return null; }, set: function( elem ) { /* eslint no-unused-expressions: "off" */ var parent = elem.parentNode; if ( parent ) { parent.selectedIndex; if ( parent.parentNode ) { parent.parentNode.selectedIndex; } } } }; } jQuery.each( [ "tabIndex", "readOnly", "maxLength", "cellSpacing", "cellPadding", "rowSpan", "colSpan", "useMap", "frameBorder", "contentEditable" ], function() { jQuery.propFix[ this.toLowerCase() ] = this; } ); // Strip and collapse whitespace according to HTML spec // https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace function stripAndCollapse( value ) { var tokens = value.match( rnothtmlwhite ) || []; return tokens.join( " " ); } function getClass( elem ) { return elem.getAttribute && elem.getAttribute( "class" ) || ""; } function classesToArray( value ) { if ( Array.isArray( value ) ) { return value; } if ( typeof value === "string" ) { return value.match( rnothtmlwhite ) || []; } return []; } jQuery.fn.extend( { addClass: function( value ) { var classes, elem, cur, curValue, clazz, j, finalValue, i = 0; if ( isFunction( value ) ) { return this.each( function( j ) { jQuery( this ).addClass( value.call( this, j, getClass( this ) ) ); } ); } classes = classesToArray( value ); if ( classes.length ) { while ( ( elem = this[ i++ ] ) ) { curValue = getClass( elem ); cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); if ( cur ) { j = 0; while ( ( clazz = classes[ j++ ] ) ) { if ( cur.indexOf( " " + clazz + " " ) < 0 ) { cur += clazz + " "; } } // Only assign if different to avoid unneeded rendering. finalValue = stripAndCollapse( cur ); if ( curValue !== finalValue ) { elem.setAttribute( "class", finalValue ); } } } } return this; }, removeClass: function( value ) { var classes, elem, cur, curValue, clazz, j, finalValue, i = 0; if ( isFunction( value ) ) { return this.each( function( j ) { jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) ); } ); } if ( !arguments.length ) { return this.attr( "class", "" ); } classes = classesToArray( value ); if ( classes.length ) { while ( ( elem = this[ i++ ] ) ) { curValue = getClass( elem ); // This expression is here for better compressibility (see addClass) cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); if ( cur ) { j = 0; while ( ( clazz = classes[ j++ ] ) ) { // Remove *all* instances while ( cur.indexOf( " " + clazz + " " ) > -1 ) { cur = cur.replace( " " + clazz + " ", " " ); } } // Only assign if different to avoid unneeded rendering. finalValue = stripAndCollapse( cur ); if ( curValue !== finalValue ) { elem.setAttribute( "class", finalValue ); } } } } return this; }, toggleClass: function( value, stateVal ) { var type = typeof value, isValidValue = type === "string" || Array.isArray( value ); if ( typeof stateVal === "boolean" && isValidValue ) { return stateVal ? this.addClass( value ) : this.removeClass( value ); } if ( isFunction( value ) ) { return this.each( function( i ) { jQuery( this ).toggleClass( value.call( this, i, getClass( this ), stateVal ), stateVal ); } ); } return this.each( function() { var className, i, self, classNames; if ( isValidValue ) { // Toggle individual class names i = 0; self = jQuery( this ); classNames = classesToArray( value ); while ( ( className = classNames[ i++ ] ) ) { // Check each className given, space separated list if ( self.hasClass( className ) ) { self.removeClass( className ); } else { self.addClass( className ); } } // Toggle whole class name } else if ( value === undefined || type === "boolean" ) { className = getClass( this ); if ( className ) { // Store className if set dataPriv.set( this, "__className__", className ); } // If the element has a class name or if we're passed `false`, // then remove the whole classname (if there was one, the above saved it). // Otherwise bring back whatever was previously saved (if anything), // falling back to the empty string if nothing was stored. if ( this.setAttribute ) { this.setAttribute( "class", className || value === false ? "" : dataPriv.get( this, "__className__" ) || "" ); } } } ); }, hasClass: function( selector ) { var className, elem, i = 0; className = " " + selector + " "; while ( ( elem = this[ i++ ] ) ) { if ( elem.nodeType === 1 && ( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) { return true; } } return false; } } ); var rreturn = /\r/g; jQuery.fn.extend( { val: function( value ) { var hooks, ret, valueIsFunction, elem = this[ 0 ]; if ( !arguments.length ) { if ( elem ) { hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ]; if ( hooks && "get" in hooks && ( ret = hooks.get( elem, "value" ) ) !== undefined ) { return ret; } ret = elem.value; // Handle most common string cases if ( typeof ret === "string" ) { return ret.replace( rreturn, "" ); } // Handle cases where value is null/undef or number return ret == null ? "" : ret; } return; } valueIsFunction = isFunction( value ); return this.each( function( i ) { var val; if ( this.nodeType !== 1 ) { return; } if ( valueIsFunction ) { val = value.call( this, i, jQuery( this ).val() ); } else { val = value; } // Treat null/undefined as ""; convert numbers to string if ( val == null ) { val = ""; } else if ( typeof val === "number" ) { val += ""; } else if ( Array.isArray( val ) ) { val = jQuery.map( val, function( value ) { return value == null ? "" : value + ""; } ); } hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; // If set returns undefined, fall back to normal setting if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) { this.value = val; } } ); } } ); jQuery.extend( { valHooks: { option: { get: function( elem ) { var val = jQuery.find.attr( elem, "value" ); return val != null ? val : // Support: IE <=10 - 11 only // option.text throws exceptions (#14686, #14858) // Strip and collapse whitespace // https://html.spec.whatwg.org/#strip-and-collapse-whitespace stripAndCollapse( jQuery.text( elem ) ); } }, select: { get: function( elem ) { var value, option, i, options = elem.options, index = elem.selectedIndex, one = elem.type === "select-one", values = one ? null : [], max = one ? index + 1 : options.length; if ( index < 0 ) { i = max; } else { i = one ? index : 0; } // Loop through all the selected options for ( ; i < max; i++ ) { option = options[ i ]; // Support: IE <=9 only // IE8-9 doesn't update selected after form reset (#2551) if ( ( option.selected || i === index ) && // Don't return options that are disabled or in a disabled optgroup !option.disabled && ( !option.parentNode.disabled || !nodeName( option.parentNode, "optgroup" ) ) ) { // Get the specific value for the option value = jQuery( option ).val(); // We don't need an array for one selects if ( one ) { return value; } // Multi-Selects return an array values.push( value ); } } return values; }, set: function( elem, value ) { var optionSet, option, options = elem.options, values = jQuery.makeArray( value ), i = options.length; while ( i-- ) { option = options[ i ]; /* eslint-disable no-cond-assign */ if ( option.selected = jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1 ) { optionSet = true; } /* eslint-enable no-cond-assign */ } // Force browsers to behave consistently when non-matching value is set if ( !optionSet ) { elem.selectedIndex = -1; } return values; } } } } ); // Radios and checkboxes getter/setter jQuery.each( [ "radio", "checkbox" ], function() { jQuery.valHooks[ this ] = { set: function( elem, value ) { if ( Array.isArray( value ) ) { return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 ); } } }; if ( !support.checkOn ) { jQuery.valHooks[ this ].get = function( elem ) { return elem.getAttribute( "value" ) === null ? "on" : elem.value; }; } } ); // Return jQuery for attributes-only inclusion support.focusin = "onfocusin" in window; var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, stopPropagationCallback = function( e ) { e.stopPropagation(); }; jQuery.extend( jQuery.event, { trigger: function( event, data, elem, onlyHandlers ) { var i, cur, tmp, bubbleType, ontype, handle, special, lastElement, eventPath = [ elem || document ], type = hasOwn.call( event, "type" ) ? event.type : event, namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : []; cur = lastElement = tmp = elem = elem || document; // Don't do events on text and comment nodes if ( elem.nodeType === 3 || elem.nodeType === 8 ) { return; } // focus/blur morphs to focusin/out; ensure we're not firing them right now if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { return; } if ( type.indexOf( "." ) > -1 ) { // Namespaced trigger; create a regexp to match event type in handle() namespaces = type.split( "." ); type = namespaces.shift(); namespaces.sort(); } ontype = type.indexOf( ":" ) < 0 && "on" + type; // Caller can pass in a jQuery.Event object, Object, or just an event type string event = event[ jQuery.expando ] ? event : new jQuery.Event( type, typeof event === "object" && event ); // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) event.isTrigger = onlyHandlers ? 2 : 3; event.namespace = namespaces.join( "." ); event.rnamespace = event.namespace ? new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) : null; // Clean up the event in case it is being reused event.result = undefined; if ( !event.target ) { event.target = elem; } // Clone any incoming data and prepend the event, creating the handler arg list data = data == null ? [ event ] : jQuery.makeArray( data, [ event ] ); // Allow special events to draw outside the lines special = jQuery.event.special[ type ] || {}; if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { return; } // Determine event propagation path in advance, per W3C events spec (#9951) // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) if ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) { bubbleType = special.delegateType || type; if ( !rfocusMorph.test( bubbleType + type ) ) { cur = cur.parentNode; } for ( ; cur; cur = cur.parentNode ) { eventPath.push( cur ); tmp = cur; } // Only add window if we got to document (e.g., not plain obj or detached DOM) if ( tmp === ( elem.ownerDocument || document ) ) { eventPath.push( tmp.defaultView || tmp.parentWindow || window ); } } // Fire handlers on the event path i = 0; while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) { lastElement = cur; event.type = i > 1 ? bubbleType : special.bindType || type; // jQuery handler handle = ( dataPriv.get( cur, "events" ) || {} )[ event.type ] && dataPriv.get( cur, "handle" ); if ( handle ) { handle.apply( cur, data ); } // Native handler handle = ontype && cur[ ontype ]; if ( handle && handle.apply && acceptData( cur ) ) { event.result = handle.apply( cur, data ); if ( event.result === false ) { event.preventDefault(); } } } event.type = type; // If nobody prevented the default action, do it now if ( !onlyHandlers && !event.isDefaultPrevented() ) { if ( ( !special._default || special._default.apply( eventPath.pop(), data ) === false ) && acceptData( elem ) ) { // Call a native DOM method on the target with the same name as the event. // Don't do default actions on window, that's where global variables be (#6170) if ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) { // Don't re-trigger an onFOO event when we call its FOO() method tmp = elem[ ontype ]; if ( tmp ) { elem[ ontype ] = null; } // Prevent re-triggering of the same event, since we already bubbled it above jQuery.event.triggered = type; if ( event.isPropagationStopped() ) { lastElement.addEventListener( type, stopPropagationCallback ); } elem[ type ](); if ( event.isPropagationStopped() ) { lastElement.removeEventListener( type, stopPropagationCallback ); } jQuery.event.triggered = undefined; if ( tmp ) { elem[ ontype ] = tmp; } } } } return event.result; }, // Piggyback on a donor event to simulate a different one // Used only for `focus(in | out)` events simulate: function( type, elem, event ) { var e = jQuery.extend( new jQuery.Event(), event, { type: type, isSimulated: true } ); jQuery.event.trigger( e, null, elem ); } } ); jQuery.fn.extend( { trigger: function( type, data ) { return this.each( function() { jQuery.event.trigger( type, data, this ); } ); }, triggerHandler: function( type, data ) { var elem = this[ 0 ]; if ( elem ) { return jQuery.event.trigger( type, data, elem, true ); } } } ); // Support: Firefox <=44 // Firefox doesn't have focus(in | out) events // Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787 // // Support: Chrome <=48 - 49, Safari <=9.0 - 9.1 // focus(in | out) events fire after focus & blur events, // which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order // Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857 if ( !support.focusin ) { jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) { // Attach a single capturing handler on the document while someone wants focusin/focusout var handler = function( event ) { jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) ); }; jQuery.event.special[ fix ] = { setup: function() { var doc = this.ownerDocument || this, attaches = dataPriv.access( doc, fix ); if ( !attaches ) { doc.addEventListener( orig, handler, true ); } dataPriv.access( doc, fix, ( attaches || 0 ) + 1 ); }, teardown: function() { var doc = this.ownerDocument || this, attaches = dataPriv.access( doc, fix ) - 1; if ( !attaches ) { doc.removeEventListener( orig, handler, true ); dataPriv.remove( doc, fix ); } else { dataPriv.access( doc, fix, attaches ); } } }; } ); } var location = window.location; var nonce = Date.now(); var rquery = ( /\?/ ); // Cross-browser xml parsing jQuery.parseXML = function( data ) { var xml; if ( !data || typeof data !== "string" ) { return null; } // Support: IE 9 - 11 only // IE throws on parseFromString with invalid input. try { xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" ); } catch ( e ) { xml = undefined; } if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) { jQuery.error( "Invalid XML: " + data ); } return xml; }; var rbracket = /\[\]$/, rCRLF = /\r?\n/g, rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, rsubmittable = /^(?:input|select|textarea|keygen)/i; function buildParams( prefix, obj, traditional, add ) { var name; if ( Array.isArray( obj ) ) { // Serialize array item. jQuery.each( obj, function( i, v ) { if ( traditional || rbracket.test( prefix ) ) { // Treat each array item as a scalar. add( prefix, v ); } else { // Item is non-scalar (array or object), encode its numeric index. buildParams( prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]", v, traditional, add ); } } ); } else if ( !traditional && toType( obj ) === "object" ) { // Serialize object item. for ( name in obj ) { buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); } } else { // Serialize scalar item. add( prefix, obj ); } } // Serialize an array of form elements or a set of // key/values into a query string jQuery.param = function( a, traditional ) { var prefix, s = [], add = function( key, valueOrFunction ) { // If value is a function, invoke it and use its return value var value = isFunction( valueOrFunction ) ? valueOrFunction() : valueOrFunction; s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value == null ? "" : value ); }; // If an array was passed in, assume that it is an array of form elements. if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { // Serialize the form elements jQuery.each( a, function() { add( this.name, this.value ); } ); } else { // If traditional, encode the "old" way (the way 1.3.2 or older // did it), otherwise encode params recursively. for ( prefix in a ) { buildParams( prefix, a[ prefix ], traditional, add ); } } // Return the resulting serialization return s.join( "&" ); }; jQuery.fn.extend( { serialize: function() { return jQuery.param( this.serializeArray() ); }, serializeArray: function() { return this.map( function() { // Can add propHook for "elements" to filter or add form elements var elements = jQuery.prop( this, "elements" ); return elements ? jQuery.makeArray( elements ) : this; } ) .filter( function() { var type = this.type; // Use .is( ":disabled" ) so that fieldset[disabled] works return this.name && !jQuery( this ).is( ":disabled" ) && rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) && ( this.checked || !rcheckableType.test( type ) ); } ) .map( function( i, elem ) { var val = jQuery( this ).val(); if ( val == null ) { return null; } if ( Array.isArray( val ) ) { return jQuery.map( val, function( val ) { return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; } ); } return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; } ).get(); } } ); var r20 = /%20/g, rhash = /#.*$/, rantiCache = /([?&])_=[^&]*/, rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg, // #7653, #8125, #8152: local protocol detection rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, rnoContent = /^(?:GET|HEAD)$/, rprotocol = /^\/\//, /* Prefilters * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) * 2) These are called: * - BEFORE asking for a transport * - AFTER param serialization (s.data is a string if s.processData is true) * 3) key is the dataType * 4) the catchall symbol "*" can be used * 5) execution will start with transport dataType and THEN continue down to "*" if needed */ prefilters = {}, /* Transports bindings * 1) key is the dataType * 2) the catchall symbol "*" can be used * 3) selection will start with transport dataType and THEN go to "*" if needed */ transports = {}, // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression allTypes = "*/".concat( "*" ), // Anchor tag for parsing the document origin originAnchor = document.createElement( "a" ); originAnchor.href = location.href; // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport function addToPrefiltersOrTransports( structure ) { // dataTypeExpression is optional and defaults to "*" return function( dataTypeExpression, func ) { if ( typeof dataTypeExpression !== "string" ) { func = dataTypeExpression; dataTypeExpression = "*"; } var dataType, i = 0, dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || []; if ( isFunction( func ) ) { // For each dataType in the dataTypeExpression while ( ( dataType = dataTypes[ i++ ] ) ) { // Prepend if requested if ( dataType[ 0 ] === "+" ) { dataType = dataType.slice( 1 ) || "*"; ( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func ); // Otherwise append } else { ( structure[ dataType ] = structure[ dataType ] || [] ).push( func ); } } } }; } // Base inspection function for prefilters and transports function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) { var inspected = {}, seekingTransport = ( structure === transports ); function inspect( dataType ) { var selected; inspected[ dataType ] = true; jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) { var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR ); if ( typeof dataTypeOrTransport === "string" && !seekingTransport && !inspected[ dataTypeOrTransport ] ) { options.dataTypes.unshift( dataTypeOrTransport ); inspect( dataTypeOrTransport ); return false; } else if ( seekingTransport ) { return !( selected = dataTypeOrTransport ); } } ); return selected; } return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" ); } // A special extend for ajax options // that takes "flat" options (not to be deep extended) // Fixes #9887 function ajaxExtend( target, src ) { var key, deep, flatOptions = jQuery.ajaxSettings.flatOptions || {}; for ( key in src ) { if ( src[ key ] !== undefined ) { ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ]; } } if ( deep ) { jQuery.extend( true, target, deep ); } return target; } /* Handles responses to an ajax request: * - finds the right dataType (mediates between content-type and expected dataType) * - returns the corresponding response */ function ajaxHandleResponses( s, jqXHR, responses ) { var ct, type, finalDataType, firstDataType, contents = s.contents, dataTypes = s.dataTypes; // Remove auto dataType and get content-type in the process while ( dataTypes[ 0 ] === "*" ) { dataTypes.shift(); if ( ct === undefined ) { ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" ); } } // Check if we're dealing with a known content-type if ( ct ) { for ( type in contents ) { if ( contents[ type ] && contents[ type ].test( ct ) ) { dataTypes.unshift( type ); break; } } } // Check to see if we have a response for the expected dataType if ( dataTypes[ 0 ] in responses ) { finalDataType = dataTypes[ 0 ]; } else { // Try convertible dataTypes for ( type in responses ) { if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) { finalDataType = type; break; } if ( !firstDataType ) { firstDataType = type; } } // Or just use first one finalDataType = finalDataType || firstDataType; } // If we found a dataType // We add the dataType to the list if needed // and return the corresponding response if ( finalDataType ) { if ( finalDataType !== dataTypes[ 0 ] ) { dataTypes.unshift( finalDataType ); } return responses[ finalDataType ]; } } /* Chain conversions given the request and the original response * Also sets the responseXXX fields on the jqXHR instance */ function ajaxConvert( s, response, jqXHR, isSuccess ) { var conv2, current, conv, tmp, prev, converters = {}, // Work with a copy of dataTypes in case we need to modify it for conversion dataTypes = s.dataTypes.slice(); // Create converters map with lowercased keys if ( dataTypes[ 1 ] ) { for ( conv in s.converters ) { converters[ conv.toLowerCase() ] = s.converters[ conv ]; } } current = dataTypes.shift(); // Convert to each sequential dataType while ( current ) { if ( s.responseFields[ current ] ) { jqXHR[ s.responseFields[ current ] ] = response; } // Apply the dataFilter if provided if ( !prev && isSuccess && s.dataFilter ) { response = s.dataFilter( response, s.dataType ); } prev = current; current = dataTypes.shift(); if ( current ) { // There's only work to do if current dataType is non-auto if ( current === "*" ) { current = prev; // Convert response if prev dataType is non-auto and differs from current } else if ( prev !== "*" && prev !== current ) { // Seek a direct converter conv = converters[ prev + " " + current ] || converters[ "* " + current ]; // If none found, seek a pair if ( !conv ) { for ( conv2 in converters ) { // If conv2 outputs current tmp = conv2.split( " " ); if ( tmp[ 1 ] === current ) { // If prev can be converted to accepted input conv = converters[ prev + " " + tmp[ 0 ] ] || converters[ "* " + tmp[ 0 ] ]; if ( conv ) { // Condense equivalence converters if ( conv === true ) { conv = converters[ conv2 ]; // Otherwise, insert the intermediate dataType } else if ( converters[ conv2 ] !== true ) { current = tmp[ 0 ]; dataTypes.unshift( tmp[ 1 ] ); } break; } } } } // Apply converter (if not an equivalence) if ( conv !== true ) { // Unless errors are allowed to bubble, catch and return them if ( conv && s.throws ) { response = conv( response ); } else { try { response = conv( response ); } catch ( e ) { return { state: "parsererror", error: conv ? e : "No conversion from " + prev + " to " + current }; } } } } } } return { state: "success", data: response }; } jQuery.extend( { // Counter for holding the number of active queries active: 0, // Last-Modified header cache for next request lastModified: {}, etag: {}, ajaxSettings: { url: location.href, type: "GET", isLocal: rlocalProtocol.test( location.protocol ), global: true, processData: true, async: true, contentType: "application/x-www-form-urlencoded; charset=UTF-8", /* timeout: 0, data: null, dataType: null, username: null, password: null, cache: null, throws: false, traditional: false, headers: {}, */ accepts: { "*": allTypes, text: "text/plain", html: "text/html", xml: "application/xml, text/xml", json: "application/json, text/javascript" }, contents: { xml: /\bxml\b/, html: /\bhtml/, json: /\bjson\b/ }, responseFields: { xml: "responseXML", text: "responseText", json: "responseJSON" }, // Data converters // Keys separate source (or catchall "*") and destination types with a single space converters: { // Convert anything to text "* text": String, // Text to html (true = no transformation) "text html": true, // Evaluate text as a json expression "text json": JSON.parse, // Parse text as xml "text xml": jQuery.parseXML }, // For options that shouldn't be deep extended: // you can add your own custom options here if // and when you create one that shouldn't be // deep extended (see ajaxExtend) flatOptions: { url: true, context: true } }, // Creates a full fledged settings object into target // with both ajaxSettings and settings fields. // If target is omitted, writes into ajaxSettings. ajaxSetup: function( target, settings ) { return settings ? // Building a settings object ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) : // Extending ajaxSettings ajaxExtend( jQuery.ajaxSettings, target ); }, ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), ajaxTransport: addToPrefiltersOrTransports( transports ), // Main method ajax: function( url, options ) { // If url is an object, simulate pre-1.5 signature if ( typeof url === "object" ) { options = url; url = undefined; } // Force options to be an object options = options || {}; var transport, // URL without anti-cache param cacheURL, // Response headers responseHeadersString, responseHeaders, // timeout handle timeoutTimer, // Url cleanup var urlAnchor, // Request state (becomes false upon send and true upon completion) completed, // To know if global events are to be dispatched fireGlobals, // Loop variable i, // uncached part of the url uncached, // Create the final options object s = jQuery.ajaxSetup( {}, options ), // Callbacks context callbackContext = s.context || s, // Context for global events is callbackContext if it is a DOM node or jQuery collection globalEventContext = s.context && ( callbackContext.nodeType || callbackContext.jquery ) ? jQuery( callbackContext ) : jQuery.event, // Deferreds deferred = jQuery.Deferred(), completeDeferred = jQuery.Callbacks( "once memory" ), // Status-dependent callbacks statusCode = s.statusCode || {}, // Headers (they are sent all at once) requestHeaders = {}, requestHeadersNames = {}, // Default abort message strAbort = "canceled", // Fake xhr jqXHR = { readyState: 0, // Builds headers hashtable if needed getResponseHeader: function( key ) { var match; if ( completed ) { if ( !responseHeaders ) { responseHeaders = {}; while ( ( match = rheaders.exec( responseHeadersString ) ) ) { responseHeaders[ match[ 1 ].toLowerCase() ] = match[ 2 ]; } } match = responseHeaders[ key.toLowerCase() ]; } return match == null ? null : match; }, // Raw string getAllResponseHeaders: function() { return completed ? responseHeadersString : null; }, // Caches the header setRequestHeader: function( name, value ) { if ( completed == null ) { name = requestHeadersNames[ name.toLowerCase() ] = requestHeadersNames[ name.toLowerCase() ] || name; requestHeaders[ name ] = value; } return this; }, // Overrides response content-type header overrideMimeType: function( type ) { if ( completed == null ) { s.mimeType = type; } return this; }, // Status-dependent callbacks statusCode: function( map ) { var code; if ( map ) { if ( completed ) { // Execute the appropriate callbacks jqXHR.always( map[ jqXHR.status ] ); } else { // Lazy-add the new callbacks in a way that preserves old ones for ( code in map ) { statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; } } } return this; }, // Cancel the request abort: function( statusText ) { var finalText = statusText || strAbort; if ( transport ) { transport.abort( finalText ); } done( 0, finalText ); return this; } }; // Attach deferreds deferred.promise( jqXHR ); // Add protocol if not provided (prefilters might expect it) // Handle falsy url in the settings object (#10093: consistency with old signature) // We also use the url parameter if available s.url = ( ( url || s.url || location.href ) + "" ) .replace( rprotocol, location.protocol + "//" ); // Alias method option to type as per ticket #12004 s.type = options.method || options.type || s.method || s.type; // Extract dataTypes list s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ]; // A cross-domain request is in order when the origin doesn't match the current origin. if ( s.crossDomain == null ) { urlAnchor = document.createElement( "a" ); // Support: IE <=8 - 11, Edge 12 - 15 // IE throws exception on accessing the href property if url is malformed, // e.g. http://example.com:80x/ try { urlAnchor.href = s.url; // Support: IE <=8 - 11 only // Anchor's host property isn't correctly set when s.url is relative urlAnchor.href = urlAnchor.href; s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !== urlAnchor.protocol + "//" + urlAnchor.host; } catch ( e ) { // If there is an error parsing the URL, assume it is crossDomain, // it can be rejected by the transport if it is invalid s.crossDomain = true; } } // Convert data if not already a string if ( s.data && s.processData && typeof s.data !== "string" ) { s.data = jQuery.param( s.data, s.traditional ); } // Apply prefilters inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); // If request was aborted inside a prefilter, stop there if ( completed ) { return jqXHR; } // We can fire global events as of now if asked to // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118) fireGlobals = jQuery.event && s.global; // Watch for a new set of requests if ( fireGlobals && jQuery.active++ === 0 ) { jQuery.event.trigger( "ajaxStart" ); } // Uppercase the type s.type = s.type.toUpperCase(); // Determine if request has content s.hasContent = !rnoContent.test( s.type ); // Save the URL in case we're toying with the If-Modified-Since // and/or If-None-Match header later on // Remove hash to simplify url manipulation cacheURL = s.url.replace( rhash, "" ); // More options handling for requests with no content if ( !s.hasContent ) { // Remember the hash so we can put it back uncached = s.url.slice( cacheURL.length ); // If data is available and should be processed, append data to url if ( s.data && ( s.processData || typeof s.data === "string" ) ) { cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data; // #9682: remove data so that it's not used in an eventual retry delete s.data; } // Add or update anti-cache param if needed if ( s.cache === false ) { cacheURL = cacheURL.replace( rantiCache, "$1" ); uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce++ ) + uncached; } // Put hash and anti-cache on the URL that will be requested (gh-1732) s.url = cacheURL + uncached; // Change '%20' to '+' if this is encoded form body content (gh-2658) } else if ( s.data && s.processData && ( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) { s.data = s.data.replace( r20, "+" ); } // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. if ( s.ifModified ) { if ( jQuery.lastModified[ cacheURL ] ) { jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] ); } if ( jQuery.etag[ cacheURL ] ) { jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] ); } } // Set the correct header, if data is being sent if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { jqXHR.setRequestHeader( "Content-Type", s.contentType ); } // Set the Accepts header for the server, depending on the dataType jqXHR.setRequestHeader( "Accept", s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ? s.accepts[ s.dataTypes[ 0 ] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : s.accepts[ "*" ] ); // Check for headers option for ( i in s.headers ) { jqXHR.setRequestHeader( i, s.headers[ i ] ); } // Allow custom headers/mimetypes and early abort if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) { // Abort if not done already and return return jqXHR.abort(); } // Aborting is no longer a cancellation strAbort = "abort"; // Install callbacks on deferreds completeDeferred.add( s.complete ); jqXHR.done( s.success ); jqXHR.fail( s.error ); // Get transport transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); // If no transport, we auto-abort if ( !transport ) { done( -1, "No Transport" ); } else { jqXHR.readyState = 1; // Send global event if ( fireGlobals ) { globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); } // If request was aborted inside ajaxSend, stop there if ( completed ) { return jqXHR; } // Timeout if ( s.async && s.timeout > 0 ) { timeoutTimer = window.setTimeout( function() { jqXHR.abort( "timeout" ); }, s.timeout ); } try { completed = false; transport.send( requestHeaders, done ); } catch ( e ) { // Rethrow post-completion exceptions if ( completed ) { throw e; } // Propagate others as results done( -1, e ); } } // Callback for when everything is done function done( status, nativeStatusText, responses, headers ) { var isSuccess, success, error, response, modified, statusText = nativeStatusText; // Ignore repeat invocations if ( completed ) { return; } completed = true; // Clear timeout if it exists if ( timeoutTimer ) { window.clearTimeout( timeoutTimer ); } // Dereference transport for early garbage collection // (no matter how long the jqXHR object will be used) transport = undefined; // Cache response headers responseHeadersString = headers || ""; // Set readyState jqXHR.readyState = status > 0 ? 4 : 0; // Determine if successful isSuccess = status >= 200 && status < 300 || status === 304; // Get response data if ( responses ) { response = ajaxHandleResponses( s, jqXHR, responses ); } // Convert no matter what (that way responseXXX fields are always set) response = ajaxConvert( s, response, jqXHR, isSuccess ); // If successful, handle type chaining if ( isSuccess ) { // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. if ( s.ifModified ) { modified = jqXHR.getResponseHeader( "Last-Modified" ); if ( modified ) { jQuery.lastModified[ cacheURL ] = modified; } modified = jqXHR.getResponseHeader( "etag" ); if ( modified ) { jQuery.etag[ cacheURL ] = modified; } } // if no content if ( status === 204 || s.type === "HEAD" ) { statusText = "nocontent"; // if not modified } else if ( status === 304 ) { statusText = "notmodified"; // If we have data, let's convert it } else { statusText = response.state; success = response.data; error = response.error; isSuccess = !error; } } else { // Extract error from statusText and normalize for non-aborts error = statusText; if ( status || !statusText ) { statusText = "error"; if ( status < 0 ) { status = 0; } } } // Set data for the fake xhr object jqXHR.status = status; jqXHR.statusText = ( nativeStatusText || statusText ) + ""; // Success/Error if ( isSuccess ) { deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); } else { deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); } // Status-dependent callbacks jqXHR.statusCode( statusCode ); statusCode = undefined; if ( fireGlobals ) { globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError", [ jqXHR, s, isSuccess ? success : error ] ); } // Complete completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); if ( fireGlobals ) { globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); // Handle the global AJAX counter if ( !( --jQuery.active ) ) { jQuery.event.trigger( "ajaxStop" ); } } } return jqXHR; }, getJSON: function( url, data, callback ) { return jQuery.get( url, data, callback, "json" ); }, getScript: function( url, callback ) { return jQuery.get( url, undefined, callback, "script" ); } } ); jQuery.each( [ "get", "post" ], function( i, method ) { jQuery[ method ] = function( url, data, callback, type ) { // Shift arguments if data argument was omitted if ( isFunction( data ) ) { type = type || callback; callback = data; data = undefined; } // The url can be an options object (which then must have .url) return jQuery.ajax( jQuery.extend( { url: url, type: method, dataType: type, data: data, success: callback }, jQuery.isPlainObject( url ) && url ) ); }; } ); jQuery._evalUrl = function( url ) { return jQuery.ajax( { url: url, // Make this explicit, since user can override this through ajaxSetup (#11264) type: "GET", dataType: "script", cache: true, async: false, global: false, "throws": true } ); }; jQuery.fn.extend( { wrapAll: function( html ) { var wrap; if ( this[ 0 ] ) { if ( isFunction( html ) ) { html = html.call( this[ 0 ] ); } // The elements to wrap the target around wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true ); if ( this[ 0 ].parentNode ) { wrap.insertBefore( this[ 0 ] ); } wrap.map( function() { var elem = this; while ( elem.firstElementChild ) { elem = elem.firstElementChild; } return elem; } ).append( this ); } return this; }, wrapInner: function( html ) { if ( isFunction( html ) ) { return this.each( function( i ) { jQuery( this ).wrapInner( html.call( this, i ) ); } ); } return this.each( function() { var self = jQuery( this ), contents = self.contents(); if ( contents.length ) { contents.wrapAll( html ); } else { self.append( html ); } } ); }, wrap: function( html ) { var htmlIsFunction = isFunction( html ); return this.each( function( i ) { jQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html ); } ); }, unwrap: function( selector ) { this.parent( selector ).not( "body" ).each( function() { jQuery( this ).replaceWith( this.childNodes ); } ); return this; } } ); jQuery.expr.pseudos.hidden = function( elem ) { return !jQuery.expr.pseudos.visible( elem ); }; jQuery.expr.pseudos.visible = function( elem ) { return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length ); }; jQuery.ajaxSettings.xhr = function() { try { return new window.XMLHttpRequest(); } catch ( e ) {} }; var xhrSuccessStatus = { // File protocol always yields status code 0, assume 200 0: 200, // Support: IE <=9 only // #1450: sometimes IE returns 1223 when it should be 204 1223: 204 }, xhrSupported = jQuery.ajaxSettings.xhr(); support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported ); support.ajax = xhrSupported = !!xhrSupported; jQuery.ajaxTransport( function( options ) { var callback, errorCallback; // Cross domain only allowed if supported through XMLHttpRequest if ( support.cors || xhrSupported && !options.crossDomain ) { return { send: function( headers, complete ) { var i, xhr = options.xhr(); xhr.open( options.type, options.url, options.async, options.username, options.password ); // Apply custom fields if provided if ( options.xhrFields ) { for ( i in options.xhrFields ) { xhr[ i ] = options.xhrFields[ i ]; } } // Override mime type if needed if ( options.mimeType && xhr.overrideMimeType ) { xhr.overrideMimeType( options.mimeType ); } // X-Requested-With header // For cross-domain requests, seeing as conditions for a preflight are // akin to a jigsaw puzzle, we simply never set it to be sure. // (it can always be set on a per-request basis or even using ajaxSetup) // For same-domain requests, won't change header if already provided. if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) { headers[ "X-Requested-With" ] = "XMLHttpRequest"; } // Set headers for ( i in headers ) { xhr.setRequestHeader( i, headers[ i ] ); } // Callback callback = function( type ) { return function() { if ( callback ) { callback = errorCallback = xhr.onload = xhr.onerror = xhr.onabort = xhr.ontimeout = xhr.onreadystatechange = null; if ( type === "abort" ) { xhr.abort(); } else if ( type === "error" ) { // Support: IE <=9 only // On a manual native abort, IE9 throws // errors on any property access that is not readyState if ( typeof xhr.status !== "number" ) { complete( 0, "error" ); } else { complete( // File: protocol always yields status 0; see #8605, #14207 xhr.status, xhr.statusText ); } } else { complete( xhrSuccessStatus[ xhr.status ] || xhr.status, xhr.statusText, // Support: IE <=9 only // IE9 has no XHR2 but throws on binary (trac-11426) // For XHR2 non-text, let the caller handle it (gh-2498) ( xhr.responseType || "text" ) !== "text" || typeof xhr.responseText !== "string" ? { binary: xhr.response } : { text: xhr.responseText }, xhr.getAllResponseHeaders() ); } } }; }; // Listen to events xhr.onload = callback(); errorCallback = xhr.onerror = xhr.ontimeout = callback( "error" ); // Support: IE 9 only // Use onreadystatechange to replace onabort // to handle uncaught aborts if ( xhr.onabort !== undefined ) { xhr.onabort = errorCallback; } else { xhr.onreadystatechange = function() { // Check readyState before timeout as it changes if ( xhr.readyState === 4 ) { // Allow onerror to be called first, // but that will not handle a native abort // Also, save errorCallback to a variable // as xhr.onerror cannot be accessed window.setTimeout( function() { if ( callback ) { errorCallback(); } } ); } }; } // Create the abort callback callback = callback( "abort" ); try { // Do send the request (this may raise an exception) xhr.send( options.hasContent && options.data || null ); } catch ( e ) { // #14683: Only rethrow if this hasn't been notified as an error yet if ( callback ) { throw e; } } }, abort: function() { if ( callback ) { callback(); } } }; } } ); // Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432) jQuery.ajaxPrefilter( function( s ) { if ( s.crossDomain ) { s.contents.script = false; } } ); // Install script dataType jQuery.ajaxSetup( { accepts: { script: "text/javascript, application/javascript, " + "application/ecmascript, application/x-ecmascript" }, contents: { script: /\b(?:java|ecma)script\b/ }, converters: { "text script": function( text ) { jQuery.globalEval( text ); return text; } } } ); // Handle cache's special case and crossDomain jQuery.ajaxPrefilter( "script", function( s ) { if ( s.cache === undefined ) { s.cache = false; } if ( s.crossDomain ) { s.type = "GET"; } } ); // Bind script tag hack transport jQuery.ajaxTransport( "script", function( s ) { // This transport only deals with cross domain requests if ( s.crossDomain ) { var script, callback; return { send: function( _, complete ) { script = jQuery( "

Here find some simple tags


Lorem ipsum dolor sit amet consectetur adipisicing elit. A quo, autem quaerat explicabo impedit mollitia amet molestiae nulla cum architecto ducimus itaque sit blanditiis quasi animi optio ab facilis nihil?

Here are some escaped characters: & (ampersand), à (a with grave), № (numero sign).

This is a form that demonstrates loose attribute formatting

A table with normal closing tags

Pet Features
Feature Cat Dog
Tail
Eyes
Ears
Barking
Litter Box

A table without closing tags

Pet Features
Feature Cat Dog
Tail
Eyes
Ears
Barking
Litter Box

A math section with CDATA

You can add a string to a number, but this stringifies the number:

a / b - 7 = a / b - 7
bat-0.19.0/tests/syntax-tests/source/Haskell/test.hs000064400000000000000000000036270072674642500205470ustar 00000000000000{-# LANGUAGE OverloadedStrings #-} -- simple parser for a Lisp-like syntax I wrote some time ago import Data.Void (Void) import Data.Text (Text) import qualified Data.Text as T import Text.Megaparsec.Char import Text.Megaparsec.Error (errorBundlePretty) import Text.Megaparsec hiding (State) import qualified Text.Megaparsec.Char.Lexer as L data LispVal = Symbol Text | List [LispVal] | Number Integer | String Text | LispTrue | LispFalse | Nil deriving (Show, Eq) type Parser = Parsec Void Text readStr :: Text -> Either String [LispVal] readStr t = case parse pLisp "f" t of Right parsed -> Right parsed Left err -> Left $ errorBundlePretty err {-# INLINABLE readStr #-} sc :: Parser () sc = L.space space1 (L.skipLineComment ";") empty {-# INLINABLE sc #-} lexeme :: Parser a -> Parser a lexeme = L.lexeme sc {-# INLINE lexeme #-} symbol :: Text -> Parser Text symbol = L.symbol sc {-# INLINE symbol #-} symbol' :: Text -> Parser Text symbol' = L.symbol' sc {-# INLINE symbol' #-} pNil :: Parser LispVal pNil = symbol' "nil" >> return Nil {-# INLINE pNil #-} integer :: Parser Integer integer = lexeme L.decimal {-# INLINE integer #-} lispSymbols :: Parser Char lispSymbols = oneOf ("#$%&|*+-/:<=>?@^_~" :: String) {-# INLINE lispSymbols #-} pLispVal :: Parser LispVal pLispVal = choice [pList, pNumber, pSymbol, pNil, pString] {-# INLINE pLispVal #-} pSymbol :: Parser LispVal pSymbol = (Symbol . T.pack <$> lexeme (some (letterChar <|> lispSymbols))) {-# INLINABLE pSymbol #-} pList :: Parser LispVal pList = List <$> between (symbol "(") (symbol ")") (many pLispVal) {-# INLINABLE pList #-} pLisp :: Parser [LispVal] pLisp = some pLispVal {-# INLINE pLisp #-} pNumber :: Parser LispVal pNumber = Number <$> integer {-# INLINE pNumber #-} pString :: Parser LispVal pString = do str <- char '\"' *> manyTill L.charLiteral (char '\"') return $ String (T.pack str) {-# INLINABLE pString #-} bat-0.19.0/tests/syntax-tests/source/Hosts/hosts000064400000000000000000000003740072674642500200300ustar 00000000000000#this is a comment in the hosts file 127.0.0.1 localhost 192.168.0.1 sample.test #a comment 192.160.0.200 try.sample.test try #another comment 216.58.223.238 google.com ::1 localhost.try ip6-localhost bat-0.19.0/tests/syntax-tests/source/INI/test.ini000064400000000000000000000005730072674642500177450ustar 00000000000000[section] key=value numeric = 42 quotes="this value is quoted" quotes2="this is not a comment ;foo" different_quotes='these are other characters' [another one] first = value ; comment on own line ;another one second=value ; comment at the end of a line third = value;another one # is this a comment? maybe. [section.with.dots] [section\with\backspaces] [section;with;semicola] bat-0.19.0/tests/syntax-tests/source/Ignored suffixes/test.rs.bak000064400000000000000000000000740072674642500231270ustar 00000000000000// foo.bak (editor etc backup) should highlight same as foo bat-0.19.0/tests/syntax-tests/source/Ignored suffixes/test.rs.dpkg-dist000064400000000000000000000001030072674642500242510ustar 00000000000000// foo.dpkg-dist (Debian dpkg backup) should highlight same as foo bat-0.19.0/tests/syntax-tests/source/Ignored suffixes/test.rs.dpkg-old000064400000000000000000000001020072674642500240630ustar 00000000000000// foo.dpkg-old (Debian dpkg backup) should highlight same as foo bat-0.19.0/tests/syntax-tests/source/Ignored suffixes/test.rs.in000064400000000000000000000000740072674642500230000ustar 00000000000000// foo.in (build system input) should highlight same as foo bat-0.19.0/tests/syntax-tests/source/Ignored suffixes/test.rs.in.in000064400000000000000000000001200072674642500233750ustar 00000000000000// foo.in.in (build system input, doubly replaced) should highlight same as foo bat-0.19.0/tests/syntax-tests/source/Ignored suffixes/test.rs.old000064400000000000000000000000740072674642500231500ustar 00000000000000// foo.old (editor etc backup) should highlight same as foo bat-0.19.0/tests/syntax-tests/source/Ignored suffixes/test.rs.orig000064400000000000000000000001030072674642500233230ustar 00000000000000// foo.orig (editor, diff etc backup) should highlight same as foo bat-0.19.0/tests/syntax-tests/source/Ignored suffixes/test.rs.orig~000064400000000000000000000001210072674642500235210ustar 00000000000000// foo.orig~ (backup of an editor, diff etc backup) should highlight same as foo bat-0.19.0/tests/syntax-tests/source/Ignored suffixes/test.rs.rpmnew000064400000000000000000000001000072674642500236700ustar 00000000000000// foo.rpmnew (Red Hat rpm backup) should highlight same as foo bat-0.19.0/tests/syntax-tests/source/Ignored suffixes/test.rs.rpmorig000064400000000000000000000001010072674642500240400ustar 00000000000000// foo.rpmorig (Red Hat rpm backup) should highlight same as foo bat-0.19.0/tests/syntax-tests/source/Ignored suffixes/test.rs.rpmsave000064400000000000000000000001010072674642500240360ustar 00000000000000// foo.rpmsave (Red Hat rpm backup) should highlight same as foo bat-0.19.0/tests/syntax-tests/source/Ignored suffixes/test.rs.ucf-dist000064400000000000000000000001010072674642500240770ustar 00000000000000// foo.ucf-dist (Debian ucf backup) should highlight same as foo bat-0.19.0/tests/syntax-tests/source/Ignored suffixes/test.rs.ucf-new000064400000000000000000000001000072674642500237240ustar 00000000000000// foo.ucf-new (Debian ucf backup) should highlight same as foo bat-0.19.0/tests/syntax-tests/source/Ignored suffixes/test.rs.ucf-old000064400000000000000000000001000072674642500237110ustar 00000000000000// foo.ucf-old (Debian ucf backup) should highlight same as foo bat-0.19.0/tests/syntax-tests/source/Ignored suffixes/test.rs~000064400000000000000000000000650072674642500225710ustar 00000000000000// foo~ (editor backup) should highlight same as foo bat-0.19.0/tests/syntax-tests/source/Ignored suffixes/test.unknown~000064400000000000000000000000550072674642500236430ustar 00000000000000// foo~ for unknown foo should not highlight bat-0.19.0/tests/syntax-tests/source/JSON/test.json000064400000000000000000000010030072674642500202560ustar 00000000000000[ { "name": "john", "age": 42, "isCustomer": false, "children": [] }, { "name": "james", "age": 35, "isCustomer": true, "children": [ { "name": "linus", "age": 4 }, { "name": "sandra", "age": 2 } ] }, { "name": "jessica", "age": null, "isCustomer": false, "children": [] } ] bat-0.19.0/tests/syntax-tests/source/Java/test.java000064400000000000000000000016040072674642500203450ustar 00000000000000import java.util.Scanner; /* This Java program was submiited to help bat * with its syntax highlighting tests */ public class Main { public static void main(String[] arg) { Scanner st = new Scanner(System.in); int t; t = st.nextInt(); String tem; tem = st.nextLine(); for(int zz=0;zz <%-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --%> <%@page session="false" contentType="text/html; charset=ISO-8859-1" %> <%@page import="java.util.Enumeration" %> <%@page import="jakarta.servlet.http.HttpSession" %> <%@page import="org.apache.catalina.Session" %> <%@page import="org.apache.catalina.manager.JspHelper" %> <%@page import="org.apache.catalina.util.ContextName" %> <%--!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"--%> <% String path = (String) request.getAttribute("path"); String version = (String) request.getAttribute("version"); ContextName cn = new ContextName(path, version); Session currentSession = (Session)request.getAttribute("currentSession"); String currentSessionId = null; HttpSession currentHttpSession = null; if (currentSession != null) { currentHttpSession = currentSession.getSession(); currentSessionId = JspHelper.escapeXml(currentSession.getId()); } else { currentSessionId = "Session invalidated"; } String submitUrl = JspHelper.escapeXml(response.encodeURL( ((HttpServletRequest) pageContext.getRequest()).getRequestURI() + "?path=" + path + "&version=" + version)); %> Sessions Administration: details for <%= currentSessionId %> <% if (currentHttpSession == null) { %>

<%=currentSessionId%>

<% } else { %>

Details for Session <%= currentSessionId %>

Session Id <%= currentSessionId %>
Guessed Locale <%= JspHelper.guessDisplayLocaleFromSession(currentSession) %>
Guessed User <%= JspHelper.guessDisplayUserFromSession(currentSession) %>
Creation Time <%= JspHelper.getDisplayCreationTimeForSession(currentSession) %>
Last Accessed Time <%= JspHelper.getDisplayLastAccessedTimeForSession(currentSession) %>
Session Max Inactive Interval <%= JspHelper.secondsToTimeString(currentSession.getMaxInactiveInterval()) %>
Used Time <%= JspHelper.getDisplayUsedTimeForSession(currentSession) %>
Inactive Time <%= JspHelper.getDisplayInactiveTimeForSession(currentSession) %>
TTL <%= JspHelper.getDisplayTTLForSession(currentSession) %>
<% if ("Primary".equals(request.getParameter("sessionType"))) { %> <% } %>
<%= JspHelper.escapeXml(request.getAttribute("error")) %>
<%= JspHelper.escapeXml(request.getAttribute("message")) %>
<% int nAttributes = 0; Enumeration attributeNamesEnumeration = currentHttpSession.getAttributeNames(); while (attributeNamesEnumeration.hasMoreElements()) { attributeNamesEnumeration.nextElement(); ++nAttributes; } %> <%--tfoot> <% attributeNamesEnumeration = currentHttpSession.getAttributeNames(); while (attributeNamesEnumeration.hasMoreElements()) { String attributeName = attributeNamesEnumeration.nextElement(); %> <% } // end while %>
<%= JspHelper.formatNumber(nAttributes) %> attributes
Remove Attribute Attribute name Attribute value
TODO: set Max Inactive Interval on sessions
<% if ("Primary".equals(request.getParameter("sessionType"))) { %> <% } else { out.print("Primary sessions only"); } %>
<%= JspHelper.escapeXml(attributeName) %> <% Object attributeValue = currentHttpSession.getAttribute(attributeName); %>"><%= JspHelper.escapeXml(attributeValue) %>
<% } // endif%>

<%--div style="display: none;">

Valid HTML 4.01! Valid XHTML 1.0! Valid XHTML 1.1!

bat-0.19.0/tests/syntax-tests/source/JavaScript/test.js000064400000000000000000000052070072674642500212300ustar 00000000000000let letNumber = 1000; const constNumber = 10; var varNumber = -1234; const constNegativeFloat = -1.23; var tooMuch = Infinity; nothing = null; let listofthings = ["thing", 'thing2', `foo`, ["bar"]]; // Simple comment /** * ######### * Multiline * comment * ######### */ let test; for (let i = 0; i < constNumber; i++) { if (test) continue; else test += 1; // random things } while(test < 100 && typeof test === "number") { test = test > 30 ? test+5 : test+1; } function weatherSays(when=Date.now()) { return "rain"; } const thereAreClouds = true; const cloudsCount = 20; switch(weatherSays(Date.now())) { case 'rain': break; case 'sun': default: break; } let rain = false; if ((thereAreClouds && cloudsCount >= 20) || weatherSays() === "rain") { rain = false; } else if (thereAreClouds && weatherSays() == "rain") { // oh no, unsafe two equals checking! rain = true; } else { rain = !!cloudsCount; } class Forecast { constructor(where, isGonnaRainA=true, isGonnaRainB=false, isGonnaRainC=false, ...randomArgs) { this.station = { location: [where.x, where.y, where.z], surroundings: { zoneA: { location: [1, 2, 3], isGonnaRain: isGonnaRainA }, zoneB: { location: [-1, 2, 2], isGonnaRain: isGonnaRainB }, zoneC: { location: [-2, 0, 0], isGonnaRainC: isGonnaRainC }, } }; } async getLocalPrevisions() { const rainZones = [this.station.surroundings.zoneA.isGonnaRain, this.station.surroundings.zoneB.isGonnaRain, this.station.surroundings.zoneC.isGonnaRain]; return await rainZones.filter(z => !!z).length > (rainZones.length / 2); } communicatePrevisions(isGonnaRain=undefined) { if (isGonnaRain) console.log("Take the umbrella."); } destroy() { delete this.station; } static startHiring() { console.log("We're looking for weather presenters."); console.log("A lot of presenters came. Hiring stops."); } /* This forecasting station is magic. It can generate rain, but this method is secret because it's a generator function - nobody uses them! */ * generateRainInZoneC(clouds=[1, 2, 3]) { this.station.surroundings.zoneC.isGonnaRain = true; const makeRain = () => { return "raining!"; }; yield clouds; // first, keeps clouds do { console.log(makeRain()); yield clouds.pop(); // then all clouds do rain } while(clouds.length >= 1); } } Forecast.startHiring(); const forecasting = new Forecast([3, 3, 3]); (async() => { const raining = forecasting.generateRainInZoneC(); raining.next(); forecasting.communicatePrevisions(await forecasting.getLocalPrevisions()); raining.next(); raining.next(); raining.return("stop!"); forecasting.destroy(); })(); bat-0.19.0/tests/syntax-tests/source/Jinja2/template.jinja2000064400000000000000000000012510072674642500216670ustar 00000000000000{% extends 'base.jinja2' %}

{% block title %}{% endblock %}

{% for entry in entries %} Entry {{ loop.index }} {% if entry.show %}

{{ entry.value }}

{% else if false %}

No value

{% endif %} {% endfor %} {% set some_value = 123 %}
{{ some_value | custom_filter }}, {{ some_value | abs }}
{% endset %} {{ some_dict['val'].val }} {# comment #} {# longer comment {{ value }} #} {% raw %} {{ do not transform }} {% endraw %} {% macro some_macro(value) -%}

{{ value }}

{%- endmacro %} {% if another_val is defined %}

{{ another_val }}

{% else %}

Unknown

{% endif %} bat-0.19.0/tests/syntax-tests/source/Julia/test.jl000064400000000000000000000010250072674642500202110ustar 00000000000000x = 3 y = 2x typeof(y) f(x) = 2 + x f f(10) function g(x, y) z = x + y return z^2 end g(1, 2) let s = 0 for i in 1:10 s += i # Equivalent to s = s + i end s end typeof(1:10) function mysum(n) s = 0 for i in 1:n s += i end return s end mysum(100) a = 3 a < 5 if a < 5 "small" else "big" end v = [1, 2, 3] typeof(v) v[2] v[2] = 10 v2 = [i^2 for i in 1:10] M = [1 2 3 4] typeof(M) zeros(5, 5) zeros(Int, 4, 5) [i + j for i in 1:5, j in 1:6] bat-0.19.0/tests/syntax-tests/source/Kotlin/test.kt000064400000000000000000000035660072674642500204320ustar 00000000000000import kotlin.math.* data class Example( val name: String, val numbers: List ) fun interface JokeInterface { fun isFunny(): Boolean } abstract class AbstractJoke : JokeInterface { override fun isFunny() = false abstract fun content(): String } class Joke : AbstractJoke() { override fun isFunny(): Boolean { return true } override fun content(): String = "content of joke here, haha" } class DelegatedJoke(val joke: Joke) : JokeInterface by joke { val number: Long = 123L companion object { const val someConstant = "some constant text" } } object SomeSingleton sealed class Shape { abstract fun area(): Double } data class Square(val sideLength: Double) : Shape() { override fun area(): Double = sideLength.pow(2) } object Point : Shape() { override fun area() = .0 } class Circle(val radius: Double) : Shape() { override fun area(): Double { return PI * radius * radius } } fun String.extensionMethod() = "test" fun main() { val name = """ multiline string some numbers: 123123 42 """.trimIndent() val example = Example(name = name, numbers = listOf(512, 42, null, -1)) example.numbers .filterNotNull() .forEach { println(it) } setOf(Joke(), DelegatedJoke(Joke()).joke) .filter(JokeInterface::isFunny) .map(AbstractJoke::content) .forEachIndexed { index: Int, joke -> println("I heard a funny joke(#${index + 1}): $joke") } listOf(Square(12.3), Point, Circle(5.2)) .associateWith(Shape::area) .toList() .sortedBy { it.second } .forEach { println("${it.first}: ${it.second}") } println("some string".extensionMethod()) require(SomeSingleton::class.simpleName == "SomeSingletonName") { "something does not seem right..." } } bat-0.19.0/tests/syntax-tests/source/LLVM/test.ll000064400000000000000000000033210072674642500177220ustar 00000000000000; ModuleID = 'test.c' source_filename = "test.c" target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-pc-linux-gnu" @.str = private unnamed_addr constant [13 x i8] c"Hello World!\00", align 1 ; Function Attrs: noinline norecurse optnone uwtable define dso_local i32 @main(i32 %0, i8** %1) #0 { %3 = alloca i32, align 4 %4 = alloca i32, align 4 %5 = alloca i8**, align 8 store i32 0, i32* %3, align 4 store i32 %0, i32* %4, align 4 store i8** %1, i8*** %5, align 8 %6 = call i32 @puts(i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str, i64 0, i64 0)) ret i32 1337 } declare dso_local i32 @puts(i8*) #1 attributes #0 = { noinline norecurse optnone uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } !llvm.module.flags = !{!0} !llvm.ident = !{!1} !0 = !{i32 1, !"wchar_size", i32 4} !1 = !{!"clang version 10.0.0-4ubuntu1 "} bat-0.19.0/tests/syntax-tests/source/Lean/test.lean000064400000000000000000000041650072674642500203460ustar 00000000000000import data.matrix.notation import data.vector2 /-! Helpers that don't currently fit elsewhere... -/ lemma split_eq {m n : Type*} (x : m × n) (p p' : m × n) : p = x ∨ p' = x ∨ (x ≠ p ∧ x ≠ p') := by tauto -- For `playfield`s, the piece type and/or piece index type. variables (X : Type*) variables [has_repr X] namespace chess.utils section repr /-- An auxiliary wrapper for `option X` that allows for overriding the `has_repr` instance for `option`, and rather, output just the value in the `some` and a custom provided `string` for `none`. -/ structure option_wrapper := (val : option X) (none_s : string) instance wrapped_option_repr : has_repr (option_wrapper X) := ⟨λ ⟨val, s⟩, (option.map has_repr.repr val).get_or_else s⟩ variables {X} /-- Construct an `option_wrapper` term from a provided `option X` and the `string` that will override the `has_repr.repr` for `none`. -/ def option_wrap (val : option X) (none_s : string) : option_wrapper X := ⟨val, none_s⟩ -- The size of the "vectors" for a `fin n' → X`, for `has_repr` definitions variables {m' n' : ℕ} /-- For a "vector" `X^n'` represented by the type `Π n' : ℕ, fin n' → X`, where the `X` has a `has_repr` instance itself, we can provide a `has_repr` for the "vector". This definition is used for displaying rows of the playfield, when it is defined via a `matrix`, likely through notation. -/ def vec_repr : Π {n' : ℕ}, (fin n' → X) → string := λ _ v, string.intercalate ", " ((vector.of_fn v).to_list.map repr) instance vec_repr_instance : has_repr (fin n' → X) := ⟨vec_repr⟩ /-- For a `matrix` `X^(m' × n')` where the `X` has a `has_repr` instance itself, we can provide a `has_repr` for the matrix, using `vec_repr` for each of the rows of the matrix. This definition is used for displaying the playfield, when it is defined via a `matrix`, likely through notation. -/ def matrix_repr : Π {m' n'}, matrix (fin m') (fin n') X → string := λ _ _ M, string.intercalate ";\n" ((vector.of_fn M).to_list.map repr) instance matrix_repr_instance : has_repr (matrix (fin n') (fin m') X) := ⟨matrix_repr⟩ end repr end chess.utils bat-0.19.0/tests/syntax-tests/source/Less/example.less000064400000000000000000000016400072674642500210730ustar 00000000000000// Load fonts @import url(https://fonts.googleapis.com/css?family=Lustria|Lato:700); // Color scheme https://kuler.adobe.com/Salmon-on-Ice-color-theme-2291686/ @dk: #3E454C; // dark @hl: #2185C5; // highlight @hll: #7ECEFD; // lighter highlight @lt: #FFF6E5; // light @ct: #FF7F66; // contrast // Sizes @contentWidth: 750px; @marginTop: 50px; @marginSide: 100px; // Fonts and Text @font: 'Lustria', serif; @headerFont: 'Lato', sans; @fontSize: 19px; @fontSizeH1: 50px; @fontSizeH2: 30px; @parSep: 40px; @linkSizeFactor: 0.8; // Sizes for small devices @smallMarginTop: 25px; @smallMarginSide: 25px; @smallFontSize: 18px; @smallFontSizeH1: 40px; @smallFontSizeH2: 28px; @smallParSep: 25px; #wrapper { width: 100%; margin: auto; min-height: 100%; height: auto !important; height: 100%; overflow: hidden !important; position: relative; } bat-0.19.0/tests/syntax-tests/source/Lisp/LICENSE.md000064400000000000000000000022160072674642500201550ustar 00000000000000The `utils.lisp` file has been added from https://github.com/zkat/chillax under the following license: Copyright © 2009-2010 Kat Marchán Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. bat-0.19.0/tests/syntax-tests/source/Lisp/utils.lisp000064400000000000000000000055100072674642500206020ustar 00000000000000(cl:defpackage :chillax.utils (:use :cl :alexandria) (:export :fun :mkhash :hashget :strcat :dequote :at)) (in-package :chillax.utils) ;;; Functions (defmacro fun (&body body) "This macro puts the FUN back in FUNCTION." `(lambda (&optional _) (declare (ignorable _)) ,@body)) ;;; Hash tables (defun mkhash (&rest keys-and-values &aux (table (make-hash-table :test #'equal))) "Convenience function for `literal' hash table definition." (loop for (key val) on keys-and-values by #'cddr do (setf (gethash key table) val) finally (return table))) (defun hashget (hash &rest keys) "Convenience function for recursively accessing hash tables." (reduce (lambda (h k) (gethash k h)) keys :initial-value hash)) (define-compiler-macro hashget (hash &rest keys) (if (null keys) hash (let ((hash-sym (make-symbol "HASH")) (key-syms (loop for i below (length keys) collect (make-symbol (format nil "~:@(~:R~)-KEY" i))))) `(let ((,hash-sym ,hash) ,@(loop for key in keys for sym in key-syms collect `(,sym ,key))) ,(reduce (lambda (hash key) `(gethash ,key ,hash)) key-syms :initial-value hash-sym))))) (defun (setf hashget) (new-value hash key &rest more-keys) "Uses the last key given to hashget to insert NEW-VALUE into the hash table returned by the second-to-last key. tl;dr: DWIM SETF function for HASHGET." (if more-keys (setf (gethash (car (last more-keys)) (apply #'hashget hash key (butlast more-keys))) new-value) (setf (gethash key hash) new-value))) ;;; Strings (defun strcat (string &rest more-strings) (apply #'concatenate 'string string more-strings)) (defun dequote (string) (let ((len (length string))) (if (and (> len 1) (starts-with #\" string) (ends-with #\" string)) (subseq string 1 (- len 1)) string))) ;;; ;;; At ;;; (defgeneric at (doc &rest keys)) (defgeneric (setf at) (new-value doc key &rest more-keys)) (defmethod at ((doc hash-table) &rest keys) (apply #'hashget doc keys)) (defmethod (setf at) (new-value (doc hash-table) key &rest more-keys) (apply #'(setf hashget) new-value doc key more-keys)) (defmethod at ((doc list) &rest keys) (reduce (lambda (alist key) (cdr (assoc key alist :test #'equal))) keys :initial-value doc)) (defmethod (setf at) (new-value (doc list) key &rest more-keys) (if more-keys (setf (cdr (assoc (car (last more-keys)) (apply #'at doc key (butlast more-keys)) :test #'equal)) new-value) (setf (cdr (assoc key doc :test #'equal)) new-value))) ;; A playful alias. (defun @ (doc &rest keys) (apply #'at doc keys)) (defun (setf @) (new-value doc key &rest more-keys) (apply #'(setf at) new-value doc key more-keys)) bat-0.19.0/tests/syntax-tests/source/Literate Haskell/Main.lhs000064400000000000000000000022610072674642500223530ustar 00000000000000\documentclass{article} \begin{document} \section*{Introduction} Text outside code environments should follow TeX/LaTeX highlighting. The code environment delimiters themselves should be highlighted. Text inside code environments should follow regular Haskell highlighting. \begin{code} import Data.List import System.Environment import Text.Printf twoSumN :: Int -> [Int] -> [Int] twoSumN _ [] = [] twoSumN n (x : xs) | (n - x) `elem` xs = [x, n - x] | otherwise = twoSumN n xs threeSumN :: Int -> [Int] -> [Int] threeSumN _ [] = [] threeSumN n (x : xs) | null partial = threeSumN n xs | otherwise = x : partial where partial = twoSumN (n - x) xs \end{code} Text in-between code environments. % LaTeX comment. \begin{code} output :: String -> IO () output path = do input <- sort . map read . filter (not . null) . lines <$> readFile path printf "File: %s\n" path printf " Part 1: %d\n" . product . twoSumN 2020 $ input printf " Part 2: %d\n" . product . threeSumN 2020 $ input -- Haskell comment inside code environment. main :: IO () main = getArgs >>= mapM_ output \end{code} \end{document} bat-0.19.0/tests/syntax-tests/source/LiveScript/LICENSE.md000064400000000000000000000023400072674642500213300ustar 00000000000000The `livescript-demo.ls` file has been added from https://github.com/paulmillr/LiveScript.tmbundle under the following license: The MIT License (MIT) Copyright (c) 2012 Paul Miller (http://paulmillr.com/), Jeremy Ashkenas Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. bat-0.19.0/tests/syntax-tests/source/LiveScript/livescript-demo.ls000064400000000000000000000025410072674642500233750ustar 00000000000000a = -> 1 const b = --> 2 var c = ~> 3 d = ~~> e = (a) -> (b) ~> (c) --> (d, e) ~~> 5 dashes-identifiers = -> a - a b -- c 1-1 1- -1 a- a a -a //abc #eaze #@ // // a #baze // publi if it is \abc and ($-y = !(a,) ->) ~= map //a#// then match that | _ | otherwise => implements $("#abc #@a") switch |a=>b | a then b if a => b else c underscores_i$d = -> /regexp1/ and //regexp2//g 'strings' and "strings" and \strings ([2 til 10] or [1 to 50]) |> map (* 2) |> filter (> 5) |> fold (+) setTimeout _, 3000 <| do-stuff _.map; _abc; __ class Class extends Anc-est-or (args) -> copy = (from, to, callback) --> error, data <- read file return callback error if error? error <~ write file, data return callback error if error? callback() $(\#gafBr).text $t.fmtFloat(efb.gaf) -> ~> ~~> --> # Comment /* Comment */ # error, data <- read file /* error, data <- read file */ add = (a=1, b=2) --> a + b add 1 2 do-stuff! do-stuff? # do-stuff? 1 do-stuff + 1 @do-stuff +1 @do-stuff /1 a b c |> d <| e f(g) 'cats' is 'cats' 'cats' `_.is-insensitive` 'CATS' setTimeout _, 1000 <| !-> console.log 'Who summoned me' private-list = yield @get-private-list! switch | true => "#@@spaghetti" ~function add a=1, b=2 => a + b row.0._id new Spaghetti (++a++) (++ 2 ++) (.cool.) (+ a -) (/ 2 *) (ina -a in) (-> a) (ina in$a) (a is-in) (in) ((((((+ a((a)))))))) bat-0.19.0/tests/syntax-tests/source/Log/example.log000064400000000000000000000002430072674642500205170ustar 000000000000002021-03-06 23:22:21.392 https://[2001:db8:4006:812::200e]:8080/path/the%20page.html 2021-03-06 23:22:21 https://example.com:8080/path/the%20page(with_parens).html bat-0.19.0/tests/syntax-tests/source/Lua/test.lua000064400000000000000000000012750072674642500200510ustar 00000000000000--- Finds factorial of a number. -- @param value Number to find factorial. -- @return Factorial of number. local function factorial(value) if value <= 1 then return 1 else return value * factorial(value - 1) end end --- Joins a table of strings into a new string. -- @param table Table of strings. -- @param separator Separator character. -- @return Joined string. local function join(table, separator) local data = "" for index, value in ipairs(table) do data = data .. value .. separator end data = data:sub(1, data:len() - 1) return data end local a = factorial(5) print(a) local b = join({ "l", "u", "a" }, ",") print(b) bat-0.19.0/tests/syntax-tests/source/MATLAB/LICENSE.md000064400000000000000000000027520072674642500202130ustar 00000000000000The `test.matlab` file is a modified version of https://github.com/pygments/pygments/blob/3e1b79c82d2df318f63f24984d875fd2a3400808/tests/test_matlab.py under the following license: Copyright (c) 2006-2020 by the respective authors (see AUTHORS file). All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. bat-0.19.0/tests/syntax-tests/source/MATLAB/test.matlab000064400000000000000000000011370072674642500207440ustar 00000000000000function zz=sample(aa) %%%%%%%%%%%%%%%%%% % some comments %%%%%%%%%%%%%%%%%% x = 'a string'; % some 'ticks' in a comment y = 'a string with ''interal'' quotes'; for i=1:20 disp(i); end a = rand(30); b = rand(30); c = a .* b ./ a \ ... comment at end of line and continuation (b .* a + b - a); c = a' * b'; % note: these ticks are for transpose, not quotes. disp('a comment symbol, %, in a string'); !echo abc % this isn't a comment - it's passed to system command function y=myfunc(x) y = exp(x); %{ a block comment %} function no_arg_func fprintf('%s\n', 'function with no args') end bat-0.19.0/tests/syntax-tests/source/Makefile/LICENSE.md000064400000000000000000000031650072674642500207670ustar 00000000000000The `Makefile` (https://github.com/redis/redis/blob/6.0.8/src/Makefile) file has been added from Redis (https://github.com/redis/redis) under the following license: Copyright (c) 2006-2020, Salvatore Sanfilippo All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Redis nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.bat-0.19.0/tests/syntax-tests/source/Makefile/Makefile000064400000000000000000000272540072674642500210300ustar 00000000000000# Redis Makefile # Copyright (C) 2009 Salvatore Sanfilippo # This file is released under the BSD license, see the COPYING file # # The Makefile composes the final FINAL_CFLAGS and FINAL_LDFLAGS using # what is needed for Redis plus the standard CFLAGS and LDFLAGS passed. # However when building the dependencies (Jemalloc, Lua, Hiredis, ...) # CFLAGS and LDFLAGS are propagated to the dependencies, so to pass # flags only to be used when compiling / linking Redis itself REDIS_CFLAGS # and REDIS_LDFLAGS are used instead (this is the case of 'make gcov'). # # Dependencies are stored in the Makefile.dep file. To rebuild this file # Just use 'make dep', but this is only needed by developers. release_hdr := $(shell sh -c './mkreleasehdr.sh') uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not') uname_M := $(shell sh -c 'uname -m 2>/dev/null || echo not') OPTIMIZATION?=-O2 DEPENDENCY_TARGETS=hiredis linenoise lua NODEPS:=clean distclean # Default settings STD=-std=c11 -pedantic -DREDIS_STATIC='' ifneq (,$(findstring clang,$(CC))) ifneq (,$(findstring FreeBSD,$(uname_S))) STD+=-Wno-c11-extensions endif endif WARN=-Wall -W -Wno-missing-field-initializers OPT=$(OPTIMIZATION) PREFIX?=/usr/local INSTALL_BIN=$(PREFIX)/bin INSTALL=install PKG_CONFIG?=pkg-config # Default allocator defaults to Jemalloc if it's not an ARM MALLOC=libc ifneq ($(uname_M),armv6l) ifneq ($(uname_M),armv7l) ifeq ($(uname_S),Linux) MALLOC=jemalloc endif endif endif # To get ARM stack traces if Redis crashes we need a special C flag. ifneq (,$(filter aarch64 armv,$(uname_M))) CFLAGS+=-funwind-tables else ifneq (,$(findstring armv,$(uname_M))) CFLAGS+=-funwind-tables endif endif # Backwards compatibility for selecting an allocator ifeq ($(USE_TCMALLOC),yes) MALLOC=tcmalloc endif ifeq ($(USE_TCMALLOC_MINIMAL),yes) MALLOC=tcmalloc_minimal endif ifeq ($(USE_JEMALLOC),yes) MALLOC=jemalloc endif ifeq ($(USE_JEMALLOC),no) MALLOC=libc endif # Override default settings if possible -include .make-settings FINAL_CFLAGS=$(STD) $(WARN) $(OPT) $(DEBUG) $(CFLAGS) $(REDIS_CFLAGS) FINAL_LDFLAGS=$(LDFLAGS) $(REDIS_LDFLAGS) $(DEBUG) FINAL_LIBS=-lm DEBUG=-g -ggdb # Linux ARM needs -latomic at linking time ifneq (,$(filter aarch64 armv,$(uname_M))) FINAL_LIBS+=-latomic else ifneq (,$(findstring armv,$(uname_M))) FINAL_LIBS+=-latomic endif endif ifeq ($(uname_S),SunOS) # SunOS ifneq ($(@@),32bit) CFLAGS+= -m64 LDFLAGS+= -m64 endif DEBUG=-g DEBUG_FLAGS=-g export CFLAGS LDFLAGS DEBUG DEBUG_FLAGS INSTALL=cp -pf FINAL_CFLAGS+= -D__EXTENSIONS__ -D_XPG6 FINAL_LIBS+= -ldl -lnsl -lsocket -lresolv -lpthread -lrt else ifeq ($(uname_S),Darwin) # Darwin FINAL_LIBS+= -ldl OPENSSL_CFLAGS=-I/usr/local/opt/openssl/include OPENSSL_LDFLAGS=-L/usr/local/opt/openssl/lib else ifeq ($(uname_S),AIX) # AIX FINAL_LDFLAGS+= -Wl,-bexpall FINAL_LIBS+=-ldl -pthread -lcrypt -lbsd else ifeq ($(uname_S),OpenBSD) # OpenBSD FINAL_LIBS+= -lpthread ifeq ($(USE_BACKTRACE),yes) FINAL_CFLAGS+= -DUSE_BACKTRACE -I/usr/local/include FINAL_LDFLAGS+= -L/usr/local/lib FINAL_LIBS+= -lexecinfo endif else ifeq ($(uname_S),FreeBSD) # FreeBSD FINAL_LIBS+= -lpthread -lexecinfo else ifeq ($(uname_S),DragonFly) # FreeBSD FINAL_LIBS+= -lpthread -lexecinfo else ifeq ($(uname_S),OpenBSD) # OpenBSD FINAL_LIBS+= -lpthread -lexecinfo else ifeq ($(uname_S),NetBSD) # NetBSD FINAL_LIBS+= -lpthread -lexecinfo else # All the other OSes (notably Linux) FINAL_LDFLAGS+= -rdynamic FINAL_LIBS+=-ldl -pthread -lrt endif endif endif endif endif endif endif endif # Include paths to dependencies FINAL_CFLAGS+= -I../deps/hiredis -I../deps/linenoise -I../deps/lua/src # Determine systemd support and/or build preference (defaulting to auto-detection) BUILD_WITH_SYSTEMD=no # If 'USE_SYSTEMD' in the environment is neither "no" nor "yes", try to # auto-detect libsystemd's presence and link accordingly. ifneq ($(USE_SYSTEMD),no) LIBSYSTEMD_PKGCONFIG := $(shell $(PKG_CONFIG) --exists libsystemd && echo $$?) # If libsystemd cannot be detected, continue building without support for it # (unless a later check tells us otherwise) ifeq ($(LIBSYSTEMD_PKGCONFIG),0) BUILD_WITH_SYSTEMD=yes endif endif ifeq ($(USE_SYSTEMD),yes) ifneq ($(LIBSYSTEMD_PKGCONFIG),0) $(error USE_SYSTEMD is set to "$(USE_SYSTEMD)", but $(PKG_CONFIG) cannot find libsystemd) endif # Force building with libsystemd BUILD_WITH_SYSTEMD=yes endif ifeq ($(BUILD_WITH_SYSTEMD),yes) FINAL_LIBS+=$(shell $(PKG_CONFIG) --libs libsystemd) FINAL_CFLAGS+= -DHAVE_LIBSYSTEMD endif ifeq ($(MALLOC),tcmalloc) FINAL_CFLAGS+= -DUSE_TCMALLOC FINAL_LIBS+= -ltcmalloc endif ifeq ($(MALLOC),tcmalloc_minimal) FINAL_CFLAGS+= -DUSE_TCMALLOC FINAL_LIBS+= -ltcmalloc_minimal endif ifeq ($(MALLOC),jemalloc) DEPENDENCY_TARGETS+= jemalloc FINAL_CFLAGS+= -DUSE_JEMALLOC -I../deps/jemalloc/include FINAL_LIBS := ../deps/jemalloc/lib/libjemalloc.a $(FINAL_LIBS) endif ifeq ($(BUILD_TLS),yes) FINAL_CFLAGS+=-DUSE_OPENSSL $(OPENSSL_CFLAGS) FINAL_LDFLAGS+=$(OPENSSL_LDFLAGS) LIBSSL_PKGCONFIG := $(shell $(PKG_CONFIG) --exists libssl && echo $$?) ifeq ($(LIBSSL_PKGCONFIG),0) LIBSSL_LIBS=$(shell $(PKG_CONFIG) --libs libssl) else LIBSSL_LIBS=-lssl endif LIBCRYPTO_PKGCONFIG := $(shell $(PKG_CONFIG) --exists libcrypto && echo $$?) ifeq ($(LIBCRYPTO_PKGCONFIG),0) LIBCRYPTO_LIBS=$(shell $(PKG_CONFIG) --libs libcrypto) else LIBCRYPTO_LIBS=-lcrypto endif FINAL_LIBS += ../deps/hiredis/libhiredis_ssl.a $(LIBSSL_LIBS) $(LIBCRYPTO_LIBS) endif REDIS_CC=$(QUIET_CC)$(CC) $(FINAL_CFLAGS) REDIS_LD=$(QUIET_LINK)$(CC) $(FINAL_LDFLAGS) REDIS_INSTALL=$(QUIET_INSTALL)$(INSTALL) CCCOLOR="\033[34m" LINKCOLOR="\033[34;1m" SRCCOLOR="\033[33m" BINCOLOR="\033[37;1m" MAKECOLOR="\033[32;1m" ENDCOLOR="\033[0m" ifndef V QUIET_CC = @printf ' %b %b\n' $(CCCOLOR)CC$(ENDCOLOR) $(SRCCOLOR)$@$(ENDCOLOR) 1>&2; QUIET_LINK = @printf ' %b %b\n' $(LINKCOLOR)LINK$(ENDCOLOR) $(BINCOLOR)$@$(ENDCOLOR) 1>&2; QUIET_INSTALL = @printf ' %b %b\n' $(LINKCOLOR)INSTALL$(ENDCOLOR) $(BINCOLOR)$@$(ENDCOLOR) 1>&2; endif REDIS_SERVER_NAME=redis-server REDIS_SENTINEL_NAME=redis-sentinel REDIS_SERVER_OBJ=adlist.o quicklist.o ae.o anet.o dict.o server.o sds.o zmalloc.o lzf_c.o lzf_d.o pqsort.o zipmap.o sha1.o ziplist.o release.o networking.o util.o object.o db.o replication.o rdb.o t_string.o t_list.o t_set.o t_zset.o t_hash.o config.o aof.o pubsub.o multi.o debug.o sort.o intset.o syncio.o cluster.o crc16.o endianconv.o slowlog.o scripting.o bio.o rio.o rand.o memtest.o crcspeed.o crc64.o bitops.o sentinel.o notify.o setproctitle.o blocked.o hyperloglog.o latency.o sparkline.o redis-check-rdb.o redis-check-aof.o geo.o lazyfree.o module.o evict.o expire.o geohash.o geohash_helper.o childinfo.o defrag.o siphash.o rax.o t_stream.o listpack.o localtime.o lolwut.o lolwut5.o lolwut6.o acl.o gopher.o tracking.o connection.o tls.o sha256.o timeout.o setcpuaffinity.o REDIS_CLI_NAME=redis-cli REDIS_CLI_OBJ=anet.o adlist.o dict.o redis-cli.o zmalloc.o release.o ae.o crcspeed.o crc64.o siphash.o crc16.o REDIS_BENCHMARK_NAME=redis-benchmark REDIS_BENCHMARK_OBJ=ae.o anet.o redis-benchmark.o adlist.o dict.o zmalloc.o siphash.o REDIS_CHECK_RDB_NAME=redis-check-rdb REDIS_CHECK_AOF_NAME=redis-check-aof all: $(REDIS_SERVER_NAME) $(REDIS_SENTINEL_NAME) $(REDIS_CLI_NAME) $(REDIS_BENCHMARK_NAME) $(REDIS_CHECK_RDB_NAME) $(REDIS_CHECK_AOF_NAME) @echo "" @echo "Hint: It's a good idea to run 'make test' ;)" @echo "" Makefile.dep: -$(REDIS_CC) -MM *.c > Makefile.dep 2> /dev/null || true ifeq (0, $(words $(findstring $(MAKECMDGOALS), $(NODEPS)))) -include Makefile.dep endif .PHONY: all persist-settings: distclean echo STD=$(STD) >> .make-settings echo WARN=$(WARN) >> .make-settings echo OPT=$(OPT) >> .make-settings echo MALLOC=$(MALLOC) >> .make-settings echo BUILD_TLS=$(BUILD_TLS) >> .make-settings echo USE_SYSTEMD=$(USE_SYSTEMD) >> .make-settings echo CFLAGS=$(CFLAGS) >> .make-settings echo LDFLAGS=$(LDFLAGS) >> .make-settings echo REDIS_CFLAGS=$(REDIS_CFLAGS) >> .make-settings echo REDIS_LDFLAGS=$(REDIS_LDFLAGS) >> .make-settings echo PREV_FINAL_CFLAGS=$(FINAL_CFLAGS) >> .make-settings echo PREV_FINAL_LDFLAGS=$(FINAL_LDFLAGS) >> .make-settings -(cd ../deps && $(MAKE) $(DEPENDENCY_TARGETS)) .PHONY: persist-settings # Prerequisites target .make-prerequisites: @touch $@ # Clean everything, persist settings and build dependencies if anything changed ifneq ($(strip $(PREV_FINAL_CFLAGS)), $(strip $(FINAL_CFLAGS))) .make-prerequisites: persist-settings endif ifneq ($(strip $(PREV_FINAL_LDFLAGS)), $(strip $(FINAL_LDFLAGS))) .make-prerequisites: persist-settings endif # redis-server $(REDIS_SERVER_NAME): $(REDIS_SERVER_OBJ) $(REDIS_LD) -o $@ $^ ../deps/hiredis/libhiredis.a ../deps/lua/src/liblua.a $(FINAL_LIBS) # redis-sentinel $(REDIS_SENTINEL_NAME): $(REDIS_SERVER_NAME) $(REDIS_INSTALL) $(REDIS_SERVER_NAME) $(REDIS_SENTINEL_NAME) # redis-check-rdb $(REDIS_CHECK_RDB_NAME): $(REDIS_SERVER_NAME) $(REDIS_INSTALL) $(REDIS_SERVER_NAME) $(REDIS_CHECK_RDB_NAME) # redis-check-aof $(REDIS_CHECK_AOF_NAME): $(REDIS_SERVER_NAME) $(REDIS_INSTALL) $(REDIS_SERVER_NAME) $(REDIS_CHECK_AOF_NAME) # redis-cli $(REDIS_CLI_NAME): $(REDIS_CLI_OBJ) $(REDIS_LD) -o $@ $^ ../deps/hiredis/libhiredis.a ../deps/linenoise/linenoise.o $(FINAL_LIBS) # redis-benchmark $(REDIS_BENCHMARK_NAME): $(REDIS_BENCHMARK_OBJ) $(REDIS_LD) -o $@ $^ ../deps/hiredis/libhiredis.a $(FINAL_LIBS) dict-benchmark: dict.c zmalloc.c sds.c siphash.c $(REDIS_CC) $(FINAL_CFLAGS) $^ -D DICT_BENCHMARK_MAIN -o $@ $(FINAL_LIBS) DEP = $(REDIS_SERVER_OBJ:%.o=%.d) $(REDIS_CLI_OBJ:%.o=%.d) $(REDIS_BENCHMARK_OBJ:%.o=%.d) -include $(DEP) # Because the jemalloc.h header is generated as a part of the jemalloc build, # building it should complete before building any other object. Instead of # depending on a single artifact, build all dependencies first. %.o: %.c .make-prerequisites $(REDIS_CC) -MMD -o $@ -c $< clean: rm -rf $(REDIS_SERVER_NAME) $(REDIS_SENTINEL_NAME) $(REDIS_CLI_NAME) $(REDIS_BENCHMARK_NAME) $(REDIS_CHECK_RDB_NAME) $(REDIS_CHECK_AOF_NAME) *.o *.gcda *.gcno *.gcov redis.info lcov-html Makefile.dep dict-benchmark rm -f $(DEP) .PHONY: clean distclean: clean -(cd ../deps && $(MAKE) distclean) -(rm -f .make-*) .PHONY: distclean test: $(REDIS_SERVER_NAME) $(REDIS_CHECK_AOF_NAME) @(cd ..; ./runtest) test-sentinel: $(REDIS_SENTINEL_NAME) @(cd ..; ./runtest-sentinel) check: test lcov: $(MAKE) gcov @(set -e; cd ..; ./runtest --clients 1) @geninfo -o redis.info . @genhtml --legend -o lcov-html redis.info test-sds: sds.c sds.h $(REDIS_CC) sds.c zmalloc.c -DSDS_TEST_MAIN $(FINAL_LIBS) -o /tmp/sds_test /tmp/sds_test .PHONY: lcov bench: $(REDIS_BENCHMARK_NAME) ./$(REDIS_BENCHMARK_NAME) 32bit: @echo "" @echo "WARNING: if it fails under Linux you probably need to install libc6-dev-i386" @echo "" $(MAKE) CFLAGS="-m32" LDFLAGS="-m32" gcov: $(MAKE) REDIS_CFLAGS="-fprofile-arcs -ftest-coverage -DCOVERAGE_TEST" REDIS_LDFLAGS="-fprofile-arcs -ftest-coverage" noopt: $(MAKE) OPTIMIZATION="-O0" valgrind: $(MAKE) OPTIMIZATION="-O0" MALLOC="libc" helgrind: $(MAKE) OPTIMIZATION="-O0" MALLOC="libc" CFLAGS="-D__ATOMIC_VAR_FORCE_SYNC_MACROS" src/help.h: @../utils/generate-command-help.rb > help.h install: all @mkdir -p $(INSTALL_BIN) $(REDIS_INSTALL) $(REDIS_SERVER_NAME) $(INSTALL_BIN) $(REDIS_INSTALL) $(REDIS_BENCHMARK_NAME) $(INSTALL_BIN) $(REDIS_INSTALL) $(REDIS_CLI_NAME) $(INSTALL_BIN) $(REDIS_INSTALL) $(REDIS_CHECK_RDB_NAME) $(INSTALL_BIN) $(REDIS_INSTALL) $(REDIS_CHECK_AOF_NAME) $(INSTALL_BIN) @ln -sf $(REDIS_SERVER_NAME) $(INSTALL_BIN)/$(REDIS_SENTINEL_NAME) uninstall: rm -f $(INSTALL_BIN)/{$(REDIS_SERVER_NAME),$(REDIS_BENCHMARK_NAME),$(REDIS_CLI_NAME),$(REDIS_CHECK_RDB_NAME),$(REDIS_CHECK_AOF_NAME),$(REDIS_SENTINEL_NAME)} bat-0.19.0/tests/syntax-tests/source/Manpage/bat-0.16.man000064400000000000000000000220540072674642500210410ustar 00000000000000BAT(1) General Commands Manual BAT(1) NAME bat - a cat(1) clone with syntax highlighting and Git integration. USAGE bat [OPTIONS] [FILE]... bat cache [CACHE-OPTIONS] [--build|--clear] DESCRIPTION bat prints the syntax-highlighted content of a collection of FILEs to the terminal. If no FILE is specified, or when FILE is '-', it reads from standard input. bat supports a large number of programming and markup languages. It also communicates with git(1) to show modifications with respect to the git index. bat automatically pipes its output through a pager (by de‐ fault: less). Whenever the output of bat goes to a non-interactive terminal, i.e. when the output is piped into another process or into a file, bat will act as a drop-in replacement for cat(1) and fall back to printing the plain file contents. OPTIONS General remarks: Command-line options like '-l'/'--language' that take values can be specified as either '--language value', '--lan‐ guage=value', '-l value' or '-lvalue'. -A, --show-all Show non-printable characters like space, tab or newline. Use '--tabs' to control the width of the tab-placeholders. -p, --plain Only show plain style, no decorations. This is an alias for '--style=plain'. When '-p' is used twice ('-pp'), it also dis‐ ables automatic paging (alias for '--style=plain --pager=never'). -l, --language Explicitly set the language for syntax highlighting. The lan‐ guage can be specified as a name (like 'C++' or 'LaTeX') or pos‐ sible file extension (like 'cpp', 'hpp' or 'md'). Use '--list-languages' to show all supported language names and file extensions. -H, --highlight-line ... Highlight the specified line ranges with a different background color For example: --highlight-line 40 highlights line 40 --highlight-line 30:40 highlights lines 30 to 40 --highlight-line :40 highlights lines 1 to 40 --highlight-line 40: highlights lines 40 to the end of the file --tabs Set the tab width to T spaces. Use a width of 0 to pass tabs through directly --wrap Specify the text-wrapping mode (*auto*, never, character). The '--terminal-width' option can be used in addition to control the output width. --terminal-width Explicitly set the width of the terminal instead of determining it automatically. If prefixed with '+' or '-', the value will be treated as an offset to the actual terminal width. See also: '--wrap'. -n, --number Only show line numbers, no other decorations. This is an alias for '--style=numbers' --color Specify when to use colored output. The automatic mode only en‐ ables colors if an interactive terminal is detected. Possible values: *auto*, never, always. --italic-text Specify when to use ANSI sequences for italic text in the out‐ put. Possible values: always, *never*. --decorations Specify when to use the decorations that have been specified via '--style'. The automatic mode only enables decorations if an in‐ teractive terminal is detected. Possible values: *auto*, never, always. -f, --force-colorization Alias for '--decorations=always --color=always'. This is useful if the output of bat is piped to another program, but you want to keep the colorization/decorations. --paging Specify when to use the pager. To disable the pager, use '--pag‐ ing=never' or its alias, -P. To disable the pager permanently, set BAT_PAGER to an empty string. To control which pager is used, see the '--pager' option. Possible values: *auto*, never, always. --pager Determine which pager is used. This option will override the PAGER and BAT_PAGER environment variables. The default pager is 'less'. To control when the pager is used, see the '--paging' option. Example: '--pager "less -RF"'. -m, --map-syntax ... Map a glob pattern to an existing syntax name. The glob pattern is matched on the full path and the filename. For example, to highlight *.build files with the Python syntax, use -m '*.build:Python'. To highlight files named '.myignore' with the Git Ignore syntax, use -m '.myignore:Git Ignore'. --theme Set the theme for syntax highlighting. Use '--list-themes' to see all available themes. To set a default theme, add the '--theme="..."' option to the configuration file or export the BAT_THEME environment variable (e.g.: export BAT_THEME="..."). --list-themes Display a list of supported themes for syntax highlighting. --style Configure which elements (line numbers, file headers, grid bor‐ ders, Git modifications, ..) to display in addition to the file contents. The argument is a comma-separated list of components to display (e.g. 'numbers,changes,grid') or a pre-defined style ('full'). To set a default style, add the '--style=".."' option to the configuration file or export the BAT_STYLE environment variable (e.g.: export BAT_STYLE=".."). Possible values: *auto*, full, plain, changes, header, grid, numbers, snip. -r, --line-range ... Only print the specified range of lines for each file. For exam‐ ple: --line-range 30:40 prints lines 30 to 40 --line-range :40 prints lines 1 to 40 --line-range 40: prints lines 40 to the end of the file -L, --list-languages Display a list of supported languages for syntax highlighting. -u, --unbuffered This option exists for POSIX-compliance reasons ('u' is for 'un‐ buffered'). The output is always unbuffered - this option is simply ignored. -h, --help Print this help message. -V, --version Show version information. POSITIONAL ARGUMENTS ... Files to print and concatenate. Use a dash ('-') or no argument at all to read from standard input. SUBCOMMANDS cache - Modify the syntax-definition and theme cache. FILES bat can also be customized with a configuration file. The location of the file is dependent on your operating system. To get the default path for your system, call: bat --config-file Alternatively, you can use the BAT_CONFIG_PATH environment variable to point bat to a non-default location of the configuration file. ADDING CUSTOM LANGUAGES bat supports Sublime Text .sublime-syntax language files, and can be customized to add additional languages to your local installation. To do this, add the .sublime-snytax language files to `$(bat --config- dir)/syntaxes` and run `bat cache --build`. Example: mkdir -p "$(bat --config-dir)/syntaxes" cd "$(bat --config-dir)/syntaxes" # Put new '.sublime-syntax' language definition files # in this folder (or its subdirectories), for example: git clone https://github.com/tellnobody1/sublime-purescript-syntax # And then build the cache. bat cache --build Once the cache is built, the new language will be visible in `bat --list-languages`. If you ever want to remove the custom languages, you can clear the cache with `bat cache --clear`. ADDING CUSTOM THEMES Similarly to custom languages, bat supports Sublime Text .tmTheme themes. These can be installed to `$(bat --config-dir)/themes`, and are added to the cache with `bat cache --build`. MORE INFORMATION For more information and up-to-date documentation, visit the bat repo: https://github.com/sharkdp/bat BAT(1) bat-0.19.0/tests/syntax-tests/source/Manpage/select-2.man000064400000000000000000000442540072674642500213350ustar 00000000000000SELECT(2) Linux Programmer's Manual SELECT(2) NAME select, pselect, FD_CLR, FD_ISSET, FD_SET, FD_ZERO - synchronous I/O multiplexing SYNOPSIS #include int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); void FD_CLR(int fd, fd_set *set); int FD_ISSET(int fd, fd_set *set); void FD_SET(int fd, fd_set *set); void FD_ZERO(fd_set *set); int pselect(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, const struct timespec *timeout, const sigset_t *sigmask); Feature Test Macro Requirements for glibc (see feature_test_macros(7)): pselect(): _POSIX_C_SOURCE >= 200112L DESCRIPTION select() allows a program to monitor multiple file descriptors, waiting until one or more of the file descriptors become "ready" for some class of I/O operation (e.g., input possible). A file descriptor is considered ready if it is possible to perform a corresponding I/O operation (e.g., read(2), or a sufficiently small write(2)) without blocking. select() can monitor only file descriptors numbers that are less than FD_SETSIZE; poll(2) and epoll(7) do not have this limi‐ tation. See BUGS. File descriptor sets The principal arguments of select() are three "sets" of file descriptors (declared with the type fd_set), which allow the caller to wait for three classes of events on the specified set of file descriptors. Each of the fd_set arguments may be specified as NULL if no file descriptors are to be watched for the corresponding class of events. Note well: Upon return, each of the file descriptor sets is modified in place to indicate which file descriptors are currently "ready". Thus, if using select() within a loop, the sets must be reinitialized before each call. The implementation of the fd_set arguments as value-result arguments is a design error that is avoided in poll(2) and epoll(7). The contents of a file descriptor set can be manipulated using the following macros: FD_ZERO() This macro clears (removes all file descriptors from) set. It should be employed as the first step in initializing a file descriptor set. FD_SET() This macro adds the file descriptor fd to set. Adding a file descriptor that is already present in the set is a no-op, and does not produce an error. FD_CLR() This macro removes the file descriptor fd from set. Removing a file descriptor that is not present in the set is a no- op, and does not produce an error. FD_ISSET() select() modifies the contents of the sets according to the rules described below. After calling select(), the FD_IS‐ SET() macro can be used to test if a file descriptor is still present in a set. FD_ISSET() returns nonzero if the file descriptor fd is present in set, and zero if it is not. Arguments The arguments of select() are as follows: readfds The file descriptors in this set are watched to see if they are ready for reading. A file descriptor is ready for reading if a read operation will not block; in particular, a file descriptor is also ready on end-of-file. After select() has returned, readfds will be cleared of all file descriptors except for those that are ready for read‐ ing. writefds The file descriptors in this set are watched to see if they are ready for writing. A file descriptor is ready for writing if a write operation will not block. However, even if a file descriptor indicates as writable, a large write may still block. After select() has returned, writefds will be cleared of all file descriptors except for those that are ready for writ‐ ing. exceptfds The file descriptors in this set are watched for "exceptional conditions". For examples of some exceptional condi‐ tions, see the discussion of POLLPRI in poll(2). After select() has returned, exceptfds will be cleared of all file descriptors except for those for which an excep‐ tional condition has occurred. nfds This argument should be set to the highest-numbered file descriptor in any of the three sets, plus 1. The indicated file descriptors in each set are checked, up to this limit (but see BUGS). timeout The timeout argument is a timeval structure (shown below) that specifies the interval that select() should block wait‐ ing for a file descriptor to become ready. The call will block until either: • a file descriptor becomes ready; • the call is interrupted by a signal handler; or • the timeout expires. Note that the timeout interval will be rounded up to the system clock granularity, and kernel scheduling delays mean that the blocking interval may overrun by a small amount. If both fields of the timeval structure are zero, then select() returns immediately. (This is useful for polling.) If timeout is specified as NULL, select() blocks indefinitely waiting for a file descriptor to become ready. pselect() The pselect() system call allows an application to safely wait until either a file descriptor becomes ready or until a signal is caught. The operation of select() and pselect() is identical, other than these three differences: • select() uses a timeout that is a struct timeval (with seconds and microseconds), while pselect() uses a struct timespec (with seconds and nanoseconds). • select() may update the timeout argument to indicate how much time was left. pselect() does not change this argument. • select() has no sigmask argument, and behaves as pselect() called with NULL sigmask. sigmask is a pointer to a signal mask (see sigprocmask(2)); if it is not NULL, then pselect() first replaces the current sig‐ nal mask by the one pointed to by sigmask, then does the "select" function, and then restores the original signal mask. (If sigmask is NULL, the signal mask is not modified during the pselect() call.) Other than the difference in the precision of the timeout argument, the following pselect() call: ready = pselect(nfds, &readfds, &writefds, &exceptfds, timeout, &sigmask); is equivalent to atomically executing the following calls: sigset_t origmask; pthread_sigmask(SIG_SETMASK, &sigmask, &origmask); ready = select(nfds, &readfds, &writefds, &exceptfds, timeout); pthread_sigmask(SIG_SETMASK, &origmask, NULL); The reason that pselect() is needed is that if one wants to wait for either a signal or for a file descriptor to become ready, then an atomic test is needed to prevent race conditions. (Suppose the signal handler sets a global flag and returns. Then a test of this global flag followed by a call of select() could hang indefinitely if the signal arrived just after the test but just before the call. By contrast, pselect() allows one to first block signals, handle the signals that have come in, then call pselect() with the desired sigmask, avoiding the race.) The timeout The timeout argument for select() is a structure of the following type: struct timeval { time_t tv_sec; /* seconds */ suseconds_t tv_usec; /* microseconds */ }; The corresponding argument for pselect() has the following type: struct timespec { time_t tv_sec; /* seconds */ long tv_nsec; /* nanoseconds */ }; On Linux, select() modifies timeout to reflect the amount of time not slept; most other implementations do not do this. (POSIX.1 permits either behavior.) This causes problems both when Linux code which reads timeout is ported to other operating systems, and when code is ported to Linux that reuses a struct timeval for multiple select()s in a loop without reinitializing it. Consider timeout to be undefined after select() returns. RETURN VALUE On success, select() and pselect() return the number of file descriptors contained in the three returned descriptor sets (that is, the total number of bits that are set in readfds, writefds, exceptfds). The return value may be zero if the timeout ex‐ pired before any file descriptors became ready. On error, -1 is returned, and errno is set to indicate the error; the file descriptor sets are unmodified, and timeout becomes undefined. ERRORS EBADF An invalid file descriptor was given in one of the sets. (Perhaps a file descriptor that was already closed, or one on which an error has occurred.) However, see BUGS. EINTR A signal was caught; see signal(7). EINVAL nfds is negative or exceeds the RLIMIT_NOFILE resource limit (see getrlimit(2)). EINVAL The value contained within timeout is invalid. ENOMEM Unable to allocate memory for internal tables. VERSIONS pselect() was added to Linux in kernel 2.6.16. Prior to this, pselect() was emulated in glibc (but see BUGS). CONFORMING TO select() conforms to POSIX.1-2001, POSIX.1-2008, and 4.4BSD (select() first appeared in 4.2BSD). Generally portable to/from non-BSD systems supporting clones of the BSD socket layer (including System V variants). However, note that the System V variant typically sets the timeout variable before returning, but the BSD variant does not. pselect() is defined in POSIX.1g, and in POSIX.1-2001 and POSIX.1-2008. NOTES An fd_set is a fixed size buffer. Executing FD_CLR() or FD_SET() with a value of fd that is negative or is equal to or larger than FD_SETSIZE will result in undefined behavior. Moreover, POSIX requires fd to be a valid file descriptor. The operation of select() and pselect() is not affected by the O_NONBLOCK flag. On some other UNIX systems, select() can fail with the error EAGAIN if the system fails to allocate kernel-internal resources, rather than ENOMEM as Linux does. POSIX specifies this error for poll(2), but not for select(). Portable programs may wish to check for EAGAIN and loop, just as with EINTR. The self-pipe trick On systems that lack pselect(), reliable (and more portable) signal trapping can be achieved using the self-pipe trick. In this technique, a signal handler writes a byte to a pipe whose other end is monitored by select() in the main program. (To avoid possibly blocking when writing to a pipe that may be full or reading from a pipe that may be empty, nonblocking I/O is used when reading from and writing to the pipe.) Emulating usleep(3) Before the advent of usleep(3), some code employed a call to select() with all three sets empty, nfds zero, and a non-NULL timeout as a fairly portable way to sleep with subsecond precision. Correspondence between select() and poll() notifications Within the Linux kernel source, we find the following definitions which show the correspondence between the readable, writable, and exceptional condition notifications of select() and the event notifications provided by poll(2) and epoll(7): #define POLLIN_SET (EPOLLRDNORM | EPOLLRDBAND | EPOLLIN | EPOLLHUP | EPOLLERR) /* Ready for reading */ #define POLLOUT_SET (EPOLLWRBAND | EPOLLWRNORM | EPOLLOUT | EPOLLERR) /* Ready for writing */ #define POLLEX_SET (EPOLLPRI) /* Exceptional condition */ Multithreaded applications If a file descriptor being monitored by select() is closed in another thread, the result is unspecified. On some UNIX sys‐ tems, select() unblocks and returns, with an indication that the file descriptor is ready (a subsequent I/O operation will likely fail with an error, unless another process reopens file descriptor between the time select() returned and the I/O oper‐ ation is performed). On Linux (and some other systems), closing the file descriptor in another thread has no effect on se‐ lect(). In summary, any application that relies on a particular behavior in this scenario must be considered buggy. C library/kernel differences The Linux kernel allows file descriptor sets of arbitrary size, determining the length of the sets to be checked from the value of nfds. However, in the glibc implementation, the fd_set type is fixed in size. See also BUGS. The pselect() interface described in this page is implemented by glibc. The underlying Linux system call is named pselect6(). This system call has somewhat different behavior from the glibc wrapper function. The Linux pselect6() system call modifies its timeout argument. However, the glibc wrapper function hides this behavior by using a local variable for the timeout argument that is passed to the system call. Thus, the glibc pselect() function does not modify its timeout argument; this is the behavior required by POSIX.1-2001. The final argument of the pselect6() system call is not a sigset_t * pointer, but is instead a structure of the form: struct { const kernel_sigset_t *ss; /* Pointer to signal set */ size_t ss_len; /* Size (in bytes) of object pointed to by 'ss' */ }; This allows the system call to obtain both a pointer to the signal set and its size, while allowing for the fact that most ar‐ chitectures support a maximum of 6 arguments to a system call. See sigprocmask(2) for a discussion of the difference between the kernel and libc notion of the signal set. Historical glibc details Glibc 2.0 provided an incorrect version of pselect() that did not take a sigmask argument. In glibc versions 2.1 to 2.2.1, one must define _GNU_SOURCE in order to obtain the declaration of pselect() from . BUGS POSIX allows an implementation to define an upper limit, advertised via the constant FD_SETSIZE, on the range of file descrip‐ tors that can be specified in a file descriptor set. The Linux kernel imposes no fixed limit, but the glibc implementation makes fd_set a fixed-size type, with FD_SETSIZE defined as 1024, and the FD_*() macros operating according to that limit. To monitor file descriptors greater than 1023, use poll(2) or epoll(7) instead. According to POSIX, select() should check all specified file descriptors in the three file descriptor sets, up to the limit nfds-1. However, the current implementation ignores any file descriptor in these sets that is greater than the maximum file descriptor number that the process currently has open. According to POSIX, any such file descriptor that is specified in one of the sets should result in the error EBADF. Starting with version 2.1, glibc provided an emulation of pselect() that was implemented using sigprocmask(2) and select(). This implementation remained vulnerable to the very race condition that pselect() was designed to prevent. Modern versions of glibc use the (race-free) pselect() system call on kernels where it is provided. On Linux, select() may report a socket file descriptor as "ready for reading", while nevertheless a subsequent read blocks. This could for example happen when data has arrived but upon examination has the wrong checksum and is discarded. There may be other circumstances in which a file descriptor is spuriously reported as ready. Thus it may be safer to use O_NONBLOCK on sockets that should not block. On Linux, select() also modifies timeout if the call is interrupted by a signal handler (i.e., the EINTR error return). This is not permitted by POSIX.1. The Linux pselect() system call has the same behavior, but the glibc wrapper hides this behavior by internally copying the timeout to a local variable and passing that variable to the system call. EXAMPLES #include #include #include int main(void) { fd_set rfds; struct timeval tv; int retval; /* Watch stdin (fd 0) to see when it has input. */ FD_ZERO(&rfds); FD_SET(0, &rfds); /* Wait up to five seconds. */ tv.tv_sec = 5; tv.tv_usec = 0; retval = select(1, &rfds, NULL, NULL, &tv); /* Don't rely on the value of tv now! */ if (retval == -1) perror("select()"); else if (retval) printf("Data is available now.\n"); /* FD_ISSET(0, &rfds) will be true. */ else printf("No data within five seconds.\n"); exit(EXIT_SUCCESS); } SEE ALSO accept(2), connect(2), poll(2), read(2), recv(2), restart_syscall(2), send(2), sigprocmask(2), write(2), epoll(7), time(7) For a tutorial with discussion and examples, see select_tut(2). COLOPHON This page is part of release 5.08 of the Linux man-pages project. A description of the project, information about reporting bugs, and the latest version of this page, can be found at https://www.kernel.org/doc/man-pages/. Linux 2020-04-11 SELECT(2) bat-0.19.0/tests/syntax-tests/source/Markdown/example.md000064400000000000000000000014140072674642500214000ustar 00000000000000# H1 ## H2 ### H3 #### H4 ##### H5 ###### H6 **bold** *italic* ~~strike~~ [~~***link***~~](https://guides.github.com/features/mastering-markdown/) __bold__ _italic_ * Unordered * List * With Indents 1. Ordered 2. List 3. With Indents ![Markdown Logo](https://upload.wikimedia.org/wikipedia/commons/4/48/Markdown-mark.svg) > quotes > and more `fn inline_code() -> String { "inline code".to_string() }` ```rust fn syntax_highlighted>(thing: T) { println!("The best code has syntax highlighting: {}", thing); } ``` - [x] Task - [] Unfinished Task - [] Another unfinished task First Header | Second Header ------------ | ------------- Content from cell 1 | Content from cell 2 Content in the first column | Content in the second column bat-0.19.0/tests/syntax-tests/source/MediaWiki/test.mediawiki000064400000000000000000000010110072674642500223410ustar 00000000000000= Heading 1 = == Heading 2 == === Heading 3 === ==== Heading 4 ==== ===== Heading 5 ===== ====== Heading 6 ====== == Lists == * Unordered * lists ** with nested *** elements # Ordered # lists ## with nested ### elements ; Description : lists with single definition ; Description : lists : with more : definitions == Text formatting == ''italic text'' '''bold text''' '''''bold italic text''''' == Links == [https://www.wikipedia.org/ Wikipedia] == Images == [[File:MediaWiki-2020-logo.svg|thumb|MediaWiki logo]] bat-0.19.0/tests/syntax-tests/source/MemInfo/test.meminfo000064400000000000000000000027030072674642500215300ustar 00000000000000MemTotal: 1004892 kB MemFree: 109424 kB MemAvailable: 498032 kB Buffers: 66360 kB Cached: 448344 kB SwapCached: 0 kB Active: 547076 kB Inactive: 196864 kB Active(anon): 249956 kB Inactive(anon): 7328 kB Active(file): 297120 kB Inactive(file): 189536 kB Unevictable: 18516 kB Mlocked: 18516 kB SwapTotal: 0 kB SwapFree: 0 kB Dirty: 276 kB Writeback: 0 kB AnonPages: 247780 kB Mapped: 168472 kB Shmem: 19860 kB KReclaimable: 59128 kB Slab: 108616 kB SReclaimable: 59128 kB SUnreclaim: 49488 kB KernelStack: 2060 kB PageTables: 4232 kB NFS_Unstable: 0 kB Bounce: 0 kB WritebackTmp: 0 kB CommitLimit: 502444 kB Committed_AS: 678300 kB VmallocTotal: 34359738367 kB VmallocUsed: 10756 kB VmallocChunk: 0 kB Percpu: 784 kB HardwareCorrupted: 0 kB AnonHugePages: 0 kB ShmemHugePages: 0 kB ShmemPmdMapped: 0 kB FileHugePages: 0 kB FilePmdMapped: 0 kB CmaTotal: 0 kB CmaFree: 0 kB HugePages_Total: 0 HugePages_Free: 0 HugePages_Rsvd: 0 HugePages_Surp: 0 Hugepagesize: 2048 kB Hugetlb: 0 kB DirectMap4k: 118764 kB DirectMap2M: 929792 kB DirectMap1G: 0 kB bat-0.19.0/tests/syntax-tests/source/NAnt Build File/Default.build000064400000000000000000000150130072674642500227660ustar 00000000000000 bat-0.19.0/tests/syntax-tests/source/NAnt Build File/LICENSE.md000064400000000000000000000022630072674642500217700ustar 00000000000000The `Default.build` file has been added from https://github.com/tillig/nant-tasks under the following license: ```text The MIT License (MIT) Copyright (c) 2009 Travis Illig Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ``` bat-0.19.0/tests/syntax-tests/source/Ninja/LICENSE.md000064400000000000000000000263140072674642500203120ustar 00000000000000The `test.ninja` file has been added from [https://ninja-build.org/manual.html] under the following license: Apache License Version 2.0, January 2010 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. bat-0.19.0/tests/syntax-tests/source/Ninja/test.ninja000064400000000000000000000001260072674642500206770ustar 00000000000000cflags = -Wall rule cc command = gcc $cflags -c $in -o $out build foo.o: cc foo.c bat-0.19.0/tests/syntax-tests/source/OCaml/syntax-test.ml000064400000000000000000000027720072674642500215010ustar 00000000000000let s = "hello world" let n : int = 87 let id x = x let add x y = x + y let add' x y = let left = x in let right = y in x + y let add'' : int -> int -> int = fun x -> fun y -> x + y let unwrap_option default opt = match opt with | None -> default | Some v -> v let string_of_bool = function true -> "true" | false -> "false" let is_a c = if c = 'a' then true else false let _ = Printf.printf "%s" "hello" let () = Printf.printf "%s\n" "world" let x = ref 0 let _ = x := 1 type my_bool = True | False type shape = Circle of float | Square of float | Rectangle of (float * float) type user = { login : string; password : string; } type 'a my_ref = { mutable ref_value : 'a } let (:=) r v = r.ref_value <- v let (+) 2 2 = 5 exception Bad_value of string let bad_value_error () = raise (Bad_value "your value is bad and you should feel bad") let () = try bad_value_error () with Bad_value _ -> () let () = try bad_value_error () with | Bad_value _ -> () | Not_found -> () module type FOO = sig val foo : 'a -> 'a end module Foo : FOO = struct let foo x = x end let greeter = object val greeting = "Hello" method greet name = Printf.sprintf "%s, %s!" greeting name end let greeting = greeter#greet "world" class greeter_factory greeting_text = object (self) val greeting = greeting_text method greet name = Printf.sprintf "%s, %s!" greeting name initializer Printf.printf "Objects will greet the user with \"%s\"\n" greeting end let g = new greeter_factory "Hi" bat-0.19.0/tests/syntax-tests/source/Objective-C/test.m000064400000000000000000000010360072674642500210700ustar 00000000000000#import @import Foundation // Single line comments /* * Multi line comment */ int main (int argc, const char * argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; NSLog(@"Storage size for int : %d \n", sizeof(int)); NSLog (@"hello world"); if (NO) { NSLog(@"I am never run"); } else if (0) { NSLog(@"I am also never run"); } else { NSLog(@"I print"); } [pool drain]; return 0; } @implementation MyClass { long distance; NSNumber height; } bat-0.19.0/tests/syntax-tests/source/Objective-C++/test.mm000064400000000000000000000023110072674642500213700ustar 00000000000000#import class Hello { private: id greeting_text; public: Hello() { greeting_text = @"Hello, world!"; } Hello(const char* initial_greeting_text) { greeting_text = [[NSString alloc] initWithUTF8String:initial_greeting_text]; } void say_hello() { printf("%s\n", [greeting_text UTF8String]); } }; @interface Greeting : NSObject { @private Hello *hello; } - (id)init; - (void)dealloc; - (void)sayGreeting; - (void)sayGreeting:(Hello*)greeting; @end @implementation Greeting - (id)init { self = [super init]; if (self) { hello = new Hello(); } return self; } - (void)dealloc { delete hello; [super dealloc]; } - (void)sayGreeting { hello->say_hello(); } - (void)sayGreeting:(Hello*)greeting { greeting->say_hello(); } @end int main() { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; Greeting *greeting = [[Greeting alloc] init]; [greeting sayGreeting]; Hello *hello = new Hello("Bonjour, monde!"); [greeting sayGreeting:hello]; delete hello; [greeting release]; [pool release]; return 0; } bat-0.19.0/tests/syntax-tests/source/PHP/test.php000064400000000000000000000032070072674642500177620ustar 00000000000000= 3 || $numberone <=2) && $numberone != 2.5){ echo "what a number!!!"; } if($numberone >= 3 and $numberone <=2 and $numberone != 2.5){ echo "something is wrong, this is supposed to be impossible"; } if ($number < 3){ $languages = array("HTML", "CSS", "JS"); print_r($languages); echo $languages[2]; print $languages[$number]; } elseif ($number == 3 ){ function favMovie() { echo "JUMAJI"; return true; } favMovie(); } else { switch ($number) { case 4: echo "fours"; break; default: echo "I dont know you"; } } while($number <= 6 ){ echo $number; $number++; $number += 1; } do { $number++; } while ($number < 10); for ($houses = 0; $houses <= 5; $housees++){ break; echo "getting more houses"; } class Person { public $name; public $age; function __construct($name){ $this->name = $name; } function __destruct(){ echo "On my way out"; } function setName($name) { $this->name = $name; } } $doe = new Person("John Do"); $doe->setName('John Doe'); $ending = 2 > 3 ? "yep" : "nah"; ?> bat-0.19.0/tests/syntax-tests/source/Pascal/test.pas000064400000000000000000000012250072674642500205300ustar 00000000000000program Hello; uses crt; type str = string[1]; arr = array[1..20, 1..60] of char; var x, y:integer; carr:arr; c:char; Procedure start; {comment here} begin write (' Press enter to begin. '); readln; end; Function Valid (var choice:char): boolean; begin valid:= false; case choice of '1':valid:= true; '2': valid:= true; '3': valid:= true; '4': valid:= true; '5': valid:= true; '6': valid:= true; end; end; begin for y:=1 to 3 do begin writeln (y); end; repeat writeln(y); y := y + 1; until y > 5; writeln ('Hello World'); end. bat-0.19.0/tests/syntax-tests/source/Passwd/passwd000064400000000000000000000004270072674642500203310ustar 00000000000000root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin syslog:x:104:106::/nonexistent:/usr/sbin/nologin sshd:x:109:65534::/run/sshd:/usr/sbin/nologin reima:x:1000:1000:,,,:/home/reima:/bin/bash bat-0.19.0/tests/syntax-tests/source/Perl/test.pl000064400000000000000000000063500072674642500200630ustar 00000000000000# Perl Test # By saul-bt # PUBLIC DOMAIN use strict; use warnings; ## REFERENCES ## my @colors = ("red", "green", "blue"); # '\' can be used to get a reference my $colorsRef = \@colors; my %superHash = ( "colors" => $colorsRef, # Also you can create an anonymous # array with '[]' ({} for hashes) # that returns the reference "numbers" => [1, 2, 3] ); # Now the hash stores something like # this: ("colors", ARRAY(0x...), # "numbers", ARRAY(0x...)) # And you can access these arrays with: print qq(@{$superHash{"colors"}}\n); # To print an element: print qq(${$superHash{"numbers"}}[0]\n); print $superHash{"colors"} -> [0], "\n"; # Size of array: print scalar @{$superHash{"colors"}}; ## ARRAYS ## %meh1 = (num => 0, val => 4); %meh2 = ( num => 1, val => 3 ); @mehs = (\%meh1, \%meh2); print $mehs[0]{val}; ## HANDLERS & HEREDOC ## print "What's your name? "; $name = ; chomp($name); print <; chomp($place); print <) { print $line; } print "What are you looking for? "; $numResults = 0; $word = ; chomp($word); for $line (<>) { if ($line =~ m/\b$word\b/i) { $numResults += 1; print "[$word FOUND]> $line\n"; next; } print $line; } print "\n\n=== There are $numResults coincidences ==="; ## SCRIPT ARGUMENTS ## $nargs = $#ARGV + 1; print "There are $nargs arguments:\n"; for $arg (@ARGV) { print "- $arg\n"; } ## REGEX STUFF ## $string = "Perl is cool"; if ($string =~ m/[Pp]erl/) { print "Yeah"; } elsif ($string =~ m(perl)i) { print "Sad"; } else { print "MEH"; } # From my dummy recreation of printf sub checkTypes { my @percents = @{scalar(shift)}; my @args = @{scalar(shift)}; my $size = scalar(@percents); foreach my $n (0..$size - 1) { my $currArg = $args[$n]; my $currFormat = substr($percents[$n],-1); $currFormat eq 's' && $currArg =~ m/^\D+$/ || $currFormat =~ m/[dx]/ && $currArg =~ m/^\d+$/ || $currFormat eq 'f' && $currArg =~ m/^\d+(?:\.\d+)?$/ or die "'$currArg' can't be formatted as '$currFormat'"; } } ## WEIRD STUFF (JAPH) ## # VMS <3 not exp log srand xor s qq qx xor s x x length uc ord and print chr ord for qw q join use sub tied qx xor eval xor print qq q q xor int eval lc q m cos and print chr ord for qw y abs ne open tied hex exp ref y m xor scalar srand print qq q q xor int eval lc qq y sqrt cos and print chr ord for qw x printf each return local x y or print qq s s and eval q s undef or oct xor time xor ref print chr int ord lc foreach qw y hex alarm chdir kill exec return y s gt sin sort split @P=split//,".URRUU\c8R";@d=split//,"\nrekcah xinU / lreP rehtona tsuJ";sub p{ @p{"r$p","u$p"}=(P,P);pipe"r$p","u$p";++$p;($q*=2)+=$f=!fork;map{$P=$P[$f^ord ($p{$_})&6];$p{$_}=/ ^$P/ix?$P:close$_}keys%p}p;p;p;p;p;map{$p{$_}=~/^[P.]/&& close$_}%p;wait until$?;map{/^r/&&<$_>}%p;$_=$d[$q];sleep rand(2)if/\S/;print ''=~('(?{'.('-)@.)@_*([]@!@/)(@)@-@),@(@@+@)' ^'][)@]`}`]()`@.@]@%[`}%[@`@!#@%[').',"})') bat-0.19.0/tests/syntax-tests/source/Plaintext/README.md000064400000000000000000000004350072674642500210720ustar 00000000000000This text file was generated with the following script. ```python with open("plaintext.txt", "w"): for i in range(176): try: f.write(chr(i) + "\n") except: pass f.write("\n") f.write("Here is a line with multiple characters\n") ``` bat-0.19.0/tests/syntax-tests/source/Plaintext/bat_options000064400000000000000000000000130072674642500220470ustar 00000000000000--show-all bat-0.19.0/tests/syntax-tests/source/Plaintext/plaintext.txt000064400000000000000000000006650072674642500223710ustar 00000000000000                           ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~  €  ‚ ƒ „ … † ‡ ˆ ‰ Š ‹ Œ  Ž   ‘ ’ “ ” • – — ˜ ™ š › œ  ž Ÿ   ¡ ¢ £ ¤ ¥ ¦ § ¨ © ª « ¬ ­ ® Here's a line with multiple characters. bat-0.19.0/tests/syntax-tests/source/PowerShell/test.ps1000075500000000000000000000026320072674642500213370ustar 00000000000000# PowerShell script for testing syntax highlighting function Get-FutureTime { param ( [Int32] $Minutes ) $time = Get-Date | % { $_.AddMinutes($Minutes) } "{0:d2}:{1:d2}:{2:d2}" -f @($time.hour, $time.minute, $time.second) } if ($env:PATH -match '.*rust.*') { 'Path contains Rust' try { & "cargo" "--version" } catch { Write-Error "Failed to run cargo" } } else { 'Path does not contain Rust' } (5..30) | ? { $_ % (2 * 2 + 1) -eq 0 } | % {"In {0} minutes, the time will be {1}." -f $_, $( Get-FutureTime $_ )} $later = Get-FutureTime -Minutes $( Get-Random -Minimum 60 -Maximum 120 ) "The time will be " + $later + " later." bat-0.19.0/tests/syntax-tests/source/Protocol Buffer/vyconf.proto000064400000000000000000000056570072674642500232420ustar 00000000000000message Request { enum ConfigFormat { CURLY = 0; JSON = 1; } enum OutputFormat { OutPlain = 0; OutJSON = 1; } message Status { } message SetupSession { optional string ClientApplication = 1; optional int32 OnBehalfOf = 2; } message Set { repeated string Path = 1; optional bool Ephemeral = 3; } message Delete { repeated string Path = 1; } message Rename { repeated string EditLevel = 1; required string From = 2; required string To = 3; } message Copy { repeated string EditLevel = 1; required string From = 2; required string To = 3; } message Comment { repeated string Path = 1; required string Comment = 2; } message Commit { optional bool Confirm = 1; optional int32 ConfirmTimeout = 2; optional string Comment = 3; } message Rollback { required int32 Revision = 1; } message Load { required string Location = 1; optional ConfigFormat format = 2; } message Merge { required string Location = 1; optional ConfigFormat format = 2; } message Save { required string Location = 1; optional ConfigFormat format = 2; } message ShowConfig { repeated string Path = 1; optional ConfigFormat format = 2; } message Exists { repeated string Path = 1; } message GetValue { repeated string Path = 1; optional OutputFormat output_format = 2; } message GetValues { repeated string Path = 1; optional OutputFormat output_format = 2; } message ListChildren { repeated string Path = 1; optional OutputFormat output_format = 2; } message RunOpMode { repeated string Path = 1; optional OutputFormat output_format = 2; } message Confirm { } message EnterConfigurationMode { required bool Exclusive = 1; required bool OverrideExclusive = 2; } message ExitConfigurationMode { } oneof msg { Status status = 1; SetupSession setup_session = 2; Set set = 3; Delete delete = 4; Rename rename = 5; Copy copy = 6; Comment comment = 7; Commit commit = 8; Rollback rollback = 9; Merge merge = 10; Save save = 11; ShowConfig show_config = 12; Exists exists = 13; GetValue get_value = 14; GetValues get_values = 15; ListChildren list_children = 16; RunOpMode run_op_mode = 17; Confirm confirm = 18; EnterConfigurationMode configure = 19; ExitConfigurationMode exit_configure = 20; string teardown = 21; } } message RequestEnvelope { optional string token = 1; required Request request = 2; } enum Status { SUCCESS = 0; FAIL = 1; INVALID_PATH = 2; INVALID_VALUE = 3; COMMIT_IN_PROGRESS = 4; CONFIGURATION_LOCKED = 5; INTERNAL_ERROR = 6; PERMISSION_DENIED = 7; PATH_ALREADY_EXISTS = 8; } message Response { required Status status = 1; optional string output = 2; optional string error = 3; optional string warning = 4; } bat-0.19.0/tests/syntax-tests/source/Puppet/LICENSE.md000064400000000000000000000263640072674642500205350ustar 00000000000000The `manifest_large_exported_classes_node.pp` file has been added from https://github.com/puppetlabs/puppet under the following license: ```text Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "{}" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright {yyyy} {name of copyright owner} Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ``` bat-0.19.0/tests/syntax-tests/source/Puppet/manifest_large_exported_classes_node.pp000064400000000000000000000037140072674642500271000ustar 00000000000000class foo ($bar) { @@notify { 'foo': } } @@file { "somedir/${name}_${munin_port_real}": ensure => present, content => template("munin/defaultclient.erb"), } # Collect all exported files File <<||>> # Compile the munin.conf with a local header concatenated_file { "/etc/munin/munin.conf": dir => somedir, header => "/etc/munin/munin.conf.header", } hosting_vserver_configuration { "erics": domain => "orange.co", type => "friend", context => 13, ip => "255.255.255.254", prefix => 27, admin_user => "erict", admin_user_name => "hello, its me", admin_user_email => "erict@orange.co", customer => "hello? is it me?", admin_password => file("/etc/puppet/secrets/hosting/erict_passwd"), } class davids_black_co_at { ## Create users for my parents and my grandmother hosting::user { rztt: realname => "some other rztt", uid => 2001, admin => true; same: realname => "could be same", uid => 2002; imapersontoodamnit: realname => "some one else", uid => 2003; } # Install git.black.co.at include git::daemon include git::web git::web::export { [manifests, "puppet-trunk"]: } # Provision an additional mysql database on the database server hosting::database { "fogbugz": type => mysql } # Create another VirtualHost apache2::site { "local-fogbugz": source => "puppet://$servername/files/hosting/erict/sites/local-fogbugz" } } node backuppc { # only use the smarthost $mta = ssmtp # this is a vserver on this host, so register correctly in nagios $nagios_parent = "orange.co" # I'm sharing an IP here, so those things have to have their own ports $apache2_port = 8080 $munin_port = 5008 $munin_stats_port = 8667 # default configuration include dbp # configure the backuppc server include backuppc::server } bat-0.19.0/tests/syntax-tests/source/PureScript/test.purs000064400000000000000000000051300072674642500216320ustar 00000000000000-- | This module defines a datatype `Pair` together with a few useful instances -- | and helper functions. Note that this is not just `Tuple a a` but rather a -- | list with exactly two elements. Specifically, the `Functor` instance maps -- | over both values (in contrast to the `Functor` instance for `Tuple a`). module Data.Pair ( Pair(..) , (~) , fst , snd , curry , uncurry , swap ) where import Prelude import Data.Foldable (class Foldable) import Data.Traversable (class Traversable) import Data.Distributive (class Distributive) import Test.QuickCheck.Arbitrary (class Arbitrary, arbitrary) -- | A pair simply consists of two values of the same type. data Pair a = Pair a a infixl 6 Pair as ~ -- | Returns the first component of a pair. fst ∷ ∀ a. Pair a → a fst (x ~ _) = x -- | Returns the second component of a pair. snd ∷ ∀ a. Pair a → a snd (_ ~ y) = y -- | Turn a function that expects a pair into a function of two arguments. curry ∷ ∀ a b. (Pair a → b) → a → a → b curry f x y = f (x ~ y) -- | Turn a function of two arguments into a function that expects a pair. uncurry ∷ ∀ a b. (a → a → b) → Pair a → b uncurry f (x ~ y) = f x y -- | Exchange the two components of the pair swap ∷ ∀ a. Pair a → Pair a swap (x ~ y) = y ~ x derive instance eqPair ∷ Eq a ⇒ Eq (Pair a) derive instance ordPair ∷ Ord a ⇒ Ord (Pair a) instance showPair ∷ Show a ⇒ Show (Pair a) where show (x ~ y) = "(" <> show x <> " ~ " <> show y <> ")" instance functorPair ∷ Functor Pair where map f (x ~ y) = f x ~ f y instance applyPair ∷ Apply Pair where apply (f ~ g) (x ~ y) = f x ~ g y instance applicativePair ∷ Applicative Pair where pure x = x ~ x instance bindPair ∷ Bind Pair where bind (x ~ y) f = fst (f x) ~ snd (f y) instance monadPair ∷ Monad Pair instance semigroupPair ∷ Semigroup a ⇒ Semigroup (Pair a) where append (x1 ~ y1) (x2 ~ y2) = (x1 <> x2) ~ (y1 <> y2) instance monoidPair ∷ Monoid a ⇒ Monoid (Pair a) where mempty = mempty ~ mempty instance foldablePair ∷ Foldable Pair where foldr f z (Pair x y) = x `f` (y `f` z) foldl f z (Pair x y) = (z `f` x) `f` y foldMap f (Pair x y) = f x <> f y instance traversablePair ∷ Traversable Pair where traverse f (Pair x y) = Pair <$> f x <*> f y sequence (Pair mx my) = Pair <$> mx <*> my instance distributivePair ∷ Distributive Pair where distribute xs = map fst xs ~ map snd xs collect f xs = map (fst <<< f) xs ~ map (snd <<< f) xs instance arbitraryPair ∷ Arbitrary a ⇒ Arbitrary (Pair a) where arbitrary = Pair <$> arbitrary <*> arbitrary bat-0.19.0/tests/syntax-tests/source/Python/battest.py000064400000000000000000000025550072674642500211510ustar 00000000000000from os import getcwd import numpy as np from matplotlib.pyplot import plot as plt from time import * # COMMENT test h2 = 4 # this is a comment """this is also a comment""" # Import test # class test class Hello: def __init__(self, x): self.name = x def selfprint(self): print("hello my name is ", self.name) def testprint(self): print(1*2, 2+3, 4 % 5, 8-4, 9/4, 23//4) # Decorators test class Decorators: @classmethod def decoratorsTest(self): pass H1 = Hello("john") H1.selfprint() H1.testprint() # list test a = [1, 2, 3, 4, 5] a.sort() print(a[1:3]) print(a[:4]) print(a[2]) print(a[2:]) # dictionary test # copied from w3schools example myfamily = { "child1": { "name": "Emil", "year": 2004 }, "child2": { "name": "Tobias", "year": 2007 }, "child3": { "name": "Linus", "year": 2011 } } # tuple test testTuple = ("one", 2, "3") print(testTuple) print(np.random.randint(5, 45)) # string test a = "hello world" b = """good morning hello world bye""" formattest = "teststring is ={}".format(5) # lambda test def x2(n): lambda n: n/7 # if else ladder if 1 > 2: print("yes") elif 4 > 5: print("maybe") else: print("no") # loops i = 5 while(i > 0): print(i) i -= 1 for x in range(1, 20, 2): print(x) bat-0.19.0/tests/syntax-tests/source/QML/BatSyntaxTest.qml000064400000000000000000000145320072674642500215670ustar 00000000000000import QtQuick 2.0 import "../components" Page { id: page // properties property bool startup: true readonly property var var1: null readonly property QtObject var2: null allowedOrientations: Orientation.All /* components */ DBusServiceWatcher { id: dbusService service: "org.bat.service" onRegisteredChanged: { if (dbusService.registered) { announcedNameField.text = daemon.announcedName() } } } Component.onCompleted: { console.debug("completed") } Flickable { anchors.fill: parent contentHeight: column.height visible: dbusService.registered ViewPlaceholder { enabled: !startup && trustedDevices.count == 0 && nearDevices.count == 0 text: qsTr("Install Bat.") } Column { id: column width: page.width spacing: Theme.paddingLarge PageHeader { title: qsTr("Syntax Test") } TextField { id: announcedNameField width: parent.width label: qsTr("Device Name") text: dbusService.registered ? daemon.announcedName() : "" onActiveFocusChanged: { if (activeFocus) return if (text.length === 0) { text = daemon.announcedName() } else { daemon.setAnnouncedName(text) placeholderText = text } } EnterKey.onClicked: announcedNameField.focus = false EnterKey.iconSource: "image://theme/icon-m-enter-close" } Component { id: deviceDelegate ListItem { id: listItem property bool showStatus: deviceStatusLabel.text.length width: page.width height: Theme.itemSizeMedium Image { id: icon source: iconUrl x: Theme.horizontalPageMargin anchors.verticalCenter: parent.verticalCenter sourceSize.width: Theme.iconSizeMedium sourceSize.height: Theme.iconSizeMedium } Label { id: deviceNameLabel anchors { left: icon.right leftMargin: Theme.paddingLarge right: parent.right rightMargin: Theme.horizontalPageMargin } y: listItem.contentHeight / 2 - implicitHeight / 2 - showStatus * (deviceStatusLabel.implicitHeight / 2) text: name color: listItem.highlighted ? Theme.highlightColor : Theme.primaryColor truncationMode: TruncationMode.Fade textFormat: Text.PlainText Behavior on y { NumberAnimation {} } } Label { id: deviceStatusLabel anchors { left: deviceNameLabel.left top: deviceNameLabel.bottom right: parent.right rightMargin: Theme.horizontalPageMargin } text: (trusted && reachable) ? qsTr("Connected") : (hasPairingRequests || waitsForPairing ? qsTr("Pending pairing request ...") : "") color: listItem.highlighted ? Theme.secondaryHighlightColor : Theme.secondaryColor truncationMode: TruncationMode.Fade font.pixelSize: Theme.fontSizeExtraSmall opacity: showStatus ? 1.0 : 0.0 width: parent.width textFormat: Text.PlainText Behavior on opacity { FadeAnimation {} } } onClicked: { pageStack.push( Qt.resolvedUrl("DevicePage.qml"), { deviceId: id }) } } } DeviceListModel { id: devicelistModel } ColumnView { id: devicesView width: page.width itemHeight: Theme.itemSizeMedium model: trustedDevicesModel delegate: deviceDelegate visible: devicesView.count > 0 } } PullDownMenu { // MenuItem { // text: qsTr("About ...") // onClicked: pageStack.push(Qt.resolvedUrl("AboutPage.qml")) // } MenuItem { text: qsTr("Settings ...") onClicked: pageStack.push(Qt.resolvedUrl("SettingsPage.qml")) } } VerticalScrollDecorator {} } /* Connections { target: ui onOpeningDevicePage: openDevicePage(deviceId) }*/ Timer { interval: 1000 running: true repeat: false onTriggered: startup = false } function openDevicePage(deviceId) { if (typeof pageStack === "undefined") return; console.log("opening device " + deviceId) window.activate() var devicePage = pageStack.find(function(page) { return page.objectName === "DevicePage" }) if (devicePage !== null && devicePage.deviceId === deviceId) { pageStack.pop(devicePage) ui.showMainWindow() return } pageStack.pop(page, PageStackAction.Immediate) pageStack.push( Qt.resolvedUrl("DevicePage.qml"), { deviceId: deviceId }, PageStackAction.Immediate) } } bat-0.19.0/tests/syntax-tests/source/R/test.r000064400000000000000000000102470072674642500172100ustar 00000000000000# take input from the user num = as.integer(readline(prompt="Enter a number: ")) factorial = 1 # check is the number is negative, positive or zero if(num < 0) { print("Sorry, factorial does not exist for negative numbers") } else if(num == 0) { print("The factorial of 0 is 1") } else { for(i in 1:num) { factorial = factorial * i } print(paste("The factorial of", num ,"is",factorial)) } x <- 0 if (x < 0) { print("Negative number") } else if (x > 0) { print("Positive number") } else print("Zero") x <- 1:5 for (val in x) { if (val == 3){ next } print(val) } x <- 1 repeat { print(x) x = x+1 if (x == 6){ break } } `%divisible%` <- function(x,y) { if (x%%y ==0) return (TRUE) else return (FALSE) } switch("length", "color" = "red", "shape" = "square", "length" = 5) [1] 5 recursive.factorial <- function(x) { if (x == 0) return (1) else return (x * recursive.factorial(x-1)) } pow <- function(x, y) { # function to print x raised to the power y result <- x^y print(paste(x,"raised to the power", y, "is", result)) } A <- read.table("x.data", sep=",", col.names=c("year", "my1", "my2")) nrow(A) # Count the rows in A summary(A$year) A$newcol <- A$my1 + A$my2 # Makes a new newvar <- A$my1 - A$my2 # Makes a A$my1 <- NULL # Removes str(A) summary(A) library(Hmisc) contents(A) describe(A) set.seed(102) # This yields a good illustration. x <- sample(1:3, 15, replace=TRUE) education <- factor(x, labels=c("None", "School", "College")) x <- sample(1:2, 15, replace=TRUE) gender <- factor(x, labels=c("Male", "Female")) age <- runif(15, min=20,max=60) D <- data.frame(age, gender, education) rm(x,age,gender,education) print(D) # Table about education table(D$education) # Table about education and gender -- table(D$gender, D$education) # Joint distribution of education and gender -- table(D$gender, D$education)/nrow(D) # Add in the marginal distributions also addmargins(table(D$gender, D$education)) addmargins(table(D$gender, D$education))/nrow(D) # Generate a good LaTeX table out of it -- library(xtable) xtable(addmargins(table(D$gender, D$education))/nrow(D), digits=c(0,2,2,2,2)) by(D$age, D$gender, mean) by(D$age, D$gender, sd) by(D$age, D$gender, summary) a <- matrix(by(D$age, list(D$gender, D$education), mean), nrow=2) rownames(a) <- levels(D$gender) colnames(a) <- levels(D$education) print(a) print(xtable(a)) dat <- read.csv(file = "files/dataset-2013-01.csv", header = TRUE) interim_object <- data.frame(rep(1:100, 10), rep(101:200, 10), rep(201:300, 10)) object.size(interim_object) rm("interim_object") ls() rm(list = ls()) vector1 <- c(5,9,3) vector2 <- c(10,11,12,13,14,15) array1 <- array(c(vector1,vector2),dim = c(3,3,2)) vector3 <- c(9,1,0) vector4 <- c(6,0,11,3,14,1,2,6,9) array2 <- array(c(vector1,vector2),dim = c(3,3,2)) matrix1 <- array1[,,2] matrix2 <- array2[,,2] result <- matrix1+matrix2 print(result) column.names <- c("COL1","COL2","COL3") row.names <- c("ROW1","ROW2","ROW3") matrix.names <- c("Matrix1","Matrix2") result <- array(c(vector1,vector2),dim = c(3,3,2),dimnames = list(row.names, column.names, matrix.names)) print(result[3,,2]) print(result[1,3,1]) print(result[,,2]) # Load the package required to read JSON files. library("rjson") result <- fromJSON(file = "input.json") print(result) x <- c(151, 174, 138, 186, 128, 136, 179, 163, 152, 131) y <- c(63, 81, 56, 91, 47, 57, 76, 72, 62, 48) relation <- lm(y~x) print(relation) relation <- lm(y~x) png(file = "linearregression.png") plot(y,x,col = "blue",main = "Height & Weight Regression", abline(lm(x~y)),cex = 1.3,pch = 16,xlab = "Weight in Kg",ylab = "Height in cm") dev.off() data <- c("East","West","East","North","North","East","West","West","West","East","North") print(data) print(is.factor(data)) factor_data <- factor(data) print(factor_data) print(is.factor(factor_data)) v <- c(7,12,28,3,41) # Give the chart file a name. png(file = "line_chart_label_colored.jpg") plot(v,type = "o", col = "red", xlab = "Month", ylab = "Rain fall", main = "Rain fall chart") bat-0.19.0/tests/syntax-tests/source/Racket/test.rkt000064400000000000000000000032310072674642500205520ustar 00000000000000#lang racket (require "main.rkt" rackunit) ;; Helper for test cases with multiple outputs ;; See: https://stackoverflow.com/questions/41081395/unit-testing-in-racket-with-multiple-outputs (define-syntax check-values-equal? (syntax-rules () [(_ a b) (check-equal? (call-with-values (thunk a) list) b)])) ;; Named POSIX semaphores (test-begin (define test-sem-name "/test-nix-1") ;; Unlink if already exists (sem-unlink test-sem-name) ;; Open and unlink (define test-sem-p (sem-open test-sem-name (+ O_CREAT O_EXCL))) (check-not-false test-sem-p) (check-not-equal? test-sem-p (void)) (check-exn exn:fail? (lambda () (sem-open test-sem-name (+ O_CREAT O_EXCL))) "Permission denied") (check-exn exn:fail? (lambda () (sem-open test-sem-name (+ O_CREAT O_EXCL)))) ;; Change values (check-equal? (sem-getvalue test-sem-p) 0) (sem-post test-sem-p) (check-equal? (sem-getvalue test-sem-p) 1) (sem-wait test-sem-p) (check-equal? (sem-getvalue test-sem-p) 0) (sem-post test-sem-p) (check-equal? (sem-getvalue test-sem-p) 1) (sem-post test-sem-p) (check-equal? (sem-getvalue test-sem-p) 2) (sem-trywait test-sem-p) (check-equal? (sem-getvalue test-sem-p) 2) ;; Can't unlink twice (check-not-false (sem-unlink test-sem-name)) (check-false (sem-unlink test-sem-name))) ;; Named POSIX shared memory (test-begin (define test-shm-name "test-nix-mem-1") ;; Open and unlink (shm-unlink test-shm-name) (define test-shm-fd (shm-open test-shm-name (+ O_EXCL O_CREAT O_RDWR) #o644)) (check > test-shm-fd 0) (check-not-false (shm-unlink test-shm-name)) (check-false (shm-unlink test-shm-name))) bat-0.19.0/tests/syntax-tests/source/Rego/LICENSE.md000064400000000000000000000023660072674642500201500ustar 00000000000000The `src_test.rego` file has been added from https://github.com/Azure/Community-Policy under the following license: ```text MIT License Copyright (c) Microsoft Corporation. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE ``` bat-0.19.0/tests/syntax-tests/source/Rego/src_test.rego000064400000000000000000000104760072674642500212510ustar 00000000000000package k8sazureprocmount test_input_container_not_proc_mount_allowed { input := { "review": input_review, "parameters": input_parameters_default} results := violation with input as input count(results) == 0 } test_input_container_proc_mount_not_allowed { input := { "review": input_review_unmasked, "parameters": input_parameters_default} results := violation with input as input count(results) == 1 } test_input_container_proc_mount_not_allowed_null_param { input := { "review": input_review_unmasked, "parameters": null } results := violation with input as input count(results) == 1 } test_input_container_proc_mount_not_allowed_missing_param { input := { "review": input_review_unmasked } results := violation with input as input count(results) == 1 } test_input_container_many_not_proc_mount_allowed { input := { "review": input_review_many, "parameters": input_parameters_default} results := violation with input as input count(results) == 0 } test_input_container_many_mixed_proc_mount_not_allowed { input := { "review": input_review_many_mixed, "parameters": input_parameters_default} results := violation with input as input count(results) == 1 } test_input_container_many_mixed_proc_mount_not_allowed_two { input := { "review": input_review_many_mixed_two, "parameters": input_parameters_default} results := violation with input as input count(results) == 2 } test_input_container_proc_mount_case_insensitive { input := { "review": input_review, "parameters": input_parameters_default_lower} results := violation with input as input count(results) == 0 } test_input_container_not_proc_mount_unmasked { input := { "review": input_review, "parameters": input_parameters_unmasked} results := violation with input as input count(results) == 0 } test_input_container_proc_mount_unmasked { input := { "review": input_review_unmasked, "parameters": input_parameters_unmasked} results := violation with input as input count(results) == 0 } test_input_container_many_mixed_proc_mount_allowed_two { input := { "review": input_review_many_mixed_two, "parameters": input_parameters_unmasked} results := violation with input as input count(results) == 0 } input_review = { "object": { "metadata": { "name": "nginx" }, "spec": { "containers": input_containers_one } } } input_review_unmasked = { "object": { "metadata": { "name": "nginx" }, "spec": { "containers": input_containers_one_unmasked } } } input_review_many = { "object": { "metadata": { "name": "nginx" }, "spec": { "containers": input_containers_many, "initContainers": input_containers_one } } } input_review_many_mixed = { "object": { "metadata": { "name": "nginx" }, "spec": { "containers": input_containers_many, "initContainers": input_containers_one_unmasked } } } input_review_many_mixed_two = { "object": { "metadata": { "name": "nginx" }, "spec": { "containers": input_containers_many_mixed, "initContainers": input_containers_one_unmasked } } } input_containers_one = [ { "name": "nginx", "image": "nginx", "securityContext": { "procMount": "Default" } }] input_containers_one_unmasked = [ { "name": "nginx", "image": "nginx", "securityContext": { "procMount": "Unmasked" } }] input_containers_many = [ { "name": "nginx", "image": "nginx", "securityContext": { "procMount": "Default" } }, { "name": "nginx1", "image": "nginx" }, { "name": "nginx2", "image": "nginx", "securityContext": { "runAsUser": "1000" } }] input_containers_many_mixed = [ { "name": "nginx", "image": "nginx", "securityContext": { "procMount": "Default" } }, { "name": "nginx1", "image": "nginx", "securityContext": { "procMount": "Unmasked" } }] input_parameters_default = { "procMount": "Default" } input_parameters_default_lower = { "procMount": "default" } input_parameters_unmasked = { "procMount": "Unmasked" } bat-0.19.0/tests/syntax-tests/source/Regular Expression/test.re000064400000000000000000000000710072674642500226670ustar 00000000000000^\[START\]\d\D\h\H\s\S[a-z]\v\V\w\W.([a-z]){3,5}\[END\]$ bat-0.19.0/tests/syntax-tests/source/Robot Framework/LICENSE.md000064400000000000000000000023300072674642500222460ustar 00000000000000The `recipe141_aws_simple_storage_service.robot` file has been added from https://github.com/adrianyorke/robotframework-cookbook under the following license: ```text MIT License Copyright (c) 2020 Adrian Yorke Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ``` bat-0.19.0/tests/syntax-tests/source/Robot Framework/recipe141_aws_simple_storage_service.robot000064400000000000000000000025330072674642500311020ustar 00000000000000*** Settings *** Documentation PROBLEM: ... You want to test the existence of a file in an AWS S3 bucket ... without using lower level Python code or developing a custom library. ... DISCUSSION: ... This recipe demonstrates: ... - using a Suite Teardown to end the test suite cleanly ... - using keywords from an external library ... - accessing OS Environment Variables directly using %{} syntax ... This recipe has the following external dependencies: ... $ pip install --upgrade robotframework-aws ... This recipe also requires the following OS environment variables: ... AWS_ACCESS_KEY_ID ... AWS_SECRET_ACCESS_KEY Suite Teardown Delete All Sessions Library AWSLibrary Force Tags no-ci-testing *** Variables *** ${recipe} Recipe 14.1 AWS Simple Storage Service ${level} Intermediate ${category} External Library: AWSLibrary ${REGION} us-east-1 ${BUCKET} YOUR_BUCKET_NAME_GOES_HERE ${KEY} YOUR_FILE_PATH_GOES_HERE *** Test Cases *** Check Key Exists In Bucket Log Variables Create Session With Keys ${REGION} %{AWS_ACCESS_KEY_ID} %{AWS_SECRET_ACCESS_KEY} Key Should Exist ${BUCKET} ${KEY} bat-0.19.0/tests/syntax-tests/source/Ruby/output.rb000064400000000000000000000026500072674642500204520ustar 00000000000000class RepeatedSubstring def find_repeated_substring(s) # catch the edge cases return 'NONE' if s == '' # check if the string consists of only one character => "aaaaaa" => "a" return s.split('').uniq[0] if s.split('').uniq.length == 1 searched = [] longest_prefix = 0 long_prefix = '' (0..s.length - 1).each do |i| next if searched.include? s[i] searched.push(s[i]) next_occurrences = next_index(s, i + 1, s[i]) next_occurrences.each do |next_occurrence| next if next_occurrence == -1 prefix = ge_prefix(s[i..next_occurrence - 1], s[next_occurrence..s.length]) if prefix.length > longest_prefix longest_prefix = prefix.length long_prefix = prefix end end end # if prefix == " " it is a invalid sequence return 'NONE' if long_prefix.strip.empty? long_prefix end def get_prefix(s1, s2) prefix = '' min_length = [s1.length, s2.length].min return '' if s1.nil? || s2.nil? (0..min_length - 1).each do |i| return prefix if s1[i] != s2[i] prefix += s1[i] end prefix end def next_index(seq, index, value) indexes = [] (index..seq.length).each do |i| indexes.push(i) if seq[i] == value end indexes end def find_repeated_substring_file(file_path) File.open(file_path).read.each_line.map { |line| find_repeated_substring(line) } end end bat-0.19.0/tests/syntax-tests/source/Ruby Haml/test.html.haml000064400000000000000000000005430072674642500222130ustar 00000000000000%html %head %title Test Title %body %navigation = render :partial => "navigation_top" %h1= page.title %p Here is a point to emphasize: %strong.highlighted#search_item_found= item1.text %span{:class => "fancy", :id => "fancy1"}= item2.text .special= special.text %ol %li First %li Second bat-0.19.0/tests/syntax-tests/source/Ruby On Rails/test.rb000064400000000000000000000007110072674642500214550ustar 00000000000000class ContactsController < ApplicationController def new @contact = Contact.new end def create @contact = Contact.new(secure_params) if @contact.valid? UserMailer.contact_email(@contact).deliver_now flash[:notice] = "Message sent from #{@contact.name}." redirect_to root_path else render :new end end private def secure_params params.require(:contact).permit(:name, :email, :content) end end bat-0.19.0/tests/syntax-tests/source/Rust/output.rs000064400000000000000000000125670072674642500205170ustar 00000000000000use std::io::{self, Write}; #[cfg(feature = "paging")] use std::process::Child; use crate::error::*; #[cfg(feature = "paging")] use crate::less::retrieve_less_version; #[cfg(feature = "paging")] use crate::paging::PagingMode; #[derive(Debug)] pub enum OutputType { #[cfg(feature = "paging")] Pager(Child), Stdout(io::Stdout), } impl OutputType { #[cfg(feature = "paging")] pub fn from_mode(mode: PagingMode, pager: Option<&str>) -> Result { use self::PagingMode::*; Ok(match mode { Always => OutputType::try_pager(false, pager)?, QuitIfOneScreen => OutputType::try_pager(true, pager)?, _ => OutputType::stdout(), }) } /// Try to launch the pager. Fall back to stdout in case of errors. #[cfg(feature = "paging")] fn try_pager(quit_if_one_screen: bool, pager_from_config: Option<&str>) -> Result { use std::env; use std::ffi::OsString; use std::path::PathBuf; use std::process::{Command, Stdio}; let mut replace_arguments_to_less = false; let pager_from_env = match (env::var("BAT_PAGER"), env::var("PAGER")) { (Ok(bat_pager), _) => Some(bat_pager), (_, Ok(pager)) => { // less needs to be called with the '-R' option in order to properly interpret the // ANSI color sequences printed by bat. If someone has set PAGER="less -F", we // therefore need to overwrite the arguments and add '-R'. // // We only do this for PAGER (as it is not specific to 'bat'), not for BAT_PAGER // or bats '--pager' command line option. replace_arguments_to_less = true; Some(pager) } _ => None, }; let pager_from_config = pager_from_config.map(|p| p.to_string()); if pager_from_config.is_some() { replace_arguments_to_less = false; } let pager = pager_from_config .or(pager_from_env) .unwrap_or_else(|| String::from("less")); let pagerflags = shell_words::split(&pager).chain_err(|| "Could not parse pager command.")?; match pagerflags.split_first() { Some((pager_name, args)) => { let mut pager_path = PathBuf::from(pager_name); if pager_path.file_stem() == Some(&OsString::from("bat")) { pager_path = PathBuf::from("less"); } let is_less = pager_path.file_stem() == Some(&OsString::from("less")); let mut process = if is_less { let mut p = Command::new(&pager_path); if args.is_empty() || replace_arguments_to_less { p.arg("--RAW-CONTROL-CHARS"); if quit_if_one_screen { p.arg("--quit-if-one-screen"); } // Passing '--no-init' fixes a bug with '--quit-if-one-screen' in older // versions of 'less'. Unfortunately, it also breaks mouse-wheel support. // // See: http://www.greenwoodsoftware.com/less/news.530.html // // For newer versions (530 or 558 on Windows), we omit '--no-init' as it // is not needed anymore. match retrieve_less_version() { None => { p.arg("--no-init"); } Some(version) if (version < 530 || (cfg!(windows) && version < 558)) => { p.arg("--no-init"); } _ => {} } } else { p.args(args); } p.env("LESSCHARSET", "UTF-8"); p } else { let mut p = Command::new(&pager_path); p.args(args); p }; Ok(process .stdin(Stdio::piped()) .spawn() .map(OutputType::Pager) .unwrap_or_else(|_| OutputType::stdout())) } None => Ok(OutputType::stdout()), } } pub(crate) fn stdout() -> Self { OutputType::Stdout(io::stdout()) } #[cfg(feature = "paging")] pub(crate) fn is_pager(&self) -> bool { if let OutputType::Pager(_) = self { true } else { false } } #[cfg(not(feature = "paging"))] pub(crate) fn is_pager(&self) -> bool { false } pub fn handle(&mut self) -> Result<&mut dyn Write> { Ok(match *self { #[cfg(feature = "paging")] OutputType::Pager(ref mut command) => command .stdin .as_mut() .chain_err(|| "Could not open stdin for pager")?, OutputType::Stdout(ref mut handle) => handle, }) } } #[cfg(feature = "paging")] impl Drop for OutputType { fn drop(&mut self) { if let OutputType::Pager(ref mut command) = *self { let _ = command.wait(); } } } bat-0.19.0/tests/syntax-tests/source/SCSS/example.scss000064400000000000000000000031760072674642500207530ustar 00000000000000@import 'fonts'; $theme_dark: ( "background-color": null, ); $theme_main: ( "text-size": 3em, "text-color": black, "text-shadow": #36ad 0px 0px 3px, "card-background": #d6f, "card-shadow": #11121212 0px 0px 2px 1px, "card-padding": 1rem, "card-margin": 0.5in, "image-width": 600px, "image-height": 100vh, "background-color": #dedbef, "i-ran-out-of-placeholders-for-units": (1vw 100% 60pt), ); $current_theme: $theme_main; @mixin themed() { $current_theme: $theme_main !global; @content; @media (prefers-color-scheme: dark) { $current_theme: $theme_dark !global; @content; } .#{"dark"} & { $current_theme: $theme_dark !global; @content; } } @function theme($variable) { @if map-has_key($current_theme, $variable) { @return map-get($current_theme, $variable); } @else { @error "Unknown theme variable: #{$variable}"; } } body { @include themed { background-color: theme('background-color'); background-image: url("https://github.com/sharkdp/bat/raw/master/doc/logo-header.svg"); } header[data-selectable="false"] { -webkit-user-select: none; -moz-user-select: none; -ms-user-select: /* CSS comment */ none; cursor: default !important; // SCSS comment } > div { border: #04f 1px solid; &::after { content: 'Pseudo'; color: #2F5F7F; box-sizing: border-box; } } } @keyframes rotate { 0% { transform: rotate(0deg); } 50% { transform: rotate(180deg)} 100% {transform: rotate(0rad);} } @font-face { font-family: 'Example Font'; src: url(example.ttf) format('ttf'); src: local('Comic Sans MS'); } bat-0.19.0/tests/syntax-tests/source/SLS/test.sls000064400000000000000000000024710072674642500200100ustar 00000000000000required_packages: pkg.installed: - pkgs: - git - perl - fortune cowsay_source: git.latest: - name: https://github.com/jasonm23/cowsay.git - target: /root/cowsay run_installer: cmd.run: - name: ./install.sh /usr/local - cwd: /root/cowsay - onchanges: - git: cowsay_source {% set cowfiles = salt.cmd.run('cowsay -l').split('\n')[1:] %} {% set ascii_arts = cowfiles | join(' ') %} {% for ascii_art in ascii_arts.split(' ') %} run_cowsay_{{ ascii_art }}: # name must be unique cmd.run: {% if ascii_art is in ['head-in', 'sodomized', 'telebears'] %} - name: echo cowsay -f {{ ascii_art }} should not be used {% else %} - name: fortune | cowsay -f {{ ascii_art }} {% endif %} {% endfor %} echo_pillar_demo_1: cmd.run: - name: "echo {{ pillar.demo_text | default('pillar not defined') }}" echo_pillar_demo_2: cmd.run: - name: "echo {{ pillar.demo.text | default('pillar not defined') }}" # Comment {% set rand = salt['random.get_str'](20) %} {% set IP_Address = pillar['IP_Address'] %} wait: cmd.run: - name: sleep 210 # another comment create_roster_file: file.managed: - name: /tmp/salt-roster-{{ rand }} - contents: - 'switch:' - ' host: {{ IP_Address }}' - " user: test" - " passwd: {{ passwd }}" bat-0.19.0/tests/syntax-tests/source/SML/sample.sml000064400000000000000000000012670072674642500203000ustar 00000000000000val x = 0 val hello = "hello world" val id = fn x => x fun id' x = x val () = print "hello world\n" val _ = let val hello = "hello" val world = "world" in print (hello ^ " " ^ world ^ "\n") end fun isZero n = if n = 0 then true else false fun isTrue b = case b of true => true | false => false exception Bad_value of string fun isTrue' b = case b of true => true | _ => raise (Bad_value "value is not true!") val alwaysTrue = isTrue' false handle Bad_value _ => true datatype myBool = True | False datatype shape = Square of real | Circle of real | Point signature FOO = sig val foo : 'a -> 'a end structure Foo :> FOO = struct fun foo x = x end bat-0.19.0/tests/syntax-tests/source/SQL/ims.sql000064400000000000000000000216070072674642500176170ustar 00000000000000-- interships create table interships (intership_id number(7) constraint intership_id_pk primary key, name varchar2(50), start_date date, end_date date); insert into interships values (1, 'Leaderator 2019', to_date('15/02/2019', 'DD/MM/YYYY'), to_date('01/09/2019', 'DD/MM/YYYY')); insert into interships (intership_id, name, start_date) values (2, 'Leaderator 2020', to_date('10/02/2019', 'DD/MM/YYYY')); commit; -- directions create table directions (direction_id number(7) constraint direction_id_pk primary key, name varchar2(50)); insert into directions values (1, 'Data Science'); insert into directions values (2, 'Oracle Development'); commit; -- participants create table participants (participant_id number(7) constraint participant_id_pk primary key, first_name varchar2(25), last_name varchar2(25), personal_id number(11), intership_id number(7) constraint participant_inter_id_fk references interships (intership_id), direction_id number(7) constraint participant_direct_id_fk references directions (direction_id), constraint personal_id_unique unique (personal_id)); insert into participants values (1, 'Erekle', 'Tvinadze', 01011234567, 1, 1); insert into participants values (2, 'Mariami', 'Chakhvadze', 01011234568, 2, 2); commit; -- hiring_layer_types create table hiring_layer_types (layer_type_id number(7) constraint layer_id_pk primary key, type varchar2(50)); insert into hiring_layer_types values (1, 'GMAT'); insert into hiring_layer_types values (2, 'Algorithms'); insert into hiring_layer_types values (3, 'Interview'); commit; -- hiring_layers create table hiring_layers (layer_id number(7) constraint layer_pk primary key, layer_type_id number(7) constraint layer_type_fk references hiring_layer_types (layer_type_id), participant_id number(7) constraint participant_id_fk references participants (participant_id), result number(3)); insert into hiring_layers values (1, 1, 1, 52); insert into hiring_layers values (2, 1, 2, 80); insert into hiring_layers values (3, 2, 2, 75); insert into hiring_layers values (4, 3, 2, 100); commit; -- subjects create table subjects (subject_id number(7) constraint subject_id_pk primary key, name varchar2(100), minimum_score number(3)); insert into subjects values (1, 'SQL', 70); insert into subjects values (2, 'Machine Learning', 70); commit; -- direction_subjects create table direction_subjects (direction_subject_id number(7) constraint direct_sub_id primary key, direction_id number(7) constraint direct_id_fk references directions (direction_id), subject_id number(7) constraint subject_id_fk references subjects (subject_id)); insert into direction_subjects values (1, 2, 1); insert into direction_subjects values (2, 1, 1); insert into direction_subjects values (3, 1, 2); commit; -- component_types create table component_types (component_type_id number(7) constraint com_type_id_pk primary key, type varchar2(50)); insert into component_types values (1, 'Homework'); insert into component_types values (2, 'Quiz'); commit; -- components create table components (component_id number(7) constraint component_id_pk primary key, subject_id number(7) constraint sub_id_fk references subjects (subject_id), minimum_score number(3), component_type_id number(7) constraint com_type_id_fk references component_types (component_type_id), weight number(3)); insert into components values (1, 1, 60, 1, 20); insert into components values (2, 2, 65, 2, 50); commit; -- results create table results (result_id number(7) constraint result_id_pk primary key, issue_date date, grade number(3), participant_id number(7) constraint particip_id_fk references participants (participant_id), component_id number(7) constraint component_id_fk references components (component_id)); insert into results values (1, to_date('04/05/2020', 'DD/MM/YYYY'), 87, 2, 2); commit; -- learning_material_types create table learning_material_types (material_type_id number(7) constraint lear_material_id_pk primary key, type varchar(50)); insert into learning_material_types values (1, 'Book'); insert into learning_material_types values (2, 'PPT'); insert into learning_material_types values (3, 'Youtube Video'); commit; -- learning_materials create table learning_materials (learning_material_id number(7), url varchar2(3000), subject_id number(7) constraint subj_id_fk references subjects (subject_id), material_type_id number(7) constraint material_type_id_fk references learning_material_types (material_type_id)); insert into learning_materials values (1, 'www.youtube.com', 1, 3); commit; -- sessions create table sessions (session_id number(7) constraint session_id_pk primary key, start_date date, end_date date, intership_id number(7) constraint inter_idd_fk references interships (intership_id), direction_id number(7) constraint direct_fk references directions (direction_id), subject_id number(7) constraint subject_fk references subjects (subject_id)); -- attendances create table attendances (attendance_id number(7) constraint attend_id_pk primary key, participant_id number(7) constraint participant_fk references participants (participant_id), session_id number(7) constraint session_id_fk references sessions (session_id), status varchar2(25)); /* შექმენით view სადაც იქნება სტაჟირების შესახებ ინფორმაცია: სახელი, დაწყების თარიღი, დასრულების თარიღი, მონაწილეების რაოდენობა. */ create view intership_info as select i.name, i.start_date, i.end_date, (select count(participant_id) from participants p where p.intership_id = i.intership_id) number_of_participants from interships i; /* შექმენით view სადაც იქნება მონაწილეებზე ინფორმაცია: სტაჟირების სახელი, მონაწილის სახელი, მიმართულება, შერჩევის რამდენი ეტაპი გაიარა, სტაჟირების სტატუსი(გაიარა, ვერ გაიარა, მიმდინარე,ვერ მოხვდა სტაჟირებაზე) */ create view participant_info as select i.name intership, p.first_name, p.last_name, d.name direction, (select count(h2.participant_id) from hiring_layers h2 where h2.participant_id = p.participant_id) number_of_layers, case when p.direction_id is null then 'Rejected' when i.end_date is null then 'Present' when (select h2.result from hiring_layers h2 join hiring_layer_types l on h2.layer_type_id = l.layer_type_id where h2.participant_id = p.participant_id and l.type = 'Intership') > (select minimum_score from subjects) then 'Passed' else 'Failed' end status from interships i, participants p, directions d where i.intership_id = p.intership_id and (d.direction_id = p.direction_id or p.direction_id is null); /* შექნენით view სადაც იქნება მიმართულებებზე ინფორმაცია: მიმართულების სახელი, რა საგნები ისწავლება */ create view direction_info as select d.name direction, s.name subject from directions d, direction_subjects ds, subjects s where d.direction_id = ds.direction_id and ds.subject_id = s.subject_id; /* შექმენით view სადც იქნება საგნების ინფორმაცია: საგნის სახელი, საგნის ზღვარი, შეფასების კომპონენტები(სახელი, ზღვარი , წონა). */ create view subject_info as select s.name, s.minimum_score subject_min_score, ct.type, c.minimum_score component_min_score, c.weight from subjects s, component_types ct, components c where s.subject_id = c.subject_id and c.component_type_id = ct.component_type_id; /* შექმენით view დასწრების აღრიცხვა მონაწილეების მიხედვით: სტაჟირებაზე მიმართულების მიხედვით: რამდენი ჩატარდა, რამდენს დაესწრო, რამდენს არ დაესწრო. */ create view attendance_info as select p.first_name, p.last_name, (select count(s2.session_id) from sessions s2 where s2.direction_id = p.direction_id) lectures, (select count(a2.attendance_id) from attendances a2 where a2.participant_id = p.participant_id and a2.status = 'Present') present, (select count(a2.attendance_id) from attendances a2 where a2.participant_id = p.participant_id and a2.status = 'Absent') absent from participants p, attendances a, sessions s where p.participant_id = a.participant_id and a.session_id = s.session_id; bat-0.19.0/tests/syntax-tests/source/SSH Config/ssh_config000064400000000000000000000002230072674642500215260ustar 00000000000000# A comment Host example.com User dummy Compression no Host *.co.uk BatchMode no GlobalKnownHostsFile "/etc/ssh/ssh_known_hosts" bat-0.19.0/tests/syntax-tests/source/SSHD Config/sshd_config000064400000000000000000000012130072674642500217760ustar 00000000000000# This test sshd config file is intended for syntax testing # purposes only. # # Definitely do not use this in production for sshd. Port 22 # Here's a directive commented out: #ListenAddress 0.0.0.0 ListenAddress 127.0.0.1 HostKey /etc/ssh/ssh_host_rsa_key IgnoreRhosts yes PrintMotd yes X11Forwarding no AllowAgentForwarding no PermitRootLogin forced-commands-only SyslogFacility AUTH LogLevel VERBOSE AuthorizedKeysFile /etc/ssh/authorized-keys/%u PasswordAuthentication yes PermitEmptyPasswords no AllowUsers alice # pass locale information AcceptEnv LANG LC_* Banner /etc/sshd_banner AllowTcpForwarding yes PermitTunnel no PermitTTY yes bat-0.19.0/tests/syntax-tests/source/Sass/example.sass000064400000000000000000000030200072674642500210730ustar 00000000000000@import "fonts" $theme_dark: ( "background-color": null ) $theme_main: ( "text-size": 3em "text-color": black "text-shadow": #36ad 0px 0px 3px "card-background": #d6f "card-shadow": #11121212 0px 0px 2px 1px "card-padding": 1rem "card-margin": 0.5in "image-width": 600px "image-height": 100vh "background-color": #dedbef "i-ran-out-of-placeholders-for-units": ( 1vw 100% 60pt ) ) $current_theme: $theme_main @mixin themed() $current_theme: $theme_main !global @content @media (prefers-color-scheme: dark) $current_theme: $theme_dark !global @content .#{"dark"} & $current_theme: $theme_dark !global @content @function theme($variable) @if map-has_key($current_theme, $variable) @return map-get($current_theme, $variable) @else @error "Unknown theme variable: #{$variable}" body @include themed background-color: theme("background-color") background-image: url("https://github.com/sharkdp/bat/raw/master/doc/logo-header.svg") header[data-selectable="false"] -webkit-user-select: none -moz-user-select: none -ms-user-select: /* CSS comment */ none cursor: default !important // Sass comment > div border: #04f 1px solid &::after content: "Pseudo" color: #2f5f7f box-sizing: border-box @keyframes rotate 0% transform: rotate(0deg) 50% transform: rotate(180deg) 100% transform: rotate(0rad) @font-face font-family: "Example Font" src: url(example.ttf) format("ttf") src: local("Comic Sans MS") bat-0.19.0/tests/syntax-tests/source/Scala/ConcurrentEffectLaws.scala000064400000000000000000000062760072674642500237720ustar 00000000000000/* * Copyright (c) 2017-2019 The Typelevel Cats-effect Project Developers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package cats package effect package laws import cats.effect.concurrent.Deferred import cats.syntax.all._ import cats.laws._ import scala.concurrent.Promise trait ConcurrentEffectLaws[F[_]] extends ConcurrentLaws[F] with EffectLaws[F] { implicit def F: ConcurrentEffect[F] def runAsyncRunCancelableCoherence[A](fa: F[A]) = { val fa1 = IO.async[A] { cb => F.runAsync(fa)(r => IO(cb(r))).unsafeRunSync() } val fa2 = IO.cancelable[A] { cb => F.toIO(F.runCancelable(fa)(r => IO(cb(r))).unsafeRunSync()) } fa1 <-> fa2 } def runCancelableIsSynchronous[A] = { val lh = Deferred.uncancelable[F, Unit].flatMap { latch => val spawned = Promise[Unit]() // Never ending task val ff = F.cancelable[A] { _ => spawned.success(()); latch.complete(()) } // Execute, then cancel val token = F.delay(F.runCancelable(ff)(_ => IO.unit).unsafeRunSync()).flatMap { cancel => // Waiting for the task to start before cancelling it Async.fromFuture(F.pure(spawned.future)) >> cancel } F.liftIO(F.runAsync(token)(_ => IO.unit).toIO) *> latch.get } lh <-> F.unit } def runCancelableStartCancelCoherence[A](a: A) = { // Cancellation via runCancelable val f1: F[A] = for { effect1 <- Deferred.uncancelable[F, A] latch <- F.delay(Promise[Unit]()) never = F.cancelable[A] { _ => latch.success(()); effect1.complete(a) } cancel <- F.liftIO(F.runCancelable(never)(_ => IO.unit).toIO) // Waiting for the task to start before cancelling it _ <- Async.fromFuture(F.pure(latch.future)) // TODO get rid of this, IO, and Future here _ <- cancel result <- effect1.get } yield result // Cancellation via start.flatMap(_.cancel) val f2: F[A] = for { effect2 <- Deferred.uncancelable[F, A] // Using a latch to ensure that the task started latch <- Deferred.uncancelable[F, Unit] never = F.bracket(latch.complete(()))(_ => F.never[Unit])(_ => effect2.complete(a)) fiber <- F.start(never) // Waiting for the task to start before cancelling it _ <- latch.get _ <- F.start(fiber.cancel) result <- effect2.get } yield result f1 <-> f2 } def toIORunCancelableConsistency[A](fa: F[A]) = ConcurrentEffect.toIOFromRunCancelable(fa) <-> F.toIO(fa) } object ConcurrentEffectLaws { def apply[F[_]](implicit F0: ConcurrentEffect[F], contextShift0: ContextShift[F]): ConcurrentEffectLaws[F] = new ConcurrentEffectLaws[F] { val F = F0 val contextShift = contextShift0 } } bat-0.19.0/tests/syntax-tests/source/Scala/LICENSE.md000064400000000000000000000240770072674642500203020ustar 00000000000000The `ConcurrentEffectLaws.scala` file has been added from https://github.com/typelevel/cats-effect under the following license: Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS bat-0.19.0/tests/syntax-tests/source/Slim/test.slim000064400000000000000000000005430072674642500204140ustar 00000000000000doctype html html lang=locale head meta charset='utf-8' title #{@title ? "#{@title} | Testing" : 'Testing'} == stylesheet('app.css') body header h1.title Testing - @links.each do |link| a href=link.href =link.title div == yield - if APP_ENV == 'production' footer p Testing bat-0.19.0/tests/syntax-tests/source/Solidity/ERC721.sol000064400000000000000000000312620072674642500210270ustar 00000000000000// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./IERC721.sol"; import "./IERC721Receiver.sol"; import "./extensions/IERC721Metadata.sol"; import "../../utils/Address.sol"; import "../../utils/Context.sol"; import "../../utils/Strings.sol"; import "../../utils/introspection/ERC165.sol"; /** * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including * the Metadata extension, but not including the Enumerable extension, which is available separately as * {ERC721Enumerable}. */ contract ERC721 is Context, ERC165, IERC721, IERC721Metadata { using Address for address; using Strings for uint256; // Token name string private _name; // Token symbol string private _symbol; // Mapping from token ID to owner address mapping (uint256 => address) private _owners; // Mapping owner address to token count mapping (address => uint256) private _balances; // Mapping from token ID to approved address mapping (uint256 => address) private _tokenApprovals; // Mapping from owner to operator approvals mapping (address => mapping (address => bool)) private _operatorApprovals; /** * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection. */ constructor (string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { return interfaceId == type(IERC721).interfaceId || interfaceId == type(IERC721Metadata).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721-balanceOf}. */ function balanceOf(address owner) public view virtual override returns (uint256) { require(owner != address(0), "ERC721: balance query for the zero address"); return _balances[owner]; } /** * @dev See {IERC721-ownerOf}. */ function ownerOf(uint256 tokenId) public view virtual override returns (address) { address owner = _owners[tokenId]; require(owner != address(0), "ERC721: owner query for nonexistent token"); return owner; } /** * @dev See {IERC721Metadata-name}. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev See {IERC721Metadata-symbol}. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev See {IERC721Metadata-tokenURI}. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token"); string memory baseURI = _baseURI(); return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : ''; } /** * @dev Base URI for computing {tokenURI}. Empty by default, can be overriden * in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ""; } /** * @dev See {IERC721-approve}. */ function approve(address to, uint256 tokenId) public virtual override { address owner = ERC721.ownerOf(tokenId); require(to != owner, "ERC721: approval to current owner"); require(_msgSender() == owner || isApprovedForAll(owner, _msgSender()), "ERC721: approve caller is not owner nor approved for all" ); _approve(to, tokenId); } /** * @dev See {IERC721-getApproved}. */ function getApproved(uint256 tokenId) public view virtual override returns (address) { require(_exists(tokenId), "ERC721: approved query for nonexistent token"); return _tokenApprovals[tokenId]; } /** * @dev See {IERC721-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) public virtual override { require(operator != _msgSender(), "ERC721: approve to caller"); _operatorApprovals[_msgSender()][operator] = approved; emit ApprovalForAll(_msgSender(), operator, approved); } /** * @dev See {IERC721-isApprovedForAll}. */ function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev See {IERC721-transferFrom}. */ function transferFrom(address from, address to, uint256 tokenId) public virtual override { //solhint-disable-next-line max-line-length require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved"); _transfer(from, to, tokenId); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override { safeTransferFrom(from, to, tokenId, ""); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override { require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved"); _safeTransfer(from, to, tokenId, _data); } /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * `_data` is additional data, it has no specified format and it is sent in call to `to`. * * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g. * implement alternative mechanisms to perform token transfer, such as signature-based. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeTransfer(address from, address to, uint256 tokenId, bytes memory _data) internal virtual { _transfer(from, to, tokenId); require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer"); } /** * @dev Returns whether `tokenId` exists. * * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}. * * Tokens start existing when they are minted (`_mint`), * and stop existing when they are burned (`_burn`). */ function _exists(uint256 tokenId) internal view virtual returns (bool) { return _owners[tokenId] != address(0); } /** * @dev Returns whether `spender` is allowed to manage `tokenId`. * * Requirements: * * - `tokenId` must exist. */ function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) { require(_exists(tokenId), "ERC721: operator query for nonexistent token"); address owner = ERC721.ownerOf(tokenId); return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender)); } /** * @dev Safely mints `tokenId` and transfers it to `to`. * * Requirements: * * - `tokenId` must not exist. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeMint(address to, uint256 tokenId) internal virtual { _safeMint(to, tokenId, ""); } /** * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. */ function _safeMint(address to, uint256 tokenId, bytes memory _data) internal virtual { _mint(to, tokenId); require(_checkOnERC721Received(address(0), to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer"); } /** * @dev Mints `tokenId` and transfers it to `to`. * * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible * * Requirements: * * - `tokenId` must not exist. * - `to` cannot be the zero address. * * Emits a {Transfer} event. */ function _mint(address to, uint256 tokenId) internal virtual { require(to != address(0), "ERC721: mint to the zero address"); require(!_exists(tokenId), "ERC721: token already minted"); _beforeTokenTransfer(address(0), to, tokenId); _balances[to] += 1; _owners[tokenId] = to; emit Transfer(address(0), to, tokenId); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId) internal virtual { address owner = ERC721.ownerOf(tokenId); _beforeTokenTransfer(owner, address(0), tokenId); // Clear approvals _approve(address(0), tokenId); _balances[owner] -= 1; delete _owners[tokenId]; emit Transfer(owner, address(0), tokenId); } /** * @dev Transfers `tokenId` from `from` to `to`. * As opposed to {transferFrom}, this imposes no restrictions on msg.sender. * * Requirements: * * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * * Emits a {Transfer} event. */ function _transfer(address from, address to, uint256 tokenId) internal virtual { require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer of token that is not own"); require(to != address(0), "ERC721: transfer to the zero address"); _beforeTokenTransfer(from, to, tokenId); // Clear approvals from the previous owner _approve(address(0), tokenId); _balances[from] -= 1; _balances[to] += 1; _owners[tokenId] = to; emit Transfer(from, to, tokenId); } /** * @dev Approve `to` to operate on `tokenId` * * Emits a {Approval} event. */ function _approve(address to, uint256 tokenId) internal virtual { _tokenApprovals[tokenId] = to; emit Approval(ERC721.ownerOf(tokenId), to, tokenId); } /** * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address. * The call is not executed if the target address is not a contract. * * @param from address representing the previous owner of the given token ID * @param to target address that will receive the tokens * @param tokenId uint256 ID of the token to be transferred * @param _data bytes optional data to send along with the call * @return bool whether the call correctly returned the expected magic value */ function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data) private returns (bool) { if (to.isContract()) { try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) { return retval == IERC721Receiver(to).onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { revert("ERC721: transfer to non ERC721Receiver implementer"); } else { // solhint-disable-next-line no-inline-assembly assembly { revert(add(32, reason), mload(reason)) } } } } else { return true; } } /** * @dev Hook that is called before any token transfer. This includes minting * and burning. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, ``from``'s `tokenId` will be burned. * - `from` cannot be the zero address. * - `to` cannot be the zero address. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual { } } bat-0.19.0/tests/syntax-tests/source/Solidity/LICENSE.md000064400000000000000000000023640072674642500210520ustar 00000000000000The `ERC721.sol` file has been added from [](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/ERC721.sol) under the following license: The MIT License (MIT) Copyright (c) 2016-2020 zOS Global Limited Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. bat-0.19.0/tests/syntax-tests/source/Strace/ls.strace000064400000000000000000000150620072674642500207070ustar 00000000000000execve("/usr/bin/ls", ["ls"], 0x7fff7d89cea0 /* 34 vars */) = 0 brk(NULL) = 0x55bc0a294000 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory) openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=45404, ...}) = 0 mmap(NULL, 45404, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f7066972000 close(3) = 0 openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libselinux.so.1", O_RDONLY|O_CLOEXEC) = 3 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0@k\0\0\0\0\0\0"..., 832) = 832 fstat(3, {st_mode=S_IFREG|0644, st_size=155296, ...}) = 0 mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7066970000 mmap(NULL, 2259632, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f7066748000 mprotect(0x7f706676d000, 2093056, PROT_NONE) = 0 mmap(0x7f706696c000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x24000) = 0x7f706696c000 mmap(0x7f706696e000, 6832, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f706696e000 close(3) = 0 openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3 read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\260A\2\0\0\0\0\0"..., 832) = 832 fstat(3, {st_mode=S_IFREG|0755, st_size=1824496, ...}) = 0 mmap(NULL, 1837056, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f7066587000 mprotect(0x7f70665a9000, 1658880, PROT_NONE) = 0 mmap(0x7f70665a9000, 1343488, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x22000) = 0x7f70665a9000 mmap(0x7f70666f1000, 311296, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x16a000) = 0x7f70666f1000 mmap(0x7f706673e000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1b6000) = 0x7f706673e000 mmap(0x7f7066744000, 14336, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f7066744000 close(3) = 0 openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libpcre.so.3", O_RDONLY|O_CLOEXEC) = 3 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\340!\0\0\0\0\0\0"..., 832) = 832 fstat(3, {st_mode=S_IFREG|0644, st_size=468944, ...}) = 0 mmap(NULL, 471304, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f7066513000 mmap(0x7f7066515000, 335872, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x2000) = 0x7f7066515000 mmap(0x7f7066567000, 122880, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x54000) = 0x7f7066567000 mmap(0x7f7066585000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x71000) = 0x7f7066585000 close(3) = 0 openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libdl.so.2", O_RDONLY|O_CLOEXEC) = 3 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0000\21\0\0\0\0\0\0"..., 832) = 832 fstat(3, {st_mode=S_IFREG|0644, st_size=14592, ...}) = 0 mmap(NULL, 16656, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f706650e000 mmap(0x7f706650f000, 4096, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1000) = 0x7f706650f000 mmap(0x7f7066510000, 4096, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x2000) = 0x7f7066510000 mmap(0x7f7066511000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x2000) = 0x7f7066511000 close(3) = 0 openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libpthread.so.0", O_RDONLY|O_CLOEXEC) = 3 read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0@l\0\0\0\0\0\0"..., 832) = 832 fstat(3, {st_mode=S_IFREG|0755, st_size=146968, ...}) = 0 mmap(NULL, 132288, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f70664ed000 mmap(0x7f70664f3000, 61440, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x6000) = 0x7f70664f3000 mmap(0x7f7066502000, 24576, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x15000) = 0x7f7066502000 mmap(0x7f7066508000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1a000) = 0x7f7066508000 mmap(0x7f706650a000, 13504, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f706650a000 close(3) = 0 mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f70664eb000 arch_prctl(ARCH_SET_FS, 0x7f70664ec380) = 0 mprotect(0x7f706673e000, 16384, PROT_READ) = 0 mprotect(0x7f7066508000, 4096, PROT_READ) = 0 mprotect(0x7f7066511000, 4096, PROT_READ) = 0 mprotect(0x7f7066585000, 4096, PROT_READ) = 0 mprotect(0x7f706696c000, 4096, PROT_READ) = 0 mprotect(0x55bc08de8000, 4096, PROT_READ) = 0 mprotect(0x7f70669a5000, 4096, PROT_READ) = 0 munmap(0x7f7066972000, 45404) = 0 set_tid_address(0x7f70664ec650) = 1737 set_robust_list(0x7f70664ec660, 24) = 0 rt_sigaction(SIGRTMIN, {sa_handler=0x7f70664f36b0, sa_mask=[], sa_flags=SA_RESTORER|SA_SIGINFO, sa_restorer=0x7f70664ff730}, NULL, 8) = 0 rt_sigaction(SIGRT_1, {sa_handler=0x7f70664f3740, sa_mask=[], sa_flags=SA_RESTORER|SA_RESTART|SA_SIGINFO, sa_restorer=0x7f70664ff730}, NULL, 8) = 0 rt_sigprocmask(SIG_UNBLOCK, [RTMIN RT_1], NULL, 8) = 0 prlimit64(0, RLIMIT_STACK, NULL, {rlim_cur=8192*1024, rlim_max=RLIM64_INFINITY}) = 0 statfs("/sys/fs/selinux", 0x7ffd655ea110) = -1 ENOENT (No such file or directory) statfs("/selinux", 0x7ffd655ea110) = -1 ENOENT (No such file or directory) brk(NULL) = 0x55bc0a294000 brk(0x55bc0a2b5000) = 0x55bc0a2b5000 openat(AT_FDCWD, "/proc/filesystems", O_RDONLY|O_CLOEXEC) = 3 fstat(3, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0 read(3, "nodev\tsysfs\nnodev\trootfs\nnodev\tr"..., 1024) = 333 read(3, "", 1024) = 0 close(3) = 0 access("/etc/selinux/config", F_OK) = -1 ENOENT (No such file or directory) openat(AT_FDCWD, "/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=3031696, ...}) = 0 mmap(NULL, 3031696, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f7066206000 close(3) = 0 ioctl(1, TCGETS, {B38400 opost isig icanon echo ...}) = 0 ioctl(1, TIOCGWINSZ, {ws_row=46, ws_col=173, ws_xpixel=0, ws_ypixel=0}) = 0 openat(AT_FDCWD, ".", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_DIRECTORY) = 3 fstat(3, {st_mode=S_IFDIR|0700, st_size=4096, ...}) = 0 getdents64(3, /* 3 entries */, 32768) = 80 getdents64(3, /* 0 entries */, 32768) = 0 close(3) = 0 fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(0x88, 0), ...}) = 0 write(1, "ls.strace\n", 10) = 10 close(1) = 0 close(2) = 0 exit_group(0) = ? +++ exited with 0 +++ bat-0.19.0/tests/syntax-tests/source/Stylus/LICENSE.md000064400000000000000000000023040072674642500205470ustar 00000000000000The `gradients.styl` file has been added from https://github.com/stylus/nib under the following license: ```text The MIT License (MIT) Copyright (c) 2014 TJ Holowaychuk Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ``` bat-0.19.0/tests/syntax-tests/source/Stylus/gradients.styl000064400000000000000000000037400072674642500220450ustar 00000000000000@import 'config' /* * Implicit color stop position. */ pos-in-stops(i, stops) len = length(stops) if len - 1 == i 100% else if i unit(i / len * 100, '%') else 0 /* * Normalize color stops: * * - (color pos) -> (pos color) * - (color) -> (implied-pos color) * */ normalize-stops(stops) stops = clone(stops) for stop, i in stops if length(stop) == 1 color = stop[0] stop[0] = pos-in-stops(i, stops) stop[1] = color else if typeof(stop[1]) == 'unit' pos = stop[1] stop[1] = stop[0] stop[0] = pos stops /* * Join color stops with the given translation function. */ join-stops(stops, translate) str = '' len = length(stops) for stop, i in stops str += ', ' if i pos = stop[0] color = stop[1] str += translate(color, pos) unquote(str) /* * Standard color stop. */ std-stop(color, pos) '%s %s' % (color pos) /* * Create a linear gradient with the given start position * and variable number of color stops. * * Examples: * * background: linear-gradient(top, red, green, blue) * background: linear-gradient(bottom, red, green 50%, blue) * background: linear-gradient(bottom, red, 50% green, blue) * background: linear-gradient(bottom, red, 50% green, 90% white, blue) * */ linear-gradient(start, stops...) error('color stops required') unless length(stops) unquote('linear-gradient(' + join(', ',arguments) + ')') /* * Create a linear gradient image with the given start position * and variable number of color stops. */ linear-gradient-image(start, stops...) error('node-canvas is required for linear-gradient-image()') unless has-canvas stops = stops[0] if length(stops) == 1 error('gradient image size required') unless start[0] is a 'unit' size = start[0] start = start[1] or 'top' grad = create-gradient-image(size, start) stops = normalize-stops(stops) add-color-stop(grad, stop[0], stop[1]) for stop in stops 'url(%s)' % gradient-data-uri(grad) bat-0.19.0/tests/syntax-tests/source/Svelte/App.svelte000064400000000000000000000021720072674642500210510ustar 00000000000000
{#if item} {:else if page} {/if}
bat-0.19.0/tests/syntax-tests/source/Svelte/LICENSE.md000064400000000000000000000024310072674642500205070ustar 00000000000000The `App.svelte` file has been added from: https://github.com/sveltejs/svelte/blob/master/site/content/examples/21-miscellaneous/01-hacker-news/App.svelte Under the following license: Copyright (c) 2016-20 [these people](https://github.com/sveltejs/svelte/graphs/contributors) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. bat-0.19.0/tests/syntax-tests/source/Swift/test.swift000064400000000000000000000200620072674642500207720ustar 00000000000000class Person { // We can define class property here var age = 25 // Implement Class initializer. Initializers are called when a new object of this class is created init() { print(“A new instance of this class Person is created.”) } } // We can now create an instance of class Person - an object - by putting parentheses after the class name let personObj = Person() // Once an instance of Person class is created we can access its properties using the dot “.” syntax. print(“This person age is \(personObj.age)”) import Foundation class Friend : Comparable { let name : String let age : Int init(name : String, age: Int) { self.name = name self.age = age } } func < (lhs: Friend, rhs: Friend) -> Bool { return lhs.age < rhs.age }; func > (lhs: Friend, rhs: Friend) -> Bool { return lhs.age > rhs.age } func == (lhs: Friend, rhs: Friend) -> Bool { var returnValue = false if (lhs.name == rhs.name) && (lhs.age == rhs.age) { returnValue = true } return returnValue } let friend1 = Friend(name: "Sergey", age: 35) let friend2 = Friend(name: "Sergey", age: 30) print("Compare Friend object. Same person? (friend1 == friend2)") func sayHelloWorld() { print("Hello World") } // Call function sayHelloWorld() func printOutFriendNames(names: String...) { for name in names { print(name) } } // Call the printOutFriendNames with two parameters printOutFriendNames("Sergey", "Bill") // Call the function with more parameters printOutFriendNames("Sergey", "Bill", "Max") let simpleClosure = { print("From a simpleClosure") } // Call closure simpleClosure() let fullName = { (firstName:String, lastName:String)->String in return firstName + " " + lastName } // Call Closure let myFullName = fullName("Sergey", "Kargopolov") print("My full name is \(myFullName)") let myDictionary = [String:String]() // Another way to create an empty dictionary let myDictionary2:[String:String] = [:] // Keys in dictionary can also be of type Int let myDictionary3 = [Int:String]() var myDictionary = ["first_name": "Sergey", "last_name": "Kargopolov"] // print to preview print(myDictionary) // Add a new key with a value myDictionary["user_id"] = "f5h7ru0tJurY8f7g5s6fd" // We should now have 3 key value pairs printed print(myDictionary) var myDictionary = ["first_name": "Sergey", "last_name": "Kargopolov"] // Loop through dictionary keys and print values for (key,value) in myDictionary { print("\(key) = \(value)") } class Friend { let name : String let age : Int init(name : String, age: Int) { self.name = name self.age = age } } var friends:[Friend] = [] let friend1 = Friend(name: "Sergey", age: 30) let friend2 = Friend(name: "Bill", age: 35) let friend3 = Friend(name: "Michael", age: 21) friends.append(friend1) friends.append(friend2) friends.append(friend3) printFriends(friends: friends) // Get sorted array in descending order (largest to the smallest number) let sortedFriends = friends.sorted(by: { $0.age > $1.age }) printFriends(friends: sortedFriends) // Get sorted array in ascending order (smallest to the largest number) let sortedFriendsAscendingOrder = friends.sorted(by: { $0.age < $1.age }) printFriends(friends: sortedFriendsAscendingOrder) func printFriends(friends: [Friend]) { for friendEntry in friends { print("Name: \(friendEntry.name), age: \(friendEntry.age)") } } import UIKit class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) // Create destination URL let documentsUrl:URL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first as URL! let destinationFileUrl = documentsUrl.appendingPathComponent("downloadedFile.jpg") //Create URL to the source file you want to download let fileURL = URL(string: "https://s3.amazonaws.com/learn-swift/IMG_0001.JPG") let sessionConfig = URLSessionConfiguration.default let session = URLSession(configuration: sessionConfig) let request = URLRequest(url:fileURL!) let task = session.downloadTask(with: request) { (tempLocalUrl, response, error) in if let tempLocalUrl = tempLocalUrl, error == nil { // Success if let statusCode = (response as? HTTPURLResponse)?.statusCode { print("Successfully downloaded. Status code: \(statusCode)") } do { try FileManager.default.copyItem(at: tempLocalUrl, to: destinationFileUrl) } catch (let writeError) { print("Error creating a file \(destinationFileUrl) : \(writeError)") } } else { print("Error took place while downloading a file. Error description: %@", error?.localizedDescription); } } task.resume() } } do { // Convert JSON Object received from server side into Swift NSArray. // Note the use "try" if let convertedJsonIntoArray = try JSONSerialization.JSONObjectWithData(data!, options: []) as? NSArray { } } catch let error as NSError { print(error.localizedDescription) } DispatchQueue.global(qos: .userInitiated).async { // Do some time consuming task in this background thread // Mobile app will remain to be responsive to user actions print("Performing time consuming task in this background thread") DispatchQueue.main.async { // Task consuming task has completed // Update UI from this block of code print("Time consuming task has completed. From here we are allowed to update user interface.") } } import UIKit class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. let button = UIButton(type: UIButtonType.system) as UIButton let xPostion:CGFloat = 50 let yPostion:CGFloat = 100 let buttonWidth:CGFloat = 150 let buttonHeight:CGFloat = 45 button.frame = CGRect(x:xPostion, y:yPostion, width:buttonWidth, height:buttonHeight) button.backgroundColor = UIColor.lightGray button.setTitle("Tap me", for: UIControlState.normal) button.tintColor = UIColor.black button.addTarget(self, action: #selector(ViewController.buttonAction(_:)), for: .touchUpInside) self.view.addSubview(button) } func buttonAction(_ sender:UIButton!) { print("Button tapped") } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } } import UIKit class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() //Create Activity Indicator let myActivityIndicator = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.gray) // Position Activity Indicator in the center of the main view myActivityIndicator.center = view.center // If needed, you can prevent Acivity Indicator from hiding when stopAnimating() is called myActivityIndicator.hidesWhenStopped = false // Start Activity Indicator myActivityIndicator.startAnimating() // Call stopAnimating() when need to stop activity indicator //myActivityIndicator.stopAnimating() view.addSubview(myActivityIndicator) } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } } bat-0.19.0/tests/syntax-tests/source/Syslog/example.syslog000064400000000000000000000036240072674642500220230ustar 00000000000000Apr 4 00:00:01 hostname-here systemd[1]: logrotate.service: Succeeded. Apr 4 00:00:01 hostname-here systemd[1]: Finished Rotate log files. Apr 4 00:00:01 hostname-here colord[920]: failed to get session [pid 137485]: No data available Apr 4 00:00:21 hostname-here kernel: [55604.908232] audit: type=1400 audit(1617483621.094:28): apparmor="DENIED" operation="capable" profile="/usr/sbin/cups-browsed" pid=59311 comm="cups-browsed" capability=23 capname="sys_nice" Apr 4 00:01:38 hostname-here systemd-resolved[721]: Server returned error NXDOMAIN, mitigating potential DNS violation DVE-2018-0001, retrying transaction with reduced feature level UDP. Apr 4 00:04:46 hostname-here ntpd[952]: Soliciting pool server 255.76.59.37 Apr 4 00:05:21 hostname-here ntpd[952]: ::1 local addr 0:0:0:0:0:0:0:1 -> Apr 4 00:06:29 hostname-here ntpd[952]: receive: Unexpected origin timestamp 0xe414a8d1.82e825f5 does not match aorg 0xe414a8d5.82c50d8c from server@127.0.0.1 xmt 0xe414a8d1.e671d7c4 Apr 4 09:30:01 hostname-here CRON[89278]: (root) CMD ([ -x /etc/init.d/anacron ] && if [ ! -d /run/systemd/system ]; then /usr/sbin/invoke-rc.d anacron start >/dev/null; fi) Apr 4 16:32:07 hostname-here NetworkManager[740]: [1617629527.1101] manager: NetworkManager state is now CONNECTED_GLOBAL Apr 4 22:00:45 hostname-here dbus-daemon[1094]: [session uid=1000 pid=1094] Successfully activated service 'io.github.celluloid_player.Celluloid' Aug 11 13:29:06 hostname-here insomnia_insomnia.desktop[142666]: 13:29:06.316 › [updater] Updater not running platform=linux dev=false Aug 11 13:36:34 192.168.220.5 nginx: 2021/08/11 13:36:34 [debug] 2031#2031: epoll add event: fd:6 op:1 ev:00002001 Aug 11 21:31:08 ::1 nginx: 2021/08/11 21:31:08 [debug] 760831#760831: epoll add event: fd:6 op:1 ev:10000001 Aug 11 21:40:31 hostname-here scop hello Aug 16 21:38:21 hostname-here systemd[1]: Finished Cleanup of Temporary Directories. bat-0.19.0/tests/syntax-tests/source/SystemVerilog/output.sv000064400000000000000000000041120072674642500223650ustar 00000000000000`timescale 1ns/1ps // Design Code module ADDER( input clk, input [7:0] a, input [7:0] b, input bIsPos, output reg [8:0] result ); always @ (posedge clk) begin if (bIsPos) begin result <= a + b; end else begin result <= a - b; end end endmodule: ADDER interface adder_if( input bit clk, input [7:0] a, input [7:0] b, input bIsPos, input [8:0] result ); clocking cb @(posedge clk); output a; output b; output bIsPos; input result; endclocking : cb endinterface: adder_if bind ADDER adder_if my_adder_if( .clk(clk), .a(a), .b(b), .bIsPos(bIsPos), .result(result) ); // Testbench Code import uvm_pkg::*; `include "uvm_macros.svh" class testbench_env extends uvm_env; virtual adder_if m_if; function new(string name, uvm_component parent = null); super.new(name, parent); endfunction function void connect_phase(uvm_phase phase); assert(uvm_resource_db#(virtual adder_if)::read_by_name(get_full_name(), "adder_if", m_if)); endfunction: connect_phase task run_phase(uvm_phase phase); phase.raise_objection(this); `uvm_info(get_name(), "Starting test!", UVM_HIGH); begin int a = 8'h4, b = 8'h5; @(m_if.cb); m_if.cb.a <= a; m_if.cb.b <= b; m_if.cb.bIsPos <= 1'b1; repeat(2) @(m_if.cb); `uvm_info(get_name(), $sformatf("%0d + %0d = %0d", a, b, m_if.cb.result), UVM_LOW); end `uvm_info(get_name(), "Ending test!", UVM_HIGH); phase.drop_objection(this); endtask: run_phase endclass module top; bit clk; env environment; ADDER dut(.clk (clk)); initial begin environment = new("testbench_env"); uvm_resource_db#(virtual adder_if)::set("env", "adder_if", dut.my_adder_if); clk = 0; run_test(); end // Clock generation initial begin forever begin #(1) clk = ~clk; end end endmodule bat-0.19.0/tests/syntax-tests/source/Tcl/test.tcl000064400000000000000000000005030072674642500200440ustar 00000000000000set part1 hello set part2 how; set part3 are set part4 you set part2; set greeting $part1$part2$part3$part4 set somevar { This is a literal $ sign, and this \} escaped brace remains uninterpreted } set name Neo set greeting "Hello, $name" variable name NotNeo namespace eval people { set name NeoAgain } bat-0.19.0/tests/syntax-tests/source/TeX/main.tex000064400000000000000000000072620072674642500200160ustar 00000000000000% !TeX program = lualatex \documentclass{article} \usepackage{verse} \usepackage{fontspec} \newcommand{\attrib}[1]{\nopagebreak{\raggedleft\footnotesize #1\par}} \renewcommand{\poemtitlefont}{\normalfont\large\itshape\centering} \setmainfont{DejaVu Sans} \begin{document} \poemtitle{სევდამოსილი} \settowidth{\versewidth}{Than Tycho Brahe, or Erra Pater:} \begin{verse}[\versewidth] ცა პირს შეიკრავს, ჩამობნელდება, \\ გრილი ნიავი მოცერავს ფერდობს, \\ ჩვენი სიცოცხლე უმალ ნელდება, \\ იმედი აქცევს არსს უმოქმედოს. \\ \bigskip სხვისი წესებით აგებულ სხეულს, \\ მიჯაჭვულია გონებით, ხორცით, \\ მილიონიდან განსახებს ეულს, \\ დილის ნათება ეწყება ლოცვით. \\ \bigskip ახალგაზრდაა, დიდსულოვანი, \\ ზოგჯერ რაინდი, ხანაც მგოსანი, \\ თავდადებული, კონტრნაღმოსანი, \\ თვისი სამიზნე - დოტას როშანი. \\ \bigskip თუ შეიყვარებ, არასდროს გავნებს, \\ დღეგამოშვებით იბარებს თავნებს, \\ ყველას ჰპატიობს, გულქვას და თავნებს, \\ სხვის მაგივრადაც საკუთარ თავს ვნებს. \\ \bigskip მისი სახელი - თენგიზი (დიდი), \\ სახის იერი - ნაზი და მშვიდი, \\ ვიზუალურად - ათიდან შვიდი, \\ ხანმოკლე ვითარც ეფემერიდი. \\ \bigskip მე ის მახარებს რომ სხვას ახარებ, \\ შაირს რომ იტყვი, იმასხარავებ, \\ კეთილ საქმეს რომ არვის ახარბებ, \\ გულიანად რომ გადიხარხარებ. \\ \bigskip როცა დაგჭირდეს, ჭირში თუ ლხინში, \\ მიწაზე, წყალში... ნავში თუ ქარში, \\ ჩათვალე, მიდგას კოდურად ჯინში, \\ სათქმელი არის? იქნება პირში. \\ \bigskip შენ არ იჯავრო, - კარგად იქნები, \\ მიხედე შენს თავს, ეძიე უკვლევს, \\ მეგზურად გყვება ჩუმი ფიქრები, \\ შეუმჩნევლად რომ გითვლიან სულ წლებს. \\ \bigskip გილოცავ ამ დღეს, დედამ რომ გშობა, \\ როცა შეჰმატე გარემოს ფერები, \\ ერთად გეტაროთ აღდგომა, შობა, \\ მე კი ლექსიდან მოგეფერები. \\ \bigskip \end{verse} \attrib{გიორგი ბერიაშვილი (1999--$\infty)$} \end{document} bat-0.19.0/tests/syntax-tests/source/Terraform/main.tf000064400000000000000000000023070072674642500210630ustar 00000000000000provider "github" { organization = var.github_organization } resource "tls_private_key" "deploy_key" { algorithm = "RSA" rsa_bits = "4096" } resource "null_resource" "private_key_file" { triggers = { deploy_key = tls_private_key.deploy_key.private_key_pem } provisioner "file" { content = tls_private_key.deploy_key.private_key_pem destination = "~/${var.repo_name}_deploy_key.pem" connection { type = "ssh" user = "centos" private_key = var.terraform_ssh_key host = var.server_ip } } provisioner "remote-exec" { inline = [ "sudo mv ~/${var.repo_name}_deploy_key.pem /app/ssh_keys/", "sudo chmod 0400 /app/ssh_keys/${var.repo_name}_deploy_key.pem", "sudo chown app:app /app/ssh_keys/${var.repo_name}_deploy_key.pem", ] connection { type = "ssh" user = "centos" private_key = var.terraform_ssh_key host = var.server_ip } } } resource "github_repository_deploy_key" "repo_deploy_key" { title = "${var.env_name} Deploy Key" repository = var.repo_name key = tls_private_key.deploy_key.public_key_openssh read_only = var.read_only } bat-0.19.0/tests/syntax-tests/source/Textile/test.textile000064400000000000000000000010540072674642500216360ustar 00000000000000###. Single line comment ###.. Multi line comment. This line is also part of comment. Continues till next block element p. This is not a comment, but I am a paragraph. h1. This is an

h2. This is an

h3. This is an

h4. This is an

h5. This is an

h6. This is an
-- * Item ** Sub-Item * Another item ** Another sub-item ** Yet another sub-item *** Three levels deep p{color:red}. This line will be red. %span% are enclosed in percent symbols. div. This is a new div element bat-0.19.0/tests/syntax-tests/source/TypeScript/LICENSE.md000064400000000000000000000022720072674642500213560ustar 00000000000000The `example.ts` file has been added from https://www.typescriptlang.org/docs/handbook/ under the following license: The MIT License (MIT) Copyright (c) Microsoft Corporation Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. bat-0.19.0/tests/syntax-tests/source/TypeScript/example.ts000064400000000000000000000031670072674642500217610ustar 00000000000000let letNumber = 10; const constNumber = 20; const bool: boolean = true; const list: number[] = [1, 2, 3]; const array: Array = [1, 2, 3]; const pair: [string, number] = ['hello', 10]; for (let i = 0; i < list.length; i += 1) { console.log(list[i]); } if (bool) { console.log('True'); } else { console.log('False'); } const str: string = 'Jake'; const templateStr: string = `Hello, ${str}!`; // A comment /* * Multiline comments * Multiline comments */ interface SquareConfig { label: string; color?: string; width?: number; [propName: string]: any; } interface SearchFunc { (source: string, subString: string): boolean; } enum Color { Red, Green, } type Easing = "ease-in" | "ease-out" | "ease-in-out"; class Greeter { private readonly greeting: string; constructor(message: string) { this.greeting = message; } greet() { return "Hello, " + this.greeting; } } let greeter = new Greeter("world"); class Animal { move(distanceInMeters: number = 0) { console.log(`Animal moved ${distanceInMeters}m.`); } } class Dog extends Animal { bark() { console.log("Woof! Woof!"); } } const dog = new Dog(); dog.bark(); dog.move(10); dog.bark(); class Point { x: number; y: number; } interface Point3d extends Point { z: number; } let point3d: Point3d = { x: 1, y: 2, z: 3 }; function add(x, y) { return x + y; } let myAdd = function (x, y) { return x + y; }; (function () { console.log('IIFE'); }()); function identity(arg: T): T { return arg; } let myIdentity: (arg: T) => T = identity; class GenericNumber { zeroValue: T; add: (x: T, y: T) => T; } bat-0.19.0/tests/syntax-tests/source/TypeScriptReact/LICENSE.md000064400000000000000000000022760072674642500223410ustar 00000000000000The `app.tsx` file has been added from https://github.com/Lemoncode/react-typescript-samples under the following license: ```text The MIT License (MIT) Copyright (c) 2016 brauliodiez Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ``` bat-0.19.0/tests/syntax-tests/source/TypeScriptReact/app.tsx000064400000000000000000000014760072674642500222560ustar 00000000000000import * as React from "react"; import { HelloComponent } from "./hello"; import { NameEditComponent } from "./nameEdit"; export const App = () => { const [name, setName] = React.useState("defaultUserName"); const [editingName, setEditingName] = React.useState("defaultUserName"); const loadUsername = () => { setTimeout(() => { setName("name from async call"); setEditingName("name from async call"); }, 500); }; React.useEffect(() => { loadUsername(); }, []); const setUsernameState = () => { setName(editingName); }; return ( <> ); }; bat-0.19.0/tests/syntax-tests/source/Verilog/LICENSE.md000064400000000000000000000253400072674642500206600ustar 00000000000000The `div_pipelined.v` file has been added from https://github.com/seldridge/verilog under the following license: ```text Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "{}" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright {yyyy} {name of copyright owner} Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ``` bat-0.19.0/tests/syntax-tests/source/Verilog/div_pipelined.v000064400000000000000000000163320072674642500222570ustar 00000000000000// Copyright 2018 Schuyler Eldridge // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Implements a fixed-point parameterized pipelined division // operation. Outputs are expected to be on range [-1,1), techincally // [-1,2^(BITS-1)-1/2^(BITS-1)]. There is no convergent rounding. // // [TODO] Implement optional convergent rounding and some form of // variable output binary point placement. There are arguments in // these changes that make sense (specifically, adding an additional // bit results in a gain of one value when all the other 2^6 values // greater than 1 aren't used). Other improvements that are needed: 1) // quotient_gen is getting smaller by one bit in every stage, it would // make more sense to generate this as such, 2) there's some weird // initial behavior after rst_n is deasserted, you get weird output on // the quotient line for a number of cycles. // // [TODO] This doesn't exactly behave as expected if you specify // different BITS and STAGES parameters (which for a functional // module, should be implemented). Note, that this technically works, // but needs more investigation to fully understand its properties. `timescale 1ns / 1ps module div_pipelined ( input clk, input rst_n, input start, input [BITS-1:0] dividend, input [BITS-1:0] divisor, output reg data_valid, output reg div_by_zero, output reg [STAGES-1:0] quotient // output reg [7:0] quotient_correct ); // WARNING!!! THESE PARAMETERS ARE INTENDED TO BE MODIFIED IN A TOP // LEVEL MODULE. LOCAL CHANGES HERE WILL, MOST LIKELY, BE // OVERWRITTEN! parameter BITS = 8, STAGES = BITS; // y = a/bQ reg [STAGES-1:0] start_gen, negative_quotient_gen, div_by_zero_gen; reg [BITS*2*(STAGES-1)-1:0] dividend_gen, divisor_gen, quotient_gen; wire [BITS-1:0] pad_dividend; wire [BITS-2:0] pad_divisor; assign pad_dividend = 0; assign pad_divisor = 0; // sign conversion stage always @ (posedge clk or negedge rst_n) begin if (!rst_n) begin div_by_zero_gen[0] <= 0; start_gen[0] <=0; negative_quotient_gen[0] <= 0; dividend_gen[BITS*2-1:0] <= 0; divisor_gen[BITS*2-1:0] <= 0; end else begin div_by_zero_gen[0] <= (divisor == 0); start_gen[0] <= start; negative_quotient_gen[0] <= dividend[BITS-1] ^ divisor[BITS-1]; dividend_gen[BITS*2-1:0] <= (dividend[BITS-1]) ? ~{dividend,pad_dividend} + 1 : {dividend,pad_dividend}; divisor_gen[BITS*2-1:0] <= (divisor [BITS-1]) ? ~{1'b1,divisor, pad_divisor} + 1 : {1'b0,divisor, pad_divisor}; end end // first computation stage always @ (posedge clk or negedge rst_n) begin if (!rst_n) begin div_by_zero_gen[1] <= 0; start_gen[1] <= 0; negative_quotient_gen[1] <= 0; divisor_gen[BITS*2*2-1:BITS*2] <= 0; quotient_gen[BITS*2-1:0] <= 0; dividend_gen[BITS*2*2-1:BITS*2] <= 0; end else begin div_by_zero_gen[1] <= div_by_zero_gen[0]; start_gen[1] <= start_gen[0]; negative_quotient_gen[1] <= negative_quotient_gen[0]; divisor_gen[BITS*2*2-1:BITS*2] <= divisor_gen[BITS*2-1:0] >> 1; if ( dividend_gen[BITS*2-1:0] >= divisor_gen[BITS*2-1:0]) begin quotient_gen[BITS*2-1:0] <= 1 << STAGES - 2; dividend_gen[BITS*2*2-1:BITS*2] <= dividend_gen[BITS*2-1:0] - divisor_gen[BITS*2-1:0]; end else begin quotient_gen[BITS*2-1:0] <= 0; dividend_gen[BITS*2*2-1:BITS*2] <= dividend_gen[BITS*2-1:0]; end end // else: !if(!rst_n) end // always @ (posedge clk) generate genvar i; for (i = 1; i < STAGES - 2; i = i + 1) begin : pipeline always @ (posedge clk or negedge rst_n) begin if (!rst_n) begin div_by_zero_gen[i+1] <= 0; start_gen[i+1] <= 0; negative_quotient_gen[i+1] <= 0; divisor_gen[BITS*2*(i+2)-1:BITS*2*(i+1)] <= 0; quotient_gen[BITS*2*(i+1)-1:BITS*2*i] <= 0; dividend_gen[BITS*2*(i+2)-1:BITS*2*(i+1)] <= 0; end else begin div_by_zero_gen[i+1] <= div_by_zero_gen[i]; start_gen[i+1] <= start_gen[i]; negative_quotient_gen[i+1] <= negative_quotient_gen[i]; divisor_gen[BITS*2*(i+2)-1:BITS*2*(i+1)] <= divisor_gen[BITS*2*(i+1)-1:BITS*2*i] >> 1; if (dividend_gen[BITS*2*(i+1)-1:BITS*2*i] >= divisor_gen[BITS*2*(i+1)-1:BITS*2*i]) begin quotient_gen[BITS*2*(i+1)-1:BITS*2*i] <= quotient_gen[BITS*2*i-1:BITS*2*(i-1)] | (1 << (STAGES-2-i)); dividend_gen[BITS*2*(i+2)-1:BITS*2*(i+1)] <= dividend_gen[BITS*2*(i+1)-1:BITS*2*i] - divisor_gen[BITS*2*(i+1)-1:BITS*2*i]; end else begin quotient_gen[BITS*2*(i+1)-1:BITS*2*i] <= quotient_gen[BITS*2*i-1:BITS*2*(i-1)]; dividend_gen[BITS*2*(i+2)-1:BITS*2*(i+1)] <= dividend_gen[BITS*2*(i+1)-1:BITS*2*i]; end end // else: !if(!rst_n) end // always @ (posedge clk or negedge rst_n) end // block: pipeline endgenerate // last computation stage always @ (posedge clk or negedge rst_n) begin if (!rst_n) begin div_by_zero_gen[STAGES-1] <= 0; start_gen[STAGES-1] <= 0; negative_quotient_gen[STAGES-1] <= 0; quotient_gen[BITS*2*(STAGES-1)-1:BITS*2*(STAGES-2)] <= 0; end else begin div_by_zero_gen[STAGES-1] <= div_by_zero_gen[STAGES-2]; start_gen[STAGES-1] <= start_gen[STAGES-2]; negative_quotient_gen[STAGES-1] <= negative_quotient_gen[STAGES-2]; if ( dividend_gen[BITS*2*(STAGES-1)-1:BITS*2*(STAGES-2)] >= divisor_gen[BITS*2*(STAGES-1)-1:BITS*2*(STAGES-2)] ) quotient_gen[BITS*2*(STAGES-1)-1:BITS*2*(STAGES-2)] <= quotient_gen[BITS*2*(STAGES-2)-1:BITS*2*(STAGES-3)] | 1; else quotient_gen[BITS*2*(STAGES-1)-1:BITS*2*(STAGES-2)] <= quotient_gen[BITS*2*(STAGES-2)-1:BITS*2*(STAGES-3)]; end // else: !if(!rst_n) end // always @ (posedge clk) // sign conversion stage always @ (posedge clk or negedge rst_n) begin if (!rst_n) begin div_by_zero <= 0; data_valid <= 0; quotient <= 0; end else begin div_by_zero <= div_by_zero_gen[STAGES-1]; data_valid <= start_gen[STAGES-1]; quotient <= (negative_quotient_gen[STAGES-1]) ? ~quotient_gen[BITS*2*(STAGES-1)-1:BITS*2*(STAGES-2)] + 1 : quotient_gen[BITS*2*(STAGES-1)-1:BITS*2*(STAGES-2)]; end end endmodule bat-0.19.0/tests/syntax-tests/source/VimL/source.vim000064400000000000000000000033730072674642500205330ustar 00000000000000if &compatible set nocompatible endif if has('win32') || has ('win64') let $VIMHOME = $HOME . "/vimfiles" elseif v:false && v:true echo "Can't get here" else let $VIMHOME = $HOME . "/.vim" endif " show existing tab with 2 spaces width set tabstop=2 " when indenting with '>', use 2 spaces width set shiftwidth=2 " always set autoindenting on set autoindent autocmd VimEnter * echo "Hello Vim" " Allow :W and :Wq to save too command! Wq :wq command! W :w augroup vimrc autocmd! autocmd FileType * echo "New filetype" augroup END function! s:echo(what) return a:what endfunction function! HelloWorld(name) let l:function_local = "function_local_var" let l:parts = split(l:function_local, "_") let l:greeting = "Hello " . a:name return s:echo(l:greeting) endfunction function! source#Hello() return "Hello from namespace" endfunction function! EchoFunc(...) for s in a:000 echon ' ' . s endfor endfunction imap =HelloWorld("World") command! -nargs=? Echo :call EchoFunc() " TODO test stuff let g:global = "global var" let s:script_var = "script var" let w:window_var = "window war" let b:buffer_var = "buffer war" let t:tab_var = "tab war" echo v:false 3 + 5 echo "Hello" ==# "Hello2" echo "Hello" ==? "Hello2" echo "Hello" == "Hello2" echo "Hello" is "Hello2" echo "Hello" isnot "Hello2" echo "Hello" =~ 'xx*' echo "Hello" !~ "Hello2" echo "Hello" !~ "Hello2" echo "/This/should/not/be/a/regex" " Error case from issue #1604 (https://github.com/sharkdp/bat/issues/1064) set runtimepath=~/foo/bar silent g/Aap/p let g:dict = {} let g:dict.item = ['l1', 'l2'] let g:dict2 = {'dict_item': ['l1', 'l2'], 'di2': 'x'} silent g/regex/ silent v/regex/ silent %s/regex/not_regex/ filetype plugin indent on syntax enable bat-0.19.0/tests/syntax-tests/source/Vue/example.vue000064400000000000000000000016720072674642500205620ustar 00000000000000 bat-0.19.0/tests/syntax-tests/source/Vyper/LICENSE.md000064400000000000000000000263730072674642500203650ustar 00000000000000The `crowdsale.vy` file has been added from [](https://github.com/binodnp/vyper-crowdsale/blob/master/contracts/crowdsale.v.py) under the following license: Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. bat-0.19.0/tests/syntax-tests/source/Vyper/crowdsale.vy000064400000000000000000000054660072674642500213240ustar 00000000000000# IndividuallyCappedCrowdsale # Contributors: Binod Nirvan # This file is released under Apache 2.0 license. # @dev Crowdsale with a limit for total contributions. # Ported from Open Zeppelin # https://github.com/OpenZeppelin # # See https://github.com/OpenZeppelin # Open Zeppelin tests ported: Crowdsale.test.js #@dev ERC20/223 Features referenced by this contract contract TokenContract: def transfer(_to: address, _value: uint256) -> bool: modifying # Event for token purchase logging # @param _purchaser who paid for the tokens # @param _beneficiary who got the tokens # @param _value weis paid for purchase # @param _amount amount of tokens purchased TokenPurchase: event({_purchaser: indexed(address), _beneficiary: indexed(address), _value: uint256(wei), _amount: uint256}) # The token being sold token: public(address) #Address where funds are collected wallet: public(address) # How many token units a buyer gets per wei. # The rate is the conversion between wei and the smallest and indivisible token unit. # So, if you are using a rate of 1 with a DetailedERC20 token with 3 decimals called TOK # 1 wei will give you 1 unit, or 0.001 TOK. rate: public(uint256) #Amount of wei raised weiRaised: public(uint256(wei)) @public def __init__(_rate: uint256, _wallet: address, _token: address): """ @dev Initializes this contract @param _rate Number of token units a buyer gets per wei @param _wallet Address where collected funds will be forwarded to @param _token Address of the token being sold """ assert _rate > 0, "Invalid value supplied for the parameter \"_rate\"." assert _wallet != ZERO_ADDRESS, "Invalid wallet address." assert _token != ZERO_ADDRESS, "Invalid token address." self.rate = _rate self.wallet = _wallet self.token = _token @private @constant def getTokenAmount(_weiAmount: uint256) -> uint256: return _weiAmount * self.rate @private def processTransaction(_sender: address, _beneficiary: address, _weiAmount: uint256(wei)): #pre validate assert _beneficiary != ZERO_ADDRESS, "Invalid address." assert _weiAmount != 0, "Invalid amount received." #calculate the number of tokens for the Ether contribution. tokens: uint256 = self.getTokenAmount(as_unitless_number(_weiAmount)) self.weiRaised += _weiAmount #process purchase assert TokenContract(self.token).transfer(_beneficiary, tokens), "Could not forward funds due to an unknown error." log.TokenPurchase(_sender, _beneficiary, _weiAmount, tokens) #forward funds to the receiving wallet address. send(self.wallet, _weiAmount) #post validate @public @payable def buyTokens(_beneficiary: address): self.processTransaction(msg.sender, _beneficiary, msg.value) @public @payable def __default__(): self.processTransaction(msg.sender, msg.sender, msg.value) bat-0.19.0/tests/syntax-tests/source/XAML/ItemPage.xaml000064400000000000000000000344010072674642500207620ustar 00000000000000 bat-0.19.0/tests/syntax-tests/source/XAML/LICENSE.md000064400000000000000000000024100072674642500200030ustar 00000000000000The `ItemPage.xaml` file has been added from https://github.com/microsoft/Xaml-Controls-Gallery under the following license: MIT License Copyright (c) Microsoft Corporation. All rights reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE bat-0.19.0/tests/syntax-tests/source/XML/example.xml000064400000000000000000000015770072674642500204700ustar 00000000000000 &name; bat-0.19.0/tests/syntax-tests/source/YAML/example.yaml000064400000000000000000000010650072674642500207240ustar 00000000000000--- # Simple example id: 3595 name: Test User username: "testuser" other_names: ['Bob', 'Bill', 'George'] hexa: 0x11c3 #inline comment octa: 021131 lastseen: .NAN enabled: true locked: false groups: - administrators - engineering - sfa address: > 123 Alphabet Way San Francisco, CA bio: | I am a hardworking person and a member of the executive staff phone: null email: ~ building_access: yes secure_access: no bulb: On fans: Off emails: executives: - bob@example.com - bill@example.com supervisors: - george@example.com bat-0.19.0/tests/syntax-tests/source/Zig/example.zig000064400000000000000000000047140072674642500205460ustar 00000000000000//! this is a top level doc, starts with "//!" const std = @import("std"); pub fn main() anyerror!void { const stdout = std.io.getStdOut().writer(); try stdout.print("Hello, {}!\n", .{"world"}); } const expect = std.testing.expect; test "comments" { // comments start with "//" until newline // foo bar baz const x = true; // another comment expect(x); } /// a doc comment starts with "///" /// multiple lines are merged together const Timestamp = struct { /// number of seconds since epoch seconds: i64, /// number of nanoseconds past the second nano: u32, const Self = @This(); pub fn unixEpoch() Self { return Self{ .seconds = 0, .nanos = 0, }; } }; const my_val = switch (std.Target.current.os.tag) { .linux => "Linux", else => "not Linux", }; const Book = enum { paperback, hardcover, ebook, pdf, }; const TokenType = union(enum) { int: isize, float: f64, string: []const u8, }; const array_lit: [4]u8 = .{ 11, 22, 33, 44 }; const sentinal_lit = [_:0]u8{ 1, 2, 3, 4 }; test "address of syntax" { // Get the address of a variable: const x: i32 = 1234; const x_ptr = &x; // Dereference a pointer: expect(x_ptr.* == 1234); // When you get the address of a const variable, you get a const pointer to a single item. expect(@TypeOf(x_ptr) == *const i32); // If you want to mutate the value, you'd need an address of a mutable variable: var y: i32 = 5678; const y_ptr = &y; expect(@TypeOf(y_ptr) == *i32); y_ptr.* += 1; expect(y_ptr.* == 5679); } // integer literals const decimal_int = 98222; const hex_int = 0xff; const another_hex_int = 0xFF; const octal_int = 0o755; const binary_int = 0b11110000; // underscores may be placed between two digits as a visual separator const one_billion = 1_000_000_000; const binary_mask = 0b1_1111_1111; const permissions = 0o7_5_5; const big_address = 0xFF80_0000_0000_0000; // float literals const floating_point = 123.0E+77; const another_float = 123.0; const yet_another = 123.0e+77; const hex_floating_point = 0x103.70p-5; const another_hex_float = 0x103.70; const yet_another_hex_float = 0x103.70P-5; // underscores may be placed between two digits as a visual separator const lightspeed = 299_792_458.000_000; const nanosecond = 0.000_000_001; const more_hex = 0x1234_5678.9ABC_CDEFp-10; fn max(comptime T: type, a: T, b: T) T { return if (a > b) a else b; } bat-0.19.0/tests/syntax-tests/source/dash/LICENSE.md000064400000000000000000000022650072674642500201710ustar 00000000000000The `shfm` file is a modified version of the file from https://github.com/dylanaraps/shfm, added under the following license: The MIT License (MIT) Copyright (c) 2020 Dylan Araps Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. bat-0.19.0/tests/syntax-tests/source/dash/shfm000064400000000000000000000215630072674642500174470ustar 00000000000000#!/usr/bin/env dash esc() { case $1 in # vt100 (IL is vt102) (DECTCEM is vt520) CUD) printf '%s[%sB' "$esc_c" "$2" ;; # cursor down CUP) printf '%s[%s;%sH' "$esc_c" "$2" "$3" ;; # cursor home CUU) printf '%s[%sA' "$esc_c" "$2" ;; # cursor up DECAWM) printf '%s[?7%s' "$esc_c" "$2" ;; # line wrap DECRC) printf '%s8' "$esc_c" ;; # cursor restore DECSC) printf '%s7' "$esc_c" ;; # cursor save DECSTBM) printf '%s[%s;%sr' "$esc_c" "$2" "$3" ;; # scroll region DECTCEM) printf '%s[?25%s' "$esc_c" "$2" ;; # cursor visible ED[0-2]) printf '%s[%sJ' "$esc_c" "${1#ED}" ;; # clear screen EL[0-2]) printf '%s[%sK' "$esc_c" "${1#EL}" ;; # clear line IL) printf '%s[%sL' "$esc_c" "$2" ;; # insert line SGR) printf '%s[%s;%sm' "$esc_c" "$2" "$3" ;; # colors # xterm (since 1988, supported widely) screen_alt) printf '%s[?1049%s' "$esc_c" "$2" ;; # alternate buffer esac } term_setup() { stty=$(stty -g) stty -icanon -echo esc screen_alt h esc DECAWM l esc DECTCEM l esc ED2 esc DECSTBM 1 "$((LINES - 2))" } term_reset() { esc DECAWM h >&2 esc DECTCEM h >&2 esc ED2 >&2 esc DECSTBM >&2 esc screen_alt l >&2 stty "$stty" # needed for cd-on-exit printf '%s\n' "$PWD" >&1 } term_resize() { # false-positive, behavior intentional, globbing is disabled. # shellcheck disable=2046 { set -f set +f -- $(stty size) } LINES=$1 COLUMNS=$2 # space for status_line bottom=$((LINES - 2)) } term_scroll_down() { case $((y - $#)) in [0-9]*) return esac y=$((y + 1)) y2=$((y2 + 1 < bottom ? y2 + 1 : bottom)) line_print "$((y - 1))" "$@" printf '\n' line_print "$y" "$@" status_line "$#" } term_scroll_up() { case $y in -*|0|1) return esac y=$((y - 1)) line_print "$((y + 1))" "$@" case $y2 in 1) esc IL ;; *) esc CUU; y2=$((y2 > 1 ? y2 - 1 : 1)) esac line_print "$y" "$@" status_line "$#" } cmd_run() { stty "$stty" esc DECTCEM h esc DECSTBM esc ED2 "$@" ||: esc DECSTBM 1 "$((LINES - 2))" esc DECTCEM l stty -icanon -echo hist=2 } file_escape() { tmp=$1 safe= # loop over string char by char while c=${tmp%"${tmp#?}"}; do case $c in '') return ;; [[:cntrl:]]) safe=$safe\? ;; *) safe=$safe$c ;; esac tmp=${tmp#?} done } hist_search() { hist=0 j=1 for file do case ${PWD%%/}/$file in "$old_pwd") y=$j y2=$((j > bottom ? mid : j)) cur=$file esac j=$((j + 1)) done } list_print() { esc ED2 esc CUP i=1 end=$((bottom + 1)) mid=$((bottom / 4 < 5 ? 1 : bottom / 4)) case $# in 1) [ -e "$1" ] || set -- empty esac case $hist in 2) # redraw after cmd run shift "$((y > y2 ? y - y2 : 0))" ;; 1) # redraw after go-to-parent hist_search "$@" shift "$((y >= bottom ? y - mid : 0))" ;; *) # everything else shift "$((y >= bottom ? y - bottom : 0))" ;; esac for file do case $i in "$y2") esc SGR 0 7 esac case $((i - end)) in -*) line_format "$file" esc CUD ;; esac i=$((i + 1)) done esc CUP "$((y > y2 ? y2 : y))" } redraw() { list_print "$@" status_line "$#" } status_line() { esc DECSC esc CUP "$LINES" case $USER in root) esc SGR 31 7 ;; *) esc SGR 34 7 ;; esac printf '%*s\r%s ' "$COLUMNS" "" "($y/$1)" case $ltype in '') printf %s "$PWD" ;; *) printf %s "$ltype" esac esc SGR 0 0 esc DECRC } prompt() { esc DECSC esc CUP "$LINES" printf %s "$1" esc DECTCEM h esc EL0 case $2 in r) stty icanon echo read -r ans ||: stty -icanon -echo ;; esac esc DECRC esc DECTCEM l status_line "($y/$#) $PWD" } line_print() { offset=$1 case $offset in "$y") esc SGR 0 7 esac shift "$offset" case $offset in "$y") cur=$1 esac line_format "$1" } line_format() { file_escape "$1" [ -d "$1" ] && esc SGR 1 31 printf %s "$safe" [ -d "$1" ] && printf / esc SGR 0 0 esc EL0 printf '\r' } main() { set -e case $1 in -h|--help) printf 'shfm -[hv] \n' exit 0 ;; -v|--version) printf 'shfm 0.4.2\n' exit 0 ;; *) cd -- "${1:-"$PWD"}" ;; esac esc_c=$(printf '\033') bs_char=$(printf '\177') set -- * cur=$1 term_resize term_setup trap 'term_reset' EXIT INT trap 'term_resize; term_setup; y=1 y2=1; redraw "$@"' WINCH y=1 y2=1 redraw "$@" while key=$(dd ibs=1 count=1 2>/dev/null); do case $key${esc:=0} in k?|A2) term_scroll_up "$@" ;; j?|B2) term_scroll_down "$@" ;; l?|C2|"$esc") # ARROW RIGHT if [ -d "$cur" ] && cd -- "$cur" >/dev/null 2>&1; then set -- * y=1 y2=1 cur=$1 ltype= redraw "$@" elif [ -e "$cur" ]; then cmd_run "${SHFM_OPENER:="${EDITOR:=vi}"}" "$cur" redraw "$@" fi ;; h?|D2|"$bs_char"?) # ARROW LEFT old_pwd=$PWD case $ltype in '') cd .. || continue ;; *) ltype= ;; esac set -- * y=1 y2=1 cur=$1 hist=1 redraw "$@" ;; g?) case $y in 1) continue esac y=1 y2=1 cur=$1 redraw "$@" ;; G?) y=$# y2=$(($# < bottom ? $# : bottom)) redraw "$@" ;; .?) case ${hidden:=1} in 1) hidden=0; set -- .* ;; 0) hidden=1; set -- * esac y=1 y2=1 cur=$1 redraw "$@" ;; :?) prompt "cd: " r # false positive, behavior intentional # shellcheck disable=2088 case $ans in '~') ans=$HOME ;; '~/'*) ans=$HOME/${ans#"~/"} esac cd -- "${ans:="$0"}" >/dev/null 2>&1|| continue set -- * y=1 y2=1 cur=$1 redraw "$@" ;; /?) prompt / r # word splitting and globbing intentional # shellcheck disable=2086 set -- $ans* case $1$# in "$ans*1") set -- 'no results' esac y=1 y2=1 cur=$1 ltype="search $PWD/$ans*" redraw "$@" status_line "$#" ;; -?) cd -- "$OLDPWD" >/dev/null 2>&1|| continue set -- * y=1 y2=1 cur=$1 redraw "$@" ;; \~?) cd || continue set -- * y=1 y2=1 cur=$1 redraw "$@" ;; \!?) export SHFM_LEVEL SHFM_LEVEL=$((SHFM_LEVEL + 1)) cmd_run "${SHELL:=/bin/sh}" redraw "$@" ;; \??) set -- 'j - down' \ 'k - up' \ 'l - open file or directory' \ 'h - go up level' \ 'g - go to top' \ 'G - go to bottom' \ 'q - quit' \ ': - cd to ' \ '/ - search current directory *' \ '- - go to last directory' \ '~ - go home' \ '! - spawn shell' \ '. - toggle hidden files' \ '? - show keybinds' y=1 y2=1 cur=$1 ltype=keybinds redraw "$@" status_line "$#" ;; q?) exit 0 ;; # handle keys which emit escape sequences "$esc_c"*) esc=1 ;; '[1') esc=2 ;; *) esc=0 ;; esac done } main "$@" >/dev/tty bat-0.19.0/tests/syntax-tests/source/gnuplot/test.gp000064400000000000000000000005040072674642500206370ustar 00000000000000set terminal pngcairo enhanced set output "/tmp/polynomial.png" set grid set xrange [-5:5] set yrange [-5:10] set samples 10000 set key bottom right f(x) = 1.0 / 14.0 * ((x+4) * (x+1) * (x-1) * (x-3)) + 0.5 plot \ f(x) title "polynomial of degree 4" \ with lines \ linewidth 2 \ linetype rgb '#0077ff' bat-0.19.0/tests/syntax-tests/source/http-request-response/example.http000064400000000000000000000015400072674642500244760ustar 00000000000000POST /foo/bar?id=4&x=y%20z HTTP/1.1 X-Forwarded-For: 127.0.0.1 Content-Length: 124 Cache-Control: no-cache X-Forwarded-Proto: https Content-Type: application/json; charset=utf-8 Host: example.com Accept: */*; q=0.5, application/xml Accept-Encoding: gzip { "id": "blahblahblahblah", "object": "event", "api_version": "2020-03-02", "created": 1626790174, "data": { } } HTTP/1.1 200 OK Server: nginx Date: Fri, 23 Jul 2021 10:15:12 GMT Content-Type: text/html; charset=utf-8 Transfer-Encoding: chunked Connection: keep-alive Vary: Accept-Encoding Cache-Control: private; max-age=0 X-Frame-Options: DENY X-Content-Type-Options: nosniff X-XSS-Protection: 1; mode=block Referrer-Policy: origin Strict-Transport-Security: max-age=31556900 Hello World bat-0.19.0/tests/syntax-tests/source/jsonnet/LICENSE.md000064400000000000000000000263300072674642500207310ustar 00000000000000The `stdlib.jsonnet` file has been added from https://github.com/google/jsonnet under the following license: ```text Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ``` bat-0.19.0/tests/syntax-tests/source/jsonnet/stdlib.jsonnet000064400000000000000000000043010072674642500222020ustar 00000000000000local html = import 'html.libsonnet'; local jekyll = import 'jekyll.libsonnet'; local content = import 'stdlib-content.jsonnet'; local h1 = html.h1, p = html.p; local manifestJsonSingleLine(val) = std.strReplace(std.manifestJsonEx(val, ''), '\n', ' '); local exampleDoc(ex) = local exRep = if std.isString(ex) then ex else html.spaceless([html.code({}, ex.input), ' yields ', html.code({}, manifestJsonSingleLine(ex.output))]) ; html.p({}, html.spaceless(['Example: ', exRep, '.'])) ; local hgroup(body) = html.div({ class: 'hgroup' }, body); local hgroup_inline(body) = html.div({ class: 'hgroup-inline' }, [body, '
']); local panel(body) = html.div({ class: 'panel' }, body); local in_panel(body) = hgroup(hgroup_inline(panel(body))); local fieldParams(f) = if std.objectHas(f, 'params') then '(' + std.join(', ', f.params) + ')' else '' ; local fieldDescription(f) = if std.isString(f.description) then html.p({}, f.description) else f.description ; local fieldDoc(f, prefix) = [ in_panel(html.h4({ id: f.name }, prefix + '.' + f.name + fieldParams(f))), in_panel([ if std.objectHas(f, 'availableSince') then ( html.p( {}, html.em( {}, if f.availableSince == 'upcoming' then 'Available in upcoming release.' else 'Available since version ' + f.availableSince + '.' ) ) ), fieldDescription(f), if std.objectHas(f, 'examples') then [ exampleDoc(ex) for ex in f.examples ] else [], ]), '', ]; local group(group_spec, prefix) = [ in_panel(html.h3({ id: group_spec.id }, group_spec.name)), if std.objectHas(group_spec, 'intro') then in_panel(group_spec.intro), '', [fieldDoc(f, prefix) for f in group_spec.fields], '', ]; local stdlibPage = [ in_panel(html.h1({id: 'standard_library'}, 'Standard Library')), '', in_panel(content.intro), '', [group(g, content.prefix) for g in content.groups], ]; local stdlibFrontMatter = { layout: 'default', title: 'Standard Library', }; jekyll.renderWithFrontMatter(stdlibFrontMatter, stdlibPage) bat-0.19.0/tests/syntax-tests/source/nginx/nginx.conf000064400000000000000000000057650072674642500207730ustar 00000000000000#user nobody; worker_processes 1; #pid logs/nginx.pid; load_module "/usr/local/libexec/nginx/ngx_http_xslt_filter_module.so"; load_module "/usr/local/libexec/nginx/ngx_rtmp_module.so"; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; gzip on; gzip_disable "msie6"; include /usr/local/etc/nginx/sites.d/*; } rtmp { server { listen 1935; max_message 10M; application wnob { live on; record off; } application strim { live on; hls on; hls_path /usr/local/www/hls/; hls_variant _low BANDWIDTH=250000; hls_variant _mid BANDWIDTH=500000; hls_variant _high BANDWIDTH=1000000; hls_variant _hd720 BANDWIDTH=1500000; hls_variant _src BANDWIDTH=2000000; } } } server { listen 443 ssl; server_name host.example.com root /usr/local/www/host.example.com/; error_page 404 /404.html; index index.html; autoindex on; autoindex_localtime off; autoindex_format xml; location / { xslt_stylesheet /usr/local/www/host.example.com/index.xslt; } location ~ /\..* { return 404; } location ~ /.+/ { xslt_stylesheet /usr/local/www/host.example.com/project.xslt; } location ~ /.*\.xslt/ { return 404; } location ~ \.thumb\.png$ { error_page 404 /404.thumb.png; } ssl_certificate /usr/local/etc/letsencrypt/live/host.example.com/fullchain.pem; # managed by Certbot ssl_certificate_key /usr/local/etc/letsencrypt/live/host.example.com/privkey.pem; # managed by Certbot include /usr/local/etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /usr/local/etc/letsencrypt/ssl-dhparams.pem; add_header Strict-Transport-Security "max-age=31536000" always; } server { listen 80; server_name host.example.com; if ($host = host.example.com) { return 301 https://$host$request_uri; } return 404; } server { listen 443 ssl; server_name other.example.com; ssl_certificate /usr/local/etc/letsencrypt/live/other.example.com/fullchain.pem; ssl_certificate_key /usr/local/etc/letsencrypt/live/other.example.com/privkey.pem; include /usr/local/etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /usr/local/etc/letsencrypt/ssl-dhparams.pem; add_header Strict-Transport-Security "max-age=31536000" always; access_log /home/otherapp/logs/access.log; error_log /home/otherapp/logs/error.log; client_max_body_size 5M; location / { root /home/otherapp/app/static; index man.txt; try_files $uri @proxy; } location @proxy { proxy_set_header Host $http_host; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_pass http://unix:/var/run/otherapp/sock:; } } server { listen 80; server_name other.example.com; if ($host = other.example.com) { return 301 https://$host$request_uri; } return 404; } bat-0.19.0/tests/syntax-tests/source/nim/main.nim000064400000000000000000000012530072674642500200560ustar 00000000000000import json const message = "hello world" multiLine = """ foo bar """ numbers = @[1, 2, 3] type Options = enum A, B, C ## Top-level comment type SomeStruct* = ref object value*: string proc someFunc*(): string = ## Function docs ## ## More docs result = message proc someOtherFunc(startingValue: int): (string, int) = var num = startingValue num += 1 if num > 10 * 10 * 10: echo "Encountered an error" raise newException(ValueError, "Value was over 1000") ("Fizz", num) proc `+=`(a: var SomeStruct, b: SomeStruct): string = a.value.add(b.value) return a.value echo someFunc() echo(someOtherFunc(123)) discard someFunc() bat-0.19.0/tests/syntax-tests/source/nim/test.nimble000064400000000000000000000006500072674642500205740ustar 00000000000000version = "0.1.0" author = "creator_name" description = "Tests nimble syntax highlighting" license = "custom" bin = @["test"] srcdir = "src" installExt = @["nim"] # Dependencies requires "nim >= 1.6.2" when defined(nimdistros): import distros if detectOs(Ubuntu): foreignDep "external_lib" else: foreignDep "other_lib" task test, "Runs a task called 'test'": withDir "tests": exec "nim c -r tester" bat-0.19.0/tests/syntax-tests/source/nix/test.nix000064400000000000000000000003610072674642500201360ustar 00000000000000{ nixpkgs ? , nixpkgs' ? import nixpkgs {}}: with nixpkgs'; # some comment stdenv.mkDerivation rec { pname = "test"; version = "0.2.3"; name = "${pname}-${version}"; buildInputs = [ gzip bzip2 python27 ]; } bat-0.19.0/tests/syntax-tests/source/orgmode/test.org000064400000000000000000000012450072674642500207670ustar 00000000000000* This is header ** sub header *** sub sub header **** sub sub sub header * Table representation | Name | Age | |---------+-----| | Milli | 23 | | Vanilli | 22 | * Spreadsheets | n | n + 2 | n ^ 2 | |---+-------+-------| | 1 | 3 | 1 | | 2 | 4 | 4 | | 3 | 5 | 9 | #+TBLFM: $2=$1+2::$3=$1*$1 * Source Code #+BEGIN_SRC rust # recursive fibonacci fn fib(n: u32) -> u32 { match n { 0 | 1 => 1, _ => fib(n - 1) + fib(n - 2), } } #+END_SRC * ToDo and Checkboxes Example ** DONE Write source example ** TODO Generate highlighted example [1/3] - [X] run update script - [-] get code review - [ ] merge into master bat-0.19.0/tests/syntax-tests/source/reStructuredText/reference.rst000064400000000000000000000152410072674642500236740ustar 00000000000000===== Title ===== Subtitle -------- Titles are underlined (or over- and underlined) with a printing nonalphanumeric 7-bit ASCII character. Recommended choices are "``= - ` : ' " ~ ^ _ * + # < >``". The underline/overline must be at least as long as the title text. A lone top-level (sub)section is lifted up to be the document's (sub)title. Inline syntaxes --------------- *emphasis* **strong emphasis** `interpreted text` ``inline literal`` http://docutils.sf.net/ Bullet lists ------------ - This is item 1 - This is item 2 - Bullets are "-", "*" or "+". Continuing text must be aligned after the bullet and whitespace. Note that a blank line is required before the first item and after the last, but is optional between items. Enumerated lists ---------------- 3. This is the first item 4. This is the second item 5. Enumerators are arabic numbers, single letters, or roman numerals 6. List items should be sequentially numbered, but need not start at 1 (although not all formatters will honour the first index). #. This item is auto-enumerated Definition lists ---------------- what Definition lists associate a term with a definition. how The term is a one-line phrase, and the definition is one or more paragraphs or body elements, indented relative to the term. Blank lines are not allowed between term and definition. Field lists ----------- :Authors: Tony J. (Tibs) Ibbs, David Goodger (and sundry other good-natured folks) :Version: 1.0 of 2001/08/08 :Dedication: To my father. Options lists ------------- -a command-line option "a" -b file options can have arguments and long descriptions --long options can be long also --input=file long options can also have arguments /V DOS/VMS-style options too Literal Blocks -------------- A paragraph containing only two colons indicates that the following indented or quoted text is a literal block. :: Whitespace, newlines, blank lines, and all kinds of markup (like *this* or \this) is preserved by literal blocks. The paragraph containing only '::' will be omitted from the result. The ``::`` may be tacked onto the very end of any paragraph. The ``::`` will be omitted if it is preceded by whitespace. The ``::`` will be converted to a single colon if preceded by text, like this:: It's very convenient to use this form. Literal blocks end when text returns to the preceding paragraph's indentation. This means that something like this is possible:: We start here and continue here and end here. Per-line quoting can also be used on unindented literal blocks:: > Useful for quotes from email and > for Haskell literate programming. Line blocks ----------- A paragraph containing only two colons indicates that the following indented or quoted text is a literal block. :: Whitespace, newlines, blank lines, and all kinds of markup (like *this* or \this) is preserved by literal blocks. The paragraph containing only '::' will be omitted from the result. The ``::`` may be tacked onto the very end of any paragraph. The ``::`` will be omitted if it is preceded by whitespace. The ``::`` will be converted to a single colon if preceded by text, like this:: It's very convenient to use this form. Literal blocks end when text returns to the preceding paragraph's indentation. This means that something like this is possible:: We start here and continue here and end here. Per-line quoting can also be used on unindented literal blocks:: > Useful for quotes from email and > for Haskell literate programming. Block quotes ------------ Block quotes are just: Indented paragraphs, and they may nest. Doctest blocks -------------- Doctest blocks are interactive Python sessions. They begin with "``>>>``" and end with a blank line. >>> print "This is a doctest block." This is a doctest block. Tables ------ Grid table: +------------+------------+-----------+ | Header 1 | Header 2 | Header 3 | +============+============+===========+ | body row 1 | column 2 | column 3 | +------------+------------+-----------+ | body row 2 | Cells may span columns.| +------------+------------+-----------+ | body row 3 | Cells may | - Cells | +------------+ span rows. | - contain | | body row 4 | | - blocks. | +------------+------------+-----------+ Simple table: ===== ===== ====== Inputs Output ------------ ------ A B A or B ===== ===== ====== False False False True False True False True True True True True ===== ===== ====== Transitions ----------- A transition marker is a horizontal line of 4 or more repeated punctuation characters. ------------ A transition should not begin or end a section or document, nor should two transitions be immediately adjacent. Footnotes --------- Footnote references, like [5]_. Note that footnotes may get rearranged, e.g., to the bottom of the "page". .. [5] A numerical footnote. Note there's no colon after the ``]``. Autonumbered footnotes are possible, like using [#]_ and [#]_. .. [#] This is the first one. .. [#] This is the second one. They may be assigned 'autonumber labels' - for instance, [#fourth]_ and [#third]_. .. [#third] a.k.a. third_ .. [#fourth] a.k.a. fourth_ Auto-symbol footnotes are also possible, like this: [*]_ and [*]_. .. [*] This is the first one. .. [*] This is the second one. Citations --------- Citation references, like [CIT2002]_. Note that citations may get rearranged, e.g., to the bottom of the "page". .. [CIT2002] A citation (as often used in journals). Citation labels contain alphanumerics, underlines, hyphens and fullstops. Case is not significant. Given a citation like [this]_, one can also refer to it like this_. .. [this] here. Hyperlink Targets ----------------- External hyperlinks, like Python_. .. _Python: http://www.python.org/ External hyperlinks, like `Python `_. Internal crossreferences, like example_. .. _example: This is an example crossreference target. Python_ is `my favourite programming language`__. .. _Python: http://www.python.org/ __ Python_ Titles are targets, too ======================= Implict references, like `Titles are targets, too`_. Directives ---------- For instance: .. image:: images/ball1.gif The |biohazard| symbol must be used on containers used to dispose of medical waste. .. |biohazard| image:: biohazard.png Comments -------- .. This text will not be shown (but, for instance, in HTML might be rendered as an HTML comment) An "empty comment" does not consume following blocks. (An empty comment is ".." with blank lines before and after.) .. So this block is not "lost", despite its indentation. bat-0.19.0/tests/syntax-tests/source/resolv.conf/resolv.conf000064400000000000000000000001370072674642500222610ustar 00000000000000# A comment domain example.com nameserver 192.168.123.123 nameserver aa00::aaaa:0000:1234:abcd bat-0.19.0/tests/syntax-tests/source/varlink/LICENSE.md000064400000000000000000000304360072674642500207210ustar 00000000000000The `org.varlink.certification.varlink` file has been added from https://github.com/varlink/rust under the following licenses: ```text Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright 2018 Red Hat, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ``` ```text MIT License Copyright (c) 2016 - 2018 Red Hat, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ``` bat-0.19.0/tests/syntax-tests/source/varlink/org.varlink.certification.varlink000064400000000000000000000043160072674642500257610ustar 00000000000000# Interface to test varlink implementations against. # First you write a varlink client calling: # Start, Test01, Test02, …, Test09, End # The return value of the previous call should be the argument of the next call. # Then you test this client against well known servers like python or rust from # https://github.com/varlink/ # # Next you write a varlink server providing the same service as the well known ones. # Now run your client against it and run well known clients like python or rust # from https://github.com/varlink/ against your server. If all works out, then # your new language bindings should be varlink certified. interface org.varlink.certification type Interface ( foo: ?[]?[string](foo, bar, baz), anon: (foo: bool, bar: bool) ) type MyType ( object: object, enum: (one, two, three), struct: (first: int, second: string), array: []string, dictionary: [string]string, stringset: [string](), nullable: ?string, nullable_array_struct: ?[](first: int, second: string), interface: Interface ) method Start() -> (client_id: string) method Test01(client_id: string) -> (bool: bool) method Test02(client_id: string, bool: bool) -> (int: int) method Test03(client_id: string, int: int) -> (float: float) method Test04(client_id: string, float: float) -> (string: string) method Test05(client_id: string, string: string) -> ( bool: bool, int: int, float: float, string: string ) method Test06( client_id: string, bool: bool, int: int, float: float, string: string ) -> ( struct: ( bool: bool, int: int, float: float, string: string ) ) method Test07( client_id: string, struct: ( bool: bool, int: int, float: float, string: string ) ) -> (map: [string]string) method Test08(client_id: string, map: [string]string) -> (set: [string]()) method Test09(client_id: string, set: [string]()) -> (mytype: MyType) # returns more than one reply with "continues" method Test10(client_id: string, mytype: MyType) -> (string: string) # must be called as "oneway" method Test11(client_id: string, last_more_replies: []string) -> () method End(client_id: string) -> (all_ok: bool) error ClientIdError () error CertificationError (wants: object, got: object) bat-0.19.0/tests/syntax-tests/test_custom_assets.sh000075500000000000000000000041540072674642500206370ustar 00000000000000#!/usr/bin/env bash set -o errexit -o nounset -o pipefail ### ENVIRONMENT BAT_CONFIG_DIR=$(mktemp -d) export BAT_CONFIG_DIR BAT_CACHE_PATH=$(mktemp -d) export BAT_CACHE_PATH echo " BAT_CONFIG_DIR = ${BAT_CONFIG_DIR} BAT_CACHE_PATH = ${BAT_CACHE_PATH} " ### HELPER VARS custom_syntax_args=( "--language=BatTestCustomAssets" "tests/syntax-tests/source/BatTestCustomAssets/NoColorsUnlessCustomAssetsAreUsed.battestcustomassets" ) integrated_syntax_args=( "--language=Rust" "examples/simple.rs" ) ### HELPER FUNCTIONS echo_step() { echo -e "\n== $1 ==" } fail_test() { echo -e "FAIL: $1" exit 1 } ### TEST STEPS echo_step "TEST: Make sure 'BatTestCustomAssets' is not part of integrated syntaxes" bat -f "${custom_syntax_args[@]}" && fail_test "EXPECTED: 'unknown syntax' error ACTUAL: no error occured" echo_step "PREPARE: Install custom syntax 'BatTestCustomAssets'" custom_syntaxes_dir="$(bat --config-dir)/syntaxes" mkdir -p "${custom_syntaxes_dir}" cp -v "tests/syntax-tests/BatTestCustomAssets.sublime-syntax" \ "${custom_syntaxes_dir}/BatTestCustomAssets.sublime-syntax" echo_step "PREPARE: Build custom assets to enable 'BatTestCustomAssets' syntax" bat cache --build echo_step "TEST: 'BatTestCustomAssets' is a known syntax" bat -f "${custom_syntax_args[@]}" || fail_test "EXPECTED: syntax highlighting to work ACTUAL: there was an error" echo_step "TEST: The 'Rust' syntax is still available" bat -f "${integrated_syntax_args[@]}" || fail_test "EXPECTED: syntax highlighting still works with integrated assets ACTUAL: there was an error" echo_step "TEST: 'BatTestCustomAssets' is an unknown syntax with --no-custom-assets" bat -f --no-custom-assets "${custom_syntax_args[@]}" && fail_test "EXPECTED: 'unknown syntax' error because of --no-custom-assets ACTUAL: no error occured" echo_step "TEST: 'bat cache --clear' removes all files" bat cache --clear remaining_files=$(ls -A "${BAT_CACHE_PATH}") [ -z "${remaining_files}" ] || fail_test "EXPECTED: no files remain ACTUAL: some files remain:\n${remaining_files}" echo_step "CLEAN" rm -rv "${BAT_CONFIG_DIR}" "${BAT_CACHE_PATH}" bat-0.19.0/tests/syntax-tests/update.sh000075500000000000000000000003110072674642500161550ustar 00000000000000#!/usr/bin/env bash cd "$(dirname "${BASH_SOURCE[0]}")" || exit python="python3" if ! command -v python3 &>/dev/null; then python="python"; fi "$python" create_highlighted_versions.py -O highlighted bat-0.19.0/tests/tester.rs000064400000000000000000000057720072674642500135420ustar 00000000000000use std::env; use std::fs::{self, File}; use std::io::Read; use std::path::{Path, PathBuf}; use std::process::Command; use tempfile::TempDir; use git2::build::CheckoutBuilder; use git2::Repository; use git2::Signature; pub struct BatTester { /// Temporary working directory temp_dir: TempDir, /// Path to the *bat* executable exe: PathBuf, } impl BatTester { pub fn test_snapshot(&self, name: &str, style: &str) { let output = Command::new(&self.exe) .current_dir(self.temp_dir.path()) .args(&[ "sample.rs", "--no-config", "--paging=never", "--color=never", "--decorations=always", "--terminal-width=80", &format!("--style={}", style), ]) .output() .expect("bat failed"); // have to do the replace because the filename in the header changes based on the current working directory let actual = String::from_utf8_lossy(&output.stdout) .as_ref() .replace("tests/snapshots/", ""); let mut expected = String::new(); let mut file = File::open(format!("tests/snapshots/output/{}.snapshot.txt", name)) .expect("snapshot file missing"); file.read_to_string(&mut expected) .expect("could not read snapshot file"); assert_eq!(expected, actual); } } impl Default for BatTester { fn default() -> Self { let temp_dir = create_sample_directory().expect("sample directory"); let root = env::current_exe() .expect("tests executable") .parent() .expect("tests executable directory") .parent() .expect("bat executable directory") .to_path_buf(); let exe_name = if cfg!(windows) { "bat.exe" } else { "bat" }; let exe = root.join(exe_name); BatTester { temp_dir, exe } } } fn create_sample_directory() -> Result { // Create temp directory and initialize repository let temp_dir = TempDir::new().expect("Temp directory"); let repo = Repository::init(&temp_dir)?; // Copy over `sample.rs` let sample_path = temp_dir.path().join("sample.rs"); println!("{:?}", &sample_path); fs::copy("tests/snapshots/sample.rs", &sample_path).expect("successful copy"); // Commit let mut index = repo.index()?; index.add_path(Path::new("sample.rs"))?; let oid = index.write_tree()?; let signature = Signature::now("bat test runner", "bat@test.runner")?; let tree = repo.find_tree(oid)?; let _ = repo.commit( Some("HEAD"), // point HEAD to our new commit &signature, // author &signature, // committer "initial commit", &tree, &[], ); let mut opts = CheckoutBuilder::new(); repo.checkout_head(Some(opts.force()))?; fs::copy("tests/snapshots/sample.modified.rs", &sample_path).expect("successful copy"); Ok(temp_dir) } bat-0.19.0/tests/utils/mocked_pagers.rs000064400000000000000000000043070072674642500161700ustar 00000000000000use assert_cmd::Command; use predicates::prelude::predicate; use std::env; use std::path::{Path, PathBuf}; /// For some tests we want mocked versions of some pagers /// This fn returns the absolute path to the directory with these mocked pagers fn get_mocked_pagers_dir() -> PathBuf { let cargo_manifest_dir = env::var("CARGO_MANIFEST_DIR").expect("Missing CARGO_MANIFEST_DIR"); Path::new(&cargo_manifest_dir) .join("tests") .join("mocked-pagers") } /// On Unix: 'most' -> 'most' /// On Windows: 'most' -> 'most.bat' pub fn from(base: &str) -> String { if cfg!(windows) { format!("{}.bat", base) } else { String::from(base) } } /// Prepends a directory to the PATH environment variable /// Returns the original value for later restoration fn prepend_dir_to_path_env_var(dir: PathBuf) -> String { // Get current PATH let original_path = env::var("PATH").expect("No PATH?!"); // Add the new dir first let mut split_paths = env::split_paths(&original_path).collect::>(); split_paths.insert(0, dir); // Set PATH with the new dir let new_path = env::join_paths(split_paths).expect("Failed to join paths"); env::set_var("PATH", new_path); // Return the original value for later restoration of it original_path } /// Helper to restore the value of PATH fn restore_path(original_path: String) { env::set_var("PATH", original_path); } /// Allows test to run that require our mocked versions of 'more' and 'most' /// in PATH. Temporarily changes PATH while the test code runs, and then restore it /// to avoid pollution of global state pub fn with_mocked_versions_of_more_and_most_in_path(actual_test: fn()) { let original_path = prepend_dir_to_path_env_var(get_mocked_pagers_dir()); // Make sure our own variants of 'more' and 'most' are used Command::new(from("more")) .assert() .success() .stdout(predicate::str::contains("I am more")); Command::new(from("most")) .assert() .success() .stdout(predicate::str::contains("I am most")); // Now run the actual test actual_test(); // Make sure to restore PATH since it is global state restore_path(original_path); } bat-0.19.0/tests/utils/mod.rs000064400000000000000000000000270072674642500141370ustar 00000000000000pub mod mocked_pagers;