pax_global_header00006660000000000000000000000064141426246440014521gustar00rootroot0000000000000052 comment=08484512c560b68e4720442c8d77bc6b9d9479df scrot-1.7/000077500000000000000000000000001414262464400125225ustar00rootroot00000000000000scrot-1.7/.cirrus.yml000066400000000000000000000061001414262464400146270ustar00rootroot00000000000000# Copyright (C) 2021 Guilherme Janczak # # 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 of the Software and its documentation and acknowledgment shall be # given in the documentation and software packages that this Software was # used. # # 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 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. common_template: &common_script name: ${OS}-${CC} build_script: - ./autogen.sh - ./configure - make on_failure: autotools_artifacts: path: config.log task: matrix: - container: image: alpine:latest env: OS: alpine-latest - container: image: alpine:edge env: OS: alpine-edge container: kvm: true env: matrix: - CC: clang - CC: gcc install_script: - apk add autoconf autoconf-archive automake make pkgconfig clang gcc xorg-server-dev libxcomposite-dev libxext-dev libxfixes-dev imlib2-dev musl-dev bsd-compat-headers << : *common_script task: matrix: - container: image: debian:testing env: OS: debian-testing - container: image: debian:unstable env: OS: debian-unstable container: kvm: true env: matrix: - CC: clang - CC: gcc install_script: - apt-get update - apt-get install -y autoconf autoconf-archive make pkg-config clang gcc libx11-dev libxcomposite-dev libxext-dev libxfixes-dev libimlib2-dev libbsd-dev << : *common_script task: freebsd_instance: # Keep updated with the newest release from # https://www.freebsd.org/releases/ image: freebsd-13-0-release-amd64 env: OS: freebsd matrix: - CC: clang - CC: gcc install_script: - pkg install -y autoconf autoconf-archive automake pkgconf gcc libX11 libXcomposite libXext libXfixes imlib2 << : *common_script task: macos_instance: image: big-sur-base env: OS: macos matrix: - CC: clang - CC: gcc install_script: - brew update - brew install autoconf autoconf-archive automake make pkg-config gcc libx11 libxcomposite libxext libxfixes imlib2 << : *common_script scrot-1.7/.github/000077500000000000000000000000001414262464400140625ustar00rootroot00000000000000scrot-1.7/.github/workflows/000077500000000000000000000000001414262464400161175ustar00rootroot00000000000000scrot-1.7/.github/workflows/full-check.yml000066400000000000000000000015611414262464400206620ustar00rootroot00000000000000# Copyright 2020 Daniel T. Borelli # Copyright 2020 Jeroen Roovers # Copyright 2020 Joao Eriberto Mota Filho # Copyright 2021 Guilherme Janczak name: full-check on: [push, pull_request] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: install_dependencies run: sudo apt install autoconf-archive libimlib2-dev libxcomposite-dev libxfixes-dev libbsd-dev - name: first_build run: | ./autogen.sh ./configure make sudo make install sudo make uninstall make distclean - name: second_build run: | ./autogen.sh ./configure make sudo make install - name: run_program run: | scrot -v scrot-1.7/.gitignore000066400000000000000000000003251414262464400145120ustar00rootroot00000000000000*.bz2 *.gz *.in Makefile aclocal.m4 autom4te.cache compile compile_commands.json config.* configure depcomp install-sh missing src/*.o src/.deps src/Makefile src/config.h src/scrot src/scrot_config.h src/stamp-h1 scrot-1.7/AUTHORS000066400000000000000000000004541414262464400135750ustar00rootroot00000000000000Principle author: Tom Gilbert (giblet) Since 2019, this source code is being maintained by: Daniel T. Borelli Guilherme Janczak Joao Eriberto Mota Filho and some people sending patches! scrot-1.7/CONTRIBUTING.md000066400000000000000000000031521414262464400147540ustar00rootroot00000000000000# CONTRIBUTING TO SCROT DEVELOPMENT #### Changes are to be sent as [pull requests on GitHub](https://github.com/resurrecting-open-source-projects/scrot/pulls). ## Setting up the development machine scrot aims to build with no modifications on all the free unix systems. The master branch is also kept in working order at all times. Our builds are tested all the way back to [Debian oldstable](https://wiki.debian.org/DebianOldStable), so a scrot developer shouldn't need to build the latest git versions of the dependencies to start hacking. You will want to install the dependencies listed in the `Building` section of [README.md](README.md). Look for the text `install_script` in the [.cirrus.yml](.cirrus.yml) CI definitions for example package manager invocations on many operating systems. ## Style scrot is primarily written in C99 with [POSIX 2008](https://pubs.opengroup.org/onlinepubs/9699919799.2008edition/) extensions. You're also free to make use of any documented function from our libraries. Make sure to use [libbsd functions](https://manpages.debian.org/unstable/libbsd-dev/libbsd.7.en.html) where they're safer, cleaner or more convenient. scrot follows [WebKit's code style guidelines](https://webkit.org/code-style-guidelines/) with additional restrictions: - No explicit casts. - Use the identifier and not the type as the argument to the `sizeof` operator. When in doubt, make use of the `clang-format` source code formatter-it comes with the WebKit style by default. ## Low-hanging fruit Ongoing tasks will be written to [TODO.md](TODO.md). Regular contributors can ask to join the scrot project on GitHub. scrot-1.7/COPYING000066400000000000000000000021701414262464400135550ustar00rootroot00000000000000Copyright (C) 1999,2000 Tom Gilbert. 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 of the Software and its documentation and acknowledgment shall be given in the documentation and software packages that this Software was used. 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 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. scrot-1.7/ChangeLog000066400000000000000000000322141414262464400142760ustar00rootroot00000000000000Tue Nov 09 20:41:00 -03:00 2021 Joao Eriberto Mota Filho Version 1.7 [ a1346054 ] * Fixed: code style, add missing final newline. * Fixed: autogen.sh: fix some shellcheck issues. [ c0dev0id ] * Replace insecure c-strings functions (following libbsd integration). [ Daniel T. Borelli ] alias @daltomi * New option: --select=hole (-shole), hole selection area. * New option: --select=hide (-shide), hide selection area, support image. * New option: --select=blur (-sblur), blur selection area. * New option: (-) add redirection to standard output (format PNG). * Improvement option: --stack, add an optional join direction (v/h). * Fixed: free memory image and font resources. * Bug fixed: segfault if mouse cursor image was not obtained. * Use err/warn functions (following libbsd integration). * Others various code improvement. [ Guilherme Janczak ] alias @guijan * Added new library dependency: libbsd. * Autotools: added option --without-libbsd. * Improvement: Autotools: remove unused files, remove obsolete macros, assume C89 functions exist, delete scrot.spec. * Improvement: remove unused C macro, use strndup function, use designated initializers (C99). * Improvement: Doc: polish the txt2man manual, CONTRIBUTING.md, TODO.md. * Others various code improvement. [ IFo Hancroft ] alias @ifohancroft * New option: --file (-F), provide the filename as an option. * Fixed: code style guideline violations (WebKit). * Use strlcpy/strlcat (following libbsd integration). [ Joao Eriberto Mota Filho ] alias @eribertomota * Fixed a mistake in README.md. [ Peter Wu ] alias @peterwu * Convert all source files to the WebKit style. [ Wilson Smith ] alias @0wsmith * New option: --ignorekeyboard (-i), Don't exit for keyboard input. ESC still exits. Sun Jul 25 23:30:00 -03:00 2021 Joao Eriberto Mota Filho Version 1.6 [ Christopher R. Nelson ] alias @languidnights * Removed dependence on giblib library. [ Daniel T. Borelli ] alias @daltomi * Fixed the capture when a window is hidden behind another. * Fixed the capture of the edge of the focused window. * Avoid capturing the selection box when drag and drop quickly. * Fixed issue when selection reaches the end of screen. * New feature: resize the selection with the arrow keys. * New feature: support script Imlib2 commands. * New feature: added WM_CLASS to exclude selection mode edge from some composite window managers. * Improvement: selection option, capture the mouse cursor when the delay option is used. * Removed forced compiler options: -g -O3 [ Guilherme Janczak ] alias @guijan * Removed the local implementation function: strdup. * Removed the local implementation function: getopt_long. * Removed unused file debug.h. [ Martin C ] alias @Cationiz3r * New feature: change the cursor pointer according to the movement of the selection. [ Shawn Webb ] alias @lattera * Fixed Control Flow Integrity complain in HardenedBSD. Thu Feb 04 22:35:00 -03:00 2021 Joao Eriberto Mota Filho Version 1.5 [ c0dev0id ] * Fixed compilation on Sparc64. [ Cungsten Tarbide ] * New feature: retry to grab the keyboard for 1s in 50ms intervals if it is still being grabbed by the windows manager. [ daltomi ] * Added 'make dist' feature. * Do not record pointer when selecting an area. * Fixed a possible overflow in src/options.c. * Fixed a segfault with --multidisp option. * Fixed issues when file extension is more than 3 characters. * New feature: allow save thumbnail without extension. * New option --class (-C): discriminate windows by class name. * Support various modes of drawing selection. * Use correct type for calloc and other assignments. [ Joao Eriberto Mota Filho ] * Added rights for blockparole, c0dev0id, Cungsten Tarbide, daltomi and nothub. [ nothub ] * Fix grammar in an error message. Sat Jul 18 23:23:00 -03:00 2020 Joao Eriberto Mota Filho Version 1.4 [ ideal ] * Fix SIGSEGV, if running without DISPLAY environment variable. [ Jeroen Roovers ] * README.md: mention libXcomposite in build requirements. * Removed libXcursor references. [ Joao Eriberto Mota Filho ] * Added a new logo 128x128. * Added rights for "ideal", Jeroen Roovers and spycapitan. * Fixed spelling errors in manpage. * Prepare for new release. * Updated manpage. * Using create-man.sh 2.0 from txt2man package from Debian. [ spycapitan ] * Call XCloseDisplay on exit. This is the right thing in every X server program, to release acquired resources. * Fixed autoselect. * Fixed capturing partially hidden windows on the edge of the desktop. * Fixed required number. * Fixed SIGSEGV, option --note. * Minor fix: variable is assigned that is never used. * New Feature: capture stack/overlapping windows. Depends of libXcomposite (X11). New option: --stack or -k. * Stack windows: client list spec EWMH. Sun Apr 16 00:08:00 -03:00 2020 Joao Eriberto Mota Filho Version 1.3 [ Joao Eriberto Mota Filho ] * Added rights for Hinigatsu and Sean Brennan. * Created full-check.yml to provide CI tests. * Prepare for new release. * Updated manpage. * Using an updated README.md as replace for README. [ Hinigatsu ] * Added delay option to autoselect. * Fixed bug #39, mouse pointer not captured with -a -p options. [ Sean Brennan ] * Added -D option to specify the display to use. Sun Aug 19 08:35:00 -03:00 2019 Joao Eriberto Mota Filho Version 1.2 [ Daniel T. Borelli ] * Changed the cursor to indicate the selection mode. * Fixed GCC >=8.0 warning: -Wstringop-truncation. * Evaluate return of strftime. [ Jade Auer ] * Added a gitignore to prevent accidentally including any files generated by autotools. [ Santhosh Raju ] * Fixes ambiguous else warning by providing proper braces for if in src/getopt.c. * Fixed missing warnings. [ Joao Eriberto Mota Filho ] * Added rights for Santhosh Raju. * Prepare for new release. Tue Jul 11 23:45:00 -03:00 2019 Joao Eriberto Mota Filho Version 1.1.1 [ Daniel T. Borelli ] * Update manpage and help. [ Joao Eriberto Mota Filho ] * New release. Tue Jul 09 18:51:00 -03:00 2019 Joao Eriberto Mota Filho Version 1.1 [ Daniel T. Borelli ] * Added (-n, --note) to draw a text. * Added (-l, --line) to define the line to use to select an area to capture. [ Jade Auer ] * Added a specifier ($a) to embed hostname in output file. [ Joao Eriberto Mota Filho ] * Added a check for autoconf-archive presence in configure.ac. * Added rights for Jade. * Adjusted Makefile.am to remove src/scrot_config.h when distclean. * Updated manpage. * Final adjustments for a new release. * Several tests in Debian. Sun Jun 11 11:01:00 -03:00 2019 Joao Eriberto Mota Filho Version 1.0 [ Daniel Lublin ] * Added EXIT_FAILURE when are no arguments required by some options. Fix Debian bug #685173. * Improved the manpage to show undocumented options. [ Daniel T. Borelli ] * Added option: --overwrite or -o. Now, by default do not overwrite the file. Fix Debian bug #807139. * Added support to grab mouse pointer (-p option). Fix Ubuntu bug #1698375. * Added support to freeze the screen when selection is activated (-f option). * Do not use gib_eprintf in calls to X11 functions. Fix Ubuntu bug #1523212. * Fix: scrot can't save files without extension. Fix Ubuntu bug #148659. * Fix: scrot don't complain about invalid numeric argument. Fix Ubuntu bug #371784. * Fixed some compiling warnings. [ Joao Eriberto Mota Filho ] * Final adjustments for a new release. * Several tests in Debian. * Updated AUTHORS file. Tue Feb 12 19:06:11 -03:00 2019 Joao Eriberto Mota Filho Version 0.9 * Added --autoselect rectangle option. Thanks to Stoney Sauce . * Added --focused option. Thanks to James Cameron . * Added an autogen.sh file. * Added some explanation about how to help the project. * Character cleanup for UTF-8 compatibility. Thanks to William Vera . * Fixed a missing option for beep prevention. Thanks to Ibragimov Rinat . * Fixed spelling errors in final binary. Thanks to William Vera . * Improved the autotools (acinclude.m4, configure.ac, Makefile.am and src/Makefile.am). * Improved the GCC hardening. * Prevent arbitrary long file names. Thanks to George Danchev . * Several fixes in manpage. Wed Mar 12 13:20:11 GMT 2003 Tom Gilbert * Patch from Claes Nasten * Enhances thumbnail related options: "First, specifying -t would break the $f param to -exec. Second, the thumbnail and the screenshot got different timestamps. Third, one weren't able to specify geometry with -t. I fixed those and added, $m ( mini, instead of $t as it was taken ) so that one can do. $ scrot -t 91x0 -e 'echo $f,$m' 2003-03-08-104735_800x600_scrot.png,2003-03-08-104735_91x68_scrot-thumb.png` About the geometry, having either the width or height set to 0 makes it fill in the other pertaining the aspect ratio. " * Once I update the docs I'll release 0.8 Tue Feb 25 13:13:03 GMT 2003 Tom Gilbert * Update for latest giblib. Requires latest release now. * release 0.7 Sat Feb 23 12:37:29 GMT 2002 Tom Gilbert * Patch from Eric Z. Ayers * Changes the cursor to a bottom left corner when you start to drag to select a grab region. Thu Jan 11 17:43:19 2001 Tom Gilbert * Patch from Michael Roberts to add -t, --thumb option to generate thumbnails. I modified it a little, specify the percentage size of the thumbnail on the command line. Mon Dec 4 23:46:03 2000 Tom Gilbert * Added -m, --multidisp, which is for multiple heads (not xinerama) grabs shots from each and joins them together. * Fixed doing the string escapes when saving files. My bad. Sun Nov 12 15:16:40 2000 Tom Gilbert * Now uses giblib. You'll need the very latest giblib from CVS as of right now. Sun Nov 5 02:17:57 2000 Tom Gilbert * Beep when about to take the shot. * Added -b, --border to grab wm borders too. * Ungrab mouse, keyboard before sleeping for --delay. * -e 'feh &f' is not intuitive. Can't use '%' cos that's reserved for strftime, so now the internal format specifiers are prefixed '$'. Trouble is, you now _must_ use '', not "", or the shell will interpret the $ sign and perform variable substitution. Suggestions? * Purged boring debugging shit. Mon Oct 30 18:54:05 2000 Tom Gilbert * I can't be arsed to type all this again, so here's the new manpage entries: * If [file] is not specified, a date-stamped file will be dropped in the current directory. * SPECIAL STRINGS Both the --exec and filename parameters can take format specifiers that are expanded by scrot when encountered. There are two types of format specifier. Characters preceded by a '%' are interpreted by strftime(2). See man strftime for examples. These options may be used to refer to the current date and time. The second kind are internal to scrot and are prefixed by '&' The following specifiers are recognised: &f image path/filename (ignored when used in the filename) &n image name (ignored when used in the filename) &s image size (bytes) (ignored when used in the filename) &p image pixel size &w image width &h image height &t image format && prints a literal '&' \n prints a newline (ignored when used in the filename) EXAMPLE scrot '%Y-%m-%d_&wx&h.png' -e 'mv &f ~/shots/' This would create a file called something like 2000-10-30_2560x1024.png and move it to your shots directory. Sun Oct 29 01:02:16 2000 Tom Gilbert * Added -q, --quality for setting compression quality. Fri Oct 27 21:01:45 2000 Tom Gilbert * Added -s, --select. Let's you pick which window to grab by clicking on it, or you can draw a rectangle and grab that area :-) Also, while scrot has the mouse grabbed, hitting any key will cancel the shot and release it. * Plus, something import won't do, if you set a delay, you can choose the window or area first, then the delay occurs before the shot is taken. Thu Oct 26 20:37:08 2000 Tom Gilbert * Patch from richlowe to show countdown with delay (-c, --count). Cheers bud. Thu Oct 26 15:22:22 2000 Tom Gilbert * Added -d, --delay option to wait before shooting. Thu Oct 26 14:09:52 2000 Tom Gilbert * Created scrot. scrot-1.7/Makefile.am000066400000000000000000000041141414262464400145560ustar00rootroot00000000000000# Copyright 1999-2000 Tom Gilbert # Copyright 2015-2019 Joao Eriberto Mota Filho # Copyright 2019-2021 Daniel T. Borelli # Copyright 2021 Guilherme Janczak # # 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 of the Software and its documentation and acknowledgment shall be # given in the documentation and software packages that this Software was # used. # # 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 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. ## Process this file with automake to produce Makefile.in AUTOMAKE_OPTIONS = 1.10 foreign # A list of all the files in the current directory which can be regenerated MAINTAINERCLEANFILES = Makefile.in man_MANS = man/scrot.1 docs_DATA = README.md AUTHORS ChangeLog doc/scrot.png docsdir = $(prefix)/share/doc/scrot EXTRA_DIST = man/scrot.1 $(docs_DATA) SUBDIRS = src distclean-local: -rm -rf autom4te.cache/ -rm -f *~ \ src/*~ \ aclocal.m4 \ compile \ configure \ depcomp \ install-sh \ Makefile.in \ missing \ src/config.h.in \ src/Makefile.in \ src/scrot_config.h scrot-1.7/README.md000066400000000000000000000053751414262464400140130ustar00rootroot00000000000000# scrot (SCReenshOT) #### scrot - command line screen capture utility ## What is scrot? ## scrot is a simple command line screen capture utility, it uses imlib2 to grab and save images. scrot has many useful features: - Support for multiple image formats: JPG, PNG, GIF, and others. - The screenshot's quality is configurable. - It is possible to capture a specific window or a rectangular area on the screen. Because scrot is a command line utility, it can easily be scripted and put to novel uses. For instance, scrot can be used to monitor an X server in absence. scrot is free software under the [MIT-advertising](COPYING) license. ## Help this project ## scrot needs your help. **If you are a programmer** and want to help a nice project, this is your opportunity. The original scrot went unmaintained; the source of the last version, 0.8, was [imported from Debian](https://snapshot.debian.org/package/scrot/). After, patches from Debian and elsewhere were applied to create the 0.9 release. The details of our releases are registered in the [ChangeLog](ChangeLog) file. Now, scrot is maintained by volunteers under [Resurrecting Open Source Projects](https://github.com/resurrecting-open-source-projects). If you are interested in helping scrot, read the [CONTRIBUTING.md](CONTRIBUTING.md) file. ## Building ## scrot requires a few projects and libraries: - [autoconf](https://www.gnu.org/software/autoconf/autoconf.html) (build time only) - [autoconf-archive](https://www.gnu.org/software/autoconf-archive/) (build time only) - [pkg-config](https://www.freedesktop.org/wiki/Software/pkg-config/) (build time only) - [imlib2](https://sourceforge.net/projects/enlightenment/files/imlib2-src/) - [libbsd](https://libbsd.freedesktop.org/wiki/) (if `./configure --without-libbsd; make` fails) - X [(e.g. X.Org)](https://www.x.org/wiki/) - libXcomposite [(can be found in X.Org)](https://gitlab.freedesktop.org/xorg/lib/libxcomposite) - libXext [(can be found in X.Org)](https://gitlab.freedesktop.org/xorg/lib/libxext) - libxfixes [(can be found in X.Org)](https://gitlab.freedesktop.org/xorg/lib/libxfixes) From a Unix command line, building is simple: ``` $ ./autogen.sh $ ./configure $ make ``` Cleaning up the build is also simple: ``` $ make distclean ``` You can return to a pristine source tree before running `./configure`: ``` $ ./autogen.sh clean ``` ## Installing ## If you've built scrot from source, scrot needs to be installed from a root shell: ``` # make install ``` Debian users can install scrot from their package manager: ``` $ sudo apt install scrot ``` ## Author ## scrot was originally developed by Tom Gilbert. Currently, source code is maintained by volunteers. Newer versions are available at https://github.com/resurrecting-open-source-projects/scrot scrot-1.7/TODO.md000066400000000000000000000042661414262464400136210ustar00rootroot00000000000000# TODO #### The lists in this page summarize current efforts in the scrot project. ## Fix bugs Look for any bugs reported downstream or in our github issues and fix them: - https://github.com/resurrecting-open-source-projects/scrot/issues - https://bugs.debian.org/cgi-bin/pkgreport.cgi?dist=unstable;package=scrot - https://bugs.launchpad.net/ubuntu/+source/scrot/+bugs - https://apps.fedoraproject.org/packages/scrot/bugs - https://bugs.gentoo.org/buglist.cgi?quicksearch=scrot ## Integrate [libbsd](https://libbsd.freedesktop.org/wiki/) The BSD systems provide nonstandard C functions; many of the functions remove the need for some boilerplate code, and provide safer or easier to use APIs compared to the C standard library. scrot is in the process of auditing its source to make use of BSD extensions to the C library where they are found to improve code quality. scrot depends on libbsd to provide the required functions where they're missing to remain portable. libbsd includes manuals for all the functions it implements-a list of them can be found at libbsd(7). The manual can alternatively be accessed from the web at [manpages.debian.org](https://manpages.debian.org/unstable/libbsd-dev/libbsd.7.en.html). BSD systems provide manuals for these functions in the default install. The following libbsd integration efforts are in progress: - ~~Replace strncpy() and strcpy() calls with strlcpy().~~ - ~~Replace strcat() and strncat() calls with strlcat().~~ - ~~Replace error exits with the err() family of functions.~~ - ~~Replace local implementations of data structures with the sys/queue.h API.~~ - Find places where other BSD functions can serve scrot well. ## Comply with WebKit style We're currently in the process of complying with the new obligatory C style described in [CONTRIBUTING.md](CONTRIBUTING.md). The following files are yet to be converted: - ~~src/imlib.c~~ - ~~src/main.c~~ - ~~src/note.c~~ - ~~src/options.c~~ - ~~src/scrot_selection.c~~ - ~~src/selection_classic.c~~ - ~~src/selection_edge.c~~ - ~~src/note.h~~ - ~~src/options.h~~ - ~~src/slist.c~~ - ~~src/scrot.h~~ - ~~src/scrot_selection.h~~ - ~~src/selection_classic.h~~ - ~~src/selection_edge.h~~ - ~~src/slist.h~~ - ~~src/structs.h~~ scrot-1.7/autogen.sh000077500000000000000000000044551414262464400145330ustar00rootroot00000000000000#!/bin/sh # autogen.sh with clean option, v0.1-scrot # Copyright 2019 Joao Eriberto Mota Filho # # This file is under BSD-3-Clause license. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. 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. # 3. Neither the name of the authors 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 REGENTS 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 REGENTS 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. # Use clean option if [ "$1" = "clean" ] && [ ! -e Makefile ] then echo "Vanishing the code" rm -rf aclocal.m4 autom4te.cache/ compile configure depcomp install-sh \ Makefile.in missing src/config.h.in src/Makefile.in exit 0 fi # Do not use clean option if [ "$1" = "clean" ] && [ -e Makefile ] then echo "I can not clean. Use '$ make distclean'." exit 0 fi # Do autoreconf autoreconf -i \ && { echo " "; \ echo "Done. You can use the 'clean' option to vanish the source code."; \ echo "Example of use: $ ./autogen.sh clean"; \ echo " "; \ echo "Now run ./configure, make, and make install."; \ } \ || { echo "We have a problem..."; exit 1; } scrot-1.7/configure.ac000066400000000000000000000033261414262464400150140ustar00rootroot00000000000000dnl Process this file with autoconf to create configure. AC_INIT([scrot], [1.7], [https://github.com/resurrecting-open-source-projects/scrot/issues], [],[https://github.com/resurrecting-open-source-projects/scrot]) AC_CONFIG_SRCDIR([src/main.c]) AM_INIT_AUTOMAKE(dist-bzip2) AC_CONFIG_HEADERS([src/config.h]) AX_PREFIX_CONFIG_H([src/scrot_config.h]) # Checks for programs. AC_PROG_CC AC_PROG_INSTALL AC_PROG_MAKE_SET AM_MAINTAINER_MODE # Checks for libraries. PKG_CHECK_MODULES([X11], [x11]) PKG_CHECK_MODULES([XCOMPOSITE], [xcomposite]) PKG_CHECK_MODULES([XEXT], [xext]) PKG_CHECK_MODULES([XFIXES], [xfixes]) PKG_CHECK_MODULES([IMLIB2], [imlib2]) AC_ARG_WITH([libbsd], AS_HELP_STRING([--without-libbsd], [Error when BSD functions are not found])) AC_CHECK_FUNCS([strlcpy strlcat err errx],, [LIBBSD_NEEDED=yes]) AS_IF([test "x$LIBBSD_NEEDED" = "xyes"], [ AS_IF([test "x$with_libbsd" = "xno"], [ AC_MSG_ERROR([BSD functions not found and --without-libbsd was used]) ]) PKG_CHECK_MODULES([LIBBSD], [libbsd-overlay],, [AC_MSG_ERROR([BSD functions not found, libbsd is required])]) ]) AC_SUBST([LIBS], ["$X11_LIBS $XCOMPOSITE_LIBS $XEXT_LIBS $XFIXES_LIBS \ $IMLIB2_LIBS $LIBBSD_LIBS $LIBS"]) AC_SUBST([CPPFLAGS], ["$X11_CFLAGS $XCOMPOSITE_CFLAGS $XEXT_CFLAGS \ $XFIXES_CFLAGS $IMLIB2_CFLAGS $LIBBSD_CFLAGS $CPPFLAGS"]) # Checks for header files. AC_CHECK_HEADERS([stdint.h sys/time.h unistd.h]) # Required: Checks for library functions. AC_CHECK_FUNCS([getopt_long getsubopt gethostname select strdup strerror strndup strtol],, AC_MSG_ERROR([required functions are not present.])) m4_pattern_forbid([^AX_],[=> GNU autoconf-archive not present. <=]) AC_CONFIG_FILES([Makefile src/Makefile]) AC_OUTPUT scrot-1.7/doc/000077500000000000000000000000001414262464400132675ustar00rootroot00000000000000scrot-1.7/doc/UPDATE-CHECK000066400000000000000000000005431414262464400150110ustar00rootroot00000000000000To release a new version: - Update rights - Update changeLog - Check for spelling errors in ChangeLog, manpage and README - man/create-man.sh (DATE, version) - Generate a new manpage - Check final manpage with man command - Update README - Update configure.ac (VERSION) - Test in Debian Sid - Generate extra tarballs via 'make dist' and upload to GitHub scrot-1.7/doc/scrot-128x128.png000066400000000000000000000346761414262464400161020ustar00rootroot00000000000000PNG  IHDR>abKGD pHYs B(xtIME溉 IDATx}Wu7۲%7l̐ PB[t2d %5 Cd2a1 d¡Ll mY-KVyk}{ӻ>KNx/{>}{_.?#G@>}#G@>}#G@>}xj"2̪4?Z( EBR.ϼX^j3uIyZ˳BCXi_h0.Ԛ=wo9a3wbǗ=X̷rB.C:ϣ/a!_%&kF՛Vr+,;6S(fgsz5lT&\Q5Шz VoԘ 2vefҶnj?qK3-0YZ\W1 HAƂ噺BA4tRP@;1-߿e󩍩bsFfWeP5xQsE=xʥ^C`Eq鸭f F嚔i-$L!-wQh5/jh\Xg \< l-<"Bll,/bQe6z~2ԛ{><~c֝1f- mg;JCKHV:2lkH 9Z趁cTiǚXU[K8,gYv (~(WVLqg;[{GcgX+o,\i x1`ҏ՟q^\Mj1D_}Ec?}8gl꒞TZ(Mᴌ8듳#޾A~mgI}j"8d>I|'z9PoI602QQ$ZЫ=ͼꩪM(S䛹]<͛sTV5s'yqx"!}'qF@L "FY'G94%82i(|1Syr x`{?[ӵz9g89OKu{hR, R%Q@<5B]+Ux{T3\k6Q9Wih6꓇3ԡímo]yǍ\8hU_õ;e_?rI8'qo6 C1ѩsrDZC.9d~ctSJJw Nyا@Voㄹ˫_X:| .YT^WW:yΛuec~ݟ}וO؏̗` /D0a<ޟ䊣WQ+)Fpapa8O*A :B"K "\qš?7~=Y6^/˷x%3{&FD!aIP+geOu'8&pݤ*R A.7#LSu;~x9wm]ܧmm֋oW* V2^# Incѹ|ERƪAG,8˵ Sv.\[~-@Nz}˪7yV a'4,`S/l+9q'-?&`5|z@֑xA7"_lY;g~{R%8C8Ab*p .ͼMa8AN@C3]b[8Ĩ $P)r)A&n@QST|ip8Pz ]TC7uԅv}O?H%Fa3@׫*ԮBEQC1)P)zS:uޥ׍/[:E_ 5I IIJcIIxPBz1b$40P!H:a0_Cp0_x/z>9StqL@ŠI&l[,<:j(&浖aGđ{m뇧˳'Ǔ9pu֦g܆'y,t {t D'r,G8(@6uJki| _%))\y9TD9^؂4GwfMNـM"T᣷D;vlѱBA0K2ZM#'$3Q`3D( N:G@L[t^peVtr!bM8 <`l7В{ 6%<x 4xPSCYN̓q* տ653ج)kCLݱ$D85-IQF\Y9hK )q#d:TR$X+*ޅ_tUg8DWA,4N~xp3ggnp&ȇpyXb\">;}=:^'bXCm{\_bBsVs=92e3A &^:g0KNe:|.DCӤ$cK<@lRrs)]'xV F?qh&R.3#7X±%Ҩpl֌f_84N-0>!bI" zA#;h}6-1 }ݲAnÞ6X'nHOuNzcIw2\JD~TXȔ_'ԩ}Rgl}*KۅσпG(B}=2#i%lܰtٲ\QY.X\KmEorki] q02݆c}9rFʣƮ+24"?>=a p_:So 07rzM}8K=x}f8o{F<*hC9ݸ~( }giܓ^_rUUaf 7]mU&'{Iܫ!؏pC\=b jժW^ٺGFF@_L0o׌F@E uLX \q; x,d,0<^ΕnQ9Ub|Ip?x@mϞ=|!V8 ¼ǚ5kjW_}u. W |o[oBf0ɍ 3iN(I%a"6 2r+m P-ٖHsk즋joEN5gY{^꛽i O srnvz3qVme'A}g9,r4YV:q7{t-]ܐգn>%(flUsIN( tg[)1YǝQmb{ iEQ` @ONȇ{~xmo%)'_?(~$c]eY13Aۄ~,Yi"ɞ].A)׼5g?Y$Z|.Q$?~z+$NF 3Y24 DH[eBVq_L t(I>sYϥE"9{z) "Ghbϯ-*f0'|f${з912%DUrڎ2X fV b@Q̎CxcT9Al%?T?p ]4204Z*[zсs\}ob׌O2YF J,9t$iT:Fܻ}]yU06>VZ41}\፴=ÁW{?uO9$%@#zFzcS|ĺ0%yUM{ 7W{OLϽԝ{DMKcCU4sYg6>%9' ¡]UPǨg̼l5^INLl5wm'9ܾwr`hvZK`.<eLԻK}WDD`|30i$QLC *:˷; [ =^^3u\:AS?8]q=֩O?v.*>D|)Q҅d |F$W%Fug/N }]m33͌/ \ |ܺ] 6@'il"yN26%WH\NəKBQڇ ۶>Ըs_iq-e|nwU}]f4m 'p6`9 d!TrsSgr۹v%?k;nl8 +XGW`[,y>lpn'Ȗo*aNʌ I9`QOMwzr2w׿3b3=XtC_V=ߩpWT3ى -qNi%2餎$N2٦I`%t8K˓hǥ V)A^XgBy!TXX[je5wz$w'?[Gtq<ϾOGQ}^P]2f32Hh+IŹ@L96A@ &a~Ͼi444Tᕔrw>Gq7y#,:%?:  D:z uZ dk&jZ ݶG>W5yh+zOW}g#x µ3X+faK7'o$ r쳙[j|<5W-3sk9swu ~$%D[>#9pr{mY(cKWs A@K!yZ?uOx/Vfkgf\pz'~ 'hݱkE$$:<_sP;Js;s kuiI9k׮yb,4i`Gs 6HQds3B.s!N6fŏnߕ?:/qV,_x??eC/ +L9]'}w6WףpW787 HvԓtJ)!Q^+gt< z*rx*U[,jaҌۀ=U&KSii䡱A)!X|(2!~c𡃇rz`[efI/?Y?Z~i~w>bwiWoz=;WrɝnYlj# i?mVgG}zw/sǽָc[.S4$ݏ+ 'f=DȖ#PI.Ws\&B`y: MV(>Ut?NhratY~jF>KEn hrsSp.qn m><菱Ǟ_=\&λ ؉c`NBLo!2NK1a q"W@U(2PIv96e;䤨bҒaLC6G5|>tw_Z{b?N>|M1cp-d_n޵ZB>EXvy6 /K;D2c4dY_/L.I8au'n'& %!^rP6gف(ϛ>'k?oӉomenZx ?Ԝ}=G鶧;4x yoK6I.Ɏ={+E:҈HsFmc˿?!!Vn}w#[J`P܉b o4%X2$;Ryz.9Ade+_6uKVmp߹ҳx#vsܐ2zc5'`/9kYw7N:ܽu'ޱsxjy^3}WoҍI6~G'ڍT˳,BʛC mڰc{mg3q-wVmX ͫ' [0Id1cI-qqtΨQx[+&FA(g"I;钃V=YTyt+-?w7nDak{g[0 A( I c}۬ׄD|Ȑpb3Ȟhۤ3|_-4- Žı>{JIOo9p"I>v-SN_?S|8.Hc-N2G8QF)0|#x#kS R5c :g>.cIr(r=CYG;w0ö9w% Y9SڜP}`th~Q:gpBu?N4'1OU6>cwG9rs9 |ViVjV\=1zOϣJRsY ^$?1g~sOi?BL8N,K&VL)"CcA ҨHxɠr']ʇrnLl/^X&h@axt#}{u3jo|7u,Y'Ȓ-p' %kv' p9ʒ7<=m V#_GNġ5,4 c# dfz  ƔxVeyzQYMp%@9 ߹}}&t6_2U|v ,'Lt9ijc ⓚDb1_rG3euÏOG^\D>y.AlaD0:CBHobZϧS8p1}'w<=? 69I:XVvIIϚB< 3ElWb.gv(X;*K;wwJg)I'kmw.t3@&yty&9c\9{OkS@Ё ǧ+Bx$aNШ! ;eI@!znVm22 ^G%ڍrIښҒSYԇcX=:(Ovvraqj'ۯbi@L?ٕcCa9h(Oj1w,7qsKf=ɇs!?! :#GS];6 ^55a0]vg-5нH  9%DѾ=2x7OJ|QMzcl1LF5W`^!9|{Y-S;D[õ?AY3+'qJB?HGM1Atj r t2eɜ!a0? wTW-|+{:_؁xODr'3 _)7g)c&N?L3O&IoKp ƨ6s'hIbh/dtRҦP`2cHȅ"۵i-^cu~[5ر?Ϲx{hQC&92ɤ hbb%ZfhŤk?gw- Qo9n$86QGl$V} =+C/#gRgd4#@#:>fvS 6ge/6 WGʍ;7oY`e䲱hN61VI)F?x[jEʰ!ThP>VqFAsP !K3_JƛUBMm,pX{׳p1u7og0Gf#mH m*EH~& Ă2_1q`> eYY*A-BFZ1y@^Se$2%r٥gV H$F꧟v&쯽=;7p]z^q=|Oq!?`ދTS/qcǭ $F:75ѥMe[N(LQp/޻)5 @1KMIP<?T4,ƐT V42'ʕ+k7Gr;~/h'?mJnрq[&S4DFjl[,Fx&/M36NspJ,d3c8X;/zd!kB;c= L ES4Y/RMȻlE^c8i|E)|M>5Ϫ6M+Ш+bx988O1b:M&Iښ}m4P\I{ ԤWbFN$E9@$ČI le4JAb_QmxSAz(u 1;˖-$속Hyb2 "W6šmA9?l}'/#TUTEo2"O)$9lyS<`R/cysxme|p ]:i-YxFc# Y9m>ƃaI4ŧup5訪 IK3Uvnf2."'#5q4|No}tc:h23\ %+c֗p9B@s[7E%Q#.˟G8'tnMOğ95zs~#1,\ p-n!\ܷp(dKHz]>H\vh_Hnf5)r ԟ~EmE"|a3OAb?66Vi$J8 p$GHvzacsf:y'/o0g/ZyGeQ A,YYe36BXǜle `\HJ_캛A;韃8dz~ן9Lwup`9 rꪲH"i#$&tjDjA9U$ci~4C0á%/lѺNB}6 ,Gmj osBR(j?ǟp(KEZ8aʉ d°o?n1K L0r=GO@PFg fg-{FlVgߙӕ%  ܫ^e7@Ӊ"lA/V{e$X ۰-z`[9Lےۊ`f o.>Ȝt(JՉR'tGoѰd;|R1SqjH{Z2 .ڤLE l}ɴrK--o._uUj3K/Ax1RGVXq20# 6qׯ 97[FbN@ 4)ߌ mNHG@}ҠSCARMz4=8we۱}[` @@^𶷽5 I%xi4N${7n,@9nQQndAIJ @ER[iDWyg;Q*$0H@܉2 'RYod&F"8;Hr"iqW\U|[R>j_1{e=%1l4͎,6v$9v;ˇ2a?OzsOHg7IL$Rd!BNS񴟬i~)xx/{i0ZTG̯pٗ=q5>bY9`+(ԏrSmV9P$v9Ⱦ]ݎaJLm@>۝>id3N:`鈣ur%wzw>Kxx?aE~:@" em8ɆYpp2g9g>SϙMrEwxsLKj$;] /b$!)"ƽ"Fʂ4 `o٩ګ` pQ^j>+ ~~ᙛoy;g f`C'<4>Lyy1=tN!nam kX #? nݺAo{o C8 `( E[a o%U/_^Ixju͎mv^:ec&hlR6F )s-!<&:] !, sҌh7ˤu xr|IddCT9;>2z!)G[-YpwyÓ={L߿w}x ]Ďr#% PB~I\cKnWmȦ/apNbk*ƅc+iytۊ;RotP#"O6dARPe"qIJigd(m3ӼS`+vin8J(4papѵkk|/~{ wuͩC[Xr n sV:tc,9U9K^v:fxpS-fw? ztFP Q$(y=llj#9̫ YZ}LadL0'>mblX5SdOǖ } :@Ӑw9:+ lX..D<>@-y웥_8 E,a>Ή 9#&+mxmbLK !-@]D]ROOuܔ/fǖVsz% MҘz9lc7)KVl^, c_fʺm[waFrHG@7\i1m6z>ӘH'\m蓔{YVEُ h3}Rl]襲Wc>Ufl>^5AR"բ^A09.i`J[~Jv:7N)FFk3 !`Ҿ-B\ef`96Kt9ׅrh.VgvrA:g12қ$~.N2ɻHuv8V3ԑ;è]XϺ;>-[a`HHrhd,O ޟ H]/@Y>l.Y}#J'wGFOʅkҖ&d&qt2U])h! ɛø*fK!iG:!˗+01==]Ӗ_t)b 00p0r$F+Kr0\rKcl} Ͱp YFY=]kd=u1]9t,L/|;]#Yd3 ?<Z:>v|fo| ourAZV]䲯t={Ko?Է`R 9/d2Mob$Z%=%Qɿ`2sFධPq.7'vjck継/ߩ[y:gvd$ۙܡBG+8o]煬臧&ׂێx<*')[r8+S Ontkž#vc@@N>#}#G@>}#G@>}#G@>}D-QkIENDB`scrot-1.7/doc/scrot.png000066400000000000000000001215221414262464400151320ustar00rootroot00000000000000PNG  IHDR<bKGD pHYs B(xtIME& IDATx eWUTC@**  B B¨ @ۀV/m8"(hC0$2g"B2**U}ks{Ruo ޾{Ϲ7< 7CÙt Cxz\cr.m3p7sdʴe,bx$gS6 -ۏpǺfmGx=}o&FujFOgs3촎tt4% CYC:95ʹ2 ^my>Ƶ d'gȱo6dwl ]W45.Cr{0z0 n]JKXE Q JmJ:Mz!.Ê}Wzo8]u^3ㇷc>ϼ3NqO<[ Ⓘ *nzb)t8?3rs\ļe:D$Dq0)@e!VTx&@Me>@PinPN†fVv#88[xǹ-^7*vn݁iZnt'*z'O|>g仇u? 8_wc^c?oc& z{ϕ|j˞Y;-L*ES+33`]Y5->[9Ylkyby#?>m;|n ޶C#Ŏl'yAՑtNN'9nnx;r+q>?tf7O>!d%?g_ğ} vT'2 #u@s&wQYG[eLs[lbIae"M읭ܻsWԮT mT# km݀׵$t׮C ~ݷwW_?ezKɯ{WyA'sWXUfVs[R'皠x8'·WiNd{`v(X: pe/\ktVhr 8ځJ=(ua@D<$4SmٍAk0&ǔZ?].QKi'̓sQthBK(Mw\^)eN 5# 3VZ ZbN-7W]k6Vpb3 1:$uuòX3%|zࠣaظ;zmC'~YqI0n :Wq"(V]gEZ Vg_43=Ѯr+lK^}o&bO*۪>WuR{/1tg@L<vil*fϬt`-dL&ɲZ%?xȰk?z>S 'Uߨ/ھ%^\7;6>t -iOr yN`UPTS&w(g]d@ë:0>G=`U3 /w]#mҞ}[F/߼CUٝ}Ew\; 5v9H[[p B1$eNyUTީ >1xvy/zQN:\AgE;%xzŬ*CG]iZhKIgL~'nZo.|;}-.}Gzs[ߐV`/ؾCU۴wr|x ڕ+|k|T=UA,B ׂw{-ЫUj6-.?ubq^>CĈ7! g^g.,~^︑;A{qޭ\_N+x Cu#baUbuImNjը4Sa{r!<x 3ίk+[AK+]ʍѿq`,y=1 qY?*o;2z'U0׾^8íƫ 6u1557;.30 1զ6N;ߗ͊nfr|vz|Wk]~/諏o<~ÿ }O%ϻdxltN?!PyvDO)Q ;c4ij:>L eW9R}fx0{ ^_gt H1i)&$=4=c+f֏4sS2fJ?@ WfcqS<.'/xy+/ԅJ.I~O_>턗?r~"{>mvUSU̸n`<8<]| W\n1dxeGl:- .XiUU- ,Īyb rbBF|8{g_ pOZs׾ֶв&0)4PRŴW*E]#Q`TVXSeMZy`scjW" x`l"d{GgYA}崛.H[V[:)Kf|ZymVwϧ+urJp= W3KNpz+J[rRL|nׯ8@ԗwÏ_^S:|]-;\("}hZv U2;(p aS>l>Ї\MsD aX_])ȇF)2ƤM\kMfd0:tg[ ĺڡJgxf8o~y/Җ d?3 Oxޖ;MDՐlN1  ?hMAuˆf-1E 7>t<̞`)*7Y ݵ`Y1VlMةMc~JFi/y5o|lUNjx{khXV,+.9EbO_>#صe(U]`X zo;X92+VwJc;\e}h1|5Ej+C 7f~+;<'~Z|7^pɳggR ԙ:R2 Jo*s_fEŽhK Am^ tZTmuE3},ɡK2{NY/A'DVȅO扏]bJ;V1geT6݇:C[oI+C%֫4΁>ҫv<99pv jl⢞\bA]*,v<\ Poŭ*y3 ojԞ-gߡ_t>kMݱO|RW`j1ZP\fD*Ggu~S_ [ nVmnհљA rk!i x;ȣ@+R9n9mGxe>L^[C=^"YeJ8Ur@R>W`bmB<<)/%+2U NL \Y.+a#pvh\sݹ;;v+FW.Ss..Q<樍$yݺ $uXe;#L,/PmUNA6RWBSTK+!U/o/ #4q T_LZSL(w(Ыw _쫞|]эd+$ FX,UlZ[.bh޴c {ĺp\,?܀CCN(*`5[g+st-dc^j<*N4[wl+Y֌rn{亿x^xُA^o]prljh&uI` "ړd^!ar +!]SC*лKBn6 +X+`'P+mU~_?sUT,Ңſ 1K]%F뫭Lmr̺6q'm}7J0-+;.D;WA?B -ȍG;zVq" 4r9=4׵/~ QeYbEolj`VȄ=nAgksdqɁ[u/.lk'>[ܧ][|S3Lr}3 Z)E u~ovR`pWw^ڎs ?o" <]=y3%9+3rᮽnЙ@S:UFfك &ߠcWnI[ʴmdӞyէ[)ghwt(@a D)pj^u%.\[۝tI:n}6K\׉r">|O#%=kirW7r|w݂iWev+8wĝ M<97)V1]gWoڊs3NWo)H4ͧAd#$QS~KkEH"m,ۗ߇m}{Mgz`ɧ&Xnѵ™c~lPY`q4$@rV |f%@J,4h'5DpiFVr@qz:1EVI$<4erU'?q=OeˬPdi˾4(y^,<$S]JE(z&{t,r-Vt]O΄C1Q *C02w3ޤG<\Aͤ%],Au#nŤTו(K-CgUy{u$5TD@VJZ&[2 5J=yXȾ #JN} j܎* t?+|)1;BǞ:|IAx󿽥kZ |xS2f^(W*UX:?vo_Q$bU( ڒ2 7I=`7DzN f;eZx 1v afOeeQM@N,VXS*ADP' ";[x jb-o)oҟ fMق}76OOD, gOdS[\ جöevPSWJ6!j+EWDj@IA PļEҢE )mن۠=Ɖv䣂ݴ=; HZc0LDxF o_+YYy80/xN U:1r͍t@[{f\ @DF2peZ8!6Q>D:N]H $;({2攖R=y]!cmT4Y%ՠoOmϺ,uxcWrpO7L׉fGrb(Wrk.o]nnYT`r9pxCPE&e-WUwʼnR_N`~" 7 7LC'ȁa|][.Xf^ۙtn|mm ߊ|[rw| [^5S-gݣѱFG :W]~ky(U< 73;띕LSJ|ZU(T!Ķâ|;hlo[{A,~ZE.6Az'^AEΡǂСӥȡI5RIɚc Cf_3r;y%}gopKiKy/U5kҮ'ȬxCvKR<#偻Z~:Vz0Kǒ_R<] KΥ3E~]}cbؓv.4S|&eђ<ЯxIWtOG_î-Rtc)-y`{JXdw8黭Jo:)%%,y`Wy3tp~Ҏ:+x~;dђ< ncOvӎ:|H/nWrK2Q:>0\Ԇ tVrnRZz8Y&q`Gb~,<䁽$ tdݢi{EKXCOA+3byvŐK%,y!遍Z]hbwY m)zk䁇Vɼstl׋m(¥;]nQBܮyn_cvE {뚳zfs7zH}Q#P?2:i.%~w5}q55#a $̃TI)z-e=BnȬ )k}DP?]bCG<4ѕup + m_6Mv"OkgO.`8EG\ /SDzѕ2.\<#0+i!IJ'04 dϨl"\ ߾~[>iy?Se(wyF4C$EM,q.davΠL=4fE+A.xm{;de:mֲY퇎;`y3v]/KA+ÎKЕ\K5>Y0U-}4(eבdEb =@OtS};pΟNǾ|0W$iH@g?9,S5/ Q:1Qb7c@GT1w0 wE$Y 4yX^k*6eَ[N Y#+9~ML`@ȁQP9s8A^Aρ1q] vrӶPh({:16jږW#mv vr2XjTsF˒/xqcM@JM24$";!ee 6crq!w1xV~% |J93p9ǝmwƹQN0#[!&4qVkMC`h.\ڞv͹ ڽ_e~ ߫e'0 yc;[_qQ8*at E RH'j@AЃ^$쉝vtBAk>ʆF} ˨=F+rבNY4u"ƄI&HC&M'0Ὥ8}<߲fbf7k5皜A.CW=dI^^} R2Tw-J uWաic4V|}A:( 0 O'輡=AwY^ آ "՜Oc®9 #呋4psPt v8: a^ 8w-v'qNE,'Ɗ?1 -˴/m?-VwlbNE1V Z[ AmDp&%zҹMyk0Lk>1\A>G>'y: %&a dhg7e"l=ޔc ɿsl]Je>C 'G;gxM"XLat"~e<ӛ;,Vk"Y)l#9:3D%uЬASd<$CIEs唓4hֈ \NJ#r4!VK3& :2vѸl6m׿ hc5 yY 'O )=`=Σ)A>k&Viy[U|;rBJUuG'5Қ0d|> r+FEZhU0!`bok ' ,zӁ[zqveF=zZu_ h .D_osl<b"hZhêTЁC30Y"Yy#FuMۧl xdgug7~ 7؁8[$'Gdw@}7~?5%b *brms#LGLINnv8SuDfGd=nHL'<==Y ەy@TN2gĘGkjx;|f5&huP7Pa .~6r _Yi^>Gh'4ژX|`QA)=6zyDctl4veSd% ;OggQ-:O8?Dw-w[m+h)xs ;dX,u9a@HL`%y"J?F\S/$bF&Lkodɖ `ȢmZ`y2:h{i?N@qBg`4$SO/TpS D1@FbDLub]tʰuɒ8l2:CfakQ_MZIy.gJفZ)#Z't]E?{;po滚Z׬{]M'?f#o>怃lV=CnuCpnL?\6]ϮOU@aJ튓aU1iCD Zd⃐C`Eoz".|>ȡKsT$Q\ߎYw˝ͽICn< ;@ϑ#4euӘI3vL#®NC]A~vR@% Nɉk[y} Ydu~Xa淜P۹lZD/{t.2bŹN|TD "E]{n=:-d+4C@J^|*enPѯ!3fl <]<ʡ\A@ ?ɶdƘ~Oȳ̤M^6T  [w(ȭD66+Wlc-@٦+C>H(Љo09{-{m ^mDFQNp#N2BW< ?{DrLu (fdG!3)ZZ&V 2 L=RK URRWd-覵|[i>Oh[{WuG?ņNj#5Wr<S"c2hcCYfLMiB3&l CNɏ< !ֹI3tSM ۯiG]~ ngx)vUcL:A&O%ZۻFAU$mtk/*p:igPpAs`R-6y--ORgT 6,ڬtmYP, L0TY.՗_9m*$?dӍ85O}s59V0nO\7O+(zKyt΄ۧxRg@ pġKjl\{__fʕcu@*_#41_(QI`;]O(ͭ4JuwhR-2]CM<%z 2Pw0#Y: +ń˜oMA D^y1LbL/!+lygsD:?0knl>Gkӛ'ӋW)YRxT ł%I}uRT6Xak'6kKz{Ji{1Sl7|]mYO7\bȡM,e?"[*:D-u(ֲκP|j%qV"ǜD0YPbj IDATa'‘*XV0[ϲY~~36gﵬ]pwUfqXژsht ̞p@dL @$ᶄ:&h jް#%XEDK%UzR`wqgs;?\~P 9W5/nA(gAW=r s2\~'X)Ԋ@M'**Vg{>y[iX- |=AeU|x+#nQ,(3+O:)Gu{h]tLLMfϦC *k&K}e`64|np:znJW>e&"`c%:Zurd En@}+7o/C七t뷮k>{hn5Var&}$ZセmIg8c&Z jzp錪 O#ؘ&VFêCH}  tJ )~(xBX6 )渕A8b~V$" ,XNYg,.&tIhKe2\!` :BYHOy/~5Sz5%P|rddp !>Ui݋;P{Dgg_iEzm1nWpϾ~AGY6wi+tuЁ^U~&RG =#$ ЄzNVIsܞhH7U].2. Aܭ||5@=( 8 uσd҅C%Y50;4ã݁￿ރ/2jk.?lޠRItE0*%4L8@rToEguXx@(%-,*wu1o璘v0҈UzX"G~+(*77ZkTcH '_- ; pI z!ۓ-c* 򉀧Y}#<0E#öSRڅ2m+m1`Tn[Œ4P/Vs屼; w[$*7,G1: Qp+cȀ`bdŊuS #i ܰqpR!:b#[ucz}ͷ/!?koiqK&}l?_jO= 83|~wdpґvwI൚t&|@U}w 5?Esw\ĆVNi_2S@_Y/supOnf FaJ!aFB'".%#̴'8L+)xk D)'>6G[(Mù&7o;+&ݗFVUv~?e{Ȋe[Y3y|ߙɕo:9z-wʛvvU;?_Мջ&}Fz%X 1A'BB9p_-6RcNVfr2/V o]*< n6lQ;4P70U<6m4CQgH'qnQ,W@4sV]HQ9a,;dx\L[ `bf"!B ?|S_u[}‰_=.;_C((~ֵn%'uOpG_47]f^ GL]?V9ǽ/cg T:8+;$;Uu_ՠХ:M 6onT+8+y/ZW IÈprOT6ѴFm l{[c< r0p@8!@r@~P5#-rAF83*k~"uS@jmPcQZzqJzչS$ؚ7'|qq?qv2ga+-MҕG|_D|+S\zReµ_Y]Sl&+{ݾt4] (2`crtՏ)*L 0_pXHN/X9z)Wd; 퐞ciG7SNaeÍʓ2(s!jL@$sN1HxՒkuU7C=ǟח~x1>@;e/TMC p ڦ=r3<'|喻ɟGܾz}".;W7.I;'js*C@R4%,~2 GVnߡ p7Ǥ=ˊq@Y*x ˾ M1(qҗ9溵|҅6ipQ3+G%:3-Cra(Jx ]((v n\S/R9M6,]~ vWᇭ<^|}}u j5ClI7o08ßy{3ibrrkoyt߯ Q NpKs'4˧|.yؓN`冻Ul6o5!RydpW{F&  yҸ 4r| `qs w0gǖѲۢU|"9w] [% CcQG5oխt~2hp8㫱0\ mp͉G}hʚ^0iw/ /ͼؐA"mGY^Cͅ|_qͅ4rt_{{񉷾?޵V4 a߶b8А"i#zC`CqMg#?O v[qmsu؇ZUq - ޮiO:Nbp082ȽrC_Aɵ; ey Gء:G~Ma#D3&ojH[OنSFD$g/>]i1]ƫbOW V0"^ gir%L':NIQKfup5`ÒDp+l}7kޭw- s8m++DZ{ut;h]'ݷX:&Vb# H\!}SH$%Mж>t, N4Vawq!:s-t—$(dY%44wU˻"t95g]Jtj:qQW`zNdn8unuaCM(k^s%ϯv#m^o~i~睾_l`*FE'Gds#^V/y-xؖ3@$ W]!g^_'a#ZdLB^^|y OShɲ[9*  tŸP64b_87#4-VĻ! p`Q!F<` K ;,icz ɀ7|o1eu9SoE:201|xc+ AYե~!o7z;o|Ӡ /o6}4˩lq0!ࠋqz{\9-Qw;# gꮏ T`{H%=DzDrPhsoN:*s=nAY PY@/賤Wt##[';Q%UȒUuEAgrttddWX0+0O]tD4xy;n#0WNwayA&9h_xte$_WoGkK؃x䝧nQ9{߸FZjU3',ΨGxp^Ȁ7a$rtȇa-VG4}*Phy _},ƒB6fDL:_=S"C *듍9 fJBvk9whq6ijplCqZFC?no>~ǀ X?~& ւ,n f\rm6=MkVcюhξh\>+Ѻ^%wNeKN?îA!̱׿21~T)mrU V^-Uq]B*-g J:k{IukHzxhQ_Q&ڻ60PxαoyٿJ%-A9Hs έ D`2Gz&N2<oԱ}'~p g]Ռ_1m[hm>rhƚLS 緁/[ vnIYA5`FM0.!*^RfXH=4ֆY^Bze /1]'I-UWw#BJjTS=h+9?Fk~Y՝G9 +m9`FG-\O{ +dXRA04`@eD!jA, dZQRP<]9w>MdT,Q*;GEyi+k{lP2vzTfܧ>#`鰟=m#;ҔSLw0 KO;T0.VZ^fMsgm04bI9(_\7|}k9 ԷZ ?[eNDeP㿴U8WdAIHJ t$FxWzmcMh7':+TT=hr79i6s-V!}%Y(I1!䶛omƷ<_}I mih뉫"؛Lş|) y><lt[GF|o˟/mf%%-lW9ZNVs,9j .82*Ez#O#&h$OZ@ASfN:~l8ƅ6҆.Nu>$#Vg dT;Vt9 ɀ=X`L)y&00Hw4"+O#C37{H! `Q&{<@o{":,>JO&(s:l?̿hƾ#Ƶ;,p/Si! x vbCDG`>Ru/ACWPcZ}-D@ɤa3 eU !ю'Z/N2&|lg:AS94TuN$>T l`ԶQ3U?>NcO{Ŀ3âS"h ؼnK)3m'{;fW)׍=턁ބyU7Hm3ޅ#`Qݫ5p&_y&8':3 *LQ$8aMyXO8R|KJz(e6ע13!2(< te+7VIgޤŻv|4XstH⅑%'Ūk5:w:𥧿KDzmtZtM7g.[mWOێAboS3qZU::" piu`>c*O ֨68tL!揺A), Й*"9lhhe@N3l 6'e0R4srTdp9•A_tUIv`L9l Uۀ؏"Yv GCt7%d5 /\Lb~Q4ݼllcxHjҲ=s>qwTg6&+[v dYV ]twb^msA>|4Żb<"oe:/ }4X[NnTeP4M^褭[.f84A.r`n'iT8 /yDQL)A]͗vyRPpQ&X]bx OԷȑr|Spp^OUM5t6ӗ,[PU_u,':j]֎F{;D_c<ϔ%«{E-^z('\v:XMIk/v.h<^UXW?iWVq Ǖͧ7?bL΍5 ˻^En =-@U6Q]Z"&\^Џ%#0\}ʋZc]Ih? nlJlK-n='C/<:3r zI3mB;xP)yቹW-1̠r c47KUF֬:d0: U&J%>1' ,jnJ [FJ.u\s*D9nw9Uk3}ﵭ,o%]+3X prggUλt\2dDu,xW9fP4بƢZ>p1!yAA4`52bj04&KC.WW*Y4 []AAMs>| pP7ȱFesa[C-*x@2zhd` ޣ[% ?M; yNZ/uĘ1s 3ahM}'tzZ? 1 \yR&UT(t ^0 XU!V>k7Sg[&"Wu̷!q]VT-|H ڤ3_]O_hJ%O FGU_z7aTo6P'AԆq^Nbmp`!g=:`dk]B܁D`KHk[CG9àrlLl:u[ܨEhAMvHʳvEHnP.T` 9xV< ́c'3Ē̪[vim#> ClI۷Bz,@ge%nMWA ' "?vS7P"i@Fr%஺a$jT0 4)”W&D1 0 S@94kp8AoiM!JYA-F/|n_9PY8;ͮ꼟xfȈ>3k`܎C3%:/G$!_|o9s0bDs0z)pVN˂.:h YzVuKE`kn!`Ht{/zp,yȠqt"îEn#|'c߾xhcom]03R&5…mvd~`vc[ W7Ψ9:8fκKH<;BF3IF.W޶b`٩@_[@ďމOrjZ b*ѳUxeA8y2L خ&&ta|:d,GwIa%x}7fk#_ݨɚ3B6APٟHUkLFi$dB3^ƺ }xm> bkm@}88P^z+grfZO/ij'm%{Vzx7^[%#ja=y23Pݽte/R&[U=ףzۊ|7DѫwUvmUmQbS^CMj[$7:֕›8j{E-}HDe¢&Br֡jo7>0Lzo. ²OrX1 ]˵R1B{L:墋3k}b{j%x!F#!)ekiיMI"f5c(O?9}6#G!8 O4I"+%'&^GU4Kd?E܄ V!`%72tL u_r\zә1peXq+jCJtߧ5 (*ɬCz5X`c frÏ U'#o׈%A(b9ѢxY EnqH|BwyO5 ?-#٭yS N# 2cR1c.pG-ϼu!U3<g"pV*Z߱ĞHߒvg;T*XPђg%Bɪ[I[-0m-˪DuOTƙ}ɋV1g!s+= _HP:b F(ueC_ c)c..mɈbIzxN&k}HZS^~kY%Od3Ao_3jV:u3lAg-xzٿQnйD'"6֙ ~t WbqB2i`*ժ.z q`"*օm2UGw*bkB'N10.R'4u8bԶNԬc.;fqĵņn].=+E$ZZ4"aPM 5X:>$X\| D3c\lOFM*r9׺rhܦJtH =ԭ3Nsb{LuC >67ڔQy~\U8uq2u!WW1ѾYq1ޠsgʱO%" ~ø;L b5[${ശ^l:>t=Pm{/6b8__ .}a@%^_{E iW%(n2ش-g,w|&`yB`)X1`n$EL`f(؃MpB}(C[BZ0I"&0֚WYo}T{+_冂1}'ȼ1Xixeg9b_$ssGvuTי/& ֓w I0 t $~zP5[2e|N ʺ :LH-[>)QƗ!x^~nMW^ut9cxIHR^;Di. z60Jqzty?>;<{e1!ܖK*+w1iNLbU?K;Fe*`AӠ3PmLϘgeu%Sќօcx5+KBT ^,x֚zmM5.{!йA,\nM F_=5UldF~fW2T;L:y2x$B2)? LVCrGk^ ?V?UL %6Ժ/Y/I-kE0kͼ@.V:3{u^ƕ (.uQKT{cH\:Qb D,>NtxQln`f&aF +J̫րG86m1~K{H^?#?RQkF%X8m=s5fY֚#>\B_2ɭ?l×N^xc n J6*/tmn}^ }}MB 2`䊳_ʔsnh!W/jNkc0bvp\eSՈU9fU|(?~v'kҞ:~pKa'!OkkFqky1Or9h=(6qow$SG[v'Uͧҹ~,~s=cIɅ.ǘE`+g'L"P1yv7'1&Μa3ApЂj:SshS6JJת?~zt9?* biW>o#քU~WLY3"2hSEb k`#{{e=6馛n^@}Xrr%LǏkWYe֠6@W5"vc3$lMTV RF'DXr8qF!)VFdE*YYqպDz"ΖI P˓yrD˩l DmbR6ƺ5{=| pH\ִ9ݭX N[?v?~`c7,SuSUInA鬃]NT&XSڵl!-%[xkuΊ Ωte}!6'겏6 GU>Ο٨=DV687#s:I_wzVamFYm-OݓDXLkD>Eyf%YЛҺ t ,ʨW}|wկvz^g-wx)ӌ4mNg=+Nךy枹e픔5Y 96s;8Tx86W"rbnyٴG]>(mY'J'R+#F}HAUG;d1i4;XJQfߒXϠ3^p]Ss姐FZFe06뮻{^J~g:Hm}q]q`kLԕW̡۬'gIK}Bud[ÌZj/:݇ߝմB IDAT sQG68KHB[ y܇Mm!/?cJ_-7V5d=O&J&CҠZwľ&' âʢZh*P4T|6B'Ʀ1e7^shz+^1}_>8pW_O^}:cr#ur Lq3^K2Wi[-mmR$ǩ_vnb;ċeVi!!ds֌q8ӈn;dꫧ7Koys;?$ d~2 F"-'65k~Xj֓K>tֈ dv]XpՏ*d $%IMK>PdpJƫ9ɝ ܶ3^[V%:{3A9Gg/ࣦLdK ƩcȚ/p ui1_2a AE@ǓŶw>}ŗL"/ǧ;S?zޘk;-՘z%2\0t֩*鶘Nu3-7 vj.|U;Wwd$.΅ GCNv ! ݺJt{Yp5N.d߇=OM|H(}k~O&UM1G߷~t._ܹ{J~;Y5IȜ0/j=Z^3>c {7W#Zڐ Xj=O'dݣ4fЏb:K4(uJ8-+Y L9/gO] Zչ 3՚^̞50Um ڛesq0~ᚭ8\sQEBu?) dNK.^WNw~-{~>{\L@/#CK:yT `=w\8f~s/$yV\Z2U'Ip-=)INf<g|#]q)bn(.njݽԏ{>f8 2gV|A<4x)Mf'vW1IY_=uE>nm߄G>"}k8^W+U2S jd4,P5T /#ns,'6x51iI'麤NhP \5}|= 6ǗIl^ <1#L#,YWc1"]0탢9βU}w6wpi=xƷ5:BWL@8U KvYL"g۩IԶe`d7]-k-y;W2} _>ON7{gwX{ݝT1fQ l+:&XfBẈ u9vK,\c B"%ȹ[;cP$ 2\@waƼ)6պD#3@8U;qMD iTZ0w>›NIXP9Yk-+bݸ,Ia:A`=9Qղ\)d 6c{~!nnzxzks#cmY웃qBg#Kofj)؅ݐxopmZSVc8*5"$>w£a$j ZW`d0vJ&FtpV&p 2焁zHa[Чǰillc,x0.Q-Kmu$a?jHGm"+u$f&-}!Hb i)p43ӷ1Py G-beEr=P }ũ0DvKȚöR*DICAojxKP%65|8fSx?rz Fb9;/z=FSɉy;PSaVzD|Tz+'7RI#6 ۦ %K*|%7Z<7G$vY㈻/b Qۅd=O#&|TT5\lѩW[=FuCqJǭI[el|$ oG>va .ނ̍*.QWGbE{q$~T%>T;wo4 N[PJr^N_şCq7`4uK}uok_7}A8lFF#4& `oֈ{ =buK:^gеî'`hXE-*V|6S>BR8AʒڽiL70cU,erDZmD|Zd p,!1qxw;< r蓘3G62آRrb}2$OJNFi:M2"R}pK\"KCfe,ܺ|ӿ0661,#Bq:$thiT_@e.#Oȉ;q"flC ]P@<;;VV82'?d# ?:C %&E ħ #>|K3/rU$%csaU[_"[6kCX\sr,`e:.mh7a@%D"ۅNnhE0tr"Q[hn.̦?^܎gA9DSFgZDZ-o}[O} l4/wO y-[y W5GQnkz"kvƳHE҄&2vhaQqjBy7C~\6E\O,2ρ[ q]`4(*V 3d C51v(/G]a6J;MOt "SY6QVzrUvևn3Nar %Aј3 HpdRlWꋦ~oor_lk)ה"Ymؿmog= Msk}MtG݋Q>Zt7gG7 `ˊ y6]xT^<[87v"Ȏn챥 t_+4f~͑*ilkPh"sFc0Em|r+c`jŗ%64/EɷhAjTGL -R]}B *5MOJ:Pѥ$nhm`p&cIW-TjSoJ~3m},?JާcL=OҊ)IQK#X$D>v/j)ˬla^ݲp Q7@ʂ!X5Guٱ- p4hͫ(j!#18gp$)si5ܑ>|Z4(rХ vpb[W3~p!oƨO 7Y)YCaچKYv\x|ԕn|ͯ5Ԓh.m#k+PX3_$*~}ė}2=IS}o~OO A'N?j&u[\ePb{mW5<)nJ]zIxuڝ$&aRlډ6O8~y?HpICeO$Cۄ8TgsH!nIn|ER)X[l;U2`:![ޱ^:a3sdtcΉ^,,!9ԗMXHۑ͜ĕywPG_ѱ?G+?M/y y̴0ұY,"%GǸ]Fk\ņ+s胷NzSmcAxbM#3Ifj+g=߰ ~,?1~ۗ ;`0t 7yÛdRc"8(f>,_.zYu2CaFVrrʼnmGs#+_ %wC$O盭8M"W0ӶS57ki]TYUNmt&n7)<k9':Osұu'>Mw~t嗍EԂy$Q#Z wˈb b*Yx$[ [l.#/eW:E~e;3FoR(V,a|PW+)_-0oƆL#d#hw/ ¸PFn2<欦8W~fҸ'22N7%X M֔\IHnͺU8D ނ/6:Ǹ\(ZotIG?#;No\{tXQԋ9 ;MXG ߑ ؐ%P5 yYop;9҇_1W!ܡÇ#\6b, O ,l8X^p!} )=5z ;]Z#Ǝ9]^.pQFǭ/`c{.2sن/ɏpqs!&aбV Qk82?X/mm]/fG_,.sXkp2&MTn?n~idاAh ~~KuK஽ |Om:^F#:znv33KiIN{ߣ#|VQήf`73/~w f);RdԱ%:#@b: <%g(t>YRt<}է+x8^ uŽToUwu>$/IN{nv3]_Sx$'ߧ~چ#q&nv3p3/_qqtޣK/uܹr'n |T?G3*ޕuܣnv3pvfuܯlbD?A$tܥc?\!]n6gosu=rɟl^I+v3;2d/OC;~| ?<ww ymnZ8cWv32i3-.s--".I.p[.3. . / / / / / / / .).yP.R.+. .]=sH 7ńB3 51 q .|,*J)'J&$#"/!5 '!P$8% on' 5(& (o*>(*(*P++-H,T-9,-E -U-).-4<.}.w...F.]n.5./ / / / / / / . .+.Rw.O.(- -`' \((:( ) ) 51 lZ     9  p    y F '  !  2! x 7TP1)))))))))))))))))))))))))))))))))))))))))//////////////////////////////////// / / / .(.u.i-1Z---WY,=,b+'*w (,Y"% 9B887 654 3 o1 80 o..M-.-m-'--Sc,/,h+ +r* *J*E)(YG(:& W$)T"=Ѥ|UB3%%3BM#b"Z!C 6!F" $(&<(5*o-/ 0 G5&CT`kwwk`?-K-,-k,%,,fQ+,*e* )o) (G(?'&A^%;# W U'V|;Rb b!I"5#$%E' ((*D, 5. Հ0€.3ذF 6TC&?))))))))))))))))))))))))))))))))))))) ) ) ( (+(v'g'\.&&&SS%>$b#&! x"Z*3 2E210 /.- + *6 ( ,q*,{&2Y ??&$q z+X2}b>1 bandeira #1!? "     %$#-95i/`t]m    "$&(*,/13579;=?AC  !#%')+-/2468:<>ABD  !#&(*,.13479;=?ACF  "$&(+-/1368:<>@BDF !#%'*+-02468;=?ACEG !$&(*,/13579;=@BDFH  "$&(+-/1468:<>ABEGI !#%'*+-02468;=?ACFHI !#&(*,.1357:;=@BDFHK "$&(+-/1368:ABEGIKM "$&(+-/1468:=?ACEHILN  "$&)+-/2468;=?ADFHJMO !#%'*+.03479;=@BDFIKMO !#%(*,.1357:;>ABEGIKNP !#&(*,/1368:@BDGIKMPR !#%(*,1357:;>ABEGIKNPR !#&(*,/2368:@BDGIKNOR !$&(+-/1468;=?ADFGIKNPR !$&(+-/1468;=?BDFHKMORT !$&(+-/1468;=?BDFHKMORT !$&(+-/2468;=?BDFHKMORT !$&(+-/1468;=?BDFHKMORT !$&(+-/1468;=?BDFHKMORT !$&(+-/1468;=?ADFHKMORT !$&(*-/1468:=?ADFHKMOQT !#&(*-/1468:=?ADFHJMOQT !#&(*-/1368:=?ACFHJMOQS !#&(*,/1368:ACEHILNPS !#%'*,.1357:;>ABEGIKNPR  #$'*+.03479;>@BDGIKMPR  "$')+-02469;=@BDFIKMOR "$&)+-/2468;=?BDFHKMOQ !$&(+-/1468:=?ACFHJMOQ !#&(*,/1368:ABEGIKNP !#%'*+.03479;=@BDFIKMO  "$&)+-/2468;=?ADFHJMO "$&(+-/1468:=?ACEHILN !#&(*,/1358:<>ABEGIKM !#%'*+.03479;=@BDFHKM  #$')+-/2468;=?ACFHJL "$&(+-/1368:ABEGI !$&(*,/13579;=@BDFH !#%'*+-02468;=?ACEG  "$&(+-/1368:<>@BDF  !#&(*,.13479;=?ACF  !#%')+-/2468:<>ABD   "$&(*,/13579;=?AC! !#%'*+-02468:<>AB            ! ፎ ᎏ ᎏߍߍߎߎލލލގގݍݍݍݍݎޏގݍݍݍݍ܍܍܍܍܍܍܍܍܍܍܍܍܍ݎݎݎݎݍݍݍݍގގލލލߎߎߍߍ ᎏ ᎏ ፎ!䎏   "#$&'   !"$%&'   "#$&'(  !"$%&'(  "#$&'((  "#%&'()  !"$%&(()  "#$&'((* !"#%&'()*  !"$%&((*+  "#$&'((*+  "#%&'()*,  !"$%&(()+,  !#$&'((*+,  "#$&'()*,-  "#%&'()*,- !"$%&((*+,-  !"$%'((*+,.  !#$&'()*,-.  "#$&'()*,-.  "#%&'()*,-/  "$%&'()+,-/ !"$%&((*+,./ !"$'((*+,./  !#$%'()*+,.  !#$%'()*+-.  !#$&'()*,-.  !#$&'()*,-.  "#$&'(()*,-.  "#$&'()*,-/0  "#$&'()*,-/0  "#$&'()*,-/0  "#$&'()*,-/0  "#$&'()*,-/0  "#$&'()*,-/0  !#$&'()*,-.0  !#$&'()*,-.0  !#$&'((*,-./  !"$%'((*+-./  !"$%'((*+,./ !"$%&((*+,./  "$%&'()+,-/  "#%&'()*,-/  "#$&'()*,-.  !#$&'()*,-.  !"$%'((*+,. !"$%&((*+,-  "#%&'()*,-  "#$&'()*,-  !#$&'((*+,  !"$%&(()+,  "#%&'()*,  "#$&'((*+  !"$%&((*+ !"#%&'()*  "#$&'((*  !"$%&(()  "#%&'()  "#$&'((  !"$%&'(   "#$&'(   !"$%&'   "#$&'!  !"$%&FHIKMPPRTVY[]_acegikmnprtuwy{|FHKMOPRSUWY[^`bdfhjlnprtuwz|}~HIKNPRTVWXZ\^bdfgikmoqsuxz}~HKMOPSUWY[]]_acgikmnprtwy|~씠IKMPRTVXZ\^`bcefhlnprtuy{~鑡JLOPRUWY[]_aceghjlmqsux{~KMOQTVWZ\^`bdfhjmmoqtvy|LNPRTVY[]_acegikmoprtw{~MOQSVWY\^`bdfhjmnprtux{~MPRTVX[]^acegikmortuwz|~OPRUWY[]`bdfhjlnprtwy|~OQSVWZ\^`begikmoqtuwz|PRTVX[]_acfgilnprtvy{|PRUWY[]`bdfhkmnqsuwy{~QSVWZ\^`begikmprtvx{|~RTVX[]^acfgjlnpruwy{}RTVY[]_bdfhkmoqsuwz|~RUWY[^`bdgikmprtvx{|SVWZ\^`cegilnprtwy{}TVXZ]^acfgjlnpsuwy|~TVY[]_bdfhkmoqtuxz|~TWY[]`bdfikmortvy{}UWY[^`bdgiknprtwy{}UWY\^`begilnpruwy{~TWZ\^`cegjlnpsuwy|~TVX[]_bdfhmnqtvx{~TVY[]_bdfiknqsvy|~⾿UVY[]`befimnrtwz}UVY\]`begimorvx{~VX[]_bdfiknqtwz~VY[]_bdfiknquxz~VY[]_bdfiknqux{VY[]_bdfiknquxz~VX[]_bdfiknqtwz~VX[]_bdfhknqtwz|VX[]_adfhknpsvy{VXZ]_adfhjmpruw{|VWZ]^acfgjmnqtvx{~VWZ\^`cegjlnpsuwy|~UWY\^`begilnpruwz|UWY[^`bdgiknprtx{}TWY[]`bdfikmoruw{~TVY[]_bdfhkmoquw{}TVXZ]^acfgjlnqtwz|SVWZ\^`cegilnqsvz}RUWY[^`bdgikmpsvy|RTVY[]_bdfhkmoruxz~꽾RTVX[]^acfgjlnqswz|~뽾QSVWZ\^`begikmpsux{~PRUWY[]`bdfhkmnqtvy{}PRTVX[]_acfgilnpruwz|}OQSVWZ\^`begikmoqtuwz|~ľOPRUWY[]`bdfhjlnprtwy{|~MPRTVX[]^acegikmortuwy|~MOQSVWY\^`bdfhjmnprtwy{|~LNPRTVY[]_acegikmortuwy{}KMOQTVWZ\^`bdfhjmnprtvxz|~JLOPRUWY[]_acegikmoqsuwy{|~IKMPRTVXZ\^`bdfhjlnprtuwy{}HKMOPSUWY[]_acegikmnprtvxz|~HIKNPRTVWZ\^`bdfgikmoqsuwy{|~ȀFHKMOPRUWY[]^`bdfhjlnprtuwy{|~FHIKMPRTVWY[]_acegikmnprtuwy{|~DFHKMOPRTVXZ\^`bdfgikmoprtvwy{|~                         #   #  "$     ѫݱ 歮𵶷渹׭ڭ򯰱轾ݮ鯯ޯ߯ ߯۰ఱ԰ᰱ䲳䲳䰲ư䰱䰱䰱㱲䱳㱳䱳䱲䱲䱲䱲DZ㱲Ⱳ㱲峴䲳䲳찱ᰱఱఱ߯߯쯯ܮ鮯鮮ڭ٭嬭䬭ҭʫɫϪ(*+,--.01346789:;<=>?@ABCEFGHIN\r|SLMNMLJKJJLLM()*,-.//0234689:;<<>?@ABCEEGHHM[riOLLMNONNMMKJKLMLNOP(*+,-/01223568:;<<=>@ABCDEGGHLYqhNLMNNOONMLKJKKLMMNONPPQ)*,-./123455789;<=>?@ACDEFHIKXnlMKKLMMNOPPONMMKLMNNPPQQRST*+,-/013456799:;<>?@ABCEGHIJUjvOJJKLMNMNOQPONPQRSUVWX*+-./12346789:<=>ABCDEHIJSfSLKKJKLMNNOPRQRQQPPQSSUVWVYYZ[[\+,-.01245679:;<<>>?@CDEGHJP`XLKJKLNOOQRTUUTSUVXZ[Z]^_`+,./01345789:<<=>@@ABCFHILZsdMLKJKMNPQTVXWVWX[]^`_abcd,-./1235678:;<<>?@ACCDEGJThyPNMLJKNPSTWZ[Z\_acefefggh,-/01345689:;<=>@ABCEFFHJ^WMNNOONMLLNPSUY[^_`cfhijiklmnm-./1234678:;<<>?@ACDEGHJRgrMMNNONOONPTVY\`cedfilopopqqrs-./1245689:;<=>@ABCEFGHN`TKLMNOPQSW[^bfijjiknqtuwuvwxy-/01345789;<<>?@ACDEGHIUo`KLKLNNOPQQRSSUTUW\aehnoopnrvx|}{|}./1234678:;<=>?ABCEFGHM`OJKLKLMOOPRTUWWXYZ]bgkotuv{}./1245689:;<=>@ABDEGHISmcJKLMNQSUWYZ\^^`bhmqv{||z}/01345689;<<>?@ACDEGHK\QJKLMMOSUX[]_adeghnuy~/0134678:;<=>@ABCEFGHQflKJKMOPSWZ_cfhkkmou|/1234679:;<=>@ABDEGHIVtXJKJKOQTVY_chlnqstu}/1245689:<<>?@ACDEGHK^NJJKLMOPSV[^cinrvyz}|01345689;<<>?@BCEFGHQfkJJKKLNOPRTUZ_chnty~0134678:;<=>@ABCEFHITqZJJKKLLMOPSTVX\^dimsz0234678:;<=>@ABDEGHJZQJJKKLMMNOPRTVY\`bfgnty1234679:;<=?@ACDEGHL`LJJKKLLMMORTVX\^bfilptz1235689:<<>?@ACDFGHOelJKLMOQUVY^aeilpux|0245689:<<>?@BCEFGIRk`JKLMOQTVY^bgkotx}01245789;<>?ABCEFHITrXJKLNPSVY]bfkqu|濺01345789;<=>?ACEFGIXzSKJKMORUX\afjpuzĽ0134578:;<=>@BCEFHIVuVKLMOQRTWZ`diotz0134578:;<=>@BCEFIJX{SLMNPRTVZ^bgiorw|134678:;<=>@BCEFIIJZRLMNOQSWX\`dhkqu{134678:;<=>@BDEGIJNaQNNOPSTWX[_cgkosx~134678:;<=>@BDFGIKNbPOPQSUXY]aeimqw|134678:;<=>@BDEGIJNaQNNOPSTWX[_cgkotz134678:;<=>@BCEFIJL_PMNOPRUWZ]adimrw|134578:;<=>@ACEFHJL^PMNOQSUW[^bgiorw|134578:;<=>@ACEFHIJZRLMOQRTWZ`eiotz134578:;<<>@ABDFGIJXzSKJKNOSUY\bfkpuz1245689;<<>?ABCEFHITrXJKLMOQTWZ^bgkqu|1245689:<<>?@BCEFGIRk`KLMOPRUWZ^cglptx}1235689:<<>?@ACDFGHPfmKLMNOQSVWZ_afjlpux|1234679:;<=?@ACDEGIMaNLMNOQSVXZ\_cfimptx{ľ0234678:;<=>@ABDEHIK[SMMNNOPQRTVWZ]`bfglpuy0134678:;<=>@ABCFGIKVs\MNNOQRTUVY\^bejnrw|Ǿ01345689;<<>?@BCFGHJShmMNOPQRTUX\`dgkoty|Ź/1245689:<<>?@ACEFHJM`QMNOPQSWZ^aehmqty|/1234679:;<=>@ACEFHJKXvZLMLKMNPSUX[_cfjmquy}/0134678:;<=>@ABDFGHJSgmMLKJKLNPQSVY]`dfjnqvzⓕ/01345689;<<>?@ADEFHIL]RKJKMNPRTWZ^`dgjnru./1245689:;<=>@ABEFHIJTndJKLMOQSUXZ^adgjnru./1234678:;<=>?ABCEFGHM`OJKLNPQSUX[^adfknorv-/01345789;<<>?@ACDEGHIUo` JKMNPQSUX[^`dfhknrwy|}{|}~-./1245689:;<=>@ABCEFGHN`PJKLMNPQSUXZ^loqgkosvvwuwy{|{z-./1234678:;<<>?@ACDEGHITmeKJKLMNPQSUXfikmptknqrqqrsuvut,-/01345689:;<=>@ABCEFGHL]T JKLMNPQS`begjnqikllmkmopn,-./1235678:;<<>?@ACDEGHIRfwM JKLMNP\^kmcgknpghhgfiikkji+,./01345789:<<=>@ABCEFGHJXqb JKLMNghijlqgkncdcbbegfe+,-.01245679:;<<>?@ACDEFGHN^V JKLXefghkmqgj^^_^_aabcba*+-./12346789:<<=>@ABCDEGHIQeQ JKVWcegiknc[ZYZ\]^_^]*+,-/01345679:;<<>?@ABCEFGHITiuN JTVWcfhklbXXVVUWYYZY)*,-./12345789:;<=>?@ACDEFGHJWnlM JTVegi^VUUTTSTUUWVVU(*+,-/01245678:;<<=>@ABCDEGGHLYqhMJTVYZ[]SQPRSR()*,-./12345689:;<<>?@ABCEEGHHM[rhMJTWXY[QQPPONNOQQRRQQ((*+,-/012346789:;<=>?@ABCEFGHIN[qlNJKWXNONLNON'()*,-./01345678:;<<=>@@ACDEFGHIMYnuQJKLMNNOONNMKLM}zwtqnjgeca_][YWTRPNLKIHFCA?}|xtqnjhfdb`^]YWUSQPOMKHFDBAͲ{xtpmkigfdb`\ZXVVTRPNKIHFCAŷ{wrpnmkigea_]\[YWUSPOMKHFDBʽ~yutrpnljfeca`^\ZXVTRPMKIGEC{ywusqoljhfeca_][YWURPOLJHFD~|zxvtromkjhfdb`^\ZWVTQOMKIGC݃¾}{ywtrpomkigeca_][YVTRPNLHFDĿ~|ywusrpnmjhfdb`^\YWVSONKIGE~|zxwutromkigeca^][XUSPNLJIGý}|{ywtrpnljhfdb`\ZXUSQPOLJF~|zwutqomkigca_]ZXWVSQNKIG|{yvtrpnlhfdb_]][XUSPNLJGĿĺ~{ywusomkigedb`\ZXUSQONLIľܿ~|{xtspnlkigca_]ZXVVSQOMJ|zxusrpnjhfdb_^][XVTROMK}zzwuromljffdb_][YVTRPNKɀ{ywuussomjgdb`^[YWURPNL~~}|{yvtqokhec`^\ZWVSQOM}{yusplhfca^]ZXVTQOM}|xtrnjfdb_][YVTROM}zvsokfdb`][YWTQNL{xuplhdb_\ZXUSQOL½}ytplgca_]ZXVSQON|yuplgda`^\ZWVSPO}zurmifca^]ZWVSQO}yurmjfda_]ZXVTQO¾|xuqnifda_][XVTQO}{xtqmifdb_][XVTROĿ|yvspmjfdb_][XVTRO}zwuqolifdb_][YVTRO}{yvtromkifdb_][YVTRO}{yvtromkifdb_][YVTROû}{yvtromkifdb_][XVTROú}{xvtromkhfdb_][XVTROú|{xvtqomkhfda_][XVTQOú|zxutqomjhfda_]ZXVTQOù~|zwusqnmjgfca^]ZWVSQO~|ywuspnljgec`^\ZWVSPO~{ywurpnligeb`^\YWUSPNú}{ywtrpnkigdb`^[YWURPNù}{yvtromkifdb`][YWTRPMķ~|zxutqomkhfdb_][YVTROMú~|ywuspnljgfca^]ZXVTQOMĹ}{ywtrpnligec`^\ZWVSQOMû|{xvtrpmkigdb`^[YWURPNLĺ~|zwusqomkhfdb_][YVTRPNKû}{ywurpnljgfca^][XVTROMKĺ~|{xvtrpmkigeb`^\ZWVSQOMJĻ~{ywusqnmkhfdb`][YWURPNLIڹ|{yvtrpnligfca_][XVTRPMKIĺ~|zwutqomkigeb`^\ZWVSQOMKHĻ~|{ywtrpnljhfdb`][YWURPOLJHĻ~|ywutromkigeca^][XVTRPMKIGֹ~|{ywtrpnmjhfdb`^\YWVSQOMKHFع}{ywutromkigeca_][YVTRPNLIHF׺~|zxvtrpnmjhfdb`^\ZWVTQOMKIGEֹ~|{ywusqomkigeca_][YWURPOLJHFDӻ}{ywutrpnljhfdb`^\ZXVTRPMKIGECѻ~|zxvtrpnmkigeca_][YWUSPOMKHFDBѺ~|{ywusqomkigfdb`^\ZWVTRPNKIHFCAл~|{ywutrpnljhfdb`^][YWURPOMKHFDBAλ~|{ywutrpnmkigeca_][YWVTRPMKIHFCA? ̻~|{ywvtrpomkigfdb`^\ZXVTRPOMKHFDBA>                     (        %          谯建췵  MORTTUT][X__^STSKMRpuaTPONJHFDCBA?><;:98764320.-,++*(('&$PQUVWX`_hfaa^_^_TSTMOPSnxbUOLKIGEECA@><<;:9865320/..-,*)('&%QTWYZZomifca_TSTXOPQRUox`PMKIIGECB@>=<<;:87532110/-,+*(('&TVZ\^hq{wsqnomma__TSTXZPQRSTWlYNLKIGFDA@?>=<;:87544321/.-,*)('&W[^``j~xtrroqona_^TWZ\RSTTUSYiVMKIGECBA@?><;:977654310/-,+*(('[^bcq{yvttrsqon_^WZ\]TTUUSRQ[iTKIGEDCBA@=<<::98764321/.-+*)('`egiy|ywuvtsrqmbg\^_UTSQPPZ`OHGFEDCA?>=<<;:97654210.-,+)(&ejl{~~~yxvutqqhj_`UTSRPPOMdqXJHGFEBA@@>=<<:98754310/.,+)('hnqy~ywttwlmbbUUTTRQPOMLMwfRIHEDCBA@?><<;:8765321/-,*)('otv}xvy|~qeXWTTSQPOMKJJT]IGFEECBA@>=<;:9865430/-,+)*(ty||tZYWUSRPNLJKefQHHGEDCA@?><<;:874320/..-+*({k]\YXTSPNKJIS|`NHGFECBA@>=<;97653221/.,*)(}~m_][WUQMJKIJ`oUIHGEDCA@?><:98755430/-,+)(d`^[WSNLJO`MHGFECB?>=<;::875320/.,,+*jfb_ZUOONNMLKLKKJcmSIHGEBA@?==<;97653211/.-,*瞚}lgc]WSSRQNMNMMLKJQ\KGFDCBA@?<<:987654310/-,*rmhbYYWVSQPPONMLKJK|aMGFFECA?>=<;;:8764310/-,+~ytmfa_][XVUTQONMLKKJII`lVIGEDBA>=<;:9764321/.,+zsihfe`][ZXURPNMLJJIIJN|XIGGEEDBA@?<<:9865421/.-,xqpnjgfb_\WTROMKKJIKzbSJIHGEDB@?<<;98654310.-,|{ytromid_ZWUPMKLKIKLM]tWLKIHFECB?><;:8764310/-,}{xsohd_YVSQNKIJLNNOV^OLKIHEDB@><;:8764320.,+zsnib]XVQMNNOOPPQReRMLIHGDBA>=;:965320/.,+~yqkgb[UUVVTTRRSRrkUNMKIGEC?>=:9865321/.,,}uqhdbb_\[ZXWVUTSgqYPMKHGDB@>=:98865421/.-zusqnkhea_\ZXWUTShqXNLJIFFDA?=<;9865421/.-Ĺ~{wsokfb_]ZYUTSRZ~]ONKIGEDB?=<;:8754310.-ſztplfa^\YXUTSSRW^OMKIGECB?><;:8754310.-ÿ~ysolhd_][YWUUTSSRQQT`OLKHGDCA?=<;:8754310/-ļ{uqlgc_\ZWTSRRQQPOOR`MKJGFDBA?=<;:8764310/-|vqlhd`[XWSRONMP`MJHFEDB@>=<;:8764310/-}ysnhd`\XTQPMLJL_KHGEDCA@>=<;:8764310/-}ysmhd`\XTQPMLJM^KHGEDCA@>=<;:8764310/-|xrmhd_[WTQPMKJM]JHGEDBA@>=<;:8764310/-{wqmgd_[WSQOMKJN\JHGEDBA@>=<;:8754310/-{vqlgc_ZWSQOMKJPYIHGEDBA@>=<;:8754310.-~ytpkfb^YVSQNMKJRyWIHFECBA@><<;:8754310.-}ytnjea]YUSPNLKJXrTIHFECBA?><<;9865421/.-{wqmhd`\XTRPNLKJ`kRIGFECB@?><<:9865421/.-~ytpkfc_ZWSQPMLJleOHGFDCA@?><<:9865321/.,{xsniea]YVSQOMKJL`LHGEDCA@?=<;:9764321/.,~yuplgd_\XURPNLKJQZJHGEDBA@>=<;:8764320/-,{wrnjeb^ZVSQPMLJZqTIHFECBA@>=<;:8764310/-,|ytokgd`\XUSPNMKJkfQHGFECB@?><<;98654310.-,}ztqmhea^ZWSQPNLKJN^KHGEDCA@?><<:9865421/.-,|zvrmjfc_[XUSPNMKJXtVIHGEDBA@>=<;:9764321/.,+|yurokfd`]YVSQPNLKJKlfQHGFECBA@>=<;:8764310/-,+~{ytqnjhd`^ZWTRPNMKJQ\KHGEDCA@?><<;98654310/-,*~{ywtqmjgda^ZXUSQOMLKJcmSIHGEDBA@>=<;:9865421/.-,*~}{yxuromjfda^[XUSQPNLKJO`MHGFECBA?>=<;:8764321/.,+*|{{yywtspnkhfd`^[XUSQPNMK J`oUIHGEDCA@?><<;98754310/-,+)xwvttqpnljgec`^ZXUSQPNMLKJP`NHGFECBA@>=<;:9865421/.-,*)rqqpnmkigeda_]ZXUSQPNMLKJKemTIHGEDCA@?><<;:8764321/.-+*(mmlkjhfedb`^[YWUSQPNMLK JT]LHGFECBA@>=<;:98654310/-,+*(hggfedca_^\ZXVTSQPNMLK JMwfRIHGEDCA@?><<;:8765321/.-,*)(ddcba`_]\ZXWUSRQPNMLK JbqXJHGFECBA@>=<<:98754310/.,+*((_^]\ZYXVUSSQPONMLK JV^NHGFEDCA@?><<;:97654210.-,+)(([[ZYYXWVUSSQPPNMLKK JQeQIHGEDCBA@>=<<:98764321/.-+*)('WVUTSSRQPPNNMLK JNuiTIHGFECBA@?><<;:97654310/-,+*(('TSRQQPPNNMLKK JMlnWJHGFEDCA@?>=<;:98754321/.-,*)('&QPONMMLKK JMhqYLHGGEDCBA@>=<<;:87654210/-,+*(('&POONMLK JMhr[MHHGEECBA@?><<;:98654321/.-,*)('&%MLKJNlq[NIHGFECBA@?>=<;:987643210/-,+*(('&$KJQunYMIHGFEDCA@@>=<<;:87654310/.-,*)('&%$=;97531/,*(&$"  ><:8642/-+)'#! ?=;97431.,(&$"  @><:8630-+)'%"  A?=;8520.,*'%%#! B@<:7531/,,*(&"  A?<:96441/-)'%"  A@>;;8640.,*'%#! CB@=;8531/,*(&&#! EB?=:96420--+(&$" DA@>;97542/-+)'$#  EC@>=;97430.+*'%#! EBA><:8531/,*(&#! HECA?=:8641/-+(&$" HFDA?=;8642/-+)&$"  IFDB@=;97430.+*'%#! IGEBA>;:7531.,*(%#! IHECA?<:8631/,*(&#! JHFCA?=:8641/-+($"  KHFDB?=;8620.,)'%"  KIFD@><97530.,)'%#  JGECA><:7531.,*''$#  JHECA?<::7531.,*'%#! LIHECA><:8531.,*(%#! LJHFCA?<:8631/,*(&#! MJHFCA?=:8631/-*(&#! MJHFDA?=:8641/-*(&#! MKHFDA?=:8641/-*(&$! MKHFDA?=;8641/-+(&$! MKHFDB?=;8641/-+(&$! MKHFDB?=;8641/-+(&$! MKHFDB?=;8642/-+(&$! MKHFDB?=;8641/-+(&$! MKHFDB?=;8641/-+(&$! MKHFDA?=;8641/-+(&$! MKHFDA?=:8641/-*(&$! MJHFDA?=:8641/-*(&#! MJHFCA?=:8631/-*(&#! LJHFCA?<:8631/,*(&#! LIHECA><:8531.,*(%#! KIGEBA>;:7531.,*'%#! KIGDB@>;97430.+*'$#  KIFDB@=;96420-+)'$"  KHFDB?=;8642/-+)&$" JHFCA?=:8641/-+(&$! IHECA?<:8631/,*(&#! IGEBA>;:7531.,*(%#! IFDB@=;97430.+*'%#! HFDA?=;8642/-+)&$"  HECA?=:8641/-+(&$" GEBA><:8531/,*(&#! FDB@=;97430.+*'%#! FCA?=;8642/-+)'$#  EBA?<:8631/-+(&$" DB@=;:7531.,*(&#! CA?=;86420-+*'%#! BA><:8641/-+(&$"  B@=;97531/,*(&$! A?=;86420-+*'%#! @><:8631/-+(&$"  ?=;97431.,*(&#! ><:8642/-+)'%#! =;97531/,*(&$"  <:86420-+*'%#!                             䦥姦姦򨧦㩧驨䦥䨦⪩ᩨ᪩姦ᬪᬫଫᬫ婧᭬᭬꭬򬫪񜛚ଫ߮߮߮߮߮߮߮߮߮߮߮߮߮߮߮߮߮୬୬୬୬୬䩧ଫଫᬫᬪ᫪᫪᫪⪩⪩⪩䧦㩨㩧㨧䧦䧦䦥妥#"  $"!  $#"  %$"!  &$#"  &%"! %$"!  %$#!"  &%#" (&$#!  '%$#!  '&%##"  (&%$"!  ('&$#!  )('&$#"  )('&%#"  *((&%$"! *(('%$"!  *)('&$#!  *)('&$#"  *)('%#"  )((&%#"! )((&%$"!! +*(('%$"!  +*(('%$"!  ,*(('&$#!  ,*)('&$#!  ,*)('&$#!  ,*)('&$#"  ,*)('&$#"  ,*)('&$#"  ,*)('&$#"  ,*)('&$#"  ,*)('&$#"  ,*)('&$#"  ,*)('&$#!  ,*)('&$#!  ,*(('&$#!  +*(('%$"!  +*(('%$"!  +*((&%$"! +)('&%$"  *)('&%#"  *)('&$#"  *)('&$#!  *(('%$"!  *((&%$"! )('&%#"  )('&$#"  ('&$#!  (&%$"!  ('&%#"  ('&$#"  (&%$"!  '&%#"! '&$#"  &%$"!  &%#"  &$#"  %$"!  $#"  $"!  #"  "!  !  "$&(+-/13579;=?A! !#&(*+.02468:<>A" !#$&)+-/13579;=?" !$&(*,.02468:<>" !#$')+-/13579;=# !$&(*+.02468:;# !#$&)+-/13468;$ !$&(*+-/1368:$ !#$&(*,.13468% !#%')+-/1357%  "$&(*,.0246& !#%')+-/134&  "$&(*+-/13' !#$&(*,.01' !#%')+-.0(  "$&(*+-/( !#$&(*+-) !#$&(*,)  !#%')+*  "$&')+ !#$&(+ !#$&, !#$-  !#-  ".  / 0 0 1 2 3 4 5 6 6 7 8 9 ; <=>@! ! " " " # #$$%%&&''(())*++,--./001 2 3 4 5 66789;<=>@!⎏!"㎏"㍏"㍎##䍎$$华%掏%捎&玏&'莏'荎((퍎)ꎏ)ꍎ*덎+쎏+썎,퍎--./0񎏏0񍎏1򍎏2󍎏3􍎏4566789;<=>@!  "#$&!  !"$%"  "#$"  !"$"  "##  !"#  "$  !$  % % & & ' ' ( ( ) ) * + + , - - . / 0 0 1 2 3 4 5 6 6 789;<=>@CFHIKMOQSUWY[]^`bdfhjlmoqstvwy{|~BDFHJLNPRTVWY[]_acegijlnoqstvwy{|~ACEGIKMOQSTVXZ\^`bdegiklnpqstvwy{|~@BDFHILNPRSUWY[]^`bdfgikmnpqstvwy{|}~̶?ABEGIKMOPRTVWY[]^`bdfgikmnpqstuwyz{|~б=@BDFHIKMOPRTVXZ[]_abdfgikmnoqrtuwxy{|}~=?ABDFHIKMOQSUVXZ\]_abdfgiklnoprtuvwyz{|;=?ACEFHJLNPRSUWYZ\^_abdfgiklmoprstuwxy{~:<>@BCEGIKMOPRTVWY[\^_abdfgijlmnpqrtuvwz|9;=?@BDFHIKMOPRTVWY[\^_abdfgijkmnoprstuyz~8:;=?ABDFHIKMOPRTVWY[\^_abdeghiklmnpqruwy|} 68:;=?ACDFHJKMOPRTVWY[\]_`bdefgijkmnoqtuxy{}~}}~468:<>@ACEGHJLMOQRTVWYZ\]^`bcdfghiklmprtwxz{}~~}~~||{|}3579;=>@BDEGIJLMOQRTVWYZ[]^`abdefgijloprtvxy{{|{zyz{2468:;=?ABDFGIJLMOPRTVWXZ[]^_`bcdfghjlnqrtuwyyxyyxwuvwxy13468:;=?ABDFGIJLMOPRTUVXY[\]^`abdegiklnprtuuvutuv/13468:;=?ABDFGIJLMOPRSUVWYZ[]^_`bcegijmnpqststsrqrst./13568:;=?ABDFGIJKMOPRSTVWXY[\]^`bcegijlnopqpqqpqopqr,.023578:;=?ABDFGHJKMOPQRTUVWYZ[]^`aceghjkmmnonnmno+-.024578:<=?ABDEGHIKMNOPRSTVWXY[\^`acdfhijkklkjklm*+-/024578:;=?ABDEFHIKLMOPRSTUVWYZ\^_abdfghijiihghijk(*+-/124578:;=?ABCDFHIJKMOPQpqrtWWZ\]^`abefefghi&(*+-/124578:;=?@ACDFGHIKMNOooprsVWY[\]_abccddcdef%&(*+-/124578:;=>@ABDEFHIKLMmnoppTUWXY[[^^_`a`abcd#%&(*+-/124568:;=>?ABCEFHIIKklnooRSTVWXYZ[\]]^_^_`ab"#%'(*+-/023568:;<=?@BCDFGHIJjllOPPRRTUWXYYZ[\[\]^_ "#%'(*+-/0234689:;=?@ABDEFGHIKKMNOPPQRSUVWWXYZ[\] "#%&(*+-.0134678:;=>?ABBDEFHHIKKMMOOPQRRSTUVWXYZ[ "#%&(*+-./134568:;<=?@ABCDFFHHIKKLMNOPPQRRSTTUVWXY "#%&(*+,./1234689:;==?@ABCDFFHHIJKLMMOOPPQRSTUV "#$&()+,-/0134678:;;=>?AABCDFFGHIIKKLMMNOOPPQQRST !#$&')*+-.01345688:;<=>?AABCDEFGHHIJKKLMMNNOPQR !#$&'(*+-./12346689:;<=>?AABCDEFFGHHIIJKKLMNO!#$%&(*+,-/013346789:;<=>?@ABBCDEFFGHHIJKLM!"#$&()*+-./113456789:;<=>?@AABBCDEEFFGHIJK !#$&'(*+,-./123456789:;<==>?@AABBCDDEEFG H !#$%&()*+,-/0123456789:;;<==??@ABCDEF!"#$&'()*+-./01234567889:;;<==>??@ABCD  !#$%&'(*++-./01234466788::;;<=>?@AB !"#JKK()*+,-./0123345667889::;<=>?  GHIJ&&()*++--//112344566789:;<= FFGI$$&'()*++,-./011233445667789:; F!!#$$&&((**+,--//0112334567 8 !!#$$&&'()*++,--.//01123456 !!##$%&'((**++,--./01234 !!"#$%&&'((**+,--../0121  !"##$%&&'(()**+,-./  !!"#$$%&&''(()*+,-  !!"##$$%&'()*+  !!"#$%&' (   !!""#$%&   !"#$   !            !     $ (          !#&..-+*)('%$"! "#&* 4 3 2 1/.,*)'%#! !"%(, 7 5 4 20.,*(&# !$(ʪЩ鲳Ϩڧ榨齾岳ԥ ϥ㦧콾ɤ 룤֢⢣̡롢ꠡ岳롢矠 枟矠ڟ矠 䟠矠 񦧨 򟠡럠 🠡󕖖 򔕖 񔕖 󑒒 ꐑ  퓔 􎏏󗘘 덎  򍎏        !$ ('((*+,-./12345689:;<<>>@ABCDEFGHHLWiVJKLMNONMLKJJKKLLKKJ&'()*+,-/012346789:;<<>?@ABCDEFGHHJTebMJKLLMNOONNMLJKJ&'(()*,-./01345678::;<=>?@ABCDEFGGHIQ^qwTKJKLMMNONNMLKJKJ%&'((*+,-//12345688:;<<=>?@ABCDEEGGHINXfeQKLMNNONNMLKJKJ$%&(()*,--/012346689:;<<=>?@ABCCEEFGHHJR]maQMNMLKJKJ#%&'((*+,-./013446789:;<<=>?@AABCDEFGGHILUapfTONMMLK J#$%&'()*+,-./113456789:;<<=>?@@ABCDEEFGHHJOWboo[QLLK J"#$&'(()*+,-//123456789:;<<=>>@@ABCCDEFGGIJKPV_ivm[RL J!"$%&'(()*,--/0123456789:;<>?@AABCDEEGHIJKLOTY`hrl`XRPNMMLM "#$%&'((*+,-./0123456789:;;<<=>?@@ABCCEFFHIJKLMSUZ`ekry !"#$%&'()*+,-./0123456789::;<<=>>?@AABDDFGGIJIJJLORTWY\]^_^ !"#$&''()*+,-./0123456788::;<=>?@@ABCEEFHIHIHIJK !"$%&'(()*+,-./01234566889:;;<<=>>?AABCDEFGFGGFGFGH "#$%&'(()*+,-./01234466789::;<=>?@ABCCEDEEFEFEFG !"#$%&'(()*+,-./012344567889:;;<>??ABBCDCDDCDE !"#$%&'(()*+,-./011334566789::;<=>@@AABCD !"#$%&'(()*+,-.//112344567889::<=>?@A@ABC !"#$%&'(()*+,--//0123345667899;;<<=>>?>?@?@A !"#$%&'(()*+,--./0112344567789:;;<=>?@ !"#$%&'(()*+,,-.//0123345567799:;;<=<= > !"#$%&'(()**+,--//01123445668899::;;<<;<= !"#$%&''(()*+,--.668922344557789:; < !"#$%&''(()*+,,-45689123344567789:; !"#$%&&'(()**+,34566011223344556789: !"#$$%&'()**23445//012334567 8 !""#$%&''()*233--.//001122334567 !"#$%&&'()**+,,--..//0123456 !"#$$%&&'()**+,,--../01234 !""#$%%&''()**++,,--../0123 !"##$%&&''()**++,,-./0 1 !""#$$%&&''()*+,-./0 !""#$$%&&''()*+,-./  !""#$$%&&''()*+,-  !""#$$%&'()*+,  !""#$$%%&'() *  !""##$$%%&' ()  !"#$%&' (  !"#$%& '  !"#$%&  !"# $  !"#  !"                                               !$ (  ʺ~|{ywvtsqomljhfdb`^][YWUSQOMKIHFCA?=Ż~|{ywvtsqonljigeca_][YWVTRPNLJHFDBA><~|{ywvtsqpnlkigedb`^\ZXVTSQOMKIGECA?=;~}|{ywvtsqpnmkigfdb`^][YWUSRPNLIHFDB@><:~|{zywutsqpnmkigfdb`^][YWVTRPOMKIGEBA?=;9~}|{yxwutrqonmkigfdba_][ZXVTRPOMKIHFDB@=;:8󥤣~|{zywvutrponlkigfdba_]\ZXVUSQOMKIHFDBA?=;86~||{yxwutsrpomlkigfdba_^\ZYWUSRPNLJHFECA?=;:86~|{yywvutrqpnmljigfdba_^\[YWVTRPOMKIGECB@><:864~}|{{zywwutsrponmkjigfdba_^\[YWVTRPOMKIHFDB@?=;9753~~}||{{yywwuttrqpnmlkihgedba_^\[YWVTRPOMKIHFDBA?=;:8642~}|{zyxwvuttrrponmkjigfedb`_]\[YWVTRPOMKJHFDCA?=;:86431}}|{zyyxwwvuttrrponmlkihgfdcb`^]\ZYWVTRQOMLJHGECA@><:86431/{zyxwwvuutsrqponmmkjigfedba`^][ZYWVTRQOMLJIGEDB@>=;975310.yxwvuuttsrrqponmmkjihgfdcb`_^][ZXWVTRPOMLJIGFDBA?=;:86420.-vutsrrqppnnmlkjihgfedba`^]\[YXVUTRPOMLJIGFDBA?=;:86431/-+tsrqponmmlkjihgfedcb`_^][ZYWVUSRPOMLJIGFDBA?=;:86431/-+*rrqponmlkkiihgfedcba`^]\[YXWVTSRPOMKJIGFDBA?=;:86531/.,*(onmlkjihggfedcba`_^][ZYWVUTRQPOMKJHGFDBA?=;:875320.,+)'mlkjiihggffedcba`_^]\[YXWVTSRPONMKIHGEDBA?=<:875420.-+)'&kjihgfedcbba`_^]\[ZYWVUTSRPOMLKIHFEDBA?=;:875420/-+*(&$ihgfeddcbba``^^]\[ZYWWVTSRQPOMKJIHFDCBA?=;:875421/-+*(&$#fedcba``_^]]\[ZYXWVUTRQPONMKIHGFDCA@?=;:875421/-+*(&$#!dcba``_^^]]\[[YYWWVUTRRPONMLKIHFEDBA@>=;:875421/-+*(&%#! bba`_^]\[[ZYXWVVUTSRPPOMLKIIHFECBA?>=;:865421/-+*(&%#" _^]\[ZYXWWVVTTRRPPOMMKJIHGFDCB@?=<;:865320/-+*('%#" ]\[ZYXWWVVUTSRQPPONMKKIHGFEDBA@?=;:9864320/-+*('%#" [ZYXWWVUTSRRQPOOMMKKIHHFEDBBA?>=;:8764310.-+*(&%#" XWVUTTSRRQPPONMLKKIHHFFDCBA@?=<;:865431/.-+*(&%#" VUTSRQPPOOMMLKJIHHFFDCBA@?==;:9864321/.,+*(&%#" TSRQPONMMLKKIIHGFFDCBAA?>=;;:8764310/-,+)(&$#" RRQPONMLKKJIHHGFEDCBAA?>=<;:88654310.-+*)'&$#! ONMLKKJIIHHGFFEDCBAA?>=<;:98664321/.-+*('&$#! MLKJIHGFFEDCBBA@?>=<;:987643310/-,+*(&%$#!KJIHGFFEEDCBBAA@?>=<;:987654311/.-+*)(&$#"!HGFEDCBBAA@?>==<;:987654321/.-,+*('&$#!  FEDCBA@??==<;;:9876543210/-,+*)(&%$#!  DCBA@??>==<;;:98876543210/.-+*)('&$#"! BA@?>=<;;::88766443210/.-++*('&%$#!  ?>=<;:9887665433210/.-,+*)(&%$#"! =<;:987665443211//--++*)(&&$#"!  ;;:9876544332110/.-,++*)('&$$#!  8765432110//--,+**((&&$$#!! 65432110//.--,++*)('&&$$#!! 43210/.--,++**(('&%$##!! 10/.-,+*('&&%$#"!! /.-,+*)(('&&%$##"!  -,+*)((''&&%$$#"!!  +*)('&%$$##"!!   ('&%$#"!!   &%$#"!   $#"!   !               !    $  '+      !#&++*('&%$"! "# & * 1 0/.,+)'&$"  !"%(, 4 2 1 /-+)'%# !$'+ 򰯮㻺ᄑ񰯮־޻׾泲ۺ޷ֻ谯尯氯 训㰯簯ꮭ 뭬뭬񩨧 񨧦 󜛚𝜜읜윛𙘘睜 񕔔뙘           !$ ' +JViWLHHGFEDCBA@>><<;:98654321/.-,+*(('&$#JMbeTJHHGFEDCBA@?><<;:987643210/-,+*)('&%$"JKTwq^QIHGGFEDCBA@?>=<;::87654310/.-,*)(('&$#"JPefXNIHGGEEDCBA@?>=<<;:88654321//-,+*(('&%$"!JO`m]RJHHGFEECCBA@?>=<<;:986643210/--,*)((&%$#" JKQco`TLIHGGFEDCBAA@?>=<<;:987644310/.-,+*(('&%#"! JNXlm`UNIHHGFEEDCBA@@?>=<<;:987654311/.-,+*)('&%$#" JLQZktf\SMIHHGGFEDCCBA@@>>=<<;:987654321//-,+*)(('&$#"! MNPRX`lqf^VQKIHHGGFEEDCBAA@?>><;:9876543210/--,*)(('&%$"! yrke`ZTQKIHGFEEDCCBA@@?>=<<;;:9876543210/.-,+*(('&%$#" ]\YWTROLJIHGFEEDCCBAA@?>>=<<;::9876543210/.-,+*)('&%$#"! JJIHGFEDCCBAA@@?>=<;::8876543210/.-,+*)(''&$#"! HGFEDCBAA@@?>>=<<;;:98866543210/.-,+*)(('&%$"! GFEDCBA@?>>=<;::98766443210/.-,+*)(('&%$#" EDCBA@?>>=<;:988765443210/.-,+*)(('&%$#"! DCBA@?>=<;::987665433110/.-,+*)(('&%$#"! BA@?>=<;::988765443211//.-,+*)(('&%$#"! A@?>=<;:987665433210//--,+*)(('&%$#"! @?>=<;:9877654432110/.--,+*)(('&%$#"! >=<;:98877655433210//.-,,+*)(('&%$#"! =<;:987654432110//--,+**)(('&%$#"! <;:98766554432210//.--,+*)((''&%$#"! ;:98765432110/.--,,+*)((''&%$#"! :9876543210//.-,,+**)(('&&%$#"! 876543210//.--,+**)('&%$$#"! 76543210/.--,,+*)('&%$#""! 6543210//..--,,+**)('&&%$#"! 43210/.-,+**)('&&%$$#"! 3210/.-,+*)('&%%$#""! 10/.-,+*)('&%$##"!  0/.-,+*)('&%$$#""!  //.-,+*)('&%$$#""!  -,+*)('&%$$#""!  ,+*)('&%$$#""!  *)('&%$#""!  ) ('&%$#"!  ('&%$#"!  '&%$#"!  &%$#"!  $#"!  #"!  ""!                                                         !$'+;97531/-+(&$"  :86420.+*(&#! 97531/-+)&$#! 86420.,*(&$! 7531/-+)'$#! 6420.+*(&$!  431/-+)&$#!  31/-+*(&$! !31.,*(&$#! !1/-+)'%#! "0.,*(&$"  "/-+)'%#! #-+*(&$"  #,*(&$#! $+)'%#! $*(&$"  %(&$#! %&$#! &%#!  &$"  '#! (! ( ) * * + , - - . / 0 1 2 3 3 456  !!""##$$%%&&'(()** + , - - . /01233456礣楤椣椣 顠 !袡!顠"顠"ꠟ##럞$흜$%잝%흜&휛&'(񙘗(𚙘)񙘗*󗖕*򘗖+󗖖,--./01233456"  !            ! ! " " # # $ $ % % & & ' ( ( ) * * + , - -  . / 0 1233456-5-5 - 5 - 5 00 0 0}b>1 bandeira!? "     %$#Fr%%!)A05]u, $$$$    !G&(*+,-../ ~   ?G@ ~}|zyxvvutrqonnlljihffebba__]\[ZXWVUSRQ}|zzxwvutsrqonmkjjhgfecca`_]\[ZYXWUTTRQ~||zxxwutsrqpomlkjhgfedcb``^][[ZXWVTSRQP~}|{zxxwutrqponlljihgfdcba__^\[ZYWVVTSRPO~}}{zywwvttrqonmlkjihfecca`_^]\[YXVVUTRQPO~}|zyxwvutsqponmljihgfedb``^]\[ZXWVUTSRQON~|{zxxwutsrponmljjhgfdcca`_^]\ZYXWUTTSQPOM~|{zyxwvttsqpomlkjihgedcb`_^]\[ZYXVUTSRPONM~}|{zxwwutsqponmlkihffedba__]][ZXXWUTSRPOONL~}{zyxwvttrqpnmlkjihgedcb``^\\[YXWVUSRQPONML }|{{yxwvtsrqponlkjhhgfdcba_^]\ZYXWVUTRR~}|{yyxvutsrqonmlkihgfdcba`_]\[ZXXWVTTRQ~}{zyxwvtsrqpomlkjigfedbb`__]\ZYXWUTTRQP~}|{yxwvutrqpommkjihgfdcb`__]\[ZYWVVTSRQO~~|{zywwuusrqpomlkiigfedcaa_^\[ZYXWUUTSQPO~|{zyxwvtssrpomlkjihgfdcba`_]\[YXWVUTRRQPN~}|{zxxwvtsqqonmljihgfecca`_^]\[YXWUTSRQPNN~}|zyxwvutrqpnnmkjihfedcb``^]\ZZXXVTTSQPONM~}|{zxwvussrqonmljiigedccb`_^\[ZYWWUUSRQPNML~|{zyxwutsrqpomlkihggedbb`_^]\ZZXWVUSRQQONMK }|{zyxwvusrqoonlljihgedcaa_^]\[YXWVUSRQ}|{zywwutrqqonlkkjigeecba`^^][ZYWWUUSRP~|{{yxwuttrqoommkjhhfedbb``^]\[YYWVTSRQP~}{{zxwvutrqqonlkkihgfecba`^^][YYWWUUSRPO~||zywwutsrqpnmlkihgfedba`_^]\[YXWVTSSQPO}}{zyxwvutrqpnnmkjihffdcba_^]\[YYWVUTSQQON~}}{zyxwvtsrqonmlkjhgfeccaa_^][ZYXWVUSRQPOM~||zyxwvttrqpomlkjihgfdcaa__]\[ZXWVUTSQPPNM}|{zywvutsrponmkkjhgfddba`_^\[ZYWVUTSRQOONL~}{zyxwvttsppomlkjigfedcba_^]\ZYYWVUSSQPOMMK ?G@ <PONMLKJHGFDCBA@?>=;:97654321PNMLKJIHFEDCAA?>=;;986654210/.-+*ONMLJIHFFDCBA@?=<;997654320/.-,+*('NMLJJHGFECCB@?>=;:987643210..,+*((&%$NLKJIHFFDCBA?>=<::876543200.-,*)('&%#"MLJIHGFDDCA@?>=<:986543210..,+*)(&%$#! LKJIGFEDCAA@>=;:987654210/.-+*)(&%$$#! KJJHGFDDCA@?==;:987643210.-,*)((&%$"!! KJHHFEDCA@?>=<;98765432//.-++)('%$#"!JIHGEECBA@>=<;987654321/.-,+*)'&%$#!  <PONMLJJHGFEDBA@?=<;:98664321PONLKJHGFEDBAA?><<:987643210/.,+*ONMKKIHGFDCBA??=<;:887543210.-,*)('NMLKIHGFEDCBA?><;;987544210.-,+*)(&%%MKJIGFFDCBA@>><;:88654320/.,+*))'&%##MLJIIGEEDCA@?>=<;986543200.--+))('%$#"!LKJIHFEDCBA@>=<::87654310/.,++)('&%#"! LKIHGFDCBA@?><;:877543210.-,+)('&%$"" KJIGFEDCB@?>=;;:87643210/-,+*)'&%$#"! JIHFFDCBA@>=<;:87654321/.-,*)('&%$#!  <PNLKJIHGFEDBA@?><;:97754320POMLKJIGFEDBB@?>=;;987644320/--+*ONLKJIHFEDDB@@>=<;998654321/.-,+))'OMLKJHGFEDCB@?>=<:987654210..,+*)('&$MLKJIHFEDCAA@?=<;988654210/.-,+))'%$#"MLJIIGFECCA@?>=;:987543100.--+))(&%$#! LKJIHGFDCAA??=;:987653210/-,+*)(&%$#"! LJIHGEECBA@?>=;:886543200..,**('&%$#!!KIIGFEDBA@@><<::96553310/--+*)('%$#"! JIHGFDCBA@?=<;997654320/.-,*)('&%##!  <G "$%&'(()//00000000000000000000000000000000000000000000000000000000000000߀2  "#$$%&'(()**++,,---.../////00񿾼0񾽻0񽼻0󻹸0񼺺0񻺹0񻹸0񺸷0񹸷0񹸶0񸶶0񷵵0򴲲/𶴳/𵴳/4  "#$$%&'(()**++,,---.../////0񿾼0񿾼0񾽻0񽼻0񼻺0񼺹0񼺹0񺹸0񹸷0񹸷0񹷶0񸶵0񷵵0𷵴/𶵳/𵴲/4  "#$$%&'(()**++,,---.../////󾼻0񿾽0񾽼0񾼻0񽼻0񼻻0󹸷0񻺸0񻺸0񺸷0񹸷0񸷶0񸶶0񷶵0𷵴/𶵳/𵴳/GG4 /,*(&$"! p "#$$%&'(()**++,,---...////G/00000000000000///~}|zyxwvutsqqonmlkihffddba__]\[YYXWUTSQQPNMLK}|{zywvutsrqpnmlkjhgfedbb`_^]\ZZXWUUSRQPONMKJ~||{yxwvtssqponlkjiggedcba_^]\[ZYXVUTSRPONMLJJ~|{zywvutsrpoomlkjhgfedca`_]\[ZYXWUUSRQOOMLKII}}|zzxvvusrqpomlljihgfdcaa`^][[ZXWVUSSQPONMKJIH~}|zzxwvutrqqonmkjihgfddba`_]\\ZYXWUTSRQPNMLKJIH~|{{yxwuusrqoomlkjhhfedcb`_^]\ZYXWVUSSQPONMLJIHG~}{{yxwvutrqponmlkihgeecb``_^\[ZXWWUTSRPONMLKJHGFƉ~|{zxwvutsrppomlkjigfecbb`_^]\ZYXWUTSRQOOMMKJIGGF ʃ~||zyxwvutrqpnmlkjihffecba`_^\[ZYWVUTSQPPNMKKJHGFE }|{zxwwutrrpoomlkihgfedca`_^][ZYXVVUSRQPNMLLJHHGED{zywwutssqoonmkjihfedcba`^][[YXWVUTRRPONMLKIIGFECywvutsqppnmlkihgfddba`^^\\ZYXVVTSRQONMLKJHGGEDBusrqonmlkjigfedcb`_^][ZYYWVUTSQPNNMLJIHFFDCBsqponlljihgeecb``_]][YYWVUTSRQONMLKIIGFEDCBpoomlkjihfedba`_^\[[YXWVUSSQPOMLKJHHGEECBAnlkjiggedcba__]\[ZXWWUTRQQONMKKIIGFECBB@lkjigfddba`_^][ZYXWVTSRPPNMLKJHGGEDCBA@jigfedcb`_^]\[ZXXVUTRQQOMLKJIHFFDDBA@?hgeddba`_^\[ZYXVVUSRPPNMLKJHGGEDCA@?>edbba_^]\[ZXWVUSRQPONLLJHGGEDDB@??=cba_^]\[ZYWVVTSRQPNMKJJHGFDDBAA?>=a`_^][ZYXWVTSRQPOMLKJHHGEDCBA@>=<`^\ZZYWWUTRQPPNMLKIHGEEDBA@?><<^]\[YXWUTSRQONMLKIHGFEDCAA?>=<: ]\[ZXXVUTSQPONMKJIHGEDCBA??=<;:![ZYXVVTSQPONMLKJHGFEDCA@?>=<:9"YXWVUSRQPONMKJIGFEECBA?>==;:9"YXVUTSRQONMKKIHGFEDCB@?>=;;98#WVUTRQONMLKJIGFEDCAA?>><;:87$UTSQPONMLJIHGEDCBA@>>=<:986$TSRQPNMLKIIHFEDCB@@>=<;9875%SQPONMKJIHFFDCBA@>==;:9876%RQPNMLKIHGFDDBA@?>=;;:8755&PNNLLJIGGFDDBA@?><;:88654&ONMLKJHGEEDBB@?>=;::87653'MLKJIHFEDCAA?>=<;:876543'MLJIHFEDCBA@?><;:9866432'LKIIGGEDCAA?>=<;:9765321(JIHGFDDBA@?><;:97754310(JHGFEDCB@?><;::87643210(IHFEDCB@@?><;:97653220/)GEDDCA@?>=<;986653210.)FEDCBA@?=<::87653221/.)FDDBA@?>=;:97754321/.-)ECBA@?>=;:987644310/.,)ECBA@>><;:876543200.-,*BA@?>=<:98755331//.,+*BA@>=<;:98654320/.-,**A@?>=<:987543210..,+**A?>=;;:97653310/.-,***@>><;:98754321/.-,**)*?>=<:987654210/--+*)'*?=<;:977543200.-,*))'*>=;::97653210/--+*)(&*=<;:976542110.-++)('&*<;:987543210/-,+))'&%*;:97654310/.-+**('%$*;:986653200/-,+*((&%$*:987643320..,,*)('%%#*:87754310/.-,*)('&$##):987654210..,,*)''%$#"):886543100.-,+*('&%##!)98764321//-,+*((&&$#"!~}|{yxwvutrqqonlljihgfecba`_]\[ZXXWVTSRQONMLJ~~|{zyxvutsrponmlkihgfedca`_^\[[YXVUUSRQPONLLJ~}|zyxwvutsqpommkjihgedcba_^^\ZZYWVUSSQQONMLKJ~}|{yyxvutsqponmlkihhfecba`_^]\ZYXVVTSRQOOMMKJI}|{{yxvvutrqponlkjihfedcb`_^]\ZZYWVUSRQPONMKJIH}|{zxxvutrqponmljihgfedca__^][ZXWWUTSRQPNNLKJIG}|{zyxwuusrqonmmkjiggedba`_^][ZZXWVUTSQPONLLJIHG~}|zyxwvutsqponmljjhgfddba`^^\[ZYWVUTSQQONMLKIHGFƈ~|{zyxvutrrqpnmlkjigfedca`_^]\ZZXVVUSRQPOMLLJIGGE ʂ~}|zyxwvutrqponlkjihffdcba__^\[ZXWWUTRQPPNMKKIHGFE }|{zyxvutsrqoomlkiigfedcb`_^][ZYXVUTSRQONNLKJHHGFD|{yxwuttrqponmkjihfedcba_^][[YYWVUTRRQONLLKJHGFDCxwvutrrponmljihgfecba`_]\[ZYXWUTSQQONMLKJHGGEDButsrqpnnlkjigfedba`_^]\[ZXWVUTRQONNMKJIHGEDDBsqponmljihgfecba__]\[ZYXVUTSRPONMLKJHGFEDCBqpnnlkjhggedcb`_^\\[YXVVUSRQONMMKJHHFFDCA@mlljihffddba`_]\[ZYWWUTSQPPNMKJJHGFDDCA@lkihgfddbb`_^]\ZYXWUUTRPPNMLKJIGFEDBB@?jigfedcaa`^]\[YXXVUTRRPONMKJIHGFDCBA@?hgfedba`^^\\ZYXWUUSRPOOMLKIHGFEDCBA?>edbba_^\[[ZYWVUTSQPONLKJIGGFDCBA?>>cba`^^\[ZXWVUTSRPONMLKIHGFEDBA@?><a`_^][ZZXWVTSRQPNMLLJIHFEDCBA@>=<a`^]\[ZYWVUTRQPONMLJIHGFECBB@?=<<_^][ZYWVVTSRQONNLJJIGFEDBAA?>=<; ]\[YXWVUSSRPONLKKIHGEECBA@?==;:![ZYXVUTSRQPNMLKJHGFEDCAA?><;;:"ZXWVUSRQPOMLLJIHGFDCB@@>==;:9"YXVUTSQPPNMLJIHGFEDCB@?><<::8#WUTSRQPONMKJIHFEDCB@?>=<;:87$UTSRPONLLJJHGFECBA@?==<:976$TSQQPOMMKJIGFECBA@?>=<;9876%RQPOMMLJJHFFDCBA@>><;:8876%RPONMLKJHGFEDCAA@>=;;:8764&ONLKJIGFFDCBA@?=<;:88654&OMLKIHGFDCCB@?>=<:987644'NMKJIHFEDCB@?>=<:9977543'MKJIIGFEDBA@?><;:9875442'LKIIGGECCB@@?=<;98764321(JHGFDCBA@?=<;:88664311(JIGFECBA@?>=<:987653210(IHGFDCBA@?>=;998754211/)GFDDBA@?=<;:98655321/.)FEDCB@??><:997654220/.)FDCBA@?>=;:98755311/.-)EDCBA?>=<::97653310/.-)ECBA??==;:976643210.-,*BA@?>=<;987644210..,+*B@@?><:997654310/.-,+*A@?==;;:87543310.--+**@?>=<;:97653210/.-+*)*@>><;:98654321/.-,+*(*?>=;:987654210/.-,+)(*><;:88754320/.-++)('*>=;:987653210..,+*(('*=<;9986543100.-++)('%*<;;977543200/-,+*)'&%*;987654210/.-++)('&%*;:986543210.-,+*((&%#*;987654210.-,+*)(&&$#*98654311//-,+)('&%$"):987554310/.-+*)'&&$#"):876543210.,,**)'%%#"!)98654321/.-,+*(('%$#!~}|{yxxvussqqonmkkihgfedba`_]][ZYWVUTRQQPNMLK~~|{zyxwuttrqpnmlkjigfedcb`_]]\ZZXWVUTSQPNMLKJ~}{zyxwuusrqqonmlkihffdcba_^]\[ZYWVUSSRPONMLJI}|{zywvutsrppnmljihgfecbb`_^\[ZYWWVUSRQPNMLKJI~}{zyxwvtsrqpomlkihgfedcb`_^]\[YXXVUTRRPONMLJIH~}|{zywvusrqppnmljihgfecba_^]][ZYXVVTSRQPONLKJIH~|{{yxvutsrppommkihhgedcba_^]\ZZXWVUTRQPONLKJIHF~}|{yxwvussrponmljjhgfecb`_^]\[ZYWVUTSRPPNMLKJHGFƈ~}|{zywvutsrppnmlkjigfedca``^]\[YXWVTTRQPONLLJIHGF ʃ~}|{yxwvusrqponlkjihgeedba`^]\[ZXWVUSRQPONMKKJIGFE ~}|{zywvutrrpoomljjigfddca`_^]\[YXWVTSRQPNMLKJIHGED|zzxwutsrqoonmkjihgedcba_^]\[ZYWVUTSQQONMLJJHGFDCxwvutsrponmljjhgfdcba`_^\[ZYXWUTSRPOOMLKJIGFEDBvtsrqpnmlkiigfedca``^][ZYXWVUSRQPOMMLJIHGEDCBrponmkjihffdcba`^^\\ZYWVVTSRQONMLKJHGFECBAponnlkjhgfedbb`_^]\[YXWVUSRQPNNLKJIHGEDCBAnlkjihgedcba`_]\[ZYWVUTRRPOMMLKIHGFECBA@ljihgfecca`_^\[ZYXWVTSRQONNLKJIGGEDBB@?jihffdcaa_^]\[ZXWVUSRQPONMLKJHGFDDCA?>igfedba`_]][ZYXVUTSRQONNLKJIHGEDCA@@>edcb``^\\ZYXWVTSRQPONMLKIHGFECBA@?=ca`_]\[ZXWVUTSRQONMLKIHGFEDCA@?>=b`_^]\[YXWVTSRQPOMMKJIGGFECBA@>=<a__]][ZXWVUTRRPONLLKIHGFDDBB@?><;_^\[ZYWWUUSRPONMLJIHGGEECBA@>=<; ]\ZYXXVUTRQPONMLJIGGEEDCA@>==;:![ZXWWUTSRQONMLJJIGFEDBB@?>=<::"ZXWVTSRQOOMLKJIGGFDCB@??><;99"XWUTSQQONMLKIHGFDDBB@?>=;::8#WVTSRQPNMMKJIHGEDCAA@?><;:97$UTSQQONMLJJHFFECBA@?><;;987$TSRQONMLKJIGFEDCB@?>=<:9876%RPOMLKJJHGFECBA@?><;:9876%RQONMLKJHHFEDBB@?>=<;98764&PNMLLJIGGEDCB@@>><;:88654&ONMLJJHGFECBB@?>=;:976554'NLKJHGFEDCBA?>><;9876543'MKJIHGEECBA@>><;:9865532'LKIIHGEDBBA?>=<:98765321(JIHGFDCBA@?=<;:98654310(JHGFEDBA@?>=;:987653310(IHGFDCBA@?=<;:87754320/)GFECBA@?>=;:98755321/.)FEDCBA?>><;987644320/.)FECBA@?><;:987543200/-)EDCA@?>=<;:97643310/.,)DCBA@?>=;:97654310/.-,*B@?>=<:987643210/--+*BA?>=<;:97654310/.-,**A@?><;:987654200.-,+**@>=<;:87653321/.-+*)*@?><<;987643200/-,+*)*?>=<;987654210/.-+*)(*>=<;:98664321/.-,+)('*>=;;:86653210/--+*)''*=<;987754320/.,,*))'&*<;;98754421/.-,+*)'&%*;97654220/.-,*)('%$*;:987653200.-,+))'&%$*:87553210/.,+*)('&%#*:97654320/.-,+*)'&%$#);987654210.--+*)''%$#")987654320/.-+*)('&$$"!)977653310/--+*('&%$#!9 5 20.,*('&%#"!  !""#$$%%&&'''((()))))**************)))IGFEDBA@?>=;:98764321//.,+*)(&%$#" IHGEDCBA?>=<;:87654221/.-,+)('&$$"!IHFEDBA@?>=;:976653210.-,+))(&%$#!!GFEDCBA?>=<;:97654320/.,+**('&$$"! GFEDBA@?><<:887543110.-,+*)('$$"" FEDCB@?>=<;987643210.-,+*)''&%#"! FDCBA@?=<;:88654211/.-++)('&%#"" ECCA@?>=<;987653210.--+*)('%$#!!DCB@@?=<;:886543*)('&%##" DBA@?><<;987543)'&%$""!CA@?>=<;:97554 '&$##! CA@?=<;:98755 %$"! A@?><<:98764 $#"!A@>><;:97654 "! @?>=;;987544 " @>=<;9876543 !?><;:9865432 >=<;:87644311   =<;:977543200/ ! =<;987543310/."!  <;:88654320/.-,+"!  ;98655321/.-,+*)'$#"!  ;:88654310/.,,*)('&$$"!  :98754320//-,+)('&%$#"! 987654310/.,+*(''&$#"!  98754311/.-,+*('&%##"  86653210.-,+*)(&&$#"  7542210.-,*)('&%$#!  7543200/--+*('&%$"!  654311/.-++)('&$$"!  54310/..,**(''%$#!  420/.-+*)(&%$#"! 4320/.-,+))'&%$"!  4210/.-+*((&%$#!!  3110.-,+*)'&%#"!  21//-,+*)''&$#!  20/--,**(&&%#"!  0.-,+*('&%$""  0/.,+*)('%$#"!  /-,+*)'&$##!  .,+*)''%$#!  .-,+)('&$#"!  -,+*)'&%$#"  -,+)('&%#"!  ,+*)'&%$#!  +*)('&$#"  *('&$##!  )('&&$#"  )('&$$#!  ('&%$#!! ('%%#"  '&%$#!  &%%#"  &%#""  &$#"! $"!  $#!  $"!  #!! "  "       JHGFECCA@?=<<:987653210/-,+*((&&$#"!IHGFDCBA??=<;:97654320/.,,**('&%##" HGFECCB@?>=;;986643210.-,+*)(&%$#!! HGEDCB@?>=;;987654310/.,,**(&%$#"! GEDCBA@?><;:976543210.-,+*)'&%$#" FEDCA@?>=;:987643210..,++)('%$#"! FDCBA@?><;:976543100.-++*)'&%$"! EDBBA?><;;986653210/.,+*)'&&$#" DCBA??>;;:976542+)('&%$"! DCA@?><;:987543)(&%$#! CB@?>=<:997654 '&$#"! CA@>=<<:87764 %$""!B@?>=;:98764 $#" A@?><;:97664 #! @?><;;987643 " ?>=<;:976543 ! ?>=;:9866432 >=<:987653210 !  =;:886543200/ !  =;;:87653210.-"  <;:88654320/.-,+"  <:98764321//.,+*)'$#"!  ;:97654320/--+*)('%$#"!  :97754321/.-,+*(''%$#"  987653310/-,,*)('%$$"! 97754321/.-,+)('&$$#"  8764332//.,+*)'&%$#"  8654320/.,++*)'&$##!  7653210/--+*)(&&$#!! 653320/-,,+)('&$$"!  543210.-,*)('&%##"  4210/--,*)('%$#"  4321/.-,**('&%$"!! 3220/.,+*((&&$#"! 210/.-,+*('&$##!  210/.,+*)(&%$#!  10/.,,+)('%$#"!  1/.-,+*(''%$""!  0/--,+)('%$#"!  /-,+))'&$$#"  /.,+*(''%%#!!  .-,+)('&$##!  -,+*((&%$#!! -++)('&%#"!  ,+*)'&%$#!!  ,*)('&$#"! *)('&%$#!  *)''&$#"! )'%%##!  ('&%$""  ('%$#"!  '&%$#"  '&$#"! %$#!  %$#"  %$"! $#"  #"!  "!  ! !        IHGFEDBB@?>=<:987644210..-+*)(&%%#" IGGEECB@@>=<;:87653310/.-++)('&%##! IHFDDCA@>><<:88754321//.,+)((&%$#! HFEDCAA?>=;;:97644320/.-,*)('%$$"! FDCCA@?>=;:877543210/-,**)'&%$#!!FEDCB@?>=<::87653210/-,+*)(&%$#"!EDDBA@?=<;9887543110.-,*)('&$$"! ECBAA?==;:987543210.--+*)''%%#" ECBA?>=<;:886532*)('&%#"! DCA@?>=<:976543('&%$""!CB@?>=<:997654 '%$#"!BA@?><;:97654 %##" A@?>=;;98765 %#"! A@>><;:97654 #" @?>=;:987543 " @>=<;:877542 ! ?>=<:9876431  >=<;987654210 !  ><;:98654321/. !  =<;98755431//."  <;:976542210.-+*#!  ;:987643210..,+))'$#"!  ;:97754310/.,,*)('&%#"!  :986553210/-,**(''%$#"  :87644310/--+*)('&%#"!  87543200.-+**)'&%$#!  87544210/--+*)'&%$#"!  76543100.,,+)('&%$"!  7644210.-,+*)'&%$#!!  654211/.,,+*('%%#"! 653210.-,+*)'&%$""  43210..-+*)(&%$#"!  43210.-,*))'&%#"!  3210..,+*)''&$#"  20/.,,**('&%##! 21/.-,+*)(&%$#"! 10/-,,+*('&$$"!  0/.-,**((&%$#!! 0/-,+*)(&%$$"!  /.-,+))'&%$"!  /-,,*)'&%$#"  .-,*)('&%$"!  .,+*)'&%$#"  ,*)('&%#"!  ,+*)'&%$#"  +*)(&&$#"! *))'&$#""  *)'&%$#"! )('&$$"!  )(&%$""! ('%%#"!  (&%$""! '%$#"! &$$#"  %$#"!  $#"! $#!  #"!  "!  ! "  !    ))******          \  \******************************************۽۽ۼ00000000000000000000000000000000000000000///..-,+*)'G#𴳲/񱰰.ﳲ.ﲱ.---,,쮭+𩨧+뭬*묫*ꬫ)髪(髪(誩'穨&稧&樦%姦$䦥#壢"⥤!ᥣ ߤޣ~|ݣ~}|{ۢ}|{yyxڡ~}{zyxwuؠ~}|{zxwvuts֠~}{zywwvusrqo՝~}|zyxwvutrqponmlў}|{yywwvtsrqpnnlkjh͝~}|{yywvutrqpnnmkjihfedc ȝ~}|zzywvussrponmljjhgfddca`_]]@}|{zyxvvusrqponlkjiggedcb`_^]\[ZXWVUTR~}|{zxwvussrqonmlkihgfedbb`_^][ZYXWUTSQ~}|{zywwvtsrqpomlkjhgfedca``^]\ZZYWVUSRQ~}|zzxwvussqpomlkjihffdcba`_^\[ZYXWUTSQP~|{zxxwutsrqpnmlkjhgfedbb`_^\\ZYXWVUTRQP~}{zyxwvutrqponlkjihgeedba_^]\ZZYXVUTRRQO~}|{yywwutsrqonmkjiigfdcba`_^][ZYXWVTSRPOO~||{yxwvusrpoomlkjihfedcba`^]\[ZXWVUTRQPOM~}|{zxwvutrqponlkkjigfedba`_^][[YXVVUSQPOOM}}{{ywwutsrqoomlkjihfedca`_^]\[ZXWVTSRQPONL~}|{yxwvttrqpommljihfeecba`_]\[ZYXVUTSQQOOML~|{zyxwvusqqonmlkihgfecbb`_^\\ZYXWUTTRQPONMK~||zyxwvutrqponmkjihgfedb``^]\[ZXXVUTSQPONMLJ}|{zywvutsqponmkjihgfedcb`_^]\ZYXVUTSRQPNMLKJ~|{zyxwuusrqpomlkjihfedcba_^]\[YXWVUTSQQONLKJI~}{{yxwvusrrponllkihgfecba`_]]\ZYXWUTSRQONMLKJI}|{zywvvtsrqonmlkjhhfedcb``^][[YXWVUTRQPONLLJIH𴳲/ﴲ.ﳲ.ﳲ.---ﭬ,,쯭+쮭+뭬*묫*ꫪ)髪(髩(詨'穨&馥&覤%祣$䧦#㦤"⥤!ᤣ ߤ~ޣ}}ݢ~}|zۢ~|{zywڡ~|{{yxwvؠ~}|{zyxvuts֠~}|{zyxwvtsrqpӟ~}|{zxwvtssrpommkџ~~|{zyxvutsqqonmlkjh͞~}|zyxwvtsrqpommkjihgfdc ȝ}|{zxwvutrqponmlkihgfecba`_]\@}|{zyxwvutrqponlkjihffecba_^]\ZYXWVTSR~}|{yyxvutsrponmkkjhgeecba`^]\[ZYXVVTSR~}}|zxwwvusrqpomlkihgfedca`_^]\ZYYWUUTSQ~}|{zywvusrqponmljihgfdcba`_]][ZYXVUTSRP~|{zyxvuusrqpnmlkjhgfedcaa_^][[YXWUUTRQP}}|zyxwvttsqponmkjihgfecba`_]\[YXWVUTSRQO}|{zywvutsrponmkkihgfecca`_]]\[YXVUTSRQOO~}{{yxvutsrqpnmmkjiggedcaa_^]\ZZXWVUSRRQON~}|zzywwttsrponlkjihgfdccb`^]\[[XXVVTSRPPNN~}{zxxvutsrqpnmlkjhggedcb``_]\ZYXWUUSRQPOML~}|zzywuussqponlkjihgfecba`^^\[ZYWVVTRQQOOML}|{zyxvutrqqonmkkjigfecca`_^][[YXWVTTRQPONLK~}{zyxwutsrqpnmmkjhhfedcba`^]\[ZYWVUTSRPONMLK~~|{zxxwutsqponmlkjhgfedca`_^\[ZYXWVTSRQOOMLKI}}{zyxwvttrqpnnlkihggedcba`_]\[YXWVUSRQPONMKKI~}|zzxxvutsrponlkjihffdcca`^]\[ZYWVUTSRPPNMLKJH~||zxxwvusrponmlkjigfedbaa_^]\[YXXVUSSQPONLKJHH𴳲/ﴲ.ﴲ.ﲱ.---,,쮭+쮬+뭬*묫*ꫪ)髪(骩(誩'穨&馤&槦%姦$䦥#壢"⥤!ᤣ ߣ~ޣ~}}ݢ~}{{ۢ~}|{yyxڡ}|{{zxwvڞ~}|{yxxvuts֠~~}{zyxwutsrqpӟ~}|{yxwvttrqpnnmlў~~|{zywwutsqpoonlkji͞~||{yxwvutrqpnmmkjigffdc ȝ~}|{yxwvutsrqonmlkihgfecca`^^]@~}|{yxwutsrqpnnlkjihfeecba`^][[YXWVUTS~}|{yywvutsrqpnmkjihgfecba`_]\[ZXXWUTSR~}{zyxwvutqqonmlkiihfecbaa`^]\[YXWUUSRQ}|zzxwvutsqponlljihffedb``_^\[ZXWVUTRQP}|{zyxwuusrppnmkjjhgfedcb`_]\\[YXWVTTRQP~}{zyxwvussqpomlkjihfeddb``^]\[ZXWVUSSRPP~|{zywvutsrponlkjjhhfedca`_^][ZYXWVTTRPPN~}{zywwvusrqpnnlkjihfedcba`^][[ZYWVUTRQPON~}|{yxwvttsqponmlkjhgfddbb`_^][ZYWVUTSRPOOM~}{{yxwuusrppnmlkihhfedca``^]\[YXWVUTSQPONL~}{{zxwvusrqpommkjihgfecba`_^\[ZXWWUTRRQONML~~|{zywwuusrppnmlkiigfedba`_^][[YXWUUSRQONMLK~}|{yxwvtsrqpnmmljihgfdcb``^]\[YXWVUTRRPONMLJ}|{zywwutsrqonlkkiigeddba`_^][ZYXWUUTRPONNLKJ}}|zyxwvtsrqonmlkjhgfedcb``^^[ZYXWVUTRRPONMLJJ~}|{zywvussrponlkjihgfedba`_^]\ZYXVVTSQPPNMLKJH}|{zyxvutsrqonmlkihgfedba`_^][[ZXWVUSRQPONLKJIH/...---,,++**)(('&&%$#"! !"$%'),.2 7@)87653310/.-,+*('%$$"! (98764320/.-,+*((&%$"!!(87553210/-,+*)''%$#" (7543200.-,+)('&%$#! '87553310/.,+*((&%%#"! '7654310/.-,+)('&%$"! '7543200.-,+)((&%$#!!&8654210/.-,+*(&%$#"! &754321/.-,+*((&%$#! %7653220/--,*)(&%$#"! %654320/.-++))'&$$"! $7653210/.,+*('&%$#" $6532100.,++)('%$#"! #764321/.-,+*((&%$#" "8653210/.,,*)('&$#"! "754321/.-,+))'&%##! !7654310/-,,+)'&%$#"!  7654210/.-++))'&$$"!  765321//-,+))(&%%#! 7654310/.-++*('&$#"! 8655321/.-,+*)'&%$#"!87653210/--,*)('%%#"! 98764320/.-,+*('&%$"" :87653220/.-+*)('&%#"! :97664320/.-,+*('&%$#! ;98654321/.-,+*)('%$#"! <;:87654320/.-,+*('%%##! =;:98754321/.-,+))(&%$#! ?=<;987643310..,,*)('&%#"!  ><;:98654321/.-,**(''%$#"  @?>=;;:87643210/.,+*)('&$#"!  BA?>><;:976543210.-,*)('&%$"!  ECCB@?><<:987543210.-,+*)'&&$#"! GEDCBA??=<;:87654210/.-+*)('&$$#!  KJHGFDCCA@?><<:986643200/.,+))'&%$""! OOMLKJHHFEDBBA@>=<:987654210/.-+*)'&%%#"! QPONLKJIHGFDCBA@?><;:98754321/.-+**('&%$"!! QONMLKJIGGEDCB@?==<;:87553210/-,,*)'&%$#"!  PONMLJIHGEDDBA?>==;998654311/.-,+)('&%##"  ONMLJJHGFEDCA@?==<:987644210.-,+*)'&%%#"! NNLLJHGGEDCBA@>=<;987653220/.-+*)('%%#"!  NMLKIHGEEDBA@>>=;:98654320/.-,+*('&%$#"  MLKJIHFFDCAA?>=;;987654310/--+*)(&%$#"!  MKJIHGFDCCA@?=<;:97754311/.-,**('&%#""  LKJHGFEDBBA?>=;::87553210/.,+*((&%$#"  LJIGFEDCBA@?=<;:97654321/.-,*)('%%#"!  JJIGEECCA@?><<:987653310/-,+*)(&%$#"  JIHFEECBA?>><;:87654211/.,,**('&%$"!  IHFFEDBA@>><<:986653210/-,**)''%$#!  IGFEDCB@?>=;;997653220.-,++)('&$#"!  HGEEDBA??=<<:887543210.-,+*('&$#"!!  GFEDCBA?>=;;987643210/-,+*)('&%#"  GEDCBA@>><;:88664211//-,**('&$#"!  )97653210/.,++)(&&$#"! (87664320//-,+*((&%$#! (87654311..,,*)(&%$#" (8764310//-,*)('&%$#! '87654210/--,*)'&&$#! '76533210.-,**('%$$"! '7543210..-+*)(&%$#! &7654211/.-+*)('&%#"!&654320/.-,+*)'&%$#" %7654210/.-++)(&&$#!! %754220//-,+*((%%##! $7643310.-,,*)(&%$#" $6543110.-++*('%$$"! #754321/..,+*)('%#"" "7644320/.-,*)('%%#"! "7543210..,+*('&%##" !7643210/-,,*)''&%#"! 86543200.-++)('&$$#"  7553210/.,+*)(&%$#"! 8654211/.-,**('&%#"! 8754320//--+*(''%$#"!87653210/--,**('%%$"!97654321/.-,+*('&%$"! 9755321//--+*)''%$#"! :97754321/.-,**('&%$"! ;:98764321/.-,+*)('%$#"! <;:87653210/.-,+)(&&%#"! =;:98765321/.-,**)''%$#!! ?=<:987654310/.,+*)('%$#"!  ?=<;:98754310//-,**('&%#"!  @?>=<;987654210..,+*)''%$#"!  BA@?=<;:97654310/.-,+)('&%$"!  EDBA@?==<:987643210..,+*)(&%$#"! FDCBA?>=<;:88654220/.-+*)('&%$"!  KJHGFEDBA@?==<:97754321//.,+*)'&%$#!  PONLKJIHFFDCA@?>=<;:88654210/.,+*)('%$#"!  QPNNLKJJHGEEDCA??==;:98754221/.-,*)('&%$"!  POOMLKJIHFEDBB@?>=<;98755431//-,+*((&%%#"! PONMKJHHFEDDBA@>><;:97654220/.-++)('&%$#!  ONMKJIHGFECCA@?>=<:986653210..,+*)'&%$#"  OMLKJHHGEDCBA?>><::97654220/.-++)('&%$"! NMKJIHGEEDCA@?><<:987543210.-,+)((&%$#"! MLKJIHFEDCAA?>=<::87643220/.-+*)(&&$#"!  MKKIHFFECBA@>><;:977553110.-,+*)'&$$"!  KKIIGGEDCB@?>=<:987543210/.,,*)(&%$#"  KJIHGFECBA@>=<;:98654320/.-,+*('&%#"!  KIIGFEDCA@?>=<::87643210..-+*('&&$#!  JIGFFECBA@>=<;:88654210/.-,*)('&$#"!  IHGFECBB@?>=;:977643110/-,+*((&%$#!  IGFEDCA@@>=<;:87654210/.-,*)('&%#"!  HGFDCBA@?><;:98664310/.-,*))'&$$"!!  GFEDBB@?>=;::87643210..,+*('&&$#"  GEDCBA@>=<;:88654321/.-,**('&%$"!  )87653210/--,+)('&$$"! (987643210/.,+)('&$$"! (87654210..-+*)('&%#"! (86543200/-,+*('&%$#! '87643220/.,+*)('&$""! '86543210.,+*)('&$#"! '7544310.-,+*)'&%$#!!&7654210/.,,*)('&$##! &6543200..,+*)'&%$#! %7643220/--+*)('%%$"!%754311/.-,**)'&%#"! $7653210/--+*)(&%%#! $644220/.-,+*('&%$"! #7553200/.,+)(('%$#" "7653210/--,+)(&%%#"!"7542200.-,+)('&%##" !7643310/-,,*)('&$#"  76543110.-+*)('&$#"!  643210/--+*)'&&$#" 7654210/.-,+)('&$#"" 8755321//.,+*('&%$#" 97654210/.-+*)(&&%#"! 87643200/-,+))''%$#!!98765331//.,+*((&&$#" 976543200.-+*)('&$#"! ;:98764321//-,+*)'&%$#" <;:98654220/.,,*))'&$$"!<;:98664321/.-,+*)('%$#!!>=;;:97643310/--+*)('&%#"!  ?=<;:98654320/.-,+)((&%$#!! @?>=<:987654210/-,,*)('%$#"! BA@?><;:88754320/.-+*))'&%$#!  ECCA@?><<:98655321//.,+*)(&%$#"! GEDCB@@>=<::87654321/.-,+)('&%##! KIHGFEDBA@?=<;;97754321//.,**((&%$"!  PNNLKJIGFEDCBA?>=<;:97644310/.,,*)('&$#"!  QPOMLLJIHFEEDBA@?==;:88654321/.-,+*)'&%$#!  QONMLKJIGFEDCA@?>=;:987653210/-,+*((&%%#"  PONLKJIHFFECBA@?=<;:98754320/.-,*)(&&%$"!  ONMKKIHGFEDCB@?>=;:986643210.-,+*)'&%$#"  OMMKJHGFEDCAA?>=<;:87654310/--,*)(&%$##!  NMLKIHGFDCBB@>><;:986543210/-,+))'&%#""! MLKIIGFEDCB@?>=<;987654210/.,,*)(&&%#"!  MKJIHGFDCBA@?=<;:987643210/-++*('&%#""  LJJHGFEDCBA@>=<;987653210.-,,*(('%$#"  KJIHGFECBA@>><;:886543200.-++)('&%$""  JJHGEDDCA@?><;::87643210/.,+*)(&%$#"!  JIHFEECBA?>=<;997643310/.-++)('%%#"!  IHGEECBA@?=<;;98654311/.-,**('&%$"!! HGFEDCB@?>=<;:87554310/.-+*)''&$#"!  HGEDDBA??==;:986543200/-,+)((&$$#!  HFEDCA@?>=;::97654310/-,+*)''%$#"  FEDCBA@>>=;998654220//-++))'&%$"! )((('''&&%%$$#""!   !"#$%'(*+-/ 1 48~                                                                                                      *****************************************)))(('&%$#!G}b>1scrot-1.7/man/000077500000000000000000000000001414262464400132755ustar00rootroot00000000000000scrot-1.7/man/create-man.sh000077500000000000000000000015731414262464400156560ustar00rootroot00000000000000#!/bin/bash # Copyright 2015-2020 Joao Eriberto Mota Filho # Create a manpage using txt2man command. Version 2.0, 2020-06-19. # This file is part of txt2man package for Debian. # This script can be used under BSD-3-Clause license. #-------------------------------------------------------- # Don't change the following lines TEST=$(txt2man -h 2> /dev/null) [ "$TEST" ] || { echo -e "\nYou need to install txt2man, from https://github.com/mvertes/txt2man.\n"; exit 1; } function create-man { txt2man -d "$T2M_DATE" -t $T2M_NAME -r $T2M_NAME-$T2M_VERSION -s $T2M_LEVEL -v "$T2M_DESC" $T2M_NAME.txt > $T2M_NAME.$T2M_LEVEL } #-------------------------------------------------------- # Put here all data for your first manpage (in T2M lines) T2M_DATE="09 Nov 2021" T2M_NAME=scrot T2M_VERSION=1.7 T2M_LEVEL=1 T2M_DESC="command line screen capture utility" create-man scrot-1.7/man/scrot.1000066400000000000000000000206301414262464400145120ustar00rootroot00000000000000.\" Text automatically generated by txt2man .TH scrot 1 "09 Nov 2021" "scrot-1.7" "command line screen capture utility" .SH NAME \fBscrot \fP- command line screen capture utility \fB .SH SYNOPSIS .nf .fam C \fBscrot\fP [\fB-bcfhikmopsuvz\fP] [\fB-a\fP \fIX,Y,W,H\fP] [\fB-C\fP \fINAME\fP] [\fB-D\fP \fIDISPLAY\fP] [\fB-d\fP \fISEC\fP] [\fB-e\fP \fICMD\fP] [\fB-F\fP \fIFILE\fP] [\fB-l\fP \fISTYLE\fP] [\fB-n\fP \fIOPTS\fP] [\fB-q\fP \fINUM\fP] [\fB-S\fP \fICMD\fP] [\fB-t\fP \fINUM\fP | \fIGEOM\fP] [\fIFILE\fP] .fam T .fi .fam T .fi .SH DESCRIPTION \fBscrot\fP (SCReenshOT) is a simple command line screen capture utility, it uses imlib2 to grab and save images. .PP \fBscrot\fP has many useful features: .RS .IP \(bu 3 Support for multiple image formats: JPG, PNG, GIF, and others. .IP \(bu 3 The screenshot's quality is configurable. .IP \(bu 3 It is possible to capture a specific window or a rectangular area on the screen. .RE .PP Because \fBscrot\fP is a command line utility, it can easily be scripted and put to novel uses. For instance, \fBscrot\fP can be used to monitor an X server in absence. .PP \fBscrot\fP is free software under the MIT-advertising license. .SH OPTIONS .TP .B \fB-a\fP, \fB--autoselect\fP \fIX,Y,W,H\fP Non-interactively choose a rectangle starting at position X,Y and of W by H resolution. .TP .B \fB-b\fP, \fB--border\fP When selecting a window, grab the WM's border too. Use with \fB-s\fP to raise the focus of the window. .TP .B \fB-C\fP, \fB--class\fP \fINAME\fP \fINAME\fP is a window class name. Associative with \fB-k\fP. .TP .B \fB-c\fP, \fB--count\fP Display a countdown when used with \fB-d\fP. .TP .B \fB-D\fP, \fB--display\fP \fIDISPLAY\fP \fIDISPLAY\fP is the display to use; see \fBX\fP(7). .TP .B \fB-d\fP, \fB--delay\fP \fISEC\fP Wait \fISEC\fP seconds before taking a shot. .TP .B \fB-e\fP, \fB--exec\fP \fICMD\fP Execute \fICMD\fP on the saved image. .TP .B \fB-F\fP, \fB--file\fP File name. See SPECIAL STRINGS. .TP .B \fB-f\fP, \fB--freeze\fP Freeze the screen when \fB-s\fP is used. .TP .B \fB-h\fP, \fB--help\fP Display help and exit. .TP .B \fB-i\fP, \fB--ignorekeyboard\fP Don't exit for keyboard input. ESC still exits. .TP .B \fB-k\fP, \fB--stack\fP OPT Capture stack/overlapped windows and join them. A running Composite Manager is needed. OPT it's optional join letter: v/h (vertical/horizontal). Default: h .TP .B \fB-l\fP, \fB--line\fP \fISTYLE\fP \fISTYLE\fP indicates the style of the line when the \fB-s\fP option is used; see SELECTION \fISTYLE\fP. .TP .B \fB-m\fP, \fB--multidisp\fP For multiple heads, screenshot all of them in order. .TP .B \fB-n\fP, \fB--note\fP \fIOPTS\fP \fIOPTS\fP is a collection of options which specify notes to bake into the image. See NOTE FORMAT. .TP .B \fB-o\fP, \fB--overwrite\fP By default \fBscrot\fP does not overwrite the output \fIFILE\fP, use this option to enable it. .TP .B \fB-p\fP, \fB--pointer\fP Capture the mouse pointer. .TP .B \fB-q\fP, \fB--quality\fP \fINUM\fP \fINUM\fP must be between 1 and 100. For lossless output formats, a higher value represents better but slower compression. For lossy output formats, a higher value represents higher quality and larger file size. Default: 75. .TP .B \fB-S\fP, \fB--script\fP \fICMD\fP \fICMD\fP is an imlib2 script. .TP .B \fB-s\fP, \fB--select\fP OPT Interactively select a window or rectangle with the mouse, use the arrow keys to resize. See the \fB-l\fP and \fB-f\fP options. OPT it's optional; see SELECTION MODE .TP .B \fB-t\fP, \fB--thumb\fP \fINUM\fP | \fIGEOM\fP Also generate a thumbnail. The argument is the resolution of the thumbnail, it may be a percentage \fINUM\fP or a resolution \fIGEOM\fP. Examples: 10, 25, 320x240, 500x200. .TP .B \fB-u\fP, \fB--focused\fP Use the currently focused window. .TP .B \fB-v\fP, \fB--version\fP Output version information and exit. .TP .B \fB-z\fP, \fB--silent\fP Prevent beeping. .TP .B - Redirection to standard output. The output image format is PNG. .SH SPECIAL STRINGS \fB-e\fP, \fB-F\fP and \fIFILE\fP parameters can take format specifiers that are expanded by \fBscrot\fP when encountered. There are two types of format specifier: Characters preceded by a '%' are interpreted by \fBstrftime\fP(2). The second kind are internal to \fBscrot\fP and are prefixed by '$'. The following specifiers are recognised by \fBscrot\fP: .PP .nf .fam C $$ A literal '$'. $a The system's hostname. $f The image's full path (ignored when used in the filename). $h The image's height. $m The thumbnail's full path (ignored when used in the filename). $n The image's basename (ignored when used in the filename). $p The image's pixel size. $s The image's size in bytes (ignored when used in the filename). $t The image's file format (ignored when used in the filename). $w The image's width. \\n A literal newline (ignored when used in the filename). .fam T .fi Example: .PP .nf .fam C $ scrot '%Y-%m-%d_$wx$h.png' -e 'optipng $f' .fam T .fi This would create a PNG file with a name similar to 2000-10-30_2560x1024.png and optimize it with \fBoptipng\fP(1). .SH SELECTION MODE When using \fB-s\fP, optionally you can indicate the action to perform with the selection area. Some actions allow optional parameters too. .PP .nf .fam C capture Capture the selection area, this action is by default and does not need to be specified. hole Highlight the selected area overshadowing the rest of the capture. hide,IMAGE Hide the selection area by drawing an area of color (or image) over it. Optionally indicate name of the image to use as cover. Image has priority over color. blur,AMOUNT Blurs the selection area. Optionally you can specify the amount of blur. Amount,range: 1..30, default: 18 .fam T .fi In modes 'hole' and 'hide' the color of the area is indicated by 'color' property of the line style and the opacity of the color (or image) is indicated by property 'opacity', SELECTION \fISTYLE\fP .PP If the 'hide' mode uses an image that does not have an alpha channel, the opacity parameter will be ignored and it will be drawn fully opaque. .PP Examples: .PP .nf .fam C $ scrot --select=hide $ scrot -shole --line color="Dark Salmon",opacity=200 $ scrot -sblur,10 $ scrot -shide,stamp.png --line opacity=120 .fam T .fi .SH SELECTION STYLE When using \fB-s\fP, you can indicate the style of the line with \fB-l\fP. .PP \fB-l\fP takes a comma-separated list of specifiers as argument: .PP .nf .fam C style=STYLE STYLE is either "solid" or "dash" without quotes. width=NUM NUM is a pixel count between 1 and 8 inclusive. color="COLOR" Color is a hexadecimal HTML color code or the name of a color. HTML color codes are composed of a pound sign '#' followed by a sequence of 3 2-digit hexadecimal numbers which represent red, green, and blue respectively. Examples: #FF0000 (red), #E0FFFF (light cyan), #000000 (black). opacity=NUM NUM is between 0 and 255 inclusive. 255 means 100% opaque, 0 means 100% transparent. For the opacity of the line this is only effective if a Composite Manager is running. mode=MODE MODE is either "edge" or "classic" without quotes. edge is the new selection, classic uses the old one. "edge" ignores the style specifier and the -f flag, "classic" ignores the opacity specifier. .fam T .fi Without the \fB-l\fP option, a default style is used: .PP .nf .fam C mode=classic,style=solid,width=1,opacity=100 .fam T .fi Example: .PP .nf .fam C $ scrot -l style=dash,width=3,color="red" -s .fam T .fi .SH NOTE FORMAT The \fB-n\fP option's argument is more arguments: .PP .nf .fam C -f 'FontName/size' -t 'text' -x position (optional) -y position (optional) -c color(RGBA, range 0..255) (optional) -a angle (optional) .fam T .fi Example: .PP .nf .fam C $ scrot -n "-f '/usr/share/fonts/TTF/DroidSans-Bold/40' -x 10 -y 20 -c 255,0,0,255 -t 'Hi'" .fam T .fi .SH AUTHOR \fBscrot\fP was originally developed by Tom Gilbert. .PP Currently, source code is maintained by volunteers. Newer versions are available at https://github.com/resurrecting-open-source-projects/\fBscrot\fP scrot-1.7/man/scrot.txt000066400000000000000000000175641414262464400152050ustar00rootroot00000000000000NAME scrot - command line screen capture utility SYNOPSIS scrot [-bcfhikmopsuvz] [-a X,Y,W,H] [-C NAME] [-D DISPLAY] [-d SEC] [-e CMD] [-F FILE] [-l STYLE] [-n OPTS] [-q NUM] [-S CMD] [-t NUM | GEOM] [FILE] DESCRIPTION scrot (SCReenshOT) is a simple command line screen capture utility, it uses imlib2 to grab and save images. scrot has many useful features: - Support for multiple image formats: JPG, PNG, GIF, and others. - The screenshot's quality is configurable. - It is possible to capture a specific window or a rectangular area on the screen. Because scrot is a command line utility, it can easily be scripted and put to novel uses. For instance, scrot can be used to monitor an X server in absence. scrot is free software under the MIT-advertising license. OPTIONS -a, --autoselect X,Y,W,H Non-interactively choose a rectangle starting at position X,Y and of W by H resolution. -b, --border When selecting a window, grab the WM's border too. Use with -s to raise the focus of the window. -C, --class NAME NAME is a window class name. Associative with -k. -c, --count Display a countdown when used with -d. -D, --display DISPLAY DISPLAY is the display to use; see X(7). -d, --delay SEC Wait SEC seconds before taking a shot. -e, --exec CMD Execute CMD on the saved image. -F, --file File name. See SPECIAL STRINGS. -f, --freeze Freeze the screen when -s is used. -h, --help Display help and exit. -i, --ignorekeyboard Don't exit for keyboard input. ESC still exits. -k, --stack OPT Capture stack/overlapped windows and join them. A running Composite Manager is needed. OPT it's optional join letter: v/h (vertical/horizontal). Default: h -l, --line STYLE STYLE indicates the style of the line when the -s option is used; see SELECTION STYLE. -m, --multidisp For multiple heads, screenshot all of them in order. -n, --note OPTS OPTS is a collection of options which specify notes to bake into the image. See NOTE FORMAT. -o, --overwrite By default scrot does not overwrite the output FILE, use this option to enable it. -p, --pointer Capture the mouse pointer. -q, --quality NUM NUM must be between 1 and 100. For lossless output formats, a higher value represents better but slower compression. For lossy output formats, a higher value represents higher quality and larger file size. Default: 75. -S, --script CMD CMD is an imlib2 script. -s, --select OPT Interactively select a window or rectangle with the mouse, use the arrow keys to resize. See the -l and -f options. OPT it's optional; see SELECTION MODE -t, --thumb NUM | GEOM Also generate a thumbnail. The argument is the resolution of the thumbnail, it may be a percentage NUM or a resolution GEOM. Examples: 10, 25, 320x240, 500x200. -u, --focused Use the currently focused window. -v, --version Output version information and exit. -z, --silent Prevent beeping. - Redirection to standard output. The output image format is PNG. SPECIAL STRINGS -e, -F and FILE parameters can take format specifiers that are expanded by scrot when encountered. There are two types of format specifier: Characters preceded by a '%' are interpreted by strftime(2). The second kind are internal to scrot and are prefixed by '$'. The following specifiers are recognised by scrot: $$ A literal '$'. $a The system's hostname. $f The image's full path (ignored when used in the filename). $h The image's height. $m The thumbnail's full path (ignored when used in the filename). $n The image's basename (ignored when used in the filename). $p The image's pixel size. $s The image's size in bytes (ignored when used in the filename). $t The image's file format (ignored when used in the filename). $w The image's width. \\n A literal newline (ignored when used in the filename). Example: $ scrot '%Y-%m-%d_$wx$h.png' -e 'optipng $f' This would create a PNG file with a name similar to 2000-10-30_2560x1024.png and optimize it with optipng(1). SELECTION MODE When using -s, optionally you can indicate the action to perform with the selection area. Some actions allow optional parameters too. capture Capture the selection area, this action is by default and does not need to be specified. hole Highlight the selected area overshadowing the rest of the capture. hide,IMAGE Hide the selection area by drawing an area of color (or image) over it. Optionally indicate name of the image to use as cover. Image has priority over color. blur,AMOUNT Blurs the selection area. Optionally you can specify the amount of blur. Amount,range: 1..30, default: 18 In modes 'hole' and 'hide' the color of the area is indicated by 'color' property of the line style and the opacity of the color (or image) is indicated by property 'opacity', SELECTION STYLE If the 'hide' mode uses an image that does not have an alpha channel, the opacity parameter will be ignored and it will be drawn fully opaque. Examples: $ scrot --select=hide $ scrot -shole --line color="Dark Salmon",opacity=200 $ scrot -sblur,10 $ scrot -shide,stamp.png --line opacity=120 SELECTION STYLE When using -s, you can indicate the style of the line with -l. -l takes a comma-separated list of specifiers as argument: style=STYLE STYLE is either "solid" or "dash" without quotes. width=NUM NUM is a pixel count between 1 and 8 inclusive. color="COLOR" Color is a hexadecimal HTML color code or the name of a color. HTML color codes are composed of a pound sign '#' followed by a sequence of 3 2-digit hexadecimal numbers which represent red, green, and blue respectively. Examples: #FF0000 (red), #E0FFFF (light cyan), #000000 (black). opacity=NUM NUM is between 0 and 255 inclusive. 255 means 100% opaque, 0 means 100% transparent. For the opacity of the line this is only effective if a Composite Manager is running. mode=MODE MODE is either "edge" or "classic" without quotes. edge is the new selection, classic uses the old one. "edge" ignores the style specifier and the -f flag, "classic" ignores the opacity specifier. Without the -l option, a default style is used: mode=classic,style=solid,width=1,opacity=100 Example: $ scrot -l style=dash,width=3,color="red" -s NOTE FORMAT The -n option's argument is more arguments: -f 'FontName/size' -t 'text' -x position (optional) -y position (optional) -c color(RGBA, range 0..255) (optional) -a angle (optional) Example: $ scrot -n "-f '/usr/share/fonts/TTF/DroidSans-Bold/40' -x 10 -y 20 -c 255,0,0,255 -t 'Hi'" AUTHOR scrot was originally developed by Tom Gilbert. Currently, source code is maintained by volunteers. Newer versions are available at https://github.com/resurrecting-open-source-projects/scrot scrot-1.7/src/000077500000000000000000000000001414262464400133115ustar00rootroot00000000000000scrot-1.7/src/Makefile.am000066400000000000000000000040641414262464400153510ustar00rootroot00000000000000# Copyright 1999-2000 Tom Gilbert # Copyright 2016 Joao Eriberto Mota Filho # Copyright 2020-2021 Daniel T. Borelli # Copyright 2020 Jeroen Roovers # Copyright 2021 Christopher R. Nelson # Copyright 2021 Guilherme Janczak # # 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 of the Software and its documentation and acknowledgment shall be # given in the documentation and software packages that this Software was # used. # # 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 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. # A list of all the files in the current directory which can be regenerated MAINTAINERCLEANFILES = Makefile.in # Substitution variables bin_PROGRAMS = scrot scrot_CPPFLAGS = @CPPFLAGS@ scrot_LDADD = @LIBS@ scrot_SOURCES = main.c scrot.h \ options.c options.h imlib.c structs.h note.c note.h \ scrot_selection.c scrot_selection.h \ selection_classic.c selection_classic.h \ selection_edge.c selection_edge.h \ slist.h scrot-1.7/src/imlib.c000066400000000000000000000050731414262464400145560ustar00rootroot00000000000000/* imlib.c Copyright 1999-2000 Tom Gilbert Copyright 2020-2021 Daniel T. Borelli Copyright 2020 ideal Copyright 2020 Sean Brennan Copyright 2021 Christopher R. Nelson Copyright 2021 Peter Wu 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 of the Software and its documentation and acknowledgment shall be given in the documentation and software packages that this Software was used. 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 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. */ #include "options.h" #include "scrot.h" Display* disp = NULL; Visual* vis = NULL; Screen* scr = NULL; Colormap cm; int depth; Window root = 0; void initXAndImlib(char* dispStr, int screenNumber) { disp = XOpenDisplay(dispStr); if (!disp) { char const* const format = "Can't open X display. It *is* running, " "yeah? [%s]"; char const* env = NULL; char const* const value = dispStr ? dispStr : (env = getenv("DISPLAY")) ? env : "NULL"; errx(EXIT_FAILURE, format, value); } if (screenNumber) scr = ScreenOfDisplay(disp, screenNumber); else scr = ScreenOfDisplay(disp, DefaultScreen(disp)); vis = DefaultVisual(disp, XScreenNumberOfScreen(scr)); depth = DefaultDepth(disp, XScreenNumberOfScreen(scr)); cm = DefaultColormap(disp, XScreenNumberOfScreen(scr)); root = RootWindow(disp, XScreenNumberOfScreen(scr)); imlib_context_set_drawable(root); imlib_context_set_display(disp); imlib_context_set_visual(vis); imlib_context_set_colormap(cm); imlib_context_set_color_modifier(NULL); imlib_context_set_operation(IMLIB_OP_COPY); } scrot-1.7/src/main.c000066400000000000000000000564711414262464400144160ustar00rootroot00000000000000/* main.c Copyright 1999-2000 Tom Gilbert Copyright 2009 James Cameron Copyright 2010 Ibragimov Rinat Copyright 2017 Stoney Sauce Copyright 2019-2021 Daniel T. Borelli Copyright 2019 Jade Auer Copyright 2020 blockparole Copyright 2020 Cungsten Tarbide Copyright 2020 Hinigatsu Copyright 2020 nothub Copyright 2020 Sean Brennan Copyright 2021 c0dev0id Copyright 2021 Christopher R. Nelson Copyright 2021 Guilherme Janczak Copyright 2021 IFo Hancroft Copyright 2021 Peter Wu 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 of the Software and its documentation and acknowledgment shall be given in the documentation and software packages that this Software was used. 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 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. */ #include "scrot.h" #include /* atexit register func. */ static void uninitXAndImlib(void) { if (opt.note) scrotNoteFree(); if (disp) { XCloseDisplay(disp); disp = NULL; } } // It assumes that the local variable 'main.c:Imlib_Image image' is in context static void applyFilterIfRequired(void) { if (opt.script) imlib_apply_filter(opt.script); } int main(int argc, char** argv) { Imlib_Image image; Imlib_Image thumbnail; Imlib_Load_Error imErr; char* filenameIM = NULL; char* filenameThumb = NULL; char* haveExtension = NULL; time_t t; struct tm* tm; optionsParse(argc, argv); initXAndImlib(opt.display, 0); atexit(uninitXAndImlib); if (!opt.outputFile) { opt.outputFile = strdup("%Y-%m-%d-%H%M%S_$wx$h_scrot.png"); opt.thumbFile = strdup("%Y-%m-%d-%H%M%S_$wx$h_scrot-thumb.png"); } else { if (opt.thumb) opt.thumbFile = optionsNameThumbnail(opt.outputFile); scrotHaveFileExtension(opt.outputFile, &haveExtension); } if (opt.focused) image = scrotGrabFocused(); else if (opt.selection.mode & SELECTION_MODE_ANY) image = scrotSelectionSelectMode(); else if (opt.autoselect) image = scrotGrabAutoselect(); else { scrotDoDelay(); if (opt.multidisp) image = scrotGrabShotMulti(); else if (opt.stack) image = scrotGrabStackWindows(); else image = scrotGrabShot(); } if (!image) err(EXIT_FAILURE, "no image grabbed"); if (opt.note) scrotNoteDraw(image); time(&t); /* Get the time directly after the screenshot */ tm = localtime(&t); imlib_context_set_image(image); imlib_image_attach_data_value("quality", NULL, opt.quality, NULL); if (!haveExtension) imlib_image_set_format("png"); filenameIM = imPrintf(opt.outputFile, tm, NULL, NULL, image); scrotCheckIfOverwriteFile(&filenameIM); applyFilterIfRequired(); imlib_save_image_with_error_return(filenameIM, &imErr); if (imErr) err(EXIT_FAILURE, "Saving to file %s failed", filenameIM); if (opt.thumb) { int cwidth, cheight; int twidth, theight; cwidth = imlib_image_get_width(); cheight = imlib_image_get_height(); /* Geometry based thumb size */ if (opt.thumbWidth || opt.thumbHeight) { if (!opt.thumbWidth) { twidth = cwidth * opt.thumbHeight / cheight; theight = opt.thumbHeight; } else if (!opt.thumbHeight) { twidth = opt.thumbWidth; theight = cheight * opt.thumbWidth / cwidth; } else { twidth = opt.thumbWidth; theight = opt.thumbHeight; } } else { twidth = cwidth * opt.thumb / 100; theight = cheight * opt.thumb / 100; } imlib_context_set_anti_alias(1); thumbnail = imlib_create_cropped_scaled_image(0, 0, cwidth, cheight, twidth, theight); if (!thumbnail) err(EXIT_FAILURE, "unable to create thumbnail"); else { scrotHaveFileExtension(opt.thumbFile, &haveExtension); imlib_context_set_image(thumbnail); if (!haveExtension) imlib_image_set_format("png"); filenameThumb = imPrintf(opt.thumbFile, tm, NULL, NULL, thumbnail); scrotCheckIfOverwriteFile(&filenameThumb); imlib_save_image_with_error_return(filenameThumb, &imErr); imlib_free_image_and_decache(); if (imErr) err(EXIT_FAILURE, "Saving thumbnail %s failed", filenameThumb); } } if (opt.exec) scrotExecApp(image, tm, filenameIM, filenameThumb); imlib_context_set_image(image); imlib_free_image_and_decache(); return 0; } void scrotDoDelay(void) { if (opt.delay) { if (opt.countdown) { int i; printf("Taking shot in %d.. ", opt.delay); fflush(stdout); sleep(1); for (i = opt.delay - 1; i > 0; i--) { printf("%d.. ", i); fflush(stdout); sleep(1); } printf("0.\n"); fflush(stdout); } else sleep(opt.delay); } } size_t scrotHaveFileExtension(char const* filename, char** ext) { *ext = strrchr(filename, '.'); if (*ext) return strlen(*ext); return 0; } void scrotCheckIfOverwriteFile(char** filename) { if (opt.overwrite) return; if (access(*filename, F_OK) == -1) return; const size_t maxCounter = 999; size_t counter = 0; char* ext = NULL; size_t extLength = 0; const size_t slen = strlen(*filename); size_t nalloc = slen + 4 + 1; // _000 + NUL byte char fmt[5]; char* newName = NULL; extLength = scrotHaveFileExtension(*filename, &ext); if (ext) nalloc += extLength; // .ext newName = calloc(nalloc, sizeof(*newName)); memcpy(newName, *filename, slen); do { char* ptr = newName + slen; snprintf(fmt, sizeof(fmt), "_%03zu", counter++); if(ext) { ptr -= extLength; memcpy(ptr, fmt, sizeof(fmt)); memcpy(ptr + sizeof(fmt) - 1, ext, extLength); } else memcpy(ptr, fmt, sizeof(fmt)); } while ((counter < maxCounter) && !access(newName, F_OK)); assert(newName[nalloc - 1] == '\0'); free(*filename); *filename = newName; if (counter == maxCounter) { errx(EXIT_FAILURE, "scrot can no longer generate new file names.\n" "The last attempt is %s", newName); } } int scrotMatchWindowClassName(Window target) { assert(disp != NULL); const int NOT_MATCH = 0; const int MATCH = 1; /* By default all class names match since windowClassName by default is NULL*/ int retval = MATCH; if (!opt.windowClassName) return retval; XClassHint classHint; retval = NOT_MATCH; // windowClassName != NULL, by default NOT_MATCH if (XGetClassHint(disp, target, &classHint) != BadWindow) { retval = optionsCompareWindowClassName(classHint.res_class); XFree(classHint.res_name); XFree(classHint.res_class); } return retval; } void scrotGrabMousePointer(const Imlib_Image image, const int xOffset, const int yOffset) { XFixesCursorImage* xcim = XFixesGetCursorImage(disp); if (!xcim) { warnx("Failed to get mouse cursor image."); return; } const unsigned short width = xcim->width; const unsigned short height = xcim->height; const int x = (xcim->x - xcim->xhot) - xOffset; const int y = (xcim->y - xcim->yhot) - yOffset; DATA32* pixels = NULL; #ifdef __i386__ pixels = (DATA32*)xcim->pixels; #else DATA32 data[width * height * 4]; unsigned int i; for (i = 0; i < (width * height); i++) data[i] = (DATA32)xcim->pixels[i]; pixels = data; #endif Imlib_Image imcursor = imlib_create_image_using_data(width, height, pixels); XFree(xcim); if (!imcursor) errx(EXIT_FAILURE, "scrotGrabMousePointer: Failed create image using data."); imlib_context_set_image(imcursor); imlib_image_set_has_alpha(1); imlib_context_set_image(image); imlib_blend_image_onto_image(imcursor, 0, 0, 0, width, height, x, y, width, height); imlib_context_set_image(imcursor); imlib_free_image(); } Imlib_Image scrotGrabShot(void) { Imlib_Image im; if (!opt.silent) XBell(disp, 0); im = imlib_create_image_from_drawable(0, 0, 0, scr->width, scr->height, 1); if (opt.pointer) scrotGrabMousePointer(im, 0, 0); return im; } void scrotExecApp(Imlib_Image image, struct tm* tm, char* filenameIM, char* filenameThumb) { char* execStr; int ret; execStr = imPrintf(opt.exec, tm, filenameIM, filenameThumb, image); errno = 0; ret = system(execStr); if (ret == -1) warn("The child process could not be created"); else if (WEXITSTATUS(ret) == 127) warnx("scrot could not execute the command: %s", execStr); exit(0); } Imlib_Image scrotGrabFocused(void) { Imlib_Image im = NULL; int rx = 0, ry = 0, rw = 0, rh = 0; Window target = None; int ignored; scrotDoDelay(); XGetInputFocus(disp, &target, &ignored); if (!scrotGetGeometry(target, &rx, &ry, &rw, &rh)) return NULL; scrotNiceClip(&rx, &ry, &rw, &rh); im = imlib_create_image_from_drawable(0, rx, ry, rw, rh, 1); if (opt.pointer) scrotGrabMousePointer(im, rx, ry); return im; } Imlib_Image scrotGrabAutoselect(void) { Imlib_Image im = NULL; int rx = opt.autoselectX, ry = opt.autoselectY, rw = opt.autoselectW, rh = opt.autoselectH; scrotDoDelay(); scrotNiceClip(&rx, &ry, &rw, &rh); im = imlib_create_image_from_drawable(0, rx, ry, rw, rh, 1); if (opt.pointer) scrotGrabMousePointer(im, rx, ry); return im; } /* Clip rectangle nicely */ void scrotNiceClip(int* rx, int* ry, int* rw, int* rh) { if (*rx < 0) { *rw += *rx; *rx = 0; } if (*ry < 0) { *rh += *ry; *ry = 0; } if ((*rx + *rw) > scr->width) *rw = scr->width - *rx; if ((*ry + *rh) > scr->height) *rh = scr->height - *ry; } static Bool scrotXEventVisibility(Display* dpy, XEvent* ev, XPointer arg) { (void)dpy; // unused Window* win = (Window*)arg; return (ev->xvisibility.window == *win); } /* Get geometry of window and use that */ int scrotGetGeometry(Window target, int* rx, int* ry, int* rw, int* rh) { Window child; XWindowAttributes attr; int stat, frames = 0; /* Get windowmanager frame of window */ if (target != root) { unsigned int d; int x; int status; status = XGetGeometry(disp, target, &root, &x, &x, &d, &d, &d, &d); if (status) { Window rt, *children, parent; XEvent ev; for (;;) { /* Find window manager frame. */ status = XQueryTree(disp, target, &rt, &parent, &children, &d); if (status && (children != None)) XFree(children); if (!status || (parent == None) || (parent == rt)) break; target = parent; ++frames; } /* Get client window. */ if (!opt.border) target = scrotGetClientWindow(disp, target); XRaiseWindow(disp, target); /* Give the WM time to update the hidden area of the window. Some windows never send the event, a time limit is placed. */ XSelectInput(disp, target, FocusChangeMask); struct timespec delay = {0, 10000000L}; // 10ms for (short i = 0; i < 30; ++i) { if (XCheckIfEvent(disp, &ev, &scrotXEventVisibility, (XPointer)&target)) break; nanosleep(&delay, NULL); } } } stat = XGetWindowAttributes(disp, target, &attr); if (!stat || (attr.map_state != IsViewable)) return 0; *rw = attr.width; *rh = attr.height; XTranslateCoordinates(disp, target, root, 0, 0, rx, ry, &child); /* Special case when the TWM emulates the border directly on the window. */ if (opt.border == 1 && frames < 2 && attr.border_width > 0) { *rw += attr.border_width * 2; *rh += attr.border_width * 2; *rx -= attr.border_width; *ry -= attr.border_width; } return 1; } Window scrotGetWindow(Display* display, Window window, int x, int y) { Window source, target; int status, xOffset, yOffset; source = root; target = window; if (window == None) window = root; while (1) { status = XTranslateCoordinates(display, source, window, x, y, &xOffset, &yOffset, &target); if (!status) break; if (target == None) break; source = window; window = target; x = xOffset; y = yOffset; } if (target == None) target = window; return target; } char* imPrintf(char* str, struct tm* tm, char* filenameIM, char* filenameThumb, Imlib_Image im) { char* c; char buf[20]; char ret[4096]; char strf[4096]; char* tmp; struct stat st; ret[0] = '\0'; if (strftime(strf, 4095, str, tm) == 0) errx(EXIT_FAILURE, "strftime returned 0"); imlib_context_set_image(im); for (c = strf; *c != '\0'; c++) { if (*c == '$') { c++; switch (*c) { case 'a': gethostname(buf, sizeof(buf)); strlcat(ret, buf, sizeof(ret)); break; case 'f': if (filenameIM) strlcat(ret, filenameIM, sizeof(ret)); break; case 'm': /* t was already taken, so m as in mini */ if (filenameThumb) strlcat(ret, filenameThumb, sizeof(ret)); break; case 'n': if (filenameIM) { tmp = strrchr(filenameIM, '/'); if (tmp) strlcat(ret, tmp + 1, sizeof(ret)); else strlcat(ret, filenameIM, sizeof(ret)); } break; case 'w': snprintf(buf, sizeof(buf), "%d", imlib_image_get_width()); strlcat(ret, buf, sizeof(ret)); break; case 'h': snprintf(buf, sizeof(buf), "%d", imlib_image_get_height()); strlcat(ret, buf, sizeof(ret)); break; case 's': if (filenameIM) { if (!stat(filenameIM, &st)) { int size; size = st.st_size; snprintf(buf, sizeof(buf), "%d", size); strlcat(ret, buf, sizeof(ret)); } else strlcat(ret, "[err]", sizeof(ret)); } break; case 'p': snprintf(buf, sizeof(buf), "%d", imlib_image_get_width() * imlib_image_get_height()); strlcat(ret, buf, sizeof(ret)); break; case 't': tmp = imlib_image_format(); if (tmp) strlcat(ret, tmp, sizeof(ret)); break; case '$': strlcat(ret, "$", sizeof(ret)); break; default: snprintf(buf, sizeof(buf), "%.1s", c); strlcat(ret, buf, sizeof(ret)); break; } } else if (*c == '\\') { c++; switch (*c) { case 'n': if (filenameIM) strlcat(ret, "\n", sizeof(ret)); break; default: snprintf(buf, sizeof(buf), "%.1s", c); strlcat(ret, buf, sizeof(ret)); break; } } else { const size_t length = strlen(ret); ret[length] = *c; ret[length + 1] = '\0'; } } return strdup(ret); } Window scrotGetClientWindow(Display* display, Window target) { Atom state; Atom type = None; int format, status; unsigned char* data; unsigned long after, items; Window client; state = XInternAtom(display, "WM_STATE", True); if (state == None) return target; status = XGetWindowProperty(display, target, state, 0L, 0L, False, AnyPropertyType, &type, &format, &items, &after, &data); if ((status == Success) && (type != None)) return target; client = scrotFindWindowByProperty(display, target, state); if (!client) return target; return client; } Window scrotFindWindowByProperty(Display* display, const Window window, const Atom property) { Atom type = None; int format, status; unsigned char* data; unsigned int i, numberChildren; unsigned long after, numberItems; Window child = None, *children, parent, rootReturn; status = XQueryTree(display, window, &rootReturn, &parent, &children, &numberChildren); if (!status) return None; for (i = 0; (i < numberChildren) && (child == None); i++) { status = XGetWindowProperty(display, children[i], property, 0L, 0L, False, AnyPropertyType, &type, &format, &numberItems, &after, &data); if (data) XFree(data); if ((status == Success) && type) child = children[i]; } for (i = 0; (i < numberChildren) && (child == None); i++) child = scrotFindWindowByProperty(display, children[i], property); if (children != None) XFree(children); return (child); } Imlib_Image scrotGrabStackWindows(void) { if (XGetSelectionOwner(disp, XInternAtom(disp, "_NET_WM_CM_S0", False)) == None) errx(EXIT_FAILURE, "option --stack: Composite Manager is not running, required to use this option."); unsigned long numberItemsReturn; unsigned long bytesAfterReturn; unsigned char* propReturn; long offset = 0L; long length = ~0L; Bool delete = False; int actualFormatReturn; Atom actualTypeReturn; Imlib_Image im = NULL; XImage* ximage = NULL; XWindowAttributes attr; unsigned long i = 0; #define EWMH_CLIENT_LIST "_NET_CLIENT_LIST" // spec EWMH Atom atomProp = XInternAtom(disp, EWMH_CLIENT_LIST, False); Atom atomType = AnyPropertyType; int result = XGetWindowProperty(disp, root, atomProp, offset, length, delete, atomType, &actualTypeReturn, &actualFormatReturn, &numberItemsReturn, &bytesAfterReturn, &propReturn); if (result != Success || numberItemsReturn == 0) errx(EXIT_FAILURE, "option --stack: Failed XGetWindowProperty: " EWMH_CLIENT_LIST); initializeScrotList(images); XCompositeRedirectSubwindows(disp, root, CompositeRedirectAutomatic); for (i = 0; i < numberItemsReturn; i++) { Window win = *((Window*)propReturn + i); if (!XGetWindowAttributes(disp, win, &attr)) errx(EXIT_FAILURE, "option --stack: Failed XGetWindowAttributes"); /* Only visible windows */ if (attr.map_state != IsViewable) continue; if (!scrotMatchWindowClassName(win)) continue; ximage = XGetImage(disp, win, 0, 0, attr.width, attr.height, AllPlanes, ZPixmap); if (!ximage) errx(EXIT_FAILURE, "option --stack: Failed XGetImage: Window id 0x%lx", win); im = imlib_create_image_from_ximage(ximage, NULL, attr.x, attr.y, attr.width, attr.height, 1); XFree(ximage); appendToScrotList(images, im); } return stalkImageConcat(&images, opt.stackDirection); } Imlib_Image scrotGrabShotMulti(void) { int screens = ScreenCount(disp); if (screens < 2) return scrotGrabShot(); int i; char* dispStr; char* subDisp; char newDisp[255]; Imlib_Image ret = NULL; initializeScrotList(images); subDisp = strdup(DisplayString(disp)); for (i = 0; i < screens; i++) { dispStr = strchr(subDisp, ':'); if (dispStr) { dispStr = strchr(dispStr, '.'); if (dispStr) *dispStr = '\0'; } snprintf(newDisp, sizeof(newDisp), "%s.%d", subDisp, i); initXAndImlib(newDisp, i); ret = imlib_create_image_from_drawable(0, 0, 0, scr->width, scr->height, 1); appendToScrotList(images, ret); } free(subDisp); return stalkImageConcat(&images, HORIZONTAL); } Imlib_Image stalkImageConcat(ScrotList* images, enum Direction const dir) { if (isEmptyScrotList(images)) return NULL; int total = 0, max = 0; int x = 0, y = 0, w , h; Imlib_Image ret, im; ScrotListNode* image = NULL; bool const vertical = (dir == VERTICAL) ? true : false; forEachScrotList(images, image) { im = (Imlib_Image) image->data; imlib_context_set_image(im); h = imlib_image_get_height(); w = imlib_image_get_width(); if (!vertical) { if (h > max) max = h; total += w; } else { if (w > max) max = w; total += h; } } if (!vertical) { w = total; h = max; } else { w = max; h = total; } ret = imlib_create_image(w, h); imlib_context_set_image(ret); imlib_context_set_color(0, 0, 0, 255); imlib_image_fill_rectangle(0, 0, w, h); image = firstScrotList(images); while (image) { im = (Imlib_Image) image->data; imlib_context_set_image(im); h = imlib_image_get_height(); w = imlib_image_get_width(); imlib_context_set_image(ret); imlib_context_set_anti_alias(0); imlib_context_set_dither(1); imlib_context_set_blend(0); imlib_context_set_angle(0); imlib_blend_image_onto_image(im, 0, 0, 0, w, h, x, y, w, h); (!vertical) ? (x += w) : (y += h); imlib_context_set_image(im); imlib_free_image_and_decache(); nextAndFreeScrotList(image); } return ret; } scrot-1.7/src/note.c000066400000000000000000000143651414262464400144330ustar00rootroot00000000000000/* note.c Copyright 2019-2021 Daniel T. Borelli Copyright 2021 Guilherme Janczak Copyright 2021 IFo Hancroft Copyright 2021 Peter Wu 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 of the Software and its documentation and acknowledgment shall be given in the documentation and software packages that this Software was used. 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 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. */ /* This file is part of the scrot project. */ #include #include #include "scrot.h" enum { // default color DEF_COLOR_RED = 0, DEF_COLOR_GREEN = 0, DEF_COLOR_BLUE = 0, DEF_COLOR_ALPHA = 255 }; ScrotNote note; static Imlib_Font imFont = NULL; static void loadFont(void); static char* parseText(char**, char* const); static inline void pfree(char** ptr) { free(*ptr); *ptr = NULL; } static inline void nextSpace(char** token) { while (*++*token == ' ' && **token != '\0') { } } static inline void nextNotSpace(char** token) { while (*++*token != ' ' && **token != '\0') { } } void scrotNoteNew(char* format) { scrotNoteFree(); note = (ScrotNote) { NULL, NULL, 0, 0, 0.0, { DEF_COLOR_RED, DEF_COLOR_GREEN, DEF_COLOR_BLUE, DEF_COLOR_ALPHA } }; char* const end = format + strlen(format); char* token = strpbrk(format, "-"); if (!token || (strlen(token) == 1)) { malformed: pfree(&format); errx(EXIT_FAILURE, "Error --note option : Malformed syntax."); } while (token) { const char type = *++token; char* savePtr = NULL; char* c; nextSpace(&token); switch (type) { case 'f': note.font = parseText(&token, end); if (!note.font) errx(EXIT_FAILURE, "Error --note option : Malformed syntax for -f"); char* number = strrchr(note.font, '/'); if (!number) errx(EXIT_FAILURE, "Error --note option : Malformed syntax for -f, required number."); int fontSize = optionsParseRequiredNumber(++number); if (fontSize < 6) warnx("Warning: --note option: font size < 6"); break; case 'x': if ((1 != sscanf(token, "%d", ¬e.x) || (note.x < 0))) errx(EXIT_FAILURE, "Error --note option : Malformed syntax for -x"); nextNotSpace(&token); break; case 'y': if ((1 != sscanf(token, "%d", ¬e.y)) || (note.y < 0)) errx(EXIT_FAILURE, "Error --note option : Malformed syntax for -y"); nextNotSpace(&token); break; case 'a': if ((1 != sscanf(token, "%lf", ¬e.angle))) errx(EXIT_FAILURE, "Error --note option : Malformed syntax for -a"); nextNotSpace(&token); break; case 't': note.text = parseText(&token, end); if (!note.text) errx(EXIT_FAILURE, "Error --note option : Malformed syntax for -t"); break; case 'c': c = strtok_r(token, ",", &savePtr); int numberColors = 0; while (c) { token = c; int const color = optionsParseRequireRange( optionsParseRequiredNumber(c), 0 ,255); switch (++numberColors) { case 1: note.color.r = color; break; case 2: note.color.g = color; break; case 3: note.color.b = color; break; case 4: note.color.a = color; break; } c = strtok_r(NULL, ",", &savePtr); } if (numberColors > 4) warnx("Warning --note option : Malformed syntax for -c"); break; default: errx(EXIT_FAILURE, "Error --note option : unknown option: '-%c'", type); } token = strpbrk(token, "-"); } if (!note.font || !note.text) goto malformed; loadFont(); } void scrotNoteFree(void) { if (note.text) pfree(¬e.text); if (note.font) pfree(¬e.font); if (imFont) { imlib_context_set_font(imFont); imlib_free_font(); } } void scrotNoteDraw(Imlib_Image im) { if (!im) return; imlib_context_set_image(im); imlib_context_set_font(imFont); imlib_context_set_direction(IMLIB_TEXT_TO_ANGLE); imlib_context_set_angle(note.angle); imlib_context_set_color(note.color.r, note.color.g, note.color.b, note.color.a); imlib_text_draw(note.x, note.y, note.text); } void loadFont(void) { imFont = imlib_load_font(note.font); if (!imFont) { warnx("Error --note option : Failed to load fontname: %s", note.font); scrotNoteFree(); exit(EXIT_FAILURE); } } char* parseText(char** token, char* const end) { assert(NULL != *token); assert(NULL != end); if (**token != '\'') return NULL; (*token)++; char* begin = *token; while ((*token != end) && **token != '\'') (*token)++; ptrdiff_t length = (*token - begin); if (length == 0) return NULL; return strndup(begin, length); } scrot-1.7/src/note.h000066400000000000000000000043071414262464400144330ustar00rootroot00000000000000/* note.h Copyright 2019-2021 Daniel T. Borelli Copyright 2021 Christopher R. Nelson Copyright 2021 Peter Wu 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 of the Software and its documentation and acknowledgment shall be given in the documentation and software packages that this Software was used. 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 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. */ /* This file is part of the scrot project. */ #pragma once #include "options.h" #include /* * Format: -f 'NAME/SIZE' -x NUM -y NUM -t 'TEXT' -c NUM,NUM,NUM,NUM * * -f fontname/size - absolute path * -x screen position x * -y screen position y * -t text note * -c color(red,green,blue,alpha) range 0..255 * * */ struct __ScrotNote { char* font; /* font name */ char* text; /* text of the note */ int x; /* position screen (optional) */ int y; /* position screen (optional) */ double angle; /* angle text (optional) */ struct Color { /* (optional) */ int r, /* red */ g, /* green */ b, /* blue */ a; /* alpha */ } color; }; extern ScrotNote note; void scrotNoteNew(char*); void scrotNoteFree(void); void scrotNoteDraw(Imlib_Image); scrot-1.7/src/options.c000066400000000000000000000430631414262464400151560ustar00rootroot00000000000000/* options.c Copyright 1999-2000 Tom Gilbert Copyright 2008 William Vera Copyright 2009 George Danchev Copyright 2009 James Cameron Copyright 2010 Ibragimov Rinat Copyright 2017 Stoney Sauce Copyright 2019 Daniel Lublin Copyright 2019-2021 Daniel T. Borelli Copyright 2019 Jade Auer Copyright 2020 Sean Brennan Copyright 2021 Christopher R. Nelson Copyright 2021 Guilherme Janczak Copyright 2021 IFo Hancroft Copyright 2021 Peter Wu Copyright 2021 Wilson Smith <01wsmith+gh@gmail.com> 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 of the Software and its documentation and acknowledgment shall be given in the documentation and software packages that this Software was used. 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 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. */ #include "options.h" #include "scrot.h" #include #define STR_LEN_MAX_FILENAME(msg, fileName) do { \ if (strlen((fileName)) > MAX_FILENAME) { \ errx(EXIT_FAILURE, #msg " filename too long, must be " \ "less than %d characters", MAX_FILENAME); \ } \ } while(0) #define checkMaxOutputFileName(fileName) \ STR_LEN_MAX_FILENAME(output, (fileName)) #define checkMaxInputFileName(fileName) \ STR_LEN_MAX_FILENAME(input, (fileName)) enum { MAX_LEN_WINDOW_CLASS_NAME = 80, //characters MAX_FILENAME = 256, // characters MAX_DISPLAY_NAME = 256, // characters }; ScrotOptions opt = { .quality = 75, .lineStyle = LineSolid, .lineWidth = 1, .lineOpacity = SELECTION_OPACITY_DEFAULT, .lineMode = LINE_MODE_S_CLASSIC, .stackDirection = HORIZONTAL, }; int optionsParseRequiredNumber(char const* str) { assert(NULL != str); // fix yout caller function, // the user does not impose this behavior char* end = NULL; long ret = 0L; errno = 0; ret = strtol(str, &end, 10); if (errno) goto range_error; if (str == end) errx(EXIT_FAILURE, "the option is not a number: %s", end); if (ret > INT_MAX || ret < INT_MIN) { errno = ERANGE; goto range_error; } return ret; range_error: err(EXIT_FAILURE, "error strtol"); } static int nonNegativeNumber(int number) { return (number < 0) ? 0 : number; } int optionsParseRequireRange(int n, int lo, int hi) { return (n < lo ? lo : n > hi ? hi : n); } bool optionsParseIsString(char const* const str) { return (str && (str[0] != '\0')); } static void optionsParseStack(char const* optarg) { // the suboption it's optional if (!optarg) { opt.stackDirection = HORIZONTAL; return; } char const* value = strchr(optarg, '='); if (value) ++value; else value = optarg; if (*value == 'v') opt.stackDirection = VERTICAL; else if (*value == 'h') opt.stackDirection = HORIZONTAL; else { errx(EXIT_FAILURE, "option --stack: Unknown value for suboption '%s'", value); } } static void optionsParseSelection(char const* optarg) { // the suboption it's optional if (!optarg) { opt.selection.mode = SELECTION_MODE_CAPTURE; return; } char const* value = strchr(optarg, '='); if (value) ++value; else value = optarg; if (!strncmp(value, SELECTION_MODE_S_CAPTURE, SELECTION_MODE_L_CAPTURE)) { opt.selection.mode = SELECTION_MODE_CAPTURE; return; /* it has no parameter */ } else if (!strncmp(value, SELECTION_MODE_S_HIDE, SELECTION_MODE_L_HIDE)) { opt.selection.mode = SELECTION_MODE_HIDE; value += SELECTION_MODE_L_HIDE; } else if (!strncmp(value, SELECTION_MODE_S_HOLE, SELECTION_MODE_L_HOLE)) { opt.selection.mode = SELECTION_MODE_HOLE; } else if (!strncmp(value, SELECTION_MODE_S_BLUR, SELECTION_MODE_L_BLUR)) { opt.selection.mode = SELECTION_MODE_BLUR; opt.selection.paramNum = SELECTION_MODE_BLUR_DEFAULT; value += SELECTION_MODE_L_BLUR; } else { errx(EXIT_FAILURE, "option --select: Unknown value for suboption '%s'", value); } if (opt.selection.mode & SELECTION_MODE_NOT_NEED_PARAM) return; if (*value != SELECTION_MODE_SEPARATOR) return; if (*(++value) == '\0') errx(EXIT_FAILURE, "option --select: Invalid parameter."); if (opt.selection.mode == SELECTION_MODE_BLUR) { int const num = nonNegativeNumber(optionsParseRequiredNumber(value)); opt.selection.paramNum = optionsParseRequireRange(num, SELECTION_MODE_BLUR_MIN, SELECTION_MODE_BLUR_MAX); } else { // SELECTION_MODE_HIDE checkMaxInputFileName(value); opt.selection.paramStr = strdup(value); } } static void optionsParseLine(char* optarg) { enum { Style = 0, Width, Color, Opacity, Mode }; char* const token[] = { [Style] = "style", [Width] = "width", [Color] = "color", [Opacity] = "opacity", [Mode] = "mode", NULL }; char* subopts = optarg; char* value = NULL; while (*subopts != '\0') { switch (getsubopt(&subopts, token, &value)) { case Style: if (!optionsParseIsString(value)) { errx(EXIT_FAILURE, "Missing value for suboption '%s'", token[Style]); } if (!strncmp(value, "dash", 4)) opt.lineStyle = LineOnOffDash; else if (!strncmp(value, "solid", 5)) opt.lineStyle = LineSolid; else { errx(EXIT_FAILURE, "Unknown value for suboption '%s': %s", token[Style], value); } break; case Width: if (!optionsParseIsString(value)) { errx(EXIT_FAILURE, "Missing value for suboption '%s'", token[Width]); } opt.lineWidth = optionsParseRequiredNumber(value); if (opt.lineWidth <= 0 || opt.lineWidth > 8) { errx(EXIT_FAILURE, "Value of the range (1..8) for " "suboption '%s': %d", token[Width], opt.lineWidth); } break; case Color: if (!optionsParseIsString(value)) { errx(EXIT_FAILURE, "Missing value for suboption '%s'", token[Color]); } opt.lineColor = strdup(value); break; case Mode: if (!optionsParseIsString(value)) { errx(EXIT_FAILURE, "Missing value for suboption '%s'", token[Mode]); } bool isValidMode = !strncmp(value, LINE_MODE_S_CLASSIC, LINE_MODE_L_CLASSIC); isValidMode = isValidMode || !strncmp(value, LINE_MODE_S_EDGE, LINE_MODE_L_EDGE); if (!isValidMode) { errx(EXIT_FAILURE, "Unknown value for suboption '%s': %s", token[Mode], value); } opt.lineMode = strdup(value); break; case Opacity: if (!optionsParseIsString(value)) { errx(EXIT_FAILURE, "Missing value for suboption '%s'", token[Opacity]); } opt.lineOpacity = optionsParseRequiredNumber(value); break; default: errx(EXIT_FAILURE, "No match found for token: '%s'", value); break; } } /* while */ } static void optionsParseWindowClassName(const char* windowClassName) { assert(windowClassName != NULL); if (windowClassName[0] != '\0') opt.windowClassName = strndup(windowClassName, MAX_LEN_WINDOW_CLASS_NAME); } static bool accessFileOk(const char* const pathName) { errno = 0; return (0 == access(pathName, W_OK)); } static char* getPathOfStdout(void) { char path[16] = {"/dev/stdout"}; size_t const len = sizeof(path); if (!accessFileOk(path)) { snprintf(path, len, "/dev/fd/%d", STDOUT_FILENO); if (!accessFileOk(path)) { snprintf(path, len, "/proc/self/fd/%d", STDOUT_FILENO); if (!accessFileOk(path)) { // We quit because imlib2 will fail later anyway. err(EXIT_FAILURE, "access to stdout failed"); } } } return strndup(path, len); } void optionsParse(int argc, char** argv) { static char stropts[] = "a:ofipbcd:e:hmq:s::t:uvzn:l:D:k::C:S:F:"; static struct option lopts[] = { /* actions */ { "help", no_argument, 0, 'h' }, { "version", no_argument, 0, 'v' }, { "count", no_argument, 0, 'c' }, { "focused", no_argument, 0, 'u' }, { "focussed", no_argument, 0, 'u' }, /* macquarie dictionary has both spellings */ { "border", no_argument, 0, 'b' }, { "multidisp", no_argument, 0, 'm' }, { "silent", no_argument, 0, 'z' }, { "pointer", no_argument, 0, 'p' }, { "ignorekeyboard", no_argument, 0, 'i' }, { "freeze", no_argument, 0, 'f' }, { "overwrite", no_argument, 0, 'o' }, /* toggles */ { "stack", optional_argument, 0, 'k' }, { "select", optional_argument, 0, 's' }, { "thumb", required_argument, 0, 't' }, { "delay", required_argument, 0, 'd' }, { "quality", required_argument, 0, 'q' }, { "exec", required_argument, 0, 'e' }, { "autoselect", required_argument, 0, 'a' }, { "display", required_argument, 0, 'D' }, { "note", required_argument, 0, 'n' }, { "line", required_argument, 0, 'l' }, { "class", required_argument, 0, 'C' }, { "script", required_argument, 0, 'S' }, { "file", required_argument, 0, 'F' }, { 0, 0, 0, 0 } }; int optch = 0, cmdx = 0; /* Now to pass some optionarinos */ while ((optch = getopt_long(argc, argv, stropts, lopts, &cmdx)) != EOF) { switch (optch) { case 0: break; case 'h': showUsage(); break; case 'v': showVersion(); break; case 'b': opt.border = 1; break; case 'd': opt.delay = nonNegativeNumber(optionsParseRequiredNumber(optarg)); break; case 'e': opt.exec = strdup(optarg); break; case 'm': opt.multidisp = 1; break; case 'q': opt.quality = optionsParseRequiredNumber(optarg); break; case 's': optionsParseSelection(optarg); break; case 'u': opt.focused = 1; break; case 'c': opt.countdown = 1; break; case 't': optionsParseThumbnail(optarg); break; case 'z': opt.silent = 1; break; case 'p': opt.pointer = 1; break; case 'i': opt.ignoreKeyboard = 1; break; case 'f': opt.freeze = 1; break; case 'o': opt.overwrite = 1; break; case 'a': optionsParseAutoselect(optarg); break; case 'D': optionsParseDisplay(optarg); break; case 'n': optionsParseNote(optarg); break; case 'l': optionsParseLine(optarg); break; case 'k': opt.stack = 1; optionsParseStack(optarg); break; case 'C': optionsParseWindowClassName(optarg); break; case 'S': opt.script = strdup(optarg); break; case 'F': optionsParseFileName(optarg); break; case '?': exit(EXIT_FAILURE); default: break; } } /* Now the leftovers, which must be files */ while (optind < argc) { /* If recursive is NOT set, but the only argument is a directory name, we grab all the files in there, but not subdirs */ if (!opt.outputFile) { optionsParseFileName(argv[optind++]); bool const redirectChar = ( opt.outputFile[0] == '-' && opt.outputFile[1] == '\0'); if (redirectChar) { free(opt.outputFile); opt.outputFile = getPathOfStdout(); opt.overwrite = 1; opt.thumb = 0; } } else warnx("unrecognised option %s", argv[optind++]); } /* So that we can safely be called again */ optind = 1; } char* optionsNameThumbnail(const char* name) { const char* const thumbSuffix = "-thumb"; const size_t thumbSuffixLength = 7; const size_t newNameLength = strlen(name) + thumbSuffixLength; char* newName = calloc(1, newNameLength); if (!newName) err(EXIT_FAILURE, "Unable to allocate thumbnail"); const char* const extension = strrchr(name, '.'); if (extension) { /* We add one so length includes '\0'*/ const ptrdiff_t nameLength = (extension - name) + 1; strlcpy(newName, name, nameLength); strlcat(newName, thumbSuffix, newNameLength); strlcat(newName, extension, newNameLength); } else snprintf(newName, newNameLength, "%s%s", name, thumbSuffix); return newName; } void optionsParseAutoselect(char* optarg) { char* token; const char tokenDelimiter[2] = ","; int dimensions[4]; int i = 0; if (strchr(optarg, ',')) { /* geometry dimensions must be in format x,y,w,h */ dimensions[i++] = optionsParseRequiredNumber(strtok(optarg, tokenDelimiter)); while ((token = strtok(NULL, tokenDelimiter))) dimensions[i++] = optionsParseRequiredNumber(token); opt.autoselect = 1; opt.autoselectX = dimensions[0]; opt.autoselectY = dimensions[1]; opt.autoselectW = dimensions[2]; opt.autoselectH = dimensions[3]; if (i != 4) errx(EXIT_FAILURE, "option 'autoselect' require 4 arguments"); } else errx(EXIT_FAILURE, "invalid format for option -- 'autoselect'"); } void optionsParseDisplay(char* optarg) { opt.display = strndup(optarg, MAX_DISPLAY_NAME); if (!opt.display) err(EXIT_FAILURE, "Unable to allocate display"); } void optionsParseThumbnail(char* optarg) { char* token; if (strchr(optarg, 'x')) { /* We want to specify the geometry */ token = strtok(optarg, "x"); opt.thumbWidth = optionsParseRequiredNumber(token); token = strtok(NULL, "x"); if (token) { opt.thumbWidth = optionsParseRequiredNumber(optarg); opt.thumbHeight = optionsParseRequiredNumber(token); if (opt.thumbWidth < 0) opt.thumbWidth = 1; if (opt.thumbHeight < 0) opt.thumbHeight = 1; if (!opt.thumbWidth && !opt.thumbHeight) opt.thumb = 0; else opt.thumb = 1; } } else { opt.thumb = optionsParseRequiredNumber(optarg); if (opt.thumb < 1) opt.thumb = 1; else if (opt.thumb > 100) opt.thumb = 100; } } void optionsParseFileName(const char* optarg) { checkMaxOutputFileName(optarg); opt.outputFile = strdup(optarg); } void optionsParseNote(char* optarg) { opt.note = strdup(optarg); if (!opt.note) return; if (opt.note[0] == '\0') errx(EXIT_FAILURE, "Required arguments for --note."); scrotNoteNew(opt.note); } /* Return: 0 : It does not match 1 : If it matches */ int optionsCompareWindowClassName(const char* targetClassName) { assert(targetClassName != NULL); assert(opt.windowClassName != NULL); return !!(!strncmp(targetClassName, opt.windowClassName, MAX_LEN_WINDOW_CLASS_NAME - 1)); } void showVersion(void) { printf(SCROT_PACKAGE " version " SCROT_VERSION "\n"); exit(0); } void showUsage(void) { fputs(/* Check that everything lines up after any changes. */ "usage: " SCROT_PACKAGE " [-bcfhikmopsuvz] [-a X,Y,W,H] [-C NAME] [-D DISPLAY]" "\n" " [-F FILE] [-d SEC] [-e CMD] [-l STYLE] [-n OPTS] [-q NUM] [-S CMD] \n" " [-t NUM | GEOM] [FILE]\n", stdout); exit(0); } scrot-1.7/src/options.h000066400000000000000000000057551414262464400151710ustar00rootroot00000000000000/* options.h Copyright 1999-2000 Tom Gilbert Copyright 2009 James Cameron Copyright 2010 Ibragimov Rinat Copyright 2017 Stoney Sauce Copyright 2019-2021 Daniel T. Borelli Copyright 2020 Sean Brennan Copyright 2021 IFo Hancroft Copyright 2021 Peter Wu Copyright 2021 Wilson Smith <01wsmith+gh@gmail.com> 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 of the Software and its documentation and acknowledgment shall be given in the documentation and software packages that this Software was used. 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 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. */ #include "structs.h" #include "scrot_selection.h" #pragma once // General purpose enum enum Direction { // see main.c:stalkImageConcat(...) HORIZONTAL, VERTICAL, }; struct __ScrotOptions { int delay; int countdown; int focused; int quality; int border; int silent; int multidisp; int thumb; int thumbWidth; int thumbHeight; int pointer; int ignoreKeyboard; int freeze; int overwrite; int lineStyle; int lineWidth; int lineOpacity; int stack; enum Direction stackDirection; char* lineColor; char* lineMode; char* outputFile; char* thumbFile; char* exec; char* display; char* note; char* windowClassName; char* script; int autoselect; int autoselectX; int autoselectY; int autoselectH; int autoselectW; SelectionMode selection; }; void optionsParse(int, char**); char* optionsNameThumbnail(const char*); void optionsParseFileName(const char*); void optionsParseThumbnail(char*); void optionsParseAutoselect(char*); void optionsParseDisplay(char*); void optionsParseNote(char*); int optionsParseRequiredNumber(char const *); int optionsCompareWindowClassName(const char*); int optionsParseRequireRange(int, int, int); extern ScrotOptions opt; scrot-1.7/src/scrot.h000066400000000000000000000070141414262464400146160ustar00rootroot00000000000000/* scrot.h Copyright 1999-2000 Tom Gilbert Copyright 2009 James Cameron Copyright 2019-2021 Daniel T. Borelli Copyright 2020 Jeroen Roovers Copyright 2020 Hinigatsu Copyright 2021 Christopher R. Nelson Copyright 2021 Guilherme Janczak Copyright 2021 Peter Wu 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 of the Software and its documentation and acknowledgment shall be given in the documentation and software packages that this Software was used. 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 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. */ #pragma once #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "options.h" #include "note.h" #include "scrot_config.h" #include "scrot_selection.h" #include "slist.h" #include "structs.h" typedef void (*signalHandler)(int); void showUsage(void); void showVersion(void); void initXAndImlib(char*, int); Imlib_Image scrotGrabShot(void); void scrotExecApp(Imlib_Image, struct tm*, char*, char*); void scrotDoDelay(void); Imlib_Image scrotGrabFocused(void); Imlib_Image scrotGrabAutoselect(void); void scrotSelArea(int*, int*, int*, int*); void scrotNiceClip(int*, int*, int*, int*); int scrotGetGeometry(Window, int*, int*, int*, int*); int scrotMatchWindowClassName(Window); Window scrotGetWindow(Display*, Window, int, int); Window scrotGetClientWindow(Display*, Window); Window scrotFindWindowByProperty(Display*, const Window, const Atom); char* imPrintf(char*, struct tm*, char*, char*, Imlib_Image); Imlib_Image scrotGrabShotMulti(void); Imlib_Image scrotGrabStackWindows(void); Imlib_Image stalkImageConcat(ScrotList*, enum Direction const); void scrotGrabMousePointer(const Imlib_Image, const int, const int); void scrotCheckIfOverwriteFile(char**); size_t scrotHaveFileExtension(char const*, char**); /* Imlib stuff */ extern Display* disp; extern Visual* vis; extern Colormap cm; extern int depth; /* Thumbnail sizes */ extern Window root; extern Screen* scr; scrot-1.7/src/scrot_selection.c000066400000000000000000000362551414262464400166670ustar00rootroot00000000000000/* scrot_selection.c Copyright 2020-2021 Daniel T. Borelli Copyright 2021 Martin C Copyright 2021 Peter Wu Copyright 2021 Wilson Smith <01wsmith+gh@gmail.com> 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 of the Software and its documentation and acknowledgment shall be given in the documentation and software packages that this Software was used. 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 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. */ /* This file is part of the scrot project. Part of the code comes from the main.c file and maintains its authorship. */ #include "scrot.h" #include "selection_classic.h" #include "selection_edge.h" struct Selection** selectionGet(void) { static struct Selection* sel = NULL; return &sel; } static void selectionAllocate(void) { struct Selection** sel = selectionGet(); *sel = calloc(1, sizeof(**sel)); } static void selectionDeallocate(void) { struct Selection** sel = selectionGet(); free(*sel); *sel = NULL; } static void createCursors(void) { struct Selection* const sel = *selectionGet(); assert(sel != NULL); if (opt.selection.mode == SELECTION_MODE_CAPTURE) sel->curCross = XCreateFontCursor(disp, XC_cross); else if (opt.selection.mode == SELECTION_MODE_HIDE) sel->curCross = XCreateFontCursor(disp, XC_spraycan); else if (opt.selection.mode == SELECTION_MODE_BLUR) sel->curCross = XCreateFontCursor(disp, XC_box_spiral); else // SELECTION_MODE_HOLE sel->curCross = XCreateFontCursor(disp, XC_target); sel->curAngleNE = XCreateFontCursor(disp, XC_ur_angle); sel->curAngleNW = XCreateFontCursor(disp, XC_ul_angle); sel->curAngleSE = XCreateFontCursor(disp, XC_lr_angle); sel->curAngleSW = XCreateFontCursor(disp, XC_ll_angle); } static void freeCursors(void) { struct Selection* const sel = *selectionGet(); assert(sel != NULL); XFreeCursor(disp, sel->curCross); XFreeCursor(disp, sel->curAngleNE); XFreeCursor(disp, sel->curAngleNW); XFreeCursor(disp, sel->curAngleSE); XFreeCursor(disp, sel->curAngleSW); } void selectionCalculateRect(int x0, int y0, int x1, int y1) { struct SelectionRect* const rect = scrotSelectionGetRect(); rect->x = x0; rect->y = y0; rect->w = x1 - x0; rect->h = y1 - y0; if (rect->w == 0) rect->w++; if (rect->h == 0) rect->h++; if (rect->w < 0) { rect->x += rect->w; rect->w = 0 - rect->w; } if (rect->h < 0) { rect->y += rect->h; rect->h = 0 - rect->h; } } void scrotSelectionCreate(void) { selectionAllocate(); struct Selection* const sel = *selectionGet(); assert(sel != NULL); createCursors(); if (!strncmp(opt.lineMode, LINE_MODE_S_CLASSIC, LINE_MODE_L_CLASSIC)) { sel->create = selectionClassicCreate; sel->draw = selectionClassicDraw; sel->motionDraw = selectionClassicMotionDraw; sel->destroy = selectionClassicDestroy; } else if (!strncmp(opt.lineMode, LINE_MODE_S_EDGE, LINE_MODE_L_EDGE)) { sel->create = selectionEdgeCreate; sel->draw = selectionEdgeDraw; sel->motionDraw = selectionEdgeMotionDraw; sel->destroy = selectionEdgeDestroy; } else { // It never happened, fix the options.c file assert(0); } sel->create(); unsigned int const EVENT_MASK = ButtonMotionMask | ButtonPressMask | ButtonReleaseMask; if ((XGrabPointer(disp, root, False, EVENT_MASK, GrabModeAsync, GrabModeAsync, root, sel->curCross, CurrentTime) != GrabSuccess)) { scrotSelectionDestroy(); errx(EXIT_FAILURE, "couldn't grab pointer"); } } void scrotSelectionDestroy(void) { struct Selection* const sel = *selectionGet(); XUngrabPointer(disp, CurrentTime); freeCursors(); XSync(disp, True); sel->destroy(); selectionDeallocate(); } void scrotSelectionDraw(void) { struct Selection const* const sel = *selectionGet(); sel->draw(); } void scrotSelectionMotionDraw(int x0, int y0, int x1, int y1) { struct Selection const* const sel = *selectionGet(); unsigned int const EVENT_MASK = ButtonMotionMask | ButtonReleaseMask; Cursor cursor = None; if (x1 > x0 && y1 > y0) cursor = sel->curAngleSE; else if (x1 > x0) cursor = sel->curAngleNE; else if (y1 > y0) cursor = sel->curAngleSW; else cursor = sel->curAngleNW; XChangeActivePointerGrab(disp, EVENT_MASK, cursor, CurrentTime); sel->motionDraw(x0, y0, x1, y1); } struct SelectionRect* scrotSelectionGetRect(void) { return &(*selectionGet())->rect; } Status scrotSelectionCreateNamedColor(char const* nameColor, XColor* color) { assert(nameColor != NULL); assert(color != NULL); return XAllocNamedColor(disp, XDefaultColormap(disp, DefaultScreen(disp)), nameColor, color, &(XColor) {}); } void scrotSelectionGetLineColor(XColor* color) { scrotSelectionSetDefaultColorLine(); Status const ret = scrotSelectionCreateNamedColor(opt.lineColor, color); if (!ret) { scrotSelectionDestroy(); errx(EXIT_FAILURE, "Error allocate color:%s", strerror(BadColor)); } } void scrotSelectionSetDefaultColorLine(void) { if (!opt.lineColor) opt.lineColor = "gray"; } bool scrotSelectionGetUserSel(struct SelectionRect* selectionRect) { static int xfd = 0; static int fdSize = 0; XEvent ev; fd_set fdSet; int count = 0, done = 0; int rx = 0, ry = 0, rw = 0, rh = 0, isButtonPressed = 0; Window target = None; Status ret; scrotSelectionCreate(); xfd = ConnectionNumber(disp); fdSize = xfd + 1; ret = XGrabKeyboard(disp, root, False, GrabModeAsync, GrabModeAsync, CurrentTime); if (ret == AlreadyGrabbed) { int attempts = 20; struct timespec delay = { 0, 50 * 1000L * 1000L }; do { nanosleep(&delay, NULL); ret = XGrabKeyboard(disp, root, False, GrabModeAsync, GrabModeAsync, CurrentTime); } while (--attempts > 0 && ret == AlreadyGrabbed); } if (ret != GrabSuccess) { scrotSelectionDestroy(); errx(EXIT_FAILURE, "failed to grab keyboard"); } while (1) { /* Handle events here */ while (!done && XPending(disp)) { XNextEvent(disp, &ev); switch (ev.type) { case MotionNotify: if (isButtonPressed) scrotSelectionMotionDraw(rx, ry, ev.xbutton.x, ev.xbutton.y); break; case ButtonPress: isButtonPressed = 1; rx = ev.xbutton.x; ry = ev.xbutton.y; target = scrotGetWindow(disp, ev.xbutton.subwindow, ev.xbutton.x, ev.xbutton.y); if (target == None) target = root; break; case ButtonRelease: done = 1; break; case KeyPress: { KeySym* keysym = NULL; int keycode; /*dummy*/ keysym = XGetKeyboardMapping(disp, ev.xkey.keycode, 1, &keycode); if (!keysym) break; if (!isButtonPressed) { key_abort_shot: if (!opt.ignoreKeyboard || *keysym == XK_Escape) { warnx("Key was pressed, aborting shot"); done = 2; } XFree(keysym); break; } switch (*keysym) { case XK_Right: if (++rx > scr->width) rx = scr->width; break; case XK_Left: if (--rx < 0) rx = 0; break; case XK_Down: if (++ry > scr->height) ry = scr->height; break; case XK_Up: if (--ry < 0) ry = 0; break; default: goto key_abort_shot; } XFree(keysym); scrotSelectionMotionDraw(rx, ry, ev.xbutton.x, ev.xbutton.y); break; } case KeyRelease: /* ignore */ break; default: break; } } if (done) break; /* now block some */ FD_ZERO(&fdSet); FD_SET(xfd, &fdSet); errno = 0; count = select(fdSize, &fdSet, NULL, NULL, NULL); if ((count < 0) && ((errno == ENOMEM) || (errno == EINVAL) || (errno == EBADF))) { scrotSelectionDestroy(); errx(EXIT_FAILURE, "Connection to X display lost"); } } scrotSelectionDraw(); XUngrabKeyboard(disp, CurrentTime); bool const isAreaSelect = (scrotSelectionGetRect()->w > 5); scrotSelectionDestroy(); if (done == 2) return false; if (isAreaSelect) { /* If a rect has been drawn, it's an area selection */ rw = ev.xbutton.x - rx; rh = ev.xbutton.y - ry; if ((ev.xbutton.x + 1) == WidthOfScreen(scr)) ++rw; if ((ev.xbutton.y + 1) == HeightOfScreen(scr)) ++rh; if (rw < 0) { rx += rw; rw = 0 - rw; } if (rh < 0) { ry += rh; rh = 0 - rh; } // Not record pointer if there is a selection area because it is busy on that, // unless the delay option is used. if (opt.delay == 0) opt.pointer = 0; } else { /* else it's a window click */ if (!scrotGetGeometry(target, &rx, &ry, &rw, &rh)) return false; } scrotNiceClip(&rx, &ry, &rw, &rh); if (!opt.silent) XBell(disp, 0); selectionRect->x = rx; selectionRect->y = ry; selectionRect->w = rw; selectionRect->h = rh; return true; } static void changeImageOpacity(Imlib_Image image, int const opacity) { #define PIXEL_ARGB(a, r, g, b) ((a) << 24) | ((r) << 16) | ((g) << 8) | (b) #define PIXEL_A(argb) (((argb) >> 24) & 0xff) #define PIXEL_R(argb) (((argb) >> 16) & 0xff) #define PIXEL_G(argb) (((argb) >> 8) & 0xff) #define PIXEL_B(argb) (((argb) ) & 0xff) imlib_context_set_image(image); int const w = imlib_image_get_width(); int const h = imlib_image_get_height(); DATA32* data = imlib_image_get_data(); DATA32* end = data + (h * w); for (DATA32* pixel = data; pixel != end; ++pixel) { DATA8 const a = PIXEL_A(*pixel) * opacity / 255; DATA8 const r = PIXEL_R(*pixel); DATA8 const g = PIXEL_G(*pixel); DATA8 const b = PIXEL_B(*pixel); *pixel = (DATA32)PIXEL_ARGB(a, r, g, b); } imlib_image_put_back_data(data); } static Imlib_Image loadImage(char const* const fileName, int const opacity) { Imlib_Image image = imlib_load_image(fileName); if (!image) { errx(EXIT_FAILURE, "option --select: Failed to load image:%s", fileName); } imlib_context_set_image(image); if (imlib_image_has_alpha() == 0) { warnx("Warning, ignoring the opacity parameter because the image '%s'" " has no alpha channel, it will be drawn fully opaque.", fileName); return image; } if (opacity == 255) { // Do nothing if a totally opaque image is expected. return image; } changeImageOpacity(image, opacity); return image; } Imlib_Image scrotSelectionSelectMode(void) { struct SelectionRect rect0, rect1; unsigned int const oldMode = opt.selection.mode; opt.selection.mode = SELECTION_MODE_CAPTURE; if (!scrotSelectionGetUserSel(&rect0)) return NULL; opt.selection.mode = oldMode; if (opt.selection.mode & SELECTION_MODE_NOT_CAPTURE) if (!scrotSelectionGetUserSel(&rect1)) return NULL; scrotDoDelay(); Imlib_Image capture = imlib_create_image_from_drawable(0, rect0.x, rect0.y, rect0.w, rect0.h, 1); if (opt.pointer) scrotGrabMousePointer(capture, rect0.x, rect0.y); if (opt.selection.mode == SELECTION_MODE_CAPTURE) return capture; XColor color; scrotSelectionGetLineColor(&color); int const x = rect1.x - rect0.x; int const y = rect1.y - rect0.y; int const opacity = optionsParseRequireRange(opt.lineOpacity, SELECTION_OPACITY_MIN, SELECTION_OPACITY_MAX); imlib_context_set_image(capture); switch(opt.selection.mode) { case SELECTION_MODE_HOLE: if (opacity > 0) { Imlib_Image hole = imlib_clone_image(); imlib_context_set_color(color.red, color.green, color.blue, opacity); imlib_image_fill_rectangle(0, 0, rect0.w, rect0.h); imlib_blend_image_onto_image(hole, 0, x, y, rect1.w, rect1.h, x, y, rect1.w, rect1.h); imlib_context_set_image(hole); imlib_free_image_and_decache(); } break; case SELECTION_MODE_HIDE: { char* const fileName = opt.selection.paramStr; if (fileName) { if (opacity > 0) { Imlib_Image hide = loadImage(fileName, opacity); imlib_context_set_image(hide); int const w = imlib_image_get_width(); int const h = imlib_image_get_height(); imlib_context_set_image(capture); imlib_blend_image_onto_image(hide, 0, 0, 0, w, h, x, y, rect1.w, rect1.h); imlib_context_set_image(hide); imlib_free_image_and_decache(); } free(fileName); } else { imlib_context_set_color(color.red, color.green, color.blue, opacity); imlib_image_fill_rectangle(x, y, rect1.w, rect1.h); } break; } case SELECTION_MODE_BLUR: { int const amountBlur = opt.selection.paramNum; Imlib_Image blur = imlib_clone_image(); imlib_context_set_image(blur); imlib_image_blur(amountBlur); imlib_context_set_image(capture); imlib_blend_image_onto_image(blur, 0, x, y, rect1.w, rect1.h, x, y, rect1.w, rect1.h); imlib_context_set_image(blur); imlib_free_image_and_decache(); break; } default: assert(0); } return capture; } scrot-1.7/src/scrot_selection.h000066400000000000000000000074501414262464400166670ustar00rootroot00000000000000/* scrot_selection.h Copyright 2020-2021 Daniel T. Borelli Copyright 2021 Martin C Copyright 2021 Peter Wu 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 of the Software and its documentation and acknowledgment shall be given in the documentation and software packages that this Software was used. 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 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. */ /* This file is part of the scrot project. Part of the code comes from the main.c file and maintains its authorship. */ #pragma once #include #include #include #include #include #include #include #include /* S: string, L: len */ #define LINE_MODE_S_CLASSIC "classic" #define LINE_MODE_L_CLASSIC 7 #define LINE_MODE_S_EDGE "edge" #define LINE_MODE_L_EDGE 4 #define SELECTION_MODE_S_CAPTURE "capture" #define SELECTION_MODE_L_CAPTURE 7 #define SELECTION_MODE_S_HIDE "hide" #define SELECTION_MODE_L_HIDE 4 #define SELECTION_MODE_S_HOLE "hole" #define SELECTION_MODE_L_HOLE 4 #define SELECTION_MODE_S_BLUR "blur" #define SELECTION_MODE_L_BLUR 4 enum { SELECTION_MODE_SEPARATOR = ',', SELECTION_MODE_CAPTURE = (1 << 1), SELECTION_MODE_HIDE = (1 << 2), SELECTION_MODE_HOLE = (1 << 3), SELECTION_MODE_BLUR = (1 << 4), SELECTION_MODE_ANY = (SELECTION_MODE_CAPTURE | SELECTION_MODE_HIDE | SELECTION_MODE_HOLE | SELECTION_MODE_BLUR), SELECTION_MODE_NOT_CAPTURE = (SELECTION_MODE_ANY & ~SELECTION_MODE_CAPTURE), SELECTION_MODE_NEED_PARAM = (SELECTION_MODE_HIDE | SELECTION_MODE_BLUR), SELECTION_MODE_NOT_NEED_PARAM = (~SELECTION_MODE_NEED_PARAM), SELECTION_MODE_BLUR_MIN= 1, SELECTION_MODE_BLUR_MAX= 30, SELECTION_MODE_BLUR_DEFAULT = 18, SELECTION_OPACITY_MIN = 0, SELECTION_OPACITY_MAX = 255, SELECTION_OPACITY_DEFAULT = 100, SELECTION_EDGE_OPACITY_MIN = 10, SELECTION_EDGE_OPACITY_MAX = 100, }; struct SelectionRect { int x, y, w, h; }; typedef struct SelectionMode { unsigned int mode; int paramNum; char* paramStr; } SelectionMode; struct SelectionClassic; struct SelectionEdge; struct Selection { Cursor curCross, curAngleNW, curAngleNE, curAngleSW, curAngleSE; struct SelectionRect rect; struct SelectionClassic* classic; struct SelectionEdge* edge; void (*create)(void); void (*destroy)(void); void (*draw)(void); void (*motionDraw)(int, int, int, int); }; void scrotSelectionCreate(void); void scrotSelectionDestroy(void); void scrotSelectionDraw(void); void scrotSelectionMotionDraw(int, int, int, int); struct SelectionRect* scrotSelectionGetRect(void); void scrotSelectionGetLineColor(XColor*); Status scrotSelectionCreateNamedColor(char const*, XColor*); void scrotSelectionSetDefaultColorLine(void); bool scrotSelectionGetUserSel(struct SelectionRect*); Imlib_Image scrotSelectionSelectMode(void); scrot-1.7/src/selection_classic.c000066400000000000000000000064401414262464400171470ustar00rootroot00000000000000/* scrot_selection_classic.c Copyright 2020-2021 Daniel T. Borelli Copyright 2021 Peter Wu 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 of the Software and its documentation and acknowledgment shall be given in the documentation and software packages that this Software was used. 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 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. */ /* This file is part of the scrot project. Part of the code comes from the main.c file and maintains its authorship. */ #include "selection_classic.h" extern void selectionCalculateRect(int, int, int, int); extern struct Selection** selectionGet(void); struct SelectionClassic { XGCValues gcValues; GC gc; }; void selectionClassicCreate(void) { struct Selection* const sel = *selectionGet(); sel->classic = calloc(1, sizeof(*sel->classic)); struct SelectionClassic* pc = sel->classic; unsigned long const whiteColor = XWhitePixel(disp, 0); unsigned long const blackColor = XBlackPixel(disp, 0); pc->gcValues.function = GXxor; pc->gcValues.foreground = whiteColor; pc->gcValues.background = blackColor; pc->gcValues.plane_mask = pc->gcValues.background ^ pc->gcValues.foreground; pc->gcValues.subwindow_mode = IncludeInferiors; XColor color; scrotSelectionGetLineColor(&color); if (color.pixel != blackColor) pc->gcValues.foreground = color.pixel; pc->gc = XCreateGC(disp, root, GCFunction | GCForeground | GCBackground | GCSubwindowMode, &pc->gcValues); assert(pc->gc != NULL); XSetLineAttributes(disp, pc->gc, opt.lineWidth, opt.lineStyle, CapRound, JoinRound); if (opt.freeze) XGrabServer(disp); } void selectionClassicDestroy(void) { struct Selection const* const sel = *selectionGet(); struct SelectionClassic* pc = sel->classic; if (opt.freeze) XUngrabServer(disp); if (pc->gc) XFreeGC(disp, pc->gc); free(pc); } void selectionClassicDraw(void) { struct Selection const* const sel = *selectionGet(); struct SelectionClassic const* const pc = sel->classic; XDrawRectangle(disp, root, pc->gc, sel->rect.x, sel->rect.y, sel->rect.w, sel->rect.h); XFlush(disp); } void selectionClassicMotionDraw(int x0, int y0, int x1, int y1) { struct Selection const* const sel = *selectionGet(); if (sel->rect.w) selectionClassicDraw(); selectionCalculateRect(x0, y0, x1, y1); selectionClassicDraw(); } scrot-1.7/src/selection_classic.h000066400000000000000000000030511414262464400171470ustar00rootroot00000000000000/* scrot_selection_classic.h Copyright 2020-2021 Daniel T. Borelli Copyright 2021 Peter Wu 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 of the Software and its documentation and acknowledgment shall be given in the documentation and software packages that this Software was used. 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 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. */ /* This file is part of the scrot project. Part of the code comes from the main.c file and maintains its authorship. */ #pragma once #include "scrot.h" void selectionClassicCreate(void); void selectionClassicDestroy(void); void selectionClassicDraw(void); void selectionClassicMotionDraw(int, int, int, int); scrot-1.7/src/selection_edge.c000066400000000000000000000113331414262464400164270ustar00rootroot00000000000000/* scrot_selection_edge.c Copyright 2020-2021 Daniel T. Borelli Copyright 2021 Peter Wu 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 of the Software and its documentation and acknowledgment shall be given in the documentation and software packages that this Software was used. 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 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. */ /* This file is part of the scrot project. Part of the code comes from the main.c file and maintains its authorship. */ #include "scrot.h" extern void selectionCalculateRect(int, int, int, int); extern struct Selection** selectionGet(void); struct SelectionEdge { Window wndDraw; XClassHint* classHint; }; static Bool xeventUnmap(Display* dpy, XEvent* ev, XPointer arg) { (void)dpy; // unused Window* win = (Window*)arg; return (ev->xunmap.window == *win); } static void waitUnmapWindowNotify(void) { struct Selection const* const sel = *selectionGet(); struct SelectionEdge const* const pe = sel->edge; XEvent ev; XSelectInput(disp, pe->wndDraw, StructureNotifyMask); XUnmapWindow(disp, pe->wndDraw); struct timespec delay = {0, 80000000L}; // 80ms for (short i = 0; i < 30; ++i) { if (XCheckIfEvent(disp, &ev, &xeventUnmap, (XPointer) & (pe->wndDraw))) break; nanosleep(&delay, NULL); } } void selectionEdgeCreate(void) { struct Selection* const sel = *selectionGet(); sel->edge = calloc(1, sizeof(*sel->edge)); struct SelectionEdge* const pe = sel->edge; XColor color; scrotSelectionGetLineColor(&color); XSetWindowAttributes attr; attr.background_pixel = color.pixel; attr.override_redirect = True; pe->classHint = XAllocClassHint(); pe->classHint->res_name = "scrot"; pe->classHint->res_class = "scrot"; pe->wndDraw = XCreateWindow(disp, root, 0, 0, WidthOfScreen(scr), HeightOfScreen(scr), 0, CopyFromParent, InputOutput, CopyFromParent, CWOverrideRedirect | CWBackPixel, &attr); int const lineOpacity = optionsParseRequireRange(opt.lineOpacity, SELECTION_EDGE_OPACITY_MIN, SELECTION_OPACITY_MAX); unsigned long opacity = lineOpacity * ((unsigned)-1 / 100); XChangeProperty(disp, pe->wndDraw, XInternAtom(disp, "_NET_WM_WINDOW_OPACITY", False), XA_CARDINAL, 32, PropModeReplace, (unsigned char*) &opacity, 1L); XChangeProperty(disp, pe->wndDraw, XInternAtom(disp, "_NET_WM_WINDOW_TYPE", False), XA_ATOM, 32, PropModeReplace, (unsigned char*) &(Atom) { XInternAtom(disp, "_NET_WM_WINDOW_TYPE_DOCK", False) }, 1L); XSetClassHint(disp, pe->wndDraw, pe->classHint); } void selectionEdgeDestroy(void) { struct Selection const* const sel = *selectionGet(); struct SelectionEdge* pe = sel->edge; if (pe->wndDraw != 0) { waitUnmapWindowNotify(); XFree(pe->classHint); XDestroyWindow(disp, pe->wndDraw); } free(pe); } void selectionEdgeDraw(void) { struct Selection const* const sel = *selectionGet(); struct SelectionEdge const* const pe = sel->edge; XRectangle rects[4] = { { sel->rect.x, sel->rect.y, opt.lineWidth, sel->rect.h }, // left { sel->rect.x, sel->rect.y, sel->rect.w, opt.lineWidth }, // top { sel->rect.x + sel->rect.w, sel->rect.y, opt.lineWidth, sel->rect.h }, // right { sel->rect.x, sel->rect.y + sel->rect.h, sel->rect.w + opt.lineWidth, opt.lineWidth } // bottom }; XShapeCombineRectangles(disp, pe->wndDraw, ShapeBounding, 0, 0, rects, 4, ShapeSet, 0); XMapWindow(disp, pe->wndDraw); } void selectionEdgeMotionDraw(int x0, int y0, int x1, int y1) { struct Selection* const sel = *selectionGet(); selectionCalculateRect(x0, y0, x1, y1); sel->rect.x -= opt.lineWidth; sel->rect.y -= opt.lineWidth; sel->rect.w += opt.lineWidth; sel->rect.h += opt.lineWidth; selectionEdgeDraw(); } scrot-1.7/src/selection_edge.h000066400000000000000000000030321414262464400164310ustar00rootroot00000000000000/* scrot_selection_edge.h Copyright 2020-2021 Daniel T. Borelli Copyright 2021 Peter Wu 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 of the Software and its documentation and acknowledgment shall be given in the documentation and software packages that this Software was used. 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 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. */ /* This file is part of the scrot project. Part of the code comes from the main.c file and maintains its authorship. */ #pragma once #include "scrot.h" void selectionEdgeCreate(void); void selectionEdgeDestroy(void); void selectionEdgeDraw(void); void selectionEdgeMotionDraw(int, int, int, int); scrot-1.7/src/slist.h000066400000000000000000000044271414262464400146270ustar00rootroot00000000000000/* slist.h Copyright 2021 Christopher Nelson Copyright 2021 Peter Wu Copyright 2021 Daniel T. Borelli 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 of the Software and its documentation and acknowledgment shall be given in the documentation and software packages that this Software was used. 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 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. */ #pragma once #include typedef struct ScrotListNode { void* data; STAILQ_ENTRY(ScrotListNode) nodes; } ScrotListNode; typedef STAILQ_HEAD(ScrotLists, ScrotListNode) ScrotList; #define initializeScrotList(name) \ ScrotList name = STAILQ_HEAD_INITIALIZER(name); \ STAILQ_INIT(&name); #define appendToScrotList(name, newData) do { \ ScrotListNode* node = calloc(1, sizeof(*node)); \ node->data = (void*)newData; \ STAILQ_INSERT_TAIL(&name, node, nodes); \ } while(0) #define isEmptyScrotList(name) \ STAILQ_EMPTY(name) #define forEachScrotList(name, node) \ STAILQ_FOREACH(node, name, nodes) #define firstScrotList(name) \ STAILQ_FIRST(name) #define nextScrotList(name) \ STAILQ_NEXT(name, nodes); #define nextAndFreeScrotList(name) do { \ ScrotListNode* next = nextScrotList(name); \ free(name); \ name = next; \ } while(0) scrot-1.7/src/stamp-h.in000066400000000000000000000000121414262464400152030ustar00rootroot00000000000000timestamp scrot-1.7/src/structs.h000066400000000000000000000024411414262464400151720ustar00rootroot00000000000000/* structs.h Copyright (C) 1999,2000 Tom Gilbert. Copyright (C) 2021 Peter Wu 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 of the Software and its documentation and acknowledgment shall be given in the documentation and software packages that this Software was used. 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 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. */ #pragma once typedef struct __ScrotOptions ScrotOptions; typedef struct __ScrotNote ScrotNote;