xmlgraphics-commons-2.6/0040755 0000000 0000000 00000000000 13777276623 014131 5ustar000000000 0000000 xmlgraphics-commons-2.6/examples/0040755 0000000 0000000 00000000000 13777276623 015747 5ustar000000000 0000000 xmlgraphics-commons-2.6/examples/java/0040755 0000000 0000000 00000000000 13777276623 016670 5ustar000000000 0000000 xmlgraphics-commons-2.6/examples/java/image/0040755 0000000 0000000 00000000000 13777276623 017752 5ustar000000000 0000000 xmlgraphics-commons-2.6/examples/java/image/loader/0040755 0000000 0000000 00000000000 13777276623 021220 5ustar000000000 0000000 xmlgraphics-commons-2.6/examples/java/image/writer/0040755 0000000 0000000 00000000000 13777276623 021266 5ustar000000000 0000000 xmlgraphics-commons-2.6/examples/java/java2d/0040755 0000000 0000000 00000000000 13777276623 020037 5ustar000000000 0000000 xmlgraphics-commons-2.6/examples/java/java2d/ps/0040755 0000000 0000000 00000000000 13777276623 020461 5ustar000000000 0000000 xmlgraphics-commons-2.6/examples/java/ps/0040755 0000000 0000000 00000000000 13777276623 017312 5ustar000000000 0000000 xmlgraphics-commons-2.6/examples/java/xmp/0040755 0000000 0000000 00000000000 13777276623 017474 5ustar000000000 0000000 xmlgraphics-commons-2.6/lib/0040755 0000000 0000000 00000000000 13777276623 014677 5ustar000000000 0000000 xmlgraphics-commons-2.6/lib/build/0040755 0000000 0000000 00000000000 13777276623 015776 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/0040755 0000000 0000000 00000000000 13777276623 014720 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/documentation/0040755 0000000 0000000 00000000000 13777276623 017571 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/documentation/classes/0040755 0000000 0000000 00000000000 13777276623 021226 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/documentation/content/0040755 0000000 0000000 00000000000 13777276623 021243 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/documentation/content/xdocs/0040755 0000000 0000000 00000000000 13777276623 022363 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/documentation/resources/0040755 0000000 0000000 00000000000 13777276623 021603 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/documentation/resources/images/0040755 0000000 0000000 00000000000 13777276623 023050 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/documentation/resources/stylesheets/0040755 0000000 0000000 00000000000 13777276623 024157 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/documentation/translations/0040755 0000000 0000000 00000000000 13777276623 022312 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/main/0040755 0000000 0000000 00000000000 13777276623 015644 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/main/java/0040755 0000000 0000000 00000000000 13777276623 016565 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/0040755 0000000 0000000 00000000000 13777276623 017354 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/0040755 0000000 0000000 00000000000 13777276623 020575 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/0040755 0000000 0000000 00000000000 13777276623 023116 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/fonts/0040755 0000000 0000000 00000000000 13777276623 024247 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/0040755 0000000 0000000 00000000000 13777276623 024200 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/codec/0040755 0000000 0000000 00000000000 13777276623 025255 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/codec/png/0040755 0000000 0000000 00000000000 13777276623 026041 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/codec/tiff/0040755 0000000 0000000 00000000000 13777276623 026205 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/codec/util/0040755 0000000 0000000 00000000000 13777276623 026232 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/0040755 0000000 0000000 00000000000 13777276623 025446 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/cache/0040755 0000000 0000000 00000000000 13777276623 026511 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/0040755 0000000 0000000 00000000000 13777276623 026407 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/imageio/0040755 0000000 0000000 00000000000 13777276623 030021 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/pipeline/0040755 0000000 0000000 00000000000 13777276623 027253 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/spi/0040755 0000000 0000000 00000000000 13777276623 026241 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/util/0040755 0000000 0000000 00000000000 13777276623 026423 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/rendered/0040755 0000000 0000000 00000000000 13777276623 025770 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/writer/0040755 0000000 0000000 00000000000 13777276623 025514 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/writer/imageio/0040755 0000000 0000000 00000000000 13777276623 027126 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/writer/internal/0040755 0000000 0000000 00000000000 13777276623 027330 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/io/0040755 0000000 0000000 00000000000 13777276623 023525 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/java2d/0040755 0000000 0000000 00000000000 13777276623 024265 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/java2d/color/0040755 0000000 0000000 00000000000 13777276623 025403 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/java2d/color/profile/0040755 0000000 0000000 00000000000 13777276623 027043 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/java2d/ps/0040755 0000000 0000000 00000000000 13777276623 024707 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/0040755 0000000 0000000 00000000000 13777276623 023540 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/dsc/0040755 0000000 0000000 00000000000 13777276623 024311 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/dsc/events/0040755 0000000 0000000 00000000000 13777276623 025615 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/dsc/tools/0040755 0000000 0000000 00000000000 13777276623 025451 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/util/0040755 0000000 0000000 00000000000 13777276623 024073 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/util/dijkstra/0040755 0000000 0000000 00000000000 13777276623 025706 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/util/i18n/0040755 0000000 0000000 00000000000 13777276623 024652 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/util/io/0040755 0000000 0000000 00000000000 13777276623 024502 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/util/uri/0040755 0000000 0000000 00000000000 13777276623 024672 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/xmp/0040755 0000000 0000000 00000000000 13777276623 023722 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/xmp/merge/0040755 0000000 0000000 00000000000 13777276623 025021 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/xmp/schemas/0040755 0000000 0000000 00000000000 13777276623 025345 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/xmp/schemas/pdf/0040755 0000000 0000000 00000000000 13777276623 026116 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/main/resources/0040755 0000000 0000000 00000000000 13777276623 017656 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/main/resources/META-INF/0040755 0000000 0000000 00000000000 13777276623 021016 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/main/resources/META-INF/services/0040755 0000000 0000000 00000000000 13777276623 022641 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/main/resources/org/0040755 0000000 0000000 00000000000 13777276623 020445 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/main/resources/org/apache/0040755 0000000 0000000 00000000000 13777276623 021666 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/main/resources/org/apache/xmlgraphics/0040755 0000000 0000000 00000000000 13777276623 024207 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/main/resources/org/apache/xmlgraphics/fonts/0040755 0000000 0000000 00000000000 13777276623 025340 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/main/resources/org/apache/xmlgraphics/image/0040755 0000000 0000000 00000000000 13777276623 025271 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/main/resources/org/apache/xmlgraphics/image/codec/0040755 0000000 0000000 00000000000 13777276623 026346 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/main/resources/org/apache/xmlgraphics/image/writer/0040755 0000000 0000000 00000000000 13777276623 026605 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/main/resources/org/apache/xmlgraphics/ps/0040755 0000000 0000000 00000000000 13777276623 024631 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/test/0040755 0000000 0000000 00000000000 13777276623 015677 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/test/java/0040755 0000000 0000000 00000000000 13777276623 016620 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/test/java/org/0040755 0000000 0000000 00000000000 13777276623 017407 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/test/java/org/apache/0040755 0000000 0000000 00000000000 13777276623 020630 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/0040755 0000000 0000000 00000000000 13777276623 023151 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/fonts/0040755 0000000 0000000 00000000000 13777276623 024302 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/0040755 0000000 0000000 00000000000 13777276623 024233 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/codec/0040755 0000000 0000000 00000000000 13777276623 025310 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/codec/png/0040755 0000000 0000000 00000000000 13777276623 026074 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/codec/tiff/0040755 0000000 0000000 00000000000 13777276623 026240 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/loader/0040755 0000000 0000000 00000000000 13777276623 025501 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/loader/cache/0040755 0000000 0000000 00000000000 13777276623 026544 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/loader/impl/0040755 0000000 0000000 00000000000 13777276623 026442 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/loader/mocks/0040755 0000000 0000000 00000000000 13777276623 026615 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/writer/0040755 0000000 0000000 00000000000 13777276623 025547 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/writer/imageio/0040755 0000000 0000000 00000000000 13777276623 027161 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/writer/internal/0040755 0000000 0000000 00000000000 13777276623 027363 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/io/0040755 0000000 0000000 00000000000 13777276623 023560 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/java2d/0040755 0000000 0000000 00000000000 13777276623 024320 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/java2d/color/0040755 0000000 0000000 00000000000 13777276623 025436 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/java2d/color/profile/0040755 0000000 0000000 00000000000 13777276623 027076 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/java2d/ps/0040755 0000000 0000000 00000000000 13777276623 024742 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/ps/0040755 0000000 0000000 00000000000 13777276623 023573 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/ps/dsc/0040755 0000000 0000000 00000000000 13777276623 024344 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/ps/dsc/events/0040755 0000000 0000000 00000000000 13777276623 025650 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/ps/dsc/tools/0040755 0000000 0000000 00000000000 13777276623 025504 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/util/0040755 0000000 0000000 00000000000 13777276623 024126 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/util/io/0040755 0000000 0000000 00000000000 13777276623 024535 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/util/uri/0040755 0000000 0000000 00000000000 13777276623 024725 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/xmp/0040755 0000000 0000000 00000000000 13777276623 023755 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/test/resources/0040755 0000000 0000000 00000000000 13777276623 017711 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/test/resources/META-INF/0040755 0000000 0000000 00000000000 13777276623 021051 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/test/resources/org/0040755 0000000 0000000 00000000000 13777276623 020500 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/test/resources/org/apache/0040755 0000000 0000000 00000000000 13777276623 021721 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/test/resources/org/apache/xmlgraphics/0040755 0000000 0000000 00000000000 13777276623 024242 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/test/resources/org/apache/xmlgraphics/io/0040755 0000000 0000000 00000000000 13777276623 024651 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/test/resources/org/apache/xmlgraphics/java2d/0040755 0000000 0000000 00000000000 13777276623 025411 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/test/resources/org/apache/xmlgraphics/java2d/color/0040755 0000000 0000000 00000000000 13777276623 026527 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/test/resources/org/apache/xmlgraphics/java2d/color/profile/0040755 0000000 0000000 00000000000 13777276623 030167 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/test/resources/org/apache/xmlgraphics/util/0040755 0000000 0000000 00000000000 13777276623 025217 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/test/resources/org/apache/xmlgraphics/util/io/0040755 0000000 0000000 00000000000 13777276623 025626 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/tools/0040755 0000000 0000000 00000000000 13777276623 016060 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/tools/resources/0040755 0000000 0000000 00000000000 13777276623 020072 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/tools/resources/checkstyle/0040755 0000000 0000000 00000000000 13777276623 022230 5ustar000000000 0000000 xmlgraphics-commons-2.6/src/tools/resources/findbugs/0040755 0000000 0000000 00000000000 13777276623 021673 5ustar000000000 0000000 xmlgraphics-commons-2.6/test/0040755 0000000 0000000 00000000000 13777276623 015110 5ustar000000000 0000000 xmlgraphics-commons-2.6/test/images/0040755 0000000 0000000 00000000000 13777276623 016355 5ustar000000000 0000000 xmlgraphics-commons-2.6/KEYS0100644 0000000 0000000 00000065576 13777276623 014647 0ustar000000000 0000000 This file contains the PGP keys of various developers. Please don't use them for email unless you have to. Their main purpose is code signing. Users: pgp < KEYS (gpg --import < KEYS) Developers: pgp -kxa and append it to this file. (pgpk -ll && pgpk -xa ) >> this file. (gpg --list-keys && gpg --armor --export ) >> this file. pub 1024D/8408F755 2003-01-20 Christian Geisert sub 1024g/41D98B12 2003-01-20 pub 1024D/7C611584 2005-07-19 Jeremias M�rki sub 2048g/C0F1AD34 2005-07-19 pub 1024D/4358C584 2006-12-08 Vincent Hennebert sub 2048g/0BD6AC9B 2006-12-08 pub 1024D/CC31AE97 2008-03-27 [expires: 2011-01-01] uid Maximilian Berger pub 1024R/C93C5700 2008-07-12 uid Maximilian Berger pub 4096R/72FA275A 2014-07-22 uid Vincent Hennebert sub 4096R/EC50D2FD 2014-07-22 -----BEGIN PGP PUBLIC KEY BLOCK----- Version: GnuPG v1.0.6 (GNU/Linux) Comment: Weitere Infos: siehe http://www.gnupg.org mQGiBD4rT6kRBADPozVPJAOKLqcgtnGFHj0Qav5OBPqjTprJji0BgxPrcZLZQFUO 0AmeJpzwgE0vDISx+DgGOKPcqeCLnSqtoR3rYc5Tf57FPlZ/E2/fzMwC0soYzJ6e E9uSsXBIPeeRHcrxyCYJx69g2D/zS2vGnAIr0LYLXhadvChK1zngU0pFswCg5z0a TjCH+9VWzerOLaEQYqVyGgMD/i456FFD2lWes8amcN+wpBLSpxysyrbu1FOZ3sVi MjYsODDeLKRB1Cxn6UMx7WE+Av+UhtoJkoTsvcGBtkj+rFfEav2WmCsYDvLwbqpE P5Pun7qgXbznbzCqdNUavXM0goBQtyFhtGkJSoOVXM6H5raO3THEPXU971gkOC9+ agZDA/0WdV3VumDwi9DvII58Fv8K5HKxkZrLeUWAYJzgzeroYgfvuNKr/SrAFuyR W8XxDMPMAMvO1qKUU1Zjffx6RUjeiptmF4ozLvU3I/Pr6atWJL8SPH6rrk6xDpZ5 Ev/we0MmRU5kk9Y8KGavAsOjbMbTv77DL2AZ8qapUQYqfuuiR7QlQ2hyaXN0aWFu IEdlaXNlcnQgPGNocmlzZ0BhcGFjaGUub3JnPohXBBMRAgAXBQI+K0+pBQsHCgME AxUDAgMWAgECF4AACgkQc84u+4QI91W/OwCffMPR+FpADYlte9AabXRuzomhdh4A oNvl89kJdg43/nMw5CErpMvMFNjVuQENBD4rT6sQBACr7d7g+yOPuYaFeS9+wXlO vz3gVWZNUOPalrJwWPQ2yXxCzEd4chpBDUsq7TusEe/RCSUuSQYe0FAET2der4Uj 6TJPB7SuJos3hrqsUQOluoEHS8bCPD7mpXIjd1+tQu57jxgcW4/VnEn3/c57blgY V2/rpAUE8nDRPB1Z8oveJwAECwQAp0zOTs1ehN4MFzy/3T1xO8HVN7LiaZSc4mEs oyIcEcD3iwxJqsVPmJLOfP8fhuqyv4QfG+7gdNBZqji5WTUK2o1vYgnEbvsnGDst Lx9kwaWCalGMXdbuEzXoheX2JJCeP8YkPQw/r9rCeP0jLXExU3B6RJkDXBrZB7L3 Jdj2mxKIRgQYEQIABgUCPitPqwAKCRBzzi77hAj3VeUxAKCJXCs0vrCcfMSO/2M/ Eq/rMruVPwCg34SJtFP5wtlgHa7kdhBLKoenD7g= =+cef -----END PGP PUBLIC KEY BLOCK----- -----BEGIN PGP PUBLIC KEY BLOCK----- Version: GnuPG v1.4.2 (MingW32) mQGiBELdQqsRBACPvRuWTsO4Sv95wSFzaMJcSJs81b9lpAT4BKsi3K/1y7pcxTJW IKP5Khc6cOom3nnRDofEh1KcLnvx+X+A+WF5YF7c1qd4EG3tWgjzqnkT9NUsw6t/ 3yAHL9iHr5nB7aZuiDdXgsLL5F2wNjuiSrTEDVM1wSm+QLuqqJ2lSJOcCwCg97BA yyX59XauxdQNfF00pfYIW3UD/R2TzMD5YxHbCO2Ib3j5O2cJU+G56q1krLwFKSzq XsiKOh2+8Bvwj2bBlQ6uYMwZc08WOgtiG3uRMDsdPE3JIoDogIguuADzO1LFFoi5 mAEizqCN+8OSZ6luVeznUKCObF+yJvqJyG9RoDgv+v8KdqVz5NZ2BdtcY7LxHGKI 6k/LA/9WH1p8N10GETyagzNtU1tDMZGk8zB5C1qE9hgMDr5iRKrFuGnwBzMseKOj nQ4tPW47hWYeXLaou6JPTRhGP0wITnOoYmcP5ymgOPZJZwARfC3qXznrdOAmL8D2 x+W7DP7ZtKPCYDa0norSEq3VPSUWjAjAPvskgiN6u6Y5/0J487QlSmVyZW1pYXMg TcOkcmtpIDxqZXJlbWlhc0BtYWVya2kub3JnPoheBBMRAgAeBQJC3VVHAhsjBgsJ CAcDAgMVAgMDFgIBAh4BAheAAAoJEPcwlXB8YRWECjoAnA90rdo+Ob3k1BOMz5cK PaQZtuuiAKCHOPtp1foBDjGPBA0FR9MtSCmMLYhGBBIRAgAGBQJC31YgAAoJEKIR WuFfa4tyKSsAnj6YCONElnEDA5vaa1lJES4UcVAeAJ9JG4bXlEPUqyBPhOtvetVS OWtNGIhGBBMRAgAGBQJC7u6uAAoJEME58VMjy3oqElwAnijYebpmsWIw86ilU2Zf epTWKSt1AJ0cMQZmjm/WrGI68rCRcEL7X2wTOYhGBBMRAgAGBQJDK/iDAAoJEDf2 j/UBWvyKp3YAniyZxx/ee9g7asY2AR87yAVWPRjQAJ0U4l3dC/8ugLmyE7RbkFqL iALoRLQpSmVyZW1pYXMgTcOkcmtpIDxpbmZvQGplcmVtaWFzLW1hZXJraS5jaD6I XgQTEQIAHgUCQt1VXQIbIwYLCQgHAwIDFQIDAxYCAQIeAQIXgAAKCRD3MJVwfGEV hNNHAKDkYf0faxpqpmnwtFNeFETmTqd7HACeK0jaTfp7b/VhTlFmF+cSkrO4lK2I RgQSEQIABgUCQt9WIAAKCRCiEVrhX2uLcpUWAKClQPvTzFXFlDk/nDBa0wxesi4n qwCfWiXArQAoIm/hG9zpK+h2zHwlYg6IRgQTEQIABgUCQu7urgAKCRDBOfFTI8t6 KpDiAKCCPK5ixmDxrKvvIKnx7hofZ0LiAQCfV6vfRmuVmfWo2LMMaa9xw5WBtUKI RgQTEQIABgUCQyv4gwAKCRA39o/1AVr8iqV2AJ9sBMWQ6YjZHIfBp+aoo84EI/Kg 6wCfRDkrpQhjpeSM4DPaRiKgL1LQrVm0JUplcmVtaWFzIE3DpHJraSA8amVyZW1p YXNAYXBhY2hlLm9yZz6IXgQTEQIAHgUCQt1VgwIbIwYLCQgHAwIDFQIDAxYCAQIe AQIXgAAKCRD3MJVwfGEVhAjAAKDme5j7fzFk365pOZm1lJyEHMJuPACgspAO3iPV 7G659xb8l8IQQIZn18CIRgQSEQIABgUCQt9WGAAKCRCiEVrhX2uLcirOAKCwgb9x 2zr8Q3j7KnD9XSgqrwv33ACgzcUOgabzbXlJWEOiW4d2LIK4zjyIRgQTEQIABgUC Qu7uqQAKCRDBOfFTI8t6KuNXAJ40TlT/Goa/tV/5zL+ZH6OdWjTImACghZxdWnD+ CLZORMpBFYUlUKffSlWIRgQTEQIABgUCQyv4bAAKCRA39o/1AVr8iv1/AKCX8NY8 nffFDHsck7SMPWdb8toSvwCfd0Yf8OOYq3/O8JidWNpnNTAZabqIYQQTEQIAIQIb IwYLCQgHAwIDFQIDAxYCAQIeAQIXgAUCQt1VmwIZAQAKCRD3MJVwfGEVhOZyAJ9G J6pU0t9yrsVkuHcAkhF1YG6RDgCdFOb6NohfGeBbOraUGdQvKwJ3J0W5Ag0EQt1C vhAIAIhBOvTiliy95oxWLplZzCiXq6Dm3lYUOhDxmioKavI6KH2FzdnrHHvz91ES f7tGUNizHQyv4+zSAv8B8JmKiQ7Tk6DL5yJjZ6otwyOuR0ZIviXZwYirT8lOO4wP m3oV1V6Uf1oIwZQ2Y1fTFO4+8UPlTT0IUNMxuIIbvkRSMup6FIFGDoJQ/IYtBB4G 4mo6DMilyNzDiaqJ5k+iSY/GcCIzdWUd7ryr7344DffnJHg0CDynR/gpISWWj0sf YCnjZJANrVGV7O5WnKsVKqzTIRfJKSGBoB1ekvQ8AtGq1X8DfGgKubjlzGjCNbeW YiKNEa/M4DOAwhFzvftGueuzujMAAwUH/1+A8nfA3YgoG8wGPifhXBrB5aUx5I12 1akJvK4KQaIFE3dDRRYtwQHp0EyKB85z3lTlmdOupE5oKHd3ZYeeaQSUnt5i+dtz Xxz3RLBB6NYlcYJJyqSb31rTAMoq1iultLYbH+ugK/kUPTIOslvUJ/q4J22NJ/wS aIEqBlz/RczCAniNooQ/2ie733MpJ6NfROGIiOrNsRlQw+7P9TOmB3FxKLtzIunD F/Oo/4vznSoaVSUtVFMCKM2tLLbVV2LWBm9ztakfOXwmV0aoveAZ6a0J5+9RbC82 HJW5Sez4fLZxK7tENCQoscjkjM/xfsDz5mz/8JF4T0tLehUjKrLBlsaIRgQYEQIA BgUCQt1CvgAKCRD3MJVwfGEVhD0+AJwLiZ/2jUDCKVngO+lqNscX8TQ0LQCeM4DI UKHCLjnj2UtX8OfockTGIic= =1nMU -----END PGP PUBLIC KEY BLOCK----- -----BEGIN PGP PUBLIC KEY BLOCK----- Version: GnuPG v1.4.2.2 (GNU/Linux) mQGiBEV5mbgRBACBd9xGOGzs8ah/N11zlDi8woJUh02EgztXdMfij4F3u12DkneC OIwGH14fWHdkhKjwYMi5LQfvBsnd3P5v5PTBxYati7ZQDDjvYsAJiMXbyUdszdyQ ig/UuNMwdB5YBrdtklzZcOuiNt/yeoocURQRwkwklsVBIYWwovcdXLTRWwCglPVQ 0NrC7VPRPTgK0Y1wxOgwzj0D/RpwFEAcl1SJHoOwhwKykNzA05YABaxXhksKi2qQ C8M4mUofqweU3ocU0tBqQAR351n7hQWAaIs6ScOQtcKPJj9SV8SQgqxwj7WfHscj 9X3lkP6cxstW+W8SblTgrKwl7JLLkja1u1cNUeD0QzWImuRBpOjh4s97ZFwSHRoH hCLgA/4/GDXbOhC4Wi9i8HHQNhEA6l86ZBteGq5u4SW57cK69mnOGj8iBxenIWeU +NuB/LqVcG/75JnDvVGImvoykCBEl9xASNOj1C4HvBwNrU7iIpvRig1wwHK8/wqU Dhq5433rh40YbOfN0PLZDhQNhf3MysP3ipTZkVdwIKhsvl/vibQ2VmluY2VudCBI ZW5uZWJlcnQgPHZpbmNlbnQuaGVubmViZXJ0QGFueXdhcmUtdGVjaC5jb20+iGAE ExECACAFAkV5mgcCGwMGCwkIBwMCBBUCCAMEFgIDAQIeAQIXgAAKCRCgctTQQ1jF hH7uAJ9BFRNMuSpvSq//lEWLc6WOTMW70ACghjA0jtaMQUVjDU3RUOdGMRkqRZu0 KVZpbmNlbnQgSGVubmViZXJ0IDx2aGVubmViZXJ0QGFwYWNoZS5vcmc+iGMEExEC ACMCGwMGCwkIBwMCBBUCCAMEFgIDAQIeAQIXgAUCRXmahgIZAQAKCRCgctTQQ1jF hLRSAJ9KgHLa9V4Q2k0NFiMpPuhfnsK9bQCeJbGjFdIgrzyIvYIUZUPQGww597+5 Ag0ERXmZwhAIAJhskbWZaLuwdZ3aLqVimVu65bR2ve1U28dfsSVCKx0uYCl3YJkj lF9P3BfMMPVdNRqDz4Agz/Vrn13j+p4ZQQhVhv6IGhE4p4T4RebMaZ/d30/6REls DP3Luc9IrnJbA72jSeXt+vI3WysB/wuJJ/kb+3KtFa1NowwVVypHCiSmme0VCUaR K6jlN0245IpR0IA4Q1VziRO7v1VufZAef64/2U2T/IthwPqDoThNj++9Zg5Tctrt TL02Z++n2Nj9bQf9R+FhA3YhvHuf6OLAPE2emcM/0As+JwBHqcMrmybnrxEJg0Aq 4Q1k1Ka7beb35QJ7158rzL1PU1V2totLeW8AAwUH/1NJVnMD/p4op2kbJYMgKSqz zZfypt60aWeImeJ2qZD7FAtsz6KQu2a5ZkcVmyCeuAo9Sj0IqxXyn8Z6bHuHXNe+ aidjS+n5kc2Y+5RQ1oMGV+BzXQMPGOgh0ertbLaairT7mCljTEd4kUGxOIcfAh/q Ie+p7Guvw6+T4K7hgfY8bAiVgzhZLWIFTQXpjU+91q6kTt4eIWjdCGdNQ/OBezGY f5SCy0phzTmRqcu68nKaLznwUpI7SuSFSIeVemGz602KdFsLEHHbZE0KJgd6aHYu ynK3sugKIpz/NXpT2vBsVkK6EP5xzWYOpqMGb8uQD8CT7loY81SK+rHBm7dicgiI SQQYEQIACQUCRXmZwgIbDAAKCRCgctTQQ1jFhBc3AKCQ1X7oIVR8g7GvSGEUw6DE HgEaUgCgkl30lcl9gGa9hqk4cuGYn1OTyks= =XphF -----END PGP PUBLIC KEY BLOCK----- -----BEGIN PGP PUBLIC KEY BLOCK----- Version: GnuPG v1.4.7 (OpenBSD) mQGiBEfrX/ARBADulGs9V7StbfK8CFfClihdh4lRpw2tktMuYiQJ/rIsNq4zghkT UGxFU0eUC2ZVPYvwG6sXgZ5SSm6i8Ii79YdIIxUG7oNwXaY/e9rK+xX193xqmDgl Vh5vm4LUtncHi9TZDSF+g1YU1DVHbSjTd2oQEHxbBppL0CLfaLv3U1qr2wCgxeGw ZIwb6KD6yesRLx6vGDkDzAMEAL99p0m4sNnjZdKC25Rrt6NZ7CROXWs89/+dkewg JCZiVEoAcdSa0z5d8+XaSzmqR8BJWM1PBPjG48eEdqOevwypd0F/U1mwZ42MvQEw oBayUY+7/pptW7C5L3Fjk18drE0a8lIzt9VBGX5fe3GoXtZKuOzDv0hEuHyzR9q9 JLXsA/sELFfrHf0tBfXAdE7pj/Mahalu17/GAyb0RHSvuOfoUvXSXZA91cFg8ycB 4x265NtYZk52M32wi5ePrYeSJIZ6vWRvPuWVAXDg5S6HCMjcXc6ElkgLcUt1NoPI DmRXe4FIDZkGSYSXdLTUByu7+8fCuWQHCFG2sALdOyVlucij2LQoTWF4aW1pbGlh biBCZXJnZXIgPG1heGJlcmdlckBhcGFjaGUub3JnPohmBBMRAgAmBQJH61/wAhsD BQkFM4sABgsJCAcDAgQVAggDBBYCAwECHgECF4AACgkQ4+RAT8wxrpcs1wCeIAoI B0MwZfWLV+wD3pt1wDkPXbsAnjuOsyZ7EeNOcpoqSteB17aPRGeLiEYEEBECAAYF Akfrb00ACgkQByq3OugVkrx76ACgqJ8W64IhBYgBvp3dTDLS825gCQQAnjB6X5+4 eW/0pQUpJcvolxbT9xvF =bbQO -----END PGP PUBLIC KEY BLOCK----- -----BEGIN PGP PUBLIC KEY BLOCK----- Version: GnuPG v1.2.6 (GNU/Linux) mI4ESHiTQAEEANXyMbT/YZLUQoG2e5bVl1OcZ4Ttpt+Uk7KfZd1vehgwkr7VOUT5 Y5JZ74mS/XxdG3JoSI5AF96pAxEl/xplqnTXtR/ZG6IcK7BZPblpYf4l8zB+M9g0 QbTphAAiYeWBLoDWNZW6jiicsQ27EZmGgotcJ855t1x3CbEey0KpmEeHACCrR/j3 tChNYXhpbWlsaWFuIEJlcmdlciA8bWF4YmVyZ2VyQGFwYWNoZS5vcmc+iEYEEBEC AAYFAkh5tUsACgkQ4+RAT8wxrpeT/gCgvLNl0Ygmq8vBSdu6QXRzrWzQqGoAmQEq gEXNzkIENamBEmderAxauC8HiLYEEwECACAFAkh4lMECGwMGCwkIBwMCBBUCCAME FgIDAQIeAQIXgAAKCRD5iaLlyTxXAJlABACYHTf8nSIv0wR57ApHmF2AKub6OKPs KBzHP0/xQKpJ+75suk/0CNL7ve5RknHZ9f202DBQ1UOE2ibW6CbXokuhLPQHiWcD h/LNjn/gIB8y8yIr64SNX2u6563ZKhs2p72BTAJRquWdIwjcg6sXeWbvY/B7AFeJ 14v8GKWL3YWxQbiOBEh4k0gBBADGhb6pch9zGC9pGDPEyOujwXK1Iq9V7k6ECBSs uzANb8GCAA+xj+jna20Nphnckd7ZMkiNyd+GD2fyFGL6BvIMGQZrLcuOK0yCkZqN SVZ/Tk98u0PaaFMBMh1XwdCgn5NKtzxBOZ2b2klBJlI3Rr4vBUqwe6/mytH96DfM cP5KWwAg9S7R24ifBBgBAgAJBQJIeJNIAhsgAAoJEPmJouXJPFcAFl8D/i5vkJOc O/x3ANfQE/tod4DVo1f5+oEULBZOrq03M3bBAQOqe41hvlmrLjr0gTcKAwBp70w4 iu/YXdirZTx9eTRMhnMS7HRJE2Aeui2eE3adDQV0hl7MouOgdWidIAQC3H+sNwT2 rvqbxAg5UkH8u6UUGuMmtbOteaHArPDrujg5uI4ESHiTVgEEANRz9ivIoA1WSH+4 Sr8QhhFMn/SUit/o403tAhCkIRJszvzIfelTLQzv17jBgNiVsnxtOtY+dIJLFfWS cJohYlTEnLjeZeeA8abQUMjXpuKc0jUxspaHes3ywB/dcTAUZcsKxLboVT/X9S6j 99ErdM4Map9KOVgAzPGZLNgxLcq9ACCUGpzdiJ8EGAECAAkFAkh4k1YCGwwACgkQ +Ymi5ck8VwBjxAQAhdcrZG0Q4LIk0d1RewO5dGua4XjqwyyhYuzHjs2X3Bel62bW oK46DpretsNxnP80m79leHQOJalTAW2jMU6KGdLvlGaaaaZ0aAcxzeRltBsBWwe8 9TdzBiO/eMiU4XB3PW+cjsc/gN/T4+hcbculNFB9skt7ODV4JHu6EZdSLmO5AaIE SHm3yBEEALKRSNJ7OcgSRHAEDGLj0KZuy2PxMoCtUl4dPkdnWlcGe57j6l6PE5aW jK6lxKQ10i7J4KM5kOt4nudWCmxD4SzSiZx7O7md4PgLypzDG3nDvPImS0Yu3G+S g1oZ5bksqjd77X6f/OuGUl3/gOpo6IejlaMy21ixeRPR/8ZMl/OjAKDLontnXlp0 y39oOJx+tQ8iWIzzuQP+NOqKnaO3aHnRE+Balyw/TpBpX5NnufgCFr0Psejf2fQz xTbPpny7CsmMbMJlPHXE+OZ8mSy8mdryUIFy8C9bwPe/6iSsv5rnZ6JWJ2oRc8qC fI38oSepEHTtHz9PhgaN8RNCqVyomuzXZmfkrcIVitsq3KVFTw8HhBA1Y/mHFjME AIW1VSa0Pxm2eHCCcuieqa8zVtg/dt3qO5bgyyR2qCvA5xuYLrnTRYiOkddw9MQx Zz5ZB2IGlF2jAyja+zHZqZAO3NiepvZwjo9zhQKzacKP/w94C1R/gL1V54/7p80H ySRD1JolwBjoYxdKFtDj5HoJ5rC3jTbWY3l1AQQMShJxiO0EGAECAA8FAkh5t8gC GwIFCQHhM4AAUgkQ+Ymi5ck8VwBHIAQZEQIABgUCSHm3yAAKCRCmAuWryUxvA7AE AJ9jajPUCTGt3apXlLI18VFpxB8yCACdHKZcZ1JoDN94BVI2Qyt5SJ7RKknmMQQA k6cWvEftN5Q94VOMjPuFOcrOvnjDGJkh4GgpbfSCLBTkX/nqus9iOMNYjHLL5pUi jWEfdXJUenPfo58avgTzvDtF1EGoTw8ykzbPUZ1+CmekCt1/NaVSSY8+8HxS2FiE kZoXlf56ekQOjeoa01Uo+MLc3aLBnFjW1fWAQmocRfC5AaIESHm4zBEEANrn/MA4 BglSMlASTsCEnVJZ7vQwZYuQfxxCiGsjFckBWY/D4Xm+RB0L4y5bOuqNeAc01sb0 +2MHpBqE1Zeq0nLFfTBACKH5GUnWB6f4T5P613Yjo3kR17/WSb28FnSQww2sP9gW oSDoTn1x6iNeXh2waXW9WJQoCZHUDfkT68OrAKC9nE6MeuSPd+PNhAfBcR3S6SOd hQQAuTmpLKGqx2auUnwDAajM/RuDCS1lNCAku2tHpvqSdDb0xfyLnTNwbjHG/cDX oZLx9CYEoNkxQmlyUfg91/64xXjskbs7aTRV4tERV24duQnNXrWvQ2bfJeYxWNrV VqlSeGokL5EYe7AViMwi+uLmDVlHjtxASiWaqqxIVC3dLXEEAK0F7bdFvw3RnPGT x+JJV/5+L8mbTFdfwvWVXuN8oDkgAu9PkCLcAuPD/ZYsaZDic8MkcMbo5dmbH9+j Qr8pft0pWJjueAj77zmETGKohqsf6LGRc10FAFF1E9zPFS8hvqdI9TfVBlxdPjwi pNisGmlYsIUBqnHvrQva5L0sEofziO0EGAECAA8FAkh5uMwCGwIFCQHhM4AAUgkQ +Ymi5ck8VwBHIAQZEQIABgUCSHm4zAAKCRCOHjXGZ1Q1G9DZAKC9K0qtWQE6CVic IV659tdM0rZzqgCfaOC25bYAp4ISZBo+HUH6zJy51BDMzAP/TyqD7Fme1lwF2dWT tWcUInqOwhLX896WaH9Y5NJYe98MNpQxr3wizYOwdJa3t9+MVvH0+s6ih4aaJ49n 71yaef7YVkZ+0gbdKrOOrILwPg4hHizMKKDGbMaJ1OTJbE3PjFhEsdZRy1M1wjzX Jysr6rop4tOTfXLTX7m5hXkfJ/k= =soRW -----END PGP PUBLIC KEY BLOCK----- pub 1024D/5F298824 2006-09-30 [expires: 2011-09-29] uid Simon Pepping sub 2048g/40F32100 2006-09-30 [expires: 2011-09-29] -----BEGIN PGP PUBLIC KEY BLOCK----- Version: GnuPG v1.4.10 (GNU/Linux) mQGiBEUeNZ4RBADSETFxXTVUP98ydSQKh6gEkS59JPaCAkeNbMeM5VBK6RcVvjtK zxadtIfcaFx++OCkABCdWnlIIVhjYMMYVV9h3DRFVwYEp1LZb9ktU+PxIw9kI75+ eNMsxCpvYBvw9nFyHFPAdtnQPNpMSG7SeCNOHtSuErACuxOuo9JpwIWNwwCg469m S/sca2kkmYuKqrWXD2cfZdED/3awMvn3cThlTsT0zqtQjuGBJjH9bJwiRdvNpU0M cxw7xC1HGtfBYVQd9XastVj1xToDq7gCY5+qoHXLgv5BqLwecadtjuKEF4FXAmtN 1qmz9sAVlYsnA4azCADyLv0A440Azbzg9ruEBAf1U6JL6BtpKuLQ3RSCrYicO3Vu fHJWA/0crJgn3GTDtFegMTDtlLvBcRXbsKBVAddbew9WOVfcTo1x7r71iziJZtgj o88pNLHy6IXWvZr+VvB4c0V5U0K7eB9B956G3/t+1G8lDfuzVBqkSqAQXv7XmIWB r4FIBMW20uNl8LO3461u+lDpIIXHZrucPmpHxrcFrzVTxknWqLQmU2ltb24gUGVw cGluZyA8c3BlcHBpbmdAbGV2ZXJrcnVpZC5ldT6IaQQTEQIAKQIbAwUJCWYBgAYL CQgHAwIEFQIIAwQWAgMBAh4BAheABQJFHkuQAhkBAAoJED4qb8JfKYgkvcAAnjXG Sg3CFkDVdHQNA8pURERLc0dkAKCx583xMH1Mj6Bicvu2Y6YBKBl03ohMBBMRAgAM BQJFIm1bBYMJYcnDAAoJEPcwlXB8YRWE5ykAoJHj4TgPp7PrHQBmvcU+6iUN9Iba AJ9yP6eQoewU5K6z3fgH533MeNJZn4hmBBMRAgAmBQJFHjWeAhsDBQkJZgGABgsJ CAcDAgQVAggDBBYCAwECHgECF4AACgkQPipvwl8piCSi+wCfbyubA0KeYeq81I21 8k8EZBeh8hAAn0jfjHGnPRjLkTMntXKn5ecBMHl+iQEiBBABAgAMBQJFHkebBQMA EnUAAAoJEJcQuJvKV618iBYH/izt6qzYzon3wLNQWdsNpPE31we5HQK8dV1Q9n+Y eVBkPOvCJdFmIpWZ0GPzIa5c3Z5BUJ/Jl218eOOosmSme3I4Z2iWRvXTCzwxM7Ns AR07jsRtnpf/hwyyQsLM/CXC+XQ868/2CJ/a9BomBbweQ4uLX9YMfJaZfty+TN8p 2Iw4ScluvM5zghYC9OYRNPtxGGpWwxiiz7XGxLvcDMzGvpq7Z7BT/3D895BAc15Z LOLUTgGmPJResjojlPuf8cN5IgzKbr3jb67MwFwa+p0kwMX0RxSmFSu1PciyXgsI vLHqIKq97SX226VReoojLXVlgH4692BAc8NDLmuhOufxCU6IRgQQEQIABgUCRXmd sAAKCRCgctTQQ1jFhI/HAKCBpbQJlBCg6c5pCpQA0pbWJj4H7wCdEn4Tp6cOL4om Mrn+WcndhYQV1VmInAQQAQIABgUCRjoJCwAKCRCazTzAqZ913b/cBADPHk651AFC fjEyV9ag281WhylVErEOEbnKuftRGLQmrR7DwPqbESVMBbdfPOQGcTCtaL518W0J A1nyF+0CR+VF5Ca+RVR7v5eN+EXaUYkSvEpGWGRizLZ4kXPC34MVV1+HWTO9hH0W 4i/9GYeOmtN1h+EkObhKvPpQsKyQcKuDnIkBIgQQAQIADAUCRjUVOgUDABJ1AAAK CRCXELibyletfAVHCAC2d80OSi18/Q8eohrF7GGz3LpOs5pJlV03t8Ym0gpeUj36 8sH14vtIcy4Ris809osV4Qwb1rHSdesTXcEmbXqp+DyGbny1FK0AqASWU7jx90iC eR17kHKQzKfXQzO8GLic8nM4baQoJc/G1hhNYHhv6e1KR7jjurIqETFsP1ilAjBz cK7WvPIHTKVNJtPE/JVPMoE20oM0AhbVTmqNuIezVar2LRnHq93ug3SO+p0/CJ2n KnJy5uXI9dPwmEkwoHvlfYygcCMlFMyWJdbVtX9Oip1LWCcmk0V3Gyzajx6gQ3Gp OT4Gm6I8DmdJ729PexLzB6REqseGewsbZGVbcKF5iEYEEBECAAYFAkY45HkACgkQ FUWz/uIi3k/4hQCdEveDkhYCwUZANCdt7/YnNzrLd8cAniY3rgKN5iADh079Y7BV pz0DGDNniEYEEBECAAYFAkY46RQACgkQY9CtrpESA+RUMQCffDDmM06WKNy6UtK9 qZ1vuqxdaHQAnRi1+tt0C8AVxHLmrc8xJ4riWi8yiEYEEBECAAYFAkY6CQsACgkQ UI6uxTAtpWgkPwCglCV6zLcE6W5eWHDc5iEe9ZbmOuwAn146k5PkdrdDbZmxOjnS 5K5nPoWyiEYEEBECAAYFAkY6CQsACgkQ3bpkuiwxLS8kPwCfWLpuiJrau1qcSBG5 NXykWDOr0gIAn3aJCWmN+CGA4r34jYNRGtacXWlhiEYEEBECAAYFAkY8ymYACgkQ mHDv8/EvYHJe0wCgkB0m7in5++2gZcEmdttG45hfTj0AoI/ii53ITSPefqHmJQzB bals0Yu7iEYEExECAAYFAkY5GTYACgkQ4eHysJkO1Kq8GACeN5/Y3yzwehxoJGZh 0JKOg8hvwYQAn3ovqhb6frS9LpofciPlQqMvXSWFiEwEExECAAwFAkY8T/EFgwhH 5y0ACgkQTAQoGDEaPeXlSgCgtmGBnRIe8S5K3IpqlcfCAPdPxvUAoJGBgJHXg1Im UshwAbwteZkdQVGyiEYEExECAAYFAkY9pHAACgkQLrlGgoiBdAJNogCdE7iG/eKK O0VEFOSqQDYQ6Sng3MwAoIRMfBXZxir7htM/oidQDFkz7SJaiEYEEBECAAYFAkY+ FAgACgkQAqWmBQt+bPrp7wCbBFHuKLDk6eRA0W3gdvyif6hJfVsAoKxSa6CAW8g5 WNR952HrF8ppI8MciEYEEBECAAYFAkY+2+wACgkQVCINLMh0FVyfjwCeNCOwfFse NsdCgcshIX1bY3l4h6IAoIP3umLxOhE/yV5iS6FQHwa30zT5iEYEEBECAAYFAkY4 ++EACgkQc92MFgFTAjX0lwCght491w1RhqKIwrav3K/fXqzKr5QAnRpvWtad3/2X 00mgOIpCrvKY/B/kiEYEEBECAAYFAkZGEngACgkQohFa4V9ri3JOogCdHeVASK7A nKQRtmieDzqKl1lChgIAoNqpkJ3VEyl/WvoFW9An/lHSzIC4iHEEEBECADEFAkZI xWEqHEhlbm5pbmcgU2NobWllZGVoYXVzZW4gPGhwc0BpbnRlcm1ldGEuZGU+AAoJ EDKGTkGchSIrOG8AnROvc1A0G8kgCdUWkJMC2XSwMmh9AJ46ANKYC8natSxqozxM gW7pOccPJoipBBARAgBpBQJGU8qlIBxTYW5kZXIgVGVtbWUgPHNhbmRlckB0ZW1t ZS5uZXQ+IhxTYW5kZXIgVGVtbWUgPHNjdGVtbWVAYXBhY2hlLm9yZz4eHFNhbmRl ciBUZW1tZSA8c2FuZGVyQG1hYy5jb20+AAoJELK+vEAVKSSvaB0AoNZvVKqr44P5 +N2O67pg9raBEK1AAKDVfaF3I88KgwoxhVT9GI2UzjVB3YhGBBARAgAGBQJGPypG AAoJEPXCYBZM7tdfs9UAniR2tRh8h7s7RflPT6lYYm5qzFWEAJ91ffpU1A53yRVR +JhZejmuCarVN4hGBBARAgAGBQJGQL6SAAoJEG0LxzpAWBg3TucAn3Ae4QnaEqhe KEHP/equWOPxnWmrAJwLv0enRtVE1Db59OzRs0CHmf2cRYhGBBARAgAGBQJGTEbA AAoJEB8hI8Nr2HKgjukAn2gKtl0NF1OBdA8xqneWJPIxVircAKDRQZjglFLJLBez JQz8MnGJ/G7UaohGBBARAgAGBQJGTIJCAAoJEA9FCiZiEL/Ao3AAoMOpPKpPGxJf 1KvbnEsH8v3CQN+zAJ9uUKEoBiGUxisZZqHXXd4Xf9G19IhGBBARAgAGBQJGUne3 AAoJEDLB1u8PFDvBQycAni+fIPBFC36EF50yne0E0rXosVeiAJ9REycXBtugmf+5 MDRR+fCgveyYYIhGBBARAgAGBQJGUnfBAAoJEMuuvjmkbEyhT4IAoNqs2oGq9pSa kOh1jRMjbBcs45+WAJwPrhkv5v4d1AXR/BHkFv7YAOE0nYhGBBARAgAGBQJGXt33 AAoJEJqG18zRqupg020AoOpOpYtaGLZtLeKRFT1Cxv7jrIKgAJkBy1XCk3eyk0l6 JPhcTMjeF2YEfohGBBARAgAGBQJGXt5SAAoJEJqG18zRqupgMMIAoNivpEP5OOfq ynsSlqy5mpZu5/NJAKDZZEYMVmnlbYIG+lq8beNIoOYej4hGBBARAgAGBQJGXt5b AAoJEJqG18zRqupgQMIAn0n53SiM2QT+Pyh0Abg/8N8th67HAKDvh31p6Nbs+Go+ E34KkJhystH2EIkBIgQQAQIADAUCRmpbBQUDABJ1AAAKCRCXELibyletfMatB/0Q 5EsLwryhcjAQUWrxisUl7Fx3JFv9txAr85yRirO6EmtjhfTjM1rCYVAQZ+G82PyA EWE5hAGqXAE75y2+o/PJZJTSsB2nCjie0cLhsuWh+epRcC7t8Q3jevV0Y0uobAP7 1q7jFIAaE5hSHOC4glfCVv5R9plHJBxGJ+AA+kEf6OSXmakvBTRybI7dNltaxs6s z+XwfxOaPwHOcKDtOkIgF9zWPdWaNln4CYW50QRo4u0GTUTJncUqHF3RQE3mRF3s K+FDhtDf1biXdy+6B0gROchvjiek6kZxBTsoKdyqsFyl+rRUloEQ9d8Kr26VRCZM KPjAav8ZKI5aI77IxFt4iEYEEBECAAYFAkZ0E18ACgkQ1TNOdbExPeJFVwCgpGSO XyEXyod1fLU3qZ2ZYU+lCvAAn1KbMu+gtTrDtkw9Rsw5cZ9AJttBiEYEEBECAAYF AkalUscACgkQOb5RoQhMkRP87QCfb2LvY177HP7ggfvxFJjgMoAieuYAn1kCosw3 DKlTqIe+gyc4P6X+iWmviGsEEBECACsFAkmMmbUFgwHihQAeGmh0dHA6Ly93d3cu Y2FjZXJ0Lm9yZy9jcHMucGhwAAoJENK7DQFl0P1YPjoAn1eJPt58UwBXT8tR5qm6 rHY0P2UTAJ9NOUtxQeEestgMuHjToiguxhP35IhGBBARAgAGBQJGrdMCAAoJEDPN ZzOvXsRSgQAAoIBihP4nHW05Og6dyCFV/eFYoOoRAJ4nA6H9GTZM6+tt8H2OlfOz aR9W/4kBIgQQAQIADAUCRzgQ1gUDABJ1AAAKCRCXELibyletfDF0B/90XPtQD4tu MovOM++nGgpk7MINP+K1eOIyidGFD5NWHdJGOwvsP+NoNvXZxsO2+SXF/1ucnR+v RWmTSa8VumiKN/zcfMwd8e6tzHw3vQUlQCkW9RYtxHNqtff6IEJSQSb+d7hL6WbK RuGckVm7jJLTY4mdBvgbBXJ9dyYgAe0I3tptGx/KoChT4mBZkUofNLefs99ODdEP rqchJ+tQ9yLeEXA4wIHQUooZUVueQgllymTv1QLg4phLwAsyRuvzkOBVIjO9uzx9 XNc3cN+Zodqti4aoRFwpxGDfkzSXw1HW+P9+dSqnhwfHj21dHGcW0TJdSZILINO0 nHsO+slRqoWdiQEiBBABAgAMBQJIEj/lBQMAEnUAAAoJEJcQuJvKV618CEAIAJ8M +wBDED0VlEJFVNYJQOLS0TKwThI7LY73vgU0XyaGh0lsNaLJSfDktdzweo02UhCw DgnnYFBQfitV5jLBHKHJsmHLFC7vLLngbnKmYG63bjRC6PTfNBCbOuaDyPEXxgAR 5g4z0tjme7t/wVAQgxKUJTfhAoXMK76y0RMlc0OjHCPs/L6Xn+jJawt7tKdIC5BY Rzy2R7Y7zas1vYhGjl7vlU44+jplAXSbmuXtdnRovvkxxc3x39Ej8CzPrSTeoa/I nWB55+C0Ud3zh7dsSmKXIU75ho/wOuDZbW+1l1pb9g5Tu6/lhGXlVs00bh1EjLhT MHg2zQcFVkMQzcVBsWu5Ag0ERR41qRAIAIhe8b/RLEnK4T9cbL4QobABV2NsnTPP 2DJFOs5YKGxz+7MjptVSvGVAbBoSqxsIjvSovlaTsKcXXGUK618xrbxhdIm2U/OO 9wAA8Mk7SSZdYnQxhgPeuh3t+qNuKlbZPldDhRn7+fcoOdXY+iGwGeacY5drfScL z6ALiahvNugiHyYFeqZk5wZbbYv/mJJZb5BTEeOcKU4JzU0VbCoui7KGmEBSM+H4 z4uyx0zCgmTz4tcPwi6uJ0fOUxtThaR/67YpYmTsEvf9deX3LUhJ8MBkn2/N+zqK UaYqZpS+YzJKjGq66Nmt21r7HjYZnXjN3CsgZQtEtnQK/+xVywbzdpMAAwUH/iag f9dLI9A75pbMgdw+t95nNDOjRAvfQwpIpkmqgkAlqtrV1nsuUsi8IJ3W9ZH5QIk/ LoWZ4gIDJ4ZtOmHzifurv0Ftvvp7MeoM5/Momu60wZfIeZloyy9RfymHCyr/A8VE /ayEZQnpo76HiyhjsmcIQIvkiK8gzGnLpQPchcwNTM3CiZ2Wc9e2wlJtp1/r60uz Lmv3m5iMms241FOfmxn0BnsVfFzEOG0uR5fQUXuanFAa7aGPxGticGi22mJkYhWO RLrKoDYnnccpp8cN3shNKZVLYrGAiLPtM2p83I830BV5rTET5oCM948ZtNxkXnWP ZAiIYSaFU+YapzevSpCITwQYEQIADwUCRR41qQIbDAUJCWYBgAAKCRA+Km/CXymI JCaWAKCbFrAAM1xAOda4Wkn+NodF2EMosACeOEChn8Oeu4bPGP4DuLJgQH0jpSQ= =geh1 -----END PGP PUBLIC KEY BLOCK----- pub 2048R/0ED3D317 2012-04-09 [expires: 2017-04-08] uid Glenn Adams sig 3 0ED3D317 2012-04-09 Glenn Adams sub 2048R/F23E86C1 2012-04-09 [expires: 2017-04-08] sig 0ED3D317 2012-04-09 Glenn Adams -----BEGIN PGP PUBLIC KEY BLOCK----- Version: GnuPG v1.4.11 (Darwin) mQENBE+DFvEBCACwHesM5hkZrlgPiq588FbZPe7QGtDRVdh0YbgI2A4Ky2odbFmA /n7lF9v+yf+FUn/0H2igwDYqLFx4JsB7z+Nvj+hwExdGQxuDaGSwMjjpJeEiuEmf b1Er5KYgpeFNm1MVP+r5kW5962O+HGIEx1xQ85AskNbr/jQkAg/wbbwWLFBQRMER PqFs1rXL2aWip8XtNPKnKBLPlFPn9a7glgB5Whgbls44KpR0dplAVoCWMnZEYnTA JYITcaDTCGFQI7aYgbj986RpS80o/Wcsnb8rjHKRZG8TaDr9MbgmmK39KwiJCflJ 9LvXR9g1j3addxgqEUuQBEtoLkWs/eDT/KQ7ABEBAAG0H0dsZW5uIEFkYW1zIDxn YWRhbXNAYXBhY2hlLm9yZz6JAT4EEwECACgFAk+DFvECGwMFCQlmAYAGCwkIBwMC BhUIAgkKCwQWAgMBAh4BAheAAAoJEGZUur4O09MXl7MH/jfeyE012/ABTTjvwvRw 2evD3cfghrZOQVT3PVEcVnXIcnVlmznO2DDs8aWXlhJ94ZnNdw8iKE8weK1FGXdd qWA7vHrOI1UAo7h+CDaBt0TM6OEM3Mp3+5baOJMRXyrjhbv74sj88HYRtoPhA2+z 5ilVNmmX4PEAc6wqt87ZfNQ2ZqX2YzR+OaT5OggSB12qU/uE7d4d0NcDozEKQFUP CMAuPJRNd4/J5yFy0DStfgsDKuUTir0oldlUElAjbhF8WtAgRwufIYuG/r4Cbuid Qc32yVAoy069ZcggwBpkzVPOpL2by1fzeSohjIkntDIL474KuSSoBKCuw2nYxpyw b0O5AQ0ET4MW8QEIAMFUAScm2Dw1fmBhmKMVc0mzqpR8TvSQvwJLiXRSP86NI1zc DtuiXCFfNZykOifFk50otMH1hd91hqeQ6HfsxxYtXLg2UDHG2gTKzlWefwA+1eFc M8fz/oV0CanGjqaOd6VZoYeg+LSD6YgrJZVjuoxNN/S0A9fNd8B3CXsG+92udkkW YMyiUpD5qjMEwcjmj6ITX3M9VLxDCKKhYwN+u5wokuAk3yKtvBpWhJDQbaJcuDaC rLH788gFybZDzyJ8Ug/95peV9Z57OCjMJLtn67ES7fB544EQRYVmDGnX5tTo9sYj 0bDjlbKX9lqS1sCGSezPxYxGgeXlnQrt+Sm+gd0AEQEAAYkBJQQYAQIADwUCT4MW 8QIbDAUJCWYBgAAKCRBmVLq+DtPTF2YbB/0Vo8Xr9N1adqlY1UAofvo5AoXZFxFJ jkB0Eb3z1V3iSBh8P921LD0gUQz6JXptXZPVGnwgm/44RdqXC+kX+4MxiVBtNAHp 0ODjIXiabBrixAHnT7EcAJkWue0RP2J5wiYKklwWFbEetjl0QSmitz8Jh33eA76j kFYW+vgKUMA8UrJ6j2Hk+vMFi0Odtntbc7AXvLifSPSmSztNe/Mws69EbuBph6bQ +zSmTQ6nt8PX+v3e0PnkXdGD8si9H6hj0K32pEMz86ttSnAtrhvsAdKPYOkY7/JD 0Bl+bnb7FLxJjJGlGuO/Rn5SIR3fFNQGrE/zl2wsKtftUXse6kkZSue+ =XDBB -----END PGP PUBLIC KEY BLOCK----- -----BEGIN PGP PUBLIC KEY BLOCK----- Version: GnuPG v1 mQINBFPO06wBEADhHglUaaLI6Nk+CUkpKMRWtVScsljRTmS16wxTdJ22kHgzkVYq jomMDI2jAs0Bx//ju8Khsn3zZ/ipPVPgr9Wg3cwmnrmBDUP1qT34t0UQwBzot6PZ YHY2sGvCaIPbuh8ZOIbT7u73ir9L+pNl+BmeCPDGV7H++71HxvCAW+2fEjwo+14K Vua7HR/cwDa7DqnWXCLON7XMJmrzCr2YcKhyF9qAcMOyu/Y67yXEmlest6L/Nybm tuY8g9EBz3iyQ7Ahc6KPRw9uWTRwuUhQlEDRnqOgUGGwijBj6dArLCkK5Y4Uq/2w 1MbWzjMcNVQO3nZJIhatczcvBWjR0MfdW5Px+lpdVanOTNPYz3lNsOcVr3UQEvJR T8sPB3qTRu/inQJ2HJwzh490z/FnCfGepxB+36RaEjy06vBTZYWH77adg1eklUQF h4pQq/mbEZvL/g1O3bWlUnWw/Xz1oBO/K8yqaryEEdTjcEVDXrvz3xDRSmXmZiei hcSbNuvEvZI8l4Pe3dDwkSeJxKpaIGgZfPZH833Uder3R8rO+WJynpNKdHChrDTN +y3CqOVNtmdd9Cf3mFS91U89ul0wqrGyESV0180FsRBMLTQX6xsGARpGZg+DW4DB MhidUJbTOT7C0LYK39mimgFlzM+oN0tfU7tfYsNWzjsPJ5Rni/KGc9s8vQARAQAB tClWaW5jZW50IEhlbm5lYmVydCA8dmhlbm5lYmVydEBhcGFjaGUub3JnPokCOAQT AQIAIgUCU87TrAIbAwYLCQgHAwIGFQgCCQoLBBYCAwECHgECF4AACgkQ720xx3L6 J1p8eg/+MkA0oWfP3SV47QtVxXSywCTGn1oN9R1k+iw+FHFitJ2u3dfZpVWbySSv o49OhlR5YoQjA5aR4hXpicSmu0DJyBbZQBHjzllZC8CcU810uwT5E7qMD6rKviwk cKM+q2ntI0yfZ0wI8rHWtTIV9FV0Y3YNuHoIPP86gyDTmNOMX5lR5EXGPYLZdD6e NTMzu5VlQoW11AgXx5N+2qbRVD07v9nJpbl8c76/9A4eahVSXV9nhFsP2PFuEsDu /EbszLALevu/ieE2delBpXcOErZsn4Tkg56pebOS4kjitERvzb5axAskulhQVVF0 DTUOq21d77pD7Al6qRHODFH3hPGjCsk/2h8yVs1SK/IKRHR7LE5IP9EfVazJmOZa /7DQ1my5WGD61/i2qa4hXYmDVTNEUWfJ5eSZ9Newm8pwa4pAVx2umOLe0xqxbUnk SzbZGXKREIFOiDh0XA9VN7yNUWAFs6T49NsCHzn6q138I2Pp8hVL8Q142ywu5OLH RDNTYfJZ0qLV/UyQv53g0zss2OkJz/r9WL7feWNtj15N3jJj+SCtj4f7PsJ5O7GX LFWBV7HrXhfNQxwaRoE6ksDshW/AVIJ7mwNu4tXmXksFYd32VVHoHL+ppOqRo9aV iN5aRt6CJFWYk4CU47rm7Vfgp9RRCXJyen8vM+KOe8gfIMG7g/OIRgQQEQIABgUC U87YHgAKCRCgctTQQ1jFhA3gAJ9P8I4e6oTZrE7MPF0f+VlxW06BvQCfect5XgkZ SjzjS7htUjNUApEcbN25Ag0EU87TrAEQAJ34nOX/79PUAl8kAyyPl/3V2My0DxnB gyXwYne47fQxwYne1EWljO90KGRKiJoarClUZ3/QkD0jArGRgLKK2kEAF1RIkLdz xNYE/weo7vc2rjRePSsGieE1Jy5aZHZkejaD95d/8Ve39qZqc17wWwF1ccw2OFlZ e0Z4rwLo4f1nNrRoI+RHeB/2vdwYGdQRWQ8IQVCkEZs41wFh9XUVuM/SpY7+Tet7 pL/NsSy0YmyXae0mHMOn1pXq0/K0zXZGy54EDD2flvyZhai+t+I/+R0xElrFsBDo gt291s9YGPLJaQOHKXS9vxwUp7nj64rkE4fo5ogCSP+4WReZRfJaz+8tee3NE1zM JHuc7oolZKUpxJlBmKrFs9qZCvAnpkrBcIZgUwiEqgZP8ptGXvcle9fqcIhpvqDo NRyW98cGQZOe9QwV9tCnBtSFMnoUFUXuvfy3stEBBWLYSWABip98W75TO8tVn8DG SX3ApIpIIBhUmnDR3RWN9N/5AFTiDLr/Ux+mUBM7u7vTImMvuQF8+UNxXCg//rmg vtYtMQ8Jv1k6V7RPbjEbkRXNt+JIpxSy5rQo/USEJxiwoiQKq5blGrBxURWS4jQs Vc/Mhh9OUdDftqyH4ZHgNbbzgTu9y9CCloD4N0gzGTjqPFvLpKMuiv3IKKlHe9wC Vtjq2eShQOxvABEBAAGJAh8EGAECAAkFAlPO06wCGwwACgkQ720xx3L6J1qAzw/+ PQ1gpXiNz4+6GJqDWhtmzbPpg5XVUMkO1fCyaqdJu7QmQhZQo3ZNtqqq7zm2PuA8 /HJEzbzq6s7jB+qiR7lsLIzqiXVTe0kBpjva8PbPf9m8o7sm79hDwIhxuP0vac+6 bpdpbzuEQ9VczVVgz1UruHhfA2Jgd67D9gXykQCNWWTewZ6MX0bWUQFkI0kIcFSq QqPMoHBm1LNef6sUg+bCDn1lGiXZZYeMkbeMZ7zlsqERBijFGfAatyjUk/I/W/R6 o9ZKHsWJTLYg9oKTzwYYErHXoDm0wYehGC8vhMlc4QpCx0HrLBl2w+br7AErfKO9 5g/YF1lotpsgFm8gswmED0+8qM9xm7JbJah3ahv6anttk7FjUOxgcclMNf+8ZW8l oKnOev7LmF9pBLBZ2YYZPl/GOU/x5aRqU12qmxeHwPp1hZ0C7kngkhtlR/WGuWp3 FfAihujJYCm/OLL/sfZYJcC1W1w5Q/tJsoVlwCuAJLifpHxvNcScdLYLfSVFX7L+ WZd4RVs2TDptk5ovcQk0GnlMK090aGE8nV3+oV72wssjWlMycKfQnCN2fP/DvHic C7ntv74LfH+9sIY9lrW3mqPSUqBpEkVQvWfO5yaABDyKWQKbL0oTIOqwDSqOw0Ll Jb8/mPX9jDboY95OyNYZ8D7o+lwQFeUbNwQp/qCS52g= =zlG2 -----END PGP PUBLIC KEY BLOCK----- pub 4096R/7CDB6DEA 2015-05-20 uid Simon Steiner (CODE SIGNING KEY) sub 4096R/73382B77 2015-05-20 -----BEGIN PGP PUBLIC KEY BLOCK----- Version: GnuPG v1 mQINBFVcZesBEAC5Poew53ijRTE5kV2o2Tj+plJmoQMRtfiurMUpPQ4s/vTz8Bte WoHdNfJrzordHBZdy1S7V8p2kTtKWyaNFMyVoavBqo/BurmJ/3qUKH5otXkXuaAi zFaJPeEnR6y7pxTYkwFKyrn7TE4I84JKZEMLEbJIw1YF3t76nj055/OnzRtwc2Df cPyGqDALyoFXk6R04qIotVmlX3NwwF6A0M79+W+kWvPg4sD4R6SqwJb1UhcqHrqb kQOllg74cBjyAikRbqrCfoydHM10gc8f5w9+8v/fbDkSBtoh8Y31WSK6ocoWIg85 I3odqHFxThwFTAYQC2tdw1M5kYcOiYVqw91JvBivpKH02vryH2BJu9zQDNFeyXud wyengMLlzUUmf9jBk3M8IUE4JTerw1AzWj0b3jdvG7FrgHrlszb6eCzE3BdY7zGS Qh6e+ROsF2LEKkbjxeAg58nl/h5iLythheY0S6sspeOTuDtgLgm8TZiGHA+j/qKH DY+aRReI0X2bzqNZROhTIXHSKsoX9+9g5a+1NYQeZmiICNo4vj+r4+i037QvIoy6 3K4NSVQgKnR9bbgyQCUprifrkywKF5a8eP3wtUGtH2FNqFQg1rUKBgLjLbRJ8PF2 Ag8O0jmJBPxdOIdVP4vz37m+jyKE6L4JWjnaFldtD3NDJI1QQYX4MmXEaQARAQAB tDZTaW1vbiBTdGVpbmVyIChDT0RFIFNJR05JTkcgS0VZKSA8c3N0ZWluZXJAYXBh Y2hlLm9yZz6JAjgEEwECACIFAlVcZesCGwMGCwkIBwMCBhUIAgkKCwQWAgMBAh4B AheAAAoJEFuT8d98223qTtoP/j5AH1w90HOiYioGGgxrxOciQdGNht0yOVPXHDyj 8oKNBKYhNYQ9tAxNxEZFVS2KxB3R5dy/Q/9XvOP/NYTP8p0VyXmxNMkicUhJQOJ/ 6mnxkTY/jk7y2XkYtdCby28SfMdExbM501arnG+vmXRtr3TpRRAxXCfS3FBI2n1H Y7aX8pVX3NNRQqGxjnSv4q/2NKrR1ZFt7aDuAO9VfLXd5NkJkaGJ7E7T4AQMJE6K KYUFkYKGeOc5dm1mHZMTVanyYRS0qWSpcnsamdU76HQgtC7koJmaeeI0MtntMkpB jObTY80iam97P81hfhEi9UsAPy0WPBmossNqQFYQ5kQzxq030C1ERJl1nXJCkIpl CpVv/aIV+kM+WQeA41IHgfLZsxHTkYRxtCZXh8HbFhpyKGwNRZhyvPn0oSbjQcke oAbfnxCj1YH6TQGJQH1R1rGPv3ph3omq9pRuJ/th4uFmq06xpO6VLjUICV9F1N1J kmiVpivC5iRDKw30YeRFe/J0BpflPizQh2gnTFCg0Q0ICUdehGovWKPDkJsG2+hb AJaxfYQg5cJQI1P0UOc3w6rLh2ye3qkSRxF1O9oyRHuAZtKtsabEg3v7bx6RnX1F BYGCB8ckud+qYlBjiGKLP7fJotuZv3hFWlFBoXb9F0WDpx+gUoEUH8H+9ygodEUq gjCRuQINBFVcZesBEADFcTVSAZoaax9xpw1zxwjVgfQrNfobqnJM33r2EBSB4b80 NbPOtoHJ2OUvHq4w84PB+H4+JNAIA2KbPOvzB+u1Bn5IgJr9asH5lhrnrUSR+YCw UlnCw+2YJumdv/l6RKcFKbSRZHWSwTD3ZLBMuPUqX9uZkOuG1ftTkcVtfFHN3WAu ckHjVxTSkaHhZ7ALz8LIUH+8AL3/3eThM1KEgx+bcod8YttctzjTy9cAaT93DwKO qzqHXpk6Fpv9bvdiNye8Ye7f8487N0/3alMPpJqt2tHAqjxJRDb590/09cbt2N6l 6B+WlpM5hgkV//7ViL357Hids64sqbYSnmpQjZWUdafDvVvMKYbITmx26BEoWtIq wwpj7+DdQlxd/7bAtyk8XiHe6Ej9FF1PUEvBQw5NXOUiCSBo0hzcMMNy1uRb/Wpd oZX3TFKXTWulv95uzKGAo3zrUuKcfOGfDgqZ/H2dy8Yw9DaWJRnXyYwweUi1Ptnc Nk9ktycypCcVbsOQhGdQJNyGVUVgVV1CWz5GJ3eqtjHY09r7HEm6bGviJRu/sosk XmmjRUFpqwtDCRACYShDpnFjpmWTZegPcwpN+492qLP6cjh1XSN4Cg1YZ/0BMY4N V/yeadQf/hbM5hzPOhN6mr+VHOLulyXuV49EWisIRferqaXG67zIXbVQ4qfqfwAR AQABiQIfBBgBAgAJBQJVXGXrAhsMAAoJEFuT8d98223qGKoP/RtyjtE5zEkrd7oa vRK5FmNtdh8r63v8lwjxayCfmpQw14AQaPY7//ulfJQExpxqcCLFIEBqZ8o22RYA XnsV6RF3JAIjSktAh57GMqUljeNxBtlix2zv5MVi/XiYcmQrID812KNfp3/guJfK 3Us5BOxLyDwHylwyb88dLM3rP4W8VvaRAEXfd0/6rhEugdCdcHD1c+E1XliqBw/T UP3JjnnABfKR4NMZ67ENxc5jPDg2Jh3wychGGhvLddqk32KEIDTbV2SZYxtw3ylP cRUtEoVGvkCDj8KpcLvvTbE7QCOycQMj1aHt5tc0w+Ibqbj3X+DdJEAxuZhMDyR6 hDkIr7YGkRjFacYeaunoY4tX4+x4tkf33eNsBa3DV6r6R18DWh8o6bWzHpPuEMZT ewbUuSHF9xm0Ti3uehDHNHIFsnEpGDanb2UMO1kd2Xr6kjabce4DIHn+PhOqwC1o bO9KBKaWO4uR7K1eWjOkqn70F7ykGz01AveouwRyOjh59VdpVe/Zpgtp/IvD6bP2 FbW6pZZeHWWoj+zaDmyRDn5wRfGkNuLUIMblgCXQXttAm/nYdRwPQyAI+T5CP8f+ nmZfX1E6PwDD9rT+fU+0R1eAIkEZE+0UfWoBwbnei19Xqpwx6VH5x8mtfvUH9J5H PYDEgpBqDxD3E1CYq/cVFhKQRxpK =n+z/ -----END PGP PUBLIC KEY BLOCK----- xmlgraphics-commons-2.6/LICENSE0100644 0000000 0000000 00000026136 13777276623 015143 0ustar000000000 0000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. xmlgraphics-commons-2.6/NOTICE0100644 0000000 0000000 00000000265 13777276623 015035 0ustar000000000 0000000 Apache XML Graphics Commons Copyright 2006-2021 The Apache Software Foundation This product includes software developed at The Apache Software Foundation (http://www.apache.org/). xmlgraphics-commons-2.6/README0100644 0000000 0000000 00000011764 13777276623 015017 0ustar000000000 0000000 $Id: README 1885379 2021-01-12 09:32:59Z ssteiner $ ============================================================================== APACHE XML GRAPHICS COMMONS - README ============================================================================== Contents of this file: - What is Apache XML Graphics Commons? - Where to get help? - How do I build Apache XML Graphics Commons? - Legal information - Release Notes ============================================================================== What is Apache XML Graphics Commons? --------------------------------------- It is a place where the Apache Batik and Apache FOP share commonly used components. Many components in here are also usable and useful stand-alone. Documentation --------------------- The documentation can be found under: http://xmlgraphics.apache.org/commons/ Where to get help? --------------------- Please subscribe to the general@xmlgraphics.apache.org mailing list by sending an empty mail to general-subscribe@xmlgraphics.apache.org. All you questions about XML Graphics Commons will be answered there. Please report bugs to JIRA at http://issues.apache.org/jira/ (project XMLGraphicsCommons). How do I build Apache XML Graphics Commons? ---------------------------------------------- If you've downloaded a binary distribution of Apache FOP or Apache Batik, you don't need to build XML Graphics Commons. It is distributed with these two products. Otherwise, install Apache Ant (http://ant.apache.org) and run "ant" from the command-line in the directory where you find "build.xml". Legal information -------------------- Apache XML Graphics Commons is published under the Apache License version 2.0. For the license text, please see the following files: - LICENSE - NOTICE Legal information on libraries used by Apache XML Graphics Commons, i.e. its dependencies, can be found in the "lib/README.txt" file. Apache XML Graphics Commons contains unmodified copies of the Adobe Glyph List and the ITC Zapf Dingbats Glyph List, available from: http://www.adobe.com/devnet/opentype/archives/glyph.html License labeling (according to http://www.apache.org/legal/3party.html): - Multi-Licensed - Source Available - No Reciprocity Required ============================================================================== KNOWN ISSUES ============================================================================== - PostScript output: When TexturePaint is used with PSGraphics2D, the output violates the DSC specification. Extracting single pages from a multi-page PostScript file can result in errors. ============================================================================== RELEASE NOTES ============================================================================== For more detailed info about the changes, please see: http://xmlgraphics.apache.org/commons/changes.html Version 2.6 -------------- Minor release to be used with FOP 2.6 Version 2.4 -------------- Minor release to be used with FOP 2.4 Version 2.3 -------------- Minor release to be used with FOP 2.3 Version 2.2 -------------- * Transition from Ant to Maven Build Process Minor release to be used with FOP 2.2 Version 2.1 -------------- Minor release to be used with FOP 2.1 Version 2.0.1 -------------- Minor release to be used with FOP 2.0 Version 2.0 -------------- The main new feature is the introduction of a URI resolution framework that makes it easier to control resource access in a cloud environment. Because of changes to the API, the version number has been bumped to 2.0. This release also contains a number of bug fixes. Version 1.5 -------------- This release of Apache XML Graphics Commons primarily addresses bug fixes and also adds a number of new features. Version 1.4 ----------- This release adds the option to generate smaller PostScript files, support for the AdobeStandardCyrillic encoding, RefinedImageFlavor, TexturePaint support for PSGraphics2D (PostScript tiling patterns), improvements to the XMP framework, optimization for PostScript state handling in (E)PSDocumentGraphics2D, and more. In addition it contains a number of bug fixes. Version 1.3.1 -------------- This release is mostly a bugfix release for the image loading framework that has been introduced in version 1.3. Version 1.3 -------------- The most important addition in this release is an image loading framework which supports all sorts of different image formats (bitmap and vector) and is highly extensible. Besides that there were a larger number of smaller additions and bugfixes. Support for Java 1.3 has been dropped. Java 1.4 or later is required now. Version 1.2 -------------- This release mainly adds support for CMYK and GRAY color spaces for PSGenerator. Version 1.1 -------------- This release adds an XMP metadata framework and brings improvements for the ImageWriter package plus some minor fixes mainly in the PostScript area. Version 1.0 -------------- This is the first release of Apache XML Graphics Commons. There are currently no known issues with the code. xmlgraphics-commons-2.6/build.properties0100644 0000000 0000000 00000002740 13777276623 017346 0ustar000000000 0000000 ## This is a template for settings which are useful to be ## overridden in a developer specific property files. ## Copy this to build-local.properties, uncomment and change ## properties which should be overridden. ## The file buil-local.properties is not stored in the code ## repository and ignored for file adds. ## =================================================================== ## 1. Path settings ## Path to your IKVM installation. Set this if you want to compile ## XML Graphics Commons to a .NET DLL. ## NOTE: If you want to compile the .NET DLL you'll have to ## disable the internal codecs. See below. #ikvm.dir=C:\\javalib\\ikvm-12-07-2004\\ikvm ## =================================================================== ## 2. Switches for common tasks ## Javac switches # javac.debug = on # javac.optimize = off # javac.deprecation = on # javac.source = 1.4 # javac.target = 1.4 # javac.fork = on ## JUnit task switches # junit.fork = on ## Packages to produce javadoc. # javadoc.packages = org.apache.xmlgraphics.* ## =================================================================== ## 3. Project specific properties version = 2.6 ## Allows you to switch off the compilation of the internal image ## codecs which depend on Sun-private classes. Setting this to true ## enabled compatibility with non-Sun Java implementations such as ## Kaffe, IKVM, GCC/GCJ or even Apache Harmony (i.e. system which ## are based on GNU Classpath, for example). # internal-codecs.disabled = false xmlgraphics-commons-2.6/build.xml0100644 0000000 0000000 00000075545 13777276623 015767 0ustar000000000 0000000 NOTE: ************************************************************************** * One or more of the Junit tests had Failures or Errors or were skipped! * * Please check the output above for relevant messages. * ************************************************************************** All Junit tests passed!
xmlgraphics-commons-2.6/examples/java/image/loader/ImageViewer.java0100644 0000000 0000000 00000011703 13777276623 024266 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageViewer.java 750418 2009-03-05 11:03:54Z vhennebert $ */ package image.loader; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics2D; import java.awt.geom.Rectangle2D; import java.io.File; import java.io.IOException; import org.apache.xmlgraphics.image.loader.ImageException; import org.apache.xmlgraphics.image.loader.ImageFlavor; import org.apache.xmlgraphics.image.loader.ImageInfo; import org.apache.xmlgraphics.image.loader.ImageManager; import org.apache.xmlgraphics.image.loader.ImageSessionContext; import org.apache.xmlgraphics.image.loader.ImageSize; import org.apache.xmlgraphics.image.loader.impl.DefaultImageContext; import org.apache.xmlgraphics.image.loader.impl.DefaultImageSessionContext; import org.apache.xmlgraphics.image.loader.impl.ImageGraphics2D; import org.apache.xmlgraphics.java2d.Graphics2DImagePainter; /** * Very simple image viewer application that demonstrates the use of the image loader framework. */ public class ImageViewer { private ImageManager imageManager; public ImageViewer() { //The ImageManager is set up for the whole application this.imageManager = new ImageManager(new DefaultImageContext()); } public void display(File f) throws IOException { //The ImageSessionContext might for each processing run ImageSessionContext sessionContext = new DefaultImageSessionContext( this.imageManager.getImageContext(), null); //Construct URI from filename String uri = f.toURI().toASCIIString(); ImageGraphics2D g2dImage = null; try { //Preload image ImageInfo info = this.imageManager.getImageInfo(uri, sessionContext); //Load image and request Graphics2D image g2dImage = (ImageGraphics2D)this.imageManager.getImage( info, ImageFlavor.GRAPHICS2D, sessionContext); } catch (ImageException e) { e.printStackTrace(); //Create "error image" if the image cannot be displayed g2dImage = createErrorImage(); } //Display frame with image ViewerFrame frame = new ViewerFrame(g2dImage); frame.setVisible(true); } private ImageGraphics2D createErrorImage() { Graphics2DImagePainter painter = new Graphics2DImagePainter() { public Dimension getImageSize() { return new Dimension(10, 10); } public void paint(Graphics2D g2d, Rectangle2D area) { g2d.translate(area.getX(), area.getY()); double w = area.getWidth(); double h = area.getHeight(); //Fit in paint area Dimension imageSize = getImageSize(); double sx = w / imageSize.getWidth(); double sy = h / imageSize.getHeight(); if (sx != 1.0 || sy != 1.0) { g2d.scale(sx, sy); } g2d.setColor(Color.RED); g2d.setStroke(new BasicStroke(0)); g2d.drawRect(0, 0, imageSize.width, imageSize.height); g2d.drawLine(0, 0, imageSize.width, imageSize.height); g2d.drawLine(0, imageSize.height, imageSize.width, 0); } }; Dimension dim = painter.getImageSize(); ImageSize size = new ImageSize(); size.setSizeInMillipoints(dim.width, dim.height); size.setResolution(imageManager.getImageContext().getSourceResolution()); size.calcPixelsFromSize(); ImageInfo info = new ImageInfo(null, null); info.setSize(size); return new ImageGraphics2D(info, painter); } /** * The application's main method. * @param args the command-line arguments */ public static void main(String[] args) { try { ImageViewer app = new ImageViewer(); if (args.length < 1) { throw new IllegalArgumentException("No filename given as application argument"); } app.display(new File(args[0])); } catch (Throwable t) { t.printStackTrace(); System.exit(-1); } } } xmlgraphics-commons-2.6/examples/java/image/loader/ViewerFrame.java0100644 0000000 0000000 00000006433 13777276623 024302 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ViewerFrame.java 750418 2009-03-05 11:03:54Z vhennebert $ */ package image.loader; import java.awt.Dimension; import java.awt.Frame; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Rectangle; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.awt.geom.Rectangle2D; import javax.swing.JPanel; import org.apache.xmlgraphics.image.loader.impl.ImageGraphics2D; import org.apache.xmlgraphics.java2d.Graphics2DImagePainter; /** * Viewer frame for the image viewer. */ public class ViewerFrame extends Frame { public static final String TITLE = "Very Simple Image Viewer"; public ViewerFrame(ImageGraphics2D g2dImage) { super(TITLE); addWindowListener(new WindowHandler()); buildGUI(g2dImage); setSize(500, 400); } private void buildGUI(final ImageGraphics2D g2dImage) { JPanel imagePanel = new JPanel() { /** {@inheritDoc} */ protected void paintComponent(Graphics graphics) { super.paintComponent(graphics); Graphics2D g2d = (Graphics2D)graphics.create(); try { Rectangle paintRect = new Rectangle( 30, 30, getWidth() - 60, getHeight() - 60); //g2d.translate(paintRect.getX(), paintRect.getY()); Graphics2DImagePainter painter = g2dImage.getGraphics2DImagePainter(); Dimension dim = painter.getImageSize(); double sx = paintRect.getWidth() / dim.getWidth(); double sy = paintRect.getHeight() / dim.getHeight(); //g2d.scale(sx, sy); /* Rectangle2D targetRect = new Rectangle2D.Double( paintRect.x * sx, paintRect.y * sy, dim.width, dim.height); */ Rectangle2D targetRect = new Rectangle2D.Double( paintRect.x, paintRect.y, paintRect.width, paintRect.height); g2d.draw(targetRect); painter.paint(g2d, targetRect); } finally { g2d.dispose(); } } }; add("Center", imagePanel); } private class WindowHandler extends WindowAdapter { public void windowClosing(WindowEvent we) { System.exit(0); } } } xmlgraphics-commons-2.6/examples/java/image/writer/ImageWriterExample1.java0100644 0000000 0000000 00000012411 13777276623 025741 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageWriterExample1.java 750418 2009-03-05 11:03:54Z vhennebert $ */ package image.writer; import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; import java.awt.font.TextAttribute; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.io.OutputStream; import java.text.AttributedString; import org.apache.commons.io.IOUtils; import org.apache.xmlgraphics.image.writer.ImageWriter; import org.apache.xmlgraphics.image.writer.ImageWriterParams; import org.apache.xmlgraphics.image.writer.ImageWriterRegistry; public class ImageWriterExample1 { /** * Paints a few things on a Graphics2D instance. * @param g2d the Graphics2D instance * @param pageNum a page number */ protected void paintSome(Graphics2D g2d, int pageNum) { //Paint a bounding box g2d.drawRect(0, 0, 400, 200); //A few rectangles rotated and with different color Graphics2D copy = (Graphics2D)g2d.create(); int c = 12; for (int i = 0; i < c; i++) { float f = ((i + 1) / (float)c); Color col = new Color(0.0f, 1 - f, 0.0f); copy.setColor(col); copy.fillRect(70, 90, 50, 50); copy.rotate(-2 * Math.PI / (double)c, 70, 90); } copy.dispose(); //Some text copy = (Graphics2D)g2d.create(); copy.rotate(-0.25); copy.setColor(Color.RED); copy.setFont(new Font("sans-serif", Font.PLAIN, 36)); copy.drawString("Hello world!", 140, 140); copy.setColor(Color.RED.darker()); copy.setFont(new Font("serif", Font.PLAIN, 36)); copy.drawString("Hello world!", 140, 180); copy.dispose(); //Try attributed text AttributedString aString = new AttributedString("This is attributed text."); aString.addAttribute(TextAttribute.FAMILY, "SansSerif"); aString.addAttribute(TextAttribute.FAMILY, "Serif", 8, 18); aString.addAttribute(TextAttribute.FOREGROUND, Color.orange, 8, 18); g2d.drawString(aString.getIterator(), 250, 170); g2d.drawString("Page: " + pageNum, 250, 190); } /** * Creates a bitmap file. We paint a few things on a bitmap and then save the bitmap using * an ImageWriter. * @param outputFile the target file * @param format the target format (a MIME type, ex. "image/png") * @throws IOException In case of an I/O error */ public void generateBitmapUsingJava2D(File outputFile, String format) throws IOException { //String compression = "CCITT T.6"; String compression = "PackBits"; boolean monochrome = compression.startsWith("CCITT"); //CCITT is for 1bit b/w only BufferedImage bimg; if (monochrome) { bimg = new BufferedImage(400, 200, BufferedImage.TYPE_BYTE_BINARY); } else { bimg = new BufferedImage(400, 200, BufferedImage.TYPE_INT_RGB); } Graphics2D g2d = bimg.createGraphics(); g2d.setBackground(Color.white); g2d.clearRect(0, 0, 400, 200); g2d.setColor(Color.black); //Paint something paintSome(g2d, 1); OutputStream out = new java.io.FileOutputStream(outputFile); out = new java.io.BufferedOutputStream(out); try { ImageWriter writer = ImageWriterRegistry.getInstance().getWriterFor(format); ImageWriterParams params = new ImageWriterParams(); params.setCompressionMethod(compression); params.setResolution(72); writer.writeImage(bimg, out, params); } finally { IOUtils.closeQuietly(out); } } /** * Command-line interface * @param args command-line arguments */ public static void main(String[] args) { try { File targetDir; if (args.length >= 1) { targetDir = new File(args[0]); } else { targetDir = new File("."); } if (!targetDir.exists()) { System.err.println("Target Directory does not exist: " + targetDir); } File outputFile = new File(targetDir, "eps-example1.tif"); ImageWriterExample1 app = new ImageWriterExample1(); app.generateBitmapUsingJava2D(outputFile, "image/tiff"); System.out.println("File written: " + outputFile.getCanonicalPath()); } catch (Exception e) { e.printStackTrace(); } } } xmlgraphics-commons-2.6/examples/java/image/writer/ImageWriterExample2.java0100644 0000000 0000000 00000010420 13777276623 025740 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageWriterExample2.java 750418 2009-03-05 11:03:54Z vhennebert $ */ package image.writer; import java.awt.Color; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.io.OutputStream; import org.apache.commons.io.IOUtils; import org.apache.xmlgraphics.image.writer.ImageWriter; import org.apache.xmlgraphics.image.writer.ImageWriterParams; import org.apache.xmlgraphics.image.writer.ImageWriterRegistry; import org.apache.xmlgraphics.image.writer.MultiImageWriter; public class ImageWriterExample2 extends ImageWriterExample1 { private BufferedImage createAnImage(String compression, int pageNum) { boolean monochrome = compression.startsWith("CCITT"); //CCITT is for 1bit b/w only BufferedImage bimg; if (monochrome) { bimg = new BufferedImage(400, 200, BufferedImage.TYPE_BYTE_BINARY); } else { bimg = new BufferedImage(400, 200, BufferedImage.TYPE_INT_RGB); } Graphics2D g2d = bimg.createGraphics(); g2d.setBackground(Color.white); g2d.clearRect(0, 0, 400, 200); g2d.setColor(Color.black); //Paint something paintSome(g2d, pageNum); return bimg; } /** * Creates a bitmap file. We paint a few things on a bitmap and then save the bitmap using * an ImageWriter. * @param outputFile the target file * @param format the target format (a MIME type, ex. "image/png") * @throws IOException In case of an I/O error */ public void generateBitmapUsingJava2D(File outputFile, String format) throws IOException { //String compression = "CCITT T.6"; String compression = "PackBits"; OutputStream out = new java.io.FileOutputStream(outputFile); out = new java.io.BufferedOutputStream(out); try { ImageWriter writer = ImageWriterRegistry.getInstance().getWriterFor(format); ImageWriterParams params = new ImageWriterParams(); params.setCompressionMethod(compression); params.setResolution(72); if (writer.supportsMultiImageWriter()) { MultiImageWriter multiWriter = writer.createMultiImageWriter(out); multiWriter.writeImage(createAnImage(compression, 1), params); multiWriter.writeImage(createAnImage(compression, 2), params); multiWriter.close(); } else { throw new UnsupportedOperationException("multi-page images not supported for " + format); } } finally { IOUtils.closeQuietly(out); } } /** * Command-line interface * @param args command-line arguments */ public static void main(String[] args) { try { File targetDir; if (args.length >= 1) { targetDir = new File(args[0]); } else { targetDir = new File("."); } if (!targetDir.exists()) { System.err.println("Target Directory does not exist: " + targetDir); } File outputFile = new File(targetDir, "eps-example2.tif"); ImageWriterExample2 app = new ImageWriterExample2(); app.generateBitmapUsingJava2D(outputFile, "image/tiff"); System.out.println("File written: " + outputFile.getCanonicalPath()); } catch (Exception e) { e.printStackTrace(); } } } xmlgraphics-commons-2.6/examples/java/java2d/ps/EPSColorsExample.java0100644 0000000 0000000 00000011310 13777276623 024442 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: EPSColorsExample.java 1051421 2010-12-21 08:54:25Z jeremias $ */ package java2d.ps; import java.awt.Color; import java.awt.Font; import java.io.File; import java.io.IOException; import java.io.OutputStream; import org.apache.commons.io.IOUtils; import org.apache.xmlgraphics.java2d.color.CIELabColorSpace; import org.apache.xmlgraphics.java2d.color.ColorSpaces; import org.apache.xmlgraphics.java2d.color.DeviceCMYKColorSpace; import org.apache.xmlgraphics.java2d.color.NamedColorSpace; import org.apache.xmlgraphics.java2d.ps.EPSDocumentGraphics2D; /** * This example demonstrates how colors are handled when generating PostScript/EPS. */ public class EPSColorsExample { /** * Creates an EPS file. The contents are painted using a Graphics2D implementation that * generates an EPS file. * @param outputFile the target file * @throws IOException In case of an I/O error */ public static void generateEPSusingJava2D(File outputFile) throws IOException { OutputStream out = new java.io.FileOutputStream(outputFile); out = new java.io.BufferedOutputStream(out); try { //Instantiate the EPSDocumentGraphics2D instance EPSDocumentGraphics2D g2d = new EPSDocumentGraphics2D(false); g2d.setGraphicContext(new org.apache.xmlgraphics.java2d.GraphicContext()); //Set up the document size g2d.setupDocument(out, 400, 200); //400pt x 200pt //Paint a bounding box g2d.drawRect(0, 0, 400, 200); g2d.setFont(new Font("sans-serif", Font.BOLD, 14)); g2d.drawString("Color usage example:", 10, 20); g2d.setFont(new Font("sans-serif", Font.PLAIN, 12)); g2d.drawString("RGB", 10, 84); g2d.drawString("CMYK", 60, 84); g2d.drawString("(Lab)", 110, 84); g2d.drawString("(Named)", 160, 84); //We're creating a few boxes all filled with some variant of the //"Postgelb" (postal yellow) color as used by Swiss Post. Color colRGB = new Color(255, 204, 0); g2d.setColor(colRGB); g2d.fillRect(10, 30, 40, 40); //Just convert RGB to CMYK and use that float[] compsRGB = colRGB.getColorComponents(null); DeviceCMYKColorSpace cmykCS = ColorSpaces.getDeviceCMYKColorSpace(); float[] compsCMYK = cmykCS.fromRGB(compsRGB); Color colCMYK = DeviceCMYKColorSpace.createCMYKColor(compsCMYK); g2d.setColor(colCMYK); g2d.fillRect(60, 30, 40, 40); //Try CIELab (not implemented, yet) CIELabColorSpace d50 = ColorSpaces.getCIELabColorSpaceD50(); Color colLab = d50.toColor(83.25f, 16.45f, 96.89f, 1.0f); g2d.setColor(colLab); g2d.fillRect(110, 30, 40, 40); //Try named color (Separation, not implemented, yet) float[] c1xyz = d50.toCIEXYZNative(83.25f, 16.45f, 96.89f); NamedColorSpace postgelb = new NamedColorSpace("Postgelb", c1xyz); Color colNamed = new Color(postgelb, new float[] {1.0f}, 1.0f); g2d.setColor(colNamed); g2d.fillRect(160, 30, 40, 40); //Cleanup g2d.finish(); } finally { IOUtils.closeQuietly(out); } } /** * Command-line interface * @param args command-line arguments */ public static void main(String[] args) { try { File targetDir; if (args.length >= 1) { targetDir = new File(args[0]); } else { targetDir = new File("."); } if (!targetDir.exists()) { System.err.println("Target Directory does not exist: " + targetDir); } generateEPSusingJava2D(new File(targetDir, "eps-example-colors.eps")); } catch (Exception e) { e.printStackTrace(); } } } xmlgraphics-commons-2.6/examples/java/java2d/ps/EPSExample1.java0100644 0000000 0000000 00000007354 13777276623 023356 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: EPSExample1.java 750418 2009-03-05 11:03:54Z vhennebert $ */ package java2d.ps; import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; import java.io.File; import java.io.IOException; import java.io.OutputStream; import org.apache.commons.io.IOUtils; import org.apache.xmlgraphics.java2d.ps.EPSDocumentGraphics2D; /** * This example demonstrates how you can generate an EPS (Encapsulated PostScript) file in Java * using the EPSDocumentGraphics2D class from Apache XML Graphics Commons. */ public class EPSExample1 { /** * Creates an EPS file. The contents are painted using a Graphics2D implementation that * generates an EPS file. * @param outputFile the target file * @throws IOException In case of an I/O error */ public static void generateEPSusingJava2D(File outputFile) throws IOException { OutputStream out = new java.io.FileOutputStream(outputFile); out = new java.io.BufferedOutputStream(out); try { //Instantiate the EPSDocumentGraphics2D instance EPSDocumentGraphics2D g2d = new EPSDocumentGraphics2D(false); g2d.setGraphicContext(new org.apache.xmlgraphics.java2d.GraphicContext()); //Set up the document size g2d.setupDocument(out, 400, 200); //400pt x 200pt //Paint a bounding box g2d.drawRect(0, 0, 400, 200); //A few rectangles rotated and with different color Graphics2D copy = (Graphics2D)g2d.create(); int c = 12; for (int i = 0; i < c; i++) { float f = ((i + 1) / (float)c); Color col = new Color(0.0f, 1 - f, 0.0f); copy.setColor(col); copy.fillRect(70, 90, 50, 50); copy.rotate(-2 * Math.PI / (double)c, 70, 90); } copy.dispose(); //Some text g2d.rotate(-0.25); g2d.setColor(Color.RED); g2d.setFont(new Font("sans-serif", Font.PLAIN, 36)); g2d.drawString("Hello world!", 140, 140); g2d.setColor(Color.RED.darker()); g2d.setFont(new Font("serif", Font.PLAIN, 36)); g2d.drawString("Hello world!", 140, 180); //Cleanup g2d.finish(); } finally { IOUtils.closeQuietly(out); } } /** * Command-line interface * @param args command-line arguments */ public static void main(String[] args) { try { File targetDir; if (args.length >= 1) { targetDir = new File(args[0]); } else { targetDir = new File("."); } if (!targetDir.exists()) { System.err.println("Target Directory does not exist: " + targetDir); } generateEPSusingJava2D(new File(targetDir, "eps-example1.eps")); } catch (Exception e) { e.printStackTrace(); } } } xmlgraphics-commons-2.6/examples/java/java2d/ps/TilingPatternExample.java0100644 0000000 0000000 00000012764 13777276623 025433 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: TilingPatternExample.java 752824 2009-03-12 10:05:32Z jeremias $ */ package java2d.ps; import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; import java.awt.Polygon; import java.awt.Rectangle; import java.awt.TexturePaint; import java.awt.font.GlyphVector; import java.awt.geom.AffineTransform; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.io.OutputStream; import org.apache.commons.io.IOUtils; import org.apache.xmlgraphics.image.writer.ImageWriterUtil; import org.apache.xmlgraphics.java2d.ps.PSDocumentGraphics2D; /** * This example demonstrates the usage of PostScript tiling patterns. The class also generated * a PNG file so the output can be compared. */ public class TilingPatternExample { private BufferedImage tile; private TexturePaint paint; /** * Default constructor. */ public TilingPatternExample() { //Created TexturePaint instance this.tile = new BufferedImage(40, 20, BufferedImage.TYPE_INT_RGB); Graphics2D tileg2d = tile.createGraphics(); tileg2d.setBackground(Color.WHITE); tileg2d.clearRect(0, 0, tile.getWidth(), tile.getHeight()); tileg2d.setColor(Color.BLUE); tileg2d.fillOval(2, 2, tile.getWidth() - 2, tile.getHeight() - 2); tileg2d.dispose(); Rectangle2D rect = new Rectangle2D.Double( 2, 2, tile.getWidth() / 2.0, tile.getHeight() / 2.0); this.paint = new TexturePaint(tile, rect); } /** * Creates a PostScript file. The contents are painted using a Graphics2D implementation. * @param outputFile the target file * @throws IOException In case of an I/O error */ public void generatePSusingJava2D(File outputFile) throws IOException { OutputStream out = new java.io.FileOutputStream(outputFile); out = new java.io.BufferedOutputStream(out); try { //Instantiate the PSDocumentGraphics2D instance PSDocumentGraphics2D g2d = new PSDocumentGraphics2D(false); g2d.setGraphicContext(new org.apache.xmlgraphics.java2d.GraphicContext()); //Set up the document size g2d.setupDocument(out, 400, 200); //400pt x 200pt paintTileAlone(g2d); paintShapes(g2d); paintText(g2d); g2d.nextPage(); paintText(g2d); //Cleanup g2d.finish(); } finally { IOUtils.closeQuietly(out); } } private void generatePNGusingJava2D(File outputFile) throws IOException { BufferedImage image = new BufferedImage(400, 200, BufferedImage.TYPE_INT_ARGB); Graphics2D g2d = image.createGraphics(); paintTileAlone(g2d); paintShapes(g2d); paintText(g2d); g2d.dispose(); ImageWriterUtil.saveAsPNG(image, outputFile); } private void paintTileAlone(Graphics2D g2d) { AffineTransform at = new AffineTransform(); at.translate(5, 5); g2d.drawRenderedImage(this.tile, at); } private void paintShapes(Graphics2D g2d) { g2d.setPaint(paint); Rectangle rect = new Rectangle(10, 50, 30, 30); g2d.fill(rect); rect = new Rectangle(10, 90, 40, 20); g2d.fill(rect); Polygon poly = new Polygon(new int[] {50, 100, 150}, new int[] {100, 20, 100}, 3); g2d.fill(poly); } private void paintText(Graphics2D g2d) { g2d.setPaint(paint); Font font = new Font("serif", Font.BOLD, 80); GlyphVector gv = font.createGlyphVector(g2d.getFontRenderContext(), "Java"); g2d.translate(100, 180); g2d.fill(gv.getOutline()); } /** * Command-line interface * @param args command-line arguments */ public static void main(String[] args) { try { File targetDir; if (args.length >= 1) { targetDir = new File(args[0]); } else { targetDir = new File("."); } if (!targetDir.exists()) { System.err.println("Target Directory does not exist: " + targetDir); } File outputFile = new File(targetDir, "tiling-example.ps"); File pngFile = new File(targetDir, "tiling-example.png"); TilingPatternExample app = new TilingPatternExample(); app.generatePSusingJava2D(outputFile); System.out.println("File written: " + outputFile.getCanonicalPath()); app.generatePNGusingJava2D(pngFile); System.out.println("File written: " + pngFile.getCanonicalPath()); } catch (Exception e) { e.printStackTrace(); } } } xmlgraphics-commons-2.6/examples/java/ps/DSCProcessingExample1.java0100644 0000000 0000000 00000007374 13777276623 024230 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: DSCProcessingExample1.java 750418 2009-03-05 11:03:54Z vhennebert $ */ package ps; import java.io.File; import java.io.IOException; import java.io.OutputStream; import java.io.InputStream; import org.apache.commons.io.IOUtils; import org.apache.xmlgraphics.ps.dsc.DSCException; import org.apache.xmlgraphics.ps.dsc.tools.PageExtractor; /** * Demonstrates how the DSC parser can be used to extract a series of pages from a DSC-compliant * PostScript file. For details how this works, please look into the PageExtractor class * where the actual functionality is located. This sample class only calls the code there. */ public class DSCProcessingExample1 { /** * Extracts a series of pages from a DSC-compliant PostScript file. * @param srcFile the source PostScript file * @param tgtFile the target file to write the extracted pages to * @param from the starting page number * @param to the ending page number * @throws IOException In case of an I/O error */ public void extractPages(File srcFile, File tgtFile, int from, int to) throws IOException { InputStream in = new java.io.FileInputStream(srcFile); in = new java.io.BufferedInputStream(in); try { OutputStream out = new java.io.FileOutputStream(tgtFile); out = new java.io.BufferedOutputStream(out); try { PageExtractor.extractPages(in, out, from, to); } catch (DSCException e) { throw new RuntimeException(e.getMessage()); } finally { IOUtils.closeQuietly(out); } } finally { IOUtils.closeQuietly(in); } } private static void showInfo() { System.out.println( "Call: DSCProcessingExample1 "); } /** * Command-line interface * @param args command-line arguments */ public static void main(String[] args) { try { File srcFile , tgtFile; int from, to; if (args.length >= 4) { srcFile = new File(args[0]); tgtFile = new File(args[1]); from = Integer.parseInt(args[2]); to = Integer.parseInt(args[3]); } else { throw new IllegalArgumentException("Invalid number of parameters!"); } if (!srcFile.exists()) { throw new IllegalArgumentException("Source file not found: " + srcFile); } DSCProcessingExample1 app = new DSCProcessingExample1(); app.extractPages(srcFile, tgtFile, from, to); System.out.println("File written: " + tgtFile.getCanonicalPath()); } catch (IllegalArgumentException iae) { System.err.println(iae.getMessage()); showInfo(); System.exit(1); } catch (Exception e) { e.printStackTrace(); System.exit(-1); } } } xmlgraphics-commons-2.6/examples/java/xmp/ExtractMetadataPacket.java0100644 0000000 0000000 00000006653 13777276623 024551 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ExtractMetadataPacket.java 606567 2007-12-23 15:52:49Z jeremias $ */ package xmp; import java.io.IOException; import java.io.InputStream; import java.net.URL; import javax.xml.transform.TransformerException; import org.apache.xmlgraphics.xmp.Metadata; import org.apache.xmlgraphics.xmp.XMPArray; import org.apache.xmlgraphics.xmp.XMPConstants; import org.apache.xmlgraphics.xmp.XMPPacketParser; import org.apache.xmlgraphics.xmp.XMPProperty; /** * This example shows how to parse an XMP packet from an arbitrary file. */ public class ExtractMetadataPacket { private static void parseMetadata() throws IOException, TransformerException { URL url = ExtractMetadataPacket.class.getResource("xmp-sandbox.fop.trunk.pdf"); InputStream in = url.openStream(); try { Metadata meta = XMPPacketParser.parse(in); if (meta == null) { System.err.println("No XMP packet found!"); } else { dumpSomeMetadata(meta); } } finally { in.close(); } } private static void dumpSomeMetadata(Metadata meta) { XMPProperty prop; prop = meta.getProperty(XMPConstants.DUBLIN_CORE_NAMESPACE, "creator"); if (prop != null) { XMPArray array; array = prop.getArrayValue(); for (int i = 0, c = array.getSize(); i < c; i++) { System.out.println("Creator: " + array.getValue(i)); } } prop = meta.getProperty(XMPConstants.DUBLIN_CORE_NAMESPACE, "title"); if (prop != null) { System.out.println("Title: " + prop.getValue()); } prop = meta.getProperty(XMPConstants.XMP_BASIC_NAMESPACE, "CreateDate"); if (prop != null) { System.out.println("Creation Date: " + prop.getValue()); } prop = meta.getProperty(XMPConstants.XMP_BASIC_NAMESPACE, "CreatorTool"); if (prop != null) { System.out.println("Creator Tool: " + prop.getValue()); } prop = meta.getProperty(XMPConstants.ADOBE_PDF_NAMESPACE, "Producer"); if (prop != null) { System.out.println("Producer: " + prop.getValue()); } prop = meta.getProperty(XMPConstants.ADOBE_PDF_NAMESPACE, "PDFVersion"); if (prop != null) { System.out.println("PDF version: " + prop.getValue()); } } /** * Command-line interface. * @param args the command-line arguments */ public static void main(String[] args) { try { parseMetadata(); } catch (Exception e) { e.printStackTrace(); } } } xmlgraphics-commons-2.6/examples/java/xmp/MergeMetadata.java0100644 0000000 0000000 00000006376 13777276623 023050 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: MergeMetadata.java 750418 2009-03-05 11:03:54Z vhennebert $ */ package xmp; import java.net.URL; import java.util.Date; import javax.xml.transform.TransformerException; import org.apache.xmlgraphics.xmp.Metadata; import org.apache.xmlgraphics.xmp.XMPConstants; import org.apache.xmlgraphics.xmp.XMPParser; import org.apache.xmlgraphics.xmp.XMPProperty; import org.apache.xmlgraphics.xmp.XMPSerializer; import org.apache.xmlgraphics.xmp.schemas.DublinCoreAdapter; import org.xml.sax.SAXException; /** * This example shows how to parse an XMP metadata file. */ public class MergeMetadata { private static void mergeMetadata() throws TransformerException, SAXException { URL url = MergeMetadata.class.getResource("pdf-example.xmp"); Metadata meta1 = XMPParser.parseXMP(url); Metadata meta2 = new Metadata(); DublinCoreAdapter dc = new DublinCoreAdapter(meta2); dc.setTitle("de", "Der Herr der Ringe"); dc.setTitle("en", "Lord of the Rings"); dc.addCreator("J.R.R. Tolkien"); //Will replace creator from pdf-example.xmp dc.addDate(new Date()); meta2.mergeInto(meta1); Metadata meta = meta1; XMPProperty prop; dc = new DublinCoreAdapter(meta); String[] creators = dc.getCreators(); for (int i = 0, c = creators.length; i < c; i++) { System.out.println("Creator: " + creators[i]); } System.out.println("Title: " + dc.getTitle()); System.out.println("Title de: " + dc.getTitle("de")); System.out.println("Title en: " + dc.getTitle("en")); prop = meta.getProperty(XMPConstants.XMP_BASIC_NAMESPACE, "CreateDate"); System.out.println("Creation Date: " + prop.getValue()); prop = meta.getProperty(XMPConstants.XMP_BASIC_NAMESPACE, "CreatorTool"); System.out.println("Creator Tool: " + prop.getValue()); prop = meta.getProperty(XMPConstants.ADOBE_PDF_NAMESPACE, "Producer"); System.out.println("Producer: " + prop.getValue()); prop = meta.getProperty(XMPConstants.ADOBE_PDF_NAMESPACE, "PDFVersion"); System.out.println("PDF version: " + prop.getValue()); XMPSerializer.writeXMPPacket(meta, System.out, false); } /** * Command-line interface. * @param args the command-line arguments */ public static void main(String[] args) { try { mergeMetadata(); } catch (Exception e) { e.printStackTrace(); } } } xmlgraphics-commons-2.6/examples/java/xmp/MetadataFromScratch.java0100644 0000000 0000000 00000004152 13777276623 024212 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: MetadataFromScratch.java 889803 2009-12-11 20:36:36Z jeremias $ */ package xmp; import java.util.Date; import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.stream.StreamResult; import org.xml.sax.SAXException; import org.apache.xmlgraphics.xmp.Metadata; import org.apache.xmlgraphics.xmp.XMPSerializer; import org.apache.xmlgraphics.xmp.schemas.DublinCoreAdapter; /** * This example shows how to build an XMP metadata file from scratch in Java. */ public class MetadataFromScratch { private static void buildAndPrintMetadata() throws TransformerConfigurationException, SAXException { Metadata meta = new Metadata(); DublinCoreAdapter dc = new DublinCoreAdapter(meta); dc.setTitle("de", "Der Herr der Ringe"); dc.setTitle("en", "Lord of the Rings"); dc.addDate(new Date()); dc.setFormat("application/pdf"); dc.addCreator("J.R.R. Tolkien"); StreamResult res = new StreamResult(System.out); XMPSerializer.writeXML(meta, res); } /** * Command-line interface. * @param args the command-line arguments */ public static void main(String[] args) { try { buildAndPrintMetadata(); } catch (Exception e) { e.printStackTrace(); } } } xmlgraphics-commons-2.6/examples/java/xmp/ParseMetadata.java0100644 0000000 0000000 00000006570 13777276623 023057 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ParseMetadata.java 750418 2009-03-05 11:03:54Z vhennebert $ */ package xmp; import java.net.URL; import javax.xml.transform.TransformerException; import javax.xml.transform.stream.StreamResult; import org.xml.sax.SAXException; import org.apache.xmlgraphics.xmp.Metadata; import org.apache.xmlgraphics.xmp.XMPArray; import org.apache.xmlgraphics.xmp.XMPConstants; import org.apache.xmlgraphics.xmp.XMPParser; import org.apache.xmlgraphics.xmp.XMPProperty; import org.apache.xmlgraphics.xmp.XMPSerializer; import org.apache.xmlgraphics.xmp.schemas.DublinCoreAdapter; import org.apache.xmlgraphics.xmp.schemas.DublinCoreSchema; /** * This example shows how to parse an XMP metadata file. */ public class ParseMetadata { private static void parseMetadata() throws TransformerException, SAXException { URL url = ParseMetadata.class.getResource("pdf-example.xmp"); Metadata meta = XMPParser.parseXMP(url); XMPProperty prop; prop = meta.getProperty(XMPConstants.DUBLIN_CORE_NAMESPACE, "creator"); XMPArray array; array = prop.getArrayValue(); for (int i = 0, c = array.getSize(); i < c; i++) { System.out.println("Creator: " + array.getValue(i)); } prop = meta.getProperty(XMPConstants.DUBLIN_CORE_NAMESPACE, "title"); array = prop.getArrayValue(); System.out.println("Default Title: " + array.getSimpleValue()); System.out.println("German Title: " + array.getLangValue("de")); prop = meta.getProperty(XMPConstants.XMP_BASIC_NAMESPACE, "CreateDate"); System.out.println("Creation Date: " + prop.getValue()); prop = meta.getProperty(XMPConstants.XMP_BASIC_NAMESPACE, "CreatorTool"); System.out.println("Creator Tool: " + prop.getValue()); prop = meta.getProperty(XMPConstants.ADOBE_PDF_NAMESPACE, "Producer"); System.out.println("Producer: " + prop.getValue()); prop = meta.getProperty(XMPConstants.ADOBE_PDF_NAMESPACE, "PDFVersion"); System.out.println("PDF version: " + prop.getValue()); DublinCoreAdapter dc = DublinCoreSchema.getAdapter(meta); System.out.println("Default title: " + dc.getTitle()); System.out.println("German title: " + dc.getTitle("de")); StreamResult res = new StreamResult(System.out); XMPSerializer.writeXML(meta, res); } /** * Command-line interface. * @param args the command-line arguments */ public static void main(String[] args) { try { parseMetadata(); } catch (Exception e) { e.printStackTrace(); } } } xmlgraphics-commons-2.6/examples/java/xmp/pdf-example.xmp0100644 0000000 0000000 00000002103 13777276623 022415 0ustar000000000 0000000 John Doe Jane Doe Example document Beispieldokument 2006-06-02T10:36:40+02:00 2006-06-02T10:36:40+02:00 An XML editor Apache FOP Version SVN trunk 1.4 xmlgraphics-commons-2.6/examples/java/xmp/xmp-sandbox.fop.trunk.pdf0100644 0000000 0000000 00000105622 13777276623 024357 0ustar000000000 0000000 %PDF-1.4 % 4 0 obj << /Title (XMP Metadata Sandbox FO Document) /Producer (Apache FOP Version SVN trunk) /CreationDate (D:20070418144200+02'00') >> endobj 5 0 obj << /N 3 /Length 10 0 R >> stream HLinomntrRGB XYZ  1acspMSFTIEC sRGB-HP cprtP3desclwtptbkptrXYZgXYZ,bXYZ@dmndTpdmddvuedLview$lumimeas $tech0 rTRC< gTRC< bTRC< textCopyright (c) 1998 Hewlett-Packard CompanydescsRGB IEC61966-2.1sRGB IEC61966-2.1XYZ QXYZ XYZ o8XYZ bXYZ $descIEC http://www.iec.chIEC http://www.iec.chdesc.IEC 61966-2.1 Default RGB colour space - sRGB.IEC 61966-2.1 Default RGB colour space - sRGBdesc,Reference Viewing Condition in IEC61966-2.1,Reference Viewing Condition in IEC61966-2.1view_. \XYZ L VPWmeassig CRT curv #(-27;@EJOTY^chmrw| %+28>ELRY`gnu| &/8AKT]gqz !-8COZfr~ -;HUcq~ +:IXgw'7HYj{+=Oat 2FZn  % : O d y  ' = T j " 9 Q i  * C \ u & @ Z t .Id %A^z &Ca~1Om&Ed#Cc'Ij4Vx&IlAe@e Ek*Qw;c*R{Gp@j>i  A l !!H!u!!!"'"U"""# #8#f###$$M$|$$% %8%h%%%&'&W&&&''I'z''( (?(q(())8)k))**5*h**++6+i++,,9,n,,- -A-v--..L.../$/Z///050l0011J1112*2c223 3F3334+4e4455M555676r667$7`7788P8899B999:6:t::;-;k;;<' >`>>?!?a??@#@d@@A)AjAAB0BrBBC:C}CDDGDDEEUEEF"FgFFG5G{GHHKHHIIcIIJ7J}JK KSKKL*LrLMMJMMN%NnNOOIOOP'PqPQQPQQR1R|RSS_SSTBTTU(UuUVV\VVWDWWX/X}XYYiYZZVZZ[E[[\5\\]']x]^^l^__a_``W``aOaabIbbcCccd@dde=eef=ffg=ggh?hhiCiijHjjkOkklWlmm`mnnknooxop+ppq:qqrKrss]sttptu(uuv>vvwVwxxnxy*yyzFz{{c{|!||}A}~~b~#G k͂0WGrׇ;iΉ3dʋ0cʍ1fΏ6n֑?zM _ɖ4 uL$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)Km endstream endobj 6 0 obj [/ICCBased 5 0 R] endobj 7 0 obj << /Type /Metadata /Subtype /XML /Length 11 0 R >> stream 1.4 Apache FOP Version SVN trunk 2007-04-18T14:42:00+02:00 2007-04-18T14:42:00+02:00 2007-04-18T14:42:00+02:00 XMP Metadata Sandbox FO Document endstream endobj 9 0 obj << /Length 12 0 R >> stream 1 0 0 -1 0 841.88897705 cm q 1 0 0 1 56.692 56.692 cm BT /F38 12 Tf 1 0 0 -1 0 10.266 Tm [(Hello) ( ) (World!) ] TJ 1 0 0 rg 1 0 0 -1 0 24.666 Tm [(Hello) ( ) (World!) ] TJ ET Q endstream endobj 8 0 obj << /Type /Page /Parent 1 0 R /MediaBox [ 0 0 595 842 ] /TrimBox [ 0 0 595 842 ] /BleedBox [ 0 0 595 842 ] /Resources 3 0 R /Contents 9 0 R >> endobj 10 0 obj 3144 endobj 11 0 obj 807 endobj 12 0 obj 178 endobj 13 0 obj << /Type /FontDescriptor /FontName /Helvetica /FontBBox [-100 -212 1025 723] /Flags 6 /CapHeight 718 /Ascent 718 /Descent -207 /ItalicAngle 0 /StemV 115 /FontFile 14 0 R >> endobj 14 0 obj << /Length 17 0 R /Length1 1914 /Length2 26299 /Length3 544 >> stream %!PS-AdobeFont-1.0: Helvetica 001.006 %%CreationDate: Thu Mar 15 08:57:55 1990 %%VMusage: 26389 33281 %% The digitally encoded machine readable outline data for producing the %% Typefaces licensed to you is copyrighted (c) 1981 Linotype AG and/or its %% subsidiaries. All Rights Reserved. This data is the property of Linotype %% AG and/or its subsidiaries and may not be reproduced, used, displayed, %% modified, disclosed or transferred without the express written approval of %% Linotype AG and/or its subsidiaries. %% Helvetica is a trademark of Linotype AG and/or its subsidiaries. FontDirectory/Helvetica known{/Helvetica findfont dup /UniqueID known{dup /UniqueID get 28352 eq exch /FontType get 1 eq and}{pop false}ifelse {save true}{false}ifelse}{false}ifelse 11 dict begin /FontInfo 10 dict dup begin /version (001.006) readonly def /Notice (Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All rights reserved.Helvetica is a trademark of Linotype AG and/or its subsidiaries.) readonly def /Copyright ( The digitally encoded machine readable outline data for producing the Typefaces licensed to you is copyrighted (c) 1981 Linotype AG and/or its subsidiaries. All Rights Reserved. This data is the property of Linotype AG and/or its subsidiaries and may not be reproduced, used, displayed, modified, disclosed or transferred without the express written approval of Linotype AG and/or its subsidiaries. ) readonly def /FullName (Helvetica) readonly def /FamilyName (Helvetica) readonly def /Weight (Medium) readonly def /ItalicAngle 0 def /isFixedPitch false def /UnderlinePosition -100 def /UnderlineThickness 50 def end readonly def /FontName /Helvetica def /Encoding StandardEncoding def /PaintType 0 def /FontType 1 def /FontMatrix [0.001 0 0 0.001 0 0] readonly def /UniqueID 28352 def /FontBBox{-166 -225 1000 931}readonly def currentdict end currentfile eexec awMm72:^I=17$l"rLGR+/wsFҧ.2I:t.=!J2RbY=ʄ?ߪ5o(2na;h8No0:j)cVhL/)X͕%+h~Cm.n\JXڎ 5/#L='Q]PeˮQG_Yra(%|8$fv04^ DIS<ڱ;ZG~"6-p$qk)dcfvhMlPNLd+ɪ?^ R>]C)}10[1=쒮.d }[}0'8 $)@NKt2wbЖHM:ފ\[45Ds/޴m*Z {3%m^ˀXu[8cGp&Ly({7]k"b| ~A]ꮻXSM#2D=|G@"gkb$jdm΄!zXPk!АJ'86IQ}4H$J#:ǽh'%J(8wDF.Of`A_%i Ԗ0n(w",FOGmKH:.Yww McRŠ<)I%x}˱R}9@ g^wXm+w8JM\_n9(Sڒ7Wt & B$($s2b9_n2?$J|րCBW:u[ۑX߅m\.~sK[Zʅߞ[ZLZ,nŭO[50?BP(Ss쑙4IDeD7Sˢz>r hqOFz.BʥQvql%JXAUfq7>y&)v7Z1~]v@yY=k`d] &g- /8wWNfƄ4`V)ds$m 6Pq 0P NY};3I'P5z;gL-(y^9'F_&=fkjNŋƒ༖O)+@9 ʍ[H.P,p-S:N߶%`(imko }k@%>{T阆vKe՞UZu73F ZMS\?W[^I· E=vY>[tFF!?ae"^l]/.ǃyOB])@IGi4YqM\,IҺT)BYw XO6ZCaG6s3`'&FԾ '_('~N9):h] '@H o-=,FQC kL GYP0 1?dytip1@I-:rSˏQ.R} ko#4Y~LR}'9#Ɋ[>H?tm6r(\~gïŁ)\9?J:xS;1M3+*ZBR'a5fg8s\W"({㆖uI1`[$V)Yq{E])EL=PJHKNm؟7sDxi:='SAJs-_ 0x{?-tԸ"Lp --bc*ѐ(%%J܉>v%#e6l&1:1)t2H`|1{&IHr|XeT[ ^<<>'Z{q{jrv93t/(7oy=uW/(YMYڞnG FBXRcИ {63{60X]UGzbh5+8%5$_`pG==Xc $ T+Gz+E|+ϫi,@w$ 5\Y+H82  xTYabSh W߼$U>> J(9(5cۀoA~ 18}iȴ  xԵ?]{1A4GKj_*D=0}0&оXD#mfK%k& 9M:(p8$F| ܌:]ѣ*W|_ӥZ,! ˫ʶaas 1첐3$R׏ >CFn^-R֛ S-űz{exΖXwpj|*aT^JGp<+)whgM}ޢ\.'#=C+?-Fgð#@62{=9G I\7U:<_kDЈ9>(C\2+ Af^N HؚR'eysfcj`NEScƃk(fuu<[JaE_^ Ϋ’^ @؉L#WYL$8Ә^H]?~_}6Q5zvUfYz?ΨxHNVڴe>йF &a ޠϕ =0/EZ(Uk7xlt3_+S 7%燊q.4ЩqUϐ&02ʤj<|E؜)Usl^mڧbƛEcvt'i˰΃7~JbofRWfܪIGlok2T01rI ,J3s J2le bFD/QHn nXN"ƀ8}NꈺL+\!!g#rMWЇ}EYJvk7{g61靣]憹kMJt9P %[u%=P|2l' 3-Z0NЦy:-rl!Ef;J #RMe$"uH MԚ QL딺D$k?{F=uP68~W F(`a{)Cu[k>'rh%Bk]~U[0e%[-?Hg"`;xBl=N2B٤P1y0i e|-PRږGm-  7 [:g_)8,ۣ㒒`k5_zsLOyS-]W9trtx\65wزpv/!ι;B*PY`_~4W BAܒ{2q+1P@]Y 2=/&>Y=HNH1L rD/2rytP(R_fTl"(q/!vaSx:>Lqn+dyJ=Cf:EᏇ8[kȤ9[o5u$nMŘSZ xu2I$Le::]& @ad.K7Am(, 5zrfm/+Cq6ո XnToH)4pp/{ԡ+Cܿ"e_=MKT qWyAS+hK+/=}q1C^evM y&3R=~/*93>.\AcW J?gށ2Vm޶. u|z>'p w_G?Qx9'X-vm+{9t^k'tۃ1CB܊l-o}Agyq"(Aiim6xgu9 =~ς*[q3}c- /HtB=x5p IDcC02_[xGs]Af*.\Y{Bp=@? Z(cHب_Ώ{ !}tD0/}&4w"BFI>u L 'b1b?3X۠цdgYJ#VK;RQ׳ʢ'ΩQXH}ǏRC[6 #S/hz#zR1h:QNk a-OK%@)Z9BU1U g`õqqQ`8#R&'B5ynb$A^[Wo:l >\*Hnjt5Kr+^WHTS݊؉ 3p\vԍc9#[޸SD& v}l ;nb.EJQ}W%bW2*,5;x'Fb5MܢM2w^SG$gر]$ ߡ"*ֽ17h`w̫SI]..GB|,ЍJٛsSZ1/-)];܏>MWMl+zZ ĞgtArǑ {Zڀm1[ y9DA&~T_It&4E5 GRg,˿ M⤋)9F)~CPNVE)k3vF텢0ŀ=3]gt/d-ɈˇK>BO&̄Ƣ}2PY2"RG)VP}[(OcT'r6z -菜_6ĹCZGz^a.6kD48Lv:4"؂ خ<{Xafd'-ZoMvX47yb%0~=fF.ò \uCX~}G کHT_}1E)ǚBi\2틻Ta2}80mpej7TƹT)PNda_Ox:-+9KƖ+hVNaxG-M޸M:u`@RFIDɵ?gT\|^/W=TQ*T^ތv2.,2u]@"Ts)WJd?lL@lbmtɄI t gbA; $K* ŎFQ*Ϟ5;Bo@m?3Z=dHanWӂS22ɔ_Vn}jᯰKL{4 f7*}_!\A 8)k zOԼ3QtMi ]^gS\x ޘÇߞY+|3F8_=O%0Y宥xg2q}t]brf"8&䃲.︌k4Ӊ[60_Ģƈ 8f:V~ýۡiNO\ᵘCL_Κtg8"07ډ/J#&jectL=+!EΥwBC EEU85?='Rpk&1o͆&Vux-OM uD.7R/P;B3~]oy)*TJ`L:+ v="øoc6 CU'MozK%/.fauZbERA=2br_r:uգD>)5 f Y`[<\{˱bs+].h^u69ÓyW*wUƢNm1 Q{`VZ]XH R/L r e\ h"RXH$pf'c|⸏ _93/KQ ֜5"ݬG͊ v%.ƅ΂+(%ϬowDf4K +5ipdV_\)߲2bq)Nc|L:%b2 Y)ZkpM?op,JZ%\'Y.JyWcI.]Җ L$F^$faŲA~)jFozY216W8U!+iߥ@E9D>?`řW}}{hDK0/q' Ӿ@$O_5*y,oIh)j&AS)[ 2S]Dmm_%` Fuv xh@Z2ˡ-~`ւxx;`q~zn[S@qp[( #ɼZmk@.wueU=qP`mT%g'*:lY}x${ԾBoP2VtՈYHĸl$Rr)ɵ .qR+{ qڹ2ojC$3zn9^gG lVzO ͵ -2}2u?%HWT(Kb4lUie-[hwRa6JupÕ /OHR_5U'D^Uͯ|Jj#r-_Pz 0i?pcپΊLGuxck뎅8#1[{x4ܟ֋(t4"^Pf T}#Xj@bRs7q[4Eʯts^[YB u!aA-]w)enuk7_hshχ}:Yd]Um +torꊆy&ό^oGLï%+Dϐg?< *\p>d2O b7'Pg*_0~hҏH=F;ew}gb :Q9'Qr33=j]M:{&Q)'ʽMyt ;Pz7!t_x5Qm;5b7Vjeٗ>^mDvE u+AV&ƒ Cj’mp!g< dZ&w 0D"fAM!Kb[靟MLj'Vc*'OBݟ~!+')ssTZ${Ln-F+5[J0,PeUܰ1 !.CK0Y"݇lydgtڱ,BfEkO$-:U3jPCJqWh fcC^3а SB η& qʪP ?ȗ.M:`> mDcsh](+^\*gW/)p?jyﲯP3!$7MΫsqR Rq*ݝaܭKnG~u_5q(Y/)>A3Puju槺ȏQfl8èoZ߉c114%8Ie}&5>}Wn^YJPOM*F4ɳU*s"*U\u1ww:!P=| l-U>fKQ܇= 4띈E<ƜR lYDRE.G0WZ,ȝPLu^o߯kwC05‡W |$dtDHI͟5E*snRLZm๦;ӫৣZ3~]go_.O(irĒ-[>1̕Ё#lh޵hò5Wܮ!z]Ru72ctSnnKXE J_.ڽ9ےnibG S'UXV1f fc}DQvey\0LU@hPJ xtYɀ64~ȏt s&42 #01,ԎǧN $>ʲ+8뜮_.* e2[Fkc;% Wd5ϣ@VDtAAiBH] |/s])u815rܮa[uoLRdw}EP!}{p˹gr`lroSEX)JJ!i:F])bf&JhD>)0983rPO?P7|U-Yc&j xɛq\1'iMfh^xrt ~LF>%mO&՘3r0b۔t+S&/jA zV[95gfIdnkgD C޾.A=&IpHS@>{it Gw㋊juE-bƏw3=?rT W!Gwri#No]:'|[fHLAKߤ80k&1c*ͣFx4)jS(Ml. 1#V(P26I̎Zvw{ лۤtb(%Gʯ@?mcАe܉`yIuψ9f3_vvnO ;hr*! x>Wq۫^ tkn @"@ֺoP ށ*2`Ұ&yb0AR- x  Yr߽1mL%{ |I*}. o B:3G頴919y;7@+_'vB*l+ b[R?R*/s.O۵)EKZ}z`5Ij9 #|rzB1e>fJ3~-"NowAI< BǻC Y<#gL)1LakNu~9jkY),Q[Y{BgR| [^vfҵR2{8 "L橁r,w#?W?ab';N3 ghz"OǞjS҅ԽO|$?iǦۆTZwvE)V{g??`W)?q68{ zLH@ ׶WG]!YK?~~'@Pws. y+9]z 3@Z'ϵi&%Ж%!zEX$[/~#Op$-9C%%J=:ֻҴйRԨS_}PhFkl!sk?F'J)Qw7X c<|hj5Bq ?mݙ4 'U\PB;g%<|͘BXtG+q<,6BoꍋDh'B~24a{Uaű/9C'}խ`bMC^|DSMa77WI,VH! XqQ8_M+v+C|ybzør@=Z:%vMp&Lɝ~D'N` *Co,a`we7J ΈuCy͆L-RLHl/uM}6V&n`$(ژI?\I 5ٱD{ 2M[YkQ&nآd4`,0GǬ-PDYP lKyrz5V1ɱ*4i a?,/k a*KnEֆܔTlIP[k(gk N7'ѠJXcW/*. 0#dlŕj:|>4af3pZ*Vi !.[] tr2'ϙkvzs3Q?|ٿrMRcjٓlQNOIbSZ%PcOJx"iGLyƧ.k"r= #q[p`8+=~LߌnC-*˦{S Dk(\?(K:U_<;NEz_8ڇ|(/] K4A+4@`N.\~JJ~..i0 6 W,('$/Ɲ0u i2:{ 0 zW| j1쏀4EfdE`P&(-]Wҕਗ਼j=MXmAO~lhi MBfn f(6].HP;&m5Ri9IQN!-rȉU* #"+%xݤ}ҁ*P[b7|9*ss&uNF :r Z5ח~B+ V"*^mM6VCvYhΔlNH}UMB}s)%;޷yL'@.](HR; b)fެOK[cx+dWQ/B-sgh5 !&(JkȭĤňתieP=$] "|[k)~#m+)ʭ{^"fҝ_5;a6X}`Pb<Дi!{aǵyW^?734u,SKS7}  U;9vI*\JOl|IbU@_WT*T Jƃqi#=\p'iG%N/+d.JaC#;NkO~/f*ȋW>\){&w^v\6a_uKʠwߍx+,Rܡ|L cѮyMHc܉x7eAv /d|}Ј5e/;wb?5^<>ZtCaaDI 7[*.ŭHαr=ޅ(`>P I|5Md] `*2Kϫ&>:iCݸޟocnM+I e_VL$w=^= \& 9_<=sNC7)7Pm.]V`~ÁeᓳC ]{!XO?5  dWmV?U2ox Şy&;ڗcnqVL'ܒ0 cK͙| yC].qrrA^,獩Zb6Sְm_ ǀ+gng@&Yi[l#SnOZJy9^:3Y@>{CXA-:MH >綒рtm/~y+<A΅':r?=9LZ``WKu |Zk_tkC~>-G-S59BNU. %a79\ r#(Iyv4oTOY<6'X\"mcI=KlIe~oEk<#UeҪgbL]ahr؛A0W<$2vG@8 gUCOwGA1@.`Cf9ʜ[~=!"7M0\L@ښ V<蜚 t|D3:SRcUi>⸱  *Ud^Tl׿⢍GY\jR. Lu\ ssC584' $7h72m-n6ym, UͶ3u5#f{L@h+wCLxm~Q [bwg!ށ}ʡ q]჆ M*L]ϥMSzއC`ouۺ&6x]JQoypϡW c6h+p `/ۈ;R:! j'Fg =@s#~њ\zO d\>DKݓl!k]Ϳjeٞ0R b%<,D<;؎ߛ["oꮼ~nD7DNuuUF%60(,vnUDK !T/ yG°7;N-1ך'2'7-[m`/zT@uCc8U.+,򝚓#PN[Hpoj;[7{2c7gX4`"p*xU]2uw̩̿)kO-^gp %4jl7s Y}\P?<1[i6CuU^hb'ɤM5*dmt5/dQ(Q@]_LtJtt(!/oIC jܱtrwCň.b( T] zb4V7u)/%Sq)ǢS{+RO; 8mX8ķȣ;L{p[&ᙢ o`bd7R Or>D{iEg!'w9vW&AgԬ0jɾ9_rI aě Q2ONsdG>sqJbU``6q8Pk*3< WB J v$LN0&b1L4mGF FGïRq:KVo{ԽLڈwVkZIW|>`m`[vUjiVDEx(I4·fO-_pKVͤiD(Hq}jU$Q{Q, y!\ }3AৃO`}%1P¤USh-5a9u%Mx ˪r\z@lurdVhS%&E2#ұZ^Bc&tW P_avZlu8[tbAX?ipq!xʡbax74I,ɸx~"3-!r׍/)<򢗐ggZMFvʶ: bb7fA!70ܯ21G0SssVЮCDu~ +[WnC:(yi'ITٽ[+ qMO'{)s-:ԨTUԻ0]+n1jV$eC﫹==@So*A+/UrϒAw;MH,й?U\%;x!- g?d8YD;Fz^+N8T:t= G࿝bjg!mMh?;ÆKSu {^glDP6~VO7mWƃ{VB:O\iuq\~;sEq>4WUѕ WqzbȘHT#~D>?r N*Y[%/L|O<,n/*9Sb>(!3oum`eeyIjHMǑ͆U6)jRv`Oԅ:?JGsA82xZg& }koɸԛApC i3M)5ӑ˸S–`? Rܥ!tQ_q\ ,c69\cN0RNZb:I! v):"i %h%BQ8glH%í\++*(Z?zhrd|3-ےa|ˍ@V`94Ǥbq(BŸ , :$z`^oM} RSΓ{3_Ed{Ii؞Ё~NQBGI)8\eѼbQ|pVEP5-ړylo$q(ŕC"dYx4n%PSZ)LZuO=ilVpkriXv4R15Dk:}Z5ie/{yfU&64 `@W n#jkg|'Ǎx:sk;ݣWUIbv& 1K̋ Fҏ9il cш(^wlR}SsaE/?͈Q_:P ap ײF Rb x].r͉ xk-n^'{A+켚HPq1)= дn1hݪ 6CEZ ~A7Oӄcս%֓fIIwD! Z G=n^"&8a}vHmr–fhIj>9Jz I/FJoM[ߑ dBnAM:`E٦H' IVnc7! i' Q.CX\Hm5ul[+Lg-?$#dF>w)*Xm}s!ݤt0eT|t9<۩kYCmxr?}G'4Cǫt `_3OQ]1M$t =79v]R`rRِa1i58o+X|]d!GQH,d_NȮ)aeƾKӦȹŷ,8N7()sT^ W3,u !l14Wr~;Xc5^AS^z[pVu4{5l6vL^QɁcUG1xyHT`']_qza+İhEk}.24;6 s_oY774܉VD}l7,Y8?ۃ]ho2)P[qei3i078N ۜ;6[Rߐݭh`׹]h1сU VPkzIz6q]h UN'u|m(Ĉx)a@a4ǚ.*Ơfi8e߽#0`:mcH\kO/ t-u֡< UϮІ%w[d2YESx?7Ʋt*kea2RZQ|g}؞ʥ]YɃ xeȳ*[~^C 9zy8DՃ{`ԍ:CD,9t2N >/ΥՔP p?a.ė jcC ґ3i53)$f~qLMiG wzߛyt{;`&е7ȆNV֬ىAJw-B$eOلT6^h?VOѴz=WpO2i(eM #-.dέ**vWHwǡT q9-.%o0`9FV7\ 7mɕYġ[OHF.z㋞ |zfX}:ٮuq619N8fcXb#ЈK\?\XN7:7[n˼bԘ'\')i)P2wX?_Sv&j GmVD.l~X 8KI sFf`Uwkd@U[dg35`wcۧƚY PH_ֲ HiL{T>7qߓQԸ:cA@avMojh^Tt3QwV;N'`+tKVu8/ʃ:i{!H9A90)ͩ/3`ȻĔ 2q,rY,a,ld=r·nTHar)/6yZ /Ap[u8WEo+dU!GdT{ ƙ{m xFo͠/רHr\7A^ĀF褗>ppK,osqQ!kTm^f ,)s1j⚱9xFC S[~ʳySŀrD0^CZ.-vH&'IԷs[(ri m^-tHvx|aKhMSn#a$L'e'wq6ӇXMpe6:F! \c/uXa&C![FS8SrUK0uxt&i}nCۙnPG>v-j VOܗ >*$;R]8^/E[-N#lSAC`W-0WS(N Q-P8ΜԯR+xz kKrn6إMZkQ0҉Khs8(;yǏX ȳ[ppy؁J%HǏi68߸_b:N⟱ĮIҰ7埀n%$ih6.6,i6[d:q,oGQWϷlwR,+L>5UI޿r,B_X! 5h ~81@[UF'CU hKGUZ]z2y˩/!̳ gKJKp^]#7gA33)ߑ1iHH+5P>;`Xy4Bvz2j'(DUHlrJ#j yV۷؈^zhȶߪ]=E_ I._Hۂ[gۋPaD`V{'9#2SȈ"[xZQ8;^+S1wۓKҞ8:m]+̽E!Yʨ`3s/UiEl<Ut -O e!M LCl v/@y,6:H} 2VYgDvgnςhqWG&d՞rZg5[-nP@BX6/6!I ݩ[0%fω.0 GSBnR>]EpY3`I]+^ǒ^(,ϒ0@E[ok EQH9- LE^/\%', {Tk+t &WGߕ7p^_ˤBoaQ&]gw0 c@=nYP/-IO _&dqsθs'C&@IO.P|xRE3&9j,T9{_j9e#Qg\"(aZY2\/Qin??IiW]I,4xmW˱aolky#Ri5Bbi(ɋс9bφW~m E&0PW{S,(?n].\gٷ,VX^c%˟CU»Kd T,Q3V Ӣ&*02k^C?=kLPk-rS6e#m‰}OW~gVӁRnA*ZzCˆct2X i `3I_[ aUw5,֚[<bSpMLnZz14 0 8R0S"ۨv?޼2xѡBy['ş$ hR\N${1BӤ@ha^|Ҹ|'ϣ]`E&lLTB@mde88:h#ޤxc#Jm!O璔yHLmSL( 7Wl]Q8­Y7lĆp01n0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 cleartomark {restore}if endstream endobj 15 0 obj << /Type /Font /Subtype /Type1 /Name /F38 /BaseFont /Helvetica /Encoding /WinAnsiEncoding /FirstChar 0 /LastChar 255 /Widths 16 0 R /FontDescriptor 13 0 R >> endobj 16 0 obj [ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 278 278 355 556 556 889 667 191 333 333 389 584 278 333 278 278 556 556 556 556 556 556 556 556 556 556 278 278 584 584 584 556 1015 667 667 722 722 667 611 778 722 278 500 667 556 833 722 778 667 778 722 667 611 722 667 944 667 667 611 278 278 278 469 556 333 556 556 500 556 556 278 556 556 222 222 500 222 833 556 556 556 556 333 500 278 556 500 722 500 500 500 334 260 334 584 350 350 350 222 556 333 1000 556 556 333 1000 667 333 1000 350 350 350 350 222 222 333 333 350 556 1000 333 1000 500 333 944 350 350 667 278 333 556 556 556 556 260 556 333 737 370 556 584 333 737 333 400 584 333 333 333 556 537 278 333 333 365 556 834 834 834 611 667 667 667 667 667 667 1000 722 667 667 667 667 278 278 278 278 722 722 778 778 778 778 778 584 778 722 722 722 722 667 667 611 556 556 556 556 556 556 889 500 556 556 556 556 278 278 278 278 556 556 556 556 556 556 556 584 611 556 556 556 556 500 556 0] endobj 17 0 obj 28757 endobj 1 0 obj << /Type /Pages /Count 1 /Kids [8 0 R ] >> endobj 2 0 obj << /Type /Catalog /Pages 1 0 R /Metadata 7 0 R >> endobj 3 0 obj << /Font << /F38 15 0 R >> /ProcSet [ /PDF /ImageB /ImageC /Text ] /ColorSpace << /DefaultRGB 6 0 R >> >> endobj xref 0 18 0000000000 65535 f 0000034965 00000 n 0000035023 00000 n 0000035090 00000 n 0000000015 00000 n 0000000159 00000 n 0000003363 00000 n 0000003396 00000 n 0000004521 00000 n 0000004288 00000 n 0000004678 00000 n 0000004699 00000 n 0000004719 00000 n 0000004739 00000 n 0000004930 00000 n 0000033785 00000 n 0000033959 00000 n 0000034943 00000 n trailer << /Size 18 /Root 2 0 R /Info 4 0 R /ID [<9AADD1A866DBE5F9C9E03B455D207979> <9AADD1A866DBE5F9C9E03B455D207979>] >> startxref 35215 %%EOF xmlgraphics-commons-2.6/lib/README.txt0100644 0000000 0000000 00000002023 13777276623 016367 0ustar000000000 0000000 Information on Apache XML Graphics Commons dependencies ========================================================== $Id: README.txt 606580 2007-12-23 17:45:02Z jeremias $ The Apache Licenses can also be found here: http://www.apache.org/licenses/ Normal Dependencies ---------------------- - Apache Commons IO commons-io-*.jar http://jakarta.apache.org/commons/io/ (I/O routines) Apache License v2.0 - Apache Commons Logging commons-logging-*.jar http://jakarta.apache.org/commons/logging/ (Logger abstraction) Apache License v2.0 Special Dependencies ----------------------- - JAXP 1.2 (Java 1.4 level) Additional development-time dependencies ------------------------------------------- - Apache Ant (1.6.5 or later) (not bundled, requires pre-installation) http://ant.apache.org (XML-based build system Apache License V2.0 - JUnit (3.8.1 or later) (not bundled, provided by Apache Ant or your IDE) http://www.junit.org Common Public License V1.0xmlgraphics-commons-2.6/lib/build/hamcrest.core-1.1.0.LICENSE.txt0100644 0000000 0000000 00000002711 13777276623 023006 0ustar000000000 0000000 BSD License Copyright (c) 2000-2006, www.hamcrest.org All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of Hamcrest nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.xmlgraphics-commons-2.6/lib/build/hamcrest.core-1.1.0.jar0100644 0000000 0000000 00000103034 13777276623 021662 0ustar000000000 0000000 PKpD:META-INF/MANIFEST.MFmj0S H iMI(BעGTJ.WΏ1IofwFkiC̿vszb)ՏGFQB3:&"h8^ mP̳!{6"Yin6law/T{"<)gVa+Glq"|yx![xoVmjV73ZT9"o⌳?PK>iVPK zp6 META-INF/PK yp6org/PK yp6 org/hamcrest/PK yp6org/hamcrest/core/PK yp6org/hamcrest/internal/PKpD: LICENSE.txtTM8G(iZʲ9adC,f8mĭ$44lV }Uʨ&GqѾ}o{ByhyƗ8b#Ҍ[xi:;ͣ}> &Cvɝքg;4O+1|GGH l:zݻp_(ǣ;Z7t7M7_JnZZian5ݗnQ nFB jv#G\CIcc{3.3;Xa;* hSoODPof38L7$݉. M84Zj@Bb? \lN@#3to4wKh {E.'w~]ʹ~Wd ~K8,4D\(RJVVO"-sNiK5UqnK-Ų.0/}[ɕJl 4KVjUBL::! PYi*Fhv%^\.9Te/L -O?v'WPE؆ T0|>B^*-t9* Y+.DTT>Պ',0a\8ZJDV|wH*zpUȨ{c'91>-QH-M*k^W+?`^Blӎr[$ĊX$c,e y]2 PKs!!PKpD:"org/hamcrest/BaseDescription.classWkwG~Vky[חӸʱ imJ@*$NSZRUR--p+V(RN9>po<3^kmEi{}DVZч>ₘI(VJ k4TI<+4<*J_bO'E|IxFųIlWV|ϋ/ ׄ[ᚊ)h-%oLASf >^MlxL3eRYΙNI|ĸW, vLTpѼw,t,7R> i[uS08o^6˦]]84{R.QL_s93Q}Vyge\oP[N̜^c3 {ΉK:z?'zC{-5o:WqX`ѩ`[.ژ~d`^!<:uFcEo܇T\C9Ypz G z{Woi(nh6Ƨʾ5OT"O|;SPCA=bm#ŒZCg-8<ʙХhXnKZC(ZFecs=xf\t0'lϼ^*E,jg'+U'o-6ֱ6tŐ3}j}= cs>^d_~(α+c?",浽] ub,"q\1Yc:~e:D\<`w$%0l<|q̅՜~>W a~`_}%+V咎Bot/^S :FpPğ>1bp@{=<";;nTPoܚܸD)ӉeʋR^南MWܮZI<p\.i̺_[u]6lO`MB7&D̥ 3;{g[Uӧo-H0·Fsٲ ^QΣ,RpDHe w񽛅A>7q8̯a 焱\͒v@Q|3{#>Gg.#f'%B)b8 -eGe-Y-4ŰAVmQk8$ՍⰯN)[p]+ldEbKxuۍeh.eIkdh]D>*ބ.|Mo ]n&wn{ݔ=e]F#5tήtZB:1=D/:_;Џ; .Fa7]x{0] w2p13,(qe Uofe(9_01F*kĴ'D]7ѽJuMr*&W\5x RP"2(Hc;`6[UVz k@B m!H~*DP&B K"Re% )l?_ܹʑ(J* B()>"(|7 ޲L@;94O!&^DVP/!Sc]m5>~~0M1iFv !O£1fHHHOmk?Sƚobﳡo'hdM{] md{٘lYǰs;NjVJT!nrs\X<'<ZXzj}{ Ev( !/.h4!~|NFP8x#h乞$ KCF0)kK^qdtlrm3r2r=Ch]psYry xeVl 'YO5+Č9RPK5RPKpD:!org/hamcrest/BaseDescription.javaWO0~){ ayM6@7uZDS&'u~4D@Zw磠-]1劬]"ғ#~WRT~ %+r%׆f%J}SkSj )郚 |LRKp: |egHt~zz|p?d\Be\hGk+5l T6L(@8L IFT1bLJghQ0?:dzy*ȎOÒR dΕ}^OFҨ-؜6,y6#&/j񛡎m)Dv޽QfYkS$4#L1 ܽ"ay =,íy 4EQjOOkj'>V߭g45|=>nƝ0 lo/͟4d9}19 +?jń+[Ԣ%%W: g_Zps"4vU+|,Ϡ jmFp !Q- .,Ju;31 -2f00R0 m7T獣(-Cvû)q_\qt.1or^nyزsEWjTm[*޲ŃemjFKfw\څ!Jɚl+n|c=7;Re y}K80I#vakrNK3v.C.GeHO1a5-r1=D0ЋR&;(=IH0K+`.S^ AmJjiLMIuN:{EiBn_"Xdy PK[l5PKpD:org/hamcrest/BaseMatcher.javan0 Ew}.F.)ZtHwi[,(CyW*2M6,,ax;%( գƆ`˕RE 6c:0sbZb]#/(6aΚ9kwQh#7^^7JPS ^UsQ+MG!_3X&V1)]m=:8[?CXHU노FCzcOim U>1Nןb [߀yq${INѰGdrRPK:(PKpD:org/hamcrest/CoreMatchers.class][E[vmKK)^JjMj4h"hu [X t[yzwWxCxf l̜ϙٳ0_5\gVs6_hl5hj0a&ؔ5fcHJ^Ue[ެ@{rtUc4-\nn(S2ʫks0m[nݒkVԼ㚋W6JZL&kzX [ E- K:;5Yr.X[U]Z)Fl[gbk#XcQm 4ZhQD(w=MXfw<H|T5EzΞfϰKCʑQ.sJǼADReLf< .mtӊL+QucZi|hz5siRq hhJ%П|&Bm7๴KtrOokycS`䜵HW;5K~o4oU]-S]kNcBe/ktB[zr[2[iDM2IG?ٌH{>lFxc7x&t?9~I^g#>H:Ot,aY` S*pNChyr\TK\pT3 \r XʳjVU!T4(LeyU(]%*=v:m$v`^[˸Bm7_Zٺ!ڞSL*Qzh j|ǎ(2?MbT&1Vǎ C^ acR^La&2 2v4fI蒱310&dl:iHܞwc)[B[xW{umRK%Id슄4a߯cgIRiSR.cR%X}En٦nU;䯠q3L T'{,!g#\m?$HNy<9~T~Lؼ*9+SȢJY BBze!?v8&'qQ?õ%yqK{+PǛ%"(>^PKiY~PKpD:org/hamcrest/CoreMatchers.java͘n< y $E>vA7|uvTl&*K$ (N8ٰKZ$O" C;L$FO AxhT )H$O% F# x-p@ex JsX`BX)l4ـb9YP>V)`?qŀBwcZ-^(Qd5[a>+qG7-:RSWywB(QD,([2~ng:fڸ*tiH*O M?'>:)tSk=\J=PJrs'sݛQ#]iM=hלIV;&.= :oom&Uz!3֠fithP4& T$^DOUYV0[|z4D+׎{@ oKԫոGʖNʴ)Ĉ ` 9r]jYJRawp {-p$ỳj$2J(*\+ dkPŬV*BT)[5}A{HEwp{2ptdgcLTX^_{h |JAWI#Rwf J8Xr!UtjG]vF럦/v~˂53j%] ZQ|PK'&PKpD:org/hamcrest/Description.class;o>CQvavFĂԼԊF= IJDļt̼tkMt}̂ /d YBPKX)PKpD:org/hamcrest/Description.javaTKn0]7R0R7pJTjł{L-۔Vw'*z8og"j4?"w/N# \S&qa bbˠS.z5~PK=[PKpD:org/hamcrest/Matcher.javaTn0 +^SK ]u@3h2mk%CE}I%|QvVU‡hEScfITū$Yf /k`RbE lEӣKσ U9*E(΄FMP Ռ8n}Dk[^xeW)`=lPov/akJ@i|p(9uKn~O=U҃lssFj%kTj[> d߁*k.]g*[xG,Bi4&lPA/ r8ǧTkvϡwu<#s1X6ɸ16|0q`#UNj+7y5%P\G"qkCriyCYu,7+sH&=E$@O)?3̎(B#KJتXn])r4nH4H.!E  gUR~!lBIs3g) 'M!c^{Ւ- $b2/G_VĤ4;ύYAU?",F͐`?CH\w$_ e6#Qc@ A"54gTZ( AQR4.nL_ơa~1 R'1UdQVjYK"f:*/-"ptlYwnu45`9=19ݡ|1&B 5_ٹ?KGM;Ի(U@Vc!0˲CiXZvM}PK^(PKpD:!org/hamcrest/SelfDescribing.class;o>CNvvvF̤Ԑ|FY t}\AIf~fPqp~iQr[fN*#ppjNDERf^^VbY"#4J@sRK@b`L lPK lPKpD: org/hamcrest/SelfDescribing.javaeAj0 E)lC`6] (hXV: wKh }RB#䱝p;4vXo `.T3wКQ) lt+9j+EʨTIYf~kaKxNuKVy(H&ub? ػ,EMeN)3$KWz̖:*EyNMqP{}=7PKkYPKpD:$org/hamcrest/StringDescription.classSN@=C'N ,!4-]PB.,] T)-RAT<:@ %H{?'Z3w'%L`bZFa fqʘSa=9^H¢n, K |m1$Jʱ)^~\ %M,l3F3JennD*mľ[Uΐ*^&[MU^WM hg2% 5(^m)q4K:pl3vc)(KzG8R!ȿX˳)͟.:*}Exa*_DOoJ0 ]\ZQ1(d`6x7EN,cV8qB+niL VI醕:15*n8Vh]y..m+}+{ ôҋUG6U1p&1'.V4N>LS {~#K".# f/vjwJ. *ӟbГXN.1`Lp)S7Pz^I@J4[Hi^Z#b4){_A'<8?T&O dC^<*PDjU|D;>@.|ػ tL6uGt4r͐,sҡJ\"iA݂$1a }O?MYn(nϐL*z-VBޣ S1d= PKaWnPKpD:#org/hamcrest/StringDescription.javaTn0 >/@ށ.v08 HSf/@rV N:~і'źÒ%O+x`!)(tY. u%x&$?߄H;^V`[WxNX4@(U!iEUZ }w4@FܣwvQYuB5쪊1՜F< eƧdp%9⚊5|RsץB ̞vM'0Y`|kT:SU억cn1.E]gkV}RQ]O ]l]G!Wm?Qls4ݖ6KIw"0p똕Ng>1vGj_(/Q$6̖[- 4];'A ]y'2#^DN@mc5ʫݾkum/\@T@ʐiESr:ƀoXnGS``޳kVbWl2H֌Kq@N ˌ?:텱,Em=9;uwZ%'Dơ,h8W+XװM75|[`FدyȂa庠+ ۸k wpW"e+LDc.0f4k05`=M)'tm߹wNl6GNs77̡oգ:oeTI\'r81i8}+ FUq ~_ Yv׸K`)YyҤLP? ߑ19N &i,wS6Nu[Bwd|+'$)ߐ8Ę!?`S7.$#RcÀ=sw Hc1oR[-eC}^Ay~C\ z PS'S$~^$*o]#K?=߾}XeʹIE.QfPQJcaO<sq&y&Lbp=PKЭ,oPKpD:org/hamcrest/core/AllOf.javaSˎ0 <_ ޤiP ^LJl"^I~5` #w<Xw#BZG,S:LˊjG'bT5Ӏ/(ug^P4^iu<"|D-|EQI 95FF %' I,uɧ8&*?ې}}\BvM2aJ=ʑoaXK[ЦDʹ^eV7$H̰\7@?zow$k50?N$dJ fBםS$v;,Z;H_yoS.VP$ho|tjt'C;>I<|Jh-zFq>F_c']v`i|@]\&׸Ha!$DՍI7SBLe.@N y&]Ն_PKB5hPKpD:org/hamcrest/core/AnyOf.classV]sT=ױ-[ii>JRR6-ҦƤEvDDH2C~?W^x 3?+9UKe`r\-R [2~۾onYN/۶2EoOF8BMNKL?nssYLƉ0<?u=sՒPa4F[ËiXdž;>] & 9W.+ >Ӱ{ >p4, ބaS3i+ X$>޺Df`3y$>v3iݶ;&#\:)q&KYs\~G~JJ\w9$6<@̸!/'#5u5]I<0T+=ɬ6(35_ayV>/|J;/N94ɚο5ʢ-Ji_S\)M)=y3hV PKPKpD:org/hamcrest/core/AnyOf.javaSM0=7b)JKJm¥#UɆnTTfM'ۉ=#BZGP:zL=(ҩ+kQzΏ&`QYj9e"M˖ ;S5J Hǎ1) UckJ99_+ryS6T.GC(RvI0oj~Z=pdӃJ-j^A⾘}~^ .iƎ^<'(ŌV`0C}ld&vYlZa5ە_ofj̳8q26jVئjēyM-<6xKbS2 )ew1އioGo&k5CaK*ghO'3 o⺄! Kk4ICpc" &0)#E %XDYB]BO$0EXjؑ9v%{ǑI{IW\dICJ+xNv8 }>iA8N apy@ su7AB"Z}$?%!\n8g/py=3sqǺ^򰔓Ԑ0%$f "eLH72i&Sby1&LTnU7ws0K7<-u { Ri;FҰ[Ze|ǻ;Rd=WAJ[s6|nw0tAyܰ PK@; PKpD:"org/hamcrest/core/DescribedAs.javaTj0}_yh}($< >PVjKFoJƛe3g.9G[;f"b87"vIZN'0O'Od[t:V"K)3E΄'%i[c_TL˦J׊Q9\& .(s)c+-f I>}v\~>)?mQ q8x{2ڋa@ڔ#(؝H1G]Erc]ްuaz@skPD-a$ѕ9*zvC;ڀx@:iYҊ`"4>,(r>svU#lv)cXی{GA+p#UY@,k̻?6 H_o;OMwة!R9VlUWOl~tYxN+cbю-aޞ %PK\PKpD:org/hamcrest/core/Is.classkS@ 4P"w-EҊ-0JGg K SLRFtFG?lK%gsnw7/Р~*ƃN+7Hհ2ЅS=~3en2=axѷ m)ɡ ڶp ,0B-ϴ->q0\h̠H)&Zis)gOUc|U,*Eg9(6߄-j4'? ‹J6׫U+x@MX$ 5B!Z R{ B)gؘլRC|xa,q*RDhlV :Hx Tj$N:JN>WPx}mIqÿuFqV((}7JZR:Ç*Zh' T,2,vs%sd8aO;\!NE1W*F.='zbr jzlV/.Q!ki!λDV38V cۂ~L9;Yc0e$Y/:2 Q>hv]7x?oaX E,7 Og S/:P_PK< PKpD:"org/hamcrest/core/IsAnything.classTYo@ 9\ғHRh(\*TD@y۸UbGH (Ĭ$vڴg;v0Kj]zqEujp #jgVDtMݚe\a7<9%Puh8QGaFngG#{!֖k^6T˹u6z`Clr{Z;/h4m ]! 5% adh3Z֑.>{ ׿s[9 0,oqls=rsy6_vKϻ<-|҅5xs jJ,6:~ Ȝ1S?NFqX >$2nXwX!:0Nc䎑$S2 (:H:-nۦ;G%+z$FɎO +H%KJDx}m_FgpC\r?DPKI;PKpD:org/hamcrest/core/IsEqual.classV[oEv͒iM 8 M4)nqiHc{pw)xK@G*7z}-^ L6n8+UIC,mbi#}Denwhhn>ݔuPK:PKpD:org/hamcrest/core/IsEqual.javaUMo0 WpP8i9fku+6cQ$ORm{)crtc|bF{B`:L>G(&hltp,]ޓ֙*(Riu}Ej^ZplZw~cUz X"+Mf!!IlcbLU"#`r.Jp*\S>9;mUKSH3 :_23Hp蔚EXqIܪ"dxDN/*:)ܩ"`:guX*%Ix&n*v%Y*XyX_֝d旸Pq0K愕%u痻QA2hh5-ݛ bu9ȭH-Y0ssgj ^H"#OG]nnP><LrUwuocҕ4dF>^8??7Nn|`e,4pCxfTi=MVq i݆*;G3 U` dJLf=% z3:DOPKK3f[PKpD:$org/hamcrest/core/IsInstanceOf.class}S[OA,- `[/JŻDIH*$B6vٝO>H5g;7E,9a! nq [Pd]AUU }+kޖeF {JXT+Odvb~G ZQ;X%XwyuR-gLU$qIP]?p \G}c>bոr+':sUK^*Q NIn bgMw3\3gZK 3'lŐ9aů  yOZLpMS&ve(i/HM0kux.Ҏh!Vʽg込UjJgkqM~H "BtyG2B~!rHV& LRaMlf5'HOlzMR=3ݞٯltS|nP"e46[PXE!0`m\d|v,eʊW$5/4if Ts^v'92&1knz㆑7PKf yPKpD:#org/hamcrest/core/IsInstanceOf.javamSn0 +sviP 06$9]0GɎ Ey]lXuj<r ?B|I@<wR[zBuF[?O '2^a'zِ]N^Qb]rސsAc/dU^C*9#_OA6M??ƪ3z걅mx|~ ; U_ AO3NbbPaϫK%l [FP[^mv7A\ yܡCnc5bz\w*Z|Zz5i" o0!!rZ+Fu9%?>!U*)bYk"t1qưlIwq<<9;Y_^ɡE6Z^%_nm.tK?PK>PKpD:org/hamcrest/core/IsNot.classTkOP~ vUq7QTƦ9Ʉ-Lmel:"??h4in&}yos ` [H Bx#PsȆ0-,&Ojcn4mRł+mq0 .L|,??x %مB4Fa6Jw ܳPKCPKpD:org/hamcrest/core/IsNot.javaSn0Ӝ5쪇^FQDC ?0Ʀ@5`WA͡20{ܙdeU3"OoFXr\[%oO8t$iep,[Ds:T {i37rʖȢ&|@ƞ֝_$<-*)dr52@SC`LaŤAWA9عg&}pe𫵲)(RG-* lZ"+{9cuqDmYj0w:koT4[0q\`zJ/Zz EL1?`ܰr,O"866p:U#z}4^Fnu4XK@ :G1smDToS}iR5CzT)U6a^uzIPKo= yuPKpD:org/hamcrest/core/IsNull.classTN@= [.~)kJAHH)}8V0rvE}}R_+:8NCmig={̙ *6cK,㑌ŒWbDCi6C:+1HN`(qب Wet [dM0ȉEd>,PR?YZS70,\18jz/ %LNH2Dg-G".E"<63<%C_<gHއ6PKФPKpD:org/hamcrest/core/IsNull.javaRMO1ﯘpąx(cAx)JMQ9xt`&h 4(9o]e;cF qżTCU.,QGrʾPKgb̈́PKpD:org/hamcrest/core/IsSame.classuS]OP~VVڕ(CD2QD%*&ѻdlvFxƠ?e|O[F;~>~`thAEiyQϝiUCm +`?x˝Nu{ 5Ã'I\v0_: Xo2(6eێx5资gVWH&liN%8}ugy=A iQ:U^)+@~OqàoyvK.J)M:a|qfd2SW{pǢH_ {ݮϦbN_z3p'ož:pِ.5VzGϖN}1B7܁g][^&aC1Py)ࡁ-l3uIxWX|i#}7v:[L_.;#K±F?F?$}r$ 2B:F9HfH`dyz $AB54\XɺZT}>[f̗H[׌y wd>AU>C~r(OV<, 9 (90s2,rЎ1 $12˅I([N0EJ3jXU"_17w# GpqHu!^ŸyoP )oPK,dpPKpD:org/hamcrest/core/IsSame.java}RMo0 W9;u+b@C3vg&VkKĤ Ql@P,O{\֝>t f"pP7 ׅConBz^((kkn&BVb]!<- n_I1`4V2qk|ke2w_b2^H)x@cʥѸӡMM1Z|s^ dvI->tNirY-Wdf9ιȬVբS= zmQ">S{QVuvZE({ޚ q àHnr:y DJ,G\fDNWU:a5I8(PKCPKpD:org/hamcrest/core/package.html=A B0TAH1"O͌Q2 @g30R QNV `rpbT-eߣ~ѓ7PKs^zPKpD:)org/hamcrest/internal/ArrayIterator.class[OAӖn,V[.D"Toܴ!4i%'2ltJ/>h"H"~(mbCgv9;gs~ ` ܋ WD917хI2=Lx#ݘ40cు' ]\J!Y#r)$ՌoQnN@ڗҜ:7"(G0ϡR4)D͐g{=i礍0x`!:Gq7PK;oPKpD:(org/hamcrest/internal/ArrayIterator.javaeN0DW,=%**ġ'>`nǎNZq[8ƻfvҡĚr-l%BOlP\ePh4`4I/{)zA;$HBijxg=AB Hx {@٘= 8,$ߙcq )G*(oQ)R(72-ea{CGhM55}LzyeM06Mb/ʐ!TNLo!%xpgkнɑl=cb72ot'8gkjL-ø.V iBe$1(Om;gPK$GyPKpD:/org/hamcrest/internal/SelfDescribingValue.classRMO@}$5q@j @[ $kҏSb絳Ef9? G!f4Rq؝ݙ=#Y(}yl&LlP8P0,N9wzoTWb[rKW ddXN?0俅]BϷg\@##g>>z+z ?#1b)8m?TΔrX2]A4u=U:輭n nȰQ2 U.u'` tӮ,I6e0O }g4'6lZuڗYJE ͐|%Ja9h4;6EnmYr~ߢ6\g뉡oZnMa{*]XN-z-J ˋ$tj!Q1^SNجђJR9O ܱH:6wzαM8C<9tG^WZR3ؕtylqY\e0-2ySu )ޅ/!??9GV+q6h`$9 %zC rHGet*d Xu/J`Kd)C+K<EZMvc<ބ^֧ܴy'}eC,$>M릃L.OvJ¤!/$_M)?ϡWfЅ0EvU2i%h<-_rBnTgp.nF`oPK'M<0PKpD:6org/hamcrest/internal/SelfDescribingValueIterator.java}r0 iVMETA-INF/MANIFEST.MFPK zp6 eMETA-INF/PK yp6org/PK yp6 org/hamcrest/PK yp6org/hamcrest/core/PK yp6 org/hamcrest/internal/PKpD:s!! ALICENSE.txtPKpD:5R"org/hamcrest/BaseDescription.classPKpD:g!= org/hamcrest/BaseDescription.javaPKpD:[l5borg/hamcrest/BaseMatcher.classPKpD::(=org/hamcrest/BaseMatcher.javaPKpD:iY~org/hamcrest/CoreMatchers.classPKpD:'&jorg/hamcrest/CoreMatchers.javaPKpD:X)org/hamcrest/Description.classPKpD:S org/hamcrest/Description.javaPKpD:n(| org/hamcrest/Factory.classPKpD:ļH!org/hamcrest/Factory.javaPKpD:=[9#org/hamcrest/Matcher.classPKpD:^(d$org/hamcrest/Matcher.javaPKpD: l!'org/hamcrest/SelfDescribing.classPKpD:kY (org/hamcrest/SelfDescribing.javaPKpD:aWn$)org/hamcrest/StringDescription.classPKpD:#?-org/hamcrest/StringDescription.javaPKpD:Э,ox/org/hamcrest/core/AllOf.classPKpD:B5hy3org/hamcrest/core/AllOf.javaPKpD:5org/hamcrest/core/AnyOf.classPKpD:G8[9org/hamcrest/core/AnyOf.javaPKpD:@; #;org/hamcrest/core/DescribedAs.classPKpD:\"@org/hamcrest/core/DescribedAs.javaPKpD:.9=Corg/hamcrest/core/Is.classPKpD:< AGorg/hamcrest/core/Is.javaPKpD::"Iorg/hamcrest/core/IsAnything.classPKpD:I;!Lorg/hamcrest/core/IsAnything.javaPKpD::Norg/hamcrest/core/IsEqual.classPKpD:K3f[4Sorg/hamcrest/core/IsEqual.javaPKpD:f y$Uorg/hamcrest/core/IsInstanceOf.classPKpD:>#Xorg/hamcrest/core/IsInstanceOf.javaPKpD:CZorg/hamcrest/core/IsNot.classPKpD:o= yu^org/hamcrest/core/IsNot.javaPKpD:Ф+`org/hamcrest/core/IsNull.classPKpD:gb̈́corg/hamcrest/core/IsNull.javaPKpD:,dpdorg/hamcrest/core/IsSame.classPKpD:Cgorg/hamcrest/core/IsSame.javaPKpD:s^ziorg/hamcrest/core/package.htmlPKpD:;o)Mjorg/hamcrest/internal/ArrayIterator.classPKpD:$Gy(Ymorg/hamcrest/internal/ArrayIterator.javaPKpD:@G/norg/hamcrest/internal/SelfDescribingValue.classPKpD:/$s.qorg/hamcrest/internal/SelfDescribingValue.javaPKpD:'M<07rorg/hamcrest/internal/SelfDescribingValueIterator.classPKpD:-%6torg/hamcrest/internal/SelfDescribingValueIterator.javaPKpD:"eLuorg/hamcrest/package.htmlPK33)vxmlgraphics-commons-2.6/lib/build/mockito-core-1.8.5.LICENCE.txt0100644 0000000 0000000 00000002070 13777276623 022636 0ustar000000000 0000000 The MIT License Copyright (c) 2007 Mockito contributors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.xmlgraphics-commons-2.6/lib/build/mockito-core-1.8.5.NOTICE.txt0100644 0000000 0000000 00000000240 13777276623 022552 0ustar000000000 0000000 Mockito license - MIT. Libraries used: Cglib - Apache License 2.0 ASM - BSD license Mockito all distribution: Objenesis - MIT license Hamcrest - BSD licensexmlgraphics-commons-2.6/lib/build/mockito-core-1.8.5.jar0100644 0000000 0000000 00005066675 13777276623 021564 0ustar000000000 0000000 PK p< META-INF/PK n< <n META-INF/MANIFEST.MFVˎ0G?X:XPD bèRJSuE$v{y:"s}v=UzJ_{6QLgIBWh'#"{'H"/h/$F!) $鿔IWu ^))\ARi4^L>rc4Mz!s$$ה3 |򸆜"N`#NI⩐LN$|X + oˉ.xʐ(t>L>& t %̸br\Ug Ss> <(.4۳ 1-Hô kL/f8|b O NCQ#W k9 a*URSOO`!9{8gQ1XN'zn"3z#f s΁ZvUWGϗ$1 s߫P<3/s_`+ρ~<w"Ji/?. X,]{l::> j~TQLub1 ]!em 5;ix*AeӨݵ^s'}u3<姦w4'<͑\̰VM6v|6[!`Vr utޯjsaygrux>6ٳfGvr_Jx:PK K<org/PK L< org/mockito/PK )w:org/mockito/asm/PK )w:org/mockito/asm/signature/PK )w:org/mockito/asm/tree/PK )w:org/mockito/asm/tree/analysis/PK )w:org/mockito/asm/util/PK -<org/mockito/cglib/PK )w:org/mockito/cglib/beans/PK )w:org/mockito/cglib/core/PK -<org/mockito/cglib/proxy/PK )w:org/mockito/cglib/reflect/PK )w:org/mockito/cglib/transform/PK )w:!org/mockito/cglib/transform/impl/PK )w:org/mockito/cglib/util/PK L<org/mockito/configuration/PK L<org/mockito/exceptions/PK L<org/mockito/exceptions/base/PK L< org/mockito/exceptions/misusing/PK L<$org/mockito/exceptions/verification/PK L<*org/mockito/exceptions/verification/junit/PK L<org/mockito/internal/PK L<#org/mockito/internal/configuration/PK L<org/mockito/internal/creation/PK L<$org/mockito/internal/creation/cglib/PK L<$org/mockito/internal/creation/jmock/PK L<org/mockito/internal/debugging/PK L< org/mockito/internal/exceptions/PK L<%org/mockito/internal/exceptions/base/PK L<%org/mockito/internal/exceptions/util/PK L< org/mockito/internal/invocation/PK L<+org/mockito/internal/invocation/realmethod/PK L<org/mockito/internal/listeners/PK L<org/mockito/internal/matchers/PK L<,org/mockito/internal/matchers/apachecommons/PK L<org/mockito/internal/progress/PK L<org/mockito/internal/reporting/PK L<org/mockito/internal/runners/PK L<"org/mockito/internal/runners/util/PK L<org/mockito/internal/stubbing/PK L<&org/mockito/internal/stubbing/answers/PK L<-org/mockito/internal/stubbing/defaultanswers/PK L<org/mockito/internal/util/PK L< org/mockito/internal/util/junit/PK L<%org/mockito/internal/util/reflection/PK L<"org/mockito/internal/verification/PK L<&org/mockito/internal/verification/api/PK L<3org/mockito/internal/verification/argumentmatching/PK L<+org/mockito/internal/verification/checkers/PK K<org/mockito/invocation/PK L<org/mockito/runners/PK L<org/mockito/stubbing/PK L<org/mockito/stubbing/answers/PK L<org/mockito/verification/PK J<*/|8LICENSE]R_o08IQWekI9ǐ-(6C|ڪ.PHk,c?]'w#<_w(|EvXe \NvwԌv 'k`@x3^dxYOWGL;hBk:ߞvM$l2tzo-s GnlsGڃ;- gG߹=9\\:O00dp{n!'Zh(P$.yQΘf߶ThxQ1f9ȣhfpf`g C]72*řH>D̥&l)MIKCŵ:T-P>CRK*yDUx+$kZ T ,> tƟsqPie@ "fBh6+A%KT%HUi4>L;t#kײ,*FDIW >]G轮;!dȅ)?PK J<JvNOTICEU10^q ()@E>`;`ls%Rݝ5?Qx*cs5D\Ljܽ kߴԍDZ)Dfem*ɲJ |H|4v~fXuV\k ľ.!b\g˦6DJ(^,32is wE)1RSѰ NcP3eDޔLAݨZj"eyĞ+3ʀޱA!?Iyr">G(QO@!9(ЩG- ؛5,Vo둋ճLf9*+"3@/r׫,Fgy'Ə/-6N >i vD ? C+ zKpޏX V@ :oi~b"';)-젯3J\2`r "KY3]a;6u<j~Q1 ʾo48U+lv8" ɭquNZMY[@(j_`)_DVOˎq-$obn.5?B c::e[VAn%L T"ƹd0)Y"(Ifb<2A5sgJ2%S/I 6}ԔAddITgu>Iy=@ ]'MTũezٔgTe Y V/s0#Pwa_fM[8"5P":LflȪ[w̤ս>' Gg~ UjlmDL;1 `D*虘80O[5Q*Ұ +s UƑF:ag|흹2b1]hSY<<ъӹJ$ΦyI۪IgD1&cةu|K͎ ^5@7;aRcK 88l]%;rmӚyEjf"Vׯ̀ ՗ vKR͍P_ad.1)X1D[(>C#S 7Ī|t{?3]B΁)wv#jL_5lqn N}:CC6ժGo; tr)~4jVQ+bӁړlȦ7_ Δ_J;jҶ]1 7yc`HKa>]Rušq?ˉs/q?[r=?,u0O7Ňbu^ZX~_h~K'ф+U6&MDsRpM."{ `z\[~zu_Z.~X[B!vy^ /vq{nq'nެma7 ju 9G(fR6:Z;BvgJduJ>wZntCKO7,jh :BZMА :m4R]񶻘r~Dg#8a@pt;~>?='2eD\+[qux% zw3$[J@3]BB q;sVqK#ƌ33\'މ؍Su?BQ6}/qJ`Dkr5M=vP<&`8D~<20]V.Ikd7Bx n.%B@^y uvHݧz|Yu[`ҤsrN3Wm"<# eW*>DcP~;vjIY0ODAW-p_造V2 N7Z& _@`%nQIQ~&=196uMjhWx0\ږ(hŔΣO+fxsd#H6d~EcF.׫+^х4-D=W7Re354!jYc TH|US9A "so|4Pw}Y'=WS|_ ujS Qde;\qxJM=+8 Tg9n ʐrE48\nTzenH&@9\#ϰVLo>/&r5gҐCr7 2&~%Aϣ[q$U3Mç_@|{._~|h|J#*R~iB !^9}}~*ӒaOqFjo8AS ߁xJMTANbmG8P7$uwzPK K<*k "$org/mockito/AdditionalMatchers.classtWf30_/mY*ZBB?6 fDdYE[V_m*d"ZŶjVT=?=z}w}݀;{{ٓyavR{@:g7si;kfvaӀ1ny gl*s~k A٫DMrc1wn,GńyA3t6 2zaԡt4w;@:`U~5s_j6f*]V2ѶrphpڂoaepcNN8`WHIX8矲mfvpbw=ffkn@:X b g;dd fȽōnnp*f x3ܨLKKWW&n@}hepmqu"2Јs\!@n+bIXMjm[Vm X+%jD%mGqvq|ktx܁(GČʽ81M<}R `8hc08 oUr4C٬]A6i7ڥtuٔ1Rm:l\L5ԡv!W2 @y%ӥC7TBQn]fVK 3pEUҡ nAWW/th _?iis6-ĐŕRH0ÒBq c00&AәB6alen䶣A=W$6ldH~q &n$۹]#dh3mЦ=d74 Q#冨G1nh Zd+7jF2 EChfb=i=4">RVsc>UkXng+ _e0}l汮u,|,P V۷ۼ~39vư<aRO"#uȰ!߇pqeOR{bc6jP;u`(NmkB e 6ltkN#ucEY;Wis#cr) !nۧZm^7Z\D>|6TZܢ/0m|961l υ*5|:66-+&e #g`*:Iƈ=hmIF'_G:kԙt*kbx}WK׆ >MC;h#R5BAn\2h΢'M~;߱3` `ϬW W[{_~WYE?ZNEIxXtFkԄ,Ke^D{,q$x۬:Y-'%bHi#&rҊIxGz2\DP CNj$xQ6J~Bm"o|QtH[T-vt©0:TS=r8j:J#\#=Wc%4-4SFNIn5rP t Ԭ<OE")4-4SF"B#B#=5koګH/H4UiWh$QFC$FzFjiRhWh$QF5ºHHG(FFkֈM(FF|5rH ׬HHy QViwUyD#0X!Gǁ9D<,ؕ\tHx=Wz+JoD|HwW#}\E:"&'UH '>"'MOW#ݯ"-%5jT%<"=\HFDZ?9<-#?XNLΖng !O:S@+"_sB;QyL㦠K-ڢpjl[4mQyh,hH'RP<gₚTWR/$Zp'DZ]ͧאcDI4T:A U@O@OIZ~%7NzY W~vR.<Z^.VuP_Uk~oInb[˭2D#]}e^ H-R( xYx90{~?x۴4?PK 0_0:fʟ]~*])"UӮ _п](yrYl03O"].R % #mM!?&4 B0̫Hj]$Έm+fa6؀ (|dAOY; P5I@~Lܼ1p>7 qŬ\3s0p9 e`N~uOm,[WY5ϔU CvW6^qt{0l#Ow a[UWN[=e{liWWh!vޢdE$5%xGl6?A%L͸2At >Y|5B-twG]6x5;a;F x.$o' >"o #\Ȝ.KՆW>%׭' \胠T" ;E︰}՝<{ィvqo<-]E 3iacx5W3w~iAn.;yw0rroދeUDD fHE87>nQfƠK7H74>M0i̸Ls,ό,>A.}76#3s7:8=p(`4ht.$3OcI~~\iSLЀER?@HvfÒ&[l<YyOӴmy_&<xs^eu7I`N Z(lETn;"αn`&<6/v- ׀vA"x?.%2-ons{a~IG};ve=Ky̽( ;h@%P\y0TV0ٰy=95DEJc7۴vjQli`M>;L>vS64P䦛ڋN.u@mtJ+`s@a࿽(Gi8; sڍrV͎N-oy(-ZS-:z-|(=F B ,lgh4m >NЈ~gxhhkxd'ozlidk=SPYF=ec-v;rr+Rd'$3=ЎR ʯPgCvkƹcV|TEV6|' N`O~ "|Wjkcɭ$Yb>%k ET.ڮ.gK X=2tBUrb/gľt GN'5T`&MZQNgk9_%pRoZ[3m-aLݫu>t@V/ZOtP5lJ:[)]s AdظXD-C5iSIj 8jP-VRVդ0M-k׵NIݴQQ;:`,da=>k_s~b: mO7U*O+Ű7NQtPpSAc?ZyB#1o}I3px\sQ!t+QUNoqvεc܊+{(G /w"`ܤo7_f|?+b5w\2_`- <]믱`_$K9 v s}{CcCH)U;J5ǾR W^cջcw-`)Ep org/mockito/ArgumentCaptor.classTRA=-B@@Q @C*X<˘,nvD |J*?힞g{bqz1ޙ|(lq#` uy}ukGrzQktB91t&dٵ7U%0ӖµN\rZvM;¥Q.dc^352uΐ\nzZ mBX*Am3mYF߂u؞Z`Y#h M0qFЧ_AĠ)8⸨ -`RÆOgq2UW:UVFZWuŗܢHs.)/u *+nG n#sJ.94J# 5qU h^H qRoFTEUDeiZz,)R zi9jnhԲtu3os-gD"h&߲DN}8Vv+Y-d\ʶ4b,t:oێtlW۟( P@aLjN5Ēi SyZϰ&ȃa&\= HIbd$Е#~R`001K߸O$,$8@ )N0xvx,:x).(C_Uq.J:Wu6||vN-$~A2u#Iud+a ^ZC?T%YWd*5ui#ȴ@>ǙNDUCܯE֡GCm!#l?ȋ4_$@^ 'MԷZג0tkDcDך!JPK 0<$org/mockito/ArgumentCaptor.javaWmo6 rW FC;EgJm6SIzv6#Hl{2?=>SxƈAÇ?k!N^oa%ےؖ 2ɡV767^W"̏*߰5mi]{NMB*QL%s>cPŗL 7wLzӀ;A8 @}L٬+[V6f-7Nhe}o xilD(P 3!k0CͤMfPrE+ 7mxK\nYCey#ѩ;nq.9::P/x3W3zsFjUK(ZA&sV.hIF,ro3>x-Q9 ]|2:buI+ Ӝ>.QC9fijJZiz2$jUoԽ.t͝gQ2oX Ȗ0b-#:"Tafp+f"Y~7XWgN#  <7YieB tU N: R T$\AnXD[`Ճd<%z6襨sW6M[~o9}6ΆpE 9qk{KR,JRpِߌ4b^Zw5G8s'c{6_Q آG@ВCK*{)8m6WA1"MH2کuåmP3)|T>p_ɓ'Xd'!YbSPIKNѳhtQovQ[ӧs:˂ԝݳ Jz"XѦiubDn6߳;OK/gQ,`ڽo,LHբ7X+׌s^yKpz2/[$HSq/amt~K/ߜ1y?yxs ))^M=X%򐒇MwD=?)Ry\Av2['˸G5|4&n_z"< A"mH7 f5f^\rI^cVX:+(n}7 yŀlDdX"mLq[*kB NrbzF֍WtZ;+ :*+fk_SDn5m^Ym _qd,< [!r`+Tҙ;Jvp0`7L#%?Ksjڷ KC"r3]9 .nPK KW-T26o/׆>WGv۞ }f'|&N(ۇ 0R%1ф*691W7܉eVa2BH sy(+r!3GpQ<m?PK 0<]5lo_ org/mockito/ArgumentMatcher.javaWmo6_qFRKe/ـ }Ć"Uﻣ(YN ۇB>{x4+COٳsxg; F{+x颒kJ+jZb%Bhu|2;WfcCg- N $|N!P7eG@a"(Σ5~$3ҔY)C(Ah%Z~ZYt9giC)27OjDQOgWQ)+Ljc!;cDlTȅ>ʢ!kfv8^\E;`CNI#xatKr\G:2`N@z.}uGR2 (&C꿫ɜ\j窡,'QwHbJ9U;$0Ma647/IT>,5 JJ|$5#6uv5Z`鴧iP5&Ѹ|9L_YM/hBy+'hsjwke_d[1։ mN㑫jۛ 3̳ kMi\HR(1@h+~?F}8C颥:GO8 /ԂXpcw@JYlUlx x 7 gdU^ǫW">?~M mC+d B xGNŭcyG7O;&xw*UX+.UnAww1AP)Wo+ZG^E2 }<ɼS'!G^,!HO1%2ȭ]&f%R+GA"+03X2A;MVoPK LJULLg/SF-I_|F f 0ܘ=ko+o&ӒaR5(^prMv(?g8ƛ;!m릅 c,}J.exУB%.\wdqݶqECCyq:Ad:UԃF&b抲W@iĎU-BU˜ȸx}qi|![/weX4r5JʪԌ*i04/dyuϴ!M!u})hN@[z1/ gvLKdzSkSGR"&5ڕo_]/ZfG2a[}HmڻrmM?_ B6oR4M=r9=QCxK>h.}cS_#VhK3ۓ~z;}O( 0_2_9L zN03P0FXF_,nG>cQܬHج78KMpѹ-*B}J;3J2SfநED8* f{Tܼ݊*'CaHGô3f>r:- /CO| ZagG銖3M⊤ya֝_?n:;&$\KvG9\;<\s4͚IQکBQ(X(M̌Di"fERȉԖ(SpI8{tS1#/Zyb_&c13<'CJ2kRI_9㋣(<[ӄ**TrW\6100l)R:8O̘BL,FnpBJ?̄LtCD Y V`Dc2BSDQT>1 mv `~^eq)Qʘ&ERa)3QaPCT9W[g‹x 1IQ"իFؠsye{i  T[H- Wh7riZxrf|iK{ZFnT̯ tfׁ(ŃK"MB15X2N{H/BzL4Hu!y`pϼh_*F Պ^ T!N`Omg 7O]*?ZQEr`zr]E_Cfc5h]p4p\ ±՘HUb40khR,r,dև$U{`!kL2B´\/:j (6q']m,#j^7$ښsfwrي]M# te_G4ZWAj车=WM:R 'o"لq:?>SMc?oɞ/˳71ql|1qc`PK 0<org/mockito/Captor.javaeSmk08:vJcdI |v:Oӆ҄ ےN{ q~#& org/mockito/InOrder.javaVk0~_ql/vlYhPhVe%#)I}'v_])c,`,GߝNR|҃"ә #eT x27Ri ̸Jɩb%аd[0^@ AUjL(4F%U,}`SQ闺xYIeF T<)3\gc,3$epUr.u4X}‘܈;;K0܌+mlNA# P|h :XoLCʊ3pSoU񞙟qӕ!}>JRWX* ˠ;M pK; J)m_%Kkgk_6 v{C&Sȥj!-֞yR:g)l<~U;Ϲ݆d4cU%E8mnL]~xUp/lnF;dkKA? psl Ay}\XZ8F3uAWcG3UBSKk7kw!k>%®t%YFqu֜~^GIFw%/2[Gf)tA!!nIOGȳ)Z e%eGk Bs\wWpTAޓwMƒGQWԚ @m!zCbPj2Yޱ B&~"r/7)%B q*kEk{h~f#C7Ï?HsD;%ًcSK t|-ؘ>#S*ͽ8 tï7#@pVdI*V:gIKc'#<ēW= `m (O(đm714v>%c%Yԏ<.E|UdL]z&Vy rSn:GϦQ4P()мqw}3u L@!&NvՇ(X,ngZ5 =Kд6!N++`u?< 1z6T 5R7;zPR?vڿ}"]{au[ =Q\<~'_l|q@v%r!ў`?PK LГI5RzbcҠ~ݡavcԈ kj{(F@ETH!$QՌxKpf SѫzTb,Ky'_+BN ȻU !HtrE,(Z i%q~DAra."*(/"l>!W1|mnGyIǂTMg%mɛ]J-8}kc=D⣣q#YS5s,NЉ3O8{IUXzPoA:.ImB9HY̎&ōGA H|Z=mpii $]=̀kn!|)/$gT9ăUFFJIG{viWOU|!ZsL$ZN1I2(T<~*R7FS#o ~qΘL E HIUΚ*h)3_rjt^cHrA"M!L؇ؑOET{ڙOٞO=ʙ꠸}tKBD4JMVDY pzT72_~T< _^dRfbM3!(L-a%sqJԉMoeGI`Xs֠Teek5>sՌG}NE5S+ E +=:'H 64z%=[rEV1Tځc7)z~>o̘B_/Hnj!S_2Mu{MK|9!Ys:#\fJ;歋\D&#y\ gŌk_þiDzXAiEh&=mbX9_Uw%顀UAs|l1T:W1@=Xt ,Q˽쫝)_U^5Nɾuyo!XW?%Y::0áGȡxFnQr؀yF89l&)ך/a/.wkr{l~[eM{ZF6[=- 5RMjYKם?Uyw;jPf.[UsUղ2EމW.\֒xW.3ee1.g.md{K澄^ PؗMblԝge9b1YmP> oRqÔY1n# ҍRU6!AzPTFF:,H+|r}xS6'RVTlCdQfRU5gQB!lc;JF:+Hշlʒ; @}ĭ>J,3+ @Zw fѵqڥฌ+'֞Ʃ)7#TftTt.jθU3ɫ̫)(VgnQ\o awdyi,KͲI>:uXwlm!w0q0?p`n9 /̏`ء/L-{?{HXr娰J*{<͵h>cp;`ˌ2<٩`VajLw21}`Γ>LIK0d*^g-9,R&~nANEf3{q^Z\B<]|<+I{n<=cLGtL1\Ocp3cHdF߿d~Tb)yY۟/ s+԰P-0Љ' O a@nP6?RCVY\5nkFjc3EЮ փd2%+|SV@K DZ;^3jo F3jʎŸOSbɄʀ)>~A8: E]؀Ѐċ^U^4}+2t.D)&JyBwy߈rq%?vk~Bh0 "Rюΐ33hWkYHU!LZ#EiKA 2L@o:{㹔VPTe:52]'" %_t]'4 WBՌ6sH)kA(`f1  ,T@ӂz|4Yu@[1P!2nq9#)4t+x(wY ADŽ5t Rxb%m(ek pC&}c! qJd 4ss`I2jJ[HøI*oLS7tgk.NrdΟ1iy &۬G^/Ro (@.p됽QaV="}Pvl5PpU˛o|OT*^]c hЯf- _;7{P8'!! p . r^/y;6@&[dss \ˀq`/&ۊpXڷb ®n'2Lq7xNCx-RBtۉu\f h f'pJ8"99?id0Dׂt%;FԝFǃո~1vO37RdTp"xՄղjMjCZOʋHhBݏna[ꫥKr_?}vTtȞ ߇{\-2J(gIcMGϳVu̽M?}򤇦m=͕ wwiJMt2r:/5 Du=F`-7Qhox0&c^W`J=Cً 8۷fzxπvRa2Դ`πo-̓ p&b>~eܝq0aa^^I쀺WA\ bNƴU5ɊToRnLlqj{M<{ n0;^ˤ.izkEkMx.`4a+(Bbۿ;08ݬaFdƵ[FuyU,:֭#}aLY:!γ"I0 Jh gY&GE7fo]  3S*:[htZTvH[Q gL$ l\t֡_zѲ}3Dj.>߮N;+fp'} NsaTb2uw)̒qF,7GXQV^jڨxƙ.?{׷ r9sJ> F<Yu%-hDR\jqmѲ0Jޔ0A? U+kj)@I9-mWnKФ8*~p>?i⽯\[ tƕR&  ҵ1Kꮙ>L\u'hwG=܏ھ&ӟ,1,т&վW|jCRD@bL %诶ҟZK؇&,&~M7X\Ÿ!īݽ{3ڀ:Kn7XƟ&@tpv@MBkz?0}s@wiU0翌&qv跁4 ꛄomqMTY-WK,ZȊUO` w\yPK Le[n>wVl@Q.}sJ;:LғeǷң$g[?P&YTVgp_IƔv'JcjAزt*HvHIY`EniM4G3ei_R! Xb XhZ>Xy oA(Ʋ0 LPK 0<#iorg/mockito/Mock.javaUmo"7)aJ-DV* GD'^TUUUkl/9;pIem3;gp C]nX6|w}#Lt L+gDZ9mlBi`-0' $TNܚ),e8Ls)KW9?+1{6ֺgg(q`:?:V *VHRAͷ%%Mѷ:<ƻ/}RdϠhV^6"NLe ѹU7RRG v֨r 3 :9'BBK z.5T X":$Z.6Z0~U`CF,EU1+t2,t//}S3hrt4_L6uvTd>U= ~rh_'wE\U1kp\vT㉑VӯCW,Գq_|f AԄl#|M};cy? @ZF5+XDdNC=f(\L+T3cD/Q<[F,1`w5yaJd`q?u3~*І0/? .ix?PK L<:7org/mockito/MockSettings.classN0KPhiˏZQBBTĐIo#Abx(a:9}x}0an2;r~5&l_I yLF %E(DaPM0=9#&ڑ,0~_*axC KZ*߭uD['t3`f4r>a8IQguleZ GQ-ݎe+GGuvr^V&+@_z3x&ھU{g x[z1wIPK 0~$S[6N7A&lz5er(];Y<2SB^KeDe2D(++~9_w:Uƫ?*ez%JXNxڋǏ?Ei] 36Y(eoH`[C\jNeѶ<5R:%F:l2Mo2_ B|"xayĿX$+¤Li,u Z9 18 [gVl"]Hz:٠H/J2٬JU&VH ȉ6jCS zG+s)(3U-P࣬/1صbq[o•AUM7:AZ܂в ;2sVuu2CakBIRz-l|-`O"ΘheU{2mb/8$R#v̷ﮝEO \}ߋC)6 {ʃٌyem:W @og2_xu8G=gEa+XTgb(@#l &oAa@U+ck J9JuJ&bI27,)lGLDF{דʴA7b R1lc#; 1@׃- ?_{*NMу NGEFTZnx3:뽆Q>)4!S^>M|ssEx]Jn@I3$VS?%m|9 ӸpT ;hd6vg6#qJ8|u$@ 7,{= `7djY״ nܢ ) 7rUS3fx2$RˡAc$z i7f^9ˣ>!QOom T-Q3=^~hR>D _,ÊVX -S@"8c0rQTJ>+Glt3$q"rn9ӰAM6>1DME.gBHDgyzRJ1U_4 g(2'bN;T%K2WQ5]"DbSCI~4p;F*տ]9>TΌ?n8&P J% Aww3>B'G't*?7eEHQP92.^*ϧ|s>LD㽼b(@#΁]g o.¹u5s ]śF}[^=4䑣jihl9E@ٲF]tC bCY1F=:L2YsE$CDrCOtb5pNvlF]?'}*6*sQSFTFQ ,sݨ]g'ٶklt*JZSTdgAQg61\]. šk6(i$nڷ1:-#xOK B ?j5]KvM~54NȦoog2#t܎bZyԣOUqO3 quQc08mk rX@Ⱥφ.=p1 Nef,/&6_&_'ugבN<;oٴuG,7*'EU߷Wt+Mv$cL=fȱ-In]rkbaTn/E˜.rvώY`{WK,{|q>?AkP]Z.*Q؇ HS(m]{&͡LuQ7oSg# 'BtEƻI+ܟ0Z e_Xg i]NlPS${ON-gPpgRPK L<@| "org/mockito/Mockito.classXy|\UdIi4)-IBmKPLءLI&6hxy2y/μIZPQ7** Kw\}_{ߝ-fywswI/ F:1moLcz IXk)5 B,ڏ* {Ǣ~ F5TӺAiKBpltxhdg413sjT/;lH)4<ͮSM F"Ĵ27 5cNFL Gh[5sP˘U 攖&gSM)LWpfNIjsŅ%" ‡&ը+$+% @B=dS; CK~Iش W+᷌lf\&aEnjAF'pw,(a3Maʴ*=%DZBp9-2ٴ>jP:V㊩&geDyz I /9|*Ne蛄$컀E ` zMj*t֎<]QgfKr{&9> IR ܖч z1@DXϘw<km?l]#*u%+7TEXX,.ȗKaEA3# Yq-Y#UsH*M='qC:}=5#JSf=pl ceH5X?yk=L*sqF̶2ɫQ)iqpQ%2#$0)qzjVg0%22n(Ca5mf)3OS gPLatoH1'aG1(%p9w,qL: K)A[\8F~'.xU9Toěo0}*gٙ % UͰR ]0;)@Ӷ ne'*E[0 :I:[-P3B'ۂR/s+Ѷq[{)^<< NE{ˀR`M'׭f1lRFߏ~NHF.YT[FxpsyCX}#A܋$4)$NSGaRJa :*3J1#1 x0(Pb^ ;'gLkU9h0ه-0Y嘧Se+9;_RђBeMۭk"RcJZc5~$hj-D1h;>q{t_;G ߁{Np`%@yOi82y٣놙+š90~'h@%<eC * q?7b1 הmq-gxpȦꀖRq U:vQkAz_x+ﵶM4^:}f:)ѳ ֜"/ЯlMkkn"4Sյy4å>Ŗ4WQS7W#W\! |3GFv|ip .^[Aag5j`k-tXyeQN""8ϋ,ޏռ "Ikg^N=><~?dz|y ^'|N {g{[**^$ɃWPK 0<5kzB!org/mockito/Mockito.java}s֙Ϸ3e&&$h9I*RU׶N$) d^Hz=m$y~ݍM-.h0F&z^^gMʢ)hU*YF2IU\%YLsTUQsFU:*ӋY6SEbf߭dZK˖j܏㬀$eUJ}Y&+ z\5MV,*^s=TǻuNդUU'jUSU}&+x=J~j.˴KU(K즯oHJͿ?ld7 ?8~`GjMx̵^D85`fz!u4Z*ʚhN{Y KmZ"L;^ NO3.L)S|XD]pe]u6\LukuS%ēU!O?̟ͣM50yӈ'}yx~0? 3a=S la`ϗU,£}0&ߏ?Q25`_qtR-hpB:8*70EInV\ u4&URp-vlHӋ p=Z2maJppYJwᛃoyWP+OϰUdPe#j "P"6ۃoiV8lR[B̶ǃ?\ D蟗UD|@$s1PMv脂@4f[(.ǜ&v~̮W/w涃a4OYA``,>Ӫ]59`!@9Ԭ. !`#'" `\ftE.r]К\8g27<o]L`tMVVVUko{F:$B1; ?n2 78JB-9침5˲҄z@ko2>!I%*\Ei!HrECܺⳝ85 }@AHF@@h}ޞ]!gܽ 3޽;(pb;aL.aiqDfdP{5y i<{ ah1d Zxqŋ+ps)Q|[_iqu*}Nh'v9Q~}J &jV8@QA& =JU4/yBNm?V)=1c׵]!}= 8:ܯ6\ɕ>3ط## !oRKE k 5( U2ouI*hA=>ۅ-WY'VTëG`VBWjBs {U5Uџp0 Ĉo .|0ϪїzP^`^U])QC sC4V$y1mZap \gC?@J2$B^\ZiuP5PO2$F[׍K LNIkUdIUAPLRYrpYO9bJPyp(n"͙FsO 9TMׄQQ?+AW{N}5IR"0/ƍAC%PY]Gx=Ti {̳FK#;iѕX+3 F@@)2>sU%:(U t q!ߢ *^EF4< EqӲ'@Q iY-&'=ur۳:EpXU8qEu/;/ MHU4]7bEb&g/hPP0x;JsYH٥y7e6|#Z(yN_'ZߪFLJ-*I6I!qG:43Tݝ-XV@usLl' ;e64*v-'=>chh18-T;Sj] "#AQDjQ4D,A>Α zGqh743 /Y v^gq9u^t8C0=7Zl| ̝ed9C#$c n'ԓbq- ix\  @rEv٢~O32c 3>mzȵ9ddy&Y  X~QEGV-36S.]@&ۭ|S"@bb8L.dQ[1>߲O)^Rdfo*КXA>7ADA0Ԁ-gp>% )]Ϣ/:#nJKS4{,asX ,e"#2A{k.|R+:\ֶa!>۷ӖI k|[nnidFN'6VDINyjQ(6&}ZtxH,JEkBjG }叜%;N0chn{ΖiGdXhysZ9qm GFpEvh}±6*,ȺMO7ctܡKZ(as8f1!eGka9*+eǼg/m K&b yt=䛎/LƂ-dFm_3>'mDmJ .ZH`ඨbJxh@[}kx!䏽kWC vVxV#S/}6 a]?VMY2:_CNmȎD$N2R!S%AFTV2aP3 J8 _^No&')gcj3&n #_J'm7&ZD? ZЃ@_ARQ8Yjs*}!xgEVa1qAoQ\qEq향UUM03mMLRڡQ:е wiRt^Yu3zZORd' ?Od ?mP%rOwUeWȈGI>['C~nW'M2Eg]*x Эt+w%&=; Xǧo(Ho@ED5%vljW >4rxEjb\2Y 1>Y]~Y.>bhtJZ2r<>T :'>¹L\E]lV]EG5{h2K/Sk]gUg$ZS|Ysp>gq#2S܀76-õm@RޒS  [*I/s27FQF?, nk3A*2+k3߹^s:J9 rxڒ(*á P!ATѧHњz~0׳(osRdH38}F>)6xe4=?Hx_AG^); 1BGհҤ1]^E5| ^@OsK;5c1Zcu6-\%i m{ o}- >xNpMCRqDKja_}si8j}8 Sjáp{4Bh(j.dC -vԌ\`ijc3x|3`QF3L0Wd2%'KBRA*g9h7 })16zC6[^栍#gIrЁkDtn2eCSu$P*;/p|p޹vXY\4*ݔ-Md=hm;VqEcoDqrpr^OI_k;DzԱ~䬅١P +j4˦;XĞ/O *$Ҥ 5X:Y޽qd*}<۶ ;82 #H1)J^ 8A7GMLDaqlȕGGlZ:hQ6Gdĥ!**~ ^ی G6@$$0 {7vYQn22ׯYi7gli he0T$JQ#AdwgδrMMs3R7Z'ܞ23FHMd$)D9dβZ,pD߯6oMN #5Lgt_:Ž=C'WxWܓw9{KhJݥ?pBZbQM1s`/'XРvf2O:č:Fjof6Y)y  hԂ1#՛|h ^.Sc@٦NOΌD L +TB$K`;#F] }6'Qp˛[,xAB0z3NP 1%Ff_>x/O^^ճg /HkmY=+W%9 ;L㶝CD>>z!@Ǵ=8E] p|$RHk֬AYP8q OTɼ` ^ p]}t"oQU h}n\3~ jKΌc7N$|·q8 ۢ*R`/V11/p[b&a$(h ^WE (ZEJ]3:Wy0YnP.$A0hc(g sbnj(Z*ౣlnT7l4$E(xs\ut9m jOaI!";"pt►þK]n\Qk/s :?y֗>6PoĕZ)\.GVCj=Z:ЦsT;!OKʒsΚ֛w~ *4]i]2qS"J&)r2.SgC+J߹<5r{Tajz24:bLIAmc:WciYvDaU@[>:1b|`Wy1ZZ#J  cEЂZU+҃V'>V?Ӥ;Wg:Tw?Gсx W=Rk>7DQQ.feʎծ8 XuH[aU>($k==)Kp3sCUunzmɉ0iQd+Nz*;Zǧ'yAqFX%]9ľEOm=vsW$9y91-u*ah{Z<"J{c{t.l"#KX:M\v>$z%xԾ,SF1HU$Ȁ-Ral8 GL>jzG'kFT[ɲB-o{jw%^Y:}4@?N cDEQ@I& ߢ"(/qhQάe [)d(h$,mx  F2 ,'H"V;ί}\/E;}NQ_؊,9ƑCB@xUϔP[LUT)LdݘW;i iJ|r$݅ݘ>\o"wuXR tqR~ZV20FyǓ${b=m"Uu^ll j\H o Ŷ;(cy,3BhY'k%a,‡A졎%+ `Ι瓗/N_he3{s.T:T͔% 1I=c״_. 9MJif\j *ʂ999lHcb-BlIs1[/M`ځ+ t}kRQ><(r(arK X: 4^iy %0; QԉuAjrߛ` 00z`1f5ȕR1i@FFFn%4.Op.Ԟ)(r>Gb&8pjax)EVHm̼LP չ u0VZbTdU _q YN(?Ϡc7<餪&r D0b^zbJO%ȄJ <:yONş:} +-}u5)a mMfW;J?{C$ 5sdy5BtY824qINEh^<2 !&($=5!n2IJ] NJ. "2ֶS4l\<Lqݚ\^'\J09eS"\ґhXr76asVo6ԋ(7 ?I2ױƦ rƦ֢A`b]YB߀(Z<[TNl%tEOvY٘}őr]q3b$S.P w.L/}alpX,RbJ -#:q'#}m s,Bd;wEݗ2 %h=Tny=ndB\3;S/RgY )ŝRD)+c 70֮,S'ݟ+%> *%~;$zVS5u3>Ayg}#el=?{g<:{Dk^?*uX3DHĢsΘgLU2)yJBuc|ț8br3 ۴|74U&o 4w:o%9?Obdu.ľv}{ \9~#.HZÄ0@CB75?yz9捭(b\$7A kt?F $>baI⋉Zzƭ|+UG\Go+N?AIw"0D.2j1cep:\dz!խɠV9ejE+ D/~|(Pu.q_uیʃl] >*L0p(GVҷ 6BfE^_Xo߽usȶ3oDN!}5/dw=os QFĈ>BB|r')@OHd/*ML !eϼ%ad&ysOm؂XJh ;n>]L_qZbH|t'A&URQҎy! }<8b'..s}mX!ɏ_z[d8ƉX$e[҂pPʀMpFQ!4FPL۱?aE}K9X|,ǞSkN!wjT3F_#НRMJciqkӗhxHcn9O Umnf&!Ћw';vmU `xk=󲛒M ExC>,ϣ%zipOF6PFLg&2, rٜW"643 *Gw4#*37p \FZi#+FנH?#;)u4R5J/ښ}-ivMiw4DdN{2ƯPT} %W;%Y(5Ѣl=-8HrV2E2St,f Hza$IsΓ׊t1"<*p7Zҭ ݃uW-ڣpX2%݂ӎpkf@vu?!Y%Eug-GqtY;SG 9Cg:!J~Hg`}sɳ;qk Ht'\ 21|,|>uB`14<_B֙ q>,d'),OOwdEtz)rRQ% SN4+F A[UӬgn߼BQuPTR+;ت\68lhL{P Uo/ơ4^wE?R.hI*.{rHowR?LaoC|vy?')SKT8%'j q~S.9W09FzdaȅKkJ_GJ+\Z{qNp)Jɱ>K; r.-`4T&;>"v0(S yXۻ2 ,> :1х#\ {8q9s( G]u wg9Il7ɾ!Vsu4ə5%p/!2YooLJ2(1I%mҩƿ~DAS,(̼ X$ Zf#5Ӕ!􋓏nr q/=#1M6ao*~[^s:MtBXc{1(4M^;B]85ղmj.d򠁔\u ôZjeV4L|u̟jtښ%rz *+…k^k_[k\:K L%D܈Kռ'[Twn-b&w$M##>V}ܟ|&|&|&!Vp\x{kw(Яӥ 0 ;ݎoLU7^_ 0Ӎ:f煙OαWEGAVxGA­ݿ+~gg. x)n^GA yGxaOCüۍ20Բ4Wk,āvpMYDkڥ8Pxa(caD֔- c7YsFwd",!<!MQ"cz]Vq8g$ 3mmQmæj{mS7V;v{d<d`wPm$ ΛDۍ?{l =7e==lԾ&UjoZ= 6)+d",t&90a -;rkNHO= G$uvOS:*<,^D$goQaa "*A)кTwm2Hsro,&LJN~wgh}#'9"3e@UR4'=aŤh}ǎ,#ii3_F v==旜j]\e$Q7*xdLώdX h4g tpʜ9S2m/ڞ24YLR )rdzS&<@ 9V_D(}&:0"{sg6Iz7k1'$GѢɽ&0Ijj@ Ei<3InJCrx:ud3AGF-abNw|j.B(i/q'h%Ce1%V+ϝ~'EsGW9tF6R혖9 L#3dYgVFzvS֡iރF I+}beB٢溽h Hʶ_Cy0Z4='ì0\rpIƠڥ본Mjm7/ˎ3Ow.8^,m!EO>c'IF$#ʪ5IaNq8 ̔9$wt8ϰxQ6nSS'z+E ;U쨶jpY;eNtA')YMgߓ+\hl G)sk;Ƒ8JAM.2nWՉuX~"rm\7Z.;|*$J8k' c!yT% }=}2&kz_H|Vp o xf'luxA(%5>Z ̉aYL?KoT@jfغ0Ľ;{CWҢnV/oϧij_SA_[v3\SӾ]ܰyu~uj˷wO?K~m&jgy4bE1'ֵōpa2 y[#,M}p/#uٟ{aP#б pt$f,K1RdfX$ÌL߹*_3ɱCd[Vt7Uq341 9a9Eɟ/NN!?ZLC {iaI/6')9`#;/(ͨ{ISC6XL"#ԇHu\"Ċڀ@P9RFŐsV-CIF"Ә k s.GfPv@r2e6#?% Fo8(OC ^Ъ=<q@{{LOX gc#èuWIHsTAqz lQ T-^123ȹjn ._jvՏfn$mr^+Bi cߐĝ ȁz3{enis&[/f1$q#Y*Tc>؍z-g@VGA rR⢽auQl>",Y,2~9W_*;8+Ha[YR{o~Ǔ~7  *NĪakyn آhFl_@C]UP%FW&àc 6dyt9T\ a\eL%L:|=s9=Q%ƶ-m$#jwjm'ltA}H"64vBl9%-p:3qSw}1t{:C|`VeqR ܸi$z9{ A#-lw9$}ʑ?@_+PlwͰMw^0lʇfC mgV'P81+2[\F ҝh}F{p8[3)3`a֮ 3ݞk f[Zz.NKDoA~V]Z"ؤ*7GÐ..M bkh8T*ΗE |lg]p{`EbT^6#C!D.Ō'Y(Wr"Me+䅶WQ~NL{mKjU3R3iiӸ&,5hi/ 77~[YlWs^R <뿓R&x^rc4$v-=aK+=|`絷?ҕahuCGH<|C@7Zٙ7jASBt2$*(]u LN1h,tqmpC2ޛdxVG5A?? ǰyԜ9&@$т7 ON xyqG91{qf9)\v9~z}rGx%͘~ǔL2^4*$o޶@y׫|` ˬq8[%A^-.w3~׍,te'oMB\hk&FIPm \bQz ̛2Du]r7Te)?IFJGiW`3vs2kP( |N5O!,-EF) ܱ @`p֏sNSW/ ㈺)XB'Λl̙hj^({ʡM&wEthT@Uߦ~mYl-+W]j|W o˻߷{Y[OûZ$\D3œ>[Ϥ3J퓂^ɒL۴pMr$ X@C{To68[H4Tt .(ʓo|U1CB]j$5Q>=ϣ'm5}Eee}4b.ԍ chJw vC%x:I^! ~0=Iڔ6M GS|:\:l&t n]8?7j@IQg Ҥ\l%BܪF,b7 D'38=^`Rv40ڃl$^M78580~R%>IsBȼD: vr-kbAb5HaBQMVNU$cF2V<47j215)z.-p#iuܯk4Oj*9K% %78+z`@U;-`JbTGn"\K&+*[P>S8{)6 KEՆR5ɩy`&J[Z}EVx|#{<cJѺ&9k}j3Gʦ.Khj ČSO`D%P}*Ŷb:BJ8 ʹkY]gpC8NVj\h[SK2rY8U(,G @Q{wo l.p)nle!`Vb$jb* "67sECM3 i#_hԨ'-Of2% du;wK)y'[)~u )5_]$֔wZ&_>x/O^^ճg7p,@2u|FQ^F;Ųԍ@zlI-Ԭs0$Usw,-ߡzom4l*Lֱ~3'Bk:CPΑ {hcS:A+"_UiB?p@=w>Qw KBa& 䄕'vmNV}6'6A͠k*K&ORg>^Oӈ۱o )RG)N2Gq%/59x {vW}`g`QD5nmw%W16mPK L<$Ld $org/mockito/MockitoAnnotations.classV[WU $P)Xk K-*T Tlꐜi83)k TY}ӵ|P3 MHeu9w{}M.ةKg'OCe{gؖh_֓nese ! ZG <̓j+:Z 7,;DQHA4ܛ7\m|gʂ:x[|@r+r)%svrNwՑv xtZJW9YyFmG3ۋgkyWj*#^RjrI_șҥp픖vuZJ ")1@!7m4] h-2is Si|it^ySNjOྊ4FzÍrfnKڙ@-UVVZ+O xw'K7)ټ'.yҴtD^Z+kXR9+`7̴##Ȩ%Ǟ3G /<˭rbȇjU[EE\RM^|B_ Z`Hύ"ڢSzS]8bQ9`yHvUu&5bm[^]GJx莴8pgs.ev|]ۑ5iɒ 2M{QD kR3;gtPVg/IӾYl9!Z?EwI&NJHt̲K^P?_Gj7/\ >M4b_򿺐` jMEWOMu44aϭ*:ƻ?)uVqp+E{A -h库F*/ĹR! y^@ s !~Т=ZGW)|p0Wkk ]`[]o"x?#ҝn:qJOE':pÄւ'0Q»8登$1UR S a6HM1N RP6KmOä,-M|WJr*#MˁA7]{;7Zppfנ«H_G^Uwf)lbV#ZU,-?i?B (&HKu2=1-aVq&2̀F!7R1Me?iW*_"o Ty^Ez[BebަD 2K S$oqa#tO $n_)"/1[৔׫w}bkWPPK 0 \$_^;ܚAWRSVVXGʚUKReQB B@.\:ሸV*}Psc磥59:˕JU:vTr>ReixϔXVNv$g/s")tyszX L[E3 rĈ|ymVܔs]ekU]Të[/5~Iq__Ѿtn %%+UeZE=f )em]h]?? {~s#yZ璊B}0Ъ_A21m s?]Ȣ.]ˢ0knA.TAjQh8W3Ykmn(U"tL%V#۾c T(|~ B9acSDszh-)iv#0Ttv.~R-t<;:A2>3Ρ|#ބsA7bB]'^bQ͘%nhSJq(zӰܯy4?xöpJ:lTT/Qmۊ;&8ig4Q뮋">OYԻszr#N4c$ZOK C3>)b`mWB9JH"WIatLkv]ŏ##wz /~fw5ƴ++=Ndt1v" ?\+e)Df]#-lȉ=D= ]w3K4Kd@ kykVKA.|rqƖ̝)wD\&x3xBΗkxˬ˸bOv-#;[ UzdqAsdk!|?C#N@LԖDV;w5tKγ'c =:+Nbo( }FCЅ,L#ŝz^ruA`5<>1pW%!7/) y'#h?D{B2$WC_ʭ9BGX$p7#a_a'4 jyNr#]=PUUms}f?7C0ɒIcq;B;W^1pgQO'PyTw'g>74?Rq_i]\3Y==t?PK LCNFt̒|}_풚TZ X\ T (33,?9$3?A]#kM$tkFҢT̜T6F&`did`c`8$+PK 0<@r*i org/mockito/MockitoDebugger.java5=k0ûcCJZhr:#B,CN<qrI1>9zVY sX [Xb 4_e+ETpe[eia~ R5?PK L^k{ \tW뇵 UuE;Vu[`(K|^ " 6貉v޲!{`\t X(Wc?o(0,۾Cg6lFU 9֝&"zpGpOa+=TXl)];{~`{UmRL#ǔ}˺+Trr1FǠmm?*3V%DqDF1\E/%b;Mw7" +\DgLz$uh(a7z9ry?PK L<&org/mockito/Spy.classN0m))姅:b13!5*5WWS)ց6]">;^{ g-3[UHadŒ& wUYIm!d3nH5v\uGl0}F1>ĄfK*ˌ'g4 Wت*V6~zax =N ;©h{qqPK 04lH2iYumtVF!'~n^/_}|`k#`h]l,#Uu}*B6;: /bPt, `:Bʒc8Up[rY_NEӾXGgy(֠*l%_j11}߱R%+r`y7aqaoN6D}$$Ⱦ/ :VA)Aab>#>c(P "SDayOL,:;Y_->ۻ͌rt5l|Hl7>zsx*Q,oPK (w:*,'org/mockito/asm/AnnotationVisitor.classj1Uѱg㾫UYuPp!>N!I FWsCI h"{90BtJ} _MJeJbm:KlefeUB|`J 9F Y)*OL$.v9ǹwц͇ /]k#[P,U^'TP;APGXm5BѱNA PK mN:"&org/mockito/asm/AnnotationVisitor.javaW]o}7p}X`tP PmIYP-al{ ):V<3g^^\\{3(KUA a?72ׅԺ-EtEZ䓮X^?qY~N?{7 $=EKd ;vZYod1 ;BVbZ#IUdt[GpyI5Kҵ_YB-TnHԒֲ^kQR4#TIUPX޸{;Czѻhj\-wW:, ~nT.=,QJ2β [Bdm]=ZzWk½?rPەџ%EcA 5V4;1~ .(n^q{?-uY *{$1GAk,\gK"$V0Kh-~ ˢSYjثX5rr3bd7aJi|I@hO.c>`2Q<}H뛌n8HR1F, ,~?I?zi) I@XH( MMf0 M0ò,ذE;J]Nڼ ]OS?l'4%8up8LG? xQF?DGA! w&? I08]k"ģtBn?O Q<>]Jтc{0xgN/g9awiN5_i*Etv\jkxzWz]md0Uĥkl*cyj/7._l"Gj ir(1[5_оvͷpyNaGAUwc?Y 2Lxj%'dՃ]qyӁBȽΏ#>ejWr^-Vwm.Π&}ZKPRXo]AEZvJo̴Uw-gZ$5ŧ'`UsI+,D ^`H KlvD񮀸ӏdÒ fu\qz'>ǿvٖ{*zcPK (w:ȶ)6 &org/mockito/asm/AnnotationWriter.classXktTνwr8de(I $3̄/|bU"w2ZUm]uVY>V?Cmo{y u'g}w9gs8 ` SOtU#xU8[.©h<֖ +'\uU]ݱˊL m&Gh4aI0UN#Z}35T5hb3( , nAoRČGV/>DcĮUed$ci(5|b;vn5!mNiM씶D!m4lxKb8ecKįү'NcÔ)q7c})= y#׈uX2%= $'m*q@PnḕPCc}]s.np w0Ɋ,ƽ w{gB${U5 9 &d g &&';sZgO)Sj$"x6\&* tb&T=V+ãxL2,/ۏ~# H) ct`Oq(4ՊLJɰY LR'IOJp܇O{|xɄ/pQ%՞3 0)*i3.=p()i:H-:N.ix$ND<[kƬMVx8bرHEGrǶ@ݲmΰE*ۙv+KD{Ca;?a $X1yA1"0l8EoQ$L4[.- Ö<&~7}{hKcM\0mC;dlW\FeNtv_u۠gGk5i\FB96 ]Ҹz1Cũd4e/}W!}:֫.*b[c ~G%E_qko6Q}vfRЁW, (i%ݮ$].{\@1(-G1$uѾ m a4J}3(Q-. _I7$[~}LK>6mzvQ. ?Ogs+\ A(#3D!mEso<~3v-/m<uLK#3_XJ'P;x93(*.w&c l'-w {.YmJ>7=K3^zjՆ3(;Ҩi~|N 1!j5Ŷ9l~O!΋\ϣD|RΎ<[/&ުy'3; | Mɹ<5rbP:4S<0UMyC5 %ʋ**8YkU>?g*&Uȏ֙ 0 5748R.O5Rd,2sKE`Ʃ5v\""i6%VU03T~ϑzs G@L;95KQϘz$?kX&BJ`?㵉V"͸Ǝ5qN+q?H&+!QoֆӘ %TVXؠʰIc@VUbXj j)jWqZJ U8Fj5G}מPK mN:A& ,%org/mockito/asm/AnnotationWriter.javaZ[sH~OU`0Sq VWxSyR=% ӭ%ǪK{48b5 <:Oʁɵ`n1X8_&#x4rlF_%nl.ihmGN2J*ʑ#bX̢:!;MXD|HYO3a!'jAa۰ba$lǧܕ ,YB0Q#!#<AdCL_v*N3L "1ᠺי+J\ B]F O!YJu}/X$*(K %iЌɂ|n ,K!ʾt`ȸHiE0}E1PPIpgu & - 2 i  . Ld1.1ӠGSH %s)p, (nqY$yا֨o_j~n.ރ+ԡ;:2SNGnZ {:MxlfW*S^繩[L02D 6 jc&v1.Yj.xэ3 Bl: $qLfOBLg<\N0K\bʸXa\WETSU FT$b5j=\UUܱ9N`O`ZT%w}Mn,&Hs UaߐMY#B|Q/;P*^[RLq^`FkN 6)dbUэeT<6u_ Ds-G@H97NgN݊_I^f!Imr) 3Me)|]_1\B"\EC<͙%AgbFR\ $#Ʌxڊ@0 <+jV]鼰m`1e'{ D[kҔe)ua[¶4Ew̫֫QdGu}/((\:PGjhVqOa#U7St;uQQ٨)TʻvBX4u\de`L|\)B,j`n.MBP)kw7]3e - 22M-wZ3I❝MfR& :Az[ؿ=h҆V6@i! O2Mb(or 1Q3̱VK Qb:Nvo*j)o(QPFRSq;wMt_=Pkz BJR]l1d$"jIe E[ OΘ؍EW(/uYFF"n Ϩު`&;*ڍ(8??sZ[Wb>/ Jki&۳hH/D !!C]={|Ph0]5+33^o8`lUfgVa0k0[5+33Snu VOivڮΉ~nx {!G淬C^=aWX-"ܐSB.WU'OJ.4A :d/f*[_gmX lp%OYP=p\kⷹ5TߜIĊퟆ7|3S/m^aC-L @4vt:DL$Q ϗjg tӦӄ:&odMkm|yЄ,'_9ֆGzp#߶+V)WY|';BEÇ[.- ZОf,5vbzĔdMkyi"Mn:OYȺX6 rHi^#+aސ9h;t|GKD9k[DIλG8o%6$chνR4^$"7^P"C9fWL]}rE1tqh_LPloU]1A+%g8c8]qhYZ!z =MQ.~=Ts<+S։GSCC8:r퍱'y^`3>Wjpu)p>d#*1cט)Nbk%)i%_)w0pDꍆm8C22ʝQ>ִVW+Jj=$髏ϝ׌ȷ̸MqUHg/yt~dzRn-dcj&L6r%%uhi=GaF&ͨ+wn6.9w)(&\OT>Q'Duܵߝnݟ֯Kџ\eEPK mN:Cc c'org/mockito/asm/Attribute.javaZmoF aP;a BK;YT\ȇx@. ]JHrr@Ħe^}fы/?`zoHXKCB?؊V 9$,eD0YY~#e m]/ӫW~{ڦ'9K>QR<_p@raT#kW8iйr3Μr=0'#}<pw 9 .KiylmJ< ;A&\ocӅ{xJ8شϭ@`}&>xgxs9\r6㱥#۵>y}"h`jO{e\EVij5ŅFyn<i8us29ԷqF{r?C{cǓM=@-IDxلB~[;mgrD$D9 &-]jBh"-u^i>9[ÊelC1[Ʋ@ޤ:.(vS}퓒׫1VbZY3p2î-l$SK%3\,mydؑ(Ey~9}@ƨV)?@~Wﺼp(sz%U@-h $!2yQV5fCi^j1;{gYs©ZwN#UO8^}^q6|c㳗1q쓂,xIc$m_bU6,BW&D3`R45\ڀc7y$k.c u?n,!^!Gj{X3xGy{߈Ԣ6loِǎ䷕-7(pS0nA,T_Aݤ=/8j5(KF^k@7 Vu!R2 _ 4MFQ-b jn W -\g![[;gկޱwulcDA's~}:(q*°yk9H'߹?IhufV,kɋt+MQv \2nntZ5NU^4ky.Ly-)f;XiucZpܢӻ5W,C5]+Z['Yv|]NWKe?~-n svK>`ۚ^i]|I\o!T"_ug];Qmd\daC]v.xlj܉{ j=ȪaXA*aZmp_'wX=+coŠAOh|}s uI8RDyvu vjY<)29-$^bmRi?7|qG|=y7m_ŧ,kR7W7皽+Mۡ:w! TFp)M{z/IkƯ}s | :[6yaSuW58Z5N_ _C:$;x9E:_)USwH)FGxE*ZkAx.ڊh&hVEtiy @)JGUkP"a_9)= _=΋`_#ǟf՛ҾM&J y'NC=̇țKrC^#E: E_׭c5/ ~3傔W-djuP6^5h}%o[VA ߆|tUo3fU,E}|%؇k:fXVߡr4rz,mtAAVD.}UZߞ+?PK )w:" org/mockito/asm/ByteVector.classVklSe~nTn"J dl T$HFc* KL  MD/!5h |9=+s&{zBhHv훢D0lMEFS!mn!? 5C h)~r78cxgK@4r jS׺yv #9ITWG|},Ք*oV`4 VGG[RRJ72 BjEp3XZ1  7m ,Vw%)lpoc\.FM͉x4ediY2O`fy@Vxg0F< T4Jafc{W8Y2]Lыym؜ e;E NF '^ 4toO*m`@nXhOl@6f>V7(SuyA=!%::d2fv5mUk"D{86bb7G㑕["Ik%oubK=$yr0!L9G@ȼ{g8Swub#nsg$|W\SFYƖQKVUhYh4,uZOh \e{rwJV~O+89-QjS0^c"G=\]Aɕ<jމXu;[¨0t |X9$s#&f6lLq$G% B b;Mᔘ[현 fvJmڞ7ޕq-ӯa0hq8N1F^'C4[ln#WIeX}%#u&벪pΊY W ObUqaj?BR12hn^V5frɲ1Xeg`8C'DqFDw"`( 3L g&b$2ÔGH>iފ!$@D0A )}ʒw1-3񄡻-=2$QD xED ܲ q-:y$3UWФu{PPpaA y\HLP"cS> FD@-${n9t[avjM8&47uvy4mNv\:]/j Cs毗8еl[lZSƑhV  mrQɰD[Un .LqƩնieB\k5zmÆ˞}uشF۰.f@`^s^{1m a!SֶӶ bM6.E6?k`"vKaщ1MqUv=DhY'CXF6/nK9SǵܞkY۔wLj1L^1h5cy `x#{-},6H݌W*SM'{*n] {jd 4M$^I8%,fD%ʀ=`{a "0# Q$ 8Ӿwo|VS'^DzUk%9P'o`C2I<RR=|#@q2Y)"dd'=K=L` XȒ5G)Q ;(Zx'M_p~y,irtlSk\A!]K|:#sԗVeTpd4c[mMe*S$CPqDs"ϑ!NjtXRՈ1厌yFH6_BL+w^M 晗}$*#{ӎvd73M*- <ɂWPDy O6:zo5qV4iŒ +fLXΓ籴il񿦲qAièF?  &17#L7' ջsBY(^Pdae[^,?rD &ȪSqM iW.&8yaa1De ϐ1ia 9@GgugՆ 4ӨxImD,6"gm$2(Y-ZKDuԘ<0}L❏6GΪMm`AcI=W.bI:5Ѝc`'sx e+}^܋:u^GblU"ڏR?7x~̽߀AдvqpVoMS:5+^J/:ڔC179&li[RNcȼV?U SAskStP W!(oKN־;1qiO]lB_d o[WP.TBm=ZIx,;Hxk%so4jH FAo>ThGwQ\4.Эw5 MD/׻8űz6,z'+bدjMJt3: ^1_~MJ!Utpq!PЊ6Ѷl~r&ױ &'a f͜XC$nbXD{O9yQFQG;ZՋ@H [&Ysi3qR&AZ!"Asoeʟo6< PK )w:l "org/mockito/asm/ClassAdapter.classUksD=kvc+q\BHh^u^5Ҧ iCݺC3 UkKIN30G1]mLDڽ{ι?1XN/ȯZa׵pmFNnYծu~ݹ2$5 ".էv=7XLw]i ++Myy5q33H(`DtZ2GNQ`DuOUdqA w{,vBJ3<<.0ϊ#4s(' *'~?yj4!HW,K>i;~G Vy*ؓ>UIT!sffȊTNy2QaoXdžd&Vs1IDbLhW%&uZXr`EFɺud$nJ[_ WPm 3vqEߞ̳xwY^(Æ|D| |qV'] 1X=ܗ%aE)IL*߶M+p-67bFroؾȗcAyyk)V~J1pPDD=4׉ɵ\Xј?#?6Bv9.#2[Ƣ"*cwheu ZCIwuZJySJY[tBÕxoV*ǔz{c#ogϪRZSiN/N M?!, PM)!BqY5wOWpF|tcM ǀtXYcLt3Un.yQ]#y5ee.N[W6n6aDZRBY2t5`2|N~NR|rh-H،w48w/yK_q@yPK mN:"!org/mockito/asm/ClassAdapter.javaWQo6~pSxN= h1$lɓZ6Q)rc@&}\^\\x=XKU!DRT5./Lu&Z5.aiD!y^XYz޾}~ <7+#TB"sD*WcwT`d%ZfCZTUh/TT n "B)/)<ߺ-L3T%<a$)T] VFUQ!(* ehSeahc!oU-'SY Kb״*dQ)uR9@UAlCܥ^\B{M]d`Y#626,kӢ`(W[m!RٍdPb+oã3i* `keScq8hxzˆ42YI ]Kpraa"ºZo+P3E[mPdJ{"+]UUHnx qxyϢFgI&Yq6H">'!Nb$\{`fc#ل# z ,I'1  L'hrl^o ,o7[W< :`E /<<'Yg`,H &o"Q;؄{ s11PdۑB"9 '1yq] 1GC471̳# ayĦD=@|'<' plYt}I[1#2G󘓆N aQ4%< 1w< l(X0a10<$Fo~QԤ/z¯Y3Z M!Ɉ;w6u {E= ~V/ڀpcUښgx<`蔋5}$tST!AAnFO bKtdlB&Ī6I>S+^v_cTFԶ+ʪ7̣*~| N`4uى,rul8^qê ~PU]V,Ws8Un>>+V;Dh^|Fȍ' > ~6B8OljmD'y"\4E\k9zg}YaaQ-1ط&R*WK1^iXDtZC)6#1f)¹ŝ.~ձy#+Ug`7L.}Zn3<8l|s)͏d%UzX˞c:@+׭@-vP B\b $E._SwƔ=7o^^˺o~lnX.xYR)9X=9䭿rs +%l'vfoVR6oX9^Gnq#S{hblZ'+oQMZGD=,ݎPK )w:i~4`!org/mockito/asm/ClassReader.class| |TEpޛ+3<Ȑ+ d ȥ$-tQAt=oueu=W9ߏeca~I,\Z\?iِڊUՍ%+V-R`Iue 1dقie3g sJiJ ʊK!Z4`WϘQ\V4$/[DZzZLD v6Зo^\SAQ K7ـÊ oDuM5ꪫJ76# ~!%=!QguCm 8D0$S@l@#]Sj4P Qp!2> /,VWUEMMRc41'*! oh}dz+Ptgj&(44#Mq]su T>d Z.DߩT7^__KozsF#zJcZoWb! N7B] f@ l! ͟f l6:vs'j39'W 'rBMsSYNr@,A9T $CJ4Ed,!m@L6kN6eAmXk耳 $ V-rw8ӋO+aPe5iqa}U  Ӻ' !l~.,ȪAC &j1^Z."t\n,P7s.F'ʼu'\)4J8Ú7V7-ru6pЍ8 N 1"$pjSZI9Sp֊"Q5D)CcerBy"%E++k4$mM. !1z («m`hۮ -5ri5j1Rgv6 a+du') Y=B^;Ȗv@CsA}P cW\ɧk43[+ |rXl(<.{0bz27]XRWe}6(C GD|MmlLż W;_K&؈)$"6l# o6xP)ƩR񬚦144c{@8qFIݎbiH3xamHYlr'V[3_-M]4;|!\KY\WW(V}C\TWY[߄2yq=?EyGEsK# dFK]sͲj iA:D(3[ǰs"4k^\\Sip%5tXeQjl,gyqnKp ,N=b)>ɔյy'(+~cu ]s> 7P#,+prnt,N80xK &tJlBr(5 \=8|]a&0sH|px zлDI*j[DI? IkS)Cɨ>qGG_tGz M2oނq8+e,_8nks;H*I&uTS]QT 1'XGʈ .z1K ;$MiU9HȡDB0˰E& ;N^XRl!cF\Эc M k2]F$cwCRC KwcIkxL*W8f%PR15$z[!AN͂7vQ qov0Ī)hHULÝ'Km… rӍF3:;i)3jgbZu 2Nfyt$䉉xq&9KL.dPcVP;'1.uv0B"!UOn1f'tjdSd@Na4ROgT-3AęF+i6yǜe:rBPmԴqUaEs Ț!vUZM{[ʊY5"e-,d&Vp[ # g,)nLrHUOkYD^E\dpyisEҩ &Fta\&Ύ\s+ q?0APB6|bRߚDU/q4` &s}D E)2Ҡv (N1YZ(fb0H&-J^Ȝalu jD[ĶGA]ր¶5a.CZ\x!'F >Ȑ0W4y9eJ= ^VKuUqBa5 ҀVdR'fk4G8b>7*1|'.0E/p"XR@^ݝ_hAiIa <ʳSqfM-6 NaAn= ۅ勱bbV,w) alhVWitȩ uz}>=JѳD>cfNwL2cרA*5Vh]>6N1ի{OXPKl. GeL-hx GiXdb֟;NBpfߌSu+Jyt3G6ITlT#Jdg3LYtP"괙S8%b8l#uBzq6/ltƺ(/)8ra8bkʳB.ބ)3,q7Ҽp!^90vfA0A9+{G)jkm.*owZl@1ny FA;!T$.e[Kѩ8[vŔX)'`Sb=No'd  [`{C`ڡuQ!UYB.@&6%>;r'b!; gt?m)m!ۿ _ݐJVPy@5Ad{yh2<|̧ ^>%~5`iH~)Xtq%@UEPon!5|ޥ0 F--0iC2 %\ "@Bp'AHU\*M@Hqʺ G3Ap#b؍+z7#R= SH B/K"ꖏ1<`8Gh: cR9Ubƿu y- r;bvva/ 41Rc6Ɵ&SNKނN+9$AVBtşدVˬȭ?ζr<Se7@@1 <Ȁi؊I]xEB(8 Г 7B: Ӎ!<`(=UNG`FsJY 'PHP5<stf-&qLr=>s>8fWUEWCXDcu+R.=0';}Y!h BX%WrItԉa0b/4w:+9A4 <%G&3+E2C'FD,`h 붜ݰA,mx6 (bicE`8#w^&墥W2RvMѠ q 9O7 ӍpCI,K -R܊8+ ! զB[aFHQp C0xqtLm-ul{"]"$ IB=R`-.9p;`h'~xd3$'2>'(ɅQX|b!㈝L ^RH|d"OH)&iw:CpI,e$5%<'əd'9K7勆pw;{v1q,¹!;%Lsј}>vؙvބxd/<Ou?"?cijihDU}p眄gG{~6֟q p~ Xjo~Kg0g{m39|,Vn_ƁxEyWN+;<k򤧠Bp4sa$3*6 9K0p|OZaRd !\s1䓍0\0\eJ8\Nq5CB ;&({ࣨUcDF0;|Qа`# ֩t*~#&lA_a4bHZn;<X~!(qX Vtja9q|>FɮJ[ݸ|m%ZHHq[%n 8PP꠺{ `:,w "(//8ZCǿhuCIP'$ؓIG:3$#HJ܇?6b{H͚8Yp-W. &L#z&Hˠm0󅋊ɽWK;zJwgjI>%g}u ?8nwD$l"H6~\P{ Bd3}InS(i_ApR|݄RpEj|4{2qt_A, `<qx\D׫9p7{3EWnD>>l)ۧ8u/àhza,bg,td ;M]-0Í20q:Whư"do@"j]70O0q.ylY =;“bsҢ[{Hst!)בּ~[ҝ͌qP頱dOVO?''k؟rfHW$d`s.fޮn3tmn!a77Ya_*#o'v|}:0r<-h`#}X eX6Y ժzps\zfx]!#M 1x; nH8=dT O9oT8$zHn _}t=wDO5Ok3fԐX\R3 u,Ugm)Vz:q+_j~K;Hl}i߀]d.r.XX|4@_ S7!%rpAtm阨1Q3]fnlcM!ɻI)XdV(ngn]Bp_So@;)?7 |:Kijqf<+.Lt*]n%z/0Lb#ibDHA69\<2Ҥ+#;AߵAJ#.xϿ4JI p2$-zy&C2,s+˧2hJL>[$DZ {*SV W` ACvFJ7u0W7ٛhgo/:J/ӗE:9 %02l#a.c d,f!,0@ '$8ruUf|rycrB.0n}qBshϯy0lw pBP;T.W{Hk+3D\h"|GPYVg7ť'=RS@mf`; !X!GID*`Cfb=5S\e6..9T ==1ň].l\|xp>@= pDZzu>F[GSd ޺=dq&3s_k?G]A{u׈7DJw`iARYt/& Qk<DJv4 .m /"Dc]B^nG zȪ0*Ñ=-'87 ‰; AV1B"DC={ F4bxj"F|@.!Guo"H "=7ַAQW}#S|vr pAۯg WfQm=)|' Rm V*yY *@oi}"JL-.q+g<0$2M0  iI fû/qC#` cѕ8WĹr%fcc cr+o4L뱮7Λ~\oy !X1Ԛ/sz<Ѓ[s?G/[>)bd!~Uu=\Ez \XE ϋjզ@G/.MibC[o(a.V!H#'x3isdz>w EN#fHbvn`A7j0 OtAt}Y  .%?O%mo0?5 &`m kpz#B/U_Ar8,$c8B ,;X 2l,J(EhL LO9BY7W ]\©TAhL2p1p:;n)fnC89WBFASkrT{&Ѿ ~؞fO#4>6"cۂ;a=6a}mHp0B`߸6P?B}siB]ki&BLDӋ84fCjqsAu1I!E?CŅ >7HBqpL=yc0^Ksr@r}6!8Su*>Bz-)oJz țҞB: ROG#]T4\S# HC(vz_c":[ y 4$;C(xDo.ƢK\/Y@< N,ē0j=m_tayƓW Tayɛp.y 6 |19דw;ɇ|(cקp|Mw;ߑ+8F&87$0;3C3&?HhAQTA{ҿ`M EϧHq%Mҁv0"͡o}[~At=F3F N`NZٗKot):Ex=봑'fJ[@g|$]5|]gsb7sZ_HW fz> xWz^˿C^?^ݢ [t)hRDoW&;]khIWMˤǴ!dˆ6L0%j̧-g ,I%kW:[`]KӞ` MY}Fj?3cc-˷x8K"o&Z"H6dX&S-E2M4r_fXc+L˵lemͱ`s-y}lqVnyUX^c ,J[h[dX~cˬ*Ƴzk"kag[Z֍lʺ]k;[g}>γbV[Bvsvv.6/ҖƮ B8]onn`l3f\vbGVmk=u^ylgmd.gm׳=XV׶umϳ}7~k]eOڭbسv=gOdۓ E{?=b/{{>gu{>{^޴Obo٧;rvľkodW ه+G}6 ;Ca:l#ы}`q~v_3ٯ쿎%h.vlyZq+OrɎx+<Os`ǿٛx7>4aqv<|D\7Fqظ2wŽO5#?->թiN ӝxs /s3#,g,s3|YLgs5p+Bg+s^F5ɹ8; |s_|s;?Ο%c|ůvy.7]9|k$oq緺 W1:osmEu u=庙vm{]z?z?z?z.%u?t[n_tAUv毹B{KF}}+{};}ֽwu}|"O|1?)~9>?_@ TX|+j|bL_Q*??x_WG^+G_ 'MЕ~ } ÔԄ S %Jf\%;ZP MhT%TrU'lTF$\L[ $l脿)y O*cR(W Q&$U W<2cQNؕbO23P93XWJ<tDSyTfzjY lFeegr!,ORٯ,ɛ4{ӕ0e7OYWV{ 5ީZorw{rw޻V9ϻQJ{rwrvbvne1Reg˽+_*W{R\=[E\RcBM/Vng(ws^ܫ(ڡ/Wvkp7YM#x]OR+12̽Z%.{ZŬNbj7:~D/km0V.۶@hO}lORʳNǴphݥ՘@[B+4D%SmqzwIͦKdj,lDT֊-KH$ $2`[0^-7i*NI|+j8/T!Uyr0Jy 複(AS;0I}tE\52IJo'cZ4E$ siAF 2|QNG30 cr,M2ތ]oh`SpGH_ Q~\T.jpx\>4L.%I\d打X|3O5>,;Ijy&'L&AD"L>M/ ,xg0[>C ~·WоeuKzImA>:k{`tNfl[ҿ@}.͐𺶝.dK.4״(Mȓ"8вcw"u{iS0[._wG'v)2Rvtq 14qތ64/g{|GIЕxmFt 0uV>ysx|So ( 5hQڕǵ:)`6>+A[Lc[mlƶ=Ҹ޵qI퇢=a[{ѥ:mŶj0.Ҷ/ܽPuz{y\y6ήBN͝jgo7k,Sױs'yKuN=j+Kԋxz1nK2>A!|z%^gWy굼B/U7V77MFu3߬·{-1u+gaV_яfj6\|7&\J+ fjDu武hLƧBZ 4s7p@T܋8K"CZF?xO1/.%:N54$!m2 Dƚ_zIe M+<\+/Rxu/LR;X%~0OTC$,QeФ>`</e!R}nU_mkcffsW轙I9OC\f>R7^^7LƻH߼ 3JweO@U?9)EPE) Eɟs̗U\S&od+EDTD12YdQP4  U#_(ea 4E9WDX@KF"CiviHP ^ 7nw&IQ0"JiDq!k"ƙ+vaG7`65`綬L2S_JMآsf!OTL 4ݙY/mT Z3x衭m%Z }3J#I.$/xNmЗ=SY)OD׮:~)$` c}ֹՕ=nzAzom;AQޱsKӻ(`NO1vXP\#Ky Kkj=sYXE+D; 3PK mN: R8L org/mockito/asm/ClassReader.java}s67sȉi'_WŖ+%'x2Dی%RHqߟ A[N^1w,b],ݻ׿{;|l..Y: Sv)X2 $d iEIN,Hc;_.ӳÇ7?g~vA<()[iX@?(B|iȢr(d1K"XeF`f$:Ƅp,ʲpdMCvdMEqO"ll8 V]ʒ'(EqŸ 8ɢq؆*Qʦ=M4f(Q.5HT`%wK0>P j09w`ZELӜ4oY߷F+p~Vd: ) ESeA'Pq\ F0!4Kqrcx]0-"PdX:j6B&\ ŜT`^l8|~s0x?Ï==xA{5 Yw_ŝZ ~zzs_@ᠻ?mX{;m@`#6cVnu`}~>w}o:7݃Qp{ 98Nt GlW~` a;GB{m6|޿z0m˅`P*KfB0Mۇ׈` _ G^;Dam7|C"׆^F]DgpGrzoFL;С w}6lp3Fz|ٻW=f~_ptE #* Die{:@Hކ+y!5n.#^Xcl ۯy׿̃yp+3KQtt_ Pqȓw3T h-Z+pB/Ol>E])A5o01V !!--C,,Q?o> @'edxy lU.Q.N 8r{yI8%,B! 95UK@ @!N1HWXqW.I{qhȏ%ތ.cGI'LE5 QEpH,߁t _o^UW,sKD\I$ .dA xdd&a %iVy?ͥ5T{q K$XN<8G` 9CmE{wN4$`(4fcvm"쨩s{L@TٶӋ2"qCP[Q0B0AiDX_]8Gx݀$<]@ .<P c$e@Y++?9&|FP/#P{ )mHRU֕;riH:,ЉsI]aP/bA;`Ns; *#v$4P& _氳zg8b0_6OIv hנ(YSa`f*Qd@Ay&uj506:6Jcqf{$WѬ0;S*XB@FDG\7AV80)}S4['BS ZDsC,Gm54Y۝q)k` NZјcƁ=`k* v"QLKC܌Pes%{.ԇIg4ʾ2fo .USeJ 4(!g a]})@\KhIm4YPj6ڤ, | ֘>JF$xOxrJ;e31n!Hdxn qqFbhŷ\g)a8X!"Pa[.13J! y' q$44%,|^DSãh,$uv_F|+| ^Ae0MR$c`so~/}ثAg՝ U^56D'EBr,|XxUfP^w8 Vw8:c UqEKЪ1%bA?e N2qb琜0UA-q}v5Rk@1 b0**.RCEtLac;!؛h.p2N$ȽhCC/X jx mqKySfif&[{}aIQYzo+JX^|+U}Р]&lҠqh7W5TUHVa4]N\! QYx_XGiɞ.s3d{]S֏\y^ΛD[F,{/ӧ7 ,f#Nq/O ZG   !c@amk圸䀾j3~k;0DuYtDDx3V |~DP,Քo%4zTXGŠD=,P<`G-ODs+7xXica EH.!:Nꡦ\KvG6P}GW>04wǪ>h&_f?Z:㵡 y,6ǚ~ sf:Iu09HjKZwk3٘K>|-=Ln:،ljKZk}Ϙ0\&*VՊ,HKJ@q =}av1tv$ͲGEڨCNf8ƶ,цptٗҢ "_5GN ?tПETրKˣ!KD]#oz5CU` cwaa#{I|Z3ޖ{F; &ag Hq_0UT55 -l5,t&LsZ b,5Ѯf ťy468U2cxh;uWVYU: SSa%`Ym m(S& t GQęj%nFju2{q]<1m8Z3 Rv*޵Z;Qd@1TpX1b)M/J7n+tc# bqYOH H(DNj~a/A\!Md*Y)؃mvݍthwQNK'tSռ$GLsUv "J |5yϩ17;ܷ``20(GFi'XN[sZ<6Yaj!qeh55ɟv (@~j;9a`ě[v7 xk)nVn "Q<48< VQUw:ln~_՗FUh++W9Rs J$ClR0XUHGmѰjt6K0U4,xNޣvX7ԯ7&$@h"<RCU}z̃Irt/1z–,Ox\Qj9➓"/bilë^Zw0w`AڏQ;/p3Kʯ=KN A"hYwb"S2dpC"t 3o ~3C%Z.d[f.+ Ec<9˸/OO,E Yb6;F$Wz6[#e:k)R!ڡH*NGG}GMx|SHq,SJN*]0Dh.ORlU$4M"ϚjBjځ&ogN >9)I8f) 24Cc7[nfĸIAu21L K!J~3-KQT 㫺4D¯r[OK۵ż_5֫ro`[ f[T*8=c(.,#-pc筫k57p&JRV/Ů>R7/-w.vXޫj=a􎒎\FD[r'Jʂ>J\c256P( "-b3g!j]+Ef/eA-Ehȍhݤ(taczNӖkZnv653ٓ4\}h ξ. oqX'p–܂O.`\X&n)iW.k8w#8MsqUqFK5,,7<@ԪT*GD@;w{طV3cۮl.+Y&n⦮(ځ4{ZND,{R\ XeF=Mw3gS#ݥ/n !Wb<~K@؊ k,y,k42u=:=ҲRmc KK.eY5X,YaLFY:-ՏacScKQĖbIvj(<~#,n6 ɪ3,W5K?r ` OE+y36Ǫ5y-6 -^Y|,_Y<-`YNVjWǝ+K,K5,P-l]Ixeoꡐ4k0'ټ]h迭,eLiM;RA.C=HX<"緪Z6&Mv;!vlT?HW G2 4p(d[M_q.&SF>PCRjV$+A췲=^]XV7#t3 boAPAyvDG;\\ή"ylY|aM]c=1¢܇<:Fo^G36"ˉMT5-)淲/!lfwJ$'*yiVxp&J?̬faS--(ؖxO0>+=&UuVXcfG5 \F[=f kiM#> VƅXx4OR:ڏ0θOR:3)zrɇLύ*r"} ,.R/`Vk`1?AP7$vC ,Xc tv)2V]*sPf?:ZiSe (;zF=RV( /w/@%s|T _ǂ`=yEyמ+kYun -XPf7DXJYTGqYi},X7 ,fըAYeDX5f:PA9 G[IuwUxWuP폸 mQ;lMٵFѮP7kkݺN_0ЪUh0%Z`1M, .n;D# &^q~4uR /xA; TX/u'gN/\޲)r4m$M[1zM1%Q 4EH#ۭYs/]XSt֨mLgxC.y'VXhj,8zp,zx]QyEtJVYGT"wWTs'wK*+߭ $m4+K !)UX>(9'  'k0+ifj5_mr0Z%keY<3S\ X@{Q |;#j+K ;T%~>Q<IVmg1Eo.E4\=j}vOg.jWĸCzύ \+'<׈.t]5/LʵZ:M H]%WP2<*-0l9?g t gAQ:`v1Kq#N*0mffK%tOn)exDߓr#TǙ6N+SfUxU1x`S;=h?V]2jrݽ{;ajH?­7QwA.iŀdbpV-\(+T;c/Ei0ΒYX'.E?cJ>|V&SHk;רSbv^Gf+sRZHqu};o4Á6 G5רFwsQ/׏YE*`)>cya/ `<.5Ex8@I $Zi4 G|x({a^HsEi:mJߙpWӡM\aƼ۞[O8ʞ5R9 Q&c8*ޓv?3`t{ǏǷW>Z,Okpy`Z.:5ym/}bw)}/3qw׃ޠ;Z{}Osvփ^V0|X$A , Y&5 Kpzt~ڶP5Ts잨aNg<@mycf>[%U~~-L\^TNpS[,!eNiqQPcGشi9%467 bƅ8u2W^6 FU$̔)T*3/Ddc. \yMSSqkgϚڇ޿F<&&cаY>ϫXnƯ B#R} j k-SoB<}ý/lz{&*|76?$m*U\|Y6.G[dfJ4KHbS'9S盛W-⛘5zx5Z]Sci*4M|u}6zo!#AR]cgy쮾Hb\V +^VĀqC'{,Ӟ. vuoXﺭa, b/?i,2yFY{ǴQ`hp `!~xZI(fܯ{,W4C͟4G{>ҽAwFEkz'i9kxR]w'stow~/vt( jSbYsֽ ldb%_tl򾴙n `v(nM$-RRe6$&ያL(^JPuXaߐU gHj)-O y4.{!:o*w4o'="\XZLߌ_|b$WXmn Qp|˗꽄oQ%r7$gUNMOСOu<J$y; Q ]Q%JIoLWoHLGAMsk #aÜ ؓA@#ܽo3l6˾*n^R$m^-*SKR>-I#^Et n=\w<.SUkTBQ+/@}@8=P/C,@!r/jՠҞ͎yв^^{$,Ie /=hgžKlN+}riCޝʤ$ԢהȽJ >-_?XĴI+mewa{2_%*y=Sg_+cUR !C+U=^OǔɎ1 A%w (zUnD6r3l^7>]Fb4˞cꪧx}2,Ş9{蔄r|"9| 'DmΏƅ&.O c8mqJ?ĠKsW|{;Lt'1ew,΃E` %:`Y3Nfʞ1><%eˉ+ޑ8KN_2?e)wc$Lx(a &Ly*e̺JSxa\KDXJkt9"$,$O;*IK/7M HyryTm%ôcοj ~0.N0&QJ}6J cԯ7wܼ3|q^s{42*6t /.{Mx[汵 ]Sx RL%ʭEƗ68moxD0)op(x>9("k)4I=z  +uOC.j=^2J5$ h,8@6VvYVTr1 28"%5VH:b+&tM4zbS ]q1>QL+D\qQYum!u]PDDB ӅNvo y9HFd]|s.l~rKϴɮ&$lmvmve{Њ Z<2hoGUNl/.ZTsB*qAbP\_:t)}`nwoX屪8:8쭉C7 h7YNwnچMfBӢ,u0;euUyMhyoJ9PҿQJQ[d1GWbwEWK[ՁOsMXHsp,Ihd{>9џzQ'䠪B^5J*p+)Luɑ6):#aN$A197*.䧅ȃa(7Ы8/+_ <5_Lno2~|UgS˭NE /Dr"7 \ 47D >±0A<<oƷ: 0Hy{5IѭRi#_Lou*:A_Mr2u`tП-/ɭK[LĈonof&bf+K h>Lniv/Tس[zk ŅqW<73mQxQ+tG-2H.-eaB5eiL 57gZ#讇| ;zߞt {^:;;RǽZ7I18HmLa3 QNqG@T"@| ERd*5KDg%@Rt)[[9$1.!<;Uqwc|TH0ŸwԤ=~Rх X-OlS-c67[H7TY$ZPZad0T: ֍/5x1C#8`" AM@ <,PWO(R NpRѡSARu*qNTqǸK),9SG{~m<&(HkaIH\D# |g1ƇZ$*8$ckU9!~R(LU`lqAc@7TjEP%P\ۜJT&eE0u/ɠ/8ꤎukag~+xںX*D)mLu?h_`O" P9eIWg#zcM\ aqrX}tuhHqgtHABic@car(=Ҍ<12\SQheb; W.8]\C<epVT^l>]늴ɧ󑦆&b!7ty̵q!j+T($ 07=A`n:Th88>2HY}dўUgy<ƴ~OìZ4V{>J(xTpQ 5k*gMQwjRM{r>%X ~4ۤKp{U[5sȍWcpLGdp|A\&*L{~e[%xiVӫtK gEDL7j)sVVhro}o+c6xT,f>|JBTS'UB5[zG1 XrEejXG Ӈ^;?GRnE6h66PoeS)cRM5$*Vj5n+b2xQQWk48M)>L2Y2 hL]x?PNt$$iƘE x4(]{CNEGVS2p51bܩݽ.qKGmHӸu/Jow=߸*:2; γm=cs_,k ~8̍_py;HIY oZb.pPer٤B[݋wT^{ f c|;S[3:pF 8t+S$ScG8+ԈI- ~[[?1D^wbL Ax@Clqe{R6'Ͷ]gkQU4Aex:hPhj2?HS-j\@i-ăϕs+| ՏOGh=3&(ZnW ۱9kJyIsT4~]$SX.-\urW 0Q7KTA3~+HPRcj/(==e"Aym0@~WuZU\pl'f PK mN:5 "!org/mockito/asm/ClassVisitor.javaZKo09l(fs03X -6YtHj`-%ub lR^g[ݙ :T?_U5}~zz ޼{?ڲ4%b=ccpزLʔBfٖ?1\7~3~ y9cYsx+;\|ϓ3ГO*r,5/TDJ9RVA+BDD9xEr/|(6/T>l A&Cx'2f*r9/KtRiZHSO& 1. R$HtZŮX5N\[ ~,[fDA]FҀQ"ȸ`-AKUc~7V3s7҂ Z~4BU%PD!-q=’SOs|@1 5z/ׄdI'Ch&,Ss^u^ &vцnf ꯏĵ99E^fYrhcF-'?G9=e7Aknw *F5Y%cT{U RV0RoS}G Z=P|UMrJ MDKfv9d NRX[)ci7mi $R0z?9 FP>_%+0o~UoōI~Y&$Ī/MG[U<\kޗV T $9+RNOڬiRzΛ(RC]J̛!Q-hQH5>d6OLVx:l1,ˁ=d MR kFatNx}ڋe^}25k^;jlk0DD&uxbg0]N޿V?~jW"庄7'i _k`)1̀Ȩ78&H"V9[;%_NUIܜn09tT9OWԺ)ũTmFJG8o ^ׇ&؁ OyˇEMm VxݦR#me+ݍK_ yiR ag{uoߒժ@w@ Jzު;@j#]lQ<Rd(w,ڍfW+oQ9*vP_YZrW ST#i0ԓd^awZS9Weg܄WʔReX|b-t!׾=ou}?kC:[ҝ2 t5b-]8X =lrLel׸]I+aۖTÔʬ(Wѐ`DPG!oMn%^lt5}ѬL|~a?neifP<#iZdT싵@a%GsqwhnVubXpXQ},D4f۾ajĢ {>cZJXx>WZɫ׫kE}m{Tz{P54s R>$=cᵶ؂Z s-6c]@\h Ive*Y!gw*K̆O-0ц65ƪz}_UZmzjܵ9sfIk{sS,H¾p`4?з?01"@P†QH6Ot^h[jK]M蓄Ȍӫ몚*\ kDiZB\LچfPhsa0ՉU'𔆆lB&mB6*b4 AF+j˛HX̧ljnffm(VP!aZZ'l\S[\}4WO*}^]U*OtD֦tƀ39#C! >p/9ոwFS.Z &#ܿs 'Xق _7:a㿉 X`W:[4|uf>DAD-L1g76Vŷ 7 [ߦ$F pv4w|wh1lͰ[E9)FT#K,]bڋRu k=vtulwy(K!lX[P}$9d3%O-9Y1x̀sְ@Gr"!bMub6d!'鷩'!GN|~)E'ecahv;٘],h n5} )Lo~?tٍ9]dfۥN`)fڱsS{$k\M:0sRC.xƙ߻}Lc1SV,zJOP$5\&8/ Kv&Sg#.s|:B\D呈'[WvrI;m ^P5@'B*NOqz%u%k%B׭`+ XՍXML"(oŵTϺGY[cs)<@ u:}$ڀr`g]/tMWbB2L0Ҍ,[iuNYݔBB7 7cb"LuE c; IDfbyV.r=`O /ƭ.*jJJ"\Q800/$j*fNbM`ԅ>jްֻodL̨6p'^AY+VV@ pb|njánk Ҭׯ9WxGl o /RT~ u5e%&3Ry]yFbfohcv8 #kx})\:f+ ;-x+ًh쀑,<&x~ҔJ*j#~Fo7GmE G*2褐 t{#hUr]x`/ i 8a<+IE܏r13>!70asYNpSI FHOG3%@JzCF1.L&le]?N~7rz'ا\0Obݼ؂YY ] Cy\e#Y) s=x9NEʋK ^NˀO<_W/MUO.y!M"Ti\ +E)ax7):iA3i8US\E-qd0}%9FX,{xgĕia@ 5o\=ߙya:J|1/SHAX'!4:q9@ ųuqNds 1Wcek.ᥬI.z.U%4 ;Y**RX,aE1Q,Z+l|YЂgs\bXF.1h-Н{.QƇ;8P>ܓ#>>ǭMX)VT|WBNR&0MS 4ytL"֦P,%FǭHN~1Pm9|N4f|\oߋNJB̏/HXβ^U+c~VWW[[?U)~\/ԥ"T7k̟ի˫u>_M >SӸ/_ * ]eQ 6zW~{nGbVyp Ecp-k\g1z;kޖcv9S#w(H+?_T,z5QϵӧZ3SxX[Fd=azngy kv찞P._34lKޓ*Cث 6ahf#<Cpw|{.=rk` `w'ѼқhrIݫg1DN67/*}p2^ (ALMP`<$<0MLS^Lb:J/Ybmuo0|EC3q{g7|U1a".%C`}usJsNo-[ޒ۽%Cv &x-w^8Hbדv 4jZ]HS*(\ TPG*ybL<z`sPҞ`2Ivf-R .>WCXʹ G 2m4!Ol3D'GI@@mLj6.Q)&{=1O&oRPb&yV^ڽ4Zk Z_ď$n< ϶x}/ AG#k8/ `h4׶*dZ+J~MiESrBd-> 2X,vY/ >z ~cRCE!xꍱiɄ(}W~_ K]M =Nc,G-HCx[ZcEf9!Y}L,%qblEոuuxQ޳lKY:pa Is7A*A@u$%4/o~qG s<)'Ymj *~9J&w>w&e\EW#Eg#ȳly6<0򹉠@ &*i0MP7'S萓ʟ}=mer:)xs /aF[Y!P`Ju~ jOymeN,%JwiD1Ll:SCqh5h|S-98mW| f@ӨyK^?tc;ܡ=-X/&ùp5j~Le Òi,^BpQ[wweøqŨg6#i͉a9v9v#N\udE?׹:DQ`ƪi#,08aI9mC2I1ψĜpnb2><\Ec8fn2UYR'yD|#sЛ|5>H^m;"kH Z(}yk8ha8CJZwP)2trfrPRiK& 6Z&[>A5X$oÍTP' iYь-t:8w*U4!HQe$LOQe4xŏax?J jijP'Cx6ax* (~AE%◰K v_×kpxno7oa%ބ!<(ކx^/5'xKß_)>,!N#'>bKZJH{#҅x49L|Jfҍ-9ߓ9\C,r"LY 4q.J (gy&A9WčP|[z=H<$3rxI.oR3e\*ȳp3v-\}dK"MwvNO=^4RKK|Ba>9ߡ@+LEp!#r$:ڤYТkЮ딟 2"W%u 8&6ŇuF窯nJ^>D@> fTh??,A7#jR=ZۊSZֹTor՗px J:H\BM\0R֩̆PiEl".0 NOlρE\8KBXχu/\z1l! avKp~&)7eV GtNLY6,Ŋ,f}~L} h_a y^謕 GC &z5x`Ge3pKLxҨst <9nEy.PK mN:َ.$˶ org/mockito/asm/ClassWriter.java=kw6{NHshW脭,y%9ܞJm6KRvw>EW'f`f0嗟~"K7Y,řg؝sW,[N8 {F7X]E,8 ^؃ig djD"t#7tm|A/G܋Л ҳ\" !@'Sw \F-q"`e0μN芕.8vbN h<\a`ť? uY̦5p.tcE4WC>~{3EH, I0SdnHyRE u UltQ}%!HP솞S!d!ܾbzT pH~`1w.HQ`\:b=O/~l^]kTcbjI @09x O69?XKTÇj60l8z-ϡQY2.v'fQ LE~a "j.Xf;Y@]WC[>+ɗ c[Tv_.!OVs# f8h;駟|c5g}DwD+/B swCP4KP/qZ0p#wq!0x9 ՁfHCμpbX_+ga 'bE&&~_٩\T3wVj%d*F3$267Ӎ]wg /V0\no7տA;bAk̀7Dr偝[ɾy$%NjF# ufM[҅M1"0C@1P_'Tw9IKYjs^ Hn9BZHuBB NRCWEꇶMĕ$,PۗF8s0e#nzύ4,?:A I Yʤskvw`xk@=BFzG<>|mJ]hx /Poc}Z x)_߮$3/#!h3|s+^л [lX͉o7~AZxϿ CRtm{d[pt BF2/G09 Y=92~+V 4X8Sw~+~ܝ׊y݊P^+Lbx ׭ oVc$Fl';PAجk{N6FY9_NOn +j\u:>;ΠmV75[ GN1@>~0|cp`U _#!3td#Uѱ,~g<4#֡{v+|ki "D\Oahݙ3sV7z2ֻ5dTKym6ԲpYN|;;ZFnpŢQ5gAb䰎 o > oQԛn4[!<P 0&`l65 3>cƗXmMKCD:*p =x藁 W@>cxQ*(QHW=+yj_>'ŞykV>4Rm+ <;{Rn[y=fz&BCR›]p_^15W40кpwш,)fxwb9÷K7(աK :8<Ϣlr%D}%Tg>Od""432է,0C^3J=))s'vQ|$*We8WrBW/DqZGD;Z/i..B]EM^fe!.2?ɡ:A tBoq͊{ /Dӊ ž;sM݌L"n5"k N֊CgF<,#,P1KM S Z3B暔`3p8l,=Ss.HRRM T&/ K*Nf]y`U Ѐm]K\`J^I>@wq-8u hfA\:5Pa!i2()1\`XEXs^9╨#=zUkp%323*fzvb, ~\:DZAFǵjN<\Ӄi7Qc銘Cmҿ*ڒnr\r+lJ}M°r)K Tl JajQTOU*tjɽ~bt̰&AQӚO^wM0\7 4@N(]DNť y%IS;] ' 0Fן-O,:gFDΆW`yd8$Pj3R€\Fclrtfd]Av\:Ͽ?^%F/싹K 1֬@IAL2+Jc֕Ijulc(Jɓe4; shw̚(]vlΖ,ZNh/1@|2LViQ%ʍx$3,צe-;+WsHH܎G$HoPNm-O)Fa >k@f4ϋ8tvJDW 0K'EpIҤ30gЃ3_0gԓ)Mr"׈z0a ]@ȶt 7dFҶ2D)Nl߫ޖc=}41p兵\̃Yr?M~Tx.|ft2/~?VGvp+v6T;.kg> u:G'Y0cp c 2'i{S5.n 6Mшڳ ' (xy4 $_*T H2c+4Kj'f*U׮tJ$u?ON/+JJ>k4N蚕Hԙ bP՝ND|Y \^9Ɠʣ w7*v"Lfj-lMb6jD/+Ikta1MݗV.fy:Bn ݸ˯-mx཰&vbwsٷefWF^r#iݔxܾ\SZ$n߯)=lp pS|b8}+_T) 䵲JxOq~̆-{ll`8=]|xfs DxYoCaB$S||k0s<.,w.6SJH J1H."#J,.a&SKT~pyt>0Viy.~u.26urvð n7h5`{lVlPo+tC#nPE![B,۫VijI<ƞUi(o>gz dEcUB d^ʹWkTђ{UI̹a pZD?;JRx3h9Qb&˳ SS̫w_CƶÝEjdS|;Њ*xURo(xp}1[z++g,(șw1:25T1 Af`DN$'֋ųc~=Le BKcf 7G;54Nq-9.[qVbԆ\ʈ$.p;A-1]bX,*Bw >chj G֥"`.o-mJN'q+⸃% YJӒeLC9N 63S=u!FWq|Xe Ȗ\3EFÙяY`^1DLYuW2 ZyYPǹjΡ*m/+u][X +JNүǓ )j>m{H>߈3I+ꨰ8@b3O͏sYJ9 !4͍ 45ikP"*R}Y,7ڣC VKҎ FZ(T-Y’nQ0EHGo5fN˵A}2Or)"Z}j ^,DY5ɃC "Hd\F3:"=cw.m$t"1]{ }lnfpA_ }NGdRFvEgf&N.;DJ$)sq?<},O89OeRcU*Z@] cTw>w1jd;%+ħ8mԥnNOʹaYFF岚-Ÿ;ûi%-!\M;c~¯3|!BLEǬIJEv锗 򨴅;0SEh{xfQUQ%$ʬNgngbw"2 {.'nf0yiM.Ӗ8a|4T >MLyfR힛6Agެe) bHi. wiHU$x]r jSC5#~ĕ-}mEvledf]/#5$G"\#k@ -_:p!'c`38K(MRnJl`uwD?vCH[4aĉp95I#Afc6o}sdvz$UJAT:Wx\)鶦}tgaU;{> X5S-z׏Y9~0gA\=87rg'+dm'.Նs_2ߴ\E:LdxY5'-E#N`P柾HβWȝ{`Qk q:aMJNHs"}G )%&U7t0ǚ, ]@!L <,Q8g*ɐ%389?TBHJOb_<h(+DpE,CЛM| i@#a+ 7ѳ0 6UOR|9@1ZQ_A jkS/H 0C X=4Z Ir**RN^$D97?T{\3 Ƿv NOYuܲ _;b,$tm$?~\SN5DDnRqH}]XKa\n?") ")Q$e{APy0>ȕ(fm]Uڎւڎ$ٕbzZ XfBu—*۲G7>nuq˚Mc,qiHzn@]ѥ%F+.g#g"$.1:j:DRog.FA-qrmO>OC7~Ygo?9k%id?ۇ&|g(hQLO^E/k9ed$lP "\XÀ`  `˞9o!#J64pJhYJ $=ZR/dBk5턅jU -$ I[IPma4>OCAvd:G,=Iv#UĪ`2AR׻'rebɟCn6z5\d Xyo*Sw9h<} q/K_r5Yl8d_6s:Q+X8>c-7fpD) K~"DsASL҇aBE7#a[|d :Vc=4T#3\t *AAjV-/q65QYt`8:[ȲK^&,;k?jfI&lѲ"O؝VojG'Q<] ࡄJGTz&:}u c!6N–|kcAO,n]n_Ne4DېKw0[y;F@x}y\? 0]6DgiDl*kyѱYˆZIJ'd'O"5FfٖJk8Z.R=!ݧzBEsNl=9\F 7yLIug2 sX ly2}B" ҏ-O+J_KgLp`[ؗKNM`Q/@J:LMt0h-10&MkfQ׀ʛGm\VjF|U%z09 >]$vY,3_+eks}͜$+o3*9܋Fk΀τPXe1DCﰔZ<('i]p3s?jGG91/xP]$1ip"0D'_H6Ϲ8fޡ m/Dt<(Σ0X6ͲrXѲ@.dADBp?2/Jה_LCgހ͛ //$-M 8Yǩp&z䷆<ͤp*]VIs+i*4:Y';Ν9Z(⃳cϖp<_0pfc{E +WHg}UPC~/=l&wSUH]tJ(OB/ I?!bnxo߁QV^S|-١9A̿:Ц_@0Ņlrm_k,Bh<;O;S!PK )w:TSp/org/mockito/asm/Edge.classePMO1 "'/&g!`ݥbqiݮod_FMg}4 v:K?J-l.` A<G 2<7W!zֽ'{YV E5Y"t y$SJV0t%ؙgRIsNkhb"ZThdPk̔' gPUPK mN:)r, org/mockito/asm/Edge.javaVMo6d/I:V鄅-SAKtF]Qv.z-z"o޼y>Vdg(HM7T4^:5*PunJTjM0|3_U㴦>^^^'A$*U]iDER:k 2Yn*/\,泰YT@'T<1̶9d*,j33Y>SGE4,kѼ2B,7(2H zs@'2%ð봏Et+}_Q?xX%@9}gKְQ>HD 3*AۻN0piC0z``գEw7Q`ay,I d)Bd/_ u_^6d;u e̋dCKJv힩[${uo%_`XmȿY㣹J#̤Oymή.63$=ui)hDO(SIaUb"/ƺhMq/j 'S-J]r Z+3^а9u5Z(:N)'hn,ɔ&ҩh[JW?N<0QܻѦzI)rLp`x.V_V+,^mTd_yjVy91-5an,fRow)Q $T5[D.q^f)zEC+ի9Fc1 S~(H'!}$SYY]O1O7+v|叁w;ň\?O+_dK}EC+Nf(jN4aa,. qPN v:s1 l7QrH6awJsS-҆7K=5Q߯%mt}rMۺh-NaiE7jʶvAȦmqߍ\n6ɿ;0vT]e z|PK )w:'^!"org/mockito/asm/FieldVisitor.classe @E$~b;!&.a5B\8 ?7>Ptܙ{fm@t'fgf%>g9W[$[.BTڙRp#"LC/M!UG::cB0p"\mnPK},R\xV|j 6дBv;PK mN:b$ !org/mockito/asm/FieldVisitor.javaVMo6) Tg=,]+tB\}$#-1hP %َR#phr͛ᐷ777p~{i^EUhJ؈ob/`jeK hԮU|ը筅>'EWƊ1w+JDwy#@~@$H ?luUJbG+eۑCk4+%FA6%J*Tk+ %Pqzc_,jv' *5ܫ Yӗ[ێ9lSHy' pJ>c3>" ^=%~"g,If8e Yw.) *?8K=X䫌5UB|>sǑ '&=\>YbM&澾`t)!?HjEHmFc%9_v/qrm7JiԎ< Ob\WkM7ۍ9MŘ-^'hxivyrπ$^hB>FR?*(llywrgzts`vSqVW)V](k+)1O?ǍRJ?]}ZJ#^oCCﯭ*/Txԍ?nYׯjC6N2zM{oHVf-UYx((./PK )w:' !org/mockito/asm/FieldWriter.classWkpT~dd"Q6DUJ4B!$)BN6@rwOAxo2e?&A h[q2x@mc}~ٿ^lne$e3?Ҳζzrk"P ;1et[62nAպ< SCKĆBȱ :lSd$>lE 3yE0`3 c9cLǡ9Ӭvkv)۞ptat%2Qג@V؎Rˆ(`Iԭll6p&10w.9zv.:Y0 X*g{s D `N\*kT8֞)6N)m T~` i-1Pa  Zj:y7Z# VSm3p!~(>.R3Dˤ΀r#Pk{%ۚLP.²pI_{Кq#YbX+Mu;9̂t%fv9֋῍x?V-?引㥽"l4Pӥ?"ց-x%i0SrxXZQXBӓ)T3Q0% JMо:vr;}^?RϮrc\6`ˤ p8sq,D1d(N^fYӵ-2=':=bu{5*u1kRcL;c3UX\WIӲŘL> +9GQV=( a#B̓zCH彊3+qB+u,̢=;`:g3pMgv#VΧ:p>;b*x!5r 5-0* r4Cs|)$LE$5HF]j /Tr N`!^LMd$)4O%J44>J>ٚ8j>+pVLb:sKtRIZJcX@cq\"X5fc5ӸrJ9Jiec^4`?עa%~5Xd3`;B/Jlo9cK1)lsۄjnƦCMH$+r%Z-8Mm]6О2b@'/ ^MҔ׵bG&u~=)@ǬJ [ϘP~τhutCZu#z =U >]5>9Xd)[ |ciBִ) ~ uED)\׷SJx;8d~ {=N?rqU4VWY9t(+'?c7q[" ?^xvyȼ*MT, j]q0J=h-bu1֦^n[WbWIY8M{=x|5'Zxj=1D+}/1|&;ľ|Giz؝\Y^ }a_c_A7o͕}.{؊ }acœ ֧v| ӗWxڷ'Mwt\ŕR*J@UKUDW&S;l=:PK mN:[% # org/mockito/asm/FieldWriter.javaXmoF arN^&9hԑ]*(qe"r% of%ŵ~vgygfu|tt^ >XrCf~*?ʇɽ`8`0#Xqğu|zO흀δ ONN⟟SYGS i",YOraOE'KY xiLF&O,X2BI;_@ayt 8 8-J% -3߰.x´%Lh.xESY$ >Q,P" ᔚuP4%2R~TY Kn ,Ѽg9TOs ?߻cܖ i~o\uDc,B0*z/쇻8 X."CA(8a(УX(A`…s=KZ|dx&֔YA`SJ5\) JH[I tϼk1G}e=q .p\ЬZc=^i.|Nj uv MD fy${ ` KC1b34?jn3ӳH*`93]G.LWj1+ІÆe8BS64ӡ1t<+t $9;2t^ Isnzʶ\cDh9!&}d}&3ܶ2\~]Z< N5)*g8x䙶ŭ(a4\>-6vn![QH\UEQ/ի q>4 K7h&k5. Juhz$uOn0g L2?-p,p;/-G勅?҉.⾟?|q^"98, xRɃ"[&UkFJF8F/'`$xOeDe̐NC@KS6q|2f|#3(!}I 2nj'P>t9ԱzZ!mZ="Jixn}ǧwĔ=D A*pU  *;aުRNꛅm:WG|kQ*|\c\-\m=1=ݴQ0xZ@a!?-K _P4-:0<62ٌN{ȒbSpI6xSZ#-SIH#;~ѽUTj> hMVdq87GmiG]:|:#,Q$^E1})SlЇM0rVxT@y yRh8GQԨpg)V{A%.ԌEa6gjRlW螼Q TqXzVM᳭eAژr1Ck'cVޭJݪ= )fJ`!^x6aDԚ>[UMAڄpr_9JІ;C#ݦLҚT(\r=aו,%RM)VU wGt މDrd3&VGۗEtSswUZ'%3ʞ}IxYrT7E9qw 6̏`1W@c% ?{=NqŨHd{LT#( dԞ%F R ۊ"bAl"ʥU.]DyIUfӲk dQ}:ç  w-Wp½0O[:00Fk1-6ŻA,ܻMpsaK! $]),5m7H~ڏf~%=H~L!TGe{p҃ECFӤ*A`sSXNSJ{}鿾c5g;n~:ܤ/Yp<+7nkae!WRes\~h2zœi͛Y MZS=$v*vSB#] GȦ~Nj =k{Pv4Mn֙hyT7ߩiu6tsNہUm8ȀGmÁ|=fh.fZMņj3}6n.VO eKуPK )w:Mqb+org/mockito/asm/Frame.class9 xTgwYHyM(АY$’,!lBT곊V%BjGBVjb{@osf̙393ỵ06lHeUɒHՐ`m 5ʐA`lH`PI: m xN,F8M˚=/0'*ܙ[;%( pr~aOP bFV\gϞe7>(wv%&z`bΪ%iza~a~q~VA*YsgeO\!801>(*$ŊY$/GN L+6RPRm>@< # $,DW<1Hԫ( ĸjy8T ܝ).Uf_T+jIY +K0pUEb-nWU3Z.+W#U쪺pAB{*H8^.; ;#Q,D15P F8@BdeuZ!^H4l3)" Gep݃B S`j;-ZY U0 *XS\YRU?\3)_;HF0IZ]WZ_f*CB׸bȔ\Im J64R9B7eJp ʬ&G& O=Oڙ5P蘥EjeA։PᤕT`̕Pdr 2#픆jKȾg~̀:E,4]V8a~ЊB\ v"F6[P2.| \p(c2 &+tv[V' E#AYW %6IX-U‘aD;=W)ȢVa~Ơ'NVMYb.ՄWj]p^eH[]02_`e $޲ .lcڅ.8Z~VE8q'/$&9 uÀݤnڻa.hS_K_R zEzdd5tM[B&br|Z*0oVvri38E4@XnaraڎH)[j[x Gq`IID`MYmRF)lVNz Eh=Q_ؓ;TUg(:YԹ G:6FB/`LЋd~mѹP^]QG/31hڐi)PJ*R[W]]U ,/,J)} MR? ?[ =KoJ[~]]lm9p ܽSty:'^~&?pC<\F+J~ ԃ!iNRAFGq#)G~#=jtwNʅ0d0 mtl(rp!?#)UjʔgfgȝF;(1_`( -7P S"\>.=l'4T.)t\.SYC&flM!cLI<;kNȣ_n9'QYl-/W<8DdNȝC&LINq?rެr,s8YoZL=):leR`Mv8O(( *jl$4"C(HB a8ǟ;9O <1Bw%[ &{ Dx<zү }Ի9zr}}# >1x*bp?i1x:1`‡C 'e/U&skU_fהz]Uty+8%h yea +I M'6H,pZ'm$bZ%K- .FmLѮ9ZP(KQOZ!m~ABLo8&J~kDT>jԎZGkbTFˌkS]IrNVi3(ZѽǒE[A|'kL-*1:%j8 My6ROeevYcWF~ C?,#f374/Ok뱴~Rh&3ZD47J!k:{"XBz*ٵ,lrZ3%S4&}du9@Vfe7˪.+/ 2n-jn#)G$ALuuPBn;-+븁hAH]Z)L[  _ fZh"p@[ jiZhkDm-ڍl6CnaWkT)+dK,j:^R6۵Ml Xm&EK[ (W&BEYQbwg.r&VS4r*6HTxJi&C{qSKvG02 k(E~۞vMFJ3i> KdI99Hu)۬6,|ЎSx\)UF'쨅Z'봅o@gM· M{2w`v YK`+i k'IiiaqM0k>Po&7B/">5]+>3-ʭōna:3u:gn4ۭSDK<_qoj5BհWTklE#_P1YA5%&d t !eeFiS߯\|&e#JoZ2(AaGT;RңE?BJ1A,4Kꗤگ iT;}h?QvkgF)X|8 p~co${n6j/'-$:7`(UK٩@ʟl'm1in}x L#mHtn:3f;N'euSNNt6ӜF%W(}55DgypdH=H^H> y_Au|\O ɵ҉18n":Wxb`> ŔgW~'[WTF4$* ;*ϜSǖ?Qy;TkBw*db1JěT+=?3?Rk=@e6J*dKzͦK˶-V*J.\=V9o\L$穐_,㰵98[79&T `M+o~3=j2[d z)OL?H%V{_+;IdSxXEk~Ax^T:A2ԦYS:)-K2ڦt^6~BQ׊:EU$KV/5񣱬:_s#~]&5|PRű[%j lMzLvhfY;Ӟ[[Sngl9`:tЏ-IkvvځcTn;J/5[[ۮxc6ÓiJ.Ӟ; 6_==ϐ&oo7ZkxLk0*0M<]Vg)$W^ȋ{LЇ.w_W9v9=9U @geZ󩌡+%PGG 7?VnO@j8~3ܤ,NMkoa8= |8Nko[) -g2$ 1N85%1LJl?D=2)>+s(]Q'sq fe>*!ha(&1'1!3)Ѣ䣩CfC^X>O#$>Oc >|.aW+ռ/sx Ae]W{y%| ;R <:~/ _ɟu˯'|ʿ 9_q.Lw$~/Lc&7HGoʼn'x%g]xo?|7:|n&~C{~ E:I|}!~?/秄?On Ŀ>˿&]S ߈b4NdE?#&b*L\X\,BKPK!VcV%6`';L;؍x&[<3$Lo`OW`/q {/1Epqh=]p8Ayzb}NGg =gSp>3q><=%XbCuHq~.*}Vqހu\?f\up~ZAoux!ެ[xihp]1}F,d/|bDp ոݸw7Oqilqр6|h_ako8G 1^q{|8G:>ǧ#qd೎Gr|YsX7҉EWyyy ;60f"X dd6g:܎ME&v *ǻ SuqX`6X6u목jv*/Osd87ZNk3qAottǽ$)];˧$[جctY#]ɸu5k;PK{ۉ)ymVE}/?CEp1RF )ZmV(G_6y Ά1!F큁6$YƎcEPVXlqf(VtZv[O컶b)(Ap-%.t^`']8j3H*O!6`h.u? :ރ.7'!߇!dG0?< S<i/` nfw +9IpxU #| tV `cu.":" ](a +YHbWD$ av_f[E %.b}/;&mNAHӸiq"tkxu҇|8, ,NfOW76BeE$s7nt'DRo&mxcFȴ{5C̤~Uvoa=װk$Wlc7Acuz[}P-ATlx@X= YpUI- ((|R?!HURE"S'TڞɁtxZ>>) dOQ#PK mN:K%org/mockito/asm/Frame.java=ksFSa[Q-۲6@)#H-v| "! 1Pn3<@=݄kz{Ӎ'}ݟa1gzUܰ_-ٙfgg7YpYYG,/8D0z& /2Y첃O>yt Ef ]rF, @`YnҳIF,7 @_N20`qB7Y O0˂%['U/مZatq qPJ`pe@<ۯQ,'iKr_aAOg"B0e+pJb,XeA@)%'x]nqFsPx LK Р,HByC2#l4;DpH~/gj$)0P) 4cx߰ 8Y-Uhqqbt](-|H@i|]Zmc:X0A%il:9>'[=4Yo|~7۟L3rlgc3BFg=S60d@0qF3?J 7:2Fz ]DLКCx9=xB8כ ;ONSYtiox}w̬?g8q<~7O s}vI7Co=$9I}ə\nƣis;Gf"!|?F4Ngl>볣%O^?}Ɇ) o>wA H| Gd2?y.L;. |<"A`{wo;(p6qP$Sbo&w ԙ/Qc!]1;y;pQ4u@*)u&yo=$_ jL=F0p:S@KɟYO9x)}?|o᳼훰0q_k,Xk.CSX+ 'k9aMdq$H:b`}ء"5h| rLFe1-4-7 Q*LC2(CB亰aq0XMٕcaZܬ>Rt ^>$7. KZBbIpƛP@d Hȝ{=E,qDeDa#>b.%. \D| 9aL N+@`lBAc/iA *Et4/Ap/$\)e)!RM"2 x-NL. h$C+q vJU,8Y*POݬ > @XN+:?] xi9LAq*\]\kqh@_!P\\KG9TD/cB14$~ĕ)4Yb`JClæZ# D'a 4)i1fC`BP% LUdK ir2D`S8avk :BO yԓf8)s.a/Gɣ Pb9fu%(/A s&1brB@bI,!R0LSL|^CqN|Z(\ "q E2XSF?@t~u>z^!KAi miXpGSh-! ?o0 PN;kF3'\\5PFC,Pi*@1h]?q-qGY3y#s |]˔Ra:%{7†-`,iwNݰO!;\XW)8\=_%{ mo.buQ\P}AGE5>hu#T9Gș]pa -Xj. DjwJ/8,ʵ'r Bz,[ :8 Eo0X-w&.w<ǭawkXj3 , W1hf0'((m풎V$AD ;~Y!sVE@O>c𴴙q Y:ެ[t"ZǺɧTP iV2 BU?K.$F\ 1c8VOZihU?)]O?σL$勓{܊!41e;YEfE :@4o2 _![CҠfO?K<~ \-O s._LL*EʵQg7?yv`\9!SKil `AWh^$r[QK%WG>[ Bx>| n׶j)"8=!# "F^ JBO5ms N!dK&L,bל/@߶ |}!z9iF%k*{YpOVpA}`4JttvYƉaHkN5:d^F-J_OQĐJ IZiE,: 0h̝$jA+Lg2Gb~Bںr΃s7iE4lU*]x<;#="ZrUvJ@/O=!gA$< ƙ< ᙖ|0Dp%Z*Q +BMl0;+i[u;L@nh^hь_h*#==RВ{ 9dsioeͩ^0i{'NGląq 26m.9ȳol w:߭$&g༅/+]0qQpM<=M0` =st?}󨄖أsU>np^-^F.ϰhԨfw9~fn`iniaipZƫ\ }w25A Ӳ0E>S(Z| *qK$oHO%NM#iiqYU fYnWiЂh?X, ~ׂߵw-] ~ǂ߱w,-|q8XDP@L]`|hnfo:2mx̍CS)m37юYaj6 `%x vFFFFFFFFkhpm486 GOnԖNsݼCϹж<ޱZ{{"aժ6mU򦏿j.jGus%ʢM XjV&Es /*,7F: #]Ho:?4 cmFzsՎF4rizo85ikMzF4U7~ymhh\u[?oBa4R͍C321u#9VBm|ܯF>HyaqC:KYx6HhJ\ϔh9]%DJ0-ށtiuޱ`U[VRo~\8{no0L#L#}7k|C5r5r5Vf^+/Ҽ1&@WSyg+laY]wެWS tzf ͨx6,͚T|22u4Sמ;PxG۞ Nʃl:sfdxKRs&w2kP /d6w$_qL/"ODtߡGMG֛͘bz_SGw%uvzЍN.uGGRd:S%H7/wjGX常GPҦUT_w7SxBg\;T_^'-$"TN%U]}γCLrZbTkp$:<@!wݼȂY\OGZwI"tpu+ *"d @$͓rêǤer*nhF}*Qw-ITg(w&`i 00g;w;uuvvwvJ(]1/֑aАƌByCSTsOg@HS40|7娟 p(A|m) U0£blIJ=b3K9)|-t0Y}eK/r:?K҇:K߬25gVtgRHeh۾j /1-XWt7Q|}}QDa7͟ThkA1'+?|Ҵk֨ Icūy?/4 հvx櫆Geƶâ4w5, y!Qɶh 󣴨Ek$]= %SD +0䜂Wf=ۅxQTQ8NDWb;)*xHx+$]疛aE,h7WURPL'L\g7]1md%x͋/qjn,w2?jl#Fx.4[X=I5`su._qu,*KpZ4Q61l N:$bҦ4HDh(|]܃kY˃axPs@㤀~rRu;C٢,Ğy :ߌDKEf#GvpNb~#U=PPt{|9e*/$NQ{ˏ0[\owqydgϵzt_Yr ]>V\8Zc3s4 IʨQDUYd#j 3 #] XxLQxLZ-@e~.0  F\e-ulRLe w%dS*-sQ 6p6/(5N)WzuP|:XKYrw2?ֈE*>쭿h_]G/Ԃ@jgW*+6M}~]71PNuy\7 BH ٓo~@\rvsشh{ʯ C<)5&S%F1s3sf2^amS)txCGu0C{o57?OsZE<\q_+V)ŵ_ŕm_Ѐfs@9xH+SeJM MȱrXT1[Y |ZF"{*[6M} +QahREɼ7O4j}yCMj92NǙPG5ƽ[,n3k)oVy(jy"9]QoR'bt~t* -/| (w@.sdMEIjە7~<?ts ]Q NL7D!kތ}`iw-gn1QΓ,T*#ytTgVE=#&\>mE-ԇת3Z{P!5ݴ'ua [}h":ݽVZP>hA L[`mk"OD-[7c8zƍ0əٞlD% Nw+4BQN6:w+\El8Tv i6~'+?:B54e`sGmHgRjd0=%2cWz?kT@L;E+Q2N2R0vҹ۲fx==t7Wg[:ZW?Aۭg :=U+ )_] x{]ݒtH\>8g) y4n WBstq`9ꨱvI) ml:{nni3S/S)e+Z].{GkFP՞}߈ŭОXNGFh22Wە;wq]eF7/U+3bjNr6~,Tc{H6g>v+dSEQE'Rj|m 9ms *jO:a=~PͷT߅zpe~;:Vs{;iC>{@RSF`@l#,ol?{k Lxa5n3{oOߘ-4LŢmTѬ0C - 3(Т0C 1l*L.OeyQA,X= ``zs.LJ95 ˵˵˵m +gW6bӆ6i93z k߉z\Őy!U>'v! B@jRC:F^ޚ_966܅䟧F1髞gI|MWx'( /E@4; /Ꜧ:N`siD ӠGu+$uό*]);#.*kg Vbτ_}+EG\)+%M8)Ӧu6z`[Y1jՌ^쪇MQz;vOkG9}Zq:2,A".jIZ)qgxxQT]!Jy^͝8*ȱ=aR5۰ 3կ5'-nJa> /]o5W`kҜDR[]3"o K>P>ZNMYArNYrvj_NQ OŬ #*~̒M |ɫTJ:xJUQ %:k$L&z_'?VK̇qZ>, 6Z9CwTgADwN P|Ae_,ڬ%BZqQW;UGUXz6b r9 ٙ ^RyJ.ɹ]"JhzSt62`xb%WSDѳK~q+.ƮJ?Jƶy~k :9T):j8f G?HdzEdқR]13"hpBGujX-(TDiM[gXQ^Ϛ%U‡-8ڕFA¯0O4\uwu )$ejl%4Fbѹ|5ֆj;(nm=s&-L~Ȟ"ЛfLG=Z粊^~bOoNYix6yh1[y[{67ВzNvG啺rg]Qr7 H׹YXFd%QSVUм$zyjn|xI$Ƌ/xpvNMV2?N d6jVD=xd*(Mo5AC5gY^VVuCnzwK1(rRzk`j؇JR)mU ~ =AEHFEqQe5f៼XbqTR H= \_x}4, ΢zy)Jhw 4'%3NX[GoJ9nU8DlRT2U98Ju$pzhЕ&D}|pf :\)P~7⇎Uσ(X)e۟j˥Fsn)&&1 εYfOY KħY:3.RF\aǸ$}й=[bO4'jr%JI}d&,k Q붠:Xg&Pf(b;cЛeMڔ4]57U_wS|hPK )w:6Korg/mockito/asm/Handler.classeNMK@}ۦjkyԃEJdHlE'?%ήAf{cQexQeVyI&哌K.SfCz tj+eU"S*ڤsp&Tg~bkHGM;䳺{qx4afj*'TeJdZҽkDi].R2 MJ} J FXú .>q17l®_$ȇ8WuPK mN:8 org/mockito/asm/Handler.javaUn6}˚@sa@[ e: K(%#- QI4$:1wHIfm_y9˫#:P,ߓ;od]l+ҟNzoUi*ElvWKMKN6t=FdNZz[л$a@N\@jV:իNU73Uvz\NϮW[ͮ{֭>{mot쬇iL7mhۙ;]aaoŗP]{PiJøF/z2딕pܹ!Ok.U#٧,ԍSk)|fA rv?!Te]Z+;CY t :-~_71fpa&U ,\HwB"cK'={ QLE"gt3`%@q*y`X p0pXO IβX:>:Yum0kweKT[SX׈Cp_;b۵ʚv0{Z;6wF9m8b I[ݖ8φE,ת~xa~[\{rpa3Bӽ~Hӏxi:b#Gkowu 7/oQ3{3|U`+[K[cj*pL#7r RD=jiDnKC?GPK )w:(K\worg/mockito/asm/Item.classTKlU=vLmB\'Ƥ4_[ MӀI+ZEPę&:'  @RXtQ"A. ~B$ ` dp{/c'}97W>6蔧N:Y2͹lBc|TČUp ]MviҚ9{K.fQ XtJSRtelkݲ]{i2ߙ$@ɚw{6`ct2iB"c{3!")ka-*@Ү35m6``khS ڕ@z"EUDbSLa4=bE{#EǤfcsxnE nwEF5M n0)ui@G n S9aAsqs0JjW<:g8UFqkqLn#9 U 睂Y7˶ɥ;o -\`EmM"_ZK٦e:n=yv$2")>+Gd[=!DTCR $^_!<(Įy[E/X1*,U$XU2YEetfq\Xː'Ye#$:INQ˞BO#gƳ^>}xz]Z32"}*'n9FՓi+UyMfY Wɴp7@e0MK[RfΒML3<9M2vI0S7USiߡ_nљf:dߒq{醩zT؋;Vz>ELuJ% JD3<#^ޘH%.F[kP!h%PWnt"ëobwFBjrƯ_jd=9 |N|E{-,|c'#OKwfL{i+~|;N9}S7mc7Fs. _$C YdI\=:BGF$VEp|nx [&$ jöO_oxEI?W(kPK mN:T; W"org/mockito/asm/Item.javaYms6Lo&s:9?&݄(72#ԡEƄ$|d'wDPR8}ѻw^"^| 1ydW"8MI'dKE?b 09X"'"ؓ(>kcw,??i F"̜ hI &YȒ!ǹ%\߮YJ2s"ŪI1E&䉫{" X)-& _Vx@ₑVd\)B<}Ai*x~G"O82I-3>?7D,+ L+@`*uQn|+qDHK l$\dmZp"y uU#[T !JT"*|wn@P@)V8 o(mxH<5#p>{&`@C]•4;hY2'H'aNP 0A0X/Hz°(P^AX`&ܤ,2sПFWNx OtN ld_<"l!q #^I$t^_n? rFA 8^Dp8';B)F9M@\:ADypF8x w2-d~rlaf65-k$9S|p] n + ΁Ĺp̃@OÈF%g?؇nP79`O!E ^2w'pf`~p:w=xޫ,! q&sԨe/ܳ=s>J{XHDW=G@; v0SL>QT  4BZ0y"G_=ċf0\a,ׯ^:zTqȃ)$;ˆЅ6IsLEb.7ost}}4 iȲ>~Cӣ^IU7EB hx:IT7wբVP%v ynnjo&y|dmm&"Z۲Urnmni_P[I >'`m Hrd:CZZC{> %P8ԪLn] if,546"@Ft܈I)[KiɨV$ *HXֽ7,C#lDZ~II՝Q}AL:NDZ:ڥ..^'2"Td0 fMh:=x  LWNTTKM˜ 9tQ=I";5([,bDd[2)ႈ~Vx*3efvLQi/ZpK% t5BleMKf/k rsljf΢O3Ш<&FOypk(5 Œ:g){΋r YP%GJ5o4_37-si"㒤Z'Պ6rժ< D)*jl!֠ETS /LX?EYNu򌣃!)z2Vgg$V%@#p;l8yy:fQFY*2SFL4Rj6D-9b n{pH4sg7z̐ďh`5hnCƱ2+!EUБE;}UsĂ.+o1'>->wO>w^Fܹ:[G3."k Ȟq +p+Kz;mAsdrw|g&BD:=8)|MA()'U2򺣚٢cH07V|>U^>IUF1Aq1|E#(AHVO<S qOz9g8ɟ9q[<_ P ӊݒ pF5sF+/jeKxeTa0Jd p" eW?Wym6U4ʋ*%S`RxU茱кH,Ϣ Kcv31z,s~0L:J qRrNi&[Iw;LgovŪH(r [d8"CYWQlrcc&~I A4m: OQ*~Ʊs5"ӗd=<<[JBw*&pf7qu<^([KxN _ xA Ϗc8PhQ_Qz>&ViaUISW Io4MX%c쎀BcLbQņJ P;wBҿ$ ?B-C=6?g?]S/8"7CkqI|QJ&C/7!  |oWgK~HPK mN:C ISorg/mockito/asm/Label.javaG_svRf~LJ_矉EwtŝZq,d&/](&3)Va7qGi"Yi`,Z,sњ㣣o? mqTҊOshT2>C9TE lQ"T2PJ}/EMN`V,GSB-LVQ˙Xg]4/2 8,Mƕ<따S"M\&E$GC>IGSن%1D8d":h%38Gzl1 L5KLĒ‚ 4(Yʱ䆐}Bo;/#ڈ P8 [2g2S@[E"re0:t WიH'(2UpZ.PL^k1HBkPk9EU*aJ)e("`$F'p:8ӷ'7o˱\#ï08'|†ϛao4o' qϮnσ ?:òV1׽%{\tE0yp`Wt;7Û!\;,z{]vJ{C$@) W=>>1R澝#ͫgh߶.;A-,{}dvptv;]# 4='^ Qo:8덞w;q@09x OoG9ۛq0]~N l``#?Hm,R8:ޫUç&. 7]8Y@m.Duk~PQ6n.D?lN߅ EgNEy }١Y"'2&#c :U䭴?r A|: 7*r8Kj4Ot -7@/pq <ĀbEnL2p&y6~#"dca~#%b&;/c&'svoRuhH‹?rSy̑I"MB6 !O嚸DOt*K@3ZWLAX!zE0~Pb/Rp˕-$.?G֛ +AlhTx~nXSXCIZ=#z,TS%ާ)9rG(ز,|QVH%xmbnn~y`¯~ڌ$6-z} Sr%9y83dEX%΋U|NKcH#t=a2Qi #u\gm#AJMB,&HYHyf(?B!c!Gv!?|4n͢U@(xHclKb'iKaMRz uBR[߄ʦd6~io3btU:C u Ыk+r4z*|6+B!LOZj[#뎶6JAOar5Ic1?hXhet*Vkqw+Qa]92e-Cf{cU!r$Wa+~0TtM{y'o5r{d rgIcbw QB@=f] 5IXS$3W2/ZHZK }BKcr%DyQL;NQEo Ԃ#DMj Vv:DQ=m- 4[,lB(e#|:N׵UڵEpnĹ ŧ4ʕ'hpUaV>ewp:_H\ j\{7ڸGҁ %:n onǽ] ׽ѣ)@ >ASxAai$hם| +64s7 rY*y%x)bs)s8I/%l8=EF'\T L&iUV4姅2-ilMA3 f2r|F%\V $J)( wm#ʩf>eǣf%^3J#lQ2GV2tCtQ,7MgXbػâԺ觕eﳫij_֧[-;f ]:wqG3 vhǴ2W, >Xݨ;>}2<-tWܮ}R=A6`:dƀ V >BHua4XfR 8|(^'/Oj@S4 ~FPG:4+5?G {7juE&?}._ѡmꐝ΋(x}me6i}&mW2 $m"sGYaNc9w\9JvB8]7ݦ{eʺd!sQ3RBda)˧a[#t銌k d5(+P'fjªO6Ifk:?'(g27m)oX#Y“R|YVf*-}6ʐFZkTIJ(n a XBtPXWH^1Z2!^T9e{KWR1fNG؊ZIU8<:~n+/Jb)zBD-}.VLu)'`~-Pox!"\^`/ͳ?YWʟt& }-]q՗"wŸ:ƿ?k3:lOD p`z*[]?%{-۫+N,⅃5ڹ+}Z*87iTCS|?'/d"wJwtҷJk VP՜K&\Q)& s>u\!{m~80"M0#cAa ܸ߬_ׯXתZr}rC]Q^iV{Jz[7oJ˫)m`B)J0bB6ٶ&!ٴTA@AAAE3Qя(޻ll,ޛ{}99ߏn&33ۗ2 eTߨf͙L 1FڗTپZܪ! =l 2j^0mU=(t@7t `tM(TGJA5T[K> 3 Xsz۠ -r!0-M6E кz Q+p HH⸕э $lC1&#6hp`Lͨ) ѹ=gWV6F6 F[Ybsy zc=TuT&oaT'VG+z"TV+qvQGyrCF̌IF[*j_ZVҵHc>f:)\%:5_FʹQDAuBpUKaT 4|Pm2ʱGX!=#L=+Y =Nr0 ^Cd@ֽl,T=Ux.t҄i-)Li O_dCP1hN(%ҙHy @}r~.sπP۲fݙlS]ܝҪVeA{>*,n$K.v"2 ݒt&\8FKYrh >j1!kQ#=y~aq5 d"\mԍL\ѓmý T)K:Kch3~>mRBML$fג~XŕlccdjSLEJlL+k#:W8Bwg6][K( m*W{06p܎MypBL03n2q _ܰazz">*e1PO]0*Qt 8J6{ M2 rΆ06;{[<Jǹ&cGDc~$/f{tF2V:4Xp< X npWH*߅X^!Pa/ao#>Z=Y:ݓj,b{2ll Ib K@F.~)v|Ibk>2E[je}{z )A9Ydn2 ZxTb'Y+'oX2<\*-[]ڬ]wXS?m 1l f1m]ĬpvbƝ ه>r!~-n:;x`dwk؟:؟dw`?׭jn?p WBPK mN:$1"org/mockito/asm/MethodAdapter.javaXmo6A?9 }(Em%QaK$' 脍$HYRK,E8c3ϼp>?-W;92`E kKmv%Od!gT+,`XΟz2)X >~=~z+1)VюРjm͐BJ*cT(@J!DZ\Y +2kC`Æ\%OaVP>8e|$H)iC9/2?1zN\7l*%CVrK[u ~ YQDhpj1se"?SAGaii&6`mRT9/J"Q@a\ CM?GsaI#V2KAʤDa~Xh9S=Gx*AN,9paa"Z?&@Zg*@oxBPQܴn<2A\wN>/֛S `qz71FS\/s"$t{p[nA7_<D Ǟ $Nf˩_Abys/F8av pr?7{cʋ}wX8aM3'2\#^49ܝZcn‰c 6̵<;r[oF`D&x!m|/#bh#n.;A x1`AxO!ݸСDI|,v13'.tEEB/"!ϚsB`RQQMgz:^yub)0G KȇQ.'Q޿lfV<ߔ;s&'s<(ڞy阳t ܪ3N64߬tGDT"yvM䛌S#uc-7R)-#wƫ`VJDM {YFYh>  XU/eĪZejY잗>@R+tRHmk:7k.P4М=o?Y) |J+DNmm.ОPqfg>]PL2:KK_kLj40lSfUVNJQQG]jnp0bp\҈:[Iq< ρ+wla9xCiΈN9X79"3Q k>>{#kbgbЊdwzȹֈ ? (m3'l+0_uhF%nMMIj\\ DmAz ] zKkdv!p|kJ;e{ 2kxKm4H`Ixb}*)YV/WW!s>JU)f YH=_q<7Vʌx}VQ m6[!ۼ e;r-LCɋXi<>(4F zEsl;]geM %%2olYF?[R>UW|{+LNg-{fx ϟB>G)IE[ 2Q CG8u:XudSc\p.Z}t1w jPx(6ϕ-pkwϡkq,^D*_ߜ ٽ+?wf8pP;vm6OPK )w:aKP(#org/mockito/asm/MethodVisitor.classS]S@= ehHdOLΔEZ%Jr)]8]WJ Ġ,P-l-j06D%LQbV,+(" p?waj̵3VǟZ'3߅#_!K y k<-3L ǷL8gC9 "5|} w$tpƉe[sd7 115TLfӉ18$qhy۰yn: nP^8I{l8MZSs#e h}Ḿ7{h2xg:16N9Ff'o3;${v=b30o 8dYCl[s. >$ s0g&䝂Bj K |qs:! 0<>djKg˔^TL1ьbǒO$*4Aɽ!L&:( Aw: cO/iH}r`.!LK$E0 @M)f&=2&Hj޾˻$RI]&W7s*ǎGql`T)ȓt< {#h-sL+=Fޣ#!f9N )K]f_<Dr;qDX2xMcn_:K . h}lNc>Od&R&*-h!l9CYHZ_b~l]UfP06rאO1@œуH i5Iyj⾊50h x7z?P "P0c?قJiF.M+8"R 𞲢JO+?䰰8ܭ-U%TǖHu,yzx\4 b$ I.(iRv0^_'F_RedKzҶbd$\zrw4A/RX|Jʞ@AACpHK0 ẋw?RMByIPWTgSB7-ōQܔ Sm:2I:}뎌\ q w9Jȇ6wQm[4k4&+1 92 ux}tJto+\H~㔝ݞehlh(x/~̶)XRy܀zw.x e܂U錟`m1׽ }CKxK?(09\ux3˫:cWa^)+G`a!) w%U\Ai2?DЀk3w-,nYq#BuM#7PYYincl# ml$YWS)-]x`0OT3ʖ5<8~SCvuw 3p qv,G-Y677E;<} FiIMyyضj²)[@+{,MvZ@,S@6 ڪfεiqlK"eX1Ҧݫ:߃3Tw^0#/ToR<mE"C}ruύއ|,(,6> BTU> Ӳʒ)Jz@HjQj> 5c\}^B}ެ$Q,[&f,[v~}.[9RU-PZ_VɕWU;om,630'ޞd46N-TfZ\,Ee}˖wAFX{%L+ 3zT#C 1t+KTUW࠶sbqAQqEܹU-벊KUgЦxiaqyUIYiFYu)v*>3/(--B:˪ Gt;WziiYU (QrZ6#HVWTV$m BJJK,?zd*fU3f@=Łi0Ãvk&ΧrJp0)̀Ep @BC\VSJ%; ΡBMREiɓ f?uA3(K<jT=Ui JKJHT9} q`xT+-\L,Z*T {X!WW̫^Q^Z4V)N&΁ajd2'`6O&B@)F0p+R{1y29>U”$l-4 %h6VUKpUѭHrU삥'};șlT܂ꅨ={蹞w}ˠ88?S[ғ=@rҺ nE$g5!U YΊuAڱZ`g㚋Jy,?<1x\9uc= ˜1aQj)TՔ^,Zex^VBU]fi#P\]/Pl 10aU\rYyqEj<%d&9pa?H DCК)%`\ATch\Naƒ,gb`P^AAòUrۘE ֐+5)Xra9,/:$Zd TW)%pT6 #*69"@"-)%< 1]"D3f+^s6'< (YVa(iZI\Tȯf\r^L ЂC4VB'a24,f*VJHESZQ JVEVUS1E,r [F|YB>s.ea#A0*[ 9s$Kٮ@s/fKA¯ڍZyLʍѪîWʽ6h +VVA{:'7! oZJ 2KJݩm,USP KFqyKJ .ZJN vdў:vHsɧKNa[6Z JAͥPRV]QHTlAuy53Q_P2th/I(Xͭ 4dlH^,qqVr 5U4[!=aPNnȨaHa!1qXzo@rw[G7JMѤR')Mg(%2w;xf 9,ƪ8_սڬ>Y׫\z`ܤr0W-ZVr3 BSsUe <w?!#{Tt:hX ƈx|$hHn2:ByLq([<V*jo^#ÆϭAӔUp*Oݶ3̑r N1X9f6v,>KԟFWTY<`,Jm?#KJOQSN8\DvptH1nŭtE R+Z-EޓҺ% w6/8A:`B#U&W_?1K8,݀1 .1xsL/b@/SY

nk1mB(2=+XgVTSϙ6>21& 2ϝ0* PK -.&N0$$qRHq7[ƶ2 _ى'S9\.ϯ1w.a79-)%9l+vf۱GhB 2E*A.#x !a,gݖ˼jrpX ŐM7:((q~PnP}y+'۔~P~"S*&if!eLֿ '?5\OA ;PK -6ew*`8$NNWqͬ( >߄ek;ob`,bd(lWLQob!)( Q(eVYX(G!iYYu>Ok~mt1ʎ: PK L<7Forg/mockito/exceptions/misusing/MissingMethodInvocationException.classPMK@}STbV/ +E K5mIV$xI xp3o޼x{ypM©N^{e'C`N+L2J;ӓA2ס_*pX %_Gwb.-#S%@9*X<율D^$xMYbE5BΔ!]K1϶zHl I從\#yBWL?w4*FU|lW2G/vc%3OgEdZXnk9bf^SPK -<;iEorg/mockito/exceptions/misusing/MissingMethodInvocationException.java;o0 w Nڥѩ ve&DHQWyu(PD~wGpPX%13s 1I D<̼y3~{ye®;[hK>.P3LhױN{]N}?PCc_I7oĽ L+ᴤol$`P^oF#XyVYLdD jvq1# 5 JFDۑ^^f)[G, Z 9.yba )s^DPl*On[}${CߖʑXEKQAԘ[).FZ{F)(YE>gc_)E\>Wcjledis5-qi-٩PK -<&)ȟ4Borg/mockito/exceptions/misusing/MockitoConfigurationException.javaP;o1 O:hSiw_09'7s*K=%^'}5V^8yPޥmN>ʉX D#Z(O#l Av:D ZaɊPL*ڡ&Q7AQH4% ;=b|LQ[,߯.ְePܻ-g@Dnsc݁J{LT0i拢 ^i9C<|+'K"(>.%9P\8} fy7_PK L<1--7org/mockito/exceptions/misusing/NotAMockException.classPMK@}STb7o~a(+ JKm\jF[8M=ξ7||aY$:|PV9V2QiL=sVͅ1VݥAGIZFfJ3o.t|8{ xoS}B5ƈHC`Ejg"ιۢW,^y,TNd.oğ< 兊%vPa D_rF 770V?xE-Q4,v䡅ut8Z.xPK -Dc^)e+{#cm vhwR"l %KۗH9v<ӚA{Gcae("nrB,妺M"sKT˩H x^%tScħ`K֗۸R:TӉaė10P6 b蠜g|G-W%O୮j=Ok }<]L9oPK L< 5 @org/mockito/exceptions/misusing/NullInsteadOfMockException.classPMO1}Q4b7^pAM0{Y*V['qvp{3[ŜȄʙ@>) R6*T^lӫHeh~" sbxz,M@%*VCh3E/:r WcGB)KhoE(GZ1߁j[9)]3͹&dLab9LLd$JK{Il0*`3lq\gXo՗qs<Աƚ&~^5bf)}PK -$x_8t Z)ˎ C [K C,8k?/xbv:}ԥVgպqåtHGׇ٩0 PK L<4Aorg/mockito/exceptions/misusing/UnfinishedStubbingException.classPN0-mB_ 'B/$P֐(v G!6)HH.^! }MDGwjO>F*/Q&7*zFķy2tŪHrX l!yp+cdD08>?!E C#Bo{TtxU}V'hŒ*)C8hPO1b* ݟ !kY@9C=):b̈́.=RʓPf<䙊%P%6]~U802`·SY6GB-,sOsP1}PK -<7@org/mockito/exceptions/misusing/UnfinishedStubbingException.java}n@E[ CҤR%)ү׃=b_Y#LHTshs9^BHq|&#|N܎9$JtG'V0@Ȕ fÚ yP*js=!v7Άbv,Ő_Vt۽]Z60V`YylΙ|'R(t&Hֹ H[{%~gr#E{RDeg|f0KLۮ`x\,%P2CY.mǂc^mhuOBC#^cb͎PIlKuTE'Gp RyA8Kcا_*VW\oE {,5y^T?rЩPh92h Ah{1e^ɢxXkuOɻXIDt)Kɐ(O˱6g PK Lf}LLv"bi%s6N$.ιzFByCiS3G*XEwfXX4U gY8H *9gE<1ǚ&~^5bf)~PK -Q]B< 380'6 z]mY!J[KҖ 8Н| 6䕚f\W{ }.n  kXuUWbjzlXT _#t5L@D~'{L0Z-%ak- n1]#r9 neUW%PK -<;ba89,org/mockito/exceptions/misusing/package.htmlIOrHN-(+V((/S(HSO,W,V,.-NMkPK -<}//9#org/mockito/exceptions/package.htmlIOrHN-(SM-.NLO-QHed%%b=.}PK L ^G!f!5`33go?!H$t|X~tJ6Kf*ދF&)2;;2TfҰQ>VF/+|d4~j6-z+sAt%҉4>?%Ћ{6\cB?Q*$:sFp0 J:BBݽW0!IkE" [֝΄N*cww;irFSiZfz.)cX岅a_ō["􌰿Je(m w ',։MDZ>/,xTs*4K$8ӅyTb5=4W:#org/mockito/exceptions/verification/ArgumentsAreDifferent.javauN0 } C@ 4s;kiiB{wV8qcჩFXyx6zczK}ͺtlAw.-B6UkXA'RIsJ`䝨*2YFM+.u:;A>=hN[F#%9LЖ E`u۠2cSU!pm.B3 Y`tDa] }Cy]Š:/rIߠHZ(`0ir}QC{w6ʴs-!?[vl()_=OJ/PK L<MY= ?org/mockito/exceptions/verification/NeverWantedButInvoked.classPMO1}EX (pG↣(jA.(2ek.oy2Ggo3;6vg逞CzrJ'6XQ*Y ;8,e\/Skd1ڔ"ѣ\H:ӕd,n⪄މJ 4"e#gTuXQDE #P2"ywr,8eR9WlBIL7YX|BG:5!]=_4*`3H+/9gE <Ա&~VC33M PK -org/mockito/exceptions/verification/NeverWantedButInvoked.javauP=O1 +v C/^ΝP;[d?Ӊŵ~6{:ڽ6,s=Q7;H[a@S}hXw)<\Id2Uw`9eV:KinRzID)YXOxbE!se!sh7-c J%qer1(lGEcGܭW%f<;V-$\K2[/PK L<^(:>org/mockito/exceptions/verification/NoInteractionsWanted.classPMO1}kVE7o~$n1$5 ekuٚ'qv^a:潙~|hapMNus$ҩ Ҩ; :iDnDh +ë~j4|n6>[ <|sA1[d$M@%,NT\g0iQi`%@eB+K8cO"uJɎ#̘TI{d,}l: zf"ylW,sF)kt+s9n,Pir:J*'tj4N"a"dq|U9UA-rR6f6AhZ/4]T0=<;Tr]B{+XQ0tFQg{Teew,/B5֊HZg=DF"ΘTۂC6"8y ,U*Y2:3bW;ΨbIs}NxF_rEIM9Ŗqp7Мոö́ xZLKփUpViI5?d;ZE2NeqPK L<_3>Dorg/mockito/exceptions/verification/TooLittleActualInvocations.classPN06E/  C"깨* .-#۩-NH> Ia;;'>v$B@I`)|1ϫ`u(SbIe+f̹M&/Ѧ5cO3tH#M.u ޙL2\(&&>h0Tݣ  a-OCRh.*#Ru .P'?s%fy`h2b./Oufbq%*v2=xF )c5[ Vp)(Zh桃M(^ 51bPK -<,s;Corg/mockito/exceptions/verification/TooLittleActualInvocations.javauP;o@ Wx@t@PSiad;UAV< 8 5$LyxCdBuo,z[RJPZCxv=l)`ReNA`in0qj@#QYEwr]jHBgޒYUMxPa:(?A,4xCP+GJ>B@A_(Z85vy#1"ԡjy̴X½((zq PK L<?>Borg/mockito/exceptions/verification/TooManyActualInvocations.classPMO1}EXʗ(xG3&u.iD'qvכdәf@ }m`'t ^"V6X #eij*k=u'cn` 5܊`ZCkKcbp]G -RHXBo 캂X/t$S Wq0sFwcG5{a0Cu)`hPqBD*]ΥI",04'Rtg:5Jsx-MU BNQ9  4uyha4 1bfPK -<-+Aorg/mockito/exceptions/verification/TooManyActualInvocations.javauP;o@ Wx@t@PLM; ɾDѭx?I:)w ?j^bVn,jjg)P8"l7u lS4%DEUt2Kj${LKOzweFz?TE4 m`>4"5:rK0c5~RIyL`<8b f ߤV4_wx(zY[,z2+0 tX^;_PK L<'<Dorg/mockito/exceptions/verification/VerificationInOrderFailure.classPMO1}/Q4b!z@ek.oy2Gg&=Lg^ߛϯmlDLO@)`.WȪ`$7f*M_85 "+~f4|a6ev=~sAhFy)ws]8<;Qr]Bk)X$Q0rF%Q`\5ETE,t?By&$4%T{ΉčE2ӜCv"$Y ԇ*l"tjBW w6xMUQf#] |{GoM[ 5yh`5-33MPK -#%m QfkiIPK Lv;Cķ4i qeu&4|bǯ9'0BR!#8LavE`٩P)Kؖ. bZ֔7ԘA\DP6WC0.`F],v9I+S#YCe؅GFyPYĮyB@٦DXcJrq4gSj'l{3ra+`X]^w:u=\+2Q$|& DBQ*Dh4(!j^p|ڱP QbqqȁΣ ~pqB%ݔwv;N:ʸJ^+AnPK LO@"Cϴ+lԄ&szw.?}p |U-CJ ]dM:\kV^P!0XPbIjBcKj7ĞEÕ |oK7R"4C% ]eP\{^!y(G!CwEG.JWy5醄X] Cp>k" sc)[ ]L\:"ldP{-zgR5 :55q6x h^UjydgH2ůaM WM`T{1 *$p'r ֤a9Go؊!֒$x1[ҵ߉K)UVG21! e )0тH- hj{.i2܍ cѯDZ$})`oƆPsŏT< 1bA F}R@f,k?-HD^!)пbxdal z7`L>Bj#l9P`L:z tu X A5Yː!"rmyš JXJ.<F)|6XE.#2dtS_L*+R2OjJ3EE8@DvCd?rM;r%]n=FWNš'DT68K>GʔteLv D"6RSLiFgp:si%b.,4kpXGcy;Hqf\2=GVx#l e"I GD {%};PK -Ք ՗d2<6z"<:ur67{PIW#(u)w%B{$B@2\[ZYgT#8ʅiQXG$i%HV|6iS9 W)mkO:ː8h@+UJ:WK^ >0'QZ(o6}]<צfo`rӴ"2VObL%I{g?&]zZcgWVUɶ wj%Yy&K?o_G{ZOF!Hn j=Rm=#P,Gw=AyT@ BBe g™qz0xt8G9 S˪oIsKX<=7i&]̝/5#X#4c&c`Pe #?II6Q| PK -<ՐQV6org/mockito/exceptions/verification/junit/package.html̻ 0 E>S ` (Žܘ4CXVaa \QL/΄Dd5Ǯ}5:T;PK -<@'"#0org/mockito/exceptions/verification/package.htmlIO K-LLN,SH-*/*KPK L<;X9 &org/mockito/internal/InOrderImpl.classV[WWIP54U[ b56 J^d#8fKt-mY~gfaf9g}/'' vnAvRZX:y/;4uk>yusCQ7&-.%s+m+euKڦ} Qʩ@80C?ĪNJ1% QTK R־lx|x2^eWɌ,h4VaD[xc[m :K˽-Kmic6HKLldbF3`/kvSiÁ4}##ԞzԞc;X F^A !!pl9zHðI1N=d{9IۦDt*q3r4=Kk"vJgvs,&W &x8>@e6 ;$T/K:OhT6hע (n`,"Yxn$`)6iOY}j7[nDS|i9onYtD3DoL#^N}Q#'}~wğnk>X`b_`!:)#Oqpp}O[F?Gqb2z)S8S-R|Q,^ Nx_q5yj5\BxY^^pl$3F!V09)2rmw*x:_bOZ 2lVPX}fJ`*l^fK =Iț؏j1"JPԁ_jE3|MƖ:xC4o9 sLFQۯU~=uQinPK 0<1( %org/mockito/internal/InOrderImpl.javaVn0 +p]vHW` V @]IȒ'Ia>ʶRՇ@G)#8. 7l /.>\g[r2e崱~bCJFBb'HDT),U2-2TSf9"ۊ56hBFT8x`r$R[oȺI죟]ʙ3,h=^̷0\xәXL١@uS|to4,t^:k Jz஄+q~Zzo^Dj ֙ւJ栴%>b~TB+QI"RR֢[~J,PkGOS "G迩6Eg_$ 0Q.:]Vzܑ|0_c)pO|@`2n2j0&ʟQ7Ng H7c#C Sld(&rqִɢI.K`SGe#x:ǮZAn0qR6W;WE(H0~#j̀b2BV nPoncMLaS|+ n8x'Gġ1.laOn\tҕse4E{x'P^NG ZP8J|EoҴh P~Mn+6W{̽?1 Cm PK LGww2!}JDE6ak&x@5IR N]PhR5щ Z* `T[7 '1*f՘685504 Tz*hh[jPoLCif舀8ӯ#U)>fO%333:=_H?3ڱ9j<qʫ zGH̄Q'_@l@+bP y0=$Ziֶ%n讍wq'n`#65b3*IAIuV+C0vI͸Ubm"P+hL`\\JhCGA%Poު喭]U%( aJav /JmO} gAxTԓ:jp? |Ac lΏ1=KLjX95=l/1O֤mNٜFdjA ~`Jd5j6-5AC_ɐd-45-WUAdm]SCqJ6 [LK͞3El%Y\Yğd&$'F=13NJ^(ԇ0-@㪭MڼDp-rE2/VB#W']#x8΋0brѡ5ڪxHJ*V$˜\&b\`kpD0A)_GMpnZV 2Gw2N3O6K۠lG`ɛW #a]@MHqOZZʴ-\C-Y~OJ er+ WQ$APC7Y15eg,-6',s{ڼ #0gÆR~߳J縹f/fLߗ[l GMTr]=O6ꥌ2nIpG#DܯlM~p^@g-a% eߚwhfi8Y dwVVZUӥ_݈Mݑ,rs|@Ճ"A%0j6~ϴw>u᷇iz2:m*3n7pΕł9ޗB lIhz٬MgKV {ZMfcNolrZ噞\OQREM嘖撻_{Be+fipq(43VL;'5,ğOhB+ǚyf3/䉗[(Msp}Wqe|n;w-bw{"Iiѹ*[\PD1ḣ\>Kcݹ.Ӕ4~]vtr эB'3zZ$F{iʁev#FÎ}CaK˙0VESM90!ϩ\Onއ(3>W+A&pel ݗpz\u.aJ\sǿ$0^&u}{ߔO-AD l[Ŭ Uw2Ζu Vqّ\Ɨ崔}ʝ'7C-O%ėge~H^XŖk9aA^t"^$x 7 4u 抣ȵux ~˵o1K^,|nxAp^ £20@GhŽ!f(ǃ8 gF' eOug09GGvPK 0<]%org/mockito/internal/MockHandler.javaXMs6{aKCiS;uƍgqR3DB`P]@T~` xvxTqre!JFnTEXVyi6J(ZjYʁ1[[TZ?NT"vRD\HvxaFoT^2ˆ]4_jUVL&@?'-Iw]$$!4UL$d'^U">2siM#kկ6W%M* -r0 XdJ.q_Z 0%LW'g'ǧǯ^<Ǘ @"Lj ovowQcuǤ_jiPm?X l*x G{ GDXob).6cx[6 q1,VSn9CSV0:~ޣ[o,R8bGgjcwj ovhxLzM5Fؕ#ADTUXxgTo$H'L c ^D^$f5;3lёyg)TJ}:;4 ,~$@ӝt{}2XNb{1;`?-uR,+)a0W;#:MXO(M`OBG3فYPK 0<ՒJ.org/mockito/internal/MockHandlerInterface.javaQN0#:܊UBDjD0;kbKB;vBL{3>*LdiЛD !|\S*em*m J#8)`D'^ݸY{nf\lVZlSC&` 54LLx Rfc o0' =ᴀۊZ {xmQ׸P-絥/,IˎOh/ ,KonOj/VG_P hDa㧙;#* psY%u|Ã\uvS`;!2uY|vc/iM//r)?<gxNF~N[9N'ٗYQF+jr *I͈>5da3q Ŵ%ïre\R?mϹgyݷ5wV//;iD[?rfO>b7kt8=O0luC. Wbq0ۈXuncb EgzCFl0;ZgD.Cshd3⵰)o9VϝWŹ$.y%G+2{=ۖAqbq`<;Ãns4WLi(_T"?_;B~k|;HI5S3}(9|,“(b>$*NP@L^.ߥF\j2ϝ˹BZ3Rbq#(՞F:RW;U.|X:hQ^=Z\qT~! 9Z[O1eD+RѴ.r \OjN'EnqJg;($g>٪47CiYd]_:8qō>ߣxfITY1L&@ m,`XD؛doJ$+^wuw]f|F6o&\ [dze ?IC(n9X,5[n 1m>$Q2p`~Sg'GpYlD#7ˢg&3Tr6[ˌ ;]29_W$@6%dPX1 $+\/&SeM 㣜DdA!pe,E$GGlg\7$%K1d+.<'LHǥ9I9t=Tj>R)Y~=dY*TrWL ?erX|(a)Q`5&lCt6]G2V9g4  x‡VdVw9EEckCT-mL5ZZiOXU>Pdڅ! cTzQm($h8Xiz5m8kcآ.@`P _.I\ 5f>52F?pnj'5ݞ]D`/FZ+:v\IC GF)z|YWLEj|9fքSQbr%BJ߫LO'ævOe23TGEݜn].LZ;P`3[,Vv`*SPNoHb 8PҠ +yAE]oy ﳄ OX 9y5}o4~(?sL5*@uhnAgDo[́*BZscfu>kpx#IۿN+!qmJls,<=S{,-RqF`떞"2-;_t; SUwr ..CDDt  qjf~"> úaS?RdGX"_Y1/OE(^y?~0B.y{ҠɆN?AaQT _X#wA8\/1xɷ"UwPy>YL@:uԙՊ ]7SWUlntp qfс^=T2@PwE gύv}ݣM(tU"KvOBn=eC%id<=E6PK 0<( z lnD͞1~>ZJlopRCbb_әBv'u}0FV&y11G/sט,ۻPK L<18org/mockito/internal/configuration/ClassPathLoader.classT[OAK[KRZ@@-+JB JLvN+Q>g5I=}|sL3f׵3jUj@O+0|-̑š ` TؾP5tM .Od,d4Y^R1tKb!YKs 3j)g0;iL.Ðg*4BC$ f#=}L3$YGuM: Zn|yՏ>蟀5z2 ^5 "!Kđ4nS~s/v>"Η?cwa]viMC2`yL`, oUߤB$!JbYQ͖>xD"%Y!iOSfe،PK /<*}$7org/mockito/internal/configuration/ClassPathLoader.javaTM0_jR] K/elȒnÒ^Yv8u=TylǛ7Og `e orFFU%,4Fkf|F!q- ڐW82]ė 'eiAŒ@]5&TR(Y([tBd:uxز8  _e U/k)8p¢ݿ5|6ם!獂Xm .aRؼ31d4*@koiΫG7B,7fo2Kr=3tG{#ۣ3Ⱥ\kJ+NJUQ:sDy*toHsjBe[jRQ*ˠ(E Y?Wf2E/Ke*Neh5\e \pUiS%v{XɨCR{ ?I5>o9dЏ߻{RZ CD@r5Vi>K,4:{lk<ܴ3cPK LP=HXaOIJ!|Hy6Td_ ah+Ra;qZEa<!fw[f*ox䌞0JϕcSg0n#-ll]=*cg@S&eA]Ԡd^(D6- 'r,"$A$I߶ COLj(-*&Hp *4$Od32o~:s^{>&S RTRmLZ:k;ڸ̸LJah]r OX G%}&# ]p*'OaJA8-t6ڔe bO y%MScjY[jysl)5yZOgRMٜ0cZrQbMxF1=Xa|\u 5#2'zIMFҐV2vPEW7%t39@OT$ȴ+w 닋nY;WLsذ` 5[MlArO2`pN eWGtAYxM5h2uKՙ̩x3^Jfw\%T\|KInU}Lw#fB3:H!Rr?bx2كҪ鷂Zm*_irBS^)kg~ }*U4S7- -Ced:+jeXlJ,֋,xʭu1GfϪs5Y3B>,3!T-mZrtRe[A6TʜaM=)czn%mA0MK˟i/Fd-K V{ Y+&JIx`CswHk~N}gW@TwLc/|I,Ewf5A ]GCG;h˜'8qh'8w]W5y %.Ѧm|cKrA.\w(A^*k8wJ辊9u$a~u@c1NG+xV ~mG/;yugC|Si*d1}YaZy|"j*M9sXcӰ9QQ9<7Oݘ4?K T ^O,Azх0胪_W(QS[{ɧ5 ➃NMtE)u3WU5-5-b$R/X[ F_]zo%tH]KpG$ֿix;"譝Hp?4KXHe򢶺LTs4Nꍳϝ3sȏ!3>[/{ L];*ŴQ7_2`u B،4᨞ sL5x7Ҁsj,!jgcs%vUl{[5O%TDv\?Bô8B{ȏ0.G9:ƿqzy=F_GdMO1?ɛWgpOs}Yͮ)\ot$]Snt5/(_GPK /T͸b%c2``*03 ~) 3<<RIYkK .Ny^)fÃ^Υ2T%y„'BS\q, W% sh';;[4\Sˍ=B"A\nL~G{=޵'R͵fex`s13 Tzcamx* Y( 35ԍ&Iltkw >xC\hDR6$fh+Ս6"VU"Oͫa"k<~C%UTEѐ666@P|AHإܺ,$.369nQv)#ARȩ)).hY85wS'Q?+H\D8"$Gf ƧEtn^(4%E);,XQ4P.h9jr ۀ'׊z0'3O% _ԮFѝ<r'/e֥T~:C&P=mUH­*qc.Bk /^)YVVf䒪k郰6hܘCYi3mK_"c[oMx; ̘"wITwDs:TŒLw«]af&7SihÔ躨׃$i .'Dc W#|rIj@n+rdSYs_E8_HykĐ'qWA]~/pg5=ңQ--n6HM,>QЦ=0pL=G!o ]4ATn;{G?37q:zz:Zd gn茪z3 ߃xDS1{V@M;Aqri4)I]&Ghw(8hTsk\6{ѪZ{q.R݌M|(#gEYPK L<[lI?org/mockito/internal/configuration/DefaultInjectionEngine.classWWhC`C"q1GE* vBS0 8N3H#FD#iN4MJ M"Jh= '~wfH1'?Hz{]`:3I'3afb9iLe6c6SjkXJ3b&dۏJKe;5R -%q3vV=Pi ! <*4 j *Y6,72Pfb}J@ȡHYZ[(MgLaPܸ(dvm0$OdXg:)ݤu] Ircx/s׏Ƕ+mVF:K\e:A\ˬKnR n-4/;c;44X"2Ѳi[H&]vAܒKfkjxUnj6q@ɋ񃟉$ 5X^3 ^][~??2\x3\K&C5ޔ3c-eetKrf#n}r(θH?ل~ʔx&=#7I~%hVdVxIg:F!F4<š =Jhݨ ٹ O ϝBC(=,f-snnLB?nt0|\5߿C .:Elz U@޵B>6?2ڽ{[iK,o6ܹѶ&nMao$%_xDOalE0q%w O@dzreh9r$m+{5UJr4ױvd^Q"ف&~7I "(zFQ'³Q^|хW'~⮢\k!%YzrW} CaOowm",av 9*^g"?V寢.wKtqOYXȓ4K x;Nq|_$}8/L/6qTi\bR _!^P)ZpͦTW(mAjIR7i "Y8>mrZEš<{ K&KmR=R 6knG:weӢ아Vagy9(=N{C>A=>9?+/A`nls1mZ7riPGػ <9ox6IoK߻UߟGO߱]'VKnxDm{޵Ȇ(=E?YOGd>ao[V#sX.?Bχ֖7Zo>^{Hh{|hR}ysy tٮgYϸA'fPK /<org/mockito/internal/configuration/DefaultInjectionEngine.javaWmo6dϓa؀:$-`%DlhR#ΐ#)JdY_=Bj:>;1rX6d#7#32)bHÚi(,7$@d)T" ̚jAnXF53=;-IH RƟ2Z]R0)fgglSJer"TI3YW2J;ɭ>=uOM &N?gt$eM໰<۫8[q}@hM>s #=S 0%(NVRk BHC a_fs O|/S x쀬ݾ,/!Ւ 2N["7:Jh+{B, =@s .AmVq:u>Q15Ӭ8]rvE 1 #"g܁ٕ#V(0DX :ޫ*|_ Eƭw)r)7J@ʶsİ"5O@.`\ƆoM-V%?mEG6^P)ۯB"2j[q[RJN-YFf\zՔE.bU/F2FU/gԮQys5IKC `%sl1_+m:ɛ?DM}(EZl1ߒNz]1!|`-\IlEfTw]-GW^сxwf IeXi6Hp/21 ?M,*ۋÆz%ۢl"[l&4-wmכvx ozl/6> B2nI!zz%"3hCAqa2)Ȱؠ8r$8GT- ~ڛ0 puH2Evyypu>=11[ǖy4aw$mV7b@ ;=mɔ,c}ۈ X{]k?iglw{|#w86Q+qgpbmA ݓ!>saQ4ROENKВrWG7b$Ͻ>}r#u=X{k-|WrȋìG_zFGFZ_PK L<\[r<org/mockito/internal/configuration/GlobalConfiguration.classUkOY~NeQnۂhʨKXbXFǙdTj%iMc|L8 6鹼}yo \ †,p:]_Зc v߾5l =ϥIaߩ=QΡMތ5|"NAec(7UJCgoי1&2a) e5t$._YK l[itp}%0c & `xJѢӥP:*.pըFleڏ^P`(0Zez3ƜYqL}7i8<%}&s덻}YrdfJ g5$!KlmC3b u[7Öΐh'",tA&3(Ɓ}6C~R28b\ *WQ aFZ{=y*N+n%on sS:;60-ƪk(s?-:Aw8Qmw O \G(;ɗStYA1-CאL "6'g)aKLسǿqE ̞-ɜFl`.ַ`V3O7z֮5 27ߠ# ׅ4PK /<;org/mockito/internal/configuration/GlobalConfiguration.javaUmo0)O$Z!kS_H6]٘56Mn )t RPwDpG#O`6W k匈KboVBatfX7g [3!Y,JBphr :7Зƣ{!hy EYɐ`S9x4u+eD{)~QJW oɹĔ5v\lo֕q,TF4;7:F#z46M1Ȓ}RÊz~)iM^!Zb6( ZE\m U$lY^0`0kLe,.Mzm|m?/qzH3 VQh,%Z\燳|6tx< ˆ5s)WԜ^2H8oH&U;=pŴ1 @J?֑bo6d.llRtÞ6M3zЭE]hҥL F2%̀p7aH!$ g_)e2,epqX&Юަv+G&8@zjJ][mI=.m 0:m8ݧ5j6Zִir;9Zh`ϻEneXkAqce\%:!w^l3JҟaPK L% `TQH䏛9O2?iR'c D^e*,lc"Mձ=Nk)D+̃ *߄T+D-kgFP|0r}F.- ,٠S`e$Ӻm)Խ*~lN#XX] :Zj94h&3\3zڏу-lVfqmhhԳPaGK`}dNߎOcG4<@(2;;1(wmX17IeĐ@ɎF63Zk۹aqMy#WQos~XgFV5j0HSٴ1O28ՌOmpK6b+XBVI fMKAbGH`Lr.Ы6Z%3 uăeP-f:WO HJ咺ݳ'R*y&$ & % &áR4=Rq0N;*ڟDzN`V)qf&aK@!/;Z*NI$Tq}U* "5:͈38+>"G[f@ZVOљ kN)''V#Ks,u;.0+ zY90j)f߬D̪nUB" dF @Ior;,tMk/܌1+دZB$<xEy;Gǒ e%\%|Ť]<~xV'7W5tc+Km%57d7qEn5Wsq=giUf%`U|5Gm ͜ʵIk%~4tk#~/kBV t) 6 #`>,qSF̬O.ۙ:-tNo6/$"P^ɤ!+׭$7?#X!LROmSxPW ;#qvgZf͖D$/~{]q#0z%\nоO$4e`䰆 -ojF>G’4Bcr]ʛX6g~(l>XE笫1`wtF˺Z5Wg aJI~5/^l#g%vHW7C!^-5o*b54%ƼM1_"E>W>PQn!Mh.vv`/J?]q4VP +){=kR)gOMF0Qr^s7b|Sna}qMAw4NQtr%ݎqgcd(ϳU1TuegR_T%n{)9DǸgR 3#*QrhwK+NNAa7.c[x^@s)Z/Ga6.: :y ss\"@=܈1Nh$ܢJ@*I=߁gsH1jx#x{J@2eޠm8u&D~aFtDXvTwA{O_i E\E\F`co45Eܐ"nnݻW<>@LlAA ?Uy‹uB0A'X&y kq]´U<دyj9@WP\Tu²ب9 ZsiZnvAz,=yr@=n>?TO?xV\?PK /& tuM9%,=6qg)=:(_` l^eH XP%ewc8f>'C>d{? 3]PMzXf>Sz +UмK4=P!N?GB*W-✎ rh>`LȐUh.1Jx%#o|D]>b̞#zc&[-4鍺p. jMo檄b ¸y!AIX8?8`Ho8877rp ji<`+O,T/fHLg-%* / ;2C@E/;9jHu;U`sOjveKM#%s:Ag L)y6Wokٟ:p8"?AiWt=~Țo'>[_C]o'a?PK L#y1 lQYMOs}0RNZ5а[`fk,zҗN pWggH {0Jf瓆29tB 8t[4ۓ<Ã)!4 p*$/Y9<Q_Wߕrvn1JqZ`,\)+\9hj+G>,2[$RGRUFq4ʮg '(OYIi-6 >\R8/0]XvHSf@RDAytr ,d:$ȹnM) ΧPE+i\T$.VJq56E剪a=-bT fM$>VdyϽdL @AX'+,bg_VKf[{gLY۸RƖeq \ /PakGHֹm6Nɚ|7W56yK u^ ~@xew[!nzNGkҜ[-XN嶆<|2Eh3\*a2ݙ՝-bm>sn)[43g6òl jAzv+dު0h=bNݺW,e$}qjH;yOk>8 ν.=1Vd8__smᨔs)UMT~ =؎׬mnњX;@N͉D__w=߷oRӵP٫k63k}cp)/3Rof<>]k`b"k&umɤS7pxfc.sJ ΙjxR y5<94p:uQKzUd#ӓp = |Ytz &Qg~mxd%n'w]ⷈDC|αQz.#X+ W'!#k~:o?^dMK\)2,iaUmZUF(oqj@&Q^z?Xhx c=G<|Ϙ`F~fu~r Fon{L[tS ;n=S1OњX_cDD'8VЙYEg,n3bZjӴ=]8įiRз8h!I=PK /ǀÀS@궁8]$G.-Y>%-A"w̓aAׯ:{NC326>lˆN⫐HKZhm/?r'%9LQc"A;, ?@鏄1kOչT'af[h8$ްYt#>gj :ϧEO*O<@%Lt'PMGk_mك"iQB&jk#-);ܙ,)1Wi^HeW[Gj[_rHN%{Én?oLP>4IW!Ź[RV/ q) R];8hf9LWJ;xF/}p´VXBJ:(L)L˶$<`pŗoC[G1M8> l BM[8X/5gi0W' JUYkz'Z @|IHG-jzuE{w&CE _UAڜ4=9If%mQjjkZKˉ>t]jeig[ֻ`wqBtt|1CKH PK /<#$/org/mockito/internal/configuration/package.htmlIOO,WHKL/-J,PK L<̝k+>org/mockito/internal/creation/AbstractMockitoMethodProxy.classRMO1}C[L Q _T"ғwf¿8Qq PUh73o"KUe&[i2]R8zҾf~8{|HTeU=׉#|7g'nӽBBϚɌLȕʻ@@5sHXʏ!B۩9Kũ0Hj)}I55l?]C( ta0F ǀ^޼rܚ0i^6:buCMT v! TL5vzFX8mt0ϲMs5UPA`\_Z\<1!}>)R?rG@GҐެwzyJ+2cЍMzg{Nϝ~|ba?R7G cBaHUMYX6gHwFH]aRTaGBgk ,u[ 2)V71g!G_F;E,ir"= etFYgJi<7k]h e/h v#)n(a=TKtrief0j-IZqSì^3}, 2'Q+/úގx{)61X2eӝPK .<2org/mockito/internal/creation/ClassNameFinder.javaOj0o38&K)P4le5dNr{%; ޻w {?~}DJlG.&z("vCz0,qg&w&F x "J.k1JuYWr2.ibxbZk!`g@'$RhR\)^wRXP])ECIE[r:b;ZUcRU+o3n*~PK L< d&4org/mockito/internal/creation/DelegatingMethod.classYOQ0,UPж,^@E!11kfpfJ|MeQyP?i¼v}rNC*OA\$R'E6}^{K>3r1?<ݨ?s}(\ Ro'PN<9%)!`J$jDmJg@B "wW|*TVMv PK .<ͻ3org/mockito/internal/creation/DelegatingMethod.javaOo1@r qNN2FT߽&Qćy7ov`G֪ 0-̜|t6.wy=4c ƒW %1 ܢ{}W-z s>5(P8V mˢ vr<t8]A bFrf'LەN֌M[-AnɐJzDla q5W:\~{l'Ąbxu 5IH(+\Ⱦ!H*=m噦>O%5#8LeibxO6ğOCwU k:5w{&9fmc$ppxoXwM4ҭ~[.iC<.PܝiOOe< 6FOPK L<ߩL@org/mockito/internal/creation/DelegatingMockitoMethodProxy.classQMK@}ۦ_iLĴhD)A=It5v+?%N=H)^f޼fgܱ oH4W2qy#I{\Rɇ bi0_"Ck3ǿÎ7?0bw;С-Q^_4fam3&BtЂd,G'\Ko^t#t΃-y(ǁ_PK L<A;org/mockito/internal/creation/MethodInterceptorFilter.classWWW=  h TBQP ec2: Z[X_=F73&A' '3/}/=n$#i=q]1Ij$aȒZdB6Sl'䌩#Jka5iN&'L bD2>(mELɆ"-iF 9iZ qȒb ?H]YU6">N1mNOXΎ Q cR:qvrht<6h-ۅh1tədx9l2`Du,QIB)1@1VW0PƽhNuQܫ ]"y[Q= *B&`+9A/ڽ؆| CR(}|t/? kha>08 E;|U-GX qyhI>ߴФdOIj;Pڤ%/"8#Cu[uU4 Ls^eh \*6!zqωx}L%;&eSCl⨭aS9 ^E ]"y1DJرuFt$yĊMq,SEN+SEe\k銣K]ElOH&İ1<%& $2Tr \Tx9h }hZȚrZ<볲f*£-ޣ9m5o[Uga.ww>@yOY l ?q3W;,rR⮸)T.RY+\ٖ_{C^d#+9!]˚fN)9`'ԸDfIlW4:;y> 8h 隯h ?5d7 k֓4zm v[uVZziy` m:BKjl&T[Jjj֭ Eӝۏ؍6!0:`MHh\FC4j{P3jWs}o(W1-cCg{}e\&}Vq'"5ydpI˟ RPw*U]tJ(qfp$ dɣYJ%"DiPRDA @28NEvWeiNU"nGt0pisқ; _-fo޲.'M[? e|@XiJ'k->&ݟfKo" Pyr3i*.%i_3Vi$-ôkPK .V4nFyQ$xg mNFw,F昡0-&}Gz`b/ hc+O`lHA;ߨep|pˡ?”]Y'h!Q\:4hٸ)Ufh Y .ƣJoml5V5'\X-kiDlWPͼ7qxQ.?VĦ5:DS˻ DB+Q á~akĸzv"'IUt+rq:5WCpk QH)h5loul ֞UEQKM+Xjo".QoZ%L$Uμ5r\ Z]OcZR>CZv fMgfQ#8n-9]pXɅ?/Q dh.St+RLJӨCr~ujGwj[PK L<D_ 4org/mockito/internal/creation/MockSettingsImpl.classUSU!\BJ- ֦K Bm)n]6qwoOǾ;#e37o~g7 !{];'1)9s?~~ٹf4T=5jk9#JMZضf[ɃUc?y*v zˑ+"MHbYT}[=L(P/YW1MC=`eڴm2Z&eFc%ˆ0˴B&CT-Bed4_sNUGtҊ!kwjFaA34{QA}dl;Km|rd,uPCE_0HE*gRU@N<ˊo|df 1"z).hP-{%]d#T䄵2ZA7T !6O\WЬY% !181O$7nYtdBh|h^*9E%Ny_ث%^zFyBFL^^XNDJFĿ'ISy)k #k&f#5mͰ)îU~<}|Z5+}겶{8 ࡜be˪">bHn$_DnJkjL}ܞ |UtܜR! a%ݧ͞7| $wk \߬3`:W0⮦ rv>}DmiDW u<[#ǜ=i~I5DZ~?)UcYшB\kp$2p/i-Cџ=2w7gSo \wc1v-o1s7/u_bzwc%Wh+ >տFcqwZdk,G ,HeTϮ`;̨ܹnڻspu紮p8+0`RF0VJ$ͬu~Wpr󝧊dxd<d6/:/Ѻa*cC+.30V),( GU5$ DUۨ ޝV(y*8GdFt.H-*:'i!s Gb{vx),\*,LΟ*l#x@ɞPK .ϥ9n-bmX ڀ\cQ {E岤޻SRUbV%{hNy1m #c Zry&Us˺tyX z{%#|J%[*mN2* ˶ziԶjMʿ?iՌ-Xx#`z/!/f{T6͋ePK L<6[*X6org/mockito/internal/creation/MockitoMethodProxy.classe1N1E% DHP"j:*m8!\-E(Xӌ?3_߻=j&fe(#2uw2㸐ק D8[VNZ=VK6Fxn8nw/]4"{^ЕGQͱp9LLlz'I'20)ivPK .<' s5org/mockito/internal/creation/MockitoMethodProxy.javaU1O0H7&r+LHD 18qP!;NhvSGvL 4d'k'!N {]dY{ȥ>k7vDB #O@E4OxvCB5l"j3h@l\]A0jqeQGb;V5.A{S;:QeYq=K{B#>ӀoSDO٢]z$9g9fWPK LL-nf[Ifw93ߙ>pk W46]멐!=Ǵ c'L[4 6VPY.7}Bc_z%nfyb>3 IC Ϩ ]~sϧlkvcMm&ÑL6MORcO3ֹo1Dj 9 Hcnr6Ž nCa,S+UERSF {ЬpgF"gh:D!2yy춢aa-JR؆ JpCH^pk$\Ȝͨњ/вdzc#:(ЄVttbTH!ߜ(:,yt4@="^S8$ 5cS2'[ztDž0qQG\fh+٫:"*WI\]у*J3sIgo?W+AhhCW*ZwwQqc*r_̛vI]R:W:2LR[U2kF8|Y^u$sK1B }hEmBKJ~>∲AvkUJ}E3=@: }6Ne㓑Qjb Dw:x#~ĥ2fa9^/fE(ͯh7PK .<[>`Aorg/mockito/internal/creation/SerializableMockitoMethodProxy.javaTn0}GT̅B+MSTItݳc.cGSM](NǨ'Gsq|v)\b!)dfFU'+WzH@܁lI{[H -8+0 (4.y4ej1WJ8kx J E S0:0kUf/ tDŽ*@ z^rKҴ On &üG4ތ|lR~QMm+B!{C* \YF<$M\;*lwkoUd 6ؚjCkBDs-`#=w=q2Z BVeZOv`Q`IC>VςPuV2zg)Hz 6J@oߟkr7^7$z9|Z@_cܤw8-<ǹdF'3{H϶%9L{$#G2l_ѥfbnOѓ Y,,joй(+Y ILc$3r1Jy"Ȣҏl WIJvc+Ǒ gn5$>oc՝2#|L/E*A 0NJlqoA7PK .<H~4org/mockito/internal/creation/cglib/CGLIBHacker.javaUO0~Ge)b@U[%(h:ؑt.NiOvswlou13"D JG4pic]&,F@ל%l„d#P -\ RpT fo{`ڤq^G"/d 2'y*Ũ%B+:E#WTK.(xe:1iyEe7)r$.v9r҇?)0`0 V)Xo%3㓃ÓG;:ewUh5dP鍦Oh=W~jW`~4{oV3jwXW{5^^SZY)SZAŎ)qz@#]E!o/@F]]ϐF` VZ_u*%6zJ)۫}5j * oNU>3pxǢ<5.3z TN0֩u^~MFL:9 ֽBڅFmy<ڗ۲( u3BبU*!|j77M"2TK#lQ]ےgrYDžTgPg׿0h큠B1ݞ2 䐴> JR][6!B/U7 [> p0)JaK<#ǥm]/_ɪ+ V` Ҩ`f 5 PK LjK[I".BKc6n`M~+%n'7y}{zՁGGJ|(3R{Jټs$dh|[=l~@ g;tO ݔ4Z_,lHM i0=(N8*{kԚ iSBkrmH]4dr  ͙@(:x4Azpq" $TCFƸ2U|Q}1-̓C:t!lcV,JK?/i.!q9#њ]T49PK .<ꀇ 0org/mockito/internal/creation/cglib/package.htmlIOsvtR(JI,IMQ(.)MKPK L< {=org/mockito/internal/creation/jmock/ClassImposterizer$1.classRkkA=q6jվ$},E$B!}@dt3f'bU?J JMЅ{ws_~: ckĩr&TIy +SF c$;ݞI>KUb w=U::0gEdfP7;#gx~%JE V5CZ; Pµ2r(3܉J^6(DҥR"j cYoeՑ5.0:$ၕm%8 ܿ7}[eL{%a2zn3lL9>app.MLy ڙ1zcz@{VO I2 [AeO3# Z*zmR큌bo SM^ےvT)ߩV$DlWC^;ZK>L _K`xBYHQ5m?=)ޠXUH+˚y 1aJewkQ~_`>aQ糥ϖl1Q;{-:*S?b~PK Lpc y*NϭŁpZ 7Jz3 #wvz򞑅ڌ^070?!+Ϫ?3ijq|z~C' .oj+v\ ^p*̀0j)%\uf Q*ϰle0PK L<I|(0corg/mockito/internal/creation/jmock/ClassImposterizer$ClassWithSuperclassToWorkAroundCglibBug.classPMK1}ںZŻ q0xItA(='6lnz_IG՛Lț7K?^bؔ/MPpZd ,7%6"2L-SGPSyzlbprp;س-'T~5sd|n]e/\hVpq\4ԣ (pY"ESjdw,ݦ` n@,=k#$m^,"!6A]3sr9R6❴hjin=AjKDXb`{>+tuUܲwf Qp)-kfG=,9YF&g)ɅR)-Xmb7/nO;G+@IʕNŞb5VY3J*-7R!h/"$\Ԝ`IKXEؠ- z>RAsGCBPHbi*+DCl5i Al,˪]W V0E^#@n+XزTaKu/QoVpIEH(8UZEY4[ՃkBprvP N^T\w`(2T" tù? vD`8XE=IV~˶o-*pX\?i`.8#sp Lq˷HO2$Uv/3Sa@psMBp/BI U9 Dh9FE3goRh ÃJI awֆM`$gW0hVG.?2E 8 oOk6 ;A:a*`Δ2x?cH^u*4zcYJ; ssKȰu|WY8Tsc  ?^s eTr+^6Vs(2g %άܘ c o`n1 s)<>-+刺[Bčv赮:Ѡ=~j Gn%uh܉ZN7_κ(jVou.{Ѡug'62ǤİX-Q!i 16 Y(5T-˚0l©15ŃʓiRРbb x j`2JwdŰϻ ﹁'}Ys{ts~]|Rk0&N+gbWfmruGp ڒ 0bB9bu׻@g .2(v k~5>s.{K*+XϻwTɽ;crq{3d欩l2Da%)Aϻ.ӿ F,XO'>P;eDsyE#ke鋼DT8e8B#(6UarhBO6t vmm2LDS[^eyV^CmBjsI64M-47)L?$'y Ô['BJLMżqm)qVXrrA7! RSMNF+pO L!78cR6+0V}XL#.F~^@8y&XF^S4MxA{QrrX̓bao5x}ǎڔ9yIE-~}I' nfa ku;NQ Eʰjdž ԔKqLG滍,0aigo5[F2$bEH1|||yPK L<# >org/mockito/internal/creation/jmock/SearchingClassLoader.classU[WWNFT0 0 PM Ū ! &3ɤ>_q!(-}go{3kFmӵsschi[5i-ViU[+NB }ʚU1:4 x.ھ@G0 2> N6:ӷ "hQC!fU`H5ǰ\c]Y6-÷TW25}+hÉJ ui0XY.z {[5,:`V8N > {GGdqҍ3 ,cib~ealT<Հи ,ҿ㴸8KP.dM@E?eGQU|(,WqCHX@qp[Е8(ʆE!!Jttd+f6*sGXPM4%3_w')f? \L 15"e e7~idOSx7V&I'iMG컧n˘ Qo^1Wݧ\5,w֜58H7ʫ=FPiLս+b>|yaӇi vэYl y[#b9\ݢ=L٢f^@Q9!M8cgi2XVϫQ@IT(R7Zb+>:Egh?˷?E)˹ Yu6h2X,O?ٶnb`vq @1Jm8O4z0qrڅnLPJD?xeZ$3)KSGa4dۿs2 `&&=<ˇRLR'7 S՗[Y|B-^ݯv7 OB[϶0 Ͽ XcH<Hso v&mAR#7BģD7xwx/ 2vG j%CEjwB|Lw( ч]yr'H3dAZp)2f]^ַ9}Rа̌;yf:yv?XnyZ?PK .< =org/mockito/internal/creation/jmock/SearchingClassLoader.javaVMo8^ٰl/ MvE mo=Xf"IM?HP]lp摋xSx{#LLA;4icz'-FW@+#=%ߔр!84 /p#*̇YG5w@Ц`UƤ"/K& r'b~i9Gq`-`l6 %~#[,b:M为@o}h-l'DTߗM #fS`܈TECw+ySa+s@Zxh\bLY;@ *7;tr]&˧5k{i酮6Ra|.ch; ƨ_٣ Tc6Ml|k2 :cuvq<~U@B"Vkvo>C<abk&ӕ(em.b.ͽuuphXGY1,[8ȲlHT {oVi"NXR%ѴmsԜQ;| g{H$!CeL t^CgKAN"wD9QI`DGDX_t7_zD:ep;85VElv@'[/(~W~PonDMB۶싮'uXa2A. ,iw>#/rP̒*K*v~AZcaP\B'V(Qq$b%m#MD[ZKFUDRb )b0F*?~\PrھQ$LNQqt!n>\?^˹ak7^5NA6+[q1 . :aZ>CKu{bf`2t:Eijiˆk^"#M_q'מU=+%r H*ǁ2s< bE vL3S.9^ vbM=<QBVq=?ʧo0uA [PK .pAxu{%rrSf{ExyL_;|~mY)c#F7,Ӯ<@yry\<Ӕӛ)7z]rjGG/nО\G'0NyGjGe)̎.\L=z^\M>OcґLECFiNxZ=ܓp*TbQUɵ!&KDbXf%%g[14m] ]3i79 YTM):'T*eVmZіbl)*ao%\+1h*nt 8V)LQ1`$̆Uէ)Nr0C#[VB$Լq+\0L ,L+5(BJekn;EG|6 Y+lc9*φQp'U*: %b@)Ζ3!-׺Phdh-JQa=Hpıa%X4ޖڛIu%\B-;+;kzu NY Eת`JV6}"LzUh C_U+#.J نͽ-K,W \,aer3zh:'ic-.MzۣI Mi&+}s[0m G12 >:01PK .ryݵ+l2;.um2_*wdvƉ z̤^n?RL"9F ~z7U,_&2-wj٫qө|"=jW,kn)-eb&ݧ~g׽@=:@h{$- -Wb71[n6v13nN1szg˲+n[rd}H.^m 2gPK .<~\-org/mockito/internal/debugging/Localized.javamn0w$7Bu@ۥSD]xc.c#cRU޽Ohr^ξy#lj/ǪHd+O-5q{뺱CrAHQY&"_<=[=K2efG'֩l0e**{بP w#u\}1{OQR1ByҔg2z[t2adXZcQNL(R'+5 (N|ld`1f:ZW>5t'NPK .<9,org/mockito/internal/debugging/Location.javan0Ea4/#Q .vdAQc5E CN[KIv, Iqp'ɖHC$bHxba'VޒkbrP ǂg|͕FL>GHl. )!1gAŊKKS& ,ôRy7 (-yllVk?I"R>. tiej%@h̬Vc;ZŸZa#8*Fk &p:N.oϯn>mr}q9ZC]rwNӇ{=zhH5jO&c۷;:1.{HmDA:6F8 T!9><>ֺzuP:cpn[UiPiOAN㴏}hmҿ&Gh*ȕ^#+]I+8@xXxS i=Ckg1<\{1̏+4J! HZ3Tk+7]=l?ZsP1 pL?B |oCgx* LGNR2+<~s*΄z>zA{P3TgxCY %DT)-eJ9 ҐjZV#0 3P em`=Fh ?weV'<.qcߤPKPK .DY! ~贯ڏ"Q mu&DX,ȸЙFWECNt3|F'GPCHѭFdKVδ-UWϳ퍉Q\sP :)pؽtzT5k7A(庅 ƅ*mwA?gu)sxY_䓸̴M)Z|>e޿`?8`񌕺bVz>=YLl:>t1LT 紫Z9SJle T-ieZ)6layC+_@S1[,3 \!ݔLja TFb* |4hB}PfVmEEd&PeF{,sybK茜/sW)a'MgsYE0C6_Pf¸Q:@8IXGSx]f# ul-h0EUdj\N=٬O&=')&Zg>6A|Vֶ\+OF{Gd,Ϲk)aJXأ%S.n]Ow!4 =']oiĽЮOhtM.!F< X!.7>sGګbT;|-Wcԫz' uU~3 xU4^ ~N= HU[t$ME~QQݰJG ("n ,q[ȡJcԵc #Wo"O}TylA,-~)̵\妳S m ۆNڎd,Rm_Qob'.=/C4S8%#Ⱥ7 ]y{`9"@Wsͻ^Q~Y΃p"qNE/+CkG\''r U)K:#|(PK .<B7org/mockito/internal/debugging/MockitoDebuggerImpl.javaTn0?lu z)7>zHz녒i1E ʭQKRSЄ˝ՈYU{͋ BOW\I3ĮϬ)AT50Z8uCj 5W'aawPBq1zfK#Mun*XR"s+alی֒> ?}= M캶 (iNy3oUҕR0`Z 3m@q`N;dHЏP0F,ˋB\kD `E|Eg7#U8IAӘ[2_訔k1.u-MA07јxϳOiev2fYTZ}="jtQإPK L<Q 3org/mockito/internal/debugging/WarningsFinder.classVkOU~{XP..BKr RZtVc2vO;̘bnd1 &sf˲Btv;^Omw]S962 )p--('/=B]k2m[r7:9sVI9AIW W׋灯lsQi:I)gݴ|:f*NSG5|%,J/(G"$Zq*(ڒhAN'R:~Q1C茎k>si j[fՕݢD߀5YK:j{2zRϻMu˕Kn(Ь]O'=X觓˭yUh~;It+ +vBuS용$߈@sokxV qV-I 2f]5L$0m4xY pD92 %=s^sk(=b@ On;2pJ&yp04'xs:uN^Dd'Mnj Xvy 7R@G5ryGlhGmCVXq;4|r5\[VTnK"uSVΖ'O 2QTll넖B2R1}CXLy[eɯOv+1bXWK!;D?Gw8:3v}l$6A "C6uq|AFߥ._B]:6Jc$={BBb/&B $ec-\OTW駉[&i =Iq_$N?1P^| +2QÐPK .Mƞd3vz8z3kJXEV% g %/TnWZf<-` .*L:tXzEW.vBZ>?밠Uѓ9tzݼl`>b[=tWRf~ 6咮X{XO4WsP ̣[n#ecv& jyS\B4|gNLه4^7cg8%u>Sp'-v\`PK L^1,::(鮭YJ^aچAsmZ o]:ER:ի<ӱF2tRVs _@mk^ns:b\v cXgny% e]*/%H^-QXhC?djl!vɫ:!P!SiZ6tiߕxBB2*~V5Xp}.pE$t-Q!qc"te :)22:ꄰ$ay=d0tOD.9a<"yp'6 '_Joje-0.;?]"i;aVw˞iؚd[?)~׾D2r|7o1: }%,+ZT*QVVy6(sG].V7YMX#;Fk)zlIĺ /u.c31"7=,*PT(D0,(p!Ye2/w294yL&OEjUZ2Õ-DAzoF( B&O:>[w(UXY n,ם42F폋ʋ;9E_ߝl$&r;gB1.hꠇ#5REL-VR'qPh(n͵'d#%2j.e#q2qv0$B&1 ύ-μPK .<r67+org/mockito/internal/debugging/package.htmlIO H,I-K-RH)(VSHIM*MOKWHKIMQ(I-.)kPK LF$A3q)Osj3/(aO!Hה&`qBm.yCHl)6\Y5J"D˓f)Cʵ]"$2D[?!a¯2e.fM̋ӾyF< -i>"W)Ob@+b/FGյGdi 0Ƒ( N<&587X,4PK .t9ˮݪ߂D j~(-Ő>̙̙9p+ֶgoгJ%u<7"ּ)N1֊/lD9n=⍰VgMi&bH<(}%^inV "V{@K,}H."=w]USjҪ/4Z\y6^\f '5bN*Gezp:Ȋq-8^Y82G? $َ +8gҤ.tkYnd6g^𽷺l`c)LqmG 7{t5 ؁D=¡+Ί  әˆG-0@82'4]=Յ'9p cǰu\Ô:=%zVF9 nXNƼS?,fu+V?ċ^Տ .1c1Іv^G qFknh&xͻe s}C} "!^bd'2cQ9_knKhi:/Lc7#{0`-OF&6ĉ`^8>dE$7PK .<P}MEorg/mockito/internal/exceptions/base/ConditionalStackTraceFilter.javamPKo0+7lf#SJ)^ifӇ`09g 05+`7`3y T޲96,[c++ezS!_!xցǏIq(EI,ˍh 8Fjvq$!XMMrŔ8۹ |Ӷ } CKM ΅ԏ>[Ttp EJq>))PA[ӀA?] |ϯW7|v;xuy_1G8]8Q5͊#ݲD\R5Xol>!} Q7HCp}ϦmvӞ%nӔ6l(K˪HifwT$Pp}O{ν^+p挆[[װ@zi\ ,Kc<0k Y,6:{槦aΜ1V'k@G\c\zi[̪-u٭QBS#Ix|E@P~.X $ 2ؑJ0o*!G̺|y-ڲ!`0-p̜ JfC|aSLr2؏idqPHOUgtj3?eHOO lb8@:i9,Fy4%csGЕF'h14q^ٙX=8xl 5b@Ɲ57䣳-;g=%:Mc\n˭lk*m6jݶ טom\<,~ Ħ1V#Ќ>i&KټIz c]".')Ib .c$+eH઀71|vT^=gAc4Q Ծ-uǻ%׶wk(1B˶Ɯj!QK }.)jEwy,>;j. 0dHޜEa܎=YA4aRn#.;JSݤRr\V!:vor٨JٿizmzѼ8ƣD ۸Z $F2*1 j v,𝉕؍=\m>Z x[?Z:ҷC8v1qr8 J$z%*ɪRCI>Y<GleSg4cp$R{YiJju?W?MDw/'8c~h$jeU%=NgU\Idqĭ:% MbcDt!4_;k匈N.BatfxBH"U-\-`.bTzWF~ч/7,cyҪYYKILd$|C/N=|W{;w>܊K!ih[ *EHd0KM 2R[,\Z]& jQZqE%6E^! ]{4ZѐfpO}gPkX01="k(Z)qJOU颕]`ȓb:*+<62oN4tqH;G?Uf῵N+S;ZSMD[;OƓ䵔Al9]ۆٸPK .NJrwy@룹|@|mA. q", 2B1W>V^+2~ dS¦U}*GjZu KPa*mjw032l=V-.pz]FD)V%pc\v7RU:<.= orO"$?p3ISxQyd ~;2]ZΆ>gl(@HQAw10Dwp..`.~A&j a/Ȧ  $2| +`T)֙T=\ǷL, ߡ>qyǭ([JRc}M$4pg$rU}3{woV_PK .4R Jԇi eSa/@b:Nn ubI> +CCG%)˭txe6v0M[hRntd ~nXS\N#wsYĂ>tP~abF}1H.Uhֻ3`t!jlAGV[ kDX\<|lIG| 0_c"1<Ͽf(}vu̸DFpdY0~^Bl:Aq  3WZ|S2K퓮Mff3H=|A]O8Nƈ ?f|eOY%ȉeU(u:_cg_=PK L<Rtɫ<org/mockito/internal/invocation/AllInvocationsFinder$1.classMA1=z%l,5! _P\j,|Ebee91ڄ89u4 Q{6S2bf^8zHa%b+92BWc:%LNhm+4V VZǃ:+fVdh$f*RJ5PK L<#rSorg/mockito/internal/invocation/AllInvocationsFinder$SequenceNumberComparator.classOPǿgN _R LQFS7nfu?Ҍ#HsϹ72;L Zo؞kn8N+lwOٚ8)>vZx "Է#t,e4E3i:k7}~peB0.sU U(~KwRUOXue:A >Cn~ev`up 9)0q€L}mpj3͉m|UBU<$Dp1mx.Ut&y]桄 {'w3%'x˘9E C..Ý56[9RƦ ߘ.8A28!& w.y!V S,_"*]0^aˋD}F&CXu4N wx?PK L砐^/|jDZ%iJXQjhGj/D{,tBʏ;);kө)OWvM*ۺcSnB{z2uˋXصtp^gՆz[#%T媡 C ePn 8 t xe>c'1 oAl wCS=L0VNδpv}K@W,pX aµDOdCPڸõ|"F>ǿz+~g3/bSM|In<_kkS xd-ih3:o,3yz]`漄<oNnb1PK /<=W^;9org/mockito/internal/invocation/AllInvocationsFinder.java}TM0+hR٦"UL7ƦIUU`|7f>K`kS8y`"{x6,aP{c]ݟʚh[_TjBhK|cO:';-b㹹&[ 4}:Wh7vhCzU w(} yy](5l?\[*Tvp-_tjeVm1\Q!zo^2*kRYtUۄHUY`"! 5nU򇠒1nq]O1+G@[3]@,߯`NC/AaN3A@HcpH!!t˅a8(5$9>NI&G]ԾND]sR1 8N;8IVg $R|',B])3qQ.:f}fԲ}&q_ )OcөUR8sMY~bVu L;f|{WåG:6W2`-LIxGa-QTzq;ސ /0޶fԛ7v-ɏsai';IkEM[z6Z By:Ǔt}%yo=,1z۔FWiľ<]^"=(FV\ Ӝl s{/4rݮ9EU2i+$ ʼ7Og(?skIDGL-=БLXҙGoBUFpT 009ʔg2v~3m6? |Q9;=ǘȌL`*][rI+D%.zcTQA2?Sw=yD`6qc$UvSτb1ҿWb=X,4+䣎븺K2PY}s,m/~\Ȫ[PWMD[菇[W*AOщ xl x0㗞f!y>_m_fEy·X!kT vC(Hc-}S꼂)3]C_c<<`O'U8PK /<-% 8org/mockito/internal/invocation/ArgumentsComparator.javaVKo8JmVJ{كEmXfL6e I[l>8 ק'foDr)nuNC3b66~] KnQHKdʂ^W$ R&?=`ƒ@2jkP|JVVӓQmqQtUaȺ]"3Um?R r4= 73> ·/~aw4J&/sŚ/Rϥ(h-\WO/c_#7Z*V2zt4^8^9^pe*;*܏bᲙd%η$ 9oFLﵦp[4axk! PsXBoeTVpv9Pi Jf?]-QZ:.{yoތgϞrgH?>4p^3C] ҋP!pk\8^v\ObYFr \=:X]xe&/ز@ 8\0~-M\|a+8(V8p͙~;Vo z6GCݔ9qs\y(g“z@lЪ?3hhi>m>TpGM2ݫmzR.w 稊+AL2nc61K /_B\ !fUPAû< 쏷 n#oUryr &=`ђ9Ysv`QITcu!:~(PčN:|I2:ZRvu(SL Ε4<Ԗ#?ʄR 2Y^W"/n̮6Z*7eNC{ ?z`8سlW4{Op#֜8p[)-L&l[mzw-tLN<>O}j2̞hgPK L<98Dorg/mockito/internal/invocation/CapturesArgumensFromInvocation.class1 @Dǘ7ZD`.Kؘ&JLT)>3 `>a.,Y7f%a++˕KB2q\l>q " 3YKK1ƿD"߰@rJ'&!@V"ĭCPK /<4Zí;p?"!_p/kͦB wWmۡƜ%i.h:@|}*}ZU-[N&Fp$j6VEZ-;~LjK8#[_XI06K g{ D) P0 +ZGdYNelmZWӰy kmDL`LT;K j ]mZD.MȯKZ =:mu^WEڻZ(J;۵lxRFP%PbZ]"^gLnF#&WD jXh JX׶0SkT%M\ "["p]q'hС[qI31;ݘLx$[nL)5GluTFmEѨZlp@vA/fopĢύJwѨnL$i^Ezk+[KRjzĤq I&d)EӬQ.EF;;sZlE_\GX+p& 5iЉz?,vcЀҰ/A(WkQ t HIkě&$mhL :qmjl wRBkEW̾MF|>vBN(2bE+#1t'|:C.}+I)r)m{s Ե;M*͑8^*(Lt7Ǎ)*3)@)ݔD 2zZ*R:TuZIAԅAt5uExY%Rb"\(KT2#n|c}Nv.ƥ_cEMS\QˎX)ƍ=9z/k(z#o MVv2ϳgnb|kQ,XԚFPTmWzi #YC)2)nrfiX@rz6J'%hz\'5:;yH ũ&Zm;%LhҳqJ9n,+@ԌJ&2 u>x5rH='-p\7qH8ӞsN,#Htİx)Oifa'S,U*G$un`ÉAِe#V bmOJ2;HM+Sd#S:y4}CŵG.21 "JlLȥ1a09V_ wk}BѕhmBkCd)SFQmܡ )9yJ/ V$u6pby:AIZ0 JEY9::Z[*9T?W]^ 'x^";[_JG1'wFJ=rd[^g`8cPEY6_f]LfFrI=:&|}w'\1%WM]Vm?a;sr, B,8|57z=ۿzoޕ ^|/7#gQ~F#(SE(1X؋jOY/{ XG+Kb)KtE*@BV4ZC#m%ݱ4!`{2Jt}!ǫ0(",&d]x=*aC]ڇ\pCrhIٷ&Ş~P6Xi/*Ǒ*V26V8i [ vB.[SiVzF dhS7#t0 9q: Qr(,ڷ@_k! ;EUO <&§. {C Y+E&>t3uїN̵Ux! C8KѕxFv>y7ghdVy!˄ٽAH=*!W}{ج>ze~,U*B&g,W%LG;i\hX_p2~^`>`.@92\n*5J'Cn>yc5$hkp-k>ܘ un(yX"%FMd[ d |W2_e6VsU H^#{M iǰ.;=`(zK% >^ACi>XU8cR Yd~po:yCN#"У\]_D;DAt(t?4*R"H#j)$zߧ^}և9k;9~GSnr=} t *ȉzwB^25ݘ+i1ls?wIKzcMR=|)%Ռ3loq\G)J)>T>s<;#-4}2#=ٗT3D1bG\9vŊL?NW@z5 xY~׋~acjQO5P \[j^_,gIi[QhfEb f5G@ڹ^9,P֢шyet>ĔDMkU jo13;:2[UPDJ<誚6$dw 0SRk~oo-=:M-Fj.љEH$8/_|zx>zїϏ.Šap_/ߜzq滛O?YZ7:z9*:rmyXXX[yx=f(\D3kJZ[tne@X_w]pypF$ZM#iӼeL6x)8NTq_=uqB"G"0&L>$Ue)"S#]K|"VkD~X2H)[=豚 )#SNTp8MO0Ǯ$[>ıLڹfjCf (=9x)k. >GRKڝ*+&0ݏII *JJxx Ig=ԖꖷSAѭ$nm$l PRӚaat6ܷް}FMG-0的^t}Q:5P$idEbo1׏MT^P::97R>O#ki63-_T- c+.ܰƜ ~C@#GȤ R+'bmq2\"6ozO{@!XN1 Z -͢L0Nq)U(wp:ۡ3B37AOM(lu4UCC2$P&.fMu6yiҠc__a^6a\9e\Яqǡ!ycn[<'ڳ0䉛x@\NU ܲ7)7B p ,&TE`?k r344C>$j2Rep@q;akD\Wb&Ϛu=^nn_[X%t t?~lӴ랡3e=f(۽a6Mm<)yCqZf>0"6 F*.$ .WI0ϝf@糈7̣$j4YA[ddfVJ=Hl\h?yABvM\qAߐv)4FGWn0Y\tJճz2D"'eСh9E Iyfo&`L.WUReT|+xSd5\3" W0l[M1,aw8ʓUmŦ&+ i^mKvf4%۸1xBi% PL\AWZXĂTZS]i+4m3C4n1T'k6C+0uq qN l6X؃]vGtj1ӚMS{kPfhņ uH7PK L<:I/ 6org/mockito/internal/invocation/InvocationMarker.classUMOQ= б|#CK[JUB"A;CSĥK$@pa\3L}Ӂh&}s޹w}￾|0ge紂 1lSseeuGX6> V@u}KW֍~;*aia 'E /?~gM jE$ jeJXd\M%G䵌(:ɿMdY;W*fqζ BeB$N0X6#2|7Tф Bhs]AAYӋ ƶJEюN6t]薸BMSK"U| P DBd7$qNt5RLtw 6sQG}ҋq)eKeq\ A1%0qB;5o.ګwKZgo=}Shňmk+& PpOr~c@Ȯ 20y>y|s֪W>/WK934Jf:NnBDԥw/%5[d1'm?H8ÿ4~?=Y$#ֺ3A %?1Pl} 57Ma|w~J}Y ~=&x2aq.H y!kdfn5org/mockito/internal/invocation/InvocationMarker.javaRj0<cz)4P@B/wEmɬd+?Z$}j.Lj)Z B+Kx*&b (Hspǜx1LBBI` VRn@G;TFf)%hYMc\;TZpZm?1/4YxvsXi1c{4v"I% #h/#9y[IvEyPȸ1z: \JcSRp`Pn-I{ܙ `xNH8o@_& ܌'MMMT cݘuvQ,y&ԍLt=m GZl[}qTU/a@モ]O+!Pcv`?m*\PK L<ԀeX+7org/mockito/internal/invocation/InvocationMatcher.classWiW~FH zj;11ca\;qAؒFؤK$M%]vӸE|~ȷϝ Bjw.]߫{] s:6WuˈK33j9#Zx1Jhf+K+Z ¯ Z,Lf/;cR:քQpY6kN6CebaTge\ZdL#],F݈5SWS 3Z,ZڞI'53˳s#O*PNU3yOAx wpPQQZSQ=kd-|FM'hsaѭ~OWTgǤ{dakl 5MAz v(ٓYkNŇ$;>G*hVY csKS{G)0=-hpQkF' /8PA"Z@ KBR?M"P#,:"C<֬1͚1 ٵejER91ud)J2Vjsk2m%K)ָf~"ئli2X"8AS0يCvt48EI{>}#Sc`fl\MkN"8! ~HϪjgÈ#r` ]"8I.P}@geZj~Nk3\:^۝1kN}Vb@Y%9IbQ-9vl t(] SDPz{x bIq=aʺ;I Ra%Gzׇ~Yט vIFp}T)ȱ<5ZN%Šgֲ$[ biO&OgTbHeNI*[߄<o(^ϥ49Υ2(E7 p0ƾ\~}WUy(q#g&!=a*jF~lC=`|h&GJ*E>W ~DH.w`G;踋%]|!oaA{%{%|X:r/\o#\nC k;zp&.H : g{};@ E<Is\i"sjs7Gb3wr_"8Fi A8~ayciϜEw/gsU;/pUM \9K\lD(eSi!s58O {ڋ ugBpRip< .^O+K%^Wuk:8W[wwqc`H`k]X@^M4o v`%㔻cak5nڙ8olgװB WY)ϻYo;Oܴ:5hԆ?—l;]^y9t(e즟c ɛa9wvp'e1ns PK /<5"6org/mockito/internal/invocation/InvocationMatcher.javaWKs6WsȐJ+ijQi&3HI  rI"$8 {:;)\^t!Cx6]wL גK-2-SPHJnsP {2(<2W 6 ,\Q&w$ d嵨q$^D3 !5|@ђJF2H{i$&nފ'(5ˢkV w4Y0/qsn4ߒM&lO4( CK!<UQE"?~q/?tl1pjN*}HhrWk4[jW8)h*إrC6ԫAX & Wª4S\狖msDԺÍS T׻!)+?rGM1r/c~Rڈ`?D\E9buKN;ΈBdp +uIUP3u硗f=~ [$6RVm"/$j6+WƩFcN CfoJ.*tRcCj+]7uXq0=,i}q 8:H^U U)qO h“EVvH1\hX㬁y%gCe]dCdb%,6#.&5ϟFLSYƸ8[AvS?m`TGȾ~Mw}Pt޿NI`Ft:g]exR5/.` 5#(ڟ;#˨=1/H3}!GaKۤ2T7Cgwua&y9k` "MOmЕ *|h&ܔAa*Yz\J 0b=T\Zuh8͐*xgXy ia!yU݃N:d$2k牆*1[QP,*C b3O0sPa^ uS>YVk3DThfF6m:sl_xtr.xG_M>U7}\W".k44dTi#tzG]1pάb3miM(Y:\"O4! J} oKHz1xQy _q=x#ҩO:(RBg,1R7?@Qzc_WHTZdYa@q GHnb)1R~ȎQ!$ adPK Lߗ}_c8X}˴-1+z͚}2r&бd*h1 ¹ j1dOu`F0|OLC!vŽ!D!;[E ǏT@z%̠fG/[eX`A[*}CHo2)#]h$p i!1|Q\I Q1LNU«h$V ֧iVC\xHX-Va$t?HE8?|7i #ZiTz-% VϔM w{&w':{.=8=U)i.yUA#VRj-&Ii"¤FYc,|&W&,iu aAxK;'23,#h?g]P1c> @u (BC(%5-x0F:=cPK L<"L7org/mockito/internal/invocation/InvocationsFinder.classXs= C;RK:M\;ʂ6 DIK~黅IKBu3tk:cSW{w%1am0^}9ǽ/o}t|67uδrq3kac.7[f.O¨M @Y}NgtƔD@[jf,r@[OU `ac5A{!6 @ =VŀDOR݅2ac%7W!r2.ôw+lE]J-s ncȞ3J 3uh1+nBV3:ץIIPN$d2`/L1{_hD_br͸9θ` yQz6!HM2rr*Urf YP5G:=8ݧ k*^Rߍ vJw Y:łeBCׂEwvV YzI$S%H R8! $1z*a&~B}ckǃgBJ&ޏd 8dU'2w>Cr"w.rG<] 1A >ů1a'HRO37RRҚYxtuQSR8E z dnD42ŎfF'*L<ݘ#Veܰfri 3x=rP5J#쑌Y(pdRr P niIAVq.`PGQ/grDaRϘ%N:>D͓zJS14Z/k);h_5|Q0\(ElHݛU[ p 2*cy WAηJW/Kzu1nX=gfZxsiCf 3zOgHьTqwzږNx4us:[<7ڣ#sܘg}6\f=]1WމzzP"O.T]w̻÷]~z@05:+槌QSZ"%$ FATm'߂odm7h5g; ~kec Br$^_jV[uVՍjx7vp6Y9{s$[@owy͎ͮuي_V9Sڜ1=ce1ػ79E;$@ݿ"dn21{ 8a .O6D3&aY*"Rǣ{ <@70|b#E H,"%p;epm+Xk/CM86"to`+;1ELG ܤHR TKrnF %6I)uww9a8aL;0h5׾JYIֿcDݟR]WdV1B4D%#.#pYhHA|.: sc`RqUU*DMPmA. !X?';&,Ii 92*z߄bu}5˯e_J飔K3Xsr+} P6VԏҒS)t) &IO8y|vv+Ѩu_zl{oKkc1x.+Wrµic)g\ ⼚q_`uLn%/UPĞtT k_זZk6Hu@OltbTQj,^enQmҫ˭Tqsle82SǀCT2s!UW+B^v,s#o9L5;LDmՌUUM*D06? ?EjkVa]pHyN+^6qw5uvQ(π} /u>m_FZW1(ZFPK /AFLn_JUXҿ }I6 {gn^a075޹77&x#C񍷅vio:n\BGp[iK߬a'[U}vnxﮂ6vTl뮷FWn_PK L|4(Q'ѷwkh ;j8 !{?]CaC6PK L<B3org/mockito/internal/invocation/MockitoMethod.classuMN0ےBl8@kB@A,`e1.]9nWc8b Pfy+m0lZ&[ΈMAYH`B0PLOQv(Щ[9*OH2,'}wڨO|֭`2:̊7O?HgW;Eq׿.Soia* b pݍ=0TVDT 54 EN:]?t E"ڔ(*3PK /SR^Wpk@Xfg5.C¸ʡMFngyfz5),:]T,J7CmDF8x sti,ASÞf.G@qWeB#7E~]3[Br)r.I9dȳOPK L<&T 8org/mockito/internal/invocation/SerializableMethod.classVSWm\-H*bт(Em`&w7\ŗӱ}o|3vlTgԿM0$Lg:/8G ,{)R ׊9W9bJab ai<L1%܌AQ{Y_c[]YX)7mհIШX=;SYDHAgA$)l/W\nL vEm#4iꎣ`OiV"$i=+$\;S0z*bQ-܂T%R"//j1nOK\+ ƌ++SgE|PF *`At):ǒpW`* wTĮpDA>>mdx}R_JLpN1 J񘊽h-TVo6@UuVWgɸ\-O)~ &t}H.x|pUm[1W VeL@9xytɛs} ŷh-,S;M-c{㔞 b1h@@.6_RC82#O^IdY?'l"'ALh<*7ȕ·zGJ#rSW;uEw i/EB f۸a\=F+|}$7p7Y"s'7-]Y܁ ul+8Z03xX 2čT xt+{Up bߊe%%B#2T`  Wū+xSc pf'#HUg-悴+ύLR,xUKe\Ɨ8+?ҽ-cS_)dI4sZOnkk\ #{2^n[IJBZ2aQg qoj{-S+~ 6w +N<@)EUJ?_38],NN,ߎO,;ܺȐVEݢخupR&^ہ2j=}>8f=ΘմvpZ@tiY| ^IU1›6C ?iKB}TL 5!ib-ᗰ{JF.2F?"lEpMAhfG]]Zd֤ćsY*AD=Ws oe]'3IҊ_e^t!2ko,!-wu?،ݠR$}**hnfmx>6F{  S#uh&?ɈF1i#8辗7HҘwU;KLg<1PK L9GWܯxaΨ7 ->g( NZi tƧ\5%($3+sIaoQcV ee3xeu|$h -MhzqFrGC[N 7oĮ&#Fa~uk4Mtc!t,HG7t3_>_ I9I%'pRHMCU#LG7Li("7kPh7*FO n׶s/BE2k״L1Fg[Mi--_Ynh al)@vv)}-v=*sx יHn2)V#yU)i iyph7k&6M2f|U.0-D[W*ېC;lt#uK>G PK /鼴G1>B܃õHn1<7F= 6CX o 9ZMLH(&q2'B/!<#\`CV2ɢoh= a5ɠs[dyiPK /<0mLorg/mockito/internal/invocation/realmethod/FilteredCGLIBProxyRealMethod.javaSo0GǤB.[G B{6$Цeڃqű#҉}fžǝ}yLq2*;'AjFQǽá(tPK LgK!0^#*K0J<^ڧ+hsVNc*뚂}SKw- -+~< 6 SKl],ꫮPK LheuQՎM'Կ[lP̾oOo_oWc1z1wgoxX.rEQ̲tU8PK /<%S#:org/mockito/internal/invocation/realmethod/RealMethod.java-=O@ HV(XP7\99E߹ڃʏO2Fq:=7y8I[L4oyʠQH=u625fe/qܬcu5h`MT\őyI26JXWK^1 n~V^OvuĻ2ҁV|@Kdy_TOeuPK /$q]<#08&Qy&tUae&"ejVNAڹ -qzx!J*Y7AXA5GXqz'O҉nT?ĈG(v[XZBeBپSaC`lup ?7\EQtXN/eZ]?D#o^#z.*X:ƩWO͉/_Oz!lO&uH:I\{*goy.Pb__ ~*l7yuQ Ϩ}5Oخ^fPGS l_Emkptwfg O|F7Uۗ_1>t< ["Mz'PK /<]CZ7org/mockito/internal/listeners/CollectCreatedMocks.javamPJ1vŋĂ xhs6w&K2[MֺB7\3XTܮVwuH@9˞ꁝo)@]eI O `5zw{~l_!6H2bKu F7A6VYihчbV̨ 3!3f9(b`2b%2co/U-#y !(AkQ'Q`8Xo~Rg)=b1$=3EMd|ǩ*iq`0N+# $rZku9wwwu~LZ ux%DPK L<$F|<org/mockito/internal/listeners/MockingProgressListener.class;o>CvFt̒|̼ԢԼԢb}_T^z@Q~zQjqTA +,Q?'1/]?)+5A=jFҢT̜T6F&`d`L PK /|E֚܃<#[%qjE U\85:6ANu_38˟ۚ5_PK L<)y6;org/mockito/internal/listeners/MockingStartedListener.class @g5 6ڤBKwpwp>%& Ͳ7+1:8Px# j*g։ee?eKBxQ(nj@hP@h]}[CPK /<\4:org/mockito/internal/listeners/MockingStartedListener.javaUOj0KNN(N襇^ 9bZgYȪb-^nJJ;;ڙvp * GdL8PZ`D tB!0Va x@`$ yd$f_QQh@vZm|六I)=EY s"zS{mYbaZk6: ncIjFs>z˱2I~iboΊDsp3YEl藣AճQppoePDi/Ð41GJ +[b?tCuPkTeȶe'ѓ%ȥl|rkKygY58>B%1 kJ)\eS$̗Ki@8Eu*U~C"Q⌭K>ʯv 5n{C),|zuu]]O Aʟ'F6"qr-O)<%pxIH5fMad`<Ɖ,[m5D& ?`lxso(1g; $?+82*1pp]o,,\9e# ޙ,Sb>Ox7d]-f'6GX; ;v,f{Msb=U\ǧ}uy]W$l3Y2>^?OƳy~PK /<4\&org/mockito/internal/matchers/And.javaRn0+>IAFb#U[4h.=SZf,2=+YZAyZr^_p_llKVV4YP֐IEjpYAe#T&EE ti6Z(X:( LVBcd. IjA:' W+ҹXdR{:mP=钴5 auO]Vh|~ʒm2*Øa:Jr@{7)/BrWnc}ltz/ $hNrk2 /xf6Ofd2ߎ'˸sc:hGl:ElE<(/?Z5z)&(M TTɼ+S@"_/M x/^r62CpYlr=jou i3[ m>:B%Ś#IN|N~Mn0i_k(Hiqu_ 򵇼Q`_.C PK L߰ Z]iy2td0 $v0^)Xab1ȇَđ:{QjezD6y,o`} ~:bgțZ9G-lL9rFϸÛ˿ޛrQ,#g#?Ðp ˽PK /^6W=Q .G6M+%E^x qZ!o;Ha5X,Ajb@iL;x0\<\z &&ܸ4nZ)I!7>$6hAw iLQ;Mz8l;rD>4#;㚘-zzzObB_YA[6K)~IP0 /JA: J{2`k o;xo,VXzlm>H~Y\X:=x9:_%t0-?f_gG&Fpg=MNjszv>gCHݥgw˳IPK L<-org/mockito/internal/matchers/AnyVararg.classQjA=I&dM6xy0/BH8_wlv;@O7"y(X3, U5:]`p7C;RSX$E#e3=ac8Qƽ(RSBr.KSq(B++ ! Լz@ku~ٛ08H&UƁ6="T{a-\QCPs#z\kyeY!4Crp"{CHh0wŅX*xoMp&Kte+XɧQt9v6!?\9SfLyuGӌFO lx`*gظ,N!5PK /d;&k7avRo4yڝs朳;LJqpy!Q]zc:@9+Z-w^hp,qIk3CP%1HA ĥLpYOI#sGlmÔE( 8#]V^K]2#hgo ,d L$+8:UF#6Thy qhʠڏ2r.d/ P2w_5XQ~9->C;p} g wz2Gdܓɔ>=/*hXz{F; dB "|.{%%&4Ij \.&6PK L%uy'j8!HAy=7H9ON55@ in.yJ 2Ә ` t-VզVYogUd4KKV!W[+c/xgtv`J$asnH`x>FXW30O%TW`L]D67cXEXgAM@vaůcsipٜ *7%\+ֵI<=9}wPsrKX( f|)KsZY^q&/5-,)`,/YNu$.vP:ǔ 5ɇFwsdc> Q;|\sKXxok9=Vz qw%p@tNCI:t' @uMW];$V[n6]u;{ug~Vkls}`,TPfBKJ4Qk.‘ F +d*]<+pI?A!9ƿ&yV#߾qsT{7Z՟prCBuCK61UҠ l+30g MRLo MScPK /d/DSPht[2D.H5ίFp<4x?L^/cmEo-X1#G9O*z+\NIg.5#m@„wh[BX[\CVpoo6X-񃖏!j y +'`v2).[ l ͜G2Mh6rUPvCdp&kS:Z g!p6ֶCX;֒ 3vLN 7&Jǚ:;RYM,Fu4Jqnv@9I7$W61vPkGc;і_[:t*Blۇ,}`xG}STUM߭9Fg+(#[4{"^U [r")h!OPS Ǟ})dct8g"4Kt݆eO#_h=k+?n @o'k=My!Էr+amo׽kVZ!jޟNĉEoɍguPK LBߡ A!8vbݷ/_XME?hmy$oKOAhk݌-jR!.ZQZj%huS_Ѩ*!aVb"ܕ-WTNL&b300E}a"nn{؍\Οcwa cJv]zD.CE)xP= ty*=j biBGM010mb11 3 mIr?(^gGTqU #i7̦@npImR謣(&Ea>ŭñ !Ib *y-QYƚ ;1X-$͔,o 4 GVI^ ơ2]BPqj3jƆt+3>TV%Ē+pfTmnZ$G,,38BuFO0Lkj@rYZ*/p_-isI|JuLB֖ws 5If=ؒ< gz#q? jnh s!?,dpynKۇn螧ii~Yߝ- 㯰LfٳZ}فp):)|q ;,ʐ!k*6Y#t%~T܈'cc?>HR/Oxr2:&_NώGtϛGXwP'DADCeKª%S)-5JJnFL1ULJ-1"Nyct)so; fQ3i3e Cnάc@ ۦ~rJ.h Q]B{fk 'a UHىl]:ћiM~f%Rj)3;  +dߍ޵6KVf6PK L<;K 0org/mockito/internal/matchers/CompareEqual.classRMoQ=hk[qm!`H,{/Û&SL\2q0&IQbp1s{9y~`=[{g)WK;jx@"vD8uZRXpI8eө֫T/ngބLU,9$? èV~O>QK~61 -)!90o3r11w ?sZb@#l5msnF6nױPG UFb1m!v$"LVčP,Ex#Ȁ(%bv/u>ƽ(PK /<܊Yge/org/mockito/internal/matchers/CompareEqual.javaMO@ !"Rp@VZwwbҁTnS>ȓ"wR4 Fb%A.ףfH{FZzp #Y6nRIм`Ol7]Q̒8ϊYY =EgYMYa u@w K^?8kRy aEz A=Y .fQ/atzztzׇGʹl3 Z~+t+'F~\h0 u['CO `t_naF~Q&Z00C,PK L&N[WLiUH-M5T[w(Nl~nFTg{qMak|M7x`-Hoe!BWhDr%C_ˏUG=ppW.ӋXE[1Aj)$t򘫫S`H A CC$;FfFGQ'ndUH7 ěH&ۡt\(x.c.n$dL%4KwďWPK /<;LF,org/mockito/internal/matchers/CompareTo.java}S0 +LO"uW\8̲M=0i%BM~~~~Ino >?2(]װd؃iG1Mhvh,`tE#S'%OCnU'5m= #Ŵ+ 3yqБ(hv[]ǁ3alрm√A[LIFj}u4}.@VLp0~LI%=5vj!uf79OatImD]Ym[[B֤I<Fۖ `\bt$W۲iE1:8M,8kJiƊ"֫QلM|! Kxon5 )3*x *廘/U6_7b[(/2: yдPK L<P,org/mockito/internal/matchers/Contains.classSRQ=7 Ax<|<D +"K\Ln%cY.J\? ˞ Xnnt>tߞ|0%ij*mS}IS ),JK%,[Y6 5Î1ܯd50CBe΍Rf4ˋe?JUX׵72?0*_Ҝ{anHfOV؃{lmic!n;uÐл\dӅC8_%1 D?!-fWoDvPeAtjb!4Å-nUKG$1NS_\: bH4ZZ] ~-V-aKemI7NMMoOu>)n__~2 .֖0 G +(BBfuiVKKFEf!{\Q\&uZ2)1$qp jKnAl6$J;isi݃aӮ +īZұOTMRŪ mQđ Lt}HI~bsV)"(bXm:O# 3aIS4Sf%̖~ SGdvpmD; Y|^8$rsbu+rzT~3>Lj\!NI, K;4ݩZfmdHt-Gwy9|`ʊ!NհCZ_A ܡ[+PGn F2iPbIC^J'3uE!ԍ /W Z:IYR4l[*BxӋKҴ5/q+"|~pWnKal & i!DFg#) ǻ[jZj1[|/;q_~cD\pXTGDGd2:3ُ4jnюiqppvfrR`;o (q(y_M6䷕S:Io?PK La@C2!u/PK /G\R{eǧ Xb14B0$ UWܲF^cWxɪܐҖ*jԕQ/ ^LJ[B C@aFj aPҼS0lR+Lg^)v)( ! Lg:[afp,c`eɆ2A" {Aqukݠa51>F1L`2ND&[>CmUf2LzjS-7-ک^s^lӈܡTm 1#b"@ShhizE VQpY`Hv#$w%º^C qp;0޽t4l-Nlָ$F:9PIQY+ʖE~l, -^hȎQ #Џ)6a:kr>FrHsoyː\A`(?H8 FgI1K>f2réW |ƐŐic% 3L!#?#V#g0Åz_$i\ $RD1A-'ۮPK /Mv5}:K_/PK LE_ܶrMq%f PK L<=r,org/mockito/internal/matchers/Equals$1.classTR@ )H)HEP+EUqShs.m0MjU|,gx|(dziif=OY`Y󬷶LەwcָܻwTVct[1_%5t1$B,_,goColC_ dNy3: !0܁yc]l{äΟo)} =jy*/I%X][2\һ1b/"d2yC:1Э` +r Q2'lUXR`ѣNO5l,| :*fD1Aez]eY#g)}JԆ!'1QbܲD@l?9+y)(2ۆB2C1f80OVw at-29a2DSQdON|*(e鵔1WI< ߦѤuLXc +uEq ۾3g$x҇UR0DSD޳}QT !obQ+ - ^÷ĦsxRȪGv]=t,W~@z'iv tV=3!.} m6i i0QnJh6B"(g$~ WW_1Dy:'ka߰룠#-vP[ SQgX6|4ڃRt6,PK L<< *org/mockito/internal/matchers/Equals.classUrE=-K4[1ve!D~^#i,3qfFa˖+Vdㅩ* 6I+>*vD%9Xsv v m$UVL]֒.J.ݫʚc:s4YV:sK9z)y;ԍT n˪n-٦`WYѷ ܪ`{ӽO5;Qhx@ lѲX0 l? a#|EWQ ʲU^0Tj}.{\F# }Smht7Թy !lJ}qc%PP,k|zz^dzGRZ6!kUuX3F^23zp6jWL̩%]&Q5 ʲ]WL!bu~~k8<80hAqY=F,wis<4 G`h}m4%@;s ~`g\o !C *.PR+`5~Ev5Qa",.ߑJe13[q=Q|-jHga9^Ò8b5qPiA״J2s> c .q{j7iʌp~ǭhgUA!'M |4H8D$$oN-57IM㸍`#`)g: ݱH| _~7x9M0S/T<޶ u Dh8(>%!o@:ͳDg>w+K<N&NiJ5-:b(&e(9:lI^[71v:yxٮQ:ݑ$B] qI /PK /<1/i)org/mockito/internal/matchers/Equals.javaUMS0W,>P |MN;RIK/d$9@K{זĔYzvjӁ8@wCwCq#!(>)T!WrX-O$E(4Y15QheGuqA6QLNgTnCe4BY^nKeBm ԱR[#Lg4bԑ|U"Ca6Lk/X 5-3q&a\G)+1( t:@+W| 6aIH?H2~uxxxvt|x;:\<'M*l  e=&5CylLL E\OJX:㣻r8Cp>aezp!Igr΢Z%w ?!stUH-.;{!AAI*$.eI.Q ZR G"&ܪc7gzVGą14׊ꎐ`XvPK /Iz&o,.$ҹl6}͑/Bt=߄к}Oa E/uv70ÙJCG|H kȼ}h&uaO ;V@5t ĩiąD +1MK s^sMu4nf }CH"|ӆpPK /<$?'org/mockito/internal/matchers/Find.javamQMo0 Wp>v7Y!)(V (`ԋ,3ZY$:6 EHwq9|vguCN=irˎ\}|pu-p A6405c{;FrxdB-ڑJh=VJR X$n  4WU$;FY|I٪ F'l1/8uע(Q|W@#|Ѷ|&Uj?l `0W "Ib8[C, \fsayZ^6bY/a3 %gtB`:~{c9(3(-k@*ꤙ.)ovLZ f٤/?B}/:T%\63t⹪ٷ޳w;0K4okcO{s.KJzyPK LIBi(MB] 5QXEYݦWno+G|Bb ֬žs?~p v^}L(H =]g̚-48Yo*_}TK0|u $6 Bݕ'q|#쑟Lx L#9_81s,,b @#rYsnǵX*,#;)Rɭ$@lm$c3Yd8Frv5Xl\@n3)\PK /<he1org/mockito/internal/matchers/GreaterOrEqual.java[K$A W|j}h{vTFAE/gcOuiSú}3# R;^=Ul(.&u}hm01d!GIfizZ:Z8Z%#\5CJ)EO:FTerl,iVQ2~Becubk-}퇅QJ&@ڤ=z丙)s q9䄏SŮ)Up1tHGukcx: Goi}4m)FO"7biYʱ\gzW{g;lɍ|Gr.vշEl{1Qw:_syΣuPSn8.!L;乁5=:PK L<\BT.org/mockito/internal/matchers/InstanceOf.classTKSA& ,, **[A rjf7;_ETi(ʣenL2=L__ CqZ1^L[p- cd{B BcX=>+%ntnGkn7T3mnzS ( {\fCRC$Ʀc?^g`Mʄ2ɰ]# yD7!wibɆ&C8ڌ 1M艢!"M!_e M ܔ֗lT1E-{ 291$S DqT *7yfі.N~*c Q-X#S=5|aJ"l%XY%" ״s*Q1&[0!aenƏ ҦR Z%2&e+2l1^u z>"}#cc'. ı\O${߆2 ''1g1MݪPwFE%;u \ޕcЀ4&tra'Й3mZ)[^ySq `Z4M i@+TП&6݉0]&{]^.aՋ&; :oȇ؎* _,Aj#sиP@l>VB;~V0uh[@B{F[n+RIFU5iみ.l,:&MnedqSITH3 HMpp 1K呦qCڕSX!YfQ?M$@7VszRq-9Ƭ?6G&5Jڍ6M$vB2hK1в@{4X[!q)@:FUeC~U,iYQ?Cecub?;ƍQJXsJMOaՀ)6d7j./Ĭ";84% bp1tH >|~q^_ԋl~VZg| [r#gONr{i\}۲m.*wyK9Tb;ڍL;BV‚.OISҮJJF0j>p(~J>둠  Ar0"5Gs=x_6N~otN(eUw}9]ױF S^p3QNaҳ=>dm&Tӛ$6 eӚR;qz\-Yf_PmmM _(QS Éa[nS8VNKl"S q5`8 =1LͬFw9ҺGGӥ'x gy8Vu7›8x;':Snf-"XSC)QDZM~Sb)(2JSF><4fb ^w0ͻ[:y:}U}I-19ZuVgBb8Y>5؊eJRop7. `B~G)>axTξF)e)q#ClLވ񇈏ḌҀ(!GBEtH9Bd?2J9)ڠKĿPK /<(*3org/mockito/internal/matchers/LocalizedMatcher.javaU[O0~pHJYMCBC1rԐؑɭ%F'>ss7h--xã3+(bYMa;[ Vf 2a![1y5%EPe|7{QsA2"#?)|!KOKvD*mX|)jb;k@KpWw!γ(2gV(Y@]O4%iIeG {}c=IR-a JktH i?[f/)ɅIAI,(+krß\&ЕjbXJF` >q7/pzv|~zy88=8 O\qz۰3Flez6㵢X,l6k㚜$>EyuCJTAP,0g2 2( i+#Pv&āHŗn~TX%Di4qQLtokei87+}KtK(pGyPk=z֪rъ[7%SKl=xQf< te ̛Itcv{k4+`lp S?v{Svf_{{MGSe%o8(*bթ*oJKAPޔְa|J&8e bJRۏYv 08*WAtH& ߩq*oؚ+$F-{r Klat'ۯ>a_Wg)A[;zA{uU] ^|bN$ޭMhPL VC(؍eWT=Ӱk%7a_Pk^| n[)qғN͵ѴWWPK L< J 3org/mockito/internal/matchers/MatchersPrinter.classVmSU~n4I@ymlQ7VkU@Ŧ)6Zq K4f67~u7 ~);ԯ'_Y 6L=<9߿*Y+n-]v9f6ebyuv0Y5 BԖiTMlY߲JRC`tZ"scy=@Z aD²b2|ْWrcrd=o;]=sjHj=ܫg\O$+ZRgKe9\Tge`nK]h苡_e"(BT9gHZqG Wto{g0C#; r6.M`ǴH\Zdqm9a("_[hAΫGdSeFAxO3MK?q<[oXVRhNu*e|G{Ozk-Jz@Jߕ QvZoi\ &P v~P$[gPK /$ lݬyC"u.2Sb}8!! 9 CHldX#H3紐JoV t0NKHb\hƿ}\|bMyzԚfsG(+^.uߡVnTorA8do#5E^fa#).G i1(D-h$ۼn_4\Pe̸-%tWjV醥ڞ9Nil;acݼHC =˖EhpjزUW4z*=z#ЗMQ+s zTEæX*X [㫺qst?iA Ks{)R4.jj>2ُHxYy"Ž ax);S>溏~Gr7$3Ù]DBo m!I$q|.AyF|2tOd_0l.<%+{B+ { wxj(s],\#QV3AysPK / qg*r}q{qQn/z۽Il#le7$b9b-0mb2ݴ?_ߡT - RQ/. B:-iI NN( f$ NPVxpͩ4])#`-m0OT: r#$b8C<"2@z [6M7fН{(Lը h+~2;\ֱs~ZR%CWPMaXqlOq[u5ThbS`< 7$[5ŞJht<%;J4F_{Н~EZܧ@M$-7/PK L<>+org/mockito/internal/matchers/NotNull.classR]OQ=S"P4QFSKLKM{q{l/&>`n$Xޙ;s̙;oBp5tWʸFzZ8P{ tMwq{C͓Zkr[{ijŔkފ#sRUB+(tXr]=NHzOB~o4%kJ+S'Lʝ"|R KqCUq=P^\µ W-· @b/pᴀ< ıPK /<}'org/mockito/internal/matchers/Null.javamMO0#NYa]P*]z`>qd-{mAwUCO|<;cV (S:@;+^\C>&`aM{d!mM% ]8>7;ذ&)OQ?cCBwT6X4y[ T;SRw ZN_Sԁ#4}GVH(W5h1mo ![GWDZ q sKQ$#8@p5\BqVgXΗoM9a&_(&uZ=EYw &7CMas´MjZH`?pw\C=nfs,iջhqzSPK Lh3*dmKRA] l~AV;H ݕJW lFKWJh8։l댫}˥EQ~]T֣x][n]wLU jrڒF:MTȼ&0ja] /; !X0[gU JKzMwej6&f0i@`"_cNb:)ۘ!,{&厃38[8 H= t8x6N,J(eR=&AidteY"TF7Ԛ/0`1mIb~O]x16עT_ekV 8,>NX6UI:0].4cv% .^HϬVW 'M7?nȺVʽU _'6G>w,nwV-p=5'}u>WlgYsd|~gq/$PK /<)%org/mockito/internal/matchers/Or.javaRM0W8%KAM[^g,넰$ dy<7W[vTlbdt>AZiI0% 0̬(M*{B RE7A|SW76w8iw/rȵ3t]GHڛr۹pmވuw-dUXшGţ$p'Rq$ h%EF,Lپ"Ҿ޵_{%T|?PK L<*v.(org/mockito/internal/matchers/Same.classTKo@6I$M>(/LlyRʣU(PJmU6#{S^ c;m23ٙYs0c;nLi%cQTky](` wso;f]XApn9ɷQVxT%]>61y|ɋ5e8 2ļr0ÀG Ti[O1=~~m (lZ\aNg t@ 聚@?10UesD 3*de(6l_#\ibaAS a7 ɰYC^:Uf%p 3},CiKJ`qjMha4qdpb0ֽ8< g& *wf]bW*JZ5Mt. oQ-C*gZa^N˛˦Cv#=죇 0`$勳_.JaqyS(gaC+uڻcZaN3C؜QyQHK5m!%VS䆂fl:N8ESM/"n2(!+d$~=7 \Cm@G[2A`dTB}/ʼn7pRWb^ݥNJtPꭷx,^`X,3Km;o# %sZN@Tܠ=q-WCsȻdsx}Lm'X2c> m87-cZ/Xo=a-'M0?zSV.U$?Toy7GgL?K2IOe?wPK LjA]&jTݎDKfjeuapLvP//~0F\u*=x_!;xL0C%1&qYlc&ߑC*]xp5B7 }$N >C?YPa6bu;Ϙ}.|8W#OU\k(^.EzoPK /<+-org/mockito/internal/matchers/StartsWith.javamMo@S6$ EBR2^Om׻8*c8=}\]&p _}+bf^?`}]2ˀ5HXcA{4sKкpE~wXmhr\% ', |(Uݣq2ЪYW*IL(eP0huv":PduKQӰn5n8R񺇈JҴ5a84\=3"?#6G\DRW1$ fLYwFv] CVn]/r6[\ϧrՙN/%I;H'YDXP*]L+:oo#iܢ 6ondqHœ{o (WiA!{6m+!MC:I_WPK L]PK /< $H0org/mockito/internal/matchers/VarargMatcher.javaMN1E{K[B 'BbDމw_{l6 9w`RTqp8g윧~PK L<\L #?org/mockito/internal/matchers/apachecommons/EqualsBuilder.class |eƟ/i3mJE Ц)R .m)ZUU1MCL, * D+ (kQ9o\]>fof&mEj_fޙ}5o&ՎZrOBu:Cw p99pkkcNo0rNv̬vzĜ8R# jDi M0ff]hAHd`HxxĒDFp20~DfI۰'? KNC^g08"Hi(US΂40tB{kHZ4)[)#epI_vI1Fmrjg $(8CK~|$~UR 2掎S``{- F-p3ҀpgfECPҲՇ<^ǔ@ x!a䵤"yЌLc!^=T-bL>lܒ2:n/rJQ1%F[˙;j숺lMf|ŒY(;YK1M׍qb=HABNEt Rp1.Y5ѓW^8s̢" *2 ALWyyXj<q@-g+/ F M5Eç`JCΐeAv KuCyjw8ق_blE1I,E~N.ѝj`ǝ,bQ C1c 0;hX!6` ?}{e?$g/f+[[}}0w3uָ)ZEL`rfy!*#)1O^6oagym P.fwdO0c2i=+Grro9P>gp*|o SNS}h^gVs>[׍HK?Qro nͶ=H%F3KZ4 RѝۯMTKi8MW:HehBm^AH&RU.5R){@NJ˳ZEרڋoDsҢEMEsbEm$rty|M^Q3neoAb6(Ghf cXnb5Y6{z[sdYMJ#k}X䙍Rg? sd˶*֤ք&*a=V%g3^}B&Y8kí- t,AOԷ~6&P ٠O&UDuȑ sP+W'Pɬd-܏i?c~N/xγlc-5G>Nȷ?If^``Ƈ^|Ǿtq뉺j{y2#GbMla3dZ8oeƳғMBuғ&sj(ߋ4DI۰*yoH}hk2ӻ̼.cFt5ǒ9=ރk,O'n(e秎^O9fE-gV!+8dgu$?mPG8Fu+q:Jd^n 5}p5~eVư* 0#qp`b4,LL"7vLnEw׀D[?XmV4}ɒ[[izE1qtLS7%<Q϶oQ7:Q.0~]6݌0V7`|CXC&Ö ( H02FA c:>M^ϽaJF|O;* nM-صMx{uصMq?vm4@nݸ Z}صM8?vm4n<ď]ۄq^#صMώJMqGer#+u\!.fB/aB2!M  <^QlQ ƒR\|Q񵻞eDB/O+XOU(fq(ZqO%DX!j*˳m0֨Bbn9}#ڗO-֗OZɮ!Z6l)ݣIkTCxֈC+PZp~nF:V]gb06^]btx/D9:|ዪËpD^7z֋^WQ}zz#IC4 7O郈t.ӷ=P=}5D&QD!ɆnmHU>;|vyckwyCd89#~6^Ӗ1ƞ1FFy|#9ʀgFɀdsi3 <H3 Fdba8F ې ٘tC )%`{Y1` 6` v.,`JBM#X VD36Ҟ1Y1` %`IJUMy!`5\`g3 ΂mm[D[Bv Z-#r]O[EA``#`clvA HM`wl  ``.k?: ++l` v`a$a!ai]xg_v`/%LW*^#{`omC `gl=cT,Xs9s}A/ !ط`'0BF tI;)/: v0v01H5A/!gll0l0Q˄q:[(clD)1/&oaބ'}&u*mA0qio{3' ј#_$PK /< (q>org/mockito/internal/matchers/apachecommons/EqualsBuilder.java=sƙبJ(PveL[r֑3&s%KlcX E= 5c ~>Zo.yxyqqBh__o/ıjtśZ/0 L u:i8K"L$daHdK,` a88h}{ @&100BC/YFh/J-DTI%BѪ?3,f"i)'21Y DWJTƃB12cE@ QP <0!ZBdxKFc#E"u6VKGKp +k:lx[A4(8AP sh[NFO¥HR#f@95@*e0HW $ĉH~7glqX,hR=j9[d2݋cK79%?S_p > !,4 '`|ErsT~\vWty6/ޫ7?/oۗ[yys w/EWySH92JTF^gMϦrj%Y8bΥNTROT̀j T"jH:+e@%`qZЙUǀ=hM0@R-=; <8]q4V.wmeV"q"*WZ_O1.P`x2}R3]əQxJ0  wGDqe)%P:vET4 6s$Hgp| :q۞X }b r:;.CpO_`ܓVl&z_l< 8DLCm`l;H ы ('4OtJϞq9ZI}bn;jp D;&Č+4zdpdA$n\xm0B6jTj1ȎhH3BkʚeF$Dаwf!dD.+ !Bǚ"J)9laPՎcm%8! f?0_D1cTeL6sAۑqǏnQEͨ%YnB =qr Ī,~9xSqq`;<`t1HKoK!v$E EٙHfq Af1T|\)gl[0JƑLw9^QF-\q&D!ݶȅ ֞cqK"T&QwYJbӐaI *@lc1e&]񲉦N\(%ߝaAd:8X$ DJź23x.!;2[12 +^BLWsp|BlN6f#wD xBI)PK UL^>1ug 1 Ul3|(29ACd&g\)pЌN cl 5P/) AWCa<QaJJl c[%t}\oA,|ʕ[)KPLq7iYڪ= g@.kǐK2_>KȤR̸O$ΩSڦc%~^OA1jq[c8JԟNBRͳLa% gs[݉WÇţ>>yx{q''=Kz8|_B1,BJFG\*: apdD')ӚHCHb3rnG\ۇ$W)nT|Ρ=H1]9*R6SRh ښ{%[+-[>$?I,}IyXՎHcnFň&ԂNROfӅMy )<kٯX,Y $+VelU4pD&r҇\=M:K /ŲX+TNjo>ֺT.1%JA Wց~C!4 %*}"SW,˾5wgPVywj%%\<4-hyKH?*2T޼N<K&O&!+Qnlł&};Ĉ2}-{? G@ . 3Z7ip"R]rТQx3B)G,ƒ:\1evncu\(2PdCQh6#^--*6Ѽؐow+mr h FC{l0Y,?O{)/< c (逹f fY8hzב)fBEDwUh輏輏M?8̣<\P;hBggeF/Sމ{n0?ɛz0/Uā=@B]kO{΀x,J̠/BJozNS#!*.d]0P:31k15(dp9JtD6e͂` /#7vDtuZ = TIJA LQ׀Rʩ\X(]KHaT32v=xs[Y>|m eԀg×gZƘsyhy{Wꎧ@^|<\~:d0[t?1Sm3Gu(l}'jxvZ +vδo<)80n 5^52/Wt$Y?~A24N^0).A,* U(6`a543$(# dB{bQ#e*Q!eV3VJ&F[ ͮ,ɥh`'w.u<Ə~xAfzrV#PwfدQv?^w)3096Pvr XDѯ8(tj%Jw}M", U5(K0J*~3l<ǔ]jܱz&oaЮϰCfdm\r۴uEUhMT^&ՕLGސOes] /t,@'h-<^ҳĨ,ʉo2M-J&EEа0.NuD~aCxNL RqvdXʳ9#o4_FjoU 8.^NET] (c> !1z_vأ:1//qn~2=,Eϕ f^\ZY[,zWQ7@BudSD5-}݋9ls-z f][27"Hu2NCc%8C`UIhs5EMB eF(f}EɞT'wu|\s7Hfm70~&P6J"9[Dғ+\[:BY{Y RhB"M| Fw!u e|,`;V*Ra2"bT2_*8 } z,=^#S miV #]Y{aCmdf[8@ <<\ken[aVoI^3~[ zy3o):XjćK/^+];]W\ N2T bb'W|zV@b_p_@UTlI[[m]-cb˵;]lq`Dv ~]*aT֮ͭ 'h˾<6AdBĆ̗;㗈& dψknnv&Sdh7NníҨݭ#o2IjOTe95venSܠ(C*24;wjVտh$ ȯ3qSY7nw;{p{p]3Vw78wjͺxө5}eUWV񚩤űcO;Whv}}:Q}Č~G%a]9{;,"wV!}-uO{(_o{6{ȼK# 2bd{F.f78 c*vwXڥ 2"u77tni\7w ݲ/ړڠ4hQy{?5uiiu)c]XCطnDej:߷W^5\}U <,3Sïӧ sUb̡ǃPK L^e`O:DŽױ"CLo.12D%rTc>LU/SV ꪵ $m_L"CEŅ.0AzoQIt1? zD5Ц(x˶BM5D(]s"d0E%^SL7 qmɎ\QL^U7VuƛY^ CDx=1QrF`FlSNU+4f&゙ h!dYC3." rw]<5{߷f۾EA ]`9D[Bcad4+F;e(y2mczrΟٕ"77]y˖mкi#B%/ ζG%2&I` >B<5}CBv (zs=ЇUlY)#F9c,hi2ß8h zH]:^:v.qI!} > Ǹ>:lI4DxuÚc=CPK /Mޕ `A;TsM؂<Ċ 7ܶY_mZI$5{, /饄XEn~hp:eP{ʝӄF\lr()6BoS4Pi4$KvNPt%iAzhe.nM:c7 ^PK /<#)z$-Dorg/mockito/internal/matchers/apachecommons/commons-lang-license.txtZmo^ aKi'MXr֑ I#>2w_gf_eV!h< 񉟋JѵwOe6j(^|_w\AscW;{xOwR\/n[Wooo.߽u]|-K^Sf­e׉pAٍoDmƯbtVmiƚWq/znz9tSU#{qj˗8q L=nT?fl^avRaBXo>1ntjɰ++_KAJvw?c|%dDA 1x#C5]%UFt,fcUxS#⵱,v[MOmf|'_kvV0H Wb0>c-X\)"zDnXp>X499ӐzK[Jִ7/pk?4n0U.n="j N/$-Mg _vv^Zbt3nV~wPX;osr>$:'ֈIVZlmY萍i4'9ʒu_w#+Q)z3No4 :;4'8 w7 ^_y:5~.cZ!yxHUtVHuUKM0j 0ⅻOn=5\|0oT(vxR3<}Jpl.RwrEL("%oep+"ty}mʕ@ه{Qn8+z^n~Dtufw^RYm>(AZqC_cN+"h n_JGV98:!bQhֺ^ V4۔| q#ll {{w< q8FNtcm $TPA(VmҲːn&eUGPXyK 9L/7<_l+kN UDf" )ӖE8IDȤ1&Qhi؟XVkᅏ]*"d`pvݍKIHOXx0D>9>JJBCp/BOcbn5yNTp ])cYZ3E`A1Ѽ"] .UO g)/K@@]cr{7@;(ԜB+ (/zNHY3*'݁ףcGnC|Xd-1ntLmu=!7~ 0D%n^d)I$]CRq; F̨T#a\=YAWBa fD7ܪI8욝&>қõgFvE5n?koԄ>Ttd԰%>K8b:DgvSaHgX*!)|%u.AZ>(fI$M!DvPP/@'!CՁ>2ˑrX5=Ϫ&< ՝PTɻ*Nh#Vs !S^,̝6 Ғ^w W! N g1Ţ%7%z' z児+If Ye[3ݤ6#,;@NܨmV>;@kQ3@S‹B^lTg͢U6ikSL*!jbi-ȼ|֠x%&.ҺO&c;*1 _ŭ*Ms>}# ب#Bl-C>v(b=39#VR8F)ot<p23y;V$3kXd%O΅%Vr8,>i6,}L&Yr''+% KNRb(uqUBDpEoXQQYo.E *){0\з2NHtYո &HAtSRA;i_89'4KF~j|XbQep"tf+-e%j@uRU:>/]h索OjtJ:*&#&0}Qʬ𬥩'M"}C9u3V'T-#/,f80le|&ÎyF' CMCIk_uavfOCT%s P4FdRlBtr(}EM`ɵ.IӨ7N<'"/Q`{!P-x^9TTEPNZi%\|H EĘSL{BkG*7ahD6IӉS79ԴÓ .pf͜ŻYֱ#Ϊ5мg1ɝ!,cE[죭<3B.UFƂTIOhUqY_Q4¹i©FDip' UZjz`9RZIGY%K9Y#,wcPOӋ? E7wݕ1NwlJ=kIVn>QɮL8A6 ǥN!&a/6|OhZc4|;5% REc:"'"@ޯOhH/zmr u:~.^a,k/ ր{@sEYv9d?(vBYGWIib|EΦKa5c+Kl(l mBǙJ-zԦi~բKyi7 M'M=Z't1 FQOV]>N{BVl"- ~|u}IY{ፋo/ɖqç巆7gWLsKUǴ%xAYTCTj5N w }:X҄TMg:x ѱmCXsqvi?/ʠ\peS*Hlbi ˍ/+;G31vh&|痽96&8] g,V 7 gGsE /8M,^Աɹ2w`܀>`j9d'oﮞAsxHJ:):u`ь|ᣴ쑬{)5":=3 8nׯFF%bld6PK /?*org/mockito/internal/matchers/package.htmlIOr,J/M+QM,IH-*VH/R(K-LLN,SHKQ(.)MJKkPK 0<+59;!org/mockito/internal/package.htmlIO+I-KQHI,.N-Q/Q(WHJU(-NMQHJeq5PK L<`U$ :org/mockito/internal/progress/ArgumentMatcherStorage.classPN0=R VD&R׎Q' |{ڟ_.qJ66eJgNXˬIs6i=r<0Z-g_"qLZ#&N*!4BEc_m`}TAqTD8oPK .org/mockito/internal/progress/ArgumentMatcherStorageImpl.classV{=o60d4ndUP`Q.D ZYfwY$]ZlWbml5cٿƿ@=&|'s{go܌iMIsVޓnްɺXLRN潃9.QqL !~8e$m#MLOCD`Ǖ԰BmSȜX;XV^( lkAuGQluY:6h Gݍ!R6m?٘XG* ޔ(bS]Cm _U[T(a蜽au ߮fFB;VdliQܦD׎ZrUk_o 67ǮDU9N)o2bl_߶pڌbQǓlWl|&F=g}*ĠI/q[]B(z5E:c^Gq7Q ({5Ž:KjPl^d☥-Hm-Y]5X=#DUmPű6<n4uiԥ#QWx_IEa`B)6Î6vɲM\Tc}M(X-QX Tliw+Gl Oȕ4{[ʌREմxN73j T'0? 4㌿ u"i)<8{FqaȚZzϫSx/SjiZ(R={*DȂ9X*d*[|(G&+7\pV:^}@jsyHI`F{Egqnri G* pY/öT%z?;)RBVmceH,cM9QfgU=a&l##͚e'[vD|=}P[THV6o@šor?j1a#—(NzBo o@{+t^/ ]Tat3ZںqM>(D{lvj/݀_0l{O`+SD,Ui$ޅ?tq2nM "2'0ѵ$f'XB؊ՈӚ !u =+9#X|E2eұ+DtġSiA˭|*BCu8qś#5ƚ* %j вtIo}ڕ:@(͞ &;aM#3B/4NƬ>5^h±&8#O?*"NpщefUg $˯Jߟ^]Ô=)4K|P1_oae>\6_Ɵ?;oSV^ vM&~Nazːc>T2O h)1B+7"] u҉+OqnxSp>>ߠwm*5G>a>W W9ٹR8n|VoQxR,JgGퟨyI&W1q(If"yNVRK,*Q&+b14ȡ ҂#|e~Re|gDBi#tcF4lc:߸*>  56ϴ&nꙩ܆yve~6`oaO^(SI6IƧ ;k`= ;+ciWod4#~}L5uCEKW WfuLQ5. NDJݟ t3^ )T/"y$7fb9^Iö6㭺J(5n(zZiM W׋8{DwK(iwN2Z#ka_"Yy 7Km&?ι@N2]8X{jHӁސO =#AtVLJ}Kÿ#y_d}oS^PK K M|52DH|fvf~` ,*FaG Ema\SJQ4e)\+첩r,C6- vaD xT1ͪjgjuP(CZ cKyׅi8y+RvHeMchOL n,p qW٦( oPՁ䩸-kj mUSޘj{rZUT\0 }sye}8% +)9wzODc&T9F5&(Nl/??I-d̼Lڣ&J$?la ?|_h}_7vv?BSC~y}Q)7`\(S-?PK .<(&3org/mockito/internal/progress/IOngoingStubbing.java]j0D{aą}I2ibR~`%²֬;#6̼隺BWoP`t8<;"ѼkOCȘU҄u1B!%9VQX 9G<=XN-H!NkCZ]b8痺ڦkE{1$]w&R<Ʌ'lH^VgYlKbbM_?PK K<0' 3org/mockito/internal/progress/MockingProgress.classRMO1""* bECbBdejiIwyݺXu:3o^_67 Eh`y8$cPySIB7x*mU jPO&} ;'S-͋>D%,x'O4exUcE錵5%i=r()٨{?-=KtouBMu2=;:)b -;Yu9k pϓބ*r m^i߸;ސ*5nZGQsaZc>YȽlPa\L*q|=1> 2+flBl;,"Ba'Akp3PK .<ӟ"2org/mockito/internal/progress/MockingProgress.java}SM0+F{"QEV{顗V9EZgc& hV5Y Ivx d6%ӊإ1"H#G-]Hꐻ _BlН>VQzX%]_6FCqPa /.3 /v*/K°)! fmGJap tKϏ*&[v [gA5R|ei^ǿ+n@sv.4b<.?LoG8) d@BdQZ$a^yQݷh9W, EiMzlS__9Z?Q~:{GEtyIiPK L<3 Z7org/mockito/internal/progress/MockingProgressImpl.classWWW@#நPC@u`X($cfɄtvߗOўSsz{N73 ! p2w- @~ttJ+fVֲ1ӗ#3#!4ΪQC5ѱĴtX'p`M`lBeD`OY2nʀ@js3錪NrJeiMHlyZg*I3ŝ\"@ X#%eV[zRGE*D.U4f%UChmՓ,^6:Qa$CY则_s5IzLcʜR;sR`]sBA Zf+8=AlfuGvNj ]A`A4H= 6"$[) x\LFGzIS`S&geKp v &T9%^C`uNe@TG#).B@3 hJ(&68BeñB4б ⸂Flj0syZnX\RWJ0in%HHږVpC0spؐ2Ĉ̵#-yKOloP^eȻ[td 2|PW\kR+,9.f)-Ub нDU1f0HC xJ̊)ęސAfޖTgݘł]Bݜ#!kqcgqp{o()Y eJOmu0j&)rkڄ%3%2--YJoI+Fw[)UƔgq띂h~{Oq;# zaCfC2qquzeHNa! > xOxH::)[eD"zۖN4+!ٕ/2~zTvt=-&T[W6.1.fVNjtCX FC^rH^ xY%Om7Ëۦ#no1|~oXy-6簓laoD̡7ww>:? g3Wna98I*k#]s, z>l3D v >K΋zT5@;^co>Ur-y0t1NapKp ^D 1"‘Їh+\"<9kK};>M۹lg8*1XvU"OВPA8z;C~\4<b8h*")|bHڽ_}C`L~hs=knN?[O^ ڸ^M)cd=rY q,瞧8W \mzs.nSXf"r%%J(ZՃMSs93s8onVpw:KZDY ߽v"{J@&4m}8*) IJ˒D(#)ChxA,kn4C^clVI dr KZXV+ZVBAG(/D@ͰRT:-ʠOxE#QJ~c"%ݛW1mBIEFKP~rvXΫ0Z+(6]՟6 <'@-п;}SUDrSh#xU5)d5xe@dX"W ~TB8P/>~h}Ec^ߐ;a~lhڤm '3&)5-ҥ7PNI-FrGv_8+O# GG:((,@vɜy$FPD'UnYvBgI?* {u~kdysÒtSd}򺹁 wsŝRBOa|&Bi1I96~h΃+|̂a5,&(,|?IOL-ow۳:N_uum62!|?"EkH30G1azdst3&?pW`3^y][Ιm /i~3M4!ӭ3i]+h im^gQ|cѕo49jhĎ۠}wmi{σص[V_i֟Axz4kExZxOl]mƉIoħ̴TV r)K.L>+=l  >y졪6V8v⩚Rf]DTS{ü)NӄS6o6^kz`$O2gI?Ǖ†_9 Vl󞯃/v|~0Nr&Χq5ο2"YVa]̴Q[hy}?g}/opk\?2PΚ]h!p؆C}3+1\{ +=mĘwK%ΰwе1.̽ 8WV7hh&qĠ {^UĠǙb&J ; (X1Ą smd$QBtT8擣Cܢd6Ȑ7!o偉TfJ ħitkk@'25vժ9$9^>l8d@a[ _kC,| uv`"[ɣLIbocwow~AϫbԢQPK .RHH0j#R2WZ,C`[ *jA0J r>GXƘP.GKY U UVxYIeb.gc>՝1\ccb+Sf|v)6(PiGC[}K׼},efUeQ~1%gƣ^<`ZS,ak X0 G@{UoAІ$R䠝դdz5^OngW7>F2Z| |2}Dcʑi.%K4nó_C9#ֺ(|cƚqN۝nJ9~n%^KKLZo46~o#t|E%+D۰^Y+%1L̢`PZhpp]MIp ӣ[J, AUy/m{^ z=v6$4s,Nh,TJF0T}xG+%3UBNG''$dwݵ^An=ʥ筳>P4oPhЍ;PK .<12*org/mockito/internal/progress/package.htmlIOOKW((O/J-.V(.I,IM+QHI,.N-SPK L<<2org/mockito/internal/reporting/PrintSettings.classkOA)вrPx" "IcFm2-OA2.bfggf7Y,0L]aYa\z5+)maT%׸X0؎g:mwx!vpFaU[T&Y{,t2p}>CXzv^Gv̟;ف.HtK /Y O,'xN~_CRY)Q0KzuCB/VdM^+rFBkf]rLkYo0Ce4w77a ;e:,UE-man-6:W VuXW4Ik-<٫rᔳal=+2Nj )$,mXeĻڊw?P߈C-*B}AՁc<~KO@Zv-Gp5%(/eA]*ə, J= t$#FFSQ36myռB'cB$Qt:awn dž&Zv]xb3×Ge;\Fr^Gz@`t::} %'+t_~>D'ݿ-c%uBOPK K<Bζ?org/mockito/internal/reporting/PrintingFriendlyInvocation.classNK 0}Sk[]y1\BOc(1 ^ͅPb Wxg#ʺ8*o2^:5slWe;TNIsз^Yi}'1 L@(m|F\ydqcNJiC)!C oPK /org/mockito/internal/reporting/PrintingFriendlyInvocation.javaMOAj@ 9&98z, ke-bKF^B߻\ 36=]b [8[K2.|.k/3&4"Ñ:=HjƢ;RH r>^q:sDNaֈ8OI4~U. EQ`|{YraQ()~\6%smiPK L<0ߔ1org/mockito/internal/reporting/SmartPrinter.classSNSA]RN-"T+Pc( 4=ڃsp:Ex_5%(㞶`P^gf|`'+Mzf+/oJH;y)*s}۵W#i'0+mᖝ9w۳=pЧQdEBjLFOLqJJ-SaDuXHyG3ē?0ч.qCS\m03S(ׅkBjDgYj(۱]`$aDv!ﹲB֖iP,iDyVG;J-1{ É2quK  A\a>s\ zpICDDD`BLzb?kV/PxƌWzSigKCtgYm Ĭ|.H4bn:xI]>Ebz>C螺02 cg~hvFx h5p9I#2νoVGV+;Ɛ(T[!_nR 86g LXy:uήd7[vq4д shpQMPK /<j0org/mockito/internal/reporting/SmartPrinter.javaSKk@$֡\CM 6x=Kbvd4=XibZ !GK(청@bSxws U%c]n]CX>&=W9A [!."MϖYLM3J;ghՌZ17Le`q> 9N縣bU-P+ր^/+d׼VE!/t0wՋaP~X|  5ac 8{?7s%R: V|ƥc7!SBw4R Zki5$<&̟6)i m_ԣ_EysY꟢&ۚ3'џt;z nΧ}S6Iobߟʷ>5^e8MmPK /<=>+org/mockito/internal/reporting/package.htmlIOrIM)V(,PLNͩT((+KW(K-LLN,SH-*/*VPK L<$L26org/mockito/internal/runners/JUnit44RunnerImpl$1.classS]OA=Ӗ.ݮP UmR[ A4Q2)[32Vd9{w}@ t FZ"<"Igodww_QWCDd_A*Aae"v pgE3m%dvarQZ١ӕh1I;81}@? H~G$#5lbV$O"{(X }#3M;b_JfGe5^̒,OXXH,ѹbXB2vtl-*9餹 =%f/Ѯf `Y~kYlsN;*EPK L<4org/mockito/internal/runners/JUnit44RunnerImpl.classTN@=CNVR.4HTUY"!ǎlWH~T; Kgrιw?0a;%lgcqp%xiI/Y+助1t0U2o!0z%i6xelN0ÍZSU ,{[CR$Co"wRM\BVM{Ҷv4t0ɼ]Qa1kR("E{-3zK]kmOSfSsn@uu$q5ò=# ~Ugjj̕ڪ4etyI䩧En>TeG1Ay5ǿ);d] dLƖ JN@{)[8ݦDH89Nmi199y V[xy-z"%d[Amj^ &GBȥh׳{"a&,RzYنƨ"d7M*+˾z O6+~)O\0[˃O ]c:j}4S_w*.$K*wo=:Td.~hG$c=-H`9{)iTTp=٥HON&EΕMξUwņҥG9hT :ZuUB%g$.QdEc }Kӱ}rp;$ 套=|A4uvAfq*£Q6 oe)GVyH>D>t+ZfF_i^nӶ}c)j7 M& rM3 M>`VP #M*jr^BdBz9 +v9c4nOȿ?o%111;vģ~XHO]_q4A"_x1s2 B|kd ^PK L<7IR=org/mockito/internal/runners/JUnit45AndHigherRunnerImpl.classTkOA=C ۖ<|ЇtA" S1Je`Kv~$ $δG vv>9Ν/ØewUts;2p-smy%oYud0:6_–}k` -#lw"1 ^yi0qE" HdVm(=cnb_P֤$C{<{\$RXE7/lkL+yhbk&LF+xueEC'C8ؒ>5L ;pt29E-T)3572;`QSUG/>R mkEvV}^k<TUbA/CҼy>~ \FQ ЏAe@]7Cĩȡ14DJ9O*/CO焦50f1F8h|gF1e׸'-VyeќX,7WĪBh˲䑣jVeƖݒQ^ZaPSw~5><@[CDדt@YCY $Mz-iMrB+1Ul %ihUɧ;RY''+{:XBGUB>E5 +M~J`DAc[,\;M]aQJ`2к}4 p4Ŏ5q$8~gmp>Ϡpy$$aN'ڠMvTEftYD 8Zu9V s~#^H=IW|͠[ڙ6ŔZ16UiBSLE *n*yCƛp&MBg܏?,iאzA#/"YG_ku+6GRn KVyײ iskRxZsԳv:(GG0?PK L/1䗲D]YDpØaR#B7"r.t'N*)dSa$x4!|͈ 6Q=JjM Z&ʲ|pnBu .2\ 'qXK3&{ WD.1!Ŕaqa1eXLq&T%c ХPe/5I_8_2?~rWnwudlgJ<*_ytQEo򒒃r'S'wJVE,K .+d+< WuKUxx'FD)U-$Wfy' 1>IC9'ҥ}PMQ̂N<`XIu "-B)m}$C N:a<ͳ]xدAJTZE|UV,+|=u;G6[,Sj֌Hܤk"DyЦ{z]4 DueAWT-N:[_]%5- /RW9D]('t}fgJxc~˚-M*c &RlYrU AJ, ~}UZH(m@q6-f,B_Gpc41Fjj]Y>Iu ;.ߠpV> z8 '\Q(k D&&pP*pv@8wӇ'wc9 @೵6c_̹J{';@ʖF: + p.5с MVթO.2f)3X*AU0CĐUBta~c-RYhRE@KRٳKӴ8s/'XFX;./f7sῦI uNC^^CsmHЌI=7Y!B~o[iugoNR^vv5`8G e PK .org/mockito/internal/runners/util/FrameworkUsageValidator.javaRMk1A1`6Bq{cĻ2_lbhuX$yotwկL"@ffi> kgg6Ǿn P۳@t!B+n=6"֣jIڡ˷VGuv!zhFrf8g=E.ќv])Qpe|*r|"nR 8lg:WG;@DӐf{4ovz|ofyӉLU\ȑfQCΣ7$bzHMV{"xS,yOŽIv_~ѪZVcݒg;췭ϡqxŮߒ %MX8{HULop-Rh&:tk^ S~? =qr9NV^a]JOn42Hb'],ZI Sk[ySs [>N)Wg¹?j]8WgI>Ool~h]"Y\ݎbu;";{vwޣνg5Ϩb#@M5fX3Ǫy)R˱@yvZΤIC5^`vpC#:daK1!K!@A$c1AAVÂPK .<úAz5org/mockito/internal/runners/util/RunnerProvider.javaS]o0}pdBބ@.eDZ"?~߻{͞ RTg3d$@<C@J4I0nOe~CcC-v۶?`h+3T#U_fPK L<+9org/mockito/internal/runners/util/TestMethodsFinder.classROQv-ZZG[5rBbH&M m+۷ĻW/^xDuV!xpyߛo?:ၯ;Now VRB s pW]H{\q5{ڈWw ܔJ[xzAv $® !d!7ɔkBO,Mj^/|C\Mo? s*l| D1HS/?W.FI@8}/#hOAPK .<&78.org/mockito/internal/runners/util/package.htmlIO+I-KQ(-)VH/R(*K-R-IM+I,+PK L<j 0org/mockito/internal/stubbing/BaseStubbing.classV]Sg~d !VZ0B!RC$PIK؁ؘ0ɂeg[{#c;ezL/#z׿` }?{ssy7m'yM\ /nĦq/l"XcŵFΜ<:\[,n8V!1GgMc@65(ՠ ͬ&  |1oN C>[ :<57anl 5"EO+Or%f۪h(g" ?ZF=!K^gG/l tF ]ɇtJ}-' vm\Ka(R(\yNTej9T%>C 6ffTA6=}`4^$\1glRQÈ@1z(,_y謣1\28SA!y %C/ s. 6V1nʾ vi2K՛`koB6{5>Kfwsn{C$п K7~_H.D:݋++= i TI@gDw@ͼƤ gȾ=@_9e~.s+B-yV:FFe\k ̖E'C: 2Jfa`ViGĞMz$ ٕ];DMH#<}PPX8xN4yzr }ǞjPK /4p5MuY lг+T.S eX2:Pk:OEԭh9؁n KU-G4!sv}/RUKx'QōR~j|O1x^ͫ׾e=ϥ#Mh7AY,Z5V+.v?#qxf q1|')U;t-_cH kH_ͤ'vJCHWNk s[#Giܢ,ۄ\Ǎ^3K5755ʢ;PK /wgGi#x2x!L&4jKހ23e7v!Md IJZ7r`q\jj+ Å鐥e)t1M4=\a-Zqg{DO%?SgW,ʺ6{ޙofحZ0d&*oPK L<4m_ ;org/mockito/internal/stubbing/InvocationContainerImpl.classW_~^X\&x+]q/HPU@Ui2#.;dfg^H6i$&N;m}П> ~0;>}s?7Vl;a8fH;R15xzLiG3ҺJ)sk#Z,Q@qQP.~ƀ *`K薡3ZoJWOa\AGlJ*F{ч? @]c1R#}BOv"]CkԖ$< v7[-; 9]~KmXi!_ ֙Z>IVWJscSm.nSPrGc'Riy7Ɯ{P`jf`]݆-G*[8C676Dz0BXM+XJ,WQٳP$4!fYiO0nr0_5 lF*VbaZb.j&3`0>[II*\aN<7@ݦD6O)C%ZZ`u56̀@lgX$#6Zd"bNXz@ᴊ3 "%,Ið#zf;*n3nS<*؃}aR|OiOrL[cFY3*(4= n2tGO; $RS|^v~RsLǡ0zd}Vxs@Ԯiyװl~a jLWn^5A q^ĵT4)$ZRUU oтbp?IаsRA`L< I+idaoݹUs٦̓ޙ>|HչW2>6C]x2PaÑ:,Pe MҲJ٦'eOg x毻QyJe_SEw9i@SGU_|ҜVok=KطmA:!]u֋~OrwXE\ ~'%-8 &>f*x{ D Tg)u~ x{"4 H 43 v=ԝlk >>Is8*G>A ~m% ϡrS)ŹT xG~#&_)5arNLG$ '%ϨQKTn_TY/k)Eֵe{,Kf3a\L6nUdpI*߹'HK޳r_X:ESV@E_J,L.*Ϟ+,[L8kf2 n6RI 0^8/P2 S\cķ'Lc]פKL%:*~+ zSEUU})0{J{JG߰mt}ұ%%¨ΩW'}w^f8W`~yq<s:z>7KhcKX55a("yHtrAgpG_9^Brtנ' 7:!QF."͠%[B5s5sq+-Ԑ?ZCnl{Ӈ,WUbwv5DiWw?Iѕ]];3>b$OMX3 t;6~g_V#Td`Zk]|~!('OM-ݧqA3xq<|zO͘cX/cJ#6HcNw3W/e ^XXϟ ?UEo pb>NLB"|Qig[ݷ,?d .H̖PK /{O4#ۙIl2ZJؾ__/sx}zz2FB$Q|]tv5J&f)] 3f0iV暚h7RlE:HYyH~`J) `~lx,A,bq_'.nMeP%pNB Xwxu#R5P YJYƄq.9[HoQ@\cmJ!$ |oޜzo_[-j>4m`!\gб`{mz2> PK L<%L /7org/mockito/internal/stubbing/OngoingStubbingImpl.classU]OA=S m ""Y m jH$Ҡ>nI,d4QH4g]ZvΜ{X}%ǭNSٞtmfֽF쪹aWΛ^-!2_\.XYҎ,{BhϬ BJN sv.)-L-O9c{aG}[FVފrj-Tz+F<10*U]q]|2mi?+xmG>KwGOfЇ)%UIRN!i`60~G]00a+Śhgz&&4]{FrZdUzodUYd\LBkfGx~;NqZ;U"V X۲\ej㛟`7[nk'5\گz֫;[mvx0XW9hfcieB$n"sJ9g#s7}j> E}lQz'Ø` &61+{m|#3aYhl%qVDp?O}nWZf<@km1f4wZ! <PK /<6org/mockito/internal/stubbing/OngoingStubbingImpl.javaTn0ݑA]:@ZX@H-?8Gؑ@%R Xs|^݂.Ma)^{T{!o@-7֕59ȬLVR"!Zk6u`V|)EAk262F06i (-|AnQ'%=-*)ۡ%iEhcÑZ-e)$rOJ )Pt~@i #w:r,׊'G,mY,u)?Imt=^J)Y*9WógDC"@3  E41}n5h5a*n{ 4o4VyoQxxXb19zg{bb_Bk1y3Z PK L<=\'( <org/mockito/internal/stubbing/StubbedInvocationMatcher.classU]SW~N 5P?B`j "hb ]f?Mgz;oz3:vtƋN^xy}߳oFQb;]Y5=[7-O:Q]/MkY/N[ᙶ5cx!F5{}ZNvk4ajC@C㑡^iF& z"p #눱sL7cX bh*pֱWwkģOmuH~ ˖%T:s>D)9uM|/6Ae[ vPK /'Ţ&*#}p|:<|w;Z)~}-,77:: a|GM VT :in+y\e)Gڝ_a>*t º|y~R@8*}3FJ'c._<֬!&15t6#Z = V<uH̙9MgAX>[X;}Zw*ֲ]{9nl5=x3]k5JKINkJ&S1nL>frكr`{`+PK L$d%.oϤsNvqa6Sj'=b wT&3Le=]UEFW%#FTcHEU<1+>b,ba`{n"h[/$ps6:*LԔ˽`UT0$3[)d7|BSīU|8j=m^Zf"# C^HPk8-*sLqWE_аZiPp >VXn6Du N߱xN׉讼?| dxJJ(3`H\"z .utj~ *cHN̻cztLjb:͌6{,j;* tFCMK'CZ WMc.P+)yҥIr7n78I!rG>D5R$x5g"p8IJ d п[Z0EP7o j˟ɩX!~ҩ$L*O%>mJqiv$Yz^"d&3IW5L]RF{DrvoV1 縢<+YUߖ!yhyOyI6BpJT?;Гl\ D&BKT*JklTxLPK /FHc$nֈt=8_bx2JPK /<+ Dorg/mockito/internal/stubbing/answers/AnswerReturnValuesAdapter.javauSQO0~pe)\A[6 mT 4{84# &I i~}}猎W?zS,zNNpM[ڻcVMYI؜<%A _1Eq=+23J5ؔrb84Yfl<_$d`¦S )}ol(bai Y5Iol /.[i-h4deԵ'fIb$ +>] G G@v$/rXׄXX4R"T2%[x44zK_X CT /7#=qTS{@A4, Jg ^6&Wgd6LǟO'W8~qnw'I߅F=q_|3>x}HCanHYc:_Χ=WPK L<}bixs <org/mockito/internal/stubbing/answers/AnswersValidator.classViSG~ZЅupAQQe%^MV0Ib240CfgAs\~EJ֪*?*?*gf/D뇙~=鷏OgyIǗ}õJx&VfM:馱hqSTL!l=b; Й(*kV&> 2,viC} tmZ k؅P=v "P.˖pVHD}c֪Bw{N\ef{-37\mooޱ Tjuh]sl+,P_u%@exqm|R‚ʘM4G3QEƒxLrp_S ^.w;I!.L0Zb!WXPԐ8Xt4\cYܨL8?8EPRr˶EX+V>!ԒLݗE;!ϋ͹rȹ)"{-[Fbi ޛf鎡䳾M$aXr2N i-W3FҹrOm0RGxouRr0%:y_*e..Q{ݱ?p)'kj{iwk@-*j7 ~EcAE " /T\Cdh]QyP*0)Ak sBcʜGe4A*ssabm$BQx4p)t|d0J2R8Ӓ8HTrq,Z^?Ќ/v!`B5 )P I4 u|+_G fC ANС~P:1K\˦g 4m!/RIoCS*%D}#MjJBߍĔfC]Ib{3uT ԍ!/wb9yDs;KQWn)!^(o&fTiKW`pcꞂ>=I"{r1uT|{43쭢v)oI._ '7yGbȝohL}Kb5ݔYF"8<(i~(sWZI̞ ]nj+j>E?.S5 !&ecz:Bu5Vu߿Q.^'o=ʬatU}o x2n_enJax`RR s>0V-kK"{ĐdmqE:?PK L<<org/mockito/internal/stubbing/answers/CallsRealMethods.classR]OA=])C/č/dTM05>.vp1`L|?xwC|{fϜ{;{/O ej>GSf羽.MHVZb%~< /aeO.3>#1Vc(X/HaqW5gp\"䀿JޣE>H_,lw;O>2ﯲA9kPK /<Q];org/mockito/internal/stubbing/answers/CallsRealMethods.javamTMoH i7 \mm-HТgjDɓfUm䌒A}||||rGu6:\;ul!~wgP, Ao+|WҊlB`-67ErESؗM6 r\s> W++hRw~pFlyJwMx(.NGYdXU\ B rʺ.S(P^*`+{ ;4=%{Xqc;OSv dc%սaKA-jP<*~HH ?q6 V$$bc3%Zq(ងR1 Иk腽*=f WpQ^ Jz1<\y̹ "Sџ:*URWlm8БҵV+85< _7@hVPAҀM7 cV/oS3E "cF֑*Y]bnQ]g5&ٔx潑  VXe02T|ЍGV3܏yAci^s4ÞG[o;DCx)D4rpEF%ߺe>k9[}^T< ٝ',kmQ*w0,e]XŜԐٗ,(li1V.Lw"m6q]پ +ar܌||/_9Yzr*DŽiM˓Ӌ;;_a=R:iE'{xZ\gpkrn`AX,`O]#=֎kR?qx:S tڃf7RȢb>kލIC,+ ijƍ?l>.Pb;960J%JvF E;kտOVߜʭM|p{r O4g?wTmgnuK]CiE)crnJ:G]wTsu$:C h hѧ%jt7{툦[с Dv?0O4 mW()@(=kWt~*OfwTyCalvN)=xJze|Y-W#2DXq5j0 ^^S*g5QOzh1U nMfQ2&^fy~GP8,g"wUTM]u)9>KWQ'W6oPK L<037org/mockito/internal/stubbing/answers/DoesNothing.classRMO@} >K?pU%T"QpڬR5TUC@߄:kAΌ߾y;_W?~X+ºM_BR#< isfb۪lϺ#sx,ϤH$scn84xWlܥouKL[W&Du =ſxcw< x7mͧm}:kB}CA3m9BU2›}%L\fcx;*GZGXR{^и"tϚI2ٳC&&f>fBm^~iS/LHo4V;:QXA= $O1&L!o3gĹvcE/ ,*:JWOxӘKUr}nPK /\'vo)o<[JrP[. \#Ƚ$-sИ5Z%G[9M{YV0'ơ8 㨖j' :6A&TM)4M(z6A,^ђy g%=s4'w O-q[7&JK`^ؗ!B wХ/-*x+XkK{bl(ε5n6YdYr3.KGVS8TMiA?RiY5`'1PK Lܳ%0fUeHn).kRj˪^dq b5Mc8*-YdʧJ.t7?|#TC***k)YolAЇː.*_߰JTjؓлLjZSafͩjm0 pHK"BBD?C:Q Rt\ SܖQ-*Blgӗw}'qtJT nRuZ"uEx#Ukr#vfELawl8=`b_TkuMٗk&" Nf? 2% I,"u;>2~3I QE{2_35 EPcyCoXn c{HILMy u~VVL#켪(utѢZec2tP4fEU54!<>i0gv UȜc83ɏv##;W ; 1E'((sщg2 uBMdA\}[md]Qsv5-›cˎ]).O|G8{YG6EvS&Eso+α4tUGz9npG]*PK /<9 &2org/mockito/internal/stubbing/answers/Returns.javaRQO0~p)atF)lJ@%GjpvNT!>}ww>v`Lje ,a2.`K頴& @5g m͞PX7UZYs<(NPF$s&0`;'oÛgU檊]c0YM+meH6[ mNӚGUVz6Ҍ>hXL6,C!//13F!mM1hB|p5[h\ඖx{`l6/PK L<;org/mockito/internal/stubbing/answers/ThrowsException.classTNQ]^2"j CK|0cf`|;4H$'_(>S(5agu꾤?}` [3vCؾ2<^fp3](mΞ}| V [|'jeˬE&ɓd*|1߈ (+g輌UaC6\`Z"I ekh-/IԅJga¢1<-lyƒcoyV˫拀C [ zKl!gRE*Uч.$a@C:770׺튬bX/q:U.Ar]W(^]QpaO2$9 n OiUk :ZyzlhĔ1L.&e?o352dzZCA~|im̭:#KDZeNLRQS1ӈڜ2^5uW&N 6MoPK /<5 m:org/mockito/internal/stubbing/answers/ThrowsException.java}Ro0GǤ\B:i6 UJ#\ؑ>}vLB`)~Y}W\~*l2Z ricՖ,TF˒D -CSZЛ\= TY*.^yMH)%sRx4QYių1 qIo~ ieYν;\>9de$}2RHϳ/i:[v CݯMUɭ[1$81A|~,7 _wy16䭀Ԫ!{7te,S6_DFVCjBھnARc.:31P5iH˺+x. f &O gN# $\i DhSxPٖ=};g*`];gqK\@NG]wHNtQCɾPK /<'(2org/mockito/internal/stubbing/answers/package.htmlIOr+.O-*VH/R(.)MJJMQHN)PK L<#':org/mockito/internal/stubbing/defaultanswers/Answers.classUkwWݗw&$X-` MM(Z78v 5*.?Guat>̙s%x$lK*GW:@cT: OhSj7q[D"iŌJ7nsj$?-H65G;`Ȟ5hګ[Cr? %߈[)\ " ~b3QL4-$<Ґ5$8y'$l! kf8ߓɅH6ipH ITn+Z[ύ=lSCÄuR zF̹BfYihvoME**_lD<]D.rJl&TEdhb3̕zvxU+p033b ѻs8 =n?;\״b(g]$\qWKR>:b%> z gp#cwe`97C~"(u ' WN89o7D+:{!RbI߯j{>q-Vm[ Kؚ{ ,eci$챍m96V 'Ǫ\&׼}嚯m(E5fJ/!B$dѢ{l>hQsPK /ܼ<4D&/hSf(m5,BsYg;mL)=i^hҺBnoPK L<3-nu#Q7rO2ޙiZH\{^;=UG}Bc+/'(kw侈t(D#~S7޾Fl$7<ւvC醵YhZv^Ks-+[hY#s-d W[&/p07+~aTٵ2ދM=ͭ~?w;B~My*\' U"P* qB6&ieL2>'dẙ;',|RBS)'n $Q4sI,PK /毨/9+4׎2 ̈O֔c YNϧglMfb2&Ld„χ{<7-/]f04΀`(J wX:`v )!?PK L<]bEorg/mockito/internal/stubbing/defaultanswers/ReturnsDeepStubs$1.classn@ɍ1$ʡ)A\*RJ$Y-κ7)<u b39|ٱ@(( uKEx'zJ{=\ĉNQ7B)%qCu9UwOE߹S^YLm0r Y(07p^-5"čk)`j+ۨ-N 1aʫ,&1@& ZJk jG*w:/kډ2 P2:Cj"ܴ-aoܺ2ʰ:3s { l% ^uٌz, Av`(GaW1g@۲8khLUF Mw( 18J$ rٜ @Δ R!Y/9K=W&>"P";] 1ɻL0,/4-^tN:lȑ}vZœTl\E,{~PK Lﯿ#pe]7\rOacT)ilCќI4kceL7t\Wn*R D"6#xFp}𞀦nOgj N]+O>Xʼn^ F p)DN*μhKR)O_c D8{Di!O5=u:&5{xH7&o,ՠ_\X Ra7%sEKǫn. }Sy +n!w-5I:dRG?[I= F! H.- !oih!63z qW8Z|TQ> 7Cc/!p|dߡ9z9w/|A/XX "N[!NJ`EQi% dcZm1ѿ(QǙ2/_:=ROʼ< Ěx4YUF|}|1Z<(ϔ(O)`C )nidHF%A_%xRuW9G r}D :vpg\PK /S%w+'ɷx2NFp8_u H|JYvC=D/S"¨E=1Vφ]5u^$^({M99ڵʢMM^W}q;熠8u#J;[37$uI Z`'(;^jk:ƄI&wN 5ZVױod61ٞީuⶸO!:"sGȞ _²,|g)7{| ]JPK L< 9F Eorg/mockito/internal/stubbing/defaultanswers/ReturnsEmptyValues.classVsEL+`@ ȱ`E@ \H@q;I&@@TPPQ<"ReOVbU_$|ww?XF X~ӱf1 ƜxW n=qhaǂ 'nGcup1@GC>#:%SՐ7nS^SL+jئ1]J`F:oއ|P 0'3bVtw=ourj3j:59~L y)1M 3 7ߥ liBCms(KV5>XtT?N0ߦÑwca"Y;f$(5Ƈ{4,(ۤWdTReX.UվXkܶ1T0;PlIGLo{5#]/v[08hDA{_j|Y=ن[ڈIQɃPineMbK~TZzlW,cVXh6 L*3~lf9A N:dz&6K2ۙQ kT 0Kd#d5 ̽;R;mà fG(M.f+f5̨@߃'̀*CqIύ>_r;=-<9sp1j33#.i(jNZlst!Ïn9!XӢ lsylI=aR4زU2Ɍ0AJ H4?mZ،{( f71^Q5- <1r6QC@e$uJWrCk4LFG(i4>ctx(.b_TSja6b /zԑ{+<0ySQ@( ʯ1?>.Xy]!9L舂zQzqtBA'$G!tZA @%! 35%hDA#.qM&FNLN$lg:w(d _~;g%mLnԢ)C^e:yi 1zS,lVyqy\C~B/~+;'˪{gN:ҕ_{Psq6W遗&/4%$xhRq8rZPK /<џ}Dorg/mockito/internal/stubbing/defaultanswers/ReturnsEmptyValues.javaWr6}W\Lײqu&#D$$@j$I9•Og 'GGp'Gn$DRǹJ[ьkȔ*ݦ,F`s6Nr3C0R rnFp#Cbw2=)T0B.#Xj\L',O  >txIe+) 8KVbnxW-n6-kW2I02\ߙݱloxx3^߆`[kǍb;ʮ8LH!n,ŏ&VsyMu=Bo=EfO9 - U.ɁCW|Ox[<8GA\&WB˨63 T0~Q9Y)]]%uM%9e:xRl|i5p9pMx%?U#ewffAEl T~/ԆTdƸdcԑ♓89f#=4zӈL|p|vw'o޾y{zKly-buK2WY^%o7YQ [^| ѐQ|`B E8|ٝ@؟ e %JsmM@2n+:)PMweèzTAftL]vHvW{zvgq]+]u rY0׽s%TS\a~}k ̱(,9ŒmOahHKW7Mҿ| d[䂊]D/B+dmeCd(t{& Lt:1<g(I?H(9O8[Xjm1..Tz*;`ƚ('c!ʬඓ-_ui3h/ gC x}e'u%'3 {e=?{W@}#NMjt[4(itenǶ]UNmTםTNfy- ~;:ҡA%;/ nUT[G:j2^lu>}nAZ1 Rix_'j?Wmsw8JQW`[$֖sJKV1)=ڱ!(b"\K`9r.G_*wT+y1䛨t[*SܺW˖-1EIhE7!$*BxB{H.P?2p&gמSӼ@s)~7񝌠W4b OrnůZ0݅쟈ehj{-ޤWȒ2|p(rgrՍ zbD^旳LKL~c23ϑgqw2 4pWef &Q=~*^yʴNo;'uPK /org/mockito/internal/stubbing/defaultanswers/ReturnsMocks.javaTQO"1~'?oj< p^B"2,ni߯R/:Kf{ql) T<[HX ./0R[LIyZZM;sV90S\T r Y0N3h6 htFPpP bl\fd3Z KY6fy+J"cԜ ;Y}2Fjdֺn0/ 5;_ܰ_}PP9S /Tp̗_hK-g0(.3?n Kju0q' .u{mM׻|vS(2(4i}@6 S1/MM  |rsʸw[_;ٱF$= 'RVL痮T-msOlU2Ў4i8x4Y~hd~뵜|m2|OQYLW%MM&z~}<$}bۿPK Lt[FpT]A`ȷ幻Q^I!0'p/p[T[+=yF[H".%:. 'yRFBl&OmɶBp՚K.f{}H:()0 xD?uXS#Z-9GYWDu aI`\YU3"c7IE%HGp+m%"4>H:rl+he>fQZ{ЌݐVbԭcRRt7e&U&l΍+#kIٻz髖  =Pnk5˖c_ rh HA`psIGsNp lL{s?bQo*,9>)E~:j7 j-wo sс.y0{ o44$E}7Dk:M=J8Q]zD_9b60Q (~34k|'TQxh*rA>^E8ax3=`c:$HR" hgPK /<7Horg/mockito/internal/stubbing/defaultanswers/ReturnsMoreEmptyValues.javaUo0~_qi4P4Tv"'fNsv$]4'ݥ{܁cQFBp]X%Kn$JZ*mȵJ5ˀ#s`,̀Zhw~I:k/v}yG(6T *9 PZ k.T@[ڃ/ p毮"Ji['ae7!V)ڱc6 Z14$t}t@VۦSMm:7L\vU\lZɂ" sN%W%ڪޏ>hq{:42`za]wPK L<^ F>!Forg/mockito/internal/stubbing/defaultanswers/ReturnsSmartNulls$1.classAjAEL&]eEib =3ɘex(եK ~u80sU{WwV%!VUg[&h+Em8Doe>1:ANhet"Վ됣Ox{}Os E_{g0Z8I×kOֲ-‚:}I{!yytu{ 1[JMA\SrwLozv:7ƺgڦ$`;w8.!9y=+*0!0sN!L8."Xx k$P0^OGKt_8gmuj? 2gBaIf{fqnC{7P0"ʫWq|DIY̲[Nʱ]۹VMңS1p+h 2="JG A )p9}1Dz%|,p)I5Bϔcs + m5<y2-uGp6g?UQb'#7Y =_(3*PHFGc:=Ʊ/0s_F5hڭJMk<y㓶+NMuk[wMn.M[ C[tP{hId]tϓ~E*Hr n޴ FV c<{!>>}N#q%[@8FqI"6La&L?a - qO"-£W(gt|5gS:6(*Ͼfȶ-T b2u vXwH1|g|VXl{\!)apOCYx %9ei1TC"BYHPK L<Dorg/mockito/internal/stubbing/defaultanswers/ReturnsSmartNulls.classUmSU~.IlRJ)b)InSUR0PMM4inf7iK0mG㳻 IT&ssyι'wi|#ڲ뮥+mS3TTCcQc EFቬrqoNh. .MN ,~4MCmzۭc~;:Hڿ>aoв)o님ݜL]ъ45:|O ȨiUEz)˝V]]q3U(kO<R:iӔt.RO|q@Cu?Gx#(!0:Knүo5@wP\CY8`~0eR\C(-73>Y%6Sˋ>=|ǩ[}/0[(>(Ѿ 4)LJ"(x©/:py[ԕE{WVb0T6Q.̄ $]j1! ݙFulX:@cӀR. 8Z#Ihh n.ZGF =< pAUé., DodP9쬒#` *"[KmNLZME5Mͥv Ncʠt ?2޶$*Eswn>j:_hGFWNH4tJ'bS{-0+~9\ XH3l4`aͼ2dd !CRmð! CRvNNJ{ Sj}Z]#| T{jZL(_ϣ0&0ɐ3XPJK20~10ǐhcKKNşW!/Di6%(q I- ]q$*R4!ENqBFyC,S'$(}٘ N;1$LWWge(鋛!rrfuQsTJ9gHpͶ#cC}^kA 9@)ˢ0żLN#?jUJ_fkKY!쭮n?PK LJג2DT>װZb8{V#cuQ qL5F:KW]֑S N'I6xfDͨf@ ⴊ2! Dw=33qnޝ5"Gdyeۑ3q5Ybțg ӷEG^W@`rZ^~dos,a߁V)wErB͠U{M5#zʫB HD/Fy!ͯЕP[؞ܱz$wsYFZ^d0N1d!Ո5O/wVoi{gc,y%LB"Kuo=e@]4Cvʖ!>>Vb==ge )|X.?Z{48#7֛JZh. ҚK7 k 4*a."#➗ڔlhuN,dj1%fkD&{~ŝ!()@(n-|AkT/G5#C;J"0 5G&tJIܞ~wWEYO` \SBq`ғP}ZJ )]ZràHmIt)GKx>١?dD^AwN^$'NQn>+Zg}4x'ªF+$XICFN*{wd6="I{6^ p.Zώz@e-(1ďf_'cN_[<~baӣq{PK L<+org/mockito/internal/util/IdentitySet.classRNA=ZZjQQ"VkĄ D ,vjzÍBM| h#x1Μ;9~+x F(jz:0*  6B+2xϻG4Mtl#zhmK:8T6#h)w\0 Gt!  <̾ =%s00R$ҪD.My>}+[.Q\(^g ݗÎ;ܞ5X¥ޓ.n\Dj̩u0JeDH]cJ^v x< *{ߑ]_@ׯ:GQO=վ!HpMxڴg8l ^GKa=*np91csPJzj '<[oPfY|ǿ7ȩ=T%Nj]}PM4*E'EV,[ꉋZ f)':}Ϧfx3 PK 0<$w;>*org/mockito/internal/util/IdentitySet.javamPMk0 DOIiePTh١[I:vG2gڎ$/isxP:xO3l5?r*ﴱwߒư³cIVIp-CYl{Ge24?An0,#YIPkb!uD!Ak?Qͼ-@W8pɬ@ȝw;NCMd +PyWJQZ"S0R6{<*ÈZ_A+,MHTC61`#3F3=G~ͤ.'Mw-bWTչPK L<#HJ/org/mockito/internal/util/ListUtil$Filter.classn@ CIH/P1 UBBb ]):^KC! b=0$+WP mrVQmRC1Mr+0Җb٪"axb<W_11!m"W?o яKܗԨ5ɏ"OKߑ:fpKFy-NO"ӟi\$(w 3t$fQԘ]?%Z5x Hi崟W)DDO౟22o}PK 0<6u7r'org/mockito/internal/util/ListUtil.javamQN0 )>n턺 .6q)-M!w'mǺ|Iǎ3 ̰t헧͖w=NS-ml4$#KJ{Vo\=$+REhˍ[edJuL&y.lъ?"ՊGiە!G @#Xr<gL>A[_T/aǸf+Fr3:f:N8̎M3YU_k=F_YMTlsFKqפPK L<z5org/mockito/internal/util/MockCreationValidator.classT]SU~N>!lCJ|(!K F`t^-ˑ\vS{猿^7xAgt:]J2㘝<{޳KwGgBTn(}rvcj뾴BW'X<־ pS ]Y7C 2cD*%:p@eVw X_|$poj;hkS8iydEFswA%p?Jn*F1Q2-c h*/\.`JGz0ĭkg ´E-[v`~&[zg GR"K u_kǔvxM`֚=O{LzVC7+˖<[ÒzD\"uވ9TX 0ڛ6G@JQٍsy#G2cŞ xK]ξm9t,Wzd֮,t4k ?Wݖ 7-זq?ֱ!p%heuPlJ;lm9ً/re}r D3:rSiY} ^۷r$g'/ o?frZ[}S ) jgr:I&0z'\]߮c*!iQs/0Ƿ׻|cRa7uc|7q+~ʸ<ե?9]j.\ˤײl9ٕdNjgO)0*!ugk|:۲{tLJY !қHEtg"B5Iifӛ}+|TBm kg猩yKv.萘&KHGTسd%TYv)/PK 0L'TVڸV*A^MBŒ[xuzlE]UFmt\+QXcv<~$"xw.)> tvD|LC2?\zY tQ0ǒE&b}b->z72ش0Xh[3:DG]lŸh)3ܛf= }JW$lrm^G pqr4Ww~МFt&T¬Yrm]ޡp`+,Qq%p`4<=IvQO 8-&6Q/ϒ”%W,àOPK L<+#(org/mockito/internal/util/MockName.classTMSA}CaTpI  f7?`iW' = B8LO7oz/)C挼})|]۴/,cf+ӰL;gllFMycd+LKC cBBs,5Cڝb>zޣ.GR^,)"`1U R:bE+#54OKJ'JyWL؀۝F:ٛEUH"He %7]-c4 D HԄN݂VFnY3L>܀@duLtcPMijMONEi#2%޸;BN.<$FYRwMו̔laΏ,;]cΡvIU%T=Y_nWxbn]h,\QRcfW2^mH^]8\ 3.*PQ+kKdUIKC+[;XiL=ɖlEkHe8pX=_nnz^3#Ŭ-4n~iLyqE苎932lX5r=y߇R(xIcJN7,E%4Cp>l,7@8dʍ^EcL@ٱS21|OZO,6*B;.#dL0E+ "ee F+9nO&l f9=A%(qڂԲTN7yE12^sw<;ho:a³.ϹQ0DLo-^hɔb2WD;19Ⱦ5O}7e8(cK,//EvJIJ,I*6qV`ǼO\_Oo |-/*V௼VЀ{N"}=\G&b716f'?}-` Ρ5+y6Aý|&LZ\nyy4mylc[9m\Gf,]gg%TFCuGjGh]_8Κi2^eQk8j ܷUOO+4e7Fw2\48w_܅P)gÇ8uq6n<<;$AY\\q n+#E4)gaĸcb4O[ۘ6Va$LvbtЖ~n73'RV8t01!;39+3kx\`&rn.\-F(Ư} &W-XϚq azY(/r,o&A?ѳDEz+g̨ 3ҫ-3%4oq&"Wg1y!NjyܐE.zm{fEml=J+z|fm'ym=mtdW ݂jUXaC<j7Q_|I΅czbcToa?D l?GW,6 jwy{kDM6x5i[WS6~C9!(eO F7^mw?o|eEkǔ?PK 0w'Pm[0`ꗈD TxYs 6t֚XͶaHDa@vϻbZpl4>E+z+( aExV=_[]W+AVlxO3,D!zU_> 6f#鍋 96|&lxrXUaL -/'/5֚m\!ub,i!G # \?p<|ZD?f8:IHLvjCwt|w95T4'A!ۈ^^]4:ǁO[qIym /{R"GQ 7T'"8t@;M%ۨmFA$;->! Wl}q>‡t~= 9+7hr2dI8S%rFr6juPJH'tYBK}z>r2֋r% fJ *Iya۪/7ϰǢ\2h YAo?~;Ϊ"IM]}r9aksV@T1Kφzix~0(͸QJ1RO]D|Ԁ@{vwk@ ꆁy{qGvI5FkhIʋz?x;.] Ssj_dkhz3\!bPK L<Ӽ-org/mockito/internal/util/MockitoLogger.class]1 1D36~V,5Cz8 DN1 7` a)UK.$<$yXkfi:X>{%0!^,aѴDe9ojB 9Tj0tPK 0O!5 c 'X0NL? 7fY=y&_uJbvE he0.AE/VbyYM-~V{NyvU=LMsCy :d9oao\M'n 681Ơu&agC;.rW0È҉Z}OsUB v4lG3tpaHi70DZe~Wt/$eqZ'7 (v(ޤJ+5:/>DPD Zi_ڒh H|Gi~ \#I!B7%}ΐ%h=* HQ6DEuC>BRjR I]#x6b(ojEm^KJut5#uQ̅:_熯Ը3{(_PK 0<=0org/mockito/internal/util/ObjectMethodsGuru.javaRQO0~pJfRTZP'6$M˴ǽ:ǗN'6h*݋wߝ8sDpe3XU@V'ZP*KµkJ\#f|іh~,/Wp)s4T\r@V21epj|8TYp"vVq~5ZݬF2³% WdjjsO-\+Bsc~Y5K4A nj=AAFEd$ _./`oǧdzMO&lr6?D ZuXIHq¢Ox:cȼdR{cI  XAa; %)h/R(7v1G͵KFkw-+l=Q(}~{//Y++im NPK K< P *org/mockito/internal/util/Primitives.classV]SU~NloRjKI|%4%D0daM7ZpF{ƋX3^;/ s|O6dԡ0s}sޏ/7 㚞 iCBjH**!+u]> X*z.bH\({ e  }w`|oHFIW7E$/Q{F|_,nّH_Vb129N8 ӛ='N~ը'kIȪl3M?Ё^#/D<1#ذ̠0 Jm?…!Y<ae5exO:aS}E.B[;3CZpM3\m#ukSN2(,dB~\e Htڑae^3p,z0ЙUSQ{ғZIQb$<40tGJ0Z Eoi$|H;(uGed¬7qbY(Q,g #£mY*TPy^%j&M' wZ2bT^өWW' 9[5$eBSsStD@-c&Җr- lӊVUHmtR" Y1꬗NCq>$C;2xkA7M#TR?~ͥOsH"SDzG@Bˊʦ"IOߖ*v%ݨ" -<0Iϵ@[kMayY )gH.>7~ˁH d{l~}.zۗF͌ \J4MO1u`19*1<o&b&h~dC޲q֥=&N{q{}BxνZ)#hr=xA;H?h'=2Z_sp_lH*rM*Tp' 7mfs/0Xȸ+XhQݵxqݷdImXPt[ed||nA;Udz+Ϡ gY eH-c߲e,+YF޲eȖ)v8<( {5zs;e}-7S@9e+qlP%*T!s0?;N̰A`0˦鳶9a&"ҷ[̳').akPK 0'&̦\qwΆ~a$ʵye| >½T גR5IAR/,xF0e8e*>#tA@T qf+4^ K-ܠ8fq)=,d24V=.:~˴*KIzĒS+tV ق"J cX)xtI5]F6Hi+͆w%hT\^$jI$mYET\S~5jpW9,:Bb*履̷Puȉ~O]Ā]// ڐ[  4_cBnyX>S+I+ u O$îR'lG-f &X}nw^YitcU hۯ~T`3sc ̝,#D!\7kM\F(5Pian#q W(ɝsC[ # 2 4@7aWAqSw177vY`[# @n@Z.nSh3*9ftJp0QnSӾh%89:3 u4l,uTJq!u,5D#eIx [ z=dH!%+/Y$a<#['ڶz$m|0C|`|l`i"e]n HpfLy&e>ޠo{b:qM&%o)\(:DW}@\E@!xSpL#PK LLK\ @±/=oB|wGA0a?]7g0oHP'XlOk-%|DR6R:4ĕ!2j }$??,e2+kC?e,&#"JK 2*By:gjk-9lp6k_UiVaU#l?PK 0<{4) +org/mockito/internal/util/StringJoiner.javau=o1 ;R %%QC>hA>v<_4RWp7!;cˍIojVԻ2V!F alϖb4)#ީF(i{2!BѠJ ^y <{-p+`˒rQoQH)#-4Uci6gGpq/7WTi#wTB@*;$˪:_tng|rtU`nnP՟Mz^PK L<-8org/mockito/internal/util/junit/JUnitFailureHacker.classTSW.(6A1ZjBVk[IRP `;PۧMraKw/t:ә>Ĥ{wss;}ݓw"Ps"-=g7RR;kѺ¥!wDc8UyNcazz2/J:0Zbi )dR#C'Rc8j>恒M8PDJQ-r-}$I[: CZg !gqFpJZ~AyQ E^M,4ׂΫcR5'TNu0V.>' N(܍ k_Hٗd~ ( >5Q7SAS6ILISd;MVȾ5\&IBs![ /HzLblrL,ߣ^ PK 0<(cD7org/mockito/internal/util/junit/JUnitFailureHacker.javaSMO0aS /ꡕXq*Tq`.%1dvP9VUydϰWۼ8]V .zBY`J{4ΖNn˭ԵkBk6*B EryOxr>kz%Rlw mh}ktXg6օm CNt 9V{:ӳ&8FFV:oVIGEM#p[@}(7m^kUKqqä{~ynw>Zl2?b<5{aJ<,vA_@ٶ /CrZgV۴\.WWlZI<^gb @I~lj*iJf;5hd Զ"}?]} q; ()ctT"):=Lՠh^)CO} fGnCu BT0H?(L}%c ɝb=Y8ȟN#Ng')atEgocܝ~ȭI Ww>a-ں+D/O_qǶT>'ÿPK 0<"L4&org/mockito/internal/util/package.htmlIO .I,LV(-) PK L<1J?org/mockito/internal/util/reflection/AccessibilityChanger.classS]OA=.,]J | eOh(OE Mmಛn!?DMQ;ۥmby1Mfvs=N 3ށqZD 瘶mxns+clX}Q6M{*ȑyb6];#B3L/K(Щ_m0Zx67.=Y%|5п.`5(uCM a%8>CdYYTbu%1k|HޡJ1H2 ƕמ璟&3qDM:TLC:1a kS1Oorg/mockito/internal/util/reflection/AccessibilityChanger.javaQN0 O?[C;q8mҤrMڿ-tӄ!J|KX$\V6V[Px]뭸V[ 5x@ָIWv`y+2N&T{, iwKAu*ThRy3+>CT)IҴ; FY)rwٟU`g_{l ^ՄFR Lur_B 'uC;A7sHm(s1*x0祙7#i*j/1YLgPUɶ{k,X oŢb.n+E!~+rk}lY.4E^3M[PK L<"26org/mockito/internal/util/reflection/FieldReader.classT]OA= ₊m),!|!2elF1b"%DMQ;5Z 1̽{{Ν~`=lz[!=SU){\sCpgv1$wXn|Y: (E`S .-%Cx1emO%0 4lYCJh>ϰXU敊( G0/ WeLK Lv[8bfozH[G:AvhсN`йk`CA 1/?{j-u>Yu7 36?R/w=ℳ!]d_ŠY*|tؒpkUcRHr]O>hT%{F0t FL::.d98H f -m|21t 5K\+E:f0fP,K VY]c+ .co/ӳ-g򅚹j!iEaH|˫6(i Q$PXl:z˝ ;Ercs1t_gaFp <OqEN EaғD/RuidC !BDOhOE?O1sIR50}ORDp.l9b-[ V⺂A F^PK 0<`uD5org/mockito/internal/util/reflection/FieldReader.javam݊0y!Wv.)4E --}2gW46}-'UB~fOn+]N5Kf\q!6b:qO6`{ PüxؒOd&j@-A鳛a]tpd߮WCjf7_ܾ,)%鷥aHAu_= c؂ur? q`łͳ`lIefny&ZJv,]تj<'煭.0nKz"%D">.͖S,K`#O|.I\NI賯Q*𠷢XAu~4ZO^~jC%! !>{ S7[ʹ:߀~PK L<գf6org/mockito/internal/util/reflection/FieldSetter.classSkOA=Cв؂B[ (ૢC$2.n"?$wn+ag99w38nQ/9g9=چW} ColnrzdvW6}U*Đ0|"PŅ#2reEslC eh^ Owg`+Ъ#K{+>2CeђE<3 uU цv$-IX>LBk|qZ Ӂ4D"$z0 z䏾n"LZ%Nߘz V=Ngofizp* C5#Y_q$/%BUdz^ڃ~ĕ4$]DW~PK 07w؇-Eo@NAյEp~_notUs^<FuEM. h;_+zELY WWv)P[2`_2&d$2𽾗:4o1'(*by6iøXSKg8w :i&"{vgc0F/[KR0~ߤTۙХ-jn:ieJ@Yͦ}cXcspL>͏Ŕa"" ~o]e܁ 9ϘbuJ ,N$= FzPK L<"o8org/mockito/internal/util/reflection/GenericMaster.classRnP=Cj< S,*ĂTR٤AMW7έűcO nXQ; ,en|̙3sۧna-]{8Uʏd ώ#١<J_& BP'|~44De]1M?гSwF0ܳMm#pe8COʗ;x()= Б[ʓ _~2 }̯~wIzy> 7q>-~>힢z{G4S[面ub^.%*mWYn+jԀ3pK$PXeteԸXg&zPK 0<iٺs7org/mockito/internal/util/reflection/GenericMaster.javaRMk@9HjZZCj,oѐl5NA՛7oN3/f0k5Uw-;u"PxdidҶrq_&^ͫ{|-p󒹥 S q1@oUت_8d x_AS;]*iժ}0Ht 3ZE;_xc>ɹE&GX}1STU5`N⊣^9y$Y!g/)Çxst*t> YgN:꽸YsKdTcUty| zE[mjz`4TTfQ1Q7?a'GZ438z/C5놆[l DG1!ʜ|?I]Gmh|+ZwգI|8距k\# 9kǸ%o7] ϛN$ޢԂ/(Rw]ėʯhsGHԡ8B‡!$p A^Ѕ+v@hۃ IC/C"ˇ/>E2ZHR>DJr0L)X.KաK: aLP/1y(q2惁Pw(|H>!;~DS1ژG0+:,z՗'~/~ƈ κXr5eWNRZs c 3J=er]Ͱl>~oe!GÜ 01)3hHPK 0|#F{KmV5 BIsP- ]80E\epM4LǣD0LM4{iړJ- 'gxD8X.[}zI7&ForiѹjҥKj-+LW=W$A*\&>(3FŘ,fT(vgyWLf4 Orm@ N2(YC6_JmG˴D&F#Gl@Z' caͿx3[ǵ$oC">A@*[r-mߓ&|mq)sL,@ẒNɌT.}Ţ:M@6yyRQ hBH$n#^VeF2I؃]wߥ}9)W7Q Ov5h6Eɮ۱}a$y,tzմTt7͒Bkヅ T>k]G/_db8QZ]_MC˳ PK L<%x 3org/mockito/internal/util/reflection/Whitebox.classUmWG~Fb"\Q!$j[%A Dj}]@nvs6~N+~O={NJCgf$Jw<>߿#9_WOvm7k9F`;y_9؞P=C>[yrwV#C>jY vv`J#=D  t AŮ +syep3+V .)4YJo녱V'#O˲qXifNG[D/@?]l^-}/W L[*"(8cpּ.rYr釪q"Ad P`M$!VM㻫wn`WeSw-4$s}f]\2kX)#4}Y@ZoV-a=LǮ]8'IVr{OTB(bT@ \g۴kuRҩ9bزѽR_ z/;\WG'T2I= KD!U=I>DR&2%:c-h5lgUq$0Nز0Xn`VwTEu2ivaj56Zk1E(2bFuhWX՚#V[1PwEQs449q\ UEJ 0gpu0xTYܧӪ~T5ϟ R\=k:߄_\(/w^A?#lxR l9KoSyߢyەFuEnjۮ%{ݵt˧S (y ,lG l@uB[ | el%'P H iK7I6̐*pfGƳ0P8F5.綐~1Cg!CgYshaBC&S/ (lljN;qqzx32S>F|fbN4 xȌo M!AC~>d "2dwg#j6I:(h 08\JgC{):f>d,E3b-fⳅ?0IԮ/[rO-pWj^Ⰹ-,`̐Cb6# eR|b<8Gi%͏IkZddSacugǍ/o閅Q)qXwlNw:Fv T_PK 02vn /org/mockito/internal/verification/AtLeast.classW]WUݷ!|@)5 # B Ң:KfڟZ>櫮Uaլ>\;*!ɽϞ{=GF jgږ4[3,Gf-vdX3Rcؖ6$sW6dUcgC[:21kgWe6iJ?Kx<R}@Ψq{rĬ@ͨaθ/2]Dj>\9ONɌi+zNjIo~`ڏ&9&m6ravºiڻr5.-7"CaG7hFk nne֊ίZ;gCH ҏDwVlԺLmlNKs<V0:yB/Nɮ@,C? 43akDO0v!R +MOnC0,Ѻѣzݔ#1+VKJ~9a>TZJ*UT|tLwF#vuZ1̟8 ^y/J[?Q5p[=bMWx9:OXS$ym"=:z%/G~ M!_OơjrW="2Q&仄oCx2!+>"U^=5 ?HB~|}߬Az\kQgVBո3mת?PK . a&53)bHO+!Q2R4n(tRB0b rM`Ei UD"a[&XHeBR82mq_L0M*Yy"+#dFMBvKЄgg;5"J (yFɃ"c/P͗UseԲ gLk& XgWCr(4tYZC 8cFĂ+-% le*:/jb82+% p e1 )f(r!ņ耶*L _Z7K7W9f!/l)9#R"`7U|ecS~y+Gupy7us iRo BwU_33֛؊r(v|::Üzܙk$k6m8y{ml:qgEڛd*c.D.W?և#ߥФJ@p0{A=wPK LQr2@p^k6ۍn v [x꣤dX,Q8a,+[y+L!-ЗnP ! gbH`8q_w"_UdGb-i(6eN;21LVviYΞ_HWEdxT*\aqG z/;L4Vg>l>4=3zlQL \KoղdmOYFQ18f@?M~6*pЫEN{)ueW5bQЕϐ)oaA\꾋+~> q{ t\OY! @8S(h}q_ 꺗{ǹf6+[nݐ,4^ֈJ;+-9m񾬜HwWn$^C>Ci^ԛ!i9m YSmܱSEe`Jƺ^7?NۭueI\t rOqHB?(cE%tn#$c a}\'7W:`i?OxĠ !a\(R L25qQ6+yyf`,RٹNH2WY_[|C2CbFc%<:CG>Fp6y標AEP>XnhmPKWwiif:y"r/`PK .<;@-org/mockito/internal/verification/AtMost.javaTn0 +P]vH[X;@[شE Iv Q(!iG]ʗd0ɊDТvX$ ѹ)l$)PuDph :kwpO GLV2G&EWJPɘR*ѠH(o"jGJܓuxH Vfwo[Hw{mQNn?K,(|iVگOmd8!+?tr s"WU/%(i-\Fa0D(^F:XFC],|˂f#Á P /Nm|B(x< .`fF[C'3Ah߶R;J5l˶vd oov)X_ 埰)/vW}U.rtJU@dGWA# C#; BAggȀͻ%AГ.e]~jw|:bQ/;Ȭc癷$n7PK L<%e:org/mockito/internal/verification/InOrderContextImpl.classOAǿC+GÖJߊ j_PCbҤL|ޭ8p#˶(=VEvnw3ߝoOx&Ijw~KC6N[p-H9NM6[6v3{$PSC&[=9s1=\ ,ZQV03J1a3?pXövglmJ͵n}EpGAT*!d H[$lNưv}퍴!b#x* !+Jrǿ);%4u35@UU/ѯ3CvW~Oo關h,TʐI˪ec7]Z}9mZSTwQ,6q]KB(cVb ,"'|da!:nHZ nVz1{Խ5R6/7mg,PK .<7-19org/mockito/internal/verification/InOrderContextImpl.javan0 >ډSvOS,$Jnhݗ B#Y v3jO3l:;Pre)6R#NAhG` M.r F}EyFpHdSFthGJ29ʳ<ƻd;7JEyqWLF-ߑOSu~Тo+C 1mlT`QN#I6;J@#5i >L3(m9B{ m.b_sʥԺIPK L"șEMBK|pD?cT m."q+ 㗘`j1g1KBb5}pt]b#ɏN3/@u0,߃ 6Cp{sV:e![콶]؁XAx YFUAmYekx✔#i3+ږjR(EMg|ƕKP{R&5д21R7:* Z?PKEW{&F ٽ1Lm1=noPK L<źfAorg/mockito/internal/verification/MockAwareVerificationMode.classN@vL! a/YFc )@ N@8v&486мHFÁ՝RWW*]EZN8td(s&"y =0p]?hNHxq S3kH̻5~*[\z K ̑1"O I *VL()LMWf _1aDz($ul|iyD{(HjeJPK .PK L< @-:org/mockito/internal/verification/NoMoreInteractions.classU[SPm;TlQDP 3-xch`Hj2;%(3>rܓR2By9fo|7Yl0Yv^;߄citmvm'#,S۶Җͷ;=+-Es_?5C7>:  j%5LCq- KOĵ-sqۃPkHj N!S3a af(2̧)>A1C"v 6tGOٺ<ȭmqSTHݲ*esg0*"15hE'F?B CvdzIx!QnMe=# q( .1=/X#+ "*+0kNg㨟;idOdaf*Z 36OaꭁBAI*B"2 ՑYm{P}9פћWIRpo {f/:YU]% qQ%w Q. )a.}Ku¥kU|Sch܄V<RLiZI2yi aψvtоJWk颵]ew _3C x_Q2/Ϯ^/&袱I0dz]k/M $?Eza!}%MSoO_ݧ1}w'nX&x`OHASR `n'G:BF2PK .<&|9org/mockito/internal/verification/NoMoreInteractions.javaTOo0SG w".i,N[~^[;sfxX9]e1{;?PK Le@H ,}5i "Ы.j&c^¡n({iqƢ%f ^1Dweq=?ׁ?eݷd>jhcsV^N Jlj(HLv`CHq(QMELONGqFcӘqSV#L?f?dUG#ܱoF$0ʷf_`F뱔wq=q{ѩw? Vk1n4k:6~^`HW`Q o:(V4s;:wFm2Vٯ~ wGI3|Mo4-w]I]V+3_f[Bx~Z 8` `WTlR8$57v/e_-Yҹ}NyArY[nHv}_5iex! ;W/ _SSp̼@ ={;8J11g(_>[=-:u'q Y Z:F .2En2c$;g]`Z~dCcphs=xoXPHF(?-kEL+~fd޴"xD_ Og?ֱD&70rpV:8+Lg!Cn1F4[8K@6̌~>PK .< +org/mockito/internal/verification/Only.javaTMo0 ='@CaCb_(ހ[ϊ8\lɐdwY>Ɋc${$i__ pTҔ-,D"7[HXU fU4 2Pji^;FN~8-icl/mH.3q.;!D^hրAx']$B+EY_Dk/PK LK*ulWVNp?8 kJm'6@0~Yo~,!w YDŽ磕їZ9bZxN݌ BXnVPK LU+mG>(WCQ>?}wJ?(n_Sco QovPEc&DqHqR2 $řHmЄW8 U;e MXa au(*!^(6Ӹe I$$'nܣQ$_Qg,wtc:\W]g=ܷŃe(LX)\6Xa|ъP?,A y~|T3wcZi{n9(K5AےHc6TGAcj=-yXHk-]}1gJy^6, 4Y[gP;=TbL|RMoyi,+cաrr8 f=ar#WlzOd`}CT..tF\γdGaql x> de9 \wq PK L<5U=org/mockito/internal/verification/RegisteredInvocations.classTRPNFBRQzx"Zou_hc=4eFwDg|ADdٳowϗ?%ϯ^ 06/5.dC"k!U%ۯ1G_l&)Ӻ2/'0ݤ* c6(M 9%]L 3%HhЯj 5148z閟+_E^$&zYa`Gu`@;qd擭{aU0) PIf籩s'8݉S0ɝI_?l(k,qA_d"J!51L D^U;u7WQ\3lmI::O>y[jWyэ[{ "ܠd9uRױ(}y¥`i䥵>]ijWWl?lo/zul3z׵< UkgpMoN`?8vV~̡Л]' /{]~id㻗n@zp?1 z%WOlLX}^ Bý,u5~#( \")%m } F7Ljd}w>? !#cg״-;i8fXZȬjuǰ-mؒ9?@ӆknis2Q%dz k."){EQ-[e]1W@M̰ g\N. T{1 Go2e=''*&5+aGvts[\Ȳn\ ˬupy'kXkQ/vKh ":\Ms֍SO^[2;vlO~j\)ai^GcS%TWC,!^j0@c{|hMn{E|kUcw0tK.V#Xߒ=98jdyGTώ^FZ-NWׂ ԛ{?-$&sQ)"p5iXң i=6ST ٴ6L{|ՠkDq)g bw>U\p3@ 3ϰEnd/-GHE`IBZ][G hdžh my&o=H=l\7@P51WժPK .<Vu ,org/mockito/internal/verification/Times.javaVM0W8%[ET*U+ҲڳI0%# u> ]Q޼q&2{V aGO0ᆌP htu& )הGe5Ajl Qhdx1T1KP(䆤{T(,7Ҧw))Ĭi6V~z|tKuT6=dMF25xF3~%|**JD0:74$X&ʻp5ڮ|%v#.3|Paµ$0zr5S&cEX7R4tXoBVvAC[Z߻`n.Y+[8mQOr,/! $[6m絜 BRUZӎ>λw}5 Vmu=߱\Eb4ߒıCد3 g2[k߬yVmpA䲙老ܵ"˲;6'54O kwi>%êڔU> \^o'fe3a_(~+GXpu'Cު׹-9EӔH0~T*40)T{M?PK L<ƒu<org/mockito/internal/verification/VerificationDataImpl.classTkOA=SZj*P VEhMiY[w?!(_MQ;)*|3ssw@ KS[!m]Xp,n#vDKa[zKۯa0=~u[eeq(0Z W0B ͸ C{N` :}vҮdK1\Y-aͶ$Ѻ",!I5F5NZɂ Qѩ!pak8rS(UEЧ3宠/7㟟]65*K$^T0p%fN# &01]m Hit$zrvWjDeoUwFN5f1vL"Y $F!*M{C:$h 3U%15h|(O?Q qeO4̫&` m.\ <`uަ2 y/E= Q:|yVeDݰNx&LAМSAZ_C;e:qh'uTzS5;d! v <#DG(a/}83~(V3B }! 2'IL>T>5k?ޫa\x='" ԉaL.tMMS##PK .}U5(:nsP:9Y@X2E$-Pp v>l[x&ƣhhnRW!XSdH-jt#%Y-u /AITLZ%vo * 6Oq Y9z(YIUI{8X@:i( \Z2Ž4̢7l7q_s+.:pq/Ȥ#=rjkk߹nNK:'5 d_h!WΌ_Pӳ{R c\`*'Aj~Xv>y(f&HC{DP`=O<nPK L<ƈ65?org/mockito/internal/verification/VerificationModeFactory.class]OAߡK*(R( D/4cBҤ&\N32TWxU#?e>org/mockito/internal/verification/VerificationModeFactory.java1o0C.J,9EU:$Z*;? ᝛j!Ux_!g՞AֳNhp%h |, pƢ&hmI~CI^C>[\+e4XT9ʴ :ۑV5ihӰ_kEyuȹ4mQkFoUpsŠY| _ZEuKȷb/t21yilvњdT(K{x;=3o`[9,cA6w{4`OЬaBU[;| -r=PK LŮ㔌ý5 T> zͰ^5N.˘> *kZ^qm_q[ڶe1ȐtR@;1୙W!u*ԡ1zzܕPK4rUJV|O&'m߅%f pM2H.&wX}d mtF/!hZ%M~@-&hM}A̅ƒ'LR,1g;RN%q"n7#8Ż0$5.l?#t3@Qz<#ta(M8f(qBZ<#h23YoxZ c!`ts*TIS I)BNJlQL$EJפ\nHƨg./]<DvEFyPK .<Borg/mockito/internal/verification/VerificationWithTimeoutImpl.javaTK0#foʠ^z`9T[ P{6ΐX85vآ^?͋DZgx ^9,JxjqNе#o&mw`H+ˊĥ{9!U!l7;.YYg#/4JlLޫ抝A W|&+@ ,s{ZNi5:øGg;>sluQiJ [ ]ҕ;Ynܦ2 ~t!䨰.`s\rڲ*aެq*UMfMv,R8NPI#[ nN bªvwo\:k d=T5|ȁ^I{p4Ġ.)PK L1F8HfDkmiI9akgwԦ':aPRτ/⅘eLbu_GpX:袭NCy2`PzBY~PK . f>p?Mh3T(X[6Z4W ? 3/ywiKZom_0kLePK L<@Corg/mockito/internal/verification/api/VerificationDataInOrder.classJC1Fikk>n .*E(T(::5&^|6>%νjffI?^bpbydN6=8xYj\~'6@.rgjt7&P'.9(ӄ̦s_?Xyb]ƾh K<$!o )941s0Ҩx6ּ?P=NXPOIvTL[&G2/ ,Dj1ܙ W=h-IUax[Ȣ\guY,giiĐ3I NaQ '>GLn,Y*O$b(vT>}b9i{ud/+W@ЭT}LXn7\L/ ?o?^!x&aIsnN4j{AS*u;64 78*O ZNΩn0{otMsAbɏg3Vra>w<\Ϥ y ^kt{ PK LCNFt̒|̼ԢԢ̴Ē<ĂL0$<"TvFFIJDļt}vfFZ@xVTB%4|HwKbI"k0FҢT̜T6F&`dad`c`8$+PK .<Borg/mockito/internal/verification/api/VerificationInOrderMode.javaM@ DH)bAPP5HD48EM$t%e[fviҴpD!Q5Drj㢽2b0mzA3IGeǘBņ2"[?Be)7\sٽly6PPk\9 ԹMjEANyc9\-EM>TXoH;4oO+PK .<V\2org/mockito/internal/verification/api/package.html лS \xi$3NX#JEtٓQZ8)JwI-A6ьuSFPK L<@hMorg/mockito/internal/verification/argumentmatching/ArgumentMatchingTool.classUWW$dBkQ FPZDԴ1&Ū&/dg&Kti,FL{걫?}3! 0Esμys~Ͽ~y ` L.7Mu]sLY3n.orKih!+VTuy#TLS֔ME,qՑdH!<3LWC"Cih6C?gXNeohfl}dvda*s&UtyM˧{eʫ-1pRQ˰0aG%0z0y3IQF%PbM{-t88-b1 KxAj(vo9nVx19Jp#{9qw/ Zvd[ kz[^4 G {i˱/5jf8f+5o{.T/Vާ'$\LR+XܥG-E=eCq)WWp5 ަrm*z/D iq F{TQZcVFBrRRnǼ0 7hX C@ [oth͓Sп  Q{ v4z _ua*: #@=T92&>yN/zs۪mxy?I Ӈ_%}w6<C||)WK#*[=pzZ U.ygkeZ4\3UE_Q,Mpan^j5WՑ1(ZPE=1FfRMM8G0 ;Vdz3ze3mX5 E] q#)r&q ?" g=*Hu.d_vPK 'ÿ#L2Ka &;O_!#>x''L^`bOiRl nSn3Eܠ/Pp8Q^bw c|)8(,18Q.eЕF§ݢy ?ۑ 7e;d;yF >w:uLq`ۮc8,|[<w$WK'.u #o ~G,U=;pN_ö-K{ #A! $ٚ 5 eBd@Ό~޾S>޻2^$4S(~y&gB.}p#0}PK .<ٌ~+,?org/mockito/internal/verification/argumentmatching/package.htmlIOrIM)V(,PM,IKWH,J/M+)PK L< <Corg/mockito/internal/verification/checkers/AtLeastDiscrepancy.classQ]o0=nd0`RW "LJR! 93qǯUB\G>9럿[7N8Vfx ٩t+k2q$űtesK\ 7Sưu^B~r/^7_=? G(aq0m$ .Â?R%aXس lDAҿҕZ}śv47l;eƤ{V)]Ha=Jd6侯C[~|2`?kwzм`Ô6h n0mݞ-$C[wj:\:9A}[9!_(- AqN#ք-KuY(d(k1@JG7 WևSܤ /l Yxf-PK .FA>ڟT$&2M6Me&9 .[\ӜPK L7h_AH!$xb }ZS! 8Et~h@+:ы.iB(O @zdt& Wc'cpZmM6+t+mܠFț{dsr\%n7t/|}Md1jnnƨ=e4[*{6ׇ9謩lAR#Zmp?@A CYNEiѲ%%jj֭X^NL(}ʅv7 hW/M}]EaIF?q?ol$ +H}%_/Rq/}[M_TU'#h|j6n}<<./. ucnC 3iP%ZҗZz75/25{$Y0c"lC~ܧ"#fo0m!O"۔!a?<k"ygnXylLA ]"иq>S"zJC^EzƸX͊u|~"Z}0Xͳh1;PK L'4a)g~pMKd1V[H +*T\W/R"VMJ !.p^ST1 KjlY1?H*2_ u*&wqO0C*b{λ$Н*hH!H߷./92;is(~4$^sAS"D37h.٧s)MU a~LzgM_+5%{  Li&e7c$ Jُpxߊ";h [wQ{(5>[`U=hN,H+CG5\VDݳՅ1/;f9.]? (\, A# Y}J/)%K @=[ LvWx׻523d^ 2GF0tezEP|Om#^}hDA""nV M*S䬑1 }#_1v3>${<|Mt`ֲ~vhO)vN/cs53 %d^"øgw*"!#ER,FhuPYz'o㥮 VPK .< fYorg/mockito/internal/verification/checkers/AtLeastXNumberOfInvocationsInOrderChecker.javaSn0+(҃(ҢW^[K@RNޥ^ 5;ۛn`fWKCF#̍ڐ77օOkrPY[YOKD[I\^FhKf,OBPpۤj#scsQT4c,-HIOF FA&IBeeL'jO~ _Vw h' K\yN:i/'a\5mo=[JJ512j/^@9 *bmo9qvhU//yȣ0La$IkY4!`z4cxQU 1a1$ϢH^xc2iw iĮgSZjbF"9;]բq dPK L<! Iorg/mockito/internal/verification/checkers/MissingInvocationChecker.classVRG$,kv a 82G809i% +l"'oWŢ3?PJHȢ@K/wa2NQ5.l[X/qRsznWw\u.ikHsEc5Ь< WO }v*HuNZaf(p+/e͏ͨ5/$gŽY:ݖuHPq XB>{ _FB6w[j-2BVp=X]a 5]oGj: >F HCI[ w= p 0(G% FmWa.Z24gcHa wս\QdYtu0qV՗3Knt1*^g7ӊYRy_UJB'3i~qBsv^'*X.ҿ&2җJTv.d;ثvfyҼCk =\9k #t=؆i>`CcRh!zGSo|"JKL6wRQI4Q<C[ TUb%bJ櫏Gi"tcx A3;2n.MïxYJN1wINa4*cSGHm&h!OI$6Z 2Ad7~U2}|Gxtm9^O K|O0a ?Gy O!O`dukV$ F4IJ#Sjq,ܢ(1F&wH.F20hw.1U?PK .< Mqf`BHorg/mockito/internal/verification/checkers/MissingInvocationChecker.javaTM0W tUeW\8,EZ*h%NҡNNw+;"3_knoG%!ۻwHFQ+Tڕn!W2Q,{M EG`Pd\>[XLcd9G HD(= ę!EJTX0$iƻcu]T]IIV53kr{Sb(KMʔ=u2)f&u<ݜ*[)i^qi kڦZ)rE'fbP/TqHZi\#* k0çp6YǸHW!ED=aMn.$+[RuȉĬ]j Іq{`VVsԈ47gw"Дo3`[5z؛dCXwl*(=4U$ _xF-:'NvLi lҮk釅^+޳v&pS7ft+f w'cT!";?KR PiqUa((4N톏0vVG [xk87.PK L< LrwPorg/mockito/internal/verification/checkers/MissingInvocationInOrderChecker.classW[SG, *qQeQ r4aYZfg֙Y\lRyLs(K%TT='=RƇl u/NoA(C~<.=R@g(QI@xG kGObb.'N']ܓ'HޠoY DUԤcL;>CcO #y<艭QE1c %'T"~p Z}PpN|C:1C}U.aro|6_B[-7*rvW꤮yAZ*CՆ?[R SJ ak8Oy.(khE"3 .-(j>Z,7Z5 )e[+dܕINJ+6-ʢ %cvьStM>,,ԟ6п:vfg=i\AbHuzV+| Dos~h\upӴ^O]Od Z:lPr&bj&S4h$s:i=E#E,'ŁxC ㍿!3uܛ#K8K5%SxK\[""\70T­T*F{MSQR90!*3 RZ4)|H9jO07FQq&RF2̆_&GeV·(^K!| I^R>L68FVٞ1A-Β琡9\$/;~G\% /_VPK .< Hs Oorg/mockito/internal/verification/checkers/MissingInvocationInOrderChecker.javaVMo8WLor`HE/z0E{`ĵD $$h;D}٭{3|It+if 뷰 FH]5J@KؑHP Bܻn{7wRa; aY<8gZÎkMxµq?GfȂ?jPO&[oټ#X6Lc^ tjTX{zfk>,iR ؋# t+x`d㓇~솾 ]ϡL&qVCKr^Zp\[? y6+Ir!ycBS)m>MtIxMC_㷆u4=kYNATy>&]] ʷ6pбF(%6qj;R[+:CtwMo "8b&ss8y0lҰut1BGȌ)EQLS)XQ5%rt+OoRz`vjmePdom+{!]=!GhHŦby3ɺ'V#3kƢּ?ms/4=Uռ{$ =`Ӟz>lsd2LVUSI^tr >ꌬs4˘iҵ{[퀘<X,wbrQ AM/lزqRs.ٴO93*hV:m}B;-,g.F=t8-N?PK L<˄ca Korg/mockito/internal/verification/checkers/NumberOfInvocationsChecker.classVSW.I$ 5 "VJ 6m+\%\ fCksLgN `2w=?0ikVvM:&MǰMm\YݑeWa;eÞ[I'+Ny @#}S Y'@wm@mlX6OMW1g @WVI 4H3obhGθF4o9rtG1&M b | NG;!4E`nAЦlce-g!wVeQvuG^d~Z<q!NDB.FЈDp MjwI Xڽ%G,:01;tc'S*UD"_N`"Gýd^JxyIE']/|^:\% aX.pݺ%YnfxR)Όpw,+-`Ld^8ޓq]qUS(?¨<֭ RTT+1ß$6b)]=+z/0O)h[uJ\;|3n׌qQ.wvD62x2%QPq^lR Rn |. /&FksÇ[ЭàAr=[:_x/ tr*ZҸ <)u?(!A8=?q°{x |Xmm#D;WAuՂRw f /hiT>$'%X6^?4zZUwxo d!GWN0nP; ڕjA}r91ԊM<:o峝N6y5MϼFǤ]9+k[\UևR(hTs&zĸ< :J;}ic^{:Zqr PK L<ҽ^` Rorg/mockito/internal/verification/checkers/NumberOfInvocationsInOrderChecker.classVkOG=@# eCҤ- [ic^kTꯨ"C?E*)g8{3w?27W<{Y)]`9\H5%^v9]Z:b]sŴ;?U5,Xnޜ>v@NwV=<sΪ3U IEё}+Oj#OYrt GeEcL2Fb9='Dn-v|{O6>tQN`IdIQZ H"h@FPCBNR fFdU;ЍL"vkU;1zD< *Ψ~O-\rtxpE%^L(wtj#Mİ@K 2V1Th $_*~4Ŝ-1&Q$ efy\{;X:]ԛa,ed ;(YWOqG(ls}">FeѨteGLƕ $N&n`MHvp%RNYB>L%SZ}~^']OPZ JSVNw 3dTE)@84^~1c.Jasn#;~(*JFr\5Êo}g.W]ܩ?$X6Oy%,Y]E붮Mμ󺔗cjSz-_亯nD:SymyRi Rgo;ࠏphS 6MQ;W| ZٞFl[8k52o"7Tp^wT-}-[E_I n/1{^{ȊW5RD)5zNx"Nn{pU'(/;u0nOqYMFC>jpxq78&~_Ao4%nmb F}ʗhhH0LByD1R])<"浀 -l= PK .<ȻYQorg/mockito/internal/verification/checkers/NumberOfInvocationsInOrderChecker.javaTn0+(҃(ij%o-I9q {)ʒȏ"J-YBIi][M}ِJ\ܴ)q*@e. Y=J̝rU\lytʖt1l2ܒLlPlQyQY)mᷣc-a=< VMa_b?.ꓸ^^:IlZ$wG{YqLuYHFMA/G+rE-\[S^$@^kY*M;n2rLt_)hYOa__'8[wW}Y3G8ylusYM^kz~ s2&))J_ู f^W'9=' =LĦގi^4[HK+B/~쨸34ڛ"ףɌmR WU3޽gMzqTΩlpzBhi#A"{a+hKӘ/\'y?/clwlZz<{X,qqXDsPCB].[hەЮ#unIv쉯A}PK .<_~,org/mockito/invocation/InvocationOnMock.javaSQk0 ~ϯc{+ʞ = ]cK:vc}\ǭ >}\- XW7bv9\^\\ک(gz }>veAܢ6X6:@{ptY>Vd=*T/8n>Sn ]%u]Xѯdiж%Ɛ B I؍ ?Bda0T9 8NO>eЃBcMr#cO6 AL0Lh%H+6Rm/@p~ȗoLadsM1Ϣf|~CyZ |1SROCoN'#厁IQ'd}of)8?/%9I0 j~44Ȉ'Ve EX:@Od0K8VT*7ʹ>0_ɑD[GOSS:.?_PK .<"j=>#org/mockito/invocation/package.htmlIO (MLΩT(,LIUHI,.N-V(JI,IMQ(W+ON,SPK 0<RFTorg/mockito/package.htmlIOO,W,VHTrr2*tSS` s \Ze6 PK L~L7Q:扰8CII<7GEpW!sif9Œ{$j]+2ga9,ܥ! e0Z|&arP l3gT&0J 7<%F_À+"n5J-|Pv]D]PFR$M^[ 81&iuE 20>! .bICzCh&+2 O0?1v<f70_DI<]hB!v/"&wxafn9AOPK LR9fpp89LC o@6L 8]4s|-{!"d9\/O+gx~J*Ox[ŝ;rR#U^[,$on5FQ1~۸;N"oiZuDRovFT+bqԭ +pz2+]-Cżd:k%!h//s`†䞹mCl=njp /t)r^}R8 -A ]Z@%Ӌ1 %tKDÊOq/)jZ*% \0Yh2cAL<  _b([[ p@)WΰUk)"4MdDݩ,k a]ϑni:UF*V{LK\h_,W $3A։$g5 ձDތDlwaVk6[˕$<]ң|nb 92o$}nM#<RC+Pʦ]QAT@7n_5w\vG{Q#FhAPx>6`@ hPnD%)ܴ>5P-y$}ꖤG: e֚QM27F-9]1 X@REt;5JL!KGG2M >B!*R:yJ0D#l!PR#B_%, Ǥxo~ AAB~oŠ%•0K+%sۊ=TWPlc:DN8r?EzXe_*^ʢT#7n>^x.ȎE2.~v9Fg*Y0RmiLvY0^H'`j{3y=yDżbU#>[=Kl6(|gu4FXzb +5$wr9"zu =#mi}rbnvIOPRa]y68;N0Y{989& LB3u7fMA}G OxG@Yϑ@FioSffVOl+@L>S}l珳ą)8}yf_wӦ<.IqcW g PqMX%G %{}_htWÆ%/><N`Jb=/$:JfȕkЏ(Ǜk|k,iMܲ&+"`J*y!ehd@&%/;:HP\<|)x2tQ4gLGTݫ6qޤ ;:*jOtUҹm˛~UȔ8 mwЎ _K lra?ˌnOSi`OӪhQ+pʹ咭fȬY;ElQ:tVf硝MN,/ ,0ч9Gng(G'KF, ?1 0Ȋf;fbTmGMd;7>%O;v~"[U6e'M~ȓy_{%|f;6?| {V_e?(v}c)=GrDE6{W}gBΫjqdiIriȟm>4P6]y(pׁòHeiok(BlЖCC쓶- X)zWjS{%A[/PK LК +G+R!4Ohe8 u(,O"!~rBXP.B "DPrC8܄wrX5NrUdIF!Qx{yvE^pw"Q4[%ML,N=pƏ  wpƚE{!isHMnEXg,,LKsgk1n/ۮ"~ zNl|dMmy! CϺt.1pQ>ݽog4J6,y6˵ Rި[PK L<{,org/mockito/runners/MockitoJUnitRunner.classT[S@ i)@/JCȌK\BlRF̨ :G9MB)ԇdw;ߞ%1}]uj/C w{%ÍȖc7{ 2&Ω3͐osָC+gUz|T{=~lBT'"%-IYfW qUu6C̨Ů'YSq*ן]Q7 ltm  1ׇ [ș>W  Q\1c6102d@]t7?Q)L-Rqm 097[rW3dף31ݞjLٸ,.CJ@h^QaƷ"Wh B;@KtyS@SڍIp8wq亿%05.U()Ч]9uH*UH6|F[0vxX?u UڎЉj! lʪaCcMF֦Ю &S$P%/Ĝ-d:Кuxş}8H;ƿaiSYfLI _$+n ؒx/s1;l2>_&ZpVΈu`{+jۚl̈́dDhU-ExGe1a' +V!hSu̖V)4vvr|r,F[%\ZߣF4Nh5{&`P3%V2' ^kO[=>[`̈́|vb!x&.!ĮlYϯ(2٧"ɮ='Uln䰻\2U˯ZG޷TYٺ!3pKQaO*aIFsN$F$BK7BUP6V^-]WZ0)E[ uA,25r& Ie@ZD5UE(K`4)kF'j ؽ}Ģ +Ifn*#h]m0F}R&g%l463}"DzSC[D/{k&tzS.>%f[kQ]VgKF)iw9 d4"~֐ː|1>8T4b:Y{5*ganxn@o!C2MYo~/{\*ԜTe³s4OWilTF97HȲvvHF^(9z:*PaBE֛~[?]tQ]Ca!EZ*?}ŏ „?9)rtx^hK/%GG zB#BPK L< 75org/mockito/runners/VerboseMockitoJUnitRunner$1.classTkOA=C+ eY . Z j D1OP]2;+-D?xgY(d3{wn?0`noP-#2׸!_>2 .vKCQmFdNBl?Pb]o"Ba 0OM0ޔ )1L*JY\Lgבa9<@2LUNkw<ƫQNX1ԼV!$uT:tN%.4˸vP.eF!%1#͗HRZUT0|NkxJ;K2ٞCYa&d4p;AdMtԥ!=F:I/9‹$g.QXCP4 [U̳&ざ8BOvnu^/ln-f`tvv_kҳӏa\3O0ŏ\mDGY~rPHT=^o ]hebɜLeVH|IEHh7ZWsѓB&CN.taNӄИ5^G!pghƖyگ41j: !8%4?3k{tJ{'ܟ[#!,J1::$w:IҏIcPSxH(3F$+dQ>2'1+Q*/ڰoIȋH]FKmT,pT3yb^F}OvtYӿ3LRݷ#1 8hB@VbxKdA^c֜A_ݕ_P@]6Z^wy88aamGqBcڼ<.8EAwբn1#-x$c/RfKX5o{;b{R{l $ W[fsjۃ L:G_t#.詫@6K2jIǢ0V7iFT r=#:Mk>lF$Ӛ#N|Yt`W\s\{+?r_qd>QցGz Nb1sosM%qo*zأO=x]c\DZuT_p擱Ĵ2L g=E&/`%J֭uZ;[~S3o&pjA at4X?asnqIݗ-q$Ao`|l$3~`Ze(H>J2C1#Ym:UeόwύNPK .<L} 2org/mockito/runners/VerboseMockitoJUnitRunner.javaVKo8"\eNy`h@GZɬ)ˇC8of .VAQ෷osR>N>͸mTkXX 6^h΂j|JeP3>?ӬA쒵x)2R0ٖ+BUq%i?Wq(~C[;vs;qck/ JWzBg0IKxëlr)c[):<ȧx%E,(kooT?%3d;-~"9?o*2F; >AXT*6jAۺ;J$ QVXBTx䅃ZNZEYCXO|xݽijFymJuQjzB#.Ь@9pK.T3j.cJ|v%g_]I4vBj\%I2Fp9i!}I! E:(pEf W/fZӊn"=ٙ&NRPҁpy5'wR@CLd4R J #vxf6`vȂ f$7toS"R2m y:At'"k7/HXy`<EwÝQ-"0>]`Y[nwW=TY RWRJB>mXP'1&;YHf,nCWa6#ͨ&b[H\1rX$IxIC{hl7x7t_׸B:7dԣẍZpHmRmc!7-/젤XK*rq0m6AUlž_{$vxkXxca] >'u ~9# r up:<݊|x(B߆4x(Jj>p ]j$5Z6zmb49؃{ k/h~ Ma*vXFvoaȕE|Z'xD0HC`Mb4G,V_Q:! y ^~e6QPK .< org/mockito/runners/package.htmlIO ,Q(*K-*чPK L<<k!org/mockito/stubbing/Answer.classON1qW@ģ/&01p`_4kqmM >2Bdgfk0 L;fE(Lm>zp+)r<]jFO{ŨZe$Drq+d0Ί83Gjɫwk:FМ|*QdVkBIͅ+&KTW[>\3u@PK 0<8m& org/mockito/stubbing/Answer.javaTQk0~?y]2h2QXCV +g[37I''N &-}ݧ|KBިv>\]}5g$igT;2c7hO[E;Q4ޢW#84*y%Q[M>uB> LQ-/ l>SmGƽptv>,Ce,;j4J>RH AᳳL(TUow `;TA͗#\(_P /0za'O1j԰>f`Pfk|uW-?vzx1 F 0j&B]:I4:VhƢ~3A/Fs4~0OgYT}$ ,z )&GkX{N`xviߨihwgW-یz1yk"*? >w"6}-9h^5qܠ f=3-75G'C|bjCυL+ZAyl.?PK Ll0M%;N׷8c=m$cf5/l$|cx*}z` D\0aj)XgʢQ"cAp`XC -oЖF1 %X?=ep Dc&ey)}_ގ22q6ã@R̯MD4)^f9R4`/4!O]۰waoiWM8ͭwPK 0<\MkGb۰ghkW|񘽂m$YK[7eiӆd7pF\*J5ҊuC[O—sөZ-ya/Ph֛bQd=.ʋ j8l.k1@ILt)An.|NYa+Ɠ9c9OYzX%(]Fy@0ILw"3E\m>gMIlblkr2Y̚vzr<r?w @[Q ?Po'zv}{ce8H iN'/PK 0<ǣb`gxk4dZ9#icRZ.+#HKFh-ʂ^?_W0ٵ()*XKkTbvxpx Z7ЗGfPc3*zb'C)$o, P`d$-pkaHVB'Y΢ bRrX7m $~DsӀ=lW7mن^ChUrYT!>q:}(T( ҕ3H"!4<>)삊]cf/=vīw\"FܛUơ!"Ĭ"츷?)нX?g] {Owq >c޾D.䶝bĢ_gΣLoPK LK_? ?cr†?J5רJƁ^8?*FPe)c\ &9&T`gHS_paL$lGJueHyڡ> $jUﳍ8Ñ>`/ZrUO94m;5D[h#^*!CZV8iF}OUYۨ4xy.zv༲;U lnĤQvUcs-tzSIR&xT8EtQFu.9n ڟ@`$gMd>{7ěݬz(ww;|ch- oQulݑ:%˺!V-|[O b^7o3%URj ]p<;xfSM6$QHrGy~zv=yni;7JM*:17N̿_L* \L$WSZmU+S -ց_@aْmͱ+⣏ Q/$H}OjWSr753Y^]`Ǒ1Y# &4Vڍ4Q~u73 PK Lxv#\܂D Vt|3Yv,d-;E 4 g/ %ʛgjMO7\!z;ZKg)B˵ע:q{_PC[U׍g0oYh#džs>Zb< $NdǁOa!.J|x%>Ὅv0؜wPK 0<! -org/mockito/stubbing/VoidMethodStubbable.javaVk8~z{9hZJ @odyl+%#-eɿIv!Y[|iF9|RV~ nVWj4Vi@UYtYL,)[ Xԕ |ħ'5,GP:.[dl$B旧''=+8>I1Z%R*a `_JFp>bUk\+/ \0jShH|«#' 3NYfG!Y !?*AX4Q C% @V}EhRt/;k4-sKܮǷb*u$BI%Uܓ~/ &) n8{%s=OV5|sjtp 1F^C!=n<AһĀ16K F-Wch,/@I\߈\27w6i fn$L`w/CVqCh/C`pZ:d^(ep`&SȄ3  MLԇe"Fgw mWZ*&۩GLy(VVظ9W/4g u gjh/xVRUSnJ΄:\cMFIN(, U*&E**"(Wxآ.zzV>==?sQԻ6~t^e?n;!x+onT| ˗Mꛆ~ gQΛ~x 'ڨu N/U"8҆@b%g='d L$RI6 W~3rf>D堝\VGr@XRs /r{%=.޻(K`8%4p%eC&sȤlf^P:Lg΁M&+ jcq6 ש~Ua F([`|EA9*wG}lS[D6(KF)Zq|'gOj䊫7EzŐM]Y.V9#VΗӷѹBR{-$)'Ia=mcؖOy[f~zMuG@пуX&(/2'cQFm}亰}qK o)v<PK 0<2~01!org/mockito/stubbing/package.htmlIOr(I-KQ(.)MJKW(JI,IMQHI,.N-V+PK L/g)1 Zbl?IJܕynKLoʲ C?iΞS0y٭ .c1"0o0,.IMf pkN^`H'Y"#lkGth5I쒬2 _T0T52! c-30W낸!NS!dWDTiv2&Kd+N@ R cW4 sWmT";R7k樕Y#x%4FGM1̶aŵU9 bB#<֐B!RAyGT6vӃ,myzV\3EnkVO/'ҐLMi=^NUDbLHǢ5C3eЛ+bS4{hJ^JC`g~Pb:(.=U6٣O>Pt7ЍFBw-7 DYpH4'K!8AkI"E!93EwȺIQ:8UG.QqcD܍ N~D΃[G;o[Ac㧘N}Ï蟢w[?LL*}uЃPnR bg&):m?B+jSԔ)&/`MiN}/PK -<!%org/mockito/verification/Timeout.javaŕOk0|9:!8ٽ ]{V=1n(+Kv[&nu047O2Ý.AGu6[rVкrؠ]d4:7L,C`;FB24 FZЛ\8*i]f:oYMІ8s|8HڸǓy?orŊ$-d).)J L1_!?>LshϷzmdZ.́(Q9۷k{Cy+7ƛM|n Ixo9 ]e69.;QthO=A[Zd23ow,v2f<-KHu56rk4騲2*{ ѭ/u=v8&9z]@mDzC?iJ?*wA Oz9PK K<1/org/mockito/verification/VerificationMode.class]1 @Dh;:X)Bﺆ,kYx%&VS 30{/+L:}TmEsgU);w2 0+fU-X F![lxU7A8Ks^TfD I0n< PK -<:c.org/mockito/verification/VerificationMode.javak0 W#9Jҵ86= zae$G8w+z]##Zdo vrU'xAycaH7 KwkC0:MbG)|3m6?oJTYj-miP70w,cO<I- Ğߏ~|Lj®S_wZ#( AMɑ1A;EPExZ4ɑPKQ%UhsS̓)PK L<ɝ6org/mockito/verification/VerificationWithTimeout.classPANAeW>2zNB88L'@8e%{bJUu?#<Xo% ¯Y1+&aif+vWuM3 \zT! z_i&΂cBV1BjT% l #sJ!ziB@ +]a5YCvPK -<'K&F 5org/mockito/verification/VerificationWithTimeout.javaVO0~_q 4M41M{Dah{vKbؑ2}Zڬ Cn|~=*{@td0#LHaOT.)Z\ hX/ٸD4MF 1ywjLX UW~xgϪe2'qq ;؞uV\lk7՛tІ CVlꕔw!oH$Gh+v\öóHH@.EyO7t'>])kz >]]rDϤgQS '@org/mockito/ArgumentCaptor.classPK 0<$Corg/mockito/ArgumentCaptor.javaPK K q~#& korg/mockito/InOrder.javaPK Lorg/mockito/asm/ClassAdapter.classPK mN:"!Borg/mockito/asm/ClassAdapter.javaPK )w:i~4`!Horg/mockito/asm/ClassReader.classPK mN: R8L }org/mockito/asm/ClassReader.javaPK )w:^5;t"org/mockito/asm/ClassVisitor.classPK mN:5 "!org/mockito/asm/ClassVisitor.javaPK )w:뚅 0?!org/mockito/asm/ClassWriter.classPK mN:َ.$˶ org/mockito/asm/ClassWriter.javaPK )w:TSp/Dorg/mockito/asm/Edge.classPK mN:)r, org/mockito/asm/Edge.javaPK )w:'^!" org/mockito/asm/FieldVisitor.classPK mN:b$ ! org/mockito/asm/FieldVisitor.javaPK )w:' !org/mockito/asm/FieldWriter.classPK mN:[% # org/mockito/asm/FieldWriter.javaPK )w:Mqb+a#org/mockito/asm/Frame.classPK mN:K% ;org/mockito/asm/Frame.javaPK )w:6K`org/mockito/asm/Handler.classPK mN:8 aorg/mockito/asm/Handler.javaPK )w:(K\wforg/mockito/asm/Item.classPK mN:T; W"Mkorg/mockito/asm/Item.javaPK )w:|u{* ktorg/mockito/asm/Label.classPK mN:C IS"~org/mockito/asm/Label.javaPK )w:~#%org/mockito/asm/MethodAdapter.classPK mN:$1"org/mockito/asm/MethodAdapter.javaPK )w:aKP(#Uorg/mockito/asm/MethodVisitor.classPK mN:5¼I"org/mockito/asm/MethodVisitor.javaPK )w: I<p"org/mockito/asm/MethodWriter.classPK mN: org/mockito/asm/tree/InsnList$InsnListIterator.classPK )w:MH9s ##org/mockito/asm/tree/InsnList.classPK mN:%yS"org/mockito/asm/tree/InsnList.javaPK )w:4N9#*org/mockito/asm/tree/InsnNode.classPK mN: ",org/mockito/asm/tree/InsnNode.javaPK )w:,tv&W3org/mockito/asm/tree/IntInsnNode.classPK mN:"*- %5org/mockito/asm/tree/IntInsnNode.javaPK )w:-k ]';org/mockito/asm/tree/JumpInsnNode.classPK nN:T<2&=org/mockito/asm/tree/JumpInsnNode.javaPK )w:uFb $Corg/mockito/asm/tree/LabelNode.classPK mN:` ' #jForg/mockito/asm/tree/LabelNode.javaPK )w:(l"&SKorg/mockito/asm/tree/LdcInsnNode.classPK mN:1J7 %uMorg/mockito/asm/tree/LdcInsnNode.javaPK )w:<@)Rorg/mockito/asm/tree/LineNumberNode.classPK mN:`?X (^Uorg/mockito/asm/tree/LineNumberNode.javaPK )w:ڦ@,Zorg/mockito/asm/tree/LocalVariableNode.classPK mN:MV)U+]org/mockito/asm/tree/LocalVariableNode.javaPK )w:(g?(/|corg/mockito/asm/tree/LookupSwitchInsnNode.classPK nN:a[}.gorg/mockito/asm/tree/LookupSwitchInsnNode.javaPK )w:p9%norg/mockito/asm/tree/MemberNode.classPK nN:K˰~$qorg/mockito/asm/tree/MemberNode.javaPK )w:\U)worg/mockito/asm/tree/MethodInsnNode.classPK mN:-?(Jzorg/mockito/asm/tree/MethodInsnNode.javaPK )w:c '^org/mockito/asm/tree/MethodNode$1.classPK )w:Ƭ&%eorg/mockito/asm/tree/MethodNode.classPK nN:,LаA$Torg/mockito/asm/tree/MethodNode.javaPK )w:q'΋1Forg/mockito/asm/tree/MultiANewArrayInsnNode.classPK mN:dZ 0org/mockito/asm/tree/MultiANewArrayInsnNode.javaPK )w:=.[. org/mockito/asm/tree/TableSwitchInsnNode.classPK nN:+"-org/mockito/asm/tree/TableSwitchInsnNode.javaPK )w:NAy`,eorg/mockito/asm/tree/TryCatchBlockNode.classPK mN:M<} +org/mockito/asm/tree/TryCatchBlockNode.javaPK )w:M'org/mockito/asm/tree/TypeInsnNode.classPK nN:a?jr &org/mockito/asm/tree/TypeInsnNode.javaPK )w:f3# &org/mockito/asm/tree/VarInsnNode.classPK nN: %org/mockito/asm/tree/VarInsnNode.javaPK )w:0@7(,org/mockito/asm/tree/analysis/Analyzer.classPK nN:c?2R+6org/mockito/asm/tree/analysis/Analyzer.javaPK )w:R`~?&5org/mockito/asm/tree/analysis/AnalyzerException.classPK nN:@H 47org/mockito/asm/tree/analysis/AnalyzerException.javaPK )w:1t4 org/mockito/asm/tree/analysis/BasicInterpreter.classPK nN:# +3org/mockito/asm/tree/analysis/BasicInterpreter.javaPK )w:g. org/mockito/asm/tree/analysis/BasicValue.classPK nN:UDE=-org/mockito/asm/tree/analysis/BasicValue.javaPK )w:Iu 15org/mockito/asm/tree/analysis/BasicVerifier.classPK nN:S!/ <0"org/mockito/asm/tree/analysis/BasicVerifier.javaPK )w:6\S=m%)-org/mockito/asm/tree/analysis/Frame.classPK nN:q8d(=org/mockito/asm/tree/analysis/Frame.javaPK )w:s/F/]Morg/mockito/asm/tree/analysis/Interpreter.classPK nN:a !.Norg/mockito/asm/tree/analysis/Interpreter.javaPK )w:>s %29Yorg/mockito/asm/tree/analysis/SimpleVerifier.classPK nN:  9)1borg/mockito/asm/tree/analysis/SimpleVerifier.javaPK )w:ĩ7a]k,morg/mockito/asm/tree/analysis/SmallSet.classPK nN:Ul+qorg/mockito/asm/tree/analysis/SmallSet.javaPK )w:M{mP85Bxorg/mockito/asm/tree/analysis/SourceInterpreter.classPK nN:>P74~org/mockito/asm/tree/analysis/SourceInterpreter.javaPK )w:|Ȓ /org/mockito/asm/tree/analysis/SourceValue.classPK nN:m) .org/mockito/asm/tree/analysis/SourceValue.javaPK )w:3.org/mockito/asm/tree/analysis/Subroutine.classPK nN:ş< -org/mockito/asm/tree/analysis/Subroutine.javaPK )w:Y|)org/mockito/asm/tree/analysis/Value.classPK nN:yI(org/mockito/asm/tree/analysis/Value.javaPK V[5߭yJe *org/mockito/asm/tree/analysis/package.htmlPK T[5) !org/mockito/asm/tree/package.htmlPK )w:VDZ%org/mockito/asm/util/ASMifiable.classPK nN: pk $îorg/mockito/asm/util/ASMifiable.javaPK )w:7 2org/mockito/asm/util/ASMifierAbstractVisitor.classPK nN:!1%org/mockito/asm/util/ASMifierAbstractVisitor.javaPK )w:b= 4Dorg/mockito/asm/util/ASMifierAnnotationVisitor.classPK nN:9mʻ3org/mockito/asm/util/ASMifierAnnotationVisitor.javaPK )w:Of#/org/mockito/asm/util/ASMifierClassVisitor.classPK nN:NAJ.org/mockito/asm/util/ASMifierClassVisitor.javaPK )w:|y /[org/mockito/asm/util/ASMifierFieldVisitor.classPK nN:bUA_.org/mockito/asm/util/ASMifierFieldVisitor.javaPK )w:Xp%0>org/mockito/asm/util/ASMifierMethodVisitor.classPK nN:(4v :/org/mockito/asm/util/ASMifierMethodVisitor.javaPK )w:_y;N*org/mockito/asm/util/AbstractVisitor.classPK nN:gW/ )org/mockito/asm/util/AbstractVisitor.javaPK )w:zc+ 1&org/mockito/asm/util/CheckAnnotationAdapter.classPK nN:*3G0+org/mockito/asm/util/CheckAnnotationAdapter.javaPK )w:ia&,)2org/mockito/asm/util/CheckClassAdapter.classPK nN:7/YH+Dorg/mockito/asm/util/CheckClassAdapter.javaPK )w:5خ,LXorg/mockito/asm/util/CheckFieldAdapter.classPK nN:}  +[org/mockito/asm/util/CheckFieldAdapter.javaPK )w:\2*C-aorg/mockito/asm/util/CheckMethodAdapter.classPK nN:vު,korg/mockito/asm/util/CheckMethodAdapter.javaPK )w:0+org/mockito/asm/util/CheckSignatureAdapter.classPK nN:"O&/org/mockito/asm/util/CheckSignatureAdapter.javaPK )w: /.org/mockito/asm/util/TraceAbstractVisitor.classPK nN:9\.Xorg/mockito/asm/util/TraceAbstractVisitor.javaPK )w:p i 1Sorg/mockito/asm/util/TraceAnnotationVisitor.classPK nN:&8l#0 org/mockito/asm/util/TraceAnnotationVisitor.javaPK )w:)4o",org/mockito/asm/util/TraceClassVisitor.classPK nN:l[B+org/mockito/asm/util/TraceClassVisitor.javaPK )w: e/*a,morg/mockito/asm/util/TraceFieldVisitor.classPK nN:[7 +org/mockito/asm/util/TraceFieldVisitor.javaPK )w:6l+-.org/mockito/asm/util/TraceMethodVisitor.classPK nN:0; *E, org/mockito/asm/util/TraceMethodVisitor.javaPK )w:W 0org/mockito/asm/util/TraceSignatureVisitor.classPK nN:zW 5$/!org/mockito/asm/util/TraceSignatureVisitor.javaPK )w:fW$7+org/mockito/asm/util/Traceable.classPK nN:3, # ,org/mockito/asm/util/Traceable.javaPK T[5QTS!!0org/mockito/asm/util/package.htmlPK )w:2rҐ465org/mockito/cglib/beans/BeanCopier$BeanCopierKey.classPK )w:mb 26org/mockito/cglib/beans/BeanCopier$Generator.classPK )w:qJ (PAorg/mockito/cglib/beans/BeanCopier.classPK jN:0'Eorg/mockito/cglib/beans/BeanCopier.javaPK )w:S?<yMorg/mockito/cglib/beans/BeanGenerator$BeanGeneratorKey.classPK )w:Г2 %+Norg/mockito/cglib/beans/BeanGenerator.classPK jN:|`,di*pXorg/mockito/cglib/beans/BeanGenerator.javaPK )w:;_:_org/mockito/cglib/beans/BeanMap$Generator$BeanMapKey.classPK )w:^`7 /F`org/mockito/cglib/beans/BeanMap$Generator.classPK )w:WΫ%eorg/mockito/cglib/beans/BeanMap.classPK jN:/4 3'$dnorg/mockito/cglib/beans/BeanMap.javaPK )w:o/Ґ.yorg/mockito/cglib/beans/BeanMapEmitter$1.classPK )w: (.}org/mockito/cglib/beans/BeanMapEmitter$2.classPK )w:.org/mockito/cglib/beans/BeanMapEmitter$3.classPK )w:L A,zorg/mockito/cglib/beans/BeanMapEmitter.classPK kN:s+Dorg/mockito/cglib/beans/BeanMapEmitter.javaPK )w:@\P2[org/mockito/cglib/beans/BulkBean$BulkBeanKey.classPK )w:p3fG 0korg/mockito/cglib/beans/BulkBean$Generator.classPK )w:;&org/mockito/cglib/beans/BulkBean.classPK kN:'g5%org/mockito/cglib/beans/BulkBean.javaPK )w:.F S-eorg/mockito/cglib/beans/BulkBeanEmitter.classPK kN:&P%>6,org/mockito/cglib/beans/BulkBeanEmitter.javaPK )w:s/!org/mockito/cglib/beans/BulkBeanException.classPK G:sS!H.Aorg/mockito/cglib/beans/BulkBeanException.javaPK )w:[)org/mockito/cglib/beans/FixedKeySet.classPK G:WUP0(*org/mockito/cglib/beans/FixedKeySet.javaPK )w:ȎZ&~5org/mockito/cglib/beans/ImmutableBean$Generator.classPK )w:V%:+org/mockito/cglib/beans/ImmutableBean.classPK kN:F*org/mockito/cglib/beans/ImmutableBean.javaPK )w:5org/mockito/cglib/core/AbstractClassGenerator$1.classPK )w:pqvqr:*org/mockito/cglib/core/AbstractClassGenerator$Source.classPK )w:sKn 3org/mockito/cglib/core/AbstractClassGenerator.classPK jN:kb=  2org/mockito/cglib/core/AbstractClassGenerator.javaPK )w:d"?org/mockito/cglib/core/Block.classPK kN:i[!org/mockito/cglib/core/Block.javaPK )w:+fU+*org/mockito/cglib/core/ClassEmitter$1.classPK )w:.+org/mockito/cglib/core/ClassEmitter$2.classPK )w:̅m+"org/mockito/cglib/core/ClassEmitter$3.classPK )w:Rz3Qorg/mockito/cglib/core/ClassEmitter$FieldInfo.classPK )w:PrF H)Worg/mockito/cglib/core/ClassEmitter.classPK kN:z9= #( org/mockito/cglib/core/ClassEmitter.javaPK )w:|+gorg/mockito/cglib/core/ClassGenerator.classPK kN:>: *aorg/mockito/cglib/core/ClassGenerator.javaPK )w:qk&{org/mockito/cglib/core/ClassInfo.classPK kN:#Sg^%org/mockito/cglib/core/ClassInfo.javaPK )w:ME!-.xorg/mockito/cglib/core/ClassNameReader$1.classPK )w:GtƲL?org/mockito/cglib/core/ClassNameReader$EarlyExitException.classPK )w: ,4!org/mockito/cglib/core/ClassNameReader.classPK kN:_lz+;$org/mockito/cglib/core/ClassNameReader.javaPK )w:f +'org/mockito/cglib/core/ClassesKey$Key.classPK )w:'(org/mockito/cglib/core/ClassesKey.classPK G:N(&+org/mockito/cglib/core/ClassesKey.javaPK )w:(ٸ .-org/mockito/cglib/core/CodeEmitter$State.classPK )w:j8a>#T(0org/mockito/cglib/core/CodeEmitter.classPK kN:+Yi'Torg/mockito/cglib/core/CodeEmitter.javaPK )w:xs4=jorg/mockito/cglib/core/CodeGenerationException.classPK G:R*3lorg/mockito/cglib/core/CodeGenerationException.javaPK )w:τ ,/oorg/mockito/cglib/core/CollectionUtils.classPK G:{ߤM +1torg/mockito/cglib/core/CollectionUtils.javaPK )w:qso, &8xorg/mockito/cglib/core/Constants.classPK kN: zi %}org/mockito/cglib/core/Constants.javaPK )w:L$C&org/mockito/cglib/core/Converter.classPK G:%korg/mockito/cglib/core/Converter.javaPK )w:l='rorg/mockito/cglib/core/Customizer.classPK kN:H4&Qorg/mockito/cglib/core/Customizer.javaPK )w:Όl[ 3^org/mockito/cglib/core/DebuggingClassWriter$1.classPK )w:ӻq 1 org/mockito/cglib/core/DebuggingClassWriter.classPK kN: 0@org/mockito/cglib/core/DebuggingClassWriter.javaPK )w:щ5org/mockito/cglib/core/DefaultGeneratorStrategy.classPK kN:VX|`4vorg/mockito/cglib/core/DefaultGeneratorStrategy.javaPK )w:KTȂ0Dorg/mockito/cglib/core/DefaultNamingPolicy.classPK G:f3w/org/mockito/cglib/core/DefaultNamingPolicy.javaPK )w:@0org/mockito/cglib/core/DuplicatesPredicate.classPK G:Q/org/mockito/cglib/core/DuplicatesPredicate.javaPK )w:X@7(org/mockito/cglib/core/EmitUtils$1.classPK )w:-Z6)org/mockito/cglib/core/EmitUtils$10.classPK )w:Aw)org/mockito/cglib/core/EmitUtils$11.classPK )w:zaH,) org/mockito/cglib/core/EmitUtils$12.classPK )w:D 9<)org/mockito/cglib/core/EmitUtils$13.classPK )w:4Њ)org/mockito/cglib/core/EmitUtils$14.classPK )w:;mN)Իorg/mockito/cglib/core/EmitUtils$15.classPK )w:gA)org/mockito/cglib/core/EmitUtils$16.classPK )w:l)(org/mockito/cglib/core/EmitUtils$2.classPK )w:.U(org/mockito/cglib/core/EmitUtils$3.classPK )w:&W͜(org/mockito/cglib/core/EmitUtils$4.classPK )w:}D!(org/mockito/cglib/core/EmitUtils$5.classPK )w:W@ (org/mockito/cglib/core/EmitUtils$6.classPK )w:%(-org/mockito/cglib/core/EmitUtils$7.classPK )w:&#(yorg/mockito/cglib/core/EmitUtils$8.classPK )w:Q(org/mockito/cglib/core/EmitUtils$9.classPK )w:9%6org/mockito/cglib/core/EmitUtils$ArrayDelimiters.classPK )w::5)org/mockito/cglib/core/EmitUtils$ParameterTyper.classPK )w:SG)d&Iorg/mockito/cglib/core/EmitUtils.classPK kN:-%a org/mockito/cglib/core/EmitUtils.javaPK )w:!-$." org/mockito/cglib/core/GeneratorStrategy.classPK G:֜@Z-# org/mockito/cglib/core/GeneratorStrategy.javaPK )w:; )' org/mockito/cglib/core/KeyFactory$1.classPK )w:cH)) org/mockito/cglib/core/KeyFactory$2.classPK )w:i 1, org/mockito/cglib/core/KeyFactory$Generator.classPK )w:Wt '7 org/mockito/cglib/core/KeyFactory.classPK kN: '&> org/mockito/cglib/core/KeyFactory.javaPK )w:#ce"J org/mockito/cglib/core/Local.classPK kN:!lL org/mockito/cglib/core/Local.javaPK )w:%3N org/mockito/cglib/core/LocalVariablesSorter$1.classPK )w:hs7O org/mockito/cglib/core/LocalVariablesSorter$State.classPK )w:6O•\ 1rQ org/mockito/cglib/core/LocalVariablesSorter.classPK kN:K80VX org/mockito/cglib/core/LocalVariablesSorter.javaPK )w: 'f` org/mockito/cglib/core/MethodInfo.classPK lN:5~&b org/mockito/cglib/core/MethodInfo.javaPK )w:)2ye org/mockito/cglib/core/MethodInfoTransformer.classPK G:,1Ph org/mockito/cglib/core/MethodInfoTransformer.javaPK )w:OPS; k org/mockito/cglib/core/MethodWrapper$MethodWrapperKey.classPK )w:̑Gg *Cl org/mockito/cglib/core/MethodWrapper.classPK G:_N)WZ)o org/mockito/cglib/core/MethodWrapper.javaPK )w:Ѹ/)As org/mockito/cglib/core/NamingPolicy.classPK G:@(?t org/mockito/cglib/core/NamingPolicy.javaPK )w:)+,.1Lx org/mockito/cglib/core/ObjectSwitchCallback.classPK lN:57>0hy org/mockito/cglib/core/ObjectSwitchCallback.javaPK )w:q&{ org/mockito/cglib/core/Predicate.classPK G:o&%j| org/mockito/cglib/core/Predicate.javaPK )w:JT\1h~ org/mockito/cglib/core/ProcessArrayCallback.classPK lN:K0T org/mockito/cglib/core/ProcessArrayCallback.javaPK )w:2m org/mockito/cglib/core/ProcessSwitchCallback.classPK lN:/;1 org/mockito/cglib/core/ProcessSwitchCallback.javaPK )w:Oupv+ org/mockito/cglib/core/ReflectUtils$1.classPK )w:9u+w org/mockito/cglib/core/ReflectUtils$2.classPK )w:C9+ org/mockito/cglib/core/ReflectUtils$3.classPK )w: d?+ org/mockito/cglib/core/ReflectUtils$4.classPK )w:]{N8)@ org/mockito/cglib/core/ReflectUtils.classPK lN:@$4C(ը org/mockito/cglib/core/ReflectUtils.javaPK )w:x4 org/mockito/cglib/core/RejectModifierPredicate.classPK G:X 3̹ org/mockito/cglib/core/RejectModifierPredicate.javaPK )w:!Mv&= org/mockito/cglib/core/Signature.classPK lN:#vX%3 org/mockito/cglib/core/Signature.javaPK )w:H&i' org/mockito/cglib/core/TinyBitSet.classPK G:mN& org/mockito/cglib/core/TinyBitSet.javaPK )w:(D org/mockito/cglib/core/Transformer.classPK G:L' org/mockito/cglib/core/Transformer.javaPK )w:F(_(& org/mockito/cglib/core/TypeUtils.classPK lN:ؘU 2%E org/mockito/cglib/core/TypeUtils.javaPK )w:T0 org/mockito/cglib/core/VisibilityPredicate.classPK lN:ǚ8z/ org/mockito/cglib/core/VisibilityPredicate.javaPK )w:؞#my& org/mockito/cglib/proxy/Callback.classPK G:9v% org/mockito/cglib/proxy/Callback.javaPK )w:o , org/mockito/cglib/proxy/CallbackFilter.classPK G:0n90L+ org/mockito/cglib/proxy/CallbackFilter.javaPK )w:DC7~ org/mockito/cglib/proxy/CallbackGenerator$Context.classPK )w:8C,/ org/mockito/cglib/proxy/CallbackGenerator.classPK G:dzk.i org/mockito/cglib/proxy/CallbackGenerator.javaPK )w:J;d , org/mockito/cglib/proxy/CallbackHelper.classPK G:rȺz +M org/mockito/cglib/proxy/CallbackHelper.javaPK )w:o+*P org/mockito/cglib/proxy/CallbackInfo.classPK kN:jEs) org/mockito/cglib/proxy/CallbackInfo.javaPK )w:ےR|(O org/mockito/cglib/proxy/Dispatcher.classPK G:`'H org/mockito/cglib/proxy/Dispatcher.javaPK )w:լ} 1 org/mockito/cglib/proxy/DispatcherGenerator.classPK kN: 0 org/mockito/cglib/proxy/DispatcherGenerator.javaPK )w:-Hs\O(# org/mockito/cglib/proxy/Enhancer$1.classPK )w:q<($ org/mockito/cglib/proxy/Enhancer$2.classPK )w:O(' org/mockito/cglib/proxy/Enhancer$3.classPK )w:EH{(* org/mockito/cglib/proxy/Enhancer$4.classPK )w:-x(- org/mockito/cglib/proxy/Enhancer$5.classPK )w:V^\ (1 org/mockito/cglib/proxy/Enhancer$6.classPK )w:r{2B7 org/mockito/cglib/proxy/Enhancer$EnhancerKey.classPK )w:Y 4*b&y8 org/mockito/cglib/proxy/Enhancer.classPK kN:j_ $ҧ%c org/mockito/cglib/proxy/Enhancer.javaPK )w:5k%އ org/mockito/cglib/proxy/Factory.classPK G:),a $ org/mockito/cglib/proxy/Factory.javaPK )w:}:z( org/mockito/cglib/proxy/FixedValue.classPK G:$' org/mockito/cglib/proxy/FixedValue.javaPK )w:DB;Z 1 org/mockito/cglib/proxy/FixedValueGenerator.classPK kN:}<0 org/mockito/cglib/proxy/FixedValueGenerator.javaPK )w:X󞄧, org/mockito/cglib/proxy/InterfaceMaker.classPK kN:.P.+ org/mockito/cglib/proxy/InterfaceMaker.javaPK )w:J/ org/mockito/cglib/proxy/InvocationHandler.classPK G:,;. org/mockito/cglib/proxy/InvocationHandler.javaPK )w:XhK8Ы org/mockito/cglib/proxy/InvocationHandlerGenerator.classPK kN:ݻ! 7Dz org/mockito/cglib/proxy/InvocationHandlerGenerator.javaPK )w:ϟǷ(= org/mockito/cglib/proxy/LazyLoader.classPK G:tCym'5 org/mockito/cglib/proxy/LazyLoader.javaPK )w:^}RDA1 org/mockito/cglib/proxy/LazyLoaderGenerator.classPK kN:ٙ 0 org/mockito/cglib/proxy/LazyLoaderGenerator.javaPK )w:gnr/ org/mockito/cglib/proxy/MethodInterceptor.classPK G:PK. org/mockito/cglib/proxy/MethodInterceptor.javaPK )w:̈́#q: org/mockito/cglib/proxy/MethodInterceptorGenerator$1.classPK )w:a: org/mockito/cglib/proxy/MethodInterceptorGenerator$2.classPK )w:c9$8 org/mockito/cglib/proxy/MethodInterceptorGenerator.classPK lN:! i%7k org/mockito/cglib/proxy/MethodInterceptorGenerator.javaPK )w:RФ+ org/mockito/cglib/proxy/MethodProxy$1.classPK )w:X vN4 org/mockito/cglib/proxy/MethodProxy$CreateInfo.classPK )w:%o7 org/mockito/cglib/proxy/MethodProxy$FastClassInfo.classPK )w:͓o) org/mockito/cglib/proxy/MethodProxy.classPK G:vP{ ( org/mockito/cglib/proxy/MethodProxy.javaPK )w:UAp85- org/mockito/cglib/proxy/Mixin$Generator.classPK )w:n s( , org/mockito/cglib/proxy/Mixin$MixinKey.classPK )w:zOZ) org/mockito/cglib/proxy/Mixin$Route.classPK )w:/iQb #8 org/mockito/cglib/proxy/Mixin.classPK lN:W؃ ( " org/mockito/cglib/proxy/Mixin.javaPK )w:E l." org/mockito/cglib/proxy/MixinBeanEmitter.classPK lN:_z-\$ org/mockito/cglib/proxy/MixinBeanEmitter.javaPK )w::$*O' org/mockito/cglib/proxy/MixinEmitter.classPK lN:[>  ). org/mockito/cglib/proxy/MixinEmitter.javaPK )w:DhK;4 4 org/mockito/cglib/proxy/MixinEverythingEmitter.classPK lN:(j_T37 org/mockito/cglib/proxy/MixinEverythingEmitter.javaPK )w:$N; org/mockito/cglib/proxy/NoOp$1.classPK )w:˪ "< org/mockito/cglib/proxy/NoOp.classPK G:БoE!= org/mockito/cglib/proxy/NoOp.javaPK )w:.ֻ@+f@ org/mockito/cglib/proxy/NoOpGenerator.classPK G:C *jD org/mockito/cglib/proxy/NoOpGenerator.javaPK )w:ʼn%G org/mockito/cglib/proxy/Proxy$1.classPK )w:f-I org/mockito/cglib/proxy/Proxy$ProxyImpl.classPK )w:?q/V #MK org/mockito/cglib/proxy/Proxy.classPK G:qJڟ1"P org/mockito/cglib/proxy/Proxy.javaPK )w:<#0V org/mockito/cglib/proxy/ProxyRefDispatcher.classPK G:/W org/mockito/cglib/proxy/ProxyRefDispatcher.javaPK )w:smctAH:Z org/mockito/cglib/proxy/UndeclaredThrowableException.classPK G:w9\ org/mockito/cglib/proxy/UndeclaredThrowableException.javaPK )w:ߝTB^ org/mockito/cglib/reflect/ConstructorDelegate$ConstructorKey.classPK )w:B=` org/mockito/cglib/reflect/ConstructorDelegate$Generator.classPK )w:E{D3 h org/mockito/cglib/reflect/ConstructorDelegate.classPK kN:2j org/mockito/cglib/reflect/ConstructorDelegate.javaPK )w:m*/^3p org/mockito/cglib/reflect/FastClass$Generator.classPK )w:7^e)t org/mockito/cglib/reflect/FastClass.classPK kN:`r[(u| org/mockito/cglib/reflect/FastClass.javaPK )w:˿!2 org/mockito/cglib/reflect/FastClassEmitter$1.classPK )w:[X2h org/mockito/cglib/reflect/FastClassEmitter$2.classPK )w:v\|S2 org/mockito/cglib/reflect/FastClassEmitter$3.classPK )w:V8%2 org/mockito/cglib/reflect/FastClassEmitter$4.classPK )w:,@]Af org/mockito/cglib/reflect/FastClassEmitter$GetIndexCallback.classPK )w:f 0" org/mockito/cglib/reflect/FastClassEmitter.classPK kN:o< p$/֡ org/mockito/cglib/reflect/FastClassEmitter.javaPK )w:W;u/ org/mockito/cglib/reflect/FastConstructor.classPK G:P|}. org/mockito/cglib/reflect/FastConstructor.javaPK )w:Q{9* org/mockito/cglib/reflect/FastMember.classPK G:†) org/mockito/cglib/reflect/FastMember.javaPK )w:HV/l * org/mockito/cglib/reflect/FastMethod.classPK G:[7C)P org/mockito/cglib/reflect/FastMethod.javaPK )w:2,8 8ڿ org/mockito/cglib/reflect/MethodDelegate$Generator.classPK )w:s.b[@ org/mockito/cglib/reflect/MethodDelegate$MethodDelegateKey.classPK )w:^j .F org/mockito/cglib/reflect/MethodDelegate.classPK kN:& $&-~ org/mockito/cglib/reflect/MethodDelegate.javaPK )w:9=O org/mockito/cglib/reflect/MulticastDelegate$Generator$1.classPK )w:1 ; org/mockito/cglib/reflect/MulticastDelegate$Generator.classPK )w:fJw1F org/mockito/cglib/reflect/MulticastDelegate.classPK lN:Vo%N0 org/mockito/cglib/reflect/MulticastDelegate.javaPK )w:} @ org/mockito/cglib/transform/AbstractClassFilterTransformer.classPK jN:C ?Z org/mockito/cglib/transform/AbstractClassFilterTransformer.javaPK )w:c ~7g org/mockito/cglib/transform/AbstractClassLoader$1.classPK )w:b5: org/mockito/cglib/transform/AbstractClassLoader.classPK jN:}m 4o org/mockito/cglib/transform/AbstractClassLoader.javaPK )w:k*B[: org/mockito/cglib/transform/AbstractClassTransformer.classPK jN:)P!9: org/mockito/cglib/transform/AbstractClassTransformer.javaPK )w:&m  5 org/mockito/cglib/transform/AbstractProcessTask.classPK G:NY봜l4 org/mockito/cglib/transform/AbstractProcessTask.javaPK )w:\, 7 org/mockito/cglib/transform/AbstractTransformTask.classPK jN:Z8 6' org/mockito/cglib/transform/AbstractTransformTask.javaPK )w:ٷ6/ org/mockito/cglib/transform/AnnotationVisitorTee.classPK jN:t52 org/mockito/cglib/transform/AnnotationVisitorTee.javaPK )w:lmx95 org/mockito/cglib/transform/ClassEmitterTransformer.classPK G:GI.87 org/mockito/cglib/transform/ClassEmitterTransformer.javaPK )w:_-/9 org/mockito/cglib/transform/ClassFilter.classPK G:yт|,: org/mockito/cglib/transform/ClassFilter.javaPK )w:O8'< org/mockito/cglib/transform/ClassFilterTransformer.classPK kN:CTb7w> org/mockito/cglib/transform/ClassFilterTransformer.javaPK )w:C"a6 A org/mockito/cglib/transform/ClassReaderGenerator.classPK kN:͙eV5C org/mockito/cglib/transform/ClassReaderGenerator.javaPK )w:,Ƣ2=F org/mockito/cglib/transform/ClassTransformer.classPK kN:Tb 1/G org/mockito/cglib/transform/ClassTransformer.javaPK )w::W7OI org/mockito/cglib/transform/ClassTransformerChain.classPK kN:eT6L org/mockito/cglib/transform/ClassTransformerChain.javaPK )w:D9QP org/mockito/cglib/transform/ClassTransformerFactory.classPK G: 89M8BQ org/mockito/cglib/transform/ClassTransformerFactory.javaPK )w:p5SS org/mockito/cglib/transform/ClassTransformerTee.classPK kN:e%44U org/mockito/cglib/transform/ClassTransformerTee.javaPK )w:1v 1W org/mockito/cglib/transform/ClassVisitorTee.classPK kN:4 l 0\ org/mockito/cglib/transform/ClassVisitorTee.javaPK )w:<E1 a org/mockito/cglib/transform/FieldVisitorTee.classPK kN:Hs0c org/mockito/cglib/transform/FieldVisitorTee.javaPK )w:9.`f org/mockito/cglib/transform/MethodFilter.classPK kN:WW-Eg org/mockito/cglib/transform/MethodFilter.javaPK )w:ʉ9i org/mockito/cglib/transform/MethodFilterTransformer.classPK lN: "8al org/mockito/cglib/transform/MethodFilterTransformer.javaPK )w:osw2Mo org/mockito/cglib/transform/MethodVisitorTee.classPK lN:Wk1w org/mockito/cglib/transform/MethodVisitorTee.javaPK )w:F<9| org/mockito/cglib/transform/TransformingClassGenerator.classPK lN:c7;k~ org/mockito/cglib/transform/TransformingClassGenerator.javaPK )w: l9 org/mockito/cglib/transform/TransformingClassLoader.classPK lN:hc8] org/mockito/cglib/transform/TransformingClassLoader.javaPK )w:ےEC E org/mockito/cglib/transform/impl/AbstractInterceptFieldCallback.classPK G:֊ D org/mockito/cglib/transform/impl/AbstractInterceptFieldCallback.javaPK )w: gF org/mockito/cglib/transform/impl/AccessFieldTransformer$Callback.classPK )w:=F org/mockito/cglib/transform/impl/AccessFieldTransformer.classPK jN:'@]< org/mockito/cglib/transform/impl/AccessFieldTransformer.javaPK )w:Ȋ?N org/mockito/cglib/transform/impl/AddDelegateTransformer$1.classPK )w:c0c= org/mockito/cglib/transform/impl/AddDelegateTransformer.classPK jN:[+<p org/mockito/cglib/transform/impl/AddDelegateTransformer.javaPK )w:cT0; org/mockito/cglib/transform/impl/AddInitTransformer$1.classPK )w:WB 9~ org/mockito/cglib/transform/impl/AddInitTransformer.classPK jN:Bp78ͯ org/mockito/cglib/transform/impl/AddInitTransformer.javaPK )w:k= org/mockito/cglib/transform/impl/AddPropertyTransformer.classPK jN:O2< org/mockito/cglib/transform/impl/AddPropertyTransformer.javaPK )w:$?C org/mockito/cglib/transform/impl/AddStaticInitTransformer.classPK jN:1I> org/mockito/cglib/transform/impl/AddStaticInitTransformer.javaPK )w:x4A org/mockito/cglib/transform/impl/FieldProvider.classPK G:ٔ3| org/mockito/cglib/transform/impl/FieldProvider.javaPK )w:4c?A org/mockito/cglib/transform/impl/FieldProviderTransformer$1.classPK )w:d\=A org/mockito/cglib/transform/impl/FieldProviderTransformer$2.classPK )w:W,AH org/mockito/cglib/transform/impl/FieldProviderTransformer$3.classPK )w:ltf'A org/mockito/cglib/transform/impl/FieldProviderTransformer$4.classPK )w:\ ?I org/mockito/cglib/transform/impl/FieldProviderTransformer.classPK kN:2D}>1 org/mockito/cglib/transform/impl/FieldProviderTransformer.javaPK )w:0a^q= org/mockito/cglib/transform/impl/InterceptFieldCallback.classPK G:I< org/mockito/cglib/transform/impl/InterceptFieldCallback.javaPK )w:la< org/mockito/cglib/transform/impl/InterceptFieldEnabled.classPK G:Ѱ<; org/mockito/cglib/transform/impl/InterceptFieldEnabled.javaPK )w:I;F org/mockito/cglib/transform/impl/InterceptFieldFilter.classPK kN:.Tb?:U org/mockito/cglib/transform/impl/InterceptFieldFilter.javaPK )w:*b<B org/mockito/cglib/transform/impl/InterceptFieldTransformer$1.classPK )w:m;% @P org/mockito/cglib/transform/impl/InterceptFieldTransformer.classPK kN:_S? org/mockito/cglib/transform/impl/InterceptFieldTransformer.javaPK )w:_NuD org/mockito/cglib/transform/impl/UndeclaredThrowableStrategy$1.classPK )w:SeB org/mockito/cglib/transform/impl/UndeclaredThrowableStrategy.classPK lN:,,&A org/mockito/cglib/transform/impl/UndeclaredThrowableStrategy.javaPK )w:I&G org/mockito/cglib/transform/impl/UndeclaredThrowableTransformer$1.classPK )w:)Ujgo E org/mockito/cglib/transform/impl/UndeclaredThrowableTransformer.classPK lN:J?NjD org/mockito/cglib/transform/impl/UndeclaredThrowableTransformer.javaPK )w:$#8* org/mockito/cglib/util/ParallelSorter$ByteComparer.classPK )w: 3>" org/mockito/cglib/util/ParallelSorter$ComparatorComparer.classPK )w:040$ org/mockito/cglib/util/ParallelSorter$Comparer.classPK )w:n#(:0% org/mockito/cglib/util/ParallelSorter$DoubleComparer.classPK )w:޹9E' org/mockito/cglib/util/ParallelSorter$FloatComparer.classPK )w:0 5W) org/mockito/cglib/util/ParallelSorter$Generator.classPK )w:ݷx7/. org/mockito/cglib/util/ParallelSorter$IntComparer.classPK )w:/4 8/ org/mockito/cglib/util/ParallelSorter$LongComparer.classPK )w:2:2 org/mockito/cglib/util/ParallelSorter$ObjectComparer.classPK )w:baz94 org/mockito/cglib/util/ParallelSorter$ShortComparer.classPK )w:Y:O9:+5 org/mockito/cglib/util/ParallelSorter.classPK lN:u &*d< org/mockito/cglib/util/ParallelSorter.javaPK )w:f `2dF org/mockito/cglib/util/ParallelSorterEmitter.classPK lN:*\ 1N org/mockito/cglib/util/ParallelSorterEmitter.javaPK )w:N( +R org/mockito/cglib/util/SorterTemplate.classPK G:(4+*`Y org/mockito/cglib/util/SorterTemplate.javaPK )w:W,7^ org/mockito/cglib/util/StringSwitcher$Generator$1.classPK )w:VZl5a org/mockito/cglib/util/StringSwitcher$Generator.classPK )w:STU7=h org/mockito/cglib/util/StringSwitcher$StringSwitcherKey.classPK )w:}f+i org/mockito/cglib/util/StringSwitcher.classPK lN:iB*m org/mockito/cglib/util/StringSwitcher.javaPK L<$C:0u org/mockito/configuration/AnnotationEngine.classPK .<[T/av org/mockito/configuration/AnnotationEngine.javaPK L<V;y org/mockito/configuration/DefaultMockitoConfiguration.classPK .<ݛw:{ org/mockito/configuration/DefaultMockitoConfiguration.javaPK L<$L"05~ org/mockito/configuration/IMockitoConfiguration.classPK .<32A 4U org/mockito/configuration/IMockitoConfiguration.javaPK .<<-.&H org/mockito/configuration/package.htmlPK L<j( org/mockito/exceptions/Discrepancy.classPK - org/mockito/exceptions/verification/ArgumentsAreDifferent.javaPK L<MY= ?M org/mockito/exceptions/verification/NeverWantedButInvoked.classPK - org/mockito/exceptions/verification/NeverWantedButInvoked.javaPK L<^(:>J org/mockito/exceptions/verification/NoInteractionsWanted.classPK -<Ȟ- = org/mockito/exceptions/verification/NoInteractionsWanted.javaPK L<]7Ch org/mockito/exceptions/verification/SmartNullPointerException.classPK -Df org/mockito/exceptions/verification/TooLittleActualInvocations.classPK -<,s;C org/mockito/exceptions/verification/TooLittleActualInvocations.javaPK L<?>Bm org/mockito/exceptions/verification/TooManyActualInvocations.classPK -<-+A org/mockito/exceptions/verification/TooManyActualInvocations.javaPK L<'<Do org/mockito/exceptions/verification/VerificationInOrderFailure.classPK -gQorg/mockito/internal/configuration/DefaultInjectionEngine.javaPK L<\[r<bVorg/mockito/internal/configuration/GlobalConfiguration.classPK /<;.Zorg/mockito/internal/configuration/GlobalConfiguration.javaPK Lxorg/mockito/internal/creation/AbstractMockitoMethodProxy.classPK .<;=zorg/mockito/internal/creation/AbstractMockitoMethodProxy.javaPK L< Ɗ3o{org/mockito/internal/creation/ClassNameFinder.classPK .<2J}org/mockito/internal/creation/ClassNameFinder.javaPK L< d&4~org/mockito/internal/creation/DelegatingMethod.classPK .<ͻ3org/mockito/internal/creation/DelegatingMethod.javaPK L<ߩL@$org/mockito/internal/creation/DelegatingMockitoMethodProxy.classPK .<{3`?΅org/mockito/internal/creation/DelegatingMockitoMethodProxy.javaPK L<A;/org/mockito/internal/creation/MethodInterceptorFilter.classPK .`A7org/mockito/internal/creation/SerializableMockitoMethodProxy.javaPK Llorg/mockito/internal/creation/jmock/SearchingClassLoader.classPK .< =org/mockito/internal/creation/jmock/SearchingClassLoader.javaPK L<|ԋi:aorg/mockito/internal/creation/jmock/SerializableNoOp.classPK .n5>Morg/mockito/internal/invocation/InvocationMarker.javaPK L<ԀeX+7Norg/mockito/internal/invocation/InvocationMatcher.classPK /<5"6Worg/mockito/internal/invocation/InvocationMatcher.javaPK L< 9\org/mockito/internal/invocation/InvocationsFinder$1.classPK L+%org/mockito/internal/matchers/NotNull.classPK /<pJ*/(org/mockito/internal/matchers/NotNull.javaPK Lorg/mockito/internal/matchers/VarargMatcher.classPK /< $H0>org/mockito/internal/matchers/VarargMatcher.javaPK L<\L #??org/mockito/internal/matchers/apachecommons/EqualsBuilder.classPK /< (q>Morg/mockito/internal/matchers/apachecommons/EqualsBuilder.javaPK L?*vorg/mockito/internal/matchers/package.htmlPK 0<+59;!Mworg/mockito/internal/package.htmlPK L<`U$ :worg/mockito/internal/progress/ArgumentMatcherStorage.classPK .zorg/mockito/internal/progress/ArgumentMatcherStorageImpl.classPK .org/mockito/internal/reporting/PrintingFriendlyInvocation.javaPK L<0ߔ1ݮorg/mockito/internal/reporting/SmartPrinter.classPK /<j0org/mockito/internal/reporting/SmartPrinter.javaPK /<=>+org/mockito/internal/reporting/package.htmlPK L<$L26sorg/mockito/internal/runners/JUnit44RunnerImpl$1.classPK L<4¶org/mockito/internal/runners/JUnit44RunnerImpl.classPK .org/mockito/internal/runners/util/FrameworkUsageValidator.javaPK L<}e26org/mockito/internal/runners/util/RunnerProvider.classPK .<úAz5lorg/mockito/internal/runners/util/RunnerProvider.javaPK L<+9org/mockito/internal/runners/util/TestMethodsFinder.classPK . org/mockito/internal/stubbing/StubberImpl.javaPK L<`Bq;org/mockito/internal/stubbing/VoidMethodStubbableImpl.classPK /<  :*org/mockito/internal/stubbing/VoidMethodStubbableImpl.javaPK L<.j Eorg/mockito/internal/stubbing/answers/AnswerReturnValuesAdapter.classPK /<+ D}org/mockito/internal/stubbing/answers/AnswerReturnValuesAdapter.javaPK L<}bixs <org/mockito/internal/stubbing/answers/AnswersValidator.classPK /<)ˠG ;yorg/mockito/internal/stubbing/answers/AnswersValidator.javaPK L<<!org/mockito/internal/stubbing/answers/CallsRealMethods.classPK /<Q];#org/mockito/internal/stubbing/answers/CallsRealMethods.javaPK L<^;q'org/mockito/internal/stubbing/answers/ClonesArguments.classPK /p`org/mockito/internal/stubbing/defaultanswers/ReturnsMocks.javaPK L!Fjorg/mockito/internal/stubbing/defaultanswers/ReturnsSmartNulls$1.classPK L*org/mockito/internal/util/IdentitySet.javaPK L<#HJ/)org/mockito/internal/util/ListUtil$Filter.classPK Lorg/mockito/internal/util/reflection/AccessibilityChanger.javaPK L2vn /3org/mockito/internal/verification/AtLeast.classPK .>/org/mockito/internal/verification/VerificationModeFactory.javaPK Lorg/mockito/internal/verification/api/VerificationDataInOrderImpl.classPK .<P9oF@org/mockito/internal/verification/api/VerificationDataInOrderImpl.javaPK L#~org/mockito/invocation/package.htmlPK 0<RFTorg/mockito/package.htmlPK L21+4Az|W~WUX_+Ҟ9[8;Z-:u/m%[U fNo1u*ؐ48PK-PK 5O6 META-INF/PK 0O6org/PK 0O6org/objenesis/PK 0O6org/objenesis/instantiator/PK 0O6!org/objenesis/instantiator/basic/PK 0O6org/objenesis/instantiator/gcj/PK 0O6#org/objenesis/instantiator/jrockit/PK 0O6org/objenesis/instantiator/sun/PK 0O6org/objenesis/strategy/PKpD:ZL]=org/objenesis/instantiator/basic/AccessibleInstantiator.classQMK1}ۮnm"Q"HA/j޲1֔uW6[%QlZQ@y3L cA<,T,jfΐաN-o(nD8@m^tJWB*^$ENOJ.ax#Be:4-(0Z})1XSn*q{MJo08(@?+l49.dc  [laOf/",IBR raX)V4&\5hT2iuIEN,yȐ#Xz2^!:P$9(2BdVDi̝PKZL]PKpD:Ehd#]>org/objenesis/instantiator/basic/ConstructorInstantiator.classS]OA=C׮]|*/F/UU$$tːun($(mŅVLL3͝s9g??`8LT-԰&n!&nZXBDDDa\~=!Coq'E 3(Zol1`G2\gnG'Sn CCFk6Uѡ |b2]1s=HE"5܏'=NGJ>I&5T2˃>ZHl d=z{/<:Fr{ĊU86`ᖡvߢa&nۘT ųeVΩǜ.(PN;mkj KIUeXxs`2w"O cf}2`Cd_,!/b(4 D*D1hj3њ Os@ C3C5.T$FaGȽw5}K >aH4WJj cF/PKEhd#]PKpD:d`7: >org/objenesis/instantiator/basic/NewInstanceInstantiator.classRYK@Mcxh^EQ(}|EԤ$ǿR}Gj !s|>?0#44 1 :0aRÔiDx yOUUAΐܐ 7E+Rj֖mT_:yLsx}3ˀa#˫ք+X BoUy kW"#JmQ #J'$P[`Pz.};bGF)r 1[ì^1@09޻QTs !uL?0=2w[>3./TA*FvȎѩK7]E, $sH O &i<&i6Y<2׈"~i?`'B )Qc<1Q#M_?i o1 F^PKd`7: PKpD:Wތ Oorg/objenesis/instantiator/basic/ObjectInputStreamInstantiator$MockStream.classVwA !-VbDXAq^k G4g$y%/ 8M$Ao,>蜹w̝]? 3ᄁ&" yU$mx zWٝi lypYMXpddb#M<~F+䬉s(|!%ai` )kYHhT"oݹs\5oh0JNAh2?윯8^x2}rFT1%'(k̋y839=>:3!v4=:ְi:rzt&3y~bv]Holp=gw;_s/9;p jLUB &( {R%̆c K(h(3t472SKdzAvDޚFSv<"ϸ<j2JK~g)C#v-xX3^#Lu (Z(kk:GF{208,*YX+Eba6cpmtΏe2i/--g&2{`XvɞePe"հJ&oZ+!iaI [ROv:h Q׺ޙ]66k{xo,B~gr|`>G>'>g0S Z8g ŸgBC++kh{@ټ=ޛنoTI}2mJQx4٥pl\s ;岽Ȥ=IЯ9>wOuHx^iD9;s4WPĊR0yICƷWe>T9l̸cw%xޔj9tVd_"Ήk g"R%ߚ= 4"'>CHK 8cP4+[xep#%/U:v3GYnzG|f}N\TŋZ-Pz"Ct-] lA D×0X=~s5.8a75]5Wk:wtDrVu1% 5;9u'?2W{HWJ؋Cx4UV$Goa/ q=]6sjz_qn2i0+L0\䰭25<7A ^ao3w)TJ#`p*M=էsw}AcǤ7릹6ʮ'C?73ѧrzt*N}ݷ5Urz}hw勫fTFzyd2V9PKWތ PKpD:#%Dorg/objenesis/instantiator/basic/ObjectInputStreamInstantiator.classVmS[E~6rk -T1Ԇ*FCPhMr K]F`Ƿqԯ&1gM%D̰ws>ٳ?‡*Ẃ* ip3QFF {UAV 9=X +*bƪo蕱bXSч7%aV1,2;a=+@Π.2--cPm۰z]uƳM#=EjiL80\^ IpX1,W^ }kE7)7:9DV>6 EnrgLrl! J&妑n k ˊ^Yi1nL2?$Y[4.LZ5lpjVX唠"$m0 vީx30pz2'lF󇈶.EʩeY2l[/;o%Eҕm/6/R%:_zuť}l,_ؙ'kG<Y u6Xx#?8S KO%Y? -||K`O'e@g w/#FQ< )g'ND.b'$CM!R^$o",??.$@fX^pIZF̺MOV 4V 3wUh.D??^iI㪆xVM|aNü ncA%Wn+XUÒC.:o96_dX,i9 [Mnfh0Ίrkwiy-\!hH˶1 B vչ/l]8VS:ck 9ILU8[UoI*mfB[[6t(50c2&[٪t&e AH/]nyŽ'TTG{$+Ro: C(UaDUQl4*cm8d9mIA;фLT|ANYX0_ Bj25p_x(`d((eE9El`5ηpR=.:(߫ϰ! kX7p.Cef_{0\;#@:^ےnڥ_g5btrvmDK?7=ߴm+L*!QmW>Th,u9iJyfz|Ry nďڌ)=̓ìΥw;ִjb]K#H^ KsHIN]0m*y2"h&CPAhKd" HCxGj:qҎt$hR#JG899$/2 b^hW rb<Ȝ*ߣ@~E?ą_*qOP zN`BNPe["Ml֢ʕA!q.H\H''ST bASx> ?PKmPKpD:%4org/objenesis/instantiator/gcj/GCJInstantiator.classT[S@-MF.-EEĢ@xA,R.KXƊU`n!D%"ZL^&a/"m*Jz<͋%0$foâb>lkYJXR ղRK\T]WPwQ߹EPQdh n MXViT]fԋl$nPj΍VS߸wl.RVE/F?/qhF yh'O+hk':ЅAZ,\ Nj`ắ7 : &>Nt+,St|Fw|#7&)+ĂPIp!$ 7g B 'xo~3t1|X"0;5sp wʓPK%PKpD:ib-Dorg/objenesis/instantiator/gcj/GCJInstantiatorBase$DummyStream.classQN1=EAw.\ RC" 26X´,W&.?xŰpcls}$}x}шPZzuo1w AIjGiyio`LJc1 r-^9yO=oH*Ҷ9IӎCn#S+^ o,&#~վ3c1v!6Lfyr_FATb? [< ҐzY> (&M9P{&P@HwDhPa*_EX", HYgi#\}PKib-PKpD:u8org/objenesis/instantiator/gcj/GCJInstantiatorBase.classUmSW~nXɲ)"mjk_ThmCv\d(2_:?wCؒԎ{ܛW 5 =RŬ4pSCn%qg.y; ,+T_'(pyKPeߨV0*Ux3ߨ׷:8ܛ}^?[^Vă[foOMf:52mb ]mC,: 4lorH< KAKl240$NPm1F|l7ӆَf`㫄9I/4k[1jI]ˬ-䦒o0BΖ7ub|FDeȶ% Mo]bDC3*ֆqwbDw#=T[\@G0L ({۩Lw(kl:iC ܆Sfۺ&j!1c՚kEY|HN>f #'.W:\OG uHFu\%sPvsmN&~!95?'u_f߾ȝ:."ÙD7"BP!pI2|NDŠ^S0I}6Y4t71",SJ)4H, !o#t&,BE5R3ˆ'Tj zܦ/Zmy_کYj#3< 02rnMyhPKuPKpD:$[RKAorg/objenesis/instantiator/gcj/GCJSerializationInstantiator.classS[oAʲhъ\.Klhap%KkUxF}Gm`6=|߹7~@]QSqKahH<.*XK*2 BE^AArgkfmcMj%p"C聰a.;%AFSZFͤHl sp.ò4uw g;z֟+2MmLވwHs#nRG\FMweMԊsOj" hƌVkBL5\װ 7p175m 30,uHM0cc Mxl'$97IO Mm!"W5MP_nxk LFHU<UX=o7q\Ҽv״{qEM]b4wػrfg"G6I8y?/|}ެOgA򢘣8=+>UP*O8 jF~REMP$!}SH/$?PK$[RKPKpD:B{ ?org/objenesis/instantiator/jrockit/JRockit131Instantiator.classVkWWb&(GE@ZH">j-j 4@a`DXuӟ}gBXs=L?|*pKE32-C6\ v wTy9aFU-SPP0"y]^Jؽ+x F *![%pY+ *( 8k[6<8YnӮT2 /擐eqk%Y5egQhG}4JZDID_Wå=bLnΖS[6= tO.йjٖS51geN %ZK:q^1 :B#̚ 4zY*p(YG^ YsNl,9 ;:"!"5)xdvnkZ"D)-/}?ZN><`0% 4 =ײ# i}XwB&]iLsWS)9aɜk#%iXŨ@ tͥ于"iH.&J&SLeMY a2zE`Qaǥ9%U!7aTÐD"+~H浥1VHGJ:k$WKk m,{ܽ=Bj*{k)N15Ŭ*~5coP[N_eE˲lb]}G+Ʀν&/k.k &|mk5 ^$9'^v'-[ɱSK~ڏKԲ;RiÞu*aH6GÏ*?ǘ\; Y*4pÜmB/o0P!n $b@Ky%oC+QZ=D ls3/( n_-)hg@=Q=Og,.#iW8 6>">h" l6:/lSr(sqxGњ{c[8j;wOS xC9b(Pф8y(cLUY29+d]%25]!z ,>Juy)y\?يf@yzv?GA_V-Qz7q'YZ&rx5rD5'W`ͅMD/k2-UQF c5 \Ԣ`N@PKB{ PKpD:|Borg/objenesis/instantiator/jrockit/JRockitLegacyInstantiator.classT]WWݗL2NBb-V$VH"Bk(mi.a0qMZ]m]꾓"Y+=g߳}rXM _k:BG" SMwu O f5iчouRW*DAÂ@njյW7/H]8_4\t*9OW5taoTz>bX)@ҷ-vl6/4J,⌻Covdq*%sJIZfulun 6K>mסv뾬 DiJ p5`7l6UpJe}ӡ6=zb +{ Aӎ|YR5JP+Δ|v*#]Rٳ3.0tRQtywYkgTUhު6s-ϒUV ,"+piRtЬ\o< | |G>y&v-p\mH n)*q)C@ K~4tyȋG_-rg\4Z>Q}'Ki3cy^ѬtzErJukwg%ѓkG~ vs\>{N ^e_;pr\;҆>Sm 1Zu6\SibzrF,6ϗxq D^^B;xID!VӇ0/?G>/W$3/٣na:DCd.S9Tc1"FUٿLY|͇q6 L|n@59@? UT ~:A#7[yę  -|Sզi* =Ue~G8<@+36p<ӢK"&qT-u{.aA<N58¬RO#H-õ/{QT@j j/H1ƿPK|PKpD:1org/objenesis/instantiator/NullInstantiator.classPJ@=7mֶZ_AB](OPH[\~x@B 9sϹOL'hwI+B>(8F-Oe23l"ӕtkuN8l6(r mr'L,iz ^**a|m4kq.nD]AP уO8Gw¤݋àiZzyAy_Aow_}pV1LwkI-赥5ޯrTPKPKpD:p3org/objenesis/instantiator/ObjectInstantiator.class;o>}NvvvFrϼļTF MIJDļt}kFҢTq0DSIfbI~H#n~Q~>P6/8X?I>&Ft@b`L lPKpPKpD:Bc@org/objenesis/instantiator/SerializationInstantiatorHelper.classSNA=Ӗn.Rʇ V ~J4G [Rvݭ}I'ᣨw KBn2wΝsνs?X2:BcRGSq CA';fpKl upG]afy^jzgL+xo8CoQ 5˩T_}Bg+03{so ,kH"bDC 5ahbS1. L1Hc P40+ݰCb^!"^t7a%ٮڦcC4]9ѢdܨqŬ9JY5}[[ _>moRYx6ljGɹ<vt);}y12N{\$1HH"xv3 ؞f8{P%/EeHZNKVlQR"e|aȥIy98a8pRl*^mt\ٶ 8". VTc;L _."?cLǗ8 `;> ?(GesiuN5zۘvէP IHN~j.taDF]JUዧ+ 2w_ [|bL!L}G( <$M5Ri)U]5q_ъč4,Q3r? #C@aeEоxRLj=.Fj{AU˳aHQeuI`EYcdjh:ў.?_0w=\F5?C+HI=fEڢ|4dy[HPw$j$Z 7jTIr8uj<9wPu~A}F^PKW3{PKpD:vEorg/objenesis/instantiator/sun/SunReflectionFactoryInstantiator.classUmSW= *DLA4[L5 ۺ,KCWu&ԙNe]e}<Ͻ? q[;*BHETEw>bYW(T>SQ)\CHAI/vYv6 q.?蹚nWr[3 / 5^i ^~LK%Xg;my ș c m{ۦo8(8^]KSSjUӫ:; g96UX*8n%Pm֭zbJY:v԰r]^<TOu=I׆uqZR߮6m0=3|8 #~=RA[Kkٕ.5 rzxyayڿ.`PKN5̼%K]V2(%H -0,ltABY6eK&qY\{nȸ74|Y}Į /-x]I3iStlkDŽCۅ:kbS]jM{x DQX޲0(Ac)⧼PLQcjVz]tI wkg}iy8s O1V:ȥmfqfzԁL`5GݯcigꦷdjtjK+v=F׫T, ;o_*7JF7-*7$ǒ>>M o8Jc( 1>C#%!~;D_dbw$2!>ąIE i P4F8璜DnQeLuR2P*ELSJ/1kN19''QC TxK# F=A(Ȝjj 9Fכ<8'[qc<{1VHsd;h7M]ǻ_y PKvPKpD:mRorg/objenesis/instantiator/sun/SunReflectionFactorySerializationInstantiator.classVSG~6H!hj+XDjP8䜸kљ?O%ˇ8޻>^yO:Løk\Tq ( U𝂫 dTĤK z|.BTIJ`Uf|?X9㙡 Q~X⦧2 ǮYNBK%u3 %3 d-s}l%iji ǒ5#6y,sh,bgقF2䲶S'\pru³ ⦻جҦCr~甲djHZ("}Q& MKa/. HNc )LA&wxu JR Zҩ1,}+TgIq^"jCV66iQװi!YeFaIJ KrI|̓KnѰ Sɢ&t}˓4(sǔdG= ;ؕkݓ} P(N+x1 {ͺkHcZhKdCtd5ηdU^" ڼ58 -.u4޶0S :Jj!C?ԥT|2 L{u{gW-^ RoH:oܝ` ]!լNF3i޷tlC˽E.< hjWrJ(w&[6 jqYx ԟq~X5"ѕe#ZA|7Lw=b;GPƵ *?53?y8 O }#8K9fR?(>um #I 9FsԺ%G|I }?FS42RE:D{_D\`C gq_ zkN"!DzBw ) ӓ;`4OiTvf<, ALk҄;&B2wIk;_ ^apR'ciȑL&Elb4Ԃ5p5J561Gar!ٶbpr 4 M{& f"jv1cAR9]g(v3>K3A)}#Q1K!^ eX o1^a_iwqStomw(]P//w&WȝyP//?PK PKpD:{'bJs&org/objenesis/ObjenesisException.classOPǿw֭Tc /WPO!}utnv(WDo|6\B{sϽTLຊ"RPt#*PRr^]c`m rczװZv{ o9aiѠR&tLgXI?<Ŧu6,O|=xko9:s,C~T@O4UE`F10aRY$g%(!H.cRAMC4haV6>7Wirף 5e(Ϣ7t`VlNG4EΰilmJ454>1ަGpG{ m?q>w#R%1BvzlyqFNL1ӴD־PjFYd(2ɬ&Il'org/objenesis/ObjenesisSerializer.classQN1 x^< d 6PI[L>]ly`]e̙9gpj6C?B(#q3~ uǻ#:)q\IOf 5~~w"ZvGEk!;֢{׊Ǫ'+/Pg8Bō?sב6<2X9ZسPaY*s5yT Բ$NbdGG \); )#h6MĚqj}Kǟ ۨBBjT#( YMPK>ɬ&IlPKpD::?@O org/objenesis/ObjenesisStd.classQN@}KbTT[@*ƃDF-%&ݭ婉&~e7w>\vknc>CBR_2Xq!ߎP%xJZ ciY2R1Q1nCy%Q%(80`hn]+j Vr#8M<9 uONsX7˜:[@^b-ʴ| qS5H΍ rfd aQ!}PK:?@OPKpD:l$G:5org/objenesis/strategy/BaseInstantiatorStrategy.classSRA=B2%\4x4+ 0h0l4 y6aJv U|僖~e3D3}Lw?~p2,p3(`q#X⸫GQq_2x40jՍw|-SQVF6d+?TuO޸h2R+W]$nVZ;vEAv +R 'F+A(^!:;u? 's3,Wdrd-BWu(JF^AfrƓ)6-9wQNQO1L}1QHWD2LㅅZ8eb $-\_baZc:ܓSf5g cǗZbX@|͈.= f*"[}NJt[B侈I,>Y*9Oo3 8;qD 2ٓ'+di?'mp3}5CZ .~b9ZS䘧: 4ܭ(؉=h0e r{`6h9`Aq|*r16E,PKl$G:PKpD:1org/objenesis/strategy/InstantiatorStrategy.classmNA 0UOz`Л z KJH _|آ`0 3>;q4ň037> uőY Yh6j>[iW^^D\~KF*SZ} nmW޳ ; ð PKPKpD:~g<org/objenesis/strategy/SerializingInstantiatorStrategy.classUSE~6pJVGA"Vi@!QBSSx dp.?_gHw)I3&ݽyW@ǎB R*B"*Ƒu|*2lA{ TCZQVUh2,d7QdT#+rQ|;c؈"`Sl(x⚜ 2$v_isΟ0vnXU}Qƥ{[3]^fw ɩئ lsdڛ>N,#F`6=wn; 3®ꢴcZqm5{*ܪZkX.7\a;~2lO\aaTWHsd.A _ ( JګM,x#+eѴ͆˅Eޔ2yѴ2%"BR(^CT: W /Yl[ G9|P#2)E2x<4Ĭ W8f(sʺA@h J$N[v;n 7cCCg\ְ[ SpPTU 5 &rG-iVu^wR Rv"Cr甒(mqbOH\0PcP*tZժ鮛cTadr*ѻ>uN7tO X`hNCWZ7ˢf !޴YR+{lvta"mZe,nkfb;h媒w6V Q GWCn e7mTT$*mǂ'%4xI7wyC<W0$cU˦1q HX1O8/56^Hf/`o[f(9w GÍ22Rĝ\d*OkeT=yri!t%(KMN۬gM#?FA9 q<_K)?JЍ2MINt,~;[ }Ӭ3J"B2_fznodf1;Ieq U@֖OnV:Y0~øY'hz>|hxrGa8&>:~>aۍurǍkr%W\jqޟnAvTy?FQ!)~+t `QT1;;wϽr? PK)cPK 5O6META-INF/maven/PK 5O6META-INF/maven/org.objenesis/PK 5O6'META-INF/maven/org.objenesis/objenesis/PKpD:O#;qy.META-INF/maven/org.objenesis/objenesis/pom.xml_K0߅}%ԂlLķw]f$k7IYq|K=w.'$F9ԉZXldS&2,?۶]ݦ邼W~P9Q G2+ŨJ^R¼Ynm;[&Eȅ*~c=Eg:駲XvG`XT8(LafjN&pw?c !|gD{eP>iYgPө9>+O3%m$):|pI h8X2-c"LI탧f]cI~2'-Zi0?Kڀ>} _PKO#;qyPKpD:cn5META-INF/maven/org.objenesis/objenesis/pom.propertiesSvOK-J,IMQHTM,KR(UpKMR04U0021"g#s^Ԣ<[C=^t,iřż\E%i% (PKcnPKL6Q"yQorg/objenesis/Objenesis.javaRn0 ? 6(%@/ͥ,gFR6dHr/-mǩl"93#s=#}O9IׅF|P닣Ҹ\, 炇ђaj[,6*BJ|Vq> FvۖNCjYW]m\~F ,OD x>p3ȟ`{#`0wWEr0-஥>Lȹ7U\:EGasݟ^0Q'*7e\V!,; H)5X[BLz=inN+@ 7%K8 .D[+F Dmq וqz3ZE'eo3c?꭮PK+M6k~p org/objenesis/ObjenesisBase.javaVN1}GFC7-BQ+PUxhU+KX* J${|fΙSmޤ*GߕJ[g,,3\NlXCНj R.erfNoi9׽cjfqS}q{;;99> B.1`E^@*Ie,ZZ=5gA%`zK& C北kXsM4D-q*UPj42juv|TVytpy;? pʐmwYk |)|Vp $3I@oRr ݅ڻ&2`ʸMoKٮ3o!(0BVHe2岐4 q/cr>LPRbi8IEH:U/cݘʥ s.|q_O/- SJ U@ON^bjjp-nЛקKWS gu;YLHNs/'Nd}q%s !BvCVZd !,ہ4eۓkH쌢 ?f>`qBsyHHYj9БCI9 WyFYn_*CGAQ|< Ĥ -`ovjBrn'/4N]H"-uPt z@. rY'gvJ#`Qc"" 7&jD08>N-s!7\S˜z^g2 0Nti :c8Vbm *iP +H&xRkE- IvbJ{Gi؄ ;d@FHtjn6l$V[oxíER9KPiߵ'n-!.NXIyhq ;%4uPiP=`PQk _/`TR~ t QVo9򙔕pN!]PtܪйEE.*%' D, kQ-) Cvy Qή'穏=xO Y?egGQ8Ce}#Y<`$y1S=+k&SٵAE. ) {uG;AbCKW"">:~ZBp5LeO& =}Hw , uz)*?pI?!s.SJ,KPKL69K|"org/objenesis/ObjenesisHelper.javaUj@}7PbJ!J jWlV(!1}h-!휹33.YckסJ(p3#^J[ز= cԜ ~0X&-gVpESu^t:~U.YZC0V+Yc * f`Tn(̘b (e*Q.Qj7D;Ge sɄwqJE]Pjg<=T27f`~uGky=zIU@>S傪`jGH$\Cʄu%Ӭp$ךJhVZ)`̗ERQ`5->M.a7#[f 2%#^V6)BdMA0g.Tȹ&RI0ykI>Gw69&]Hl-R]`D`w AN?wRjne5QGUQ ~<΀ {K\vdXH:m'ZXP(ySv<[I&gN`7d ݠу%ZxJF5.ͺ7b{ϫ_>vR0 уHhpɽT\?aNp"Z"f;8C$}PKeN6q:3&org/objenesis/ObjenesisSerializer.javan0 >B5in0m4GM}HLhQUKqߟץRagyy({dw劼F60Zί0+<^G9,#kg!7 p~ 8/d7Omep7fyh`;yO&>=br x FàW`' K[L$/{ڿWoVs#]ijX>s*aTqѡVI ;!YCE ]D!GpW$PKN6'(\org/objenesis/ObjenesisStd.javan @>&є~@/Ѷz +j꿏ЦʹMSWd;l mKS&'2MDutl=nV1jnX(4S4#K;[RRnlr,#>.zV«Vxi2ZIBsW@zg,.،p@<b&X/g"Ƴ.Gliв<_6.hC:7b%We5L<}RjTqd:]NF瓳E:{=f(YTbR\#30׍?M&À>b2ϧ;T'5 YFKJlod9ͮf:4E d^ƪ(A|>ݢ5qPKL66*l0org/objenesis/strategy/InstantiatorStrategy.javamPN0 G;|G}.HiMh(6MwV1"Evq"I#橍.E2 O'kKY |(BA'ʴ@Ή[J ϳ_/#ryCux@>psuPKL6ah:;org/objenesis/strategy/SerializingInstantiatorStrategy.javaUN1}I6B<!($X9ٍcl/{Mp*+e/9gN?B+lbaanYgv)^9Nh5ʌbZ˷LBYǔi`D ]Jfy \_ޮZ?Mb+:>9Dn v p]&clr1( *ྻ~Ƞl=y. QQhA)J( K*Bn L3&Sqϭ΅.PCwE](h3)1%pYɷ@`QrbF:ȰDEBͺɛA)H{="<_8}4N12mwKz4|6!4$0l5PN{4p;mq?6hj,o&/A6[Ցx ߙŝ cPی><^x?BMwHY-{QvӒv͒zyl\~^("/%Tpo%BرjdU^`mak`y}wg%K5ZQ(a`.71za}gn W^o_DFwWt3o&q!)!ũ䤳LW3^Ӭ}[*QZ'zQ=*}4(*%.tPKL6(F] 3org/objenesis/strategy/StdInstantiatorStrategy.javaVo0~_qm\uF koMԎlgtKlb@(~|G|%a[@,SֺriJ#ۯj-f ka Q=|Vub2ƙaӄ6M(y#oEƀ#LXz)f%D 7gR"I* ;W'3r"m9L N3QdK+4S11@Xro&nPKuGܴn?iS\nKO(BD1X ]Bw~}bIkZi6IDTUq6?,5lUL>h3- EXwog̀&Vd~E#tU Z8V(8|AP#S&ZV,ϵZBHJv`o8Y " sk쓫Qؚq̷79;И`r(o `16ضZQ|_h'úakj{ V5UzL[\ ԑUma7ׄWj[کV Ft6X*{jj_Q=keƁcbVݥ_ ,(cs%X٨q;|7 wpE`*hJ#TviPKL6Cܷ40org/objenesis/instantiator/NullInstantiator.javaU D$^dcQJ n0̛<Ƙm7wmYX)ҪmР"d '"<~q~3\|:"C.;zej^zg qI;ΎGqMFwFRI]渢e*e׺5 犻8ټ/oPKL64@=2org/objenesis/instantiator/ObjectInstantiator.java}1N@ E9hLI&h !$ETFFcVNjd&d!>;TCW :[nQ8g\—s^ ol[;\';#AgJ }&.`Y֙V#uQK{9ixgmvޱg}|_v?PKL6Wl?org/objenesis/instantiator/SerializationInstantiatorHelper.javaSn0 } Z}AtÆm:`(2mSDd}dE!*SuA't/A`T g9Գ* {d^gh[dAH ;9lŒkCPuNG'ک.4). ՙw3 *a?MiBg'LTcy BepOJݜ*PPgt9cZ>2MaN_@)*b: %GqLH6&RnWZIHGwk[NK𺺌KAV-Hn:2%N xYZP0 =O+)aߵpn#4Nѩ1!{E+$ ?m"YdwlcGw Hnze%2T8V>d p'JX\NъѮ\N$J\;<렲/Y RмϷL)XZ-Y;[H căm0,NM=Oڞڃ";%OҴSx?]ziR>PKL6͙U59org/objenesis/instantiator/sun/Sun13InstantiatorBase.javaSMo0  zrBEѣ1`[Cu=8LV>~E+V/Q4QdT\]ea6 OEez;vȁpS!JZZA{o4GoM-3ȑ7WJq53Fm1FXku q70$ XMk{OķKk~2:Vq䓊/&sis[}\уYp2Wg,ƕCte|OP%t.8ޝSc1Ra{ Z2{z"SXyܳ/I8ݱCuS O# ϶|MPKL6GCDorg/objenesis/instantiator/sun/SunReflectionFactoryInstantiator.javaTK0W {!WHVH+vyD8 ;IvdOZªqJ*d{̌SJ]­bAhHZҒWI7r+63qip(,I;k:FF5]N L/҂k gv4F4= z#3BJI @22p]F 7ݛw O$EXT>/ u kHpE nВc5 N@Nao v WGjzYd5k`n[܇ej(YjFD{a<%~uhյ:6]x$Pzn390ΑF#%N:*qȑFtrաUǓRkx/b6&vG ik ʘ}wWT~tJg}8t v`q3\ڸ+PKL6lt1 Qorg/objenesis/instantiator/sun/SunReflectionFactorySerializationInstantiator.javaUQO0~^~ũ/MBbC4ֽM{pKcpv躩}wIIBaD&;wK떙]ܡA|%uoI.xٍ stJhG,4~-xf9,4ʐ[Bu$ސn@*Z^>k$R}߻_Ț&p; V4^%(_# k*GC("CZ)H MhGG-]QoQH lJZYW9{Caf'$TҮ\ƆA]߭U'΢WI,ۓSڝ& N=p⎉lUc7)I[a]x V0cwICk%aM[VL׸htFiWkOuQnz=ٴCFQiW`{ћA鍝7y?=9Eln!DÊ\H9=;"kpאz5E{\{)`hTR[)LIsƚU.stԡqg(h xLf*XFIؖB#w26"'CW2+R^W˶Ol$*<a{3;%\X70i+grDy g<RZyϡ5t݀պFx)N;W|+/$6&PKL6ژ >org/objenesis/instantiator/jrockit/JRockit131Instantiator.javaU]o"7}nN_)@)w((u.'+I9G_GW8b@! \cӚ{Ɋ'6sbճۃJV:]"@/il&/aԊ\5Œy?2r#KF5>Oф<=>P3͔yL*|׹ӆ={|t|$P_pVp5e'uqg(6W̆HPۉ7X>vXnAn t==OzJ>b"&;4ԉ w 2hE Mľ!ׂ]#;߇$LYeEM {v,AkDpOt UNܵ_b#zLm]I8ŷ`g"(k5|[@[OPLlOaeNJ1k{\.9 H<bDM֜Ym% [^b KmACI/H=3l;]ף:>]_%1eA u9-PE+C-nyLwbmNse{d{ǛF1Q/ЄӱNPu[U#6+Zli4jvd0\+,3TPKL6<釯Aorg/objenesis/instantiator/jrockit/JRockitLegacyInstantiator.javaUQO#7~G?P-(5w TJ V>dc⵷7Ͻq3lE+uofƜ1\}w0ti(W"5"B͛su!bpٴnK,a ÷)m k`-6j 0wi}hڠ=<@@d<<-zULQ@ dùP&F+!%يߑ˳.U fAGjel( +DxlZʊr2HW@ZaU+D}Xez:B4q)~#ȭ#-xbtG VA+4V ܠҗn1R]bޞYZ0_fRG] } ΓÃÃL W=Oh"]FţOHglT٣\Iaǹ~[$ՔcMA(lEg{,7bףb^22K33'ZWu;ߟ~/ bImt@|h@}~=WRQ4ZN }' 0ffr)eؐe~-QwOkЫܸYkw"6] }o{ojHKk1nN`hzKBA,9sc~`[cv=WND&t@{3ȔTUuFGw v]t|5~HŪQ&Gg*pE$=l9MX\t >R^_լ P{jQ W6Eq:e{{iչ5kpAV^ /.cAd2OmؐCSȁ2K\L2vڮ tHEn'10Z+PKL6Jf3org/objenesis/instantiator/gcj/GCJInstantiator.java}Rj0 :fXee]#7JPS:1Ɩ{zm,E`\5zS= MJqi.8#U[{ :a WtF آj!ߋBzi8ͮRr잍N!GB?pb~HVA:w#_$!v*2x%1u8ݣ6<w}0%&YS+9njp s>~KF Er90mwS8^ox PKL6<"W$7org/objenesis/instantiator/gcj/GCJInstantiatorBase.java}TM0#F*ݭ*8X8C0MԞҊމHH|y#} B&jfpko$C ."i ަq,b@ f$]pYREcV[vzy$1xQަXR PKM6# @org/objenesis/instantiator/gcj/GCJSerializationInstantiator.javaSn0 ?V/H +ŲR2ȜƖ4Qr8 {ީQ#Z &VbGyW|f_!n5z6ή@in_w-)Z,3X)Z3'HV<'a@\"p`8[Z]BH)Ch'ĻC%iI f*#@w/lkW-SXd,+߆urF/$xaZ=K2iZi+:p5hwGyjz]gF /3-hzYQ$:{=$@ea}8JJY:\X)#v%7g77NƁnԘM*cO?%o.0+ڦ7,YFA/x,OOZԡdnT=K]PKNN6䏍 N<org/objenesis/instantiator/basic/AccessibleInstantiator.java}PAn1 mA%<U*ĩo6NDQ,]Ìgƚ;:w $,d 1d[v+c9l 8"ОKض::u;>stDvUJ׈ͨNDGC,A5, D^sMssx!E_Za 8ڠ$P] RQ?QJH{(vq8jIJwmA|?9a4xB0[YߑV BBB, p̴1vdO(ݱФX2r|J߼h4.rl 0|4ul ϐKzJr)kK a)2]+6Ѫ}h2uo,mTo]XSGu[4=[7icXfU".ݦJt\ ;r`-.Ońqp,𡣺T˘T|pK99xMp }pQs,q:=| ւ繸|9MQPKL6+Corg/objenesis/instantiator/basic/ObjectInputStreamInstantiator.javaXms8||9HӻM)!N N; 1dR,llKoV^-!xPrH*)Δ1|rRR  [qD-5T1I)MpviQ\O!Ɯ;XO^M>U)GJlL" .'W>ͧ]{R!["LJ58l%0h`DhF AXkA@͙ޱ)b !4T"RA چ#H@QA?_h%0a w"e,dzj-0Ԩ2) <2`0@)\M W&\ 1$,@:3g+$Y*dW\$2\k u@bUJ%,&  q+kQw "l4)A+,OcObB6)وT갧 Kȗ("P~M2o$?Iז8ٝ:wفk 1:(!T$Lm^mˆj1AZR_͓0>}6vR"%k"¡af$=NMf҅ߚ;<$qB{.;5jU|օ?3[Ng-ӽJ2m덍ʇZANUm҂ `)O$}]UPխ -\ᐶTo8NGNWPp[[9giQJ[pjԾG!/?=:RPD4C{Eaf:nchSa rTB.λ"u[ӏݶm+GuSuVRj;s q,S- fX{Fm+^6Nt|X@Z; [_ό.ßՕ"8< ck{;ܧ/Bg~,Dvvn燊.4@=}|FhAOMit4LB˵OёkOg)ߦ+Y :R| QGJ:{qwpս1M$؅8Ց#bPK/>sr1y}j;\K b庮77 G9O5$WgDQo˶-zF왾8l*(t2g,sLwˇ#}w\.[RY.RlGn':l_AU׫fDWkEKԧD:FYi{i&o[:N=JR3Wsi _$ r}ș}RI?PKL6V7Corg/objenesis/instantiator/basic/ObjectStreamClassInstantiator.javaTn0 =/@eNaAvvPV#KD'ˊ(q8k!K|k!7@ zse< CJuRx%x:'%=CQkõfT@**|8>XfdO\sSLLtȠ{h2h\@*Zک-AGA]B#У!P|_W]CZ'ID@f' mUsR#cN DYa'0\w]}S{-\Ĭ5242םhb_V5D{aq:fHއm$ˬʨtv% kvFܭmÙ?ŷd-TzpAMSgmמjI{ގлpH3|Rfk7uͺ^K:3 ײT)PKpD:-META-INF/MANIFEST.MFPK 5O6 sMETA-INF/PK 0O6org/PK 0O6org/objenesis/PK 0O6org/objenesis/instantiator/PK 0O6!!org/objenesis/instantiator/basic/PK 0O6`org/objenesis/instantiator/gcj/PK 0O6#org/objenesis/instantiator/jrockit/PK 0O6org/objenesis/instantiator/sun/PK 0O6org/objenesis/strategy/PKpD:ZL]=Porg/objenesis/instantiator/basic/AccessibleInstantiator.classPKpD:Ehd#]>org/objenesis/instantiator/basic/ConstructorInstantiator.classPKpD:d`7: >org/objenesis/instantiator/basic/NewInstanceInstantiator.classPKpD:Wތ O org/objenesis/instantiator/basic/ObjectInputStreamInstantiator$MockStream.classPKpD:#%Dorg/objenesis/instantiator/basic/ObjectInputStreamInstantiator.classPKpD:mDForg/objenesis/instantiator/basic/ObjectStreamClassInstantiator.classPKpD:%4dorg/objenesis/instantiator/gcj/GCJInstantiator.classPKpD:ib-Dorg/objenesis/instantiator/gcj/GCJInstantiatorBase$DummyStream.classPKpD:u8Vorg/objenesis/instantiator/gcj/GCJInstantiatorBase.classPKpD:$[RKA"org/objenesis/instantiator/gcj/GCJSerializationInstantiator.classPKpD:B{ ?F%org/objenesis/instantiator/jrockit/JRockit131Instantiator.classPKpD:|B*org/objenesis/instantiator/jrockit/JRockitLegacyInstantiator.classPKpD:1.org/objenesis/instantiator/NullInstantiator.classPKpD:p3)0org/objenesis/instantiator/ObjectInstantiator.classPKpD:Bc@1org/objenesis/instantiator/SerializationInstantiatorHelper.classPKpD: =6=4org/objenesis/instantiator/sun/Sun13Instantiator.classPKpD:h:u7org/objenesis/instantiator/sun/Sun13InstantiatorBase.classPKpD:W3{Ck;org/objenesis/instantiator/sun/Sun13SerializationInstantiator.classPKpD:vE>org/objenesis/instantiator/sun/SunReflectionFactoryInstantiator.classPKpD:mRkBorg/objenesis/instantiator/sun/SunReflectionFactorySerializationInstantiator.classPKpD:B6/Forg/objenesis/Objenesis.classPKpD: !Gorg/objenesis/ObjenesisBase.classPKpD:{'bJs&Korg/objenesis/ObjenesisException.classPKpD:B#=Norg/objenesis/ObjenesisHelper.classPKpD:>ɬ&Il'Porg/objenesis/ObjenesisSerializer.classPKpD::?@O IRorg/objenesis/ObjenesisStd.classPKpD:l$G:5Sorg/objenesis/strategy/BaseInstantiatorStrategy.classPKpD:1tVorg/objenesis/strategy/InstantiatorStrategy.classPKpD:~g<qWorg/objenesis/strategy/SerializingInstantiatorStrategy.classPKpD:)c4[org/objenesis/strategy/StdInstantiatorStrategy.classPK 5O6^META-INF/maven/PK 5O6_META-INF/maven/org.objenesis/PK 5O6'C_META-INF/maven/org.objenesis/objenesis/PKpD:O#;qy._META-INF/maven/org.objenesis/objenesis/pom.xmlPKpD:cn5UaMETA-INF/maven/org.objenesis/objenesis/pom.propertiesPKL6Q"yQ borg/objenesis/Objenesis.javaPK+M6k~p corg/objenesis/ObjenesisBase.javaPKL6Tga% gorg/objenesis/ObjenesisException.javaPKL69K|" iorg/objenesis/ObjenesisHelper.javaPKeN6q:3& lorg/objenesis/ObjenesisSerializer.javaPKN6'(\ morg/objenesis/ObjenesisStd.javaPK L6ЀK4 ]oorg/objenesis/strategy/BaseInstantiatorStrategy.javaPKL66*l0 /qorg/objenesis/strategy/InstantiatorStrategy.javaPKL6ah:; _rorg/objenesis/strategy/SerializingInstantiatorStrategy.javaPKL6(F] 3 ^uorg/objenesis/strategy/StdInstantiatorStrategy.javaPKL6Cܷ40 yorg/objenesis/instantiator/NullInstantiator.javaPKL64@=2 zorg/objenesis/instantiator/ObjectInstantiator.javaPKL6Wl? {org/objenesis/instantiator/SerializationInstantiatorHelper.javaPKL65;r5 }org/objenesis/instantiator/sun/Sun13Instantiator.javaPKL6͙U59 Lorg/objenesis/instantiator/sun/Sun13InstantiatorBase.javaPKL6#B morg/objenesis/instantiator/sun/Sun13SerializationInstantiator.javaPKL6GCD org/objenesis/instantiator/sun/SunReflectionFactoryInstantiator.javaPKL6lt1 Q Oorg/objenesis/instantiator/sun/SunReflectionFactorySerializationInstantiator.javaPKL6ژ > org/objenesis/instantiator/jrockit/JRockit131Instantiator.javaPKL6<釯A Horg/objenesis/instantiator/jrockit/JRockitLegacyInstantiator.javaPKL6Jf3 Vorg/objenesis/instantiator/gcj/GCJInstantiator.javaPKL6<"W$7 org/objenesis/instantiator/gcj/GCJInstantiatorBase.javaPKM6# @ org/objenesis/instantiator/gcj/GCJSerializationInstantiator.javaPKNN6䏍 N< org/objenesis/instantiator/basic/AccessibleInstantiator.javaPKL6:Ha= ,org/objenesis/instantiator/basic/ConstructorInstantiator.javaPKL6GQF-= org/objenesis/instantiator/basic/NewInstanceInstantiator.javaPKL6+C porg/objenesis/instantiator/basic/ObjectInputStreamInstantiator.javaPKL6V7C org/objenesis/instantiator/basic/ObjectStreamClassInstantiator.javaPKII4xmlgraphics-commons-2.6/lib/build/resolver-1.2.LICENSE.txt0100644 0000000 0000000 00000026136 13777276623 021764 0ustar000000000 0000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. xmlgraphics-commons-2.6/lib/build/resolver-1.2.NOTICE.txt0100644 0000000 0000000 00000001553 13777276623 021657 0ustar000000000 0000000 ========================================================================= == NOTICE file corresponding to section 4(d) of the Apache License, == == Version 2.0, in this case for the Apache xml-commons xml-apis == == distribution. == ========================================================================= Apache XML Commons Copyright 2001-2003,2006 The Apache Software Foundation. This product includes software developed at The Apache Software Foundation (http://www.apache.org/). Portions of this software were originally based on the following: - software copyright (c) 1999, IBM Corporation., http://www.ibm.com. - software copyright (c) 1999, Sun Microsystems., http://www.sun.com. - software copyright (c) 2000 World Wide Web Consortium, http://www.w3.org xmlgraphics-commons-2.6/lib/build/resolver-1.2.jar0100644 0000000 0000000 00000244173 13777276623 020643 0ustar000000000 0000000 PK zt5 META-INF/PK zt5щMETA-INF/MANIFEST.MFu;o!{$eRq,Ypnm,ǿ\ǒrgYlab.S)1S7Ù2QT3 r;5WE',H JM]suv 5;0{TOg= ߸,yQeׁB-z5" ,p3 NymybI0LEe6b_J4u5=ЭPK zt5org/PK zt5 org/apache/PK zt5org/apache/env/PK zt5org/apache/xml/PK zt5org/apache/xml/resolver/PK zt5org/apache/xml/resolver/apps/PK zt5org/apache/xml/resolver/etc/PK zt5 org/apache/xml/resolver/helpers/PK zt5 org/apache/xml/resolver/readers/PK zt5org/apache/xml/resolver/tools/PK zt5t ud&org/apache/env/WhichFactory.propertiesN0+ܼ*jo Pຸ Iבmحƹ'lNnE:l-t_s&/Wi!⇴\ >ϪY(EF$tY$1]j_Fk0Tg%^puW+n1[R/"$߲PfZFt 2[fiU'Vx?zu!a ;=ra! BS'k.] J1OhBĩ4sFp1d 璍xrf700igֆaaF mqau pTA PŒ3Od@"a*9M}Ȩ UɵTlxEXYf5X_D9$PgWriAMu T1ayq/OZr iou''Ǒ&+23u^(򲆀ț-;Jc3<*ke^?Vs|K9*ki>۸#r~es8"W@>ޜ?C* N@@=CH 3WZiePR$Wxvf tVXL[ZvU„viMݎ(v3)ǬjmdA1HIgq)/!c\$~[*AپavP[rTzOXš*ǽs@Xt!S15ˀMlwMGn*ڏE$koyEvUSp$ac(5{x(6COFH8C b8#q}VY]qPK zt5$E._%org/apache/xml/resolver/Catalog.classͼx?~v@!Rd!Bh0 MP%Y & *RU"k{^;g݄ x?w=3s̙|@B/|xxA|s~ǣxǽɏ'Oy! s-|%_B'WX٫x׽`s[xepw6{ >~`⇜~M??4+k~|c=4oM؄8?xhOl/jonհza!` ΅&Z Y)ZzahD")INY)RWL`uсǰ],ѕn^S2E%z{< "4:i>ܲ/9`dbc[ eÆq.-1#-18֑m2+rXrqsy"'X,8i?rZ`O_&Z3,-Y(9l uNZ+,I L22ũm,R1saKZ1,<_Xx%,Qn VG|%"Z5BK,X3,K98Y|K\o"~,Ŗ2n|).r.*VWrU+ypXUA=9̜)#Xc'L--BىrRk9Ϟ;{1y93&O-@E%SX;2cR.禌Eޔ:?p]jN=%ob! WTZN/ʋ*x坄%iEC C}+5}JšPY弜E%TVDJ~zmMiYi5I, Ֆ̮\DJKH-Ό5.U#y}CUᾋFՕeԦoNWZ&Ur, e[P C%HA !%CkBsãu#d1f54rMN%U~iE|N82蹟iH);Bf~)H>ӏlY:.i^&3R{;U#YmU/"tWZU"TwrITv\'| ;:n0fV 6W#jR4lPMxB%%<*Lh7j+d[)KQ+$DMJrsrּ=? ŕUKS0Qz+‹w2\}R^w>$ńO_(̳(鐐qHnkB\TZQRLM Rc7c.إv.e\~Ux:Knkqgi 'LYHV2~XsXxC sHC-Ǚ;GCegڽPЂ,>gI '"wynjEumUUe[Q\֘B\.MIk֫8bIvRTWkDqz'WF6|7]>ׇ 3u>>l-}؊ʼnH⇟LdlbO|b׋ nHIvhL'EهTU!}\}}(7F**CեY ꬚,{idj~f}#61{r uJ UUrV#aoLC_NPݷ,TZubOl7ѾH[VY-\Vz%;|NwvÝ8}/Bߊ}bh0.؍|>q?<`'GgG <}bxMSI:fAjT іYAxP<8S<{ţ:l>|%Vq vI j)jTиyǿ tihXڸ]r3/abpѐ@a"JxL<>')v>񤸇pNAdaڹEAN)j'$"HU 7?z"QxJx;RFP4"1{}TxQ 7S#rχWa$Lrg^[ʧ` }Ρ)hߩq-XRR /.i) T!;ѱ`"*j\)$I9F;N  |gO|SA{>q?'.g~_?$?4~\+?~wtZ WΫ \F5ġ>҇0!Q' 7gG,J|-6!LoT qҲ,)e΍TqÃC |}$R;'q#lEMX;M^'~[ɗ 7јcju,LJ6;$feu'ʜnG>q@H= x?uATCqhsaMx.e pP E~}8ry}'ÑW>H\ƹ!0?d~NIHYB : mPE6V5vvmů>~q_Gnş`xa)Z$E%&&$GE]|!IE}CO6ט|-ʧj2-(ԙ|mAE(/!c+hTr]]0=NSW5UO/irdwxqM_n"uãS| P{5:SI U5,-69:R b{̵eJ krau^THةW?TK|Mh|&7Ҩ8e(Zs=p(v%9 ^U1rEC9%vt=/1ZZ7w*+MF3' We5n^eZD wwn$Oѓ#_[IvFۺ9䮵]a50E־_ 5H\ /,-&++C+{̹D ch~b&7#~+uHpUW!*&10SrrH=-vq&DpdOB'wܓe_O+?EfbY^Z30?(yJ|]4<Q*;;7Q!A1jP.G'Iv_W'Iw?O'=h|P):pR餚*RI=UiT[#Ot$';i2Viz{lGoARpj.= f4m'i fLlŲX&PG;eLj 0@>@jZZX:PIÒ8F$3aV`{j-ؑRccdSIMl EG90aMuch)tԗ)s{Kt@yCzKhb\g5Ĉ5;AwCb~I{ yF.h]hoS.!:Nc 35fFxjJh-^A\ ix=F8Sf8fjnH{`O002 11=|2렳t-|+}z=w評^UM1@wA&^d0V:8 r؇,o -/#˳4ǀaE2 ٌ ze [Tb'd۹,z b ȳAӹV_CzBP `AIMU~4KuLk=7|"1H?M9Z4/ |(Wa&p: \oZz߂+e֨@u8I OJ8%Gu(r`C-tS\)$ġ# ̳5@6G`pA/F#>6c{ ô=EX# ^#`TMkd7Q5Ӥ85{6MU*UIz|;,J UXrsi9$㜉j[{Hк\30'l#fyZHxIh}a =8YBAAWA~ZpX3 q+ΆypVSFiQ)kp"E\H@`<&T3(,zZy0C9o3A);Ԟs"mIr:T]0,Ft+b,PYTؙ=,cֳ*g+tN(SD3as0#:Fe{𓇯]R:"6Pq=d8 f-q+,ADgmp ˨n֖׷ ƑxsNi,(JZ-^nWx#HRز͵%됧<  C"ett s7v_N~ET3us= W,NwᴀpD_©bpj) 32]2gc3ʦ CxRXrhjd=gЇ밃 p'ռ6gEx iC2 O_<@/J^1E8+px 6, JJ׈`_[xVG)DK"&JAj؃>A҃ҋ(?UdK $\ X-qlQzlgx[dGLT_~=)T5{RHCHDW`QWZDឧIӰxο OLWJzH+"YZ@K<%oT, /4d 9>h,&1Jr Q۸gZT+y>?;Eiqb[ƹ|,$R-靤8p8$1Ӧ]ei i6y2YVg0aOkAhg4y zP0ڱvCRt<`c<T@OlZE{ l<GĻ_@/Ĥ(^AbBr9p GADKL5r<.9v|- `{$xNNDNI<Y Wd9{ ̐_VIVJ5T@pI*&X:F9”`'lP.)t[x]=tK9k䍱M o[0 l*"viNhO#ǟ?pAg Q,o?8c//U6&i-og=:0$Xޒ#<3n&v_z>-~뵭d:虦 o \i[tbv\^9n0-o jF;zWkR**߯VR3ԬQn+D5M4Hêڦ_ZT@jgN͚:fkquN:뎤w}cݩ͆:8zgHz鸱flld)J65R2lSMMfH$=[M>sSTϹ疿֦z(o]5B5#~9k٤h 5ێ]5~;i8}40r6 J`qp)\Lwg /Z /].Hˠ0FIj&WB.a\r#<(q 7[r+|*ood=$oACކ>y;Wwb7yeq܁KAYn"y?^ A\#z}1/g>|S?OI<(^Hω_|A /Qe+_U1K.t8S#.{b|_l[G.xX~&ų R|*_o[O~/< 3OrY<"'?eX535!/4R3)o,yh Q'Z׵D$򀖬iZhIZ;^:hZIuf4uʴZC;K]VjM;=ZWiohIW`W @'kY1p6Bԇi|-[5u=Cwޏ؁r$C@],AB lr: j*rHRQA6Xsh@R'tRBE*dW,d)`VZDhc͂v[d5J9*{dJ+UOf- ,L2UO֐l=peʴlb[Rb7Z9΍[9y/ɺ.}stoZu*@uR|B6ZkV*z`gKkhguz{ƉQB07o`: .a:vd0%< Ȩ]K;8M|\.$n:6ݸZ93Y1[6Gw&$C {$ѰkA-Y];zkB_<#b(.ڥ0[[h" XAUUEFIx.{ܫ19Q;Dg9B$\^\; 㜱Qw]!QY.X@ȷAo|[ zG0I n0Gz8K p꙰L WZ?XׇKφxHρXxFυq>>OM==z&9^/;*T_CJ9A!Tj * *K*gT"MP9rA"K*TTVTVT!!%#'l \OPRGPLPrar* 'FE5MО-.vQB{kFКMr~2*Suvj54)P +eyxx&ZL)eWˀsbԢ+x_i8rOk[h\O~sq\>KlrUó*8Mo(Z6c d'#tx7A[?7@8zC!C,1$cL6F#j1p6_bWypqhLMF>inaLE1>64f`Kc3NŠ1{!l1F1%x*ʟi(ˍr\mT 7 zTfGBvU*܅P*TQ,k!d2bsE&p#&t1N)S͕փ`^C-,`1Z^]ÄU/A8!8H $45"vk+9 gyk(%%4k 1^6G?ZL/1y@Ok?H=`BO]ii0{x`8,1j㟰x%*x>4^ƛhoa6Q;d1}Ӎds,r1<('~Mox;7_ [~iZ3A>1D1 f(4[fQ~NDL[E]׮!*p1ת.Ӝ/2"9:E O\&:F( 0KqLlsz%D>~0P"Rԋ:D_¥H"!1敉4AtׄHo82_k1"],9za9s83G@9&9 Dz;0yİuXa %3vKnKCaf!?jK@A<`1RLC-FYM㒢l \qSŒx(S#Z#%AL#v qH,XW$sГ~0'[&#_go`8v*X4H0Cy3?g X39pY S0f΅<<Ve,MT~Y w^0τͳ5lx<>1σ/\An^8\A;U8\Xh^'s-3aW7Zo2o[-ݼ2)|ּ0o#VEHsvhݢyI~f8ּO-G$EYp,߹|MX<OxN1S!0Lq/cb<^Ðb<>qτ_ƳCG=tbDO1].)F1e so &RSo c % 74JBf]h3B/K#?;߄5'y&4#U?*˯|]v7)m ӷ+,kA:ҭʊV{@ԦM"hRK_1;ĵAA~q{DOӷO&WghC=1&QrMGI׍0a8%6 JNzRrFLY%go$J 8Si>wrY"Km:XA9qP[ c@5 Z'Bwk YSa5YpIU|zy_ԧ^Tcxk"1íxގw,gSVAƅԎäv *ں8Y4D-$Z i<°Q9|Pw(5Jt<%r9mk3V7toq!lr_77-[G-9gpSَ uGZk~ j9$YW@kk+!պ [+a FYB 50̴6bkS-:a뼠@uނ*G1ṂE ^B*T Q/o{vfοά3*dgۙwڙ;wٙmvf;s*;Yάdg6ڙ-z;sV;s ; Pt;Z΅Ra=7p; >]j2w?PK zt5[jG *org/apache/xml/resolver/CatalogEntry.classVOuf; -ڛbaiKVawL]fqw_L|/j4iMl&^RˣA2&6.www.?sH/~:F#؂1"hǸ\τq6zhMDp^WDk2 M?rwt)i"ɞY :uJyGpۃ.cG^Pn?XWŪeR8[MP?> ;?g ۘELc_{)Ui\nrj$#ZJ5X*"&=.GED;jr}Bn R}5)ʿKJ?.Āg?0Hïx)tBnRԩBw槽KͿZ)Q`׏ V;-jKh⦢uΘvG4v ؟l¿p\%5VÐ 裦OE/=?Ln9ƈ%hQio5s3hѪhىI%1MA;pv|-L`hc *#w yV5B:PK zt5$Ϩ.org/apache/xml/resolver/CatalogException.classT]od~$ ke 0>Z:6ā0ljҴK9B 5Eb n궮9999~$^4&0lޓp+n}~٬p PT$$| m[-- Szm־ Y׷ZUN{ )gR$IzqC Δ~GoջfQwL`rS뚟}GVkj}̦Uڭ4 chx}׾0%˰{%ؽF͌b:_L;n ,둔 ۽-TŹO3Z6{1YjΎamnqLy9nd ]h*бnbx=<i_\'s;WT%>„LǤs8Zb]/N1 Mn8YTg΅e\Ç2 2^,-lS.QlXdiTeIGF2 DŘq#I6m }_vA-b/>tu3#u0Y<ŷY—"x|/W"*~3,"x~)אή%/ϗRL4>5~NFr#^#I]8=W2"ERQ]Y@jffF̟33aR+;c<(4# 1K}G~q>ڀQM|L\dwx'&9cWFS4|ȴO3)KܨPK zt5Գd,,org/apache/xml/resolver/CatalogManager.classY |T?N\LHa"ȪHMN08 3UaHE (U]kk[{OV___n}V|d&owsݼOG^7y C.k<\KNǻMbOz3YRw'ceG4%=l?}#tZ ,an[{ VvF 8nwE[ͶX ,fe9 BJ,Tt.qW&G~DJIbJ,*['XA t o9MPަv3@P"#<( 0XeDYeKBE;e%#,HقhQ=pE69 \(y1x˰M!lEpǤEsU<38_7&󦣒爻з!]_oÑV Ai(Tvu˒RBri/L4yJh%XJhDCfQb~Z<1>1 ݔƹplqעS;R-Gc 9T" "͕0 K3E3ϹȟaIb7FncoSNJh`.Z%o J,,H3Bͻ `x.E fkQ${Io8=#LSnmtA7ӵnc.KJ)2%A{d.]]ն8{0>ߠhAJw_ZJCZ).uotC&`q㋫E0#/Jy~{rt1n{Y7kAy? |́P?0!z& U-9:ߠѝpcߋ) ]-l_,lw?wQ;Dip'y#~Dj-tAү~̠#bhlK3}PaA FAqlYHip<6OIbk z^.!i0'S_T 2^28d8 'ě:|Ȇqx$?e;Aӵrd#)nV]OdS)G E?BvקOpM&&֑o? ~4؏‚dҥ}K~}z_ \ ~Q(oA7JTlRφ*HWEU[`"Xm$k9%aaph=[m'1{Ü)O\RJ"o(_Y2JòKd)ٷYܪ !wtdŕۢ1y,Hގq%r[BN[vX!UҺXN;XQf:'c˼`yk8HBi 0Ⲵd%/zXBJT@|}Hkӑ,xEkAITIc4X91Ͳܐ5"p750bbd*eII~ۀOkܾʖ?upopoJ(# G0o|fUIc*FG2) > ^u.VAUkPE#![is^cI?)P6,V0bFA1n+Bzgv 4Tdi֐ĸѳإtEsFVy;M:h$h@BynѪQ}(#A*G lLd6ho@.%@iQ;Dvؽ4:-I {\6TVJ M:*:e]9 M馩{ڸرԍ{iblc}?FEG T =tbmE8D3OˆoDѳ׎8H'`D?0;i_ X(>(?1s|# 6SS(FWDi=t7VxkUè֡q}U@w(4"1L7nŝOŠSm ,`5ª^Zvw[=tz*V] (X{X Pd[4S}Y` | gE*>/[/ hcԪW>^}j@%w͐TZ]]_K@VtRB%P Έ_^ȯ 5 P)*w47& ~wq ^uo.vJrlraZVg3kZaj.o,L&@p/e~fְ:~/3g`__A ZMڂ΄~1O>2s_kZ\̷h9`0Gz>?A .dd鿑eA-.3gKWmFدl|mms&[DyZ9iTUdkhvNpע}͡ē!QڈQ-ʻeoN'ł~#FqJN#C[!b#ƾcCJV' `I~fְ8Xh+gk& 7ƍ1À1gA ia,qxRyp\\$] 0~npZ0^FvhigtG:6Inxx<[=I70.ۀiK!,[[/GVOp??$!i~C)M48\Z:gW?"]d<O]xsSm;i >0fs`Q*sMGe]%vP/VhnGQwp[nݮnw{LfHk{sw;9o(i7 7K?#'MvzOV'BTU~"~tB_i.V/HMwEAViMߪt<[x~N|=}⤓arnʊ_ֺɫT^r^#,2$ԅB]$TPkXuí*Ui3:ۚ;71q3־%=5_ikW{#cE8Nd+dktQ5ۥ;]xźxXA[r{84g],&ޮ Fjz"٭k,b9LJT_ q%z0jWm`Md,Dpd=bqS(h&6S I} p5t-[pѩJ`(M0UV%e0.H)3b">HzzT Fմ'60$ҁc+ƕM!Z!&E2d8RM`2p"I,8Э vѾ'{3a͡ѩ Hi8M^!Z -I= F2 li# v odBFM gw7`|"U0AQhjj}9,mM K.HG$='k:ցρv Enk;Fu.29)n Fzb^=EI-קGCu9ߣaD9|H!س[)1fݱT[l9*bEM/\ImsHu~M9 SN]rP:DSF& G8)7_chk9Pk eIdeU+nm9/.oaȁ3VbGw0!&cfek`"9Npkv&Ě0K6aC9!O] =wM=AKMvи;_k41rejSE5TTUT[*OQ2*we* Ăp" ;$&|(&NPKϴdhHmjY.j?Y7K0- E*5}`8eUڣ{4RAҰ!'6'o8;4 %UC¸^8½N#MjW㿠z7k/5;cj9xNW\jX4>L1|Z[XdObPMALJH,J/dX%}JsN(8@!ރB=4~\'dPOo1~j:GD26JoĮSq}`\j@i 01 0cADTHZ֛L>cG(\ ߚ)8DMO)j+Wnay] _eN}USҺd(j Fį3^|,N0bH!+%wZHFlB8a |~& ,YQދ: [^ ǝ0@T<{w@6G%7Օ0+HCX>Vez`%3"f0gthrabCu fGKOjVS%cPe*OTѻOˏw/*3nɍ ysO󳘠zN,4Jى"9Ƒ\!.6i5#el6"iFI2 d~UrLD[$IGA*2%rnfU7ım$j3ڛ! [qHG*fsYбyC#зvwMfg-Ӂu:[[qT!:LGN{|`ք`&(f=Aq+Eo=EU4 Q0}E˂PCt/@RO9mUv,#q~j,7 !-< Áw?p]@C#@c@ )@x ~G҇?Hq 3\[iUӀmV{mT킁j%,v ٴ`ezqWB瀵Brrs1 *%T3!0lϡ5m |]7Zi:|u{ c@| ,6 cILxh$=E:W|zw w|yb4Y(Ӡ7wԐB=m1VڳHv2B|QKD ǦH*1FwQ;8%^0QOҋ;Η DWu^":YMO?VRr&WgP-N~% 3 t^3{6 (Pƥ}:yNUqNnl|H]:FZ6#-ȨA3$,i z)kKQKΨ2cTuU$$Fyh7 *7G.{H\p.6M0z4?Qulx&MhӰԑ$SK,rF-N,rj1 Dyβl>"}P}>J5No`]ں o[zO V:sRI=|es%r̃De>D ^{9䀣U }(?B4#3P?elR޳=fI9T4\ב@E%PO73V-̠(pW'aMC;sYm1^]k8x=Bm|#pťL'NmZRw(Sa1)rm5Cv9Aw  BCUEiK{P󚜛@v+G6bۚ"Xe4PFؖ5Ga羍Ǥ5xᑁ:3lg7 oi 5|z2sMҜ0 6?CA+L.NN`3$i s`:bEiBT,eRSgs(PMG`+T EҝU{Vgΐ#5B>Me /&_,">Kq1NKө( LU\<7#PK zt5ho .org/apache/xml/resolver/apps/XParseError.classU[wU&N2 m )$mZ@**mZZId&Lh b7x_|EKO{2IC"/g뜿OуHxY&L19d,q>/D0`o+xe\]#"R&Y&(qE0#(EE\eגk2dKP9,Ӳ%HTk7$ZS懄mkY d19g .M:W1fg$68]RfdSE*$4y稄p|r21&!gN -yC S:M͌iV0Qrд)er"5_SMHVSF4n~ )D#s%K\NAR JcE<3U==E'o6+t]@E_W?Vf ׶n\ u.3&̙|ja-"6UBWWD"ao=C!gH֑. @2js[zHaA xQn&q$T$t1FBTڪ=䕇ʸޓqSX=Z*ipM;^d|C,ʸ#V#*>'2>U>X㥙A~.A_|)+_㞊opDƷ*âqOBY*xfjVdh6ַU;ӺA&^}NEa)n]p>N4.Z~8fESxo߷=ub # ӏZ؎f9xIh~_M4kYVڥ)۳lM E%*k[E;oFH!BM׽z'[/:p"V|3Rllx]T[v=vs /"@nutϤwvygw^ҩ} /}nlk؎CQ8EG8H4^92:.2\U!?%O 8eɇh- ϸ jE(?p9_}F _7|CƗ|Q +GI;ܨЃJ3d3zhhժDH'_y'k%Tef.(vC J2-+p1wr`55 {;f.jNOJg6$/[ Ā2C~/Nߠo>5t?KeĆ{"Zƺhe ?a6v)HO!-el-c[#:V*5's%N4Ѓ-҃4b=qM1Y iqguM6@1D2aPK zt5;; +org/apache/xml/resolver/apps/resolver.classX xNf3`% a)jM `dwHV7qw@ֶXhڪ(>j[mj깳3,Dks'ŏ~"n)ƭYv?rs[`#p}rz6?8KN C!9>,/}~Vk1H~~4 ar}MRX|ڇ?Yӟ? <+* xA/ $,W)W^xCMxG]@ |$'Obn#A]nBMk*2hZݛL*LzD΄H`#)[OoK*fZI-e;TFb˵zi32k$al PHvڭt\\e&5,#^Oi͔ 3jFkXc xF/E_+Fb<ͬXfz8!`tan؎m\F&Q9BQϊREar GNVhVWYQÄFbe*k1R/1ӱ8+R* /B+JdB- ,R՟Iclì,(bH6ǩ>RҧMфhT65ټNǶ|8QO#A>쓟$'+?|TJ4q4J)95J@4|TШ}FJB%-Kil s z.?xLZq>j)f{Q'h4^^*OܝpLYm;UI1 mK:wD}^AE9FK1.?5Ҳ Yrr4`ww,\<̲&J"0C|Ȯ\i5D:a瓤,h;O71\M6Tg&jia:o8Xa]vs5XLwiN^\| g8Z;:0#wN֎D4R .B&h-TR$eX,Os~~d5'2IU/.OHjInK͗3my꣺Se6zkʈgx40.]2듹M+[=ˀ}zF3K3z1 ~>]&_3lMtw59YÔOZf7;ϥdm헟a;̋fRVP[)yC ~N݂]JuV[7)4bʦQFsig^Fw}Ii챿x*$ʶ؈R6ƥG-Bk$imYf4nWEPݎ ÇX ժC %h+$/a$B%Y ,#ÁzEl 'P%yZNNtt/ncxqԽ!T>S6A>fxyLrɰ}b̋,s7g 3l(WʔJFe ¬\V&|.jWv.\+Pc1ǡ 0'2I8' `.p4hCLF*^$H3~G}dq)VJ| 73&|,ll%so1G=^bo,\Gi ji_̢J̡ǗHq4RzhDX4]YX~ +oG`XW;۽PK zt56f )org/apache/xml/resolver/apps/xparse.classW xT{3yo޼, !QDZ "Ȣ(2y$ JXZjF(*`RUB]Rf&,J}s=ͣ޻*Ec\E,q N"Te:~:.7p`2WkFG:+ \?D=rr$-ެa[pDnӰ>].wH5:SZwi2Gǟ$xsvg$/6~Οn8ұI:ju<1d?!'%:gtnuNIhOK'vX)j\bŢVjf5qJ!Q*%2V,2N}^3Xh$S*9IAtS:#v[&LD F l'm5C{^&C9(%(jۣݑd{"C쩝m\G9LЂ)ӤbQ"<錕̉ fVҝC/| ͞80!hΩh,Mfp%Mps&etmR$V3>i /ix"|S:'FJd-e3v98ع6 >=I m/Ml};^LfӴcW[{A$)KV6s8G/Z$/wb&c 4_|ädkV:2?|+Pҿ%MlV{jHEKlR!LxSE!+MfVD̊b9+hDlAD_GfZ SxPƐ2odbVB)I$stWvyy$] @(WM9h2$/ˌdf*WsAzfPVQwY?VY;x "˨;4RS}8G+FSi;]U ))lFlgcd̶+ m%|hFVObg&UbP{NFFP} IkJGOםtW-X .a[?^) =}Vov2s8.1rw3EjW9^{t:jφ T#Rږ+9uNaIYܳÜL@1SeKEմ&K#Gt+a9~&#nc?~% 9S 8OQ|%Αuk(8kCy\͜cwNO)E-pa(-&ˌZ= Z[CjXWk==29}%.. YЃGuۡ9KR.q(^9ˡ2$סB A](EIa=p=h9kz({e)ްrFe1u]kXA`i(`ث֚=uŐ,.3 Vnc=E/eQ4~~FgKbHlDtX08.G,-R %1 s=)U. $z0*<@2 Cs=0¾ ^;6||rO]S78+Ǐ/@ו;:_uC񺀳/@p}q]`X*zXay.H|- }<` q,M=#p @`g@NL$''C\;DnSj+CPÂHS}GquhGˢ5Ls1TH#Tjd#$:uٗkxiq?D)l?(&;;C@ƩsQqA8 #p2BBMlPFPP:#\HERFv&VXp7~M56Sr oqSS\5N.\ŏ Wr\+N샕b$5cqQfaah-"RvwuX'6^cmx@qAEC< fe_SN8^T:r^V+ExU)T>[6WKUj|NG1Dy\M |^+z7)HTʁLsu볐ܥ 5zkwPG3Bz!T/el>C飕깈RM|Y-X $[m5sH>C(g" i(g`6a!Þ$=q?{dө[)KQ .:X'';K1@q nP+q6R"`J0뗰ךPsPy;}V<waZq^,j]<OPK zt5ܶ5A 9(org/apache/xml/resolver/apps/xread.classW |ݝ`&I$&@)Mm-W4%D!Y݋ɡVEhJj,vU* gڂQz Q}}}uvȘ|ڰR* VRH懫T\*~bkT\:uc>5+Pq:7j=RnRp2 T'j l԰ wCZf /[ĝ**K kvVޫJo*5<9!'?,)*fGUEx$:Sh{Йnz0A!_0]gX"VLz'D*+K j޿C!!7lwx)c:rLbU1(P,BʹKjD:鬜`}0$',9C@Tfzyϧ4Go9!2u2oWgc ~lJi"N4P|J,΂ kzE%AĻ@~̣kl4y) ~b"f_ԎG9S0m3MDxyvs-򉼿E\w(夸Ӵgfo1ufČ1{~Kcy5T"G>_5;𧈼c1-qR !ZqTn8'tiT1?PCez9 a>>|(U d7eVȔ:-Iʇ:PHf8IُAo?yc "KH1oCCWSBx<Ә:hgf HXDK TZ NbN'.VU*7hSGSwU:AqG )!ržZ6Hùh4\ Rx@A#ng iQ3ǬwJah9))&&0McWMעvUQoy Πd!9LH1T^էfyUNl%&V}GxJ6Q$ʹgb#0k 8c:_񹽅i~F|(K G50U6b(JH_g%UQ36Xu𓟟j%UOmC-53> bZr>'El(u7x _Yp6xž;AA@\ˈb o͵g0gU`cplnb-Y;6B⸃|1ʮƝl-bq7ۊn`q{#x\'xJjRHM)59i.vIxA:/JxIeHU2.i5^R oJ-i3ޖ9'2<c'r=><_ȧK9sh]dRS\1V$dlh)S .UCI2)NJ4$CuQ G)]T9%8 *.]"*Fof86IFQ@9e= ӮqM|:e-KeM5Qp:& \/%"B:jVi4~BP U[TIbeH^x(wNq[4mDHYl9:JA6@նRe(k32 ?'3V%yq*v!'x[2 nS#³*>^XNrlبx&?fѪh'Mp tֈhz H}=nb{A8I@TŹDx^ @<$u=S pL{gQf' g6 <ɇ'#E`w١kw6H;U+ ޫ,HD_@rdSR+%e~#fGQ@H08z\2s+؋c/ |5g%Z!:bDU噬%6FFT%H-[oC-NDV\->pZSP-/ Ty#`U>:^dO- =:UloN(_*Ng1%~{YCrLh*[) A3j7f$n Py9*eU"'c PK zt5RהA'org/apache/xml/resolver/etc/catalog.rngX[o0~f! C u׍Ic6MBCyYq"Yz8`0>D;9[3hdhn3805CsXd#Dad Ō&.K( a|(~$q66sm gK;)LJ2#b,C|;< w  'gݲg%c0 nmwڱoۃ+xscðA0e NC߅QѡpcAKO 7w04Ŝ, dbV#̫Qbƀs [wU`z{7_|Rʠk=r |<;~e 8cVx(SvPeR (tdyy>OFS/u 0UqP~V<>,RD.-4q!1H'YOԱ23k#VQm\hY39wbI QvH˴`Qv4hFŮ!HܑhqT!nN[fl& o^uUjv_ъTPl2>su4Dr|p L~q1P? Lךxؾ2⯖ PK zt5&@G7org/apache/xml/resolver/helpers/BootstrapResolver.classW[wƖ5< b'AlORAؘb bsMzXҌ^4MhӴ$\4 4$mҘI&8c_^?ɲkei}ٗo}}}TGCBf>G 2hw;zFڗ f3?lZEBuu@=LLHdCWI=_wLAot%ﳝQM1CcvhcF*c8e۞9zfBwNJ¼i:=gzFc8 lkeޠu"n%ICO v8ͼmPs =]ش >Q\}Oϴ-`NB$X/rGl' 9t4ш ˣ1}H1mgS- 3wE5́߯ce~Cno$@jlpz#ƶ!" VjyLuԚ׿8:;6ZR Tt[v1^nUԒFeW51д{5mM 6_$T7UoIL\ӎ?ivvv:mza<ͧ B =%Q Z;)xK: c>*~IXtsAIXz%sE۸Z-=T0;[PkQU*PG n_*㈊? ĻRg흝NƛʎOԢ&jRg|o·%4b 񑊿_ei=tHZ^A?'_z$QN.%sgب%[ vϭϟHٲ+ZtfHX,,z-O7-wևhtfNiCx׺xDw^hKgwqSׄgJ.Ve6wƒ^HAmVS5jrAhVO1A=xw]=^ն_{CE-B~'uӎO'gh[u#G "؄͐Ť!_,Ho+џo/NVe_EŶ)HmӨ:4Mm9a%}Xvp(CmR5"%$$s-/[[Tl-\/]GsL0"v>솆=X}8*O,:N HRǀZC?|=%H\H[۞]g.L1q rx_/LՎX7:,~d"^ae< D9 LҤ4I[yƪBq,8JdFӐbؔ G!Z1{Я1ଊ USW3-Qq= V WDM#%v#XxuMjjΣ!V #9ABTAE`gpR3XZDJ,x]ni9%\BF["3.Q8e5Ph=46Vy,̥wrDXy kNc " Sg"_'$+1!,xsDy Ӭq/b aγ+_ΗW "U} Q87-0ǻ7*"BhyU V>|PL }|b˴>$X)0 Pf_3 'J+m]M.asO#,;ؐDle4s۰YVvqCJ||4~[4Co;a@wjX L*M^5%-PPK zt5q+org/apache/xml/resolver/helpers/Debug.classmOPw֭VAq> 1&!N$&$صKM2&F!26E_sϽs@Uw]KF>5SZs [))l3u$w; X gjҲN?3DfˢP8r*cLk+㞊x@=9玊1$jEue cNZ\6=bzZ9iQ]9'i}0R܁3C 0Y>{YUt)xVHP(#J+h@1 T9,1A+58ILӸ*mPUBW 'T?[ֲ0 Dt0ˡ毁T #\$p%,ޥ<' |Fr=AԊ-_DX9\DT5M\=FtZz;R&+9JCdc[伃y"Ε@)r.EΥYDE>l)!C Ǜy3R ]'] Mmbj{/3'o'99+q (uުU@]7ODO'JtLx$ĤZH "IF2h @iI3]m~-civ@qP 9hs ;Hke) 3G=۰zvɏI)']NoahKݎ:֮1{`|E$_kwYc,I)2J\UZь.A[PK zt57Nr0org/apache/xml/resolver/helpers/Namespaces.classTmSW~n޳YH R[Tżᶥ/(mt +uF76٤K_ڿ@D:?swa?vys"9lKa.$&H _ 0)|8~HpQ8*0u1fQߔ0[,q;euԝEpYp4UdnS34Kk36CYZ-Ei=w vx-e=nJMpι]aH>C!>Tven:֞k-eñtEqq2Lp׀Xχ ޽LuNrHospCN5Rr:c ňʗ=8[M~W*S2`qܕ~Q=aǡXEM0LX:Cn.'.1uA&d<Š_X,ȸiז!sh&Hߺ>-3GKJ7l0VM3`HӬGݿAjar"c,)-dD4C)6)ބ|v_`/DA)   *G+97{3; K W8=KL@O{{lG$6}*~EOHg'$l#[+#)} g.Z=U|jCX=2^2|"^jƔPK zt5ch.org/apache/xml/resolver/helpers/PublicId.classTRG=jۼl- `!a?&! ~1H ^5nM ᪻|q%_TrFz՝<O{Lؚ^f*8-`j}`*Y~$A:؁8n9 zj`|eP+?ýQW[ u%xmQ xTJ88=x $Њa0NqEÐbA1} CaϣѼOzp~y?oWxEePU@c 4Fd-'d2@<)٦iAYle+/!qLPy4cznsoܗ.nwMJGYw-㢣˨ȎxĦ H0ܳ,Q+ N)p ([+O(pY6)(8&G+)Cc,J(۱EIX,,t ߪ/%w: } Fv`g{reG"~r5βW[u#K8[6EN^/ot`7_7gȧHqy:;yk:Lj.{X N'?vPK zt5-c}3org/apache/xml/resolver/readers/CatalogReader.classPMK@Wk~T{7Az BТ5}ƔnlK?J Noa{{y88 J۔p9K*Trk鸴zN6IR%2\xtr@l.|fM)p(p$0$\7.kY埉 v O3̈́F>e]TlWJD~5=8񄳚2O弼-Ӷ;VTR|7݀za Ыٽ6p+PK zt5kV!6org/apache/xml/resolver/readers/DOMCatalogParser.classu`Eg+ށ#tg/؏vRӯVjC +93vtA2⌍&qWa{f5"N8 ]TRkrQ8 6AI _7wvp(ү(L2G$*AE{:PyPK zt5}э+6org/apache/xml/resolver/readers/DOMCatalogReader.classW{|Unv4I[jI -Wb6m$5IK_$:i+_( EĠXE# 73fҤ;9޳g{QІsaG6\k#!nwJ QpHDn&rx+@ >+H"'"4vGħ4>g#>""$/+pݥk!ܭp(zF J|SAߒ÷#xߑFT]SpD@!=;mX`QmDKL\e곺ӡ9i2Y=#pU55k @\V ;.PmXzonO얆f2|/,A#+pEHh:'FDF戞DKlbɝJ{{vvIi|vn9|v0,Ls|oTsa5 CT/Na'CX]r(+f\ F~-ؙ[]Q Clr2Nswzr["pۨNӮa[@.9mmMr"7b̓R=Te ԕJ,wmW[_PMLZvCpaSV?We k;vJ2*4Y1=&VjfnJlvjJ}y-L VhÔ rHI1暸ǀoIV99zj$e&ES$\TC$eRz!OEUlT}cTٜ3*:Fq䐊8$N $T0xDţxLi9< DӒ#O1~P͔ &TO*8)<`x* n,i6ۙFT+Z`Ue~h2.,vM[K7.10Sr$8h)%>#T@"X]\y 'LqyF/-^Q;^ ojGŸEūuAǫ)UkPm6 kg{K{44IL!;O_iijD֭@= 9v}o{~tjDsU XA/kZ0?y>{b頖TFyΣhfitv*pVŜ*]sŬծ9df6_|+oKM33enKh4ʢMq_\ߔP{dk,m@Fy6tiq4 z_/-RЫx_WqxAZ5K]+plljX:UψO3M l9HL4je.tp_͓ka[ Lx+: KtTs~v;2cmyT0|G`qiA_!W(Vj .8jMx=W=x\7Zlq9Y;,U61b(s>ȑxJj],i8LjKу>)!.50>mJ8Zam@҆)6QK7^ @mo[ :931%DZ`}q,|L$cA(Y=d V}K5(G,j)1ai2 O`wL*cX,5TB| H 2ݣ"O127\ j}R-.+*E%QK(Vs::űHK,zmNoGQa똎1ή)\>_jZzr}ч v<Ε'haMxgpO8+xF4Yω6؎_E^=xQ&R^0_6Ig!*<d$vbhk{8HFgO9^DWn,DO8 a܌7,-x+a;K]JMa!͢qbdk`d*'KǑzk{M[borg/apache/xml/resolver/readers/ExtendedXMLCatalogReader.classW[wUNd&a%H(bo(f[.Mi e ihrzwEmQ[]KE]}At|;Y,V'>{{_GTc=N蒏 vy@݋A{+w4`q?xTxX(zP CAiW1"␼hȍ$ᔊ\dT;Yil*TTQpT@1b۩fFRvҏ#V6oXܖNzdF-T&Popct&RtTOل\k0a :xP̓Fpd8f:yRcF "l-=w; Hc4Y=i )K`+ݦ>lYY& 2g%^#jeʀnC̺ya+`.\u` DxSZ/Ǹ&%7]!KW&SDҹlHH"-҉fk GAʄQ=iDhS  y$ 8N*84j8 F5<6,8ќ3f A#g䆊 9YSS?\YV4-rCa]Јd*1;]_Ԓ%g>0 ֣?'5*'v| W pH:\sEEzڻ97c6qU?|P30q6 鲕lS&l;ہV<\v~Lj3ԼAuFwp웁34]_{]MPg 1sxo%:FOX KiU; ӸjBn)ջRi.k$w$ZˣW^%\X`lxWLc8>*;8perEiW2)ۼv/{ ]=%eֻ!\jc01 #ꋬp'pubL'>pN@+ߎ+ډM؅an~_K,cԌw%=bV`"pcH80,aьSl%pTg(N1oO ?)q Oޕ}%; ̕mv+Hi#*[R- p_f2+~le+4a;Ý<2+7Zq\mq3NeLyJ@=;; f-`j zF4g )J)4@,'sڈܹ7Ϻ<1 Nq}z3<~@>BiӃIS~o xEZM E`X4JQ*Rh]*o=oɻڥr(`dm*-W*ڙbW_PK zt50}';org/apache/xml/resolver/readers/OASISXMLCatalogReader.classY xTUOU%BAؗBBRI-!)4!@Vz$P=ҭ-nmccqo`PqkEpmnnlGv>WK !{w{9[<Ï2C;q_lx͏~冊B9x\G/t %)FˍƗ+_ :NtIMU'M']Ǔ[d`0* |G=B]HFhƈXƉx&D&wN{NLjMu#:M7T,ә;T'Ne:T *5:@$J\V:6bs{"n&bxE%208h7,b.S>pv"V4%E@4"Id|3*jed 0BJ%Ñ 9$b=̐v{0i+XGũ3hȵĂȊ@<,+Nf 7!3hi7jU-üwkcp4<,O.,;PTjl. Z9l FI3Ǣ]|$fl7Iۨ]ESf[nX#!-<m8G/xm/6~]>#f5ɣíX\md: :ⱠH:?gx*V4 ʒ ]!axI^dZ]\7ׅ77::X쳣aB>0 wS, "{5+ :Q IU2h61p.f?:(0p66,["6pkJXt.B|д[p jkqA+So9l-2=gAfPZV2kู)¥V|t2,Mu2dTNBn{&+3 1'4"gJBQss+àĸAO+0EYP jZVXPA!97dNtU+ j‘pt5MdE=b^/#jٴ|B*vߴw3Iio\^qJqy6έ bW[7j .nli7rŢ7-j%䲐O9="Km#{KmLF; Ġ%HcGǒvTN?市KE=,u$?{ ,@%p0s'1l Hk|@)\hCW>ݗSO C'YVZHp uh@6MwXVKD`1 sQSsԖ樽V{,)݃A[톑U>?yUpV^K3T(dWKY5ɖ0slؔn nD! !<@wĸ2O~7@~#.q;`pŽo;Cu[XýӘ30 gbb-c>J%ǿ3A7NGF^.(6&?SJ< HᇸV:6Xo1c^ԍ(X<;RtrLd$[u2  E@/\́^ nMĠGy9.2ZV*wcLV_ʽ1.؇0΁4Ӯֻ0Jѻ1AV-n+:bكji1yݘ܉yuz 6˻<DzN(9܂!T1KΌ?Mz7^O gt#v5HZD1x210Y.t;'VYcyYeeXyU'./}G,}])\(EEȃ>ӹ- 96t 6CΈ-zfqٸúp;s3"=p{='/pu? \󳸛,O t]0ܚHGƝr`p8__|׳(Kwdw.ʈK1/qg \޵S.jMT鵃L:jj\GgU5K zp ^lA.4Ћ͈=+ҸKlܶ.,q6#wyl:9q{HN.(P~n'*2Ȕ[{ebtʓ/󶣌{n)-YمLICrx1a=!Gy=+sNzV ӻ_Y?ӽg/^)v^V6s)%B u\ܪSILu6h׵cUt8~N..*fs y#dQ ~…O2Ϲdɻ w#؍؃>^|GH4H`cF),UO1ɯlSsQ)WQ+J~ZcyQKun.1|1OE\j>m|+H9]ѤhH\cgb8{&o}&Nig߮)h:rUghA3*hVZC8b_NW.]8.5I8)4z Oxl.>RCJbbSOi9/(@_Qtߪ+-;e=wRvhW**dtJpM$o>ÄGV(d\nv;_yw(9n<`󻙺n9{(xW öM$`!ܐ\G 3Q}0{ 'T/O|PK zt5T]6org/apache/xml/resolver/readers/SAXCatalogParser.classujAՍOihB {Bٽl"̌⳥PA..|;#IV(<^”[^s [ξE6F;Kg2XVNjw.#mu v^h{&-9\׷9pYϯdЍ+Q|S[)8ns V] JhgPK zt5H(6org/apache/xml/resolver/readers/SAXCatalogReader.classX{`Tՙ}$<" #LX0GxbI&0u]@vvۺ*- i+>.j[nյjw3W?s}ߙ7Q9T}U@?y {y#U{ ?Q?`"ˍj8U 7^T+_jxIL¯4ڍW;(/ɧ]P7ɑpo4W뺾pҢY`1J$::¸YnDtATź,:Hrn@0p[Wzz !]'ظEUM[)\DT2idU jJkhvMV(#8L28O* iV_ GcIZz]:d͈nŦ~:9¿?싥~oqG #Y[m٤f٢c/lZ!J^(r\vZN̽V$2Q]vɍ_nХSt閐.=s]$V&)c_Wq!g|ϴmiۢV\EiL8CwB)i5gA֜9GY+#^.ֻc7Aʘ1eHФ螋@ϙ4Ävzs4.9n^J8 42b#]~=<&0mb-pjhv)fNsSU܅scKO+Nʪeߧغkܜ5rÖ+sT۬,**:twF31k{M)~$Fc PU&:9iAE\P\+ˎadQF04qØƂXt\U-X\1|RXtsښjͦN}A,˃Aٸ:X8ž ^SNa#Xe1飆'ĂNTXl? d;UjRmDK"%L+hƙr5؎7?0ؾ0Y]rq8=TEk2oJԈGjJIE2AɲILFBDwlٸc593?'֐!g:i4?pGW(yrcw"S/⟉s_—7p?*D<5dO.m0pf;z "SUV9Pbr 4Zá +ɡ'-XjP9DBpI m ePe=Ww2+p{흇#4к/WRf8+g6oUGSM0՟EuSLI0{Ηi;oJcM)AW*GP]7]09C&рϥqCW~Γb"WfFMry y8H C|#fuH'ߜlqrV1MځYYgi¦)[1wflQp"3y2cU9ڏ󄞓)2ZA2!T6Gs2b`9ܲղ^Y)r fd-: FlM j[pnCv#w xPnijI =xK¢=2S[bDr*I]O:e$GM>(NGJO-e(ñv׸ Ġrfxv 2`O.PLl0-3PQ!IL7#[>Oۘo,fOry>'] ~ci*.aq.`zo0l9pDby!jʇ8>pT^"% ʗqZ9y?LW|Ra2Ce|YuY]j-d5eZ.ĂV9X-hcC"Zf)\_ZE<0źZtO%jYqyuTN"^S|3aNt7\4źQ30ଭW[l~bt;u?O?'O2to"u,CPVT3r/ruYun,L*|zTD/SᯇQ8UE ύ{}caѴX[63)PK zt5p;3 6org/apache/xml/resolver/readers/SAXParserHandler.classUrV]8J  ! RzB1 !P>$$NNN/>~TH‘v2::{}Yi. Ҭ 6븱 7ۃIsG|..ͪ4ii֤0`J 7Gg;CJg޶|atj>' g'^SBEKƪp&wrvE7!ߣ͌_7<G +u0Q\UzS7u'ΌxQA2?YC"D5%*X?KnJ+kXز4V4WMR$"{!+lXcإŅp|ömx*R]g ԉ?u{^AO2f sª++f8L"7)7ǁI7`/qi<;ȵ5c8 d0J~'S0j,ەڹ^7akWѽly۬Ȇ(8rSLMLUu*y[ߦL;eilS*Ȼo8>WP 0dcZ8$N\m]A)^>zDlMF6YCޱSyX&a^P+ƱS} o-o 054a;Xѯbs [4FI1.!f4{pʽsҥ.`N{(oS]t;#qǝZ@lryg?ϱ 1alsyaJ+Phwmܝʤ+RҤ 搡=L`x;Z(p9S@%HP"xc3t7;:K+F~Xs+k)N3쒏2i<]97lS*Ob}[+Pw*ND#y2l3٧7E*ň,> ?EU33N{Z`aƃVq-Ƹm<>p6=ɳKGy"GHȭG Y%ALK؁G"84Oʚ>`Dn(y|TsY/{)M. [R ;dJrm.,'PBA5VX_q;rma86I`)v@] ԣ(j(N͍nO%ǖ6{ /[kG$W=?NZIj1IֿB^(#wfZ%[v m"'<<.lѤ*g?c?Pʼn*`-PK zt5U  9org/apache/xml/resolver/readers/TR9401CatalogReader.classVsUtM-)-,HRJVVBZD&tnH6-"0:N:bȌY7_/I*0a܇=sί#Ѓ; ^À~脂xW N \LiĽ8#ֳ^ ;'}!#2F،0 &qA/ hJƴK  M$2M>\BJ1ӚҚ1t"%{V/2OZlDkYY/Z/exI;t8ٚaed?&A"/USOi ZD" 3_m tM˞J\Ԓ9oZ7̸iD[֍$Oۖpm[ .$S^SX|4KBLKVɴ)inx|1ndC"#djW˄J4?tAᲊNR!B* „1##"#(ddU*t<?;1GQ_8LTP|TX3(:4uPv6J*pCƢ%,SqfվDMᖊqU@e8P/r2cr;2׬Bg&ƒa0m4SXלjLRZPj4LņVgDVL7"fQӵJ?eڶ&y^iBï4MwdfHS3$ϰUC hzb AQL&nV(uρW}a0:bUBÔB*fjYa*\U^*W:eL gyZ0꽯H" &^g*FQ(ܶzrINh:8ȣ$7h{]U>=\pCZe+h :v 2bľʢn{A HQXʐ[VEaSjSk>׷+L}O~;]Ö2ZW0wۤ!Bt-hQ&PƎ'm"RJ麄o-\V,1Ai>Go!1VG=%:L`="H՚1L8.mPN}rIepKte`t6q[E|IW}E|GͿotNw Ff|v K*wE{D3?Mu$M(C^:p <:#$%{ >7Aq<؁^$崥ŨӪPK zt5y_F ;7org/apache/xml/resolver/readers/TextCatalogReader.classW{tdvg d $$"†Eu#F!i:NLܝQ۪Z(h -lPj[>zN_xaw'!/ s&/}xoq&zWj)rNA7RzI>o-A܊ۂd]A|wZ_ w{7& "X-;W.;u|[wIt|'jO>p{QRcR|Wr~OxB.{u<: qH,Ҧf4D힬M[fw/mͲ)37n2U$rN [v&&S$?'i'UdYQ@kp<)nJVs{`n49q3L'GܮdF&'5{xNEVImܘ +nz5SNg"ѮP"mAZ&iDq23 9iR'Y`EGZ2N(;FSJ LO[:%2ACJamM3FAljT<]zܤcKt ɶ#XKcwG^O42&S sldmsvW8F92>Ej$ӆ^Cu;}^4S=|q2qW 2y=x4@G6SɫVJh" ]xlĻq'7++͍wi3Ei YaOVz'[kUMR@.0p6bq=@ *bp>=:~yjَ+bbhCm r: < CqXǏ ~gr|r֨'zr'G s.q]÷.~m:2QDadZ|)<~r`-yй^H }&B6z”OC6I%o| |yZWQJ1RziR\kXfOVTWĖQF ig%/l̓(j_2`s?1M `ȡx 9y]3cZBˡ$Y(js(=2dsد\-cJVa]7ab.Э,P8ʓVE+c݂6ldB JEj$m3}ޢb!-U_gAcfdL_H'Ŵ (ֽ`-=+%K #EL{Z/9T|0oN^"ΏF)\Qԏ⊀T)7ҢRkW9,ǦŸ"b'N:1uÜȣ D: 0kTR/pe~$roU{{5\ KHe1%Uyo$MDX[pnc:r»{]ivPNJ`vqhί~ w%]mLĚ%MT:[z}yZُ]}zUUUr=#^I.[EWw괈W=0^ծ=nJNRVatMU--[2tnUv'kADYXJ$$ﴯ,ެwܔ:e Z&QO'GkR'WўC驇˄10ɴE= ?!tMCP]=ػ}\I߄ Gh@HaYQD!M[-t# CLb&EyD,b1[,^*xH>xL/5l<;IO)xZ c:\trId3<9w,wCroF$Cd 놭?ROsg˜i%>\4 {p,1,FeF;nrbcL\۶܉ !#>msRd83>85* +:-9}])CjBBMr<ZfYQYf*QW0)J948{؁Ww\@Y:bRӚ,ᣇ(Uh8x%K闓åJ[&DDOX{,ѷл۴S`-}zEnF;va:}%$#NW*Wr%Z[$ T`h$-0⶚>(Ү %}KJD"e8!CE(-1|؍J;]GogCp bFمtHB:c?'B}o1V /IC%B>zb =5LMMu`mXw8ĵZ_/nJ҆R]5~\&q}+H`?qĦHllL", oVnj5`ߒ`)7;.! %tQD mRu;(b-zvYgUbm0v=^|x 蝧.P>ЁG9Pm=C pq3 ""QCU8t0DQPQsmZҵy|;wxλP&a#p'}O8|Fn7zq7>|(_/*_/"A_kL|C|ӇzǠܦ[ CxqPĐ>܉r+% ru=W>/Kpԋ(q(?}1~"!~<,o=I9{/J ~7uWi }- ]Z:ԌT[@Ihr55iDcXNgӻ\lLz6vѺ@xK6&zV2)c@uak]6INhMeBo۪u fZzKɽ t=@lLvF6ΗvPruwInu}nוNXry]-)Jh K([7 ^L1R^Z,ec[FHA޾Bg:hIJU:zR 'ݶ_bYa"M'w/W.S ^B!&aN^; eZcp2^Px+mc2m38ʬaxVel-F?ae{c "V >> \1rUAfHOZ/̲uA [q*j}"#*8]զVY9Zkjju .%Z>r r95wДv Qxg(2v(|`[67e{t̻u$⯮uqE+Eewğo6E."ZQUn,EUU[tPK zt5RA"3org/apache/xml/resolver/tools/ResolvingParser.classY x\U>GI6[cyyX;cKbK3$+^c;̳4hf<ƖKڐP M 4uZBZZY,[q&uKRhC-ei)[{4,SOwg?k}?Kb+H'J:A"O/+2 )&MF -}C)ٷd!HH;A's ZEwӿi=|*S oC<|Lиp*zFvj!/ rkF1rZA\%np|y,{xB*q+T Uax-tB& "`}ۃwUMAț|ƛ5E-ߪV1դq31bsFdLF27Dj!df.?I)SL9cb,Dx;r݇veooggƁtvTt_OfʺHœ6bľ8[qy6a ܈5@t)R9g:Ld@p42R*uF2>w3Z%r״#g98-}SՍo1D*abDe\@"eGac$tH5 vX"2M7l<J/<(bœ˜bZskĬt<8VLM5-/Ŵ,2+dL:gcݗмX-a ŒhєefSF?Mueiܣ1"E,rs9``1gZ})\7G BM |9#ݟ]9m[zT/fE tsy+A_ƌ,aENFr"6p,"BLZة2SA_IJUELYIcc .1MPOh*ge1 4~R +d^dw&3 ԑA#y*7((Ip!Qdg{Y,Y@j*#'曱]kTNbJ-,-s OaYЯ:h`J[3cIm7dyR4I&b*E)UFv\۴ssRaTd͐ TBB-a"H٤1D9%[̰]J=s E|mYSZb9#tMoBүZ ,g@qtV8:Q(tZ:]:%i\u8CNY9tz'e?Aovޭ{WaW}:!%̍t/==ӻQ%\:nQ7Ͻ߯!SR׺ÒG ϡycBѵj8:%줡Tמ0t) "c|D*lUF@VOӯttU}F>O_Q-,'tx:?!^I[p d"pwN'uz__k D)Fi3|Ga)#0b`4bGFE7:1Mg1IᬩT ufw>h KXcSgfuÂIULfBf ~RAyN`&R[΢u7B+ܼ<ܥϙwŪ[_)4FJ*:пY:7rBi=tpp)Hw]rm4ayx,>g?Hj3(bY!Uݞ+^Tv<7NێO喊NӋG̏rMhYxuEEhՑw|:O?09m֘̈~"Do;\ ]*DOɠ?f,g9KU]ٸ0uB[ۢ2.Br ^0 a ]ВB$fs,۶c;Ro} r/Fq}8ּA{jeX|Vyx(7 N}ns4/RO*)YbxmjUge<7Uoubϸ>X&]Ԛ5shj-2^T=}ja㭝kaGͻAo_7Emo[[|MX[eg:Oӡ׃ig?:;!{f3|:5jJ]R2mjYn|z4/+Rݧh^MZ(ڛQ]Y5E`{IEs嫰 E-,XNҺsL{h}vLI E{ n+Ah-p{ Bi큇+pU>&+UVz'.Pp%eh#5ϕ4A::\MYGy=+^U7ky<ʷpyަ"npGt" _W,=(y9D>zk~܋D/KnILW7O홓u4Eu|\/j9;$T쳫ksX`6 ޛ$!ueT~ʳ+ m[s{}s0 ĈR6mE@AWG }Q[@U; kv.@*zUUJ;*kt*q2Ez(|wBdIy/&-d \jvʣl|E2[5<STְ>KmG(?~{8=Sf:(5U08fUfE[Lm΋LQ"^y mJǗX1}+ș?tNhhZk\ubqZ v3Пk/h#c쇊G0I0 S?Lk#C!Ig2.( E\SNkn߃1*Rj-{|b)þf&?|_@Y d q(/+~<$2|UGdhxԇĨ8,Б'xR~Ïo+? ?'><09I&SF:?MTBED7X#PךH4I=k4Śx,i \0>PhHy1)]3R$=Kjlj!-4_6J+Zw;a6b+RnDAѸў2Rg]1R*[=EOE&hZa1{j}4fZLOz6z77P=B/}}kkK1L0n&鳙ē#IE K'*1\QCdp>uTB|X1iyufawM[xBmʺ5w+*"䣠'3]hD4m\9b&͔yN|4a˱Ȕ gR=-0]kD(lٸ@w;Igv--niҦ2Ō>+| obIbW4ҖF:P)\ݺi2uOJhT& IrlX 3l ϗDv1Ӕ_*.dv$2Gݥw%ç*> z_2f4S2X۔NM,]Q7Xwp}(-^#4R&g)}`s;,Q';Vo-Z40eCjo!ԇwerSxH'D&;׻qv"X694H|Ǭ3yyi9e"FWvL7i0SRO4{k"a%TbWm79>&#W·y]xđTb\c];|qC(:AȲߒqрX24c"M%2zD?@Ycc]O fT BlN LUN FV[,X6۰E;/8.b\S[[sɝw 6J+8붓8z-|f_vk>mK, pgsz-z >N|H.9g77(D=am6aRytD[tar:u=fču 袔*:$nJ1,.:kؠfؠlD(k '¹;c24E8383J̼/br>V;]ߐ#/adlk԰MVB|O {jY1rN^\Ε8d11jG@u4sFQn}q/ǀ\Y XgxOr<+ 8*YNE):o o0t[AdPnK !aZv&緛syu t¡ܨ9 z1);@*.Re$1Q( (y*;Jk܃X4RdzW-KsGl+0rT#F׹~c ;p\x'h8>s\1x*^_Y=JW ,OL܊TDEYX;Y4]qn{GB>S=/a?)ڲP.O=<"A {p%L̖CcHdRR)$N>'̗ܾM 8SPМgX6aH  A,Ow292iz) #ӱTLQV>T~ԩRwUҰAf:DjRj2R3qlܡث᠚B<)/zVMjZ֫TZr+Γ=VlmxSضVpW6ka%˘>r -ACLIЬ*W<mWm! ilmo8Y&[m+5'*㹌~`yX/|Upfhj-m8ZTm ՁմK|N5}!zJl,ͷWs%ϖ2> ê|Qܨl+@Gu«ujWR 6J?Nw,:[*h+8hPK zt5WJ"6org/apache/xml/resolver/tools/ResolvingXMLReader.classTRA=6 +(WE"^0njw}Y ~ey&IQ񆐇>gNw``…$.b,#Hi+z%7K&.'1+4e⪉k]*Kjn[J@<HnIِ:fωfTz] 6o0;xjM ˓cy$u8oƢM'Aٖ,읊k*-ؑﻡZwYi! Y/Ϳ[r TAh=][w4g`8Q]텝F2'yI/'L0+ G0Lm \%h`Bp &[q-L[֌nc w1g➅y M,XXD9$pM9ϊ4dF+Qhz[A`h=5ӕUԢK?iittHToTnUhRudʋNJ?nͺEk,.ІZ =0 =Q\{{. m'5ĸБ,dr5kH|@@#'1KD#u1c؍YF0qb>akǙm0#qf9dFgHk5hߣ<ޤهQCcr<(cĞiN1Ś4uIMmD45<ޓ5]0hHGIt 2!<i'PK zt5gMETA-INF/INDEX.LISTJ,KI K-*ϳR03*J-)K-J,/JlԼ2~En:_fN XA1nԒdܒ9@VPWAI~~N1PK zt5 AMETA-INF/PK zt5щ+META-INF/MANIFEST.MFPK zt5A<org/PK zt5 A^org/apache/PK zt5Aorg/apache/env/PK zt5Aorg/apache/xml/PK zt5Aorg/apache/xml/resolver/PK zt5Aorg/apache/xml/resolver/apps/PK zt5ARorg/apache/xml/resolver/etc/PK zt5 Aorg/apache/xml/resolver/helpers/PK zt5 Aorg/apache/xml/resolver/readers/PK zt5Aorg/apache/xml/resolver/tools/PK zt5t ud&Dorg/apache/env/WhichFactory.propertiesPK zt5⥳T"yorg/apache/env/WhichJar.propertiesPK zt5$E._% org/apache/xml/resolver/Catalog.classPK zt5[jG *`9org/apache/xml/resolver/CatalogEntry.classPK zt5$Ϩ.?org/apache/xml/resolver/CatalogException.classPK zt5Գd,,Corg/apache/xml/resolver/CatalogManager.classPK zt5Q'&Vorg/apache/xml/resolver/Resolver.classPK zt5=L %}iorg/apache/xml/resolver/Version.classPK zt5ho .korg/apache/xml/resolver/apps/XParseError.classPK zt5;; +qorg/apache/xml/resolver/apps/resolver.classPK zt56f )org/apache/xml/resolver/apps/xparse.classPK zt5ܶ5A 9(org/apache/xml/resolver/apps/xread.classPK zt5Ȯ'org/apache/xml/resolver/etc/catalog.dtdPK zt5RהA'̘org/apache/xml/resolver/etc/catalog.rngPK zt5,T!'Мorg/apache/xml/resolver/etc/catalog.xsdPK zt5 Ml3D(iorg/apache/xml/resolver/etc/xcatalog.dtdPK zt5&@G7org/apache/xml/resolver/helpers/BootstrapResolver.classPK zt5q+org/apache/xml/resolver/helpers/Debug.classPK zt5jmt-org/apache/xml/resolver/helpers/FileURL.classPK zt57Nr0Ѱorg/apache/xml/resolver/helpers/Namespaces.classPK zt5ch.org/apache/xml/resolver/helpers/PublicId.classPK zt5-c}3Torg/apache/xml/resolver/readers/CatalogReader.classPK zt5kV!6org/apache/xml/resolver/readers/DOMCatalogParser.classPK zt5}э+6org/apache/xml/resolver/readers/DOMCatalogReader.classPK zt5]Ta>worg/apache/xml/resolver/readers/ExtendedXMLCatalogReader.classPK zt50}';org/apache/xml/resolver/readers/OASISXMLCatalogReader.classPK zt5T]6org/apache/xml/resolver/readers/SAXCatalogParser.classPK zt5H(6org/apache/xml/resolver/readers/SAXCatalogReader.classPK zt5p;3 6sorg/apache/xml/resolver/readers/SAXParserHandler.classPK zt5U  9org/apache/xml/resolver/readers/TR9401CatalogReader.classPK zt5y_F ;7qorg/apache/xml/resolver/readers/TextCatalogReader.classPK zt5FJ4org/apache/xml/resolver/readers/XCatalogReader.classPK zt5g50R w3q org/apache/xml/resolver/tools/CatalogResolver.classPK zt5RA"3org/apache/xml/resolver/tools/ResolvingParser.classPK zt5b| 6'org/apache/xml/resolver/tools/ResolvingXMLFilter.classPK zt5WJ"64org/apache/xml/resolver/tools/ResolvingXMLReader.classPK zt5gO7META-INF/INDEX.LISTPK11~7xmlgraphics-commons-2.6/lib/commons-io-1.3.1.jar0100644 0000000 0000000 00000243235 13777276623 020121 0ustar000000000 0000000 PK I6 META-INF/PK I65|META-INF/MANIFEST.MFMK1SZb{[TʐLȦޤ,^ygyrIbBMD*}GkޚuDH1ӷ\xTCUZ5dJg[Bq8 4gc) #eu@:g!>X4O)v^s> ZCť]?B qw}{ws-~]SW j.T;=rnk3' M#Z%;1Ie['dWtbtVTc_^>[i7X{!pKUAUB֌۝N>hxΔcX/cO+Mzw P  8s+lv[z!S@me#Ic$핐%I ZY/^Ao i ! RcWҴ$arxùxg,я71ɪG3/eFGqB_RWY*;w!#J N,`E+;U<׍+VN$ٹe \hЄvGI%/i;aA:d AFu`R+'3=6L\Z]^&Qy|x[<'$ְ[ )GZoUkM[p4IY3htqw3r!8#A^ ?Pv;Q|lpcl(?jkZ Q9|RoRyH\1=qtLH^cBRs g' NPn*-pc4 (KҘp#-1bZYdąn`x8[ dV9 X[BA[/eΰœⓋW#$Sc Wh7; $AP|#:Tp~*܊܅r8kiՃ&Wbi|66|y6yaX唃H!K4LouNՓ/ı0HVRT)h:Fj'2㤓 ND%"Ѩ'Ju"9S6/'\Q6 pHd6 ~J"KQMm7n;h#ZLjDe}5ie^f^˰H5腍l(uD>[_`FWPhd!R+K:"7@)AZV"r75wTXBJ v?V>f+kF/2DAfmprtTiǖȏx4`YC ʾo48U+lv8" ɭquNZMY[@(j_`)_DVOˎq-$obn.5?B c::e[VAn%L T"ƹd0)Y"(Ifb<2Aŗ5sgJ2%S/I 6}ԔAddITgu>Iy=@ ]'MTũezٔgTe Y V/s0#Pwa_fM[8"5P":LflȪ[w̤ս$ Gg~ UjlmDL;1 `D*虘80O[5Q*Ұ +s UƑF:ag|흹2b1]hSY<<ъӹJ$ΦyI۪IgD1&cةu|K͎ ^5@7:aRcK 88l]%;rmӚyEjf"Vׯ̀ ՗ vKR͍P_ad.1)X1D[(>C#S 7Ī|t{?3]B΁)wv#jL_5lqn N}:CC6ժFo; tr)~4jVQ+bӁړlȦ7_ ΔԟJ;jҶ]1 7yc`HKa>]Rušq?ˉs/q?[r=?,u07bu^ZX~_h~K'ф+U6&MDsRpM."{ `z\[z?]߽\|B~u^N~Y_so@6t@73NOB˝1<I䲝fjExPGʮT|ǠwՒ4c6Awa6Boy̗ZcsmhJЮ `ՙѹ-!Q ъ)Gkm&CW*QӹF:-l>ƌ6F]8WWXWϽG/no?ߠ iZz/o>%.(kiBB>F:Zr $;o)D_gh2!Nz..L@A.uԦ: @;vv7"zVp6/i?' (Nr@!c嶋hfqZݨ ݐM.r4F a|_PM<½kϤ!o9e/UBzG>HgO*.("#\Uo87+&%cu,cbI+1Oz),Xo@ch]:) $9 U;,.Ֆ]ts/; Ad(n#PV-{yV8 X'pY\8[YcvysA>KN!>c L9āh$DkI"_g6hd\s@U+org/apache/commons/io/DirectoryWalker.classVSW$d% Q(Z! DmhZ%$ ,,?C;:Kf:}QpC/m]6Kt{=~s?)hė>TcЇ 4,%è.ኄ;&LaL bN!%E >LbJ XN iFHfŠP9 *:zRѺo% rLוLf,;j9%CO'n$j:ڣjJ Rl8WgblpZaLƉҟW2Éq5x:FU-'72x:3M%SJ4MYܥfd.})ףx3hlaHEjR6p 'g&XWT-ڙ4 ʳD&ggk- RFunВFNm-GFDa/8bP*/1%T-\7DŕIe.&M$5%i0J)Meme6׶tN/T2rHMqUEkT[0J6Q9_d֭Tr~ 弪(&a&b8*dF$eMpXZB5|Z68^#ZVS`|$]48v ||;2nbыv ˸O𩌸3|.㜐%[(D;0>vVQlutV2+=1aVB= v[hö,`Dg8}^7I4l|45Ve}s-Ԭ]_ܰF S JGe=cZKCawd;C,ϣKص~9)ua`gPGӰefA N,#hCwqb%|8Oi%uPT7՞6OYp6҆ӆ ^xn3讲Ic^-6ʅJ!ƕ0RV'V_dp=ZāRqhf2"a}*h:je_w2*`[b"g6DSU-#υMX䕼$grvk).ݍ‹P(Ս(i#tNRq4: :0+>q7wKM`?D8 0J aw$hm_{2np]3OÛa9BrPaBA}$'4`!EdAd(X=,c@~aj{bC C sx;ہ8 .; F8Db@,QѪ2ک^ni L1;7%LY$ЀInl3S(yШ|PA,BBFp;W:]~]D>-_[,{kզ@T~qECJ$Z#d{Q4xql.5S7Ѩ~cu-t&B=30|76.`l:e^IQf1 B[G>)3"Dxq:$ n$gZBRI Q,?tI]1~Jҁā \8Fצѵa8{U]mc" NA1z8}Z=m\:nz t:a9PܕP~ %7y@n.tp)A ׬\.DhmJ'9w6|?1RaD!N9FNGBARA* #-ZqF9\`Z1 @Ɲ 5𻅅i.ƍi=aK+`Yy" jqF> OꮘӌEqt\'Y6dh*HW>o,m8s=us 2!#G3D$V.*ં^\SЧVpx=*nংT bH-="*@gﷄt?Is3TJyr5Gܻ/,WXcz 08Д uGgQ>wL */;uKh'" K:а'C$uNԌeނgZƵmnVv7ݛ'<-FM3D'TeFp o=) )>B =9%"@Ւo!@ko(-Qˑ~>H?+fE6+PFVДzTՓ4ICar no~m_% "7Y>Y?/~ F_M{If[YJEfF8ZG+Ei+ ShnAOPK I6@:$K/org/apache/commons/io/FileCleaner$Tracker.classS]OA=nt݂QPDQ~} }.vqۭ!_|ш$jQ3ݐ _vܹs| Ҩᦅ.09ኊ53MMw mR: ZyA.0I>{S@FmGHCvasy@-wgxO4Ի&7DEҧ>KH~5|TIr|ҫH+ȼP"fa gZ؏\RQmX8eb yD$ZUUOr}ґAvE **K˫7&qV~`Jߣ.+RrR((?9*(+ul^;:SM{.RW#Fu;51 ~s&pБ:R)hIpL0>#aݧ?')\YLjn PK I6YY 'org/apache/commons/io/FileCleaner.classVkSU~ۆeH lhSJA[ J)BK]CfSuo8/heF;cgQ,!` 89}ysoha x_ŭF4T`Tm;n5 !Li1**f41fʜЈ|e4X  m7T,*Pg\#"\m w2YUP5%5|}lxh$,N'\KvRLDN)y0tlȒ)ے&SpP),iDϢ.uhMA bE\7]3{ҌT ڴɠ=_ #TܵHCvrnR '.:K*+J0 Ǵ='ŚԳJDWsY/j;^tQDmJĤ%b@\VpBLA+'mXI;Q[|ݯhҰenHEdhźc@RFBUudЫedte+`Övu3'o߿%>PM?Ù]w9Fæ\jl"'8[R |Db_7з$]N C'hV3'J~" J^nqgj/Bc={4 Zs-|)~hE+7"h-)'F!d.m@9.à]7(v4/_PK I6c֋Forg/apache/commons/io/FileDeleteStrategy$ForceFileDeleteStrategy.classRJ@=ƦhUEEjq#iQ #ܸR\~x3JAp 39 ,a.4:1(lۘ $WU5B"_(M}" }%ȽZEs$SҞ"T Zљjwt-HDd 7}hHntXuE]xgt:FHHf0/K)Q,sS '6&?Tq'2.|B)AS6`vJ?;ꁐmAe % E>j;2hgk}^: 0miЍ^>-g$ w7 VBl AGacdvPK I6.5K.org/apache/commons/io/FileDeleteStrategy.classS[OQN˲ U` =-K] ?7A!D|GlZ)$dsfgonoр!mg9TW{|w\wuwz-%#Wt|<J, gypd ?F$pn7Lq4€E>"2 %v}Hރ(K Ռ$'@ HOꫠT0EwR\Qd`--&?bG 6Gh$rc?NxKZM*}̥D^K?N/~AGfR f2"o-| <$Ox>8ȅ:b!Cu\'x Okސ .h[5%@ 55≸ a*s鐙>J3!@HePIMlN3ɁI "Q_VRJvP8SILgs2!P֊)SUWu,S:U %|gl3[\q`^Pwe3;]פǐ^+‡ 2T U UW/_IK. ra`; 5i.3d1F2Ҹ3UMӣyY5~CnU}ϲ*E(qo_bX(VU ӚlUb-n)hr1+Xtl*X^Ŵ0Wh!Q̐r ːA*fH5D`$a=`H/SK*ØE24&)CҲZ048W1SYscy_ytH"3IVPաndM@L܉0≡DLv>zʌUH6eS\Uw 3V|K.R/!W/r %!Uxcfn=Eq7G[}@g7GS0Q K:\M0yJӪ s Y6\U8(vVEuL7QK7*)ݺZ)+ZI^d]%7O]Y*J']d%VmmYSmCW^ߝQ Ρ}{yu djΖ \ӹbiUvRnRfbl\3'J9ﶫB;suyKT㓢`}*D@Xk<&R \3x˲ڮjke:/'?ND!vNRd&o,&B0~(*Ő.:A"U:i 0vhUT , ϧ֡ (taDIC>SI;?X?]]5쳸%]1l 1bn= g~͇^lFϠ\p,sac÷~MƇg͔r3ʗ%w݁}Ә?(qӼQ޺<` {^"w|{K/`q lPpW=s Ͻ},/+ ,qa0A- C[m#lû ?!sߥi`c%伍~#H{879!TI 9tֵεڭž,7Pjoq߮Ϲ~i~ \$AYctWIGd!ek 6Vo󴑋x֪÷iGbGh󵴘C=H[ RGq=:ʪ|h;VYa *y;>#G,"VFhsq/<>>3܏an):GA7(7z`/ap #ޠ$ϣhr%eJ.Nv+Z`VE>ڣm1l6W6ʃ?ẍ́)=Zp 4 ̐U-k0O:Zk#n=f<'[5َ7?{||5ΧJ"_˭eU*DR*9qt6~7ްL ͘a9@x0b2u% cg0L'$1+mXC}v`b,^YO2jU _PK I6k/+I%org/apache/commons/io/FileUtils.classZ |g?盙2 y@ 噰 P›%lxh@ K24ѷֶVP@ B*X[[jZVk[իj9n6~|-ǃ|9ėf |o3?cL/×k,|ۃa>3̿z{S[ /_pn|_̻£Wy_~ď?O:?ϼos;/x/V…j -۲j Dop,!5K4(\ּmƦe[] a榝])周1Vϋ"J jC6ޮmFOkx[fpOI5#@>%naLiwug)듑h wXwor]w!Lerƣc)}vF^A6e{ڍdL7?# Z;cĒe&xo,_ItG{E.#+)e$KC:sԒEٌJ/s'zۍ |.'_7ģQQh➞^*F/`Jz@cx6H,f4E0ޙ;bLO=S[xr A^e.BrD*B7Ҷ4!.W0vڋLS|sNKӯIÒ3i%qۛa749;cO҈%L-ɹē75MGfۓ"׼<7rHO~G,']Og&˹Y%=d+^_f>s}JJFc)6e5D2d±pmtǙcAbIRJ *IsJqJ&6֖ǻ;  {M8F"I23}?+1F.=Kɋ4̡#`kRgHQ #ϔcF01[ ]$#?c lҊa2'yTf@\xoOLX$o$fa:FH:.7yۣF8xg2o 0gG$Xq~= \#2dTK=៍~==IIK{lF:BB42ӽf洕3xADHq ̏JPeal4&o^"T/c(c'} =JBs ;I49}+_≴TB6kJx&')uVsmG8Fvi0IVXvIvX‹++7yPnZܣ*XwR-/v[shHgRWHe@rҬpR^E%(rJjjD<ectTs;ddfJ^eoDY[#;o$հasYr"SK4gS~a-pvZ@:L;/ZV/)]GyC~#SmKzc]J^1/:¨*! ߶ޤ/}v|Q@4P]2*_{8'} INTBq1T;xO:FIB,s(bJeNJTq]] K-F;|֪vڃó⼓]X^tx ^x1җ#+oGl6cpU}UXa,CiT F֎8J?f[L$x-Rd]E-i,vL5"@BOuQ+ʳ͏ZÛ igmv.& Nc o!LlǪ.>(Ŏ/.ZYs3Xf :#fVt1LZ\9Q/J]b.Eyf.RQITelas\]SJVebnBziu Y1\JŅ3qp3jc!]2|X#Jl ٜJSsdqA k@ǡHѥQPyK:{]LU h*RL$ADX2i;}h!+9pe39D6 `$sպX#f\83bq]ckt*8Cl ԱNlNfzVl]\$tǹn6E|@73'IӴ`\X}r 6 &b,հ-:,j}MqA[ߌ!ZXmS|%%<ֺȚdjC[jp-*Fet t܄u `BBڇ'ȑ'QVʳfm;#8:P` > VKCfsδܓa9[\؁^+6rOqs\-ώҩzKVnrwq}K'5XxX1Q<]f)S {ItS:QB|%WFfY>p@UeH^~(O5x/v9ʘk qIGO>@I܇`@jX2S(KM0A#-:~J*W1`TWwX=91&}+U֍-qƥM׍LLB/d5Ytm5DCڼI x`"mw9KX:/aRShP}&u8utdXBW^B1@ ɑOB{ h+|A}ARZJO4~KG!D/( 6 K.ya%(]%xAbӼ@L < 3:jJy쇩}P Ǐ4X<~/R_߈{$0HOBy.$?3M?~42V!^ .Cp+{98_¯$kQރIRB-[&XKP-e,k+WO򐿦b?>p lNb8EZ pjmLLP&W&Sf paN?:)ZE+ށߚIr=G> rhaӪpWXY&ki%=<WBL!hPJnBAvu\~hW͇jRbX{ x?|QrGGa56 cp)~'~gs=ty%:0E(:#Ԍ.w4*n9 8T[+\[OPMaa?lN >T4{z6䪋Lo Nmmz)2b|bË0_ 2ŇWWa ]?q`qBJL!;$Xh1.CX,>2 y(,I*>+y9OI3cd?@դ ڎT [?wLF =rB! D&̡;)=JR+TPfW`.%XJ24P!\mv`(at-F8RfO-pn1.tbb!}5 ؚU"V((ܘgٕbm{pCv %K.YUT=U<HFq GiFrKAˠ@\b+Yr YH;8: G8Sp୦ȟc# vrT;rW4Bް9WLa~I3z.{fMScu[]ьO-lu?04)%%"bz9W@ Va½bW~)nB Ǣrhd*G[B2;t xm9`P|#>VqN׻xKNԻy}éǑ2՝ץ)=iT)" 7#9CnRSӄ~wlq7, q/}ExzA88'A642 `!a cIfBaA{ܔ f ;rĆZ\!$V(Ku§ o~ʳH|,px,{p# ܄.7刊eDdvty/2KmmV"9O..ptN+-tA!y Ŋ+hPR;|أJ!)E~p6RwqNl\`/) fi!6Fl=jVE*X&J3V|yq4me>#MzTTP?~r5p-1.}òG?,~gRGz4R0AyPC@0j-SX0RWG"EeXCɂeT^zcb/98Ū!>ijH[rgcwΎW]GR'7Dƫyj-'%Q<0V+YXfUjTYڤ) p営JmO"mRdc ؔ9A2̻@WwOacmF<\$w#%4ŸbiU0{ lQo&jN2DDz#5(,(,~ZPEQL']f*j*IQIs &paPԣGaT_rdɶȓ-y\)h5 |?' ڄG˥:),כ"^>h4 1ng"L鷹j/Y-//B2T5V?V 6[bY57Z?m|*MZFq-"6~w?se/;O*@tPQ+m7P 5 QdFNՐϳtpk0J+ ZbX FQmĴ HhaV Wj>F -D]wj+5d/Z1zyZ2nC(gRm]d~69ؼ6Z0K[󴅰Z[ mRnsi2a +ϲEnZ;a CWAe /!<^adEj-$j5d#d#F6Jm3hua6k[!mÌ+hz-"Y! gT?+J ̱䋨00}l~kZaoy3y*:Iݛ2`.;Aծ ]_դk1mj?gem~Oz Pv 0&0:@E`I&S>o l:n c}e FYB<;HClpTC*}F{HPQz (v7OA -+l8e}ܟ$<b)8Җ:˧ps|x9j:eU%~eMW)]eP%05 *5*As rrz0~l>IN1>9\ċPK I6!'nj&)org/apache/commons/io/FilenameUtils.classY |\e߬II'mJWIҴD蒒RmRHڢtLi$)mEѧQA6EDRQ `Q*|CE>gܹLҩk{w;ꩧZi a5 2|)s!B_V+^|͏+M^R[~|;bU)w??E?pJ?Qb)dՇ/.̘J/](BT)]ԛWOŖBXPu+[ښ[[n[uWIPؔO'z]y-WQ*N0icsEo\%mj[rM.u"[әnXU)Ց$Ξdmɾum]ĔN'6$:u"MzGg`T5uDd]{u.J$ӝ]Kȵm_:ٽ#YP@|7їHȴI`O;v [zgD]W皺t_g5KNG1X]u)Y-=9 :R-c#ps^>BMD޾νo/maJ/K$d'S=퉴<Y'lK'&tFc.As չ]j}hz3;pb3 $kW'{Ñ|TFy; )&uj$7(#=6Et* {ɞQء(0U(Xq9Hɗyog=(I[(bF#îwߌ"tEڕhg%U693^:GI8խ@ZhOk)Sib̔ͣX m%&|*D*w735 quO킓n_^nV7ӱEƇϕL;-A})1VM|SNΆwLG '9/4G< m~j3JOGJ.;-zcS.-ỹz׻etR0߅A4Y;rZ/Y_u[zli{x𹉫ssd3!k0- [hwu(c@/sNJ,3KyF%u 8m9Oιs`c@P/ |/n::rNv5yN[yN!^V<?,'ƏWQ֧Mrc g{D?^x3F^1r5<0(U8?sa.2hqȀ%yAci#(yCX  x]DTf>G/n͜F#!فcޭ8F`!]w+D$ \a{z/̊١1*!5 *|EBJB#PFccfk@P(HK>JG(>&,$ F|(MS)V|"IE0MJuRJn6HNS(H YxqPC=*sϤINr#(s9-R/W[d3mX_zAɅr g;er*`9igykF^@.WMN:lpj7nm(]7!dW ]\KvCO;O:b2 .[?7n\|f-f~dCl(.f:QXo"lE(?MO"LI7%Qb2h1Y>r3#|+mvTʇ@G-h2#Gt6Z/ۻ.vs(d6UvdL"BHDX崵rmןq]:sGQ2~,/wduLll)/q-S y l+ 9˲M]|<7[{hVlˢCQa05  /f tMF .=k`cjZM#I b*0N xhxAL>_񸊼-6R#J8בxyG Y:8;U$~ވWEƙ] ?A_<57"'יǿlq\X.*+߰EY6x xLJi/z /{O{JpS*2S ] ܩ^xUXw;5 o nĽxw-T~{+]/3潣ÛܣinhG:]VAŎIO% >O5 =5,ZGϳ3\\= gs2}N-ԕ˕:ϑzg-VUL@)WӔ#8%l7oʖuT[F6ͥNӬb9)ѸU1c9SIRg <($O=ݨ2F*7xA|0vsSin 9}gyýB4 QuɃ{i Ul燹G釣1q ae'1ss?S^1:|2tGUU/*F;V0+bƹι;ǫe2(dQni`U*V4Z9wgs֝Hf@*FƝL;_\R(w80fYQXKު59]#J3UD}1l>=*XUp 6v''*:M=kHE7Q[[Pj5Gኬwg&\?dĥ)n7%9ʳ⊲~P1s>[rxpv}gU=o|L~>8|z=123yeǖAiN/wuS8Do[_G%Lm̰^,Ym(tz^u(k;k- d~!*`c'}UnՌɨ_rUfטndx=瞋g >wts8v5yUCV@3: k Xɜ)Έǜŏ9#(6ČL9ƇƏs /56dm 6QWٴZ'/mW4ȧ; ZԀ|&`a }m(5101לfXN3'džK6\J>I=R ;S d`Fj|LHy<'YA< X=Ofg̠g:ɭ#&S0kjx-L3sjVҹ-VVq,:o?y8Pf^a_-,=KwT}=zAɈDc\"pn1w]%HO6Y_& cüFO/ۯ"(`a|b$5W303`:0;2](1ݘlRTQGIf]؃zI2l4[ͻnޏ}&57c܊!s;͝܅pNx܃/{?9_/9Sf@Dc2a`]2t(CƏ`/ALQY abj?jP:Vr8`2leDYq*;K>k#ggĿ |.5/2_fu\m%F[w|I)C%Q$4kgp%c@*_GR ᠆C:ZTfvY`c=ގg ci'cWN hC| b}AcG4ha|. Gr^H8\*Y;vFGb%w{3Nvꖪ.莄=cC`N6[]Iųh~i@h͜gRwQ?φ8#`Gre2\8˅]rD6p*Tmeճ`ta\S-=yŚ9K:mkb=*ʆ)&=NOU*E6ǯm%]gvE)-O n@̻@3hzؕ!Qukzҽb{țje ՀC?^qm Svr@-ZT[x㪹lRCe/]d^aRiGI y]U58/ N?5)0aBZ4 #°2kM3 f,&ΔmVu YWvp7X`'Jcwu"/R ">K ܄i!agzz)DS&F} -Lͫ&:&ܾf p޿̮Kk8z [jl`U<;'Bth L#>"IG#CCWE{\]o\v@:{"Jxj)LT@nLˍ)MnLr`JnJMnVʠFi]!Ci^Er7bG @o ЖdIhJ2L2d=K@ja1B* ߢ+ 6bjPK I6@N^ "org/apache/commons/io/IOCase.classU[SG̲ 7`@VLdaBD1 xvedvgfRe*C^yIRh"XJbs~E~@R93,:Xݧ9߹|g?>EC{1ŗqL#ǥ\1+b2.Ő_>#%v9NWcGƗyRbXc㸎%x6ΨOXv)-kE)Xe:ʨcÎKhR5\>73~NBl]3fyA=-A:+y]tg5"5G$M$$&k+ZR&ںY"F+ I,;+ԇS/_1Hɲd:=B"Lڋ&M S|MP w8f.s✢x9%"q6pu`->p+UpKܹ$$^{0('h]{&̘S{3};5Ƒ8`C@c8)Oi_7ȃѼ|bϸhJRVk[=Jk*75E'HBR\#͑@" h:ԧ} FG8YX"[stPnPqځV? ϼ S)i K8|u {ZDŽ OAЦioHk^*}P^~'l,><^P, խ>M':8 CX^BCA1MW C OKVD2/PK I6P[+#org/apache/commons/io/IOUtils.classZ xT>;d2#! 3 Q@$$4jɐ 31l+Vm?v [ v1(Xvnm*m׮=~ss;1<+s=;<>ޓOB" ^^^z/?{Բ19sYvK٢NP~L\׶)Է}Ӻu@ ^ eFjAJ͂Ԏ`DPA(t oEؗ@89<{9&cjCѡHx`82ص rD-Mhll @,1v<IvçFFƒѕGƓ p.,c!y@d$MW2MJsYŞ\T1DAn$K{l㊠ʩGz4ægʜ&4i׷ ZACDa5t@J酶i{^i# n1hd j:ãGGyRiO 8?E3SF, }E<[5P2<[9cϜ.{x}るEo r ^0-q͖Pt,F5vz8W\fy0o0o j [l~+qTp2&Xu͜%&;SI頗踷܏Mr32kSS0y68;YdGtyCsUgCgbՌw;{倦o6 ٜg)xut:Xd@{^nyCg\8ꥦdzLnʋjn@4 Qԁޏ+,6͂l 1ju E.ڦe,e23 '8]Wͭl$vf֠3D<';oƸvMS+:Ekw/M @ax>0dZERo3nwܼnIwcb|t .]Oy´#|چVڡQ -&G'IYh 3礏Eq@@_4PR܃@Qc\A-ee{G~'x>qX+EN[?'V+Y]÷m2f=nU'bGt:U2%[zNi? ⫗|2/L.&l:\2GnԿ"v ñvsPܫc?S}|⬇Ͳ(r/7kvhAJ˻D-k4w}z#$zolpx[۠4 j(S}AcokY_ EFš\8g4: DJz \ԇM͸Gc\I~c:_o8Wчi1cb\0n1-zKtt;E0h; 7)* l/&(&H ֶgS.)`1LjJ0Yp0 QvigP 1HHЈ  z߀c6 YA<)̟I 8݄5/*$O1)gK(y7BOab2^"gwt3߂;[tKb3Lʛ 8}ބR,c$sBKҏ{D_F(-Tn fG~ b7œbV1ء)3j@9GƦQ>/4*FEV"4n`hʮkT0mШ=M#ƪ6Ed^n`%v k/}ܮ^)`fYQe [2,ޝt nzʔz6[dnd]=tYﱫ7EKS*)ճL<͙~ k23%s~1ҧXaggcTiQALa\HX N+7IU 6;pדxr8ˀއwL>_K0lqy\9]Mi8Z1?WS*?3%@SDvY?#=Ie^sCTLׅ=AM'hhg.iʛy/Ƞzs%\it}I׋.\ cMiƛҌA?r]I.rQ]& .NЗ%#C~7ZrKnFK.qw"sf$d \?bhB{u&T䊘xTIlhgx@Z e,┌p^K&R1\/q|6dx-J| C7 iI:NỈLb] bg1JAi;\R@RH>8KN9`8uPR ) @J#*~Tӎ~Hrk^jWPi*B]C $ /DD*RbFJR`NdU28a;Zt1k kt:=&]&~h!0^8#4?A᥺P+UJ(-uh A\xyhH~AncIyǩ\jir]|.\r2 zk3_]c©n'P->?O6霎JN?}~sK.nTuJi4nPl֥o X~r$)C`0)X2 U)_zZʣFyۨخ3l$[}Dk3ѥox-IGe,[c9K_*d WQ< ~O#g xQ|h V*/jj5xq6b('%a>W-ۇVܻQZNYÑx3g~I-͠ߢ$1ǡ7rڕ * 4)u{..q_8W({eí\UPQUFmo7|[@u1ٰ^*A-3mnh"KR+)GuIBÃBY sӶ=#eHjRp?ȪcNwZWRեS/!FpARL:X9ue"TeC)?u5?4P#_c>E!2Yc#F~<<8-̏Ij$8qآҝȑȑDǤRIAqYz M]*Or'\y.4PŲ#W WPEՃ>jʗ:{U&Jϗҩd$u>|b]BBx^jJQZ]]TCڜzlk?yoTi$FrYxիgZJ۴D}/[~:BM/MHCmѿ`PyV/3}iss4<_y< -%x < Ϸm|ssE̦~ɏG(]k A7=AK-yFa\Gn \oK5pH]ENl|PK I6k$(org/apache/commons/io/LineIterator.classT]SU~ dY> *vE!MJ ,_n7Yfi7hoRnhG!̈OQIRʌN&<>{Ͽ!i\8.)ۓ *"\r5 + fU]];0`!Ers ދ}5ຂ]ʊy(qH[Nc'j(ŬU6u?(<*#b }uM@o, /;E"uKj)oFa/%`3Y㮦 I%]pJ%\$㙮9k 9yL+śʚQ5y9m?pk\5.ê,HїxR M͂'u=jvkTL沟_ɹCSU-ӳ?8?HXdsʒ:i<-iixcÐPgƶUþVKdG`.^Vu\G~Z:f ː8eiriFm!R[&piڙߑ`>aC# .Jӛo_ M j }#l-\ y=$ S!kFĿeZ7oP02|߂16xa,&.H!;NֿPK I6*b9org/apache/commons/io/filefilter/AbstractFileFilter.classR]OA=vnKVn}0^UluŝHfbAWO\%Zz,c5$lƙET$2J Kʢ/yh]n-Dl3>r,`-P~BXU_h;R5R1p*ٙN0X9[ AXD+,$wP?AD&lƭB{W%=i> -SOٚgȾcuC`l3 vFU"Ĺ^Dzk601c3Ym+p &DB'"vEw7\̗xk%Jo.Ptz9^ N3+PK I6+4org/apache/commons/io/filefilter/AgeFileFilter.classSNA=.],_JilEQQѠ6@nӲV|}}Dwf7c{{9L Ce(+)QtpUD:f`5 51$f ,. UK<սOm/qjVSReNu d/5;Ô-CUzY6Щ .ERtJNR X&bmZ&X@+t>BI >)5-p3PH-J$ʑNkygp6<bt+T^Wm2Hȩ2NXd#sXf̾n2HcdFx2'Dȯ[sߐ\[3>ejS;b{Ɩnq^%r!f(/PK I6hkXa 4org/apache/commons/io/filefilter/AndFileFilter.classU]SU~6 ,$ $BkR J ~MXvNiigqt:3*bg+;pߡ>v|8 EΞ}=o_ Qtᜊ(B8׌N1p1FGx) \bWlJ bx+1pU91U1b^55dL%ǨTl1KٜYu+h3-ӹ XRW 92jQY%t^Z+ňnTή=nd vl[լigNXӾI"H3C V=d; `ʅʹ-EÙ#97aml7 ٪B(hrC #A;wnJ3\[Wt-kt]p*Ut,,m.Z N%5$5EV]D?t 3QKblXԆӶ. r$,I䍄U+ ⤊ bI-ְV4 !aHQ0tS N0Qj+K{y$˼+O޲قvIVF~լj.t>!#C6MW x~ػ* u|vu:'Hl] !Q9gr|eC("|ǵz9F#hi18x H/ MJ+Gq$ڗGi䞄LC'<ҏ)QHߡf!~ HHDs*á~*ǫd`d'5uqCH KBzz V/*n#7\?ckxMb+HbC6$B[Q OKqOQSdZ@LdOy9M|eq2gǃ>QB6 BCk(DOf ~C Or]A;*|ay,`Ie)W6FST͜CXAzj-*v?mwHO$MG®נ'=?!٧$>/HK)K 8KnKH3EJp PK I6Ar; 8org/apache/commons/io/filefilter/CanReadFileFilter.classSn@=\!ZuZCRP+(qjjؕUD$>B8VK33;gxw_H`oT\ÊxJ,-<I^Pֆd,*!R-I;ݍ %,|*#rqٺ+&G!"9@jt!2#dٹ:E$;"f$P}-0R/PK I6B-c9org/apache/commons/io/filefilter/CanWriteFileFilter.classRaKA}kzF&FڪTAHpD!_f{$'_ 4G3$Chngfwޛ7; |E@YXбh^6AGK4,`E'DXu`ٞa+.%fk-׳݆C*e0 ]>h{ \-y m9f+֠ ިrߕq na{on IѸU0/ ?#nfH0 J6k_(NٿKlJq$u|65j;͑в Ʊn”Uvs1Q NP]ѷ?N?_2=1ddWeDDUOYF6SIZ @R`<2LJ`̍}ym@S[gz !Xz38}I]DN;> օvzXwdNX Y>νPK I6qނ<org/apache/commons/io/filefilter/ConditionalFileFilter.class͊0jѝO.40ٸBp.ч<%ds ݛMbbD(ZTEAUČ_xx,TYINt&։'b맒0 7ήZ,^ƅM|F;ZBzjN]#yZgUvf#My1n TqcB m.:Voj'PK I6 C`9org/apache/commons/io/filefilter/DelegateFileFilter.class[oQRIzZ/1il&ėb큮Yve1~hH5ѷ3[R19of9?~~ *C7܌V @1[52*ıgUR-Ӓޑ5+0_5j#'Ukݩ&aڦH`0)PqW ٓigNS iN&!o /5t9[ےlͩ5yp^ҜOD7 y dF%+3Z5z"pdev[\n=!n78=sKXa#Bkm:scSb}zzyM{H!-8O^@FpY:Elv=W7?9= ̞D" 7 p#EiV|~G />BJ'?34"LJeD;fag~ Z1ODz@J7&2>nm@jU3#cبGpXR:<%('` jDy2pW gBf 2G,A>#}3xeG PK I6c-Ă:org/apache/commons/io/filefilter/DirectoryFileFilter.classQJ@=tZ//.hJAZ MǨ#m#i'_Q❴n >nsιg2oO/0EQLL`2)g8if%w|e`\B;t ٲkßxvqbae/"9T6XZBy!T)_5jW:OKÐZvHn~)K\*]kI]>fqM'$~w='ٱzaE1ga C܂8!N{B_|^\cvg=Hm\BB qL+v@Hp49YϕaI lqzn?"G;.YW|0@#B!|H;ا%l[lPK I6f6org/apache/commons/io/filefilter/EmptyFileFilter.classSMo@};qB-_m)V(RcEN.R\JDRQY׊rz{ff:XאÒes[; jHcI%sO} Y<AInjwLvM{d;}t&s|ڡ`' j~3|ȣ R0O.CC7Ay)Zc{;"Nr! hTqQpd}?ق u , ;Գȓbٝ%hJt(ࢂUTtU56CL^ӏY<ґԍԭ^3gЧg\'*iØM,ݨ_%V1(@Ey 1H |<; Ey ApV sB*"H˫?yrRW(7wI8Q)x )4pXmDM|-~P)nLZh`C(Gv@C=vW,1FթeoƵPK I6P6org/apache/commons/io/filefilter/FalseFileFilter.classR]KA=٘6k[MEQP"RKmNfW6!Ђ??l$,;޹9wg} k:Q- jYc)/ ƎqN~ <{d(ME5 J:3L4[.-t\^9`vc0H]nH;~'RM+= 4x8<<YPZOWP_9"aEe(>0TfYȣI4< iD?N|Cϯ \ڸC@ԽvT4X%z yJ t4ZGlV`W(Ҫ"&)r&LDH FUa^ޱm]3gSEeCi 4_YƬP̠?ݍOJ`auܕċZJchvPK I65o5org/apache/commons/io/filefilter/FileFileFilter.classQ]KP~Nsijih#) "AuQyw\+dn$H(Ǖt<9F'WE^ 26dl3H~͠7:fؽw5֞Ig:ZNMo њշ p$+dHV߼ڦs]dt&w,CX.rsΗ9ErjEɐ\qrVs QBNkX29 Pp fU@,e36ĩ> +8o:2s@oi2xDרr7pFYPq%3Z,ݷ޹r`\Dl֕+M*  1M gRڅoj#\VIzd^dw'+ 4S'Lat`#Fڌ5h]DM%.IBF`Č7Te!ZWB‰:`L*}#jpXόgY8.o @6Pɨt\ ִecd|ZJRոhF}U5ji|[6߱~54mᓱCkQqe `PE}жX~hϜ,d#i L LOLÖWcx$0$ߏC4*ݣI-Z\Y_@?HM78颥ɷ% ŷ6OTzPY}z{xҗK |ؑ\Ro'_w^CG0;zK:-&H<ĥWWP~=}` 8hm76~^=Kz|ᦪ>2T,@;]h.zI ޶֏؅4[3uڄp)pGlEᆩ\טV_g3Spűfc9c0=v01ga t3PK I6 xM2U7org/apache/commons/io/filefilter/HiddenFileFilter.classRkKA=fE.%AzCoՄnXPGEwV 담s93ϯ4LcFŬF s*5(dA"ɞ qo ~ϭ[۰jթ עbٮ8OB6=6Hd_ԄwH$ l3f%۽ ULwŠw+ 3\k<(ܲ{a0aG."ee^a[a-<#)Iч%XaMzR]9daU.ԣRsg;M3xdqz8=],&-R ( t)2&X' ШQzA-0Lam]ZEӏ2>yhl ď%wM_zR|F V*G}6Y!mPK I6VÌٷ3org/apache/commons/io/filefilter/IOFileFilter.class]@Cu\8>D"qps[Umݦ9x%vhd2DCe1 R%a4$*xl*Nr'Lw ]Y:`g.Tk[X/Up @hXk-@UmPK I6(5org/apache/commons/io/filefilter/NameFileFilter.classoTƟuf_mXGJ6aBR-[* W{8N\H\1,Hf7 j w;;8&M2w9é8qZ(~I10WUl2)y=t.59(H:f\9]Zk}7M5oV%_rêL Ԛ^ҭ%ph;z]fWUv8˥=eX;-p4Ȳ@d^)]4,}^-ΒZ6-ښj.!`]7hi S՝Ay;IDI3O&'U=_wQw 3_4j=$# V5M 7Ȼ,' pcO6U%h^ ~rGE]i՜q*nsJm . sUST^sSzʪT:uI( .%P <% Cʩn쵔ꁢړKMv .'pbAboFI wL: g Js RayG8< מȶbyC؎1DkkP ޫ֟ zzhS6~]5*g^sfû xUFsb'oqq/P!Jod]F~GJ8WTcۈEl71fEڼ^\f+=zøA$\ss2-މ&+@Ŷ(&gz}ME*\+3U)n⚉ A(Ew1(J$.EqwPDāpۙ:d0$B/^Ez!ej!OC[g7KıdXrz/+ zF0?YaX[D!}w_AGUIzj jK-Xa7Hk5v adzl(8v_qJ禅*fM8h(dؚI2Kw\vqCߜj/h/+oauz7rэSU]ǪVp rOPK I6C>e 3org/apache/commons/io/filefilter/OrFileFilter.classUmSU~ndCH)JS_B^@ņ_:K v6~kuS_AgTΨzfCp<=ܓ?WQFpV1pp˘B hb0e,>\cx7A,{|vMFIƲ2Cڢn8b*QbэbIo9";s `4njvsSWMv%k)9[:K(wVZͦeUu]؋b=ٯÁ*#s=z&]޾4ÀZuKQt+hhb0[Dolimk|Z"ju7"ׅ%Q+V<](8n6\"Smj9%mWIe&1FՑ2ogVd*k nbE-P!>b()7 ((̳0sf˱ժ:sׂet:Er#Q3EM^>B%q fӪuѐ\to[9/!{0%E#NA%VYPKԼG@נC4b.Pv,]= a i>x'^d){*.Q8K/!Mř_ ҔG$ryA 9=]aYCSR7B.JʠHkRcEu}<k|P/G[ZALI1ERӸHt)CܝG7>XU` >i4rU"u9I\R%E+H")~:* )WJk` -u"}t ;Cw;@+_zYݻ_wm=@?t+ʖQӯT$ ]C{7X &Nڻe>%aJ>_PK I6DD55org/apache/commons/io/filefilter/SizeFileFilter.classRnP=qĸ Miiy$qI-PUZhIUn1rb;;؀سaD(܋UR6Y93rhc@K X:, ,WqMGCGAKWuL 1A ;~mۈRux4{˃]2@- Í^{?P8n4Ea> EJ; a{쓅MIӿ0ɈGU Ud*ҴVMC٦v70|)𣐡3uyhQ:dMib:VM\G0g Ic]Bv,K?Hܜ<7UW0LC v }r%;G}hmi`UaAƔU|3_+w:BޮA#H5= M"x%l+Ѻ:2Qm.q!]Q?!O{hoPU@!G`_>xoBq"۠IL%kPK I6x$T7org/apache/commons/io/filefilter/SuffixFileFilter.class[S@RJ_DE ^@.8`@4lK4aW> /( :oI4&9=~~ b6$ăHCR@ 1Pr-cX #BōpS- y'xe#*Yyɶ4#;P==;;_a̚!|ɥu4LUWK^0`oiMVVVvu˪˙F^L9.[klsn@x)* x[唖h +wl&/ ur.1ԗPPrg] =R+X"ВXRN:$rhCOXY' 0C6'sv0HG GׅN {Ghbe)#f&4Qa uڨ0L1) aŽ0fpa=ߜt޶.DLkܝFI9#fmc4^tW:AnlW5{/:ҧѧK *zJo*~%q5|B՚?oim4S0V4S'.cbΕtEtHEQ>|%>\_PK I60]EL5org/apache/commons/io/filefilter/TrueFileFilter.classR]K@=Ĭnm}QAS)E)- 6u$Hb}Qg&"!s{s3.cT2ls x_> D,EDG*~?KO#E:Q| G;[Ll.0jw>6oT܅]JnfJ`S*nfdWM8ҧ7jĂ/Xi՞ԯ]½ έu#^ Dw[?PK I6J+S ? 9org/apache/commons/io/filefilter/WildcardFileFilter.classUSU=7 lJ-5R$ ,JRh VGg67fS8>cX}zf Yu2{;w߿CO8p2nRp: Q0cŘ˞b\EL&$xSqLE/)cK,U^ϯԜZ\u 4&OS+zA*k\35y)UU[s].V%gعI.e3I{I'tްj; jd3ok:|w ;}0u^bBdݔ( `RB2P-TЋ|U0syzۃ[ޮj 7XK#y)`eCh۰Έl@`WMZ2"7&Ѓ>9,зc4jN8jYܩw%sözf3SjMY*)j0+]QTp!<IzZ4IiɢT0K ^IXx(V\G]05WYYb 6V>+=!#i|qEhӀ]Ҕ.\<5U]mY`*(>a Ƥy q~+Y}{Bڊ|:Onwe(+6 hyr-Q<xmF6Gǯ_loh0}~@t;mŕu]x䯅/Y׊k?]pcp I\F %&_$Z Y c S^6]HeVHZ%fx)"eHcR=&H=R>X} ]7I-?@@[<}'c7L<[#`w1#Et{N GhKlkbBY~om%d:M">fe>NcP_0TCb (D͞'()E"sm5g-a"Qdա _w0h&u-Ghir(c1PK I6?!>org/apache/commons/io/input/ClassLoaderObjectInputStream.classSn@=cHH&Cex^U~ U! uwG 5)92sg GWtI, y]:?CB2}lZO@Kja$rB6 6qO|WlК.x: .`ACѠ Px.c`N1Fu`cB*EPK I6E5org/apache/commons/io/input/CountingInputStream.classToU^6-n&86j;Nڤ!uhiR6^wͺJĉ[PHPHKT;i!|xov}3_Xё%Y.b3brE9ף8㸪 ,,.:tܐ8⸩mWPK Y۱9|}YҢj˾g͙ªnX '*cj7-o\oГUjz|Nͯ[ +W+-ZJUt- lO0`; #u {e:6E~mj|\qT ^\ɵa!_*HxR /tvN5P`L "~u[3zDV3óFpZ,S9/DЕJW=ۯ7-߮U98'4YM8]l0[-Y{+naz5Vv]œ[m:Y wo+"'0Ow$}uO@Q/~N/%ٿvՅ%ȕ7 ar&ߠpnH|q#wa$')$WPK I6t(Vx2org/apache/commons/io/input/DemuxInputStream.classR]OA=R ~jb4B|S!l“n'vn 74QH41>g s{ιgo?*0 ӘM-UVgB)@nw*j^2pC֒M+c6\  $ +U_ɭ^&]#vFM=l$ZAò;Ӕ۾׵\rN/v`S;25׫+r VHFsVjztZ~x~NRV &ޤc c5v^;wz5dbL7a₉țXe22&p9C]GAsTFvm_::x0zE><c|fI'|qx Qm?sO4Iԑg~f0a0c!^M ʟN)D9.oT6LR%fsͨ(EE>"Eԉ,Hb$1V:U~1ۘfzH3NCKB"kBoM̿4b3*;'[GHqbXt7PK I68@nr 1org/apache/commons/io/input/NullInputStream.classV[sSUvIS-f!FA-7 -R.isH ''Fq^<|<8V-|6tttԵNNCZg43ٗ^k}N>Ӈ"x "؄OL/q37ܼ}ugXgB88s%&"{Nsrf2 q:_&t:rA\0 5U@ rF^4C'b^jӚ%U Lr2P!3LKM vkf%O-;`)̪>MW yBϒ%gL(S1)rk3ɤS&1=mf$5=Wl6ţ!ҜޑV5ZJ`-.H!kXhb$ZK m Y#_H HMUbБhb>h"c*怑U/UIkJ jVTu_+EV6GתiL>,w+ hqZ*W<܉)ʄ0GW3wk@,:9[+5ŹNт7\KN8>Z㨇)&gj9<}囔[m?}LƋ48Q'cM7PSVo6i]t 8_e#J JE*pP +mշ8pljq\ۤd(L<+B<1Ul"ݨۖit;i!# m޶X[sa? ԎGl-7\N_i.Z&4hkc]hKK+kѭ(F hG11RTi=ꥑ||)Ur݇?<@LB8"kX8Dy:MTW7؈?ߟY!pQx\0WQ;>"LР*J޸g0%w*6^ڵTJ+AQ-]ERCh!шl-ُ`d$.(>\ӭ5x+-.:<_pN9ܿ7Ń\/(%$J% GCp<_B"ZIyIگ_@TDq%\_QVϞPK I6}` ,org/apache/commons/io/input/NullReader.classVoU}vK.vKc*E-m-0ݝlw]$&>@4ბ5h449wK[swνB)`':aM0943LfL!LEPi?Lg#4:<l lx:&s!dC0 r(b>6Đ@`F0Y:Y–sƼQfM ܀ eZ6( UF("Ogh7n#Y:H6SZfwbְæ5 Z*'S4R19R)?x)T3Oux &dTδu)dZ* ~E=䗄,J+f^,YagtBJ6/,36oEvqis 5ȄYRzySWAvY09E;ڢxI'(:n|xd]jc{]GqNqʉu1**UdU/KU^cUQ$& @2j&c%UVF6Te?^.F^VVYQW9(;ډ]8 G*8ZC8au{8rӭm\B]Ζv&o $I"M@y-nͪ{֠iqxd\iXvYD:pH~TC;s\Z\;ڲ_I9FѷF_%n!×Wt!Է011dA=݂f{,< K>p8=w̝OwUlШνZ%lm]6V.)\70B"g Ufy00f7z~݌?_Zg.cЩcnaWor [:޷ҿgC+Ι} -‡".DR+8&"Q"1ec6ywP{H[)hv:]5bKǯܣ/WMH3$ y?a>~ o#t5PhT ؇A_p|UJۓPK I6|I2org/apache/commons/io/input/ProxyInputStream.classkOQvi M`/@/\ &FH$ʧȑvwOqfvC%윙ϼ3?a[)c1If)x!e6-DVf5􃉩(9 9gfya /SLd6Gxe)3,/XY ,XH,8 '`0Wd}J[z+}w5w_ W|ӪIګQeVmâ8M|?,ϲdvudZAiw%D)r@jȖ^2]f5J2c@@lAo:* 4HAj5)U[!RLs$p/m<IԖmdlod&V0l`5\gɲ;&cDyM:T1)0}:Z<-7:8$}'`%O =f([B Q(FQ W,' %TNiY*z kCҡ%T}F̓9!}uTlHZ ]%TlCΘJvL%1Q-VБ6QNu8nEӘHZN_'?Fkd Ž=׈_tC\7'zxO吶zm$ l^Ef*&.4›i_:ھJjÿPK I6 m@ 8org/apache/commons/io/input/SwappedDataInputStream.classsUǿ'fB/ZrRJ@H/J^nmٍO>93 o3N 稿,uC9}?}0⾄A| !1 C 7#w[IJ +\*b-%'|ŧE|!b!rE34ka(xG43W0jMk٪Ju* ̚%wQ3ԛZ_Qu ,EE_S;Bh E^)5XQsEZ5k[jjiNm =9C"8K3N7Efit!jZ0f+J̙̒Ma1ĸ(eKmISwɭ挝y$HBK#NC%CVebWʮQ&tPEiu]qh* _Wrb'T[<2Yp<\dKVV6T'^l߽ƒlj\J& il֋j^ 9! xDl(")$C%Ӹ*bGF] ][:eTA):2xrYji6 ']a0{9f*ɦQGC8JK 7lod32U7Po1q'`p[JJH3f#Gp<حy)ƪ aq930紜O';4ait<4 jYw'D꿓9NkD:ALD'm!o>=|p 8NA04|vd`*zJ4[ZzIbPp8"3{=(<eFI'4I4^Ƨ!^obރ{N#XO"42i 4'> +b^u+,9k22pzbSϘ[՚'ȏ>Z$U5{l4!&{2DOBCl2JD! >/B"ROҋStEFl-%JX^ҨP:M57ls=ppx/|<4)v9~ w]Yg+ZY?vet?YhWƻ+=zG;3DqEvh޶ PK I6mr$~`8org/apache/commons/io/output/ByteArrayOutputStream.classVmP\g~.{w\H!YR%SE1Y[0IҨpٽ.݄5j1m1Xg@c2$3mY?g:>ewtFy眻GK6 |"VL l') LٖaZ|8"*ʛlfe!%>\d ܜWcǜ>!g' < O `3>%C6PqO13YJ Y9It :Y. u\&c'>%3s 릝DŽGrWjRI:nO۶1 TA'iNٙQk*TJYGC=гLbGXjv6v8TM܎ݛX'~,ɬs*gsN>mǗIx^Gr6 (KMOsLIسNhrSCO[W!1 %RY* 0&yڔ2є|fŸh_[9a7UJQGkmy +9ӑ?έm<]Sc'cw\xvjFRLHL)C%*aa[ѦaKY:c%z33Y5![r7 9f7wht5 NY0&n|Dvp6DLDo]V۱p/"7%<2~ shlgl+pxD7zL[Y}7Q GO`H4k]>=TƵX*Nw|V:m'O' B62VCF H)W*:jǤՔ[Zs; Hzx|m\Y&^@KYc5q-E捜׊-lB*j&^oShR6]gV"KJ}ڇN̼ޏE΂+ETD32g*|Wa_W@hU 0Q}=ZDM^#cɫ0c6he>o`_VQOU>D&_ M/mT VYU_{8Zyuo! yai2\F""elǰHPwCylQOQ!V 6V\QTsuE3Rt=\F0Ç1xB$agzTޜiܥB^J(A^8P}6]DmiR֕AU7\oRKoL&ަO*1;>n`e?}Œ'j}_5.A<*97T^D?;9@цe[ ,$YbF?Α_!J D";,qoS Ġy|enzưBKKCD5BCÕArL T,bV0=uBF}Rp薳pQX&jl AY;qt2}R{T-*x%mBb 6>^, b_Gqڣ({͟>(1z+Ra)FUC2zUOek-ܼAzvKݞyGZHztOлp˼\hMŞͷV# ~ZWlٿ&Æ[F'o~+S91(n2CdNAT,+ǎ_voFpĵ+t5~O'ϓjA]6xB9NXn8kA,Wj~O{@%'grM4/oQ?[dٛ0)^2[AmUNЩU.?Yy# h^D˪ρVQHCU/h*XjUxj Aa}{}9g?@ױf` OE)█mGGGI%qǀS  )ܕd`eXRܶ+۱y|創om[m՜T-Zab;zݬjoê6hIWܚش<[1{ U\^ZVmWkn:{Ev'?^>#ury#\o"x1qj]/\„+!K,1e"$4A4>B7G iD|DSԢ !u%,p86yپ Q_y=aO7&_ "`XȎ ϸ[alup.m|!*_~6m<4?PK I6ח/&{;org/apache/commons/io/output/DeferredFileOutputStream.classU[oU&;mҸҖ@ M҂&M^@[g,z DT-E)H!RKƱt.{f9??~ pxeW a7Ah2-(% f/^>"qhD{=(?J .ϽЂqϠSB]7M|^ILW'}I$ʜDO[PŞ$W{%iU`x }z]ͺ~o8|hUJKhMB|v5Dg#44_KYr;NH_H_.F'?H?/M361 41xoPK I64org/apache/commons/io/output/DemuxOutputStream.classR]OA=*E-,~ Fj@ `۵]vIw!5QH41>gvP>̝;ws`K*RI BLfU<]Q9ieLO`![[XF.o izݰ:gTFceݶ@SvzmUΆ6cװIPv:u1̆N]vtt=}juw+FZjkI`>Tʔ?͞f@n3R',-یkvE~%WWLDB-WxJu15[ʑ2Mٳ5\u wpWE=J*p\&RݶLoYў׸Lq<=\ DD 1ô|L",&1“`c>vB̒{hacpyP`AE.pEƠ=>E.)*ܕEY Ga ,1>rŧi!M ɐ2OQ\Sg Y#SҔHi88!P/(a8qM"">T-fO1*r|-rKCQ{U˩._ PK I6=Z 5org/apache/commons/io/output/LockableFileWriter.classWytT$兄 p m"@BB@Kd2/μ1AKkKVJ7` ԴkZW۪]m{ӞdHs߷w}>bƯT Qq7Q| xSs&⃲!!Vq>"}xĽ~|L 9I>9Ni~FV>[J 煜d!?#Bǣ3)a{L~l\˰ū\Y:ܘ[Ɛ$` UC*6T::nDEԁvK6[QUWl'L1UP] eVO,N)XY8 TV!k6f*6H1SD:*ZÇohxw*^ RYnfڬ;LἆM )jY k$䰆1[^> w,(@uLУA# FBXfy2ONf54e[ɓRzBE^oEhcA [UCX 5, ^nb`ܴF<t -9aeS*hٌcVvL,p:YK~4܁;5Tfpm 2K %5 YU1َڑ]T ïs!Kh!&~B\mB,!BF5E[Ͼ|&b:L8^`q.u@vdxBly6NSe!-'ӮpB[˲nˈQ5EGQˌdfKSQ6EƥL$a=amEZG9^h8!e:+lXNV]]a :}ܹ ZT閾3ξ* _Au}رf7Rn;E@ji_vXηܵJ 㬈=ir[98ET=cc Uۆn>.Ǐl7:06nknm!ڸA/WFM %q%Z 5]Fi[0 Q5:AA Zq}'+FpVC;Jܣs8Y\ ᱭ/mlRMj pOJ3"J3"J3n*-覃N +v5OadSX!ȵ&G2^(kER"TL`?|}ijJL`a[KM S!sc'Evx&Q՗F5.GM`18Q{uFեfm`'CTa*(b !<_WOJO>7e;iX.qM m\tg9L+fͮX<42ltfV@F0Țn[La,Dv2r3IeDpo9m N4c;(Lڔry(W*}d6"*حO.[sRRMpN狲0\%8[.^,k镶\ TeyV/@2JQ"{t;G9:c}cv=%ƞӎsiGvq4]8/T'ɕY6OrDfqIK㙲O{_{˳\X;ȼPK I6Mэ`3org/apache/commons/io/output/NullOutputStream.classQMO@} -U@E@L$؋404!pp"k.)-*Qv2h;#y+9 .6sJ*Xl jz'  4D'"+㦀JVX. 4=ڙ(}^?qz}>N3dFYŮrrM[h-#/o4[{ .42D왢A=OUe9\'UXHYe:e\J)Q&#SY/Sf}Gn}| )6iB5+^KEJa SMk'>Mtt.h6RS {\rZ/ a-c:jmGS&A+PpCwp.% M#4ޒeB x)eLW}"4&%xyh}JG褏6>$;rS|Ă^WS|Ž kS}(AAOoWc&ث d/uPmLŃ#_AͿPK I6{N2org/apache/commons/io/output/TeeOutputStream.classR]oQ=wRD+`[k+,Z`>TCJMiYY,Y?D!2\ؕj|sf93s_AE ;1đM 1ĨĮ̃dd20hx\÷vK U{gL3냠7N߱:v`_N͟ D^xoŚuY6E5϶? F({C)  +IF+R!5*đF#dKՉBb Ɏsamk;RWMUFkHRc릇V}Nl{ζ~e6lOw#̳0K;I~}?uk&˜US]XOH~PK I6~,9|;org/apache/commons/io/output/ThresholdingOutputStream.classTMoU=۵;Iݤ nnZL􃒐 Wn*(ę'|ZT 6l@(Rb.ԟP'U}LlX{9޹zO=Fx+Cx;Y.IĮuUwe&xO)0-I`V!WNUTQ!m}Nt滲,;reW|qb۴(*ugU[rRW v?~m*\,yՂf+Nj^YpZ~a~ڭԡ[~ñkb"@jI!%|'Yi~Qꠚ: }чtt+I_! fm"{(?vI09&I~7׃+Z 0,¾~!x5@I9 Ǩ fP}- SN{p&rxs<:=>$=.>PK I6 AMETA-INF/PK I65|+META-INF/MANIFEST.MFPK I6A4org/PK I6 AVorg/apache/PK I6Aorg/apache/commons/PK I6Aorg/apache/commons/io/PK I6!Aorg/apache/commons/io/filefilter/PK I6A#org/apache/commons/io/input/PK I6A]org/apache/commons/io/output/PK I6]m_,META-INF/LICENSE.txtPK I6G7META-INF/NOTICE.txtPK I60Ԛu %org/apache/commons/io/CopyUtils.classPK I6B5;org/apache/commons/io/DirectoryWalker$CancelException.classPK I6>U+org/apache/commons/io/DirectoryWalker.classPK I6v'C!org/apache/commons/io/EndianUtils.classPK I6**9 .)org/apache/commons/io/FileCleaner$Reaper.classPK I6@:$K/-org/apache/commons/io/FileCleaner$Tracker.classPK I6YY '/org/apache/commons/io/FileCleaner.classPK I6c֋F}4org/apache/commons/io/FileDeleteStrategy$ForceFileDeleteStrategy.classPK I6.5K.l6org/apache/commons/io/FileDeleteStrategy.classPK I65˴P;+9org/apache/commons/io/FileSystemUtils.classPK I6k/+I%Iorg/apache/commons/io/FileUtils.classPK I6!'nj&)fhorg/apache/commons/io/FilenameUtils.classPK I623 #|org/apache/commons/io/HexDump.classPK I6@N^ "korg/apache/commons/io/IOCase.classPK I6P[+# org/apache/commons/io/IOUtils.classPK I6k$(org/apache/commons/io/LineIterator.classPK I6*b9Vorg/apache/commons/io/filefilter/AbstractFileFilter.classPK I6+4norg/apache/commons/io/filefilter/AgeFileFilter.classPK I6hkXa 4_org/apache/commons/io/filefilter/AndFileFilter.classPK I6Ar; 86org/apache/commons/io/filefilter/CanReadFileFilter.classPK I6B-c9org/apache/commons/io/filefilter/CanWriteFileFilter.classPK I6qނ<org/apache/commons/io/filefilter/ConditionalFileFilter.classPK I6 C`9org/apache/commons/io/filefilter/DelegateFileFilter.classPK I6c-Ă:org/apache/commons/io/filefilter/DirectoryFileFilter.classPK I6f6org/apache/commons/io/filefilter/EmptyFileFilter.classPK I6P6org/apache/commons/io/filefilter/FalseFileFilter.classPK I65o5org/apache/commons/io/filefilter/FileFileFilter.classPK I6(.6ѷorg/apache/commons/io/filefilter/FileFilterUtils.classPK I6 xM2U7Sorg/apache/commons/io/filefilter/HiddenFileFilter.classPK I6VÌٷ3^org/apache/commons/io/filefilter/IOFileFilter.classPK I6(5forg/apache/commons/io/filefilter/NameFileFilter.classPK I64org/apache/commons/io/filefilter/NotFileFilter.classPK I6C>e 3org/apache/commons/io/filefilter/OrFileFilter.classPK I6$V7org/apache/commons/io/filefilter/PrefixFileFilter.classPK I6DD55-org/apache/commons/io/filefilter/SizeFileFilter.classPK I6x$T7org/apache/commons/io/filefilter/SuffixFileFilter.classPK I60]EL5.org/apache/commons/io/filefilter/TrueFileFilter.classPK I6J+S ? 9>org/apache/commons/io/filefilter/WildcardFileFilter.classPK I6r[x5org/apache/commons/io/filefilter/WildcardFilter.classPK I6?!>org/apache/commons/io/input/ClassLoaderObjectInputStream.classPK I6E5 org/apache/commons/io/input/CountingInputStream.classPK I6t(Vx2Aorg/apache/commons/io/input/DemuxInputStream.classPK I68@nr 1org/apache/commons/io/input/NullInputStream.classPK I6}` ,org/apache/commons/io/input/NullReader.classPK I6|I2org/apache/commons/io/input/ProxyInputStream.classPK I6 iZ~-org/apache/commons/io/input/ProxyReader.classPK I6 m@ 8org/apache/commons/io/input/SwappedDataInputStream.classPK I6mr$~`8org/apache/commons/io/output/ByteArrayOutputStream.classPK I6Mz7 org/apache/commons/io/output/CountingOutputStream.classPK I6ח/&{; org/apache/commons/io/output/DeferredFileOutputStream.classPK I64Qorg/apache/commons/io/output/DemuxOutputStream.classPK I6=Z 5)org/apache/commons/io/output/LockableFileWriter.classPK I6Mэ`3org/apache/commons/io/output/NullOutputStream.classPK I6- org/apache/commons/io/output/NullWriter.classPK I6LʊD 44o"org/apache/commons/io/output/ProxyOutputStream.classPK I6aL3.$org/apache/commons/io/output/ProxyWriter.classPK I6{N2b'org/apache/commons/io/output/TeeOutputStream.classPK I6~,9|;*org/apache/commons/io/output/ThresholdingOutputStream.classPKEE-xmlgraphics-commons-2.6/lib/commons-io.LICENSE.txt0100644 0000000 0000000 00000026137 13777276623 020607 0ustar000000000 0000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. xmlgraphics-commons-2.6/lib/commons-io.NOTICE.txt0100644 0000000 0000000 00000000264 13777276623 020477 0ustar000000000 0000000 Apache Jakarta Commons IO Copyright 2001-2007 The Apache Software Foundation This product includes software developed by The Apache Software Foundation (http://www.apache.org/). xmlgraphics-commons-2.6/lib/commons-logging-1.0.4.jar0100644 0000000 0000000 00000112177 13777276623 021140 0ustar000000000 0000000 PK 0 META-INF/PK0META-INF/MANIFEST.MF0E{K)Em dEfIg"mچq?ٱVZ]PK>FPK 0org/PK 0 org/apache/PK 0org/apache/commons/PK 0org/apache/commons/logging/PK 0 org/apache/commons/logging/impl/PK06org/apache/commons/logging/impl/Log4JCategoryLog.classWEǿ[ a!(X ZhmJ  Ru f9oo9-G}x{wKC<;7Te|n RLxvirkw0ϟ zE.r{\cZ)*:q{<%9l(b b9ܖБ4\LYS2+j,oWc gJ&cd#XX+Iԍ>$4L; n֊ji 5Y%TEI츱LCIMWS%՜S*72J~^15v;(T+ꊱX.9!])b~2ZƙYZU3=/ŢSk GV3bH%Y4pt,K՚5TLzU4L%Tk; ݠ':$ܵ'uSG^GV"sM $qJB8sf+. +a˓[u |4w,8k5q䴖GDad4*g%OVFq MDo2l 5"Cê⒌2(8?td|SF[\lpĖkܺ$AFuc?ʱ-_ƪ|đX 'TYLى"k: t6-=2xҋsƄU) & 719v禄Vys99UP=JPOӥLgT's2Igsft = "3T8hc+ ^*_Q?s`]4P?xC=^,aM_Kub(DHCv*wG-^K)bDy =H]T?w|CO:Oo 0 `{rmKZDZ{P.9z'a&ePK!xCe3#a?Ic&Ş4 ͈,Q6c{z`Azqx\2qHBit[k\?SݭFRj&Ιz&lj ROH&5S˜a&#ꈚ"\3x}FMk)5 Һ.0i# 2AH*Hak9U.V'}ܰ`Z[KIfzG6=QBICJT+czF4GHiFBMPMginXJXh8")D5*/ivy,g mJZ"gi-USsH \aò,,)G">@g**ÔӔJhmEWW 'D|OX{{Q~vP۔;»{Ei @GDGjijR8G)>+=ZT{H{PE"!ogH{@{JJGJ";j&_W"mIy=.} *B4z/`bs&OWaNo?O+rAIjK)9q?X\||,Iڙ*{Jcii57u2|`|^*G*E@ө_8ET)Te'^Y<@^ɫ'yV3|V.@:%}!Rze_Y1eV={$>ªpAG["Ẅ́Njҡa\M.i 3jeVM.e|aNb^G'55>ng-T +檙0\@Mi˱3yԘ( #g]Q nѴMRb*XqzY12_te[*YN)o+vW.nQ&QÙQۤ@livaEK9f9@gsvJ$&h^*vMy{=qZXC͓~hӝ.,O d]iK٦;FӢm޹=uXŊwGoeE]p4}#,2t$# fOG[lZ5궀GɠϹU(/X*;vTY༬xhrK8x%ԃ5Ч@0a@1$ lŠ,4 8p=* TAC;Ӌws%TFa|M {3Iܟxf7X^۲,ڛI&Di־lӮ'~^K[wd8a5h4'&cs%$h_晛|cJFl'IFsq_B Q_ط@c2gI{ h?#5l1<϶ )YЎ+\1jxxOH ~:0p_ :cmbi:Z1#xO~GLҩ4jnJSC=khQ: *4L>EsoaP5zƧκ'oq"q2?<58Oq JK4*ϼK:sєk:^m=@/c+kȑYrx Z]p!wSzN}T!'|r dN#Q s+طz9_X*Dx)X8WOE=W|ͼ&zS ޫɺN?aaO8^9߱@Yυ(cL= PKkv PK06org/apache/commons/logging/impl/LogFactoryImpl$1.classR]OA=-JEPhi-蛆IHb}؎%2%'oj" %0txzrܾ՛.ߗIRi4_mnWF!,]7VÌ51"XncU27x6lmo"N T")L> 3b_s3gIp}dLϑ?1^}F ccg͔Sa9~G tb.P | Yeg,f=11d?PKg APK04org/apache/commons/logging/impl/LogFactoryImpl.classX |fdC Dso@ 9@IvLN Z=ZU譵-mi) ao{_֪ޛI&_&x:\b*؀pLjB̘5݅Dƅ1z *ўtOTb5ߑ<Yid:8Ι»3Q\hgX]KFdԢچX:!mVE/Y\i68ޭfhΣ0ndͺ5Mx CY,%4F*~hQVgfb~QY7A3֤.̢t)3 q攰x,Ri6e2a^Ӑ@k>4 SJܭbH1ba';8*p-Dqý*v!b Ivjհa'T9UP؝TH~ѫ؏i4mSJ"!BNt8v?`b喾rXv0D_Gތk'3G26y:6;"V,LE>v*В& c_2.RyDўJ1yH.5Sv![9F>hwMcH7lF{g20sАm=ed5jK&ŇzFخoëmkSZ<*vf<6߈4^5%9ݎ\0qm+t%&{? f36M^ޛɾ]EefչLzoFs'[|bj6`oq"h9 VW**Fh\`v΃:T#7`zDkh`7rrϽ?3r6> Zcrtx2ü y Go8@[NkP|Q"AI(J{a( 0P0 T.f@* EBf dM`q;.X6aTd!BTfPW1&E _Ҙ̃YD$6@&;N3Y,@Fe(J)TQ비<GUwo _&UO|s5@( Jq !qKp$}:x+n`nK7mu &^;Nf5ƂޫUnA" br^a=V4SXtȢyڔFͶRْ09OzƖ1P=Y]. Ȋ8'W%Yy/pp\(HqmPhKKJO%Dw}>M$sr-#d>RfRHUPCHޏO|$iC c6j64ҨgWv`6yxyv^7KAfr5ؙ_nmUl ~ C|\URt>ZiVӅhKMkpm@6"Fc7Epm-wPn|Ty6XqWdW>]۞M]!*3ڪTH{Ų4 Şxw +za%g  *lq5Om+}*}ht}SUT8gڍs3N ubX#1>^;'tEq"g&>-KrÅP #:9M'YxN](Ϗqmpl#g PFI BڃZA#zNoN?Ϯ.pģt%}Ӈ |6qlXe&/C<߿Z\˜ve?χmS"!s웼WkrEN{TsasŖH#(އ@){r\$bOg0u2~E*cW˕X<~;ɣg_b6n<}wFpTNca/M xg 30<Ë k /13l0 .*Ux6 ؝#]ъ=Kl8.ki5]`g~SҲU2 Ǵ ڋϙ٘w{rȧ򦥟o ]ԪcWmT̺t0KѮlΙ R͚+Uwl ݻxu)JaS/6ܴJM5C: *kǾqD|Bw)GI/4 :im9UuDZ}eU-ZL+ LL^pˋ藩 ì/pal K:j7dCHo4@CxMاAW1IxW@Q!dT(+0CEEW9^jW+WO∊ pD`L@R~NCh#.Ǵ: e|=tiFꌩ;S%0L÷f;.MO?Lqr/MVm+eaKSuw;;/] c}"Hy2EOnIS~?_=!w){sw53QecIDC$}$nt6*~R<>_DğIkuQwߓvDÑeIIu|{Lr)-|kSu:ډ?* ?ՉK?։[? uvPKhq; PK0-org/apache/commons/logging/impl/NoOpLog.class]o0ӏ@> j,6 $hh5ݹizJ*Io+$.(ıkUU/y$M~ Zڰgþ ,f ByA}K.Q.Xr4ablRM'Cǣǩ `qh:g|Jý_Rd Ƀccv z {޻Lv) fp@MU߈Y$srwѣFpC~+ѐ"K?v,|2N1),O7tōO7|#'J?e⿨g|(ܫPB`y ,dw:>!*`,|,(B @ ^oXj'kYw $8Z$|ܠ`1[%y2T+I|Dc*L"{*"㯐ђ͹1[Xh|V>>kz5 cuKϺ統φgCgSsPxcd^x2E^/Wa i,a\P$Mɲ>B(+>)x.s]˧sT`[x!Zp?סx,w:ڙɜ|z(kcIE? I'AF iE|;MZteZ|_F\!N ~]" X k(X9'Gכ9W% m}q)u&4ޣl|qLm^$-\#zbױ^?QPK PK0/org/apache/commons/logging/impl/SimpleLog.classZ xu>gҌV$C`" 6/c XI d1^V#ia+vWv$N&cIK쐤&MPBۭmMcN4vWcihM?wFY1i3u9(V>}SzCi> ~>O_>-|yNFoOo{yu;G^suYiBK:kź<ӸG7қ>6x΅:\l:yuN2/zIRh=/x6h/˧_ >.2]!EOΕ2 M|\+}\AWi\jMyv"t^/"4.D7moѸNb[^1"7h/xۅجwYƭ>:LиM]ָ]Jfo?t8|,}t24>OplԹ0D߮db04JGcA!tLAxACcSݞPƃ-[ꠤ ՟8P:ɴE3dNQæDr ILfH''xQjv0Ը1ts>54nݳMؚ"76 5'U*Tov!f:BB΃S亐"RI NQd(4iD+d3cVhLGbT\_.+Oَ 1Oh)h &}p,$rCK;& }fڪ ;L+*./JZ'zd=hl8d&;ÇbT^" '2޸Zw2 9J4=x"b8sqd=`x(c[Oq}ڼMx4i[t{*((((%LNNQ82vֽ͢PPr**Y2SUpa3v58.DD3 ٛ3sˈe y3Rio=V=1=桡iY).+/7 G4^8f27t8j}(2M"!̊) ]0CEMKS<H\J**7B\qr^wE3ݟ,80bPE}2X "Ԗs{t?/ $_oMt E-{N9i7SdĬKDS;j9>8XeVdZ~66@='Vɣ6{kk"ݔgy @Z1}S$f TJ;AkzSeK}C8#,w4EfKMzA=1]k!LPL f$qsA4g~StlA"|tr}=,_d5vg;kU0J.p1@M{!8#E=fc҆=Dt E0 ðY:د5TC~AHY kā2N |>mA/[ 9)k[ߕ"s\.>q_fq>1<ɧPʮ%G0niUZhPRipX*7O €SveһɠJVRQ5mi;v0hͤ >w:rh)U1 c_%S} Ԇ'Ot7!Qs6`FҠw ~iU3RgПѧXÆZfq̶}C'q(N]9L]`]Ǣ'-p|FkVoњzI1fiDs+\Ѷc! <)]<]$P8j'f}8e^r &q`L2UO'&i;v3U= s `=?5t(e_jMݣyTd  iБGtZvA+>W8KH rz/3Dž*C1 _nq WPhqVA,<9.H*?T\I+IpK]R^)#}ܭWfF ;T lT$hC`0zH1>>e$>Et]7:ĉ^+R8y(A4QJJO,tA?@ `@z8 zݗw:ݎ1/s?tߏ?|*? S\to;}1+#]Oc6CqB#mY#Ug! b: K`y>,xDVQ~\3 P'mӻ".h *Q1Û\|J}^FRs)D=n[^{es3KG(oTѬ/Lt<17cc.l +E ˅e7B* X Ł*@ssh^q*kCUtlEc:X/|d/Tȁ/$x߿x]%} 4A ZM/&FHMڷ@q_/c+Ui~@_8CۿAONoOxE?c }ҤFZY ?Wy?]*vvl@T~nZu?ԏCjg2}Ts\d|ȹJa1jr=Uim(-?MK^qnb*Q%]%^@ޥkX!ZUۈ&V݂a5p5\a5a`JT{vbE HM˟*O]cZ_ʟ&+$2XZKGii>9?xihllQ-" aCE]{6m[YUK%(ۄ9Pe*'i1buTĥRh/z:t7/ zGy%r ]ZzW& Bo\xʋ6-e+f.nVn%8S鬪!Q0|FOyg\^*}Mٮz F?F[1%(L`AW.ڶ­ROEΙ^ŒBlXYlzv*nT|*)/ stDb*Dɴ|jN.OB)h/,# 6qkzl6w q~J懠3Yly?ƙkxSݼ#{mCsl94yh*4?9c'\mq 6.OivEh44c/eo^A{f W3V/e?[ ^ס .-|RMvo>EZ\ut-Y+.>!eŸbWpHWJ"E'Y7\Ҽ30A84NۺSߎ2j`S9B7ВVmO~FLjP*RcT*;hY2A[{-8 :5N˳j=cO/{SgxgXw (E W K ].b6݌k'x$_;VT+܉;Eq~{᝼7]cqۍ3 (IY*Fڙ+_V` Hea6'8K$ĭW=xqsZy{y qk'#u $T8N&jXU GqBE:܍:ŀ!e%zNP(BGp?E1;,;dJ1>dcя@㨢32j վwp8 ~ BdsZNQ[~-UcnX8\ߪv SPK.#Mh$PK02org/apache/commons/logging/impl/AvalonLogger.classUMWd~20 LÔZ:@RP壥"VۚdfB3N&#+]ٕBk;<.t++̈́4$ܛ{>{7ϨILesͥq9(^?cbWpߖ,YaU6ؼ:lb6ln;11dbP4g՜\ѭy#WMORPn9S.y'Yj)/Q5Ir)^L1Y޿JSFPk%uR̨抜mCUwVA+D1ETV\mfWġ`ޔWe9׿i)ΕfL%/@-fTDV c:k9 UMNr%`Z)G <͔ͭ>+|7LY.tZy +ބkYrşx FTYջMC,Hs "c"Y=8&օ_13)꺥D3xI\NYF*몢45r)Bb2=δ Ɛ"'!/MPΫ8+bavﰫ;#쎳;$$[0J<t5^Vdӡ*hzv;0QĨ.5˵nFǪ}{w xs 607[h m EGz/(>G/{uEst-KDr7C]eW{nfKDoQ-j H;7 Y&>C+Ui[r6lZƋxɦ[Ħ:P-9[PlSm9`qE:']$оHI J)g)aR>)-A)wIH9&/-(g)g¤|HR>EHCA)=K  It)sO;-W.^si;Xj#$_D Ch "|Ya, #&¹}fM0 ¯5&ڢMmc54V2VaRR J޳0)]>)R!)>QJ#ゃf?ϖr ??PKdqՆ PK0,org/apache/commons/logging/impl/package.htmleAo@+^}j%nScYF2N0`w;DMT2ofyC S9f gBjeɏapoz]ɠTISJ_Y9r+|9t+0M@+(Zz)(tURA\! $%-20^sk  jl\WO./vN)%wy!-ӔČ`dcLSAf ?{&P):Ql<[[%5iX[ZdR);~?i~vl]v9wK]źd!UWA}m8RjUPeChrg%)?3\%ЪNo("6BO7bm7[KG.ԑ~5v;~Z4S\0xX.\ PKƼPK01org/apache/commons/logging/impl/Jdk14Logger.class[pU&&l[zJ)%r  %@H)&6ݤK753雗GuA- 裏o3 iݦu|ȷg|ls.x3>$؀œ Ҥ8 H sgGF 1|V|pQ$^_EUa UƔi ~絢Mu#*t3Mc$xMI1TeENnzÏNr5)ҕ”VP geUcR--% )sjvFfB2Ku]zaΈݹcFNQhqqm =3EkA BBFyE>])\YL & 5;;QTZ Yj_sA+Xb+CԖf+JevxrA+#Y !5Um9_d'Ӊ1;2NI~FhoŏW0>{j[6># E%2$Ld ^|q O@;{߇8x['/sq2 z-.|[co 1W &3]@(`Lu{$$$Z/Aކж=FGۏ4:p9,du,vcyE%~/Cjǖǖ0cAF[ >Y)lg_? G xVznNf6@nf;q-rC!吂` fVƭy(WC҈[C֋~Gnz_lwN7o֦m76X'w/-<6ıeu76؇Ƕ+J!4t>mCivKD~4K5Z։+e :oly]=7D#Z?8"!nOcn^ώcU/ڤVA+(ᨷMDoQo޿{z۫_PK$Q]PK0$org/apache/commons/logging/Log.classmN0Oacn /x+$&$^H4tCލ 2.'bž|Oz]"0HT(kfНxuMW\7A'큕hqg+`2]'472{wf n[j?Uk_A∛03r2؃+Bi_Zycpc/"+~oMi+=8 ۤǀA @1"g/j1yBɇ)yJ>"yfcvPKc` PK0-org/apache/commons/logging/LogFactory$1.classQJ@hVE<(ZA TPzߦK%fS[I($ў\ؙo{|yEGr`a2VlX0}"ciNV=Pe,.aW[ލ*QkhL^ı' +z}j8TqE* ez y`(Nc僆?#EBr:7*Ձ8Q^źmb ɰ0a;Zwrwΰ V&xOhZءX4)%Yzyi:|{3y@!~`6QBAnd /UpKXe s򕑝PKXf[CPK0-org/apache/commons/logging/LogFactory$2.classVSU!dv%m(7ܶAsI[Q{PLAkC(Ra5ev7^t}l/}N(BN;98 .˸"cBUL*R0k]ǴQPu1+4B |_ME!(pKAe,X5%LkQIéKVӴl3YtYwS‰]}]Wu ] _eHdeJo &RtE','%UzIB9Tl^VTzuIw-PFE@zöI|MMM~JíNMZ =p\7$n-N.l|ͷl%PkzPu# 7m4.0jCfsb8/AYpgj@^9a$#KJd|,8bT0FT Mg*>Ǹ/*^e*^+!8s p5K CG, *tH?:cZfՅIG}5xSҬZ׸xpO_>MȜ6_'|p+m:ͱrOC e #ܺ͟5Fݵk0yyk'A^uܒ^[νh*&&o=\{Do}K@GJm $48f{7lmtSԡcY޴Y-uHСIߖifMA,AK~AU]L'!Diz?CXgvdBΌ=DgR1$iL(ZkH0B!dC׈֞Jo17bvʟ85'@Kн+ԟ%6?nhDѐ`dW}i?n 2mMݏѳ89-!зEuQT18Nh6I)`LEK`*6l߱]}6m6X!`{'l3#0A40F2AnпNz؁9Vx+VTEm%"R4+PKNRnQPK0-org/apache/commons/logging/LogFactory$3.classR]kA=ɺ&5ZU>*B) Sd3lI UGQIVpa{Ι\|t||A`X'ohVDPK[.JVPK0+org/apache/commons/logging/LogFactory.classW |[Uivmn6MkYm7(g޶iRnn >x(  *"nC۲"@ *A!(AE~K⯿sw}**m);]-db2$}@°`TJ/#WbLFI=8  |zq9d^U sLnTvjj>5+.!T0S[}UCC-!-"֦S˂2` X(JzΪܞ~Ymnߡuo3W^5f1ma0?TLy ;jʌ(!ijT %65/>/Ēկ$,ٱe: 7NPM0R5:3P㏸x?kg7LNb})Mnl3ig)Bj8EAb0 3ݪvX"t!wV̅1oug N9צXOB3fpq 9b+E㥖ƅmg-F ݧt~\~2L^Sݧq|vGS-6EjO(Z]U848}m-d|/"B$])'Re3FaAX7240^bv@55)( XQmj"j]݊)u5e=&XQˋf%!,&y!ΓpJX=VI 9#Q$P-Hqat\ %v3֩&5 UUa<ν32H)XL jBQq~CQF+ 7sY\,˸P)*DP(K`,Ȑ< :l,W)Wz\9r[n|1P|`FlCR]U(Ξ7k6L)wvo(ԆTǟh(M8LlLJa 5dcv{^q0/Iov"!4w漩2 zM1PrۯTH>e[Nn]`#Vg@7Cp%\h pmrR^w Nfz.Ŀ=j[)z ^WVpFkƣGyTLp2fՏ)"L1iAE1slQ>E⸟tsU>sQd7YAa{UFRuce͕U!d UHdW9!8[X]ec ;(7(c? e(~AT8+ӥ5.S<\GՄ=YUטOCj}ycXNp7$˦wųLP/W GPױo07[4]lQf6C0 547B 1DJN~ZCJ&n6B^Qww![CW0d b'1W-bFGzhǍXOLw13K K eeW"çxɘ<ʸvOsD^F ^Fb9݆Ut{ aZ+1\-]PFrkP^]K85Q!qZC7[W93pZwf%Ά08U~Wq[Ӎy f4io~T}XCa=3 'ӆ+OO=J8k|_`ٳ ׍j'A|ў9ֲ[;S; #w‹ E6K(/ mڲha8O* 0<{L2 5x~k )~]ˤ+K` ;\4WB.x*+'p!DZ&;6o-2 /*H,ѭoەǟlxOÆNrԎl+DfNW|ZMhk'8N֕sVv(Oikn [TdP̥, Q&2Dy>,Fy9PKm2 PK0:org/apache/commons/logging/LogConfigurationException.classSOP֭TSD*B|#Q\0ė\]H4?xn[ǀŗ{Ϲwְ%c "ᮈɸL 2(R@Uzjr8\zgmsF+[6f︞2LTG =uQɃ2u߶GV<=̆-iu-Mt|g}qYw|u ]{]PTa@m1὞m+#ňJ}Xp^bB: Џ?wjEPL㺈%+0P$ '{@1(Z%Xk~&2l K^G^vǙRɎOb`r6%/_5OD{ /a%E9YZg(A"@t /e0K3@*(bs) XYfRT}R701j7x3O)nb魔tJՍ_'HFYj;c.U=Uj,<]Ny#ߜŴHKYvAJ/2q7Ac#$"1p6Vx$+2ٹwbPKhX`PK0*org/apache/commons/logging/LogSource.classWksU~Nt (%WZHZ ޖtIMaS~?hQZQqO GGo9MCɞsyy/FkN+mt=r}{V w{"#uҰ/,4D1,G#!ߌ E hGI『܃Qi^_!pɖfٹԍfi3=SxsR& vS<<84q35{\s\6^,dS/ge&PܲT v;v&gVWhɘku {C6YJ;n6e̐8<R䑵 vNH7,/V3=)x ~LS&gJ3P to"mYRSg_xՈ+!9Ds$ Yy[pU٬T 'qWi6 ix82-i:0Љ"2IL9$ x˓Iy2Pnu Wu$VO&ϠQÛ3+`\KhR{$ ϥĦ6bfͮ+{ʩl3gZn63C7 V,ɣ)WmV})j hOuG܎x=9Raˆqf+8Dfgz]"T,S:h@#Ufd>UN:ͬ.pU闾ΟUw"ٜKS#0]RkVuھP)yV7Nrʴ)@B1@A6Kv 5v#[&G B".ΊY!qҀ|F8+װNVJT$o45zxASvuƠc,S֪y#<ʗ1V e\/VzlԸ WSv9 b#&\hnh$IRL2Lw >)ǣ $|8EįZK&>I&v0lGS8"ߠ9-:|HK!ge[4;"|OO5 qE3zHq[.ȦN9'0wrRLiK ο$KLc&И{r8K%M1Nfugo\  uoMv=0}N~ev&HEX\x /`ZLy-&qdŋ_yZI79L)4"e, S8-}EtkѶR(m8[G4EWXĴ_0jq,=J%UJjclbzl8G\s|VU`Ch*쵘zzb5wΪ`%0BAp.DӸ=ޥCJmOb2u2@u6@\򊣼fޟ=te-&P5t+o:PKnZ; PK0'org/apache/commons/logging/package.htmlZr}@zR$9+mL9[΀$``H3){N707M*K.}D^&Rl.C5~rV~KУJX\j<^uW|.gSS웼¦JSςKe50uGcWcSIfR7YVPߤ:hԗHs{ȬfZys^]i>8/f:L]0_D]_7G>##uYgze.yj$-킀kC kL}=a> !"Mʗg/f%.vg|@ \iA|̌sl3 !g1p^Wr6b(gKPI j{K)up x $q["ڪRa൭#BK{𖲚#kQwӽ1~1vy]/1:$`CEg<`fbk]#=,o `ZCk3Z98HX+`#fN>/NğY!wONZ8K;[:iax^0"cP$aNf ]s":++<-=B/B0^Vatmbw\zU$p`--}[&҅9Wqk^o/X-gW+cmv]i/aY $N}:#FT| ,`U.h'iii1k/RS ]zH )+]4(e욕,PKUuba" #.D:2tdž6i~MSϸ4_jMq*'ZrN9"d/'VU-ØW+l¹*" 5n/O'ꉀ~Qcb)Uvk1pJ3(.J|u|  r̍8MUC~y<޽{m9?2򄂫u"\ҒtQp,y-QZ*:3uZծNSm/Yc5 @C0aMn|FA=9c8K WimRۑEeV+8n!PNMt}AdHKVU/e!A-;JP@dR1y-}6&rOqALTR@+es#⢄U3P٭z^l@/"ϚQh]!^\6yH N:a="*Asm{G*6ښsU0+IP ȃoQ(#Ui[5} bFm„0"x <*ˢMlT2o!&jz$!ْa5x{C1 ~WkvRgwQb6N $zyb/,^K$%nu0X2dU^UxQAF:F^g\LHF2 Qq'h/Grba/afmW=C|I:tQ:n@ H$XRRGY_$Ի}F2k[Ab*yoA#kކCI}>z8y04tK~M.d6sq\X:}=~%b5$ tt{9yG.]0 i (l1OF8Ao]ƛiF\-gX:)l=g܄ڇiX Xq lf_|rv~茪#cc?]M[?ȬhBH,m,v ċ޳.Ԡig:Gߺ$`5 >2Wz]V؃%FmE?)$4oc(a9e 2GNtA@mI]lɅYͥ)!"eT!kk8 ۣ=jqr­Lg<,n2T}юݺw|[dDÍ+? VȼC[8Zl#>r?0g`s8[~$<lQ C8:Lbw,cښJjw:h<49MgU)dQtf 9>=i'x NۨDL?5zh&\-1GAP ?bO5]۲ȦirOYǦB4 w2C[#"^??va67㙧0}̤Y)'T5E]QD88:+f~RUHM x쿟qJBTޟ|FmXj%iњʷe`gǞg0.rQ9c0 A:"tH/;Sb3NJd9hC4=Sa1ld jֱ|ΨӐFgsLrM-u7[sJGWt8t<6k:=S l邛!MRˮ.v[$8 5mH@Q/i\K~h|ټ4vecƳ?1-,?=zHcD\A3*juRMZ_knt'CHԒt*;s̰+W(dӔ/ҠxJ$WnhzVU.m Q72Tdq< ъCH(7A|>C:vg* )mw=3/EOg>ޕW$s lOv$|5?PK/K@ (PK0META-INF/LICENSE.txtZ[s~rSi4i牱䆭CiDn&% . =dwVM5Iٳ E/˝u:^ qw}{ws-~]SW j.T;=rnk3' M#Z%;1Ie['dWtbtVTc_^>[i7X{!pKUAUB֌۝N>hxΔcX/cO+Mzw P  8s+lv[z!S@me#Ic$핐%I ZY/^Ao i ! RcWҴ$arxùxg,я71ɪG3/eFGqB_RWY*;w!#J N,`E+;U<׍+VN$ٹe \hЄvGI%/i;aA:d AFu`R+'3=6L\Z]^&Qy|x[<'$ְ[ )GZoUkM[p4IY3htqw3r!8#A^ ?Pv;Q|lpcl(?jkZ Q9|RoRyH\1=qtLH^cBRs g' NPn*-pc4 (KҘp#-1bZYdąn`x8[ dV9 X[BA[/eΰœⓋW#$Sc Wh7; $AP|#:Tp~*܊܅r8kiՃ&Wbi|66|y6yaX唃H!K4LouNՓ/ı0HVRT)h:Fj'2㤓 ND%"Ѩ'Ju"9S6/'\Q6 pHd6 ~J"KQMm7n;h#ZLjDe}5ie^f^˰H5腍l(uD>[_`FWPhd!R+K:"7@)AZV"r75wTXBJ v?V>f+kF/2DAfmprtTiǖȏx4`YC ʾo48U+lv8" ɭquNZMY[@(j_`)_DVOˎq-$obn.5?B c::e[VAn%L T"ƹd0)Y"(Ifb<2Aŗ5sgJ2%S/I 6}ԔAddITgu>Iy=@ ]'MTũezٔgTe Y V/s0#Pwa_fM[8"5P":LflȪ[w̤ս$ Gg~ UjlmDL;1 `D*虘80O[5Q*Ұ +s UƑF:ag|흹2b1]hSY<<ъӹJ$ΦyI۪IgD1&cةu|K͎ ^5@7:aRcK 88l]%;rmӚyEjf"Vׯ̀ ՗ vKR͍P_ad.1)X1D[(>C#S 7Ī|t{?3]B΁)wv#jL_5lqn N}:CC6ժFo; tr)~4jVQ+bӁړlȦ7_ ΔԟJ;jҶ]1 7yc`HKa>]Rušq?ˉs/q?[r=?,u07bu^ZX~_h~K'ф+U6&MDsRpM."{ `z\[z?]߽\|B~u^N~Y_so@6t@73NOB˝1<I䲝fjExPGʮT|ǠwՒ4c6Awa6Boy̗ZcsmhJЮ `ՙѹ-!Q ъ)Gkm&CW*QӹF:-l>ƌ6F]8WWXWϽG/no?ߠ iZz/o>%.(kiBB>F:Zr $;o)D_gh2!Nz..L@A.uԦ: @;vv7"zVp6/i?' (Nr@!c嶋hfqZݨ ݐM.r4F a|_PM<½kϤ!o9e/UBzG>HgO*.("#\F'META-INF/MANIFEST.MFPK 0A(org/PK 0 AJorg/apache/PK 0Asorg/apache/commons/PK 0Aorg/apache/commons/logging/PK 0 Aorg/apache/commons/logging/impl/PK0 4.0.0 org.apache.xmlgraphics xmlgraphics-commons 2.6 ${project.groupId}:${project.artifactId} XML Graphics Commons http://xmlgraphics.apache.org/commons/ 2.15 1.4.0 3.0.4 1.7 4.11 2.8 UTF-8 2.5.2 2.18.1 ${env.JAVA_HOME} The Apache Software License, Version 2.0 http://www.apache.org/licenses/LICENSE-2.0.txt repo scm:svn:https://svn.apache.org/repos/asf/xmlgraphics/commons/trunk/ scm:svn:https://svn.apache.org/repos/asf/xmlgraphics/commons/trunk/ Apache Software Foundation http://www.apache.org/ ${project.artifactId}-site ${project.baseUri} commons-io commons-io 1.3.2 commons-logging commons-logging 1.2 junit junit ${junit.version} test org.mockito mockito-core 1.8.5 test xml-resolver xml-resolver 1.2 test org.apache.maven.plugins maven-compiler-plugin ${java.version} ${java.version} org.apache.maven.plugins maven-project-info-reports-plugin ${project.info.reports.version} org.apache.maven.plugins maven-surefire-plugin ${surefire.version} org.apache.maven.plugins maven-checkstyle-plugin ${checkstyle.version} ${project.baseUri}src/tools/resources/checkstyle/checkstyle.xml ${project.baseUri}src/tools/resources/checkstyle/LICENSE.txt false false false true ${project.baseUri}src/tools/resources/checkstyle/suppressions.xml warning org.codehaus.mojo findbugs-maven-plugin ${findbugs.version} src/tools/resources/findbugs/exclusions.xml Max Low maven-surefire-plugin ${surefire.version} **/*TestCase.java **/*TestCases.java true src/main/resources ${basedir} LICENSE NOTICE META-INF src/test/java **/*.png **/*.tiff **/*.txt **/*.xmp src/test/resources **/* custom-javac jdk.path org.apache.maven.plugins maven-compiler-plugin ${java.version} ${java.version} ${jdk.path}/bin/javac true org.apache.maven.plugins maven-checkstyle-plugin ${checkstyle.version} ${project.baseUri}src/tools/resources/checkstyle/checkstyle.xml ${project.baseUri}src/tools/resources/checkstyle/LICENSE.txt false false false ${project.baseUri}src/tools/resources/checkstyle/suppressions.xml org.codehaus.mojo findbugs-maven-plugin ${findbugs.version} src/tools/resources/findbugs/exclusions.xml Max true true Low true xmlgraphics-commons-2.6/src/documentation/README.txt0100644 0000000 0000000 00000000541 13777276623 021264 0ustar000000000 0000000 This is the base documentation directory. skinconf.xml # This file customizes Forrest for your project. In it, you # tell forrest the project name, logo, copyright info, etc sitemap.xmap # Optional. This sitemap is consulted before all core sitemaps. # See http://forrest.apache.org/docs/project-sitemap.html xmlgraphics-commons-2.6/src/documentation/classes/CatalogManager.properties0100644 0000000 0000000 00000003262 13777276623 026211 0ustar000000000 0000000 # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. #======================================================================= # CatalogManager.properties # # This is the default properties file for Apache Forrest. # This facilitates local configuration of application-specific catalogs. # # See the Apache Forrest documentation: # http://forrest.apache.org/docs/your-project.html # http://forrest.apache.org/docs/validation.html # verbosity ... level of messages for status/debug # See forrest/src/core/context/WEB-INF/cocoon.xconf # catalogs ... list of additional catalogs to load # (Note that Apache Forrest will automatically load its own default catalog # from src/core/context/resources/schema/catalog.xcat) # use full pathnames # pathname separator is always semi-colon (;) regardless of operating system # directory separator is always slash (/) regardless of operating system # #catalogs=/home/me/forrest/my-site/src/documentation/resources/schema/catalog.xcat catalogs= xmlgraphics-commons-2.6/src/documentation/content/doap.rdf0100644 0000000 0000000 00000010516 13777276623 022663 0ustar000000000 0000000 2006-04-17 Apache XML Graphics Commons Common components for Apache Batik and Apache FOP Apache XML Graphics Commons is a library that consists of several reusable components used by Apache Batik and Apache FOP. Many of these components can easily be used separately outside the domains of SVG and XSL-FO. You will find components such as a PDF library, an RTF library, Graphics2D implementations that let you generate PDF and PostScript files and much more. Java PostScript Adobe Systems Incorporated PS Extensible Metadata Platform (XMP) Adobe Systems Incorporated XMP Current release (stable) 2012-10-20 1.5 Previous release (stable) 2010-07-07 1.4 Previous release (stable) 2008-06-11 1.3.1 Previous release (stable) 2008-03-07 1.3 Previous release (stable) 2007-07-21 1.2 Previous release (stable) 2006-12-22 1.1 Previous release (stable) 2006-04-17 1.0 Jeremias Maerki xmlgraphics-commons-2.6/src/documentation/content/xdocs/bugs.xml0100644 0000000 0000000 00000007711 13777276623 024050 0ustar000000000 0000000

Apache™ XML Graphics Commons: Bugs and Other Trackable Issues $Revision: 911792 $

Information on this page applies to enhancement requests and other trackable issues as well as bugs.

Reported Issues

A list of unresolved reported bugs can be found at XML Graphics Commons Open Bugs (Bugzilla). If you have an interest in an issue already reported, please consider the following:

  • If you have insight that may help developers solve an existing problem, please add comments and/or file attachments to the existing issue.
  • If you would like to track the status of the issue, consider adding your email address to the list of "CC" recipients, so that you will receive an email as changes are made to the issue.
Unreported Issues (Reporting New Issues)

User reports of bugs and requests for enhancements are extremely important parts of XML Graphics Commons development, and we appreciate the time you take to help us track these issues down.

  • Review the Apache Bug Writing Guidelines before submitting your report.
  • Enter a new issue report at the XML Graphics Commons issue database (Bugzilla). You will be asked to login to an existing Bugzilla account or to create a new one. When entering the bug report, please make your description complete and concise. If appropriate, attach a minimal fo file to your report which demonstrates the problem.
  • After submission, a copy of your bug report will be automatically sent to the XML Graphics General discussion list.
xmlgraphics-commons-2.6/src/documentation/content/xdocs/download.xml0100644 0000000 0000000 00000004511 13777276623 024712 0ustar000000000 0000000
Download Apache™ XML Graphics Commons
Download a Release

Source ("-src") and binary ("-bin") distributions can be downloaded from a Apache™ XML Graphics Commons Distribution Mirror.

Download from Subversion

The latest source code is available directly from the Subversion repository:

Trunk
Repository URL http://svn.apache.org/repos/asf/xmlgraphics/commons/trunk/
Web view http://svn.apache.org/viewvc/xmlgraphics/commons/trunk/
Committers need to replace "http" with "https" and then log in so they can gain write access!
xmlgraphics-commons-2.6/src/documentation/content/xdocs/favicon.ico0100644 0000000 0000000 00000007066 13777276623 024512 0ustar000000000 0000000 h& ( @7\o OhU.;mt1-"`9?vc Rd^eiYUx#V|zwA Lt^%uhmD uTnt lk(kAzG Gh2j]bQ# }xn P v@ylgN'd pCn +M s5[ \hdGq>"8XB$OD]! ^)*@.PI_J4k2jm`l=cWfrVQg L:<7&T#3SeZR% UFH9poA0;K1,aiEYN6'?b/(-( @i DT~M@rʦ uf*>GB2`m=^-Z8t[1^tlll[¶N"""AFrr&zzua#J vuZX~~~ :Y )aL[_í]uYiM] Dw UY{+q"ɦ1erwNWM4nry Ib`lM5rIx[sz:o Ri6_'~bO:+Y|dbU! Tld W=^ aD7JsYPZ\AY-z)P[clZj>Ʒg aWusl*z%ĺ xK F]  i}YX zu tnX[fH R] ^nź\"^!W_ oeS(k JmZ1f\W&{uW)u/ZT& Rn[#Z3jnz ,^b vSv2v9vPԿ (2$5P\:dJ ֶ$G+|-W(}eܮQT4vNJ.bFoMY|3NކG7 ŊT?X%G|I?XC6ׂܦYkefU) j_1>VGh@ZB{NJQc
Apache™ XML Graphics Commons: Image Loader Framework
Overview

Apache™ XML Graphics Commons contains a unified framework for loading and processing images (bitmap and vector). The package name is org.apache.xmlgraphics.image.loader. Key features:

  • Unified basic API for all supported image types.
  • Image "Preloading": It allows automatic detection on the image content type and can extract the intrinsic size (in pixels and length units) of the image without loading the whole image into memory in most cases. Apache FOP uses this as it only needs the size of the image to do the layout. The image is only fully read at the rendering stage.
  • Image conversion facility: Images can be converted into different representations depending on the needs of the consumer.
  • Supported formats: All bitmap formats for which there are codecs for the ImageIO API (like JPEG, PNG, GIF etc.), EPS, EMF. These formats are bundled. Other formats such as SVG and WMF are available through plug-ins hosted elsewhere.
  • Supported in-memory representations:
    • RenderedImage/BufferedImage
    • raw/undecoded (JPEG, EPS, CCITT group 3/4)
    • Java2D (Images painted through Graphics2D)
    • XML DOM (for SVG, MathML etc.)
    • Additional representations can be added as necessary.
  • Custom image loaders and converters can be dynamically plugged in. Automatic plug-in detection through the application classpath.
  • An image cache speeds up the processing for images that are requested multiple times.
Tutorial
Setting up the manager

Before we can start to work with the package we need to set up the ImageManager. It provides convenience methods to load and convert images and holds the image cache.

The ImageManager needs an ImageContext. This interface provides the ImageManager with important context and configuration data. Currently this is only the source resolution. The ImageManager and ImageContext are intended to be shared within an application.

In this example, DefaultImageContext is used. You may need to write your own implementation of ImageContext for your use case.
Preloading an image

In order to load an image, it needs to be "preloaded" first, i.e. the image content type is detected and the intrinsic size of the image is determined. The result of this process is an ImageInfo instance which contains the URI, MIME type and intrinsic size. In most cases, this is done without loading the whole image (see SPI section below for information on exceptions to this rule).

Preloading is normally done through the ImageManager's getImageInfo() method. For this operation an ImageSessionContext needs to be provided. It is responsible for supplying JAXP Source objects, URI resolution and providing other information needed for the image operations. In simple cases you can simply use DefaultImageSessionContext, but often you will want to write your own implementation of ImageSessionContext. In that case, it's recommended to subclass AbstractImageSessionContext which lets you avoid rewriting a lot of code for providing Source objects.

Loading an image

Once the image is "preloaded", it can be fully loaded in the form/flavor that is needed by the consuming application. The required flavor is indicated through the ImageFlavor class. If you want the image as a bitmap image in memory, you could request an ImageFlavor.RENDERED_IMAGE. Again, the ImageSessionContext will be needed.

In this example above, we simply acquire the image as a RenderedImage instance. If the original image was a vector graphic image (SVG, WMF etc.), it's automatically converted to a bitmap image. Note: The resolution of the created image is controlled by the target resolution returned by the ImageSessionContext.

Of course, the framework can only provide images in the formats, it has image loaders or image converters for. An example: It is possible to load EPS images, but they can only be provided in raw form. In order to provide it as a bitmap image, a PostScript interpreter would be needed to interpret the PostScript code. This interpreter would be integrated using an ImageConverter implementation (see SPI section below). If the requested form of the image cannot be provided you will get an ImageException on which you'll have to react as needed.

In Apache FOP, each renderer supports a different set of image flavors that can be embedded in the target format. For example: The PDF renderer can deal with Java2D image, bitmaps, XML, native JPEG and CCITT images. The PCL renderer, however, can only consume bitmap images. So, if you can accept more than one flavor, the package allows you to specify all of them in an ordered list (the first in the list is the preferred format). The package will then try to return the best representation possible. Here's a code example:

While each BufferedImage is also a RenderedImage, it can be more efficient to also specify ImageFlavor.BUFFERED_IMAGE in the flavor array.
Tips & Tricks

If you are loading bitmap images and you get an error like "Cannot load image (no suitable loader/converter combination available) for myimage.tif (image/tiff), you maybe be missing the necessary ImageIO codec to decode the image. A number of well-written codecs can be found in JAI Image I/O Tools Project. Just download the distribution and add the JAR to the classpath. ImageIO will automatically pick up the new codecs and they will subsequently be available to the image framework.

Service Provider Interface (SPI, Plug-ins)

The whole image framework is designed to be highly extensible. There are various extension points where new functionality can be added. The three main SPI interfaces are:

  • ImagePreloader: detects the content type and preloads an image
  • ImageLoader and ImageLoaderFactory: loads images
  • ImageConverter: converts images from one representation into another

If you plan to write an implementation of one of the above interfaces, please also take a look at the existing implementations for reference.

Throughout the SPI, you'll find a Map parameter (hints) in the most important methods. That's a way to supply additional information to the implementation by the caller. For example, the source and target resolutions from the image (session) context is stored in the hints. The implementation should not rely on the presence of specialized information and should always have sensible defaults to rely on in this case.

ImagePreloader

The first task is identifying whether the implementation supports the given image. If the image is loaded using an ImageInputStream it is important to always reset the stream position to the beginning of the file at the end of the preloadImage() method, because all registered preloaders are check in turn until one implementation signals that it supports the format. In that case, it has to extract only the minimal information from the image necessary to identify the image's intrinsic size. For most formats, this is doable without loading the whole image into memory.

However, for some formats (like MathML or WMF), loading the whole image at preloading time is hard to avoid since the image's size can only be determined that way. In such a case, the ImagePreloader implementations shall pass the loaded document to the respective ImageLoader through the custom objects that can be attached to the ImageInfo object. If the preloader loads the whole document, it shall close the given Source object (calling ImageUtil.closeQuietly(Source)).

The priority the implementation reports is used to sort all registered implementations. This is to fine-tune the inner workings and to optimize performance since some formats are usually used more frequently than others.

Normally, if you implement an ImagePreloader you will also need to implement the respective ImageLoader/ImageLoaderFactory, or vice versa.
ImageLoader and ImageLoaderFactory

The factory interface has been created to allow checking if some library that an implementation depends on is really in the classpath so it can report back that the ImageLoader is not funtional. The factory also reports what kind of image formats it supports and which image flavors it can return. There can be a complex relationship between the two. It is recommmended, however, to write smaller implementations rather than big, almighty ones.

The usage penalty is used when constructing image conversion pipelines. There can be multiple ways to provide an image in one of the supported flavors and this value helps to make the best decision.

While the factory basically just provides information and creates new ImageLoader instances, the image loaders are doing the actual leg work of decoding the images. The image flavor returned by the loader must match the flavor that is returned by getTargetFlavor().

ImageConverter

The image converter is responsible to transform one image representation into another. Bundled implementations support these conversions: Java2D to bitmap, bitmap to Java2D and RenderedImage to "raw" PNG. Ideas for additional image converters could be: PDF to Java2D, EPS to Java2D or MathML to SVG or Java2D.

Each ImageConverter comes with a usage penalty which is used when constructing conversion pipelines so the pipeline with the least penalty value can be chosen. This is necessary as the consuming application my support multiple image flavors and there can be multiple ways to convert an image in one of the requested image flavors. Internally, Dijkstra's shortest path algorithm is used to find the best path using the penalties as "way lengths".

Customization
Disabling Source Re-use

By default, the Source object being used during the pre-loading stage is re-used when the image is fully loaded later (assuming an ImageSessionContext is used that descends from AbstractImageSessionContext). That means that a stream is only opened once and the image loading framework tries to re-wind the stream when it has to re-read portions of the stream when loading the complete image.

In some situations, this behavior may be undesired. Therefore, it can be disabled through a system property (org.apache.xmlgraphics.image.loader.impl.AbstractImageSessionContext.no-source-reuse). Set it to "true" and that feature will be disabled.

Adjusting plug-in penalties

Every image loader plug-in has a hard-coded usage penalty that influences which solution is chosen if there are multiple possibilities to load an image. Sometimes, though, these penalties need to be tweaked. The ImageImplRegistry (reachable through ImageManager.getRegistry()) supports storing additional penalty values. An example:

This increases the penalty for the raw CCITT loader significantly so it will only be used if no other solutions exist. You can also set Penalty.INFINITE_PENALTY to disable the plug-in altogether. Negative penalties are possible to promote a plug-in but a negative penalty sum will be treated as zero penalty in most cases.

xmlgraphics-commons-2.6/src/documentation/content/xdocs/index.xml0100644 0000000 0000000 00000011026 13777276623 024211 0ustar000000000 0000000
Apache™ XML Graphics Commons
Overview

Apache™ XML Graphics Commons is a library that consists of several reusable components used by Apache Batik and Apache FOP. Many of these components can easily be used separately outside the domains of SVG and XSL-FO. You will find components such as a PDF library, an RTF library, Graphics2D implementations that let you generate PDF & PostScript files, and much more.

The Apache™ XML Graphics Commons project is part of the Apache™ Software Foundation, which is a wider community of users and developers of open source projects.

In the Wiki, we have a Roadmap for Apache XML Graphics Commons. This roadmap is the place to describe new ideas for the project.

Features

Components which have been ported from Apache Batik and Apache FOP include:

Description Package Provenance
Image codecs for PNG and TIFF org.apache.xmlgraphics.image.codec Batik
Bitmap image writer abstraction with implementation for the above codecs and for the Image I/O API. org.apache.xmlgraphics.image.writer Batik
Java2D helper classes org.apache.xmlgraphics.image.rendered and org.apache.xmlgraphics.java2d Batik
Image loader framework (format detection, conversion and unified handling for bitmap and vector images). org.apache.xmlgraphics.image.loader new
Graphics2D implementation that produces PostScript and EPS org.apache.xmlgraphics.java2d.ps FOP
Helper classes for PostScript code production org.apache.xmlgraphics.ps FOP
Parser/Processor for DSC-compliant PostScript files (DSC = Document Structuring Conventions) org.apache.xmlgraphics.ps.dsc new
XMP metadata framework org.apache.xmlgraphics.xmp new
Various I/O classes, encoders and decoders for various formats org.apache.xmlgraphics.util.io Batik/FOP
News

RSS Feed: Subproject News Feed

xmlgraphics-commons-2.6/src/documentation/content/xdocs/news.xml0100644 0000000 0000000 00000005120 13777276623 024054 0ustar000000000 0000000

This release consists primarily of bug fixes, improved code practices, and improved coverage of CCITTFax Group 3 image formats. For details, please see Changes.

This release adds the option to generate smaller PostScript files, support for the AdobeStandardCyrillic encoding, RefinedImageFlavor, TexturePaint support for PSGraphics2D (PostScript tiling patterns), improvements to the XMP framework, optimization for PostScript state handling in (E)PSDocumentGraphics2D, and more. In addition it contains a number of bug fixes. For details, please see the Changes page.

We are pleased to note that many new features were contributed from outside the team of committers. Such broader interest ensures the healthy further development of the project.

This release is mostly a bugfix release for the image loading framework that has been introduced in version 1.3. For details, please see the Changes page.

The most important addition in this release is an image loading framework which supports all sorts of different image formats (bitmap and vector) and is highly extensible.

Besides that there were a larger number of smaller additions and bugfixes.

Support for Java 1.3 has been dropped. Java 1.4 or later is required now.

This release mainly adds support for CMYK and GRAY color spaces for PSGenerator. For details about other fixes, please see the Changes page.

This release adds an XMP metadata framework and brings improvements for the ImageWriter package plus some minor fixes mainly in the PostScript area.

This is the first release of Apache XML Graphics Commons. There are currently no known issues with the code.

xmlgraphics-commons-2.6/src/documentation/content/xdocs/postscript.xml0100644 0000000 0000000 00000015516 13777276623 025324 0ustar000000000 0000000
Tools for Adobe PostScript
Overview

Apache™ XML Graphics Commons contains various tools for writing and processing Adobe PostScript files. This includes:

  • A PostScript generator class which helps writing PostScript files from scratch.
  • Two Graphics2D implementations, one for plain PostScript and one for writing Encapsulated PostScript (EPS).
  • A DSC-parser/processor: Parse, post-process and change DSC-compliant PostScript files.
We don't currently include a PostScript interpreter though we would love to have one. A Java-based PostScript interpreter to keep an eye on is the one from the FOray project.
The PostScript generator

The "PSGenerator" class can help writing PostScript files. It deals with things like escaping, saving/tracking/restoring graphics state, writing DSC comments and tracking of DSC resources.

You will rarely interact with the PS generator itself, as it is probably more interesting to generate a PostScript file using Java2D which is described in the following section.

Java2D: Graphics2D implementation for generating PostScript and EPS

We provide two classes (PSDocumentGraphics2D and EPSDocumentGraphics2D) which you can use to generated complete PostScript files using normal Java2D means. The difference between the two classes is that the EPS variant creates a fully compliant Encapsulated PostScript file while the PS variant simply creates a normal DSC-compliant level 2 PostScript file. It depends on your requirement which variant you choose. The PS variant is mostly for printing purposes while the EPS variant is better suited for inclusion in other documents.

Creating an EPS file

Creating an EPS file using the Graphics2D implementation is easy. Instantiate EPSDocumentGraphics2D, set a GraphicContext and set up the output document. Here's an example:

A complete example for generating an EPS files can be found in the "examples" directory in the distribution.

DSC parser/processor

Many PostScript files use special comments to structure a document. This allows manipulation of PostScript files without interpreting them. These special comments are defined in the Document Structuring Conventions. The code in Commons is designed to work with DSC 3.0. For details on how DSC is used, please take a look at the DSC specification.

The DSC support in Commons was primarily developed to implement resource optimization features in Apache FOP's PostScript output support. Resources like images which are used repeatedly in a document should not be written to the PostScript file each time it is used. Instead it is written once at the beginning of the file as a PostScript form. The form is then called whenever the image needs painting.

But the DSC parser could potentially be used for other purposes. The most obvious is extracting a subset of pages from a DSC-compliant file. Assume you want to print only page 45 to 57 of a particular document. There's an example that demonstrates exactly this. Check out the "examples" directory in the distribution. Other potential use cases for the DSC parser are:

  • Patching PostScript files, for example, adding OMR marks for automatic packaging
  • Imposition (2-up, n-up, rotation, etc.)
  • EPS graphic extraction
  • Inspecting the page count
  • etc. etc.

The DSC parser (DSCParser) was designed as a pull parser, i.e. you fetch new events from the parser inspecting them and acting on them as they are found. If you prefer to work with a push parser, you can pass the DSCParser a DSCHandler implementation and the parser will send you all the events.

The best example to understand how to use the DSC parser is the PageExtractor class that implements the page extraction functionality mentioned above.

The DSC parser is not considered feature-complete. The basic infrastructure is there but, for example, not all DSC comments are available as concrete Java classes. If you need to extend the DSC parser for your own use cases, please send us your patches.
xmlgraphics-commons-2.6/src/documentation/content/xdocs/site.xml0100644 0000000 0000000 00000006001 13777276623 024043 0ustar000000000 0000000 " " " xmlgraphics-commons-2.6/src/documentation/content/xdocs/tabs.xml0100644 0000000 0000000 00000003434 13777276623 024037 0ustar000000000 0000000 xmlgraphics-commons-2.6/src/documentation/resources/images/apache-xml-graphics.gif0100644 0000000 0000000 00000015507 13777276623 027361 0ustar000000000 0000000 GIF89a3ދ֊ȲΉʆŸ򯬽篽ַιɹ˸Ѽ˭̴έʽ̭¶Ÿꜰџ훁̢唪~єȞ̘凨|鄜ˍzӅsrŅʅiissm`{c}]]nTsbWsn{{h{RkfoR{PPRs`suJknwR{Js{RnR{JsRs{QkRZRFFmvjcs{sRR{BBUa_{{{{R{{scRShZjYsnrm{_xys{{ssViUYsssZ^yuokZvo`XrkvRkkkZgR|Z}T.&s]yn`ap\kcccc]ZoRccVhZZZqOV1BsZZRRZZ9\}\QVRRZRRRFaXFJOGRJJJTBBIBJBBBK8?:::1:::1::1)=-11.1/()+ !!!!! ,3 E#JHŋ3jhܟYxpC (RI M$I͛86"HX4h$ϩh%B#m dP@U*etib69Ê;!>6hPhH/\ݫNݿ @(ABń*2O]#G@`E` 6r,yj.1ŇDHaJ†lL0U _=j"wX.9qviX~5!P?L0lQ? #| L2~D,S@w$rWJ)gЉzR-#{MP@6 23,DY?SG~W0ad?}%Y");"\$PK 8Tbm SO3?XsC@y)_*@AK P:΢jXߥ8^y(ʜuډd0vHKzsN"af(^zqr?6?r) 1lTC5mK«ڔf ght&F#L%Q eP?dO=zTQ ,_|?ˁ\ 1#)`:|0L';*#O6SLY֫"=ТEw4AM = ^ɼ< dϵ5E,ϢX^+s7GD/DnP htFI+@B …䖄tR<nQApm.R(QODGX]хS^;twŕ@|_PGEfH#7x*)0Pc=aF 'B n|qm/Jyty1FqGC.^D3AD '5Oϳӿ7J|Z,*QaF [@_#81 C ч>@X갆-!A ( o41%.8Sl lh2@fb0!b(F UbP(f!Ml@E&2a I0C-! U"*mtыcNwT=h<#S 3)47 |h+fbr"4% IOBД*8&` [>;NoJAr n',EJn\ƌBP w#y3hh} n0BJbDQ5L Nx `+x Bb7ͮ@@#BIm$ MG"N MMwB\$$A01꠆ʰ_#ѐS!9 x4 t }.ىNZ8{#pE, X؁;ߵA/9evvF&ҌL6Hvh$ B~;d 5@D Wΰy䀩i#X ;hAbp #XpD/2&,W}7ɹY$6P0Z1 W< R^İ6pAzyGS @3p'|Q ` ]c hAX x Zzh ApBs~%Rl'1B_P(1v\eBHv BMgC:PXԣ8ǻHЗ( mxP?XG_-Qs/# ͩ{d+^ъF̡],3L/t?%,A=+| b"Ypppv ^&#\zY #Qk*m1ldZa l@(H ƒ+փ4 wA&v! QJ)D`:&nt821 Z4 ;`PSBc ry}EMRox˜x8"Z^P[۠9l8P ^A#oUV֋yP@|ռ2 ͌ $ao>!MOA:b+KAIK?Ret#3c08^ h0hwqrXЋ6^i 6 Pp\Ћc{pc&KЁ:zq#HmVg tmz13@=0f0p3f@b|pu$+P +|%E !]N!F,poPIFTu0? `H0d6C4L  ` @ 2B|Ҕ<0/P0>{4 @ Fr$G ?t+GLt~p)Я)! H+@`p@j誈/wP0[uSM8PJs57 P p@n Ӏ fK BgFԓ 0 p` ͐ Qʠ z Mw婖TMb@H@KB0alO*3PQ4~ @ y "[s   P k K] р  5 $K#D5O` p  4HJ SM @V `ZbT`@DBp5EqKaI3tBLp@` 0 PV t ෡M @ 0 `0 İp ʬBӐ ` K,Kp +Q4G` ` PDP@лpJT A@ .$x"X)/1.o+I=>px080u P { I r(Ic5 0[G⃬LڦZؐ7,  P @DлP+B&ءF %*ﲼRyXEθA#@~P0 4 PPPĮHX Ps) GCpɊȀI 46lLO * b!0H:!cK wFRѱ]]T4l 3iR!*1"<1= )pdt [Ĭ' 0DEMʵ4HYL ˻eF  ΐซ̑+ϬƗKOp :!8`Lb PƫR 1iXɒ0w~S);, B)` 4 =`;@fpp?彭2'Q{G5fJk; pHp < p p Ґ p -T\͊a*RqwgRKjԬ!#Rm3]j͛Bp bmL H +I Qф Ż%pk Q} L'L'2 cPP+TPx - 7] >HMEPqQ]%0"V Q@('-5p ` %Pp' Npqp c]ff l((j G I@˘Es`|\>  PF C @x m@P1$ Y'6 et'0*M!18*@@ 5 @@ AA@0 (`e 0*%`AP@2 nG23@ # 01P@>04P ˯ 0C+@}@TpԪ-    V0   r `Mp֠ j` P^ d M IA`M[V8H`@+D@t,zVRRA(kaW,3-Y .GOU'FP$*" Oxc]ys* ` M @  P UNr%` 2%p  V `}Z- H pB`w.) 6  Td0P@HdP@ N@bCiQJ ?1FӘA +P 84r$1@e ZΌ<+%iXòс ŤKm aAZsRjv Z<8(:K$I.1ٲ "I2£  Ya D(i0,HBl $ .@P !̸M"fӘx@hf#=id FԦq)v F{&PCu`qK/$X J!C!bk8'-pN`Kx(PD&)E < MҞB(lM#`i6j-PIm>'a!AXȈJl'舋Jb Yf X:e.2:-D*1 2RkHI(Q@j !^iBsp&b0 w58AW`I+Q+#t4#&͵ I&Pi'5Hۇ=*i4Ӛژ$\rxMGz)|Ba pV)P!] X>4x<(!4\I3:KmM%k5Vv٤^~}s~Jbxa1Tzygaf.Em馣⦶\7礕顣j6l:vxmlgraphics-commons-2.6/src/documentation/resources/images/apache-xml-graphics.jpg0100644 0000000 0000000 00000013232 13777276623 027365 0ustar000000000 0000000 JFIF``C       C   3"8!1"AQa2q#$3BRbr0!1AQ"aq23B ?Е޽,C;Xmf㦴HR3xө}Lk3lAB$Sl 'ZNLRi6N$m'>GYGGIQe.tXIsc%'i)<2|(#~yB}fm3]KtVJW'>t_T}XMYtTX_4jPRRRFUJSi^ڵ6R]ee `B{iV}6;q ÷*ccm,pp$[ V5Z*+1OMT6lՕ _iYm* BP6 <}ĴgTauE1ّcNu;/ITHw9PIT3l*ӪiΩ5857a-h@ۀO:H}%uPJ^xD})J+,(_% jI0Ǩ]Vk}Lft| ^VڪÓ#DdIi ovRw-;tqzn[K9Jcrk06Լ[1Y9J$~qFEŘQޖ 18:N\BK3e -9#$:y]*uUfmԉ2kqm hmIUKu ~ſ&{5)0zgm2PòЕʝRRPN ίa=Р+7, a8fZ k[)HR[)δ+4P&tYPo$$T[ $G ѦuMDDuZUt ,d,je EuѯFr5GEhѣDF4DhѣDF4E\uN⮪+JW%F'g}0jR(5j [ N6 FggtӨu+eʹTHHGSKBR:WtuV~@L>k]E-$3rGTY#ccN}l`818Vhn&h *O};]nkr@* mIjSJqikją'<|WL+ԅ{Ir?X%.S9/jJTSxFRV[w^.ʕ?sJ7p$a$Zw~tKؗ 4;nȘpNV9Rt:Ӫ'O4"!OToOiAǹ)::%2]a.Q-SAJU%*d2VuZ%̴tuR4{} kd+8ıOXk&ycN~=:ʍf]'S$RDcU\ucTOOV5꬏W=Dߞ+2"A'lQ$}twXH4 _M^I+Hmh)I Yx*]_nNwjfv+jW-2e(lkqˣy>qc-4lx2*Ѩf7J'!$$UPjO)P}BγW{iZ^㏱$OnQ>#_Ke.8:Kҗ:tQ} FíπqIA !;@xZ+X4@@hϞ]PnF)‚1#ܴ!E%[|jCqOilTQFm _)*ѽXQ)#Ϋz,;wv+ѭH;uo6´nݧ*QM7 nandŪV{vo<$q+ *Vgm:i+=VzѭbșvJPZJdE+*$::ꎵ~tĸ-\6B ވujL jCHQgrTTP9|uԍLێ hJzL5Y/Gg1g#*\Ug\m [g%GrBWk&'gF'N> ,t.n{AnXBePr2ljyNVߩtЬ~XVs SnJ} ^*bWW%`Ru~\t)E8'CLp=W=񹆜)Gm:IW:{l6t5Re7%%MFP}98RI۝7ԺNZ%􉱫H1|ȑ6VT2KI 8ޘzB^Xu-]UlAv{{-%߶N6pz5Jv}2Wl2Yzm=: UiD&eQړB,=$2BW\:%EK@"ow{%~\r7TV甏H\/w(hҨZ&f*RqZine t {A(m` F]ITMF܆%l9S ,VRԣ/QmM#Acz3 ×!h¹8θլےKbdD[s?R;"MVUNL[DԕHoӲҝђ#_;`nJRN9(RdETL6jNOmM2mͻ[@UFf$7;̒| 'ao_O| u~=Iq8׬j[%I<*IZ 6mNOUni̽NuBU-(tRw-!9*@QN`PkSn,V;)Hc饩FPNnqH; vG?S"#dF7uyYYSD(ttIy@'}p:~Tj/RejI (u t)IXgYԖj55@ TL RYXm9lP)(%ZAT^*i"K|8Qϸn<ƨ'p4ٮk6no. xPQVӎ8ZmT@' sʂ4*!E)=Ep{!FT *L͐n`Q|GnWi3bΧ)cp#ր,*Th㼭h@I_GV\FSoU)!s~@ 'uj`Gק*Uǔ"m?ZjsHLqxH~@Q| 'f@26WBK$)JXN#OƗU j;Qlυ)rsȤ~t.Qf]bǝ]Q'θ\씶nART|$4 7!}-kBI $#MmW*Ē(򁕥IIRysmJzGԡsH##%SZQ[C!Yv6~ǝ4D,EcFe;h ޳Jǒp9?m4EFFy8#Ee:B('~thiIFf2u,29 F"o[VOĈ ,tHݴ qT4GOѣDAeF[OשmFt^Ѣ#F"03sF4hxmlgraphics-commons-2.6/src/documentation/resources/images/apache-xml-graphics.png0100644 0000000 0000000 00000042246 13777276623 027400 0ustar000000000 0000000 PNG  IHDR3Hf cHRMz&u0`:pQ<gAMA|QsRGBbKGD pHYs+ IDATx}]Uw{;e)d+B tDQT!"`F,OD)*H{2dz=9$ 󻿹}YZ{}Ld2' & lX,l{5n_lvs/#?EEEx<~sr?c~lz;_>n+3~v/`%ݴf2%Z`0(}*RȈHm6ܖZCdxN t:W_t3nnq'@E_no޸8<NSkYSݴZꚦ&COPﵐ? ]]زu+JKKIDM(psq_9ҟ <#lj_F%{ᇱh"L:}潔?m\~yts;nV<6 CA\:pz*nfa8ElDfr:<9spkذa&3KK"J+1eż$ YmҤIؽ{7JG? ^.dclwر_җ`Q?? _8l&/puՒ%_G8zW8J8Kx: GyFa~?+WLzs=`4!;{zׇ9ar!ðau݊(߾l "+Z>\vW)GF!-hmmRe_~֭1~x[<&,v{m05v%r QF} -MdVnZޤs?.lڦK/a Xw0S 38V K.oUW_ |}Q?FTLI6s<9ۓX=}Fݵ{?|~}5e*V_D"(p7XSiӦgU򗿌_]nb;29M`|ԧ^C۟tI7{>n& AascCDI~5ʵ|h2)(~;:::ۋW_}ׯW;ET vz+}ylǜcw߃?7iƸb/[믢"OWq aUq)+>?_"T p~gyO<+o~ $X2xy)pwˀ6?(㷿-/}袋>;~ <%O;fm9UW]'|R"zzz;1ڨ#ŌJ&bb^>-!clۺ |,A 0d|HD8nLxGi٥;RDMyȝq :hЌ41XYx?>v[wwAscfC~q ȼxbƠɎgOtf H2\O?KKK >aذaJhicp1bDw3duW&Vn UH h*ŜlՌx_ E,N4C=㝅} tdVo+VU͛7c۶mC|iNM|>&Vj i6󀧞&6<:#gΜq_D)lPH_R7ߌo o_-mYXKnZ6y:l0aJ<0Y_&OK8ؓ׷_kVo}5 ~_.<ګv 3ص?,]y8 ĵ^'g>g>|*f7#GFSjj` ;=7ՠ;X3b4=6=50&m(ʙC:; ^ &+J9Q x:t-j#l d‰򖗠[+kQ𿞣4fAc>@jױwz~^)/ksgޭ>?yOHq ٖE#i3GS AP<ML&MKLE=EE +ZX>O q$D8WuVb^7(C<`)t6OK *# aDMiR@e%.nBl]^Urt`,ɘJ&ϥ֊)f;1aA4ҁV.S=J1zBޘvfd?ōA *}w)q3<<+̣$ݱ;'/ @5BEQg+Zчt<>I?z=p7)\\8M.L &i*,McYQ6EL$l,b? ͔I0'u0-!oaA<W`~Y4=5א0D'=) 1Π tdtKLKftw0HEMlraJ0NJ a63ǝHe39pE8mxd 3HSX䌢q%壙-C= 4 cs-I\ \Y%3B0 kKc@V9.ĞBWGV0È:6oaYZ!+/P@QB0S>n>3ޅpPjՎpWi/GYXؾP1V;v;}( W–ˢՅ'V$HikwN4D1@Ma7 AbN /U ߝ-Y>}܂9~ 8#Isl2caM]-TB$v dJ&P& ƳO\365 Kh`Ej?PG)tttsu:l Szjތ1- GYV|_Toe˖\F#( @tՕ5pQCqٔ .g2"eb9)"+en DbHP)AcӪB_P1 WMݬ.MApKx 8Y6&%Ž"v!iu0FQd?$ؑVW7Cǜx D |~_v=L ]X^E]ӧ{|%0$ZZzzM:ŋA6t11ٌ2Aoq,twWU WE/(!r]hn J^_"[ >-1gqYEO:lFCq [ -yڶkkǜK+?dL9.L?,1C4,6: m:-E%1a*\ZS%۰=]*sN7?fa*E} dw˕CYFΗ@S%T4F: z3&;T j[4c?}U^0I Q!3{vJgcF!rќk?)z܏$|dFcYg> 7mB_?.&N@qq rb ?׮O/?Ջ5 g&k5-Ɗ_ ڧO>3ӸsnV:lps?#MN0 _;™ã [#Ug|@ :940"ۭ/D_YVj w EkZ.b9~u_;ڛ!b 'D\QlJe-lNѽUx+D%j(ʢ1=nhRW)t&~<`a-࿒u~گ~+&8}Śޗas?j9z" ;;1bh @BXbaxxsbyub1UY p))?Ϡ {gXn=:B _glꆈϙUr;ᾬ'tcy3)p1 dD3`OlY>=Lӂ&;6 _A[(sZ0 /Zw"jfXі"2i>b\_:!&>͌%;YÕ8!KZhrъOWqdBo&a/@{嗫sSY B( >U(imJhm#UvmۊD,nT G]CF6²ŋ0MIpQuN\HҨHɩe(c3U}XZԭyEWr Bл#so\9D$ (YU(K+fCJ ߻!]+q'%`³>w.~xӍ(z<֎ML>-+b<6t7O0͘s?IXvcW&5qщ<2O}8n2T k\*$|o~URĴ;$gr S~ӟ*w*KZfJ즯oVQ8l]|acQ611b8SXx*Gu?ϔG p;>2[o:^oэ*܎&)}[}L<9>lZvF8"=&`0]ni1f\X*loGIQކoc9c l0,lG&?@ mu>WUe Deъ޽6lA 4ju mh$齮!) ! dK b7[܃z=H9`c]O'vwSS^ƘE m\e_ %?łu+ &'ی1j${y.4TV+?pͮ굥|hpժф}WS?b}{*4KW> k,2$o+N%qe2ؘ)D~܁*}@%Q 8wkܹJCSO=# L64/6'lF6$kҟܸqs 0~OpʻٯC` ^2Bv3H²*K# Yl\&5<67dT})yn{q4sw^z`*гk;$ _ Ǎ.ƅXڰ #t“%)%emK<7Yk pV2'gEƐ>#=˟'dI 8KβIR%HZXru'_(=QB%gEpdMO|^|"f15AێF{ߠf2˶HG#Z؆w*n۝(lw!g7{(p\>>]4ЅZE~_f8^$ o/XJN|{ -+N ?2kX1ƌKK~ Yˆ'P7rڵs!"AQ!KS*)bSqj{h#É-bj۾MR(O)fJ%_vKV*qYl<5Žس#´Cn pϨ`a+}p2 .=lgfr%v*sX@Ά~W5%{@%7<%¬SO3aƵb͹#7,Ujp݃w坪йmO<8{V\)uF\{2߻ AyY C +PVQDM¼G`b]Ql۽Gո}ae?QGyD e\pC 4SB Ѧ]L|oES8lx_@1b*-h['* Z,غa=&M'z&7nH5esro^BWvyZ*0?ro9qx~Y~m^wc{+@g$_T'~w?݃?G6krAߤpHĄ 㡗Xc3V܆q ͸[zp?<$mh!B)kC!W`UW;o2 v#>?z۳nCE&'hDP]= 6:MhLasHr<,.9gʊ,&"زv'ď˔|g6mRDdA2- cAonnZ@5Nȓ7&K_.+FZO>OA4%t^TLRG1 3]Og*J{T]9DiSz Vؚ1~Lj>ٺ@M}³[aT8ԘL$qPv,[c{zx˱޵#OcO*)aB1;Mւa(W%p)7iX4׏Vj(ǯɛ6=)ꖱ }B$ NXaʚfu`IkҳG>SN{GkkXv_Z^Vny0OTOvw8-$7yK:HBP5 56,f"1hZ2`Ua_ +h2@)F6aS MaN4/GW]wݥ>|E%bZȚSdxt1=r >s:Ao*`{Mخ/*Ỷ&LÙG nO{J6@[Au _t-LEdC{WZ;߾vryHbJRTW? cd6lH FOW~!Y{N )犒!q/;7~{ l~Cp%L! !gQaœFqH<{-\rƙp9]j:͵+؆u o¸j^C&?&߫?d Q ow*/TCjLsK84022Kߤ6Teʔ9D~<c+PS ʖerʀ 4,> o/0צo@ .i&LLii<,&173qtY1Pڀb-VtCp8 & $jޅ8}.8JܰyT1.RMvalqQ<kԍ`$`Z{/ЋJ'L|4mxCB<ML*-&QWw Y*~GNQ޹ GcD0 $+fDg{ιļzE/!{TX8b12 -n`Y]/oC20k+f2}.1c[@oۃ*|9 ]$l劥VUuȦGxfq^T2[V[i)l5VنhGVU#󕼫VP+k#TX f\OTRj'E P܆`OGEhn@C@" ?y}ۗS8JEѻy)MD~1M94D6,Rtb̊fMC8j{mpT,lm(%J1(5N%7ɖr.9}>V92T'F>aw?zMgl DT"Oq.7Ikp=&֬KM\W(tp]G$BDb+82c.fa!JȀS.vK 5DQ{3Fh0e L6OVVBpg5l z~Q: ఠ\q֮؁n D\rr- 3oCZviJQ&Җ3#GN+I۸D64 '9!mj܎梑R{ j?SZڞVYaBG:/Uwf`[o X}jukF)e!1J*܍g^a#Dʶ$Q15aOgLJ̲~TEeܝ5BU0̫قD%{bln9l0<(\ى6:ʐ_(PP^]"TcUZmvB%T$+9ftY@/aB4+ZؔSP00z\{%D:`=~]VNz'e!ZԁY2o9Ң^ ޑ1)~Qd*Œ,- ¤2U*dB9Q&imI d K9ӔL׎~ YIOk`*_?{Iy0 츮0Е qXVE,vTDӀ‹s,`UveLS.ʶgOy̡d4o[IS-ʿ K+2hmHhȪmڣbpgܽ(Vֆl19~}7E:=fJ;݇YTL@|}3ړIL1Inq[ Ňp߀ks%J( sC,W5$=8qTHB+۾XC@Yl,\ލ8=@I:ϖ'U.)M2%gS`\Ek|\B1 Aa j=6Սc>'vZ\w +Z1g!==ae2m-{A#caA4 lO[Öo s8 WҊD{٪JUDAS %JWTtN/&(K&,_,L)dv09'(0.Dd >10}:ۇɺi1˜>ħMp9쎭lBf6cRq"QLmZQ$A@9܁S@]## IO|dP\| ж ƹh5.&6õLL3M!s2GV9$SYw,-GJcnj>#Eqe0q̤["F) DxL;Ͱ <ŘK <kj B3tRM~_Pb/@k%VɾG fp#s‰Ѩ#88rHqkF͗nPYK}E*8^ڗ f3en:\pV|(4a+bṱ(Zfn'VL%-UDc0fQ/EfEʌ@\y &'lk#R5=<b~_;jr4J_LaTF@* i\)co&k 5cZ %ۀɉN1|ށsNAUY++2݃r19LgKC eeWpRX̦F ̕bxd">fB!5*5 8'1 [#sR#!3ʥ4#6N1ij#K?v[ə@0icPy26oZl*L*g=6acioΠamLS/;\J$9!ݢzx: s)&V-/޾i]Ӄ Mo3}T(9Ҥ*3AW+V|VM ҵ֢*BnE=OYQ b+-L8L`W/G aۑiAq^S o ֡bɤYlvc!+"KII?JGњ.&ju(-~Q.[k[%s|(qoZi1TB@07ׄPmac^,]h613RjT-/cM:!~ :#2-wƇL(A0h GhpZAO~bbqӑ= 9 i@ fU|ew}'xPfΛ{vY7bw4G`oI1'Ȯي)}9-RYLKՓʛLRL-X (3D8gUd07B Td %0fãvl@7V7I;"-#Z+J>iCM'mƉɦw$ӳTUcroqUmF 1rZ4P덠7i ha K6@˄{E/ˤ$0cfyApKJ @o>-ܶp i4p#P kO9唃 eisIi"@'?y <T Ӧ6uc]4ccte-V6v91I̘MN$1iYP[:ž[ck([PWVlǀhx&PJ8&*0SnjBa*21r1}GGJU1VCk "s5W9E`iGrr \n +1#PǪkPcc*PvPr#f7Ҏ8R&e {Qh)^9VY{ar9bSqr4,ݽQa:ZLiG+Fݏd_o Bb4]=Ms82,^DlX&8xMo|,/ر`mGO)V-ţwe;_ ओP^րUSW6pRVOVRKsE#VR`I,iML0]z饊 zlFX4k,$J/~ }u2W_}Pi?K,aT< 3ȹs d\ j}kCؼQdU+Tq ۶oc^Ě!?wWG[?~ _?Ιox-F-Y[?y:[]GGbd-yӵ+.Ö6C8܅G;ih|@(?4{;~{_0L}O?`\U swVYVvKƌ ܂Wpl߉pf3bMDޗFpSūu<Ǵ'3EuM Q49%%s,]-ʫSZ8}>ZNd0:\2nNd&%8%+^wuM9́"+ފ9`%u"T2;r(ːM$᫩D`qQ 2\x,DO}.6.fYKaFH H zħ٧Psg7?4N:i!f/47FBGo89q'C̬k kzvc0 ~q::[1q:\[]4<8t|7ʸeqeCĖÅW^zGLPv(mO>Oa'1Պ`~ϗDž\ N_j†8.ˆV,X^L䓱HB}-X8P@`qAP,6mb{gͣjs`R 'iu e2KL8'` ( ry6>AL9<3FQhmTF0s'Ս^8 u(xccU0YXMl\'cqR:Uk>>R `A,oL D X_ vtcgk9*;TE]t_}tྻe1rߕU"ډz$z%j)$OX6}q?jڮ۶r1#.fDn?|T;Rr1"Q`7ΌKarkVjTb9P0Ω"6nDo6 &Z1Mb(ar+j-90ҺnƵFɚ0}k _E1n< +6u L5c __f+M`4l`GֈߜNe`3-7M2Z#a0F:⽥LjoL"k{4F5tW ezJ̓sdIG5E"+EAu/+oᆡ%l5/B4UG3ɒ{q,L7}d_9P1x# sbTjS&ٞ׭#>0Ǵ(T {HBV|8nFԋo̺ey^.۪J˶mi6՗8#E:3FTXxӊ7/FYa gyȉͣf::;T"p'>QEn-x㾿%²~}XtYمj1~BL>1 YX21Geђr8_5o=ѡ9%lvcV &5WHyTf{_ 8-wQ8is0$XBENc?)oLL/hnѴQcrfV Q $<$bd3d6R2IDATyT>>%@'Y]^8#-`:@%ਁ(KbKMɰnY2M4)xnjCWV~Wn&5ÕÏ>_ #Z>2c}2KVW>"._._I?J#9O.7}T?.5-í#ު3WRBI|_ n$fMʯ]p̜ISat^G-,׽\LT,(\nyF^G}c\C-K!o%:cEӶx(k[TsfT Dd쿱1vˏzȤ\Uk j0KHYZW66 3M}/3E`'㵂)UYܞ\d,2KOMu-P|')$é73oJ#LlJq"ԍFŵp1 }B d3%dSS{s'㼯n㣣#ezx tyQacQ8@k~ŶZPVzq# jXJۗU=4}fQ)oSĝ• ~ &fB? ־0 AlEL _}_幱R׆@}e=Nrƺ}IENDB`xmlgraphics-commons-2.6/src/documentation/resources/images/apache-xml-graphics.svg0100644 0000000 0000000 00000331752 13777276623 027416 0ustar000000000 0000000 The Apache XML Graphics Project <?xml version <!DOCTYPE http://xmlgraphics.apache.org/ xmlgraphics-commons-2.6/src/documentation/resources/images/feed-icon-14x14.png0100644 0000000 0000000 00000001261 13777276623 026163 0ustar000000000 0000000 PNG  IHDRH-gAMA7tEXtSoftwareAdobe ImageReadyqe<CIDATxڌMHaδ1E"!HD*(PKtPnEХ:oAAHBRQ!%B]Y; ys4I@#֒Ps ZH sYLKDzzdR`TB ~;Ub# 4b^)uk)C2̝KhJlMlhim~&@eI25 K,M mGa<]ao% ޏ/q'Qʽbv[M)`q~fBYxaqd dg)BWM7H^lP@Qzz֦`H/7JeyJ%W\If m}XX\^+`_ǹ\,űX{+17j6+NDuZ(5]t6j.<&m+ARDž) ݬN GhȮ4ytPZ*k`r4M1MDC E2X$? GbIENDB`xmlgraphics-commons-2.6/src/documentation/resources/stylesheets/changes2document.xsl0100644 0000000 0000000 00000013223 13777276623 030136 0ustar000000000 0000000
<xsl:choose> <xsl:when test="@title!=''"> <xsl:value-of select="@title"/> </xsl:when> <xsl:otherwise> <xsl:text>History of Changes</xsl:text> <xsl:value-of select="$versionNumber"/> </xsl:otherwise> </xsl:choose>
Version <xsl:value-of select="@version"/> (<xsl:value-of select="@date"/>)
<xsl:choose> <xsl:when test="//contexts/context[@id=$context]"> <xsl:value-of select="//contexts/context[@id=$context]/@title"/> </xsl:when> <xsl:otherwise> <xsl:value-of select="@context"/> </xsl:otherwise> </xsl:choose>
  • () Thanks to . Fixes .
  • ,
    xmlgraphics-commons-2.6/src/documentation/resources/stylesheets/dotdots.xsl0100644 0000000 0000000 00000005506 13777276623 026372 0ustar000000000 0000000 ../ xmlgraphics-commons-2.6/src/documentation/resources/stylesheets/news2document.xsl0100644 0000000 0000000 00000003423 13777276623 027503 0ustar000000000 0000000
    News
    <xsl:value-of select="date:day-in-month(@date)"/> <xsl:text> </xsl:text> <xsl:value-of select="date:month-abbreviation(@date)"/> <xsl:text> </xsl:text> <xsl:value-of select="date:year(@date)"/> <xsl:text>: </xsl:text> <xsl:value-of select="@title"/>
    xmlgraphics-commons-2.6/src/documentation/resources/stylesheets/news2rss.xsl0100644 0000000 0000000 00000004501 13777276623 026472 0ustar000000000 0000000 <xsl:value-of select="$project-name"/> News Subproject News for en <xsl:value-of select="date:day-in-month(@date)"/> <xsl:text> </xsl:text> <xsl:value-of select="date:month-abbreviation(@date)"/> <xsl:text> </xsl:text> <xsl:value-of select="date:year(@date)"/> <xsl:text>: </xsl:text> <xsl:value-of select="@title"/> news- /index.html#news- xmlgraphics-commons-2.6/src/documentation/resources/stylesheets/releaseNotes2document.xsl0100644 0000000 0000000 00000011036 13777276623 031157 0ustar000000000 0000000
    <xsl:choose> <xsl:when test="@title!=''"> <xsl:value-of select="@title"/> </xsl:when> <xsl:otherwise> <xsl:text>Release Notes for Apache Forrest </xsl:text><xsl:value-of select="$versionNumber"/> </xsl:otherwise> </xsl:choose>
    Version is a development release, these notes are therefore not complete, they are intended to be an indicator of the major features that are so far included in this version.
    Major Changes in Version <xsl:value-of select="@version"/> This is not a complete list of changes, a full list of changes in this release is available.
    Important Changes Code Base
    Important Changes Documentation
    Important Changes Project Administration
    Important Changes Design
    Important Changes Build
    xmlgraphics-commons-2.6/src/documentation/sitemap.xmap0100644 0000000 0000000 00000004247 13777276623 022126 0ustar000000000 0000000 xmlgraphics-commons-2.6/src/documentation/skinconf.xml0100644 0000000 0000000 00000036517 13777276623 022136 0ustar000000000 0000000 true false true true true true true false .at. false Apache™ XML Graphics Commons Common components for Apache Batik and Apache FOP http://xmlgraphics.apache.org/commons/ xmlgraphics.apache.org Apache XML Graphics is responsible for the creation and maintenance of software for managing the conversion of XML formats to graphical output, and the creation and maintenance of related software components, based on software licensed to the Foundation http://xmlgraphics.apache.org/ images/apache-xml-graphics.gif favicon.ico 2006-2012 The Apache Software Foundation. http://www.apache.org/licenses/ Apache, Apache XML Graphics Commons, and the Apache feather logo are trademarks of The Apache Software Foundation. All other marks mentioned may be trademarks or registered trademarks of their respective owners. p.quote { margin-left: 2em; padding: .5em; background-color: #f0f0f0; font-family: monospace; } 1 0.5in 0.5in 1in 0.5in false false Built with Apache Forrest http://forrest.apache.org/ images/built-with-forrest-button.png 88 31 PDF created by Apache FOP http://xmlgraphics.apache.org/fop/ images/logo.jpg 138 31 xmlgraphics-commons-2.6/src/documentation/translations/langcode.xml0100644 0000000 0000000 00000002051 13777276623 024603 0ustar000000000 0000000 English Espanol Italiano xmlgraphics-commons-2.6/src/documentation/translations/languages_en.xml0100644 0000000 0000000 00000001722 13777276623 025463 0ustar000000000 0000000 English Spanish Dutch xmlgraphics-commons-2.6/src/documentation/translations/languages_es.xml0100644 0000000 0000000 00000001724 13777276623 025472 0ustar000000000 0000000 Ingles Espanol Holandes xmlgraphics-commons-2.6/src/documentation/translations/menu.xml0100644 0000000 0000000 00000002731 13777276623 024000 0ustar000000000 0000000 About Index Changes Todo Samples Apache document Static content Linking Wiki page Ihtml page Ehtml page FAQ Simplifed Docbook XSP page xmlgraphics-commons-2.6/src/documentation/translations/menu_af.xml0100644 0000000 0000000 00000003025 13777276623 024443 0ustar000000000 0000000 Aangaande Inhoud Veranderinge Om te doen Voorbeelde Apache dokument Statise Inhoud Linking Wiki bladsy Ihtml bladsy Ehtml bladsy FAQ Vereenvoudigde Docbook XSP bladsy xmlgraphics-commons-2.6/src/documentation/translations/menu_de.xml0100644 0000000 0000000 00000003006 13777276623 024444 0ustar000000000 0000000 Über Index Änderungen Todo Beispiele Apache Dokumentationsseite Statischer Inhalt Linking Wiki Seite ihtml Seite ehtml Seite FAQ Vereinfachte Docbook XSP Seite xmlgraphics-commons-2.6/src/documentation/translations/menu_es.xml0100644 0000000 0000000 00000003104 13777276623 024462 0ustar000000000 0000000 Acerca de Indice Cambios Tareas pendientes Ejemplos Documento Apache Contenido Estático Linking Página Wiki Página ihtml Página ehtml Preguntas Frecuentes Página Simplifed Docbook Página XSP xmlgraphics-commons-2.6/src/documentation/translations/menu_it.xml0100644 0000000 0000000 00000003037 13777276623 024474 0ustar000000000 0000000 Riguardo a Indice Cambiamenti Cose da fare Esempi Apache document Contenuto Statico Linking Pagina Wiki Pagina ihtml Pagina ehtml Domande frequenti Simplifed Docbook Pagina XSP xmlgraphics-commons-2.6/src/documentation/translations/menu_no.xml0100644 0000000 0000000 00000003001 13777276623 024463 0ustar000000000 0000000 Om Indeks Endringer Oppgave liste Eksempler Apache Dokument Statisk innhold Linking Wiki side ihtml side ehtml side FAQ Simplifed Docbook XSP side xmlgraphics-commons-2.6/src/documentation/translations/menu_ru.xml0100644 0000000 0000000 00000003255 13777276623 024510 0ustar000000000 0000000 О проекте Содержание Изменения План Примеры Страница документа Apache Статическое содержание Linking Страница Wiki Страница ihtml Страница ehtml Вопросы/Ответы Docbook страница XSP страница xmlgraphics-commons-2.6/src/documentation/translations/menu_sk.xml0100644 0000000 0000000 00000003064 13777276623 024475 0ustar000000000 0000000 O programe Zoznám Zmeny Úlohy Príklady Apache Document Statický Obsah Linking Wiki stránka ihtml stránka ehtml stránka Casté Otázky Simplifed Docbook stránka XSP stránka xmlgraphics-commons-2.6/src/documentation/translations/tabs.xml0100644 0000000 0000000 00000001744 13777276623 023770 0ustar000000000 0000000 Home Samples Apache XML Projects xmlgraphics-commons-2.6/src/documentation/translations/tabs_es.xml0100644 0000000 0000000 00000001750 13777276623 024454 0ustar000000000 0000000 Inicio Ejemplos Projectos XML Apache xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/fonts/Glyphs.java0100644 0000000 0000000 00000111237 13777276623 026362 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: Glyphs.java 1804124 2017-08-04 14:13:54Z ssteiner $ */ package org.apache.xmlgraphics.fonts; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.StringTokenizer; import org.apache.commons.io.IOUtils; /** * This class provides a number of constants for glyph management. */ public final class Glyphs { private Glyphs() { } /** * Glyph name for the "notdef" glyph */ public static final String NOTDEF = ".notdef"; /** * Glyph names for Mac encoding * @deprecated That array was supposed to represent the standard Macintosh ordering * of glyphs in a TrueType font (it does NOT correspond to the MacRoman encoding). * In addition some entries are incorrect. */ @Deprecated public static final String[] MAC_GLYPH_NAMES = { /* 0x00 */ Glyphs.NOTDEF, ".null", "CR", "space", "exclam", "quotedbl", "numbersign", "dollar", "percent", "ampersand", "quotesingle", "parenleft", "parenright", "asterisk", "plus", "comma", /* 0x10 */ "hyphen", "period", "slash", "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "colon", "semicolon", "less", /* 0x20 */ "equal", "greater", "question", "at", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", /* 0x30 */ "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "bracketleft", "backslash", /* 0x40 */ "bracketright", "asciicircum", "underscore", "grave", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", /* 0x50 */ "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "braceleft", "bar", /* 0x60 */ "braceright", "asciitilde", "Adieresis", "Aring", "Ccedilla", "Eacute", "Ntilde", "Odieresis", "Udieresis", "aacute", "agrave", "acircumflex", "adieresis", "atilde", "aring", "ccedilla", /* 0x70 */ "eacute", "egrave", "ecircumflex", "edieresis", "iacute", "igrave", "icircumflex", "idieresis", "ntilde", "oacute", "ograve", "ocircumflex", "odieresis", "otilde", "uacute", "ugrave", /* 0x80 */ "ucircumflex", "udieresis", "dagger", "degree", "cent", "sterling", "section", "bullet", "paragraph", "germandbls", "registered", "copyright", "trademark", "acute", "dieresis", "notequal", /* 0x90 */ "AE", "Oslash", "infinity", "plusminus", "lessequal", "greaterequal", "yen", "mu", "partialdiff", "Sigma", "Pi", "pi", "integral", "ordfeminine", "ordmasculine", "Omega", /* 0xa0 */ "ae", "oslash", "questiondown", "exclamdown", "logicalnot", "radical", "florin", "approxequal", "Delta", "guillemotleft", "guillemotright", "ellipsis", "nbspace", "Agrave", "Atilde", "Otilde", /* 0xb0 */ "OE", "oe", "endash", "emdash", "quotedblleft", "quotedblright", "quoteleft", "quoteright", "divide", "lozenge", "ydieresis", "Ydieresis", "fraction", "currency", "guilsinglleft", "guilsinglright", /* 0xc0 */ "fi", "fl", "daggerdbl", "periodcentered", "quotesinglbase", "quotedblbase", "perthousand", "Acircumflex", "Ecircumflex", "Aacute", "Edieresis", "Egrave", "Iacute", "Icircumflex", "Idieresis", "Igrave", /* 0xd0 */ "Oacute", "Ocircumflex", "applelogo", "Ograve", "Uacute", "Ucircumflex", "Ugrave", "dotlessi", "circumflex", "tilde", "macron", "breve", "dotaccent", "ring", "cedilla", "hungarumlaut", /* 0xe0 */ "ogonek", "caron", "Lslash", "lslash", "Scaron", "scaron", "Zcaron", "zcaron", "brokenbar", "Eth", "eth", "Yacute", "yacute", "Thorn", "thorn", "minus", /* 0xf0 */ "multiply", "onesuperior", "twosuperior", "threesuperior", "onehalf", "onequarter", "threequarters", "franc", "Gbreve", "gbreve", "Idot", "Scedilla", "scedilla", "Cacute", "cacute", "Ccaron", /* 0x100 */ "ccaron", "dmacron" }; /** * Glyph names for tex8r encoding */ public static final String[] TEX8R_GLYPH_NAMES = { // 0x00 NOTDEF, "dotaccent", "fi", "fl", "fraction", "hungarumlaut", "Lslash", "lslash", "ogonek", "ring", ".notdef", "breve", "minus", ".notdef", "Zcaron", "zcaron", // 0x10 "caron", "dotlessi", "dotlessj", "ff", "ffi", "ffl", ".notdef", ".notdef", NOTDEF, NOTDEF, NOTDEF, NOTDEF, NOTDEF, NOTDEF, "grave", "quotesingle", // 0x20 "space", "exclam", "quotedbl", "numbersign", "dollar", "percent", "ampersand", "quoteright", "parenleft", "parenright", "asterisk", "plus", "comma", "hyphen", "period", "slash", // 0x30 "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "colon", "semicolon", "less", "equal", "greater", "question", // 0x40 "at", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", // 0x50 "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "bracketleft", "backslash", "bracketright", "asciicircum", "underscore", // 0x60 "quoteleft", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", // 0x70 "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "braceleft", "bar", "braceright", "asciitilde", NOTDEF, // 0x80 "Euro", NOTDEF, "quotesinglbase", "florin", "quotedblbase", "ellipsis", "dagger", "daggerdbl", "circumflex", "perthousand", "Scaron", "guilsinglleft", "OE", NOTDEF, NOTDEF, NOTDEF, // 0x90 NOTDEF, NOTDEF, NOTDEF, "quotedblleft", "quotedblright", "bullet", "endash", "emdash", "tilde", "trademark", "scaron", "guilsinglright", "oe", NOTDEF, NOTDEF, "Ydieresis", // 0xA0 NOTDEF, "exclamdown", "cent", "sterling", "currency", "yen", "brokenbar", "section", "dieresis", "copyright", "ordfeminine", "guillemotleft", "logicalnot", "hyphen", "registered", "macron", // 0xB0 "degree", "plusminus", "twosuperior", "threesuperior", "acute", "mu", "paragraph", "periodcentered", "cedilla", "onesuperior", "ordmasculine", "guillemotright", "onequarter", "onehalf", "threequarters", "questiondown", // 0xC0 "Agrave", "Aacute", "Acircumflex", "Atilde", "Adieresis", "Aring", "AE", "Ccedilla", "Egrave", "Eacute", "Ecircumflex", "Edieresis", "Igrave", "Iacute", "Icircumflex", "Idieresis", // 0xD0 "Eth", "Ntilde", "Ograve", "Oacute", "Ocircumflex", "Otilde", "Odieresis", "multiply", "Oslash", "Ugrave", "Uacute", "Ucircumflex", "Udieresis", "Yacute", "Thorn", "germandbls", // 0xE0 "agrave", "aacute", "acircumflex", "atilde", "adieresis", "aring", "ae", "ccedilla", "egrave", "eacute", "ecircumflex", "edieresis", "igrave", "iacute", "icircumflex", "idieresis", // 0xF0 "eth", "ntilde", "ograve", "oacute", "ocircumflex", "otilde", "odieresis", "divide", "oslash", "ugrave", "uacute", "ucircumflex", "udieresis", "yacute", "thorn", "ydieresis" }; /** * The characters in WinAnsiEncoding */ public static final char[] WINANSI_ENCODING = { // not used until char 32 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x20 ' ', '\u0021', '\"', '\u0023', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '\u002d', '\u002e', '/', // 0x30 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', '@', // 0x40 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', // 0x50 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '\u005b', '\\', '\u005d', '^', '_', // 0x60 '\u2018', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', // 0x70 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '\u007b', '\u007c', '\u007d', '\u007e', '\u2022', // 0x80 '\u20ac', '\u2022', '\u201a', '\u0192', '\u201e', '\u2026', '\u2020', '\u2021', '\u02c6', '\u2030', '\u0160', '\u2039', '\u0152', '\u2022', '\u017d', '\u2022', // 0x90 '\u2022', '\u2018', // quoteleft '\u2019', // quoteright '\u201c', // quotedblleft '\u201d', // quotedblright '\u2022', // bullet '\u2013', // endash '\u2014', // emdash '~', '\u2122', // trademark '\u0161', '\u203a', '\u0153', '\u2022', '\u017e', '\u0178', // 0xA0 ' ', '\u00a1', '\u00a2', '\u00a3', '\u00a4', '\u00a5', '\u00a6', '\u00a7', '\u00a8', '\u00a9', '\u00aa', '\u00ab', '\u00ac', '\u00ad', '\u00ae', '\u00af', // 0xb0 '\u00b0', '\u00b1', '\u00b2', '\u00b3', '\u00b4', '\u00b5', // This is hand-coded, the rest is assumption '\u00b6', // and *might* not be correct... '\u00b7', '\u00b8', '\u00b9', '\u00ba', '\u00bb', '\u00bc', '\u00bd', '\u00be', '\u00bf', // 0xc0 '\u00c0', '\u00c1', '\u00c2', '\u00c3', '\u00c4', '\u00c5', // Aring '\u00c6', // AE '\u00c7', '\u00c8', '\u00c9', '\u00ca', '\u00cb', '\u00cc', '\u00cd', '\u00ce', '\u00cf', // 0xd0 '\u00d0', '\u00d1', '\u00d2', '\u00d3', '\u00d4', '\u00d5', '\u00d6', '\u00d7', '\u00d8', // Oslash '\u00d9', '\u00da', '\u00db', '\u00dc', '\u00dd', '\u00de', '\u00df', // 0xe0 '\u00e0', '\u00e1', '\u00e2', '\u00e3', '\u00e4', '\u00e5', // aring '\u00e6', // ae '\u00e7', '\u00e8', '\u00e9', '\u00ea', '\u00eb', '\u00ec', '\u00ed', '\u00ee', '\u00ef', // 0xf0 '\u00f0', '\u00f1', '\u00f2', '\u00f3', '\u00f4', '\u00f5', '\u00f6', '\u00f7', '\u00f8', '\u00f9', '\u00fa', '\u00fb', '\u00fc', '\u00fd', '\u00fe', '\u00ff' }; /** * The characters in AdobeStandardCyrillicEncoding */ public static final char[] ADOBECYRILLIC_ENCODING = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ' ', //space '\u0021', //exclam '\"', //quotedbl '\u0023', //numbersign '$', //dollar '%', //percent '&', //ampersand '\'', //quotesingle '(', //parenleft ')', //parenright '*', //asterisk '+', //plus ',', //comma '\u002d', //hyphen '\u002e', //period '/', //slash '0', //zero '1', //one '2', //two '3', //three '4', //four '5', //five '6', //six '7', //seven '8', //eight '9', //nine ':', //colon ';', //semicolon '<', //less '=', //equal '>', //greater '?', //question '@', //at 'A', //A 'B', //B 'C', //C 'D', //D 'E', //E 'F', //F 'G', //G 'H', //H 'I', //I 'J', //J 'K', //K 'L', //L 'M', //M 'N', //N 'O', //O 'P', //P 'Q', //Q 'R', //R 'S', //S 'T', //T 'U', //U 'V', //V 'W', //W 'X', //X 'Y', //Y 'Z', //Z '\u005b', //bracketleft '\\', //backslash '\u005d', //bracketright '^', //asciicircum '_', //underscore '\u0060', //grave 'a', //a 'b', //b 'c', //c 'd', //d 'e', //e 'f', //f 'g', //g 'h', //h 'i', //i 'j', //j 'k', //k 'l', //l 'm', //m 'n', //n 'o', //o 'p', //p 'q', //q 'r', //r 's', //s 't', //t 'u', //u 'v', //v 'w', //w 'x', //x 'y', //y 'z', //z '\u007b', //braceleft '\u007c', //bar '\u007d', //braceright '\u007e', //asciitilde 0, '\u0402', //afii10051 '\u0403', //afii10052 '\u201a', //quotesinglebase '\u0453', //afii10100 '\u201e', //quotedblbase '\u2026', //ellipsis '\u2020', //dagger '\u2021', //daggerdbl '\u20ac', //euro '\u2030', //perthousand '\u0409', //afii10058 '\u2039', //guilsignlleft '\u040a', //afii10059 '\u040c', //afii10061 '\u040b', //afii10060 '\u040f', //afii10045 '\u0452', //afii10099 '\u2018', //quoteleft '\u2019', //quoteright '\u201c', //quotedblleft '\u201d', //quotedblright '\u2022', //bullet '\u2013', //endash '\u2014', //emdash 0, '\u2122', //trademark '\u0459', //afii10106 '\u203a', //guilsinglright '\u045a', //afii10107 '\u045c', //afii10109 '\u045b', //afii10108 '\u045f', //afii10193 '\u00a0', //nbspace '\u040e', //afii10062 '\u045e', //afii10110 '\u0408', //afii10057 '\u00a4', //currency '\u0490', //afii10050 '\u00a6', //brokenbar '\u00a7', //section '\u0401', //afii10023 '\u00a9', //copyright '\u0404', //afii10053 '\u00ab', //guillemotleft '\u00ac', //logicalnot '\u00ad', //softhyphen '\u00ae', //registered '\u0407', //afii10056 '\u00b0', //degree '\u00b1', //plusminus '\u0406', //afii10055 '\u0456', //afii10103 '\u0491', //afii10098 '\u00b5', //mu '\u00b6', //paragraph '\u00b7', //periodcentered '\u0451', //afii10071 '\u2116', //afii61352 '\u0454', //afii10101 '\u00bb', //guillemotright '\u0458', //afii10105 '\u0405', //afii10054 '\u0455', //afii10102 '\u0457', //afii10104 '\u0410', //afii10017 '\u0411', //afii10018 '\u0412', //afii10019 '\u0413', //afii10020 '\u0414', //afii10021 '\u0415', //afii10022 '\u0416', //afii10024 '\u0417', //afii10025 '\u0418', //afii10026 '\u0419', //afii10027 '\u041a', //afii10028 '\u041b', //afii10029 '\u041c', //afii10030 '\u041d', //afii10031 '\u041e', //afii10032 '\u041f', //afii10033 '\u0420', //afii10034 '\u0421', //afii10035 '\u0422', //afii10036 '\u0423', //afii10037 '\u0424', //afii10038 '\u0425', //afii10039 '\u0426', //afii10040 '\u0427', //afii10041 '\u0428', //afii10042 '\u0429', //afii10043 '\u042a', //afii10044 '\u042b', //afii10045 '\u042c', //afii10046 '\u042d', //afii10047 '\u042e', //afii10048 '\u042f', //afii10049 '\u0430', //afii10065 '\u0431', //afii10066 '\u0432', //afii10067 '\u0433', //afii10068 '\u0434', //afii10069 '\u0435', //afii10070 '\u0436', //afii10072 '\u0437', //afii10073 '\u0438', //afii10074 '\u0439', //afii10075 '\u043a', //afii10076 '\u043b', //afii10077 '\u043c', //afii10078 '\u043d', //afii10079 '\u043e', //afii10080 '\u043f', //afii10081 '\u0440', //afii10082 '\u0441', //afii10083 '\u0442', //afii10084 '\u0443', //afii10085 '\u0444', //afii10086 '\u0445', //afii10087 '\u0446', //afii10088 '\u0447', //afii10089 '\u0448', //afii10090 '\u0449', //afii10091 '\u044a', //afii10092 '\u044b', //afii10093 '\u044c', //afii10094 '\u044d', //afii10095 '\u044e', //afii10096 '\u044f', //afii10097 }; /** * List of unicode glyphs */ private static final String[] UNICODE_GLYPHS; private static final String[] DINGBATS_GLYPHS; private static final Map CHARNAME_ALTERNATIVES; private static final Map CHARNAMES_TO_UNICODE; static { Map map = new java.util.TreeMap(); UNICODE_GLYPHS = loadGlyphList("glyphlist.txt", map); DINGBATS_GLYPHS = loadGlyphList("zapfdingbats.txt", map); CHARNAMES_TO_UNICODE = Collections.unmodifiableMap(map); map = new java.util.TreeMap(); addAlternatives(map, new String[] {"Omega", "Omegagreek"}); addAlternatives(map, new String[] {"Delta", "Deltagreek"}); //fraction maps to 2044 (FRACTION SLASH) and 2215 (DIVISION SLASH) addAlternatives(map, new String[] {"fraction", "divisionslash"}); //hyphen maps to 002D (HYPHEN-MINUS) and 00AD (SOFT HYPHEN) addAlternatives(map, new String[] {"hyphen", "sfthyphen", "softhyphen", "minus"}); //macron maps to 00AF (MACRON) and 02C9 (MODIFIER LETTER MACRON) addAlternatives(map, new String[] {"macron", "overscore"}); //mu maps to 00B5 (MICRO SIGN) and 03BC (GREEK SMALL LETTER MU) addAlternatives(map, new String[] {"mu", "mu1", "mugreek"}); //periodcentered maps to 00B7 (MIDDLE DOT) and 2219 (BULLET OPERATOR) addAlternatives(map, new String[] {"periodcentered", "middot", "bulletoperator", "anoteleia"}); //space maps to 0020 (SPACE) and 00A0 (NO-BREAK SPACE) addAlternatives(map, new String[] {"space", "nonbreakingspace", "nbspace"}); //Scedilla maps to 015E (and F6C1 in private use area) //Tcommaaccent maps to 0162 (LATIN CAPITAL LETTER T WITH CEDILLA) // and 021a (LATIN CAPITAL LETTER T WITH COMMA BELOW) //scedilla maps to 015f (LATIN SMALL LETTER S WITH CEDILLA) (and F6C2 in private use area) //tcommaaccent maps to 0163 and 021b //map numbers from and to their respective "oldstyle" variant addAlternatives(map, new String[] {"zero", "zerooldstyle"}); addAlternatives(map, new String[] {"one", "oneoldstyle"}); addAlternatives(map, new String[] {"two", "twooldstyle"}); addAlternatives(map, new String[] {"three", "threeoldstyle"}); addAlternatives(map, new String[] {"four", "fouroldstyle"}); addAlternatives(map, new String[] {"five", "fiveoldstyle"}); addAlternatives(map, new String[] {"six", "sixoldstyle"}); addAlternatives(map, new String[] {"seven", "sevenoldstyle"}); addAlternatives(map, new String[] {"eight", "eightoldstyle"}); addAlternatives(map, new String[] {"nine", "nineoldstyle"}); //map currency signs from and to their respective "oldstyle" variant addAlternatives(map, new String[] {"cent", "centoldstyle"}); addAlternatives(map, new String[] {"dollar", "dollaroldstyle"}); //Cyrillic names according Adobe Techninal Note #5013 aka Adobe Standard Cyrillic Font Specification addAlternatives(map, new String[] {"Acyrillic", "afii10017"}); addAlternatives(map, new String[] {"Becyrillic", "afii10018"}); addAlternatives(map, new String[] {"Vecyrillic", "afii10019"}); addAlternatives(map, new String[] {"Gecyrillic", "afii10020"}); addAlternatives(map, new String[] {"Decyrillic", "afii10021"}); addAlternatives(map, new String[] {"Iecyrillic", "afii10022"}); addAlternatives(map, new String[] {"Iocyrillic", "afii10023"}); addAlternatives(map, new String[] {"Zhecyrillic", "afii10024"}); addAlternatives(map, new String[] {"Zecyrillic", "afii10025"}); addAlternatives(map, new String[] {"Iicyrillic", "afii10026"}); addAlternatives(map, new String[] {"Iishortcyrillic", "afii10027"}); addAlternatives(map, new String[] {"Kacyrillic", "afii10028"}); addAlternatives(map, new String[] {"Elcyrillic", "afii10029"}); addAlternatives(map, new String[] {"Emcyrillic", "afii10030"}); addAlternatives(map, new String[] {"Encyrillic", "afii10031"}); addAlternatives(map, new String[] {"Ocyrillic", "afii10032"}); addAlternatives(map, new String[] {"Pecyrillic", "afii10033"}); addAlternatives(map, new String[] {"Ercyrillic", "afii10034"}); addAlternatives(map, new String[] {"Escyrillic", "afii10035"}); addAlternatives(map, new String[] {"Tecyrillic", "afii10036"}); addAlternatives(map, new String[] {"Ucyrillic", "afii10037"}); addAlternatives(map, new String[] {"Efcyrillic", "afii10038"}); addAlternatives(map, new String[] {"Khacyrillic", "afii10039"}); addAlternatives(map, new String[] {"Tsecyrillic", "afii10040"}); addAlternatives(map, new String[] {"Checyrillic", "afii10041"}); addAlternatives(map, new String[] {"Shacyrillic", "afii10042"}); addAlternatives(map, new String[] {"Shchacyrillic", "afii10043"}); addAlternatives(map, new String[] {"Hardsigncyrillic", "afii10044"}); addAlternatives(map, new String[] {"Yericyrillic", "afii10045"}); addAlternatives(map, new String[] {"Softsigncyrillic", "afii10046"}); addAlternatives(map, new String[] {"Ereversedcyrillic", "afii10047"}); addAlternatives(map, new String[] {"IUcyrillic", "afii10048"}); addAlternatives(map, new String[] {"IAcyrillic", "afii10049"}); addAlternatives(map, new String[] {"acyrillic", "afii10065"}); addAlternatives(map, new String[] {"becyrillic", "afii10066"}); addAlternatives(map, new String[] {"vecyrillic", "afii10067"}); addAlternatives(map, new String[] {"gecyrillic", "afii10068"}); addAlternatives(map, new String[] {"decyrillic", "afii10069"}); addAlternatives(map, new String[] {"iecyrillic", "afii10070"}); addAlternatives(map, new String[] {"iocyrillic", "afii10071"}); addAlternatives(map, new String[] {"zhecyrillic", "afii10072"}); addAlternatives(map, new String[] {"zecyrillic", "afii10073"}); addAlternatives(map, new String[] {"iicyrillic", "afii10074"}); addAlternatives(map, new String[] {"iishortcyrillic", "afii10075"}); addAlternatives(map, new String[] {"kacyrillic", "afii10076"}); addAlternatives(map, new String[] {"elcyrillic", "afii10077"}); addAlternatives(map, new String[] {"emcyrillic", "afii10078"}); addAlternatives(map, new String[] {"encyrillic", "afii10079"}); addAlternatives(map, new String[] {"ocyrillic", "afii10080"}); addAlternatives(map, new String[] {"pecyrillic", "afii10081"}); addAlternatives(map, new String[] {"ercyrillic", "afii10082"}); addAlternatives(map, new String[] {"escyrillic", "afii10083"}); addAlternatives(map, new String[] {"tecyrillic", "afii10084"}); addAlternatives(map, new String[] {"ucyrillic", "afii10085"}); addAlternatives(map, new String[] {"efcyrillic", "afii10086"}); addAlternatives(map, new String[] {"khacyrillic", "afii10087"}); addAlternatives(map, new String[] {"tsecyrillic", "afii10088"}); addAlternatives(map, new String[] {"checyrillic", "afii10089"}); addAlternatives(map, new String[] {"shacyrillic", "afii10090"}); addAlternatives(map, new String[] {"shchacyrillic", "afii10091"}); addAlternatives(map, new String[] {"hardsigncyrillic", "afii10092"}); addAlternatives(map, new String[] {"yericyrillic", "afii10093"}); addAlternatives(map, new String[] {"softsigncyrillic", "afii10094"}); addAlternatives(map, new String[] {"ereversedcyrillic", "afii10095"}); addAlternatives(map, new String[] {"iucyrillic", "afii10096"}); addAlternatives(map, new String[] {"iacyrillic", "afii10097"}); addAlternatives(map, new String[] {"Gheupturncyrillic", "afii10050"}); addAlternatives(map, new String[] {"Djecyrillic", "afii10051"}); addAlternatives(map, new String[] {"Gjecyrillic", "afii10052"}); addAlternatives(map, new String[] {"Ecyrillic", "afii10053"}); addAlternatives(map, new String[] {"Dzecyrillic", "afii10054"}); addAlternatives(map, new String[] {"Icyrillic", "afii10055"}); addAlternatives(map, new String[] {"Yicyrillic", "afii10056"}); addAlternatives(map, new String[] {"Jecyrillic", "afii10057"}); addAlternatives(map, new String[] {"Ljecyrillic", "afii10058"}); addAlternatives(map, new String[] {"Njecyrillic", "afii10059"}); addAlternatives(map, new String[] {"Tshecyrillic", "afii10060"}); addAlternatives(map, new String[] {"Kjecyrillic", "afii10061"}); addAlternatives(map, new String[] {"Ushortcyrillic", "afii10062"}); addAlternatives(map, new String[] {"Dzhecyrillic", "afii10145"}); addAlternatives(map, new String[] {"Yatcyrillic", "afii10146"}); addAlternatives(map, new String[] {"Fitacyrillic", "afii10147"}); addAlternatives(map, new String[] {"Izhitsacyrillic", "afii10148"}); addAlternatives(map, new String[] {"gheupturncyrillic", "afii10098"}); addAlternatives(map, new String[] {"djecyrillic", "afii10099"}); addAlternatives(map, new String[] {"gjecyrillic", "afii10100"}); addAlternatives(map, new String[] {"ecyrillic", "afii10101"}); addAlternatives(map, new String[] {"dzecyrillic", "afii10102"}); addAlternatives(map, new String[] {"icyrillic", "afii10103"}); addAlternatives(map, new String[] {"yicyrillic", "afii10104"}); addAlternatives(map, new String[] {"jecyrillic", "afii10105"}); addAlternatives(map, new String[] {"ljecyrillic", "afii10106"}); addAlternatives(map, new String[] {"njecyrillic", "afii10107"}); addAlternatives(map, new String[] {"tshecyrillic", "afii10108"}); addAlternatives(map, new String[] {"kjecyrillic", "afii10109"}); addAlternatives(map, new String[] {"ushortcyrillic", "afii10110"}); addAlternatives(map, new String[] {"dzhecyrillic", "afii10193"}); addAlternatives(map, new String[] {"yatcyrillic", "afii10194"}); addAlternatives(map, new String[] {"fitacyrillic", "afii10195"}); addAlternatives(map, new String[] {"izhitsacyrillic", "afii10196"}); CHARNAME_ALTERNATIVES = Collections.unmodifiableMap(map); } private static void addAlternatives(Map map, String[] alternatives) { for (int i = 0, c = alternatives.length; i < c; i++) { String[] alt = new String[c - 1]; int idx = 0; for (int j = 0; j < c; j++) { if (i != j) { alt[idx] = alternatives[j]; idx++; } } map.put(alternatives[i], alt); } } private static String[] loadGlyphList(String filename, Map charNameToUnicodeMap) { List lines = new java.util.ArrayList(); InputStream in = Glyphs.class.getResourceAsStream(filename); if (in == null) { throw new RuntimeException("Cannot load " + filename + ". The Glyphs class cannot properly be initialized!"); } try { BufferedReader reader = new BufferedReader(new InputStreamReader(in, "US-ASCII")); String line; try { while ((line = reader.readLine()) != null) { if (!line.startsWith("#")) { lines.add(line); } } } finally { reader.close(); } } catch (UnsupportedEncodingException uee) { throw new RuntimeException("Incompatible JVM! US-ASCII encoding is not supported." + " The Glyphs class cannot properly be initialized!"); } catch (IOException ioe) { throw new RuntimeException("I/O error while loading " + filename + ". The Glyphs class cannot properly be initialized!"); } finally { IOUtils.closeQuietly(in); } String[] arr = new String[lines.size() * 2]; int pos = 0; StringBuffer buf = new StringBuffer(); for (Object line1 : lines) { String line = (String) line1; int semicolon = line.indexOf(';'); if (semicolon <= 0) { continue; } String charName = line.substring(0, semicolon); String rawUnicode = line.substring(semicolon + 1); buf.setLength(0); StringTokenizer tokenizer = new StringTokenizer(rawUnicode, " ", false); while (tokenizer.hasMoreTokens()) { String token = tokenizer.nextToken(); assert token.length() == 4; buf.append(hexToChar(token)); } String unicode = buf.toString(); arr[pos] = unicode; pos++; arr[pos] = charName; pos++; assert !charNameToUnicodeMap.containsKey(charName); charNameToUnicodeMap.put(charName, unicode); } return arr; } private static char hexToChar(String hex) { return (char)Integer.parseInt(hex, 16); } /** * Return the glyphname from a character, * eg, charToGlyphName('\\') returns "backslash" * * @param ch glyph to evaluate * @return the name of the glyph */ public static String charToGlyphName(char ch) { return stringToGlyph(Character.toString(ch)); } /** * Returns a String containing the Unicode sequence the given glyph name represents. * @param glyphName the glyph name * @return the Unicode sequence of the glyph (or null if the glyph name is unknown) */ public static String getUnicodeSequenceForGlyphName(String glyphName) { //Mapping: see http://www.adobe.com/devnet/opentype/archives/glyph.html //Step 1 int period = glyphName.indexOf('.'); if (period >= 0) { glyphName = glyphName.substring(0, period); } //Step 2 StringBuffer sb = new StringBuffer(); StringTokenizer tokenizer = new StringTokenizer(glyphName, "_", false); while (tokenizer.hasMoreTokens()) { String token = tokenizer.nextToken(); //Step 3 String sequence = (String)CHARNAMES_TO_UNICODE.get(token); if (sequence == null) { if (token.startsWith("uni")) { int len = token.length(); int pos = 3; while (pos + 4 <= len) { try { sb.append(hexToChar(token.substring(pos, pos + 4))); } catch (NumberFormatException nfe) { return null; } pos += 4; } } else if (token.startsWith("u")) { if (token.length() > 5) { //TODO: Unicode scalar values greater than FFFF are currently not supported return null; } if (token.length() < 5) { /* * This is not in the form of 'u1234' --probably a * non-official glyph name that isn't listed in the * unicode map. */ return null; } try { sb.append(hexToChar(token.substring(1, 5))); } catch (NumberFormatException nfe) { return null; } } else { //ignore (empty string) } } else { sb.append(sequence); } } if (sb.length() == 0) { return null; } else { return sb.toString(); } } /** * Return the glyphname from a string, * eg, glyphToString("\\") returns "backslash" * * @param name glyph to evaluate * @return the name of the glyph * TODO: javadocs for glyphToString and stringToGlyph are confused * @deprecated User getUnicodeCodePointsForGlyphName instead. This method only returns the * first Unicode code point it finds. */ @Deprecated public static String glyphToString(String name) { for (int i = 0; i < UNICODE_GLYPHS.length; i += 2) { if (UNICODE_GLYPHS[i + 1].equals(name)) { return UNICODE_GLYPHS[i]; } } return ""; } /** * Return the string representation of a glyphname, * eg stringToGlyph("backslash") returns "\\" * * @param name name of the glyph * @return the string representation (or an empty String if no match was found) */ public static String stringToGlyph(String name) { for (int i = 0; i < UNICODE_GLYPHS.length; i += 2) { if (UNICODE_GLYPHS[i].equals(name)) { return UNICODE_GLYPHS[i + 1]; } } for (int i = 0; i < DINGBATS_GLYPHS.length; i += 2) { if (DINGBATS_GLYPHS[i].equals(name)) { return DINGBATS_GLYPHS[i + 1]; } } return ""; } /** * Returns an array of char names which can serve as alternatives for the given one. * @param charName the character name to search alternatives for * @return an array of char names or null if no alternatives are available */ public static String[] getCharNameAlternativesFor(String charName) { return (String[])CHARNAME_ALTERNATIVES.get(charName); } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/fonts/package.html0100644 0000000 0000000 00000001663 13777276623 026533 0ustar000000000 0000000 org.apache.xmlgraphics.fonts Package

    Classes for handling fonts, glyphs, font encodings etc.

    xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/GraphicsConstants.java0100644 0000000 0000000 00000002530 13777276623 030475 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: GraphicsConstants.java 750418 2009-03-05 11:03:54Z vhennebert $ */ package org.apache.xmlgraphics.image; public final class GraphicsConstants { /** * The default DPI used when they cannot be determined by the graphics * environment or loaded from the image. */ public static final int DEFAULT_DPI = 72; /** * Graphics may be sampled at this resolution. */ public static final int DEFAULT_SAMPLE_DPI = 300; /** * This class should not be instantiated. */ private GraphicsConstants() { } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/GraphicsUtil.java0100644 0000000 0000000 00000132522 13777276623 027443 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: GraphicsUtil.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.image; import java.awt.Point; import java.awt.Rectangle; import java.awt.color.ColorSpace; import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import java.awt.image.ColorModel; import java.awt.image.ComponentSampleModel; import java.awt.image.DataBuffer; import java.awt.image.DataBufferByte; import java.awt.image.DataBufferInt; import java.awt.image.DataBufferShort; import java.awt.image.DataBufferUShort; import java.awt.image.DirectColorModel; import java.awt.image.Raster; import java.awt.image.RenderedImage; import java.awt.image.SampleModel; import java.awt.image.SinglePixelPackedSampleModel; import java.awt.image.WritableRaster; import org.apache.xmlgraphics.image.rendered.Any2LsRGBRed; import org.apache.xmlgraphics.image.rendered.Any2sRGBRed; import org.apache.xmlgraphics.image.rendered.BufferedImageCachableRed; import org.apache.xmlgraphics.image.rendered.CachableRed; import org.apache.xmlgraphics.image.rendered.RenderedImageCachableRed; // CSOFF: AvoidNestedBlocks // CSOFF: ConstantName // CSOFF: MethodName // CSOFF: MultipleVariableDeclarations // CSOFF: NeedBraces // CSOFF: OneStatementPerLine // CSOFF: OperatorWrap // CSOFF: StaticVariableName // CSOFF: WhitespaceAfter // CSOFF: WhitespaceAround /** * Set of utility methods for Graphics. * These generally bypass broken methods in Java2D or provide tweaked * implementations. * * @version $Id: GraphicsUtil.java 1732018 2016-02-24 04:51:06Z gadams $ * * Originally authored by Thomas DeWeese. */ public final class GraphicsUtil { private GraphicsUtil() { } public static final AffineTransform IDENTITY = new AffineTransform(); /** * Standard prebuilt Linear_sRGB color model with no alpha */ public static final ColorModel Linear_sRGB = new DirectColorModel(ColorSpace.getInstance( ColorSpace.CS_LINEAR_RGB), 24, 0x00FF0000, 0x0000FF00, 0x000000FF, 0x0, false, DataBuffer.TYPE_INT); /** * Standard prebuilt Linear_sRGB color model with premultiplied alpha. */ public static final ColorModel Linear_sRGB_Pre = new DirectColorModel(ColorSpace.getInstance( ColorSpace.CS_LINEAR_RGB), 32, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000, true, DataBuffer.TYPE_INT); /** * Standard prebuilt Linear_sRGB color model with unpremultiplied alpha. */ public static final ColorModel Linear_sRGB_Unpre = new DirectColorModel(ColorSpace.getInstance( ColorSpace.CS_LINEAR_RGB), 32, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000, false, DataBuffer.TYPE_INT); /** * Standard prebuilt sRGB color model with no alpha. */ public static final ColorModel sRGB = new DirectColorModel(ColorSpace.getInstance( ColorSpace.CS_sRGB), 24, 0x00FF0000, 0x0000FF00, 0x000000FF, 0x0, false, DataBuffer.TYPE_INT); /** * Standard prebuilt sRGB color model with premultiplied alpha. */ public static final ColorModel sRGB_Pre = new DirectColorModel(ColorSpace.getInstance( ColorSpace.CS_sRGB), 32, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000, true, DataBuffer.TYPE_INT); /** * Standard prebuilt sRGB color model with unpremultiplied alpha. */ public static final ColorModel sRGB_Unpre = new DirectColorModel(ColorSpace.getInstance( ColorSpace.CS_sRGB), 32, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000, false, DataBuffer.TYPE_INT); /** * Method that returns either Linear_sRGB_Pre or Linear_sRGB_UnPre * based on premult flag. * @param premult True if the ColorModel should have premultiplied alpha. * @return a ColorMdoel with Linear sRGB colorSpace and * the alpha channel set in accordance with * premult */ public static ColorModel makeLinear_sRGBCM(boolean premult) { return premult ? Linear_sRGB_Pre : Linear_sRGB_Unpre; } /** * Constructs a BufferedImage with a linear sRGB colorModel, and alpha. * @param width The desired width of the BufferedImage * @param height The desired height of the BufferedImage * @param premult The desired state of alpha premultiplied * @return The requested BufferedImage. */ public static BufferedImage makeLinearBufferedImage(int width, int height, boolean premult) { ColorModel cm = makeLinear_sRGBCM(premult); WritableRaster wr = cm.createCompatibleWritableRaster(width, height); return new BufferedImage(cm, wr, premult, null); } /** * This method will return a CacheableRed that has it's data in * the linear sRGB colorspace. If src is already in * linear sRGB then this method does nothing and returns src. * Otherwise it creates a transform that will convert * src's output to linear sRGB and returns that CacheableRed. * * @param src The image to convert to linear sRGB. * @return An equivilant image to src who's data is in * linear sRGB. */ public static CachableRed convertToLsRGB(CachableRed src) { ColorModel cm = src.getColorModel(); ColorSpace cs = cm.getColorSpace(); if (cs == ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB)) { return src; } return new Any2LsRGBRed(src); } /** * This method will return a CacheableRed that has it's data in * the sRGB colorspace. If src is already in * sRGB then this method does nothing and returns src. * Otherwise it creates a transform that will convert * src's output to sRGB and returns that CacheableRed. * * @param src The image to convert to sRGB. * @return An equivilant image to src who's data is in sRGB. */ public static CachableRed convertTosRGB(CachableRed src) { ColorModel cm = src.getColorModel(); ColorSpace cs = cm.getColorSpace(); if (cs == ColorSpace.getInstance(ColorSpace.CS_sRGB)) { return src; } return new Any2sRGBRed(src); } /** * Convertes any RenderedImage to a CacheableRed.

    * If ri is already a CacheableRed it casts it down and * returns it.

    * * In cases where ri is not already a CacheableRed it * wraps ri with a helper class. The wrapped * CacheableRed "Pretends" that it has no sources since it has no * way of inteligently handling the dependency/dirty region calls * if it exposed the source. * @param ri The RenderedImage to convert. * @return a CacheableRed that contains the same data as ri. */ public static CachableRed wrap(RenderedImage ri) { if (ri instanceof CachableRed) { return (CachableRed) ri; } if (ri instanceof BufferedImage) { return new BufferedImageCachableRed((BufferedImage)ri); } return new RenderedImageCachableRed(ri); } /** * An internal optimized version of copyData designed to work on * Integer packed data with a SinglePixelPackedSampleModel. Only * the region of overlap between src and dst is copied. * * Calls to this should be preflighted with is_INT_PACK_Data * on both src and dest (requireAlpha can be false). * * @param src The source of the data * @param dst The destination for the data. */ public static void copyData_INT_PACK(Raster src, WritableRaster dst) { // System.out.println("Fast copyData"); int x0 = dst.getMinX(); if (x0 < src.getMinX()) { x0 = src.getMinX(); } int y0 = dst.getMinY(); if (y0 < src.getMinY()) { y0 = src.getMinY(); } int x1 = dst.getMinX() + dst.getWidth() - 1; if (x1 > src.getMinX() + src.getWidth() - 1) { x1 = src.getMinX() + src.getWidth() - 1; } int y1 = dst.getMinY() + dst.getHeight() - 1; if (y1 > src.getMinY() + src.getHeight() - 1) { y1 = src.getMinY() + src.getHeight() - 1; } int width = x1 - x0 + 1; int height = y1 - y0 + 1; SinglePixelPackedSampleModel srcSPPSM; srcSPPSM = (SinglePixelPackedSampleModel)src.getSampleModel(); final int srcScanStride = srcSPPSM.getScanlineStride(); DataBufferInt srcDB = (DataBufferInt)src.getDataBuffer(); final int [] srcPixels = srcDB.getBankData()[0]; final int srcBase = (srcDB.getOffset() + srcSPPSM.getOffset(x0 - src.getSampleModelTranslateX(), y0 - src.getSampleModelTranslateY())); SinglePixelPackedSampleModel dstSPPSM; dstSPPSM = (SinglePixelPackedSampleModel)dst.getSampleModel(); final int dstScanStride = dstSPPSM.getScanlineStride(); DataBufferInt dstDB = (DataBufferInt)dst.getDataBuffer(); final int [] dstPixels = dstDB.getBankData()[0]; final int dstBase = (dstDB.getOffset() + dstSPPSM.getOffset(x0 - dst.getSampleModelTranslateX(), y0 - dst.getSampleModelTranslateY())); if ((srcScanStride == dstScanStride) && (srcScanStride == width)) { // System.out.println("VERY Fast copyData"); System.arraycopy(srcPixels, srcBase, dstPixels, dstBase, width * height); } else if (width > 128) { int srcSP = srcBase; int dstSP = dstBase; for (int y = 0; y < height; y++) { System.arraycopy(srcPixels, srcSP, dstPixels, dstSP, width); srcSP += srcScanStride; dstSP += dstScanStride; } } else { for (int y = 0; y < height; y++) { int srcSP = srcBase + y * srcScanStride; int dstSP = dstBase + y * dstScanStride; for (int x = 0; x < width; x++) { dstPixels[dstSP++] = srcPixels[srcSP++]; } } } } public static void copyData_FALLBACK(Raster src, WritableRaster dst) { // System.out.println("Fallback copyData"); int x0 = dst.getMinX(); if (x0 < src.getMinX()) { x0 = src.getMinX(); } int y0 = dst.getMinY(); if (y0 < src.getMinY()) { y0 = src.getMinY(); } int x1 = dst.getMinX() + dst.getWidth() - 1; if (x1 > src.getMinX() + src.getWidth() - 1) { x1 = src.getMinX() + src.getWidth() - 1; } int y1 = dst.getMinY() + dst.getHeight() - 1; if (y1 > src.getMinY() + src.getHeight() - 1) { y1 = src.getMinY() + src.getHeight() - 1; } int width = x1 - x0 + 1; int [] data = null; for (int y = y0; y <= y1; y++) { data = src.getPixels(x0, y, width, 1, data); dst.setPixels(x0, y, width, 1, data); } } /** * Copies data from one raster to another. Only the region of * overlap between src and dst is copied. Src and * Dst must have compatible SampleModels. * * @param src The source of the data * @param dst The destination for the data. */ public static void copyData(Raster src, WritableRaster dst) { if (is_INT_PACK_Data(src.getSampleModel(), false) && is_INT_PACK_Data(dst.getSampleModel(), false)) { copyData_INT_PACK(src, dst); return; } copyData_FALLBACK(src, dst); } /** * Creates a new raster that has a copy of the data in * ras. This is highly optimized for speed. There is * no provision for changing any aspect of the SampleModel. * * This method should be used when you need to change the contents * of a Raster that you do not "own" (ie the result of a * getData call). * @param ras The Raster to copy. * @return A writable copy of ras */ public static WritableRaster copyRaster(Raster ras) { return copyRaster(ras, ras.getMinX(), ras.getMinY()); } /** * Creates a new raster that has a copy of the data in * ras. This is highly optimized for speed. There is * no provision for changing any aspect of the SampleModel. * However you can specify a new location for the returned raster. * * This method should be used when you need to change the contents * of a Raster that you do not "own" (ie the result of a * getData call). * * @param ras The Raster to copy. * * @param minX The x location for the upper left corner of the * returned WritableRaster. * * @param minY The y location for the upper left corner of the * returned WritableRaster. * * @return A writable copy of ras */ public static WritableRaster copyRaster(Raster ras, int minX, int minY) { WritableRaster ret = Raster.createWritableRaster( ras.getSampleModel(), new Point(0, 0)); ret = ret.createWritableChild( ras.getMinX() - ras.getSampleModelTranslateX(), ras.getMinY() - ras.getSampleModelTranslateY(), ras.getWidth(), ras.getHeight(), minX, minY, null); // Use System.arraycopy to copy the data between the two... DataBuffer srcDB = ras.getDataBuffer(); DataBuffer retDB = ret.getDataBuffer(); if (srcDB.getDataType() != retDB.getDataType()) { throw new IllegalArgumentException( "New DataBuffer doesn't match original"); } int len = srcDB.getSize(); int banks = srcDB.getNumBanks(); int [] offsets = srcDB.getOffsets(); for (int b = 0; b < banks; b++) { switch (srcDB.getDataType()) { case DataBuffer.TYPE_BYTE: { DataBufferByte srcDBT = (DataBufferByte)srcDB; DataBufferByte retDBT = (DataBufferByte)retDB; System.arraycopy(srcDBT.getData(b), offsets[b], retDBT.getData(b), offsets[b], len); break; } case DataBuffer.TYPE_INT: { DataBufferInt srcDBT = (DataBufferInt)srcDB; DataBufferInt retDBT = (DataBufferInt)retDB; System.arraycopy(srcDBT.getData(b), offsets[b], retDBT.getData(b), offsets[b], len); break; } case DataBuffer.TYPE_SHORT: { DataBufferShort srcDBT = (DataBufferShort)srcDB; DataBufferShort retDBT = (DataBufferShort)retDB; System.arraycopy(srcDBT.getData(b), offsets[b], retDBT.getData(b), offsets[b], len); break; } case DataBuffer.TYPE_USHORT: { DataBufferUShort srcDBT = (DataBufferUShort)srcDB; DataBufferUShort retDBT = (DataBufferUShort)retDB; System.arraycopy(srcDBT.getData(b), offsets[b], retDBT.getData(b), offsets[b], len); break; } default: throw new UnsupportedOperationException("unsupported data type: " + srcDB.getDataType()); } } return ret; } /** * Coerces ras to be writable. The returned Raster continues to * reference the DataBuffer from ras, so modifications to the returned * WritableRaster will be seen in ras.

    * * This method should only be used if you need a WritableRaster due to * an interface (such as to construct a BufferedImage), but have no * intention of modifying the contents of the returned Raster. If * you have any doubt about other users of the data in ras, * use copyRaster (above). * @param ras The raster to make writable. * @return A Writable version of ras (shares DataBuffer with * ras). */ public static WritableRaster makeRasterWritable(Raster ras) { return makeRasterWritable(ras, ras.getMinX(), ras.getMinY()); } /** * Coerces ras to be writable. The returned Raster continues to * reference the DataBuffer from ras, so modifications to the returned * WritableRaster will be seen in ras.

    * * You can specify a new location for the returned WritableRaster, this * is especially useful for constructing BufferedImages which require * the Raster to be at (0,0). * * This method should only be used if you need a WritableRaster due to * an interface (such as to construct a BufferedImage), but have no * intention of modifying the contents of the returned Raster. If * you have any doubt about other users of the data in ras, * use copyRaster (above). * * @param ras The raster to make writable. * * @param minX The x location for the upper left corner of the * returned WritableRaster. * * @param minY The y location for the upper left corner of the * returned WritableRaster. * * @return A Writable version of ras with it's upper left * hand coordinate set to minX, minY (shares it's DataBuffer * with ras). */ public static WritableRaster makeRasterWritable(Raster ras, int minX, int minY) { WritableRaster ret = Raster.createWritableRaster( ras.getSampleModel(), ras.getDataBuffer(), new Point(0, 0)); ret = ret.createWritableChild( ras.getMinX() - ras.getSampleModelTranslateX(), ras.getMinY() - ras.getSampleModelTranslateY(), ras.getWidth(), ras.getHeight(), minX, minY, null); return ret; } /** * Create a new ColorModel with it's alpha premultiplied state matching * newAlphaPreMult. * @param cm The ColorModel to change the alpha premult state of. * @param newAlphaPreMult The new state of alpha premult. * @return A new colorModel that has isAlphaPremultiplied() * equal to newAlphaPreMult. */ public static ColorModel coerceColorModel(ColorModel cm, boolean newAlphaPreMult) { if (cm.isAlphaPremultiplied() == newAlphaPreMult) { return cm; } // Easiest way to build proper colormodel for new Alpha state... // Eventually this should switch on known ColorModel types and // only fall back on this hack when the CM type is unknown. WritableRaster wr = cm.createCompatibleWritableRaster(1, 1); return cm.coerceData(wr, newAlphaPreMult); } /** * Coerces data within a bufferedImage to match newAlphaPreMult, * Note that this can not change the colormodel of bi so you * * @param wr The raster to change the state of. * @param cm The colormodel currently associated with data in wr. * @param newAlphaPreMult The desired state of alpha Premult for raster. * @return A new colormodel that matches newAlphaPreMult. */ public static ColorModel coerceData(WritableRaster wr, ColorModel cm, boolean newAlphaPreMult) { // System.out.println("CoerceData: " + cm.isAlphaPremultiplied() + // " Out: " + newAlphaPreMult); if (!cm.hasAlpha()) { // Nothing to do no alpha channel return cm; } if (cm.isAlphaPremultiplied() == newAlphaPreMult) { // nothing to do alpha state matches... return cm; } // System.out.println("CoerceData: " + wr.getSampleModel()); if (newAlphaPreMult) { multiplyAlpha(wr); } else { divideAlpha(wr); } return coerceColorModel(cm, newAlphaPreMult); } public static void multiplyAlpha(WritableRaster wr) { if (is_BYTE_COMP_Data(wr.getSampleModel())) { mult_BYTE_COMP_Data(wr); } else if (is_INT_PACK_Data(wr.getSampleModel(), true)) { mult_INT_PACK_Data(wr); } else { int [] pixel = null; int bands = wr.getNumBands(); float norm = 1f / 255f; int x0; int x1; int y0; int y1; int a; int b; float alpha; x0 = wr.getMinX(); x1 = x0 + wr.getWidth(); y0 = wr.getMinY(); y1 = y0 + wr.getHeight(); for (int y = y0; y < y1; y++) { for (int x = x0; x < x1; x++) { pixel = wr.getPixel(x, y, pixel); a = pixel[bands - 1]; if ((a >= 0) && (a < 255)) { alpha = a * norm; for (b = 0; b < bands - 1; b++) { pixel[b] = (int)(pixel[b] * alpha + 0.5f); } wr.setPixel(x, y, pixel); } } } } } public static void divideAlpha(WritableRaster wr) { if (is_BYTE_COMP_Data(wr.getSampleModel())) { divide_BYTE_COMP_Data(wr); } else if (is_INT_PACK_Data(wr.getSampleModel(), true)) { divide_INT_PACK_Data(wr); } else { int x0; int x1; int y0; int y1; int a; int b; float ialpha; int bands = wr.getNumBands(); int [] pixel = null; x0 = wr.getMinX(); x1 = x0 + wr.getWidth(); y0 = wr.getMinY(); y1 = y0 + wr.getHeight(); for (int y = y0; y < y1; y++) { for (int x = x0; x < x1; x++) { pixel = wr.getPixel(x, y, pixel); a = pixel[bands - 1]; if ((a > 0) && (a < 255)) { ialpha = 255 / (float)a; for (b = 0; b < bands - 1; b++) { pixel[b] = (int)(pixel[b] * ialpha + 0.5f); } wr.setPixel(x, y, pixel); } } } } } /** * Copies data from one bufferedImage to another paying attention * to the state of AlphaPreMultiplied. * * @param src The source * @param dst The destination */ public static void copyData(BufferedImage src, BufferedImage dst) { Rectangle srcRect = new Rectangle(0, 0, src.getWidth(), src.getHeight()); copyData(src, srcRect, dst, new Point(0, 0)); } /** * Copies data from one bufferedImage to another paying attention * to the state of AlphaPreMultiplied. * * @param src The source * @param srcRect The Rectangle of source data to be copied * @param dst The destination * @param destP The Place for the upper left corner of srcRect in dst. */ public static void copyData(BufferedImage src, Rectangle srcRect, BufferedImage dst, Point destP) { /* if (srcCS != dstCS) throw new IllegalArgumentException ("Images must be in the same ColorSpace in order "+ "to copy Data between them"); */ boolean srcAlpha = src.getColorModel().hasAlpha(); boolean dstAlpha = dst.getColorModel().hasAlpha(); // System.out.println("Src has: " + srcAlpha + // " is: " + src.isAlphaPremultiplied()); // // System.out.println("Dst has: " + dstAlpha + // " is: " + dst.isAlphaPremultiplied()); if (srcAlpha == dstAlpha) { if (!srcAlpha || src.isAlphaPremultiplied() == dst.isAlphaPremultiplied()) { // They match one another so just copy everything... copyData(src.getRaster(), dst.getRaster()); return; } } // System.out.println("Using Slow CopyData"); int [] pixel = null; Raster srcR = src.getRaster(); WritableRaster dstR = dst.getRaster(); int bands = dstR.getNumBands(); int dx = destP.x - srcRect.x; int dy = destP.y - srcRect.y; int w = srcRect.width; int x0 = srcRect.x; int y0 = srcRect.y; int y1 = y0 + srcRect.height - 1; if (!srcAlpha) { // Src has no alpha dest does so set alpha to 1.0 everywhere. // System.out.println("Add Alpha"); int [] oPix = new int[bands * w]; int out = (w * bands) - 1; // The 2 skips alpha channel while (out >= 0) { // Fill alpha channel with 255's oPix[out] = 255; out -= bands; } int b; int in; for (int y = y0; y <= y1; y++) { pixel = srcR.getPixels(x0, y, w, 1, pixel); in = w * (bands - 1) - 1; out = (w * bands) - 2; // The 2 skips alpha channel on last pix switch (bands) { case 4: while (in >= 0) { oPix[out--] = pixel[in--]; oPix[out--] = pixel[in--]; oPix[out--] = pixel[in--]; out--; } break; default: while (in >= 0) { for (b = 0; b < bands - 1; b++) { oPix[out--] = pixel[in--]; } out--; } } dstR.setPixels(x0 + dx, y + dy, w, 1, oPix); } } else if (dstAlpha && dst.isAlphaPremultiplied()) { // Src and dest have Alpha but we need to multiply it for dst. // System.out.println("Mult Case"); int a; int b; int alpha; int in; int fpNorm = (1 << 24) / 255; int pt5 = 1 << 23; for (int y = y0; y <= y1; y++) { pixel = srcR.getPixels(x0, y, w, 1, pixel); in = bands * w - 1; switch (bands) { case 4: while (in >= 0) { a = pixel[in]; if (a == 255) { in -= 4; } else { in--; alpha = fpNorm * a; pixel[in] = (pixel[in] * alpha + pt5) >>> 24; in--; pixel[in] = (pixel[in] * alpha + pt5) >>> 24; in--; pixel[in] = (pixel[in] * alpha + pt5) >>> 24; in--; } } break; default: while (in >= 0) { a = pixel[in]; if (a == 255) { in -= bands; } else { in--; alpha = fpNorm * a; for (b = 0; b < bands - 1; b++) { pixel[in] = (pixel[in] * alpha + pt5) >>> 24; in--; } } } } dstR.setPixels(x0 + dx, y + dy, w, 1, pixel); } } else if (dstAlpha && !dst.isAlphaPremultiplied()) { // Src and dest have Alpha but we need to divide it out for dst. // System.out.println("Div Case"); int a; int b; int ialpha; int in; int fpNorm = 0x00FF0000; int pt5 = 1 << 15; for (int y = y0; y <= y1; y++) { pixel = srcR.getPixels(x0, y, w, 1, pixel); in = (bands * w) - 1; switch(bands) { case 4: while (in >= 0) { a = pixel[in]; if ((a <= 0) || (a >= 255)) { in -= 4; } else { in--; ialpha = fpNorm / a; pixel[in] = (pixel[in] * ialpha + pt5) >>> 16; in--; pixel[in] = (pixel[in] * ialpha + pt5) >>> 16; in--; pixel[in] = (pixel[in] * ialpha + pt5) >>> 16; in--; } } break; default: while (in >= 0) { a = pixel[in]; if ((a <= 0) || (a >= 255)) { in -= bands; } else { in--; ialpha = fpNorm / a; for (b = 0; b < bands - 1; b++) { pixel[in] = (pixel[in] * ialpha + pt5) >>> 16; in--; } } } } dstR.setPixels(x0 + dx, y + dy, w, 1, pixel); } } else if (src.isAlphaPremultiplied()) { int [] oPix = new int[bands * w]; // Src has alpha dest does not so unpremult and store... // System.out.println("Remove Alpha, Div Case"); int a; int b; int ialpha; int in; int out; int fpNorm = 0x00FF0000; int pt5 = 1 << 15; for (int y = y0; y <= y1; y++) { pixel = srcR.getPixels(x0, y, w, 1, pixel); in = (bands + 1) * w - 1; out = (bands * w) - 1; while (in >= 0) { a = pixel[in]; in--; if (a > 0) { if (a < 255) { ialpha = fpNorm / a; for (b = 0; b < bands; b++) { oPix[out--] = (pixel[in--] * ialpha + pt5) >>> 16; } } else { for (b = 0; b < bands; b++) { oPix[out--] = pixel[in--]; } } } else { in -= bands; for (b = 0; b < bands; b++) { oPix[out--] = 255; } } } dstR.setPixels(x0 + dx, y + dy, w, 1, oPix); } } else { // Src has unpremult alpha, dest does not have alpha, // just copy the color channels over. Rectangle dstRect = new Rectangle(destP.x, destP.y, srcRect.width, srcRect.height); for (int b = 0; b < bands; b++) { copyBand(srcR, srcRect, b, dstR, dstRect, b); } } } public static void copyBand(Raster src, int srcBand, WritableRaster dst, int dstBand) { Rectangle sR = src.getBounds(); Rectangle dR = dst.getBounds(); Rectangle cpR = sR.intersection(dR); copyBand(src, cpR, srcBand, dst, cpR, dstBand); } public static void copyBand(Raster src, Rectangle sR, int sBand, WritableRaster dst, Rectangle dR, int dBand) { int dy = dR.y - sR.y; int dx = dR.x - sR.x; sR = sR.intersection(src.getBounds()); dR = dR.intersection(dst.getBounds()); int width; int height; if (dR.width < sR.width) { width = dR.width; } else { width = sR.width; } if (dR.height < sR.height) { height = dR.height; } else { height = sR.height; } int x = sR.x + dx; int [] samples = null; for (int y = sR.y; y < sR.y + height; y++) { samples = src.getSamples(sR.x, y, width, 1, sBand, samples); dst.setSamples(x, y + dy, width, 1, dBand, samples); } } public static boolean is_INT_PACK_Data(SampleModel sm, boolean requireAlpha) { // Check ColorModel is of type DirectColorModel if (!(sm instanceof SinglePixelPackedSampleModel)) { return false; } // Check transfer type if (sm.getDataType() != DataBuffer.TYPE_INT) { return false; } SinglePixelPackedSampleModel sppsm; sppsm = (SinglePixelPackedSampleModel)sm; int [] masks = sppsm.getBitMasks(); if (masks.length == 3) { if (requireAlpha) { return false; } } else if (masks.length != 4) { return false; } if (masks[0] != 0x00ff0000) { return false; } if (masks[1] != 0x0000ff00) { return false; } if (masks[2] != 0x000000ff) { return false; } if ((masks.length == 4) && (masks[3] != 0xff000000)) { return false; } return true; } public static boolean is_BYTE_COMP_Data(SampleModel sm) { // Check ColorModel is of type DirectColorModel if (!(sm instanceof ComponentSampleModel)) { return false; } // Check transfer type if (sm.getDataType() != DataBuffer.TYPE_BYTE) { return false; } return true; } protected static void divide_INT_PACK_Data(WritableRaster wr) { // System.out.println("Divide Int"); SinglePixelPackedSampleModel sppsm; sppsm = (SinglePixelPackedSampleModel)wr.getSampleModel(); final int width = wr.getWidth(); final int scanStride = sppsm.getScanlineStride(); DataBufferInt db = (DataBufferInt)wr.getDataBuffer(); final int base = (db.getOffset() + sppsm.getOffset(wr.getMinX() - wr.getSampleModelTranslateX(), wr.getMinY() - wr.getSampleModelTranslateY())); // Access the pixel data array final int[] pixels = db.getBankData()[0]; for (int y = 0; y < wr.getHeight(); y++) { int sp = base + y * scanStride; final int end = sp + width; while (sp < end) { int pixel = pixels[sp]; int a = pixel >>> 24; if (a <= 0) { pixels[sp] = 0x00FFFFFF; } else if (a < 255) { int aFP = (0x00FF0000 / a); pixels[sp] = ((a << 24) | (((((pixel & 0xFF0000) >> 16) * aFP) & 0xFF0000)) | (((((pixel & 0x00FF00) >> 8) * aFP) & 0xFF0000) >> 8) | (((((pixel & 0x0000FF)) * aFP) & 0xFF0000) >> 16)); } sp++; } } } protected static void mult_INT_PACK_Data(WritableRaster wr) { // System.out.println("Multiply Int: " + wr); SinglePixelPackedSampleModel sppsm; sppsm = (SinglePixelPackedSampleModel)wr.getSampleModel(); final int width = wr.getWidth(); final int scanStride = sppsm.getScanlineStride(); DataBufferInt db = (DataBufferInt)wr.getDataBuffer(); final int base = (db.getOffset() + sppsm.getOffset(wr.getMinX() - wr.getSampleModelTranslateX(), wr.getMinY() - wr.getSampleModelTranslateY())); // Access the pixel data array final int[] pixels = db.getBankData()[0]; for (int y = 0; y < wr.getHeight(); y++) { int sp = base + y * scanStride; final int end = sp + width; while (sp < end) { int pixel = pixels[sp]; int a = pixel >>> 24; if ((a >= 0) && (a < 255)) { // this does NOT include a == 255 (0xff) ! pixels[sp] = ((a << 24) | ((((pixel & 0xFF0000) * a) >> 8) & 0xFF0000) | ((((pixel & 0x00FF00) * a) >> 8) & 0x00FF00) | ((((pixel & 0x0000FF) * a) >> 8) & 0x0000FF)); } sp++; } } } protected static void divide_BYTE_COMP_Data(WritableRaster wr) { // System.out.println("Multiply Int: " + wr); ComponentSampleModel csm; csm = (ComponentSampleModel)wr.getSampleModel(); final int width = wr.getWidth(); final int scanStride = csm.getScanlineStride(); final int pixStride = csm.getPixelStride(); final int [] bandOff = csm.getBandOffsets(); DataBufferByte db = (DataBufferByte)wr.getDataBuffer(); final int base = (db.getOffset() + csm.getOffset(wr.getMinX() - wr.getSampleModelTranslateX(), wr.getMinY() - wr.getSampleModelTranslateY())); int aOff = bandOff[bandOff.length - 1]; int bands = bandOff.length - 1; // Access the pixel data array final byte[] pixels = db.getBankData()[0]; for (int y = 0; y < wr.getHeight(); y++) { int sp = base + y * scanStride; final int end = sp + width * pixStride; while (sp < end) { int a = pixels[sp + aOff] & 0xFF; if (a == 0) { for (int b = 0; b < bands; b++) { pixels[sp + bandOff[b]] = (byte)0xFF; } } else if (a < 255) { // this does NOT include a == 255 (0xff) ! int aFP = (0x00FF0000 / a); for (int b = 0; b < bands; b++) { int i = sp + bandOff[b]; pixels[i] = (byte)(((pixels[i] & 0xFF) * aFP) >>> 16); } } sp += pixStride; } } } protected static void mult_BYTE_COMP_Data(WritableRaster wr) { // System.out.println("Multiply Int: " + wr); ComponentSampleModel csm; csm = (ComponentSampleModel)wr.getSampleModel(); final int width = wr.getWidth(); final int scanStride = csm.getScanlineStride(); final int pixStride = csm.getPixelStride(); final int [] bandOff = csm.getBandOffsets(); DataBufferByte db = (DataBufferByte)wr.getDataBuffer(); final int base = (db.getOffset() + csm.getOffset(wr.getMinX() - wr.getSampleModelTranslateX(), wr.getMinY() - wr.getSampleModelTranslateY())); int aOff = bandOff[bandOff.length - 1]; int bands = bandOff.length - 1; // Access the pixel data array final byte[] pixels = db.getBankData()[0]; for (int y = 0; y < wr.getHeight(); y++) { int sp = base + y * scanStride; final int end = sp + width * pixStride; while (sp < end) { int a = pixels[sp + aOff] & 0xFF; if (a != 0xFF) { for (int b = 0; b < bands; b++) { int i = sp + bandOff[b]; pixels[i] = (byte)(((pixels[i] & 0xFF) * a) >> 8); } } sp += pixStride; } } } /* This is skanky debugging code that might be useful in the future: if (count == 33) { String label = "sub [" + x + ", " + y + "]: "; org.ImageDisplay.showImage (label, subBI); org.ImageDisplay.printImage (label, subBI, new Rectangle(75-iR.x, 90-iR.y, 32, 32)); } // if ((count++ % 50) == 10) // org.ImageDisplay.showImage("foo: ", subBI); Graphics2D realG2D = g2d; while (realG2D instanceof sun.java2d.ProxyGraphics2D) { realG2D = ((sun.java2d.ProxyGraphics2D)realG2D).getDelegate(); } if (realG2D instanceof sun.awt.image.BufferedImageGraphics2D) { count++; if (count == 34) { RenderedImage ri; ri = ((sun.awt.image.BufferedImageGraphics2D)realG2D).bufImg; // g2d.setComposite(SVGComposite.OVER); // org.ImageDisplay.showImage("Bar: " + count, cr); org.ImageDisplay.printImage("Bar: " + count, cr, new Rectangle(75, 90, 32, 32)); org.ImageDisplay.showImage ("Foo: " + count, ri); org.ImageDisplay.printImage("Foo: " + count, ri, new Rectangle(75, 90, 32, 32)); System.out.println("BI: " + ri); System.out.println("BISM: " + ri.getSampleModel()); System.out.println("BICM: " + ri.getColorModel()); System.out.println("BICM class: " + ri.getColorModel().getClass()); System.out.println("BICS: " + ri.getColorModel().getColorSpace()); System.out.println ("sRGB CS: " + ColorSpace.getInstance(ColorSpace.CS_sRGB)); System.out.println("G2D info"); System.out.println("\tComposite: " + g2d.getComposite()); System.out.println("\tTransform" + g2d.getTransform()); java.awt.RenderingHints rh = g2d.getRenderingHints(); java.util.Set keys = rh.keySet(); java.util.Iterator iter = keys.iterator(); while (iter.hasNext()) { Object o = iter.next(); System.out.println("\t" + o.toString() + " -> " + rh.get(o).toString()); } ri = cr; System.out.println("RI: " + ri); System.out.println("RISM: " + ri.getSampleModel()); System.out.println("RICM: " + ri.getColorModel()); System.out.println("RICM class: " + ri.getColorModel().getClass()); System.out.println("RICS: " + ri.getColorModel().getColorSpace()); } } */ /** * Extracts an alpha raster from a RenderedImage. The method tries to avoid copying data * unnecessarily by checking if the RenderedImage is a BufferedImage which offers suitable * direct methods. * @param image the image * @return the alpha raster */ public static Raster getAlphaRaster(RenderedImage image) { ColorModel cm = image.getColorModel(); if (!cm.hasAlpha() || cm.getTransparency() != ColorModel.TRANSLUCENT) { throw new IllegalStateException("Image doesn't have an alpha channel"); } Raster alpha; if (image instanceof BufferedImage) { //Optimization possible with BufferedImage (No copying) alpha = ((BufferedImage)image).getAlphaRaster(); } else { WritableRaster wraster = GraphicsUtil.makeRasterWritable(image.getData()); alpha = image.getColorModel().getAlphaRaster(wraster); } return alpha; } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/codec/png/PNGChunk.java0100644 0000000 0000000 00000013602 13777276623 030320 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: PNGChunk.java 1732019 2016-02-24 05:01:10Z gadams $ */ package org.apache.xmlgraphics.image.codec.png; import java.io.DataInputStream; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; public class PNGChunk { int length; int type; byte[] data; int crc; String typeString; /** logger */ protected static final Log log = LogFactory.getLog(PNGChunk.class); /** * See http://en.wikipedia.org/wiki/Portable_Network_Graphics for a light explanation; * See http://www.libpng.org/pub/png/spec/1.2/PNG-Chunks.html for the spec. */ public enum ChunkType { IHDR, // IHDR must be the first chunk PLTE, // PLTE contains the palette IDAT, // IDAT contains the image, which may be split among multiple IDAT chunks IEND, // IEND marks the image end bKGD, // bKGD gives the default background color cHRM, // cHRM gives the chromaticity coordinates gAMA, // gAMA specifies gamma hIST, // hIST can store the histogram iCCP, // iCCP is an ICC color profile iTXt, // iTXt contains UTF-8 text pHYs, // pHYs holds the intended pixel size sBIT, // sBIT (significant bits) indicates the color-accuracy sPLT, // sPLT suggests a palette to use sRGB, // sRGB indicates that the standard sRGB color space is used sTER, // sTER stereo-image indicator chunk for stereoscopic images tEXt, // tEXt can store text that can be represented in ISO/IEC 8859-1 tIME, // tIME stores the time that the image was last changed tRNS, // tRNS contains transparency information zTXt; // zTXt contains compressed text with the same limits as tEXt } public PNGChunk(int length, int type, byte[] data, int crc) { this.length = length; this.type = type; this.data = data; this.crc = crc; this.typeString = typeIntToString(this.type); } public int getLength() { return length; } public int getType() { return type; } public String getTypeString() { return typeString; } public byte[] getData() { return data; } public byte getByte(int offset) { return data[offset]; } public int getInt1(int offset) { return data[offset] & 0xff; } public int getInt2(int offset) { return ((data[offset] & 0xff) << 8) | (data[offset + 1] & 0xff); } public int getInt4(int offset) { return ((data[offset] & 0xff) << 24) | ((data[offset + 1] & 0xff) << 16) | ((data[offset + 2] & 0xff) << 8) | (data[offset + 3] & 0xff); } public String getString4(int offset) { return "" + (char) data[offset] + (char) data[offset + 1] + (char) data[offset + 2] + (char) data[offset + 3]; } public boolean isType(String typeName) { return typeString.equals(typeName); } /** * Reads the next chunk from the input stream. * @param distream the input stream * @return the chunk */ public static PNGChunk readChunk(DataInputStream distream) { try { int length = distream.readInt(); int type = distream.readInt(); byte[] data = new byte[length]; distream.readFully(data); int crc = distream.readInt(); return new PNGChunk(length, type, data, crc); } catch (Exception e) { e.printStackTrace(); return null; } } /** * Returns the PNG chunk type, a four letter case sensitive ASCII type/name. * @param distream the input stream * @return a four letter case sensitive ASCII type/name */ public static String getChunkType(DataInputStream distream) { try { distream.mark(8); /* int length = */distream.readInt(); int type = distream.readInt(); distream.reset(); return typeIntToString(type); } catch (Exception e) { e.printStackTrace(); return null; } } private static String typeIntToString(int type) { String typeString = ""; typeString += (char) (type >> 24); typeString += (char) ((type >> 16) & 0xff); typeString += (char) ((type >> 8) & 0xff); typeString += (char) (type & 0xff); return typeString; } /** * Skips the next chunk from the input stream. * @param distream the input stream * @return true if skipping successful, false otherwise */ public static boolean skipChunk(DataInputStream distream) { try { int length = distream.readInt(); distream.readInt(); // is this really faster than reading? int skipped = distream.skipBytes(length); distream.readInt(); if (skipped != length) { log.warn("Incorrect number of bytes skipped."); return false; } return true; } catch (Exception e) { log.warn(e.getMessage()); return false; } } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/codec/png/PNGDecodeParam.java0100644 0000000 0000000 00000031424 13777276623 031416 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: PNGDecodeParam.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.image.codec.png; import org.apache.xmlgraphics.image.codec.util.ImageDecodeParam; import org.apache.xmlgraphics.image.codec.util.PropertyUtil; // CSOFF: WhitespaceAround /** * An instance of ImageDecodeParam for decoding images in * the PNG format. * * PNGDecodeParam allows several aspects of the decoding * process for PNG images to be controlled. By default, decoding produces * output images with the following properties: * *

    Images with a bit depth of 8 or less use a * DataBufferByte to hold the pixel data. 16-bit images * use a DataBufferUShort. * *

    Palette color images and non-transparent grayscale images with * bit depths of 1, 2, or 4 will have a * MultiPixelPackedSampleModel and an * IndexColorModel. For palette color images, the * ColorModel palette contains the red, green, blue, and * optionally alpha palette information. For grayscale images, the * palette is used to expand the pixel data to cover the range 0-255. * The pixels are stored packed 8, 4, or 2 to the byte. * *

    All other images are stored using a * PixelInterleavedSampleModel with each sample of a pixel * occupying its own byte or short within * the DataBuffer. A ComponentColorModel is * used which simply extracts the red, green, blue, gray, and/or alpha * information from separate DataBuffer entries. * *

    Five aspects of this process may be altered by means of methods * in this class. * *

    setSuppressAlpha() prevents an alpha channel * from appearing in the output. * *

    setExpandPalette() turns palette-color images into * 3-or 4-channel full-color images. * *

    setOutput8BitGray() causes 1, 2, or 4 bit * grayscale images to be output in 8-bit form, using a * ComponentSampleModel and * ComponentColorModel. * *

    setDecodingExponent() causes the output image to be * gamma-corrected using a supplied output gamma value. * *

    setExpandGrayAlpha() causes 2-channel gray/alpha * (GA) images to be output as full-color (GGGA) images, which may * simplify further processing and display. * *

    This class is not a committed part of the JAI API. It may * be removed or changed in future releases of JAI. */ public class PNGDecodeParam implements ImageDecodeParam { private static final long serialVersionUID = 3957265194926624623L; /** * Constructs a default instance of PNGDecodeParam. */ public PNGDecodeParam() { } private boolean suppressAlpha; /** * Returns true if alpha (transparency) will * be prevented from appearing in the output. */ public boolean getSuppressAlpha() { return suppressAlpha; } /** * If set, no alpha (transparency) channel will appear in the * output image. * *

    The default is to allow transparency to appear in the * output image. */ public void setSuppressAlpha(boolean suppressAlpha) { this.suppressAlpha = suppressAlpha; } private boolean expandPalette; /** * Returns true if palette-color images will be expanded to * produce full-color output. */ public boolean getExpandPalette() { return expandPalette; } /** * If set, palette color images (PNG color type 3) will * be decoded into full-color (RGB) output images. The output * image may have 3 or 4 channels, depending on the presence of * transparency information. * *

    The default is to output palette images using a single * channel. The palette information is used to construct the * output image's ColorModel. */ public void setExpandPalette(boolean expandPalette) { this.expandPalette = expandPalette; } private boolean output8BitGray; /** * Returns the current value of the 8-bit gray output parameter. */ public boolean getOutput8BitGray() { return output8BitGray; } /** * If set, grayscale images with a bit depth less than 8 * (1, 2, or 4) will be output in 8 bit form. The output values * will occupy the full 8-bit range. For example, gray values * 0, 1, 2, and 3 of a 2-bit image will be output as * 0, 85, 170, and 255. * *

    The decoding of non-grayscale images and grayscale images * with a bit depth of 8 or 16 are unaffected by this setting. * *

    The default is not to perform expansion. Grayscale images * with a depth of 1, 2, or 4 bits will be represented using * a MultiPixelPackedSampleModel and an * IndexColorModel. */ public void setOutput8BitGray(boolean output8BitGray) { this.output8BitGray = output8BitGray; } private boolean performGammaCorrection = true; /** * Returns true if gamma correction is to be performed * on the image data. The default is true. * *

    If gamma correction is to be performed, the * getUserExponent() and * getDisplayExponent() methods are used in addition to * the gamma value stored within the file (or the default value of * 1/2.2 used if no value is found) to produce a single exponent * using the formula: *

         * decoding_exponent = user_exponent/(gamma_from_file * display_exponent)
         * 
    */ public boolean getPerformGammaCorrection() { return performGammaCorrection; } /** * Turns gamma corection of the image data on or off. */ public void setPerformGammaCorrection(boolean performGammaCorrection) { this.performGammaCorrection = performGammaCorrection; } private float userExponent = 1.0F; /** * Returns the current value of the user exponent parameter. * By default, the user exponent is equal to 1.0F. */ public float getUserExponent() { return userExponent; } /** * Sets the user exponent to a given value. The exponent * must be positive. If not, an * IllegalArgumentException will be thrown. * *

    The output image pixels will be placed through a transformation * of the form: * *

         * sample = integer_sample / (2^bitdepth - 1.0)
         * decoding_exponent = user_exponent/(gamma_from_file * display_exponent)
         * output = sample ^ decoding_exponent
         * 
    * * where gamma_from_file is the gamma of the file * data, as determined by the gAMA, sRGB, * and/or iCCP chunks, and display_exponent * is the exponent of the intrinsic transfer curve of the display, * generally 2.2. * *

    Input files which do not specify any gamma are assumed to * have a gamma of 1/2.2; such images may be displayed * on a CRT with an exponent of 2.2 using the default user * exponent of 1.0. * *

    The user exponent may be used in order to change the * effective gamma of a file. If a file has a stored gamma of * X, but the decoder believes that the true file gamma is Y, * setting a user exponent of Y/X will produce the same result * as changing the file gamma. * *

    This parameter affects the decoding of all image types. * * @throws IllegalArgumentException if userExponent is * negative. */ public void setUserExponent(float userExponent) { if (userExponent <= 0.0F) { throw new IllegalArgumentException(PropertyUtil.getString("PNGDecodeParam0")); } this.userExponent = userExponent; } private float displayExponent = 2.2F; /** * Returns the current value of the display exponent parameter. * By default, the display exponent is equal to 2.2F. */ public float getDisplayExponent() { return displayExponent; } /** * Sets the display exponent to a given value. The exponent * must be positive. If not, an * IllegalArgumentException will be thrown. * *

    The output image pixels will be placed through a transformation * of the form: * *

         * sample = integer_sample / (2^bitdepth - 1.0)
         * decoding_exponent = user_exponent/(gamma_from_file * display_exponent)
         * output = sample ^ decoding_exponent
         * 
    * * where gamma_from_file is the gamma of the file * data, as determined by the gAMA, sRGB, * and/or iCCP chunks, and user_exponent * is an additional user-supplied parameter. * *

    Input files which do not specify any gamma are assumed to * have a gamma of 1/2.2; such images should be * decoding using the default display exponent of 2.2. * *

    If an image is to be processed further before being displayed, * it may be preferable to set the display exponent to 1.0 in order * to produce a linear output image. * *

    This parameter affects the decoding of all image types. * * @throws IllegalArgumentException if userExponent is * negative. */ public void setDisplayExponent(float displayExponent) { if (displayExponent <= 0.0F) { throw new IllegalArgumentException(PropertyUtil.getString("PNGDecodeParam1")); } this.displayExponent = displayExponent; } private boolean expandGrayAlpha; /** * Returns the current setting of the gray/alpha expansion. */ public boolean getExpandGrayAlpha() { return expandGrayAlpha; } /** * If set, images containing one channel of gray and one channel of * alpha (GA) will be output in a 4-channel format (GGGA). This * produces output that may be simpler to process and display. * *

    This setting affects both images of color type 4 (explicit * alpha) and images of color type 0 (grayscale) that contain * transparency information. * *

    By default, no expansion is performed. */ public void setExpandGrayAlpha(boolean expandGrayAlpha) { this.expandGrayAlpha = expandGrayAlpha; } private boolean generateEncodeParam; private PNGEncodeParam encodeParam; /** * Returns true if an instance of * PNGEncodeParam will be available after an image * has been decoded via the getEncodeParam method. */ public boolean getGenerateEncodeParam() { return generateEncodeParam; } /** * If set, an instance of PNGEncodeParam will be * available after an image has been decoded via the * getEncodeParam method that encapsulates information * about the contents of the PNG file. If not set, this information * will not be recorded and getEncodeParam() will * return null. */ public void setGenerateEncodeParam(boolean generateEncodeParam) { this.generateEncodeParam = generateEncodeParam; } /** * If getGenerateEncodeParam() is true, * this method may be called after decoding has completed, and * will return an instance of PNGEncodeParam containing * information about the contents of the PNG file just decoded. */ public PNGEncodeParam getEncodeParam() { return encodeParam; } /** * Sets the current encoder param instance. This method is * intended to be called by the PNG decoder and will overwrite the * current instance returned by getEncodeParam. */ public void setEncodeParam(PNGEncodeParam encodeParam) { this.encodeParam = encodeParam; } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/codec/png/PNGEncodeParam.java0100644 0000000 0000000 00000137513 13777276623 031436 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: PNGEncodeParam.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.image.codec.png; import java.awt.image.ColorModel; import java.awt.image.IndexColorModel; import java.awt.image.RenderedImage; import java.awt.image.SampleModel; import java.util.ArrayList; import java.util.Date; import java.util.List; import org.apache.xmlgraphics.image.codec.util.ImageEncodeParam; import org.apache.xmlgraphics.image.codec.util.PropertyUtil; // CSOFF: MemberName // CSOFF: MultipleVariableDeclarations // CSOFF: NeedBraces // CSOFF: OperatorWrap // CSOFF: ParameterName // CSOFF: WhitespaceAround /** * An instance of ImageEncodeParam for encoding images in * the PNG format. * *

    This class is not a committed part of the JAI API. It may * be removed or changed in future releases of JAI. */ public abstract class PNGEncodeParam implements ImageEncodeParam { private static final long serialVersionUID = -7851509538552141263L; /** Constant for use with the sRGB chunk. */ public static final int INTENT_PERCEPTUAL = 0; /** Constant for use with the sRGB chunk. */ public static final int INTENT_RELATIVE = 1; /** Constant for use with the sRGB chunk. */ public static final int INTENT_SATURATION = 2; /** Constant for use with the sRGB chunk. */ public static final int INTENT_ABSOLUTE = 3; /** Constant for use in filtering. */ public static final int PNG_FILTER_NONE = 0; /** Constant for use in filtering. */ public static final int PNG_FILTER_SUB = 1; /** Constant for use in filtering. */ public static final int PNG_FILTER_UP = 2; /** Constant for use in filtering. */ public static final int PNG_FILTER_AVERAGE = 3; /** Constant for use in filtering. */ public static final int PNG_FILTER_PAETH = 4; /** * Returns an instance of PNGEncodeParam.Palette, * PNGEncodeParam.Gray, or * PNGEncodeParam.RGB appropriate for encoding * the given image. * *

    If the image has an IndexColorModel, an * instance of PNGEncodeParam.Palette is returned. * Otherwise, if the image has 1 or 2 bands an instance of * PNGEncodeParam.Gray is returned. In all other * cases an instance of PNGEncodeParam.RGB is * returned. * *

    Note that this method does not provide any guarantee that * the given image will be successfully encoded by the PNG * encoder, as it only performs a very superficial analysis of * the image structure. */ public static PNGEncodeParam getDefaultEncodeParam(RenderedImage im) { ColorModel colorModel = im.getColorModel(); if (colorModel instanceof IndexColorModel) { return new PNGEncodeParam.Palette(); } SampleModel sampleModel = im.getSampleModel(); int numBands = sampleModel.getNumBands(); if (numBands == 1 || numBands == 2) { return new PNGEncodeParam.Gray(); } else { return new PNGEncodeParam.RGB(); } } public static class Palette extends PNGEncodeParam { private static final long serialVersionUID = -5181545170427733891L; /** Constructs an instance of PNGEncodeParam.Palette. */ public Palette() { } // bKGD chunk private boolean backgroundSet; /** * Suppresses the 'bKGD' chunk from being output. */ public void unsetBackground() { backgroundSet = false; } /** * Returns true if a 'bKGD' chunk will be output. */ public boolean isBackgroundSet() { return backgroundSet; } /** * Sets the desired bit depth for a palette image. The bit * depth must be one of 1, 2, 4, or 8, or else an * IllegalArgumentException will be thrown. */ public void setBitDepth(int bitDepth) { if (bitDepth != 1 && bitDepth != 2 && bitDepth != 4 && bitDepth != 8) { throw new IllegalArgumentException(PropertyUtil.getString("PNGEncodeParam2")); } this.bitDepth = bitDepth; bitDepthSet = true; } // PLTE chunk private int[] palette; private boolean paletteSet; /** * Sets the RGB palette of the image to be encoded. * The rgb parameter contains alternating * R, G, B values for each color index used in the image. * The number of elements must be a multiple of 3 between * 3 and 3*256. * *

    The 'PLTE' chunk will encode this information. * * @param rgb An array of ints. */ public void setPalette(int[] rgb) { if (rgb.length < 1 * 3 || rgb.length > 256 * 3) { throw new IllegalArgumentException(PropertyUtil.getString("PNGEncodeParam0")); } if ((rgb.length % 3) != 0) { throw new IllegalArgumentException(PropertyUtil.getString("PNGEncodeParam1")); } palette = (int[])(rgb.clone()); paletteSet = true; } /** * Returns the current RGB palette. * *

    If the palette has not previously been set, or has been * unset, an IllegalStateException will be thrown. * * @throws IllegalStateException if the palette is not set. * * @return An array of ints. */ public int[] getPalette() { if (!paletteSet) { throw new IllegalStateException(PropertyUtil.getString("PNGEncodeParam3")); } return (int[])(palette.clone()); } /** * Suppresses the 'PLTE' chunk from being output. */ public void unsetPalette() { palette = null; paletteSet = false; } /** * Returns true if a 'PLTE' chunk will be output. */ public boolean isPaletteSet() { return paletteSet; } // bKGD chunk private int backgroundPaletteIndex; /** * Sets the palette index of the suggested background color. * *

    The 'bKGD' chunk will encode this information. */ public void setBackgroundPaletteIndex(int index) { backgroundPaletteIndex = index; backgroundSet = true; } /** * Returns the palette index of the suggested background color. * *

    If the background palette index has not previously been * set, or has been unset, an * IllegalStateException will be thrown. * * @throws IllegalStateException if the palette index is not set. */ public int getBackgroundPaletteIndex() { if (!backgroundSet) { throw new IllegalStateException(PropertyUtil.getString("PNGEncodeParam4")); } return backgroundPaletteIndex; } // tRNS chunk private int[] transparency; /** * Sets the alpha values associated with each palette entry. * The alpha parameter should have as many entries * as there are RGB triples in the palette. * *

    The 'tRNS' chunk will encode this information. */ public void setPaletteTransparency(byte[] alpha) { transparency = new int[alpha.length]; for (int i = 0; i < alpha.length; i++) { transparency[i] = alpha[i] & 0xff; } transparencySet = true; } /** * Returns the alpha values associated with each palette entry. * *

    If the palette transparency has not previously been * set, or has been unset, an * IllegalStateException will be thrown. * * @throws IllegalStateException if the palette transparency is * not set. */ public byte[] getPaletteTransparency() { if (!transparencySet) { throw new IllegalStateException(PropertyUtil.getString("PNGEncodeParam5")); } byte[] alpha = new byte[transparency.length]; for (int i = 0; i < alpha.length; i++) { alpha[i] = (byte)transparency[i]; } return alpha; } } public static class Gray extends PNGEncodeParam { private static final long serialVersionUID = -2055439792025795274L; /** Constructs an instance of PNGEncodeParam.Gray. */ public Gray() { } // bKGD chunk private boolean backgroundSet; /** * Suppresses the 'bKGD' chunk from being output. */ public void unsetBackground() { backgroundSet = false; } /** * Returns true if a 'bKGD' chunk will be output. */ public boolean isBackgroundSet() { return backgroundSet; } /** * Sets the desired bit depth for a grayscale image. The bit * depth must be one of 1, 2, 4, 8, or 16. * *

    When encoding a source image of a greater bit depth, * pixel values will be clamped to the smaller range after * shifting by the value given by getBitShift(). * When encoding a source image of a smaller bit depth, pixel * values will be shifted and left-filled with zeroes. */ public void setBitDepth(int bitDepth) { if (bitDepth != 1 && bitDepth != 2 && bitDepth != 4 && bitDepth != 8 && bitDepth != 16) { throw new IllegalArgumentException(PropertyUtil.getString("PNGEncodeParam2")); } this.bitDepth = bitDepth; bitDepthSet = true; } // bKGD chunk private int backgroundPaletteGray; /** * Sets the suggested gray level of the background. * *

    The 'bKGD' chunk will encode this information. */ public void setBackgroundGray(int gray) { backgroundPaletteGray = gray; backgroundSet = true; } /** * Returns the suggested gray level of the background. * *

    If the background gray level has not previously been * set, or has been unset, an * IllegalStateException will be thrown. * * @throws IllegalStateException if the background gray level * is not set. */ public int getBackgroundGray() { if (!backgroundSet) { throw new IllegalStateException(PropertyUtil.getString("PNGEncodeParam6")); } return backgroundPaletteGray; } // tRNS chunk private int[] transparency; /** * Sets the gray value to be used to denote transparency. * *

    Setting this attribute will cause the alpha channel * of the input image to be ignored. * *

    The 'tRNS' chunk will encode this information. */ public void setTransparentGray(int transparentGray) { transparency = new int[1]; transparency[0] = transparentGray; transparencySet = true; } /** * Returns the gray value to be used to denote transparency. * *

    If the transparent gray value has not previously been * set, or has been unset, an * IllegalStateException will be thrown. * * @throws IllegalStateException if the transparent gray value * is not set. */ public int getTransparentGray() { if (!transparencySet) { throw new IllegalStateException(PropertyUtil.getString("PNGEncodeParam7")); } int gray = transparency[0]; return gray; } private int bitShift; private boolean bitShiftSet; /** * Sets the desired bit shift for a grayscale image. * Pixels in the source image will be shifted right by * the given amount prior to being clamped to the maximum * value given by the encoded image's bit depth. */ public void setBitShift(int bitShift) { if (bitShift < 0) { throw new IllegalArgumentException(PropertyUtil.getString("PNGEncodeParam25")); } this.bitShift = bitShift; bitShiftSet = true; } /** * Returns the desired bit shift for a grayscale image. * *

    If the bit shift has not previously been set, or has been * unset, an IllegalStateException will be thrown. * * @throws IllegalStateException if the bit shift is not set. */ public int getBitShift() { if (!bitShiftSet) { throw new IllegalStateException(PropertyUtil.getString("PNGEncodeParam8")); } return bitShift; } /** * Suppresses the setting of the bit shift of a grayscale image. * Pixels in the source image will not be shifted prior to encoding. */ public void unsetBitShift() { bitShiftSet = false; } /** * Returns true if the bit shift has been set. */ public boolean isBitShiftSet() { return bitShiftSet; } /** * Returns true if the bit depth has been set. */ public boolean isBitDepthSet() { return bitDepthSet; } } public static class RGB extends PNGEncodeParam { private static final long serialVersionUID = -8918762026006670891L; /** Constructs an instance of PNGEncodeParam.RGB. */ public RGB() { } // bKGD chunk private boolean backgroundSet; /** * Suppresses the 'bKGD' chunk from being output. */ public void unsetBackground() { backgroundSet = false; } /** * Returns true if a 'bKGD' chunk will be output. */ public boolean isBackgroundSet() { return backgroundSet; } /** * Sets the desired bit depth for an RGB image. The bit * depth must be 8 or 16. */ public void setBitDepth(int bitDepth) { if (bitDepth != 8 && bitDepth != 16) { throw new IllegalArgumentException(PropertyUtil.getString("PNGEncodeParam26")); } this.bitDepth = bitDepth; bitDepthSet = true; } // bKGD chunk private int[] backgroundRGB; /** * Sets the RGB value of the suggested background color. * The rgb parameter should have 3 entries. * *

    The 'bKGD' chunk will encode this information. */ public void setBackgroundRGB(int[] rgb) { if (rgb.length != 3) { throw new IllegalArgumentException(PropertyUtil.getString("PNGEncodeParam27")); } backgroundRGB = rgb; backgroundSet = true; } /** * Returns the RGB value of the suggested background color. * *

    If the background color has not previously been set, or has been * unset, an IllegalStateException will be thrown. * * @throws IllegalStateException if the background color is not set. */ public int[] getBackgroundRGB() { if (!backgroundSet) { throw new IllegalStateException(PropertyUtil.getString("PNGEncodeParam9")); } return backgroundRGB; } // tRNS chunk private int[] transparency; /** * Sets the RGB value to be used to denote transparency. * *

    Setting this attribute will cause the alpha channel * of the input image to be ignored. * *

    The 'tRNS' chunk will encode this information. */ public void setTransparentRGB(int[] transparentRGB) { transparency = (int[])(transparentRGB.clone()); transparencySet = true; } /** * Returns the RGB value to be used to denote transparency. * *

    If the transparent color has not previously been set, * or has been unset, an IllegalStateException * will be thrown. * * @throws IllegalStateException if the transparent color is not set. */ public int[] getTransparentRGB() { if (!transparencySet) { throw new IllegalStateException(PropertyUtil.getString("PNGEncodeParam10")); } return (int[])(transparency.clone()); } } protected int bitDepth; protected boolean bitDepthSet; /** * Sets the desired bit depth of an image. */ public abstract void setBitDepth(int bitDepth); /** * Returns the desired bit depth for a grayscale image. * *

    If the bit depth has not previously been set, or has been * unset, an IllegalStateException will be thrown. * * @throws IllegalStateException if the bit depth is not set. */ public int getBitDepth() { if (!bitDepthSet) { throw new IllegalStateException(PropertyUtil.getString("PNGEncodeParam11")); } return bitDepth; } /** * Suppresses the setting of the bit depth of a grayscale image. * The depth of the encoded image will be inferred from the source * image bit depth, rounded up to the next power of 2 between 1 * and 16. */ public void unsetBitDepth() { bitDepthSet = false; } private boolean useInterlacing; /** * Turns Adam7 interlacing on or off. */ public void setInterlacing(boolean useInterlacing) { this.useInterlacing = useInterlacing; } /** * Returns true if Adam7 interlacing will be used. */ public boolean getInterlacing() { return useInterlacing; } // bKGD chunk - delegate to subclasses // In JAI 1.0, 'backgroundSet' was private. The JDK 1.2 compiler // was lenient and incorrectly allowed this variable to be // accessed from the subclasses. The JDK 1.3 compiler correctly // flags this as a use of a non-static variable in a static // context. Changing 'backgroundSet' to protected would have // solved the problem, but would have introduced a visible API // change. Thus we are forced to adopt the solution of placing a // separate private variable in each subclass and providing // separate implementations of 'unsetBackground' and // 'isBackgroundSet' in each concrete subclass. /** * Suppresses the 'bKGD' chunk from being output. * For API compatibility with JAI 1.0, the superclass * defines this method to throw a RuntimeException; * accordingly, subclasses must provide their own implementations. */ public void unsetBackground() { throw new RuntimeException(PropertyUtil.getString("PNGEncodeParam23")); } /** * Returns true if a 'bKGD' chunk will be output. * For API compatibility with JAI 1.0, the superclass * defines this method to throw a RuntimeException; * accordingly, subclasses must provide their own implementations. */ public boolean isBackgroundSet() { throw new RuntimeException(PropertyUtil.getString("PNGEncodeParam24")); } // cHRM chunk private float[] chromaticity; private boolean chromaticitySet; /** * Sets the white point and primary chromaticities in CIE (x, y) * space. * *

    The chromaticity parameter should be a * float array of length 8 containing the white point * X and Y, red X and Y, green X and Y, and blue X and Y values in * order. * *

    The 'cHRM' chunk will encode this information. */ public void setChromaticity(float[] chromaticity) { if (chromaticity.length != 8) { throw new IllegalArgumentException(PropertyUtil.getString("PNGEncodeParam28")); } this.chromaticity = (float[])(chromaticity.clone()); chromaticitySet = true; } /** * A convenience method that calls the array version. */ public void setChromaticity(float whitePointX, float whitePointY, float redX, float redY, float greenX, float greenY, float blueX, float blueY) { float[] chroma = new float[8]; chroma[0] = whitePointX; chroma[1] = whitePointY; chroma[2] = redX; chroma[3] = redY; chroma[4] = greenX; chroma[5] = greenY; chroma[6] = blueX; chroma[7] = blueY; setChromaticity(chroma); } /** * Returns the white point and primary chromaticities in * CIE (x, y) space. * *

    See the documentation for the setChromaticity * method for the format of the returned data. * *

    If the chromaticity has not previously been set, or has been * unset, an IllegalStateException will be thrown. * * @throws IllegalStateException if the chromaticity is not set. */ public float[] getChromaticity() { if (!chromaticitySet) { throw new IllegalStateException(PropertyUtil.getString("PNGEncodeParam12")); } return (float[])(chromaticity.clone()); } /** * Suppresses the 'cHRM' chunk from being output. */ public void unsetChromaticity() { chromaticity = null; chromaticitySet = false; } /** * Returns true if a 'cHRM' chunk will be output. */ public boolean isChromaticitySet() { return chromaticitySet; } // gAMA chunk private float gamma; private boolean gammaSet; /** * Sets the file gamma value for the image. * *

    The 'gAMA' chunk will encode this information. */ public void setGamma(float gamma) { this.gamma = gamma; gammaSet = true; } /** * Returns the file gamma value for the image. * *

    If the file gamma has not previously been set, or has been * unset, an IllegalStateException will be thrown. * * @throws IllegalStateException if the gamma is not set. */ public float getGamma() { if (!gammaSet) { throw new IllegalStateException(PropertyUtil.getString("PNGEncodeParam13")); } return gamma; } /** * Suppresses the 'gAMA' chunk from being output. */ public void unsetGamma() { gammaSet = false; } /** * Returns true if a 'gAMA' chunk will be output. */ public boolean isGammaSet() { return gammaSet; } // hIST chunk private int[] paletteHistogram; private boolean paletteHistogramSet; /** * Sets the palette histogram to be stored with this image. * The histogram consists of an array of integers, one per * palette entry. * *

    The 'hIST' chunk will encode this information. */ public void setPaletteHistogram(int[] paletteHistogram) { this.paletteHistogram = (int[])(paletteHistogram.clone()); paletteHistogramSet = true; } /** * Returns the palette histogram to be stored with this image. * *

    If the histogram has not previously been set, or has been * unset, an IllegalStateException will be thrown. * * @throws IllegalStateException if the histogram is not set. */ public int[] getPaletteHistogram() { if (!paletteHistogramSet) { throw new IllegalStateException(PropertyUtil.getString("PNGEncodeParam14")); } return paletteHistogram; } /** * Suppresses the 'hIST' chunk from being output. */ public void unsetPaletteHistogram() { paletteHistogram = null; paletteHistogramSet = false; } /** * Returns true if a 'hIST' chunk will be output. */ public boolean isPaletteHistogramSet() { return paletteHistogramSet; } // iCCP chunk private byte[] iccProfileData; private boolean iccProfileDataSet; /** * Sets the ICC profile data to be stored with this image. * The profile is represented in raw binary form. * *

    The 'iCCP' chunk will encode this information. */ public void setICCProfileData(byte[] iccProfileData) { this.iccProfileData = (byte[])(iccProfileData.clone()); iccProfileDataSet = true; } /** * Returns the ICC profile data to be stored with this image. * *

    If the ICC profile has not previously been set, or has been * unset, an IllegalStateException will be thrown. * * @throws IllegalStateException if the ICC profile is not set. */ public byte[] getICCProfileData() { if (!iccProfileDataSet) { throw new IllegalStateException(PropertyUtil.getString("PNGEncodeParam15")); } return (byte[])(iccProfileData.clone()); } /** * Suppresses the 'iCCP' chunk from being output. */ public void unsetICCProfileData() { iccProfileData = null; iccProfileDataSet = false; } /** * Returns true if a 'iCCP' chunk will be output. */ public boolean isICCProfileDataSet() { return iccProfileDataSet; } // pHYS chunk private int[] physicalDimension; private boolean physicalDimensionSet; /** * Sets the physical dimension information to be stored with this * image. The physicalDimension parameter should be a 3-entry * array containing the number of pixels per unit in the X * direction, the number of pixels per unit in the Y direction, * and the unit specifier (0 = unknown, 1 = meters). * *

    The 'pHYS' chunk will encode this information. */ public void setPhysicalDimension(int[] physicalDimension) { this.physicalDimension = (int[])(physicalDimension.clone()); physicalDimensionSet = true; } /** * A convenience method that calls the array version. */ public void setPhysicalDimension(int xPixelsPerUnit, int yPixelsPerUnit, int unitSpecifier) { int[] pd = new int[3]; pd[0] = xPixelsPerUnit; pd[1] = yPixelsPerUnit; pd[2] = unitSpecifier; setPhysicalDimension(pd); } /** * Returns the physical dimension information to be stored * with this image. * *

    If the physical dimension information has not previously * been set, or has been unset, an * IllegalStateException will be thrown. * * @throws IllegalStateException if the physical dimension information * is not set. */ public int[] getPhysicalDimension() { if (!physicalDimensionSet) { throw new IllegalStateException(PropertyUtil.getString("PNGEncodeParam16")); } return (int[])(physicalDimension.clone()); } /** * Suppresses the 'pHYS' chunk from being output. */ public void unsetPhysicalDimension() { physicalDimension = null; physicalDimensionSet = false; } /** * Returns true if a 'pHYS' chunk will be output. */ public boolean isPhysicalDimensionSet() { return physicalDimensionSet; } // sPLT chunk private PNGSuggestedPaletteEntry[] suggestedPalette; private boolean suggestedPaletteSet; /** * Sets the suggested palette information to be stored with this * image. The information is passed to this method as an array of * PNGSuggestedPaletteEntry objects. * *

    The 'sPLT' chunk will encode this information. */ public void setSuggestedPalette(PNGSuggestedPaletteEntry[] palette) { suggestedPalette = (PNGSuggestedPaletteEntry[])(palette.clone()); suggestedPaletteSet = true; } /** * Returns the suggested palette information to be stored with this * image. * *

    If the suggested palette information has not previously * been set, or has been unset, an * IllegalStateException will be thrown. * * @throws IllegalStateException if the suggested palette * information is not set. */ public PNGSuggestedPaletteEntry[] getSuggestedPalette() { if (!suggestedPaletteSet) { throw new IllegalStateException(PropertyUtil.getString("PNGEncodeParam17")); } return (PNGSuggestedPaletteEntry[])(suggestedPalette.clone()); } /** * Suppresses the 'sPLT' chunk from being output. */ public void unsetSuggestedPalette() { suggestedPalette = null; suggestedPaletteSet = false; } /** * Returns true if a 'sPLT' chunk will be output. */ public boolean isSuggestedPaletteSet() { return suggestedPaletteSet; } // sBIT chunk private int[] significantBits; private boolean significantBitsSet; /** * Sets the number of significant bits for each band of the image. * *

    The number of entries in the significantBits * array must be equal to the number of output bands in the image: * 1 for a gray image, 2 for gray+alpha, 3 for index or truecolor, * and 4 for truecolor+alpha. * *

    The 'sBIT' chunk will encode this information. */ public void setSignificantBits(int[] significantBits) { this.significantBits = (int[])(significantBits.clone()); significantBitsSet = true; } /** * Returns the number of significant bits for each band of the image. * *

    If the significant bits values have not previously been * set, or have been unset, an IllegalStateException * will be thrown. * * @throws IllegalStateException if the significant bits values are * not set. */ public int[] getSignificantBits() { if (!significantBitsSet) { throw new IllegalStateException(PropertyUtil.getString("PNGEncodeParam18")); } return (int[])significantBits.clone(); } /** * Suppresses the 'sBIT' chunk from being output. */ public void unsetSignificantBits() { significantBits = null; significantBitsSet = false; } /** * Returns true if an 'sBIT' chunk will be output. */ public boolean isSignificantBitsSet() { return significantBitsSet; } // sRGB chunk private int srgbIntent; private boolean srgbIntentSet; /** * Sets the sRGB rendering intent to be stored with this image. * The legal values are 0 = Perceptual, 1 = Relative Colorimetric, * 2 = Saturation, and 3 = Absolute Colorimetric. Refer to the * PNG specification for information on these values. * *

    The 'sRGB' chunk will encode this information. */ public void setSRGBIntent(int srgbIntent) { this.srgbIntent = srgbIntent; srgbIntentSet = true; } /** * Returns the sRGB rendering intent to be stored with this image. * *

    If the sRGB intent has not previously been set, or has been * unset, an IllegalStateException will be thrown. * * @throws IllegalStateException if the sRGB intent is not set. */ public int getSRGBIntent() { if (!srgbIntentSet) { throw new IllegalStateException(PropertyUtil.getString("PNGEncodeParam19")); } return srgbIntent; } /** * Suppresses the 'sRGB' chunk from being output. */ public void unsetSRGBIntent() { srgbIntentSet = false; } /** * Returns true if an 'sRGB' chunk will be output. */ public boolean isSRGBIntentSet() { return srgbIntentSet; } // tEXt chunk private String[] text; private boolean textSet; /** * Sets the textual data to be stored in uncompressed form with this * image. The data is passed to this method as an array of * Strings. * *

    The 'tEXt' chunk will encode this information. */ public void setText(String[] text) { this.text = text; textSet = true; } /** * Returns the text strings to be stored in uncompressed form with this * image as an array of Strings. * *

    If the text strings have not previously been set, or have been * unset, an IllegalStateException will be thrown. * * @throws IllegalStateException if the text strings are not set. */ public String[] getText() { if (!textSet) { throw new IllegalStateException(PropertyUtil.getString("PNGEncodeParam20")); } return text; } /** * Suppresses the 'tEXt' chunk from being output. */ public void unsetText() { text = null; textSet = false; } /** * Returns true if a 'tEXt' chunk will be output. */ public boolean isTextSet() { return textSet; } // tIME chunk private Date modificationTime; private boolean modificationTimeSet; /** * Sets the modification time, as a Date, to be * stored with this image. The internal storage format will use * UTC regardless of how the modificationTime * parameter was created. * *

    The 'tIME' chunk will encode this information. */ public void setModificationTime(Date modificationTime) { this.modificationTime = modificationTime; modificationTimeSet = true; } /** * Returns the modification time to be stored with this image. * *

    If the bit depth has not previously been set, or has been * unset, an IllegalStateException will be thrown. * * @throws IllegalStateException if the bit depth is not set. */ public Date getModificationTime() { if (!modificationTimeSet) { throw new IllegalStateException(PropertyUtil.getString("PNGEncodeParam21")); } return modificationTime; } /** * Suppresses the 'tIME' chunk from being output. */ public void unsetModificationTime() { modificationTime = null; modificationTimeSet = false; } /** * Returns true if a 'tIME' chunk will be output. */ public boolean isModificationTimeSet() { return modificationTimeSet; } // tRNS chunk boolean transparencySet; /** * Suppresses the 'tRNS' chunk from being output. */ public void unsetTransparency() { transparencySet = false; } /** * Returns true if a 'tRNS' chunk will be output. */ public boolean isTransparencySet() { return transparencySet; } // zTXT chunk private String[] zText; private boolean zTextSet; /** * Sets the text strings to be stored in compressed form with this * image. The data is passed to this method as an array of * Strings. * *

    The 'zTXt' chunk will encode this information. */ public void setCompressedText(String[] text) { this.zText = text; zTextSet = true; } /** * Returns the text strings to be stored in compressed form with * this image as an array of Strings. * *

    If the compressed text strings have not previously been * set, or have been unset, an IllegalStateException * will be thrown. * * @throws IllegalStateException if the compressed text strings are * not set. */ public String[] getCompressedText() { if (!zTextSet) { throw new IllegalStateException(PropertyUtil.getString("PNGEncodeParam22")); } return zText; } /** * Suppresses the 'zTXt' chunk from being output. */ public void unsetCompressedText() { zText = null; zTextSet = false; } /** * Returns true if a 'zTXT' chunk will be output. */ public boolean isCompressedTextSet() { return zTextSet; } // Other chunk types List chunkType = new ArrayList(); List chunkData = new ArrayList(); /** * Adds a private chunk, in binary form, to the list of chunks to * be stored with this image. * * @param type a 4-character String giving the chunk type name. * @param data an array of bytes containing the * chunk data. */ public synchronized void addPrivateChunk(String type, byte[] data) { chunkType.add(type); chunkData.add(data.clone()); } /** * Returns the number of private chunks to be written to the * output file. */ public synchronized int getNumPrivateChunks() { return chunkType.size(); } /** * Returns the type of the private chunk at a given index, as a * 4-character String. The index must be smaller * than the return value of getNumPrivateChunks. */ public synchronized String getPrivateChunkType(int index) { return (String)chunkType.get(index); } /** * Returns the data associated of the private chunk at a given * index, as an array of bytes. The index must be * smaller than the return value of * getNumPrivateChunks. */ public synchronized byte[] getPrivateChunkData(int index) { return (byte[])chunkData.get(index); } /** * Remove all private chunks associated with this parameter instance * whose 'safe-to-copy' bit is not set. This may be advisable when * transcoding PNG images. */ public synchronized void removeUnsafeToCopyPrivateChunks() { List newChunkType = new ArrayList(); List newChunkData = new ArrayList(); int len = getNumPrivateChunks(); for (int i = 0; i < len; i++) { String type = getPrivateChunkType(i); char lastChar = type.charAt(3); if (lastChar >= 'a' && lastChar <= 'z') { newChunkType.add(type); newChunkData.add(getPrivateChunkData(i)); } } chunkType = newChunkType; chunkData = newChunkData; } /** * Remove all private chunks associated with this parameter instance. */ public synchronized void removeAllPrivateChunks() { chunkType = new ArrayList(); chunkData = new ArrayList(); } /** * An abs() function for use by the Paeth predictor. */ private static int abs(int x) { return (x < 0) ? -x : x; } /** * The Paeth predictor routine used in PNG encoding. This routine * is included as a convenience to subclasses that override the * filterRow method. */ public static int paethPredictor(int a, int b, int c) { int p = a + b - c; int pa = abs(p - a); int pb = abs(p - b); int pc = abs(p - c); if ((pa <= pb) && (pa <= pc)) { return a; } else if (pb <= pc) { return b; } else { return c; } } /** * Performs filtering on a row of an image. This method may be * overridden in order to provide a custom algorithm for choosing * the filter type for a given row. * *

    The method is supplied with the current and previous rows * of the image. For the first row of the image, or of an * interlacing pass, the previous row array will be filled with * zeros as required by the PNG specification. * *

    The method is also supplied with five scratch arrays. * These arrays may be used within the method for any purpose. * At method exit, the array at the index given by the return * value of the method should contain the filtered data. The * return value will also be used as the filter type. * *

    The default implementation of the method performs a trial * encoding with each of the filter types, and computes the sum of * absolute values of the differences between the raw bytes of the * current row and the predicted values. The index of the filter * producing the smallest result is returned. * *

    As an example, to perform only 'sub' filtering, this method * could be implemented (non-optimally) as follows: * *

         * for (int i = bytesPerPixel; i < bytesPerRow + bytesPerPixel; i++) {
         *     int curr = currRow[i] & 0xff;
         *     int left = currRow[i - bytesPerPixel] & 0xff;
         *     scratchRow[PNG_FILTER_SUB][i] = (byte)(curr - left);
         * }
         * return PNG_FILTER_SUB;
         * 
    * * @param currRow The current row as an array of bytes * of length at least bytesPerRow + bytesPerPixel. * The pixel data starts at index bytesPerPixel; * the initial bytesPerPixel bytes are zero. * @param prevRow The current row as an array of bytes * The pixel data starts at index bytesPerPixel; * the initial bytesPerPixel bytes are zero. * @param scratchRows An array of 5 byte arrays of * length at least bytesPerRow + * bytesPerPixel, useable to hold temporary results. * The filtered row will be returned as one of the entries * of this array. The returned filtered data should start * at index bytesPerPixel; The initial * bytesPerPixel bytes are not used. * @param bytesPerRow The number of bytes in the image row. * This value will always be greater than 0. * @param bytesPerPixel The number of bytes representing a single * pixel, rounded up to an integer. This is the 'bpp' parameter * described in the PNG specification. * * @return The filter type to be used. The entry of * scratchRows[] at this index holds the * filtered data. */ public int filterRow(byte[] currRow, byte[] prevRow, byte[][] scratchRows, int bytesPerRow, int bytesPerPixel) { int [] badness = {0, 0, 0, 0, 0}; int curr; int left; int up; int upleft; int diff; int pa; int pb; int pc; for (int i = bytesPerPixel; i < bytesPerRow + bytesPerPixel; i++) { curr = currRow[i] & 0xff; left = currRow[i - bytesPerPixel] & 0xff; up = prevRow[i] & 0xff; upleft = prevRow[i - bytesPerPixel] & 0xff; // no filter badness[0] += curr; // sub filter diff = curr - left; scratchRows[1][i] = (byte)diff; badness [1] += (diff > 0) ? diff : -diff; // up filter diff = curr - up; scratchRows[2][i] = (byte)diff; badness [2] += (diff >= 0) ? diff : -diff; // average filter diff = curr - ((left + up) >> 1); scratchRows[3][i] = (byte)diff; badness [3] += (diff >= 0) ? diff : -diff; // paeth filter // Original code much simplier but doesn't take full // advantage of relationship between pa/b/c and // information gleaned in abs operations. /// pa = up -upleft; /// pb = left-upleft; /// pc = pa+pb; /// pa = abs(pa); /// pb = abs(pb); /// pc = abs(pc); /// if ((pa <= pb) && (pa <= pc)) /// diff = curr-left; /// else if (pb <= pc) /// diff = curr-up; /// else /// diff = curr-upleft; pa = up - upleft; pb = left - upleft; if (pa < 0) { if (pb < 0) { // both pa & pb neg so pc is always greater than or // equal to pa or pb; if (pa >= pb) { // since pa & pb neg check sense is reversed. diff = curr - left; } else { diff = curr - up; } } else { // pa neg pb pos so we must compute pc... pc = pa + pb; pa = -pa; if (pa <= pb) { // pc is positive and less than pb if (pa <= pc) { diff = curr - left; } else { diff = curr - upleft; } } else { // pc is negative and less than or equal to pa, // but since pa is greater than pb this isn't an issue... if (pb <= -pc) { diff = curr - up; } else { diff = curr - upleft; } } } } else { if (pb < 0) { pb = -pb; // make it positive... if (pa <= pb) { // pc would be negative and less than or equal to pb pc = pb - pa; if (pa <= pc) { diff = curr - left; } else if (pb == pc) { // if pa is zero then pc==pb otherwise // pc must be less than pb. diff = curr - up; } else { diff = curr - upleft; } } else { // pc would be positive and less than pa. pc = pa - pb; if (pb <= pc) { diff = curr - up; } else { diff = curr - upleft; } } } else { // both pos so pa+pb is always greater than pa/pb if (pa <= pb) { diff = curr - left; } else { diff = curr - up; } } } scratchRows[4][i] = (byte)diff; badness [4] += (diff >= 0) ? diff : -diff; } int filterType = 0; int minBadness = badness[0]; for (int i = 1; i < 5; i++) { if (badness[i] < minBadness) { minBadness = badness[i]; filterType = i; } } if (filterType == 0) { System.arraycopy(currRow, bytesPerPixel, scratchRows[0], bytesPerPixel, bytesPerRow); } return filterType; } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/codec/png/PNGImageDecoder.java0100644 0000000 0000000 00000173755 13777276623 031600 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: PNGImageDecoder.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.image.codec.png; import java.awt.Color; import java.awt.Point; import java.awt.Transparency; import java.awt.color.ColorSpace; import java.awt.image.ColorModel; import java.awt.image.ComponentColorModel; import java.awt.image.DataBuffer; import java.awt.image.DataBufferByte; import java.awt.image.DataBufferUShort; import java.awt.image.IndexColorModel; import java.awt.image.Raster; import java.awt.image.RenderedImage; import java.awt.image.SampleModel; import java.awt.image.WritableRaster; import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; import java.io.DataInputStream; import java.io.IOException; import java.io.InputStream; import java.io.SequenceInputStream; import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.GregorianCalendar; import java.util.List; import java.util.Locale; import java.util.TimeZone; import java.util.zip.Inflater; import java.util.zip.InflaterInputStream; import javax.imageio.stream.ImageInputStream; import org.apache.xmlgraphics.image.codec.util.ImageDecoderImpl; import org.apache.xmlgraphics.image.codec.util.ImageInputStreamSeekableStreamAdapter; import org.apache.xmlgraphics.image.codec.util.PropertyUtil; import org.apache.xmlgraphics.image.codec.util.SeekableStream; import org.apache.xmlgraphics.image.codec.util.SimpleRenderedImage; import org.apache.xmlgraphics.image.loader.ImageSize; import org.apache.xmlgraphics.image.loader.impl.PNGConstants; // CSOFF: ConstantName // CSOFF: InnerAssignment // CSOFF: MethodName // CSOFF: MissingSwitchDefault // CSOFF: MultipleVariableDeclarations // CSOFF: NoWhitespaceAfter // CSOFF: OperatorWrap // CSOFF: WhitespaceAround /** * @version $Id: PNGImageDecoder.java 1732018 2016-02-24 04:51:06Z gadams $ */ public class PNGImageDecoder extends ImageDecoderImpl { public PNGImageDecoder(InputStream input, PNGDecodeParam param) { super(input, param); } @Override public RenderedImage decodeAsRenderedImage(int page) throws IOException { if (page != 0) { throw new IOException(PropertyUtil.getString("PNGImageDecoder19")); } return new PNGImage(input, (PNGDecodeParam)param); } public static void readPNGHeader(ImageInputStream inputStream, ImageSize size) throws IOException { SeekableStream seekStream = new ImageInputStreamSeekableStreamAdapter(inputStream) { public void close() throws IOException { } }; PNGImage pngImage = new PNGImage(seekStream); size.setSizeInPixels(pngImage.getWidth(), pngImage.getHeight()); double dpiHorz = size.getDpiHorizontal(); double dpiVert = size.getDpiVertical(); if (pngImage.unitSpecifier == 1) { if (pngImage.xPixelsPerUnit != 0) { dpiHorz = pngImage.xPixelsPerUnit * 0.0254; } if (pngImage.yPixelsPerUnit != 0) { dpiVert = pngImage.yPixelsPerUnit * 0.0254; } } size.setResolution(dpiHorz, dpiVert); size.calcSizeFromPixels(); } } /** * TO DO: * * zTXt chunks * */ class PNGImage extends SimpleRenderedImage implements PNGConstants { private static final String[] colorTypeNames = { "Grayscale", "Error", "Truecolor", "Index", "Grayscale with alpha", "Error", "Truecolor with alpha" }; private int[][] bandOffsets = { null, { 0 }, // G { 0, 1 }, // GA in GA order { 0, 1, 2 }, // RGB in RGB order { 0, 1, 2, 3 } // RGBA in RGBA order }; private int bitDepth; private int colorType; private int compressionMethod; private int filterMethod; private int interlaceMethod; private int paletteEntries; private byte[] redPalette; private byte[] greenPalette; private byte[] bluePalette; private byte[] alphaPalette; private int bkgdRed; private int bkgdGreen; private int bkgdBlue; private int grayTransparentAlpha; private int redTransparentAlpha; private int greenTransparentAlpha; private int blueTransparentAlpha; private int maxOpacity; private int[] significantBits; // Parameter information // If true, the user wants destination alpha where applicable. private boolean suppressAlpha; // If true, perform palette lookup internally private boolean expandPalette; // If true, output < 8 bit gray images in 8 bit components format private boolean output8BitGray; // Create an alpha channel in the destination color model. private boolean outputHasAlphaPalette; // Perform gamma correction on the image private boolean performGammaCorrection; // Expand GA to GGGA for compatbility with Java2D private boolean expandGrayAlpha; // Produce an instance of PNGEncodeParam private boolean generateEncodeParam; // PNGDecodeParam controlling decode process private PNGDecodeParam decodeParam; // PNGEncodeParam to store file details in private PNGEncodeParam encodeParam; private boolean emitProperties = true; private float fileGamma = 45455 / 100000.0F; private float userExponent = 1.0F; private float displayExponent = 2.2F; private float[] chromaticity; private int sRGBRenderingIntent = -1; // Post-processing step implied by above parameters private int postProcess = POST_NONE; protected int xPixelsPerUnit; protected int yPixelsPerUnit; protected int unitSpecifier; // Possible post-processing steps // Do nothing private static final int POST_NONE = 0; // Gamma correct only private static final int POST_GAMMA = 1; // Push gray values through grayLut to expand to 8 bits private static final int POST_GRAY_LUT = 2; // Push gray values through grayLut to expand to 8 bits, add alpha private static final int POST_GRAY_LUT_ADD_TRANS = 3; // Push palette value through R,G,B lookup tables private static final int POST_PALETTE_TO_RGB = 4; // Push palette value through R,G,B,A lookup tables private static final int POST_PALETTE_TO_RGBA = 5; // Add transparency to a given gray value (w/ optional gamma) private static final int POST_ADD_GRAY_TRANS = 6; // Add transparency to a given RGB value (w/ optional gamma) private static final int POST_ADD_RGB_TRANS = 7; // Remove the alpha channel from a gray image (w/ optional gamma) private static final int POST_REMOVE_GRAY_TRANS = 8; // Remove the alpha channel from an RGB image (w/optional gamma) private static final int POST_REMOVE_RGB_TRANS = 9; // Mask to add expansion of GA -> GGGA private static final int POST_EXP_MASK = 16; // Expand gray to G/G/G private static final int POST_GRAY_ALPHA_EXP = POST_NONE | POST_EXP_MASK; // Expand gray to G/G/G through a gamma lut private static final int POST_GAMMA_EXP = POST_GAMMA | POST_EXP_MASK; // Push gray values through grayLut to expand to 8 bits, expand, add alpha private static final int POST_GRAY_LUT_ADD_TRANS_EXP = POST_GRAY_LUT_ADD_TRANS | POST_EXP_MASK; // Add transparency to a given gray value, expand private static final int POST_ADD_GRAY_TRANS_EXP = POST_ADD_GRAY_TRANS | POST_EXP_MASK; private List streamVec = new ArrayList(); private DataInputStream dataStream; private int bytesPerPixel; // number of bytes per input pixel private int inputBands; private int outputBands; // Number of private chunks private int chunkIndex; private List textKeys = new ArrayList(); private List textStrings = new ArrayList(); private List ztextKeys = new ArrayList(); private List ztextStrings = new ArrayList(); private WritableRaster theTile; private int[] gammaLut; private void initGammaLut(int bits) { double exp = (double)userExponent / (fileGamma * displayExponent); int numSamples = 1 << bits; int maxOutSample = (bits == 16) ? 65535 : 255; gammaLut = new int[numSamples]; for (int i = 0; i < numSamples; i++) { double gbright = (double)i / (numSamples - 1); double gamma = Math.pow(gbright, exp); int igamma = (int)(gamma * maxOutSample + 0.5); if (igamma > maxOutSample) { igamma = maxOutSample; } gammaLut[i] = igamma; } } private final byte[][] expandBits = { null, { (byte)0x00, (byte)0xff }, { (byte)0x00, (byte)0x55, (byte)0xaa, (byte)0xff }, null, { (byte)0x00, (byte)0x11, (byte)0x22, (byte)0x33, (byte)0x44, (byte)0x55, (byte)0x66, (byte)0x77, (byte)0x88, (byte)0x99, (byte)0xaa, (byte)0xbb, (byte)0xcc, (byte)0xdd, (byte)0xee, (byte)0xff } }; private int[] grayLut; private void initGrayLut(int bits) { int len = 1 << bits; grayLut = new int[len]; if (performGammaCorrection) { System.arraycopy(gammaLut, 0, grayLut, 0, len); } else { for (int i = 0; i < len; i++) { grayLut[i] = expandBits[bits][i]; } } } public PNGImage(InputStream stream) throws IOException { DataInputStream distream = new DataInputStream(stream); long magic = distream.readLong(); if (magic != PNG_SIGNATURE) { throw new IOException("Not a png file"); } while (true) { String chunkType = PNGChunk.getChunkType(distream); if (chunkType.equals(PNGChunk.ChunkType.IHDR.name())) { PNGChunk chunk = PNGChunk.readChunk(distream); parse_IHDR_chunk(chunk); } else if (chunkType.equals(PNGChunk.ChunkType.pHYs.name())) { PNGChunk chunk = PNGChunk.readChunk(distream); parse_pHYs_chunk(chunk); return; } else if (chunkType.equals(PNGChunk.ChunkType.IEND.name())) { return; } else { PNGChunk.readChunk(distream); } } } public PNGImage(InputStream stream, PNGDecodeParam decodeParam) throws IOException { if (!stream.markSupported()) { stream = new BufferedInputStream(stream); } DataInputStream distream = new DataInputStream(stream); if (decodeParam == null) { decodeParam = new PNGDecodeParam(); } this.decodeParam = decodeParam; // Get parameter values this.suppressAlpha = decodeParam.getSuppressAlpha(); this.expandPalette = decodeParam.getExpandPalette(); this.output8BitGray = decodeParam.getOutput8BitGray(); this.expandGrayAlpha = decodeParam.getExpandGrayAlpha(); if (decodeParam.getPerformGammaCorrection()) { this.userExponent = decodeParam.getUserExponent(); this.displayExponent = decodeParam.getDisplayExponent(); performGammaCorrection = true; output8BitGray = true; } this.generateEncodeParam = decodeParam.getGenerateEncodeParam(); if (emitProperties) { properties.put("file_type", "PNG v. 1.0"); } try { long magic = distream.readLong(); if (magic != PNG_SIGNATURE) { String msg = PropertyUtil.getString("PNGImageDecoder0"); throw new RuntimeException(msg); } } catch (IOException ioe) { ioe.printStackTrace(); String msg = PropertyUtil.getString("PNGImageDecoder1"); throw new RuntimeException(msg); } do { // try { PNGChunk chunk; String chunkType = PNGChunk.getChunkType(distream); if (chunkType.equals(PNGChunk.ChunkType.IHDR.name())) { chunk = PNGChunk.readChunk(distream); parse_IHDR_chunk(chunk); } else if (chunkType.equals(PNGChunk.ChunkType.PLTE.name())) { chunk = PNGChunk.readChunk(distream); parse_PLTE_chunk(chunk); } else if (chunkType.equals(PNGChunk.ChunkType.IDAT.name())) { chunk = PNGChunk.readChunk(distream); streamVec.add(new ByteArrayInputStream(chunk.getData())); } else if (chunkType.equals(PNGChunk.ChunkType.IEND.name())) { chunk = PNGChunk.readChunk(distream); try { parse_IEND_chunk(chunk); } catch (Exception e) { e.printStackTrace(); String msg = PropertyUtil.getString("PNGImageDecoder2"); throw new RuntimeException(msg); } break; // fall through to the bottom } else if (chunkType.equals(PNGChunk.ChunkType.bKGD.name())) { chunk = PNGChunk.readChunk(distream); parse_bKGD_chunk(chunk); } else if (chunkType.equals(PNGChunk.ChunkType.cHRM.name())) { chunk = PNGChunk.readChunk(distream); parse_cHRM_chunk(chunk); } else if (chunkType.equals(PNGChunk.ChunkType.gAMA.name())) { chunk = PNGChunk.readChunk(distream); parse_gAMA_chunk(chunk); } else if (chunkType.equals(PNGChunk.ChunkType.hIST.name())) { chunk = PNGChunk.readChunk(distream); parse_hIST_chunk(chunk); } else if (chunkType.equals(PNGChunk.ChunkType.iCCP.name())) { chunk = PNGChunk.readChunk(distream); parse_iCCP_chunk(chunk); } else if (chunkType.equals(PNGChunk.ChunkType.pHYs.name())) { chunk = PNGChunk.readChunk(distream); parse_pHYs_chunk(chunk); } else if (chunkType.equals(PNGChunk.ChunkType.sBIT.name())) { chunk = PNGChunk.readChunk(distream); parse_sBIT_chunk(chunk); } else if (chunkType.equals(PNGChunk.ChunkType.sRGB.name())) { chunk = PNGChunk.readChunk(distream); parse_sRGB_chunk(chunk); } else if (chunkType.equals(PNGChunk.ChunkType.tEXt.name())) { chunk = PNGChunk.readChunk(distream); parse_tEXt_chunk(chunk); } else if (chunkType.equals(PNGChunk.ChunkType.tIME.name())) { chunk = PNGChunk.readChunk(distream); parse_tIME_chunk(chunk); } else if (chunkType.equals(PNGChunk.ChunkType.tRNS.name())) { chunk = PNGChunk.readChunk(distream); parse_tRNS_chunk(chunk); } else if (chunkType.equals(PNGChunk.ChunkType.zTXt.name())) { chunk = PNGChunk.readChunk(distream); parse_zTXt_chunk(chunk); } else { chunk = PNGChunk.readChunk(distream); // Output the chunk data in raw form String type = chunk.getTypeString(); byte[] data = chunk.getData(); if (encodeParam != null) { encodeParam.addPrivateChunk(type, data); } if (emitProperties) { String key = "chunk_" + chunkIndex++ + ':' + type; properties.put(key.toLowerCase(Locale.getDefault()), data); } } // } catch (Exception e) { // e.printStackTrace(); // String msg = PropertyUtil.getString("PNGImageDecoder2"); // throw new RuntimeException(msg); // } } while (true); // Final post-processing if (significantBits == null) { significantBits = new int[inputBands]; for (int i = 0; i < inputBands; i++) { significantBits[i] = bitDepth; } if (emitProperties) { properties.put("significant_bits", significantBits); } } } private void parse_IHDR_chunk(PNGChunk chunk) { tileWidth = width = chunk.getInt4(0); tileHeight = height = chunk.getInt4(4); bitDepth = chunk.getInt1(8); if ((bitDepth != 1) && (bitDepth != 2) && (bitDepth != 4) && (bitDepth != 8) && (bitDepth != 16)) { // Error -- bad bit depth String msg = PropertyUtil.getString("PNGImageDecoder3"); throw new RuntimeException(msg); } maxOpacity = (1 << bitDepth) - 1; colorType = chunk.getInt1(9); if ((colorType != PNG_COLOR_GRAY) && (colorType != PNG_COLOR_RGB) && (colorType != PNG_COLOR_PALETTE) && (colorType != PNG_COLOR_GRAY_ALPHA) && (colorType != PNG_COLOR_RGB_ALPHA)) { System.out.println(PropertyUtil.getString("PNGImageDecoder4")); } if ((colorType == PNG_COLOR_RGB) && (bitDepth < 8)) { // Error -- RGB images must have 8 or 16 bits String msg = PropertyUtil.getString("PNGImageDecoder5"); throw new RuntimeException(msg); } if ((colorType == PNG_COLOR_PALETTE) && (bitDepth == 16)) { // Error -- palette images must have < 16 bits String msg = PropertyUtil.getString("PNGImageDecoder6"); throw new RuntimeException(msg); } if ((colorType == PNG_COLOR_GRAY_ALPHA) && (bitDepth < 8)) { // Error -- gray/alpha images must have >= 8 bits String msg = PropertyUtil.getString("PNGImageDecoder7"); throw new RuntimeException(msg); } if ((colorType == PNG_COLOR_RGB_ALPHA) && (bitDepth < 8)) { // Error -- RGB/alpha images must have >= 8 bits String msg = PropertyUtil.getString("PNGImageDecoder8"); throw new RuntimeException(msg); } if (emitProperties) { properties.put("color_type", colorTypeNames[colorType]); } if (generateEncodeParam) { if (colorType == PNG_COLOR_PALETTE) { encodeParam = new PNGEncodeParam.Palette(); } else if (colorType == PNG_COLOR_GRAY || colorType == PNG_COLOR_GRAY_ALPHA) { encodeParam = new PNGEncodeParam.Gray(); } else { encodeParam = new PNGEncodeParam.RGB(); } decodeParam.setEncodeParam(encodeParam); } if (encodeParam != null) { encodeParam.setBitDepth(bitDepth); } if (emitProperties) { properties.put("bit_depth", bitDepth); } if (performGammaCorrection) { // Assume file gamma is 1/2.2 unless we get a gAMA chunk float gamma = (1.0F / 2.2F) * (displayExponent / userExponent); if (encodeParam != null) { encodeParam.setGamma(gamma); } if (emitProperties) { properties.put("gamma", gamma); } } compressionMethod = chunk.getInt1(10); if (compressionMethod != 0) { // Error -- only know about compression method 0 String msg = PropertyUtil.getString("PNGImageDecoder9"); throw new RuntimeException(msg); } filterMethod = chunk.getInt1(11); if (filterMethod != 0) { // Error -- only know about filter method 0 String msg = PropertyUtil.getString("PNGImageDecoder10"); throw new RuntimeException(msg); } interlaceMethod = chunk.getInt1(12); if (interlaceMethod == 0) { if (encodeParam != null) { encodeParam.setInterlacing(false); } if (emitProperties) { properties.put("interlace_method", "None"); } } else if (interlaceMethod == 1) { if (encodeParam != null) { encodeParam.setInterlacing(true); } if (emitProperties) { properties.put("interlace_method", "Adam7"); } } else { // Error -- only know about Adam7 interlacing String msg = PropertyUtil.getString("PNGImageDecoder11"); throw new RuntimeException(msg); } bytesPerPixel = (bitDepth == 16) ? 2 : 1; switch (colorType) { case PNG_COLOR_GRAY: inputBands = 1; outputBands = 1; if (output8BitGray && (bitDepth < 8)) { postProcess = POST_GRAY_LUT; } else if (performGammaCorrection) { postProcess = POST_GAMMA; } else { postProcess = POST_NONE; } break; case PNG_COLOR_RGB: inputBands = 3; bytesPerPixel *= 3; outputBands = 3; if (performGammaCorrection) { postProcess = POST_GAMMA; } else { postProcess = POST_NONE; } break; case PNG_COLOR_PALETTE: inputBands = 1; bytesPerPixel = 1; outputBands = expandPalette ? 3 : 1; if (expandPalette) { postProcess = POST_PALETTE_TO_RGB; } else { postProcess = POST_NONE; } break; case PNG_COLOR_GRAY_ALPHA: inputBands = 2; bytesPerPixel *= 2; if (suppressAlpha) { outputBands = 1; postProcess = POST_REMOVE_GRAY_TRANS; } else { if (performGammaCorrection) { postProcess = POST_GAMMA; } else { postProcess = POST_NONE; } if (expandGrayAlpha) { postProcess |= POST_EXP_MASK; outputBands = 4; } else { outputBands = 2; } } break; case PNG_COLOR_RGB_ALPHA: inputBands = 4; bytesPerPixel *= 4; outputBands = (!suppressAlpha) ? 4 : 3; if (suppressAlpha) { postProcess = POST_REMOVE_RGB_TRANS; } else if (performGammaCorrection) { postProcess = POST_GAMMA; } else { postProcess = POST_NONE; } break; } } private void parse_IEND_chunk(PNGChunk chunk) throws Exception { // Store text strings int textLen = textKeys.size(); String[] textArray = new String[2 * textLen]; for (int i = 0; i < textLen; i++) { String key = (String)textKeys.get(i); String val = (String)textStrings.get(i); textArray[2 * i] = key; textArray[2 * i + 1] = val; if (emitProperties) { String uniqueKey = "text_" + i + ':' + key; properties.put(uniqueKey.toLowerCase(Locale.getDefault()), val); } } if (encodeParam != null) { encodeParam.setText(textArray); } // Store compressed text strings int ztextLen = ztextKeys.size(); String[] ztextArray = new String[2 * ztextLen]; for (int i = 0; i < ztextLen; i++) { String key = (String)ztextKeys.get(i); String val = (String)ztextStrings.get(i); ztextArray[2 * i] = key; ztextArray[2 * i + 1] = val; if (emitProperties) { String uniqueKey = "ztext_" + i + ':' + key; properties.put(uniqueKey.toLowerCase(Locale.getDefault()), val); } } if (encodeParam != null) { encodeParam.setCompressedText(ztextArray); } // Parse prior IDAT chunks InputStream seqStream = new SequenceInputStream(Collections.enumeration(streamVec)); InputStream infStream = new InflaterInputStream(seqStream, new Inflater()); dataStream = new DataInputStream(infStream); // Create an empty WritableRaster int depth = bitDepth; if ((colorType == PNG_COLOR_GRAY) && (bitDepth < 8) && output8BitGray) { depth = 8; } if ((colorType == PNG_COLOR_PALETTE) && expandPalette) { depth = 8; } int bytesPerRow = (outputBands * width * depth + 7) / 8; int scanlineStride = (depth == 16) ? (bytesPerRow / 2) : bytesPerRow; theTile = createRaster(width, height, outputBands, scanlineStride, depth); if (performGammaCorrection && (gammaLut == null)) { initGammaLut(bitDepth); } if ((postProcess == POST_GRAY_LUT) || (postProcess == POST_GRAY_LUT_ADD_TRANS) || (postProcess == POST_GRAY_LUT_ADD_TRANS_EXP)) { initGrayLut(bitDepth); } decodeImage(interlaceMethod == 1); sampleModel = theTile.getSampleModel(); if ((colorType == PNG_COLOR_PALETTE) && !expandPalette) { if (outputHasAlphaPalette) { colorModel = new IndexColorModel(bitDepth, paletteEntries, redPalette, greenPalette, bluePalette, alphaPalette); } else { colorModel = new IndexColorModel(bitDepth, paletteEntries, redPalette, greenPalette, bluePalette); } } else if ((colorType == PNG_COLOR_GRAY) && (bitDepth < 8) && !output8BitGray) { byte[] palette = expandBits[bitDepth]; colorModel = new IndexColorModel(bitDepth, palette.length, palette, palette, palette); } else { colorModel = createComponentColorModel(sampleModel); } } private static final int[] GrayBits8 = { 8 }; private static final ComponentColorModel colorModelGray8 = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_GRAY), GrayBits8, false, false, Transparency.OPAQUE, DataBuffer.TYPE_BYTE); private static final int[] GrayAlphaBits8 = { 8, 8 }; private static final ComponentColorModel colorModelGrayAlpha8 = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_GRAY), GrayAlphaBits8, true, false, Transparency.TRANSLUCENT, DataBuffer.TYPE_BYTE); private static final int[] GrayBits16 = { 16 }; private static final ComponentColorModel colorModelGray16 = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_GRAY), GrayBits16, false, false, Transparency.OPAQUE, DataBuffer.TYPE_USHORT); private static final int[] GrayAlphaBits16 = { 16, 16 }; private static final ComponentColorModel colorModelGrayAlpha16 = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_GRAY), GrayAlphaBits16, true, false, Transparency.TRANSLUCENT, DataBuffer.TYPE_USHORT); private static final int[] GrayBits32 = { 32 }; private static final ComponentColorModel colorModelGray32 = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_GRAY), GrayBits32, false, false, Transparency.OPAQUE, DataBuffer.TYPE_INT); private static final int[] GrayAlphaBits32 = { 32, 32 }; private static final ComponentColorModel colorModelGrayAlpha32 = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_GRAY), GrayAlphaBits32, true, false, Transparency.TRANSLUCENT, DataBuffer.TYPE_INT); private static final int[] RGBBits8 = { 8, 8, 8 }; private static final ComponentColorModel colorModelRGB8 = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), RGBBits8, false, false, Transparency.OPAQUE, DataBuffer.TYPE_BYTE); private static final int[] RGBABits8 = { 8, 8, 8, 8 }; private static final ComponentColorModel colorModelRGBA8 = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), RGBABits8, true, false, Transparency.TRANSLUCENT, DataBuffer.TYPE_BYTE); private static final int[] RGBBits16 = { 16, 16, 16 }; private static final ComponentColorModel colorModelRGB16 = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), RGBBits16, false, false, Transparency.OPAQUE, DataBuffer.TYPE_USHORT); private static final int[] RGBABits16 = { 16, 16, 16, 16 }; private static final ComponentColorModel colorModelRGBA16 = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), RGBABits16, true, false, Transparency.TRANSLUCENT, DataBuffer.TYPE_USHORT); private static final int[] RGBBits32 = { 32, 32, 32 }; private static final ComponentColorModel colorModelRGB32 = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), RGBBits32, false, false, Transparency.OPAQUE, DataBuffer.TYPE_INT); private static final int[] RGBABits32 = { 32, 32, 32, 32 }; private static final ComponentColorModel colorModelRGBA32 = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), RGBABits32, true, false, Transparency.TRANSLUCENT, DataBuffer.TYPE_INT); /** * A convenience method to create an instance of * ComponentColorModel suitable for use with the * given SampleModel. The SampleModel * should have a data type of DataBuffer.TYPE_BYTE, * TYPE_USHORT, or TYPE_INT and between * 1 and 4 bands. Depending on the number of bands of the * SampleModel, either a gray, gray+alpha, rgb, or * rgb+alpha ColorModel is returned. */ public static ColorModel createComponentColorModel(SampleModel sm) { int type = sm.getDataType(); int bands = sm.getNumBands(); ComponentColorModel cm = null; if (type == DataBuffer.TYPE_BYTE) { switch (bands) { case 1: cm = colorModelGray8; break; case 2: cm = colorModelGrayAlpha8; break; case 3: cm = colorModelRGB8; break; case 4: cm = colorModelRGBA8; break; } } else if (type == DataBuffer.TYPE_USHORT) { switch (bands) { case 1: cm = colorModelGray16; break; case 2: cm = colorModelGrayAlpha16; break; case 3: cm = colorModelRGB16; break; case 4: cm = colorModelRGBA16; break; } } else if (type == DataBuffer.TYPE_INT) { switch (bands) { case 1: cm = colorModelGray32; break; case 2: cm = colorModelGrayAlpha32; break; case 3: cm = colorModelRGB32; break; case 4: cm = colorModelRGBA32; break; } } return cm; } private void parse_PLTE_chunk(PNGChunk chunk) { paletteEntries = chunk.getLength() / 3; redPalette = new byte[paletteEntries]; greenPalette = new byte[paletteEntries]; bluePalette = new byte[paletteEntries]; int pltIndex = 0; // gAMA chunk must precede PLTE chunk if (performGammaCorrection) { if (gammaLut == null) { initGammaLut(bitDepth == 16 ? 16 : 8); } for (int i = 0; i < paletteEntries; i++) { byte r = chunk.getByte(pltIndex++); byte g = chunk.getByte(pltIndex++); byte b = chunk.getByte(pltIndex++); redPalette[i] = (byte)gammaLut[r & 0xff]; greenPalette[i] = (byte)gammaLut[g & 0xff]; bluePalette[i] = (byte)gammaLut[b & 0xff]; } } else { for (int i = 0; i < paletteEntries; i++) { redPalette[i] = chunk.getByte(pltIndex++); greenPalette[i] = chunk.getByte(pltIndex++); bluePalette[i] = chunk.getByte(pltIndex++); } } } private void parse_bKGD_chunk(PNGChunk chunk) { switch (colorType) { case PNG_COLOR_PALETTE: int bkgdIndex = chunk.getByte(0) & 0xff; bkgdRed = redPalette[bkgdIndex] & 0xff; bkgdGreen = greenPalette[bkgdIndex] & 0xff; bkgdBlue = bluePalette[bkgdIndex] & 0xff; if (encodeParam != null) { ((PNGEncodeParam.Palette)encodeParam).setBackgroundPaletteIndex(bkgdIndex); } break; case PNG_COLOR_GRAY: case PNG_COLOR_GRAY_ALPHA: int bkgdGray = chunk.getInt2(0); bkgdRed = bkgdGreen = bkgdBlue = bkgdGray; if (encodeParam != null) { ((PNGEncodeParam.Gray)encodeParam).setBackgroundGray(bkgdGray); } break; case PNG_COLOR_RGB: case PNG_COLOR_RGB_ALPHA: bkgdRed = chunk.getInt2(0); bkgdGreen = chunk.getInt2(2); bkgdBlue = chunk.getInt2(4); int[] bkgdRGB = new int[3]; bkgdRGB[0] = bkgdRed; bkgdRGB[1] = bkgdGreen; bkgdRGB[2] = bkgdBlue; if (encodeParam != null) { ((PNGEncodeParam.RGB)encodeParam).setBackgroundRGB(bkgdRGB); } break; } int r = 0; int g = 0; int b = 0; if (bitDepth < 8) { r = expandBits[bitDepth][bkgdRed]; g = expandBits[bitDepth][bkgdGreen]; b = expandBits[bitDepth][bkgdBlue]; } else if (bitDepth == 8) { r = bkgdRed; g = bkgdGreen; b = bkgdBlue; } else if (bitDepth == 16) { r = bkgdRed >> 8; g = bkgdGreen >> 8; b = bkgdBlue >> 8; } if (emitProperties) { properties.put("background_color", new Color(r, g, b)); } } private void parse_cHRM_chunk(PNGChunk chunk) { // If an sRGB chunk exists, ignore cHRM chunks if (sRGBRenderingIntent != -1) { return; } chromaticity = new float[8]; chromaticity[0] = chunk.getInt4(0) / 100000.0F; chromaticity[1] = chunk.getInt4(4) / 100000.0F; chromaticity[2] = chunk.getInt4(8) / 100000.0F; chromaticity[3] = chunk.getInt4(12) / 100000.0F; chromaticity[4] = chunk.getInt4(16) / 100000.0F; chromaticity[5] = chunk.getInt4(20) / 100000.0F; chromaticity[6] = chunk.getInt4(24) / 100000.0F; chromaticity[7] = chunk.getInt4(28) / 100000.0F; if (encodeParam != null) { encodeParam.setChromaticity(chromaticity); } if (emitProperties) { properties.put("white_point_x", chromaticity[0]); properties.put("white_point_y", chromaticity[1]); properties.put("red_x", chromaticity[2]); properties.put("red_y", chromaticity[3]); properties.put("green_x", chromaticity[4]); properties.put("green_y", chromaticity[5]); properties.put("blue_x", chromaticity[6]); properties.put("blue_y", chromaticity[7]); } } private void parse_gAMA_chunk(PNGChunk chunk) { // If an sRGB chunk exists, ignore gAMA chunks if (sRGBRenderingIntent != -1) { return; } fileGamma = chunk.getInt4(0) / 100000.0F; float exp = performGammaCorrection ? displayExponent / userExponent : 1.0F; if (encodeParam != null) { encodeParam.setGamma(fileGamma * exp); } if (emitProperties) { properties.put("gamma", fileGamma * exp); } } private void parse_hIST_chunk(PNGChunk chunk) { if (redPalette == null) { String msg = PropertyUtil.getString("PNGImageDecoder18"); throw new RuntimeException(msg); } int length = redPalette.length; int[] hist = new int[length]; for (int i = 0; i < length; i++) { hist[i] = chunk.getInt2(2 * i); } if (encodeParam != null) { encodeParam.setPaletteHistogram(hist); } } private void parse_iCCP_chunk(PNGChunk chunk) { // String name = ""; // todo simplify this // byte b; // int textIndex = 0; // while ((b = chunk.getByte(textIndex++)) != 0) { // name += (char)b; // } } private void parse_pHYs_chunk(PNGChunk chunk) { xPixelsPerUnit = chunk.getInt4(0); yPixelsPerUnit = chunk.getInt4(4); unitSpecifier = chunk.getInt1(8); if (encodeParam != null) { encodeParam.setPhysicalDimension(xPixelsPerUnit, yPixelsPerUnit, unitSpecifier); } if (emitProperties) { properties.put("x_pixels_per_unit", xPixelsPerUnit); properties.put("y_pixels_per_unit", yPixelsPerUnit); properties.put("pixel_aspect_ratio", (float) xPixelsPerUnit / yPixelsPerUnit); if (unitSpecifier == 1) { properties.put("pixel_units", "Meters"); } else if (unitSpecifier != 0) { // Error -- unit specifier must be 0 or 1 String msg = PropertyUtil.getString("PNGImageDecoder12"); throw new RuntimeException(msg); } } } private void parse_sBIT_chunk(PNGChunk chunk) { if (colorType == PNG_COLOR_PALETTE) { significantBits = new int[3]; } else { significantBits = new int[inputBands]; } for (int i = 0; i < significantBits.length; i++) { int bits = chunk.getByte(i); int depth = (colorType == PNG_COLOR_PALETTE) ? 8 : bitDepth; if (bits <= 0 || bits > depth) { // Error -- significant bits must be between 0 and // image bit depth. String msg = PropertyUtil.getString("PNGImageDecoder13"); throw new RuntimeException(msg); } significantBits[i] = bits; } if (encodeParam != null) { encodeParam.setSignificantBits(significantBits); } if (emitProperties) { properties.put("significant_bits", significantBits); } } private void parse_sRGB_chunk(PNGChunk chunk) { sRGBRenderingIntent = chunk.getByte(0); // The presence of an sRGB chunk implies particular // settings for gamma and chroma. fileGamma = 45455 / 100000.0F; chromaticity = new float[8]; chromaticity[0] = 31270 / 10000.0F; chromaticity[1] = 32900 / 10000.0F; chromaticity[2] = 64000 / 10000.0F; chromaticity[3] = 33000 / 10000.0F; chromaticity[4] = 30000 / 10000.0F; chromaticity[5] = 60000 / 10000.0F; chromaticity[6] = 15000 / 10000.0F; chromaticity[7] = 6000 / 10000.0F; if (performGammaCorrection) { // File gamma is 1/2.2 float gamma = fileGamma * (displayExponent / userExponent); if (encodeParam != null) { encodeParam.setGamma(gamma); encodeParam.setChromaticity(chromaticity); } if (emitProperties) { properties.put("gamma", gamma); properties.put("white_point_x", chromaticity[0]); properties.put("white_point_y", chromaticity[1]); properties.put("red_x", chromaticity[2]); properties.put("red_y", chromaticity[3]); properties.put("green_x", chromaticity[4]); properties.put("green_y", chromaticity[5]); properties.put("blue_x", chromaticity[6]); properties.put("blue_y", chromaticity[7]); } } } private void parse_tEXt_chunk(PNGChunk chunk) { byte b; StringBuffer key = new StringBuffer(); int textIndex = 0; while ((b = chunk.getByte(textIndex++)) != 0) { key.append((char)b); } StringBuilder value = new StringBuilder(); for (int i = textIndex; i < chunk.getLength(); i++) { value.append((char)chunk.getByte(i)); } textKeys.add(key.toString()); textStrings.add(value.toString()); } private void parse_tIME_chunk(PNGChunk chunk) { int year = chunk.getInt2(0); int month = chunk.getInt1(2) - 1; int day = chunk.getInt1(3); int hour = chunk.getInt1(4); int minute = chunk.getInt1(5); int second = chunk.getInt1(6); TimeZone gmt = TimeZone.getTimeZone("GMT"); GregorianCalendar cal = new GregorianCalendar(gmt); cal.set(year, month, day, hour, minute, second); Date date = cal.getTime(); if (encodeParam != null) { encodeParam.setModificationTime(date); } if (emitProperties) { properties.put("timestamp", date); } } private void parse_tRNS_chunk(PNGChunk chunk) { if (colorType == PNG_COLOR_PALETTE) { int entries = chunk.getLength(); if (entries > paletteEntries) { // Error -- mustn't have more alpha than RGB palette entries String msg = PropertyUtil.getString("PNGImageDecoder14"); throw new RuntimeException(msg); } // Load beginning of palette from the chunk alphaPalette = new byte[paletteEntries]; for (int i = 0; i < entries; i++) { alphaPalette[i] = chunk.getByte(i); } // Fill rest of palette with 255 for (int i = entries; i < paletteEntries; i++) { alphaPalette[i] = (byte)255; } if (!suppressAlpha) { if (expandPalette) { postProcess = POST_PALETTE_TO_RGBA; outputBands = 4; } else { outputHasAlphaPalette = true; } } } else if (colorType == PNG_COLOR_GRAY) { grayTransparentAlpha = chunk.getInt2(0); if (!suppressAlpha) { if (bitDepth < 8) { output8BitGray = true; maxOpacity = 255; postProcess = POST_GRAY_LUT_ADD_TRANS; } else { postProcess = POST_ADD_GRAY_TRANS; } if (expandGrayAlpha) { outputBands = 4; postProcess |= POST_EXP_MASK; } else { outputBands = 2; } if (encodeParam != null) { ((PNGEncodeParam.Gray)encodeParam).setTransparentGray(grayTransparentAlpha); } } } else if (colorType == PNG_COLOR_RGB) { redTransparentAlpha = chunk.getInt2(0); greenTransparentAlpha = chunk.getInt2(2); blueTransparentAlpha = chunk.getInt2(4); if (!suppressAlpha) { outputBands = 4; postProcess = POST_ADD_RGB_TRANS; if (encodeParam != null) { int[] rgbTrans = new int[3]; rgbTrans[0] = redTransparentAlpha; rgbTrans[1] = greenTransparentAlpha; rgbTrans[2] = blueTransparentAlpha; ((PNGEncodeParam.RGB)encodeParam).setTransparentRGB(rgbTrans); } } } else if (colorType == PNG_COLOR_GRAY_ALPHA || colorType == PNG_COLOR_RGB_ALPHA) { // Error -- GA or RGBA image can't have a tRNS chunk. String msg = PropertyUtil.getString("PNGImageDecoder15"); throw new RuntimeException(msg); } } private void parse_zTXt_chunk(PNGChunk chunk) { int textIndex = 0; StringBuffer key = new StringBuffer(); byte b; while ((b = chunk.getByte(textIndex++)) != 0) { key.append((char)b); } // skip method textIndex++; StringBuffer value = new StringBuffer(); try { int length = chunk.getLength() - textIndex; byte[] data = chunk.getData(); InputStream cis = new ByteArrayInputStream(data, textIndex, length); InputStream iis = new InflaterInputStream(cis); int c; while ((c = iis.read()) != -1) { value.append((char)c); } ztextKeys.add(key.toString()); ztextStrings.add(value.toString()); } catch (Exception e) { e.printStackTrace(); } } private WritableRaster createRaster(int width, int height, int bands, int scanlineStride, int bitDepth) { DataBuffer dataBuffer; WritableRaster ras = null; Point origin = new Point(0, 0); if ((bitDepth < 8) && (bands == 1)) { dataBuffer = new DataBufferByte(height * scanlineStride); ras = Raster.createPackedRaster(dataBuffer, width, height, bitDepth, origin); } else if (bitDepth <= 8) { dataBuffer = new DataBufferByte(height * scanlineStride); ras = Raster.createInterleavedRaster(dataBuffer, width, height, scanlineStride, bands, bandOffsets[bands], origin); } else { dataBuffer = new DataBufferUShort(height * scanlineStride); ras = Raster.createInterleavedRaster(dataBuffer, width, height, scanlineStride, bands, bandOffsets[bands], origin); } return ras; } // Data filtering methods private static void decodeSubFilter(byte[] curr, int count, int bpp) { for (int i = bpp; i < count; i++) { int val; val = curr[i] & 0xff; val += curr[i - bpp] & 0xff; curr[i] = (byte)val; } } private static void decodeUpFilter(byte[] curr, byte[] prev, int count) { for (int i = 0; i < count; i++) { int raw = curr[i] & 0xff; int prior = prev[i] & 0xff; curr[i] = (byte)(raw + prior); } } private static void decodeAverageFilter(byte[] curr, byte[] prev, int count, int bpp) { int raw; int priorPixel; int priorRow; for (int i = 0; i < bpp; i++) { raw = curr[i] & 0xff; priorRow = prev[i] & 0xff; curr[i] = (byte)(raw + priorRow / 2); } for (int i = bpp; i < count; i++) { raw = curr[i] & 0xff; priorPixel = curr[i - bpp] & 0xff; priorRow = prev[i] & 0xff; curr[i] = (byte)(raw + (priorPixel + priorRow) / 2); } } private static void decodePaethFilter(byte[] curr, byte[] prev, int count, int bpp) { int raw; int priorPixel; int priorRow; int priorRowPixel; for (int i = 0; i < bpp; i++) { raw = curr[i] & 0xff; priorRow = prev[i] & 0xff; curr[i] = (byte)(raw + priorRow); } for (int i = bpp; i < count; i++) { raw = curr[i] & 0xff; priorPixel = curr[i - bpp] & 0xff; priorRow = prev[i] & 0xff; priorRowPixel = prev[i - bpp] & 0xff; curr[i] = (byte)(raw + PNGEncodeParam.paethPredictor(priorPixel, priorRow, priorRowPixel)); } } private void processPixels(int process, Raster src, WritableRaster dst, int xOffset, int step, int y, int width) { int srcX; int dstX; // Create an array suitable for holding one pixel int[] ps = src.getPixel(0, 0, (int[])null); int[] pd = dst.getPixel(0, 0, (int[])null); dstX = xOffset; switch (process) { case POST_NONE: for (srcX = 0; srcX < width; srcX++) { src.getPixel(srcX, 0, ps); dst.setPixel(dstX, y, ps); dstX += step; } break; case POST_GAMMA: for (srcX = 0; srcX < width; srcX++) { src.getPixel(srcX, 0, ps); for (int i = 0; i < inputBands; i++) { int x = ps[i]; ps[i] = gammaLut[x]; } dst.setPixel(dstX, y, ps); dstX += step; } break; case POST_GRAY_LUT: for (srcX = 0; srcX < width; srcX++) { src.getPixel(srcX, 0, ps); pd[0] = grayLut[ps[0]]; dst.setPixel(dstX, y, pd); dstX += step; } break; case POST_GRAY_LUT_ADD_TRANS: for (srcX = 0; srcX < width; srcX++) { src.getPixel(srcX, 0, ps); int val = ps[0]; pd[0] = grayLut[val]; if (val == grayTransparentAlpha) { pd[1] = 0; } else { pd[1] = maxOpacity; } dst.setPixel(dstX, y, pd); dstX += step; } break; case POST_PALETTE_TO_RGB: for (srcX = 0; srcX < width; srcX++) { src.getPixel(srcX, 0, ps); int val = ps[0]; pd[0] = redPalette[val]; pd[1] = greenPalette[val]; pd[2] = bluePalette[val]; dst.setPixel(dstX, y, pd); dstX += step; } break; case POST_PALETTE_TO_RGBA: for (srcX = 0; srcX < width; srcX++) { src.getPixel(srcX, 0, ps); int val = ps[0]; pd[0] = redPalette[val]; pd[1] = greenPalette[val]; pd[2] = bluePalette[val]; pd[3] = alphaPalette[val]; dst.setPixel(dstX, y, pd); dstX += step; } break; case POST_ADD_GRAY_TRANS: for (srcX = 0; srcX < width; srcX++) { src.getPixel(srcX, 0, ps); int val = ps[0]; if (performGammaCorrection) { val = gammaLut[val]; } pd[0] = val; if (val == grayTransparentAlpha) { pd[1] = 0; } else { pd[1] = maxOpacity; } dst.setPixel(dstX, y, pd); dstX += step; } break; case POST_ADD_RGB_TRANS: for (srcX = 0; srcX < width; srcX++) { src.getPixel(srcX, 0, ps); int r = ps[0]; int g = ps[1]; int b = ps[2]; if (performGammaCorrection) { pd[0] = gammaLut[r]; pd[1] = gammaLut[g]; pd[2] = gammaLut[b]; } else { pd[0] = r; pd[1] = g; pd[2] = b; } if ((r == redTransparentAlpha) && (g == greenTransparentAlpha) && (b == blueTransparentAlpha)) { pd[3] = 0; } else { pd[3] = maxOpacity; } dst.setPixel(dstX, y, pd); dstX += step; } break; case POST_REMOVE_GRAY_TRANS: for (srcX = 0; srcX < width; srcX++) { src.getPixel(srcX, 0, ps); int g = ps[0]; if (performGammaCorrection) { pd[0] = gammaLut[g]; } else { pd[0] = g; } dst.setPixel(dstX, y, pd); dstX += step; } break; case POST_REMOVE_RGB_TRANS: for (srcX = 0; srcX < width; srcX++) { src.getPixel(srcX, 0, ps); int r = ps[0]; int g = ps[1]; int b = ps[2]; if (performGammaCorrection) { pd[0] = gammaLut[r]; pd[1] = gammaLut[g]; pd[2] = gammaLut[b]; } else { pd[0] = r; pd[1] = g; pd[2] = b; } dst.setPixel(dstX, y, pd); dstX += step; } break; case POST_GAMMA_EXP: for (srcX = 0; srcX < width; srcX++) { src.getPixel(srcX, 0, ps); int val = ps[0]; int alpha = ps[1]; int gamma = gammaLut[val]; pd[0] = gamma; pd[1] = gamma; pd[2] = gamma; pd[3] = alpha; dst.setPixel(dstX, y, pd); dstX += step; } break; case POST_GRAY_ALPHA_EXP: for (srcX = 0; srcX < width; srcX++) { src.getPixel(srcX, 0, ps); int val = ps[0]; int alpha = ps[1]; pd[0] = val; pd[1] = val; pd[2] = val; pd[3] = alpha; dst.setPixel(dstX, y, pd); dstX += step; } break; case POST_ADD_GRAY_TRANS_EXP: for (srcX = 0; srcX < width; srcX++) { src.getPixel(srcX, 0, ps); int val = ps[0]; if (performGammaCorrection) { val = gammaLut[val]; } pd[0] = val; pd[1] = val; pd[2] = val; if (val == grayTransparentAlpha) { pd[3] = 0; } else { pd[3] = maxOpacity; } dst.setPixel(dstX, y, pd); dstX += step; } break; case POST_GRAY_LUT_ADD_TRANS_EXP: for (srcX = 0; srcX < width; srcX++) { src.getPixel(srcX, 0, ps); int val = ps[0]; int val2 = grayLut[val]; pd[0] = val2; pd[1] = val2; pd[2] = val2; if (val == grayTransparentAlpha) { pd[3] = 0; } else { pd[3] = maxOpacity; } dst.setPixel(dstX, y, pd); dstX += step; } break; } } /** * Reads in an image of a given size and returns it as a * WritableRaster. */ private void decodePass(WritableRaster imRas, int xOffset, int yOffset, int xStep, int yStep, int passWidth, int passHeight) { if ((passWidth == 0) || (passHeight == 0)) { return; } int bytesPerRow = (inputBands * passWidth * bitDepth + 7) / 8; int eltsPerRow = (bitDepth == 16) ? bytesPerRow / 2 : bytesPerRow; byte[] curr = new byte[bytesPerRow]; byte[] prior = new byte[bytesPerRow]; // Create a 1-row tall Raster to hold the data WritableRaster passRow = createRaster(passWidth, 1, inputBands, eltsPerRow, bitDepth); DataBuffer dataBuffer = passRow.getDataBuffer(); int type = dataBuffer.getDataType(); byte[] byteData = null; short[] shortData = null; if (type == DataBuffer.TYPE_BYTE) { byteData = ((DataBufferByte)dataBuffer).getData(); } else { shortData = ((DataBufferUShort)dataBuffer).getData(); } // Decode the (sub)image row-by-row int srcY; int dstY; for (srcY = 0, dstY = yOffset; srcY < passHeight; srcY++, dstY += yStep) { // Read the filter type byte and a row of data int filter = 0; try { filter = dataStream.read(); dataStream.readFully(curr, 0, bytesPerRow); } catch (Exception e) { e.printStackTrace(); } switch (filter) { case PNG_FILTER_NONE: break; case PNG_FILTER_SUB: decodeSubFilter(curr, bytesPerRow, bytesPerPixel); break; case PNG_FILTER_UP: decodeUpFilter(curr, prior, bytesPerRow); break; case PNG_FILTER_AVERAGE: decodeAverageFilter(curr, prior, bytesPerRow, bytesPerPixel); break; case PNG_FILTER_PAETH: decodePaethFilter(curr, prior, bytesPerRow, bytesPerPixel); break; default: // Error -- uknown filter type String msg = PropertyUtil.getString("PNGImageDecoder16"); throw new RuntimeException(msg); } // Copy data into passRow byte by byte if (bitDepth < 16) { System.arraycopy(curr, 0, byteData, 0, bytesPerRow); } else { int idx = 0; for (int j = 0; j < eltsPerRow; j++) { shortData[j] = (short)((curr[idx] << 8) | (curr[idx + 1] & 0xff)); idx += 2; } } processPixels(postProcess, passRow, imRas, xOffset, xStep, dstY, passWidth); // Swap curr and prior byte[] tmp = prior; prior = curr; curr = tmp; } } private void decodeImage(boolean useInterlacing) { if (!useInterlacing) { decodePass(theTile, 0, 0, 1, 1, width, height); } else { decodePass(theTile, 0, 0, 8, 8, (width + 7) / 8, (height + 7) / 8); decodePass(theTile, 4, 0, 8, 8, (width + 3) / 8, (height + 7) / 8); decodePass(theTile, 0, 4, 4, 8, (width + 3) / 4, (height + 3) / 8); decodePass(theTile, 2, 0, 4, 4, (width + 1) / 4, (height + 3) / 4); decodePass(theTile, 0, 2, 2, 4, (width + 1) / 2, (height + 1) / 4); decodePass(theTile, 1, 0, 2, 2, width / 2, (height + 1) / 2); decodePass(theTile, 0, 1, 1, 2, width, height / 2); } } // RenderedImage stuff public Raster getTile(int tileX, int tileY) { if (tileX != 0 || tileY != 0) { // Error -- bad tile requested String msg = PropertyUtil.getString("PNGImageDecoder17"); throw new IllegalArgumentException(msg); } return theTile; } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/codec/png/PNGImageEncoder.java0100644 0000000 0000000 00000103404 13777276623 031572 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: PNGImageEncoder.java 1804124 2017-08-04 14:13:54Z ssteiner $ */ package org.apache.xmlgraphics.image.codec.png; import java.awt.Rectangle; import java.awt.image.ColorModel; import java.awt.image.IndexColorModel; import java.awt.image.Raster; import java.awt.image.RenderedImage; import java.awt.image.SampleModel; import java.io.ByteArrayOutputStream; import java.io.DataOutput; import java.io.DataOutputStream; import java.io.FilterOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import java.util.TimeZone; import java.util.zip.Deflater; import java.util.zip.DeflaterOutputStream; import org.apache.xmlgraphics.image.codec.util.ImageEncoderImpl; import org.apache.xmlgraphics.image.codec.util.PropertyUtil; // CSOFF: ConstantName // CSOFF: InnerAssignment // CSOFF: LocalVariableName // CSOFF: MissingSwitchDefault // CSOFF: OperatorWrap // CSOFF: WhitespaceAround final class CRC { private CRC() { } private static int[] crcTable = new int[256]; static { // Initialize CRC table for (int n = 0; n < 256; n++) { int c = n; for (int k = 0; k < 8; k++) { if ((c & 1) == 1) { c = 0xedb88320 ^ (c >>> 1); } else { c >>>= 1; } crcTable[n] = c; } } } public static int updateCRC(int crc, byte[] data, int off, int len) { int c = crc; for (int n = 0; n < len; n++) { c = crcTable[(c ^ data[off + n]) & 0xff] ^ (c >>> 8); } return c; } } class ChunkStream extends OutputStream implements DataOutput { private String type; private ByteArrayOutputStream baos; private DataOutputStream dos; ChunkStream(String type) throws IOException { this.type = type; this.baos = new ByteArrayOutputStream(); this.dos = new DataOutputStream(baos); } @Override public void write(byte[] b) throws IOException { dos.write(b); } @Override public void write(byte[] b, int off, int len) throws IOException { dos.write(b, off, len); } @Override public void write(int b) throws IOException { dos.write(b); } public void writeBoolean(boolean v) throws IOException { dos.writeBoolean(v); } public void writeByte(int v) throws IOException { dos.writeByte(v); } public void writeBytes(String s) throws IOException { dos.writeBytes(s); } public void writeChar(int v) throws IOException { dos.writeChar(v); } public void writeChars(String s) throws IOException { dos.writeChars(s); } public void writeDouble(double v) throws IOException { dos.writeDouble(v); } public void writeFloat(float v) throws IOException { dos.writeFloat(v); } public void writeInt(int v) throws IOException { dos.writeInt(v); } public void writeLong(long v) throws IOException { dos.writeLong(v); } public void writeShort(int v) throws IOException { dos.writeShort(v); } public void writeUTF(String str) throws IOException { dos.writeUTF(str); } public void writeToStream(DataOutputStream output) throws IOException { byte[] typeSignature = new byte[4]; typeSignature[0] = (byte)type.charAt(0); typeSignature[1] = (byte)type.charAt(1); typeSignature[2] = (byte)type.charAt(2); typeSignature[3] = (byte)type.charAt(3); dos.flush(); baos.flush(); byte[] data = baos.toByteArray(); int len = data.length; output.writeInt(len); output.write(typeSignature); output.write(data, 0, len); int crc = 0xffffffff; crc = CRC.updateCRC(crc, typeSignature, 0, 4); crc = CRC.updateCRC(crc, data, 0, len); output.writeInt(crc ^ 0xffffffff); } /** {@inheritDoc} */ @Override public void close() throws IOException { if (baos != null) { baos.close(); baos = null; } if (dos != null) { dos.close(); dos = null; } } } class IDATOutputStream extends FilterOutputStream { private static final byte[] TYPE_SIGNATURE = {(byte)'I', (byte)'D', (byte)'A', (byte)'T'}; private int bytesWritten; private int segmentLength; private byte[] buffer; public IDATOutputStream(OutputStream output, int segmentLength) { super(output); this.segmentLength = segmentLength; this.buffer = new byte[segmentLength]; } @Override public void close() throws IOException { flush(); } private void writeInt(int x) throws IOException { out.write(x >> 24); out.write((x >> 16) & 0xff); out.write((x >> 8) & 0xff); out.write(x & 0xff); } @Override public void flush() throws IOException { if (bytesWritten == 0) { return; } // Length writeInt(bytesWritten); // 'IDAT' signature out.write(TYPE_SIGNATURE); // Data out.write(buffer, 0, bytesWritten); int crc = 0xffffffff; crc = CRC.updateCRC(crc, TYPE_SIGNATURE, 0, 4); crc = CRC.updateCRC(crc, buffer, 0, bytesWritten); // CRC writeInt(crc ^ 0xffffffff); // Reset buffer bytesWritten = 0; } @Override public void write(byte[] b) throws IOException { this.write(b, 0, b.length); } @Override public void write(byte[] b, int off, int len) throws IOException { while (len > 0) { int bytes = Math.min(segmentLength - bytesWritten, len); System.arraycopy(b, off, buffer, bytesWritten, bytes); off += bytes; len -= bytes; bytesWritten += bytes; if (bytesWritten == segmentLength) { flush(); } } } @Override public void write(int b) throws IOException { buffer[bytesWritten++] = (byte)b; if (bytesWritten == segmentLength) { flush(); } } } /** * An ImageEncoder for the PNG file format. * * @since EA4 */ public class PNGImageEncoder extends ImageEncoderImpl { private static final int PNG_COLOR_GRAY = 0; private static final int PNG_COLOR_RGB = 2; private static final int PNG_COLOR_PALETTE = 3; private static final int PNG_COLOR_GRAY_ALPHA = 4; private static final int PNG_COLOR_RGB_ALPHA = 6; private static final byte[] MAGIC = { (byte)137, (byte) 80, (byte) 78, (byte) 71, (byte) 13, (byte) 10, (byte) 26, (byte) 10 }; private PNGEncodeParam param; private RenderedImage image; private int width; private int height; private int bitDepth; private int bitShift; private int numBands; private int colorType; private int bpp; // bytes per pixel, rounded up private boolean skipAlpha; private boolean compressGray; private boolean interlace; private byte[] redPalette; private byte[] greenPalette; private byte[] bluePalette; private byte[] alphaPalette; private DataOutputStream dataOutput; public PNGImageEncoder(OutputStream output, PNGEncodeParam param) { super(output, param); if (param != null) { this.param = param; } this.dataOutput = new DataOutputStream(output); } private void writeMagic() throws IOException { dataOutput.write(MAGIC); } private void writeIHDR() throws IOException { ChunkStream cs = new ChunkStream("IHDR"); try { cs.writeInt(width); cs.writeInt(height); cs.writeByte((byte)bitDepth); cs.writeByte((byte)colorType); cs.writeByte((byte)0); cs.writeByte((byte)0); cs.writeByte(interlace ? (byte)1 : (byte)0); cs.writeToStream(dataOutput); } finally { cs.close(); } } private byte[] prevRow; private byte[] currRow; private byte[][] filteredRows; private static int clamp(int val, int maxValue) { return (val > maxValue) ? maxValue : val; } private void encodePass(OutputStream os, Raster ras, int xOffset, int yOffset, int xSkip, int ySkip) throws IOException { int minX = ras.getMinX(); int minY = ras.getMinY(); int width = ras.getWidth(); int height = ras.getHeight(); xOffset *= numBands; xSkip *= numBands; int samplesPerByte = 8 / bitDepth; int numSamples = width * numBands; int[] samples = new int[numSamples]; int pixels = (numSamples - xOffset + xSkip - 1) / xSkip; int bytesPerRow = pixels * numBands; if (bitDepth < 8) { bytesPerRow = (bytesPerRow + samplesPerByte - 1) / samplesPerByte; } else if (bitDepth == 16) { bytesPerRow *= 2; } if (bytesPerRow == 0) { return; } currRow = new byte[bytesPerRow + bpp]; prevRow = new byte[bytesPerRow + bpp]; filteredRows = new byte[5][bytesPerRow + bpp]; int maxValue = (1 << bitDepth) - 1; for (int row = minY + yOffset; row < minY + height; row += ySkip) { ras.getPixels(minX, row, width, 1, samples); if (compressGray) { int shift = 8 - bitDepth; for (int i = 0; i < width; i++) { samples[i] >>= shift; } } int count = bpp; // leave first 'bpp' bytes zero int pos = 0; int tmp = 0; switch (bitDepth) { case 1: case 2: case 4: // Image can only have a single band int mask = samplesPerByte - 1; for (int s = xOffset; s < numSamples; s += xSkip) { int val = clamp(samples[s] >> bitShift, maxValue); tmp = (tmp << bitDepth) | val; if (pos++ == mask) { currRow[count++] = (byte)tmp; tmp = 0; pos = 0; } } // Left shift the last byte if (pos != 0) { tmp <<= (samplesPerByte - pos) * bitDepth; currRow[count++] = (byte)tmp; } break; case 8: for (int s = xOffset; s < numSamples; s += xSkip) { for (int b = 0; b < numBands; b++) { currRow[count++] = (byte)clamp(samples[s + b] >> bitShift, maxValue); } } break; case 16: for (int s = xOffset; s < numSamples; s += xSkip) { for (int b = 0; b < numBands; b++) { int val = clamp(samples[s + b] >> bitShift, maxValue); currRow[count++] = (byte)(val >> 8); currRow[count++] = (byte)(val & 0xff); } } break; } // Perform filtering int filterType = param.filterRow(currRow, prevRow, filteredRows, bytesPerRow, bpp); os.write(filterType); os.write(filteredRows[filterType], bpp, bytesPerRow); // Swap current and previous rows byte[] swap = currRow; currRow = prevRow; prevRow = swap; } } private void writeIDAT() throws IOException { IDATOutputStream ios = new IDATOutputStream(dataOutput, 8192); DeflaterOutputStream dos = new DeflaterOutputStream(ios, new Deflater(9)); // Future work - don't convert entire image to a Raster It // might seem that you could just call image.getData() but // 'BufferedImage.subImage' doesn't appear to set the Width // and height properly of the Child Raster, so the Raster // you get back here appears larger than it should. // This solves that problem by bounding the raster to the // image's bounds... Raster ras = image.getData(new Rectangle(image.getMinX(), image.getMinY(), image.getWidth(), image.getHeight())); // System.out.println("Image: [" + // image.getMinY() + ", " + // image.getMinX() + ", " + // image.getWidth() + ", " + // image.getHeight() + "]"); // System.out.println("Ras: [" + // ras.getMinX() + ", " + // ras.getMinY() + ", " + // ras.getWidth() + ", " + // ras.getHeight() + "]"); if (skipAlpha) { int numBands = ras.getNumBands() - 1; int[] bandList = new int[numBands]; for (int i = 0; i < numBands; i++) { bandList[i] = i; } ras = ras.createChild(0, 0, ras.getWidth(), ras.getHeight(), 0, 0, bandList); } if (interlace) { // Interlacing pass 1 encodePass(dos, ras, 0, 0, 8, 8); // Interlacing pass 2 encodePass(dos, ras, 4, 0, 8, 8); // Interlacing pass 3 encodePass(dos, ras, 0, 4, 4, 8); // Interlacing pass 4 encodePass(dos, ras, 2, 0, 4, 4); // Interlacing pass 5 encodePass(dos, ras, 0, 2, 2, 4); // Interlacing pass 6 encodePass(dos, ras, 1, 0, 2, 2); // Interlacing pass 7 encodePass(dos, ras, 0, 1, 1, 2); } else { encodePass(dos, ras, 0, 0, 1, 1); } dos.finish(); dos.close(); ios.flush(); ios.close(); } private void writeIEND() throws IOException { ChunkStream cs = new ChunkStream("IEND"); try { cs.writeToStream(dataOutput); } finally { cs.close(); } } private static final float[] SRGB_CHROMA = { 0.31270F, 0.329F, 0.64F, 0.33F, 0.3F, 0.6F, 0.15F, 0.06F }; private void writeCHRM() throws IOException { if (param.isChromaticitySet() || param.isSRGBIntentSet()) { ChunkStream cs = new ChunkStream("cHRM"); try { float[] chroma; if (!param.isSRGBIntentSet()) { chroma = param.getChromaticity(); } else { chroma = SRGB_CHROMA; // SRGB chromaticities } for (int i = 0; i < 8; i++) { cs.writeInt((int)(chroma[i] * 100000)); } cs.writeToStream(dataOutput); } finally { cs.close(); } } } private void writeGAMA() throws IOException { if (param.isGammaSet() || param.isSRGBIntentSet()) { ChunkStream cs = new ChunkStream("gAMA"); try { float gamma; if (!param.isSRGBIntentSet()) { gamma = param.getGamma(); } else { gamma = 1.0F / 2.2F; // SRGB gamma } // TD should include the .5 but causes regard to say // everything is different. cs.writeInt((int)(gamma * 100000/*+0.5*/)); cs.writeToStream(dataOutput); } finally { cs.close(); } } } private void writeICCP() throws IOException { if (param.isICCProfileDataSet()) { ChunkStream cs = new ChunkStream("iCCP"); try { byte[] iccProfileData = param.getICCProfileData(); cs.write(iccProfileData); cs.writeToStream(dataOutput); } finally { cs.close(); } } } private void writeSBIT() throws IOException { if (param.isSignificantBitsSet()) { ChunkStream cs = new ChunkStream("sBIT"); try { int[] significantBits = param.getSignificantBits(); for (int significantBit : significantBits) { cs.writeByte(significantBit); } cs.writeToStream(dataOutput); } finally { cs.close(); } } } private void writeSRGB() throws IOException { if (param.isSRGBIntentSet()) { ChunkStream cs = new ChunkStream("sRGB"); try { int intent = param.getSRGBIntent(); cs.write(intent); cs.writeToStream(dataOutput); } finally { cs.close(); } } } private void writePLTE() throws IOException { if (redPalette == null) { return; } ChunkStream cs = new ChunkStream("PLTE"); try { for (int i = 0; i < redPalette.length; i++) { cs.writeByte(redPalette[i]); cs.writeByte(greenPalette[i]); cs.writeByte(bluePalette[i]); } cs.writeToStream(dataOutput); } finally { cs.close(); } } private void writeBKGD() throws IOException { if (param.isBackgroundSet()) { ChunkStream cs = new ChunkStream("bKGD"); try { switch (colorType) { case PNG_COLOR_GRAY: case PNG_COLOR_GRAY_ALPHA: int gray = ((PNGEncodeParam.Gray)param).getBackgroundGray(); cs.writeShort(gray); break; case PNG_COLOR_PALETTE: int index = ((PNGEncodeParam.Palette)param).getBackgroundPaletteIndex(); cs.writeByte(index); break; case PNG_COLOR_RGB: case PNG_COLOR_RGB_ALPHA: int[] rgb = ((PNGEncodeParam.RGB)param).getBackgroundRGB(); cs.writeShort(rgb[0]); cs.writeShort(rgb[1]); cs.writeShort(rgb[2]); break; } cs.writeToStream(dataOutput); } finally { cs.close(); } } } private void writeHIST() throws IOException { if (param.isPaletteHistogramSet()) { ChunkStream cs = new ChunkStream("hIST"); try { int[] hist = param.getPaletteHistogram(); for (int aHist : hist) { cs.writeShort(aHist); } cs.writeToStream(dataOutput); } finally { cs.close(); } } } private void writeTRNS() throws IOException { if (param.isTransparencySet() && (colorType != PNG_COLOR_GRAY_ALPHA) && (colorType != PNG_COLOR_RGB_ALPHA)) { ChunkStream cs = new ChunkStream("tRNS"); try { if (param instanceof PNGEncodeParam.Palette) { byte[] t = ((PNGEncodeParam.Palette)param).getPaletteTransparency(); for (byte aT : t) { cs.writeByte(aT); } } else if (param instanceof PNGEncodeParam.Gray) { int t = ((PNGEncodeParam.Gray)param).getTransparentGray(); cs.writeShort(t); } else if (param instanceof PNGEncodeParam.RGB) { int[] t = ((PNGEncodeParam.RGB)param).getTransparentRGB(); cs.writeShort(t[0]); cs.writeShort(t[1]); cs.writeShort(t[2]); } cs.writeToStream(dataOutput); } finally { cs.close(); } } else if (colorType == PNG_COLOR_PALETTE) { int lastEntry = Math.min(255, alphaPalette.length - 1); int nonOpaque; for (nonOpaque = lastEntry; nonOpaque >= 0; nonOpaque--) { if (alphaPalette[nonOpaque] != (byte)255) { break; } } if (nonOpaque >= 0) { ChunkStream cs = new ChunkStream("tRNS"); try { for (int i = 0; i <= nonOpaque; i++) { cs.writeByte(alphaPalette[i]); } cs.writeToStream(dataOutput); } finally { cs.close(); } } } } private void writePHYS() throws IOException { if (param.isPhysicalDimensionSet()) { ChunkStream cs = new ChunkStream("pHYs"); try { int[] dims = param.getPhysicalDimension(); cs.writeInt(dims[0]); cs.writeInt(dims[1]); cs.writeByte((byte)dims[2]); cs.writeToStream(dataOutput); } finally { cs.close(); } } } private void writeSPLT() throws IOException { if (param.isSuggestedPaletteSet()) { ChunkStream cs = new ChunkStream("sPLT"); try { System.out.println("sPLT not supported yet."); cs.writeToStream(dataOutput); } finally { cs.close(); } } } private void writeTIME() throws IOException { if (param.isModificationTimeSet()) { ChunkStream cs = new ChunkStream("tIME"); try { Date date = param.getModificationTime(); TimeZone gmt = TimeZone.getTimeZone("GMT"); GregorianCalendar cal = new GregorianCalendar(gmt); cal.setTime(date); int year = cal.get(Calendar.YEAR); int month = cal.get(Calendar.MONTH); int day = cal.get(Calendar.DAY_OF_MONTH); int hour = cal.get(Calendar.HOUR_OF_DAY); int minute = cal.get(Calendar.MINUTE); int second = cal.get(Calendar.SECOND); cs.writeShort(year); cs.writeByte(month + 1); cs.writeByte(day); cs.writeByte(hour); cs.writeByte(minute); cs.writeByte(second); cs.writeToStream(dataOutput); } finally { cs.close(); } } } private void writeTEXT() throws IOException { if (param.isTextSet()) { String[] text = param.getText(); for (int i = 0; i < text.length / 2; i++) { byte[] keyword = text[2 * i].getBytes("UTF-8"); byte[] value = text[2 * i + 1].getBytes("UTF-8"); ChunkStream cs = new ChunkStream("tEXt"); try { cs.write(keyword, 0, Math.min(keyword.length, 79)); cs.write(0); cs.write(value); cs.writeToStream(dataOutput); } finally { cs.close(); } } } } private void writeZTXT() throws IOException { if (param.isCompressedTextSet()) { String[] text = param.getCompressedText(); for (int i = 0; i < text.length / 2; i++) { byte[] keyword = text[2 * i].getBytes("UTF-8"); byte[] value = text[2 * i + 1].getBytes("UTF-8"); ChunkStream cs = new ChunkStream("zTXt"); try { cs.write(keyword, 0, Math.min(keyword.length, 79)); cs.write(0); cs.write(0); DeflaterOutputStream dos = new DeflaterOutputStream(cs); try { dos.write(value); dos.finish(); } finally { dos.close(); } cs.writeToStream(dataOutput); } finally { cs.close(); } } } } private void writePrivateChunks() throws IOException { int numChunks = param.getNumPrivateChunks(); for (int i = 0; i < numChunks; i++) { String type = param.getPrivateChunkType(i); byte[] data = param.getPrivateChunkData(i); ChunkStream cs = new ChunkStream(type); try { cs.write(data); cs.writeToStream(dataOutput); } finally { cs.close(); } } } /** * Analyzes a set of palettes and determines if it can be expressed * as a standard set of gray values, with zero or one values being * fully transparent and the rest being fully opaque. If it * is possible to express the data thusly, the method returns * a suitable instance of PNGEncodeParam.Gray; otherwise it * returns null. */ private PNGEncodeParam.Gray createGrayParam(byte[] redPalette, byte[] greenPalette, byte[] bluePalette, byte[] alphaPalette) { PNGEncodeParam.Gray param = new PNGEncodeParam.Gray(); int numTransparent = 0; int grayFactor = 255 / ((1 << bitDepth) - 1); int entries = 1 << bitDepth; for (int i = 0; i < entries; i++) { byte red = redPalette[i]; if ((red != i * grayFactor) || (red != greenPalette[i]) || (red != bluePalette[i])) { return null; } // All alphas must be 255 except at most 1 can be 0 byte alpha = alphaPalette[i]; if (alpha == (byte)0) { param.setTransparentGray(i); ++numTransparent; if (numTransparent > 1) { return null; } } else if (alpha != (byte)255) { return null; } } return param; } /** * This method encodes a RenderedImage into PNG. * The stream into which the PNG is dumped is not closed at * the end of the operation, this should be done if needed * by the caller of this method. */ @Override public void encode(RenderedImage im) throws IOException { this.image = im; this.width = image.getWidth(); this.height = image.getHeight(); SampleModel sampleModel = image.getSampleModel(); int[] sampleSize = sampleModel.getSampleSize(); // Set bitDepth to a sentinel value this.bitDepth = -1; this.bitShift = 0; // Allow user to override the bit depth of gray images if (param instanceof PNGEncodeParam.Gray) { PNGEncodeParam.Gray paramg = (PNGEncodeParam.Gray)param; if (paramg.isBitDepthSet()) { this.bitDepth = paramg.getBitDepth(); } if (paramg.isBitShiftSet()) { this.bitShift = paramg.getBitShift(); } } // Get bit depth from image if not set in param if (this.bitDepth == -1) { // Get bit depth from channel 0 of the image this.bitDepth = sampleSize[0]; // Ensure all channels have the same bit depth for (int i = 1; i < sampleSize.length; i++) { if (sampleSize[i] != bitDepth) { throw new RuntimeException(PropertyUtil.getString("PNGImageEncoder0")); } } // Round bit depth up to a power of 2 if (bitDepth > 2 && bitDepth < 4) { bitDepth = 4; } else if (bitDepth > 4 && bitDepth < 8) { bitDepth = 8; } else if (bitDepth > 8 && bitDepth < 16) { bitDepth = 16; } else if (bitDepth > 16) { throw new RuntimeException(PropertyUtil.getString("PNGImageEncoder1")); } } this.numBands = sampleModel.getNumBands(); this.bpp = numBands * ((bitDepth == 16) ? 2 : 1); ColorModel colorModel = image.getColorModel(); if (colorModel instanceof IndexColorModel) { if (bitDepth < 1 || bitDepth > 8) { throw new RuntimeException(PropertyUtil.getString("PNGImageEncoder2")); } if (sampleModel.getNumBands() != 1) { throw new RuntimeException(PropertyUtil.getString("PNGImageEncoder3")); } IndexColorModel icm = (IndexColorModel)colorModel; int size = icm.getMapSize(); redPalette = new byte[size]; greenPalette = new byte[size]; bluePalette = new byte[size]; alphaPalette = new byte[size]; icm.getReds(redPalette); icm.getGreens(greenPalette); icm.getBlues(bluePalette); icm.getAlphas(alphaPalette); this.bpp = 1; if (param == null) { param = createGrayParam(redPalette, greenPalette, bluePalette, alphaPalette); } // If param is still null, it can't be expressed as gray if (param == null) { param = new PNGEncodeParam.Palette(); } if (param instanceof PNGEncodeParam.Palette) { // If palette not set in param, create one from the ColorModel. PNGEncodeParam.Palette parami = (PNGEncodeParam.Palette)param; if (parami.isPaletteSet()) { int[] palette = parami.getPalette(); size = palette.length / 3; int index = 0; for (int i = 0; i < size; i++) { redPalette[i] = (byte)palette[index++]; greenPalette[i] = (byte)palette[index++]; bluePalette[i] = (byte)palette[index++]; alphaPalette[i] = (byte)255; } } this.colorType = PNG_COLOR_PALETTE; } else if (param instanceof PNGEncodeParam.Gray) { redPalette = greenPalette = bluePalette = alphaPalette = null; this.colorType = PNG_COLOR_GRAY; } else { throw new RuntimeException(PropertyUtil.getString("PNGImageEncoder4")); } } else if (numBands == 1) { if (param == null) { param = new PNGEncodeParam.Gray(); } this.colorType = PNG_COLOR_GRAY; } else if (numBands == 2) { if (param == null) { param = new PNGEncodeParam.Gray(); } if (param.isTransparencySet()) { skipAlpha = true; numBands = 1; if ((sampleSize[0] == 8) && (bitDepth < 8)) { compressGray = true; } bpp = (bitDepth == 16) ? 2 : 1; this.colorType = PNG_COLOR_GRAY; } else { if (this.bitDepth < 8) { this.bitDepth = 8; } this.colorType = PNG_COLOR_GRAY_ALPHA; } } else if (numBands == 3) { if (param == null) { param = new PNGEncodeParam.RGB(); } this.colorType = PNG_COLOR_RGB; } else if (numBands == 4) { if (param == null) { param = new PNGEncodeParam.RGB(); } if (param.isTransparencySet()) { skipAlpha = true; numBands = 3; bpp = (bitDepth == 16) ? 6 : 3; this.colorType = PNG_COLOR_RGB; } else { this.colorType = PNG_COLOR_RGB_ALPHA; } } interlace = param.getInterlacing(); writeMagic(); writeIHDR(); writeCHRM(); writeGAMA(); writeICCP(); writeSBIT(); writeSRGB(); writePLTE(); writeHIST(); writeTRNS(); writeBKGD(); writePHYS(); writeSPLT(); writeTIME(); writeTEXT(); writeZTXT(); writePrivateChunks(); writeIDAT(); writeIEND(); dataOutput.flush(); dataOutput.close(); } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/codec/png/PNGRed.java0100644 0000000 0000000 00000175074 13777276623 027776 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: PNGRed.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.image.codec.png; import java.awt.Color; import java.awt.Point; import java.awt.Rectangle; import java.awt.Transparency; import java.awt.color.ColorSpace; import java.awt.image.ColorModel; import java.awt.image.ComponentColorModel; import java.awt.image.DataBuffer; import java.awt.image.DataBufferByte; import java.awt.image.DataBufferUShort; import java.awt.image.IndexColorModel; import java.awt.image.Raster; import java.awt.image.SampleModel; import java.awt.image.WritableRaster; import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; import java.io.DataInputStream; import java.io.IOException; import java.io.InputStream; import java.io.SequenceInputStream; import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.GregorianCalendar; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.TimeZone; import java.util.zip.Inflater; import java.util.zip.InflaterInputStream; import org.apache.xmlgraphics.image.GraphicsUtil; import org.apache.xmlgraphics.image.codec.util.PropertyUtil; import org.apache.xmlgraphics.image.rendered.AbstractRed; import org.apache.xmlgraphics.image.rendered.CachableRed; // CSOFF: ConstantName // CSOFF: InnerAssignment // CSOFF: MethodName // CSOFF: MissingSwitchDefault // CSOFF: MultipleVariableDeclarations // CSOFF: NoWhitespaceAfter // CSOFF: OperatorWrap // CSOFF: WhitespaceAround /** * @version $Id: PNGRed.java 1732018 2016-02-24 04:51:06Z gadams $ */ public class PNGRed extends AbstractRed { static class PNGChunk { int length; int type; byte[] data; String typeString; public PNGChunk(int length, int type, byte[] data, int crc) { this.length = length; this.type = type; this.data = data; typeString = ""; typeString += (char)(type >> 24); typeString += (char)((type >> 16) & 0xff); typeString += (char)((type >> 8) & 0xff); typeString += (char)(type & 0xff); } public int getLength() { return length; } public int getType() { return type; } public String getTypeString() { return typeString; } public byte[] getData() { return data; } public byte getByte(int offset) { return data[offset]; } public int getInt1(int offset) { return data[offset] & 0xff; } public int getInt2(int offset) { return ((data[offset] & 0xff) << 8) | (data[offset + 1] & 0xff); } public int getInt4(int offset) { return ((data[offset] & 0xff) << 24) | ((data[offset + 1] & 0xff) << 16) | ((data[offset + 2] & 0xff) << 8) | (data[offset + 3] & 0xff); } public String getString4(int offset) { String s = ""; s += (char)data[offset]; s += (char)data[offset + 1]; s += (char)data[offset + 2]; s += (char)data[offset + 3]; return s; } public boolean isType(String typeName) { return typeString.equals(typeName); } } public static final int PNG_COLOR_GRAY = 0; public static final int PNG_COLOR_RGB = 2; public static final int PNG_COLOR_PALETTE = 3; public static final int PNG_COLOR_GRAY_ALPHA = 4; public static final int PNG_COLOR_RGB_ALPHA = 6; private static final String[] colorTypeNames = { "Grayscale", "Error", "Truecolor", "Index", "Grayscale with alpha", "Error", "Truecolor with alpha" }; public static final int PNG_FILTER_NONE = 0; public static final int PNG_FILTER_SUB = 1; public static final int PNG_FILTER_UP = 2; public static final int PNG_FILTER_AVERAGE = 3; public static final int PNG_FILTER_PAETH = 4; private int[][] bandOffsets = { null, { 0 }, // G { 0, 1 }, // GA in GA order { 0, 1, 2 }, // RGB in RGB order { 0, 1, 2, 3 } // RGBA in RGBA order }; private int bitDepth; private int colorType; private int compressionMethod; private int filterMethod; private int interlaceMethod; private int paletteEntries; private byte[] redPalette; private byte[] greenPalette; private byte[] bluePalette; private byte[] alphaPalette; private int bkgdRed; private int bkgdGreen; private int bkgdBlue; private int grayTransparentAlpha; private int redTransparentAlpha; private int greenTransparentAlpha; private int blueTransparentAlpha; private int maxOpacity; private int[] significantBits; // Parameter information // If true, the user wants destination alpha where applicable. private boolean suppressAlpha; // If true, perform palette lookup internally private boolean expandPalette; // If true, output < 8 bit gray images in 8 bit components format private boolean output8BitGray; // Create an alpha channel in the destination color model. private boolean outputHasAlphaPalette; // Perform gamma correction on the image private boolean performGammaCorrection; // Expand GA to GGGA for compatbility with Java2D private boolean expandGrayAlpha; // Produce an instance of PNGEncodeParam private boolean generateEncodeParam; // PNGDecodeParam controlling decode process private PNGDecodeParam decodeParam; // PNGEncodeParam to store file details in private PNGEncodeParam encodeParam; private boolean emitProperties = true; private float fileGamma = 45455 / 100000.0F; private float userExponent = 1.0F; private float displayExponent = 2.2F; private float[] chromaticity; private int sRGBRenderingIntent = -1; // Post-processing step implied by above parameters private int postProcess = POST_NONE; // Possible post-processing steps // Do nothing private static final int POST_NONE = 0; // Gamma correct only private static final int POST_GAMMA = 1; // Push gray values through grayLut to expand to 8 bits private static final int POST_GRAY_LUT = 2; // Push gray values through grayLut to expand to 8 bits, add alpha private static final int POST_GRAY_LUT_ADD_TRANS = 3; // Push palette value through R,G,B lookup tables private static final int POST_PALETTE_TO_RGB = 4; // Push palette value through R,G,B,A lookup tables private static final int POST_PALETTE_TO_RGBA = 5; // Add transparency to a given gray value (w/ optional gamma) private static final int POST_ADD_GRAY_TRANS = 6; // Add transparency to a given RGB value (w/ optional gamma) private static final int POST_ADD_RGB_TRANS = 7; // Remove the alpha channel from a gray image (w/ optional gamma) private static final int POST_REMOVE_GRAY_TRANS = 8; // Remove the alpha channel from an RGB image (w/optional gamma) private static final int POST_REMOVE_RGB_TRANS = 9; // Mask to add expansion of GA -> GGGA private static final int POST_EXP_MASK = 16; // Expand gray to G/G/G private static final int POST_GRAY_ALPHA_EXP = POST_NONE | POST_EXP_MASK; // Expand gray to G/G/G through a gamma lut private static final int POST_GAMMA_EXP = POST_GAMMA | POST_EXP_MASK; // Push gray values through grayLut to expand to 8 bits, expand, add alpha private static final int POST_GRAY_LUT_ADD_TRANS_EXP = POST_GRAY_LUT_ADD_TRANS | POST_EXP_MASK; // Add transparency to a given gray value, expand private static final int POST_ADD_GRAY_TRANS_EXP = POST_ADD_GRAY_TRANS | POST_EXP_MASK; private List streamVec = new ArrayList(); private DataInputStream dataStream; private int bytesPerPixel; // number of bytes per input pixel private int inputBands; private int outputBands; // Number of private chunks private int chunkIndex; private List textKeys = new ArrayList(); private List textStrings = new ArrayList(); private List ztextKeys = new ArrayList(); private List ztextStrings = new ArrayList(); private WritableRaster theTile; private Rectangle bounds; /** A Hashtable containing the image properties. */ private Map properties = new HashMap(); private int[] gammaLut; private void initGammaLut(int bits) { double exp = (double)userExponent / (fileGamma * displayExponent); int numSamples = 1 << bits; int maxOutSample = (bits == 16) ? 65535 : 255; gammaLut = new int[numSamples]; for (int i = 0; i < numSamples; i++) { double gbright = (double)i / (numSamples - 1); double gamma = Math.pow(gbright, exp); int igamma = (int)(gamma * maxOutSample + 0.5); if (igamma > maxOutSample) { igamma = maxOutSample; } gammaLut[i] = igamma; } } private final byte[][] expandBits = { null, { (byte)0x00, (byte)0xff }, { (byte)0x00, (byte)0x55, (byte)0xaa, (byte)0xff }, null, { (byte)0x00, (byte)0x11, (byte)0x22, (byte)0x33, (byte)0x44, (byte)0x55, (byte)0x66, (byte)0x77, (byte)0x88, (byte)0x99, (byte)0xaa, (byte)0xbb, (byte)0xcc, (byte)0xdd, (byte)0xee, (byte)0xff } }; private int[] grayLut; private void initGrayLut(int bits) { int len = 1 << bits; grayLut = new int[len]; if (performGammaCorrection) { System.arraycopy(gammaLut, 0, grayLut, 0, len); } else { for (int i = 0; i < len; i++) { grayLut[i] = expandBits[bits][i]; } } } public PNGRed(InputStream stream) throws IOException { this(stream, null); } public PNGRed(InputStream stream, PNGDecodeParam decodeParam) throws IOException { if (!stream.markSupported()) { stream = new BufferedInputStream(stream); } DataInputStream distream = new DataInputStream(stream); if (decodeParam == null) { decodeParam = new PNGDecodeParam(); } this.decodeParam = decodeParam; // Get parameter values this.suppressAlpha = decodeParam.getSuppressAlpha(); this.expandPalette = decodeParam.getExpandPalette(); this.output8BitGray = decodeParam.getOutput8BitGray(); this.expandGrayAlpha = decodeParam.getExpandGrayAlpha(); if (decodeParam.getPerformGammaCorrection()) { this.userExponent = decodeParam.getUserExponent(); this.displayExponent = decodeParam.getDisplayExponent(); performGammaCorrection = true; output8BitGray = true; } this.generateEncodeParam = decodeParam.getGenerateEncodeParam(); if (emitProperties) { properties.put("file_type", "PNG v. 1.0"); } long magic = distream.readLong(); if (magic != 0x89504e470d0a1a0aL) { String msg = PropertyUtil.getString("PNGImageDecoder0"); throw new RuntimeException(msg); } do { PNGChunk chunk; String chunkType = getChunkType(distream); if (chunkType.equals("IHDR")) { chunk = readChunk(distream); parse_IHDR_chunk(chunk); } else if (chunkType.equals("PLTE")) { chunk = readChunk(distream); parse_PLTE_chunk(chunk); } else if (chunkType.equals("IDAT")) { chunk = readChunk(distream); streamVec.add(new ByteArrayInputStream(chunk.getData())); } else if (chunkType.equals("IEND")) { chunk = readChunk(distream); try { parse_IEND_chunk(chunk); } catch (Exception e) { e.printStackTrace(); String msg = PropertyUtil.getString("PNGImageDecoder2"); throw new RuntimeException(msg); } break; // fall through to the bottom } else if (chunkType.equals("bKGD")) { chunk = readChunk(distream); parse_bKGD_chunk(chunk); } else if (chunkType.equals("cHRM")) { chunk = readChunk(distream); parse_cHRM_chunk(chunk); } else if (chunkType.equals("gAMA")) { chunk = readChunk(distream); parse_gAMA_chunk(chunk); } else if (chunkType.equals("hIST")) { chunk = readChunk(distream); parse_hIST_chunk(chunk); } else if (chunkType.equals("iCCP")) { chunk = readChunk(distream); } else if (chunkType.equals("pHYs")) { chunk = readChunk(distream); parse_pHYs_chunk(chunk); } else if (chunkType.equals("sBIT")) { chunk = readChunk(distream); parse_sBIT_chunk(chunk); } else if (chunkType.equals("sRGB")) { chunk = readChunk(distream); parse_sRGB_chunk(chunk); } else if (chunkType.equals("tEXt")) { chunk = readChunk(distream); parse_tEXt_chunk(chunk); } else if (chunkType.equals("tIME")) { chunk = readChunk(distream); parse_tIME_chunk(chunk); } else if (chunkType.equals("tRNS")) { chunk = readChunk(distream); parse_tRNS_chunk(chunk); } else if (chunkType.equals("zTXt")) { chunk = readChunk(distream); parse_zTXt_chunk(chunk); } else { chunk = readChunk(distream); // Output the chunk data in raw form String type = chunk.getTypeString(); byte[] data = chunk.getData(); if (encodeParam != null) { encodeParam.addPrivateChunk(type, data); } if (emitProperties) { String key = "chunk_" + chunkIndex++ + ':' + type; properties.put(key.toLowerCase(Locale.getDefault()), data); } } } while (true); // Final post-processing if (significantBits == null) { significantBits = new int[inputBands]; for (int i = 0; i < inputBands; i++) { significantBits[i] = bitDepth; } if (emitProperties) { properties.put("significant_bits", significantBits); } } distream.close(); stream.close(); } private static String getChunkType(DataInputStream distream) { try { distream.mark(8); /* int length = */ distream.readInt(); int type = distream.readInt(); distream.reset(); String typeString = "" + (char)((type >> 24) & 0xff) + (char)((type >> 16) & 0xff) + (char)((type >> 8) & 0xff) + (char)(type & 0xff); return typeString; } catch (Exception e) { e.printStackTrace(); return null; } } private static PNGChunk readChunk(DataInputStream distream) { try { int length = distream.readInt(); int type = distream.readInt(); byte[] data = new byte[length]; distream.readFully(data); int crc = distream.readInt(); return new PNGChunk(length, type, data, crc); } catch (Exception e) { e.printStackTrace(); return null; } } private void parse_IHDR_chunk(PNGChunk chunk) { int width = chunk.getInt4(0); int height = chunk.getInt4(4); bounds = new Rectangle(0, 0, width, height); bitDepth = chunk.getInt1(8); int validMask = (1 << 1) | (1 << 2) | (1 << 4) | (1 << 8) | (1 << 16); if (((1 << bitDepth) & validMask) == 0) { // bitDepth is not one of { 1, 2, 4, 8, 16 }: Error -- bad bit depth String msg = PropertyUtil.getString("PNGImageDecoder3"); throw new RuntimeException(msg); } maxOpacity = (1 << bitDepth) - 1; colorType = chunk.getInt1(9); if ((colorType != PNG_COLOR_GRAY) && (colorType != PNG_COLOR_RGB) && (colorType != PNG_COLOR_PALETTE) && (colorType != PNG_COLOR_GRAY_ALPHA) && (colorType != PNG_COLOR_RGB_ALPHA)) { System.out.println(PropertyUtil.getString("PNGImageDecoder4")); } if ((colorType == PNG_COLOR_RGB) && (bitDepth < 8)) { // Error -- RGB images must have 8 or 16 bits String msg = PropertyUtil.getString("PNGImageDecoder5"); throw new RuntimeException(msg); } if ((colorType == PNG_COLOR_PALETTE) && (bitDepth == 16)) { // Error -- palette images must have < 16 bits String msg = PropertyUtil.getString("PNGImageDecoder6"); throw new RuntimeException(msg); } if ((colorType == PNG_COLOR_GRAY_ALPHA) && (bitDepth < 8)) { // Error -- gray/alpha images must have >= 8 bits String msg = PropertyUtil.getString("PNGImageDecoder7"); throw new RuntimeException(msg); } if ((colorType == PNG_COLOR_RGB_ALPHA) && (bitDepth < 8)) { // Error -- RGB/alpha images must have >= 8 bits String msg = PropertyUtil.getString("PNGImageDecoder8"); throw new RuntimeException(msg); } if (emitProperties) { properties.put("color_type", colorTypeNames[colorType]); } if (generateEncodeParam) { if (colorType == PNG_COLOR_PALETTE) { encodeParam = new PNGEncodeParam.Palette(); } else if (colorType == PNG_COLOR_GRAY || colorType == PNG_COLOR_GRAY_ALPHA) { encodeParam = new PNGEncodeParam.Gray(); } else { encodeParam = new PNGEncodeParam.RGB(); } decodeParam.setEncodeParam(encodeParam); } if (encodeParam != null) { encodeParam.setBitDepth(bitDepth); } if (emitProperties) { properties.put("bit_depth", bitDepth); } if (performGammaCorrection) { // Assume file gamma is 1/2.2 unless we get a gAMA chunk float gamma = (1.0F / 2.2F) * (displayExponent / userExponent); if (encodeParam != null) { encodeParam.setGamma(gamma); } if (emitProperties) { properties.put("gamma", gamma); } } compressionMethod = chunk.getInt1(10); if (compressionMethod != 0) { // Error -- only know about compression method 0 String msg = PropertyUtil.getString("PNGImageDecoder9"); throw new RuntimeException(msg); } filterMethod = chunk.getInt1(11); if (filterMethod != 0) { // Error -- only know about filter method 0 String msg = PropertyUtil.getString("PNGImageDecoder10"); throw new RuntimeException(msg); } interlaceMethod = chunk.getInt1(12); if (interlaceMethod == 0) { if (encodeParam != null) { encodeParam.setInterlacing(false); } if (emitProperties) { properties.put("interlace_method", "None"); } } else if (interlaceMethod == 1) { if (encodeParam != null) { encodeParam.setInterlacing(true); } if (emitProperties) { properties.put("interlace_method", "Adam7"); } } else { // Error -- only know about Adam7 interlacing String msg = PropertyUtil.getString("PNGImageDecoder11"); throw new RuntimeException(msg); } bytesPerPixel = (bitDepth == 16) ? 2 : 1; switch (colorType) { case PNG_COLOR_GRAY: inputBands = 1; outputBands = 1; if (output8BitGray && (bitDepth < 8)) { postProcess = POST_GRAY_LUT; } else if (performGammaCorrection) { postProcess = POST_GAMMA; } else { postProcess = POST_NONE; } break; case PNG_COLOR_RGB: inputBands = 3; bytesPerPixel *= 3; outputBands = 3; if (performGammaCorrection) { postProcess = POST_GAMMA; } else { postProcess = POST_NONE; } break; case PNG_COLOR_PALETTE: inputBands = 1; bytesPerPixel = 1; outputBands = expandPalette ? 3 : 1; if (expandPalette) { postProcess = POST_PALETTE_TO_RGB; } else { postProcess = POST_NONE; } break; case PNG_COLOR_GRAY_ALPHA: inputBands = 2; bytesPerPixel *= 2; if (suppressAlpha) { outputBands = 1; postProcess = POST_REMOVE_GRAY_TRANS; } else { if (performGammaCorrection) { postProcess = POST_GAMMA; } else { postProcess = POST_NONE; } if (expandGrayAlpha) { postProcess |= POST_EXP_MASK; outputBands = 4; } else { outputBands = 2; } } break; case PNG_COLOR_RGB_ALPHA: inputBands = 4; bytesPerPixel *= 4; outputBands = (!suppressAlpha) ? 4 : 3; if (suppressAlpha) { postProcess = POST_REMOVE_RGB_TRANS; } else if (performGammaCorrection) { postProcess = POST_GAMMA; } else { postProcess = POST_NONE; } break; } } private void parse_IEND_chunk(PNGChunk chunk) throws Exception { // Store text strings int textLen = textKeys.size(); String[] textArray = new String[2 * textLen]; for (int i = 0; i < textLen; i++) { String key = (String)textKeys.get(i); String val = (String)textStrings.get(i); textArray[2 * i] = key; textArray[2 * i + 1] = val; if (emitProperties) { String uniqueKey = "text_" + i + ':' + key; properties.put(uniqueKey.toLowerCase(Locale.getDefault()), val); } } if (encodeParam != null) { encodeParam.setText(textArray); } // Store compressed text strings int ztextLen = ztextKeys.size(); String[] ztextArray = new String[2 * ztextLen]; for (int i = 0; i < ztextLen; i++) { String key = (String)ztextKeys.get(i); String val = (String)ztextStrings.get(i); ztextArray[2 * i] = key; ztextArray[2 * i + 1] = val; if (emitProperties) { String uniqueKey = "ztext_" + i + ':' + key; properties.put(uniqueKey.toLowerCase(Locale.getDefault()), val); } } if (encodeParam != null) { encodeParam.setCompressedText(ztextArray); } // Parse prior IDAT chunks InputStream seqStream = new SequenceInputStream(Collections.enumeration(streamVec)); InputStream infStream = new InflaterInputStream(seqStream, new Inflater()); dataStream = new DataInputStream(infStream); // Create an empty WritableRaster int depth = bitDepth; if ((colorType == PNG_COLOR_GRAY) && (bitDepth < 8) && output8BitGray) { depth = 8; } if ((colorType == PNG_COLOR_PALETTE) && expandPalette) { depth = 8; } int width = bounds.width; int height = bounds.height; int bytesPerRow = (outputBands * width * depth + 7) / 8; int scanlineStride = (depth == 16) ? (bytesPerRow / 2) : bytesPerRow; theTile = createRaster(width, height, outputBands, scanlineStride, depth); if (performGammaCorrection && (gammaLut == null)) { initGammaLut(bitDepth); } if ((postProcess == POST_GRAY_LUT) || (postProcess == POST_GRAY_LUT_ADD_TRANS) || (postProcess == POST_GRAY_LUT_ADD_TRANS_EXP)) { initGrayLut(bitDepth); } decodeImage(interlaceMethod == 1); // Free resources associated with compressed data. dataStream.close(); infStream.close(); seqStream.close(); streamVec = null; SampleModel sm = theTile.getSampleModel(); ColorModel cm; if ((colorType == PNG_COLOR_PALETTE) && !expandPalette) { if (outputHasAlphaPalette) { cm = new IndexColorModel(bitDepth, paletteEntries, redPalette, greenPalette, bluePalette, alphaPalette); } else { cm = new IndexColorModel(bitDepth, paletteEntries, redPalette, greenPalette, bluePalette); } } else if ((colorType == PNG_COLOR_GRAY) && (bitDepth < 8) && !output8BitGray) { byte[] palette = expandBits[bitDepth]; cm = new IndexColorModel(bitDepth, palette.length, palette, palette, palette); } else { cm = createComponentColorModel(sm); } init((CachableRed)null, bounds, cm, sm, 0, 0, properties); } private static final int[] GrayBits8 = { 8 }; private static final ComponentColorModel colorModelGray8 = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_GRAY), GrayBits8, false, false, Transparency.OPAQUE, DataBuffer.TYPE_BYTE); private static final int[] GrayAlphaBits8 = { 8, 8 }; private static final ComponentColorModel colorModelGrayAlpha8 = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_GRAY), GrayAlphaBits8, true, false, Transparency.TRANSLUCENT, DataBuffer.TYPE_BYTE); private static final int[] GrayBits16 = { 16 }; private static final ComponentColorModel colorModelGray16 = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_GRAY), GrayBits16, false, false, Transparency.OPAQUE, DataBuffer.TYPE_USHORT); private static final int[] GrayAlphaBits16 = { 16, 16 }; private static final ComponentColorModel colorModelGrayAlpha16 = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_GRAY), GrayAlphaBits16, true, false, Transparency.TRANSLUCENT, DataBuffer.TYPE_USHORT); private static final int[] GrayBits32 = { 32 }; private static final ComponentColorModel colorModelGray32 = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_GRAY), GrayBits32, false, false, Transparency.OPAQUE, DataBuffer.TYPE_INT); private static final int[] GrayAlphaBits32 = { 32, 32 }; private static final ComponentColorModel colorModelGrayAlpha32 = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_GRAY), GrayAlphaBits32, true, false, Transparency.TRANSLUCENT, DataBuffer.TYPE_INT); private static final int[] RGBBits8 = { 8, 8, 8 }; private static final ComponentColorModel colorModelRGB8 = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), RGBBits8, false, false, Transparency.OPAQUE, DataBuffer.TYPE_BYTE); private static final int[] RGBABits8 = { 8, 8, 8, 8 }; private static final ComponentColorModel colorModelRGBA8 = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), RGBABits8, true, false, Transparency.TRANSLUCENT, DataBuffer.TYPE_BYTE); private static final int[] RGBBits16 = { 16, 16, 16 }; private static final ComponentColorModel colorModelRGB16 = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), RGBBits16, false, false, Transparency.OPAQUE, DataBuffer.TYPE_USHORT); private static final int[] RGBABits16 = { 16, 16, 16, 16 }; private static final ComponentColorModel colorModelRGBA16 = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), RGBABits16, true, false, Transparency.TRANSLUCENT, DataBuffer.TYPE_USHORT); private static final int[] RGBBits32 = { 32, 32, 32 }; private static final ComponentColorModel colorModelRGB32 = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), RGBBits32, false, false, Transparency.OPAQUE, DataBuffer.TYPE_INT); private static final int[] RGBABits32 = { 32, 32, 32, 32 }; private static final ComponentColorModel colorModelRGBA32 = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), RGBABits32, true, false, Transparency.TRANSLUCENT, DataBuffer.TYPE_INT); /** * A convenience method to create an instance of * ComponentColorModel suitable for use with the * given SampleModel. The SampleModel * should have a data type of DataBuffer.TYPE_BYTE, * TYPE_USHORT, or TYPE_INT and between * 1 and 4 bands. Depending on the number of bands of the * SampleModel, either a gray, gray+alpha, rgb, or * rgb+alpha ColorModel is returned. */ public static ColorModel createComponentColorModel(SampleModel sm) { int type = sm.getDataType(); int bands = sm.getNumBands(); ComponentColorModel cm = null; if (type == DataBuffer.TYPE_BYTE) { switch (bands) { case 1: cm = colorModelGray8; break; case 2: cm = colorModelGrayAlpha8; break; case 3: cm = colorModelRGB8; break; case 4: cm = colorModelRGBA8; break; } } else if (type == DataBuffer.TYPE_USHORT) { switch (bands) { case 1: cm = colorModelGray16; break; case 2: cm = colorModelGrayAlpha16; break; case 3: cm = colorModelRGB16; break; case 4: cm = colorModelRGBA16; break; } } else if (type == DataBuffer.TYPE_INT) { switch (bands) { case 1: cm = colorModelGray32; break; case 2: cm = colorModelGrayAlpha32; break; case 3: cm = colorModelRGB32; break; case 4: cm = colorModelRGBA32; break; } } return cm; } private void parse_PLTE_chunk(PNGChunk chunk) { paletteEntries = chunk.getLength() / 3; redPalette = new byte[paletteEntries]; greenPalette = new byte[paletteEntries]; bluePalette = new byte[paletteEntries]; int pltIndex = 0; // gAMA chunk must precede PLTE chunk if (performGammaCorrection) { if (gammaLut == null) { initGammaLut(bitDepth == 16 ? 16 : 8); } for (int i = 0; i < paletteEntries; i++) { byte r = chunk.getByte(pltIndex++); byte g = chunk.getByte(pltIndex++); byte b = chunk.getByte(pltIndex++); redPalette[i] = (byte)gammaLut[r & 0xff]; greenPalette[i] = (byte)gammaLut[g & 0xff]; bluePalette[i] = (byte)gammaLut[b & 0xff]; } } else { for (int i = 0; i < paletteEntries; i++) { redPalette[i] = chunk.getByte(pltIndex++); greenPalette[i] = chunk.getByte(pltIndex++); bluePalette[i] = chunk.getByte(pltIndex++); } } } private void parse_bKGD_chunk(PNGChunk chunk) { switch (colorType) { case PNG_COLOR_PALETTE: int bkgdIndex = chunk.getByte(0) & 0xff; bkgdRed = redPalette[bkgdIndex] & 0xff; bkgdGreen = greenPalette[bkgdIndex] & 0xff; bkgdBlue = bluePalette[bkgdIndex] & 0xff; if (encodeParam != null) { ((PNGEncodeParam.Palette)encodeParam).setBackgroundPaletteIndex(bkgdIndex); } break; case PNG_COLOR_GRAY: case PNG_COLOR_GRAY_ALPHA: int bkgdGray = chunk.getInt2(0); bkgdRed = bkgdGreen = bkgdBlue = bkgdGray; if (encodeParam != null) { ((PNGEncodeParam.Gray)encodeParam).setBackgroundGray(bkgdGray); } break; case PNG_COLOR_RGB: case PNG_COLOR_RGB_ALPHA: bkgdRed = chunk.getInt2(0); bkgdGreen = chunk.getInt2(2); bkgdBlue = chunk.getInt2(4); int[] bkgdRGB = new int[3]; bkgdRGB[0] = bkgdRed; bkgdRGB[1] = bkgdGreen; bkgdRGB[2] = bkgdBlue; if (encodeParam != null) { ((PNGEncodeParam.RGB)encodeParam).setBackgroundRGB(bkgdRGB); } break; } if (emitProperties) { int r = 0; int g = 0; int b = 0; if ((colorType == PNG_COLOR_PALETTE) || (bitDepth == 8)) { r = bkgdRed; g = bkgdGreen; b = bkgdBlue; } else if (bitDepth < 8) { r = expandBits[bitDepth][bkgdRed]; g = expandBits[bitDepth][bkgdGreen]; b = expandBits[bitDepth][bkgdBlue]; } else if (bitDepth == 16) { r = bkgdRed >> 8; g = bkgdGreen >> 8; b = bkgdBlue >> 8; } properties.put("background_color", new Color(r, g, b)); } } private void parse_cHRM_chunk(PNGChunk chunk) { // If an sRGB chunk exists, ignore cHRM chunks if (sRGBRenderingIntent != -1) { return; } chromaticity = new float[8]; chromaticity[0] = chunk.getInt4(0) / 100000.0F; chromaticity[1] = chunk.getInt4(4) / 100000.0F; chromaticity[2] = chunk.getInt4(8) / 100000.0F; chromaticity[3] = chunk.getInt4(12) / 100000.0F; chromaticity[4] = chunk.getInt4(16) / 100000.0F; chromaticity[5] = chunk.getInt4(20) / 100000.0F; chromaticity[6] = chunk.getInt4(24) / 100000.0F; chromaticity[7] = chunk.getInt4(28) / 100000.0F; if (encodeParam != null) { encodeParam.setChromaticity(chromaticity); } if (emitProperties) { properties.put("white_point_x", chromaticity[0]); properties.put("white_point_y", chromaticity[1]); properties.put("red_x", chromaticity[2]); properties.put("red_y", chromaticity[3]); properties.put("green_x", chromaticity[4]); properties.put("green_y", chromaticity[5]); properties.put("blue_x", chromaticity[6]); properties.put("blue_y", chromaticity[7]); } } private void parse_gAMA_chunk(PNGChunk chunk) { // If an sRGB chunk exists, ignore gAMA chunks if (sRGBRenderingIntent != -1) { return; } fileGamma = chunk.getInt4(0) / 100000.0F; // System.out.println("Gamma: " + fileGamma); float exp = performGammaCorrection ? displayExponent / userExponent : 1.0F; if (encodeParam != null) { encodeParam.setGamma(fileGamma * exp); } if (emitProperties) { properties.put("gamma", fileGamma * exp); } } private void parse_hIST_chunk(PNGChunk chunk) { if (redPalette == null) { String msg = PropertyUtil.getString("PNGImageDecoder18"); throw new RuntimeException(msg); } int length = redPalette.length; int[] hist = new int[length]; for (int i = 0; i < length; i++) { hist[i] = chunk.getInt2(2 * i); } if (encodeParam != null) { encodeParam.setPaletteHistogram(hist); } } private void parse_pHYs_chunk(PNGChunk chunk) { int xPixelsPerUnit = chunk.getInt4(0); int yPixelsPerUnit = chunk.getInt4(4); int unitSpecifier = chunk.getInt1(8); if (encodeParam != null) { encodeParam.setPhysicalDimension(xPixelsPerUnit, yPixelsPerUnit, unitSpecifier); } if (emitProperties) { properties.put("x_pixels_per_unit", xPixelsPerUnit); properties.put("y_pixels_per_unit", yPixelsPerUnit); properties.put("pixel_aspect_ratio", (float) xPixelsPerUnit / yPixelsPerUnit); if (unitSpecifier == 1) { properties.put("pixel_units", "Meters"); } else if (unitSpecifier != 0) { // Error -- unit specifier must be 0 or 1 String msg = PropertyUtil.getString("PNGImageDecoder12"); throw new RuntimeException(msg); } } } private void parse_sBIT_chunk(PNGChunk chunk) { if (colorType == PNG_COLOR_PALETTE) { significantBits = new int[3]; } else { significantBits = new int[inputBands]; } for (int i = 0; i < significantBits.length; i++) { int bits = chunk.getByte(i); int depth = (colorType == PNG_COLOR_PALETTE) ? 8 : bitDepth; if (bits <= 0 || bits > depth) { // Error -- significant bits must be between 0 and // image bit depth. String msg = PropertyUtil.getString("PNGImageDecoder13"); throw new RuntimeException(msg); } significantBits[i] = bits; } if (encodeParam != null) { encodeParam.setSignificantBits(significantBits); } if (emitProperties) { properties.put("significant_bits", significantBits); } } private void parse_sRGB_chunk(PNGChunk chunk) { sRGBRenderingIntent = chunk.getByte(0); // The presence of an sRGB chunk implies particular // settings for gamma and chroma. fileGamma = 45455 / 100000.0F; chromaticity = new float[8]; chromaticity[0] = 31270 / 10000.0F; chromaticity[1] = 32900 / 10000.0F; chromaticity[2] = 64000 / 10000.0F; chromaticity[3] = 33000 / 10000.0F; chromaticity[4] = 30000 / 10000.0F; chromaticity[5] = 60000 / 10000.0F; chromaticity[6] = 15000 / 10000.0F; chromaticity[7] = 6000 / 10000.0F; if (performGammaCorrection) { // File gamma is 1/2.2 float gamma = fileGamma * (displayExponent / userExponent); if (encodeParam != null) { encodeParam.setGamma(gamma); encodeParam.setChromaticity(chromaticity); } if (emitProperties) { properties.put("gamma", gamma); properties.put("white_point_x", chromaticity[0]); properties.put("white_point_y", chromaticity[1]); properties.put("red_x", chromaticity[2]); properties.put("red_y", chromaticity[3]); properties.put("green_x", chromaticity[4]); properties.put("green_y", chromaticity[5]); properties.put("blue_x", chromaticity[6]); properties.put("blue_y", chromaticity[7]); } } } private void parse_tEXt_chunk(PNGChunk chunk) { StringBuffer key = new StringBuffer(); StringBuffer value = new StringBuffer(); byte b; int textIndex = 0; while ((b = chunk.getByte(textIndex++)) != 0) { key.append((char)b); } for (int i = textIndex; i < chunk.getLength(); i++) { value.append((char)chunk.getByte(i)); } textKeys.add(key.toString()); textStrings.add(value.toString()); } private void parse_tIME_chunk(PNGChunk chunk) { int year = chunk.getInt2(0); int month = chunk.getInt1(2) - 1; int day = chunk.getInt1(3); int hour = chunk.getInt1(4); int minute = chunk.getInt1(5); int second = chunk.getInt1(6); TimeZone gmt = TimeZone.getTimeZone("GMT"); GregorianCalendar cal = new GregorianCalendar(gmt); cal.set(year, month, day, hour, minute, second); Date date = cal.getTime(); if (encodeParam != null) { encodeParam.setModificationTime(date); } if (emitProperties) { properties.put("timestamp", date); } } private void parse_tRNS_chunk(PNGChunk chunk) { if (colorType == PNG_COLOR_PALETTE) { int entries = chunk.getLength(); if (entries > paletteEntries) { // Error -- mustn't have more alpha than RGB palette entries String msg = PropertyUtil.getString("PNGImageDecoder14"); throw new RuntimeException(msg); } // Load beginning of palette from the chunk alphaPalette = new byte[paletteEntries]; for (int i = 0; i < entries; i++) { alphaPalette[i] = chunk.getByte(i); } // Fill rest of palette with 255 for (int i = entries; i < paletteEntries; i++) { alphaPalette[i] = (byte)255; } if (!suppressAlpha) { if (expandPalette) { postProcess = POST_PALETTE_TO_RGBA; outputBands = 4; } else { outputHasAlphaPalette = true; } } } else if (colorType == PNG_COLOR_GRAY) { grayTransparentAlpha = chunk.getInt2(0); if (!suppressAlpha) { if (bitDepth < 8) { output8BitGray = true; maxOpacity = 255; postProcess = POST_GRAY_LUT_ADD_TRANS; } else { postProcess = POST_ADD_GRAY_TRANS; } if (expandGrayAlpha) { outputBands = 4; postProcess |= POST_EXP_MASK; } else { outputBands = 2; } if (encodeParam != null) { ((PNGEncodeParam.Gray)encodeParam).setTransparentGray(grayTransparentAlpha); } } } else if (colorType == PNG_COLOR_RGB) { redTransparentAlpha = chunk.getInt2(0); greenTransparentAlpha = chunk.getInt2(2); blueTransparentAlpha = chunk.getInt2(4); if (!suppressAlpha) { outputBands = 4; postProcess = POST_ADD_RGB_TRANS; if (encodeParam != null) { int[] rgbTrans = new int[3]; rgbTrans[0] = redTransparentAlpha; rgbTrans[1] = greenTransparentAlpha; rgbTrans[2] = blueTransparentAlpha; ((PNGEncodeParam.RGB)encodeParam).setTransparentRGB(rgbTrans); } } } else if (colorType == PNG_COLOR_GRAY_ALPHA || colorType == PNG_COLOR_RGB_ALPHA) { // Error -- GA or RGBA image can't have a tRNS chunk. String msg = PropertyUtil.getString("PNGImageDecoder15"); throw new RuntimeException(msg); } } private void parse_zTXt_chunk(PNGChunk chunk) { StringBuffer key = new StringBuffer(); StringBuffer value = new StringBuffer(); byte b; int textIndex = 0; while ((b = chunk.getByte(textIndex++)) != 0) { key.append((char)b); } // skip method textIndex++; try { int length = chunk.getLength() - textIndex; byte[] data = chunk.getData(); InputStream cis = new ByteArrayInputStream(data, textIndex, length); InputStream iis = new InflaterInputStream(cis); int c; while ((c = iis.read()) != -1) { value.append((char)c); } ztextKeys.add(key.toString()); ztextStrings.add(value.toString()); } catch (Exception e) { e.printStackTrace(); } } private WritableRaster createRaster(int width, int height, int bands, int scanlineStride, int bitDepth) { DataBuffer dataBuffer; WritableRaster ras = null; Point origin = new Point(0, 0); if ((bitDepth < 8) && (bands == 1)) { dataBuffer = new DataBufferByte(height * scanlineStride); ras = Raster.createPackedRaster(dataBuffer, width, height, bitDepth, origin); } else if (bitDepth <= 8) { dataBuffer = new DataBufferByte(height * scanlineStride); ras = Raster.createInterleavedRaster(dataBuffer, width, height, scanlineStride, bands, bandOffsets[bands], origin); } else { dataBuffer = new DataBufferUShort(height * scanlineStride); ras = Raster.createInterleavedRaster(dataBuffer, width, height, scanlineStride, bands, bandOffsets[bands], origin); } return ras; } // Data filtering methods private static void decodeSubFilter(byte[] curr, int count, int bpp) { for (int i = bpp; i < count; i++) { int val; val = curr[i] & 0xff; val += curr[i - bpp] & 0xff; curr[i] = (byte)val; } } private static void decodeUpFilter(byte[] curr, byte[] prev, int count) { for (int i = 0; i < count; i++) { int raw = curr[i] & 0xff; int prior = prev[i] & 0xff; curr[i] = (byte)(raw + prior); } } private static void decodeAverageFilter(byte[] curr, byte[] prev, int count, int bpp) { for (int i = 0; i < bpp; i++) { int raw = curr[i] & 0xff; int priorRow = prev[i] & 0xff; curr[i] = (byte)(raw + priorRow / 2); } for (int i = bpp; i < count; i++) { int raw = curr[i] & 0xff; int priorPixel = curr[i - bpp] & 0xff; int priorRow = prev[i] & 0xff; curr[i] = (byte)(raw + (priorPixel + priorRow) / 2); } } private static int paethPredictor(int a, int b, int c) { int p = a + b - c; int pa = Math.abs(p - a); int pb = Math.abs(p - b); int pc = Math.abs(p - c); if ((pa <= pb) && (pa <= pc)) { return a; } else if (pb <= pc) { return b; } else { return c; } } private static void decodePaethFilter(byte[] curr, byte[] prev, int count, int bpp) { int priorPixel; int priorRowPixel; for (int i = 0; i < bpp; i++) { int raw = curr[i] & 0xff; int priorRow = prev[i] & 0xff; curr[i] = (byte)(raw + priorRow); } for (int i = bpp; i < count; i++) { int raw = curr[i] & 0xff; priorPixel = curr[i - bpp] & 0xff; int priorRow = prev[i] & 0xff; priorRowPixel = prev[i - bpp] & 0xff; curr[i] = (byte)(raw + paethPredictor(priorPixel, priorRow, priorRowPixel)); } } private void processPixels(int process, Raster src, WritableRaster dst, int xOffset, int step, int y, int width) { int srcX; int dstX; // Create an array suitable for holding one pixel int[] ps = src.getPixel(0, 0, (int[])null); int[] pd = dst.getPixel(0, 0, (int[])null); dstX = xOffset; switch (process) { case POST_NONE: for (srcX = 0; srcX < width; srcX++) { src.getPixel(srcX, 0, ps); dst.setPixel(dstX, y, ps); dstX += step; } break; case POST_GAMMA: for (srcX = 0; srcX < width; srcX++) { src.getPixel(srcX, 0, ps); for (int i = 0; i < inputBands; i++) { int x = ps[i]; ps[i] = gammaLut[x]; } dst.setPixel(dstX, y, ps); dstX += step; } break; case POST_GRAY_LUT: for (srcX = 0; srcX < width; srcX++) { src.getPixel(srcX, 0, ps); pd[0] = grayLut[ps[0]]; dst.setPixel(dstX, y, pd); dstX += step; } break; case POST_GRAY_LUT_ADD_TRANS: for (srcX = 0; srcX < width; srcX++) { src.getPixel(srcX, 0, ps); int val = ps[0]; pd[0] = grayLut[val]; if (val == grayTransparentAlpha) { pd[1] = 0; } else { pd[1] = maxOpacity; } dst.setPixel(dstX, y, pd); dstX += step; } break; case POST_PALETTE_TO_RGB: for (srcX = 0; srcX < width; srcX++) { src.getPixel(srcX, 0, ps); int val = ps[0]; pd[0] = redPalette[val]; pd[1] = greenPalette[val]; pd[2] = bluePalette[val]; dst.setPixel(dstX, y, pd); dstX += step; } break; case POST_PALETTE_TO_RGBA: for (srcX = 0; srcX < width; srcX++) { src.getPixel(srcX, 0, ps); int val = ps[0]; pd[0] = redPalette[val]; pd[1] = greenPalette[val]; pd[2] = bluePalette[val]; pd[3] = alphaPalette[val]; dst.setPixel(dstX, y, pd); dstX += step; } break; case POST_ADD_GRAY_TRANS: for (srcX = 0; srcX < width; srcX++) { src.getPixel(srcX, 0, ps); int val = ps[0]; if (performGammaCorrection) { val = gammaLut[val]; } pd[0] = val; if (val == grayTransparentAlpha) { pd[1] = 0; } else { pd[1] = maxOpacity; } dst.setPixel(dstX, y, pd); dstX += step; } break; case POST_ADD_RGB_TRANS: boolean flagGammaCorrection = performGammaCorrection; // local is cheaper int[] workGammaLut = gammaLut; for (srcX = 0; srcX < width; srcX++) { src.getPixel(srcX, 0, ps); int r = ps[0]; int g = ps[1]; int b = ps[2]; if (flagGammaCorrection) { pd[0] = workGammaLut[r]; pd[1] = workGammaLut[g]; pd[2] = workGammaLut[b]; } else { pd[0] = r; pd[1] = g; pd[2] = b; } if ((r == redTransparentAlpha) && (g == greenTransparentAlpha) && (b == blueTransparentAlpha)) { pd[3] = 0; } else { pd[3] = maxOpacity; } dst.setPixel(dstX, y, pd); dstX += step; } break; case POST_REMOVE_GRAY_TRANS: for (srcX = 0; srcX < width; srcX++) { src.getPixel(srcX, 0, ps); int g = ps[0]; if (performGammaCorrection) { pd[0] = gammaLut[g]; } else { pd[0] = g; } dst.setPixel(dstX, y, pd); dstX += step; } break; case POST_REMOVE_RGB_TRANS: for (srcX = 0; srcX < width; srcX++) { src.getPixel(srcX, 0, ps); int r = ps[0]; int g = ps[1]; int b = ps[2]; if (performGammaCorrection) { pd[0] = gammaLut[r]; pd[1] = gammaLut[g]; pd[2] = gammaLut[b]; } else { pd[0] = r; pd[1] = g; pd[2] = b; } dst.setPixel(dstX, y, pd); dstX += step; } break; case POST_GAMMA_EXP: for (srcX = 0; srcX < width; srcX++) { src.getPixel(srcX, 0, ps); int val = ps[0]; int alpha = ps[1]; int gamma = gammaLut[val]; pd[0] = gamma; pd[1] = gamma; pd[2] = gamma; pd[3] = alpha; dst.setPixel(dstX, y, pd); dstX += step; } break; case POST_GRAY_ALPHA_EXP: for (srcX = 0; srcX < width; srcX++) { src.getPixel(srcX, 0, ps); int val = ps[0]; int alpha = ps[1]; pd[0] = val; pd[1] = val; pd[2] = val; pd[3] = alpha; dst.setPixel(dstX, y, pd); dstX += step; } break; case POST_ADD_GRAY_TRANS_EXP: for (srcX = 0; srcX < width; srcX++) { src.getPixel(srcX, 0, ps); int val = ps[0]; if (performGammaCorrection) { val = gammaLut[val]; } pd[0] = val; pd[1] = val; pd[2] = val; if (val == grayTransparentAlpha) { pd[3] = 0; } else { pd[3] = maxOpacity; } dst.setPixel(dstX, y, pd); dstX += step; } break; case POST_GRAY_LUT_ADD_TRANS_EXP: for (srcX = 0; srcX < width; srcX++) { src.getPixel(srcX, 0, ps); int val = ps[0]; int val2 = grayLut[val]; pd[0] = val2; pd[1] = val2; pd[2] = val2; if (val == grayTransparentAlpha) { pd[3] = 0; } else { pd[3] = maxOpacity; } dst.setPixel(dstX, y, pd); dstX += step; } break; } } /** * Reads in an image of a given size and returns it as a * WritableRaster. */ private void decodePass(WritableRaster imRas, int xOffset, int yOffset, int xStep, int yStep, int passWidth, int passHeight) { if ((passWidth == 0) || (passHeight == 0)) { return; } int bytesPerRow = (inputBands * passWidth * bitDepth + 7) / 8; int eltsPerRow = (bitDepth == 16) ? bytesPerRow / 2 : bytesPerRow; byte[] curr = new byte[bytesPerRow]; byte[] prior = new byte[bytesPerRow]; // Create a 1-row tall Raster to hold the data WritableRaster passRow = createRaster(passWidth, 1, inputBands, eltsPerRow, bitDepth); DataBuffer dataBuffer = passRow.getDataBuffer(); int type = dataBuffer.getDataType(); byte[] byteData = null; short[] shortData = null; if (type == DataBuffer.TYPE_BYTE) { byteData = ((DataBufferByte)dataBuffer).getData(); } else { shortData = ((DataBufferUShort)dataBuffer).getData(); } // Decode the (sub)image row-by-row int srcY; int dstY; for (srcY = 0, dstY = yOffset; srcY < passHeight; srcY++, dstY += yStep) { // Read the filter type byte and a row of data int filter = 0; try { filter = dataStream.read(); dataStream.readFully(curr, 0, bytesPerRow); } catch (Exception e) { e.printStackTrace(); } switch (filter) { case PNG_FILTER_NONE: break; case PNG_FILTER_SUB: decodeSubFilter(curr, bytesPerRow, bytesPerPixel); break; case PNG_FILTER_UP: decodeUpFilter(curr, prior, bytesPerRow); break; case PNG_FILTER_AVERAGE: decodeAverageFilter(curr, prior, bytesPerRow, bytesPerPixel); break; case PNG_FILTER_PAETH: decodePaethFilter(curr, prior, bytesPerRow, bytesPerPixel); break; default: // Error -- unknown filter type String msg = PropertyUtil.getString("PNGImageDecoder16"); throw new RuntimeException(msg); } // Copy data into passRow byte by byte if (bitDepth < 16) { System.arraycopy(curr, 0, byteData, 0, bytesPerRow); } else { int idx = 0; for (int j = 0; j < eltsPerRow; j++) { shortData[j] = (short)((curr[idx] << 8) | (curr[idx + 1] & 0xff)); idx += 2; } } processPixels(postProcess, passRow, imRas, xOffset, xStep, dstY, passWidth); // Swap curr and prior byte[] tmp = prior; prior = curr; curr = tmp; } } private void decodeImage(boolean useInterlacing) { int width = bounds.width; int height = bounds.height; if (!useInterlacing) { decodePass(theTile, 0, 0, 1, 1, width, height); } else { decodePass(theTile, 0, 0, 8, 8, (width + 7) / 8, (height + 7) / 8); decodePass(theTile, 4, 0, 8, 8, (width + 3) / 8, (height + 7) / 8); decodePass(theTile, 0, 4, 4, 8, (width + 3) / 4, (height + 3) / 8); decodePass(theTile, 2, 0, 4, 4, (width + 1) / 4, (height + 3) / 4); decodePass(theTile, 0, 2, 2, 4, (width + 1) / 2, (height + 1) / 4); decodePass(theTile, 1, 0, 2, 2, width / 2, (height + 1) / 2); decodePass(theTile, 0, 1, 1, 2, width, height / 2); } } public WritableRaster copyData(WritableRaster wr) { GraphicsUtil.copyData(theTile, wr); return wr; } // RenderedImage stuff @Override public Raster getTile(int tileX, int tileY) { if (tileX != 0 || tileY != 0) { // Error -- bad tile requested String msg = PropertyUtil.getString("PNGImageDecoder17"); throw new IllegalArgumentException(msg); } return theTile; } } ././@LongLink0100644 0000000 0000000 00000000153 13777276623 011656 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/codec/png/PNGSuggestedPaletteEntry.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/codec/png/PNGSuggestedPaletteEntr0100644 0000000 0000000 00000003410 13777276623 032426 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: PNGSuggestedPaletteEntry.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.image.codec.png; import java.io.Serializable; /** * A class representing the fields of a PNG suggested palette entry. * *

    This class is not a committed part of the JAI API. It may * be removed or changed in future releases of JAI. */ public class PNGSuggestedPaletteEntry implements Serializable { private static final long serialVersionUID = 8718480055883536195L; /** The name of the entry. */ public String name; /** The depth of the color samples. */ public int sampleDepth; /** The red color value of the entry. */ public int red; /** The green color value of the entry. */ public int green; /** The blue color value of the entry. */ public int blue; /** The alpha opacity value of the entry. */ public int alpha; /** The probable frequency of the color in the image. */ public int frequency; } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/codec/png/package.html0100644 0000000 0000000 00000001641 13777276623 030321 0ustar000000000 0000000 org.apache.xmlgraphics.image.codec.png Package

    Contains a PNG image codec.

    xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/codec/tiff/CompressionValue.java0100644 0000000 0000000 00000005546 13777276623 032355 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.xmlgraphics.image.codec.tiff; /** Enumerates the possible compression values for TIFF images. */ public enum CompressionValue { /** No compression. */ NONE(1), /** * Modified Huffman Compression (CCITT Group 3 1D facsimile compression). *

    Not currently supported. */ GROUP3_1D(2), /** * CCITT T.4 bilevel compression (CCITT Group 3 2D facsimile compression). *

    Not currently supported. */ GROUP3_2D(3), /** * CCITT T.6 bilevel compression (CCITT Group 4 facsimile compression). *

    Not currently supported. */ GROUP4(4), /** LZW compression.

    Not supported. */ LZW(5), /** * Code for original JPEG-in-TIFF compression which has been depricated (for many good reasons) * in favor of Tech Note 2 JPEG compression (compression scheme 7). *

    Not supported. */ JPEG_BROKEN(6), /** JPEG-in-TIFF compression. */ JPEG_TTN2(7), /** Byte-oriented run-length encoding "PackBits" compression. */ PACKBITS(32773), /** * * DEFLATE lossless compression (also known as "Zip-in-TIFF"). */ DEFLATE(32946); private final int compressionValue; private CompressionValue(int compressionValue) { this.compressionValue = compressionValue; } int getValue() { return compressionValue; } /** * Gets the compression value given the name of the compression type. * @param name the compression name * @return the compression value */ public static CompressionValue getValue(String name) { if (name == null) { return PACKBITS; } for (CompressionValue cv : CompressionValue.values()) { if (cv.toString().equalsIgnoreCase(name)) { return cv; } } throw new IllegalArgumentException("Unknown compression value: " + name); } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/codec/tiff/ExtraSamplesType.java0100644 0000000 0000000 00000002637 13777276623 032327 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.xmlgraphics.image.codec.tiff; import java.awt.image.ColorModel; enum ExtraSamplesType { UNSPECIFIED(0), ASSOCIATED_ALPHA(1), UNASSOCIATED_ALPHA(2); private final int typeValue; private ExtraSamplesType(int value) { this.typeValue = value; } static ExtraSamplesType getValue(ColorModel colorModel, int numExtraSamples) { if (numExtraSamples == 1 && colorModel.hasAlpha()) { return colorModel.isAlphaPremultiplied() ? ASSOCIATED_ALPHA : UNASSOCIATED_ALPHA; } return UNSPECIFIED; } int getValue() { return typeValue; } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/codec/tiff/ImageInfo.java0100644 0000000 0000000 00000017103 13777276623 030705 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.xmlgraphics.image.codec.tiff; import java.awt.color.ColorSpace; import java.awt.image.ColorModel; import java.awt.image.IndexColorModel; import java.awt.image.RenderedImage; final class ImageInfo { // Default values private static final int DEFAULT_ROWS_PER_STRIP = 8; private final int numExtraSamples; private final ExtraSamplesType extraSampleType; private final ImageType imageType; private final int colormapSize; private final char[] colormap; private final int tileWidth; private final int tileHeight; private final int numTiles; private final long bytesPerRow; private final long bytesPerTile; private ImageInfo(ImageInfoBuilder builder) { this.numExtraSamples = builder.numExtraSamples; this.extraSampleType = builder.extraSampleType; this.imageType = builder.imageType; this.colormapSize = builder.colormapSize; this.colormap = copyColormap(builder.colormap); this.tileWidth = builder.tileWidth; this.tileHeight = builder.tileHeight; this.numTiles = builder.numTiles; this.bytesPerRow = builder.bytesPerRow; this.bytesPerTile = builder.bytesPerTile; } private static char[] copyColormap(char[] colorMap) { if (colorMap == null) { return null; } char[] copy = new char[colorMap.length]; System.arraycopy(colorMap, 0, copy, 0, colorMap.length); return copy; } private static int getNumberOfExtraSamplesForColorSpace(ColorSpace colorSpace, ImageType imageType, int numBands) { if (imageType == ImageType.GENERIC) { return numBands - 1; } else if (numBands > 1) { return numBands - colorSpace.getNumComponents(); } else { return 0; } } private static char[] createColormap(final int sizeOfColormap, byte[] r, byte[] g, byte[] b) { int redIndex = 0; int greenIndex = sizeOfColormap; int blueIndex = 2 * sizeOfColormap; char[] colormap = new char[sizeOfColormap * 3]; for (int i = 0; i < sizeOfColormap; i++) { // beware of sign extended bytes colormap[redIndex++] = convertColorToColormapChar(0xff & r[i]); colormap[greenIndex++] = convertColorToColormapChar(0xff & g[i]); colormap[blueIndex++] = convertColorToColormapChar(0xff & b[i]); } return colormap; } private static char convertColorToColormapChar(int color) { return (char) (color << 8 | color); } int getNumberOfExtraSamples() { return numExtraSamples; } ExtraSamplesType getExtraSamplesType() { return extraSampleType; } ImageType getType() { return imageType; } int getColormapSize() { return colormapSize; } char[] getColormap() { return copyColormap(colormap); } int getTileWidth() { return tileWidth; } int getTileHeight() { return tileHeight; } int getNumTiles() { return numTiles; } long getBytesPerRow() { return bytesPerRow; } long getBytesPerTile() { return bytesPerTile; } static ImageInfo newInstance(RenderedImage im, int dataTypeSize, int numBands, ColorModel colorModel, TIFFEncodeParam params) { ImageInfoBuilder builder = new ImageInfoBuilder(); if (colorModel instanceof IndexColorModel) { // Bilevel or palette IndexColorModel indexColorModel = (IndexColorModel) colorModel; int colormapSize = indexColorModel.getMapSize(); byte[] r = new byte[colormapSize]; indexColorModel.getReds(r); byte[] g = new byte[colormapSize]; indexColorModel.getGreens(g); byte[] b = new byte[colormapSize]; indexColorModel.getBlues(b); builder.imageType = ImageType.getTypeFromRGB(colormapSize, r, g, b, dataTypeSize, numBands); if (builder.imageType == ImageType.PALETTE) { builder.colormap = createColormap(colormapSize, r, g, b); builder.colormapSize = colormapSize * 3; } } else if (colorModel == null) { if (dataTypeSize == 1 && numBands == 1) { // bilevel builder.imageType = ImageType.BILEVEL_BLACK_IS_ZERO; } else { builder.imageType = ImageType.GENERIC; builder.numExtraSamples = numBands > 1 ? numBands - 1 : 0; } } else { ColorSpace colorSpace = colorModel.getColorSpace(); builder.imageType = ImageType.getTypeFromColorSpace(colorSpace, params); builder.numExtraSamples = getNumberOfExtraSamplesForColorSpace(colorSpace, builder.imageType, numBands); builder.extraSampleType = ExtraSamplesType.getValue(colorModel, builder.numExtraSamples); } // Initialize tile dimensions. final int width = im.getWidth(); final int height = im.getHeight(); if (params.getWriteTiled()) { builder.tileWidth = params.getTileWidth() > 0 ? params.getTileWidth() : width; builder.tileHeight = params.getTileHeight() > 0 ? params.getTileHeight() : height; // NB: Parentheses are used in this statement for correct rounding. builder.numTiles = ((width + builder.tileWidth - 1) / builder.tileWidth) * ((height + builder.tileHeight - 1) / builder.tileHeight); } else { builder.tileWidth = width; builder.tileHeight = params.getTileHeight() > 0 ? params.getTileHeight() : DEFAULT_ROWS_PER_STRIP; builder.numTiles = (int) Math.ceil(height / (double) builder.tileHeight); } builder.setBytesPerRow(dataTypeSize, numBands) .setBytesPerTile(); return builder.build(); } private static final class ImageInfoBuilder { private ImageType imageType = ImageType.UNSUPPORTED; private int numExtraSamples; private char[] colormap; private int colormapSize; private ExtraSamplesType extraSampleType = ExtraSamplesType.UNSPECIFIED; private int tileWidth; private int tileHeight; private int numTiles; private long bytesPerRow; private long bytesPerTile; private ImageInfoBuilder setBytesPerRow(int dataTypeSize, int numBands) { bytesPerRow = (long) Math.ceil((dataTypeSize / 8.0) * tileWidth * numBands); return this; } private ImageInfoBuilder setBytesPerTile() { bytesPerTile = bytesPerRow * tileHeight; return this; } private ImageInfo build() { return new ImageInfo(this); } } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/codec/tiff/ImageType.java0100644 0000000 0000000 00000006503 13777276623 030735 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.xmlgraphics.image.codec.tiff; import java.awt.color.ColorSpace; import org.apache.xmlgraphics.image.codec.util.PropertyUtil; enum ImageType { UNSUPPORTED(-1), BILEVEL_WHITE_IS_ZERO(0), BILEVEL_BLACK_IS_ZERO(1), GRAY(1), PALETTE(3), RGB(2), CMYK(5), YCBCR(6), CIELAB(8), GENERIC(1); private final int photometricInterpretation; private ImageType(int photometricInterpretation) { this.photometricInterpretation = photometricInterpretation; } int getPhotometricInterpretation() { return photometricInterpretation; } static ImageType getTypeFromRGB(int mapSize, byte[] r, byte[] g, byte[] b, int dataTypeSize, int numBands) { if (numBands == 1) { if (dataTypeSize == 1) { // Bilevel image if (mapSize != 2) { throw new IllegalArgumentException(PropertyUtil.getString("TIFFImageEncoder7")); } if (isBlackZero(r, g, b)) { return BILEVEL_BLACK_IS_ZERO; } else if (isWhiteZero(r, g, b)) { return BILEVEL_WHITE_IS_ZERO; } } return PALETTE; } return UNSUPPORTED; } private static boolean rgbIsValueAt(byte[] r, byte[] g, byte[] b, byte value, int i) { return r[i] == value && g[i] == value && b[i] == value; } private static boolean bilevelColorValue(byte[] r, byte[] g, byte[] b, int blackValue, int whiteValue) { return rgbIsValueAt(r, g, b, (byte) blackValue, 0) && rgbIsValueAt(r, g, b, (byte) whiteValue, 1); } private static boolean isBlackZero(byte[] r, byte[] g, byte[] b) { return bilevelColorValue(r, g, b, 0, 0xff); } private static boolean isWhiteZero(byte[] r, byte[] g, byte[] b) { return bilevelColorValue(r, g, b, 0xff, 0); } static ImageType getTypeFromColorSpace(ColorSpace colorSpace, TIFFEncodeParam params) { switch (colorSpace.getType()) { case ColorSpace.TYPE_CMYK: return CMYK; case ColorSpace.TYPE_GRAY: return GRAY; case ColorSpace.TYPE_Lab: return CIELAB; case ColorSpace.TYPE_RGB: if (params.getJPEGCompressRGBToYCbCr()) { return ImageType.YCBCR; } else { return ImageType.RGB; } case ColorSpace.TYPE_YCbCr: return YCBCR; default: return GENERIC; } } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/codec/tiff/TIFFDecodeParam.java0100644 0000000 0000000 00000014315 13777276623 031666 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: TIFFDecodeParam.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.image.codec.tiff; import org.apache.xmlgraphics.image.codec.util.ImageDecodeParam; /** * An instance of ImageDecodeParam for decoding images in * the TIFF format. * *

    To determine the number of images present in a TIFF file, use * the getNumPages() method on the * ImageDecoder object that will be used to perform the * decoding. The desired page number may be passed as an argument to * the ImageDecoder.decodeAsRaster)() or * decodeAsRenderedImage() methods. * *

    For TIFF Palette color images, the colorMap always has entries * of short data type, the color Black being represented by 0,0,0 and * White by 65536,65536,65536. In order to display these images, the * default behavior is to dither the short values down to 8 bits. * The dithering is done by calling the decode16BitsTo8Bits * method for each short value that needs to be dithered. The method has * the following implementation: * * byte b; * short s; * s = s & 0xffff; * b = (byte)((s >> 8) & 0xff); * * If a different algorithm is to be used for the dithering, this class * should be subclassed and an appropriate implementation should be * provided for the decode16BitsTo8Bits method in the subclass. * *

    If the palette contains image data that is signed short, as specified * by the SampleFormat tag, the dithering is done by calling * decodeSigned16BitsTo8Bits instead. The method has the * following implementation: * * byte b; * short s; * b = (byte)((s + Short.MIN_VALUE) >> 8); * * In order to use a different algorithm for the dithering, this class * should be subclassed and the method overridden. * *

    If it is desired that the Palette be decoded such that the output * image is of short data type and no dithering is performed, the * setDecodePaletteAsShorts method should be used. * *

    This class is not a committed part of the JAI API. It may * be removed or changed in future releases of JAI. * * @see TIFFDirectory */ public class TIFFDecodeParam implements ImageDecodeParam { private static final long serialVersionUID = -2371665950056848358L; private boolean decodePaletteAsShorts; private Long ifdOffset; private boolean convertJPEGYCbCrToRGB = true; /** Constructs a default instance of TIFFDecodeParam. */ public TIFFDecodeParam() { } /** * If set, the entries in the palette will be decoded as shorts * and no short to byte lookup will be applied to them. */ public void setDecodePaletteAsShorts(boolean decodePaletteAsShorts) { this.decodePaletteAsShorts = decodePaletteAsShorts; } /** * Returns true if palette entries will be decoded as * shorts, resulting in an output image with short datatype. */ public boolean getDecodePaletteAsShorts() { return decodePaletteAsShorts; } /** * Returns an unsigned 8 bit value computed by dithering the unsigned * 16 bit value. Note that the TIFF specified short datatype is an * unsigned value, while Java's short datatype is a * signed value. Therefore the Java short datatype cannot * be used to store the TIFF specified short value. A Java * int is used as input instead to this method. The method * deals correctly only with 16 bit unsigned values. */ public byte decode16BitsTo8Bits(int s) { return (byte)((s >> 8) & 0xffff); } /** * Returns an unsigned 8 bit value computed by dithering the signed * 16 bit value. This method deals correctly only with values in the * 16 bit signed range. */ public byte decodeSigned16BitsTo8Bits(short s) { return (byte)((s + Short.MIN_VALUE) >> 8); } /** * Sets the offset in the stream from which to read the image. There * must be an Image File Directory (IFD) at that position or an error * will occur. If setIFDOffset() is never invoked then * the decoder will assume that the TIFF stream is at the beginning of * the 8-byte image header. If the directory offset is set and a page * number is supplied to the TIFF ImageDecoder then the * page will be the zero-relative index of the IFD in linked list of * IFDs beginning at the specified offset with a page of zero indicating * the directory at that offset. */ public void setIFDOffset(long offset) { ifdOffset = offset; } /** * Returns the value set by setIFDOffset() or * null if no value has been set. */ public Long getIFDOffset() { return ifdOffset; } /** * Sets a flag indicating whether to convert JPEG-compressed YCbCr data * to RGB. The default value is true. This flag is * ignored if the image data are not JPEG-compressed. */ public void setJPEGDecompressYCbCrToRGB(boolean convertJPEGYCbCrToRGB) { this.convertJPEGYCbCrToRGB = convertJPEGYCbCrToRGB; } /** * Whether JPEG-compressed YCbCr data will be converted to RGB. */ public boolean getJPEGDecompressYCbCrToRGB() { return convertJPEGYCbCrToRGB; } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/codec/tiff/TIFFDirectory.java0100644 0000000 0000000 00000050213 13777276623 031463 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: TIFFDirectory.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.image.codec.tiff; import java.io.IOException; import java.io.Serializable; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.apache.xmlgraphics.image.codec.util.PropertyUtil; import org.apache.xmlgraphics.image.codec.util.SeekableStream; // CSOFF: ConstantName // CSOFF: EmptyStatement // CSOFF: InnerAssignment // CSOFF: LocalVariableName // CSOFF: MemberName // CSOFF: MultipleVariableDeclarations // CSOFF: NeedBraces // CSOFF: ParameterName // CSOFF: WhitespaceAround /** * A class representing an Image File Directory (IFD) from a TIFF 6.0 * stream. The TIFF file format is described in more detail in the * comments for the TIFFDescriptor class. * *

    A TIFF IFD consists of a set of TIFFField tags. Methods are * provided to query the set of tags and to obtain the raw field * array. In addition, convenience methods are provided for acquiring * the values of tags that contain a single value that fits into a * byte, int, long, float, or double. * *

    Every TIFF file is made up of one or more public IFDs that are * joined in a linked list, rooted in the file header. A file may * also contain so-called private IFDs that are referenced from * tag data and do not appear in the main list. * *

    This class is not a committed part of the JAI API. It may * be removed or changed in future releases of JAI. * * @see TIFFField * @version $Id: TIFFDirectory.java 1732018 2016-02-24 04:51:06Z gadams $ */ public class TIFFDirectory implements Serializable { private static final long serialVersionUID = 2007844835460959003L; /** A boolean storing the endianness of the stream. */ boolean isBigEndian; /** The number of entries in the IFD. */ int numEntries; /** An array of TIFFFields. */ TIFFField[] fields; /** A Hashtable indexing the fields by tag number. */ Map fieldIndex = new HashMap(); /** The offset of this IFD. */ long ifdOffset = 8; /** The offset of the next IFD. */ long nextIFDOffset; /** The default constructor. */ TIFFDirectory() { } private static boolean isValidEndianTag(int endian) { return ((endian == 0x4949) || (endian == 0x4d4d)); } /** * Constructs a TIFFDirectory from a SeekableStream. * The directory parameter specifies which directory to read from * the linked list present in the stream; directory 0 is normally * read but it is possible to store multiple images in a single * TIFF file by maintaing multiple directories. * * @param stream a SeekableStream to read from. * @param directory the index of the directory to read. */ public TIFFDirectory(SeekableStream stream, int directory) throws IOException { long globalSaveOffset = stream.getFilePointer(); long ifdOffset; // Read the TIFF header stream.seek(0L); int endian = stream.readUnsignedShort(); if (!isValidEndianTag(endian)) { throw new IllegalArgumentException(PropertyUtil.getString("TIFFDirectory1")); } isBigEndian = (endian == 0x4d4d); int magic = readUnsignedShort(stream); if (magic != 42) { throw new IllegalArgumentException(PropertyUtil.getString("TIFFDirectory2")); } // Get the initial ifd offset as an unsigned int (using a long) ifdOffset = readUnsignedInt(stream); for (int i = 0; i < directory; i++) { if (ifdOffset == 0L) { throw new IllegalArgumentException(PropertyUtil.getString("TIFFDirectory3")); } stream.seek(ifdOffset); long entries = readUnsignedShort(stream); stream.skip(12 * entries); ifdOffset = readUnsignedInt(stream); } if (ifdOffset == 0L) { throw new IllegalArgumentException(PropertyUtil.getString("TIFFDirectory3")); } stream.seek(ifdOffset); initialize(stream); stream.seek(globalSaveOffset); } /** * Constructs a TIFFDirectory by reading a SeekableStream. * The ifd_offset parameter specifies the stream offset from which * to begin reading; this mechanism is sometimes used to store * private IFDs within a TIFF file that are not part of the normal * sequence of IFDs. * * @param stream a SeekableStream to read from. * @param ifdOffset the long byte offset of the directory. * @param directory the index of the directory to read beyond the * one at the current stream offset; zero indicates the IFD * at the current offset. */ public TIFFDirectory(SeekableStream stream, long ifdOffset, int directory) throws IOException { long globalSaveOffset = stream.getFilePointer(); stream.seek(0L); int endian = stream.readUnsignedShort(); if (!isValidEndianTag(endian)) { throw new IllegalArgumentException(PropertyUtil.getString("TIFFDirectory1")); } isBigEndian = (endian == 0x4d4d); // Seek to the first IFD. stream.seek(ifdOffset); // Seek to desired IFD if necessary. int dirNum = 0; while (dirNum < directory) { // Get the number of fields in the current IFD. long numEntries = readUnsignedShort(stream); // Skip to the next IFD offset value field. stream.seek(ifdOffset + 12 * numEntries); // Read the offset to the next IFD beyond this one. ifdOffset = readUnsignedInt(stream); // Seek to the next IFD. stream.seek(ifdOffset); // Increment the directory. dirNum++; } initialize(stream); stream.seek(globalSaveOffset); } private static final int[] SIZE_OF_TYPE = { 0, // 0 = n/a 1, // 1 = byte 1, // 2 = ascii 2, // 3 = short 4, // 4 = long 8, // 5 = rational 1, // 6 = sbyte 1, // 7 = undefined 2, // 8 = sshort 4, // 9 = slong 8, // 10 = srational 4, // 11 = float 8 // 12 = double }; private void initialize(SeekableStream stream) throws IOException { long nextTagOffset; int i; int j; ifdOffset = stream.getFilePointer(); numEntries = readUnsignedShort(stream); fields = new TIFFField[numEntries]; for (i = 0; i < numEntries; i++) { int tag = readUnsignedShort(stream); int type = readUnsignedShort(stream); int count = (int)(readUnsignedInt(stream)); int value = 0; // The place to return to to read the next tag nextTagOffset = stream.getFilePointer() + 4; try { // If the tag data can't fit in 4 bytes, the next 4 bytes // contain the starting offset of the data if (count * SIZE_OF_TYPE[type] > 4) { value = (int)(readUnsignedInt(stream)); stream.seek(value); } } catch (ArrayIndexOutOfBoundsException ae) { // System.err.println(tag + " " + "TIFFDirectory4"); TODO - log this message // if the data type is unknown we should skip this TIFF Field stream.seek(nextTagOffset); continue; } fieldIndex.put(tag, i); Object obj = null; switch (type) { case TIFFField.TIFF_BYTE: case TIFFField.TIFF_SBYTE: case TIFFField.TIFF_UNDEFINED: case TIFFField.TIFF_ASCII: byte[] bvalues = new byte[count]; stream.readFully(bvalues, 0, count); if (type == TIFFField.TIFF_ASCII) { // Can be multiple strings int index = 0; int prevIndex = 0; List v = new ArrayList(); while (index < count) { while ((index < count) && (bvalues[index++] != 0)) { // NOP } // When we encountered zero, means one string has ended v.add(new String(bvalues, prevIndex, (index - prevIndex), "UTF-8")); prevIndex = index; } count = v.size(); String[] strings = new String[count]; v.toArray(strings); obj = strings; } else { obj = bvalues; } break; case TIFFField.TIFF_SHORT: char[] cvalues = new char[count]; for (j = 0; j < count; j++) { cvalues[j] = (char)(readUnsignedShort(stream)); } obj = cvalues; break; case TIFFField.TIFF_LONG: long[] lvalues = new long[count]; for (j = 0; j < count; j++) { lvalues[j] = readUnsignedInt(stream); } obj = lvalues; break; case TIFFField.TIFF_RATIONAL: long[][] llvalues = new long[count][2]; for (j = 0; j < count; j++) { llvalues[j][0] = readUnsignedInt(stream); llvalues[j][1] = readUnsignedInt(stream); } obj = llvalues; break; case TIFFField.TIFF_SSHORT: short[] svalues = new short[count]; for (j = 0; j < count; j++) { svalues[j] = readShort(stream); } obj = svalues; break; case TIFFField.TIFF_SLONG: int[] ivalues = new int[count]; for (j = 0; j < count; j++) { ivalues[j] = readInt(stream); } obj = ivalues; break; case TIFFField.TIFF_SRATIONAL: int[][] iivalues = new int[count][2]; for (j = 0; j < count; j++) { iivalues[j][0] = readInt(stream); iivalues[j][1] = readInt(stream); } obj = iivalues; break; case TIFFField.TIFF_FLOAT: float[] fvalues = new float[count]; for (j = 0; j < count; j++) { fvalues[j] = readFloat(stream); } obj = fvalues; break; case TIFFField.TIFF_DOUBLE: double[] dvalues = new double[count]; for (j = 0; j < count; j++) { dvalues[j] = readDouble(stream); } obj = dvalues; break; default: throw new RuntimeException(PropertyUtil.getString("TIFFDirectory0")); } fields[i] = new TIFFField(tag, type, count, obj); stream.seek(nextTagOffset); } // Read the offset of the next IFD. nextIFDOffset = readUnsignedInt(stream); } /** Returns the number of directory entries. */ public int getNumEntries() { return numEntries; } /** * Returns the value of a given tag as a TIFFField, * or null if the tag is not present. */ public TIFFField getField(int tag) { Integer i = (Integer)fieldIndex.get(tag); if (i == null) { return null; } else { return fields[i]; } } /** * Returns true if a tag appears in the directory. */ public boolean isTagPresent(int tag) { return fieldIndex.containsKey(tag); } /** * Returns an ordered array of ints indicating the tag * values. */ public int[] getTags() { int[] tags = new int[fieldIndex.size()]; Iterator iter = fieldIndex.keySet().iterator(); int i = 0; while (iter.hasNext()) { tags[i++] = (Integer) iter.next(); } return tags; } /** * Returns an array of TIFFFields containing all the fields * in this directory. */ public TIFFField[] getFields() { return fields; } /** * Returns the value of a particular index of a given tag as a * byte. The caller is responsible for ensuring that the tag is * present and has type TIFFField.TIFF_SBYTE, TIFF_BYTE, or * TIFF_UNDEFINED. */ public byte getFieldAsByte(int tag, int index) { Integer i = (Integer)fieldIndex.get(tag); byte [] b = (fields[i]).getAsBytes(); return b[index]; } /** * Returns the value of index 0 of a given tag as a * byte. The caller is responsible for ensuring that the tag is * present and has type TIFFField.TIFF_SBYTE, TIFF_BYTE, or * TIFF_UNDEFINED. */ public byte getFieldAsByte(int tag) { return getFieldAsByte(tag, 0); } /** * Returns the value of a particular index of a given tag as a * long. The caller is responsible for ensuring that the tag is * present and has type TIFF_BYTE, TIFF_SBYTE, TIFF_UNDEFINED, * TIFF_SHORT, TIFF_SSHORT, TIFF_SLONG or TIFF_LONG. */ public long getFieldAsLong(int tag, int index) { Integer i = (Integer)fieldIndex.get(tag); return (fields[i]).getAsLong(index); } /** * Returns the value of index 0 of a given tag as a * long. The caller is responsible for ensuring that the tag is * present and has type TIFF_BYTE, TIFF_SBYTE, TIFF_UNDEFINED, * TIFF_SHORT, TIFF_SSHORT, TIFF_SLONG or TIFF_LONG. */ public long getFieldAsLong(int tag) { return getFieldAsLong(tag, 0); } /** * Returns the value of a particular index of a given tag as a * float. The caller is responsible for ensuring that the tag is * present and has numeric type (all but TIFF_UNDEFINED and * TIFF_ASCII). */ public float getFieldAsFloat(int tag, int index) { Integer i = (Integer)fieldIndex.get(tag); return fields[i].getAsFloat(index); } /** * Returns the value of index 0 of a given tag as a float. The * caller is responsible for ensuring that the tag is present and * has numeric type (all but TIFF_UNDEFINED and TIFF_ASCII). */ public float getFieldAsFloat(int tag) { return getFieldAsFloat(tag, 0); } /** * Returns the value of a particular index of a given tag as a * double. The caller is responsible for ensuring that the tag is * present and has numeric type (all but TIFF_UNDEFINED and * TIFF_ASCII). */ public double getFieldAsDouble(int tag, int index) { Integer i = (Integer)fieldIndex.get(tag); return fields[i].getAsDouble(index); } /** * Returns the value of index 0 of a given tag as a double. The * caller is responsible for ensuring that the tag is present and * has numeric type (all but TIFF_UNDEFINED and TIFF_ASCII). */ public double getFieldAsDouble(int tag) { return getFieldAsDouble(tag, 0); } // Methods to read primitive data types from the stream private short readShort(SeekableStream stream) throws IOException { if (isBigEndian) { return stream.readShort(); } else { return stream.readShortLE(); } } private int readUnsignedShort(SeekableStream stream) throws IOException { if (isBigEndian) { return stream.readUnsignedShort(); } else { return stream.readUnsignedShortLE(); } } private int readInt(SeekableStream stream) throws IOException { if (isBigEndian) { return stream.readInt(); } else { return stream.readIntLE(); } } private long readUnsignedInt(SeekableStream stream) throws IOException { if (isBigEndian) { return stream.readUnsignedInt(); } else { return stream.readUnsignedIntLE(); } } // private long readLong(SeekableStream stream) // throws IOException { // if (isBigEndian) { // return stream.readLong(); // } else { // return stream.readLongLE(); // } // } private float readFloat(SeekableStream stream) throws IOException { if (isBigEndian) { return stream.readFloat(); } else { return stream.readFloatLE(); } } private double readDouble(SeekableStream stream) throws IOException { if (isBigEndian) { return stream.readDouble(); } else { return stream.readDoubleLE(); } } private static int readUnsignedShort(SeekableStream stream, boolean isBigEndian) throws IOException { if (isBigEndian) { return stream.readUnsignedShort(); } else { return stream.readUnsignedShortLE(); } } private static long readUnsignedInt(SeekableStream stream, boolean isBigEndian) throws IOException { if (isBigEndian) { return stream.readUnsignedInt(); } else { return stream.readUnsignedIntLE(); } } // Utilities /** * Returns the number of image directories (subimages) stored in a * given TIFF file, represented by a SeekableStream. */ public static int getNumDirectories(SeekableStream stream) throws IOException { long pointer = stream.getFilePointer(); // Save stream pointer stream.seek(0L); int endian = stream.readUnsignedShort(); if (!isValidEndianTag(endian)) { throw new IllegalArgumentException(PropertyUtil.getString("TIFFDirectory1")); } boolean isBigEndian = (endian == 0x4d4d); int magic = readUnsignedShort(stream, isBigEndian); if (magic != 42) { throw new IllegalArgumentException(PropertyUtil.getString("TIFFDirectory2")); } stream.seek(4L); long offset = readUnsignedInt(stream, isBigEndian); int numDirectories = 0; while (offset != 0L) { ++numDirectories; stream.seek(offset); long entries = readUnsignedShort(stream, isBigEndian); stream.skip(12 * entries); offset = readUnsignedInt(stream, isBigEndian); } stream.seek(pointer); // Reset stream pointer return numDirectories; } /** * Returns a boolean indicating whether the byte order used in the * the TIFF file is big-endian. That is, whether the byte order is from * the most significant to the least significant. */ public boolean isBigEndian() { return isBigEndian; } /** * Returns the offset of the IFD corresponding to this * TIFFDirectory. */ public long getIFDOffset() { return ifdOffset; } /** * Returns the offset of the next IFD after the IFD corresponding to this * TIFFDirectory. */ public long getNextIFDOffset() { return nextIFDOffset; } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/codec/tiff/TIFFEncodeParam.java0100644 0000000 0000000 00000022056 13777276623 031701 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: TIFFEncodeParam.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.image.codec.tiff; import java.util.Iterator; import java.util.zip.Deflater; import org.apache.xmlgraphics.image.codec.util.ImageEncodeParam; import org.apache.xmlgraphics.image.codec.util.PropertyUtil; /** * An instance of ImageEncodeParam for encoding images in * the TIFF format. * *

    This class allows for the specification of encoding parameters. By * default, the image is encoded without any compression, and is written * out consisting of strips, not tiles. The particular compression scheme * to be used can be specified by using the setCompression() * method. The compression scheme specified will be honored only if it is * compatible with the type of image being written out. For example, * Group3 and Group4 compressions can only be used with Bilevel images. * Writing of tiled TIFF images can be enabled by calling the * setWriteTiled() method. * *

    This class is not a committed part of the JAI API. It may * be removed or changed in future releases of JAI. * */ public class TIFFEncodeParam implements ImageEncodeParam { private static final long serialVersionUID = 2471949735040024055L; private CompressionValue compression = CompressionValue.NONE; private boolean writeTiled; private int tileWidth; private int tileHeight; private Iterator extraImages; private TIFFField[] extraFields; private boolean convertJPEGRGBToYCbCr = true; private int deflateLevel = Deflater.DEFAULT_COMPRESSION; /** * Constructs a TIFFEncodeParam object with default values for * all parameters. */ public TIFFEncodeParam() { //nop } /** Returns the value of the compression parameter. */ public CompressionValue getCompression() { return compression; } /** * Specifies the type of compression to be used. The compression type * specified will be honored only if it is compatible with the image * being written out. Currently only PackBits, JPEG, and DEFLATE * compression schemes are supported. * *

    If compression is set to any value but * COMPRESSION_NONE and the OutputStream * supplied to the ImageEncoder is not a * SeekableOutputStream, then the encoder will use either * a temporary file or a memory cache when compressing the data * depending on whether the file system is accessible. Compression * will therefore be more efficient if a SeekableOutputStream * is supplied. * * @param compression The compression type. */ public void setCompression(CompressionValue compression) { switch(compression) { case NONE: case PACKBITS: case DEFLATE: // Do nothing. break; default: throw new RuntimeException(PropertyUtil.getString("TIFFEncodeParam0")); } this.compression = compression; } /** * Returns the value of the writeTiled parameter. */ public boolean getWriteTiled() { return writeTiled; } /** * If set, the data will be written out in tiled format, instead of * in strips. * * @param writeTiled Specifies whether the image data should be * wriiten out in tiled format. */ public void setWriteTiled(boolean writeTiled) { this.writeTiled = writeTiled; } /** * Sets the dimensions of the tiles to be written. If either * value is non-positive, the encoder will use a default value. * *

    If the data are being written as tiles, i.e., * getWriteTiled() returns true, then the * default tile dimensions used by the encoder are those of the tiles * of the image being encoded. * *

    If the data are being written as strips, i.e., * getWriteTiled() returns false, the width * of each strip is always the width of the image and the default * number of rows per strip is 8. * * @param tileWidth The tile width; ignored if strips are used. * @param tileHeight The tile height or number of rows per strip. */ public void setTileSize(int tileWidth, int tileHeight) { this.tileWidth = tileWidth; this.tileHeight = tileHeight; } /** * Retrieves the tile width set via setTileSize(). */ public int getTileWidth() { return tileWidth; } /** * Retrieves the tile height set via setTileSize(). */ public int getTileHeight() { return tileHeight; } /** * Sets an Iterator of additional images to be written * after the image passed as an argument to the ImageEncoder. * The methods on the supplied Iterator must only be invoked * by the ImageEncoder which will exhaust the available * values unless an error occurs. * *

    The value returned by an invocation of next() on the * Iterator must return either a RenderedImage * or an Object[] of length 2 wherein the element at index * zero is a RenderedImage amd the other element is a * TIFFEncodeParam. If no TIFFEncodeParam is * supplied in this manner for an additional image, the parameters used * to create the ImageEncoder will be used. The extra * image Iterator set on any TIFFEncodeParam * of an additional image will in all cases be ignored. */ public synchronized void setExtraImages(Iterator extraImages) { this.extraImages = extraImages; } /** * Returns the additional image Iterator specified via * setExtraImages() or null if none was * supplied or if a null value was supplied. */ public synchronized Iterator getExtraImages() { return extraImages; } /** * Sets the compression level for DEFLATE-compressed data which should * either be java.util.Deflater.DEFAULT_COMPRESSION or a * value in the range [1,9] where larger values indicate more compression. * The default setting is Deflater.DEFAULT_COMPRESSION. This * setting is ignored if the compression type is not DEFLATE. */ public void setDeflateLevel(int deflateLevel) { if (deflateLevel != Deflater.DEFAULT_COMPRESSION) { throw new RuntimeException(PropertyUtil.getString("TIFFEncodeParam1")); } this.deflateLevel = deflateLevel; } /** * Gets the compression level for DEFLATE compression. */ public int getDeflateLevel() { return deflateLevel; } /** * Sets flag indicating whether to convert RGB data to YCbCr when the * compression type is JPEG. The default value is true. * This flag is ignored if the compression type is not JPEG. */ public void setJPEGCompressRGBToYCbCr(boolean convertJPEGRGBToYCbCr) { this.convertJPEGRGBToYCbCr = convertJPEGRGBToYCbCr; } /** * Whether RGB data will be converted to YCbCr when using JPEG compression. */ public boolean getJPEGCompressRGBToYCbCr() { return convertJPEGRGBToYCbCr; } /** * Sets an array of extra fields to be written to the TIFF Image File * Directory (IFD). Fields with tags equal to the tag of any * automatically generated fields are ignored. No error checking is * performed with respect to the validity of the field contents or * the appropriateness of the field for the image being encoded. * * @param extraFields An array of extra fields; the parameter is * copied by reference. */ public void setExtraFields(TIFFField[] extraFields) { this.extraFields = extraFields; } /** * Returns the value set by setExtraFields(). */ public TIFFField[] getExtraFields() { if (extraFields == null) { return new TIFFField[0]; } return extraFields; } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/codec/tiff/TIFFFaxDecoder.java0100644 0000000 0000000 00000154654 13777276623 031541 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: TIFFFaxDecoder.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.image.codec.tiff; import org.apache.xmlgraphics.image.codec.util.PropertyUtil; // CSOFF: InnerAssignment // CSOFF: MultipleVariableDeclarations // CSOFF: OperatorWrap // CSOFF: WhitespaceAround class TIFFFaxDecoder { private int bitPointer; private int bytePointer; private byte[] data; private int w; private int fillOrder; // Data structures needed to store changing elements for the previous // and the current scanline private int changingElemSize; private int[] prevChangingElems; private int[] currChangingElems; // Element at which to start search in getNextChangingElement private int lastChangingElement; private int compression = 2; // Variables set by T4Options // private int uncompressedMode = 0; private int fillBits; private int oneD; static int[] table1 = { 0x00, // 0 bits are left in first byte - SHOULD NOT HAPPEN 0x01, // 1 bits are left in first byte 0x03, // 2 bits are left in first byte 0x07, // 3 bits are left in first byte 0x0f, // 4 bits are left in first byte 0x1f, // 5 bits are left in first byte 0x3f, // 6 bits are left in first byte 0x7f, // 7 bits are left in first byte 0xff // 8 bits are left in first byte }; static int[] table2 = { 0x00, // 0 0x80, // 1 0xc0, // 2 0xe0, // 3 0xf0, // 4 0xf8, // 5 0xfc, // 6 0xfe, // 7 0xff // 8 }; // Table to be used when fillOrder = 2, for flipping bytes. static byte[] flipTable = { 0, -128, 64, -64, 32, -96, 96, -32, 16, -112, 80, -48, 48, -80, 112, -16, 8, -120, 72, -56, 40, -88, 104, -24, 24, -104, 88, -40, 56, -72, 120, -8, 4, -124, 68, -60, 36, -92, 100, -28, 20, -108, 84, -44, 52, -76, 116, -12, 12, -116, 76, -52, 44, -84, 108, -20, 28, -100, 92, -36, 60, -68, 124, -4, 2, -126, 66, -62, 34, -94, 98, -30, 18, -110, 82, -46, 50, -78, 114, -14, 10, -118, 74, -54, 42, -86, 106, -22, 26, -102, 90, -38, 58, -70, 122, -6, 6, -122, 70, -58, 38, -90, 102, -26, 22, -106, 86, -42, 54, -74, 118, -10, 14, -114, 78, -50, 46, -82, 110, -18, 30, -98, 94, -34, 62, -66, 126, -2, 1, -127, 65, -63, 33, -95, 97, -31, 17, -111, 81, -47, 49, -79, 113, -15, 9, -119, 73, -55, 41, -87, 105, -23, 25, -103, 89, -39, 57, -71, 121, -7, 5, -123, 69, -59, 37, -91, 101, -27, 21, -107, 85, -43, 53, -75, 117, -11, 13, -115, 77, -51, 45, -83, 109, -19, 29, -99, 93, -35, 61, -67, 125, -3, 3, -125, 67, -61, 35, -93, 99, -29, 19, -109, 83, -45, 51, -77, 115, -13, 11, -117, 75, -53, 43, -85, 107, -21, 27, -101, 91, -37, 59, -69, 123, -5, 7, -121, 71, -57, 39, -89, 103, -25, 23, -105, 87, -41, 55, -73, 119, -9, 15, -113, 79, -49, 47, -81, 111, -17, 31, -97, 95, -33, 63, -65, 127, -1, }; // The main 10 bit white runs lookup table static short[] white = { // 0 - 7 6430, 6400, 6400, 6400, 3225, 3225, 3225, 3225, // 8 - 15 944, 944, 944, 944, 976, 976, 976, 976, // 16 - 23 1456, 1456, 1456, 1456, 1488, 1488, 1488, 1488, // 24 - 31 718, 718, 718, 718, 718, 718, 718, 718, // 32 - 39 750, 750, 750, 750, 750, 750, 750, 750, // 40 - 47 1520, 1520, 1520, 1520, 1552, 1552, 1552, 1552, // 48 - 55 428, 428, 428, 428, 428, 428, 428, 428, // 56 - 63 428, 428, 428, 428, 428, 428, 428, 428, // 64 - 71 654, 654, 654, 654, 654, 654, 654, 654, // 72 - 79 1072, 1072, 1072, 1072, 1104, 1104, 1104, 1104, // 80 - 87 1136, 1136, 1136, 1136, 1168, 1168, 1168, 1168, // 88 - 95 1200, 1200, 1200, 1200, 1232, 1232, 1232, 1232, // 96 - 103 622, 622, 622, 622, 622, 622, 622, 622, // 104 - 111 1008, 1008, 1008, 1008, 1040, 1040, 1040, 1040, // 112 - 119 44, 44, 44, 44, 44, 44, 44, 44, // 120 - 127 44, 44, 44, 44, 44, 44, 44, 44, // 128 - 135 396, 396, 396, 396, 396, 396, 396, 396, // 136 - 143 396, 396, 396, 396, 396, 396, 396, 396, // 144 - 151 1712, 1712, 1712, 1712, 1744, 1744, 1744, 1744, // 152 - 159 846, 846, 846, 846, 846, 846, 846, 846, // 160 - 167 1264, 1264, 1264, 1264, 1296, 1296, 1296, 1296, // 168 - 175 1328, 1328, 1328, 1328, 1360, 1360, 1360, 1360, // 176 - 183 1392, 1392, 1392, 1392, 1424, 1424, 1424, 1424, // 184 - 191 686, 686, 686, 686, 686, 686, 686, 686, // 192 - 199 910, 910, 910, 910, 910, 910, 910, 910, // 200 - 207 1968, 1968, 1968, 1968, 2000, 2000, 2000, 2000, // 208 - 215 2032, 2032, 2032, 2032, 16, 16, 16, 16, // 216 - 223 10257, 10257, 10257, 10257, 12305, 12305, 12305, 12305, // 224 - 231 330, 330, 330, 330, 330, 330, 330, 330, // 232 - 239 330, 330, 330, 330, 330, 330, 330, 330, // 240 - 247 330, 330, 330, 330, 330, 330, 330, 330, // 248 - 255 330, 330, 330, 330, 330, 330, 330, 330, // 256 - 263 362, 362, 362, 362, 362, 362, 362, 362, // 264 - 271 362, 362, 362, 362, 362, 362, 362, 362, // 272 - 279 362, 362, 362, 362, 362, 362, 362, 362, // 280 - 287 362, 362, 362, 362, 362, 362, 362, 362, // 288 - 295 878, 878, 878, 878, 878, 878, 878, 878, // 296 - 303 1904, 1904, 1904, 1904, 1936, 1936, 1936, 1936, // 304 - 311 -18413, -18413, -16365, -16365, -14317, -14317, -10221, -10221, // 312 - 319 590, 590, 590, 590, 590, 590, 590, 590, // 320 - 327 782, 782, 782, 782, 782, 782, 782, 782, // 328 - 335 1584, 1584, 1584, 1584, 1616, 1616, 1616, 1616, // 336 - 343 1648, 1648, 1648, 1648, 1680, 1680, 1680, 1680, // 344 - 351 814, 814, 814, 814, 814, 814, 814, 814, // 352 - 359 1776, 1776, 1776, 1776, 1808, 1808, 1808, 1808, // 360 - 367 1840, 1840, 1840, 1840, 1872, 1872, 1872, 1872, // 368 - 375 6157, 6157, 6157, 6157, 6157, 6157, 6157, 6157, // 376 - 383 6157, 6157, 6157, 6157, 6157, 6157, 6157, 6157, // 384 - 391 -12275, -12275, -12275, -12275, -12275, -12275, -12275, -12275, // 392 - 399 -12275, -12275, -12275, -12275, -12275, -12275, -12275, -12275, // 400 - 407 14353, 14353, 14353, 14353, 16401, 16401, 16401, 16401, // 408 - 415 22547, 22547, 24595, 24595, 20497, 20497, 20497, 20497, // 416 - 423 18449, 18449, 18449, 18449, 26643, 26643, 28691, 28691, // 424 - 431 30739, 30739, -32749, -32749, -30701, -30701, -28653, -28653, // 432 - 439 -26605, -26605, -24557, -24557, -22509, -22509, -20461, -20461, // 440 - 447 8207, 8207, 8207, 8207, 8207, 8207, 8207, 8207, // 448 - 455 72, 72, 72, 72, 72, 72, 72, 72, // 456 - 463 72, 72, 72, 72, 72, 72, 72, 72, // 464 - 471 72, 72, 72, 72, 72, 72, 72, 72, // 472 - 479 72, 72, 72, 72, 72, 72, 72, 72, // 480 - 487 72, 72, 72, 72, 72, 72, 72, 72, // 488 - 495 72, 72, 72, 72, 72, 72, 72, 72, // 496 - 503 72, 72, 72, 72, 72, 72, 72, 72, // 504 - 511 72, 72, 72, 72, 72, 72, 72, 72, // 512 - 519 104, 104, 104, 104, 104, 104, 104, 104, // 520 - 527 104, 104, 104, 104, 104, 104, 104, 104, // 528 - 535 104, 104, 104, 104, 104, 104, 104, 104, // 536 - 543 104, 104, 104, 104, 104, 104, 104, 104, // 544 - 551 104, 104, 104, 104, 104, 104, 104, 104, // 552 - 559 104, 104, 104, 104, 104, 104, 104, 104, // 560 - 567 104, 104, 104, 104, 104, 104, 104, 104, // 568 - 575 104, 104, 104, 104, 104, 104, 104, 104, // 576 - 583 4107, 4107, 4107, 4107, 4107, 4107, 4107, 4107, // 584 - 591 4107, 4107, 4107, 4107, 4107, 4107, 4107, 4107, // 592 - 599 4107, 4107, 4107, 4107, 4107, 4107, 4107, 4107, // 600 - 607 4107, 4107, 4107, 4107, 4107, 4107, 4107, 4107, // 608 - 615 266, 266, 266, 266, 266, 266, 266, 266, // 616 - 623 266, 266, 266, 266, 266, 266, 266, 266, // 624 - 631 266, 266, 266, 266, 266, 266, 266, 266, // 632 - 639 266, 266, 266, 266, 266, 266, 266, 266, // 640 - 647 298, 298, 298, 298, 298, 298, 298, 298, // 648 - 655 298, 298, 298, 298, 298, 298, 298, 298, // 656 - 663 298, 298, 298, 298, 298, 298, 298, 298, // 664 - 671 298, 298, 298, 298, 298, 298, 298, 298, // 672 - 679 524, 524, 524, 524, 524, 524, 524, 524, // 680 - 687 524, 524, 524, 524, 524, 524, 524, 524, // 688 - 695 556, 556, 556, 556, 556, 556, 556, 556, // 696 - 703 556, 556, 556, 556, 556, 556, 556, 556, // 704 - 711 136, 136, 136, 136, 136, 136, 136, 136, // 712 - 719 136, 136, 136, 136, 136, 136, 136, 136, // 720 - 727 136, 136, 136, 136, 136, 136, 136, 136, // 728 - 735 136, 136, 136, 136, 136, 136, 136, 136, // 736 - 743 136, 136, 136, 136, 136, 136, 136, 136, // 744 - 751 136, 136, 136, 136, 136, 136, 136, 136, // 752 - 759 136, 136, 136, 136, 136, 136, 136, 136, // 760 - 767 136, 136, 136, 136, 136, 136, 136, 136, // 768 - 775 168, 168, 168, 168, 168, 168, 168, 168, // 776 - 783 168, 168, 168, 168, 168, 168, 168, 168, // 784 - 791 168, 168, 168, 168, 168, 168, 168, 168, // 792 - 799 168, 168, 168, 168, 168, 168, 168, 168, // 800 - 807 168, 168, 168, 168, 168, 168, 168, 168, // 808 - 815 168, 168, 168, 168, 168, 168, 168, 168, // 816 - 823 168, 168, 168, 168, 168, 168, 168, 168, // 824 - 831 168, 168, 168, 168, 168, 168, 168, 168, // 832 - 839 460, 460, 460, 460, 460, 460, 460, 460, // 840 - 847 460, 460, 460, 460, 460, 460, 460, 460, // 848 - 855 492, 492, 492, 492, 492, 492, 492, 492, // 856 - 863 492, 492, 492, 492, 492, 492, 492, 492, // 864 - 871 2059, 2059, 2059, 2059, 2059, 2059, 2059, 2059, // 872 - 879 2059, 2059, 2059, 2059, 2059, 2059, 2059, 2059, // 880 - 887 2059, 2059, 2059, 2059, 2059, 2059, 2059, 2059, // 888 - 895 2059, 2059, 2059, 2059, 2059, 2059, 2059, 2059, // 896 - 903 200, 200, 200, 200, 200, 200, 200, 200, // 904 - 911 200, 200, 200, 200, 200, 200, 200, 200, // 912 - 919 200, 200, 200, 200, 200, 200, 200, 200, // 920 - 927 200, 200, 200, 200, 200, 200, 200, 200, // 928 - 935 200, 200, 200, 200, 200, 200, 200, 200, // 936 - 943 200, 200, 200, 200, 200, 200, 200, 200, // 944 - 951 200, 200, 200, 200, 200, 200, 200, 200, // 952 - 959 200, 200, 200, 200, 200, 200, 200, 200, // 960 - 967 232, 232, 232, 232, 232, 232, 232, 232, // 968 - 975 232, 232, 232, 232, 232, 232, 232, 232, // 976 - 983 232, 232, 232, 232, 232, 232, 232, 232, // 984 - 991 232, 232, 232, 232, 232, 232, 232, 232, // 992 - 999 232, 232, 232, 232, 232, 232, 232, 232, // 1000 - 1007 232, 232, 232, 232, 232, 232, 232, 232, // 1008 - 1015 232, 232, 232, 232, 232, 232, 232, 232, // 1016 - 1023 232, 232, 232, 232, 232, 232, 232, 232, }; // Additional make up codes for both White and Black runs static short[] additionalMakeup = { 28679, 28679, 31752, (short)32777, (short)33801, (short)34825, (short)35849, (short)36873, (short)29703, (short)29703, (short)30727, (short)30727, (short)37897, (short)38921, (short)39945, (short)40969 }; // Initial black run look up table, uses the first 4 bits of a code static short[] initBlack = { // 0 - 7 3226, 6412, 200, 168, 38, 38, 134, 134, // 8 - 15 100, 100, 100, 100, 68, 68, 68, 68 }; // static short[] twoBitBlack = {292, 260, 226, 226}; // 0 - 3 // Main black run table, using the last 9 bits of possible 13 bit code static short[] black = { // 0 - 7 62, 62, 30, 30, 0, 0, 0, 0, // 8 - 15 0, 0, 0, 0, 0, 0, 0, 0, // 16 - 23 0, 0, 0, 0, 0, 0, 0, 0, // 24 - 31 0, 0, 0, 0, 0, 0, 0, 0, // 32 - 39 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, // 40 - 47 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, // 48 - 55 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, // 56 - 63 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, // 64 - 71 588, 588, 588, 588, 588, 588, 588, 588, // 72 - 79 1680, 1680, 20499, 22547, 24595, 26643, 1776, 1776, // 80 - 87 1808, 1808, -24557, -22509, -20461, -18413, 1904, 1904, // 88 - 95 1936, 1936, -16365, -14317, 782, 782, 782, 782, // 96 - 103 814, 814, 814, 814, -12269, -10221, 10257, 10257, // 104 - 111 12305, 12305, 14353, 14353, 16403, 18451, 1712, 1712, // 112 - 119 1744, 1744, 28691, 30739, -32749, -30701, -28653, -26605, // 120 - 127 2061, 2061, 2061, 2061, 2061, 2061, 2061, 2061, // 128 - 135 424, 424, 424, 424, 424, 424, 424, 424, // 136 - 143 424, 424, 424, 424, 424, 424, 424, 424, // 144 - 151 424, 424, 424, 424, 424, 424, 424, 424, // 152 - 159 424, 424, 424, 424, 424, 424, 424, 424, // 160 - 167 750, 750, 750, 750, 1616, 1616, 1648, 1648, // 168 - 175 1424, 1424, 1456, 1456, 1488, 1488, 1520, 1520, // 176 - 183 1840, 1840, 1872, 1872, 1968, 1968, 8209, 8209, // 184 - 191 524, 524, 524, 524, 524, 524, 524, 524, // 192 - 199 556, 556, 556, 556, 556, 556, 556, 556, // 200 - 207 1552, 1552, 1584, 1584, 2000, 2000, 2032, 2032, // 208 - 215 976, 976, 1008, 1008, 1040, 1040, 1072, 1072, // 216 - 223 1296, 1296, 1328, 1328, 718, 718, 718, 718, // 224 - 231 456, 456, 456, 456, 456, 456, 456, 456, // 232 - 239 456, 456, 456, 456, 456, 456, 456, 456, // 240 - 247 456, 456, 456, 456, 456, 456, 456, 456, // 248 - 255 456, 456, 456, 456, 456, 456, 456, 456, // 256 - 263 326, 326, 326, 326, 326, 326, 326, 326, // 264 - 271 326, 326, 326, 326, 326, 326, 326, 326, // 272 - 279 326, 326, 326, 326, 326, 326, 326, 326, // 280 - 287 326, 326, 326, 326, 326, 326, 326, 326, // 288 - 295 326, 326, 326, 326, 326, 326, 326, 326, // 296 - 303 326, 326, 326, 326, 326, 326, 326, 326, // 304 - 311 326, 326, 326, 326, 326, 326, 326, 326, // 312 - 319 326, 326, 326, 326, 326, 326, 326, 326, // 320 - 327 358, 358, 358, 358, 358, 358, 358, 358, // 328 - 335 358, 358, 358, 358, 358, 358, 358, 358, // 336 - 343 358, 358, 358, 358, 358, 358, 358, 358, // 344 - 351 358, 358, 358, 358, 358, 358, 358, 358, // 352 - 359 358, 358, 358, 358, 358, 358, 358, 358, // 360 - 367 358, 358, 358, 358, 358, 358, 358, 358, // 368 - 375 358, 358, 358, 358, 358, 358, 358, 358, // 376 - 383 358, 358, 358, 358, 358, 358, 358, 358, // 384 - 391 490, 490, 490, 490, 490, 490, 490, 490, // 392 - 399 490, 490, 490, 490, 490, 490, 490, 490, // 400 - 407 4113, 4113, 6161, 6161, 848, 848, 880, 880, // 408 - 415 912, 912, 944, 944, 622, 622, 622, 622, // 416 - 423 654, 654, 654, 654, 1104, 1104, 1136, 1136, // 424 - 431 1168, 1168, 1200, 1200, 1232, 1232, 1264, 1264, // 432 - 439 686, 686, 686, 686, 1360, 1360, 1392, 1392, // 440 - 447 12, 12, 12, 12, 12, 12, 12, 12, // 448 - 455 390, 390, 390, 390, 390, 390, 390, 390, // 456 - 463 390, 390, 390, 390, 390, 390, 390, 390, // 464 - 471 390, 390, 390, 390, 390, 390, 390, 390, // 472 - 479 390, 390, 390, 390, 390, 390, 390, 390, // 480 - 487 390, 390, 390, 390, 390, 390, 390, 390, // 488 - 495 390, 390, 390, 390, 390, 390, 390, 390, // 496 - 503 390, 390, 390, 390, 390, 390, 390, 390, // 504 - 511 390, 390, 390, 390, 390, 390, 390, 390, }; static byte[] twoDCodes = { // 0 - 7 80, 88, 23, 71, 30, 30, 62, 62, // 8 - 15 4, 4, 4, 4, 4, 4, 4, 4, // 16 - 23 11, 11, 11, 11, 11, 11, 11, 11, // 24 - 31 11, 11, 11, 11, 11, 11, 11, 11, // 32 - 39 35, 35, 35, 35, 35, 35, 35, 35, // 40 - 47 35, 35, 35, 35, 35, 35, 35, 35, // 48 - 55 51, 51, 51, 51, 51, 51, 51, 51, // 56 - 63 51, 51, 51, 51, 51, 51, 51, 51, // 64 - 71 41, 41, 41, 41, 41, 41, 41, 41, // 72 - 79 41, 41, 41, 41, 41, 41, 41, 41, // 80 - 87 41, 41, 41, 41, 41, 41, 41, 41, // 88 - 95 41, 41, 41, 41, 41, 41, 41, 41, // 96 - 103 41, 41, 41, 41, 41, 41, 41, 41, // 104 - 111 41, 41, 41, 41, 41, 41, 41, 41, // 112 - 119 41, 41, 41, 41, 41, 41, 41, 41, // 120 - 127 41, 41, 41, 41, 41, 41, 41, 41, }; /** * @param fillOrder The fill order of the compressed data bytes. * @param w The width of the image in pixels * @param h The height of the image in pixels */ public TIFFFaxDecoder(int fillOrder, int w, int h) { this.fillOrder = fillOrder; this.w = w; // this.h = h; this.bitPointer = 0; this.bytePointer = 0; this.prevChangingElems = new int[w]; this.currChangingElems = new int[w]; } // One-dimensional decoding methods public void decode1D(byte[] buffer, byte[] compData, int startX, int height) { this.data = compData; int lineOffset = 0; int scanlineStride = (w + 7) / 8; bitPointer = 0; bytePointer = 0; for (int i = 0; i < height; i++) { decodeNextScanline(buffer, lineOffset, startX); lineOffset += scanlineStride; } } public void decodeNextScanline(byte[] buffer, int lineOffset, int bitOffset) { int bits = 0; int code = 0; int isT = 0; int current; int entry; int twoBits; boolean isWhite = true; // Initialize starting of the changing elements array changingElemSize = 0; // While scanline not complete while (bitOffset < w) { while (isWhite) { // White run current = nextNBits(10); entry = white[current]; // Get the 3 fields from the entry isT = entry & 0x0001; bits = (entry >>> 1) & 0x0f; if (bits == 12) { // Additional Make up code // Get the next 2 bits twoBits = nextLesserThan8Bits(2); // Consolidate the 2 new bits and last 2 bits into 4 bits current = ((current << 2) & 0x000c) | twoBits; entry = additionalMakeup[current]; bits = (entry >>> 1) & 0x07; // 3 bits 0000 0111 code = (entry >>> 4) & 0x0fff; // 12 bits bitOffset += code; // Skip white run updatePointer(4 - bits); } else if (bits == 0) { // ERROR throw new RuntimeException(PropertyUtil.getString("TIFFFaxDecoder0")); } else if (bits == 15) { // EOL throw new RuntimeException(PropertyUtil.getString("TIFFFaxDecoder1")); } else { // 11 bits - 0000 0111 1111 1111 = 0x07ff code = (entry >>> 5) & 0x07ff; bitOffset += code; updatePointer(10 - bits); if (isT == 0) { isWhite = false; currChangingElems[changingElemSize++] = bitOffset; } } } // Check whether this run completed one width, if so // advance to next byte boundary for compression = 2. if (bitOffset == w) { if (compression == 2) { advancePointer(); } break; } while (!isWhite) { // Black run current = nextLesserThan8Bits(4); entry = initBlack[current]; // Get the 3 fields from the entry isT = entry & 0x0001; bits = (entry >>> 1) & 0x000f; code = (entry >>> 5) & 0x07ff; if (code == 100) { current = nextNBits(9); entry = black[current]; // Get the 3 fields from the entry isT = entry & 0x0001; bits = (entry >>> 1) & 0x000f; code = (entry >>> 5) & 0x07ff; if (bits == 12) { // Additional makeup codes updatePointer(5); current = nextLesserThan8Bits(4); entry = additionalMakeup[current]; bits = (entry >>> 1) & 0x07; // 3 bits 0000 0111 code = (entry >>> 4) & 0x0fff; // 12 bits setToBlack(buffer, lineOffset, bitOffset, code); bitOffset += code; updatePointer(4 - bits); } else if (bits == 15) { // EOL code throw new RuntimeException(PropertyUtil.getString("TIFFFaxDecoder2")); } else { setToBlack(buffer, lineOffset, bitOffset, code); bitOffset += code; updatePointer(9 - bits); if (isT == 0) { isWhite = true; currChangingElems[changingElemSize++] = bitOffset; } } } else if (code == 200) { // Is a Terminating code current = nextLesserThan8Bits(2); entry = twoBitBlack[current]; code = (entry >>> 5) & 0x07ff; bits = (entry >>> 1) & 0x0f; setToBlack(buffer, lineOffset, bitOffset, code); bitOffset += code; updatePointer(2 - bits); isWhite = true; currChangingElems[changingElemSize++] = bitOffset; } else { // Is a Terminating code setToBlack(buffer, lineOffset, bitOffset, code); bitOffset += code; updatePointer(4 - bits); isWhite = true; currChangingElems[changingElemSize++] = bitOffset; } } // Check whether this run completed one width if (bitOffset == w) { if (compression == 2) { advancePointer(); } break; } } currChangingElems[changingElemSize++] = bitOffset; } // Two-dimensional decoding methods public void decode2D(byte[] buffer, byte[] compData, int startX, int height, long tiffT4Options) { this.data = compData; compression = 3; bitPointer = 0; bytePointer = 0; int scanlineStride = (w + 7) / 8; int a0; int a1; int b1; int b2; int[] b = new int[2]; int entry; int code; int bits; boolean isWhite; int currIndex = 0; int[] temp; // fillBits - dealt with this in readEOL // 1D/2D encoding - dealt with this in readEOL // uncompressedMode - haven't dealt with this yet. oneD = (int)(tiffT4Options & 0x01); // uncompressedMode = (int)((tiffT4Options & 0x02) >> 1); fillBits = (int)((tiffT4Options & 0x04) >> 2); // The data must start with an EOL code if (readEOL() != 1) { throw new RuntimeException(PropertyUtil.getString("TIFFFaxDecoder3")); } int lineOffset = 0; int bitOffset; // Then the 1D encoded scanline data will occur, changing elements // array gets set. decodeNextScanline(buffer, lineOffset, startX); lineOffset += scanlineStride; for (int lines = 1; lines < height; lines++) { // Every line must begin with an EOL followed by a bit which // indicates whether the following scanline is 1D or 2D encoded. if (readEOL() == 0) { // 2D encoded scanline follows // Initialize previous scanlines changing elements, and // initialize current scanline's changing elements array temp = prevChangingElems; prevChangingElems = currChangingElems; currChangingElems = temp; currIndex = 0; // a0 has to be set just before the start of this scanline. a0 = -1; isWhite = true; bitOffset = startX; lastChangingElement = 0; while (bitOffset < w) { // Get the next changing element getNextChangingElement(a0, isWhite, b); b1 = b[0]; b2 = b[1]; // Get the next seven bits entry = nextLesserThan8Bits(7); // Run these through the 2DCodes table entry = (int)(twoDCodes[entry] & 0xff); // Get the code and the number of bits used up code = (entry & 0x78) >>> 3; bits = entry & 0x07; if (code == 0) { if (!isWhite) { setToBlack(buffer, lineOffset, bitOffset, b2 - bitOffset); } bitOffset = a0 = b2; // Set pointer to consume the correct number of bits. updatePointer(7 - bits); } else if (code == 1) { // Horizontal updatePointer(7 - bits); // identify the next 2 codes. int number; if (isWhite) { number = decodeWhiteCodeWord(); bitOffset += number; currChangingElems[currIndex++] = bitOffset; number = decodeBlackCodeWord(); setToBlack(buffer, lineOffset, bitOffset, number); bitOffset += number; currChangingElems[currIndex++] = bitOffset; } else { number = decodeBlackCodeWord(); setToBlack(buffer, lineOffset, bitOffset, number); bitOffset += number; currChangingElems[currIndex++] = bitOffset; number = decodeWhiteCodeWord(); bitOffset += number; currChangingElems[currIndex++] = bitOffset; } a0 = bitOffset; } else if (code <= 8) { // Vertical a1 = b1 + (code - 5); currChangingElems[currIndex++] = a1; // We write the current color till a1 - 1 pos, // since a1 is where the next color starts if (!isWhite) { setToBlack(buffer, lineOffset, bitOffset, a1 - bitOffset); } bitOffset = a0 = a1; isWhite = !isWhite; updatePointer(7 - bits); } else { throw new RuntimeException(PropertyUtil.getString("TIFFFaxDecoder4")); } } // Add the changing element beyond the current scanline for the // other color too currChangingElems[currIndex++] = bitOffset; changingElemSize = currIndex; } else { // 1D encoded scanline follows decodeNextScanline(buffer, lineOffset, startX); } lineOffset += scanlineStride; } } public synchronized void decodeT6(byte[] buffer, byte[] compData, int startX, int height, long tiffT6Options) { this.data = compData; compression = 4; bitPointer = 0; bytePointer = 0; int scanlineStride = (w + 7) / 8; int a0; int a1; int b1; int b2; int entry; int code; int bits; boolean isWhite; int currIndex; int[] temp; // Return values from getNextChangingElement int[] b = new int[2]; // uncompressedMode - have written some code for this, but this // has not been tested due to lack of test images using this optional // uncompressedMode = (int)((tiffT6Options & 0x02) >> 1); // Local cached reference int[] cce = currChangingElems; // Assume invisible preceding row of all white pixels and insert // both black and white changing elements beyond the end of this // imaginary scanline. changingElemSize = 0; cce[changingElemSize++] = w; cce[changingElemSize++] = w; int lineOffset = 0; int bitOffset; for (int lines = 0; lines < height; lines++) { // a0 has to be set just before the start of the scanline. a0 = -1; isWhite = true; // Assign the changing elements of the previous scanline to // prevChangingElems and start putting this new scanline's // changing elements into the currChangingElems. temp = prevChangingElems; prevChangingElems = currChangingElems; cce = currChangingElems = temp; currIndex = 0; // Start decoding the scanline at startX in the raster bitOffset = startX; // Reset search start position for getNextChangingElement lastChangingElement = 0; // Till one whole scanline is decoded while (bitOffset < w) { // Get the next changing element getNextChangingElement(a0, isWhite, b); b1 = b[0]; b2 = b[1]; // Get the next seven bits entry = nextLesserThan8Bits(7); // Run these through the 2DCodes table entry = (int)(twoDCodes[entry] & 0xff); // Get the code and the number of bits used up code = (entry & 0x78) >>> 3; bits = entry & 0x07; if (code == 0) { // Pass // We always assume WhiteIsZero format for fax. if (!isWhite) { setToBlack(buffer, lineOffset, bitOffset, b2 - bitOffset); } bitOffset = a0 = b2; // Set pointer to only consume the correct number of bits. updatePointer(7 - bits); } else if (code == 1) { // Horizontal // Set pointer to only consume the correct number of bits. updatePointer(7 - bits); // identify the next 2 alternating color codes. int number; if (isWhite) { // Following are white and black runs number = decodeWhiteCodeWord(); bitOffset += number; cce[currIndex++] = bitOffset; number = decodeBlackCodeWord(); setToBlack(buffer, lineOffset, bitOffset, number); bitOffset += number; cce[currIndex++] = bitOffset; } else { // First a black run and then a white run follows number = decodeBlackCodeWord(); setToBlack(buffer, lineOffset, bitOffset, number); bitOffset += number; cce[currIndex++] = bitOffset; number = decodeWhiteCodeWord(); bitOffset += number; cce[currIndex++] = bitOffset; } a0 = bitOffset; } else if (code <= 8) { // Vertical a1 = b1 + (code - 5); cce[currIndex++] = a1; // We write the current color till a1 - 1 pos, // since a1 is where the next color starts if (!isWhite) { setToBlack(buffer, lineOffset, bitOffset, a1 - bitOffset); } bitOffset = a0 = a1; isWhite = !isWhite; updatePointer(7 - bits); } else if (code == 11) { if (nextLesserThan8Bits(3) != 7) { throw new RuntimeException(PropertyUtil.getString("TIFFFaxDecoder5")); } int zeros = 0; boolean exit = false; while (!exit) { while (nextLesserThan8Bits(1) != 1) { zeros++; } if (zeros > 5) { // Exit code // Zeros before exit code zeros = zeros - 6; if (!isWhite && (zeros > 0)) { cce[currIndex++] = bitOffset; } // Zeros before the exit code bitOffset += zeros; if (zeros > 0) { // Some zeros have been written isWhite = true; } // Read in the bit which specifies the color of // the following run if (nextLesserThan8Bits(1) == 0) { if (!isWhite) { cce[currIndex++] = bitOffset; } isWhite = true; } else { if (isWhite) { cce[currIndex++] = bitOffset; } isWhite = false; } exit = true; } if (zeros == 5) { if (!isWhite) { cce[currIndex++] = bitOffset; } bitOffset += zeros; // Last thing written was white isWhite = true; } else { bitOffset += zeros; cce[currIndex++] = bitOffset; setToBlack(buffer, lineOffset, bitOffset, 1); ++bitOffset; // Last thing written was black isWhite = false; } } } else { throw new RuntimeException(PropertyUtil.getString("TIFFFaxDecoder5")); } } // Add the changing element beyond the current scanline for the // other color too cce[currIndex++] = bitOffset; // Number of changing elements in this scanline. changingElemSize = currIndex; lineOffset += scanlineStride; } } private void setToBlack(byte[] buffer, int lineOffset, int bitOffset, int numBits) { int bitNum = 8 * lineOffset + bitOffset; int lastBit = bitNum + numBits; int byteNum = bitNum >> 3; // Handle bits in first byte int shift = bitNum & 0x7; if (shift > 0) { int maskVal = 1 << (7 - shift); byte val = buffer[byteNum]; while (maskVal > 0 && bitNum < lastBit) { val |= maskVal; maskVal >>= 1; ++bitNum; } buffer[byteNum] = val; } // Fill in 8 bits at a time byteNum = bitNum >> 3; while (bitNum < lastBit - 7) { buffer[byteNum++] = (byte)255; bitNum += 8; } // Fill in remaining bits while (bitNum < lastBit) { byteNum = bitNum >> 3; buffer[byteNum] |= 1 << (7 - (bitNum & 0x7)); ++bitNum; } } // Returns run length private int decodeWhiteCodeWord() { int current; int entry; int bits; int isT; int twoBits; int code = -1; int runLength = 0; boolean isWhite = true; while (isWhite) { current = nextNBits(10); entry = white[current]; // Get the 3 fields from the entry isT = entry & 0x0001; bits = (entry >>> 1) & 0x0f; if (bits == 12) { // Additional Make up code // Get the next 2 bits twoBits = nextLesserThan8Bits(2); // Consolidate the 2 new bits and last 2 bits into 4 bits current = ((current << 2) & 0x000c) | twoBits; entry = additionalMakeup[current]; bits = (entry >>> 1) & 0x07; // 3 bits 0000 0111 code = (entry >>> 4) & 0x0fff; // 12 bits runLength += code; updatePointer(4 - bits); } else if (bits == 0) { // ERROR throw new RuntimeException(PropertyUtil.getString("TIFFFaxDecoder0")); } else if (bits == 15) { // EOL throw new RuntimeException(PropertyUtil.getString("TIFFFaxDecoder1")); } else { // 11 bits - 0000 0111 1111 1111 = 0x07ff code = (entry >>> 5) & 0x07ff; runLength += code; updatePointer(10 - bits); if (isT == 0) { isWhite = false; } } } return runLength; } // Returns run length private int decodeBlackCodeWord() { int current; int entry; int bits; int isT; int code = -1; int runLength = 0; boolean isWhite = false; while (!isWhite) { current = nextLesserThan8Bits(4); entry = initBlack[current]; // Get the 3 fields from the entry // isT = entry & 0x0001; bits = (entry >>> 1) & 0x000f; code = (entry >>> 5) & 0x07ff; if (code == 100) { current = nextNBits(9); entry = black[current]; // Get the 3 fields from the entry isT = entry & 0x0001; bits = (entry >>> 1) & 0x000f; code = (entry >>> 5) & 0x07ff; if (bits == 12) { // Additional makeup codes updatePointer(5); current = nextLesserThan8Bits(4); entry = additionalMakeup[current]; bits = (entry >>> 1) & 0x07; // 3 bits 0000 0111 code = (entry >>> 4) & 0x0fff; // 12 bits runLength += code; updatePointer(4 - bits); } else if (bits == 15) { // EOL code throw new RuntimeException(PropertyUtil.getString("TIFFFaxDecoder2")); } else { runLength += code; updatePointer(9 - bits); if (isT == 0) { isWhite = true; } } } else if (code == 200) { // Is a Terminating code current = nextLesserThan8Bits(2); entry = twoBitBlack[current]; code = (entry >>> 5) & 0x07ff; runLength += code; bits = (entry >>> 1) & 0x0f; updatePointer(2 - bits); isWhite = true; } else { // Is a Terminating code runLength += code; updatePointer(4 - bits); isWhite = true; } } return runLength; } private int readEOL() { if (fillBits == 0) { if (nextNBits(12) != 1) { throw new RuntimeException(PropertyUtil.getString("TIFFFaxDecoder6")); } } else if (fillBits == 1) { // First EOL code word xxxx 0000 0000 0001 will occur // As many fill bits will be present as required to make // the EOL code of 12 bits end on a byte boundary. int bitsLeft = 8 - bitPointer; if (nextNBits(bitsLeft) != 0) { throw new RuntimeException(PropertyUtil.getString("TIFFFaxDecoder8")); } // If the number of bitsLeft is less than 8, then to have a 12 // bit EOL sequence, two more bytes are certainly going to be // required. The first of them has to be all zeros, so ensure // that. if (bitsLeft < 4) { if (nextNBits(8) != 0) { throw new RuntimeException(PropertyUtil.getString("TIFFFaxDecoder8")); } } // There might be a random number of fill bytes with 0s, so // loop till the EOL of 0000 0001 is found, as long as all // the bytes preceding it are 0's. int n; while ((n = nextNBits(8)) != 1) { // If not all zeros if (n != 0) { throw new RuntimeException(PropertyUtil.getString("TIFFFaxDecoder8")); } } } // If one dimensional encoding mode, then always return 1 if (oneD == 0) { return 1; } else { // Otherwise for 2D encoding mode, // The next one bit signifies 1D/2D encoding of next line. return nextLesserThan8Bits(1); } } private void getNextChangingElement(int a0, boolean isWhite, int[] ret) { // Local copies of instance variables int[] pce = this.prevChangingElems; int ces = this.changingElemSize; // If the previous match was at an odd element, we still // have to search the preceeding element. // int start = lastChangingElement & ~0x1; int start = lastChangingElement > 0 ? lastChangingElement - 1 : 0; if (isWhite) { start &= ~0x1; // Search even numbered elements } else { start |= 0x1; // Search odd numbered elements } int i = start; for (; i < ces; i += 2) { int temp = pce[i]; if (temp > a0) { lastChangingElement = i; ret[0] = temp; break; } } if (i + 1 < ces) { ret[1] = pce[i + 1]; } } private int nextNBits(int bitsToGet) { byte b; byte next; byte next2next; int l = data.length - 1; int bp = this.bytePointer; if (fillOrder == 1) { b = data[bp]; if (bp == l) { next = 0x00; next2next = 0x00; } else if ((bp + 1) == l) { next = data[bp + 1]; next2next = 0x00; } else { next = data[bp + 1]; next2next = data[bp + 2]; } } else if (fillOrder == 2) { b = flipTable[data[bp] & 0xff]; if (bp == l) { next = 0x00; next2next = 0x00; } else if ((bp + 1) == l) { next = flipTable[data[bp + 1] & 0xff]; next2next = 0x00; } else { next = flipTable[data[bp + 1] & 0xff]; next2next = flipTable[data[bp + 2] & 0xff]; } } else { throw new RuntimeException(PropertyUtil.getString("TIFFFaxDecoder7")); } int bitsLeft = 8 - bitPointer; int bitsFromNextByte = bitsToGet - bitsLeft; int bitsFromNext2NextByte = 0; if (bitsFromNextByte > 8) { bitsFromNext2NextByte = bitsFromNextByte - 8; bitsFromNextByte = 8; } bytePointer++; int i1 = (b & table1[bitsLeft]) << (bitsToGet - bitsLeft); int i2 = (next & table2[bitsFromNextByte]) >>> (8 - bitsFromNextByte); int i3 = 0; if (bitsFromNext2NextByte != 0) { i2 <<= bitsFromNext2NextByte; i3 = (next2next & table2[bitsFromNext2NextByte]) >>> (8 - bitsFromNext2NextByte); i2 |= i3; bytePointer++; bitPointer = bitsFromNext2NextByte; } else { if (bitsFromNextByte == 8) { bitPointer = 0; bytePointer++; } else { bitPointer = bitsFromNextByte; } } int i = i1 | i2; return i; } private int nextLesserThan8Bits(int bitsToGet) { byte b; byte next; int l = data.length - 1; int bp = this.bytePointer; if (fillOrder == 1) { b = data[bp]; if (bp == l) { next = 0x00; } else { next = data[bp + 1]; } } else if (fillOrder == 2) { b = flipTable[data[bp] & 0xff]; if (bp == l) { next = 0x00; } else { next = flipTable[data[bp + 1] & 0xff]; } } else { throw new RuntimeException(PropertyUtil.getString("TIFFFaxDecoder7")); } int bitsLeft = 8 - bitPointer; int bitsFromNextByte = bitsToGet - bitsLeft; int shift = bitsLeft - bitsToGet; int i1; int i2; if (shift >= 0) { i1 = (b & table1[bitsLeft]) >>> shift; bitPointer += bitsToGet; if (bitPointer == 8) { bitPointer = 0; bytePointer++; } } else { i1 = (b & table1[bitsLeft]) << (-shift); i2 = (next & table2[bitsFromNextByte]) >>> (8 - bitsFromNextByte); i1 |= i2; bytePointer++; bitPointer = bitsFromNextByte; } return i1; } // Move pointer backwards by given amount of bits private void updatePointer(int bitsToMoveBack) { int i = bitPointer - bitsToMoveBack; if (i < 0) { bytePointer--; bitPointer = 8 + i; } else { bitPointer = i; } } // Move to the next byte boundary private boolean advancePointer() { if (bitPointer != 0) { bytePointer++; bitPointer = 0; } return true; } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/codec/tiff/TIFFField.java0100644 0000000 0000000 00000034174 13777276623 030552 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: TIFFField.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.image.codec.tiff; import java.io.Serializable; // CSOFF: WhitespaceAround /** * A class representing a field in a TIFF 6.0 Image File Directory. * *

    The TIFF file format is described in more detail in the * comments for the TIFFDescriptor class. * *

    A field in a TIFF Image File Directory (IFD). A field is defined * as a sequence of values of identical data type. TIFF 6.0 defines * 12 data types, which are mapped internally onto the Java datatypes * byte, int, long, float, and double. * *

    This class is not a committed part of the JAI API. It may * be removed or changed in future releases of JAI. * * @see TIFFDirectory */ public class TIFFField implements Comparable, Serializable { /** Flag for 8 bit unsigned integers. */ public static final int TIFF_BYTE = 1; /** Flag for null-terminated ASCII strings. */ public static final int TIFF_ASCII = 2; /** Flag for 16 bit unsigned integers. */ public static final int TIFF_SHORT = 3; /** Flag for 32 bit unsigned integers. */ public static final int TIFF_LONG = 4; /** Flag for pairs of 32 bit unsigned integers. */ public static final int TIFF_RATIONAL = 5; /** Flag for 8 bit signed integers. */ public static final int TIFF_SBYTE = 6; /** Flag for 8 bit uninterpreted bytes. */ public static final int TIFF_UNDEFINED = 7; /** Flag for 16 bit signed integers. */ public static final int TIFF_SSHORT = 8; /** Flag for 32 bit signed integers. */ public static final int TIFF_SLONG = 9; /** Flag for pairs of 32 bit signed integers. */ public static final int TIFF_SRATIONAL = 10; /** Flag for 32 bit IEEE floats. */ public static final int TIFF_FLOAT = 11; /** Flag for 64 bit IEEE doubles. */ public static final int TIFF_DOUBLE = 12; private static final long serialVersionUID = 207783128222415437L; /** The tag number. */ int tag; /** The tag type. */ int type; /** The number of data items present in the field. */ int count; /** The field data. */ Object data; /** The default constructor. */ TIFFField() { } /** * Constructs a TIFFField with arbitrary data. The data * parameter must be an array of a Java type appropriate for the * type of the TIFF field. Since there is no available 32-bit * unsigned datatype, long is used. The mapping between types is * as follows: * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    TIFF type Java type
    TIFF_BYTE byte
    TIFF_ASCII String
    TIFF_SHORT char
    TIFF_LONG long
    TIFF_RATIONAL long[2]
    TIFF_SBYTE byte
    TIFF_UNDEFINED byte
    TIFF_SSHORT short
    TIFF_SLONG int
    TIFF_SRATIONAL int[2]
    TIFF_FLOAT float
    TIFF_DOUBLE double
    */ public TIFFField(int tag, int type, int count, Object data) { this.tag = tag; this.type = type; this.count = count; this.data = data; } /** * Returns the tag number, between 0 and 65535. */ public int getTag() { return tag; } /** * Returns the type of the data stored in the IFD. * For a TIFF6.0 file, the value will equal one of the * TIFF_ constants defined in this class. For future * revisions of TIFF, higher values are possible. * */ public int getType() { return type; } /** * Returns the number of elements in the IFD. */ public int getCount() { return count; } /** * Returns the data as an uninterpreted array of bytes. * The type of the field must be one of TIFF_BYTE, TIFF_SBYTE, * or TIFF_UNDEFINED; * *

    For data in TIFF_BYTE format, the application must take * care when promoting the data to longer integral types * to avoid sign extension. * *

    A ClassCastException will be thrown if the field is not * of type TIFF_BYTE, TIFF_SBYTE, or TIFF_UNDEFINED. */ public byte[] getAsBytes() { return (byte[])data; } /** * Returns TIFF_SHORT data as an array of chars (unsigned 16-bit * integers). * *

    A ClassCastException will be thrown if the field is not * of type TIFF_SHORT. */ public char[] getAsChars() { return (char[])data; } /** * Returns TIFF_SSHORT data as an array of shorts (signed 16-bit * integers). * *

    A ClassCastException will be thrown if the field is not * of type TIFF_SSHORT. */ public short[] getAsShorts() { return (short[])data; } /** * Returns TIFF_SLONG data as an array of ints (signed 32-bit * integers). * *

    A ClassCastException will be thrown if the field is not * of type TIFF_SLONG. */ public int[] getAsInts() { return (int[])data; } /** * Returns TIFF_LONG data as an array of longs (signed 64-bit * integers). * *

    A ClassCastException will be thrown if the field is not * of type TIFF_LONG. */ public long[] getAsLongs() { return (long[])data; } /** * Returns TIFF_FLOAT data as an array of floats. * *

    A ClassCastException will be thrown if the field is not * of type TIFF_FLOAT. */ public float[] getAsFloats() { return (float[])data; } /** * Returns TIFF_DOUBLE data as an array of doubles. * *

    A ClassCastException will be thrown if the field is not * of type TIFF_DOUBLE. */ public double[] getAsDoubles() { return (double[])data; } /** * Returns TIFF_SRATIONAL data as an array of 2-element arrays of ints. * *

    A ClassCastException will be thrown if the field is not * of type TIFF_SRATIONAL. */ public int[][] getAsSRationals() { return (int[][])data; } /** * Returns TIFF_RATIONAL data as an array of 2-element arrays of longs. * *

    A ClassCastException will be thrown if the field is not * of type TIFF_RATTIONAL. */ public long[][] getAsRationals() { return (long[][])data; } /** * Returns data in TIFF_BYTE, TIFF_SBYTE, TIFF_UNDEFINED, TIFF_SHORT, * TIFF_SSHORT, or TIFF_SLONG format as an int. * *

    TIFF_BYTE and TIFF_UNDEFINED data are treated as unsigned; * that is, no sign extension will take place and the returned * value will be in the range [0, 255]. TIFF_SBYTE data will * be returned in the range [-128, 127]. * *

    A ClassCastException will be thrown if the field is not of * type TIFF_BYTE, TIFF_SBYTE, TIFF_UNDEFINED, TIFF_SHORT, * TIFF_SSHORT, or TIFF_SLONG. */ public int getAsInt(int index) { switch (type) { case TIFF_BYTE: case TIFF_UNDEFINED: return ((byte[])data)[index] & 0xff; case TIFF_SBYTE: return ((byte[])data)[index]; case TIFF_SHORT: return ((char[])data)[index] & 0xffff; case TIFF_SSHORT: return ((short[])data)[index]; case TIFF_SLONG: return ((int[])data)[index]; default: throw new ClassCastException(); } } /** * Returns data in TIFF_BYTE, TIFF_SBYTE, TIFF_UNDEFINED, TIFF_SHORT, * TIFF_SSHORT, TIFF_SLONG, or TIFF_LONG format as a long. * *

    TIFF_BYTE and TIFF_UNDEFINED data are treated as unsigned; * that is, no sign extension will take place and the returned * value will be in the range [0, 255]. TIFF_SBYTE data will * be returned in the range [-128, 127]. * *

    A ClassCastException will be thrown if the field is not of * type TIFF_BYTE, TIFF_SBYTE, TIFF_UNDEFINED, TIFF_SHORT, * TIFF_SSHORT, TIFF_SLONG, or TIFF_LONG. */ public long getAsLong(int index) { switch (type) { case TIFF_BYTE: case TIFF_UNDEFINED: return ((byte[])data)[index] & 0xff; case TIFF_SBYTE: return ((byte[])data)[index]; case TIFF_SHORT: return ((char[])data)[index] & 0xffff; case TIFF_SSHORT: return ((short[])data)[index]; case TIFF_SLONG: return ((int[])data)[index]; case TIFF_LONG: return ((long[])data)[index]; default: throw new ClassCastException(); } } /** * Returns data in any numerical format as a float. Data in * TIFF_SRATIONAL or TIFF_RATIONAL format are evaluated by * dividing the numerator into the denominator using * double-precision arithmetic and then truncating to single * precision. Data in TIFF_SLONG, TIFF_LONG, or TIFF_DOUBLE * format may suffer from truncation. * *

    A ClassCastException will be thrown if the field is * of type TIFF_UNDEFINED or TIFF_ASCII. */ public float getAsFloat(int index) { switch (type) { case TIFF_BYTE: return ((byte[])data)[index] & 0xff; case TIFF_SBYTE: return ((byte[])data)[index]; case TIFF_SHORT: return ((char[])data)[index] & 0xffff; case TIFF_SSHORT: return ((short[])data)[index]; case TIFF_SLONG: return ((int[])data)[index]; case TIFF_LONG: return ((long[])data)[index]; case TIFF_FLOAT: return ((float[])data)[index]; case TIFF_DOUBLE: return (float)((double[])data)[index]; case TIFF_SRATIONAL: int[] ivalue = getAsSRational(index); return (float)((double)ivalue[0] / ivalue[1]); case TIFF_RATIONAL: long[] lvalue = getAsRational(index); return (float)((double)lvalue[0] / lvalue[1]); default: throw new ClassCastException(); } } /** * Returns data in any numerical format as a float. Data in * TIFF_SRATIONAL or TIFF_RATIONAL format are evaluated by * dividing the numerator into the denominator using * double-precision arithmetic. * *

    A ClassCastException will be thrown if the field is of * type TIFF_UNDEFINED or TIFF_ASCII. */ public double getAsDouble(int index) { switch (type) { case TIFF_BYTE: return ((byte[])data)[index] & 0xff; case TIFF_SBYTE: return ((byte[])data)[index]; case TIFF_SHORT: return ((char[])data)[index] & 0xffff; case TIFF_SSHORT: return ((short[])data)[index]; case TIFF_SLONG: return ((int[])data)[index]; case TIFF_LONG: return ((long[])data)[index]; case TIFF_FLOAT: return ((float[])data)[index]; case TIFF_DOUBLE: return ((double[])data)[index]; case TIFF_SRATIONAL: int[] ivalue = getAsSRational(index); return (double)ivalue[0] / ivalue[1]; case TIFF_RATIONAL: long[] lvalue = getAsRational(index); return (double)lvalue[0] / lvalue[1]; default: throw new ClassCastException(); } } /** * Returns a TIFF_ASCII data item as a String. * *

    A ClassCastException will be thrown if the field is not * of type TIFF_ASCII. */ public String getAsString(int index) { return ((String[])data)[index]; } /** * Returns a TIFF_SRATIONAL data item as a two-element array * of ints. * *

    A ClassCastException will be thrown if the field is not * of type TIFF_SRATIONAL. */ public int[] getAsSRational(int index) { return ((int[][])data)[index]; } /** * Returns a TIFF_RATIONAL data item as a two-element array * of ints. * *

    A ClassCastException will be thrown if the field is not * of type TIFF_RATIONAL. */ public long[] getAsRational(int index) { return ((long[][])data)[index]; } /** * Compares this TIFFField with another * TIFFField by comparing the tags. * *

    Note: this class has a natural ordering that is inconsistent * with equals(). * * @throws NullPointerException if the parameter is null. * @throws ClassCastException if the parameter is not a * TIFFField. */ public int compareTo(Object o) { if (o == null) { throw new NullPointerException(); } int oTag = ((TIFFField)o).getTag(); if (tag < oTag) { return -1; } else if (tag > oTag) { return 1; } else { return 0; } } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/codec/tiff/TIFFImage.java0100644 0000000 0000000 00000212564 13777276623 030552 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: TIFFImage.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.image.codec.tiff; import java.awt.Rectangle; import java.awt.Transparency; import java.awt.color.ColorSpace; import java.awt.image.ColorModel; import java.awt.image.ComponentColorModel; import java.awt.image.DataBuffer; import java.awt.image.DataBufferByte; import java.awt.image.DataBufferInt; import java.awt.image.DataBufferShort; import java.awt.image.DataBufferUShort; import java.awt.image.IndexColorModel; import java.awt.image.MultiPixelPackedSampleModel; import java.awt.image.PixelInterleavedSampleModel; import java.awt.image.Raster; import java.awt.image.SampleModel; import java.awt.image.WritableRaster; import java.io.IOException; import java.util.HashMap; import java.util.Map; import java.util.zip.DataFormatException; import java.util.zip.Inflater; import org.apache.xmlgraphics.image.codec.util.PropertyUtil; import org.apache.xmlgraphics.image.codec.util.SeekableStream; import org.apache.xmlgraphics.image.rendered.AbstractRed; import org.apache.xmlgraphics.image.rendered.CachableRed; // CSOFF: LocalVariableName // CSOFF: MissingSwitchDefault // CSOFF: MultipleVariableDeclarations // CSOFF: OperatorWrap // CSOFF: WhitespaceAround public class TIFFImage extends AbstractRed { // Compression types public static final int COMP_NONE = 1; public static final int COMP_FAX_G3_1D = 2; public static final int COMP_FAX_G3_2D = 3; public static final int COMP_FAX_G4_2D = 4; public static final int COMP_LZW = 5; public static final int COMP_JPEG_OLD = 6; public static final int COMP_JPEG_TTN2 = 7; public static final int COMP_PACKBITS = 32773; public static final int COMP_DEFLATE = 32946; // Image types private static final int TYPE_UNSUPPORTED = -1; private static final int TYPE_BILEVEL = 0; private static final int TYPE_GRAY_4BIT = 1; private static final int TYPE_GRAY = 2; private static final int TYPE_GRAY_ALPHA = 3; private static final int TYPE_PALETTE = 4; private static final int TYPE_RGB = 5; private static final int TYPE_RGB_ALPHA = 6; private static final int TYPE_YCBCR_SUB = 7; private static final int TYPE_GENERIC = 8; // Incidental tags private static final int TIFF_JPEG_TABLES = 347; private static final int TIFF_YCBCR_SUBSAMPLING = 530; SeekableStream stream; int tileSize; int tilesX; int tilesY; long[] tileOffsets; long[] tileByteCounts; char[] colormap; int sampleSize; int compression; byte[] palette; int numBands; int chromaSubH; int chromaSubV; // Fax compression related variables long tiffT4Options; long tiffT6Options; int fillOrder; // LZW compression related variable int predictor; // DEFLATE variables Inflater inflater; // Endian-ness indicator boolean isBigEndian; int imageType; boolean isWhiteZero; int dataType; boolean decodePaletteAsShorts; boolean tiled; // Decoders private TIFFFaxDecoder decoder; private TIFFLZWDecoder lzwDecoder; /** * Inflates deflated into inflated using the * Inflater constructed during class instantiation. */ private void inflate(byte[] deflated, byte[] inflated) { inflater.setInput(deflated); try { inflater.inflate(inflated); } catch (DataFormatException dfe) { throw new RuntimeException(PropertyUtil.getString("TIFFImage17") + ": " + dfe.getMessage()); } inflater.reset(); } private static SampleModel createPixelInterleavedSampleModel( int dataType, int tileWidth, int tileHeight, int bands) { int [] bandOffsets = new int[bands]; for (int i = 0; i < bands; i++) { bandOffsets[i] = i; } return new PixelInterleavedSampleModel( dataType, tileWidth, tileHeight, bands, tileWidth * bands, bandOffsets); } /** * Return as a long[] the value of a TIFF_LONG or TIFF_SHORT field. */ private long[] getFieldAsLongs(TIFFField field) { long[] value = null; if (field.getType() == TIFFField.TIFF_SHORT) { char[] charValue = field.getAsChars(); value = new long[charValue.length]; for (int i = 0; i < charValue.length; i++) { value[i] = charValue[i] & 0xffff; } } else if (field.getType() == TIFFField.TIFF_LONG) { value = field.getAsLongs(); } else { throw new RuntimeException(PropertyUtil.getString("TIFFImage18") + ": " + field.getType()); } return value; } /** * Constructs a TIFFImage that acquires its data from a given * SeekableStream and reads from a particular IFD of the stream. * The index of the first IFD is 0. * * @param stream the SeekableStream to read from. * @param param an instance of TIFFDecodeParam, or null. * @param directory the index of the IFD to read from. */ public TIFFImage(SeekableStream stream, TIFFDecodeParam param, int directory) throws IOException { this.stream = stream; if (param == null) { param = new TIFFDecodeParam(); } decodePaletteAsShorts = param.getDecodePaletteAsShorts(); // Read the specified directory. TIFFDirectory dir = param.getIFDOffset() == null ? new TIFFDirectory(stream, directory) : new TIFFDirectory(stream, param.getIFDOffset(), directory); // Get the number of samples per pixel TIFFField sfield = dir.getField(TIFFImageDecoder.TIFF_SAMPLES_PER_PIXEL); int samplesPerPixel = sfield == null ? 1 : (int)sfield.getAsLong(0); // Read the TIFF_PLANAR_CONFIGURATION field TIFFField planarConfigurationField = dir.getField(TIFFImageDecoder.TIFF_PLANAR_CONFIGURATION); char[] planarConfiguration = planarConfigurationField == null ? new char[] {1} : planarConfigurationField.getAsChars(); // Support planar format (band sequential) only for 1 sample/pixel. if (planarConfiguration[0] != 1 && samplesPerPixel != 1) { throw new RuntimeException(PropertyUtil.getString("TIFFImage0")); } // Read the TIFF_BITS_PER_SAMPLE field TIFFField bitsField = dir.getField(TIFFImageDecoder.TIFF_BITS_PER_SAMPLE); char[] bitsPerSample = null; if (bitsField != null) { bitsPerSample = bitsField.getAsChars(); } else { bitsPerSample = new char[] {1}; // Ensure that all samples have the same bit depth. for (int i = 1; i < bitsPerSample.length; i++) { if (bitsPerSample[i] != bitsPerSample[0]) { throw new RuntimeException(PropertyUtil.getString("TIFFImage1")); } } } sampleSize = bitsPerSample[0]; // Read the TIFF_SAMPLE_FORMAT tag to see whether the data might be // signed or floating point TIFFField sampleFormatField = dir.getField(TIFFImageDecoder.TIFF_SAMPLE_FORMAT); char[] sampleFormat = null; if (sampleFormatField != null) { sampleFormat = sampleFormatField.getAsChars(); // Check that all the samples have the same format for (int l = 1; l < sampleFormat.length; l++) { if (sampleFormat[l] != sampleFormat[0]) { throw new RuntimeException(PropertyUtil.getString("TIFFImage2")); } } } else { sampleFormat = new char[] {1}; } // Set the data type based on the sample size and format. boolean isValidDataFormat = false; switch (sampleSize) { case 1: case 4: case 8: if (sampleFormat[0] != 3) { // Ignore whether signed or unsigned: treat all as unsigned. dataType = DataBuffer.TYPE_BYTE; isValidDataFormat = true; } break; case 16: if (sampleFormat[0] != 3) { dataType = sampleFormat[0] == 2 ? DataBuffer.TYPE_SHORT : DataBuffer.TYPE_USHORT; isValidDataFormat = true; } break; case 32: if (sampleFormat[0] == 3) { isValidDataFormat = false; } else { dataType = DataBuffer.TYPE_INT; isValidDataFormat = true; } break; } if (!isValidDataFormat) { throw new RuntimeException(PropertyUtil.getString("TIFFImage3")); } // Figure out what compression if any, is being used. TIFFField compField = dir.getField(TIFFImageDecoder.TIFF_COMPRESSION); compression = compField == null ? COMP_NONE : compField.getAsInt(0); // Get the photometric interpretation. int photometricType; TIFFField photometricTypeField = dir.getField( TIFFImageDecoder.TIFF_PHOTOMETRIC_INTERPRETATION); if (photometricTypeField == null) { photometricType = 0; // White is zero } else { photometricType = photometricTypeField.getAsInt(0); } // Determine which kind of image we are dealing with. imageType = TYPE_UNSUPPORTED; switch(photometricType) { case 0: // WhiteIsZero isWhiteZero = true; case 1: // BlackIsZero if (sampleSize == 1 && samplesPerPixel == 1) { imageType = TYPE_BILEVEL; } else if (sampleSize == 4 && samplesPerPixel == 1) { imageType = TYPE_GRAY_4BIT; } else if (sampleSize % 8 == 0) { if (samplesPerPixel == 1) { imageType = TYPE_GRAY; } else if (samplesPerPixel == 2) { imageType = TYPE_GRAY_ALPHA; } else { imageType = TYPE_GENERIC; } } break; case 2: // RGB if (sampleSize % 8 == 0) { if (samplesPerPixel == 3) { imageType = TYPE_RGB; } else if (samplesPerPixel == 4) { imageType = TYPE_RGB_ALPHA; } else { imageType = TYPE_GENERIC; } } break; case 3: // RGB Palette if (samplesPerPixel == 1 && (sampleSize == 4 || sampleSize == 8 || sampleSize == 16)) { imageType = TYPE_PALETTE; } break; case 4: // Transparency mask if (sampleSize == 1 && samplesPerPixel == 1) { imageType = TYPE_BILEVEL; } break; default: // Other including CMYK, CIE L*a*b*, unknown. if (sampleSize % 8 == 0) { imageType = TYPE_GENERIC; } } // Bail out if not one of the supported types. if (imageType == TYPE_UNSUPPORTED) { throw new RuntimeException(PropertyUtil.getString("TIFFImage4") + ": " + imageType); } // Set basic image layout Rectangle bounds = new Rectangle( 0, 0, (int)dir.getFieldAsLong(TIFFImageDecoder.TIFF_IMAGE_WIDTH), (int)dir.getFieldAsLong(TIFFImageDecoder.TIFF_IMAGE_LENGTH)); // Set a preliminary band count. This may be changed later as needed. numBands = samplesPerPixel; // Figure out if any extra samples are present. TIFFField efield = dir.getField(TIFFImageDecoder.TIFF_EXTRA_SAMPLES); int extraSamples = efield == null ? 0 : (int)efield.getAsLong(0); int tileWidth; int tileHeight; if (dir.getField(TIFFImageDecoder.TIFF_TILE_OFFSETS) != null) { tiled = true; // Image is in tiled format tileWidth = (int)dir.getFieldAsLong(TIFFImageDecoder.TIFF_TILE_WIDTH); tileHeight = (int)dir.getFieldAsLong(TIFFImageDecoder.TIFF_TILE_LENGTH); tileOffsets = (dir.getField(TIFFImageDecoder.TIFF_TILE_OFFSETS)).getAsLongs(); tileByteCounts = getFieldAsLongs(dir.getField(TIFFImageDecoder.TIFF_TILE_BYTE_COUNTS)); } else { tiled = false; // Image is in stripped format, looks like tiles to us // Note: Some legacy files may have tile width and height // written but use the strip offsets and byte counts fields // instead of the tile offsets and byte counts. Therefore // we default here to the tile dimensions if they are written. tileWidth = dir.getField(TIFFImageDecoder.TIFF_TILE_WIDTH) != null ? (int)dir.getFieldAsLong(TIFFImageDecoder.TIFF_TILE_WIDTH) : bounds.width; TIFFField field = dir.getField(TIFFImageDecoder.TIFF_ROWS_PER_STRIP); if (field == null) { // Default is infinity (2^32 -1), basically the entire image tileHeight = dir.getField(TIFFImageDecoder.TIFF_TILE_LENGTH) != null ? (int)dir.getFieldAsLong(TIFFImageDecoder.TIFF_TILE_LENGTH) : bounds.height; } else { long l = field.getAsLong(0); long infinity = 1; infinity = (infinity << 32) - 1; if (l == infinity) { // 2^32 - 1 (effectively infinity, entire image is 1 strip) tileHeight = bounds.height; } else { tileHeight = (int)l; } } TIFFField tileOffsetsField = dir.getField(TIFFImageDecoder.TIFF_STRIP_OFFSETS); if (tileOffsetsField == null) { throw new RuntimeException(PropertyUtil.getString("TIFFImage5")); } else { tileOffsets = getFieldAsLongs(tileOffsetsField); } TIFFField tileByteCountsField = dir.getField(TIFFImageDecoder.TIFF_STRIP_BYTE_COUNTS); if (tileByteCountsField == null) { throw new RuntimeException(PropertyUtil.getString("TIFFImage6")); } else { tileByteCounts = getFieldAsLongs(tileByteCountsField); } } // Calculate number of tiles and the tileSize in bytes tilesX = (bounds.width + tileWidth - 1) / tileWidth; tilesY = (bounds.height + tileHeight - 1) / tileHeight; tileSize = tileWidth * tileHeight * numBands; // Check whether big endian or little endian format is used. isBigEndian = dir.isBigEndian(); TIFFField fillOrderField = dir.getField(TIFFImageDecoder.TIFF_FILL_ORDER); if (fillOrderField != null) { fillOrder = fillOrderField.getAsInt(0); } else { // Default Fill Order fillOrder = 1; } switch(compression) { case COMP_NONE: case COMP_PACKBITS: // Do nothing. break; case COMP_DEFLATE: inflater = new Inflater(); break; case COMP_FAX_G3_1D: case COMP_FAX_G3_2D: case COMP_FAX_G4_2D: if (sampleSize != 1) { throw new RuntimeException(PropertyUtil.getString("TIFFImage7")); } // Fax T.4 compression options if (compression == 3) { TIFFField t4OptionsField = dir.getField(TIFFImageDecoder.TIFF_T4_OPTIONS); if (t4OptionsField != null) { tiffT4Options = t4OptionsField.getAsLong(0); } else { // Use default value tiffT4Options = 0; } } // Fax T.6 compression options if (compression == 4) { TIFFField t6OptionsField = dir.getField(TIFFImageDecoder.TIFF_T6_OPTIONS); if (t6OptionsField != null) { tiffT6Options = t6OptionsField.getAsLong(0); } else { // Use default value tiffT6Options = 0; } } // Fax encoding, need to create the Fax decoder. decoder = new TIFFFaxDecoder(fillOrder, tileWidth, tileHeight); break; case COMP_LZW: // LZW compression used, need to create the LZW decoder. TIFFField predictorField = dir.getField(TIFFImageDecoder.TIFF_PREDICTOR); if (predictorField == null) { predictor = 1; } else { predictor = predictorField.getAsInt(0); if (predictor != 1 && predictor != 2) { throw new RuntimeException(PropertyUtil.getString("TIFFImage8")); } if (predictor == 2 && sampleSize != 8) { throw new RuntimeException(PropertyUtil.getString("TIFFImage9")); } } lzwDecoder = new TIFFLZWDecoder(tileWidth, predictor, samplesPerPixel); break; case COMP_JPEG_OLD: throw new RuntimeException(PropertyUtil.getString("TIFFImage15")); default: throw new RuntimeException(PropertyUtil.getString("TIFFImage10") + ": " + compression); } ColorModel colorModel = null; SampleModel sampleModel = null; switch(imageType) { case TYPE_BILEVEL: case TYPE_GRAY_4BIT: sampleModel = new MultiPixelPackedSampleModel(dataType, tileWidth, tileHeight, sampleSize); if (imageType == TYPE_BILEVEL) { byte[] map = new byte[] {(byte)(isWhiteZero ? 255 : 0), (byte)(isWhiteZero ? 0 : 255)}; colorModel = new IndexColorModel(1, 2, map, map, map); } else { byte [] map = new byte[16]; if (isWhiteZero) { for (int i = 0; i < map.length; i++) { map[i] = (byte)(255 - (16 * i)); } } else { for (int i = 0; i < map.length; i++) { map[i] = (byte)(16 * i); } } colorModel = new IndexColorModel(4, 16, map, map, map); } break; case TYPE_GRAY: case TYPE_GRAY_ALPHA: case TYPE_RGB: case TYPE_RGB_ALPHA: // Create a pixel interleaved SampleModel with decreasing // band offsets. int[] reverseOffsets = new int[numBands]; for (int i = 0; i < numBands; i++) { reverseOffsets[i] = numBands - 1 - i; } sampleModel = new PixelInterleavedSampleModel( dataType, tileWidth, tileHeight, numBands, numBands * tileWidth, reverseOffsets); if (imageType == TYPE_GRAY) { colorModel = new ComponentColorModel( ColorSpace.getInstance(ColorSpace.CS_GRAY), new int[] {sampleSize}, false, false, Transparency.OPAQUE, dataType); } else if (imageType == TYPE_RGB) { colorModel = new ComponentColorModel( ColorSpace.getInstance(ColorSpace.CS_sRGB), new int[] {sampleSize, sampleSize, sampleSize}, false, false, Transparency.OPAQUE, dataType); } else { // hasAlpha // Transparency.OPAQUE signifies image data that is // completely opaque, meaning that all pixels have an alpha // value of 1.0. So the extra band gets ignored, which is // what we want. int transparency = Transparency.OPAQUE; if (extraSamples == 1) { // associated (premultiplied) alpha transparency = Transparency.TRANSLUCENT; } else if (extraSamples == 2) { // unassociated alpha transparency = Transparency.BITMASK; } colorModel = createAlphaComponentColorModel(dataType, numBands, extraSamples == 1, transparency); } break; case TYPE_GENERIC: case TYPE_YCBCR_SUB: // For this case we can't display the image, so we create a // SampleModel with increasing bandOffsets, and keep the // ColorModel as null, as there is no appropriate ColorModel. int[] bandOffsets = new int[numBands]; for (int i = 0; i < numBands; i++) { bandOffsets[i] = i; } sampleModel = new PixelInterleavedSampleModel( dataType, tileWidth, tileHeight, numBands, numBands * tileWidth, bandOffsets); colorModel = null; break; case TYPE_PALETTE: // Get the colormap TIFFField cfield = dir.getField(TIFFImageDecoder.TIFF_COLORMAP); if (cfield == null) { throw new RuntimeException(PropertyUtil.getString("TIFFImage11")); } else { colormap = cfield.getAsChars(); } // Could be either 1 or 3 bands depending on whether we use // IndexColorModel or not. if (decodePaletteAsShorts) { numBands = 3; // If no SampleFormat tag was specified and if the // sampleSize is less than or equal to 8, then the // dataType was initially set to byte, but now we want to // expand the palette as shorts, so the dataType should // be ushort. if (dataType == DataBuffer.TYPE_BYTE) { dataType = DataBuffer.TYPE_USHORT; } // Data will have to be unpacked into a 3 band short image // as we do not have a IndexColorModel that can deal with // a colormodel whose entries are of short data type. sampleModel = createPixelInterleavedSampleModel( dataType, tileWidth, tileHeight, numBands); colorModel = new ComponentColorModel( ColorSpace.getInstance(ColorSpace.CS_sRGB), new int[] {16, 16, 16}, false, false, Transparency.OPAQUE, dataType); } else { numBands = 1; if (sampleSize == 4) { // Pixel data will not be unpacked, will use // MPPSM to store packed data and // IndexColorModel to do the unpacking. sampleModel = new MultiPixelPackedSampleModel( DataBuffer.TYPE_BYTE, tileWidth, tileHeight, sampleSize); } else if (sampleSize == 8) { sampleModel = createPixelInterleavedSampleModel( DataBuffer.TYPE_BYTE, tileWidth, tileHeight, numBands); } else if (sampleSize == 16) { // Here datatype has to be unsigned since we // are storing indices into the // IndexColorModel palette. Ofcourse the // actual palette entries are allowed to be // negative. dataType = DataBuffer.TYPE_USHORT; sampleModel = createPixelInterleavedSampleModel( DataBuffer.TYPE_USHORT, tileWidth, tileHeight, numBands); } int bandLength = colormap.length / 3; byte[] r = new byte[bandLength]; byte[] g = new byte[bandLength]; byte[] b = new byte[bandLength]; int gIndex = bandLength; int bIndex = bandLength * 2; if (dataType == DataBuffer.TYPE_SHORT) { for (int i = 0; i < bandLength; i++) { r[i] = param.decodeSigned16BitsTo8Bits( (short)colormap[i]); g[i] = param.decodeSigned16BitsTo8Bits( (short)colormap[gIndex + i]); b[i] = param.decodeSigned16BitsTo8Bits( (short)colormap[bIndex + i]); } } else { for (int i = 0; i < bandLength; i++) { r[i] = param.decode16BitsTo8Bits( colormap[i] & 0xffff); g[i] = param.decode16BitsTo8Bits( colormap[gIndex + i] & 0xffff); b[i] = param.decode16BitsTo8Bits( colormap[bIndex + i] & 0xffff); } } colorModel = new IndexColorModel(sampleSize, bandLength, r, g, b); } break; default: throw new RuntimeException(PropertyUtil.getString("TIFFImage4") + ": " + imageType); } Map properties = new HashMap(); // Set a property "tiff_directory". properties.put("tiff_directory", dir); // System.out.println("Constructed TIFF"); init((CachableRed)null, bounds, colorModel, sampleModel, 0, 0, properties); } /** * Reads a private IFD from a given offset in the stream. This * method may be used to obtain IFDs that are referenced * only by private tag values. */ public TIFFDirectory getPrivateIFD(long offset) throws IOException { return new TIFFDirectory(stream, offset, 0); } public WritableRaster copyData(WritableRaster wr) { copyToRaster(wr); return wr; } /** * Returns tile (tileX, tileY) as a Raster. */ public synchronized Raster getTile(int tileX, int tileY) { if ((tileX < 0) || (tileX >= tilesX) || (tileY < 0) || (tileY >= tilesY)) { throw new IllegalArgumentException(PropertyUtil.getString("TIFFImage12")); } // System.out.println("Called TIFF getTile:" + tileX + "," + tileY); // Get the data array out of the DataBuffer byte[] bdata = null; short[] sdata = null; int[] idata = null; SampleModel sampleModel = getSampleModel(); WritableRaster tile = makeTile(tileX, tileY); DataBuffer buffer = tile.getDataBuffer(); int dataType = sampleModel.getDataType(); if (dataType == DataBuffer.TYPE_BYTE) { bdata = ((DataBufferByte)buffer).getData(); } else if (dataType == DataBuffer.TYPE_USHORT) { sdata = ((DataBufferUShort)buffer).getData(); } else if (dataType == DataBuffer.TYPE_SHORT) { sdata = ((DataBufferShort)buffer).getData(); } else if (dataType == DataBuffer.TYPE_INT) { idata = ((DataBufferInt)buffer).getData(); } // Variables used for swapping when converting from RGB to BGR byte bswap; short sswap; int iswap; // Save original file pointer position and seek to tile data location. long saveOffset = 0; try { saveOffset = stream.getFilePointer(); stream.seek(tileOffsets[tileY * tilesX + tileX]); } catch (IOException ioe) { throw new RuntimeException(PropertyUtil.getString("TIFFImage13") + ": " + ioe.getMessage()); } // Number of bytes in this tile (strip) after compression. int byteCount = (int)tileByteCounts[tileY * tilesX + tileX]; // Find out the number of bytes in the current tile Rectangle newRect; if (!tiled) { newRect = tile.getBounds(); } else { newRect = new Rectangle(tile.getMinX(), tile.getMinY(), tileWidth, tileHeight); } int unitsInThisTile = newRect.width * newRect.height * numBands; // Allocate read buffer if needed. byte[] data = compression != COMP_NONE || imageType == TYPE_PALETTE ? new byte[byteCount] : null; // Read the data, uncompressing as needed. There are four cases: // bilevel, palette-RGB, 4-bit grayscale, and everything else. if (imageType == TYPE_BILEVEL) { // bilevel try { if (compression == COMP_PACKBITS) { stream.readFully(data, 0, byteCount); // Since the decompressed data will still be packed // 8 pixels into 1 byte, calculate bytesInThisTile int bytesInThisTile; if ((newRect.width % 8) == 0) { bytesInThisTile = (newRect.width / 8) * newRect.height; } else { bytesInThisTile = (newRect.width / 8 + 1) * newRect.height; } decodePackbits(data, bytesInThisTile, bdata); } else if (compression == COMP_LZW) { stream.readFully(data, 0, byteCount); lzwDecoder.decode(data, bdata, newRect.height); } else if (compression == COMP_FAX_G3_1D) { stream.readFully(data, 0, byteCount); decoder.decode1D(bdata, data, 0, newRect.height); } else if (compression == COMP_FAX_G3_2D) { stream.readFully(data, 0, byteCount); decoder.decode2D(bdata, data, 0, newRect.height, tiffT4Options); } else if (compression == COMP_FAX_G4_2D) { stream.readFully(data, 0, byteCount); decoder.decodeT6(bdata, data, 0, newRect.height, tiffT6Options); } else if (compression == COMP_DEFLATE) { stream.readFully(data, 0, byteCount); inflate(data, bdata); } else if (compression == COMP_NONE) { stream.readFully(bdata, 0, byteCount); } stream.seek(saveOffset); } catch (IOException ioe) { throw new RuntimeException(PropertyUtil.getString("TIFFImage13") + ": " + ioe.getMessage()); } } else if (imageType == TYPE_PALETTE) { // palette-RGB if (sampleSize == 16) { if (decodePaletteAsShorts) { short[] tempData = null; // At this point the data is 1 banded and will // become 3 banded only after we've done the palette // lookup, since unitsInThisTile was calculated with // 3 bands, we need to divide this by 3. int unitsBeforeLookup = unitsInThisTile / 3; // Since unitsBeforeLookup is the number of shorts, // but we do our decompression in terms of bytes, we // need to multiply it by 2 in order to figure out // how many bytes we'll get after decompression. int entries = unitsBeforeLookup * 2; // Read the data, if compressed, decode it, reset the pointer try { if (compression == COMP_PACKBITS) { stream.readFully(data, 0, byteCount); byte[] byteArray = new byte[entries]; decodePackbits(data, entries, byteArray); tempData = new short[unitsBeforeLookup]; interpretBytesAsShorts(byteArray, tempData, unitsBeforeLookup); } else if (compression == COMP_LZW) { // Read in all the compressed data for this tile stream.readFully(data, 0, byteCount); byte[] byteArray = new byte[entries]; lzwDecoder.decode(data, byteArray, newRect.height); tempData = new short[unitsBeforeLookup]; interpretBytesAsShorts(byteArray, tempData, unitsBeforeLookup); } else if (compression == COMP_DEFLATE) { stream.readFully(data, 0, byteCount); byte[] byteArray = new byte[entries]; inflate(data, byteArray); tempData = new short[unitsBeforeLookup]; interpretBytesAsShorts(byteArray, tempData, unitsBeforeLookup); } else if (compression == COMP_NONE) { // byteCount tells us how many bytes are there // in this tile, but we need to read in shorts, // which will take half the space, so while // allocating we divide byteCount by 2. tempData = new short[byteCount / 2]; readShorts(byteCount / 2, tempData); } stream.seek(saveOffset); } catch (IOException ioe) { throw new RuntimeException(PropertyUtil.getString("TIFFImage13") + ": " + ioe.getMessage()); } if (dataType == DataBuffer.TYPE_USHORT) { // Expand the palette image into an rgb image with ushort // data type. int cmapValue; int count = 0; int lookup; int len = colormap.length / 3; int len2 = len * 2; for (int i = 0; i < unitsBeforeLookup; i++) { // Get the index into the colormap lookup = tempData[i] & 0xffff; // Get the blue value cmapValue = colormap[lookup + len2]; sdata[count++] = (short)(cmapValue & 0xffff); // Get the green value cmapValue = colormap[lookup + len]; sdata[count++] = (short)(cmapValue & 0xffff); // Get the red value cmapValue = colormap[lookup]; sdata[count++] = (short)(cmapValue & 0xffff); } } else if (dataType == DataBuffer.TYPE_SHORT) { // Expand the palette image into an rgb image with // short data type. int cmapValue; int count = 0; int lookup; int len = colormap.length / 3; int len2 = len * 2; for (int i = 0; i < unitsBeforeLookup; i++) { // Get the index into the colormap lookup = tempData[i] & 0xffff; // Get the blue value cmapValue = colormap[lookup + len2]; sdata[count++] = (short)cmapValue; // Get the green value cmapValue = colormap[lookup + len]; sdata[count++] = (short)cmapValue; // Get the red value cmapValue = colormap[lookup]; sdata[count++] = (short)cmapValue; } } } else { // No lookup being done here, when RGB values are needed, // the associated IndexColorModel can be used to get them. try { if (compression == COMP_PACKBITS) { stream.readFully(data, 0, byteCount); // Since unitsInThisTile is the number of shorts, // but we do our decompression in terms of bytes, we // need to multiply unitsInThisTile by 2 in order to // figure out how many bytes we'll get after // decompression. int bytesInThisTile = unitsInThisTile * 2; byte[] byteArray = new byte[bytesInThisTile]; decodePackbits(data, bytesInThisTile, byteArray); interpretBytesAsShorts(byteArray, sdata, unitsInThisTile); } else if (compression == COMP_LZW) { stream.readFully(data, 0, byteCount); // Since unitsInThisTile is the number of shorts, // but we do our decompression in terms of bytes, we // need to multiply unitsInThisTile by 2 in order to // figure out how many bytes we'll get after // decompression. byte[] byteArray = new byte[unitsInThisTile * 2]; lzwDecoder.decode(data, byteArray, newRect.height); interpretBytesAsShorts(byteArray, sdata, unitsInThisTile); } else if (compression == COMP_DEFLATE) { stream.readFully(data, 0, byteCount); byte[] byteArray = new byte[unitsInThisTile * 2]; inflate(data, byteArray); interpretBytesAsShorts(byteArray, sdata, unitsInThisTile); } else if (compression == COMP_NONE) { readShorts(byteCount / 2, sdata); } stream.seek(saveOffset); } catch (IOException ioe) { throw new RuntimeException(PropertyUtil.getString("TIFFImage13") + ": " + ioe.getMessage()); } } } else if (sampleSize == 8) { if (decodePaletteAsShorts) { byte[] tempData = null; // At this point the data is 1 banded and will // become 3 banded only after we've done the palette // lookup, since unitsInThisTile was calculated with // 3 bands, we need to divide this by 3. int unitsBeforeLookup = unitsInThisTile / 3; // Read the data, if compressed, decode it, reset the pointer try { if (compression == COMP_PACKBITS) { stream.readFully(data, 0, byteCount); tempData = new byte[unitsBeforeLookup]; decodePackbits(data, unitsBeforeLookup, tempData); } else if (compression == COMP_LZW) { stream.readFully(data, 0, byteCount); tempData = new byte[unitsBeforeLookup]; lzwDecoder.decode(data, tempData, newRect.height); } else if (compression == COMP_DEFLATE) { stream.readFully(data, 0, byteCount); tempData = new byte[unitsBeforeLookup]; inflate(data, tempData); } else if (compression == COMP_NONE) { tempData = new byte[byteCount]; stream.readFully(tempData, 0, byteCount); } else { throw new RuntimeException(PropertyUtil.getString("IFFImage10") + ": " + compression); } stream.seek(saveOffset); } catch (IOException ioe) { throw new RuntimeException(PropertyUtil.getString("TIFFImage13") + ": " + ioe.getMessage()); } // Expand the palette image into an rgb image with ushort // data type. int cmapValue; int count = 0; int lookup; int len = colormap.length / 3; int len2 = len * 2; for (int i = 0; i < unitsBeforeLookup; i++) { // Get the index into the colormap lookup = tempData[i] & 0xff; // Get the blue value cmapValue = colormap[lookup + len2]; sdata[count++] = (short)(cmapValue & 0xffff); // Get the green value cmapValue = colormap[lookup + len]; sdata[count++] = (short)(cmapValue & 0xffff); // Get the red value cmapValue = colormap[lookup]; sdata[count++] = (short)(cmapValue & 0xffff); } } else { // No lookup being done here, when RGB values are needed, // the associated IndexColorModel can be used to get them. try { if (compression == COMP_PACKBITS) { stream.readFully(data, 0, byteCount); decodePackbits(data, unitsInThisTile, bdata); } else if (compression == COMP_LZW) { stream.readFully(data, 0, byteCount); lzwDecoder.decode(data, bdata, newRect.height); } else if (compression == COMP_DEFLATE) { stream.readFully(data, 0, byteCount); inflate(data, bdata); } else if (compression == COMP_NONE) { stream.readFully(bdata, 0, byteCount); } else { throw new RuntimeException(PropertyUtil.getString("TIFFImage10") + ": " + compression); } stream.seek(saveOffset); } catch (IOException ioe) { throw new RuntimeException(PropertyUtil.getString("TIFFImage13") + ": " + ioe.getMessage()); } } } else if (sampleSize == 4) { int padding = (newRect.width % 2 == 0) ? 0 : 1; int bytesPostDecoding = ((newRect.width / 2 + padding) * newRect.height); // Output short images if (decodePaletteAsShorts) { byte[] tempData = null; try { stream.readFully(data, 0, byteCount); stream.seek(saveOffset); } catch (IOException ioe) { throw new RuntimeException(PropertyUtil.getString("TIFFImage13") + ": " + ioe.getMessage()); } // If compressed, decode the data. if (compression == COMP_PACKBITS) { tempData = new byte[bytesPostDecoding]; decodePackbits(data, bytesPostDecoding, tempData); } else if (compression == COMP_LZW) { tempData = new byte[bytesPostDecoding]; lzwDecoder.decode(data, tempData, newRect.height); } else if (compression == COMP_DEFLATE) { tempData = new byte[bytesPostDecoding]; inflate(data, tempData); } else if (compression == COMP_NONE) { tempData = data; } int bytes = unitsInThisTile / 3; // Unpack the 2 pixels packed into each byte. data = new byte[bytes]; int srcCount = 0; int dstCount = 0; for (int j = 0; j < newRect.height; j++) { for (int i = 0; i < newRect.width / 2; i++) { data[dstCount++] = (byte)((tempData[srcCount] & 0xf0) >> 4); data[dstCount++] = (byte)(tempData[srcCount++] & 0x0f); } if (padding == 1) { data[dstCount++] = (byte)((tempData[srcCount++] & 0xf0) >> 4); } } int len = colormap.length / 3; int len2 = len * 2; int cmapValue; int lookup; int count = 0; for (int i = 0; i < bytes; i++) { lookup = data[i] & 0xff; cmapValue = colormap[lookup + len2]; sdata[count++] = (short)(cmapValue & 0xffff); cmapValue = colormap[lookup + len]; sdata[count++] = (short)(cmapValue & 0xffff); cmapValue = colormap[lookup]; sdata[count++] = (short)(cmapValue & 0xffff); } } else { // Output byte values, use IndexColorModel for unpacking try { // If compressed, decode the data. if (compression == COMP_PACKBITS) { stream.readFully(data, 0, byteCount); decodePackbits(data, bytesPostDecoding, bdata); } else if (compression == COMP_LZW) { stream.readFully(data, 0, byteCount); lzwDecoder.decode(data, bdata, newRect.height); } else if (compression == COMP_DEFLATE) { stream.readFully(data, 0, byteCount); inflate(data, bdata); } else if (compression == COMP_NONE) { stream.readFully(bdata, 0, byteCount); } stream.seek(saveOffset); } catch (IOException ioe) { throw new RuntimeException(PropertyUtil.getString("TIFFImage13") + ": " + ioe.getMessage()); } } } } else if (imageType == TYPE_GRAY_4BIT) { // 4-bit gray try { if (compression == COMP_PACKBITS) { stream.readFully(data, 0, byteCount); // Since the decompressed data will still be packed // 2 pixels into 1 byte, calculate bytesInThisTile int bytesInThisTile; if ((newRect.width % 8) == 0) { bytesInThisTile = (newRect.width / 2) * newRect.height; } else { bytesInThisTile = (newRect.width / 2 + 1) * newRect.height; } decodePackbits(data, bytesInThisTile, bdata); } else if (compression == COMP_LZW) { stream.readFully(data, 0, byteCount); lzwDecoder.decode(data, bdata, newRect.height); } else if (compression == COMP_DEFLATE) { stream.readFully(data, 0, byteCount); inflate(data, bdata); } else { stream.readFully(bdata, 0, byteCount); } stream.seek(saveOffset); } catch (IOException ioe) { throw new RuntimeException(PropertyUtil.getString("TIFFImage13") + ": " + ioe.getMessage()); } } else { // everything else try { if (sampleSize == 8) { if (compression == COMP_NONE) { stream.readFully(bdata, 0, byteCount); } else if (compression == COMP_LZW) { stream.readFully(data, 0, byteCount); lzwDecoder.decode(data, bdata, newRect.height); } else if (compression == COMP_PACKBITS) { stream.readFully(data, 0, byteCount); decodePackbits(data, unitsInThisTile, bdata); } else if (compression == COMP_DEFLATE) { stream.readFully(data, 0, byteCount); inflate(data, bdata); } else { throw new RuntimeException(PropertyUtil.getString("TIFFImage10") + ": " + compression); } } else if (sampleSize == 16) { if (compression == COMP_NONE) { readShorts(byteCount / 2, sdata); } else if (compression == COMP_LZW) { stream.readFully(data, 0, byteCount); // Since unitsInThisTile is the number of shorts, // but we do our decompression in terms of bytes, we // need to multiply unitsInThisTile by 2 in order to // figure out how many bytes we'll get after // decompression. byte[] byteArray = new byte[unitsInThisTile * 2]; lzwDecoder.decode(data, byteArray, newRect.height); interpretBytesAsShorts(byteArray, sdata, unitsInThisTile); } else if (compression == COMP_PACKBITS) { stream.readFully(data, 0, byteCount); // Since unitsInThisTile is the number of shorts, // but we do our decompression in terms of bytes, we // need to multiply unitsInThisTile by 2 in order to // figure out how many bytes we'll get after // decompression. int bytesInThisTile = unitsInThisTile * 2; byte[] byteArray = new byte[bytesInThisTile]; decodePackbits(data, bytesInThisTile, byteArray); interpretBytesAsShorts(byteArray, sdata, unitsInThisTile); } else if (compression == COMP_DEFLATE) { stream.readFully(data, 0, byteCount); byte[] byteArray = new byte[unitsInThisTile * 2]; inflate(data, byteArray); interpretBytesAsShorts(byteArray, sdata, unitsInThisTile); } } else if (sampleSize == 32 && dataType == DataBuffer.TYPE_INT) { // redundant if (compression == COMP_NONE) { readInts(byteCount / 4, idata); } else if (compression == COMP_LZW) { stream.readFully(data, 0, byteCount); // Since unitsInThisTile is the number of ints, // but we do our decompression in terms of bytes, we // need to multiply unitsInThisTile by 4 in order to // figure out how many bytes we'll get after // decompression. byte[] byteArray = new byte[unitsInThisTile * 4]; lzwDecoder.decode(data, byteArray, newRect.height); interpretBytesAsInts(byteArray, idata, unitsInThisTile); } else if (compression == COMP_PACKBITS) { stream.readFully(data, 0, byteCount); // Since unitsInThisTile is the number of ints, // but we do our decompression in terms of bytes, we // need to multiply unitsInThisTile by 4 in order to // figure out how many bytes we'll get after // decompression. int bytesInThisTile = unitsInThisTile * 4; byte[] byteArray = new byte[bytesInThisTile]; decodePackbits(data, bytesInThisTile, byteArray); interpretBytesAsInts(byteArray, idata, unitsInThisTile); } else if (compression == COMP_DEFLATE) { stream.readFully(data, 0, byteCount); byte[] byteArray = new byte[unitsInThisTile * 4]; inflate(data, byteArray); interpretBytesAsInts(byteArray, idata, unitsInThisTile); } } stream.seek(saveOffset); } catch (IOException ioe) { throw new RuntimeException(PropertyUtil.getString("TIFFImage13") + ": " + ioe.getMessage()); } // Modify the data for certain special cases. switch (imageType) { case TYPE_GRAY: case TYPE_GRAY_ALPHA: if (isWhiteZero) { // Since we are using a ComponentColorModel with this // image, we need to change the WhiteIsZero data to // BlackIsZero data so it will display properly. if (dataType == DataBuffer.TYPE_BYTE && !(getColorModel() instanceof IndexColorModel)) { for (int l = 0; l < bdata.length; l += numBands) { bdata[l] = (byte)(255 - bdata[l]); } } else if (dataType == DataBuffer.TYPE_USHORT) { int ushortMax = Short.MAX_VALUE - Short.MIN_VALUE; for (int l = 0; l < sdata.length; l += numBands) { sdata[l] = (short)(ushortMax - sdata[l]); } } else if (dataType == DataBuffer.TYPE_SHORT) { for (int l = 0; l < sdata.length; l += numBands) { sdata[l] = (short)(~sdata[l]); } } else if (dataType == DataBuffer.TYPE_INT) { long uintMax = ((long)Integer.MAX_VALUE - (long)Integer.MIN_VALUE); for (int l = 0; l < idata.length; l += numBands) { idata[l] = (int)(uintMax - idata[l]); } } } break; case TYPE_RGB: // Change RGB to BGR order, as Java2D displays that faster. // Unnecessary for JPEG-in-TIFF as the decoder handles it. if (sampleSize == 8 && compression != COMP_JPEG_TTN2) { for (int i = 0; i < unitsInThisTile; i += 3) { bswap = bdata[i]; bdata[i] = bdata[i + 2]; bdata[i + 2] = bswap; } } else if (sampleSize == 16) { for (int i = 0; i < unitsInThisTile; i += 3) { sswap = sdata[i]; sdata[i] = sdata[i + 2]; sdata[i + 2] = sswap; } } else if (sampleSize == 32) { if (dataType == DataBuffer.TYPE_INT) { for (int i = 0; i < unitsInThisTile; i += 3) { iswap = idata[i]; idata[i] = idata[i + 2]; idata[i + 2] = iswap; } } } break; case TYPE_RGB_ALPHA: // Convert from RGBA to ABGR for Java2D if (sampleSize == 8) { for (int i = 0; i < unitsInThisTile; i += 4) { // Swap R and A bswap = bdata[i]; bdata[i] = bdata[i + 3]; bdata[i + 3] = bswap; // Swap G and B bswap = bdata[i + 1]; bdata[i + 1] = bdata[i + 2]; bdata[i + 2] = bswap; } } else if (sampleSize == 16) { for (int i = 0; i < unitsInThisTile; i += 4) { // Swap R and A sswap = sdata[i]; sdata[i] = sdata[i + 3]; sdata[i + 3] = sswap; // Swap G and B sswap = sdata[i + 1]; sdata[i + 1] = sdata[i + 2]; sdata[i + 2] = sswap; } } else if (sampleSize == 32) { if (dataType == DataBuffer.TYPE_INT) { for (int i = 0; i < unitsInThisTile; i += 4) { // Swap R and A iswap = idata[i]; idata[i] = idata[i + 3]; idata[i + 3] = iswap; // Swap G and B iswap = idata[i + 1]; idata[i + 1] = idata[i + 2]; idata[i + 2] = iswap; } } } break; case TYPE_YCBCR_SUB: // Post-processing for YCbCr with subsampled chrominance: // simply replicate the chroma channels for displayability. int pixelsPerDataUnit = chromaSubH * chromaSubV; int numH = newRect.width / chromaSubH; int numV = newRect.height / chromaSubV; byte[] tempData = new byte[numH * numV * (pixelsPerDataUnit + 2)]; System.arraycopy(bdata, 0, tempData, 0, tempData.length); int samplesPerDataUnit = pixelsPerDataUnit * 3; int[] pixels = new int[samplesPerDataUnit]; int bOffset = 0; int offsetCb = pixelsPerDataUnit; int offsetCr = offsetCb + 1; int y = newRect.y; for (int j = 0; j < numV; j++) { int x = newRect.x; for (int i = 0; i < numH; i++) { int cb = tempData[bOffset + offsetCb]; int cr = tempData[bOffset + offsetCr]; int k = 0; while (k < samplesPerDataUnit) { pixels[k++] = tempData[bOffset++]; pixels[k++] = cb; pixels[k++] = cr; } bOffset += 2; tile.setPixels(x, y, chromaSubH, chromaSubV, pixels); x += chromaSubH; } y += chromaSubV; } break; } } return tile; } private void readShorts(int shortCount, short[] shortArray) { // Since each short consists of 2 bytes, we need a // byte array of double size int byteCount = 2 * shortCount; byte[] byteArray = new byte[byteCount]; try { stream.readFully(byteArray, 0, byteCount); } catch (IOException ioe) { throw new RuntimeException(PropertyUtil.getString("TIFFImage13") + ": " + ioe.getMessage()); } interpretBytesAsShorts(byteArray, shortArray, shortCount); } private void readInts(int intCount, int[] intArray) { // Since each int consists of 4 bytes, we need a // byte array of quadruple size int byteCount = 4 * intCount; byte[] byteArray = new byte[byteCount]; try { stream.readFully(byteArray, 0, byteCount); } catch (IOException ioe) { throw new RuntimeException(PropertyUtil.getString("TIFFImage13") + ": " + ioe.getMessage()); } interpretBytesAsInts(byteArray, intArray, intCount); } // Method to interpret a byte array to a short array, depending on // whether the bytes are stored in a big endian or little endian format. private void interpretBytesAsShorts(byte[] byteArray, short[] shortArray, int shortCount) { int j = 0; int firstByte; int secondByte; if (isBigEndian) { for (int i = 0; i < shortCount; i++) { firstByte = byteArray[j++] & 0xff; secondByte = byteArray[j++] & 0xff; shortArray[i] = (short)((firstByte << 8) + secondByte); } } else { for (int i = 0; i < shortCount; i++) { firstByte = byteArray[j++] & 0xff; secondByte = byteArray[j++] & 0xff; shortArray[i] = (short)((secondByte << 8) + firstByte); } } } // Method to interpret a byte array to a int array, depending on // whether the bytes are stored in a big endian or little endian format. private void interpretBytesAsInts(byte[] byteArray, int[] intArray, int intCount) { int j = 0; if (isBigEndian) { for (int i = 0; i < intCount; i++) { intArray[i] = (((byteArray[j++] & 0xff) << 24) | ((byteArray[j++] & 0xff) << 16) | ((byteArray[j++] & 0xff) << 8) | (byteArray[j++] & 0xff)); } } else { for (int i = 0; i < intCount; i++) { intArray[i] = ((byteArray[j++] & 0xff) | ((byteArray[j++] & 0xff) << 8) | ((byteArray[j++] & 0xff) << 16) | ((byteArray[j++] & 0xff) << 24)); } } } // Uncompress packbits compressed image data. private byte[] decodePackbits(byte[] data, int arraySize, byte[] dst) { if (dst == null) { dst = new byte[arraySize]; } int srcCount = 0; int dstCount = 0; byte repeat; byte b; try { while (dstCount < arraySize) { b = data[srcCount++]; if (b >= 0 && b <= 127) { // literal run packet for (int i = 0; i < (b + 1); i++) { dst[dstCount++] = data[srcCount++]; } } else if (b <= -1 && b >= -127) { // 2 byte encoded run packet repeat = data[srcCount++]; for (int i = 0; i < (-b + 1); i++) { dst[dstCount++] = repeat; } } else { // no-op packet. Do nothing srcCount++; } } } catch (java.lang.ArrayIndexOutOfBoundsException ae) { throw new RuntimeException(PropertyUtil.getString("TIFFImage14") + ": " + ae.getMessage()); } return dst; } // Need a createColorModel(). // Create ComponentColorModel for TYPE_RGB images private ComponentColorModel createAlphaComponentColorModel( int dataType, int numBands, boolean isAlphaPremultiplied, int transparency) { ComponentColorModel ccm = null; int[] rgbBits = null; ColorSpace cs = null; switch(numBands) { case 2: // gray+alpha cs = ColorSpace.getInstance(ColorSpace.CS_GRAY); break; case 4: // RGB+alpha cs = ColorSpace.getInstance(ColorSpace.CS_sRGB); break; default: throw new IllegalArgumentException(PropertyUtil.getString("TIFFImage19") + ": " + numBands); } int componentSize = 0; switch(dataType) { case DataBuffer.TYPE_BYTE: componentSize = 8; break; case DataBuffer.TYPE_USHORT: case DataBuffer.TYPE_SHORT: componentSize = 16; break; case DataBuffer.TYPE_INT: componentSize = 32; break; default: throw new IllegalArgumentException(PropertyUtil.getString("TIFFImage20") + ": " + dataType); } rgbBits = new int[numBands]; for (int i = 0; i < numBands; i++) { rgbBits[i] = componentSize; } ccm = new ComponentColorModel(cs, rgbBits, true, isAlphaPremultiplied, transparency, dataType); return ccm; } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/codec/tiff/TIFFImageDecoder.java0100644 0000000 0000000 00000010510 13777276623 032023 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: TIFFImageDecoder.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.image.codec.tiff; import java.awt.image.RenderedImage; import java.io.IOException; import org.apache.xmlgraphics.image.codec.util.ImageDecoderImpl; import org.apache.xmlgraphics.image.codec.util.PropertyUtil; import org.apache.xmlgraphics.image.codec.util.SeekableStream; /** * A baseline TIFF reader. The reader has some functionality in addition to * the baseline specifications for Bilevel images, for which the group 3 and * group 4 decompression schemes have been implemented. Support for LZW * decompression has also been added. Support for Horizontal differencing * predictor decoding is also included, when used with LZW compression. * However, this support is limited to data with bitsPerSample value of 8. * When reading in RGB images, support for alpha and extraSamples being * present has been added. Support for reading in images with 16 bit samples * has been added. Support for the SampleFormat tag (signed samples as well * as floating-point samples) has also been added. In all other cases, support * is limited to Baseline specifications. * * */ public class TIFFImageDecoder extends ImageDecoderImpl { // All the TIFF tags that we care about public static final int TIFF_IMAGE_WIDTH = 256; public static final int TIFF_IMAGE_LENGTH = 257; public static final int TIFF_BITS_PER_SAMPLE = 258; public static final int TIFF_COMPRESSION = 259; public static final int TIFF_PHOTOMETRIC_INTERPRETATION = 262; public static final int TIFF_FILL_ORDER = 266; public static final int TIFF_STRIP_OFFSETS = 273; public static final int TIFF_SAMPLES_PER_PIXEL = 277; public static final int TIFF_ROWS_PER_STRIP = 278; public static final int TIFF_STRIP_BYTE_COUNTS = 279; public static final int TIFF_X_RESOLUTION = 282; public static final int TIFF_Y_RESOLUTION = 283; public static final int TIFF_PLANAR_CONFIGURATION = 284; public static final int TIFF_T4_OPTIONS = 292; public static final int TIFF_T6_OPTIONS = 293; public static final int TIFF_RESOLUTION_UNIT = 296; public static final int TIFF_PREDICTOR = 317; public static final int TIFF_COLORMAP = 320; public static final int TIFF_TILE_WIDTH = 322; public static final int TIFF_TILE_LENGTH = 323; public static final int TIFF_TILE_OFFSETS = 324; public static final int TIFF_TILE_BYTE_COUNTS = 325; public static final int TIFF_EXTRA_SAMPLES = 338; public static final int TIFF_SAMPLE_FORMAT = 339; public static final int TIFF_S_MIN_SAMPLE_VALUE = 340; public static final int TIFF_S_MAX_SAMPLE_VALUE = 341; public static final int TIFF_ICC_PROFILE = 34675; public TIFFImageDecoder(SeekableStream input, TIFFDecodeParam param) { super(input, param); } public int getNumPages() throws IOException { return TIFFDirectory.getNumDirectories(input); } public RenderedImage decodeAsRenderedImage(int page) throws IOException { if ((page < 0) || (page >= getNumPages())) { throw new IOException(PropertyUtil.getString("TIFFImageDecoder0")); } return new TIFFImage(input, (TIFFDecodeParam) param, page); } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/codec/tiff/TIFFImageEncoder.java0100644 0000000 0000000 00000152013 13777276623 032042 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: TIFFImageEncoder.java 1804124 2017-08-04 14:13:54Z ssteiner $ */ package org.apache.xmlgraphics.image.codec.tiff; import java.awt.Rectangle; import java.awt.image.ColorModel; import java.awt.image.ComponentSampleModel; import java.awt.image.DataBuffer; import java.awt.image.DataBufferByte; import java.awt.image.IndexColorModel; import java.awt.image.MultiPixelPackedSampleModel; import java.awt.image.Raster; import java.awt.image.RenderedImage; import java.awt.image.SampleModel; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.OutputStream; import java.io.RandomAccessFile; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.SortedSet; import java.util.TreeSet; import java.util.zip.Deflater; import org.apache.xmlgraphics.image.codec.util.ImageEncodeParam; import org.apache.xmlgraphics.image.codec.util.ImageEncoderImpl; import org.apache.xmlgraphics.image.codec.util.PropertyUtil; import org.apache.xmlgraphics.image.codec.util.SeekableOutputStream; // CSOFF: ConstantName // CSOFF: MissingSwitchDefault // CSOFF: MultipleVariableDeclarations // CSOFF: OperatorWrap // CSOFF: WhitespaceAround /** * A baseline TIFF writer. The writer outputs TIFF images in either Bilevel, * Greyscale, Palette color or Full Color modes. * */ public class TIFFImageEncoder extends ImageEncoderImpl { // Incidental tags private static final int TIFF_JPEG_TABLES = 347; private static final int TIFF_YCBCR_SUBSAMPLING = 530; private static final int TIFF_YCBCR_POSITIONING = 531; private static final int TIFF_REF_BLACK_WHITE = 532; public TIFFImageEncoder(OutputStream output, ImageEncodeParam param) { super(output, param); if (this.param == null) { this.param = new TIFFEncodeParam(); } } /** * Encodes a RenderedImage and writes the output to the * OutputStream associated with this ImageEncoder. */ public void encode(RenderedImage im) throws IOException { // Write the file header (8 bytes). writeFileHeader(); // Get the encoding parameters. TIFFEncodeParam encodeParam = (TIFFEncodeParam)param; Iterator iter = encodeParam.getExtraImages(); if (iter != null) { int ifdOffset = 8; RenderedImage nextImage = im; TIFFEncodeParam nextParam = encodeParam; boolean hasNext; do { hasNext = iter.hasNext(); ifdOffset = encode(nextImage, nextParam, ifdOffset, !hasNext); if (hasNext) { Object obj = iter.next(); if (obj instanceof RenderedImage) { nextImage = (RenderedImage)obj; nextParam = encodeParam; } else if (obj instanceof Object[]) { Object[] o = (Object[])obj; nextImage = (RenderedImage)o[0]; nextParam = (TIFFEncodeParam)o[1]; } } } while(hasNext); } else { encode(im, encodeParam, 8, true); } } /** * Encodes a RenderedImage as part of a multi-page file and writes the output to the * OutputStream associated with this ImageEncoder. *

    * When you sent all pages, make sure you call finishMultiple() in the end. Otherwise, * the generated file will be corrupted. * @param context the context object you receive as return value to a previous call to * encodeMultiple(). Set null for the first image. * @param img the image * @return a context object needed for writing multiple pages for a single image file * @throws IOException In case of an I/O error */ public Object encodeMultiple(Object context, RenderedImage img) throws IOException { // Get the encoding parameters. TIFFEncodeParam encodeParam = (TIFFEncodeParam)param; if (encodeParam.getExtraImages() != null) { throw new IllegalStateException(PropertyUtil.getString("TIFFImageEncoder11")); } Context c = (Context)context; if (c == null) { c = new Context(); // Write the file header (8 bytes). writeFileHeader(); } else { //write image c.ifdOffset = encode(c.nextImage, encodeParam, c.ifdOffset, false); } c.nextImage = img; return c; } /** * Signals the encoder that you've finished sending pages for a multi-page image files. * @param context the context object you receive as return value to a previous call to * encodeMultiple() * @throws IOException In case of an I/O error */ public void finishMultiple(Object context) throws IOException { if (context == null) { throw new NullPointerException(); } Context c = (Context)context; // Get the encoding parameters. TIFFEncodeParam encodeParam = (TIFFEncodeParam)param; //write last image c.ifdOffset = encode(c.nextImage, encodeParam, c.ifdOffset, true); } private static class Context { //TODO This approach causes always two images to be present at the same time. //The encoder has to be changed a little to avoid that. private RenderedImage nextImage; private int ifdOffset = 8; //Initial offset } private int encode(RenderedImage im, TIFFEncodeParam encodeParam, int ifdOffset, boolean isLast) throws IOException { // Currently all images are stored uncompressed. CompressionValue compression = encodeParam.getCompression(); if (compression == CompressionValue.JPEG_TTN2) { throw new IllegalArgumentException(PropertyUtil.getString("TIFFImageEncoder12")); } // Get tiled output preference. boolean isTiled = encodeParam.getWriteTiled(); // Set bounds. int minX = im.getMinX(); int minY = im.getMinY(); int width = im.getWidth(); int height = im.getHeight(); // Get SampleModel. SampleModel sampleModel = im.getSampleModel(); ColorModel colorModel = im.getColorModel(); int[] sampleSize = sampleModel.getSampleSize(); int dataTypeSize = sampleSize[0]; int numBands = sampleModel.getNumBands(); int dataType = sampleModel.getDataType(); validateImage(dataTypeSize, sampleSize, numBands, dataType, colorModel); boolean dataTypeIsShort = dataType == DataBuffer.TYPE_SHORT || dataType == DataBuffer.TYPE_USHORT; // Set image type. ImageInfo imageInfo = ImageInfo.newInstance(im, dataTypeSize, numBands, colorModel, encodeParam); if (imageInfo.getType() == ImageType.UNSUPPORTED) { throw new RuntimeException(PropertyUtil.getString("TIFFImageEncoder8")); } final int numTiles = imageInfo.getNumTiles(); final long bytesPerTile = imageInfo.getBytesPerTile(); final long bytesPerRow = imageInfo.getBytesPerRow(); final int tileHeight = imageInfo.getTileHeight(); final int tileWidth = imageInfo.getTileWidth(); long[] tileByteCounts = new long[numTiles]; for (int i = 0; i < numTiles; i++) { tileByteCounts[i] = bytesPerTile; } if (!isTiled) { // Last strip may have lesser rows long lastStripRows = height - (tileHeight * (numTiles - 1)); tileByteCounts[numTiles - 1] = lastStripRows * bytesPerRow; } long totalBytesOfData = bytesPerTile * (numTiles - 1) + tileByteCounts[numTiles - 1]; long[] tileOffsets = new long[numTiles]; // Basic fields - have to be in increasing numerical order. // ImageWidth 256 // ImageLength 257 // BitsPerSample 258 // Compression 259 // PhotoMetricInterpretation 262 // StripOffsets 273 // RowsPerStrip 278 // StripByteCounts 279 // XResolution 282 // YResolution 283 // ResolutionUnit 296 // Create Directory SortedSet fields = new TreeSet(); // Image Width fields.add(new TIFFField(TIFFImageDecoder.TIFF_IMAGE_WIDTH, TIFFField.TIFF_LONG, 1, new long[] {width})); // Image Length fields.add(new TIFFField(TIFFImageDecoder.TIFF_IMAGE_LENGTH, TIFFField.TIFF_LONG, 1, new long[] {height})); char [] shortSampleSize = new char[numBands]; for (int i = 0; i < numBands; i++) { shortSampleSize[i] = (char) dataTypeSize; } fields.add(new TIFFField(TIFFImageDecoder.TIFF_BITS_PER_SAMPLE, TIFFField.TIFF_SHORT, numBands, shortSampleSize)); fields.add(new TIFFField(TIFFImageDecoder.TIFF_COMPRESSION, TIFFField.TIFF_SHORT, 1, new char[] {(char)compression.getValue()})); fields.add( new TIFFField(TIFFImageDecoder.TIFF_PHOTOMETRIC_INTERPRETATION, TIFFField.TIFF_SHORT, 1, new char[] {(char) imageInfo.getType().getPhotometricInterpretation()})); if (!isTiled) { fields.add(new TIFFField(TIFFImageDecoder.TIFF_STRIP_OFFSETS, TIFFField.TIFF_LONG, numTiles, tileOffsets)); } fields.add(new TIFFField(TIFFImageDecoder.TIFF_SAMPLES_PER_PIXEL, TIFFField.TIFF_SHORT, 1, new char[] {(char)numBands})); if (!isTiled) { fields.add(new TIFFField(TIFFImageDecoder.TIFF_ROWS_PER_STRIP, TIFFField.TIFF_LONG, 1, new long[] {tileHeight})); fields.add(new TIFFField(TIFFImageDecoder.TIFF_STRIP_BYTE_COUNTS, TIFFField.TIFF_LONG, numTiles, tileByteCounts)); } if (imageInfo.getColormap() != null) { fields.add(new TIFFField(TIFFImageDecoder.TIFF_COLORMAP, TIFFField.TIFF_SHORT, imageInfo.getColormapSize(), imageInfo.getColormap())); } if (isTiled) { fields.add(new TIFFField(TIFFImageDecoder.TIFF_TILE_WIDTH, TIFFField.TIFF_LONG, 1, new long[] {tileWidth})); fields.add(new TIFFField(TIFFImageDecoder.TIFF_TILE_LENGTH, TIFFField.TIFF_LONG, 1, new long[] {tileHeight})); fields.add(new TIFFField(TIFFImageDecoder.TIFF_TILE_OFFSETS, TIFFField.TIFF_LONG, numTiles, tileOffsets)); fields.add(new TIFFField(TIFFImageDecoder.TIFF_TILE_BYTE_COUNTS, TIFFField.TIFF_LONG, numTiles, tileByteCounts)); } if (imageInfo.getNumberOfExtraSamples() > 0) { char[] extraSamples = new char[imageInfo.getNumberOfExtraSamples()]; for (int i = 0; i < imageInfo.getNumberOfExtraSamples(); i++) { extraSamples[i] = (char) imageInfo.getExtraSamplesType().getValue(); } fields.add(new TIFFField(TIFFImageDecoder.TIFF_EXTRA_SAMPLES, TIFFField.TIFF_SHORT, imageInfo.getNumberOfExtraSamples(), extraSamples)); } // Data Sample Format Extension fields. if (dataType != DataBuffer.TYPE_BYTE) { // SampleFormat char[] sampleFormat = new char[numBands]; if (dataType == DataBuffer.TYPE_FLOAT) { sampleFormat[0] = 3; } else if (dataType == DataBuffer.TYPE_USHORT) { sampleFormat[0] = 1; } else { sampleFormat[0] = 2; } for (int b = 1; b < numBands; b++) { sampleFormat[b] = sampleFormat[0]; } fields.add(new TIFFField(TIFFImageDecoder.TIFF_SAMPLE_FORMAT, TIFFField.TIFF_SHORT, numBands, sampleFormat)); // NOTE: We don't bother setting the SMinSampleValue and // SMaxSampleValue fields as these both default to the // extrema of the respective data types. Probably we should // check for the presence of the "extrema" property and // use it if available. } if (imageInfo.getType() == ImageType.YCBCR) { // YCbCrSubSampling: 2 is the default so we must write 1 as // we do not (yet) do any subsampling. char subsampleH = 1; char subsampleV = 1; fields.add(new TIFFField(TIFF_YCBCR_SUBSAMPLING, TIFFField.TIFF_SHORT, 2, new char[] {subsampleH, subsampleV})); // YCbCr positioning. fields.add(new TIFFField(TIFF_YCBCR_POSITIONING, TIFFField.TIFF_SHORT, 1, new char[] {(char) ((compression == CompressionValue.JPEG_TTN2) ? 1 : 2)})); // Reference black/white. long[][] refbw; refbw = new long[][] // CCIR 601.1 headroom/footroom (presumptive) {{15, 1}, {235, 1}, {128, 1}, {240, 1}, {128, 1}, {240, 1}}; fields.add(new TIFFField(TIFF_REF_BLACK_WHITE, TIFFField.TIFF_RATIONAL, 6, refbw)); } // ---- No more automatically generated fields should be added // after this point. ---- // Add extra fields specified via the encoding parameters. TIFFField[] extraFields = encodeParam.getExtraFields(); List extantTags = new ArrayList(fields.size()); for (TIFFField fld : fields) { extantTags.add(fld.getTag()); } for (TIFFField fld : extraFields) { Integer tagValue = fld.getTag(); if (!extantTags.contains(tagValue)) { fields.add(fld); extantTags.add(tagValue); } } // ---- No more fields of any type should be added after this. ---- // Determine the size of the IFD which is written after the header // of the stream or after the data of the previous image in a // multi-page stream. int dirSize = getDirectorySize(fields); // The first data segment is written after the field overflow // following the IFD so initialize the first offset accordingly. tileOffsets[0] = ifdOffset + dirSize; // Branch here depending on whether data are being compressed. // If not, then the IFD is written immediately. // If so then there are three possibilities: // A) the OutputStream is a SeekableOutputStream (outCache null); // B) the OutputStream is not a SeekableOutputStream and a file cache // is used (outCache non-null, tempFile non-null); // C) the OutputStream is not a SeekableOutputStream and a memory cache // is used (outCache non-null, tempFile null). OutputStream outCache = null; byte[] compressBuf = null; File tempFile = null; int nextIFDOffset = 0; boolean skipByte = false; Deflater deflater = null; boolean jpegRGBToYCbCr = false; if (compression == CompressionValue.NONE) { // Determine the number of bytes of padding necessary between // the end of the IFD and the first data segment such that the // alignment of the data conforms to the specification (required // for uncompressed data only). int numBytesPadding = 0; if (dataTypeSize == 16 && tileOffsets[0] % 2 != 0) { numBytesPadding = 1; tileOffsets[0]++; } else if (dataTypeSize == 32 && tileOffsets[0] % 4 != 0) { numBytesPadding = (int)(4 - tileOffsets[0] % 4); tileOffsets[0] += numBytesPadding; } // Update the data offsets (which TIFFField stores by reference). for (int i = 1; i < numTiles; i++) { tileOffsets[i] = tileOffsets[i - 1] + tileByteCounts[i - 1]; } if (!isLast) { // Determine the offset of the next IFD. nextIFDOffset = (int)(tileOffsets[0] + totalBytesOfData); // IFD offsets must be on a word boundary. if ((nextIFDOffset & 0x01) != 0) { nextIFDOffset++; skipByte = true; } } // Write the IFD and field overflow before the image data. writeDirectory(ifdOffset, fields, nextIFDOffset); // Write any padding bytes needed between the end of the IFD // and the start of the actual image data. if (numBytesPadding != 0) { for (int padding = 0; padding < numBytesPadding; padding++) { output.write((byte)0); } } } else { // If compressing, the cannot be written yet as the size of the // data segments is unknown. if (output instanceof SeekableOutputStream) { // Simply seek to the first data segment position. ((SeekableOutputStream)output).seek(tileOffsets[0]); } else { // Cache the original OutputStream. outCache = output; try { // Attempt to create a temporary file. tempFile = File.createTempFile("jai-SOS-", ".tmp"); tempFile.deleteOnExit(); RandomAccessFile raFile = new RandomAccessFile(tempFile, "rw"); output = new SeekableOutputStream(raFile); // this method is exited! } catch (IOException e) { // Allocate memory for the entire image data (!). output = new ByteArrayOutputStream((int)totalBytesOfData); } } int bufSize = 0; switch(compression) { case PACKBITS: bufSize = (int) (bytesPerTile + ((bytesPerRow + 127) / 128) * tileHeight); break; case DEFLATE: bufSize = (int) bytesPerTile; deflater = new Deflater(encodeParam.getDeflateLevel()); break; default: bufSize = 0; } if (bufSize != 0) { compressBuf = new byte[bufSize]; } } // ---- Writing of actual image data ---- // Buffer for up to tileHeight rows of pixels int[] pixels = null; float[] fpixels = null; // Whether to test for contiguous data. boolean checkContiguous = ((dataTypeSize == 1 && sampleModel instanceof MultiPixelPackedSampleModel && dataType == DataBuffer.TYPE_BYTE) || (dataTypeSize == 8 && sampleModel instanceof ComponentSampleModel)); // Also create a buffer to hold tileHeight lines of the // data to be written to the file, so we can use array writes. byte[] bpixels = null; if (compression != CompressionValue.JPEG_TTN2) { if (dataType == DataBuffer.TYPE_BYTE) { bpixels = new byte[tileHeight * tileWidth * numBands]; } else if (dataTypeIsShort) { bpixels = new byte[2 * tileHeight * tileWidth * numBands]; } else if (dataType == DataBuffer.TYPE_INT || dataType == DataBuffer.TYPE_FLOAT) { bpixels = new byte[4 * tileHeight * tileWidth * numBands]; } } // Process tileHeight rows at a time int lastRow = minY + height; int lastCol = minX + width; int tileNum = 0; for (int row = minY; row < lastRow; row += tileHeight) { int rows = isTiled ? tileHeight : Math.min(tileHeight, lastRow - row); int size = rows * tileWidth * numBands; for (int col = minX; col < lastCol; col += tileWidth) { // Grab the pixels Raster src = im.getData(new Rectangle(col, row, tileWidth, rows)); boolean useDataBuffer = false; if (compression != CompressionValue.JPEG_TTN2) { // JPEG access Raster if (checkContiguous) { if (dataTypeSize == 8) { // 8-bit ComponentSampleModel csm = (ComponentSampleModel)src.getSampleModel(); int[] bankIndices = csm.getBankIndices(); int[] bandOffsets = csm.getBandOffsets(); int pixelStride = csm.getPixelStride(); int lineStride = csm.getScanlineStride(); if (pixelStride != numBands || lineStride != bytesPerRow) { useDataBuffer = false; } else { useDataBuffer = true; for (int i = 0; useDataBuffer && i < numBands; i++) { if (bankIndices[i] != 0 || bandOffsets[i] != i) { useDataBuffer = false; } } } } else { // 1-bit MultiPixelPackedSampleModel mpp = (MultiPixelPackedSampleModel)src.getSampleModel(); if (mpp.getNumBands() == 1 && mpp.getDataBitOffset() == 0 && mpp.getPixelBitStride() == 1) { useDataBuffer = true; } } } if (!useDataBuffer) { if (dataType == DataBuffer.TYPE_FLOAT) { fpixels = src.getPixels(col, row, tileWidth, rows, fpixels); } else { pixels = src.getPixels(col, row, tileWidth, rows, pixels); } } } int index; int pixel = 0; int k = 0; switch (dataTypeSize) { case 1: if (useDataBuffer) { byte[] btmp = ((DataBufferByte)src.getDataBuffer()).getData(); MultiPixelPackedSampleModel mpp = (MultiPixelPackedSampleModel)src.getSampleModel(); int lineStride = mpp.getScanlineStride(); int inOffset = mpp.getOffset(col - src.getSampleModelTranslateX(), row - src.getSampleModelTranslateY()); if (lineStride == bytesPerRow) { System.arraycopy(btmp, inOffset, bpixels, 0, (int) bytesPerRow * rows); } else { int outOffset = 0; for (int j = 0; j < rows; j++) { System.arraycopy(btmp, inOffset, bpixels, outOffset, (int) bytesPerRow); inOffset += lineStride; outOffset += bytesPerRow; } } } else { index = 0; // For each of the rows in a strip for (int i = 0; i < rows; i++) { // Write number of pixels exactly divisible by 8 for (int j = 0; j < tileWidth / 8; j++) { pixel = (pixels[index++] << 7) | (pixels[index++] << 6) | (pixels[index++] << 5) | (pixels[index++] << 4) | (pixels[index++] << 3) | (pixels[index++] << 2) | (pixels[index++] << 1) | pixels[index++]; bpixels[k++] = (byte)pixel; } // Write the pixels remaining after division by 8 if (tileWidth % 8 > 0) { pixel = 0; for (int j = 0; j < tileWidth % 8; j++) { pixel |= (pixels[index++] << (7 - j)); } bpixels[k++] = (byte)pixel; } } } if (compression == CompressionValue.NONE) { output.write(bpixels, 0, rows * ((tileWidth + 7) / 8)); } else if (compression == CompressionValue.PACKBITS) { int numCompressedBytes = compressPackBits(bpixels, rows, bytesPerRow, compressBuf); tileByteCounts[tileNum++] = numCompressedBytes; output.write(compressBuf, 0, numCompressedBytes); } else if (compression == CompressionValue.DEFLATE) { int numCompressedBytes = deflate(deflater, bpixels, compressBuf); tileByteCounts[tileNum++] = numCompressedBytes; output.write(compressBuf, 0, numCompressedBytes); } break; case 4: index = 0; // For each of the rows in a strip for (int i = 0; i < rows; i++) { // Write the number of pixels that will fit into an // even number of nibbles. for (int j = 0; j < tileWidth / 2; j++) { pixel = (pixels[index++] << 4) | pixels[index++]; bpixels[k++] = (byte)pixel; } // Last pixel for odd-length lines if ((tileWidth & 1) == 1) { pixel = pixels[index++] << 4; bpixels[k++] = (byte)pixel; } } if (compression == CompressionValue.NONE) { output.write(bpixels, 0, rows * ((tileWidth + 1) / 2)); } else if (compression == CompressionValue.PACKBITS) { int numCompressedBytes = compressPackBits(bpixels, rows, bytesPerRow, compressBuf); tileByteCounts[tileNum++] = numCompressedBytes; output.write(compressBuf, 0, numCompressedBytes); } else if (compression == CompressionValue.DEFLATE) { int numCompressedBytes = deflate(deflater, bpixels, compressBuf); tileByteCounts[tileNum++] = numCompressedBytes; output.write(compressBuf, 0, numCompressedBytes); } break; case 8: if (compression != CompressionValue.JPEG_TTN2) { if (useDataBuffer) { byte[] btmp = ((DataBufferByte)src.getDataBuffer()).getData(); ComponentSampleModel csm = (ComponentSampleModel)src.getSampleModel(); int inOffset = csm.getOffset(col - src.getSampleModelTranslateX(), row - src.getSampleModelTranslateY()); int lineStride = csm.getScanlineStride(); if (lineStride == bytesPerRow) { System.arraycopy(btmp, inOffset, bpixels, 0, (int) bytesPerRow * rows); } else { int outOffset = 0; for (int j = 0; j < rows; j++) { System.arraycopy(btmp, inOffset, bpixels, outOffset, (int) bytesPerRow); inOffset += lineStride; outOffset += bytesPerRow; } } } else { for (int i = 0; i < size; i++) { bpixels[i] = (byte)pixels[i]; } } } if (compression == CompressionValue.NONE) { output.write(bpixels, 0, size); } else if (compression == CompressionValue.PACKBITS) { int numCompressedBytes = compressPackBits(bpixels, rows, bytesPerRow, compressBuf); tileByteCounts[tileNum++] = numCompressedBytes; output.write(compressBuf, 0, numCompressedBytes); } else if (compression == CompressionValue.DEFLATE) { int numCompressedBytes = deflate(deflater, bpixels, compressBuf); tileByteCounts[tileNum++] = numCompressedBytes; output.write(compressBuf, 0, numCompressedBytes); } break; case 16: int ls = 0; for (int i = 0; i < size; i++) { int value = pixels[i]; bpixels[ls++] = (byte)((value & 0xff00) >> 8); bpixels[ls++] = (byte) (value & 0x00ff); } if (compression == CompressionValue.NONE) { output.write(bpixels, 0, size * 2); } else if (compression == CompressionValue.PACKBITS) { int numCompressedBytes = compressPackBits(bpixels, rows, bytesPerRow, compressBuf); tileByteCounts[tileNum++] = numCompressedBytes; output.write(compressBuf, 0, numCompressedBytes); } else if (compression == CompressionValue.DEFLATE) { int numCompressedBytes = deflate(deflater, bpixels, compressBuf); tileByteCounts[tileNum++] = numCompressedBytes; output.write(compressBuf, 0, numCompressedBytes); } break; case 32: if (dataType == DataBuffer.TYPE_INT) { int li = 0; for (int i = 0; i < size; i++) { int value = pixels[i]; bpixels[li++] = (byte)((value & 0xff000000) >>> 24); bpixels[li++] = (byte)((value & 0x00ff0000) >>> 16); bpixels[li++] = (byte)((value & 0x0000ff00) >>> 8); bpixels[li++] = (byte)(value & 0x000000ff); } } else { // DataBuffer.TYPE_FLOAT int lf = 0; for (int i = 0; i < size; i++) { int value = Float.floatToIntBits(fpixels[i]); bpixels[lf++] = (byte)((value & 0xff000000) >>> 24); bpixels[lf++] = (byte)((value & 0x00ff0000) >>> 16); bpixels[lf++] = (byte)((value & 0x0000ff00) >>> 8); bpixels[lf++] = (byte)(value & 0x000000ff); } } if (compression == CompressionValue.NONE) { output.write(bpixels, 0, size * 4); } else if (compression == CompressionValue.PACKBITS) { int numCompressedBytes = compressPackBits(bpixels, rows, bytesPerRow, compressBuf); tileByteCounts[tileNum++] = numCompressedBytes; output.write(compressBuf, 0, numCompressedBytes); } else if (compression == CompressionValue.DEFLATE) { int numCompressedBytes = deflate(deflater, bpixels, compressBuf); tileByteCounts[tileNum++] = numCompressedBytes; output.write(compressBuf, 0, numCompressedBytes); } break; default: break; } } } if (compression == CompressionValue.NONE) { // Write an extra byte for IFD word alignment if needed. if (skipByte) { output.write((byte)0); } } else { // Recompute the tile offsets the size of the compressed tiles. int totalBytes = 0; for (int i = 1; i < numTiles; i++) { int numBytes = (int)tileByteCounts[i - 1]; totalBytes += numBytes; tileOffsets[i] = tileOffsets[i - 1] + numBytes; } totalBytes += (int)tileByteCounts[numTiles - 1]; nextIFDOffset = isLast ? 0 : ifdOffset + dirSize + totalBytes; if ((nextIFDOffset & 0x01) != 0) { // make it even nextIFDOffset++; skipByte = true; } if (outCache == null) { // Original OutputStream must be a SeekableOutputStream. // Write an extra byte for IFD word alignment if needed. if (skipByte) { output.write((byte)0); } SeekableOutputStream sos = (SeekableOutputStream)output; // Save current position. long savePos = sos.getFilePointer(); // Seek backward to the IFD offset and write IFD. sos.seek(ifdOffset); writeDirectory(ifdOffset, fields, nextIFDOffset); // Seek forward to position after data. sos.seek(savePos); } else if (tempFile != null) { // Using a file cache for the image data. // Open a FileInputStream from which to copy the data. FileInputStream fileStream = new FileInputStream(tempFile); try { // Close the original SeekableOutputStream. output.close(); // Reset variable to the original OutputStream. output = outCache; // Write the IFD. writeDirectory(ifdOffset, fields, nextIFDOffset); // Write the image data. byte[] copyBuffer = new byte[8192]; int bytesCopied = 0; while (bytesCopied < totalBytes) { int bytesRead = fileStream.read(copyBuffer); if (bytesRead == -1) { break; } output.write(copyBuffer, 0, bytesRead); bytesCopied += bytesRead; } } finally { // Delete the temporary file. fileStream.close(); } boolean isDeleted = tempFile.delete(); assert isDeleted; // Write an extra byte for IFD word alignment if needed. if (skipByte) { output.write((byte)0); } } else if (output instanceof ByteArrayOutputStream) { // Using a memory cache for the image data. ByteArrayOutputStream memoryStream = (ByteArrayOutputStream)output; // Reset variable to the original OutputStream. output = outCache; // Write the IFD. writeDirectory(ifdOffset, fields, nextIFDOffset); // Write the image data. memoryStream.writeTo(output); // Write an extra byte for IFD word alignment if needed. if (skipByte) { output.write((byte)0); } } else { // This should never happen. throw new IllegalStateException(PropertyUtil.getString("TIFFImageEncoder13")); } } return nextIFDOffset; } private void validateImage(int dataTypeSize, int[] sampleSize, int numBands, int dataType, ColorModel colorModel) { // Retrieve and verify sample size. for (int i = 1; i < sampleSize.length; i++) { if (sampleSize[i] != dataTypeSize) { throw new RuntimeException(PropertyUtil.getString("TIFFImageEncoder0")); } } // Check low bit limits. if ((dataTypeSize == 1 || dataTypeSize == 4) && numBands != 1) { throw new RuntimeException(PropertyUtil.getString("TIFFImageEncoder1")); } // Retrieve and verify data type. switch (dataType) { case DataBuffer.TYPE_BYTE: if (dataTypeSize == 4) { throw new RuntimeException(PropertyUtil.getString("TIFFImageEncoder2")); } break; case DataBuffer.TYPE_SHORT: case DataBuffer.TYPE_USHORT: if (dataTypeSize != 16) { throw new RuntimeException(PropertyUtil.getString("TIFFImageEncoder3")); } break; case DataBuffer.TYPE_INT: case DataBuffer.TYPE_FLOAT: if (dataTypeSize != 32) { throw new RuntimeException(PropertyUtil.getString("TIFFImageEncoder4")); } break; default: throw new RuntimeException(PropertyUtil.getString("TIFFImageEncoder5")); } if (colorModel instanceof IndexColorModel && dataType != DataBuffer.TYPE_BYTE) { // Don't support (unsigned) short palette-color images. throw new RuntimeException(PropertyUtil.getString("TIFFImageEncoder6")); } } /** * Calculates the size of the IFD. */ private int getDirectorySize(SortedSet fields) { // Get the number of entries. int numEntries = fields.size(); // Initialize the size excluding that of any values > 4 bytes. int dirSize = 2 + numEntries * 12 + 4; // Loop over fields adding the size of all values > 4 bytes. for (Object field1 : fields) { // Get the field. TIFFField field = (TIFFField) field1; // Determine the size of the field value. int valueSize = field.getCount() * SIZE_OF_TYPE[field.getType()]; // Add any excess size. if (valueSize > 4) { dirSize += valueSize; } } return dirSize; } private void writeFileHeader() throws IOException { // 8 byte image file header // Byte order used within the file - Big Endian output.write('M'); output.write('M'); // Magic value output.write(0); output.write(42); // Offset in bytes of the first IFD. writeLong(8); } private void writeDirectory(int thisIFDOffset, SortedSet fields, int nextIFDOffset) throws IOException { // 2 byte count of number of directory entries (fields) int numEntries = fields.size(); long offsetBeyondIFD = thisIFDOffset + 12 * numEntries + 4 + 2; List tooBig = new ArrayList(); // Write number of fields in the IFD writeUnsignedShort(numEntries); for (Object field1 : fields) { // 12 byte field entry TIFFField TIFFField field = (TIFFField) field1; // byte 0-1 Tag that identifies a field int tag = field.getTag(); writeUnsignedShort(tag); // byte 2-3 The field type int type = field.getType(); writeUnsignedShort(type); // bytes 4-7 the number of values of the indicated type except // ASCII-valued fields which require the total number of bytes. int count = field.getCount(); int valueSize = getValueSize(field); writeLong(type == TIFFField.TIFF_ASCII ? valueSize : count); // bytes 8 - 11 the value or value offset if (valueSize > 4) { // We need an offset as data won't fit into 4 bytes writeLong(offsetBeyondIFD); offsetBeyondIFD += valueSize; tooBig.add(field); } else { writeValuesAsFourBytes(field); } } // Address of next IFD writeLong(nextIFDOffset); // Write the tag values that did not fit into 4 bytes for (Object aTooBig : tooBig) { writeValues((TIFFField) aTooBig); } } /** * Determine the number of bytes in the value portion of the field. */ private static int getValueSize(TIFFField field) throws UnsupportedEncodingException { int type = field.getType(); int count = field.getCount(); int valueSize = 0; if (type == TIFFField.TIFF_ASCII) { for (int i = 0; i < count; i++) { byte[] stringBytes = field.getAsString(i).getBytes("UTF-8"); // note: default encoding @work here! valueSize += stringBytes.length; if (stringBytes[stringBytes.length - 1] != 0) { valueSize++; } } } else { valueSize = count * SIZE_OF_TYPE[type]; } return valueSize; } private static final int[] SIZE_OF_TYPE = { 0, // 0 = n/a 1, // 1 = byte 1, // 2 = ascii 2, // 3 = short 4, // 4 = long 8, // 5 = rational 1, // 6 = sbyte 1, // 7 = undefined 2, // 8 = sshort 4, // 9 = slong 8, // 10 = srational 4, // 11 = float 8 // 12 = double }; private void writeValuesAsFourBytes(TIFFField field) throws IOException { int dataType = field.getType(); int count = field.getCount(); switch (dataType) { // unsigned 8 bits case TIFFField.TIFF_BYTE: byte[] bytes = field.getAsBytes(); if (count > 4) { count = 4; } for (int i = 0; i < count; i++) { output.write(bytes[i]); } for (int i = 0; i < (4 - count); i++) { output.write(0); } break; // unsigned 16 bits case TIFFField.TIFF_SHORT: char[] chars = field.getAsChars(); if (count > 2) { count = 2; } for (int i = 0; i < count; i++) { writeUnsignedShort(chars[i]); } for (int i = 0; i < (2 - count); i++) { writeUnsignedShort(0); } break; // unsigned 32 bits case TIFFField.TIFF_LONG: long[] longs = field.getAsLongs(); for (int i = 0; i < count; i++) { writeLong(longs[i]); } break; } } private void writeValues(TIFFField field) throws IOException { int dataType = field.getType(); int count = field.getCount(); switch (dataType) { // unsigned 8 bits case TIFFField.TIFF_BYTE: case TIFFField.TIFF_SBYTE: case TIFFField.TIFF_UNDEFINED: byte[] bytes = field.getAsBytes(); for (int i = 0; i < count; i++) { output.write(bytes[i]); } break; // unsigned 16 bits case TIFFField.TIFF_SHORT: char[] chars = field.getAsChars(); for (int i = 0; i < count; i++) { writeUnsignedShort(chars[i]); } break; case TIFFField.TIFF_SSHORT: short[] shorts = field.getAsShorts(); for (int i = 0; i < count; i++) { writeUnsignedShort(shorts[i]); } break; // unsigned 32 bits case TIFFField.TIFF_LONG: case TIFFField.TIFF_SLONG: long[] longs = field.getAsLongs(); for (int i = 0; i < count; i++) { writeLong(longs[i]); } break; case TIFFField.TIFF_FLOAT: float[] floats = field.getAsFloats(); for (int i = 0; i < count; i++) { int intBits = Float.floatToIntBits(floats[i]); writeLong(intBits); } break; case TIFFField.TIFF_DOUBLE: double[] doubles = field.getAsDoubles(); for (int i = 0; i < count; i++) { long longBits = Double.doubleToLongBits(doubles[i]); writeLong(longBits >>> 32); // write upper 32 bits writeLong(longBits & 0xffffffffL); // write lower 32 bits } break; case TIFFField.TIFF_RATIONAL: case TIFFField.TIFF_SRATIONAL: long[][] rationals = field.getAsRationals(); for (int i = 0; i < count; i++) { writeLong(rationals[i][0]); writeLong(rationals[i][1]); } break; case TIFFField.TIFF_ASCII: for (int i = 0; i < count; i++) { byte[] stringBytes = field.getAsString(i).getBytes("UTF-8"); output.write(stringBytes); if (stringBytes[stringBytes.length - 1] != (byte)0) { output.write((byte)0); } } break; default: throw new RuntimeException(PropertyUtil.getString("TIFFImageEncoder10")); } } // Here s is never expected to have value greater than what can be // stored in 2 bytes. private void writeUnsignedShort(int s) throws IOException { output.write((s & 0xff00) >>> 8); output.write(s & 0x00ff); } /** * despite its name, this method writes only 4 bytes to output. * @param l 32bits of this are written as 4 bytes * @throws IOException */ private void writeLong(long l) throws IOException { output.write((int)((l & 0xff000000) >>> 24)); output.write((int)((l & 0x00ff0000) >>> 16)); output.write((int)((l & 0x0000ff00) >>> 8)); output.write((int) (l & 0x000000ff)); } // /** // * Returns the current offset in the supplied OutputStream. // * This method should only be used if compressing data. // */ // private long getOffset(OutputStream out) throws IOException { // if (out instanceof ByteArrayOutputStream) { // return ((ByteArrayOutputStream)out).size(); // } else if (out instanceof SeekableOutputStream) { // return ((SeekableOutputStream)out).getFilePointer(); // } else { // // Shouldn't happen. // throw new IllegalStateException(PropertyUtil.getString("TIFFImageEncoder13")); // } // } /** * Performs PackBits compression on a tile of data. */ private static int compressPackBits(byte[] data, int numRows, long bytesPerRow, byte[] compData) { int inOffset = 0; int outOffset = 0; for (int i = 0; i < numRows; i++) { outOffset = packBits(data, inOffset, (int) bytesPerRow, compData, outOffset); inOffset += bytesPerRow; } return outOffset; } /** * Performs PackBits compression for a single buffer of data. * This should be called for each row of each tile. The returned * value is the offset into the output buffer after compression. */ private static int packBits(byte[] input, int inOffset, int inCount, byte[] output, int outOffset) { int inMax = inOffset + inCount - 1; int inMaxMinus1 = inMax - 1; while (inOffset <= inMax) { int run = 1; byte replicate = input[inOffset]; while (run < 127 && inOffset < inMax && input[inOffset] == input[inOffset + 1]) { run++; inOffset++; } if (run > 1) { inOffset++; output[outOffset++] = (byte)(-(run - 1)); output[outOffset++] = replicate; } run = 0; int saveOffset = outOffset; while (run < 128 && ((inOffset < inMax && input[inOffset] != input[inOffset + 1]) || (inOffset < inMaxMinus1 && input[inOffset] != input[inOffset + 2]))) { run++; output[++outOffset] = input[inOffset++]; } if (run > 0) { output[saveOffset] = (byte)(run - 1); outOffset++; } if (inOffset == inMax) { if (run > 0 && run < 128) { output[saveOffset]++; output[outOffset++] = input[inOffset++]; } else { output[outOffset++] = (byte)0; output[outOffset++] = input[inOffset++]; } } } return outOffset; } private static int deflate(Deflater deflater, byte[] inflated, byte[] deflated) { deflater.setInput(inflated); deflater.finish(); int numCompressedBytes = deflater.deflate(deflated); deflater.reset(); return numCompressedBytes; } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/codec/tiff/TIFFLZWDecoder.java0100644 0000000 0000000 00000015321 13777276623 031462 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: TIFFLZWDecoder.java 1804124 2017-08-04 14:13:54Z ssteiner $ */ package org.apache.xmlgraphics.image.codec.tiff; import org.apache.xmlgraphics.image.codec.util.PropertyUtil; // CSOFF: InnerAssignment // CSOFF: MultipleVariableDeclarations // CSOFF: OneStatementPerLine // CSOFF: OperatorWrap // CSOFF: WhitespaceAround /** * A class for performing LZW decoding. */ public class TIFFLZWDecoder { byte[][] stringTable; byte[] data; byte[] uncompData; int tableIndex; int bitsToGet = 9; int bytePointer; // int bitPointer; int dstIndex; int w; int predictor; int samplesPerPixel; int nextData; int nextBits; int[] andTable = { 511, 1023, 2047, 4095 }; public TIFFLZWDecoder(int w, int predictor, int samplesPerPixel) { this.w = w; this.predictor = predictor; this.samplesPerPixel = samplesPerPixel; } /** * Method to decode LZW compressed data. * * @param data The compressed data. * @param uncompData Array to return the uncompressed data in. * @param h The number of rows the compressed data contains. */ public byte[] decode(byte[] data, byte[] uncompData, int h) { if (data[0] == (byte)0x00 && data[1] == (byte)0x01) { throw new UnsupportedOperationException(PropertyUtil.getString("TIFFLZWDecoder0")); } initializeStringTable(); this.data = data; // this.h = h; this.uncompData = uncompData; // Initialize pointers bytePointer = 0; // bitPointer = 0; dstIndex = 0; nextData = 0; nextBits = 0; int code; int oldCode = 0; byte[] string; while ((code = getNextCode()) != 257 && dstIndex != uncompData.length) { if (code == 256) { initializeStringTable(); code = getNextCode(); if (code == 257) { break; } writeString(stringTable[code]); oldCode = code; } else { if (code < tableIndex) { string = stringTable[code]; writeString(string); addStringToTable(stringTable[oldCode], string[0]); oldCode = code; } else { string = stringTable[oldCode]; string = composeString(string, string[0]); writeString(string); addStringToTable(string); oldCode = code; } } } // Horizontal Differencing Predictor if (predictor == 2) { int count; for (int j = 0; j < h; j++) { count = samplesPerPixel * (j * w + 1); for (int i = samplesPerPixel; i < w * samplesPerPixel; i++) { uncompData[count] += uncompData[count - samplesPerPixel]; count++; } } } return uncompData; } /** * Initialize the string table. */ public void initializeStringTable() { stringTable = new byte[4096][]; for (int i = 0; i < 256; i++) { stringTable[i] = new byte[1]; stringTable[i][0] = (byte)i; } tableIndex = 258; bitsToGet = 9; } /** * Write out the string just uncompressed. */ public void writeString(byte[] string) { for (byte aString : string) { uncompData[dstIndex++] = aString; } } /** * Add a new string to the string table. */ public void addStringToTable(byte[] oldString, byte newString) { int length = oldString.length; byte[] string = new byte[length + 1]; System.arraycopy(oldString, 0, string, 0, length); string[length] = newString; // Add this new String to the table stringTable[tableIndex++] = string; if (tableIndex == 511) { bitsToGet = 10; } else if (tableIndex == 1023) { bitsToGet = 11; } else if (tableIndex == 2047) { bitsToGet = 12; } } /** * Add a new string to the string table. */ public void addStringToTable(byte[] string) { // Add this new String to the table stringTable[tableIndex++] = string; if (tableIndex == 511) { bitsToGet = 10; } else if (tableIndex == 1023) { bitsToGet = 11; } else if (tableIndex == 2047) { bitsToGet = 12; } } /** * Append newString to the end of oldString. */ public byte[] composeString(byte[] oldString, byte newString) { int length = oldString.length; byte[] string = new byte[length + 1]; System.arraycopy(oldString, 0, string, 0, length); string[length] = newString; return string; } // Returns the next 9, 10, 11 or 12 bits public int getNextCode() { // Attempt to get the next code. The exception is caught to make // this robust to cases wherein the EndOfInformation code has been // omitted from a strip. Examples of such cases have been observed // in practice. try { nextData = (nextData << 8) | (data[bytePointer++] & 0xff); nextBits += 8; if (nextBits < bitsToGet) { nextData = (nextData << 8) | (data[bytePointer++] & 0xff); nextBits += 8; } int code = (nextData >> (nextBits - bitsToGet)) & andTable[bitsToGet - 9]; nextBits -= bitsToGet; return code; } catch (ArrayIndexOutOfBoundsException e) { // Strip not terminated as expected: return EndOfInformation code. return 257; } } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/codec/tiff/package.html0100644 0000000 0000000 00000001643 13777276623 030467 0ustar000000000 0000000 org.apache.xmlgraphics.image.codec.tiff Package

    Contains a TIFF image codec.

    ././@LongLink0100644 0000000 0000000 00000000153 13777276623 011656 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/codec/util/FileCacheSeekableStream.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/codec/util/FileCacheSeekableStrea0100644 0000000 0000000 00000022670 13777276623 032417 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: FileCacheSeekableStream.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.image.codec.util; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.RandomAccessFile; /** * A subclass of SeekableStream that may be used to wrap * a regular InputStream. Seeking backwards is supported * by means of a file cache. In circumstances that do not allow the * creation of a temporary file (for example, due to security * consideration or the absence of local disk), the * MemoryCacheSeekableStream class may be used instead. * *

    The mark() and reset() methods are * supported. * *

    This class is not a committed part of the JAI API. It may * be removed or changed in future releases of JAI. */ public final class FileCacheSeekableStream extends SeekableStream { /** The source stream. */ private InputStream stream; /** The cache File. */ private File cacheFile; /** The cache as a RandomAcessFile. */ private RandomAccessFile cache; /** The length of the read buffer. */ private int bufLen = 1024; /** The read buffer. */ private byte[] buf = new byte[bufLen]; /** Number of bytes in the cache. */ private long length; /** Next byte to be read. */ private long pointer; /** True if we've encountered the end of the source stream. */ private boolean foundEOF; /** * Constructs a MemoryCacheSeekableStream that takes * its source data from a regular InputStream. * Seeking backwards is supported by means of an file cache. * *

    An IOException will be thrown if the * attempt to create the cache file fails for any reason. */ public FileCacheSeekableStream(InputStream stream) throws IOException { this.stream = stream; this.cacheFile = File.createTempFile("jai-FCSS-", ".tmp"); cacheFile.deleteOnExit(); this.cache = new RandomAccessFile(cacheFile, "rw"); } /** * Ensures that at least pos bytes are cached, * or the end of the source is reached. The return value * is equal to the smaller of pos and the * length of the source file. */ private long readUntil(long pos) throws IOException { // We've already got enough data cached if (pos < length) { return pos; } // pos >= length but length isn't getting any bigger, so return it if (foundEOF) { return length; } long len = pos - length; cache.seek(length); while (len > 0) { // Copy a buffer's worth of data from the source to the cache // bufLen will always fit into an int so this is safe int nbytes = stream.read(buf, 0, (int)Math.min(len, bufLen)); if (nbytes == -1) { foundEOF = true; return length; } cache.setLength(cache.length() + nbytes); cache.write(buf, 0, nbytes); len -= nbytes; length += nbytes; } return pos; } /** * Returns true since all * FileCacheSeekableStream instances support seeking * backwards. */ public boolean canSeekBackwards() { return true; } /** * Returns the current offset in this file. * * @return the offset from the beginning of the file, in bytes, * at which the next read occurs. */ public long getFilePointer() { return pointer; } /** * Sets the file-pointer offset, measured from the beginning of this * file, at which the next read occurs. * * @param pos the offset position, measured in bytes from the * beginning of the file, at which to set the file * pointer. * @exception IOException if pos is less than * 0 or if an I/O error occurs. */ public void seek(long pos) throws IOException { if (pos < 0) { throw new IOException(PropertyUtil.getString("FileCacheSeekableStream0")); } pointer = pos; } /** * Reads the next byte of data from the input stream. The value byte is * returned as an int in the range 0 to * 255. If no byte is available because the end of the stream * has been reached, the value -1 is returned. This method * blocks until input data is available, the end of the stream is detected, * or an exception is thrown. * * @return the next byte of data, or -1 if the end of the * stream is reached. * @exception IOException if an I/O error occurs. */ public int read() throws IOException { long next = pointer + 1; long pos = readUntil(next); if (pos >= next) { cache.seek(pointer++); return cache.read(); } else { return -1; } } /** * Reads up to len bytes of data from the input stream into * an array of bytes. An attempt is made to read as many as * len bytes, but a smaller number may be read, possibly * zero. The number of bytes actually read is returned as an integer. * *

    This method blocks until input data is available, end of file is * detected, or an exception is thrown. * *

    If b is null, a * NullPointerException is thrown. * *

    If off is negative, or len is negative, or * off+len is greater than the length of the array * b, then an IndexOutOfBoundsException is * thrown. * *

    If len is zero, then no bytes are read and * 0 is returned; otherwise, there is an attempt to read at * least one byte. If no byte is available because the stream is at end of * file, the value -1 is returned; otherwise, at least one * byte is read and stored into b. * *

    The first byte read is stored into element b[off], the * next one into b[off+1], and so on. The number of bytes read * is, at most, equal to len. Let k be the number of * bytes actually read; these bytes will be stored in elements * b[off] through b[off+k-1], * leaving elements b[off+k] through * b[off+len-1] unaffected. * *

    In every case, elements b[0] through * b[off] and elements b[off+len] through * b[b.length-1] are unaffected. * *

    If the first byte cannot be read for any reason other than end of * file, then an IOException is thrown. In particular, an * IOException is thrown if the input stream has been closed. * * @param b the buffer into which the data is read. * @param off the start offset in array b * at which the data is written. * @param len the maximum number of bytes to read. * @return the total number of bytes read into the buffer, or * -1 if there is no more data because the end of * the stream has been reached. * @exception IOException if an I/O error occurs. */ public int read(byte[] b, int off, int len) throws IOException { if (b == null) { throw new NullPointerException(); } if ((off < 0) || (len < 0) || (off + len > b.length)) { throw new IndexOutOfBoundsException(); } if (len == 0) { return 0; } long pos = readUntil(pointer + len); // len will always fit into an int so this is safe len = (int)Math.min(len, pos - pointer); if (len > 0) { cache.seek(pointer); cache.readFully(b, off, len); pointer += len; return len; } else { return -1; } } /** * Closes this stream and releases any system resources * associated with the stream. * * @throws IOException if an I/O error occurs. */ public void close() throws IOException { super.close(); cache.close(); cacheFile.delete(); } } ././@LongLink0100644 0000000 0000000 00000000151 13777276623 011654 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/codec/util/ForwardSeekableStream.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/codec/util/ForwardSeekableStream.0100644 0000000 0000000 00000007616 13777276623 032456 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ForwardSeekableStream.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.image.codec.util; import java.io.IOException; import java.io.InputStream; /** * A subclass of SeekableStream that may be used * to wrap a regular InputStream efficiently. * Seeking backwards is not supported. * */ public class ForwardSeekableStream extends SeekableStream { /** The source InputStream. */ private InputStream src; /** The current position. */ long pointer; /** * Constructs a InputStreamForwardSeekableStream from a * regular InputStream. */ public ForwardSeekableStream(InputStream src) { this.src = src; } /** Forwards the request to the real InputStream. */ public final int read() throws IOException { int result = src.read(); if (result != -1) { ++pointer; } return result; } /** Forwards the request to the real InputStream. */ public final int read(byte[] b, int off, int len) throws IOException { int result = src.read(b, off, len); if (result != -1) { pointer += result; } return result; } /** Forwards the request to the real InputStream. */ public final long skip(long n) throws IOException { long skipped = src.skip(n); pointer += skipped; return skipped; } /** Forwards the request to the real InputStream. */ public final int available() throws IOException { return src.available(); } /** Forwards the request to the real InputStream. */ public final void close() throws IOException { src.close(); } /** * Forwards the request to the real InputStream. * We use {@link SeekableStream#markPos} */ public final synchronized void mark(int readLimit) { markPos = pointer; src.mark(readLimit); } /** * Forwards the request to the real InputStream. * We use {@link SeekableStream#markPos} */ public final synchronized void reset() throws IOException { if (markPos != -1) { pointer = markPos; } src.reset(); } /** Forwards the request to the real InputStream. */ public boolean markSupported() { return src.markSupported(); } /** Returns false since seking backwards is not supported. */ public final boolean canSeekBackwards() { return false; } /** Returns the current position in the stream (bytes read). */ public final long getFilePointer() { return pointer; } /** * Seeks forward to the given position in the stream. * If pos is smaller than the current position * as returned by getFilePointer(), nothing * happens. */ public final void seek(long pos) throws IOException { while (pos - pointer > 0) { pointer += src.skip(pos - pointer); } } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/codec/util/ImageDecodeParam.java0100644 0000000 0000000 00000002352 13777276623 032203 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageDecodeParam.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.image.codec.util; import java.io.Serializable; /** * An empty (marker) interface to be implemented by all image decoder * parameter classes. * *

    This interface is not a committed part of the JAI API. It may * be removed or changed in future releases of JAI. */ public interface ImageDecodeParam extends Cloneable, Serializable { } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/codec/util/ImageDecoder.java0100644 0000000 0000000 00000006726 13777276623 031415 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageDecoder.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.image.codec.util; import java.awt.image.Raster; import java.awt.image.RenderedImage; import java.io.IOException; /** * An interface describing objects that transform an InputStream into a * BufferedImage or Raster. * */ public interface ImageDecoder { /** * Returns the current parameters as an instance of the * ImageDecodeParam interface. Concrete implementations of this * interface will return corresponding concrete implementations of * the ImageDecodeParam interface. For example, a JPEGImageDecoder * will return an instance of JPEGDecodeParam. */ ImageDecodeParam getParam(); /** * Sets the current parameters to an instance of the * ImageDecodeParam interface. Concrete implementations * of ImageDecoder may throw a RuntimeException if the * param argument is not an instance of the appropriate * subclass or subinterface. For example, a JPEGImageDecoder * will expect param to be an instance of JPEGDecodeParam. */ void setParam(ImageDecodeParam param); /** Returns the SeekableStream associated with this ImageDecoder. */ SeekableStream getInputStream(); /** Returns the number of pages present in the current stream. */ int getNumPages() throws IOException; /** * Returns a Raster that contains the decoded contents of the * SeekableStream associated with this ImageDecoder. Only * the first page of a multi-page image is decoded. */ Raster decodeAsRaster() throws IOException; /** * Returns a Raster that contains the decoded contents of the * SeekableStream associated with this ImageDecoder. * The given page of a multi-page image is decoded. If * the page does not exist, an IOException will be thrown. * Page numbering begins at zero. * * @param page The page to be decoded. */ Raster decodeAsRaster(int page) throws IOException; /** * Returns a RenderedImage that contains the decoded contents of the * SeekableStream associated with this ImageDecoder. Only * the first page of a multi-page image is decoded. */ RenderedImage decodeAsRenderedImage() throws IOException; /** * Returns a RenderedImage that contains the decoded contents of the * SeekableStream associated with this ImageDecoder. * The given page of a multi-page image is decoded. If * the page does not exist, an IOException will be thrown. * Page numbering begins at zero. * * @param page The page to be decoded. */ RenderedImage decodeAsRenderedImage(int page) throws IOException; } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/codec/util/ImageDecoderImpl.java0100644 0000000 0000000 00000013223 13777276623 032225 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageDecoderImpl.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.image.codec.util; import java.awt.image.Raster; import java.awt.image.RenderedImage; import java.io.IOException; import java.io.InputStream; /** * A partial implementation of the ImageDecoder interface * useful for subclassing. * */ public abstract class ImageDecoderImpl implements ImageDecoder { /** * The SeekableStream associcted with this * ImageEncoder. */ protected SeekableStream input; /** * The ImageDecodeParam object associated with this * ImageEncoder. */ protected ImageDecodeParam param; /** * Constructs an ImageDecoderImpl with a given * SeekableStream and ImageDecodeParam * instance. */ public ImageDecoderImpl(SeekableStream input, ImageDecodeParam param) { this.input = input; this.param = param; } /** * Constructs an ImageDecoderImpl with a given * InputStream and ImageDecodeParam * instance. The input parameter will be used to * construct a ForwardSeekableStream; if the ability * to seek backwards is required, the caller should construct * an instance of SeekableStream and * make use of the other contructor. */ public ImageDecoderImpl(InputStream input, ImageDecodeParam param) { this.input = new ForwardSeekableStream(input); this.param = param; } /** * Returns the current parameters as an instance of the * ImageDecodeParam interface. Concrete * implementations of this interface will return corresponding * concrete implementations of the ImageDecodeParam * interface. For example, a JPEGImageDecoder will * return an instance of JPEGDecodeParam. */ public ImageDecodeParam getParam() { return param; } /** * Sets the current parameters to an instance of the * ImageDecodeParam interface. Concrete * implementations of ImageDecoder may throw a * RuntimeException if the param * argument is not an instance of the appropriate subclass or * subinterface. For example, a JPEGImageDecoder * will expect param to be an instance of * JPEGDecodeParam. */ public void setParam(ImageDecodeParam param) { this.param = param; } /** * Returns the SeekableStream associated with * this ImageDecoder. */ public SeekableStream getInputStream() { return input; } /** * Returns the number of pages present in the current stream. * By default, the return value is 1. Subclasses that deal with * multi-page formats should override this method. */ public int getNumPages() throws IOException { return 1; } /** * Returns a Raster that contains the decoded * contents of the SeekableStream associated * with this ImageDecoder. Only * the first page of a multi-page image is decoded. */ public Raster decodeAsRaster() throws IOException { return decodeAsRaster(0); } /** * Returns a Raster that contains the decoded * contents of the SeekableStream associated * with this ImageDecoder. * The given page of a multi-page image is decoded. If * the page does not exist, an IOException will be thrown. * Page numbering begins at zero. * * @param page The page to be decoded. */ public Raster decodeAsRaster(int page) throws IOException { RenderedImage im = decodeAsRenderedImage(page); return im.getData(); } /** * Returns a RenderedImage that contains the decoded * contents of the SeekableStream associated * with this ImageDecoder. Only * the first page of a multi-page image is decoded. */ public RenderedImage decodeAsRenderedImage() throws IOException { return decodeAsRenderedImage(0); } /** * Returns a RenderedImage that contains the decoded * contents of the SeekableStream associated * with this ImageDecoder. * The given page of a multi-page image is decoded. If * the page does not exist, an IOException will be thrown. * Page numbering begins at zero. * * @param page The page to be decoded. */ public abstract RenderedImage decodeAsRenderedImage(int page) throws IOException; } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/codec/util/ImageEncodeParam.java0100644 0000000 0000000 00000002400 13777276623 032207 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageEncodeParam.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.image.codec.util; import java.io.Serializable; /** * An empty (marker) interface to be implemented by all image encoder * parameter classes. * *

    This interface is not a committed part of the JAI API. It may * be removed or changed in future releases of JAI. */ public interface ImageEncodeParam extends ImageDecodeParam, Cloneable, Serializable { } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/codec/util/ImageEncoder.java0100644 0000000 0000000 00000005146 13777276623 031422 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageEncoder.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.image.codec.util; import java.awt.image.ColorModel; import java.awt.image.Raster; import java.awt.image.RenderedImage; import java.io.IOException; import java.io.OutputStream; /** * An interface describing objects that transform a BufferedImage or * Raster into an OutputStream. * *

    This interface is not a committed part of the JAI API. It may * be removed or changed in future releases of JAI. */ public interface ImageEncoder { /** * Returns the current parameters as an instance of the * ImageEncodeParam interface. Concrete implementations of this * interface will return corresponding concrete implementations of * the ImageEncodeParam interface. For example, a JPEGImageEncoder * will return an instance of JPEGEncodeParam. */ ImageEncodeParam getParam(); /** * Sets the current parameters to an instance of the * ImageEncodeParam interface. Concrete implementations * of ImageEncoder may throw a RuntimeException if the * params argument is not an instance of the appropriate * subclass or subinterface. For example, a JPEGImageEncoder * will expect param to be an instance of JPEGEncodeParam. */ void setParam(ImageEncodeParam param); /** Returns the OutputStream associated with this ImageEncoder. */ OutputStream getOutputStream(); /** * Encodes a Raster with a given ColorModel and writes the output * to the OutputStream associated with this ImageEncoder. */ void encode(Raster ras, ColorModel cm) throws IOException; /** * Encodes a RenderedImage and writes the output to the * OutputStream associated with this ImageEncoder. */ void encode(RenderedImage im) throws IOException; } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/codec/util/ImageEncoderImpl.java0100644 0000000 0000000 00000006520 13777276623 032241 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageEncoderImpl.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.image.codec.util; import java.awt.image.ColorModel; import java.awt.image.Raster; import java.awt.image.RenderedImage; import java.io.IOException; import java.io.OutputStream; /** * A partial implementation of the ImageEncoder interface useful for * subclassing. * *

    This class is not a committed part of the JAI API. It may * be removed or changed in future releases of JAI. */ public abstract class ImageEncoderImpl implements ImageEncoder { /** The OutputStream associcted with this ImageEncoder. */ protected OutputStream output; /** The ImageEncodeParam object associcted with this ImageEncoder. */ protected ImageEncodeParam param; /** * Constructs an ImageEncoderImpl with a given OutputStream * and ImageEncoderParam instance. */ public ImageEncoderImpl(OutputStream output, ImageEncodeParam param) { this.output = output; this.param = param; } /** * Returns the current parameters as an instance of the * ImageEncodeParam interface. Concrete implementations of this * interface will return corresponding concrete implementations of * the ImageEncodeParam interface. For example, a JPEGImageEncoder * will return an instance of JPEGEncodeParam. */ public ImageEncodeParam getParam() { return param; } /** * Sets the current parameters to an instance of the * ImageEncodeParam interface. Concrete implementations * of ImageEncoder may throw a RuntimeException if the * params argument is not an instance of the appropriate * subclass or subinterface. For example, a JPEGImageEncoder * will expect param to be an instance of JPEGEncodeParam. */ public void setParam(ImageEncodeParam param) { this.param = param; } /** Returns the OutputStream associated with this ImageEncoder. */ public OutputStream getOutputStream() { return output; } /** * Encodes a Raster with a given ColorModel and writes the output * to the OutputStream associated with this ImageEncoder. */ public void encode(Raster ras, ColorModel cm) throws IOException { RenderedImage im = new SingleTileRenderedImage(ras, cm); encode(im); } /** * Encodes a RenderedImage and writes the output to the * OutputStream associated with this ImageEncoder. */ public abstract void encode(RenderedImage im) throws IOException; } ././@LongLink0100644 0000000 0000000 00000000171 13777276623 011656 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/codec/util/ImageInputStreamSeekableStreamAdapter.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/codec/util/ImageInputStreamSeekab0100644 0000000 0000000 00000004444 13777276623 032511 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageInputStreamSeekableStreamAdapter.java 1683736 2015-06-05 12:18:54Z ssteiner $ */ package org.apache.xmlgraphics.image.codec.util; import java.io.IOException; import javax.imageio.stream.ImageInputStream; /** * A subclass of SeekableStream that may be used to wrap * a regular ImageInputStream. */ public class ImageInputStreamSeekableStreamAdapter extends SeekableStream { /** The source stream. */ private ImageInputStream stream; /** * Constructs a SeekableStream that takes * its source data from a regular ImageInputStream. * @param stream the underlying ImageInputStream to use */ public ImageInputStreamSeekableStreamAdapter(ImageInputStream stream) throws IOException { this.stream = stream; } /** {@inheritDoc} */ public boolean canSeekBackwards() { return true; } /** {@inheritDoc} */ public long getFilePointer() throws IOException { return stream.getStreamPosition(); } /** {@inheritDoc} */ public void seek(long pos) throws IOException { stream.seek(pos); } /** {@inheritDoc} */ public int read() throws IOException { return stream.read(); } /** {@inheritDoc} */ public int read(byte[] b, int off, int len) throws IOException { return stream.read(b, off, len); } /** {@inheritDoc} */ public void close() throws IOException { super.close(); stream.close(); } } ././@LongLink0100644 0000000 0000000 00000000155 13777276623 011660 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/codec/util/MemoryCacheSeekableStream.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/codec/util/MemoryCacheSeekableStr0100644 0000000 0000000 00000022342 13777276623 032476 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: MemoryCacheSeekableStream.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.image.codec.util; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.List; /** * A subclass of SeekableStream that may be used to wrap * a regular InputStream. Seeking backwards is supported * by means of an in-memory cache. For greater efficiency, * FileCacheSeekableStream should be used in * circumstances that allow the creation of a temporary file. * *

    The mark() and reset() methods are * supported. * *

    This class is not a committed part of the JAI API. It may * be removed or changed in future releases of JAI. */ public final class MemoryCacheSeekableStream extends SeekableStream { /** The source input stream. */ private InputStream src; /** Position of first unread byte. */ private long pointer; /** Log_2 of the sector size. */ private static final int SECTOR_SHIFT = 9; /** The sector size. */ private static final int SECTOR_SIZE = 1 << SECTOR_SHIFT; /** A mask to determine the offset within a sector. */ private static final int SECTOR_MASK = SECTOR_SIZE - 1; /** A Vector of source sectors. */ private List data = new ArrayList(); /** Number of sectors stored. */ // int sectors = 0; /** Number of bytes read. */ int length; /** True if we've previously reached the end of the source stream */ boolean foundEOS; /** * Constructs a MemoryCacheSeekableStream that takes * its source data from a regular InputStream. * Seeking backwards is supported by means of an in-memory cache. */ public MemoryCacheSeekableStream(InputStream src) { this.src = src; } /** * Ensures that at least pos bytes are cached, * or the end of the source is reached. The return value * is equal to the smaller of pos and the * length of the source stream. */ private long readUntil(long pos) throws IOException { // We've already got enough data cached if (pos < length) { return pos; } // pos >= length but length isn't getting any bigger, so return it if (foundEOS) { return length; } int sector = (int)(pos >> SECTOR_SHIFT); // First unread sector int startSector = length >> SECTOR_SHIFT; // Read sectors until the desired sector for (int i = startSector; i <= sector; i++) { byte[] buf = new byte[SECTOR_SIZE]; data.add(buf); // Read up to SECTOR_SIZE bytes int len = SECTOR_SIZE; int off = 0; while (len > 0) { int nbytes = src.read(buf, off, len); // Found the end-of-stream if (nbytes == -1) { foundEOS = true; return length; } off += nbytes; len -= nbytes; // Record new data length length += nbytes; } } return length; } /** * Returns true since all * MemoryCacheSeekableStream instances support seeking * backwards. */ public boolean canSeekBackwards() { return true; } /** * Returns the current offset in this file. * * @return the offset from the beginning of the file, in bytes, * at which the next read occurs. */ public long getFilePointer() { return pointer; } /** * Sets the file-pointer offset, measured from the beginning of this * file, at which the next read occurs. * * @param pos the offset position, measured in bytes from the * beginning of the file, at which to set the file * pointer. * @exception IOException if pos is less than * 0 or if an I/O error occurs. */ public void seek(long pos) throws IOException { if (pos < 0) { throw new IOException(PropertyUtil.getString("MemoryCacheSeekableStream0")); } pointer = pos; } /** * Reads the next byte of data from the input stream. The value byte is * returned as an int in the range 0 to * 255. If no byte is available because the end of the stream * has been reached, the value -1 is returned. This method * blocks until input data is available, the end of the stream is detected, * or an exception is thrown. * * @return the next byte of data, or -1 if the end of the * stream is reached. */ public int read() throws IOException { long next = pointer + 1; long pos = readUntil(next); if (pos >= next) { byte[] buf = (byte[])data.get((int)(pointer >> SECTOR_SHIFT)); return buf[(int)(pointer++ & SECTOR_MASK)] & 0xff; } else { return -1; } } /** * Reads up to len bytes of data from the input stream into * an array of bytes. An attempt is made to read as many as * len bytes, but a smaller number may be read, possibly * zero. The number of bytes actually read is returned as an integer. * *

    This method blocks until input data is available, end of file is * detected, or an exception is thrown. * *

    If b is null, a * NullPointerException is thrown. * *

    If off is negative, or len is negative, or * off+len is greater than the length of the array * b, then an IndexOutOfBoundsException is * thrown. * *

    If len is zero, then no bytes are read and * 0 is returned; otherwise, there is an attempt to read at * least one byte. If no byte is available because the stream is at end of * file, the value -1 is returned; otherwise, at least one * byte is read and stored into b. * *

    The first byte read is stored into element b[off], the * next one into b[off+1], and so on. The number of bytes read * is, at most, equal to len. Let k be the number of * bytes actually read; these bytes will be stored in elements * b[off] through b[off+k-1], * leaving elements b[off+k] through * b[off+len-1] unaffected. * *

    In every case, elements b[0] through * b[off] and elements b[off+len] through * b[b.length-1] are unaffected. * *

    If the first byte cannot be read for any reason other than end of * file, then an IOException is thrown. In particular, an * IOException is thrown if the input stream has been closed. * * @param b the buffer into which the data is read. * @param off the start offset in array b * at which the data is written. * @param len the maximum number of bytes to read. * @return the total number of bytes read into the buffer, or * -1 if there is no more data because the end of * the stream has been reached. */ public int read(byte[] b, int off, int len) throws IOException { if (b == null) { throw new NullPointerException(); } if ((off < 0) || (len < 0) || (off + len > b.length)) { throw new IndexOutOfBoundsException(); } if (len == 0) { return 0; } long pos = readUntil(pointer + len); // End-of-stream if (pos <= pointer) { return -1; } byte[] buf = (byte[])data.get((int)(pointer >> SECTOR_SHIFT)); int nbytes = Math.min(len, SECTOR_SIZE - (int)(pointer & SECTOR_MASK)); System.arraycopy(buf, (int)(pointer & SECTOR_MASK), b, off, nbytes); pointer += nbytes; return nbytes; } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/codec/util/PropertyUtil.java0100644 0000000 0000000 00000003041 13777276623 031552 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: PropertyUtil.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.image.codec.util; import java.util.MissingResourceException; import org.apache.xmlgraphics.util.i18n.LocalizableSupport; public final class PropertyUtil { private PropertyUtil() { } private static final String RESOURCES = "org.apache.xmlgraphics.image.codec.Messages"; private static final LocalizableSupport LOCALIZABLESUPPORT = new LocalizableSupport( RESOURCES, PropertyUtil.class.getClassLoader()); public static String getString(String key) { try { return LOCALIZABLESUPPORT.formatMessage(key, null); } catch (MissingResourceException e) { return key; } } } ././@LongLink0100644 0000000 0000000 00000000150 13777276623 011653 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/codec/util/SeekableOutputStream.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/codec/util/SeekableOutputStream.j0100644 0000000 0000000 00000005152 13777276623 032515 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: SeekableOutputStream.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.image.codec.util; import java.io.IOException; import java.io.OutputStream; import java.io.RandomAccessFile; /** * An OutputStream which can seek to an arbitrary offset. * * @version $Id: SeekableOutputStream.java 1732018 2016-02-24 04:51:06Z gadams $ */ public class SeekableOutputStream extends OutputStream { private RandomAccessFile file; /** * Constructs a SeekableOutputStream from a * RandomAccessFile. Unless otherwise indicated, * all method invocations are fowarded to the underlying * RandomAccessFile. * * @param file The RandomAccessFile to which calls * will be forwarded. * @exception IllegalArgumentException if file is * null. */ public SeekableOutputStream(RandomAccessFile file) { if (file == null) { throw new IllegalArgumentException("SeekableOutputStream0"); } this.file = file; } public void write(int b) throws IOException { file.write(b); } public void write(byte[] b) throws IOException { file.write(b); } public void write(byte[] b, int off, int len) throws IOException { file.write(b, off, len); } /** * Invokes getFD().sync() on the underlying * RandomAccessFile. */ public void flush() throws IOException { file.getFD().sync(); } public void close() throws IOException { file.close(); } public long getFilePointer() throws IOException { return file.getFilePointer(); } public void seek(long pos) throws IOException { file.seek(pos); } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/codec/util/SeekableStream.java0100644 0000000 0000000 00000114064 13777276623 031767 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: SeekableStream.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.image.codec.util; import java.io.DataInput; import java.io.DataInputStream; import java.io.EOFException; import java.io.IOException; import java.io.InputStream; /** * An abstract subclass of java.io.InputStream that allows seeking * within the input, similar to the RandomAccessFile class. * Additionally, the DataInput interface is supported and extended * to include support for little-endian representations of fundamental data * types. * *

    In addition to the familiar methods from InputStream, the * methods getFilePointer(), seek(), are defined as in * the RandomAccessFile class. The canSeekBackwards() * method will return true if it is permissible to seek to a * position earlier in the stream than the current value of * getFilePointer(). Some subclasses of * SeekableStream guarantee the ability to seek backwards while * others may not offer this feature in the interest of providing greater * efficiency for those users who do not require it. * *

    The DataInput interface is supported as well. This included * the skipBytes() and readFully() methods and a * variety of read methods for various data types. * *

    Three classes are provided for the purpose of adapting a standard * InputStream to the SeekableStream interface. * ForwardSeekableStream does not allows seeking backwards, but is * inexpensive to use. FileCacheSeekableStream maintains a copy of * all of the data read from the input in a temporary file; this file will be * discarded automatically when the FileSeekableStream is * finalized, or when the JVM exits normally. * FileCacheSeekableStream is intended to be reasonably efficient * apart from the unavoidable use of disk space. In circumstances where the * creation of a temporary file is not possible, * MemoryCacheSeekableStream may be used. * MemoryCacheSeekableStream creates a potentially large in-memory * buffer to store the stream data and so should be avoided when possible. * *

    The FileSeekableStream class wraps a File or * RandomAccessFile. It forwards requests to the real underlying * file. It performs a limited amount of caching in order to avoid excessive * I/O costs. * *

    The SegmentedSeekableStream class performs a different sort * of function. It creates a SeekableStream from another * SeekableStream by selecting a series of portions or "segments". * Each segment starts at a specified location within the source * SeekableStream and extends for a specified number of bytes. The * StreamSegmentMapper interface and StreamSegment * class may be used to compute the segment positions dynamically. * *

    A convenience methods, wrapInputStream is provided to * construct a suitable SeekableStream instance whose data is * supplied by a given InputStream. The caller, by means of the * canSeekBackwards parameter, determines whether support for * seeking backwards is required. * */ public abstract class SeekableStream extends InputStream implements DataInput { /** * Returns a SeekableStream that will read from a * given InputStream, optionally including support * for seeking backwards. This is a convenience method that * avoids the need to instantiate specific subclasses of * SeekableStream depending on the current security * model. * * @param is An InputStream. * @param canSeekBackwards true if the ability to seek * backwards in the output is required. * @return An instance of SeekableStream. */ public static SeekableStream wrapInputStream(InputStream is, boolean canSeekBackwards) { SeekableStream stream = null; if (canSeekBackwards) { try { stream = new FileCacheSeekableStream(is); } catch (Exception e) { stream = new MemoryCacheSeekableStream(is); } } else { stream = new ForwardSeekableStream(is); } return stream; } // Methods from InputStream /** * Reads the next byte of data from the input stream. The value byte is * returned as an int in the range 0 to * 255. If no byte is available because the end of the stream * has been reached, the value -1 is returned. This method * blocks until input data is available, the end of the stream is detected, * or an exception is thrown. * *

    A subclass must provide an implementation of this method. * * @return the next byte of data, or -1 if the end of the * stream is reached. * @exception IOException if an I/O error occurs. */ public abstract int read() throws IOException; /** * Reads up to len bytes of data from the input stream into * an array of bytes. An attempt is made to read as many as * len bytes, but a smaller number may be read, possibly * zero. The number of bytes actually read is returned as an integer. * *

    This method blocks until input data is available, end of stream is * detected, or an exception is thrown. * *

    If b is null, a * NullPointerException is thrown. * *

    If off is negative, or len is negative, or * off+len is greater than the length of the array * b, then an IndexOutOfBoundsException is * thrown. * *

    If len is zero, then no bytes are read and * 0 is returned; otherwise, there is an attempt to read at * least one byte. If no byte is available because the stream is at end of * stream, the value -1 is returned; otherwise, at least one * byte is read and stored into b. * *

    The first byte read is stored into element b[off], the * next one into b[off+1], and so on. The number of bytes read * is, at most, equal to len. Let k be the number of * bytes actually read; these bytes will be stored in elements * b[off] through b[off+k-1], * leaving elements b[off+k] through * b[off+len-1] unaffected. * *

    In every case, elements b[0] through * b[off] and elements b[off+len] through * b[b.length-1] are unaffected. * *

    If the first byte cannot be read for any reason other than end of * stream, then an IOException is thrown. In particular, an * IOException is thrown if the input stream has been closed. * *

    A subclass must provide an implementation of this method. * * @param b the buffer into which the data is read. * @param off the start offset in array b * at which the data is written. * @param len the maximum number of bytes to read. * @return the total number of bytes read into the buffer, or * -1 if there is no more data because the end of * the stream has been reached. * @exception IOException if an I/O error occurs. */ public abstract int read(byte[] b, int off, int len) throws IOException; // Implemented in InputStream: // // public int read(byte[] b) throws IOException { // public long skip(long n) throws IOException // public int available) throws IOException // public void close() throws IOException; /** Marked position, shared by {@link ForwardSeekableStream} */ protected long markPos = -1L; /** * Marks the current file position for later return using * the reset() method. */ public synchronized void mark(int readLimit) { try { markPos = getFilePointer(); } catch (IOException e) { markPos = -1L; } } /** * Returns the file position to its position at the time of * the immediately previous call to the mark() * method. */ public synchronized void reset() throws IOException { if (markPos != -1) { seek(markPos); } } /** * Returns true if marking is supported. * Marking is automatically supported for SeekableStream * subclasses that support seeking backeards. Subclasses that do * not support seeking backwards but do support marking must override * this method. */ public boolean markSupported() { return canSeekBackwards(); } /** * Returns true if this object supports calls to * seek(pos) with an offset pos smaller * than the current offset, as returned by getFilePointer. */ public boolean canSeekBackwards() { return false; } /** * Returns the current offset in this stream. * * @return the offset from the beginning of the stream, in bytes, * at which the next read occurs. * @exception IOException if an I/O error occurs. */ public abstract long getFilePointer() throws IOException; /** * Sets the offset, measured from the beginning of this * stream, at which the next read occurs. * *

    If canSeekBackwards() returns false, * then setting pos to an offset smaller than * the current value of getFilePointer() will have * no effect. * * @param pos the offset position, measured in bytes from the * beginning of the stream, at which to set the stream * pointer. * @exception IOException if pos is less than * 0 or if an I/O error occurs. */ public abstract void seek(long pos) throws IOException; // Methods from RandomAccessFile /** * Reads b.length bytes from this stream into the byte * array, starting at the current stream pointer. This method reads * repeatedly from the stream until the requested number of bytes are * read. This method blocks until the requested number of bytes are * read, the end of the stream is detected, or an exception is thrown. * * @param b the buffer into which the data is read. * @exception EOFException if this stream reaches the end before reading * all the bytes. * @exception IOException if an I/O error occurs. */ public final void readFully(byte[] b) throws IOException { readFully(b, 0, b.length); } /** * Reads exactly len bytes from this stream into the byte * array, starting at the current stream pointer. This method reads * repeatedly from the stream until the requested number of bytes are * read. This method blocks until the requested number of bytes are * read, the end of the stream is detected, or an exception is thrown. * * @param b the buffer into which the data is read. * @param off the start offset of the data. * @param len the number of bytes to read. * @exception EOFException if this stream reaches the end before reading * all the bytes. * @exception IOException if an I/O error occurs. */ public final void readFully(byte[] b, int off, int len) throws IOException { int n = 0; do { int count = this.read(b, off + n, len - n); if (count < 0) { throw new EOFException(); } n += count; } while (n < len); } // Methods from DataInput, plus little-endian versions /** * Attempts to skip over n bytes of input discarding the * skipped bytes. *

    * * This method may skip over some smaller number of bytes, possibly zero. * This may result from any of a number of conditions; reaching end of * stream before n bytes have been skipped is only one * possibility. This method never throws an EOFException. * The actual number of bytes skipped is returned. If n * is negative, no bytes are skipped. * * @param n the number of bytes to be skipped. * @return the actual number of bytes skipped. * @exception IOException if an I/O error occurs. */ public int skipBytes(int n) throws IOException { if (n <= 0) { return 0; } return (int)skip(n); } /** * Reads a boolean from this stream. This method reads a * single byte from the stream, starting at the current stream pointer. * A value of 0 represents * false. Any other value represents true. * This method blocks until the byte is read, the end of the stream * is detected, or an exception is thrown. * * @return the boolean value read. * @exception EOFException if this stream has reached the end. * @exception IOException if an I/O error occurs. */ public final boolean readBoolean() throws IOException { int ch = this.read(); if (ch < 0) { throw new EOFException(); } return (ch != 0); } /** * Reads a signed eight-bit value from this stream. This method reads a * byte from the stream, starting from the current stream pointer. * If the byte read is b, where * 0 <= b <= 255, * then the result is: *

         *     (byte)(b)
         * 
    *

    * This method blocks until the byte is read, the end of the stream * is detected, or an exception is thrown. * * @return the next byte of this stream as a signed eight-bit * byte. * @exception EOFException if this stream has reached the end. * @exception IOException if an I/O error occurs. */ public final byte readByte() throws IOException { int ch = this.read(); if (ch < 0) { throw new EOFException(); } return (byte)(ch); } /** * Reads an unsigned eight-bit number from this stream. This method reads * a byte from this stream, starting at the current stream pointer, * and returns that byte. *

    * This method blocks until the byte is read, the end of the stream * is detected, or an exception is thrown. * * @return the next byte of this stream, interpreted as an unsigned * eight-bit number. * @exception EOFException if this stream has reached the end. * @exception IOException if an I/O error occurs. */ public final int readUnsignedByte() throws IOException { int ch = this.read(); if (ch < 0) { throw new EOFException(); } return ch; } /** * Reads a signed 16-bit number from this stream. * The method reads two * bytes from this stream, starting at the current stream pointer. * If the two bytes read, in order, are * b1 and b2, where each of the two values is * between 0 and 255, inclusive, then the * result is equal to: *

         *     (short)((b1 << 8) | b2)
         * 
    *

    * This method blocks until the two bytes are read, the end of the * stream is detected, or an exception is thrown. * * @return the next two bytes of this stream, interpreted as a signed * 16-bit number. * @exception EOFException if this stream reaches the end before reading * two bytes. * @exception IOException if an I/O error occurs. */ public final short readShort() throws IOException { int ch1 = this.read(); int ch2 = this.read(); if ((ch1 | ch2) < 0) { throw new EOFException(); } return (short)((ch1 << 8) + (ch2 << 0)); } /** * Reads a signed 16-bit number from this stream in little-endian order. * The method reads two * bytes from this stream, starting at the current stream pointer. * If the two bytes read, in order, are * b1 and b2, where each of the two values is * between 0 and 255, inclusive, then the * result is equal to: *

         *     (short)((b2 << 8) | b1)
         * 
    *

    * This method blocks until the two bytes are read, the end of the * stream is detected, or an exception is thrown. * * @return the next two bytes of this stream, interpreted as a signed * 16-bit number. * @exception EOFException if this stream reaches the end before reading * two bytes. * @exception IOException if an I/O error occurs. */ public final short readShortLE() throws IOException { int ch1 = this.read(); int ch2 = this.read(); if ((ch1 | ch2) < 0) { throw new EOFException(); } return (short)((ch2 << 8) + (ch1 << 0)); } /** * Reads an unsigned 16-bit number from this stream. This method reads * two bytes from the stream, starting at the current stream pointer. * If the bytes read, in order, are * b1 and b2, where * 0 <= b1, b2 <= 255, * then the result is equal to: *

         *     (b1 << 8) | b2
         * 
    *

    * This method blocks until the two bytes are read, the end of the * stream is detected, or an exception is thrown. * * @return the next two bytes of this stream, interpreted as an * unsigned 16-bit integer. * @exception EOFException if this stream reaches the end before reading * two bytes. * @exception IOException if an I/O error occurs. */ public final int readUnsignedShort() throws IOException { int ch1 = this.read(); int ch2 = this.read(); if ((ch1 | ch2) < 0) { throw new EOFException(); } return (ch1 << 8) + (ch2 << 0); } /** * Reads an unsigned 16-bit number from this stream in little-endian order. * This method reads * two bytes from the stream, starting at the current stream pointer. * If the bytes read, in order, are * b1 and b2, where * 0 <= b1, b2 <= 255, * then the result is equal to: *

         *     (b2 << 8) | b1
         * 
    *

    * This method blocks until the two bytes are read, the end of the * stream is detected, or an exception is thrown. * * @return the next two bytes of this stream, interpreted as an * unsigned 16-bit integer. * @exception EOFException if this stream reaches the end before reading * two bytes. * @exception IOException if an I/O error occurs. */ public final int readUnsignedShortLE() throws IOException { int ch1 = this.read(); int ch2 = this.read(); if ((ch1 | ch2) < 0) { throw new EOFException(); } return (ch2 << 8) + (ch1 << 0); } /** * Reads a Unicode character from this stream. This method reads two * bytes from the stream, starting at the current stream pointer. * If the bytes read, in order, are * b1 and b2, where * 0 <= b1, b2 <= 255, * then the result is equal to: *

         *     (char)((b1 << 8) | b2)
         * 
    *

    * This method blocks until the two bytes are read, the end of the * stream is detected, or an exception is thrown. * * @return the next two bytes of this stream as a Unicode character. * @exception EOFException if this stream reaches the end before reading * two bytes. * @exception IOException if an I/O error occurs. */ public final char readChar() throws IOException { int ch1 = this.read(); int ch2 = this.read(); if ((ch1 | ch2) < 0) { throw new EOFException(); } return (char)((ch1 << 8) + (ch2 << 0)); } /** * Reads a Unicode character from this stream in little-endian order. * This method reads two * bytes from the stream, starting at the current stream pointer. * If the bytes read, in order, are * b1 and b2, where * 0 <= b1, b2 <= 255, * then the result is equal to: *

         *     (char)((b2 << 8) | b1)
         * 
    *

    * This method blocks until the two bytes are read, the end of the * stream is detected, or an exception is thrown. * * @return the next two bytes of this stream as a Unicode character. * @exception EOFException if this stream reaches the end before reading * two bytes. * @exception IOException if an I/O error occurs. */ public final char readCharLE() throws IOException { int ch1 = this.read(); int ch2 = this.read(); if ((ch1 | ch2) < 0) { throw new EOFException(); } return (char)((ch2 << 8) + (ch1 << 0)); } /** * Reads a signed 32-bit integer from this stream. This method reads 4 * bytes from the stream, starting at the current stream pointer. * If the bytes read, in order, are b1, * b2, b3, and b4, where * 0 <= b1, b2, b3, b4 <= 255, * then the result is equal to: *

         *     (b1 << 24) | (b2 << 16) + (b3 << 8) + b4
         * 
    *

    * This method blocks until the four bytes are read, the end of the * stream is detected, or an exception is thrown. * * @return the next four bytes of this stream, interpreted as an * int. * @exception EOFException if this stream reaches the end before reading * four bytes. * @exception IOException if an I/O error occurs. */ public final int readInt() throws IOException { int ch1 = this.read(); int ch2 = this.read(); int ch3 = this.read(); int ch4 = this.read(); if ((ch1 | ch2 | ch3 | ch4) < 0) { throw new EOFException(); } return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0)); } /** * Reads a signed 32-bit integer from this stream in little-endian order. * This method reads 4 * bytes from the stream, starting at the current stream pointer. * If the bytes read, in order, are b1, * b2, b3, and b4, where * 0 <= b1, b2, b3, b4 <= 255, * then the result is equal to: *

         *     (b4 << 24) | (b3 << 16) + (b2 << 8) + b1
         * 
    *

    * This method blocks until the four bytes are read, the end of the * stream is detected, or an exception is thrown. * * @return the next four bytes of this stream, interpreted as an * int. * @exception EOFException if this stream reaches the end before reading * four bytes. * @exception IOException if an I/O error occurs. */ public final int readIntLE() throws IOException { int ch1 = this.read(); int ch2 = this.read(); int ch3 = this.read(); int ch4 = this.read(); if ((ch1 | ch2 | ch3 | ch4) < 0) { throw new EOFException(); } return ((ch4 << 24) + (ch3 << 16) + (ch2 << 8) + (ch1 << 0)); } /** * Reads an unsigned 32-bit integer from this stream. This method reads 4 * bytes from the stream, starting at the current stream pointer. * If the bytes read, in order, are b1, * b2, b3, and b4, where * 0 <= b1, b2, b3, b4 <= 255, * then the result is equal to: *

         *     (b1 << 24) | (b2 << 16) + (b3 << 8) + b4
         * 
    *

    * This method blocks until the four bytes are read, the end of the * stream is detected, or an exception is thrown. * * @return the next four bytes of this stream, interpreted as a * long. * @exception EOFException if this stream reaches the end before reading * four bytes. * @exception IOException if an I/O error occurs. */ public final long readUnsignedInt() throws IOException { long ch1 = this.read(); long ch2 = this.read(); long ch3 = this.read(); long ch4 = this.read(); if ((ch1 | ch2 | ch3 | ch4) < 0) { throw new EOFException(); } return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0)); } private byte[] ruileBuf = new byte[4]; /** * Reads an unsigned 32-bit integer from this stream in little-endian * order. This method reads 4 * bytes from the stream, starting at the current stream pointer. * If the bytes read, in order, are b1, * b2, b3, and b4, where * 0 <= b1, b2, b3, b4 <= 255, * then the result is equal to: *

         *     (b4 << 24) | (b3 << 16) + (b2 << 8) + b1
         * 
    *

    * This method blocks until the four bytes are read, the end of the * stream is detected, or an exception is thrown. * * @return the next four bytes of this stream, interpreted as a * long. * @exception EOFException if this stream reaches the end before reading * four bytes. * @exception IOException if an I/O error occurs. */ public final long readUnsignedIntLE() throws IOException { this.readFully(ruileBuf); long ch1 = (ruileBuf[0] & 0xff); long ch2 = (ruileBuf[1] & 0xff); long ch3 = (ruileBuf[2] & 0xff); long ch4 = (ruileBuf[3] & 0xff); return ((ch4 << 24) + (ch3 << 16) + (ch2 << 8) + (ch1 << 0)); } /** * Reads a signed 64-bit integer from this stream. This method reads eight * bytes from the stream, starting at the current stream pointer. * If the bytes read, in order, are * b1, b2, b3, * b4, b5, b6, * b7, and b8, where: *

         *     0 <= b1, b2, b3, b4, b5, b6, b7, b8 <=255,
         * 
    *

    * then the result is equal to: *

         *     ((long)b1 << 56) + ((long)b2 << 48)
         *     + ((long)b3 << 40) + ((long)b4 << 32)
         *     + ((long)b5 << 24) + ((long)b6 << 16)
         *     + ((long)b7 << 8) + b8
         * 
    *

    * This method blocks until the eight bytes are read, the end of the * stream is detected, or an exception is thrown. * * @return the next eight bytes of this stream, interpreted as a * long. * @exception EOFException if this stream reaches the end before reading * eight bytes. * @exception IOException if an I/O error occurs. */ public final long readLong() throws IOException { return ((long)(readInt()) << 32) + (readInt() & 0xFFFFFFFFL); } /** * Reads a signed 64-bit integer from this stream in little-endian * order. This method reads eight * bytes from the stream, starting at the current stream pointer. * If the bytes read, in order, are * b1, b2, b3, * b4, b5, b6, * b7, and b8, where: *

         *     0 <= b1, b2, b3, b4, b5, b6, b7, b8 <=255,
         * 
    *

    * then the result is equal to: *

         *     ((long)b1 << 56) + ((long)b2 << 48)
         *     + ((long)b3 << 40) + ((long)b4 << 32)
         *     + ((long)b5 << 24) + ((long)b6 << 16)
         *     + ((long)b7 << 8) + b8
         * 
    *

    * This method blocks until the eight bytes are read, the end of the * stream is detected, or an exception is thrown. * * @return the next eight bytes of this stream, interpreted as a * long. * @exception EOFException if this stream reaches the end before reading * eight bytes. * @exception IOException if an I/O error occurs. */ public final long readLongLE() throws IOException { int i1 = readIntLE(); int i2 = readIntLE(); return ((long)i2 << 32) + (i1 & 0xFFFFFFFFL); } /** * Reads a float from this stream. This method reads an * int value, starting at the current stream pointer, * as if by the readInt method * and then converts that int to a float * using the intBitsToFloat method in class * Float. *

    * This method blocks until the four bytes are read, the end of the * stream is detected, or an exception is thrown. * * @return the next four bytes of this stream, interpreted as a * float. * @exception EOFException if this stream reaches the end before reading * four bytes. * @exception IOException if an I/O error occurs. */ public final float readFloat() throws IOException { return Float.intBitsToFloat(readInt()); } /** * Reads a float from this stream in little-endian order. * This method reads an * int value, starting at the current stream pointer, * as if by the readInt method * and then converts that int to a float * using the intBitsToFloat method in class * Float. *

    * This method blocks until the four bytes are read, the end of the * stream is detected, or an exception is thrown. * * @return the next four bytes of this stream, interpreted as a * float. * @exception EOFException if this stream reaches the end before reading * four bytes. * @exception IOException if an I/O error occurs. */ public final float readFloatLE() throws IOException { return Float.intBitsToFloat(readIntLE()); } /** * Reads a double from this stream. This method reads a * long value, starting at the current stream pointer, * as if by the readLong method * and then converts that long to a double * using the longBitsToDouble method in * class Double. *

    * This method blocks until the eight bytes are read, the end of the * stream is detected, or an exception is thrown. * * @return the next eight bytes of this stream, interpreted as a * double. * @exception EOFException if this stream reaches the end before reading * eight bytes. * @exception IOException if an I/O error occurs. */ public final double readDouble() throws IOException { return Double.longBitsToDouble(readLong()); } /** * Reads a double from this stream in little-endian order. * This method reads a * long value, starting at the current stream pointer, * as if by the readLong method * and then converts that long to a double * using the longBitsToDouble method in * class Double. *

    * This method blocks until the eight bytes are read, the end of the * stream is detected, or an exception is thrown. * * @return the next eight bytes of this stream, interpreted as a * double. * @exception EOFException if this stream reaches the end before reading * eight bytes. * @exception IOException if an I/O error occurs. */ public final double readDoubleLE() throws IOException { return Double.longBitsToDouble(readLongLE()); } /** * Reads the next line of text from this stream. This method successively * reads bytes from the stream, starting at the current stream pointer, * until it reaches a line terminator or the end * of the stream. Each byte is converted into a character by taking the * byte's value for the lower eight bits of the character and setting the * high eight bits of the character to zero. This method does not, * therefore, support the full Unicode character set. * *

    A line of text is terminated by a carriage-return character * ('\r'), a newline character ('\n'), a * carriage-return character immediately followed by a newline character, * or the end of the stream. Line-terminating characters are discarded and * are not included as part of the string returned. * *

    This method blocks until a newline character is read, a carriage * return and the byte following it are read (to see if it is a newline), * the end of the stream is reached, or an exception is thrown. * * @return the next line of text from this stream, or null if end * of stream is encountered before even one byte is read. * @exception IOException if an I/O error occurs. */ public final String readLine() throws IOException { StringBuffer input = new StringBuffer(); int c = -1; boolean eol = false; while (!eol) { c = read(); switch (c) { case -1: case '\n': eol = true; break; case '\r': eol = true; long cur = getFilePointer(); if ((read()) != '\n') { seek(cur); } break; default: input.append((char)c); break; } } if ((c == -1) && (input.length() == 0)) { return null; } return input.toString(); } /** * Reads in a string from this stream. The string has been encoded * using a modified UTF-8 format. *

    * The first two bytes are read, starting from the current stream * pointer, as if by * readUnsignedShort. This value gives the number of * following bytes that are in the encoded string, not * the length of the resulting string. The following bytes are then * interpreted as bytes encoding characters in the UTF-8 format * and are converted into characters. *

    * This method blocks until all the bytes are read, the end of the * stream is detected, or an exception is thrown. * * @return a Unicode string. * @exception EOFException if this stream reaches the end before * reading all the bytes. * @exception IOException if an I/O error occurs. * @exception java.io.UTFDataFormatException if the bytes do not represent * valid UTF-8 encoding of a Unicode string. */ public final String readUTF() throws IOException { return DataInputStream.readUTF(this); } /** * Releases any system resources associated with this stream * by calling the close() method. */ protected void finalize() throws Throwable { super.finalize(); close(); } } ././@LongLink0100644 0000000 0000000 00000000147 13777276623 011661 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/codec/util/SimpleRenderedImage.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/codec/util/SimpleRenderedImage.ja0100644 0000000 0000000 00000044535 13777276623 032423 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: SimpleRenderedImage.java 1804124 2017-08-04 14:13:54Z ssteiner $ */ package org.apache.xmlgraphics.image.codec.util; import java.awt.Point; import java.awt.Rectangle; import java.awt.image.ColorModel; import java.awt.image.Raster; import java.awt.image.RenderedImage; import java.awt.image.SampleModel; import java.awt.image.WritableRaster; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Vector; // CSOFF: WhitespaceAround /** * A simple class implemented the RenderedImage * interface. Only the getTile() method needs to be * implemented by subclasses. The instance variables must also be * filled in properly. * *

    Normally in JAI PlanarImage is used for this * purpose, but in the interest of modularity the * use of PlanarImage has been avoided. * * @version $Id: SimpleRenderedImage.java 1804124 2017-08-04 14:13:54Z ssteiner $ */ public abstract class SimpleRenderedImage implements RenderedImage { /** The X coordinate of the image's upper-left pixel. */ protected int minX; /** The Y coordinate of the image's upper-left pixel. */ protected int minY; /** The image's width in pixels. */ protected int width; /** The image's height in pixels. */ protected int height; /** The width of a tile. */ protected int tileWidth; /** The height of a tile. */ protected int tileHeight; /** The X coordinate of the upper-left pixel of tile (0, 0). */ protected int tileGridXOffset; /** The Y coordinate of the upper-left pixel of tile (0, 0). */ protected int tileGridYOffset; /** The image's SampleModel. */ protected SampleModel sampleModel; /** The image's ColorModel. */ protected ColorModel colorModel; /** The image's sources, stored in a Vector. */ // protected List sources = new ArrayList(); /** A Hashtable containing the image properties. */ protected Map properties = new HashMap(); public SimpleRenderedImage() { } /** Returns the X coordinate of the leftmost column of the image. */ public int getMinX() { return minX; } /** * Returns the X coordinate of the column immediatetely to the * right of the rightmost column of the image. getMaxX() is * implemented in terms of getMinX() and getWidth() and so does * not need to be implemented by subclasses. */ public final int getMaxX() { return getMinX() + getWidth(); } /** Returns the X coordinate of the uppermost row of the image. */ public int getMinY() { return minY; } /** * Returns the Y coordinate of the row immediately below the * bottom row of the image. getMaxY() is implemented in terms of * getMinY() and getHeight() and so does not need to be * implemented by subclasses. */ public final int getMaxY() { return getMinY() + getHeight(); } /** Returns the width of the image. */ public int getWidth() { return width; } /** Returns the height of the image. */ public int getHeight() { return height; } /** Returns a Rectangle indicating the image bounds. */ public Rectangle getBounds() { return new Rectangle(getMinX(), getMinY(), getWidth(), getHeight()); } /** Returns the width of a tile. */ public int getTileWidth() { return tileWidth; } /** Returns the height of a tile. */ public int getTileHeight() { return tileHeight; } /** * Returns the X coordinate of the upper-left pixel of tile (0, 0). */ public int getTileGridXOffset() { return tileGridXOffset; } /** * Returns the Y coordinate of the upper-left pixel of tile (0, 0). */ public int getTileGridYOffset() { return tileGridYOffset; } /** * Returns the horizontal index of the leftmost column of tiles. * getMinTileX() is implemented in terms of getMinX() * and so does not need to be implemented by subclasses. */ public int getMinTileX() { return convertXToTileX(getMinX()); } /** * Returns the horizontal index of the rightmost column of tiles. * getMaxTileX() is implemented in terms of getMaxX() * and so does not need to be implemented by subclasses. */ public int getMaxTileX() { return convertXToTileX(getMaxX() - 1); } /** * Returns the number of tiles along the tile grid in the * horizontal direction. getNumXTiles() is implemented in terms * of getMinTileX() and getMaxTileX() and so does not need to be * implemented by subclasses. */ public int getNumXTiles() { return getMaxTileX() - getMinTileX() + 1; } /** * Returns the vertical index of the uppermost row of tiles. getMinTileY() * is implemented in terms of getMinY() and so does not need to be * implemented by subclasses. */ public int getMinTileY() { return convertYToTileY(getMinY()); } /** * Returns the vertical index of the bottom row of tiles. getMaxTileY() * is implemented in terms of getMaxY() and so does not need to * be implemented by subclasses. */ public int getMaxTileY() { return convertYToTileY(getMaxY() - 1); } /** * Returns the number of tiles along the tile grid in the vertical * direction. getNumYTiles() is implemented in terms * of getMinTileY() and getMaxTileY() and so does not need to be * implemented by subclasses. */ public int getNumYTiles() { return getMaxTileY() - getMinTileY() + 1; } /** Returns the SampleModel of the image. */ public SampleModel getSampleModel() { return sampleModel; } /** Returns the ColorModel of the image. */ public ColorModel getColorModel() { return colorModel; } /** * Gets a property from the property set of this image. If the * property name is not recognized, null will be returned. * * @param name the name of the property to get, as a * String. * @return a reference to the property * Object, or the value null */ public Object getProperty(String name) { name = name.toLowerCase(Locale.getDefault()); return properties.get(name); } /** * Returns a list of the properties recognized by this image. If * no properties are available, an empty String[] will be returned. * * @return an array of Strings representing valid * property names. */ public String[] getPropertyNames() { String[] names = new String[properties.size()]; properties.keySet().toArray(names); return names; } /** * Returns an array of Strings recognized as names by * this property source that begin with the supplied prefix. If * no property names match, null will be returned. * The comparison is done in a case-independent manner. * *

    The default implementation calls * getPropertyNames() and searches the list of names * for matches. * * @return an array of Strings giving the valid * property names (can be null). */ public String[] getPropertyNames(String prefix) { String[] propertyNames = getPropertyNames(); // if (propertyNames == null) { // return null; // } prefix = prefix.toLowerCase(Locale.getDefault()); List names = new ArrayList(); for (String propertyName : propertyNames) { if (propertyName.startsWith(prefix)) { names.add(propertyName); } } if (names.size() == 0) { return null; } // Copy the strings from the Vector over to a String array. String[] prefixNames = new String[names.size()]; names.toArray(prefixNames); return prefixNames; } // Utility methods. /** * Converts a pixel's X coordinate into a horizontal tile index * relative to a given tile grid layout specified by its X offset * and tile width. */ public static int convertXToTileX(int x, int tileGridXOffset, int tileWidth) { x -= tileGridXOffset; if (x < 0) { x += 1 - tileWidth; // Force round to -infinity } return x / tileWidth; } /** * Converts a pixel's Y coordinate into a vertical tile index * relative to a given tile grid layout specified by its Y offset * and tile height. */ public static int convertYToTileY(int y, int tileGridYOffset, int tileHeight) { y -= tileGridYOffset; if (y < 0) { y += 1 - tileHeight; // Force round to -infinity } return y / tileHeight; } /** * Converts a pixel's X coordinate into a horizontal tile index. * This is a convenience method. No attempt is made to detect * out-of-range coordinates. * * @param x the X coordinate of a pixel. * @return the X index of the tile containing the pixel. */ public int convertXToTileX(int x) { return convertXToTileX(x, getTileGridXOffset(), getTileWidth()); } /** * Converts a pixel's Y coordinate into a vertical tile index. * This is a convenience method. No attempt is made to detect * out-of-range coordinates. * * @param y the Y coordinate of a pixel. * @return the Y index of the tile containing the pixel. */ public int convertYToTileY(int y) { return convertYToTileY(y, getTileGridYOffset(), getTileHeight()); } /** * Converts a horizontal tile index into the X coordinate of its * upper left pixel relative to a given tile grid layout specified * by its X offset and tile width. */ public static int tileXToX(int tx, int tileGridXOffset, int tileWidth) { return tx * tileWidth + tileGridXOffset; } /** * Converts a vertical tile index into the Y coordinate of * its upper left pixel relative to a given tile grid layout * specified by its Y offset and tile height. */ public static int tileYToY(int ty, int tileGridYOffset, int tileHeight) { return ty * tileHeight + tileGridYOffset; } /** * Converts a horizontal tile index into the X coordinate of its * upper left pixel. This is a convenience method. No attempt is made * to detect out-of-range indices. * * @param tx the horizontal index of a tile. * @return the X coordinate of the tile's upper left pixel. */ public int tileXToX(int tx) { return tx * tileWidth + tileGridXOffset; } /** * Converts a vertical tile index into the Y coordinate of its * upper left pixel. This is a convenience method. No attempt is made * to detect out-of-range indices. * * @param ty the vertical index of a tile. * @return the Y coordinate of the tile's upper left pixel. */ public int tileYToY(int ty) { return ty * tileHeight + tileGridYOffset; } public Vector getSources() { return null; } /** * Returns the entire image in a single Raster. For images with * multiple tiles this will require making a copy. * *

    The returned Raster is semantically a copy. This means * that updates to the source image will not be reflected in the * returned Raster. For non-writable (immutable) source images, * the returned value may be a reference to the image's internal * data. The returned Raster should be considered non-writable; * any attempt to alter its pixel data (such as by casting it to * WritableRaster or obtaining and modifying its DataBuffer) may * result in undefined behavior. The copyData method should be * used if the returned Raster is to be modified. * * @return a Raster containing a copy of this image's data. */ public Raster getData() { Rectangle rect = new Rectangle(getMinX(), getMinY(), getWidth(), getHeight()); return getData(rect); } /** * Returns an arbitrary rectangular region of the RenderedImage * in a Raster. The rectangle of interest will be clipped against * the image bounds. * *

    The returned Raster is semantically a copy. This means * that updates to the source image will not be reflected in the * returned Raster. For non-writable (immutable) source images, * the returned value may be a reference to the image's internal * data. The returned Raster should be considered non-writable; * any attempt to alter its pixel data (such as by casting it to * WritableRaster or obtaining and modifying its DataBuffer) may * result in undefined behavior. The copyData method should be * used if the returned Raster is to be modified. * * @param bounds the region of the RenderedImage to be returned. */ public Raster getData(Rectangle bounds) { int startX = convertXToTileX(bounds.x); int startY = convertYToTileY(bounds.y); int endX = convertXToTileX(bounds.x + bounds.width - 1); int endY = convertYToTileY(bounds.y + bounds.height - 1); Raster tile; if ((startX == endX) && (startY == endY)) { tile = getTile(startX, startY); return tile.createChild(bounds.x, bounds.y, bounds.width, bounds.height, bounds.x, bounds.y, null); } else { // Create a WritableRaster of the desired size SampleModel sm = sampleModel.createCompatibleSampleModel(bounds.width, bounds.height); // Translate it WritableRaster dest = Raster.createWritableRaster(sm, bounds.getLocation()); for (int j = startY; j <= endY; j++) { for (int i = startX; i <= endX; i++) { tile = getTile(i, j); Rectangle intersectRect = bounds.intersection(tile.getBounds()); Raster liveRaster = tile.createChild(intersectRect.x, intersectRect.y, intersectRect.width, intersectRect.height, intersectRect.x, intersectRect.y, null); dest.setDataElements(0, 0, liveRaster); } } return dest; } } /** * Copies an arbitrary rectangular region of the RenderedImage * into a caller-supplied WritableRaster. The region to be * computed is determined by clipping the bounds of the supplied * WritableRaster against the bounds of the image. The supplied * WritableRaster must have a SampleModel that is compatible with * that of the image. * *

    If the raster argument is null, the entire image will * be copied into a newly-created WritableRaster with a SampleModel * that is compatible with that of the image. * * @param dest a WritableRaster to hold the returned portion of * the image. * @return a reference to the supplied WritableRaster, or to a * new WritableRaster if the supplied one was null. */ public WritableRaster copyData(WritableRaster dest) { Rectangle bounds; Raster tile; if (dest == null) { bounds = getBounds(); Point p = new Point(minX, minY); /* A SampleModel to hold the entire image. */ SampleModel sm = sampleModel.createCompatibleSampleModel( width, height); dest = Raster.createWritableRaster(sm, p); } else { bounds = dest.getBounds(); } int startX = convertXToTileX(bounds.x); int startY = convertYToTileY(bounds.y); int endX = convertXToTileX(bounds.x + bounds.width - 1); int endY = convertYToTileY(bounds.y + bounds.height - 1); for (int j = startY; j <= endY; j++) { for (int i = startX; i <= endX; i++) { tile = getTile(i, j); Rectangle intersectRect = bounds.intersection(tile.getBounds()); Raster liveRaster = tile.createChild(intersectRect.x, intersectRect.y, intersectRect.width, intersectRect.height, intersectRect.x, intersectRect.y, null); /* * WritableRaster.setDataElements takes into account of * inRaster's minX and minY and add these to x and y. Since * liveRaster has the origin at the correct location, the * following call should not again give these coordinates in * places of x and y. */ dest.setDataElements(0, 0, liveRaster); } } return dest; } } ././@LongLink0100644 0000000 0000000 00000000153 13777276623 011656 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/codec/util/SingleTileRenderedImage.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/codec/util/SingleTileRenderedImag0100644 0000000 0000000 00000004373 13777276623 032467 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: SingleTileRenderedImage.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.image.codec.util; import java.awt.image.ColorModel; import java.awt.image.Raster; // CSOFF: InnerAssignment /** * A simple class that provides RenderedImage functionality * given a Raster and a ColorModel. * * @version $Id: SingleTileRenderedImage.java 1732018 2016-02-24 04:51:06Z gadams $ */ public class SingleTileRenderedImage extends SimpleRenderedImage { Raster ras; /** * Constructs a SingleTileRenderedImage based on a Raster * and a ColorModel. * * @param ras A Raster that will define tile (0, 0) of the image. * @param colorModel A ColorModel that will serve as the image's * ColorModel. */ public SingleTileRenderedImage(Raster ras, ColorModel colorModel) { this.ras = ras; this.tileGridXOffset = this.minX = ras.getMinX(); this.tileGridYOffset = this.minY = ras.getMinY(); this.tileWidth = this.width = ras.getWidth(); this.tileHeight = this.height = ras.getHeight(); this.sampleModel = ras.getSampleModel(); this.colorModel = colorModel; } /** * Returns the image's Raster as tile (0, 0). */ public Raster getTile(int tileX, int tileY) { if (tileX != 0 || tileY != 0) { throw new IllegalArgumentException(PropertyUtil.getString("SingleTileRenderedImage0")); } return ras; } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/codec/util/package.html0100644 0000000 0000000 00000001661 13777276623 030514 0ustar000000000 0000000 org.apache.xmlgraphics.image.codec.util Package

    Contains utility classes for image codecs.

    xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/Image.java0100644 0000000 0000000 00000004307 13777276623 027334 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: Image.java 750418 2009-03-05 11:03:54Z vhennebert $ */ package org.apache.xmlgraphics.image.loader; import java.awt.color.ColorSpace; import java.awt.color.ICC_Profile; /** * Represents an instance of an image (bitmap or vector graphic). The image may or may not be loaded * into memory. Implementing classes will expose additional methods to access the actual image data. */ public interface Image { /** * Returns an object with basic information (URI, MIME type, intrinsic size) about the image. * @return the image information object */ ImageInfo getInfo(); /** * Returns the image's intrinsic size. This is a shortcut for getInfo().getSize(). * @return the image's intrinsic size */ ImageSize getSize(); /** * Returns the flavor of the image. * @return the image flavor */ ImageFlavor getFlavor(); /** * Indicates whether the Image instance is cacheable in memory. * @return true if the Image is cacheable */ boolean isCacheable(); /** * Returns the ICC color profile if one is associated with the image. * @return the ICC color profile or null if there's no profile */ ICC_Profile getICCProfile(); /** * Returns the image's color space if the information is available. * @return the color space or null if the color space is unknown or undefined */ ColorSpace getColorSpace(); } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/ImageContext.java0100644 0000000 0000000 00000002432 13777276623 030676 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageContext.java 750418 2009-03-05 11:03:54Z vhennebert $ */ package org.apache.xmlgraphics.image.loader; /** * The ImageContext interface provides session-independent information (mainly configuration * values). */ public interface ImageContext { /** * Returns the resolution (in dpi) that is to be used when interpreting pixel sizes where no * resolution information is available. * @return the source resolution (in dpi) */ float getSourceResolution(); } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/ImageException.java0100644 0000000 0000000 00000004330 13777276623 031207 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageException.java 750418 2009-03-05 11:03:54Z vhennebert $ */ package org.apache.xmlgraphics.image.loader; /** * Base class for all image-related exceptions. */ public class ImageException extends Exception { private static final long serialVersionUID = 3785613905389979249L; /** * Constructs an ImageException with the specified detail * message. The error message string s can later be * retrieved by the {@link java.lang.Throwable#getMessage} * method of class java.lang.Throwable. * * @param s the detail message. */ public ImageException(String s) { super(s); } /** * Constructs a new ImageException with the specified detail message and * cause.

    Note that the detail message associated with * cause is not automatically incorporated in * this exception's detail message. * * @param message the detail message (which is saved for later retrieval * by the {@link #getMessage()} method). * @param cause the cause (which is saved for later retrieval by the * {@link #getCause()} method). (A null value is * permitted, and indicates that the cause is nonexistent or * unknown.) */ public ImageException(String message, Throwable cause) { super(message, cause); } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/ImageFlavor.java0100644 0000000 0000000 00000013655 13777276623 030514 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageFlavor.java 829060 2009-10-23 13:42:53Z jeremias $ */ package org.apache.xmlgraphics.image.loader; import org.apache.xmlgraphics.util.MimeConstants; /** * The flavor of an image indicates in which form it is available. A bitmap image loaded into * memory might be represented as a BufferedImage (indicated by ImageFlavor.BUFFERED_IMAGE). * It is mostly used by consuming code to indicate what kind of flavors can be processed so a * processing pipeline can do the necessary loading operations and conversions. */ public class ImageFlavor { /** An image in form of a RenderedImage instance */ public static final ImageFlavor RENDERED_IMAGE = new ImageFlavor("RenderedImage"); /** An image in form of a BufferedImage instance */ public static final ImageFlavor BUFFERED_IMAGE = new SimpleRefinedImageFlavor( RENDERED_IMAGE, "BufferedImage"); /** An image in form of a W3C DOM instance */ private static final ImageFlavor DOM = new ImageFlavor("DOM"); /** An XML-based image in form of a W3C DOM instance */ public static final ImageFlavor XML_DOM = new MimeEnabledImageFlavor(DOM, "text/xml"); /** An image in form of a raw PNG file/stream */ public static final ImageFlavor RAW = new ImageFlavor("Raw"); /** An image in form of a raw PNG file/stream */ public static final ImageFlavor RAW_PNG = new MimeEnabledImageFlavor(RAW, MimeConstants.MIME_PNG); /** An image in form of a raw JPEG/JFIF file/stream */ public static final ImageFlavor RAW_JPEG = new MimeEnabledImageFlavor(RAW, MimeConstants.MIME_JPEG); /** An image in form of a raw TIFF file/stream */ public static final ImageFlavor RAW_TIFF = new MimeEnabledImageFlavor(RAW, MimeConstants.MIME_TIFF); /** An image in form of a raw EMF (Windows Enhanced Metafile) file/stream */ public static final ImageFlavor RAW_EMF = new MimeEnabledImageFlavor(RAW, MimeConstants.MIME_EMF); /** An image in form of a raw EPS (Encapsulated PostScript) file/stream */ public static final ImageFlavor RAW_EPS = new MimeEnabledImageFlavor(RAW, MimeConstants.MIME_EPS); /** An image in form of a raw LZW file/stream */ public static final ImageFlavor RAW_LZW = new ImageFlavor("RawLZW"); /** An image in form of a raw CCITTFax stream */ public static final ImageFlavor RAW_CCITTFAX = new ImageFlavor("RawCCITTFax"); /** An image in form of a Graphics2DImage (can be painted on a Graphics2D interface) */ public static final ImageFlavor GRAPHICS2D = new ImageFlavor("Graphics2DImage"); private String name; /** * Constructs a new ImageFlavor. Please reuse existing constants wherever possible! * @param name the name of the flavor (must be unique) */ public ImageFlavor(String name) { this.name = name; } /** * Returns the name of the ImageFlavor. * @return the flavor name */ public String getName() { return this.name; } /** * Returns the MIME type that the image flavor represents if a MIME type is available. This * is only applicable to images which can also exist as files. For images flavors like * decoded in-memory images (Rendered/BufferedImage), this method will return null. * @return the MIME type or null if no MIME type can be provided (like for in-memory images) */ public String getMimeType() { return null; } /** * Returns the XML namespace URI that the image flavor represents if such a namespace URI * is available. This is only applicable to images in XML form. Other image types will return * null. * @return the XML or null if no MIME type can be provided (like for in-memory images) */ public String getNamespace() { return null; } /** * Indicates whether a particular image flavor is compatible with this one. * @param flavor the other image flavor * @return true if the two are compatible */ public boolean isCompatible(ImageFlavor flavor) { return this.equals(flavor); } /** {@inheritDoc} */ public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((name == null) ? 0 : name.hashCode()); return result; } /** {@inheritDoc} */ public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } final ImageFlavor other = (ImageFlavor)obj; if (name == null) { if (other.name != null) { return false; } } else if (!name.equals(other.name)) { return false; } return true; } /** {@inheritDoc} */ public String toString() { return getName(); } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/ImageInfo.java0100644 0000000 0000000 00000010602 13777276623 030143 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageInfo.java 750418 2009-03-05 11:03:54Z vhennebert $ */ package org.apache.xmlgraphics.image.loader; import java.util.Map; /** * Represents an image that may not have been fully loaded. Usually, the loading only goes as far * as necessary to know the intrinsic size of the image. The image will only fully loaded later * when the image needs to be presented in a particular format so the consuming component can * actually process it. The "preloading" is done so a layout engine can work with the image without * having to fully load it (in memory). */ public class ImageInfo { /** * Key to register the "original object" among the custom objects of an ImageInfo instance. * @see #getOriginalImage() */ public static final Object ORIGINAL_IMAGE = Image.class; /** * Key to register information about additional (sub-)images in the image file after the * selected one. Valid values for this key is either a positive Integer or the constant * {@link Boolean#TRUE} or {@link Boolean#FALSE}. A value of TRUE indicates that there are * more subimages available but the exact number of additional images has not been determined * for performance reasons. */ public static final Object HAS_MORE_IMAGES = "HAS_MORE_IMAGES"; /** Original URI the image was accessed with */ private String originalURI; /** MIME type of the image */ private String mimeType; /** the image size */ private ImageSize size; /** * Map of custom objects that components further down the processing pipeline might need. * Example: The DOM of an XML document. */ private Map customObjects = new java.util.HashMap(); /** * Main constructor. * @param originalURI the original URI that was specified by the user (not the resolved URI!) * @param mimeType the MIME type of the image */ public ImageInfo(String originalURI, String mimeType) { this.originalURI = originalURI; this.mimeType = mimeType; } /** * Returns the original URI of the image. * @return the original URI */ public String getOriginalURI() { return this.originalURI; } /** * Returns the image's MIME type. * @return the MIME type */ public String getMimeType() { return this.mimeType; } /** * Returns the image's intrinsic size. * @return the image size */ public ImageSize getSize() { return this.size; } /** * Sets the image's intrinsic size. * @param size the size */ public void setSize(ImageSize size) { this.size = size; } /** * Returns a Map of custom objects associated with this instance. * @return the Map of custom objects */ public Map getCustomObjects() { return this.customObjects; } /** * Returns the original Image instance if such an Image instance is created while building * this ImageInfo object. Some images cannot be "preloaded". They have to be fully loaded * in order to determine the intrinsic image size. This method allows access to that fully * loaded image so no additional re-loading has to be done later. *

    * This method is short for: (Image)this.customObjects.get(ORIGINAL_IMAGE); * @return the original Image instance or null if none is set * @see #ORIGINAL_IMAGE */ public Image getOriginalImage() { return (Image)this.customObjects.get(ORIGINAL_IMAGE); } /** {@inheritDoc} */ public String toString() { return getOriginalURI() + " (" + getMimeType() + ")"; } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/ImageManager.java0100644 0000000 0000000 00000044740 13777276623 030634 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageManager.java 1804124 2017-08-04 14:13:54Z ssteiner $ */ package org.apache.xmlgraphics.image.loader; import java.io.IOException; import java.util.Iterator; import java.util.Map; import javax.xml.transform.Source; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.xmlgraphics.image.loader.cache.ImageCache; import org.apache.xmlgraphics.image.loader.pipeline.ImageProviderPipeline; import org.apache.xmlgraphics.image.loader.pipeline.PipelineFactory; import org.apache.xmlgraphics.image.loader.spi.ImageImplRegistry; import org.apache.xmlgraphics.image.loader.spi.ImagePreloader; import org.apache.xmlgraphics.image.loader.util.ImageUtil; import org.apache.xmlgraphics.image.loader.util.Penalty; import org.apache.xmlgraphics.io.XmlSourceUtil; /** * ImageManager is the central starting point for image access. */ public class ImageManager { /** logger */ protected static final Log log = LogFactory.getLog(ImageManager.class); /** Holds all registered interface implementations for the image package */ private ImageImplRegistry registry; /** Provides session-independent information */ private ImageContext imageContext; /** The image cache for this instance */ private ImageCache cache = new ImageCache(); private PipelineFactory pipelineFactory = new PipelineFactory(this); /** * Main constructor. * @param context the session-independent context information */ public ImageManager(ImageContext context) { this(ImageImplRegistry.getDefaultInstance(), context); } /** * Constructor for testing purposes. * @param registry the implementation registry with all plug-ins * @param context the session-independent context information */ public ImageManager(ImageImplRegistry registry, ImageContext context) { this.registry = registry; this.imageContext = context; } /** * Returns the ImageImplRegistry in use by the ImageManager. * @return the ImageImplRegistry */ public ImageImplRegistry getRegistry() { return this.registry; } /** * Returns the ImageContext in use by the ImageManager. * @return the ImageContext */ public ImageContext getImageContext() { return this.imageContext; } /** * Returns the ImageCache in use by the ImageManager. * @return the ImageCache */ public ImageCache getCache() { return this.cache; } /** * Returns the PipelineFactory in use by the ImageManager. * @return the PipelineFactory */ public PipelineFactory getPipelineFactory() { return this.pipelineFactory; } /** * Returns an ImageInfo object containing its intrinsic size for a given URI. The ImageInfo * is retrieved from an image cache if it has been requested before. * @param uri the URI of the image * @param session the session context through which to resolve the URI if the image is not in * the cache * @return the ImageInfo object created from the image * @throws ImageException If no suitable ImagePreloader can be found to load the image or * if an error occurred while preloading the image. * @throws IOException If an I/O error occurs while preloading the image */ public ImageInfo getImageInfo(String uri, ImageSessionContext session) throws ImageException, IOException { if (getCache() != null) { return getCache().needImageInfo(uri, session, this); } else { return preloadImage(uri, session); } } /** * Preloads an image, i.e. the format of the image is identified and some basic information * (MIME type, intrinsic size and possibly other values) are loaded and returned as an * ImageInfo object. Note that the image is not fully loaded normally. Only with certain formats * the image is already fully loaded and references added to the ImageInfo's custom objects * (see {@link ImageInfo#getOriginalImage()}). *

    * The reason for the preloading: Apache FOP, for example, only needs the image's intrinsic * size during layout. Only when the document is rendered to the final format does FOP need * to load the full image. Like this a lot of memory can be saved. * @param uri the original URI of the image * @param session the session context through which to resolve the URI * @return the ImageInfo object created from the image * @throws ImageException If no suitable ImagePreloader can be found to load the image or * if an error occurred while preloading the image. * @throws IOException If an I/O error occurs while preloading the image */ public ImageInfo preloadImage(String uri, ImageSessionContext session) throws ImageException, IOException { Source src = session.needSource(uri); ImageInfo info = preloadImage(uri, src); session.returnSource(uri, src); return info; } /** * Preloads an image, i.e. the format of the image is identified and some basic information * (MIME type, intrinsic size and possibly other values) are loaded and returned as an * ImageInfo object. Note that the image is not fully loaded normally. Only with certain formats * the image is already fully loaded and references added to the ImageInfo's custom objects * (see {@link ImageInfo#getOriginalImage()}). *

    * The reason for the preloading: Apache FOP, for example, only needs the image's intrinsic * size during layout. Only when the document is rendered to the final format does FOP need * to load the full image. Like this a lot of memory can be saved. * @param uri the original URI of the image * @param src the Source object to load the image from * @return the ImageInfo object created from the image * @throws ImageException If no suitable ImagePreloader can be found to load the image or * if an error occurred while preloading the image. * @throws IOException If an I/O error occurs while preloading the image */ public ImageInfo preloadImage(String uri, Source src) throws ImageException, IOException { Iterator iter = registry.getPreloaderIterator(); while (iter.hasNext()) { ImagePreloader preloader = (ImagePreloader) iter.next(); ImageInfo info = preloader.preloadImage(uri, src, imageContext); if (info != null) { return info; } } throw new ImageException("The file format is not supported. No ImagePreloader found for " + uri); } private Map prepareHints(Map hints, ImageSessionContext sessionContext) { Map newHints = new java.util.HashMap(); if (hints != null) { newHints.putAll(hints); //Copy in case an unmodifiable map is passed in } if (!newHints.containsKey(ImageProcessingHints.IMAGE_SESSION_CONTEXT) && sessionContext != null) { newHints.put(ImageProcessingHints.IMAGE_SESSION_CONTEXT, sessionContext); } if (!newHints.containsKey(ImageProcessingHints.IMAGE_MANAGER)) { newHints.put(ImageProcessingHints.IMAGE_MANAGER, this); } return newHints; } /** * Loads an image. The caller can indicate what kind of image flavor is requested. When this * method is called the code looks for a suitable ImageLoader and, if necessary, builds * a conversion pipeline so it can return the image in exactly the form the caller needs. *

    * Optionally, it is possible to pass in Map of hints. These hints may be used by ImageLoaders * and ImageConverters to act on the image. See {@link ImageProcessingHints} for common hints * used by the bundled implementations. You can, of course, define your own hints. * @param info the ImageInfo instance for the image (obtained by * {@link #getImageInfo(String, ImageSessionContext)}) * @param flavor the requested image flavor. * @param hints a Map of hints to any of the background components or null * @param session the session context * @return the fully loaded image * @throws ImageException If no suitable loader/converter combination is available to fulfill * the request or if an error occurred while loading the image. * @throws IOException If an I/O error occurs */ public Image getImage(ImageInfo info, ImageFlavor flavor, Map hints, ImageSessionContext session) throws ImageException, IOException { hints = prepareHints(hints, session); Image img = null; ImageProviderPipeline pipeline = getPipelineFactory().newImageConverterPipeline( info, flavor); if (pipeline != null) { img = pipeline.execute(info, hints, session); } if (img == null) { throw new ImageException( "Cannot load image (no suitable loader/converter combination available) for " + info); } XmlSourceUtil.closeQuietly(session.getSource(info.getOriginalURI())); return img; } /** * Loads an image. The caller can indicate what kind of image flavors are requested. When this * method is called the code looks for a suitable ImageLoader and, if necessary, builds * a conversion pipeline so it can return the image in exactly the form the caller needs. * The array of image flavors is ordered, so the first image flavor is given highest priority. *

    * Optionally, it is possible to pass in Map of hints. These hints may be used by ImageLoaders * and ImageConverters to act on the image. See {@link ImageProcessingHints} for common hints * used by the bundled implementations. You can, of course, define your own hints. * @param info the ImageInfo instance for the image (obtained by * {@link #getImageInfo(String, ImageSessionContext)}) * @param flavors the requested image flavors (in preferred order). * @param hints a Map of hints to any of the background components or null * @param session the session context * @return the fully loaded image * @throws ImageException If no suitable loader/converter combination is available to fulfill * the request or if an error occurred while loading the image. * @throws IOException If an I/O error occurs */ public Image getImage(ImageInfo info, ImageFlavor[] flavors, Map hints, ImageSessionContext session) throws ImageException, IOException { hints = prepareHints(hints, session); Image img = null; ImageProviderPipeline[] candidates = getPipelineFactory().determineCandidatePipelines( info, flavors); ImageProviderPipeline pipeline = choosePipeline(candidates); if (pipeline != null) { img = pipeline.execute(info, hints, session); } if (img == null) { throw new ImageException( "Cannot load image (no suitable loader/converter combination available) for " + info); } XmlSourceUtil.closeQuietly(session.getSource(info.getOriginalURI())); return img; } /** * Loads an image with no hints. See * {@link #getImage(ImageInfo, ImageFlavor, Map, ImageSessionContext)} for more * information. * @param info the ImageInfo instance for the image (obtained by * {@link #getImageInfo(String, ImageSessionContext)}) * @param flavor the requested image flavor. * @param session the session context * @return the fully loaded image * @throws ImageException If no suitable loader/converter combination is available to fulfill * the request or if an error occurred while loading the image. * @throws IOException If an I/O error occurs */ public Image getImage(ImageInfo info, ImageFlavor flavor, ImageSessionContext session) throws ImageException, IOException { return getImage(info, flavor, ImageUtil.getDefaultHints(session), session); } /** * Loads an image with no hints. See * {@link #getImage(ImageInfo, ImageFlavor[], Map, ImageSessionContext)} for more * information. * @param info the ImageInfo instance for the image (obtained by * {@link #getImageInfo(String, ImageSessionContext)}) * @param flavors the requested image flavors (in preferred order). * @param session the session context * @return the fully loaded image * @throws ImageException If no suitable loader/converter combination is available to fulfill * the request or if an error occurred while loading the image. * @throws IOException If an I/O error occurs */ public Image getImage(ImageInfo info, ImageFlavor[] flavors, ImageSessionContext session) throws ImageException, IOException { return getImage(info, flavors, ImageUtil.getDefaultHints(session), session); } /** * Closes the resources associated to the given image. This method should be * used only when none of the {@code getImage} methods is called by the * client application. * * @param uri the URI of the image * @param session the session context that was used to resolve the URI */ public void closeImage(String uri, ImageSessionContext session) { XmlSourceUtil.closeQuietly(session.getSource(uri)); } /** * Converts an image. The caller can indicate what kind of image flavors are requested. When * this method is called the code looks for a suitable combination of ImageConverters so it * can return the image in exactly the form the caller needs. * The array of image flavors is ordered, so the first image flavor is given highest priority. *

    * Optionally, it is possible to pass in Map of hints. These hints may be used by * ImageConverters to act on the image. See {@link ImageProcessingHints} for common hints * used by the bundled implementations. You can, of course, define your own hints. * @param image the image to convert * @param flavors the requested image flavors (in preferred order). * @param hints a Map of hints to any of the background components or null * @return the fully loaded image * @throws ImageException If no suitable loader/converter combination is available to fulfill * the request or if an error occurred while loading the image. * @throws IOException If an I/O error occurs */ public Image convertImage(Image image, ImageFlavor[] flavors, Map hints) throws ImageException, IOException { hints = prepareHints(hints, null); ImageInfo info = image.getInfo(); Image img = null; for (ImageFlavor flavor : flavors) { if (image.getFlavor().equals(flavor)) { //Shortcut (the image is already in one of the requested formats) return image; } } ImageProviderPipeline[] candidates = getPipelineFactory().determineCandidatePipelines( image, flavors); ImageProviderPipeline pipeline = choosePipeline(candidates); if (pipeline != null) { img = pipeline.execute(info, image, hints, null); } if (img == null) { throw new ImageException( "Cannot convert image " + image + " (no suitable converter combination available)"); } return img; } /** * Converts an image with no hints. See * {@link #convertImage(Image, ImageFlavor[], Map)} for more * information. * @param image the image to convert * @param flavors the requested image flavors (in preferred order). * @return the fully loaded image * @throws ImageException If no suitable loader/converter combination is available to fulfill * the request or if an error occurred while loading the image. * @throws IOException If an I/O error occurs */ public Image convertImage(Image image, ImageFlavor[] flavors) throws ImageException, IOException { return convertImage(image, flavors, null); } /** * Chooses the best {@link ImageProviderPipeline} from a set of candidates. * @param candidates the candidates * @return the best pipeline */ public ImageProviderPipeline choosePipeline(ImageProviderPipeline[] candidates) { ImageProviderPipeline pipeline = null; int minPenalty = Integer.MAX_VALUE; int count = candidates.length; if (log.isTraceEnabled()) { log.trace("Candidate Pipelines:"); for (int i = 0; i < count; i++) { if (candidates[i] == null) { continue; } log.trace(" " + i + ": " + candidates[i].getConversionPenalty(getRegistry()) + " for " + candidates[i]); } } for (int i = count - 1; i >= 0; i--) { if (candidates[i] == null) { continue; } Penalty penalty = candidates[i].getConversionPenalty(getRegistry()); if (penalty.isInfinitePenalty()) { continue; //Exclude candidate on infinite penalty } if (penalty.getValue() <= minPenalty) { pipeline = candidates[i]; minPenalty = penalty.getValue(); } } if (log.isDebugEnabled()) { log.debug("Chosen pipeline: " + pipeline); } return pipeline; } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/ImageProcessingHints.java0100644 0000000 0000000 00000006531 13777276623 032400 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageProcessingHints.java 924666 2010-03-18 08:26:30Z jeremias $ */ package org.apache.xmlgraphics.image.loader; /** * This interface defines some standard hints to be used for image processing in this package. * They are provided for convenience. You can define your own hints as you like. * Generally, consumers should not rely on the presence of any hint! */ public interface ImageProcessingHints { /** Used to send a hint about the source resolution for pixel to unit conversions. */ Object SOURCE_RESOLUTION = "SOURCE_RESOLUTION"; //Value: Number (unit dpi) /** Used to send a hint about the target resolution (of the final output format). */ Object TARGET_RESOLUTION = "TARGET_RESOLUTION"; //Value: Number (unit dpi) /** * Used to pass in the {@link ImageSessionContext}. A consumer can use this to load embedded * images over the same mechanism as the main image (ex. JPEG images referenced in an * SVG image). * @since 1.4 */ Object IMAGE_SESSION_CONTEXT = "IMAGE_SESSION_CONTEXT"; //Value: ImageSessionContext instance /** * Used to pass in the {@link ImageManager}. A consumer can use this to load embedded * images over the same mechanism as the main image (ex. JPEG images referenced in an * SVG image). * @since 1.4 */ Object IMAGE_MANAGER = "IMAGE_MANAGER"; //Value: ImageManager instance /** Used to tell the image loader to ignore any color profile in the image. */ Object IGNORE_COLOR_PROFILE = "IGNORE_COLOR_PROFILE"; //Value: Boolean /** Used to tell a bitmap producer to generate a certain type of bitmap. */ Object BITMAP_TYPE_INTENT = "BITMAP_TYPE_INTENT"; /** * Used with BITMAP_TYPE_INTENT to indicate that the generated bitmap should be a * grayscale image. */ String BITMAP_TYPE_INTENT_GRAY = "gray"; /** * Used with BITMAP_TYPE_INTENT to indicate that the generated bitmap should be a * 1 bit black and white image. */ String BITMAP_TYPE_INTENT_MONO = "mono"; /** * Used to indicate how existing transparency information (for example, an alpha channel) * shall be treated. */ Object TRANSPARENCY_INTENT = "TRANSPARENCY_INTENT"; /** * Used with TRANSPARENCY_INTENT to indicate that any transparency information shall be * preserved (the default). */ String TRANSPARENCY_INTENT_PRESERVE = "preserve"; /** * Used with TRANSPARENCY_INTENT to indicate that any transparency information shall be * ignored. */ String TRANSPARENCY_INTENT_IGNORE = "ignore"; } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/ImageSessionContext.java0100644 0000000 0000000 00000006553 13777276623 032252 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageSessionContext.java 750418 2009-03-05 11:03:54Z vhennebert $ */ package org.apache.xmlgraphics.image.loader; import java.io.FileNotFoundException; import javax.xml.transform.Source; /** * This interface is used to tell the cache which images are used by a session (in FOP that would * be a rendering run). Images access within a session get a hard reference so they cannot be * discarded. That could increase memory usage but helps with performance because the images * don't get unloaded between layout and rendering which would mean that they have to be reloaded. */ public interface ImageSessionContext { /** * Returns the session-independent context object which provides configuration information. * @return the associated ImageContext instance */ ImageContext getParentContext(); /** * Returns the resolution (in dpi) of the target device used when painting images. * @return the target resolution (in dpi) */ float getTargetResolution(); /** * Attempts to create a Source object from the given URI. If possible this method returns * an ImageSource instance which provides the best possible method to access the image. * @param uri URI to access * @return A {@link javax.xml.transform.Source} object, or null if the URI * cannot be resolved. */ Source newSource(String uri); /** * Returns a Source object for a URI. This method is not guaranteed to return an instance. * Implementations normally return already created Sources from a pool (normally populated * through the {@link #returnSource(String, Source)} method). * @param uri the URI of the image * @return the Source object to load the image from, or null */ Source getSource(String uri); /** * Returns a Source object for a URI. This method is guaranteed to return a Source object. If * the image cannot be found, a {@link FileNotFoundException} is thrown. * @param uri the URI of the image * @return the Source object to load the image from * @throws FileNotFoundException if the image cannot be found */ Source needSource(String uri) throws FileNotFoundException; /** * Returns a Source object to a pool. This is provided in order to reuse a Source object * between the preloading and the final loading of an image. Note that not all Source objects * can be reused! Non-reusable Sources are discarded. * @param uri the URI of the image * @param src the Source object belonging to the URI */ void returnSource(String uri, Source src); } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/ImageSize.java0100644 0000000 0000000 00000017076 13777276623 030176 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageSize.java 696968 2008-09-19 07:52:04Z jeremias $ */ package org.apache.xmlgraphics.image.loader; import java.awt.Dimension; import java.awt.geom.Dimension2D; import org.apache.xmlgraphics.java2d.Dimension2DDouble; import org.apache.xmlgraphics.util.UnitConv; /** * Encapsulates the size of an image. */ public class ImageSize { private int widthPx; private int heightPx; private int widthMpt; private int heightMpt; private int baselinePositionFromBottomMpt; private double dpiHorizontal; private double dpiVertical; /** * Constructor. * @param widthPx the width of the image in pixels * @param heightPx the height of the image in pixels * @param dpiHorizontal the horizontal resolution in dots per inch * @param dpiVertical the vertical resolution in dots per inch */ public ImageSize(int widthPx, int heightPx, double dpiHorizontal, double dpiVertical) { setSizeInPixels(widthPx, heightPx); setResolution(dpiHorizontal, dpiVertical); } /** * Constructor. * @param widthPx the width of the image in pixels * @param heightPx the height of the image in pixels * @param dpi the resolution in dots per inch */ public ImageSize(int widthPx, int heightPx, double dpi) { this(widthPx, heightPx, dpi, dpi); } /** * Default Constructor. */ public ImageSize() { //nop } /** * Sets the image's size in pixels. * @param width the width in pixels * @param height the height in pixels */ public void setSizeInPixels(int width, int height) { this.widthPx = width; this.heightPx = height; } /** * Sets the image's size in millipoints. * @param width the width in millipoints * @param height the height in millipoints */ public void setSizeInMillipoints(int width, int height) { this.widthMpt = width; this.heightMpt = height; } /** * Sets the image's resolution for interpreting the pixel size. * @param horizontal the horizontal resolution in dpi * @param vertical the vertical resolution in dpi */ public void setResolution(double horizontal, double vertical) { this.dpiHorizontal = horizontal; this.dpiVertical = vertical; } /** * Sets the image's resolution for interpreting the pixel size. * @param resolution the resolution in dpi */ public void setResolution(double resolution) { setResolution(resolution, resolution); } /** * Sets the vertical position of the baseline of the image relative to the bottom of the image. * The default is 0mpt (i.e. the image is bottom-aligned). This is used for MathML images, for * example, which have a baseline. Using the value the images can be properly aligned with * other text. Most other image don't have an implicit baseline. * @param distance the distance from the bottom of the image in millipoints */ public void setBaselinePositionFromBottom(int distance) { this.baselinePositionFromBottomMpt = distance; } /** * Returns the vertical position of the baseline of the image relative to the bottom of the * image. The default is 0mpt (i.e. the image is bottom-aligned). This is used for MathML * images, for example, which have a baseline. Using the value the images can be properly * aligned with other text. Most other image don't have an implicit baseline. * @return the distance from the bottom of the image in millipoints */ public int getBaselinePositionFromBottom() { return this.baselinePositionFromBottomMpt; } /** * Returns the image's width in pixels. * @return the width in pixels */ public int getWidthPx() { return widthPx; } /** * Returns the image's height in pixels. * @return the height in pixels */ public int getHeightPx() { return heightPx; } /** * Returns the image's width in millipoints. * @return the width in millipoints */ public int getWidthMpt() { return widthMpt; } /** * Returns the image's height in millipoints. * @return the height in millipoints */ public int getHeightMpt() { return heightMpt; } /** * Returns the image's horizontal resolution in dpi (dots per inch). * @return the horizontal resolution in dpi */ public double getDpiHorizontal() { return dpiHorizontal; } /** * Returns the image's vertical resolution in dpi (dots per inch). * @return the vertical resolution in dpi */ public double getDpiVertical() { return dpiVertical; } /** * Returns the size in millipoints as a Dimension object. * @return the size in millipoints */ public Dimension getDimensionMpt() { return new Dimension(getWidthMpt(), getHeightMpt()); } /** * Returns the size in points as a Dimension2D object. * @return the size in points */ public Dimension2D getDimensionPt() { return new Dimension2DDouble(getWidthMpt() / 1000.0, getHeightMpt() / 1000.0); } /** * Returns the size in pixels as a Dimension object. * @return the size in pixels */ public Dimension getDimensionPx() { return new Dimension(getWidthPx(), getHeightPx()); } private void checkResolutionAvailable() { if (this.dpiHorizontal == 0 || this.dpiVertical == 0) { throw new IllegalStateException("The resolution must be set"); } } /** * Calculates the size in millipoints based on the size in pixels and the resolution. */ public void calcSizeFromPixels() { checkResolutionAvailable(); this.widthMpt = (int)Math.round(UnitConv.in2mpt(this.widthPx / this.dpiHorizontal)); this.heightMpt = (int)Math.round(UnitConv.in2mpt(this.heightPx / this.dpiVertical)); } /** * Calculates the size in pixels based on the size in millipoints and the resolution. */ public void calcPixelsFromSize() { checkResolutionAvailable(); this.widthPx = (int)Math.round(UnitConv.mpt2in(this.widthMpt * this.dpiHorizontal)); this.heightPx = (int)Math.round(UnitConv.mpt2in(this.heightMpt * this.dpiVertical)); } /** {@inheritDoc} */ public String toString() { StringBuffer sb = new StringBuffer(); sb.append("Size: "); sb.append(getWidthMpt()).append('x').append(getHeightMpt()).append(" mpt"); sb.append(" ("); sb.append(getWidthPx()).append('x').append(getHeightPx()).append(" px"); sb.append(" at ").append(getDpiHorizontal()).append('x').append(getDpiVertical()); sb.append(" dpi"); sb.append(")"); return sb.toString(); } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/ImageSource.java0100644 0000000 0000000 00000006173 13777276623 030520 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageSource.java 750418 2009-03-05 11:03:54Z vhennebert $ */ package org.apache.xmlgraphics.image.loader; import java.io.InputStream; import javax.imageio.stream.ImageInputStream; import javax.xml.transform.Source; import org.apache.xmlgraphics.image.loader.util.ImageInputStreamAdapter; /** * Acts as a holder for the input to image loading operations. */ public class ImageSource implements Source { private String systemId; private ImageInputStream iin; private boolean fastSource; /** * Main constructor. * @param in the ImageInputStream to load from * @param systemId the system identifier (resolved URI) of the image * @param fastSource true if it's a fast source (accessing local files) */ public ImageSource(ImageInputStream in, String systemId, boolean fastSource) { assert in != null : "InputStream is null"; this.iin = in; this.systemId = systemId; this.fastSource = fastSource; } /** * Returns an InputStream which operates on the underlying ImageInputStream. * @return the InputStream or null if the stream has been closed */ public InputStream getInputStream() { if (this.iin == null) { return null; } else { return new ImageInputStreamAdapter(this.iin); } } /** * Returns the ImageInputStream. * @return the ImageInputStream or null if the stream has been closed */ public ImageInputStream getImageInputStream() { return this.iin; } /** * Sets the ImageInputStream. * @param in the ImageInputStream */ public void setImageInputStream(ImageInputStream in) { this.iin = in; } /** {@inheritDoc} */ public String getSystemId() { return this.systemId; } /** {@inheritDoc} */ public void setSystemId(String systemId) { this.systemId = systemId; } /** * Indicates whether this ImageSource is a fast source, i.e. accesses local files rather than * network resources. * @return true if it's a fast source */ public boolean isFastSource() { return this.fastSource; } /** {@inheritDoc} */ public String toString() { return (isFastSource() ? "FAST " : "") + "ImageSource: " + getSystemId() + " " + getImageInputStream(); } } ././@LongLink0100644 0000000 0000000 00000000146 13777276623 011660 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/MimeEnabledImageFlavor.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/MimeEnabledImageFlavor.jav0100644 0000000 0000000 00000004244 13777276623 032430 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: MimeEnabledImageFlavor.java 1731775 2016-02-23 01:13:36Z gadams $ */ package org.apache.xmlgraphics.image.loader; /** * Special image flavor subclass which enables the restriction to a particular MIME type. */ public class MimeEnabledImageFlavor extends RefinedImageFlavor { private String mime; /** * Constructs a new image flavor. * @param parentFlavor the parent image flavor * @param mime a MIME type refining the parent image flavor */ public MimeEnabledImageFlavor(ImageFlavor parentFlavor, String mime) { super(mime + ";" + parentFlavor.getName(), parentFlavor); this.mime = mime; } /** {@inheritDoc} */ public String getMimeType() { return this.mime; } @Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } if (!super.equals(o)) { return false; } MimeEnabledImageFlavor that = (MimeEnabledImageFlavor) o; if (mime != null ? !mime.equals(that.mime) : that.mime != null) { return false; } return true; } @Override public int hashCode() { int result = super.hashCode(); result = 31 * result + (mime != null ? mime.hashCode() : 0); return result; } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/RefinedImageFlavor.java0100644 0000000 0000000 00000004437 13777276623 032007 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: RefinedImageFlavor.java 734638 2009-01-15 09:19:32Z jeremias $ */ package org.apache.xmlgraphics.image.loader; /** * Special image flavor subclass which enables the refinement to specific (sub-)flavors but * maintaining compatibility to a parent (i.e. more general) flavor. */ public abstract class RefinedImageFlavor extends ImageFlavor { private ImageFlavor parentFlavor; /** * Constructs a new image flavor. * @param parentFlavor the parent image flavor */ protected RefinedImageFlavor(ImageFlavor parentFlavor) { this(parentFlavor.getName(), parentFlavor); } /** * Constructs a new image flavor. * @param parentFlavor the parent image flavor * @param name the name of the flavor (must be unique) */ protected RefinedImageFlavor(String name, ImageFlavor parentFlavor) { super(name); this.parentFlavor = parentFlavor; } /** * Returns the associated parent image flavor. * @return the parent image flavor */ public ImageFlavor getParentFlavor() { return this.parentFlavor; } /** {@inheritDoc} */ public String getMimeType() { return this.parentFlavor.getMimeType(); } /** {@inheritDoc} */ public String getNamespace() { return this.parentFlavor.getNamespace(); } /** {@inheritDoc} */ public boolean isCompatible(ImageFlavor flavor) { return getParentFlavor().isCompatible(flavor) || super.isCompatible(flavor); } } ././@LongLink0100644 0000000 0000000 00000000150 13777276623 011653 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/SimpleRefinedImageFlavor.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/SimpleRefinedImageFlavor.j0100644 0000000 0000000 00000002556 13777276623 032471 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: SimpleRefinedImageFlavor.java 682720 2008-08-05 14:22:29Z jeremias $ */ package org.apache.xmlgraphics.image.loader; /** * Simple refined image flavor implementation that just differs flavors by name but allows to * specify a parent flavor. */ public class SimpleRefinedImageFlavor extends RefinedImageFlavor { /** * Main constructor. * @param parentFlavor the parent image flavor * @param name the name of the image flavor */ public SimpleRefinedImageFlavor(ImageFlavor parentFlavor, String name) { super(name, parentFlavor); } } ././@LongLink0100644 0000000 0000000 00000000151 13777276623 011654 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/SubImageNotFoundException.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/SubImageNotFoundException.0100644 0000000 0000000 00000004450 13777276623 032477 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: SubImageNotFoundException.java 750418 2009-03-05 11:03:54Z vhennebert $ */ package org.apache.xmlgraphics.image.loader; /** * Exception which indicates that a particular (sub-)image could not be found. */ public class SubImageNotFoundException extends ImageException { private static final long serialVersionUID = 3785613905389979249L; /** * Constructs an ImageException with the specified detail * message. The error message string s can later be * retrieved by the {@link java.lang.Throwable#getMessage} * method of class java.lang.Throwable. * * @param s the detail message. */ public SubImageNotFoundException(String s) { super(s); } /** * Constructs a new ImageException with the specified detail message and * cause.

    Note that the detail message associated with * cause is not automatically incorporated in * this exception's detail message. * * @param message the detail message (which is saved for later retrieval * by the {@link #getMessage()} method). * @param cause the cause (which is saved for later retrieval by the * {@link #getCause()} method). (A null value is * permitted, and indicates that the cause is nonexistent or * unknown.) */ public SubImageNotFoundException(String message, Throwable cause) { super(message, cause); } } ././@LongLink0100644 0000000 0000000 00000000156 13777276623 011661 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/XMLNamespaceEnabledImageFlavor.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/XMLNamespaceEnabledImageFl0100644 0000000 0000000 00000004770 13777276623 032353 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: XMLNamespaceEnabledImageFlavor.java 1731775 2016-02-23 01:13:36Z gadams $ */ package org.apache.xmlgraphics.image.loader; /** * Special image flavor subclass which enables the restriction to a particular XML namespace. */ public class XMLNamespaceEnabledImageFlavor extends RefinedImageFlavor { /** An XML-based SVG image in form of a W3C DOM instance */ public static final ImageFlavor SVG_DOM = new XMLNamespaceEnabledImageFlavor( ImageFlavor.XML_DOM, "http://www.w3.org/2000/svg"); private String namespace; /** * Constructs a new image flavor. * @param parentFlavor the parent image flavor * @param namespace an XML namespace URI refining the parent image flavor */ public XMLNamespaceEnabledImageFlavor(ImageFlavor parentFlavor, String namespace) { super(parentFlavor.getName() + ";namespace=" + namespace, parentFlavor); this.namespace = namespace; } /** {@inheritDoc} */ public String getNamespace() { return this.namespace; } @Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } if (!super.equals(o)) { return false; } XMLNamespaceEnabledImageFlavor that = (XMLNamespaceEnabledImageFlavor) o; if (namespace != null ? !namespace.equals(that.namespace) : that.namespace != null) { return false; } return true; } @Override public int hashCode() { int result = super.hashCode(); result = 31 * result + (namespace != null ? namespace.hashCode() : 0); return result; } } ././@LongLink0100644 0000000 0000000 00000000155 13777276623 011660 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/cache/DefaultExpirationPolicy.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/cache/DefaultExpirationPol0100644 0000000 0000000 00000003775 13777276623 032547 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: DefaultExpirationPolicy.java 1681108 2015-05-22 13:26:12Z ssteiner $ */ package org.apache.xmlgraphics.image.loader.cache; /** * Implements the default expiration policy for the image cache. */ public class DefaultExpirationPolicy implements ExpirationPolicy { public static final int EXPIRATION_IMMEDIATE = 0; public static final int EXPIRATION_NEVER = -1; private int expirationAfter; //in seconds /** * Creates a new policy with default settings (expiration in 60 seconds). */ public DefaultExpirationPolicy() { this(60); } /** * Creates a new policy. * @param expirationAfter the expiration in seconds (a negative value means: never expire) */ public DefaultExpirationPolicy(int expirationAfter) { this.expirationAfter = expirationAfter; } private boolean isNeverExpired() { return (this.expirationAfter < 0); } /** {@inheritDoc} */ public boolean isExpired(TimeStampProvider provider, long timestamp) { if (isNeverExpired()) { return false; } else { long now = provider.getTimeStamp(); return now >= (timestamp + (this.expirationAfter * 1000L)); } } } ././@LongLink0100644 0000000 0000000 00000000146 13777276623 011660 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/cache/ExpirationPolicy.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/cache/ExpirationPolicy.jav0100644 0000000 0000000 00000002723 13777276623 032516 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ExpirationPolicy.java 759150 2009-03-27 14:21:45Z jeremias $ */ package org.apache.xmlgraphics.image.loader.cache; /** * Represents an expiration policy for cache entries that have a creation time stamp. */ public interface ExpirationPolicy { /** * Indicates whether a cache entry is expired given its creation time stamp. * @param provider the provider for new time stamps * @param timestamp the creation time stamp (the semantics of * {@link System#currentTimeMillis()} apply) * @return true if the entry is to be considered expired, false if not */ boolean isExpired(TimeStampProvider provider, long timestamp); } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/cache/ImageCache.java0100644 0000000 0000000 00000025324 13777276623 031325 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageCache.java 1804124 2017-08-04 14:13:54Z ssteiner $ */ package org.apache.xmlgraphics.image.loader.cache; import java.io.FileNotFoundException; import java.io.IOException; import java.util.Collections; import java.util.HashSet; import java.util.Map; import java.util.Set; import javax.xml.transform.Source; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.xmlgraphics.image.loader.Image; import org.apache.xmlgraphics.image.loader.ImageException; import org.apache.xmlgraphics.image.loader.ImageFlavor; import org.apache.xmlgraphics.image.loader.ImageInfo; import org.apache.xmlgraphics.image.loader.ImageManager; import org.apache.xmlgraphics.image.loader.ImageSessionContext; import org.apache.xmlgraphics.image.loader.util.SoftMapCache; /** * This class provides a cache for images. The main key into the images is the original URI the * image was accessed with. *

    * Don't use one ImageCache instance in the context of multiple base URIs because relative URIs * would not work correctly anymore. *

    * By default, the URIs of inaccessible images are remembered but these entries are discarded * after 60 seconds (which causes a retry next time the same URI is requested). This allows * to counteract performance loss when accessing invalid or temporarily unavailable images * over slow connections. */ public class ImageCache { /** logger */ protected static final Log log = LogFactory.getLog(ImageCache.class); //Handling of invalid URIs private Map invalidURIs = Collections.synchronizedMap(new java.util.HashMap()); private ExpirationPolicy invalidURIExpirationPolicy; //Actual image cache private SoftMapCache imageInfos = new SoftMapCache(true); private SoftMapCache images = new SoftMapCache(true); private ImageCacheListener cacheListener; private TimeStampProvider timeStampProvider; private long lastHouseKeeping; /** * Default constructor with default settings. */ public ImageCache() { this(new TimeStampProvider(), new DefaultExpirationPolicy()); } /** * Constructor for customized behaviour and testing. * @param timeStampProvider the time stamp provider to use * @param invalidURIExpirationPolicy the expiration policy for invalid URIs */ public ImageCache(TimeStampProvider timeStampProvider, ExpirationPolicy invalidURIExpirationPolicy) { this.timeStampProvider = timeStampProvider; this.invalidURIExpirationPolicy = invalidURIExpirationPolicy; this.lastHouseKeeping = this.timeStampProvider.getTimeStamp(); } /** * Sets an ImageCacheListener instance so the events in the image cache can be observed. * @param listener the listener instance */ public void setCacheListener(ImageCacheListener listener) { this.cacheListener = listener; } /** * Returns an ImageInfo instance for a given URI. * @param uri the image's URI * @param session the session context * @param manager the ImageManager handling the images * @return the ImageInfo instance * @throws ImageException if an error occurs while parsing image data * @throws IOException if an I/O error occurs while loading image data */ public ImageInfo needImageInfo(String uri, ImageSessionContext session, ImageManager manager) throws ImageException, IOException { //Fetch unique version of the URI and use it for synchronization so we have some sort of //"row-level" locking instead of "table-level" locking (to use a database analogy). //The fine locking strategy is necessary since preloading an image is a potentially long //operation. if (isInvalidURI(uri)) { throw new FileNotFoundException("Image not found: " + uri); } String lockURI = uri.intern(); synchronized (lockURI) { ImageInfo info = getImageInfo(uri); if (info == null) { try { Source src = session.needSource(uri); if (src == null) { registerInvalidURI(uri); throw new FileNotFoundException("Image not found: " + uri); } info = manager.preloadImage(uri, src); session.returnSource(uri, src); } catch (IOException ioe) { registerInvalidURI(uri); throw ioe; } catch (ImageException e) { registerInvalidURI(uri); throw e; } if (info.getOriginalImage() == null || info.getOriginalImage().isCacheable()) { putImageInfo(info); } } return info; } } /** * Indicates whether a URI has previously been identified as an invalid URI. * @param uri the image's URI * @return true if the URI is invalid */ public boolean isInvalidURI(String uri) { boolean expired = removeInvalidURIIfExpired(uri); if (expired) { return false; } else { if (cacheListener != null) { cacheListener.invalidHit(uri); } return true; } } private boolean removeInvalidURIIfExpired(String uri) { Long timestamp = (Long) invalidURIs.get(uri); boolean expired = (timestamp == null) || this.invalidURIExpirationPolicy.isExpired( this.timeStampProvider, timestamp); if (expired) { this.invalidURIs.remove(uri); } return expired; } /** * Returns an ImageInfo instance from the cache or null if none is found. * @param uri the image's URI * @return the ImageInfo instance or null if the requested information is not in the cache */ protected ImageInfo getImageInfo(String uri) { ImageInfo info = (ImageInfo)imageInfos.get(uri); if (cacheListener != null) { if (info != null) { cacheListener.cacheHitImageInfo(uri); } else { if (!isInvalidURI(uri)) { cacheListener.cacheMissImageInfo(uri); } } } return info; } /** * Registers an ImageInfo instance with the cache. * @param info the ImageInfo instance */ protected void putImageInfo(ImageInfo info) { //An already existing ImageInfo is replaced. imageInfos.put(info.getOriginalURI(), info); } private static final long ONE_HOUR = 60 * 60 * 1000; /** * Registers a URI as invalid so getImageInfo can indicate that quickly with no I/O access. * @param uri the URI of the invalid image */ void registerInvalidURI(String uri) { invalidURIs.put(uri, timeStampProvider.getTimeStamp()); considerHouseKeeping(); } /** * Returns an image from the cache or null if it wasn't found. * @param info the ImageInfo instance representing the image * @param flavor the requested ImageFlavor for the image * @return the requested image or null if the image is not in the cache */ public Image getImage(ImageInfo info, ImageFlavor flavor) { return getImage(info.getOriginalURI(), flavor); } /** * Returns an image from the cache or null if it wasn't found. * @param uri the image's URI * @param flavor the requested ImageFlavor for the image * @return the requested image or null if the image is not in the cache */ public Image getImage(String uri, ImageFlavor flavor) { if (uri == null || "".equals(uri)) { return null; } ImageKey key = new ImageKey(uri, flavor); Image img = (Image)images.get(key); if (cacheListener != null) { if (img != null) { cacheListener.cacheHitImage(key); } else { cacheListener.cacheMissImage(key); } } return img; } /** * Registers an image with the cache. * @param img the image */ public void putImage(Image img) { String originalURI = img.getInfo().getOriginalURI(); if (originalURI == null || "".equals(originalURI)) { return; //Don't cache if there's no URI } //An already existing Image is replaced. if (!img.isCacheable()) { throw new IllegalArgumentException( "Image is not cacheable! (Flavor: " + img.getFlavor() + ")"); } ImageKey key = new ImageKey(originalURI, img.getFlavor()); images.put(key, img); } /** * Clears the image cache (all ImageInfo and Image objects). */ public void clearCache() { invalidURIs.clear(); imageInfos.clear(); images.clear(); doHouseKeeping(); } private void considerHouseKeeping() { long ts = timeStampProvider.getTimeStamp(); if (this.lastHouseKeeping + ONE_HOUR > ts) { //Housekeeping is only triggered through registration of an invalid URI at the moment. //Depending on the environment this could be triggered next to never. //Doing this check for every image access could be relatively costly. //The only alternative is a cleanup thread which is rather heavy-weight. this.lastHouseKeeping = ts; doHouseKeeping(); } } /** * Triggers some house-keeping, i.e. removes stale entries. */ public void doHouseKeeping() { imageInfos.doHouseKeeping(); images.doHouseKeeping(); doInvalidURIHouseKeeping(); } private void doInvalidURIHouseKeeping() { final Set currentEntries = new HashSet(this.invalidURIs.keySet()); for (Object currentEntry : currentEntries) { final String key = (String) currentEntry; removeInvalidURIIfExpired(key); } } } ././@LongLink0100644 0000000 0000000 00000000150 13777276623 011653 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/cache/ImageCacheListener.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/cache/ImageCacheListener.j0100644 0000000 0000000 00000003430 13777276623 032335 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageCacheListener.java 750418 2009-03-05 11:03:54Z vhennebert $ */ package org.apache.xmlgraphics.image.loader.cache; import java.util.EventListener; /** * This interface can be implemented by classes which want to know what's going on inside the * image cache. */ public interface ImageCacheListener extends EventListener { /** * An URi previously identified as invalid was requested again * @param uri the invalid URI */ void invalidHit(String uri); /** * An ImageInfo was found in the cache * @param uri the image's URI */ void cacheHitImageInfo(String uri); /** * An ImageInfo was not in the cache * @param uri the image's URI */ void cacheMissImageInfo(String uri); /** * An Image was found in the cache * @param key the image key */ void cacheHitImage(ImageKey key); /** * An Image was not in the cache * @param key the image key */ void cacheMissImage(ImageKey key); } ././@LongLink0100644 0000000 0000000 00000000152 13777276623 011655 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/cache/ImageCacheStatistics.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/cache/ImageCacheStatistics0100644 0000000 0000000 00000010703 13777276623 032453 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageCacheStatistics.java 1681108 2015-05-22 13:26:12Z ssteiner $ */ package org.apache.xmlgraphics.image.loader.cache; import java.util.Collections; import java.util.Map; /** * Convenience class that gathers statistical information about the image cache. */ public class ImageCacheStatistics implements ImageCacheListener { private int invalidHits; private int imageInfoCacheHits; private int imageInfoCacheMisses; private int imageCacheHits; private int imageCacheMisses; private Map imageCacheHitMap; private Map imageCacheMissMap; /** * Main constructor. * @param detailed true if the cache hits/misses for each Image instance should be recorded. */ public ImageCacheStatistics(boolean detailed) { if (detailed) { imageCacheHitMap = new java.util.HashMap(); imageCacheMissMap = new java.util.HashMap(); } } /** * Reset the gathered statistics information. */ public void reset() { this.imageInfoCacheHits = 0; this.imageInfoCacheMisses = 0; this.invalidHits = 0; } /** {@inheritDoc} */ public void invalidHit(String uri) { invalidHits++; } /** {@inheritDoc} */ public void cacheHitImageInfo(String uri) { imageInfoCacheHits++; } /** {@inheritDoc} */ public void cacheMissImageInfo(String uri) { imageInfoCacheMisses++; } private void increaseEntry(Map map, Object key) { Integer v = (Integer)map.get(key); if (v == null) { v = 1; } else { v++; } map.put(key, v); } /** {@inheritDoc} */ public void cacheHitImage(ImageKey key) { imageCacheHits++; if (imageCacheHitMap != null) { increaseEntry(imageCacheHitMap, key); } } /** {@inheritDoc} */ public void cacheMissImage(ImageKey key) { imageCacheMisses++; if (imageCacheMissMap != null) { increaseEntry(imageCacheMissMap, key); } } /** * Returns the number of times an invalid URI is tried. * @return the number of times an invalid URI is tried. */ public int getInvalidHits() { return invalidHits; } /** * Returns the number of cache hits for ImageInfo instances. * @return the number of cache hits for ImageInfo instances. */ public int getImageInfoCacheHits() { return imageInfoCacheHits; } /** * Returns the number of cache misses for ImageInfo instances. * @return the number of cache misses for ImageInfo instances. */ public int getImageInfoCacheMisses() { return imageInfoCacheMisses; } /** * Returns the number of cache hits for Image instances. * @return the number of cache hits for Image instances. */ public int getImageCacheHits() { return imageCacheHits; } /** * Returns the number of cache misses for Image instances. * @return the number of cache misses for Image instances. */ public int getImageCacheMisses() { return imageCacheMisses; } /** * Returns a Map<ImageKey, Integer> with the number of cache hits. * @return a Map<ImageKey, Integer> with the number of cache hits */ public Map getImageCacheHitMap() { return Collections.unmodifiableMap(imageCacheHitMap); } /** * Returns a Map<ImageKey, Integer> with the number of cache misses. * @return a Map<ImageKey, Integer> with the number of cache misses */ public Map getImageCacheMissMap() { return Collections.unmodifiableMap(imageCacheMissMap); } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/cache/ImageKey.java0100644 0000000 0000000 00000004667 13777276623 031061 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageKey.java 1345683 2012-06-03 14:50:33Z gadams $ */ package org.apache.xmlgraphics.image.loader.cache; import org.apache.xmlgraphics.image.loader.ImageFlavor; /** * Key class for Image instances in the cache. */ public class ImageKey { private String uri; private org.apache.xmlgraphics.image.loader.ImageFlavor flavor; /** * Main constructor. * @param uri the original URI * @param flavor the image flavor */ public ImageKey(String uri, ImageFlavor flavor) { if (uri == null) { throw new NullPointerException("URI must not be null"); } if (flavor == null) { throw new NullPointerException("flavor must not be null"); } this.uri = uri; this.flavor = flavor; } /** {@inheritDoc} */ public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((flavor == null) ? 0 : flavor.hashCode()); result = prime * result + ((uri == null) ? 0 : uri.hashCode()); return result; } /** {@inheritDoc} */ public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } final ImageKey other = (ImageKey)obj; if (!uri.equals(other.uri)) { return false; } if (!flavor.equals(other.flavor)) { return false; } return true; } /** {@inheritDoc} */ public String toString() { return uri + " (" + flavor + ")"; } } ././@LongLink0100644 0000000 0000000 00000000147 13777276623 011661 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/cache/TimeStampProvider.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/cache/TimeStampProvider.ja0100644 0000000 0000000 00000002612 13777276623 032441 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: TimeStampProvider.java 759150 2009-03-27 14:21:45Z jeremias $ */ package org.apache.xmlgraphics.image.loader.cache; /** * Returns time stamps for the image cache for entry expiration functionality. This functionality * is in its own class so it's easy to write a mock class for testing. */ class TimeStampProvider { /** * Returns the current time stamp. * @return the current time stamp (the value returned follows the semantics of * {@link System#currentTimeMillis()}) */ public long getTimeStamp() { return System.currentTimeMillis(); } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/cache/package.html0100644 0000000 0000000 00000001645 13777276623 030775 0ustar000000000 0000000 org.apache.fop.image2.cache Package

    Contains image caching infrastructure.

    xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/AbstractImage.java0100644 0000000 0000000 00000004200 13777276623 031751 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: AbstractImage.java 750418 2009-03-05 11:03:54Z vhennebert $ */ package org.apache.xmlgraphics.image.loader.impl; import java.awt.color.ColorSpace; import java.awt.color.ICC_ColorSpace; import java.awt.color.ICC_Profile; import org.apache.xmlgraphics.image.loader.Image; import org.apache.xmlgraphics.image.loader.ImageInfo; import org.apache.xmlgraphics.image.loader.ImageSize; /** * Abstract base class for Image implementations. */ public abstract class AbstractImage implements Image { private ImageInfo info; /** * Main constructor * @param info the image info object associated with this image */ public AbstractImage(ImageInfo info) { this.info = info; } /** {@inheritDoc} */ public ImageInfo getInfo() { return this.info; } /** {@inheritDoc} */ public ImageSize getSize() { return getInfo().getSize(); } /** {@inheritDoc} */ public ColorSpace getColorSpace() { return null; } /** {@inheritDoc} */ public ICC_Profile getICCProfile() { if (getColorSpace() instanceof ICC_ColorSpace) { return ((ICC_ColorSpace)getColorSpace()).getProfile(); } else { return null; } } /** {@inheritDoc} */ public String toString() { return getClass().getName() + ": " + getInfo(); } } ././@LongLink0100644 0000000 0000000 00000000153 13777276623 011656 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/AbstractImageConverter.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/AbstractImageConverte0100644 0000000 0000000 00000003171 13777276623 032545 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: AbstractImageConverter.java 750418 2009-03-05 11:03:54Z vhennebert $ */ package org.apache.xmlgraphics.image.loader.impl; import org.apache.xmlgraphics.image.loader.Image; import org.apache.xmlgraphics.image.loader.spi.ImageConverter; /** * Abstract base class for ImageConverter implementations. */ public abstract class AbstractImageConverter implements ImageConverter { /** * Checks if the source flavor of the given image is compatible with this ImageConverter. * @param img the image to check */ protected void checkSourceFlavor(Image img) { if (!getSourceFlavor().equals(img.getFlavor())) { throw new IllegalArgumentException("Incompatible image: " + img); } } /** {@inheritDoc} */ public int getConversionPenalty() { return MEDIUM_CONVERSION_PENALTY; } } ././@LongLink0100644 0000000 0000000 00000000150 13777276623 011653 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/AbstractImageLoader.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/AbstractImageLoader.j0100644 0000000 0000000 00000004372 13777276623 032422 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: AbstractImageLoader.java 1681108 2015-05-22 13:26:12Z ssteiner $ */ package org.apache.xmlgraphics.image.loader.impl; import java.io.IOException; import java.util.Map; import org.apache.xmlgraphics.image.loader.Image; import org.apache.xmlgraphics.image.loader.ImageException; import org.apache.xmlgraphics.image.loader.ImageInfo; import org.apache.xmlgraphics.image.loader.ImageProcessingHints; import org.apache.xmlgraphics.image.loader.ImageSessionContext; import org.apache.xmlgraphics.image.loader.spi.ImageLoader; /** * Simple abstract base class for ImageLoaders. */ public abstract class AbstractImageLoader implements ImageLoader { /** {@inheritDoc} */ public Image loadImage(ImageInfo info, ImageSessionContext session) throws ImageException, IOException { return loadImage(info, null, session); } /** {@inheritDoc} */ public int getUsagePenalty() { return NO_LOADING_PENALTY; } /** * Indicates whether an embedded color profile should be ignored. * @param hints a Map of hints that can be used by implementations to customize the loading * process (may be null). * @return true if any color profile should be ignored */ protected boolean ignoreColorProfile(Map hints) { if (hints == null) { return false; } Boolean b = (Boolean)hints.get(ImageProcessingHints.IGNORE_COLOR_PROFILE); return (b != null) && b; } } ././@LongLink0100644 0000000 0000000 00000000157 13777276623 011662 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/AbstractImageLoaderFactory.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/AbstractImageLoaderFa0100644 0000000 0000000 00000003506 13777276623 032437 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: AbstractImageLoaderFactory.java 924666 2010-03-18 08:26:30Z jeremias $ */ package org.apache.xmlgraphics.image.loader.impl; import org.apache.xmlgraphics.image.loader.ImageFlavor; import org.apache.xmlgraphics.image.loader.ImageInfo; import org.apache.xmlgraphics.image.loader.spi.ImageLoader; import org.apache.xmlgraphics.image.loader.spi.ImageLoaderFactory; /** * Abstract base class for ImageLoaderFactory implementations. */ public abstract class AbstractImageLoaderFactory implements ImageLoaderFactory { /** {@inheritDoc} */ public boolean isSupported(ImageInfo imageInfo) { //Most ImageLoaderFactories are assumed to support the complete feature set of //an image format. return true; } /** * {@inheritDoc} * @deprecated Redundancy with {@link ImageLoader#getUsagePenalty()} */ public int getUsagePenalty(String mime, ImageFlavor flavor) { //Kept for compatibility ImageLoader loader = newImageLoader(flavor); return loader.getUsagePenalty(); } } ././@LongLink0100644 0000000 0000000 00000000153 13777276623 011656 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/AbstractImagePreloader.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/AbstractImagePreloade0100644 0000000 0000000 00000004116 13777276623 032513 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: AbstractImagePreloader.java 750418 2009-03-05 11:03:54Z vhennebert $ */ package org.apache.xmlgraphics.image.loader.impl; import java.io.IOException; import java.util.Arrays; import javax.imageio.stream.ImageInputStream; import org.apache.xmlgraphics.image.loader.spi.ImagePreloader; /** * Abstract base class for image preloaders. It provides helper methods for often-used tasks. */ public abstract class AbstractImagePreloader implements ImagePreloader { /** * Allows to read an image header (usually just a magic number). The InputStream is reset * to the position before the header was read. * @param in the ImageInputStream to read from * @param size the size of the header * @return the loaded header * @throws IOException if an I/O error occurs while reading the header */ protected byte[] getHeader(ImageInputStream in, int size) throws IOException { byte[] header = new byte[size]; long startPos = in.getStreamPosition(); int read = in.read(header); if (read < size) { Arrays.fill(header, (byte)0); } in.seek(startPos); //Seek back to start position return header; } /** {@inheritDoc} */ public int getPriority() { return DEFAULT_PRIORITY; } } ././@LongLink0100644 0000000 0000000 00000000160 13777276623 011654 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/AbstractImageSessionContext.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/AbstractImageSessionC0100644 0000000 0000000 00000040005 13777276623 032503 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: AbstractImageSessionContext.java 1796008 2017-05-24 08:16:01Z ssteiner $ */ package org.apache.xmlgraphics.image.loader.impl; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.net.MalformedURLException; import java.net.URL; import javax.imageio.ImageIO; import javax.imageio.stream.ImageInputStream; import javax.xml.transform.Source; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.sax.SAXSource; import javax.xml.transform.stream.StreamSource; import org.apache.commons.io.IOUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.xmlgraphics.image.loader.ImageSessionContext; import org.apache.xmlgraphics.image.loader.ImageSource; import org.apache.xmlgraphics.image.loader.util.ImageUtil; import org.apache.xmlgraphics.image.loader.util.SoftMapCache; import org.apache.xmlgraphics.io.XmlSourceUtil; /** * Abstract base class for classes implementing ImageSessionContext. This class provides all the * special treatment for Source creation, i.e. it provides optimized Source objects where possible. */ public abstract class AbstractImageSessionContext implements ImageSessionContext { /** logger */ private static final Log log = LogFactory.getLog(AbstractImageSessionContext.class); private static boolean noSourceReuse; static { //TODO Temporary measure to track down a problem //See: http://markmail.org/message/k6mno3jsxmovaz2e String noSourceReuseString = System.getProperty( AbstractImageSessionContext.class.getName() + ".no-source-reuse"); noSourceReuse = Boolean.valueOf(noSourceReuseString); } private final FallbackResolver fallbackResolver; public AbstractImageSessionContext() { fallbackResolver = new UnrestrictedFallbackResolver(); } /** * @param fallbackResolver the fallback resolution mechanism to be used when simply getting an * {@link InputStream} that backs a {@link Source} isn't possible. */ public AbstractImageSessionContext(FallbackResolver fallbackResolver) { this.fallbackResolver = fallbackResolver; } /** * Attempts to resolve the given URI. * @param uri URI to access * @return A {@link javax.xml.transform.Source} object, or null if the URI * cannot be resolved. */ protected abstract Source resolveURI(String uri); /** {@inheritDoc} */ public Source newSource(String uri) { Source source = resolveURI(uri); if (source instanceof StreamSource || source instanceof SAXSource) { return fallbackResolver.createSource(source, uri); } //Return any non-stream Sources and let the ImageLoaders deal with them return source; } protected static ImageInputStream createImageInputStream(InputStream in) throws IOException { ImageInputStream iin = ImageIO.createImageInputStream(in); return (ImageInputStream) Proxy.newProxyInstance( ImageInputStream.class.getClassLoader(), new Class[] {ImageInputStream.class}, new ObservingImageInputStreamInvocationHandler(iin, in)); } private static class ObservingImageInputStreamInvocationHandler implements InvocationHandler { private ImageInputStream iin; private InputStream in; public ObservingImageInputStreamInvocationHandler(ImageInputStream iin, InputStream underlyingStream) { this.iin = iin; this.in = underlyingStream; } /** {@inheritDoc} */ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { try { if ("close".equals(method.getName())) { try { return method.invoke(iin, args); } finally { IOUtils.closeQuietly(this.in); this.in = null; } } else { return method.invoke(iin, args); } } catch (InvocationTargetException e) { throw e.getCause(); } } } /** * Convert from a URL to a File. *

    * This method will decode the URL. * Syntax such as file:///my%20docs/file.txt will be * correctly decoded to /my docs/file.txt. *

    * Note: this method has been copied over from Apache Commons IO and enhanced to support * UNC paths. * * @param url the file URL to convert, null returns null * @return the equivalent File object, or null * if the URL's protocol is not file * @throws IllegalArgumentException if the file is incorrectly encoded */ public static File toFile(URL url) { if (url == null || !url.getProtocol().equals("file")) { return null; } else { try { String filename = ""; if (url.getHost() != null && url.getHost().length() > 0) { filename += Character.toString(File.separatorChar) + Character.toString(File.separatorChar) + url.getHost(); } filename += url.getFile().replace('/', File.separatorChar); filename = java.net.URLDecoder.decode(filename, "UTF-8"); final File f = new File(filename); if (!f.isFile()) { return null; } return f; } catch (java.io.UnsupportedEncodingException uee) { assert false; return null; } } } private SoftMapCache sessionSources = new SoftMapCache(false); //no need for synchronization /** {@inheritDoc} */ public Source getSource(String uri) { return (Source) sessionSources.remove(uri); } /** {@inheritDoc} */ public Source needSource(String uri) throws FileNotFoundException { Source src = getSource(uri); if (src == null) { if (log.isDebugEnabled()) { log.debug("Creating new Source for " + uri); } src = newSource(uri); if (src == null) { throw new FileNotFoundException("Image not found: " + uri); } } else { if (log.isDebugEnabled()) { log.debug("Reusing Source for " + uri); } } return src; } /** {@inheritDoc} */ public void returnSource(String uri, Source src) { //Safety check to make sure the Preloaders behave ImageInputStream in = ImageUtil.getImageInputStream(src); try { if (in != null && in.getStreamPosition() != 0) { throw new IllegalStateException("ImageInputStream is not reset for: " + uri); } } catch (IOException ioe) { //Ignore exception XmlSourceUtil.closeQuietly(src); } if (isReusable(src)) { //Only return the Source if it's reusable log.debug("Returning Source for " + uri); sessionSources.put(uri, src); } else { //Otherwise, try to close if possible and forget about it XmlSourceUtil.closeQuietly(src); } } /** * Indicates whether a Source is reusable. A Source object is reusable if it's an * {@link ImageSource} (containing an {@link ImageInputStream}) or a {@link DOMSource}. * @param src the Source object * @return true if the Source is reusable */ protected boolean isReusable(Source src) { if (noSourceReuse) { return false; } if (src instanceof ImageSource) { ImageSource is = (ImageSource) src; if (is.getImageInputStream() != null) { return true; } } if (src instanceof DOMSource) { return true; } return false; } /** * Implementations of this interface will be used as the mechanism for creating the * {@link Source} that wraps resources. This interface allows clients to define their own * implementations so that they have fine-grained control over how resources are acquired. */ public interface FallbackResolver { /** * The fallback mechanism used to create the source which takes in both the {@link Source} * that the the regular mechanisms attempted to create and the URI that the user provided. * * @param source the source * @param uri the URI provided by the user * @return the source that the contingency mechanism has been acquired */ Source createSource(Source source, String uri); } /** * An unrestricted resolver that has various contingency mechanisms that access the file-system. * This is most suitable for use via the CLI or in environments where controlling I/O isn't a * priority. */ public static final class UnrestrictedFallbackResolver implements FallbackResolver { /** {@inheritDoc} */ public Source createSource(Source source, String uri) { if (source == null) { if (log.isDebugEnabled()) { log.debug("URI could not be resolved: " + uri); } return null; } ImageSource imageSource = null; String resolvedURI = source.getSystemId(); URL url; try { url = new URL(resolvedURI); } catch (MalformedURLException e) { url = null; } File f = /*FileUtils.*/toFile(url); if (f != null) { boolean directFileAccess = true; assert (source instanceof StreamSource) || (source instanceof SAXSource); InputStream in = XmlSourceUtil.getInputStream(source); if (in == null) { try { in = new java.io.FileInputStream(f); } catch (FileNotFoundException fnfe) { log.error("Error while opening file." + " Could not load image from system identifier '" + source.getSystemId() + "' (" + fnfe.getMessage() + ")"); return null; } } in = ImageUtil.decorateMarkSupported(in); try { if (ImageUtil.isGZIPCompressed(in)) { //GZIPped stream are not seekable, so buffer/cache like other URLs directFileAccess = false; } } catch (IOException ioe) { log.error("Error while checking the InputStream for GZIP compression." + " Could not load image from system identifier '" + source.getSystemId() + "' (" + ioe.getMessage() + ")"); return null; } if (directFileAccess) { //Close as the file is reopened in a more optimal way IOUtils.closeQuietly(in); try { // We let the OS' file system cache do the caching for us // --> lower Java memory consumption, probably no speed loss final ImageInputStream newInputStream = ImageIO .createImageInputStream(f); if (newInputStream == null) { log.error("Unable to create ImageInputStream for local file " + f + " from system identifier '" + source.getSystemId() + "'"); return null; } else { imageSource = new ImageSource(newInputStream, resolvedURI, true); } } catch (IOException ioe) { log.error("Unable to create ImageInputStream for local file" + " from system identifier '" + source.getSystemId() + "' (" + ioe.getMessage() + ")"); } } } if (imageSource == null) { if (XmlSourceUtil.hasReader(source) && !ImageUtil.hasInputStream(source)) { //We don't handle Reader instances here so return the Source unchanged return source; } // Got a valid source, obtain an InputStream from it InputStream in = XmlSourceUtil.getInputStream(source); if (in == null && url != null) { try { in = url.openStream(); } catch (Exception ex) { log.error("Unable to obtain stream from system identifier '" + source.getSystemId() + "'"); } } if (in == null) { log.error("The Source that was returned from URI resolution didn't contain" + " an InputStream for URI: " + uri); return null; } return createImageSource(in, source); } return imageSource; } } private static ImageSource createImageSource(InputStream in, Source source) { try { //Buffer and uncompress if necessary return new ImageSource(createImageInputStream(ImageUtil.autoDecorateInputStream(in)), source.getSystemId(), false); } catch (IOException ioe) { log.error("Unable to create ImageInputStream for InputStream" + " from system identifier '" + source.getSystemId() + "' (" + ioe.getMessage() + ")"); } return null; } /** * This fallback resolver is to be used in environments where controlling file access is of * critical importance. It disallows any contingency mechanisms by which a {@link Source} object * would be created. */ public static final class RestrictedFallbackResolver implements FallbackResolver { /** {@inheritDoc} */ public Source createSource(Source source, String uri) { if (source == null) { if (log.isDebugEnabled()) { log.debug("URI could not be resolved: " + uri); } return null; } if (ImageUtil.hasInputStream(source)) { return createImageSource(XmlSourceUtil.getInputStream(source), source); } throw new UnsupportedOperationException("There are no contingency mechanisms for I/O."); } } } ././@LongLink0100644 0000000 0000000 00000000151 13777276623 011654 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/CompositeImageLoader.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/CompositeImageLoader.0100644 0000000 0000000 00000007576 13777276623 032460 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: CompositeImageLoader.java 1804124 2017-08-04 14:13:54Z ssteiner $ */ package org.apache.xmlgraphics.image.loader.impl; import java.io.IOException; import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.xmlgraphics.image.loader.Image; import org.apache.xmlgraphics.image.loader.ImageException; import org.apache.xmlgraphics.image.loader.ImageFlavor; import org.apache.xmlgraphics.image.loader.ImageInfo; import org.apache.xmlgraphics.image.loader.ImageSessionContext; import org.apache.xmlgraphics.image.loader.spi.ImageLoader; /** * Composite ImageLoader implementation in order to provide fallbacks when one ImageLoader * fails due to some limitation. */ public class CompositeImageLoader extends AbstractImageLoader { /** logger */ protected static final Log log = LogFactory.getLog(CompositeImageLoader.class); private ImageLoader[] loaders; /** * Main constructor. * @param loaders the contained image loaders */ public CompositeImageLoader(ImageLoader[] loaders) { if (loaders == null || loaders.length == 0) { throw new IllegalArgumentException("Must at least pass one ImageLoader as parameter"); } for (int i = 1, c = loaders.length; i < c; i++) { if (!loaders[0].getTargetFlavor().equals(loaders[i].getTargetFlavor())) { throw new IllegalArgumentException( "All ImageLoaders must produce the same target flavor"); } } this.loaders = loaders; } /** {@inheritDoc} */ public ImageFlavor getTargetFlavor() { return loaders[0].getTargetFlavor(); } /** {@inheritDoc} */ public int getUsagePenalty() { int maxPenalty = NO_LOADING_PENALTY; for (int i = 1, c = loaders.length; i < c; i++) { maxPenalty = Math.max(maxPenalty, loaders[i].getUsagePenalty()); } return maxPenalty; } /** {@inheritDoc} */ public Image loadImage(ImageInfo info, Map hints, ImageSessionContext session) throws ImageException, IOException { ImageException firstException = null; for (ImageLoader loader : this.loaders) { try { Image img = loader.loadImage(info, hints, session); if (img != null && firstException != null) { log.debug("First ImageLoader failed (" + firstException.getMessage() + "). Fallback was successful."); } return img; } catch (ImageException ie) { if (firstException == null) { firstException = ie; } } } throw firstException; } /** {@inheritDoc} */ public String toString() { StringBuffer sb = new StringBuffer("["); for (int i = 0; i < this.loaders.length; i++) { if (i > 0) { sb.append(","); } sb.append(this.loaders[i].toString()); } sb.append("]"); return sb.toString(); } } ././@LongLink0100644 0000000 0000000 00000000150 13777276623 011653 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/DefaultImageContext.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/DefaultImageContext.j0100644 0000000 0000000 00000003345 13777276623 032460 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: DefaultImageContext.java 750418 2009-03-05 11:03:54Z vhennebert $ */ package org.apache.xmlgraphics.image.loader.impl; import java.awt.GraphicsEnvironment; import java.awt.Toolkit; import org.apache.xmlgraphics.image.GraphicsConstants; import org.apache.xmlgraphics.image.loader.ImageContext; /** * Very simple ImageContext implementation that uses the Toolkit's screen resolution. */ public class DefaultImageContext implements ImageContext { private final float sourceResolution; /** * Main constructor. */ public DefaultImageContext() { if (GraphicsEnvironment.isHeadless()) { this.sourceResolution = GraphicsConstants.DEFAULT_DPI; } else { this.sourceResolution = Toolkit.getDefaultToolkit() .getScreenResolution(); } } /** {@inheritDoc} */ public float getSourceResolution() { return this.sourceResolution; } } ././@LongLink0100644 0000000 0000000 00000000157 13777276623 011662 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/DefaultImageSessionContext.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/DefaultImageSessionCo0100644 0000000 0000000 00000005434 13777276623 032512 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: DefaultImageSessionContext.java 750418 2009-03-05 11:03:54Z vhennebert $ */ package org.apache.xmlgraphics.image.loader.impl; import java.io.File; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import javax.xml.transform.Source; import javax.xml.transform.stream.StreamSource; import org.apache.xmlgraphics.image.loader.ImageContext; /** * Very simple implementation of the ImageSessionContext interface. It works for absolute URLs * and local filenames only. Consider writing your own implementation of the ImageSessionContext * if you need more sophisticated functionality. */ public class DefaultImageSessionContext extends AbstractImageSessionContext { private ImageContext context; private File baseDir; /** * Main constructor. * @param context the parent image context * @param baseDir the base directory for resolving relative filenames */ public DefaultImageSessionContext(ImageContext context, File baseDir) { this.context = context; this.baseDir = baseDir; } /** {@inheritDoc} */ public ImageContext getParentContext() { return this.context; } /** * Returns the base directory for resolving relative filenames. * @return the base directory */ public File getBaseDir() { return this.baseDir; } /** {@inheritDoc} */ protected Source resolveURI(String uri) { try { URL url = new URL(uri); return new StreamSource(url.openStream(), url.toExternalForm()); } catch (MalformedURLException e) { File f = new File(baseDir, uri); if (f.isFile()) { return new StreamSource(f); } else { return null; } } catch (IOException ioe) { return null; } } /** {@inheritDoc} */ public float getTargetResolution() { return getParentContext().getSourceResolution(); //same as source resolution } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/ImageBuffered.java0100644 0000000 0000000 00000003604 13777276623 031737 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageBuffered.java 798806 2009-07-29 08:11:13Z maxberger $ */ package org.apache.xmlgraphics.image.loader.impl; import java.awt.Color; import java.awt.image.BufferedImage; import org.apache.xmlgraphics.image.loader.ImageFlavor; import org.apache.xmlgraphics.image.loader.ImageInfo; /** * This class is an implementation of the Image interface exposing a BufferedImage. */ public class ImageBuffered extends ImageRendered { /** * Main constructor. * @param info the image info object * @param buffered the BufferedImage instance * @param transparentColor the transparent color or null */ public ImageBuffered(ImageInfo info, BufferedImage buffered, Color transparentColor) { super(info, buffered, transparentColor); } /** {@inheritDoc} */ public ImageFlavor getFlavor() { return ImageFlavor.BUFFERED_IMAGE; } /** * Returns the contained BufferedImage instance. * @return the BufferedImage instance */ public java.awt.image.BufferedImage getBufferedImage() { return (BufferedImage)getRenderedImage(); } } ././@LongLink0100644 0000000 0000000 00000000155 13777276623 011660 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/ImageConverterBitmap2G2D.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/ImageConverterBitmap20100644 0000000 0000000 00000005702 13777276623 032464 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageConverterBitmap2G2D.java 1681108 2015-05-22 13:26:12Z ssteiner $ */ package org.apache.xmlgraphics.image.loader.impl; import java.awt.Dimension; import java.awt.Graphics2D; import java.awt.geom.AffineTransform; import java.awt.geom.Rectangle2D; import java.awt.image.RenderedImage; import java.util.Map; import org.apache.xmlgraphics.image.loader.Image; import org.apache.xmlgraphics.image.loader.ImageFlavor; import org.apache.xmlgraphics.java2d.Graphics2DImagePainter; /** * This ImageConverter wraps a bitmap image in a Graphics2D image. */ public class ImageConverterBitmap2G2D extends AbstractImageConverter { /** {@inheritDoc} */ public Image convert(Image src, Map hints) { checkSourceFlavor(src); assert src instanceof ImageRendered; final ImageRendered rendImage = (ImageRendered)src; Graphics2DImagePainterImpl painter = new Graphics2DImagePainterImpl(rendImage); ImageGraphics2D g2dImage = new ImageGraphics2D(src.getInfo(), painter); return g2dImage; } static class Graphics2DImagePainterImpl implements Graphics2DImagePainter { ImageRendered rendImage; public Graphics2DImagePainterImpl(ImageRendered rendImage) { this.rendImage = rendImage; } public Dimension getImageSize() { return rendImage.getSize().getDimensionMpt(); } public void paint(Graphics2D g2d, Rectangle2D area) { RenderedImage ri = rendImage.getRenderedImage(); double w = area.getWidth(); double h = area.getHeight(); AffineTransform at = new AffineTransform(); at.translate(area.getX(), area.getY()); //Scale image to fit double sx = w / ri.getWidth(); double sy = h / ri.getHeight(); if (sx != 1.0 || sy != 1.0) { at.scale(sx, sy); } g2d.drawRenderedImage(ri, at); } } /** {@inheritDoc} */ public ImageFlavor getSourceFlavor() { return ImageFlavor.RENDERED_IMAGE; } /** {@inheritDoc} */ public ImageFlavor getTargetFlavor() { return ImageFlavor.GRAPHICS2D; } } ././@LongLink0100644 0000000 0000000 00000000164 13777276623 011660 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/ImageConverterBuffered2Rendered.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/ImageConverterBuffere0100644 0000000 0000000 00000003652 13777276623 032546 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageConverterBuffered2Rendered.java 1681108 2015-05-22 13:26:12Z ssteiner $ */ package org.apache.xmlgraphics.image.loader.impl; import java.util.Map; import org.apache.xmlgraphics.image.loader.Image; import org.apache.xmlgraphics.image.loader.ImageFlavor; /** * This ImageConverter converts BufferedImages to RenderedImages (well, it's basically just a * class cast). */ public class ImageConverterBuffered2Rendered extends AbstractImageConverter { /** {@inheritDoc} */ public Image convert(Image src, Map hints) { checkSourceFlavor(src); assert src instanceof ImageBuffered; ImageBuffered buffered = (ImageBuffered)src; return new ImageRendered(buffered.getInfo(), buffered .getRenderedImage(), buffered.getTransparentColor()); } /** {@inheritDoc} */ public ImageFlavor getSourceFlavor() { return ImageFlavor.BUFFERED_IMAGE; } /** {@inheritDoc} */ public ImageFlavor getTargetFlavor() { return ImageFlavor.RENDERED_IMAGE; } /** {@inheritDoc} */ public int getConversionPenalty() { return NO_CONVERSION_PENALTY; } } ././@LongLink0100644 0000000 0000000 00000000155 13777276623 011660 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/ImageConverterG2D2Bitmap.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/ImageConverterG2D2Bit0100644 0000000 0000000 00000020630 13777276623 032260 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageConverterG2D2Bitmap.java 1754511 2016-07-29 13:09:37Z ssteiner $ */ package org.apache.xmlgraphics.image.loader.impl; import java.awt.Color; import java.awt.Graphics2D; import java.awt.Point; import java.awt.RenderingHints; import java.awt.Transparency; import java.awt.color.ColorSpace; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; import java.awt.image.ColorModel; import java.awt.image.ComponentColorModel; import java.awt.image.DataBuffer; import java.awt.image.PixelInterleavedSampleModel; import java.awt.image.Raster; import java.awt.image.WritableRaster; import java.util.Map; import org.apache.xmlgraphics.image.GraphicsConstants; import org.apache.xmlgraphics.image.loader.Image; import org.apache.xmlgraphics.image.loader.ImageFlavor; import org.apache.xmlgraphics.image.loader.ImageProcessingHints; import org.apache.xmlgraphics.image.loader.ImageSize; import org.apache.xmlgraphics.java2d.color.DeviceCMYKColorSpace; import org.apache.xmlgraphics.util.UnitConv; /** * This ImageConverter converts Graphics2D images to a BufferedImage. */ public class ImageConverterG2D2Bitmap extends AbstractImageConverter { /** {@inheritDoc} */ public Image convert(Image src, Map hints) { checkSourceFlavor(src); assert src instanceof ImageGraphics2D; ImageGraphics2D g2dImage = (ImageGraphics2D)src; Object formatIntent = hints.get(ImageProcessingHints.BITMAP_TYPE_INTENT); int bitsPerPixel = 24; if (ImageProcessingHints.BITMAP_TYPE_INTENT_GRAY.equals(formatIntent)) { bitsPerPixel = 8; } else if (ImageProcessingHints.BITMAP_TYPE_INTENT_MONO.equals(formatIntent)) { bitsPerPixel = 1; } Object transparencyIntent = hints.get(ImageProcessingHints.TRANSPARENCY_INTENT); boolean withAlpha = true; if (ImageProcessingHints.TRANSPARENCY_INTENT_IGNORE.equals(transparencyIntent)) { withAlpha = false; } int resolution = GraphicsConstants.DEFAULT_SAMPLE_DPI; Number res = (Number)hints.get(ImageProcessingHints.TARGET_RESOLUTION); if (res != null) { resolution = res.intValue(); } boolean cmyk = Boolean.TRUE.equals(hints.get("CMYK")); BufferedImage bi = paintToBufferedImage(g2dImage, bitsPerPixel, withAlpha, resolution, cmyk); ImageBuffered bufImage = new ImageBuffered(src.getInfo(), bi, null); return bufImage; } /** * Paints a Graphics2D image on a BufferedImage and returns this bitmap. * @param g2dImage the Graphics2D image * @param bitsPerPixel the desired number of bits per pixel (supported: 1, 8, 24) * @param withAlpha true if the generated image should have an alpha channel * @param resolution the requested bitmap resolution * @return the newly created BufferedImage */ protected BufferedImage paintToBufferedImage(ImageGraphics2D g2dImage, int bitsPerPixel, boolean withAlpha, int resolution, boolean cmyk) { ImageSize size = g2dImage.getSize(); RenderingHints additionalHints = null; int bmw = (int)Math.ceil(UnitConv.mpt2px(size.getWidthMpt(), resolution)); int bmh = (int)Math.ceil(UnitConv.mpt2px(size.getHeightMpt(), resolution)); BufferedImage bi; switch (bitsPerPixel) { case 1: bi = new BufferedImage(bmw, bmh, BufferedImage.TYPE_BYTE_BINARY); withAlpha = false; //withAlpha is ignored in this case additionalHints = new RenderingHints(null); //The following usually has no effect but some class libraries might support it additionalHints.put(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE); break; case 8: if (withAlpha) { bi = createGrayBufferedImageWithAlpha(bmw, bmh); } else { bi = new BufferedImage(bmw, bmh, BufferedImage.TYPE_BYTE_GRAY); } break; default: if (withAlpha) { bi = new BufferedImage(bmw, bmh, BufferedImage.TYPE_INT_ARGB); } else { if (cmyk) { ComponentColorModel ccm = new ComponentColorModel( new DeviceCMYKColorSpace(), false, false, 1, DataBuffer.TYPE_BYTE); int[] bands = {0, 1, 2, 3}; PixelInterleavedSampleModel sm = new PixelInterleavedSampleModel( DataBuffer.TYPE_BYTE, bmw, bmh, 4, bmw * 4, bands); WritableRaster raster = WritableRaster.createWritableRaster(sm, new Point(0, 0)); bi = new BufferedImage(ccm, raster, false, null); } else { bi = new BufferedImage(bmw, bmh, BufferedImage.TYPE_INT_RGB); } } } Graphics2D g2d = bi.createGraphics(); try { g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON); setRenderingHintsForBufferedImage(g2d); if (additionalHints != null) { g2d.addRenderingHints(additionalHints); } g2d.setBackground(Color.white); g2d.setColor(Color.black); if (!withAlpha) { g2d.clearRect(0, 0, bmw, bmh); } /* debug code int off = 2; g2d.drawLine(off, 0, off, bmh); g2d.drawLine(bmw - off, 0, bmw - off, bmh); g2d.drawLine(0, off, bmw, off); g2d.drawLine(0, bmh - off, bmw, bmh - off); */ double sx = (double)bmw / size.getWidthMpt(); double sy = (double)bmh / size.getHeightMpt(); g2d.scale(sx, sy); //Paint the image on the BufferedImage Rectangle2D area = new Rectangle2D.Double( 0.0, 0.0, size.getWidthMpt(), size.getHeightMpt()); g2dImage.getGraphics2DImagePainter().paint(g2d, area); } finally { g2d.dispose(); } return bi; } private static BufferedImage createGrayBufferedImageWithAlpha(int width, int height) { BufferedImage bi; boolean alphaPremultiplied = true; int bands = 2; int[] bits = new int[bands]; for (int i = 0; i < bands; i++) { bits[i] = 8; } ColorModel cm = new ComponentColorModel( ColorSpace.getInstance(ColorSpace.CS_GRAY), bits, true, alphaPremultiplied, Transparency.TRANSLUCENT, DataBuffer.TYPE_BYTE); WritableRaster wr = Raster.createInterleavedRaster( DataBuffer.TYPE_BYTE, width, height, bands, new Point(0, 0)); bi = new BufferedImage(cm, wr, alphaPremultiplied, null); return bi; } /** * Sets rendering hints on the Graphics2D created for painting to a BufferedImage. Subclasses * can modify the settings to customize the behaviour. * @param g2d the Graphics2D instance */ protected void setRenderingHintsForBufferedImage(Graphics2D g2d) { g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_OFF); } /** {@inheritDoc} */ public ImageFlavor getSourceFlavor() { return ImageFlavor.GRAPHICS2D; } /** {@inheritDoc} */ public ImageFlavor getTargetFlavor() { return ImageFlavor.BUFFERED_IMAGE; } } ././@LongLink0100644 0000000 0000000 00000000157 13777276623 011662 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/ImageConverterRendered2PNG.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/ImageConverterRendere0100644 0000000 0000000 00000005244 13777276623 032553 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageConverterRendered2PNG.java 1681108 2015-05-22 13:26:12Z ssteiner $ */ package org.apache.xmlgraphics.image.loader.impl; import java.io.IOException; import java.util.Map; import org.apache.commons.io.output.ByteArrayOutputStream; import org.apache.xmlgraphics.image.loader.Image; import org.apache.xmlgraphics.image.loader.ImageException; import org.apache.xmlgraphics.image.loader.ImageFlavor; import org.apache.xmlgraphics.image.writer.ImageWriter; import org.apache.xmlgraphics.image.writer.ImageWriterParams; import org.apache.xmlgraphics.image.writer.ImageWriterRegistry; import org.apache.xmlgraphics.util.MimeConstants; /** * This ImageConverter converts Rendered to PNG images. */ public class ImageConverterRendered2PNG extends AbstractImageConverter { /** {@inheritDoc} */ public Image convert(Image src, Map hints) throws ImageException, IOException { checkSourceFlavor(src); assert src instanceof ImageRendered; ImageRendered rendered = (ImageRendered)src; ImageWriter writer = ImageWriterRegistry.getInstance().getWriterFor(MimeConstants.MIME_PNG); if (writer == null) { throw new ImageException("Cannot convert image to PNG. No suitable ImageWriter found."); } ByteArrayOutputStream baout = new ByteArrayOutputStream(); ImageWriterParams params = new ImageWriterParams(); params.setResolution((int)Math.round(src.getSize().getDpiHorizontal())); writer.writeImage(rendered.getRenderedImage(), baout, params); return new ImageRawStream(src.getInfo(), getTargetFlavor(), new java.io.ByteArrayInputStream(baout.toByteArray())); } /** {@inheritDoc} */ public ImageFlavor getSourceFlavor() { return ImageFlavor.RENDERED_IMAGE; } /** {@inheritDoc} */ public ImageFlavor getTargetFlavor() { return ImageFlavor.RAW_PNG; } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/ImageGraphics2D.java0100644 0000000 0000000 00000004550 13777276623 032144 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageGraphics2D.java 1784728 2017-02-28 11:53:12Z ssteiner $ */ package org.apache.xmlgraphics.image.loader.impl; import org.apache.xmlgraphics.image.loader.Image; import org.apache.xmlgraphics.image.loader.ImageFlavor; import org.apache.xmlgraphics.image.loader.ImageInfo; import org.apache.xmlgraphics.java2d.Graphics2DImagePainter; /** * This class is an implementation of the Image interface exposing a Graphics2DImagePainter. */ public class ImageGraphics2D extends AbstractImage { private Graphics2DImagePainter painter; /** * Main constructor. * @param info the image info object * @param painter the image painter that will paint the Java2D image */ public ImageGraphics2D(ImageInfo info, Graphics2DImagePainter painter) { super(info); setGraphics2DImagePainter(painter); } /** {@inheritDoc} */ public ImageFlavor getFlavor() { return ImageFlavor.GRAPHICS2D; } /** {@inheritDoc} */ public boolean isCacheable() { Image img = getInfo().getOriginalImage(); if (img == null) { return true; } return img.isCacheable(); } /** * Returns the contained Graphics2DImagePainter instance. * @return the image painter */ public Graphics2DImagePainter getGraphics2DImagePainter() { return this.painter; } /** * Sets the Graphics2DImagePainter instance. * @param painter the image painter */ public void setGraphics2DImagePainter(Graphics2DImagePainter painter) { this.painter = painter; } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderEPS.java0100644 0000000 0000000 00000005513 13777276623 031774 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageLoaderEPS.java 1391005 2012-09-27 13:39:57Z mehdi $ */ package org.apache.xmlgraphics.image.loader.impl; import java.io.IOException; import java.io.InputStream; import java.util.Map; import javax.xml.transform.Source; import org.apache.xmlgraphics.image.loader.Image; import org.apache.xmlgraphics.image.loader.ImageException; import org.apache.xmlgraphics.image.loader.ImageFlavor; import org.apache.xmlgraphics.image.loader.ImageInfo; import org.apache.xmlgraphics.image.loader.ImageSessionContext; import org.apache.xmlgraphics.io.XmlSourceUtil; import org.apache.xmlgraphics.util.MimeConstants; import org.apache.xmlgraphics.util.io.SubInputStream; /** * ImageLoader for EPS (Encapsulated PostScript) images. */ public class ImageLoaderEPS extends AbstractImageLoader { /** * Main constructor. */ public ImageLoaderEPS() { } /** {@inheritDoc} */ public ImageFlavor getTargetFlavor() { return ImageFlavor.RAW_EPS; } /** {@inheritDoc} */ public Image loadImage(ImageInfo info, Map hints, ImageSessionContext session) throws ImageException, IOException { if (!MimeConstants.MIME_EPS.equals(info.getMimeType())) { throw new IllegalArgumentException( "ImageInfo must be from a image with MIME type: " + MimeConstants.MIME_EPS); } Source src = session.needSource(info.getOriginalURI()); InputStream in = XmlSourceUtil.needInputStream(src); XmlSourceUtil.removeStreams(src); //so others cannot close them, we take them over PreloaderEPS.EPSBinaryFileHeader binaryHeader; binaryHeader = (PreloaderEPS.EPSBinaryFileHeader)info.getCustomObjects().get( PreloaderEPS.EPS_BINARY_HEADER); if (binaryHeader != null) { //Binary EPS: just extract the EPS part in.skip(binaryHeader.getPSStart()); in = new SubInputStream(in, binaryHeader.getPSLength(), true); } ImageRawEPS epsImage = new ImageRawEPS(info, in); return epsImage; } } ././@LongLink0100644 0000000 0000000 00000000152 13777276623 011655 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderFactoryEPS.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderFactoryEPS0100644 0000000 0000000 00000003765 13777276623 032413 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageLoaderFactoryEPS.java 1681137 2015-05-22 14:54:05Z ssteiner $ */ package org.apache.xmlgraphics.image.loader.impl; import org.apache.xmlgraphics.image.loader.ImageFlavor; import org.apache.xmlgraphics.image.loader.spi.ImageLoader; import org.apache.xmlgraphics.util.MimeConstants; /** * Factory class for the ImageLoader for EPS (Encapsulated PostScript) images. */ public class ImageLoaderFactoryEPS extends AbstractImageLoaderFactory { private static final String[] MIMES = new String[] { MimeConstants.MIME_EPS}; private static final ImageFlavor[] FLAVORS = new ImageFlavor[] { ImageFlavor.RAW_EPS}; /** {@inheritDoc} */ public String[] getSupportedMIMETypes() { return MIMES; } /** {@inheritDoc} */ public ImageFlavor[] getSupportedFlavors(String mime) { if (MimeConstants.MIME_EPS.equals(mime)) { return FLAVORS; } throw new IllegalArgumentException("Unsupported MIME type: " + mime); } /** {@inheritDoc} */ public ImageLoader newImageLoader(ImageFlavor targetFlavor) { return new ImageLoaderEPS(); } /** {@inheritDoc} */ public boolean isAvailable() { return true; } } ././@LongLink0100644 0000000 0000000 00000000163 13777276623 011657 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderFactoryInternalTIFF.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderFactoryInt0100644 0000000 0000000 00000004041 13777276623 032502 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageLoaderFactoryInternalTIFF.java 1681137 2015-05-22 14:54:05Z ssteiner $ */ package org.apache.xmlgraphics.image.loader.impl; import org.apache.xmlgraphics.image.loader.ImageFlavor; import org.apache.xmlgraphics.image.loader.spi.ImageLoader; import org.apache.xmlgraphics.util.MimeConstants; /** * Factory class for the ImageLoader for TIFF (based on Commons' internal TIFF codec). */ public class ImageLoaderFactoryInternalTIFF extends AbstractImageLoaderFactory { private static final String[] MIMES = new String[] { MimeConstants.MIME_TIFF}; private static final ImageFlavor[] FLAVORS = new ImageFlavor[] { ImageFlavor.RENDERED_IMAGE}; /** {@inheritDoc} */ public String[] getSupportedMIMETypes() { return MIMES; } /** {@inheritDoc} */ public ImageFlavor[] getSupportedFlavors(String mime) { if (MimeConstants.MIME_TIFF.equals(mime)) { return FLAVORS; } throw new IllegalArgumentException("Unsupported MIME type: " + mime); } /** {@inheritDoc} */ public ImageLoader newImageLoader(ImageFlavor targetFlavor) { return new ImageLoaderInternalTIFF(); } /** {@inheritDoc} */ public boolean isAvailable() { return true; } } ././@LongLink0100644 0000000 0000000 00000000152 13777276623 011655 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderFactoryPNG.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderFactoryPNG0100644 0000000 0000000 00000003707 13777276623 032404 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageLoaderFactoryPNG.java 1732019 2016-02-24 05:01:10Z gadams $ */ package org.apache.xmlgraphics.image.loader.impl; import org.apache.xmlgraphics.image.loader.ImageFlavor; import org.apache.xmlgraphics.image.loader.spi.ImageLoader; import org.apache.xmlgraphics.util.MimeConstants; public class ImageLoaderFactoryPNG extends AbstractImageLoaderFactory { private static final String[] MIMES = new String[] {MimeConstants.MIME_PNG}; private static final ImageFlavor[] FLAVORS = new ImageFlavor[] {ImageFlavor.RENDERED_IMAGE}; public ImageLoaderFactoryPNG() { // } /** {@inheritDoc} */ public String[] getSupportedMIMETypes() { return MIMES; } /** {@inheritDoc} */ public ImageFlavor[] getSupportedFlavors(String mime) { if (MimeConstants.MIME_PNG.equals(mime)) { return FLAVORS; } throw new IllegalArgumentException("Unsupported MIME type: " + mime); } /** {@inheritDoc} */ public ImageLoader newImageLoader(ImageFlavor targetFlavor) { return new ImageLoaderPNG(); } /** {@inheritDoc} */ public boolean isAvailable() { return true; } } ././@LongLink0100644 0000000 0000000 00000000152 13777276623 011655 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderFactoryRaw.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderFactoryRaw0100644 0000000 0000000 00000006450 13777276623 032507 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageLoaderFactoryRaw.java 1681137 2015-05-22 14:54:05Z ssteiner $ */ package org.apache.xmlgraphics.image.loader.impl; import org.apache.xmlgraphics.image.loader.ImageFlavor; import org.apache.xmlgraphics.image.loader.spi.ImageLoader; import org.apache.xmlgraphics.util.MimeConstants; /** * Factory class for the ImageLoader for raw/undecoded images. */ public class ImageLoaderFactoryRaw extends AbstractImageLoaderFactory { /** MIME type for EMF (Windows Enhanced Metafile) */ public static final String MIME_EMF = "image/x-emf"; private static final String[] MIMES = new String[] { MimeConstants.MIME_PNG, MimeConstants.MIME_JPEG, MimeConstants.MIME_TIFF, MIME_EMF}; private static final ImageFlavor[][] FLAVORS = new ImageFlavor[][] { {ImageFlavor.RAW_PNG}, {ImageFlavor.RAW_JPEG}, {ImageFlavor.RAW_TIFF}, {ImageFlavor.RAW_EMF}}; /** * Returns the MIME type for a given ImageFlavor if it is from a format that is consumed * without being undecoded. If the ImageFlavor is no raw flavor, an IllegalArgumentException * is thrown. * @param flavor the image flavor * @return the associated MIME type */ public static String getMimeForRawFlavor(ImageFlavor flavor) { for (int i = 0, ci = FLAVORS.length; i < ci; i++) { for (int j = 0, cj = FLAVORS[i].length; j < cj; j++) { if (FLAVORS[i][j].equals(flavor)) { return MIMES[i]; } } } throw new IllegalArgumentException("ImageFlavor is not a \"raw\" flavor: " + flavor); } /** {@inheritDoc} */ public String[] getSupportedMIMETypes() { return MIMES; } /** {@inheritDoc} */ public ImageFlavor[] getSupportedFlavors(String mime) { for (int i = 0, c = MIMES.length; i < c; i++) { if (MIMES[i].equals(mime)) { return FLAVORS[i]; } } throw new IllegalArgumentException("Unsupported MIME type: " + mime); } /** {@inheritDoc} */ public ImageLoader newImageLoader(ImageFlavor targetFlavor) { if (targetFlavor.equals(ImageFlavor.RAW_JPEG)) { return new ImageLoaderRawJPEG(); } else if (targetFlavor.equals(ImageFlavor.RAW_PNG)) { return new ImageLoaderRawPNG(); } else { return new ImageLoaderRaw(targetFlavor); } } /** {@inheritDoc} */ public boolean isAvailable() { return true; } } ././@LongLink0100644 0000000 0000000 00000000162 13777276623 011656 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderFactoryRawCCITTFax.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderFactoryRaw0100644 0000000 0000000 00000010505 13777276623 032503 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageLoaderFactoryRawCCITTFax.java 1681137 2015-05-22 14:54:05Z ssteiner $ */ package org.apache.xmlgraphics.image.loader.impl; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.xmlgraphics.image.codec.tiff.TIFFImage; import org.apache.xmlgraphics.image.loader.ImageFlavor; import org.apache.xmlgraphics.image.loader.ImageInfo; import org.apache.xmlgraphics.image.loader.spi.ImageLoader; import org.apache.xmlgraphics.util.MimeConstants; /** * Factory class for the ImageLoader for raw/undecoded CCITT encoded images. */ public class ImageLoaderFactoryRawCCITTFax extends AbstractImageLoaderFactory { /** logger */ private transient Log log = LogFactory.getLog(ImageLoaderFactoryRawCCITTFax.class); private static final String[] MIMES = new String[] { MimeConstants.MIME_TIFF}; private static final ImageFlavor[][] FLAVORS = new ImageFlavor[][] { {ImageFlavor.RAW_CCITTFAX}}; /** * Returns the MIME type for a given ImageFlavor if it is from a format that is consumed * without being undecoded. If the ImageFlavor is no raw flavor, an IllegalArgumentException * is thrown. * @param flavor the image flavor * @return the associated MIME type */ public static String getMimeForRawFlavor(ImageFlavor flavor) { for (int i = 0, ci = FLAVORS.length; i < ci; i++) { for (int j = 0, cj = FLAVORS[i].length; j < cj; j++) { if (FLAVORS[i][j].equals(flavor)) { return MIMES[i]; } } } throw new IllegalArgumentException("ImageFlavor is not a \"raw\" flavor: " + flavor); } /** {@inheritDoc} */ public String[] getSupportedMIMETypes() { return MIMES; } /** {@inheritDoc} */ public ImageFlavor[] getSupportedFlavors(String mime) { for (int i = 0, c = MIMES.length; i < c; i++) { if (MIMES[i].equals(mime)) { return FLAVORS[i]; } } throw new IllegalArgumentException("Unsupported MIME type: " + mime); } /** {@inheritDoc} */ public ImageLoader newImageLoader(ImageFlavor targetFlavor) { if (targetFlavor.equals(ImageFlavor.RAW_CCITTFAX)) { return new ImageLoaderRawCCITTFax(); } else { throw new IllegalArgumentException("Unsupported image flavor: " + targetFlavor); } } /** {@inheritDoc} */ public boolean isAvailable() { return true; } /** {@inheritDoc} */ public boolean isSupported(ImageInfo imageInfo) { Boolean tiled = (Boolean)imageInfo.getCustomObjects().get("TIFF_TILED"); if (Boolean.TRUE.equals(tiled)) { //We don't support tiled images log.trace("Raw CCITT loading not supported for tiled TIFF image"); return false; } Integer compression = (Integer)imageInfo.getCustomObjects().get("TIFF_COMPRESSION"); if (compression == null) { return false; } switch (compression) { case TIFFImage.COMP_FAX_G3_1D: case TIFFImage.COMP_FAX_G3_2D: case TIFFImage.COMP_FAX_G4_2D: Integer stripCount = (Integer)imageInfo.getCustomObjects().get("TIFF_STRIP_COUNT"); boolean supported = (stripCount != null && stripCount == 1); if (!supported) { log.trace("Raw CCITT loading not supported for multi-strip TIFF image"); } return supported; default: return false; } } } ././@LongLink0100644 0000000 0000000 00000000154 13777276623 011657 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderInternalTIFF.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderInternalTI0100644 0000000 0000000 00000006034 13777276623 032435 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageLoaderInternalTIFF.java 1681108 2015-05-22 13:26:12Z ssteiner $ */ package org.apache.xmlgraphics.image.loader.impl; import java.io.IOException; import java.util.Map; import javax.imageio.stream.ImageInputStream; import javax.xml.transform.Source; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.xmlgraphics.image.codec.util.ImageInputStreamSeekableStreamAdapter; import org.apache.xmlgraphics.image.codec.util.SeekableStream; import org.apache.xmlgraphics.image.loader.Image; import org.apache.xmlgraphics.image.loader.ImageException; import org.apache.xmlgraphics.image.loader.ImageFlavor; import org.apache.xmlgraphics.image.loader.ImageInfo; import org.apache.xmlgraphics.image.loader.ImageSessionContext; import org.apache.xmlgraphics.image.loader.util.ImageUtil; /** * An ImageLoader implementation based on Commons' internal TIFF codec. */ public class ImageLoaderInternalTIFF extends AbstractImageLoader { /** logger */ protected static final Log log = LogFactory.getLog(ImageLoaderInternalTIFF.class); /** * Main constructor. */ public ImageLoaderInternalTIFF() { //nop } /** {@inheritDoc} */ public ImageFlavor getTargetFlavor() { return ImageFlavor.RENDERED_IMAGE; } /** {@inheritDoc} */ public Image loadImage(ImageInfo info, Map hints, ImageSessionContext session) throws ImageException, IOException { Source src = session.needSource(info.getOriginalURI()); ImageInputStream imgStream = ImageUtil.needImageInputStream(src); SeekableStream seekStream = new ImageInputStreamSeekableStreamAdapter(imgStream); try { org.apache.xmlgraphics.image.codec.tiff.TIFFImage img = new org.apache.xmlgraphics.image.codec.tiff.TIFFImage( seekStream, null, 0); // TODO: This may ignore ICC Profiles stored in TIFF images. return new ImageRendered(info, img, null); } catch (RuntimeException e) { throw new ImageException("Could not load image with internal TIFF codec", e); } } /** {@inheritDoc} */ public int getUsagePenalty() { return 1000; //Provide this only as a fallback } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderPNG.java0100644 0000000 0000000 00000005652 13777276623 031775 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageLoaderPNG.java 1732019 2016-02-24 05:01:10Z gadams $ */ package org.apache.xmlgraphics.image.loader.impl; import java.awt.image.RenderedImage; import java.io.IOException; import java.util.Map; import javax.imageio.stream.ImageInputStream; import javax.xml.transform.Source; import org.apache.xmlgraphics.image.codec.png.PNGDecodeParam; import org.apache.xmlgraphics.image.codec.png.PNGImageDecoder; import org.apache.xmlgraphics.image.codec.util.ImageInputStreamSeekableStreamAdapter; import org.apache.xmlgraphics.image.codec.util.SeekableStream; import org.apache.xmlgraphics.image.loader.Image; import org.apache.xmlgraphics.image.loader.ImageException; import org.apache.xmlgraphics.image.loader.ImageFlavor; import org.apache.xmlgraphics.image.loader.ImageInfo; import org.apache.xmlgraphics.image.loader.ImageSessionContext; import org.apache.xmlgraphics.image.loader.util.ImageUtil; public class ImageLoaderPNG extends AbstractImageLoader { public ImageLoaderPNG() { // } /** {@inheritDoc} */ public Image loadImage(ImageInfo info, Map hints, ImageSessionContext session) throws ImageException, IOException { Source src = session.needSource(info.getOriginalURI()); ImageInputStream imgStream = ImageUtil.needImageInputStream(src); SeekableStream seekStream = new ImageInputStreamSeekableStreamAdapter(imgStream); PNGImageDecoder decoder = new PNGImageDecoder(seekStream, new PNGDecodeParam()); RenderedImage image = decoder.decodeAsRenderedImage(); // need transparency here? return new ImageRendered(info, image, null); } /** {@inheritDoc} */ public ImageFlavor getTargetFlavor() { return ImageFlavor.RENDERED_IMAGE; } /** {@inheritDoc} */ public int getUsagePenalty() { // since this image loader does not provide any benefits over the default sun.imageio one we add // some penalty to it so that it is not chosen by default; instead users need to give it a negative // penalty in fop.xconf so that it is used; this image loader is mostly for testing purposes for now. return 1000; } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderRaw.java0100644 0000000 0000000 00000004732 13777276623 032100 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageLoaderRaw.java 1391005 2012-09-27 13:39:57Z mehdi $ */ package org.apache.xmlgraphics.image.loader.impl; import java.io.IOException; import java.util.Map; import javax.xml.transform.Source; import org.apache.xmlgraphics.image.loader.Image; import org.apache.xmlgraphics.image.loader.ImageException; import org.apache.xmlgraphics.image.loader.ImageFlavor; import org.apache.xmlgraphics.image.loader.ImageInfo; import org.apache.xmlgraphics.image.loader.ImageSessionContext; import org.apache.xmlgraphics.io.XmlSourceUtil; /** * ImageLoader for formats consumed "raw" (undecoded). Provides a raw/undecoded stream. */ public class ImageLoaderRaw extends AbstractImageLoader { private String mime; private ImageFlavor targetFlavor; /** * Main constructor. * @param targetFlavor the target flavor */ public ImageLoaderRaw(ImageFlavor targetFlavor) { this.targetFlavor = targetFlavor; this.mime = ImageLoaderFactoryRaw.getMimeForRawFlavor(targetFlavor); } /** {@inheritDoc} */ public ImageFlavor getTargetFlavor() { return this.targetFlavor; } /** {@inheritDoc} */ public Image loadImage(ImageInfo info, Map hints, ImageSessionContext session) throws ImageException, IOException { if (!this.mime.equals(info.getMimeType())) { throw new IllegalArgumentException( "ImageInfo must be from a image with MIME type: " + this.mime); } Source src = session.needSource(info.getOriginalURI()); ImageRawStream rawImage = new ImageRawStream(info, getTargetFlavor(), XmlSourceUtil.needInputStream(src)); return rawImage; } } ././@LongLink0100644 0000000 0000000 00000000153 13777276623 011656 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderRawCCITTFax.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderRawCCITTFa0100644 0000000 0000000 00000022144 13777276623 032213 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageLoaderRawCCITTFax.java 1681108 2015-05-22 13:26:12Z ssteiner $ */ package org.apache.xmlgraphics.image.loader.impl; import java.io.FilterInputStream; import java.io.IOException; import java.io.InputStream; import java.util.Map; import javax.imageio.stream.ImageInputStream; import javax.xml.transform.Source; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.xmlgraphics.image.codec.tiff.TIFFDirectory; import org.apache.xmlgraphics.image.codec.tiff.TIFFField; import org.apache.xmlgraphics.image.codec.tiff.TIFFImage; import org.apache.xmlgraphics.image.codec.tiff.TIFFImageDecoder; import org.apache.xmlgraphics.image.codec.util.SeekableStream; import org.apache.xmlgraphics.image.loader.Image; import org.apache.xmlgraphics.image.loader.ImageException; import org.apache.xmlgraphics.image.loader.ImageFlavor; import org.apache.xmlgraphics.image.loader.ImageInfo; import org.apache.xmlgraphics.image.loader.ImageSessionContext; import org.apache.xmlgraphics.image.loader.util.ImageUtil; import org.apache.xmlgraphics.image.loader.util.SeekableStreamAdapter; import org.apache.xmlgraphics.io.XmlSourceUtil; import org.apache.xmlgraphics.util.MimeConstants; import org.apache.xmlgraphics.util.io.SubInputStream; /** * ImageLoader for CCITT group 3 and 4 images consumed "raw" (undecoded). Provides a * raw/undecoded stream. */ public class ImageLoaderRawCCITTFax extends AbstractImageLoader implements JPEGConstants { private static final int COMPRESSION_CCITT_1D = 2; private static final int COMPRESSION_FAX_GROUP3 = 3; private static final int COMPRESSION_FAX_GROUP4 = 4; /** logger */ protected static final Log log = LogFactory.getLog(ImageLoaderRawCCITTFax.class); /** * Main constructor. */ public ImageLoaderRawCCITTFax() { } /** {@inheritDoc} */ public ImageFlavor getTargetFlavor() { return ImageFlavor.RAW_CCITTFAX; } /** {@inheritDoc} */ public Image loadImage(ImageInfo info, Map hints, ImageSessionContext session) throws ImageException, IOException { if (!MimeConstants.MIME_TIFF.equals(info.getMimeType())) { throw new IllegalArgumentException("ImageInfo must be from a image with MIME type: " + MimeConstants.MIME_TIFF); } int fillOrder = 1; int compression = TIFFImage.COMP_NONE; long stripOffset; long stripLength; TIFFDirectory dir; Source src = session.needSource(info.getOriginalURI()); ImageInputStream in = ImageUtil.needImageInputStream(src); in.mark(); try { SeekableStream seekable = new SeekableStreamAdapter(in); dir = new TIFFDirectory(seekable, 0); TIFFField fld; fld = dir.getField(TIFFImageDecoder.TIFF_COMPRESSION); if (fld != null) { compression = fld.getAsInt(0); switch (compression) { case COMPRESSION_CCITT_1D: case COMPRESSION_FAX_GROUP4: break; case COMPRESSION_FAX_GROUP3: //Note: the TIFFImage compression constants seem to be a bit misleading! compression = TIFFImage.COMP_FAX_G3_1D; //1D is the default for Group3 fld = dir.getField(TIFFImageDecoder.TIFF_T4_OPTIONS); if (fld != null) { long t4Options = fld.getAsLong(0); if ((t4Options & 0x01) != 0) { compression = TIFFImage.COMP_FAX_G3_2D; //"Abusing" for 2D signalling } } break; default: log.debug("Unsupported compression " + compression); throw new ImageException( "ImageLoader doesn't support TIFF compression: " + compression); } } //Read information used for raw embedding fld = dir.getField(TIFFImageDecoder.TIFF_FILL_ORDER); if (fld != null) { fillOrder = fld.getAsInt(0); } int stripCount; fld = dir.getField(TIFFImageDecoder.TIFF_ROWS_PER_STRIP); if (fld == null) { stripCount = 1; } else { stripCount = (int)(info.getSize().getHeightPx() / fld.getAsLong(0)); } if (stripCount > 1) { log.debug("More than one strip found in TIFF image."); throw new ImageException( "ImageLoader doesn't support multiple strips"); } stripOffset = dir.getField(TIFFImageDecoder.TIFF_STRIP_OFFSETS).getAsLong(0); stripLength = dir.getField(TIFFImageDecoder.TIFF_STRIP_BYTE_COUNTS).getAsLong(0); } finally { in.reset(); } in.seek(stripOffset); InputStream subin = new SubInputStream(XmlSourceUtil.needInputStream(src), stripLength, true); if (fillOrder == 2) { //Decorate to flip bit order subin = new FillOrderChangeInputStream(subin); } ImageRawCCITTFax rawImage = new ImageRawCCITTFax(info, subin, compression); //Strip stream from source as we pass it on internally XmlSourceUtil.removeStreams(src); return rawImage; } private static class FillOrderChangeInputStream extends FilterInputStream { protected FillOrderChangeInputStream(InputStream in) { super(in); } /** {@inheritDoc} */ @Override public int read(byte[] b, int off, int len) throws IOException { int result = super.read(b, off, len); if (result > 0) { int endpos = off + result; for (int i = off; i < endpos; i++) { b[i] = FLIP_TABLE[b[i] & 0xff]; } } return result; } /** {@inheritDoc} */ @Override public int read() throws IOException { int b = super.read(); if (b < 0) { return b; } else { return FLIP_TABLE[b] & 0xff; } } // Table to be used when fillOrder = 2, for flipping bytes. // Copied from XML Graphics Commons' TIFFFaxDecoder class private static final byte[] FLIP_TABLE = { 0, -128, 64, -64, 32, -96, 96, -32, 16, -112, 80, -48, 48, -80, 112, -16, 8, -120, 72, -56, 40, -88, 104, -24, 24, -104, 88, -40, 56, -72, 120, -8, 4, -124, 68, -60, 36, -92, 100, -28, 20, -108, 84, -44, 52, -76, 116, -12, 12, -116, 76, -52, 44, -84, 108, -20, 28, -100, 92, -36, 60, -68, 124, -4, 2, -126, 66, -62, 34, -94, 98, -30, 18, -110, 82, -46, 50, -78, 114, -14, 10, -118, 74, -54, 42, -86, 106, -22, 26, -102, 90, -38, 58, -70, 122, -6, 6, -122, 70, -58, 38, -90, 102, -26, 22, -106, 86, -42, 54, -74, 118, -10, 14, -114, 78, -50, 46, -82, 110, -18, 30, -98, 94, -34, 62, -66, 126, -2, 1, -127, 65, -63, 33, -95, 97, -31, 17, -111, 81, -47, 49, -79, 113, -15, 9, -119, 73, -55, 41, -87, 105, -23, 25, -103, 89, -39, 57, -71, 121, -7, 5, -123, 69, -59, 37, -91, 101, -27, 21, -107, 85, -43, 53, -75, 117, -11, 13, -115, 77, -51, 45, -83, 109, -19, 29, -99, 93, -35, 61, -67, 125, -3, 3, -125, 67, -61, 35, -93, 99, -29, 19, -109, 83, -45, 51, -77, 115, -13, 11, -117, 75, -53, 43, -85, 107, -21, 27, -101, 91, -37, 59, -69, 123, -5, 7, -121, 71, -57, 39, -89, 103, -25, 23, -105, 87, -41, 55, -73, 119, -9, 15, -113, 79, -49, 47, -81, 111, -17, 31, -97, 95, -33, 63, -65, 127, -1, }; // end } } ././@LongLink0100644 0000000 0000000 00000000147 13777276623 011661 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderRawJPEG.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderRawJPEG.ja0100644 0000000 0000000 00000026302 13777276623 032214 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageLoaderRawJPEG.java 1681108 2015-05-22 13:26:12Z ssteiner $ */ package org.apache.xmlgraphics.image.loader.impl; import java.awt.color.ColorSpace; import java.awt.color.ICC_Profile; import java.io.ByteArrayInputStream; import java.io.DataInputStream; import java.io.IOException; import java.util.Map; import javax.imageio.stream.ImageInputStream; import javax.xml.transform.Source; import org.apache.commons.io.output.ByteArrayOutputStream; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.xmlgraphics.image.loader.Image; import org.apache.xmlgraphics.image.loader.ImageException; import org.apache.xmlgraphics.image.loader.ImageFlavor; import org.apache.xmlgraphics.image.loader.ImageInfo; import org.apache.xmlgraphics.image.loader.ImageSessionContext; import org.apache.xmlgraphics.image.loader.util.ImageUtil; import org.apache.xmlgraphics.io.XmlSourceUtil; import org.apache.xmlgraphics.java2d.color.ColorSpaces; import org.apache.xmlgraphics.java2d.color.profile.ColorProfileUtil; import org.apache.xmlgraphics.util.MimeConstants; /** * ImageLoader for JPEG images consumed "raw" (undecoded). Provides a * raw/undecoded stream. */ public class ImageLoaderRawJPEG extends AbstractImageLoader implements JPEGConstants { /** logger */ protected static final Log log = LogFactory.getLog(ImageLoaderRawJPEG.class); /** * Main constructor. */ public ImageLoaderRawJPEG() { } /** {@inheritDoc} */ public ImageFlavor getTargetFlavor() { return ImageFlavor.RAW_JPEG; } /** {@inheritDoc} */ public Image loadImage(ImageInfo info, Map hints, ImageSessionContext session) throws ImageException, IOException { if (!MimeConstants.MIME_JPEG.equals(info.getMimeType())) { throw new IllegalArgumentException("ImageInfo must be from a image with MIME type: " + MimeConstants.MIME_JPEG); } ColorSpace colorSpace = null; boolean appeFound = false; int sofType = 0; ByteArrayOutputStream iccStream = null; Source src = session.needSource(info.getOriginalURI()); ImageInputStream in = ImageUtil.needImageInputStream(src); JPEGFile jpeg = new JPEGFile(in); in.mark(); try { outer: while (true) { int reclen; int segID = jpeg.readMarkerSegment(); if (log.isTraceEnabled()) { log.trace("Seg Marker: " + Integer.toHexString(segID)); } switch (segID) { case EOI: log.trace("EOI found. Stopping."); break outer; case SOS: log.trace("SOS found. Stopping early."); //TODO Not sure if this is safe break outer; case SOI: case NULL: break; case SOF0: //baseline case SOF1: //extended sequential DCT case SOF2: //progressive (since PDF 1.3) case SOFA: //progressive (since PDF 1.3) sofType = segID; if (log.isTraceEnabled()) { log.trace("SOF: " + Integer.toHexString(sofType)); } in.mark(); try { reclen = jpeg.readSegmentLength(); in.skipBytes(1); //data precision in.skipBytes(2); //height in.skipBytes(2); //width int numComponents = in.readUnsignedByte(); if (numComponents == 1) { colorSpace = ColorSpace.getInstance( ColorSpace.CS_GRAY); } else if (numComponents == 3) { colorSpace = ColorSpace.getInstance( ColorSpace.CS_LINEAR_RGB); } else if (numComponents == 4) { colorSpace = ColorSpaces.getDeviceCMYKColorSpace(); } else { throw new ImageException("Unsupported ColorSpace for image " + info + ". The number of components supported are 1, 3 and 4."); } } finally { in.reset(); } in.skipBytes(reclen); break; case APP2: //ICC (see ICC1V42.pdf) in.mark(); try { reclen = jpeg.readSegmentLength(); // Check for ICC profile byte[] iccString = new byte[11]; in.readFully(iccString); in.skipBytes(1); //string terminator (null byte) if ("ICC_PROFILE".equals(new String(iccString, "US-ASCII"))) { in.skipBytes(2); //chunk sequence number and total number of chunks int payloadSize = reclen - 2 - 12 - 2; if (ignoreColorProfile(hints)) { log.debug("Ignoring ICC profile data in JPEG"); in.skipBytes(payloadSize); } else { byte[] buf = new byte[payloadSize]; in.readFully(buf); if (iccStream == null) { if (log.isDebugEnabled()) { log.debug("JPEG has an ICC profile"); DataInputStream din = new DataInputStream(new ByteArrayInputStream(buf)); log.debug("Declared ICC profile size: " + din.readInt()); } //ICC profiles can be split into several chunks //so collect in a byte array output stream iccStream = new ByteArrayOutputStream(); } iccStream.write(buf); } } } finally { in.reset(); } in.skipBytes(reclen); break; case APPE: //Adobe-specific (see 5116.DCT_Filter.pdf) in.mark(); try { reclen = jpeg.readSegmentLength(); // Check for Adobe header byte[] adobeHeader = new byte[5]; in.readFully(adobeHeader); if ("Adobe".equals(new String(adobeHeader, "US-ASCII"))) { // The reason for reading the APPE marker is that Adobe Photoshop // generates CMYK JPEGs with inverted values. The correct thing // to do would be to interpret the values in the marker, but for now // only assume that if APPE marker is present and colorspace is CMYK, // the image is inverted. appeFound = true; } } finally { in.reset(); } in.skipBytes(reclen); break; default: jpeg.skipCurrentMarkerSegment(); } } } finally { in.reset(); } ICC_Profile iccProfile = buildICCProfile(info, colorSpace, iccStream); if (iccProfile == null && colorSpace == null) { throw new ImageException("ColorSpace could not be identified for JPEG image " + info); } boolean invertImage = false; if (appeFound && colorSpace.getType() == ColorSpace.TYPE_CMYK) { if (log.isDebugEnabled()) { log.debug("JPEG has an Adobe APPE marker. Note: CMYK Image will be inverted. (" + info.getOriginalURI() + ")"); } invertImage = true; } ImageRawJPEG rawImage = new ImageRawJPEG(info, XmlSourceUtil.needInputStream(src), sofType, colorSpace, iccProfile, invertImage); return rawImage; } private ICC_Profile buildICCProfile(ImageInfo info, ColorSpace colorSpace, ByteArrayOutputStream iccStream) throws IOException, ImageException { if (iccStream != null && iccStream.size() > 0) { if (log.isDebugEnabled()) { log.debug("Effective ICC profile size: " + iccStream.size()); } final int alignment = 4; int padding = (alignment - (iccStream.size() % alignment)) % alignment; if (padding != 0) { try { iccStream.write(new byte[padding]); } catch (IOException ioe) { throw new IOException("Error while aligning ICC stream: " + ioe.getMessage()); } } ICC_Profile iccProfile = null; try { iccProfile = ColorProfileUtil.getICC_Profile(iccStream.toByteArray()); if (log.isDebugEnabled()) { log.debug("JPEG has an ICC profile: " + iccProfile.toString()); } } catch (IllegalArgumentException iae) { log.warn("An ICC profile is present in the JPEG file but it is invalid (" + iae.getMessage() + "). The color profile will be ignored. (" + info.getOriginalURI() + ")"); return null; } if (iccProfile.getNumComponents() != colorSpace.getNumComponents()) { log.warn("The number of components of the ICC profile (" + iccProfile.getNumComponents() + ") doesn't match the image (" + colorSpace.getNumComponents() + "). Ignoring the ICC color profile."); return null; } else { return iccProfile; } } else { return null; //no ICC profile available } } } ././@LongLink0100644 0000000 0000000 00000000146 13777276623 011660 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderRawPNG.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderRawPNG.jav0100644 0000000 0000000 00000006403 13777276623 032301 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageLoaderRawPNG.java 1843559 2018-10-11 14:59:17Z ssteiner $ */ // Original author: Matthias Reichenbacher package org.apache.xmlgraphics.image.loader.impl; import java.io.IOException; import java.util.Map; import javax.imageio.stream.ImageInputStream; import javax.xml.transform.Source; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.xmlgraphics.image.codec.util.ImageInputStreamSeekableStreamAdapter; import org.apache.xmlgraphics.image.codec.util.SeekableStream; import org.apache.xmlgraphics.image.loader.Image; import org.apache.xmlgraphics.image.loader.ImageException; import org.apache.xmlgraphics.image.loader.ImageFlavor; import org.apache.xmlgraphics.image.loader.ImageInfo; import org.apache.xmlgraphics.image.loader.ImageSessionContext; import org.apache.xmlgraphics.image.loader.util.ImageUtil; import org.apache.xmlgraphics.io.XmlSourceUtil; import org.apache.xmlgraphics.util.MimeConstants; public class ImageLoaderRawPNG extends AbstractImageLoader { /** logger */ protected static final Log log = LogFactory.getLog(ImageLoaderRawPNG.class); /** * Main constructor. */ public ImageLoaderRawPNG() { } /** {@inheritDoc} */ public ImageFlavor getTargetFlavor() { return ImageFlavor.RAW_PNG; } /** {@inheritDoc} */ public Image loadImage(ImageInfo info, Map hints, ImageSessionContext session) throws ImageException, IOException { if (!MimeConstants.MIME_PNG.equals(info.getMimeType())) { throw new IllegalArgumentException("ImageInfo must be from a image with MIME type: " + MimeConstants.MIME_PNG); } Source src = session.needSource(info.getOriginalURI()); ImageInputStream in = ImageUtil.needImageInputStream(src); // Remove streams as we do things with them at some later time. XmlSourceUtil.removeStreams(src); SeekableStream seekStream = new ImageInputStreamSeekableStreamAdapter(in); PNGFile im = new PNGFile(seekStream, info.getOriginalURI()); ImageRawPNG irpng = im.getImageRawPNG(info); return irpng; } /** {@inheritDoc} */ public int getUsagePenalty() { // since this image loader does not handle all kinds of PNG images then we add some penalty to it // so that it is not chosen by default; instead, users need to give it a negative penalty in // fop.xconf so that it is used return 1000; } } ././@LongLink0100644 0000000 0000000 00000000145 13777276623 011657 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/ImageRawCCITTFax.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/ImageRawCCITTFax.java0100644 0000000 0000000 00000004074 13777276623 032176 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageRawCCITTFax.java 750418 2009-03-05 11:03:54Z vhennebert $ */ package org.apache.xmlgraphics.image.loader.impl; import java.awt.color.ColorSpace; import org.apache.xmlgraphics.image.loader.ImageFlavor; import org.apache.xmlgraphics.image.loader.ImageInfo; /** * This class is an implementation of the Image interface exposing a 1-bit bitmap image stream * that can be decoded by the PostScript or PDF CCITTFaxDecode filter. */ public class ImageRawCCITTFax extends ImageRawStream { private int compression; /** * Main constructor. * @param info the image info object * @param in the ImageInputStream with the raw content * @param compression the integer value of the TIFF compression scheme */ public ImageRawCCITTFax(ImageInfo info, java.io.InputStream in, int compression) { super(info, ImageFlavor.RAW_CCITTFAX, in); this.compression = compression; } /** * Returns the image's color space * @return the color space */ public ColorSpace getColorSpace() { return ColorSpace.getInstance(ColorSpace.CS_GRAY); } /** * Returns the TIFF compression scheme. * @return the TIFF compression scheme */ public int getCompression() { return this.compression; } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/ImageRawEPS.java0100644 0000000 0000000 00000004206 13777276623 031315 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageRawEPS.java 722804 2008-12-03 08:06:44Z jeremias $ */ package org.apache.xmlgraphics.image.loader.impl; import java.awt.geom.Rectangle2D; import java.io.InputStream; import org.apache.xmlgraphics.image.loader.ImageFlavor; import org.apache.xmlgraphics.image.loader.ImageInfo; /** * This class is an implementation of the Image interface exposing EPS file. It provides an * InputStream to access the EPS content and the decoded high-res bounding box. */ public class ImageRawEPS extends ImageRawStream { /** * Main constructor. * @param info the image info object * @param streamFactory the InputStreamFactory that is used to create InputStream instances */ public ImageRawEPS(ImageInfo info, InputStreamFactory streamFactory) { super(info, ImageFlavor.RAW_EPS, streamFactory); } /** * Main constructor. * @param info the image info object * @param in the InputStream with the raw content */ public ImageRawEPS(ImageInfo info, InputStream in) { super(info, ImageFlavor.RAW_EPS, in); } /** * Returns the bounding box of the EPS image. * @return the bounding box */ public Rectangle2D getBoundingBox() { Rectangle2D bbox = (Rectangle2D)getInfo().getCustomObjects().get( PreloaderEPS.EPS_BOUNDING_BOX); return bbox; } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/ImageRawJPEG.java0100644 0000000 0000000 00000005777 13777276623 031431 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageRawJPEG.java 1610846 2014-07-15 20:44:18Z vhennebert $ */ package org.apache.xmlgraphics.image.loader.impl; import java.awt.color.ColorSpace; import java.awt.color.ICC_Profile; import org.apache.xmlgraphics.image.loader.ImageFlavor; import org.apache.xmlgraphics.image.loader.ImageInfo; /** * This class is an implementation of the Image interface exposing a JPEG file. It provides an * InputStream to access the JPEG content and some additional information on the image. */ public class ImageRawJPEG extends ImageRawStream { private int sofType; private ColorSpace colorSpace; private ICC_Profile iccProfile; private boolean invertImage; /** * Main constructor. * @param info the image info object * @param in the ImageInputStream with the raw content * @param sofType the SOFn identifier * @param colorSpace the color space * @param iccProfile an ICC color profile or null if no profile is associated * @param invertImage true if the image should be inverted when painting it */ public ImageRawJPEG(ImageInfo info, java.io.InputStream in, int sofType, ColorSpace colorSpace, ICC_Profile iccProfile, boolean invertImage) { super(info, ImageFlavor.RAW_JPEG, in); this.sofType = sofType; this.colorSpace = colorSpace; this.iccProfile = iccProfile; this.invertImage = invertImage; } /** * Returns the SOFn identifier of the image which describes the coding format of the image. * @return the SOFn identifier */ public int getSOFType() { return this.sofType; } /** * Returns the ICC color profile if one is associated with the JPEG image. * @return the ICC color profile or null if there's no profile */ public ICC_Profile getICCProfile() { return this.iccProfile; } /** * Indicates whether the image should be inverted when interpreting it. * @return true if the image is to be inverted */ public boolean isInverted() { return this.invertImage; } /** * Returns the image's color space * @return the color space */ public ColorSpace getColorSpace() { return this.colorSpace; } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/ImageRawPNG.java0100644 0000000 0000000 00000011660 13777276623 031314 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageRawPNG.java 1732019 2016-02-24 05:01:10Z gadams $ */ // Original author: Matthias Reichenbacher package org.apache.xmlgraphics.image.loader.impl; import java.awt.Color; import java.awt.color.ColorSpace; import java.awt.color.ICC_Profile; import java.awt.image.ColorModel; import java.io.InputStream; import org.apache.xmlgraphics.image.loader.ImageFlavor; import org.apache.xmlgraphics.image.loader.ImageInfo; public class ImageRawPNG extends ImageRawStream { private ColorModel cm; private ICC_Profile iccProfile; private int bitDepth; private boolean isTransparent; private int grayTransparentAlpha; private int redTransparentAlpha; private int greenTransparentAlpha; private int blueTransparentAlpha; private int renderingIntent = -1; /** * Main constructor. * @param info the image info object * @param in the ImageInputStream with the raw content * @param colorModel the color model * @param bitDepth the bit depth * @param iccProfile an ICC color profile or null if no profile is associated */ public ImageRawPNG(ImageInfo info, InputStream in, ColorModel colorModel, int bitDepth, ICC_Profile iccProfile) { super(info, ImageFlavor.RAW_PNG, in); this.iccProfile = iccProfile; this.cm = colorModel; this.bitDepth = bitDepth; } /** * The bit depth of each color channel. * @return the bit depth of one channel (same for all) */ public int getBitDepth() { return bitDepth; } /** * Returns the ICC color profile if one is associated with the PNG image. * @return the ICC color profile or null if there's no profile */ public ICC_Profile getICCProfile() { return this.iccProfile; } /** * Returns the image's color model. * @return the color model */ public ColorModel getColorModel() { return this.cm; } /** * Returns the image's color space. * @return the color space */ public ColorSpace getColorSpace() { return this.cm.getColorSpace(); } /** * Sets the gray transparent pixel value. * @param gray the transparent pixel gray value (0...255) */ protected void setGrayTransparentAlpha(int gray) { this.isTransparent = true; this.grayTransparentAlpha = gray; } /** * Sets the RGB transparent pixel values. * @param red the transparent pixel red value (0...255) * @param green the transparent pixel green value (0...255) * @param blue the transparent pixel blue value (0...255) */ protected void setRGBTransparentAlpha(int red, int green, int blue) { this.isTransparent = true; this.redTransparentAlpha = red; this.greenTransparentAlpha = green; this.blueTransparentAlpha = blue; } /** * Used to flag image as transparent when the image is of pallete type. */ protected void setTransparent() { this.isTransparent = true; } /** * Whether the image is transparent (meaning there is a transparent pixel) * @return true if transparent pixel exists */ public boolean isTransparent() { return this.isTransparent; } /** * The color of the transparent pixel. * @return the color of the transparent pixel. */ public Color getTransparentColor() { Color color = null; if (!this.isTransparent) { return color; } if (cm.getNumColorComponents() == 3) { color = new Color(this.redTransparentAlpha, this.greenTransparentAlpha, this.blueTransparentAlpha); } else { color = new Color(this.grayTransparentAlpha, 0, 0); } return color; } /** * Used to set the rendering intent when the color space is sRGB. * @param intent the rendering intent of the sRGB color space */ public void setRenderingIntent(int intent) { renderingIntent = intent; } /** * Returns the rendering intent of the sRGB color space. * @return the rendering intent */ public int getRenderingIntent() { return this.renderingIntent; } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/ImageRawStream.java0100644 0000000 0000000 00000014244 13777276623 032124 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageRawStream.java 1681137 2015-05-22 14:54:05Z ssteiner $ */ package org.apache.xmlgraphics.image.loader.impl; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.apache.commons.io.IOUtils; import org.apache.xmlgraphics.image.loader.ImageFlavor; import org.apache.xmlgraphics.image.loader.ImageInfo; import org.apache.xmlgraphics.image.loader.MimeEnabledImageFlavor; /** * This class is an implementation of the Image interface exposing an InputStream for loading the * raw/undecoded image. */ public class ImageRawStream extends AbstractImage { private ImageFlavor flavor; private InputStreamFactory streamFactory; /** * Main constructor. * @param info the image info object * @param flavor the image flavor for the raw image * @param streamFactory the InputStreamFactory that is used to create InputStream instances */ public ImageRawStream(ImageInfo info, ImageFlavor flavor, InputStreamFactory streamFactory) { super(info); this.flavor = flavor; setInputStreamFactory(streamFactory); } /** * Constructor for a simple InputStream as parameter. * @param info the image info object * @param flavor the image flavor for the raw image * @param in the InputStream with the raw content */ public ImageRawStream(ImageInfo info, ImageFlavor flavor, InputStream in) { this(info, flavor, new SingleStreamFactory(in)); } /** {@inheritDoc} */ public ImageFlavor getFlavor() { return this.flavor; } /** * Returns the MIME type of the stream data. * @return the MIME type */ public String getMimeType() { if (getFlavor() instanceof MimeEnabledImageFlavor) { return getFlavor().getMimeType(); } else { //Undetermined return "application/octet-stream"; } } /** {@inheritDoc} */ public boolean isCacheable() { return !this.streamFactory.isUsedOnceOnly(); } /** * Sets the InputStreamFactory to be used by this image. This method allows to replace the * original factory. * @param factory the new InputStreamFactory */ public void setInputStreamFactory(InputStreamFactory factory) { if (this.streamFactory != null) { this.streamFactory.close(); } this.streamFactory = factory; } /** * Returns a new InputStream to access the raw image. * @return the InputStream */ public InputStream createInputStream() { return this.streamFactory.createInputStream(); } /** * Writes the content of the image to an OutputStream. The OutputStream in NOT closed at the * end. * @param out the OutputStream * @throws IOException if an I/O error occurs */ public void writeTo(OutputStream out) throws IOException { InputStream in = createInputStream(); try { IOUtils.copy(in, out); } finally { IOUtils.closeQuietly(in); } } /** * Represents a factory for InputStream objects. Make sure the class is thread-safe! */ public interface InputStreamFactory { /** * Indicates whether this factory is only usable once or many times. * @return true if the factory can only be used once */ boolean isUsedOnceOnly(); /** * Creates and returns a new InputStream. * @return the new InputStream */ InputStream createInputStream(); /** * Closes the factory and releases any resources held open during the lifetime of this * object. */ void close(); } /** * InputStream factory that can return a pre-constructed InputStream exactly once. */ private static class SingleStreamFactory implements InputStreamFactory { private InputStream in; public SingleStreamFactory(InputStream in) { this.in = in; } public synchronized InputStream createInputStream() { if (this.in != null) { InputStream tempin = this.in; this.in = null; //Don't close, just remove the reference return tempin; } else { throw new IllegalStateException("Can only create an InputStream once!"); } } public synchronized void close() { IOUtils.closeQuietly(this.in); this.in = null; } public boolean isUsedOnceOnly() { return true; } /** {@inheritDoc} */ protected void finalize() { close(); } } /** * InputStream factory that wraps a byte array. */ public static class ByteArrayStreamFactory implements InputStreamFactory { private byte[] data; /** * Main constructor. * @param data the byte array */ public ByteArrayStreamFactory(byte[] data) { this.data = data; } /** {@inheritDoc} */ public InputStream createInputStream() { return new ByteArrayInputStream(data); } /** {@inheritDoc} */ public void close() { //nop } /** {@inheritDoc} */ public boolean isUsedOnceOnly() { return false; } } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/ImageRendered.java0100644 0000000 0000000 00000005653 13777276623 031753 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageRendered.java 995366 2010-09-09 10:02:17Z jeremias $ */ package org.apache.xmlgraphics.image.loader.impl; import java.awt.Color; import java.awt.color.ColorSpace; import java.awt.color.ICC_ColorSpace; import java.awt.color.ICC_Profile; import java.awt.image.RenderedImage; import org.apache.xmlgraphics.image.loader.ImageFlavor; import org.apache.xmlgraphics.image.loader.ImageInfo; /** * This class is an implementation of the Image interface exposing a RenderedImage. */ public class ImageRendered extends AbstractImage { private final RenderedImage red; private final Color transparentColor; private final ColorSpace colorSpace; private final ICC_Profile iccProfile; /** * Main constructor. * @param info the image info object * @param red the RenderedImage instance * @param transparentColor the transparent color or null */ public ImageRendered(ImageInfo info, RenderedImage red, Color transparentColor) { super(info); this.red = red; this.transparentColor = transparentColor; this.colorSpace = red.getColorModel().getColorSpace(); if (this.colorSpace instanceof ICC_ColorSpace) { ICC_ColorSpace icccs = (ICC_ColorSpace) this.colorSpace; this.iccProfile = icccs.getProfile(); } else { this.iccProfile = null; } } /** {@inheritDoc} */ public ImageFlavor getFlavor() { return ImageFlavor.RENDERED_IMAGE; } /** {@inheritDoc} */ public boolean isCacheable() { return true; } /** * Returns the contained RenderedImage instance. * @return the RenderedImage instance */ public RenderedImage getRenderedImage() { return this.red; } /** {@inheritDoc} */ public ColorSpace getColorSpace() { return this.colorSpace; } /** {@inheritDoc} */ public ICC_Profile getICCProfile() { return this.iccProfile; } /** * Returns the transparent color if available. * @return the transparent color or null */ public Color getTransparentColor() { return this.transparentColor; } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/ImageXMLDOM.java0100644 0000000 0000000 00000005313 13777276623 031214 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageXMLDOM.java 682720 2008-08-05 14:22:29Z jeremias $ */ package org.apache.xmlgraphics.image.loader.impl; import org.w3c.dom.Document; import org.apache.xmlgraphics.image.loader.ImageFlavor; import org.apache.xmlgraphics.image.loader.ImageInfo; import org.apache.xmlgraphics.image.loader.XMLNamespaceEnabledImageFlavor; /** * This class is an implementation of the Image interface exposing an XML DOM (W3C). */ public class ImageXMLDOM extends AbstractImage { private ImageFlavor flavor; private Document doc; private String rootNamespace; /** * Main constructor. * @param info the image info object * @param doc the W3C DOM document * @param rootNamespace the root XML namespace of the XML document in the DOM */ public ImageXMLDOM(ImageInfo info, Document doc, String rootNamespace) { super(info); this.doc = doc; this.rootNamespace = rootNamespace; this.flavor = new XMLNamespaceEnabledImageFlavor(ImageFlavor.XML_DOM, rootNamespace); } /** * Main constructor. * @param info the image info object * @param doc the W3C DOM document * @param flavor the image flavor */ public ImageXMLDOM(ImageInfo info, Document doc, XMLNamespaceEnabledImageFlavor flavor) { super(info); this.doc = doc; this.rootNamespace = flavor.getNamespace(); this.flavor = flavor; } /** {@inheritDoc} */ public ImageFlavor getFlavor() { return this.flavor; } /** {@inheritDoc} */ public boolean isCacheable() { return true; } /** * Returns the contained W3C DOM document. * @return the DOM */ public Document getDocument() { return this.doc; } /** * Returns the root XML namespace of the XML document. * @return the root namespace */ public String getRootNamespace() { return this.rootNamespace; } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/JPEGConstants.java0100644 0000000 0000000 00000004343 13777276623 031675 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: JPEGConstants.java 750418 2009-03-05 11:03:54Z vhennebert $ */ package org.apache.xmlgraphics.image.loader.impl; /** * Constants for JPEG images */ public interface JPEGConstants { /* * Only SOFn and APPn markers are defined as SOFn is needed for the height * and width search. APPn is also defined because if the JPEG contains * thumbnails the dimensions of the thumbnail would also be after the SOFn * marker enclosed inside the APPn marker. And we don't want to confuse * those dimensions with the image dimensions. */ /** Beginning of a Marker */ int MARK = 0xff; /** Special case for 0xff00 */ int NULL = 0x00; /** Baseline DCT */ int SOF0 = 0xc0; /** Extended Sequential DCT */ int SOF1 = 0xc1; /** Progressive DCT only PDF 1.3 */ int SOF2 = 0xc2; /** Progressive DCT only PDF 1.3 */ int SOFA = 0xca; /** Application marker, JFIF, JFXX, CIFF */ int APP0 = 0xe0; /** Application marker, EXIF, XMP */ int APP1 = 0xe1; /** Application marker, ICC, FlashPix */ int APP2 = 0xe2; /** Application marker APPD/APP13, Photoshop, Adobe_CM */ int APPD = 0xed; /** Application marker APPE/APP14, Adobe */ int APPE = 0xee; /** Application marker APPF/APP15, GraphicConverter */ int APPF = 0xef; /** Start of Scan */ int SOS = 0xda; /** start of Image */ int SOI = 0xd8; /** end of Image */ int EOI = 0xd9; } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/JPEGFile.java0100644 0000000 0000000 00000006512 13777276623 030600 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: JPEGFile.java 1681108 2015-05-22 13:26:12Z ssteiner $ */ package org.apache.xmlgraphics.image.loader.impl; import java.io.DataInput; import java.io.IOException; import java.io.InputStream; import javax.imageio.stream.ImageInputStream; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * Provides methods useful for processing JPEG files. */ public class JPEGFile implements JPEGConstants { /** logger */ protected static final Log log = LogFactory.getLog(JPEGFile.class); private DataInput in; /** * Constructor for ImageInputStreams. * @param in the input stream to read the image from */ public JPEGFile(ImageInputStream in) { this.in = in; } /** * Constructor for InputStreams. * @param in the input stream to read the image from */ public JPEGFile(InputStream in) { this.in = new java.io.DataInputStream(in); } /** * Returns the {@link DataInput} instance this object operates on. * @return the data input instance */ public DataInput getDataInput() { return this.in; } /** * Reads the next marker segment identifier and returns it. * @return the marker segment identifier * @throws IOException if an I/O error occurs while reading from the image file */ public int readMarkerSegment() throws IOException { int marker; do { marker = in.readByte() & 0xFF; //Skip any non-0xFF bytes (useful for JPEG files with bad record lengths) } while (marker != MARK); int segID; do { segID = in.readByte() & 0xFF; //Skip any pad bytes (0xFF) which are legal here. } while (segID == 0xFF); return segID; } /** * Reads the segment length of the current marker segment and returns it. * The method assumes the file cursor is right after the segment header. * @return the segment length * @throws IOException if an I/O error occurs while reading from the image file */ public int readSegmentLength() throws IOException { int reclen = in.readUnsignedShort(); return reclen; } /** * Skips the current marker segment. * The method assumes the file cursor is right after the segment header. * @throws IOException if an I/O error occurs while reading from the image file */ public void skipCurrentMarkerSegment() throws IOException { int reclen = readSegmentLength(); in.skipBytes(reclen - 2); } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/PNGConstants.java0100644 0000000 0000000 00000002626 13777276623 031576 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: PNGConstants.java 1732019 2016-02-24 05:01:10Z gadams $ */ package org.apache.xmlgraphics.image.loader.impl; public interface PNGConstants { /* * First 8 bytes of any PNG file. */ long PNG_SIGNATURE = 0x89504e470d0a1a0aL; /* * Color types. */ int PNG_COLOR_GRAY = 0; int PNG_COLOR_RGB = 2; int PNG_COLOR_PALETTE = 3; int PNG_COLOR_GRAY_ALPHA = 4; int PNG_COLOR_RGB_ALPHA = 6; /* * Filter types. */ int PNG_FILTER_NONE = 0; int PNG_FILTER_SUB = 1; int PNG_FILTER_UP = 2; int PNG_FILTER_AVERAGE = 3; int PNG_FILTER_PAETH = 4; } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/PNGFile.java0100644 0000000 0000000 00000027125 13777276623 030502 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: PNGFile.java 1843559 2018-10-11 14:59:17Z ssteiner $ */ package org.apache.xmlgraphics.image.loader.impl; import java.awt.color.ColorSpace; import java.awt.color.ICC_ColorSpace; import java.awt.color.ICC_Profile; import java.awt.image.ColorModel; import java.awt.image.ComponentColorModel; import java.awt.image.DataBuffer; import java.awt.image.IndexColorModel; import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; import java.io.DataInputStream; import java.io.IOException; import java.io.InputStream; import java.io.SequenceInputStream; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.zip.Inflater; import java.util.zip.InflaterInputStream; import org.apache.xmlgraphics.image.codec.png.PNGChunk; import org.apache.xmlgraphics.image.codec.util.PropertyUtil; import org.apache.xmlgraphics.image.loader.ImageException; import org.apache.xmlgraphics.image.loader.ImageInfo; // CSOFF: MethodName /** * Provides methods useful for processing PNG files. */ class PNGFile implements PNGConstants { private ColorModel colorModel; private ICC_Profile iccProfile; private int sRGBRenderingIntent = -1; private int bitDepth; private int colorType; private boolean isTransparent; private int grayTransparentAlpha; private int redTransparentAlpha; private int greenTransparentAlpha; private int blueTransparentAlpha; private List streamVec = new ArrayList(); private int paletteEntries; private byte[] redPalette; private byte[] greenPalette; private byte[] bluePalette; private byte[] alphaPalette; private boolean hasPalette; private boolean hasAlphaPalette; public PNGFile(InputStream stream, String uri) throws IOException, ImageException { if (!stream.markSupported()) { stream = new BufferedInputStream(stream); } DataInputStream distream = new DataInputStream(stream); long magic = distream.readLong(); if (magic != PNG_SIGNATURE) { String msg = PropertyUtil.getString("PNGImageDecoder0"); throw new ImageException(msg); } // only some chunks are worth parsing in the current implementation do { try { PNGChunk chunk; String chunkType = PNGChunk.getChunkType(distream); if (chunkType.equals(PNGChunk.ChunkType.IHDR.name())) { chunk = PNGChunk.readChunk(distream); parse_IHDR_chunk(chunk); } else if (chunkType.equals(PNGChunk.ChunkType.PLTE.name())) { chunk = PNGChunk.readChunk(distream); parse_PLTE_chunk(chunk); } else if (chunkType.equals(PNGChunk.ChunkType.IDAT.name())) { chunk = PNGChunk.readChunk(distream); streamVec.add(new ByteArrayInputStream(chunk.getData())); } else if (chunkType.equals(PNGChunk.ChunkType.IEND.name())) { // chunk = PNGChunk.readChunk(distream); PNGChunk.skipChunk(distream); break; // fall through to the bottom } else if (chunkType.equals(PNGChunk.ChunkType.tRNS.name())) { chunk = PNGChunk.readChunk(distream); parse_tRNS_chunk(chunk); } else if (chunkType.equals(PNGChunk.ChunkType.iCCP.name())) { chunk = PNGChunk.readChunk(distream); parse_iCCP_chunk(chunk); } else if (chunkType.equals(PNGChunk.ChunkType.sRGB.name())) { chunk = PNGChunk.readChunk(distream); parse_sRGB_chunk(chunk); } else { if (Character.isUpperCase(chunkType.charAt(0))) { throw new ImageException("PNG unknown critical chunk: " + chunkType); } PNGChunk.skipChunk(distream); } } catch (Exception e) { String msg = PropertyUtil.getString("PNGImageDecoder2"); throw new RuntimeException(msg + " " + uri, e); } } while (true); } public ImageRawPNG getImageRawPNG(ImageInfo info) throws ImageException { InputStream seqStream = new SequenceInputStream(Collections.enumeration(streamVec)); ColorSpace rgbCS = null; switch (colorType) { case PNG_COLOR_GRAY: if (hasPalette) { throw new ImageException("Corrupt PNG: color palette is not allowed!"); } colorModel = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_GRAY), false, false, ColorModel.OPAQUE, DataBuffer.TYPE_BYTE); break; case PNG_COLOR_RGB: if (iccProfile != null) { rgbCS = new ICC_ColorSpace(iccProfile); } else if (sRGBRenderingIntent != -1) { rgbCS = ColorSpace.getInstance(ColorSpace.CS_sRGB); } else { rgbCS = ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB); } colorModel = new ComponentColorModel(rgbCS, false, false, ColorModel.OPAQUE, DataBuffer.TYPE_BYTE); break; case PNG_COLOR_PALETTE: if (hasAlphaPalette) { colorModel = new IndexColorModel(bitDepth, paletteEntries, redPalette, greenPalette, bluePalette, alphaPalette); } else { colorModel = new IndexColorModel(bitDepth, paletteEntries, redPalette, greenPalette, bluePalette); } break; case PNG_COLOR_GRAY_ALPHA: if (hasPalette) { throw new ImageException("Corrupt PNG: color palette is not allowed!"); } colorModel = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_GRAY), true, false, ColorModel.TRANSLUCENT, DataBuffer.TYPE_BYTE); break; case PNG_COLOR_RGB_ALPHA: if (iccProfile != null) { rgbCS = new ICC_ColorSpace(iccProfile); } else if (sRGBRenderingIntent != -1) { rgbCS = ColorSpace.getInstance(ColorSpace.CS_sRGB); } else { rgbCS = ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB); } colorModel = new ComponentColorModel(rgbCS, true, false, ColorModel.TRANSLUCENT, DataBuffer.TYPE_BYTE); break; default: throw new ImageException("Unsupported color type: " + colorType); } // the iccProfile is still null for now ImageRawPNG rawImage = new ImageRawPNG(info, seqStream, colorModel, bitDepth, iccProfile); if (isTransparent) { if (colorType == PNG_COLOR_GRAY) { rawImage.setGrayTransparentAlpha(grayTransparentAlpha); } else if (colorType == PNG_COLOR_RGB) { rawImage.setRGBTransparentAlpha(redTransparentAlpha, greenTransparentAlpha, blueTransparentAlpha); } else if (colorType == PNG_COLOR_PALETTE) { rawImage.setTransparent(); } else { // } } if (sRGBRenderingIntent != -1) { rawImage.setRenderingIntent(sRGBRenderingIntent); } return rawImage; } private void parse_IHDR_chunk(PNGChunk chunk) { bitDepth = chunk.getInt1(8); colorType = chunk.getInt1(9); int compressionMethod = chunk.getInt1(10); if (compressionMethod != 0) { throw new RuntimeException("Unsupported PNG compression method: " + compressionMethod); } int filterMethod = chunk.getInt1(11); if (filterMethod != 0) { throw new RuntimeException("Unsupported PNG filter method: " + filterMethod); } int interlaceMethod = chunk.getInt1(12); if (interlaceMethod != 0) { // this is a limitation of the current implementation throw new RuntimeException("Unsupported PNG interlace method: " + interlaceMethod); } } private void parse_PLTE_chunk(PNGChunk chunk) { paletteEntries = chunk.getLength() / 3; redPalette = new byte[paletteEntries]; greenPalette = new byte[paletteEntries]; bluePalette = new byte[paletteEntries]; hasPalette = true; int pltIndex = 0; for (int i = 0; i < paletteEntries; i++) { redPalette[i] = chunk.getByte(pltIndex++); greenPalette[i] = chunk.getByte(pltIndex++); bluePalette[i] = chunk.getByte(pltIndex++); } } private void parse_tRNS_chunk(PNGChunk chunk) { if (colorType == PNG_COLOR_PALETTE) { int entries = chunk.getLength(); if (entries > paletteEntries) { // Error -- mustn't have more alpha than RGB palette entries String msg = PropertyUtil.getString("PNGImageDecoder14"); throw new RuntimeException(msg); } // Load beginning of palette from the chunk alphaPalette = new byte[paletteEntries]; for (int i = 0; i < entries; i++) { alphaPalette[i] = chunk.getByte(i); } // Fill rest of palette with 255 for (int i = entries; i < paletteEntries; i++) { alphaPalette[i] = (byte) 255; } hasAlphaPalette = true; } else if (colorType == PNG_COLOR_GRAY) { grayTransparentAlpha = chunk.getInt2(0); } else if (colorType == PNG_COLOR_RGB) { redTransparentAlpha = chunk.getInt2(0); greenTransparentAlpha = chunk.getInt2(2); blueTransparentAlpha = chunk.getInt2(4); } else if (colorType == PNG_COLOR_GRAY_ALPHA || colorType == PNG_COLOR_RGB_ALPHA) { // Error -- GA or RGBA image can't have a tRNS chunk. String msg = PropertyUtil.getString("PNGImageDecoder15"); throw new RuntimeException(msg); } isTransparent = true; } private void parse_iCCP_chunk(PNGChunk chunk) { int length = chunk.getLength(); int textIndex = 0; while (chunk.getByte(textIndex++) != 0) { //NOP } textIndex++; byte[] profile = new byte[length - textIndex]; System.arraycopy(chunk.getData(), textIndex, profile, 0, length - textIndex); ByteArrayInputStream bais = new ByteArrayInputStream(profile); InflaterInputStream iis = new InflaterInputStream(bais, new Inflater()); try { iccProfile = ICC_Profile.getInstance(iis); } catch (IOException ioe) { // this is OK; the profile will be null } } private void parse_sRGB_chunk(PNGChunk chunk) { sRGBRenderingIntent = chunk.getByte(0); } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/PreloaderBMP.java0100644 0000000 0000000 00000006720 13777276623 031530 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: PreloaderBMP.java 750418 2009-03-05 11:03:54Z vhennebert $ */ package org.apache.xmlgraphics.image.loader.impl; import java.io.IOException; import java.nio.ByteOrder; import javax.imageio.stream.ImageInputStream; import javax.xml.transform.Source; import org.apache.xmlgraphics.image.loader.ImageContext; import org.apache.xmlgraphics.image.loader.ImageException; import org.apache.xmlgraphics.image.loader.ImageInfo; import org.apache.xmlgraphics.image.loader.ImageSize; import org.apache.xmlgraphics.image.loader.util.ImageUtil; import org.apache.xmlgraphics.util.UnitConv; /** * Image preloader for BMP images. */ public class PreloaderBMP extends AbstractImagePreloader { /** Length of the BMP header */ protected static final int BMP_SIG_LENGTH = 2; /** offset to width */ private static final int WIDTH_OFFSET = 18; /** {@inheritDoc} */ public ImageInfo preloadImage(String uri, Source src, ImageContext context) throws IOException, ImageException { if (!ImageUtil.hasImageInputStream(src)) { return null; } ImageInputStream in = ImageUtil.needImageInputStream(src); byte[] header = getHeader(in, BMP_SIG_LENGTH); boolean supported = ((header[0] == (byte) 0x42) && (header[1] == (byte) 0x4d)); if (supported) { ImageInfo info = new ImageInfo(uri, "image/bmp"); info.setSize(determineSize(in, context)); return info; } else { return null; } } private ImageSize determineSize(ImageInputStream in, ImageContext context) throws IOException, ImageException { in.mark(); ByteOrder oldByteOrder = in.getByteOrder(); try { ImageSize size = new ImageSize(); // BMP uses little endian notation! in.setByteOrder(ByteOrder.LITTLE_ENDIAN); in.skipBytes(WIDTH_OFFSET); int width = in.readInt(); int height = in.readInt(); size.setSizeInPixels(width, height); in.skipBytes(12); int xRes = in.readInt(); double xResDPI = UnitConv.in2mm(xRes / 1000d); if (xResDPI == 0) { xResDPI = context.getSourceResolution(); } int yRes = in.readInt(); double yResDPI = UnitConv.in2mm(yRes / 1000d); if (yResDPI == 0) { yResDPI = context.getSourceResolution(); } size.setResolution(xResDPI, yResDPI); size.calcSizeFromPixels(); return size; } finally { in.setByteOrder(oldByteOrder); in.reset(); } } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/PreloaderEMF.java0100644 0000000 0000000 00000010514 13777276623 031515 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: PreloaderEMF.java 1576437 2014-03-11 17:49:35Z vhennebert $ */ package org.apache.xmlgraphics.image.loader.impl; import java.io.IOException; import java.nio.ByteOrder; import javax.imageio.stream.ImageInputStream; import javax.xml.transform.Source; import org.apache.xmlgraphics.image.loader.ImageContext; import org.apache.xmlgraphics.image.loader.ImageException; import org.apache.xmlgraphics.image.loader.ImageInfo; import org.apache.xmlgraphics.image.loader.ImageSize; import org.apache.xmlgraphics.image.loader.util.ImageUtil; import org.apache.xmlgraphics.util.UnitConv; /** * Image preloader for EMF images. */ public class PreloaderEMF extends AbstractImagePreloader { /** Length of the EMF header */ protected static final int EMF_SIG_LENGTH = 88; /** offset to signature */ private static final int SIGNATURE_OFFSET = 40; /** offset to width */ private static final int WIDTH_OFFSET = 32; /** offset to height */ private static final int HEIGHT_OFFSET = 36; /** offset to horizontal resolution in pixel */ private static final int HRES_PIXEL_OFFSET = 72; /** offset to vertical resolution in pixel */ private static final int VRES_PIXEL_OFFSET = 76; /** offset to horizontal resolution in mm */ private static final int HRES_MM_OFFSET = 80; /** offset to vertical resolution in mm */ private static final int VRES_MM_OFFSET = 84; /** {@inheritDoc} */ public ImageInfo preloadImage(String uri, Source src, ImageContext context) throws IOException, ImageException { if (!ImageUtil.hasImageInputStream(src)) { return null; } ImageInputStream in = ImageUtil.needImageInputStream(src); byte[] header = getHeader(in, EMF_SIG_LENGTH); boolean supported = ((header[SIGNATURE_OFFSET + 0] == (byte) 0x20) && (header[SIGNATURE_OFFSET + 1] == (byte) 0x45) && (header[SIGNATURE_OFFSET + 2] == (byte) 0x4D) && (header[SIGNATURE_OFFSET + 3] == (byte) 0x46)); if (supported) { ImageInfo info = new ImageInfo(uri, "image/emf"); info.setSize(determineSize(in, context)); return info; } else { return null; } } private ImageSize determineSize(ImageInputStream in, ImageContext context) throws IOException, ImageException { in.mark(); ByteOrder oldByteOrder = in.getByteOrder(); try { ImageSize size = new ImageSize(); // BMP uses little endian notation! in.setByteOrder(ByteOrder.LITTLE_ENDIAN); //resolution in.skipBytes(WIDTH_OFFSET); int width = (int)in.readUnsignedInt(); int height = (int)in.readUnsignedInt(); in.skipBytes(HRES_PIXEL_OFFSET - WIDTH_OFFSET - 8); long hresPixel = in.readUnsignedInt(); long vresPixel = in.readUnsignedInt(); long hresMM = in.readUnsignedInt(); long vresMM = in.readUnsignedInt(); double resHorz = hresPixel / UnitConv.mm2in(hresMM); double resVert = vresPixel / UnitConv.mm2in(vresMM); size.setResolution(resHorz, resVert); width = (int)Math.round(UnitConv.mm2mpt(width / 100f)); height = (int)Math.round(UnitConv.mm2mpt(height / 100f)); size.setSizeInMillipoints(width, height); size.calcPixelsFromSize(); return size; } finally { in.setByteOrder(oldByteOrder); in.reset(); } } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/PreloaderEPS.java0100644 0000000 0000000 00000022327 13777276623 031542 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: PreloaderEPS.java 1610846 2014-07-15 20:44:18Z vhennebert $ */ package org.apache.xmlgraphics.image.loader.impl; import java.awt.geom.Rectangle2D; import java.io.IOException; import java.nio.ByteOrder; import javax.imageio.stream.ImageInputStream; import javax.xml.transform.Source; import org.apache.xmlgraphics.image.loader.ImageContext; import org.apache.xmlgraphics.image.loader.ImageInfo; import org.apache.xmlgraphics.image.loader.ImageSize; import org.apache.xmlgraphics.image.loader.util.ImageInputStreamAdapter; import org.apache.xmlgraphics.image.loader.util.ImageUtil; import org.apache.xmlgraphics.ps.DSCConstants; import org.apache.xmlgraphics.ps.dsc.DSCException; import org.apache.xmlgraphics.ps.dsc.DSCParser; import org.apache.xmlgraphics.ps.dsc.DSCParserConstants; import org.apache.xmlgraphics.ps.dsc.events.DSCComment; import org.apache.xmlgraphics.ps.dsc.events.DSCCommentBoundingBox; import org.apache.xmlgraphics.ps.dsc.events.DSCEvent; import org.apache.xmlgraphics.util.MimeConstants; /** * Image preloader for EPS images (Encapsulated PostScript). */ public class PreloaderEPS extends AbstractImagePreloader { /** Key for binary header object used in custom objects of the ImageInfo class. */ public static final Object EPS_BINARY_HEADER = EPSBinaryFileHeader.class; /** Key for bounding box used in custom objects of the ImageInfo class. */ public static final Object EPS_BOUNDING_BOX = Rectangle2D.class; /** {@inheritDoc} */ public ImageInfo preloadImage(String uri, Source src, ImageContext context) throws IOException { if (!ImageUtil.hasImageInputStream(src)) { return null; } ImageInputStream in = ImageUtil.needImageInputStream(src); in.mark(); ByteOrder originalByteOrder = in.getByteOrder(); in.setByteOrder(ByteOrder.LITTLE_ENDIAN); EPSBinaryFileHeader binaryHeader = null; try { long magic = in.readUnsignedInt(); magic &= 0xFFFFFFFFL; //Work-around for bug in Java 1.4.2 // Check if binary header boolean supported = false; if (magic == 0xC6D3D0C5L) { supported = true; //binary EPS binaryHeader = readBinaryFileHeader(in); in.reset(); in.mark(); //Mark start of file again in.seek(binaryHeader.psStart); } else if (magic == 0x53502125L) { //"%!PS" in little endian supported = true; //ascii EPS in.reset(); in.mark(); //Mark start of file again } else { in.reset(); } if (supported) { ImageInfo info = new ImageInfo(uri, MimeConstants.MIME_EPS); boolean success = determineSize(in, context, info); in.reset(); //Need to go back to start of file if (!success) { //No BoundingBox found, so probably no EPS return null; } if (in.getStreamPosition() != 0) { throw new IllegalStateException("Need to be at the start of the file here"); } if (binaryHeader != null) { info.getCustomObjects().put(EPS_BINARY_HEADER, binaryHeader); } return info; } else { return null; } } finally { in.setByteOrder(originalByteOrder); } } private EPSBinaryFileHeader readBinaryFileHeader(ImageInputStream in) throws IOException { EPSBinaryFileHeader offsets = new EPSBinaryFileHeader(); offsets.psStart = in.readUnsignedInt(); offsets.psLength = in.readUnsignedInt(); offsets.wmfStart = in.readUnsignedInt(); offsets.wmfLength = in.readUnsignedInt(); offsets.tiffStart = in.readUnsignedInt(); offsets.tiffLength = in.readUnsignedInt(); return offsets; } private boolean determineSize(ImageInputStream in, ImageContext context, ImageInfo info) throws IOException { in.mark(); try { Rectangle2D bbox = null; DSCParser parser; try { parser = new DSCParser(new ImageInputStreamAdapter(in)); outerLoop: while (parser.hasNext()) { DSCEvent event = parser.nextEvent(); switch (event.getEventType()) { case DSCParserConstants.HEADER_COMMENT: case DSCParserConstants.COMMENT: //ignore break; case DSCParserConstants.DSC_COMMENT: DSCComment comment = event.asDSCComment(); if (comment instanceof DSCCommentBoundingBox) { DSCCommentBoundingBox bboxComment = (DSCCommentBoundingBox)comment; if (DSCConstants.BBOX.equals(bboxComment.getName()) && bbox == null) { bbox = (Rectangle2D)bboxComment.getBoundingBox().clone(); //BoundingBox is good but HiRes is better so continue } else if (DSCConstants.HIRES_BBOX.equals(bboxComment.getName())) { bbox = (Rectangle2D)bboxComment.getBoundingBox().clone(); //HiRefBBox is great so stop break outerLoop; } } break; default: //No more header so stop break outerLoop; } } if (bbox == null) { return false; } } catch (DSCException e) { throw new IOException("Error while parsing EPS file: " + e.getMessage()); } ImageSize size = new ImageSize(); size.setSizeInMillipoints( (int)Math.round(bbox.getWidth() * 1000), (int)Math.round(bbox.getHeight() * 1000)); size.setResolution(context.getSourceResolution()); size.calcPixelsFromSize(); info.setSize(size); info.getCustomObjects().put(EPS_BOUNDING_BOX, bbox); return true; } finally { in.reset(); } } /** * Holder class for various pointers to the contents of the EPS file. */ public static class EPSBinaryFileHeader { private long psStart; private long psLength; private long wmfStart; private long wmfLength; private long tiffStart; private long tiffLength; /** * Returns the start offset of the PostScript section. * @return the start offset */ public long getPSStart() { return psStart; } /** * Returns the length of the PostScript section. * @return the length of the PostScript section (in bytes) */ public long getPSLength() { return psLength; } /** * Indicates whether the EPS has a WMF preview. * @return true if there is a WMF preview */ public boolean hasWMFPreview() { return (wmfStart != 0); } /** * Returns the start offset of the WMF preview. * @return the start offset (or 0 if there's no WMF preview) */ public long getWMFStart() { return wmfStart; } /** * Returns the length of the WMF preview. * @return the length of the WMF preview (in bytes) */ public long getWMFLength() { return wmfLength; } /** * Indicates whether the EPS has a TIFF preview. * @return true if there is a TIFF preview */ public boolean hasTIFFPreview() { return (tiffStart != 0); } /** * Returns the start offset of the TIFF preview. * @return the start offset (or 0 if there's no TIFF preview) */ public long getTIFFStart() { return tiffStart; } /** * Returns the length of the TIFF preview. * @return the length of the TIFF preview (in bytes) */ public long getTIFFLength() { return tiffLength; } } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/PreloaderGIF.java0100644 0000000 0000000 00000006171 13777276623 031517 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: PreloaderGIF.java 1556077 2014-01-07 00:07:33Z lbernardo $ */ package org.apache.xmlgraphics.image.loader.impl; import java.io.IOException; import java.util.Iterator; import javax.imageio.ImageIO; import javax.imageio.ImageReader; import javax.imageio.stream.ImageInputStream; import javax.xml.transform.Source; import org.apache.xmlgraphics.image.loader.ImageContext; import org.apache.xmlgraphics.image.loader.ImageInfo; import org.apache.xmlgraphics.image.loader.ImageSize; import org.apache.xmlgraphics.image.loader.util.ImageUtil; import org.apache.xmlgraphics.util.MimeConstants; /** * Image preloader for GIF images. */ public class PreloaderGIF extends AbstractImagePreloader { private static final int GIF_SIG_LENGTH = 10; /** {@inheritDoc} */ public ImageInfo preloadImage(String uri, Source src, ImageContext context) throws IOException { if (!ImageUtil.hasImageInputStream(src)) { return null; } ImageInputStream in = ImageUtil.needImageInputStream(src); byte[] header = getHeader(in, GIF_SIG_LENGTH); boolean supported = ((header[0] == 'G') && (header[1] == 'I') && (header[2] == 'F') && (header[3] == '8') && (header[4] == '7' || header[4] == '9') && (header[5] == 'a')); if (supported) { ImageInfo info = new ImageInfo(uri, MimeConstants.MIME_GIF); info.setSize(determineSize(header, context, in)); return info; } else { return null; } } private ImageSize determineSize(byte[] header, ImageContext context, ImageInputStream in) throws IOException { int [] dim = extractImageMetadata(in); ImageSize size = new ImageSize(dim[0], dim[1], context.getSourceResolution()); size.calcSizeFromPixels(); return size; } private int[] extractImageMetadata(ImageInputStream in) throws IOException { long startPos = in.getStreamPosition(); Iterator readers = ImageIO.getImageReadersByFormatName("gif"); ImageReader reader = (ImageReader) readers.next(); reader.setInput(in, true); int width = reader.getWidth(0); int height = reader.getHeight(0); int[] dim = {width, height}; in.seek(startPos); return dim; } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/PreloaderJPEG.java0100644 0000000 0000000 00000026311 13777276623 031635 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: PreloaderJPEG.java 1681108 2015-05-22 13:26:12Z ssteiner $ */ package org.apache.xmlgraphics.image.loader.impl; import java.io.IOException; import java.nio.ByteOrder; import javax.imageio.stream.ImageInputStream; import javax.xml.transform.Source; import org.apache.xmlgraphics.image.loader.ImageContext; import org.apache.xmlgraphics.image.loader.ImageException; import org.apache.xmlgraphics.image.loader.ImageInfo; import org.apache.xmlgraphics.image.loader.ImageSize; import org.apache.xmlgraphics.image.loader.util.ImageUtil; import org.apache.xmlgraphics.util.MimeConstants; import org.apache.xmlgraphics.util.UnitConv; /** * Image preloader for JPEG images. */ public class PreloaderJPEG extends AbstractImagePreloader implements JPEGConstants { private static final int JPG_SIG_LENGTH = 3; private static final int[] BYTES_PER_COMPONENT = {0, 1, 1, 2, 4, 8, 1, 1, 2, 4, 8, 4, 8}; // ignore 0 private static final int EXIF = 0x45786966; private static final int II = 0x4949; // Intel private static final int MM = 0x4d4d; // Motorola private static final int X_RESOLUTION = 0x011a; private static final int Y_RESOLUTION = 0x011b; private static final int RESOLUTION_UNIT = 0x0128; /** {@inheritDoc} * @throws ImageException */ public ImageInfo preloadImage(String uri, Source src, ImageContext context) throws IOException, ImageException { if (!ImageUtil.hasImageInputStream(src)) { return null; } ImageInputStream in = ImageUtil.needImageInputStream(src); byte[] header = getHeader(in, JPG_SIG_LENGTH); boolean supported = ((header[0] == (byte)MARK) && (header[1] == (byte)SOI) && (header[2] == (byte)MARK)); if (supported) { ImageInfo info = new ImageInfo(uri, MimeConstants.MIME_JPEG); info.setSize(determineSize(in, context)); return info; } else { return null; } } private ImageSize determineSize(ImageInputStream in, ImageContext context) throws IOException, ImageException { in.mark(); try { ImageSize size = new ImageSize(); JPEGFile jpeg = new JPEGFile(in); while (true) { int segID = jpeg.readMarkerSegment(); //System.out.println("Segment: " + Integer.toHexString(segID)); switch (segID) { case SOI: case NULL: break; case APP0: int reclen = jpeg.readSegmentLength(); in.skipBytes(7); int densityUnits = in.read(); int xdensity = in.readUnsignedShort(); int ydensity = in.readUnsignedShort(); if (size.getDpiHorizontal() == 0) { if (densityUnits == 2) { //dots per centimeter size.setResolution( xdensity * UnitConv.IN2CM, ydensity * UnitConv.IN2CM); } else if (densityUnits == 1) { //dots per inch size.setResolution(xdensity, ydensity); } else { //resolution not specified size.setResolution(context.getSourceResolution()); } } if (size.getWidthPx() != 0) { size.calcSizeFromPixels(); return size; } in.skipBytes(reclen - 14); break; case APP1: // see http://www.media.mit.edu/pia/Research/deepview/exif.html reclen = jpeg.readSegmentLength(); int bytesToEnd = reclen - 2; // read Exif Header: 0x.45.78.69.66.00.00 int exif = in.readInt(); // 0x.45.78.69.66 in.readUnsignedShort(); // 0x.00.00 // in.skipBytes(6); bytesToEnd -= 6; if (exif != EXIF) { // there may be multiple APP1 segments but we want the Exif one in.skipBytes(bytesToEnd); break; } // start TIFF data int currentTIFFOffset = 0; // byte align: 0x.49.49 (19789) means Intel, 0x.4D.4D means Motorola int align = in.readUnsignedShort(); bytesToEnd -= 2; currentTIFFOffset += 2; ByteOrder originalByteOrder = in.getByteOrder(); // Intel = little, Motorola = big in.setByteOrder(align == MM ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN); in.skipBytes(2); // 0x.2A.00 (Intel) or 0x.00.2A (Motorola) bytesToEnd -= 2; currentTIFFOffset += 2; int firstIFDOffset = in.readInt(); bytesToEnd -= 4; currentTIFFOffset += 4; in.skipBytes(firstIFDOffset - 8); bytesToEnd -= firstIFDOffset - 8; currentTIFFOffset += firstIFDOffset - 8; int directoryEntries = in.readUnsignedShort(); bytesToEnd -= 2; currentTIFFOffset += 2; int resolutionOffset = 0; int resolutionFormat = 0; int resolutionUnits = 0; int resolution = 0; boolean foundResolution = false; for (int j = 0; j < directoryEntries; j++) { int tag = in.readUnsignedShort(); if ((tag == X_RESOLUTION || tag == Y_RESOLUTION) && !foundResolution) { // 0x011A (XResolution), 0x011B (YResolution) int format = in.readUnsignedShort(); int components = in.readInt(); int dataByteLength = components * BYTES_PER_COMPONENT[format]; int value = in.readInt(); if (dataByteLength > 4) { // value is offset to data value resolutionOffset = value; } else { // value is data value resolution = value; } resolutionFormat = format; foundResolution = true; } else if (tag == RESOLUTION_UNIT) { // 0x0128 (ResolutionUnit) int format = in.readUnsignedShort(); int components = in.readInt(); int dataByteLength = components * BYTES_PER_COMPONENT[format]; if (dataByteLength < 5 && format == 3) { int value = in.readUnsignedShort(); in.skipBytes(2); resolutionUnits = value; } else { in.skipBytes(4); } } else { in.skipBytes(10); } bytesToEnd -= 12; currentTIFFOffset += 12; } in.readInt(); // not needed, but has thumbnail info bytesToEnd -= 4; currentTIFFOffset += 4; if (resolutionOffset != 0) { in.skipBytes(resolutionOffset - currentTIFFOffset); bytesToEnd -= resolutionOffset - currentTIFFOffset; if (resolutionFormat == 5 || resolutionFormat == 10) { int numerator = in.readInt(); int denominator = in.readInt(); resolution = numerator / denominator; bytesToEnd -= 8; } } in.skipBytes(bytesToEnd); in.setByteOrder(originalByteOrder); if (resolutionUnits == 3) { // dots per centimeter size.setResolution(resolution * UnitConv.IN2CM, resolution * UnitConv.IN2CM); } else if (resolutionUnits == 2) { // dots per inch size.setResolution(resolution, resolution); } else { // resolution not specified; set default if not set yet if (size.getDpiHorizontal() == 0) { size.setResolution(context.getSourceResolution()); } } if (size.getWidthPx() != 0) { size.calcSizeFromPixels(); return size; } break; case SOF0: case SOF1: case SOF2: // SOF2 and SOFA are only supported by PDF 1.3 case SOFA: reclen = jpeg.readSegmentLength(); in.skipBytes(1); int height = in.readUnsignedShort(); int width = in.readUnsignedShort(); size.setSizeInPixels(width, height); if (size.getDpiHorizontal() != 0) { size.calcSizeFromPixels(); return size; } in.skipBytes(reclen - 7); break; case SOS: case EOI: // Break as early as possible (we don't want to read the whole file here) if (size.getDpiHorizontal() == 0) { size.setResolution(context.getSourceResolution()); size.calcSizeFromPixels(); } return size; default: jpeg.skipCurrentMarkerSegment(); } } } finally { in.reset(); } } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/PreloaderRawPNG.java0100644 0000000 0000000 00000004527 13777276623 032213 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: PreloaderRawPNG.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.image.loader.impl; import java.io.IOException; import java.nio.ByteBuffer; import javax.imageio.stream.ImageInputStream; import javax.xml.transform.Source; import org.apache.xmlgraphics.image.codec.png.PNGImageDecoder; import org.apache.xmlgraphics.image.loader.ImageContext; import org.apache.xmlgraphics.image.loader.ImageException; import org.apache.xmlgraphics.image.loader.ImageInfo; import org.apache.xmlgraphics.image.loader.ImageSize; import org.apache.xmlgraphics.image.loader.util.ImageUtil; public class PreloaderRawPNG extends AbstractImagePreloader { public ImageInfo preloadImage(String uri, Source src, ImageContext context) throws ImageException, IOException { if (!ImageUtil.hasImageInputStream(src)) { return null; } ImageInputStream in = ImageUtil.needImageInputStream(src); long bb = ByteBuffer.wrap(getHeader(in, 8)).getLong(); if (bb != PNGConstants.PNG_SIGNATURE) { return null; } in.mark(); ImageSize size = new ImageSize(); //Resolution (first a default, then try to read the metadata) size.setResolution(context.getSourceResolution()); try { PNGImageDecoder.readPNGHeader(in, size); } finally { in.reset(); } ImageInfo info = new ImageInfo(uri, "image/png"); info.setSize(size); return info; } public int getPriority() { return DEFAULT_PRIORITY * 2; } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/PreloaderTIFF.java0100644 0000000 0000000 00000017263 13777276623 031646 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: PreloaderTIFF.java 1681108 2015-05-22 13:26:12Z ssteiner $ */ package org.apache.xmlgraphics.image.loader.impl; import java.io.IOException; import java.text.MessageFormat; import javax.imageio.stream.ImageInputStream; import javax.xml.transform.Source; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.xmlgraphics.image.codec.tiff.TIFFDirectory; import org.apache.xmlgraphics.image.codec.tiff.TIFFField; import org.apache.xmlgraphics.image.codec.tiff.TIFFImageDecoder; import org.apache.xmlgraphics.image.codec.util.SeekableStream; import org.apache.xmlgraphics.image.loader.ImageContext; import org.apache.xmlgraphics.image.loader.ImageException; import org.apache.xmlgraphics.image.loader.ImageInfo; import org.apache.xmlgraphics.image.loader.ImageSize; import org.apache.xmlgraphics.image.loader.SubImageNotFoundException; import org.apache.xmlgraphics.image.loader.util.ImageUtil; import org.apache.xmlgraphics.image.loader.util.SeekableStreamAdapter; import org.apache.xmlgraphics.util.MimeConstants; import org.apache.xmlgraphics.util.UnitConv; /** * Image preloader for TIFF images. *

    * Note: The implementation relies on the TIFF codec code in Apache XML Graphics Commons for * access to the TIFF directory. */ public class PreloaderTIFF extends AbstractImagePreloader { private static Log log = LogFactory.getLog(PreloaderTIFF.class); private static final int TIFF_SIG_LENGTH = 8; /** {@inheritDoc} * @throws ImageException */ public ImageInfo preloadImage(String uri, Source src, ImageContext context) throws IOException, ImageException { if (!ImageUtil.hasImageInputStream(src)) { return null; } ImageInputStream in = ImageUtil.needImageInputStream(src); byte[] header = getHeader(in, TIFF_SIG_LENGTH); boolean supported = false; // first 2 bytes = II (little endian encoding) if (header[0] == (byte) 0x49 && header[1] == (byte) 0x49) { // look for '42' in byte 3 and '0' in byte 4 if (header[2] == 42 && header[3] == 0) { supported = true; } } // first 2 bytes == MM (big endian encoding) if (header[0] == (byte) 0x4D && header[1] == (byte) 0x4D) { // look for '42' in byte 4 and '0' in byte 3 if (header[2] == 0 && header[3] == 42) { supported = true; } } if (supported) { ImageInfo info = createImageInfo(uri, in, context); return info; } else { return null; } } private ImageInfo createImageInfo(String uri, ImageInputStream in, ImageContext context) throws IOException, ImageException { ImageInfo info = null; in.mark(); try { int pageIndex = ImageUtil.needPageIndexFromURI(uri); SeekableStream seekable = new SeekableStreamAdapter(in); TIFFDirectory dir; try { dir = new TIFFDirectory(seekable, pageIndex); } catch (IllegalArgumentException iae) { String errorMessage = MessageFormat.format( "Subimage {0} does not exist.", new Object[] {pageIndex}); throw new SubImageNotFoundException(errorMessage); } int width = (int)dir.getFieldAsLong(TIFFImageDecoder.TIFF_IMAGE_WIDTH); int height = (int)dir.getFieldAsLong(TIFFImageDecoder.TIFF_IMAGE_LENGTH); ImageSize size = new ImageSize(); size.setSizeInPixels(width, height); int unit = 2; //inch is default if (dir.isTagPresent(TIFFImageDecoder.TIFF_RESOLUTION_UNIT)) { unit = (int)dir.getFieldAsLong(TIFFImageDecoder.TIFF_RESOLUTION_UNIT); } if (unit == 2 || unit == 3) { float xRes; float yRes; TIFFField fldx = dir.getField(TIFFImageDecoder.TIFF_X_RESOLUTION); TIFFField fldy = dir.getField(TIFFImageDecoder.TIFF_Y_RESOLUTION); if (fldx == null || fldy == null) { unit = 2; xRes = context.getSourceResolution(); yRes = xRes; } else { xRes = fldx.getAsFloat(0); yRes = fldy.getAsFloat(0); } if (xRes == 0 || yRes == 0) { //Some TIFFs may report 0 here which would lead to problems size.setResolution(context.getSourceResolution()); } else if (unit == 2) { size.setResolution(xRes, yRes); //Inch } else { size.setResolution( UnitConv.in2mm(xRes) / 10, UnitConv.in2mm(yRes) / 10); //Centimeters } } else { size.setResolution(context.getSourceResolution()); } size.calcSizeFromPixels(); if (log.isTraceEnabled()) { log.trace("TIFF image detected: " + size); } info = new ImageInfo(uri, MimeConstants.MIME_TIFF); info.setSize(size); TIFFField fld; fld = dir.getField(TIFFImageDecoder.TIFF_COMPRESSION); if (fld != null) { int compression = fld.getAsInt(0); if (log.isTraceEnabled()) { log.trace("TIFF compression: " + compression); } info.getCustomObjects().put("TIFF_COMPRESSION", compression); } fld = dir.getField(TIFFImageDecoder.TIFF_TILE_WIDTH); if (fld != null) { if (log.isTraceEnabled()) { log.trace("TIFF is tiled"); } info.getCustomObjects().put("TIFF_TILED", Boolean.TRUE); } int stripCount; fld = dir.getField(TIFFImageDecoder.TIFF_ROWS_PER_STRIP); if (fld == null) { stripCount = 1; } else { stripCount = (int)Math.ceil(size.getHeightPx() / (double)fld.getAsLong(0)); } if (log.isTraceEnabled()) { log.trace("TIFF has " + stripCount + " strips."); } info.getCustomObjects().put("TIFF_STRIP_COUNT", stripCount); try { //Check if there is a next page new TIFFDirectory(seekable, pageIndex + 1); info.getCustomObjects().put(ImageInfo.HAS_MORE_IMAGES, Boolean.TRUE); if (log.isTraceEnabled()) { log.trace("TIFF is multi-page."); } } catch (IllegalArgumentException iae) { info.getCustomObjects().put(ImageInfo.HAS_MORE_IMAGES, Boolean.FALSE); } } finally { in.reset(); } return info; } } ././@LongLink0100644 0000000 0000000 00000000150 13777276623 011653 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/imageio/ImageIOUtil.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/imageio/ImageIOUtil.j0100644 0000000 0000000 00000011751 13777276623 032306 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageIOUtil.java 1804124 2017-08-04 14:13:54Z ssteiner $ */ package org.apache.xmlgraphics.image.loader.impl.imageio; import javax.imageio.metadata.IIOMetadata; import javax.imageio.metadata.IIOMetadataFormatImpl; import javax.xml.transform.OutputKeys; import javax.xml.transform.Result; import javax.xml.transform.Source; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.apache.xmlgraphics.image.loader.ImageSize; import org.apache.xmlgraphics.util.UnitConv; /** * Helper and convenience methods for ImageIO. */ public final class ImageIOUtil { private ImageIOUtil() { } /** Key for ImageInfo's custom objects to embed the ImageIO metadata */ public static final Object IMAGEIO_METADATA = IIOMetadata.class; /** * Extracts the resolution information from the standard ImageIO metadata. * @param iiometa the metadata provided by ImageIO * @param size the image size object */ public static void extractResolution(IIOMetadata iiometa, ImageSize size) { if (iiometa != null && iiometa.isStandardMetadataFormatSupported()) { Element metanode = (Element)iiometa.getAsTree( IIOMetadataFormatImpl.standardMetadataFormatName); Element dim = getChild(metanode, "Dimension"); if (dim != null) { Element child; double dpiHorz = size.getDpiHorizontal(); double dpiVert = size.getDpiVertical(); child = getChild(dim, "HorizontalPixelSize"); if (child != null) { float value = Float.parseFloat(child.getAttribute("value")); if (value != 0 && !Float.isInfinite(value)) { dpiHorz = UnitConv.IN2MM / value; } } child = getChild(dim, "VerticalPixelSize"); if (child != null) { float value = Float.parseFloat(child.getAttribute("value")); if (value != 0 && !Float.isInfinite(value)) { dpiVert = UnitConv.IN2MM / value; } } size.setResolution(dpiHorz, dpiVert); size.calcSizeFromPixels(); } } } /** * Returns a child element of another element or null if there's no such child. * @param el the parent element * @param name the name of the requested child * @return the child or null if there's no such child */ public static Element getChild(Element el, String name) { NodeList nodes = el.getElementsByTagName(name); if (nodes.getLength() > 0) { return (Element)nodes.item(0); } else { return null; } } /** * Dumps the content of an IIOMetadata instance to System.out. * @param iiometa the metadata */ public static void dumpMetadataToSystemOut(IIOMetadata iiometa) { String[] metanames = iiometa.getMetadataFormatNames(); for (String metaname : metanames) { System.out.println("--->" + metaname); dumpNodeToSystemOut(iiometa.getAsTree(metaname)); } } /** * Serializes a W3C DOM node to a String and dumps it to System.out. * @param node a W3C DOM node */ private static void dumpNodeToSystemOut(Node node) { Transformer trans = null; try { trans = TransformerFactory.newInstance().newTransformer(); trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); trans.setOutputProperty(OutputKeys.INDENT, "yes"); Source src = new DOMSource(node); Result res = new StreamResult(System.out); trans.transform(src, res); } catch (TransformerConfigurationException e) { e.printStackTrace(); } catch (TransformerException e) { e.printStackTrace(); } } } ././@LongLink0100644 0000000 0000000 00000000166 13777276623 011662 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/imageio/ImageLoaderFactoryImageIO.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/imageio/ImageLoaderFa0100644 0000000 0000000 00000003655 13777276623 032372 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageLoaderFactoryImageIO.java 1681137 2015-05-22 14:54:05Z ssteiner $ */ package org.apache.xmlgraphics.image.loader.impl.imageio; import javax.imageio.ImageIO; import org.apache.xmlgraphics.image.loader.ImageFlavor; import org.apache.xmlgraphics.image.loader.impl.AbstractImageLoaderFactory; import org.apache.xmlgraphics.image.loader.spi.ImageLoader; /** * Factory class for the ImageLoader based on ImageIO. */ public class ImageLoaderFactoryImageIO extends AbstractImageLoaderFactory { private static final ImageFlavor[] FLAVORS = new ImageFlavor[] { ImageFlavor.RENDERED_IMAGE, ImageFlavor.BUFFERED_IMAGE}; /** {@inheritDoc} */ public String[] getSupportedMIMETypes() { return ImageIO.getReaderMIMETypes(); } /** {@inheritDoc} */ public ImageFlavor[] getSupportedFlavors(String mime) { return FLAVORS; } /** {@inheritDoc} */ public ImageLoader newImageLoader(ImageFlavor targetFlavor) { return new ImageLoaderImageIO(targetFlavor); } /** {@inheritDoc} */ public boolean isAvailable() { return (getSupportedMIMETypes().length > 0); } } ././@LongLink0100644 0000000 0000000 00000000157 13777276623 011662 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/imageio/ImageLoaderImageIO.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/imageio/ImageLoaderIm0100644 0000000 0000000 00000043372 13777276623 032411 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageLoaderImageIO.java 1804124 2017-08-04 14:13:54Z ssteiner $ */ package org.apache.xmlgraphics.image.loader.impl.imageio; import java.awt.Color; import java.awt.color.ICC_ColorSpace; import java.awt.color.ICC_Profile; import java.awt.image.BufferedImage; import java.awt.image.ColorModel; import java.awt.image.ComponentColorModel; import java.awt.image.IndexColorModel; import java.awt.image.Raster; import java.awt.image.RenderedImage; import java.awt.image.WritableRaster; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.HashSet; import java.util.Iterator; import java.util.Locale; import java.util.Map; import java.util.Set; import java.util.StringTokenizer; import java.util.zip.DataFormatException; import java.util.zip.Inflater; import javax.imageio.IIOException; import javax.imageio.ImageIO; import javax.imageio.ImageReadParam; import javax.imageio.ImageReader; import javax.imageio.ImageTypeSpecifier; import javax.imageio.metadata.IIOMetadata; import javax.imageio.metadata.IIOMetadataFormatImpl; import javax.imageio.metadata.IIOMetadataNode; import javax.imageio.spi.IIOServiceProvider; import javax.imageio.stream.ImageInputStream; import javax.xml.transform.Source; import org.w3c.dom.Element; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.xmlgraphics.image.loader.Image; import org.apache.xmlgraphics.image.loader.ImageException; import org.apache.xmlgraphics.image.loader.ImageFlavor; import org.apache.xmlgraphics.image.loader.ImageInfo; import org.apache.xmlgraphics.image.loader.ImageSessionContext; import org.apache.xmlgraphics.image.loader.impl.AbstractImageLoader; import org.apache.xmlgraphics.image.loader.impl.ImageBuffered; import org.apache.xmlgraphics.image.loader.impl.ImageRendered; import org.apache.xmlgraphics.image.loader.util.ImageUtil; import org.apache.xmlgraphics.io.XmlSourceUtil; import org.apache.xmlgraphics.java2d.color.profile.ColorProfileUtil; /** * An ImageLoader implementation based on ImageIO for loading bitmap images. */ public class ImageLoaderImageIO extends AbstractImageLoader { /** logger */ protected static final Log log = LogFactory.getLog(ImageLoaderImageIO.class); private ImageFlavor targetFlavor; private static final String PNG_METADATA_NODE = "javax_imageio_png_1.0"; private static final String JPEG_METADATA_NODE = "javax_imageio_jpeg_image_1.0"; private static final Set PROVIDERS_IGNORING_ICC = new HashSet(); /** * Main constructor. * @param targetFlavor the target flavor */ public ImageLoaderImageIO(ImageFlavor targetFlavor) { if (!(ImageFlavor.BUFFERED_IMAGE.equals(targetFlavor) || ImageFlavor.RENDERED_IMAGE.equals(targetFlavor))) { throw new IllegalArgumentException("Unsupported target ImageFlavor: " + targetFlavor); } this.targetFlavor = targetFlavor; } /** {@inheritDoc} */ public ImageFlavor getTargetFlavor() { return this.targetFlavor; } /** {@inheritDoc} */ public Image loadImage(ImageInfo info, Map hints, ImageSessionContext session) throws ImageException, IOException { RenderedImage imageData = null; IIOException firstException = null; IIOMetadata iiometa = (IIOMetadata)info.getCustomObjects().get( ImageIOUtil.IMAGEIO_METADATA); boolean ignoreMetadata = (iiometa != null); boolean providerIgnoresICC = false; Source src = session.needSource(info.getOriginalURI()); ImageInputStream imgStream = ImageUtil.needImageInputStream(src); try { Iterator iter = ImageIO.getImageReaders(imgStream); while (iter.hasNext()) { ImageReader reader = (ImageReader)iter.next(); try { imgStream.mark(); reader.setInput(imgStream, false, ignoreMetadata); ImageReadParam param = getParam(reader, hints); final int pageIndex = ImageUtil.needPageIndexFromURI(info.getOriginalURI()); try { // if (ImageFlavor.BUFFERED_IMAGE.equals(this.targetFlavor)) { imageData = reader.read(pageIndex, param); // } else { // imageData = reader.read(pageIndex, param); //imageData = reader.readAsRenderedImage(pageIndex, param); //TODO Reenable the above when proper listeners are implemented //to react to late pixel population (so the stream can be closed //properly). // } if (iiometa == null) { iiometa = reader.getImageMetadata(pageIndex); } providerIgnoresICC = checkProviderIgnoresICC(reader .getOriginatingProvider()); break; //Quit early, we have the image } catch (IndexOutOfBoundsException indexe) { throw new ImageException("Page does not exist. Invalid image index: " + pageIndex); } catch (IllegalArgumentException iae) { //Some codecs like com.sun.imageio.plugins.wbmp.WBMPImageReader throw //IllegalArgumentExceptions when they have trouble parsing the image. throw new ImageException("Error loading image using ImageIO codec", iae); } catch (IIOException iioe) { if (firstException == null) { firstException = iioe; } else { log.debug("non-first error loading image: " + iioe.getMessage()); } } try { //Try fallback for CMYK images BufferedImage bi = getFallbackBufferedImage(reader, pageIndex, param); imageData = bi; firstException = null; //Clear exception after successful fallback attempt break; } catch (IIOException iioe) { //ignore } imgStream.reset(); } finally { reader.dispose(); } } } finally { XmlSourceUtil.closeQuietly(src); //TODO Some codecs may do late reading. } if (firstException != null) { throw new ImageException("Error while loading image: " + firstException.getMessage(), firstException); } if (imageData == null) { throw new ImageException("No ImageIO ImageReader found ."); } ColorModel cm = imageData.getColorModel(); Color transparentColor = null; if (cm instanceof IndexColorModel) { //transparent color will be extracted later from the image } else { if (providerIgnoresICC && cm instanceof ComponentColorModel) { // Apply ICC Profile to Image by creating a new image with a new // color model. ICC_Profile iccProf = tryToExctractICCProfile(iiometa); if (iccProf != null) { ColorModel cm2 = new ComponentColorModel( new ICC_ColorSpace(iccProf), cm.hasAlpha(), cm .isAlphaPremultiplied(), cm .getTransparency(), cm.getTransferType()); WritableRaster wr = Raster.createWritableRaster(imageData .getSampleModel(), null); imageData.copyData(wr); try { BufferedImage bi = new BufferedImage(cm2, wr, cm2 .isAlphaPremultiplied(), null); imageData = bi; cm = cm2; } catch (IllegalArgumentException iae) { String msg = "Image " + info.getOriginalURI() + " has an incompatible color profile." + " The color profile will be ignored." + "\nColor model of loaded bitmap: " + cm + "\nColor model of color profile: " + cm2; if (info.getCustomObjects().get("warningincustomobject") != null) { info.getCustomObjects().put("warning", msg); } else { log.warn(msg); } } } } // ImageIOUtil.dumpMetadataToSystemOut(iiometa); // Retrieve the transparent color from the metadata if (iiometa != null && iiometa.isStandardMetadataFormatSupported()) { Element metanode = (Element)iiometa.getAsTree( IIOMetadataFormatImpl.standardMetadataFormatName); Element dim = ImageIOUtil.getChild(metanode, "Transparency"); if (dim != null) { Element child; child = ImageIOUtil.getChild(dim, "TransparentColor"); if (child != null) { String value = child.getAttribute("value"); if (value.length() == 0) { //ignore } else if (cm.getNumColorComponents() == 1) { int gray = Integer.parseInt(value); transparentColor = new Color(gray, gray, gray); } else { StringTokenizer st = new StringTokenizer(value); transparentColor = new Color( Integer.parseInt(st.nextToken()), Integer.parseInt(st.nextToken()), Integer.parseInt(st.nextToken())); } } } } } if (ImageFlavor.BUFFERED_IMAGE.equals(this.targetFlavor)) { return new ImageBuffered(info, (BufferedImage)imageData, transparentColor); } else { return new ImageRendered(info, imageData, transparentColor); } } private ImageReadParam getParam(ImageReader reader, Map hints) throws IOException { if (hints != null && Boolean.TRUE.equals(hints.get("CMYK"))) { Iterator types = reader.getImageTypes(0); while (types.hasNext()) { ImageTypeSpecifier type = types.next(); if (type.getNumComponents() == 4) { ImageReadParam param = new ImageReadParam(); param.setDestinationType(type); return param; } } } return reader.getDefaultReadParam(); } /** * Checks if the provider ignores the ICC color profile. This method will * assume providers work correctly, and return false if the provider is * unknown. This ensures backward-compatibility. * * @param provider * the ImageIO Provider * @return true if we know the provider to be broken and ignore ICC * profiles. */ private boolean checkProviderIgnoresICC(IIOServiceProvider provider) { // TODO: This information could be cached. StringBuffer b = new StringBuffer(provider.getDescription(Locale.ENGLISH)); b.append('/').append(provider.getVendorName()); b.append('/').append(provider.getVersion()); if (log.isDebugEnabled()) { log.debug("Image Provider: " + b.toString()); } return ImageLoaderImageIO.PROVIDERS_IGNORING_ICC.contains(b.toString()); } /** * Extract ICC Profile from ImageIO Metadata. This method currently only * supports PNG and JPEG metadata. * * @param iiometa * The ImageIO Metadata * @return an ICC Profile or null. */ private ICC_Profile tryToExctractICCProfile(IIOMetadata iiometa) { ICC_Profile iccProf = null; String[] supportedFormats = iiometa.getMetadataFormatNames(); for (String format : supportedFormats) { Element root = (Element) iiometa.getAsTree(format); if (PNG_METADATA_NODE.equals(format)) { iccProf = this .tryToExctractICCProfileFromPNGMetadataNode(root); } else if (JPEG_METADATA_NODE.equals(format)) { iccProf = this.tryToExctractICCProfileFromJPEGMetadataNode(root); } } return iccProf; } private ICC_Profile tryToExctractICCProfileFromPNGMetadataNode( Element pngNode) { ICC_Profile iccProf = null; Element iccpNode = ImageIOUtil.getChild(pngNode, "iCCP"); if (iccpNode instanceof IIOMetadataNode) { IIOMetadataNode imn = (IIOMetadataNode) iccpNode; byte[] prof = (byte[]) imn.getUserObject(); String comp = imn.getAttribute("compressionMethod"); if ("deflate".equalsIgnoreCase(comp)) { Inflater decompresser = new Inflater(); decompresser.setInput(prof); byte[] result = new byte[100]; ByteArrayOutputStream bos = new ByteArrayOutputStream(); boolean failed = false; while (!decompresser.finished() && !failed) { try { int resultLength = decompresser.inflate(result); bos.write(result, 0, resultLength); if (resultLength == 0) { // this means more data or an external dictionary is // needed. Both of which are not available, so we // fail. log.debug("Failed to deflate ICC Profile"); failed = true; } } catch (DataFormatException e) { log.debug("Failed to deflate ICC Profile", e); failed = true; } } decompresser.end(); try { iccProf = ColorProfileUtil.getICC_Profile(bos.toByteArray()); } catch (IllegalArgumentException e) { log.debug("Failed to interpret embedded ICC Profile", e); iccProf = null; } } } return iccProf; } private ICC_Profile tryToExctractICCProfileFromJPEGMetadataNode( Element jpgNode) { ICC_Profile iccProf = null; Element jfifNode = ImageIOUtil.getChild(jpgNode, "app0JFIF"); if (jfifNode != null) { Element app2iccNode = ImageIOUtil.getChild(jfifNode, "app2ICC"); if (app2iccNode instanceof IIOMetadataNode) { IIOMetadataNode imn = (IIOMetadataNode) app2iccNode; iccProf = (ICC_Profile) imn.getUserObject(); } } return iccProf; } private BufferedImage getFallbackBufferedImage(ImageReader reader, int pageIndex, ImageReadParam param) throws IOException { //Work-around found at: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4799903 //There are some additional ideas there if someone wants to go further. // Try reading a Raster (no color conversion). Raster raster = reader.readRaster(pageIndex, param); // Arbitrarily select a BufferedImage type. int imageType; int numBands = raster.getNumBands(); switch(numBands) { case 1: imageType = BufferedImage.TYPE_BYTE_GRAY; break; case 3: imageType = BufferedImage.TYPE_3BYTE_BGR; break; case 4: imageType = BufferedImage.TYPE_4BYTE_ABGR; break; default: throw new UnsupportedOperationException("Unsupported band count: " + numBands); } // Create a BufferedImage. BufferedImage bi = new BufferedImage(raster.getWidth(), raster.getHeight(), imageType); // Set the image data. bi.getRaster().setRect(raster); return bi; } static { // TODO: This list could be kept in a resource file. PROVIDERS_IGNORING_ICC .add("Standard PNG image reader/Sun Microsystems, Inc./1.0"); PROVIDERS_IGNORING_ICC .add("Standard PNG image reader/Oracle Corporation/1.0"); PROVIDERS_IGNORING_ICC .add("Standard JPEG Image Reader/Sun Microsystems, Inc./0.5"); PROVIDERS_IGNORING_ICC .add("Standard JPEG Image Reader/Oracle Corporation/0.5"); } } ././@LongLink0100644 0000000 0000000 00000000155 13777276623 011660 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/imageio/PreloaderImageIO.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/imageio/PreloaderImag0100644 0000000 0000000 00000011211 13777276623 032450 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: PreloaderImageIO.java 1452610 2013-03-05 01:00:35Z lbernardo $ */ package org.apache.xmlgraphics.image.loader.impl.imageio; import java.io.IOException; import java.util.Iterator; import javax.imageio.ImageIO; import javax.imageio.ImageReader; import javax.imageio.metadata.IIOMetadata; import javax.imageio.stream.ImageInputStream; import javax.xml.transform.Source; import org.apache.xmlgraphics.image.loader.ImageContext; import org.apache.xmlgraphics.image.loader.ImageException; import org.apache.xmlgraphics.image.loader.ImageInfo; import org.apache.xmlgraphics.image.loader.ImageSize; import org.apache.xmlgraphics.image.loader.impl.AbstractImagePreloader; import org.apache.xmlgraphics.image.loader.util.ImageUtil; /** * Image preloader for images supported by ImageIO. *

    * Note: The implementation relies on the presence of a working ImageIO implementation which * provides accurate image metadata. This is particularly important for PNG image because the * PNG loader relies on that. */ public class PreloaderImageIO extends AbstractImagePreloader { /** {@inheritDoc} * @throws ImageException */ public ImageInfo preloadImage(String uri, Source src, ImageContext context) throws IOException, ImageException { if (!ImageUtil.hasImageInputStream(src)) { return null; } ImageInputStream in = ImageUtil.needImageInputStream(src); Iterator iter = ImageIO.getImageReaders(in); if (!iter.hasNext()) { return null; } IOException firstIOException = null; IIOMetadata iiometa = null; ImageSize size = null; String mime = null; while (iter.hasNext()) { in.mark(); ImageReader reader = (ImageReader)iter.next(); try { reader.setInput(ImageUtil.ignoreFlushing(in), true, false); final int imageIndex = 0; iiometa = reader.getImageMetadata(imageIndex); size = new ImageSize(); size.setSizeInPixels(reader.getWidth(imageIndex), reader.getHeight(imageIndex)); mime = reader.getOriginatingProvider().getMIMETypes()[0]; break; } catch (IOException ioe) { //remember the first exception, ignore all others and continue if (firstIOException == null) { firstIOException = ioe; } } finally { reader.dispose(); in.reset(); } } if (iiometa == null) { if (firstIOException == null) { throw new ImageException("Could not extract image metadata"); } else { throw new ImageException("I/O error while extracting image metadata" + (firstIOException.getMessage() != null ? ": " + firstIOException.getMessage() : ""), firstIOException); } } //Resolution (first a default, then try to read the metadata) size.setResolution(context.getSourceResolution()); ImageIOUtil.extractResolution(iiometa, size); if (size.getWidthPx() <= 0 || size.getHeightPx() <= 0) { //Watch out for a special case: a TGA image was erroneously identified //as a WBMP image by a Sun ImageIO codec. return null; } if (size.getWidthMpt() == 0) { size.calcSizeFromPixels(); } ImageInfo info = new ImageInfo(uri, mime); info.getCustomObjects().put(ImageIOUtil.IMAGEIO_METADATA, iiometa); info.setSize(size); return info; } /** {@inheritDoc} */ public int getPriority() { //Lower priority than default to give the specialized preloaders a chance. return 2 * DEFAULT_PRIORITY; } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/imageio/package.html0100644 0000000 0000000 00000001707 13777276623 032304 0ustar000000000 0000000 org.apache.fop.image2.impl.imageio Package

    Contains an implementation of an image loader which uses ImageIO.

    xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/impl/package.html0100644 0000000 0000000 00000001667 13777276623 030677 0ustar000000000 0000000 org.apache.fop.image2.impl Package

    Contains implementations of image loaders and converters.

    xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/package.html0100644 0000000 0000000 00000001736 13777276623 027733 0ustar000000000 0000000 org.apache.fop.image2 Package

    Contains image loading and conversion infrastructure for various image sources and an image cache.

    ././@LongLink0100644 0000000 0000000 00000000154 13777276623 011657 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/pipeline/ImageConversionEdge.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/pipeline/ImageConversionEd0100644 0000000 0000000 00000004615 13777276623 032542 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageConversionEdge.java 924666 2010-03-18 08:26:30Z jeremias $ */ package org.apache.xmlgraphics.image.loader.pipeline; import org.apache.xmlgraphics.image.loader.spi.ImageConverter; import org.apache.xmlgraphics.image.loader.util.Penalty; import org.apache.xmlgraphics.util.dijkstra.Edge; import org.apache.xmlgraphics.util.dijkstra.Vertex; /** * Represents an image conversion. The class basically wraps an ImageConverter so it can be * used with Dijkstra's shortest route algorithm to build image conversion pipelines. */ class ImageConversionEdge implements Edge { private ImageRepresentation source; private ImageRepresentation target; private ImageConverter converter; private int penalty; /** * Main constructor. * @param converter the image converter * @param penalty the penalty for this edge */ public ImageConversionEdge(ImageConverter converter, Penalty penalty) { this.converter = converter; this.source = new ImageRepresentation(converter.getSourceFlavor()); this.target = new ImageRepresentation(converter.getTargetFlavor()); this.penalty = Math.max(0, penalty.getValue()); } /** * Returns the wrapped ImageConverter. * @return the ImageConverter */ public ImageConverter getImageConverter() { return this.converter; } /** {@inheritDoc} */ public int getPenalty() { return this.penalty; } /** {@inheritDoc} */ public Vertex getStart() { return this.source; } /** {@inheritDoc} */ public Vertex getEnd() { return this.target; } } ././@LongLink0100644 0000000 0000000 00000000156 13777276623 011661 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/pipeline/ImageProviderPipeline.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/pipeline/ImageProviderPipe0100644 0000000 0000000 00000027620 13777276623 032555 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageProviderPipeline.java 1804124 2017-08-04 14:13:54Z ssteiner $ */ package org.apache.xmlgraphics.image.loader.pipeline; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.Collections; import java.util.List; import java.util.Map; import org.apache.commons.io.IOUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.xmlgraphics.image.loader.Image; import org.apache.xmlgraphics.image.loader.ImageException; import org.apache.xmlgraphics.image.loader.ImageFlavor; import org.apache.xmlgraphics.image.loader.ImageInfo; import org.apache.xmlgraphics.image.loader.ImageSessionContext; import org.apache.xmlgraphics.image.loader.cache.ImageCache; import org.apache.xmlgraphics.image.loader.impl.ImageRawStream; import org.apache.xmlgraphics.image.loader.spi.ImageConverter; import org.apache.xmlgraphics.image.loader.spi.ImageImplRegistry; import org.apache.xmlgraphics.image.loader.spi.ImageLoader; import org.apache.xmlgraphics.image.loader.util.Penalty; /** * Represents a pipeline of ImageConverters with an ImageLoader at the beginning of the * pipeline. */ public class ImageProviderPipeline { /** logger */ protected static final Log log = LogFactory.getLog(ImageProviderPipeline.class); private ImageCache cache; private ImageLoader loader; private List converters = new java.util.ArrayList(); /** * Main constructor. * @param cache the image cache (may be null if no caching is desired) * @param loader the image loader to drive the pipeline with */ public ImageProviderPipeline(ImageCache cache, ImageLoader loader) { this.cache = cache; setImageLoader(loader); } /** * Constructor for operation without caching. * @param loader the image loader to drive the pipeline with */ public ImageProviderPipeline(ImageLoader loader) { this(null, loader); } /** * Default constructor without caching and without an ImageLoader (or the ImageLoader may * be set later). */ public ImageProviderPipeline() { this(null, null); } /** * Executes the image converter pipeline. First, the image indicated by the ImageInfo instance * is loaded through an ImageLoader and then optionally converted by a series of * ImageConverters. At the end of the pipeline, the fully loaded and converted image is * returned. * @param info the image info object indicating the image to load * @param hints a Map of image conversion hints * @param context the session context * @return the requested image * @throws ImageException if an error occurs while loader or converting the image * @throws IOException if an I/O error occurs */ public Image execute(ImageInfo info, Map hints, ImageSessionContext context) throws ImageException, IOException { return execute(info, null, hints, context); } /** * Executes the image converter pipeline. First, the image indicated by the ImageInfo instance * is loaded through an ImageLoader and then optionally converted by a series of * ImageConverters. At the end of the pipeline, the fully loaded and converted image is * returned. * @param info the image info object indicating the image to load * @param originalImage the original image to start the pipeline off or null if an ImageLoader * is used * @param hints a Map of image conversion hints * @param context the session context * @return the requested image * @throws ImageException if an error occurs while loader or converting the image * @throws IOException if an I/O error occurs */ public Image execute(ImageInfo info, Image originalImage, Map hints, ImageSessionContext context) throws ImageException, IOException { if (hints == null) { hints = Collections.EMPTY_MAP; } long start = System.currentTimeMillis(); Image img = null; //Remember the last image in the pipeline that is cacheable and cache that. Image lastCacheableImage = null; int converterCount = converters.size(); int startingPoint = 0; if (cache != null) { for (int i = converterCount - 1; i >= 0; i--) { ImageConverter converter = getConverter(i); ImageFlavor flavor = converter.getTargetFlavor(); img = cache.getImage(info, flavor); if (img != null) { startingPoint = i + 1; break; } } if (img == null && loader != null) { //try target flavor of loader from cache ImageFlavor flavor = loader.getTargetFlavor(); img = cache.getImage(info, flavor); } } if (img == null && originalImage != null) { img = originalImage; } boolean entirelyInCache = true; long duration; if (img == null && loader != null) { //Load image img = loader.loadImage(info, hints, context); if (log.isTraceEnabled()) { duration = System.currentTimeMillis() - start; log.trace("Image loading using " + loader + " took " + duration + " ms."); } //Caching entirelyInCache = false; if (img.isCacheable()) { lastCacheableImage = img; } } if (img == null) { throw new ImageException( "Pipeline fails. No ImageLoader and no original Image available."); } if (converterCount > 0) { for (int i = startingPoint; i < converterCount; i++) { ImageConverter converter = getConverter(i); start = System.currentTimeMillis(); img = converter.convert(img, hints); if (log.isTraceEnabled()) { duration = System.currentTimeMillis() - start; log.trace("Image conversion using " + converter + " took " + duration + " ms."); } //Caching entirelyInCache = false; if (img.isCacheable()) { lastCacheableImage = img; } } } //Note: Currently we just cache the end result of the pipeline, not all intermediate //results as it is expected that the cache hit ration would be rather small. if (cache != null && !entirelyInCache) { if (lastCacheableImage == null) { //Try to make the Image cacheable lastCacheableImage = forceCaching(img); } if (lastCacheableImage != null) { if (log.isTraceEnabled()) { log.trace("Caching image: " + lastCacheableImage); } cache.putImage(lastCacheableImage); } } return img; } private ImageConverter getConverter(int index) { return (ImageConverter)converters.get(index); } /** * In some cases the provided Image is not cacheable, nor is any of the intermediate Image * instances (for example, when loading a raw JPEG file). If the image is loaded over a * potentially slow network, it is preferrable to download the whole file and cache it * in memory or in a temporary file. It's not always possible to convert an Image into a * cacheable variant. * @param img the Image to investigate * @return the converted, cacheable Image or null if the Image cannot be converted * @throws IOException if an I/O error occurs */ protected Image forceCaching(Image img) throws IOException { if (img instanceof ImageRawStream) { ImageRawStream raw = (ImageRawStream)img; if (log.isDebugEnabled()) { log.debug("Image is made cacheable: " + img.getInfo()); } //Read the whole stream and hold it in memory so the image can be cached ByteArrayOutputStream baout = new ByteArrayOutputStream(); InputStream in = raw.createInputStream(); try { IOUtils.copy(in, baout); } finally { IOUtils.closeQuietly(in); } final byte[] data = baout.toByteArray(); raw.setInputStreamFactory(new ImageRawStream.ByteArrayStreamFactory(data)); return raw; } return null; } /** * Sets the ImageLoader that is used at the beginning of the pipeline if the image is not * loaded, yet. * @param imageLoader the image loader implementation */ public void setImageLoader(ImageLoader imageLoader) { this.loader = imageLoader; } /** * Adds an additional ImageConverter to the end of the pipeline. * @param converter the ImageConverter instance */ public void addConverter(ImageConverter converter) { //TODO check for compatibility this.converters.add(converter); } /** {@inheritDoc} */ public String toString() { StringBuffer sb = new StringBuffer(); sb.append("Loader: ").append(loader); if (converters.size() > 0) { sb.append(" Converters: "); sb.append(converters); } return sb.toString(); } /** * Returns the overall conversion penalty for the pipeline. This can be used to choose among * different possible pipelines. * @return the overall penalty (a non-negative integer) */ public int getConversionPenalty() { return getConversionPenalty(null).getValue(); } /** * Returns the overall conversion penalty for the pipeline. This can be used to choose among * different possible pipelines. * @param registry the image implementation registry * @return the overall penalty (a non-negative integer) */ public Penalty getConversionPenalty(ImageImplRegistry registry) { Penalty penalty = Penalty.ZERO_PENALTY; if (loader != null) { penalty = penalty.add(loader.getUsagePenalty()); if (registry != null) { penalty = penalty.add( registry.getAdditionalPenalty(loader.getClass().getName())); } } for (Object converter1 : converters) { ImageConverter converter = (ImageConverter) converter1; penalty = penalty.add(converter.getConversionPenalty()); if (registry != null) { penalty = penalty.add( registry.getAdditionalPenalty(converter.getClass().getName())); } } return penalty; } /** * Returns the target flavor generated by this pipeline. * @return the target flavor */ public ImageFlavor getTargetFlavor() { if (converters.size() > 0) { return getConverter(converters.size() - 1).getTargetFlavor(); } else if (this.loader != null) { return this.loader.getTargetFlavor(); } else { return null; } } } ././@LongLink0100644 0000000 0000000 00000000154 13777276623 011657 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/pipeline/ImageRepresentation.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/pipeline/ImageRepresentati0100644 0000000 0000000 00000004316 13777276623 032607 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageRepresentation.java 1681108 2015-05-22 13:26:12Z ssteiner $ */ package org.apache.xmlgraphics.image.loader.pipeline; import org.apache.xmlgraphics.image.loader.ImageFlavor; import org.apache.xmlgraphics.util.dijkstra.Vertex; /** * This class represents a combination of MIME type and an image flavor. * It is used in conjunction with Dijkstra's algorithm to find and construct a * conversion pipeline for images. */ public class ImageRepresentation implements Vertex { private ImageFlavor flavor; /** * Main constructor * @param flavor the image flavor */ public ImageRepresentation(ImageFlavor flavor) { if (flavor == null) { throw new NullPointerException("flavor must not be null"); } this.flavor = flavor; } /** * Returns the image flavor. * @return the image flavor */ public ImageFlavor getFlavor() { return flavor; } /** {@inheritDoc} */ public boolean equals(Object obj) { assert obj != null; return toString().equals(obj.toString()); } /** {@inheritDoc} */ public int hashCode() { return getFlavor().hashCode(); } /** {@inheritDoc} */ public int compareTo(Object obj) { return toString().compareTo(((ImageRepresentation)obj).toString()); } /** {@inheritDoc} */ public String toString() { return getFlavor().toString(); } } ././@LongLink0100644 0000000 0000000 00000000150 13777276623 011653 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/pipeline/PipelineFactory.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/pipeline/PipelineFactory.j0100644 0000000 0000000 00000030474 13777276623 032530 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: PipelineFactory.java 1804124 2017-08-04 14:13:54Z ssteiner $ */ package org.apache.xmlgraphics.image.loader.pipeline; import java.io.Serializable; import java.util.Arrays; import java.util.Collection; import java.util.Comparator; import java.util.LinkedList; import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.xmlgraphics.image.loader.Image; import org.apache.xmlgraphics.image.loader.ImageFlavor; import org.apache.xmlgraphics.image.loader.ImageInfo; import org.apache.xmlgraphics.image.loader.ImageManager; import org.apache.xmlgraphics.image.loader.impl.CompositeImageLoader; import org.apache.xmlgraphics.image.loader.spi.ImageConverter; import org.apache.xmlgraphics.image.loader.spi.ImageImplRegistry; import org.apache.xmlgraphics.image.loader.spi.ImageLoader; import org.apache.xmlgraphics.image.loader.spi.ImageLoaderFactory; import org.apache.xmlgraphics.image.loader.util.Penalty; import org.apache.xmlgraphics.util.dijkstra.DefaultEdgeDirectory; import org.apache.xmlgraphics.util.dijkstra.DijkstraAlgorithm; import org.apache.xmlgraphics.util.dijkstra.Vertex; /** * Factory class for image processing pipelines. */ public class PipelineFactory { /** logger */ protected static final Log log = LogFactory.getLog(PipelineFactory.class); private ImageManager manager; private int converterEdgeDirectoryVersion = -1; /** Holds the EdgeDirectory for all image conversions */ private DefaultEdgeDirectory converterEdgeDirectory; /** * Main constructor. * @param manager the ImageManager instance */ public PipelineFactory(ImageManager manager) { this.manager = manager; } private DefaultEdgeDirectory getEdgeDirectory() { ImageImplRegistry registry = manager.getRegistry(); if (registry.getImageConverterModifications() != converterEdgeDirectoryVersion) { Collection converters = registry.getImageConverters(); //Rebuild edge directory DefaultEdgeDirectory dir = new DefaultEdgeDirectory(); for (Object converter1 : converters) { ImageConverter converter = (ImageConverter) converter1; Penalty penalty = Penalty.toPenalty(converter.getConversionPenalty()); penalty = penalty.add( registry.getAdditionalPenalty(converter.getClass().getName())); dir.addEdge(new ImageConversionEdge(converter, penalty)); } converterEdgeDirectoryVersion = registry.getImageConverterModifications(); this.converterEdgeDirectory = dir; //Replace (thread-safe) } return this.converterEdgeDirectory; } /** * Creates and returns an {@link ImageProviderPipeline} that allows to load an image of the * given MIME type and present it in the requested image flavor. * @param originalImage the original image that serves as the origin point of the conversion * @param targetFlavor the requested image flavor * @return an {@link ImageProviderPipeline} or null if no suitable pipeline could be assembled */ public ImageProviderPipeline newImageConverterPipeline( Image originalImage, ImageFlavor targetFlavor) { //Get snapshot to avoid concurrent modification problems (thread-safety) DefaultEdgeDirectory dir = getEdgeDirectory(); ImageRepresentation destination = new ImageRepresentation(targetFlavor); ImageProviderPipeline pipeline = findPipeline(dir, originalImage.getFlavor(), destination); return pipeline; } /** * Creates and returns an {@link ImageProviderPipeline} that allows to load an image of the * given MIME type and present it in the requested image flavor. * @param imageInfo the image info object of the original image * @param targetFlavor the requested image flavor * @return an {@link ImageProviderPipeline} or null if no suitable pipeline could be assembled */ public ImageProviderPipeline newImageConverterPipeline( ImageInfo imageInfo, ImageFlavor targetFlavor) { ImageProviderPipeline[] candidates = determineCandidatePipelines(imageInfo, targetFlavor); //Choose best pipeline if (candidates.length > 0) { Arrays.sort(candidates, new PipelineComparator()); ImageProviderPipeline pipeline = (ImageProviderPipeline)candidates[0]; if (pipeline != null && log.isDebugEnabled()) { log.debug("Pipeline: " + pipeline + " with penalty " + pipeline.getConversionPenalty()); } return pipeline; } else { return null; } } /** * Determines all possible pipelines for the given image that can produce the requested * target flavor. * @param imageInfo the image information * @param targetFlavor the target flavor * @return the candidate pipelines */ public ImageProviderPipeline[] determineCandidatePipelines( ImageInfo imageInfo, ImageFlavor targetFlavor) { String originalMime = imageInfo.getMimeType(); ImageImplRegistry registry = manager.getRegistry(); List candidates = new java.util.ArrayList(); //Get snapshot to avoid concurrent modification problems (thread-safety) DefaultEdgeDirectory dir = getEdgeDirectory(); ImageLoaderFactory[] loaderFactories = registry.getImageLoaderFactories( imageInfo, targetFlavor); if (loaderFactories != null) { //Directly load image and return it ImageLoader loader; if (loaderFactories.length == 1) { loader = loaderFactories[0].newImageLoader(targetFlavor); } else { int count = loaderFactories.length; ImageLoader[] loaders = new ImageLoader[count]; for (int i = 0; i < count; i++) { loaders[i] = loaderFactories[i].newImageLoader(targetFlavor); } loader = new CompositeImageLoader(loaders); } ImageProviderPipeline pipeline = new ImageProviderPipeline(manager.getCache(), loader); candidates.add(pipeline); } else { //Need to use ImageConverters if (log.isTraceEnabled()) { log.trace("No ImageLoaderFactory found that can load this format (" + targetFlavor + ") directly. Trying ImageConverters instead..."); } ImageRepresentation destination = new ImageRepresentation(targetFlavor); //Get Loader for originalMIME // --> List of resulting flavors, possibly multiple loaders loaderFactories = registry.getImageLoaderFactories(originalMime); if (loaderFactories != null) { //Find best pipeline -> best loader for (ImageLoaderFactory loaderFactory : loaderFactories) { ImageFlavor[] flavors = loaderFactory.getSupportedFlavors(originalMime); for (ImageFlavor flavor : flavors) { ImageProviderPipeline pipeline = findPipeline(dir, flavor, destination); if (pipeline != null) { ImageLoader loader = loaderFactory.newImageLoader(flavor); pipeline.setImageLoader(loader); candidates.add(pipeline); } } } } } return (ImageProviderPipeline[])candidates.toArray( new ImageProviderPipeline[candidates.size()]); } /** Compares two pipelines based on their conversion penalty. */ private static class PipelineComparator implements Comparator, Serializable { private static final long serialVersionUID = 1161513617996198090L; public int compare(Object o1, Object o2) { ImageProviderPipeline p1 = (ImageProviderPipeline)o1; ImageProviderPipeline p2 = (ImageProviderPipeline)o2; //Lowest penalty first return p1.getConversionPenalty() - p2.getConversionPenalty(); } } private ImageProviderPipeline findPipeline(DefaultEdgeDirectory dir, ImageFlavor originFlavor, ImageRepresentation destination) { DijkstraAlgorithm dijkstra = new DijkstraAlgorithm( dir); ImageRepresentation origin = new ImageRepresentation(originFlavor); dijkstra.execute(origin, destination); if (log.isTraceEnabled()) { log.trace("Lowest penalty: " + dijkstra.getLowestPenalty(destination)); } Vertex prev = destination; Vertex pred = dijkstra.getPredecessor(destination); if (pred == null) { if (log.isTraceEnabled()) { log.trace("No route found!"); } return null; } else { LinkedList stops = new LinkedList(); while ((pred = dijkstra.getPredecessor(prev)) != null) { ImageConversionEdge edge = (ImageConversionEdge) dir.getBestEdge(pred, prev); stops.addFirst(edge); prev = pred; } ImageProviderPipeline pipeline = new ImageProviderPipeline(manager.getCache(), null); for (Object stop : stops) { ImageConversionEdge edge = (ImageConversionEdge) stop; pipeline.addConverter(edge.getImageConverter()); } return pipeline; } } /** * Finds and returns an array of {@link ImageProviderPipeline} instances which can handle * the given MIME type and return one of the given {@link ImageFlavor}s. * @param imageInfo the image info object * @param flavors the possible target flavors * @return an array of pipelines */ public ImageProviderPipeline[] determineCandidatePipelines(ImageInfo imageInfo, ImageFlavor[] flavors) { List candidates = new java.util.ArrayList(); for (ImageFlavor flavor : flavors) { //Find the best pipeline for each flavor ImageProviderPipeline pipeline = newImageConverterPipeline(imageInfo, flavor); if (pipeline == null) { continue; //No suitable pipeline found for flavor } Penalty p = pipeline.getConversionPenalty(this.manager.getRegistry()); if (!p.isInfinitePenalty()) { candidates.add(pipeline); } } return (ImageProviderPipeline[])candidates.toArray( new ImageProviderPipeline[candidates.size()]); } /** * Finds and returns an array of {@link ImageProviderPipeline} instances which can handle * the convert the given {@link Image} and return one of the given {@link ImageFlavor}s. * @param sourceImage the image to be converted * @param flavors the possible target flavors * @return an array of pipelines */ public ImageProviderPipeline[] determineCandidatePipelines(Image sourceImage, ImageFlavor[] flavors) { List candidates = new java.util.ArrayList(); for (ImageFlavor flavor : flavors) { //Find the best pipeline for each flavor ImageProviderPipeline pipeline = newImageConverterPipeline(sourceImage, flavor); if (pipeline != null) { candidates.add(pipeline); } } return (ImageProviderPipeline[])candidates.toArray( new ImageProviderPipeline[candidates.size()]); } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/pipeline/package.html0100644 0000000 0000000 00000001664 13777276623 031540 0ustar000000000 0000000 org.apache.fop.image2.pipeline Package

    Provides an image loading and processing pipeline.

    xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/spi/ImageConverter.java0100644 0000000 0000000 00000005135 13777276623 032017 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageConverter.java 1400596 2012-10-21 08:49:02Z gadams $ */ package org.apache.xmlgraphics.image.loader.spi; import java.io.IOException; import java.util.Map; import org.apache.xmlgraphics.image.loader.Image; import org.apache.xmlgraphics.image.loader.ImageException; import org.apache.xmlgraphics.image.loader.ImageFlavor; /** * Defines an image converter that can convert one image representation into another. */ public interface ImageConverter { /** Used if the conversion penalty is negligible (for example a simple cast). */ int NO_CONVERSION_PENALTY = 0; /** Used if the conversion penalty is minimal */ int MINIMAL_CONVERSION_PENALTY = 1; /** Default/Medium conversion penalty (if there's some effort to convert the image format) */ int MEDIUM_CONVERSION_PENALTY = 10; /** * Converts an image into a different representation. *

    Consumers can get the effective MIME type (if any) from the * associated {@link ImageFlavor}. * @param src the source image * @param hints the conversion hints * @return the converted image * @throws ImageException if an error occurs while converting the image * @throws IOException if an I/O error occurs while converting the image */ Image convert(Image src, Map hints) throws ImageException, IOException; /** * Returns the flavor that this converter converts images into. * @return the target flavor */ ImageFlavor getTargetFlavor(); /** * Returns the flavor that this converter expects. * @return the source flavor */ ImageFlavor getSourceFlavor(); /** * Returns the conversion penalty for the conversion that this implementation supports. * @return the conversion penalty (must be a non-negative integer) */ int getConversionPenalty(); } ././@LongLink0100644 0000000 0000000 00000000145 13777276623 011657 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/spi/ImageImplRegistry.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/spi/ImageImplRegistry.java0100644 0000000 0000000 00000037042 13777276623 032504 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageImplRegistry.java 1804124 2017-08-04 14:13:54Z ssteiner $ */ package org.apache.xmlgraphics.image.loader.spi; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.xmlgraphics.image.loader.ImageFlavor; import org.apache.xmlgraphics.image.loader.ImageInfo; import org.apache.xmlgraphics.image.loader.util.Penalty; import org.apache.xmlgraphics.util.Service; /** * This class is the registry for all implementations of the various service provider interfaces * for the image package. */ public class ImageImplRegistry { /** logger */ protected static final Log log = LogFactory.getLog(ImageImplRegistry.class); /** Infinite penalty value which shall force any implementation to become ineligible. */ public static final int INFINITE_PENALTY = Integer.MAX_VALUE; /** Holds the list of preloaders */ private List preloaders = new java.util.ArrayList(); //Content: List private int lastPreloaderIdentifier; private int lastPreloaderSort; /** Holds the list of ImageLoaderFactories */ private Map loaders = new java.util.HashMap(); //Content: Map> /** Holds the list of ImageConverters */ private List converters = new java.util.ArrayList(); //Content: List private int converterModifications; /** A Map (key: implementation classes) with additional penalties to fine-tune the registry. */ private Map additionalPenalties = new java.util.HashMap(); // //Note: String as key chosen to avoid possible class-unloading leaks /** Singleton instance */ private static ImageImplRegistry defaultInstance = new ImageImplRegistry(); /** * Main constructor. This constructor allows to disable plug-in discovery for testing purposes. * @param discover true if implementation classes shall automatically be discovered. */ public ImageImplRegistry(boolean discover) { if (discover) { discoverClasspathImplementations(); } } /** * Main constructor. */ public ImageImplRegistry() { this(true); } /** * Returns the default instance of the Image implementation registry. * @return the default instance */ public static ImageImplRegistry getDefaultInstance() { return defaultInstance; } /** * Discovers all implementations in the application's classpath. */ public void discoverClasspathImplementations() { //Dynamic registration of ImagePreloaders Iterator iter = Service.providers(ImagePreloader.class); while (iter.hasNext()) { registerPreloader((ImagePreloader)iter.next()); } //Dynamic registration of ImageLoaderFactories iter = Service.providers(ImageLoaderFactory.class); while (iter.hasNext()) { registerLoaderFactory((ImageLoaderFactory)iter.next()); } //Dynamic registration of ImageConverters iter = Service.providers(ImageConverter.class); while (iter.hasNext()) { registerConverter((ImageConverter)iter.next()); } } /** * Registers a new ImagePreloader. * @param preloader An ImagePreloader instance */ public void registerPreloader(ImagePreloader preloader) { if (log.isDebugEnabled()) { log.debug("Registered " + preloader.getClass().getName() + " with priority " + preloader.getPriority()); } preloaders.add(newPreloaderHolder(preloader)); } private synchronized PreloaderHolder newPreloaderHolder(ImagePreloader preloader) { PreloaderHolder holder = new PreloaderHolder(); holder.preloader = preloader; holder.identifier = ++lastPreloaderIdentifier; return holder; } /** Holder class for registered {@link ImagePreloader} instances. */ private static class PreloaderHolder { private ImagePreloader preloader; private int identifier; public String toString() { return preloader + " " + identifier; } } private synchronized void sortPreloaders() { if (this.lastPreloaderIdentifier != this.lastPreloaderSort) { Collections.sort(this.preloaders, new Comparator() { public int compare(Object o1, Object o2) { PreloaderHolder h1 = (PreloaderHolder)o1; long p1 = h1.preloader.getPriority(); p1 += getAdditionalPenalty(h1.preloader.getClass().getName()).getValue(); PreloaderHolder h2 = (PreloaderHolder)o2; int p2 = h2.preloader.getPriority(); p2 += getAdditionalPenalty(h2.preloader.getClass().getName()).getValue(); int diff = Penalty.truncate(p1 - p2); if (diff != 0) { return diff; } else { diff = h1.identifier - h2.identifier; return diff; } } }); this.lastPreloaderSort = lastPreloaderIdentifier; } } /** * Registers a new ImageLoaderFactory. * @param loaderFactory An ImageLoaderFactory instance */ public void registerLoaderFactory(ImageLoaderFactory loaderFactory) { if (!loaderFactory.isAvailable()) { if (log.isDebugEnabled()) { log.debug("ImageLoaderFactory reports not available: " + loaderFactory.getClass().getName()); } return; } String[] mimes = loaderFactory.getSupportedMIMETypes(); for (String mime : mimes) { synchronized (loaders) { Map flavorMap = (Map) loaders.get(mime); if (flavorMap == null) { flavorMap = new HashMap(); loaders.put(mime, flavorMap); } ImageFlavor[] flavors = loaderFactory.getSupportedFlavors(mime); for (ImageFlavor flavor : flavors) { List factoryList = (List) flavorMap.get(flavor); if (factoryList == null) { factoryList = new ArrayList(); flavorMap.put(flavor, factoryList); } factoryList.add(loaderFactory); if (log.isDebugEnabled()) { log.debug("Registered " + loaderFactory.getClass().getName() + ": MIME = " + mime + ", Flavor = " + flavor); } } } } } /** * Returns the Collection of registered ImageConverter instances. * @return a Collection<ImageConverter> */ public Collection getImageConverters() { return Collections.unmodifiableList(this.converters); } /** * Returns the number of modifications to the collection of registered ImageConverter instances. * This is used to detect changes in the registry concerning ImageConverters. * @return the number of modifications */ public int getImageConverterModifications() { return this.converterModifications; } /** * Registers a new ImageConverter. * @param converter An ImageConverter instance */ public void registerConverter(ImageConverter converter) { converters.add(converter); converterModifications++; if (log.isDebugEnabled()) { log.debug("Registered: " + converter.getClass().getName()); } } /** * Returns an iterator over all registered ImagePreloader instances. * @return an iterator over ImagePreloader instances. */ public Iterator getPreloaderIterator() { sortPreloaders(); final Iterator iter = this.preloaders.iterator(); //Unpack the holders MyIterator i = new MyIterator(); i.iter = iter; return i; } static class MyIterator implements Iterator { Iterator iter; public boolean hasNext() { return iter.hasNext(); } public Object next() { Object obj = iter.next(); if (obj != null) { return ((PreloaderHolder)obj).preloader; } else { return null; } } public void remove() { iter.remove(); } } /** * Returns the best ImageLoaderFactory supporting the {@link ImageInfo} and image flavor. * If there are multiple ImageLoaderFactories the one with the least usage penalty is selected. * @param imageInfo the image info object * @param flavor the image flavor. * @return an ImageLoaderFactory instance or null, if no suitable implementation was found */ public ImageLoaderFactory getImageLoaderFactory(ImageInfo imageInfo, ImageFlavor flavor) { String mime = imageInfo.getMimeType(); Map flavorMap = (Map)loaders.get(mime); if (flavorMap != null) { List factoryList = (List)flavorMap.get(flavor); if (factoryList != null && factoryList.size() > 0) { Iterator iter = factoryList.iterator(); int bestPenalty = Integer.MAX_VALUE; ImageLoaderFactory bestFactory = null; while (iter.hasNext()) { ImageLoaderFactory factory = (ImageLoaderFactory)iter.next(); if (!factory.isSupported(imageInfo)) { continue; } ImageLoader loader = factory.newImageLoader(flavor); int penalty = loader.getUsagePenalty(); if (penalty < bestPenalty) { bestPenalty = penalty; bestFactory = factory; } } return bestFactory; } } return null; } /** * Returns an array of {@link ImageLoaderFactory} instances that support the MIME type * indicated by an {@link ImageInfo} object and can generate the given image flavor. * @param imageInfo the image info object * @param flavor the target image flavor * @return the array of image loader factories */ public ImageLoaderFactory[] getImageLoaderFactories(ImageInfo imageInfo, ImageFlavor flavor) { String mime = imageInfo.getMimeType(); Collection matches = new java.util.TreeSet(new ImageLoaderFactoryComparator(flavor)); Map flavorMap = (Map) loaders.get(mime); if (flavorMap != null) { for (Object i : flavorMap.entrySet()) { Map.Entry e = (Map.Entry) i; ImageFlavor checkFlavor = (ImageFlavor) e.getKey(); if (checkFlavor.isCompatible(flavor)) { List factoryList = (List)e.getValue(); if (factoryList != null && factoryList.size() > 0) { for (Object aFactoryList : factoryList) { ImageLoaderFactory factory = (ImageLoaderFactory) aFactoryList; if (factory.isSupported(imageInfo)) { matches.add(factory); } } } } } } if (matches.size() == 0) { return null; } else { return (ImageLoaderFactory[])matches.toArray(new ImageLoaderFactory[matches.size()]); } } /** Comparator for {@link ImageLoaderFactory} classes. */ private class ImageLoaderFactoryComparator implements Comparator { private ImageFlavor targetFlavor; public ImageLoaderFactoryComparator(ImageFlavor targetFlavor) { this.targetFlavor = targetFlavor; } public int compare(Object o1, Object o2) { ImageLoaderFactory f1 = (ImageLoaderFactory)o1; ImageLoader l1 = f1.newImageLoader(targetFlavor); long p1 = l1.getUsagePenalty(); p1 += getAdditionalPenalty(l1.getClass().getName()).getValue(); ImageLoaderFactory f2 = (ImageLoaderFactory)o2; ImageLoader l2 = f2.newImageLoader(targetFlavor); // long p2 = l2.getUsagePenalty(); long p2 = getAdditionalPenalty(l2.getClass().getName()).getValue(); //Lowest penalty first return Penalty.truncate(p1 - p2); } } /** * Returns an array of ImageLoaderFactory instances which support the given MIME type. The * instances are returned in no particular order. * @param mime the MIME type to find ImageLoaderFactories for * @return the array of ImageLoaderFactory instances */ public ImageLoaderFactory[] getImageLoaderFactories(String mime) { Map flavorMap = (Map)loaders.get(mime); if (flavorMap != null) { Set factories = new java.util.HashSet(); for (Object o : flavorMap.values()) { List factoryList = (List) o; factories.addAll(factoryList); } int factoryCount = factories.size(); if (factoryCount > 0) { return (ImageLoaderFactory[])factories.toArray( new ImageLoaderFactory[factoryCount]); } } return new ImageLoaderFactory[0]; } /** * Sets an additional penalty for a particular implementation class for any of the interface * administered by this registry class. No checking is performed to verify if the className * parameter is valid. * @param className the fully qualified class name of the implementation class * @param penalty the additional penalty or null to clear any existing value */ public void setAdditionalPenalty(String className, Penalty penalty) { if (penalty != null) { this.additionalPenalties.put(className, penalty); } else { this.additionalPenalties.remove(className); } this.lastPreloaderSort = -1; //Force resort, just in case this was a preloader } /** * Returns the additional penalty value set for a particular implementation class. * If no such value is set, 0 is returned. * @param className the fully qualified class name of the implementation class * @return the additional penalty value */ public Penalty getAdditionalPenalty(String className) { Penalty p = (Penalty)this.additionalPenalties.get(className); return (p != null ? p : Penalty.ZERO_PENALTY); } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/spi/ImageLoader.java0100644 0000000 0000000 00000006175 13777276623 031263 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageLoader.java 924666 2010-03-18 08:26:30Z jeremias $ */ package org.apache.xmlgraphics.image.loader.spi; import java.io.IOException; import java.util.Map; import org.apache.xmlgraphics.image.loader.Image; import org.apache.xmlgraphics.image.loader.ImageException; import org.apache.xmlgraphics.image.loader.ImageFlavor; import org.apache.xmlgraphics.image.loader.ImageInfo; import org.apache.xmlgraphics.image.loader.ImageSessionContext; /** * This interface is implemented by classes which load images from a source. Normally, such a * source will be an InputStream but can also be something else. */ public interface ImageLoader { /** Used if the loading penalty is negligible (image doesn't need to be decoded). */ int NO_LOADING_PENALTY = 0; /** Default/Medium conversion penalty (if there's some effort to load the image format) */ int MEDIUM_LOADING_PENALTY = 10; /** * Loads and returns an image. * @param info the image info object indicating the image * @param hints a Map of hints that can be used by implementations to customize the loading * process (may be null). * @param session the session context * @return the fully loaded image * @throws ImageException if an error occurs while loading the image * @throws IOException if an I/O error occurs while loading the image */ Image loadImage(ImageInfo info, Map hints, ImageSessionContext session) throws ImageException, IOException; /** * Loads and returns an image. * @param info the image info object indicating the image * @param session the session context * @return the fully loaded image * @throws ImageException if an error occurs while loading the image * @throws IOException if an I/O error occurs while loading the image */ Image loadImage(ImageInfo info, ImageSessionContext session) throws ImageException, IOException; /** * Returns the image flavor that is returned by this ImageLoader implementation. * @return the target image flavor */ ImageFlavor getTargetFlavor(); /** * Returns the penalty assigned to using this image loader. The value is used to select the * best processing chain for images. * @return the usage penalty (must be a non-negative integer) */ int getUsagePenalty(); } ././@LongLink0100644 0000000 0000000 00000000146 13777276623 011660 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/spi/ImageLoaderFactory.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/spi/ImageLoaderFactory.jav0100644 0000000 0000000 00000006712 13777276623 032447 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageLoaderFactory.java 924666 2010-03-18 08:26:30Z jeremias $ */ package org.apache.xmlgraphics.image.loader.spi; import org.apache.xmlgraphics.image.loader.ImageFlavor; import org.apache.xmlgraphics.image.loader.ImageInfo; /** * This interface is implemented to provide information about an ImageLoader and to create new * instances. A separate factory allows implementation to dynamically detect if the underlying * libraries are available in the classpath so the caller can skip this implementation if it's * not functional. */ public interface ImageLoaderFactory { /** * Returns an array of MIME types supported by this implementation. * @return the MIME type array */ String[] getSupportedMIMETypes(); /** * Returns an array of ImageFlavors that are supported by this implementation for a given * MIME type. * @param mime the MIME type * @return the ImageFlavor array */ ImageFlavor[] getSupportedFlavors(String mime); /** * Indicates whether the given image (represented by an {@link ImageInfo} object) is supported * by the loader. By default, implementations return true assuming all images of the supported * MIME types can be processed correctly. In some cases, however, an ImageLoader may only * support a subset of a format because it offers an optimized way to embed the image in * the target format (for example: CCITT compressed TIFF files in PDF and PostScript). For * this to work, the preloader must register some information in the ImageInfo's custom * objects so the factory can identify if an image may or may not be supported. * @param imageInfo the image info object * @return true if the image is supported by the loaders generated by this factory */ boolean isSupported(ImageInfo imageInfo); /** * Creates and returns a new ImageLoader instance. * @param targetFlavor the target image flavor to produce * @return a new ImageLoader instance */ ImageLoader newImageLoader(ImageFlavor targetFlavor); /** * Returns the usage penalty for a particular ImageLoader. This is used to select the best * ImageLoader implementation for loading an image. * @param mime the MIME type * @param flavor the target image flavor * @return the usage penalty (must be a non-negative integer) * @deprecated Redundancy with {@link ImageLoader#getUsagePenalty()} */ int getUsagePenalty(String mime, ImageFlavor flavor); /** * Indicates whether the underlying libraries needed by the implementation are available. * @return true if the implementation is functional. */ boolean isAvailable(); } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/spi/ImagePreloader.java0100644 0000000 0000000 00000005402 13777276623 031762 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImagePreloader.java 750116 2009-03-04 19:23:59Z jeremias $ */ package org.apache.xmlgraphics.image.loader.spi; import java.io.IOException; import javax.xml.transform.Source; import org.apache.xmlgraphics.image.loader.ImageContext; import org.apache.xmlgraphics.image.loader.ImageException; import org.apache.xmlgraphics.image.loader.ImageInfo; /** * This interface provides two functions: determining whether an image format is supported and if * that's the case, some minimal information (mostly the image's intrinsic size) is extracted * and returned. */ public interface ImagePreloader { /** Default priority for preloaders */ int DEFAULT_PRIORITY = 1000; /** * "Preloads" an image, i.e. indentifies whether the source image is supported by this * implementation and determines the image's intrinsic size and possibly some additional * information. The image is usually not fully loaded at this time to conserve memory. * The method returns null if the image was not identified. An {@link ImageException} is only * thrown if the image is identified but some error has happened while working on the file. * @param originalURI the original (unresolved) URI of the image * @param src a image source the image is loaded from * @param context the context object that provides configuration information * @return an image info object with the basic information about an image or null if the * image is not supported by this implementation * @throws ImageException if an error occurs while preloading the image * @throws IOException if an I/O error occurs while preloading the image */ ImageInfo preloadImage(String originalURI, Source src, ImageContext context) throws ImageException, IOException; /** * Returns the priority of the preloader. The lower the value, the higher the preloader's * priority. * @return an integer (default is 1000) */ int getPriority(); } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/spi/package.html0100644 0000000 0000000 00000001676 13777276623 030531 0ustar000000000 0000000 org.apache.fop.image2.spi Package

    Defines service provider interfaces for the image infrastructure.

    ././@LongLink0100644 0000000 0000000 00000000154 13777276623 011657 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/util/ImageInputStreamAdapter.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/util/ImageInputStreamAdapt0100644 0000000 0000000 00000005706 13777276623 032543 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageInputStreamAdapter.java 750418 2009-03-05 11:03:54Z vhennebert $ */ package org.apache.xmlgraphics.image.loader.util; import java.io.IOException; import java.io.InputStream; import javax.imageio.stream.ImageInputStream; /** * Decorates an ImageInputStream with an InputStream interface. The methods mark() * and reset() are fully supported. The method available() will * always return 0. */ public class ImageInputStreamAdapter extends InputStream { private ImageInputStream iin; private long lastMarkPosition; /** * Creates a new ImageInputStreamAdapter. * @param iin the underlying ImageInputStream */ public ImageInputStreamAdapter(ImageInputStream iin) { assert iin != null : "InputStream is null"; this.iin = iin; } /** {@inheritDoc} */ public int read(byte[] b, int off, int len) throws IOException { return iin.read(b, off, len); } /** {@inheritDoc} */ public int read(byte[] b) throws IOException { return iin.read(b); } /** {@inheritDoc} */ public int read() throws IOException { return iin.read(); } /** {@inheritDoc} */ public long skip(long n) throws IOException { return iin.skipBytes(n); } /** {@inheritDoc} */ public void close() throws IOException { iin.close(); iin = null; } /** {@inheritDoc} */ public synchronized void mark(int readlimit) { //Parameter readlimit is ignored try { //Cannot use mark()/reset() since they are nestable, and InputStream's are not this.lastMarkPosition = iin.getStreamPosition(); } catch (IOException ioe) { throw new RuntimeException( "Unexpected IOException in ImageInputStream.getStreamPosition()", ioe); } } /** {@inheritDoc} */ public boolean markSupported() { return true; } /** {@inheritDoc} */ public synchronized void reset() throws IOException { iin.seek(this.lastMarkPosition); } /** {@inheritDoc} */ public int available() throws IOException { return 0; } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/util/ImageUtil.java0100644 0000000 0000000 00000027714 13777276623 031156 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageUtil.java 1681108 2015-05-22 13:26:12Z ssteiner $ */ package org.apache.xmlgraphics.image.loader.util; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.net.URI; import java.net.URISyntaxException; import java.util.Map; import java.util.zip.GZIPInputStream; import javax.imageio.stream.ImageInputStream; import javax.xml.transform.Source; import org.apache.xmlgraphics.image.loader.ImageProcessingHints; import org.apache.xmlgraphics.image.loader.ImageSessionContext; import org.apache.xmlgraphics.image.loader.ImageSource; import org.apache.xmlgraphics.io.XmlSourceUtil; /** * Helper and convenience methods for working with the image package. */ public final class ImageUtil { private ImageUtil() { } /** * Returns the InputStream of a Source object. * @param src the Source object * @return the InputStream (or null if there's not InputStream available) * @deprecated Please use {@link XmlSourceUtil#getInputStream(Source)} instead. */ @Deprecated public static InputStream getInputStream(Source src) { return XmlSourceUtil.getInputStream(src); } /** * Returns the ImageInputStream of a Source object. * @param src the Source object * @return the ImageInputStream (or null if there's not ImageInputStream available) */ public static ImageInputStream getImageInputStream(Source src) { if (src instanceof ImageSource) { return ((ImageSource) src).getImageInputStream(); } else { return null; } } /** * Returns the InputStream of a Source object. This method throws an IllegalArgumentException * if there's no InputStream instance available from the Source object. * @param src the Source object * @return the InputStream * @deprecated use {@link XmlSourceUtil#needInputStream(Source)} instead */ @Deprecated public static InputStream needInputStream(Source src) { return XmlSourceUtil.needInputStream(src); } /** * Returns the ImageInputStream of a Source object. This method throws an * IllegalArgumentException if there's no ImageInputStream instance available from the * Source object. * @param src the Source object * @return the ImageInputStream */ public static ImageInputStream needImageInputStream(Source src) { if (src instanceof ImageSource) { ImageSource isrc = (ImageSource) src; if (isrc.getImageInputStream() == null) { throw new IllegalArgumentException( "ImageInputStream is null/cleared on ImageSource"); } return isrc.getImageInputStream(); } else { throw new IllegalArgumentException("Source must be an ImageSource"); } } /** * Indicates whether the Source object has an InputStream instance. * @param src the Source object * @return true if an InputStream is available */ public static boolean hasInputStream(Source src) { return XmlSourceUtil.hasInputStream(src) || hasImageInputStream(src); } /** * Indicates whether the Source object has a Reader instance. * @param src the Source object * @return true if an Reader is available * @deprecated use {@link XmlSourceUtil#hasReader(Source)} instead */ @Deprecated public static boolean hasReader(Source src) { return XmlSourceUtil.hasReader(src); } /** * Indicates whether the Source object has an ImageInputStream instance. * @param src the Source object * @return true if an ImageInputStream is available */ public static boolean hasImageInputStream(Source src) { return getImageInputStream(src) != null; } /** * Removes any references to InputStreams or Readers from the given Source to prohibit * accidental/unwanted use by a component further downstream. * @param src the Source object * @deprecated use {@link XmlSourceUtil#removeStreams(Source)} instead */ @Deprecated public static void removeStreams(Source src) { XmlSourceUtil.removeStreams(src); } /** * Closes the InputStreams or ImageInputStreams of Source objects. Any exception occurring * while closing the stream is ignored. * @param src the Source object * @deprecated use {@link XmlSourceUtil#closeQuietly(Source)} instead */ @Deprecated public static void closeQuietly(Source src) { XmlSourceUtil.closeQuietly(src); } /** * Decorates an ImageInputStream so the flush*() methods are ignored and have no effect. * The decoration is implemented using a dynamic proxy. * @param in the ImageInputStream * @return the decorated ImageInputStream */ public static ImageInputStream ignoreFlushing(final ImageInputStream in) { return (ImageInputStream) Proxy.newProxyInstance(in.getClass().getClassLoader(), new Class[] {ImageInputStream.class}, new InvocationHandler() { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { String methodName = method.getName(); //Ignore calls to flush*() if (!methodName.startsWith("flush")) { try { return method.invoke(in, args); } catch (InvocationTargetException ite) { throw ite.getCause(); } } else { return null; } } }); } /** * GZIP header magic number bytes, like found in a gzipped * files, which are encoded in Intel format (i..e. little indian). */ private static final byte[] GZIP_MAGIC = {(byte) 0x1f, (byte) 0x8b}; /** * Indicates whether an InputStream is GZIP compressed. The InputStream must support * mark()/reset(). * @param in the InputStream (must return true on markSupported()) * @return true if the InputStream is GZIP compressed * @throws IOException in case of an I/O error */ public static boolean isGZIPCompressed(InputStream in) throws IOException { if (!in.markSupported()) { throw new IllegalArgumentException("InputStream must support mark()!"); } byte[] data = new byte[2]; in.mark(2); in.read(data); in.reset(); return ((data[0] == GZIP_MAGIC[0]) && (data[1] == GZIP_MAGIC[1])); } /** * Decorates an InputStream with a BufferedInputStream if it doesn't support mark()/reset(). * @param in the InputStream * @return the decorated InputStream */ public static InputStream decorateMarkSupported(InputStream in) { if (in.markSupported()) { return in; } else { return new java.io.BufferedInputStream(in); } } /** * Automatically decorates an InputStream so it is buffered. Furthermore, it makes sure * it is decorated with a GZIPInputStream if the stream is GZIP compressed. * @param in the InputStream * @return the decorated InputStream * @throws IOException in case of an I/O error */ public static InputStream autoDecorateInputStream(InputStream in) throws IOException { in = decorateMarkSupported(in); if (isGZIPCompressed(in)) { return new GZIPInputStream(in); } return in; } /** * Creates a new hint Map with values from the FOUserAgent. * @param session the session context * @return a Map of hints */ public static Map getDefaultHints(ImageSessionContext session) { java.util.Map hints = new java.util.HashMap(); hints.put(ImageProcessingHints.SOURCE_RESOLUTION, session.getParentContext().getSourceResolution()); hints.put(ImageProcessingHints.TARGET_RESOLUTION, session.getTargetResolution()); hints.put(ImageProcessingHints.IMAGE_SESSION_CONTEXT, session); return hints; } private static final String PAGE_INDICATOR = "page="; /** * Extracts page index information from a URI. The expected pattern is "page=x" where x is * a non-negative integer number. The page index must be specified as part of the URI fragment * and is 1-based, i.e. the first page is 1 but the the method returns a zero-based page * index. * An example: http://www.foo.bar/images/scan1.tif#page=4 (The method will return * 3.) *

    * If no page index information is found in the URI or if the URI cannot be parsed, the * method returns null. * @param uri the URI that should be inspected * @return the page index (0 is the first page) or null if there's no page index information * in the URI */ public static Integer getPageIndexFromURI(String uri) { if (uri.indexOf('#') < 0) { return null; } try { URI u = new URI(uri); String fragment = u.getFragment(); if (fragment != null) { int pos = fragment.indexOf(PAGE_INDICATOR); if (pos >= 0) { pos += PAGE_INDICATOR.length(); StringBuffer sb = new StringBuffer(); while (pos < fragment.length()) { char c = fragment.charAt(pos); if (c >= '0' && c <= '9') { sb.append(c); } else { break; } pos++; } if (sb.length() > 0) { int pageIndex = Integer.parseInt(sb.toString()) - 1; pageIndex = Math.max(0, pageIndex); return pageIndex; } } } } catch (URISyntaxException e) { throw new IllegalArgumentException("URI is invalid: " + e.getLocalizedMessage()); } return null; } /** * Extracts page index information from a URI. The expected pattern is "page=x" where x is * a non-negative integer number. The page index must be specified as part of the URI fragment * and is 1-based, i.e. the first page is 1 but the the method returns a zero-based page * index. * An example: http://www.foo.bar/images/scan1.tif#page=4 (The method will return * 3.) *

    * If no page index information is found in the URI, the * method just returns 0 which indicates the first page. * @param uri the URI that should be inspected * @return the page index (0 is the first page) */ public static int needPageIndexFromURI(String uri) { Integer res = getPageIndexFromURI(uri); if (res != null) { return res; } else { return 0; } } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/util/Penalty.java0100644 0000000 0000000 00000006470 13777276623 030706 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: Penalty.java 1345683 2012-06-03 14:50:33Z gadams $ */ package org.apache.xmlgraphics.image.loader.util; /** * Immutable class representing a penalty value. It's valid value range is that of an * {@link Integer}, but giving {@link Integer#MAX_VALUE} a special meaning: it means infinite * penalty, i.e. a candidate with this penalty will be excluded from any choice. */ public final class Penalty { public static final Penalty ZERO_PENALTY = new Penalty(0); public static final Penalty INFINITE_PENALTY = new Penalty(Integer.MAX_VALUE); private final int value; /** * Turns a penalty value into a penaly object. * @param value the penalty value * @return the penalty object */ public static Penalty toPenalty(int value) { switch (value) { case 0: return ZERO_PENALTY; case Integer.MAX_VALUE: return INFINITE_PENALTY; default: return new Penalty(value); } } private Penalty(int value) { this.value = value; } /** * Adds a penalty to this one and returns the combined penalty. * @param value the penalty value to add * @return the resulting penalty */ public Penalty add(Penalty value) { return add(value.getValue()); } /** * Adds a penalty to this one and returns the combined penalty. * @param value the penalty value to add * @return the resulting penalty */ public Penalty add(int value) { long p = (long)getValue() + value; return toPenalty(truncate(p)); } /** * Returns the penalty value. * @return the penalty value */ public int getValue() { return this.value; } /** * Indicates whether this is an infinite penalty, meaning that a solution with this penalty * is effectively ineligible. * @return true if this is an infinite penalty */ public boolean isInfinitePenalty() { return (value == Integer.MAX_VALUE); } /** {@inheritDoc} */ public String toString() { return "Penalty: " + (isInfinitePenalty() ? "INF" : Integer.toString(getValue())); } /** * Truncates the long penalty value to an integer without sign side-effects. * @param penalty the penalty value as a long * @return the penalty value as an int */ public static int truncate(long penalty) { penalty = Math.min(Integer.MAX_VALUE, penalty); penalty = Math.max(Integer.MIN_VALUE, penalty); return (int)penalty; } } ././@LongLink0100644 0000000 0000000 00000000152 13777276623 011655 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/util/SeekableStreamAdapter.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/util/SeekableStreamAdapter0100644 0000000 0000000 00000004116 13777276623 032535 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: SeekableStreamAdapter.java 750418 2009-03-05 11:03:54Z vhennebert $ */ package org.apache.xmlgraphics.image.loader.util; import java.io.IOException; import javax.imageio.stream.ImageInputStream; import org.apache.xmlgraphics.image.codec.util.SeekableStream; /** * Adapter which provides a SeekableStream interface over an ImageInputStream. */ public class SeekableStreamAdapter extends SeekableStream { private ImageInputStream iin; /** * Main constructor * @param iin the ImageInputStream to operate on */ public SeekableStreamAdapter(ImageInputStream iin) { this.iin = iin; } /** {@inheritDoc} */ public long getFilePointer() throws IOException { return iin.getStreamPosition(); } /** {@inheritDoc} */ public int read() throws IOException { return iin.read(); } /** {@inheritDoc} */ public int read(byte[] b, int off, int len) throws IOException { return iin.read(b, off, len); } /** {@inheritDoc} */ public void seek(long pos) throws IOException { iin.seek(pos); } /** {@inheritDoc} */ public boolean canSeekBackwards() { return true; } /** {@inheritDoc} */ public int skipBytes(int n) throws IOException { return iin.skipBytes(n); } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/util/SoftMapCache.java0100644 0000000 0000000 00000010315 13777276623 031560 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: SoftMapCache.java 750418 2009-03-05 11:03:54Z vhennebert $ */ package org.apache.xmlgraphics.image.loader.util; import java.lang.ref.Reference; import java.lang.ref.ReferenceQueue; import java.util.Collections; import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * Provides a simple cache using soft references and storing the values in a Map. The keys into * the Map are hard references, the values are referenced through soft references. The collected * values are cleaned up through a ReferenceQueue. */ public class SoftMapCache { /** logger */ private static Log log = LogFactory.getLog(SoftMapCache.class); private Map map; private ReferenceQueue refQueue = new ReferenceQueue(); /** * Creates a new soft cache. * @param synched true if the Map containing the values should by synchronized */ public SoftMapCache(boolean synched) { this.map = new java.util.HashMap(); if (synched) { this.map = Collections.synchronizedMap(this.map); } } /** * Returns the value associated with the given key. If the value is not found or the value * has been collected, null is returned. * @param key the key * @return the requested value or null */ public Object get(Object key) { Reference ref = (Reference)map.get(key); return getReference(key, ref); } /** * Removed the value associated with the given key. The value that is removed is returned * as the methods result. If the value is not found or the value has been collected, * null is returned. * @param key the key * @return the requested value or null */ public Object remove(Object key) { Reference ref = (Reference)map.remove(key); return getReference(key, ref); } private Object getReference(Object key, Reference ref) { Object value = null; if (ref != null) { value = ref.get(); if (value == null) { //Remove key if its value has been garbage collected if (log.isTraceEnabled()) { log.trace("Image has been collected: " + key); } checkReferenceQueue(); } } return value; } /** * Put a new value in the cache overwriting any existing value with the same key. * @param key The key * @param value the value */ public void put(Object key, Object value) { map.put(key, wrapInReference(value, key)); } /** * Clears the cache. */ public void clear() { map.clear(); } /** * Triggers some house-keeping, i.e. processes any pending objects in the reference queue. */ public void doHouseKeeping() { checkReferenceQueue(); } private Reference wrapInReference(Object obj, Object key) { return new SoftReferenceWithKey(obj, key, refQueue); } /** * Checks the reference queue if any references have been cleared and removes them from the * cache. */ private void checkReferenceQueue() { SoftReferenceWithKey ref; while ((ref = (SoftReferenceWithKey)refQueue.poll()) != null) { if (log.isTraceEnabled()) { log.trace("Removing ImageInfo from ref queue: " + ref.getKey()); } map.remove(ref.getKey()); } } } ././@LongLink0100644 0000000 0000000 00000000151 13777276623 011654 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/util/SoftReferenceWithKey.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/util/SoftReferenceWithKey.0100644 0000000 0000000 00000003402 13777276623 032457 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: SoftReferenceWithKey.java 1345683 2012-06-03 14:50:33Z gadams $ */ package org.apache.xmlgraphics.image.loader.util; import java.lang.ref.ReferenceQueue; import java.lang.ref.SoftReference; /** * Special SoftReference subclass that holds an additional key object that can be used to remove * a reference from a Map once the referenced object is collected, for example. */ public class SoftReferenceWithKey extends SoftReference { private Object key; /** * Creates a new SoftReference with a key. * @param referent object the new soft reference will refer to * @param key the key object * @param q queue the soft reference is registered with */ public SoftReferenceWithKey(Object referent, Object key, ReferenceQueue q) { super(referent, q); this.key = key; } /** * Returns the key associated with this reference. * @return the key */ public Object getKey() { return this.key; } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/loader/util/package.html0100644 0000000 0000000 00000001723 13777276623 030704 0ustar000000000 0000000 org.apache.fop.image2.util Package

    Contains utilities and helper classes useful in conjunction with the image package.

    xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/package.html0100644 0000000 0000000 00000000660 13777276623 026460 0ustar000000000 0000000 org.apache.xmlgraphics.image Classes, codecs and utilities for bitmap images. Contains extensions to the java.awt.image package. This package provides convenient methods, some utility classes and image codec classes. These generally bypass broken methods in Java2D or provide tweaked implementations. xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/rendered/AbstractRed.java0100644 0000000 0000000 00000060172 13777276623 031034 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: AbstractRed.java 1804124 2017-08-04 14:13:54Z ssteiner $ */ package org.apache.xmlgraphics.image.rendered; import java.awt.Point; import java.awt.Rectangle; import java.awt.Shape; import java.awt.Transparency; import java.awt.color.ColorSpace; import java.awt.image.ColorModel; import java.awt.image.ComponentColorModel; import java.awt.image.DataBuffer; import java.awt.image.Raster; import java.awt.image.RenderedImage; import java.awt.image.SampleModel; import java.awt.image.WritableRaster; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.Vector; import org.apache.xmlgraphics.image.GraphicsUtil; // CSOFF: LocalVariableName // CSOFF: MultipleVariableDeclarations // CSOFF: NeedBraces // CSOFF: NoWhitespaceAfter // CSOFF: WhitespaceAround /** * This is an abstract base class that takes care of most of the * normal issues surrounding the implementation of the CachableRed * (RenderedImage) interface. It tries to make no assumptions about * the subclass implementation. * * @version $Id: AbstractRed.java 1804124 2017-08-04 14:13:54Z ssteiner $ * * Originally authored by Thomas DeWeese. */ public abstract class AbstractRed implements CachableRed { protected Rectangle bounds; protected Vector srcs; protected Map props; protected SampleModel sm; protected ColorModel cm; protected int tileGridXOff; protected int tileGridYOff; protected int tileWidth; protected int tileHeight; protected int minTileX; protected int minTileY; protected int numXTiles; protected int numYTiles; /** * void constructor. The subclass must call one of the * flavors of init before the object becomes usable. * This is useful when the proper parameters to the init * method need to be computed in the subclasses constructor. */ protected AbstractRed() { } /** * Construct an Abstract RenderedImage from a bounds rect and props * (may be null). The srcs Vector will be empty. * @param bounds this defines the extent of the rable in the * user coordinate system. * @param props this initializes the props Map (may be null) */ protected AbstractRed(Rectangle bounds, Map props) { init((CachableRed)null, bounds, null, null, bounds.x, bounds.y, props); } /** * Construct an Abstract RenderedImage from a source image and * props (may be null). * @param src will be the first (and only) member of the srcs * Vector. Src is also used to set the bounds, ColorModel, * SampleModel, and tile grid offsets. * @param props this initializes the props Map. */ protected AbstractRed(CachableRed src, Map props) { init(src, src.getBounds(), src.getColorModel(), src.getSampleModel(), src.getTileGridXOffset(), src.getTileGridYOffset(), props); } /** * Construct an Abstract RenderedImage from a source image, bounds * rect and props (may be null). * @param src will be the first (and only) member of the srcs * Vector. Src is also used to set the ColorModel, SampleModel, * and tile grid offsets. * @param bounds The bounds of this image. * @param props this initializes the props Map. */ protected AbstractRed(CachableRed src, Rectangle bounds, Map props) { init(src, bounds, src.getColorModel(), src.getSampleModel(), src.getTileGridXOffset(), src.getTileGridYOffset(), props); } /** * Construct an Abstract RenderedImage from a source image, bounds * rect and props (may be null). * @param src if not null, will be the first (and only) member * of the srcs Vector. Also if it is not null it provides the * tile grid offsets, otherwise they are zero. * @param bounds The bounds of this image. * @param cm The ColorModel to use. If null it will default to * ComponentColorModel. * @param sm The sample model to use. If null it will construct * a sample model the matches the given/generated ColorModel and is * the size of bounds. * @param props this initializes the props Map. */ protected AbstractRed(CachableRed src, Rectangle bounds, ColorModel cm, SampleModel sm, Map props) { init(src, bounds, cm, sm, (src == null) ? 0 : src.getTileGridXOffset(), (src == null) ? 0 : src.getTileGridYOffset(), props); } /** * Construct an Abstract Rable from a bounds rect and props * (may be null). The srcs Vector will be empty. * @param src will be the first (and only) member of the srcs * Vector. Src is also used to set the ColorModel, SampleModel, * and tile grid offsets. * @param bounds this defines the extent of the rable in the * user coordinate system. * @param cm The ColorModel to use. If null it will default to * ComponentColorModel. * @param sm The sample model to use. If null it will construct * a sample model the matches the given/generated ColorModel and is * the size of bounds. * @param tileGridXOff The x location of tile 0,0. * @param tileGridYOff The y location of tile 0,0. * @param props this initializes the props Map. */ protected AbstractRed(CachableRed src, Rectangle bounds, ColorModel cm, SampleModel sm, int tileGridXOff, int tileGridYOff, Map props) { init(src, bounds, cm, sm, tileGridXOff, tileGridYOff, props); } /** * This is one of two basic init function (this is for single * source rendereds). * It is provided so subclasses can compute various values * before initializing all the state in the base class. * You really should call this method before returning from * your subclass constructor. * * @param src The source for the filter * @param bounds The bounds of the image * @param cm The ColorModel to use. If null it defaults to * ComponentColorModel/ src's ColorModel. * @param sm The Sample modle to use. If this is null it will * use the src's sample model if that is null it will * construct a sample model that matches the ColorModel * and is the size of the whole image. * @param tileGridXOff The x location of tile 0,0. * @param tileGridYOff The y location of tile 0,0. * @param props Any properties you want to associate with the image. */ protected void init(CachableRed src, Rectangle bounds, ColorModel cm, SampleModel sm, int tileGridXOff, int tileGridYOff, Map props) { this.srcs = new Vector(1); if (src != null) { this.srcs.add(src); if (bounds == null) { bounds = src.getBounds(); } if (cm == null) { cm = src.getColorModel(); } if (sm == null) { sm = src.getSampleModel(); } } this.bounds = bounds; this.tileGridXOff = tileGridXOff; this.tileGridYOff = tileGridYOff; this.props = new HashMap(); if (props != null) { this.props.putAll(props); } if (cm == null) { cm = new ComponentColorModel( ColorSpace.getInstance(ColorSpace.CS_GRAY), new int [] { 8 }, false, false, Transparency.OPAQUE, DataBuffer.TYPE_BYTE); } this.cm = cm; if (sm == null) { sm = cm.createCompatibleSampleModel(bounds.width, bounds.height); } this.sm = sm; // Recompute tileWidth/Height, minTileX/Y, numX/YTiles. updateTileGridInfo(); } /** * Construct an Abstract Rable from a List of sources a bounds rect * and props (may be null). * @param srcs This is used to initialize the srcs Vector. All * the members of srcs must be CachableRed otherwise an error * will be thrown. * @param bounds this defines the extent of the rendered in pixels * @param props this initializes the props Map. */ protected AbstractRed(List srcs, Rectangle bounds, Map props) { init(srcs, bounds, null, null, bounds.x, bounds.y, props); } /** * Construct an Abstract RenderedImage from a bounds rect, * ColorModel (may be null), SampleModel (may be null) and props * (may be null). The srcs Vector will be empty. * @param srcs This is used to initialize the srcs Vector. All * the members of srcs must be CachableRed otherwise an error * will be thrown. * @param bounds this defines the extent of the rendered in pixels * @param cm The ColorModel to use. If null it will default to * ComponentColorModel. * @param sm The sample model to use. If null it will construct * a sample model the matches the given/generated ColorModel and is * the size of bounds. * @param props this initializes the props Map. */ protected AbstractRed(List srcs, Rectangle bounds, ColorModel cm, SampleModel sm, Map props) { init(srcs, bounds, cm, sm, bounds.x, bounds.y, props); } /** * Construct an Abstract RenderedImage from a bounds rect, * ColorModel (may be null), SampleModel (may be null), tile grid * offsets and props (may be null). The srcs Vector will be * empty. * @param srcs This is used to initialize the srcs Vector. All * the members of srcs must be CachableRed otherwise an error * will be thrown. * @param bounds this defines the extent of the rable in the * user coordinate system. * @param cm The ColorModel to use. If null it will default to * ComponentColorModel. * @param sm The sample model to use. If null it will construct * a sample model the matches the given/generated ColorModel and is * the size of bounds. * @param tileGridXOff The x location of tile 0,0. * @param tileGridYOff The y location of tile 0,0. * @param props this initializes the props Map. */ protected AbstractRed(List srcs, Rectangle bounds, ColorModel cm, SampleModel sm, int tileGridXOff, int tileGridYOff, Map props) { init(srcs, bounds, cm, sm, tileGridXOff, tileGridYOff, props); } /** * This is the basic init function. * It is provided so subclasses can compute various values * before initializing all the state in the base class. * You really should call this method before returning from * your subclass constructor. * * @param srcs The list of sources * @param bounds The bounds of the image * @param cm The ColorModel to use. If null it defaults to * ComponentColorModel. * @param sm The Sample modle to use. If this is null it will * construct a sample model that matches the ColorModel * and is the size of the whole image. * @param tileGridXOff The x location of tile 0,0. * @param tileGridYOff The y location of tile 0,0. * @param props Any properties you want to associate with the image. */ protected void init(List srcs, Rectangle bounds, ColorModel cm, SampleModel sm, int tileGridXOff, int tileGridYOff, Map props) { this.srcs = new Vector(); if (srcs != null) { this.srcs.addAll(srcs); if (srcs.size() != 0) { CachableRed src = (CachableRed)srcs.get(0); if (bounds == null) { bounds = src.getBounds(); } if (cm == null) { cm = src.getColorModel(); } if (sm == null) { sm = src.getSampleModel(); } } } this.bounds = bounds; this.tileGridXOff = tileGridXOff; this.tileGridYOff = tileGridYOff; this.props = new HashMap(); if (props != null) { this.props.putAll(props); } if (cm == null) { cm = new ComponentColorModel( ColorSpace.getInstance(ColorSpace.CS_GRAY), new int [] { 8 }, false, false, Transparency.OPAQUE, DataBuffer.TYPE_BYTE); } this.cm = cm; if (sm == null) { sm = cm.createCompatibleSampleModel(bounds.width, bounds.height); } this.sm = sm; // Recompute tileWidth/Height, minTileX/Y, numX/YTiles. updateTileGridInfo(); } /** * This function computes all the basic information about the tile * grid based on the data stored in sm, and tileGridX/YOff. * It is responsible for updating tileWidth, tileHeight, * minTileX/Y, and numX/YTiles. */ protected void updateTileGridInfo() { this.tileWidth = sm.getWidth(); this.tileHeight = sm.getHeight(); int x1; int y1; int maxTileX; int maxTileY; // This computes and caches important information about the // structure of the tile grid in general. minTileX = getXTile(bounds.x); minTileY = getYTile(bounds.y); x1 = bounds.x + bounds.width - 1; // Xloc of right edge maxTileX = getXTile(x1); numXTiles = maxTileX - minTileX + 1; y1 = bounds.y + bounds.height - 1; // Yloc of right edge maxTileY = getYTile(y1); numYTiles = maxTileY - minTileY + 1; } public Rectangle getBounds() { return new Rectangle(getMinX(), getMinY(), getWidth(), getHeight()); } public Vector getSources() { return srcs; } public ColorModel getColorModel() { return cm; } public SampleModel getSampleModel() { return sm; } public int getMinX() { return bounds.x; } public int getMinY() { return bounds.y; } public int getWidth() { return bounds.width; } public int getHeight() { return bounds.height; } public int getTileWidth() { return tileWidth; } public int getTileHeight() { return tileHeight; } public int getTileGridXOffset() { return tileGridXOff; } public int getTileGridYOffset() { return tileGridYOff; } public int getMinTileX() { return minTileX; } public int getMinTileY() { return minTileY; } public int getNumXTiles() { return numXTiles; } public int getNumYTiles() { return numYTiles; } public Object getProperty(String name) { Object ret = props.get(name); if (ret != null) { return ret; } for (Object src : srcs) { RenderedImage ri = (RenderedImage) src; ret = ri.getProperty(name); if (ret != null) { return ret; } } return null; } public String [] getPropertyNames() { Set keys = props.keySet(); String[] ret = new String[keys.size()]; keys.toArray(ret); for (Object src : srcs) { RenderedImage ri = (RenderedImage) src; String[] srcProps = ri.getPropertyNames(); if (srcProps.length != 0) { String[] tmp = new String[ret.length + srcProps.length]; System.arraycopy(ret, 0, tmp, 0, ret.length); System.arraycopy(srcProps, 0, tmp, ret.length, srcProps.length); ret = tmp; } } return ret; } public Shape getDependencyRegion(int srcIndex, Rectangle outputRgn) { if ((srcIndex < 0) || (srcIndex > srcs.size())) { throw new IndexOutOfBoundsException( "Nonexistent source requested."); } // Return empty rect if they don't intersect. if (!outputRgn.intersects(bounds)) { return new Rectangle(); } // We only depend on our source for stuff that is inside // our bounds... return outputRgn.intersection(bounds); } public Shape getDirtyRegion(int srcIndex, Rectangle inputRgn) { if (srcIndex != 0) { throw new IndexOutOfBoundsException( "Nonexistent source requested."); } // Return empty rect if they don't intersect. if (!inputRgn.intersects(bounds)) { return new Rectangle(); } // Changes in the input region don't propogate outside our // bounds. return inputRgn.intersection(bounds); } // This is not included but can be implemented by the following. // In which case you _must_ reimplement getTile. // public WritableRaster copyData(WritableRaster wr) { // copyToRaster(wr); // return wr; // } public Raster getTile(int tileX, int tileY) { WritableRaster wr = makeTile(tileX, tileY); return copyData(wr); } public Raster getData() { return getData(bounds); } public Raster getData(Rectangle rect) { SampleModel smRet = sm.createCompatibleSampleModel( rect.width, rect.height); Point pt = new Point(rect.x, rect.y); WritableRaster wr = Raster.createWritableRaster(smRet, pt); // System.out.println("GD DB: " + wr.getDataBuffer().getSize()); return copyData(wr); } /** * Returns the x index of tile under xloc. * @param xloc the x location (in pixels) to get tile for. * @return The tile index under xloc (may be outside tile grid). */ public final int getXTile(int xloc) { int tgx = xloc - tileGridXOff; // We need to round to -infinity... if (tgx >= 0) { return tgx / tileWidth; } else { return (tgx - tileWidth + 1) / tileWidth; } } /** * Returns the y index of tile under yloc. * @param yloc the y location (in pixels) to get tile for. * @return The tile index under yloc (may be outside tile grid). */ public final int getYTile(int yloc) { int tgy = yloc - tileGridYOff; // We need to round to -infinity... if (tgy >= 0) { return tgy / tileHeight; } else { return (tgy - tileHeight + 1) / tileHeight; } } /** * Copies data from this images tile grid into wr. wr may * extend outside the bounds of this image in which case the * data in wr outside the bounds will not be touched. * @param wr Raster to fill with image data. */ public void copyToRaster(WritableRaster wr) { int tx0 = getXTile(wr.getMinX()); int ty0 = getYTile(wr.getMinY()); int tx1 = getXTile(wr.getMinX() + wr.getWidth() - 1); int ty1 = getYTile(wr.getMinY() + wr.getHeight() - 1); if (tx0 < minTileX) { tx0 = minTileX; } if (ty0 < minTileY) { ty0 = minTileY; } if (tx1 >= minTileX + numXTiles) { tx1 = minTileX + numXTiles - 1; } if (ty1 >= minTileY + numYTiles) { ty1 = minTileY + numYTiles - 1; } final boolean isIntPack = GraphicsUtil.is_INT_PACK_Data(getSampleModel(), false); for (int y = ty0; y <= ty1; y++) { for (int x = tx0; x <= tx1; x++) { Raster r = getTile(x, y); if (isIntPack) { GraphicsUtil.copyData_INT_PACK(r, wr); } else { GraphicsUtil.copyData_FALLBACK(r, wr); } } } } // static DataBufferReclaimer reclaim = new DataBufferReclaimer(); /** * This is a helper function that will create the tile requested * Including properly subsetting the bounds of the tile to the * bounds of the current image. * @param tileX The x index of the tile to be built * @param tileY The y index of the tile to be built * @return The tile requested * @exception IndexOutOfBoundsException if the requested tile index * falles outside of the bounds of the tile grid for the image. */ public WritableRaster makeTile(int tileX, int tileY) { if ((tileX < minTileX) || (tileX >= minTileX + numXTiles) || (tileY < minTileY) || (tileY >= minTileY + numYTiles)) { throw new IndexOutOfBoundsException( "Requested Tile (" + tileX + ',' + tileY + ") lies outside the bounds of image"); } Point pt = new Point(tileGridXOff + tileX * tileWidth, tileGridYOff + tileY * tileHeight); WritableRaster wr; wr = Raster.createWritableRaster(sm, pt); // if (!(sm instanceof SinglePixelPackedSampleModel)) // wr = Raster.createWritableRaster(sm, pt); // else { // SinglePixelPackedSampleModel sppsm; // sppsm = (SinglePixelPackedSampleModel)sm; // int stride = sppsm.getScanlineStride(); // int sz = stride*sppsm.getHeight(); // // int [] data = reclaim.request(sz); // DataBuffer db = new DataBufferInt(data, sz); // // reclaim.register(db); // // wr = Raster.createWritableRaster(sm, db, pt); // } // System.out.println("MT DB: " + wr.getDataBuffer().getSize()); int x0 = wr.getMinX(); int y0 = wr.getMinY(); int x1 = x0 + wr.getWidth() - 1; int y1 = y0 + wr.getHeight() - 1; if ((x0 < bounds.x) || (x1 >= (bounds.x + bounds.width)) || (y0 < bounds.y) || (y1 >= (bounds.y + bounds.height))) { // Part of this raster lies outside our bounds so subset // it so it only advertises the stuff inside our bounds. if (x0 < bounds.x) { x0 = bounds.x; } if (y0 < bounds.y) { y0 = bounds.y; } if (x1 >= (bounds.x + bounds.width)) { x1 = bounds.x + bounds.width - 1; } if (y1 >= (bounds.y + bounds.height)) { y1 = bounds.y + bounds.height - 1; } wr = wr.createWritableChild(x0, y0, x1 - x0 + 1, y1 - y0 + 1, x0, y0, null); } return wr; } public static void copyBand(Raster src, int srcBand, WritableRaster dst, int dstBand) { Rectangle srcR = new Rectangle(src.getMinX(), src.getMinY(), src.getWidth(), src.getHeight()); Rectangle dstR = new Rectangle(dst.getMinX(), dst.getMinY(), dst.getWidth(), dst.getHeight()); Rectangle cpR = srcR.intersection(dstR); int [] samples = null; for (int y = cpR.y; y < cpR.y + cpR.height; y++) { samples = src.getSamples(cpR.x, y, cpR.width, 1, srcBand, samples); dst.setSamples(cpR.x, y, cpR.width, 1, dstBand, samples); } } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/rendered/Any2LsRGBRed.java0100644 0000000 0000000 00000026141 13777276623 030732 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: Any2LsRGBRed.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.image.rendered; import java.awt.Point; import java.awt.Rectangle; import java.awt.color.ColorSpace; import java.awt.image.BandCombineOp; import java.awt.image.BufferedImage; import java.awt.image.ColorConvertOp; import java.awt.image.ColorModel; import java.awt.image.DataBuffer; import java.awt.image.Raster; import java.awt.image.SampleModel; import java.awt.image.SinglePixelPackedSampleModel; import java.awt.image.WritableRaster; import org.apache.xmlgraphics.image.GraphicsUtil; // CSOFF: ConstantName // CSOFF: NeedBraces // CSOFF: WhitespaceAfter // CSOFF: WhitespaceAround /** * This function will tranform an image from any colorspace into a * luminance image. The alpha channel if any will be copied to the * new image. * * @version $Id: Any2LsRGBRed.java 1732018 2016-02-24 04:51:06Z gadams $ * * Originally authored by Thomas DeWeese. */ public class Any2LsRGBRed extends AbstractRed { boolean srcIssRGB; /** * Construct a luminace image from src. * * @param src The image to convert to a luminance image */ public Any2LsRGBRed(CachableRed src) { super(src, src.getBounds(), fixColorModel(src), fixSampleModel(src), src.getTileGridXOffset(), src.getTileGridYOffset(), null); ColorModel srcCM = src.getColorModel(); if (srcCM == null) { return; } ColorSpace srcCS = srcCM.getColorSpace(); if (srcCS == ColorSpace.getInstance(ColorSpace.CS_sRGB)) { srcIssRGB = true; } } /** * Gamma for linear to sRGB convertion */ private static final double GAMMA = 2.4; private static final double LFACT = 1.0 / 12.92; public static final double sRGBToLsRGB(double value) { if (value <= 0.003928) { return value * LFACT; } return Math.pow((value + 0.055) / 1.055, GAMMA); } /** * Lookup tables for RGB lookups. The linearToSRGBLut is used * when noise values are considered to be on a linearScale. The * linearToLinear table is used when the values are considered to * be on the sRGB scale to begin with. */ private static final int[] sRGBToLsRGBLut = new int[256]; static { final double scale = 1.0 / 255; // System.out.print("S2L: "); for (int i = 0; i < 256; i++) { double value = sRGBToLsRGB(i * scale); sRGBToLsRGBLut[i] = (int)Math.round(value * 255.0); // System.out.print(sRGBToLsRGBLut[i] + ","); } // System.out.println(""); } public WritableRaster copyData(WritableRaster wr) { // Get my source. CachableRed src = (CachableRed)getSources().get(0); ColorModel srcCM = src.getColorModel(); SampleModel srcSM = src.getSampleModel(); // Fast case, SRGB source, INT Pack writable raster... if (srcIssRGB && Any2sRGBRed.is_INT_PACK_COMP(wr.getSampleModel())) { src.copyData(wr); if (srcCM.hasAlpha()) { GraphicsUtil.coerceData(wr, srcCM, false); } Any2sRGBRed.applyLut_INT(wr, sRGBToLsRGBLut); return wr; } if (srcCM == null) { // We don't really know much about this source, let's // guess based on the number of bands... float [][] matrix = null; switch (srcSM.getNumBands()) { case 1: matrix = new float[1][3]; matrix[0][0] = 1; // Red matrix[0][1] = 1; // Grn matrix[0][2] = 1; // Blu break; case 2: matrix = new float[2][4]; matrix[0][0] = 1; // Red matrix[0][1] = 1; // Grn matrix[0][2] = 1; // Blu matrix[1][3] = 1; // Alpha break; case 3: matrix = new float[3][3]; matrix[0][0] = 1; // Red matrix[1][1] = 1; // Grn matrix[2][2] = 1; // Blu break; default: matrix = new float[srcSM.getNumBands()][4]; matrix[0][0] = 1; // Red matrix[1][1] = 1; // Grn matrix[2][2] = 1; // Blu matrix[3][3] = 1; // Alpha break; } Raster srcRas = src.getData(wr.getBounds()); BandCombineOp op = new BandCombineOp(matrix, null); op.filter(srcRas, wr); } else { ColorModel dstCM = getColorModel(); BufferedImage dstBI; if (!dstCM.hasAlpha()) { // No alpha ao we don't have to work around the bug // in the color convert op. dstBI = new BufferedImage( dstCM, wr.createWritableTranslatedChild(0, 0), dstCM.isAlphaPremultiplied(), null); } else { // All this nonsense is to work around the fact that // the Color convert op doesn't properly copy the // Alpha from src to dst. SinglePixelPackedSampleModel dstSM; dstSM = (SinglePixelPackedSampleModel)wr.getSampleModel(); int [] masks = dstSM.getBitMasks(); SampleModel dstSMNoA = new SinglePixelPackedSampleModel( dstSM.getDataType(), dstSM.getWidth(), dstSM.getHeight(), dstSM.getScanlineStride(), new int[] {masks[0], masks[1], masks[2]}); ColorModel dstCMNoA = GraphicsUtil.Linear_sRGB; WritableRaster dstWr; dstWr = Raster.createWritableRaster(dstSMNoA, wr.getDataBuffer(), new Point(0, 0)); dstWr = dstWr.createWritableChild( wr.getMinX() - wr.getSampleModelTranslateX(), wr.getMinY() - wr.getSampleModelTranslateY(), wr.getWidth(), wr.getHeight(), 0, 0, null); dstBI = new BufferedImage(dstCMNoA, dstWr, false, null); } // Divide out alpha if we have it. We need to do this since // the color convert may not be a linear operation which may // lead to out of range values. ColorModel srcBICM = srcCM; WritableRaster srcWr; if (srcCM.hasAlpha() && srcCM.isAlphaPremultiplied()) { Rectangle wrR = wr.getBounds(); SampleModel sm = srcCM.createCompatibleSampleModel( wrR.width, wrR.height); srcWr = Raster.createWritableRaster( sm, new Point(wrR.x, wrR.y)); src.copyData(srcWr); srcBICM = GraphicsUtil.coerceData(srcWr, srcCM, false); } else { Raster srcRas = src.getData(wr.getBounds()); srcWr = GraphicsUtil.makeRasterWritable(srcRas); } BufferedImage srcBI; srcBI = new BufferedImage(srcBICM, srcWr.createWritableTranslatedChild(0, 0), false, null); /* * System.out.println("src: " + srcBI.getWidth() + "x" + * srcBI.getHeight()); * System.out.println("dst: " + dstBI.getWidth() + "x" + * dstBI.getHeight()); */ ColorConvertOp op = new ColorConvertOp(null); op.filter(srcBI, dstBI); if (dstCM.hasAlpha()) { copyBand(srcWr, srcSM.getNumBands() - 1, wr, getSampleModel().getNumBands() - 1); } } return wr; } /** * This function 'fixes' the source's color model. Right now * it just selects if it should have one or two bands based on * if the source had an alpha channel. */ protected static ColorModel fixColorModel(CachableRed src) { ColorModel cm = src.getColorModel(); if (cm != null) { if (cm.hasAlpha()) { return GraphicsUtil.Linear_sRGB_Unpre; } return GraphicsUtil.Linear_sRGB; } else { // No ColorModel so try to make some intelligent // decisions based just on the number of bands... // 1 bands -> replicated into RGB // 2 bands -> Band 0 replicated into RGB & Band 1 -> alpha premult // 3 bands -> sRGB (not-linear?) // 4 bands -> sRGB premult (not-linear?) SampleModel sm = src.getSampleModel(); switch (sm.getNumBands()) { case 1: return GraphicsUtil.Linear_sRGB; case 2: return GraphicsUtil.Linear_sRGB_Unpre; case 3: return GraphicsUtil.Linear_sRGB; default: return GraphicsUtil.Linear_sRGB_Unpre; } } } /** * This function 'fixes' the source's sample model. * Right now it just selects if it should have 3 or 4 bands * based on if the source had an alpha channel. */ protected static SampleModel fixSampleModel(CachableRed src) { SampleModel sm = src.getSampleModel(); ColorModel cm = src.getColorModel(); boolean alpha = false; if (cm != null) { alpha = cm.hasAlpha(); } else { switch (sm.getNumBands()) { case 1: case 3: alpha = false; break; default: alpha = true; break; } } if (alpha) { return new SinglePixelPackedSampleModel( DataBuffer.TYPE_INT, sm.getWidth(), sm.getHeight(), new int [] {0xFF0000, 0xFF00, 0xFF, 0xFF000000}); } else { return new SinglePixelPackedSampleModel( DataBuffer.TYPE_INT, sm.getWidth(), sm.getHeight(), new int [] {0xFF0000, 0xFF00, 0xFF}); } } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/rendered/Any2sRGBRed.java0100644 0000000 0000000 00000031656 13777276623 030625 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: Any2sRGBRed.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.image.rendered; import java.awt.color.ColorSpace; import java.awt.image.BandCombineOp; import java.awt.image.BufferedImage; import java.awt.image.ColorConvertOp; import java.awt.image.ColorModel; import java.awt.image.DataBuffer; import java.awt.image.DataBufferInt; import java.awt.image.Raster; import java.awt.image.SampleModel; import java.awt.image.SinglePixelPackedSampleModel; import java.awt.image.WritableRaster; import org.apache.xmlgraphics.image.GraphicsUtil; // CSOFF: ConstantName // CSOFF: MethodName // CSOFF: MultipleVariableDeclarations // CSOFF: NeedBraces // CSOFF: OperatorWrap // CSOFF: WhitespaceAfter // CSOFF: WhitespaceAround /** * This function will tranform an image from any colorspace into a * luminance image. The alpha channel if any will be copied to the * new image. * * @version $Id: Any2sRGBRed.java 1732018 2016-02-24 04:51:06Z gadams $ * * Originally authored by Thomas DeWeese. */ public class Any2sRGBRed extends AbstractRed { boolean srcIsLsRGB; /** * Construct a luminace image from src. * * @param src The image to convert to a luminance image */ public Any2sRGBRed(CachableRed src) { super(src, src.getBounds(), fixColorModel(src), fixSampleModel(src), src.getTileGridXOffset(), src.getTileGridYOffset(), null); ColorModel srcCM = src.getColorModel(); if (srcCM == null) { return; } ColorSpace srcCS = srcCM.getColorSpace(); if (srcCS == ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB)) { srcIsLsRGB = true; } } public static boolean is_INT_PACK_COMP(SampleModel sm) { if (!(sm instanceof SinglePixelPackedSampleModel)) { return false; } // Check transfer types if (sm.getDataType() != DataBuffer.TYPE_INT) { return false; } SinglePixelPackedSampleModel sppsm; sppsm = (SinglePixelPackedSampleModel)sm; int [] masks = sppsm.getBitMasks(); if ((masks.length != 3) && (masks.length != 4)) { return false; } if (masks[0] != 0x00ff0000) { return false; } if (masks[1] != 0x0000ff00) { return false; } if (masks[2] != 0x000000ff) { return false; } if ((masks.length == 4) && (masks[3] != 0xff000000)) { return false; } return true; } /** * Exponent for linear to sRGB convertion */ private static final double GAMMA = 2.4; /** * Lookup tables for RGB lookups. The linearToSRGBLut is used * when noise values are considered to be on a linearScale. The * linearToLinear table is used when the values are considered to * be on the sRGB scale to begin with. */ private static final int[] linearToSRGBLut = new int[256]; static { final double scale = 1.0 / 255; final double exp = 1.0 / GAMMA; // System.out.print("L2S: "); for (int i = 0; i < 256; i++) { double value = i * scale; if (value <= 0.0031308) { value *= 12.92; } else { value = 1.055 * Math.pow(value, exp) - 0.055; } linearToSRGBLut[i] = (int)Math.round(value * 255.); // System.out.print(linearToSRGBLut[i] + ","); } // System.out.println(""); } public static WritableRaster applyLut_INT(WritableRaster wr, final int []lut) { SinglePixelPackedSampleModel sm = (SinglePixelPackedSampleModel)wr.getSampleModel(); DataBufferInt db = (DataBufferInt)wr.getDataBuffer(); final int srcBase = (db.getOffset() + sm.getOffset(wr.getMinX() - wr.getSampleModelTranslateX(), wr.getMinY() - wr.getSampleModelTranslateY())); // Access the pixel data array final int[] pixels = db.getBankData()[0]; final int width = wr.getWidth(); final int height = wr.getHeight(); final int scanStride = sm.getScanlineStride(); int end; int pix; // For alpha premult we need to multiply all comps. for (int y = 0; y < height; y++) { int sp = srcBase + y * scanStride; end = sp + width; while (sp < end) { pix = pixels[sp]; pixels[sp] = ((pix & 0xFF000000) | (lut[(pix >>> 16) & 0xFF] << 16) | (lut[(pix >>> 8) & 0xFF] << 8) | (lut[pix & 0xFF])); sp++; } } return wr; } public WritableRaster copyData(WritableRaster wr) { // Get my source. CachableRed src = (CachableRed)getSources().get(0); ColorModel srcCM = src.getColorModel(); SampleModel srcSM = src.getSampleModel(); // Fast case, Linear SRGB source, INT Pack writable raster... if (srcIsLsRGB && is_INT_PACK_COMP(wr.getSampleModel())) { src.copyData(wr); if (srcCM.hasAlpha()) { GraphicsUtil.coerceData(wr, srcCM, false); } applyLut_INT(wr, linearToSRGBLut); return wr; } if (srcCM == null) { // We don't really know much about this source, let's // guess based on the number of bands... float [][] matrix = null; switch (srcSM.getNumBands()) { case 1: matrix = new float[3][1]; matrix[0][0] = 1; // Red matrix[1][0] = 1; // Grn matrix[2][0] = 1; // Blu break; case 2: matrix = new float[4][2]; matrix[0][0] = 1; // Red matrix[1][0] = 1; // Grn matrix[3][0] = 1; // Blu matrix[3][1] = 1; // Alpha break; case 3: matrix = new float[3][3]; matrix[0][0] = 1; // Red matrix[1][1] = 1; // Grn matrix[2][2] = 1; // Blu break; default: matrix = new float[4][srcSM.getNumBands()]; matrix[0][0] = 1; // Red matrix[1][1] = 1; // Grn matrix[2][2] = 1; // Blu matrix[3][3] = 1; // Alpha break; } Raster srcRas = src.getData(wr.getBounds()); BandCombineOp op = new BandCombineOp(matrix, null); op.filter(srcRas, wr); return wr; } if (srcCM.getColorSpace() == ColorSpace.getInstance(ColorSpace.CS_GRAY)) { // This is a little bit of a hack. There is only // a linear grayscale ICC profile in the JDK so // many things use this when the data _really_ // has sRGB gamma applied. try { float [][] matrix = null; switch (srcSM.getNumBands()) { case 1: matrix = new float[3][1]; matrix[0][0] = 1; // Red matrix[1][0] = 1; // Grn matrix[2][0] = 1; // Blu break; case 2: default: matrix = new float[4][2]; matrix[0][0] = 1; // Red matrix[1][0] = 1; // Grn matrix[3][0] = 1; // Blu matrix[4][1] = 1; // Alpha break; } Raster srcRas = src.getData(wr.getBounds()); BandCombineOp op = new BandCombineOp(matrix, null); op.filter(srcRas, wr); } catch (Throwable t) { t.printStackTrace(); } return wr; } ColorModel dstCM = getColorModel(); if (srcCM.getColorSpace() == dstCM.getColorSpace()) { // No transform needed, just reformat data... // System.out.println("Bypassing"); if (is_INT_PACK_COMP(srcSM)) { src.copyData(wr); } else { GraphicsUtil.copyData(src.getData(wr.getBounds()), wr); } return wr; } Raster srcRas = src.getData(wr.getBounds()); assert srcRas instanceof WritableRaster; WritableRaster srcWr = (WritableRaster)srcRas; // Divide out alpha if we have it. We need to do this since // the color convert may not be a linear operation which may // lead to out of range values. ColorModel srcBICM = srcCM; if (srcCM.hasAlpha()) { srcBICM = GraphicsUtil.coerceData(srcWr, srcCM, false); } BufferedImage srcBI; BufferedImage dstBI; srcBI = new BufferedImage(srcBICM, srcWr.createWritableTranslatedChild(0, 0), false, null); // System.out.println("src: " + srcBI.getWidth() + "x" + // srcBI.getHeight()); ColorConvertOp op = new ColorConvertOp(dstCM.getColorSpace(), null); dstBI = op.filter(srcBI, null); // System.out.println("After filter:"); WritableRaster wr00 = wr.createWritableTranslatedChild(0, 0); for (int i = 0; i < dstCM.getColorSpace().getNumComponents(); i++) { copyBand(dstBI.getRaster(), i, wr00, i); } if (dstCM.hasAlpha()) { copyBand(srcWr, srcSM.getNumBands() - 1, wr, getSampleModel().getNumBands() - 1); } return wr; } /** * This function 'fixes' the source's color model. Right now * it just selects if it should have one or two bands based on * if the source had an alpha channel. */ protected static ColorModel fixColorModel(CachableRed src) { ColorModel cm = src.getColorModel(); if (cm != null) { if (cm.hasAlpha()) { return GraphicsUtil.sRGB_Unpre; } return GraphicsUtil.sRGB; } else { // No ColorModel so try to make some intelligent // decisions based just on the number of bands... // 1 bands -> replicated into RGB // 2 bands -> Band 0 replicated into RGB & Band 1 -> alpha premult // 3 bands -> sRGB (not-linear?) // 4 bands -> sRGB premult (not-linear?) SampleModel sm = src.getSampleModel(); switch (sm.getNumBands()) { case 1: return GraphicsUtil.sRGB; case 2: return GraphicsUtil.sRGB_Unpre; case 3: return GraphicsUtil.sRGB; default: return GraphicsUtil.sRGB_Unpre; } } } /** * This function 'fixes' the source's sample model. * Right now it just selects if it should have 3 or 4 bands * based on if the source had an alpha channel. */ protected static SampleModel fixSampleModel(CachableRed src) { SampleModel sm = src.getSampleModel(); ColorModel cm = src.getColorModel(); boolean alpha = false; if (cm != null) { alpha = cm.hasAlpha(); } else { switch (sm.getNumBands()) { case 1: case 3: alpha = false; break; default: alpha = true; break; } } if (alpha) { return new SinglePixelPackedSampleModel( DataBuffer.TYPE_INT, sm.getWidth(), sm.getHeight(), new int [] {0xFF0000, 0xFF00, 0xFF, 0xFF000000}); } else { return new SinglePixelPackedSampleModel( DataBuffer.TYPE_INT, sm.getWidth(), sm.getHeight(), new int [] {0xFF0000, 0xFF00, 0xFF}); } } } ././@LongLink0100644 0000000 0000000 00000000152 13777276623 011655 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/rendered/BufferedImageCachableRed.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/rendered/BufferedImageCachableRed0100644 0000000 0000000 00000011454 13777276623 032440 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: BufferedImageCachableRed.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.image.rendered; import java.awt.Rectangle; import java.awt.image.BufferedImage; import java.awt.image.Raster; import java.awt.image.WritableRaster; import org.apache.xmlgraphics.image.GraphicsUtil; // CSOFF: NeedBraces // CSOFF: WhitespaceAfter // CSOFF: WhitespaceAround /** * This implements CachableRed based on a BufferedImage. * You can use this to wrap a BufferedImage that you want to * appear as a CachableRed. * It essentially ignores the dependency and dirty region methods. * * Originally authored by Thomas DeWeese. * @version $Id: BufferedImageCachableRed.java 1732018 2016-02-24 04:51:06Z gadams $ */ public class BufferedImageCachableRed extends AbstractRed { // The bufferedImage that we wrap... BufferedImage bi; /** * Construct an instance of CachableRed around a BufferedImage. */ public BufferedImageCachableRed(BufferedImage bi) { super((CachableRed)null, new Rectangle(bi.getMinX(), bi.getMinY(), bi.getWidth(), bi.getHeight()), bi.getColorModel(), bi.getSampleModel(), bi.getMinX(), bi.getMinY(), null); this.bi = bi; } public BufferedImageCachableRed(BufferedImage bi, int xloc, int yloc) { super((CachableRed)null, new Rectangle(xloc, yloc, bi.getWidth(), bi.getHeight()), bi.getColorModel(), bi.getSampleModel(), xloc, yloc, null); this.bi = bi; } public Rectangle getBounds() { return new Rectangle(getMinX(), getMinY(), getWidth(), getHeight()); } /** * fetch the bufferedImage from this node. */ public BufferedImage getBufferedImage() { return bi; } public Object getProperty(String name) { return bi.getProperty(name); } public String [] getPropertyNames() { return bi.getPropertyNames(); } public Raster getTile(int tileX, int tileY) { return bi.getTile(tileX, tileY); } public Raster getData() { Raster r = bi.getData(); return r.createTranslatedChild(getMinX(), getMinY()); } public Raster getData(Rectangle rect) { Rectangle r = (Rectangle)rect.clone(); if (!r.intersects(getBounds())) { return null; } r = r.intersection(getBounds()); r.translate(-getMinX(), -getMinY()); Raster ret = bi.getData(r); return ret.createTranslatedChild(ret.getMinX() + getMinX(), ret.getMinY() + getMinY()); } public WritableRaster copyData(WritableRaster wr) { WritableRaster wr2 = wr.createWritableTranslatedChild( wr.getMinX() - getMinX(), wr.getMinY() - getMinY()); GraphicsUtil.copyData(bi.getRaster(), wr2); /* This was the original code. This is _bad_ since it causes a * multiply and divide of the alpha channel to do the draw * operation. I believe that at some point I switched to * drawImage in order to avoid some issues with * BufferedImage's copyData implementation but I can't * reproduce them now. Anyway I'm now using GraphicsUtil which * should generally be as fast if not faster... */ /* BufferedImage dest; dest = new BufferedImage(bi.getColorModel(), wr.createWritableTranslatedChild(0,0), bi.getColorModel().isAlphaPremultiplied(), null); java.awt.Graphics2D g2d = dest.createGraphics(); g2d.drawImage(bi, null, getMinX()-wr.getMinX(), getMinY()-wr.getMinY()); g2d.dispose(); */ return wr; } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/rendered/CachableRed.java0100644 0000000 0000000 00000005200 13777276623 030742 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: CachableRed.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.image.rendered; import java.awt.Rectangle; import java.awt.Shape; import java.awt.image.RenderedImage; /** * This provides a number of extra methods that enable a system to * better analyse the dependencies between nodes in a render graph. * * @version $Id: CachableRed.java 1732018 2016-02-24 04:51:06Z gadams $ * * Originally authored by Thomas DeWeese. */ public interface CachableRed extends RenderedImage { /** * Returns the bounds of the current image. * This should be 'in sync' with getMinX, getMinY, getWidth, getHeight */ Rectangle getBounds(); /** * Returns the region of input data is is required to generate * outputRgn. * @param srcIndex The source to do the dependency calculation for. * @param outputRgn The region of output you are interested in * generating dependencies for. The is given in the output pixel * coordiate system for this node. * @return The region of input required. This is in the output pixel * coordinate system for the source indicated by srcIndex. */ Shape getDependencyRegion(int srcIndex, Rectangle outputRgn); /** * This calculates the region of output that is affected by a change * in a region of input. * @param srcIndex The input that inputRgn reflects changes in. * @param inputRgn the region of input that has changed, used to * calculate the returned shape. This is given in the pixel * coordinate system of the source indicated by srcIndex. * @return The region of output that would be invalid given * a change to inputRgn of the source selected by srcIndex. * this is in the output pixel coordinate system of this node. */ Shape getDirtyRegion(int srcIndex, Rectangle inputRgn); } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/rendered/FormatRed.java0100644 0000000 0000000 00000017025 13777276623 030520 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: FormatRed.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.image.rendered; import java.awt.Point; import java.awt.Transparency; import java.awt.color.ColorSpace; import java.awt.image.BufferedImage; import java.awt.image.ColorModel; import java.awt.image.ComponentColorModel; import java.awt.image.ComponentSampleModel; import java.awt.image.DataBuffer; import java.awt.image.DirectColorModel; import java.awt.image.Raster; import java.awt.image.SampleModel; import java.awt.image.SinglePixelPackedSampleModel; import java.awt.image.WritableRaster; import org.apache.xmlgraphics.image.GraphicsUtil; // CSOFF: NeedBraces // CSOFF: WhitespaceAfter // CSOFF: WhitespaceAround /** * This allows you to specify the ColorModel, Alpha premult and/or * SampleModel to be used for output. If the input image lacks * Alpha and alpha is included in output then it is filled with * alpha=1. In all other cases bands are simply copied. * * @version $Id: FormatRed.java 1732018 2016-02-24 04:51:06Z gadams $ * * Originally authored by Thomas DeWeese. */ public class FormatRed extends AbstractRed { public static CachableRed construct(CachableRed src, ColorModel cm) { ColorModel srcCM = src.getColorModel(); if ((cm.hasAlpha() != srcCM.hasAlpha()) || (cm.isAlphaPremultiplied() != srcCM.isAlphaPremultiplied())) { return new FormatRed(src, cm); } if (cm.getNumComponents() != srcCM.getNumComponents()) { throw new IllegalArgumentException( "Incompatible ColorModel given"); } if ((srcCM instanceof ComponentColorModel) && (cm instanceof ComponentColorModel)) { return src; } if ((srcCM instanceof DirectColorModel) && (cm instanceof DirectColorModel)) { return src; } return new FormatRed(src, cm); } /** * Construct an instance of CachableRed around a BufferedImage. */ public FormatRed(CachableRed cr, SampleModel sm) { super(cr, cr.getBounds(), makeColorModel(cr, sm), sm, cr.getTileGridXOffset(), cr.getTileGridYOffset(), null); } public FormatRed(CachableRed cr, ColorModel cm) { super(cr, cr.getBounds(), cm, makeSampleModel(cr, cm), cr.getTileGridXOffset(), cr.getTileGridYOffset(), null); } /** * fetch the source image for this node. */ public CachableRed getSource() { return (CachableRed)getSources().get(0); } public Object getProperty(String name) { return getSource().getProperty(name); } public String [] getPropertyNames() { return getSource().getPropertyNames(); } public WritableRaster copyData(WritableRaster wr) { ColorModel cm = getColorModel(); CachableRed cr = getSource(); ColorModel srcCM = cr.getColorModel(); SampleModel srcSM = cr.getSampleModel(); srcSM = srcSM.createCompatibleSampleModel(wr.getWidth(), wr.getHeight()); WritableRaster srcWR; srcWR = Raster.createWritableRaster(srcSM, new Point(wr.getMinX(), wr.getMinY())); getSource().copyData(srcWR); BufferedImage srcBI = new BufferedImage( srcCM, srcWR.createWritableTranslatedChild(0, 0), srcCM.isAlphaPremultiplied(), null); BufferedImage dstBI = new BufferedImage( cm, wr.createWritableTranslatedChild(0, 0), cm.isAlphaPremultiplied(), null); GraphicsUtil.copyData(srcBI, dstBI); return wr; } public static SampleModel makeSampleModel(CachableRed cr, ColorModel cm) { SampleModel srcSM = cr.getSampleModel(); return cm.createCompatibleSampleModel(srcSM.getWidth(), srcSM.getHeight()); } public static ColorModel makeColorModel(CachableRed cr, SampleModel sm) { ColorModel srcCM = cr.getColorModel(); ColorSpace cs = srcCM.getColorSpace(); int bands = sm.getNumBands(); int bits; int dt = sm.getDataType(); switch (dt) { case DataBuffer.TYPE_BYTE: bits = 8; break; case DataBuffer.TYPE_SHORT: bits = 16; break; case DataBuffer.TYPE_USHORT: bits = 16; break; case DataBuffer.TYPE_INT: bits = 32; break; default: throw new IllegalArgumentException( "Unsupported DataBuffer type: " + dt); } boolean hasAlpha = srcCM.hasAlpha(); if (hasAlpha) { // if Src has Alpha then our out bands must // either be one less than the source (no out alpha) // or equal (still has alpha) if (bands == srcCM.getNumComponents() - 1) { hasAlpha = false; } else if (bands != srcCM.getNumComponents()) { throw new IllegalArgumentException( "Incompatible number of bands in and out"); } } else { if (bands == srcCM.getNumComponents() + 1) { hasAlpha = true; } else if (bands != srcCM.getNumComponents()) { throw new IllegalArgumentException( "Incompatible number of bands in and out"); } } boolean preMult = srcCM.isAlphaPremultiplied(); if (!hasAlpha) { preMult = false; } if (sm instanceof ComponentSampleModel) { int [] bitsPer = new int[bands]; for (int i = 0; i < bands; i++) { bitsPer[i] = bits; } return new ComponentColorModel( cs, bitsPer, hasAlpha, preMult, hasAlpha ? Transparency.TRANSLUCENT : Transparency.OPAQUE, dt); } else if (sm instanceof SinglePixelPackedSampleModel) { SinglePixelPackedSampleModel sppsm; sppsm = (SinglePixelPackedSampleModel)sm; int[] masks = sppsm.getBitMasks(); if (bands == 4) { return new DirectColorModel( cs, bits, masks[0], masks[1], masks[2], masks[3], preMult, dt); } else if (bands == 3) { return new DirectColorModel( cs, bits, masks[0], masks[1], masks[2], 0x0, preMult, dt); } else { throw new IllegalArgumentException( "Incompatible number of bands out for ColorModel"); } } throw new IllegalArgumentException( "Unsupported SampleModel Type"); } } ././@LongLink0100644 0000000 0000000 00000000152 13777276623 011655 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/rendered/RenderedImageCachableRed.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/rendered/RenderedImageCachableRed0100644 0000000 0000000 00000010614 13777276623 032443 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: RenderedImageCachableRed.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.image.rendered; import java.awt.Rectangle; import java.awt.Shape; import java.awt.image.BufferedImage; import java.awt.image.ColorModel; import java.awt.image.Raster; import java.awt.image.RenderedImage; import java.awt.image.SampleModel; import java.awt.image.WritableRaster; import java.util.Vector; // CSOFF: NeedBraces // CSOFF: WhitespaceAround /** * This implements CachableRed around a RenderedImage. * You can use this to wrap a RenderedImage that you want to * appear as a CachableRed. * It essentially ignores the dependency and dirty region methods. * * @version $Id: RenderedImageCachableRed.java 1732018 2016-02-24 04:51:06Z gadams $ * * Originally authored by Thomas DeWeese. */ public class RenderedImageCachableRed implements CachableRed { public static CachableRed wrap(RenderedImage ri) { if (ri instanceof CachableRed) { return (CachableRed) ri; } if (ri instanceof BufferedImage) { return new BufferedImageCachableRed((BufferedImage)ri); } return new RenderedImageCachableRed(ri); } private RenderedImage src; private Vector srcs = new Vector(0); public RenderedImageCachableRed(RenderedImage src) { if (src == null) { throw new NullPointerException(); } this.src = src; } public Vector getSources() { return srcs; // should always be empty... } public Rectangle getBounds() { return new Rectangle(getMinX(), // could we cache the rectangle?? getMinY(), getWidth(), getHeight()); } public int getMinX() { return src.getMinX(); } public int getMinY() { return src.getMinY(); } public int getWidth() { return src.getWidth(); } public int getHeight() { return src.getHeight(); } public ColorModel getColorModel() { return src.getColorModel(); } public SampleModel getSampleModel() { return src.getSampleModel(); } public int getMinTileX() { return src.getMinTileX(); } public int getMinTileY() { return src.getMinTileY(); } public int getNumXTiles() { return src.getNumXTiles(); } public int getNumYTiles() { return src.getNumYTiles(); } public int getTileGridXOffset() { return src.getTileGridXOffset(); } public int getTileGridYOffset() { return src.getTileGridYOffset(); } public int getTileWidth() { return src.getTileWidth(); } public int getTileHeight() { return src.getTileHeight(); } public Object getProperty(String name) { return src.getProperty(name); } public String[] getPropertyNames() { return src.getPropertyNames(); } public Raster getTile(int tileX, int tileY) { return src.getTile(tileX, tileY); } public WritableRaster copyData(WritableRaster raster) { return src.copyData(raster); } public Raster getData() { return src.getData(); } public Raster getData(Rectangle rect) { return src.getData(rect); } public Shape getDependencyRegion(int srcIndex, Rectangle outputRgn) { throw new IndexOutOfBoundsException( "Nonexistant source requested."); } public Shape getDirtyRegion(int srcIndex, Rectangle inputRgn) { throw new IndexOutOfBoundsException( "Nonexistant source requested."); } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/rendered/package.html0100644 0000000 0000000 00000001745 13777276623 030255 0ustar000000000 0000000 org.apache.xmlgraphics.image.rendered Package

    Specialized subclasses of RenderedImage for various tasks (color space conversion, caching etc.)

    xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/writer/AbstractImageWriter.java0100644 0000000 0000000 00000003607 13777276623 032265 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: AbstractImageWriter.java 750418 2009-03-05 11:03:54Z vhennebert $ */ package org.apache.xmlgraphics.image.writer; import java.io.IOException; import java.io.OutputStream; /** * Abstract base class for ImageWriter implementations. * * @version $Id: AbstractImageWriter.java 750418 2009-03-05 11:03:54Z vhennebert $ */ public abstract class AbstractImageWriter implements ImageWriter { /** * @see org.apache.xmlgraphics.image.writer.ImageWriter#createMultiImageWriter( * java.io.OutputStream) */ public MultiImageWriter createMultiImageWriter(OutputStream out) throws IOException { throw new UnsupportedOperationException("This ImageWriter does not support writing" + " multiple images to a single image file."); } /** @see org.apache.xmlgraphics.image.writer.ImageWriter#isFunctional() */ public boolean isFunctional() { return true; } /** @see org.apache.xmlgraphics.image.writer.ImageWriter#supportsMultiImageWriter() */ public boolean supportsMultiImageWriter() { return false; } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/writer/Endianness.java0100644 0000000 0000000 00000004105 13777276623 030443 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: Endianness.java 1732019 2016-02-24 05:01:10Z gadams $ */ package org.apache.xmlgraphics.image.writer; /** * Enumeration for specifying the endianness of the image. * * @see Wikipedia on Endianness */ public enum Endianness { /** * Default endianness. This can be different depending on the output format or is used * when the image format doesn't allow to specify the endianness. */ DEFAULT, /** Little endian, least significant byte first, LSB, Intel Format. */ LITTLE_ENDIAN, /** Big endian, most significant byte first, MSB, Motorola Format. */ BIG_ENDIAN; /** * Translates an endian type specified in the configuration file into the * equivalent type should one exist. * @param value The value specified in the configration file * @return Returns the Endianess object of the found type. If no type matches * it returns null. */ public static Endianness getEndianType(String value) { if (value != null) { for (Endianness endianValue : Endianness.values()) { if (endianValue.toString().equalsIgnoreCase(value)) { return endianValue; } } } return null; } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/writer/ImageWriter.java0100644 0000000 0000000 00000005160 13777276623 030575 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageWriter.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.image.writer; import java.awt.image.RenderedImage; import java.io.IOException; import java.io.OutputStream; /** * Interface which allows image library independent image writing. * * @version $Id: ImageWriter.java 1732018 2016-02-24 04:51:06Z gadams $ */ public interface ImageWriter { /** * Encodes an image and writes it to an OutputStream. * @param image the image to be encoded * @param out the OutputStream to write to * @throws IOException In case of an /IO problem */ void writeImage(RenderedImage image, OutputStream out) throws IOException; /** * Encodes an image and writes it to an OutputStream. * @param image the image to be encoded * @param out the OutputStream to write to * @param params a parameters object to customize the encoding. * @throws IOException In case of an /IO problem */ void writeImage(RenderedImage image, OutputStream out, ImageWriterParams params) throws IOException; /** @return the target MIME type supported by this ImageWriter */ String getMIMEType(); /** @return true if the ImageWriter is expected to work properly in the current environment */ boolean isFunctional(); /** @return true if the implemented format supports multiple pages in a single file */ boolean supportsMultiImageWriter(); /** * Creates a MultiImageWriter instance that lets you put multiple pages into a single file * if the format supports it. * @param out the OutputStream to write the image to * @return the requested MultiImageWriter instance * @throws IOException In case of an /IO problem */ MultiImageWriter createMultiImageWriter(OutputStream out) throws IOException; } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/writer/ImageWriterParams.java0100644 0000000 0000000 00000014744 13777276623 031751 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageWriterParams.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.image.writer; /** * Parameters for the encoder which is accessed through the * ImageWriter interface. * * @version $Id: ImageWriterParams.java 1732018 2016-02-24 04:51:06Z gadams $ */ public class ImageWriterParams { /** Forces a single strip for the whole image. */ public static final int SINGLE_STRIP = -1; /** Used for generating exactly one strip for each row */ public static final int ONE_ROW_PER_STRIP = 1; private Integer xResolution; private Integer yResolution; private Float jpegQuality; private Boolean jpegForceBaseline; private String compressionMethod; private ResolutionUnit resolutionUnit = ResolutionUnit.INCH; private int rowsPerStrip = ONE_ROW_PER_STRIP; private Endianness endianness = Endianness.DEFAULT; /** * Default constructor. */ public ImageWriterParams() { //nop } /** * @return true if resolution has been set */ public boolean hasResolution() { return getXResolution() != null && getYResolution() != null; } /** * @return the image resolution in dpi, or null if undefined */ public Integer getResolution() { return getXResolution(); } /** * @return the quality value for encoding a JPEG image * (0.0-1.0), or null if undefined */ public Float getJPEGQuality() { return this.jpegQuality; } /** * @return true if the baseline quantization table is forced, * or null if undefined. */ public Boolean getJPEGForceBaseline() { return this.jpegForceBaseline; } /** @return the compression method for encoding the image */ public String getCompressionMethod() { return this.compressionMethod; } /** * Sets the target resolution of the bitmap image to be written * (sets both the horizontal and vertical resolution to the same value). * @param resolution the resolution */ public void setResolution(int resolution) { setXResolution(resolution); setYResolution(resolution); } /** * Sets the quality setting for encoding JPEG images. * @param quality the quality setting (0.0-1.0) * @param forceBaseline force baseline quantization table */ public void setJPEGQuality(float quality, boolean forceBaseline) { this.jpegQuality = quality; this.jpegForceBaseline = forceBaseline ? Boolean.TRUE : Boolean.FALSE; } /** * Set the compression method that shall be used to encode the image. * @param method the compression method */ public void setCompressionMethod(String method) { this.compressionMethod = method; } /** * Checks if image is single strip (required by some fax processors). * @return true if one row per strip. */ public boolean isSingleStrip() { return rowsPerStrip == SINGLE_STRIP; } /** * Convenience method to set rows per strip to single strip, * otherwise sets to one row per strip. * @param isSingle true if a single strip shall be produced, false if multiple strips are ok */ public void setSingleStrip(boolean isSingle) { rowsPerStrip = isSingle ? SINGLE_STRIP : ONE_ROW_PER_STRIP; } /** * Sets the rows per strip (default is one row per strip); * if set to -1 (single strip), will use height of the current page, * required by some fax processors. * @param rowsPerStrip the value to set. */ public void setRowsPerStrip(int rowsPerStrip) { this.rowsPerStrip = rowsPerStrip; } /** * The number of rows per strip of the TIFF image, default 1. A value of -1 * indicates a single strip per page will be used and RowsPerStrip will be set * to image height for the associated page. * @return the number of rows per strip, default 1. */ public int getRowsPerStrip() { return rowsPerStrip; } /** * Returns the unit in which resolution values are given (ex. units per inch). * @return the resolution unit. */ public ResolutionUnit getResolutionUnit() { return resolutionUnit; } /** * Sets the resolution unit of the image for calculating resolution. * @param resolutionUnit the resolution unit (inches, centimeters etc.) */ public void setResolutionUnit(ResolutionUnit resolutionUnit) { this.resolutionUnit = resolutionUnit; } /** * @return the horizontal image resolution in the current resolution unit, or null if undefined */ public Integer getXResolution() { return xResolution; } /** * Sets the target horizontal resolution of the bitmap image to be written. * @param resolution the resolution value */ public void setXResolution(int resolution) { xResolution = resolution; } /** * @return the vertical image resolution in the current resolution unit, or null if undefined */ public Integer getYResolution() { return yResolution; } /** * Sets the target vertical resolution of the bitmap image to be written. * @param resolution the resolution value */ public void setYResolution(int resolution) { yResolution = resolution; } /** * Returns the endianness selected for the image. * @return the endianness */ public Endianness getEndianness() { return this.endianness; } /** * Sets the endianness selected for the image. * @param endianness the endianness */ public void setEndianness(Endianness endianness) { this.endianness = endianness; } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/writer/ImageWriterRegistry.java0100644 0000000 0000000 00000014223 13777276623 032326 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageWriterRegistry.java 1804124 2017-08-04 14:13:54Z ssteiner $ */ package org.apache.xmlgraphics.image.writer; import java.io.IOException; import java.io.InputStream; import java.util.Iterator; import java.util.List; import java.util.ListIterator; import java.util.Map; import java.util.Properties; import org.apache.xmlgraphics.util.Service; /** * Registry for {@link ImageWriter} implementations. */ public final class ImageWriterRegistry { private static volatile ImageWriterRegistry instance; private Map> imageWriterMap = new java.util.HashMap>(); private Map preferredOrder; /** * Default constructor. The default preferred order for the image writers is loaded from the * resources. */ public ImageWriterRegistry() { Properties props = new Properties(); InputStream in = getClass().getResourceAsStream("default-preferred-order.properties"); if (in != null) { try { try { props.load(in); } finally { in.close(); } } catch (IOException ioe) { throw new RuntimeException( "Could not load default preferred order due to I/O error: " + ioe.getMessage()); } } setPreferredOrder(props); setup(); } /** * Special constructor. The preferred order for the image writers can be specified as a * Map (for example a Properties file). The entries of the Map consists of fully qualified * class or package names as keys and integer numbers as values. Zero (0) is the default * priority. * @param preferredOrder the map of order properties used to order the plug-ins */ public ImageWriterRegistry(Properties preferredOrder) { setPreferredOrder(preferredOrder); setup(); } private void setPreferredOrder(Properties preferredOrder) { Map order = new java.util.HashMap(); for (Map.Entry entry : preferredOrder.entrySet()) { order.put(entry.getKey().toString(), Integer.parseInt(entry.getValue().toString())); } this.preferredOrder = order; } /** @return a singleton instance of the ImageWriterRegistry. */ public static ImageWriterRegistry getInstance() { if (instance == null) { instance = new ImageWriterRegistry(); } return instance; } private void setup() { Iterator iter = Service.providers(ImageWriter.class); while (iter.hasNext()) { ImageWriter writer = (ImageWriter)iter.next(); register(writer); } } private int getPriority(ImageWriter writer) { String key = writer.getClass().getName(); Integer value = preferredOrder.get(key); while (value == null) { int pos = key.lastIndexOf("."); if (pos < 0) { break; } key = key.substring(0, pos); value = preferredOrder.get(key); } return (value != null) ? value : 0; } /** * Registers a new ImageWriter implementation with the associated priority in the registry. * Higher priorities get preference over lower priorities. * @param writer the ImageWriter instance to register. * @param priority the priority of the writer in the registry. * @see #register(ImageWriter) */ public void register(ImageWriter writer, int priority) { String key = writer.getClass().getName(); // Register the priority to preferredOrder; overwrite original priority if exists preferredOrder.put(key, priority); register(writer); } /** * Registers a new ImageWriter implementation in the registry. If an ImageWriter for the same * target MIME type has already been registered, it is placed in an array based on priority. * @param writer the ImageWriter instance to register. */ public synchronized void register(ImageWriter writer) { List entries = imageWriterMap.get(writer.getMIMEType()); if (entries == null) { entries = new java.util.ArrayList(); imageWriterMap.put(writer.getMIMEType(), entries); } int priority = getPriority(writer); ListIterator li = entries.listIterator(); while (li.hasNext()) { ImageWriter w = li.next(); if (getPriority(w) < priority) { li.previous(); break; } } li.add(writer); } /** * Returns an ImageWriter that can be used to encode an image to the requested MIME type. * @param mime the MIME type of the desired output format * @return a functional ImageWriter instance handling the desired output format or * null if none can be found. */ public synchronized ImageWriter getWriterFor(String mime) { List entries = imageWriterMap.get(mime); if (entries == null) { return null; } for (ImageWriter writer : entries) { if (writer.isFunctional()) { return writer; } } return null; } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/writer/ImageWriterUtil.java0100644 0000000 0000000 00000005574 13777276623 031444 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageWriterUtil.java 1345683 2012-06-03 14:50:33Z gadams $ */ package org.apache.xmlgraphics.image.writer; import java.awt.image.RenderedImage; import java.io.File; import java.io.IOException; import java.io.OutputStream; import org.apache.commons.io.IOUtils; /** * Convenience methods around ImageWriter for the most important tasks. */ public final class ImageWriterUtil { private ImageWriterUtil() { } /** * Saves a RenderedImage as a PNG file with 96 dpi. * @param bitmap the bitmap to encode * @param outputFile the target file * @throws IOException in case of an I/O problem */ public static void saveAsPNG(RenderedImage bitmap, File outputFile) throws IOException { saveAsPNG(bitmap, 96, outputFile); } /** * Saves a RenderedImage as a PNG file. * @param bitmap the bitmap to encode * @param resolution the bitmap resolution * @param outputFile the target file * @throws IOException in case of an I/O problem */ public static void saveAsPNG(RenderedImage bitmap, int resolution, File outputFile) throws IOException { saveAsFile(bitmap, resolution, outputFile, "image/png"); } /** * Saves a RenderedImage as a file. The image format is given through the MIME type * @param bitmap the bitmap to encode * @param resolution the bitmap resolution * @param outputFile the target file * @param mime the MIME type of the target file * @throws IOException in case of an I/O problem */ public static void saveAsFile(RenderedImage bitmap, int resolution, File outputFile, String mime) throws IOException { OutputStream out = new java.io.FileOutputStream(outputFile); try { ImageWriter writer = ImageWriterRegistry.getInstance().getWriterFor(mime); ImageWriterParams params = new ImageWriterParams(); params.setResolution(resolution); writer.writeImage(bitmap, out, params); } finally { IOUtils.closeQuietly(out); } } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/writer/MultiImageWriter.java0100644 0000000 0000000 00000003110 13777276623 031601 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: MultiImageWriter.java 1345683 2012-06-03 14:50:33Z gadams $ */ package org.apache.xmlgraphics.image.writer; import java.awt.image.RenderedImage; import java.io.IOException; /** * Interface which allows writing multiple images into one image file if the output format * supports this feature. * * @version $Id: MultiImageWriter.java 1345683 2012-06-03 14:50:33Z gadams $ */ public interface MultiImageWriter { /** * Encodes an image and writes it to the image file. * @param image the image to be encoded * @param params a parameters object to customize the encoding. * @throws IOException In case of an /IO problem */ void writeImage(RenderedImage image, ImageWriterParams params) throws IOException; void close() throws IOException; } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/writer/ResolutionUnit.java0100644 0000000 0000000 00000004556 13777276623 031371 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ResolutionUnit.java 1732019 2016-02-24 05:01:10Z gadams $ */ package org.apache.xmlgraphics.image.writer; import java.util.EnumSet; import java.util.HashMap; import java.util.Map; /** * Enumeration for resolution units used by images; 1 for None, 2 for Inch and 3 for Centimeter. */ public enum ResolutionUnit { /** no resolution unit */ NONE(1, "None"), /** units per inch */ INCH(2, "Inch"), /** units per centimeter */ CENTIMETER(3, "Centimeter"); //Reverse Lookup Table private static final Map LOOKUP = new HashMap(); static { for (ResolutionUnit unit : EnumSet.allOf(ResolutionUnit.class)) { LOOKUP.put(unit.getValue(), unit); } } private final int value; private final String description; private ResolutionUnit(int value, String description) { this.value = value; this.description = description; } /** * Retrieves the numeric value of the resolution unit. * * @return 1, 2 or 3. */ public int getValue() { return value; } /** * Retrieves the standard textual description of the resolution unit. * * @return None, Inch or Centimeter. */ public String getDescription() { return description; } /** * Reverse lookup by value. * * @param value the numeric value of the resolution unit * @return the resolution unit */ public static ResolutionUnit get(int value) { return LOOKUP.get(value); } } ././@LongLink0100644 0000000 0000000 00000000152 13777276623 011655 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/writer/imageio/ImageIOImageWriter.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/writer/imageio/ImageIOImageWriter0100644 0000000 0000000 00000032224 13777276623 032463 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageIOImageWriter.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.image.writer.imageio; import java.awt.image.RenderedImage; import java.io.IOException; import java.io.OutputStream; import java.util.Iterator; import javax.imageio.IIOImage; import javax.imageio.ImageIO; import javax.imageio.ImageTypeSpecifier; import javax.imageio.ImageWriteParam; import javax.imageio.event.IIOWriteWarningListener; import javax.imageio.metadata.IIOInvalidTreeException; import javax.imageio.metadata.IIOMetadata; import javax.imageio.metadata.IIOMetadataNode; import javax.imageio.stream.ImageOutputStream; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.apache.xmlgraphics.image.writer.ImageWriter; import org.apache.xmlgraphics.image.writer.ImageWriterParams; import org.apache.xmlgraphics.image.writer.MultiImageWriter; import org.apache.xmlgraphics.image.writer.ResolutionUnit; import org.apache.xmlgraphics.util.UnitConv; /** * ImageWriter implementation that uses Image I/O to write images. * * @version $Id: ImageIOImageWriter.java 1732018 2016-02-24 04:51:06Z gadams $ */ public class ImageIOImageWriter implements ImageWriter, IIOWriteWarningListener { private static final String DIMENSION = "Dimension"; private static final String VERTICAL_PIXEL_SIZE = "VerticalPixelSize"; private static final String HORIZONTAL_PIXEL_SIZE = "HorizontalPixelSize"; private static final String STANDARD_METADATA_FORMAT = "javax_imageio_1.0"; private String targetMIME; /** * Main constructor. * @param mime the MIME type of the image format */ public ImageIOImageWriter(String mime) { this.targetMIME = mime; } /** {@inheritDoc} */ public void writeImage(RenderedImage image, OutputStream out) throws IOException { writeImage(image, out, null); } /** {@inheritDoc} */ public void writeImage(RenderedImage image, OutputStream out, ImageWriterParams params) throws IOException { javax.imageio.ImageWriter iiowriter = getIIOImageWriter(); iiowriter.addIIOWriteWarningListener(this); ImageOutputStream imgout = ImageIO.createImageOutputStream(out); try { ImageWriteParam iwParam = getDefaultWriteParam(iiowriter, image, params); IIOMetadata streamMetadata = createStreamMetadata(iiowriter, iwParam, params); ImageTypeSpecifier type; if (iwParam.getDestinationType() != null) { type = iwParam.getDestinationType(); } else { type = ImageTypeSpecifier.createFromRenderedImage(image); } //Handle metadata IIOMetadata meta = iiowriter.getDefaultImageMetadata( type, iwParam); //meta might be null for some JAI codecs as they don't support metadata if (params != null && meta != null) { meta = updateMetadata(image, meta, params); } //Write image iiowriter.setOutput(imgout); IIOImage iioimg = new IIOImage(image, null, meta); iiowriter.write(streamMetadata, iioimg, iwParam); } finally { imgout.close(); iiowriter.dispose(); } } /** * Creates the stream metadata for image. By default, this method returns null which * causes the default stream metadata to be used. Subclasses can override this to * supply special stream metadata (see TIFF for an example). * @param writer the image write * @param writeParam the ImageIO write parameters * @param params the ImageWriter write parameters * @return the stream metadata (or null if no special metadata needs to be produced) */ protected IIOMetadata createStreamMetadata(javax.imageio.ImageWriter writer, ImageWriteParam writeParam, ImageWriterParams params) { return null; //leave the default } private javax.imageio.ImageWriter getIIOImageWriter() { Iterator iter = ImageIO.getImageWritersByMIMEType(getMIMEType()); javax.imageio.ImageWriter iiowriter = null; if (iter.hasNext()) { iiowriter = iter.next(); } if (iiowriter == null) { throw new UnsupportedOperationException("No ImageIO codec for writing " + getMIMEType() + " is available!"); } return iiowriter; } /** * Returns the default write parameters for encoding the image. * @param iiowriter The IIO ImageWriter that will be used * @param image the image to be encoded * @param params the parameters for this writer instance * @return the IIO ImageWriteParam instance */ protected ImageWriteParam getDefaultWriteParam( javax.imageio.ImageWriter iiowriter, RenderedImage image, ImageWriterParams params) { ImageWriteParam param = iiowriter.getDefaultWriteParam(); //System.err.println("Param: " + params); if ((params != null) && (params.getCompressionMethod() != null)) { param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); param.setCompressionType(params.getCompressionMethod()); } return param; } /** * Updates the metadata information based on the parameters to this writer. * @param image the current image being rendered * @param meta the metadata * @param params the parameters * @return the updated metadata */ protected IIOMetadata updateMetadata(RenderedImage image, IIOMetadata meta, ImageWriterParams params) { if (meta.isStandardMetadataFormatSupported() && params.getResolution() != null) { //NOTE: There are several bugs in ImageIO codecs concerning resolution handling //http://www.tracemodeler.com/articles/aging-bugs-and-setting-dpi-with-java-image-io/ float multiplier = (ResolutionUnit.CENTIMETER == params.getResolutionUnit()) ? 10f : UnitConv.IN2MM; double pixelWidthInMillimeters = multiplier / params.getXResolution().doubleValue(); double pixelHeightInMillimeters = multiplier / params.getYResolution().doubleValue(); //Try with the right value as per the ImageIO spec updatePixelSize(meta, pixelWidthInMillimeters, pixelHeightInMillimeters); //Check the merge result double checkMerged = getHorizontalPixelSize(meta); if (!equals(checkMerged, pixelWidthInMillimeters, 0.00001)) { //Merging bug in Sun/Oracle JRE encountered //Try compensation strategy for PNG bug: //http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5106305 double horzValue = 1 / pixelWidthInMillimeters; double vertValue = 1 / pixelHeightInMillimeters; updatePixelSize(meta, horzValue, vertValue); } } return meta; } private static boolean equals(double d1, double d2, double maxDelta) { return Math.abs(d1 - d2) <= maxDelta; } private double getHorizontalPixelSize(IIOMetadata meta) { double result = 0; IIOMetadataNode root = (IIOMetadataNode)meta.getAsTree(STANDARD_METADATA_FORMAT); IIOMetadataNode dim = getChildNode(root, DIMENSION); if (dim != null) { IIOMetadataNode horz = getChildNode(dim, HORIZONTAL_PIXEL_SIZE); if (horz != null) { result = Double.parseDouble(horz.getAttribute("value")); } } return result; } private void updatePixelSize(IIOMetadata meta, double horzValue, double vertValue) { IIOMetadataNode root = (IIOMetadataNode)meta.getAsTree(STANDARD_METADATA_FORMAT); IIOMetadataNode dim = getChildNode(root, DIMENSION); IIOMetadataNode child; child = getChildNode(dim, HORIZONTAL_PIXEL_SIZE); if (child == null) { child = new IIOMetadataNode(HORIZONTAL_PIXEL_SIZE); dim.appendChild(child); } child.setAttribute("value", Double.toString(horzValue)); child = getChildNode(dim, VERTICAL_PIXEL_SIZE); if (child == null) { child = new IIOMetadataNode(VERTICAL_PIXEL_SIZE); dim.appendChild(child); } child.setAttribute("value", Double.toString(vertValue)); try { meta.mergeTree(STANDARD_METADATA_FORMAT, root); } catch (IIOInvalidTreeException e) { throw new RuntimeException("Cannot update image metadata: " + e.getMessage()); } } /** * Returns a specific metadata child node * @param n the base node * @param name the name of the child * @return the requested child node */ protected static IIOMetadataNode getChildNode(Node n, String name) { NodeList nodes = n.getChildNodes(); for (int i = 0; i < nodes.getLength(); i++) { Node child = nodes.item(i); if (name.equals(child.getNodeName())) { return (IIOMetadataNode)child; } } return null; } /** {@inheritDoc} */ public String getMIMEType() { return this.targetMIME; } /** {@inheritDoc} */ public boolean isFunctional() { Iterator iter = ImageIO.getImageWritersByMIMEType(getMIMEType()); //Only return true if an IIO ImageWriter is available in the current environment return (iter.hasNext()); } /** {@inheritDoc} */ public void warningOccurred(javax.imageio.ImageWriter source, int imageIndex, String warning) { System.err.println("Problem while writing image using ImageI/O: " + warning); } /** {@inheritDoc} */ public MultiImageWriter createMultiImageWriter(OutputStream out) throws IOException { return new IIOMultiImageWriter(out); } /** {@inheritDoc} */ public boolean supportsMultiImageWriter() { javax.imageio.ImageWriter iiowriter = getIIOImageWriter(); try { return iiowriter.canWriteSequence(); } finally { iiowriter.dispose(); } } private class IIOMultiImageWriter implements MultiImageWriter { private javax.imageio.ImageWriter iiowriter; private ImageOutputStream imageStream; private boolean prepared; public IIOMultiImageWriter(OutputStream out) throws IOException { this.iiowriter = getIIOImageWriter(); if (!iiowriter.canWriteSequence()) { throw new UnsupportedOperationException("This ImageWriter does not support writing" + " multiple images to a single image file."); } iiowriter.addIIOWriteWarningListener(ImageIOImageWriter.this); imageStream = ImageIO.createImageOutputStream(out); iiowriter.setOutput(imageStream); } public void writeImage(RenderedImage image, ImageWriterParams params) throws IOException { if (iiowriter == null) { throw new IllegalStateException("MultiImageWriter already closed!"); } ImageWriteParam iwParam = getDefaultWriteParam(iiowriter, image, params); if (!prepared) { //Only prepare once IIOMetadata streamMetadata = createStreamMetadata(iiowriter, iwParam, params); iiowriter.prepareWriteSequence(streamMetadata); prepared = true; } ImageTypeSpecifier type; if (iwParam.getDestinationType() != null) { type = iwParam.getDestinationType(); } else { type = ImageTypeSpecifier.createFromRenderedImage(image); } //Handle metadata IIOMetadata meta = iiowriter.getDefaultImageMetadata( type, iwParam); //meta might be null for some JAI codecs as they don't support metadata if (params != null && meta != null) { meta = updateMetadata(image, meta, params); } //Write image IIOImage iioimg = new IIOImage(image, null, meta); iiowriter.writeToSequence(iioimg, iwParam); } public void close() throws IOException { imageStream.close(); imageStream = null; iiowriter.dispose(); iiowriter = null; } } } ././@LongLink0100644 0000000 0000000 00000000156 13777276623 011661 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/writer/imageio/ImageIOJPEGImageWriter.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/writer/imageio/ImageIOJPEGImageWr0100644 0000000 0000000 00000013707 13777276623 032252 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageIOJPEGImageWriter.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.image.writer.imageio; import java.awt.image.RenderedImage; import javax.imageio.ImageWriteParam; import javax.imageio.ImageWriter; import javax.imageio.metadata.IIOInvalidTreeException; import javax.imageio.metadata.IIOMetadata; import javax.imageio.metadata.IIOMetadataNode; import javax.imageio.plugins.jpeg.JPEGImageWriteParam; import org.apache.xmlgraphics.image.writer.ImageWriterParams; /** * ImageWriter that encodes JPEG images using Image I/O. * * @version $Id: ImageIOJPEGImageWriter.java 1732018 2016-02-24 04:51:06Z gadams $ */ public class ImageIOJPEGImageWriter extends ImageIOImageWriter { private static final String JPEG_NATIVE_FORMAT = "javax_imageio_jpeg_image_1.0"; /** * Main constructor. */ public ImageIOJPEGImageWriter() { super("image/jpeg"); } @Override protected IIOMetadata updateMetadata(RenderedImage image, IIOMetadata meta, ImageWriterParams params) { if (JPEG_NATIVE_FORMAT.equals(meta.getNativeMetadataFormatName())) { meta = addAdobeTransform(meta); IIOMetadataNode root = (IIOMetadataNode)meta.getAsTree(JPEG_NATIVE_FORMAT); IIOMetadataNode jv = getChildNode(root, "JPEGvariety"); if (jv == null) { jv = new IIOMetadataNode("JPEGvariety"); root.appendChild(jv); } IIOMetadataNode child; if (params.getResolution() != null) { child = getChildNode(jv, "app0JFIF"); if (child == null) { child = new IIOMetadataNode("app0JFIF"); jv.appendChild(child); } //JPEG gets special treatment because there seems to be a bug in //the JPEG codec in ImageIO converting the pixel size incorrectly //(or not at all) when using standard metadata format. child.setAttribute("majorVersion", null); child.setAttribute("minorVersion", null); switch (params.getResolutionUnit()) { case INCH: child.setAttribute("resUnits", "1"); //dots per inch break; case CENTIMETER: child.setAttribute("resUnits", "2"); //dots per cm break; default: child.setAttribute("resUnits", "0"); //no unit } child.setAttribute("Xdensity", params.getXResolution().toString()); child.setAttribute("Ydensity", params.getYResolution().toString()); child.setAttribute("thumbWidth", null); child.setAttribute("thumbHeight", null); } try { meta.setFromTree(JPEG_NATIVE_FORMAT, root); //meta.mergeTree(JPEG_NATIVE_FORMAT, root); } catch (IIOInvalidTreeException e) { throw new RuntimeException("Cannot update image metadata: " + e.getMessage(), e); } } return meta; } private static IIOMetadata addAdobeTransform(IIOMetadata meta) { // add the adobe transformation (transform 1 -> to YCbCr) IIOMetadataNode root = (IIOMetadataNode)meta.getAsTree(JPEG_NATIVE_FORMAT); IIOMetadataNode markerSequence = getChildNode(root, "markerSequence"); if (markerSequence == null) { throw new RuntimeException("Invalid metadata!"); } IIOMetadataNode adobeTransform = getChildNode(markerSequence, "app14Adobe"); if (adobeTransform == null) { adobeTransform = new IIOMetadataNode("app14Adobe"); adobeTransform.setAttribute("transform" , "1"); // convert RGB to YCbCr adobeTransform.setAttribute("version", "101"); adobeTransform.setAttribute("flags0", "0"); adobeTransform.setAttribute("flags1", "0"); markerSequence.appendChild(adobeTransform); } else { adobeTransform.setAttribute("transform" , "1"); } try { meta.setFromTree(JPEG_NATIVE_FORMAT, root); } catch (IIOInvalidTreeException e) { throw new RuntimeException("Cannot update image metadata: " + e.getMessage(), e); } return meta; } /** {@inheritDoc} */ @Override protected ImageWriteParam getDefaultWriteParam( ImageWriter iiowriter, RenderedImage image, ImageWriterParams params) { JPEGImageWriteParam param = new JPEGImageWriteParam(iiowriter.getLocale()); //ImageTypeSpecifier type = ImageTypeSpecifier.createFromRenderedImage(image); /* ImageTypeSpecifier type = new ImageTypeSpecifier( image.getColorModel(), image.getSampleModel()); */ /* didn't work as expected... ImageTypeSpecifier type = ImageTypeSpecifier.createFromBufferedImageType( BufferedImage.TYPE_INT_RGB); param.setDestinationType(type); param.setSourceBands(new int[] {0, 1, 2}); */ return param; } } ././@LongLink0100644 0000000 0000000 00000000155 13777276623 011660 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/writer/imageio/ImageIOPNGImageWriter.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/writer/imageio/ImageIOPNGImageWri0100644 0000000 0000000 00000002360 13777276623 032313 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageIOPNGImageWriter.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.image.writer.imageio; /** * ImageWriter that encodes PNG images using Image I/O. * * @version $Id: ImageIOPNGImageWriter.java 1732018 2016-02-24 04:51:06Z gadams $ */ public class ImageIOPNGImageWriter extends ImageIOImageWriter { /** * Main constructor. */ public ImageIOPNGImageWriter() { super("image/png"); } } ././@LongLink0100644 0000000 0000000 00000000156 13777276623 011661 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/writer/imageio/ImageIOTIFFImageWriter.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/writer/imageio/ImageIOTIFFImageWr0100644 0000000 0000000 00000023747 13777276623 032262 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageIOTIFFImageWriter.java 1833700 2018-06-18 10:08:45Z ssteiner $ */ package org.apache.xmlgraphics.image.writer.imageio; import java.awt.image.RenderedImage; import java.util.Arrays; import java.util.Set; import javax.imageio.ImageWriteParam; import javax.imageio.metadata.IIOInvalidTreeException; import javax.imageio.metadata.IIOMetadata; import javax.imageio.metadata.IIOMetadataNode; import org.w3c.dom.Node; import org.apache.xmlgraphics.image.codec.tiff.TIFFImageDecoder; import org.apache.xmlgraphics.image.writer.Endianness; import org.apache.xmlgraphics.image.writer.ImageWriterParams; import org.apache.xmlgraphics.image.writer.ResolutionUnit; // CSOFF: MultipleVariableDeclarations /** * ImageWriter that encodes TIFF images using Image I/O. * * @version $Id: ImageIOTIFFImageWriter.java 1833700 2018-06-18 10:08:45Z ssteiner $ */ public class ImageIOTIFFImageWriter extends ImageIOImageWriter { private static final String SUN_TIFF_NATIVE_FORMAT = "com_sun_media_imageio_plugins_tiff_image_1.0"; private static final String JAVA_TIFF_NATIVE_FORMAT = "javax_imageio_tiff_image_1.0"; private static final String SUN_TIFF_NATIVE_STREAM_FORMAT = "com_sun_media_imageio_plugins_tiff_stream_1.0"; private static final String JAVA_TIFF_NATIVE_STREAM_FORMAT = "javax_imageio_tiff_stream_1.0"; /** * Main constructor. */ public ImageIOTIFFImageWriter() { super("image/tiff"); } /** {@inheritDoc} */ @Override protected IIOMetadata updateMetadata(RenderedImage image, IIOMetadata meta, ImageWriterParams params) { meta = super.updateMetadata(image, meta, params); //We set the resolution manually using the native format since it appears that //it doesn't work properly through the standard metadata. Haven't figured out why //that happens. if (params.getResolution() != null) { if (SUN_TIFF_NATIVE_FORMAT.equals(meta.getNativeMetadataFormatName()) || JAVA_TIFF_NATIVE_FORMAT.equals(meta.getNativeMetadataFormatName())) { IIOMetadataNode root = new IIOMetadataNode(meta.getNativeMetadataFormatName()); IIOMetadataNode ifd = getChildNode(root, "TIFFIFD"); if (ifd == null) { ifd = new IIOMetadataNode("TIFFIFD"); root.appendChild(ifd); } ifd.appendChild(createResolutionUnitField(params)); ifd.appendChild(createResolutionField(TIFFImageDecoder.TIFF_X_RESOLUTION, "XResolution", params.getXResolution(), params.getResolutionUnit())); ifd.appendChild(createResolutionField(TIFFImageDecoder.TIFF_Y_RESOLUTION, "YResolution", params.getYResolution(), params.getResolutionUnit())); int rows = params.isSingleStrip() ? image.getHeight() : params.getRowsPerStrip(); ifd.appendChild(createShortMetadataNode(TIFFImageDecoder.TIFF_ROWS_PER_STRIP, "RowsPerStrip", Integer.toString(rows))); try { meta.mergeTree(meta.getNativeMetadataFormatName(), root); } catch (IIOInvalidTreeException e) { throw new RuntimeException("Cannot update image metadata: " + e.getMessage(), e); } } } return meta; } //number of pixels in 100 Meters private static final String DENOMINATOR_CENTIMETER = "/" + (100 * 100); private static final String DENOMINATOR_INCH = "/" + 1; private IIOMetadataNode createResolutionField(int number, String name, Integer resolution, ResolutionUnit unit) { String value; if (unit == ResolutionUnit.INCH) { value = resolution + DENOMINATOR_INCH; } else { float pixSzMM = 25.4f / resolution.floatValue(); int numPix = (int)(((1000 * 100) / pixSzMM) + 0.5); value = numPix + DENOMINATOR_CENTIMETER; } return createRationalMetadataNode(number, name, value); } /** * Generate a TIFFField for resolution unit based on the parameters. * @param params * @return the new metadata node */ private IIOMetadataNode createResolutionUnitField(ImageWriterParams params) { return createShortMetadataNode(TIFFImageDecoder.TIFF_RESOLUTION_UNIT, "ResolutionUnit", Integer.toString(params.getResolutionUnit().getValue()), params.getResolutionUnit().getDescription()); } /** * Utility to create a TIFFShort metadata child node of a TIFFShorts node for TIFF metadata. * * @param number value of the number attribute of the TIFField * @param name value of the name attribute of the TIFFField * @param value value of the value attribute of the TIFFShort * @return the new metadata node */ public static final IIOMetadataNode createShortMetadataNode(int number, String name, String value) { return createShortMetadataNode(number, name, value, null); } /** * Utility to create a TIFFShort metadata child node of a TIFFShorts node for TIFF metadata. * * @param number value of the number attribute of the TIFField * @param name value of the name attribute of the TIFFField * @param value value of the value attribute of the TIFFShort * @param description value of the description attribute of the TIFFShort, ignored if null * @return the new metadata node */ public static final IIOMetadataNode createShortMetadataNode(int number, String name, String value, String description) { IIOMetadataNode field = createMetadataField(number, name); IIOMetadataNode arrayNode; IIOMetadataNode valueNode; arrayNode = new IIOMetadataNode("TIFFShorts"); field.appendChild(arrayNode); valueNode = new IIOMetadataNode("TIFFShort"); valueNode.setAttribute("value", value); if (description != null) { valueNode.setAttribute("description", description); } arrayNode.appendChild(valueNode); return field; } /** * Utility to create a TIFFRational metadata child node of a TIFFRationals node for * TIFF metadata. * * @param number value of the number attribute of the TIFField * @param name value of the name attribute of the TIFFField * @param value value of the value attribute of the TIFFRational * @return the new metadata node */ public static final IIOMetadataNode createRationalMetadataNode(int number, String name, String value) { IIOMetadataNode field = createMetadataField(number, name); IIOMetadataNode arrayNode; IIOMetadataNode valueNode; arrayNode = new IIOMetadataNode("TIFFRationals"); field.appendChild(arrayNode); valueNode = new IIOMetadataNode("TIFFRational"); valueNode.setAttribute("value", value); arrayNode.appendChild(valueNode); return field; } /** * Utility function to create a base TIFFField node for TIFF metadata. * * @param number value of the number attribute of the TIFField * @param name value of the name attribute of the TIFFField * @return the new metadata node */ public static final IIOMetadataNode createMetadataField(int number, String name) { IIOMetadataNode field = new IIOMetadataNode("TIFFField"); field.setAttribute("number", Integer.toString(number)); field.setAttribute("name", name); return field; } /** {@inheritDoc} */ @Override protected IIOMetadata createStreamMetadata(javax.imageio.ImageWriter writer, ImageWriteParam writeParam, ImageWriterParams params) { Endianness endian = (params != null ? params.getEndianness() : Endianness.DEFAULT); if (endian == Endianness.DEFAULT || endian == null) { return super.createStreamMetadata(writer, writeParam, params); } //Try changing the Byte Order IIOMetadata streamMetadata = writer.getDefaultStreamMetadata(writeParam); if (streamMetadata != null) { Set names = new java.util.HashSet( Arrays.asList(streamMetadata.getMetadataFormatNames())); setFromTree(names, streamMetadata, endian, SUN_TIFF_NATIVE_STREAM_FORMAT); setFromTree(names, streamMetadata, endian, JAVA_TIFF_NATIVE_STREAM_FORMAT); } return streamMetadata; } private void setFromTree(Set names, IIOMetadata streamMetadata, Endianness endian, String format) { if (names.contains(format)) { Node root = streamMetadata.getAsTree(format); root.getFirstChild().getAttributes().item(0).setNodeValue(endian.toString()); try { streamMetadata.setFromTree(format, root); } catch (IIOInvalidTreeException e) { //This should not happen since we check if the format is supported. throw new IllegalStateException( "Could not replace TIFF stream metadata: " + e.getMessage(), e); } } } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/writer/imageio/package.html0100644 0000000 0000000 00000001700 13777276623 031402 0ustar000000000 0000000 org.apache.xmlgraphics.image.writer.imageio Package

    Implementations of ImageWriter using the ImageIO API.

    ././@LongLink0100644 0000000 0000000 00000000147 13777276623 011661 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/writer/internal/PNGImageWriter.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/writer/internal/PNGImageWriter.ja0100644 0000000 0000000 00000003653 13777276623 032434 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: PNGImageWriter.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.image.writer.internal; import java.awt.image.RenderedImage; import java.io.IOException; import java.io.OutputStream; import org.apache.xmlgraphics.image.codec.png.PNGImageEncoder; import org.apache.xmlgraphics.image.writer.AbstractImageWriter; import org.apache.xmlgraphics.image.writer.ImageWriterParams; /** * ImageWriter implementation that uses the internal PNG codec to * write PNG files. * * @version $Id: PNGImageWriter.java 1732018 2016-02-24 04:51:06Z gadams $ */ public class PNGImageWriter extends AbstractImageWriter { /** {@inheritDoc} */ public void writeImage(RenderedImage image, OutputStream out) throws IOException { writeImage(image, out, null); } /** {@inheritDoc} */ public void writeImage(RenderedImage image, OutputStream out, ImageWriterParams params) throws IOException { PNGImageEncoder encoder = new PNGImageEncoder(out, null); encoder.encode(image); } /** {@inheritDoc} */ public String getMIMEType() { return "image/png"; } } ././@LongLink0100644 0000000 0000000 00000000150 13777276623 011653 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/writer/internal/TIFFImageWriter.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/writer/internal/TIFFImageWriter.j0100644 0000000 0000000 00000013224 13777276623 032372 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: TIFFImageWriter.java 1681108 2015-05-22 13:26:12Z ssteiner $ */ package org.apache.xmlgraphics.image.writer.internal; import java.awt.image.RenderedImage; import java.io.IOException; import java.io.OutputStream; import org.apache.xmlgraphics.image.codec.tiff.CompressionValue; import org.apache.xmlgraphics.image.codec.tiff.TIFFEncodeParam; import org.apache.xmlgraphics.image.codec.tiff.TIFFField; import org.apache.xmlgraphics.image.codec.tiff.TIFFImageDecoder; import org.apache.xmlgraphics.image.codec.tiff.TIFFImageEncoder; import org.apache.xmlgraphics.image.writer.AbstractImageWriter; import org.apache.xmlgraphics.image.writer.ImageWriterParams; import org.apache.xmlgraphics.image.writer.MultiImageWriter; import org.apache.xmlgraphics.image.writer.ResolutionUnit; /** * ImageWriter implementation that uses the internal TIFF codec to * write TIFF files. * * @version $Id: TIFFImageWriter.java 1681108 2015-05-22 13:26:12Z ssteiner $ */ public class TIFFImageWriter extends AbstractImageWriter { /** {@inheritDoc} */ public void writeImage(RenderedImage image, OutputStream out) throws IOException { writeImage(image, out, null); } /** {@inheritDoc} */ public void writeImage(RenderedImage image, OutputStream out, ImageWriterParams params) throws IOException { TIFFEncodeParam encodeParams = createTIFFEncodeParams(params); TIFFImageEncoder encoder = new TIFFImageEncoder(out, encodeParams); encoder.encode(image); } private TIFFEncodeParam createTIFFEncodeParams(ImageWriterParams params) { TIFFEncodeParam encodeParams = new TIFFEncodeParam(); if (params == null) { encodeParams.setCompression(CompressionValue.NONE); } else { encodeParams.setCompression(CompressionValue.getValue(params.getCompressionMethod())); if (params.getResolution() != null) { int numPixX; int numPixY; int denom; if (ResolutionUnit.INCH == params.getResolutionUnit()) { numPixX = params.getXResolution(); numPixY = params.getYResolution(); denom = 1; } else { // Set target resolution float pixXSzMM = 25.4f / params.getXResolution().floatValue(); float pixYSzMM = 25.4f / params.getYResolution().floatValue(); // num Pixs in 100 Meters numPixX = (int)(((1000 * 100) / pixXSzMM) + 0.5); numPixY = (int)(((1000 * 100) / pixYSzMM) + 0.5); denom = 100 * 100; // Centimeters per 100 Meters; } long [] xRational = {numPixX, denom}; long [] yRational = {numPixY, denom}; TIFFField [] fields = { new TIFFField(TIFFImageDecoder.TIFF_RESOLUTION_UNIT, TIFFField.TIFF_SHORT, 1, new char[] {(char)params.getResolutionUnit().getValue()}), new TIFFField(TIFFImageDecoder.TIFF_X_RESOLUTION, TIFFField.TIFF_RATIONAL, 1, new long[][] {xRational}), new TIFFField(TIFFImageDecoder.TIFF_Y_RESOLUTION, TIFFField.TIFF_RATIONAL, 1, new long[][] {yRational}) }; encodeParams.setExtraFields(fields); } } return encodeParams; } /** {@inheritDoc} */ public String getMIMEType() { return "image/tiff"; } /** {@inheritDoc} */ @Override public MultiImageWriter createMultiImageWriter(OutputStream out) throws IOException { return new TIFFMultiImageWriter(out); } /** {@inheritDoc} */ @Override public boolean supportsMultiImageWriter() { return true; } private class TIFFMultiImageWriter implements MultiImageWriter { private OutputStream out; private TIFFEncodeParam encodeParams; private TIFFImageEncoder encoder; private Object context; public TIFFMultiImageWriter(OutputStream out) throws IOException { this.out = out; } public void writeImage(RenderedImage image, ImageWriterParams params) throws IOException { if (encoder == null) { encodeParams = createTIFFEncodeParams(params); encoder = new TIFFImageEncoder(out, encodeParams); } context = encoder.encodeMultiple(context, image); } public void close() throws IOException { if (encoder != null) { encoder.finishMultiple(context); } encoder = null; encodeParams = null; out.flush(); } } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/writer/internal/package.html0100644 0000000 0000000 00000001713 13777276623 031610 0ustar000000000 0000000 org.apache.xmlgraphics.image.writer.internal Package

    Implementations of ImageWriter using Commons' own image codecs.

    xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/image/writer/package.html0100644 0000000 0000000 00000001677 13777276623 030005 0ustar000000000 0000000 org.apache.xmlgraphics.image.writer Package

    Abstraction layer with interfaces for writing bitmap images.

    xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/io/Resource.java0100644 0000000 0000000 00000003303 13777276623 026153 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: Resource.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.io; import java.io.FilterInputStream; import java.io.InputStream; /** * This class represents a resolved resource. The type property is used by XGC to identify the * resource content. */ public class Resource extends FilterInputStream { private final String type; /** * @param type resource type * @param inputStream input stream of the resource */ public Resource(String type, InputStream inputStream) { super(inputStream); this.type = type; } /** * Constructs a resource of 'unknown' type. * * @param inputStream input stream of the resource */ public Resource(InputStream inputStream) { this("unknown", inputStream); } /** * @return the resource type */ public String getType() { return this.type; } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/io/ResourceResolver.java0100644 0000000 0000000 00000003501 13777276623 027675 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ResourceResolver.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.io; import java.io.IOException; import java.io.OutputStream; import java.net.URI; /** * Implementations of this resource resolver allow XGC users to control the URI resolution * mechanism. All resource and output stream acquisition goes through this when its implementation * is given to the org.apache.fop.apps.EnvironmentProfile. */ public interface ResourceResolver { /** * Get a resource given the URI pointing to said resource. * * @param uri the resource URI * @return the resource * @throws IOException if an I/O error occured during resource acquisition */ Resource getResource(URI uri) throws IOException; /** * Gets an output stream of a given URI. * * @param uri the output stream URI * @return the output stream * @throws IOException if an I/O error occured while creating an output stream */ OutputStream getOutputStream(URI uri) throws IOException; } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/io/TempResourceResolver.java0100644 0000000 0000000 00000003435 13777276623 030531 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: TempResourceResolver.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.io; import java.io.IOException; import java.io.OutputStream; /** * Implementations of this interface resolve URIs for temporary files used by XGC. The temporary- * resource URI scheme comes from {@link TempResourceURIGenerator#TMP_SCHEME}. */ public interface TempResourceResolver { /** * Get a temporary-resource given the identifier pointing to said resource. * * @param id the resource identifier * @return the resource * @throws IOException if an I/O error occured during resource acquisition */ Resource getResource(String id) throws IOException; /** * Gets an temporary-output stream of a given identifier. * * @param id the output stream identifier * @return the output stream * @throws IOException if an I/O error occured while creating an output stream */ OutputStream getOutputStream(String id) throws IOException; } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/io/TempResourceURIGenerator.java0100644 0000000 0000000 00000003424 13777276623 031234 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.xmlgraphics.io; import java.net.URI; import java.util.concurrent.atomic.AtomicLong; /** * Creates a URI for any temporary resource used within XGC. */ public final class TempResourceURIGenerator { public static final String TMP_SCHEME = "tmp"; private final String tempURIPrefix; private final AtomicLong counter; /** * @param uriPrefix a prefix used to name the unique URI */ public TempResourceURIGenerator(String uriPrefix) { counter = new AtomicLong(); tempURIPrefix = URI.create(TMP_SCHEME + ":///" + uriPrefix).toASCIIString(); } /** * Generate a unique URI for a temporary resource * @return the URI */ public URI generate() { return URI.create(tempURIPrefix + getUniqueId()); } private String getUniqueId() { return Long.toHexString(counter.getAndIncrement()); } public static boolean isTempURI(URI uri) { return TMP_SCHEME.equals(uri.getScheme()); } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/io/URIResolverAdapter.java0100644 0000000 0000000 00000004667 13777276623 030064 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.xmlgraphics.io; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.URI; import java.net.URL; import javax.xml.transform.Source; import javax.xml.transform.TransformerException; import javax.xml.transform.URIResolver; /** * An adapter between {@link URIResolver} to {@link ResourceResolver}. This adapter allows users * to utilize the resolvers from the XML library for resource acquisition. */ public class URIResolverAdapter implements ResourceResolver { private final URIResolver resolver; /** * @param resolver the desired {@link URIResolver} */ public URIResolverAdapter(URIResolver resolver) { this.resolver = resolver; } /** {@inheritDoc} */ public Resource getResource(URI uri) throws IOException { try { Source src = resolver.resolve(uri.toASCIIString(), null); InputStream resourceStream = XmlSourceUtil.getInputStream(src); if (resourceStream == null) { URL url = new URL(src.getSystemId()); resourceStream = url.openStream(); } return new Resource(resourceStream); } catch (TransformerException e) { throw new IOException(e.getMessage()); } } /** {@inheritDoc} */ public OutputStream getOutputStream(URI uri) throws IOException { try { Source src = resolver.resolve(uri.toASCIIString(), null); return new URL(src.getSystemId()).openConnection().getOutputStream(); } catch (TransformerException te) { throw new IOException(te.getMessage()); } } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/io/XmlSourceUtil.java0100644 0000000 0000000 00000014161 13777276623 027147 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.xmlgraphics.io; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.Reader; import javax.xml.transform.Source; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.sax.SAXSource; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; import org.xml.sax.InputSource; import org.apache.commons.io.IOUtils; import org.apache.xmlgraphics.image.loader.ImageSource; import org.apache.xmlgraphics.image.loader.util.ImageInputStreamAdapter; import org.apache.xmlgraphics.image.loader.util.ImageUtil; /** * A utility class for handling {@link Source} objects, more specficially the streams that back * the {@link Source}. */ public final class XmlSourceUtil { private XmlSourceUtil() { } /** * Returns the {@link InputStream} that is backing the given {@link Source} object. * * @param src is backed by an {@link InputStream} * @return the input stream */ public static InputStream getInputStream(Source src) { try { if (src instanceof StreamSource) { return ((StreamSource) src).getInputStream(); } else if (src instanceof DOMSource) { ByteArrayOutputStream outStream = new ByteArrayOutputStream(); StreamResult xmlSource = new StreamResult(outStream); TransformerFactory.newInstance().newTransformer().transform(src, xmlSource); return new ByteArrayInputStream(outStream.toByteArray()); } else if (src instanceof SAXSource) { return ((SAXSource) src).getInputSource().getByteStream(); } else if (src instanceof ImageSource) { return new ImageInputStreamAdapter(((ImageSource) src).getImageInputStream()); } } catch (Exception e) { // TODO: How do we want to handle these? They all come from the TransformerFactory } return null; } /** * Returns the InputStream of a Source object. This method throws an IllegalArgumentException * if there's no InputStream instance available from the Source object. * @param src the Source object * @return the InputStream */ public static InputStream needInputStream(Source src) { InputStream in = getInputStream(src); if (in != null) { return in; } else { throw new IllegalArgumentException("Source must be a StreamSource with an InputStream" + " or an ImageSource"); } } /** * Indicates whether the Source object has a Reader instance. * @param src the Source object * @return true if an Reader is available */ public static boolean hasReader(Source src) { if (src instanceof StreamSource) { Reader reader = ((StreamSource) src).getReader(); return (reader != null); } else if (src instanceof SAXSource) { InputSource is = ((SAXSource) src).getInputSource(); if (is != null) { return (is.getCharacterStream() != null); } } return false; } /** * Removes any references to InputStreams or Readers from the given Source to prohibit * accidental/unwanted use by a component further downstream. * @param src the Source object */ public static void removeStreams(Source src) { if (src instanceof ImageSource) { ImageSource isrc = (ImageSource) src; isrc.setImageInputStream(null); } else if (src instanceof StreamSource) { StreamSource ssrc = (StreamSource) src; ssrc.setInputStream(null); ssrc.setReader(null); } else if (src instanceof SAXSource) { InputSource is = ((SAXSource) src).getInputSource(); if (is != null) { is.setByteStream(null); is.setCharacterStream(null); } } } /** * Closes the InputStreams or ImageInputStreams of Source objects. Any exception occurring * while closing the stream is ignored. * @param src the Source object */ public static void closeQuietly(Source src) { if (src instanceof StreamSource) { StreamSource streamSource = (StreamSource) src; IOUtils.closeQuietly(streamSource.getReader()); } else if (src instanceof ImageSource) { if (ImageUtil.getImageInputStream(src) != null) { try { ImageUtil.getImageInputStream(src).close(); } catch (IOException ioe) { // ignore } } } else if (src instanceof SAXSource) { InputSource is = ((SAXSource) src).getInputSource(); if (is != null) { IOUtils.closeQuietly(is.getByteStream()); IOUtils.closeQuietly(is.getCharacterStream()); } } removeStreams(src); } /** * Indicates whether the Source object has an InputStream instance. * @param src the Source object * @return true if an InputStream is available */ public static boolean hasInputStream(Source src) { return getInputStream(src) != null; } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/java2d/AbstractGraphics2D.java0100644 0000000 0000000 00000171077 13777276623 030554 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: AbstractGraphics2D.java 1739071 2016-04-14 12:30:21Z ssteiner $ */ package org.apache.xmlgraphics.java2d; import java.awt.AlphaComposite; import java.awt.Color; import java.awt.Composite; import java.awt.Font; import java.awt.Graphics2D; import java.awt.Image; import java.awt.Paint; import java.awt.Polygon; import java.awt.Rectangle; import java.awt.RenderingHints; import java.awt.Shape; import java.awt.Stroke; import java.awt.font.FontRenderContext; import java.awt.font.GlyphVector; import java.awt.font.TextLayout; import java.awt.geom.AffineTransform; import java.awt.geom.Arc2D; import java.awt.geom.Ellipse2D; import java.awt.geom.GeneralPath; import java.awt.geom.Line2D; import java.awt.geom.NoninvertibleTransformException; import java.awt.geom.RoundRectangle2D; import java.awt.image.BufferedImage; import java.awt.image.BufferedImageOp; import java.awt.image.ImageObserver; import java.text.AttributedCharacterIterator; import java.util.Map; // CSOFF: NeedBraces // CSOFF: ParameterName // CSOFF: WhitespaceAround /** * This extension of the java.awt.Graphics2D abstract class * is still abstract, but it implements a lot of the Graphics2D * method in a way that concrete implementations can reuse. * * This class uses a GraphicContext to store the state of * its various attributes that control the rendering, such as the * current Font, Paint or clip. * * Concrete implementations can focus on implementing the rendering * methods, such as drawShape. As a convenience, rendering * methods that can be expressed with other rendering methods (e.g., * drawRect can be expressed as draw(new Rectangle(..))), * are implemented by AbstractGraphics2D * * @version $Id: AbstractGraphics2D.java 1739071 2016-04-14 12:30:21Z ssteiner $ * @see org.apache.xmlgraphics.java2d.GraphicContext * * Originally authored by Vincent Hardy. */ public abstract class AbstractGraphics2D extends Graphics2D implements Cloneable { /** * Current state of the Graphic Context. The GraphicsContext * class manages the state of this Graphics2D graphic context * attributes. */ protected GraphicContext gc; /** * Text handling strategy. */ protected boolean textAsShapes; /** * Protection agains infinite recursion */ protected boolean inPossibleRecursion; /** * @param textAsShapes if true, all text is turned into shapes in the * convertion. No text is output. * */ public AbstractGraphics2D(boolean textAsShapes) { this.textAsShapes = textAsShapes; } /** * Creates a new AbstractGraphics2D from an existing instance. * @param g the AbstractGraphics2D whose properties should be copied */ public AbstractGraphics2D(AbstractGraphics2D g) { this.gc = (GraphicContext)g.gc.clone(); this.gc.validateTransformStack(); this.textAsShapes = g.textAsShapes; } /** * Translates the origin of the graphics context to the point * (xy) in the current coordinate system. * Modifies this graphics context so that its new origin corresponds * to the point (xy) in this graphics context's * original coordinate system. All coordinates used in subsequent * rendering operations on this graphics context will be relative * to this new origin. * @param x the x coordinate. * @param y the y coordinate. */ public void translate(int x, int y) { gc.translate(x, y); } /** * Gets this graphics context's current color. * @return this graphics context's current color. * @see java.awt.Color * @see java.awt.Graphics#setColor */ public Color getColor() { return gc.getColor(); } /** * Sets this graphics context's current color to the specified * color. All subsequent graphics operations using this graphics * context use this specified color. * @param c the new rendering color. * @see java.awt.Color * @see java.awt.Graphics#getColor */ public void setColor(Color c) { gc.setColor(c); } /** * Sets the paint mode of this graphics context to overwrite the * destination with this graphics context's current color. * This sets the logical pixel operation function to the paint or * overwrite mode. All subsequent rendering operations will * overwrite the destination with the current color. */ public void setPaintMode() { gc.setComposite(AlphaComposite.SrcOver); } /** * Gets the current font. * @return this graphics context's current font. * @see java.awt.Font * @see java.awt.Graphics#setFont */ public Font getFont() { return gc.getFont(); } /** * Sets this graphics context's font to the specified font. * All subsequent text operations using this graphics context * use this font. * @param font the font. * @see java.awt.Graphics#getFont */ public void setFont(Font font) { gc.setFont(font); } /** * Returns the bounding rectangle of the current clipping area. * This method refers to the user clip, which is independent of the * clipping associated with device bounds and window visibility. * If no clip has previously been set, or if the clip has been * cleared using setClip(null), this method returns * null. * The coordinates in the rectangle are relative to the coordinate * system origin of this graphics context. * @return the bounding rectangle of the current clipping area, * or null if no clip is set. * @see java.awt.Graphics#getClip * @see java.awt.Graphics#clipRect * @see java.awt.Graphics#setClip(int, int, int, int) * @see java.awt.Graphics#setClip(Shape) * @since JDK1.1 */ public Rectangle getClipBounds() { return gc.getClipBounds(); } /** * Intersects the current clip with the specified rectangle. * The resulting clipping area is the intersection of the current * clipping area and the specified rectangle. If there is no * current clipping area, either because the clip has never been * set, or the clip has been cleared using setClip(null), * the specified rectangle becomes the new clip. * This method sets the user clip, which is independent of the * clipping associated with device bounds and window visibility. * This method can only be used to make the current clip smaller. * To set the current clip larger, use any of the setClip methods. * Rendering operations have no effect outside of the clipping area. * @param x the x coordinate of the rectangle to intersect the clip with * @param y the y coordinate of the rectangle to intersect the clip with * @param width the width of the rectangle to intersect the clip with * @param height the height of the rectangle to intersect the clip with * @see #setClip(int, int, int, int) * @see #setClip(Shape) */ public void clipRect(int x, int y, int width, int height) { gc.clipRect(x, y, width, height); } /** * Sets the current clip to the rectangle specified by the given * coordinates. This method sets the user clip, which is * independent of the clipping associated with device bounds * and window visibility. * Rendering operations have no effect outside of the clipping area. * @param x the x coordinate of the new clip rectangle. * @param y the y coordinate of the new clip rectangle. * @param width the width of the new clip rectangle. * @param height the height of the new clip rectangle. * @see java.awt.Graphics#clipRect * @see java.awt.Graphics#setClip(Shape) * @since JDK1.1 */ public void setClip(int x, int y, int width, int height) { gc.setClip(x, y, width, height); } /** * Gets the current clipping area. * This method returns the user clip, which is independent of the * clipping associated with device bounds and window visibility. * If no clip has previously been set, or if the clip has been * cleared using setClip(null), this method returns * null. * @return a Shape object representing the * current clipping area, or null if * no clip is set. * @see java.awt.Graphics#getClipBounds() * @see java.awt.Graphics#clipRect(int, int, int, int) * @see java.awt.Graphics#setClip(int, int, int, int) * @see java.awt.Graphics#setClip(Shape) * @since JDK1.1 */ public Shape getClip() { return gc.getClip(); } /** * Sets the current clipping area to an arbitrary clip shape. * Not all objects that implement the Shape * interface can be used to set the clip. The only * Shape objects that are guaranteed to be * supported are Shape objects that are * obtained via the getClip method and via * Rectangle objects. This method sets the * user clip, which is independent of the clipping associated * with device bounds and window visibility. * @param clip the Shape to use to set the clip * @see java.awt.Graphics#getClip() * @see java.awt.Graphics#clipRect * @see java.awt.Graphics#setClip(int, int, int, int) * @since JDK1.1 */ public void setClip(Shape clip) { gc.setClip(clip); } /** * Draws a line, using the current color, between the points * (x1, y1) and (x2, y2) * in this graphics context's coordinate system. * @param x1 the first point's x coordinate. * @param y1 the first point's y coordinate. * @param x2 the second point's x coordinate. * @param y2 the second point's y coordinate. */ public void drawLine(int x1, int y1, int x2, int y2) { Line2D line = new Line2D.Float(x1, y1, x2, y2); draw(line); } /** * Fills the specified rectangle. * The left and right edges of the rectangle are at * x and x + width - 1. * The top and bottom edges are at * y and y + height - 1. * The resulting rectangle covers an area * width pixels wide by * height pixels tall. * The rectangle is filled using the graphics context's current color. * @param x the x coordinate * of the rectangle to be filled. * @param y the y coordinate * of the rectangle to be filled. * @param width the width of the rectangle to be filled. * @param height the height of the rectangle to be filled. * @see java.awt.Graphics#clearRect * @see java.awt.Graphics#drawRect */ public void fillRect(int x, int y, int width, int height) { Rectangle rect = new Rectangle(x, y, width, height); fill(rect); } public void drawRect(int x, int y, int width, int height) { Rectangle rect = new Rectangle(x, y, width, height); draw(rect); } /** * Clears the specified rectangle by filling it with the background * color of the current drawing surface. This operation does not * use the current paint mode. *

    * Beginning with Java 1.1, the background color * of offscreen images may be system dependent. Applications should * use setColor followed by fillRect to * ensure that an offscreen image is cleared to a specific color. * @param x the x coordinate of the rectangle to clear. * @param y the y coordinate of the rectangle to clear. * @param width the width of the rectangle to clear. * @param height the height of the rectangle to clear. * @see java.awt.Graphics#fillRect(int, int, int, int) * @see java.awt.Graphics#drawRect * @see java.awt.Graphics#setColor(java.awt.Color) * @see java.awt.Graphics#setPaintMode * @see java.awt.Graphics#setXORMode(java.awt.Color) */ public void clearRect(int x, int y, int width, int height) { Paint paint = gc.getPaint(); gc.setColor(gc.getBackground()); fillRect(x, y, width, height); gc.setPaint(paint); } /** * Draws an outlined round-cornered rectangle using this graphics * context's current color. The left and right edges of the rectangle * are at x and x + width, * respectively. The top and bottom edges of the rectangle are at * y and y + height. * @param x the x coordinate of the rectangle to be drawn. * @param y the y coordinate of the rectangle to be drawn. * @param width the width of the rectangle to be drawn. * @param height the height of the rectangle to be drawn. * @param arcWidth the horizontal diameter of the arc * at the four corners. * @param arcHeight the vertical diameter of the arc * at the four corners. * @see java.awt.Graphics#fillRoundRect */ public void drawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) { RoundRectangle2D rect = new RoundRectangle2D.Float(x, y, width, height, arcWidth, arcHeight); draw(rect); } /** * Fills the specified rounded corner rectangle with the current color. * The left and right edges of the rectangle * are at x and x + width - 1, * respectively. The top and bottom edges of the rectangle are at * y and y + height - 1. * @param x the x coordinate of the rectangle to be filled. * @param y the y coordinate of the rectangle to be filled. * @param width the width of the rectangle to be filled. * @param height the height of the rectangle to be filled. * @param arcWidth the horizontal diameter * of the arc at the four corners. * @param arcHeight the vertical diameter * of the arc at the four corners. * @see java.awt.Graphics#drawRoundRect */ public void fillRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) { RoundRectangle2D rect = new RoundRectangle2D.Float(x, y, width, height, arcWidth, arcHeight); fill(rect); } /** * Draws the outline of an oval. * The result is a circle or ellipse that fits within the * rectangle specified by the x, y, * width, and height arguments. *

    * The oval covers an area that is * width + 1 pixels wide * and height + 1 pixels tall. * @param x the x coordinate of the upper left * corner of the oval to be drawn. * @param y the y coordinate of the upper left * corner of the oval to be drawn. * @param width the width of the oval to be drawn. * @param height the height of the oval to be drawn. * @see java.awt.Graphics#fillOval */ public void drawOval(int x, int y, int width, int height) { Ellipse2D oval = new Ellipse2D.Float(x, y, width, height); draw(oval); } /** * Fills an oval bounded by the specified rectangle with the * current color. * @param x the x coordinate of the upper left corner * of the oval to be filled. * @param y the y coordinate of the upper left corner * of the oval to be filled. * @param width the width of the oval to be filled. * @param height the height of the oval to be filled. * @see java.awt.Graphics#drawOval */ public void fillOval(int x, int y, int width, int height) { Ellipse2D oval = new Ellipse2D.Float(x, y, width, height); fill(oval); } /** * Draws the outline of a circular or elliptical arc * covering the specified rectangle. *

    * The resulting arc begins at startAngle and extends * for arcAngle degrees, using the current color. * Angles are interpreted such that 0 degrees * is at the 3 o'clock position. * A positive value indicates a counter-clockwise rotation * while a negative value indicates a clockwise rotation. *

    * The center of the arc is the center of the rectangle whose origin * is (xy) and whose size is specified by the * width and height arguments. *

    * The resulting arc covers an area * width + 1 pixels wide * by height + 1 pixels tall. *

    * The angles are specified relative to the non-square extents of * the bounding rectangle such that 45 degrees always falls on the * line from the center of the ellipse to the upper right corner of * the bounding rectangle. As a result, if the bounding rectangle is * noticeably longer in one axis than the other, the angles to the * start and end of the arc segment will be skewed farther along the * longer axis of the bounds. * @param x the x coordinate of the * upper-left corner of the arc to be drawn. * @param y the y coordinate of the * upper-left corner of the arc to be drawn. * @param width the width of the arc to be drawn. * @param height the height of the arc to be drawn. * @param startAngle the beginning angle. * @param arcAngle the angular extent of the arc, * relative to the start angle. * @see java.awt.Graphics#fillArc */ public void drawArc(int x, int y, int width, int height, int startAngle, int arcAngle) { Arc2D arc = new Arc2D.Float(x, y, width, height, startAngle, arcAngle, Arc2D.OPEN); draw(arc); } /** * Fills a circular or elliptical arc covering the specified rectangle. *

    * The resulting arc begins at startAngle and extends * for arcAngle degrees. * Angles are interpreted such that 0 degrees * is at the 3 o'clock position. * A positive value indicates a counter-clockwise rotation * while a negative value indicates a clockwise rotation. *

    * The center of the arc is the center of the rectangle whose origin * is (xy) and whose size is specified by the * width and height arguments. *

    * The resulting arc covers an area * width + 1 pixels wide * by height + 1 pixels tall. *

    * The angles are specified relative to the non-square extents of * the bounding rectangle such that 45 degrees always falls on the * line from the center of the ellipse to the upper right corner of * the bounding rectangle. As a result, if the bounding rectangle is * noticeably longer in one axis than the other, the angles to the * start and end of the arc segment will be skewed farther along the * longer axis of the bounds. * @param x the x coordinate of the * upper-left corner of the arc to be filled. * @param y the y coordinate of the * upper-left corner of the arc to be filled. * @param width the width of the arc to be filled. * @param height the height of the arc to be filled. * @param startAngle the beginning angle. * @param arcAngle the angular extent of the arc, * relative to the start angle. * @see java.awt.Graphics#drawArc */ public void fillArc(int x, int y, int width, int height, int startAngle, int arcAngle) { Arc2D arc = new Arc2D.Float(x, y, width, height, startAngle, arcAngle, Arc2D.PIE); fill(arc); } /** * Draws a sequence of connected lines defined by * arrays of x and y coordinates. * Each pair of (xy) coordinates defines a point. * The figure is not closed if the first point * differs from the last point. * @param xPoints an array of x points * @param yPoints an array of y points * @param nPoints the total number of points * @see java.awt.Graphics#drawPolygon(int[], int[], int) * @since JDK1.1 */ public void drawPolyline(int[] xPoints, int[] yPoints, int nPoints) { if (nPoints > 0) { GeneralPath path = new GeneralPath(); path.moveTo(xPoints[0], yPoints[0]); for (int i = 1; i < nPoints; i++) { path.lineTo(xPoints[i], yPoints[i]); } draw(path); } } /** * Draws a closed polygon defined by * arrays of x and y coordinates. * Each pair of (xy) coordinates defines a point. *

    * This method draws the polygon defined by nPoint line * segments, where the first nPoint - 1 * line segments are line segments from * (xPoints[i - 1], yPoints[i - 1]) * to (xPoints[i], yPoints[i]), for * 1 ≤ i ≤ nPoints. * The figure is automatically closed by drawing a line connecting * the final point to the first point, if those points are different. * @param xPoints a an array of x coordinates. * @param yPoints a an array of y coordinates. * @param nPoints a the total number of points. * @see java.awt.Graphics#fillPolygon(int[],int[],int) * @see java.awt.Graphics#drawPolyline */ public void drawPolygon(int[] xPoints, int[] yPoints, int nPoints) { Polygon polygon = new Polygon(xPoints, yPoints, nPoints); draw(polygon); } /** * Fills a closed polygon defined by * arrays of x and y coordinates. *

    * This method draws the polygon defined by nPoint line * segments, where the first nPoint - 1 * line segments are line segments from * (xPoints[i - 1], yPoints[i - 1]) * to (xPoints[i], yPoints[i]), for * 1 ≤ i ≤ nPoints. * The figure is automatically closed by drawing a line connecting * the final point to the first point, if those points are different. *

    * The area inside the polygon is defined using an * even-odd fill rule, also known as the alternating rule. * @param xPoints a an array of x coordinates. * @param yPoints a an array of y coordinates. * @param nPoints a the total number of points. * @see java.awt.Graphics#drawPolygon(int[], int[], int) */ public void fillPolygon(int[] xPoints, int[] yPoints, int nPoints) { Polygon polygon = new Polygon(xPoints, yPoints, nPoints); fill(polygon); } /** * Draws the text given by the specified string, using this * graphics context's current font and color. The baseline of the * first character is at position (xy) in this * graphics context's coordinate system. * @param str the string to be drawn. * @param x the x coordinate. * @param y the y coordinate. * @see java.awt.Graphics#drawBytes * @see java.awt.Graphics#drawChars */ public void drawString(String str, int x, int y) { drawString(str, (float)x, (float)y); } /** * Generic implementation for drawing attributed strings using TextLayout. * * @param iterator the iterator whose text is to be rendered * @param x the x coordinate where the iterator's text is to be rendered * @param y the y coordinate where the iterator's text is to be rendered * @see java.awt.Graphics2D#drawString (java.text.AttributedCharacterIterator, * float, float) */ public void drawString(AttributedCharacterIterator iterator, float x, float y) { if (inPossibleRecursion) { System.err.println("Called itself: drawString(AttributedCharacterIterator)"); } else { inPossibleRecursion = true; TextLayout layout = new TextLayout(iterator, getFontRenderContext()); layout.draw(this, x, y); inPossibleRecursion = false; } } /** * Draws the text given by the specified iterator, using this * graphics context's current color. The iterator has to specify a font * for each character. The baseline of the * first character is at position (xy) in this * graphics context's coordinate system. * @param iterator the iterator whose text is to be drawn * @param x the x coordinate. * @param y the y coordinate. * @see java.awt.Graphics#drawBytes * @see java.awt.Graphics#drawChars */ public void drawString(AttributedCharacterIterator iterator, int x, int y) { drawString(iterator, (float)x, (float)y); } /** * Draws as much of the specified image as is currently available. * The image is drawn with its top-left corner at * (xy) in this graphics context's coordinate * space. Transparent pixels are drawn in the specified * background color. *

    * This operation is equivalent to filling a rectangle of the * width and height of the specified image with the given color and then * drawing the image on top of it, but possibly more efficient. *

    * This method returns immediately in all cases, even if the * complete image has not yet been loaded, and it has not been dithered * and converted for the current output device. *

    * If the image has not yet been completely loaded, then * drawImage returns false. As more of * the image becomes available, the process that draws the image notifies * the specified image observer. * @param img the specified image to be drawn. * @param x the x coordinate. * @param y the y coordinate. * @param bgcolor the background color to paint under the * non-opaque portions of the image. * @param observer object to be notified as more of * the image is converted. * @see java.awt.Image * @see java.awt.image.ImageObserver * @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int) */ public boolean drawImage(Image img, int x, int y, Color bgcolor, ImageObserver observer) { return drawImage(img, x, y, img.getWidth(null), img.getHeight(null), bgcolor, observer); } /** * Draws as much of the specified image as has already been scaled * to fit inside the specified rectangle. *

    * The image is drawn inside the specified rectangle of this * graphics context's coordinate space, and is scaled if * necessary. Transparent pixels are drawn in the specified * background color. * This operation is equivalent to filling a rectangle of the * width and height of the specified image with the given color and then * drawing the image on top of it, but possibly more efficient. *

    * This method returns immediately in all cases, even if the * entire image has not yet been scaled, dithered, and converted * for the current output device. * If the current output representation is not yet complete then * drawImage returns false. As more of * the image becomes available, the process that draws the image notifies * the specified image observer. *

    * A scaled version of an image will not necessarily be * available immediately just because an unscaled version of the * image has been constructed for this output device. Each size of * the image may be cached separately and generated from the original * data in a separate image production sequence. * @param img the specified image to be drawn. * @param x the x coordinate. * @param y the y coordinate. * @param width the width of the rectangle. * @param height the height of the rectangle. * @param bgcolor the background color to paint under the * non-opaque portions of the image. * @param observer object to be notified as more of * the image is converted. * @see java.awt.Image * @see java.awt.image.ImageObserver * @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int) */ public boolean drawImage(Image img, int x, int y, int width, int height, Color bgcolor, ImageObserver observer) { Paint paint = gc.getPaint(); gc.setPaint(bgcolor); fillRect(x, y, width, height); gc.setPaint(paint); drawImage(img, x, y, width, height, observer); return true; } /** * Draws as much of the specified area of the specified image as is * currently available, scaling it on the fly to fit inside the * specified area of the destination drawable surface. Transparent pixels * do not affect whatever pixels are already there. *

    * This method returns immediately in all cases, even if the * image area to be drawn has not yet been scaled, dithered, and converted * for the current output device. * If the current output representation is not yet complete then * drawImage returns false. As more of * the image becomes available, the process that draws the image notifies * the specified image observer. *

    * This method always uses the unscaled version of the image * to render the scaled rectangle and performs the required * scaling on the fly. It does not use a cached, scaled version * of the image for this operation. Scaling of the image from source * to destination is performed such that the first coordinate * of the source rectangle is mapped to the first coordinate of * the destination rectangle, and the second source coordinate is * mapped to the second destination coordinate. The subimage is * scaled and flipped as needed to preserve those mappings. * @param img the specified image to be drawn * @param dx1 the x coordinate of the first corner of the * destination rectangle. * @param dy1 the y coordinate of the first corner of the * destination rectangle. * @param dx2 the x coordinate of the second corner of the * destination rectangle. * @param dy2 the y coordinate of the second corner of the * destination rectangle. * @param sx1 the x coordinate of the first corner of the * source rectangle. * @param sy1 the y coordinate of the first corner of the * source rectangle. * @param sx2 the x coordinate of the second corner of the * source rectangle. * @param sy2 the y coordinate of the second corner of the * source rectangle. * @param observer object to be notified as more of the image is * scaled and converted. * @see java.awt.Image * @see java.awt.image.ImageObserver * @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int) * @since JDK1.1 */ public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, ImageObserver observer) { BufferedImage src = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_ARGB); Graphics2D g = src.createGraphics(); g.drawImage(img, 0, 0, null); g.dispose(); src = src.getSubimage(sx1, sy1, sx2 - sx1, sy2 - sy1); return drawImage(src, dx1, dy1, dx2 - dx1, dy2 - dy1, observer); } /** * Draws as much of the specified area of the specified image as is * currently available, scaling it on the fly to fit inside the * specified area of the destination drawable surface. *

    * Transparent pixels are drawn in the specified background color. * This operation is equivalent to filling a rectangle of the * width and height of the specified image with the given color and then * drawing the image on top of it, but possibly more efficient. *

    * This method returns immediately in all cases, even if the * image area to be drawn has not yet been scaled, dithered, and converted * for the current output device. * If the current output representation is not yet complete then * drawImage returns false. As more of * the image becomes available, the process that draws the image notifies * the specified image observer. *

    * This method always uses the unscaled version of the image * to render the scaled rectangle and performs the required * scaling on the fly. It does not use a cached, scaled version * of the image for this operation. Scaling of the image from source * to destination is performed such that the first coordinate * of the source rectangle is mapped to the first coordinate of * the destination rectangle, and the second source coordinate is * mapped to the second destination coordinate. The subimage is * scaled and flipped as needed to preserve those mappings. * @param img the specified image to be drawn * @param dx1 the x coordinate of the first corner of the * destination rectangle. * @param dy1 the y coordinate of the first corner of the * destination rectangle. * @param dx2 the x coordinate of the second corner of the * destination rectangle. * @param dy2 the y coordinate of the second corner of the * destination rectangle. * @param sx1 the x coordinate of the first corner of the * source rectangle. * @param sy1 the y coordinate of the first corner of the * source rectangle. * @param sx2 the x coordinate of the second corner of the * source rectangle. * @param sy2 the y coordinate of the second corner of the * source rectangle. * @param bgcolor the background color to paint under the * non-opaque portions of the image. * @param observer object to be notified as more of the image is * scaled and converted. * @see java.awt.Image * @see java.awt.image.ImageObserver * @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int) * @since JDK1.1 */ public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, Color bgcolor, ImageObserver observer) { Paint paint = gc.getPaint(); gc.setPaint(bgcolor); fillRect(dx1, dy1, dx2 - dx1, dy2 - dy1); gc.setPaint(paint); return drawImage(img, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, observer); } /** * Renders an image, applying a transform from image space into user space * before drawing. * The transformation from user space into device space is done with * the current Transform in the Graphics2D. * The specified transformation is applied to the image before the * transform attribute in the Graphics2D context is applied. * The rendering attributes applied include the Clip, * Transform, and Composite attributes. * Note that no rendering is done if the specified transform is * noninvertible. * @param img the Image to be rendered * @param xform the transformation from image space into user space * @param obs the {@link ImageObserver} * to be notified as more of the Image * is converted * @return true if the Image is * fully loaded and completely rendered; * false if the Image is still being loaded. * @see #transform * @see #setTransform * @see #setComposite * @see #clip * @see #setClip(Shape) */ public boolean drawImage(Image img, AffineTransform xform, ImageObserver obs) { boolean retVal = true; if (xform == null) { xform = new AffineTransform(); } if (xform.getDeterminant() != 0) { AffineTransform inverseTransform = null; try { inverseTransform = xform.createInverse(); } catch (NoninvertibleTransformException e) { // Should never happen since we checked the // matrix determinant throw new RuntimeException(e); } gc.transform(xform); retVal = drawImage(img, 0, 0, null); gc.transform(inverseTransform); } else { AffineTransform savTransform = new AffineTransform(gc.getTransform()); gc.transform(xform); retVal = drawImage(img, 0, 0, null); gc.setTransform(savTransform); } return retVal; } /** * Renders a BufferedImage that is * filtered with a * {@link BufferedImageOp}. * The rendering attributes applied include the Clip, * Transform * and Composite attributes. This is equivalent to: *

         * img1 = op.filter(img, null);
         * drawImage(img1, new AffineTransform(1f,0f,0f,1f,x,y), null);
         * 
    * @param img the BufferedImage to be rendered * @param op the filter to be applied to the image before rendering * @param x the x coordinate in user space where the image is rendered * @param y the y coordinate in user space where the image is rendered * @see #transform * @see #setTransform * @see #setComposite * @see #clip * @see #setClip(Shape) */ public void drawImage(BufferedImage img, BufferedImageOp op, int x, int y) { img = op.filter(img, null); drawImage(img, x, y, null); } /** * Renders the text of the specified * {@link GlyphVector} using * the Graphics2D context's rendering attributes. * The rendering attributes applied include the Clip, * Transform, Paint, and * Composite attributes. The GlyphVector * specifies individual glyphs from a {@link Font}. * The GlyphVector can also contain the glyph positions. * This is the fastest way to render a set of characters to the * screen. * * @param g the GlyphVector to be rendered * @param x the x position in user space where the glyphs should be * rendered * @param y the y position in user space where the glyphs should be * rendered * * @see java.awt.Font#createGlyphVector(FontRenderContext, char[]) * @see java.awt.font.GlyphVector * @see #setPaint * @see java.awt.Graphics#setColor * @see #setTransform * @see #setComposite * @see #setClip(Shape) */ public void drawGlyphVector(GlyphVector g, float x, float y) { Shape glyphOutline = g.getOutline(x, y); fill(glyphOutline); } /** * Checks whether or not the specified Shape intersects * the specified {@link Rectangle}, which is in device * space. If onStroke is false, this method checks * whether or not the interior of the specified Shape * intersects the specified Rectangle. If * onStroke is true, this method checks * whether or not the Stroke of the specified * Shape outline intersects the specified * Rectangle. * The rendering attributes taken into account include the * Clip, Transform, and Stroke * attributes. * @param rect the area in device space to check for a hit * @param s the Shape to check for a hit * @param onStroke flag used to choose between testing the * stroked or the filled shape. If the flag is true, the * Stroke oultine is tested. If the flag is * false, the filled Shape is tested. * @return true if there is a hit; false * otherwise. * @see #setStroke * @see #fill(Shape) * @see #draw(Shape) * @see #transform * @see #setTransform * @see #clip * @see #setClip(Shape) */ public boolean hit(Rectangle rect, Shape s, boolean onStroke) { if (onStroke) { s = gc.getStroke().createStrokedShape(s); } s = gc.getTransform().createTransformedShape(s); return s.intersects(rect); } /** * Sets the Composite for the Graphics2D context. * The Composite is used in all drawing methods such as * drawImage, drawString, draw, * and fill. It specifies how new pixels are to be combined * with the existing pixels on the graphics device during the rendering * process. *

    If this Graphics2D context is drawing to a * Component on the display screen and the * Composite is a custom object rather than an * instance of the AlphaComposite class, and if * there is a security manager, its checkPermission * method is called with an AWTPermission("readDisplayPixels") * permission. * @param comp the Composite object to be used for rendering * @throws SecurityException * if a custom Composite object is being * used to render to the screen and a security manager * is set and its checkPermission method * does not allow the operation. * @see java.awt.Graphics#setXORMode * @see java.awt.Graphics#setPaintMode * @see java.awt.AlphaComposite */ public void setComposite(Composite comp) { gc.setComposite(comp); } /** * Sets the Paint attribute for the * Graphics2D context. Calling this method * with a null Paint object does * not have any effect on the current Paint attribute * of this Graphics2D. * @param paint the Paint object to be used to generate * color during the rendering process, or null * @see java.awt.Graphics#setColor */ public void setPaint(Paint paint) { gc.setPaint(paint); } /** * Sets the Stroke for the Graphics2D context. * @param s the Stroke object to be used to stroke a * Shape during the rendering process */ public void setStroke(Stroke s) { gc.setStroke(s); } /** * Sets the value of a single preference for the rendering algorithms. * Hint categories include controls for rendering quality and overall * time/quality trade-off in the rendering process. Refer to the * RenderingHints class for definitions of some common * keys and values. * @param hintKey the key of the hint to be set. * @param hintValue the value indicating preferences for the specified * hint category. * @see RenderingHints */ public void setRenderingHint(RenderingHints.Key hintKey, Object hintValue) { gc.setRenderingHint(hintKey, hintValue); } /** * Returns the value of a single preference for the rendering algorithms. * Hint categories include controls for rendering quality and overall * time/quality trade-off in the rendering process. Refer to the * RenderingHints class for definitions of some common * keys and values. * @param hintKey the key corresponding to the hint to get. * @return an object representing the value for the specified hint key. * Some of the keys and their associated values are defined in the * RenderingHints class. * @see RenderingHints */ public Object getRenderingHint(RenderingHints.Key hintKey) { return gc.getRenderingHint(hintKey); } /** * Replaces the values of all preferences for the rendering * algorithms with the specified hints. * The existing values for all rendering hints are discarded and * the new set of known hints and values are initialized from the * specified {@link Map} object. * Hint categories include controls for rendering quality and * overall time/quality trade-off in the rendering process. * Refer to the RenderingHints class for definitions of * some common keys and values. * @param hints the rendering hints to be set * @see RenderingHints */ public void setRenderingHints(Map hints) { gc.setRenderingHints(hints); } /** * Sets the values of an arbitrary number of preferences for the * rendering algorithms. * Only values for the rendering hints that are present in the * specified Map object are modified. * All other preferences not present in the specified * object are left unmodified. * Hint categories include controls for rendering quality and * overall time/quality trade-off in the rendering process. * Refer to the RenderingHints class for definitions of * some common keys and values. * @param hints the rendering hints to be set * @see RenderingHints */ public void addRenderingHints(Map hints) { gc.addRenderingHints(hints); } /** * Gets the preferences for the rendering algorithms. Hint categories * include controls for rendering quality and overall time/quality * trade-off in the rendering process. * Returns all of the hint key/value pairs that were ever specified in * one operation. Refer to the * RenderingHints class for definitions of some common * keys and values. * @return a reference to an instance of RenderingHints * that contains the current preferences. * @see RenderingHints */ public RenderingHints getRenderingHints() { return gc.getRenderingHints(); } /** * Concatenates the current * Graphics2D Transform * with a translation transform. * Subsequent rendering is translated by the specified * distance relative to the previous position. * This is equivalent to calling transform(T), where T is an * AffineTransform represented by the following matrix: *

         *          [   1    0    tx  ]
         *          [   0    1    ty  ]
         *          [   0    0    1   ]
         * 
    * @param tx the distance to translate along the x-axis * @param ty the distance to translate along the y-axis */ public void translate(double tx, double ty) { gc.translate(tx, ty); } /** * Concatenates the current Graphics2D * Transform with a rotation transform. * Subsequent rendering is rotated by the specified radians relative * to the previous origin. * This is equivalent to calling transform(R), where R is an * AffineTransform represented by the following matrix: *
         *          [   cos(theta)    -sin(theta)    0   ]
         *          [   sin(theta)     cos(theta)    0   ]
         *          [       0              0         1   ]
         * 
    * Rotating with a positive angle theta rotates points on the positive * x axis toward the positive y axis. * @param theta the angle of rotation in radians */ public void rotate(double theta) { gc.rotate(theta); } /** * Concatenates the current Graphics2D * Transform with a translated rotation * transform. Subsequent rendering is transformed by a transform * which is constructed by translating to the specified location, * rotating by the specified radians, and translating back by the same * amount as the original translation. This is equivalent to the * following sequence of calls: *
         *          translate(x, y);
         *          rotate(theta);
         *          translate(-x, -y);
         * 
    * Rotating with a positive angle theta rotates points on the positive * x axis toward the positive y axis. * @param theta the angle of rotation in radians * @param x the x coordinate of the origin of the rotation * @param y the y coordinate of the origin of the rotation */ public void rotate(double theta, double x, double y) { gc.rotate(theta, x, y); } /** * Concatenates the current Graphics2D * Transform with a scaling transformation * Subsequent rendering is resized according to the specified scaling * factors relative to the previous scaling. * This is equivalent to calling transform(S), where S is an * AffineTransform represented by the following matrix: *
         *          [   sx   0    0   ]
         *          [   0    sy   0   ]
         *          [   0    0    1   ]
         * 
    * @param sx the amount by which X coordinates in subsequent * rendering operations are multiplied relative to previous * rendering operations. * @param sy the amount by which Y coordinates in subsequent * rendering operations are multiplied relative to previous * rendering operations. */ public void scale(double sx, double sy) { gc.scale(sx, sy); } /** * Concatenates the current Graphics2D * Transform with a shearing transform. * Subsequent renderings are sheared by the specified * multiplier relative to the previous position. * This is equivalent to calling transform(SH), where SH * is an AffineTransform represented by the following * matrix: *
         *          [   1   shx   0   ]
         *          [  shy   1    0   ]
         *          [   0    0    1   ]
         * 
    * @param shx the multiplier by which coordinates are shifted in * the positive X axis direction as a function of their Y coordinate * @param shy the multiplier by which coordinates are shifted in * the positive Y axis direction as a function of their X coordinate */ public void shear(double shx, double shy) { gc.shear(shx, shy); } /** * Composes an AffineTransform object with the * Transform in this Graphics2D according * to the rule last-specified-first-applied. If the current * Transform is Cx, the result of composition * with Tx is a new Transform Cx'. Cx' becomes the * current Transform for this Graphics2D. * Transforming a point p by the updated Transform Cx' is * equivalent to first transforming p by Tx and then transforming * the result by the original Transform Cx. In other * words, Cx'(p) = Cx(Tx(p)). A copy of the Tx is made, if necessary, * so further modifications to Tx do not affect rendering. * @param tx the AffineTransform object to be composed with * the current Transform * @see #setTransform * @see AffineTransform */ public void transform(AffineTransform tx) { gc.transform(tx); } /** * Sets the Transform in the Graphics2D * context. * @param tx the AffineTransform object to be used in the * rendering process * @see #transform * @see AffineTransform */ public void setTransform(AffineTransform tx) { gc.setTransform(tx); } /** * Returns a copy of the current Transform in the * Graphics2D context. * @return the current AffineTransform in the * Graphics2D context. * @see #transform * @see #setTransform */ public AffineTransform getTransform() { return gc.getTransform(); } /** * Returns the current Paint of the * Graphics2D context. * @return the current Graphics2D Paint, * which defines a color or pattern. * @see #setPaint * @see java.awt.Graphics#setColor */ public Paint getPaint() { return gc.getPaint(); } /** * Returns the current Composite in the * Graphics2D context. * @return the current Graphics2D Composite, * which defines a compositing style. * @see #setComposite */ public Composite getComposite() { return gc.getComposite(); } /** * Sets the background color for the Graphics2D context. * The background color is used for clearing a region. * When a Graphics2D is constructed for a * Component, the background color is * inherited from the Component. Setting the background color * in the Graphics2D context only affects the subsequent * clearRect calls and not the background color of the * Component. To change the background * of the Component, use appropriate methods of * the Component. * @param color the background color that isused in * subsequent calls to clearRect * @see #getBackground * @see java.awt.Graphics#clearRect */ public void setBackground(Color color) { gc.setBackground(color); } /** * Returns the background color used for clearing a region. * @return the current Graphics2D Color, * which defines the background color. * @see #setBackground */ public Color getBackground() { return gc.getBackground(); } /** * Returns the current Stroke in the * Graphics2D context. * @return the current Graphics2D Stroke, * which defines the line style. * @see #setStroke */ public Stroke getStroke() { return gc.getStroke(); } /** * Intersects the current Clip with the interior of the * specified Shape and sets the Clip to the * resulting intersection. The specified Shape is * transformed with the current Graphics2D * Transform before being intersected with the current * Clip. This method is used to make the current * Clip smaller. * To make the Clip larger, use setClip. * The user clip modified by this method is independent of the * clipping associated with device bounds and visibility. If no clip has * previously been set, or if the clip has been cleared using * {@link java.awt.Graphics#setClip(Shape) setClip} with a * null argument, the specified Shape becomes * the new user clip. * @param s the Shape to be intersected with the current * Clip. If s is null, * this method clears the current Clip. */ public void clip(Shape s) { gc.clip(s); } /** * Get the rendering context of the Font within this * Graphics2D context. * The {@link FontRenderContext} * encapsulates application hints such as anti-aliasing and * fractional metrics, as well as target device specific information * such as dots-per-inch. This information should be provided by the * application when using objects that perform typographical * formatting, such as Font and * TextLayout. This information should also be provided * by applications that perform their own layout and need accurate * measurements of various characteristics of glyphs such as advance * and line height when various rendering hints have been applied to * the text rendering. * * @return a reference to an instance of FontRenderContext. * @see java.awt.font.FontRenderContext * @see java.awt.Font#createGlyphVector(FontRenderContext,char[]) * @see java.awt.font.TextLayout * @since JDK1.2 */ public FontRenderContext getFontRenderContext() { return gc.getFontRenderContext(); } /** * @return the {@link GraphicContext} of this Graphics2D. */ public GraphicContext getGraphicContext() { return gc; } } ././@LongLink0100644 0000000 0000000 00000000147 13777276623 011661 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/java2d/AbstractGraphicsConfiguration.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/java2d/AbstractGraphicsConfiguration.ja0100644 0000000 0000000 00000003457 13777276623 032563 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: AbstractGraphicsConfiguration.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.java2d; import java.awt.image.VolatileImage; /** * Adapter to allow subclassing java.awt.GraphicsConfiguration without * compilation errors. * The version for JDK 1.4 needs to add an override for the abstract * createCompatibleVolatileImage() method. It can't be overidden * for JDK 1.3 because there is no VolatileImage there. * */ public abstract class AbstractGraphicsConfiguration extends java.awt.GraphicsConfiguration { /** * @see java.awt.GraphicsConfiguration#createCompatibleVolatileImage(int, int) * @since JDK 1.4 */ public VolatileImage createCompatibleVolatileImage(int width, int height) { return null; } /** * @see java.awt.GraphicsConfiguration#createCompatibleVolatileImage(int, int, int) * @since JDK 1.5 */ public VolatileImage createCompatibleVolatileImage(int width, int height, int transparency) { return null; } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/java2d/CMYKColorSpace.java0100644 0000000 0000000 00000004613 13777276623 027647 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: CMYKColorSpace.java 954487 2010-06-14 14:40:26Z jeremias $ */ package org.apache.xmlgraphics.java2d; import java.awt.color.ColorSpace; /** * This class represents an uncalibrated CMYK color space. * @deprecated This class has been moved to the "color" subpackage. */ public class CMYKColorSpace extends ColorSpace { private static final long serialVersionUID = 2925508946083542974L; private static CMYKColorSpace instance; /** * @see java.awt.color.ColorSpace#ColorSpace(int, int) */ protected CMYKColorSpace(int type, int numcomponents) { super(type, numcomponents); } /** * Returns an instance of an uncalibrated CMYK color space. * @return CMYKColorSpace the requested color space object */ public static CMYKColorSpace getInstance() { if (instance == null) { instance = new CMYKColorSpace(TYPE_CMYK, 4); } return instance; } /** {@inheritDoc} */ public float[] toRGB(float[] colorvalue) { return new float [] { (1 - colorvalue[0]) * (1 - colorvalue[3]), (1 - colorvalue[1]) * (1 - colorvalue[3]), (1 - colorvalue[2]) * (1 - colorvalue[3])}; } /** {@inheritDoc} */ public float[] fromRGB(float[] rgbvalue) { throw new UnsupportedOperationException("NYI"); } /** {@inheritDoc} */ public float[] toCIEXYZ(float[] colorvalue) { throw new UnsupportedOperationException("NYI"); } /** {@inheritDoc} */ public float[] fromCIEXYZ(float[] colorvalue) { throw new UnsupportedOperationException("NYI"); } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/java2d/DefaultGraphics2D.java0100644 0000000 0000000 00000041216 13777276623 030364 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: DefaultGraphics2D.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.java2d; import java.awt.Color; import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.GraphicsConfiguration; import java.awt.Image; import java.awt.Shape; import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import java.awt.image.ImageObserver; import java.awt.image.RenderedImage; import java.awt.image.renderable.RenderableImage; import java.text.AttributedCharacterIterator; // CSOFF: WhitespaceAround /** * This concrete implementation of AbstractGraphics2D is a * simple help to programmers to get started with their own * implementation of Graphics2D. * DefaultGraphics2D implements all the abstract methods * is AbstractGraphics2D and makes it easy to start * implementing a Graphic2D piece-meal. * * @version $Id: DefaultGraphics2D.java 1732018 2016-02-24 04:51:06Z gadams $ * @see org.apache.xmlgraphics.java2d.AbstractGraphics2D * * Originally authored by Vincent Hardy. */ public class DefaultGraphics2D extends AbstractGraphics2D { /** * Default constructor */ public DefaultGraphics2D(boolean textAsShapes) { super(textAsShapes); } /** * This constructor supports the create method */ public DefaultGraphics2D(DefaultGraphics2D g) { super(g); } /** * Creates a new Graphics object that is * a copy of this Graphics object. * @return a new graphics context that is a copy of * this graphics context. */ public Graphics create() { return new DefaultGraphics2D(this); } /** * Draws as much of the specified image as is currently available. * The image is drawn with its top-left corner at * (xy) in this graphics context's coordinate * space. Transparent pixels in the image do not affect whatever * pixels are already there. *

    * This method returns immediately in all cases, even if the * complete image has not yet been loaded, and it has not been dithered * and converted for the current output device. *

    * If the image has not yet been completely loaded, then * drawImage returns false. As more of * the image becomes available, the process that draws the image notifies * the specified image observer. * @param img the specified image to be drawn. * @param x the x coordinate. * @param y the y coordinate. * @param observer object to be notified as more of * the image is converted. * @see java.awt.Image * @see java.awt.image.ImageObserver * @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int) */ public boolean drawImage(Image img, int x, int y, ImageObserver observer) { System.err.println("drawImage"); return true; } /** * Draws as much of the specified image as has already been scaled * to fit inside the specified rectangle. *

    * The image is drawn inside the specified rectangle of this * graphics context's coordinate space, and is scaled if * necessary. Transparent pixels do not affect whatever pixels * are already there. *

    * This method returns immediately in all cases, even if the * entire image has not yet been scaled, dithered, and converted * for the current output device. * If the current output representation is not yet complete, then * drawImage returns false. As more of * the image becomes available, the process that draws the image notifies * the image observer by calling its imageUpdate method. *

    * A scaled version of an image will not necessarily be * available immediately just because an unscaled version of the * image has been constructed for this output device. Each size of * the image may be cached separately and generated from the original * data in a separate image production sequence. * @param img the specified image to be drawn. * @param x the x coordinate. * @param y the y coordinate. * @param width the width of the rectangle. * @param height the height of the rectangle. * @param observer object to be notified as more of * the image is converted. * @see java.awt.Image * @see java.awt.image.ImageObserver * @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int) */ public boolean drawImage(Image img, int x, int y, int width, int height, ImageObserver observer) { System.out.println("drawImage"); return true; } /** * Disposes of this graphics context and releases * any system resources that it is using. * A Graphics object cannot be used after * disposehas been called. *

    * When a Java program runs, a large number of Graphics * objects can be created within a short time frame. * Although the finalization process of the garbage collector * also disposes of the same system resources, it is preferable * to manually free the associated resources by calling this * method rather than to rely on a finalization process which * may not run to completion for a long period of time. *

    * Graphics objects which are provided as arguments to the * paint and update methods * of components are automatically released by the system when * those methods return. For efficiency, programmers should * call dispose when finished using * a Graphics object only if it was created * directly from a component or another Graphics object. * @see java.awt.Graphics#finalize * @see java.awt.Component#paint * @see java.awt.Component#update * @see java.awt.Component#getGraphics * @see java.awt.Graphics#create() */ public void dispose() { System.out.println("dispose"); } /** * Strokes the outline of a Shape using the settings of the * current Graphics2D context. The rendering attributes * applied include the Clip, Transform, * Paint, Composite and * Stroke attributes. * @param s the Shape to be rendered * @see #setStroke(java.awt.Stroke) * @see #setPaint(java.awt.Paint) * @see java.awt.Graphics#setColor * @see #setTransform(AffineTransform) * @see #setClip(Shape) * @see #setComposite(java.awt.Composite) */ public void draw(Shape s) { System.out.println("draw(Shape)"); } /** * Renders a {@link RenderedImage}, * applying a transform from image * space into user space before drawing. * The transformation from user space into device space is done with * the current Transform in the Graphics2D. * The specified transformation is applied to the image before the * transform attribute in the Graphics2D context is applied. * The rendering attributes applied include the Clip, * Transform, and Composite attributes. Note * that no rendering is done if the specified transform is * noninvertible. * @param img the image to be rendered * @param xform the transformation from image space into user space * @see #setTransform(AffineTransform) * @see #setComposite(java.awt.Composite) * @see #setClip(Shape) */ public void drawRenderedImage(RenderedImage img, AffineTransform xform) { System.out.println("drawRenderedImage"); } /** * Renders a * {@link RenderableImage}, * applying a transform from image space into user space before drawing. * The transformation from user space into device space is done with * the current Transform in the Graphics2D. * The specified transformation is applied to the image before the * transform attribute in the Graphics2D context is applied. * The rendering attributes applied include the Clip, * Transform, and Composite attributes. Note * that no rendering is done if the specified transform is * noninvertible. *

    * Rendering hints set on the Graphics2D object might * be used in rendering the RenderableImage. * If explicit control is required over specific hints recognized by a * specific RenderableImage, or if knowledge of which hints * are used is required, then a RenderedImage should be * obtained directly from the RenderableImage * and rendered using *{@link #drawRenderedImage(RenderedImage, AffineTransform) drawRenderedImage}. * @param img the image to be rendered * @param xform the transformation from image space into user space * @see #setTransform(AffineTransform) * @see #setComposite(java.awt.Composite) * @see #setClip(Shape) * @see #drawRenderedImage */ public void drawRenderableImage(RenderableImage img, AffineTransform xform) { System.out.println("drawRenderableImage"); } /** * Renders the text specified by the specified String, * using the current Font and Paint attributes * in the Graphics2D context. * The baseline of the first character is at position * (xy) in the User Space. * The rendering attributes applied include the Clip, * Transform, Paint, Font and * Composite attributes. For characters in script systems * such as Hebrew and Arabic, the glyphs can be rendered from right to * left, in which case the coordinate supplied is the location of the * leftmost character on the baseline. * @param s the String to be rendered * @param x the x coordinate where the String should be * rendered * @param y the y coordinate where the String should be * rendered * @see #setPaint(java.awt.Paint) * @see java.awt.Graphics#setColor * @see java.awt.Graphics#setFont * @see #setTransform(AffineTransform) * @see #setComposite(java.awt.Composite) * @see #setClip(Shape) */ public void drawString(String s, float x, float y) { System.out.println("drawString(String)"); } /** * Renders the text of the specified iterator, using the * Graphics2D context's current Paint. The * iterator must specify a font * for each character. The baseline of the * first character is at position (xy) in the * User Space. * The rendering attributes applied include the Clip, * Transform, Paint, and * Composite attributes. * For characters in script systems such as Hebrew and Arabic, * the glyphs can be rendered from right to left, in which case the * coordinate supplied is the location of the leftmost character * on the baseline. * @param iterator the iterator whose text is to be rendered * @param x the x coordinate where the iterator's text is to be rendered * @param y the y coordinate where the iterator's text is to be rendered * @see #setPaint(java.awt.Paint) * @see java.awt.Graphics#setColor * @see #setTransform(AffineTransform) * @see #setComposite(java.awt.Composite) * @see #setClip(Shape) */ public void drawString(AttributedCharacterIterator iterator, float x, float y) { System.err.println("drawString(AttributedCharacterIterator)"); } /** * Fills the interior of a Shape using the settings of the * Graphics2D context. The rendering attributes applied * include the Clip, Transform, * Paint, and Composite. * @param s the Shape to be filled * @see #setPaint(java.awt.Paint) * @see java.awt.Graphics#setColor * @see #setTransform(AffineTransform) * @see #setComposite(java.awt.Composite) * @see #setClip(Shape) */ public void fill(Shape s) { System.err.println("fill"); } /** * Returns the device configuration associated with this * Graphics2D. */ public GraphicsConfiguration getDeviceConfiguration() { System.out.println("getDeviceConviguration"); return null; } /** * Used to create proper font metrics */ private Graphics2D fmg; { BufferedImage bi = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB); fmg = bi.createGraphics(); } /** * Gets the font metrics for the specified font. * @return the font metrics for the specified font. * @param f the specified font * @see java.awt.Graphics#getFont * @see java.awt.FontMetrics * @see java.awt.Graphics#getFontMetrics() */ public FontMetrics getFontMetrics(Font f) { return fmg.getFontMetrics(f); } /** * Sets the paint mode of this graphics context to alternate between * this graphics context's current color and the new specified color. * This specifies that logical pixel operations are performed in the * XOR mode, which alternates pixels between the current color and * a specified XOR color. *

    * When drawing operations are performed, pixels which are the * current color are changed to the specified color, and vice versa. *

    * Pixels that are of colors other than those two colors are changed * in an unpredictable but reversible manner; if the same figure is * drawn twice, then all pixels are restored to their original values. * @param c1 the XOR alternation color */ public void setXORMode(Color c1) { System.out.println("setXORMode"); } /** * Copies an area of the component by a distance specified by * dx and dy. From the point specified * by x and y, this method * copies downwards and to the right. To copy an area of the * component to the left or upwards, specify a negative value for * dx or dy. * If a portion of the source rectangle lies outside the bounds * of the component, or is obscured by another window or component, * copyArea will be unable to copy the associated * pixels. The area that is omitted can be refreshed by calling * the component's paint method. * @param x the x coordinate of the source rectangle. * @param y the y coordinate of the source rectangle. * @param width the width of the source rectangle. * @param height the height of the source rectangle. * @param dx the horizontal distance to copy the pixels. * @param dy the vertical distance to copy the pixels. */ public void copyArea(int x, int y, int width, int height, int dx, int dy) { System.out.println("copyArea"); } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/java2d/Dimension2DDouble.java0100644 0000000 0000000 00000005372 13777276623 030402 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: Dimension2DDouble.java 1345683 2012-06-03 14:50:33Z gadams $ */ package org.apache.xmlgraphics.java2d; import java.awt.geom.Dimension2D; import java.io.Serializable; /** * Subclass of Dimension2D which takes double values. */ public class Dimension2DDouble extends Dimension2D implements Serializable { private static final long serialVersionUID = 7909028357685520189L; private double width; private double height; /** * Default constructor. */ public Dimension2DDouble() { this.width = 0; this.height = 0; } /** * Main constructor. * @param width initial width * @param height initial height */ public Dimension2DDouble(double width, double height) { this.width = width; this.height = height; } /** {@inheritDoc} */ public double getWidth() { return width; } /** {@inheritDoc} */ public double getHeight() { return height; } /** {@inheritDoc} */ public void setSize(double w, double h) { this.width = w; this.height = h; } /** {@inheritDoc} */ public boolean equals(Object obj) { if (this == obj) { return true; } if (obj instanceof Dimension2DDouble) { final Dimension2DDouble other = (Dimension2DDouble)obj; if (Double.doubleToLongBits(height) != Double.doubleToLongBits(other.height)) { return false; } if (Double.doubleToLongBits(width) != Double.doubleToLongBits(other.width)) { return false; } return true; } else { return false; } } /** {@inheritDoc} */ public int hashCode() { double sum = width + height; return (int)(sum * (sum + 1) / 2 + width); } /** {@inheritDoc} */ public String toString() { return getClass().getName() + "[width=" + width + ",height=" + height + "]"; } } ././@LongLink0100644 0000000 0000000 00000000147 13777276623 011661 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/java2d/GeneralGraphics2DImagePainter.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/java2d/GeneralGraphics2DImagePainter.ja0100644 0000000 0000000 00000002270 13777276623 032311 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: GeneralGraphics2DImagePainter.java 1812121 2017-10-13 12:12:29Z ssteiner $ */ package org.apache.xmlgraphics.java2d; import java.awt.Graphics2D; import org.apache.xmlgraphics.ps.PSGenerator; public interface GeneralGraphics2DImagePainter extends Graphics2DImagePainter { Graphics2D getGraphics(boolean textAsShapes, PSGenerator gen); void addFallbackFont(String name, Object font); } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/java2d/GenericGraphicsDevice.java0100644 0000000 0000000 00000005140 13777276623 031302 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: GenericGraphicsDevice.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.java2d; import java.awt.GraphicsConfigTemplate; import java.awt.GraphicsConfiguration; import java.awt.GraphicsDevice; /** * This implements the {@link GraphicsDevice} interface as appropriate for the various output * configurations. */ public class GenericGraphicsDevice extends GraphicsDevice { /** * The Graphics Config that created us... */ private final GraphicsConfiguration gc; /** * Create a new graphics2D device. * * @param gc we should reference */ public GenericGraphicsDevice(GraphicsConfiguration gc) { this.gc = gc; } /** * Ignore template and return the only config we have * * @param gct the template configuration * @return the best configuration which is the only one */ public GraphicsConfiguration getBestConfiguration(GraphicsConfigTemplate gct) { return gc; } /** * Return an array of our one GraphicsConfig * * @return an array containing the one graphics configuration */ public GraphicsConfiguration[] getConfigurations() { return new GraphicsConfiguration[] {gc}; } /** * Return out sole GraphicsConfig. * * @return the graphics configuration that created this object */ public GraphicsConfiguration getDefaultConfiguration() { return gc; } /** * Generate an IdString.. * * @return the ID string for this device, uses toString */ public String getIDstring() { return toString(); } /** * Let the caller know that we are "a printer" * * @return the type which is always printer */ public int getType() { return GraphicsDevice.TYPE_PRINTER; } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/java2d/GraphicContext.java0100644 0000000 0000000 00000102641 13777276623 030053 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: GraphicContext.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.java2d; import java.awt.AlphaComposite; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Composite; import java.awt.Font; import java.awt.Paint; import java.awt.Rectangle; import java.awt.RenderingHints; import java.awt.Shape; import java.awt.Stroke; import java.awt.font.FontRenderContext; import java.awt.geom.AffineTransform; import java.awt.geom.Area; import java.awt.geom.GeneralPath; import java.awt.geom.NoninvertibleTransformException; import java.util.ArrayList; import java.util.List; import java.util.Map; // CSOFF: OperatorWrap // CSOFF: ParameterName // CSOFF: WhitespaceAround /** * Handles the attributes in a graphic context:
    * + Composite
    * + Font
    * + Paint
    * + Stroke
    * + Clip
    * + RenderingHints
    * + AffineTransform
    * * @version $Id: GraphicContext.java 1732018 2016-02-24 04:51:06Z gadams $ * * Originally authored by Vincent Hardy and Christophe Jolif. */ public class GraphicContext implements Cloneable { /** * Default Transform to be used for creating FontRenderContext. */ protected AffineTransform defaultTransform = new AffineTransform(); /** * Current AffineTransform. This is the concatenation * of the original AffineTransform (i.e., last setTransform * invocation) and the following transform invocations, * as captured by originalTransform and the transformStack. */ protected AffineTransform transform = new AffineTransform(); /** * Transform stack */ protected List transformStack = new ArrayList(); /** * Defines whether the transform stack is valid or not. * This is for use by the class clients. The client should * validate the stack every time it starts using it. The * stack becomes invalid when a new transform is set. * @see #invalidateTransformStack() * @see #isTransformStackValid * @see #setTransform */ protected boolean transformStackValid = true; /** * Current Paint */ protected Paint paint = Color.black; /** * Current Stroke */ protected Stroke stroke = new BasicStroke(); /** * Current Composite */ protected Composite composite = AlphaComposite.SrcOver; /** * Current clip */ protected Shape clip; /** * Current set of RenderingHints */ protected RenderingHints hints = new RenderingHints(null); /** * Current Font */ protected Font font = new Font("sanserif", Font.PLAIN, 12); /** * Current background color. */ protected Color background = new Color(0, 0, 0, 0); /** * Current foreground color */ protected Color foreground = Color.black; /** * Default constructor */ public GraphicContext() { // to workaround a JDK bug hints.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_DEFAULT); } /** * @param defaultDeviceTransform Default affine transform applied to map the user space to the * user space. */ public GraphicContext(AffineTransform defaultDeviceTransform) { this(); defaultTransform = new AffineTransform(defaultDeviceTransform); transform = new AffineTransform(defaultTransform); if (!defaultTransform.isIdentity()) { transformStack.add(TransformStackElement.createGeneralTransformElement(defaultTransform)); } } /** * Copy constructor. * @param template the instance to make a copy of */ protected GraphicContext(GraphicContext template) { this(template.defaultTransform); // // Now, copy each GC element in turn // // Default transform /* Set in constructor */ // Transform this.transform = new AffineTransform(template.transform); // Transform stack this.transformStack = new ArrayList(template.transformStack.size()); for (int i = 0; i < template.transformStack.size(); i++) { TransformStackElement stackElement = (TransformStackElement)template.transformStack.get(i); this.transformStack.add(stackElement.clone()); } // Transform stack validity this.transformStackValid = template.transformStackValid; // Paint (immutable by requirement) this.paint = template.paint; // Stroke (immutable by requirement) this.stroke = template.stroke; // Composite (immutable by requirement) this.composite = template.composite; // Clip if (template.clip != null) { this.clip = new GeneralPath(template.clip); } else { this.clip = null; } // RenderingHints this.hints = (RenderingHints)template.hints.clone(); // Font (immutable) this.font = template.font; // Background, Foreground (immutable) this.background = template.background; this.foreground = template.foreground; } /** * @return a deep copy of this context */ public Object clone() { return new GraphicContext(this); } /** * Gets this graphics context's current color. * @return this graphics context's current color. * @see java.awt.Color * @see java.awt.Graphics#setColor */ public Color getColor() { return foreground; } /** * Sets this graphics context's current color to the specified * color. All subsequent graphics operations using this graphics * context use this specified color. * @param c the new rendering color. * @see java.awt.Color * @see java.awt.Graphics#getColor */ public void setColor(Color c) { if (c == null) { return; } if (paint != c) { setPaint(c); } } /** * Gets the current font. * @return this graphics context's current font. * @see java.awt.Font * @see java.awt.Graphics#setFont */ public Font getFont() { return font; } /** * Sets this graphics context's font to the specified font. * All subsequent text operations using this graphics context * use this font. * @param font the font. * @see java.awt.Graphics#getFont */ public void setFont(Font font) { if (font != null) { this.font = font; } } /** * Returns the bounding rectangle of the current clipping area. * This method refers to the user clip, which is independent of the * clipping associated with device bounds and window visibility. * If no clip has previously been set, or if the clip has been * cleared using setClip(null), this method returns * null. * The coordinates in the rectangle are relative to the coordinate * system origin of this graphics context. * @return the bounding rectangle of the current clipping area, * or null if no clip is set. * @see java.awt.Graphics#getClip * @see java.awt.Graphics#clipRect * @see java.awt.Graphics#setClip(int, int, int, int) * @see java.awt.Graphics#setClip(Shape) * @since JDK1.1 */ public Rectangle getClipBounds() { Shape c = getClip(); if (c == null) { return null; } else { return c.getBounds(); } } /** * Intersects the current clip with the specified rectangle. * The resulting clipping area is the intersection of the current * clipping area and the specified rectangle. If there is no * current clipping area, either because the clip has never been * set, or the clip has been cleared using setClip(null), * the specified rectangle becomes the new clip. * This method sets the user clip, which is independent of the * clipping associated with device bounds and window visibility. * This method can only be used to make the current clip smaller. * To set the current clip larger, use any of the setClip methods. * Rendering operations have no effect outside of the clipping area. * @param x the x coordinate of the rectangle to intersect the clip with * @param y the y coordinate of the rectangle to intersect the clip with * @param width the width of the rectangle to intersect the clip with * @param height the height of the rectangle to intersect the clip with * @see #setClip(int, int, int, int) * @see #setClip(Shape) */ public void clipRect(int x, int y, int width, int height) { clip(new Rectangle(x, y, width, height)); } /** * Sets the current clip to the rectangle specified by the given * coordinates. This method sets the user clip, which is * independent of the clipping associated with device bounds * and window visibility. * Rendering operations have no effect outside of the clipping area. * @param x the x coordinate of the new clip rectangle. * @param y the y coordinate of the new clip rectangle. * @param width the width of the new clip rectangle. * @param height the height of the new clip rectangle. * @see java.awt.Graphics#clipRect * @see java.awt.Graphics#setClip(Shape) * @since JDK1.1 */ public void setClip(int x, int y, int width, int height) { setClip(new Rectangle(x, y, width, height)); } /** * Gets the current clipping area. * This method returns the user clip, which is independent of the * clipping associated with device bounds and window visibility. * If no clip has previously been set, or if the clip has been * cleared using setClip(null), this method returns * null. * @return a Shape object representing the * current clipping area, or null if * no clip is set. * @see java.awt.Graphics#getClipBounds() * @see java.awt.Graphics#clipRect * @see java.awt.Graphics#setClip(int, int, int, int) * @see java.awt.Graphics#setClip(Shape) * @since JDK1.1 */ public Shape getClip() { try { return transform.createInverse().createTransformedShape(clip); } catch (NoninvertibleTransformException e) { return null; } } /** * Sets the current clipping area to an arbitrary clip shape. * Not all objects that implement the Shape * interface can be used to set the clip. The only * Shape objects that are guaranteed to be * supported are Shape objects that are * obtained via the getClip method and via * Rectangle objects. This method sets the * user clip, which is independent of the clipping associated * with device bounds and window visibility. * @param clip the Shape to use to set the clip * @see java.awt.Graphics#getClip() * @see java.awt.Graphics#clipRect * @see java.awt.Graphics#setClip(int, int, int, int) * @since JDK1.1 */ public void setClip(Shape clip) { if (clip != null) { this.clip = transform.createTransformedShape(clip); } else { this.clip = null; } } /** * Sets the Composite for the Graphics2D context. * The Composite is used in all drawing methods such as * drawImage, drawString, draw, * and fill. It specifies how new pixels are to be combined * with the existing pixels on the graphics device during the rendering * process. *

    If this Graphics2D context is drawing to a * Component on the display screen and the * Composite is a custom object rather than an * instance of the AlphaComposite class, and if * there is a security manager, its checkPermission * method is called with an AWTPermission("readDisplayPixels") * permission. * * @param comp the Composite object to be used for rendering * @throws SecurityException * if a custom Composite object is being * used to render to the screen and a security manager * is set and its checkPermission method * does not allow the operation. * @see java.awt.Graphics#setXORMode * @see java.awt.Graphics#setPaintMode * @see java.awt.AlphaComposite */ public void setComposite(Composite comp) { this.composite = comp; } /** * Sets the Paint attribute for the * Graphics2D context. Calling this method * with a null Paint object does * not have any effect on the current Paint attribute * of this Graphics2D. * @param paint the Paint object to be used to generate * color during the rendering process, or null * @see java.awt.Graphics#setColor * @see java.awt.GradientPaint * @see java.awt.TexturePaint */ public void setPaint(Paint paint) { if (paint == null) { return; } this.paint = paint; if (paint instanceof Color) { foreground = (Color)paint; } else { // use default; otherwise the previous Color will be used foreground = Color.black; } } /** * Sets the Stroke for the Graphics2D context. * @param s the Stroke object to be used to stroke a * Shape during the rendering process * @see BasicStroke */ public void setStroke(Stroke s) { stroke = s; } /** * Sets the value of a single preference for the rendering algorithms. * Hint categories include controls for rendering quality and overall * time/quality trade-off in the rendering process. Refer to the * RenderingHints class for definitions of some common * keys and values. * @param hintKey the key of the hint to be set. * @param hintValue the value indicating preferences for the specified * hint category. * @see RenderingHints */ public void setRenderingHint(RenderingHints.Key hintKey, Object hintValue) { hints.put(hintKey, hintValue); } /** * Returns the value of a single preference for the rendering algorithms. * Hint categories include controls for rendering quality and overall * time/quality trade-off in the rendering process. Refer to the * RenderingHints class for definitions of some common * keys and values. * @param hintKey the key corresponding to the hint to get. * @return an object representing the value for the specified hint key. * Some of the keys and their associated values are defined in the * RenderingHints class. * @see RenderingHints */ public Object getRenderingHint(RenderingHints.Key hintKey) { return hints.get(hintKey); } /** * Replaces the values of all preferences for the rendering * algorithms with the specified hints. * The existing values for all rendering hints are discarded and * the new set of known hints and values are initialized from the * specified {@link Map} object. * Hint categories include controls for rendering quality and * overall time/quality trade-off in the rendering process. * Refer to the RenderingHints class for definitions of * some common keys and values. * @param hints the rendering hints to be set * @see RenderingHints */ public void setRenderingHints(Map hints) { this.hints = new RenderingHints(hints); } /** * Sets the values of an arbitrary number of preferences for the * rendering algorithms. * Only values for the rendering hints that are present in the * specified Map object are modified. * All other preferences not present in the specified * object are left unmodified. * Hint categories include controls for rendering quality and * overall time/quality trade-off in the rendering process. * Refer to the RenderingHints class for definitions of * some common keys and values. * @param hints the rendering hints to be set * @see RenderingHints */ public void addRenderingHints(Map hints) { this.hints.putAll(hints); } /** * Gets the preferences for the rendering algorithms. Hint categories * include controls for rendering quality and overall time/quality * trade-off in the rendering process. * Returns all of the hint key/value pairs that were ever specified in * one operation. Refer to the * RenderingHints class for definitions of some common * keys and values. * @return a reference to an instance of RenderingHints * that contains the current preferences. * @see RenderingHints */ public RenderingHints getRenderingHints() { return hints; } /** * Translates the origin of the graphics context to the point * (xy) in the current coordinate system. * Modifies this graphics context so that its new origin corresponds * to the point (xy) in this graphics context's * original coordinate system. All coordinates used in subsequent * rendering operations on this graphics context will be relative * to this new origin. * @param x the x coordinate. * @param y the y coordinate. */ public void translate(int x, int y) { if (x != 0 || y != 0) { transform.translate(x, y); transformStack.add(TransformStackElement.createTranslateElement(x, y)); } } /** * Concatenates the current * Graphics2D Transform * with a translation transform. * Subsequent rendering is translated by the specified * distance relative to the previous position. * This is equivalent to calling transform(T), where T is an * AffineTransform represented by the following matrix: *

         *          [   1    0    tx  ]
         *          [   0    1    ty  ]
         *          [   0    0    1   ]
         * 
    * @param tx the distance to translate along the x-axis * @param ty the distance to translate along the y-axis */ public void translate(double tx, double ty) { transform.translate(tx, ty); transformStack.add(TransformStackElement.createTranslateElement(tx, ty)); } /** * Concatenates the current Graphics2D * Transform with a rotation transform. * Subsequent rendering is rotated by the specified radians relative * to the previous origin. * This is equivalent to calling transform(R), where R is an * AffineTransform represented by the following matrix: *
         *          [   cos(theta)    -sin(theta)    0   ]
         *          [   sin(theta)     cos(theta)    0   ]
         *          [       0              0         1   ]
         * 
    * Rotating with a positive angle theta rotates points on the positive * x axis toward the positive y axis. * @param theta the angle of rotation in radians */ public void rotate(double theta) { transform.rotate(theta); transformStack.add(TransformStackElement.createRotateElement(theta)); } /** * Concatenates the current Graphics2D * Transform with a translated rotation * transform. Subsequent rendering is transformed by a transform * which is constructed by translating to the specified location, * rotating by the specified radians, and translating back by the same * amount as the original translation. This is equivalent to the * following sequence of calls: *
         *          translate(x, y);
         *          rotate(theta);
         *          translate(-x, -y);
         * 
    * Rotating with a positive angle theta rotates points on the positive * x axis toward the positive y axis. * @param theta the angle of rotation in radians * @param x x coordinate of the origin of the rotation * @param y y coordinate of the origin of the rotation */ public void rotate(double theta, double x, double y) { transform.rotate(theta, x, y); transformStack.add(TransformStackElement.createTranslateElement(x, y)); transformStack.add(TransformStackElement.createRotateElement(theta)); transformStack.add(TransformStackElement.createTranslateElement(-x, -y)); } /** * Concatenates the current Graphics2D * Transform with a scaling transformation * Subsequent rendering is resized according to the specified scaling * factors relative to the previous scaling. * This is equivalent to calling transform(S), where S is an * AffineTransform represented by the following matrix: *
         *          [   sx   0    0   ]
         *          [   0    sy   0   ]
         *          [   0    0    1   ]
         * 
    * @param sx the amount by which X coordinates in subsequent * rendering operations are multiplied relative to previous * rendering operations. * @param sy the amount by which Y coordinates in subsequent * rendering operations are multiplied relative to previous * rendering operations. */ public void scale(double sx, double sy) { transform.scale(sx, sy); transformStack.add(TransformStackElement.createScaleElement(sx, sy)); } /** * Concatenates the current Graphics2D * Transform with a shearing transform. * Subsequent renderings are sheared by the specified * multiplier relative to the previous position. * This is equivalent to calling transform(SH), where SH * is an AffineTransform represented by the following * matrix: *
         *          [   1   shx   0   ]
         *          [  shy   1    0   ]
         *          [   0    0    1   ]
         * 
    * @param shx the multiplier by which coordinates are shifted in * the positive X axis direction as a function of their Y coordinate * @param shy the multiplier by which coordinates are shifted in * the positive Y axis direction as a function of their X coordinate */ public void shear(double shx, double shy) { transform.shear(shx, shy); transformStack.add(TransformStackElement.createShearElement(shx, shy)); } /** * Composes an AffineTransform object with the * Transform in this Graphics2D according * to the rule last-specified-first-applied. If the current * Transform is Cx, the result of composition * with Tx is a new Transform Cx'. Cx' becomes the * current Transform for this Graphics2D. * Transforming a point p by the updated Transform Cx' is * equivalent to first transforming p by Tx and then transforming * the result by the original Transform Cx. In other * words, Cx'(p) = Cx(Tx(p)). A copy of the Tx is made, if necessary, * so further modifications to Tx do not affect rendering. * @param tx the AffineTransform object to be composed with * the current Transform * @see #setTransform * @see AffineTransform */ public void transform(AffineTransform tx) { transform.concatenate(tx); transformStack.add(TransformStackElement.createGeneralTransformElement(tx)); } /** * Sets the Transform in the Graphics2D * context. * @param tx the AffineTransform object to be used in the * rendering process * @see #transform * @see AffineTransform */ public void setTransform(AffineTransform tx) { transform = new AffineTransform(tx); invalidateTransformStack(); if (!tx.isIdentity()) { transformStack.add(TransformStackElement.createGeneralTransformElement(tx)); } } /** * Marks the GraphicContext's isNewTransformStack to false * as a memento that the current transform stack was read and * has not been reset. Only the setTransform method can * override this memento. */ public void validateTransformStack() { transformStackValid = true; } /** * Checks the status of the transform stack. * @return true if the transform stack is valid */ public boolean isTransformStackValid() { return transformStackValid; } /** * @return array containing the successive transforms that * were concatenated with the original one. */ public TransformStackElement[] getTransformStack() { TransformStackElement[] stack = new TransformStackElement[transformStack.size()]; transformStack.toArray(stack); return stack; } /** * Marks the GraphicContext's isNewTransformStack to true * as a memento that the current transform stack was reset * since it was last read. Only validateTransformStack * can override this memento */ protected void invalidateTransformStack() { transformStack.clear(); transformStackValid = false; } /** * Returns a copy of the current Transform in the * Graphics2D context. * @return the current AffineTransform in the * Graphics2D context. * @see #transform * @see #setTransform */ public AffineTransform getTransform() { return new AffineTransform(transform); } /** * Returns the current Paint of the * Graphics2D context. * @return the current Graphics2D Paint, * which defines a color or pattern. * @see #setPaint * @see java.awt.Graphics#setColor */ public Paint getPaint() { return paint; } /** * Returns the current Composite in the * Graphics2D context. * @return the current Graphics2D Composite, * which defines a compositing style. * @see #setComposite */ public Composite getComposite() { return composite; } /** * Sets the background color for the Graphics2D context. * The background color is used for clearing a region. * When a Graphics2D is constructed for a * Component, the background color is * inherited from the Component. Setting the background color * in the Graphics2D context only affects the subsequent * clearRect calls and not the background color of the * Component. To change the background * of the Component, use appropriate methods of * the Component. * @param color the background color that isused in * subsequent calls to clearRect * @see #getBackground * @see java.awt.Graphics#clearRect */ public void setBackground(Color color) { if (color == null) { return; } background = color; } /** * Returns the background color used for clearing a region. * @return the current Graphics2D Color, * which defines the background color. * @see #setBackground */ public Color getBackground() { return background; } /** * Returns the current Stroke in the * Graphics2D context. * @return the current Graphics2D Stroke, * which defines the line style. * @see #setStroke */ public Stroke getStroke() { return stroke; } /** * Intersects the current Clip with the interior of the * specified Shape and sets the Clip to the * resulting intersection. The specified Shape is * transformed with the current Graphics2D * Transform before being intersected with the current * Clip. This method is used to make the current * Clip smaller. * To make the Clip larger, use setClip. * The user clip modified by this method is independent of the * clipping associated with device bounds and visibility. If no clip has * previously been set, or if the clip has been cleared using * {@link java.awt.Graphics#setClip(Shape) setClip} with a * null argument, the specified Shape becomes * the new user clip. * @param s the Shape to be intersected with the current * Clip. If s is null, * this method clears the current Clip. */ public void clip(Shape s) { if (s != null) { s = transform.createTransformedShape(s); } if (clip != null) { Area newClip = new Area(clip); newClip.intersect(new Area(s)); clip = new GeneralPath(newClip); } else { clip = s; } } /** * Get the rendering context of the Font within this * Graphics2D context. * The {@link FontRenderContext} * encapsulates application hints such as anti-aliasing and * fractional metrics, as well as target device specific information * such as dots-per-inch. This information should be provided by the * application when using objects that perform typographical * formatting, such as Font and * TextLayout. This information should also be provided * by applications that perform their own layout and need accurate * measurements of various characteristics of glyphs such as advance * and line height when various rendering hints have been applied to * the text rendering. * * @return a reference to an instance of FontRenderContext. * @see java.awt.font.FontRenderContext * @see java.awt.Font#createGlyphVector(FontRenderContext,char[]) * @see java.awt.font.TextLayout * @since JDK1.2 */ public FontRenderContext getFontRenderContext() { // // Find if antialiasing should be used. // Object antialiasingHint = hints.get(RenderingHints.KEY_TEXT_ANTIALIASING); boolean isAntialiased = true; if (antialiasingHint != RenderingHints.VALUE_TEXT_ANTIALIAS_ON && antialiasingHint != RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT) { // If antialias was not turned off, then use the general rendering // hint. if (antialiasingHint != RenderingHints.VALUE_TEXT_ANTIALIAS_OFF) { antialiasingHint = hints.get(RenderingHints.KEY_ANTIALIASING); // Test general hint if (antialiasingHint != RenderingHints.VALUE_ANTIALIAS_ON && antialiasingHint != RenderingHints.VALUE_ANTIALIAS_DEFAULT) { // Antialiasing was not requested. However, if it was not turned // off explicitly, use it. if (antialiasingHint == RenderingHints.VALUE_ANTIALIAS_OFF) { isAntialiased = false; } } } else { isAntialiased = false; } } // // Find out whether fractional metrics should be used. // boolean useFractionalMetrics = true; if (hints.get(RenderingHints.KEY_FRACTIONALMETRICS) == RenderingHints.VALUE_FRACTIONALMETRICS_OFF) { useFractionalMetrics = false; } FontRenderContext frc = new FontRenderContext(defaultTransform, isAntialiased, useFractionalMetrics); return frc; } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/java2d/Graphics2DImagePainter.java0100644 0000000 0000000 00000003307 13777276623 031344 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: Graphics2DImagePainter.java 1345683 2012-06-03 14:50:33Z gadams $ */ package org.apache.xmlgraphics.java2d; import java.awt.Dimension; import java.awt.Graphics2D; import java.awt.geom.Rectangle2D; /** * This interface is used to paint vector graphic images. Components that can paint using * a Graphics2D instance (i.e. Java2D) can implement this interface to paint themselves. */ public interface Graphics2DImagePainter { /** * Called to paint the image. Implementations should scale so the image is * painted fully inside the given area indicated by then Rectangle2D object. * @param g2d the Graphics2D instance to paint on * @param area the target area for the image (in target device units) */ void paint(Graphics2D g2d, Rectangle2D area); /** * @return the dimensions (intrinsic size) of the image to be painted in millipoints */ Dimension getImageSize(); } ././@LongLink0100644 0000000 0000000 00000000157 13777276623 011662 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/java2d/GraphicsConfigurationWithTransparency.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/java2d/GraphicsConfigurationWithTranspa0100644 0000000 0000000 00000010551 13777276623 032664 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: GraphicsConfigurationWithTransparency.java 1862543 2019-07-04 09:25:38Z ssteiner $ */ package org.apache.xmlgraphics.java2d; import java.awt.GraphicsDevice; import java.awt.Rectangle; import java.awt.Transparency; import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import java.awt.image.ColorModel; /** * An implementation of {@link java.awt.GraphicsConfiguration} that supports transparencies (alpha * channels). */ public class GraphicsConfigurationWithTransparency extends AbstractGraphicsConfiguration { // We use this to get a good colormodel.. private static final BufferedImage BI_WITH_ALPHA = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB); // We use this to get a good colormodel.. private static final BufferedImage BI_WITHOUT_ALPHA = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB); /** * Construct a buffered image with an alpha channel, unless transparency is OPAQUE (no alpha * at all). * * @param width the width of the image * @param height the height of the image * @param transparency the alpha value of the image * @return the new buffered image */ public BufferedImage createCompatibleImage(int width, int height, int transparency) { if (transparency == Transparency.OPAQUE) { return new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); } else { return new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); } } /** * Construct a buffered image with an alpha channel. * * @param width the width of the image * @param height the height of the image * @return the new buffered image */ public BufferedImage createCompatibleImage(int width, int height) { return new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); } /** * TODO: This should return the page bounds in Pts, I couldn't figure out how to get this for * the current page (this still works for now, but it should be fixed...). * * @return the bounds of the document page */ public Rectangle getBounds() { return new Rectangle(); } /** * Return a good default color model for this 'device'. * @return the colour model for the configuration */ public ColorModel getColorModel() { return BI_WITH_ALPHA.getColorModel(); } /** * Return a good color model given transparency * * @param transparency the alpha value for the colour model * @return the colour model for the configuration */ public ColorModel getColorModel(int transparency) { if (transparency == Transparency.OPAQUE) { return BI_WITHOUT_ALPHA.getColorModel(); } else { return BI_WITH_ALPHA.getColorModel(); } } /** * The default transform (1:1). * * @return the default transform for the configuration */ public AffineTransform getDefaultTransform() { return new AffineTransform(); } /** * The normalizing transform (1:1) (since we currently * render images at 72dpi, which we might want to change * in the future). * * @return the normalizing transform for the configuration */ public AffineTransform getNormalizingTransform() { return new AffineTransform(2, 0, 0, 2, 0, 0); } /** * Return our dummy instance of GraphicsDevice * * @return the graphics device */ public GraphicsDevice getDevice() { return new GenericGraphicsDevice(this); } } ././@LongLink0100644 0000000 0000000 00000000162 13777276623 011656 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/java2d/GraphicsConfigurationWithoutTransparency.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/java2d/GraphicsConfigurationWithoutTran0100644 0000000 0000000 00000006031 13777276623 032706 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.xmlgraphics.java2d; import java.awt.GraphicsDevice; import java.awt.Rectangle; import java.awt.Transparency; import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import java.awt.image.ColorModel; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * An implementation of {@link java.awt.GraphicsConfiguration} that does not support transparencies * (alpha channels). */ public class GraphicsConfigurationWithoutTransparency extends AbstractGraphicsConfiguration { private static final Log LOG = LogFactory.getLog(GraphicsConfigurationWithoutTransparency.class); // We use this to get a good colormodel.. private static final BufferedImage BI_WITHOUT_ALPHA = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB); private final GraphicsConfigurationWithTransparency defaultDelegate = new GraphicsConfigurationWithTransparency(); @Override public GraphicsDevice getDevice() { return new GenericGraphicsDevice(this); } @Override public BufferedImage createCompatibleImage(int width, int height) { return defaultDelegate.createCompatibleImage(width, height, Transparency.OPAQUE); } @Override public BufferedImage createCompatibleImage(int width, int height, int transparency) { if (transparency != Transparency.OPAQUE) { LOG.warn("Does not support transparencies (alpha channels) in images"); } return defaultDelegate.createCompatibleImage(width, height, Transparency.OPAQUE); } @Override public ColorModel getColorModel() { return BI_WITHOUT_ALPHA.getColorModel(); } @Override public ColorModel getColorModel(int transparency) { if (transparency == Transparency.OPAQUE) { LOG.warn("Does not support transparencies (alpha channels) in images"); } return getColorModel(); } @Override public AffineTransform getDefaultTransform() { return defaultDelegate.getDefaultTransform(); } @Override public AffineTransform getNormalizingTransform() { return defaultDelegate.getNormalizingTransform(); } @Override public Rectangle getBounds() { return new Rectangle(); } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/java2d/StrokingTextHandler.java0100644 0000000 0000000 00000003262 13777276623 031073 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: StrokingTextHandler.java 995366 2010-09-09 10:02:17Z jeremias $ */ package org.apache.xmlgraphics.java2d; import java.awt.Graphics2D; import java.awt.Shape; import java.awt.font.FontRenderContext; import java.awt.font.GlyphVector; import java.io.IOException; /** * Default TextHandler implementation which paints text using graphics primitives (shapes). */ public class StrokingTextHandler implements TextHandler { /** * Default constructor. */ public StrokingTextHandler() { //nop } /** {@inheritDoc} */ public void drawString(Graphics2D g2d, String text, float x, float y) throws IOException { java.awt.Font awtFont = g2d.getFont(); FontRenderContext frc = g2d.getFontRenderContext(); GlyphVector gv = awtFont.createGlyphVector(frc, text); Shape glyphOutline = gv.getOutline(x, y); g2d.fill(glyphOutline); } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/java2d/TextHandler.java0100644 0000000 0000000 00000002743 13777276623 027355 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: TextHandler.java 995366 2010-09-09 10:02:17Z jeremias $ */ package org.apache.xmlgraphics.java2d; import java.awt.Graphics2D; import java.io.IOException; /** * Interface which the Graphics2D class delegates text painting to. */ public interface TextHandler { /** * Draw some text. * @param g2d the graphics 2D implementation * @param text the text to paint * @param x the x-coordinate where the String should be rendered * @param y the y-coordinate where the String should be rendered * @throws IOException In case of an I/O error */ void drawString(Graphics2D g2d, String text, float x, float y) throws IOException; } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/java2d/TransformStackElement.java0100644 0000000 0000000 00000017071 13777276623 031406 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: TransformStackElement.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.java2d; import java.awt.geom.AffineTransform; // CSOFF: EmptyBlock // CSOFF: NoWhitespaceAfter // CSOFF: OperatorWrap // CSOFF: WhitespaceAround /** * Contains a description of an elementary transform stack element, * such as a rotate or translate. A transform stack element has a * type and a value, which is an array of double values.
    * * @version $Id: TransformStackElement.java 1732018 2016-02-24 04:51:06Z gadams $ * * Originally authored by Vincent Hardy and Paul Evenblij. */ public abstract class TransformStackElement implements Cloneable { /** * Transform type */ private TransformType type; /** * Value */ private double[] transformParameters; /** * @param type transform type * @param transformParameters parameters for transform */ protected TransformStackElement(TransformType type, double[] transformParameters) { this.type = type; this.transformParameters = transformParameters; } /** * @return an object which is a deep copy of this one */ public Object clone() { TransformStackElement newElement = null; // start with a shallow copy to get our implementations right try { newElement = (TransformStackElement) super.clone(); } catch (java.lang.CloneNotSupportedException ex) { throw new AssertionError(); } // now deep copy the parameter array double[] transformParameters = new double[this.transformParameters.length]; System.arraycopy(this.transformParameters, 0, transformParameters, 0, transformParameters.length); newElement.transformParameters = transformParameters; return newElement; } /* * Factory methods */ public static TransformStackElement createTranslateElement(double tx, double ty) { return new TransformStackElement(TransformType.TRANSLATE, new double[]{ tx, ty }) { boolean isIdentity(double[] parameters) { return parameters[0] == 0 && parameters[1] == 0; } }; } public static TransformStackElement createRotateElement(double theta) { return new TransformStackElement(TransformType.ROTATE, new double[]{ theta }) { boolean isIdentity(double[] parameters) { return Math.cos(parameters[0]) == 1; } }; } public static TransformStackElement createScaleElement(double scaleX, double scaleY) { return new TransformStackElement(TransformType.SCALE, new double[]{ scaleX, scaleY }) { boolean isIdentity(double[] parameters) { return parameters[0] == 1 && parameters[1] == 1; } }; } public static TransformStackElement createShearElement(double shearX, double shearY) { return new TransformStackElement(TransformType.SHEAR, new double[]{ shearX, shearY }) { boolean isIdentity(double[] parameters) { return parameters[0] == 0 && parameters[1] == 0; } }; } public static TransformStackElement createGeneralTransformElement( AffineTransform txf) { double[] matrix = new double[6]; txf.getMatrix(matrix); return new TransformStackElement(TransformType.GENERAL, matrix) { boolean isIdentity(double[] m) { return (m[0] == 1 && m[2] == 0 && m[4] == 0 && m[1] == 0 && m[3] == 1 && m[5] == 0); } }; } /** * Implementation should determine if the parameter list represents * an identity transform, for the instance transform type. */ abstract boolean isIdentity(double[] parameters); /** * @return true iff this transform is the identity transform */ public boolean isIdentity() { return isIdentity(transformParameters); } /** * @return array of values containing this transform element's parameters */ public double[] getTransformParameters() { return transformParameters; } /** * @return this transform type */ public TransformType getType() { return type; } /* * Concatenation utility. Requests this transform stack element * to concatenate with the input stack element. Only elements * of the same types are concatenated. For example, if this * element represents a translation, it will concatenate with * another translation, but not with any other kind of * stack element. * @param stackElement element to be concatenated with this one. * @return true if the input stackElement was concatenated with * this one. False otherwise. */ public boolean concatenate(TransformStackElement stackElement) { boolean canConcatenate = false; if (type.toInt() == stackElement.type.toInt()) { canConcatenate = true; switch(type.toInt()) { case TransformType.TRANSFORM_TRANSLATE: transformParameters[0] += stackElement.transformParameters[0]; transformParameters[1] += stackElement.transformParameters[1]; break; case TransformType.TRANSFORM_ROTATE: transformParameters[0] += stackElement.transformParameters[0]; break; case TransformType.TRANSFORM_SCALE: transformParameters[0] *= stackElement.transformParameters[0]; transformParameters[1] *= stackElement.transformParameters[1]; break; case TransformType.TRANSFORM_GENERAL: transformParameters = matrixMultiply(transformParameters, stackElement.transformParameters); break; default: canConcatenate = false; } } return canConcatenate; } /** * Multiplies two 2x3 matrices of double precision values */ private double[] matrixMultiply(double[] matrix1, double[] matrix2) { double[] product = new double[6]; AffineTransform transform1 = new AffineTransform(matrix1); transform1.concatenate(new AffineTransform(matrix2)); transform1.getMatrix(product); return product; } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/java2d/TransformType.java0100644 0000000 0000000 00000007360 13777276623 027750 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: TransformType.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.java2d; // CSOFF: WhitespaceAround /** * Enumeration for transformation types. * * @version $Id: TransformType.java 1732018 2016-02-24 04:51:06Z gadams $ * Originally authored by Vincent Hardy. */ public final class TransformType { /* * Transform type constants */ public static final int TRANSFORM_TRANSLATE = 0; public static final int TRANSFORM_ROTATE = 1; public static final int TRANSFORM_SCALE = 2; public static final int TRANSFORM_SHEAR = 3; public static final int TRANSFORM_GENERAL = 4; /** * Strings describing the elementary transforms */ public static final String TRANSLATE_STRING = "translate"; public static final String ROTATE_STRING = "rotate"; public static final String SCALE_STRING = "scale"; public static final String SHEAR_STRING = "shear"; public static final String GENERAL_STRING = "general"; /** * TransformType values */ public static final TransformType TRANSLATE = new TransformType(TRANSFORM_TRANSLATE, TRANSLATE_STRING); public static final TransformType ROTATE = new TransformType(TRANSFORM_ROTATE, ROTATE_STRING); public static final TransformType SCALE = new TransformType(TRANSFORM_SCALE, SCALE_STRING); public static final TransformType SHEAR = new TransformType(TRANSFORM_SHEAR, SHEAR_STRING); public static final TransformType GENERAL = new TransformType(TRANSFORM_GENERAL, GENERAL_STRING); private String desc; private int val; /** * Constructor is private so that no instances other than * the ones in the enumeration can be created. * @see #readResolve */ private TransformType(int val, String desc) { this.desc = desc; this.val = val; } /** * @return description */ public String toString() { return desc; } /** * Convenience for enumeration switching. * That is, *
         *   switch(transformType.toInt()){
         *       case TransformType.TRANSFORM_TRANSLATE:
         *        ....
         *       case TransformType.TRANSFORM_ROTATE:
         * 
    */ public int toInt() { return val; } /** * This is called by the serialization code before it returns an unserialized * object. To provide for unicity of instances, the instance that was read * is replaced by its static equivalent */ public Object readResolve() { switch(val) { case TRANSFORM_TRANSLATE: return TransformType.TRANSLATE; case TRANSFORM_ROTATE: return TransformType.ROTATE; case TRANSFORM_SCALE: return TransformType.SCALE; case TRANSFORM_SHEAR: return TransformType.SHEAR; case TRANSFORM_GENERAL: return TransformType.GENERAL; default: throw new RuntimeException("Unknown TransformType value"); } } } ././@LongLink0100644 0000000 0000000 00000000160 13777276623 011654 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/java2d/color/AbstractDeviceSpecificColorSpace.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/java2d/color/AbstractDeviceSpecificColo0100644 0000000 0000000 00000002763 13777276623 032501 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: AbstractDeviceSpecificColorSpace.java 1051421 2010-12-21 08:54:25Z jeremias $ */ package org.apache.xmlgraphics.java2d.color; import java.awt.color.ColorSpace; /** * Base class for device-specific (uncalibrated) color spaces. */ public abstract class AbstractDeviceSpecificColorSpace extends ColorSpace { private static final long serialVersionUID = -4888985582872101875L; /** * Creates a new instance. * @param type the color space type ({@link ColorSpace}.TYPE_*) * @param numcomponents the number of color components applicable to the color space */ protected AbstractDeviceSpecificColorSpace(int type, int numcomponents) { super(type, numcomponents); } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/java2d/color/CIELabColorSpace.java0100644 0000000 0000000 00000025057 13777276623 031246 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: CIELabColorSpace.java 1051421 2010-12-21 08:54:25Z jeremias $ */ package org.apache.xmlgraphics.java2d.color; import java.awt.Color; import java.awt.color.ColorSpace; /** * This class defines the CIE L*a*b* (CIE 1976) color space. Valid values for L* are between 0 * and 100, for a* and b* between -127 and +127. * @see http://en.wikipedia.org/wiki/Lab_color_space */ public class CIELabColorSpace extends ColorSpace { private static final long serialVersionUID = -1821569090707520704L; //CIE XYZ tristimulus values of the reference white point: Observer= 2 degrees, Illuminant= D65 private static final float REF_X_D65 = 95.047f; private static final float REF_Y_D65 = 100.000f; private static final float REF_Z_D65 = 108.883f; //CIE XYZ tristimulus values of the reference white point: Illuminant= D50 private static final float REF_X_D50 = 96.42f; private static final float REF_Y_D50 = 100.00f; private static final float REF_Z_D50 = 82.49f; private static final double D = 6.0 / 29.0; private static final double REF_A = 1.0 / (3 * Math.pow(D, 2)); //7.787037... private static final double REF_B = 16.0 / 116.0; private static final double T0 = Math.pow(D, 3); //0.008856... private float wpX; private float wpY; private float wpZ; /** * Default constructor using the D65 white point. */ public CIELabColorSpace() { this(getD65WhitePoint()); } /** * CIE Lab space constructor which allows to give an arbitrary white point. * @param whitePoint the white point in XYZ coordinates (valid values: 0.0f to 1.0f, although * values slightly larger than 1.0f are common) */ public CIELabColorSpace(float[] whitePoint) { super(ColorSpace.TYPE_Lab, 3); checkNumComponents(whitePoint, 3); this.wpX = whitePoint[0]; this.wpY = whitePoint[1]; this.wpZ = whitePoint[2]; } /** * Returns the D65 white point. * @return the D65 white point. */ public static float[] getD65WhitePoint() { return new float[] {REF_X_D65, REF_Y_D65, REF_Z_D65}; } /** * Returns the D50 white point. * @return the D50 white point. */ public static float[] getD50WhitePoint() { return new float[] {REF_X_D50, REF_Y_D50, REF_Z_D50}; } private void checkNumComponents(float[] colorvalue) { checkNumComponents(colorvalue, getNumComponents()); } private void checkNumComponents(float[] colorvalue, int expected) { if (colorvalue == null) { throw new NullPointerException("color value may not be null"); } if (colorvalue.length != expected) { throw new IllegalArgumentException("Expected " + expected + " components, but got " + colorvalue.length); } } /** * Returns the configured white point. * @return the white point in CIE XYZ coordinates */ public float[] getWhitePoint() { return new float[] {wpX, wpY, wpZ}; } private static final String CIE_LAB_ONLY_HAS_3_COMPONENTS = "CIE Lab only has 3 components!"; /** {@inheritDoc} */ @Override public float getMinValue(int component) { switch (component) { case 0: //L* return 0f; case 1: //a* case 2: //b* return -128f; default: throw new IllegalArgumentException(CIE_LAB_ONLY_HAS_3_COMPONENTS); } } /** {@inheritDoc} */ @Override public float getMaxValue(int component) { switch (component) { case 0: //L* return 100f; case 1: //a* case 2: //b* return 128f; default: throw new IllegalArgumentException(CIE_LAB_ONLY_HAS_3_COMPONENTS); } } /** {@inheritDoc} */ @Override public String getName(int component) { switch (component) { case 0: return "L*"; case 1: return "a*"; case 2: return "b*"; default: throw new IllegalArgumentException(CIE_LAB_ONLY_HAS_3_COMPONENTS); } } //Note: the conversion functions used here were mostly borrowed from Apache Commons Sanselan //and adjusted to the local requirements. /** {@inheritDoc} */ @Override public float[] fromCIEXYZ(float[] colorvalue) { checkNumComponents(colorvalue, 3); float x = colorvalue[0]; float y = colorvalue[1]; float z = colorvalue[2]; double varX = x / wpX; double varY = y / wpY; double varZ = z / wpZ; if (varX > T0) { varX = Math.pow(varX, (1 / 3.0)); } else { varX = (REF_A * varX) + REF_B; } if (varY > T0) { varY = Math.pow(varY, 1 / 3.0); } else { varY = (REF_A * varY) + REF_B; } if (varZ > T0) { varZ = Math.pow(varZ, 1 / 3.0); } else { varZ = (REF_A * varZ) + REF_B; } float l = (float)((116 * varY) - 16); float a = (float)(500 * (varX - varY)); float b = (float)(200 * (varY - varZ)); //Normalize to range 0.0..1.0 l = normalize(l, 0); a = normalize(a, 1); b = normalize(b, 2); return new float[] {l, a, b}; } /** {@inheritDoc} */ @Override public float[] fromRGB(float[] rgbvalue) { ColorSpace sRGB = ColorSpace.getInstance(ColorSpace.CS_sRGB); float[] xyz = sRGB.toCIEXYZ(rgbvalue); return fromCIEXYZ(xyz); } /** {@inheritDoc} */ @Override public float[] toCIEXYZ(float[] colorvalue) { checkNumComponents(colorvalue); //Scale to native value range float l = denormalize(colorvalue[0], 0); float a = denormalize(colorvalue[1], 1); float b = denormalize(colorvalue[2], 2); return toCIEXYZNative(l, a, b); } /** * Transforms a color value assumed to be in this {@link ColorSpace} * into the CS_CIEXYZ conversion color space. This method uses component values * in CIE Lab's native color ranges rather than the normalized values between 0 and 1. * @param l the L* component (values between 0 and 100) * @param a the a* component (usually between -128 and +128) * @param b the b* component (usually between -128 and +128) * @return the XYZ color values * @see #toCIEXYZ(float[]) */ public float[] toCIEXYZNative(float l, float a, float b) { double varY = (l + 16) / 116.0; double varX = a / 500 + varY; double varZ = varY - b / 200.0; if (Math.pow(varY, 3) > T0) { varY = Math.pow(varY, 3); } else { varY = (varY - 16 / 116.0) / REF_A; } if (Math.pow(varX, 3) > T0) { varX = Math.pow(varX, 3); } else { varX = (varX - 16 / 116.0) / REF_A; } if (Math.pow(varZ, 3) > T0) { varZ = Math.pow(varZ, 3); } else { varZ = (varZ - 16 / 116.0) / REF_A; } float x = (float)(wpX * varX / 100); float y = (float)(wpY * varY / 100); float z = (float)(wpZ * varZ / 100); return new float[] {x, y, z}; } /** {@inheritDoc} */ @Override public float[] toRGB(float[] colorvalue) { ColorSpace sRGB = ColorSpace.getInstance(ColorSpace.CS_sRGB); float[] xyz = toCIEXYZ(colorvalue); return sRGB.fromCIEXYZ(xyz); } private float getNativeValueRange(int component) { return getMaxValue(component) - getMinValue(component); } private float normalize(float value, int component) { return (value - getMinValue(component)) / getNativeValueRange(component); } private float denormalize(float value, int component) { return value * getNativeValueRange(component) + getMinValue(component); } /** * Converts normalized (0..1) color components to CIE L*a*b*'s native value range. * @param comps the normalized components. * @return the denormalized components */ public float[] toNativeComponents(float[] comps) { checkNumComponents(comps); float[] nativeComps = new float[comps.length]; for (int i = 0, c = comps.length; i < c; i++) { nativeComps[i] = denormalize(comps[i], i); } return nativeComps; } /** * Creates a {@link Color} instance from color values usually used by the L*a*b* color space * by scaling them to the 0.0..1.0 range expected by Color's constructor. * @param colorvalue the original color values * (native value range, i.e. not normalized to 0.0..1.0) * @param alpha the alpha component * @return the requested color instance */ public Color toColor(float[] colorvalue, float alpha) { int c = colorvalue.length; float[] normalized = new float[c]; for (int i = 0; i < c; i++) { normalized[i] = normalize(colorvalue[i], i); } //Using ColorWithAlternatives for better equals() functionality return new ColorWithAlternatives(this, normalized, alpha, null); } /** * Creates a {@link Color} instance from color values usually used by the L*a*b* color space * by scaling them to the 0.0..1.0 range expected by Color's constructor. * @param l the L* component (values between 0 and 100) * @param a the a* component (usually between -128 and +127) * @param b the b* component (usually between -128 and +127) * @param alpha the alpha component (values between 0 and 1) * @return the requested color instance */ public Color toColor(float l, float a, float b, float alpha) { return toColor(new float[] {l, a, b}, alpha); } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/java2d/color/ColorConverter.java0100644 0000000 0000000 00000002201 13777276623 031204 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ColorConverter.java 1358252 2012-07-06 15:03:16Z mehdi $ */ package org.apache.xmlgraphics.java2d.color; import java.awt.Color; /** * Utility for implementing a color conversion scheme. */ public interface ColorConverter { /** * @param color to convert * @return converted color */ Color convert(Color color); } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/java2d/color/ColorSpaceOrigin.java0100644 0000000 0000000 00000002603 13777276623 031446 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ColorSpaceOrigin.java 1598621 2014-05-30 14:55:00Z ssteiner $ */ package org.apache.xmlgraphics.java2d.color; /** * Interface used to decorate java.awt.color.ColorSpaces subclasses * to report the origin of the associated color profile. */ public interface ColorSpaceOrigin { /** * Returns the name of the profile used to identify the color space in a particular context. * @return the profile name */ String getProfileName(); /** * Returns the URI identifying the associate color profile. * @return the profile URI */ String getProfileURI(); } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/java2d/color/ColorSpaces.java0100644 0000000 0000000 00000006472 13777276623 030471 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ColorSpaces.java 1051421 2010-12-21 08:54:25Z jeremias $ */ package org.apache.xmlgraphics.java2d.color; import java.awt.color.ColorSpace; /** * Provides access to various color spaces. */ public final class ColorSpaces { private static DeviceCMYKColorSpace deviceCMYK; private static CIELabColorSpace cieLabD50; private static CIELabColorSpace cieLabD65; private ColorSpaces() { //Don't instantiate this class } /** * Returns an instance of the device-specific CMYK color space. * @return an instance of the device-specific CMYK color space */ public static synchronized DeviceCMYKColorSpace getDeviceCMYKColorSpace() { if (deviceCMYK == null) { deviceCMYK = new DeviceCMYKColorSpace(); } return deviceCMYK; } /** * Indicates whether the given color space is device-specific (i.e. uncalibrated). * @param cs the color space to check * @return true if the color space is device-specific */ public static boolean isDeviceColorSpace(ColorSpace cs) { return (cs instanceof AbstractDeviceSpecificColorSpace); } /** * Returns an instance of the CIE L*a*b* color space using the D50 white point. * @return an instance of the requested CIE L*a*b* color space */ public static synchronized CIELabColorSpace getCIELabColorSpaceD50() { if (cieLabD50 == null) { cieLabD50 = new CIELabColorSpace(CIELabColorSpace.getD50WhitePoint()); } return cieLabD50; } /** * Returns an instance of the CIE L*a*b* color space using the D65 white point. * @return an instance of the requested CIE L*a*b* color space */ public static synchronized CIELabColorSpace getCIELabColorSpaceD65() { if (cieLabD65 == null) { cieLabD65 = new CIELabColorSpace(CIELabColorSpace.getD65WhitePoint()); } return cieLabD65; } private static final ColorSpaceOrigin UNKNOWN_ORIGIN = new ColorSpaceOrigin() { public String getProfileURI() { return null; } public String getProfileName() { return null; } }; /** * Returns information about the origin of a color space. * @param cs the color space * @return the origin information */ public static ColorSpaceOrigin getColorSpaceOrigin(ColorSpace cs) { if (cs instanceof ColorSpaceOrigin) { return (ColorSpaceOrigin)cs; } else { return UNKNOWN_ORIGIN; } } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/java2d/color/ColorUtil.java0100644 0000000 0000000 00000013563 13777276623 030167 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ColorUtil.java 1051421 2010-12-21 08:54:25Z jeremias $ */ package org.apache.xmlgraphics.java2d.color; import java.awt.Color; /** * Generic Color helper class. *

    * This class supports parsing string values into color values and creating * color values for strings. It provides a list of standard color names. */ public final class ColorUtil { /** * Private constructor since this is an utility class. */ private ColorUtil() { } /** * Lightens up a color for groove, ridge, inset and outset border effects. * @param col the color to lighten up * @param factor factor by which to lighten up (negative values darken the color) * @return the modified color */ public static Color lightenColor(Color col, float factor) { // TODO: This function converts the color into the sRGB namespace. // This should be avoided if possible. float[] cols = new float[4]; cols = col.getRGBComponents(cols); if (factor > 0) { cols[0] += (1.0 - cols[0]) * factor; cols[1] += (1.0 - cols[1]) * factor; cols[2] += (1.0 - cols[2]) * factor; } else { cols[0] -= cols[0] * -factor; cols[1] -= cols[1] * -factor; cols[2] -= cols[2] * -factor; } return new Color(cols[0], cols[1], cols[2], cols[3]); } /** * Indicates whether the color is a gray value. * @param col the color * @return true if it is a gray value */ public static boolean isGray(Color col) { return (col.getRed() == col.getBlue() && col.getRed() == col.getGreen()); } /** * Creates an uncalibrated CMYK color with the given gray value. * @param black the gray component (0 - 1) * @return the CMYK color */ public static Color toCMYKGrayColor(float black) { //Calculated color components float[] cmyk = new float[] {0f, 0f, 0f, 1.0f - black}; //Create native color return DeviceCMYKColorSpace.createCMYKColor(cmyk); } /** * Converts an arbitrary {@link Color} to a plain sRGB color doing the conversion at the * best possible conversion quality. * @param col the original color * @return the sRGB equivalent */ public static Color toSRGBColor(Color col) { if (col.getColorSpace().isCS_sRGB()) { return col; //Don't convert if already sRGB to avoid conversion differences } float[] comps = col.getColorComponents(null); float[] srgb = col.getColorSpace().toRGB(comps); comps = col.getComponents(null); float alpha = comps[comps.length - 1]; return new Color(srgb[0], srgb[1], srgb[2], alpha); } /** * Checks if two colors are the same color. This check is much more restrictive than * {@link Color#equals(Object)} in that it doesn't only check if both colors result in the * same sRGB value. For example, if two colors not of the same exact class are compared, * they are treated as not the same. *

    * Note: At the moment, this method only supports {@link Color} and * {@link ColorWithAlternatives} only. Other subclasses of {@link Color} are checked only using * the {@link Color#equals(Object)} method. * @param col1 the first color * @param col2 the second color * @return true if both colors are the same color */ public static boolean isSameColor(Color col1, Color col2) { //Check fallback sRGB values first, then go into details if (!col1.equals(col2)) { return false; } //Consider same-ness only between colors of the same class (not subclasses) //but consider a ColorWithAlternatives without alternatives to be the same as a Color. Class cl1 = col1.getClass(); if (col1 instanceof ColorWithAlternatives && !((ColorWithAlternatives) col1).hasAlternativeColors()) { cl1 = Color.class; } Class cl2 = col2.getClass(); if (col2 instanceof ColorWithAlternatives && !((ColorWithAlternatives) col2).hasAlternativeColors()) { cl2 = Color.class; } if (cl1 != cl2) { return false; } //Check color space if (!col1.getColorSpace().equals(col2.getColorSpace())) { return false; } //Check native components float[] comps1 = col1.getComponents(null); float[] comps2 = col2.getComponents(null); if (comps1.length != comps2.length) { return false; } for (int i = 0, c = comps1.length; i < c; i++) { if (comps1[i] != comps2[i]) { return false; } } //Compare alternative colors, order is relevant if (col1 instanceof ColorWithAlternatives && col2 instanceof ColorWithAlternatives) { ColorWithAlternatives ca1 = (ColorWithAlternatives) col1; ColorWithAlternatives ca2 = (ColorWithAlternatives) col2; return ca1.hasSameAlternativeColors(ca2); } return true; } } ././@LongLink0100644 0000000 0000000 00000000145 13777276623 011657 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/java2d/color/ColorWithAlternatives.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/java2d/color/ColorWithAlternatives.java0100644 0000000 0000000 00000020031 13777276623 032533 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ColorWithAlternatives.java 1804124 2017-08-04 14:13:54Z ssteiner $ */ package org.apache.xmlgraphics.java2d.color; import java.awt.Color; import java.awt.color.ColorSpace; import java.util.Arrays; /** * Extended {@link Color} class allowing to specify a prioritized list of alternative colors. * The alternative colors shall be the ones that are preferred if an output format supports them. * This is normally used for passing device-specific colors through to the output format. *

    * This class only adds a single reference to a color array which should not increase memory * consumption by much if no alternative colors are specified. *

    * Important: Due to a flaw in {@link Color#equals(Object)}, the equals() * method should not be used to compare two colors, especially when used to update the current * color for some output format. {@link Color} only takes the sRGB values into account but not * more the advanced facets of this class. Use {@link ColorUtil#isSameColor(Color, Color)} for * such a check. */ public class ColorWithAlternatives extends Color { private static final long serialVersionUID = -6125884937776779150L; private Color[] alternativeColors; /** * Constructor for RGBA colors. * @param r the red component * @param g the green component * @param b the blue component * @param a the alpha component * @param alternativeColors the prioritized list of alternative colors. * @see Color#Color(float, float, float, float) */ public ColorWithAlternatives(float r, float g, float b, float a, Color[] alternativeColors) { super(r, g, b, a); initAlternativeColors(alternativeColors); } /** * Constructor for RGB colors. * @param r the red component * @param g the green component * @param b the blue component * @param alternativeColors the prioritized list of alternative colors. * @see Color#Color(float, float, float) */ public ColorWithAlternatives(float r, float g, float b, Color[] alternativeColors) { super(r, g, b); initAlternativeColors(alternativeColors); } /** * Constructor for RGBA colors. * @param rgba the combined RGBA value * @param hasalpha true if the alpha bits are valid, false otherwise * @param alternativeColors the prioritized list of alternative colors. * @see Color#Color(int, boolean) */ public ColorWithAlternatives(int rgba, boolean hasalpha, Color[] alternativeColors) { super(rgba, hasalpha); initAlternativeColors(alternativeColors); } /** * Constructor for RGBA colors. * @param r the red component * @param g the green component * @param b the blue component * @param a the alpha component * @param alternativeColors the prioritized list of alternative colors. * @see Color#Color(int, int, int, int) */ public ColorWithAlternatives(int r, int g, int b, int a, Color[] alternativeColors) { super(r, g, b, a); initAlternativeColors(alternativeColors); } /** * Constructor for RGB colors. * @param r the red component * @param g the green component * @param b the blue component * @param alternativeColors the prioritized list of alternative colors. * @see Color#Color(int, int, int) */ public ColorWithAlternatives(int r, int g, int b, Color[] alternativeColors) { super(r, g, b); initAlternativeColors(alternativeColors); } /** * Constructor for RGB colors. * @param rgb the combined RGB components * @param alternativeColors the prioritized list of alternative colors. * @see Color#Color(int) */ public ColorWithAlternatives(int rgb, Color[] alternativeColors) { super(rgb); initAlternativeColors(alternativeColors); } /** * Constructor for colors with an arbitrary color space. * @param cspace the color space * @param components the color components * @param alpha the alpha component * @param alternativeColors the prioritized list of alternative colors. * @see Color#Color(ColorSpace, float[], float) */ public ColorWithAlternatives(ColorSpace cspace, float[] components, float alpha, Color[] alternativeColors) { super(cspace, components, alpha); initAlternativeColors(alternativeColors); } private void initAlternativeColors(Color[] colors) { if (colors != null) { //Colors are immutable but array are not, so copy this.alternativeColors = new Color[colors.length]; System.arraycopy(colors, 0, this.alternativeColors, 0, colors.length); } } /** * Returns the list of alternative colors. An empty array will be returned if no alternative * colors are available. * @return the list of alternative colors */ public Color[] getAlternativeColors() { if (this.alternativeColors != null) { Color[] cols = new Color[this.alternativeColors.length]; System.arraycopy(this.alternativeColors, 0, cols, 0, this.alternativeColors.length); return cols; } else { return new Color[0]; } } /** * Indicates whether alternative colors are available. * @return true if alternative colors are available. */ public boolean hasAlternativeColors() { return this.alternativeColors != null && this.alternativeColors.length > 0; } /** * Indicates whether another instance has the same alternative colors. * @param col the color to compare the alternatives to * @return true if the same alternative colors are present */ public boolean hasSameAlternativeColors(ColorWithAlternatives col) { if (!hasAlternativeColors()) { return !col.hasAlternativeColors(); } // this.hasAlternativeColors() if (!col.hasAlternativeColors()) { return false; } // this.hasAlternativeColors() && col.hasAlternativeColors() Color[] alt1 = getAlternativeColors(); Color[] alt2 = col.getAlternativeColors(); if (alt1.length != alt2.length) { return false; } for (int i = 0, c = alt1.length; i < c; i++) { Color c1 = alt1[i]; Color c2 = alt2[i]; if (!ColorUtil.isSameColor(c1, c2)) { return false; } } return true; } /** * Returns the first alternative color found with the given color space type. * @param colorSpaceType the color space type ({@link ColorSpace}.TYPE_*). * @return the requested alternative color or null, if no match was found */ public Color getFirstAlternativeOfType(int colorSpaceType) { if (hasAlternativeColors()) { for (Color alternativeColor : this.alternativeColors) { if (alternativeColor.getColorSpace().getType() == colorSpaceType) { return alternativeColor; } } } return null; } public int hashCode() { int hash = super.hashCode(); if (alternativeColors != null) { hash = 37 * hash + Arrays.hashCode(alternativeColors); } return hash; } } ././@LongLink0100644 0000000 0000000 00000000145 13777276623 011657 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/java2d/color/DefaultColorConverter.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/java2d/color/DefaultColorConverter.java0100644 0000000 0000000 00000003062 13777276623 032517 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: DefaultColorConverter.java 1345683 2012-06-03 14:50:33Z gadams $ */ package org.apache.xmlgraphics.java2d.color; import java.awt.Color; /** * A default implementation that does not apply any conversion */ public final class DefaultColorConverter implements ColorConverter { /** * private constructor to support singleton pattern */ private static final DefaultColorConverter SINGLETON = new DefaultColorConverter(); private DefaultColorConverter() { } /** * static factory * * @return singleton instance of DefaultColorConverter */ public static DefaultColorConverter getInstance() { return SINGLETON; } /** {@inheritDoc} */ public Color convert(Color color) { return color; } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/java2d/color/DeviceCMYKColorSpace.java0100644 0000000 0000000 00000007515 13777276623 032111 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: DeviceCMYKColorSpace.java 1400596 2012-10-21 08:49:02Z gadams $ */ package org.apache.xmlgraphics.java2d.color; import java.awt.Color; /** * This class represents an uncalibrated CMYK color space. */ public class DeviceCMYKColorSpace extends AbstractDeviceSpecificColorSpace implements ColorSpaceOrigin { private static final long serialVersionUID = 2925508946083542974L; /** The name for the uncalibrated CMYK pseudo-profile */ public static final String PSEUDO_PROFILE_NAME = "#CMYK"; /** * Constructs an uncalibrated CMYK ColorSpace object with * {@link java.awt.color.ColorSpace#TYPE_CMYK} and 4 components. * @see java.awt.color.ColorSpace#ColorSpace(int, int) */ public DeviceCMYKColorSpace() { super(TYPE_CMYK, 4); } /** * Returns an instance of an uncalibrated CMYK color space. * @return CMYKColorSpace the requested color space object * @deprecated Use {@link ColorSpaces#getDeviceCMYKColorSpace()} instead. */ @Deprecated public static DeviceCMYKColorSpace getInstance() { return ColorSpaces.getDeviceCMYKColorSpace(); } /** {@inheritDoc} */ @Override public float[] toRGB(float[] colorvalue) { return new float [] { (1 - colorvalue[0]) * (1 - colorvalue[3]), (1 - colorvalue[1]) * (1 - colorvalue[3]), (1 - colorvalue[2]) * (1 - colorvalue[3])}; } /** {@inheritDoc} */ @Override public float[] fromRGB(float[] rgbvalue) { assert rgbvalue.length == 3; //Note: this is an arbitrary conversion, not a color-managed one! float r = rgbvalue[0]; float g = rgbvalue[1]; float b = rgbvalue[2]; if (r == g && r == b) { return new float[] {0, 0, 0, 1 - r}; } else { float c = 1 - r; float m = 1 - g; float y = 1 - b; float k = Math.min(c, Math.min(m, y)); return new float[] {c, m, y, k}; } } /** {@inheritDoc} */ @Override public float[] toCIEXYZ(float[] colorvalue) { throw new UnsupportedOperationException("NYI"); } /** {@inheritDoc} */ @Override public float[] fromCIEXYZ(float[] colorvalue) { throw new UnsupportedOperationException("NYI"); } /** * Creates a color instance representing a device-specific CMYK color. An sRGB value * is calculated from the CMYK colors but it may not correctly represent the given CMYK * values. * @param cmykComponents the CMYK components * @return the device-specific color */ public static Color createCMYKColor(float[] cmykComponents) { DeviceCMYKColorSpace cmykCs = ColorSpaces.getDeviceCMYKColorSpace(); Color cmykColor = new ColorWithAlternatives(cmykCs, cmykComponents, 1.0f, null); return cmykColor; } /** {@inheritDoc} */ public String getProfileName() { return PSEUDO_PROFILE_NAME; } /** {@inheritDoc} */ public String getProfileURI() { return null; //No URI } } ././@LongLink0100644 0000000 0000000 00000000147 13777276623 011661 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/java2d/color/GrayScaleColorConverter.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/java2d/color/GrayScaleColorConverter.ja0100644 0000000 0000000 00000003760 13777276623 032463 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: GrayScaleColorConverter.java 1345683 2012-06-03 14:50:33Z gadams $ */ package org.apache.xmlgraphics.java2d.color; import java.awt.Color; /** * Converts to grayscale using the standard RED=30%, GREEN=59% and BLUE=11% * weights (see http://en.wikipedia.org/wiki/Grayscale) */ public final class GrayScaleColorConverter implements ColorConverter { private static final int RED_WEIGHT = 77; private static final int GREEN_WEIGTH = 150; private static final int BLUE_WEIGHT = 28; private static final GrayScaleColorConverter SINGLETON = new GrayScaleColorConverter(); private GrayScaleColorConverter() { } /** * Returns a singleton instance. * * @return singleton instance of GrayScaleColorConverter */ public static GrayScaleColorConverter getInstance() { return SINGLETON; } /** * The color is converted to CMYK with just the K component. * {@inheritDoc} */ public Color convert(Color color) { float kValue = (RED_WEIGHT * color.getRed() + GREEN_WEIGTH * color.getGreen() + BLUE_WEIGHT * color.getBlue()) / 255.0f / 255.0f; return ColorUtil.toCMYKGrayColor(kValue); } } ././@LongLink0100644 0000000 0000000 00000000147 13777276623 011661 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/java2d/color/ICCColorSpaceWithIntent.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/java2d/color/ICCColorSpaceWithIntent.ja0100644 0000000 0000000 00000011207 13777276623 032304 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ICCColorSpaceWithIntent.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.java2d.color; import java.awt.color.ColorSpace; import java.awt.color.ICC_ColorSpace; import java.awt.color.ICC_Profile; /** * This class extends the ICCColorSpace class by providing * convenience methods to convert to sRGB using various * methods, forcing a given intent, such as perceptual or * relative colorimetric. It also additionally holds the name * and source URI of the color profile. */ public class ICCColorSpaceWithIntent extends ICC_ColorSpace implements ColorSpaceOrigin { private static final long serialVersionUID = -3338065900662625221L; static final ColorSpace SRGB = ColorSpace.getInstance(ColorSpace.CS_sRGB); private RenderingIntent intent; private String profileName; private String profileURI; /** * Creates a new ICC-based color space. * @param p the color profile * @param intent the overriding rendering intent (use {@link RenderingIntent#AUTO} * to preserve the profile's) * @param profileName the color profile name * @param profileURI the source URI of the color profile */ public ICCColorSpaceWithIntent(ICC_Profile p, RenderingIntent intent, String profileName, String profileURI) { super(p); this.intent = intent; /** * Apply the requested intent into the profile */ if (intent != RenderingIntent.AUTO) { byte[] hdr = p.getData(ICC_Profile.icSigHead); hdr[ICC_Profile.icHdrRenderingIntent] = (byte)intent.getIntegerValue(); } this.profileName = profileName; this.profileURI = profileURI; } /** * Returns the sRGB value obtained by forcing the * conversion method to the intent passed to the * constructor. * @param values the color values in the local color space * @return the sRGB values */ public float[] intendedToRGB(float[] values) { switch(intent) { case ABSOLUTE_COLORIMETRIC: return absoluteColorimetricToRGB(values); case PERCEPTUAL: case AUTO: return perceptualToRGB(values); case RELATIVE_COLORIMETRIC: return relativeColorimetricToRGB(values); case SATURATION: return saturationToRGB(values); default: throw new RuntimeException("invalid intent:" + intent); } } /** * Perceptual conversion is the method implemented by the * base class's toRGB method * @param values the color values in the local color space * @return the sRGB values */ private float[] perceptualToRGB(float[] values) { return toRGB(values); } /** * Relative colorimetric needs to happen through CIEXYZ * conversion. * @param values the color values in the local color space * @return the sRGB values */ private float[] relativeColorimetricToRGB(float[] values) { float[] ciexyz = toCIEXYZ(values); return SRGB.fromCIEXYZ(ciexyz); } /** * Absolute colorimetric. NOT IMPLEMENTED. * Temporarily returns same as perceptual. * @param values the color values in the local color space * @return the sRGB values */ private float[] absoluteColorimetricToRGB(float[] values) { return perceptualToRGB(values); } /** * Saturation. NOT IMPLEMENTED. Temporarily returns same * as perceptual. * @param values the color values in the local color space * @return the sRGB values */ private float[] saturationToRGB(float[] values) { return perceptualToRGB(values); } /** {@inheritDoc} */ public String getProfileName() { return this.profileName; } /** {@inheritDoc} */ public String getProfileURI() { return this.profileURI; } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/java2d/color/NamedColorSpace.java0100644 0000000 0000000 00000016201 13777276623 031242 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: NamedColorSpace.java 1051421 2010-12-21 08:54:25Z jeremias $ */ package org.apache.xmlgraphics.java2d.color; import java.awt.Color; import java.awt.color.ColorSpace; /** * Implements a pseudo color space for a named color which is defined in the CIE XYZ color space. * At the moment, this color space always returns the fully opaque color regardless of the single * component value (tint) given to its conversion methods. */ public class NamedColorSpace extends ColorSpace implements ColorSpaceOrigin { private static final long serialVersionUID = -8957543225908514658L; private final String name; private final float[] xyz; private final String profileName; private final String profileURI; /** * Creates a new named color. * @param name the color name * @param xyz the CIE XYZ coordinates (valid values: 0.0f to 1.0f, although * values slightly larger than 1.0f are common) */ public NamedColorSpace(String name, float[] xyz) { this(name, xyz, null, null); } /** * Creates a new named color. * @param name the color name * @param xyz the CIE XYZ coordinates (valid values: 0.0f to 1.0f, although * values slightly larger than 1.0f are common) * @param profileName Optional profile name associated with this color space * @param profileURI Optional profile URI associated with this color space */ public NamedColorSpace(String name, float[] xyz, String profileName, String profileURI) { super(ColorSpace.TYPE_GRAY, 1); checkNumComponents(xyz, 3); if (name == null || name.trim().length() == 0) { throw new IllegalArgumentException("No name provided for named color space"); } this.name = name.trim(); this.xyz = new float[3]; System.arraycopy(xyz, 0, this.xyz, 0, 3); this.profileName = profileName; this.profileURI = profileURI; } /** * Creates a new named color. * @param name the color name * @param color the color to use when the named color's specific color properties are not * available. * @param profileName Optional profile name associated with this color space * @param profileURI Optional profile URI associated with this color space */ public NamedColorSpace(String name, Color color, String profileName, String profileURI) { this(name, color.getColorSpace().toCIEXYZ(color.getColorComponents(null)), profileName, profileURI); } /** * Creates a new named color. * @param name the color name * @param color the color to use when the named color's specific color properties are not * available. */ public NamedColorSpace(String name, Color color) { this(name, color.getColorSpace().toCIEXYZ(color.getColorComponents(null)), null, null); } private void checkNumComponents(float[] colorvalue, int expected) { if (colorvalue == null) { throw new NullPointerException("color value may not be null"); } if (colorvalue.length != expected) { throw new IllegalArgumentException("Expected " + expected + " components, but got " + colorvalue.length); } } /** * Returns the color name. * @return the color name */ public String getColorName() { return this.name; } /** {@inheritDoc} */ public String getProfileName() { return this.profileName; } /** {@inheritDoc} */ public String getProfileURI() { return this.profileURI; } /** * Returns the XYZ coordinates of the named color. * @return the XYZ coordinates of the named color */ public float[] getXYZ() { float[] result = new float[this.xyz.length]; System.arraycopy(this.xyz, 0, result, 0, this.xyz.length); return result; } /** * Returns an sRGB-based color representing the full-tint color defined by this named color * space. * @return the sRGB color */ public Color getRGBColor() { float[] comps = toRGB(this.xyz); return new Color(comps[0], comps[1], comps[2]); } /** {@inheritDoc} */ public float getMinValue(int component) { return getMaxValue(component); //same as min, i.e. always 1.0 } /** {@inheritDoc} */ public float getMaxValue(int component) { switch (component) { case 0: return 1f; default: throw new IllegalArgumentException("A named color space only has 1 component!"); } } /** {@inheritDoc} */ public String getName(int component) { switch (component) { case 0: return "Tint"; default: throw new IllegalArgumentException("A named color space only has 1 component!"); } } /** {@inheritDoc} */ public float[] fromCIEXYZ(float[] colorvalue) { //ignore the given color values as this is a fixed color. return new float[] {1.0f}; //Return value for full tint } /** {@inheritDoc} */ public float[] fromRGB(float[] rgbvalue) { //ignore the given color values as this is a fixed color. return new float[] {1.0f}; //Return value for full tint } /** {@inheritDoc} */ public float[] toCIEXYZ(float[] colorvalue) { float[] ret = new float[3]; System.arraycopy(this.xyz, 0, ret, 0, this.xyz.length); return ret; } /** {@inheritDoc} */ public float[] toRGB(float[] colorvalue) { ColorSpace sRGB = ColorSpace.getInstance(ColorSpace.CS_sRGB); return sRGB.fromCIEXYZ(this.xyz); } /** {@inheritDoc} */ public boolean equals(Object obj) { if (!(obj instanceof NamedColorSpace)) { return false; } NamedColorSpace other = (NamedColorSpace)obj; if (!this.name.equals(other.name)) { return false; } for (int i = 0, c = this.xyz.length; i < c; i++) { if (this.xyz[i] != other.xyz[i]) { return false; } } return true; } /** {@inheritDoc} */ public int hashCode() { return (this.profileName + name).hashCode(); } /** {@inheritDoc} */ public String toString() { return "Named Color Space: " + getColorName(); } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/java2d/color/RenderingIntent.java0100644 0000000 0000000 00000005342 13777276623 031346 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: RenderingIntent.java 1051421 2010-12-21 08:54:25Z jeremias $ */ package org.apache.xmlgraphics.java2d.color; import java.awt.color.ICC_Profile; /** * Enumeration for rendering intents. */ public enum RenderingIntent { /** Perceptual rendering intent. Typical use: scanned images. */ PERCEPTUAL(ICC_Profile.icPerceptual), /** Relative colorimetric rendering intent. Typical use: vector graphics. */ RELATIVE_COLORIMETRIC(ICC_Profile.icRelativeColorimetric), /** Absolute colorimetric rendering intent. Typical use: logos and solid colors. */ ABSOLUTE_COLORIMETRIC(ICC_Profile.icAbsoluteColorimetric), /** Saturation rendering intent. Typical use: business graphics. */ SATURATION(ICC_Profile.icSaturation), /** Automatic rendering intent. The color profile's intent isn't overridden. */ AUTO(4); private int intValue; private RenderingIntent(int value) { this.intValue = value; } /** * Returns an integer value identifying the rendering intent. This is the same value defined * by the ICC specification (0..3) plus one for "auto" (4). (See also {@link ICC_Profile}.ic*) * @return the integer value */ public int getIntegerValue() { return this.intValue; } /** * Returns the enum value for the given integer rendering intent (as defined by the ICC * specification). * @param value the rendering intent as ICC value * @return the matching enum */ public static RenderingIntent fromICCValue(int value) { switch (value) { case ICC_Profile.icPerceptual: return PERCEPTUAL; case ICC_Profile.icRelativeColorimetric: return RELATIVE_COLORIMETRIC; case ICC_Profile.icAbsoluteColorimetric: return ABSOLUTE_COLORIMETRIC; case ICC_Profile.icSaturation: return SATURATION; default: throw new IllegalArgumentException("Invalid value for rendering intent: " + value); } } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/java2d/color/package.html0100644 0000000 0000000 00000000454 13777276623 027664 0ustar000000000 0000000 Extended color infrastructure for Java2D

    Provides additional color infrastructure so SVG and XSL-FO implementations can store additional color information and do things like specialized color conversions.

    ././@LongLink0100644 0000000 0000000 00000000150 13777276623 011653 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/java2d/color/profile/ColorProfileUtil.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/java2d/color/profile/ColorProfileUtil.j0100644 0000000 0000000 00000013715 13777276623 032457 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ColorProfileUtil.java 1400525 2012-10-20 22:03:56Z lbernardo $ */ package org.apache.xmlgraphics.java2d.color.profile; import java.awt.color.ColorSpace; import java.awt.color.ICC_Profile; import java.awt.color.ICC_ProfileRGB; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.util.Arrays; // CSOFF: MethodName /** * Helper methods for handling color profiles. */ public final class ColorProfileUtil { private ColorProfileUtil() { } /** * Returns the profile description of an ICC profile * @param profile the profile * @return the description */ public static String getICCProfileDescription(ICC_Profile profile) { byte[] data = profile.getData(ICC_Profile.icSigProfileDescriptionTag); if (data == null) { return null; } else { //Info on the data format: http://www.color.org/ICC-1_1998-09.PDF int length = (data[8] << 3 * 8) | (data[9] << 2 * 8) | (data[10] << 8) | data[11]; length--; //Remove trailing NUL character try { return new String(data, 12, length, "US-ASCII"); } catch (UnsupportedEncodingException e) { throw new UnsupportedOperationException("Incompatible VM"); } } } /** * Indicates whether a given color profile is identical to the default sRGB profile * provided by the Java class library. * @param profile the color profile to check * @return true if it is the default sRGB profile */ public static boolean isDefaultsRGB(ICC_Profile profile) { if (!(profile instanceof ICC_ProfileRGB)) { return false; } // not sure what the best way to compare two profiles is, but comparing instances is not the right way ICC_Profile sRGBProfile = ICC_Profile.getInstance(ColorSpace.CS_sRGB); if (profile.getProfileClass() != sRGBProfile.getProfileClass()) { return false; } if (profile.getMajorVersion() != sRGBProfile.getMajorVersion()) { return false; } if (profile.getMinorVersion() != sRGBProfile.getMinorVersion()) { return false; } if (!Arrays.equals(profile.getData(), sRGBProfile.getData())) { return false; } return true; } /** * Proxy method for {@link ICC_Profile#getInstance(byte[])} * that properly synchronizes the call to avoid a potential race condition. * @param data the specified ICC Profile data * @return an {@link ICC_Profile} instance corresponding to the data in the * specified byte array */ public static ICC_Profile getICC_Profile(byte[] data) { synchronized (ICC_Profile.class) { return ICC_Profile.getInstance(data); } } /** * Proxy method for {@link ICC_Profile#getInstance(int)} * that properly synchronizes the call to avoid a potential race condition. * @param colorSpace the type of color space to create a profile for. The specified type is * one of the color space constants defined in the {@link ColorSpace} * class. * @return an {@link ICC_Profile} instance corresponding to the specified {@code ColorSpace} * @throws IllegalArgumentException if {@code colorSpace} is not one of the predefined types */ public static ICC_Profile getICC_Profile(int colorSpace) { synchronized (ICC_Profile.class) { return ICC_Profile.getInstance(colorSpace); } } /** * Proxy method for {@link ICC_Profile#getInstance(java.io.InputStream)} * that properly synchronizes the call to avoid a potential race condition. * @param in the input stream from which to read the profile data * @return an {@link ICC_Profile} instance corresponding to the data in the * specified {@link InputStream} * @throws IOException if an I/O error occurs while reading the stream * @throws IllegalArgumentException if the stream does not contain valid ICC Profile data */ public static ICC_Profile getICC_Profile(InputStream in) throws IOException { synchronized (ICC_Profile.class) { return ICC_Profile.getInstance(in); } } /** * Proxy method for {@link ICC_Profile#getInstance(java.lang.String)} * that properly synchronizes the call to avoid a potential race condition. * @param fileName the name of the file that contains the profile data * @return an {@link ICC_Profile} instance corresponding to the data in the specified file * @throws IOException if the file cannot be opened, or an I/O error occurs while reading * the stream * @throws IllegalArgumentException if the stream does not contain valid ICC Profile data * @throws SecurityException if a security manager is installed and it does not permit read * access to the given file. */ public static ICC_Profile getICC_Profile(String fileName) throws IOException { synchronized (ICC_Profile.class) { return ICC_Profile.getInstance(fileName); } } } ././@LongLink0100644 0000000 0000000 00000000151 13777276623 011654 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/java2d/color/profile/NamedColorProfile.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/java2d/color/profile/NamedColorProfile.0100644 0000000 0000000 00000006733 13777276623 032416 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: NamedColorProfile.java 1804124 2017-08-04 14:13:54Z ssteiner $ */ package org.apache.xmlgraphics.java2d.color.profile; import org.apache.xmlgraphics.java2d.color.NamedColorSpace; import org.apache.xmlgraphics.java2d.color.RenderingIntent; /** * Simplified in-memory representation of an ICC named color profile. */ public class NamedColorProfile { private String profileName; private String copyright; private NamedColorSpace[] namedColors; private RenderingIntent renderingIntent = RenderingIntent.PERCEPTUAL; /** * Creates a new named color profile. * @param profileName the profile name * @param copyright the copyright * @param namedColors the array of named colors * @param intent the rendering intent */ public NamedColorProfile(String profileName, String copyright, NamedColorSpace[] namedColors, RenderingIntent intent) { this.profileName = profileName; this.copyright = copyright; this.namedColors = namedColors; this.renderingIntent = intent; } /** * Returns the color profile's rendering intent. * @return the rendering intent * (See {@link java.awt.color.ICC_Profile}.ic*) */ public RenderingIntent getRenderingIntent() { return this.renderingIntent; } /** * Returns the array of named colors. * @return the array of named colors */ public NamedColorSpace[] getNamedColors() { NamedColorSpace[] copy = new NamedColorSpace[this.namedColors.length]; System.arraycopy(this.namedColors, 0, copy, 0, this.namedColors.length); return copy; } /** * Returns a named color. * @param name the color name * @return the named color (or null if it is not available) */ public NamedColorSpace getNamedColor(String name) { if (this.namedColors != null) { for (NamedColorSpace namedColor : this.namedColors) { if (namedColor.getColorName().equals(name)) { return namedColor; } } } return null; } /** * Returns the profile name. * @return the profile name */ public String getProfileName() { return this.profileName; } /** * Returns the profile copyright. * @return the profile copyright */ public String getCopyright() { return this.copyright; } /** {@inheritDoc} */ @Override public String toString() { StringBuffer sb = new StringBuffer("Named color profile: "); sb.append(getProfileName()); sb.append(", ").append(namedColors.length).append(" colors"); return sb.toString(); } } ././@LongLink0100644 0000000 0000000 00000000157 13777276623 011662 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/java2d/color/profile/NamedColorProfileParser.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/java2d/color/profile/NamedColorProfileP0100644 0000000 0000000 00000017250 13777276623 032454 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: NamedColorProfileParser.java 1681108 2015-05-22 13:26:12Z ssteiner $ */ package org.apache.xmlgraphics.java2d.color.profile; import java.awt.color.ColorSpace; import java.awt.color.ICC_Profile; import java.io.ByteArrayInputStream; import java.io.DataInput; import java.io.DataInputStream; import java.io.IOException; import org.apache.xmlgraphics.java2d.color.CIELabColorSpace; import org.apache.xmlgraphics.java2d.color.ColorSpaces; import org.apache.xmlgraphics.java2d.color.NamedColorSpace; import org.apache.xmlgraphics.java2d.color.RenderingIntent; /** * This class is a parser for ICC named color profiles. It uses Java's {@link ICC_Profile} class * for parsing the basic structure but adds functionality to parse certain profile tags. */ public class NamedColorProfileParser { private static final int MLUC = 0x6D6C7563; //'mluc' private static final int NCL2 = 0x6E636C32; //'ncl2' /** * Indicates whether the profile is a named color profile. * @param profile the color profile * @return true if the profile is a named color profile, false otherwise */ public static boolean isNamedColorProfile(ICC_Profile profile) { return profile.getProfileClass() == ICC_Profile.CLASS_NAMEDCOLOR; } /** * Parses a named color profile (NCP). * @param profile the profile to analyze * @param profileName Optional profile name associated with this color profile * @param profileURI Optional profile URI associated with this color profile * @return an object representing the parsed NCP * @throws IOException if an I/O error occurs */ public NamedColorProfile parseProfile(ICC_Profile profile, String profileName, String profileURI) throws IOException { if (!isNamedColorProfile(profile)) { throw new IllegalArgumentException("Given profile is not a named color profile (NCP)"); } String profileDescription = getProfileDescription(profile); String copyright = getCopyright(profile); RenderingIntent intent = getRenderingIntent(profile); NamedColorSpace[] ncs = readNamedColors(profile, profileName, profileURI); return new NamedColorProfile(profileDescription, copyright, ncs, intent); } /** * Parses a named color profile (NCP). * @param profile the profile to analyze * @return an object representing the parsed NCP * @throws IOException if an I/O error occurs */ public NamedColorProfile parseProfile(ICC_Profile profile) throws IOException { return parseProfile(profile, null, null); } private String getProfileDescription(ICC_Profile profile) throws IOException { byte[] tag = profile.getData(ICC_Profile.icSigProfileDescriptionTag); return readSimpleString(tag); } private String getCopyright(ICC_Profile profile) throws IOException { byte[] tag = profile.getData(ICC_Profile.icSigCopyrightTag); return readSimpleString(tag); } private RenderingIntent getRenderingIntent(ICC_Profile profile) throws IOException { byte[] hdr = profile.getData(ICC_Profile.icSigHead); int value = hdr[ICC_Profile.icHdrRenderingIntent]; return RenderingIntent.fromICCValue(value); } private NamedColorSpace[] readNamedColors(ICC_Profile profile, String profileName, String profileURI) throws IOException { byte[] tag = profile.getData(ICC_Profile.icSigNamedColor2Tag); DataInput din = new DataInputStream(new ByteArrayInputStream(tag)); int sig = din.readInt(); if (sig != NCL2) { throw new UnsupportedOperationException("Unsupported structure type: " + toSignatureString(sig) + ". Expected " + toSignatureString(NCL2)); } din.skipBytes(8); int numColors = din.readInt(); NamedColorSpace[] result = new NamedColorSpace[numColors]; int numDeviceCoord = din.readInt(); String prefix = readAscii(din, 32); String suffix = readAscii(din, 32); for (int i = 0; i < numColors; i++) { String name = prefix + readAscii(din, 32) + suffix; int[] pcs = readUInt16Array(din, 3); float[] colorvalue = new float[3]; for (int j = 0; j < pcs.length; j++) { colorvalue[j] = ((float)pcs[j]) / 0x8000; } //device coordinates are ignored for now /*int[] deviceCoord =*/ readUInt16Array(din, numDeviceCoord); switch (profile.getPCSType()) { case ColorSpace.TYPE_XYZ: result[i] = new NamedColorSpace(name, colorvalue, profileName, profileURI); break; case ColorSpace.TYPE_Lab: //Not sure if this always D50 here, //but the illuminant in the header is fixed to D50. CIELabColorSpace labCS = ColorSpaces.getCIELabColorSpaceD50(); result[i] = new NamedColorSpace(name, labCS.toColor(colorvalue, 1.0f), profileName, profileURI); break; default: throw new UnsupportedOperationException( "PCS type is not supported: " + profile.getPCSType()); } } return result; } private int[] readUInt16Array(DataInput din, int count) throws IOException { if (count == 0) { return new int[0]; } int[] result = new int[count]; for (int i = 0; i < count; i++) { int v = din.readUnsignedShort(); result[i] = v; } return result; } private String readAscii(DataInput in, int maxLength) throws IOException { byte[] data = new byte[maxLength]; in.readFully(data); String result = new String(data, "US-ASCII"); int idx = result.indexOf('\0'); if (idx >= 0) { result = result.substring(0, idx); } return result; } private String readSimpleString(byte[] tag) throws IOException { DataInput din = new DataInputStream(new ByteArrayInputStream(tag)); int sig = din.readInt(); if (sig == MLUC) { return readMLUC(din); } else { return null; //Unsupported tag structure type } } private String readMLUC(DataInput din) throws IOException { din.skipBytes(16); int firstLength = din.readInt(); int firstOffset = din.readInt(); int offset = 28; din.skipBytes(firstOffset - offset); byte[] utf16 = new byte[firstLength]; din.readFully(utf16); return new String(utf16, "UTF-16BE"); } private String toSignatureString(int sig) { StringBuffer sb = new StringBuffer(); sb.append((char)(sig >> 24 & 0xFF)); sb.append((char)(sig >> 16 & 0xFF)); sb.append((char)(sig >> 8 & 0xFF)); sb.append((char)(sig & 0xFF)); return sb.toString(); } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/java2d/color/profile/package.html0100644 0000000 0000000 00000000363 13777276623 031323 0ustar000000000 0000000 Additional color around the topic of color profiles

    Provides classes around the topic of color profiles, like support for ICC named color profiles.

    xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/java2d/package.html0100644 0000000 0000000 00000000474 13777276623 026550 0ustar000000000 0000000 Java2D utilities and extensions

    Provides convenience base and utility classes for subclassing the java.awt.Graphics2D class in order to translate Java 2D primitives into another graphic format.

    ././@LongLink0100644 0000000 0000000 00000000151 13777276623 011654 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/java2d/ps/AbstractPSDocumentGraphics2D.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/java2d/ps/AbstractPSDocumentGraphics2D.0100644 0000000 0000000 00000022740 13777276623 032266 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: AbstractPSDocumentGraphics2D.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.java2d.ps; import java.awt.Color; import java.awt.Shape; import java.awt.geom.AffineTransform; import java.io.IOException; import java.io.OutputStream; import org.apache.xmlgraphics.ps.DSCConstants; import org.apache.xmlgraphics.ps.PSGenerator; import org.apache.xmlgraphics.ps.PSProcSets; /** * This class is a wrapper for the PSGraphics2D that * is used to create a full document around the PostScript rendering from * PSGraphics2D. * * @version $Id: AbstractPSDocumentGraphics2D.java 1732018 2016-02-24 04:51:06Z gadams $ * @see org.apache.xmlgraphics.java2d.ps.PSGraphics2D * * Originally authored by Keiron Liddle. */ public abstract class AbstractPSDocumentGraphics2D extends PSGraphics2D { protected static final Integer ZERO = 0; protected int width; protected int height; protected float viewportWidth; protected float viewportHeight; protected int pagecount; protected boolean pagePending; protected Shape initialClip; protected AffineTransform initialTransform; /** * Create a new AbstractPSDocumentGraphics2D. * This is used to create a new PostScript document, the height, * width and output stream can be setup later. * For use by the transcoder which needs font information * for the bridge before the document size is known. * The resulting document is written to the stream after rendering. * * @param textAsShapes set this to true so that text will be rendered * using curves and not the font. */ AbstractPSDocumentGraphics2D(boolean textAsShapes) { super(textAsShapes); } /** * Setup the document. * @param stream the output stream to write the document * @param width the width of the page * @param height the height of the page * @throws IOException an io exception if there is a problem * writing to the output stream */ public void setupDocument(OutputStream stream, int width, int height) throws IOException { this.width = width; this.height = height; this.pagecount = 0; this.pagePending = false; //Setup for PostScript generation setPSGenerator(new PSGenerator(stream)); writeFileHeader(); } /** * Writes the file header. * @throws IOException if an I/O error occurs */ protected abstract void writeFileHeader() throws IOException; /** * Create a new AbstractPSDocumentGraphics2D. * This is used to create a new PostScript document of the given height * and width. * The resulting document is written to the stream after rendering. * * @param textAsShapes set this to true so that text will be rendered * using curves and not the font. * @param stream the stream that the final document should be written to. * @param width the width of the document * @param height the height of the document * @throws IOException an io exception if there is a problem * writing to the output stream */ public AbstractPSDocumentGraphics2D(boolean textAsShapes, OutputStream stream, int width, int height) throws IOException { this(textAsShapes); setupDocument(stream, width, height); } /** * Set the dimensions of the document that will be drawn. * This is useful if the dimensions of the document are different * from the PostScript document that is to be created. * The result is scaled so that the document fits correctly inside the * PostScript document. * @param w the width of the page * @param h the height of the page * @throws IOException in case of an I/O problem */ public void setViewportDimension(float w, float h) throws IOException { this.viewportWidth = w; this.viewportHeight = h; /* if (w != this.width || h != this.height) { gen.concatMatrix(width / w, 0, 0, height / h, 0, 0); }*/ } /** * Set the background of the PostScript document. * This is used to set the background for the PostScript document * Rather than leaving it as the default white. * @param col the background colour to fill */ public void setBackgroundColor(Color col) { /**(todo) Implement this */ /* Color c = col; PDFColor currentColour = new PDFColor(c.getRed(), c.getGreen(), c.getBlue()); currentStream.write("q\n"); currentStream.write(currentColour.getColorSpaceOut(true)); currentStream.write("0 0 " + width + " " + height + " re\n"); currentStream.write("f\n"); currentStream.write("Q\n"); */ } /** * Returns the number of pages generated so far. * @return the number of pages */ public int getPageCount() { return this.pagecount; } /** * Closes the current page and prepares to start a new one. * @throws IOException if an I/O error occurs */ public void nextPage() throws IOException { closePage(); } /** * Closes the current page. * @throws IOException if an I/O error occurs */ protected void closePage() throws IOException { if (!this.pagePending) { return; //ignore } //Finish page writePageTrailer(); this.pagePending = false; } /** * Writes the page header for a page. * @throws IOException In case an I/O error occurs */ protected abstract void writePageHeader() throws IOException; /** * Writes the page trailer for a page. * @throws IOException In case an I/O error occurs */ protected abstract void writePageTrailer() throws IOException; /** * Writes the ProcSets ending up in the prolog to the PostScript file. Override to add your * own ProcSets if so desired. * @throws IOException In case an I/O error occurs */ protected void writeProcSets() throws IOException { PSProcSets.writeStdProcSet(gen); PSProcSets.writeEPSProcSet(gen); } /** {@inheritDoc} */ public void preparePainting() { if (this.pagePending) { return; } try { startPage(); } catch (IOException ioe) { handleIOException(ioe); } } /** * Starts a new page. * @throws IOException if an I/O error occurs */ protected void startPage() throws IOException { if (this.pagePending) { throw new IllegalStateException("Close page first before starting another"); } //Start page this.pagecount++; if (this.initialTransform == null) { //Save initial transformation matrix this.initialTransform = getTransform(); this.initialClip = getClip(); } else { //Reset transformation matrix setTransform(this.initialTransform); setClip(this.initialClip); } writePageHeader(); AffineTransform at; if ((this.viewportWidth != this.width || this.viewportHeight != this.height) && (this.viewportWidth > 0) && (this.viewportHeight > 0)) { at = new AffineTransform(this.width / this.viewportWidth, 0, 0, -1 * (this.height / this.viewportHeight), 0, this.height); } else { at = new AffineTransform(1, 0, 0, -1, 0, this.height); } // Do not use concatMatrix, since it alters PSGenerator current state //gen.concatMatrix(at); gen.writeln(gen.formatMatrix(at) + " " + gen.mapCommand("concat")); gen.writeDSCComment(DSCConstants.END_PAGE_SETUP); this.pagePending = true; } /** * The rendering process has finished. * This should be called after the rendering has completed as there is * no other indication it is complete. * This will then write the results to the output stream. * @throws IOException an io exception if there is a problem * writing to the output stream */ public void finish() throws IOException { if (this.pagePending) { closePage(); } //Finish document gen.writeDSCComment(DSCConstants.TRAILER); gen.writeDSCComment(DSCConstants.PAGES, this.pagecount); gen.writeDSCComment(DSCConstants.EOF); gen.flush(); } /** * This constructor supports the create method * @param g the PostScript document graphics to make a copy of */ public AbstractPSDocumentGraphics2D(AbstractPSDocumentGraphics2D g) { super(g); } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/java2d/ps/EPSDocumentGraphics2D.java0100644 0000000 0000000 00000007462 13777276623 031555 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: EPSDocumentGraphics2D.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.java2d.ps; import java.io.IOException; import org.apache.xmlgraphics.ps.DSCConstants; /** * This class is a wrapper for the AbstractPSDocumentGraphics2D that * is used to create EPS (Encapsulated PostScript) files instead of PS file. * * @version $Id: EPSDocumentGraphics2D.java 1732018 2016-02-24 04:51:06Z gadams $ * @see org.apache.xmlgraphics.java2d.ps.PSGraphics2D * @see org.apache.xmlgraphics.java2d.ps.AbstractPSDocumentGraphics2D */ public class EPSDocumentGraphics2D extends AbstractPSDocumentGraphics2D { /** * Create a new EPSDocumentGraphics2D. * This is used to create a new EPS document, the height, * width and output stream can be setup later. * For use by the transcoder which needs font information * for the bridge before the document size is known. * The resulting document is written to the stream after rendering. * * @param textAsShapes set this to true so that text will be rendered * using curves and not the font. */ public EPSDocumentGraphics2D(boolean textAsShapes) { super(textAsShapes); } /** {@inheritDoc} */ protected void writeFileHeader() throws IOException { final Long pagewidth = (long) this.width; final Long pageheight = (long) this.height; //PostScript Header gen.writeln(DSCConstants.PS_ADOBE_30 + " " + DSCConstants.EPSF_30); gen.writeDSCComment(DSCConstants.CREATOR, new String[] {"Apache XML Graphics Commons" + ": EPS Generator for Java2D"}); gen.writeDSCComment(DSCConstants.CREATION_DATE, new Object[] {new java.util.Date()}); gen.writeDSCComment(DSCConstants.PAGES, DSCConstants.ATEND); gen.writeDSCComment(DSCConstants.BBOX, new Object[] {ZERO, ZERO, pagewidth, pageheight}); gen.writeDSCComment(DSCConstants.LANGUAGE_LEVEL, gen.getPSLevel()); gen.writeDSCComment(DSCConstants.END_COMMENTS); //Prolog gen.writeDSCComment(DSCConstants.BEGIN_PROLOG); writeProcSets(); if (customTextHandler instanceof PSTextHandler) { ((PSTextHandler)customTextHandler).writeSetup(); } gen.writeDSCComment(DSCConstants.END_PROLOG); } /** {@inheritDoc} */ protected void writePageHeader() throws IOException { Integer pageNumber = this.pagecount; gen.writeDSCComment(DSCConstants.PAGE, new Object[] {pageNumber.toString(), pageNumber}); gen.writeDSCComment(DSCConstants.PAGE_BBOX, new Object[] {ZERO, ZERO, width, height}); gen.writeDSCComment(DSCConstants.BEGIN_PAGE_SETUP); if (customTextHandler instanceof PSTextHandler) { ((PSTextHandler)customTextHandler).writePageSetup(); } } /** {@inheritDoc} */ protected void writePageTrailer() throws IOException { //nop, no DSC PageTrailer needed } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/java2d/ps/PSDocumentGraphics2D.java0100644 0000000 0000000 00000012565 13777276623 031450 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: PSDocumentGraphics2D.java 1681108 2015-05-22 13:26:12Z ssteiner $ */ package org.apache.xmlgraphics.java2d.ps; import java.io.IOException; import java.io.OutputStream; import org.apache.xmlgraphics.ps.DSCConstants; /** * This class is a wrapper for the PSGraphics2D that * is used to create a full document around the PostScript rendering from * PSGraphics2D. * * @version $Id: PSDocumentGraphics2D.java 1681108 2015-05-22 13:26:12Z ssteiner $ * @see org.apache.xmlgraphics.java2d.ps.PSGraphics2D * * Originally authored by Keiron Liddle. */ public class PSDocumentGraphics2D extends AbstractPSDocumentGraphics2D { /** * Create a new AbstractPSDocumentGraphics2D. * This is used to create a new PostScript document, the height, * width and output stream can be setup later. * For use by the transcoder which needs font information * for the bridge before the document size is known. * The resulting document is written to the stream after rendering. * * @param textAsShapes set this to true so that text will be rendered * using curves and not the font. */ public PSDocumentGraphics2D(boolean textAsShapes) { super(textAsShapes); } /** * Create a new AbstractPSDocumentGraphics2D. * This is used to create a new PostScript document of the given height * and width. * The resulting document is written to the stream after rendering. * * @param textAsShapes set this to true so that text will be rendered * using curves and not the font. * @param stream the stream that the final document should be written to. * @param width the width of the document * @param height the height of the document * @throws IOException an io exception if there is a problem * writing to the output stream */ public PSDocumentGraphics2D(boolean textAsShapes, OutputStream stream, int width, int height) throws IOException { this(textAsShapes); setupDocument(stream, width, height); } /** {@inheritDoc} */ public void nextPage() throws IOException { closePage(); } /** {@inheritDoc} */ protected void writeFileHeader() throws IOException { final Long pagewidth = (long) this.width; final Long pageheight = (long) this.height; //PostScript Header gen.writeln(DSCConstants.PS_ADOBE_30); gen.writeDSCComment(DSCConstants.CREATOR, new String[] {"Apache XML Graphics Commons" + ": PostScript Generator for Java2D"}); gen.writeDSCComment(DSCConstants.CREATION_DATE, new Object[] {new java.util.Date()}); gen.writeDSCComment(DSCConstants.PAGES, DSCConstants.ATEND); gen.writeDSCComment(DSCConstants.BBOX, new Object[] {ZERO, ZERO, pagewidth, pageheight}); gen.writeDSCComment(DSCConstants.LANGUAGE_LEVEL, gen.getPSLevel()); gen.writeDSCComment(DSCConstants.END_COMMENTS); //Defaults gen.writeDSCComment(DSCConstants.BEGIN_DEFAULTS); gen.writeDSCComment(DSCConstants.END_DEFAULTS); //Prolog gen.writeDSCComment(DSCConstants.BEGIN_PROLOG); gen.writeDSCComment(DSCConstants.END_PROLOG); //Setup gen.writeDSCComment(DSCConstants.BEGIN_SETUP); writeProcSets(); if (customTextHandler instanceof PSTextHandler) { ((PSTextHandler)customTextHandler).writeSetup(); } gen.writeDSCComment(DSCConstants.END_SETUP); } /** {@inheritDoc} */ protected void writePageHeader() throws IOException { Integer pageNumber = this.pagecount; gen.writeDSCComment(DSCConstants.PAGE, new Object[] {pageNumber.toString(), pageNumber}); gen.writeDSCComment(DSCConstants.PAGE_BBOX, new Object[] {ZERO, ZERO, width, height}); gen.writeDSCComment(DSCConstants.BEGIN_PAGE_SETUP); gen.writeln("<<"); gen.writeln("/PageSize [" + width + " " + height + "]"); gen.writeln("/ImagingBBox null"); gen.writeln(">> setpagedevice"); if (customTextHandler instanceof PSTextHandler) { ((PSTextHandler)customTextHandler).writePageSetup(); } } /** {@inheritDoc} */ protected void writePageTrailer() throws IOException { gen.showPage(); } /** * This constructor supports the create method * @param g the PostScript document graphics to make a copy of */ public PSDocumentGraphics2D(PSDocumentGraphics2D g) { super(g); } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/java2d/ps/PSGraphics2D.java0100644 0000000 0000000 00000106004 13777276623 027741 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: PSGraphics2D.java 1845492 2018-11-01 15:54:06Z ssteiner $ */ package org.apache.xmlgraphics.java2d.ps; //Java import java.awt.AlphaComposite; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Composite; import java.awt.Dimension; import java.awt.GradientPaint; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.GraphicsConfiguration; import java.awt.Image; import java.awt.Paint; import java.awt.Rectangle; import java.awt.Shape; import java.awt.Stroke; import java.awt.TexturePaint; import java.awt.geom.AffineTransform; import java.awt.geom.Area; import java.awt.geom.Line2D; import java.awt.geom.PathIterator; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; import java.awt.image.ImageObserver; import java.awt.image.RenderedImage; import java.awt.image.renderable.RenderableImage; import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.apache.xmlgraphics.java2d.AbstractGraphics2D; import org.apache.xmlgraphics.java2d.GraphicContext; import org.apache.xmlgraphics.java2d.GraphicsConfigurationWithoutTransparency; import org.apache.xmlgraphics.java2d.StrokingTextHandler; import org.apache.xmlgraphics.java2d.TextHandler; import org.apache.xmlgraphics.ps.PSGenerator; import org.apache.xmlgraphics.ps.PSImageUtils; /** * This is a concrete implementation of AbstractGraphics2D (and * therefore of Graphics2D) which is able to generate PostScript * code. * * @version $Id: PSGraphics2D.java 1845492 2018-11-01 15:54:06Z ssteiner $ * @see org.apache.xmlgraphics.java2d.AbstractGraphics2D * * Originally authored by Keiron Liddle. */ public class PSGraphics2D extends AbstractGraphics2D { private static final AffineTransform IDENTITY_TRANSFORM = new AffineTransform(); private static final boolean DEBUG = false; protected List pathHashCache = new ArrayList(); protected boolean startCache; /** * The G2D instance that represents the root instance * (used in context with create()/dispose()). Null if this instance is the root instance. */ protected PSGraphics2D rootG2D; /** the PostScript generator being created */ protected PSGenerator gen; /** Disable or enable clipping */ protected boolean clippingDisabled; /** Fallback text handler */ protected TextHandler fallbackTextHandler = new StrokingTextHandler(); /** Custom text handler */ protected TextHandler customTextHandler; /** * the current colour for use in svg */ protected Color currentColour = new Color(0, 0, 0); /** * Create a new Graphics2D that generates PostScript code. * @param textAsShapes True if text should be rendered as graphics * @see org.apache.xmlgraphics.java2d.AbstractGraphics2D#AbstractGraphics2D(boolean) */ public PSGraphics2D(boolean textAsShapes) { super(textAsShapes); } /** * Create a new Graphics2D that generates PostScript code. * @param textAsShapes True if text should be rendered as graphics * @param gen PostScript generator to use for output * @see org.apache.xmlgraphics.java2d.AbstractGraphics2D#AbstractGraphics2D(boolean) */ public PSGraphics2D(boolean textAsShapes, PSGenerator gen) { this(textAsShapes); setPSGenerator(gen); } /** * Constructor for creating copies * @param g parent PostScript Graphics2D */ public PSGraphics2D(PSGraphics2D g) { super(g); this.rootG2D = (g.rootG2D != null ? g.rootG2D : g); setPSGenerator(g.gen); this.clippingDisabled = g.clippingDisabled; //this.fallbackTextHandler is not copied //TODO The customTextHandler should probably not be passed over just like that //fallbackTextHandler, for example, has to be recreated to point to the sub-Graphics2D //to get the text positioning right. This might require changes in the TextHandler interface this.customTextHandler = g.customTextHandler; this.currentColour = g.currentColour; } /** * Sets the PostScript generator * @param gen the PostScript generator */ public void setPSGenerator(PSGenerator gen) { this.gen = gen; } /** @return the PostScript generator used by this instance. */ public PSGenerator getPSGenerator() { return this.gen; } /** * Sets the GraphicContext * @param c GraphicContext to use */ public void setGraphicContext(GraphicContext c) { gc = c; //setPrivateHints(); } /** @return the fallback TextHandler implementation */ public TextHandler getFallbackTextHandler() { return this.fallbackTextHandler; } /** @return the custom TextHandler implementation */ public TextHandler getCustomTextHandler() { return this.customTextHandler; } /** * Sets a custom TextHandler implementation that is responsible for painting text. The default * TextHandler paints all text as shapes. A custom implementation can implement text painting * using text painting operators. * @param handler the custom TextHandler implementation */ public void setCustomTextHandler(TextHandler handler) { this.customTextHandler = handler; } /* TODO Add me back at the right place!!! private void setPrivateHints() { setRenderingHint(RenderingHintsKeyExt.KEY_AVOID_TILE_PAINTING, RenderingHintsKeyExt.VALUE_AVOID_TILE_PAINTING_ON); }*/ /** * Disable clipping on each draw command. * * @param b set to true to disable all clipping. */ public void disableClipping(boolean b) { this.clippingDisabled = b; } /** * Creates a new Graphics object that is * a copy of this Graphics object. * @return a new graphics context that is a copy of * this graphics context. */ public Graphics create() { preparePainting(); return new PSGraphics2D(this); } /** * Central handler for IOExceptions for this class. * @param ioe IOException to handle */ public void handleIOException(IOException ioe) { //TODO Surely, there's a better way to do this. ioe.printStackTrace(); } /** * This method is used by AbstractPSDocumentGraphics2D to prepare a new page if * necessary. */ public void preparePainting() { //nop, used by AbstractPSDocumentGraphics2D if (rootG2D != null) { rootG2D.preparePainting(); } } /** * Draws as much of the specified image as is currently available. * The image is drawn with its top-left corner at * (xy) in this graphics context's coordinate * space. Transparent pixels in the image do not affect whatever * pixels are already there. *

    * This method returns immediately in all cases, even if the * complete image has not yet been loaded, and it has not been dithered * and converted for the current output device. *

    * If the image has not yet been completely loaded, then * drawImage returns false. As more of * the image becomes available, the process that draws the image notifies * the specified image observer. * @param img the specified image to be drawn. * @param x the x coordinate. * @param y the y coordinate. * @param observer object to be notified as more of * the image is converted. * @return True if the image has been fully drawn/loaded * @see java.awt.Image * @see java.awt.image.ImageObserver * @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int) */ public boolean drawImage(Image img, int x, int y, ImageObserver observer) { return drawImage(img, x, y, observer, null); } public boolean drawImage(Image img, int x, int y, ImageObserver observer, Color mask) { preparePainting(); if (DEBUG) { System.out.println("drawImage: " + x + ", " + y + " " + img.getClass().getName()); } final int width = img.getWidth(observer); final int height = img.getHeight(observer); if (width == -1 || height == -1) { return false; } Dimension size = new Dimension(width, height); BufferedImage buf = buildBufferedImage(size); java.awt.Graphics2D g = buf.createGraphics(); g.setComposite(AlphaComposite.SrcOver); g.setBackground(new Color(1, 1, 1, 0)); g.fillRect(0, 0, width, height); g.clip(new Rectangle(0, 0, buf.getWidth(), buf.getHeight())); if (!g.drawImage(img, 0, 0, observer)) { return false; } g.dispose(); try { AffineTransform at = getTransform(); gen.saveGraphicsState(); gen.concatMatrix(at); Shape imclip = getClip(); writeClip(imclip); PSImageUtils.renderBitmapImage(buf, x, y, width, height, gen, mask); gen.restoreGraphicsState(); } catch (IOException ioe) { handleIOException(ioe); } return true; } /** * Creates a buffered image. * @param size dimensions of the image to be created * @return the buffered image */ public BufferedImage buildBufferedImage(Dimension size) { return new BufferedImage(size.width, size.height, BufferedImage.TYPE_INT_ARGB); } /** * Draws as much of the specified image as has already been scaled * to fit inside the specified rectangle. *

    * The image is drawn inside the specified rectangle of this * graphics context's coordinate space, and is scaled if * necessary. Transparent pixels do not affect whatever pixels * are already there. *

    * This method returns immediately in all cases, even if the * entire image has not yet been scaled, dithered, and converted * for the current output device. * If the current output representation is not yet complete, then * drawImage returns false. As more of * the image becomes available, the process that draws the image notifies * the image observer by calling its imageUpdate method. *

    * A scaled version of an image will not necessarily be * available immediately just because an unscaled version of the * image has been constructed for this output device. Each size of * the image may be cached separately and generated from the original * data in a separate image production sequence. * @param img the specified image to be drawn. * @param x the x coordinate. * @param y the y coordinate. * @param width the width of the rectangle. * @param height the height of the rectangle. * @param observer object to be notified as more of * the image is converted. * @return True if the image has been fully loaded/drawn * @see java.awt.Image * @see java.awt.image.ImageObserver * @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int) */ public boolean drawImage(Image img, int x, int y, int width, int height, ImageObserver observer) { preparePainting(); System.err.println("NYI: drawImage"); return true; } /** * Disposes of this graphics context and releases * any system resources that it is using. * A Graphics object cannot be used after * disposehas been called. *

    * When a Java program runs, a large number of Graphics * objects can be created within a short time frame. * Although the finalization process of the garbage collector * also disposes of the same system resources, it is preferable * to manually free the associated resources by calling this * method rather than to rely on a finalization process which * may not run to completion for a long period of time. *

    * Graphics objects which are provided as arguments to the * paint and update methods * of components are automatically released by the system when * those methods return. For efficiency, programmers should * call dispose when finished using * a Graphics object only if it was created * directly from a component or another Graphics object. * @see java.awt.Graphics#finalize * @see java.awt.Component#paint * @see java.awt.Component#update * @see java.awt.Component#getGraphics * @see java.awt.Graphics#create */ public void dispose() { this.gen = null; this.fallbackTextHandler = null; this.customTextHandler = null; this.currentColour = null; } /** * Processes a Shape generating the necessary painting operations. * @param s Shape to process * @return the winding rule of the path defining the shape * @throws IOException In case of an I/O problem. */ public int processShape(Shape s, boolean cached) throws IOException { if (s instanceof Rectangle2D) { // Special optimization in case of Rectangle Shape Rectangle2D r = (Rectangle2D) s; gen.defineRect(r.getX(), r.getY(), r.getWidth(), r.getHeight()); return PathIterator.WIND_NON_ZERO; } else { PathIterator iter = s.getPathIterator(IDENTITY_TRANSFORM); if (cached) { processPathIteratorCached(s); } else { processPathIterator(iter); } return iter.getWindingRule(); } } protected String processPathIteratorToString(PathIterator iter) throws IOException { StringBuilder cmd = new StringBuilder(); double[] vals = new double[6]; while (!iter.isDone()) { int type = iter.currentSegment(vals); switch (type) { case PathIterator.SEG_CUBICTO: cmd.append(gen.formatDouble(vals[0])).append(" ").append(gen.formatDouble(vals[1])).append(" ") .append(gen.formatDouble(vals[2])).append(" ").append(gen.formatDouble(vals[3])).append(" ") .append(gen.formatDouble(vals[4])).append(" ").append(gen.formatDouble(vals[5])).append(" ") .append(gen.mapCommand("curveto")).append("\n"); break; case PathIterator.SEG_LINETO: cmd.append(gen.formatDouble(vals[0])).append(" ").append(gen.formatDouble(vals[1])).append(" ") .append(gen.mapCommand("lineto")).append("\n"); break; case PathIterator.SEG_MOVETO: cmd.append(gen.formatDouble(vals[0])).append(" ").append(gen.formatDouble(vals[1])).append(" ") .append(gen.mapCommand("moveto")).append("\n"); break; case PathIterator.SEG_QUADTO: cmd.append(gen.formatDouble(vals[0])).append(" ").append(gen.formatDouble(vals[1])).append(" ") .append(gen.formatDouble(vals[2])).append(" ").append(gen.formatDouble(vals[3])).append(" QT") .append("\n"); break; case PathIterator.SEG_CLOSE: cmd.append(gen.mapCommand("closepath")).append("\n"); break; default: break; } iter.next(); } return cmd.toString().trim(); } protected void processPathIteratorCached(Shape s) throws IOException { String cmd = processPathIteratorToString(s.getPathIterator(IDENTITY_TRANSFORM)); int hash = cmd.hashCode(); if (!startCache) { if (pathHashCache.contains(hash)) { startCache = true; pathHashCache.clear(); } else { gen.writeln(cmd); pathHashCache.add(hash); } } if (startCache) { if (!pathHashCache.contains(hash)) { gen.writeln("/f" + hash + "{" + cmd + "}def"); pathHashCache.add(hash); } gen.writeln("f" + hash); } } /** * Processes a path iterator generating the nexessary painting operations. * @param iter PathIterator to process * @throws IOException In case of an I/O problem. */ public void processPathIterator(PathIterator iter) throws IOException { gen.writeln(processPathIteratorToString(iter)); } /** * Strokes the outline of a Shape using the settings of the * current Graphics2D context. The rendering attributes * applied include the Clip, Transform, * Paint, Composite and * Stroke attributes. * @param s the Shape to be rendered * @see #setStroke * @see #setPaint * @see java.awt.Graphics#setColor * @see #transform * @see #setTransform * @see #clip * @see #setClip * @see #setComposite */ public void draw(Shape s) { preparePainting(); try { gen.saveGraphicsState(); AffineTransform trans = getTransform(); boolean newTransform = !trans.isIdentity(); if (newTransform) { gen.concatMatrix(trans); } Shape imclip = getClip(); if (shouldBeClipped(imclip, s)) { writeClip(imclip); } establishColor(getColor()); applyPaint(getPaint(), false); applyStroke(getStroke()); gen.writeln(gen.mapCommand("newpath")); processShape(s, false); doDrawing(false, true, false); gen.restoreGraphicsState(); } catch (IOException ioe) { handleIOException(ioe); } } /** * Determines if a shape interacts with a clipping region. * @param clip Shape defining the clipping region * @param s Shape to be drawn * @return true if code for a clipping region needs to be generated. */ public boolean shouldBeClipped(Shape clip, Shape s) { if (clip == null || s == null) { return false; } if (s instanceof Line2D) { //Line shapes don't work with intersections so always clip return true; } Area as = new Area(s); Area imclip = new Area(clip); imclip.intersect(as); return !imclip.equals(as); } /** * Establishes a clipping region * @param s Shape defining the clipping region */ public void writeClip(Shape s) { if (s == null) { return; } if (!this.clippingDisabled) { preparePainting(); try { gen.writeln(gen.mapCommand("newpath")); processShape(s, false); // clip area gen.writeln(gen.mapCommand("clip")); } catch (IOException ioe) { handleIOException(ioe); } } } /** * Applies a new Paint object. * @param paint Paint object to use * @param fill True if to be applied for filling */ protected void applyPaint(Paint paint, boolean fill) { preparePainting(); if (paint instanceof GradientPaint) { System.err.println("NYI: Gradient paint"); } else if (paint instanceof TexturePaint) { if (fill) { try { // create pattern with texture and use it for filling of a graphics object PSTilingPattern psTilingPattern = new PSTilingPattern("Pattern1", (TexturePaint)paint, 0, 0, 3, null); gen.write(psTilingPattern.toString(gen.isAcrobatDownsample())); gen.writeln("/Pattern " + gen.mapCommand("setcolorspace")); gen.writeln(psTilingPattern.getName() + " " + gen.mapCommand("setcolor")); } catch (IOException ioe) { handleIOException(ioe); } } } } /** * Applies a new Stroke object. * @param stroke Stroke object to use */ protected void applyStroke(Stroke stroke) { preparePainting(); try { applyStroke(stroke, gen); } catch (IOException ioe) { handleIOException(ioe); } } /** * Applies a new Stroke object. * @param stroke the Stroke instance * @param gen the PS generator * @throws IOException if an I/O error occurs */ public static void applyStroke(Stroke stroke, final PSGenerator gen) throws IOException { if (stroke instanceof BasicStroke) { BasicStroke basicStroke = (BasicStroke)stroke; float[] da = basicStroke.getDashArray(); if (da != null) { StringBuffer sb = new StringBuffer("["); for (int count = 0; count < da.length; count++) { sb.append(gen.formatDouble(da[count])); if (count < da.length - 1) { sb.append(" "); } } sb.append("] "); float offset = basicStroke.getDashPhase(); sb.append(gen.formatDouble(offset)); gen.useDash(sb.toString()); } else { gen.useDash(null); } int ec = basicStroke.getEndCap(); switch (ec) { case BasicStroke.CAP_BUTT: gen.useLineCap(0); break; case BasicStroke.CAP_ROUND: gen.useLineCap(1); break; case BasicStroke.CAP_SQUARE: gen.useLineCap(2); break; default: System.err.println("Unsupported line cap: " + ec); } int lj = basicStroke.getLineJoin(); switch (lj) { case BasicStroke.JOIN_MITER: gen.useLineJoin(0); float ml = basicStroke.getMiterLimit(); gen.useMiterLimit(ml >= -1 ? ml : 1); break; case BasicStroke.JOIN_ROUND: gen.useLineJoin(1); break; case BasicStroke.JOIN_BEVEL: gen.useLineJoin(2); break; default: System.err.println("Unsupported line join: " + lj); } float lw = basicStroke.getLineWidth(); gen.useLineWidth(lw); } else { System.err.println("Stroke not supported: " + stroke.toString()); } } /** * Renders a {@link RenderedImage}, * applying a transform from image * space into user space before drawing. * The transformation from user space into device space is done with * the current Transform in the Graphics2D. * The specified transformation is applied to the image before the * transform attribute in the Graphics2D context is applied. * The rendering attributes applied include the Clip, * Transform, and Composite attributes. Note * that no rendering is done if the specified transform is * noninvertible. * @param img the image to be rendered * @param xform the transformation from image space into user space * @see #transform * @see #setTransform * @see #setComposite * @see #clip * @see #setClip */ public void drawRenderedImage(RenderedImage img, AffineTransform xform) { preparePainting(); try { AffineTransform at = getTransform(); gen.saveGraphicsState(); gen.concatMatrix(at); gen.concatMatrix(xform); Shape imclip = getClip(); writeClip(imclip); PSImageUtils.renderBitmapImage(img, 0, 0, img.getWidth(), img.getHeight(), gen, null); gen.restoreGraphicsState(); } catch (IOException ioe) { handleIOException(ioe); } } /** * Renders a * {@link RenderableImage}, * applying a transform from image space into user space before drawing. * The transformation from user space into device space is done with * the current Transform in the Graphics2D. * The specified transformation is applied to the image before the * transform attribute in the Graphics2D context is applied. * The rendering attributes applied include the Clip, * Transform, and Composite attributes. Note * that no rendering is done if the specified transform is * noninvertible. *

    * Rendering hints set on the Graphics2D object might * be used in rendering the RenderableImage. * If explicit control is required over specific hints recognized by a * specific RenderableImage, or if knowledge of which hints * are used is required, then a RenderedImage should be * obtained directly from the RenderableImage * and rendered using * {@link #drawRenderedImage(RenderedImage, AffineTransform) drawRenderedImage}. * @param img the image to be rendered * @param xform the transformation from image space into user space * @see #transform * @see #setTransform * @see #setComposite * @see #clip * @see #setClip * @see #drawRenderedImage */ public void drawRenderableImage(RenderableImage img, AffineTransform xform) { preparePainting(); System.err.println("NYI: drawRenderableImage"); } /** * Establishes the given color in the PostScript interpreter. * @param c the color to set * @throws IOException In case of an I/O problem */ public void establishColor(Color c) throws IOException { gen.useColor(c); } /** * Renders the text specified by the specified String, * using the current Font and Paint attributes * in the Graphics2D context. * The baseline of the first character is at position * (xy) in the User Space. * The rendering attributes applied include the Clip, * Transform, Paint, Font and * Composite attributes. For characters in script systems * such as Hebrew and Arabic, the glyphs can be rendered from right to * left, in which case the coordinate supplied is the location of the * leftmost character on the baseline. * @param s the String to be rendered * @param x the x-coordinate where the String * should be rendered * @param y the y-coordinate where the String * should be rendered * @see #setPaint * @see java.awt.Graphics#setColor * @see java.awt.Graphics#setFont * @see #setTransform * @see #setComposite * @see #setClip */ public void drawString(String s, float x, float y) { try { if (customTextHandler != null && !textAsShapes) { customTextHandler.drawString(this, s, x, y); } else { fallbackTextHandler.drawString(this, s, x, y); } } catch (IOException ioe) { handleIOException(ioe); } } /** * Fills the interior of a Shape using the settings of the * Graphics2D context. The rendering attributes applied * include the Clip, Transform, * Paint, and Composite. * @param s the Shape to be filled * @see #setPaint * @see java.awt.Graphics#setColor * @see #transform * @see #setTransform * @see #setComposite * @see #clip * @see #setClip */ public void fill(Shape s) { if (!hasAlpha()) { preparePainting(); try { gen.saveGraphicsState(); AffineTransform trans = getTransform(); boolean newTransform = !trans.isIdentity(); if (newTransform) { gen.concatMatrix(trans); } Shape imclip = getClip(); if (shouldBeClipped(imclip, s)) { writeClip(imclip); } establishColor(getColor()); applyPaint(getPaint(), true); gen.writeln(gen.mapCommand("newpath")); int windingRule = processShape(s, true); doDrawing(true, false, windingRule == PathIterator.WIND_EVEN_ODD); gen.restoreGraphicsState(); } catch (IOException ioe) { handleIOException(ioe); } } } private boolean hasAlpha() { Composite composite = getComposite(); return composite instanceof AlphaComposite && ((AlphaComposite) composite).getAlpha() == 0f; } /** * Commits a painting operation. * @param fill filling * @param stroke stroking * @param nonzero true if the non-zero winding rule should be used when filling * @exception IOException In case of an I/O problem */ protected void doDrawing(boolean fill, boolean stroke, boolean nonzero) throws IOException { preparePainting(); if (fill) { if (stroke) { if (!nonzero) { gen.writeln(gen.mapCommand("gsave") + " " + gen.mapCommand("fill") + " " + gen.mapCommand("grestore") + " " + gen.mapCommand("stroke")); } else { gen.writeln(gen.mapCommand("gsave") + " " + gen.mapCommand("eofill") + " " + gen.mapCommand("grestore") + " " + gen.mapCommand("stroke")); } } else { if (!nonzero) { gen.writeln(gen.mapCommand("fill")); } else { gen.writeln(gen.mapCommand("eofill")); } } } else { // if(stroke) gen.writeln(gen.mapCommand("stroke")); } } /** * Returns the device configuration associated with this * Graphics2D. * @return the device configuration */ public GraphicsConfiguration getDeviceConfiguration() { return new GraphicsConfigurationWithoutTransparency(); } /** * Used to create proper font metrics */ private Graphics2D fmg; { BufferedImage bi = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB); fmg = bi.createGraphics(); } /** * Gets the font metrics for the specified font. * @return the font metrics for the specified font. * @param f the specified font * @see java.awt.Graphics#getFont * @see java.awt.FontMetrics * @see java.awt.Graphics#getFontMetrics() */ public java.awt.FontMetrics getFontMetrics(java.awt.Font f) { return fmg.getFontMetrics(f); } /** * Sets the paint mode of this graphics context to alternate between * this graphics context's current color and the new specified color. * This specifies that logical pixel operations are performed in the * XOR mode, which alternates pixels between the current color and * a specified XOR color. *

    * When drawing operations are performed, pixels which are the * current color are changed to the specified color, and vice versa. *

    * Pixels that are of colors other than those two colors are changed * in an unpredictable but reversible manner; if the same figure is * drawn twice, then all pixels are restored to their original values. * @param c1 the XOR alternation color */ public void setXORMode(Color c1) { System.err.println("NYI: setXORMode"); } /** * Copies an area of the component by a distance specified by * dx and dy. From the point specified * by x and y, this method * copies downwards and to the right. To copy an area of the * component to the left or upwards, specify a negative value for * dx or dy. * If a portion of the source rectangle lies outside the bounds * of the component, or is obscured by another window or component, * copyArea will be unable to copy the associated * pixels. The area that is omitted can be refreshed by calling * the component's paint method. * @param x the x coordinate of the source rectangle. * @param y the y coordinate of the source rectangle. * @param width the width of the source rectangle. * @param height the height of the source rectangle. * @param dx the horizontal distance to copy the pixels. * @param dy the vertical distance to copy the pixels. */ public void copyArea(int x, int y, int width, int height, int dx, int dy) { System.err.println("NYI: copyArea"); } /* --- for debugging public void transform(AffineTransform tx) { System.out.println("transform(" + toArray(tx) + ")"); super.transform(zx); } public void scale(double sx, double sy) { System.out.println("scale(" + sx + ", " + sy + ")"); super.scale(sx, sy); } public void translate(double tx, double ty) { System.out.println("translate(double " + tx + ", " + ty + ")"); super.translate(tx, ty); } public void translate(int tx, int ty) { System.out.println("translate(int " + tx + ", " + ty + ")"); super.translate(tx, ty); } */ } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/java2d/ps/PSTextHandler.java0100644 0000000 0000000 00000003201 13777276623 030230 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: PSTextHandler.java 995366 2010-09-09 10:02:17Z jeremias $ */ package org.apache.xmlgraphics.java2d.ps; import java.io.IOException; import org.apache.xmlgraphics.java2d.TextHandler; /** * Interface which the Graphics2D class delegates text painting to for Postscript. */ public interface PSTextHandler extends TextHandler { /** * Is called by when the "Setup" or "Prolog" of the PostScript document is generated. * Subclasses can do font registration, for example. * @throws IOException In case of an I/O error */ void writeSetup() throws IOException; /** * Is called by when a "PageSetup" section of the PostScript document is generated. * Subclasses can do some font initialization if necessary. * @throws IOException In case of an I/O error */ void writePageSetup() throws IOException; } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/java2d/ps/PSTilingPattern.java0100644 0000000 0000000 00000045432 13777276623 030606 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: PSTilingPattern.java 1809627 2017-09-25 13:42:08Z ssteiner $ */ package org.apache.xmlgraphics.java2d.ps; import java.awt.AlphaComposite; import java.awt.Color; import java.awt.Graphics2D; import java.awt.Rectangle; import java.awt.TexturePaint; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; import java.util.List; /** * This class is implementation of PostScript tiling pattern. It allows to make a pattern * with defined PaintProc or texture. * * Originally authored by Jiri Kunhart. */ public class PSTilingPattern { /** * A code identifying the pattern type that this dictionary describes; * must be 1 for a tiling pattern */ public static final int PATTERN_TYPE_TILING = 1; /** PostScript constant for a shading pattern (unsupported) */ public static final int PATTERN_TYPE_SHADING = 2; /** the pattern type of this pattern */ protected int patternType = PATTERN_TYPE_TILING; //TODO To be moved to a super class once shading patterns are implemented. /** * The name of the pattern (for example: "Pattern1" ) */ protected String patternName; /** * The XUID is an extended unique ID -- an array of integers that provides for * distributed, hierarchical management of the space of unique ID numbers * (optional) */ protected List xUID; /** * A PostScript procedure for painting the pattern cell */ protected StringBuffer paintProc; /** * An array of four numbers in the pattern coordinate system, giving * the coordinates of the left, bottom, right, and top edges, respectively, of the * pattern cell's bounding box */ protected Rectangle2D bBox; /** * The desired horizontal spacing between pattern cells, measured in * the pattern coordinate system */ protected double xStep; /** * The desired vertical spacing between pattern cells, measured in * the pattern coordinate system */ protected double yStep; /** * A code that determines how the color of the pattern cell is to be * specified: 1 for colored pattern, 2 for uncolored pattern */ protected int paintType = 2; /** * A code that controls adjustments to the spacing of tiles relative to * the device pixel grid: * 1 for constant spacing, * 2 for no distortion * 3 for constant spacing and faster tiling. */ protected int tilingType = 1; /** * A texture is used for filling shapes */ protected TexturePaint texture; /** * Constructor for the creation of pattern with defined PaintProc * * @param patternName the name of the pattern (for example: "Pattern1" ), if * the name is null, the pattern should be stored in PSPatternStorage, where the pattern * gets a name (the pattern without name cannot be use in PS file) * @param paintProc a postscript procedure for painting the pattern cell * @param bBox a pattern cell's bounding box * @param xStep the desired horizontal spacing between pattern cells * @param yStep the desired vertical spacing between pattern cells * @param paintType 1 for colored pattern, 2 for uncolored pattern * @param tilingType adjustments to the spacing of tiles relative to * the device pixel grid (1,2 or 3) * @param xUID an extended unique ID (optional) */ public PSTilingPattern(String patternName, StringBuffer paintProc, Rectangle bBox, double xStep, double yStep, int paintType, int tilingType, List xUID) { // check the parameters this.patternName = patternName; this.paintProc = paintProc; setBoundingBox(bBox); setXStep(xStep); setYStep(yStep); setPaintType(paintType); setTilingType(tilingType); this.xUID = xUID; } /** * Constructor for the creation of pattern with defined texture * * @param patternName the name of the pattern (for example: "Pattern1" ), if * the name is null, the pattern should be stored in PSPatternStorage, where the pattern * gets a name (a pattern without name cannot be use in PS file) * @param texture a texture is used for filling a shape * @param xStep the desired horizontal spacing between pattern cells * @param yStep yStep the desired vertical spacing between pattern cells * @param tilingType adjustments to the spacing of tiles relative to * the device pixel grid (1,2 or 3) * @param xUID xUID an extended unique ID (optional) */ public PSTilingPattern(String patternName, TexturePaint texture, double xStep, double yStep, int tilingType, List xUID) { this(patternName, null, new Rectangle(), 1, 1, 1, tilingType, xUID); this.texture = texture; Rectangle2D anchor = texture.getAnchorRect(); bBox = new Rectangle2D.Double( anchor.getX(), anchor.getY(), anchor.getX() + anchor.getWidth(), anchor.getY() + anchor.getHeight()); // xStep and yStep may be either positive or negative, but not zero => if it is zero, // we set xStep and yStep in this way that the pattern will be without spaces this.xStep = (xStep == 0) ? anchor.getWidth() : xStep; this.yStep = (yStep == 0) ? anchor.getHeight() : yStep; } /** * Gets the name of the pattern * * @return String representing the name of the pattern. */ public String getName() { return (this.patternName); } /** * Sets the name of the pattern. * @param name the name of the pattern. Can be anything without spaces (for example "Pattern1"). */ public void setName(String name) { if (name == null) { throw new NullPointerException("Parameter patternName must not be null"); } if (name.length() == 0) { throw new IllegalArgumentException("Parameter patternName must not be empty"); } if (name.indexOf(" ") >= 0) { throw new IllegalArgumentException( "Pattern name must not contain any spaces"); } this.patternName = name; } /** * Returns the bounding box. * * @return a pattern cell's bounding box */ public Rectangle2D getBoundingBox() { return (this.bBox); } /** * Sets the bounding box. * * @param bBox a pattern cell's bounding box */ public void setBoundingBox(Rectangle2D bBox) { if (bBox == null) { throw new NullPointerException("Parameter bBox must not be null"); } this.bBox = bBox; } /** * Gets the postscript procedure PaintProc * * @return the postscript procedure PaintProc */ public StringBuffer getPaintProc() { return (this.paintProc); } /** * Sets the postscript procedure PaintProc * * @param paintProc the postscript procedure PaintProc */ public void setPaintProc(StringBuffer paintProc) { this.paintProc = paintProc; } /** * Gets the horizontal spacing between pattern cells * * @return the horizontal spacing between pattern cells */ public double getXStep() { return (this.xStep); } /** * Sets the horizontal spacing between pattern cells * * @param xStep the horizontal spacing between pattern cells */ public void setXStep(double xStep) { if (xStep == 0) { throw new IllegalArgumentException("Parameter xStep must not be 0"); } this.xStep = xStep; } /** * Gets the vertical spacing between pattern cells * * @return the vertical spacing between pattern cells */ public double getYStep() { return (this.yStep); } /** * Sets the vertical spacing between pattern cells * * @param yStep the vertical spacing between pattern cells */ public void setYStep(double yStep) { if (yStep == 0) { throw new IllegalArgumentException("Parameter yStep must not be 0"); } this.yStep = yStep; } /** * Gets the code that determines how the color of the pattern cell is to be * specified: 1 for colored pattern, 2 for uncolored pattern * * @return the paint type */ public int getPaintType() { return (this.paintType); } /** * Sets the code that determines how the color of the pattern cell is to be * specified: 1 for colored pattern, 2 for uncolored pattern * * @param paintType the paint type */ public void setPaintType(int paintType) { if ((paintType != 1) && (paintType != 2)) { throw new IllegalArgumentException("Parameter paintType must not be " + paintType + " (only 1 or 2)"); } this.paintType = paintType; } /** * Gets a code that controls adjustments to the spacing of tiles relative to * the device pixel grid: 1 for constant spacing, 2 for no distortion * 3 for constant spacing and faster tiling * * @return the tiling type */ public int getTilingType() { return (this.tilingType); } /** * Sets a code that controls adjustments to the spacing of tiles relative to * the device pixel grid: 1 for constant spacing, 2 for no distortion * 3 for constant spacing and faster tiling * * @param tilingType the tiling type */ public void setTilingType(int tilingType) { if (!((tilingType <= 3) && (tilingType >= 1))) { throw new IllegalArgumentException("Parameter tilingType must not be " + tilingType + " (only 1, 2 or 3)"); } this.tilingType = tilingType; } /** * Gets a texture which is used for filling shapes * * @return the texture */ public TexturePaint getTexturePaint() { return (this.texture); } /** * Sets a texture which is used for filling shapes * * @param texturePaint the texture */ public void setTexturePaint(TexturePaint texturePaint) { this.texture = texturePaint; } /** * Gets an extended unique ID that uniquely identifies the pattern * * @return xUID the unique ID */ public List getXUID() { return (this.xUID); } /** * Sets an extended unique ID that uniquely identifies the pattern * * @param xUID the unique ID */ public void setXUID(List xUID) { this.xUID = xUID; } /** * Generates postscript code for a pattern * * @return The string which contains postscript code of pattern definition */ public String toString(boolean acrobatDownsample) { StringBuffer sb = new StringBuffer("<<\n"); sb.append("/PatternType " + this.patternType + "\n"); sb.append("/PaintType " + paintType + "\n"); sb.append("/TilingType " + tilingType + "\n"); sb.append("/XStep " + xStep + "\n"); sb.append("/YStep " + yStep + "\n"); sb.append("/BBox " + "[" + bBox.getX() + " " + bBox.getY() + " " + bBox.getWidth() + " " + bBox.getHeight() + "]" + "\n"); sb.append("/PaintProc\n" + "{\n"); // the PaintProc procedure is expected to consume its dictionary operand ! if ((paintProc == null) || (paintProc.indexOf("pop") != 0)) { sb.append("pop\n"); } if (texture != null) { int width = texture.getImage().getWidth(); int height = texture.getImage().getHeight(); Rectangle2D anchor = texture.getAnchorRect(); if (anchor.getX() != 0 || anchor.getY() != 0) { sb.append(anchor.getX() + " " + anchor.getY() + " translate\n"); } double scaleX = anchor.getWidth() / width; double scaleY = anchor.getHeight() / height; if (scaleX != 1 || scaleY != 1) { sb.append(scaleX + " " + scaleY + " scale\n"); } // define color image: width height bits/comp matrix // datasrc0 datasrcncomp-1 multi ncomp colorimage // width height bits/comp matrix int bits = 8; if (acrobatDownsample) { bits = 4; } sb.append(width).append(" ").append(height).append(" ").append(bits).append(" ").append("matrix\n"); int [] argb = new int[width * height]; // datasrc0 datasrcncomp-1 getAsRGB().getRGB(0, 0, width, height, argb, 0, width); writeImage(sb, argb, width, bits); sb.append(" false 3 colorimage"); // multi ncomp colorimage } else { sb.append(paintProc); } sb.append("\n} bind \n"); // the end of PaintProc sb.append(">>\n"); // create pattern instance from prototype sb.append("matrix\n"); sb.append("makepattern\n"); // save pattern to current dictionary sb.append("/" + patternName + " exch def\n"); return sb.toString(); } private void writeImage(StringBuffer sb, int[] argb, int width, int bits) { int count = 0; sb.append("{<"); for (int i = 0; i < argb.length; i++) { if ((i % width == 0) || (count > 249)) { sb.append('\n'); count = 0; // line should not be longer than 255 characters } if (bits == 4) { Color c = new Color(argb[i]); int v = c.getRed() / 16; String s = Integer.toHexString(v); sb.append(s); v = c.getGreen() / 16; s = Integer.toHexString(v); sb.append(s); v = c.getBlue() / 16; s = Integer.toHexString(v); sb.append(s); count += 3; } else { // delete alpha canal and write to output StringBuffer sRGB = new StringBuffer(Integer.toHexString(argb[i] & 0x00ffffff)); if (sRGB.length() != 6) { sRGB.insert(0, "000000"); // zero padding sRGB = new StringBuffer(sRGB.substring(sRGB.length() - 6)); } sb.append(sRGB); count += 6; } } sb.append("\n>}"); } private BufferedImage getAsRGB() { BufferedImage img = texture.getImage(); if (img.getType() != BufferedImage.TYPE_INT_RGB) { BufferedImage buf = new BufferedImage(img.getWidth(), img.getHeight(), BufferedImage.TYPE_INT_RGB); Graphics2D g = buf.createGraphics(); g.setComposite(AlphaComposite.SrcOver); g.setBackground(Color.white); g.fillRect(0, 0, img.getWidth(), img.getHeight()); g.drawImage(img, 0, 0, null); g.dispose(); return buf; } return img; } /** {@inheritDoc} */ public int hashCode() { return 0 ^ patternType ^ ((xUID != null) ? xUID.hashCode() : 0) ^ ((paintProc != null) ? paintProc.hashCode() : 0) ^ ((bBox != null) ? bBox.hashCode() : 0) ^ Double.valueOf(xStep).hashCode() ^ Double.valueOf(yStep).hashCode() ^ paintType ^ tilingType ^ ((texture != null) ? texture.hashCode() : 0); } /** * Compares two patterns data (except their names). * {@inheritDoc} */ public boolean equals(Object pattern) { if (pattern == null) { return false; } if (!(pattern instanceof PSTilingPattern)) { return false; } if (this == pattern) { return true; } PSTilingPattern patternObj = (PSTilingPattern) pattern; if (this.patternType != patternObj.patternType) { return false; } TexturePaint patternTexture = patternObj.getTexturePaint(); if (((patternTexture == null) && (texture != null)) || ((patternTexture != null) && (texture == null))) { return false; } if ((patternTexture != null) && (texture != null)) { // compare textures data int width = texture.getImage().getWidth(); int height = texture.getImage().getHeight(); int widthPattern = patternTexture.getImage().getWidth(); int heightPattern = patternTexture.getImage().getHeight(); if (width != widthPattern) { return false; } if (height != heightPattern) { return false; } int [] rgbData = new int[width * height]; int [] rgbDataPattern = new int[widthPattern * heightPattern]; texture.getImage().getRGB(0, 0, width, height, rgbData, 0, width); patternTexture.getImage().getRGB(0, 0, widthPattern, heightPattern, rgbDataPattern, 0, widthPattern); for (int i = 0; i < rgbData.length; i++) { if (rgbData[i] != rgbDataPattern[i]) { return false; } } } else { // compare PaintProc if (!paintProc.toString().equals(patternObj.getPaintProc().toString())) { return false; } } // compare other parameters if (xStep != patternObj.getXStep()) { return false; } if (yStep != patternObj.getYStep()) { return false; } if (paintType != patternObj.getPaintType()) { return false; } if (tilingType != patternObj.getTilingType()) { return false; } if (!bBox.equals(patternObj.getBoundingBox())) { return false; } if ((xUID != null) && (patternObj.getXUID() != null)) { if (!xUID.equals(patternObj.getXUID())) { return false; } } return true; } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/java2d/ps/package.html0100644 0000000 0000000 00000001745 13777276623 027174 0ustar000000000 0000000 org.apache.xmlgraphics.commons.java2d.ps Package

    Graphics2D implementations for generating PostScript and Encapsulated PostScript (EPS) files.

    xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/overview.html0100644 0000000 0000000 00000001057 13777276623 025652 0ustar000000000 0000000 Apache XML Graphics Commons Overview

    Apache XML Graphics Commons is a library in which the two XML Graphics subprojects (Apache Batik and Apache FOP) extracted components which are used by both codebases. The goal is to create a clean dependency hierarchy and to make components more visible which can be usable separately (i.e. without Batik and FOP).

    To more information, including general documentation, go to the Apache XML Graphics Project Website.

    xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/DSCConstants.java0100644 0000000 0000000 00000024470 13777276623 026715 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: DSCConstants.java 1345683 2012-06-03 14:50:33Z gadams $ */ package org.apache.xmlgraphics.ps; /** * This class defines constants with Strings for the DSC specification. * * @version $Id: DSCConstants.java 1345683 2012-06-03 14:50:33Z gadams $ */ public final class DSCConstants { private DSCConstants() { } // ----==== General Header Comments ====---- /** Lead-in for a DSC-conformant PostScript file */ public static final String PS_ADOBE_30 = "%!PS-Adobe-3.0"; /** Lead-in for an EPS file */ public static final String EPSF_30 = "EPSF-3.0"; /** Bounding box for the document */ public static final String BBOX = "BoundingBox"; /** High-resolution bounding box for the document */ public static final String HIRES_BBOX = "HiResBoundingBox"; /** Copyright information associated with the document or resource */ public static final String COPYRIGHT = "Copyright"; /** Creator of the document */ public static final String CREATOR = "Creator"; /** Date and time when the document was created */ public static final String CREATION_DATE = "CreationDate"; /** Type of data */ public static final String DOCUMENT_DATA = "BoundingBox"; /** Use for indicating an emulator being invoked in the document */ public static final String EMULATION = "Emulation"; /** Explicit end of comments */ public static final String END_COMMENTS = "EndComments"; /** Required PostScript Level 1 extension for this document */ public static final String EXTENSIONS = "Extensions"; /** Indicates who is this document printed for */ public static final String FOR = "For"; /** Indicates the PostScript language level used in the document */ public static final String LANGUAGE_LEVEL = "LanguageLevel"; /** Indicates the orientation of the document */ public static final String ORIENTATION = "Orientation"; /** Number of pages in the document */ public static final String PAGES = "Pages"; /** Indicates the order of the pages */ public static final String PAGE_ORDER = "PageOrder"; /** Indicates how the document should be routed back to its owner */ public static final String ROUTING = "Routing"; /** Title of the document */ public static final String TITLE = "Title"; /** Version of the document */ public static final String VERSION = "Version"; // ----==== General Body Comments ====---- /** Indicates a continued line */ public static final String NEXT_LINE = "+ "; //Skipping BeginBinary/EndBinary. They are deprecated. /** Indicates the start of a data section*/ public static final String BEGIN_DATA = "BeginData"; /** Indicates the end of a data section*/ public static final String END_DATA = "EndData"; /** Indicates the start of the defaults section */ public static final String BEGIN_DEFAULTS = "BeginDefaults"; /** Indicates the end of the defaults section */ public static final String END_DEFAULTS = "EndDefaults"; /** Indicates the start of a non-PostScript section */ public static final String BEGIN_EMULATION = "BeginEmulation"; /** Indicates the end of a non-PostScript section */ public static final String END_EMULATION = "EndEmulation"; /** Indicates the start of a preview section (EPS only)*/ public static final String BEGIN_PREVIEW = "BeginPreview"; /** Indicates the end of a preview section (EPS only)*/ public static final String END_PREVIEW = "EndPreview"; /** Indicates the start of the prolog */ public static final String BEGIN_PROLOG = "BeginProlog"; /** Indicates the end of the prolog */ public static final String END_PROLOG = "EndProlog"; /** Indicates the start of the document setup */ public static final String BEGIN_SETUP = "BeginSetup"; /** Indicates the end of the document setup */ public static final String END_SETUP = "EndSetup"; // ----==== General Page Comments ====---- /** Indicates the start of a graphic object */ public static final String BEGIN_OBJECT = "BeginObject"; /** Indicates the end of a graphic object */ public static final String END_OBJECT = "EndObject"; /** Indicates the start of the page setup section */ public static final String BEGIN_PAGE_SETUP = "BeginPageSetup"; /** Indicates the end of the page setup section */ public static final String END_PAGE_SETUP = "EndPageSetup"; /** Indicates a page number */ public static final String PAGE = "Page"; /** Bounding box for a page */ public static final String PAGE_BBOX = "PageBoundingBox"; /** High-resolution bounding box for a page */ public static final String PAGE_HIRES_BBOX = "PageHiResBoundingBox"; /** Bounding box for a page */ public static final String PAGE_ORIENTATION = "PageOrientation"; // ----==== General Trailer Comments ====---- /** Indicates the start of the page trailer */ public static final String PAGE_TRAILER = "PageTrailer"; /** Indicates the start of the document trailer */ public static final String TRAILER = "Trailer"; /** * Indicates the end of a page (NON-STANDARD!) * @deprecated Shouldn't really use that. Bad idea. "Page" and "Trailer" end a page. */ public static final String END_PAGE = "EndPage"; /** Indicates the end of the document */ public static final String EOF = "EOF"; // ----==== Requirements Conventions ====---- /** * This comment indicates all types of paper media (paper sizes, weight, color) * this document requires. */ public static final String DOCUMENT_MEDIA = "DocumentMedia"; /** This comment provides a list of resources the document needs */ public static final String DOCUMENT_NEEDED_RESOURCES = "DocumentNeededResources"; /** This comment provides a list of resources the document includes */ public static final String DOCUMENT_SUPPLIED_RESOURCES = "DocumentSuppliedResources"; //Skipping %%DocumentPrinterRequired //Skipping %%DocumentNeededFiles -> deprecated //Skipping %%DocumentSuppliedFiles -> deprecated //Skipping %%DocumentFonts -> deprecated //Skipping %%DocumentNeededFonts -> deprecated //Skipping %%DocumentSuppliedFonts -> deprecated //Skipping %%DocumentNeededProcSets -> deprecated //Skipping %%DocumentSuppliedProcSets -> deprecated //Skipping %%OperatorIntervention //Skipping %%OperatorMessage //Skipping %%ProofMode /** * This comment describes document requirements, such as duplex printing, * hole punching, collating, or other physical document processing needs. */ public static final String REQUIREMENTS = "Requirements"; //Skipping %%VMlocation //Skipping %%VMusage // ----==== Requirement Body Comments ====---- /** Indicates the start of an embedded document */ public static final String BEGIN_DOCUMENT = "BeginDocument"; /** Indicates the end of an embedded document */ public static final String END_DOCUMENT = "EndDocument"; /** Indicates a referenced embedded document */ public static final String INCLUDE_DOCUMENT = "IncludeDocument"; /** Indicates the start of a PPD feature */ public static final String BEGIN_FEATURE = "BeginFeature"; /** Indicates the end of a PPD feature */ public static final String END_FEATURE = "EndFeature"; /** Indicates a referenced a PPD feature */ public static final String INCLUDE_FEATURE = "IncludeFeature"; //Skipping BeginFile/EndFile/IncludeFile. They are deprecated. //Skipping BeginFont/EndFont/IncludeFont. They are deprecated. //Skipping BeginProcSet/EndProcSet/IncludeProcSet. They are deprecated. /** Indicates the start of a resource (font, file, procset) */ public static final String BEGIN_RESOURCE = "BeginResource"; /** Indicates the end of a resource (font, file, procset) */ public static final String END_RESOURCE = "EndResource"; /** Indicates a referenced a resource (font, file, procset) */ public static final String INCLUDE_RESOURCE = "IncludeResource"; // ----==== Requirement Page Comments ====---- //Skipping %%PageFonts -> deprecated //Skipping %%PageFiles -> deprecated /** Indicates that the paper attributes denoted by medianame are invoked on this page. */ public static final String PAGE_MEDIA = "PageMedia"; /** * This is the page-level invocation of a combination of the options listed in * the %%Requirements: comment. */ public static final String PAGE_REQUIREMENTS = "PageRequirements"; /** * This comment indicates the names and values of all resources that are needed * or supplied on the present page. */ public static final String PAGE_RESOURCES = "PageResources"; // ----==== (atend) indicator ====---- /** * Indicator for the PostScript interpreter that the value is provided * later in the document (mostly in the %%Trailer section). */ public static final Object ATEND = new AtendIndicator(); /** Used for the ATEND constant. See there. */ private static final class AtendIndicator extends Object { private AtendIndicator() { super(); } public String toString() { return "(atend)"; } } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/FormGenerator.java0100644 0000000 0000000 00000010601 13777276623 027150 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: FormGenerator.java 750418 2009-03-05 11:03:54Z vhennebert $ */ package org.apache.xmlgraphics.ps; import java.awt.geom.AffineTransform; import java.awt.geom.Dimension2D; import java.awt.geom.Rectangle2D; import java.io.IOException; /** * Abstract helper class for generating PostScript forms. */ public abstract class FormGenerator { private String formName; private String title; private Dimension2D dimensions; /** * Main constructor. * @param formName the form's name * @param title the form's title or null * @param dimensions the form's dimensions */ public FormGenerator(String formName, String title, Dimension2D dimensions) { this.formName = formName; this.title = title; this.dimensions = dimensions; } /** * Returns the form's name. * @return the form's name */ public String getFormName() { return this.formName; } /** * Returns the form's title. * @return the form's title or null if there's no title */ public String getTitle() { return this.title; } /** * returns the form's dimensions. * @return the form's dimensions */ public Dimension2D getDimensions() { return this.dimensions; } /** * Generates the PostScript code for the PaintProc of the form. * @param gen the PostScript generator * @throws IOException if an I/O error occurs */ protected abstract void generatePaintProc(PSGenerator gen) throws IOException; /** * Generates some PostScript code right after the form definition (used primarily for * bitmap data). * @param gen the PostScript generator * @throws IOException if an I/O error occurs */ protected void generateAdditionalDataStream(PSGenerator gen) throws IOException { //nop } /** * Returns the matrix for use in the form. * @return the matrix */ protected AffineTransform getMatrix() { return new AffineTransform(); } /** * Returns the form's bounding box. * @return the form's bounding box */ protected Rectangle2D getBBox() { return new Rectangle2D.Double(0, 0, dimensions.getWidth(), dimensions.getHeight()); } /** * Generates the PostScript form. * @param gen the PostScript generator * @return a PSResource instance representing the form * @throws IOException if an I/O error occurs */ public PSResource generate(PSGenerator gen) throws IOException { if (gen.getPSLevel() < 2) { throw new UnsupportedOperationException( "Forms require at least Level 2 PostScript"); } gen.writeDSCComment(DSCConstants.BEGIN_RESOURCE, new Object[] {PSResource.TYPE_FORM, getFormName()}); if (title != null) { gen.writeDSCComment(DSCConstants.TITLE, title); } gen.writeln("/" + formName); gen.writeln("<< /FormType 1"); gen.writeln(" /BBox " + gen.formatRectangleToArray(getBBox())); gen.writeln(" /Matrix " + gen.formatMatrix(getMatrix())); gen.writeln(" /PaintProc {"); gen.writeln(" pop"); gen.writeln(" gsave"); generatePaintProc(gen); gen.writeln(" grestore"); gen.writeln(" } bind"); gen.writeln(">> def"); generateAdditionalDataStream(gen); gen.writeDSCComment(DSCConstants.END_RESOURCE); PSResource res = new PSResource(PSResource.TYPE_FORM, formName); gen.getResourceTracker().registerSuppliedResource(res); return res; } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/ImageEncoder.java0100644 0000000 0000000 00000002770 13777276623 026730 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageEncoder.java 750418 2009-03-05 11:03:54Z vhennebert $ */ package org.apache.xmlgraphics.ps; import java.io.IOException; import java.io.OutputStream; /** * The interface is implemented by classes that can generate the raw bitmap field for an image * that might be further encoded/compressed by the image handler class. */ public interface ImageEncoder { /** * Writes the whole raw bitmap field to the given OutputStream. The implementation must not * close the OutputStream when it is finished! * @param out the OutputStream to write to * @throws IOException if an I/O error occurs */ void writeTo(OutputStream out) throws IOException; String getImplicitFilter(); } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/ImageEncodingHelper.java0100644 0000000 0000000 00000044515 13777276623 030242 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageEncodingHelper.java 1713619 2015-11-10 11:55:53Z ssteiner $ */ package org.apache.xmlgraphics.ps; import java.awt.color.ColorSpace; import java.awt.image.BufferedImage; import java.awt.image.ColorModel; import java.awt.image.ComponentColorModel; import java.awt.image.DataBuffer; import java.awt.image.DataBufferByte; import java.awt.image.DirectColorModel; import java.awt.image.IndexColorModel; import java.awt.image.PixelInterleavedSampleModel; import java.awt.image.Raster; import java.awt.image.RenderedImage; import java.awt.image.SampleModel; import java.io.IOException; import java.io.OutputStream; import java.util.Arrays; import org.apache.xmlgraphics.image.GraphicsUtil; /** * Helper class for encoding bitmap images. */ public class ImageEncodingHelper { private static final ColorModel DEFAULT_RGB_COLOR_MODEL = new ComponentColorModel( ColorSpace.getInstance(ColorSpace.CS_sRGB), false, false, ColorModel.OPAQUE, DataBuffer.TYPE_BYTE); private final RenderedImage image; private ColorModel encodedColorModel; private boolean firstTileDump; private boolean enableCMYK; private boolean isBGR; private boolean isKMYC; private boolean outputbw; private boolean bwinvert; /** * Main constructor * @param image the image */ public ImageEncodingHelper(RenderedImage image) { this(image, true); outputbw = true; } /** * Main constructor * @param image the image * @param enableCMYK true to enable CMYK, false to disable */ public ImageEncodingHelper(RenderedImage image, boolean enableCMYK) { this.image = image; this.enableCMYK = enableCMYK; determineEncodedColorModel(); } /** * Returns the associated image. * @return the image */ public RenderedImage getImage() { return this.image; } /** * Returns the native {@link ColorModel} used by the image. * @return the native color model */ public ColorModel getNativeColorModel() { return getImage().getColorModel(); } /** * Returns the effective {@link ColorModel} used to encode the image. If this is different * from the value returned by {@link #getNativeColorModel()} this means that the image * is converted in order to encode it because no native encoding is currently possible. * @return the effective color model */ public ColorModel getEncodedColorModel() { return this.encodedColorModel; } /** * Indicates whether the image has an alpha channel. * @return true if the image has an alpha channel */ public boolean hasAlpha() { return image.getColorModel().hasAlpha(); } /** * Indicates whether the image is converted during encodation. * @return true if the image cannot be encoded in its native format */ public boolean isConverted() { return getNativeColorModel() != getEncodedColorModel(); } private void writeRGBTo(OutputStream out) throws IOException { boolean encoded = encodeRenderedImageWithDirectColorModelAsRGB(image, out); if (encoded) { return; } encodeRenderedImageAsRGB(image, out, outputbw, bwinvert); } public static void encodeRenderedImageAsRGB(RenderedImage image, OutputStream out) throws IOException { encodeRenderedImageAsRGB(image, out, false, false); } /** * Writes a RenderedImage to an OutputStream by converting it to RGB. * @param image the image * @param out the OutputStream to write the pixels to * @throws IOException if an I/O error occurs */ public static void encodeRenderedImageAsRGB(RenderedImage image, OutputStream out, boolean outputbw, boolean bwinvert) throws IOException { Raster raster = getRaster(image); Object data; int nbands = raster.getNumBands(); int dataType = raster.getDataBuffer().getDataType(); switch (dataType) { case DataBuffer.TYPE_BYTE: data = new byte[nbands]; break; case DataBuffer.TYPE_USHORT: data = null; break; case DataBuffer.TYPE_INT: data = new int[nbands]; break; case DataBuffer.TYPE_FLOAT: data = new float[nbands]; break; case DataBuffer.TYPE_DOUBLE: data = new double[nbands]; break; default: throw new IllegalArgumentException("Unknown data buffer type: " + dataType); } ColorModel colorModel = image.getColorModel(); int w = image.getWidth(); int h = image.getHeight(); int numDataElements = 3; if (colorModel.getPixelSize() == 1 && outputbw) { numDataElements = 1; } byte[] buf = new byte[w * numDataElements]; for (int y = 0; y < h; y++) { int idx = -1; for (int x = 0; x < w; x++) { int rgb = colorModel.getRGB(raster.getDataElements(x, y, data)); if (numDataElements > 1) { buf[++idx] = (byte)(rgb >> 16); buf[++idx] = (byte)(rgb >> 8); } else if (bwinvert && rgb == -1) { rgb = 1; } buf[++idx] = (byte)(rgb); } out.write(buf); } } /** * Writes a RenderedImage to an OutputStream. This method optimizes the encoding * of the {@link DirectColorModel} as it is returned by {@link ColorModel#getRGBdefault}. * @param image the image * @param out the OutputStream to write the pixels to * @return true if this method encoded this image, false if the image is incompatible * @throws IOException if an I/O error occurs */ public static boolean encodeRenderedImageWithDirectColorModelAsRGB( RenderedImage image, OutputStream out) throws IOException { ColorModel cm = image.getColorModel(); if (cm.getColorSpace() != ColorSpace.getInstance(ColorSpace.CS_sRGB)) { return false; //Need to go through color management } if (!(cm instanceof DirectColorModel)) { return false; //Only DirectColorModel is supported here } DirectColorModel dcm = (DirectColorModel)cm; final int[] templateMasks = new int[] {0x00ff0000 /*R*/, 0x0000ff00 /*G*/, 0x000000ff /*B*/, 0xff000000 /*A*/}; int[] masks = dcm.getMasks(); if (!Arrays.equals(templateMasks, masks)) { return false; //no flexibility here right now, might never be used anyway } Raster raster = getRaster(image); int dataType = raster.getDataBuffer().getDataType(); if (dataType != DataBuffer.TYPE_INT) { return false; //not supported } int w = image.getWidth(); int h = image.getHeight(); int[] data = new int[w]; byte[] buf = new byte[w * 3]; for (int y = 0; y < h; y++) { int idx = -1; raster.getDataElements(0, y, w, 1, data); for (int x = 0; x < w; x++) { int rgb = data[x]; buf[++idx] = (byte)(rgb >> 16); buf[++idx] = (byte)(rgb >> 8); buf[++idx] = (byte)(rgb); } out.write(buf); } return true; } private static Raster getRaster(RenderedImage image) { if (image instanceof BufferedImage) { return ((BufferedImage)image).getRaster(); } else { //Note: this copies the image data (double memory consumption) //TODO Investigate encoding in stripes: RenderedImage.copyData(WritableRaster) return image.getData(); } } /** * Converts a byte array containing 24 bit RGB image data to a grayscale * image. * * @param raw * the buffer containing the RGB image data * @param width * the width of the image in pixels * @param height * the height of the image in pixels * @param bitsPerPixel * the number of bits to use per pixel * @param out the OutputStream to write the pixels to * * @throws IOException if an I/O error occurs */ public static void encodeRGBAsGrayScale( byte[] raw, int width, int height, int bitsPerPixel, OutputStream out) throws IOException { int pixelsPerByte = 8 / bitsPerPixel; int bytewidth = (width / pixelsPerByte); if ((width % pixelsPerByte) != 0) { bytewidth++; } //TODO Rewrite to encode directly from a RenderedImage to avoid buffering the whole RGB //image in memory byte[] linedata = new byte[bytewidth]; byte ib; for (int y = 0; y < height; y++) { ib = 0; int i = 3 * y * width; for (int x = 0; x < width; x++, i += 3) { // see http://www.jguru.com/faq/view.jsp?EID=221919 double greyVal = 0.212671d * (raw[i] & 0xff) + 0.715160d * (raw[i + 1] & 0xff) + 0.072169d * (raw[i + 2] & 0xff); switch (bitsPerPixel) { case 1: if (greyVal < 128) { ib |= (byte) (1 << (7 - (x % 8))); } break; case 4: greyVal /= 16; ib |= (byte) ((byte) greyVal << ((1 - (x % 2)) * 4)); break; case 8: ib = (byte) greyVal; break; default: throw new UnsupportedOperationException( "Unsupported bits per pixel: " + bitsPerPixel); } if ((x % pixelsPerByte) == (pixelsPerByte - 1) || ((x + 1) == width)) { linedata[(x / pixelsPerByte)] = ib; ib = 0; } } out.write(linedata); } } private boolean optimizedWriteTo(OutputStream out) throws IOException { if (this.firstTileDump) { Raster raster = image.getTile(0, 0); DataBuffer buffer = raster.getDataBuffer(); if (buffer instanceof DataBufferByte) { byte[] bytes = ((DataBufferByte) buffer).getData(); // see determineEncodingColorModel() to see why we permute B and R here if (isBGR) { byte[] bytesPermutated = new byte[bytes.length]; for (int i = 0; i < bytes.length; i += 3) { bytesPermutated[i] = bytes[i + 2]; bytesPermutated[i + 1] = bytes[i + 1]; bytesPermutated[i + 2] = bytes[i]; } out.write(bytesPermutated); } else if (isKMYC) { byte[] bytesPermutated = new byte[bytes.length]; for (int i = 0; i < bytes.length; i += 4) { bytesPermutated[i] = bytes[i + 3]; bytesPermutated[i + 1] = bytes[i + 2]; bytesPermutated[i + 2] = bytes[i + 1]; bytesPermutated[i + 3] = bytes[i]; } out.write(bytesPermutated); } else { out.write(bytes); } return true; } } return false; } /** * Indicates whether the image consists of multiple tiles. * @return true if there are multiple tiles */ protected boolean isMultiTile() { int tilesX = image.getNumXTiles(); int tilesY = image.getNumYTiles(); return (tilesX != 1 || tilesY != 1); } /** * Determines the color model used for encoding the image. */ protected void determineEncodedColorModel() { this.firstTileDump = false; this.encodedColorModel = DEFAULT_RGB_COLOR_MODEL; ColorModel cm = image.getColorModel(); ColorSpace cs = cm.getColorSpace(); int numComponents = cm.getNumComponents(); if (!isMultiTile()) { if (numComponents == 1 && cs.getType() == ColorSpace.TYPE_GRAY) { if (cm.getTransferType() == DataBuffer.TYPE_BYTE) { this.firstTileDump = true; this.encodedColorModel = cm; } } else if (cm instanceof IndexColorModel) { if (cm.getTransferType() == DataBuffer.TYPE_BYTE) { this.firstTileDump = true; this.encodedColorModel = cm; } } else if (cm instanceof ComponentColorModel && (numComponents == 3 || (enableCMYK && numComponents == 4)) && !cm.hasAlpha()) { Raster raster = image.getTile(0, 0); DataBuffer buffer = raster.getDataBuffer(); SampleModel sampleModel = raster.getSampleModel(); if (sampleModel instanceof PixelInterleavedSampleModel) { PixelInterleavedSampleModel piSampleModel; piSampleModel = (PixelInterleavedSampleModel)sampleModel; int[] offsets = piSampleModel.getBandOffsets(); for (int i = 0; i < offsets.length; i++) { if (offsets[i] != i && offsets[i] != offsets.length - 1 - i) { //Don't encode directly as samples are not next to each other //i.e. offsets are not 012 (RGB) or 0123 (CMYK) // let also pass 210 BGR and 3210 (KYMC); 3210 will be skipped below // if 210 (BGR) the B and R bytes will be permuted later in optimizeWriteTo() return; } } // check if we are in a BGR case; this is added here as a workaround for bug fix // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6549882 that causes some PNG // images to be loaded as BGR with the consequence that performance was being impacted this.isBGR = false; if (offsets.length == 3 && offsets[0] == 2 && offsets[1] == 1 && offsets[2] == 0) { this.isBGR = true; } // make sure we did not get here due to a KMYC image if (offsets.length == 4 && offsets[0] == 3 && offsets[1] == 2 && offsets[2] == 1 && offsets[3] == 0) { isKMYC = true; } } if (cm.getTransferType() == DataBuffer.TYPE_BYTE && buffer.getOffset() == 0 && buffer.getNumBanks() == 1) { this.firstTileDump = true; this.encodedColorModel = cm; } } } } /** * Encodes the image and writes everything to the given OutputStream. * @param out the OutputStream * @throws IOException if an I/O error occurs */ public void encode(OutputStream out) throws IOException { if (!isConverted()) { if (optimizedWriteTo(out)) { return; } } writeRGBTo(out); } /** * Encodes the image's alpha channel. If it doesn't have an alpha channel, an * {@link IllegalStateException} is thrown. * @param out the OutputStream * @throws IOException if an I/O error occurs */ public void encodeAlpha(OutputStream out) throws IOException { if (!hasAlpha()) { throw new IllegalStateException("Image doesn't have an alpha channel"); } Raster alpha = GraphicsUtil.getAlphaRaster(image); DataBuffer buffer = alpha.getDataBuffer(); if (buffer instanceof DataBufferByte) { out.write(((DataBufferByte)buffer).getData()); } else { throw new UnsupportedOperationException( "Alpha raster not supported: " + buffer.getClass().getName()); } } /** * Writes all pixels (color components only) of a RenderedImage to an OutputStream. * @param image the image to be encoded * @param out the OutputStream to write to * @throws IOException if an I/O error occurs */ public static void encodePackedColorComponents(RenderedImage image, OutputStream out) throws IOException { ImageEncodingHelper helper = new ImageEncodingHelper(image); helper.encode(out); } /** * Create an ImageEncoder for the given RenderImage instance. * @param img the image * @return the requested ImageEncoder */ public static ImageEncoder createRenderedImageEncoder(RenderedImage img) { return new RenderedImageEncoder(img); } /** * ImageEncoder implementation for RenderedImage instances. */ private static class RenderedImageEncoder implements ImageEncoder { private final RenderedImage img; public RenderedImageEncoder(RenderedImage img) { this.img = img; } public void writeTo(OutputStream out) throws IOException { ImageEncodingHelper.encodePackedColorComponents(img, out); } public String getImplicitFilter() { return null; //No implicit filters with RenderedImage instances } } public void setBWInvert(boolean v) { bwinvert = v; } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/ImageFormGenerator.java0100644 0000000 0000000 00000014756 13777276623 030132 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageFormGenerator.java 1881060 2020-08-21 15:38:04Z ssteiner $ */ package org.apache.xmlgraphics.ps; import java.awt.Dimension; import java.awt.color.ColorSpace; import java.awt.geom.AffineTransform; import java.awt.geom.Dimension2D; import java.awt.image.RenderedImage; import java.io.IOException; /** * Abstract helper class for generating PostScript forms. */ public class ImageFormGenerator extends FormGenerator { //Mode 1 (RenderedImage) private RenderedImage image; //Mode 2 (ImageEncoder) private ImageEncoder encoder; private ColorSpace colorSpace; private int bitsPerComponent = 8; private boolean invertImage; private Dimension pixelDimensions; /** * Main constructor. * @param formName the form's name * @param title the form's title or null * @param dimensions the form's dimensions in units (usually points) * @param image the image * @param invertImage true if the image shall be inverted */ public ImageFormGenerator(String formName, String title, Dimension2D dimensions, RenderedImage image, boolean invertImage) { super(formName, title, dimensions); this.image = image; this.encoder = ImageEncodingHelper.createRenderedImageEncoder(image); this.invertImage = invertImage; this.pixelDimensions = new Dimension(image.getWidth(), image.getHeight()); } /** * Main constructor. * @param formName the form's name * @param title the form's title or null * @param dimensions the form's dimensions in units (usually points) * @param dimensionsPx the form's dimensions in pixels * @param encoder the image encoder * @param colorSpace the target color space * @param bitsPerComponent the bits per component * @param invertImage true if the image shall be inverted */ public ImageFormGenerator(String formName, String title, Dimension2D dimensions, Dimension dimensionsPx, ImageEncoder encoder, ColorSpace colorSpace, int bitsPerComponent, boolean invertImage) { super(formName, title, dimensions); this.pixelDimensions = dimensionsPx; this.encoder = encoder; this.colorSpace = colorSpace; this.bitsPerComponent = bitsPerComponent; this.invertImage = invertImage; } /** * Main constructor. * @param formName the form's name * @param title the form's title or null * @param dimensions the form's dimensions in units (usually points) * @param dimensionsPx the form's dimensions in pixels * @param encoder the image encoder * @param colorSpace the target color space * @param invertImage true if the image shall be inverted */ public ImageFormGenerator(String formName, String title, Dimension2D dimensions, Dimension dimensionsPx, ImageEncoder encoder, ColorSpace colorSpace, boolean invertImage) { this(formName, title, dimensions, dimensionsPx, encoder, colorSpace, 8, invertImage); } /** * Returns the name of the data segment associated with this image form. * @return the data segment name */ protected String getDataName() { return getFormName() + ":Data"; } private String getAdditionalFilters(PSGenerator gen) { String implicitFilter = encoder.getImplicitFilter(); if (implicitFilter != null) { return "/ASCII85Decode filter " + implicitFilter + " filter"; } else { if (gen.getPSLevel() >= 3) { return "/ASCII85Decode filter"; } else { return "/ASCII85Decode filter /RunLengthDecode filter"; } } } /** {@inheritDoc} */ protected void generatePaintProc(PSGenerator gen) throws IOException { if (gen.getPSLevel() == 2) { gen.writeln(" userdict /i 0 put"); //rewind image data } else { gen.writeln(" " + getDataName() + " 0 setfileposition"); //rewind image data } String dataSource; if (gen.getPSLevel() == 2) { dataSource = "{ " + getDataName() + " i get /i i 1 add store } bind"; } else { dataSource = getDataName(); if (gen.getPSLevel() >= 3) { String implicitFilter = encoder.getImplicitFilter(); if (implicitFilter == null) { dataSource += " /FlateDecode filter"; } } } AffineTransform at = new AffineTransform(); at.scale(getDimensions().getWidth(), getDimensions().getHeight()); gen.concatMatrix(at); PSDictionary imageDict = new PSDictionary(); imageDict.put("/DataSource", dataSource); if (this.image != null) { PSImageUtils.writeImageCommand(this.image, imageDict, gen); } else { imageDict.put("/BitsPerComponent", Integer.toString(this.bitsPerComponent)); PSImageUtils.writeImageCommand(imageDict, this.pixelDimensions, this.colorSpace, this.invertImage, gen); } } /** {@inheritDoc} */ protected void generateAdditionalDataStream(PSGenerator gen) throws IOException { gen.writeln("/" + getDataName() + " currentfile"); gen.writeln(getAdditionalFilters(gen)); if (gen.getPSLevel() == 2) { //Creates a data array from the inline file gen.writeln("{ /temp exch def [" + " { temp 16384 string readstring not {exit } if } loop ] } exec"); } else { gen.writeln("/ReusableStreamDecode filter"); } PSImageUtils.compressAndWriteBitmap(encoder, gen); gen.writeln("def"); } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/PSCommandMap.java0100644 0000000 0000000 00000002626 13777276623 026665 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: PSCommandMap.java 924840 2010-03-18 14:52:36Z jeremias $ */ package org.apache.xmlgraphics.ps; /** * Interface to map standard PostScript commands to other commands or macros, for example * shorthands for compact PostScript code. */ public interface PSCommandMap { /** * Maps a standard PostScript command (like "setlinejoin" or "setrgbcolor") to a macro. If * no mapping is available, the command itself is returned again. * @param command the command * @return the mapped command (or the "command" parameter if no mapping is available) */ String mapCommand(String command); } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/PSDictionary.java0100644 0000000 0000000 00000026330 13777276623 026754 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: PSDictionary.java 1804124 2017-08-04 14:13:54Z ssteiner $ */ package org.apache.xmlgraphics.ps; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.StringTokenizer; // CSOFF: InnerAssignment /** * This class is used to encapsulate postscript dictionary objects. */ public class PSDictionary extends java.util.HashMap { private static final long serialVersionUID = 815367222496219197L; /** * This class is used to parse dictionary strings. */ private static class Maker { /** * Simple token holding class */ private static class Token { /** * start index in string */ private int startIndex = -1; /** * end index in string */ private int endIndex = -1; /** * token string value */ private String value; } private static final String[][] BRACES = { {"<<", ">>"}, {"[", "]"}, {"{", "}"}, {"(", ")"} }; private static final int OPENING = 0; private static final int CLOSING = 1; private static final int DICTIONARY = 0; private static final int ARRAY = 1; private static final int PROCEDURE = 2; private static final int STRING = 3; /** * Returns a Token containing the start, end index and value of the next token * found in a given string * * @param str * string to search * @param fromIndex * search from index * @return Token containing the start, end index and value of the next token */ protected Token nextToken(String str, int fromIndex) { Token t = null; for (int i = fromIndex; i < str.length(); i++) { boolean isWhitespace = Character.isWhitespace(str.charAt(i)); // start index found if (t == null && !isWhitespace) { t = new Token(); t.startIndex = i; // end index found } else if (t != null && isWhitespace) { t.endIndex = i; break; } } // start index found if (t != null) { // end index not found so take end of string if (t.endIndex == -1) { t.endIndex = str.length(); } t.value = str.substring(t.startIndex, t.endIndex); } return t; } /** * Returns the closing brace index from a given string searches from a * given index * * @param str * string to search * @param braces * string array of opening and closing brace * @param fromIndex * searches from index * @return matching brace index * @throws org.apache.xmlgraphics.ps.PSDictionaryFormatException * thrown in the event that a parsing error occurred */ private int indexOfMatchingBrace(String str, String[] braces, int fromIndex) throws PSDictionaryFormatException { final int len = str.length(); if (braces.length != 2) { throw new PSDictionaryFormatException("Wrong number of braces"); } for (int openCnt = 0, closeCnt = 0; fromIndex < len; fromIndex++) { if (str.startsWith(braces[OPENING], fromIndex)) { openCnt++; } else if (str.startsWith(braces[CLOSING], fromIndex)) { closeCnt++; if (openCnt > 0 && openCnt == closeCnt) { return fromIndex; // found } } } return -1; // not found } /** * Strips braces from complex object string * * @param str * String to parse * @param braces * String array containing opening and closing braces * @return String with braces stripped * @throws org.apache.xmlgraphics.ps.PSDictionaryFormatException * thrown in the event that a parsing error occurred */ private String stripBraces(String str, String[] braces) throws PSDictionaryFormatException { // find first opening brace int firstIndex = str.indexOf(braces[OPENING]); if (firstIndex == -1) { throw new PSDictionaryFormatException( "Failed to find opening parameter '" + braces[OPENING] + ""); } // find last matching brace int lastIndex = indexOfMatchingBrace(str, braces, firstIndex); if (lastIndex == -1) { throw new PSDictionaryFormatException( "Failed to find matching closing parameter '" + braces[CLOSING] + "'"); } // strip brace and trim int braceLen = braces[OPENING].length(); str = str.substring(firstIndex + braceLen, lastIndex).trim(); return str; } /** * Parses a dictionary string and provides a dictionary object * * @param str a dictionary string * @return A postscript dictionary object * @throws org.apache.xmlgraphics.ps.PSDictionaryFormatException * thrown in the event that a parsing error occurred */ public PSDictionary parseDictionary(String str) throws PSDictionaryFormatException { PSDictionary dictionary = new PSDictionary(); str = stripBraces(str.trim(), BRACES[DICTIONARY]); // length of dictionary string final int len = str.length(); Token keyToken; for (int currIndex = 0; (keyToken = nextToken(str, currIndex)) != null && currIndex <= len;) { if (keyToken.value == null) { throw new PSDictionaryFormatException("Failed to parse object key"); } Token valueToken = nextToken(str, keyToken.endIndex + 1); String[] braces = null; for (String[] brace : BRACES) { if (valueToken.value.startsWith(brace[OPENING])) { braces = brace; break; } } Object obj = null; if (braces != null) { // find closing brace valueToken.endIndex = indexOfMatchingBrace(str, braces, valueToken.startIndex) + braces[OPENING].length(); if (valueToken.endIndex < 0) { throw new PSDictionaryFormatException("Closing value brace '" + braces[CLOSING] + "' not found for key '" + keyToken.value + "'"); } valueToken.value = str.substring(valueToken.startIndex, valueToken.endIndex); } if (braces == null || braces == BRACES[PROCEDURE] || braces == BRACES[STRING]) { obj = valueToken.value; } else if (BRACES[ARRAY] == braces) { List objList = new java.util.ArrayList(); String objString = stripBraces(valueToken.value, braces); StringTokenizer tokenizer = new StringTokenizer(objString, ","); while (tokenizer.hasMoreTokens()) { objList.add(tokenizer.nextToken()); } obj = objList; } else if (BRACES[DICTIONARY] == braces) { obj = parseDictionary(valueToken.value); } dictionary.put(keyToken.value, obj); currIndex = valueToken.endIndex + 1; } return dictionary; } } /** * Parses a given a dictionary string and returns an object * * @param str dictionary string * @return dictionary object * @throws org.apache.xmlgraphics.ps.PSDictionaryFormatException * thrown in the event that a parsing error occurred */ public static PSDictionary valueOf(String str) throws PSDictionaryFormatException { return (new Maker()).parseDictionary(str); } /** * @param obj object to test equality against * @return whether a given object is equal to this dictionary object * @see java.lang.Object#equals(Object) */ public boolean equals(Object obj) { if (!(obj instanceof PSDictionary)) { return false; } PSDictionary dictionaryObj = (PSDictionary) obj; if (dictionaryObj.size() != size()) { return false; } for (Object e : entrySet()) { Map.Entry entry = (Map.Entry) e; String key = (String) entry.getKey(); if (!dictionaryObj.containsKey(key)) { return false; } if (!dictionaryObj.get(key).equals(entry.getValue())) { return false; } } return true; } /** {@inheritDoc} */ public int hashCode() { int hashCode = 7; for (Object value : values()) { hashCode += value.hashCode(); } return hashCode; } /** {@inheritDoc} */ public String toString() { if (isEmpty()) { return ""; } StringBuffer sb = new StringBuffer("<<\n"); for (Object o : super.keySet()) { String key = (String) o; sb.append(" " + key + " "); Object obj = super.get(key); if (obj instanceof ArrayList) { List array = (List) obj; StringBuilder str = new StringBuilder("["); for (Object element : array) { str.append(element + " "); } String str2 = str.toString().trim(); str2 += "]"; sb.append(str2 + "\n"); } else { sb.append(obj.toString() + "\n"); } } sb.append(">>"); return sb.toString(); } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/PSDictionaryFormatException.java0100644 0000000 0000000 00000002503 13777276623 032000 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: PSDictionaryFormatException.java 750418 2009-03-05 11:03:54Z vhennebert $ */ package org.apache.xmlgraphics.ps; /** * Thrown to indicate that a formatting error has occurred when * trying to parse a PostScript dictionary object */ public class PSDictionaryFormatException extends Exception { private static final long serialVersionUID = 6492321557297860931L; /** * Default constructor * @param string error message */ public PSDictionaryFormatException(String string) { super(string); } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/PSFontUtils.java0100644 0000000 0000000 00000016034 13777276623 026576 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: PSFontUtils.java 1345759 2012-06-03 20:09:09Z gadams $ */ package org.apache.xmlgraphics.ps; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import org.apache.commons.io.EndianUtils; import org.apache.commons.io.IOUtils; import org.apache.xmlgraphics.fonts.Glyphs; import org.apache.xmlgraphics.util.io.ASCIIHexOutputStream; import org.apache.xmlgraphics.util.io.SubInputStream; // CSOFF: HideUtilityClassConstructor /** * Utility code for font handling in PostScript. */ public class PSFontUtils { public PSFontUtils() { } /** * This method reads a Type 1 font from a stream and embeds it into a PostScript stream. * Note: Only the IBM PC Format as described in section 3.3 of the Adobe Technical Note #5040 * is supported. * @param gen The PostScript generator * @param in the InputStream from which to read the Type 1 font * @throws IOException in case an I/O problem occurs */ public static void embedType1Font(PSGenerator gen, InputStream in) throws IOException { boolean finished = false; while (!finished) { int segIndicator = in.read(); if (segIndicator < 0) { throw new IOException("Unexpected end-of-file while reading segment indicator"); } else if (segIndicator != 128) { throw new IOException("Expected ASCII 128, found: " + segIndicator); } int segType = in.read(); if (segType < 0) { throw new IOException("Unexpected end-of-file while reading segment type"); } int dataSegLen = 0; switch (segType) { case 1: //ASCII dataSegLen = EndianUtils.readSwappedInteger(in); BufferedReader reader = new BufferedReader( new java.io.InputStreamReader( new SubInputStream(in, dataSegLen), "US-ASCII")); String line; while ((line = reader.readLine()) != null) { gen.writeln(line); } break; case 2: //binary dataSegLen = EndianUtils.readSwappedInteger(in); SubInputStream sin = new SubInputStream(in, dataSegLen); ASCIIHexOutputStream hexOut = new ASCIIHexOutputStream(gen.getOutputStream()); IOUtils.copy(sin, hexOut); gen.newLine(); break; case 3: //EOF finished = true; break; default: throw new IOException("Unsupported segment type: " + segType); } } } /** the PSResource representing the WinAnsiEncoding. */ public static final PSResource WINANSI_ENCODING_RESOURCE = new PSResource(PSResource.TYPE_ENCODING, "WinAnsiEncoding"); /** * Defines the WinAnsi encoding for use in PostScript files. * @param gen the PostScript generator * @throws IOException In case of an I/O problem */ public static void defineWinAnsiEncoding(PSGenerator gen) throws IOException { gen.writeDSCComment(DSCConstants.BEGIN_RESOURCE, WINANSI_ENCODING_RESOURCE); gen.writeln("/WinAnsiEncoding ["); for (int i = 0; i < Glyphs.WINANSI_ENCODING.length; i++) { if (i > 0) { if ((i % 5) == 0) { gen.newLine(); } else { gen.write(" "); } } final char ch = Glyphs.WINANSI_ENCODING[i]; final String glyphname = Glyphs.charToGlyphName(ch); if ("".equals(glyphname)) { gen.write("/" + Glyphs.NOTDEF); } else { gen.write("/"); gen.write(glyphname); } } gen.newLine(); gen.writeln("] def"); gen.writeDSCComment(DSCConstants.END_RESOURCE); gen.getResourceTracker().registerSuppliedResource(WINANSI_ENCODING_RESOURCE); } /** the PSResource representing the AdobeStandardCyrillicEncoding. */ public static final PSResource ADOBECYRILLIC_ENCODING_RESOURCE = new PSResource(PSResource.TYPE_ENCODING, "AdobeStandardCyrillicEncoding"); /** * Defines the AdobeStandardCyrillic encoding for use in PostScript files. * @param gen the PostScript generator * @throws IOException In case of an I/O problem */ public static void defineAdobeCyrillicEncoding(PSGenerator gen) throws IOException { gen.writeDSCComment(DSCConstants.BEGIN_RESOURCE, ADOBECYRILLIC_ENCODING_RESOURCE); gen.writeln("/AdobeStandardCyrillicEncoding ["); for (int i = 0; i < Glyphs.ADOBECYRILLIC_ENCODING.length; i++) { if (i > 0) { if ((i % 5) == 0) { gen.newLine(); } else { gen.write(" "); } } final char ch = Glyphs.ADOBECYRILLIC_ENCODING[i]; final String glyphname = Glyphs.charToGlyphName(ch); if ("".equals(glyphname)) { gen.write("/" + Glyphs.NOTDEF); } else { gen.write("/"); gen.write(glyphname); } } gen.newLine(); gen.writeln("] def"); gen.writeDSCComment(DSCConstants.END_RESOURCE); gen.getResourceTracker().registerSuppliedResource(ADOBECYRILLIC_ENCODING_RESOURCE); } /** * Redefines the encoding of a font. * @param gen the PostScript generator * @param fontName the font name * @param encoding the new encoding (must be predefined in the PS file) * @throws IOException In case of an I/O problem */ public static void redefineFontEncoding(PSGenerator gen, String fontName, String encoding) throws IOException { gen.writeln("/" + fontName + " findfont"); gen.writeln("dup length dict begin"); gen.writeln(" {1 index /FID ne {def} {pop pop} ifelse} forall"); gen.writeln(" /Encoding " + encoding + " def"); gen.writeln(" currentdict"); gen.writeln("end"); gen.writeln("/" + fontName + " exch definefont pop"); } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/PSGenerator.java0100644 0000000 0000000 00000073104 13777276623 026576 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: PSGenerator.java 1809627 2017-09-25 13:42:08Z ssteiner $ */ package org.apache.xmlgraphics.ps; import java.awt.Color; import java.awt.color.ColorSpace; import java.awt.geom.AffineTransform; import java.awt.geom.Rectangle2D; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.text.DateFormat; import java.util.Date; import java.util.Stack; import javax.xml.transform.Source; import org.apache.commons.io.IOUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.xmlgraphics.java2d.color.ColorUtil; import org.apache.xmlgraphics.java2d.color.ColorWithAlternatives; import org.apache.xmlgraphics.ps.dsc.ResourceTracker; import org.apache.xmlgraphics.util.DoubleFormatUtil; /** * This class is used to output PostScript code to an OutputStream. This class assumes that * the {@link PSProcSets#STD_PROCSET} has been added to the PostScript file. * * @version $Id: PSGenerator.java 1809627 2017-09-25 13:42:08Z ssteiner $ */ public class PSGenerator implements PSCommandMap { /** * Default postscript language level */ public static final int DEFAULT_LANGUAGE_LEVEL = 3; /** * Indicator for the PostScript interpreter that the value is provided * later in the document (mostly in the %%Trailer section). * @deprecated Please use DSCConstants.ATEND. This constant was in the wrong place. */ @Deprecated public static final Object ATEND = DSCConstants.ATEND; /** Line feed used by PostScript */ public static final char LF = '\n'; private static final String IDENTITY_H = "Identity-H"; private Log log = LogFactory.getLog(getClass()); private OutputStream out; private int psLevel = DEFAULT_LANGUAGE_LEVEL; private boolean acrobatDownsample; private boolean commentsEnabled = true; private boolean compactMode = true; private PSCommandMap commandMap = PSProcSets.STD_COMMAND_MAP; private Stack graphicsStateStack = new Stack(); private PSState currentState; private StringBuffer doubleBuffer = new StringBuffer(16); private StringBuffer tempBuffer = new StringBuffer(256); private boolean identityHEmbedded; private PSResource procsetCIDInitResource; private PSResource identityHCMapResource; /** * Creates a new instance. * @param out the OutputStream to write the generated PostScript code to */ public PSGenerator(OutputStream out) { this.out = out; resetGraphicsState(); } /** * Indicates whether this instance is in compact mode. See {@link #setCompactMode(boolean)} * for details. * @return true if compact mode is enabled (the default) */ public boolean isCompactMode() { return this.compactMode; } /** * Controls whether this instance shall produce compact PostScript (omitting comments and * using short macros). Enabling this mode requires that the standard procset * ({@link PSProcSets#STD_PROCSET}) is included in the PostScript file. Setting this to * false produces more verbose PostScript suitable for debugging. * @param value true to enable compact mode, false for verbose mode */ public void setCompactMode(boolean value) { this.compactMode = value; } /** * Indicates whether this instance allows to write comments. See * {@link #setCommentsEnabled(boolean)} for details. * @return true if comments are enabled (the default) */ public boolean isCommentsEnabled() { return this.commentsEnabled; } /** * Controls whether this instance allows to write comments using the {@link #commentln(String)} * method. * @param value true to enable comments, false to disable them */ public void setCommentsEnabled(boolean value) { this.commentsEnabled = value; } private void resetGraphicsState() { if (!this.graphicsStateStack.isEmpty()) { throw new IllegalStateException("Graphics state stack should be empty at this point"); } this.currentState = new PSState(); } /** * Returns the OutputStream the PSGenerator writes to. * @return the OutputStream */ public OutputStream getOutputStream() { return this.out; } /** * Returns the selected PostScript level. * @return the PostScript level */ public int getPSLevel() { return this.psLevel; } /** * Sets the PostScript level that is used to generate the current document. * @param level the PostScript level (currently 1, 2 and 3 are known) */ public void setPSLevel(int level) { this.psLevel = level; } public boolean isAcrobatDownsample() { return acrobatDownsample; } public void setAcrobatDownsample(boolean b) { acrobatDownsample = b; } /** * Attempts to resolve the given URI. PSGenerator should be subclasses to provide more * sophisticated URI resolution. * @param uri URI to access * @return A {@link javax.xml.transform.Source} object, or null if the URI * cannot be resolved. */ public Source resolveURI(String uri) { return new javax.xml.transform.stream.StreamSource(uri); } /** * Writes a newline character to the OutputStream. * * @throws IOException In case of an I/O problem */ public final void newLine() throws IOException { out.write(LF); } /** * Formats a double value for PostScript output. * * @param value value to format * @return the formatted value */ public String formatDouble(double value) { doubleBuffer.setLength(0); DoubleFormatUtil.formatDouble(value, 3, 3, doubleBuffer); return doubleBuffer.toString(); } /** * Formats a double value for PostScript output (higher resolution). * * @param value value to format * @return the formatted value */ public String formatDouble5(double value) { doubleBuffer.setLength(0); DoubleFormatUtil.formatDouble(value, 5, 5, doubleBuffer); return doubleBuffer.toString(); } /** * Writes a PostScript command to the stream. * * @param cmd The PostScript code to be written. * @exception IOException In case of an I/O problem */ public void write(String cmd) throws IOException { /* TODO Check disabled until clarification. if (cmd.length() > 255) { throw new RuntimeException("PostScript command exceeded limit of 255 characters"); } */ out.write(cmd.getBytes("US-ASCII")); } /** * Writes the given number to the stream in decimal format. * * @param n a number * @throws IOException in case of an I/O problem */ public void write(int n) throws IOException { write(Integer.toString(n)); } /** * Writes a PostScript command to the stream and ends the line. * * @param cmd The PostScript code to be written. * @exception IOException In case of an I/O problem */ public void writeln(String cmd) throws IOException { write(cmd); newLine(); } /** * Writes a comment to the stream and ends the line. Output of comments can * be disabled to reduce the size of the generated file. * * @param comment comment to write * @exception IOException In case of an I/O problem */ public void commentln(String comment) throws IOException { if (isCommentsEnabled()) { writeln(comment); } } /** {@inheritDoc} */ public String mapCommand(String command) { if (isCompactMode()) { return this.commandMap.mapCommand(command); } else { return command; } } /** * Writes encoded data to the PostScript stream. * * @param cmd The encoded PostScript code to be written. * @exception IOException In case of an I/O problem */ public void writeByteArr(byte[] cmd) throws IOException { out.write(cmd); newLine(); } /** * Flushes the OutputStream. * * @exception IOException In case of an I/O problem */ public void flush() throws IOException { out.flush(); } /** * Escapes a character conforming to the rules established in the PostScript * Language Reference (Search for "Literal Text Strings"). * @param c character to escape * @param target target StringBuffer to write the escaped character to */ public static final void escapeChar(char c, StringBuffer target) { switch (c) { case '\n': target.append("\\n"); break; case '\r': target.append("\\r"); break; case '\t': target.append("\\t"); break; case '\b': target.append("\\b"); break; case '\f': target.append("\\f"); break; case '\\': target.append("\\\\"); break; case '(': target.append("\\("); break; case ')': target.append("\\)"); break; default: if (c > 255) { //Ignoring non Latin-1 characters target.append('?'); } else if (c < 32 || c > 127) { target.append('\\'); target.append((char)('0' + (c >> 6))); target.append((char)('0' + ((c >> 3) % 8))); target.append((char)('0' + (c % 8))); //Integer.toOctalString(i) } else { target.append(c); } } } /** * Converts text by applying escaping rules established in the DSC specs. * @param text Text to convert * @return String The resulting String */ public static final String convertStringToDSC(String text) { return convertStringToDSC(text, false); } /** * Converts a <real> value for use in DSC comments. * @param value the value to convert * @return String The resulting String */ public static final String convertRealToDSC(float value) { return Float.toString(value); } /** * Converts text by applying escaping rules established in the DSC specs. * @param text Text to convert * @param forceParentheses Force the use of parentheses * @return String The resulting String */ public static final String convertStringToDSC(String text, boolean forceParentheses) { if ((text == null) || (text.length() == 0)) { return "()"; } else { int initialSize = text.length(); initialSize += initialSize / 2; StringBuffer sb = new StringBuffer(initialSize); if ((text.indexOf(' ') >= 0) || forceParentheses) { sb.append('('); for (int i = 0; i < text.length(); i++) { final char c = text.charAt(i); escapeChar(c, sb); } sb.append(')'); return sb.toString(); } else { for (int i = 0; i < text.length(); i++) { final char c = text.charAt(i); escapeChar(c, sb); } return sb.toString(); } } } /** * Writes a DSC comment to the output stream. * @param name Name of the DSC comment * @exception IOException In case of an I/O problem * @see org.apache.xmlgraphics.ps.DSCConstants */ public void writeDSCComment(String name) throws IOException { writeln("%%" + name); } /** * Writes a DSC comment to the output stream. The parameter to the DSC * comment can be any object. The object is converted to a String as * necessary. * @param name Name of the DSC comment * @param param Single parameter to the DSC comment * @exception IOException In case of an I/O problem * @see org.apache.xmlgraphics.ps.DSCConstants */ public void writeDSCComment(String name, Object param) throws IOException { writeDSCComment(name, new Object[] {param}); } /** * Writes a DSC comment to the output stream. The parameters to the DSC * comment can be any object. The objects are converted to Strings as * necessary. Please see the source code to find out what parameters are * currently supported. * @param name Name of the DSC comment * @param params Array of parameters to the DSC comment * @exception IOException In case of an I/O problem * @see org.apache.xmlgraphics.ps.DSCConstants */ public void writeDSCComment(String name, Object[] params) throws IOException { tempBuffer.setLength(0); tempBuffer.append("%%"); tempBuffer.append(name); if ((params != null) && (params.length > 0)) { tempBuffer.append(": "); for (int i = 0; i < params.length; i++) { if (i > 0) { tempBuffer.append(" "); } if (params[i] instanceof String) { tempBuffer.append(convertStringToDSC((String)params[i])); } else if (params[i] == DSCConstants.ATEND) { tempBuffer.append(DSCConstants.ATEND); } else if (params[i] instanceof Double) { tempBuffer.append(formatDouble((Double) params[i])); } else if (params[i] instanceof Number) { tempBuffer.append(params[i].toString()); } else if (params[i] instanceof Date) { DateFormat datef = new java.text.SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); tempBuffer.append(convertStringToDSC(datef.format((Date)params[i]))); } else if (params[i] instanceof PSResource) { tempBuffer.append(((PSResource)params[i]).getResourceSpecification()); } else { throw new IllegalArgumentException("Unsupported parameter type: " + params[i].getClass().getName()); } } } writeln(tempBuffer.toString()); } /** * Saves the graphics state of the rendering engine. * @exception IOException In case of an I/O problem */ public void saveGraphicsState() throws IOException { writeln(mapCommand("gsave")); PSState state = new PSState(this.currentState, false); this.graphicsStateStack.push(this.currentState); this.currentState = state; } /** * Restores the last graphics state of the rendering engine. * @return true if the state was restored, false if there's a stack underflow. * @exception IOException In case of an I/O problem */ public boolean restoreGraphicsState() throws IOException { if (this.graphicsStateStack.size() > 0) { writeln(mapCommand("grestore")); this.currentState = this.graphicsStateStack.pop(); return true; } else { return false; } } /** * Returns the current graphics state. * @return the current graphics state */ public PSState getCurrentState() { return this.currentState; } /** * Issues the "showpage" command and resets the painting state accordingly. * @exception IOException In case of an I/O problem */ public void showPage() throws IOException { writeln("showpage"); resetGraphicsState(); } /** * Concats the transformation matrix. * @param a A part * @param b B part * @param c C part * @param d D part * @param e E part * @param f F part * @exception IOException In case of an I/O problem */ public void concatMatrix(double a, double b, double c, double d, double e, double f) throws IOException { AffineTransform at = new AffineTransform(a, b, c, d, e, f); concatMatrix(at); } /** * Concats the transformations matrix. * @param matrix Matrix to use * @exception IOException In case of an I/O problem */ public void concatMatrix(double[] matrix) throws IOException { concatMatrix(matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5]); } /** * Formats a transformation matrix. * @param at the AffineTransform with the matrix * @return the formatted transformation matrix (example: "[1 0 0 1 0 0]") */ public String formatMatrix(AffineTransform at) { double[] matrix = new double[6]; at.getMatrix(matrix); return "[" + formatDouble5(matrix[0]) + " " + formatDouble5(matrix[1]) + " " + formatDouble5(matrix[2]) + " " + formatDouble5(matrix[3]) + " " + formatDouble5(matrix[4]) + " " + formatDouble5(matrix[5]) + "]"; } /** * Concats the transformations matric. * @param at the AffineTransform whose matrix to use * @exception IOException In case of an I/O problem */ public void concatMatrix(AffineTransform at) throws IOException { getCurrentState().concatMatrix(at); writeln(formatMatrix(at) + " " + mapCommand("concat")); } /** * Formats a Rectangle2D to an array. * @param rect the rectangle * @return the formatted array */ public String formatRectangleToArray(Rectangle2D rect) { return "[" + formatDouble(rect.getX()) + " " + formatDouble(rect.getY()) + " " + formatDouble(rect.getWidth()) + " " + formatDouble(rect.getHeight()) + "]"; } /** * Adds a rectangle to the current path. * @param x upper left corner * @param y upper left corner * @param w width * @param h height * @exception IOException In case of an I/O problem */ public void defineRect(double x, double y, double w, double h) throws IOException { writeln(formatDouble(x) + " " + formatDouble(y) + " " + formatDouble(w) + " " + formatDouble(h) + " re"); } /** * Establishes the specified line cap style. * @param linecap the line cap style (0, 1 or 2) as defined by the setlinecap command. * @exception IOException In case of an I/O problem */ public void useLineCap(int linecap) throws IOException { if (getCurrentState().useLineCap(linecap)) { writeln(linecap + " " + mapCommand("setlinecap")); } } /** * Establishes the specified line join style. * @param linejoin the line join style (0, 1 or 2) as defined by the setlinejoin command. * @exception IOException In case of an I/O problem */ public void useLineJoin(int linejoin) throws IOException { if (getCurrentState().useLineJoin(linejoin)) { writeln(linejoin + " " + mapCommand("setlinejoin")); } } /** * Establishes the specified miter limit. * @param miterlimit the miter limit as defined by the setmiterlimit command. * @exception IOException In case of an I/O problem */ public void useMiterLimit(float miterlimit) throws IOException { if (getCurrentState().useMiterLimit(miterlimit)) { writeln(miterlimit + " " + mapCommand("setmiterlimit")); } } /** * Establishes the specified line width. * @param width the line width as defined by the setlinewidth command. * @exception IOException In case of an I/O problem */ public void useLineWidth(double width) throws IOException { if (getCurrentState().useLineWidth(width)) { writeln(formatDouble(width) + " " + mapCommand("setlinewidth")); } } /** * Establishes the specified dash pattern. * @param pattern the dash pattern as defined by the setdash command. * @exception IOException In case of an I/O problem */ public void useDash(String pattern) throws IOException { if (pattern == null) { pattern = PSState.DEFAULT_DASH; } if (getCurrentState().useDash(pattern)) { writeln(pattern + " " + mapCommand("setdash")); } } /** * Establishes the specified color (RGB). * @param col the color as defined by the setrgbcolor command. * @exception IOException In case of an I/O problem * @deprecated use useColor method instead */ @Deprecated public void useRGBColor(Color col) throws IOException { useColor(col); } /** * Establishes the specified color. * @param col the color. * @exception IOException In case of an I/O problem */ public void useColor(Color col) throws IOException { if (getCurrentState().useColor(col)) { writeln(convertColorToPS(col)); } } private String convertColorToPS(Color color) { StringBuffer codeBuffer = new StringBuffer(); //Important: Right now, CMYK colors are treated as device colors (DeviceCMYK) irrespective //of any associated color profile. All other colors are converted to sRGB (if necessary) //and the resulting RGB components are treated as DeviceRGB colors. //If all three RGB components are the same, DeviceGray is used. boolean established = false; if (color instanceof ColorWithAlternatives) { ColorWithAlternatives colExt = (ColorWithAlternatives)color; //Alternative colors have priority Color[] alt = colExt.getAlternativeColors(); for (Color col : alt) { established = establishColorFromColor(codeBuffer, col); if (established) { break; } } if (log.isDebugEnabled() && alt.length > 0) { log.debug("None of the alternative colors are supported. Using fallback: " + color); } } //Fallback if (!established) { established = establishColorFromColor(codeBuffer, color); } if (!established) { establishFallbackRGB(codeBuffer, color); } return codeBuffer.toString(); } private boolean establishColorFromColor(StringBuffer codeBuffer, Color color) { //Important: see above note about color handling! float[] comps = color.getColorComponents(null); if (color.getColorSpace().getType() == ColorSpace.TYPE_CMYK) { // colorspace is CMYK writeSetColor(codeBuffer, comps, "setcmykcolor"); return true; } return false; } private void writeSetColor(StringBuffer codeBuffer, float[] comps, String command) { for (int i = 0, c = comps.length; i < c; i++) { if (i > 0) { codeBuffer.append(" "); } codeBuffer.append(formatDouble(comps[i])); } codeBuffer.append(" ").append(mapCommand(command)); } private void establishFallbackRGB(StringBuffer codeBuffer, Color color) { float[] comps; if (color.getColorSpace().isCS_sRGB()) { comps = color.getColorComponents(null); } else { if (log.isDebugEnabled()) { log.debug("Converting color to sRGB as a fallback: " + color); } ColorSpace sRGB = ColorSpace.getInstance(ColorSpace.CS_sRGB); comps = color.getColorComponents(sRGB, null); } assert comps.length == 3; boolean gray = ColorUtil.isGray(color); if (gray) { comps = new float[] {comps[0]}; } writeSetColor(codeBuffer, comps, gray ? "setgray" : "setrgbcolor"); } /** * Establishes the specified font and size. * @param name name of the font for the "F" command (see FOP Std Proc Set) * @param size size of the font * @exception IOException In case of an I/O problem */ public void useFont(String name, float size) throws IOException { if (getCurrentState().useFont(name, size)) { writeln(name + " " + formatDouble(size) + " F"); } } private ResourceTracker resTracker = new ResourceTracker(); /** * Resturns the ResourceTracker instance associated with this PSGenerator. * @return the ResourceTracker instance or null if none is assigned */ public ResourceTracker getResourceTracker() { return this.resTracker; } /** * Sets the ResourceTracker instance to be associated with this PSGenerator. * @param resTracker the ResourceTracker instance */ public void setResourceTracker(ResourceTracker resTracker) { this.resTracker = resTracker; } /** * Notifies the generator that a new page has been started and that the page resource * set can be cleared. * @deprecated Use the notifyStartNewPage() on ResourceTracker instead. */ @Deprecated public void notifyStartNewPage() { getResourceTracker().notifyStartNewPage(); } /** * Notifies the generator about the usage of a resource on the current page. * @param res the resource being used * @param needed true if this is a needed resource, false for a supplied resource * @deprecated Use the notifyResourceUsageOnPage() on ResourceTracker instead */ @Deprecated public void notifyResourceUsage(PSResource res, boolean needed) { getResourceTracker().notifyResourceUsageOnPage(res); } /** * Writes a DSC comment for the accumulated used resources, either at page level or * at document level. * @param pageLevel true if the DSC comment for the page level should be generated, * false for the document level (in the trailer) * @exception IOException In case of an I/O problem * @deprecated Use the writeResources() on ResourceTracker instead. */ @Deprecated public void writeResources(boolean pageLevel) throws IOException { getResourceTracker().writeResources(pageLevel, this); } /** * Indicates whether a particular resource is supplied, rather than needed. * @param res the resource * @return true if the resource is registered as being supplied. * @deprecated Use the isResourceSupplied() on ResourceTracker instead. */ @Deprecated public boolean isResourceSupplied(PSResource res) { return getResourceTracker().isResourceSupplied(res); } /** * Embeds the Identity-H CMap file into the output stream, if that has not * already been done. * * @return true if embedding has actually been performed, false otherwise * (which means that a call to this method had already been made earlier) * @throws IOException in case of an I/O problem */ public boolean embedIdentityH() throws IOException { if (identityHEmbedded) { return false; } else { resTracker.registerNeededResource(getProcsetCIDInitResource()); writeDSCComment(DSCConstants.BEGIN_DOCUMENT, IDENTITY_H); InputStream cmap = PSGenerator.class.getResourceAsStream(IDENTITY_H); try { IOUtils.copyLarge(cmap, out); } finally { IOUtils.closeQuietly(cmap); } writeDSCComment(DSCConstants.END_DOCUMENT); resTracker.registerSuppliedResource(getIdentityHCMapResource()); identityHEmbedded = true; return true; } } /** * Returns the PSResource instance corresponding to the Identity-H CMap * resource. * * @return the Identity-H CMap resource. */ public PSResource getIdentityHCMapResource() { if (identityHCMapResource == null) { identityHCMapResource = new PSResource(PSResource.TYPE_CMAP, IDENTITY_H); } return identityHCMapResource; } /** * Returns the PSResource instance corresponding to the CIDInit ProcSet * resource. * * @return the ProcSet CIDInit resource */ public PSResource getProcsetCIDInitResource() { if (procsetCIDInitResource == null) { procsetCIDInitResource = new PSResource(PSResource.TYPE_PROCSET, "CIDInit"); } return procsetCIDInitResource; } /** * Adds a PostScript DSC comment to the output stream requiring the * inclusion of the CIDInit ProcSet resource. * * @throws IOException in case of an I/O problem */ public void includeProcsetCIDInitResource() throws IOException { writeDSCComment(DSCConstants.INCLUDE_RESOURCE, getProcsetCIDInitResource()); } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/PSImageUtils.java0100644 0000000 0000000 00000102335 13777276623 026712 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: PSImageUtils.java 1792872 2017-04-27 12:30:09Z ssteiner $ */ package org.apache.xmlgraphics.ps; import java.awt.Color; import java.awt.Dimension; import java.awt.color.ColorSpace; import java.awt.geom.Dimension2D; import java.awt.geom.Rectangle2D; import java.awt.image.ColorModel; import java.awt.image.DataBuffer; import java.awt.image.DataBufferByte; import java.awt.image.IndexColorModel; import java.awt.image.Raster; import java.awt.image.RenderedImage; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Arrays; import org.apache.commons.io.IOUtils; import org.apache.xmlgraphics.util.io.ASCII85OutputStream; import org.apache.xmlgraphics.util.io.Finalizable; import org.apache.xmlgraphics.util.io.FlateEncodeOutputStream; import org.apache.xmlgraphics.util.io.RunLengthEncodeOutputStream; // CSOFF: HideUtilityClassConstructor /** * Utility code for rendering images in PostScript. */ public class PSImageUtils { public PSImageUtils() { } /** * Writes a bitmap image to the PostScript stream. * @param img the bitmap image as a byte array * @param imgDim the dimensions of the image * @param imgDescription the name of the image * @param targetRect the target rectangle to place the image in * @param isJPEG true if "img" contains a DCT-encoded images, false if "img" contains the * decoded bitmap * @param colorSpace the color space of the image * @param gen the PostScript generator * @throws IOException In case of an I/O exception * @deprecated Please use the variant with the more versatile ImageEncoder as parameter */ public static void writeImage(final byte[] img, Dimension imgDim, String imgDescription, Rectangle2D targetRect, final boolean isJPEG, ColorSpace colorSpace, PSGenerator gen) throws IOException { ImageEncoder encoder = new ImageEncoder() { public void writeTo(OutputStream out) throws IOException { out.write(img); } public String getImplicitFilter() { if (isJPEG) { return "<< >> /DCTDecode"; } else { return null; } } }; writeImage(encoder, imgDim, imgDescription, targetRect, colorSpace, 8, false, gen); } /** * Writes a bitmap image to the PostScript stream. * @param encoder the image encoder * @param imgDim the dimensions of the image * @param imgDescription the name of the image * @param targetRect the target rectangle to place the image in * @param colorSpace the color space of the image * @param bitsPerComponent the number of bits per component * @param invertImage true if the image shall be inverted * @param gen the PostScript generator * @throws IOException In case of an I/O exception */ public static void writeImage(ImageEncoder encoder, Dimension imgDim, String imgDescription, Rectangle2D targetRect, ColorSpace colorSpace, int bitsPerComponent, boolean invertImage, PSGenerator gen) throws IOException { gen.saveGraphicsState(); translateAndScale(gen, null, targetRect); gen.commentln("%AXGBeginBitmap: " + imgDescription); gen.writeln("{{"); // Template: (RawData is used for the EOF signal only) // gen.write("/RawData currentfile filter def"); // gen.write("/Data RawData [...] def"); String implicitFilter = encoder.getImplicitFilter(); if (implicitFilter != null) { gen.writeln("/RawData currentfile /ASCII85Decode filter def"); gen.writeln("/Data RawData " + implicitFilter + " filter def"); } else { if (gen.getPSLevel() >= 3) { gen.writeln("/RawData currentfile /ASCII85Decode filter def"); gen.writeln("/Data RawData /FlateDecode filter def"); } else { gen.writeln("/RawData currentfile /ASCII85Decode filter def"); gen.writeln("/Data RawData /RunLengthDecode filter def"); } } PSDictionary imageDict = new PSDictionary(); imageDict.put("/DataSource", "Data"); imageDict.put("/BitsPerComponent", Integer.toString(bitsPerComponent)); writeImageCommand(imageDict, imgDim, colorSpace, invertImage, gen); /* the following two lines could be enabled if something still goes wrong * gen.write("Data closefile"); * gen.write("RawData flushfile"); */ gen.writeln("} stopped {handleerror} if"); gen.writeln(" RawData flushfile"); gen.writeln("} exec"); compressAndWriteBitmap(encoder, gen); gen.newLine(); gen.commentln("%AXGEndBitmap"); gen.restoreGraphicsState(); } public static void writeImage(ImageEncoder encoder, Dimension imgDim, String imgDescription, Rectangle2D targetRect, ColorModel colorModel, PSGenerator gen) throws IOException { writeImage(encoder, imgDim, imgDescription, targetRect, colorModel, gen, null); } /** * Writes a bitmap image to the PostScript stream. * @param encoder the image encoder * @param imgDim the dimensions of the image * @param imgDescription the name of the image * @param targetRect the target rectangle to place the image in * @param colorModel the color model of the image * @param gen the PostScript generator * @throws IOException In case of an I/O exception */ public static void writeImage(ImageEncoder encoder, Dimension imgDim, String imgDescription, Rectangle2D targetRect, ColorModel colorModel, PSGenerator gen, RenderedImage ri) throws IOException { gen.saveGraphicsState(); translateAndScale(gen, null, targetRect); gen.commentln("%AXGBeginBitmap: " + imgDescription); gen.writeln("{{"); String implicitFilter = encoder.getImplicitFilter(); if (implicitFilter != null) { gen.writeln("/RawData currentfile /ASCII85Decode filter def"); gen.writeln("/Data RawData " + implicitFilter + " filter def"); } else { if (gen.getPSLevel() >= 3) { gen.writeln("/RawData currentfile /ASCII85Decode filter def"); gen.writeln("/Data RawData /FlateDecode filter def"); } else { gen.writeln("/RawData currentfile /ASCII85Decode filter def"); gen.writeln("/Data RawData /RunLengthDecode filter def"); } } PSDictionary imageDict = new PSDictionary(); imageDict.put("/DataSource", "Data"); populateImageDictionary(imgDim, colorModel, imageDict); if (ri != null) { DataBuffer buffer = ri.getData().getDataBuffer(); if (!(buffer instanceof DataBufferByte)) { imageDict.put("/BitsPerComponent", 8); } } writeImageCommand(imageDict, colorModel, gen); /* * the following two lines could be enabled if something still goes wrong * gen.write("Data closefile"); * gen.write("RawData flushfile"); */ gen.writeln("} stopped {handleerror} if"); gen.writeln(" RawData flushfile"); gen.writeln("} exec"); compressAndWriteBitmap(encoder, gen); gen.newLine(); gen.commentln("%AXGEndBitmap"); gen.restoreGraphicsState(); } /** * Writes a bitmap image to the PostScript stream. * @param encoder the image encoder * @param imgDim the dimensions of the image * @param imgDescription the name of the image * @param targetRect the target rectangle to place the image in * @param colorModel the color model of the image * @param gen the PostScript generator * @throws IOException In case of an I/O exception */ public static void writeImage(ImageEncoder encoder, Dimension imgDim, String imgDescription, Rectangle2D targetRect, ColorModel colorModel, PSGenerator gen, RenderedImage ri, Color maskColor) throws IOException { gen.saveGraphicsState(); translateAndScale(gen, null, targetRect); gen.commentln("%AXGBeginBitmap: " + imgDescription); gen.writeln("{{"); String implicitFilter = encoder.getImplicitFilter(); if (implicitFilter != null) { gen.writeln("/RawData currentfile /ASCII85Decode filter def"); gen.writeln("/Data RawData " + implicitFilter + " filter def"); } else { if (gen.getPSLevel() >= 3) { gen.writeln("/RawData currentfile /ASCII85Decode filter def"); gen.writeln("/Data RawData /FlateDecode filter def"); } else { gen.writeln("/RawData currentfile /ASCII85Decode filter def"); gen.writeln("/Data RawData /RunLengthDecode filter def"); } } PSDictionary imageDict = new PSDictionary(); imageDict.put("/DataSource", "Data"); populateImageDictionary(imgDim, colorModel, imageDict, maskColor); if (ri != null) { DataBuffer buffer = ri.getData().getDataBuffer(); if (!(buffer instanceof DataBufferByte)) { imageDict.put("/BitsPerComponent", 8); } } writeImageCommand(imageDict, colorModel, gen); /* * the following two lines could be enabled if something still goes wrong * gen.write("Data closefile"); * gen.write("RawData flushfile"); */ gen.writeln("} stopped {handleerror} if"); gen.writeln(" RawData flushfile"); gen.writeln("} exec"); compressAndWriteBitmap(encoder, gen); gen.newLine(); gen.commentln("%AXGEndBitmap"); gen.restoreGraphicsState(); } private static ColorModel populateImageDictionary(Dimension imgDim, ColorModel colorModel, PSDictionary imageDict) { imageDict.put("/ImageType", "1"); colorModel = writeImageDictionary(imgDim, imageDict, colorModel); return colorModel; } private static ColorModel populateImageDictionary(Dimension imgDim, ColorModel colorModel, PSDictionary imageDict, Color maskColor) { imageDict.put("/ImageType", "4"); colorModel = writeImageDictionary(imgDim, imageDict, colorModel); imageDict.put("/MaskColor", String.format("[ %d %d %d ]", maskColor.getRed(), maskColor.getGreen(), maskColor.getBlue())); return colorModel; } private static ColorModel writeImageDictionary(Dimension imgDim, PSDictionary imageDict, ColorModel colorModel) { String w = Integer.toString(imgDim.width); String h = Integer.toString(imgDim.height); imageDict.put("/Width", w); imageDict.put("/Height", h); boolean invertColors = false; String decodeArray = getDecodeArray(colorModel.getNumColorComponents(), invertColors); int bitsPerComp = colorModel.getComponentSize(0); // Setup scanning for left-to-right and top-to-bottom imageDict.put("/ImageMatrix", "[" + w + " 0 0 " + h + " 0 0]"); if ((colorModel instanceof IndexColorModel)) { IndexColorModel indexColorModel = (IndexColorModel) colorModel; int c = indexColorModel.getMapSize(); int hival = c - 1; if (hival > 4095) { throw new UnsupportedOperationException("hival must not go beyond 4095"); } bitsPerComp = indexColorModel.getPixelSize(); int ceiling = ((int) Math.pow(2, bitsPerComp)) - 1; decodeArray = "[0 " + ceiling + "]"; } imageDict.put("/BitsPerComponent", Integer.toString(bitsPerComp)); imageDict.put("/Decode", decodeArray); return colorModel; } private static String getDecodeArray(int numComponents, boolean invertColors) { String decodeArray; StringBuffer sb = new StringBuffer("["); for (int i = 0; i < numComponents; i++) { if (i > 0) { sb.append(" "); } if (invertColors) { sb.append("1 0"); } else { sb.append("0 1"); } } sb.append("]"); decodeArray = sb.toString(); return decodeArray; } private static void prepareColorspace(PSGenerator gen, ColorSpace colorSpace) throws IOException { gen.writeln(getColorSpaceName(colorSpace) + " setcolorspace"); } private static void prepareColorSpace(PSGenerator gen, ColorModel cm) throws IOException { //Prepare color space if ((cm instanceof IndexColorModel)) { ColorSpace cs = cm.getColorSpace(); IndexColorModel im = (IndexColorModel)cm; boolean isDeviceGray; int c = im.getMapSize(); int[] palette = new int[c]; im.getRGBs(palette); byte[] reds = new byte[c]; byte[] greens = new byte[c]; byte[] blues = new byte[c]; im.getReds(reds); im.getGreens(greens); im.getBlues(blues); int hival = c - 1; if (hival > 4095) { throw new UnsupportedOperationException("hival must not go beyond 4095"); } isDeviceGray = Arrays.equals(reds, blues) && Arrays.equals(blues, greens); if (isDeviceGray) { gen.write("[/Indexed " + "/DeviceGray"); } else { gen.write("[/Indexed " + getColorSpaceName(cs)); } gen.writeln(" " + Integer.toString(hival)); gen.write(" <"); if (isDeviceGray) { gen.write(toHexString(blues)); } else { for (int i = 0; i < c; i++) { if (i > 0) { if ((i % 8) == 0) { gen.newLine(); gen.write(" "); } else { gen.write(" "); } } gen.write(rgb2Hex(palette[i])); } } gen.writeln(">"); gen.writeln("] setcolorspace"); } else { gen.writeln(getColorSpaceName(cm.getColorSpace()) + " setcolorspace"); } } static String toHexString(byte[] color) { char[] hexChars = new char[color.length * 2]; int x; for (int i = 0; i < color.length; i++) { x = color[i] & 0xFF; hexChars[i * 2] = HEX[x >>> 4]; hexChars[i * 2 + 1] = HEX[x & 0x0F]; } return new String(hexChars); } static void writeImageCommand(RenderedImage img, PSDictionary imageDict, PSGenerator gen) throws IOException { ImageEncodingHelper helper = new ImageEncodingHelper(img, true); ColorModel cm = helper.getEncodedColorModel(); Dimension imgDim = new Dimension(img.getWidth(), img.getHeight()); populateImageDictionary(imgDim, cm, imageDict); writeImageCommand(imageDict, cm, gen); } static void writeImageCommand(PSDictionary imageDict, ColorModel cm, PSGenerator gen) throws IOException { prepareColorSpace(gen, cm); gen.write(imageDict.toString()); gen.writeln(" image"); } static void writeImageCommand(PSDictionary imageDict, Dimension imgDim, ColorSpace colorSpace, boolean invertImage, PSGenerator gen) throws IOException { imageDict.put("/ImageType", "1"); imageDict.put("/Width", Integer.toString(imgDim.width)); imageDict.put("/Height", Integer.toString(imgDim.height)); String decodeArray = getDecodeArray(colorSpace.getNumComponents(), invertImage); imageDict.put("/Decode", decodeArray); // Setup scanning for left-to-right and top-to-bottom imageDict.put("/ImageMatrix", "[" + imgDim.width + " 0 0 " + imgDim.height + " 0 0]"); prepareColorspace(gen, colorSpace); gen.write(imageDict.toString()); gen.writeln(" image"); } private static final char[] HEX = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; private static String rgb2Hex(int rgb) { StringBuffer sb = new StringBuffer(); for (int i = 5; i >= 0; i--) { int shift = i * 4; int n = (rgb & (15 << shift)) >> shift; sb.append(HEX[n % 16]); } return sb.toString(); } /** * Renders a bitmap image to PostScript. * @param img image to render * @param x x position * @param y y position * @param w width * @param h height * @param gen PS generator * @throws IOException In case of an I/O problem while rendering the image */ public static void renderBitmapImage(RenderedImage img, float x, float y, float w, float h, PSGenerator gen, Color mask) throws IOException { Rectangle2D targetRect = new Rectangle2D.Double(x, y, w, h); ImageEncoder encoder = ImageEncodingHelper.createRenderedImageEncoder(img); Dimension imgDim = new Dimension(img.getWidth(), img.getHeight()); String imgDescription = img.getClass().getName(); ImageEncodingHelper helper = new ImageEncodingHelper(img); ColorModel cm = helper.getEncodedColorModel(); if (mask == null) { writeImage(encoder, imgDim, imgDescription, targetRect, cm, gen, img); } else { writeImage(encoder, imgDim, imgDescription, targetRect, cm, gen, img, mask); } } /** * Writes a bitmap image as a PostScript form enclosed by DSC resource wrappers to the * PostScript file. * @param img the raw bitmap data * @param imgDim the dimensions of the image * @param formName the name of the PostScript form to use * @param imageDescription a description of the image added as a DSC Title comment * @param isJPEG true if "img" contains a DCT-encoded images, false if "img" contains the * decoded bitmap * @param colorSpace the color space of the image * @param gen the PostScript generator * @return a PSResource representing the form for resource tracking * @throws IOException In case of an I/O exception * @deprecated Please use {@link FormGenerator} */ public static PSResource writeReusableImage(final byte[] img, Dimension imgDim, String formName, String imageDescription, final boolean isJPEG, ColorSpace colorSpace, PSGenerator gen) throws IOException { ImageEncoder encoder = new ImageEncoder() { public void writeTo(OutputStream out) throws IOException { out.write(img); } public String getImplicitFilter() { if (isJPEG) { return "<< >> /DCTDecode"; } else { return null; } } }; return writeReusableImage(encoder, imgDim, formName, imageDescription, colorSpace, false, gen); } /** * Writes a bitmap image as a PostScript form enclosed by DSC resource wrappers to the * PostScript file. * @param encoder the ImageEncoder that will provide the raw bitmap data * @param imgDim the dimensions of the image * @param formName the name of the PostScript form to use * @param imageDescription a description of the image added as a DSC Title comment * @param colorSpace the color space of the image * @param invertImage true if the image shall be inverted * @param gen the PostScript generator * @return a PSResource representing the form for resource tracking * @throws IOException In case of an I/O exception * @deprecated Please use {@link FormGenerator} */ protected static PSResource writeReusableImage(ImageEncoder encoder, Dimension imgDim, String formName, String imageDescription, ColorSpace colorSpace, boolean invertImage, PSGenerator gen) throws IOException { if (gen.getPSLevel() < 2) { throw new UnsupportedOperationException( "Reusable images requires at least Level 2 PostScript"); } String dataName = formName + ":Data"; gen.writeDSCComment(DSCConstants.BEGIN_RESOURCE, formName); if (imageDescription != null) { gen.writeDSCComment(DSCConstants.TITLE, imageDescription); } String additionalFilters; String implicitFilter = encoder.getImplicitFilter(); if (implicitFilter != null) { additionalFilters = "/ASCII85Decode filter " + implicitFilter + " filter"; } else { if (gen.getPSLevel() >= 3) { additionalFilters = "/ASCII85Decode filter /FlateDecode filter"; } else { additionalFilters = "/ASCII85Decode filter /RunLengthDecode filter"; } } gen.writeln("/" + formName); gen.writeln("<< /FormType 1"); gen.writeln(" /BBox [0 0 " + imgDim.width + " " + imgDim.height + "]"); gen.writeln(" /Matrix [1 0 0 1 0 0]"); gen.writeln(" /PaintProc {"); gen.writeln(" pop"); gen.writeln(" gsave"); if (gen.getPSLevel() == 2) { gen.writeln(" userdict /i 0 put"); //rewind image data } else { gen.writeln(" " + dataName + " 0 setfileposition"); //rewind image data } String dataSource; if (gen.getPSLevel() == 2) { dataSource = "{ " + dataName + " i get /i i 1 add store } bind"; } else { dataSource = dataName; } PSDictionary imageDict = new PSDictionary(); imageDict.put("/DataSource", dataSource); imageDict.put("/BitsPerComponent", Integer.toString(8)); writeImageCommand(imageDict, imgDim, colorSpace, invertImage, gen); gen.writeln(" grestore"); gen.writeln(" } bind"); gen.writeln(">> def"); gen.writeln("/" + dataName + " currentfile"); gen.writeln(additionalFilters); if (gen.getPSLevel() == 2) { //Creates a data array from the inline file gen.writeln("{ /temp exch def [" + " { temp 16384 string readstring not {exit } if } loop ] } exec"); } else { gen.writeln("/ReusableStreamDecode filter"); } compressAndWriteBitmap(encoder, gen); gen.writeln("def"); gen.writeDSCComment(DSCConstants.END_RESOURCE); PSResource res = new PSResource(PSResource.TYPE_FORM, formName); gen.getResourceTracker().registerSuppliedResource(res); return res; } /** * Paints a reusable image (previously added as a PostScript form). * @param formName the name of the PostScript form implementing the image * @param targetRect the target rectangle to place the image in * @param gen the PostScript generator * @throws IOException In case of an I/O exception * @deprecated Please use {@link #paintForm(PSResource, Dimension2D, Rectangle2D, PSGenerator)} * instead. */ public static void paintReusableImage( String formName, Rectangle2D targetRect, PSGenerator gen) throws IOException { PSResource form = new PSResource(PSResource.TYPE_FORM, formName); paintForm(form, null, targetRect, gen); } /** * Paints a reusable image (previously added as a PostScript form). * @param form the PostScript form resource implementing the image * @param targetRect the target rectangle to place the image in * @param gen the PostScript generator * @throws IOException In case of an I/O exception * @deprecated Please use {@link #paintForm(PSResource, Dimension2D, Rectangle2D, PSGenerator)} * instead. */ public static void paintForm( PSResource form, Rectangle2D targetRect, PSGenerator gen) throws IOException { paintForm(form, null, targetRect, gen); } /** * Paints a reusable image (previously added as a PostScript form). * @param form the PostScript form resource implementing the image * @param formDimensions the original dimensions of the form * @param targetRect the target rectangle to place the image in * @param gen the PostScript generator * @throws IOException In case of an I/O exception */ public static void paintForm( PSResource form, Dimension2D formDimensions, Rectangle2D targetRect, PSGenerator gen) throws IOException { gen.saveGraphicsState(); translateAndScale(gen, formDimensions, targetRect); gen.writeln(form.getName() + " execform"); gen.getResourceTracker().notifyResourceUsageOnPage(form); gen.restoreGraphicsState(); } private static String getColorSpaceName(ColorSpace colorSpace) { if (colorSpace.getType() == ColorSpace.TYPE_CMYK) { return "/DeviceCMYK"; } else if (colorSpace.getType() == ColorSpace.TYPE_GRAY) { return "/DeviceGray"; } else { return "/DeviceRGB"; } } static void compressAndWriteBitmap(ImageEncoder encoder, PSGenerator gen) throws IOException { OutputStream out = gen.getOutputStream(); out = new ASCII85OutputStream(out); String implicitFilter = encoder.getImplicitFilter(); if (implicitFilter != null) { //nop } else { if (gen.getPSLevel() >= 3) { out = new FlateEncodeOutputStream(out); } else { out = new RunLengthEncodeOutputStream(out); } } encoder.writeTo(out); if (out instanceof Finalizable) { ((Finalizable)out).finalizeStream(); } else { out.flush(); } gen.newLine(); //Just to be sure } /** * Generates commands to modify the current transformation matrix so an image fits * into a given rectangle. * @param gen the PostScript generator * @param imageDimensions the image's dimensions * @param targetRect the target rectangle * @throws IOException if an I/O error occurs */ public static void translateAndScale(PSGenerator gen, Dimension2D imageDimensions, Rectangle2D targetRect) throws IOException { gen.writeln(gen.formatDouble(targetRect.getX()) + " " + gen.formatDouble(targetRect.getY()) + " translate"); if (imageDimensions == null) { imageDimensions = new Dimension(1, 1); } double sx = targetRect.getWidth() / imageDimensions.getWidth(); double sy = targetRect.getHeight() / imageDimensions.getHeight(); if (sx != 1 || sy != 1) { gen.writeln(gen.formatDouble(sx) + " " + gen.formatDouble(sy) + " scale"); } } /** * Extracts a packed RGB integer array of a RenderedImage. * @param img the image * @param startX the starting X coordinate * @param startY the starting Y coordinate * @param w the width of the cropped image * @param h the height of the cropped image * @param rgbArray the prepared integer array to write to * @param offset offset in the target array * @param scansize width of a row in the target array * @return the populated integer array previously passed in as rgbArray parameter */ public static int[] getRGB(RenderedImage img, int startX, int startY, int w, int h, int[] rgbArray, int offset, int scansize) { Raster raster = img.getData(); int yoff = offset; int off; Object data; int nbands = raster.getNumBands(); int dataType = raster.getDataBuffer().getDataType(); switch (dataType) { case DataBuffer.TYPE_BYTE: data = new byte[nbands]; break; case DataBuffer.TYPE_USHORT: data = new short[nbands]; break; case DataBuffer.TYPE_INT: data = new int[nbands]; break; case DataBuffer.TYPE_FLOAT: data = new float[nbands]; break; case DataBuffer.TYPE_DOUBLE: data = new double[nbands]; break; default: throw new IllegalArgumentException("Unknown data buffer type: " + dataType); } if (rgbArray == null) { rgbArray = new int[offset + h * scansize]; } ColorModel colorModel = img.getColorModel(); for (int y = startY; y < startY + h; y++, yoff += scansize) { off = yoff; for (int x = startX; x < startX + w; x++) { rgbArray[off++] = colorModel.getRGB(raster.getDataElements(x, y, data)); } } return rgbArray; } /** * Places an EPS file in the PostScript stream. * @param rawEPS byte array containing the raw EPS data * @param name name for the EPS document * @param x x-coordinate of viewport in points * @param y y-coordinate of viewport in points * @param w width of viewport in points * @param h height of viewport in points * @param bboxx x-coordinate of EPS bounding box in points * @param bboxy y-coordinate of EPS bounding box in points * @param bboxw width of EPS bounding box in points * @param bboxh height of EPS bounding box in points * @param gen the PS generator * @throws IOException in case an I/O error happens during output * @deprecated Please use the variant with the InputStream as parameter */ public static void renderEPS(byte[] rawEPS, String name, float x, float y, float w, float h, float bboxx, float bboxy, float bboxw, float bboxh, PSGenerator gen) throws IOException { renderEPS(new java.io.ByteArrayInputStream(rawEPS), name, new Rectangle2D.Float(x, y, w, h), new Rectangle2D.Float(bboxx, bboxy, bboxw, bboxh), gen); } /** * Places an EPS file in the PostScript stream. * @param in the InputStream that contains the EPS stream * @param name name for the EPS document * @param viewport the viewport in points in which to place the EPS * @param bbox the EPS bounding box in points * @param gen the PS generator * @throws IOException in case an I/O error happens during output */ public static void renderEPS(InputStream in, String name, Rectangle2D viewport, Rectangle2D bbox, PSGenerator gen) throws IOException { gen.getResourceTracker().notifyResourceUsageOnPage(PSProcSets.EPS_PROCSET); gen.writeln("%AXGBeginEPS: " + name); gen.writeln("BeginEPSF"); gen.writeln(gen.formatDouble(viewport.getX()) + " " + gen.formatDouble(viewport.getY()) + " translate"); gen.writeln("0 " + gen.formatDouble(viewport.getHeight()) + " translate"); gen.writeln("1 -1 scale"); double sx = viewport.getWidth() / bbox.getWidth(); double sy = viewport.getHeight() / bbox.getHeight(); if (sx != 1 || sy != 1) { gen.writeln(gen.formatDouble(sx) + " " + gen.formatDouble(sy) + " scale"); } if (bbox.getX() != 0 || bbox.getY() != 0) { gen.writeln(gen.formatDouble(-bbox.getX()) + " " + gen.formatDouble(-bbox.getY()) + " translate"); } gen.writeln(gen.formatDouble(bbox.getX()) + " " + gen.formatDouble(bbox.getY()) + " " + gen.formatDouble(bbox.getWidth()) + " " + gen.formatDouble(bbox.getHeight()) + " re clip"); gen.writeln("newpath"); PSResource res = new PSResource(PSResource.TYPE_FILE, name); gen.getResourceTracker().registerSuppliedResource(res); gen.getResourceTracker().notifyResourceUsageOnPage(res); gen.writeDSCComment(DSCConstants.BEGIN_DOCUMENT, res.getName()); IOUtils.copy(in, gen.getOutputStream()); gen.newLine(); gen.writeDSCComment(DSCConstants.END_DOCUMENT); gen.writeln("EndEPSF"); gen.writeln("%AXGEndEPS"); } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/PSPageDeviceDictionary.java0100644 0000000 0000000 00000007535 13777276623 030677 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: PSPageDeviceDictionary.java 1715211 2015-11-19 16:35:44Z ssteiner $ */ package org.apache.xmlgraphics.ps; import java.util.Map; /** * Postscript page device dictionary object * * This object is used by the postscript renderer to hold postscript page device * values. It can also be used to minimize the number of setpagedevice calls when * DSC compliance is false. */ public class PSPageDeviceDictionary extends PSDictionary { private static final long serialVersionUID = 845943256485806509L; /** * Whether or not the contents of the dictionary are flushed on retrieval */ private boolean flushOnRetrieval; /** * Dictionary content that has not been output/written yet */ private PSDictionary unRetrievedContentDictionary; /** * @param key key with which the specified value is to be associated. * @param value value to be associated with the specified key. * @return the previous value associated with the key or null * @see java.util.Map#put(Object, Object) */ public Object put(Object key, Object value) { Object previousValue = super.put(key, value); if (flushOnRetrieval) { if (previousValue == null || !previousValue.equals(value)) { unRetrievedContentDictionary.put(key, value); } } return previousValue; } public void putAll(Map m) { for (Object x : m.entrySet()) { Map.Entry e = (Map.Entry) x; put(e.getKey(), e.getValue()); } } /** * @see java.util.Map#clear() */ public void clear() { super.clear(); if (unRetrievedContentDictionary != null) { unRetrievedContentDictionary.clear(); } } /** * Returns true if this map contains no key-value mappings. * * @return true if this map contains no key-value mappings. */ public boolean isEmpty() { if (flushOnRetrieval) { return unRetrievedContentDictionary.isEmpty(); } return super.isEmpty(); } /** * The contents of the dictionary are flushed when written * @param flushOnRetrieval boolean value */ public void setFlushOnRetrieval(boolean flushOnRetrieval) { this.flushOnRetrieval = flushOnRetrieval; if (flushOnRetrieval) { unRetrievedContentDictionary = new PSDictionary(); } } /** * Returns a dictionary string with containing all unwritten content note: * unnecessary writes are important as there is a device specific * initgraphics call by the underlying postscript interpreter on every * setpagedevice call which can result in blank pages etc. * * @return unwritten content dictionary string */ public String getContent() { String content; if (flushOnRetrieval) { content = unRetrievedContentDictionary.toString(); unRetrievedContentDictionary.clear(); } else { content = super.toString(); } return content; } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/PSProcSet.java0100644 0000000 0000000 00000004255 13777276623 026230 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: PSProcSet.java 1598621 2014-05-30 14:55:00Z ssteiner $ */ package org.apache.xmlgraphics.ps; /** * PSResource subclass that represents a ProcSet resource. */ public class PSProcSet extends PSResource { private float version; private int revision; /** * Creates a new instance. * @param name name of the resource */ public PSProcSet(String name) { this(name, 1.0f, 0); } /** * Creates a new instance. * @param name name of the resource * @param version version of the resource * @param revision revision of the resource */ public PSProcSet(String name, float version, int revision) { super(TYPE_PROCSET, name); this.version = version; this.revision = revision; } /** @return the version */ public float getVersion() { return version; } /** @return the revision */ public int getRevision() { return revision; } /** @return the <resource> specification as defined in DSC v3.0 spec. */ public String getResourceSpecification() { StringBuffer sb = new StringBuffer(); sb.append(getType()).append(" ").append(PSGenerator.convertStringToDSC(getName())); sb.append(" ").append(PSGenerator.convertRealToDSC(getVersion())); sb.append(" ").append(Integer.toString(getRevision())); return sb.toString(); } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/PSProcSets.java0100644 0000000 0000000 00000036172 13777276623 026416 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: PSProcSets.java 1804124 2017-08-04 14:13:54Z ssteiner $ */ package org.apache.xmlgraphics.ps; import java.io.IOException; import java.util.Collections; import java.util.Map; /** * This class defines the basic resources (procsets) used by the Apache XML Graphics project. * * @version $Id: PSProcSets.java 1804124 2017-08-04 14:13:54Z ssteiner $ */ public final class PSProcSets { private PSProcSets() { } /** the standard procset for the XML Graphics project */ public static final PSResource STD_PROCSET; /** the EPS procset for the XML Graphics project */ public static final PSResource EPS_PROCSET = new EPSProcSet(); /** the standard command map matching the {@link #STD_PROCSET}. */ public static final PSCommandMap STD_COMMAND_MAP; static { StdProcSet stdProcSet = new StdProcSet(); STD_PROCSET = stdProcSet; STD_COMMAND_MAP = stdProcSet; } /** * The standard procset used by XML Graphics Commons. */ private static class StdProcSet extends PSProcSet implements PSCommandMap { /** A Map of standard shorthand macros defined in the {@link StdProcSet}. */ private static final Map STANDARD_MACROS; static { Map macros = new java.util.HashMap(); macros.put("moveto", "M"); macros.put("rmoveto", "RM"); macros.put("curveto", "C"); macros.put("lineto", "L"); macros.put("show", "t"); macros.put("ashow", "A"); macros.put("closepath", "cp"); macros.put("setrgbcolor", "RC"); macros.put("setgray", "GC"); macros.put("setcmykcolor", "CC"); macros.put("newpath", "N"); macros.put("setmiterlimit", "ML"); macros.put("setlinewidth", "LC"); macros.put("setlinewidth", "LW"); macros.put("setlinejoin", "LJ"); macros.put("grestore", "GR"); macros.put("gsave", "GS"); macros.put("fill", "f"); macros.put("stroke", "S"); macros.put("concat", "CT"); STANDARD_MACROS = Collections.unmodifiableMap(macros); } public StdProcSet() { super("Apache XML Graphics Std ProcSet", 1.2f, 0); } public void writeTo(PSGenerator gen) throws IOException { gen.writeDSCComment(DSCConstants.BEGIN_RESOURCE, new Object[] {TYPE_PROCSET, getName(), Float.toString(getVersion()), Integer.toString(getRevision())}); gen.writeDSCComment(DSCConstants.VERSION, new Object[] {Float.toString(getVersion()), Integer.toString(getRevision())}); gen.writeDSCComment(DSCConstants.COPYRIGHT, "Copyright 2001-2003,2010 " + "The Apache Software Foundation. " + "License terms: http://www.apache.org/licenses/LICENSE-2.0"); gen.writeDSCComment(DSCConstants.TITLE, "Basic set of procedures used by the XML Graphics project (Batik and FOP)"); gen.writeln("/bd{bind def}bind def"); gen.writeln("/ld{load def}bd"); for (Object o : STANDARD_MACROS.entrySet()) { Map.Entry entry = (Map.Entry) o; gen.writeln("/" + entry.getValue() + "/" + entry.getKey() + " ld"); } gen.writeln("/re {4 2 roll M"); //define rectangle gen.writeln("1 index 0 rlineto"); gen.writeln("0 exch rlineto"); gen.writeln("neg 0 rlineto"); gen.writeln("cp } bd"); gen.writeln("/_ctm matrix def"); //Holds the current matrix gen.writeln("/_tm matrix def"); //BT: save currentmatrix, set _tm to identitymatrix and move to 0/0 gen.writeln("/BT { _ctm currentmatrix pop matrix _tm copy pop 0 0 moveto } bd"); //ET: restore last currentmatrix gen.writeln("/ET { _ctm setmatrix } bd"); gen.writeln("/iTm { _ctm setmatrix _tm concat } bd"); gen.writeln("/Tm { _tm astore pop iTm 0 0 moveto } bd"); gen.writeln("/ux 0.0 def"); gen.writeln("/uy 0.0 def"); // F gen.writeln("/F {"); gen.writeln(" /Tp exch def"); // gen.writeln(" currentdict exch get"); gen.writeln(" /Tf exch def"); gen.writeln(" Tf findfont Tp scalefont setfont"); gen.writeln(" /cf Tf def /cs Tp def"); gen.writeln("} bd"); gen.writeln("/ULS {currentpoint /uy exch def /ux exch def} bd"); gen.writeln("/ULE {"); gen.writeln(" /Tcx currentpoint pop def"); gen.writeln(" gsave"); gen.writeln(" newpath"); gen.writeln(" cf findfont cs scalefont dup"); gen.writeln(" /FontMatrix get 0 get /Ts exch def /FontInfo get dup"); gen.writeln(" /UnderlinePosition get Ts mul /To exch def"); gen.writeln(" /UnderlineThickness get Ts mul /Tt exch def"); gen.writeln(" ux uy To add moveto Tcx uy To add lineto"); gen.writeln(" Tt setlinewidth stroke"); gen.writeln(" grestore"); gen.writeln("} bd"); gen.writeln("/OLE {"); gen.writeln(" /Tcx currentpoint pop def"); gen.writeln(" gsave"); gen.writeln(" newpath"); gen.writeln(" cf findfont cs scalefont dup"); gen.writeln(" /FontMatrix get 0 get /Ts exch def /FontInfo get dup"); gen.writeln(" /UnderlinePosition get Ts mul /To exch def"); gen.writeln(" /UnderlineThickness get Ts mul /Tt exch def"); gen.writeln(" ux uy To add cs add moveto Tcx uy To add cs add lineto"); gen.writeln(" Tt setlinewidth stroke"); gen.writeln(" grestore"); gen.writeln("} bd"); gen.writeln("/SOE {"); gen.writeln(" /Tcx currentpoint pop def"); gen.writeln(" gsave"); gen.writeln(" newpath"); gen.writeln(" cf findfont cs scalefont dup"); gen.writeln(" /FontMatrix get 0 get /Ts exch def /FontInfo get dup"); gen.writeln(" /UnderlinePosition get Ts mul /To exch def"); gen.writeln(" /UnderlineThickness get Ts mul /Tt exch def"); gen.writeln(" ux uy To add cs 10 mul 26 idiv add moveto " + "Tcx uy To add cs 10 mul 26 idiv add lineto"); gen.writeln(" Tt setlinewidth stroke"); gen.writeln(" grestore"); gen.writeln("} bd"); gen.writeln("/QT {"); gen.writeln("/Y22 exch store"); gen.writeln("/X22 exch store"); gen.writeln("/Y21 exch store"); gen.writeln("/X21 exch store"); gen.writeln("currentpoint"); gen.writeln("/Y21 load 2 mul add 3 div exch"); gen.writeln("/X21 load 2 mul add 3 div exch"); gen.writeln("/X21 load 2 mul /X22 load add 3 div"); gen.writeln("/Y21 load 2 mul /Y22 load add 3 div"); gen.writeln("/X22 load /Y22 load curveto"); gen.writeln("} bd"); gen.writeln("/SSPD {"); gen.writeln("dup length /d exch dict def"); gen.writeln("{"); gen.writeln("/v exch def"); gen.writeln("/k exch def"); gen.writeln("currentpagedevice k known {"); gen.writeln("/cpdv currentpagedevice k get def"); gen.writeln("v cpdv ne {"); gen.writeln("/upd false def"); gen.writeln("/nullv v type /nulltype eq def"); gen.writeln("/nullcpdv cpdv type /nulltype eq def"); gen.writeln("nullv nullcpdv or"); gen.writeln("{"); gen.writeln("/upd true def"); gen.writeln("} {"); gen.writeln("/sametype v type cpdv type eq def"); gen.writeln("sametype {"); gen.writeln("v type /arraytype eq {"); gen.writeln("/vlen v length def"); gen.writeln("/cpdvlen cpdv length def"); gen.writeln("vlen cpdvlen eq {"); gen.writeln("0 1 vlen 1 sub {"); gen.writeln("/i exch def"); gen.writeln("/obj v i get def"); gen.writeln("/cpdobj cpdv i get def"); gen.writeln("obj cpdobj ne {"); gen.writeln("/upd true def"); gen.writeln("exit"); gen.writeln("} if"); gen.writeln("} for"); gen.writeln("} {"); gen.writeln("/upd true def"); gen.writeln("} ifelse"); gen.writeln("} {"); gen.writeln("v type /dicttype eq {"); gen.writeln("v {"); gen.writeln("/dv exch def"); gen.writeln("/dk exch def"); gen.writeln("/cpddv cpdv dk get def"); gen.writeln("dv cpddv ne {"); gen.writeln("/upd true def"); gen.writeln("exit"); gen.writeln("} if"); gen.writeln("} forall"); gen.writeln("} {"); gen.writeln("/upd true def"); gen.writeln("} ifelse"); gen.writeln("} ifelse"); gen.writeln("} if"); gen.writeln("} ifelse"); gen.writeln("upd true eq {"); gen.writeln("d k v put"); gen.writeln("} if"); gen.writeln("} if"); gen.writeln("} if"); gen.writeln("} forall"); gen.writeln("d length 0 gt {"); gen.writeln("d setpagedevice"); gen.writeln("} if"); gen.writeln("} bd"); gen.writeln("/RE { % /NewFontName [NewEncodingArray] /FontName RE -"); gen.writeln(" findfont dup length dict begin"); gen.writeln(" {"); gen.writeln(" 1 index /FID ne"); gen.writeln(" {def} {pop pop} ifelse"); gen.writeln(" } forall"); gen.writeln(" /Encoding exch def"); gen.writeln(" /FontName 1 index def"); gen.writeln(" currentdict definefont pop"); gen.writeln(" end"); gen.writeln("} bind def"); gen.writeDSCComment(DSCConstants.END_RESOURCE); gen.getResourceTracker().registerSuppliedResource(this); } /** {@inheritDoc} */ public String mapCommand(String command) { String mapped = (String)STANDARD_MACROS.get(command); return (mapped != null ? mapped : command); } } private static class EPSProcSet extends PSProcSet { public EPSProcSet() { super("Apache XML Graphics EPS ProcSet", 1.0f, 0); } public void writeTo(PSGenerator gen) throws IOException { gen.writeDSCComment(DSCConstants.BEGIN_RESOURCE, new Object[] {TYPE_PROCSET, getName(), Float.toString(getVersion()), Integer.toString(getRevision())}); gen.writeDSCComment(DSCConstants.VERSION, new Object[] {Float.toString(getVersion()), Integer.toString(getRevision())}); gen.writeDSCComment(DSCConstants.COPYRIGHT, "Copyright 2002-2003 " + "The Apache Software Foundation. " + "License terms: http://www.apache.org/licenses/LICENSE-2.0"); gen.writeDSCComment(DSCConstants.TITLE, "EPS procedures used by the Apache XML Graphics project (Batik and FOP)"); gen.writeln("/BeginEPSF { %def"); gen.writeln("/b4_Inc_state save def % Save state for cleanup"); gen.writeln("/dict_count countdictstack def % Count objects on dict stack"); gen.writeln("/op_count count 1 sub def % Count objects on operand stack"); gen.writeln("userdict begin % Push userdict on dict stack"); gen.writeln("/showpage { } def % Redefine showpage, { } = null proc"); gen.writeln("0 setgray 0 setlinecap % Prepare graphics state"); gen.writeln("1 setlinewidth 0 setlinejoin"); gen.writeln("10 setmiterlimit [ ] 0 setdash newpath"); gen.writeln("/languagelevel where % If level not equal to 1 then"); gen.writeln("{pop languagelevel % set strokeadjust and"); gen.writeln("1 ne % overprint to their defaults."); gen.writeln("{false setstrokeadjust false setoverprint"); gen.writeln("} if"); gen.writeln("} if"); gen.writeln("} bd"); gen.writeln("/EndEPSF { %def"); gen.writeln("count op_count sub {pop} repeat % Clean up stacks"); gen.writeln("countdictstack dict_count sub {end} repeat"); gen.writeln("b4_Inc_state restore"); gen.writeln("} bd"); gen.writeDSCComment(DSCConstants.END_RESOURCE); gen.getResourceTracker().registerSuppliedResource(this); } } /** * Generates a resource defining standard procset with operations used by the XML Graphics * project. * @param gen PSGenerator to use for output * @throws IOException In case of an I/O problem */ public static void writeStdProcSet(PSGenerator gen) throws IOException { ((StdProcSet)STD_PROCSET).writeTo(gen); } /** * Generates a resource defining standard procset with operations used by the XML Graphics * project. * @param gen PSGenerator to use for output * @throws IOException In case of an I/O problem * @deprecated Use writeStdProcSet() instead. */ public static void writeFOPStdProcSet(PSGenerator gen) throws IOException { writeStdProcSet(gen); } /** * Generates a resource defining a procset for including EPS graphics. * @param gen PSGenerator to use for output * @throws IOException In case of an I/O problem */ public static void writeEPSProcSet(PSGenerator gen) throws IOException { ((EPSProcSet)EPS_PROCSET).writeTo(gen); } /** * Generates a resource defining a procset for including EPS graphics. * @param gen PSGenerator to use for output * @throws IOException In case of an I/O problem * @deprecated Use writeEPSProcSet() instead. */ public static void writeFOPEPSProcSet(PSGenerator gen) throws IOException { writeEPSProcSet(gen); } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/PSResource.java0100644 0000000 0000000 00000006477 13777276623 026450 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: PSResource.java 1598621 2014-05-30 14:55:00Z ssteiner $ */ package org.apache.xmlgraphics.ps; /** * Represents a PostScript resource (file, font, procset etc.). */ public class PSResource implements Comparable { /** a file resource */ public static final String TYPE_FILE = "file"; /** a font resource */ public static final String TYPE_FONT = "font"; /** a procset resource */ public static final String TYPE_PROCSET = "procset"; /** a procset resource */ public static final String TYPE_PATTERN = "pattern"; /** a procset resource */ public static final String TYPE_FORM = "form"; /** a procset resource */ public static final String TYPE_ENCODING = "encoding"; /** A CMap resource. */ public static final String TYPE_CMAP = "cmap"; /** A CIDFont resource. */ public static final String TYPE_CIDFONT = "cidfont"; private String type; private String name; /** * Main constructor * @param type type of the resource * @param name name of the resource */ public PSResource(String type, String name) { this.type = type; this.name = name; } /** @return the type of the resource */ public String getType() { return this.type; } /** @return the name of the resource */ public String getName() { return this.name; } /** @return the <resource> specification as defined in DSC v3.0 spec. */ public String getResourceSpecification() { StringBuffer sb = new StringBuffer(); sb.append(getType()).append(" ").append(PSGenerator.convertStringToDSC(getName())); return sb.toString(); } /** {@inheritDoc} */ public boolean equals(Object obj) { if (obj == this) { return true; } else if (obj instanceof PSResource) { PSResource other = (PSResource)obj; return other.toString().equals(toString()); } else { return false; } } /** {@inheritDoc} */ public int hashCode() { return toString().hashCode(); } /** {@inheritDoc} */ public int compareTo(Object o) { PSResource other = (PSResource)o; if (this == other) { return 0; } int result = this.getType().compareTo(other.getType()); if (result == 0) { result = this.getName().compareTo(other.getName()); } return result; } /** {@inheritDoc} */ public String toString() { return getResourceSpecification(); } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/PSState.java0100644 0000000 0000000 00000016515 13777276623 025733 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: PSState.java 1804124 2017-08-04 14:13:54Z ssteiner $ */ package org.apache.xmlgraphics.ps; import java.awt.Color; import java.awt.geom.AffineTransform; import java.io.IOException; import java.io.Serializable; import java.util.List; import org.apache.xmlgraphics.java2d.color.ColorUtil; /** * This class holds the current state of the PostScript interpreter. * * @version $Id: PSState.java 1804124 2017-08-04 14:13:54Z ssteiner $ */ public class PSState implements Serializable { /** Default for setdash */ public static final String DEFAULT_DASH = "[] 0"; /** Default color in PostScript */ public static final Color DEFAULT_RGB_COLOR = Color.black; private static final long serialVersionUID = -3862731539801753248L; private AffineTransform transform = new AffineTransform(); private List transformConcatList = new java.util.ArrayList(); private int linecap; private int linejoin; private float miterLimit; private double linewidth = 1.0f; private String dashpattern = DEFAULT_DASH; private Color color = DEFAULT_RGB_COLOR; //Font state private String fontname; private float fontsize; /** * Default constructor */ public PSState() { //nop } /** * Copy constructor * @param org the original to copy from * @param copyTransforms true if the list of matrix concats should be cloned, too */ public PSState(PSState org, boolean copyTransforms) { this.transform = (AffineTransform)org.transform.clone(); if (copyTransforms) { this.transformConcatList.addAll(org.transformConcatList); } this.linecap = org.linecap; this.linejoin = org.linejoin; this.miterLimit = org.miterLimit; this.linewidth = org.linewidth; this.dashpattern = org.dashpattern; this.color = org.color; this.fontname = org.fontname; this.fontsize = org.fontsize; } /** * Returns the transform. * @return the current transformation matrix */ public AffineTransform getTransform() { return this.transform; } /** * Check the current transform. * The transform for the current state is the combination of all * transforms in the current state. The parameter is compared * against this current transform. * * @param tf the transform the check against * @return true if the new transform is different then the current transform */ public boolean checkTransform(AffineTransform tf) { return !tf.equals(this.transform); } /** * Concats the given transformation matrix with the current one. * @param transform The new transformation matrix */ public void concatMatrix(AffineTransform transform) { this.transformConcatList.add(transform); this.transform.concatenate(transform); } /** * Establishes the specified line cap. * @param value line cap (0, 1 or 2) as defined by the setlinecap command * @return true if the line cap changed compared to the previous setting */ public boolean useLineCap(int value) { if (linecap != value) { linecap = value; return true; } else { return false; } } /** * Establishes the specified line join. * @param value line join (0, 1 or 2) as defined by the setlinejoin command * @return true if the line join changed compared to the previous setting */ public boolean useLineJoin(int value) { if (linejoin != value) { linejoin = value; return true; } else { return false; } } /** * Establishes the specified miter limit. * @param value the miter limit as defined by the setmiterlimit command * @return true if the miter limit changed compared to the previous setting */ public boolean useMiterLimit(float value) { if (miterLimit != value) { miterLimit = value; return true; } else { return false; } } /** * Establishes the specified line width. * @param value line width as defined by the setlinewidth command * @return true if the line width changed compared to the previous setting */ public boolean useLineWidth(double value) { if (linewidth != value) { linewidth = value; return true; } else { return false; } } /** * Establishes the specified dash. * @param pattern dash pattern as defined by the setdash command * @return true if the dash pattern changed compared to the previous setting */ public boolean useDash(String pattern) { if (!dashpattern.equals(pattern)) { dashpattern = pattern; return true; } else { return false; } } /** * Establishes the specified color (RGB). * @param value color as defined by the setrgbcolor command * @return true if the color changed compared to the previous setting */ public boolean useColor(Color value) { if (!ColorUtil.isSameColor(color, value)) { color = value; return true; } else { return false; } } /** * Establishes the specified font and size. * @param name name of the font for the "F" command (see FOP Std Proc Set) * @param size size of the font * @return true if the font changed compared to the previous setting */ public boolean useFont(String name, float size) { if (name == null) { throw new NullPointerException("font name must not be null"); } if (fontname == null || !fontname.equals(name) || fontsize != size) { fontname = name; fontsize = size; return true; } else { return false; } } /** * Reestablishes the graphics state represented by this instance by issueing the * necessary commands. * @param gen The generator to use for output * @exception IOException In case of an I/O problem */ public void reestablish(PSGenerator gen) throws IOException { for (Object aTransformConcatList : transformConcatList) { gen.concatMatrix((AffineTransform) aTransformConcatList); } gen.useLineCap(linecap); gen.useLineWidth(linewidth); gen.useDash(dashpattern); gen.useColor(color); if (fontname != null) { gen.useFont(fontname, fontsize); } } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/dsc/DSCCommentFactory.java0100644 0000000 0000000 00000012147 13777276623 030442 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: DSCCommentFactory.java 1780540 2017-01-27 11:10:50Z ssteiner $ */ package org.apache.xmlgraphics.ps.dsc; import java.lang.reflect.InvocationTargetException; import java.util.Map; import org.apache.xmlgraphics.ps.DSCConstants; import org.apache.xmlgraphics.ps.dsc.events.DSCComment; import org.apache.xmlgraphics.ps.dsc.events.DSCCommentBeginDocument; import org.apache.xmlgraphics.ps.dsc.events.DSCCommentBeginResource; import org.apache.xmlgraphics.ps.dsc.events.DSCCommentBoundingBox; import org.apache.xmlgraphics.ps.dsc.events.DSCCommentDocumentNeededResources; import org.apache.xmlgraphics.ps.dsc.events.DSCCommentDocumentSuppliedResources; import org.apache.xmlgraphics.ps.dsc.events.DSCCommentEndComments; import org.apache.xmlgraphics.ps.dsc.events.DSCCommentEndOfFile; import org.apache.xmlgraphics.ps.dsc.events.DSCCommentHiResBoundingBox; import org.apache.xmlgraphics.ps.dsc.events.DSCCommentIncludeResource; import org.apache.xmlgraphics.ps.dsc.events.DSCCommentLanguageLevel; import org.apache.xmlgraphics.ps.dsc.events.DSCCommentPage; import org.apache.xmlgraphics.ps.dsc.events.DSCCommentPageBoundingBox; import org.apache.xmlgraphics.ps.dsc.events.DSCCommentPageHiResBoundingBox; import org.apache.xmlgraphics.ps.dsc.events.DSCCommentPageResources; import org.apache.xmlgraphics.ps.dsc.events.DSCCommentPages; import org.apache.xmlgraphics.ps.dsc.events.DSCCommentTitle; /** * Factory for DSCComment subclasses. */ public final class DSCCommentFactory { private DSCCommentFactory() { } private static final Map DSC_FACTORIES = new java.util.HashMap(); static { DSC_FACTORIES.put(DSCConstants.END_COMMENTS, DSCCommentEndComments.class); DSC_FACTORIES.put(DSCConstants.BEGIN_RESOURCE, DSCCommentBeginResource.class); DSC_FACTORIES.put(DSCConstants.INCLUDE_RESOURCE, DSCCommentIncludeResource.class); DSC_FACTORIES.put(DSCConstants.PAGE_RESOURCES, DSCCommentPageResources.class); DSC_FACTORIES.put(DSCConstants.BEGIN_DOCUMENT, DSCCommentBeginDocument.class); DSC_FACTORIES.put(DSCConstants.PAGE, DSCCommentPage.class); DSC_FACTORIES.put(DSCConstants.PAGES, DSCCommentPages.class); DSC_FACTORIES.put(DSCConstants.BBOX, DSCCommentBoundingBox.class); DSC_FACTORIES.put(DSCConstants.HIRES_BBOX, DSCCommentHiResBoundingBox.class); DSC_FACTORIES.put(DSCConstants.PAGE_BBOX, DSCCommentPageBoundingBox.class); DSC_FACTORIES.put(DSCConstants.PAGE_HIRES_BBOX, DSCCommentPageHiResBoundingBox.class); DSC_FACTORIES.put(DSCConstants.LANGUAGE_LEVEL, DSCCommentLanguageLevel.class); DSC_FACTORIES.put(DSCConstants.DOCUMENT_NEEDED_RESOURCES, DSCCommentDocumentNeededResources.class); DSC_FACTORIES.put(DSCConstants.DOCUMENT_SUPPLIED_RESOURCES, DSCCommentDocumentSuppliedResources.class); DSC_FACTORIES.put(DSCConstants.TITLE, DSCCommentTitle.class); DSC_FACTORIES.put(DSCConstants.EOF, DSCCommentEndOfFile.class); //TODO Add additional implementations as needed } /** * Creates and returns new instances for DSC comments with a given name. * @param name the name of the DSCComment (without the "%%" prefix) * @return the new instance or null if no particular subclass registered for the given * DSC comment. */ public static DSCComment createDSCCommentFor(String name) { Class clazz = (Class)DSC_FACTORIES.get(name); if (clazz == null) { return null; } try { return (DSCComment)clazz.getDeclaredConstructor().newInstance(); } catch (InstantiationException e) { throw new RuntimeException("Error instantiating instance for '" + name + "': " + e.getMessage()); } catch (IllegalAccessException e) { throw new RuntimeException("Illegal Access error while instantiating instance for '" + name + "': " + e.getMessage()); } catch (NoSuchMethodException e) { throw new RuntimeException(e); } catch (InvocationTargetException e) { throw new RuntimeException(e); } } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/dsc/DSCException.java0100644 0000000 0000000 00000002401 13777276623 027436 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: DSCException.java 750418 2009-03-05 11:03:54Z vhennebert $ */ package org.apache.xmlgraphics.ps.dsc; /** * Exception to signal problems while parsing a supposedly DSC-conformant file. */ public class DSCException extends Exception { private static final long serialVersionUID = -1549406547978409615L; /** * Creates a new DSCException. * @param msg the exception message */ public DSCException(String msg) { super(msg); } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/dsc/DSCFilter.java0100644 0000000 0000000 00000002423 13777276623 026731 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: DSCFilter.java 750418 2009-03-05 11:03:54Z vhennebert $ */ package org.apache.xmlgraphics.ps.dsc; import org.apache.xmlgraphics.ps.dsc.events.DSCEvent; /** * Filter interface for DSC events used by the DSC parser. */ public interface DSCFilter { /** * Indicates whether a particular event is acceptable or if it should be skipped/ignored. * @param event the DSC event * @return true if the event should be accepted */ boolean accept(DSCEvent event); } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/dsc/DSCHandler.java0100644 0000000 0000000 00000004667 13777276623 027075 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: DSCHandler.java 1345683 2012-06-03 14:50:33Z gadams $ */ package org.apache.xmlgraphics.ps.dsc; import java.io.IOException; import org.apache.xmlgraphics.ps.dsc.events.DSCComment; /** * Interface containing events generated by the DSCParser. Applications can implement this * interface to react to certain events. */ public interface DSCHandler { /** * Called as a new PostScript file starts. * @param header the first line of the DSC-compliant file * @throws IOException In case of an I/O error */ void startDocument(String header) throws IOException; /** * Called when the PostScript file is fully processed, i.e. after the %%EOF comment. * @throws IOException In case of an I/O error */ void endDocument() throws IOException; /** * Called for each standard DSC comment. The classes passed to this method may be simple * DSCComment classes or special subclasses for some of the DSC comments. * @param comment the DSC comment * @throws IOException In case of an I/O error */ void handleDSCComment(DSCComment comment) throws IOException; /** * Called for a normal line of PostScript code. * @param line the line of code * @throws IOException In case of an I/O error */ void line(String line) throws IOException; /** * Called for any line containing a full-line PostScript comment. This is also called for * custom comments following the extension mechanism of the DSC specification. * @param comment the comment line * @throws IOException In case of an I/O error */ void comment(String comment) throws IOException; } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/dsc/DSCListener.java0100644 0000000 0000000 00000003372 13777276623 027275 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: DSCListener.java 727407 2008-12-17 15:05:45Z jeremias $ */ package org.apache.xmlgraphics.ps.dsc; import java.io.IOException; import org.apache.xmlgraphics.ps.dsc.events.DSCEvent; /** * Listener interface for the DSC parser. It can be used to be notified */ public interface DSCListener { /** * Called for each DSC event. You can call methods on the DSC parser to skip comments, * for example. But implementations need to be good citizens and take into account that * multiple listeners can be active at the same time and that they might interfere with * other listeners. When returning from the call, state information such as filters should * be restored. * @param event the DSC event * @param parser the DSC parser * @throws IOException if an I/O error occurs * @throws DSCException if a DSC-specific error occurs */ void processEvent(DSCEvent event, DSCParser parser) throws IOException, DSCException; } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/dsc/DSCParser.java0100644 0000000 0000000 00000042056 13777276623 026746 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: DSCParser.java 1804124 2017-08-04 14:13:54Z ssteiner $ */ package org.apache.xmlgraphics.ps.dsc; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.util.List; import java.util.NoSuchElementException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.xmlgraphics.ps.DSCConstants; import org.apache.xmlgraphics.ps.PSGenerator; import org.apache.xmlgraphics.ps.dsc.events.DSCAtend; import org.apache.xmlgraphics.ps.dsc.events.DSCComment; import org.apache.xmlgraphics.ps.dsc.events.DSCEvent; import org.apache.xmlgraphics.ps.dsc.events.DSCHeaderComment; import org.apache.xmlgraphics.ps.dsc.events.PostScriptComment; import org.apache.xmlgraphics.ps.dsc.events.PostScriptLine; import org.apache.xmlgraphics.ps.dsc.events.UnparsedDSCComment; import org.apache.xmlgraphics.ps.dsc.tools.DSCTools; /** * Parser for DSC-compliant PostScript files (DSC = Document Structuring Conventions). The parser * is implemented as a pull parser but has the ability to act as a push parser through the * DSCHandler interface. */ public class DSCParser implements DSCParserConstants { private static final Log LOG = LogFactory.getLog(DSCParser.class); private InputStream in; private BufferedReader reader; private boolean eofFound; private boolean checkEOF = true; private DSCEvent currentEvent; private DSCEvent nextEvent; private DSCListener nestedDocumentHandler; private DSCListener filterListener; private List listeners; private boolean listenersDisabled; /** * Creates a new DSC parser. * @param in InputStream to read the PostScript file from * (the stream is not closed by this class, the caller is responsible for that) * @throws IOException In case of an I/O error * @throws DSCException In case of a violation of the DSC spec */ public DSCParser(InputStream in) throws IOException, DSCException { if (in.markSupported()) { this.in = in; } else { //Decorate for better performance this.in = new java.io.BufferedInputStream(this.in); } String encoding = "US-ASCII"; try { this.reader = new java.io.BufferedReader( new java.io.InputStreamReader(this.in, encoding)); } catch (UnsupportedEncodingException e) { throw new RuntimeException("Incompatible VM! " + e.getMessage()); } parseNext(); } /** * Returns the InputStream the PostScript code is read from. * @return the InputStream the PostScript code is read from */ public InputStream getInputStream() { return this.in; } /** * This method is used to write out warning messages for the parsing process. Subclass to * override this method. The default implementation writes to logger. * @param msg the warning message */ protected void warn(String msg) { LOG.warn(msg); } /** * Reads one line from the input file * @return the line or null if there are no more lines * @throws IOException In case of an I/O error * @throws DSCException In case of a violation of the DSC spec */ protected String readLine() throws IOException, DSCException { String line; line = this.reader.readLine(); checkLine(line); return line; } private void checkLine(String line) throws DSCException { if (line == null) { if (!eofFound) { throw new DSCException("%%EOF not found. File is not well-formed."); } } else if (line.length() > 255) { warn("Line longer than 255 characters. This file is not fully PostScript conforming."); } } private boolean isWhitespace(char c) { return c == ' ' || c == '\t'; } private DSCComment parseDSCLine(String line) throws IOException, DSCException { int colon = line.indexOf(':'); String name; StringBuilder value = new StringBuilder(); if (colon > 0) { name = line.substring(2, colon); int startOfValue = colon + 1; if (startOfValue < line.length()) { if (isWhitespace(line.charAt(startOfValue))) { startOfValue++; } value = new StringBuilder(line.substring(startOfValue).trim()); if (value.toString().equals(DSCConstants.ATEND.toString())) { return new DSCAtend(name); } } String nextLine; while (true) { this.reader.mark(512); nextLine = readLine(); if (nextLine == null) { break; } else if (!nextLine.startsWith("%%+")) { break; } value.append(nextLine.substring(3)); } this.reader.reset(); } else { name = line.substring(2); return parseDSCComment(name, null); } return parseDSCComment(name, value.toString()); } private DSCComment parseDSCComment(String name, String value) { DSCComment parsed = DSCCommentFactory.createDSCCommentFor(name); if (parsed != null) { try { parsed.parseValue(value); return parsed; } catch (Exception e) { //ignore and fall back to unparsed DSC comment } } UnparsedDSCComment unparsed = new UnparsedDSCComment(name); unparsed.parseValue(value); return unparsed; } /** * Starts the parser in push parsing mode sending events to the DSCHandler instance. * @param handler the DSCHandler instance to send the events to * @throws IOException In case of an I/O error * @throws DSCException In case of a violation of the DSC spec */ public void parse(DSCHandler handler) throws IOException, DSCException { DSCHeaderComment header = DSCTools.checkAndSkipDSC30Header(this); handler.startDocument("%!" + header.getComment()); DSCEvent event; while (hasNext()) { event = nextEvent(); switch (event.getEventType()) { case HEADER_COMMENT: handler.startDocument("%!" + ((DSCHeaderComment)event).getComment()); break; case DSC_COMMENT: handler.handleDSCComment(event.asDSCComment()); break; case COMMENT: handler.comment(((PostScriptComment)event).getComment()); break; case LINE: handler.line(getLine()); break; case EOF: handler.endDocument(); break; default: throw new IllegalStateException("Illegal event type: " + event.getEventType()); } } } /** * Indicates whether there are additional items. * @return true if there are additonal items, false if the end of the file has been reached */ public boolean hasNext() { return (this.nextEvent != null); } /** * Steps to the next item indicating the type of event. * @return the type of event (See {@link DSCParserConstants}) * @throws IOException In case of an I/O error * @throws DSCException In case of a violation of the DSC spec * @throws NoSuchElementException If an attempt was made to advance beyond the end of the file */ public int next() throws IOException, DSCException { if (hasNext()) { this.currentEvent = nextEvent; parseNext(); processListeners(); return this.currentEvent.getEventType(); } else { throw new NoSuchElementException("There are no more events"); } } private void processListeners() throws IOException, DSCException { if (isListenersDisabled()) { return; } if (this.filterListener != null) { //Filter always comes first this.filterListener.processEvent(this.currentEvent, this); } if (this.listeners != null) { for (Object listener : this.listeners) { ((DSCListener) listener).processEvent(this.currentEvent, this); } } } /** * Steps to the next item returning the new event. * @return the new event * @throws IOException In case of an I/O error * @throws DSCException In case of a violation of the DSC spec */ public DSCEvent nextEvent() throws IOException, DSCException { next(); return getCurrentEvent(); } /** * Returns the current event. * @return the current event */ public DSCEvent getCurrentEvent() { return this.currentEvent; } /** * Returns the next event without moving the cursor to the next event. * @return the next event */ public DSCEvent peek() { return this.nextEvent; } /** * Parses the next event. * @throws IOException In case of an I/O error * @throws DSCException In case of a violation of the DSC spec */ protected void parseNext() throws IOException, DSCException { String line = readLine(); if (line != null) { if (isCheckEOF() && eofFound && (line.length() > 0)) { throw new DSCException("Content found after EOF"); } if (line.startsWith("%%")) { DSCComment comment = parseDSCLine(line); if (comment.getEventType() == EOF) { this.eofFound = true; } this.nextEvent = comment; } else if (line.startsWith("%!")) { this.nextEvent = new DSCHeaderComment(line.substring(2)); } else if (line.startsWith("%")) { this.nextEvent = new PostScriptComment(line.substring(1)); } else { this.nextEvent = new PostScriptLine(line); } } else { this.nextEvent = null; } } /** * Returns the current PostScript line. * @return the current PostScript line * @throws IllegalStateException if the current event is not a normal PostScript line */ public String getLine() { if (this.currentEvent.getEventType() == LINE) { return ((PostScriptLine)this.currentEvent).getLine(); } else { throw new IllegalStateException("Current event is not a PostScript line"); } } /** * Advances to the next DSC comment with the given name. * @param name the name of the DSC comment * @return the requested DSC comment or null if the end of the file is reached * @throws IOException In case of an I/O error * @throws DSCException In case of a violation of the DSC spec */ public DSCComment nextDSCComment(String name) throws IOException, DSCException { return nextDSCComment(name, null); } /** * Advances to the next DSC comment with the given name. * @param name the name of the DSC comment * @param gen PSGenerator to pass the skipped events though to * @return the requested DSC comment or null if the end of the file is reached * @throws IOException In case of an I/O error * @throws DSCException In case of a violation of the DSC spec */ public DSCComment nextDSCComment(String name, PSGenerator gen) throws IOException, DSCException { while (hasNext()) { DSCEvent event = nextEvent(); if (event.isDSCComment()) { DSCComment comment = event.asDSCComment(); if (name.equals(comment.getName())) { return comment; } } if (gen != null) { event.generate(gen); //Pipe through to PSGenerator } } return null; } /** * Advances to the next PostScript comment with the given prefix. This is used to find * comments following the DSC extension mechanism. *

    * Example: To find FOP's custom comments, pass in "FOP" as a prefix. This will find comments * like "%FOPFontSetup". * @param prefix the prefix of the extension comment * @param gen PSGenerator to pass the skipped events though to * @return the requested PostScript comment or null if the end of the file is reached * @throws IOException In case of an I/O error * @throws DSCException In case of a violation of the DSC spec */ public PostScriptComment nextPSComment(String prefix, PSGenerator gen) throws IOException, DSCException { while (hasNext()) { DSCEvent event = nextEvent(); if (event.isComment()) { PostScriptComment comment = (PostScriptComment)event; if (comment.getComment().startsWith(prefix)) { return comment; } } if (gen != null) { event.generate(gen); //Pipe through to PSGenerator } } return null; } /** * Sets a filter for DSC events. * @param filter the filter to use or null to disable filtering */ public void setFilter(DSCFilter filter) { if (filter != null) { this.filterListener = new FilteringEventListener(filter); } else { this.filterListener = null; } } /** * Adds a DSC event listener. * @param listener the listener */ public void addListener(DSCListener listener) { if (listener == null) { throw new NullPointerException("listener must not be null"); } if (this.listeners == null) { this.listeners = new java.util.ArrayList(); } this.listeners.add(listener); } /** * Removes a DSC event listener. * @param listener the listener to remove */ public void removeListener(DSCListener listener) { if (this.listeners != null) { this.listeners.remove(listener); } } /** * Allows to disable all listeners. This can be used to disable any filtering, for example in * nested documents. * @param value true to disable all listeners, false to re-enable them */ public void setListenersDisabled(boolean value) { this.listenersDisabled = value; } /** * Indicates whether the listeners are currently disabled. * @return true if they are disabled */ public boolean isListenersDisabled() { return this.listenersDisabled; } /** * Sets a NestedDocumentHandler which is used to skip nested documents like embedded EPS files. * You can also process those parts in a special way. *

    * It is suggested to use the more generally usable {@link #addListener(DSCListener)} and * {@link #removeListener(DSCListener)} instead. NestedDocumentHandler is internally * mapped onto a {@link DSCListener}. * @param handler the NestedDocumentHandler instance or null to disable the feature */ public void setNestedDocumentHandler(final NestedDocumentHandler handler) { if (handler == null) { removeListener(this.nestedDocumentHandler); } else { MyDSCListener l = new MyDSCListener(); l.handler = handler; addListener(l); } } static class MyDSCListener implements DSCListener { private NestedDocumentHandler handler; public void processEvent(DSCEvent event, DSCParser parser) throws IOException, DSCException { handler.handle(event, parser); } } /** * Tells the parser whether to check for content after the EOF comment. * This can be disabled to skip nested documents. * @param value true if the check is enabled */ public void setCheckEOF(boolean value) { this.checkEOF = value; } /** * Indicates whether the parser is configured to check for content after the EOF comment. * @return true if the check is enabled. */ public boolean isCheckEOF() { return this.checkEOF; } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/dsc/DSCParserConstants.java0100644 0000000 0000000 00000002621 13777276623 030635 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: DSCParserConstants.java 750418 2009-03-05 11:03:54Z vhennebert $ */ package org.apache.xmlgraphics.ps.dsc; /** * Constants the DSC parser uses. */ public interface DSCParserConstants { /** Indicates a header comment (starting with "%!") */ int HEADER_COMMENT = 0; /** Indicates a DSC comment (starting with "%%") */ int DSC_COMMENT = 1; /** Indicates a normal PostScript comment (starting with "%") */ int COMMENT = 2; /** Indicates a normal PostScript line */ int LINE = 3; /** Indicates the end of the file (equivalent to the "%%EOF" DSC comment) */ int EOF = 4; } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/dsc/DefaultDSCHandler.java0100644 0000000 0000000 00000005247 13777276623 030375 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: DefaultDSCHandler.java 750418 2009-03-05 11:03:54Z vhennebert $ */ package org.apache.xmlgraphics.ps.dsc; import java.io.IOException; import java.io.OutputStream; import org.apache.xmlgraphics.ps.DSCConstants; import org.apache.xmlgraphics.ps.PSGenerator; import org.apache.xmlgraphics.ps.dsc.events.DSCComment; /** * Default implementation of a DSCHandler which simply passes through the PostScript content * unchanged. Subclasses can implement different behaviour, for example to filter certain * DSC comments or to insert PostScript code at specific places. */ public class DefaultDSCHandler implements DSCHandler { protected OutputStream out; protected PSGenerator gen; /** * Creates a new instance. * @param out OutputStream to pipe all received events to */ public DefaultDSCHandler(OutputStream out) { this.out = out; this.gen = new PSGenerator(this.out); } /** @see org.apache.xmlgraphics.ps.dsc.DSCHandler#startDocument(java.lang.String) */ public void startDocument(String header) throws IOException { gen.writeln(header); } /** @see org.apache.xmlgraphics.ps.dsc.DSCHandler#endDocument() */ public void endDocument() throws IOException { gen.writeDSCComment(DSCConstants.EOF); } /** * @see org.apache.xmlgraphics.ps.dsc.DSCHandler#handleDSCComment( * org.apache.xmlgraphics.ps.dsc.events.DSCComment) */ public void handleDSCComment(DSCComment comment) throws IOException { comment.generate(gen); } /** @see org.apache.xmlgraphics.ps.dsc.DSCHandler#line(java.lang.String) */ public void line(String line) throws IOException { gen.writeln(line); } /** @see org.apache.xmlgraphics.ps.dsc.DSCHandler#comment(java.lang.String) */ public void comment(String comment) throws IOException { gen.commentln("%" + comment); } } ././@LongLink0100644 0000000 0000000 00000000146 13777276623 011660 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/dsc/DefaultNestedDocumentHandler.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/dsc/DefaultNestedDocumentHandler.jav0100644 0000000 0000000 00000007165 13777276623 032545 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: DefaultNestedDocumentHandler.java 1614048 2014-07-28 15:16:47Z vhennebert $ */ package org.apache.xmlgraphics.ps.dsc; import java.io.IOException; import org.apache.xmlgraphics.ps.DSCConstants; import org.apache.xmlgraphics.ps.PSGenerator; import org.apache.xmlgraphics.ps.dsc.events.DSCComment; import org.apache.xmlgraphics.ps.dsc.events.DSCEvent; /** * {@link DSCListener} implementation which automatically skips data * between Begin/EndDocument and Begin/EndData. */ public class DefaultNestedDocumentHandler implements DSCParserConstants, NestedDocumentHandler, DSCListener { private PSGenerator gen; /** * Creates a new instance. * @param gen PSGenerator to pass through the skipped content */ public DefaultNestedDocumentHandler(PSGenerator gen) { this.gen = gen; } /** {@inheritDoc} */ public void handle(DSCEvent event, DSCParser parser) throws IOException, DSCException { processEvent(event, parser); } /** {@inheritDoc} */ public void processEvent(DSCEvent event, DSCParser parser) throws IOException, DSCException { if (event.isDSCComment()) { DSCComment comment = event.asDSCComment(); if (DSCConstants.BEGIN_DOCUMENT.equals(comment.getName())) { if (gen != null) { comment.generate(gen); } boolean checkEOF = parser.isCheckEOF(); parser.setCheckEOF(false); parser.setListenersDisabled(true); comment = parser.nextDSCComment(DSCConstants.END_DOCUMENT, gen); if (comment == null) { throw new DSCException("File is not DSC-compliant: Didn't find an " + DSCConstants.END_DOCUMENT); } if (gen != null) { comment.generate(gen); } parser.setCheckEOF(checkEOF); parser.setListenersDisabled(false); parser.next(); } else if (DSCConstants.BEGIN_DATA.equals(comment.getName())) { if (gen != null) { comment.generate(gen); } boolean checkEOF = parser.isCheckEOF(); parser.setCheckEOF(false); parser.setListenersDisabled(true); comment = parser.nextDSCComment(DSCConstants.END_DATA, gen); if (comment == null) { throw new DSCException("File is not DSC-compliant: Didn't find an " + DSCConstants.END_DATA); } if (gen != null) { comment.generate(gen); } parser.setCheckEOF(checkEOF); parser.setListenersDisabled(false); parser.next(); } } } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/dsc/EventRecorder.java0100644 0000000 0000000 00000007130 13777276623 027721 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: EventRecorder.java 1804124 2017-08-04 14:13:54Z ssteiner $ */ package org.apache.xmlgraphics.ps.dsc; import java.io.IOException; import java.util.List; import org.apache.xmlgraphics.ps.dsc.events.DSCComment; /** * DSCHandler implementation that records DSC events. */ public class EventRecorder implements DSCHandler { private List events = new java.util.ArrayList(); /** * Replays the recorded events to a specified DSCHandler instance. * @param handler the DSCHandler to send the recorded events to * @throws IOException In case of an I/O error */ public void replay(DSCHandler handler) throws IOException { for (Object obj : events) { if (obj instanceof PSLine) { handler.line(((PSLine) obj).getLine()); } else if (obj instanceof PSComment) { handler.comment(((PSComment) obj).getComment()); } else if (obj instanceof DSCComment) { handler.handleDSCComment((DSCComment) obj); } else { throw new IllegalStateException("Unsupported class type"); } } } /** * @see org.apache.xmlgraphics.ps.dsc.DSCHandler#comment(java.lang.String) */ public void comment(String comment) throws IOException { events.add(new PSComment(comment)); } /** * @see org.apache.xmlgraphics.ps.dsc.DSCHandler#handleDSCComment( * org.apache.xmlgraphics.ps.dsc.events.DSCComment) */ public void handleDSCComment(DSCComment comment) throws IOException { events.add(comment); } /** * @see org.apache.xmlgraphics.ps.dsc.DSCHandler#line(java.lang.String) */ public void line(String line) throws IOException { events.add(new PSLine(line)); } /** * @see org.apache.xmlgraphics.ps.dsc.DSCHandler#startDocument(java.lang.String) */ public void startDocument(String header) throws IOException { throw new UnsupportedOperationException( getClass().getName() + " is only used to handle parts of a document"); } /** * @see org.apache.xmlgraphics.ps.dsc.DSCHandler#endDocument() */ public void endDocument() throws IOException { throw new UnsupportedOperationException( getClass().getName() + " is only used to handle parts of a document"); } private static class PSComment { private String comment; public PSComment(String comment) { this.comment = comment; } public String getComment() { return this.comment; } } private static class PSLine { private String line; public PSLine(String line) { this.line = line; } public String getLine() { return this.line; } } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/dsc/FilteringEventListener.java0100644 0000000 0000000 00000003024 13777276623 031603 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: FilteringEventListener.java 727407 2008-12-17 15:05:45Z jeremias $ */ package org.apache.xmlgraphics.ps.dsc; import java.io.IOException; import org.apache.xmlgraphics.ps.dsc.events.DSCEvent; /** * {@code DSCListener} implementation that filters certain DSC events. */ public class FilteringEventListener implements DSCListener { private DSCFilter filter; /** * Main constructor. * @param filter the filter */ public FilteringEventListener(DSCFilter filter) { this.filter = filter; } /** {@inheritDoc} */ public void processEvent(DSCEvent event, DSCParser parser) throws IOException, DSCException { if (!filter.accept(event)) { parser.next(); //skip } } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/dsc/NestedDocumentHandler.java0100644 0000000 0000000 00000003761 13777276623 031377 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: NestedDocumentHandler.java 1345683 2012-06-03 14:50:33Z gadams $ */ package org.apache.xmlgraphics.ps.dsc; import java.io.IOException; import org.apache.xmlgraphics.ps.dsc.events.DSCEvent; /** * Interface that is used to delegate the handling of nested documents (EPS files, data sections) * in a PostScript document. The implementation receives a parser instance so it can step forward * until the end of the nested document is reached at which point control is given back to the * original consumer. *

    * It is suggested to use the more generally usable {@link DSCListener} instead. This * interface may be deprecated in the future. */ public interface NestedDocumentHandler { /** * Handle a DSC event. Implementations may issue additional calls to the DSC parser and may * modify its state. When returning from the call, state information such as filters should * be restored. * @param event the DSC event to handle * @param parser the DSC parser to work with * @throws IOException In case of an I/O error * @throws DSCException In case of a violation of the DSC spec */ void handle(DSCEvent event, DSCParser parser) throws IOException, DSCException; } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/dsc/ResourceTracker.java0100644 0000000 0000000 00000021670 13777276623 030262 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ResourceTracker.java 1804124 2017-08-04 14:13:54Z ssteiner $ */ package org.apache.xmlgraphics.ps.dsc; import java.io.IOException; import java.util.Collection; import java.util.Collections; import java.util.Map; import java.util.Set; import org.apache.xmlgraphics.ps.PSGenerator; import org.apache.xmlgraphics.ps.PSResource; import org.apache.xmlgraphics.ps.dsc.events.DSCCommentDocumentNeededResources; import org.apache.xmlgraphics.ps.dsc.events.DSCCommentDocumentSuppliedResources; import org.apache.xmlgraphics.ps.dsc.events.DSCCommentPageResources; /** * This class is used to track resources in a DSC-compliant PostScript file. The distinction is * made between supplied and needed resources. For the details of this distinction, please see * the DSC specification. */ public class ResourceTracker { private Set documentSuppliedResources; private Set documentNeededResources; private Set usedResources; private Set pageResources; //Map private Map resourceUsageCounts; /** * Returns the set of supplied resources. * @return the set of supplied resources */ public Set getDocumentSuppliedResources() { if (documentSuppliedResources != null) { return Collections.unmodifiableSet(documentSuppliedResources); } else { return Collections.EMPTY_SET; } } /** * Returns the set of needed resources. * @return the set of needed resources */ public Set getDocumentNeededResources() { if (documentNeededResources != null) { return Collections.unmodifiableSet(documentNeededResources); } else { return Collections.EMPTY_SET; } } /** * Notifies the resource tracker that a new page has been started and that the page resource * set can be cleared. */ public void notifyStartNewPage() { if (pageResources != null) { pageResources.clear(); } } /** * Registers a supplied resource. If the same resources is already in the set of needed * resources, it is removed there. * @param res the resource */ public void registerSuppliedResource(PSResource res) { if (documentSuppliedResources == null) { documentSuppliedResources = new java.util.HashSet(); } documentSuppliedResources.add(res); if (documentNeededResources != null) { documentNeededResources.remove(res); } } /** * Registers a needed resource. If the same resources is already in the set of supplied * resources, it is ignored, i.e. it is assumed to be supplied. * @param res the resource */ public void registerNeededResource(PSResource res) { if (documentSuppliedResources == null || !documentSuppliedResources.contains(res)) { if (documentNeededResources == null) { documentNeededResources = new java.util.HashSet(); } documentNeededResources.add(res); } } private void preparePageResources() { if (pageResources == null) { pageResources = new java.util.HashSet(); } } private void prepareUsageCounts() { if (resourceUsageCounts == null) { resourceUsageCounts = new java.util.HashMap(); } } /** * Notifies the resource tracker about the usage of a resource on the current page. * @param res the resource being used */ public void notifyResourceUsageOnPage(PSResource res) { preparePageResources(); pageResources.add(res); prepareUsageCounts(); Counter counter = (Counter)resourceUsageCounts.get(res); if (counter == null) { resourceUsageCounts.put(res, new Counter()); } else { counter.inc(); } } /** * Notifies the resource tracker about the usage of resources on the current page. * @param resources the resources being used */ public void notifyResourceUsageOnPage(Collection resources) { preparePageResources(); for (Object resource : resources) { PSResource res = (PSResource) resource; notifyResourceUsageOnPage(res); } } /** * Indicates whether a particular resource is supplied, rather than needed. * @param res the resource * @return true if the resource is registered as being supplied. */ public boolean isResourceSupplied(PSResource res) { return (documentSuppliedResources != null) && documentSuppliedResources.contains(res); } /** * Writes a DSC comment for the accumulated used resources, either at page level or * at document level. * @param pageLevel true if the DSC comment for the page level should be generated, * false for the document level (in the trailer) * @param gen the PSGenerator to write the DSC comments with * @exception IOException In case of an I/O problem */ public void writeResources(boolean pageLevel, PSGenerator gen) throws IOException { if (pageLevel) { writePageResources(gen); } else { writeDocumentResources(gen); } } /** * Writes a DSC comment for the accumulated used resources on the current page. Then it commits * all those resources to the used resources on document level. * @param gen the PSGenerator to write the DSC comments with * @exception IOException In case of an I/O problem */ public void writePageResources(PSGenerator gen) throws IOException { new DSCCommentPageResources(pageResources).generate(gen); if (usedResources == null) { usedResources = new java.util.HashSet(); } usedResources.addAll(pageResources); } /** * Writes a DSC comment for the needed and supplied resourced for the current DSC document. * @param gen the PSGenerator to write the DSC comments with * @exception IOException In case of an I/O problem */ public void writeDocumentResources(PSGenerator gen) throws IOException { if (usedResources != null) { for (Object usedResource : usedResources) { PSResource res = (PSResource) usedResource; if (documentSuppliedResources == null || !documentSuppliedResources.contains(res)) { registerNeededResource(res); } } } new DSCCommentDocumentNeededResources(documentNeededResources).generate(gen); new DSCCommentDocumentSuppliedResources(documentSuppliedResources).generate(gen); } /** * This method declares that the given resource will be inlined and can therefore * be removed from resource tracking. This is useful when you don't know beforehand * if a resource will be used multiple times. If it's only used once it's better * to inline the resource to lower the maximum memory needed inside the PostScript * interpreter. * @param res the resource */ public void declareInlined(PSResource res) { if (this.documentNeededResources != null) { this.documentNeededResources.remove(res); } if (this.documentSuppliedResources != null) { this.documentSuppliedResources.remove(res); } if (this.pageResources != null) { this.pageResources.remove(res); } if (this.usedResources != null) { this.usedResources.remove(res); } } /** * Returns the number of times a resource has been used inside the current DSC document. * @param res the resource * @return the number of times the resource has been used */ public long getUsageCount(PSResource res) { Counter counter = (Counter)resourceUsageCounts.get(res); return (counter != null ? counter.getCount() : 0); } private static class Counter { private long count = 1; public void inc() { this.count++; } public long getCount() { return this.count; } public String toString() { return Long.toString(this.count); } } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/dsc/events/AbstractDSCComment.java0100644 0000000 0000000 00000011064 13777276623 032077 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: AbstractDSCComment.java 1345683 2012-06-03 14:50:33Z gadams $ */ package org.apache.xmlgraphics.ps.dsc.events; import java.util.List; /** * Abstract base class for DSC comments. */ public abstract class AbstractDSCComment extends AbstractEvent implements DSCComment { private boolean isWhitespace(char c) { return c == ' ' || c == '\t'; } private int parseNextParam(String value, int pos, List lst) { int startPos = pos; pos++; while (pos < value.length() && !isWhitespace(value.charAt(pos))) { pos++; } String param = value.substring(startPos, pos); lst.add(param); return pos; } private int parseNextParentheseString(String value, int pos, List lst) { int nestLevel = 1; pos++; StringBuffer sb = new StringBuffer(); while (pos < value.length() && nestLevel > 0) { final char c = value.charAt(pos); switch (c) { case '(': nestLevel++; if (nestLevel > 1) { sb.append(c); } break; case ')': if (nestLevel > 1) { sb.append(c); } nestLevel--; break; case '\\': pos++; char cnext = value.charAt(pos); switch (cnext) { case '\\': sb.append(cnext); break; case 'n': sb.append('\n'); break; case 'r': sb.append('\r'); break; case 't': sb.append('\t'); break; case 'b': sb.append('\b'); break; case 'f': sb.append('\f'); break; case '(': sb.append('('); break; case ')': sb.append(')'); break; default: int code = Integer.parseInt(value.substring(pos, pos + 3), 8); sb.append((char)code); pos += 2; } break; default: sb.append(c); } pos++; } lst.add(sb.toString()); pos++; return pos; } /** * Splits the params of the DSC comment value in to a List. * @param value the DSC comment value * @return the List of values */ protected List splitParams(String value) { List lst = new java.util.ArrayList(); int pos = 0; value = value.trim(); while (pos < value.length()) { if (isWhitespace(value.charAt(pos))) { pos++; continue; } if (value.charAt(pos) == '(') { pos = parseNextParentheseString(value, pos, lst); } else { pos = parseNextParam(value, pos, lst); } } return lst; } /** * @see org.apache.xmlgraphics.ps.dsc.events.DSCComment#isAtend() */ public boolean isAtend() { return false; } /** * @see org.apache.xmlgraphics.ps.dsc.events.AbstractEvent#asDSCComment() */ public DSCComment asDSCComment() { return this; } /** * @see org.apache.xmlgraphics.ps.dsc.events.AbstractEvent#isDSCComment() */ public boolean isDSCComment() { return true; } /** * @see org.apache.xmlgraphics.ps.dsc.events.DSCEvent#getEventType() */ public int getEventType() { return DSC_COMMENT; } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/dsc/events/AbstractEvent.java0100644 0000000 0000000 00000003753 13777276623 031232 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: AbstractEvent.java 750418 2009-03-05 11:03:54Z vhennebert $ */ package org.apache.xmlgraphics.ps.dsc.events; /** * Abstract base class for DSC events. */ public abstract class AbstractEvent implements DSCEvent { /** * @see org.apache.xmlgraphics.ps.dsc.events.DSCEvent#isComment() */ public boolean isComment() { return false; } /** * @see org.apache.xmlgraphics.ps.dsc.events.DSCEvent#isDSCComment() */ public boolean isDSCComment() { return false; } /** * @see org.apache.xmlgraphics.ps.dsc.events.DSCEvent#isHeaderComment() */ public boolean isHeaderComment() { return false; } /** * @see org.apache.xmlgraphics.ps.dsc.events.DSCEvent#isLine() */ public boolean isLine() { return false; } /** * @see org.apache.xmlgraphics.ps.dsc.events.DSCEvent#asDSCComment() */ public DSCComment asDSCComment() { throw new ClassCastException(this.getClass().getName()); } /** * @see org.apache.xmlgraphics.ps.dsc.events.DSCEvent#asLine() */ public PostScriptLine asLine() { throw new ClassCastException(this.getClass().getName()); } } ././@LongLink0100644 0000000 0000000 00000000153 13777276623 011656 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/dsc/events/AbstractResourceDSCComment.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/dsc/events/AbstractResourceDSCCommen0100644 0000000 0000000 00000006706 13777276623 032512 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: AbstractResourceDSCComment.java 727407 2008-12-17 15:05:45Z jeremias $ */ package org.apache.xmlgraphics.ps.dsc.events; import java.io.IOException; import java.util.Iterator; import java.util.List; import org.apache.xmlgraphics.ps.PSGenerator; import org.apache.xmlgraphics.ps.PSProcSet; import org.apache.xmlgraphics.ps.PSResource; /** * Abstract base class for resource comments. */ public abstract class AbstractResourceDSCComment extends AbstractDSCComment { private PSResource resource; /** * Creates a new instance */ public AbstractResourceDSCComment() { } /** * Creates a new instance for a given PSResource instance * @param resource the resource */ public AbstractResourceDSCComment(PSResource resource) { this.resource = resource; } /** * Returns the associated PSResource. * @return the resource */ public PSResource getResource() { return this.resource; } /** {@inheritDoc} */ public boolean hasValues() { return true; } /** {@inheritDoc} */ public void parseValue(String value) { List params = splitParams(value); Iterator iter = params.iterator(); String name = (String)iter.next(); if (PSResource.TYPE_FONT.equals(name)) { String fontname = (String)iter.next(); this.resource = new PSResource(name, fontname); } else if (PSResource.TYPE_PROCSET.equals(name)) { String procname = (String)iter.next(); String version = (String)iter.next(); String revision = (String)iter.next(); this.resource = new PSProcSet(procname, Float.parseFloat(version), Integer.parseInt(revision)); } else if (PSResource.TYPE_FILE.equals(name)) { String filename = (String)iter.next(); this.resource = new PSResource(name, filename); } else if (PSResource.TYPE_FORM.equals(name)) { String formname = (String)iter.next(); this.resource = new PSResource(name, formname); } else if (PSResource.TYPE_PATTERN.equals(name)) { String patternname = (String)iter.next(); this.resource = new PSResource(name, patternname); } else if (PSResource.TYPE_ENCODING.equals(name)) { String encodingname = (String)iter.next(); this.resource = new PSResource(name, encodingname); } else { throw new IllegalArgumentException("Invalid resource type: " + name); } } /** {@inheritDoc} */ public void generate(PSGenerator gen) throws IOException { gen.writeDSCComment(getName(), getResource()); } } ././@LongLink0100644 0000000 0000000 00000000154 13777276623 011657 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/dsc/events/AbstractResourcesDSCComment.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/dsc/events/AbstractResourcesDSCComme0100644 0000000 0000000 00000012742 13777276623 032514 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: AbstractResourcesDSCComment.java 1804124 2017-08-04 14:13:54Z ssteiner $ */ package org.apache.xmlgraphics.ps.dsc.events; import java.io.IOException; import java.util.Collection; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Set; import org.apache.xmlgraphics.ps.PSGenerator; import org.apache.xmlgraphics.ps.PSProcSet; import org.apache.xmlgraphics.ps.PSResource; /** * Abstract base class for Resource DSC comments (DocumentNeededResources, * DocumentSuppliedResources and PageResources). */ public abstract class AbstractResourcesDSCComment extends AbstractDSCComment { private Set resources; /** * Creates a new instance. */ public AbstractResourcesDSCComment() { super(); } /** * Creates a new instance. * @param resources a Collection of PSResource instances */ public AbstractResourcesDSCComment(Collection resources) { addResources(resources); } /** {@inheritDoc} */ public boolean hasValues() { return true; } private void prepareResourceSet() { if (this.resources == null) { this.resources = new java.util.TreeSet(); } } /** * Adds a new resource. * @param res the resource */ public void addResource(PSResource res) { prepareResourceSet(); this.resources.add(res); } /** * Adds a collection of resources. * @param resources a Collection of PSResource instances. */ public void addResources(Collection resources) { if (resources != null) { prepareResourceSet(); this.resources.addAll(resources); } } /** * Returns the set of resources associated with this DSC comment. * @return the set of resources */ public Set getResources() { return Collections.unmodifiableSet(this.resources); } /** * Defines the known resource types (font, procset, file, pattern etc.). */ static final Set RESOURCE_TYPES = new java.util.HashSet(); static { RESOURCE_TYPES.add(PSResource.TYPE_FONT); RESOURCE_TYPES.add(PSResource.TYPE_PROCSET); RESOURCE_TYPES.add(PSResource.TYPE_FILE); RESOURCE_TYPES.add(PSResource.TYPE_PATTERN); RESOURCE_TYPES.add(PSResource.TYPE_FORM); RESOURCE_TYPES.add(PSResource.TYPE_ENCODING); } /** {@inheritDoc} */ public void parseValue(String value) { List params = splitParams(value); String currentResourceType = null; Iterator iter = params.iterator(); while (iter.hasNext()) { String name = (String)iter.next(); if (RESOURCE_TYPES.contains(name)) { currentResourceType = name; } if (currentResourceType == null) { throw new IllegalArgumentException( " must begin with a resource type. Found: " + name); } if (PSResource.TYPE_FONT.equals(currentResourceType)) { String fontname = (String)iter.next(); addResource(new PSResource(name, fontname)); } else if (PSResource.TYPE_FORM.equals(currentResourceType)) { String formname = (String)iter.next(); addResource(new PSResource(name, formname)); } else if (PSResource.TYPE_PROCSET.equals(currentResourceType)) { String procname = (String)iter.next(); String version = (String)iter.next(); String revision = (String)iter.next(); addResource(new PSProcSet(procname, Float.parseFloat(version), Integer.parseInt(revision))); } else if (PSResource.TYPE_FILE.equals(currentResourceType)) { String filename = (String)iter.next(); addResource(new PSResource(name, filename)); } else { throw new IllegalArgumentException("Invalid resource type: " + currentResourceType); } } } /** {@inheritDoc} */ public void generate(PSGenerator gen) throws IOException { if (resources == null || resources.size() == 0) { return; } StringBuffer sb = new StringBuffer(); sb.append("%%").append(getName()).append(": "); boolean first = true; for (Object resource : resources) { if (!first) { gen.writeln(sb.toString()); sb.setLength(0); sb.append("%%+ "); } PSResource res = (PSResource) resource; sb.append(res.getResourceSpecification()); first = false; } gen.writeln(sb.toString()); } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/dsc/events/DSCAtend.java0100644 0000000 0000000 00000005107 13777276623 030045 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: DSCAtend.java 750418 2009-03-05 11:03:54Z vhennebert $ */ package org.apache.xmlgraphics.ps.dsc.events; import java.io.IOException; import org.apache.xmlgraphics.ps.DSCConstants; import org.apache.xmlgraphics.ps.PSGenerator; import org.apache.xmlgraphics.ps.dsc.DSCCommentFactory; /** * This class represents a DSC comment with an "(ATEND)" value. */ public class DSCAtend extends AbstractDSCComment { private String name; /** * Creates a new instance * @param name the name of the DSC comment (without the "%%" prefix) */ public DSCAtend(String name) { this.name = name; } /** * @see org.apache.xmlgraphics.ps.dsc.events.DSCComment#getName() */ public String getName() { return this.name; } /** * @see org.apache.xmlgraphics.ps.dsc.events.DSCComment#hasValues() */ public boolean hasValues() { return false; } /** * @see org.apache.xmlgraphics.ps.dsc.events.AbstractDSCComment#isAtend() */ public boolean isAtend() { return true; } /** * @see org.apache.xmlgraphics.ps.dsc.events.DSCComment#parseValue(java.lang.String) */ public void parseValue(String value) { //nop } /** * @see org.apache.xmlgraphics.ps.dsc.events.DSCEvent#generate( * org.apache.xmlgraphics.ps.PSGenerator) */ public void generate(PSGenerator gen) throws IOException { gen.writeDSCComment(getName(), DSCConstants.ATEND); } /** * Creates a new instance of a DSC comment with the same name as this instance but does not * have an "Atend" value. * @return the new DSC comment */ public DSCComment createDSCCommentFromAtend() { return DSCCommentFactory.createDSCCommentFor(getName()); } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/dsc/events/DSCComment.java0100644 0000000 0000000 00000003476 13777276623 030423 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: DSCComment.java 750418 2009-03-05 11:03:54Z vhennebert $ */ package org.apache.xmlgraphics.ps.dsc.events; import java.io.IOException; import org.apache.xmlgraphics.ps.PSGenerator; /** * Base interface for all DSC comments. */ public interface DSCComment extends DSCEvent { /** * Returns the name of the DSC comment. * @return the name of the DSC comment (without the "%%" prefix) */ String getName(); /** * Parses the value of the DSC comment. * @param value the value */ void parseValue(String value); /** * Indicates whether this DSC comment has values. * @return true if the DSC comment has values */ boolean hasValues(); /** * Indicates whether the DSC comment's value is "Atend". * @return true if the value is "Atend" */ boolean isAtend(); /** * @see org.apache.xmlgraphics.ps.dsc.events.DSCEvent#generate( * org.apache.xmlgraphics.ps.PSGenerator) */ void generate(PSGenerator gen) throws IOException; } ././@LongLink0100644 0000000 0000000 00000000150 13777276623 011653 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/dsc/events/DSCCommentBeginDocument.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/dsc/events/DSCCommentBeginDocument.j0100644 0000000 0000000 00000007463 13777276623 032377 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: DSCCommentBeginDocument.java 1681108 2015-05-22 13:26:12Z ssteiner $ */ package org.apache.xmlgraphics.ps.dsc.events; import java.io.IOException; import java.util.Iterator; import java.util.List; import org.apache.xmlgraphics.ps.DSCConstants; import org.apache.xmlgraphics.ps.PSGenerator; import org.apache.xmlgraphics.ps.PSResource; /** * Represents a %BeginDocument DSC comment. */ public class DSCCommentBeginDocument extends AbstractDSCComment { private PSResource resource; private Float version; private String type; /** * Creates a new instance */ public DSCCommentBeginDocument() { super(); } /** * Creates a new instance for a given PSResource instance * @param resource the resource */ public DSCCommentBeginDocument(PSResource resource) { this.resource = resource; if (resource != null && !PSResource.TYPE_FILE.equals(resource.getType())) { throw new IllegalArgumentException("Resource must be of type 'file'"); } } /** * Creates a new instance for a given PSResource instance * @param resource the resource * @param version the version of the resource (or null) * @param type the type of resource (or null) */ public DSCCommentBeginDocument(PSResource resource, Float version, String type) { this(resource); this.version = version; this.type = type; } /** * Returns the resource version. * @return the resource version (or null if not applicable) */ public Float getVersion() { return this.version; } /** * Returns the resource type * @return the resource type (or null if not applicable) */ public String getType() { return this.type; } /** {@inheritDoc} */ public String getName() { return DSCConstants.BEGIN_DOCUMENT; } /** * Returns the associated PSResource. * @return the resource */ public PSResource getResource() { return this.resource; } /** {@inheritDoc} */ public boolean hasValues() { return true; } /** {@inheritDoc} */ public void parseValue(String value) { List params = splitParams(value); Iterator iter = params.iterator(); String name = (String)iter.next(); this.resource = new PSResource(PSResource.TYPE_FILE, name); if (iter.hasNext()) { this.version = Float.valueOf(iter.next().toString()); this.type = null; if (iter.hasNext()) { this.type = (String)iter.next(); } } } /** {@inheritDoc} */ public void generate(PSGenerator gen) throws IOException { List params = new java.util.ArrayList(); params.add(getResource().getName()); if (getVersion() != null) { params.add(getVersion()); if (getType() != null) { params.add(getType()); } } gen.writeDSCComment(getName(), params.toArray()); } } ././@LongLink0100644 0000000 0000000 00000000150 13777276623 011653 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/dsc/events/DSCCommentBeginResource.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/dsc/events/DSCCommentBeginResource.j0100644 0000000 0000000 00000005276 13777276623 032410 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: DSCCommentBeginResource.java 1681108 2015-05-22 13:26:12Z ssteiner $ */ package org.apache.xmlgraphics.ps.dsc.events; import java.io.IOException; import org.apache.xmlgraphics.ps.DSCConstants; import org.apache.xmlgraphics.ps.PSGenerator; import org.apache.xmlgraphics.ps.PSResource; /** * Represents a %BeginResource DSC comment. */ public class DSCCommentBeginResource extends AbstractResourceDSCComment { private Integer min; private Integer max; /** * Creates a new instance */ public DSCCommentBeginResource() { super(); } /** * Creates a new instance for a given PSResource instance * @param resource the resource */ public DSCCommentBeginResource(PSResource resource) { super(resource); } /** * Creates a new instance for a given PSResource instance * @param resource the resource * @param min Minimum VM used by the resource * @param max Maximum VM used by the resource */ public DSCCommentBeginResource(PSResource resource, int min, int max) { super(resource); this.min = min; this.max = max; } /** * Returns the minimum VM used by the resource. * @return the minimum VM used by the resource */ public Integer getMin() { return this.min; } /** * Returns the maximum VM used by the resource. * @return the maximum VM used by the resource */ public Integer getMax() { return this.max; } /** {@inheritDoc} */ public String getName() { return DSCConstants.BEGIN_RESOURCE; } /** {@inheritDoc} */ public void generate(PSGenerator gen) throws IOException { if (getMin() != null) { Object[] params = new Object[] {getResource(), getMin(), getMax()}; gen.writeDSCComment(getName(), params); } else { super.generate(gen); } } } ././@LongLink0100644 0000000 0000000 00000000146 13777276623 011660 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/dsc/events/DSCCommentBoundingBox.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/dsc/events/DSCCommentBoundingBox.jav0100644 0000000 0000000 00000006014 13777276623 032410 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: DSCCommentBoundingBox.java 1681108 2015-05-22 13:26:12Z ssteiner $ */ package org.apache.xmlgraphics.ps.dsc.events; import java.awt.geom.Rectangle2D; import java.io.IOException; import java.util.Iterator; import java.util.List; import org.apache.xmlgraphics.ps.DSCConstants; import org.apache.xmlgraphics.ps.PSGenerator; /** * Represents a %%BoundingBox DSC comment. */ public class DSCCommentBoundingBox extends AbstractDSCComment { private Rectangle2D bbox; /** * Creates a new instance. */ public DSCCommentBoundingBox() { } /** * Creates a new instance. * @param bbox the bounding box */ public DSCCommentBoundingBox(Rectangle2D bbox) { setBoundingBox(bbox); } /** * Returns the bounding box. * @return the bounding box */ public Rectangle2D getBoundingBox() { return this.bbox; } /** * Sets the bounding box. * @param bbox the bounding box */ public void setBoundingBox(Rectangle2D bbox) { this.bbox = bbox; } /** {@inheritDoc} */ public String getName() { return DSCConstants.BBOX; } /** {@inheritDoc} */ public boolean hasValues() { return true; } /** {@inheritDoc} */ public void parseValue(String value) { List params = splitParams(value); Iterator iter = params.iterator(); double x1 = Double.parseDouble((String)iter.next()); double y1 = Double.parseDouble((String)iter.next()); double x2 = Double.parseDouble((String)iter.next()); double y2 = Double.parseDouble((String)iter.next()); this.bbox = new Rectangle2D.Double(x1, y1, x2 - x1, y2 - y1); } /** {@inheritDoc} */ public void generate(PSGenerator gen) throws IOException { if (getBoundingBox() != null) { gen.writeDSCComment(getName(), new Object[] { (int) Math.floor(this.bbox.getX()), (int) Math.floor(this.bbox.getY()), (int) Math.ceil(this.bbox.getX() + this.bbox.getWidth()), (int) Math.ceil(this.bbox.getY() + this.bbox.getHeight())}); } else { gen.writeDSCComment(getName(), DSCConstants.ATEND); } } } ././@LongLink0100644 0000000 0000000 00000000162 13777276623 011656 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/dsc/events/DSCCommentDocumentNeededResources.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/dsc/events/DSCCommentDocumentNeededR0100644 0000000 0000000 00000003220 13777276623 032414 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: DSCCommentDocumentNeededResources.java 750418 2009-03-05 11:03:54Z vhennebert $ */ package org.apache.xmlgraphics.ps.dsc.events; import java.util.Collection; import org.apache.xmlgraphics.ps.DSCConstants; /** * Represents a %%DocumentNeededResources DSC comment. */ public class DSCCommentDocumentNeededResources extends AbstractResourcesDSCComment { /** * Creates a new instance. */ public DSCCommentDocumentNeededResources() { super(); } /** * Creates a new instance. * @param resources a Collection of PSResource instances */ public DSCCommentDocumentNeededResources(Collection resources) { super(resources); } /** * @see org.apache.xmlgraphics.ps.dsc.events.DSCComment#getName() */ public String getName() { return DSCConstants.DOCUMENT_NEEDED_RESOURCES; } } ././@LongLink0100644 0000000 0000000 00000000164 13777276623 011660 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/dsc/events/DSCCommentDocumentSuppliedResources.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/dsc/events/DSCCommentDocumentSupplie0100644 0000000 0000000 00000003234 13777276623 032534 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: DSCCommentDocumentSuppliedResources.java 750418 2009-03-05 11:03:54Z vhennebert $ */ package org.apache.xmlgraphics.ps.dsc.events; import java.util.Collection; import org.apache.xmlgraphics.ps.DSCConstants; /** * Represents a %%DocumentSuppliedResources DSC comment. */ public class DSCCommentDocumentSuppliedResources extends AbstractResourcesDSCComment { /** * Creates a new instance. */ public DSCCommentDocumentSuppliedResources() { super(); } /** * Creates a new instance. * @param resources a Collection of PSResource instances */ public DSCCommentDocumentSuppliedResources(Collection resources) { super(resources); } /** * @see org.apache.xmlgraphics.ps.dsc.events.DSCComment#getName() */ public String getName() { return DSCConstants.DOCUMENT_SUPPLIED_RESOURCES; } } ././@LongLink0100644 0000000 0000000 00000000146 13777276623 011660 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/dsc/events/DSCCommentEndComments.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/dsc/events/DSCCommentEndComments.jav0100644 0000000 0000000 00000003556 13777276623 032416 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: DSCCommentEndComments.java 750418 2009-03-05 11:03:54Z vhennebert $ */ package org.apache.xmlgraphics.ps.dsc.events; import java.io.IOException; import org.apache.xmlgraphics.ps.DSCConstants; import org.apache.xmlgraphics.ps.PSGenerator; /** * Respresents a %%EndComments DSC comment. */ public class DSCCommentEndComments extends AbstractDSCComment { /** * @see org.apache.xmlgraphics.ps.dsc.events.DSCComment#getName() */ public String getName() { return DSCConstants.END_COMMENTS; } /** * @see org.apache.xmlgraphics.ps.dsc.events.DSCComment#hasValues() */ public boolean hasValues() { return false; } /** * @see org.apache.xmlgraphics.ps.dsc.events.DSCComment#parseValue(java.lang.String) */ public void parseValue(String value) { //nop } /** * @see org.apache.xmlgraphics.ps.dsc.events.DSCEvent#generate( * org.apache.xmlgraphics.ps.PSGenerator) */ public void generate(PSGenerator gen) throws IOException { gen.writeDSCComment(getName()); } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/dsc/events/DSCCommentEndOfFile.java0100644 0000000 0000000 00000003751 13777276623 032133 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: DSCCommentEndOfFile.java 750418 2009-03-05 11:03:54Z vhennebert $ */ package org.apache.xmlgraphics.ps.dsc.events; import java.io.IOException; import org.apache.xmlgraphics.ps.DSCConstants; import org.apache.xmlgraphics.ps.PSGenerator; /** * Represents a %%EOF DSC comment. */ public class DSCCommentEndOfFile extends AbstractDSCComment { /** * @see org.apache.xmlgraphics.ps.dsc.events.DSCComment#getName() */ public String getName() { return DSCConstants.EOF; } /** * @see org.apache.xmlgraphics.ps.dsc.events.DSCComment#hasValues() */ public boolean hasValues() { return false; } /** * @see org.apache.xmlgraphics.ps.dsc.events.DSCComment#parseValue(java.lang.String) */ public void parseValue(String value) { //nop } /** * @see org.apache.xmlgraphics.ps.dsc.events.DSCEvent#generate(org.apache.xmlgraphics.ps.PSGenerator) */ public void generate(PSGenerator gen) throws IOException { gen.writeDSCComment(getName()); } /** * @see org.apache.xmlgraphics.ps.dsc.events.AbstractDSCComment#getEventType() */ public int getEventType() { return EOF; } } ././@LongLink0100644 0000000 0000000 00000000153 13777276623 011656 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/dsc/events/DSCCommentHiResBoundingBox.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/dsc/events/DSCCommentHiResBoundingBo0100644 0000000 0000000 00000004126 13777276623 032376 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: DSCCommentHiResBoundingBox.java 1681108 2015-05-22 13:26:12Z ssteiner $ */ package org.apache.xmlgraphics.ps.dsc.events; import java.awt.geom.Rectangle2D; import java.io.IOException; import org.apache.xmlgraphics.ps.DSCConstants; import org.apache.xmlgraphics.ps.PSGenerator; /** * Represents a %%HiResBoundingBox DSC comment. */ public class DSCCommentHiResBoundingBox extends DSCCommentBoundingBox { /** * Creates a new instance. */ public DSCCommentHiResBoundingBox() { super(); } /** * Creates a new instance. * @param bbox the bounding box */ public DSCCommentHiResBoundingBox(Rectangle2D bbox) { super(bbox); } /** {@inheritDoc} */ public String getName() { return DSCConstants.HIRES_BBOX; } /** {@inheritDoc} */ public void generate(PSGenerator gen) throws IOException { if (getBoundingBox() != null) { gen.writeDSCComment(getName(), new Object[] { getBoundingBox().getX(), getBoundingBox().getY(), getBoundingBox().getX() + getBoundingBox().getWidth(), getBoundingBox().getY() + getBoundingBox().getHeight()}); } else { gen.writeDSCComment(getName(), DSCConstants.ATEND); } } } ././@LongLink0100644 0000000 0000000 00000000152 13777276623 011655 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/dsc/events/DSCCommentIncludeResource.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/dsc/events/DSCCommentIncludeResource0100644 0000000 0000000 00000003060 13777276623 032504 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: DSCCommentIncludeResource.java 727407 2008-12-17 15:05:45Z jeremias $ */ package org.apache.xmlgraphics.ps.dsc.events; import org.apache.xmlgraphics.ps.DSCConstants; import org.apache.xmlgraphics.ps.PSResource; /** * Represents a %IncludeResource DSC comment. */ public class DSCCommentIncludeResource extends AbstractResourceDSCComment { /** * Creates a new instance */ public DSCCommentIncludeResource() { super(); } /** * Creates a new instance for a given PSResource instance * @param resource the resource */ public DSCCommentIncludeResource(PSResource resource) { super(resource); } /** {@inheritDoc} */ public String getName() { return DSCConstants.INCLUDE_RESOURCE; } } ././@LongLink0100644 0000000 0000000 00000000150 13777276623 011653 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/dsc/events/DSCCommentLanguageLevel.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/dsc/events/DSCCommentLanguageLevel.j0100644 0000000 0000000 00000005001 13777276623 032351 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: DSCCommentLanguageLevel.java 1681108 2015-05-22 13:26:12Z ssteiner $ */ package org.apache.xmlgraphics.ps.dsc.events; import java.io.IOException; import org.apache.xmlgraphics.ps.DSCConstants; import org.apache.xmlgraphics.ps.PSGenerator; /** * Represents a %%LanguageLevel DSC comment */ public class DSCCommentLanguageLevel extends AbstractDSCComment { private int level; /** * Creates a new instance. */ public DSCCommentLanguageLevel() { } /** * Creates a new instance * @param level the PostScript language level (usually 2 or 3) */ public DSCCommentLanguageLevel(int level) { this.level = level; } /** * Returns the PostScript language level (usually 2 or 3). * @return the language level */ public int getLanguageLevel() { return this.level; } /** * @see org.apache.xmlgraphics.ps.dsc.events.DSCComment#getName() */ public String getName() { return DSCConstants.LANGUAGE_LEVEL; } /** * @see org.apache.xmlgraphics.ps.dsc.events.DSCComment#hasValues() */ public boolean hasValues() { return true; } /** * @see org.apache.xmlgraphics.ps.dsc.events.DSCComment#parseValue(java.lang.String) */ public void parseValue(String value) { this.level = Integer.parseInt(value); } /** * @see org.apache.xmlgraphics.ps.dsc.events.DSCEvent#generate(org.apache.xmlgraphics.ps.PSGenerator) */ public void generate(PSGenerator gen) throws IOException { if (level <= 0) { throw new IllegalStateException("Language Level was not properly set"); } gen.writeDSCComment(getName(), getLanguageLevel()); } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/dsc/events/DSCCommentPage.java0100644 0000000 0000000 00000007211 13777276623 031207 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: DSCCommentPage.java 1681108 2015-05-22 13:26:12Z ssteiner $ */ package org.apache.xmlgraphics.ps.dsc.events; import java.io.IOException; import java.util.Iterator; import java.util.List; import org.apache.xmlgraphics.ps.DSCConstants; import org.apache.xmlgraphics.ps.PSGenerator; /** * Represents a %%Page DSC comment. */ public class DSCCommentPage extends AbstractDSCComment { private String pageName; private int pagePosition = -1; /** * Creates a new instance. */ public DSCCommentPage() { } /** * Creates a new instance. * @param pageName the name of the page * @param pagePosition the position of the page within the file (1-based) */ public DSCCommentPage(String pageName, int pagePosition) { setPageName(pageName); setPagePosition(pagePosition); } /** * Creates a new instance. The page name will be set to the same value as the page position. * @param pagePosition the position of the page within the file (1-based) */ public DSCCommentPage(int pagePosition) { this(Integer.toString(pagePosition), pagePosition); } /** * Returns the name of the page. * @return the page name */ public String getPageName() { return this.pageName; } /** * Sets the page name. * @param name the page name */ public void setPageName(String name) { this.pageName = name; } /** * Returns the page position. * @return the page position (1-based) */ public int getPagePosition() { return this.pagePosition; } /** * Sets the page position. * @param position the page position (1-based) */ public void setPagePosition(int position) { if (position <= 0) { throw new IllegalArgumentException("position must be 1 or above"); } this.pagePosition = position; } /** * @see org.apache.xmlgraphics.ps.dsc.events.DSCComment#getName() */ public String getName() { return DSCConstants.PAGE; } /** * @see org.apache.xmlgraphics.ps.dsc.events.DSCComment#hasValues() */ public boolean hasValues() { return true; } /** * @see org.apache.xmlgraphics.ps.dsc.events.DSCComment#parseValue(java.lang.String) */ public void parseValue(String value) { List params = splitParams(value); Iterator iter = params.iterator(); this.pageName = (String)iter.next(); this.pagePosition = Integer.parseInt((String)iter.next()); } /** * @see org.apache.xmlgraphics.ps.dsc.events.DSCEvent#generate( * org.apache.xmlgraphics.ps.PSGenerator) */ public void generate(PSGenerator gen) throws IOException { gen.writeDSCComment(getName(), new Object[] {getPageName(), getPagePosition()}); } } ././@LongLink0100644 0000000 0000000 00000000152 13777276623 011655 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/dsc/events/DSCCommentPageBoundingBox.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/dsc/events/DSCCommentPageBoundingBox0100644 0000000 0000000 00000002770 13777276623 032433 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: DSCCommentPageBoundingBox.java 750418 2009-03-05 11:03:54Z vhennebert $ */ package org.apache.xmlgraphics.ps.dsc.events; import java.awt.geom.Rectangle2D; import org.apache.xmlgraphics.ps.DSCConstants; /** * Represents a %%PageBoundingBox DSC comment. */ public class DSCCommentPageBoundingBox extends DSCCommentBoundingBox { /** * Creates a new instance. */ public DSCCommentPageBoundingBox() { super(); } /** * Creates a new instance. * @param bbox the bounding box */ public DSCCommentPageBoundingBox(Rectangle2D bbox) { super(bbox); } /** {@inheritDoc} */ public String getName() { return DSCConstants.PAGE_BBOX; } } ././@LongLink0100644 0000000 0000000 00000000157 13777276623 011662 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/dsc/events/DSCCommentPageHiResBoundingBox.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/dsc/events/DSCCommentPageHiResBoundi0100644 0000000 0000000 00000003034 13777276623 032362 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: DSCCommentPageHiResBoundingBox.java 750418 2009-03-05 11:03:54Z vhennebert $ */ package org.apache.xmlgraphics.ps.dsc.events; import java.awt.geom.Rectangle2D; import org.apache.xmlgraphics.ps.DSCConstants; /** * Represents a %%PageHiResBoundingBox DSC comment. */ public class DSCCommentPageHiResBoundingBox extends DSCCommentHiResBoundingBox { /** * Creates a new instance. */ public DSCCommentPageHiResBoundingBox() { super(); } /** * Creates a new instance. * @param bbox the bounding box */ public DSCCommentPageHiResBoundingBox(Rectangle2D bbox) { super(bbox); } /** {@inheritDoc} */ public String getName() { return DSCConstants.PAGE_HIRES_BBOX; } } ././@LongLink0100644 0000000 0000000 00000000150 13777276623 011653 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/dsc/events/DSCCommentPageResources.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/dsc/events/DSCCommentPageResources.j0100644 0000000 0000000 00000003123 13777276623 032410 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: DSCCommentPageResources.java 750418 2009-03-05 11:03:54Z vhennebert $ */ package org.apache.xmlgraphics.ps.dsc.events; import java.util.Collection; import org.apache.xmlgraphics.ps.DSCConstants; /** * Represents a %%PageResources DSC comment. */ public class DSCCommentPageResources extends AbstractResourcesDSCComment { /** * Creates a new instance. */ public DSCCommentPageResources() { super(); } /** * Creates a new instance. * @param resources a Collection of PSResource instances */ public DSCCommentPageResources(Collection resources) { super(resources); } /** * @see org.apache.xmlgraphics.ps.dsc.events.DSCComment#getName() */ public String getName() { return DSCConstants.PAGE_RESOURCES; } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/dsc/events/DSCCommentPages.java0100644 0000000 0000000 00000005133 13777276623 031373 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: DSCCommentPages.java 1681108 2015-05-22 13:26:12Z ssteiner $ */ package org.apache.xmlgraphics.ps.dsc.events; import java.io.IOException; import org.apache.xmlgraphics.ps.DSCConstants; import org.apache.xmlgraphics.ps.PSGenerator; /** * Represents the %%Pages DSC comment. */ public class DSCCommentPages extends AbstractDSCComment { private int pageCount = -1; /** * Creates a new instance. */ public DSCCommentPages() { } /** * Creates a new instance. * @param pageCount the number of pages */ public DSCCommentPages(int pageCount) { this.pageCount = pageCount; } /** * Returns the page count. * @return the page count */ public int getPageCount() { return this.pageCount; } /** * Sets the page count. * @param count the new page count */ public void setPageCount(int count) { this.pageCount = count; } /** * @see org.apache.xmlgraphics.ps.dsc.events.DSCComment#getName() */ public String getName() { return DSCConstants.PAGES; } /** * @see org.apache.xmlgraphics.ps.dsc.events.DSCComment#hasValues() */ public boolean hasValues() { return true; } /** * @see org.apache.xmlgraphics.ps.dsc.events.DSCComment#parseValue(java.lang.String) */ public void parseValue(String value) { this.pageCount = Integer.parseInt(value); } /** * @see org.apache.xmlgraphics.ps.dsc.events.DSCEvent#generate(org.apache.xmlgraphics.ps.PSGenerator) */ public void generate(PSGenerator gen) throws IOException { if (getPageCount() > 0) { gen.writeDSCComment(getName(), getPageCount()); } else { gen.writeDSCComment(getName(), DSCConstants.ATEND); } } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/dsc/events/DSCCommentTitle.java0100644 0000000 0000000 00000004132 13777276623 031413 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: DSCCommentTitle.java 727407 2008-12-17 15:05:45Z jeremias $ */ package org.apache.xmlgraphics.ps.dsc.events; import java.io.IOException; import java.util.Iterator; import java.util.List; import org.apache.xmlgraphics.ps.DSCConstants; import org.apache.xmlgraphics.ps.PSGenerator; /** * Represents a %%Title DSC comment. */ public class DSCCommentTitle extends AbstractDSCComment { private String title; /** * Creates a new instance. */ public DSCCommentTitle() { } /** * Creates a new instance. * @param title the title text */ public DSCCommentTitle(String title) { this.title = title; } /** * Returns the title. * @return the title */ public String getTitle() { return this.title; } /** {@inheritDoc} */ public String getName() { return DSCConstants.TITLE; } /** {@inheritDoc} */ public boolean hasValues() { return true; } /** {@inheritDoc} */ public void parseValue(String value) { List params = splitParams(value); Iterator iter = params.iterator(); this.title = (String)iter.next(); } /** {@inheritDoc} */ public void generate(PSGenerator gen) throws IOException { gen.writeDSCComment(getName(), getTitle()); } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/dsc/events/DSCEvent.java0100644 0000000 0000000 00000005152 13777276623 030073 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: DSCEvent.java 750418 2009-03-05 11:03:54Z vhennebert $ */ package org.apache.xmlgraphics.ps.dsc.events; import java.io.IOException; import org.apache.xmlgraphics.ps.PSGenerator; import org.apache.xmlgraphics.ps.dsc.DSCParserConstants; /** * Interface representing a DSC event. A DSC event can be a DSC comment, a PostScript comment * or a line of PostScript code. */ public interface DSCEvent extends DSCParserConstants { /** * Returns the event type. * @return the event type (see {@link DSCParserConstants}) */ int getEventType(); /** * Casts this instance to a DSCComment if possible. * @return this event as a DSCComment * @throws ClassCastException if the event is no DSCComment */ DSCComment asDSCComment(); /** * Casts this instance to a PostScriptLine if possible. * @return this event as a PostScriptLine * @throws ClassCastException if the event is no PostScriptLine */ PostScriptLine asLine(); /** * Indicates whether the instance is a DSC comment. * @return true if the instance is a DSC comment */ boolean isDSCComment(); /** * Indicates whether the instance is a PostScript comment. * @return true if the instance is a PostScript comment */ boolean isComment(); /** * Indicates whether the instance is a header comment. * @return true if the instance is a header comment */ boolean isHeaderComment(); /** * Indicates whether the instance is a PostScript line. * @return true if the instance is a PostScript line */ boolean isLine(); /** * Writes the event to the given PSGenerator. * @param gen the PSGenerator to write to * @throws IOException In case of an I/O error */ void generate(PSGenerator gen) throws IOException; } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/dsc/events/DSCHeaderComment.java0100644 0000000 0000000 00000004464 13777276623 031532 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: DSCHeaderComment.java 750418 2009-03-05 11:03:54Z vhennebert $ */ package org.apache.xmlgraphics.ps.dsc.events; import java.io.IOException; import org.apache.xmlgraphics.ps.DSCConstants; import org.apache.xmlgraphics.ps.PSGenerator; /** * Represents a DSC header comment (beginning with "%!). */ public class DSCHeaderComment extends AbstractEvent { private String comment; /** * Creates a new instance. * @param comment the comment */ public DSCHeaderComment(String comment) { this.comment = comment; } /** * Returns the comment. * @return the comment */ public String getComment() { return this.comment; } /** * Indicates whether the file started by this comments is DSC 3.0 compliant. * @return true if the file is DSC 3.0 compliant. */ public boolean isPSAdobe30() { return getComment().startsWith(DSCConstants.PS_ADOBE_30.substring(2)); } /** * @see org.apache.xmlgraphics.ps.dsc.events.DSCEvent#generate( * org.apache.xmlgraphics.ps.PSGenerator) */ public void generate(PSGenerator gen) throws IOException { gen.writeln("%!" + getComment()); } /** * @see org.apache.xmlgraphics.ps.dsc.events.DSCEvent#getEventType() */ public int getEventType() { return HEADER_COMMENT; } /** * @see org.apache.xmlgraphics.ps.dsc.events.AbstractEvent#isHeaderComment() */ public boolean isHeaderComment() { return true; } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/dsc/events/PostScriptComment.java0100644 0000000 0000000 00000004142 13777276623 032113 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: PostScriptComment.java 1681108 2015-05-22 13:26:12Z ssteiner $ */ package org.apache.xmlgraphics.ps.dsc.events; import java.io.IOException; import org.apache.xmlgraphics.ps.PSGenerator; /** * Represents a PostScript comment */ public class PostScriptComment extends AbstractEvent { private String comment; /** * Creates a new instance. * @param comment the comment */ public PostScriptComment(String comment) { if (comment != null && comment.startsWith("%")) { this.comment = comment.substring(1); } else { this.comment = comment; } } /** * Returns the comment text. * @return the comment (without the "%" prefix) */ public String getComment() { return this.comment; } /** * @see org.apache.xmlgraphics.ps.dsc.events.DSCEvent#generate(org.apache.xmlgraphics.ps.PSGenerator) */ public void generate(PSGenerator gen) throws IOException { gen.commentln("%" + getComment()); } /** * @see org.apache.xmlgraphics.ps.dsc.events.DSCEvent#getEventType() */ public int getEventType() { return COMMENT; } /** * @see org.apache.xmlgraphics.ps.dsc.events.AbstractEvent#isComment() */ public boolean isComment() { return true; } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/dsc/events/PostScriptLine.java0100644 0000000 0000000 00000004056 13777276623 031404 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: PostScriptLine.java 750418 2009-03-05 11:03:54Z vhennebert $ */ package org.apache.xmlgraphics.ps.dsc.events; import java.io.IOException; import org.apache.xmlgraphics.ps.PSGenerator; /** * Represents a line of PostScript code. */ public class PostScriptLine extends AbstractEvent { private String line; /** * Creates a new instance. * @param line the code line */ public PostScriptLine(String line) { this.line = line; } /** * Returns the code line. * @return the code line */ public String getLine() { return this.line; } /** * @see org.apache.xmlgraphics.ps.dsc.events.DSCEvent#generate(org.apache.xmlgraphics.ps.PSGenerator) */ public void generate(PSGenerator gen) throws IOException { gen.writeln(getLine()); } /** * @see org.apache.xmlgraphics.ps.dsc.events.DSCEvent#getEventType() */ public int getEventType() { return LINE; } /** * @see org.apache.xmlgraphics.ps.dsc.events.AbstractEvent#asLine() */ public PostScriptLine asLine() { return this; } /** * @see org.apache.xmlgraphics.ps.dsc.events.AbstractEvent#isLine() */ public boolean isLine() { return true; } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/dsc/events/UnparsedDSCComment.java0100644 0000000 0000000 00000005554 13777276623 032124 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: UnparsedDSCComment.java 750418 2009-03-05 11:03:54Z vhennebert $ */ package org.apache.xmlgraphics.ps.dsc.events; import java.io.IOException; import org.apache.xmlgraphics.ps.PSGenerator; /** * Represents a DSC comment that is not parsed into one of the concrete DSCComment subclasses. * It is used whenever a DSC comment is encountered that is unknown to the parser. * @see org.apache.xmlgraphics.ps.dsc.DSCCommentFactory */ public class UnparsedDSCComment extends AbstractEvent implements DSCComment { private String name; private String value; /** * Creates a new instance. * @param name the name of the DSC comment */ public UnparsedDSCComment(String name) { this.name = name; } /** * @see org.apache.xmlgraphics.ps.dsc.events.DSCComment#getName() */ public String getName() { return this.name; } /** * @see org.apache.xmlgraphics.ps.dsc.events.DSCComment#hasValues() */ public boolean hasValues() { return value != null; } /** * @see org.apache.xmlgraphics.ps.dsc.events.DSCComment#isAtend() */ public boolean isAtend() { return false; } /** * @see org.apache.xmlgraphics.ps.dsc.events.DSCComment#parseValue(java.lang.String) */ public void parseValue(String value) { this.value = value; } /** * @see org.apache.xmlgraphics.ps.dsc.events.DSCEvent#generate(org.apache.xmlgraphics.ps.PSGenerator) */ public void generate(PSGenerator gen) throws IOException { gen.writeln("%%" + name + (hasValues() ? ": " + value : "")); } /** * @see org.apache.xmlgraphics.ps.dsc.events.AbstractEvent#isDSCComment() */ public boolean isDSCComment() { return true; } /** * @see org.apache.xmlgraphics.ps.dsc.events.DSCEvent#getEventType() */ public int getEventType() { return DSC_COMMENT; } /** * @see org.apache.xmlgraphics.ps.dsc.events.AbstractEvent#asDSCComment() */ public DSCComment asDSCComment() { return this; } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/dsc/events/package.html0100644 0000000 0000000 00000001651 13777276623 030076 0ustar000000000 0000000 org.apache.xmlgraphics.ps.dsc.events Package

    Event classes used by the DSC parser.

    xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/dsc/package.html0100644 0000000 0000000 00000001717 13777276623 026575 0ustar000000000 0000000 org.apache.xmlgraphics.ps.dsc Package

    Tools for DSC-compliant PostScript files (DSC = Document Structuring Conventions).

    xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/dsc/tools/DSCTools.java0100644 0000000 0000000 00000011465 13777276623 027752 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: DSCTools.java 1681108 2015-05-22 13:26:12Z ssteiner $ */ package org.apache.xmlgraphics.ps.dsc.tools; import java.io.IOException; import org.apache.xmlgraphics.ps.DSCConstants; import org.apache.xmlgraphics.ps.PSGenerator; import org.apache.xmlgraphics.ps.dsc.DSCException; import org.apache.xmlgraphics.ps.dsc.DSCParser; import org.apache.xmlgraphics.ps.dsc.DSCParserConstants; import org.apache.xmlgraphics.ps.dsc.events.DSCComment; import org.apache.xmlgraphics.ps.dsc.events.DSCEvent; import org.apache.xmlgraphics.ps.dsc.events.DSCHeaderComment; import org.apache.xmlgraphics.ps.dsc.events.PostScriptComment; /** * Helper methods commonly used when dealing with DSC-compliant PostScript files. */ public final class DSCTools implements DSCParserConstants { private DSCTools() { } /** * Indicates whether the given event ends a header comment section according to the rules in * DSC 3.0, chapter 4.4. * @param event the event to check * @return true if a header comment section would be ended either explicitely or implicitely * by the given event */ public static boolean headerCommentsEndHere(DSCEvent event) { switch (event.getEventType()) { case DSC_COMMENT: DSCComment comment = event.asDSCComment(); return (comment.getName().equals(DSCConstants.END_COMMENTS)); case COMMENT: assert event instanceof PostScriptComment; String s = ((PostScriptComment)event).getComment(); if (s == null || s.length() == 0) { return true; } else { char c = s.charAt(0); return ("\n\t ".indexOf(c) >= 0); } default: return true; } } /** * Verifies that the file being parsed is a DSC 3.0 file. * @param parser the DSC parser * @return the header comment event * @throws DSCException In case of a violation of the DSC spec * @throws IOException In case of an I/O problem */ public static DSCHeaderComment checkAndSkipDSC30Header(DSCParser parser) throws DSCException, IOException { if (!parser.hasNext()) { throw new DSCException("File has no content"); } DSCEvent event = parser.nextEvent(); if (event.getEventType() == HEADER_COMMENT) { DSCHeaderComment header = (DSCHeaderComment)event; if (!header.isPSAdobe30()) { throw new DSCException("PostScript file does not start with '" + DSCConstants.PS_ADOBE_30 + "'"); } return header; } else { throw new DSCException("PostScript file does not start with '" + DSCConstants.PS_ADOBE_30 + "'"); } } /** * Advances the parser to the next page or to the trailer or the end of file comment. * @param parser the DSC parser * @param gen the PSGenerator instance to pass the skipped events through to * @return the DSC comment found (Page, Trailer or EOF) * @throws IOException In case of an I/O error * @throws DSCException In case of a violation of the DSC spec */ public static DSCComment nextPageOrTrailer(DSCParser parser, PSGenerator gen) throws IOException, DSCException { while (parser.hasNext()) { DSCEvent event = parser.nextEvent(); if (event.getEventType() == DSC_COMMENT) { DSCComment comment = event.asDSCComment(); if (DSCConstants.PAGE.equals(comment.getName())) { return comment; } else if (DSCConstants.TRAILER.equals(comment.getName())) { return comment; } } else if (event.getEventType() == EOF) { //The Trailer may be missing return event.asDSCComment(); } if (gen != null) { event.generate(gen); //Pipe through to PSGenerator } } return null; } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/dsc/tools/PageExtractor.java0100644 0000000 0000000 00000011445 13777276623 031066 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: PageExtractor.java 1345683 2012-06-03 14:50:33Z gadams $ */ package org.apache.xmlgraphics.ps.dsc.tools; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.apache.xmlgraphics.ps.DSCConstants; import org.apache.xmlgraphics.ps.PSGenerator; import org.apache.xmlgraphics.ps.dsc.DSCException; import org.apache.xmlgraphics.ps.dsc.DSCFilter; import org.apache.xmlgraphics.ps.dsc.DSCParser; import org.apache.xmlgraphics.ps.dsc.DSCParserConstants; import org.apache.xmlgraphics.ps.dsc.DefaultNestedDocumentHandler; import org.apache.xmlgraphics.ps.dsc.events.DSCComment; import org.apache.xmlgraphics.ps.dsc.events.DSCCommentPage; import org.apache.xmlgraphics.ps.dsc.events.DSCCommentPages; import org.apache.xmlgraphics.ps.dsc.events.DSCEvent; import org.apache.xmlgraphics.ps.dsc.events.DSCHeaderComment; /** * This class can extract a certain range of pages from a DSC-compliant PostScript file. */ public final class PageExtractor implements DSCParserConstants { private PageExtractor() { } /** * Parses a DSC-compliant file and pipes the content through to the OutputStream omitting * all pages not within the range. * @param in the InputStream to parse from * @param out the OutputStream to write the modified file to * @param from the starting page (1-based) * @param to the last page (inclusive, 1-based) * @throws IOException In case of an I/O error * @throws DSCException In case of a violation of the DSC spec */ public static void extractPages(InputStream in, OutputStream out, int from, int to) throws IOException, DSCException { if (from <= 0) { throw new IllegalArgumentException("'from' page number must be 1 or higher"); } if (to < from) { throw new IllegalArgumentException( "'to' page number must be equal or larger than the 'from' page number"); } DSCParser parser = new DSCParser(in); PSGenerator gen = new PSGenerator(out); parser.addListener(new DefaultNestedDocumentHandler(gen)); int pageCount = 0; //Skip DSC header DSCHeaderComment header = DSCTools.checkAndSkipDSC30Header(parser); header.generate(gen); //Set number of pages DSCCommentPages pages = new DSCCommentPages(to - from + 1); pages.generate(gen); parser.setFilter(new DSCFilter() { public boolean accept(DSCEvent event) { if (event.isDSCComment()) { //Filter %%Pages which we add manually above return !event.asDSCComment().getName().equals(DSCConstants.PAGES); } else { return true; } } }); //Skip the prolog and to the first page DSCComment pageOrTrailer = parser.nextDSCComment(DSCConstants.PAGE, gen); if (pageOrTrailer == null) { throw new DSCException("Page expected, but none found"); } parser.setFilter(null); //Remove filter //Process individual pages (and skip as necessary) while (true) { DSCCommentPage page = (DSCCommentPage)pageOrTrailer; boolean validPage = (page.getPagePosition() >= from && page.getPagePosition() <= to); if (validPage) { page.setPagePosition(page.getPagePosition() - from + 1); page.generate(gen); pageCount++; } pageOrTrailer = DSCTools.nextPageOrTrailer(parser, (validPage ? gen : null)); if (pageOrTrailer == null) { throw new DSCException("File is not DSC-compliant: Unexpected end of file"); } else if (!DSCConstants.PAGE.equals(pageOrTrailer.getName())) { pageOrTrailer.generate(gen); break; } } //Write the rest while (parser.hasNext()) { DSCEvent event = parser.nextEvent(); event.generate(gen); } } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/dsc/tools/package.html0100644 0000000 0000000 00000001671 13777276623 027734 0ustar000000000 0000000 org.apache.xmlgraphics.ps.dsc.tools Package

    Tools for working with DSC-compliant PostScript files.

    xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/ps/package.html0100644 0000000 0000000 00000001656 13777276623 026026 0ustar000000000 0000000 org.apache.xmlgraphics.commons.ps Package

    Classes for the creation of PostScript files.

    xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/util/ClasspathResource.java0100644 0000000 0000000 00000013071 13777276623 030367 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ClasspathResource.java 1804124 2017-08-04 14:13:54Z ssteiner $ */ package org.apache.xmlgraphics.util; import java.io.IOException; import java.net.URL; import java.util.Collections; import java.util.Enumeration; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.Vector; import java.util.jar.Attributes; import java.util.jar.Manifest; /** * A class to find resources in the classpath by their mime-type specified in * the MANIFEST. *

    * This class searches for content entries in all META-INF/MANIFEST.MF files. It * will find files with a given Content-Type: attribute. This allows to add * arbitrary resources by content-type just by creating a JAR wrapper and adding * them to the classpath. *

    * Example:
    * *

     * Name: test.txt
     * Content-Type: text/plain
     * 
    */ public final class ClasspathResource { /** * Actual Type: Map<String,List<URL>>. */ private final Map contentMappings; private static final String MANIFEST_PATH = "META-INF/MANIFEST.MF"; private static final String CONTENT_TYPE_KEY = "Content-Type"; private static ClasspathResource classpathResource; private ClasspathResource() { contentMappings = new HashMap(); loadManifests(); } /** * Retrieve the singleton instance of this class. * * @return the ClassPathResource instance. */ public static synchronized ClasspathResource getInstance() { if (classpathResource == null) { classpathResource = new ClasspathResource(); } return classpathResource; } /* Actual return type: Set */ private Set getClassLoadersForResources() { Set v = new HashSet(); try { ClassLoader l = ClassLoader.getSystemClassLoader(); if (l != null) { v.add(l); } } catch (SecurityException e) { // Ignore } try { ClassLoader l = Thread.currentThread().getContextClassLoader(); if (l != null) { v.add(l); } } catch (SecurityException e) { // Ignore } try { ClassLoader l = ClasspathResource.class.getClassLoader(); if (l != null) { v.add(l); } } catch (SecurityException e) { // Ignore } return v; } private void loadManifests() { Enumeration e; try { for (Object o1 : getClassLoadersForResources()) { ClassLoader classLoader = (ClassLoader) o1; e = classLoader.getResources(MANIFEST_PATH); while (e.hasMoreElements()) { final URL u = (URL) e.nextElement(); try { final Manifest manifest = new Manifest(u.openStream()); final Map entries = manifest.getEntries(); for (Object o : entries.entrySet()) { final Map.Entry entry = (Map.Entry) o; final String name = (String) entry.getKey(); final Attributes attributes = (Attributes) entry .getValue(); final String contentType = attributes .getValue(CONTENT_TYPE_KEY); if (contentType != null) { addToMapping(contentType, name, classLoader); } } } catch (IOException io) { // TODO: Log. } } } } catch (IOException io) { // TODO: Log. } } private void addToMapping(final String contentType, final String name, final ClassLoader classLoader) { List existingFiles = (List) contentMappings.get(contentType); if (existingFiles == null) { existingFiles = new Vector(); contentMappings.put(contentType, existingFiles); } final URL url = classLoader.getResource(name); if (url != null) { existingFiles.add(url); } } /** * Retrieve a list of resources known to have the given mime-type. * * @param mimeType * the mime-type to search for. * @return a List<URL>, guaranteed to be != null. */ public List listResourcesOfMimeType(final String mimeType) { final List content = (List) contentMappings.get(mimeType); if (content == null) { return Collections.EMPTY_LIST; } else { return content; } } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/util/DateFormatUtil.java0100644 0000000 0000000 00000013550 13777276623 027623 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.xmlgraphics.util; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.Locale; import java.util.TimeZone; public final class DateFormatUtil { private static final String ISO_8601_DATE_PATTERN = "yyyy-MM-dd'T'HH:mm:ss"; private DateFormatUtil() { } /** * Formats the date according to PDF format. See section 3.8.2 of the PDF 1.4 specification. * @param date The date time to format * @param timeZone The time zone used to format the date * @return a formatted date according to PDF format (based on ISO 8824) */ public static String formatPDFDate(Date date, TimeZone timeZone) { DateFormat dateFormat = createDateFormat("'D:'yyyyMMddHHmmss", timeZone); return formatDate(date, dateFormat, '\'', true); } /** * Formats the date according to ISO 8601 standard. * @param date The date time to format * @param timeZone The time zone used to format the date * @return a formatted date according to ISO 8601 */ public static String formatISO8601(Date date, TimeZone timeZone) { DateFormat dateFormat = createDateFormat(ISO_8601_DATE_PATTERN, timeZone); return formatDate(date, dateFormat, ':', false); } private static DateFormat createDateFormat(String format, TimeZone timeZone) { DateFormat dateFormat = new SimpleDateFormat(format, Locale.ENGLISH); dateFormat.setTimeZone(timeZone); return dateFormat; } /** * Formats the date according to the specified format and returns as a string. * @param date The date / time object to format * @param dateFormat The date format to use when outputting the date * @param delimiter The character used to separate the time zone difference hours and minutes * @param endWithDelimiter Determines whether the date string will end with the delimiter character * @return the formatted date string */ private static String formatDate(Date date, DateFormat dateFormat, char delimiter, boolean endWithDelimiter) { Calendar cal = Calendar.getInstance(dateFormat.getTimeZone(), Locale.ENGLISH); cal.setTime(date); int offset = getOffsetInMinutes(cal); StringBuilder sb = new StringBuilder(dateFormat.format(date)); appendOffset(sb, delimiter, offset, endWithDelimiter); return sb.toString(); } private static int getOffsetInMinutes(Calendar cal) { int offset = cal.get(Calendar.ZONE_OFFSET); offset += cal.get(Calendar.DST_OFFSET); offset /= (1000 * 60); return offset; } private static void appendOffset(StringBuilder sb, char delimiter, int offset, boolean endWithDelimiter) { if (offset == 0) { appendOffsetUTC(sb); } else { appendOffsetNoUTC(sb, delimiter, offset, endWithDelimiter); } } private static void appendOffsetUTC(StringBuilder sb) { sb.append('Z'); } private static void appendOffsetNoUTC(StringBuilder sb, char delimiter, int offset, boolean endWithDelimiter) { int zoneOffsetHours = offset / 60; appendOffsetSign(sb, zoneOffsetHours); appendPaddedNumber(sb, Math.abs(zoneOffsetHours)); sb.append(delimiter); appendPaddedNumber(sb, Math.abs(offset % 60)); if (endWithDelimiter) { sb.append(delimiter); } } private static void appendOffsetSign(StringBuilder sb, int zoneOffsetHours) { if (zoneOffsetHours >= 0) { sb.append('+'); } else { sb.append('-'); } } private static void appendPaddedNumber(StringBuilder sb, int number) { if (number < 10) { sb.append('0'); } sb.append(number); } /** * Parses an ISO 8601 date and time value. * @param date the date and time value as an ISO 8601 string * @return the parsed date/time */ public static Date parseISO8601Date(String date) { final String errorMessage = "Invalid ISO 8601 date format: "; date = formatDateToParse(date, errorMessage); DateFormat dateFormat = new SimpleDateFormat(ISO_8601_DATE_PATTERN + "Z"); try { return dateFormat.parse(date); } catch (ParseException ex) { throw new IllegalArgumentException(errorMessage + date); } } private static String formatDateToParse(String date, String errorMessage) { /* Remove the colon from the time zone difference (+08:00) so that it can be parsed * by the SimpleDateFormat string. */ if (!date.contains("Z")) { int lastColonIndex = date.lastIndexOf(":"); if (lastColonIndex < 0) { throw new IllegalArgumentException(errorMessage + date); } date = date.substring(0, lastColonIndex) + date.substring(lastColonIndex + 1, date.length()); } else { date = date.replace("Z", "+0000"); } return date; } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/util/DoubleFormatUtil.java0100644 0000000 0000000 00000036251 13777276623 030163 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: DoubleFormatUtil.java 1732019 2016-02-24 05:01:10Z gadams $ */ package org.apache.xmlgraphics.util; /** * This class implements fast, thread-safe format of a double value * with a given number of decimal digits. *

    * The contract for the format methods is this one: * if the source is greater than or equal to 1 (in absolute value), * use the decimals parameter to define the number of decimal digits; else, * use the precision parameter to define the number of decimal digits. *

    * A few examples (consider decimals being 4 and precision being 8): *

      *
    • 0.0 should be rendered as "0" *
    • 0.1 should be rendered as "0.1" *
    • 1234.1 should be rendered as "1234.1" *
    • 1234.1234567 should be rendered as "1234.1235" (note the trailing 5! Rounding!) *
    • 1234.00001 should be rendered as "1234" *
    • 0.00001 should be rendered as "0.00001" (here you see the effect of the "precision" parameter) *
    • 0.00000001 should be rendered as "0.00000001" *
    • 0.000000001 should be rendered as "0" *
    * * Originally authored by Julien Aymé. */ public final class DoubleFormatUtil { private DoubleFormatUtil() { } /** * Rounds the given source value at the given precision * and writes the rounded value into the given target * * @param source the source value to round * @param decimals the decimals to round at (use if abs(source) ≥ 1.0) * @param precision the precision to round at (use if abs(source) < 1.0) * @param target the buffer to write to */ public static void formatDouble(double source, int decimals, int precision, StringBuffer target) { int scale = (Math.abs(source) >= 1.0) ? decimals : precision; if (tooManyDigitsUsed(source, scale) || tooCloseToRound(source, scale)) { formatDoublePrecise(source, decimals, precision, target); } else { formatDoubleFast(source, decimals, precision, target); } } /** * Rounds the given source value at the given precision * and writes the rounded value into the given target *

    * This method internally uses the String representation of the source value, * in order to avoid any double precision computation error. * * @param source the source value to round * @param decimals the decimals to round at (use if abs(source) ≥ 1.0) * @param precision the precision to round at (use if abs(source) < 1.0) * @param target the buffer to write to */ public static void formatDoublePrecise(double source, int decimals, int precision, StringBuffer target) { if (isRoundedToZero(source, decimals, precision)) { // Will always be rounded to 0 target.append('0'); return; } else if (Double.isNaN(source) || Double.isInfinite(source)) { // Cannot be formated target.append(Double.toString(source)); return; } boolean negative = source < 0.0; if (negative) { source = -source; // Done once and for all target.append('-'); } int scale = (source >= 1.0) ? decimals : precision; // The only way to format precisely the double is to use the String // representation of the double, and then to do mathematical integer operation on it. String s = Double.toString(source); if (source >= 1e-3 && source < 1e7) { // Plain representation of double: "intPart.decimalPart" int dot = s.indexOf('.'); String decS = s.substring(dot + 1); int decLength = decS.length(); if (scale >= decLength) { if ("0".equals(decS)) { // source is a mathematical integer target.append(s.substring(0, dot)); } else { target.append(s); // Remove trailing zeroes for (int l = target.length() - 1; l >= 0 && target.charAt(l) == '0'; l--) { target.setLength(l); } } return; } else if (scale + 1 < decLength) { // ignore unnecessary digits decLength = scale + 1; decS = decS.substring(0, decLength); } long intP = Long.parseLong(s.substring(0, dot)); long decP = Long.parseLong(decS); format(target, scale, intP, decP); } else { // Scientific representation of double: "x.xxxxxEyyy" int dot = s.indexOf('.'); assert dot >= 0; int exp = s.indexOf('E'); assert exp >= 0; int exposant = Integer.parseInt(s.substring(exp + 1)); String intS = s.substring(0, dot); String decS = s.substring(dot + 1, exp); int decLength = decS.length(); if (exposant >= 0) { int digits = decLength - exposant; if (digits <= 0) { // no decimal part, // no rounding involved target.append(intS); target.append(decS); for (int i = -digits; i > 0; i--) { target.append('0'); } } else if (digits <= scale) { // decimal part precision is lower than scale, // no rounding involved target.append(intS); target.append(decS.substring(0, exposant)); target.append('.'); target.append(decS.substring(exposant)); } else { // decimalDigits > scale, // Rounding involved long intP = Long.parseLong(intS) * tenPow(exposant) + Long.parseLong(decS.substring(0, exposant)); long decP = Long.parseLong(decS.substring(exposant, exposant + scale + 1)); format(target, scale, intP, decP); } } else { // Only a decimal part is supplied exposant = -exposant; int digits = scale - exposant + 1; if (digits < 0) { target.append('0'); } else if (digits == 0) { long decP = Long.parseLong(intS); format(target, scale, 0L, decP); } else if (decLength < digits) { long decP = Long.parseLong(intS) * tenPow(decLength + 1) + Long.parseLong(decS) * 10; format(target, exposant + decLength, 0L, decP); } else { long subDecP = Long.parseLong(decS.substring(0, digits)); long decP = Long.parseLong(intS) * tenPow(digits) + subDecP; format(target, scale, 0L, decP); } } } } /** * Returns true if the given source value will be rounded to zero * * @param source the source value to round * @param decimals the decimals to round at (use if abs(source) ≥ 1.0) * @param precision the precision to round at (use if abs(source) < 1.0) * @return true if the source value will be rounded to zero */ private static boolean isRoundedToZero(double source, int decimals, int precision) { // Use 4.999999999999999 instead of 5 since in some cases, 5.0 / 1eN > 5e-N (e.g. for N = 37, 42, 45, 66, ...) return source == 0.0 || Math.abs(source) < 4.999999999999999 / tenPowDouble(Math.max(decimals, precision) + 1); } /** * Most used power of ten (to avoid the cost of Math.pow(10, n) */ private static final long[] POWERS_OF_TEN_LONG = new long[19]; private static final double[] POWERS_OF_TEN_DOUBLE = new double[30]; static { POWERS_OF_TEN_LONG[0] = 1L; for (int i = 1; i < POWERS_OF_TEN_LONG.length; i++) { POWERS_OF_TEN_LONG[i] = POWERS_OF_TEN_LONG[i - 1] * 10L; } for (int i = 0; i < POWERS_OF_TEN_DOUBLE.length; i++) { POWERS_OF_TEN_DOUBLE[i] = Double.parseDouble("1e" + i); } } /** * Returns ten to the power of n * * @param n the nth power of ten to get * @return ten to the power of n */ public static long tenPow(int n) { assert n >= 0; return n < POWERS_OF_TEN_LONG.length ? POWERS_OF_TEN_LONG[n] : (long) Math.pow(10, n); } private static double tenPowDouble(int n) { assert n >= 0; return n < POWERS_OF_TEN_DOUBLE.length ? POWERS_OF_TEN_DOUBLE[n] : Math.pow(10, n); } /** * Helper method to do the custom rounding used within formatDoublePrecise * * @param target the buffer to write to * @param scale the expected rounding scale * @param intP the source integer part * @param decP the source decimal part, truncated to scale + 1 digit */ private static void format(StringBuffer target, int scale, long intP, long decP) { if (decP != 0L) { // decP is the decimal part of source, truncated to scale + 1 digit. // Custom rounding: add 5 decP += 5L; decP /= 10L; if (decP >= tenPowDouble(scale)) { intP++; decP -= tenPow(scale); } if (decP != 0L) { // Remove trailing zeroes while (decP % 10L == 0L) { decP = decP / 10L; scale--; } } } target.append(intP); if (decP != 0L) { target.append('.'); // Use tenPow instead of tenPowDouble for scale below 18, // since the casting of decP to double may cause some imprecisions: // E.g. for decP = 9999999999999999L and scale = 17, // decP < tenPow(16) while (double) decP == tenPowDouble(16) while (scale > 0 && (scale > 18 ? decP < tenPowDouble(--scale) : decP < tenPow(--scale))) { // Insert leading zeroes target.append('0'); } target.append(decP); } } /** * Rounds the given source value at the given precision * and writes the rounded value into the given target *

    * This method internally uses double precision computation and rounding, * so the result may not be accurate (see formatDouble method for conditions). * * @param source the source value to round * @param decimals the decimals to round at (use if abs(source) ≥ 1.0) * @param precision the precision to round at (use if abs(source) < 1.0) * @param target the buffer to write to */ public static void formatDoubleFast(double source, int decimals, int precision, StringBuffer target) { if (isRoundedToZero(source, decimals, precision)) { // Will always be rounded to 0 target.append('0'); return; } else if (Double.isNaN(source) || Double.isInfinite(source)) { // Cannot be formated target.append(Double.toString(source)); return; } boolean isPositive = source >= 0.0; source = Math.abs(source); int scale = (source >= 1.0) ? decimals : precision; long intPart = (long) Math.floor(source); double tenScale = tenPowDouble(scale); double fracUnroundedPart = (source - intPart) * tenScale; long fracPart = Math.round(fracUnroundedPart); if (fracPart >= tenScale) { intPart++; fracPart = Math.round(fracPart - tenScale); } if (fracPart != 0L) { // Remove trailing zeroes while (fracPart % 10L == 0L) { fracPart = fracPart / 10L; scale--; } } if (intPart != 0L || fracPart != 0L) { // non-zero value if (!isPositive) { // negative value, insert sign target.append('-'); } // append integer part target.append(intPart); if (fracPart != 0L) { // append fractional part target.append('.'); // insert leading zeroes while (scale > 0 && fracPart < tenPowDouble(--scale)) { target.append('0'); } target.append(fracPart); } } else { target.append('0'); } } /** * Returns the exponent of the given value * * @param value the value to get the exponent from * @return the value's exponent */ public static int getExponant(double value) { // See Double.doubleToRawLongBits javadoc or IEEE-754 spec // to have this algorithm long exp = Double.doubleToRawLongBits(value) & 0x7ff0000000000000L; exp = exp >> 52; return (int) (exp - 1023L); } /** * Returns true if the rounding is considered to use too many digits * of the double for a fast rounding * * @param source the source to round * @param scale the scale to round at * @return true if the rounding will potentially use too many digits */ private static boolean tooManyDigitsUsed(double source, int scale) { // if scale >= 308, 10^308 ~= Infinity double decExp = Math.log10(source); return scale >= 308 || decExp + scale >= 14.5; } /** * Returns true if the given source is considered to be too close * of a rounding value for the given scale. * * @param source the source to round * @param scale the scale to round at * @return true if the source will be potentially rounded at the scale */ private static boolean tooCloseToRound(double source, int scale) { source = Math.abs(source); long intPart = (long) Math.floor(source); double fracPart = (source - intPart) * tenPowDouble(scale); double decExp = Math.log10(source); double range = decExp + scale >= 12 ? .1 : .001; double distanceToRound1 = Math.abs(fracPart - Math.floor(fracPart)); double distanceToRound2 = Math.abs(fracPart - Math.floor(fracPart) - 0.5); return distanceToRound1 <= range || distanceToRound2 <= range; // .001 range: Totally arbitrary range, // I never had a failure in 10e7 random tests with this value // May be JVM dependent or architecture dependent } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/util/ImageIODebugUtil.java0100644 0000000 0000000 00000005025 13777276623 030014 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageIODebugUtil.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.util; import javax.imageio.metadata.IIOMetadata; import javax.imageio.metadata.IIOMetadataFormatImpl; import javax.xml.transform.OutputKeys; import javax.xml.transform.Result; import javax.xml.transform.Source; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import org.w3c.dom.Node; /** * Helper class for debugging stuff in Image I/O. * * @version $Id: ImageIODebugUtil.java 1732018 2016-02-24 04:51:06Z gadams $ */ public final class ImageIODebugUtil { private ImageIODebugUtil() { } public static void dumpMetadata(IIOMetadata meta, boolean nativeFormat) { String format; if (nativeFormat) { format = meta.getNativeMetadataFormatName(); } else { format = IIOMetadataFormatImpl.standardMetadataFormatName; } Node node = meta.getAsTree(format); dumpNode(node); } public static void dumpNode(Node node) { try { TransformerFactory tf = TransformerFactory.newInstance(); Transformer t = tf.newTransformer(); t.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); Source src = new DOMSource(node); Result res = new StreamResult(System.out); t.transform(src, res); } catch (TransformerConfigurationException e) { e.printStackTrace(); } catch (TransformerException e) { e.printStackTrace(); } } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/util/MimeConstants.java0100644 0000000 0000000 00000006236 13777276623 027526 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: MimeConstants.java 1694449 2015-08-06 10:59:25Z ssteiner $ */ package org.apache.xmlgraphics.util; /** * Frequently used MIME types for various file formats used by the XML Graphics project. */ public interface MimeConstants { /** Portable Document Format */ String MIME_PDF = "application/pdf"; /** PostScript */ String MIME_POSTSCRIPT = "application/postscript"; /** Encapsulated PostScript (same MIME type as PostScript) */ String MIME_EPS = MIME_POSTSCRIPT; /** HP's PCL */ String MIME_PCL = "application/x-pcl"; /** HP's PCL (alternative MIME type) */ String MIME_PCL_ALT = "application/vnd.hp-PCL"; /** IBM's AFP */ String MIME_AFP = "application/x-afp"; /** IBM's AFP (alternative MIME type) */ String MIME_AFP_ALT = "application/vnd.ibm.modcap"; /** IBM's AFP IOCA subset for bilevel raster image */ String MIME_AFP_IOCA_FS10 = "image/x-afp+fs10"; /** IBM's AFP IOCA subset for grayscale and color raster image */ String MIME_AFP_IOCA_FS11 = "image/x-afp+fs11"; /** IBM's AFP IOCA subset for grayscale and color tiled raster image */ String MIME_AFP_IOCA_FS45 = "image/x-afp+fs45"; /** IBM's AFP GOCA subset for graphical objects */ String MIME_AFP_GOCA = "image/x-afp+goca"; String MIME_AFP_TRUETYPE = "image/x-afp+truetype"; /** Plain text */ String MIME_PLAIN_TEXT = "text/plain"; /** Rich text format */ String MIME_RTF = "application/rtf"; /** Rich text format (alternative 1) */ String MIME_RTF_ALT1 = "text/richtext"; /** Rich text format (alternative 2) */ String MIME_RTF_ALT2 = "text/rtf"; /** FrameMaker's MIF */ String MIME_MIF = "application/mif"; /** Structured Vector Graphics */ String MIME_SVG = "image/svg+xml"; /** GIF images */ String MIME_GIF = "image/gif"; /** PNG images */ String MIME_PNG = "image/png"; /** JPEG images */ String MIME_JPEG = "image/jpeg"; /** TIFF images */ String MIME_TIFF = "image/tiff"; /** Proposed but non-registered MIME type for XSL-FO */ String MIME_XSL_FO = "text/xsl"; /** Microsoft's Enhanced Metafile */ String MIME_EMF = "image/x-emf"; } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/util/QName.java0100644 0000000 0000000 00000010522 13777276623 025734 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: QName.java 750418 2009-03-05 11:03:54Z vhennebert $ */ package org.apache.xmlgraphics.util; import java.io.Serializable; /** * Represents a qualified name of an XML element or an XML attribute. *

    * Note: This class allows to carry a namespace prefix but it is not used in the equals() and * hashCode() methods. */ public class QName implements Serializable { private static final long serialVersionUID = -5225376740044770690L; private String namespaceURI; private String localName; private String prefix; private int hashCode; /** * Main constructor. * @param namespaceURI the namespace URI * @param prefix the namespace prefix, may be null * @param localName the local name */ public QName(String namespaceURI, String prefix, String localName) { if (localName == null) { throw new NullPointerException("Parameter localName must not be null"); } if (localName.length() == 0) { throw new IllegalArgumentException("Parameter localName must not be empty"); } this.namespaceURI = namespaceURI; this.prefix = prefix; this.localName = localName; this.hashCode = toHashString().hashCode(); } /** * Main constructor. * @param namespaceURI the namespace URI * @param qName the qualified name */ public QName(String namespaceURI, String qName) { if (qName == null) { throw new NullPointerException("Parameter localName must not be null"); } if (qName.length() == 0) { throw new IllegalArgumentException("Parameter localName must not be empty"); } this.namespaceURI = namespaceURI; int p = qName.indexOf(':'); if (p > 0) { this.prefix = qName.substring(0, p); this.localName = qName.substring(p + 1); } else { this.prefix = null; this.localName = qName; } this.hashCode = toHashString().hashCode(); } /** @return the namespace URI */ public String getNamespaceURI() { return this.namespaceURI; } /** @return the namespace prefix */ public String getPrefix() { return this.prefix; } /** @return the local name */ public String getLocalName() { return this.localName; } /** @return the fully qualified name */ public String getQName() { return getPrefix() != null ? getPrefix() + ':' + getLocalName() : getLocalName(); } /** @see java.lang.Object#hashCode() */ public int hashCode() { return this.hashCode; } /** @see java.lang.Object#equals(java.lang.Object) */ public boolean equals(Object obj) { if (obj == null) { return false; } else if (obj == this) { return true; } else { if (obj instanceof QName) { QName other = (QName)obj; if ((getNamespaceURI() == null && other.getNamespaceURI() == null) || getNamespaceURI().equals(other.getNamespaceURI())) { return getLocalName().equals(other.getLocalName()); } } } return false; } /** @see java.lang.Object#toString() */ public String toString() { return prefix != null ? (prefix + ":" + localName) : toHashString(); } private String toHashString() { return (namespaceURI != null ? ("{" + namespaceURI + "}" + localName) : localName); } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/util/Service.java0100644 0000000 0000000 00000017036 13777276623 026342 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: Service.java 1780540 2017-01-27 11:10:50Z ssteiner $ */ package org.apache.xmlgraphics.util; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import java.net.URL; import java.util.Enumeration; import java.util.Iterator; import java.util.List; import java.util.Map; import org.apache.commons.io.IOUtils; /** * This class handles looking up service providers on the class path. * It implements the system described in: * * JAR * File Specification Under Service Provider. Note that this * interface is very similar to the one they describe which seems to * be missing in the JDK. * * @version $Id: Service.java 1780540 2017-01-27 11:10:50Z ssteiner $ * * Originally authored by Thomas DeWeese. */ public final class Service { private Service() { } // Remember providers we have looked up before. static Map> classMap = new java.util.HashMap>(); static Map> instanceMap = new java.util.HashMap>(); /** * Returns an iterator where each element should implement the * interface (or subclass the baseclass) described by cls. The * Classes are found by searching the classpath for service files * named: 'META-INF/services/<fully qualified classname> that list * fully qualifted classnames of classes that implement the * service files classes interface. These classes must have * default constructors. * * @param cls The class/interface to search for providers of. */ public static synchronized Iterator providers(Class cls) { String serviceFile = getServiceFilename(cls); List l = instanceMap.get(serviceFile); if (l != null) { return l.iterator(); } l = new java.util.ArrayList(); instanceMap.put(serviceFile, l); ClassLoader cl = getClassLoader(cls); if (cl != null) { List names = getProviderNames(cls, cl); for (String name : names) { try { // Try and load the class Object obj = cl.loadClass(name).getDeclaredConstructor().newInstance(); // stick it into our vector... l.add(obj); } catch (Exception ex) { // Just try the next name } } } return l.iterator(); } /** * Returns an iterator where each element should be the name * of a class that implements the * interface (or subclass the baseclass) described by cls. The * Classes are found by searching the classpath for service files * named: 'META-INF/services/<fully qualified classname> that list * fully qualified classnames of classes that implement the * service files classes interface. * * @param cls The class/interface to search for providers of. */ public static synchronized Iterator providerNames(Class cls) { String serviceFile = getServiceFilename(cls); List l = classMap.get(serviceFile); if (l != null) { return l.iterator(); } l = new java.util.ArrayList(); classMap.put(serviceFile, l); l.addAll(getProviderNames(cls)); return l.iterator(); } /** * Returns an iterator where each element should implement the * interface (or subclass the baseclass) described by cls. The * Classes are found by searching the classpath for service files * named: 'META-INF/services/<fully qualified classname> that list * fully qualified classnames of classes that implement the * service files classes interface. These classes must have * default constructors if returnInstances is true. * * This is a deprecated, type-unsafe legacy method. * * @param cls The class/interface to search for providers of. * @param returnInstances true if the iterator should return instances rather than class names. * @deprecated use the type-safe methods providers(Class) or providerNames(Class) instead. */ public static Iterator providers(Class cls, boolean returnInstances) { return (returnInstances ? providers(cls) : providerNames(cls)); } private static List getProviderNames(Class cls) { return getProviderNames(cls, getClassLoader(cls)); } private static List getProviderNames(Class cls, ClassLoader cl) { List l = new java.util.ArrayList(); // No class loader so we can't find 'serviceFile'. if (cl == null) { return l; } Enumeration e; try { e = cl.getResources(getServiceFilename(cls)); } catch (IOException ioe) { return l; } while (e.hasMoreElements()) { try { URL u = e.nextElement(); InputStream is = u.openStream(); Reader r = new InputStreamReader(is, "UTF-8"); BufferedReader br = new BufferedReader(r); try { for (String line = br.readLine(); line != null; line = br.readLine()) { // First strip any comment... int idx = line.indexOf('#'); if (idx != -1) { line = line.substring(0, idx); } // Trim whitespace. line = line.trim(); if (line.length() != 0) { l.add(line); } } } finally { IOUtils.closeQuietly(br); IOUtils.closeQuietly(is); } } catch (Exception ex) { // Just try the next file... } } return l; } private static ClassLoader getClassLoader(Class cls) { ClassLoader cl = null; try { cl = cls.getClassLoader(); } catch (SecurityException se) { // Ooops! can't get his class loader. } // Can always request your own class loader. But it might be 'null'. if (cl == null) { cl = Service.class.getClassLoader(); } if (cl == null) { cl = ClassLoader.getSystemClassLoader(); } return cl; } private static String getServiceFilename(Class cls) { return "META-INF/services/" + cls.getName(); } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/util/UnitConv.java0100644 0000000 0000000 00000015627 13777276623 026513 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: UnitConv.java 1681108 2015-05-22 13:26:12Z ssteiner $ */ package org.apache.xmlgraphics.util; import java.awt.geom.AffineTransform; import java.util.Locale; /** * Utility class for unit conversions. */ public final class UnitConv { private UnitConv() { } /** conversion factory from millimeters to inches. */ public static final float IN2MM = 25.4f; /** conversion factory from centimeters to inches. */ public static final float IN2CM = 2.54f; /** conversion factory from inches to points. */ public static final int IN2PT = 72; /** Describes the unit pica. */ public static final String PICA = "pc"; /** Describes the unit point. */ public static final String POINT = "pt"; /** Describes the unit millimeter. */ public static final String MM = "mm"; /** Describes the unit centimeter. */ public static final String CM = "cm"; /** Describes the unit inch. */ public static final String INCH = "in"; /** Describes the unit millipoint. */ public static final String MPT = "mpt"; /** Describes the unit pixel. */ public static final String PX = "px"; /** * Converts millimeters (mm) to points (pt) * @param mm the value in mm * @return the value in pt */ public static double mm2pt(double mm) { return mm * IN2PT / IN2MM; } /** * Converts millimeters (mm) to millipoints (mpt) * @param mm the value in mm * @return the value in mpt */ public static double mm2mpt(double mm) { return mm * 1000 * IN2PT / IN2MM; } /** * Converts points (pt) to millimeters (mm) * @param pt the value in pt * @return the value in mm */ public static double pt2mm(double pt) { return pt * IN2MM / IN2PT; } /** * Converts millimeters (mm) to inches (in) * @param mm the value in mm * @return the value in inches */ public static double mm2in(double mm) { return mm / IN2MM; } /** * Converts inches (in) to millimeters (mm) * @param in the value in inches * @return the value in mm */ public static double in2mm(double in) { return in * IN2MM; } /** * Converts inches (in) to millipoints (mpt) * @param in the value in inches * @return the value in mpt */ public static double in2mpt(double in) { return in * IN2PT * 1000; } /** * Converts inches (in) to points (pt) * @param in the value in inches * @return the value in pt */ public static double in2pt(double in) { return in * IN2PT; } /** * Converts millipoints (mpt) to inches (in) * @param mpt the value in mpt * @return the value in inches */ public static double mpt2in(double mpt) { return mpt / IN2PT / 1000; } /** * Converts millimeters (mm) to pixels (px) * @param mm the value in mm * @param resolution the resolution in dpi (dots per inch) * @return the value in pixels */ public static double mm2px(double mm, int resolution) { return mm2in(mm) * resolution; } /** * Converts millipoints (mpt) to pixels (px) * @param mpt the value in mpt * @param resolution the resolution in dpi (dots per inch) * @return the value in pixels */ public static double mpt2px(double mpt, int resolution) { return mpt2in(mpt) * resolution; } /** * Converts a millipoint-based transformation matrix to points. * @param at a millipoint-based transformation matrix * @return a point-based transformation matrix */ public static AffineTransform mptToPt(AffineTransform at) { double[] matrix = new double[6]; at.getMatrix(matrix); //Convert to points matrix[4] = matrix[4] / 1000; matrix[5] = matrix[5] / 1000; return new AffineTransform(matrix); } /** * Converts a point-based transformation matrix to millipoints. * @param at a point-based transformation matrix * @return a millipoint-based transformation matrix */ public static AffineTransform ptToMpt(AffineTransform at) { double[] matrix = new double[6]; at.getMatrix(matrix); //Convert to millipoints matrix[4] = matrix[4] * 1000; matrix[5] = matrix[5] * 1000; return new AffineTransform(matrix); } /** * Convert the given unit length to a dimensionless integer representing * a whole number of base units (milli-points). * * @param value input unit value * @return int millipoints */ public static int convert(String value) { double retValue = 0; if (value != null) { if (value.toLowerCase(Locale.getDefault()).indexOf(PX) >= 0) { retValue = Double.parseDouble(value.substring(0, value.length() - 2)); retValue *= 1000; } else if (value.toLowerCase(Locale.getDefault()).indexOf(INCH) >= 0) { retValue = Double.parseDouble(value.substring(0, value.length() - 2)); retValue *= 72000; } else if (value.toLowerCase(Locale.getDefault()).indexOf(CM) >= 0) { retValue = Double.parseDouble(value.substring(0, value.length() - 2)); retValue *= 28346.4567; } else if (value.toLowerCase(Locale.getDefault()).indexOf(MM) >= 0) { retValue = Double.parseDouble(value.substring(0, value.length() - 2)); retValue *= 2834.64567; } else if (value.toLowerCase(Locale.getDefault()).indexOf(MPT) >= 0) { retValue = Double.parseDouble(value.substring(0, value.length() - 3)); } else if (value.toLowerCase(Locale.getDefault()).indexOf(POINT) >= 0) { retValue = Double.parseDouble(value.substring(0, value.length() - 2)); retValue *= 1000; } else if (value.toLowerCase(Locale.getDefault()).indexOf(PICA) >= 0) { retValue = Double.parseDouble(value.substring(0, value.length() - 2)); retValue *= 12000; } } return (int)retValue; } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/util/WriterOutputStream.java0100644 0000000 0000000 00000004663 13777276623 030615 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: WriterOutputStream.java 1681108 2015-05-22 13:26:12Z ssteiner $ */ package org.apache.xmlgraphics.util; import java.io.IOException; import java.io.OutputStream; import java.io.Writer; /** * An OutputStream wrapper for a Writer. */ public class WriterOutputStream extends OutputStream { private Writer writer; private String encoding; /** * Creates a new WriterOutputStream. * @param writer the Writer to write to */ public WriterOutputStream(Writer writer) { this(writer, null); } /** * Creates a new WriterOutputStream. * @param writer the Writer to write to * @param encoding the encoding to use, or null if the default encoding should be used */ public WriterOutputStream(Writer writer, String encoding) { this.writer = writer; this.encoding = encoding; } /** * {@inheritDoc} */ public void close() throws IOException { writer.close(); } /** * {@inheritDoc} */ public void flush() throws IOException { writer.flush(); } /** * {@inheritDoc} */ public void write(byte[] buf, int offset, int length) throws IOException { if (encoding != null) { writer.write(new String(buf, offset, length, encoding)); } else { writer.write(new String(buf, offset, length, "UTF-8")); } } /** * {@inheritDoc} */ public void write(byte[] buf) throws IOException { write(buf, 0, buf.length); } /** * {@inheritDoc} */ public void write(int b) throws IOException { write(new byte[] {(byte)b}); } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/util/XMLizable.java0100644 0000000 0000000 00000003155 13777276623 026566 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: XMLizable.java 750418 2009-03-05 11:03:54Z vhennebert $ */ package org.apache.xmlgraphics.util; /* * Copied from Apache Excalibur: * https://svn.apache.org/repos/asf/excalibur/trunk/components/xmlutil/ * src/java/org/apache/excalibur/xml/sax/XMLizable.java */ import org.xml.sax.ContentHandler; import org.xml.sax.SAXException; /** * This interface can be implemented by classes willing to provide an XML representation * of their current state as SAX events. */ public interface XMLizable { /** * Generates SAX events representing the object's state. * @param handler ContentHandler instance to send the SAX events to * @throws SAXException if there's a problem generating the SAX events */ void toSAX(ContentHandler handler) throws SAXException; } ././@LongLink0100644 0000000 0000000 00000000145 13777276623 011657 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/util/dijkstra/DefaultEdgeDirectory.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/util/dijkstra/DefaultEdgeDirectory.java0100644 0000000 0000000 00000007025 13777276623 032610 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: DefaultEdgeDirectory.java 750418 2009-03-05 11:03:54Z vhennebert $ */ package org.apache.xmlgraphics.util.dijkstra; import java.util.Collections; import java.util.Iterator; import java.util.Map; /** * Default implementation of an edge directory for the {@link DijkstraAlgorithm}. */ public class DefaultEdgeDirectory implements EdgeDirectory { /** The directory of edges */ private Map edges = new java.util.HashMap(); //Map> /** * Adds a new edge between two vertices. * @param edge the new edge */ public void addEdge(Edge edge) { Map directEdges = (Map)edges.get(edge.getStart()); if (directEdges == null) { directEdges = new java.util.HashMap(); edges.put(edge.getStart(), directEdges); } directEdges.put(edge.getEnd(), edge); } /** {@inheritDoc} */ public int getPenalty(Vertex start, Vertex end) { Map edgeMap = (Map)edges.get(start); if (edgeMap != null) { Edge route = (Edge)edgeMap.get(end); if (route != null) { int penalty = route.getPenalty(); if (penalty < 0) { throw new IllegalStateException("Penalty must not be negative"); } return penalty; } } return 0; } /** {@inheritDoc} */ public Iterator getDestinations(Vertex origin) { Map directRoutes = (Map)edges.get(origin); if (directRoutes != null) { Iterator iter = directRoutes.keySet().iterator(); return iter; } return Collections.EMPTY_LIST.iterator(); } /** * Returns an iterator over all edges with the given origin. * @param origin the origin * @return an iterator over Edge instances */ public Iterator getEdges(Vertex origin) { Map directRoutes = (Map)edges.get(origin); if (directRoutes != null) { Iterator iter = directRoutes.values().iterator(); return iter; } return Collections.EMPTY_LIST.iterator(); } /** * Returns the best edge (the edge with the lowest penalty) between two given vertices. * @param start the start vertex * @param end the end vertex * @return the best vertex or null if none is found */ public Edge getBestEdge(Vertex start, Vertex end) { Edge best = null; Iterator iter = getEdges(start); while (iter.hasNext()) { Edge edge = (Edge)iter.next(); if (edge.getEnd().equals(end)) { if (best == null || edge.getPenalty() < best.getPenalty()) { best = edge; } } } return best; } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/util/dijkstra/DijkstraAlgorithm.java0100644 0000000 0000000 00000016316 13777276623 032177 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: DijkstraAlgorithm.java 1681108 2015-05-22 13:26:12Z ssteiner $ */ package org.apache.xmlgraphics.util.dijkstra; import java.util.Comparator; import java.util.Iterator; import java.util.Map; import java.util.Set; import java.util.TreeSet; /** * This is an implementation of Dijkstra's algorithm to find the shortest path for a directed * graph with non-negative edge weights. * @see WikiPedia on Dijkstra's * Algorithm */ public class DijkstraAlgorithm { /** Infinity value for distances. */ public static final int INFINITE = Integer.MAX_VALUE; /** Compares penalties between two possible destinations. */ private final Comparator penaltyComparator = new Comparator() { public int compare(Object left, Object right) { int leftPenalty = getLowestPenalty((Vertex)left); int rightPenalty = getLowestPenalty((Vertex)right); if (leftPenalty < rightPenalty) { return -1; } else if (leftPenalty == rightPenalty) { return ((Comparable)left).compareTo(right); } else { return 1; } } }; /** The directory of edges */ private EdgeDirectory edgeDirectory; /** The priority queue for all vertices under inspection, ordered by penalties/distances. */ private TreeSet priorityQueue = new TreeSet(penaltyComparator); //Set /** The set of vertices for which the lowest penalty has been found. */ private Set finishedVertices = new java.util.HashSet(); //Set /** The currently known lowest penalties for all vertices. */ private Map lowestPenalties = new java.util.HashMap(); //Map /** Map of all predecessors in the spanning tree of best routes. */ private Map predecessors = new java.util.HashMap(); //Map /** * Main Constructor. * @param edgeDirectory the edge directory this instance should work on */ public DijkstraAlgorithm(EdgeDirectory edgeDirectory) { this.edgeDirectory = edgeDirectory; } /** * Returns the penalty between two vertices. * @param start the start vertex * @param end the end vertex * @return the penalty between two vertices, or 0 if no single edge between the two vertices * exists. */ protected int getPenalty(Vertex start, Vertex end) { return this.edgeDirectory.getPenalty(start, end); } /** * Returns an iterator over all valid destinations for a given vertex. * @param origin the origin from which to search for destinations * @return the iterator over all valid destinations for a given vertex */ protected Iterator getDestinations(Vertex origin) { return this.edgeDirectory.getDestinations(origin); } private void reset() { finishedVertices.clear(); priorityQueue.clear(); lowestPenalties.clear(); predecessors.clear(); } /** * Run Dijkstra's shortest path algorithm. After this method is finished you can use * {@link #getPredecessor(Vertex)} to reconstruct the best/shortest path starting from the * destination backwards. * @param start the starting vertex * @param destination the destination vertex. */ public void execute(Vertex start, Vertex destination) { if (start == null || destination == null) { throw new NullPointerException("start and destination may not be null"); } reset(); setShortestDistance(start, 0); priorityQueue.add(start); // the current node Vertex u; // extract the vertex with the shortest distance while (priorityQueue.size() > 0) { u = (Vertex)priorityQueue.first(); priorityQueue.remove(u); if (destination.equals(u)) { //Destination reached break; } finishedVertices.add(u); relax(u); } } /** * Compute new lowest penalties for neighboring vertices. Update the lowest penalties and the * predecessor map if a better solution is found. * @param u the vertex to process */ private void relax(Vertex u) { Iterator iter = getDestinations(u); while (iter.hasNext()) { Vertex v = (Vertex)iter.next(); // skip node already settled if (isFinished(v)) { continue; } int shortDist = getLowestPenalty(u) + getPenalty(u, v); if (shortDist < getLowestPenalty(v)) { // assign new shortest distance and mark unsettled setShortestDistance(v, shortDist); // assign predecessor in shortest path setPredecessor(v, u); } } } private void setPredecessor(Vertex a, Vertex b) { predecessors.put(a, b); } /** * Indicates whether a shortest route to a vertex has been found. * @param v the vertex * @return true if the shortest route to this vertex has been found. */ private boolean isFinished(Vertex v) { return finishedVertices.contains(v); } private void setShortestDistance(Vertex vertex, int distance) { //Remove so it is inserted at the right position after the lowest penalty changes for this //vertex. priorityQueue.remove(vertex); //Update the lowest penalty. lowestPenalties.put(vertex, distance); //Insert the vertex again at the new position based on the lowest penalty priorityQueue.add(vertex); } /** * Returns the lowest penalty from the start point to a given vertex. * @param vertex the vertex * @return the lowest penalty or {@link DijkstraAlgorithm#INFINITE} if there is no route to * the destination. */ public int getLowestPenalty(Vertex vertex) { Integer d = ((Integer)lowestPenalties.get(vertex)); return (d == null) ? INFINITE : d; } /** * Returns the vertex's predecessor on the shortest path. * @param vertex the vertex for which to find the predecessor * @return the vertex's predecessor on the shortest path, or * null if there is no route to the destination. */ public Vertex getPredecessor(Vertex vertex) { return (Vertex)predecessors.get(vertex); } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/util/dijkstra/Edge.java0100644 0000000 0000000 00000003012 13777276623 027406 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: Edge.java 750418 2009-03-05 11:03:54Z vhennebert $ */ package org.apache.xmlgraphics.util.dijkstra; /** * Represents an edge (or direct route between two points) for the {@link DijkstraAlgorithm}. * Implement this class to hold the start and end vertex for an edge and implement the * getPenalty() method. */ public interface Edge { /** * Returns the start vertex of the edge. * @return the start vertex */ Vertex getStart(); /** * Returns the end vertex of the edge. * @return the end vertex */ Vertex getEnd(); /** * Returns the penalty (or distance) for this edge. * @return the penalty value (must be non-negative) */ int getPenalty(); } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/util/dijkstra/EdgeDirectory.java0100644 0000000 0000000 00000003176 13777276623 031306 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: EdgeDirectory.java 1345683 2012-06-03 14:50:33Z gadams $ */ package org.apache.xmlgraphics.util.dijkstra; import java.util.Iterator; /** * Represents a directory of edges for use by the {@link DijkstraAlgorithm}. */ public interface EdgeDirectory { /** * Returns the penalty between two vertices. * @param start the start vertex * @param end the end vertex * @return the penalty between two vertices, or 0 if no single edge between the two vertices * exists. */ int getPenalty(Vertex start, Vertex end); /** * Returns an iterator over all valid destinations for a given vertex. * @param origin the origin from which to search for destinations * @return the iterator over all valid destinations for a given vertex */ Iterator getDestinations(Vertex origin); } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/util/dijkstra/Vertex.java0100644 0000000 0000000 00000002672 13777276623 030032 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: Vertex.java 750418 2009-03-05 11:03:54Z vhennebert $ */ package org.apache.xmlgraphics.util.dijkstra; /** * Represents a vertex to be used by {@link DijkstraAlgorithm}. If you want to represent a city, * you can do "public class City implements Vertex". The purpose of this interface is to make * sure the Vertex implementation implements the Comparable interface so the sorting order is * well-defined even when two vertices have the same penalty/distance from an origin point. * Therefore, make sure you implement the compareTo(Object) and * equals(Object) methods. */ public interface Vertex extends Comparable { } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/util/dijkstra/package.html0100644 0000000 0000000 00000002054 13777276623 030165 0ustar000000000 0000000 org.apache.xmlgraphics.util.dijkstra Package

    Contains an implementation of Dijkstra's shortest path algorithm. The package is primarily used by the image loader package (org.apache.xmlgraphics.image.loader).

    xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/util/i18n/ExtendedLocalizable.java0100644 0000000 0000000 00000003733 13777276623 031422 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ExtendedLocalizable.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.util.i18n; import java.util.Locale; import java.util.ResourceBundle; /** * This interface provides much more control over internationalization * than the Localizable interface. * * @version $Id: ExtendedLocalizable.java 1732018 2016-02-24 04:51:06Z gadams $ * * Originally authored by Stephane Hillion. */ public interface ExtendedLocalizable extends Localizable { /** * Sets the group to which this object belongs. */ void setLocaleGroup(LocaleGroup lg); /** * Returns the group to which this object belongs. */ LocaleGroup getLocaleGroup(); /** * Sets the default locale for all the instances of this class in * the same LocaleGroup. */ void setDefaultLocale(Locale l); /** * Gets the current default locale in the LocaleGroup. */ Locale getDefaultLocale(); /** * Returns the current resource bundle. Getting this object gives access * to the keys in the bundle, raw string resources, arrays of raw string * resources and object resources. */ ResourceBundle getResourceBundle(); } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/util/i18n/LocaleGroup.java0100644 0000000 0000000 00000003245 13777276623 027732 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: LocaleGroup.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.util.i18n; import java.util.Locale; /** * This class represents a group of ExtendedLocalizable objects which * have a shared default locale. * * @version $Id: LocaleGroup.java 1732018 2016-02-24 04:51:06Z gadams $ * * Originally authored by Stephane Hillion. */ public class LocaleGroup { /** * The default group. */ public static final LocaleGroup DEFAULT = new LocaleGroup(); /** * The shared Locale. */ protected Locale locale; /** * Sets the default locale for all the instances of ExtendedLocalizable * in this group. */ public void setLocale(Locale l) { locale = l; } /** * Gets the current default locale in this group, or null. */ public Locale getLocale() { return locale; } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/util/i18n/Localizable.java0100644 0000000 0000000 00000004331 13777276623 027734 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: Localizable.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.util.i18n; import java.util.Locale; import java.util.MissingResourceException; /** * This interface must be implemented by the classes which must provide a * way to override the default locale. * * @version $Id: Localizable.java 1732018 2016-02-24 04:51:06Z gadams $ * * Originally authored by Stephane Hillion. */ public interface Localizable { /** * Provides a way to the user to specify a locale which override the * default one. If null is passed to this method, the used locale * becomes the global one. * @param l The locale to set. */ void setLocale(Locale l); /** * Returns the current locale or null if the locale currently used is * the default one. */ Locale getLocale(); /** * Creates and returns a localized message, given the key of the message * in the resource bundle and the message parameters. * The messages in the resource bundle must have the syntax described in * the java.text.MessageFormat class documentation. * @param key The key used to retreive the message from the resource * bundle. * @param args The objects that compose the message. * @exception MissingResourceException if the key is not in the bundle. */ String formatMessage(String key, Object[] args) throws MissingResourceException; } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/util/i18n/LocalizableSupport.java0100644 0000000 0000000 00000020176 13777276623 031336 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: LocalizableSupport.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.util.i18n; import java.text.MessageFormat; import java.util.Locale; import java.util.ResourceBundle; // CSOFF: InnerAssignment /** * This class provides a default implementation of the Localizable interface. * You can use it as a base class or as a member field and delegates various * work to it.

    * For example, to implement Localizable, the following code can be used: *

     *  package mypackage;
     *  ...
     *  public class MyClass implements Localizable {
     *      // This code fragment requires a file named
     *      // 'mypackage/resources/Messages.properties', or a
     *      // 'mypackage.resources.Messages' class which extends
     *      // java.util.ResourceBundle, accessible using the current
     *      // classpath.
     *      LocalizableSupport localizableSupport =
     *          new LocalizableSupport("mypackage.resources.Messages");
     *
     *      public void setLocale(Locale l) {
     *          localizableSupport.setLocale(l);
     *      }
     *      public Local getLocale() {
     *          return localizableSupport.getLocale();
     *      }
     *      public String formatMessage(String key, Object[] args) {
     *          return localizableSupport.formatMessage(key, args);
     *      }
     *  }
     * 
    * The algorithm for the Locale lookup in a LocalizableSupport object is: *
      *
    • * if a Locale has been set by a call to setLocale(), use this Locale, * else, *
    • *
    • * if a Locale has been set by a call to the setDefaultLocale() method * of a LocalizableSupport object in the current LocaleGroup, use this * Locale, else, *
    • *
    • * use the object returned by Locale.getDefault() (and set by * Locale.setDefault()). *
    • *
    * This offers the possibility to have a different Locale for each object, * a Locale for a group of object and/or a Locale for the JVM instance. *

    * Note: if no group is specified a LocalizableSupport object belongs to a * default group common to each instance of LocalizableSupport. * * @version $Id: LocalizableSupport.java 1732018 2016-02-24 04:51:06Z gadams $ * * Originally authored by Stephane Hillion. */ public class LocalizableSupport implements Localizable { /** * The locale group to which this object belongs. */ protected LocaleGroup localeGroup = LocaleGroup.DEFAULT; /** * The resource bundle classname. */ protected String bundleName; /** * The classloader to use to create the resource bundle. */ protected ClassLoader classLoader; /** * The current locale. */ protected Locale locale; /** * The locale in use. */ protected Locale usedLocale; /** * The resources */ protected ResourceBundle resourceBundle; /** * Same as LocalizableSupport(s, null). */ public LocalizableSupport(String s) { this(s, null); } /** * Creates a new Localizable object. * The resource bundle class name is required allows the use of custom * classes of resource bundles. * @param s must be the name of the class to use to get the appropriate * resource bundle given the current locale. * @param cl is the classloader used to create the resource bundle, * or null. * @see java.util.ResourceBundle */ public LocalizableSupport(String s, ClassLoader cl) { bundleName = s; classLoader = cl; } /** * Implements {@link org.apache.xmlgraphics.util.i18n.Localizable#setLocale(Locale)}. */ public void setLocale(Locale l) { if (locale != l) { locale = l; resourceBundle = null; } } /** * Implements {@link org.apache.xmlgraphics.util.i18n.Localizable#getLocale()}. */ public Locale getLocale() { return locale; } /** * Implements {@link * org.apache.xmlgraphics.util.i18n.ExtendedLocalizable#setLocaleGroup(LocaleGroup)}. */ public void setLocaleGroup(LocaleGroup lg) { localeGroup = lg; } /** * Implements {@link * org.apache.xmlgraphics.util.i18n.ExtendedLocalizable#getLocaleGroup()}. */ public LocaleGroup getLocaleGroup() { return localeGroup; } /** * Implements {@link * org.apache.xmlgraphics.util.i18n.ExtendedLocalizable#setDefaultLocale(Locale)}. * Later invocations of the instance methods will lead to update the * resource bundle used. */ public void setDefaultLocale(Locale l) { localeGroup.setLocale(l); } /** * Implements {@link * org.apache.xmlgraphics.util.i18n.ExtendedLocalizable#getDefaultLocale()}. */ public Locale getDefaultLocale() { return localeGroup.getLocale(); } /** * Implements {@link * org.apache.xmlgraphics.util.i18n.Localizable#formatMessage(String,Object[])}. */ public String formatMessage(String key, Object[] args) { getResourceBundle(); return MessageFormat.format(resourceBundle.getString(key), args); } /** * Implements {@link * org.apache.xmlgraphics.util.i18n.ExtendedLocalizable#getResourceBundle()}. */ public ResourceBundle getResourceBundle() { Locale l; if (resourceBundle == null) { if (locale == null) { if ((l = localeGroup.getLocale()) == null) { usedLocale = Locale.getDefault(); } else { usedLocale = l; } } else { usedLocale = locale; } if (classLoader == null) { resourceBundle = ResourceBundle.getBundle(bundleName, usedLocale); } else { resourceBundle = ResourceBundle.getBundle(bundleName, usedLocale, classLoader); } } else if (locale == null) { // Check for group Locale and JVM default locale changes. if ((l = localeGroup.getLocale()) == null) { if (usedLocale != (l = Locale.getDefault())) { usedLocale = l; if (classLoader == null) { resourceBundle = ResourceBundle.getBundle(bundleName, usedLocale); } else { resourceBundle = ResourceBundle.getBundle(bundleName, usedLocale, classLoader); } } } else if (usedLocale != l) { usedLocale = l; if (classLoader == null) { resourceBundle = ResourceBundle.getBundle(bundleName, usedLocale); } else { resourceBundle = ResourceBundle.getBundle(bundleName, usedLocale, classLoader); } } } return resourceBundle; } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/util/i18n/package.html0100644 0000000 0000000 00000000736 13777276623 027136 0ustar000000000 0000000 Provides utility classes for internationalization.

    The responsibility of the i18n package is to provide a facade for the various internationalization utility classes of the standard Java API. The API should be used for compositing string messages in a language-neutral way.

    xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/util/io/ASCII85Constants.java0100644 0000000 0000000 00000004132 13777276623 030244 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ASCII85Constants.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.util.io; /** * This interface defines constants used by the ASCII85 filters. * * @version $Id: ASCII85Constants.java 1732018 2016-02-24 04:51:06Z gadams $ */ public interface ASCII85Constants { /** Special character "z" stands for four NULL bytes (short-cut for !!!!!) */ int ZERO = 0x7A; //"z" /** ZERO as a byte array */ byte[] ZERO_ARRAY = {(byte)ZERO}; /** The start index for ASCII85 characters (!) */ int START = 0x21; //"!" /** The end index for ASCII85 characters (u) */ int END = 0x75; //"u" /** The EOL indicator (LF) */ int EOL = 0x0A; //"\n" /** The EOD (end of data) indicator */ byte[] EOD = {0x7E, 0x3E}; //"~>" /** Array of powers of 85 (4, 3, 2, 1, 0) */ long[] POW85 = new long[] {85 * 85 * 85 * 85, 85 * 85 * 85, 85 * 85, 85, 1}; /* long BASE85_4 = 85; long BASE85_3 = BASE85_4 * BASE85_4; long BASE85_2 = BASE85_3 * BASE85_4; long BASE85_1 = BASE85_2 * BASE85_4; */ } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/util/io/ASCII85InputStream.java0100644 0000000 0000000 00000012117 13777276623 030545 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ASCII85InputStream.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.util.io; import java.io.IOException; import java.io.InputStream; /** * This class applies a ASCII85 decoding to the stream. *

    * The class is derived from InputStream instead of FilteredInputStream because * we can use the read(byte[], int, int) method from InputStream which simply * delegates to read(). This makes the implementation easier. *

    * The filter is described in chapter 3.13.3 of the PostScript Language * Reference (third edition). * * @version $Id: ASCII85InputStream.java 1732018 2016-02-24 04:51:06Z gadams $ */ public class ASCII85InputStream extends InputStream implements ASCII85Constants { private InputStream in; private boolean eodReached; private int[] b = new int[4]; //decoded private int bSize; private int bIndex; /** @see java.io.FilterInputStream **/ public ASCII85InputStream(InputStream in) { super(); this.in = in; } /** @see java.io.FilterInputStream **/ public int read() throws IOException { //Check if we need to read the next tuple if (bIndex >= bSize) { if (eodReached) { return -1; } readNextTuple(); if (bSize == 0) { if (!eodReached) { throw new IllegalStateException("Internal error"); } return -1; } } int result = b[bIndex]; result = (result < 0 ? 256 + result : result); bIndex++; return result; } private int filteredRead() throws IOException { int buf; while (true) { buf = in.read(); switch (buf) { case 0: //null case 9: //tab case 10: //LF case 12: //FF case 13: //CR case 32: //space continue; //ignore case ZERO: case 126: //= EOD[0] = '~' return buf; default: if ((buf >= START) && (buf <= END)) { return buf; } else { throw new IOException("Illegal character detected: " + buf); } } } } private void handleEOD() throws IOException { final int buf = in.read(); if (buf != EOD[1]) { throw new IOException("'>' expected after '~' (EOD)"); } eodReached = true; bSize = 0; bIndex = 0; } private void readNextTuple() throws IOException { int buf; long tuple = 0; //Read ahead and check for special "z" buf = filteredRead(); if (buf == ZERO) { java.util.Arrays.fill(b, 0); bSize = 4; bIndex = 0; } else if (buf == EOD[0]) { handleEOD(); } else { int cIndex = 0; tuple = (buf - START) * POW85[cIndex]; cIndex++; while (cIndex < 5) { buf = filteredRead(); if (buf == EOD[0]) { handleEOD(); break; } else if (buf == ZERO) { //Violation 2 throw new IOException("Illegal 'z' within tuple"); } else { tuple += (buf - START) * POW85[cIndex]; cIndex++; } } int cSize = cIndex; if (cSize == 1) { //Violation 3 throw new IOException("Only one character in tuple"); } //Handle optional, trailing, incomplete tuple while (cIndex < 5) { tuple += POW85[cIndex - 1]; cIndex++; } if (tuple > (2L << 31) - 1) { //Violation 1 throw new IOException("Illegal tuple (> 2^32 - 1)"); } //Convert tuple b[0] = (byte)((tuple >> 24) & 0xFF); b[1] = (byte)((tuple >> 16) & 0xFF); b[2] = (byte)((tuple >> 8) & 0xFF); b[3] = (byte)((tuple) & 0xFF); bSize = cSize - 1; bIndex = 0; } } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/util/io/ASCII85OutputStream.java0100644 0000000 0000000 00000015533 13777276623 030753 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ASCII85OutputStream.java 1804124 2017-08-04 14:13:54Z ssteiner $ */ package org.apache.xmlgraphics.util.io; import java.io.FilterOutputStream; import java.io.IOException; import java.io.OutputStream; /** * This class applies a ASCII85 encoding to the stream. * * @version $Id: ASCII85OutputStream.java 1804124 2017-08-04 14:13:54Z ssteiner $ */ public class ASCII85OutputStream extends FilterOutputStream implements ASCII85Constants, Finalizable { private static final boolean DEBUG = false; private int pos; private long buffer; private int posinline; private int bw; /** @see java.io.FilterOutputStream **/ public ASCII85OutputStream(OutputStream out) { super(out); } /** @see java.io.FilterOutputStream **/ public void write(int b) throws IOException { if (pos == 0) { buffer += (b << 24) & 0xff000000L; } else if (pos == 1) { buffer += (b << 16) & 0xff0000L; } else if (pos == 2) { buffer += (b << 8) & 0xff00L; } else { buffer += b & 0xffL; } pos++; if (pos > 3) { checkedWrite(convertWord(buffer)); buffer = 0; pos = 0; } } /* UNUSED ATM private void checkedWrite(int b) throws IOException { if (posinline == 80) { out.write(EOL); bw++; posinline = 0; } checkedWrite(b); posinline++; bw++; }*/ private void checkedWrite(byte[] buf) throws IOException { checkedWrite(buf, buf.length, false); } private void checkedWrite(byte[] buf, boolean nosplit) throws IOException { checkedWrite(buf, buf.length, nosplit); } private void checkedWrite(byte[] buf , int len) throws IOException { checkedWrite(buf, len, false); } private void checkedWrite(byte[] buf , int len, boolean nosplit) throws IOException { if (posinline + len > 80) { int firstpart = (nosplit ? 0 : len - (posinline + len - 80)); if (firstpart > 0) { out.write(buf, 0, firstpart); } out.write(EOL); bw++; int rest = len - firstpart; if (rest > 0) { out.write(buf, firstpart, rest); } posinline = rest; } else { out.write(buf, 0, len); posinline += len; } bw += len; } /** * This converts a 32 bit value (4 bytes) into 5 bytes using base 85. * each byte in the result starts with zero at the '!' character so * the resulting base85 number fits into printable ascii chars * * @param word the 32 bit unsigned (hence the long datatype) word * @return 5 bytes (or a single byte of the 'z' character for word * values of 0) */ private byte[] convertWord(long word) { word = word & 0xffffffff; if (word == 0) { return ZERO_ARRAY; } else { if (word < 0) { word = -word; } byte c1 = (byte)((word / POW85[0]) & 0xFF); byte c2 = (byte)(((word - (c1 * POW85[0])) / POW85[1]) & 0xFF); byte c3 = (byte)(((word - (c1 * POW85[0]) - (c2 * POW85[1])) / POW85[2]) & 0xFF); byte c4 = (byte)(((word - (c1 * POW85[0]) - (c2 * POW85[1]) - (c3 * POW85[2])) / POW85[3]) & 0xFF); byte c5 = (byte)(((word - (c1 * POW85[0]) - (c2 * POW85[1]) - (c3 * POW85[2]) - (c4 * POW85[3]))) & 0xFF); byte[] ret = { (byte)(c1 + START), (byte)(c2 + START), (byte)(c3 + START), (byte)(c4 + START), (byte)(c5 + START) }; if (DEBUG) { for (byte aRet : ret) { if (aRet < 33 || aRet > 117) { System.out.println("Illegal char value " + (int) aRet); } } } return ret; } } /** @see Finalizable **/ public void finalizeStream() throws IOException { // now take care of the trailing few bytes. // with n leftover bytes, we append 0 bytes to make a full group of 4 // then convert like normal (except not applying the special zero rule) // and write out the first n+1 bytes from the result if (pos > 0) { int rest = pos; /* byte[] lastdata = new byte[4]; int i = 0; for (int j = 0; j < 4; j++) { if (j < rest) { lastdata[j] = data[i++]; } else { lastdata[j] = 0; } } long val = ((lastdata[0] << 24) & 0xff000000L) + ((lastdata[1] << 16) & 0xff0000L) + ((lastdata[2] << 8) & 0xff00L) + (lastdata[3] & 0xffL); */ byte[] conv; // special rule for handling zeros at the end if (buffer != 0) { conv = convertWord(buffer); } else { conv = new byte[5]; for (int j = 0; j < 5; j++) { conv[j] = (byte)'!'; } } // assert rest+1 <= 5 checkedWrite(conv, rest + 1); } // finally write the two character end of data marker checkedWrite(EOD, true); flush(); if (out instanceof Finalizable) { ((Finalizable)out).finalizeStream(); } } /** @see java.io.FilterOutputStream **/ public void close() throws IOException { finalizeStream(); super.close(); } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/util/io/ASCIIHexOutputStream.java0100644 0000000 0000000 00000005374 13777276623 031245 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ASCIIHexOutputStream.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.util.io; import java.io.FilterOutputStream; import java.io.IOException; import java.io.OutputStream; /** * This class applies a ASCII Hex encoding to the stream. * * @version $Id: ASCIIHexOutputStream.java 1732018 2016-02-24 04:51:06Z gadams $ */ public class ASCIIHexOutputStream extends FilterOutputStream implements Finalizable { private static final int EOL = 0x0A; //"\n" private static final int EOD = 0x3E; //">" private static final int ZERO = 0x30; //"0" private static final int NINE = 0x39; //"9" private static final int A = 0x41; //"A" private static final int ADIFF = A - NINE - 1; private int posinline; /** @see java.io.FilterOutputStream **/ public ASCIIHexOutputStream(OutputStream out) { super(out); } /** @see java.io.FilterOutputStream **/ public void write(int b) throws IOException { b &= 0xFF; int digit1 = ((b & 0xF0) >> 4) + ZERO; if (digit1 > NINE) { digit1 += ADIFF; } out.write(digit1); int digit2 = (b & 0x0F) + ZERO; if (digit2 > NINE) { digit2 += ADIFF; } out.write(digit2); posinline++; checkLineWrap(); } private void checkLineWrap() throws IOException { //Maximum line length is 80 characters if (posinline >= 40) { out.write(EOL); posinline = 0; } } /** @see Finalizable **/ public void finalizeStream() throws IOException { checkLineWrap(); //Write closing character ">" super.write(EOD); flush(); if (out instanceof Finalizable) { ((Finalizable) out).finalizeStream(); } } /** @see java.io.FilterOutputStream **/ public void close() throws IOException { finalizeStream(); super.close(); } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/util/io/Base64DecodeStream.java0100644 0000000 0000000 00000012621 13777276623 030650 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: Base64DecodeStream.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.util.io; import java.io.IOException; import java.io.InputStream; // CSOFF: ConstantName // CSOFF: MemberName // CSOFF: MultipleVariableDeclarations // CSOFF: NeedBraces // CSOFF: OperatorWrap // CSOFF: WhitespaceAround /** * This class implements a Base64 Character decoder as specified in RFC1113. * Unlike some other encoding schemes there is nothing in this encoding that * tells the decoder where a buffer starts or stops, so to use it you will need * to isolate your encoded data into a single chunk and then feed them * this decoder. The simplest way to do that is to read all of the encoded * data into a string and then use: *

     *      byte    data[];
     *      InputStream is = new ByteArrayInputStream(data);
     *      is = new Base64DecodeStream(is);
     * 
    * * On errors, this class throws a IOException with the following detail * strings: *
     *    "Base64DecodeStream: Bad Padding byte (2)."
     *    "Base64DecodeStream: Bad Padding byte (1)."
     * 
    * * @version $Id: Base64DecodeStream.java 1732018 2016-02-24 04:51:06Z gadams $ * * Originally authored by Thomas DeWeese, Vincent Hardy, and Chuck McManis. */ public class Base64DecodeStream extends InputStream { InputStream src; public Base64DecodeStream(InputStream src) { this.src = src; } private static final byte[] PEM_ARRAY = new byte[256]; static { for (int i = 0; i < PEM_ARRAY.length; i++) { PEM_ARRAY[i] = -1; } int idx = 0; for (char c = 'A'; c <= 'Z'; c++) { PEM_ARRAY[c] = (byte)idx++; } for (char c = 'a'; c <= 'z'; c++) { PEM_ARRAY[c] = (byte)idx++; } for (char c = '0'; c <= '9'; c++) { PEM_ARRAY[c] = (byte)idx++; } PEM_ARRAY['+'] = (byte)idx++; PEM_ARRAY['/'] = (byte)idx++; } public boolean markSupported() { return false; } public void close() throws IOException { eof = true; } public int available() throws IOException { return 3 - outOffset; } byte[] decodeBuffer = new byte[4]; byte[] outBuffer = new byte[3]; int outOffset = 3; boolean eof; public int read() throws IOException { if (outOffset == 3) { if (eof || getNextAtom()) { eof = true; return -1; } } return ((int)outBuffer[outOffset++]) & 0xFF; } public int read(byte []out, int offset, int len) throws IOException { int idx = 0; while (idx < len) { if (outOffset == 3) { if (eof || getNextAtom()) { eof = true; if (idx == 0) { return -1; } else { return idx; } } } out[offset + idx] = outBuffer[outOffset++]; idx++; } return idx; } final boolean getNextAtom() throws IOException { int count; int a; int b; int c; int d; int off = 0; while (off != 4) { count = src.read(decodeBuffer, off, 4 - off); if (count == -1) { return true; } int in = off; int out = off; while (in < off + count) { if ((decodeBuffer[in] != '\n') && (decodeBuffer[in] != '\r') && (decodeBuffer[in] != ' ')) { decodeBuffer[out++] = decodeBuffer[in]; } in++; } off = out; } a = PEM_ARRAY[((int)decodeBuffer[0]) & 0xFF]; b = PEM_ARRAY[((int)decodeBuffer[1]) & 0xFF]; c = PEM_ARRAY[((int)decodeBuffer[2]) & 0xFF]; d = PEM_ARRAY[((int)decodeBuffer[3]) & 0xFF]; outBuffer[0] = (byte)((a << 2) | (b >>> 4)); outBuffer[1] = (byte)((b << 4) | (c >>> 2)); outBuffer[2] = (byte)((c << 6) | d); if (decodeBuffer[3] != '=') { // All three bytes are good. outOffset = 0; } else if (decodeBuffer[2] == '=') { // Only one byte of output. outBuffer[2] = outBuffer[0]; outOffset = 2; eof = true; } else { // Only two bytes of output. outBuffer[2] = outBuffer[1]; outBuffer[1] = outBuffer[0]; outOffset = 1; eof = true; } return false; } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/util/io/Base64EncodeStream.java0100644 0000000 0000000 00000016570 13777276623 030671 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: Base64EncodeStream.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.util.io; import java.io.IOException; import java.io.OutputStream; import java.io.PrintStream; import java.io.UnsupportedEncodingException; // CSOFF: ConstantName // CSOFF: InnerAssignment // CSOFF: MultipleVariableDeclarations // CSOFF: NeedBraces // CSOFF: OneStatementPerLine // CSOFF: WhitespaceAfter // CSOFF: WhitespaceAround /** * This class implements a Base64 Character encoder as specified in RFC1113. * Unlike some other encoding schemes there is nothing in this encoding * that indicates where a buffer starts or ends. * * This means that the encoded text will simply start with the first line * of encoded text and end with the last line of encoded text. * * @version $Id: Base64EncodeStream.java 1732018 2016-02-24 04:51:06Z gadams $ * * Originally authored by Thomas DeWeese, Vincent Hardy, and Chuck McManis. */ public class Base64EncodeStream extends OutputStream { /** This array maps the 6 bit values to their characters */ private static final byte[] PEM_ARRAY = { // 0 1 2 3 4 5 6 7 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', // 0 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', // 1 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', // 2 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', // 3 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', // 4 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', // 5 'w', 'x', 'y', 'z', '0', '1', '2', '3', // 6 '4', '5', '6', '7', '8', '9', '+', '/' // 7 }; byte [] atom = new byte[3]; int atomLen; byte [] encodeBuf = new byte[4]; int lineLen; PrintStream out; boolean closeOutOnClose; public Base64EncodeStream(OutputStream out) { try { this.out = new PrintStream(out, false, "UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } closeOutOnClose = true; } public Base64EncodeStream(OutputStream out, boolean closeOutOnClose) { try { this.out = new PrintStream(out, false, "UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } this.closeOutOnClose = closeOutOnClose; } public void close() throws IOException { if (out != null) { encodeAtom(); out.flush(); if (closeOutOnClose) { out.close(); } out = null; } } /** * This can't really flush out output since that may generate * '=' chars which would indicate the end of the stream. * Instead we flush out. You can only be sure all output is * writen by closing this stream. */ public void flush() throws IOException { out.flush(); } public void write(int b) throws IOException { atom[atomLen++] = (byte)b; if (atomLen == 3) { encodeAtom(); } } public void write(byte []data) throws IOException { encodeFromArray(data, 0, data.length); } public void write(byte [] data, int off, int len) throws IOException { encodeFromArray(data, off, len); } /** * enocodeAtom - Take three bytes of input and encode it as 4 * printable characters. Note that if the length in len is less * than three is encodes either one or two '=' signs to indicate * padding characters. */ void encodeAtom() throws IOException { byte a; byte b; byte c; switch (atomLen) { case 0: return; case 1: a = atom[0]; encodeBuf[0] = PEM_ARRAY[((a >>> 2) & 0x3F)]; encodeBuf[1] = PEM_ARRAY[((a << 4) & 0x30)]; encodeBuf[2] = encodeBuf[3] = '='; break; case 2: a = atom[0]; b = atom[1]; encodeBuf[0] = PEM_ARRAY[((a >>> 2) & 0x3F)]; encodeBuf[1] = PEM_ARRAY[(((a << 4) & 0x30) | ((b >>> 4) & 0x0F))]; encodeBuf[2] = PEM_ARRAY[((b << 2) & 0x3C)]; encodeBuf[3] = '='; break; default: a = atom[0]; b = atom[1]; c = atom[2]; encodeBuf[0] = PEM_ARRAY[((a >>> 2) & 0x3F)]; encodeBuf[1] = PEM_ARRAY[(((a << 4) & 0x30) | ((b >>> 4) & 0x0F))]; encodeBuf[2] = PEM_ARRAY[(((b << 2) & 0x3C) | ((c >>> 6) & 0x03))]; encodeBuf[3] = PEM_ARRAY[c & 0x3F]; } if (lineLen == 64) { out.println(); lineLen = 0; } out.write(encodeBuf); lineLen += 4; atomLen = 0; } /** * enocodeAtom - Take three bytes of input and encode it as 4 * printable characters. Note that if the length in len is less * than three is encodes either one or two '=' signs to indicate * padding characters. */ void encodeFromArray(byte[] data, int offset, int len) throws IOException { byte a; byte b; byte c; if (len == 0) { return; } // System.out.println("atomLen: " + atomLen + // " len: " + len + // " offset: " + offset); if (atomLen != 0) { switch(atomLen) { case 1: atom[1] = data[offset++]; len--; atomLen++; if (len == 0) { return; } atom[2] = data[offset++]; len--; atomLen++; break; case 2: atom[2] = data[offset++]; len--; atomLen++; break; default: } encodeAtom(); } while (len >= 3) { a = data[offset++]; b = data[offset++]; c = data[offset++]; encodeBuf[0] = PEM_ARRAY[((a >>> 2) & 0x3F)]; encodeBuf[1] = PEM_ARRAY[(((a << 4) & 0x30) | ((b >>> 4) & 0x0F))]; encodeBuf[2] = PEM_ARRAY[(((b << 2) & 0x3C) | ((c >>> 6) & 0x03))]; encodeBuf[3] = PEM_ARRAY[c & 0x3F]; out.write(encodeBuf); lineLen += 4; if (lineLen == 64) { out.println(); lineLen = 0; } len -= 3; } switch (len) { case 1: atom[0] = data[offset]; break; case 2: atom[0] = data[offset]; atom[1] = data[offset + 1]; break; default: } atomLen = len; } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/util/io/Finalizable.java0100644 0000000 0000000 00000003152 13777276623 027563 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: Finalizable.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.util.io; /** * This interface is used for special FilteredOutputStream classes that won't * be closed (since this causes the target OutputStream to be closed, too) but * where flush() is not enough, for example because a final marker has to be * written to the target stream. * * @version $Id: Finalizable.java 1732018 2016-02-24 04:51:06Z gadams $ */ public interface Finalizable { /** * This method can be called instead of close() on a subclass of * FilteredOutputStream when a final marker has to be written to the target * stream, but close() cannot be called. * * @exception java.io.IOException In case of an IO problem */ void finalizeStream() throws java.io.IOException; } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/util/io/FlateEncodeOutputStream.java0100644 0000000 0000000 00000003413 13777276623 032111 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: FlateEncodeOutputStream.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.util.io; import java.io.IOException; import java.io.OutputStream; /** * This class applies a FlateEncode filter to the stream. It is basically the * normal DeflaterOutputStream except now also implementing the Finalizable * interface. * * @version $Id: FlateEncodeOutputStream.java 1732018 2016-02-24 04:51:06Z gadams $ */ public class FlateEncodeOutputStream extends java.util.zip.DeflaterOutputStream implements Finalizable { /** @see java.util.zip.DeflaterOutputStream **/ public FlateEncodeOutputStream(OutputStream out) { super(out); } /** @see Finalizable **/ public void finalizeStream() throws IOException { finish(); flush(); // ensure that Deflater resources are released def.end(); if (out instanceof Finalizable) { ((Finalizable)out).finalizeStream(); } } } ././@LongLink0100644 0000000 0000000 00000000146 13777276623 011660 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/util/io/RunLengthEncodeOutputStream.javaxmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/util/io/RunLengthEncodeOutputStream.jav0100644 0000000 0000000 00000013436 13777276623 032631 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: RunLengthEncodeOutputStream.java 1804124 2017-08-04 14:13:54Z ssteiner $ */ package org.apache.xmlgraphics.util.io; import java.io.FilterOutputStream; import java.io.IOException; import java.io.OutputStream; /** * This class applies a RunLengthEncode filter to the stream. * * @version $Id: RunLengthEncodeOutputStream.java 1804124 2017-08-04 14:13:54Z ssteiner $ * * Originally authored by Stephen Wolke. */ public class RunLengthEncodeOutputStream extends FilterOutputStream implements Finalizable { private static final int MAX_SEQUENCE_COUNT = 127; private static final int END_OF_DATA = 128; private static final int BYTE_MAX = 256; private static final int NOT_IDENTIFY_SEQUENCE = 0; private static final int START_SEQUENCE = 1; private static final int IN_SEQUENCE = 2; private static final int NOT_IN_SEQUENCE = 3; private int runCount; private int isSequence = NOT_IDENTIFY_SEQUENCE; private byte[] runBuffer = new byte[MAX_SEQUENCE_COUNT + 1]; /** @see java.io.FilterOutputStream **/ public RunLengthEncodeOutputStream(OutputStream out) { super(out); } /** @see java.io.FilterOutputStream **/ public void write(byte b) throws java.io.IOException { runBuffer[runCount] = b; switch (runCount) { case 0: runCount = 0; isSequence = NOT_IDENTIFY_SEQUENCE; runCount++; break; case 1: if (runBuffer[runCount] != runBuffer[runCount - 1]) { isSequence = NOT_IN_SEQUENCE; } runCount++; break; case 2: if (runBuffer[runCount] != runBuffer[runCount - 1]) { isSequence = NOT_IN_SEQUENCE; } else { if (isSequence == NOT_IN_SEQUENCE) { isSequence = START_SEQUENCE; } else { isSequence = IN_SEQUENCE; } } runCount++; break; case MAX_SEQUENCE_COUNT: if (isSequence == IN_SEQUENCE) { out.write(BYTE_MAX - (MAX_SEQUENCE_COUNT - 1)); out.write(runBuffer[runCount - 1]); runBuffer[0] = runBuffer[runCount]; runCount = 1; } else { out.write(MAX_SEQUENCE_COUNT); out.write(runBuffer, 0, runCount + 1); runCount = 0; } isSequence = NOT_IDENTIFY_SEQUENCE; break; default: switch (isSequence) { case NOT_IN_SEQUENCE: if (runBuffer[runCount] == runBuffer[runCount - 1]) { isSequence = START_SEQUENCE; } runCount++; break; case START_SEQUENCE: if (runBuffer[runCount] == runBuffer[runCount - 1]) { out.write(runCount - 3); out.write(runBuffer, 0, runCount - 2); runBuffer[0] = runBuffer[runCount]; runBuffer[1] = runBuffer[runCount]; runBuffer[2] = runBuffer[runCount]; runCount = 3; isSequence = IN_SEQUENCE; break; } else { isSequence = NOT_IN_SEQUENCE; runCount++; break; } case IN_SEQUENCE: default: if (runBuffer[runCount] != runBuffer[runCount - 1]) { out.write(BYTE_MAX - (runCount - 1)); out.write(runBuffer[runCount - 1]); runBuffer[0] = runBuffer[runCount]; runCount = 1; isSequence = NOT_IDENTIFY_SEQUENCE; break; } runCount++; break; } } } /** @see java.io.FilterOutputStream **/ public void write(byte[] b) throws IOException { for (byte aB : b) { this.write(aB); } } /** @see java.io.FilterOutputStream **/ public void write(byte[] b, int off, int len) throws IOException { for (int i = 0; i < len; i++) { this.write(b[off + i]); } } /** @see Finalizable **/ public void finalizeStream() throws IOException { switch (isSequence) { case IN_SEQUENCE: out.write(BYTE_MAX - (runCount - 1)); out.write(runBuffer[runCount - 1]); break; default: out.write(runCount - 1); out.write(runBuffer, 0, runCount); } out.write(END_OF_DATA); flush(); if (out instanceof Finalizable) { ((Finalizable) out).finalizeStream(); } } /** @see java.io.FilterOutputStream **/ public void close() throws IOException { finalizeStream(); super.close(); } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/util/io/SubInputStream.java0100644 0000000 0000000 00000007536 13777276623 030302 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: SubInputStream.java 1610846 2014-07-15 20:44:18Z vhennebert $ */ package org.apache.xmlgraphics.util.io; import java.io.FilterInputStream; import java.io.IOException; import java.io.InputStream; /** * This class is a FilterInputStream descendant that reads from an underlying InputStream * up to a defined number of bytes or the end of the underlying stream. Closing this InputStream * will not result in the underlying InputStream to be closed, too. *

    * This InputStream can be used to read chunks from a larger file of which the length is * known in advance. */ public class SubInputStream extends FilterInputStream { /** Indicates the number of bytes remaining to be read from the underlying InputStream. */ private long bytesToRead; /** * Indicates whether the underlying stream should be closed when the {@link #close()} method * is called. */ private boolean closeUnderlying; /** * Creates a new SubInputStream. * @param in the InputStream to read from * @param maxLen the maximum number of bytes to read from the underlying InputStream until * the end-of-file is signalled. * @param closeUnderlying true if the underlying stream should be closed when the * {@link #close()} method is called. */ public SubInputStream(InputStream in, long maxLen, boolean closeUnderlying) { super(in); this.bytesToRead = maxLen; this.closeUnderlying = closeUnderlying; } /** * Creates a new SubInputStream. The underlying stream is not closed, when close() is called. * @param in the InputStream to read from * @param maxLen the maximum number of bytes to read from the underlying InputStream until * the end-of-file is signalled. */ public SubInputStream(InputStream in, long maxLen) { this(in, maxLen, false); } /** {@inheritDoc} */ public int read() throws IOException { if (bytesToRead > 0) { int result = super.read(); if (result >= 0) { bytesToRead--; return result; } else { return -1; } } else { return -1; } } /** {@inheritDoc} */ public int read(byte[] b, int off, int len) throws IOException { if (bytesToRead == 0) { return -1; } int effRead = (int)Math.min(bytesToRead, len); //cast to int is safe because len can never be bigger than Integer.MAX_VALUE int result = super.read(b, off, effRead); if (result >= 0) { bytesToRead -= result; } return result; } /** {@inheritDoc} */ public long skip(long n) throws IOException { long effRead = Math.min(bytesToRead, n); long result = super.skip(effRead); bytesToRead -= result; return result; } /** {@inheritDoc} */ public void close() throws IOException { this.bytesToRead = 0; if (this.closeUnderlying) { super.close(); } } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/util/io/package.html0100644 0000000 0000000 00000001701 13777276623 026757 0ustar000000000 0000000 org.apache.xmlgraphics.util.io Package

    I/O-related classes (encoders/decoders, enhanced compressors etc.).

    xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/util/package.html0100644 0000000 0000000 00000001665 13777276623 026361 0ustar000000000 0000000 org.apache.xmlgraphics.util Package

    Various utilities used by the Apache XML Graphics project.

    xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/util/uri/CommonURIResolver.java0100644 0000000 0000000 00000007102 13777276623 031064 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: CommonURIResolver.java 1804124 2017-08-04 14:13:54Z ssteiner $ */ package org.apache.xmlgraphics.util.uri; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import javax.xml.transform.Source; import javax.xml.transform.TransformerException; import javax.xml.transform.URIResolver; import org.apache.xmlgraphics.util.Service; /** * A URI Resolver which supports pluggable entities via the {@link Service} * mechanism. *

    * This resolver will try all resolvers registered as an {@link URIResolver} * class. For proper operation, the registers URIResolvers must return null if * they cannot handle the given URI and fail fast. */ public class CommonURIResolver implements URIResolver { private final List uriResolvers = new LinkedList(); private static final class DefaultInstanceHolder { private static final CommonURIResolver INSTANCE = new CommonURIResolver(); } /** * Creates a new CommonURIResolver. Use this if you need support for * resolvers in the current context. * @see CommonURIResolver#getDefaultURIResolver() */ public CommonURIResolver() { Iterator iter = Service.providers(URIResolver.class); while (iter.hasNext()) { URIResolver resolver = (URIResolver) iter.next(); register(resolver); } } /** * Retrieve the default resolver instance. * * @return the default resolver instance. */ public static CommonURIResolver getDefaultURIResolver() { return DefaultInstanceHolder.INSTANCE; } /** {@inheritDoc} */ public Source resolve(String href, String base) { synchronized (uriResolvers) { for (Object uriResolver : uriResolvers) { final URIResolver currentResolver = (URIResolver) uriResolver; try { final Source result = currentResolver.resolve(href, base); if (result != null) { return result; } } catch (TransformerException e) { // Ignore. } } } return null; } /** * Register a given {@link URIResolver} while the software is running. * * @param uriResolver * the resolver to register. */ public void register(URIResolver uriResolver) { synchronized (uriResolvers) { uriResolvers.add(uriResolver); } } /** * Unregister a given {@link URIResolver} while the software is running. * * @param uriResolver * the resolver to unregister. */ public void unregister(URIResolver uriResolver) { synchronized (uriResolvers) { uriResolvers.remove(uriResolver); } } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/util/uri/DataURIResolver.java0100644 0000000 0000000 00000007024 13777276623 030510 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: DataURIResolver.java 1681108 2015-05-22 13:26:12Z ssteiner $ */ package org.apache.xmlgraphics.util.uri; import java.io.ByteArrayInputStream; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import javax.xml.transform.Source; import javax.xml.transform.TransformerException; import javax.xml.transform.URIResolver; import javax.xml.transform.stream.StreamSource; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.xmlgraphics.util.io.Base64DecodeStream; /** * Resolves data URLs (described in RFC 2397) returning its data as a StreamSource. * * @see javax.xml.transform.URIResolver * @see RFC 2397 */ public class DataURIResolver implements URIResolver { /** logger */ private static final Log LOG = LogFactory.getLog(URIResolver.class); /** * {@inheritDoc} */ public Source resolve(String href, String base) throws TransformerException { if (href.startsWith("data:")) { return parseDataURI(href); } else { return null; } } /** * Parses inline data URIs as generated by MS Word's XML export and FO * stylesheet. * * @see RFC 2397 */ private Source parseDataURI(String href) { int commaPos = href.indexOf(','); // header is of the form data:[][;base64] String header = href.substring(0, commaPos); String data = href.substring(commaPos + 1); if (header.endsWith(";base64")) { byte[] bytes = new byte[0]; try { bytes = data.getBytes("UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } ByteArrayInputStream encodedStream = new ByteArrayInputStream(bytes); Base64DecodeStream decodedStream = new Base64DecodeStream( encodedStream); return new StreamSource(decodedStream, href); } else { String encoding = "UTF-8"; final int charsetpos = header.indexOf(";charset="); if (charsetpos > 0) { encoding = header.substring(charsetpos + 9); } try { final String unescapedString = URLDecoder .decode(data, encoding); return new StreamSource(new java.io.StringReader( unescapedString), href); } catch (IllegalArgumentException e) { LOG.warn(e.getMessage()); } catch (UnsupportedEncodingException e) { LOG.warn(e.getMessage()); } } return null; } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/util/uri/DataURLUtil.java0100644 0000000 0000000 00000004765 13777276623 027640 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: DataURLUtil.java 1345683 2012-06-03 14:50:33Z gadams $ */ package org.apache.xmlgraphics.util.uri; import java.io.IOException; import java.io.InputStream; import java.io.StringWriter; import java.io.Writer; import org.apache.commons.io.IOUtils; import org.apache.xmlgraphics.util.WriterOutputStream; import org.apache.xmlgraphics.util.io.Base64EncodeStream; /** * Utility classes for generating RFC 2397 data URLs. */ public final class DataURLUtil { private DataURLUtil() { } /** * Creates a new data URL and returns it as a String. * @param in the InputStream to read the data from * @param mediatype the MIME type of the content, or null * @return the newly created data URL * @throws IOException if an I/O error occurs */ public static String createDataURL(InputStream in, String mediatype) throws IOException { StringWriter writer = new StringWriter(); writeDataURL(in, mediatype, writer); return writer.toString(); } /** * Generates a data URL and writes it to a Writer. * @param in the InputStream to read the data from * @param mediatype the MIME type of the content, or null * @param writer the Writer to write to * @throws IOException if an I/O error occurs */ public static void writeDataURL(InputStream in, String mediatype, Writer writer) throws IOException { writer.write("data:"); if (mediatype != null) { writer.write(mediatype); } writer.write(";base64,"); Base64EncodeStream out = new Base64EncodeStream( new WriterOutputStream(writer, "US-ASCII"), false); IOUtils.copy(in, out); out.close(); } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/xmp/Metadata.java0100644 0000000 0000000 00000013475 13777276623 026314 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: Metadata.java 1804124 2017-08-04 14:13:54Z ssteiner $ */ package org.apache.xmlgraphics.xmp; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import org.xml.sax.ContentHandler; import org.xml.sax.SAXException; import org.xml.sax.helpers.AttributesImpl; import org.apache.xmlgraphics.util.QName; import org.apache.xmlgraphics.util.XMLizable; import org.apache.xmlgraphics.xmp.merge.MergeRuleSet; import org.apache.xmlgraphics.xmp.merge.PropertyMerger; /** * This class represents the root of an XMP metadata tree. It's more or less equivalent to the * x:xmpmeta element together with its nested rdf:RDF element. */ public class Metadata implements XMLizable, PropertyAccess { private Map properties = new java.util.HashMap(); /** {@inheritDoc} */ public void setProperty(XMPProperty prop) { properties.put(prop.getName(), prop); } /** {@inheritDoc} */ public XMPProperty getProperty(String uri, String localName) { return getProperty(new QName(uri, localName)); } /** {@inheritDoc} */ public XMPProperty getProperty(QName name) { XMPProperty prop = (XMPProperty)properties.get(name); return prop; } /** {@inheritDoc} */ public XMPProperty removeProperty(QName name) { return (XMPProperty)properties.remove(name); } /** {@inheritDoc} */ public XMPProperty getValueProperty() { return getProperty(XMPConstants.RDF_VALUE); } /** {@inheritDoc} */ public int getPropertyCount() { return this.properties.size(); } /** {@inheritDoc} */ public Iterator iterator() { return this.properties.keySet().iterator(); } /** * Merges this metadata object into a given target metadata object. The merge rule set provided * by each schema is used for the merge. * @param target the target metadata to merge the local metadata into */ public void mergeInto(Metadata target, List exclude) { XMPSchemaRegistry registry = XMPSchemaRegistry.getInstance(); for (Object o : properties.values()) { XMPProperty prop = (XMPProperty) o; XMPSchema schema = registry.getSchema(prop.getNamespace()); if (!exclude.contains(schema.getClass())) { MergeRuleSet rules = schema.getDefaultMergeRuleSet(); PropertyMerger merger = rules.getPropertyMergerFor(prop); merger.merge(prop, target); } } } /** {@inheritDoc} */ public void toSAX(ContentHandler handler) throws SAXException { AttributesImpl atts = new AttributesImpl(); handler.startPrefixMapping("x", XMPConstants.XMP_NAMESPACE); handler.startElement(XMPConstants.XMP_NAMESPACE, "xmpmeta", "x:xmpmeta", atts); handler.startPrefixMapping("rdf", XMPConstants.RDF_NAMESPACE); handler.startElement(XMPConstants.RDF_NAMESPACE, "RDF", "rdf:RDF", atts); //Get all property namespaces Set namespaces = new java.util.HashSet(); Iterator iter = properties.keySet().iterator(); while (iter.hasNext()) { QName n = ((QName)iter.next()); namespaces.add(n.getNamespaceURI()); } //One Description element per namespace iter = namespaces.iterator(); while (iter.hasNext()) { String ns = (String)iter.next(); XMPSchema schema = XMPSchemaRegistry.getInstance().getSchema(ns); String prefix = (schema != null ? schema.getPreferredPrefix() : null); boolean first = true; boolean empty = true; for (Object o : properties.values()) { XMPProperty prop = (XMPProperty) o; if (prop.getName().getNamespaceURI().equals(ns)) { if (first) { if (prefix == null) { prefix = prop.getName().getPrefix(); } atts.clear(); atts.addAttribute(XMPConstants.RDF_NAMESPACE, "about", "rdf:about", "CDATA", ""); if (prefix != null) { handler.startPrefixMapping(prefix, ns); } handler.startElement(XMPConstants.RDF_NAMESPACE, "Description", "rdf:Description", atts); empty = false; first = false; } prop.toSAX(handler); } } if (!empty) { handler.endElement(XMPConstants.RDF_NAMESPACE, "Description", "rdf:Description"); if (prefix != null) { handler.endPrefixMapping(prefix); } } } handler.endElement(XMPConstants.RDF_NAMESPACE, "RDF", "rdf:RDF"); handler.endPrefixMapping("rdf"); handler.endElement(XMPConstants.XMP_NAMESPACE, "xmpmeta", "x:xmpmeta"); handler.endPrefixMapping("x"); } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/xmp/PropertyAccess.java0100644 0000000 0000000 00000004643 13777276623 027537 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: PropertyAccess.java 1345683 2012-06-03 14:50:33Z gadams $ */ package org.apache.xmlgraphics.xmp; import java.util.Iterator; import org.apache.xmlgraphics.util.QName; /** * This interface is implemented by the top-level Metadata class and stuctured properties. */ public interface PropertyAccess { /** * Sets a property. * @param prop the property */ void setProperty(XMPProperty prop); /** * Returns a property * @param uri the namespace URI of the property * @param localName the local name of the property * @return the requested property or null if it's not available */ XMPProperty getProperty(String uri, String localName); /** * Returns a property. * @param name the name of the property * @return the requested property or null if it's not available */ XMPProperty getProperty(QName name); /** * Removes a property and returns it if it was found. * @param name the name of the property * @return the removed property or null if it was not found */ XMPProperty removeProperty(QName name); /** * Returns the rdf:value property. This is a shortcut for getProperty(XMPConstants.RDF_VALUE). * @return the rdf:value property or null if it's no available */ XMPProperty getValueProperty(); /** * Returns the number of properties. * @return the number of properties in this metadata object. */ int getPropertyCount(); /** * Returns an Iterator over all properties in this structured property. * @return an Iterator over all properties */ Iterator iterator(); } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/xmp/XMPArray.java0100644 0000000 0000000 00000017664 13777276623 026243 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: XMPArray.java 1681108 2015-05-22 13:26:12Z ssteiner $ */ package org.apache.xmlgraphics.xmp; import java.net.URI; import java.util.List; import org.xml.sax.ContentHandler; import org.xml.sax.SAXException; import org.xml.sax.helpers.AttributesImpl; /** * Represents an XMP array as defined by the XMP specification. */ public class XMPArray extends XMPComplexValue { //TODO Property qualifiers are currently not supported, yet. private XMPArrayType type; private List values = new java.util.ArrayList(); private List xmllang = new java.util.ArrayList(); /** * Main constructor * @param type the intended type of array */ public XMPArray(XMPArrayType type) { this.type = type; } /** @return the type of array */ public XMPArrayType getType() { return this.type; } /** * Returns the value at a given position. * @param idx the index of the requested value * @return the value at the given position */ public Object getValue(int idx) { return this.values.get(idx); } /** * Returns the structure at a given position. If the value is not a structure a * ClassCastException is thrown. * @param idx the index of the requested value * @return the structure at the given position */ public XMPStructure getStructure(int idx) { return (XMPStructure)this.values.get(idx); } /** {@inheritDoc} */ public Object getSimpleValue() { if (values.size() == 1) { return getValue(0); } else if (values.size() > 1) { return getLangValue(XMPConstants.DEFAULT_LANGUAGE); } else { return null; } } private String getParentLanguage(String lang) { if (lang == null) { return null; } int pos = lang.indexOf('-'); if (pos > 0) { String parent = lang.substring(0, pos); return parent; } return null; } /** * Returns a language-dependent values (available for alternative arrays). * @param lang the language ("x-default" for the default value) * @return the requested value */ public String getLangValue(String lang) { String v = null; String valueForParentLanguage = null; for (int i = 0, c = values.size(); i < c; i++) { String l = (String)xmllang.get(i); if ((l == null && lang == null) || (l != null && l.equals(lang))) { v = values.get(i).toString(); break; } if (l != null && lang != null) { //Check for "parent" language, too ("en" matches "en-GB") String parent = getParentLanguage(l); if (parent != null && parent.equals(lang)) { valueForParentLanguage = values.get(i).toString(); } } } if (lang != null && v == null && valueForParentLanguage != null) { //Use value found for parent language v = valueForParentLanguage; } if (lang == null && v == null) { v = getLangValue(XMPConstants.DEFAULT_LANGUAGE); if (v == null && values.size() > 0) { v = getValue(0).toString(); //get first } } return v; } /** * Removes a language-dependent value. * @param lang the language ("x-default" for the default value) * @return the removed value (or null if no value was set) */ public String removeLangValue(String lang) { if (lang == null || "".equals(lang)) { lang = XMPConstants.DEFAULT_LANGUAGE; } for (int i = 0, c = values.size(); i < c; i++) { String l = (String)xmllang.get(i); if ((XMPConstants.DEFAULT_LANGUAGE.equals(lang) && l == null) || lang.equals(l)) { String value = (String)values.remove(i); xmllang.remove(i); return value; } } return null; } /** * Adds a new value to the array * @param value the value */ public void add(Object value) { values.add(value); xmllang.add(null); } /** * Removes a value from the array. If the value doesn't exist, nothing happens. * @param value the value to be removed * @return true if the value was removed, false if it wasn't found */ public boolean remove(String value) { int idx = values.indexOf(value); if (idx >= 0) { values.remove(idx); xmllang.remove(idx); return true; } return false; } /** * Adds a language-dependent value to the array. Make sure not to add the same language twice. * @param value the value * @param lang the language ("x-default" for the default value) */ public void add(String value, String lang) { values.add(value); xmllang.add(lang); } /** * Returns the current number of values in the array. * @return the current number of values in the array */ public int getSize() { return this.values.size(); } /** * Indicates whether the array is empty or not. * @return true if the array is empty */ public boolean isEmpty() { return getSize() == 0; } /** * Converts the array to an object array. * @return an object array of all values in the array */ public Object[] toObjectArray() { Object[] res = new Object[getSize()]; for (int i = 0, c = res.length; i < c; i++) { res[i] = getValue(i); } return res; } /** {@inheritDoc} */ public void toSAX(ContentHandler handler) throws SAXException { AttributesImpl atts = new AttributesImpl(); handler.startElement(XMPConstants.RDF_NAMESPACE, type.getName(), "rdf:" + type.getName(), atts); for (int i = 0, c = values.size(); i < c; i++) { String lang = (String)xmllang.get(i); atts.clear(); Object v = values.get(i); if (lang != null) { atts.addAttribute(XMPConstants.XML_NS, "lang", "xml:lang", "CDATA", lang); } if (v instanceof URI) { atts.addAttribute(XMPConstants.RDF_NAMESPACE, "resource", "rdf:resource", "CDATA", ((URI)v).toString()); } handler.startElement(XMPConstants.RDF_NAMESPACE, "li", "rdf:li", atts); if (v instanceof XMPComplexValue) { ((XMPComplexValue)v).toSAX(handler); } else if (!(v instanceof URI)) { String value = (String)values.get(i); char[] chars = value.toCharArray(); handler.characters(chars, 0, chars.length); } handler.endElement(XMPConstants.RDF_NAMESPACE, "li", "rdf:li"); } handler.endElement(XMPConstants.RDF_NAMESPACE, type.getName(), "rdf:" + type.getName()); } /** {@inheritDoc} */ public String toString() { return "XMP array: " + type + ", " + getSize(); } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/xmp/XMPArrayType.java0100644 0000000 0000000 00000003241 13777276623 027067 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: XMPArrayType.java 750418 2009-03-05 11:03:54Z vhennebert $ */ package org.apache.xmlgraphics.xmp; /** Enum class for XMP array types. */ public final class XMPArrayType { /** the unordered array */ public static final XMPArrayType BAG = new XMPArrayType("Bag"); /** the ordered array */ public static final XMPArrayType SEQ = new XMPArrayType("Seq"); /** the alternative array */ public static final XMPArrayType ALT = new XMPArrayType("Alt"); private String name; /** * Constructor to add a new named item. * @param name Name of the item. */ private XMPArrayType(String name) { this.name = name; } /** @return the name of the enum */ public String getName() { return this.name; } /** @see java.lang.Object#toString() */ public String toString() { return "rdf:" + name; } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/xmp/XMPComplexValue.java0100644 0000000 0000000 00000002550 13777276623 027555 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: XMPComplexValue.java 750418 2009-03-05 11:03:54Z vhennebert $ */ package org.apache.xmlgraphics.xmp; import org.apache.xmlgraphics.util.XMLizable; /** * Base class for complex data types in XMP. */ public abstract class XMPComplexValue implements XMLizable { /** * Returns a normal Java object representing the value if it is available. * @return a simple object value or null if no such value can be returned (for example, * because the value is an array and has multiple entries. */ public abstract Object getSimpleValue(); } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/xmp/XMPConstants.java0100644 0000000 0000000 00000005165 13777276623 027132 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: XMPConstants.java 1685768 2015-06-16 11:46:06Z ssteiner $ */ package org.apache.xmlgraphics.xmp; import org.apache.xmlgraphics.util.QName; /** * Constants used in XMP metadata. */ public interface XMPConstants { /** Namespace URI for the xml: prefix */ String XML_NS = "http://www.w3.org/XML/1998/namespace"; /** Namespace URI for the xmlns: prefix */ String XMLNS_NAMESPACE = "http://www.w3.org/2000/xmlns/"; /** Namespace URI for XMP */ String XMP_NAMESPACE = "adobe:ns:meta/"; /** Namespace URI for RDF */ String RDF_NAMESPACE = "http://www.w3.org/1999/02/22-rdf-syntax-ns#"; /** Namespace URI for Dublin Core */ String DUBLIN_CORE_NAMESPACE = "http://purl.org/dc/elements/1.1/"; /** Namespace URI for the XMP Basic Schema */ String XMP_BASIC_NAMESPACE = "http://ns.adobe.com/xap/1.0/"; /** Namespace URI for the Adobe PDF Schema */ String ADOBE_PDF_NAMESPACE = "http://ns.adobe.com/pdf/1.3/"; /** Namespace URI for PDF X */ String PDF_X_IDENTIFICATION = "http://www.npes.org/pdfx/ns/id/"; /** Namespace URI for PDF VT */ String PDF_VT_IDENTIFICATION = "http://www.npes.org/pdfvt/ns/id/"; String PDF_UA_IDENTIFICATION = "http://www.aiim.org/pdfua/ns/id/"; /** Namespace URI for XMP Media Management */ String XAP_MM_NAMESPACE = "http://ns.adobe.com/xap/1.0/mm/"; /** * Namespace URI for the PDF/A Identification Schema * (from the technical corrigendum 1 of ISO 19005-1:2005, note that the trailing slash * was missing in the original ISO 19005-1:2005 specification) */ String PDF_A_IDENTIFICATION = "http://www.aiim.org/pdfa/ns/id/"; /** Default language for the xml:lang property */ String DEFAULT_LANGUAGE = "x-default"; /** QName for rdf:value */ QName RDF_VALUE = new QName(RDF_NAMESPACE, "rdf", "value"); } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/xmp/XMPHandler.java0100644 0000000 0000000 00000027203 13777276623 026530 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: XMPHandler.java 1681108 2015-05-22 13:26:12Z ssteiner $ */ package org.apache.xmlgraphics.xmp; import java.net.URI; import java.net.URISyntaxException; import java.util.Stack; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.AttributesImpl; import org.xml.sax.helpers.DefaultHandler; import org.apache.xmlgraphics.util.QName; /** * Passive XMP parser implemented as a SAX DefaultHandler. After the XML document has been parsed * the Metadata object can be retrieved. */ public class XMPHandler extends DefaultHandler { private Metadata meta; private StringBuffer content = new StringBuffer(); private Stack attributesStack = new Stack(); private Stack nestingInfoStack = new Stack(); private Stack contextStack = new Stack(); /** @return the parsed metadata, available after the parsing. */ public Metadata getMetadata() { return this.meta; } private boolean hasComplexContent() { Object obj = this.contextStack.peek(); return !(obj instanceof QName); } private PropertyAccess getCurrentProperties() { Object obj = this.contextStack.peek(); if (obj instanceof PropertyAccess) { return (PropertyAccess)obj; } else { return null; } } private QName getCurrentPropName() { Object obj = this.contextStack.peek(); if (obj instanceof QName) { return (QName)obj; } else { return null; } } private QName popCurrentPropName() throws SAXException { Object obj = this.contextStack.pop(); this.nestingInfoStack.pop(); if (obj instanceof QName) { return (QName)obj; } else { throw new SAXException("Invalid XMP structure. Property name expected"); } } // private XMPComplexValue getCurrentComplexValue() { // Object obj = this.contextStack.peek(); // if (obj instanceof XMPComplexValue) { // return (XMPComplexValue)obj; // } else { // return null; // } // } private XMPStructure getCurrentStructure() { Object obj = this.contextStack.peek(); if (obj instanceof XMPStructure) { return (XMPStructure)obj; } else { return null; } } private XMPArray getCurrentArray(boolean required) throws SAXException { Object obj = this.contextStack.peek(); if (obj instanceof XMPArray) { return (XMPArray)obj; } else { if (required) { throw new SAXException("Invalid XMP structure. Not in array"); } else { return null; } } } // --- Overrides --- /** {@inheritDoc} */ public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { super.startElement(uri, localName, qName, attributes); content.setLength(0); //Reset text buffer (see characters()) attributesStack.push(new AttributesImpl(attributes)); if (XMPConstants.XMP_NAMESPACE.equals(uri)) { if (!"xmpmeta".equals(localName)) { throw new SAXException("Expected x:xmpmeta element, not " + qName); } if (this.meta != null) { throw new SAXException("Invalid XMP document. Root already received earlier."); } this.meta = new Metadata(); this.contextStack.push(this.meta); this.nestingInfoStack.push("metadata"); } else if (XMPConstants.RDF_NAMESPACE.equals(uri)) { if ("RDF".equals(localName)) { if (this.meta == null) { this.meta = new Metadata(); this.contextStack.push(this.meta); this.nestingInfoStack.push("metadata"); } } else if ("Description".equals(localName)) { String about = attributes.getValue(XMPConstants.RDF_NAMESPACE, "about"); for (int i = 0, c = attributes.getLength(); i < c; i++) { String ns = attributes.getURI(i); if (XMPConstants.RDF_NAMESPACE.equals(ns)) { //ignore } else if (XMPConstants.XMLNS_NAMESPACE.equals(ns)) { //ignore } else if ("".equals(ns)) { //ignore } else { String qn = attributes.getQName(i); String v = attributes.getValue(i); XMPProperty prop = new XMPProperty(new QName(ns, qn), v); getCurrentProperties().setProperty(prop); } } if (this.contextStack.peek().equals(this.meta)) { //rdf:RDF is the parent } else { if (about != null) { throw new SAXException( "Nested rdf:Description elements may not have an about property"); } startStructure(); } } else if ("Seq".equals(localName)) { XMPArray array = new XMPArray(XMPArrayType.SEQ); this.contextStack.push(array); this.nestingInfoStack.push("Seq"); } else if ("Bag".equals(localName)) { XMPArray array = new XMPArray(XMPArrayType.BAG); this.contextStack.push(array); this.nestingInfoStack.push("Bag"); } else if ("Alt".equals(localName)) { XMPArray array = new XMPArray(XMPArrayType.ALT); this.contextStack.push(array); this.nestingInfoStack.push("Alt"); } else if ("li".equals(localName)) { //nop, handle in endElement() } else if ("value".equals(localName)) { QName name = new QName(uri, qName); this.contextStack.push(name); this.nestingInfoStack.push("prop:" + name); } else { throw new SAXException("Unexpected element in the RDF namespace: " + localName); } } else { if (getCurrentPropName() != null) { //Structure (shorthand form) startStructure(); } QName name = new QName(uri, qName); this.contextStack.push(name); this.nestingInfoStack.push("prop:" + name); } } private void startStructure() { //a structured property is the parent XMPStructure struct = new XMPStructure(); this.contextStack.push(struct); this.nestingInfoStack.push("struct"); } /** {@inheritDoc} */ public void endElement(String uri, String localName, String qName) throws SAXException { Attributes atts = (Attributes)attributesStack.pop(); if (XMPConstants.XMP_NAMESPACE.equals(uri)) { //nop } else if (XMPConstants.RDF_NAMESPACE.equals(uri) && !"value".equals(localName)) { if ("li".equals(localName)) { XMPStructure struct = getCurrentStructure(); if (struct != null) { //Pop the structure this.contextStack.pop(); this.nestingInfoStack.pop(); getCurrentArray(true).add(struct); } else { String s = content.toString().trim(); if (s.length() > 0) { String lang = atts.getValue(XMPConstants.XML_NS, "lang"); if (lang != null) { getCurrentArray(true).add(s, lang); } else { getCurrentArray(true).add(s); } } else { String res = atts.getValue(XMPConstants.RDF_NAMESPACE, "resource"); if (res != null) { try { URI resource = new URI(res); getCurrentArray(true).add(resource); } catch (URISyntaxException e) { throw new SAXException("rdf:resource value is not a well-formed URI", e); } } } } } else if ("Description".equals(localName)) { /* if (isInStructure()) { //Description is indicating a structure //this.currentProperties = (PropertyAccess)propertiesStack.pop(); this.nestingInfoStack.pop(); }*/ } else { //nop, don't pop stack so the parent element has access } } else { XMPProperty prop; QName name; if (hasComplexContent()) { //Pop content of property Object obj = this.contextStack.pop(); this.nestingInfoStack.pop(); name = popCurrentPropName(); if (obj instanceof XMPComplexValue) { XMPComplexValue complexValue = (XMPComplexValue)obj; prop = new XMPProperty(name, complexValue); } else { throw new UnsupportedOperationException("NYI"); } } else { name = popCurrentPropName(); String s = content.toString().trim(); prop = new XMPProperty(name, s); String lang = atts.getValue(XMPConstants.XML_NS, "lang"); String res = atts.getValue(XMPConstants.RDF_NAMESPACE, "resource"); if (lang != null) { prop.setXMLLang(lang); } if (res != null) { try { URI resource = new URI(res); prop.setValue(resource); } catch (URISyntaxException e) { throw new SAXException("rdf:resource value is not a well-formed URI", e); } } } if (prop.getName() == null) { throw new IllegalStateException("No content in XMP property"); } assert getCurrentProperties() != null : "no current property"; getCurrentProperties().setProperty(prop); } content.setLength(0); //Reset text buffer (see characters()) super.endElement(uri, localName, qName); } /* private boolean isInStructure() { return !propertiesStack.isEmpty(); } */ /** {@inheritDoc} */ public void characters(char[] ch, int start, int length) throws SAXException { content.append(ch, start, length); } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/xmp/XMPPacketParser.java0100644 0000000 0000000 00000011305 13777276623 027533 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: XMPPacketParser.java 1681108 2015-05-22 13:26:12Z ssteiner $ */ package org.apache.xmlgraphics.xmp; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import javax.xml.transform.TransformerException; import javax.xml.transform.stream.StreamSource; import org.apache.commons.io.IOUtils; import org.apache.commons.io.output.ByteArrayOutputStream; /** * This class is a parser for XMP packets. By default, it tries to locate the first XMP packet * it finds and parses it. *

    * Important: Before you use this class to look for an XMP packet in some random file, please read * the chapter on "Scanning Files for XMP Packets" in the XMP specification! */ public final class XMPPacketParser { private XMPPacketParser() { } private static final byte[] PACKET_HEADER; private static final byte[] PACKET_HEADER_END; private static final byte[] PACKET_TRAILER; static { try { PACKET_HEADER = "".getBytes("US-ASCII"); PACKET_TRAILER = "= 0) { if (b == match[found]) { found++; if (found == len) { return true; } } else { if (out != null) { if (found > 0) { out.write(match, 0, found); } out.write(b); } found = 0; } } return false; } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/xmp/XMPParser.java0100644 0000000 0000000 00000005152 13777276623 026406 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: XMPParser.java 1878394 2020-06-02 13:18:41Z ssteiner $ */ package org.apache.xmlgraphics.xmp; import java.net.URL; import javax.xml.XMLConstants; import javax.xml.transform.Source; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.sax.SAXResult; import javax.xml.transform.stream.StreamSource; /** * The XMP parser. */ public final class XMPParser { private XMPParser() { } /** * Parses an XMP file. * @param url the URL to load the file from * @return the parsed Metadata object * @throws TransformerException if an error occurs while parsing the file */ public static Metadata parseXMP(URL url) throws TransformerException { return parseXMP(new StreamSource(url.toExternalForm())); } /** * Parses an XMP file. * @param src a JAXP Source object where the XMP file can be loaded from * @return the parsed Metadata object * @throws TransformerException if an error occurs while parsing the file */ public static Metadata parseXMP(Source src) throws TransformerException { TransformerFactory tFactory = TransformerFactory.newInstance(); tFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); tFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, ""); Transformer transformer = tFactory.newTransformer(); XMPHandler handler = createXMPHandler(); SAXResult res = new SAXResult(handler); transformer.transform(src, res); return handler.getMetadata(); } /** * Creates and returns an XMPHandler for passive XMP parsing. * @return the requested XMPHandler */ public static XMPHandler createXMPHandler() { return new XMPHandler(); } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/xmp/XMPProperty.java0100644 0000000 0000000 00000016547 13777276623 027010 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: XMPProperty.java 1731596 2016-02-22 08:28:54Z gadams $ */ package org.apache.xmlgraphics.xmp; import java.net.URI; import java.util.Iterator; import java.util.Map; import org.xml.sax.ContentHandler; import org.xml.sax.SAXException; import org.xml.sax.helpers.AttributesImpl; import org.apache.xmlgraphics.util.QName; import org.apache.xmlgraphics.util.XMLizable; /** * This class is the base class for all XMP properties. */ public class XMPProperty implements XMLizable { private QName name; private Object value; private String xmllang; private Map qualifiers; /** * Creates a new XMP property. * @param name the name of the property * @param value the value for the property */ public XMPProperty(QName name, Object value) { this.name = name; this.value = value; } /** @return the qualified name of the property (namespace URI + local name) */ public QName getName() { return this.name; } /** @return the namespace URI of the property */ public String getNamespace() { return getName().getNamespaceURI(); } /** * Sets the value of the property * @param value the new value */ public void setValue(Object value) { this.value = value; } /** * @return the property value (can be a normal Java object (normally a String) or a descendant * of XMPComplexValue. */ public Object getValue() { return this.value; } /** * Sets the xml:lang value for this property * @param lang the language ("x-default" for the default language, null to make the value * language-independent) */ public void setXMLLang(String lang) { this.xmllang = lang; } /** * @return the language for language-dependent values ("x-default" for the default language) */ public String getXMLLang() { return this.xmllang; } /** * Indicates whether the property is an array. * @return true if the property is an array */ public boolean isArray() { return value instanceof XMPArray; } /** @return the XMPArray for an array or null if the value is not an array. */ public XMPArray getArrayValue() { return (isArray() ? (XMPArray)value : null); } /** * Converts a simple value to an array of a given type if the value is not already an array. * @param type the desired type of array * @return the array value */ public XMPArray convertSimpleValueToArray(XMPArrayType type) { if (getArrayValue() == null) { XMPArray array = new XMPArray(type); if (getXMLLang() != null) { array.add(getValue().toString(), getXMLLang()); } else { array.add(getValue()); } setValue(array); setXMLLang(null); return array; } else { return getArrayValue(); } } /** @return the XMPStructure for a structure or null if the value is not a structure. */ public PropertyAccess getStructureValue() { return (value instanceof XMPStructure ? (XMPStructure)value : null); } private boolean hasPropertyQualifiers() { return (this.qualifiers == null) || (this.qualifiers.size() == 0); } /** * Indicates whether this property is actually not a structure, but a normal property with * property qualifiers. If this method returns true, this structure can be converted to * an simple XMPProperty using the simplify() method. * @return true if this property is a structure property with property qualifiers */ public boolean isQualifiedProperty() { PropertyAccess props = getStructureValue(); if (props != null) { XMPProperty rdfValue = props.getValueProperty(); return (rdfValue != null); } else { return hasPropertyQualifiers(); } } public void simplify() { PropertyAccess props = getStructureValue(); if (props != null) { XMPProperty rdfValue = props.getValueProperty(); if (rdfValue != null) { if (hasPropertyQualifiers()) { throw new IllegalStateException("Illegal internal state" + " (qualifiers present on non-simplified property)"); } XMPProperty prop = new XMPProperty(getName(), rdfValue); Iterator iter = props.iterator(); while (iter.hasNext()) { QName name = (QName)iter.next(); if (!XMPConstants.RDF_VALUE.equals(name)) { prop.setPropertyQualifier(name, props.getProperty(name)); } } props.setProperty(prop); } } } private void setPropertyQualifier(QName name, XMPProperty property) { if (this.qualifiers == null) { this.qualifiers = new java.util.HashMap(); } this.qualifiers.put(name, property); } private String getEffectiveQName() { String prefix = getName().getPrefix(); if (prefix == null || "".equals(prefix)) { XMPSchema schema = XMPSchemaRegistry.getInstance().getSchema(getNamespace()); prefix = schema.getPreferredPrefix(); } return prefix + ":" + getName().getLocalName(); } /** @see org.apache.xmlgraphics.util.XMLizable#toSAX(org.xml.sax.ContentHandler) */ public void toSAX(ContentHandler handler) throws SAXException { AttributesImpl atts = new AttributesImpl(); String qName = getEffectiveQName(); if (value instanceof URI) { atts.addAttribute(XMPConstants.RDF_NAMESPACE, "resource", "rdf:resource", "CDATA", ((URI)value).toString()); } handler.startElement(getName().getNamespaceURI(), getName().getLocalName(), qName, atts); if (value instanceof XMPComplexValue) { XMPComplexValue cv = ((XMPComplexValue)value); cv.toSAX(handler); } else if (!(value instanceof URI)) { char[] chars = value.toString().toCharArray(); handler.characters(chars, 0, chars.length); } handler.endElement(getName().getNamespaceURI(), getName().getLocalName(), qName); } /** @see java.lang.Object#toString() */ public String toString() { StringBuffer sb = new StringBuffer("XMP Property "); sb.append(getName()).append(": "); sb.append(getValue()); return sb.toString(); } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/xmp/XMPSchema.java0100644 0000000 0000000 00000004336 13777276623 026355 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: XMPSchema.java 750418 2009-03-05 11:03:54Z vhennebert $ */ package org.apache.xmlgraphics.xmp; import org.apache.xmlgraphics.util.QName; import org.apache.xmlgraphics.xmp.merge.MergeRuleSet; /** * Base class for schema implementations that provide user-friendly access to XMP values. */ public class XMPSchema { private static MergeRuleSet defaultMergeRuleSet = new MergeRuleSet(); private String namespace; private String prefix; /** * Constructs a new XMP schema object. * @param namespace the namespace URI for the schema * @param preferredPrefix the preferred prefix for the schema */ public XMPSchema(String namespace, String preferredPrefix) { this.namespace = namespace; this.prefix = preferredPrefix; } /** @return the namespace URI of the schema */ public String getNamespace() { return this.namespace; } /** @return the preferred prefix of the schema */ public String getPreferredPrefix() { return this.prefix; } /** * Returns the QName for a property of this schema. * @param propName the property name * @return the QName for the property */ protected QName getQName(String propName) { return new QName(getNamespace(), propName); } /** @return the default merge rule set for this XMP schema. */ public MergeRuleSet getDefaultMergeRuleSet() { return defaultMergeRuleSet; } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/xmp/XMPSchemaAdapter.java0100644 0000000 0000000 00000035363 13777276623 027662 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: XMPSchemaAdapter.java 1829045 2018-04-13 09:22:33Z ssteiner $ */ package org.apache.xmlgraphics.xmp; import java.util.Date; import java.util.TimeZone; import org.apache.xmlgraphics.util.DateFormatUtil; import org.apache.xmlgraphics.util.QName; /** * Base class for schema-specific adapters that provide user-friendly access to XMP values. */ public class XMPSchemaAdapter { /** the Metadata object this schema instance operates on */ protected Metadata meta; private XMPSchema schema; private boolean compact = true; /** * Main constructor. * @param meta the Metadata object to wrao * @param schema the XMP schema for which this adapter was written */ public XMPSchemaAdapter(Metadata meta, XMPSchema schema) { if (meta == null) { throw new NullPointerException("Parameter meta must not be null"); } if (schema == null) { throw new NullPointerException("Parameter schema must not be null"); } this.meta = meta; this.schema = schema; } /** @return the XMP schema associated with this adapter */ public XMPSchema getSchema() { return this.schema; } /** * Returns the QName for a given property * @param propName the property name * @return the resulting QName */ protected QName getQName(String propName) { return new QName(getSchema().getNamespace(), getSchema().getPreferredPrefix(), propName); } /** * Adds a String value to an array. * @param propName the property name * @param value the String value * @param arrayType the type of array to operate on */ private void addStringToArray(String propName, String value, XMPArrayType arrayType) { if (value == null || value.length() == 0) { throw new IllegalArgumentException("'" + propName + "' value must not be empty"); } addObjectToArray(propName, value, arrayType); } /** * Adds a Object value to an array. * @param propName the property name * @param value the Object value * @param arrayType the type of array to operate on */ protected void addObjectToArray(String propName, Object value, XMPArrayType arrayType) { if (value == null) { throw new IllegalArgumentException("'" + propName + "' value must not be null"); } QName name = getQName(propName); XMPProperty prop = meta.getProperty(name); if (prop == null) { prop = new XMPProperty(name, value); meta.setProperty(prop); if (!compact) { prop.convertSimpleValueToArray(arrayType); } } else { prop.convertSimpleValueToArray(arrayType); prop.getArrayValue().add(value); } } /** * Removes a value from an array. * @param propName the name of the property * @param value the value to be removed * @return true if the value was removed, false if it was not found */ protected boolean removeStringFromArray(String propName, String value) { if (value == null) { return false; } QName name = getQName(propName); XMPProperty prop = meta.getProperty(name); if (prop != null) { if (prop.isArray()) { XMPArray arr = prop.getArrayValue(); boolean removed = arr.remove(value); if (arr.isEmpty()) { meta.removeProperty(name); } return removed; } else { Object currentValue = prop.getValue(); if (value.equals(currentValue)) { meta.removeProperty(name); return true; } } } return false; } /** * Adds a String value to an ordered array. * @param propName the property name * @param value the String value */ protected void addStringToSeq(String propName, String value) { addStringToArray(propName, value, XMPArrayType.SEQ); } /** * Adds a String value to an unordered array. * @param propName the property name * @param value the String value */ protected void addStringToBag(String propName, String value) { addStringToArray(propName, value, XMPArrayType.BAG); } /** * Formats a Date using ISO 8601 format in the default time zone. * @param dt the date * @return the formatted date */ public static String formatISO8601Date(Date dt) { return formatISO8601Date(dt, TimeZone.getDefault()); } /** * Formats a Date using ISO 8601 format in the given time zone. * @param dt the date * @param tz the time zone * @return the formatted date */ public static String formatISO8601Date(Date dt, TimeZone tz) { return DateFormatUtil.formatISO8601(dt, tz); } /** * Adds a date value to an ordered array. * @param propName the property name * @param value the date value */ protected void addDateToSeq(String propName, Date value) { String dt = formatISO8601Date(value); addStringToSeq(propName, dt); } /** * Set a date value. * @param propName the property name * @param value the date value */ protected void setDateValue(String propName, Date value) { String dt = formatISO8601Date(value); setValue(propName, dt); } /** * Returns a date value. * @param propName the property name * @return the date value or null if the value is not set */ protected Date getDateValue(String propName) { String dt = getValue(propName); if (dt == null) { return null; } else { return DateFormatUtil.parseISO8601Date(dt); } } /** * Sets a language-dependent value. * @param propName the property name * @param lang the language ("x-default" or null for the default language) * @param value the value */ protected void setLangAlt(String propName, String lang, String value) { if (lang == null) { lang = XMPConstants.DEFAULT_LANGUAGE; } QName name = getQName(propName); XMPProperty prop = meta.getProperty(name); XMPArray array; if (prop == null) { if (value != null && value.length() > 0) { prop = new XMPProperty(name, value); prop.setXMLLang(lang); meta.setProperty(prop); } } else { prop.convertSimpleValueToArray(XMPArrayType.ALT); array = prop.getArrayValue(); array.removeLangValue(lang); if (value != null && value.length() > 0) { array.add(value, lang); } else { if (array.isEmpty()) { meta.removeProperty(name); } } } } /** * Sets a simple value. * @param propName the property name * @param value the value */ protected void setValue(String propName, String value) { QName name = getQName(propName); XMPProperty prop = meta.getProperty(name); if (value != null && value.length() > 0) { if (prop != null) { prop.setValue(value); } else { prop = new XMPProperty(name, value); meta.setProperty(prop); } } else { if (prop != null) { meta.removeProperty(name); } } } /** * Returns a simple value. * @param propName the property name * @return the requested value or null if it isn't set */ protected String getValue(String propName) { QName name = getQName(propName); XMPProperty prop = meta.getProperty(name); if (prop == null) { return null; } else { return prop.getValue().toString(); } } /** * Removes a language-dependent value from an alternative array. * @param lang the language ("x-default" for the default language) * @param propName the property name * @return the removed value */ protected String removeLangAlt(String lang, String propName) { QName name = getQName(propName); XMPProperty prop = meta.getProperty(name); XMPArray array; if (prop != null && lang != null) { array = prop.getArrayValue(); if (array != null) { String removed = array.removeLangValue(lang); if (array.isEmpty()) { meta.removeProperty(name); } return removed; } else { String removed = prop.getValue().toString(); if (lang.equals(prop.getXMLLang())) { meta.removeProperty(name); } return removed; } } return null; } /** * Returns a language-dependent value. If the value in the requested language is not available * the value for the default language is returned. * @param lang the language ("x-default" for the default language) * @param propName the property name * @return the requested value */ protected String getLangAlt(String lang, String propName) { XMPProperty prop = meta.getProperty(getQName(propName)); XMPArray array; if (prop == null) { return null; } else { array = prop.getArrayValue(); if (array != null) { return array.getLangValue(lang); } else { return prop.getValue().toString(); } } } /** * Finds a structure that matches a given qualifier. * @param propName the property name * @param qualifier the qualifier * @param qualifierValue the qualifier value * @return the structure if a match was found (or null if no match was found) */ protected PropertyAccess findQualifiedStructure(String propName, QName qualifier, String qualifierValue) { XMPProperty prop = meta.getProperty(getQName(propName)); XMPArray array; if (prop != null) { array = prop.getArrayValue(); if (array != null) { for (int i = 0, c = array.getSize(); i < c; i++) { Object value = array.getValue(i); if (value instanceof PropertyAccess) { PropertyAccess pa = (PropertyAccess)value; XMPProperty q = pa.getProperty(qualifier); if (q != null && q.getValue().equals(qualifierValue)) { return pa; } } } } else if (prop.getStructureValue() != null) { PropertyAccess pa = prop.getStructureValue(); XMPProperty q = pa.getProperty(qualifier); if (q != null && q.getValue().equals(qualifierValue)) { return pa; } } } return null; } /** * Finds a value that matches a given qualifier. * @param propName the property name * @param qualifier the qualifier * @param qualifierValue the qualifier value * @return the value if a match was found (or null if no match was found) */ protected Object findQualifiedValue(String propName, QName qualifier, String qualifierValue) { PropertyAccess pa = findQualifiedStructure(propName, qualifier, qualifierValue); if (pa != null) { XMPProperty rdfValue = pa.getValueProperty(); if (rdfValue != null) { return rdfValue.getValue(); } } return null; } /** * Returns an object array representation of the property's values. * @param propName the property name * @return the object array or null if the property isn't set */ protected Object[] getObjectArray(String propName) { XMPProperty prop = meta.getProperty(getQName(propName)); if (prop == null) { return null; } XMPArray array = prop.getArrayValue(); if (array != null) { return array.toObjectArray(); } else { return new Object[] {prop.getValue()}; } } /** * Returns a String array representation of the property's values. Complex values are converted * to Strings using the toString() method. * @param propName the property name * @return the String array or null if the property isn't set */ protected String[] getStringArray(String propName) { Object[] arr = getObjectArray(propName); if (arr == null) { return null; } String[] res = new String[arr.length]; for (int i = 0, c = res.length; i < c; i++) { Object o = arr[i]; if (o instanceof PropertyAccess) { XMPProperty prop = ((PropertyAccess)o).getValueProperty(); res[i] = prop.getValue().toString(); } else { res[i] = o.toString(); } } return res; } /** * Returns a Date array representation of the property's values. * @param propName the property name * @return the Date array or null if the property isn't set */ protected Date[] getDateArray(String propName) { Object[] arr = getObjectArray(propName); if (arr == null) { return null; } Date[] res = new Date[arr.length]; for (int i = 0, c = res.length; i < c; i++) { Object obj = arr[i]; if (obj instanceof Date) { res[i] = (Date) ((Date) obj).clone(); } else { res[i] = DateFormatUtil.parseISO8601Date(obj.toString()); } } return res; } public void setCompact(boolean c) { compact = c; } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/xmp/XMPSchemaRegistry.java0100644 0000000 0000000 00000005262 13777276623 030105 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: XMPSchemaRegistry.java 1685768 2015-06-16 11:46:06Z ssteiner $ */ package org.apache.xmlgraphics.xmp; import java.util.Map; import org.apache.xmlgraphics.xmp.schemas.DublinCoreSchema; import org.apache.xmlgraphics.xmp.schemas.XMPBasicSchema; import org.apache.xmlgraphics.xmp.schemas.pdf.AdobePDFSchema; import org.apache.xmlgraphics.xmp.schemas.pdf.PDFAXMPSchema; import org.apache.xmlgraphics.xmp.schemas.pdf.PDFUAXMPSchema; import org.apache.xmlgraphics.xmp.schemas.pdf.PDFVTXMPSchema; import org.apache.xmlgraphics.xmp.schemas.pdf.PDFXXMPSchema; import org.apache.xmlgraphics.xmp.schemas.pdf.XAPMMXMPSchema; /** * This class is a registry of XMP schemas. It's implemented as a singleton. */ public final class XMPSchemaRegistry { private static XMPSchemaRegistry instance = new XMPSchemaRegistry(); private Map schemas = new java.util.HashMap(); private XMPSchemaRegistry() { init(); } /** @return the singleton instance of the XMP schema registry. */ public static XMPSchemaRegistry getInstance() { return instance; } private void init() { addSchema(new DublinCoreSchema()); addSchema(new PDFAXMPSchema()); addSchema(new XMPBasicSchema()); addSchema(new AdobePDFSchema()); addSchema(new PDFXXMPSchema()); addSchema(new PDFVTXMPSchema()); addSchema(new XAPMMXMPSchema()); addSchema(new PDFUAXMPSchema()); } /** * Adds an XMP schema to the registry. * @param schema the XMP schema */ public void addSchema(XMPSchema schema) { schemas.put(schema.getNamespace(), schema); } /** * Returns the XMP schema object for a given namespace. * @param namespace the namespace URI * @return the XMP schema or null if none is available */ public XMPSchema getSchema(String namespace) { return (XMPSchema)schemas.get(namespace); } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/xmp/XMPSerializer.java0100644 0000000 0000000 00000011232 13777276623 027257 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: XMPSerializer.java 1345683 2012-06-03 14:50:33Z gadams $ */ package org.apache.xmlgraphics.xmp; import java.io.OutputStream; import javax.xml.transform.OutputKeys; import javax.xml.transform.Result; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.sax.SAXTransformerFactory; import javax.xml.transform.sax.TransformerHandler; import javax.xml.transform.stream.StreamResult; import org.xml.sax.SAXException; /** * Serializes an XMP tree to XML or to an XMP packet. */ public final class XMPSerializer { private XMPSerializer() { } private static final String DEFAULT_ENCODING = "UTF-8"; /** * Writes the in-memory representation of the XMP metadata to a JAXP Result. * @param meta the metadata * @param res the JAXP Result to write to * @throws TransformerConfigurationException if an error occurs setting up the XML * infrastructure. * @throws SAXException if a SAX-related problem occurs while writing the XML */ public static void writeXML(Metadata meta, Result res) throws TransformerConfigurationException, SAXException { writeXML(meta, res, false, false); } /** * Writes the in-memory representation of the XMP metadata to an OutputStream as an XMP packet. * @param meta the metadata * @param out the stream to write to * @param readOnlyXMP true if the generated XMP packet should be read-only * @throws TransformerConfigurationException if an error occurs setting up the XML * infrastructure. * @throws SAXException if a SAX-related problem occurs while writing the XML */ public static void writeXMPPacket(Metadata meta, OutputStream out, boolean readOnlyXMP) throws TransformerConfigurationException, SAXException { StreamResult res = new StreamResult(out); writeXML(meta, res, true, readOnlyXMP); } private static void writeXML(Metadata meta, Result res, boolean asXMPPacket, boolean readOnlyXMP) throws TransformerConfigurationException, SAXException { SAXTransformerFactory tFactory = (SAXTransformerFactory)SAXTransformerFactory.newInstance(); TransformerHandler handler = tFactory.newTransformerHandler(); Transformer transformer = handler.getTransformer(); if (asXMPPacket) { transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); } transformer.setOutputProperty(OutputKeys.ENCODING, DEFAULT_ENCODING); try { transformer.setOutputProperty(OutputKeys.INDENT, "yes"); } catch (IllegalArgumentException iae) { //INDENT key is not supported by implementation. That's not tragic, so just ignore. } handler.setResult(res); handler.startDocument(); if (asXMPPacket) { handler.processingInstruction("xpacket", "begin=\"\uFEFF\" id=\"W5M0MpCehiHzreSzNTczkc9d\""); } meta.toSAX(handler); if (asXMPPacket) { if (readOnlyXMP) { handler.processingInstruction("xpacket", "end=\"r\""); } else { //Create padding string (40 * 101 characters is more or less the recommended 4KB) StringBuffer sb = new StringBuffer(101); sb.append('\n'); for (int i = 0; i < 100; i++) { sb.append(" "); } char[] padding = sb.toString().toCharArray(); for (int i = 0; i < 40; i++) { handler.characters(padding, 0, padding.length); } handler.characters(new char[] {'\n'}, 0, 1); handler.processingInstruction("xpacket", "end=\"w\""); } } handler.endDocument(); } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/xmp/XMPStructure.java0100644 0000000 0000000 00000006047 13777276623 027156 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: XMPStructure.java 1804124 2017-08-04 14:13:54Z ssteiner $ */ package org.apache.xmlgraphics.xmp; import java.util.Iterator; import java.util.Map; import org.xml.sax.ContentHandler; import org.xml.sax.SAXException; import org.xml.sax.helpers.AttributesImpl; import org.apache.xmlgraphics.util.QName; /** * Represents an XMP structure as defined by the XMP specification. */ public class XMPStructure extends XMPComplexValue implements PropertyAccess { private Map properties = new java.util.HashMap(); /** * Main constructor */ public XMPStructure() { } /** {@inheritDoc} */ public Object getSimpleValue() { return null; } /** {@inheritDoc} */ public void setProperty(XMPProperty prop) { properties.put(prop.getName(), prop); } /** {@inheritDoc} */ public XMPProperty getProperty(String uri, String localName) { return getProperty(new QName(uri, localName)); } /** {@inheritDoc} */ public XMPProperty getValueProperty() { return getProperty(XMPConstants.RDF_VALUE); } /** {@inheritDoc} */ public XMPProperty getProperty(QName name) { XMPProperty prop = (XMPProperty)properties.get(name); return prop; } /** {@inheritDoc} */ public XMPProperty removeProperty(QName name) { return (XMPProperty)properties.remove(name); } /** {@inheritDoc} */ public int getPropertyCount() { return this.properties.size(); } /** {@inheritDoc} */ public Iterator iterator() { return this.properties.keySet().iterator(); } /** {@inheritDoc} */ public void toSAX(ContentHandler handler) throws SAXException { AttributesImpl atts = new AttributesImpl(); atts.clear(); handler.startElement(XMPConstants.RDF_NAMESPACE, "RDF", "rdf:Description", atts); for (Object o : properties.values()) { XMPProperty prop = (XMPProperty) o; //if (prop.getName().getNamespaceURI().equals(ns)) { prop.toSAX(handler); //} } handler.endElement(XMPConstants.RDF_NAMESPACE, "RDF", "rdf:Description"); } /** {@inheritDoc} */ public String toString() { return "XMP structure: " + getPropertyCount(); } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/xmp/merge/ArrayAddPropertyMerger.java0100644 0000000 0000000 00000004515 13777276623 032264 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ArrayAddPropertyMerger.java 892977 2009-12-21 21:08:42Z jeremias $ */ package org.apache.xmlgraphics.xmp.merge; import org.apache.xmlgraphics.xmp.Metadata; import org.apache.xmlgraphics.xmp.XMPArray; import org.apache.xmlgraphics.xmp.XMPArrayType; import org.apache.xmlgraphics.xmp.XMPProperty; /** * Merges properties by adding up all items from both ends into one SEQ array. */ public class ArrayAddPropertyMerger implements PropertyMerger { /** * @see org.apache.xmlgraphics.xmp.merge.PropertyMerger#merge( * org.apache.xmlgraphics.xmp.XMPProperty, org.apache.xmlgraphics.xmp.Metadata) */ public void merge(XMPProperty sourceProp, Metadata target) { XMPProperty existing = target.getProperty(sourceProp.getName()); if (existing == null) { //simply copy over target.setProperty(sourceProp); } else { XMPArray array = existing.convertSimpleValueToArray(XMPArrayType.SEQ); XMPArray otherArray = sourceProp.getArrayValue(); if (otherArray == null) { if (sourceProp.getXMLLang() != null) { array.add(sourceProp.getValue().toString(), sourceProp.getXMLLang()); } else { array.add(sourceProp.getValue()); } } else { //TODO should be refined (xml:lang etc.) for (int i = 0, c = otherArray.getSize(); i < c; i++) { array.add(otherArray.getValue(i)); } } } } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/xmp/merge/MergeRuleSet.java0100644 0000000 0000000 00000004125 13777276623 030226 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: MergeRuleSet.java 750418 2009-03-05 11:03:54Z vhennebert $ */ package org.apache.xmlgraphics.xmp.merge; import java.util.Map; import org.apache.xmlgraphics.util.QName; import org.apache.xmlgraphics.xmp.XMPProperty; /** * Represents a set of rules used to merge to XMP properties. By default, all properties are * merged by replacing any existing values with the value from the source XMP. */ public class MergeRuleSet { private Map rules = new java.util.HashMap(); private PropertyMerger defaultMerger = new ReplacePropertyMerger(); /** Main constructor. */ public MergeRuleSet() { } /** * Returns the PropertyMerger that shall be used when merging the given property. * @param prop the property to be merged * @return the PropertyMerger to be used for merging the property */ public PropertyMerger getPropertyMergerFor(XMPProperty prop) { PropertyMerger merger = (PropertyMerger)rules.get(prop.getName()); return (merger != null ? merger : defaultMerger); } /** * Adds a merge rule to this set. * @param propName the name of the property * @param merger the property merger to be used for this property */ public void addRule(QName propName, PropertyMerger merger) { rules.put(propName, merger); } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/xmp/merge/NoReplacePropertyMerger.java0100644 0000000 0000000 00000003110 13777276623 032433 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: NoReplacePropertyMerger.java 426584 2006-07-28 16:01:47Z jeremias $ */ package org.apache.xmlgraphics.xmp.merge; import org.apache.xmlgraphics.xmp.Metadata; import org.apache.xmlgraphics.xmp.XMPProperty; /** * A basic PropertyMerger which only sets a value in the target metadata if there's not already * another value. */ public class NoReplacePropertyMerger implements PropertyMerger { /** * @see org.apache.xmlgraphics.xmp.merge.PropertyMerger#merge( * org.apache.xmlgraphics.xmp.XMPProperty, org.apache.xmlgraphics.xmp.Metadata) */ public void merge(XMPProperty sourceProp, Metadata target) { XMPProperty prop = target.getProperty(sourceProp.getName()); if (prop == null) { target.setProperty(sourceProp); } } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/xmp/merge/PropertyMerger.java0100644 0000000 0000000 00000002537 13777276623 030656 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: PropertyMerger.java 750418 2009-03-05 11:03:54Z vhennebert $ */ package org.apache.xmlgraphics.xmp.merge; import org.apache.xmlgraphics.xmp.Metadata; import org.apache.xmlgraphics.xmp.XMPProperty; /** * Defines an interface the classes can implement to provide special property merging behaviour. */ public interface PropertyMerger { /** * Merges a property into a given metadata object * @param sourceProp the source property * @param target the target metadata object */ void merge(XMPProperty sourceProp, Metadata target); } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/xmp/merge/ReplacePropertyMerger.java0100644 0000000 0000000 00000002707 13777276623 032151 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ReplacePropertyMerger.java 426584 2006-07-28 16:01:47Z jeremias $ */ package org.apache.xmlgraphics.xmp.merge; import org.apache.xmlgraphics.xmp.Metadata; import org.apache.xmlgraphics.xmp.XMPProperty; /** * The most basic PropertyMerger which simply overwrites any existing value in the target metadata. */ public class ReplacePropertyMerger implements PropertyMerger { /** * @see org.apache.xmlgraphics.xmp.merge.PropertyMerger#merge( * org.apache.xmlgraphics.xmp.XMPProperty, org.apache.xmlgraphics.xmp.Metadata) */ public void merge(XMPProperty sourceProp, Metadata target) { target.setProperty(sourceProp); } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/xmp/merge/package.html0100644 0000000 0000000 00000001667 13777276623 027311 0ustar000000000 0000000 org.apache.xmlgraphics.commons.xmp.merge Package

    Classes for merging two XMP metadata documents.

    xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/xmp/package.html0100644 0000000 0000000 00000002062 13777276623 026200 0ustar000000000 0000000 org.apache.xmlgraphics.commons.xmp Package

    This package is an XMP metadata framework. For more information on Adobe's XMP standard, visit: Adobe's XMP website

    xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/xmp/schemas/DublinCoreAdapter.java0100644 0000000 0000000 00000027303 13777276623 031541 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: DublinCoreAdapter.java 1804124 2017-08-04 14:13:54Z ssteiner $ */ package org.apache.xmlgraphics.xmp.schemas; import java.util.Date; import org.apache.xmlgraphics.xmp.Metadata; import org.apache.xmlgraphics.xmp.XMPSchemaAdapter; import org.apache.xmlgraphics.xmp.XMPSchemaRegistry; /** * Schema adapter implementation for the Dublin Core schema. *

    * Note: In Adobe's XMP specification dc:subject is defined as "bag Text", but in PDF/A-1 it is * defined as "Text". Here it is implemented as "bag Text". */ public class DublinCoreAdapter extends XMPSchemaAdapter { private static final String CONTRIBUTOR = "contributor"; private static final String COVERAGE = "coverage"; private static final String CREATOR = "creator"; private static final String DATE = "date"; private static final String DESCRIPTION = "description"; private static final String FORMAT = "format"; private static final String IDENTIFIER = "identifier"; private static final String LANGUAGE = "language"; private static final String PUBLISHER = "publisher"; private static final String RELATION = "relation"; private static final String RIGHTS = "rights"; private static final String SOURCE = "source"; private static final String SUBJECT = "subject"; private static final String TITLE = "title"; private static final String TYPE = "type"; /** * Constructs a new adapter for Dublin Core around the given metadata object. * @param meta the underlying metadata */ public DublinCoreAdapter(Metadata meta) { super(meta, XMPSchemaRegistry.getInstance().getSchema(DublinCoreSchema.NAMESPACE)); } /** * Adds a new entry to the list of contributors (other than the authors). * @param value the new value */ public void addContributor(String value) { addStringToBag(CONTRIBUTOR, value); } /** * Removes an entry from the list of contributors. * @param value the value to be removed * @return the removed entry */ public boolean removeContributor(String value) { return removeStringFromArray(CONTRIBUTOR, value); } /** * Returns an array of all contributors. * @return a String array of all contributors (or null if not set) */ public String[] getContributors() { return getStringArray(CONTRIBUTOR); } /** * Sets the extent or scope of the resource. * @param value the new value. */ public void setCoverage(String value) { setValue(COVERAGE, value); } /** * Returns the extent or scope of the resource. * @return the property value (or null if not set) */ public String getCoverage() { return getValue(COVERAGE); } /** * Adds a new entry to the list of creators (authors of the resource). * @param value the new value */ public void addCreator(String value) { addStringToSeq(CREATOR, value); } /** * Removes an entry from the list of creators (authors of the resource). * @param value the value to be removed * @return the removed entry */ public boolean removeCreator(String value) { return removeStringFromArray(CREATOR, value); } /** * Returns an array of all creators. * @return a String array of all creators (or null if not set) */ public String[] getCreators() { return getStringArray(CREATOR); } /** * Adds a new entry to the list of dates indicating points in time something interesting * happened to the resource. * @param value the date value */ public void addDate(Date value) { addDateToSeq(DATE, value); } /** * Returns a list of dates indicating point in time something interesting happened to the * resource. * @return the list of dates or null if no dates are set */ public Date[] getDates() { return getDateArray(DATE); } /** * Returns a latest date indicating point in time something interesting happened to the * resource. * @return the last date or null */ public Date getDate() { Date[] dates = getDates(); if (dates != null) { Date latest = null; for (Date date : dates) { if (latest == null || date.getTime() > latest.getTime()) { latest = date; } } return latest; } else { return null; } } /** * Sets the description of the content of the resource. * @param lang the language of the value ("x-default" or null for the default language) * @param value the new value */ public void setDescription(String lang, String value) { setLangAlt(DESCRIPTION, lang, value); } /** * Returns the description of the content of the resource (in the default language). * @return the description of the content of the resource (or null if not set) */ public String getDescription() { return getDescription(null); } /** * Returns the description of the content of the resource in a language-dependant way. * @param lang the language ("x-default" or null for the default language) * @return the language-dependent value (or null if not set) */ public String getDescription(String lang) { return getLangAlt(lang, DESCRIPTION); } /** * Sets the file format used when saving the resource. Tools and * applications should set this property to the save format of the * data. It may include appropriate qualifiers. * @param value a MIME type */ public void setFormat(String value) { setValue(FORMAT, value); } /** * Returns the file format used when saving this resource. * @return the MIME type of the file format (or null if not set) */ public String getFormat() { return getValue(FORMAT); } /** * Sets the unique identifier of the resource. * @param value the new value */ public void setIdentifier(String value) { setValue(IDENTIFIER, value); } /** * Returns the unique identifier of the resource. * @return the unique identifier (or null if not set) */ public String getIdentifier() { return getValue(IDENTIFIER); } /** * Adds a new entry to the list of languages (RFC 3066). * @param value the new value */ public void addLanguage(String value) { addStringToBag(LANGUAGE, value); } /** * Returns an array of languages. * @return a String array of all languages (or null if not set) */ public String[] getLanguages() { return getStringArray(LANGUAGE); } /** * Adds a new entry to the list of publishers. * @param value the new value */ public void addPublisher(String value) { addStringToBag(PUBLISHER, value); } /** * Returns an array of publishers. * @return a String array of all publishers (or null if not set) */ public String[] getPublisher() { return getStringArray(PUBLISHER); } /** * Adds a new entry to the list of relationships to other documents. * @param value the new value */ public void addRelation(String value) { addStringToBag(RELATION, value); } /** * Returns an array of all relationship to other documents. * @return a String array of all relationships (or null if none are set) */ public String[] getRelations() { return getStringArray(RELATION); } /** * Sets the informal rights statement. * @param lang the language of the value ("x-default" or null for the default language) * @param value the new value */ public void setRights(String lang, String value) { setLangAlt(RIGHTS, lang, value); } /** * Returns the informal rights statement. * @return the informal right statement (or null if not set) */ public String getRights() { return getRights(null); } /** * Returns the informal rights statement in a language-dependant way. * @param lang the language ("x-default" or null for the default language) * @return the language-dependent value (or null if not set) */ public String getRights(String lang) { return getLangAlt(lang, RIGHTS); } /** * Sets the unique identifier of the work from which this resource was derived. * @param value the new value */ public void setSource(String value) { setValue(SOURCE, value); } /** * Returns unique identifier of the work from which this resource was derived. * @return the source (or null if not set) */ public String getSource() { return getValue(SOURCE); } /** * Adds a new entry to the list of subjects (descriptive phrases or keywords that * specify the topic of the content of the resource). * @param value the new value */ public void addSubject(String value) { addStringToBag(SUBJECT, value); } /** * Returns an array of all subjects. * @return a String array of all subjects */ public String[] getSubjects() { return getStringArray(SUBJECT); } /** * Sets the title of the resource (in the default language). * @param value the new value */ public void setTitle(String value) { setTitle(null, value); } /** * Sets the title of the resource. * @param lang the language of the value ("x-default" or null for the default language) * @param value the new value */ public void setTitle(String lang, String value) { setLangAlt(TITLE, lang, value); } /** * Returns the title of the resource (in the default language). * @return the title of the resource (in the default language) */ public String getTitle() { return getTitle(null); } /** * Returns the title of the resource in a language-dependant way. * @param lang the language ("x-default" or null for the default language) * @return the language-dependent value (or null if not set) */ public String getTitle(String lang) { return getLangAlt(lang, TITLE); } /** * Removes a title of the resource. * @param lang the language variant to be removed * @return the previously set value or null if this language variant wasn't set */ public String removeTitle(String lang) { return removeLangAlt(lang, TITLE); } /** * Adds a new entry to the list of document types (for example: novel, poem or working paper). * @param value the new value */ public void addType(String value) { addStringToBag(TYPE, value); } /** * Returns an array of all document types. * @return a String array of all document types (or null if not set) */ public String[] getTypes() { return getStringArray(TYPE); } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/xmp/schemas/DublinCoreSchema.java0100644 0000000 0000000 00000004355 13777276623 031363 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: DublinCoreSchema.java 750418 2009-03-05 11:03:54Z vhennebert $ */ package org.apache.xmlgraphics.xmp.schemas; import org.apache.xmlgraphics.util.QName; import org.apache.xmlgraphics.xmp.Metadata; import org.apache.xmlgraphics.xmp.XMPConstants; import org.apache.xmlgraphics.xmp.XMPSchema; import org.apache.xmlgraphics.xmp.merge.ArrayAddPropertyMerger; import org.apache.xmlgraphics.xmp.merge.MergeRuleSet; /** * Schema class for Dublin Core. */ public class DublinCoreSchema extends XMPSchema { /** Namespace URI for Dublin Core */ public static final String NAMESPACE = XMPConstants.DUBLIN_CORE_NAMESPACE; private static MergeRuleSet dcMergeRuleSet; static { dcMergeRuleSet = new MergeRuleSet(); //Dates are added up not replaced dcMergeRuleSet.addRule(new QName(NAMESPACE, "date"), new ArrayAddPropertyMerger()); } /** Creates a new schema instance for Dublin Core. */ public DublinCoreSchema() { super(NAMESPACE, "dc"); } /** * Creates and returns an adapter for this schema around the given metadata object. * @param meta the metadata object * @return the newly instantiated adapter */ public static DublinCoreAdapter getAdapter(Metadata meta) { return new DublinCoreAdapter(meta); } /** @see org.apache.xmlgraphics.xmp.XMPSchema#getDefaultMergeRuleSet() */ public MergeRuleSet getDefaultMergeRuleSet() { return dcMergeRuleSet; } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/xmp/schemas/XMPBasicAdapter.java0100644 0000000 0000000 00000014111 13777276623 031112 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: XMPBasicAdapter.java 893190 2009-12-22 14:41:02Z jeremias $ */ package org.apache.xmlgraphics.xmp.schemas; import java.util.Date; import org.apache.xmlgraphics.xmp.Metadata; import org.apache.xmlgraphics.xmp.PropertyAccess; import org.apache.xmlgraphics.xmp.XMPArrayType; import org.apache.xmlgraphics.xmp.XMPConstants; import org.apache.xmlgraphics.xmp.XMPProperty; import org.apache.xmlgraphics.xmp.XMPSchemaAdapter; import org.apache.xmlgraphics.xmp.XMPSchemaRegistry; import org.apache.xmlgraphics.xmp.XMPStructure; /** * Schema adapter implementation for the XMP Basic schema. */ public class XMPBasicAdapter extends XMPSchemaAdapter { private static final String ADVISORY = "Advisory"; private static final String BASE_URL = "BaseURL"; private static final String CREATE_DATE = "CreateDate"; private static final String CREATOR_TOOL = "CreatorTool"; private static final String IDENTIFIER = "Identifier"; private static final String LABEL = "Label"; private static final String METADATA_DATE = "MetadataDate"; private static final String MODIFY_DATE = "ModifyDate"; private static final String NICKNAME = "Nickname"; private static final String RATING = "Rating"; private static final String THUMBNAILS = "Thumbnails"; /** * Constructs a new adapter for XMP Basic around the given metadata object. * @param meta the underlying metadata */ public XMPBasicAdapter(Metadata meta, String namespace) { super(meta, XMPSchemaRegistry.getInstance().getSchema(namespace)); } /** * Sets the base URL for relative URLs in the document content. * @param value the base URL */ public void setBaseUrl(String value) { setValue(BASE_URL, value); } /** * Returns the base URL for relative URLs in the document content. * @return the base URL */ public String getBaseUrl() { return getValue(BASE_URL); } /** * Sets the date and time the resource was originally created. * @param creationDate the creation date */ public void setCreateDate(Date creationDate) { setDateValue(CREATE_DATE, creationDate); } /** @return the date and time the resource was originally created */ public Date getCreateDate() { return getDateValue(CREATE_DATE); } /** * Sets the first known tool used to create the resource. * @param value the creator tool */ public void setCreatorTool(String value) { setValue(CREATOR_TOOL, value); } /** @return the first known tool used to create the resource */ public String getCreatorTool() { return getValue(CREATOR_TOOL); } /** * Adds an identifier that unambiguously identify the resource within a given context. * @param value the identifier value */ public void addIdentifier(String value) { addStringToBag(IDENTIFIER, value); } /** * Sets a qualified identifier that unambiguously identify the resource within a given context. * As qualifier, xmpidq:Scheme is used. * @param value the identifier value * @param qualifier the qualifier value (for xmpidq:Scheme) */ public void setIdentifier(String value, String qualifier) { PropertyAccess pa = findQualifiedStructure(IDENTIFIER, XMPBasicSchema.SCHEME_QUALIFIER, qualifier); if (pa != null) { pa.setProperty(new XMPProperty(XMPConstants.RDF_VALUE, value)); } else { XMPStructure struct = new XMPStructure(); struct.setProperty(new XMPProperty(XMPConstants.RDF_VALUE, value)); struct.setProperty(new XMPProperty(XMPBasicSchema.SCHEME_QUALIFIER, qualifier)); addObjectToArray(IDENTIFIER, struct, XMPArrayType.BAG); } } /** * Returns an array of all identifiers that unambiguously identify the resource within a * given context. * @return a String array of all identifiers (or null if not set) */ public String[] getIdentifiers() { return getStringArray(IDENTIFIER); } /** * Returns an identifier that matches a given qualifier. * As qualifier, xmpidq:Scheme is used. * @param qualifier the qualifier * @return the identifier (or null if no matching value was found) */ public String getIdentifier(String qualifier) { Object value = findQualifiedValue(IDENTIFIER, XMPBasicSchema.SCHEME_QUALIFIER, qualifier); return (value != null ? value.toString() : null); } /** * Sets the date and time the resource was last modified. * @param modifyDate the modification date */ public void setModifyDate(Date modifyDate) { setDateValue(MODIFY_DATE, modifyDate); } /** @return the date and time the resource was last modified */ public Date getModifyDate() { return getDateValue(MODIFY_DATE); } /** * Sets the date and time any metadata for this resource was last changed. * @param metadataDate the modification date for the metadata */ public void setMetadataDate(Date metadataDate) { setDateValue(METADATA_DATE, metadataDate); } /** @return the date and time the resource was originally created */ public Date getMetadataDate() { return getDateValue(METADATA_DATE); } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/xmp/schemas/XMPBasicSchema.java0100644 0000000 0000000 00000005223 13777276623 030736 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: XMPBasicSchema.java 892977 2009-12-21 21:08:42Z jeremias $ */ package org.apache.xmlgraphics.xmp.schemas; import org.apache.xmlgraphics.util.QName; import org.apache.xmlgraphics.xmp.Metadata; import org.apache.xmlgraphics.xmp.XMPConstants; import org.apache.xmlgraphics.xmp.XMPSchema; import org.apache.xmlgraphics.xmp.merge.MergeRuleSet; import org.apache.xmlgraphics.xmp.merge.NoReplacePropertyMerger; /** * XMP schema for XMP Basic. */ public class XMPBasicSchema extends XMPSchema { /** Namespace URI for XMP Basic */ public static final String NAMESPACE = XMPConstants.XMP_BASIC_NAMESPACE; /** Preferred prefix for XMP Basic */ public static final String PREFERRED_PREFIX = "xmp"; /** Namespace URI for the qualifier for xmp:Identifier */ public static final String QUALIFIER_NAMESPACE = "http://ns.adobe.com/xmp/Identifier/qual/1.0/"; /** The qualified name for the qualifier for xmp:Identifier */ public static final QName SCHEME_QUALIFIER = new QName(QUALIFIER_NAMESPACE, "xmpidq:Scheme"); private static MergeRuleSet mergeRuleSet = new MergeRuleSet(); /** Creates a new schema instance for Dublin Core. */ public XMPBasicSchema() { super(NAMESPACE, PREFERRED_PREFIX); } static { //CreateDate shall be preserved if it exists mergeRuleSet.addRule(new QName(NAMESPACE, "CreateDate"), new NoReplacePropertyMerger()); } /** * Creates and returns an adapter for this schema around the given metadata object. * @param meta the metadata object * @return the newly instantiated adapter */ public static XMPBasicAdapter getAdapter(Metadata meta) { return new XMPBasicAdapter(meta, NAMESPACE); } /** @see org.apache.xmlgraphics.xmp.XMPSchema#getDefaultMergeRuleSet() */ public MergeRuleSet getDefaultMergeRuleSet() { return mergeRuleSet; } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/xmp/schemas/package.html0100644 0000000 0000000 00000002207 13777276623 027624 0ustar000000000 0000000 org.apache.xmlgraphics.commons.xmp.schemas Package

    Schema and schema adapter classes for accessing XMP metadata. The schema classes provide information about a particular XMP schema. The adapter classes are wrappers around a Metadata object and provide easy Java read and write access to XMP metadata.

    xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/xmp/schemas/pdf/AdobePDFAdapter.java0100644 0000000 0000000 00000005360 13777276623 031627 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: AdobePDFAdapter.java 1666114 2015-03-12 10:00:27Z ssteiner $ */ package org.apache.xmlgraphics.xmp.schemas.pdf; import org.apache.xmlgraphics.xmp.Metadata; import org.apache.xmlgraphics.xmp.XMPSchemaAdapter; import org.apache.xmlgraphics.xmp.XMPSchemaRegistry; /** * Schema adapter implementation for the Adobe PDF schema. */ public class AdobePDFAdapter extends XMPSchemaAdapter { private static final String KEYWORDS = "Keywords"; private static final String PDFVERSION = "PDFVersion"; private static final String PRODUCER = "Producer"; private static final String TRAPPED = "Trapped"; /** * Constructs a new adapter for Adobe PDF around the given metadata object. * @param meta the underlying metadata */ public AdobePDFAdapter(Metadata meta, String namespace) { super(meta, XMPSchemaRegistry.getInstance().getSchema(namespace)); } /** @return the keywords */ public String getKeywords() { return getValue(KEYWORDS); } /** * Sets the keywords. * @param value the keywords */ public void setKeywords(String value) { setValue(KEYWORDS, value); } /** @return the PDF version */ public String getPDFVersion() { return getValue(PDFVERSION); } /** * Sets the PDF version * @param value the PDF version (ex. "1.4") */ public void setPDFVersion(String value) { setValue(PDFVERSION, value); } /** @return the name of the tool that produced the PDF document */ public String getProducer() { return getValue(PRODUCER); } /** * Sets the name of the tool that produced the PDF document * @param value the producer */ public void setProducer(String value) { setValue(PRODUCER, value); } /** * Sets if the pdf has trapping information True or False * @param v the value */ public void setTrapped(String v) { setValue(TRAPPED, v); } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/xmp/schemas/pdf/AdobePDFSchema.java0100644 0000000 0000000 00000003726 13777276623 031453 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: AdobePDFSchema.java 750418 2009-03-05 11:03:54Z vhennebert $ */ package org.apache.xmlgraphics.xmp.schemas.pdf; import org.apache.xmlgraphics.xmp.Metadata; import org.apache.xmlgraphics.xmp.XMPConstants; import org.apache.xmlgraphics.xmp.XMPSchema; import org.apache.xmlgraphics.xmp.merge.MergeRuleSet; /** * Adobe PDF XMP schema. */ public class AdobePDFSchema extends XMPSchema { /** Namespace URI for the Adobe PDF XMP schema */ public static final String NAMESPACE = XMPConstants.ADOBE_PDF_NAMESPACE; private static MergeRuleSet mergeRuleSet = new MergeRuleSet(); /** Creates a new schema instance for Dublin Core. */ public AdobePDFSchema() { super(NAMESPACE, "pdf"); } /** * Creates and returns an adapter for this schema around the given metadata object. * @param meta the metadata object * @return the newly instantiated adapter */ public static AdobePDFAdapter getAdapter(Metadata meta) { return new AdobePDFAdapter(meta, NAMESPACE); } /** @see org.apache.xmlgraphics.xmp.XMPSchema#getDefaultMergeRuleSet() */ public MergeRuleSet getDefaultMergeRuleSet() { return mergeRuleSet; } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/xmp/schemas/pdf/PDFAAdapter.java0100644 0000000 0000000 00000005463 13777276623 031001 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: PDFAAdapter.java 750418 2009-03-05 11:03:54Z vhennebert $ */ package org.apache.xmlgraphics.xmp.schemas.pdf; import org.apache.xmlgraphics.xmp.Metadata; import org.apache.xmlgraphics.xmp.XMPSchemaAdapter; import org.apache.xmlgraphics.xmp.XMPSchemaRegistry; /** * Schema adapter implementation for both the old (deprecated) and the current PDF/A schema. * The old namespace is still needed to make Adobe Acrobat happy. */ public class PDFAAdapter extends XMPSchemaAdapter { private static final String PART = "part"; private static final String AMD = "amd"; private static final String CONFORMANCE = "conformance"; /** * Constructs a new adapter for PDF/A around the given metadata object. * @param meta the underlying metadata * @param namespace the namespace to access the schema (must be one of the PDF/A schema * namespaces) */ public PDFAAdapter(Metadata meta, String namespace) { super(meta, XMPSchemaRegistry.getInstance().getSchema(namespace)); } /** * Sets the PDF/A version identifier ("part"). * @param value the version identifier ("1" for PDF/A-1) */ public void setPart(int value) { setValue(PART, Integer.toString(value)); } /** @return the PDF/A version identifier */ public int getPart() { return Integer.parseInt(getValue(PART)); } /** * Sets the PDF/A amendment identifier ("amd"). * @param value the amendment identifiert */ public void setAmendment(String value) { setValue(AMD, value); } /** @return the PDF/A amendment identifier */ public String getAmendment() { return getValue(AMD); } /** * Sets the PDF/A conformance level. * @param value the conformance level ("A" or "B" for PDF/A-1) */ public void setConformance(String value) { setValue(CONFORMANCE, value); } /** @return the PDF/A conformance level */ public String getConformance() { return getValue(CONFORMANCE); } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/xmp/schemas/pdf/PDFAXMPSchema.java0100644 0000000 0000000 00000003720 13777276623 031200 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: PDFAXMPSchema.java 750418 2009-03-05 11:03:54Z vhennebert $ */ package org.apache.xmlgraphics.xmp.schemas.pdf; import org.apache.xmlgraphics.xmp.Metadata; import org.apache.xmlgraphics.xmp.XMPConstants; import org.apache.xmlgraphics.xmp.XMPSchema; import org.apache.xmlgraphics.xmp.merge.MergeRuleSet; /** * XMP Schema for PDF/A (ISO 19005-1). */ public class PDFAXMPSchema extends XMPSchema { /** Namespace URI for Dublin Core */ public static final String NAMESPACE = XMPConstants.PDF_A_IDENTIFICATION; private static MergeRuleSet mergeRuleSet = new MergeRuleSet(); /** Creates a new schema instance for Dublin Core. */ public PDFAXMPSchema() { super(NAMESPACE, "pdfaid"); } /** * Creates and returns an adapter for this schema around the given metadata object. * @param meta the metadata object * @return the newly instantiated adapter */ public static PDFAAdapter getAdapter(Metadata meta) { return new PDFAAdapter(meta, NAMESPACE); } /** @see org.apache.xmlgraphics.xmp.XMPSchema#getDefaultMergeRuleSet() */ public MergeRuleSet getDefaultMergeRuleSet() { return mergeRuleSet; } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/xmp/schemas/pdf/PDFUAAdapter.java0100644 0000000 0000000 00000003605 13777276623 031122 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: PDFUAAdapter.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.xmp.schemas.pdf; import org.apache.xmlgraphics.xmp.Metadata; import org.apache.xmlgraphics.xmp.XMPSchemaAdapter; import org.apache.xmlgraphics.xmp.XMPSchemaRegistry; /** * Schema adapter implementation for both the old (deprecated) and the current PDF/UA schema. * The old namespace is still needed to make Adobe Acrobat happy. */ public class PDFUAAdapter extends XMPSchemaAdapter { private static final String PART = "part"; /** * Constructs a new adapter for PDF/UA around the given metadata object. * @param meta the underlying metadata * @param namespace the namespace to access the schema (must be one of the PDF/UA schema * namespaces) */ public PDFUAAdapter(Metadata meta, String namespace) { super(meta, XMPSchemaRegistry.getInstance().getSchema(namespace)); } public void setPart(int value) { setValue(PART, Integer.toString(value)); } public int getPart() { return Integer.parseInt(getValue(PART)); } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/xmp/schemas/pdf/PDFUAXMPSchema.java0100644 0000000 0000000 00000003706 13777276623 031331 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: PDFUAXMPSchema.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.xmp.schemas.pdf; import org.apache.xmlgraphics.xmp.Metadata; import org.apache.xmlgraphics.xmp.XMPConstants; import org.apache.xmlgraphics.xmp.XMPSchema; import org.apache.xmlgraphics.xmp.merge.MergeRuleSet; /** * XMP Schema for PDF/UA */ public class PDFUAXMPSchema extends XMPSchema { /** Namespace URI for Dublin Core */ public static final String NAMESPACE = XMPConstants.PDF_UA_IDENTIFICATION; private static MergeRuleSet mergeRuleSet = new MergeRuleSet(); /** Creates a new schema instance for Dublin Core. */ public PDFUAXMPSchema() { super(NAMESPACE, "pdfuaid"); } /** * Creates and returns an adapter for this schema around the given metadata object. * @param meta the metadata object * @return the newly instantiated adapter */ public static PDFUAAdapter getAdapter(Metadata meta) { return new PDFUAAdapter(meta, NAMESPACE); } /** @see org.apache.xmlgraphics.xmp.XMPSchema#getDefaultMergeRuleSet() */ public MergeRuleSet getDefaultMergeRuleSet() { return mergeRuleSet; } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/xmp/schemas/pdf/PDFVTAdapter.java0100644 0000000 0000000 00000003327 13777276623 031147 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: PDFVTAdapter.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.xmp.schemas.pdf; import java.util.Date; import org.apache.xmlgraphics.xmp.Metadata; import org.apache.xmlgraphics.xmp.XMPSchemaAdapter; import org.apache.xmlgraphics.xmp.XMPSchemaRegistry; public class PDFVTAdapter extends XMPSchemaAdapter { /** * Constructs a new adapter for PDF/VT around the given metadata object. * @param meta the underlying metadata * @param namespace the namespace to access the schema (must be one of the PDF/VT schema * namespaces) */ public PDFVTAdapter(Metadata meta, String namespace) { super(meta, XMPSchemaRegistry.getInstance().getSchema(namespace)); } public void setVersion(String v) { setValue("GTS_PDFVTVersion", v); } public void setModifyDate(Date modifyDate) { setDateValue("GTS_PDFVTModDate", modifyDate); } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/xmp/schemas/pdf/PDFVTXMPSchema.java0100644 0000000 0000000 00000003132 13777276623 031346 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: PDFVTXMPSchema.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.xmp.schemas.pdf; import org.apache.xmlgraphics.xmp.Metadata; import org.apache.xmlgraphics.xmp.XMPConstants; import org.apache.xmlgraphics.xmp.XMPSchema; public class PDFVTXMPSchema extends XMPSchema { public static final String NAMESPACE = XMPConstants.PDF_VT_IDENTIFICATION; /** Creates a new schema instance for Dublin Core. */ public PDFVTXMPSchema() { super(NAMESPACE, "pdfvtid"); } /** * Creates and returns an adapter for this schema around the given metadata object. * @param meta the metadata object * @return the newly instantiated adapter */ public static PDFVTAdapter getAdapter(Metadata meta) { return new PDFVTAdapter(meta, NAMESPACE); } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/xmp/schemas/pdf/PDFXAdapter.java0100644 0000000 0000000 00000003113 13777276623 031016 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: PDFXAdapter.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.xmp.schemas.pdf; import org.apache.xmlgraphics.xmp.Metadata; import org.apache.xmlgraphics.xmp.XMPSchemaAdapter; import org.apache.xmlgraphics.xmp.XMPSchemaRegistry; public class PDFXAdapter extends XMPSchemaAdapter { /** * Constructs a new adapter for PDF/X around the given metadata object. * @param meta the underlying metadata * @param namespace the namespace to access the schema (must be one of the PDF/X schema * namespaces) */ public PDFXAdapter(Metadata meta, String namespace) { super(meta, XMPSchemaRegistry.getInstance().getSchema(namespace)); } public void setVersion(String v) { setValue("GTS_PDFXVersion", v); } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/xmp/schemas/pdf/PDFXXMPSchema.java0100644 0000000 0000000 00000003124 13777276623 031225 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: PDFXXMPSchema.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.xmp.schemas.pdf; import org.apache.xmlgraphics.xmp.Metadata; import org.apache.xmlgraphics.xmp.XMPConstants; import org.apache.xmlgraphics.xmp.XMPSchema; public class PDFXXMPSchema extends XMPSchema { public static final String NAMESPACE = XMPConstants.PDF_X_IDENTIFICATION; /** Creates a new schema instance for Dublin Core. */ public PDFXXMPSchema() { super(NAMESPACE, "pdfxid"); } /** * Creates and returns an adapter for this schema around the given metadata object. * @param meta the metadata object * @return the newly instantiated adapter */ public static PDFXAdapter getAdapter(Metadata meta) { return new PDFXAdapter(meta, NAMESPACE); } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/xmp/schemas/pdf/XAPMMAdapter.java0100644 0000000 0000000 00000003653 13777276623 031150 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: XAPMMAdapter.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.xmp.schemas.pdf; import org.apache.xmlgraphics.xmp.Metadata; import org.apache.xmlgraphics.xmp.XMPSchemaAdapter; import org.apache.xmlgraphics.xmp.XMPSchemaRegistry; public class XAPMMAdapter extends XMPSchemaAdapter { /** * Constructs a new adapter for XAP MM around the given metadata object. * @param meta the underlying metadata * @param namespace the namespace to access the schema (must be one of the PDF/VT schema * namespaces) */ public XAPMMAdapter(Metadata meta, String namespace) { super(meta, XMPSchemaRegistry.getInstance().getSchema(namespace)); } public void setVersion(String v) { setValue("VersionID", v); } /** * The rendition class name for this resource. * @param c the value */ public void setRenditionClass(String c) { setValue("RenditionClass", c); } public void setInstanceID(String v) { setValue("InstanceID", v); } public void setDocumentID(String v) { setValue("DocumentID", v); } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/xmp/schemas/pdf/XAPMMXMPSchema.java0100644 0000000 0000000 00000003132 13777276623 031345 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: XAPMMXMPSchema.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.xmp.schemas.pdf; import org.apache.xmlgraphics.xmp.Metadata; import org.apache.xmlgraphics.xmp.XMPConstants; import org.apache.xmlgraphics.xmp.XMPSchema; public class XAPMMXMPSchema extends XMPSchema { public static final String NAMESPACE = XMPConstants.XAP_MM_NAMESPACE; /** Creates a new schema instance for Dublin Core. */ public XAPMMXMPSchema() { super(NAMESPACE, "xmpMM"); } /** * Creates and returns an adapter for this schema around the given metadata object. * * @param meta the metadata object * @return the newly instantiated adapter */ public static XAPMMAdapter getAdapter(Metadata meta) { return new XAPMMAdapter(meta, NAMESPACE); } } xmlgraphics-commons-2.6/src/main/java/org/apache/xmlgraphics/xmp/schemas/pdf/package.html0100644 0000000 0000000 00000001702 13777276623 030374 0ustar000000000 0000000 org.apache.xmlgraphics.commons.xmp.schemas.pdf Package

    PDF-specific XMP schemas and schema adapter classes.

    xmlgraphics-commons-2.6/src/main/resources/META-INF/services/javax.xml.transform.URIResolver0100644 0000000 0000000 00000000060 13777276623 030657 0ustar000000000 0000000 org.apache.xmlgraphics.util.uri.DataURIResolver ././@LongLink0100644 0000000 0000000 00000000164 13777276623 011660 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/resources/META-INF/services/org.apache.xmlgraphics.image.loader.spi.ImageConverterxmlgraphics-commons-2.6/src/main/resources/META-INF/services/org.apache.xmlgraphics.image.loader.spi0100644 0000000 0000000 00000000421 13777276623 032225 0ustar000000000 0000000 org.apache.xmlgraphics.image.loader.impl.ImageConverterBuffered2Rendered org.apache.xmlgraphics.image.loader.impl.ImageConverterG2D2Bitmap org.apache.xmlgraphics.image.loader.impl.ImageConverterBitmap2G2D org.apache.xmlgraphics.image.loader.impl.ImageConverterRendered2PNG ././@LongLink0100644 0000000 0000000 00000000170 13777276623 011655 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/resources/META-INF/services/org.apache.xmlgraphics.image.loader.spi.ImageLoaderFactoryxmlgraphics-commons-2.6/src/main/resources/META-INF/services/org.apache.xmlgraphics.image.loader.spi0100644 0000000 0000000 00000000627 13777276623 032235 0ustar000000000 0000000 org.apache.xmlgraphics.image.loader.impl.imageio.ImageLoaderFactoryImageIO org.apache.xmlgraphics.image.loader.impl.ImageLoaderFactoryRaw org.apache.xmlgraphics.image.loader.impl.ImageLoaderFactoryRawCCITTFax org.apache.xmlgraphics.image.loader.impl.ImageLoaderFactoryEPS org.apache.xmlgraphics.image.loader.impl.ImageLoaderFactoryInternalTIFF org.apache.xmlgraphics.image.loader.impl.ImageLoaderFactoryPNG ././@LongLink0100644 0000000 0000000 00000000164 13777276623 011660 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/resources/META-INF/services/org.apache.xmlgraphics.image.loader.spi.ImagePreloaderxmlgraphics-commons-2.6/src/main/resources/META-INF/services/org.apache.xmlgraphics.image.loader.spi0100644 0000000 0000000 00000000700 13777276623 032225 0ustar000000000 0000000 org.apache.xmlgraphics.image.loader.impl.PreloaderTIFF org.apache.xmlgraphics.image.loader.impl.PreloaderGIF org.apache.xmlgraphics.image.loader.impl.PreloaderJPEG org.apache.xmlgraphics.image.loader.impl.PreloaderBMP org.apache.xmlgraphics.image.loader.impl.PreloaderEMF org.apache.xmlgraphics.image.loader.impl.PreloaderEPS org.apache.xmlgraphics.image.loader.impl.imageio.PreloaderImageIO org.apache.xmlgraphics.image.loader.impl.PreloaderRawPNG././@LongLink0100644 0000000 0000000 00000000155 13777276623 011660 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/resources/META-INF/services/org.apache.xmlgraphics.image.writer.ImageWriterxmlgraphics-commons-2.6/src/main/resources/META-INF/services/org.apache.xmlgraphics.image.writer.Ima0100644 0000000 0000000 00000000501 13777276623 032205 0ustar000000000 0000000 org.apache.xmlgraphics.image.writer.internal.PNGImageWriter org.apache.xmlgraphics.image.writer.internal.TIFFImageWriter org.apache.xmlgraphics.image.writer.imageio.ImageIOPNGImageWriter org.apache.xmlgraphics.image.writer.imageio.ImageIOTIFFImageWriter org.apache.xmlgraphics.image.writer.imageio.ImageIOJPEGImageWriter xmlgraphics-commons-2.6/src/main/resources/org/apache/xmlgraphics/fonts/glyphlist.txt0100644 0000000 0000000 00000230570 13777276623 030124 0ustar000000000 0000000 # ################################################################################### # Copyright (c) 1997,1998,2002,2007 Adobe Systems Incorporated # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this documentation file to use, copy, publish, distribute, # sublicense, and/or sell copies of the documentation, and to permit # others to do the same, provided that: # - No modification, editing or other alteration of this document is # allowed; and # - The above copyright notice and this permission notice shall be # included in all copies of the documentation. # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this documentation file, to create their own derivative works # from the content of this document to use, copy, publish, distribute, # sublicense, and/or sell the derivative works, and to permit others to do # the same, provided that the derived work is not represented as being a # copy or version of this document. # # Adobe shall not be liable to any party for any loss of revenue or profit # or for indirect, incidental, special, consequential, or other similar # damages, whether based on tort (including without limitation negligence # or strict liability), contract or other legal or equitable grounds even # if Adobe has been advised or had reason to know of the possibility of # such damages. The Adobe materials are provided on an "AS IS" basis. # Adobe specifically disclaims all express, statutory, or implied # warranties relating to the Adobe materials, including but not limited to # those concerning merchantability or fitness for a particular purpose or # non-infringement of any third party rights regarding the Adobe # materials. # ################################################################################### # Name: Adobe Glyph List # Table version: 2.0 # Date: September 20, 2002 # # See http://partners.adobe.com/asn/developer/typeforum/unicodegn.html # # Format: Semicolon-delimited fields: # (1) glyph name # (2) Unicode scalar value A;0041 AE;00C6 AEacute;01FC AEmacron;01E2 AEsmall;F7E6 Aacute;00C1 Aacutesmall;F7E1 Abreve;0102 Abreveacute;1EAE Abrevecyrillic;04D0 Abrevedotbelow;1EB6 Abrevegrave;1EB0 Abrevehookabove;1EB2 Abrevetilde;1EB4 Acaron;01CD Acircle;24B6 Acircumflex;00C2 Acircumflexacute;1EA4 Acircumflexdotbelow;1EAC Acircumflexgrave;1EA6 Acircumflexhookabove;1EA8 Acircumflexsmall;F7E2 Acircumflextilde;1EAA Acute;F6C9 Acutesmall;F7B4 Acyrillic;0410 Adblgrave;0200 Adieresis;00C4 Adieresiscyrillic;04D2 Adieresismacron;01DE Adieresissmall;F7E4 Adotbelow;1EA0 Adotmacron;01E0 Agrave;00C0 Agravesmall;F7E0 Ahookabove;1EA2 Aiecyrillic;04D4 Ainvertedbreve;0202 Alpha;0391 Alphatonos;0386 Amacron;0100 Amonospace;FF21 Aogonek;0104 Aring;00C5 Aringacute;01FA Aringbelow;1E00 Aringsmall;F7E5 Asmall;F761 Atilde;00C3 Atildesmall;F7E3 Aybarmenian;0531 B;0042 Bcircle;24B7 Bdotaccent;1E02 Bdotbelow;1E04 Becyrillic;0411 Benarmenian;0532 Beta;0392 Bhook;0181 Blinebelow;1E06 Bmonospace;FF22 Brevesmall;F6F4 Bsmall;F762 Btopbar;0182 C;0043 Caarmenian;053E Cacute;0106 Caron;F6CA Caronsmall;F6F5 Ccaron;010C Ccedilla;00C7 Ccedillaacute;1E08 Ccedillasmall;F7E7 Ccircle;24B8 Ccircumflex;0108 Cdot;010A Cdotaccent;010A Cedillasmall;F7B8 Chaarmenian;0549 Cheabkhasiancyrillic;04BC Checyrillic;0427 Chedescenderabkhasiancyrillic;04BE Chedescendercyrillic;04B6 Chedieresiscyrillic;04F4 Cheharmenian;0543 Chekhakassiancyrillic;04CB Cheverticalstrokecyrillic;04B8 Chi;03A7 Chook;0187 Circumflexsmall;F6F6 Cmonospace;FF23 Coarmenian;0551 Csmall;F763 D;0044 DZ;01F1 DZcaron;01C4 Daarmenian;0534 Dafrican;0189 Dcaron;010E Dcedilla;1E10 Dcircle;24B9 Dcircumflexbelow;1E12 Dcroat;0110 Ddotaccent;1E0A Ddotbelow;1E0C Decyrillic;0414 Deicoptic;03EE Delta;2206 Deltagreek;0394 Dhook;018A Dieresis;F6CB DieresisAcute;F6CC DieresisGrave;F6CD Dieresissmall;F7A8 Digammagreek;03DC Djecyrillic;0402 Dlinebelow;1E0E Dmonospace;FF24 Dotaccentsmall;F6F7 Dslash;0110 Dsmall;F764 Dtopbar;018B Dz;01F2 Dzcaron;01C5 Dzeabkhasiancyrillic;04E0 Dzecyrillic;0405 Dzhecyrillic;040F E;0045 Eacute;00C9 Eacutesmall;F7E9 Ebreve;0114 Ecaron;011A Ecedillabreve;1E1C Echarmenian;0535 Ecircle;24BA Ecircumflex;00CA Ecircumflexacute;1EBE Ecircumflexbelow;1E18 Ecircumflexdotbelow;1EC6 Ecircumflexgrave;1EC0 Ecircumflexhookabove;1EC2 Ecircumflexsmall;F7EA Ecircumflextilde;1EC4 Ecyrillic;0404 Edblgrave;0204 Edieresis;00CB Edieresissmall;F7EB Edot;0116 Edotaccent;0116 Edotbelow;1EB8 Efcyrillic;0424 Egrave;00C8 Egravesmall;F7E8 Eharmenian;0537 Ehookabove;1EBA Eightroman;2167 Einvertedbreve;0206 Eiotifiedcyrillic;0464 Elcyrillic;041B Elevenroman;216A Emacron;0112 Emacronacute;1E16 Emacrongrave;1E14 Emcyrillic;041C Emonospace;FF25 Encyrillic;041D Endescendercyrillic;04A2 Eng;014A Enghecyrillic;04A4 Enhookcyrillic;04C7 Eogonek;0118 Eopen;0190 Epsilon;0395 Epsilontonos;0388 Ercyrillic;0420 Ereversed;018E Ereversedcyrillic;042D Escyrillic;0421 Esdescendercyrillic;04AA Esh;01A9 Esmall;F765 Eta;0397 Etarmenian;0538 Etatonos;0389 Eth;00D0 Ethsmall;F7F0 Etilde;1EBC Etildebelow;1E1A Euro;20AC Ezh;01B7 Ezhcaron;01EE Ezhreversed;01B8 F;0046 Fcircle;24BB Fdotaccent;1E1E Feharmenian;0556 Feicoptic;03E4 Fhook;0191 Fitacyrillic;0472 Fiveroman;2164 Fmonospace;FF26 Fourroman;2163 Fsmall;F766 G;0047 GBsquare;3387 Gacute;01F4 Gamma;0393 Gammaafrican;0194 Gangiacoptic;03EA Gbreve;011E Gcaron;01E6 Gcedilla;0122 Gcircle;24BC Gcircumflex;011C Gcommaaccent;0122 Gdot;0120 Gdotaccent;0120 Gecyrillic;0413 Ghadarmenian;0542 Ghemiddlehookcyrillic;0494 Ghestrokecyrillic;0492 Gheupturncyrillic;0490 Ghook;0193 Gimarmenian;0533 Gjecyrillic;0403 Gmacron;1E20 Gmonospace;FF27 Grave;F6CE Gravesmall;F760 Gsmall;F767 Gsmallhook;029B Gstroke;01E4 H;0048 H18533;25CF H18543;25AA H18551;25AB H22073;25A1 HPsquare;33CB Haabkhasiancyrillic;04A8 Hadescendercyrillic;04B2 Hardsigncyrillic;042A Hbar;0126 Hbrevebelow;1E2A Hcedilla;1E28 Hcircle;24BD Hcircumflex;0124 Hdieresis;1E26 Hdotaccent;1E22 Hdotbelow;1E24 Hmonospace;FF28 Hoarmenian;0540 Horicoptic;03E8 Hsmall;F768 Hungarumlaut;F6CF Hungarumlautsmall;F6F8 Hzsquare;3390 I;0049 IAcyrillic;042F IJ;0132 IUcyrillic;042E Iacute;00CD Iacutesmall;F7ED Ibreve;012C Icaron;01CF Icircle;24BE Icircumflex;00CE Icircumflexsmall;F7EE Icyrillic;0406 Idblgrave;0208 Idieresis;00CF Idieresisacute;1E2E Idieresiscyrillic;04E4 Idieresissmall;F7EF Idot;0130 Idotaccent;0130 Idotbelow;1ECA Iebrevecyrillic;04D6 Iecyrillic;0415 Ifraktur;2111 Igrave;00CC Igravesmall;F7EC Ihookabove;1EC8 Iicyrillic;0418 Iinvertedbreve;020A Iishortcyrillic;0419 Imacron;012A Imacroncyrillic;04E2 Imonospace;FF29 Iniarmenian;053B Iocyrillic;0401 Iogonek;012E Iota;0399 Iotaafrican;0196 Iotadieresis;03AA Iotatonos;038A Ismall;F769 Istroke;0197 Itilde;0128 Itildebelow;1E2C Izhitsacyrillic;0474 Izhitsadblgravecyrillic;0476 J;004A Jaarmenian;0541 Jcircle;24BF Jcircumflex;0134 Jecyrillic;0408 Jheharmenian;054B Jmonospace;FF2A Jsmall;F76A K;004B KBsquare;3385 KKsquare;33CD Kabashkircyrillic;04A0 Kacute;1E30 Kacyrillic;041A Kadescendercyrillic;049A Kahookcyrillic;04C3 Kappa;039A Kastrokecyrillic;049E Kaverticalstrokecyrillic;049C Kcaron;01E8 Kcedilla;0136 Kcircle;24C0 Kcommaaccent;0136 Kdotbelow;1E32 Keharmenian;0554 Kenarmenian;053F Khacyrillic;0425 Kheicoptic;03E6 Khook;0198 Kjecyrillic;040C Klinebelow;1E34 Kmonospace;FF2B Koppacyrillic;0480 Koppagreek;03DE Ksicyrillic;046E Ksmall;F76B L;004C LJ;01C7 LL;F6BF Lacute;0139 Lambda;039B Lcaron;013D Lcedilla;013B Lcircle;24C1 Lcircumflexbelow;1E3C Lcommaaccent;013B Ldot;013F Ldotaccent;013F Ldotbelow;1E36 Ldotbelowmacron;1E38 Liwnarmenian;053C Lj;01C8 Ljecyrillic;0409 Llinebelow;1E3A Lmonospace;FF2C Lslash;0141 Lslashsmall;F6F9 Lsmall;F76C M;004D MBsquare;3386 Macron;F6D0 Macronsmall;F7AF Macute;1E3E Mcircle;24C2 Mdotaccent;1E40 Mdotbelow;1E42 Menarmenian;0544 Mmonospace;FF2D Msmall;F76D Mturned;019C Mu;039C N;004E NJ;01CA Nacute;0143 Ncaron;0147 Ncedilla;0145 Ncircle;24C3 Ncircumflexbelow;1E4A Ncommaaccent;0145 Ndotaccent;1E44 Ndotbelow;1E46 Nhookleft;019D Nineroman;2168 Nj;01CB Njecyrillic;040A Nlinebelow;1E48 Nmonospace;FF2E Nowarmenian;0546 Nsmall;F76E Ntilde;00D1 Ntildesmall;F7F1 Nu;039D O;004F OE;0152 OEsmall;F6FA Oacute;00D3 Oacutesmall;F7F3 Obarredcyrillic;04E8 Obarreddieresiscyrillic;04EA Obreve;014E Ocaron;01D1 Ocenteredtilde;019F Ocircle;24C4 Ocircumflex;00D4 Ocircumflexacute;1ED0 Ocircumflexdotbelow;1ED8 Ocircumflexgrave;1ED2 Ocircumflexhookabove;1ED4 Ocircumflexsmall;F7F4 Ocircumflextilde;1ED6 Ocyrillic;041E Odblacute;0150 Odblgrave;020C Odieresis;00D6 Odieresiscyrillic;04E6 Odieresissmall;F7F6 Odotbelow;1ECC Ogoneksmall;F6FB Ograve;00D2 Ogravesmall;F7F2 Oharmenian;0555 Ohm;2126 Ohookabove;1ECE Ohorn;01A0 Ohornacute;1EDA Ohorndotbelow;1EE2 Ohorngrave;1EDC Ohornhookabove;1EDE Ohorntilde;1EE0 Ohungarumlaut;0150 Oi;01A2 Oinvertedbreve;020E Omacron;014C Omacronacute;1E52 Omacrongrave;1E50 Omega;2126 Omegacyrillic;0460 Omegagreek;03A9 Omegaroundcyrillic;047A Omegatitlocyrillic;047C Omegatonos;038F Omicron;039F Omicrontonos;038C Omonospace;FF2F Oneroman;2160 Oogonek;01EA Oogonekmacron;01EC Oopen;0186 Oslash;00D8 Oslashacute;01FE Oslashsmall;F7F8 Osmall;F76F Ostrokeacute;01FE Otcyrillic;047E Otilde;00D5 Otildeacute;1E4C Otildedieresis;1E4E Otildesmall;F7F5 P;0050 Pacute;1E54 Pcircle;24C5 Pdotaccent;1E56 Pecyrillic;041F Peharmenian;054A Pemiddlehookcyrillic;04A6 Phi;03A6 Phook;01A4 Pi;03A0 Piwrarmenian;0553 Pmonospace;FF30 Psi;03A8 Psicyrillic;0470 Psmall;F770 Q;0051 Qcircle;24C6 Qmonospace;FF31 Qsmall;F771 R;0052 Raarmenian;054C Racute;0154 Rcaron;0158 Rcedilla;0156 Rcircle;24C7 Rcommaaccent;0156 Rdblgrave;0210 Rdotaccent;1E58 Rdotbelow;1E5A Rdotbelowmacron;1E5C Reharmenian;0550 Rfraktur;211C Rho;03A1 Ringsmall;F6FC Rinvertedbreve;0212 Rlinebelow;1E5E Rmonospace;FF32 Rsmall;F772 Rsmallinverted;0281 Rsmallinvertedsuperior;02B6 S;0053 SF010000;250C SF020000;2514 SF030000;2510 SF040000;2518 SF050000;253C SF060000;252C SF070000;2534 SF080000;251C SF090000;2524 SF100000;2500 SF110000;2502 SF190000;2561 SF200000;2562 SF210000;2556 SF220000;2555 SF230000;2563 SF240000;2551 SF250000;2557 SF260000;255D SF270000;255C SF280000;255B SF360000;255E SF370000;255F SF380000;255A SF390000;2554 SF400000;2569 SF410000;2566 SF420000;2560 SF430000;2550 SF440000;256C SF450000;2567 SF460000;2568 SF470000;2564 SF480000;2565 SF490000;2559 SF500000;2558 SF510000;2552 SF520000;2553 SF530000;256B SF540000;256A Sacute;015A Sacutedotaccent;1E64 Sampigreek;03E0 Scaron;0160 Scarondotaccent;1E66 Scaronsmall;F6FD Scedilla;015E Schwa;018F Schwacyrillic;04D8 Schwadieresiscyrillic;04DA Scircle;24C8 Scircumflex;015C Scommaaccent;0218 Sdotaccent;1E60 Sdotbelow;1E62 Sdotbelowdotaccent;1E68 Seharmenian;054D Sevenroman;2166 Shaarmenian;0547 Shacyrillic;0428 Shchacyrillic;0429 Sheicoptic;03E2 Shhacyrillic;04BA Shimacoptic;03EC Sigma;03A3 Sixroman;2165 Smonospace;FF33 Softsigncyrillic;042C Ssmall;F773 Stigmagreek;03DA T;0054 Tau;03A4 Tbar;0166 Tcaron;0164 Tcedilla;0162 Tcircle;24C9 Tcircumflexbelow;1E70 Tcommaaccent;0162 Tdotaccent;1E6A Tdotbelow;1E6C Tecyrillic;0422 Tedescendercyrillic;04AC Tenroman;2169 Tetsecyrillic;04B4 Theta;0398 Thook;01AC Thorn;00DE Thornsmall;F7FE Threeroman;2162 Tildesmall;F6FE Tiwnarmenian;054F Tlinebelow;1E6E Tmonospace;FF34 Toarmenian;0539 Tonefive;01BC Tonesix;0184 Tonetwo;01A7 Tretroflexhook;01AE Tsecyrillic;0426 Tshecyrillic;040B Tsmall;F774 Twelveroman;216B Tworoman;2161 U;0055 Uacute;00DA Uacutesmall;F7FA Ubreve;016C Ucaron;01D3 Ucircle;24CA Ucircumflex;00DB Ucircumflexbelow;1E76 Ucircumflexsmall;F7FB Ucyrillic;0423 Udblacute;0170 Udblgrave;0214 Udieresis;00DC Udieresisacute;01D7 Udieresisbelow;1E72 Udieresiscaron;01D9 Udieresiscyrillic;04F0 Udieresisgrave;01DB Udieresismacron;01D5 Udieresissmall;F7FC Udotbelow;1EE4 Ugrave;00D9 Ugravesmall;F7F9 Uhookabove;1EE6 Uhorn;01AF Uhornacute;1EE8 Uhorndotbelow;1EF0 Uhorngrave;1EEA Uhornhookabove;1EEC Uhorntilde;1EEE Uhungarumlaut;0170 Uhungarumlautcyrillic;04F2 Uinvertedbreve;0216 Ukcyrillic;0478 Umacron;016A Umacroncyrillic;04EE Umacrondieresis;1E7A Umonospace;FF35 Uogonek;0172 Upsilon;03A5 Upsilon1;03D2 Upsilonacutehooksymbolgreek;03D3 Upsilonafrican;01B1 Upsilondieresis;03AB Upsilondieresishooksymbolgreek;03D4 Upsilonhooksymbol;03D2 Upsilontonos;038E Uring;016E Ushortcyrillic;040E Usmall;F775 Ustraightcyrillic;04AE Ustraightstrokecyrillic;04B0 Utilde;0168 Utildeacute;1E78 Utildebelow;1E74 V;0056 Vcircle;24CB Vdotbelow;1E7E Vecyrillic;0412 Vewarmenian;054E Vhook;01B2 Vmonospace;FF36 Voarmenian;0548 Vsmall;F776 Vtilde;1E7C W;0057 Wacute;1E82 Wcircle;24CC Wcircumflex;0174 Wdieresis;1E84 Wdotaccent;1E86 Wdotbelow;1E88 Wgrave;1E80 Wmonospace;FF37 Wsmall;F777 X;0058 Xcircle;24CD Xdieresis;1E8C Xdotaccent;1E8A Xeharmenian;053D Xi;039E Xmonospace;FF38 Xsmall;F778 Y;0059 Yacute;00DD Yacutesmall;F7FD Yatcyrillic;0462 Ycircle;24CE Ycircumflex;0176 Ydieresis;0178 Ydieresissmall;F7FF Ydotaccent;1E8E Ydotbelow;1EF4 Yericyrillic;042B Yerudieresiscyrillic;04F8 Ygrave;1EF2 Yhook;01B3 Yhookabove;1EF6 Yiarmenian;0545 Yicyrillic;0407 Yiwnarmenian;0552 Ymonospace;FF39 Ysmall;F779 Ytilde;1EF8 Yusbigcyrillic;046A Yusbigiotifiedcyrillic;046C Yuslittlecyrillic;0466 Yuslittleiotifiedcyrillic;0468 Z;005A Zaarmenian;0536 Zacute;0179 Zcaron;017D Zcaronsmall;F6FF Zcircle;24CF Zcircumflex;1E90 Zdot;017B Zdotaccent;017B Zdotbelow;1E92 Zecyrillic;0417 Zedescendercyrillic;0498 Zedieresiscyrillic;04DE Zeta;0396 Zhearmenian;053A Zhebrevecyrillic;04C1 Zhecyrillic;0416 Zhedescendercyrillic;0496 Zhedieresiscyrillic;04DC Zlinebelow;1E94 Zmonospace;FF3A Zsmall;F77A Zstroke;01B5 a;0061 aabengali;0986 aacute;00E1 aadeva;0906 aagujarati;0A86 aagurmukhi;0A06 aamatragurmukhi;0A3E aarusquare;3303 aavowelsignbengali;09BE aavowelsigndeva;093E aavowelsigngujarati;0ABE abbreviationmarkarmenian;055F abbreviationsigndeva;0970 abengali;0985 abopomofo;311A abreve;0103 abreveacute;1EAF abrevecyrillic;04D1 abrevedotbelow;1EB7 abrevegrave;1EB1 abrevehookabove;1EB3 abrevetilde;1EB5 acaron;01CE acircle;24D0 acircumflex;00E2 acircumflexacute;1EA5 acircumflexdotbelow;1EAD acircumflexgrave;1EA7 acircumflexhookabove;1EA9 acircumflextilde;1EAB acute;00B4 acutebelowcmb;0317 acutecmb;0301 acutecomb;0301 acutedeva;0954 acutelowmod;02CF acutetonecmb;0341 acyrillic;0430 adblgrave;0201 addakgurmukhi;0A71 adeva;0905 adieresis;00E4 adieresiscyrillic;04D3 adieresismacron;01DF adotbelow;1EA1 adotmacron;01E1 ae;00E6 aeacute;01FD aekorean;3150 aemacron;01E3 afii00208;2015 afii08941;20A4 afii10017;0410 afii10018;0411 afii10019;0412 afii10020;0413 afii10021;0414 afii10022;0415 afii10023;0401 afii10024;0416 afii10025;0417 afii10026;0418 afii10027;0419 afii10028;041A afii10029;041B afii10030;041C afii10031;041D afii10032;041E afii10033;041F afii10034;0420 afii10035;0421 afii10036;0422 afii10037;0423 afii10038;0424 afii10039;0425 afii10040;0426 afii10041;0427 afii10042;0428 afii10043;0429 afii10044;042A afii10045;042B afii10046;042C afii10047;042D afii10048;042E afii10049;042F afii10050;0490 afii10051;0402 afii10052;0403 afii10053;0404 afii10054;0405 afii10055;0406 afii10056;0407 afii10057;0408 afii10058;0409 afii10059;040A afii10060;040B afii10061;040C afii10062;040E afii10063;F6C4 afii10064;F6C5 afii10065;0430 afii10066;0431 afii10067;0432 afii10068;0433 afii10069;0434 afii10070;0435 afii10071;0451 afii10072;0436 afii10073;0437 afii10074;0438 afii10075;0439 afii10076;043A afii10077;043B afii10078;043C afii10079;043D afii10080;043E afii10081;043F afii10082;0440 afii10083;0441 afii10084;0442 afii10085;0443 afii10086;0444 afii10087;0445 afii10088;0446 afii10089;0447 afii10090;0448 afii10091;0449 afii10092;044A afii10093;044B afii10094;044C afii10095;044D afii10096;044E afii10097;044F afii10098;0491 afii10099;0452 afii10100;0453 afii10101;0454 afii10102;0455 afii10103;0456 afii10104;0457 afii10105;0458 afii10106;0459 afii10107;045A afii10108;045B afii10109;045C afii10110;045E afii10145;040F afii10146;0462 afii10147;0472 afii10148;0474 afii10192;F6C6 afii10193;045F afii10194;0463 afii10195;0473 afii10196;0475 afii10831;F6C7 afii10832;F6C8 afii10846;04D9 afii299;200E afii300;200F afii301;200D afii57381;066A afii57388;060C afii57392;0660 afii57393;0661 afii57394;0662 afii57395;0663 afii57396;0664 afii57397;0665 afii57398;0666 afii57399;0667 afii57400;0668 afii57401;0669 afii57403;061B afii57407;061F afii57409;0621 afii57410;0622 afii57411;0623 afii57412;0624 afii57413;0625 afii57414;0626 afii57415;0627 afii57416;0628 afii57417;0629 afii57418;062A afii57419;062B afii57420;062C afii57421;062D afii57422;062E afii57423;062F afii57424;0630 afii57425;0631 afii57426;0632 afii57427;0633 afii57428;0634 afii57429;0635 afii57430;0636 afii57431;0637 afii57432;0638 afii57433;0639 afii57434;063A afii57440;0640 afii57441;0641 afii57442;0642 afii57443;0643 afii57444;0644 afii57445;0645 afii57446;0646 afii57448;0648 afii57449;0649 afii57450;064A afii57451;064B afii57452;064C afii57453;064D afii57454;064E afii57455;064F afii57456;0650 afii57457;0651 afii57458;0652 afii57470;0647 afii57505;06A4 afii57506;067E afii57507;0686 afii57508;0698 afii57509;06AF afii57511;0679 afii57512;0688 afii57513;0691 afii57514;06BA afii57519;06D2 afii57534;06D5 afii57636;20AA afii57645;05BE afii57658;05C3 afii57664;05D0 afii57665;05D1 afii57666;05D2 afii57667;05D3 afii57668;05D4 afii57669;05D5 afii57670;05D6 afii57671;05D7 afii57672;05D8 afii57673;05D9 afii57674;05DA afii57675;05DB afii57676;05DC afii57677;05DD afii57678;05DE afii57679;05DF afii57680;05E0 afii57681;05E1 afii57682;05E2 afii57683;05E3 afii57684;05E4 afii57685;05E5 afii57686;05E6 afii57687;05E7 afii57688;05E8 afii57689;05E9 afii57690;05EA afii57694;FB2A afii57695;FB2B afii57700;FB4B afii57705;FB1F afii57716;05F0 afii57717;05F1 afii57718;05F2 afii57723;FB35 afii57793;05B4 afii57794;05B5 afii57795;05B6 afii57796;05BB afii57797;05B8 afii57798;05B7 afii57799;05B0 afii57800;05B2 afii57801;05B1 afii57802;05B3 afii57803;05C2 afii57804;05C1 afii57806;05B9 afii57807;05BC afii57839;05BD afii57841;05BF afii57842;05C0 afii57929;02BC afii61248;2105 afii61289;2113 afii61352;2116 afii61573;202C afii61574;202D afii61575;202E afii61664;200C afii63167;066D afii64937;02BD agrave;00E0 agujarati;0A85 agurmukhi;0A05 ahiragana;3042 ahookabove;1EA3 aibengali;0990 aibopomofo;311E aideva;0910 aiecyrillic;04D5 aigujarati;0A90 aigurmukhi;0A10 aimatragurmukhi;0A48 ainarabic;0639 ainfinalarabic;FECA aininitialarabic;FECB ainmedialarabic;FECC ainvertedbreve;0203 aivowelsignbengali;09C8 aivowelsigndeva;0948 aivowelsigngujarati;0AC8 akatakana;30A2 akatakanahalfwidth;FF71 akorean;314F alef;05D0 alefarabic;0627 alefdageshhebrew;FB30 aleffinalarabic;FE8E alefhamzaabovearabic;0623 alefhamzaabovefinalarabic;FE84 alefhamzabelowarabic;0625 alefhamzabelowfinalarabic;FE88 alefhebrew;05D0 aleflamedhebrew;FB4F alefmaddaabovearabic;0622 alefmaddaabovefinalarabic;FE82 alefmaksuraarabic;0649 alefmaksurafinalarabic;FEF0 alefmaksurainitialarabic;FEF3 alefmaksuramedialarabic;FEF4 alefpatahhebrew;FB2E alefqamatshebrew;FB2F aleph;2135 allequal;224C alpha;03B1 alphatonos;03AC amacron;0101 amonospace;FF41 ampersand;0026 ampersandmonospace;FF06 ampersandsmall;F726 amsquare;33C2 anbopomofo;3122 angbopomofo;3124 angkhankhuthai;0E5A angle;2220 anglebracketleft;3008 anglebracketleftvertical;FE3F anglebracketright;3009 anglebracketrightvertical;FE40 angleleft;2329 angleright;232A angstrom;212B anoteleia;0387 anudattadeva;0952 anusvarabengali;0982 anusvaradeva;0902 anusvaragujarati;0A82 aogonek;0105 apaatosquare;3300 aparen;249C apostrophearmenian;055A apostrophemod;02BC apple;F8FF approaches;2250 approxequal;2248 approxequalorimage;2252 approximatelyequal;2245 araeaekorean;318E araeakorean;318D arc;2312 arighthalfring;1E9A aring;00E5 aringacute;01FB aringbelow;1E01 arrowboth;2194 arrowdashdown;21E3 arrowdashleft;21E0 arrowdashright;21E2 arrowdashup;21E1 arrowdblboth;21D4 arrowdbldown;21D3 arrowdblleft;21D0 arrowdblright;21D2 arrowdblup;21D1 arrowdown;2193 arrowdownleft;2199 arrowdownright;2198 arrowdownwhite;21E9 arrowheaddownmod;02C5 arrowheadleftmod;02C2 arrowheadrightmod;02C3 arrowheadupmod;02C4 arrowhorizex;F8E7 arrowleft;2190 arrowleftdbl;21D0 arrowleftdblstroke;21CD arrowleftoverright;21C6 arrowleftwhite;21E6 arrowright;2192 arrowrightdblstroke;21CF arrowrightheavy;279E arrowrightoverleft;21C4 arrowrightwhite;21E8 arrowtableft;21E4 arrowtabright;21E5 arrowup;2191 arrowupdn;2195 arrowupdnbse;21A8 arrowupdownbase;21A8 arrowupleft;2196 arrowupleftofdown;21C5 arrowupright;2197 arrowupwhite;21E7 arrowvertex;F8E6 asciicircum;005E asciicircummonospace;FF3E asciitilde;007E asciitildemonospace;FF5E ascript;0251 ascriptturned;0252 asmallhiragana;3041 asmallkatakana;30A1 asmallkatakanahalfwidth;FF67 asterisk;002A asteriskaltonearabic;066D asteriskarabic;066D asteriskmath;2217 asteriskmonospace;FF0A asterisksmall;FE61 asterism;2042 asuperior;F6E9 asymptoticallyequal;2243 at;0040 atilde;00E3 atmonospace;FF20 atsmall;FE6B aturned;0250 aubengali;0994 aubopomofo;3120 audeva;0914 augujarati;0A94 augurmukhi;0A14 aulengthmarkbengali;09D7 aumatragurmukhi;0A4C auvowelsignbengali;09CC auvowelsigndeva;094C auvowelsigngujarati;0ACC avagrahadeva;093D aybarmenian;0561 ayin;05E2 ayinaltonehebrew;FB20 ayinhebrew;05E2 b;0062 babengali;09AC backslash;005C backslashmonospace;FF3C badeva;092C bagujarati;0AAC bagurmukhi;0A2C bahiragana;3070 bahtthai;0E3F bakatakana;30D0 bar;007C barmonospace;FF5C bbopomofo;3105 bcircle;24D1 bdotaccent;1E03 bdotbelow;1E05 beamedsixteenthnotes;266C because;2235 becyrillic;0431 beharabic;0628 behfinalarabic;FE90 behinitialarabic;FE91 behiragana;3079 behmedialarabic;FE92 behmeeminitialarabic;FC9F behmeemisolatedarabic;FC08 behnoonfinalarabic;FC6D bekatakana;30D9 benarmenian;0562 bet;05D1 beta;03B2 betasymbolgreek;03D0 betdagesh;FB31 betdageshhebrew;FB31 bethebrew;05D1 betrafehebrew;FB4C bhabengali;09AD bhadeva;092D bhagujarati;0AAD bhagurmukhi;0A2D bhook;0253 bihiragana;3073 bikatakana;30D3 bilabialclick;0298 bindigurmukhi;0A02 birusquare;3331 blackcircle;25CF blackdiamond;25C6 blackdownpointingtriangle;25BC blackleftpointingpointer;25C4 blackleftpointingtriangle;25C0 blacklenticularbracketleft;3010 blacklenticularbracketleftvertical;FE3B blacklenticularbracketright;3011 blacklenticularbracketrightvertical;FE3C blacklowerlefttriangle;25E3 blacklowerrighttriangle;25E2 blackrectangle;25AC blackrightpointingpointer;25BA blackrightpointingtriangle;25B6 blacksmallsquare;25AA blacksmilingface;263B blacksquare;25A0 blackstar;2605 blackupperlefttriangle;25E4 blackupperrighttriangle;25E5 blackuppointingsmalltriangle;25B4 blackuppointingtriangle;25B2 blank;2423 blinebelow;1E07 block;2588 bmonospace;FF42 bobaimaithai;0E1A bohiragana;307C bokatakana;30DC bparen;249D bqsquare;33C3 braceex;F8F4 braceleft;007B braceleftbt;F8F3 braceleftmid;F8F2 braceleftmonospace;FF5B braceleftsmall;FE5B bracelefttp;F8F1 braceleftvertical;FE37 braceright;007D bracerightbt;F8FE bracerightmid;F8FD bracerightmonospace;FF5D bracerightsmall;FE5C bracerighttp;F8FC bracerightvertical;FE38 bracketleft;005B bracketleftbt;F8F0 bracketleftex;F8EF bracketleftmonospace;FF3B bracketlefttp;F8EE bracketright;005D bracketrightbt;F8FB bracketrightex;F8FA bracketrightmonospace;FF3D bracketrighttp;F8F9 breve;02D8 brevebelowcmb;032E brevecmb;0306 breveinvertedbelowcmb;032F breveinvertedcmb;0311 breveinverteddoublecmb;0361 bridgebelowcmb;032A bridgeinvertedbelowcmb;033A brokenbar;00A6 bstroke;0180 bsuperior;F6EA btopbar;0183 buhiragana;3076 bukatakana;30D6 bullet;2022 bulletinverse;25D8 bulletoperator;2219 bullseye;25CE c;0063 caarmenian;056E cabengali;099A cacute;0107 cadeva;091A cagujarati;0A9A cagurmukhi;0A1A calsquare;3388 candrabindubengali;0981 candrabinducmb;0310 candrabindudeva;0901 candrabindugujarati;0A81 capslock;21EA careof;2105 caron;02C7 caronbelowcmb;032C caroncmb;030C carriagereturn;21B5 cbopomofo;3118 ccaron;010D ccedilla;00E7 ccedillaacute;1E09 ccircle;24D2 ccircumflex;0109 ccurl;0255 cdot;010B cdotaccent;010B cdsquare;33C5 cedilla;00B8 cedillacmb;0327 cent;00A2 centigrade;2103 centinferior;F6DF centmonospace;FFE0 centoldstyle;F7A2 centsuperior;F6E0 chaarmenian;0579 chabengali;099B chadeva;091B chagujarati;0A9B chagurmukhi;0A1B chbopomofo;3114 cheabkhasiancyrillic;04BD checkmark;2713 checyrillic;0447 chedescenderabkhasiancyrillic;04BF chedescendercyrillic;04B7 chedieresiscyrillic;04F5 cheharmenian;0573 chekhakassiancyrillic;04CC cheverticalstrokecyrillic;04B9 chi;03C7 chieuchacirclekorean;3277 chieuchaparenkorean;3217 chieuchcirclekorean;3269 chieuchkorean;314A chieuchparenkorean;3209 chochangthai;0E0A chochanthai;0E08 chochingthai;0E09 chochoethai;0E0C chook;0188 cieucacirclekorean;3276 cieucaparenkorean;3216 cieuccirclekorean;3268 cieuckorean;3148 cieucparenkorean;3208 cieucuparenkorean;321C circle;25CB circlemultiply;2297 circleot;2299 circleplus;2295 circlepostalmark;3036 circlewithlefthalfblack;25D0 circlewithrighthalfblack;25D1 circumflex;02C6 circumflexbelowcmb;032D circumflexcmb;0302 clear;2327 clickalveolar;01C2 clickdental;01C0 clicklateral;01C1 clickretroflex;01C3 club;2663 clubsuitblack;2663 clubsuitwhite;2667 cmcubedsquare;33A4 cmonospace;FF43 cmsquaredsquare;33A0 coarmenian;0581 colon;003A colonmonetary;20A1 colonmonospace;FF1A colonsign;20A1 colonsmall;FE55 colontriangularhalfmod;02D1 colontriangularmod;02D0 comma;002C commaabovecmb;0313 commaaboverightcmb;0315 commaaccent;F6C3 commaarabic;060C commaarmenian;055D commainferior;F6E1 commamonospace;FF0C commareversedabovecmb;0314 commareversedmod;02BD commasmall;FE50 commasuperior;F6E2 commaturnedabovecmb;0312 commaturnedmod;02BB compass;263C congruent;2245 contourintegral;222E control;2303 controlACK;0006 controlBEL;0007 controlBS;0008 controlCAN;0018 controlCR;000D controlDC1;0011 controlDC2;0012 controlDC3;0013 controlDC4;0014 controlDEL;007F controlDLE;0010 controlEM;0019 controlENQ;0005 controlEOT;0004 controlESC;001B controlETB;0017 controlETX;0003 controlFF;000C controlFS;001C controlGS;001D controlHT;0009 controlLF;000A controlNAK;0015 controlRS;001E controlSI;000F controlSO;000E controlSOT;0002 controlSTX;0001 controlSUB;001A controlSYN;0016 controlUS;001F controlVT;000B copyright;00A9 copyrightsans;F8E9 copyrightserif;F6D9 cornerbracketleft;300C cornerbracketlefthalfwidth;FF62 cornerbracketleftvertical;FE41 cornerbracketright;300D cornerbracketrighthalfwidth;FF63 cornerbracketrightvertical;FE42 corporationsquare;337F cosquare;33C7 coverkgsquare;33C6 cparen;249E cruzeiro;20A2 cstretched;0297 curlyand;22CF curlyor;22CE currency;00A4 cyrBreve;F6D1 cyrFlex;F6D2 cyrbreve;F6D4 cyrflex;F6D5 d;0064 daarmenian;0564 dabengali;09A6 dadarabic;0636 dadeva;0926 dadfinalarabic;FEBE dadinitialarabic;FEBF dadmedialarabic;FEC0 dagesh;05BC dageshhebrew;05BC dagger;2020 daggerdbl;2021 dagujarati;0AA6 dagurmukhi;0A26 dahiragana;3060 dakatakana;30C0 dalarabic;062F dalet;05D3 daletdagesh;FB33 daletdageshhebrew;FB33 dalethatafpatah;05D3 05B2 dalethatafpatahhebrew;05D3 05B2 dalethatafsegol;05D3 05B1 dalethatafsegolhebrew;05D3 05B1 dalethebrew;05D3 dalethiriq;05D3 05B4 dalethiriqhebrew;05D3 05B4 daletholam;05D3 05B9 daletholamhebrew;05D3 05B9 daletpatah;05D3 05B7 daletpatahhebrew;05D3 05B7 daletqamats;05D3 05B8 daletqamatshebrew;05D3 05B8 daletqubuts;05D3 05BB daletqubutshebrew;05D3 05BB daletsegol;05D3 05B6 daletsegolhebrew;05D3 05B6 daletsheva;05D3 05B0 daletshevahebrew;05D3 05B0 dalettsere;05D3 05B5 dalettserehebrew;05D3 05B5 dalfinalarabic;FEAA dammaarabic;064F dammalowarabic;064F dammatanaltonearabic;064C dammatanarabic;064C danda;0964 dargahebrew;05A7 dargalefthebrew;05A7 dasiapneumatacyrilliccmb;0485 dblGrave;F6D3 dblanglebracketleft;300A dblanglebracketleftvertical;FE3D dblanglebracketright;300B dblanglebracketrightvertical;FE3E dblarchinvertedbelowcmb;032B dblarrowleft;21D4 dblarrowright;21D2 dbldanda;0965 dblgrave;F6D6 dblgravecmb;030F dblintegral;222C dbllowline;2017 dbllowlinecmb;0333 dbloverlinecmb;033F dblprimemod;02BA dblverticalbar;2016 dblverticallineabovecmb;030E dbopomofo;3109 dbsquare;33C8 dcaron;010F dcedilla;1E11 dcircle;24D3 dcircumflexbelow;1E13 dcroat;0111 ddabengali;09A1 ddadeva;0921 ddagujarati;0AA1 ddagurmukhi;0A21 ddalarabic;0688 ddalfinalarabic;FB89 dddhadeva;095C ddhabengali;09A2 ddhadeva;0922 ddhagujarati;0AA2 ddhagurmukhi;0A22 ddotaccent;1E0B ddotbelow;1E0D decimalseparatorarabic;066B decimalseparatorpersian;066B decyrillic;0434 degree;00B0 dehihebrew;05AD dehiragana;3067 deicoptic;03EF dekatakana;30C7 deleteleft;232B deleteright;2326 delta;03B4 deltaturned;018D denominatorminusonenumeratorbengali;09F8 dezh;02A4 dhabengali;09A7 dhadeva;0927 dhagujarati;0AA7 dhagurmukhi;0A27 dhook;0257 dialytikatonos;0385 dialytikatonoscmb;0344 diamond;2666 diamondsuitwhite;2662 dieresis;00A8 dieresisacute;F6D7 dieresisbelowcmb;0324 dieresiscmb;0308 dieresisgrave;F6D8 dieresistonos;0385 dihiragana;3062 dikatakana;30C2 dittomark;3003 divide;00F7 divides;2223 divisionslash;2215 djecyrillic;0452 dkshade;2593 dlinebelow;1E0F dlsquare;3397 dmacron;0111 dmonospace;FF44 dnblock;2584 dochadathai;0E0E dodekthai;0E14 dohiragana;3069 dokatakana;30C9 dollar;0024 dollarinferior;F6E3 dollarmonospace;FF04 dollaroldstyle;F724 dollarsmall;FE69 dollarsuperior;F6E4 dong;20AB dorusquare;3326 dotaccent;02D9 dotaccentcmb;0307 dotbelowcmb;0323 dotbelowcomb;0323 dotkatakana;30FB dotlessi;0131 dotlessj;F6BE dotlessjstrokehook;0284 dotmath;22C5 dottedcircle;25CC doubleyodpatah;FB1F doubleyodpatahhebrew;FB1F downtackbelowcmb;031E downtackmod;02D5 dparen;249F dsuperior;F6EB dtail;0256 dtopbar;018C duhiragana;3065 dukatakana;30C5 dz;01F3 dzaltone;02A3 dzcaron;01C6 dzcurl;02A5 dzeabkhasiancyrillic;04E1 dzecyrillic;0455 dzhecyrillic;045F e;0065 eacute;00E9 earth;2641 ebengali;098F ebopomofo;311C ebreve;0115 ecandradeva;090D ecandragujarati;0A8D ecandravowelsigndeva;0945 ecandravowelsigngujarati;0AC5 ecaron;011B ecedillabreve;1E1D echarmenian;0565 echyiwnarmenian;0587 ecircle;24D4 ecircumflex;00EA ecircumflexacute;1EBF ecircumflexbelow;1E19 ecircumflexdotbelow;1EC7 ecircumflexgrave;1EC1 ecircumflexhookabove;1EC3 ecircumflextilde;1EC5 ecyrillic;0454 edblgrave;0205 edeva;090F edieresis;00EB edot;0117 edotaccent;0117 edotbelow;1EB9 eegurmukhi;0A0F eematragurmukhi;0A47 efcyrillic;0444 egrave;00E8 egujarati;0A8F eharmenian;0567 ehbopomofo;311D ehiragana;3048 ehookabove;1EBB eibopomofo;311F eight;0038 eightarabic;0668 eightbengali;09EE eightcircle;2467 eightcircleinversesansserif;2791 eightdeva;096E eighteencircle;2471 eighteenparen;2485 eighteenperiod;2499 eightgujarati;0AEE eightgurmukhi;0A6E eighthackarabic;0668 eighthangzhou;3028 eighthnotebeamed;266B eightideographicparen;3227 eightinferior;2088 eightmonospace;FF18 eightoldstyle;F738 eightparen;247B eightperiod;248F eightpersian;06F8 eightroman;2177 eightsuperior;2078 eightthai;0E58 einvertedbreve;0207 eiotifiedcyrillic;0465 ekatakana;30A8 ekatakanahalfwidth;FF74 ekonkargurmukhi;0A74 ekorean;3154 elcyrillic;043B element;2208 elevencircle;246A elevenparen;247E elevenperiod;2492 elevenroman;217A ellipsis;2026 ellipsisvertical;22EE emacron;0113 emacronacute;1E17 emacrongrave;1E15 emcyrillic;043C emdash;2014 emdashvertical;FE31 emonospace;FF45 emphasismarkarmenian;055B emptyset;2205 enbopomofo;3123 encyrillic;043D endash;2013 endashvertical;FE32 endescendercyrillic;04A3 eng;014B engbopomofo;3125 enghecyrillic;04A5 enhookcyrillic;04C8 enspace;2002 eogonek;0119 eokorean;3153 eopen;025B eopenclosed;029A eopenreversed;025C eopenreversedclosed;025E eopenreversedhook;025D eparen;24A0 epsilon;03B5 epsilontonos;03AD equal;003D equalmonospace;FF1D equalsmall;FE66 equalsuperior;207C equivalence;2261 erbopomofo;3126 ercyrillic;0440 ereversed;0258 ereversedcyrillic;044D escyrillic;0441 esdescendercyrillic;04AB esh;0283 eshcurl;0286 eshortdeva;090E eshortvowelsigndeva;0946 eshreversedloop;01AA eshsquatreversed;0285 esmallhiragana;3047 esmallkatakana;30A7 esmallkatakanahalfwidth;FF6A estimated;212E esuperior;F6EC eta;03B7 etarmenian;0568 etatonos;03AE eth;00F0 etilde;1EBD etildebelow;1E1B etnahtafoukhhebrew;0591 etnahtafoukhlefthebrew;0591 etnahtahebrew;0591 etnahtalefthebrew;0591 eturned;01DD eukorean;3161 euro;20AC evowelsignbengali;09C7 evowelsigndeva;0947 evowelsigngujarati;0AC7 exclam;0021 exclamarmenian;055C exclamdbl;203C exclamdown;00A1 exclamdownsmall;F7A1 exclammonospace;FF01 exclamsmall;F721 existential;2203 ezh;0292 ezhcaron;01EF ezhcurl;0293 ezhreversed;01B9 ezhtail;01BA f;0066 fadeva;095E fagurmukhi;0A5E fahrenheit;2109 fathaarabic;064E fathalowarabic;064E fathatanarabic;064B fbopomofo;3108 fcircle;24D5 fdotaccent;1E1F feharabic;0641 feharmenian;0586 fehfinalarabic;FED2 fehinitialarabic;FED3 fehmedialarabic;FED4 feicoptic;03E5 female;2640 ff;FB00 ffi;FB03 ffl;FB04 fi;FB01 fifteencircle;246E fifteenparen;2482 fifteenperiod;2496 figuredash;2012 filledbox;25A0 filledrect;25AC finalkaf;05DA finalkafdagesh;FB3A finalkafdageshhebrew;FB3A finalkafhebrew;05DA finalkafqamats;05DA 05B8 finalkafqamatshebrew;05DA 05B8 finalkafsheva;05DA 05B0 finalkafshevahebrew;05DA 05B0 finalmem;05DD finalmemhebrew;05DD finalnun;05DF finalnunhebrew;05DF finalpe;05E3 finalpehebrew;05E3 finaltsadi;05E5 finaltsadihebrew;05E5 firsttonechinese;02C9 fisheye;25C9 fitacyrillic;0473 five;0035 fivearabic;0665 fivebengali;09EB fivecircle;2464 fivecircleinversesansserif;278E fivedeva;096B fiveeighths;215D fivegujarati;0AEB fivegurmukhi;0A6B fivehackarabic;0665 fivehangzhou;3025 fiveideographicparen;3224 fiveinferior;2085 fivemonospace;FF15 fiveoldstyle;F735 fiveparen;2478 fiveperiod;248C fivepersian;06F5 fiveroman;2174 fivesuperior;2075 fivethai;0E55 fl;FB02 florin;0192 fmonospace;FF46 fmsquare;3399 fofanthai;0E1F fofathai;0E1D fongmanthai;0E4F forall;2200 four;0034 fourarabic;0664 fourbengali;09EA fourcircle;2463 fourcircleinversesansserif;278D fourdeva;096A fourgujarati;0AEA fourgurmukhi;0A6A fourhackarabic;0664 fourhangzhou;3024 fourideographicparen;3223 fourinferior;2084 fourmonospace;FF14 fournumeratorbengali;09F7 fouroldstyle;F734 fourparen;2477 fourperiod;248B fourpersian;06F4 fourroman;2173 foursuperior;2074 fourteencircle;246D fourteenparen;2481 fourteenperiod;2495 fourthai;0E54 fourthtonechinese;02CB fparen;24A1 fraction;2044 franc;20A3 g;0067 gabengali;0997 gacute;01F5 gadeva;0917 gafarabic;06AF gaffinalarabic;FB93 gafinitialarabic;FB94 gafmedialarabic;FB95 gagujarati;0A97 gagurmukhi;0A17 gahiragana;304C gakatakana;30AC gamma;03B3 gammalatinsmall;0263 gammasuperior;02E0 gangiacoptic;03EB gbopomofo;310D gbreve;011F gcaron;01E7 gcedilla;0123 gcircle;24D6 gcircumflex;011D gcommaaccent;0123 gdot;0121 gdotaccent;0121 gecyrillic;0433 gehiragana;3052 gekatakana;30B2 geometricallyequal;2251 gereshaccenthebrew;059C gereshhebrew;05F3 gereshmuqdamhebrew;059D germandbls;00DF gershayimaccenthebrew;059E gershayimhebrew;05F4 getamark;3013 ghabengali;0998 ghadarmenian;0572 ghadeva;0918 ghagujarati;0A98 ghagurmukhi;0A18 ghainarabic;063A ghainfinalarabic;FECE ghaininitialarabic;FECF ghainmedialarabic;FED0 ghemiddlehookcyrillic;0495 ghestrokecyrillic;0493 gheupturncyrillic;0491 ghhadeva;095A ghhagurmukhi;0A5A ghook;0260 ghzsquare;3393 gihiragana;304E gikatakana;30AE gimarmenian;0563 gimel;05D2 gimeldagesh;FB32 gimeldageshhebrew;FB32 gimelhebrew;05D2 gjecyrillic;0453 glottalinvertedstroke;01BE glottalstop;0294 glottalstopinverted;0296 glottalstopmod;02C0 glottalstopreversed;0295 glottalstopreversedmod;02C1 glottalstopreversedsuperior;02E4 glottalstopstroke;02A1 glottalstopstrokereversed;02A2 gmacron;1E21 gmonospace;FF47 gohiragana;3054 gokatakana;30B4 gparen;24A2 gpasquare;33AC gradient;2207 grave;0060 gravebelowcmb;0316 gravecmb;0300 gravecomb;0300 gravedeva;0953 gravelowmod;02CE gravemonospace;FF40 gravetonecmb;0340 greater;003E greaterequal;2265 greaterequalorless;22DB greatermonospace;FF1E greaterorequivalent;2273 greaterorless;2277 greateroverequal;2267 greatersmall;FE65 gscript;0261 gstroke;01E5 guhiragana;3050 guillemotleft;00AB guillemotright;00BB guilsinglleft;2039 guilsinglright;203A gukatakana;30B0 guramusquare;3318 gysquare;33C9 h;0068 haabkhasiancyrillic;04A9 haaltonearabic;06C1 habengali;09B9 hadescendercyrillic;04B3 hadeva;0939 hagujarati;0AB9 hagurmukhi;0A39 haharabic;062D hahfinalarabic;FEA2 hahinitialarabic;FEA3 hahiragana;306F hahmedialarabic;FEA4 haitusquare;332A hakatakana;30CF hakatakanahalfwidth;FF8A halantgurmukhi;0A4D hamzaarabic;0621 hamzadammaarabic;0621 064F hamzadammatanarabic;0621 064C hamzafathaarabic;0621 064E hamzafathatanarabic;0621 064B hamzalowarabic;0621 hamzalowkasraarabic;0621 0650 hamzalowkasratanarabic;0621 064D hamzasukunarabic;0621 0652 hangulfiller;3164 hardsigncyrillic;044A harpoonleftbarbup;21BC harpoonrightbarbup;21C0 hasquare;33CA hatafpatah;05B2 hatafpatah16;05B2 hatafpatah23;05B2 hatafpatah2f;05B2 hatafpatahhebrew;05B2 hatafpatahnarrowhebrew;05B2 hatafpatahquarterhebrew;05B2 hatafpatahwidehebrew;05B2 hatafqamats;05B3 hatafqamats1b;05B3 hatafqamats28;05B3 hatafqamats34;05B3 hatafqamatshebrew;05B3 hatafqamatsnarrowhebrew;05B3 hatafqamatsquarterhebrew;05B3 hatafqamatswidehebrew;05B3 hatafsegol;05B1 hatafsegol17;05B1 hatafsegol24;05B1 hatafsegol30;05B1 hatafsegolhebrew;05B1 hatafsegolnarrowhebrew;05B1 hatafsegolquarterhebrew;05B1 hatafsegolwidehebrew;05B1 hbar;0127 hbopomofo;310F hbrevebelow;1E2B hcedilla;1E29 hcircle;24D7 hcircumflex;0125 hdieresis;1E27 hdotaccent;1E23 hdotbelow;1E25 he;05D4 heart;2665 heartsuitblack;2665 heartsuitwhite;2661 hedagesh;FB34 hedageshhebrew;FB34 hehaltonearabic;06C1 heharabic;0647 hehebrew;05D4 hehfinalaltonearabic;FBA7 hehfinalalttwoarabic;FEEA hehfinalarabic;FEEA hehhamzaabovefinalarabic;FBA5 hehhamzaaboveisolatedarabic;FBA4 hehinitialaltonearabic;FBA8 hehinitialarabic;FEEB hehiragana;3078 hehmedialaltonearabic;FBA9 hehmedialarabic;FEEC heiseierasquare;337B hekatakana;30D8 hekatakanahalfwidth;FF8D hekutaarusquare;3336 henghook;0267 herutusquare;3339 het;05D7 hethebrew;05D7 hhook;0266 hhooksuperior;02B1 hieuhacirclekorean;327B hieuhaparenkorean;321B hieuhcirclekorean;326D hieuhkorean;314E hieuhparenkorean;320D hihiragana;3072 hikatakana;30D2 hikatakanahalfwidth;FF8B hiriq;05B4 hiriq14;05B4 hiriq21;05B4 hiriq2d;05B4 hiriqhebrew;05B4 hiriqnarrowhebrew;05B4 hiriqquarterhebrew;05B4 hiriqwidehebrew;05B4 hlinebelow;1E96 hmonospace;FF48 hoarmenian;0570 hohipthai;0E2B hohiragana;307B hokatakana;30DB hokatakanahalfwidth;FF8E holam;05B9 holam19;05B9 holam26;05B9 holam32;05B9 holamhebrew;05B9 holamnarrowhebrew;05B9 holamquarterhebrew;05B9 holamwidehebrew;05B9 honokhukthai;0E2E hookabovecomb;0309 hookcmb;0309 hookpalatalizedbelowcmb;0321 hookretroflexbelowcmb;0322 hoonsquare;3342 horicoptic;03E9 horizontalbar;2015 horncmb;031B hotsprings;2668 house;2302 hparen;24A3 hsuperior;02B0 hturned;0265 huhiragana;3075 huiitosquare;3333 hukatakana;30D5 hukatakanahalfwidth;FF8C hungarumlaut;02DD hungarumlautcmb;030B hv;0195 hyphen;002D hypheninferior;F6E5 hyphenmonospace;FF0D hyphensmall;FE63 hyphensuperior;F6E6 hyphentwo;2010 i;0069 iacute;00ED iacyrillic;044F ibengali;0987 ibopomofo;3127 ibreve;012D icaron;01D0 icircle;24D8 icircumflex;00EE icyrillic;0456 idblgrave;0209 ideographearthcircle;328F ideographfirecircle;328B ideographicallianceparen;323F ideographiccallparen;323A ideographiccentrecircle;32A5 ideographicclose;3006 ideographiccomma;3001 ideographiccommaleft;FF64 ideographiccongratulationparen;3237 ideographiccorrectcircle;32A3 ideographicearthparen;322F ideographicenterpriseparen;323D ideographicexcellentcircle;329D ideographicfestivalparen;3240 ideographicfinancialcircle;3296 ideographicfinancialparen;3236 ideographicfireparen;322B ideographichaveparen;3232 ideographichighcircle;32A4 ideographiciterationmark;3005 ideographiclaborcircle;3298 ideographiclaborparen;3238 ideographicleftcircle;32A7 ideographiclowcircle;32A6 ideographicmedicinecircle;32A9 ideographicmetalparen;322E ideographicmoonparen;322A ideographicnameparen;3234 ideographicperiod;3002 ideographicprintcircle;329E ideographicreachparen;3243 ideographicrepresentparen;3239 ideographicresourceparen;323E ideographicrightcircle;32A8 ideographicsecretcircle;3299 ideographicselfparen;3242 ideographicsocietyparen;3233 ideographicspace;3000 ideographicspecialparen;3235 ideographicstockparen;3231 ideographicstudyparen;323B ideographicsunparen;3230 ideographicsuperviseparen;323C ideographicwaterparen;322C ideographicwoodparen;322D ideographiczero;3007 ideographmetalcircle;328E ideographmooncircle;328A ideographnamecircle;3294 ideographsuncircle;3290 ideographwatercircle;328C ideographwoodcircle;328D ideva;0907 idieresis;00EF idieresisacute;1E2F idieresiscyrillic;04E5 idotbelow;1ECB iebrevecyrillic;04D7 iecyrillic;0435 ieungacirclekorean;3275 ieungaparenkorean;3215 ieungcirclekorean;3267 ieungkorean;3147 ieungparenkorean;3207 igrave;00EC igujarati;0A87 igurmukhi;0A07 ihiragana;3044 ihookabove;1EC9 iibengali;0988 iicyrillic;0438 iideva;0908 iigujarati;0A88 iigurmukhi;0A08 iimatragurmukhi;0A40 iinvertedbreve;020B iishortcyrillic;0439 iivowelsignbengali;09C0 iivowelsigndeva;0940 iivowelsigngujarati;0AC0 ij;0133 ikatakana;30A4 ikatakanahalfwidth;FF72 ikorean;3163 ilde;02DC iluyhebrew;05AC imacron;012B imacroncyrillic;04E3 imageorapproximatelyequal;2253 imatragurmukhi;0A3F imonospace;FF49 increment;2206 infinity;221E iniarmenian;056B integral;222B integralbottom;2321 integralbt;2321 integralex;F8F5 integraltop;2320 integraltp;2320 intersection;2229 intisquare;3305 invbullet;25D8 invcircle;25D9 invsmileface;263B iocyrillic;0451 iogonek;012F iota;03B9 iotadieresis;03CA iotadieresistonos;0390 iotalatin;0269 iotatonos;03AF iparen;24A4 irigurmukhi;0A72 ismallhiragana;3043 ismallkatakana;30A3 ismallkatakanahalfwidth;FF68 issharbengali;09FA istroke;0268 isuperior;F6ED iterationhiragana;309D iterationkatakana;30FD itilde;0129 itildebelow;1E2D iubopomofo;3129 iucyrillic;044E ivowelsignbengali;09BF ivowelsigndeva;093F ivowelsigngujarati;0ABF izhitsacyrillic;0475 izhitsadblgravecyrillic;0477 j;006A jaarmenian;0571 jabengali;099C jadeva;091C jagujarati;0A9C jagurmukhi;0A1C jbopomofo;3110 jcaron;01F0 jcircle;24D9 jcircumflex;0135 jcrossedtail;029D jdotlessstroke;025F jecyrillic;0458 jeemarabic;062C jeemfinalarabic;FE9E jeeminitialarabic;FE9F jeemmedialarabic;FEA0 jeharabic;0698 jehfinalarabic;FB8B jhabengali;099D jhadeva;091D jhagujarati;0A9D jhagurmukhi;0A1D jheharmenian;057B jis;3004 jmonospace;FF4A jparen;24A5 jsuperior;02B2 k;006B kabashkircyrillic;04A1 kabengali;0995 kacute;1E31 kacyrillic;043A kadescendercyrillic;049B kadeva;0915 kaf;05DB kafarabic;0643 kafdagesh;FB3B kafdageshhebrew;FB3B kaffinalarabic;FEDA kafhebrew;05DB kafinitialarabic;FEDB kafmedialarabic;FEDC kafrafehebrew;FB4D kagujarati;0A95 kagurmukhi;0A15 kahiragana;304B kahookcyrillic;04C4 kakatakana;30AB kakatakanahalfwidth;FF76 kappa;03BA kappasymbolgreek;03F0 kapyeounmieumkorean;3171 kapyeounphieuphkorean;3184 kapyeounpieupkorean;3178 kapyeounssangpieupkorean;3179 karoriisquare;330D kashidaautoarabic;0640 kashidaautonosidebearingarabic;0640 kasmallkatakana;30F5 kasquare;3384 kasraarabic;0650 kasratanarabic;064D kastrokecyrillic;049F katahiraprolongmarkhalfwidth;FF70 kaverticalstrokecyrillic;049D kbopomofo;310E kcalsquare;3389 kcaron;01E9 kcedilla;0137 kcircle;24DA kcommaaccent;0137 kdotbelow;1E33 keharmenian;0584 kehiragana;3051 kekatakana;30B1 kekatakanahalfwidth;FF79 kenarmenian;056F kesmallkatakana;30F6 kgreenlandic;0138 khabengali;0996 khacyrillic;0445 khadeva;0916 khagujarati;0A96 khagurmukhi;0A16 khaharabic;062E khahfinalarabic;FEA6 khahinitialarabic;FEA7 khahmedialarabic;FEA8 kheicoptic;03E7 khhadeva;0959 khhagurmukhi;0A59 khieukhacirclekorean;3278 khieukhaparenkorean;3218 khieukhcirclekorean;326A khieukhkorean;314B khieukhparenkorean;320A khokhaithai;0E02 khokhonthai;0E05 khokhuatthai;0E03 khokhwaithai;0E04 khomutthai;0E5B khook;0199 khorakhangthai;0E06 khzsquare;3391 kihiragana;304D kikatakana;30AD kikatakanahalfwidth;FF77 kiroguramusquare;3315 kiromeetorusquare;3316 kirosquare;3314 kiyeokacirclekorean;326E kiyeokaparenkorean;320E kiyeokcirclekorean;3260 kiyeokkorean;3131 kiyeokparenkorean;3200 kiyeoksioskorean;3133 kjecyrillic;045C klinebelow;1E35 klsquare;3398 kmcubedsquare;33A6 kmonospace;FF4B kmsquaredsquare;33A2 kohiragana;3053 kohmsquare;33C0 kokaithai;0E01 kokatakana;30B3 kokatakanahalfwidth;FF7A kooposquare;331E koppacyrillic;0481 koreanstandardsymbol;327F koroniscmb;0343 kparen;24A6 kpasquare;33AA ksicyrillic;046F ktsquare;33CF kturned;029E kuhiragana;304F kukatakana;30AF kukatakanahalfwidth;FF78 kvsquare;33B8 kwsquare;33BE l;006C labengali;09B2 lacute;013A ladeva;0932 lagujarati;0AB2 lagurmukhi;0A32 lakkhangyaothai;0E45 lamaleffinalarabic;FEFC lamalefhamzaabovefinalarabic;FEF8 lamalefhamzaaboveisolatedarabic;FEF7 lamalefhamzabelowfinalarabic;FEFA lamalefhamzabelowisolatedarabic;FEF9 lamalefisolatedarabic;FEFB lamalefmaddaabovefinalarabic;FEF6 lamalefmaddaaboveisolatedarabic;FEF5 lamarabic;0644 lambda;03BB lambdastroke;019B lamed;05DC lameddagesh;FB3C lameddageshhebrew;FB3C lamedhebrew;05DC lamedholam;05DC 05B9 lamedholamdagesh;05DC 05B9 05BC lamedholamdageshhebrew;05DC 05B9 05BC lamedholamhebrew;05DC 05B9 lamfinalarabic;FEDE lamhahinitialarabic;FCCA laminitialarabic;FEDF lamjeeminitialarabic;FCC9 lamkhahinitialarabic;FCCB lamlamhehisolatedarabic;FDF2 lammedialarabic;FEE0 lammeemhahinitialarabic;FD88 lammeeminitialarabic;FCCC lammeemjeeminitialarabic;FEDF FEE4 FEA0 lammeemkhahinitialarabic;FEDF FEE4 FEA8 largecircle;25EF lbar;019A lbelt;026C lbopomofo;310C lcaron;013E lcedilla;013C lcircle;24DB lcircumflexbelow;1E3D lcommaaccent;013C ldot;0140 ldotaccent;0140 ldotbelow;1E37 ldotbelowmacron;1E39 leftangleabovecmb;031A lefttackbelowcmb;0318 less;003C lessequal;2264 lessequalorgreater;22DA lessmonospace;FF1C lessorequivalent;2272 lessorgreater;2276 lessoverequal;2266 lesssmall;FE64 lezh;026E lfblock;258C lhookretroflex;026D lira;20A4 liwnarmenian;056C lj;01C9 ljecyrillic;0459 ll;F6C0 lladeva;0933 llagujarati;0AB3 llinebelow;1E3B llladeva;0934 llvocalicbengali;09E1 llvocalicdeva;0961 llvocalicvowelsignbengali;09E3 llvocalicvowelsigndeva;0963 lmiddletilde;026B lmonospace;FF4C lmsquare;33D0 lochulathai;0E2C logicaland;2227 logicalnot;00AC logicalnotreversed;2310 logicalor;2228 lolingthai;0E25 longs;017F lowlinecenterline;FE4E lowlinecmb;0332 lowlinedashed;FE4D lozenge;25CA lparen;24A7 lslash;0142 lsquare;2113 lsuperior;F6EE ltshade;2591 luthai;0E26 lvocalicbengali;098C lvocalicdeva;090C lvocalicvowelsignbengali;09E2 lvocalicvowelsigndeva;0962 lxsquare;33D3 m;006D mabengali;09AE macron;00AF macronbelowcmb;0331 macroncmb;0304 macronlowmod;02CD macronmonospace;FFE3 macute;1E3F madeva;092E magujarati;0AAE magurmukhi;0A2E mahapakhhebrew;05A4 mahapakhlefthebrew;05A4 mahiragana;307E maichattawalowleftthai;F895 maichattawalowrightthai;F894 maichattawathai;0E4B maichattawaupperleftthai;F893 maieklowleftthai;F88C maieklowrightthai;F88B maiekthai;0E48 maiekupperleftthai;F88A maihanakatleftthai;F884 maihanakatthai;0E31 maitaikhuleftthai;F889 maitaikhuthai;0E47 maitholowleftthai;F88F maitholowrightthai;F88E maithothai;0E49 maithoupperleftthai;F88D maitrilowleftthai;F892 maitrilowrightthai;F891 maitrithai;0E4A maitriupperleftthai;F890 maiyamokthai;0E46 makatakana;30DE makatakanahalfwidth;FF8F male;2642 mansyonsquare;3347 maqafhebrew;05BE mars;2642 masoracirclehebrew;05AF masquare;3383 mbopomofo;3107 mbsquare;33D4 mcircle;24DC mcubedsquare;33A5 mdotaccent;1E41 mdotbelow;1E43 meemarabic;0645 meemfinalarabic;FEE2 meeminitialarabic;FEE3 meemmedialarabic;FEE4 meemmeeminitialarabic;FCD1 meemmeemisolatedarabic;FC48 meetorusquare;334D mehiragana;3081 meizierasquare;337E mekatakana;30E1 mekatakanahalfwidth;FF92 mem;05DE memdagesh;FB3E memdageshhebrew;FB3E memhebrew;05DE menarmenian;0574 merkhahebrew;05A5 merkhakefulahebrew;05A6 merkhakefulalefthebrew;05A6 merkhalefthebrew;05A5 mhook;0271 mhzsquare;3392 middledotkatakanahalfwidth;FF65 middot;00B7 mieumacirclekorean;3272 mieumaparenkorean;3212 mieumcirclekorean;3264 mieumkorean;3141 mieumpansioskorean;3170 mieumparenkorean;3204 mieumpieupkorean;316E mieumsioskorean;316F mihiragana;307F mikatakana;30DF mikatakanahalfwidth;FF90 minus;2212 minusbelowcmb;0320 minuscircle;2296 minusmod;02D7 minusplus;2213 minute;2032 miribaarusquare;334A mirisquare;3349 mlonglegturned;0270 mlsquare;3396 mmcubedsquare;33A3 mmonospace;FF4D mmsquaredsquare;339F mohiragana;3082 mohmsquare;33C1 mokatakana;30E2 mokatakanahalfwidth;FF93 molsquare;33D6 momathai;0E21 moverssquare;33A7 moverssquaredsquare;33A8 mparen;24A8 mpasquare;33AB mssquare;33B3 msuperior;F6EF mturned;026F mu;00B5 mu1;00B5 muasquare;3382 muchgreater;226B muchless;226A mufsquare;338C mugreek;03BC mugsquare;338D muhiragana;3080 mukatakana;30E0 mukatakanahalfwidth;FF91 mulsquare;3395 multiply;00D7 mumsquare;339B munahhebrew;05A3 munahlefthebrew;05A3 musicalnote;266A musicalnotedbl;266B musicflatsign;266D musicsharpsign;266F mussquare;33B2 muvsquare;33B6 muwsquare;33BC mvmegasquare;33B9 mvsquare;33B7 mwmegasquare;33BF mwsquare;33BD n;006E nabengali;09A8 nabla;2207 nacute;0144 nadeva;0928 nagujarati;0AA8 nagurmukhi;0A28 nahiragana;306A nakatakana;30CA nakatakanahalfwidth;FF85 napostrophe;0149 nasquare;3381 nbopomofo;310B nbspace;00A0 ncaron;0148 ncedilla;0146 ncircle;24DD ncircumflexbelow;1E4B ncommaaccent;0146 ndotaccent;1E45 ndotbelow;1E47 nehiragana;306D nekatakana;30CD nekatakanahalfwidth;FF88 newsheqelsign;20AA nfsquare;338B ngabengali;0999 ngadeva;0919 ngagujarati;0A99 ngagurmukhi;0A19 ngonguthai;0E07 nhiragana;3093 nhookleft;0272 nhookretroflex;0273 nieunacirclekorean;326F nieunaparenkorean;320F nieuncieuckorean;3135 nieuncirclekorean;3261 nieunhieuhkorean;3136 nieunkorean;3134 nieunpansioskorean;3168 nieunparenkorean;3201 nieunsioskorean;3167 nieuntikeutkorean;3166 nihiragana;306B nikatakana;30CB nikatakanahalfwidth;FF86 nikhahitleftthai;F899 nikhahitthai;0E4D nine;0039 ninearabic;0669 ninebengali;09EF ninecircle;2468 ninecircleinversesansserif;2792 ninedeva;096F ninegujarati;0AEF ninegurmukhi;0A6F ninehackarabic;0669 ninehangzhou;3029 nineideographicparen;3228 nineinferior;2089 ninemonospace;FF19 nineoldstyle;F739 nineparen;247C nineperiod;2490 ninepersian;06F9 nineroman;2178 ninesuperior;2079 nineteencircle;2472 nineteenparen;2486 nineteenperiod;249A ninethai;0E59 nj;01CC njecyrillic;045A nkatakana;30F3 nkatakanahalfwidth;FF9D nlegrightlong;019E nlinebelow;1E49 nmonospace;FF4E nmsquare;339A nnabengali;09A3 nnadeva;0923 nnagujarati;0AA3 nnagurmukhi;0A23 nnnadeva;0929 nohiragana;306E nokatakana;30CE nokatakanahalfwidth;FF89 nonbreakingspace;00A0 nonenthai;0E13 nonuthai;0E19 noonarabic;0646 noonfinalarabic;FEE6 noonghunnaarabic;06BA noonghunnafinalarabic;FB9F noonhehinitialarabic;FEE7 FEEC nooninitialarabic;FEE7 noonjeeminitialarabic;FCD2 noonjeemisolatedarabic;FC4B noonmedialarabic;FEE8 noonmeeminitialarabic;FCD5 noonmeemisolatedarabic;FC4E noonnoonfinalarabic;FC8D notcontains;220C notelement;2209 notelementof;2209 notequal;2260 notgreater;226F notgreaternorequal;2271 notgreaternorless;2279 notidentical;2262 notless;226E notlessnorequal;2270 notparallel;2226 notprecedes;2280 notsubset;2284 notsucceeds;2281 notsuperset;2285 nowarmenian;0576 nparen;24A9 nssquare;33B1 nsuperior;207F ntilde;00F1 nu;03BD nuhiragana;306C nukatakana;30CC nukatakanahalfwidth;FF87 nuktabengali;09BC nuktadeva;093C nuktagujarati;0ABC nuktagurmukhi;0A3C numbersign;0023 numbersignmonospace;FF03 numbersignsmall;FE5F numeralsigngreek;0374 numeralsignlowergreek;0375 numero;2116 nun;05E0 nundagesh;FB40 nundageshhebrew;FB40 nunhebrew;05E0 nvsquare;33B5 nwsquare;33BB nyabengali;099E nyadeva;091E nyagujarati;0A9E nyagurmukhi;0A1E o;006F oacute;00F3 oangthai;0E2D obarred;0275 obarredcyrillic;04E9 obarreddieresiscyrillic;04EB obengali;0993 obopomofo;311B obreve;014F ocandradeva;0911 ocandragujarati;0A91 ocandravowelsigndeva;0949 ocandravowelsigngujarati;0AC9 ocaron;01D2 ocircle;24DE ocircumflex;00F4 ocircumflexacute;1ED1 ocircumflexdotbelow;1ED9 ocircumflexgrave;1ED3 ocircumflexhookabove;1ED5 ocircumflextilde;1ED7 ocyrillic;043E odblacute;0151 odblgrave;020D odeva;0913 odieresis;00F6 odieresiscyrillic;04E7 odotbelow;1ECD oe;0153 oekorean;315A ogonek;02DB ogonekcmb;0328 ograve;00F2 ogujarati;0A93 oharmenian;0585 ohiragana;304A ohookabove;1ECF ohorn;01A1 ohornacute;1EDB ohorndotbelow;1EE3 ohorngrave;1EDD ohornhookabove;1EDF ohorntilde;1EE1 ohungarumlaut;0151 oi;01A3 oinvertedbreve;020F okatakana;30AA okatakanahalfwidth;FF75 okorean;3157 olehebrew;05AB omacron;014D omacronacute;1E53 omacrongrave;1E51 omdeva;0950 omega;03C9 omega1;03D6 omegacyrillic;0461 omegalatinclosed;0277 omegaroundcyrillic;047B omegatitlocyrillic;047D omegatonos;03CE omgujarati;0AD0 omicron;03BF omicrontonos;03CC omonospace;FF4F one;0031 onearabic;0661 onebengali;09E7 onecircle;2460 onecircleinversesansserif;278A onedeva;0967 onedotenleader;2024 oneeighth;215B onefitted;F6DC onegujarati;0AE7 onegurmukhi;0A67 onehackarabic;0661 onehalf;00BD onehangzhou;3021 oneideographicparen;3220 oneinferior;2081 onemonospace;FF11 onenumeratorbengali;09F4 oneoldstyle;F731 oneparen;2474 oneperiod;2488 onepersian;06F1 onequarter;00BC oneroman;2170 onesuperior;00B9 onethai;0E51 onethird;2153 oogonek;01EB oogonekmacron;01ED oogurmukhi;0A13 oomatragurmukhi;0A4B oopen;0254 oparen;24AA openbullet;25E6 option;2325 ordfeminine;00AA ordmasculine;00BA orthogonal;221F oshortdeva;0912 oshortvowelsigndeva;094A oslash;00F8 oslashacute;01FF osmallhiragana;3049 osmallkatakana;30A9 osmallkatakanahalfwidth;FF6B ostrokeacute;01FF osuperior;F6F0 otcyrillic;047F otilde;00F5 otildeacute;1E4D otildedieresis;1E4F oubopomofo;3121 overline;203E overlinecenterline;FE4A overlinecmb;0305 overlinedashed;FE49 overlinedblwavy;FE4C overlinewavy;FE4B overscore;00AF ovowelsignbengali;09CB ovowelsigndeva;094B ovowelsigngujarati;0ACB p;0070 paampssquare;3380 paasentosquare;332B pabengali;09AA pacute;1E55 padeva;092A pagedown;21DF pageup;21DE pagujarati;0AAA pagurmukhi;0A2A pahiragana;3071 paiyannoithai;0E2F pakatakana;30D1 palatalizationcyrilliccmb;0484 palochkacyrillic;04C0 pansioskorean;317F paragraph;00B6 parallel;2225 parenleft;0028 parenleftaltonearabic;FD3E parenleftbt;F8ED parenleftex;F8EC parenleftinferior;208D parenleftmonospace;FF08 parenleftsmall;FE59 parenleftsuperior;207D parenlefttp;F8EB parenleftvertical;FE35 parenright;0029 parenrightaltonearabic;FD3F parenrightbt;F8F8 parenrightex;F8F7 parenrightinferior;208E parenrightmonospace;FF09 parenrightsmall;FE5A parenrightsuperior;207E parenrighttp;F8F6 parenrightvertical;FE36 partialdiff;2202 paseqhebrew;05C0 pashtahebrew;0599 pasquare;33A9 patah;05B7 patah11;05B7 patah1d;05B7 patah2a;05B7 patahhebrew;05B7 patahnarrowhebrew;05B7 patahquarterhebrew;05B7 patahwidehebrew;05B7 pazerhebrew;05A1 pbopomofo;3106 pcircle;24DF pdotaccent;1E57 pe;05E4 pecyrillic;043F pedagesh;FB44 pedageshhebrew;FB44 peezisquare;333B pefinaldageshhebrew;FB43 peharabic;067E peharmenian;057A pehebrew;05E4 pehfinalarabic;FB57 pehinitialarabic;FB58 pehiragana;307A pehmedialarabic;FB59 pekatakana;30DA pemiddlehookcyrillic;04A7 perafehebrew;FB4E percent;0025 percentarabic;066A percentmonospace;FF05 percentsmall;FE6A period;002E periodarmenian;0589 periodcentered;00B7 periodhalfwidth;FF61 periodinferior;F6E7 periodmonospace;FF0E periodsmall;FE52 periodsuperior;F6E8 perispomenigreekcmb;0342 perpendicular;22A5 perthousand;2030 peseta;20A7 pfsquare;338A phabengali;09AB phadeva;092B phagujarati;0AAB phagurmukhi;0A2B phi;03C6 phi1;03D5 phieuphacirclekorean;327A phieuphaparenkorean;321A phieuphcirclekorean;326C phieuphkorean;314D phieuphparenkorean;320C philatin;0278 phinthuthai;0E3A phisymbolgreek;03D5 phook;01A5 phophanthai;0E1E phophungthai;0E1C phosamphaothai;0E20 pi;03C0 pieupacirclekorean;3273 pieupaparenkorean;3213 pieupcieuckorean;3176 pieupcirclekorean;3265 pieupkiyeokkorean;3172 pieupkorean;3142 pieupparenkorean;3205 pieupsioskiyeokkorean;3174 pieupsioskorean;3144 pieupsiostikeutkorean;3175 pieupthieuthkorean;3177 pieuptikeutkorean;3173 pihiragana;3074 pikatakana;30D4 pisymbolgreek;03D6 piwrarmenian;0583 plus;002B plusbelowcmb;031F pluscircle;2295 plusminus;00B1 plusmod;02D6 plusmonospace;FF0B plussmall;FE62 plussuperior;207A pmonospace;FF50 pmsquare;33D8 pohiragana;307D pointingindexdownwhite;261F pointingindexleftwhite;261C pointingindexrightwhite;261E pointingindexupwhite;261D pokatakana;30DD poplathai;0E1B postalmark;3012 postalmarkface;3020 pparen;24AB precedes;227A prescription;211E primemod;02B9 primereversed;2035 product;220F projective;2305 prolongedkana;30FC propellor;2318 propersubset;2282 propersuperset;2283 proportion;2237 proportional;221D psi;03C8 psicyrillic;0471 psilipneumatacyrilliccmb;0486 pssquare;33B0 puhiragana;3077 pukatakana;30D7 pvsquare;33B4 pwsquare;33BA q;0071 qadeva;0958 qadmahebrew;05A8 qafarabic;0642 qaffinalarabic;FED6 qafinitialarabic;FED7 qafmedialarabic;FED8 qamats;05B8 qamats10;05B8 qamats1a;05B8 qamats1c;05B8 qamats27;05B8 qamats29;05B8 qamats33;05B8 qamatsde;05B8 qamatshebrew;05B8 qamatsnarrowhebrew;05B8 qamatsqatanhebrew;05B8 qamatsqatannarrowhebrew;05B8 qamatsqatanquarterhebrew;05B8 qamatsqatanwidehebrew;05B8 qamatsquarterhebrew;05B8 qamatswidehebrew;05B8 qarneyparahebrew;059F qbopomofo;3111 qcircle;24E0 qhook;02A0 qmonospace;FF51 qof;05E7 qofdagesh;FB47 qofdageshhebrew;FB47 qofhatafpatah;05E7 05B2 qofhatafpatahhebrew;05E7 05B2 qofhatafsegol;05E7 05B1 qofhatafsegolhebrew;05E7 05B1 qofhebrew;05E7 qofhiriq;05E7 05B4 qofhiriqhebrew;05E7 05B4 qofholam;05E7 05B9 qofholamhebrew;05E7 05B9 qofpatah;05E7 05B7 qofpatahhebrew;05E7 05B7 qofqamats;05E7 05B8 qofqamatshebrew;05E7 05B8 qofqubuts;05E7 05BB qofqubutshebrew;05E7 05BB qofsegol;05E7 05B6 qofsegolhebrew;05E7 05B6 qofsheva;05E7 05B0 qofshevahebrew;05E7 05B0 qoftsere;05E7 05B5 qoftserehebrew;05E7 05B5 qparen;24AC quarternote;2669 qubuts;05BB qubuts18;05BB qubuts25;05BB qubuts31;05BB qubutshebrew;05BB qubutsnarrowhebrew;05BB qubutsquarterhebrew;05BB qubutswidehebrew;05BB question;003F questionarabic;061F questionarmenian;055E questiondown;00BF questiondownsmall;F7BF questiongreek;037E questionmonospace;FF1F questionsmall;F73F quotedbl;0022 quotedblbase;201E quotedblleft;201C quotedblmonospace;FF02 quotedblprime;301E quotedblprimereversed;301D quotedblright;201D quoteleft;2018 quoteleftreversed;201B quotereversed;201B quoteright;2019 quoterightn;0149 quotesinglbase;201A quotesingle;0027 quotesinglemonospace;FF07 r;0072 raarmenian;057C rabengali;09B0 racute;0155 radeva;0930 radical;221A radicalex;F8E5 radoverssquare;33AE radoverssquaredsquare;33AF radsquare;33AD rafe;05BF rafehebrew;05BF ragujarati;0AB0 ragurmukhi;0A30 rahiragana;3089 rakatakana;30E9 rakatakanahalfwidth;FF97 ralowerdiagonalbengali;09F1 ramiddlediagonalbengali;09F0 ramshorn;0264 ratio;2236 rbopomofo;3116 rcaron;0159 rcedilla;0157 rcircle;24E1 rcommaaccent;0157 rdblgrave;0211 rdotaccent;1E59 rdotbelow;1E5B rdotbelowmacron;1E5D referencemark;203B reflexsubset;2286 reflexsuperset;2287 registered;00AE registersans;F8E8 registerserif;F6DA reharabic;0631 reharmenian;0580 rehfinalarabic;FEAE rehiragana;308C rehyehaleflamarabic;0631 FEF3 FE8E 0644 rekatakana;30EC rekatakanahalfwidth;FF9A resh;05E8 reshdageshhebrew;FB48 reshhatafpatah;05E8 05B2 reshhatafpatahhebrew;05E8 05B2 reshhatafsegol;05E8 05B1 reshhatafsegolhebrew;05E8 05B1 reshhebrew;05E8 reshhiriq;05E8 05B4 reshhiriqhebrew;05E8 05B4 reshholam;05E8 05B9 reshholamhebrew;05E8 05B9 reshpatah;05E8 05B7 reshpatahhebrew;05E8 05B7 reshqamats;05E8 05B8 reshqamatshebrew;05E8 05B8 reshqubuts;05E8 05BB reshqubutshebrew;05E8 05BB reshsegol;05E8 05B6 reshsegolhebrew;05E8 05B6 reshsheva;05E8 05B0 reshshevahebrew;05E8 05B0 reshtsere;05E8 05B5 reshtserehebrew;05E8 05B5 reversedtilde;223D reviahebrew;0597 reviamugrashhebrew;0597 revlogicalnot;2310 rfishhook;027E rfishhookreversed;027F rhabengali;09DD rhadeva;095D rho;03C1 rhook;027D rhookturned;027B rhookturnedsuperior;02B5 rhosymbolgreek;03F1 rhotichookmod;02DE rieulacirclekorean;3271 rieulaparenkorean;3211 rieulcirclekorean;3263 rieulhieuhkorean;3140 rieulkiyeokkorean;313A rieulkiyeoksioskorean;3169 rieulkorean;3139 rieulmieumkorean;313B rieulpansioskorean;316C rieulparenkorean;3203 rieulphieuphkorean;313F rieulpieupkorean;313C rieulpieupsioskorean;316B rieulsioskorean;313D rieulthieuthkorean;313E rieultikeutkorean;316A rieulyeorinhieuhkorean;316D rightangle;221F righttackbelowcmb;0319 righttriangle;22BF rihiragana;308A rikatakana;30EA rikatakanahalfwidth;FF98 ring;02DA ringbelowcmb;0325 ringcmb;030A ringhalfleft;02BF ringhalfleftarmenian;0559 ringhalfleftbelowcmb;031C ringhalfleftcentered;02D3 ringhalfright;02BE ringhalfrightbelowcmb;0339 ringhalfrightcentered;02D2 rinvertedbreve;0213 rittorusquare;3351 rlinebelow;1E5F rlongleg;027C rlonglegturned;027A rmonospace;FF52 rohiragana;308D rokatakana;30ED rokatakanahalfwidth;FF9B roruathai;0E23 rparen;24AD rrabengali;09DC rradeva;0931 rragurmukhi;0A5C rreharabic;0691 rrehfinalarabic;FB8D rrvocalicbengali;09E0 rrvocalicdeva;0960 rrvocalicgujarati;0AE0 rrvocalicvowelsignbengali;09C4 rrvocalicvowelsigndeva;0944 rrvocalicvowelsigngujarati;0AC4 rsuperior;F6F1 rtblock;2590 rturned;0279 rturnedsuperior;02B4 ruhiragana;308B rukatakana;30EB rukatakanahalfwidth;FF99 rupeemarkbengali;09F2 rupeesignbengali;09F3 rupiah;F6DD ruthai;0E24 rvocalicbengali;098B rvocalicdeva;090B rvocalicgujarati;0A8B rvocalicvowelsignbengali;09C3 rvocalicvowelsigndeva;0943 rvocalicvowelsigngujarati;0AC3 s;0073 sabengali;09B8 sacute;015B sacutedotaccent;1E65 sadarabic;0635 sadeva;0938 sadfinalarabic;FEBA sadinitialarabic;FEBB sadmedialarabic;FEBC sagujarati;0AB8 sagurmukhi;0A38 sahiragana;3055 sakatakana;30B5 sakatakanahalfwidth;FF7B sallallahoualayhewasallamarabic;FDFA samekh;05E1 samekhdagesh;FB41 samekhdageshhebrew;FB41 samekhhebrew;05E1 saraaathai;0E32 saraaethai;0E41 saraaimaimalaithai;0E44 saraaimaimuanthai;0E43 saraamthai;0E33 saraathai;0E30 saraethai;0E40 saraiileftthai;F886 saraiithai;0E35 saraileftthai;F885 saraithai;0E34 saraothai;0E42 saraueeleftthai;F888 saraueethai;0E37 saraueleftthai;F887 sarauethai;0E36 sarauthai;0E38 sarauuthai;0E39 sbopomofo;3119 scaron;0161 scarondotaccent;1E67 scedilla;015F schwa;0259 schwacyrillic;04D9 schwadieresiscyrillic;04DB schwahook;025A scircle;24E2 scircumflex;015D scommaaccent;0219 sdotaccent;1E61 sdotbelow;1E63 sdotbelowdotaccent;1E69 seagullbelowcmb;033C second;2033 secondtonechinese;02CA section;00A7 seenarabic;0633 seenfinalarabic;FEB2 seeninitialarabic;FEB3 seenmedialarabic;FEB4 segol;05B6 segol13;05B6 segol1f;05B6 segol2c;05B6 segolhebrew;05B6 segolnarrowhebrew;05B6 segolquarterhebrew;05B6 segoltahebrew;0592 segolwidehebrew;05B6 seharmenian;057D sehiragana;305B sekatakana;30BB sekatakanahalfwidth;FF7E semicolon;003B semicolonarabic;061B semicolonmonospace;FF1B semicolonsmall;FE54 semivoicedmarkkana;309C semivoicedmarkkanahalfwidth;FF9F sentisquare;3322 sentosquare;3323 seven;0037 sevenarabic;0667 sevenbengali;09ED sevencircle;2466 sevencircleinversesansserif;2790 sevendeva;096D seveneighths;215E sevengujarati;0AED sevengurmukhi;0A6D sevenhackarabic;0667 sevenhangzhou;3027 sevenideographicparen;3226 seveninferior;2087 sevenmonospace;FF17 sevenoldstyle;F737 sevenparen;247A sevenperiod;248E sevenpersian;06F7 sevenroman;2176 sevensuperior;2077 seventeencircle;2470 seventeenparen;2484 seventeenperiod;2498 seventhai;0E57 sfthyphen;00AD shaarmenian;0577 shabengali;09B6 shacyrillic;0448 shaddaarabic;0651 shaddadammaarabic;FC61 shaddadammatanarabic;FC5E shaddafathaarabic;FC60 shaddafathatanarabic;0651 064B shaddakasraarabic;FC62 shaddakasratanarabic;FC5F shade;2592 shadedark;2593 shadelight;2591 shademedium;2592 shadeva;0936 shagujarati;0AB6 shagurmukhi;0A36 shalshelethebrew;0593 shbopomofo;3115 shchacyrillic;0449 sheenarabic;0634 sheenfinalarabic;FEB6 sheeninitialarabic;FEB7 sheenmedialarabic;FEB8 sheicoptic;03E3 sheqel;20AA sheqelhebrew;20AA sheva;05B0 sheva115;05B0 sheva15;05B0 sheva22;05B0 sheva2e;05B0 shevahebrew;05B0 shevanarrowhebrew;05B0 shevaquarterhebrew;05B0 shevawidehebrew;05B0 shhacyrillic;04BB shimacoptic;03ED shin;05E9 shindagesh;FB49 shindageshhebrew;FB49 shindageshshindot;FB2C shindageshshindothebrew;FB2C shindageshsindot;FB2D shindageshsindothebrew;FB2D shindothebrew;05C1 shinhebrew;05E9 shinshindot;FB2A shinshindothebrew;FB2A shinsindot;FB2B shinsindothebrew;FB2B shook;0282 sigma;03C3 sigma1;03C2 sigmafinal;03C2 sigmalunatesymbolgreek;03F2 sihiragana;3057 sikatakana;30B7 sikatakanahalfwidth;FF7C siluqhebrew;05BD siluqlefthebrew;05BD similar;223C sindothebrew;05C2 siosacirclekorean;3274 siosaparenkorean;3214 sioscieuckorean;317E sioscirclekorean;3266 sioskiyeokkorean;317A sioskorean;3145 siosnieunkorean;317B siosparenkorean;3206 siospieupkorean;317D siostikeutkorean;317C six;0036 sixarabic;0666 sixbengali;09EC sixcircle;2465 sixcircleinversesansserif;278F sixdeva;096C sixgujarati;0AEC sixgurmukhi;0A6C sixhackarabic;0666 sixhangzhou;3026 sixideographicparen;3225 sixinferior;2086 sixmonospace;FF16 sixoldstyle;F736 sixparen;2479 sixperiod;248D sixpersian;06F6 sixroman;2175 sixsuperior;2076 sixteencircle;246F sixteencurrencydenominatorbengali;09F9 sixteenparen;2483 sixteenperiod;2497 sixthai;0E56 slash;002F slashmonospace;FF0F slong;017F slongdotaccent;1E9B smileface;263A smonospace;FF53 sofpasuqhebrew;05C3 softhyphen;00AD softsigncyrillic;044C sohiragana;305D sokatakana;30BD sokatakanahalfwidth;FF7F soliduslongoverlaycmb;0338 solidusshortoverlaycmb;0337 sorusithai;0E29 sosalathai;0E28 sosothai;0E0B sosuathai;0E2A space;0020 spacehackarabic;0020 spade;2660 spadesuitblack;2660 spadesuitwhite;2664 sparen;24AE squarebelowcmb;033B squarecc;33C4 squarecm;339D squarediagonalcrosshatchfill;25A9 squarehorizontalfill;25A4 squarekg;338F squarekm;339E squarekmcapital;33CE squareln;33D1 squarelog;33D2 squaremg;338E squaremil;33D5 squaremm;339C squaremsquared;33A1 squareorthogonalcrosshatchfill;25A6 squareupperlefttolowerrightfill;25A7 squareupperrighttolowerleftfill;25A8 squareverticalfill;25A5 squarewhitewithsmallblack;25A3 srsquare;33DB ssabengali;09B7 ssadeva;0937 ssagujarati;0AB7 ssangcieuckorean;3149 ssanghieuhkorean;3185 ssangieungkorean;3180 ssangkiyeokkorean;3132 ssangnieunkorean;3165 ssangpieupkorean;3143 ssangsioskorean;3146 ssangtikeutkorean;3138 ssuperior;F6F2 sterling;00A3 sterlingmonospace;FFE1 strokelongoverlaycmb;0336 strokeshortoverlaycmb;0335 subset;2282 subsetnotequal;228A subsetorequal;2286 succeeds;227B suchthat;220B suhiragana;3059 sukatakana;30B9 sukatakanahalfwidth;FF7D sukunarabic;0652 summation;2211 sun;263C superset;2283 supersetnotequal;228B supersetorequal;2287 svsquare;33DC syouwaerasquare;337C t;0074 tabengali;09A4 tackdown;22A4 tackleft;22A3 tadeva;0924 tagujarati;0AA4 tagurmukhi;0A24 taharabic;0637 tahfinalarabic;FEC2 tahinitialarabic;FEC3 tahiragana;305F tahmedialarabic;FEC4 taisyouerasquare;337D takatakana;30BF takatakanahalfwidth;FF80 tatweelarabic;0640 tau;03C4 tav;05EA tavdages;FB4A tavdagesh;FB4A tavdageshhebrew;FB4A tavhebrew;05EA tbar;0167 tbopomofo;310A tcaron;0165 tccurl;02A8 tcedilla;0163 tcheharabic;0686 tchehfinalarabic;FB7B tchehinitialarabic;FB7C tchehmedialarabic;FB7D tchehmeeminitialarabic;FB7C FEE4 tcircle;24E3 tcircumflexbelow;1E71 tcommaaccent;0163 tdieresis;1E97 tdotaccent;1E6B tdotbelow;1E6D tecyrillic;0442 tedescendercyrillic;04AD teharabic;062A tehfinalarabic;FE96 tehhahinitialarabic;FCA2 tehhahisolatedarabic;FC0C tehinitialarabic;FE97 tehiragana;3066 tehjeeminitialarabic;FCA1 tehjeemisolatedarabic;FC0B tehmarbutaarabic;0629 tehmarbutafinalarabic;FE94 tehmedialarabic;FE98 tehmeeminitialarabic;FCA4 tehmeemisolatedarabic;FC0E tehnoonfinalarabic;FC73 tekatakana;30C6 tekatakanahalfwidth;FF83 telephone;2121 telephoneblack;260E telishagedolahebrew;05A0 telishaqetanahebrew;05A9 tencircle;2469 tenideographicparen;3229 tenparen;247D tenperiod;2491 tenroman;2179 tesh;02A7 tet;05D8 tetdagesh;FB38 tetdageshhebrew;FB38 tethebrew;05D8 tetsecyrillic;04B5 tevirhebrew;059B tevirlefthebrew;059B thabengali;09A5 thadeva;0925 thagujarati;0AA5 thagurmukhi;0A25 thalarabic;0630 thalfinalarabic;FEAC thanthakhatlowleftthai;F898 thanthakhatlowrightthai;F897 thanthakhatthai;0E4C thanthakhatupperleftthai;F896 theharabic;062B thehfinalarabic;FE9A thehinitialarabic;FE9B thehmedialarabic;FE9C thereexists;2203 therefore;2234 theta;03B8 theta1;03D1 thetasymbolgreek;03D1 thieuthacirclekorean;3279 thieuthaparenkorean;3219 thieuthcirclekorean;326B thieuthkorean;314C thieuthparenkorean;320B thirteencircle;246C thirteenparen;2480 thirteenperiod;2494 thonangmonthothai;0E11 thook;01AD thophuthaothai;0E12 thorn;00FE thothahanthai;0E17 thothanthai;0E10 thothongthai;0E18 thothungthai;0E16 thousandcyrillic;0482 thousandsseparatorarabic;066C thousandsseparatorpersian;066C three;0033 threearabic;0663 threebengali;09E9 threecircle;2462 threecircleinversesansserif;278C threedeva;0969 threeeighths;215C threegujarati;0AE9 threegurmukhi;0A69 threehackarabic;0663 threehangzhou;3023 threeideographicparen;3222 threeinferior;2083 threemonospace;FF13 threenumeratorbengali;09F6 threeoldstyle;F733 threeparen;2476 threeperiod;248A threepersian;06F3 threequarters;00BE threequartersemdash;F6DE threeroman;2172 threesuperior;00B3 threethai;0E53 thzsquare;3394 tihiragana;3061 tikatakana;30C1 tikatakanahalfwidth;FF81 tikeutacirclekorean;3270 tikeutaparenkorean;3210 tikeutcirclekorean;3262 tikeutkorean;3137 tikeutparenkorean;3202 tilde;02DC tildebelowcmb;0330 tildecmb;0303 tildecomb;0303 tildedoublecmb;0360 tildeoperator;223C tildeoverlaycmb;0334 tildeverticalcmb;033E timescircle;2297 tipehahebrew;0596 tipehalefthebrew;0596 tippigurmukhi;0A70 titlocyrilliccmb;0483 tiwnarmenian;057F tlinebelow;1E6F tmonospace;FF54 toarmenian;0569 tohiragana;3068 tokatakana;30C8 tokatakanahalfwidth;FF84 tonebarextrahighmod;02E5 tonebarextralowmod;02E9 tonebarhighmod;02E6 tonebarlowmod;02E8 tonebarmidmod;02E7 tonefive;01BD tonesix;0185 tonetwo;01A8 tonos;0384 tonsquare;3327 topatakthai;0E0F tortoiseshellbracketleft;3014 tortoiseshellbracketleftsmall;FE5D tortoiseshellbracketleftvertical;FE39 tortoiseshellbracketright;3015 tortoiseshellbracketrightsmall;FE5E tortoiseshellbracketrightvertical;FE3A totaothai;0E15 tpalatalhook;01AB tparen;24AF trademark;2122 trademarksans;F8EA trademarkserif;F6DB tretroflexhook;0288 triagdn;25BC triaglf;25C4 triagrt;25BA triagup;25B2 ts;02A6 tsadi;05E6 tsadidagesh;FB46 tsadidageshhebrew;FB46 tsadihebrew;05E6 tsecyrillic;0446 tsere;05B5 tsere12;05B5 tsere1e;05B5 tsere2b;05B5 tserehebrew;05B5 tserenarrowhebrew;05B5 tserequarterhebrew;05B5 tserewidehebrew;05B5 tshecyrillic;045B tsuperior;F6F3 ttabengali;099F ttadeva;091F ttagujarati;0A9F ttagurmukhi;0A1F tteharabic;0679 ttehfinalarabic;FB67 ttehinitialarabic;FB68 ttehmedialarabic;FB69 tthabengali;09A0 tthadeva;0920 tthagujarati;0AA0 tthagurmukhi;0A20 tturned;0287 tuhiragana;3064 tukatakana;30C4 tukatakanahalfwidth;FF82 tusmallhiragana;3063 tusmallkatakana;30C3 tusmallkatakanahalfwidth;FF6F twelvecircle;246B twelveparen;247F twelveperiod;2493 twelveroman;217B twentycircle;2473 twentyhangzhou;5344 twentyparen;2487 twentyperiod;249B two;0032 twoarabic;0662 twobengali;09E8 twocircle;2461 twocircleinversesansserif;278B twodeva;0968 twodotenleader;2025 twodotleader;2025 twodotleadervertical;FE30 twogujarati;0AE8 twogurmukhi;0A68 twohackarabic;0662 twohangzhou;3022 twoideographicparen;3221 twoinferior;2082 twomonospace;FF12 twonumeratorbengali;09F5 twooldstyle;F732 twoparen;2475 twoperiod;2489 twopersian;06F2 tworoman;2171 twostroke;01BB twosuperior;00B2 twothai;0E52 twothirds;2154 u;0075 uacute;00FA ubar;0289 ubengali;0989 ubopomofo;3128 ubreve;016D ucaron;01D4 ucircle;24E4 ucircumflex;00FB ucircumflexbelow;1E77 ucyrillic;0443 udattadeva;0951 udblacute;0171 udblgrave;0215 udeva;0909 udieresis;00FC udieresisacute;01D8 udieresisbelow;1E73 udieresiscaron;01DA udieresiscyrillic;04F1 udieresisgrave;01DC udieresismacron;01D6 udotbelow;1EE5 ugrave;00F9 ugujarati;0A89 ugurmukhi;0A09 uhiragana;3046 uhookabove;1EE7 uhorn;01B0 uhornacute;1EE9 uhorndotbelow;1EF1 uhorngrave;1EEB uhornhookabove;1EED uhorntilde;1EEF uhungarumlaut;0171 uhungarumlautcyrillic;04F3 uinvertedbreve;0217 ukatakana;30A6 ukatakanahalfwidth;FF73 ukcyrillic;0479 ukorean;315C umacron;016B umacroncyrillic;04EF umacrondieresis;1E7B umatragurmukhi;0A41 umonospace;FF55 underscore;005F underscoredbl;2017 underscoremonospace;FF3F underscorevertical;FE33 underscorewavy;FE4F union;222A universal;2200 uogonek;0173 uparen;24B0 upblock;2580 upperdothebrew;05C4 upsilon;03C5 upsilondieresis;03CB upsilondieresistonos;03B0 upsilonlatin;028A upsilontonos;03CD uptackbelowcmb;031D uptackmod;02D4 uragurmukhi;0A73 uring;016F ushortcyrillic;045E usmallhiragana;3045 usmallkatakana;30A5 usmallkatakanahalfwidth;FF69 ustraightcyrillic;04AF ustraightstrokecyrillic;04B1 utilde;0169 utildeacute;1E79 utildebelow;1E75 uubengali;098A uudeva;090A uugujarati;0A8A uugurmukhi;0A0A uumatragurmukhi;0A42 uuvowelsignbengali;09C2 uuvowelsigndeva;0942 uuvowelsigngujarati;0AC2 uvowelsignbengali;09C1 uvowelsigndeva;0941 uvowelsigngujarati;0AC1 v;0076 vadeva;0935 vagujarati;0AB5 vagurmukhi;0A35 vakatakana;30F7 vav;05D5 vavdagesh;FB35 vavdagesh65;FB35 vavdageshhebrew;FB35 vavhebrew;05D5 vavholam;FB4B vavholamhebrew;FB4B vavvavhebrew;05F0 vavyodhebrew;05F1 vcircle;24E5 vdotbelow;1E7F vecyrillic;0432 veharabic;06A4 vehfinalarabic;FB6B vehinitialarabic;FB6C vehmedialarabic;FB6D vekatakana;30F9 venus;2640 verticalbar;007C verticallineabovecmb;030D verticallinebelowcmb;0329 verticallinelowmod;02CC verticallinemod;02C8 vewarmenian;057E vhook;028B vikatakana;30F8 viramabengali;09CD viramadeva;094D viramagujarati;0ACD visargabengali;0983 visargadeva;0903 visargagujarati;0A83 vmonospace;FF56 voarmenian;0578 voicediterationhiragana;309E voicediterationkatakana;30FE voicedmarkkana;309B voicedmarkkanahalfwidth;FF9E vokatakana;30FA vparen;24B1 vtilde;1E7D vturned;028C vuhiragana;3094 vukatakana;30F4 w;0077 wacute;1E83 waekorean;3159 wahiragana;308F wakatakana;30EF wakatakanahalfwidth;FF9C wakorean;3158 wasmallhiragana;308E wasmallkatakana;30EE wattosquare;3357 wavedash;301C wavyunderscorevertical;FE34 wawarabic;0648 wawfinalarabic;FEEE wawhamzaabovearabic;0624 wawhamzaabovefinalarabic;FE86 wbsquare;33DD wcircle;24E6 wcircumflex;0175 wdieresis;1E85 wdotaccent;1E87 wdotbelow;1E89 wehiragana;3091 weierstrass;2118 wekatakana;30F1 wekorean;315E weokorean;315D wgrave;1E81 whitebullet;25E6 whitecircle;25CB whitecircleinverse;25D9 whitecornerbracketleft;300E whitecornerbracketleftvertical;FE43 whitecornerbracketright;300F whitecornerbracketrightvertical;FE44 whitediamond;25C7 whitediamondcontainingblacksmalldiamond;25C8 whitedownpointingsmalltriangle;25BF whitedownpointingtriangle;25BD whiteleftpointingsmalltriangle;25C3 whiteleftpointingtriangle;25C1 whitelenticularbracketleft;3016 whitelenticularbracketright;3017 whiterightpointingsmalltriangle;25B9 whiterightpointingtriangle;25B7 whitesmallsquare;25AB whitesmilingface;263A whitesquare;25A1 whitestar;2606 whitetelephone;260F whitetortoiseshellbracketleft;3018 whitetortoiseshellbracketright;3019 whiteuppointingsmalltriangle;25B5 whiteuppointingtriangle;25B3 wihiragana;3090 wikatakana;30F0 wikorean;315F wmonospace;FF57 wohiragana;3092 wokatakana;30F2 wokatakanahalfwidth;FF66 won;20A9 wonmonospace;FFE6 wowaenthai;0E27 wparen;24B2 wring;1E98 wsuperior;02B7 wturned;028D wynn;01BF x;0078 xabovecmb;033D xbopomofo;3112 xcircle;24E7 xdieresis;1E8D xdotaccent;1E8B xeharmenian;056D xi;03BE xmonospace;FF58 xparen;24B3 xsuperior;02E3 y;0079 yaadosquare;334E yabengali;09AF yacute;00FD yadeva;092F yaekorean;3152 yagujarati;0AAF yagurmukhi;0A2F yahiragana;3084 yakatakana;30E4 yakatakanahalfwidth;FF94 yakorean;3151 yamakkanthai;0E4E yasmallhiragana;3083 yasmallkatakana;30E3 yasmallkatakanahalfwidth;FF6C yatcyrillic;0463 ycircle;24E8 ycircumflex;0177 ydieresis;00FF ydotaccent;1E8F ydotbelow;1EF5 yeharabic;064A yehbarreearabic;06D2 yehbarreefinalarabic;FBAF yehfinalarabic;FEF2 yehhamzaabovearabic;0626 yehhamzaabovefinalarabic;FE8A yehhamzaaboveinitialarabic;FE8B yehhamzaabovemedialarabic;FE8C yehinitialarabic;FEF3 yehmedialarabic;FEF4 yehmeeminitialarabic;FCDD yehmeemisolatedarabic;FC58 yehnoonfinalarabic;FC94 yehthreedotsbelowarabic;06D1 yekorean;3156 yen;00A5 yenmonospace;FFE5 yeokorean;3155 yeorinhieuhkorean;3186 yerahbenyomohebrew;05AA yerahbenyomolefthebrew;05AA yericyrillic;044B yerudieresiscyrillic;04F9 yesieungkorean;3181 yesieungpansioskorean;3183 yesieungsioskorean;3182 yetivhebrew;059A ygrave;1EF3 yhook;01B4 yhookabove;1EF7 yiarmenian;0575 yicyrillic;0457 yikorean;3162 yinyang;262F yiwnarmenian;0582 ymonospace;FF59 yod;05D9 yoddagesh;FB39 yoddageshhebrew;FB39 yodhebrew;05D9 yodyodhebrew;05F2 yodyodpatahhebrew;FB1F yohiragana;3088 yoikorean;3189 yokatakana;30E8 yokatakanahalfwidth;FF96 yokorean;315B yosmallhiragana;3087 yosmallkatakana;30E7 yosmallkatakanahalfwidth;FF6E yotgreek;03F3 yoyaekorean;3188 yoyakorean;3187 yoyakthai;0E22 yoyingthai;0E0D yparen;24B4 ypogegrammeni;037A ypogegrammenigreekcmb;0345 yr;01A6 yring;1E99 ysuperior;02B8 ytilde;1EF9 yturned;028E yuhiragana;3086 yuikorean;318C yukatakana;30E6 yukatakanahalfwidth;FF95 yukorean;3160 yusbigcyrillic;046B yusbigiotifiedcyrillic;046D yuslittlecyrillic;0467 yuslittleiotifiedcyrillic;0469 yusmallhiragana;3085 yusmallkatakana;30E5 yusmallkatakanahalfwidth;FF6D yuyekorean;318B yuyeokorean;318A yyabengali;09DF yyadeva;095F z;007A zaarmenian;0566 zacute;017A zadeva;095B zagurmukhi;0A5B zaharabic;0638 zahfinalarabic;FEC6 zahinitialarabic;FEC7 zahiragana;3056 zahmedialarabic;FEC8 zainarabic;0632 zainfinalarabic;FEB0 zakatakana;30B6 zaqefgadolhebrew;0595 zaqefqatanhebrew;0594 zarqahebrew;0598 zayin;05D6 zayindagesh;FB36 zayindageshhebrew;FB36 zayinhebrew;05D6 zbopomofo;3117 zcaron;017E zcircle;24E9 zcircumflex;1E91 zcurl;0291 zdot;017C zdotaccent;017C zdotbelow;1E93 zecyrillic;0437 zedescendercyrillic;0499 zedieresiscyrillic;04DF zehiragana;305C zekatakana;30BC zero;0030 zeroarabic;0660 zerobengali;09E6 zerodeva;0966 zerogujarati;0AE6 zerogurmukhi;0A66 zerohackarabic;0660 zeroinferior;2080 zeromonospace;FF10 zerooldstyle;F730 zeropersian;06F0 zerosuperior;2070 zerothai;0E50 zerowidthjoiner;FEFF zerowidthnonjoiner;200C zerowidthspace;200B zeta;03B6 zhbopomofo;3113 zhearmenian;056A zhebrevecyrillic;04C2 zhecyrillic;0436 zhedescendercyrillic;0497 zhedieresiscyrillic;04DD zihiragana;3058 zikatakana;30B8 zinorhebrew;05AE zlinebelow;1E95 zmonospace;FF5A zohiragana;305E zokatakana;30BE zparen;24B5 zretroflexhook;0290 zstroke;01B6 zuhiragana;305A zukatakana;30BA #--end xmlgraphics-commons-2.6/src/main/resources/org/apache/xmlgraphics/fonts/zapfdingbats.txt0100644 0000000 0000000 00000007666 13777276623 030571 0ustar000000000 0000000 # ################################################################################### # Copyright (c) 1997,1998,2002,2007 Adobe Systems Incorporated # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this documentation file to use, copy, publish, distribute, # sublicense, and/or sell copies of the documentation, and to permit # others to do the same, provided that: # - No modification, editing or other alteration of this document is # allowed; and # - The above copyright notice and this permission notice shall be # included in all copies of the documentation. # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this documentation file, to create their own derivative works # from the content of this document to use, copy, publish, distribute, # sublicense, and/or sell the derivative works, and to permit others to do # the same, provided that the derived work is not represented as being a # copy or version of this document. # # Adobe shall not be liable to any party for any loss of revenue or profit # or for indirect, incidental, special, consequential, or other similar # damages, whether based on tort (including without limitation negligence # or strict liability), contract or other legal or equitable grounds even # if Adobe has been advised or had reason to know of the possibility of # such damages. The Adobe materials are provided on an "AS IS" basis. # Adobe specifically disclaims all express, statutory, or implied # warranties relating to the Adobe materials, including but not limited to # those concerning merchantability or fitness for a particular purpose or # non-infringement of any third party rights regarding the Adobe # materials. # ################################################################################### # Name: ITC Zapf Dingbats Glyph List # Table version: 2.0 # Date: September 20, 2002 # # See http://partners.adobe.com/asn/developer/typeforum/unicodegn.html # # Format: Semicolon-delimited fields: # (1) glyph name # (2) Unicode scalar value # a100;275E a101;2761 a102;2762 a103;2763 a104;2764 a105;2710 a106;2765 a107;2766 a108;2767 a109;2660 a10;2721 a110;2665 a111;2666 a112;2663 a117;2709 a118;2708 a119;2707 a11;261B a120;2460 a121;2461 a122;2462 a123;2463 a124;2464 a125;2465 a126;2466 a127;2467 a128;2468 a129;2469 a12;261E a130;2776 a131;2777 a132;2778 a133;2779 a134;277A a135;277B a136;277C a137;277D a138;277E a139;277F a13;270C a140;2780 a141;2781 a142;2782 a143;2783 a144;2784 a145;2785 a146;2786 a147;2787 a148;2788 a149;2789 a14;270D a150;278A a151;278B a152;278C a153;278D a154;278E a155;278F a156;2790 a157;2791 a158;2792 a159;2793 a15;270E a160;2794 a161;2192 a162;27A3 a163;2194 a164;2195 a165;2799 a166;279B a167;279C a168;279D a169;279E a16;270F a170;279F a171;27A0 a172;27A1 a173;27A2 a174;27A4 a175;27A5 a176;27A6 a177;27A7 a178;27A8 a179;27A9 a17;2711 a180;27AB a181;27AD a182;27AF a183;27B2 a184;27B3 a185;27B5 a186;27B8 a187;27BA a188;27BB a189;27BC a18;2712 a190;27BD a191;27BE a192;279A a193;27AA a194;27B6 a195;27B9 a196;2798 a197;27B4 a198;27B7 a199;27AC a19;2713 a1;2701 a200;27AE a201;27B1 a202;2703 a203;2750 a204;2752 a205;276E a206;2770 a20;2714 a21;2715 a22;2716 a23;2717 a24;2718 a25;2719 a26;271A a27;271B a28;271C a29;2722 a2;2702 a30;2723 a31;2724 a32;2725 a33;2726 a34;2727 a35;2605 a36;2729 a37;272A a38;272B a39;272C a3;2704 a40;272D a41;272E a42;272F a43;2730 a44;2731 a45;2732 a46;2733 a47;2734 a48;2735 a49;2736 a4;260E a50;2737 a51;2738 a52;2739 a53;273A a54;273B a55;273C a56;273D a57;273E a58;273F a59;2740 a5;2706 a60;2741 a61;2742 a62;2743 a63;2744 a64;2745 a65;2746 a66;2747 a67;2748 a68;2749 a69;274A a6;271D a70;274B a71;25CF a72;274D a73;25A0 a74;274F a75;2751 a76;25B2 a77;25BC a78;25C6 a79;2756 a7;271E a81;25D7 a82;2758 a83;2759 a84;275A a85;276F a86;2771 a87;2772 a88;2773 a89;2768 a8;271F a90;2769 a91;276C a92;276D a93;276A a94;276B a95;2774 a96;2775 a97;275B a98;275C a99;275D a9;2720 #-- end xmlgraphics-commons-2.6/src/main/resources/org/apache/xmlgraphics/image/codec/Messages.properties0100644 0000000 0000000 00000021773 13777276623 032242 0ustar000000000 0000000 # # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # FileCacheSeekableStream0=pos < 0. FileSeekableStream0=pos < 0. FloatDoubleColorModel0=transferType must be DataBuffer.TYPE_FLOAT or DataBuffer.TYPE_DOUBLE. FloatDoubleColorModel10=elements required in the components array. FloatDoubleColorModel1=getRed(int) not supported by this ColorModel. FloatDoubleColorModel2=getGreen(int) not supported by this ColorModel. FloatDoubleColorModel3=getBlue(int) not supported by this ColorModel. FloatDoubleColorModel4=getAlpha(int) not supported by this ColorModel. FloatDoubleColorModel5=getRGB(int) not supported by this ColorModel. FloatDoubleColorModel6=raster transfer type must match that of this ColorModel. FloatDoubleColorModel7=Type of pixel does not match transfer type. FloatDoubleColorModel8=pixel array is not large enough to hold all color/alpha components. FloatDoubleColorModel9=Pixel values for FloatDoubleColorModel cannot be represented as a single integer. MemoryCacheSeekableStream0=pos < 0. PNGCodec0=PNG encoding not supported yet. PNGDecodeParam0=User exponent must not be negative. PNGDecodeParam1=Display exponent must not be negative. PNGEncodeParam0=Bad palette length. PNGEncodeParam10=Transparent RGB value has not been set. PNGEncodeParam11=Grayscale bit depth has not been set. PNGEncodeParam12=Chromaticity has not been set. PNGEncodeParam13=Gamma has not been set. PNGEncodeParam14=Palette histogram has not been set. PNGEncodeParam15=ICC profile has not been set. PNGEncodeParam16=Physical dimension information has not been set. PNGEncodeParam17=Suggested palette information has not been set. PNGEncodeParam18=Significant bits values have not been set. PNGEncodeParam19=sRGB rendering intent has not been set. PNGEncodeParam1=Not divisible by 3. PNGEncodeParam20=Uncompressed text strings have not been set. PNGEncodeParam21=Modification time has not been set. PNGEncodeParam22=Compressed text strings have not been set. PNGEncodeParam23='unsetBackground' not implemented by the superclass 'PNGEncodeParam'. PNGEncodeParam24='isBackgroundSet' not implemented by the superclass 'PNGEncodeParam'. PNGEncodeParam25=Bit shift must be greater than 0. PNGEncodeParam26=Bit depth must be 8 or 16. PNGEncodeParam27=RGB value must have three components. PNGEncodeParam28=Chromaticity array must be non-empty. PNGEncodeParam2=Bit depth not equal to 1, 2, 4, or 8. PNGEncodeParam3=RGB palette has not been set. PNGEncodeParam4=background palette index has not been set. PNGEncodeParam5=Palette transparency has not been set. PNGEncodeParam6=Background gray level has not been set. PNGEncodeParam7=Transparent gray value has not been set. PNGEncodeParam8=Bit shift has not been set. PNGEncodeParam9=RGB background color has not been set. PNGImageDecoder0=PNG magic number not found. PNGImageDecoder10=Unsupported PNG filter method (not 0). PNGImageDecoder11=Unsupported PNG interlace method (not 0 or 1). PNGImageDecoder12=Unknown PNG pHYs unit specifier (not 0 or 1). PNGImageDecoder13=Illegal PNG sBit value (< 0 or > bit depth). PNGImageDecoder14=Too many PNG alpha palette entries. PNGImageDecoder15=PNG image already has alpha, can't have tRNS chunk. PNGImageDecoder16=Unknown PNG filter type (not 0-4). PNGImageDecoder17=Illegal tile requested from a PNG image. PNGImageDecoder18=PNG can't have hIST chunk without a PLTE chunk. PNGImageDecoder19=Illegal page requested from a PNG file. PNGImageDecoder1=Error reading PNG header. PNGImageDecoder2=I/O error reading PNG file. PNGImageDecoder3=Illegal bit depth for a PNG image. PNGImageDecoder4=Bad color type for a PNG image. PNGImageDecoder5=An RGB PNG image can't have a bit depth less than 8. PNGImageDecoder6=A palette-color PNG image can't have a bit depth of 16. PNGImageDecoder7=A PNG Gray+Alpha image can't have a bit depth less than 8. PNGImageDecoder8=A PNG RGB+Alpha image can't have a bit depth less than 8. PNGImageDecoder9=Unsupported PNG compression method (not 0). PNGImageEncoder0=Sample size not equal to bit depth. PNGImageEncoder1=Bit depth greater than 16. PNGImageEncoder2=Bit depth less than 1 or greater than 8. PNGImageEncoder3=Number of bands not equal to 1. PNGImageEncoder4=PNG encode parameter must be Palette or Gray. PropertySet0=Not implemented. RasterFactory0=Number of bands must be greater than 0. RasterFactory10=parentY lies outside raster. RasterFactory11=(parentX + width) is outside raster. RasterFactory12=(parentY + height) is outside raster. RasterFactory13=Illegal value for transparency. RasterFactory14=Transparency cannot be opaque when useAlpha is true. RasterFactory15=bitsPerBands must be greater than 0. RasterFactory16=Size of array must be smaller than Integer.MAX_VALUE. RasterFactory1=Bank indices array is null. RasterFactory2=bankIndices.length != bandOffsets.length RasterFactory3=Unsupported data type. RasterFactory4=Band offsets array is null. RasterFactory5=Offsets between bands must be less than the scanline stride. RasterFactory6=Pixel stride times width must be less than the scanline stride. RasterFactory7=Pixel stride must be greater than or equal to the offset between bands. RasterFactory8=This method does not support the input data type. RasterFactory9=parentX lies outside raster. SegmentedSeekableStream0=Source stream does not support seeking backwards. SingleTileRenderedImage0=Illegal tile requested from a SingleTileRenderedImage. TIFFImage0=Planar (band-sequential) format TIFF is not supported. TIFFImage1=All samples must have the same bit depth. TIFFImage2=All samples must have the same data format. TIFFImage3=Unsupported combination of bit depth and sample format. TIFFImage4=Unsupported image type. TIFFImage5=Strip offsets, a required field, is not present in the TIFF file. TIFFImage5=Strip byte counts, a required field, is not present in the TIFF file. TIFFImage7=Unsupported compression type for non-bilevel data. TIFFImage8=Illegal value for predictor in TIFF file. TIFFImage9=Sample size must be 8 for horizontal differencing predictor. TIFFImage10=Unsupported compression type TIFFImage11=Colormap must be present for a Palette Color image. TIFFImage12=Illegal tile requested from a TIFFImage. TIFFImage13=IOException occured while reading TIFF image data TIFFImage14=Unable to decode packbits compressed data - not enough data TIFFImage15=Decoding of old style JPEG-in-TIFF data is not supported. TIFFImage17=Error inflating data TIFFImage18=Unsupported field type TIFFImage19=Unsupported number of bands TIFFImage20=Unsupported data type TIFFImageDecoder0=Illegal page requested from a TIFF file. TIFFImageEncoder0=All samples must have the same bit depth. TIFFImageEncoder1=1- and 4-bit data supported for single band images only. TIFFImageEncoder2=Byte buffers require 1-, 4-, or b-bit data. TIFFImageEncoder3=Short or unsigned short buffers require 16-bit data. TIFFImageEncoder4=Int or float buffers require 32-bit data. TIFFImageEncoder5=Unsupported output data type. TIFFImageEncoder6=TIFF encoder does not support (unsigned) short palette images. TIFFImageEncoder7=Invalid image - An image with sampleSize of 1 bit must have IndexColorModel with mapsize of 2. TIFFImageEncoder8=Image type not supported for output. TIFFImageEncoder9=JPEG-in-TIFF encoding supported only for 8-bit samples and either 1 (grayscale) or 3 (RGB or YCbCr) samples per pixel. TIFFImageEncoder10=Unsupported TIFFField type. TIFFImageEncoder11=Extra images may not be used when encoding multiple page file. TIFFImageEncoder12=JPEG compression not supported. TIFFImageEncoder13=No output specified. TIFFLZWDecoder0=TIFF 5.0 LZW codes are not supported. TIFFFaxDecoder0=ERROR code word (0) encountered. TIFFFaxDecoder1=EOL code word (15) encountered in White run. TIFFFaxDecoder2=EOL code word (15) encountered in Black run. TIFFFaxDecoder3=First scanline must be 1D encoded. TIFFFaxDecoder4=Invalid code encountered while decoding 2D group 3 compressed data. TIFFFaxDecoder5=Invalid code encountered while decoding 2D group 4 compressed data. TIFFFaxDecoder6=Scanline must begin with EOL code word. TIFFFaxDecoder7=TIFF_FILL_ORDER tag must be either 1 or 2. TIFFFaxDecoder8=All fill bits preceding EOL code must be 0. TIFFDirectory0=Unsupported TIFFField tag. TIFFDirectory1=Bad endianness tag (not 0x4949 or 0x4d4d). TIFFDirectory2=Bad magic number, should be 42. TIFFDirectory3=Directory number too large. TIFFEncodeParam0=Unsupported compression scheme specified. TIFFEncodeParam1=Illegal DEFLATE compression level specified.././@LongLink0100644 0000000 0000000 00000000162 13777276623 011656 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/main/resources/org/apache/xmlgraphics/image/writer/default-preferred-order.propertiesxmlgraphics-commons-2.6/src/main/resources/org/apache/xmlgraphics/image/writer/default-preferred-ord0100644 0000000 0000000 00000001566 13777276623 032717 0ustar000000000 0000000 # # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # org.apache.xmlgraphics.image.writer.internal=-2000 org.apache.xmlgraphics.image.writer.imageio=-1000xmlgraphics-commons-2.6/src/main/resources/org/apache/xmlgraphics/ps/Identity-H0100644 0000000 0000000 00000017321 13777276623 026533 0ustar000000000 0000000 %!PS-Adobe-3.0 Resource-CMap %%DocumentNeededResources: ProcSet (CIDInit) %%IncludeResource: ProcSet (CIDInit) %%BeginResource: CMap (Identity-H) %%Title: (Identity-H Adobe Identity 0) %%Version: 10.003 %%Copyright: ----------------------------------------------------------- %%Copyright: Copyright 1990-2009 Adobe Systems Incorporated. %%Copyright: All rights reserved. %%Copyright: %%Copyright: Redistribution and use in source and binary forms, with or %%Copyright: without modification, are permitted provided that the %%Copyright: following conditions are met: %%Copyright: %%Copyright: Redistributions of source code must retain the above %%Copyright: copyright notice, this list of conditions and the following %%Copyright: disclaimer. %%Copyright: %%Copyright: Redistributions in binary form must reproduce the above %%Copyright: copyright notice, this list of conditions and the following %%Copyright: disclaimer in the documentation and/or other materials %%Copyright: provided with the distribution. %%Copyright: %%Copyright: Neither the name of Adobe Systems Incorporated nor the names %%Copyright: of its contributors may be used to endorse or promote %%Copyright: products derived from this software without specific prior %%Copyright: written permission. %%Copyright: %%Copyright: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND %%Copyright: CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, %%Copyright: INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF %%Copyright: MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE %%Copyright: DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR %%Copyright: CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, %%Copyright: SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT %%Copyright: NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; %%Copyright: LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) %%Copyright: HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN %%Copyright: CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR %%Copyright: OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS %%Copyright: SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. %%Copyright: ----------------------------------------------------------- %%EndComments /CIDInit /ProcSet findresource begin 12 dict begin begincmap /CIDSystemInfo 3 dict dup begin /Registry (Adobe) def /Ordering (Identity) def /Supplement 0 def end def /CMapName /Identity-H def /CMapVersion 10.003 def /CMapType 1 def /XUID [1 10 25404 9999] def /WMode 0 def 1 begincodespacerange <0000> endcodespacerange 100 begincidrange <0000> <00ff> 0 <0100> <01ff> 256 <0200> <02ff> 512 <0300> <03ff> 768 <0400> <04ff> 1024 <0500> <05ff> 1280 <0600> <06ff> 1536 <0700> <07ff> 1792 <0800> <08ff> 2048 <0900> <09ff> 2304 <0a00> <0aff> 2560 <0b00> <0bff> 2816 <0c00> <0cff> 3072 <0d00> <0dff> 3328 <0e00> <0eff> 3584 <0f00> <0fff> 3840 <1000> <10ff> 4096 <1100> <11ff> 4352 <1200> <12ff> 4608 <1300> <13ff> 4864 <1400> <14ff> 5120 <1500> <15ff> 5376 <1600> <16ff> 5632 <1700> <17ff> 5888 <1800> <18ff> 6144 <1900> <19ff> 6400 <1a00> <1aff> 6656 <1b00> <1bff> 6912 <1c00> <1cff> 7168 <1d00> <1dff> 7424 <1e00> <1eff> 7680 <1f00> <1fff> 7936 <2000> <20ff> 8192 <2100> <21ff> 8448 <2200> <22ff> 8704 <2300> <23ff> 8960 <2400> <24ff> 9216 <2500> <25ff> 9472 <2600> <26ff> 9728 <2700> <27ff> 9984 <2800> <28ff> 10240 <2900> <29ff> 10496 <2a00> <2aff> 10752 <2b00> <2bff> 11008 <2c00> <2cff> 11264 <2d00> <2dff> 11520 <2e00> <2eff> 11776 <2f00> <2fff> 12032 <3000> <30ff> 12288 <3100> <31ff> 12544 <3200> <32ff> 12800 <3300> <33ff> 13056 <3400> <34ff> 13312 <3500> <35ff> 13568 <3600> <36ff> 13824 <3700> <37ff> 14080 <3800> <38ff> 14336 <3900> <39ff> 14592 <3a00> <3aff> 14848 <3b00> <3bff> 15104 <3c00> <3cff> 15360 <3d00> <3dff> 15616 <3e00> <3eff> 15872 <3f00> <3fff> 16128 <4000> <40ff> 16384 <4100> <41ff> 16640 <4200> <42ff> 16896 <4300> <43ff> 17152 <4400> <44ff> 17408 <4500> <45ff> 17664 <4600> <46ff> 17920 <4700> <47ff> 18176 <4800> <48ff> 18432 <4900> <49ff> 18688 <4a00> <4aff> 18944 <4b00> <4bff> 19200 <4c00> <4cff> 19456 <4d00> <4dff> 19712 <4e00> <4eff> 19968 <4f00> <4fff> 20224 <5000> <50ff> 20480 <5100> <51ff> 20736 <5200> <52ff> 20992 <5300> <53ff> 21248 <5400> <54ff> 21504 <5500> <55ff> 21760 <5600> <56ff> 22016 <5700> <57ff> 22272 <5800> <58ff> 22528 <5900> <59ff> 22784 <5a00> <5aff> 23040 <5b00> <5bff> 23296 <5c00> <5cff> 23552 <5d00> <5dff> 23808 <5e00> <5eff> 24064 <5f00> <5fff> 24320 <6000> <60ff> 24576 <6100> <61ff> 24832 <6200> <62ff> 25088 <6300> <63ff> 25344 endcidrange 100 begincidrange <6400> <64ff> 25600 <6500> <65ff> 25856 <6600> <66ff> 26112 <6700> <67ff> 26368 <6800> <68ff> 26624 <6900> <69ff> 26880 <6a00> <6aff> 27136 <6b00> <6bff> 27392 <6c00> <6cff> 27648 <6d00> <6dff> 27904 <6e00> <6eff> 28160 <6f00> <6fff> 28416 <7000> <70ff> 28672 <7100> <71ff> 28928 <7200> <72ff> 29184 <7300> <73ff> 29440 <7400> <74ff> 29696 <7500> <75ff> 29952 <7600> <76ff> 30208 <7700> <77ff> 30464 <7800> <78ff> 30720 <7900> <79ff> 30976 <7a00> <7aff> 31232 <7b00> <7bff> 31488 <7c00> <7cff> 31744 <7d00> <7dff> 32000 <7e00> <7eff> 32256 <7f00> <7fff> 32512 <8000> <80ff> 32768 <8100> <81ff> 33024 <8200> <82ff> 33280 <8300> <83ff> 33536 <8400> <84ff> 33792 <8500> <85ff> 34048 <8600> <86ff> 34304 <8700> <87ff> 34560 <8800> <88ff> 34816 <8900> <89ff> 35072 <8a00> <8aff> 35328 <8b00> <8bff> 35584 <8c00> <8cff> 35840 <8d00> <8dff> 36096 <8e00> <8eff> 36352 <8f00> <8fff> 36608 <9000> <90ff> 36864 <9100> <91ff> 37120 <9200> <92ff> 37376 <9300> <93ff> 37632 <9400> <94ff> 37888 <9500> <95ff> 38144 <9600> <96ff> 38400 <9700> <97ff> 38656 <9800> <98ff> 38912 <9900> <99ff> 39168 <9a00> <9aff> 39424 <9b00> <9bff> 39680 <9c00> <9cff> 39936 <9d00> <9dff> 40192 <9e00> <9eff> 40448 <9f00> <9fff> 40704 40960 41216 41472 41728 41984 42240 42496 42752 43008 43264 43520 43776 44032 44288 44544 44800 45056 45312 45568 45824 46080 46336 46592 46848 47104 47360 47616 47872 48128 48384 48640 48896 49152 49408 49664 49920 50176 50432 50688 50944 endcidrange 56 begincidrange 51200 51456 51712 51968 52224 52480 52736 52992 53248 53504 53760 54016 54272 54528 54784 55040 55296 55552 55808 56064 56320 56576 56832 57088 57344 57600 57856 58112 58368 58624 58880 59136 59392 59648 59904 60160 60416 60672 60928 61184 61440 61696 61952 62208 62464 62720 62976 63232 63488 63744 64000 64256 64512 64768 65024 65280 endcidrange endcmap CMapName currentdict /CMap defineresource pop end end %%EndResource %%EOF xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/StandardTestSuite.java0100644 0000000 0000000 00000004412 13777276623 027424 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: StandardTestSuite.java 1365650 2012-07-25 15:59:30Z mehdi $ */ package org.apache.xmlgraphics; import org.junit.runner.RunWith; import org.junit.runners.Suite; import org.junit.runners.Suite.SuiteClasses; import org.apache.xmlgraphics.image.codec.png.PNGEncoderTestCase; import org.apache.xmlgraphics.ps.ImageEncodingHelperTestCase; import org.apache.xmlgraphics.ps.PSEscapeTestCase; import org.apache.xmlgraphics.ps.dsc.ListenerTestCase; import org.apache.xmlgraphics.ps.dsc.events.DSCValueParserTestCase; import org.apache.xmlgraphics.ps.dsc.tools.DSCToolsTestCase; import org.apache.xmlgraphics.util.ClasspathResourceTestCase; import org.apache.xmlgraphics.util.ServiceTestCase; import org.apache.xmlgraphics.util.UnitConvTestCase; import org.apache.xmlgraphics.util.io.ASCII85InputStreamTestCase; import org.apache.xmlgraphics.util.io.ASCII85OutputStreamTestCase; import org.apache.xmlgraphics.util.io.Base64TestCase; /** * Test suite for basic functionality of XML Graphics Commons. */ @RunWith(Suite.class) @SuiteClasses({ Base64TestCase.class, ASCII85InputStreamTestCase.class, ASCII85OutputStreamTestCase.class, PNGEncoderTestCase.class, ServiceTestCase.class, ClasspathResourceTestCase.class, PSEscapeTestCase.class, ImageEncodingHelperTestCase.class, DSCValueParserTestCase.class, DSCToolsTestCase.class, ListenerTestCase.class, UnitConvTestCase.class }) public class StandardTestSuite { } xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/fonts/GlyphsTestCase.java0100644 0000000 0000000 00000007265 13777276623 030056 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: GlyphsTestCase.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.fonts; import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; /** * Tests for the Glyphs class. */ public class GlyphsTestCase { @Test public void testGetUnicodeSequenceForGlyphName() throws Exception { String glyph; String unicodes; glyph = "Omega"; unicodes = Glyphs.getUnicodeSequenceForGlyphName(glyph); assertEquals(1, unicodes.length()); assertEquals("Must contain 2126 - OHM SIGN", unicodes.charAt(0), '\u2126'); glyph = "Omegagreek"; unicodes = Glyphs.getUnicodeSequenceForGlyphName(glyph); assertEquals(1, unicodes.length()); assertEquals("Must contain 03A9 - GREEK CAPITAL LETTER OMEGA", unicodes.charAt(0), '\u03A9'); glyph = "A"; unicodes = Glyphs.getUnicodeSequenceForGlyphName(glyph); assertEquals(1, unicodes.length()); assertEquals("Must contain 0041 - LATIN CAPITAL LETTER A", unicodes.charAt(0), '\u0041'); glyph = "rehyehaleflamarabic"; unicodes = Glyphs.getUnicodeSequenceForGlyphName(glyph); assertEquals(4, unicodes.length()); assertEquals("Expected 0631 - ARABIC LETTER REH at position 0", unicodes.charAt(0), '\u0631'); assertEquals("Expected FEF3 - ARABIC LETTER YEH INITAL FORM at position 1", unicodes.charAt(1), '\uFEF3'); assertEquals("Expected FE8E - ARABIC LETTER ALEF FINAL FORM at position 2", unicodes.charAt(2), '\uFE8E'); assertEquals("Expected 0644 - ARABIC LETTER LAM at position 3", unicodes.charAt(3), '\u0644'); glyph = "Lcommaaccent_uni20AC0308_u20AC"; unicodes = Glyphs.getUnicodeSequenceForGlyphName(glyph); assertEquals(4, unicodes.length()); assertEquals("Must contain 013B", unicodes.charAt(0), '\u013B'); assertEquals("Must contain 20AC", unicodes.charAt(1), '\u20AC'); assertEquals("Must contain 0308", unicodes.charAt(2), '\u0308'); assertEquals("Must contain 20AC", unicodes.charAt(3), '\u20AC'); glyph = "blah"; unicodes = Glyphs.getUnicodeSequenceForGlyphName(glyph); assertNull(unicodes); } @Test public void testGetCharNameAlternativesFor() throws Exception { String[] alts = Glyphs.getCharNameAlternativesFor("Omega"); assertEquals(1, alts.length); assertEquals("Omegagreek", alts[0]); alts = Glyphs.getCharNameAlternativesFor("nbspace"); assertEquals(2, alts.length); assertEquals("space", alts[0]); assertEquals("nonbreakingspace", alts[1]); alts = Glyphs.getCharNameAlternativesFor("A"); assertNull(alts); } } ././@LongLink0100644 0000000 0000000 00000000151 13777276623 011654 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/codec/png/CodecResourcesTestCase.javaxmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/codec/png/CodecResourcesTestCase.0100644 0000000 0000000 00000004156 13777276623 032444 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: CodecResourcesTestCase.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.image.codec.png; import java.io.InputStream; import org.junit.Test; import static org.junit.Assert.fail; import org.apache.commons.io.IOUtils; import org.apache.xmlgraphics.image.codec.util.MemoryCacheSeekableStream; import org.apache.xmlgraphics.image.codec.util.SeekableStream; /** * Checks for the presence of message resources for the internal codecs. */ public class CodecResourcesTestCase { @Test public void testResources() throws Exception { InputStream in = new java.io.FileInputStream("test/images/barcode.eps"); SeekableStream seekStream = new MemoryCacheSeekableStream(in); try { new PNGImage(seekStream, null); fail("Exception expected"); } catch (RuntimeException re) { String msg = re.getMessage(); if ("PNGImageDecoder0".equals(msg)) { re.printStackTrace(); fail("Message resource don't seem to be present! Message is: " + msg); } else if (msg.toLowerCase().indexOf("magic") < 0) { fail("Message not as expected! Message is: " + msg); } } finally { IOUtils.closeQuietly(seekStream); IOUtils.closeQuietly(in); } } } ././@LongLink0100644 0000000 0000000 00000000145 13777276623 011657 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/codec/png/PNGEncoderTestCase.javaxmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/codec/png/PNGEncoderTestCase.java0100644 0000000 0000000 00000012540 13777276623 032316 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: PNGEncoderTestCase.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.image.codec.png; import java.awt.Color; import java.awt.Graphics2D; import java.awt.geom.AffineTransform; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; import java.awt.image.RenderedImage; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.io.OutputStream; import org.junit.Test; import static org.junit.Assert.fail; /** * This test validates the PNGEncoder operation. It creates a * BufferedImage, then encodes it with the PNGEncoder, then * decodes it and compares the decoded image with the original one. * * @version $Id: PNGEncoderTestCase.java 1732018 2016-02-24 04:51:06Z gadams $ */ public class PNGEncoderTestCase { @Test public void testPNGEncoding() throws Exception { // Create a BufferedImage to be encoded BufferedImage image = new BufferedImage(100, 75, BufferedImage.TYPE_INT_ARGB); Graphics2D ig = image.createGraphics(); ig.scale(.5, .5); ig.setPaint(new Color(128, 0, 0)); ig.fillRect(0, 0, 100, 50); ig.setPaint(Color.orange); ig.fillRect(100, 0, 100, 50); ig.setPaint(Color.yellow); ig.fillRect(0, 50, 100, 50); ig.setPaint(Color.red); ig.fillRect(100, 50, 100, 50); ig.setPaint(new Color(255, 127, 127)); ig.fillRect(0, 100, 100, 50); ig.setPaint(Color.black); ig.draw(new Rectangle2D.Double(0.5, 0.5, 199, 149)); ig.dispose(); image = image.getSubimage(50, 0, 50, 25); // Create an output stream where the PNG data // will be stored. ByteArrayOutputStream bos = new ByteArrayOutputStream(); OutputStream os = buildOutputStream(bos); try { // Now, try to encode image PNGEncodeParam params = PNGEncodeParam.getDefaultEncodeParam(image); PNGImageEncoder pngImageEncoder = new PNGImageEncoder(os, params); pngImageEncoder.encode(image); } finally { os.close(); } // Now, try to decode image InputStream is = buildInputStream(bos); PNGImageDecoder pngImageDecoder = new PNGImageDecoder(is, new PNGDecodeParam()); RenderedImage decodedRenderedImage = null; decodedRenderedImage = pngImageDecoder.decodeAsRenderedImage(0); BufferedImage decodedImage = null; if (decodedRenderedImage instanceof BufferedImage) { decodedImage = (BufferedImage) decodedRenderedImage; } else { decodedImage = new BufferedImage(decodedRenderedImage.getWidth(), decodedRenderedImage.getHeight(), BufferedImage.TYPE_INT_ARGB); ig = decodedImage.createGraphics(); ig.drawRenderedImage(decodedRenderedImage, new AffineTransform()); ig.dispose(); } // Compare images if (!checkIdentical(image, decodedImage)) { fail("Decoded image does not match the original"); } } /** * Template method for building the PNG output stream. This gives a * chance to sub-classes (e.g., Base64PNGEncoderTest) to add an * additional encoding. */ public OutputStream buildOutputStream(ByteArrayOutputStream bos) { return bos; } /** * Template method for building the PNG input stream. This gives a * chance to sub-classes (e.g., Base64PNGEncoderTest) to add an * additional decoding. */ public InputStream buildInputStream(ByteArrayOutputStream bos) { return new ByteArrayInputStream(bos.toByteArray()); } /** * Compares the data for the two images */ public static boolean checkIdentical(BufferedImage imgA, BufferedImage imgB) { boolean identical = true; if (imgA.getWidth() == imgB.getWidth() && imgA.getHeight() == imgB.getHeight()) { int w = imgA.getWidth(); int h = imgA.getHeight(); for (int i = 0; i < h; i++) { for (int j = 0; j < w; j++) { if (imgA.getRGB(j, i) != imgB.getRGB(j, i)) { identical = false; break; } } if (!identical) { break; } } } return identical; } } ././@LongLink0100644 0000000 0000000 00000000145 13777276623 011657 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/codec/tiff/ImageInfoTestCase.javaxmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/codec/tiff/ImageInfoTestCase.java0100644 0000000 0000000 00000016655 13777276623 032407 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.xmlgraphics.image.codec.tiff; import java.awt.color.ColorSpace; import java.awt.image.ColorModel; import java.awt.image.IndexColorModel; import java.awt.image.RenderedImage; import org.junit.Before; import org.junit.Test; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import static org.apache.xmlgraphics.image.codec.tiff.ExtraSamplesType.UNSPECIFIED; import static org.apache.xmlgraphics.image.codec.tiff.ImageType.BILEVEL_BLACK_IS_ZERO; import static org.apache.xmlgraphics.image.codec.tiff.ImageType.BILEVEL_WHITE_IS_ZERO; import static org.apache.xmlgraphics.image.codec.tiff.ImageType.CIELAB; import static org.apache.xmlgraphics.image.codec.tiff.ImageType.CMYK; import static org.apache.xmlgraphics.image.codec.tiff.ImageType.GENERIC; import static org.apache.xmlgraphics.image.codec.tiff.ImageType.GRAY; import static org.apache.xmlgraphics.image.codec.tiff.ImageType.RGB; import static org.apache.xmlgraphics.image.codec.tiff.ImageType.YCBCR; public class ImageInfoTestCase { private ColorSpace colorSpace; private ColorModel colorModel; private RenderedImage image; private TIFFEncodeParam params; @Before public void setUp() { colorSpace = mock(ColorSpace.class); colorModel = new TestColorModel(colorSpace, true); image = mock(RenderedImage.class); params = mock(TIFFEncodeParam.class); } @Test public void testNullColorModel() { testImageInfo(ImageInfo.newInstance(image, 1, 1, null, params), BILEVEL_BLACK_IS_ZERO, 0, null, 0, UNSPECIFIED); for (int i = 2; i < 10; i += 2) { testImageInfo(ImageInfo.newInstance(image, 1, i, null, params), GENERIC, i - 1, null, 0, UNSPECIFIED); } } @Test public void testNonIndexColorModel() { testTheColorSpaceType(ColorSpace.TYPE_CMYK, false, CMYK); testTheColorSpaceType(ColorSpace.TYPE_GRAY, false, GRAY); testTheColorSpaceType(ColorSpace.TYPE_RGB, true, YCBCR); testTheColorSpaceType(ColorSpace.TYPE_RGB, false, RGB); } private void testTheColorSpaceType(int colorSpaceType, boolean getJpegCompress, ImageType expectedType) { when(colorSpace.getType()).thenReturn(colorSpaceType); TIFFEncodeParam params = mock(TIFFEncodeParam.class); when(params.getJPEGCompressRGBToYCbCr()).thenReturn(getJpegCompress); testImageInfo(ImageInfo.newInstance(image, 1, 1, colorModel, params), expectedType, 0, null, 0, UNSPECIFIED); } @Test public void testNonIndexColorModelWithNumBandsGreaterThan1() { testWithNumOfBandsGreaterThan1(ColorSpace.TYPE_GRAY, GRAY, 3, 1); testWithNumOfBandsGreaterThan1(ColorSpace.TYPE_Lab, CIELAB, 6, 3); testWithNumOfBandsGreaterThan1(ColorSpace.TYPE_CMYK, CMYK, 5, 2); } private void testWithNumOfBandsGreaterThan1(int colorSpaceType, ImageType type, int numBands, int numComponents) { when(colorSpace.getType()).thenReturn(colorSpaceType); when(colorSpace.getNumComponents()).thenReturn(numComponents); testImageInfo(ImageInfo.newInstance(image, 2, numBands, colorModel, params), type, numBands - numComponents, null, 0, UNSPECIFIED); } private void testImageInfo(ImageInfo imageInfo, ImageType imageType, int numExtraSamples, char[] colormap, int colormapSize, ExtraSamplesType extraSamplesType) { assertEquals(imageType, imageInfo.getType()); assertEquals(numExtraSamples, imageInfo.getNumberOfExtraSamples()); assertArrayEquals(colormap, imageInfo.getColormap()); assertEquals(colormapSize, imageInfo.getColormapSize()); assertEquals(extraSamplesType, imageInfo.getExtraSamplesType()); } @Test public void testIndexColorModel() { byte[] blackIsZero = new byte[] {0, (byte) 0xff}; IndexColorModel icm = new IndexColorModel(1, 2, blackIsZero, blackIsZero, blackIsZero); testImageInfo(ImageInfo.newInstance(image, 1, 1, icm, params), BILEVEL_BLACK_IS_ZERO, 0, null, 0, UNSPECIFIED); byte[] whiteIsZero = new byte[] {(byte) 0xff, 0}; icm = new IndexColorModel(1, 2, whiteIsZero, whiteIsZero, whiteIsZero); testImageInfo(ImageInfo.newInstance(image, 1, 1, icm, params), BILEVEL_WHITE_IS_ZERO, 0, null, 0, UNSPECIFIED); } @Test public void testTileWidthHeight() { when(params.getWriteTiled()).thenReturn(true); when(image.getWidth()).thenReturn(10); when(image.getHeight()).thenReturn(10); for (int i = 1; i < 10000; i += 200) { when(params.getTileWidth()).thenReturn(i); when(params.getTileHeight()).thenReturn(i); int numTiles = ((10 + i - 1) / i) * ((10 + i - 1) / i); long bytesPerRow = (long) Math.ceil((1 / 8.0) * i * 1); long bytesPerTile = bytesPerRow * i; testTileOnImageInfo(ImageInfo.newInstance(image, 1, 1, colorModel, params), i, i, numTiles, bytesPerRow, bytesPerTile); } } private void testTileOnImageInfo(ImageInfo imageInfo, int tileWidth, int tileHeight, int numTiles, long bytesPerRow, long bytesPerTile) { assertEquals(tileWidth, imageInfo.getTileWidth()); assertEquals(tileHeight, imageInfo.getTileHeight()); assertEquals(numTiles, imageInfo.getNumTiles()); assertEquals(bytesPerRow, imageInfo.getBytesPerRow()); assertEquals(bytesPerTile, imageInfo.getBytesPerTile()); } @Test public void testGetColormap() { ImageInfo sut = ImageInfo.newInstance(image, 1, 1, new IndexColorModel(1, 2, new byte[2], new byte[2], new byte[2], new byte[2]), params); char[] colormap = sut.getColormap(); assertEquals(0, colormap[0]); colormap[0] = 1; // Assert that getColormap() returns a defensive copy assertEquals(0, sut.getColormap()[0]); } private static final class TestColorModel extends ColorModel { protected TestColorModel(ColorSpace cspace, boolean isAlphaPremultiplied) { super(1, new int[] {1, 1}, cspace, isAlphaPremultiplied, isAlphaPremultiplied, 1, 1); } @Override public int getRed(int pixel) { return 0; } @Override public int getGreen(int pixel) { return 0; } @Override public int getBlue(int pixel) { return 0; } @Override public int getAlpha(int pixel) { return 0; } } } ././@LongLink0100644 0000000 0000000 00000000145 13777276623 011657 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/codec/tiff/ImageTypeTestCase.javaxmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/codec/tiff/ImageTypeTestCase.java0100644 0000000 0000000 00000012353 13777276623 032424 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.xmlgraphics.image.codec.tiff; import java.awt.color.ColorSpace; import org.junit.Before; import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import static org.apache.xmlgraphics.image.codec.tiff.ImageType.BILEVEL_BLACK_IS_ZERO; import static org.apache.xmlgraphics.image.codec.tiff.ImageType.BILEVEL_WHITE_IS_ZERO; import static org.apache.xmlgraphics.image.codec.tiff.ImageType.CIELAB; import static org.apache.xmlgraphics.image.codec.tiff.ImageType.CMYK; import static org.apache.xmlgraphics.image.codec.tiff.ImageType.GENERIC; import static org.apache.xmlgraphics.image.codec.tiff.ImageType.GRAY; import static org.apache.xmlgraphics.image.codec.tiff.ImageType.PALETTE; import static org.apache.xmlgraphics.image.codec.tiff.ImageType.RGB; import static org.apache.xmlgraphics.image.codec.tiff.ImageType.UNSUPPORTED; import static org.apache.xmlgraphics.image.codec.tiff.ImageType.YCBCR; public class ImageTypeTestCase { private static final class ColorContainer { private final byte[] r; private final byte[] g; private final byte[] b; private ColorContainer(byte[] r, byte[] g, byte[] b) { this.r = r; this.b = b; this.g = g; } } private ColorContainer blackIsZero; private ColorContainer whiteIsZero; @Before public void setUp() { byte[] blackSetToZero = {0, (byte) 0xff}; blackIsZero = new ColorContainer(blackSetToZero, blackSetToZero, blackSetToZero); byte[] whiteSetToZero = {(byte) 0xff, 0}; whiteIsZero = new ColorContainer(whiteSetToZero, whiteSetToZero, whiteSetToZero); } @Test public void testPhotometricInterpretationValue() { assertEquals(0, BILEVEL_WHITE_IS_ZERO.getPhotometricInterpretation()); assertEquals(1, BILEVEL_BLACK_IS_ZERO.getPhotometricInterpretation()); assertEquals(1, GRAY.getPhotometricInterpretation()); assertEquals(3, PALETTE.getPhotometricInterpretation()); assertEquals(2, RGB.getPhotometricInterpretation()); assertEquals(5, CMYK.getPhotometricInterpretation()); assertEquals(6, YCBCR.getPhotometricInterpretation()); assertEquals(8, CIELAB.getPhotometricInterpretation()); assertEquals(1, GENERIC.getPhotometricInterpretation()); } @Test public void testGetTypeFromRGB() { assertEquals(BILEVEL_BLACK_IS_ZERO, ImageType.getTypeFromRGB(2, blackIsZero.r, blackIsZero.g, blackIsZero.b, 1, 1)); assertEquals(BILEVEL_WHITE_IS_ZERO, ImageType.getTypeFromRGB(2, whiteIsZero.r, whiteIsZero.g, whiteIsZero.b, 1, 1)); // Test all other values (i.e. not including 0xff) for (int b = 0; b < 255; b++) { assertEquals(PALETTE, ImageType.getTypeFromRGB(2, make2ByteArray(0, b), make2ByteArray(0, b), make2ByteArray(0, b), 1, 1)); assertEquals(PALETTE, ImageType.getTypeFromRGB(2, make2ByteArray(b, 0), make2ByteArray(b, 0), make2ByteArray(b, 0), 1, 1)); if (b != 1) { assertEquals(UNSUPPORTED, ImageType.getTypeFromRGB(2, null, null, null, 1, b)); } } } private byte[] make2ByteArray(int b1, int b2) { return new byte[] {(byte) b1, (byte) b2}; } @Test(expected = IllegalArgumentException.class) public void testException() { assertEquals(UNSUPPORTED, ImageType.getTypeFromRGB(1, null, null, null, 1, 1)); } @Test public void testGetTypeFromColorSpace() { testIndividualColorSpaceType(CMYK, ColorSpace.TYPE_CMYK, false); testIndividualColorSpaceType(GRAY, ColorSpace.TYPE_GRAY, false); testIndividualColorSpaceType(CIELAB, ColorSpace.TYPE_Lab, false); testIndividualColorSpaceType(YCBCR, ColorSpace.TYPE_YCbCr, false); testIndividualColorSpaceType(YCBCR, ColorSpace.TYPE_RGB, true); testIndividualColorSpaceType(RGB, ColorSpace.TYPE_RGB, false); } private void testIndividualColorSpaceType(ImageType expected, int type, boolean getJpegCompress) { ColorSpace colorSpace = mock(ColorSpace.class); when(colorSpace.getType()).thenReturn(type); TIFFEncodeParam params = mock(TIFFEncodeParam.class); when(params.getJPEGCompressRGBToYCbCr()).thenReturn(getJpegCompress); assertEquals(expected, ImageType.getTypeFromColorSpace(colorSpace, params)); } } ././@LongLink0100644 0000000 0000000 00000000154 13777276623 011657 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/codec/tiff/TIFFImageEncoderTestCase.javaxmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/codec/tiff/TIFFImageEncoderTestCa0100644 0000000 0000000 00000004363 13777276623 032265 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.xmlgraphics.image.codec.tiff; import java.awt.Color; import java.awt.Graphics; import java.awt.image.BufferedImage; import java.awt.image.RenderedImage; import java.io.ByteArrayOutputStream; import java.io.IOException; import org.junit.Test; import static org.junit.Assert.assertArrayEquals; import org.apache.commons.io.IOUtils; public class TIFFImageEncoderTestCase { @Test public void testGrayImage() throws IOException { testImage(BufferedImage.TYPE_BYTE_GRAY, "gray.tiff"); } @Test public void testBilevelImage() throws IOException { testImage(BufferedImage.TYPE_BYTE_BINARY, "bilevel.tiff"); } private void testImage(int imageType, String imageFileName) throws IOException { ByteArrayOutputStream byteStream = new ByteArrayOutputStream(); TIFFImageEncoder encoder = new TIFFImageEncoder(byteStream, null); encoder.encode(getImage(imageType)); byte[] actualArray = IOUtils.toByteArray(getClass().getResource(imageFileName).openStream()); assertArrayEquals(byteStream.toByteArray(), actualArray); } private RenderedImage getImage(int imageType) { BufferedImage img = new BufferedImage(400, 400, imageType); img.getSampleModel(); Graphics gfx = img.getGraphics(); gfx.setColor(Color.RED); gfx.fillRect(10, 10, 100, 100); gfx.setColor(Color.WHITE); gfx.fillRect(50, 50, 100, 100); return img; } } xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/codec/tiff/bilevel.tiff0100644 0000000 0000000 00000050052 13777276623 030533 0ustar000000000 0000000 MM* 2z2B *J j :Zz *!J"$j%')*,:-/Z02z4 57*8:J;=j>@BCE:FHZIKzM N????????????????????????????????????????????????????????????????????????????????????????????????????xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/codec/tiff/gray.tiff0100644 0000000 0000000 00000471412 13777276623 030062 0ustar000000000 0000000 MM* 2z2B  '4 @M Yf r ֊  !. :G S` ly    Њ   ( 4A MZ f LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL././@LongLink0100644 0000000 0000000 00000000145 13777276623 011657 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/loader/CorruptImagesTestCase.javaxmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/loader/CorruptImagesTestCase.java0100644 0000000 0000000 00000003251 13777276623 032562 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: CorruptImagesTestCase.java 1830541 2018-04-30 09:30:55Z ssteiner $ */ package org.apache.xmlgraphics.image.loader; import org.junit.Test; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.fail; /** * Tests for error behaviour with corrupt images. */ public class CorruptImagesTestCase { private MockImageContext imageContext = MockImageContext.getInstance(); @Test public void testCorruptPNG() throws Exception { String uri = "corrupt-image.png"; ImageSessionContext sessionContext = imageContext.newSessionContext(); ImageManager manager = imageContext.getImageManager(); try { manager.preloadImage(uri, sessionContext); fail("Expected an ImageException!"); } catch (Exception ie) { //Expected exception assertNotNull(ie.getMessage()); } } } xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/loader/DemoPainter.java0100644 0000000 0000000 00000003622 13777276623 030553 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: DemoPainter.java 606580 2007-12-23 17:45:02Z jeremias $ */ package org.apache.xmlgraphics.image.loader; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics2D; import java.awt.geom.Rectangle2D; import org.apache.xmlgraphics.java2d.Graphics2DImagePainter; public class DemoPainter implements Graphics2DImagePainter { /** {@inheritDoc} */ public Dimension getImageSize() { return new Dimension(10000, 10000); } public void paint(Graphics2D g2d, Rectangle2D area) { g2d.translate(area.getX(), area.getY()); double w = area.getWidth(); double h = area.getHeight(); //Fit in paint area Dimension imageSize = getImageSize(); double sx = w / imageSize.getWidth(); double sy = h / imageSize.getHeight(); if (sx != 1.0 || sy != 1.0) { g2d.scale(sx, sy); } g2d.setColor(Color.BLACK); g2d.setStroke(new BasicStroke()); g2d.drawRect(0, 0, imageSize.width, imageSize.height); g2d.drawOval(0, 0, imageSize.width, imageSize.height); } } xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/loader/ImageFlavorTestCase.java0100644 0000000 0000000 00000005432 13777276623 032175 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageFlavorTestCase.java 1365650 2012-07-25 15:59:30Z mehdi $ */ package org.apache.xmlgraphics.image.loader; import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import org.apache.xmlgraphics.util.MimeConstants; /** * Tests for image flavors. */ public class ImageFlavorTestCase { @Test public void testBasicFlavors() throws Exception { ImageFlavor f1; ImageFlavor f2; f1 = ImageFlavor.RAW_JPEG; f2 = ImageFlavor.RAW_PNG; assertFalse(f1.equals(f2)); assertEquals(MimeConstants.MIME_JPEG, f1.getMimeType()); assertNull(f1.getNamespace()); assertEquals(MimeConstants.MIME_PNG, f2.getMimeType()); assertNull(f2.getNamespace()); f1 = ImageFlavor.GRAPHICS2D; f2 = new ImageFlavor(ImageFlavor.GRAPHICS2D.getName()); assertTrue(f1.equals(f2)); assertNull(f1.getMimeType()); assertNull(f1.getNamespace()); } @Test public void testRefinedFlavors() throws Exception { ImageFlavor f1; ImageFlavor f2; f1 = ImageFlavor.RENDERED_IMAGE; f2 = ImageFlavor.BUFFERED_IMAGE; assertFalse(f1.equals(f2)); assertTrue(f2.isCompatible(f1)); assertFalse(f1.isCompatible(f2)); assertNull(f1.getMimeType()); assertNull(f1.getNamespace()); assertNull(f2.getMimeType()); assertNull(f2.getNamespace()); f1 = ImageFlavor.XML_DOM; f2 = new XMLNamespaceEnabledImageFlavor(ImageFlavor.XML_DOM, "http://www.w3.org/2000/svg"); assertFalse(f1.equals(f2)); assertTrue(f2.isCompatible(f1)); assertFalse(f1.isCompatible(f2)); assertEquals("text/xml", f1.getMimeType()); assertNull(f1.getNamespace()); assertEquals("text/xml", f2.getMimeType()); assertEquals("http://www.w3.org/2000/svg", f2.getNamespace()); } } xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/loader/ImageLoaderTestCase.java0100644 0000000 0000000 00000027326 13777276623 032160 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageLoaderTestCase.java 1365650 2012-07-25 15:59:30Z mehdi $ */ package org.apache.xmlgraphics.image.loader; import java.awt.color.ICC_Profile; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import javax.imageio.stream.ImageInputStream; import javax.xml.transform.Source; import javax.xml.transform.stream.StreamSource; import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.fail; import org.apache.commons.io.IOUtils; import org.apache.xmlgraphics.image.loader.impl.ImageLoaderPNG; import org.apache.xmlgraphics.image.loader.impl.ImageLoaderRawPNG; import org.apache.xmlgraphics.image.loader.impl.ImageRawStream; import org.apache.xmlgraphics.image.loader.impl.ImageRendered; import org.apache.xmlgraphics.image.loader.spi.ImageImplRegistry; import org.apache.xmlgraphics.image.loader.spi.ImageLoader; import org.apache.xmlgraphics.image.loader.spi.ImageLoaderFactory; /** * Tests for bundled ImageLoader implementations. */ public class ImageLoaderTestCase { private MockImageContext imageContext = MockImageContext.getInstance(); private MyImageSessionContext createImageSessionContext() { return new MyImageSessionContext(imageContext); } @Test public void testPNG() throws Exception { String uri = "asf-logo.png"; MyImageSessionContext sessionContext = createImageSessionContext(); ImageManager manager = imageContext.getImageManager(); ImageInfo info = manager.preloadImage(uri, sessionContext); assertNotNull("ImageInfo must not be null", info); Image img = manager.getImage(info, ImageFlavor.RENDERED_IMAGE, sessionContext); assertNotNull("Image must not be null", img); assertEquals(ImageFlavor.RENDERED_IMAGE, img.getFlavor()); ImageRendered imgRed = (ImageRendered) img; assertNotNull(imgRed.getRenderedImage()); assertEquals(169, imgRed.getRenderedImage().getWidth()); assertEquals(51, imgRed.getRenderedImage().getHeight()); info = imgRed.getInfo(); //Switch to the ImageInfo returned by the image assertEquals(126734, info.getSize().getWidthMpt()); assertEquals(38245, info.getSize().getHeightMpt()); sessionContext.checkAllStreamsClosed(); } @Test public void testGIF() throws Exception { String uri = "bgimg72dpi.gif"; MyImageSessionContext sessionContext = createImageSessionContext(); ImageManager manager = imageContext.getImageManager(); ImageInfo info = manager.preloadImage(uri, sessionContext); assertNotNull("ImageInfo must not be null", info); Image img = manager.getImage(info, ImageFlavor.RENDERED_IMAGE, sessionContext); assertNotNull("Image must not be null", img); assertEquals(ImageFlavor.RENDERED_IMAGE, img.getFlavor()); ImageRendered imgRed = (ImageRendered) img; assertNotNull(imgRed.getRenderedImage()); assertEquals(192, imgRed.getRenderedImage().getWidth()); assertEquals(192, imgRed.getRenderedImage().getHeight()); info = imgRed.getInfo(); //Switch to the ImageInfo returned by the image assertEquals(192000, info.getSize().getWidthMpt()); assertEquals(192000, info.getSize().getHeightMpt()); sessionContext.checkAllStreamsClosed(); } @Test public void testEPSASCII() throws Exception { String uri = "barcode.eps"; MyImageSessionContext sessionContext = createImageSessionContext(); ImageManager manager = imageContext.getImageManager(); ImageInfo info = manager.preloadImage(uri, sessionContext); assertNotNull("ImageInfo must not be null", info); Image img = manager.getImage(info, ImageFlavor.RAW_EPS, sessionContext); assertNotNull("Image must not be null", img); assertEquals(ImageFlavor.RAW_EPS, img.getFlavor()); ImageRawStream imgEPS = (ImageRawStream) img; InputStream in = imgEPS.createInputStream(); try { assertNotNull(in); Reader reader = new InputStreamReader(in, "US-ASCII"); char[] c = new char[4]; reader.read(c); if (!("%!PS".equals(new String(c)))) { fail("EPS header expected"); } } finally { IOUtils.closeQuietly(in); } sessionContext.checkAllStreamsClosed(); } @Test public void testEPSBinary() throws Exception { String uri = "img-with-tiff-preview.eps"; MyImageSessionContext sessionContext = createImageSessionContext(); ImageManager manager = imageContext.getImageManager(); ImageInfo info = manager.preloadImage(uri, sessionContext); assertNotNull("ImageInfo must not be null", info); Image img = manager.getImage(info, ImageFlavor.RAW_EPS, sessionContext); assertNotNull("Image must not be null", img); assertEquals(ImageFlavor.RAW_EPS, img.getFlavor()); ImageRawStream imgEPS = (ImageRawStream) img; InputStream in = imgEPS.createInputStream(); try { assertNotNull(in); Reader reader = new InputStreamReader(in, "US-ASCII"); char[] c = new char[4]; reader.read(c); if (!("%!PS".equals(new String(c)))) { fail("EPS header expected"); } } finally { IOUtils.closeQuietly(in); } sessionContext.checkAllStreamsClosed(); } @Test public void testICCProfiles() throws Exception { MyImageSessionContext sessionContext = createImageSessionContext(); List profiles = new ArrayList(); runReaders(profiles, sessionContext, "iccTest.png", "image/png", ImageFlavor.RAW_PNG); runReaders(profiles, sessionContext, "iccTest.jpg", "image/jpeg", ImageFlavor.RAW_JPEG); ICC_Profile first = profiles.get(0); byte[] firstData = first.getData(); for (int i = 1; i < profiles.size(); i++) { ICC_Profile icc = profiles.get(i); byte[] data = icc.getData(); assertEquals("Embedded ICC Profiles are not the same size!", firstData.length, data.length); for (int j = 0; j < firstData.length; j++) { assertEquals("Embedded ICC Profiles differ at index " + j, firstData[j], data[j]); } } } private void runReaders(List profiles, ImageSessionContext isc, String uri, String mime, ImageFlavor rawFlavor) throws Exception { ImageLoaderFactory[] ilfs = ImageImplRegistry.getDefaultInstance() .getImageLoaderFactories(mime); if (ilfs != null) { for (int i = 0; i < ilfs.length; i++) { ImageLoaderFactory ilf = ilfs[i]; try { final ImageLoader il = ilf.newImageLoader(rawFlavor); if (il instanceof ImageLoaderRawPNG || il instanceof ImageLoaderPNG) { // temporary measure until ImageLoaderRawPNG and ImageLoader PNG handle ICC profiles continue; } final ImageInfo im = new ImageInfo(uri, mime); final Image img = il.loadImage(im, isc); final ICC_Profile icc = img.getICCProfile(); // Assume the profile can only be correct if the image could // actually be interpreted. if (img.getColorSpace() != null) { profiles.add(icc); } } catch (IllegalArgumentException e) { // Ignore. This imageLoader does not support RAW } try { final ImageLoader il = ilf.newImageLoader(ImageFlavor.BUFFERED_IMAGE); final ImageInfo im = new ImageInfo(uri, mime); final Image img = il.loadImage(im, isc); final ICC_Profile icc = img.getICCProfile(); profiles.add(icc); } catch (IllegalArgumentException e) { // Ignore. This imageLoader does not support Buffered. } } } } @Test public void testBrokenIccPng() throws Exception { String uri = "corrupt-icc.png"; MyImageSessionContext sessionContext = createImageSessionContext(); ImageManager manager = imageContext.getImageManager(); ImageInfo info = manager.preloadImage(uri, sessionContext); assertNotNull("ImageInfo must not be null", info); Image img = manager.getImage(info, ImageFlavor.RENDERED_IMAGE, sessionContext); assertNotNull("Image must not be null", img); assertEquals(ImageFlavor.RENDERED_IMAGE, img.getFlavor()); ImageRendered imgRed = (ImageRendered) img; assertNotNull(imgRed.getRenderedImage()); assertEquals(400, imgRed.getRenderedImage().getWidth()); assertEquals(300, imgRed.getRenderedImage().getHeight()); sessionContext.checkAllStreamsClosed(); } private static class MyImageSessionContext extends MockImageSessionContext { private List streams = new java.util.ArrayList(); public MyImageSessionContext(ImageContext context) { super(context); } public Source newSource(String uri) { Source src = super.newSource(uri); if (src instanceof ImageSource) { ImageSource is = (ImageSource) src; ImageInputStream in = is.getImageInputStream(); //in = new ObservableImageInputStream(in, is.getSystemId()); in = ObservableStream.Factory.observe(in, is.getSystemId()); streams.add(in); is.setImageInputStream(in); } return src; } /** {@inheritDoc} */ protected Source resolveURI(String uri) { Source src = super.resolveURI(uri); if (src instanceof StreamSource) { StreamSource ss = (StreamSource) src; if (ss.getInputStream() != null) { InputStream in = new ObservableInputStream( ss.getInputStream(), ss.getSystemId()); streams.add(in); ss.setInputStream(in); } } return src; } public void checkAllStreamsClosed() { Iterator iter = streams.iterator(); while (iter.hasNext()) { ObservableStream stream = (ObservableStream) iter.next(); iter.remove(); if (!stream.isClosed()) { fail(stream.getClass().getName() + " is NOT closed: " + stream.getSystemID()); } } } } } ././@LongLink0100644 0000000 0000000 00000000145 13777276623 011657 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/loader/ImagePipelineTestCase.javaxmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/loader/ImagePipelineTestCase.java0100644 0000000 0000000 00000013510 13777276623 032505 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImagePipelineTestCase.java 1365650 2012-07-25 15:59:30Z mehdi $ */ package org.apache.xmlgraphics.image.loader; import java.awt.Dimension; import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import org.apache.xmlgraphics.image.loader.impl.ImageConverterBuffered2Rendered; import org.apache.xmlgraphics.image.loader.impl.ImageConverterG2D2Bitmap; import org.apache.xmlgraphics.image.loader.impl.ImageConverterRendered2PNG; import org.apache.xmlgraphics.image.loader.impl.ImageGraphics2D; import org.apache.xmlgraphics.image.loader.impl.ImageRawStream; import org.apache.xmlgraphics.image.loader.impl.imageio.ImageLoaderImageIO; import org.apache.xmlgraphics.image.loader.pipeline.ImageProviderPipeline; import org.apache.xmlgraphics.image.loader.spi.ImageLoader; import org.apache.xmlgraphics.java2d.Graphics2DImagePainter; import org.apache.xmlgraphics.util.MimeConstants; /** * Tests for the image pipeline functionality. */ public class ImagePipelineTestCase { private MockImageContext imageContext = MockImageContext.getInstance(); @Test public void testPipelineWithLoader() throws Exception { String uri = "bgimg72dpi.gif"; ImageSessionContext sessionContext = imageContext.newSessionContext(); ImageManager manager = imageContext.getImageManager(); ImageInfo info = manager.preloadImage(uri, sessionContext); assertNotNull("ImageInfo must not be null", info); ImageLoader loader = new ImageLoaderImageIO(ImageFlavor.RENDERED_IMAGE); ImageProviderPipeline pipeline = new ImageProviderPipeline(manager.getCache(), loader); pipeline.addConverter(new ImageConverterRendered2PNG()); Image img = pipeline.execute(info, null, sessionContext); assertNotNull("Image must not be null", img); assertEquals(ImageFlavor.RAW_PNG, img.getFlavor()); assertTrue(img instanceof ImageRawStream); //Original MIME type stays the same, but the flavor MIME changes assertEquals(MimeConstants.MIME_GIF, img.getInfo().getMimeType()); assertEquals(MimeConstants.MIME_PNG, img.getFlavor().getMimeType()); } @Test public void testPipelineWithoutLoader() throws Exception { ImageSessionContext sessionContext = imageContext.newSessionContext(); ImageManager manager = imageContext.getImageManager(); Image original = createG2DImage(); ImageProviderPipeline pipeline = new ImageProviderPipeline(manager.getCache(), null); pipeline.addConverter(new ImageConverterG2D2Bitmap()); pipeline.addConverter(new ImageConverterBuffered2Rendered()); pipeline.addConverter(new ImageConverterRendered2PNG()); Image img = pipeline.execute(original.getInfo(), original, null, sessionContext); assertNotNull("Image must not be null", img); assertEquals(ImageFlavor.RAW_PNG, img.getFlavor()); assertTrue(img instanceof ImageRawStream); //Original MIME type stays the same, but the flavor MIME changes assertNull(img.getInfo().getMimeType()); assertEquals(MimeConstants.MIME_PNG, img.getFlavor().getMimeType()); } private Image createG2DImage() { Graphics2DImagePainter painter = new DemoPainter(); Dimension dim = painter.getImageSize(); ImageSize size = new ImageSize(); size.setSizeInMillipoints(dim.width, dim.height); size.setResolution(72); size.calcPixelsFromSize(); ImageInfo info = new ImageInfo(null /*null is the intention here*/, null); info.setSize(size); ImageGraphics2D g2dImage = new ImageGraphics2D(info, painter); return g2dImage; } @Test public void testPipelineFromURIThroughManager() throws Exception { String uri = "asf-logo.png"; ImageSessionContext sessionContext = imageContext.newSessionContext(); ImageManager manager = imageContext.getImageManager(); ImageInfo info = manager.preloadImage(uri, sessionContext); assertNotNull("ImageInfo must not be null", info); ImageFlavor[] flavors = new ImageFlavor[] { ImageFlavor.RAW_PNG, ImageFlavor.RAW_JPEG }; Image img = manager.getImage(info, flavors, sessionContext); assertNotNull("Image must not be null", img); assertEquals(ImageFlavor.RAW_PNG, img.getFlavor()); assertTrue(img instanceof ImageRawStream); } @Test public void testPipelineWithoutURIThroughManager() throws Exception { ImageManager manager = imageContext.getImageManager(); Image original = createG2DImage(); ImageFlavor[] flavors = new ImageFlavor[] { ImageFlavor.RAW_PNG, ImageFlavor.RAW_JPEG }; Image img = manager.convertImage(original, flavors); assertNotNull("Image must not be null", img); assertEquals(ImageFlavor.RAW_PNG, img.getFlavor()); assertTrue(img instanceof ImageRawStream); } } ././@LongLink0100644 0000000 0000000 00000000146 13777276623 011660 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/loader/ImagePreloaderTestCase.javaxmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/loader/ImagePreloaderTestCase.jav0100644 0000000 0000000 00000035610 13777276623 032521 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImagePreloaderTestCase.java 1365650 2012-07-25 15:59:30Z mehdi $ */ package org.apache.xmlgraphics.image.loader; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import javax.xml.transform.Source; import javax.xml.transform.TransformerException; import javax.xml.transform.URIResolver; import javax.xml.transform.sax.SAXSource; import org.junit.Test; import org.xml.sax.InputSource; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.fail; import org.apache.xmlgraphics.image.loader.spi.ImageLoaderFactory; import org.apache.xmlgraphics.util.MimeConstants; /** * Tests for bundled Imagepreloader implementations. */ public class ImagePreloaderTestCase { private MockImageContext imageContext = MockImageContext.getInstance(); @Test public void testImageLoaderFactory() throws Exception { ImageManager manager = imageContext.getImageManager(); ImageInfo info = new ImageInfo(null, MimeConstants.MIME_PNG); ImageLoaderFactory ilf = manager.getRegistry().getImageLoaderFactory( info, ImageFlavor.BUFFERED_IMAGE); assertNotNull(ilf); } @Test public void testFileNotFound() throws Exception { String uri = "doesnotexistanywhere.png"; ImageSessionContext sessionContext = imageContext.newSessionContext(); ImageManager manager = imageContext.getImageManager(); try { manager.preloadImage(uri, sessionContext); fail("Expected a FileNotFoundException!"); } catch (FileNotFoundException e) { //expected! } } @Test public void testPNG() throws Exception { String uri = "asf-logo.png"; ImageSessionContext sessionContext = imageContext.newSessionContext(); ImageManager manager = imageContext.getImageManager(); ImageInfo info = manager.preloadImage(uri, sessionContext); assertNotNull("ImageInfo must not be null", info); assertEquals(MimeConstants.MIME_PNG, info.getMimeType()); assertEquals("asf-logo.png", info.getOriginalURI()); assertEquals(169, info.getSize().getWidthPx()); assertEquals(51, info.getSize().getHeightPx()); assertEquals(96, info.getSize().getDpiHorizontal(), 0.1); assertEquals(126734, info.getSize().getWidthMpt()); assertEquals(38245, info.getSize().getHeightMpt()); } @Test public void testPNGNoResolution() throws Exception { String uri = "no-resolution.png"; //This file contains a pHYs chunk but the resolution is set to zero. //Reported in Bugzilla #45789 ImageSessionContext sessionContext = imageContext.newSessionContext(); ImageManager manager = imageContext.getImageManager(); ImageInfo info = manager.preloadImage(uri, sessionContext); assertNotNull("ImageInfo must not be null", info); assertEquals(MimeConstants.MIME_PNG, info.getMimeType()); assertEquals("no-resolution.png", info.getOriginalURI()); assertEquals(51, info.getSize().getWidthPx()); assertEquals(24, info.getSize().getHeightPx()); //Without resolution information (or resolution=0), the default shall be used assertEquals(72, info.getSize().getDpiHorizontal(), 0.1); assertEquals(51000, info.getSize().getWidthMpt()); assertEquals(24000, info.getSize().getHeightMpt()); } @Test public void testTIFF() throws Exception { String uri = "tiff_group4.tif"; ImageSessionContext sessionContext = imageContext.newSessionContext(); ImageManager manager = imageContext.getImageManager(); ImageInfo info = manager.preloadImage(uri, sessionContext); assertNotNull("ImageInfo must not be null", info); assertEquals(MimeConstants.MIME_TIFF, info.getMimeType()); assertEquals(uri, info.getOriginalURI()); assertEquals(1560, info.getSize().getWidthPx()); assertEquals(189, info.getSize().getHeightPx()); assertEquals(204, info.getSize().getDpiHorizontal(), 0.1); assertEquals(550588, info.getSize().getWidthMpt()); assertEquals(66706, info.getSize().getHeightMpt()); } @Test public void testTIFFNoResolution() throws Exception { String uri = "no-resolution.tif"; ImageSessionContext sessionContext = imageContext.newSessionContext(); ImageManager manager = imageContext.getImageManager(); ImageInfo info = manager.preloadImage(uri, sessionContext); assertNotNull("ImageInfo must not be null", info); assertEquals(MimeConstants.MIME_TIFF, info.getMimeType()); assertEquals(uri, info.getOriginalURI()); assertEquals(51, info.getSize().getWidthPx()); assertEquals(24, info.getSize().getHeightPx()); assertEquals(imageContext.getSourceResolution(), info.getSize().getDpiHorizontal(), 0.1); assertEquals(51000, info.getSize().getWidthMpt()); assertEquals(24000, info.getSize().getHeightMpt()); } @Test public void testGIF() throws Exception { String uri = "bgimg72dpi.gif"; ImageSessionContext sessionContext = imageContext.newSessionContext(); ImageManager manager = imageContext.getImageManager(); ImageInfo info = manager.preloadImage(uri, sessionContext); assertNotNull("ImageInfo must not be null", info); assertEquals(MimeConstants.MIME_GIF, info.getMimeType()); assertEquals(uri, info.getOriginalURI()); assertEquals(192, info.getSize().getWidthPx()); assertEquals(192, info.getSize().getHeightPx()); assertEquals(imageContext.getSourceResolution(), info.getSize().getDpiHorizontal(), 0.1); assertEquals(192000, info.getSize().getWidthMpt()); assertEquals(192000, info.getSize().getHeightMpt()); } @Test public void testEMF() throws Exception { String uri = "img.emf"; ImageSessionContext sessionContext = imageContext.newSessionContext(); ImageManager manager = imageContext.getImageManager(); ImageInfo info = manager.preloadImage(uri, sessionContext); assertNotNull("ImageInfo must not be null", info); assertEquals("image/emf", info.getMimeType()); assertEquals(uri, info.getOriginalURI()); assertEquals(76, info.getSize().getWidthPx()); assertEquals(76, info.getSize().getHeightPx()); assertEquals(96, info.getSize().getDpiHorizontal(), 1.0); assertEquals(56665, info.getSize().getWidthMpt()); assertEquals(56665, info.getSize().getHeightMpt()); } @Test public void testJPEG1() throws Exception { String uri = "bgimg300dpi.jpg"; ImageSessionContext sessionContext = imageContext.newSessionContext(); ImageManager manager = imageContext.getImageManager(); ImageInfo info = manager.preloadImage(uri, sessionContext); assertNotNull("ImageInfo must not be null", info); assertEquals(MimeConstants.MIME_JPEG, info.getMimeType()); assertEquals(uri, info.getOriginalURI()); assertEquals(192, info.getSize().getWidthPx()); assertEquals(192, info.getSize().getHeightPx()); assertEquals(300, info.getSize().getDpiHorizontal(), 0.1); assertEquals(46080, info.getSize().getWidthMpt()); assertEquals(46080, info.getSize().getHeightMpt()); } @Test public void testJPEG2() throws Exception { String uri = "cmyk.jpg"; ImageSessionContext sessionContext = imageContext.newSessionContext(); ImageManager manager = imageContext.getImageManager(); ImageInfo info = manager.preloadImage(uri, sessionContext); assertNotNull("ImageInfo must not be null", info); assertEquals(MimeConstants.MIME_JPEG, info.getMimeType()); assertEquals(uri, info.getOriginalURI()); assertEquals(160, info.getSize().getWidthPx()); assertEquals(35, info.getSize().getHeightPx()); assertEquals(72, info.getSize().getDpiHorizontal(), 0.1); assertEquals(160000, info.getSize().getWidthMpt()); assertEquals(35000, info.getSize().getHeightMpt()); } @Test public void testJPEG3() throws Exception { String uri = "cmyk-pxcm.jpg"; //Contains resolution as pixels per centimeter ImageSessionContext sessionContext = imageContext.newSessionContext(); ImageManager manager = imageContext.getImageManager(); ImageInfo info = manager.preloadImage(uri, sessionContext); assertNotNull("ImageInfo must not be null", info); assertEquals(MimeConstants.MIME_JPEG, info.getMimeType()); assertEquals(uri, info.getOriginalURI()); assertEquals(160, info.getSize().getWidthPx()); assertEquals(35, info.getSize().getHeightPx()); assertEquals(71.1, info.getSize().getDpiHorizontal(), 0.1); //28 px/cm = 71.1199 dpi assertEquals(161980, info.getSize().getWidthMpt()); assertEquals(35433, info.getSize().getHeightMpt()); } @Test public void testBMP() throws Exception { String uri = "bgimg300dpi.bmp"; ImageSessionContext sessionContext = imageContext.newSessionContext(); ImageManager manager = imageContext.getImageManager(); ImageInfo info = manager.preloadImage(uri, sessionContext); assertNotNull("ImageInfo must not be null", info); assertEquals("image/bmp", info.getMimeType()); assertEquals(uri, info.getOriginalURI()); assertEquals(192, info.getSize().getWidthPx()); assertEquals(192, info.getSize().getHeightPx()); assertEquals(300, info.getSize().getDpiHorizontal(), 0.1); assertEquals(46092, info.getSize().getWidthMpt()); assertEquals(46092, info.getSize().getHeightMpt()); } @Test public void testBMPNoResolution() throws Exception { String uri = "no-resolution.bmp"; ImageSessionContext sessionContext = imageContext.newSessionContext(); ImageManager manager = imageContext.getImageManager(); ImageInfo info = manager.preloadImage(uri, sessionContext); assertNotNull("ImageInfo must not be null", info); assertEquals("image/bmp", info.getMimeType()); assertEquals(uri, info.getOriginalURI()); assertEquals(50, info.getSize().getWidthPx()); assertEquals(50, info.getSize().getHeightPx()); assertEquals(imageContext.getSourceResolution(), info.getSize().getDpiHorizontal(), 0.1); assertEquals(50000, info.getSize().getWidthMpt()); assertEquals(50000, info.getSize().getHeightMpt()); } @Test public void testEPSAscii() throws Exception { String uri = "barcode.eps"; ImageSessionContext sessionContext = imageContext.newSessionContext(); ImageManager manager = imageContext.getImageManager(); ImageInfo info = manager.preloadImage(uri, sessionContext); assertNotNull("ImageInfo must not be null", info); assertEquals(MimeConstants.MIME_EPS, info.getMimeType()); assertEquals(uri, info.getOriginalURI()); assertEquals(136, info.getSize().getWidthPx()); assertEquals(43, info.getSize().getHeightPx()); assertEquals(imageContext.getSourceResolution(), info.getSize().getDpiHorizontal(), 0.1); assertEquals(135655, info.getSize().getWidthMpt()); assertEquals(42525, info.getSize().getHeightMpt()); } @Test public void testEPSBinary() throws Exception { String uri = "img-with-tiff-preview.eps"; ImageSessionContext sessionContext = imageContext.newSessionContext(); ImageManager manager = imageContext.getImageManager(); ImageInfo info = manager.preloadImage(uri, sessionContext); assertNotNull("ImageInfo must not be null", info); assertEquals(MimeConstants.MIME_EPS, info.getMimeType()); assertEquals(uri, info.getOriginalURI()); assertEquals(17, info.getSize().getWidthPx()); assertEquals(17, info.getSize().getHeightPx()); assertEquals(imageContext.getSourceResolution(), info.getSize().getDpiHorizontal(), 0.1); assertEquals(17000, info.getSize().getWidthMpt()); assertEquals(17000, info.getSize().getHeightMpt()); } @Test public void testSAXSourceWithSystemID() throws Exception { URIResolver resolver = new URIResolver() { public Source resolve(String href, String base) throws TransformerException { if (href.startsWith("img:")) { String filename = href.substring(4); InputSource is = new InputSource(base + filename); return new SAXSource(is); } else { return null; } } }; checkImageFound("img:asf-logo.png", resolver); } @Test public void testSAXSourceWithInputStream() throws Exception { URIResolver resolver = new URIResolver() { public Source resolve(String href, String base) throws TransformerException { if (href.startsWith("img:")) { String filename = href.substring(4); InputSource is; try { is = new InputSource(new java.io.FileInputStream( new File(MockImageSessionContext.IMAGE_BASE_DIR, filename))); } catch (FileNotFoundException e) { throw new TransformerException(e); } return new SAXSource(is); } else { return null; } } }; checkImageFound("img:asf-logo.png", resolver); } private void checkImageFound(String uri, URIResolver resolver) throws ImageException, IOException { ImageSessionContext sessionContext = new SimpleURIResolverBasedImageSessionContext( imageContext, MockImageSessionContext.IMAGE_BASE_DIR, resolver); ImageManager manager = imageContext.getImageManager(); ImageInfo info = manager.preloadImage(uri, sessionContext); assertNotNull("ImageInfo must not be null", info); assertEquals(uri, info.getOriginalURI()); } } ././@LongLink0100644 0000000 0000000 00000000153 13777276623 011656 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/loader/ImageSessionContextTestCase.javaxmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/loader/ImageSessionContextTestCas0100644 0000000 0000000 00000027317 13777276623 032655 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageSessionContextTestCase.java 1391005 2012-09-27 13:39:57Z mehdi $ */ package org.apache.xmlgraphics.image.loader; import java.io.File; import java.io.FileNotFoundException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import javax.xml.transform.Source; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.URIResolver; import javax.xml.transform.dom.DOMResult; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.sax.SAXSource; import javax.xml.transform.stream.StreamSource; import org.junit.Test; import org.xml.sax.InputSource; import org.xml.sax.XMLReader; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import org.apache.xmlgraphics.image.loader.util.ImageUtil; import org.apache.xmlgraphics.io.XmlSourceUtil; /** * Tests for AbstractImageSessionContext. */ public class ImageSessionContextTestCase { private MockImageContext imageContext = MockImageContext.getInstance(); @Test public void testStreamSourceWithSystemID() throws Exception { URIResolver resolver = new URIResolver() { public Source resolve(String href, String base) throws TransformerException { if (href.startsWith("img:")) { String filename = href.substring(4); return new StreamSource(base + filename); } else { return null; } } }; String uri = "img:asf-logo.png"; ImageSource imgSrc = checkImageInputStreamAvailable(uri, resolver); assertTrue(imgSrc.isFastSource()); //Access through local file system } @Test public void testStreamSourceWithInputStream() throws Exception { URIResolver resolver = new URIResolver() { public Source resolve(String href, String base) throws TransformerException { if (href.startsWith("img:")) { String filename = href.substring(4); try { return new StreamSource(new java.io.FileInputStream( new File(MockImageSessionContext.IMAGE_BASE_DIR, filename))); } catch (FileNotFoundException e) { throw new TransformerException(e); } } else { return null; } } }; String uri = "img:asf-logo.png"; ImageSource imgSrc = checkImageInputStreamAvailable(uri, resolver); //We don't pass in the URI, so no fast source is possible assertTrue(!imgSrc.isFastSource()); } @Test public void testStreamSourceWithFile() throws Exception { URIResolver resolver = new URIResolver() { public Source resolve(String href, String base) throws TransformerException { if (href.startsWith("img:")) { String filename = href.substring(4); File f = new File(MockImageSessionContext.IMAGE_BASE_DIR, filename); return new StreamSource(f); } else { return null; } } }; String uri = "img:asf-logo.png"; ImageSource imgSrc = checkImageInputStreamAvailable(uri, resolver); assertTrue(imgSrc.isFastSource()); //Accessed through the local file system } @Test public void testStreamSourceWithInputStreamAndSystemID() throws Exception { URIResolver resolver = new URIResolver() { public Source resolve(String href, String base) throws TransformerException { if (href.startsWith("img:")) { String filename = href.substring(4); try { File f = new File(MockImageSessionContext.IMAGE_BASE_DIR, filename); return new StreamSource( new java.io.FileInputStream(f), f.toURI().toASCIIString()); } catch (FileNotFoundException e) { throw new TransformerException(e); } } else { return null; } } }; String uri = "img:asf-logo.png"; ImageSource imgSrc = checkImageInputStreamAvailable(uri, resolver); assertTrue(imgSrc.isFastSource()); //Access through local file system (thanks to the URI //being passed through by the URIResolver) } @Test public void testStreamSourceWithReader() throws Exception { URIResolver resolver = new URIResolver() { public Source resolve(String href, String base) throws TransformerException { if (href.startsWith("img:")) { String filename = href.substring(4); return new StreamSource(new java.io.StringReader(filename)); } else { return null; } } }; String uri = "img:asf-logo.png"; Source src = resolve(uri, resolver); assertTrue(src instanceof StreamSource); //Source remains unchanged assertTrue(XmlSourceUtil.hasReader(src)); } private ImageSource checkImageInputStreamAvailable(String uri, URIResolver resolver) { Source src = resolve(uri, resolver); assertNotNull("Source must not be null", src); assertTrue("Source must be an ImageSource", src instanceof ImageSource); ImageSource imgSrc = (ImageSource) src; assertTrue(ImageUtil.hasImageInputStream(imgSrc)); return imgSrc; } private Source resolve(String uri, URIResolver resolver) { ImageSessionContext sessionContext = new SimpleURIResolverBasedImageSessionContext( imageContext, MockImageSessionContext.IMAGE_BASE_DIR, resolver); Source src = sessionContext.newSource(uri); return src; } @Test public void testSAXSourceWithSystemID() throws Exception { URIResolver resolver = new URIResolver() { public Source resolve(String href, String base) throws TransformerException { if (href.startsWith("img:")) { String filename = href.substring(4); InputSource is = new InputSource(base + filename); return new SAXSource(is); } else { return null; } } }; String uri = "img:asf-logo.png"; ImageSource imgSrc = checkImageInputStreamAvailable(uri, resolver); assertTrue(imgSrc.isFastSource()); } @Test public void testSAXSourceWithInputStream() throws Exception { URIResolver resolver = new URIResolver() { public Source resolve(String href, String base) throws TransformerException { if (href.startsWith("img:")) { String filename = href.substring(4); InputSource is; try { is = new InputSource(new java.io.FileInputStream( new File(MockImageSessionContext.IMAGE_BASE_DIR, filename))); } catch (FileNotFoundException e) { throw new TransformerException(e); } return new SAXSource(is); } else { return null; } } }; String uri = "img:asf-logo.png"; checkImageInputStreamAvailable(uri, resolver); } @Test public void testSAXSourceWithReader() throws Exception { URIResolver resolver = new URIResolver() { public Source resolve(String href, String base) throws TransformerException { if (href.startsWith("img:")) { String filename = href.substring(4); InputSource is; is = new InputSource(new java.io.StringReader(filename)); return new SAXSource(is); } else { return null; } } }; String uri = "img:asf-logo.png"; Source src = resolve(uri, resolver); assertTrue(src instanceof SAXSource); //Source remains unchanged assertTrue(XmlSourceUtil.hasReader(src)); } private static final String SOME_XML = "Hello World!"; @Test public void testSAXSourceWithXMLReader() throws Exception { URIResolver resolver = new URIResolver() { public Source resolve(String href, String base) throws TransformerException { if (href.startsWith("xml:")) { String xml = href.substring(4); InputSource is = new InputSource(new java.io.StringReader(xml)); return new SAXSource(createSomeXMLReader(), is); } else { return null; } } }; String uri = "xml:" + SOME_XML; Source src = resolve(uri, resolver); assertTrue(src instanceof SAXSource); //Source remains unchanged SAXSource saxSrc = (SAXSource) src; assertNotNull(saxSrc.getXMLReader()); assertNotNull(saxSrc.getInputSource()); } @Test public void testDOMSource() throws Exception { URIResolver resolver = new URIResolver() { public Source resolve(String href, String base) throws TransformerException { if (href.startsWith("xml:")) { String xml = href.substring(4); InputSource is = new InputSource(new java.io.StringReader(xml)); SAXSource sax = new SAXSource(createSomeXMLReader(), is); //Convert SAXSource to DOMSource TransformerFactory tFactory = TransformerFactory.newInstance(); Transformer transformer = tFactory.newTransformer(); DOMResult res = new DOMResult(); transformer.transform(sax, res); return new DOMSource(res.getNode()); } else { return null; } } }; String uri = "xml:" + SOME_XML; Source src = resolve(uri, resolver); assertTrue(src instanceof DOMSource); //Source remains unchanged DOMSource domSrc = (DOMSource) src; assertNotNull(domSrc.getNode()); } private XMLReader createSomeXMLReader() { SAXParserFactory parserFactory = SAXParserFactory.newInstance(); SAXParser parser; try { parser = parserFactory.newSAXParser(); return parser.getXMLReader(); } catch (Exception e) { fail("Could not create XMLReader"); return null; } } } xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/loader/ImageUtilTestCase.java0100644 0000000 0000000 00000006643 13777276623 031666 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageUtilTestCase.java 1365650 2012-07-25 15:59:30Z mehdi $ */ package org.apache.xmlgraphics.image.loader; import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.fail; import org.apache.xmlgraphics.image.loader.util.ImageUtil; /** * Tests for the ImageUtil class. */ public class ImageUtilTestCase { /** * Tests {@link ImageUtil.needPageIndexFromURI(String)}. * @throws Exception if an error occurs */ @Test public void testNeedPageIndex() throws Exception { int pageIndex; pageIndex = ImageUtil.needPageIndexFromURI("http://localhost/images/scan1.tif"); assertEquals(0, pageIndex); pageIndex = ImageUtil.needPageIndexFromURI("http://localhost/images/scan1.tif#page=3"); assertEquals(2, pageIndex); pageIndex = ImageUtil.needPageIndexFromURI("http://localhost/images/scan1.tif#page=0"); assertEquals(0, pageIndex); pageIndex = ImageUtil.needPageIndexFromURI("http://localhost/images/scan1.tif#page="); assertEquals(0, pageIndex); pageIndex = ImageUtil.needPageIndexFromURI("http://localhost/images/scan1.tif#page=x"); assertEquals(0, pageIndex); pageIndex = ImageUtil.needPageIndexFromURI("http://localhost/images/scan1.tif#page=-1"); assertEquals(0, pageIndex); pageIndex = ImageUtil.needPageIndexFromURI("#page=2"); assertEquals(1, pageIndex); //Not a valid URI try { pageIndex = ImageUtil.needPageIndexFromURI("C:\\images\\scan1.tif#page=44"); fail("Invalid URI. Method must fail."); } catch (IllegalArgumentException e) { //expected } //Valid URI pageIndex = ImageUtil.needPageIndexFromURI("file:///C:/images/scan1.tif#page=44"); assertEquals(43, pageIndex); } /** * Tests {@link ImageUtil.getPageIndexFromURI(String)}. * @throws Exception if an error occurs */ @Test public void testGetPageIndex() throws Exception { Integer pageIndex; pageIndex = ImageUtil.getPageIndexFromURI("http://localhost/images/scan1.tif"); assertNull(pageIndex); pageIndex = ImageUtil.getPageIndexFromURI("http://localhost/images/scan1.tif#page=3"); assertEquals(2, pageIndex.intValue()); //Note: no detailed test anymore as this is tested through needPageIndexFromURI(). //getPageIndexFromURI only works on URIs, so ignore anything that doesn't have a '#' pageIndex = ImageUtil.getPageIndexFromURI("C:\\Temp\\scan1.tif"); assertNull(pageIndex); } } xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/loader/MockImageContext.java0100644 0000000 0000000 00000007275 13777276623 031555 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: MockImageContext.java 924666 2010-03-18 08:26:30Z jeremias $ */ package org.apache.xmlgraphics.image.loader; import org.apache.xmlgraphics.image.loader.impl.ImageConverterBitmap2G2D; import org.apache.xmlgraphics.image.loader.impl.ImageConverterBuffered2Rendered; import org.apache.xmlgraphics.image.loader.impl.ImageConverterG2D2Bitmap; import org.apache.xmlgraphics.image.loader.impl.ImageLoaderFactoryInternalTIFF; import org.apache.xmlgraphics.image.loader.impl.ImageLoaderFactoryRawCCITTFax; import org.apache.xmlgraphics.image.loader.impl.PreloaderEPS; import org.apache.xmlgraphics.image.loader.impl.PreloaderJPEG; import org.apache.xmlgraphics.image.loader.impl.PreloaderTIFF; import org.apache.xmlgraphics.image.loader.spi.ImageImplRegistry; /** * Mock implementation for testing. */ public class MockImageContext implements ImageContext { private static MockImageContext instance; private ImageManager imageManager; /** * Returns a singleton instance of the mock image context. * @return the singleton */ public static MockImageContext getInstance() { if (instance == null) { instance = new MockImageContext(true); } return instance; } /** * Returns an image context for testing that only contains platform- and classpath-independent * implementations so consistent test results can be obtained irrespective of the test * environment. * @return a new image context */ public static MockImageContext newSafeInstance() { MockImageContext ic = new MockImageContext(false); ImageImplRegistry registry = ic.getImageManager().getRegistry(); registry.registerPreloader(new PreloaderTIFF()); registry.registerPreloader(new PreloaderJPEG()); registry.registerPreloader(new PreloaderEPS()); registry.registerLoaderFactory(new ImageLoaderFactoryInternalTIFF()); registry.registerLoaderFactory(new ImageLoaderFactoryRawCCITTFax()); registry.registerConverter(new ImageConverterBitmap2G2D()); registry.registerConverter(new ImageConverterG2D2Bitmap()); registry.registerConverter(new ImageConverterBuffered2Rendered()); return ic; } /** * Creates a new mock image context. * @param discover true to enable plug-in discovery */ public MockImageContext(boolean discover) { this.imageManager = new ImageManager(new ImageImplRegistry(discover), this); } /** {@inheritDoc} */ public float getSourceResolution() { return 72; } /** * Returns the image manager. * @return the image manager */ public ImageManager getImageManager() { return this.imageManager; } /** * Creates a new image session context. * @return the image session context */ public ImageSessionContext newSessionContext() { return new MockImageSessionContext(this); } } ././@LongLink0100644 0000000 0000000 00000000147 13777276623 011661 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/loader/MockImageSessionContext.javaxmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/loader/MockImageSessionContext.ja0100644 0000000 0000000 00000002622 13777276623 032561 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: MockImageSessionContext.java 750418 2009-03-05 11:03:54Z vhennebert $ */ package org.apache.xmlgraphics.image.loader; import java.io.File; import org.apache.xmlgraphics.image.loader.impl.DefaultImageSessionContext; /** * Mock implementation for testing. */ public class MockImageSessionContext extends DefaultImageSessionContext { public static final File IMAGE_BASE_DIR = new File("./test/images/"); public MockImageSessionContext(ImageContext context) { super(context, IMAGE_BASE_DIR); } /** {@inheritDoc} */ public float getTargetResolution() { return 300; } } ././@LongLink0100644 0000000 0000000 00000000145 13777276623 011657 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/loader/ObservableInputStream.javaxmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/loader/ObservableInputStream.java0100644 0000000 0000000 00000004561 13777276623 032627 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ObservableInputStream.java 750418 2009-03-05 11:03:54Z vhennebert $ */ package org.apache.xmlgraphics.image.loader; import java.io.FilterInputStream; import java.io.IOException; import java.io.InputStream; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * This is a proxying input stream that records whether a stream has been closed or not. */ public class ObservableInputStream extends FilterInputStream implements ObservableStream { /** logger */ protected static Log log = LogFactory.getLog(ObservableInputStream.class); private boolean closed; private String systemID; /** * Main constructor. * @param in the underlying input stream * @param systemID the system ID for the input stream for reference */ public ObservableInputStream(InputStream in, String systemID) { super(in); this.systemID = systemID; } /** {@inheritDoc} */ public void close() throws IOException { if (!closed) { log.debug("Stream is being closed: " + getSystemID()); try { this.in.close(); } catch (IOException ioe) { log.error("Error while closing underlying stream: " + ioe.getMessage()); } closed = true; } else { throw new IllegalStateException("Stream is already closed!"); } } /** {@inheritDoc} */ public boolean isClosed() { return this.closed; } /** {@inheritDoc} */ public String getSystemID() { return this.systemID; } } xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/loader/ObservableStream.java0100644 0000000 0000000 00000007165 13777276623 031612 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ObservableStream.java 1365650 2012-07-25 15:59:30Z mehdi $ */ package org.apache.xmlgraphics.image.loader; import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import javax.imageio.stream.ImageInputStream; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * Implemented by observable streams. */ public interface ObservableStream { /** * Indicates whether the stream has been closed. * @return true if the stream is closed */ boolean isClosed(); /** * Returns the system ID for the stream being observed. * @return the system ID */ String getSystemID(); public static class Factory { public static ImageInputStream observe(ImageInputStream iin, String systemID) { return (ImageInputStream) Proxy.newProxyInstance( Factory.class.getClassLoader(), new Class[] {ImageInputStream.class, ObservableStream.class}, new ObservingImageInputStreamInvocationHandler(iin, systemID)); } } public static class ObservingImageInputStreamInvocationHandler implements InvocationHandler, ObservableStream { /** logger */ protected static Log log = LogFactory.getLog(ObservableInputStream.class); private ImageInputStream iin; private boolean closed; private String systemID; public ObservingImageInputStreamInvocationHandler(ImageInputStream iin, String systemID) { this.iin = iin; this.systemID = systemID; } /** {@inheritDoc} */ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if (method.getDeclaringClass().equals(ObservableStream.class)) { return method.invoke(this, args); } else if ("close".equals(method.getName())) { if (!closed) { log.debug("Stream is being closed: " + getSystemID()); closed = true; try { return method.invoke(iin, args); } catch (InvocationTargetException ite) { log.error("Error while closing underlying stream: " + ite.getMessage()); throw ite; } } else { throw new IllegalStateException("Stream is already closed!"); } } else { return method.invoke(iin, args); } } /** {@inheritDoc} */ public String getSystemID() { return this.systemID; } /** {@inheritDoc} */ public boolean isClosed() { return this.closed; } } } xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/loader/PenaltyTestCase.java0100644 0000000 0000000 00000005375 13777276623 031423 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: PenaltyTestCase.java 1365650 2012-07-25 15:59:30Z mehdi $ */ package org.apache.xmlgraphics.image.loader; import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import org.apache.xmlgraphics.image.loader.util.Penalty; /** * Tests for the {@link Penalty}. */ public class PenaltyTestCase { /** * Tests for penalty handling. * @throws Exception if an error occurs */ @Test public void testTruncatePenalty() throws Exception { assertEquals(0, Penalty.truncate(0)); long penalty = Integer.MAX_VALUE; assertEquals(Integer.MAX_VALUE, Penalty.truncate(penalty)); //Force integer wrap-around penalty++; assertEquals(Integer.MAX_VALUE, Penalty.truncate(penalty)); //For comparison, normal casting does this assertEquals(Integer.MIN_VALUE, (int) penalty); //Now on the other end of the spectrum... penalty = Integer.MIN_VALUE; assertEquals(Integer.MIN_VALUE, Penalty.truncate(penalty)); //Force integer wrap-around penalty -= 500; assertEquals(Integer.MIN_VALUE, Penalty.truncate(penalty)); //For comparison, normal casting does this assertEquals(Integer.MAX_VALUE - 499, (int) penalty); } /** * Tests for the {@link Penalty} class. * @throws Exception if an error occurs */ @Test public void testPenalty() throws Exception { Penalty p1 = Penalty.toPenalty(100); assertEquals(100, p1.getValue()); Penalty p2 = p1.add(Penalty.toPenalty(50)); assertEquals(150, p2.getValue()); p1 = Penalty.toPenalty(0); assertEquals(0, p1.getValue()); p1 = Penalty.INFINITE_PENALTY; assertEquals(Integer.MAX_VALUE, p1.getValue()); assertTrue(p1.isInfinitePenalty()); p2 = p1.add(p2); assertEquals(Integer.MAX_VALUE, p2.getValue()); assertTrue(p2.isInfinitePenalty()); } } ././@LongLink0100644 0000000 0000000 00000000147 13777276623 011661 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/loader/PipelineFactoryTestCase.javaxmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/loader/PipelineFactoryTestCase.ja0100644 0000000 0000000 00000022117 13777276623 032546 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: PipelineFactoryTestCase.java 1681108 2015-05-22 13:26:12Z ssteiner $ */ package org.apache.xmlgraphics.image.loader; import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.fail; import org.apache.xmlgraphics.image.codec.tiff.TIFFImage; import org.apache.xmlgraphics.image.loader.impl.ImageLoaderRawCCITTFax; import org.apache.xmlgraphics.image.loader.mocks.MockImageLoaderFactoryTIFF; import org.apache.xmlgraphics.image.loader.pipeline.ImageProviderPipeline; import org.apache.xmlgraphics.image.loader.pipeline.PipelineFactory; import org.apache.xmlgraphics.image.loader.spi.ImageImplRegistry; import org.apache.xmlgraphics.image.loader.util.Penalty; /** * Tests the pipeline factory. */ public class PipelineFactoryTestCase { /** * Tests the pipeline factory by checking to load a TIFF image. * @throws Exception if an error occurs */ @Test public void testPipelineFactoryPlain() throws Exception { MockImageContext imageContext = MockImageContext.newSafeInstance(); ImageManager manager = imageContext.getImageManager(); PipelineFactory pFactory = new PipelineFactory(manager); //Input is some TIFF file ImageInfo imageInfo = new ImageInfo("test:tiff", "image/tiff"); //We want a G2D image ImageFlavor targetFlavor = ImageFlavor.GRAPHICS2D; ImageProviderPipeline pipeline = pFactory.newImageConverterPipeline( imageInfo, targetFlavor); assertNotNull(pipeline); assertEquals(pipeline.getTargetFlavor(), targetFlavor); //penalty for internal TIFF implementation (fallback role) is 1000 + 10 for the conversion assertEquals(1010, pipeline.getConversionPenalty()); assertEquals(ImageFlavor.GRAPHICS2D, pipeline.getTargetFlavor()); if (pipeline.toString().indexOf("LoaderInternalTIFF") < 0) { fail("Chose the wrong pipeline: " + pipeline.toString()); } if (pipeline.toString().indexOf("ImageConverterBitmap2G2D") < 0) { fail("Chose the wrong pipeline: " + pipeline.toString()); } ImageProviderPipeline[] candidates = pFactory.determineCandidatePipelines( imageInfo, new ImageFlavor[] {targetFlavor}); assertEquals(1, candidates.length); //Now add another implementation that poses as TIFF loader imageContext.getImageManager().getRegistry().registerLoaderFactory( new MockImageLoaderFactoryTIFF()); candidates = pFactory.determineCandidatePipelines( imageInfo, targetFlavor); assertEquals(3, candidates.length); //3 because the mock impl provides Buffered- and RenderedImage capabilities pipeline = pFactory.newImageConverterPipeline(imageInfo, targetFlavor); assertNotNull(pipeline); assertEquals(pipeline.getTargetFlavor(), targetFlavor); //Assuming mock impl without penalty + 10 for the conversion assertEquals(10, pipeline.getConversionPenalty()); assertEquals(ImageFlavor.GRAPHICS2D, pipeline.getTargetFlavor()); if (pipeline.toString().indexOf(MockImageLoaderFactoryTIFF.class.getName()) < 0) { fail("Chose the wrong pipeline: " + pipeline.toString()); } if (pipeline.toString().indexOf("ImageConverterBitmap2G2D") < 0) { fail("Chose the wrong pipeline: " + pipeline.toString()); } } /** * Similar test as above but here we take raw CCITT loading into consideration, too. * @throws Exception if an error occurs */ @Test public void testPipelineFactoryImageInfoDependency() throws Exception { MockImageContext imageContext = MockImageContext.newSafeInstance(); ImageManager manager = imageContext.getImageManager(); PipelineFactory pFactory = new PipelineFactory(manager); //Input is some TIFF file with CCITT Group 4 compression ImageInfo imageInfo = new ImageInfo("test:tiff", "image/tiff"); imageInfo.getCustomObjects().put("TIFF_STRIP_COUNT", 1); imageInfo.getCustomObjects().put("TIFF_COMPRESSION", TIFFImage.COMP_FAX_G4_2D); //We want either a G2D image or a raw CCITT image ImageFlavor[] targetFlavors = new ImageFlavor[] { ImageFlavor.GRAPHICS2D, ImageFlavor.RAW_CCITTFAX}; ImageProviderPipeline[] candidates = pFactory.determineCandidatePipelines( imageInfo, targetFlavors); assertNotNull(candidates); assertEquals(2, candidates.length); ImageProviderPipeline pipeline = manager.choosePipeline(candidates); //0 penalty because the raw loader is the most efficient choice here assertEquals(0, pipeline.getConversionPenalty()); assertEquals(ImageFlavor.RAW_CCITTFAX, pipeline.getTargetFlavor()); if (pipeline.toString().indexOf("LoaderRawCCITTFax") < 0) { fail("Chose the wrong pipeline: " + pipeline.toString()); } //Now, we set this to a multi-strip TIFF which should disable the raw loader imageInfo.getCustomObjects().put("TIFF_STRIP_COUNT", 7); candidates = pFactory.determineCandidatePipelines( imageInfo, targetFlavors); assertNotNull(candidates); assertEquals(1, candidates.length); pipeline = manager.choosePipeline(candidates); //penalty for internal TIFF implementation (fallback role) is 1000 + 10 for the conversion assertEquals(1010, pipeline.getConversionPenalty()); assertEquals(ImageFlavor.GRAPHICS2D, pipeline.getTargetFlavor()); if (pipeline.toString().indexOf("LoaderInternalTIFF") < 0) { fail("Chose the wrong pipeline: " + pipeline.toString()); } if (pipeline.toString().indexOf("ImageConverterBitmap2G2D") < 0) { fail("Chose the wrong pipeline: " + pipeline.toString()); } } /** * Similar test as above but now we're playing with additional penalties in the registry. * @throws Exception if an error occurs */ @Test public void testPipelineFactoryAdditionalPenalty() throws Exception { MockImageContext imageContext = MockImageContext.newSafeInstance(); ImageManager manager = imageContext.getImageManager(); PipelineFactory pFactory = new PipelineFactory(manager); //Adding additional penalty for CCITT loading ImageImplRegistry registry = imageContext.getImageManager().getRegistry(); registry.setAdditionalPenalty(ImageLoaderRawCCITTFax.class.getName(), Penalty.toPenalty(10000)); //Input is some TIFF file with CCITT Group 4 compression ImageInfo imageInfo = new ImageInfo("test:tiff", "image/tiff"); imageInfo.getCustomObjects().put("TIFF_STRIP_COUNT", 1); imageInfo.getCustomObjects().put("TIFF_COMPRESSION", TIFFImage.COMP_FAX_G4_2D); //We want either a G2D image or a raw CCITT image ImageFlavor[] targetFlavors = new ImageFlavor[] { ImageFlavor.GRAPHICS2D, ImageFlavor.RAW_CCITTFAX}; ImageProviderPipeline[] candidates = pFactory.determineCandidatePipelines( imageInfo, targetFlavors); assertNotNull(candidates); assertEquals(2, candidates.length); ImageProviderPipeline pipeline = manager.choosePipeline(candidates); //penalty for internal TIFF implementation (fallback role) is 1000 + 10 for the conversion assertEquals(1010, pipeline.getConversionPenalty()); assertEquals(ImageFlavor.GRAPHICS2D, pipeline.getTargetFlavor()); if (pipeline.toString().indexOf("LoaderInternalTIFF") < 0) { fail("Chose the wrong pipeline: " + pipeline.toString()); } if (pipeline.toString().indexOf("ImageConverterBitmap2G2D") < 0) { fail("Chose the wrong pipeline: " + pipeline.toString()); } //Now set an infinite penalty making the solution ineligible registry.setAdditionalPenalty(ImageLoaderRawCCITTFax.class.getName(), Penalty.INFINITE_PENALTY); candidates = pFactory.determineCandidatePipelines(imageInfo, targetFlavors); assertNotNull(candidates); assertEquals(1, candidates.length); //While earlier 2 candidates were returned, here we only get 1 because of the infinite //penalty. } } ././@LongLink0100644 0000000 0000000 00000000171 13777276623 011656 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/loader/SimpleURIResolverBasedImageSessionContext.javaxmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/loader/SimpleURIResolverBasedImag0100644 0000000 0000000 00000003767 13777276623 032526 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: SimpleURIResolverBasedImageSessionContext.java 1365650 2012-07-25 15:59:30Z mehdi $ */ package org.apache.xmlgraphics.image.loader; import java.io.File; import javax.xml.transform.Source; import javax.xml.transform.TransformerException; import javax.xml.transform.URIResolver; import org.apache.xmlgraphics.image.loader.impl.DefaultImageSessionContext; /** * ImageSessionContext which uses a URIResolver to resolve URIs. */ public class SimpleURIResolverBasedImageSessionContext extends DefaultImageSessionContext { private URIResolver resolver; /** * Main constructor * @param context the parent image context * @param baseDir the base directory * @param resolver the URI resolver */ public SimpleURIResolverBasedImageSessionContext(ImageContext context, File baseDir, URIResolver resolver) { super(context, baseDir); this.resolver = resolver; } /** {@inheritDoc} */ protected Source resolveURI(String uri) { try { return this.resolver.resolve(uri, getBaseDir().toURI().toASCIIString()); } catch (TransformerException e) { e.printStackTrace(); return null; } } } ././@LongLink0100644 0000000 0000000 00000000165 13777276623 011661 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/loader/cache/DefaultExpirationPolicyTestCase.javaxmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/loader/cache/DefaultExpirationPol0100644 0000000 0000000 00000004540 13777276623 032571 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: DefaultExpirationPolicyTestCase.java 1365650 2012-07-25 15:59:30Z mehdi $ */ package org.apache.xmlgraphics.image.loader.cache; import org.junit.Test; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; /** * Tests {@link DefaultExpirationPolicy}. */ public class DefaultExpirationPolicyTestCase { /** * Never expire. * @throws Exception if an error occurs */ @Test public void testNeverExpire() throws Exception { ExpirationPolicy policy; policy = new DefaultExpirationPolicy(DefaultExpirationPolicy.EXPIRATION_NEVER); MockTimeStampProvider provider = new MockTimeStampProvider(); long ts = 1000000; assertFalse(policy.isExpired(provider, ts)); provider.setTimeStamp(ts + Integer.MAX_VALUE); assertFalse(policy.isExpired(provider, ts)); } /** * Normal expiration * @throws Exception if an error occurs */ @Test public void testNormalExpiration() throws Exception { ExpirationPolicy policy; policy = new DefaultExpirationPolicy(2); MockTimeStampProvider provider = new MockTimeStampProvider(); long ts = 1000000; provider.setTimeStamp(ts); assertFalse(policy.isExpired(provider, ts)); provider.setTimeStamp(ts + 1000); assertFalse(policy.isExpired(provider, ts)); provider.setTimeStamp(ts + 2000); assertTrue(policy.isExpired(provider, ts)); provider.setTimeStamp(ts + 3000); assertTrue(policy.isExpired(provider, ts)); } } ././@LongLink0100644 0000000 0000000 00000000161 13777276623 011655 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/loader/cache/ImageCacheLoggingStatistics.javaxmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/loader/cache/ImageCacheLoggingSta0100644 0000000 0000000 00000004350 13777276623 032413 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageCacheLoggingStatistics.java 750418 2009-03-05 11:03:54Z vhennebert $ */ package org.apache.xmlgraphics.image.loader.cache; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * ImageCacheListener implementation for debugging purposes. */ public class ImageCacheLoggingStatistics extends ImageCacheStatistics { /** logger */ protected static Log log = LogFactory.getLog(ImageCacheLoggingStatistics.class); /** * Main constructor. * @param detailed true if statistics for each URI should be kept. */ public ImageCacheLoggingStatistics(boolean detailed) { super(detailed); } /** {@inheritDoc} */ public void invalidHit(String uri) { super.invalidHit(uri); log.info("Invalid HIT: " + uri); } /** {@inheritDoc} */ public void cacheHitImage(ImageKey key) { super.cacheHitImage(key); log.info("Image Cache HIT: " + key); } /** {@inheritDoc} */ public void cacheHitImageInfo(String uri) { super.cacheHitImageInfo(uri); log.info("ImageInfo Cache HIT: " + uri); } /** {@inheritDoc} */ public void cacheMissImage(ImageKey key) { super.cacheMissImage(key); log.info("Image Cache MISS: " + key); } /** {@inheritDoc} */ public void cacheMissImageInfo(String uri) { super.cacheMissImageInfo(uri); log.info("ImageInfo Cache MISS: " + uri); } } ././@LongLink0100644 0000000 0000000 00000000150 13777276623 011653 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/loader/cache/ImageCacheTestCase.javaxmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/loader/cache/ImageCacheTestCase.j0100644 0000000 0000000 00000016424 13777276623 032325 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageCacheTestCase.java 1365650 2012-07-25 15:59:30Z mehdi $ */ package org.apache.xmlgraphics.image.loader.cache; import java.io.FileNotFoundException; import org.junit.Before; import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import org.apache.xmlgraphics.image.loader.ImageFlavor; import org.apache.xmlgraphics.image.loader.ImageInfo; import org.apache.xmlgraphics.image.loader.ImageManager; import org.apache.xmlgraphics.image.loader.ImageSessionContext; import org.apache.xmlgraphics.image.loader.MockImageContext; import org.apache.xmlgraphics.image.loader.impl.ImageBuffered; /** * Tests for bundled ImageLoader implementations. */ public class ImageCacheTestCase { private static final boolean DEBUG = false; private MockImageContext imageContext = MockImageContext.getInstance(); private ImageSessionContext sessionContext = imageContext.newSessionContext(); private ImageManager manager = imageContext.getImageManager(); private ImageCacheStatistics statistics = (DEBUG ? new ImageCacheLoggingStatistics(true) : new ImageCacheStatistics(true)); /** {@inheritDoc} */ @Before public void setUp() throws Exception { manager.getCache().clearCache(); statistics.reset(); manager.getCache().setCacheListener(statistics); } /** * Tests the ImageInfo cache. * @throws Exception if an error occurs */ @Test public void testImageInfoCache() throws Exception { String invalid1 = "invalid1.jpg"; String invalid2 = "invalid2.jpg"; String valid1 = "bgimg300dpi.bmp"; String valid2 = "big-image.png"; ImageInfo info1; ImageInfo info2; info1 = manager.getImageInfo(valid1, sessionContext); assertNotNull(info1); assertEquals(valid1, info1.getOriginalURI()); try { manager.getImageInfo(invalid1, sessionContext); fail("Expected FileNotFoundException for invalid URI"); } catch (FileNotFoundException e) { //expected } //2 requests: assertEquals(0, statistics.getImageInfoCacheHits()); assertEquals(2, statistics.getImageInfoCacheMisses()); assertEquals(0, statistics.getInvalidHits()); statistics.reset(); //Cache Hit info1 = manager.getImageInfo(valid1, sessionContext); assertNotNull(info1); assertEquals(valid1, info1.getOriginalURI()); //Cache Miss info2 = manager.getImageInfo(valid2, sessionContext); assertNotNull(info2); assertEquals(valid2, info2.getOriginalURI()); try { //Invalid Hit manager.getImageInfo(invalid1, sessionContext); fail("Expected FileNotFoundException for invalid URI"); } catch (FileNotFoundException e) { //expected } try { //Invalid (Cache Miss) manager.getImageInfo(invalid2, sessionContext); fail("Expected FileNotFoundException for invalid URI"); } catch (FileNotFoundException e) { //expected } //4 requests: assertEquals(1, statistics.getImageInfoCacheHits()); assertEquals(2, statistics.getImageInfoCacheMisses()); assertEquals(1, statistics.getInvalidHits()); statistics.reset(); } @Test public void testInvalidURIExpiration() throws Exception { MockTimeStampProvider provider = new MockTimeStampProvider(); ImageCache cache = new ImageCache(provider, new DefaultExpirationPolicy(2)); cache.setCacheListener(statistics); String invalid1 = "invalid1.jpg"; String invalid2 = "invalid2.jpg"; String valid1 = "valid1.jpg"; provider.setTimeStamp(1000); cache.registerInvalidURI(invalid1); provider.setTimeStamp(1100); cache.registerInvalidURI(invalid2); assertEquals(0, statistics.getInvalidHits()); //not expired, yet provider.setTimeStamp(1200); assertFalse(cache.isInvalidURI(valid1)); assertTrue(cache.isInvalidURI(invalid1)); assertTrue(cache.isInvalidURI(invalid2)); assertEquals(2, statistics.getInvalidHits()); //first expiration time reached provider.setTimeStamp(3050); assertFalse(cache.isInvalidURI(valid1)); assertFalse(cache.isInvalidURI(invalid1)); assertTrue(cache.isInvalidURI(invalid2)); assertEquals(3, statistics.getInvalidHits()); //second expiration time reached provider.setTimeStamp(3200); assertFalse(cache.isInvalidURI(valid1)); assertFalse(cache.isInvalidURI(invalid1)); assertFalse(cache.isInvalidURI(invalid2)); assertEquals(3, statistics.getInvalidHits()); } /** * Tests the image cache reusing a cacheable Image created by the ImageLoader. * @throws Exception if an error occurs */ @Test public void testImageCache1() throws Exception { String valid1 = "bgimg72dpi.gif"; ImageInfo info = manager.getImageInfo(valid1, sessionContext); assertNotNull(info); ImageBuffered img1 = (ImageBuffered) manager.getImage( info, ImageFlavor.BUFFERED_IMAGE, sessionContext); assertNotNull(img1); assertNotNull(img1.getBufferedImage()); ImageBuffered img2 = (ImageBuffered) manager.getImage( info, ImageFlavor.BUFFERED_IMAGE, sessionContext); //ImageBuffered does not have to be the same instance but we want at least the //BufferedImage to be reused. assertTrue("BufferedImage must be reused", img1.getBufferedImage() == img2.getBufferedImage()); assertEquals(1, statistics.getImageCacheHits()); assertEquals(1, statistics.getImageCacheMisses()); } /** * Test to check if doInvalidURIHouseKeeping() throws a * ConcurrentModificationException. */ @Test public void testImageCacheHouseKeeping() { ImageCache imageCache = new ImageCache(new TimeStampProvider(), new DefaultExpirationPolicy(1)); imageCache.registerInvalidURI("invalid"); imageCache.registerInvalidURI("invalid2"); try { Thread.sleep(1200); } catch (InterruptedException e) { e.printStackTrace(); } imageCache.doHouseKeeping(); } } ././@LongLink0100644 0000000 0000000 00000000153 13777276623 011656 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/loader/cache/MockTimeStampProvider.javaxmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/loader/cache/MockTimeStampProvide0100644 0000000 0000000 00000002603 13777276623 032533 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: MockTimeStampProvider.java 759144 2009-03-27 14:16:18Z jeremias $ */ package org.apache.xmlgraphics.image.loader.cache; /** * Mock subclass of the TimeStampProvider. */ class MockTimeStampProvider extends TimeStampProvider { private long timestamp; public MockTimeStampProvider() { this(0); } public MockTimeStampProvider(long timestamp) { setTimeStamp(timestamp); } public void setTimeStamp(long timestamp) { this.timestamp = timestamp; } /** {@inheritDoc} */ public long getTimeStamp() { return this.timestamp; } } ././@LongLink0100644 0000000 0000000 00000000165 13777276623 011661 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/loader/impl/ImageConverterG2D2BitmapTestCase.javaxmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/loader/impl/ImageConverterG2D2Bit0100644 0000000 0000000 00000004542 13777276623 032317 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id$ */ package org.apache.xmlgraphics.image.loader.impl; import java.awt.Dimension; import java.awt.Graphics2D; import java.awt.geom.Rectangle2D; import java.util.HashMap; import org.junit.Assert; import org.junit.Test; import org.apache.xmlgraphics.image.loader.ImageInfo; import org.apache.xmlgraphics.image.loader.ImageProcessingHints; import org.apache.xmlgraphics.image.loader.ImageSize; import org.apache.xmlgraphics.java2d.Graphics2DImagePainter; import org.apache.xmlgraphics.java2d.color.DeviceCMYKColorSpace; public class ImageConverterG2D2BitmapTestCase { @Test public void testConvert() { ImageInfo info = new ImageInfo(null, null); ImageSize imageSize = new ImageSize(100, 100, 72); imageSize.calcSizeFromPixels(); info.setSize(imageSize); HashMap hints = new HashMap(); hints.put(ImageProcessingHints.TRANSPARENCY_INTENT, ImageProcessingHints.TRANSPARENCY_INTENT_IGNORE); hints.put("CMYK", true); ImageBuffered image = (ImageBuffered) new ImageConverterG2D2Bitmap().convert( new ImageGraphics2D(info, new EmptyGraphics2DImagePainter()), hints); Assert.assertEquals(image.getBufferedImage().getColorModel().getNumColorComponents(), 4); Assert.assertEquals(image.getColorSpace().getClass(), DeviceCMYKColorSpace.class); } private static class EmptyGraphics2DImagePainter implements Graphics2DImagePainter { public void paint(Graphics2D g2d, Rectangle2D area) { } public Dimension getImageSize() { return null; } } } ././@LongLink0100644 0000000 0000000 00000000162 13777276623 011656 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderFactoryPNGTestCase.javaxmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderFactoryPNG0100644 0000000 0000000 00000004341 13777276623 032432 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageLoaderFactoryPNGTestCase.java 1732019 2016-02-24 05:01:10Z gadams $ */ package org.apache.xmlgraphics.image.loader.impl; import org.junit.Test; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import org.apache.xmlgraphics.image.loader.ImageFlavor; import org.apache.xmlgraphics.image.loader.spi.ImageLoader; import org.apache.xmlgraphics.util.MimeConstants; public class ImageLoaderFactoryPNGTestCase { private ImageLoaderFactoryPNG ilfpng = new ImageLoaderFactoryPNG(); @Test public void testGetSupportedMIMETypes() { assertArrayEquals(new String[] {MimeConstants.MIME_PNG}, ilfpng.getSupportedMIMETypes()); } @Test public void testGetSupportedFlavors() { assertArrayEquals(new ImageFlavor[] {ImageFlavor.RENDERED_IMAGE}, ilfpng.getSupportedFlavors(MimeConstants.MIME_PNG)); try { ilfpng.getSupportedFlavors(MimeConstants.MIME_JPEG); fail("An exception should have been thrown above...."); } catch (IllegalArgumentException e) { // do nothing; this is expected } } @Test public void testNewImageLoader() { ImageLoader il = ilfpng.newImageLoader(ImageFlavor.RENDERED_IMAGE); assertTrue(il instanceof ImageLoaderPNG); } @Test public void testIsAvailable() { assertTrue(ilfpng.isAvailable()); } } ././@LongLink0100644 0000000 0000000 00000000157 13777276623 011662 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderImageIOTestCase.javaxmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderImageIOTes0100644 0000000 0000000 00000004774 13777276623 032416 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageLoaderImageIOTestCase.java 1365650 2012-07-25 15:59:30Z mehdi $ */ package org.apache.xmlgraphics.image.loader.impl; import java.net.URL; import org.junit.Test; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import org.apache.xmlgraphics.image.loader.Image; import org.apache.xmlgraphics.image.loader.ImageContext; import org.apache.xmlgraphics.image.loader.ImageFlavor; import org.apache.xmlgraphics.image.loader.ImageInfo; import org.apache.xmlgraphics.image.loader.ImageSessionContext; import org.apache.xmlgraphics.image.loader.MockImageContext; import org.apache.xmlgraphics.image.loader.MockImageSessionContext; import org.apache.xmlgraphics.image.loader.impl.imageio.ImageLoaderImageIO; import org.apache.xmlgraphics.util.MimeConstants; /** * Tests for {@link ImageLoaderImageIO}. */ public class ImageLoaderImageIOTestCase { /** * Tests a grayscale PNG that has a CMYK color profile. ImageLoaderImageIO used * to fail on that with an IllegalArgumentException. * @throws Exception if an error occurs */ @Test public void testGrayPNGWithCMYKProfile() throws Exception { URL imageURL = getClass().getResource("gray-vs-cmyk-profile.png"); assertNotNull(imageURL); String uri = imageURL.toURI().toASCIIString(); ImageLoaderImageIO loader = new ImageLoaderImageIO(ImageFlavor.RENDERED_IMAGE); ImageContext context = MockImageContext.newSafeInstance(); ImageSessionContext session = new MockImageSessionContext(context); ImageInfo info = new ImageInfo(uri, MimeConstants.MIME_PNG); Image im = loader.loadImage(info, null, session); assertTrue(im instanceof ImageRendered); } } ././@LongLink0100644 0000000 0000000 00000000153 13777276623 011656 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderPNGTestCase.javaxmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderPNGTestCas0100644 0000000 0000000 00000004516 13777276623 032375 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageLoaderPNGTestCase.java 1732019 2016-02-24 05:01:10Z gadams $ */ package org.apache.xmlgraphics.image.loader.impl; import java.io.IOException; import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import org.apache.xmlgraphics.image.loader.Image; import org.apache.xmlgraphics.image.loader.ImageContext; import org.apache.xmlgraphics.image.loader.ImageException; import org.apache.xmlgraphics.image.loader.ImageFlavor; import org.apache.xmlgraphics.image.loader.ImageInfo; import org.apache.xmlgraphics.image.loader.ImageSessionContext; import org.apache.xmlgraphics.image.loader.MockImageContext; import org.apache.xmlgraphics.image.loader.MockImageSessionContext; import org.apache.xmlgraphics.util.MimeConstants; public class ImageLoaderPNGTestCase { private ImageLoaderPNG ilpng = new ImageLoaderPNG(); @Test public void testGetUsagePenalty() { assertEquals(1000, ilpng.getUsagePenalty()); } @Test public void testLoadImageImageInfoMapImageSessionContext() throws ImageException, IOException { ImageContext context = MockImageContext.newSafeInstance(); ImageSessionContext session = new MockImageSessionContext(context); ImageInfo info = new ImageInfo("basn2c08.png", MimeConstants.MIME_PNG); Image im = ilpng.loadImage(info, null, session); assertTrue(im instanceof ImageRendered); } @Test public void testGetTargetFlavor() { assertEquals(ImageFlavor.RENDERED_IMAGE, ilpng.getTargetFlavor()); } } ././@LongLink0100644 0000000 0000000 00000000163 13777276623 011657 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderRawCCITTFaxTestCase.javaxmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderRawCCITTFa0100644 0000000 0000000 00000004524 13777276623 032250 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageLoaderRawCCITTFaxTestCase.java 1732019 2016-02-24 05:01:10Z gadams $ */ package org.apache.xmlgraphics.image.loader.impl; import org.junit.Test; import static org.junit.Assert.assertEquals; import org.apache.xmlgraphics.image.loader.ImageContext; import org.apache.xmlgraphics.image.loader.ImageInfo; import org.apache.xmlgraphics.image.loader.ImageSessionContext; import org.apache.xmlgraphics.image.loader.ImageSize; import org.apache.xmlgraphics.image.loader.MockImageContext; import org.apache.xmlgraphics.image.loader.MockImageSessionContext; import org.apache.xmlgraphics.util.MimeConstants; /** * Test case for {@link ImageLoaderRawCCITTFax}. */ public class ImageLoaderRawCCITTFaxTestCase { private ImageLoaderRawCCITTFax sut; @Test public void testLoadImage() throws Exception { ImageContext context = MockImageContext.newSafeInstance(); ImageSessionContext session = new MockImageSessionContext(context); // This image file is NOT a valid tif! It is the directory table ONLY. ImageInfo info = new ImageInfo("dirOnly.tif", MimeConstants.MIME_TIFF); ImageSize size = new ImageSize(); // Size data can be retrieve by parsing the directory table in the TIFF size.setSizeInPixels(1728, 2266); size.setResolution(203, 192); size.calcSizeFromPixels(); info.setSize(size); sut = new ImageLoaderRawCCITTFax(); ImageRawCCITTFax rawImage = (ImageRawCCITTFax) sut.loadImage(info, null, session); assertEquals(2, rawImage.getCompression()); } } ././@LongLink0100644 0000000 0000000 00000000156 13777276623 011661 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderRawPNGTestCase.javaxmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderRawPNGTest0100644 0000000 0000000 00000007107 13777276623 032417 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageLoaderRawPNGTestCase.java 1732019 2016-02-24 05:01:10Z gadams $ */ package org.apache.xmlgraphics.image.loader.impl; import java.io.FileInputStream; import java.io.IOException; import javax.imageio.ImageIO; import javax.imageio.stream.ImageInputStream; import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import org.apache.xmlgraphics.image.loader.Image; import org.apache.xmlgraphics.image.loader.ImageContext; import org.apache.xmlgraphics.image.loader.ImageException; import org.apache.xmlgraphics.image.loader.ImageFlavor; import org.apache.xmlgraphics.image.loader.ImageInfo; import org.apache.xmlgraphics.image.loader.ImageSessionContext; import org.apache.xmlgraphics.image.loader.ImageSource; import org.apache.xmlgraphics.image.loader.MockImageContext; import org.apache.xmlgraphics.image.loader.MockImageSessionContext; import org.apache.xmlgraphics.util.MimeConstants; public class ImageLoaderRawPNGTestCase { private ImageLoaderRawPNG ilrpng = new ImageLoaderRawPNG(); @Test public void testGetUsagePenalty() { assertEquals(1000, ilrpng.getUsagePenalty()); } @Test public void testLoadImageBadMime() throws ImageException, IOException { ImageContext context = MockImageContext.newSafeInstance(); ImageSessionContext session = new MockImageSessionContext(context); ImageInfo info = new ImageInfo("basn2c08.png", MimeConstants.MIME_JPEG); try { ImageRawPNG irpng = (ImageRawPNG) ilrpng.loadImage(info, null, session); fail("An exception should have been thrown above"); } catch (IllegalArgumentException e) { // do nothing; this was expected } } @Test public void testGetTargetFlavor() { assertEquals(ImageFlavor.RAW_PNG, ilrpng.getTargetFlavor()); } @Test public void testLoadImageGoodMime() throws ImageException, IOException { ImageContext context = MockImageContext.newSafeInstance(); ImageSessionContext session = new MockImageSessionContext(context); ImageInfo info = new ImageInfo("basn2c08.png", MimeConstants.MIME_PNG); Image im = ilrpng.loadImage(info, null, session); assertTrue(im instanceof ImageRawPNG); } @Test public void testPreloaderRawPNG() throws IOException, ImageException { ImageInputStream iis = ImageIO.createImageInputStream(new FileInputStream("test/images/tbbn3p08.png")); ImageContext context = MockImageContext.newSafeInstance(); ImageInfo imageInfo = new PreloaderRawPNG().preloadImage(null, new ImageSource(iis, null, true), context); assertEquals(imageInfo.getMimeType(), "image/png"); assertEquals(imageInfo.getSize().getWidthPx(), 32); } } xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/loader/impl/PNGFileTestCase.java0100644 0000000 0000000 00000011012 13777276623 032155 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: PNGFileTestCase.java 1843559 2018-10-11 14:59:17Z ssteiner $ */ package org.apache.xmlgraphics.image.loader.impl; import java.awt.image.ColorModel; import java.awt.image.ComponentColorModel; import java.awt.image.IndexColorModel; import java.io.IOException; import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import org.apache.xmlgraphics.image.loader.ImageContext; import org.apache.xmlgraphics.image.loader.ImageException; import org.apache.xmlgraphics.image.loader.ImageInfo; import org.apache.xmlgraphics.image.loader.ImageSessionContext; import org.apache.xmlgraphics.image.loader.MockImageContext; import org.apache.xmlgraphics.image.loader.MockImageSessionContext; import org.apache.xmlgraphics.util.MimeConstants; public class PNGFileTestCase implements PNGConstants { @Test public void testColorTypeTwoPNG() throws ImageException, IOException { testColorTypePNG("basn2c08.png", PNG_COLOR_RGB); } @Test public void testColorTypeZeroPNG() throws ImageException, IOException { testColorTypePNG("basn0g08.png", PNG_COLOR_GRAY); } @Test public void testColorTypeSixPNG() throws ImageException, IOException { testColorTypePNG("basn6a08.png", PNG_COLOR_RGB_ALPHA); } @Test public void testColorTypeThreePNG() throws ImageException, IOException { testColorTypePNG("basn3p08.png", PNG_COLOR_PALETTE); } @Test public void testColorTypeFourPNG() throws ImageException, IOException { testColorTypePNG("basn4a08.png", PNG_COLOR_GRAY_ALPHA); } @Test public void testTransparentPNG() throws ImageException, IOException { testColorTypePNG("tbbn3p08.png", PNG_COLOR_PALETTE, true); testColorTypePNG("tbrn2c08.png", PNG_COLOR_RGB, true); } @Test public void testCorruptPNG() { ImageContext context = MockImageContext.newSafeInstance(); ImageSessionContext session = new MockImageSessionContext(context); ImageInfo info = new ImageInfo("corrupt-image.png", MimeConstants.MIME_PNG); ImageLoaderRawPNG ilrpng = new ImageLoaderRawPNG(); String exception = ""; try { ilrpng.loadImage(info, null, session); } catch (Exception e) { exception = e.getCause().getMessage(); } assertEquals("PNG unknown critical chunk: IBLA", exception); } private void testColorTypePNG(String imageName, int colorType) throws ImageException, IOException { testColorTypePNG(imageName, colorType, false); } private void testColorTypePNG(String imageName, int colorType, boolean isTransparent) throws ImageException, IOException { ImageContext context = MockImageContext.newSafeInstance(); ImageSessionContext session = new MockImageSessionContext(context); ImageInfo info = new ImageInfo(imageName, MimeConstants.MIME_PNG); ImageLoaderRawPNG ilrpng = new ImageLoaderRawPNG(); ImageRawPNG irpng = (ImageRawPNG) ilrpng.loadImage(info, null, session); ColorModel cm = irpng.getColorModel(); if (colorType == PNG_COLOR_PALETTE) { assertTrue(cm instanceof IndexColorModel); } else { assertTrue(cm instanceof ComponentColorModel); int numComponents = 3; if (colorType == PNG_COLOR_GRAY) { numComponents = 1; } else if (colorType == PNG_COLOR_GRAY_ALPHA) { numComponents = 2; } else if (colorType == PNG_COLOR_RGB_ALPHA) { numComponents = 4; } assertEquals(numComponents, cm.getNumComponents()); } if (isTransparent) { assertTrue(irpng.isTransparent()); } } } ././@LongLink0100644 0000000 0000000 00000000152 13777276623 011655 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/loader/impl/PreloaderJPEGTestCase.javaxmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/loader/impl/PreloaderJPEGTestCase0100644 0000000 0000000 00000007562 13777276623 032413 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: PreloaderJPEGTestCase.java 1732019 2016-02-24 05:01:10Z gadams $ */ package org.apache.xmlgraphics.image.loader.impl; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import javax.imageio.stream.MemoryCacheImageInputStream; import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import org.apache.xmlgraphics.image.loader.ImageContext; import org.apache.xmlgraphics.image.loader.ImageException; import org.apache.xmlgraphics.image.loader.ImageInfo; import org.apache.xmlgraphics.image.loader.ImageSize; import org.apache.xmlgraphics.image.loader.ImageSource; public class PreloaderJPEGTestCase { @Test public void testAPP1Segment() throws IOException, ImageException { // example from http://www.media.mit.edu/pia/Research/deepview/exif.html (adapted and expanded) // the bytes below have three markers: 0xFFD8 (SOI), 0xFFE1 (APP1) and 0xFFC0 (SOF0); this all // it is needed to get the image size and resolution for this test byte[] jpegBytes = {(byte) 0xFF, (byte) 0xD8, (byte) 0xFF, (byte) 0xE1, (byte) 0x00, (byte) 0x42, (byte) 0x45, (byte) 0x78, (byte) 0x69, (byte) 0x66, (byte) 0x00, (byte) 0x00, (byte) 0x49, (byte) 0x49, (byte) 0x2A, (byte) 0x00, (byte) 0x08, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x03, (byte) 0x00, (byte) 0x1A, (byte) 0x01, (byte) 0x05, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x32, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x28, (byte) 0x01, (byte) 0x03, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x69, (byte) 0x87, (byte) 0x04, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x11, (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x40, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xC0, (byte) 0xC6, (byte) 0x2D, (byte) 0x00, (byte) 0x10, (byte) 0x27, (byte) 0x00, (byte) 0x00, (byte) 0xFF, (byte) 0xC0, (byte) 0x00, (byte) 0x14, (byte) 0x00, (byte) 0x0D, (byte) 0xB4, (byte) 0x09, (byte) 0xB0, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00}; InputStream jpegInputStream = new ByteArrayInputStream(jpegBytes); MemoryCacheImageInputStream jpeg = new MemoryCacheImageInputStream(jpegInputStream); String uri = "image.jpg"; ImageSource imageSource = mock(ImageSource.class); ImageContext context = mock(ImageContext.class); when(imageSource.getImageInputStream()).thenReturn(jpeg); PreloaderJPEG preloaderJPEG = new PreloaderJPEG(); ImageInfo imageInfo = preloaderJPEG.preloadImage(uri, imageSource, context); ImageSize imageSize = imageInfo.getSize(); double expectedDPI = 300.0; assertEquals(expectedDPI, imageSize.getDpiHorizontal(), 0.01); } } ././@LongLink0100644 0000000 0000000 00000000150 13777276623 011653 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/loader/impl/gray-vs-cmyk-profile.pngxmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/loader/impl/gray-vs-cmyk-profile.0100644 0000000 0000000 00001355133 13777276623 032442 0ustar000000000 0000000 PNG  IHDRXӼ ̓iCCPiccxڬUP  A+!JҠHwlww. tw`ww~_ř9Wz>^3!\ TT%GDffٮ]] ?^hsE?':0h@YG: @8h zVb=#ZMR `Qͮt1z.<cm5,>kۮmIN_vx8}4Z+kíh+-QZvZ_ԭ ׳d`143jiuIٓ51j5k]񨍿FnnB/rrj϶'w9]J]==|W77eOnf4}(r\PpE'tVs@Ԟh-L MJ+{ף?5{֯Zyk ZY۔l)^VS2* " @B^A=D/c g^R,9iBz#c9Ǻ~[ \$q#:'k*?Tkv C4ZmMcn?86X1Dt΍_ԚZ?v}G!;ÿG7ϘM6L~1{bl\Voze7v >օm ;7h ɈlOK=LM[\= QX.%ǥe_&.zJn٬Ž59_uoAP1qljcSiS'7=|*3ss,~`xˇT\^k>u͏Xqo9! <=O/-_|Czniˏ|b|rn3?Rtu-v+u36=o01t0|in\uMMM/Ifo7d1iI\~V=ְ !M6޷鰅n [kt}&'lܱrm.gKO НѻwIktϴĿzoԾm?8XN>b50q84"5rMQQbb%qĝIVW~{zLJG( w,=XhƮL5ـ9r/(h*11%²ʀ*j7ක͠ ` )tXFi51XM a%QdL6XP7жНPv'[ P-JJ~(juQ*ZxIV6ĎNNWORr~A|xfITsɓNۜ_ =ff)W^E\[g﮹r#O3]}ruw7>|k%߿ xZ-Lg7QO苨K_Pi~X%_ G6vD0`jQY4iKTL' %Σ:I ),EJSx-gL A$C rɪ G&GScZQMu7F#4Mw*DBPI8D{%PȽl/*"%s?q;Y=|X"2fU7G :_~du7r' ›)ӥ5uB #4/qwC/xyFܝp JC B TTuf')?WmF8X ְk/\Հ][5 ~)V }|Ry=Ж \gÁpNER=QW(VȫwȖfH)'et.kЂJXtyz-i6ZEL"IB!4 (y=W0fɄ!$sQqKڸ7ޫuX O{,op)Q8_^[7YXl"/5SIȈp{_/dWb-`SF=q_Lv^yPBP:m1!.\Frvcc1k^bezrߐ|80u;Y4ڌM齔\iV%SVmb؃_J<NvH~be=´EGb 9^ Jv 18Q#AL`F"3ij\/Nd` ekui`\*O 4D.4RI+4we 7)%5_=e_硻)Y*|wo%Pq˗N2 亟4qiJufY_OFd}\j\``Bhsa|7="' eN3]nk\#cU9?`ũhshY]熚fcIA2 ex`b{J88(i) kL]>I4:ix2 H< IZd`PE#\~\|$G:= .nt-o`g@@ާ)@ŝ@I3c#e!`A1` EF{I}%h+N!􂯅LZS}Y` S'ƾ oYY 'G$.aNvb9ωpd?M)g^!їI04Q;mf@ ktso7zn*n&$yCTAͣ:Ȑ|lj<(ZYq9e&,2Lʖ:(8q>G2 XȜVΡKױ# [Syd:BJ&v1ykޥn6 l(|}.x#a8";h ꕩ Iԩ=Ha 2V-mo5)ϜHڵ.o4$ApI"y_cQF1vc@ʼi!g6j Gd]rB%Q)^ E%w!ҀC*qH\,l_&jLcMvZ]seJT60QoXμ͟<7i2w+o]A$\mGP-+{e 8"a|@3b{x\80 QM{NOx5ޜT^6RaɊ^T&t^ wQ}9? i.eLTZZY6$"X—MmDl>^tܖ)Gcgҁlvd32,AȂ; P0a5SN#Z8!(\vӺǩ a)N첛@F$6Qk;j=x[-q URk$Mu\m|qmTQĢڂxr~b-S^TP9%d_XJ0y۰Ƿ裒E7 4TxiJ7ә(W uNLΩauQ2g8_m}k wP^$WQ)Ⰹz22 _7 ޖ$Ss"1p n":$cDjx|pk!}Y ̱gF7E ]JĭZ!0~}Ty֏xFMGcnr}"aLt;Em_FHBPWꥮ,'ՈUwLvJ/S#6t Pl aut}_K a$٬Qu"~G`hGw^wPN}ݑI;E_,]܎נgZmeGwM*5Z2G߇*(dG;`"(1b"O Ԃ]wuiGfž+TK;e5V {& C&\p1X<툴sWؓf:Q=TqbYhՐ `JO$^D<;1h1tG {wM45-W,HOa}a%98NŁ Johm6T?Dt` I撃'iO쥆TQtȺ;OtlYjB:|7 -9 4JbqEWcx#'遴އ]V{hs)֦(uI+;y@|L!_w!ِ~tz-F1<Ntqlve~g~N?5wS8QuŜ1|$p~HJr]CgYZs!!*ڮ̎ &K\W66,w Y(lg5%iZ &Bi>m\ ˞u,Y?o祻Mj B둁]zF+mSu8 _#â^>U5g{ f"!68yp|3' cEC|t @/`vw0>q$!__x/kp诰w"B ?~P\zy,@\zxAB0Pyk.@춱`=3H!ahD܃19! }!\2E/ @d)YD@^VoB[%ay,TN}|jo "ynhXbHV( >sd(@2R<=-xG!vuZw5S# A}`펽rKtS/^@E/D`q+Xoso)߾0ҝl:JCn5)ıէ {l:T.nm?2=T\r&ʙPx5iµVQ h\o4ۊ bN=Ȭqc|r]0Q71#sDXff5mh @x8]ϱE2"E He]NjN]-p#UujA䚽uw)Bc=Ш!Z>* ^_:YiCQ[\TB-!+!'{`P9Ljƥ>4p* <"lB~aYVO 7D mD^"<0HG{z1%9;BJPZ3Lm䵁h6rsdGSax!ć-7#3.l@ofFȗK [d =0 P=@7dz!~-Uyƿŋ0P#c:2ߠfCj (P<2B"}-:+ )@dy,pBCc]`Ѵ)՟襣2`*Yt؀&͑ 4,4PM=H먽M##TɲH}Eb WQ(0L%hrެξ8 =$ I*;@tzIm\'lX$!uA嶄TٟxYp<95M(N턓7?S:>UɁxlX| G6sCOS3fMSEe3焱|#*]u}P"9s^mv Vxbv{(;B8LE=Ϗl5VqĠ-kSPlk|͕V JA?Ü#EXT5Z0:/8@ ilPNq8f˃ƀjRInGE76|L>ÏqxlG. 2z|Ma/BuI  wz궪s$r%8\B<.;1NMg#Z1nou$JVUڈ؁Q^d[S}g>#^j0"\(}G,5(f~X'Vz)3iFgfSJ / 5  ˜8d}ܻokYQOoD P_45Ŝl[?D mJ$ל>\==Xn539 ?%C촏&hIQnL~&*3_k+A+H32PS \A2#yWi>.\-Xꦝ8$4R۩Rsa \`A;ܘK4#Mgǎs2%BB8٥,y{-Շ㠖0 ɺ)6b@my%vD9D. EC^OYV̽4(T8gJH7c?%ԻJ{%h1"VN09Q\T3.🠑^-XbR>ߠV!G58srdOqwsbuu[f!kII,5[w|&Ԗ-._ղ:Y2>GtMv(Oٷx"O7km*[ߨ7>SE+l27ٞI90IӉxdp VN\hWfc^c]+[S2fC?O+jN"7JS;zA]GQ-nC{4 ~|ۇf0yl.':V+QQI{&/I}dMU#em1/نAO:t[#4E7NE~U;%8e/R5ea{:1ntn\  rm]5gwy\\E*\&p"t0Tf_X} *B42S8k"B=e RQ4mǺ&%=}STxD1]] ҏ8VmϢ)qA<Mm{DIMk-vd7(j]L9*a[#ٵgVrGrTp88{urOIo'ĢC#Q}T)*Hsyů=8Iɀ 4ФXc=G_ۯ nw6'T UdEΎg$'n\2؇*Y/Az*tdX,yTw~Gpw ʩ7fCRwd.!OzѨ`Ww2ݬ*I1ܩ)Җ#w qF|urWO=5 '(WyH@nN6 arY;|េ3t`A)O0\\ybYTл_Uu9enOM-TǕxMDT-PTR9\]ADhc3n+/a5=)ú ~~|ɮfpAYC,mDl8#,.I" ]&A@;Jtvz h?՝ް"6KT.{%:$r-p|Cz'>+K ,w;ʈ humH)qxO26ݤ&\=ԗ-h1av3/[A;C|]0:۸ !(DU AvDK=y)NCJ\ A^v^jl|U*g4vE2u}''M ^uθx^!mk(ůW*NlHEZG :AV0PMyw#\-$-C$_SQL0qGOy[4|F߰υ'3 :1\n5}n27|0ђщuX8eEi9"{IZ?aYѾ|)NƋUPʓ^wrʭNmŶGMS’Gezb_i կ#jA q|8Tϓ NSuoâ{1%v> ev+ͦ].] vy|”i'z~4Bphn05@B[IX]mpvh\c! 9ځˀ #a"S~8cQgLyF[~TZB % Åa(, _ vWVo{ tS fi Dr8rrU1]-. ꁷر$)scn-8~HN3eZ!HnVIg@=k! q#;- ڵiiFŏ;U;ՠz!80ɖD-verJeyį!tojP0Au\Q j0wkG:4g03'UXKUFnY5ލgPtOzyK-}Bk ^W1U!ǿVO_ˬl~F}.%X4R6FݭnrG~C1_A3i_ gKL'\" i2z^}xCrZGHcP u.GCF`%s0."׷Iˈ1p1Bؙ<@p g[:f5s)N=/4N/нnFFe3HCգLSЃu~whbf%00n ISmԛ&Z/ɳ$hF([5O2ib+PRpj원} p~g3oZ]!G!ӽWPǎ̈́PY\ci}SJ#"o: {$jr^p{L?sYVW5> 砑ݦйaު`$9)T4$H|1?]7L,KzV%WC qs:BsN" wB++-ت1b/pci5q{Maa4*A~":BzuCgHv+1xF8 /#!$x `>1D_$GjH;Ze)_/!|\Uכxwi#Zsg%'MpwXwwpEJ:P&–_: ʰZF0Wp )8afyC7g}5fٶ &4Ƅrg9Cfⴛϩk"5Նݮ<7, ыrtGs[t$} D6Sb: 3-,u\Sw*uۇm3Dupv!oa1"0^[Ƣ}KiPcU :Ijo&6++$RBo<2@$Cݎw쉝B5ꢘgi#o}@}\'UhU`O>Gڿ YRBH: T L31) ,OwMgP\)㻉O;E?[ >GScejRci*KXHo0W7-c6 )qc2.ڵk/ S ȻERn+ bf"q !Ҡ-a"h+T }e=ŏ#=fCdEFn%1 7OVQ 8~eTppC& >BK3~;]eT$7g]Rﵦa)vCK9]d-_,I[pzc' t)<țF0b_e#dfz*;B*2|-؇\-wc4mav'zH/3$zHo%Dq_[<ރU;~䷪`\NVt Gwjl$PB: Nc=keduPJM@h*ʢt^"H9'>q !q F[|T;$M3̅8-Q0>pYyH0a~ct-(E4MSAcyT I*bvж şы&`ep~#? |d籆9`JNRl@q&G'Wm:e%\y! d- Es ̃6;[h@[`m='o̭be(FZG4 t&51B+%u9l592lKAP?H{l![X pNUb~ 9=r|ORYdDf#%zpRR+T#\VET*)]+gѧ%h xoh}3PpvH 0b/'^R^wX~^1tL.6aN<\nExk0QI5c ɱpDU!G_;pWZ~`7Ѳџ'iVI, GeCWWy׹S_u%:QݝP ;pUт.F+3A6A# cwy$kLO'Tˉ^.S:*CIkcC>_jFªm6!R5Mԩj]|ޚ#SWQ#ZQEuh[\"FV0UkŹV""bsmʟq*?eEp;V 2x ;~&Z Z?FFy*P,7I$ޚA/D[A+ޯ9:$?N_%>Bmw!PmqJ^Y+7?#~-o['䅻>tD&tR,{?5u\՝v4|CàXQZ+;O; $-L8:+!xYų.솮c-&Zvk7*gmdj%i(.B)G}Ԉ7}h(XeeGUO=l`˶5P͛69j y>gV0Q 1P;ȔgwܚZڀo1*IuܣyYM(P`RovMqt9ԈZa9ބ"RƹĚA!A} Жfڸj. 2"K+Ƙ~;yILuX1[ԾZE`Jjb[ztڿ8\ ТқlL@U5s.Ap/fqV70TVPR:&I(VTFrBWfqt=!oP~Far <g]쬼ʱB(nN6gK*pQif䶂=Ir풂_$2߆Ǖ&zdU ]ڂ㯺9Ec;S%FҋSWfԗȬz+u9 8t6`y׮c$œ])f͂Uu9.gAE=90R'Y lq#<XPUB9c @'xའ9?pD 2~B?`#p[1 UX Qd/5Q8\(|ހY&Bt18=&zUMXZ$Udn^sok.QA(Md$;<~дMa$303x+nʺ)Xڞ~j6gQrXz`^Dc@2[S.8z${uCYBjiCDaQ%HWjgU+\(`[(R͐=_x_*lˀh=W@zI׆WZTYU΃ >݇aX`Pk]FMTc=(>M$c[>+^ 1xzʲ>I/#2hwޑ#5+ڭZj5Un |\sn (K* )%-% 93t 6vwwwY>{W!wbNQX+Fp?fM)8^$U9A }),>4TJDaMyhO{Zk' g̏BHR@ȃ|{\އn O$ry˨\5o?܃W(^{ϼ9֛< ugt;?3k!^-eivSKt};Lx="AAx?S!q5{dԇl*"o#pяE/J(֐1(fƱCbA=Os%rtB&&xٚA\?,yExr.Ymr}E0IN":"8/ w !~ե^;=>< (8y?)vta|Lg~ LO7na=+#dÌCH WAUtؼV .(gȳ+T9!gOBgo1&hjm!o(._XG;ճ  JC) ;/݈i?;nMP2M*Px78AmzBjj[!''=3P3#:u4H0sű *),ye=KWKu&cH{]YD;66/sy]2#k15܃nơ <UqK@>N H؃{;ˉGړfsGϒzVIF-E-Q Ekw W?*5&KFzݣyV|UhstD$FfFY/w#3FON#EtZ믉5mTYJV^So]2$ݤv>&ܶZ7p?_6`F)RYutdBH6Lm-wq (T \ػsey'yIDwr-Z$mRD>B|4eW}wzCMXrRPuڐG]m GHOwdQ@iƸDg⍪H{f%LmOyrCHs]3#—H=5/?`jI\dO ,dCzYoصsufyʑЙ߃(ȫsnu :€!t \ҙ9g+IJx~ʊpIrNF#aYROF-ܮ%oD0kkU͋ ? pyVB Sc$' ){('l߻ΈrY:۟`m@krBPVw_ !s -W̓FDRv{te; ?o9smTnQ5;H% O,u`hߚc>mk2d&8㛪\;͑~NZO¶9 j!0Fۅ::2?w‡}Hԅ0FҦCܚ+o'I᫧Fs:)ғ}܃{h#ʭP1[pe|!ґQG: ]F J=ܜV[SP8Pv 0+*;ү8}T)F pΦe'nwFGEۅQOm =M|Z-$zP3Gv* zJwx#m(;+4.$p qJUx18_TW5 r;L0ap/\(ec=[^餦|_ld<ԽT+Э}f'+R9D-ڄ=z*ecK{NxZSݨruإ/nWFuB$D"3ܶ;FDbl81e^h* wSK8jrq+rH8~9q&}7 宅Z3>TM[_01yj3֚{مv c̋n`t8?6+&0;Gc6bNb}3h郛7VIo๬x9718[|w/6ݓ7#].C3Z(4}Ovw?NۙA5)W\;-RL&ĕK !%q)};ž.ot|?3$,vj)еo,DeCލceYZoM >zדVj:6quB;5 =w\e d g4MByWvHSpj bԸG!>LI=4%&q֘Z#1,<;]8 y@I%.2튶iEQ%aP8"BVry瑆G5/QO7o2TFwZArm_rZKH %MfS Y͝6Y3xR_1o4))wl=7t`OF%dZ\.S$'fKoZonG T`D_򞬺9U?1SMjdb` C<mm36#_ǿ##6Y9kԒ?$R/ E1:b~а d6L7a6-ĽXg}@h1!?EtqbD.h﷞$ <8P!fO'(qd!pCbSHv2n뛙8|2'bߪ䵙ط)9Af.Vjq(c;ilk^c3S8ÔU93dVS~o֔ػY#VEqB1u*u_ј:cz)dYTf%M;w޺=:L&DJI1L͕"e)X>W☾L?š)V0wl6̀(ȄL.EBR5T V2w3 Y[%:ٳ}dsH#o9Ow-sijZyx/j =ZoŒw#K6 HCIA'ţmhR$w) FQ^I}|h]vW–ӻ% [ZI'3cp;/ yx m!B3V)gsUsMbaA秨6%D/Ǎ[q/S*]uzG6qVhp"ecA78$G8k*;=w$Cv(nԭO gADR*"/;>g^o)`c,`c't/2HE(],(įe)ʦyV-23ŭ+ kR3YGS'fCD/b _0%2ufK/ GjڜEyAeE67anAp{!VP9'C:uA4UD勐!:Q"(ܒ,|  gLHY#YIi+PV( 2jqyP4 (&8l!rX {=: hĿn`k 8j {Q{j>%'78д Pwתmj0Vw(hP\VeVZNaA̦aabgz:km.|@ 4G:K:\BG֞\+Aox4x`[üW:424M - ۠=^q!`2 ÒUkDOG0kǵpVo K߹JOr5cR&Ie0n=S{: Ucʤxz@k%| cjN*T&*D1{ Uᕐe %Lo@g}%P\3 $Wmlӕ= \o9LVH$Ck$K:auG_Bk-k9m cIpBRӚh.9Z:W\&#r EUT$3*䋻9}% =:dhfwP覔9^%>?UEQ4W>#=="]P,E~dT-E[2x?}!QѮi moy`ψ1/;Ρ/ݷ ![#L b~dݑ>)͸p{Vw|ˮCz-b@k!M(LٜH?_ӐtV"| gBEbrLP jSm@퓮b(![c;E:[VLu1CoZ/s u vt?)dKLِ.:F;xHmn8\'͂|ĮIŶ?‚ d]-LxAyM!(ϓ|[ 5 |qfGT]xY@&T6Kvؿc^k:{[o=Rh(^kأSMxʤ7 9, ]86e\1h׍椲4ע׌Z<~/,>Vw!9 RWSd gzV\i3RꂌUCFZJ޹"2,G8gwR 6M'VY߰GuĿGEu Ί*f[ dW=5teP:}sphܵHȈJz15Y5#"Ss D_iW^ۛnn! aƘU02ϱĭ7UN> ɗYzu"qd0yoc-793dMs^{.=m@x%\BKyeѿ}.+r~3+ 5r-Y] a@Ƌk#ߘK 2ozenb::t[dFXԅǖ@e潍 ۄc[x#&鼉YO8vutKFތIwhhL\iXJTп+"0>^|Ќ.52y-jEeyehGD۠th^ {gIf SlBgSBu+SWP0ӬHS/}߳RQ!;׃4q0dxW ï>y:qٚHovrQݴ&\5dk͵ct·QiD6L-eY,q:F7X߽]G %<ǘ(_³15P#mAEwhCѨmLMM4|8݊7w6B>g1/Xfr|MՌźZԛZ*ԩV8Ԃrn&'p쳓XeK}]CWr1Iyv 0vIy74Vu:<4>/"7]o0iQqr! 8Ey#K(wBXqbp{[_D|beu[nѹac{,Fh|-hAߛ?V;mK"6 lYޛ#:$=w jʾYdx9iB*v'hymf?MxFdq"%Sw֥_U4} $+}_|mQTxhÁӲUí]_V꾤c4V&JghweCI9} <5REI#;O1kH˫^$6ڮk h9zi1p+3;k %O xzFEǏeǖpp84g8E+>r) Pt(yH]K| †5$ f <|` J\?fc*x aT= FW_Xr=) e&KəitDÐq=?x~q:_m*$\.#}YK?V>A@=[;t'];IJ}c'^_mHy L8 '9.\e(&/轘`ݩ &F'V)ʃvoQC^Mx(o'"1-+89l%^~uNAVF٠dT4: ;ݬYd& $yn u K?vħ3E 4U/-SJ1!aQ3FlbxC?KB`hk f \P6ER/`{7kqa>i/쓠&C][u¥IҥZ8$=I[< z@gY̭ !Ӥ6W3dFYfo7gÓ7Ap@5N:ps~'/jam:9w7aěUҦ؟8sej'X-F=&҅ o9 х zf~;2X 7َ:L+;Re\ϲv\$LVȱQ,c#:vCybkv*4uN&kp<"Y\̇;Ʊ6 E;0XfԄo,ː0qA5x5KbcW4OkĪׯ-ۡV2ZRù/+PS n{AQB .*]M_Wd]*NY"(}OcI!}D 8܈4?>D[BI49`x/xʘ}}g;a~K tZKCՌbOFb̴̸lfpy{.k%t3n.OT;*IbyԂ^g}n'op/ .. =g &?6CIj5wԍh¯OF2emd X(^i } a`}o~2jSu2{0Zy@$yz# )(ZW>ACˢ.)ZÛQ;pcwrYЅF\;7]ؕtp4 |GgDTK`0sQs^ǎsmrӕvgkaN,:~"Ed6 &`Ƶ2[=foJ\ " ;:N\$Un&OP 6ٲ,z &gN`wml R;*>Џ-cP\e6%'Sf7!j:ſR\r-|.JrJD- 1~/n Z뫺*l<U  ?dQds+!_, ( H}&= zfb2/5-*waD ­v/S`VBx>#c@&^2fC͑TusNl.S5NъI5J LSA,n=)/.Ɍ\% qt,e+OX?AL@SνڗY꧉*XG9EN`#;(vz&mrt~i/Vtӫs{vcW%^:ox9U4YRc Ly`=8eOwbL84T_,܅0;k |Q}ׁԠDQ&4xk}yO-#y/a*1޻ãbiQʫ#A]1B .zv}0Cz-$}`2`Čl- IE3FA"w:T7D5g k i: bRht׮uUJEKD& Z_CtzpqkF}4?WZz%{ 8r 4ka,NԸ7O׽mj< -jM5[x[o^g0R""fKjyZQ n= xzU {V\C D#ӬQˏ4PDi+A}b 8ѯɬ;/6dN#-~d#kZ+@wQL,,c ZhšM3- Ԉ]`s-ÆG&J#%KW+H\{^%}~$(U-Bx=4RG \|h-_n O*i)D,h)ls].II{qp;=̯mg+7kUiĆ_O4f>V-\q2otS\J[Y<>Eep|id͓5Twy6}J[T}>u7eU$n|o*—& !BHP7\_0&_]K>l]D7A8Q9'%.fy ΀^NXH&63=;2L"c?V8Z7NY&/R{,l:pv.#EP_ j2^51W퇿`nKNCXic,dY[X:Y~vvK\Ӡj57 -@{ &WlUG h*@U @g -G"ap?rӝ泭(iGuYȳq1uݱ͚̓mDT+Y%)*%C򚑞'3Wʴ`CUC䴬F@_,ULgOW!V?I (Od} Y[D݌JŌPG}sxCCUWq,M]p?QK9rhZd} w9~ CjihjKN"ֱ%ӌni$"~'~A#밲ۨ yi\SSj'; f!OcGP z!Hdc|+ɹKGH(jJ'Ԭu)ŴzR% ]@?f [¨-3>,&EDvUJ͌K lS*tN/&exU/2.՞/YlotK΢G *!A@s2a1l֞G^51ɸy뷉{SEMeLBn4 MaO P $u$ FL>p71~ӱՔAk)ꢺ̈́0B VrlA_4Rpfv 3E'aqܖ,nJ/b"7<i37A~7&s۔[OAK2V5fuɁ0#1WI@}To>2iyoZBܢV"f$6_f.DGɿE"3 z=AP UnؓcNݤ ݊WVOɁjAj;"o[90Pو#jiK|yvseM6g+ 5m-kYT=A+eOgo8pMj.Xw zɯҷQc!r 2Y8w pZ'qFA(bFd%e1nvj1 "? j& i$=B*Q)r G)_zpyr&gЃpaqc}t.inprrf(eF)f.feCTWn^r(M#݀nZ!Yܦs#[MINaa0HMl[&YPƷ -G&H  c(>k ?ZĆh1WB('/IY61|>> XMObH} dXHz$ r(Z3/\nk q&76Leiwsl]nj)7va!]nft]3g"x'8 M.azT"dcol>8P#Z7ۋ*u4 Κ[{m?^oދe-`yJ5Y(IByV% ҉/dc$!9P)օ3Z|9Ws(\a(0E%̃ÃbfZg' >Pp=isPZأ(Fyx,gwIg i2lL"-3(P>8(:V`m,Hj ZYVhyMU(eurWZr`X(]LZE;  n._$GIėEH˭Eȇwzj`rK߈srRij#PʧB ClJi= 3ՎOe,S['X)d\ 5Ibfe6 /mY&?tTay+A6xS LE{aC!PjVw @k,uuTWxrDNղevs@x_ިPjk\zvlӿNDZUd9QWxO<~^-wM0w`;8.XIzRwwśU+;wMF֢kzH'C9y?yvT5%鷵bp jo3_$aa0~.;.BjG~ V׏ԇTjѬEnE(o˥ki0߂3cդqgb4UEJBNb_ f3a0w~*eƙ:}OCK[IS^G_Y`K.3,DB, gהs&+TNvtbS|Bni?+HT]Eϸ>f;;#S}Г>(S˃Ihҟ')R`%z`*K%&eQ~b\|ԿZTtJ2V$ fQ4V +4sɿ%m_x,`p)Β;qkF˿ʪxn[T 0j'3Y,Fhɀ=-]gVN΋ 9&)sP[pZ[dhDO"> *K 4m;zQz?z` Q L; Ԭ'f̊TXĖ(^ښݺ.uQ?&~Pp/cxF+GPJ2=_U].~GWh*=Uեj~4 ۱쾢.15ej)XH[D+mEv0kb)fn"oCsT5U"fzTTGK/@34_1,>v8D'~|?}F(aXs͓U&B}A<< 73֦H'-E/EÕYPzse,Y̆%l2O"3Dd<ζ9#$E+?Wvְ~u#zn";\Ni3ʊ&63d_}El_l@2GU&qk]qf#؞miދYu]y[j̓%d5bmU: g;75'`ʲU_yE՞/}ͪFdY*2fCxwbp׊7hheLrѫhY b>3D_{ցr!,z金SJe?Uڻغh\ ٙ]=SX\P痖 _G!IrOw"ҠJ~[MMFML}URMS8fKBx=:+ߣэjо*32ȿs)h<%XasmrI;3tY몇M+}rEtNzRQ!k2#H%gߡK= PeE"PEuqi$ퟘ>F)@׈*Y=u_7$Y΄KXex Ѩw-=[ <@ ro&j޶.X" ;{1%Lݜ V*Z+{E96/ҳUP3K2/|O,/&3DY@Шg*sUB<_qD^nM;4G(ԽEv^OVLzU$Q/U/e8¢ܸ\RB+W&kRvW NGq>@S[G֌ʛjdTboެ|-1c5 X DY"Df$jkx(2 ,;E*7ƌU`)+!N.UL4=M;{Z7 1c\L7avBAsHo#G 1!a?Z (cm2ZhmSfZm]nY^_2"\dQ'ܬ=S&?dVYFWK7u]+RnI}x 2db"I H?DaסS`iś(/Ҳܗ^zj=F`I@V강+cQ# )҆% !u\ P  #Ԓz)] I~W9a&FBr 3#Ƣ:U1s+k\5jɡYX4v;'*DϤ^L݀^8H[0~C!Տɱ֯\)pZ')Q4֊d1n^h H0_[wnz QÞ G_fF"px\4*t~3WzK'кޭ!&iύ,b9 Ҍ 3AAVQ &Gj'h\"*rX~#|[e̓[U52~TJVSUR~Q}B 5uKn֥4b @J ;(a+ƻbܶ[k?u(m]E_ e槥e3hE3Kyew0CVuݨZ@^7e\'OMעLq"gt}^gD6DRt6پ)b]gGqƏɺٺ7'%BLF>__K4Y!Rt\SC(e4*`<Ø.%/&,`q0:2O5~1?Ii&"a,1 n0X3U#jdwQYol /3+Eu BrAgvfH)'C[ȡO;T@ƶ \M_|%v ӌjVݸЪgMgC\ec^kkIR%S6qM|DM"9 >JI?&>[!Ski(R.8m Y$QExkŷ;?UHiO'EǻXG)qt+*3i ~K*5SA·*M']BM XnQiwehӜvM?񚽊ܤ̵*望 Ӷ&:) ya41,M:+d@&UWKW\S V7D$ q29Q)Ҡq U+-u5ѯNtPZehyKhLa/t%p i_KZam c9.3.YH`@6b(!;-3 -0uCˈmAeCRgA`Ŧ(w{X | >$Ⱦ#l}NƤ4g1Q]r(Ml') lFYX Gl~qkp\Ѷ{SZR> KhU.Q/Eqcs44zwo#]I9ݡz deD8 nYJ/Y L<*~y{(B&"[ kC GcV 7WcUvy+|~v͐n_uSRqaؚ/<"ʭ;Zk;]7-&P_h*4@*td"-dEX+9,eX"Sh\hwn61f!^V @oƚA.)9S^1Gh`2XE0NBoquAo` ¡*>X/39hCZQ;nn: 6ZwEMZaΥmH{RjO[}'{û4CM{XͺJ *T@VX| 5bSwK%MI 0PCORsX1/|[[g4;,P6Ӑ\3xUN֊fF4 ~tY& L+JZnmw-<^npJ|gU ෫<^=ޗ.\KlD}"I΀ VmGUZ|&Dž0zHRӼm׊6z̘mUw~Pų`8>SKXΣ Nzc׃.hq j[*2"Ok ꜃}6<3=brTXl#?/mZ\kvaS^^2PryKJYh/@"W"GK*trby&<0s:AFỜm0r 1X\P`Q]gTɽ/^G7!=*T l3|* 9UggկVk P~Ց /( +hŚ2TGyM)u~q_3nwÿ˯#P[v@M>Ƚ$o ?F1dj$RVb_>f}2Ѵ6n-i7d|rGn&֞쉸bVl̵dү,%fAryL+9|?vTKmۢ")τugcg9$ci|M;,91'@+_aOIBM2evSt_e{+(YBk~J] {cCerV;Xg箩3혨 F-a\?X&rS%cwq`ܹ SaJ3eT2Td,W:"$Z;k!9YW3ً8v;E-'KF!Jsn8ʏbWQӴ4Je֞MmBaTW\aӲvv|%+ '=1q{FI_B,~3Z]'0^KJ5Vd7s^IIuS%e55\B4: 'fuե&$MOv%o%GFꮣ)1(;ttVud%[tkJJ]ieOúJ$Gr+ ^q֍ A텃#sȵ.%f u:;*?K~WD. <)ggveDMBݠͬcɇ _hmyGk?&''b_GK}# Fͨ\nQ*i1Ir ȼNӖLIJ|JgrN!poNc4 ]8&FWe2#H e N溰`Pb%(q)0.}9z?-xܑ~^1kEړT`PoRa)rt8T͸I+4!v"^>,;Wi}L~ý(qYv+J~.)>Κ05)wRBTLw-17־P,99 (#R@z1kͼ͵L <w_ #ە)42<+C4ʾj"l XY\1P+Ư8f m)V,h1)Q#QІwUJݥPƆP[XiĨ5G>VL"S"AdTZ(j36M֮ZƨEkeė:99fgڂ s%:Yp} ?rY_C錜Dbe OpJDX׳m+Ԉ_ FI׼2%lC!*LV e\ǀ₋Gt{,vfrr_wtvf ) AZͨxRêЫڽ>kfK+ 5Lބo 05 B7vǐ윫6撸z[pQT*rTaN?FkJͻUV} bѩzb)KI4S(@Q?Þ*w[Qκh͢Yj44ARj$_6A4[P2]sN6Jkr4߲)NPY$%>űɧ]DQwƢ'֑$!D  jWw4}6r6k.3 J9%p|Z+N~ހϠeȥb(`EwkgU28:&0ف0Mty$ mN7vaTNo1/UZ!"vIΛ5C: :&TZЏ'mg_L)2%PTV'-GAːu}5Sf0Z7{UbjL *"*\c/G1N:2ϴ)Bn3M$֠Gjh2¨H%)H7˩0@S'/֩0̝|ɰXP0$ cn8tH,}%]C;)}d ] u?44D@ r: VWĔ@O-\*$)Z(~SZRW!Ʃ}W16ABu:κ6 R 7n|btx`hRhlű#J$w[}ۿv9qv8c\\Ykxu{اї b,1aհ"EF5FcuqȤdiڙYkrTssW~(VKo?`Vz(J#i%ƾڵƷ6W+ƣ $"BQisSk;/{ ǘ ʄ$@&o&{YŨչ-= uwoY콼A߇`pŰHhz41:ypG;Z3mkOL}]v?|ݼG\.I;yή;gu>BKW&.\qM ]o.]iOto~4Ys e7||CG'/翾g/o=X]\| JTH-q5z5=k.NkY_sYwP!TC=9Fr770y5nqts%*FE]MxL'Og].rsxTx&{y{|];?H߂ J q6_Lj'7NF튫g'k*a)iYYaA9yE1%٥%0dY%A(g y2Tw8z_ g5?kpN@B"%s)]]SLșFq.4@)MihlEճ-9uAϟ}>=WG>{n˚ OvMn_c=䙮3`9GU]?py:uj3O[?z!"r˕WO]Moަts½?>H֓O-9?{ۃ.'_¿~ n}*Z,(SU֫ըji,i[[]:mG?:u{6k?2k(X`jliȴ|K㛷Z2]mڼ=k7fu9:;9?v9:&vxyxy|s0[B CC>>>1%cjc\R6idg=kΗ/y_|+^O)S,SC藛"m*P贪 Wìb&pg oH(T+?=QB}sV`% et~cZEK@kf[Mcsv^}qБᕑcnے&Гw<ܹ:mO ao˾/xsP\|aʑGO->8ISQϐ6\:~~—Kk.[] }\x[iݠ{%<9γ/ ^nyUfw?| Ye߁?c~~ =RN,pSK)_y=5sG5k^hh}Zo=M;LG]nl<䍆2n26g:eF1гxyƒmjmnfѶnpqbۈ;#UIo#[pAIv!J!B¶"r#}6D}?#h2bLjgψ2V~s3hT~{(8ij ({\EuVJP.ɨÆ\vM$}EAS0@E<$ϒg+p*6smFSuwyq׻d%ky:rҢ۱'O=mz&, 3/_>uUZuoqon޽:G<<ʼnWa{߇>K~#ߙCO3o3237M17,U|'1| a,Jq'D ֽڛјmttAR;SrqL&X; -[4~˅S4J3l-wҞUk1r a;T?GpN?b7-d6:L녴mu" }w$ó1c>귛?,gHeᝏ tѶ"U:ky$Y({{ۛ.Q.y h /$ 4 c̾Z>{3bEVo.4@b[D3Ɓmo n+ܔ笂VNыS{/^eCky%b?UGtp>s4YPr|\ǥCl.ʝY'8>^`-uV XsA KPՕ<7+:#w9}}|{#[s 2rs=7e~nhw,翾7E_r=C9{8kѵuo~Ί<(Bn]>ݍnLcA]9KGv'tڳAl'Ԫk9{Ry6-5kV 'Ot4{w:6;:IkXK =(ʔ6MJg=ߧ9O:P۶D{"ײnOJmлawvI$Dఝޫ.BtI1YHtq0z7j_|  Y 0]dv߿U塤S)Ht`pRS$~]g;DDn]>/lni76 J.J%IZ"w@i?NбNm77|ُZS=X'[N< 4 :rX\EN6ny9f8 uBSb]tɀ{jA)Qݴ}jw˔^/)N\.m YJN,v/ȥǴ&9k?t'Sf;^{C9lQDlO(i5 ^q:ixԱ_Mz_Tk㤘qiQr” 1p ~Y79h3ʤui i (>NiQcly!ǸCY{<@!il/´|UʹXoY1Xi>$ ,G77,}k31e=#b8֩!<^imdir?uGq .{C;o(7-uT[I{sk b/IeۋyGog  T6u:m-.MsɎ5Đ]c+;Nɼ~ˣN]lhfi=E]ͧtB7ĄIvԗ'TtFr]? 6yna'Y:8LMmW4C6{sll}? ĢUG5wtZc55g+vWhGemi[Aov>0ع7i?Edc''+f0ă޾9bIj(EmpY޴:\i@ZO%8؉isphCKX+Ó{ 邎 pD T\+b*Yω@vp)u"/}gk?b!Y^g,K#"$fȎzmnP^ M(dO%kf- 6  ^ak3vmȈxK_fKgMh]g [,-'}^';)jJ vScv g<ݺMiGgukC]pLO8Yg_9Cwrv4eLCk[nXM%%<qAw\!)jLA6yCK;{#S-jmSdcZ,рMOim,μ4wgS͝^w%~(5xkU&mo-8!kŭuPD7i}ϕƟC eO%l Ut1nMXP0[)SSJ"E~!4>"`u*bEo,4zB_3`ϷM`v7񀠥e=w=FQ:VC1ӃMdLy!=?YܐP5) zNj 꽆iN.Ƥv^ŗky} {;KF5Vz3^eA<{=y_a>{ߋ0!VQ7|};6Nh>:8ǂ+z 3)h+g8+ <* DwN9fNCs# =8uN/t/_$x9~,Msȵ>'Cɦϓ"!}OH^˦}uX :c24m)3M4ЗF^\'4v?vn-g.cG뻛+œ) ۢea ~Ӳx&6MB_6Μ8b atsrv}N4n g#|5:"Dοdּ6-`鮉YlB|Uzξ]s&-{h㻹}Vwug_v`|oO;hsg[qXS1lcqy{dKH_``GZN R^-+Rcdꉆ$/Z!鰈$=/oƦwr1o̕66qzG.lwy|:Κ(b4":(ɗizJ6msy,1JgMk h^Ks Y/.6lA9;HF#P\[֊`TF:uuc,)3:lEi]_ ?57@ lpx.7\ē §}gWvBJp:@6N":T{+fR]W1alĘCJ3ğ{p cS޼1sM E0Oږ"hd~C'ѳE 'Z(z\H=sd$6,w-5(Ÿ@L@ݚ(*ސRX.WM>#$3!2fM(of !5]!IӲ.S'$RRΈؙSNH.Dvlݤiglsy %<:1d#| g N3̫pe |m2sgW9aIgsHmɉ"K~I-rgEϜ h*gww")ҍHwX￿b0A@Ύ3ֳ=d\l >iO֜'LWJ|`ARF&䡦㱫?^7َB(wܝߔ7ՇԽ K,GՊ)M\9w ~zkH&B?&RzYw&׊k%[O>#+V1%$ѻ FG& vUouuIp)R]gdǴ3| @hfǖ:{9v߹g núPr{7g CQW.u<o8tY\A_qs?!,xiJDy;n*]\FKAjtת q%cC,!b=VOZp&w~/YpFAAu, p%JsQ:0+-Af3v ԣV-5pt&n+r(W6J3iqvb7 /<|t.4sD8ݶAfg+$6qErOAm5q i_&p 6XaQQ6AvN-Q &҉ x s!oy#svfɏv4J͏3n yA]o|^:줨 N8A;ܦqҔbIثM5|*TKZKQ J=Ðl(  OzxOfۮ,Ol0M[ ۃ͐oLB ۭ?V}.o0/=a~\)VWZS  ^SzEKn,z{prnMfj[oA[Ak'W3oɶ0wy, E6[+5FV<" erk (re'H' `| PeY_t& k` 5L5(7C>%!X.% ]  ]uQۡ, #4⥔@pB,;%ZV?VuC5:W Ua\N,Ko'] V!/jo]T7psJ"_M?Xh6孶!mg S{/;"7Xs҈|ݞzmg;u:xqZqjBewuMrI Pn DTIa7?,/9~kGGZyUvj<@$$ .n|ATf<@(oIs5C)9}a8] Im,a1|1b?}]uFm]Yư.΍1W~d?4$"_#||׸}_WJswi$!%/aYfxkbSaoD.-S.ZX~BzdM3CM_h*R3G(K냤^EщTFq$bKz֪[ XK|jZ36 %>աmjP>7S#.G\6t?w6U-\.-nѹ釷QyEv Od^}Hk-H1M Zi7v+wn1ⱈk6$P.=ԭXTTfI^y,~ؖ}΋-12Co1[n8w9J3p,|zӪ/w9r50z1Nm%a^‡yh1`!UORٷ>zR[otU$AvP>swxm AuMMze@yC5,l$y4IlEOտݳ*ޗe,m8&>V[*Sw/7V8MXv\3 VFFidڥRPFt/;uX}}[OwWŃ1CvvA)iPmNwp+/|WCMlj;_Qڲ9ѺzKuWhLE8˛cوol={Fgqe%ƤAݨ.6^QTolĈn9OuZmph2dڤh?xLZ+oewk9Sl8M2羏02_9z˟s7&e"е+W>Iew^V =#fTQT{ƦgpI`az.-5y)Y9!^sp.\Qpϑ+Li r2;owl% ȿ۳@WzA}Ȩ2tQ") ˳Ća&0;c)wCny]VZkvWtqw`#I.8E8aي;{I  I%֍[S[*wkՖ6I#IU8qYFo)6'vӒbit ʄAshbzӬ 1)ʷ\/eb~ܔ.;;7wA+Kiw%W p٧FM )`%,8jt+>ܮCG:6v> 1˺8(6Qm6* ߱%t%fmI,ӈ%pbK>KqRBgfႰ > fG҅?= CuYƩ7 ݖ&%æ.X/ӈ/",x*I(]6dޝ>(6%O;Ipoo{ ^j,qlA?fh1)gqN:4{'(T¦6|'DK [a '_t=io^3."Aկ]6ywn{uOc\f=zGk%v莔<2*_C8ǚG?mŸ/d1/ج>fi#SU'0PyF+E \I+2 )-ߜ6=^Yb»2+cӟ>2 KnUK4$R$O/VP2$(A#)/_5 wgw@m7+ݩb W i84ŕ&!ߜO$b<1Qe}E]HZUƭkP_VlP1^AiUrtrlώ^ㇾv{kz~sNSV6*O5k0_ ",Vv}%r}:Iv?Kc _n-r&%h2pc$kwib_oշG5N;2َ䆞^iӴg>Ft5z{7'5;6sǁ.4tx2LI&(LgR,N>g>cNsrq{hg@/s٬B"~dk7+{1vZ 'ٟGy85Ȥ87.ZasH^ T|쐽hÚ/!D5,(>L)<[ ?s^"m&|l ?e<kbn: >3o+Qeoinv/I-8`Ý=/uW2Fz+^θpb)'5;s|XGlAl~@;ɑ#Ѕ;6?Յ3H&D ks,SXְl4c~,f3ngȑcw<c˔<ܼ"7arL QYv)өtحI#Vԯ)cp1GcRYP = m9D|v$!#TFZ_9-2[<]9*t1U@'TG#8{kdr$o X0PzBLL`3F@_ִCFhe]0׭(_foGN 8BvB$Ȧ 3`q,;Tï+2~m j3Jl&傜)' \T 7V@p50G^鹇{Lۑ  {J nfϻ/N[ 1ܛnPΝz$$W#q#K(P.n)"H!?y29^o+b8"6733E7m̹b֒0tVg.vtA3ΕsZCpۏE BI#shZa(< !0zF[Mz*ok +H"ռIU LRn3-px 'Vأm{ "U<#^>FZ3xFftV(^uBhݴ^{~I(< u^ |o%s [Y8 d vk5ʶ<,XK#KӚ4 u_ t#A*f#:#&c_ZλaYs g4-bZ;&n(ί5,Aziӑ~^K iOɝ~lO G:tKH,ڜt(Eo2ShU@g!=%!ȩ;ݒkE阿ըʿB݆-EVﮞ:'jS )V\dxIAx_p6$d4^&AXB T6!IabIj˦giqRu/(??H|tDK1^ c7U+5M,AZQw4Blۖ.xK[Cpa yiW[U|Ÿ'5oZ]tlcH7>&s8ĥ A"Л+wSyb?|.雧mCyt0#uC\?XerA_IU]p_wlP-\ )i K0υXD/2I@4Z0\j1k ["̺oqc |ϞQ11;ރok `E&4O~\ %\O7W77نT'HW7nzx|Nr=[9PtZKXA-x]flSxbCBb,]<In)RxqH,t2$ -k뵓r?emke;ča4qT07tE[Hl%Qk>Q՜sڔ 5gzsMU]Ni˻QU޻k]5Wr}59W"{yßYI$~~N;\_)ōwIB)[:*P$o|A .9łyVio$o^UMWvUJ%KG丸$uRUsRϸm(l]uiJK[>3'ԏ1eXd?fND!jOڄbj+& @}0l|ORW x4Z`}0GǦhay^{A8Llk9 >_А"wm9 Tm<|œqC6!FZ(4MvhFjiƅej~^N, Z,{"1pdnh[WѼq]fCdjC3SGV!~Q#?pGnZ:#q h nݖXWAZvEx^6Wz#M(v [Ÿᫌ]ƪ+guHn#^M> &tZtY.[Ž5n9,_H=ai26c^guynGrMM ?8Uzg /y<)>,RDlؠ b`̇X}K˙z*iU~NdP#AGm&Afn/6¯-Չw,Go۴KANΆ̳q%DS!?qoDmcH7]̻0& yg1oHC}Q}U1CNi#K S-}SU˥ ymR?n\;.0#_ ѿF9KG}#UVl}g(']/2LZ D[FֻȟV*!|?F#2jl|JҪå5[v ?liExC8-щV&S߸ڲqٔz9\z9{lFᛓttpҺcYbtda@U5z_$$r6ƭ}ٮeпGʑΦÃҒ9==Q[3QAG^>Z3~27d*X/P6<ꡲI?*PrlK9FN <-#+FS'd1Ғ_.ӯZes.0/} .0w e1]5_^@y ͏Ug);Z~^X_yUJ`،y ߤ'I>nZxXzBzx\/m^Ncay)."=ψVD`ia2UXWuLUU%?D_A"I.~'㲩 O&3ä́\[5\RzOs''9՗5/cS} \!frTs85 fJlO1 ތn9zxC%v%=>@UIYQiqJӧCڞ\=8X2vSֽk7Vѱ#Wf^c>R,o|h qAGfbPKJbɫ,vPMDV"g2* <\}Mj9f>|ƦJIk mKӌ%̖({n3se?ゥT!Tkal ջAaꀟ;X#@^ }Mvv WiS#lD@+[Š$l"cϐA^zxkL7Vc5vT{(wR@ZA; NF.xq=hsDmmݔZ奦"N1fG/hbNZ]f÷FfQ@ݜRI]6)2#"*q|$>+SNTw۶t~Q&S;uG΢)Y_65T$12ǐ;ipworn$ R7yn'0/}`–R`5&Pf 羵<s+gi^9'QQ _qߓ{.M˹bx[ 3ijy_u^d(dkإ{K7)A\0ok;TsҘ?Ϫm#YǵW+ Y\ѻzN([olNGaon4P~ZjG'IKT/ܶs"x#68Ȧ.D>:Ş8?]f/R n6m2}+59zPobMm3cO&c]Ѿ (_6!(i㘢|9rY*'VװyBr$ɤY+>ZgD3X2sb[;.φ:O-0-/ ˠ5zD^baL& 3:MiOq*d'6 -Zp{-g&vHax#c 2<,x t%RB,Ym q*To,8@ǟC[ :E}d)LncOiD;iW`N (0AyM:ӔkLA2mGb?\] wttf eW\gAIجfo(ISa!wG ҸxtaQ<3V[(o(Zd!{DD2 G%GJj3jnO<ޗ-MbkW j%ww*lnVQ;)J[''}ZO8P qd^Y'dVvn-j&nhN }Jy9j2#߬΋Q b7һ79I_5f]Lьl`Wu8HsֱBn%o^3Z$`dCmpzD=+FYpJ֣?G'9]m}PKl~"O2rz6dڲjFbpЀ\rK&=&>Wh“Py <sS[05hPv$nw_CТΪGAM}5 C=-׬f qs?N O;8POf]MmxDkuݥg]`L1ߋ5TFC{sMhb3o1V9lUp9|69.D˻B; ?.H Mh>Bu[igtrwjP 1'ÙP_,Ρ:5lFa-N ]*i,ɝ3-Z57_7B46x|kOan+u[ΘA?7s 䆭=*omM5 'z/Mr:z-,6D ]5[gwQ&>j" ]ְJ[,(wS)#JluD5G1PcL]]{BШv.6*:jŸu1i4P4 Wh KAs?^򂪀MI$"ڎ>|3L}dq}$7ejXLV(IY=8zQe0-b9}%8j2sPAz.pNezl܏ pxGsX}c-ThGWdk+Q\+_eTTԌx%y||J׬1)@~ Ηr'[]E@::Ev!6l'5?UEYWʨSP5TU\P_yͦB: q$1H[Zo[Ş{VXQyLaqf8k%umbx"ɻ.n7=DNfvz)% CۆT֔G0I{d1^k)7fWQϝ ?ţƲ2qSŶ9Z+Sk&Ye~}3"!7iSB<Ꙓ@' eg&=SE53d5N&mpcv~ZuC7i,\[yHI>ZʢPn?Ն1ٌ)nlfE/ׄgؿl쫶d$>]ȉ%6ʔZզߌ [˟ñ4r8qFAA>h. ~'@T}hRT5$@e̗>yHm[f̈́vdꖖu5O*L[gSgT3嗑}6/%+/4QC$nqMsjRӖ#>fVC2Aq??'3" ҔD6Qȯe2[xp.+˚ʛ4bV0EfÞc!P0\SVqwRWU9If:#E3Y&bh?2kBVY92 C.U FJ o;J|U{LF:ܝ.ӂ8{%3ݔd2.K*3>fղOc!y tgLh<nAL$7%J&"EzR*û" 7xXCl>ڪ?Ai?rxh,8 *\;W.iE+ѤTSx#V Hq!L<|/}XE+` !|$wQ'\W?6z y(]R3gKoý @4Sj˜(OsY^ E?!ZKrp-0Ttt9U+wV+*MmdU{RT- W `*于ؼ1_L8˹+TǪg"ꅼ55 rDt^'A_46.&bg) y`V::7pn.$sFpn%wm7ZL4[ Yb/.DV i\q{xk4Dx.6x9HC(RW r6+rJ~G, %x( #=Z^%d5i =,Z)7MW ?+=T T,k,pFZ#-n+9"1-ܩ67) i~ 1rUQ[䠴F)e}B^vC7@+㫎O5n1ZEX-|o ɿ2aKưOTÎSuKqp'w7b&!)mu9/ kwnmw/h=ywkq(,(~1nU= g%G~]Sq1xU+" Ih4n`0ʛ87NFa-&-M?FS7UַyKR!9ZL|?J/nDy}g̈́_m͠"Aڣq+8Yz01a YtR% -wL,=\(*1 d6Uh}NM8`_s^-L\ЭеeV Ir1,'s?md?qczfA{ d xl+:vmj۶6m$Mưm[glo7{*a| &^djK)$i//v lhfFpti]oѢaf }d\EB"RՌJI` rM3oX)z(~H|%O:.`\<4 qʽu1uߙiWpMnZaU5CPc*O/ d]QyZ'ճmWuXXM/Z|-C3!t &"ԕe}c.Xi8{XTov6'JK,D;B V(XG+ڇ}w;g׹ UHkYpZ* n w< V(c:jJ*>bnp^4lGh"&y[fn-[ݯ8҉/XY23nvotU@G媏™;:Eؠ$٣ yNʎ~[Nو#a_{ Tj_]hfB*y]uLn F Tp:GD 9T9Wk?TkRy VBjjIɑrm>0_9!(p!{dɊ:Ej_-W^}] \zG| ЇG[4~ީx"W+@VD."'nk:u,;cF#%4/ВKbW#e U!K0Z)h\,@]AEd+RZ-P=kw`YyÆA!S  xTkϩlyWcb_"^vPtelJKUc_s TdE=p4iOO88*DG6Z1U>.Qm(xm\9i,.'LG#BrjSo#%HCʳXWտM+74snu;lӑdpk'&UCI?"rdLG'{;T;7dh<[xCS-U(0iIŒ|u*w0YxH&G?]p!fn$.`%֦ Pwt` ({ߵljpUiU#~Lde1.[^>ܣMWGoxTfVL&WpWK ?PoC+t$@h-D| )[U2|0GW&G![p!_!4<+-G%ꃨZЍh?4:l0 vA]zK0 5WUAP+:yzPo֠rG"zbθ [ދC`aS17z ~XgJ݉"&`rICFo%8Bz".1+*-X4­AQry$ʣ9H!VmO/E~<]hx[V8x^StT2lO &c1v܉<'iF*OKNMW0+nz"i}l\HtaZ5slׁT߬#y2.X3G/)T>8]az0mNVBNϼ\v|]a#0)'2 zufn7Xע}LmWY1t 4>ڕ6Юޤ%p@J*TW![simͅ 1 W$_6XV+8il oژViBkFo U9 PYx!r+"6e䍩1,e`lbsX٬_ h^)`i>XWkRvjAYP?1uվn.-_rg)ʍnAAn+A8LKc1/Hg 8TunE:_`3Ioeb܌wҲ aY3˒[9,e2ԯb7P:9B[ķ[c[K1oD)kRqQ0ɴ0hNcPxCI]fr>_Cسww[~n֜HopJչ3ezZZ10Mh*'Vt6-WEf{J9}T0C=&BtgP:|Hcжy ۸Y'-G ŏn*d܆VeM#a:vj2Atq[^(.4>T? ~wá%'#Bu7?ޕ-A1.96X^P\< eE}Go>r 6: YM/D6Khntl}5SӠpb9~*E: XGE].c\b+.ko΍5hO ,m̩gb_ܚMW{tj )w"y;nM@]|a,0џXG܎Feuos8)Y9W.M{ P0lK:0A3rv'uN޺ K|w,޸25{5.N jz`7|qg3N{rKARϞpi˨ ]qluGJcb%Nk<C#Mn3ue~7j!{_4*=߱J5VN}W{EK_1l}6+g=Q*Vpmմ\DPc햞^kO`'wX--Ț^|N5{.q.gǦK# T_@-Rg[8Lio3qK$]zDI*L$W䌨ecO#l|JSl袁M +!TIQ ɜk bNf? K )tz!mQ0߰f=杰%5.}ggal~F,: 7kEIj>!\4۲|A]sk, V>\R!eVeֹ%V 'fuxc+0f*yQv[ + ޲|ʼnyrϜ'th%9UAHqwg0$9ph*$2(x4pŦ⑪vuR4itP.ts~y_yf3˄,88."|.!cπ]2W>'/i&Io^B,/+I8W#YPu4I iGZu nZZu|K)03O):h-̾>ĿN|tOQ 3R<ƍlO]KeF"oʇ\B5iK,zGfU>Ω`/h)yP5_!Q/1*UkkcnɘU+K"ʔN¿mGRZӛF &em/ y,a0rNONj{mEM.C3H~67H "ERɭyiኡKU#uIC ʔSM:-ӱDaYzIͬGY~2b!iJNR`AH1<Msaa6p%y{dL0-R9:Id$1Vxre(I:;Hkٮz# ]Ɔ|ZؠSMPO1+ ιo 7;djZdi8Ѱjakpi/eu_sbY8#Ҡ ^'_21Id-Gst6p+۶1Ԗ6 on*z}TN(%.j+?,~Z}eQ J͡A]/d`jwYNc0/KFqv_ %Wdcx@rB LAInguvD ZJ֩AuE0@ [Qv*ebG@@G,O£d[QN 6qʿRR̸ V|;U@00׽)3h30GWHZ2oi R3:H GÐ"Q6YFHУK27Xj(>. OpTB#?k.dž͒~}|| ]l5G8PڀX'Оݍ?$C{-,/}h^a<z4tE/ēmkYE RouG.*M?i hRe@nOXT"Jϟ*eu|.8/1JdO*:֫F{lԪt@A W:^?@YyĂG7oKQ@+OkIh@z8;+#xGP~G?ǚeU~ sBPz&P[>a Đ{I d+B.,* O_4y* #@9OAFxV"'?b\woZuVjN #r~3Q(G@~NXME}45,O ts2*:J4'<.ïƯe 4{&WT[ Uf#F,A kJt|)5ˍQ8')6T]rDYPW?8a&cA~r+ށBDC[UsJIE"*ix9#a@OnZDw؉!ֈIƿŮxVj˰3)a T0oyxN6?tyzUտͺNNjJl~ `/EJgP@MZ,& *|є\4#U6-$*Jށ=#~ɹ;]x W?se=b (G>8bW6V4Vd0mۥ ުZ֭bQıQ?[W.!>^@%^7FNV:3ӌ CSAz]08j"lXOz \.b#`?2z|T~۟6ڌw,,LF xFbuN/{%މ(_K6l[Ӝn]]6($WQ(sGxJ;h<O=Fl2}=M0Í].3L>ucʹX#InI]Eo4 oc-x {m/z <2%%4,Yd8O6 h⣪ ѲL6? 7Ά;xU&`?M\}U8N0+hgu1ót}mگjrp2|ζ [̀,D^`яk _קLqt'a. +P7ˤFō֡Һ NSh,uo;ÛSvhx~_c&?I+~F4+&׃o} nΌLṣQ{; {0 ٕP9ykJmՀ w\Hrg-ˋv-M7In8xV'D>Lb ιͩi1ƫ ڈHC>,][7'}#ih`/ùxSnIݜg}-#in 8C<[>XJ9yỉQ̑Kғ:3DkzY{Cw[k<4 wfVLgZ|5_;#z09Q9?{*k ~x>9b$B6b֥{Kxքk];ã푢R _<֏Pr~oh\;(v~ ,KHh .iCkElRѬ./rIYs9xmI;n03<Z6l98zбv_؀PM<5Y4 . Y}G~,,7~FGA{.NLc9-3xR3yVG.tw)!X]||TꀶtSͣu#Z{ySi~dg!xrGH:< )O-KJZM"[C1,j=6]g~UrB&:|& {; iQB|'׋e1;ĖIW&㘙'O&k!Udj.F]GPXQY,_=w1*x*%"%>>RUPҭγV/-2Anq`FeTPvSN法-9P U(`Hx=RؘO ~"UUø'W#' W|^ˡ74:xolh}/10k.z-S"n [|mePƷT6gRFB |*o,>[qMז$dol&u =Żu9'im2γzۢ+淩5M^}\ #'N wZۢ\樆)7ȈZgA|Qmxt9۝xKq"Apt !Dz]R|B07{# z\ )Vw2OsvU3N3؇~)$) 7vg1vhکZM>c?j,ǹg5/Ǽ6S4dP.Kj,9-eb2洑۫*㻸wT L'/k֓!oGOZL̻EYE'4Nin?vF2!J-Ia*OZ!}*(ݣx.>@3A^^ VE͔gU.OZ$j~5Q's~iߗAɌIYtؙŌE|9CZ6S?ᦜbslJTêϪ싏i^Y?~ܳqb3d&#.霂on#\nQkMǟWT*Ф?R/m[ׁ) ?p 2'*?\Pw!7X hؑ2P\?!zl!Hbt>{KO 153e7$) em֑H &9LcyQrq:%WM2ĸ_\fnGImGG"Ay|c/BQL&QUx?yY<(_05 !6^Tzݎqv YQAbW#%SPVBBxA#Gն8`A&;^4V=U26Hlө!d{&HEq{|'|ϵ_FcʯI[}9i凍 %aVv|  *|8`?C.+Ȇi#e/Q37)ME:\#i3-1hhsW%Dxc7c[LIMHf/]F`r/kU5Ns#8+PϺv~!(%q7jjM7u"'r4(oDvK$"VZXӾM!"#|5sLHE*voU+8?o[4l9M# qưL 5ss{ N#+^yQ(uPc{IK16ƣ1U-4Y6>8CkP*ì6oTvܷo!ܿSLc_<Ɓұ 3.7,/kfޛ'r1ӍgkcC {E}+RԏQq RwA7~ og44'5 =LT_c]<^)W{ ŗ|m%{U$1]#KLe)F1yJ}A zF: #'TkQ!+d, OC_Bmd 3ٺQ|UWDn)رV%]T#"d{(Cvo3Tc|K(B%^Vc V&vmK.jUfmnN-Jox_^1NSs4U]v@03JiFh^Uɼu`q}zY|pgxAHzn&tXEQT<-e %+\*w1Rنl{r^E0ZG6\ީ̶Ԉ\az?j2x}ee+ e`?w*kɨvYs>Mp1'wM2[oU^$ 2>QłT"1۱T#T\pQsJUc)sfBCaz?c@4aC`@qj_21qƞ>"<#cAvԳˣ>UWyy:P?!"]ly<'yN|K1UJ`K#+s=u4 ,ږ硙3%nbMNde]1vuda//2_jyRʵXjq׋JqY̲ބ_>APr 9a9 ?#jNβoQҟqVOOm a ^a*>? z"MK Y|7OvOBU*rc8yF!\T2[[EP^Idcx͓Pv^Ah*vzFk2JEVJٵ!NYZ\|,FɐPzrȿȇ-8˼c7dtjOj0%A %*C ޱn^}̉.x[%K>[PH7د ia.56†s篢^2S3ޓTA5Rt 88P4C-.oq_|=9{ܝYn0H@Fowz-,8LR׹j$ŹSB/TXh]Y&NTnxC2ᲹJWG3FwүU6W /ckd*眮®د3 KGSp?̏>Kru[~MZI.T)W'Fbk^[?>?m=%6Fh* 7=PR%(PLB=S=m* ^,n%g `%s]h;z=6̀S,arļx_+Wf,>r<{^"⸵CPWۨwt0繼])}ܘ(s7 YM񛴙gmB4; sy΢.]βGƪ 9q)gW8kX'Īm_{Fλb2VNYO܃(6ci8"7}9p"o|'. CۂՃm#sHFJ |E{uoTqV`zg?x o: AIx6a^'nMUvƅW цл4Vmv -_9d"Љv0:7}$½QHcH)TCQMDZ.[mkUۺUh( w;0a^HS{A}`\9y=={Vvl.`pO#qQCF4 xEpw/i71x5xKEMvlr "^kDOoX8 Z\!W9ɗ^.'c>wNqvØXs81(41}n"zM 1Q.4aJ)}Z N\'7uSo!H^]!x YxV{O8V7o|as^F2>켨b=W{c}0=xW3 7zϲ6cr}r i2wĬn]6ޮRSk8M廸U ;|>nRWVw_aO[n`m9al]s3~}Y݁ ͮ hؖce[E>.r^t^3& _Fi/~%qLl, 6V;4,|)Gxkh6^2; Giqy>;xϿ򫯏~}ÉOgo_x~~nsy.=x<ϞxA!aQ1q I)iY9yE%eU5u MR[GWOedlbjf`px{#݃JNKϠdfeS iERFYyŮohljnimkx?084<2:6>195=3;7n{.p8g:tȑ?/믏o;~'~5|jSçj(aPpTRR,k0o*Cw10},HeL9iMK֋l*Z̗+㦫T|&X*#lz5-u5}5cYm9Voq(aX`R;RSjO+PojbKi. ŌҠDzƿ^uz{&$R"7]' 5ˆvJ'wRڕk*KX*8{:g>Sos^ݰĐ֝bی4ʸ nPHhꓥUiKL;hl|?4UIL+Y`.[ktkt"! i:ˁVI~9dv|qYn-=ܗU:LrO`OEUx[tӫ% oI.:k;;{_ OJ!*4Cstɩ:Ԙnз̀vVZRM[]s}cߚ:5[ρVM"dtJT絃!~C:ۄi^i$tTٷcYT'jnd͉ S4 iA)^ZA*ߡߤgNZЭ{%Xz:zU&.^YQ"+{NE9Mjۏk'cɶ4 as z"l:l]賟˂ w$%2@Z'vW*hSHZU Uq6Za3:QӨ)X)8$:jH_P@H,D4@̈^vCjM|Edmck[4]4 G~x(".Ot@T.Љ54+$c Mnm ]u}j/DSçO ݐ)I3Y-RqXkMkǎS󍋺*m qH~VHH_÷p*?pcfs7!nF2]~3@Ff vWbj)[g]W?+"h* yX0K x9>G\eHh@D#Ƀe:=%("tMk)ϱ>ݥ2{;NO}9oB+\qbY|2nRsJ=|Z3eW]]BJڪr4hzBLl|BLlzyb7|1YYvZc:V0ܨNhEvj[ Y5Ut:7+i48D_IΟXs9O}x_ )-1d 0l%.Ք^bvaMYIk^UOrHpGiO&<>BQŅr)X`_Obxېn\Ӑ^Lj^nQS؄icj}S.)nEԏOC+"QJi݉Z9fYǞnY϶!Qd{@'˨fiµ9tE>U.)'f4J)(4m#7b[B~j҈sU82ecmss7J$[1"a'mbXzo^밲Y{մfTɰ6kXִ2բ.ɦ9ݧVg }w?+xJXbED}@JaBɲzV͋1[0E5(N4fF[}-vzN:n\m@,ftuB=]%dXJeK:qúY}z.TYPYOe-ŶDl7c|:>Eo, l篝*_V-jgOj% kQ"=t.rJvBouô87شx4~߭<>~yI !撼^C΢FLĨ&H+۳_׸c^bmɰ-1:+-:>rKe~o{vi͝EI aCOjz(40ʱ0V}_dK(X ׏M[35sBJ6drw Sp ʁjSvډ)VcFdQ4txi4Xտ}{2|"[/y8(?ɲ;Wjmh omtK}[\]V֓C*? _=i4 IlIWqKtu|VTNhe ä'ɚ6ڡ)PV(%y3S}}iW{!)P勫-*͗3ӥqcEziTü, zS&ʥ<į?;'?ͧd0ѯt  ʷOCVJ,j\ 3TsbjE Wh'fYixHώаrP@|PPtP2yB C`RfZy;ӊͬ/2WdYWR;Rzb#S#áa%Cү| ܗrވ)/OW+ZMGU<{ԣ[ڔjNʹk$:w&$$ч%CW Ŕ*et'  Jn=jޝ*QJyAqݬ*i&exч=^q%C4ާ;y+b 32curf-r؞nEAm~(VFN(iR\bIsh'uEarɐkAƕow6U@hLL~-5$m)c>mwюH/hզա1Av2.~ʒAܒAB!f7LQz)v e1mLgADnZVVaB^EhiWmS[lmp%;߶я)?\2/ׯkD%Ŕz%4G j+t|KbF2Ru Pe,Lc#[֪.ˢۂUoy-3^׉nVT3GK'҆3ct Pe^jVL}c#ɳŲ1@ih7Ⱥ ds_`Pq Ey5[NhVRVVHnwQk'n[ks`۴[47566'novs/nx'_$Cwd .k ˪> 90YTj$`7m3՞!'k>}~f~odCA lq7݌WH+^zKF>:Kڋh?E@̾ 6`O8\lxv+:H[鮒Vo[N砵e@@l56MfNΪV9Gڍ/rDf(<|hkTfjczhe0P"X*~A셯 W~ Qo@<$@V<;b1g8IHv$SËz=i뼲nҊ.:fu?>5|j_w# Ibr* J[I+q:>sFS c>aלg߂>BXq/.Ve*lba*\@Sn{RDe!] wij|ATiXm71ݓ\mSeVi[Pa]SSekYbpC«W&"Rl,U i!E7d:7N {z]Kv ݌a2:UȪ?$pqO!+~#.Od3OHAͤnjŚiތfz$>_PDiqi8$_ )$.ORc@hPR:?AэJA%Ze:6yHLטZX֔\ݜZݜ?pKHpC*?n&UBmH\dX4ECke&'[Pp.eeŞuTԦ4$xRU~2B% %9Cs 6Sj1e2ZWMoh=+YКYU]ٺxKH!vZ"CVoBbR~RíVBH.,v( s Okkcv1*? O!; ]BiBVgJlUsf4TeY'2\jbB[Cۃo(|"K q*YqH@ ^ŧSQhQ.LŔ%'kbbB#Z2ڽ#+2;|BI翄d_ 7d=_ /Md4G Zz-J55%%TӂLX2&4BJ$$Tub`$Vg+eU[{1  ^QLcj<Ւ{43񔊷DfS}? ܗ $?>%r1& . ն! D㈚-WѳU52\i0//Ty89R}mEv َKlۏB;/,lTnB'6Ú刴VԘzݼ Tetd teLMjH9%> i6h/T 5 z'&4"͞ehOg#ԓC;^mEN-ef|6jo6X5&MJ ׏{6ȾRVd.h3HI1$aL~C}nӅ+7ZiXcЖk+g5k羀g>✯x5wmPnRM傲Zɚy H^RQ HrARQy>tUnM,5* gͨy[H ȸ}f 6ΞgWWˉhSJPqYTQ$Mh$GvèLA\-դϡZG.AvP~nYd?צ$KSwt+Į+-)zΩ9MiMh'ڌGM)FCvY<|~@֯Gn4smq̛Yt֏}/c!乢崠 ֎2254M0L2Mçj:FH#~ˑ%ƍcݝ׾=Y"uG?DbA\/$-=;+ڭxZ/i-hϚXEj`5cէc_5qXzq`U 0b&]);y2t]t_#鮠MKh_Ē"_m>@u1p?8: sWOKwb9_ IyDt1 ilrh]%k56N^kKAs E4qT4'lX:)o:+۹Gsan6\;<v~YT1q uuA *F0Q-S51S=se0D+Zdw 2Xkpq<<~aB&ZBe *j*JyҒm !@[ t$Dw? y rB? @D*A@]š1i:pΑ1'M&[EGM3(#a#{ؐ3`ؖfҙ`ޙW>5k -Q zn.HcLZt #:DL=&1IV1tBƈYF15k؈3dXۇjm5}[;={n NBt Fd@Z6urtنXgg  3Zv*Ӫ` y BpB'F!Y J۱p]@9O)WDŽqg]0e:6g"=oV0`*2m[*[{g@ Q/CH b7Ut3In%Vu!KDb+WJu-_^!Or2[a8ћ li “ޮٕ~ z1!ZaR+S* ̽3G $D< 5vURyPNgP|f7pL7o3aaN9%^^!% ĜtGfU2:޹*ƥr jHzP^]I*.eS%tU"MǶ,=$hf LȡyвK=b*R(U ׺HpOCNH~v7F2]Bn!9Q`0XbUFhN3."Ds]idDHfWZu'Je{ֲ=j "Ry|&$fʨ(*T Ѵdtjv 6DKfD1CShl??6ϧS[Wu0Ds7]?2]H`B\r%8\/(jRr#|KrRmrbH#$<XBe{kIl-k a< 1C:M*E૩j1ёzIViŎVIT=[ѾLÇVmfǻ1|cѱ5Ql(vSR+!@ṳN{4W!rV@hwL[qVLbrT5>)IfblZ^Ay}7) 僩7 ?B˛O8g*yo6/rqT5*Q6]8bޫۡԬGj0Hs5h d֦T k L½Ӈ!GHwqgwu\m͚+U+˞аIUs T ӌvMvP]6.n"DO"]DY\W!HnhyreH{JbQ^xIU%gA(yV.bZoJ%eB=nB;r(d:`3虫5OWR: >7Nlyz}玾M^f.H=*^WYWLY7\(-*iYOkGO[&#.apDPF#{ CvEMsSvQ;RxuyW²FN *`;CN4'UƢRȩ{SEGg~ KQ(E)YSqChx/,t͂s!90YHih𘽂?[dr;J^ 呂HA@vGRv0 k#WMHڲ򒣟⢻O^pmg; O/sHR j"6 293(YWAbz8w({-S-4AiӚa$Ap]wq٫҃G8JW̅?O.Fû_ TLAa2::( 4VmS3SCs0F˃,XZIb%w6{Ūu#N#ܽ a 6I=IEuSQ%5%PPMM9@"dAGKRҖq@늂^1p.~ɑ g>/Np4sm7* *Rr +.R")jR)-Z2"#+ zr& {?߿{7 B).x8mllIA y9ݬY¨dEV}+vۥ7b8'>5. 1QU]B︠6-0e+Ey9äY̨Z4;7ׯn0h7!;w |݅W!LD¤!DI5{c7͜VvK !s3i)ݢ)Id{NORAR@Ri^Ow}܁0~()yP@Q7z;-m<ĀY)tHԄI\*#aԠ0iX*yH-ˠ7Ѥ/ʬ\f޻'!ܻA<B$S8Iyfj0vא8n9Iù DZD&t*ȝ-iƽi5f= tOFހߩC;w BrA4HD 9Xbz&H0m1f0փ OlHLi1Nk2)h0iM)eݙ4<뮬o aOoC#H|*."?a1c?hmJ k%x6'ĒYhZV%]̦YutPlOk߁߽K$|ovWӥu&̆v}F.o}=]j)L\Dz&9&/؊K˱Kv :׾{  ]ʒRɒP1OAt:5ZڅW˜SPJ!>>;.+/àfaiv$|;5~o Ap_7!]zBdP~OEk>.̷*6O ff9f8SB[ac[^@ɿ/BcN ~ͳ/,0[(!9FQ) 檡:Xc_FU8->>ەLLuKtN)#ТHbkQS+-Թp/ As_G7 V'4!)0CZ!JU1 +P>EQ!vNxм(p ֢V^@Ƀt8= *rQJINzcyu±loFO!HY~A!q^ž^tooϖboRk^@Ƀ|8=ɏ~~ƵJkͳ*Z j RE FN6 K'GeF<(t7W7OK^@? wAërZqOW <~,(\+ZS!oZR㕞nloGvw9 %!ͥ:1x/ ǃr8D \٤pΗg7毷Eղ&4} 陜cajJŦX4`[Ж⽀B/*ӕ7*TZ/mW#34I4|l { !-K,"' &t| *h/ ǃv8s}}RKcgWz;_nzRHR jځ~%("t.7΋+4/ҥ2ZLRZi{'>!{26?5J\-OijTv E{G*M1D 'G<:QKUl+@ tsک{a'>ǀ|jݟNuvq/5cCr:}2V݊DuobN(djrHiJhTiVhkVcufkuD]97/}ox.JqȾΜSH QtpVBYB-tqCDdőT16Y'U7m/ 7߿g_a" %e.J$.HKZ)fU\-g^ƳzsZpHiXɬ8IvHw^@ t:P7~ŗ of ?KS]0p]oYm(;kꑴM}4m݃Ceäg%g"hq 6y~g{Ể x4ڕ2QӴ%"6],TV++^2>KQKdI@o#>m; O/$0xŝA@ ol V:6;XmS;+{-QjӍ($Y8+qTum]>L;'Px|x;-@P5@E= P3P-#e3Qˀ%Z 0`%j-f/p0rƿCE/S>sx!do$t@TV@^YTT@C]4e@!H 0 N 8y~#>k?onwL#=x\ @ ˃ ȋKIBZeA_NP`,Vi/88(p@8us+?[ Fpwmw[s+9xXJ31B (5W_/<oYpn]%Ɉk#ж0[:!MDm]-}MNZU\QjZRUSӜDNy}ȧE ?@{^)HbবZH鰩䴁q]Lu_S%xx/+,* Liv!'}Zu|?\~: N㝳:x_!^OEp%mc-,vn5CHed""{Aw^oVZu(`Xc49Ь7P?!!p|w΂%7> a祈rEۛXb-M]gQx) IdA8849ԃ jћbLT:.4x=/@ SX#! Pxk[q҂6n5O  . nm 3 c3? NKGYytyp'!*&#П0@O:Y؍a[7 ?>nN6ވzшJ(釁۩Cz(9 @s.zx7ZFRlوv K;ytzY6Ņ6GFբYJp |(6a~]: n!-/r5^Bl.VNq2B941r! Mx:ۀ`edx:9iZ0i/6G&dZ&x<~p ynBdAdq$8%HaW0ʪےP'.x2Lhdu|l%%ЂHE'Z'QRl>? \!s7% \x`Jwnke}9C*w%8h[rbMar5+5ͺ75ٶ/5ӗ <!Hxz}2Et0Hh_|{NCeM ϚTLrb( d\Rr]^j"2-ەcכ%R?H'ǥ{g\ཽi$s2dɋW\]U4IT#JSu3=,bBqaAα>I>d WLg,',gn 'Cǃu(zpnxkY|*D+e5iyfYH|J{lݔv$y+/s%΍T?sÚjaRF>M4=E&ZyǸF'9Fqq9V5YVa]Y6ݙnʇ! sZ/tŃ3Nw߿PVPV)P4Ni`t]|-C]Sq. DT˄tLqBUq|WYT7ޓ!s \o|'8>}9V{My**9TlmSho쐃"ơ)^ƔAFFѝaԓI35~]s巎 6q/yv/@iQLg)YUj: [u!UDץ&#hTrZQ/Y+agx+HrtY׾|a7Ug胂st EuHȣ=ڮZ7mbtjܣ4kcUXy@ c Q ! [N4yj绒qc"wG^ KJJiz{TlK ii&ߕ!ÈkT`D}Ĝ9w8sLq}^:d̫3MLzOJj:MȢƕ,,5.q[ '/ __X٦鞱 āɒo8Z>`M9P:E3K|qK, z/9/Ih-[.)-Y.kcFxKGU{'UWw$JA7s0s>`,]8},mɹCx^ :{'j-4ږ7Q5F2W5T|of#cvG‹l;ml9 l?d" GKg5#y`x ϟOhGij h)ID0fh.o aǾmխnmi{ !FHD =c-ժ*:tө˯[mQ-V?}?}u|dm sU]y$}_aDiq85#0L,으\\ DOGx~VIX$S!'BmυQ*y]*(@e?41 Xc#ۃ-k4oѮKu#E5$ a0P*Iz*n`s-ѵ}X9{ B>-ti VZmGBlX&k8yi(\76Pwc{@-3EsR2Fl8=pU6x? h*h/p%zDZ! 5 "=lIr:8$K l:׹9|N/Y{wi7}6,o \Y1`/i<bB::A BZ ԿEݫ\Opz54=8=OD!LF^ pe b`)IC  B 0(z3sX/Y<rwB=g wʵ3z3Ko oKX[[ɸ@D\aJ!I \R! p9?Y(45)t_X9S57~?۫A>M. 4շA~0S [=HYN$`gy$t4gR3#/~1|cz]E[O /|I[䉔@z1XEiHR {A`r:g|=c/XPpZGZ^{JYߙċI|{_>O~F7KOFKX֋wD^j[@[jØNe1cin &Cd4s"8?&)9 #fCғ=_3|좎fu<Q!BfEXh|/3/~x |WH>IXzl_H~zy=ZCs=ٷn #NH9HA(Dok!Ky fT :YbDA >{.H,IΨɺ|Zp9+RНW_27|?8RrnzWZm c MFW)]a Ƽ!7 2N|*:Tt6sb߆!,il3ypkpV<]d1S".cv]ASXkIՒaC5C%졒OxiQmzP:{B[~§&3&k }UwJHs3¢:R%$ff.oVE.|2aYEDzŜܡ@(IAUP$j4jm׭jO0f7}W 9̨ NBsJ|zcb.>W^\}xiTgyqԽbr߆}+DqZMۆʿ?oE{joRg)%\#YАKIM' J%eyq9qUYq*3>/ - qrw^^Y[Ovwf3R r:!?,Z^((N*K).$Օg$U%ޮNI|S*%CEJEA:Pqh\QV ]^_䒑ҝvkgp؎Fld9[SpҊr9酙Iigi7^ħ||X $x9Iݽ V6)mWpEMMM}W owY^nsrj;\W)F 2 R ssK9UQWk5ܬ*H\'mPk)XU_V fk3bIp՗Ѩ(GϚ=R!Z?|Jck޴Bڴzw3Cw+8/e-B#t|"ZWy?ɝSݖ[@=Ոycݐ`kMG~nNH/k1x1d :/NAsB%wH @am2{A[) 5(`Kk#`\g7 f5Hg}sх4W-(pӄjwMhX uF)B5 gVس: mdNh'73h9La JUA`x 3}ռDpF*8X/ ۗupxTpl sc{0?l 6J9jXeCꃇ:ЎB2Dh+A"us.BE(⁔p l_ {Wᰴ(oV tX.muU}Gg"=X/_@ՔPÝ:N@0؃WܒY@Ro}mi2m9G?^Sf,?S[NP,g)_mR`Y1_D@אN<an4? ƀ/ n+w"q8Ii%]e{aW֟'''lf1?>` Y1/. ;c~"1j _ avMHZ@RN8pp:GA} cfh.!b@۹(VKm=puw@D۩B,1s,$a';!oڭ _ͥ:;OvaGN韜胸[gn?bs Pq& Fb_L2f2E$%Nd<zTQG][/1>0>< !~u&}sa^ ; Xape ^k$D+xG1f#B.cрx0931:]N<@h ys { c&,ψsˁwTmT=jqW2Fk7t  } zK*a&քif׍gOޱFvD-X2b!Au2v2;=Vc<g4@ǽ !eq^12 BW="5Dt~9tЃ&ԓꐉEA(KA.)RX EG͔kl>Tmmőu 3.Nzmțб Xqxb BZ䤀//(R^_U“*WyW2~)̠NؙxnStZl7/.,ݐ^ޞYv;xˬѬ"Xb RZ$!q$_ZύtwZ;rE_[#tJDDD\r\5OX]Zʭ(fFG'r8,kB RZ"IB (ػtЊ#kդߜ=i}wlݨY]:rLlɡ KV&%g&3sbZWs2f|Injf/8DURCў% ˾R\}g ZtTz8-=Y@ L4->09-)71?=_ߜw97)q^R缤bNH@8QoKߵ+.TYwMKKmnr_%ʂViN 'HIHIOI)NL>t1/6/4488"Xp׉Bq*e;%H~j''ӡjZG3L+ۻŸZZJgss3Kc2r#9iyԑ@:Q$-+}k)k;E}Qgv3v&MM. ^eJZI+&b 2ң#rrY9Cs|g 2GrkEQ 6"Vw6 =Mލ+wkmhrLQ}+֡$"8VPU&rRSJBJsJQKzKъsy#9",+ ³B_ˠ7Gzz.|Sc[U#S;J\szONcâ#uIlr۹Ěw~#9#oɈuBV% tᆲvQr[P nu%|Fob5ʌheFZ(Y)tәYYY޵_qkD {tr8zrEݿ+n=^.=#ڧ=7ؤW街a8OgYٔu=5|a`~l\A \C| ,bd &6ӃX -HҀBk5Qv;evDdB/ʙG)Fٰk9 DД#.<Âlۀ%85wcQuk0-5V$%; rA:u~oJAQ\ ŨM{{5 1,|)Xf>`c_@9t">HSZLs/BOyP;"b?YqWtK2+8 WZ}_2Z`^dU~28mRE[A=,'c8]j(@v<D xkk!`l 96`Uj50?fNMMn`?41MM㦌pߌ;frV[z!b'P x=\1 mZ6:[163Ӵ{iQIi 9q3XBAMq9F(* ^Fi|yL?9 _6֧g]f,]f,{O\'G\ZLG-Vׅ1%C_ylӝS P|H3 g9 34pSݮ ?m:esmۄc1a/Snlm}<$Y1%> ˀzt%jB`2<$,gO}a@Y/ĝRw -4l7#V[Nci94bδ '!f^zϳG+ec;})<>QzLx u{- do0,2+dM)F;';~v{A6bؿ ݟRҼsJ|k)|xwP{nn{= !{. PF H;K xB5e3fbw}^5פC{0$p/(ɷEM) _ANj_;ǸBL|z87ll%ͱZ I[^-4ŕ?դ'rt|1>tD/>^=NKO83*#r%(vZPzrub9;-#f,dOv}€&-m!{$!yk0X/|_Q/N&ruCd%f kd7S#O4ǩ~Qpf9 i1oKb>ҩ#+W~_E{ٮ7S}m.]L(.52hbC'"EЯEWџDW.]U0-s&^>TM̳ Jls1JO`x 7Eha5ő2fKLi^qh_lQ`l!sKs8ob?H|PXVizՏk )>r1|L TB>.VR~S).`7_ /͞bOfҢIBRyᚽJwRyr,:^(:+ÝʠzHa9ВTvAL.77,&s&r%rSS)鸅@:Q`o͢Udl4{|dFݭk-wU8+ql <3T6(gs3JyD~D>o"3L/DAR6@&o[O <]=[^n)[4{;r褢0ZnzThVj;-93*)(PˏKOL/B։B(oSAhf B*e7hmxD\ݱjgrOGq/7IpBSىQqiѩ|NĈ)/SƒI I@:QY/2¿JFעГMBw.\rMscGS6 X {@bfqH`JAD?Irj_URAǔFE'rX1AM W(I 4$!Z+ kBPiqCF׺Jt\Rnu⼹JyAiS.)$/ t-3(dV#Q%F>RObT4_#ƋYQtyctsعGמQuTVWЎL=?@d73COE0NƆQ" ^<8qn#qӱw|R\=>)A +KQ"ͽjoVz`5ciWM\]d t|9"g8b=žb[fOX-EϪ!t 7Pqto>ee6ߗ~\5^?e-㆟+:Ջ|s-*jR\՚P ,kXvWGXvW~w _$W=l@VBWj#eP)KgkL|jXc'##7> 0aaaUu_{>ep9A JzN#݅P-!P>@e |.Go Io̽ߒm1.oXqx,wr3{=>|4y7efg!/ۀ]{B(*Zr?oIEE&/{_,)vjX-°눯1n$a$nkk5 c5dk8ށ3xmYo|U];PeN"THAB)rbq,TfNB2E6;3mAEfc3Cӷe11fBgJw柇mrBPCE3넢gڻ4xNiMo ?[=w؃k{قx51 LCbiB:B2 ؆G)BCZ(6RA^ ˽@yh@oo 9+aN&m{uoP4yP$Ðs U兴^AB%x-BB˄ # `$.6t֘:C0+Yp m xo9Cގݐ*/9 jAxB P|A\ V cAV[n SP2%zT 4irU0X &+ra[N=Fnm&d`O lVu\ KQL XGkEtX ~Ѽynߺ=ƿt1dZgxRgxBwx\_y8{ťWYm0;m?ɊP{&X'hE޼Y '猚M~7ex->ͦ?NOϘ~575QC0p"}Rxh)+/@4v; n4d>jlZ}yo3n=`3kkkZm=Ro P/J[!r蘽nI$o>HQxt/@j^xˊi80!z8$l4]}`ކ7;>4qȆÂn1)5 |y<۳C,NqhȢ̈4ٰdvx{8<=Jd1ٿ E!LF2BY2BE2} z~b zPwHVr]펶6f{d1A.%I,BK̉S2y鴴FrT3fqFrc39B$- liaH\'4'XFKW+ƍn:M*㝭e6Jp:uy }I&%?- H$f$QRRBb+X<^3;w9{}f\ޯ0n̿ZQ\+ kt | z^/NɢSů4m3qZIݴ4.?'9;AH`b( ^ $*8+2$;b2U3Jԝ^ゎƏj3uf$B:uʻ=B(??#Z!"?J(-U_6+x/vYvX̹˛m'`ޟZQ5V%e=rU^eExO!܍PU/By}%?C !Y-D$W^ $qpth,UV` ,n8m׍ZY([U!w8C΃#v탦{̞9}  "!KA"7VQ{-f pDԗR0X&+4r*د< UJں=& x2; eAцP}R }-BďA bVYza*:_LQ ePT-C'un.˷@[X+AuO`] JX, p0] `>pؐG)FsZ@! lW</e@]aۜǮYÓܣv c6_5G-8ټUE!ڃf}jk1ye[<7ۭb`K%GA K(&2Hv[wMzG#qS50Abv:muٴ t轵K7mYO>mg _n`vHA^%+iV'D=X*ܢ5\2u^c^9p5xl؏i7zjs/&0潘ߖ=`u0[M|wug.];jq1P}=UȤϥs}Y؋w==~[!IvW`yY \70vC_G|[5ac!.{^~@U}Lbi=$FN0nCȳ^juӭk5 W1]?`: b@$ԭ) ܽcITt׽#'|f|v$$YQ(Q[|M-1MAU'Ɇ2;oǸV09ψl ٵPp(. J~5~<{U}*'*#(PdD LVx'm]x {HQz=Vۯ/9dVviTh}C0=͹Vxܣ"ޫrλrݷԷɷ0OA(PE BF Mn@Cٛѫ<9ywu^O7wW=#6s&VuᑘjV,"4_v/{h~9G$mM K uN8֡uC4z^=,<$~;OkMw鶎txfNbRlU ǔEDcK\ Yyނ*bDN ~ʘ"0I)!/Vk!z f@Ӓn؍"󌷴e?ܐS'WY01EQ\'UF I +Ka"'1( |>kg͓Y@^-}K]r$bIl=)/]p\'Gk=+ƥ V!جkzTg Gy@ewİFFDGDGqV[>Kbi8_ݬ+z\uE[B='rTeiR,s3±ѮI|^//uFp{l[*;' ^,P;ի՚]"UΖmh,5USQ,k s2Av),lb25.qs۴7< ,%h$I =FJDн |ޢ[F;C:DPQQQ;0uoww|Ž>guh86Ʌd;&٧׎:ʌyj u[u95vzhY^Z\\^Г]?Q?Vw4-FZjݫԴi+Hҟ4v2fn0'(84ņ$)3SSL'VvW3h[j8Pۗ^ٓ[UXQ!:3>m4)uKJB|j\˵)-ߓIҟ,Jc:`&&n^M՘'7 OوuUnm6Np-J/ I뫋L]3ݽ))`rD#^$Gt}O$Bx\ \NG&}3l.uەyXvL;7mҪ 0XnU<瘷&=s<7uuq`hMhH[d`L ×'8HQp8 Ls[-;u`n9.93ҵUg􊶄nɘNrJޘ7j* l}sHpu|YWޓߢ' C`^` ;IRi4^bX>W=>9 wE%%Lwܑ:[0۸w{oA^ qĨ=U~Bd1OŴGbcM"S,C.u9\qЄ]ގ/z;zmO'V;fM{C@q4xP}QZzQ5 o[ } :w.\.:mΏٝiosႃ8Z!r8lLm(Ɗ›b[*[I,bo9 E /p+L~8einoW:iշ3lh}w`lzvm'ǁ@* HXD5)WS%O}yx= w{!t??qXp8*l ,ń,i.QiUѤ+=1bs4e'̢ċY(^IrYI+#b* T3vIx](?N"ˈI1"mҿ{d~ ;%]g7_>.Y˽z#JK_/3Y1Tc&AW;NC}0#ŒMk0n8(pWu _7+|ߡIoGc )ջZ >?T(>#JsY1Qa"6Ex/NCsot񟶅R߭dZ4}1dگtTɤ{MJ+5ګkJ/+=3z#/~)?0"B,dB8*0/u܀Yr+nS|kգrHWS*/-0ߥ3*O̯<4|]/w6#XI3qc"~$Xq`_~Nx%ƵDs fg*OT؍=[vC۝l߷9~-ۇj7l_k\?:ݿlbZAWABH 2fi%M}pdz(t>PuVgl`Nv~r#[I $PI8G mIBck|}M[HW==op0dTވf6sv;Cφlri&+]6w >*I\ʗb ʋ2Y  }K6g =DOgFHKٛm+lG|zۙ6-Qӑ##ֻNϺ?6D5I8v,r6*Ke"d八NНH7I7ߜ\f)~*i]\d*51zE>3}wU>g 濈QH6~,*~$JxI޳ϡ%y$OH4dY)Fř.q@4eg6˖n%;ۼ5" klr*j˫ʚKzJB/+"iD~"_DB#q,߹ ܩ.7g;(8K ;ldo;clC~_%L)֬!Ŧ.۱Эһѯ3(b$4|SxVف̲KeO"2>g?!LR@b p8:fQ1lQcZ?d̽zVdM{Z{G^S{i]kuuscyc[ICWA]_ΊCi5SjE$W_L~\1<%WH uٕ>0{m"8B3]"rG/H'Ҹ+޲#;=%37- i0$q}X\s1 "b>֓?!-jU1`v^k)F'XtvhTЬZfX:k^ؗbۛSUrmHʹg} k#!3Y kG)`F^mnb2kYon\r݂&9#C*<}zB? ؿ}/W:`84^L7c3l&AަԺՈ~PմT& AYSiM֥YŮ͵,sw\7g|~cTrɗ>Bs1,@~Isep~mڞ+N\oyޥy_TJAcj |>.Ge+0ZN @e  Op,MqLEfH7n0ndÙY'6_쪿8~rʓ*.Y-My& GuU@ՙ7[0ƔHSESMT9] Cx3I`f1,L2XV~tld?+Og܋<˯  +t/4Ԉ8,E(RdEhQňURB&tvJg! :fPI)H=H E:QWcU&bDLX=1 !D/d͒%DVz_j]?U }WY+MeWmB_}VtJw_+|a K+JDx1H'* fLʈX۲KbE㸉Ao":Kh7 ~/EcDƄ' g?vHڂ[¯ ?W}.TOԈc5l1@' b Lހ8X{WbE,y~-n/հRA'vz"uD鎋Y/Fgk흢>)BS"< @DXhӉ,X1*17sVA|~؇~Id#޼T 7&-M4XhTZgĞΊ=1'#b ,klm ~H0 bDWN̤AN<Go;\\y9 vziW$ܦjSF'V+[J<x`F{$c~Lwį?bA/r͈31+1:q t >p}{#e9"yۡK 1v뤯mj[6d.ޒ=oLGS6?UNDm1b*A'4+N#24B1”U= /އK.O%vëHGn\{/ )w^xyYYNO9R>t]#N;:\LDBhA*+hڿ|Pgz|vy`k-L'_B!,/bY2*Y2l9ΦxL Zv4.FptêBtwn 1dMg61_bWIb9ĕJBx($$s8nr6l%,WteS"d$&(gkDn1h2i!tl}!V{/Xi3f$p0E%\̅Y\xσEKpD Ki'8-ٗ#:*=-VikJtb"qFkcM'ǣz"GmF"6 ٯ ?0~͡?Co'A#ƎxPĊT!S*#ƬK =EJoΎRڐ.-Cg"%`uRhbp|ժ.!u=1N]G;/~ѹ=S[ F!qt\/r%U x"`ˮJmn"ESJqRuG2r WVZ4Xw'Lp\0ܖ0ȭ9{cc \b$B6\B 0_/G[<[cɳExWj8Dq0F}(/Yw 'Ӱ7+ܲ#cM[ZCKjscjuY} yf,"H>7X ps+Űu}͘cMpx\Wmj{UvsEACyr:•E< {;훝w7;wNO<U&p88 nv2K]*˺|eU뢴kkM*,*Jmk \sK쾼Η;/ n}Q``|00ECFAnT6le.] XC`vش Zw5@>dAQMZQ昣G\yB Z=$>%2_0_l;߭j=?n9G|j ڋF&g@^P<dN3!") 5#=^ss9+x>M|q ƥ/I] mtᩔO~-gغX:u@I vkl. JKqiNseplۏv8.;Y<&wJ 6X{oZPQAԸ]hk []@~(9d!k=d#a8=uSSs3;37/Xt_ijibxUΡK0⛭ oq˿-l{+=dbA^ۀVX{ |P ԣ|2j}v|+~ b}a,EG3U"?7 *,bk怾@Q$y^owg~rBRhq9(e(M}1(q _ d:'):b f2opYgK@U`u0|h L'!K E!F!Bd HOKtIL(Ć n PA2 Tz jt"B'JtI' eL=XJ0+Qg#lD԰nb)C075_%8Hn,~9>Hx+~cbo؟a&8|*NȨ҉*Љ25uc!ZD=R*dXMB;8?ɭ(4{Yw{z#{ 29ȼx,/2g1"L'r4%K'Ftb fLą֋dU3z9G\ZީvqU~2ZeF۸_(~|Y'J׹*=⺯J(%w?%єCiTm:5e",,Y2JxoVn5+F:+yk>}5DkVGZxj}y5ZojỮW4eM"ODMFhBFhYN l8 bc ӡ=6cz5呼}ze ,];^'~̭UkԼˠa27ptPnYN眞+:}V[y#QYXQ;. ex+1цˑvý8O,9+x4 Mt/W2|dzQ9cls_P~]uFiLň-pr}'V .'jS%X1s:(2RxX؞L];gj7)oPݼ|@mwFߍ|ZsE{:}~ lɎ x̉{_2KWL3cOqܟ˿;.TdGLĶT9Ê6VlS[ܪ6Gk"pDgMz#  3a8O !̂xteBr)9FL28<lI(;.:_e"T}T,|]Td9Jjn]:kз_sZ~vp6`G?0=LL-@6 od }V"7>i`dйXq(<"O~KU&7S@9/`v й(?d^߁e&LXJ8GȀAA!1@ ]!j4LFiDFF iDƆN$D,ADcD(A2~/dh`hc|a|]2FdyF%3|󞢿Bs)S'UIy*%5QѧeK:QpYb-sY>eL_E>0>t2>3>0 abx#4x-tJ$e3{K ~d<@0_H(Ј4(JS2h҈h8щ/R87$ϲ9LeJ0nbz#T/+UL/%W3\\rH`z,]];oKd)AnHE1*є}*1Ҥcc1d| aV-J!KJuϔZ*u1?V`~8PqF ۙ)cp% w+`OK"'(N%jBTbBe(RJi-M]o^D1?KayPv =&ֻZ+Yhb9zCs 5=W5^ѸzI.yg5?qsJ.h"TO!b'A! &WVL-B%6diRzݤqZ/ureqpZ9q58u,ׂ-x|7%pX,=OhS //q'K7=#K]'WMk,mS.p.:g]}ƪe)nޓ|',V/9n16#/2&^»~̙93쟈>Xsx/ŷz,Sn{Qy9.y0sc;Ϲs9S#5rhw+K`gr]"snM;\;ͺosq yfyMN68ߗ^Ff7I'"`qcgV 0^\  ,Dю; ƻ+0N`ve[}*7Iln-=9$sZ k*0JqҰ;QZALã*nFq5bx#X;]ў|3QK7& o X!(_b}`ڀj Fq(+ N+U9:sKZֽq/€1*.&2p*i cm.ɚe[8?1abE&#RׄgKʌV PXܪ4ԣ8A;`N3fGuZm5f"܋&RiTOƁLiԦnK7gNuJL MIʓ,Q荨VoR T_:N%dNs1Ɛ !tC>ԇ֩!Dk},!IBO,/# CL=0Un`êF16R; ZW8z/- ,+OQ.V(-H-I*nO(0-\g]4YT=w&Q?ɿ܏.eK5`h[*V%JKقɑC_.TsN 9/f6ǹDn,^띥;2޹^paW f_m*,]U5s3P?;@> < \ty1ݗhAM2JoKP?[}O Xހ~cp ΂Evlomz BwtRBQhǞ?CX _K<|)/5u| _ǂ=Pq{;gCo@;>?'|ED9$2 h%6 q" F b9u .QDԶZGHDQY"HD0($_$eg ddꄏ2iA"6N Gyy^q<oy<O:=%^7A7DSkA4$`Dԛ&%_5$%H>Iޫ̖S'PCyViFiZ]]q R/LOdH-(}%Q#QD42D3SADK[A.%qA.)?JHVH~ם+yS'yHxLxJM{LkTkDX@w5rGpK Qz]Whl*fhi,} b'A=V򏕋/ _$/fJJIΖ<1'ylPdqZ&N!Y-3?L?^0 Zh b}AfC >$yo>A'1GRzJYHZUHXVKoYInZ.\rɵ$W{n^yPz 鹞OeO[!w KQ񸥨# @Iq}wه# r'3(Brs`L2WlKe.V\`S/{f96mrm:N?W8tGTtQe;]}OknI6 #'d]O2KnL ܤdO8xx|ҡq;Suߘ9j{GתH};FinUsۨZ[imuWkK 魷H,E+8Y. CmnL1kθ &KN;0%HqsD]3wL6Ds s7;lr\a^];6Wnj{ÕCn{Ji戏pQfT~JigK&exEG h{Kݖ-v[u6#^i:?׺~>Uqp-·P!j7gg%^fc$u*Wj.Ka'h FJ^L[ܽsu5zdYزU{C/fUsu^e>zV?7\s1p,%x9&1њʯuV^(2@{aD^]x$㚐 |AUW* л$`os}- xӧ0SG\?\S p8d)?.Ւ)$+G-I?U}A`ёs+#*"rKzUZ* Yֻ d}߼r ?'Mf}~n* 1p<î ؒڬAs ]j$UƇT&͈V]dQUa9:'bi߬~;mO٤ݵI ?-~iab[p.,؞ `m-4eWIZ9+_<9DFRQQbYABF|rؚ1F$GM:iu61wĨ'F~Gd% v–|X TXoʢ>‚25c'VdkeꔤEƛ夤uLγHO*JI/!~M\q6&oXÕ8C(MEZ+Y\dH}q/ VȟRQS=KnVQVfizFJԪޱ) EL2 "؀[“^ن'}H~&y4 h/%d,]W֓9%3Fʕ8*N.5Lˋ6MM2O]dU;"sA۠#0=mPG4%{\kg²rh *3;lҊa3);fyh6H,4+N]=2:(o`ފy?ɽn7oG7T(尡VΆEa~TQcf)3s~#Y5I9uzRv.1ᆑ3L̃z[͘{ƲJ6(9߽Z=>(r"ͅ=Q 򹰠A|k ȯ"n$vl|GńySTbyjD \c8'ԯ*ܻ칖S+ZV2@YW8W<<}rΥá"1 6ZX\5 l!6d7j) 줱c'+7LU iј0Hۿ>RgALu]]jtw]d1itwұ7Kǹ8 {ˡc.[+f/ +˜^D6VKW8pQ[>M{y0ͩMq:.M]N\ZiⰤlܒ֮c1EG5mTmT_9qY BM-HXQRBmk*Lk$vZ)kZ&h8i]S;j͂.#֬6zv ]ph7bږ@s3,hUP m{"ak .p2NI2aC츎0#;w<_}Ak |VcϏ5l7ӲMGCX[anC&H耐v5dޞgè}vˈN ) %?UfB_@ )XSr7mZ - 6Bf I!l'}0 ; +a{ 6'dL>5SXt g2g ӳG3o$Ƨ>m%X?|!w뜀%9atëѿ֗.pA?7cм*T,G^Bsnq3E!uD_`Q{%0 ]nm)UPyc3[!dOG"}:(xox~?;-;d/_8gas_Û}Sy#Ex!o›?,xW _x]P2AQ= g`tz]۠w# / 1O | )m@\N ʛ B(Gd2"^ 72B>PGfޱ?Y[U vIq< /y;#Nr7AT1DSDMKD D e=%L rQTZ^+f~gl x~q\ 'wDn@0DMD]cDC DþzCUÕUy \!dx);25&]3bHXXCڹV6=n\9?D]AF45@f ⃡tw^hVO5syQ# Z-UVYMn(Wc\Ue\TsZ߄3ZpFKK4F4QC쩋hmۂ/r;|*Oxh=$grۨF0a pp1 Wpɰ?sp p"qp7aQG bOe~IQm+onXp2˖\ep޲\8kY%'\(\*\%9n.9fMr!g%,H[k^vW]V.O.Oq:x΀uN N L.9> Wzt@Ȁ_̑94VmlmOv)67ֲQv!e Q!MqA5A㴫St++ +K晖.Zj^賭{ϱy>7[7\p΅;hhde9c8vta\mŚi*sgjVF딇$gLkh{vG-2[dGL-#ZED]zfedמſ-lw&tX27;slҒrΊy*iZi) Fq1I3ͣOX3,~UH~KZǽ 3$Vtk:vXK`A>-Ф+})*)#7I!+wrzzJtĬp8T<2󐴚AK{ Hgr?;K/=NDˆjDcK)(,)%QE)pj|AFlAvT~^x^AhnIP n~ً{dc9-崌ǖ2+]t){۝g@k),-R]e''Y#3%;+Ėy(GEkΈ *IPe[\l]Tճ{Ak],\Y5s\8 ۋaLh ePP%!{6sIGbPIܜ12Qs&ET)V P7+^׻"C߳pJf'6LIMGI%M*;H:ʡ fUCA d·Zꌈ"n u#%!u2kj=}){U9&Uۥ&_inĹ Wn2niUL~k:oRXj΃ZȩF^$CbBwc~,1ɺ/w[4]iʢHɍIjs47im;jas td {?oÖٰ/0k!6BZAעW!+-q_iḬ'8tL^.O֡%T~\K %Ûm^1y41h́Mh \M_;f-0 W@b N`zM&ދa8c7gg7x #6Jm!Evp{*%7(m?wm>^+nGگ6σEb-_ )k!j=l?&ðZ nV aˠc;9~;3Nޙ%X,ܹPcWnnHw1lm_;/U+`j %!s#n- &0h9(t?CzdfG&arM@X>]EX3wu2Z^u#ZGZ Mkv 9[ ~;0i/@r@!*{|JPEw.#{) b$Zr WÕA&v@. a!y^'?A HI*Ѓ]5 w=W?'xX>xt3Tm]B_`QcyL.Pdo=(C-xdO, < /xom]l?vw}z0$ ?/@`+h;=o y K%]ޚŸ~(=ps|ɇU-$鉈 "'"A|!I=9I1ox<~W,%y*^tyr!Oy[7}N`!"ƈBD"2&H-N/)\~g4&cMp@$ * #*Z#BFg>ß8^3ryB1#x<P}se -q\+<2s\3;:j:zƈ62w y- t Q<x@&(3,nQMjAUVr\f NrkלI7NHN*YDӮmd.Cx='.G8bk8dƻo|}FWm򘝦o$L A) s_^ܵz\9sS8eÉ^!Ñ^+9Ы*}V:abaUjjdEfVie@b_8վƜɁ9:hs`P{  ;fI,lX*2R1FMlV}uelɶޓ[mJۏ -y< wF¯#PYpK^첟v{oa 摑M#Gɴȑ]?Pv2êZʯX~հU -v*.;Rʋ>(/N$vpo,\'qjp]l0& %m2eWK[5.]elBbc*tL+TnWmKujoՍ~^;_;} OFpNN#.pIta\ S\$d.w otRIJ&(7L,UP`BZc|6siqUlǿ*hU: T8}`4.K>힖* &ww%~rSCE).pMPsISZ3X}Ysiv^]FiLúNWJpz; ' {3.xñ80vv_Zg2b W^^ )Q㙬:#Sҽ@½\|jNn+m/r;_z٠~乊p05P]i Ǣ ;~8imlM?~J|Tf$i*SU[0K޴f\Mٞ60AD'`쌂M.VfLc5 †BGKC&vV,>]40\80V( E?[;ϿX7ǯKoArt Ʃ>S|.$<2N(QhS }15c`u,T`Q ,59#%"e]fMS(W* Q V N *M^80981`IB^sqMߚ2uw*`w(B"MҊH.CBbGI'DȅMS. P , S/UOț-%9)瘱Smcߍ2?9eNL(5Ű/2H.W&~!1DU b2s$hLLw9r_`ieѪn9ZSfL.7dcfE  _8|4pp*̇\ePU%3!fCY"u FPu__(zīEƳKv@y9U *fgM=Cc|\M:gm5밮}M/u?ڗ}?̀Yt̟3+! RB|Uog-pKd~tr!r bե++RY;Guxb5v4O5/41vYr,sCiT&m̘d̈́8.e̙1̬zHi%[`*ZQkƜ᭽k) jb@k0qB,I2ukԪuen5d,V&c/+kC Z CF5C*ju0n۟.}6w^XoUp,;c1tü# -lіnنso~M_$Z˖PN_~gv[f{d1ګ^C@o__t1hwFj"P=24 =p /WAZHћ!`+m;an =!= +!sB SVprSY/>NwpV6A;m7v/t$g\PZp.[pm8\7Vʁsrnۗ;-vA^gs3v.ku&pK]=oxϧ(xUjW: ;!i/_`Q$>]σ%P -}!"/cs|^w1FDD?!T>{"yG[ x ^3ߙ+󒅼` Yo:w9qG5=ru&cD)LJ;q""~g)syBiMkRۄGj_ԫ8^F`z{Է[;ϲ][^ҡY[$hs /Ly ]3.HNO☉M8h84ݦ2N vei=[Maͦ?t/MOnzufYkI4/ VpsG~`qva7;f:l&B6Zz6  m-Bu.aU^%$˭IY6Y2 >.gmš3Ж2xq?CY7(Zh(.+T,Y9pe`y`teed.dE4 |"pr?-(-^d0ܴ cX8b5܄-#ގiwajd22\bdddiӈL2KϐY4RqxaKꇭEv!y.) {P=9>)&vzv}`89:`ZArE$; K|%K6*`l\"cg׌0wL1+fYrY/P|;=8<`+tLhwfs7mX6e8KFgi)@:r̼IѲs'%͙!_51OrbRń*U&P-uܠVWz}B8j= ל'>yO5SXnR>4}P>YR3]Z+S$[!W'?%ElJҌ)%γTk ;uڭtF3fk,5&np@hV/hRb! Vy۞9$^Ҋid=dK=CK<< 3 TsT˙:O#mf[VN4S:wuR\Nq*j) p9J?X/B.X07é/9KgyD*z+e{dz婦{M2mvgNϓu=^{|ԉ!j{ڷ BathRMu9(ʌ1Bq$It7@/@̀0 X4$ s}ub}VFlӋ9}K/n(o:QޢNs Np mQ"B]Ti0+ܔޔ0^ sdNfxʦɥ($G+%%eN/ֈP'"`^X.ǺR/n7P?Q'OԹ ǃaol5 #&*T(28ڒD2K#)2Ir A qJ1a *ajᡕڡ! t[wt >tC?0E .Nu/0%Cm ̎8⺐׃82H+$M&ĺz*Dń+EDǩEDhEVhFG4o~X;O؋.>a|B>8;a],O$ND(J!7IdsҒɣ $i򡉡 1SU4ʵcx.٤K_G?zU#JuO8ؚ kRaI*OY)P iAJ HL"3K32ri iQJ*)9)5nIM:.Iu$sN7%7)N3%Δo:#aOlʀ hȀL(̈́,Hφer ε "φ<;BA$nR\oY^9 ST]Jԝ35'g.њѮ=!『cǴt&=!oRi>r6{*̅|H,"Y‹u) ƯdijS^/V&RT4HűJm|"4wIst394GgMst7)%â|.-U!Po޳z9YvL5Y)$N>I2*L;3_qTyekUQ+j7㩪];5jv_슿M؊bXP %P42 Bfo5xΕíF)5]qfR@&֌qx93CS U!Y(3lnй3T/PTZa@.E9l(SѶmW%ʯJ[ 2(+ H ?<`BphPfl>c؇8a mtF/731Vm̐o!0_ڻEzvgdX-C֪e9/rʡ+ }.·K`| _!0Y hMs5oH4;bJ_,[ْL5ϡks`!4LV<L}7}7}UÒj e5S !|5 p\ #`NzU|9f֘ĸ}Fކht6d mhG0*PY uQmնXYuP  u D/Xmޛ[l Be1;,PvN7;vx7,]5t)d^i3A` >?TZp_px< Gh-pt {?2:>I$@ wwwww#B"$@$nŝ"}((RZB)r>~k>=֬5籎ӏ#Z:j-@ {L!;COI pA.Kpe\Wfpn4YZf0|} nm }Q;SO˜Ӡq/+5grKQoݑpO  < }mg{xv  08/airF]W@|Y߫qtp?Cu^ oNxެ439xox~%_%żYsF)]=<9w|>?s|"'}F- y=KB3Tjh+j]q>&?rW\o#' gg&4wqyJI!i< -ܥo6 |M hkfb7W9.po\WyGŌO#z<ŔG8obM_MrN_QUBi+γ 9YNr<8/9kc|rR51:À;X5ks8.29Og) f $-(8~q\g?{y^>E rux*7E50hq9\L,ȓ@N#9)8,9".᰸CZ/^I-+>NuvHM%[߰E[lQ#W`x9DQ \V\hɉAajD_#}ifF!5J٥QNzvh,gjlb^6idu?fݐ_Y;o|2 M;Zpc\%=ccpp14m٣N?;5خ6$hY3MEl,GnfivVN^hg5:?m/b\h)pw&|5.΂o]ۂ-ڎlņtk^;tigҩjViWѡ@Ja:U{\LЬ@8aQGQ\T-͆I#82Rdlכ&=2cl锹Z*Y0Hd񬐥 zB^L\ԬW+jkum]TݓT,{- #T̑K]b%BV 6M` VӾЂFybOQd-4& EuyZq&I*i&r eJ *.2xbb}B\ ny{8}X@:cif\Z,Mh…BEPm!Zb'4OWeI͊ef %f ŦmE MM*~krɟ9&rLJ9&r +8a+lrn;XcLZd?[QmCD6QE6btiMBubuR ln,=2NK/Y4?YWIYU5N'yV/XkY2!4LeK\PbFP*;y<8icBcbCRCJ~T{ՒO%`L-w v~ v~X78~:Z<=R1JOm=RaLP${rYnLhikBkRkr˒~ .T]bw8|NԢީE;U䪷hQw4S)M!>d ޮtoqW$+R䕠YY/ڣI-czǎ}0Wanjanrp PBIp  Av2LI REI_4/N1/M)/_%wjoZ>y}}@^[=K%W'ao8l UK2JB( BNx2C:$X !Bl(:O*Q JQ U ,W Wu>_ :>~Q7 H莂Hh0( 9ɈKJ$F!>ҐH #7Qx84"XVZ3dC p~2=AwQ?1c.GAQ4@zɱLlLgJX" Jc"|c=sUsZSW8F<[Na՝>9VCs<,xMDHLT&6iQI O!4y. L?QK$¥ J E* ժ+7owMcu_mbުDTv"' V&A}2,NdHO4N1qf||3 4+Nt2|E.!XCz]zuZe~=f)R.&?R3KU,魪YUGbaW*M4NtN,ʆ\S7o$^Zx-.8[${ vA"(e^*YU 2Q1K ナAɰ5VeBC&TdAA@t>o1x,Rĥd0N8Nît6XcYjEf~IihaIذ$[_R&Qa.E=s+)z8ҜPAiO&@k.BICR!/2p*^ŒUO¤ZjFFV[_ȂjOU3:V[!^H4cRnj]i_JN+/V^ TPX +k%,hȼȚӤl^ȌfktvS8_4%3j&6  O ? K߈4ދ4ދ6-R.J:pie`d+A]i탘1Zhu2c.:a\c:Ȏ,w,fhrwlbP1fʟXX h (^ M+.Z О 陀F6za!lPA !(oHBiRD=н/_ +kJj!!a ݠ60x;!AS a0إ ]s`B赅^/荀]鰫v-]a1yv>as5@e#/ ,6V&=0h/(~TC88<φ#Fph8\V^8v݄c}ᬆuܶ.03@k?<Q8p8)S hm/\p{)z^Cf{va1qN?<r \u59 w=}x` Q"<^:x') !0:3 aY񗛟}o|BΨa0-Ƌ?7bd^E<X&Vaǹewy^sAO"G9Db`+n D''yܧ{,[ڸC߰yskε="r$7y<ǜg8wp$7r"[TrZnWrU\l"9iq< p7s'_Rq9F5Gi09j}좏#"K//v򞝼k~p\e0,֜•ra8Hf?Q^*C-4vvm`+y6q~7#+ex\YT8*5吂==Sgb1RJdRە٦TV26+-aRVңJXt.t*aʏONG?9³p,ԄKj86POKv ubP/ dp6 ghCY?4CZuaaX1<2GGI44B΋pܚu48(7n$;5uM`˺ tMsB'DjBi N(ejMly*'nabϰtmj'=fTOz/,$L &pe'~P{gAm_ fDOAt}VXЮJwZuh aN: 4ҠRbt*iZ%:=BB田XPPJTNT#EpM6ɠg:zcMcLF̘f 2ge^Q-a,*Ya\( V":QlHPvC/{*]8OO.ӓU8i}V6څ@i1L,PkdN=UFnT02J EBaаDT`X-3ltI vH I3 f<&M+IחK;p .{h]a+$4 |<5:Tc e֔;SlI?fBYk$1e3M$M45m ɦGL)&z y@+,q2WE]6ld%u!)$:F"qG$K"]r. a.u!mJ:]R pN%r_J?*]tcް =SB Ƒ)^sH4 ӌXO[=]"LTg˄:72.1u+cdm3k{V{!5ZÖbX;UcM4AyCJ!D- ȶL`^=h)@E1ˇ0zXF.̈ oVSڣP[Q]^(-DeePX/PjzRkZCf ĕCH%xՀR0k-0;9(uiإk.3.Gh̄ΊOol5a-XV~ AbHZke` ajnPM"6ͣalх-a9luam--KaK'l /滰5K [ج0nqa6P]@/[ {T` ;&>7W8 R@X6#p2|Nb+W'w&v¸0d/p8 :'548#spG,.tp(\.Q; z-o` 0 h/S} E.+A(9n]sE01/ly;"yAIGyF?P,)`1L K^Oq>\#+Dq.I%-cts9g}Mrg=Fq\GLq ~"/8 #dq|QAsH+CleismZNh94t83 ΂^]ت `:k'eiM:ɘI4Orq'Y:)IQLJzRK&RUBV5Z(DkPu"N~I(H{\8v/-[fjm%ڴ|M:3էNnj;RMN :R",u(ҭ@|Un!G{I} d2t: p{67ưhzbhTOtd2*d )YQ*sd̝"/` dȕ-'KLY.kdTQ(Yv_${!J{#J Jԓn,Sf6Y XiBSe0r)΢PBC3 l5p&,2 H7% T\!٠TH2%lG,- ֗q+imYA9Ԙ@2(2H.6]HbKi0Q$& qB"Qi(ʴUi-7+ 79' 3Vj$$8m`5Pa%VR kI4ҭje@V[gEU VDY%VBU(j8ĪEl^dGhyF`yW`\`$$ wMΰ * ra?)$$n>vDYiH;v~هb'ۧ Dbe_RRoRo;RoRo?66g` A4C+9Ad;C*#wHQ2" s2'Ɏ`gW}p9FsN:狽+^M..)7o9!usx'us(=Z={"WutwHrW&}QO#}6n3^x%xz$<C|f3c|qw\}#D'[S&iyzx`3RwR#ް:*|!b!"@ 8@N;P@ZdsA~8 Am`:DlTbJb]jpBjKjLjJjNjAz6@  0†k4gC)v6؆`Ux᱂yx`^,2 KBJ CI CoJ C~-1 낡%Bq(dAbDD@P$D{A8Č.v26X2v!:bIl c1M b 1բ1+b6FˢoeQߋF.dnɎPX 8#!-b!(5&Y%O4e)1J0 [SܘǼd)Icvr03UQtXH7H7wn"ݸM2 jaQ d@R,Dă_CXfIYl-f"˖1'ۈٖvdF!LώG;;/3%kz<Ȥ̫LxVoV[A+."  -b!$<)r8~(N8OeZL(b&۠U&GYF52h-# 12# 32WFed;:`i$Cv $BD:gk.I/e0BJ5WCRSS5QU Ye*{Uy1* $VҿE*ӯeQ-{KKTCa:g@lg8,2ЯYUE b48PojL5hR3 Hc5fAC4BfXz ބP~ci6fCN$Ax!.r5f[AiJuhm6gA[}C= ڊ>XqV܇g3UPTiE]m [Za| AX Uu`pX S{6Ba Г =нA}?O)+2H4涃jփzH7-V`"lWCaX5zgn#c{`O)=KaZ{[.=z[+|5_ :=0a jA }~Apdg~O:© 8Kr8 3gE `3za^Pc!'?39 \PKCx kO?&T6CCd'V0}0 8 >/'ݐ`< ?L 'W9^jx^#|U<17p|yA(?Ï$ ' zsue+w76k;K2?%=?SyL)'o.EܡT5ܢ:kF+2WC.+xk-1k]|M_MN**y\Kq*.s,,a=Iq .xQp?OK 1o6ױ*\Ÿ qhljyGh0lf}q=b7O^ޣ5,c8'!CpD>#,b饖]4Vzq6q | cie.0|%]6RB)`%lXJֱ.ì"ܣim;G&]zYي=qc#>D7'$E䰚"VjitZ8@3h
    ,DɜM _o:9z2 3']ώT=H $Q/xxd U%k&REl.RBe?zPP9C3tAC@KTg$}w$Vߝh}?Cԏ%B?0|B b( v'S&k-a[AB1Ci#I6Dq2b26'؎pcB 1"8 dMr7)L_Ղ61 SE^ ߊ~0Vilm!R,THJx,a>0dnMYke"ޖxY KwVQuSo""W#VVCT9@=@5@6D،!f A63>xeㆧaf"ٶNpm9n99|%y"rM`V`At6:@,uΟK=CD9 s@H'8oG=< pw4WG\}pv )G ;֩MdYdxXdxMdDdm/Qt;C+ԸAB$@+B*nr4f'7ݬqps ; lcvOʽPt,V6L]L]L]~9%2s u.7hv*(,OHvh/Rk0cq򞂃 boK}'s(|R0}ޭA#"CDDa'4xA7@yC/Kp }Hl'b89`hiAn, (($rYX!lv s ˂ E4/\^~P^`𡘅kb>31 A1̏pf^7s#BыgND6˙̌t. ݐ_7ŒB'* 3 pp( c7q78=0;Μq̈@7.q1heE\)Sؽh\@+;&Gdr&GACBN($AT8F{48Ăe<'dҏCMNSg0-mS2%͚i.LJcbZ$RL-blRƤaTJ/#S12>^0:5cޱ2 j"(2>{@a Ή` & fe sՙ; qyyʳgD'B|V309;P9Z]Գ~f@ xGs4,H8LdKLρy]aTJ0tK3tKgӿR TKQ)G4L$ ,@u(zP P aYA)X*@ U+P3IH5jFjpW 5PS PK"T݇*R /RS!*>y@6d0&VèZX * n@*4Ql",-2h1hhhɆ*X˶CIh@O,ʄLφ<*R0y]e}q ʒ!{CXIdɂ$,H$@#콇!C=ꬣں:Z;Զ ~{\sߝa~z_Kô9Jc8-8َrCn̩Nr&3|άN zSrVbfr3M~1(zZ܄\Wq['n?ݙ]=5D\='9><˓Գ<;K#nbNwx61'%F\k^K}_19&>;}2EȺ <}eٜKn%ns~׎zYp@?TZ7؅~o}̟TL4,~oeSeOl]>tzߩ,}w[>o_]Co"}+rA߫>R~o-U޵6{vo W+xc^}{şץ?K^Ohe6ٛ{CXedm~iSr'=q<+]p#k}`od^4<3tƷi㴋or@>l~I3 }\!0}2+=Jܥܮ9unU nMָftʵwns܃sėmt=Gt.n!9)nqnT TA0q\g;lC9n}zov.?'_4xӜ;uN7FaNw4':QtHkpl-R{;Qdxfo3}k>XX/m=8ۅrc-iPD[ez i]fWJ;[OuM뙶k[EYis6eCֵ6nUm~mUYqwVъN_m0gq2zs˕w@vaW;&5Ӷyt-NtYuݖYmݮ!K=wʢnoZs ՂE a5C8>Cގmdsp[?VϷ-_eikQX`n]lͺV2(QeXkQ8 J-4/h:sR]f9CP31Ӄ_7-3ӂ3-gGro47r4}qcKF.U!-kIHEƙ>4ӜOe| LL,auJw*N<(VV+ (L(%qs*G3=ͣYT%3/W>29ZyRIʒs&*I8JQJ Sz#Ro)26Gc}ܘ,vd!Y,`~:3Ԍv&gP1a#0=˸GO7zZnv9e>+kF,3#Yjc4;,m kǰ4bF6LncbvWe)S#/;䌕S,'wr]itVJϽIZRs^oe,-?d.{Dz9U,cXfz,yTIa^yC!7/Jv~tF珗QP!`Ԃz)%lTpШ%/1EyJVf D j ]qqs>DZ}wWM^vd"+X]INz2P0 ~uBܫ4~AC )>^4}]_W}su_kv]i:yJ94:]ڟ̦),j&Mx:cf^G Y-nz.A-˒HqIKiR%YD%\|+E\+>b៴XSY;M 3)#s.@boVaMW͚>ZWqŚ䲦5SY35kYէYu?^b凬#+bLd,f̢. u1K ]Ajzoll@5l-`ke#ٺr-wY6˦/'khP]OU%h6m+bv5gwvwbO7}K`_V ojcξ 컖1O?T,fr2W FtM۽4ߏ8Wp G;r;XG69)ȉZN.N8",n)SVP$m%b'{跟..񗓸pgZrc;vȹܖm>sFn?88^bZ&n$oϰC.'i}\b/˘][߫1HI\΅\y.<Ņ_ĤM2$N,5/w5K>1 MLqȗ4_qhGoGrIoTT_zk>'&{Zu»z_{>m_].cW3ȷ|%F\OdwwR'ry^*YY[=msGO{؛..MgcW{Edx^{ZT{ y.heʃ6x68ﴻNï|;s.wYSkZxQg)<.ʣ="C <}*B?{l0nڭ6gtθi8yrҏN_']]緛}WŹK;8*uJgUQ3V[u=:ꈛr޵rЛ~߿l:Np+ݩu gtFS]o W שrD2A~nrwc{6[[}o|WxK~т;7^oi]]/q$vڧ^v ;v[fun6:iۭ^j?ut.օ39ٞ㭸N;p #.vȴXیU*m2oVo]4[mu-V6gE5;gi-i߷-jn\8ӏc7Cs{[_mg> 6mmkgM"Md+MlK5X~E7[~폛shvo~\́` sak6uf}tnUH+'Z=9t/{t6,=c=7ˬיV3z>˦дߚGzCkF4~¶lʺ! hnucI@Y?I67`9L63ƌXbڀuءjSlM? \XcǾHE65a`^ea`w8AfezPiAŪUM59ΤknC& I$}%_+ AIпFfW,bYHda(BZ3}hzH!1BFaRHB!L ,tJV)ۦ(Za7vqa+Я~ G6~~:D%<ű̏fn$͈`jDOUL""Ĉx"RFd)WYb|$Q3 j-}Ƙ_ȍʉJnr#rW 'ؗĖdV'$̉gV⨊ʤnc+ R(6Za(b3ǎWdl\1ϕLv&Y e&2:^ɈOFW2.#'%p,ݩlLcE Ә¬QLQjlTgţ(5XFEM;*UΨId%M<9ғJK(5e$#9YIIINQ<'$q$`h捦6LNeb%iW(L ?i ntZdY󥦗IɨQ')cQ$f쑐qť?#.]qiw?)Gښ,MMSF31Le16n2 *%+Zr(IJ)3Y\,9 br։-*ȜDd?-"Y_9:)eV.չPKrǐ97Hbpy槉?^d~F,FXNDžiDSm/1r"ݹ˒BQ>°HCg,3Ԡj+PBmwmL|\ o[~eկ/jd@)-&H.'ILЪ{R`PuacNѷ:G"NsjKuޢk!]nѹQu]'Ӟ"֗RQ^ 䖓:)DV2lϬzg kVKmεu-С\6h3kֳk5F-g>ŌWXoeؘQrJ+ȟ*FM#Й0t j fAV b\/a~5뙿w=y9_2;+Y21 6m)"g)3%lA,gzi+͗]Ͳ, `yY 4͖6 ˶(K`,yş[XPjLd:cg42'%XFǕ^5W-:~("0:o(aT/`z`ͬ{S|mi sk^CLՑYOB"3t9豆i[[=ۻ7 dpvF3y`g;Vs';NyR[#DdZlfok{%q3@H4G9Rȑj,&~CoqSLτ򖑶 ̀tI=_h9Wp 7tT ᜍmCϖqigoC7kb*QJNAuM{G2&rٖ{ro<0&̃Gyv|^T n%i#30=<ޒ';l_IPȋI^]"Gz=}ní4}ץ#sxM/lف>LR>5|n*? 0F_+G}aLO5RYC|`yQ8-w%ثW.ziwZξWR?H\Vߨ:oM ~meYz./;4Ϲ3r(?yşץ7`|@]2+* fx^_9 SV{Q{=∇1yݽ>wwuiKƻZyCWR<#ۓy\ *=Cj0ݧ>{lttNͭn[f:\tSeSu^.!>iuqRnW65Ωuz7kpr7Y-NGt;iyQt_G\uSͯԧ _kuqn7̭""Yn4N)u ׫rRjS:!\5|`d>jBO6aϻqNsgwFO78&Q6!*u@Sc:ͷ;q-kc&Eool㿿 t9<:9n8{%Nc]vU-fdZou6ZcՎXse`X^GpG;Nv\ۆWO{tS Umj,덵xkY*S0r,,v,t\{rSNlWY GYyEWYveWYreEWNb-jo1ǼmƜյVmf:տ?Q'fR@ʀ|%&T*Pt@ d} ^o |JB/w x{4Uc~sGP7ALlg `RP&* LR8p4UAK `=r3NO ~SV*;n HvD>e,fN$© zGV1 *>D4nxFd;2!UCd.]2BKCZRCޔ򹴐HO7smbY̍cV,ӣr$F^dƏi\yC #;Mʢ4,2sH%q cJx^'yhXPCG ʏjp~AEL6V%l7>g{H_=}Y1?318&41CZ-`d!#_!n38Ѐ+Iҷ$KqzTQ2SElеd.7\NE4] kvz 2#yQGv>)Q̈R'0g=*V9Rx+usu+kWUkحu ZBҦo䱬9MP81"K@H9A LLk.:LݴNʹh%k9-Ǖӊ46Eis0wQ U2 ɺB`S(+R'SAd0^5tUZ=`f3;SWNLSCԞc53?c7VP_2*(*cD*ȩ aLzyWs,h.,M@IèFPLC5 YXp fy_YTNmULĀ42 ezͣB,,kβ6,XٷjbX(`UVj+g}xK&S3Ɍ"g:3͈z-b:- +ІWe[CLu*[ز-Gr'iQ>W7i4f;E ^Ft\Ct`;+ٚӍ}?a܃(l>eξ̘IE-撹%`zm܎Me/\ɱ8ޙ99NWs[9u-U}<9KHZn5t \p#KH+n={#9Rr~ [a?|)+I[OV>:˙i!wp3m˓yfF\M/m֚7n%q_+p[SGJ'6ޗ&B߫:[wVyz-7[^񼗼E񂋞oZP4ۗ}a%ho𦪦٬u^UW~ szQO;Iw{“G}{)r)SSK|t6›b.˲h_*JϨOzie.Xa쨛FpڳNy qnhr0>mʠT<_naیqB7+uVU9cjR\o;9vCs7~tE\Y5_NW:j7&C7HvR9aS2ݵj4N=hm󱭾O&ꡦSImZ#dc Rjrטbj͖d vXuX^=gU~tw6]7]z>.0vE2m4+N1*sr--vEI i- 8ecumߚ]-oG۴E'X#jVJBZe4 Z`yV{vBz,|k=ܚso5rM6ub}{ֶb ,d0D[h̗^1lSԚayfX61Ω)^1G&duo'NhOˆ,’v-iNÕ=o1@} W2Vm$Ze*GM[ںRu馴kr%*۬Wfm朲66)i6sGOc@6b das;0CGzavu:1ӤcUv*Rީ܄NSub]e.njr.ΟgtK? @4AB@f7{Uݣ)=#HEP{D#Qi4%=sg|2zMQk ^cLrVY/^gY~tf2Q!9#9ATa@&Tޯ z+?HQai\Xml@܀b9&0CF\%cviHxK+>2OR~t}{1e 6iLAP&Q\v w?"gH!2+=prAӥϓҨmIY|C^opvv$#KM$S"gB7amY>2 1la# <,Z\(Ō=TdDFF.YXA7 x@ȗoڑY̋cF\#GQ,F1:撢J*.`dL1BcN6"%m443bG#8˒x$2-DJ(H 7xRI'.N"z O(4ap#c KL1tTQ4ːE'm0(iN0>/Ho X%4&Q̄$'16Q$'Lt2)-7"a J 1$-$2 H' \/7}>{N?W/L{^JZ]$PȀJRO%;T҉ l43 κʐ.e1 {aeG蛝wN^9yzL=gn9uYKn)Y1w:g~ے̲T3`L3HMt %p,ZAzף H0] bu.Hթ J/Ү` VjSpǴʿS˼{[_h3/6h42Ā"5"0"ҫ%WTYڗҶtJ#.Ui(ԼҥlilZ|(z1*И\F2j,#%.DUjRWNM bRbƤL&5PTa_c&~mf*K ( YRNw%]'ӮS[0ӻ075FM5nkjgjfiԗ?ZXqTxcǑ1E1ASEiL^A]fwdNweC>ƠZ.cv`yꞧw~iN1L(f%4JB0x*}jRK\9 [ЖEX܃%Yp&4,8g&f,zwiŒ  )'mUNg,̦K=W-",2,fj궬ڞ `C0#ؘXĽ Y{YuXk>5J &3k Kt^LeXXx95у]ʞh=ؽu]`)UO%gIuD#h}y5ۚ>ʾ&&r׶p{vXNk,j;ɉÉu?s{c8٤'z1V4f:o˾ˑ&7eIXA:lZm:KYuew]iɅN<џx*Jyj6O<~O N iSQ!m>}1nsiJYlpQ7:#~蔯N9> `ewwIt,+vjht6tQ3`F\gSV:ݮr WY]a P@8ΈvT:̵j]] ]i1CqWX .e;}םxno'v]]÷m@+:h'qB+;&+w.vto}5dv[f5vl=:lkmvMuWmC hˁt[0ׇpu0G8CB\fe"UڥͶkM-l6h.+Z;qjW[&+y:"&97OcnyMU[0[uBUkTnWQxHyiew)-|FIwTg9TƎQU̮rJ(01SL,VSTRUIVJ()[|_v~[n+G%rM)U5,en-5VUŔJZ*h"TMED*T)EaU~USEvejY}ꧤW}KzOdTZf\U6MdE ]njtOdJ--4R[KUe#LS41U\yu%r5ʮY'~6Ii8 ᤤ$?)m uJtulgi(h3IOqre7%lΒ\(Rjs6I-[HhY*eؖ}bZrK M?? idQsDW452'JV{H)S%MI0%O2qtL-cȎE": m|Ǖu3vƶ*ƶҸv٤y-Lfp2Zn)dM%iĈI6'[DOj{/g1=l00_}>7mm6hj &>?0A@tA 3P@ 1r,1H`k99 9y)W_U88'G)K_I:/%aỰ/PB_!'q2fhnJn>qeνop]+iZG&rvWܗk\pC.!J <<^<>cx(OzӺ#x*Plޭq{BոA^ $,FO=G5oZ ~pBp8etcO<~ᓛe /I?*/V_o[gU=>rkw=o-m8^~(y~%"S>5ǦA} }2ߵ;Me˽o:ez^sss{y`_ >CI/{ʼwzKY^6E |R[9 ur]2Wd3 9,aAs4f$3=P=QtFg.]-F-1b{4@}*㷪?&U񷩌BE>Q*btf55,g8Yyȡ' :S=)\kbTM9&%kHTTobd]SfJ2u(MZqڭRW&0բ7E):C[&-4fՐ.=Qmz|e*2jg4+˜$kaEfo_^Uroee~$+ pe.{ P̲2X:i/W64fieZoVrIJBL#13x]؃Gf2k.+Q11dƏխ6[G=vJI4{da339cHc F dNFf1yg~3#AgP7. z#q&bAØX0L`iSX͊VLdE+fbYeXzK^aG,҂nbJQKQ?Y$!j`X5! c]٘ʦ܀2M]lå+t'OֿY sKWI,4Bb. \`0x&l3] Ig_~,fffMzaߙ5P?arUƯ XGr4+9Qĉ:NLpl?Ns ̦syT.up0a[gwrٜ`8nnnܴs[9{3snxGSµ^Jv <5r,X]w<H&TH桵3O ~lOh>uݷ<-zç^798 ̢B%L*c>C]oa߱з,U޴6{ߴ{I/s<O'' ̡ dQ|Xߑ[ }K7Mv^0s=c,c6{.̃tx]Nr@ϻy; ulEzVxJ'zTMn(c]J[6[brnt3tW\ylr(5b)ݮm&ELqNa\g逇q N*p̕w]z9W7wyn'r?#u"LV\q鎚9%.A:`=ncvyNv:o^ Կ+O11a1l+vJs@}i^ʹ;nbԕ6Xe|lZXgL@߇=a8;!v%E͚\F6ހuj+tv[{bYKbGC5r{q8 zʰV5JVe:+4Y2nA̳R#֙oau! sm3o {,Dz>cF_Vc0KX"bɷPWof 6 1h̴ 9azDD/n xGuk'Y8` 1Oaq#lPm3a^=M3_:]j:\i=}/8X6ı"q̋aN"f`x}LGiuթTm֮_a-bf59ܧ74i[',-'3̬DKO=A;cu>&Oۘ+in2դ> C.1qzcw{T3*ާ2!SA_9Ogv:3I3x-&S3/ f)cWMurBNr}$7&r.5ƹYsYN?ʩLM0 \N^8s!E^ 9o]C<\Óxh:.kZHrr֒;zy扯ջ8rײS/>ˑke7xe/^ 7ծ`;';䁋'zy7'4Okq,ᣝ*>O"NZ/\S}b,|h=}N8ێz۵t=Uxŏ^t {79a|ό7bD+jhvfxdel =g3t=1_{y;^p0~_<_@&kJ}D/i)3fx,O1 K5])խZzS0Ujh]C^0&B?;06F<(fGp;.!:*ZDSiUʵdFm&:#&ZV5v*w**H8;Xâ8菣'hL-2VKP&%$CU+FgV&0?$zH[<ͱL~ucԍgb5!qSTg).P\4VIHc7nq; {IYn̐7d,3 bGGė&37tҖBSSKe4GWvDEa r 1IvY}2& KZ!5j䨃NIS„G%>c῰;u),JcV:tӒFC*5)T&SHqqA bBE˽$Vvt,Eb*6Hm7]b\%lpkEaBS"/Hfu#̤;,&eRAe:LNYAIM 11]Bbrqub[EJcBRzqׅ$Ph/lMcE樲ߗZrϦ*L2K';TRRIL !&-Vtz2Edli\րY d˘+eD#dJnSKKoyKm.9gEv&dILr„Dd\n!y巓Gэ; v{WϭfQt0)ͣ02I&1\& +/(ʘ(ΥL!JWP+(9CB|nuhNSh*o* '|+oc4La?@i&KK|@/-.erZʩ+K*!r+ &uA4FZ☜&:6ZF%&c>Z_d҇4|a~3 bAʩ jk 'tЂ`hGŶBn{hE*vyw2?Ksj.0*ɨ%I72m@' w<}2@e^Sd21}2Yzϴ/̬ :Hn"eOEz030Ae((dz ,cB_ʼC=.~70 8Jm&»{Q f<$eaUbuhҪnVeVgu,}%og&fL~FxA_"6%zTJݑ*KٲWn6OtF:%فj.[xÁ0.ph>.+8pb߻;t:3I"l$PwEe\95c133nr)N>կjr!,pm7j ,EB>ɅlL;cx8xp*KwʝOKR1am|w~\8!'bDKcy=yWgr^Ë]JMGAnh6y30>>OI?'h7?%p7?k~ȯ&o~CoQ`ewlm[m7]uW{Y/ߋ^=w}Hq d37I\?P=}GuxS{l% hS{Q9wx}m ;^E) Si-qc\;[]fspߜ d`\{@ZO8o%O[;ԻM[tYs5FCn9mS6'qw+GG9n ƍx׉quTFJ\ic1ֹ6\fu=;vʮAXπ\!!wHC\eWof{٣.vi!,J]j6:bsu^Ϭ9o kJځ@KhیUma<[9&ZŹ,ZlA]k;,~h?X輅p*Z@^UX%*1VJR-WbJKLXEZ-it2ψVl{r  x€+@? u0_y"kddosTmY j3S~32֙fnGt9C:g:EN@Řx\>O0?̐b,UbJtii=fVLU5;=ɏ4fh_7f5d8kT! tH5E6ZjQY&5Ԡ_auhZ8=}ƿ:htgR9~u5 i2VbLAz&*TLUBrsY%*vB[{R(b/ a,uO茢mM4Q7Pj6^HUbUJR.]\T^Vg\%ە$ˣ!OdahbK{,M1ESEe$eᔎR88LQPBq ȓ)We,S 3[ -hRFI䛒|$ٯlZp)"/`9.+4ZFh4i9RCVIm4C~Fč_-v㏈wFD$j?**l]~qwOݓnMCBĀA;TQNQ@ +Wk{?qp^sz6h.w@^{8 ޺ nY67ލ;a{Qص tvl۶<-[æq4lخ뷙nvkق5K`FP ~O8^{~ pp`ώհkZرmlݺl M;NƝ`îaݮ{vSX50U{Ԁa1n]a;3vloٽxxC7\:p?8`=a5}Zؼ{=lسk5{}qu`cE08?`_=M G\=p0C>?} k/#l߻6[57C;>?>p ~`%QaJ?p$PR vQ;G~< p(N0>;0`áհ:`8ضa'6NpgN)8ip"XRZAǖg~9p8-?8 0[l8kkNm8.swΟ8]l8gp6L:2m$SL\tN8z Q}Gvz` 50[ paM}CLW\ p+פj\p)B9> 37?9?`I6Xs.% [nu%[nzpKILTe׺9?vYg8t`Y6^XsuUkn>G\~g5 K)]~%.\pxj%a1Nxtu,؍+.p2;l`-`p~Py>= vY`k}7lL 'pM|>#@pbĞg6`WoiemY>p|q_t!4"ϸ 4՝jT2(()(ȦHS_n9l~ fwﻐߟFƻ]0`@@O@m4V.ܺpɇlyuE|=/z/݄*{WˏNBo,2: 'l`|c-kֽZ_>+w0 M˳ "n4w rX#y_ _\z/zϽėH6XpX5 KT8!W `5V?^|FHI<8ER4Фu? ׬]a-[عk}:|'N>s\vL~c'l_|_@HXDT\BRJFVNAQIYU퍺[]=}C#cS3s +k[{GgW7O/o_?ĤԴL '9y%ejuMm]}û&zsk[{GWwO_ٹOh?3b\f6nڼe;vڽg:|䇣ǎ8y_x׮߸OL~?!ˣǬOs<{+N.<|B"bR2r J*jo54j[XZY;8:9{xzyGDFE'$&%gdbYlG;~SN9s.^1ۙ,>ec+.n>~AaQqIiYyE5u-m=Cc3 k;gWw/Ĥ 6+O ~565ћ[Z[;:;{z{GFF޿033;ҧoov杴._h]ZY*dL9+|@ʎ_$%">iODNDNB;|wwʻP~{'RCkx9A #9섺;kXk+׷F!в hwvޮ~RYWC 8|{vn;5UYJ{9ǡu:a[\Sҷ/QߺjaW\5:Pugou58!2C C~j{kU ' EYoXy.t\ p[=h{?}XB$0K}'H"!nj;0T;P5qK=J89O[ "ytc?T9baE[F>F}'xP{N <[<`ϖ4 k'd*(fb-Kz} ]= ݆ =\ *e#WחL\*&Rb!t\wnS!ծڴƆjAZYT՛U96P\Uol.fA-̉YFyH%w*[e%6F9:t\&mFޕ'5l:0=_8,w:]VΚ6% rȎ_$f'o/9]xr;V6%|ؒ ~&b@y/0iFZh6ؒ ?tXνCZhtrscvsR A2&b5OKeAKÅۗMt*ʰ&cIYwfƪupasVaQΝUn;BƄΓ"InoZ͍655߾ݺWn?F~;:7|bccޖƧ/qɘ9RV<);rD/z4PAw-w/keӟXSgfX-w1$|_ 렱Ɔ۟nlyjNe.1^s$<_5렡چ_usշqX?yf%/QW~\O|x̶>7'- 1 MZӆnսϝJ^dqE\ωL b b|:!|!F\H#D."RQ IچuP&jߣkUKF]]"Y jEƵI-֝ŶEAC~.>n^##ޣu@eF|T6R&gZ!k@!2C!3VYP[SmXQeRJ1DjrU5T84[U8XYzB]O~KKyFJFuK'{c]ZTt\F"zR:2:r=]ͱR1lށiE~$Q2hBsD,a@2ҲW6ޤ[9٠S#MC;S]nfSoVkƫ,GWM>8N z^I!nMy^SbcҾoGԇTCU5Õt"bdbezm,t2# 8T|fHiZVmEMIg?9#jHJX$%"'w9 Д%6 3,g.˕mRդYъ|IRV" ×]7SʙOTs hԲӭ /;|޸uKO@S# _|zcT@s$_گ-[OMx8I|v#/C.# \_|c_s$_ʿ-[@0ogA9\F(;t}_s@ҿ5[Xa֔2CF/O's0`(.o+2M̰96jɣ1˗z8y5 %[ DJ1>O~Kk*ST ^BV1l&g͓u!q Ѓ'T1rWh~393d _Bc?b>c뺩'{*y4Zs% ,frf:GEΓcǁ7 r١ZsX4-_PӠ3|{?j]5llnb*R#9#8O…. D|C>#Pa>YiOf@@G7:_>Gzϓ DB"_z/`cki;hO_itWqձUrd͒l!k92Bg5muv־hmpo{ZA}F+{9F 5- mi|C¾yZ~0_׍s{%~$~ ̥CSaİDb|1|.1MЊWCkMt#MͿԷsT p9tJU& ie6%v=1Eᅎ!NÁ.#>#^ޣn~Lmjhj:|KqgBTEԠY][J5T4xS̚<*-VN6-vvm6mVeneLMjhh=@wak%q!nv9_2ɣM;"z2:rsI)ͼҸ֒bTkSeP@կqVkcuσ%OH2&܂GĂ%{m;,U1m8VmAAِlL֦h-s5lԛJ^Y[64'W"j{M :94 WSՈNTKR6LV2IQ2OUISKV*WCЏs>z6=52^SqrVhZQgRMc\KmLWyT_qD+PaD'HnX?Xv8Dz,Tj*Lr6[)m^ 3WdNƠLOإ,+ڼGYKY%5;ڎzNbSF"S.“VB6n = `df$L{4R#ria6UUa.`ࠑɼ)bp>÷:@o:4&<2Czxo%1!f6&cXPmS[^=P02!':z6'`q2GOǧ>~ ML+U51٠lXї0IN>oa3IL<<4Kb6K|4S.+S51]*́^=:/ 0E>f"<{d.(V.+K%Fn\;BDstAV<z<a7l`Q)]VieUkA?w!2&s~x\.iY&.Mieyk~ }09V/yhDQb4W&+G6AcҚ==?u ޡ0{pXC?;LEGI%Xּt)2&ty";vay|ҷҀ=z桱"\㹢Å~=b)MyEl 9s!Oow;zb; $F DLKD}zK%UdL 2w '"}̯ >H̓%,w $EL)-W9"wXq2iw]2oע 0VpqR;\eTQt#"]a(dO2AN^6F 380Tp D/nk l*R@v$K["3 QBb!f!7ML'} u8}e7T9qS9)D]6PU7Q1wW?lh{&Wm]2"B4*1wm%6v}AE~΃^C.>#N## 0P{UOՍՏnn|Jd.g@,&ިQOӡDR iw~t r62v2RNR..҈o[ Sm7;K(b]\hj|JL>I5ϯAģN¹VʾƸڦڬֲڊfN3r7rm0jУI]ԭZmgCs#lyٳR֩cҾRQ^rέvoHVt\&|Fw&E ź %.eu5CcmG_>˞QHY1q uu藊앍7VJ2RKLxۡnUo7Rkĩf+:}hhZ=l)b#qKFך~ &3v.^cR~:#rJCjj*o#t# Mb,yxt_vfzp9 =~|3gJk]~S"VZ3voeT]&T&=Ƶ#5do[FuWV8Ƕ;v;dw9rI]xRƕܹRZPO7P2'PO0U4[W:Ӫ*=:b{J]R{K\}n~;AK >e^ڋ2n@)(_e!Yl"Yk Q93NC2̯ T:5Tyuzx  {dCكҜZʼe޹R98QBD@Rtg =ΠmYEtlh/ - ,)%feeeFVJsݫ1|ܹ88?)eN`=3:0dZ*ֱ<ҽ$w0(x?}?fŒaǓc Ϋ45I{ :zN-ռ\]3\<;E ͘ ϘN ϜJ ˜LgDݫ,bɫ![x(>H$(gҳ4i&TJ}si{oah^tTNT,.&m6=&}6%:CbdT\8f":;RKV-d]ڽ0ţ0E6z+:+ޕ#LTɫVUeZK]z rC>1)) isI11a+k|֥ Yw/erpfOH JvHɐjT,BH.&!; ed,&'e|Μ _)e9ܥ;1 EJE{DDeŵ*5"\!v::1:)}&">c:,3}RI ]/Ͼs}9ZfXH\Ⱦ"Y-Zϟğ[U-USXPh99M !%͆`gBR3>'fNaVJSf'싻w9TZx6ֵS 4Bq;y >u,8g7'zڋ1ɜIL&`ddyNY] w_sIVVo4mhu l4Hoir֤B!|Q.yII.[Jֈ{I5ϳAĉWa[k\eQmYcBPu"R4WL}(y3\6Tz|cK珋&xI3b Y! Vl7d릷f LK˴˵h47(* SRh}y`vχd# b% ŜG#\{R,;T2L5:ٺ-f3F5Y䑧Rj5Wqn3yk䏜0eNGA+I!W1Q_a`A~h^8Dnd..4Nt L@Jh,]w̲_ǠX(R^zmɤ޸֘ț@a`!!0ApAH~B!Uʁrfe`qH9*μƜꬴҌe{7ZNS:b&n"B+"f |8:]~︡kS&^Hk"nUį各4ё+/PxQHhAX`oԌg|2 \NGO8׬m#t6z bQBd$Cb2HJN)#%%^̃4T @V+% ~DhfGtx:s]~VAȡǬ3Jq"aH B B/sFi#]XYJ @;Vг;P0y!G⊟gNzZG%u녦vDgtMtheb5v7l: _UЩ^ ;|H ٱ ݁BΣ'U%k0j7k$d65'08C?*]7)M;ЪE"jZ4ɴ5JR~ @P(< |@J f5 zR:ͽ2MpmFDr.&Y;'Oq#}CD&wxg: lB,(4S|5Ŵ&߲`U\.I)I-0ŜَΡpV%ʡ$DI8y(Ȟvc\mn{I}PeU|M9تh[X+O/K/9׮gs(1 Jx. |LHJPROn5Y5x:Ҝ6uT˂F]A#!)ű1]SaCSQJhe!~%?^x-3|;H{+&$vhe56ٕպ{PmNy-y-.y1Mᮅ+-`)j W5喚 hND-& Rn#ٲ}T̖8]rCyi[-1Ӟ^ذ"03P9SǫY<_}Xh@|t7Q)-K__TjWK mK uGy¼9m޹-A^@ςw+-`1fCp`}W_dHGlbEL9N`Nm &ȝ9~~yt?ƕ P™(,J\6 *ASKgSX8Z63@0gXLu v{;=rڽs[^~+5`>v3[Q"Y"h@_lg FK#ACYMSe|XaT:Z)?D9סըmLr&w8紹涸 ޭ(q%-;,a2tOg xsB]*O֬|H`P)ߩ@W}[eSiۤ_nDi7Oimkor .lX -Qq%ފ-|M}?KX_BtD&LߧҮ kRTXR+t*t}R^qz,12uDaJhP-(O?ea,˛vďGb|*9:fT='-5^A;AS`\Tg[L[ 1ނ:=Jg +SC;sUQ!)q#KڰLptt|@L[ ѺQެLLѨ RU)%%5ZjRJOZOmxl٦/~)}7-(i>)3,'%jצedήHާD>LPPSQ\\^FXMq)ka1Ԧ;j9\zlս)>œZY씨KXD}tERa&V0[ŊBwQ56dyreԂИЛNn,OOqґZ삠I𴐣{oa H>XD.TNt;\V-8K-'FI4VDC@ >Olh;oG%<'kAUx 9L8 MY9 L9Nzr_ T,@U5©E_mgtb6FlB:腤:SFJrHDMIjH Y-1-t?i/.^47Z3~9n* b$tdm:]<逮^3GLGCqʣR赀8A"bHBH"HE ˾Bo_ =gD Y+|zĥv@ڢљSoѕ˪GytY <El˧|5k |$8_ gH5;R}4X6#d(Y |@b+@0bdpE-іuh6 td:sL]=+~,A ygC ч#$Wzyze ؙɍNFzr3ry >Yq"k!^d)-T?jZ̼VwwTW~;&?*8*4"]<,U/!ҤR5;qXrgsr;<^"{^d'!5L5 >8MuuWS U QL D H#:Z#푵j_gc 1rz\x XzcTfeBkLD=8xX5&lH95bP1;j@0z@:[KWjUmTo-:s '6#ǐO+E"2EFs^dRnmgT3hX+(lP=*r@5%_קXߧ@KhU'Z*5Z5[sGO@W!ǍOȓ1AB2CJsEdN~[ȠN@fdLߛ^|bRirRCJ=IO)ѢjS :_g ym_NlB7"_Dl?k/ |%4=MfOyYX ;HHNV#vT76dP53J3ru3 Xƌ1 B'6!G( yōBPɌ[QӠAs~#ݰ.7lf=T>+W> _1J3~)o䳍߄oEnև(@oBf&<=G mzM :0깸& \O#dF4B1 hR5&|V{|qܹ?@1_Xn1+)Jp6Tv_cmЀYtsRq`fnRvfSC3!jrMjrLkfZ&{( s E?@I\"(_i>ATCx۰>wN latPŝ7vV_Ʋr(KΤ?n\\1yL bD{Pn@2̨W)^S?M1K5 /Z%אk*i7 į0P0^HP9lYB"3E<͇%t&(t٤HwewfvTg4`JdI8yl}h X (Ⱥ)҉u5'Vw3o*a;3u+kyX"",ᘔRʠv\ydkhOXp76I6I,VIO(hJ-#ѫc,PvtζiYo'/#Kq?Ja{I)WqE/Q-? !PAp\$@u@{K =k#CuX;}{v$nz 6Kd@g^ͬ)ugI=7q ONc8s}sx5b*TרerjDƣ{C9o-Gtz§"ni//DőRTDokdJŒECpcQ PJ W3@E? Fw{+'ЍYeQG,J zZABHLIFHMz+ ʱ! '^1TbA*_ @.hF56kt!pJ ]n(2KG; ?zʃ^q!H3$ɿzT# n+2὏l"Y  08Mfhz]thtb:wT]=-n]Ewp!/ӛ-V#$yC H[H'dk`(1t1 ƈa&ZFm]'mBvs^[G'#ӳwۈ/H #v)ݸo^A?^BL_Ye@W#}-Y =BR{+L$$e(d 51/KijjO|w`YZLm@!!2y D90ԐEjFH-u_7^0MX}ʱ(_o7e7*g'2h.>l$=jW'AkYbDf6 kȔ q=B&œPF#M7HRgIpAlN*DͬX݌HP`Ӹ`ӀHSĠS̰S܈E~?lVɈ̏n@&!{g哟իGRJ"ey4UM->ʄHtqpnvvs *K3v5 띌zdzu2s> ٿ`A|J\*( }MO vf=g?:MIeNOR<ދ{Jt{y<+U3ȎNFdyt=2Y3?f" Ə^ZDIEn.)"݊'b xfفY<&d("KSHB}&Y_A9?<36~q,lhnۗ%ϝJ**;3TvߐFHˆU܈X4ȑAucn {7$yNFE M H]ŽsgɈaG/+z+nz V^:7PuH?!IHD*n$,F֞ (B JPdj<[~?"d{ז|p?X\Րӣ'njny;^u'3 isH^Ņ'PB*~Z9(p1>&>k(,p OK3Suld;B^4 a"e%Rw,BށZ彨RUghaCk(+ Urtֳ>Vq}w4|Yɠg-]!ZÞ5޴/A1ԕ\_]Q#ٯI_}`sȋ"߸Iŷcr/wv23@xȧQD=kL"df"m%/@*KnE⮉Vu/mڌ-[,]s\}0$zVlɥ3M#Z`u6Gj먉yr*"iky'H_Q%nlqHMzK[m谡.3۾v[{ n*2/DL;\sW?*;T88iۿ"B,&2Vp`< /CĆ_QBK)=tYyhqPy,3?@V΁Ϊ#eI')JpA㮂CIO%˯l"db"sER>rRIt蜺ԋK:JMnpHxr_s@ Nof?w/=+vwSuC%c㧭Y).omH8RSt,ډȲc+p|΄'e, d/DF^Ȣ=_ݑZ'^ĕ{8w]m>Ruԣ03&-9%PHs =*pdΨ'1O\"2ugL6k<= 7*9{7M.&w8W{,bHwzwwmKGvp@ʾCeOJKg2k'lnRƀƪKtv|DvC#;7x\LiqXnsÙC.]}<r/\ aeYZl?=pisn-x4>kD(arsBƇOf!!KG]kZ5Lc3h<5X8PfOkェr/;^b"pDLzqۃ ҈Sw}QES^g=QCQQhQ$~6_brF GJGyQj;Pnzs`ՙzYJ26y.`kLvu˸P̈́|^愶u+맱/P_Q?}ÓM|+z0G\ݏr ^ =xo|}('Xà]D/2C:1/M$U.\TaƂ? a@Fc~ejOT%hLt&_OR:I$ݗi5f'.\g'w-~̫u+X(AUZзv l]a ?o}`UԄ(=8R|R/}uD:.\$:vAfRVrc\Nѐ(*BM:zV066-a;uD8(#Iy.rrE4zHm!xM>:2= f%b.~OH8AVJА7>LUaG-x("@OH0D8L\ ]teD5 Hl, ڹزk ی SJBZ,^R n{+ T%A( R_N#:x(#Q2.?fqa=VϲĦFرX"5 Jk^I[`u Á_;wO`;"Nx3REQD/G@ b:|FXȭ3T~"blIy @x4l-0] +7i:x^_ŀBx'p]7p34Ua c[ 5nvf 4NBwݡ<*WEkƿņ.r{gUz9T6[O2puQlLaj |{W9A:ܡu=^P >PK7o~ 4yb h;|Up6<%Oi3uDk&OGu!I0uQ+ =>=/'?0-яWcO,[Na /`Z ̆r)lF(LdkOOCZ.VY.0-Q7 }w=о4:p!2o#X=i@|v၇Yfke$`k # 1Kwe7L`c }Kg]oh+c"pB#` wF2DnB0b da`'#Z3ɞkUǼ9i7ňq{ _G}u[ =c/"8ώ<>Q"Az#T+83uD!/x ׬1¿Ybq&Of/?=%ċ_θ}I:>=D3>mD Uj=ҕ-TßQ6?B\D~N q+ \5퉄!Iϒ 'sM:z}4hQѴ@;[,{"Wqr5%d[|Mtvb L }ڣM<~m8秬^|uwxZfc r.Vq#z3/"O|5O)~3ig6e 6Exl~ʼn{ʼv!koUg>C~怏yMs6B\6Vq#nLd GJlPR-XsUTɱCrSTf]=wdyEgu+nxW1]Q}A,= +avEe) iJ諾03/v}u;54Z|\sa%.=+`@ЛƐСҚ%Ua+MLB6DFzA蒟 k?ߤ~ +oyx]bOJ8q4:?3=@HOUSȫʊ7eCeoKK"ޖLqwCJ.FɶY^I|էVoڕbqJ׹?։,VԄ昊յj"ՕG-.*~SQ=Tgb!zp| >y_[ŖZ[aۓ#jWdiyD7 $5;61-6<~Mqܩ¸Wqkss+ޔ L.DjNTmiC X̺G'DnUi38hq#,0 2:'42?.+ؾ ɯғ^פ'T'$0HXƁ=޺cק_X~ﬢе:M̎u?5t_Bu+((7?2=.)1.̗_'MLNJLJyS1$6$/@rv4ֱ/. 꽺k魋rNk*[/-x]DB6T.dj]xrn\pԶTd:.45u}B^GDd&Ky>QSt#'3͎OK"GMD7]aa}{T lVܝ6;6lh;ln:bb?e1o9)XK K[gʏH#F<wk}%"uS7|YƬ[}ײ[RvŌ)ˆkNMjoEOdz_yojk<=x: '9Jt>Pr[/Mgc4C 59WHp4փB`#B{)4;EgqvĨ. LJD]UϤ,a ر("k! 2P9d`  8+GK,I$An4⌉373Q|73'HT(7#٢;b7ލf҂La#! gIIH%+$y*@2?U6Ml7Q%D}DYD/ 9ܱfYa|.ч mȮV:%hl&)oն]p܊8MYruhݽ:rQE/Q3D ;|lVXiܺ0CyU 4Kbse 9/Ay(4 Ao,r|VFؚ_pZ׉*e=%~E?B "LasIc-6 .^~nFZY={,圅p;sg#x,^&rb3w@j.LULLw}7%'LeȖAA{L>Ğc5Į ƥaU*Ӄ+/K9``w.,Jw#,-wE ЊVj*4!W V=Hч9H0F01L@Oi ix:pɄXm⁑(,Na97LN{`'ehC-_UzPl2|NC)B>Cry&a>di l6Lbs,.h";qXzDMhB|J'̠c{a VƬ'>,taLӁ &\svkXlM',l78|3jwjpeQG޸:`ۭ]IV^=6.&<qϭ=g׀[?. >3ϐnp]Í <΋$H^;Me] 5¼ B^9>p{ZsCǶ'm"× ']#]#G{O xgJ.q#~ wX¦lMRI֪/b #-{CxQ|ݭuť;ǹ'󓨳.#ܾtz|i#z΀*4+%xp^䑀ʸ.ߓm>wRKiR9:KRe A ~s +9Oɶ_羯X^n]:r#6:=YnVgS]O$u$Ȋn +MhnLi :x#6MFUHzyhZIhjq/IAsّgf:7w/x,Qʶ5R,8[qJ oOa5Ǧ*L Kduf]. {]* I M <10 ّ +ƪ7p|ܿu';>] Z'J,{e7E꒒*sSJc2 s.Dˊ)+3j8##j$=#j4u:a28 ыؐeok*li֖8]o]eg^T_bUd$f&gf&M?,?9c^rؑѴ @6.`CBd"hr`cwKnv=ǚ;͚\J} CXq9Y)i%YIiMyq S bR>&̉K8062͆yLcLTͣO- ebjszɬ?եpjkICcEoQyPXvITljaJJ|^AVTNC+DAHЬi#S3Gҧ0!ؐe MIX B,61>ГFvzIpѭ%{ĪJB-ǵjMK涹x oKJv9R ϵcGOY9#A"yYⴛgI@Rcm&ZH19v/մ{4ղm4fh]ǪA4Y F] tu6:ao~$8 veRHiy"蚳/ˬa=őFc܋kx[I׷xMߦX/DUD7[.#:}mv:Mֱ>UTbev>uɨ>,\y:= q3m_=H`o7t/0<<6-=+ @It ё j{Azp#gG  ZZ :k 5qW};|SO.ΗTDWZ':CvA٩"FMܙ%<"=ePnRbIxG_sTsV 賕6a84ibAwi:On#:EtQNJg5gm|! + *[LoCAmXAL rDE_Qv2?ӹLt;DEDψb)s~X܎e fػr+tZZT`QMSB;/ D7x$LdQ[DER"^" #Ya%)6r >[ 2䠴@ $d7Lf\WmGM^WrJoZυ蘯fB0dRwco8$b~)uHcq ] 'A9Aܤ~@v\ _BnD S\66nh ̈́ Hs MBq 4}. = r)H5`o$Cį+`O"^+N(P(|'Y(,h%qCW`&wLf՗x-BKZ ,)(BV-RieH]U+@KT$UIB4?AuH jP 0a:[a?"|;_+m0uaHB3Mj PR_Ro.OMg1T i@`=  3`/ g9pU\gup0gXOD6HR<]6YCUojuU}Q;:oՠZOap_wa41aa;gSl6[s-܍O:ۋ;f*z \;w@) XL.gf~,\`Ɠ Ki)w&YxێְT|}UAuBN*}/` - +(?̀|vg"~!_ 3ޖe>[{ 5utJ4iOmt]PVZ^|,0vT~ైqVvDXVϐ̐_Ss6yɜ4Zk33uV~ -&2l53LRmX>e1Ea ٬L֍tPLZT8+5:s1> HMgNJafn潼OfGʍ[k4gV$eckR;c%D%DIJH`%DNM x2>P 5qtU`f'wH(Tk(v4) tόJK JM OLM<p9>"a >2{lT訸 TɀL&bg,./e:zxnZB;vnۻYe[>=s {RwBl tDWۈ.!:sz&=iOȬ:&Tԥ/ano{͆?{_RkC~C}Cm(gQֵcc%΅,@ ѳ{Dך.":}:ti5+K(ґH9n{Fbc}(ե#۾=7.ĬDq0։0Ɖ0ڟ6?ClM H"Qo!э:KmD=Kt o,g]۳$ Ѹ2-:{4w9lgw*dtO=9_OaLPDwˉ.':ItKDoSͽ9Tv#g=yiwWQ+xT놭u7=&ע,e]rԺ~YSk?]5]_Ö/03_bqO4wxv鳒{dWq^_ n3O̔+> ت^ڹL%]FtaDU&NP:Aް= Vy mrz捙{ 72zC! oTT+oєpMKÈ[ȼl/ h*zNvu"Q'L8i-{0 F:*6/V;u: k|ݭ-B\{Jcr{&zwOȋ}{(J Ai**Nu'jDTy(Qc 1;}| OV][gu6n}/w![PB8!1ؽ6u!j@Tu^DDc8b)9̰"3t 9*P20^, e{Bv;oEM8io^[brJG;ZU_#ʽK(%"+p 3M8TSܲ# {Ȼ |BЛsa&x[p/Cے%t1O4QU;$zCd:f01)l{] [8DCœ) PY u03…w.7YxP5gO2Qmw}IdHwHD np31۰ ka#*lc_!1!9jb’M&Dl_ρ=\+)U䃴lHŻX 5H[r3mֽ l+۱vly[nnfl[n֟[}*P_u䂴0f@Q Zs g6NKo"A4e#6C|+AvǎSѳwvvLn_;&|9h,b:H䂼7ẁ @dAg5X!b[d;vhN ([B}N~)]߄!UB!<h-dZn2?74Ef@G:smˡ ! R, *A7 .<s"ŮL= m?EF@xD ûĦlPY-\ AKXqtAr%t\C#` T'S~ +)[':!ӲkLkbߥ}z 6*Z韻Ic[)Hs9HM٠8a ;y`%6Vra+;nmmBsL3Az殯Eb_T|V/>!1x|'K{?*ܓ|rJ?%_)B"(A*lP_50_ p'YpT]`帵ۿ N{2ɷZC2o4 h}~G ٧ò}?zա@*5zUjS<&4Wqplre '<y)Sq77~so'\2wM`xͧL/c"vx`CZvng ~ugV]E.w1A]5"+պ=V- [\4:g[G-`e 0;`өxƋḐ K]k ?ݼcdi`zܮn;]?lalF{X;r*0̈́6g"pqkI%(AmmE{Bܥ( :ᕠ#[yKA6mN8ްovzi; ΰr]+lYLXeB3%-cK_|q޻iˮ%ok%z&YDjwpNg@AV\frF nunW\jܞT}ups=Xl6@0F`2_ϸkƍlu6I2= z079x'9^I!H [b0\K^&\xv`Ro;=,UKr3 (lɱjpTJ-K 4)L΍MpȌrM,Lh?~?&_L_+:voD1V̝I_V#z&#AOS.cZ&GgisVqJe&eE6.9>iY!VIi)^aIA$Ngp ܧL1C ED+.7o-:wji[Y_HJ>Q30 "&/><'%8+?;3FG;I_>IKT`@9D7K.o":C2څy,jRRO_4\&^-M/όUʲ *Np-v(vsʿ1﯏K23?NѕJNuw+M]<5$Tސת#l7aR>zKX{ rۊ6/+>CVeliMD#z3n]#:BtQQKvβc{QXqX?m^-ƮQMivVK755u3y9\-2'Gt~#!*;=謌32Om:'zL75nF])&Evu:;:~# k#q*sDڈ:NU'*EyWW12I"1?-~H|Ju`\KӯKԌoj㲆ޏ_IS۳ؼ 9Z5k[@# +?"˰B~1qrq!g>G@A+6dc%O4OJi*]B/啉>`% ~ ;ɳ\Hq -s,ɒ˔ ijQ(: *&!itXD{c@Y>D_$ se K4me[,Jdϑi\R%F܂K<e4򟆎gK@ 6y8l0#]@FP!Y<)I%N,acɔ"6\ ?6(J@\Dl2"cn26&+^2u#c2"ta*!jqR+IjҤ/C+diYYTH<)'|OsJ)%Ed?+ge/d&S-.26&3#n%kg> (!2N!b[!IMҤ@4{Hcr arL%LI)!Zy2oQi֥iSQjY.G>S{oު011?7"?H1iMFNrl"\E>gK~ L1b.%OSW9*U?}Yzw4ZxcuPWV75Y=xbvc-Iݳ"\dΡi*U]n 30G .?Y,%*o^O7O.͗.Z/Wh?w^iS}:ON\iQ™Nbk#T&n,i8ese^߲ss:CdDfFdvg|ۑ)fAEgQd[EeQd(P"R&jY>-8&톜DvV.dMupE˲"*9û;sWŵnKh98/^BK\K͹՜CQ C w+ 88!#]z=[=7ki5OrYRU൸<>d~d[QO [Kn̿P! (>)j2 gQ:6[Y8x8,ft[1)b(f2a Y1pY cwB`"W.e " [;w6x5WΩm錫LܐRZq(VZqŻ J,)2+-(â,~p8 X-ǎA5֦3>g=j z:,;ӜZg{474W45FV4Ǖ/I*[W?mvʹٵoSfRR^ %WQ\~NFv%p8-Ƈe -3^ 1Keq_ngOydΙn |ʂEk͛ۛ8y4%yo̦i3ޤlFJȮYuFI|Z|X7p5l]`*2Zi'ַ]kiV@Ism]okUOWiwq`AWMXngKt悞UIiSRڮINiĴy>қ(v2JWS C!`0aY+t8kvk[7yea8ʡ4ǒ,%+g6G-^Գ2>g<1Jb̢ IqF1̿䅖goرظ T{̌mTzo:kMW'pXY18~ygxQvĄ-uL ńStdEGuSds`t#l+xv*mw;r[ԊDޜ`)f %nq#-]7n[k^R* XFaAKQ1pi.ptg: Ҙs@]slD>!3N5Nܕe.b9x砧o ޞ;^{o#_-ﱁ=Rd5`}ذ:M(?SF\y'OgK9T30H w{Wyגzϙ7螏P2]9=Q@)Yk0_V_9߼s|ΧW)#L錰='ƀ=@I,s HDӞN;IÜT`B0$.3dǨ4 r(#K)\4[jyh!C|t^n00Pyȹ $&c`J!1%hISh Iϒ$3(ٱɍMlL6 r6s˒@)#J>l#|$$*_/@[H| $s$vC/E"Y0%$Q&#)lR79kEܤCS#xI5sIIM ܀ ɭ"ٵB$YdDžHOB?d }y YOI !$:Lat9!.2&cO#D~ R yB%L}?,kjS6|W!MW~P/Nk¯TH2T&$9IGCF2!kC.&7 #8~2!H?6|i#E{P'u+^[Kj\ObOH&I?"$;+PM*lSc.\͹ՙ>J/4oVŸ-D?Ջ7/δKIkRJ2~iKgFݖzh\'{F$ۘ'I)OFJl2Wf<[M&/Oo% s}X$ʡZ}32>{lJ6;gsNm[6oXRjMS.[%+RhES'#3E63"ŐC )ԒK+ﻀW~1ϽŞzΖzQ.A|Ӻo+NPV6.U2r9Ip",(Ő8BeY¢X-k m=OaaC$e ,_xݯIoeKރS/xhڤykZSo%8G9k9?CTVJgLݗ:[gwrxbfq 6.nCzѻFv*(r^Eˣi('i", u^|/Sp،sUp^Ծ]٩gfm(44bCjvI GF]Wow[}(@Kœ[_]:_oKߚw~: tX  7HfW : AJ1e)ˊ3 l{\xt,i^7?k]`KޠKAMd}h",i$(%O*L=p8,=-s-y7Ι&>6Rc*`I e K:6ym[И&>wwHm΅К!5߃s):sg2 ( \+'G bg:ZysnSj _S3ݬjm{e F6‘ʂsaeOB P`Y>d|.W#-V`W;/vLvGe喴4u6gڴ;5UW{T( *--.^Xr&qXAא *(""7"B-p8 uq[݆\+: U5tVTP`nOF1,2Lpd> kze1ܫ^Fwt F 5fW4Wy456vf7 ̬Q"(HpTǽ) cd2f@ش],],^̓Q%rW ֏KU (Z<^/gt̡YVj\w_/_pg ^D]3٣r-pl֭V 66Ic&mv%oF >2yBL&E7u48quEHmĪ!z\GuY{yx.4ƕ5k hDNU4!=@&}[bDZ[fm.7 d7m=6b1}쎝e9dWk>` `t-0 X g!4rj2Zp:N8"s V6@RlՀ%>t&sqAV -֭V@A (vɧxFqgQg\ 8 sfigj϶8]j{n͹jVg>M8IZf'H8Mv ع8 ovm{@a 8r *?).|oXo278n7#y\~Os=[V1%fI޹*i&?es>Wr}Y-u[QOy$LnlXxs(9 d/Wϛ>` bKj?UBP$cȑ `Pa6 t/+ƁEk`@ 6Zo  Y$IB!HSK1@ P T5@, t r(?d]{C@)H F|p@$ @d@eT P+@K54`> $i& GpH C\"CLVrMX& ل ap!\d O/x|7='#%Mؤ&E]6)IC^ "$."."._/8ĻCĻw/<_x~g~~yMz/vc+ל8ň!NO%W4e*Cj iNaHG!C},٤!m.҈"?UfsW.Yi>'.J}<x)UFq;k<*yp#' )~}HH U"_TғgT!+mMd!3o_ y>e)}]ZOvޗZ^h =ZLkZ[j{yUyh.tSDnhu-E" U 2dkL2"C,c4y[˔y~%s YwKo;rhݾ]}uAkvĮmlS %ݗ8eZ6pĆYdd$Ð\@@9 V }֋+江O0τO+UlPK}Iqշ{=Uk̋7z@r"y%V8^qo\9*x<&AH * +Y}<]cGp涠!-Akt6nxToc5u|1 Ud8O=?< ccIlOda\KX'I ڟ#'1UnwgWӥ @j`c)gI`e084EY M[-[f6shȹ.{1#+2L$Lr*$NJLr[Y"DpSlƦ%m4b7y/QHj/i0disqecam]\.Cne=Jry,y^Cӊrȥ(rWٖآ@κ)m5Z-UM9&E5eU%MeE= x-x푛Onuv>9'_Qp:p58U v5[[-|i,oa ̷7MsL[Sx4l㪚 FǂvKg*5̒?=f[f fKf19HLR1pljFۀ 0СZa,#5w~RcKzʦFyE yuj[]2kz2G=WJZ#*5\*WcYrp#{e X t b"Ut-2u;h YZіUҚ_0?$2kn]FsSZSk]q=^ӴzrM#:rճd|T .cq!0 ,zxٯ~ߖMzLYORQwz4Y]Y3; ͦ/Jnoovi]ٺsZth!1"Qp8ntkK@Re4kYpW9 .( VZ<5Njoar؞9V=;wow c@Oǀr \@V; }R``йhZԍj*GEyF܅f 1!7}ert9ZKÖ-0Ykyk֞K~Z{gxb[>`l뀒l1d;}P 11R"g+RXW島Ms-k>7riⴊLq%|5pؾX? ׀7[Y;;1}\) ˖ˍ;zܟ?|<\8d.X/l/E/MX\6\k|j~<й]X"j'q$K m]@^ ~=<kokA8A/EAtƃBF~ʣm78?s}⑻O4 l݀jc@I ,v t'?xLϕBJ/L g8$^BM!K]3KR= b `^PpH? D..WqPzd?Cľ(@:%8?\7& kp(:.Wsy 7H d P@m4@7{?t(> d.>=@86@|$A h:@h ~]ub[ECc^ !!$3Y,B P",bAX N||)||=KG_x [MB j2$6EB,4d C 1! !!d2"EhbXna 'V;6+3#=.-5O|++^raHJE*,Re-Y$ʐPC| q3c]d7~0XߘNWV/ k)3Yoqop^<)!HJ!y%)ʱHEE,R3c#}d~J0Eg1_DKO"5fp;VFh r֟BWX/Y g=Cg/uOۢĞ#d$¢),Rdw {V]Sm7-"!/RY |,\ (3xG8_]ۣED͐-1D~}xڰ9ʣSFB /U_FcyN͡4 K74fO il^ck$\'q0U{l;R=y$mL_&=-?W4[>eEtڲK#;"#Ft{÷_vC+~g0]7_x L.NNgӁCb3S3-xg GI %.O82T֟Xћ0G'M;n~W Î1Cƭ׌G?7nnMs`n48tL&plp(؛-9j5c8Z.1 ;0cR_FjiZ R%wO2iI`֜|NeƄ?'q}'h"H.Ny<^(c]1kgyXٞY)J 3:2gk,ՙ?F%}QNƴAԵ{S.ZUZ6yh L p> w} @bWU}(3b{sdKf˥-JSJV[XU9 8cæ~ }4m%d7u=8^n6/,ݽ~z(B29/A2Kv2g!o`23"UBTh/[wHϽ[G}EMn IW v`"` qP2W"cTG2j$qōEX/2.8+㻪\kU"UjNWVsXai/%MAj`|` Ws@Z c8FfiDo@Soq`ldm 9Yssb1I.iUc{nZn oגRf`B`r%7 ś-@6 l'࿛>{dG{MnN^%@r<7) Vxksއ2UE-+7gm@wH9<.W߀;}!'^/W (r:Z nC^Pp H= ܯ7 `=@! `A@.^%T\Z]AEPg`5 BE TB+~ ?ЇoX/ggl'Gxwxw Ib*8*,tA@@! D~Ё' VF;'%%@cUgA ^- G|2m0|n6iE $;$$ 0}ͱ~3?X{/s]׳#B_|ϔJS[Ufh%yIq< oy#xM36DhA X"tl/_3 Bsx<^,+x:Gǹy~&3aaܟ?یW)|Z0bx!K,M+\W~U{.i)%$FzS\Yam=Pޘ繩 Oxh=gp8[FsiT \7ZO+j+ƻd|Ɨ8g@r;fJ fBȿ3uD{yDDO.4Cw+^t#Q<۝=9be,E|빒srgkX˝^'=i]zy.?Fqo?BeP@BcS_{e8!P% \և#GsArvm(}#PiklԚWo^uz-vinv\shB{Я: ݕCnÿn~ q*qa k練{Ҏa*'ʶNHV<>SsӸ| j7Uꬳ[fjcY9~Øcԍbd0\Zs:O7jw?Pnz\4\<-ϸyiSe+p}usvSُx=~v+^pA_-c9{>`tD~d|4._3=pgIgN o_涤CڎŮ-gTr߲嗎.Cț&H gp.8 Ħ`Sօ`UPi}8jAZՁzUa1~mK}3)]ֱȫSVy;gygs!,3=DyÙ8{")6IYa.G.1F&bZU0`ÒHyK:-m2w{t|vM%GX)G_F'#@4슅-1> Vƴ>3UǎR$+UW<#а("4?<]nXEvhefȜU]RwK=1Xw]U/:zg?{`8 {)6$8OfqbGU&P,O 9;S 07&4;:]fdE,Ԉ"a˺džnz&*MTȻQ!kT VQsWp΅PaK*MI8E4s*zJ҆*S-J䦛kb.5.")vfبy]"&|ơ3n x#4Bt ]…uXjé(8;aC̀0C̶eug/9F97czv4/@xt˨(>OCs`q 5P ~I*^M>6͆~p>f 0 W; <Og ި{# >O3*ou v⧿6C=~',^W 0Z@![ +UІo~b *k@4{0G`-a4 o'l~ߨ7z_4|$p<oy>n X h)N `2AE4L' |d)h=xV[񚋼gg|n"$F[CL@Ÿ~!d\27*^QKq%#.BPGȷF|Ƌ^sxJ>O(1xB4pc;wNs)OOPC26BnPW|d"oq<&$pt~fw)ܦrzkl*{I.q <87N#8%QGhK¤ ¨uVcecx}Qr4QIJ&?qEuU˹ K9sM5sZvx_9#8#$E+" @(jkcC~M de#?.s$1TN-Yql9dfo{=2$\HNȷ&-[×n:B[ڡ:挕'Lx tpDvː6K{do2=V'ݶKnvI#>*4v "AX=q_?-ᆵ L/ށ~arHw L6 ̔60Oab+nHqÀJ6+_ymʫWiAuy?![O7ٳpw$\FAda9ݣ1QmtQFP0*^qm:l5*GPbDF4 ?diVKs0_|G pavph6:4/[G~z{75&*7LVY1!QV?!Cn|ŚUhՎ[]cVgNݪ'u+֝7^ؿt1BG w'eG8Ga5^odhid*>jA^sL/1,pc^i㶬mve\m,i.$u0ۡ `_l V4#}XsEeD<~k!&xwa-vsp8vGX 4TTd~0ii80Pw_ܐ`ݜHÌ )e]!goK}YDyf-Ey?zn7t +#.jfȨ2c^twJ͉P5Y%/E-gVfDnFx~ZXQrhIbHY\pyLPET3-.X<}0fa~xb?yP am¢hU<Θ]?@.?~¬8{XgOʹh6Q1q)&13r"#ۇWw [18te`y'CZ]`0k.`e",IP(Gq>ɝK+I!<^)=Q讑&&.026$<&,4zyPԂQ+;Fq{_,|"D{pa.ڵؙ P 5)0/Ӡ ]YEFPijbR4To ݈ AI3'I_3=[죎n1_,cD{ha-ڵ alO5$*383!;[vt'9g\B(l{lgYDFhvp=8Ctfi]S-SupJ91cүSh Z]М !j< fAV.+T`D|1}%#B *|4|BtFqj蒓k]vjv]Y[Ng>4k; af.DVCP"Ȅ<˃<(·BH q5W BKl., ,-+=Yy2@ 9N1/*1PĮpc tt03K(ؗ[`uAýSa!BJc|*gp{89ʩΕnJ*+k=f^6#7/??ВC9`ahʁs`y ,(.y0 \i㼸1uq&/ɤ$;I-.?vqE#ˆX^a~54.էJh:}*?͆u`|(V1GH4DckX PsV̵AcLj۝п`xqO#=ݑ)W8St nӇ8N 8aZr@v`.( 8\PKmr;~  73|pw-V*7CvHa&1|ڞ|\nl :>t</e&Zs)o |o0i{ b=IGaIu:Kq;- >%/.3=s#y]0sDc0$ ? 6*cim!7{#M}qALmهQ_s -޿?l, )7|e1_Xί]|09;|mʿwQoMz"\~c_HW2,>Q/ >P{xJ+4Ϲ3O<OFw1g'=BK4I&`)\rz.l,8YNq8roE!Pw%#cSzsf7p\!KqΓ98NS)rg5Gaq36%/#J``zX>i(^K*&ܑ@(傊#ge9IHk$pL3#Z*v +ٯ}+٣f>l{?F`?C3k(历:Wq^'FpԞfl~PG>3e4Y͢b&l8E-vx%Yw\[<{6pE Eδ7h.ޮvȎlV6ı&E&Kh/YoS"֦JnRU6k+mvHW8&]㺴 %=*,!j SxC08=6:ӑm-Mb`W"Y=8JnitVX6hAKT\4pRJ*U x\1By^&,EX85áyڱi G e$Y1S~tnt1 G'+֎TжDvjrd#V2Z_ j YZpN#g2[(Θ50q cXj?EnGa}₉JUOHS7al4gk,۫U`wA+VϚ ͜1B#gPopbwi'IX5 X؏Z'[I\|tyJe*%1bdS4jL7yάku'˲?7n't{>QhMZ^;3f/ \a3Ofr&>^A]Wy[jkZKFKVδ|,RݙNmҝV:Oq> =` Q݃rrsy({yzrGgyiLN>MBDוMF.b\F|4&DOzB[Nx@k_PЕ pVTeih$$zg{я2(sq p<>y0w&]zh]4Ph%P( 6dvHg B:B.'t|fbFJj,9(X#1(J+>0Q7& M 0z߭&>M}z0 ^B?Kiu{ 9G@}ԄCE(I(#FGfE&+r$c|ڌ)ʉ޲@ZQ:!m‚ ՙn6 ~B՝phXK* Jg@QFkcĎ&LRqVTW g^ndzFS#MC{ C`a$[ݘ'ao$lqP bav,CfĶ$u%1iIr1"U|ՂC4㢵bStcg{ƔG/6v`2-ꐉsM#s0pz0,$r`f *fH\z'>Ln' M陜㖔4W)!aєƓoM{g89VLqEAS2IE0/R!3gB\&DfݞМ "0gDOWG[fڴMǙS2gTOH_k0.m]uԷvDDtb&, %3!/Ҳ!: @ Vxaz0< $nS. N>J!*ce5j]3*wY{uG̺;"o#2Bձ(ؕ r`iρȚ6a\)n%ǹ;p(ɔ IrK=KƖD)2rnl !+57k sUc7 i/q eÚ|ɇ|-"A%9*`R  #c0f F/{F.&Gn0 rV+ZܳrMe_+(ڽLv/Vg¦BX>*99K!lTBX K`R5-5b@%lW7>u]7^ܰY@eђnu3%]u[*שncEK^I;,СV(Zc[+ePV<":5@U`FFX@ǵݱX;Fan2fMO9~-/k>zoE; ap g"h_rhEy,˖򮥃7 }ALL2All~0!G0HO~|f!X/#6޳7x3^iz-A '~Ǜ+1|&Od<>0wJ^S+ռ`3+<#!~ 2ߋҗ/3S[f^ yF>O)1<,+Z0< - ~w 5x4ByD4H%rd7:uj+M|,3+%|Xi:{94K -_N*v/ajoc!6)\bC+}d``JmC WeS0J7怖{uid^;ڄM ٪?l2F4,bJlaAV_Pg$Xj$X qG.w3ᤉGobn4۲b;7Yg9LeUlVv*S;USi9u6>[N%UҲEG!WQȉ68w=4Ycs4vZq^O}PwdI ޹Œޕr {-^Wt~3=KKz~k#?C-a4VdC_#BMݐ,¢ T[04NjhbHt"!J,R(FxNكN) X0bobm'7.afmaPX5L,CT@'I1~rcBcKF'*8gtRѨRQ5y+Urm<=jȷ*3G1B(g ÅRp g# &Ú0jh\{Nrُ~U[:>H>B`bR4YfL(V@6s q[쎪TO{4OYX8Fz)G[\`3, K'A$US2ϡ+)vl'{I\|BCbCrdY)RT'M^0ifÚ5c_kD=QEOVe{8 =a4qJ'%ʧ1Ŋٮ(pA,7i|bkRKJKjҴj q4cjE9nԞxP;v+hMaSZp{B7e^P UP.أ MM0$3Hӽ\S{)&OTNPzGip+ w[ڨ_'Nഗځ tB=;c ~BO9P,d00i%)<|c|T|bd3SügixjM_Ns]:>k M7D8`c,@~P9 2#-+)H O vrW U Q $h];ge=:^k{LZӅt1]h4{Cs ( U%%̘p+#1qr3§H]BýÂTCgC}B4h{-q Zج7-ssgߴ4_48;#`u,y0;r!}$G*OLtG{31IrAў~Q>Q#R7y_EPeXUt5ɱZ1 wj>=.ָߴ#N1"fAN<$'@t@P 4|:֛CH#qO$6M%855JyRJꄔc_>~n-wygyGl.eVe'KJ;"yP4[(jʀ5P sgAN.$Bn%0T*S-Mkҭ3]jza]3te'jCIļ&*LkaRs,"1rƕBj\ݦ|X^EPX!K7 Jg tRLVhbAa0z cmp@H4fPj WEyMTDu@VuJK !s-_×A` ׀:hCqҍH6v=` haSl6ngas45T (UK&6otA+miSvj.CmC c{\`oM%g{oÞGt-% Bc LnQ6>p8$#jpTÉpr 3np6f*8Ξs'8;+@d#n& >h{t_N֙JpYu+,ދy`_Woi0!{ǡ)0: j?Ey~̋ݘwG o@؁jy&Ȝnj?thky&`Z LgD)ae{vc y+~%h?"BПoO;|!Dޓ[xC>+xE/Y u-34~›+s\ p!qRNP1pUf ~α{-{fv!Ѝ+ c8N |9F(G0 "dW=뾐 e4+pkl`fRL4ƒV-i-z QeƢ\\e R(7_PjKbf*g" a<7\rc`XJK5zaV;CmhppZQC!^\*)wȑڗ(*w(حQʳۮc{B9}Lֿ*[ VkCxyA/zQ64hPG%nNT{Q(*uKd"$I[BkbkRKrKJVT7US&;}AP;Jr!0wM~zZE4zK*oʽ(ǝ"?QO8'Z㓨흮]UբRMY-x#ź=WuTde6pN X+Z}jޠ6ZShC^+A>`qf`$=0^!5 U)9 OY_ߤ;B;8"(+##~%Fx *p.P  AP<.&7̀0+œS¤XdؐR՘AGȐG?S TC!>ppP Rh P( " ySȎ\@F.iQF9.G$q1 HRtDrdDTZ="$lȠB/jȳ( *yÙp7Z6 #0rb$d&&S'9Vy qǹbc}D1(pYrhLJpLZ@t>QGzG=+H//#5pA+l+p*v`],tBc,TB r =ǐ8xbȭJr"R)ar$D䟘P߮n[ܾG~9EK-D vP/϶XP#$@\bҦ4mafFP( -L&%+z*V:%9$QOfmϪ ]p &dhN(L4HȀLV$4g9s ?\+|r37H%v͑Kr˔lVXfRCc>Cn$AL Ug58ւe7b4 6-A&KlaISXؔÂ*5u1iٍ')ꟊf 5a_ +)H/ :pj0lKyݓ=9KխK83Ǐ)=QLIebO {Z۽1Gotvmc6AVUBsTT@Nk ;0ƭQftxFdD"PYkZW6q-=Z\ߠOUCl::HkjnU歃iaFP6 elY[a5la5ihmkPSs6AV@[3T@v;$tAX/x~00o3Lo]`}`L8!k8"pC>8t }X PRVBd?A0:;aFQ&p8ipfӅ p.b>\l)9\z~Kk k6A6p VA0,8Sȓ ǽοC$Hxo\Wu3k'%pnۗp1~L&( );!b?7A$? ΂Wκ{yM| Q7Rc%<]OӋ؝0"L wYO_q!w^y4u /m;A@S }?p %qA /7 yN9ϩB;?O6~ #?puDï;ƒ(~"IxB1ScxD3|G?{˛|es;ovqWA \~Cg3à "E<'dq>: G]pAa/osK\w8Ϗ%8 ;%c"wQ6:Ĝ8!>O׈]yT&Kp2S99CoS p(ǸQ>8 !mF1yEnǟ3sN"i'crrP!Z8H7Y>,;glF~}WEr”8p OA'}$tv.I%i`la&S=qD?_OFû#΢)&sBXgvvF$[c3l"䳁2֋jY'je5vRtk,|M)] /R7g 8>ÒQSNMy-Fa?cX;&F߸V+fŸ*z53~9q'i>-㾡is 41CM8 k6,aۄl`nyhn +wÚ h̀ πL͆<..JЩf4jv j2Zkֺ2֟YQ̨MaZmSjTĚ~U1& L,T&%zs!Js!;!Kltaaj3u4ۦ2mڴf6hsgT[0#QkA(DrIW(4=CQ@a"(B((b) z0iVhY0F*b4S`:ЂưVx )HZ8,z~?[nTe] UV ލf 4̕0րx-N4X?/ &6Flȁ u6Wa; Njv( 0c*V`]vSa:^ {La3 r[ {:`{| {`KZ AY pflq} p8GG±Ip|ԄӦp 3C p=8-.(  ` w0k?;JG_.dQCgsޝ-LCw( >΅-pc>9~ >OQ2 v0;K0(^.oW]ȇ4n7 7jF b,D[OM|^>$sk*px??0,>Œp6|F(7#4{pRRx>u\`;9Y.q9ON!p üz OHb6Gs[L8q9H,ٜӔqNq8j2as3C-{=~{8Gcx).ssGN x)Gq9H 9짐}:v.zzg3ﲉOl%X??r39`!ُ {a7$IJ$rMT&ek8Bo[{V;pmo!&uvLي=qg~l XGYI+`9}t.V¯4#ˏcT8?ޜ1A}։-YjEOV)B)^+'ҭFJ.%ЦFJTiT9HjU>F1UjS&P:1l</}`l M-V3g-]]Cۤ`Z'G294NɢaJ!uSL^*lb&_dM'?p_N(,P0IތK6l[ @́UX>}6[94uA݃:ujR=/ TO|~e)H '^r#GSԿ'SO22\Շㆰ6j=X]ZЩ@DSDMlrl7K(YAv,)kg]Bv]d.]Gݤi!EZHai%S8l[,A1@2C,*Po@%zgOQF1d4$ݨTRI2%%|$(!D1C|d` la Pg&Pa<i-$\\s3-ȴp%҇t`R-#IL 2e U86b(|88CHj(D9]zlʬJ|I#Vt;cRIs& } R㈳OEf'Eڵvġ6'6~Y @!NVB+4@9@=:HrOR5Ir6 Œx\܉u'5h"]ERQK(ԹIRUt\x]NqZ=ܡr\! R@>Ey!4#ӎ(OW"<}zE\% ,{4}=z%%^n$nK]; bw!.O˽*}r= !g>S]@R?c s&ϋ`@"Ke|^b7AQ5׷'$N]; ^C8|r8uPy I1*DN"ykaa~%z,B'#243Y^¢f40?m/io5ϙ$ѼDACb)!;!&B+&Lr@/Oh@3YoF5 ]H'3+L[Ŕ]Lʽ)YS2flJn9ʡ0 2 ! ).` [K@LYY>L+aJ Xƕ3gS)W^5,9 0hv1t1 :B.tZ@ tBgtBg=tA>hm9 PU\Q_.U`U äN ˁJEX5 &Yz!у~+wpO25`9~U*2(+2po0l%0&AX6`pp&e&l]` l1#7(l=/`Kj!A` +@s5Y7&`˰{vDphYM;8x ;p+8JYd{y5 &&ݯC,ar"#/W#\ Zx? ׯoc{@s#Xo]`?L9# Swyͅ\>>Q[߸H.ƒAxxn9A,9O˫97?{ylxag /ckAex6f+.R~'vx/k&ZS~'{xvr\;>[s_0<3OL{#QW>Cw¾Q Ϣ].s/x\F2o#pi{8e2k%&ƞxp>Dudqlޡ˔rj.y:9Gg49YN1y1(G95<`n3Lz\Œwpޜ'DBI8A6oR18B-i 9:=g7W]  paw2o3-81DZƗ&]䰃"SVL-l\b _2(w#_'Qq n؉=qg+~l&MDX֓#~JXC iad쥇3t]<_@v~x}(a`?bۙ c:ǓPV %覐.*蠑vie좉4>|CPKjE!||;`Qc=YI~%i|hyMد tOBhҀP? ̤B}1(oN|{ \`r4"҈'S#t<4*Hh&Ic% q;ω'>pJv:C1VhЅԄj,BtYjBRk2I$M;Tpud$$CNq:ȴ{$j"T.Z[25}8f [M :̡ PW< d%C_4R -H2t@nN/F!E#3cEQ FH {3Da 5zX&p&K赆k2 (2<6a2Tә$-"\xsSmYcMEH- Ԣ`:̻ 0߀A|.m&e,e4 g m PaEgYfIVHFd6:Dik։p;OlG]vcۉz"W;Zga;B:A9BA=98HGuNZ9dA=An8 pͩu"g"GK";"EfS \ܠ \! A'm6 t?[|<\#h@?4a~.(1p&1h6o-bT.#Q+rB SCa3ZCs ['j  6BN``z /JE$Uj Tͅ%PeUVC`\ʕP*.AP3)P9)`U aZ:A4A:4kBBD@K*Asۦ3xBßP/P EY `[ 尴  ʭ@; tI[ zi\z` p"VÊfX1`ǰ{yI -RpZny0Fw_V5@h82Osa   lͩ0X i/l|6~ @F)* \t:a~LY V_(;] {$A/=p4΅pxpO-8 u`z@c-L]As^ˢ>2gZp .;p •}pݡ}9W~ b:׀zXf1{@׼˙Dž\M r)ܱn:ܫocp *[ j;, `1P:Y_Cf χ!0 dc y+?Ϗ4#o)>ܣ4a_0-vr7+k>ٿ"n Ty$~dO1f<āxr@ b9ܠ)Cj&ާk]69.q << ʫs(; 2ɗ,Ċ>O0W I9\sqZNIsuc'G8a9ȋ=0| ҃%p53y.b9x _Nq"9F,G^a}TzvNfqfdD`+^G= e,ɛ,(zƂ8vNBN$ۈe+r6 9l Tfֱ~ֳ= J?+l6d>3I;{.َ[1b3Vlĉx2?k HVKI"K=EqVޣoh9Mm}espXCoC oC5,SVbK/.,Njn"h'VRh!fhZc%l#TqJP#p o#`lTRkPfe6,}ڱ{qpj9դSI>TPFR& 9HydO5! ٤O(%uB=zO@ďDܸ/{lKddć7Ef t-EPԡb&TLQdd #Rrg=Ӓ̙dr'm/BHEDgg0ٵfu=kșy #a3&l@4 &l҆ˠe@,B (PW W}BzmERCs 5t%Ї  7L0r [0X.\zOp e: a 4fKKȴT3H2xc(e2lbK)6;gyx'ay.f8`{ӷ5[5 [C[C&zJm!l@nm R+ Vc Amc6f#&'LlJiz۱: ϲ>fod0 $@BdA&;$! BaAPwݫYGmZ֪mZkYA.~{|\TΥ MW4CnQ,s d(7x╒UtHRѥ o5cJ\n;s8sU""j)/e=]>FVE̊IfWKȕRQbVE+V,Sn11Q2oijQ€pC%l+eM)eQ_FYUU3jCԅU7ER u)QWhz]غ&uKM(vɵ'MɄGURx&T~iBy9Qƾ 6UQɢJWRSEQ-Ȭ'7 4FlSӚLmJՔorSڄ73i/6z B Quj̄f] KkXPüZ*(h k>)$, zQX<¤MX)-dcVlZ#xawA3`/5\^:cU=_Oui&E,aRƭ.cFt1Őx;Ҝבo@G~Mt,׫c+J]˲-]ےotk 8ȾllbyMkVNr":ka&!Z IldCQ'ZϺӬϰ_*heM+KZijj!md-e bW[豭};ư#Lfg;+̎Ɏ~3۞`![`s66/Emkd$fz&obVm.>q̡8qx.k9C9trac صuYT"o-}98 pzq| ⱜ\%%ll~sr'.}\"kXk]Ofҷ3c7s!Gur NҳL;gqPõ.eU\u["kqmM4ntgg*Q0"i\3Arr܊ۂٜFqo%rw6 ]}sϫ|fZwS}#$g%W`E yavyj$L,-<{1s?7?,=D_Li_Iu S]ɜ/&"}^<ÛG'LҍDF=} Xw8!Z#x z>]u| =a9=I3rWE>̧V >?>rć.w.z;^gxۗ ?g;C@񵉾 i>_|·}`-WkOv{t?85W[ƃ~^}s']sOC8o'_z[7{]GXWV{/v{!;g.ݞS |Cyr(_|COP;q~+/xQS rO[Iclpn\z7 q߻Gp9F'ƽf[;Rv7jqŮ̵VFW錃p\R;1x%`| R|)x=q^n3-ƺQpWJs]]i-Nisr'u- ]RG|:gyArPz7xi? njr6%4rWrqF[%Y i8itkV_*`?g]xwy 7Qup@Ua:̷";,Z[m\dwƯcU~݋p`nC81Gq0ͰSloU٤ nb}V:f+-s~+xWO,^!:3c;o@{?{zHzNWm3ۺ-_UjdE6&Kﵸ1 ]Z>ϯ}?5o>?}~&q$}ζl e6 bq jXVȴlD#J, hQB!+,٠9d!G51oj?fU_/T dwFpON9 q=1}\qOp|aZ*43?l慭SSu.W16eW2Ǿx x4[rY LgO[.UXŲɴOm #,,XG:iC̏!fy1jcTVbzUJ7*XUN*?ӲcneL{WdN Ȝp,sQf%5X6$2.U0Qe4 JS$Q8WaRzI &uN"+KNIjRf$y;>2= %6xv14ҚBLgR;ʓG(M S0%YS3I-Z'+ufn_rI3oY? Ip{rlv.,̠)yMy:%f U1V^d93deΖ+=͒3Qb>'e 6bf(:/bR#6% 69Ns0sX5%shC(CQ6 2'w܉s/57UJ %UI̛/>]\z{D^djuor &ȬOEfDeܐΉ,e1,ʥ1\ONYs]OjE,T4]BLE)j0͔"v(`|YXާrsñ\v峮i)`^]Bz))e$_>X\hTL3"Ԋ4Q9&W3bUW0QWYvҟQ'#?ZZpE^g&l[!X\bj)-& +I&)uE֍1oI"M7]ؼY2v^k2m1Jkտ94*U*̄m*ey ʘWFEdWRCB1D6ØAF m 2xZ i3,էy^hL;t#]_׭Cc^Ee`]%Kh*jH#DJb/m@G>Ih=$$S%E, ,Yhh;[XC T,Z#YML_@"]UX5UX5UYª\VUUct\ϊGX+ϲX} lhdi#- Pv3)-& `jzllɦ΃ns<\NygUN7?ƎVBc3 [H1[;;=ʾ$ao9{[:˞K}7g;شi]Dmd qS1~##va/p7ˑ\8Yxm c8zGos\ Gk2ڗbeaFm%lw\>8Kp ΄sU4Wu6溪+ra3s\}eU0 Uͤl'za~>}Arr5ugyH7nsGwrW&wUrr} n+} [)I>3hg`P 9BCxj|sy<}#O?ӯ-Mrt"Oz~ݗ[#q5~`^ $~[^?_H .#jȠrwk=!g9Ώy-g7O|\?;>O?7ؓ ;=vozv}נK5]ƻ=nFs]̵]UZZ=.q.uǼw]A~܎us*])]fr\ e.V" iqT u8bmw`Zkv׷noǂM IC]l&;j tDrRrا^vkj;l^[n'l|`/^[ܽKg8 uu8 >S5nvʴCmlUa:4hVXg5vY툕.+rX.0cֆz8u}C-7A{i[<0YZk9T5iԦ~jutHՠS*ޤl x^_+Q8K&r(;ǪcXCiKagAH揜qdBԆVmPHŨePzܑ7yPnx[ΈOpxxTy*l m,Hk8 uOqoON]'sqo=_ sgpA4bYˊXbXMGRA]D5!*')R$r Qy JGȍjTVQ{̎Hj䵒'ofO%MzI2sb ߋu:0kYO QK4Q[i0cD((76MNl9Ebd7;]j:ɱ͌9&1S(n?M ps4'؟$V&8$%R@e3( ~Qr&0UVBYJM`fb5vK8*6*:YS0u?M p}%g&YLk2 ̢|I$wVsL&-9Jjt)3Jɐ'!L|9f3;( D 3hIE&/N28|+RM4R oS΀Agvf$yTQK~.Yy%"˘PøiTe(!3 L12ǐR lӯr>8{ͺ=ku+}O,0.¹ϥb.ev%ĔYIx5V!km@DOһ>CZJ*dS2Ro\6ufKa@d2D> OzХuhu: RXÂrl.`+-|5ߧECiڞR֖VNc9e1*f2jfh+ѭ}iPwnXβBձXz+Xr/m?,E_VMG5՝Y J#MLX@",R.JƚѬȺh +gm VvkNV?Ǫ?V׆ziG< ɘOR 2e *zlĦ.ll1tRRY:vc;}G-EM4̧Vf-&f)Wc`v`e"=9П8<#`G29RƑsZ=81l R%-g*&#t˞ 9xnә͹t4ODv2.ťr>N%pS2mb> /ǾE9놜!↞4ܞE6r1npӿr}> rqex(rβۃ/Fe!]yx≩<Upkx1}G7o+HO_Stz7G^~?<<|hy/obM.ϯ7m#^d_@ &]ycY< g6{[a;GWѽ|? & :8&7}}է}?M>zu8On{Oޟoow2NF\lCWY{S7nUKZ/ sz.>wc"EH]fzCrRՋx ?s6yN8icvnw-~ft̟upAb3#Þ^yLoFlb0kDZmtHhWjjm-B+,Q=j Qy>R+u`.̑ʖ!?5XݓUz0r,5SaYJ@UoF [zvvT+USRS3E#?Y;,N`gIwfaqZzL3ze^UէEESg*uFA;|JnWxONO]83 Ʊ+ td< ǰ 4y@C W7hqR9$C\eCJ Q4IvCK_)cfzFyI;i?7{`8=C#hD˜7PjCr8塓(MT4*Q F])gt9d^#}i.zƬ;%|ZB$|(qWF8)¢)4E1/&PFJV4~aM>CNx9ᙲ dL(7{B $OXef6\\b?%zoŌر_pDEkZmZbS)8ʟ<@ٓdEFʈ$-*]JT3$FUla"/3e"#4yoMȉ_pe$Lc{,_jS>XF7idE=LZX1$D )&UBlEbkƶ]nJf1DD_jbO{ /M |*b2xZO2x f38f uF/K%!~)LOHeZ\SD&4HXfb& ?ě[Cq:oF~iLL`c"KhILʒDNI&1s& 1kbǛ<ٔXQ)I&oBJFRڍI`T~!ɗ>Cg>npү I|߰/ OxX;dSJ8dIK&1fjzCEd6)c SejlfљB3dΐe4 &f?Og$MbG2RY174Ә5Lë́46/B"̛nD, +2(ր'wuϹNuY-=2q8ͳYAs&5dAf$dCdSȈ> 1dJ&P2M}Kf]gqnͺhEPxsg)xҾ gu@ Tdw29 *)yD01%(c`eQ5BqVMj:UTeSUJUUTnWP~eQSٝDkuyu2\1)EL(eLëXCyݨGBi q 48Ұ}ԟf?R15_\Љ+ *hn'J-$ieLdL @h‚޴uxhbX4E,*gQ3Vp'X=Z~D4LW֖,XAI'J*'I?ZYڗXB8VNfe+gylc++F=߳cڿ*j+)kGD#cZmtYo `]wa 6y<[ؚ)m`K+׳fl->bזc~Uԑ@\3[Ɛejl+{

    6oE^K&w0t/=PBfdO}7  /VCx|￧|ٛII~B" ˍdrέ9AG,y' WQ2_*^:‹3{swri2/>d로.gYȣr6j0!߶)>;Cw睓I}jG[_JYC[|`Wťv7 y[^ŷdzAw2חFdSuɛzR[wΈb/~Yzx$ yCM5؟Ho{i^E^Ru~O-v?n3.írݬȍ]u]c-qr;]SN9'<"/?v .ܠp*q0e2N*wB48n]`#6;l9Jm{ ^兩DOQ਩.de8()WlVmq&mt ɷz/TM!]^1nvCmRli\٨zibfY"\gkv[< n]cj69F#fHkZ#*VʲB-S]%XliK 5R?4 x$=݃-:XZaF[fvS,gIj (դ|MZjeܦғ*G*W{pu/c@6dVci/tM  "Bhk^:9jQJ [*rJxL_|p[.lcP ?Mi[ꅪVj$蒪] t-Wu][t]!f9]Yna~!ݟ/v N g_(G1ţiEHS;]0(3IIiP7~W*_9Bz${(ן$XB/]39aFxR1tH%S8x!aD+{h9f#}Xjk1krI6IvLr!6cڠOD_gB9&rRy$'R>0 1w4:ܜб2GM>*ZڨxS$cBI$n7zEoꨓF$"FlbȻ&GĈKq`"XɂH"x2N$;02z6Dj(a ")r15##2b/!?5rBvMaG*b(!7hҦa I2*PHB &28aq>3+gzMS_<3Ք@UE ēOJ۬3̼gI|CuM8'tffR>$HKbf"36S3ކe6$3Ԡp39CT3s,=Av26uHw 'CR>;ճXLm %)&L,fBd$ds_z=/B׼fI^yu-&o9Emd?͜;ۖ̊TgS9FZ*ILOcJ:͈\зn})LI(%aLd%iSREJVQS&/O25 >$sYI}&eJNgF&S0)yˠbҵ+HpjP3hjfR3RjYNvSy?w}HٗVgӚCMPb6ѹD0% ,w]jP4q0ChGs$3:4Ѽ̿hx2}eY (`n^4+عL.f\#PCyhDZڅ=Y܏!di˦,esXZ,]KA\,_[TB]1EV̌R*WyO`~ºQlX6vZKYs_bZsUARSN, _|N7ve`b$`_V@ٻ謮$$DJ(q% ]hPJ-BnwmK9/؇c/O3=2&y֜s}u_lAql~6mc'0x SI\iisv{[hv&rlǗr\= \m8p> N97'ӅzaUpa?. 8w9s1s^(]ծO,!=Ğ1pnIlnSsTnYGq%\ ׿crn9A=9{ 1xH%.΅6;Qu],w;kNӄx`ًkuw^kĹR+\pkv6™:$slr uc#Qt/)ȠV!85^ &ѩ2*48F;pۍqI06sfCqmqbmx~w@XG 5A9ik@b.69)v*u5; f16d֙oqqn‹V@\C-^nǃ ::@gt^Z~`f p+KͲbAn3q3ۧf -dN.ϑDqCE*VB,S`rKX<5l2LM4Ld'rowLB& &@GcKYbI0W9rVd 3u7CidCL27XK(x#\h; a2Lp!bC tbqLhV# d$Sd,$%&fc& 2M0LC,fA6hVjqOjf?krnvvbskYȜD8&0!"oTe冫1T! C 0Vi-*l8Koשzz8=#ِŠ43=MfT"#щ lHxEQCO-hЬ1M1"9_}v8Pu8Su5S7T\ԙ`IŘLg0$ Jb`BvJ)@c\~q5>~zO=~U*7);ZiYcU _WKaKeK&sXʈ\rMs&M]JcrGҐwrWRJԥTR{j?5UT:YY<%(J$?h]SΖ|e&-+ Y 29L.`tC ڹGSriȡO&2cL=3[MV Y=Td5(nU=\QDst^!'k̬d%-:)Il6䳴Pܮ;TLs} ]@]>=GU^ny*2)/U_^~ACU0Kļ3$]#?.. ٿږ"0e -~.TSQLiIx%iKst--[Mvi̲F]ڤR6SbR ŕ.TQW,OWD~*GL`T+hrѭr*ɯ ۭ$UTH*ZCru_Ճ$TW=ML"QUPUx)O(A`N7&V1UF}7zTRUIy%EU֐Ճ&HM׹6WBmjj{mѱvko`zOP*fִ@ NnSMM5ՔԐ׃Zz;B\CdQ Y" E4T k≆4A> uuS [W͢LɨZؓA^!/q"bhLs:]^sMe -iA26Ҵx;}'4hu-s{#vU^Ga=9}HKbbl g`4B[V =!u ifpLmm|e୴>O.Z~73@[Mٛ>5HztH6 HFĶeL c3/c3gYa13ba#S3?i΀Qҟy01CQqጏbb|V0WLŔUL>I1&<ø٭LheX 447!'z4an8&3?E̯f~?ko:4oiG9YװŌLocLi@ *FQ$=r!,by<+SXRVձjL`\ϊ,#jpFkjFH ǐ1)t[E !>ؔ\6W݌yL\peݿXq61dN'a6 /_#"8*15$S9&þ1f<'R?ɞ^X\|jdNܭ NEߋrޜ?g+81NEvUD ˖w9מu8{ԫ\v$Ӹq8nZ[\в(ZMz:s?A.@ roި<_sxf&O<>k(@:\[{~7ړ58Qt[!>|VϮ1|y|p=rS07j_(ߚ+}a-2X#AewMgz͕^rz<1<߿x"_>>=CcLi^5Kx2Z)=nGA'ys{<.ߺ#g5 ?/-Ŀ(K\/+Z=lv 1]f|YdZ;] Wer],|!g}HNmEax: wxw.PnuZ]cr.3ťv.8ׁζ͙Nt '{͉~qA#|>|nvW2Q."Y.RBUSliڜbsɎ7ӱ;r;fG:δuzV_:4_lQ`vpNjsTu;U9Zu0m5!&;6[h6YDZ{ zJm}q? mt([tE[٬&6A_5[gXMl+-¾l;"7[E `B+XnN  ez_ֈFղR`V\Zb-43\̶6pӝjLi>3Mq]v K3_ Ua2S_3TL6$Lxku17%F(Wrqo Ģx0+xe3]i:&T]Ld&4Aw2Hc 70 J @6do 2Pg)U,dV$"aƈ7ZQ2oRu3TOCѦ 4JɚdFH}xBj!HŰ4H6%q͈ gCh`1PʵѬi4@_5YzYzڦSuw/5~]qX$'$t5ֈH-4I_Fy*ѠzGa3U[*lU$.S^%^SK~st,Y4&1*! H)D&76L( zwH+2[mduXc&ݢTDU5CIbEQkt*/D];\"7.9a?83 33ɰLfп N.$j"G\ UyŗHVKiB! 'orZ"+a ۤǟ,52)qwI%Gck uaAS_M,zfн T-e)iJSr)L&?V^Z?9ie6]Zb)i$&!dq)|$~SweRvˀ<RK\ș4d7IFDӰ} o)j?珖T1iNC =UԐރZzѱ7a}IN,%lZiiGlZV|(Mz 8/db-Cki'ݻSٝKIm MhŀE$uax^fd `Nf zx_=ꨮti Њ7FG36L 4)5L!0@Ϙ+#?e~<}i΀*ߏ$3!sf0{G33sN˘]ǬǬye.eLIҎׂÚ$=n4حG ĂpG4gE+|8gt5Kgy,3W~<-^=QD~d!Ou2Or`-a뗲֝~ V`PQ?tCDv t(T#eO6vf5#slC/ I^8II`˃Rg6qF$tΫΞY+80N9SNn*%{e>1˂{r=aw'ژ=9ո&r[0k7q\}=a6 ^N 8'Gngm7 <ן'*>^ƃ뾜}I:С'rO=cvkO ߃|;U|:x:,$SHqo0+}n]"Yzq7ӽrϹ`\)䢀A"6`<[ѾkyRc]e׍I^4x"OY yԁwfwxmsc?@ ^% 9U <>m;Ltn1MJY]i˝Wȃ. b{Pkt߿kQ*٭rܬ ]U@]d LsαYqNsS$;cf{qH! le WB/9Ԣ̙j8Ho(amՑq-6ڦ@{S@qz |l-v%QjCs[94̱R묵Cq.{􁕁bŻ=(Iqyhmkdd٠ʭUc_*-Vl`o},Zd9: "Qo$d@&}3ͤ:.t04rSI QFjTiRR %UV+>Ql`1cuLCRiH=HGH|/ &e3,z=,J($/ 2AjfN:g%ISv*<{$^DdAtGI{ԯ`N6si΀RKY.E9eMV]Hɦsnh1y{队C~"aEA _K6Nud?J{d}cE632&Oe>%y%;.v%1pEQ")I$|J)^4RFk(Ji^Gc}@1Eӻ" )* /<2H'bKEw"nTSKU UT XXfSnPy R%REL*ah)K+m7ҵBҊH,! "QIzSB]&uUR׋FQ7ntǩn] U02JJ/!Rˉ$艺p;ҧ};ӘFc.64qjdM4@﫨On*jQ^AQ9WTEl {рF4EŀvQL}D' 4ѳg'Yu$׷h `3߭IѾNߋS3LULƤsp>`5܇޽ދzrHiln;z6d慳0%,di KX2œX[w:snc&7p*Dbp {BvB k!!ݜ}C77n =װV|g@+ih];:;59'8`g82)]9çqj62! k,;7/u( ٴd۟|BvsqN4q^ 4phX[8tN0݋:M`9hW:qG&Wqnr.c*HYHٶe_ wL@jna[un4RWt#\¹ԟԀ*@ֳ-A$^w W2}\Ʌ90e3sN։8N:N9 $! y6`0݋]qhItL+t '{{n3a~l&jxYh/vs9_vőypUmU`6 6b3~"fc -q>Xs[v{P-.@bHk[#;rVdVn^gV hM6s,3z3a3Lsi^3o2pD Xl'<͓n\sjd&k[h58(' #uՊR+N$FjeԨTBrClEV*t)p|2r gv$ݮE:0RJ1*$\R](VB o5Seli p L!Yڑ1ePm:QMIőED( R(NDU\uA%4K^$:[[%zIo$ Yב^ҙ>{#n SG~,];.'*RNd :쐩K<Juڡ^rF1E|Bku &]/ʓ}*tbnD$z%QDY"Eu&g/Ȉ%.Rz(1RcĤKɑSsn;שYLpQE.N[9|w}♕7TPB~29Id&%R:GJ+JbB{휭SBѝ+D%֊Ll8DXD璸·p W "KҮjMw:5锥SpT&9Ĥ&GI,25C+6[>yɡKvr%*$H*c:vSSMMmTOzUPy,S(%R -_1=TX@<2yбUNώuw";]TӻR?yڟP)Bƕ)S@z!EĖqϼ54FGk -9ڃ&ZF<}i<~ ?WJ+RrJJPF IeV}/LwsF/#nh`POcJsYZ>9~5 +I"ٰ_XȄ&0-iYL-mo5e '2i 63t1<ށzߋ `o\"}Z,ba# F3.s60f^Wի]STGFoawaf7G]n.hD뻰 zլ:I__P֗&9$`Є,/ {pCٞn}DM`9gs=&ZD0: 8+Tg=Q.yyi8y'ϱ7=P>ϟ":DvWbRrJZz̬윮yE%eU5{ЯSKAۆ >b1cO8ii3f=ky.ZtZfo8`㦃6|ȡ[~đۏq̱I'rgu9]reW\y^w7|mqC?O<3>‹/k?Ov}_}wϿ۟#:DvWĤԴ.Y9] KJ+*UUtѳW}> }5ojni0p!C 1r1cǍ0q)SM1sY̝7E,]|}V^~k~t-rö~đGm?zc=N?OwϿ/o~~_qCJX˜uSC7-:zs;e;Lf%O㩕/~\σ>=龝?n*=[ {gO {x1}8ߙuïͻ?v˟5owXƻ_5|ߎ^cg\.yw g9_[|ΗVGwcɧ^ {U3c\|W}7>W:|{^_nJڌ['n:j?9욯'pKU]|ַWܲ5w?ٵwVz~S_nao\u\ݤg~9v>\%myUkuƿ_s#?,7zӦ~zGhB×]ia'}7c环朴틅ҳtyk>Z_r:ق|Poc`u/ [pNhq3#nюM.;vN^Sj>03ŷ?e~_q]g814jюUB3mc[|_UiV3ҫ/D{Ӓ{~PCšƆ3B-mDž9ckh¼B3l]h}CWfeh֭Ñz?}?qIW>dž74dKh荡ׅO]3cUh+Cf/4z~j]C77w垶=ệ'/Y[~hI߿w׮;.==N=݇NˏiL ]]OQ~bҲ/yO;ǖ\kzڍ?y78O/;/=掏j1\;ۛ*x`p1g&,iS>z~o=ΗgC7Wnu9|y)?UIaBW'Φozqҏ_ro8\+ z>{|\{ʮˣϻm41\_˿~dP] ݹz@-0HIJIww 90t =Cwwt7 Hu^ӹkW I%w*5vUw֙W'}1eK RNA H|x _(cl7Q^iAy\dbÐ|ayJmnV{R?jܣ ;g]h^X0o$+|zskvY~eaٜ~.6vf^aTׄvm+߇䇧v Q{}sapgG}ߺoɬxtƘLFbqWjNF6fnZ ACϴDvR(yz~Ag=3\m<* V_Vs 2) y~^*.Tye~sfO~/COLv;m>)bqqt z]f~ܥZ;58@O1;'ORiKм kZ1eB5nL+|D?pȴPgDߥy ˺HQ|d}<ɇ i@s^ ,*"fcM  &MRƭ2圣 KU(oQ4Ͽ>ظSC:|]eWW4͖tQ!z ZV9t5w*!o&nzpj=fT`6ROn nb+gm6t2u1XG0q\T[HHifpT`|X >J"5@NT AHtMt ̴~[[JIVr%⢝'(x݁8l9J(+肆hh2Xh[$HC/9Ru,Ǘp@ û7x9@G>i 2|V}Q0)8dCp$Ӹ5;`go -~ AeHJLUNеeacS²GcJl kjpS@xq@: -.^7YOc|= 1Qe}U_:,+ Q ' H t x?JoVwf?o5IpL t/%u9%7;j̪z LjLZe <8 i!-ae-U*"^"cPi)G7p64n,6{ SSɹТb ݲ;ժ $D_'!9-3v97!/RrEb<đ˂( FjϘrl`|8ήk,!2o,@QŹV+(R+ZwT +M0.nû~ .xgcJGN_Ĝ$$SC֛,??r4~^jC5`&5:rQ=!IWX[έ sHys}j'R+|jS3*F-H2ô0Ѯ53ڭ' O{yyy?(=A1( IHzv~7O8:yfzP⮃]2Frb[2n[6l]1pPw.CF+Mw}:+<)Z9(ߩRܤSQkԌt+BͪKGQFG! zrf?0N}]k_t )NJT̏֨ n7hlhwlqj0ߐ>UZ1S~SAErw|7*SGYvr}n[m\T90kZ2>nD>'_̫[αðŢժSzSxrsYJ}׃M$dxjѩzz׷{^.r}[o"8+>!;*6hplVmkoKm>DJ/AckeO==;xuvmm~UEɰi8JVAрYNWj|lÓm&C ^Ë5w ?:6tnm6HF/> aLЊ|ӬjVAi֨M0&O~ȿPn(R JKYx|ES%[eL!c0dG{]廂ݒZv l)mRt\Ww5ZEy~7\W])~s V~`әdv_DCG?ƻIu|g/ǀ-AdOcecbmae稸쬰z`DH_\{(o|Ĉ6G!)sR0%}PM-V#]U0Skp@)A#-MdH_&x/\+4XG# AmU15ВP]Ie0Rcy09Y? b)إ%Ip/]x޿NF-gVV%bWN9P( \2- |/WY,7 Ƙ'w Z|5Ur ˆXCȽ,$`ZQrYU,BOqj ަ6Хǧ#)-- Sܑ`_i[ߌG7w{ԗvs,eg\FDeFbBɳ?O3=ZmYPXQ nNmOtqk vl? P"9=1O@K;1|ZhRj.RhO7+(@Wdեڣ|sB2q`[sR~HԽK&,I9)F+7̯ܰزƭ!ߧ*?ˤ[?0 DҒAmJHxGss1=`gid\9!?(ҥѢk+q1rol1l׭Tϯʨo>_Qo}j˓ӓ/.0=`k^䖩Y3*¤ )gzvk:vUXuu7hw7tյ*54nQi NtNߴV-S‹&0/6#3]|<9 V)H8OQHC2v}Ekm'Yʚ  ^,dlU\ִ= .h.Y.:(,`eqyBA,&!zx >}{tdե,`zS|>Uӳ9c_F?m 쵷L56-UѮ?0X5 σH%Ff #H< Qc,xq9< &F?B'i j `Rs#e1Qs4n! 2 M_%͂G'٥Pxqc;;^>c61PMi5ЕU(*)ˀ`;AHH6\{'C7< Zû&ƨ<@M $8A[TyAOt?J@LBHQ ʉNb$"ˇBqO{.Y@XRD^K$1;1Pg E@E Y XDE H<"j ODi2{Lep=OD@N O 3Р\`p |/Rǽ<3^  B9 P/?}ş^;XgmݦS}v&kղwŬ*`٤%pɨ/xZ8tHk,Ku_;=x;YC8K`Ͽv-ݝ7]}aq>+fAK&!aC~ш}wg ep"_Bg]vFͪ5{) .%t*0o^5k;e߯;ت6\9_@E q{zB_]w!x!έuP ᛏ7p9 ?J0/K7m@ugjhe&ਈ9PA3yb@"狝dDI8H=Ps)/8&0n:hgZmT[fQRQ\דoП_" s  _) kɊ qZ3`۠ao>Oj]HnUlayVIiEYI[y~[yaW~qo~A %В*~|_BӭsxWE3fR4cQCa=>X&'\^:&ª̲KQT΢D@J"s bh ,V<,U] gɬv/w +)O(˫̵J1oh//w NAsjHgb.R!I<%M(CBCUbSVgA[pis̗tǬZM[ymW~A%s?: ϩe2^(t#|dP]WOSoXh- (KFV&`*[:toSAÓD~7͵,O*9?Պjڵ%ˢMl21I~eUɵ%8z_*_cDHK)!IHyvn'ղk9XZx>4huWI6*{Wk 3#B c!U~  ^ nnLj p)! H{zvՕJGl"BuJe9TbJyVL}!>ܽ<(4783(5ɫ٫lx?zjL2}hi"UXl- v-" FZ;cDLC7A=ݜ8x7 0>~61:YϜr,̠4$2*x|M|FE\CIxSyH[~AQ"!ЛG!.v>ݩ4mon1oS,lHU )׌ )2H3wͶ/1LGe665D%j2_?w?<1HOq֏ YdwK`ZUctS*LrKm-JʍJtKk4kUk4 Ž JM e:Rqr_}#.Oo2ã?.`2$:"[5PYV .%:r/U %+0I! vuۇPO2^lX'OB,Q̔S𘄟qP-r@/հi7n2jBFGt'&ի(ՙ $wZrܦoSpoEm2[P] ֙řXNzٹa|~!aQ=q vVִ "ј< ~%1xВmJ}tBHƫq6x~O̷'';7bh3kmnl`ZgT^cؐ՛Yןm0n8EI4e1spu ^]`zg"OLn0]Y{;Das]3"S)yI ]x0cDEC7A}*yn ?rVr{lo,-I;.Jϻ"46: MOĄ:%G9m;zp@M^7B=*|j'j>R\\C2]i*q:^x㐜 T?oh[lAkNQϩDZ'q u?(xSύK t'WoV~x>VZPXR6K ] I OwyE{fxVb1=XL~s }~~FZ8z%* 5<3C̢‚]3p~>%~_JK=|5_?QB.T:`&~*1ݲb9UϔTx㨰hsWw[hXSHr}pYM`{_WO_~Q"&ܵsȯOOտ4A_/6^:E26ZA4T$."+!5#!*&2"Ԅ^jU`؛|ϓACNK_NN<|}ssC7XyVNuR6H=0(W?;4fNvͶL$ Kt;Jt# G<)^녷=yz{Q?v hYɺVi]V)yΙF~EyE)}).Amw ?=:tvM(P ZB]ٿY[j_ceQehX阦]革VX'Wݝ'[ؓ#՟;)DӒ\ Hudeor9?%O*E=z<U-;u1NBtW^xO_h}D`~@!ϒB93Dcmu -Û9.]iQKIg e/q-θQM6Fj24Nt*-Ax1A`` ^}4f?~#F ;!/_}q6wN*˛l!+%|V>bE e-̗UШeew[o7?eNb):H[n෎} #E~FC HFrq$Rp)w_m{oq nɠDU-duT uM5-Uwll]в[>RabWX#DHG NT|x,y&׫ہ{o=X᳄ꁊ訩2X(,` P"E Dht?3Ak^2$w2i2ܧ'8`o9 k`g6^vO$J/.&2`--N!/ "$ѓ RJ~?$e2ܦge4mLt\_2W9VYPamNI0SQ>!~?DGc."HWIDx%k0p/[xDc W- xO8) Q})ʯ@Folq Gze׆ #>p.k imxL/.۫R(|% |w@.? q#vСc{} ܋ + D@IjgÅcpFa*[8Mt uJuf5><VV͇,PS<\CXvM6m-=TiE嘭[,k7X/i,hLͨ/G)֬MK)8.7=`Ul$foU{$l0jA?n^aVyF 316:mSYqnR]p`ugeg ϰ/"k lv665 6v2HL滏iUyjt(,x׫-U8 8Q= XߦM/A띝^`1߼u̴fM&m#x!l\FypzKhHhTHl@g֒۟3%18А-J>8~NC Xno⹟EX h*Lyal,.Nޞ=QAmz-:EM~B8Lk:@g/OwOi}xܧӿ ψ~D_0!-<4ꧏu;ڻ`}-L𡵆 jJʨ b\L\jOG%?>4[1n|xa:NBxmenq68x} /5(6N.0*3jFĥ"Cg0Ljo߻Jwr/F'ǓEcU4[Q:Kl%ѯ=6kEʲHM7+O5kHH6J32 4 #gjr\?wщݸR.f|bI(fTk^n矏q rHC$[&Z$G[ $-, VS!G>];G!D3\ey8Q4#$Й*bT.g;&c"❂b"Йv)v=6CIcaGWCЭ#r+Wg r0 |j͐TMP2,Բ1fX'{;zGFĆD$;:ӼRG'nG<x\=!7CcON}A;UtgUW'qTQ]l`Jq ù'%z{:ĺ:܎<x]9a7Aݣ?N3PW1eeh+S(ː3MTMuÛEۄ#}B t' {t8G?쑿>)pb/ռTgG^_idy\SUY(WF?3M&1A-2/`˰ hʴ˰!dw"Luhѩ'.t2?.",[$h K25 񌲋IaQ&a} G.Aew7?}FǢZA "yK| .S38%њwM4!b2bҵ"uÇCF<ӐBˤɆo|z=_2VT+yPw'&Cg[[d8F{릅%iפ* ǫGE x&~RWJ[io6>?]5CzXlzhok:]gQjlX&G)$ȕT'I %fȧG x"3$yh=2SCAZ&WO<[2|7ks 0W@ٿK moUqh4l4n Vmp onLom-/ @ $f<2XDt7Q Jf_Ϟyw?qۈIN~8ð堢ဆCuW~ L   h l #zh(*'CZȑEjotGM~";<ӼɜެVyQvEbBb秥/ީIOޡY? EIb&GJ_!ZJ\c@X{scifMHtMR`MQE ܺԆfVv5 m#I\LT7 %Gd ۏNiw^0=uh/uI_2{2{vJ"j"!YР4 -YRUIw ?"߻NNcjW`>wUd8@Ky_,D^H"Qb-Ҟ R܄ DH!pgM }` t*LAȽշA0sOl<'9R\ ]H)bO!w,)C; /U`! Łg~ @S.{ &` >NjOJ$Ab$hqփkTp<>+/-| 8/U. A+d[̠q t0ѝ`uAan!-1R-8MHuJQwBv`>3Gj&aO4A%_` p)\| ڗ@q@]8(AI0~}X/9M0{&* `hz|{_ »**T"$-#)?*.7/&*]v[fQfOv^;*0@:w)$: ,&X>s`b (k== /m_";b۪i[*R[2J ]r?FVW(*MR0"#Z нK ƏO3`|n0ʿK]SsCG-}ϛ:ZQ2?4(**ש~WP_VXTӜWX՚U0"c лC Npxw9o 8ȼiɺei»aa\WZъW[VZܮ?4V3TX30SQ;`AI&4`pX=<O[Zpet?17~~ni-lf裲9;U7V4Rn5PURnգn֦mآc;`II4`t>g x^}!fUcQO𛭅Լ򬉇ִ`R7d\+bT=fD =08+?ҩݾEeݺNmˬVmwh(QO nOO+jahWͲ<炫ȌܤƘ+j|P/ԶO+z[ȭSۮҋmQvoP[qV_/ܰ*ܴ:F`q(8=Oߋs8끜W^/KTwA) --ͻ=: pNfDlfgZvjq oZ+.:k\uc`AM׎1ytn0]^ cj:X㘟ؠj)βc`Rk2S[W_3쟯3 1Mw柃À}RA wg_D9Ż}4Z jlXz< >I|\Am`AP,.`7;`s,auS⟞Z~MTGam85z/}*Ws2Gc[WE_i.$+8ɸ2$Ѹ;4h*$d/t a=J V!qB݉|r{Kw7S9:"CTTt K=M \mh/dX(pdx,.b3b ;`2^?awl_Jf87HۓO-q5x% -TuS{O?.ҎI .[7 A ~֋vG<9`.Q@5 >r1D˃;2?4$%RX;%xعG]|p!a! |/!=቞ Dz~G<9]$uZsOO+fyКR**R'fk`c w v{8D`\0Na9 d|Wuw`8]|2SD0IF)3FE?mb9yzzBܣ.HGlu=v0:n !sdIKaI&\%[ʾE1Y@+ݭ+zW+$.i'8c}>8@o'-KOcg>;pΑ75)iI/,_#sdKUo>eH'F$Eym|\\p!>AHhhCqLϜa"p8K~H x=x"pUև,a[ϗR(*#b꟢H0ruv 1#t Qڄ(qnL^a"p>M g}9LVF")^]+j2'BD _,h왣ailfa3J&j&U##b'385œ!"p;E''Q!#GަCHgIn9'5sqF UzUY:x)ĆIeN&%"c@]N#ç/ >$5_ħQZ]db^e6tҮrStR󕮌 *ĉV r=\)(2Kt"-UH}'9eph+Qlx=j]ڝ֪N.Rn]EuK˘,9J)ғ -EH]= RK\%I}L7B,S9'-'d eUuUuTuQ 㦦RBx4TtԼOoϊ)2 R[A"THڷdKt'–.-1u[z~rhITPwIVLcIUFyIWA~TEjNCl][{j>ZϏAoM"HG HyM%q"d zZvt/ 7yl oIs)o)ok lHX8K؍*)Rtwwws A@AB ,LD;k[ Z_3iSOu\? p"ɻ8+<Ė"5k[yURP{g,ʆb0ک7i{`+:cb56ZZ`[cc/.8y`p kTh pSp$n( Ah*R(rh!m0Z U1[K4N۵qP[ӥ.q ʐ)([BQ#UxQ 9=ZڠvKta>;M0H#$ 0^JӤ1OFeձyәCPtd@~ eF-(*6e6\w?evuU./͖\>v5w^4s^3uņHW)[0Jc x1J\wbD,lu ,Fu5LW=Ox7_qf~ro׏V\g.Zp]Qld FRk Ʃc/&Za8¨e Z )[ 5Z kmwj͢oIϻ<;}uwtb%c6 `hYfLTfL5qL[P]NY(0Z 2_ nZ촛w74{eY;?y|99cǴN{f0a4㥙0u7fh` f؊{ʯ$/'1( mpIiw=`Iﯾ}4ׇw^Ao_>E `&I1a+jpc Z*,fkΧLȴS5KX eߧCS>_+Q/f {?`, #`(=I2b< qbj"'<Q_RRf>Th z:@~g^Mz3<.l⽀?1ïQ0_04/BY XT8+t.U+SV=f>3mJQ5OOt%= H8v/RƝd^~'rZ0 g&a4? & az,aªl+Z|uFbk?Uk+ |,=5p*)/A\y膤[mi7d^ Ξ ˹Lw<(L>.ƻ'5=>`o<<5<9.>-&7t\c^ܒyſ lS鉘A .pzy __&=>/pƶ& g=xϯ34-&%9);6!LSzݦʏ߫2艘Nj"q9 .xq`Byɍ18|žoG/%|ڎČ̼’ƖԆ I n7hJVT3W/NG<:A.Q;4p0mΑZ'M;.ٚ7T (:3zQ%@S2tna)S!K_2|/[yW-y_=#XSߩm: 9dpt\8zo 3 4,q+Eh%W8VնFꊄ5k% j6eE:fXgx@/K#]|Ν8v>@3Z(AbnI1(J\Lm;[Is 68Y#LeXmxh:S'P p BL@^ B &cqGv'C+43G&(`+a-U#;a\ctv`v2 `0-&tYFVfl3L4_õfb?DXM: s}_3^Ay^ CyrKm7ּo@t R迍i0Us`7"M߅F6_r<>St&řMY_hƀ;qzu'>"/χL DA ! a#a `( Hcgv/&u&KĈ`8 80[IX'D^hAy YzRzΥ?˱0Ѣ8y!CٹQ2J&MJHiKۚ0%Si-)Go#09$#7 E%h^1=i.syo˓h䐾ά挽i]ͩCy)SԥϯO_ȨO_IK_ F20yD!#$#??,Kw_Zv{<-9VE,K.Έ(Oh+Omilȩȯ8SXq<}2k>2{9"of0l$, b-'a𵇟fP߰͝Au+M$uihs7jp 鮎tF&4eV**ʹY\(Wnqޟ` SXIXFzvb;q^xxLư#ӽ6#Z{C}:c(-5Q Y 5EY%{ ()VU$h./h)=p%i3D´-D,e!4m]a n{'wR]=9>dD|{ИY]P^SZTUWќ]]Qv8l4eijŌ` # 3X?[U/ <9BS֙䉓Jg鉍 Y*;k llQ'-17%,3!/0f8ril͋Ҹق̄`,#s Qãpo ΟUd=#zb~!w5ݡe]1ɱmi{3ZrtD57_* k~^<[ٸ'u3@|::*xI$s 7/a6 r#約Nu3jY;R6[u !:'#1aaZtWuVxg[e`A Ej_n]N &^7Lu"\?M˗ p*/Ĥ 2{Ǭ4N;z:  J98-6r0?)d2=,Cr8,ϣ64`*ai+>&J0tK2OU=* ϻYgsM9w&:8TrdNhyTt'g8Υ;]Ir=7~3M7;n80v M2 =dE:(7c,_xZ+놳i5/ثA>Wdz^.tp/+///^\,sx$aS fSB 1l~ 7 ~ i =Emءv ߩfMzg"3m64;M1tyjk}nN|a;t3zyp'/-PPm;u7Y\ ߵE}7 n)Q燧Ǐ@UMD۟?+03h\oa\nv'#t@(Z&fN^b]Td [ Zc&FeEa[v%Xj%Z|5EonkCj5~!ӧ\<P o8ۨ"p']0bE6tAC{4A;Kt4Coac 5C 5JB[%U_J H:s`"@-=ʞdHZ!An!P"4(Iv YЀ8 ІKЃGyU07oL]XMKP6st O2_~E?%x 6(Jm(GJ ڨΨ:LhȬf[Іe:J'QL,mX% z1@KioVHG0E6>QJwP+ݴҨJ'Z;P^MЊAН80 㘷`ʖ͠-wР,33: {M6LFQ4-Chܾz@1 4@[k%WH,KbAļĜ>oh-a0>Yr?: mZgeN@VI4Buk&gd\Y5)lHfo2Fs2sFdfe~MhFeSu˂ ݝ%@c}N-@5]}V,O1 dv]~+9Y9_MQ)}1]Ag^2ڈѠ8zHӣn& fE3.vGO_atCT5UJe&? K6m}Bij\i/ʳT[̨|SXVdJ-qKTv; :EIz R`MVsaVY۹$-gעK‚sҼcCOY?lj|Z?i~g5آk;TN=Di1H1R# 81jUOPo8_>?=T~WsmOA#O|td;o>3~lsFΨt& `Zex-˱kο$:/9)-0E_'r^=ZݺMߺv>aKǛ6>qhiˊ=74㎆w<`#EFAj Fi0QS0U})Řo.N[LT⇰LE/}-{7|TG)BTe~*o^1TM4?p f#3mn:^ t1}1yqsc~7\xϙS!]ǃN  z:)d8tp8FFЇAdL&a6? K;ҽUfyY;UaNҵ@HD' NTjh?6v,?bd_胨!#{)kAv1yD, ׊>7JRiV`|ҤurrݗYʌs86s84` u$+\̾;ocۣ;buģOGܫyLr2oݓCYIҳ|$Wt%6EtwF ='FBS넦٨ՐdoNF; XHFvJ-|G$>풤ۡ~D|*OceA懋"{s}2:B[S#$4&'&&^MNxT#&e%6 j0`#Ff"fs+ zɷT&ڌDƚm׹kUźu.k̬K[֛Pz,,JJiʳҴo eˑH)Ġ? 㙈DXdMa0:2"94;(s$ Rj~擴̯Iх9Z`+ Xstpg@xo=,eu?H;G09pnXĠ6ASn{Վ}m~u-ΕM^% ɁuY5EQU5ɕmI Rc+ң+GϤU.W`D|o鈘E_*tDu׏ >8}\~xXoXFE~e`Hϼ Y{2BR "bZ#RΤM VQu&`.^Uk;0: GwRSf8'4jFɰQސu`Shϸdȃٔ1>q= wz>%xޏa]Lx[h!s'F\+" -{.j ԌH(q8m4ds"%XgL`0N'Dr<|1h#Wi0~  7yk+ }u5k&-w_vTKЏov!&|xxxù@Vw([؜A_賑u?p4.4?bG;Kf{5Ļw]Bަ܎pbt+VNw'm ݪ%B","rxFT <p@u{ESiPV%:%-QU QQ l:ڰ3nb vY4.q,ށ<۱GGxEĆx@3<ifG4D.Si,QB5ZԦۅhF/6 b(>L̏q[x0s p`# P$@#^p `&!*6n'IYeb(O%PuixЄiYљ BG1dL'ax$iPOwѡ*Z35s!P'JfjnCm~h)AT vMpMU~ܶ:mAuQ*n 4FFmI4E3:Vf@]fdCKWN4 AX~4@m[+:-B%}ZG״Fj j^^Ѽ'\GyB?5f5ք~hM62HР ZIѡ:09:sU/GoEmhT(Uk";DW޾w|ݱKW/پl·:?YUgM~Aĩb KҢ"i2 :9pDU_<˦ bK&m;w6>$`tT|/ 9[O$bCG5!o%5ڈҠ8-zѣ:z z9.'.f)#ӢSz#N~3]MhNwޘɼ6C('5: Q F cEKUo%@y.i? 9T~klۦ0cӣz`J)2m9bZwgVKJOlP-mh-HnT JR#YVCM9;l#7\W'l%kT:Q{ЩʾO݈s3l&<ԛ{`]mu[z 7|dtJ>|T*L4'G;Ɛc6ҚK Er: Vo g5M=a|(-`J]ObsW|{G\WkLoKcAQSE8tmGǍ;+ + >1fVx"FѤtΐlRCZaFY])iέ)E{w Sb/T>-DH[UIB(:\-LWQóFx&fo=YksEPVo!Ũ3/ʲ-'Ѿ%+å1.§:1"3,phI⹰{ᅉBSѫ$ ]7>LD!eQL Ւ` }Bv-<-kTzivGX)kKs*-˨,No K=z'";}xN|`^ƺO~&oO9$xUn'\/Nksi1 C*<̢$֮(Ź ۣ$ط &075$+/<#TDZu\0UtLJzNt^hw+& /d_0M?5rx&t\S'[mNZp8bt:ZG.0pvqCc]$EuK-! +шNRkWUFhM&9MfNYNXMZ\lm<ʢe0@< pQ/ Pu 1n:laMl|\wxLJL9L)LeZLjL6|<=utuj pi-WnHBo9 fz;)|Z&xZoZ;<Zi>YC]?VМy釂{W pz`${Ͽ ¿rA7Qwjt?fXlf-g~z ן&XX}ITeob?S\):p WoH~  h $Ht#N_^Q5_ѡ7^5f4XdȢדUm-]y=Sq=KKxdW $qO ; ?~a/|!#2 ,Ph$}Aj ԤQE}Z%4G[YtaB_&q gގI[EXu+ z`?``Ԡ,<u"*"Jvk|1N7ZBdBS!*F'YtVG'}&tfEwU`?fq|M2m3i$à]~7D草|֛ѽ/Ag7" Cg(/$ Y =hKtݜuٙ?])߬rEXΘ׉}2ks{>w&&%OH6+3ϒO%w7C KF/!2Sa<-j0,{rp*)ACi"7Rl_X>Qo+>4xbFM׭Q5Jnњn$  av2P+ cdߍo'PWs'.K9(>pأt~]FnٞUa{UƤ 9KJP#ʍ; hNBN"1J+A^S!҄u#3T@xٻ < n^sטtݫyeEQ NƝ9?&+ӽN$ΖA`hd l E>U:c^zg= N{0:>l|qG^3:Go {aoTЊD a!`;SxvdQ?fb}3Ud2_bdxXِtSykF2>euuޟ-.A?lD'``" `x/Hx/I|p3˔J$oqj"óB ( ۭ{vdȡ]GEGI; ) i Mk 0_ Xu1L .R7+'B,a(xxqQ盧2MxKTZ8xmAteyC.kx&NZЙ'={Am|R~zk{LD sWJYQpەp͘gV|{h֚p㑒8T9 s\`c] o:\̈́[K׭vW)^l,iKmkuۀc@aP}H D`#0O>Ϧsy>ܙIv/"D_&[̝lJjNie5|{UYW$v6l}Gq4y ^QqdvdƱl=O_M ~K#JDG1_{Ħ(0  ǁ3@` &}p8, )43g4YiG\4ț[y(W2d KҰmtVZNeg@U qX̉i$c>C2Ũ>D,ydI,$fG9MfQ7CyZ'@% :pyxK&J|P&QȓII b!aɈ&3Ev, 4dR٠6 jLD吁6r42%#~  )D%¤R+L*m¤@ !RZ'DJHi )xREw(<7w 9!c .2"3n2$@ H7M IziL"Ih/[}/Qj;vBϪ?>|NoTI* !CuMW吹Yq/t' ?A!L&ɓ0O+EHQ^~CtW~ Egg1O:D>ꜝNO_j~M6 ?&' 8d!Ke٪q79#?y u0Y$21T:/mL{? 0Y.d;ow6>, bO=2z+#oDbwMHt"2T吹"l92C\1hoIcE?ۦ.x7j&ז]/-^X K=X%bSROJ=6K5fniM9I] 2U搵,&?M5&|]xM!%IS3Dz)O۷<+nPrnmOI6WXdu"uy% g(dKanh3-xp9'}0)\y,>^cwl<íQ&#j7o\hmW;`b9e- ~g4p(M#C`.P7M? N.t cy"+oOܒ1!x}\5bFڭG.X:k(|=a9- 4n (2>ؠD6^gq7\Vse8Qfux֤S*fFjKO_n27cYbp|fE{b;Ŭq}bvWٝ1;cuΧqd1r3|M׋l\Ʃjy2쭰V&5Z8Wim^2SLҳSR*mf$v8v%,tս%GkMq/\:4'ms"͜A1tVp8_™`>ggJɵ#EK & dg-ʷ(LoKmsnIݘܽ>ig]!+sjפ|qMYd3< .T5IaO{kZ++(,- ,/7O3˱j)mΪvhlvuIL8`B` #e14_h!(XQWcRԚdגiT`X_3nwtvS|j?zԒkl-9N9Y]<-/6.VCK0T=4u,EnrU}t DONL̳M(s޺+uwpI-C[%'z\-N6]J(W1+MxW؈T-sRtRPFpɋRf[E9u.v_ïw÷_GWr !竁cX?mX?,_ :7e"7pU,Y C6k\ԕ!#zW$G-Ϝr>CN^Û=]܇;{,๘fy-&ۉn5zK`:`(нhToBv-V 5?IɓRa--}CTEQEchJ`f`h}; 瀠ˀu`Jve`F oan:35GC hnO)~YʯuܷK^ ~7Kwc@I yf^fy18*t@1~3*d(lP8{2%sĨk5s nAO'? 瀈K56`}0}~t$>(i H2 )ҁC!H^rg8Ȁ@9,P `APrH;D\|oNw@ 0d"$H"$  s(%1TÀ:u٤&5-6pHÔlIōyH&yI$jxI{xIl-!<$Ds7%r 9p>}a~+Dętؤ&-u6iirHϘCz3H˕yI9RHd*H;HxO5e=)[y~L]7ܟq|nkד?s^My9 hIKMz*l2Tc!YpV8'j?VCy7AJ(Nޏy?(}p )|~<&}%6˳iT6YrjYst/^2#8zthW |n%^k@[͕o47Jc?Kqh{g{Woi(DEf,QbL8doM6n?E |*4_I+zύ{ ?5Z.hc- =0<.t{B7 _ ]7,|Ո/A,2bdȱ]Erч06 BϬXOzdU-YE];CW4a[Qf.`R$92'4X,Ɛ4C i~N|cÝ .1wDn;p(f_/quV˳z%/-`|yuSn>c{@iS7eN>9jII)Hd>EB yNb2h+Dl~hω p+^b=&w/:V)}zv)vq '\+sQ:nǿ'St{R 'L]::O{$ToyDfnš2[ͼ?E߼X?3 lJ=a73yXN p-…n̓á<kYEGNY*)VuEBҸ,% c+FכGXoܲ+b̎[ßXF~IQdE"/€' RpES0VQh;,6gHf(% u $tLk1oln`Ϯ!]]#؏' K犀SR@vk1Kx;N)Z01u 3N7=E;-۰#ȴ5rFsREcb̺Ŷ5kgU;P"ʄ_敉4m">FӀKRxp[%m̆ܫg /-,ړٙۚa؜oڐ^nVVoYa]Ȯ,y}I.⤿9')NeYB3JRh(x9 /+5Z`g6MŚZնB+fO/.V(hOmK35.1Ȫ*l)NU1?mSnIԻιiZey~k9RX5pli&%4qj\$ze˃K#4JtjR + MJ s[lr쳳W8ffms:ᒖy%#֙dMP~2p8U6[-X*E͖ Nbu^25JUa5:eE%fV9Mi˜R8'sI̻咔>9MJ>YşGwҁ@ `S;uX}|"-S*VׇFk$TVȪ(L+oI.O(v+[r%Kl%?lJ2~1lL9pl6+z%dzv w̖n+k R)jonH5ʨϙRWbX[g=.zCdFa7+_GT$ˉNV[]]`h_8 u1WCLe^2J]ajYiImY&-Ef15VM6M5npl<p1]Py d*p@p=rWʛާ`v ii7m n5l*9C@1 $ ^gqVngu0 cιqٝ>gy>[B "&]5xS;1s$d v W#;@~ tW8ySdaqKfM05qeL %rsܯz0pOi>Շ/ɧr&ڴX5 :Շ@ w} L$ +C6t^@LhrkoFu&%6-3 G6.?{Owk(d'е9 Og ` 6āgaL"o}&O7 XwEu XI  z݀ǁ@y`e:`~0?@!N&i"xH2 P:@u3 TxH: ^n:' @ B p?@"I$@YPEP-@=e&d5X$&ic6Idl p?Cip]!vXlbY&fEX"lfv_8e+1ooAx b&"i-)HQE ,R6b%d9$!.N"<.(@=9ĿC||?yW`}=}uyyμbd^r~2/8ļ'Wg2TX"-}iIՁCJ ".%\$j~Hpwspq>p>g :~/zV<դ۬Ϙ'"?YDH)HCEZ2,WbIߎCR=5R:WO ˷s_F~2Wrk8/6q^<=y*{XS=;8?t2`hJ04C![ad2[+6{7(iWէsHeک=v86OUy~R^IÞ0I"; |#Q\ǹ(%ǘ0"=vl 0etAy kJVWۤ¯Km"#C>ր~ߪ}~G"G|!hj>:7Ց?H:DV봄l2N&?=  Õ:`k# X 6aA:M9- 6u"5ޒUŕUs˒5JtK RMڦ.4)XcU0fYpqfd3/ӣ 88 jMh+X,hBg2ZڌVNeME ٵ*5ډUq1-"V[ .;o\<˴R2+%?ݏG+6`]:y#]VU9wi`ahndV<ٴHx4<Ȇrð&຾遵+kw՞3y2ÿ择5TnV`Xw,DB Lg,#0%'Ln~wRTWjxgfpGn`{_[O S]<[Nlybȫ 4 ƚ` phaa.UFRV%WIqģ"Eˆ,JT Z5u@Og[r׾}g <1pC:.ݤsEz`g'0:Z,Ywi\ rVs!}4Rh!q4VjU.|   ?'"]ky.˺-Ӱ_CnYM᧚vC_5얐DUXX;,[ZU끼@& v0("bBmlv)DsSۦ <)*r6nWxVb3uגu lX@ m`8|T=f}>>>nDZp^۱,c"cb3ƖO&a:vVds ?&"IÝ$=]{8%;@~0| qq؍+OaI{X`,NfbO;eW!_ -k33|ڧ^k.q4Fe[]@ s0|>8fL/pYzWd h_55kh^sPԛ.,Xrdo~ . #veP:?;xˀu`].(?#9?VcCH?S'L~ {z|}{}yNcF`5@`q $qu0 _ow闀;>}T'|g;0_C` !2E ,a~a#~`a _p pp oo@Y$d%ħ2$ϐ9Y"&EHdrXRPZB7O F [ Gg7 o +G3 fL+4s)Ėyczzzº˺YʺYú̺ɺJ% ՏϪ_`ָ|u\;QM>I܇' !!7Ȝd#_hxlܛܚƺfbɾhZ`R9gRuƤI7)'9n#Ƨyoo+nc/Ȑ4 ;ȉ"OxᨊvFekغ3lgl9lǭy[Ywxf=mz[ YkQhn]'wX\͖&m$$a2ef[O^Ҹf8=ۙ5>ۗs5K~41\=N%»&pl.վOl&5KluxY'hY$V->2VL@f}yw|>oe5QY\{v͉(3CdGFR 5׹5I%uᔕ+G\6,w/}%.2JR\IOd+\ .3A8`ky Y;7E|oB>Sy i]@~װ"u=N)/Z\t{3x\.DS,X6vD6E8q_:Ox$$Jlټ4%҃Ų 6).ۥ7ZwZq6ꭾ/}Sj#f?o;!tSWeUUWV!\T'_,S%Y/V\XPߨ׫0= fvwϯ)oK_}ru}1[wgD W[ˠṼP1 AB$'J{ϓv;>WղNtяr 6PԲ U 2vBn na!wgy9:^Ԣ%cL.u<+6^P{6ח^nF; e!ٺl=lbAAp= 6$ = /@`t t~A jwQ {}Q?=pEA(i`6g[$Rg)| N÷3?TC0s02}~۠# Uфo Ǔ%fRXbBD(tA'D0$ND!HF`&r1,o >vC,[W3D?DKr;\L/CL@` ADJ 3OTugoY6b?/9 {<| !%B-B2!7!+M)=e.YKqVSHh iM!9/a(讈bzws2gxޅ~m-D~7JW\nsp6W qŰKF˸h F[8gFg8m;ǍJKzl/d5 x=;O~nǍ\1\=%{ΒQ!9٣Zzb+GzlK`2z\쮞vrz m=֟mddQ:<fA1h$[r~ JN 'sdh̡ٲR"wHܞ! w ^*s탷*l|XaˠKW0A($ֶPl%_x8+p{Fr~`Nqv<1i cl¶3)TjSlFZf+TFoT];zښgGQ[1_F ՆQBuO@cܵߦu W-9;Ǭrf {l;]dZo Qh~tuULQ[mQbʉ՚'.jN{鄝K&Y{i[&I7::59x(P^e6VmdS35k-)ѩjȺNwu^VVG Y]7z?+ѦJTX Vbi w'picZ6{ ixjr+\\}T]#59%h-pJթqfL *cp&2ۃJm>6em/zEvB0G4'p>l:#]c%QCe|0͹b+ݓTe蕻kWxzB}.vs$}\ga, ~i"

    p6ṕ jǪ>4N[`4MG7X'R;^wWAgaGqis-0}mlݦn:e=0pg]0p׽CѰ;F0YV!'uå5aNQR^USde4÷8˧C"4՝RvvI:%^$i-%y VϦ-/Ǣa_y9y.9gԚhl}_;Ozajm0[]#i+6͂ճa95Rf+0ې݉=X>{LHd2;E2WRouϒ`-Ym\f%;O)Zdb5s]˙:Ny& /-EVg V Ma\Y !v>D&ڔ~!?^k_y Ze0s9\WC:LiM2Rbh/8Mf\cܘUQ V*XUψ}M|N|0=I?XJAۃWi`2{lj9ԭnw0z? <ݏ ?@3:1AlOEx١z1(A<ϯCId?FȟȟPmmv^p#08t;ςPWe^ӄFKW1~ M B Ýp3?44Au3{ z?#`qFl?/%к 7&p[=}o £Qz/[xy^>aA>=~GL< AK*Ap<O0Pk2|hI;,/M|=ݐs@ p< 0olm!/WM/Ev~7x "@dg0??{|>S'H# ok_@dR#m?G7C`A8'r">P{x޲7,5kyf^9x-Ǽx]g邠?>L^}/9x"d)OY< 9~.[n[nPkP@(!j ,-$?I 3xD!PC*y@5˹Zn-;'\!Wy>qe~"t ]%D[-D[#nW@>)^ƟH]2M.(w*~eP5Vq\f9y.s%$_8)0P@0E Lͤ {Rw8O,xU/nJ U|.jUsN+8Sj;8vcj9Zoد{u{tg~\KSx֩疡7 bv~3q<ڧr}6p} GL*9lRAzf`yva[-H7wM!LAhz7 [.\6s=&r=zyrwDO"{I!ջPwdGmk[{6 {ާe)3ս?6rz ?i@jFïä̅95?G0 wep_ᡒcçl.qXaEMf˭Z-fh|еn_1!(,Dqɐź!B'5 Ip.Z93YNpplOvh 8C4.@fp͓Wg*,ll1JcjY\g֬B+5fT}Pk&T *3J ?+fiՅflZ)FkVrˬZF*,WhRI5j-Y4hTMܠQ9qf Z'>,Nt7҉B'_# .ip;N;U6w`CX`)wp&_a]RmU͙^1ef\R%kuw):[huM|fhvܟ\7}6*͈Y>:w B7[jWW.ފANqj)5fjϴhS`H7ϮQ/n Sٶ ^e}mi'|vKp"`h&/VzSݝZx$_X:OxZLhnڹmfeg8h0QMd_Edg$[#`C4Rt:`c-eK} }|Ts"gxkfydxyL6}Qv GŻf0o8w.t[=_FHF^^B;'` l *DBu ƔE8b |Ln\vbF4`_Ք`(Ġ:z13 +"mhw$I3φ!~ W跺 h$쉇-I.OP@Y!E=ȏ"ɉ1ɊKWHtS᭚R64(880}@k&~A}6mA[p.$ؔaiKDKʌAd$IS'&'ƺ(zGEkGFGDEm3gScϰOF^aW0hhGڞ`e6eAE @^6Y)#%edz$NQӧ'&j'hħxǖz.l[^&.O]?FnQ 58{S`Kͅey0J ?23HlORfo2Ib3ͥQVr inJAi>)Z)Im'  եP821 AqdAr ymFT $!2ASs}gx*{TȎpJvjYoQvJ*C]FVZ}lk* S~Qp @̖]2*Z qQChqGP<Rbk"9"wי~NaZ63XӛBbN y >Qo ;''aO6l Ẑ*(*HP#tc Za!q*P"k7[~`%eij 4ƕUi-]mVCgtyQ%GU$ǡ4^`e, xd.-@[ C`, ,% 쥓je&ˎ[8:OyDaTߦ6x9As >R=TAXPK !RjǢA ky04c̊Q˜%"Ґ 3alr}^Eҳ=+XIGP^+[mMUb!-e0sU \j5] )2IM hMm2O5ޏڔNYӦZIǦ3u|1^-d\Mz,] խ f-į&na :NmLvxgѮ1e.v+yh힏&v@mv!Q`y,luof` N htTcܱ~%p<'\s| ǯp ?\uk`(h9G$0jp<^vKn1>L04 jA9~F`!D o9|/7U|O,Ț 8^y]z| D$"Y-xC=Y+m<O9n<{;-a}4uZ#1ªN$+:},$ -NǞh  7•prg/>ׁ-}=/Y/~ɬ)Y/OodUJɊ 6$]w̒dޗY삾dk ꟈl 58=N phva۰l1#v #%+GK./]:"EZ?"[fBeϗ[8^fX|󆝑vGaΰ Q=L*˿ܧ%6 .ɩpO]ch6qX=~4+[0AR?~dx?iPek%V3ϑ2/V[X1NqJec+9'1'+҈Vhb ,*vηk([i.Wa+_>9YlrbɤBYf+Y,P)XZ`E-z_s&>W1oBgF-k ǧ~IYiG}7ޜV9vevr%ŶQ 3&(LMSΟ;Dm|lLMևҭkZjY=Z}b-Tïvpv` Իhе\P:rI[bBg/|\pXldLl b4*z$$]I{oI3Nh V'5g8aGl z1ӄ >zsF&olδir n!nQʩU]3Փ\ 5]h;:kO7n6N#fhu.ñ`"`E(<_%fQۓ~C5XJ|e3]R<#=U=c=5֎M0=zB醸&B܄fvp îȖ&"&*( ԧ0+A4dNLIwKOW SUMU . ^ըK뼾z{ mOw'8aG lU 8Ci°6u"3?i#I b#(.0C+0D߿FN}/s~|?:^BWhy n-3QakKɰh:̎0#J(Rz5qH+{7po (Հ~ٚ>!:^!u=Wow >@5} ([]ca;6'Ú4X5iPBr\;z71ȸIX[ِXO%5ϨLiQEڮ8G,sئqZ>C6aB!LhaGlHUY8eCQd&CRM{Gb{bKBS|}|m\Cq[umNӵyc#mV3!p lX2 r 5 b3%Ddhفd/\a)̰*#l655_:eeRI:'u&&әN{oZBՉ(ؓ au>,-YP^ E0 O<#?ѸM8M:9zOɉRIV4#Wu qK4fo}B,뮆Y[ of =ÊYPWfìِUT%2#%+mXLƺNb9M:iYr㊧+-8\ydQ*fW:ЂCꐼKk [3 *`\ײ :"O8U*e T~LqWY3*/ɨ`鈪8+KV.?g|9Vܑ3B2ػL(.m#ςs`|JAv-$,EZ]:Cueh]ԍ`Pxп΅~u~W]Gm[mK:i#NHM1BUs1 5fCRHnie`F+*52[cg4spLӱq*&o ]c4EƃYu].$˄UXo0E+!}D7jp^kl \7BM׬Df]t@kK/4 Em8TLEy'J[QؒܖRd4H6?G 2 d&z3iA[vh O &A;8c` p.x ~46cv=m;ڇ@p 8P:pNw39~p!.…Z.p/[L~3$m~pcqNgEpE/k'nvp/%xv }MPRvBlQw:r$-<<҂' ox2>gYCn`1}ePl/7?O|҃]؀~/j) @l{sC{; |#+|aSg|=Meo9x^Gx-gk!P?E0 %p ~|&O$i| e+jyAY36'yqp<G?-C? @0Gyo 51$d\J,+Gwq|C@a /9<ŏDŽ< dq|nSs A=i*^.q 9pApS f cГ' ,=wAF$7H\!Ksb3s,f9'i;8QpC< o8#!O  ]`]s1p 9E"'I838FG(0s8H gvq\`;Kf"T@h]xjBtd(8%cqwqH.r1쓛^tvK~&;.?ulQXflT4)ekVC`O&|1&p7 $\WV悪14rD{4XWב]zl `~8[c٬F 6ޠusXkh4J08˲w7|b3D~_u \z鎲ke:mƳ6tq7kK$ijk ˻fk ]K:%]Pu-daדt)dn/nBZ_;ps\ppζط?dVgwcɀv@`@f@d9yIUZtv2e)YfV!SW=6XKg;fD^,19#y#$U#c$sF&I+FfJG˔()Q-;k2٢f8$W8\'?r9Å\ΰ[ 6[:s)+ו?y-oOx7IxI iɸixqrd ̋+0_=vbKc)K1mPH#R{4nX8 ܠJ+X2YgՏ9V#)H%3-=|PѲ3&'eOΔϜT1ibڤ:{T,.LxhA9aPJ([=0+S+mްVB=,J1zQb7"qYgk/ɱufOɜ$15B.mJ|ʔ4)mʕl4ZT>m@-JPQVB)J(ݵpvAseް(wjKs7 l Id:M;9KS=debRsbKUkT#VmW;jwO=ZPN9V(ߴnpvh %0 e(r%߽33>t Hn2>r1 Q.I.a.TB;/WtڪtJ鮆[uoBQ; _m'aLԆBW}Mo^nw4ި{*T[]s㾰'#7X PYj߃g!* szȆ+++xzyW{x-՘Y븦mM7ny57!T/c1$83B -Dm Jt"G<`Ip40]?W70T;0V30MyZ@[5%N4i:t{Ps>B' 1>V$C]2T%Aa GH9b"tDXD_B"1K_'U+[#&I6:GyJtuTezIQ-"Sx6)ڤpx0쎅M)И 3:f@NLOdHR'x$=y$qN)A4Mj/;5)\zzlER T%S5O8:6Wձ/U}U+~8 ۧCS&ȅ[ !+r 8<3eqlsfza5۬1L͚M-VLEf̄xqc2f)N_82}҈Jn( O}4,ҰdþxhN50΂9PX i fsL-Pź˂.L.Ep&c| [!1+ʏO_$;8Zn`jy"/|_evXYˠzUBN%Lab c˵0+7ftywF`xHO`h0ܗ+K)+*'QJڭtkuiY/dR$dr]f -3`m, B|Y5S 4,Y5 }kӻ;jңfk&ҭƖ.5Tiu<sh_=v1MWi;U_%BjChi0 [cCb.%0z/97hӮnmA(Yeh-D!RTt+ KϣX%Q^,PkUâ:e" _WUUXy߮! PN)A EA0utc^|kk;pp\4à*b[ Fm,mS͂63hs@hK|hMl-34 ,~,_E0w#4_ 8nVnɛaV ~Ny v ]ca= W {`w 쮇ݻ`v]_`[!6V0ڝ0i@} s8Ñpt  '&I8m%a3pfn-8μ3o$nNp@{퇑aP_No>.*pu8\SsSr8v>V mۧ-!퐿 C.p fAǡ)o,o.Dvx22 H^mWGx}NHa{rA7-m'"o{ߣ|5$AX)̀t!^:~R09t@D /3H!(=e kyF^W%'yu'Nd+|‡8ޑxE>/(9C$g)l'汍"vhM46rF4u""zACp>􆋲J樬 hGјJttuekW_6w [iJs,ϧ"w_FCZvo{'kO^X[@Qp[Nsjpr"P^7L|+Z0QLǍ%MZ4?kg4uj͡J݌vT݇%AjDPBT5r((׊[y{Ĺ9YřL4Aw Kn']`7l@X5>PE0B&Isw0!hG=Dpp0x vKۭQkW;m_^l/ %B.AkW\:xiĸbHa.]|A.2..ir](x9*z8*;RrsI񩢫GEWAሷÆHaP9>ՅDz!s23 'ӌ O[<]Db_`hY/9y]K\W*:oRrt?vM퉒GEWAE9W8a)X(P2D!o$~M'o~&Y$y}#e]}}s}J}jm}Zl+Y{dX냢S/FxOI$ 5 bB ,o::xl["`cP}PmPu.+,7*S4 hX`+쎀xhLiP%IJD 3b,qKNf8Fb*YG-#e#2LËë7)UHA?䃂~,t1К * eCq&dC| $W,}pC v:x+,0cņqqrc7׎,vQBH #a[t&`i>AF.DgA\pI۴X "mfi1MqFif٣nZhvZH'5M:_fF2͔Y]R.NKSvZri vC{:lȕlVIP w9 r;9UG'W\#r\_4r™̔<Ѥ2jZJrrCr2s AV9CL\XW+PXC/E,Af)YQL-RaJgVlj-ml?l *1: :3:stA) ^¶O4HL3DO+صa;L[aX;]`/O @_88 )M8fXKcZ8]ck8?Lf 4w]0ddH{r 8#~ X ?gyn7R !anǝ`400t?WMͅ( + gWAv L?St_/]&᷍1!|q aA&uä: ]T_JI#YM>)coYVWGy>Oy_Ǔ2.`iD;>xGI% M%[G6賐e}Qw5KJcQ߻,dRKpb`9 `Ӡvjb-#\X>›򑁔 gXLddFP9o+r^&z-e,zIh.@;=6j'ȷX$r,IaXlL[E>V92ޖd<-e=,7ʹYs,jP⽜ b.Ⱥ +thPE )r%nvil;@[#m-so;"Dvbw,7bY*Y'F9Gmy/go-[ ւi)كi0%Az@H^:#Ii:id9Nvx8싫s9^)\$kT)kAiy+?Y9rVN_I1BR0/R}!B<>_qxO}&zn 8xj`y,pH pU˧?qUWG8ck#6X,}EibS2>d|l9'}_N뭜 ){ |%%%BM2%CQdB\g,.Aq }2Ӱ*`s̃1 v$8HapH?8_T&3;^fVPNYej :~hؘu.В X)ݰE"'a99F`i~ ̎ gVdH;rhf:f6ziz=zPAF=D®pI'kCfI@>f &A?a8 IƬmt J`f#3LA=!i LI(MJX-R*R?%R+R}#V*:$Yuٰ2-Pr@b>{6Xg\ʌhfF#CiL͘ c&eؠJF dlBddTz;#O0"#S_32EL%a|XQKA"I% Lì|/F%3> ?7gD#}4?y;Fy'5}sfKؔ `"I r${(Kc1X^)hQ"ˠҞ ,L1+D.էg=JVRI" %yȗ,GvQ#E/LSd>"W$ W(дJ* ҫ |+*`fUJX ݫdl d UZPeUPUQP PY;`%X',{ _\a1.p.P|-ւK-ՂN-L^ cV5УdzX`XLa3 I%wNA=XV_ꕒ=zH^ ,`z6&dE7>gf #`s&/ о~'Z?Vzz=5BxxnfS[al ln[@:Lʮ`@3Mqpp>C[8xo$ @T+xKXt we?͇CDpR N#\mJ\M%c]kC@VJouNF7r[HE9 fC2kmWO{x22x OӋ[ vn0#8ȝq/~̷Lc"l#K.|.z_ fJwQ |&$ &, yPVz^ :xA.K"/0@I>_nßׄ8^s2y<&"sg78]nr'Gn#p_?|7{&Yƌ8/C"y@,Q)mBhkv$;;&1dI"sL&c HSFդi%iA\%a#~ n@ L0vchԇ:Ve(UG1L&_U\U}UT%Cՙt5/RHQ 'Y-DtS[LJb&5ijp \ ' `9l+Xg+ al(ф=7m8*U ]c6F$iX@qhMf kYMf{DAEDD(@] s첅kC\j'I{* ZimF ΄k{HN$:IdSNOgGg[KKS[yjI8oa#B+re!C ɺM םM:熿~za㣟~SB r!v;+vѻ'v{#vκe >c&@ܠzA',uB{Ȳ$cbzi40M#H#}|1OcO9fn.8[deEve"zEL`*.whP ˃`?zB DC~6*n6G lu6[(mSY.։MmMlOm~ۼX b+ $yMA=ڕP! ^ Nx8qΎ8:NQ}lͰv '?̝"0sJiiiiXXXXX^ aP Ѱ4 "!#b <8mnv ,`n5&`G"z9"]RlZ,v1-KW v{aK4F8L 0?Ң :l|b33Q`쫁Z_/fo3}1wHӷM{THHHKkx ] aU2,OE)  >Qf!F?x/aw D8oRyO&; x"P+xjg{yp<?K9Ws$Q<'H?mrTsz~{l.Gk?{O -b&1)<0~'{$rt~#[ Ed17XuVq+]q_x"1Gcw0ērpeH:,.J3GasStQv} g".@e 5p4ޜ cs!8@6g/ M;f tm` h>e-!H=_k(ra'1fsS`^\ٍ; d;t6Jɦl4zvSs:ϬF`5G/gq80NӉ[1g3F >4Hl $tɡBVUTSC+J%GxD9(GLs\zq%ɯ=ȳlaL-1K@nƇUp$*r(gK`1u"S%O!)  Fёol[`J42uc SYQ8 7a A,S"c(bQ6B eג'nax/9 d#Kr_+'0WN`<NIЩ mi ZaJ)s(nVp; ~ed^Drz%|2{.!*{6s/)=/ߒ[T84vhALhRzU ȳ_ C,4zlF`;1wCIJX4d CKء EsDao*1T |ՅЬkg|2‘=5NƘY5$eIcHBXo36qID"b\1a*@ȸ;C฻{M8AX46s`RkATș܉IUKdTgK QjVD9N!ja4i. IkԁxM I$&,8`Vb km MXiCI7m$TTW'\]PuT%@uo|5ш[# OxhYV\4Oy g8k|Y]Y]쵄uNPa)dC=9Й 93Go-+<]+7(\SpIg :ٌ1lV9Z_)pvB3lpp\a#YCC؜1Vkupms4 G]?t#MV/RjkB(溿`9_0#g # Zݡ VzCA#$@*cO(b0Gbg` 6.X`eQ٘`jVcd3FF02,22DF-tA7Cu,BtGsYzl6qؙNt:V43 s3'̽05<#L -b`Q&t1sbg 5Da4Ú` 0?ҽ!ck=kXZbn&[[`h、6A2v.memfl0:3e -+Ae)J<І` H(0H (vTܡ#0vPa*3sCєَrtC)-hf:3éM*46טiPPD;5"`e4, I  rB}s2] wMg3ݘhz4Hz2c<*PhD}dT\?*"P PEɐ ` ׍7 ?e2O)~L@U?o&x|-czFaF>fGF{  & *`qd@f:ĥ@`Ƃe4FḞy5Oټ7FA iBYB$7UAn _!d Ykae1,_ BN$ARp[aV)L.1%0L P%dIP:JJ|$Jr$n=PՋ$]a~%UADxUM%UzAУd*JJBU+ŠɰBV vUT-5P*.Aş-,eE5 bjk4kaB- ^ ׀x PKY+ caX?6X/In-!7@H#lfʛ`ptk޹H(P>d7JH?1N)'8st%nӧm87{+P:Aiǿ:@P?q$ ?Gpx8WwpV0q J߿uB E̓</iT{1|X:we|ř>$tޑyM(xN X_<ɟC? ^+61-vp"$ CbTHn[A~2?7?#pCOlq7|>Ѝw xO<ĉx;A%߈B7B u\ 9mNSD8Ǥ|{ yӗ. mnarWeH$ɜ?|W@Vg{;VTAA" b+{7vc:I&L2:dI$df'O`}kw޳xfO =G]= }>?fg|UV[A^+z{/Ha2yLGzX}ֺVw㮺v]w e]U56}=(uC+F8En3%]y띵ݭ:t̓xaw 8PolPQu#5n6.Jq^F9c&:i3K^vm󱭾Eox5xRw tq0'E;&t(DڥmVlFwZY*_YV X)ޘZH muT::(>v`Dۥ*l2֛fJ,j+m~K]yB x)k㝹 W;r r״[SuB+R5+fUL+JU&YReEUYPuU7[u9UO]NEU6;fT?^=`zۗZ͵>\ͩ 5(gcͺniUNVeiHZT?ɂCͫens`sl6ej4fR4 aB0`BÀCx<{]z?ڗ}֕mYմMXԬCcvhZěr-r-ǚrI-g*ZhBPtAO ܠ/GNP@NP a<͝\L (6*E+۶lɴkr&uH4Cw1Ci΢L:Oմ Ұ+na[ #*FajNQp/bdڛ8 'w-i% \Et\A]NeYVe Y֒e,~,IJ,ҙ,],9X:>c,K@a˶3k&"6eA+6:0X?u YX{7k^V8};J;iWa&anwIÝTۉuCUU]݊ݝXv;]UOv< ~vp;2H;Ā,ˠ F@-O:>[)Kc]SW'LJ6{NqПۼ;o[fZY_|/>>}#'ϟLGlo-Ka׭-~o;.{ʳi_zlcezW=_s|.b.exh3 &ytϙ=m#y u+;KW5^ó"=%R=*r^k- V~Avl^Y7:YDU&YaZjYhbM}fP$&<ۆ3K%G;UU#VW%z[)rqIPeY(|3EYf[Hi.aSʽfrOL*OWAxWɕOGۛ%kZQ%U[T5j}̭ߜfWOVT#٦DSkN7|j45_󒼚cj}jL ȭ|W +a~ cgw6vduKV4n=s)ь=Mkaj&7dR 7(k44^&&0#?$k*2d6xGq{ g8˞hD&ۆk)lLlU~ZF2ƘrҌ2*hAd%j mu]jKmW%U@jqO,9ġĆǂ^uer50]1;ièF/}C 0ܰOdؐbB50%B>2v 58¹tevnFI*äH&gM{46Gk=:ICR>{3ޠ)CĆkkv}Jd>Էwp}0Wҹ5##=M٬f$2!W5O}Ia-$UlX/1}'րd"rEFL/X߾+ݮOޥW zE|wwz 7˙šv!#;TːJE6uSdd~,"j>G _wlUB-y/?Dt kGrb >uy,L`LÓH/g`LMQ7vGz$GH&+5n.q[t;c!/c1&kYƳo"[ X[|P0,҇?~UIwBsH{b/#uMepNu<^'-.i6IGN*h3YoNhphΌ$L-PJ Y4Ǩ\RGAЊ-.uJcj"O6-Y 4tCi6tCio*QQn_ʡ_YD|F3d3-$x 'SuU+hjA[ XB )Ȧ Y`&ʄLxOvz{Y)v5W1c9yKϣK1f`Ջ*(WTQLQfc fcXfNgfle ô)2ߎ/ vazVg:&ajWKiƋ򋰨겨) ۰ {p SX8YXyט"Q-s~vdġlafm"}齎4[C5T(A J*RR4%(d3X_:zUIrϲ}}ò2g'wDlVZlV*nPE`[}5g[{ug[ے6mغ;r͏Ol'PQIO>#hun0(oҁ2,ánǑȑtRqρ799k?ӏ0(G>J1Zq*/KFbY61q)4s9Sx;‡\ƣ,;AIN~ R ʯqo57䡶Anѓ< #4s0牽HKW(ws&f?B x~iL孉eowIȾAIݻ/셼xz.>(_y0ϗ|5o ᖲNҹg~c}N%fi+>WYDy7=~:NoE`_oFTOL>2ۇ[yVyoǛ?{?X/0*R}kS|"‡Y?,ˢ{douj[d,el(Lg"H-/{-1${~ݻ=LD(=Lջg^ㅆУb{m됮nӥד:IЯt_]{99>}:#YɬLJ&w؏a /ws}zӻwBӣO} -|.tXSzt]F}?t\lgL2EɄtF04FUֻ_ѯ~tKdΑu,8jhhV QiZF})(?ZE\Ǯ|6M`U> 1}4#AjI//$.1 uicLbimlmbMEdiF]0Q 0 cK#959 SJ/`xƏ%{YDBUKMb3rpg-j64NJ(iI%-IJ:fCj$N- r|"}:g|Q8GB}GIa4ZS 5puƨ>DlUMJ w~Z+?*}b*J{i ;CY[̲bfLFM%u=NMUQGMUF]T[U9X\ʈ8Ad̟*,v+P,*, Y$ ɴH _Qż5$/`z׏x%E/0cg~MOv.arJV`9K]D|b=E4ATV֣m)Ba:#:󘲎t;/L?9K9kY%LXE w ]jSeanebnC`nRȰ gPϜY̺Dѓ|_1'WvnH&lp9I]Kz* r,,o wdy/`y*rY6eX%gY(a?XJP6l+EV3~÷ޛ鰉&*lFl bS'6aS<3Xl7Yk~w[vj{(Ci7L{+/]߯lfouiȞ;riGmǚ,8C:D!!bOpLFNWziٮ_aD.v\̓NmcqƜ Q'z槩?|_'Dn0"*rwm}ݹ?\5wWe'):M2!iq7~f_erns׸[y/P^̫cym>msa9&\ "qԼunAynx!4fÚ54>W5P㗹ǀ>ia/nϭS{}☏]|y_{$2@i;m|+BϤ,|/f9޳hpǽ^}^b0[r>wON>{`oKesQ&)^6Kx/X9%v{QO1=euvYǽ,?A|wU^+B$ b=+ӆyHQΞlNI:R(J (!ѝ۩>ݱЎzv{>B:G%Q.t隣S:vCѶYm=u׵7m]+IܚҊM#XłHa`Fƒ֟pVЫ{-=B ikH{wթ{o{D 1Himh֡Z2tg4 }@4 L?j#r2989leh`pL bޏnat]Opf:.a=O>SyM#fkRDܪ~uu_U?S Kð91c؞CqOW9~J[T?\ܝŽ|*~RL.PLc4Ler9:ɤ0ZpHenQ3ɭUKJrɑ*t2!J&&*Iϒg?:ϡ)Qʡ.b4FL&y3h-T^C ޒNFd1 uî2KdG1j0c.f1lS D 8)Gnurی6t!79I&'3uO0O9RyeRV.gR&/b|=fn 1r1 jSЈzAw QLcbV2a(yd^Z:g] KV3sy+ń-<ϥ*,̪ե E)DQo23̜ƌLδ[)|o3 h2e60w=1r I\I-R*-,,z,n,ƢߢlNbRe 7(;s~FVoeVn&m6cmS7UX[MYێ=Y;iǚٔd+{;v|wmvlM;n ;밫)ڳ7ٕUZHs;w2۟eGl=ǼL:@g?h?U~aNnҡ29V59لT2ƖNn)??q+kG}c=F4>N/7<~\k]JNܵs5z>83N2)gir*7~p'l 8wyV^xRtgE]mT&zaU7ɍy/4V惼WQ('|>]g?H _$Ve14Mg268}kwvjox ?){u}t0I>4F3ѻzLTm e7^~A{ճz8хmYS5|h]A?o󚔲,(3΋&zTϙŞSVx:Qg;$&Vm6&6ȷk)j2-ubZ荲҃Fٶ~츹\v!Uhg6mH%b`+ KZl 7V¸a@F4vf|[F6'~ɵkIȠ[AL%N?QucDMҷpr?EXz/ѳn=Rn[ zwD9:= lN$E̊`r(cٞ!-k\̀oLd{Uuu? H.{ޫ4DT,X,XcI&XS51ݘhSL1=֛}<IBאx͵0+âVn6oiV5W `Z@W|m3< ȳ\=У `%sy'z Az:_9_YKDRi+l VurAW߽KV }跂~tXQ }зeҏaAhY k!k-D`3AaX+ׇs?> ` l-1%_tV慰y3lz6ch!omM`6Pw2R{1A%GlH I#pdYG۠h;$ wFOCІ<%kUGx!.fxϟަq=\AP:4o<&#g^,Mȥ{q1\wcb >raD5Iƒ?qWH~$[ 2[%|F7'1}`-y8{[|ϛkY8gŁsBX>&|@9Sͻ6x\aoes^eENrWy/8?kp<9Bq/X*@kX>Moey4^&)"exi9wijuՇV4^El5c=CѰ2DCwMP ΐnH&g-:.xxn$pA{Fl`K-XLELo` 8;b`C< $¢芃P.mcF8Zh考FacI&6`f: ӥn(3(ؖR:T -0% JC!;!J GsMl63KsW,,|1e,VYc`]u;cmhZ_@ZV?0oÖTLP2av:4BM<GCf$Lp?WgUFScm0u } G됆C!Zh:؋z2π[%x,:JE: h/R,$A$Cb $FAb$Ab=$̆>q'!uaV7t( [s΀&(lZr+Brl%V,]4L+tL? dȇZhe0i+ː%$e}#lP̂[!k:4B`=8ׂY5hO (%*PPlEP E(ATর [`1o!| ٿ2*ҡ,=0s.uB,H 1@z*BԌC ݪ3rLGU(Jeu'{s!4-y ѝ;;TۀV`j_aLׁ0=9´8SAËP9ʪз-PAB/-y`\5wNUԁNtN_茆,Ss:`v?O.+wꇆ~(^)}ܖR\ .X K'$XZKÒŰx,: `O,]]ky T5MoEÁpp9}2s3nvyPe|GM8k |p~?PvBnzH 0"QDF.νZ!/7wUfkb Z|P#oH+r"Ϩ&|B f=|>`%WȻ- .s$(A<-/-†qN$H*K.oSěF2MF2WK,"\`9Y^ p?8%C9&Cܫ381|b[8:>D^"$<;5)IU8T`h=(2-1 c4\7RG(DQCU1l)*i%5䰛l&[2 9G a1l1A=2犷JZPqaD TbOnC J!QH.!,ȠIJ v8N<+ s ;`V]M$c UQ.8N%I&L)"jbh&."XN8 (!\d"7m&7^*րXAkde(B\4DI8;q'8I#<&2 4lXC(><7ŷx;G`lUzi@l J GRƒ&)X!xAL$(IƗl)Ë<Ÿg9yG_8#n!(`=X@kC2 c@3lQpK O@ܕqUelNcqPLl{V^~,b>m̔LgPeE,9S|r a.h⩪!.j8憽/vшJsZibՆv/>xsjx[keo&m,,q0;áfj$:A5:؎8c,uqL AH/|?hE`gP uG"aSH ` @ŵ09!-b $La*v:loX{gQpq Ne]N;$8^`mi.aQtB[>4@EAZAP?x Jnfn^>@J:D$o8FY(L*~g~~i_u? V=>ϧ}MOU0ZtHd(/Bρ H0 LB5 d<@ B?CH2CH-%0q3?^JaUH2^SuP\ ) L'v (&J:k11> 1Cub! AF<@Mu0PKfQ.Ntn:Hj]zy d 0I&iABzBj0AjpH^IDl& 7!SE:m: Z }D6o-8Tqh%@P(A@!YA Cn䦋(9M"QEZ|2^0VPũ 40o:P=MJXu* *B< ʺt5S(9\3{>4΃n ` PjӤLF%hԀz0:hMu0e<+rl1t/P 9 !v>\0eaάWǽK:ԡC::BE o{9̜3@v |пA{ArH\ b0^n;Xk  DIp ! =?x%^t:&<蒕s/FF# NTX3̂ի`AX kyTu<ց:P_'ȊRƢ=BU{abxd^c6;U OFsNq8rE ޴w xw* <#3j!w6|&/Is2IRTp>ifrNc[ vryxyxa Fj00~e,_X |»)A&%GK4sv^`.ϱs 9AOrܽrH~ {K\\ \$ ,q#3dr5i8;I '8I#\)'&A0b= s ?~8l a+r%Nb 9L3M(Q\Ɛ*)#b1#"q"#`$Dď|7mxqc/< o׸]`~_Q*ppz+d@U EQ#B0db?xq1 W pGZgvƆX4V_`y8=Qؒ5yXR9͘э +1bĀKs}nHl Z$ c"L j/(rL;H0pC8+i0;lRtBsLdžcr6*4:qhDC$* j*?k" EX 103C2 !  |eFjfۢ/!hkơvj:t1VgJ:Qy1^#;aCJ"M8hyA";Ltop2K1몢hwDM U`cP2HGѰ1 `8p>/ m1ⳑSE)]iК,GCnC?{+8:5蚎EH e#[h YyXԁ,X[10{ LlI4ѹ< `NȀ4(KXHO_s#Gд&XꁕXہMئmՂ];.M`s l.uM&‚<-0% J';b \{XpG]p4'prg?p$ppiEEp߳1Vt(av L/)P 9Ya` 0G S< <B+r fW/xn]ؐ+aI9LY<CiHAi0>C`E A"RK`eAd D: k{ tAsLɐR ` @,=!R"t!m!!<3 › l0yn_:&h&lZ AZy @ $+A$jC$XB3$CB$ABj\[1!D݀ȟY˛E5aALM6¦^m藂J1P4)c!KCI1L{LȨNRBʳ|0a8glꀜV.:رLzC>Ś2TJ4DJ,8s ;`ܳs?[t6ysRfBin`<{{:`2Lт)F0j6jҡjf@OC5(Êdt-^X z;cDNۈu5ZZaFHBh&*<ۼ N@;06}`2h[5K!o -E`|D_]JУ ,`; L讁NqN sca?t @ @R?LXN}`Jܛe+  @1 ̀b˿`6e6:k@Y1E`x :gΞ{ _|_}o\yw}>~Oo~ŗOw~?nE*jZtt[XZY;8:9{xzyM6)=#3+;'7/breUuM픺Ӛhm1kή=/Xػh˖Xjoڸi۶عk#{G9zǏ?qO=}3gΞ;s/ʫ]W|w}\7>ӛ}ŗoo_ OmPccAƿ=/&{|drCbEE%**jjZZ7044226115537wpttrvqqus=OLJNMK/(*)k>{VYaw޳oG='|g~{_k~7>OoϿ[o~O?;ܽ믿_?6Fhmm|Ww6Fh哻?COVկwFhmgN?r7tO?I<?C~mtwl~}N OrGvk|_5;P;P C &6axiim}O<z˟[Ň^=<'$YB|v=X-zdh'ZRC6/{]',1 ?>AȲQWP'SP*ˊ;B/S$kȸG\T n Ě&YPSuުm+97dN6{b9YZ3a,_SOPp_E_?SG}$0C#k%ji@R7Y9ÿ_莲R~0<<ƞҊYb_5??$ĺYeq%xWsl{Kk"UF:更.#E x{QH))`4>"KZl,dWj&J=`렺$ 1K ĮM nbk2Q^dܮ+6W#_ןv/mhJqev"Qd3OM1f*6y>"1gJMJ$#qDV:O /u]8p ׄ$`(RfJ^Ơ<"BMt5TU5,\dY[/Z.BFZ=g! eji )BO  WRHz[@[HQQ1 卣S? =˛dv~HG8cvxxΠϤ)#NjYa(U BY  0 $,"o+\Yk%W3U tŤeG>/4!~hQ{S6{}ˌ4q5So.|%W%w9E8J3$0W .gސ'H0xw! B@A)@P7zrVR`g ^ϩ )5OlHk]$LzΔ:d q,_..F2o^ܷ)+nK%{G8RA5A/szfQ+ K&(}!|& 0ș8R`^TIaT qfIWr=r|B N(BA# I &&ATgZ [q}}useI?]8THYC*r+)+=X'|g-IiR@U_N;9Q $uYIBTHoo 0 K ԓzB Yג<̡5|<<wӧO>}+ɱFQY\DudVRji`B'"ψֿT wI@j++ij6j@<+猥`FpSH NW|JT!0 F~1yS{wΑha۟o߶ra̖Ʃ 3{${YnR5K2ևri@5$FyMВg}tqZ `4$ӕ$EIKj3b)碬Ӑ\I碬4~5<|AᡆlmkE2ʸ|:j粡}Oo??|W_}Bc=UEiqQ!aQIҦArvܰ7y\E9o%E"N(E<^HE{h^ -o&cTsĂUi_ 槷Ggv~#;l0qˮC$w;[h.)!ˌDI 2g% si@.H3hx@X"З|5XCyP"F$ #aTg>'W.}G۷ѓ_T*ψ ru03uD]*E9+*Z&X ܤTk~ UE$8)2?I&+X kϿ/u׾A:~gGxzeʃ/Сӗ>-{8 ?erকKwvLonni\Kyꈬ W%\/E1ۉrvQ~k^e %I' *-ke6uܒW<&U%r} hYzE$+qf-Gmm޿?{s^r] 5YRcc2껇$| 5]5 v<dయ<9sq0vIQ}_ԸIN ss\x=&n?(Y7?M$m1SΎΞAE3uE{oJ5\] h|:&_nΗj \K;>+JY^ٵsVzA5l|;Qݗ7?q|񝬸+u6}vϲ*.Orw053NG%hd&a-H  ɓ&c=wxq C-{ #cמdP2LY֓lׄgˎ>:=# <<{}8|X(+JKNJLHLI-k#4E;%Exؘy3/bEjnfJ~KΡR1X:s3/J20(YNkI:+lڳIh^ģeWXjNvբWқ}٠#%bYoٸ 5oLX|{7a\&˷z_>kC`P|Opo9k9 ݲ{fNۉj Ry/\C|7p^n~ywq9tAԊʢ#]#sǔTbϼĒZbKGD̿ pHYs  tIME1Yκ MIDATx{dU9u_v|D@i"L&`'j ?!`0ŒAQ'IFeՄDEQQ#cZ!ny{չu }[u%}<;^{!f!V +V +V +V +V +V +V +V +V +V +V +V +V +V +V +V +V +V +V +V +V +V +V +V +V~qO<%d:`v䀣g*:S!~vc6v fXJe H'"n xeU{hDAHؙ3x CH' 4$ ǐwyDg:˜}"욫7Z=}ih48ne\WԺjc J*®z]D< 嘞CNF>)$B EuGuc,EI''\Ç]8}e4$5@K7}\ C2;C#+>%N=hH%X\v;y7Vu5PJpAW,;s&NE 4h ]Cx=4}+a:}v++;kx-J;nr9߰~.XHnd*?xJb?mHh,ƧV[ǛZ@®v, p.vP*j|H5/с@ s0UZSǓq!w¸VvQ;Wvr8s;nlj݉ve)®zc{촁ӵX2K]Q OYOxs+M,%첑oϚQYY[N :v0^cvk}7LA|&]oZ}i!(̵5OZkyBU|?1"N/.!a0?Yą}!)ȎR[^`P,5rgX!NKs(評8Ԛ)nr&6 [B.+awINONF<^VLtۈx!prXQ8}a{~'Nj:D>ˋ66 aʦIcDr5*BɁn0j`,ezc|X&R7#r846]\k/"EإK KlSM$Rߖ=3b'$q*/cqAs[1.3By\ _S17\7Abfʼn䜫96k$VM䲃2@iYuP,gt^V!O9’KtsywSn 9sF~bcdnSL E XABI^]T3}j:M^FJv/^A &GZx.>9+0WN&!JRK@iݲvɹ㹐x6 ZM\pCT< $\cF.\E!m"W Eptp䭳RŠejm;MVN`KIFCv =;9SEiKKDJfIŠuB6K+yvq'"m%LIX1Q';*@8OϤ0nGLJXNZ hl^ tiffWriters = ImageIO.getImageWritersByMIMEType("image/tiff"); boolean found = false; while (tiffWriters.hasNext()) { javax.imageio.ImageWriter writer = tiffWriters.next(); if ("com.sun.media.imageioimpl.plugins.tiff.TIFFImageWriter".equals( writer.getClass().getName())) { //JAI ImageIO implementation present found = true; break; } } return found; } } ././@LongLink0100644 0000000 0000000 00000000153 13777276623 011656 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/writer/ImageWriterRegistryTestCase.javaxmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/writer/ImageWriterRegistryTestCas0100644 0000000 0000000 00000005020 13777276623 032723 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageWriterRegistryTestCase.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.image.writer; import java.awt.image.RenderedImage; import java.io.IOException; import java.io.OutputStream; import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import org.apache.xmlgraphics.image.writer.imageio.ImageIOPNGImageWriter; /** * Tests the {@link ImageWriterRegistry}. */ public class ImageWriterRegistryTestCase { @Test public void testRegistry() throws Exception { ImageWriterRegistry registry = new ImageWriterRegistry(); ImageWriter writer; writer = registry.getWriterFor("image/something"); assertNull(writer); writer = registry.getWriterFor("image/png"); assertTrue(writer instanceof ImageIOPNGImageWriter); registry.register(new DummyPNGWriter()); ImageWriter dummy = registry.getWriterFor("image/png"); assertEquals(DummyPNGWriter.class, dummy.getClass()); registry.register(new OtherPNGWriter(), 50); dummy = registry.getWriterFor("image/png"); assertEquals(OtherPNGWriter.class, dummy.getClass()); } private static class DummyPNGWriter extends AbstractImageWriter { public String getMIMEType() { return "image/png"; } public void writeImage(RenderedImage image, OutputStream out) throws IOException { //nop } public void writeImage(RenderedImage image, OutputStream out, ImageWriterParams params) throws IOException { //nop } } private static class OtherPNGWriter extends DummyPNGWriter { } } xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/writer/ResolutionTestCase.java0100644 0000000 0000000 00000013225 13777276623 032211 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ResolutionTestCase.java 1732019 2016-02-24 05:01:10Z gadams $ */ package org.apache.xmlgraphics.image.writer; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.OutputStream; import java.util.Iterator; import javax.imageio.ImageIO; import javax.imageio.ImageReader; import javax.imageio.metadata.IIOMetadata; import javax.imageio.metadata.IIOMetadataFormatImpl; import javax.imageio.stream.ImageInputStream; import org.junit.Test; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import org.apache.commons.io.IOUtils; import org.apache.xmlgraphics.util.UnitConv; public class ResolutionTestCase { @Test public void testResolution() throws IOException { File testDir = new File("./build/test/results"); testDir.mkdirs(); runChecksForFormat(testDir, "image/png", "png"); runChecksForFormat(testDir, "image/jpeg", "jpg"); if (ImageIOCheckUtility.isSunTIFFImageWriterAvailable()) { runChecksForFormat(testDir, "image/tiff", "tif"); } } private void runChecksForFormat(File testDir, String format, String ext) throws FileNotFoundException, IOException { File testFile; ImageWriterParams params1 = new ImageWriterParams(); params1.setResolution(300); ImageWriterParams params2 = new ImageWriterParams(); params2.setResolutionUnit(ResolutionUnit.CENTIMETER); params2.setXResolution(118); //~300dpi params2.setYResolution(79); //~200dpi testFile = new File(testDir, "ResolutionTest1." + ext); writeImage(params1, testFile, format); checkStdMetadata(testFile, UnitConv.IN2MM / 300f, UnitConv.IN2MM / 300f); testFile = new File(testDir, "ResolutionTest2." + ext); writeImage(params2, testFile, format); float multiplier = (!format.equals("image/tiff")) ? 10f : UnitConv.IN2MM; checkStdMetadata(testFile, multiplier / 118f, multiplier / 79f); } private void writeImage(ImageWriterParams params, File testFile, String mime) throws FileNotFoundException, IOException { BufferedImage img = createTestImage(); ImageWriter writer = ImageWriterRegistry.getInstance().getWriterFor(mime); assertNotNull(writer); OutputStream out = new java.io.FileOutputStream(testFile); try { writer.writeImage(img, out, params); } finally { IOUtils.closeQuietly(out); } } private void checkStdMetadata(File testFile, float xRes, float yRes) throws IOException { ImageInputStream in = ImageIO.createImageInputStream(testFile); try { Iterator iter = ImageIO.getImageReaders(in); assertTrue(iter.hasNext()); ImageReader reader = iter.next(); reader.setInput(in); IIOMetadata iiometa = reader.getImageMetadata(0); assertNotNull(iiometa); assertTrue(iiometa.isStandardMetadataFormatSupported()); Element metanode = (Element)iiometa.getAsTree( IIOMetadataFormatImpl.standardMetadataFormatName); Element dim = getChild(metanode, "Dimension"); float resHorz = 0.0f; float resVert = 0.0f; if (dim != null) { Element child; child = getChild(dim, "HorizontalPixelSize"); if (child != null) { resHorz = Float.parseFloat(child.getAttribute("value")); } child = getChild(dim, "VerticalPixelSize"); if (child != null) { resVert = Float.parseFloat(child.getAttribute("value")); } } assertEquals(xRes, resHorz, 0.000001f); assertEquals(yRes, resVert, 0.000001f); } finally { in.close(); } } private static Element getChild(Element el, String name) { NodeList nodes = el.getElementsByTagName(name); if (nodes.getLength() > 0) { return (Element)nodes.item(0); } else { return null; } } private BufferedImage createTestImage() { BufferedImage img = new BufferedImage(320, 240, BufferedImage.TYPE_BYTE_GRAY); Graphics2D g2d = img.createGraphics(); g2d.setBackground(Color.WHITE); g2d.clearRect(0, 0, img.getWidth(), img.getHeight()); g2d.setColor(Color.RED); g2d.fillOval(120, 80, 40, 40); g2d.setColor(Color.GREEN); g2d.setStroke(new BasicStroke(3)); g2d.drawRect(150, 120, 60, 50); g2d.dispose(); return img; } } ././@LongLink0100644 0000000 0000000 00000000166 13777276623 011662 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/writer/imageio/ImageIOTIFFImageWriterTestCase.javaxmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/image/writer/imageio/ImageIOTIFFImageWr0100644 0000000 0000000 00000017606 13777276623 032312 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageIOTIFFImageWriterTestCase.java 1833700 2018-06-18 10:08:45Z ssteiner $ */ package org.apache.xmlgraphics.image.writer.imageio; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; import java.awt.geom.Ellipse2D; import java.awt.image.BufferedImage; import java.io.IOException; import javax.imageio.metadata.IIOMetadata; import javax.imageio.metadata.IIOMetadataNode; import org.junit.Assert; import org.junit.Test; import org.w3c.dom.Node; import org.apache.commons.io.output.ByteArrayOutputStream; import org.apache.xmlgraphics.image.loader.ImageSize; import org.apache.xmlgraphics.image.writer.Endianness; import org.apache.xmlgraphics.image.writer.ImageIOCheckUtility; import org.apache.xmlgraphics.image.writer.ImageWriter; import org.apache.xmlgraphics.image.writer.ImageWriterParams; import org.apache.xmlgraphics.image.writer.MultiImageWriter; import org.apache.xmlgraphics.image.writer.ResolutionUnit; import org.apache.xmlgraphics.util.UnitConv; /** * Tests for {@link ImageIOTIFFImageWriter}. */ public class ImageIOTIFFImageWriterTestCase { /** * Checks endianness when writing multi-page TIFF. * @throws Exception if an error occurs */ @Test public void testEndianess() throws Exception { runEndiannessTest(new TestImageWriter(), 300); runEndiannessTest(new TestMultiImageWriter(), 96); } private void runEndiannessTest(ImageWriterHelper imageWriterHelper, int resolution) throws Exception { if (!ImageIOCheckUtility.isSunTIFFImageWriterAvailable()) { System.out.println("Skipping endianness test for ImageIO-based TIFF writer" + " because JAI ImageIO Tools is not available!"); return; //No JAI ImageIO TIFF codec available: skipping test } BufferedImage image = createTestImage(resolution); ImageWriterParams params = new ImageWriterParams(); params.setCompressionMethod("CCITT T.6"); params.setResolution(resolution); params.setSingleStrip(true); params.setEndianness(Endianness.LITTLE_ENDIAN); params.setResolutionUnit(ResolutionUnit.INCH); ImageWriter writer = new ImageIOTIFFImageWriter(); imageWriterHelper.createImageWriter(writer); imageWriterHelper.writeImage(image, params); byte[] tiffData = imageWriterHelper.getByteArrayOutput().toByteArray(); Assert.assertEquals('I', tiffData[0]); Assert.assertEquals('I', tiffData[1]); //Switch to big endian params.setEndianness(Endianness.BIG_ENDIAN); imageWriterHelper.createImageWriter(writer); imageWriterHelper.writeImage(image, params); tiffData = imageWriterHelper.getByteArrayOutput().toByteArray(); Assert.assertEquals('M', tiffData[0]); Assert.assertEquals('M', tiffData[1]); //Test with no params (TIFF codec defaults to big endian) imageWriterHelper.createImageWriter(writer); imageWriterHelper.writeImageNoParams(image); if (imageWriterHelper.getByteArrayOutput().size() > 0) { tiffData = imageWriterHelper.getByteArrayOutput().toByteArray(); Assert.assertEquals('M', tiffData[0]); Assert.assertEquals('M', tiffData[1]); } } private BufferedImage createTestImage(int dpi) { ImageSize size = new ImageSize(); size.setSizeInMillipoints((int)UnitConv.mm2mpt(210), (int)UnitConv.mm2mpt(297)); size.setResolution(dpi); size.calcPixelsFromSize(); int w = size.getWidthPx(); int h = size.getHeightPx(); BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_BYTE_BINARY); Graphics2D g2d = (Graphics2D)image.getGraphics(); g2d.setBackground(Color.WHITE); g2d.setColor(Color.BLACK); g2d.clearRect(0, 0, image.getWidth(), image.getHeight()); g2d.setFont(new Font("sans-serif", Font.PLAIN, 15)); g2d.drawString("This is some test text!", 20, 50); g2d.setStroke(new BasicStroke(2)); g2d.draw(new Ellipse2D.Float(200, 200, 50, 50)); g2d.dispose(); return image; } private interface ImageWriterHelper { void createImageWriter(ImageWriter imageWriter) throws IOException; void writeImage(BufferedImage image, ImageWriterParams params) throws IOException; void writeImageNoParams(BufferedImage image) throws IOException; ByteArrayOutputStream getByteArrayOutput(); } private static class TestImageWriter implements ImageWriterHelper { private ImageWriter writer; private ByteArrayOutputStream baout; public void createImageWriter(ImageWriter imageWriter) throws IOException { baout = new ByteArrayOutputStream(); writer = new ImageIOTIFFImageWriter(); } public void writeImage(BufferedImage image, ImageWriterParams params) throws IOException { writer.writeImage(image, baout, params); } public void writeImageNoParams(BufferedImage image) throws IOException { writer.writeImage(image, baout); } public ByteArrayOutputStream getByteArrayOutput() { return baout; } } private static class TestMultiImageWriter implements ImageWriterHelper { private MultiImageWriter writer; private ByteArrayOutputStream baout; public void createImageWriter(ImageWriter imageWriter) throws IOException { baout = new ByteArrayOutputStream(); writer = imageWriter.createMultiImageWriter(baout); } public void writeImage(BufferedImage image, ImageWriterParams params) throws IOException { //Writer the same image twice (producing 2 pages) writer.writeImage(image, params); writer.writeImage(image, params); writer.close(); } public void writeImageNoParams(BufferedImage image) throws IOException { //Not needed on a multi-image writer } public ByteArrayOutputStream getByteArrayOutput() { return baout; } } @Test public void testNewMetadataFormat() { ImageWriterParams params = new ImageWriterParams(); params.setResolution(92); MyIIOMetadata metadata = new MyIIOMetadata(); new ImageIOTIFFImageWriter().updateMetadata(null, metadata, params); Assert.assertEquals(metadata.mergeNode, "javax_imageio_tiff_image_1.0"); } static class MyIIOMetadata extends IIOMetadata { String mergeNode; MyIIOMetadata() { super(true, "javax_imageio_tiff_image_1.0", null, null, null); } public boolean isReadOnly() { return false; } public Node getAsTree(String formatName) { IIOMetadataNode node = new IIOMetadataNode(); node.appendChild(new IIOMetadataNode("Dimension")); return node; } public void mergeTree(String formatName, Node root) { mergeNode = root.getNodeName(); } public void reset() { } }; } ././@LongLink0100644 0000000 0000000 00000000146 13777276623 011660 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/io/TempResourceURIGeneratorTestCase.javaxmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/io/TempResourceURIGeneratorTestCase.jav0100644 0000000 0000000 00000004565 13777276623 032571 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.xmlgraphics.io; import java.net.URI; import java.util.HashSet; import java.util.Set; import java.util.regex.Pattern; import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertTrue; public class TempResourceURIGeneratorTestCase { private TempResourceURIGenerator sut = new TempResourceURIGenerator("test"); @Test public void testGenerate() { URI first = sut.generate(); URI second = sut.generate(); Pattern regex = Pattern.compile("tmp:///test.*"); assertTrue(regex.matcher(first.toASCIIString()).matches()); assertTrue(regex.matcher(second.toASCIIString()).matches()); assertNotSame(first, second); // Test that they are unique over a large number of calls to generate() Set uniqueSet = new HashSet(); int numberOfTests = 1000; for (int i = 0; i < numberOfTests; i++) { uniqueSet.add(sut.generate()); } assertEquals(numberOfTests, uniqueSet.size()); } @Test public void testIsTemURI() { assertTrue(testTempURI("tmp:///test")); assertTrue(testTempURI("tmp://test")); assertTrue(testTempURI("tmp:/test")); assertTrue(testTempURI("tmp:test")); assertFalse(testTempURI("tmp/test")); assertFalse(testTempURI("temp:///test")); } private boolean testTempURI(String uriString) { return TempResourceURIGenerator.isTempURI(URI.create(uriString)); } } xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/io/URIResolverAdapterTestCase.java0100644 0000000 0000000 00000006170 13777276623 031542 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.xmlgraphics.io; import java.io.IOException; import java.io.InputStream; import java.io.StringWriter; import java.net.URI; import java.net.URL; import javax.xml.transform.Source; import javax.xml.transform.TransformerException; import javax.xml.transform.sax.SAXSource; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; import static org.junit.Assert.assertEquals; import org.apache.commons.io.IOUtils; import org.apache.xml.resolver.tools.CatalogResolver; public class URIResolverAdapterTestCase { private final URI textFileURI = URI.create("test:catalog:resolver:testResource.txt"); private final URI httpURL = URI.create("test:http:protocol:test.html"); private final String pathOfTestFile = "src/test/resources/org/apache/xmlgraphics/io/test-catalog.xml"; @Before public void setUp() { System.setProperty("xml.catalog.files", pathOfTestFile); } @Test @Ignore("Literally no idea why this doesn't work... Gonna look at the catalog resolver source") public void testCatalogResolver() throws TransformerException, IOException { CatalogResolver catalogResolver = new CatalogResolver(); Source src = catalogResolver.resolve(textFileURI.toASCIIString(), null); if (src instanceof SAXSource) { testInputStream(new URL(src.getSystemId()).openStream()); } } @Test @Ignore("Literally no idea why this doesn't work... Gonna look at the catalog resolver source") public void testCatalogResolverInAdapter() throws IOException { ResourceResolver resourceResolver = new URIResolverAdapter(new CatalogResolver()); testInputStream(resourceResolver.getResource(textFileURI)); } private void testInputStream(InputStream stream) throws IOException { StringWriter writer = new StringWriter(); IOUtils.copy(stream, writer); assertEquals("This is a text file used to test the CatalogResolver\n", writer.toString()); } @Test public void testHttpProtocol() throws TransformerException { String url = "http://svn.apache.org/repos/asf/xmlgraphics/fop/trunk/test/resources/images/test.html"; CatalogResolver catalogResolver = new CatalogResolver(); Source src = catalogResolver.resolve(httpURL.toASCIIString(), null); assertEquals(url, src.getSystemId()); } } xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/io/XmlSourceUtilTestCase.java0100644 0000000 0000000 00000020013 13777276623 030627 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.xmlgraphics.io; import java.io.IOException; import java.io.InputStream; import java.io.Reader; import java.io.StringWriter; import javax.imageio.stream.ImageInputStream; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.Source; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.sax.SAXSource; import javax.xml.transform.stream.StreamSource; import org.junit.Before; import org.junit.Test; import org.xml.sax.InputSource; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import org.apache.commons.io.IOUtils; import org.apache.xmlgraphics.image.loader.ImageSource; import static org.apache.xmlgraphics.io.XmlSourceUtil.closeQuietly; import static org.apache.xmlgraphics.io.XmlSourceUtil.getInputStream; import static org.apache.xmlgraphics.io.XmlSourceUtil.hasInputStream; import static org.apache.xmlgraphics.io.XmlSourceUtil.hasReader; import static org.apache.xmlgraphics.io.XmlSourceUtil.needInputStream; import static org.apache.xmlgraphics.io.XmlSourceUtil.removeStreams; public class XmlSourceUtilTestCase { private StreamSource streamSource; private SAXSource saxSource; private InputSource inputSource; private ImageSource imgSource; private ImageInputStream imgInStream; private DOMSource domSource; private StringWriter writer; private InputStream testStream; private Reader reader; @Before public void setUp() throws IOException, ParserConfigurationException { testStream = mock(InputStream.class); reader = mock(Reader.class); streamSource = mock(StreamSource.class); when(streamSource.getInputStream()).thenReturn(testStream); when(streamSource.getReader()).thenReturn(reader); saxSource = mock(SAXSource.class); inputSource = mock(InputSource.class); when(saxSource.getInputSource()).thenReturn(inputSource); when(inputSource.getByteStream()).thenReturn(testStream); when(inputSource.getCharacterStream()).thenReturn(reader); imgSource = mock(ImageSource.class); imgInStream = mock(ImageInputStream.class); when(imgSource.getImageInputStream()).thenReturn(imgInStream); DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); domSource = new DOMSource(db.newDocument().createElement("test")); InputStream inStream = XmlSourceUtil.getInputStream(domSource); writer = new StringWriter(); IOUtils.copy(inStream, writer); } @Test public void testGetInputStream() throws ParserConfigurationException, IOException { getInputStream(streamSource); verify(streamSource).getInputStream(); getInputStream(saxSource); verify(inputSource).getByteStream(); getInputStream(imgSource); verify(imgSource).getImageInputStream(); assertEquals("", writer.toString()); // Test negative case Source src = mock(Source.class); assertNull(getInputStream(src)); getInputStream(null); } @Test public void testNeedInputStream() throws IOException, ParserConfigurationException { assertEquals(testStream, needInputStream(streamSource)); assertEquals(testStream, needInputStream(saxSource)); needInputStream(imgSource); verify(imgSource).getImageInputStream(); assertEquals("", writer.toString()); } @Test(expected = IllegalArgumentException.class) public void testNeedInputStreamFailureCaseSource() { Source src = mock(Source.class); needInputStream(src); } @Test(expected = IllegalArgumentException.class) public void testNeedInputStreamFailureCaseStreamSource() { needInputStream(mock(StreamSource.class)); } @Test(expected = IllegalArgumentException.class) public void testNeedInputStreamFailureCaseSAXSource() { needInputStream(mock(SAXSource.class)); } public void testNeedInputStreamFailureCaseDOMSource() throws IOException { InputStream inStream = needInputStream(new DOMSource()); StringWriter writer = new StringWriter(); IOUtils.copy(inStream, writer); assertEquals("", writer.toString()); } @Test(expected = AssertionError.class) public void testNeedInputStreamFailureCaseStreamImage() { needInputStream(mock(ImageSource.class)); } @Test(expected = IllegalArgumentException.class) public void testNeedInputStreamFailureCaseNullArg() { needInputStream(null); } @Test public void testHasReader() { assertTrue(hasReader(streamSource)); assertTrue(hasReader(saxSource)); when(streamSource.getReader()).thenReturn(null); when(inputSource.getCharacterStream()).thenReturn(null); assertFalse(hasReader(streamSource)); assertFalse(hasReader(saxSource)); assertFalse(hasReader(imgSource)); assertFalse(hasReader(domSource)); hasReader(null); } @Test public void testRemoveStreams() { removeStreams(streamSource); verify(streamSource).setInputStream(null); verify(streamSource).setReader(null); removeStreams(imgSource); verify(imgSource).setImageInputStream(null); removeStreams(saxSource); verify(inputSource).setByteStream(null); verify(inputSource).setCharacterStream(null); removeStreams(null); } @Test public void testCloseQuietlyStreamSource() throws IOException { closeQuietly(streamSource); verify(reader).close(); verify(streamSource).setInputStream(null); verify(streamSource).setReader(null); } @Test public void testCloseQuietlySaxSource() throws IOException { closeQuietly(saxSource); verify(testStream).close(); verify(reader).close(); verify(inputSource).setByteStream(null); verify(inputSource).setCharacterStream(null); } @Test public void testCloseQuietlyImageSource() throws IOException { closeQuietly(imgSource); verify(imgInStream).close(); verify(imgSource).setImageInputStream(null); } @Test public void testCloseQuietlyNull() { XmlSourceUtil.closeQuietly(null); } @Test public void testHasInputStream() { assertTrue(hasInputStream(streamSource)); assertTrue(hasInputStream(saxSource)); assertTrue(hasInputStream(imgSource)); assertTrue(hasInputStream(domSource)); assertFalse(hasInputStream(mock(StreamSource.class))); assertFalse(hasInputStream(mock(SAXSource.class))); // Can't do the ImageSource test because of an assert, do we want that assert there? // assertFalse(hasInputStream(mock(ImageSource.class))); assertFalse(hasInputStream(mock(StreamSource.class))); } } xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/java2d/GraphicContextTestCase.java0100644 0000000 0000000 00000003042 13777276623 031535 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: GraphicContextTestCase.java 1732019 2016-02-24 05:01:10Z gadams $ */ package org.apache.xmlgraphics.java2d; import java.awt.Color; import java.awt.GradientPaint; import java.awt.geom.Point2D; import org.junit.Test; import static org.junit.Assert.assertEquals; public class GraphicContextTestCase { @Test public void testSetPaint() { GraphicContext gc = new GraphicContext(); Color red = Color.RED; gc.setPaint(red); assertEquals(red, gc.getColor()); Point2D start = new Point2D.Float(0, 0); Point2D end = new Point2D.Float(50, 50); GradientPaint gp = new GradientPaint(start, Color.RED, end, Color.BLUE); gc.setPaint(gp); assertEquals(Color.BLACK, gc.getColor()); } } ././@LongLink0100644 0000000 0000000 00000000167 13777276623 011663 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/java2d/GraphicsConfigurationWithTransparencyTestCase.javaxmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/java2d/GraphicsConfigurationWithTranspa0100644 0000000 0000000 00000006040 13777276623 032715 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.xmlgraphics.java2d; import java.awt.GraphicsConfiguration; import java.awt.Transparency; import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import java.awt.image.ColorModel; import org.junit.Before; import org.junit.Test; import static org.junit.Assert.assertEquals; /** * Test case for {@link GraphicsConfigurationWithTransparency}. */ public class GraphicsConfigurationWithTransparencyTestCase { private ColorModel transparencyColorModel; private ColorModel nonTransparencyColorModel; private GraphicsConfiguration sut; @Before public void setUp() { sut = new GraphicsConfigurationWithTransparency(); transparencyColorModel = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB).getColorModel(); nonTransparencyColorModel = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB).getColorModel(); } @Test public void testGetNormalizationTransformation() { AffineTransform transform = new AffineTransform(2, 0, 0, 2, 0, 0); assertEquals(transform, sut.getNormalizingTransform()); } void testImage(int width, int height, boolean hasTransparency, BufferedImage image) { assertEquals(width, image.getWidth()); assertEquals(height, image.getHeight()); assertEquals(hasTransparency, image.getColorModel().hasAlpha()); } @Test public void testCreateCompatibleImage() { testImage(1, 2, true, sut.createCompatibleImage(1, 2, Transparency.TRANSLUCENT)); testImage(100, 90, true, sut.createCompatibleImage(100, 90, Transparency.TRANSLUCENT)); testImage(1, 2, false, sut.createCompatibleImage(1, 2, Transparency.OPAQUE)); testImage(1010, 2020, false, sut.createCompatibleImage(1010, 2020, Transparency.OPAQUE)); // test the 2 argument overriden method testImage(1, 2, true, sut.createCompatibleImage(1, 2)); testImage(1010, 2020, true, sut.createCompatibleImage(1010, 2020)); } @Test public void testGetColorModel() { assertEquals(transparencyColorModel, sut.getColorModel()); assertEquals(transparencyColorModel, sut.getColorModel(Transparency.TRANSLUCENT)); assertEquals(nonTransparencyColorModel, sut.getColorModel(Transparency.OPAQUE)); } } ././@LongLink0100644 0000000 0000000 00000000172 13777276623 011657 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/java2d/GraphicsConfigurationWithoutTransparencyTestCase.javaxmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/java2d/GraphicsConfigurationWithoutTran0100644 0000000 0000000 00000005522 13777276623 032745 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.xmlgraphics.java2d; import java.awt.GraphicsConfiguration; import java.awt.Transparency; import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import java.awt.image.ColorModel; import org.junit.Before; import org.junit.Test; import static org.junit.Assert.assertEquals; public class GraphicsConfigurationWithoutTransparencyTestCase { private ColorModel nonTransparencyColorModel; private GraphicsConfiguration sut; @Before public void setUp() { sut = new GraphicsConfigurationWithoutTransparency(); nonTransparencyColorModel = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB).getColorModel(); } @Test public void testGetNormalizationTransformation() { AffineTransform transform = new AffineTransform(2, 0, 0, 2, 0, 0); assertEquals(transform, sut.getNormalizingTransform()); } void testImage(int width, int height, boolean hasTransparency, BufferedImage image) { assertEquals(width, image.getWidth()); assertEquals(height, image.getHeight()); assertEquals(hasTransparency, image.getColorModel().hasAlpha()); } @Test public void testCreateCompatibleImage() { testImage(1, 2, false, sut.createCompatibleImage(1, 2, Transparency.TRANSLUCENT)); testImage(100, 90, false, sut.createCompatibleImage(100, 90, Transparency.TRANSLUCENT)); testImage(1, 2, false, sut.createCompatibleImage(1, 2, Transparency.OPAQUE)); testImage(1010, 2020, false, sut.createCompatibleImage(1010, 2020, Transparency.OPAQUE)); // test the 2 argument overriden method testImage(1, 2, false, sut.createCompatibleImage(1, 2)); testImage(1010, 2020, false, sut.createCompatibleImage(1010, 2020)); } @Test public void testGetColorModel() { assertEquals(nonTransparencyColorModel, sut.getColorModel()); assertEquals(nonTransparencyColorModel, sut.getColorModel(Transparency.TRANSLUCENT)); assertEquals(nonTransparencyColorModel, sut.getColorModel(Transparency.OPAQUE)); } } ././@LongLink0100644 0000000 0000000 00000000146 13777276623 011660 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/java2d/color/ColorConverterTestCase.javaxmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/java2d/color/ColorConverterTestCase.jav0100644 0000000 0000000 00000003644 13777276623 032546 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ColorConverterTestCase.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.java2d.color; import java.awt.Color; import java.awt.color.ColorSpace; import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; public class ColorConverterTestCase { @Test public void testToGray() throws Exception { ColorConverter converter = GrayScaleColorConverter.getInstance(); Color rgb = new Color(255, 184, 0); Color gray = converter.convert(rgb); ColorSpaceOrigin origin = ColorSpaces.getColorSpaceOrigin(gray.getColorSpace()); assertEquals("#CMYK", origin.getProfileName()); assertNull(origin.getProfileURI()); assertEquals(ColorSpace.TYPE_CMYK, gray.getColorSpace().getType()); float[] comps = gray.getColorComponents(null); assertEquals(4, comps.length); assertEquals(0.0f, comps[0], 0.1f); assertEquals(0.0f, comps[1], 0.1f); assertEquals(0.0f, comps[2], 0.1f); assertEquals(0.273f, comps[3], 0.01f); assertEquals(0xFFB9B9B9, gray.getRGB()); } } ././@LongLink0100644 0000000 0000000 00000000155 13777276623 011660 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/java2d/color/ColorWithAlternativesTestCase.javaxmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/java2d/color/ColorWithAlternativesTestC0100644 0000000 0000000 00000005245 13777276623 032623 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ColorWithAlternativesTestCase.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.java2d.color; import java.awt.Color; import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; /** * Tests the {@link ColorWithAlternatives} class. */ public class ColorWithAlternativesTestCase { @Test public void testEquals() throws Exception { Color col1 = new ColorWithAlternatives(255, 204, 0, null); Color col2 = new Color(255, 204, 0); assertEquals(col1, col2); assertEquals(col2, col1); CIELabColorSpace lab = ColorSpaces.getCIELabColorSpaceD50(); Color postgelbLab = lab.toColor(83.25f, 16.45f, 96.89f, 1.0f); col1 = new ColorWithAlternatives(255, 204, 0, new Color[] {postgelbLab}); //java.awt.Color tests on the sRGB value only assertEquals(col1, col2); assertEquals(col2, col1); } @Test public void testSameColor() throws Exception { Color col1 = new ColorWithAlternatives(255, 204, 0, null); Color col2 = new Color(255, 204, 0); //No alternatives. Only sRGB counts. assertTrue(ColorUtil.isSameColor(col1, col2)); CIELabColorSpace lab = ColorSpaces.getCIELabColorSpaceD50(); Color postgelbLab = lab.toColor(83.25f, 16.45f, 96.89f, 1.0f); col1 = new ColorWithAlternatives(255, 204, 0, new Color[] {postgelbLab}); //Same sRGB value but one color with alternatives: assertFalse(ColorUtil.isSameColor(col1, col2)); //Once the spotcolor naked and once as part of a color with alternatives assertFalse(ColorUtil.isSameColor(postgelbLab, col1)); //sRGB values is calculated from Lab color and doesn't exactly match the selected fallback assertFalse(postgelbLab.equals(col1)); } } xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/java2d/color/NamedColorTestCase.java0100644 0000000 0000000 00000007165 13777276623 031766 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: NamedColorTestCase.java 1829049 2018-04-13 09:37:06Z ssteiner $ */ package org.apache.xmlgraphics.java2d.color; import java.awt.Color; import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; /** * Tests named color spaces (and the CIE Lab color space implementation). */ public class NamedColorTestCase { private static final float POSTGELB_X = 0.6763079f; private static final float POSTGELB_Y = 0.6263507f; private static final float POSTGELB_Z = 0.04217565f; @Test public void testNamedColorWithCIELab() { CIELabColorSpace lab = ColorSpaces.getCIELabColorSpaceD50(); //CIE Lab definition of "Postgelb" (postal yellow) at D50 as defined by Swiss Post //Convert to XYZ float[] c1xyz = lab.toCIEXYZNative(83.25f, 16.45f, 96.89f); //Verify XYZ values are OK assertEquals(POSTGELB_X, c1xyz[0], 0.001f); assertEquals(POSTGELB_Y, c1xyz[1], 0.001f); assertEquals(POSTGELB_Z, c1xyz[2], 0.001f); //Build named color based on XYZ coordinates NamedColorSpace ncs = new NamedColorSpace("Postgelb", c1xyz); Color c1 = new Color(ncs, new float[] {1.0f}, 1.0f); assertEquals(ncs, c1.getColorSpace()); float[] comp = c1.getColorComponents(null); assertEquals(1, comp.length); assertEquals(1.0f, comp[0], 0.001f); float[] xyz = ncs.toCIEXYZ(new float[] {1.0f}); for (int i = 0; i < 3; i++) { assertEquals(c1xyz[i], xyz[i], 0.001f); } //NOTE: Allowing for some fuzziness due to differences in XYZ->sRGB calculation between //Java 1.5 and 6. assertEquals(254, c1.getRed(), 1f); assertEquals(195, c1.getGreen(), 2f); assertEquals(0, c1.getBlue()); } @Test public void testEquals() { NamedColorSpace ncs1 = new NamedColorSpace("Postgelb", new float[] {POSTGELB_X, POSTGELB_Y, POSTGELB_Z}); NamedColorSpace ncs2 = new NamedColorSpace("Postgelb", new float[] {POSTGELB_X, POSTGELB_Y, POSTGELB_Z}); assertEquals(ncs1, ncs2); //Construct the same NamedColorSpace via two different methods CIELabColorSpace lab = ColorSpaces.getCIELabColorSpaceD50(); Color postgelbLab = lab.toColor(83.25f, 16.45f, 96.89f, 1.0f); float[] xyz = lab.toCIEXYZ(postgelbLab.getColorComponents(null)); xyz[0] = POSTGELB_X; xyz[1] = POSTGELB_Y; xyz[2] = POSTGELB_Z; ncs1 = new NamedColorSpace("Postgelb", postgelbLab); ncs2 = new NamedColorSpace("Postgelb", xyz); assertEquals(ncs1, ncs2); //Compare with a similar color coming from sRGB Color rgb = new Color(255, 184, 0); ncs2 = new NamedColorSpace("PostgelbFromRGB", rgb); assertFalse(ncs1.equals(ncs2)); } } ././@LongLink0100644 0000000 0000000 00000000160 13777276623 011654 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/java2d/color/profile/ColorProfileUtilTestCase.javaxmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/java2d/color/profile/ColorProfileUtilTe0100644 0000000 0000000 00000003226 13777276623 032547 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ColorProfileUtilTestCase.java 1732019 2016-02-24 05:01:10Z gadams $ */ package org.apache.xmlgraphics.java2d.color.profile; import java.awt.color.ColorSpace; import java.awt.color.ICC_Profile; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import org.junit.Test; import static org.junit.Assert.assertTrue; public class ColorProfileUtilTestCase { @Test public void testIsDefaultsRGB() throws IOException { ICC_Profile profile = ICC_Profile.getInstance(ColorSpace.CS_sRGB); ByteArrayOutputStream baos = new ByteArrayOutputStream(); profile.write(baos); ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); ICC_Profile profileFromFile = ICC_Profile.getInstance(bais); assertTrue(ColorProfileUtil.isDefaultsRGB(profileFromFile)); } } ././@LongLink0100644 0000000 0000000 00000000167 13777276623 011663 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/java2d/color/profile/NamedColorProfileParserTestCase.javaxmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/java2d/color/profile/NamedColorProfileP0100644 0000000 0000000 00000005167 13777276623 032513 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: NamedColorProfileParserTestCase.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.java2d.color.profile; import java.awt.color.ICC_Profile; import java.io.InputStream; import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import org.apache.commons.io.IOUtils; import org.apache.xmlgraphics.java2d.color.NamedColorSpace; import org.apache.xmlgraphics.java2d.color.RenderingIntent; /** * Tests the {@link NamedColorProfileParser}. */ public class NamedColorProfileParserTestCase { private static final String NCP_EXAMPLE_FILE = "ncp-example.icc"; @Test public void testParser() throws Exception { InputStream in = getClass().getResourceAsStream(NCP_EXAMPLE_FILE); assertNotNull(NCP_EXAMPLE_FILE + " is missing!", in); ICC_Profile iccProfile; try { iccProfile = ICC_Profile.getInstance(in); } finally { IOUtils.closeQuietly(in); } NamedColorProfileParser parser = new NamedColorProfileParser(); NamedColorProfile ncp = parser.parseProfile(iccProfile); assertEquals("Named Color Profile Example", ncp.getProfileName()); assertEquals("The Apache Software Foundation", ncp.getCopyright()); assertEquals(RenderingIntent.PERCEPTUAL, ncp.getRenderingIntent()); NamedColorSpace[] namedColors = ncp.getNamedColors(); assertEquals(2, namedColors.length); NamedColorSpace ncs; ncs = namedColors[0]; assertEquals("Postgelb", ncs.getColorName()); float[] xyz = ncs.getXYZ(); assertEquals(0.6763079f, xyz[0], 0.01f); assertEquals(0.6263507f, xyz[1], 0.01f); assertEquals(0.04217565f, xyz[2], 0.01f); ncs = namedColors[1]; assertEquals("MyRed", ncs.getColorName()); } } xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/java2d/ps/PSGraphics2DTestCase.java0100644 0000000 0000000 00000014515 13777276623 031435 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: PSGraphics2DTestCase.java 1845492 2018-11-01 15:54:06Z ssteiner $ */ package org.apache.xmlgraphics.java2d.ps; import java.awt.AlphaComposite; import java.awt.Rectangle; import java.awt.Shape; import java.awt.TexturePaint; import java.awt.geom.AffineTransform; import java.awt.geom.Line2D; import java.awt.geom.Rectangle2D; import java.awt.geom.RoundRectangle2D; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.IOException; import org.junit.Before; import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import org.apache.xmlgraphics.java2d.GraphicContext; import org.apache.xmlgraphics.ps.PSGenerator; import org.apache.xmlgraphics.ps.PSState; public class PSGraphics2DTestCase { private PSGenerator gen; private PSGraphics2D gfx2d; private final AffineTransform transform = new AffineTransform(1, 0, 0, -1, 0, 792); @Before public void setup() { gen = mock(PSGenerator.class); createGraphics2D(); PSState pState = new PSState(); when(gen.getCurrentState()).thenReturn(pState); } private void createGraphics2D() { gfx2d = new PSGraphics2D(false, gen); gfx2d.setGraphicContext(new GraphicContext()); gfx2d.setTransform(transform); } @Test public void draw() throws IOException { assertEquals(gfx2d.getTransform(), transform); gfx2d.draw(new Rectangle(10, 10, 100, 100)); verify(gen, times(1)).concatMatrix(transform); } @Test public void testShouldBeClipped() { Shape line = new Line2D.Float(10, 10, 50, 50); Shape clipArea = new Rectangle2D.Float(20, 20, 100, 100); assertTrue(gfx2d.shouldBeClipped(clipArea, line)); Shape rect = new Rectangle2D.Float(30, 30, 40, 40); assertFalse(gfx2d.shouldBeClipped(clipArea, rect)); } @Test public void testFill() { ByteArrayOutputStream out = new ByteArrayOutputStream(); PSGenerator gen = new PSGenerator(out); PSGraphics2D p = new PSGraphics2D(false, gen); p.setGraphicContext(new GraphicContext()); p.fill(new RoundRectangle2D.Float()); out.reset(); p.fill(new RoundRectangle2D.Float()); assertEquals(out.toString(), "GS\nN\n/f1943450110{0 0 M\n0 0 L\n0 0 0 0 0 0 C\n0 0 L\n0 0 0 0 0 0 C\n" + "0 0 L\n0 0 0 0 0 0 C\n0 0 L\n0 0 0 0 0 0 C\ncp}def\nf1943450110\nf\nGR\n"); out.reset(); BufferedImage img = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB); p.drawImage(img, 0, 0, null); String res = "[1 0 0 1 0 0] CT\n" + "GS\n" + "0 0 translate\n" + "%AXGBeginBitmap: java.awt.image.BufferedImage\n" + "{{\n" + "/RawData currentfile /ASCII85Decode filter def\n" + "/Data RawData /FlateDecode filter def\n" + "/DeviceRGB setcolorspace\n"; assertTrue(out.toString(), out.toString().startsWith("GS\n" + res)); out.reset(); p.drawRenderedImage(img, new AffineTransform()); assertTrue(out.toString(), out.toString().startsWith("GS\n[1 0 0 1 0 0] CT\n" + res)); out.reset(); p.writeClip(new RoundRectangle2D.Float()); assertEquals(out.toString(), "N\n" + "0 0 M\n" + "0 0 L\n" + "0 0 0 0 0 0 C\n" + "0 0 L\n" + "0 0 0 0 0 0 C\n" + "0 0 L\n" + "0 0 0 0 0 0 C\n" + "0 0 L\n" + "0 0 0 0 0 0 C\n" + "cp\n" + "clip\n"); out.reset(); p.drawString("hi", 0f, 0f); assertTrue(out.toString(), out.toString().startsWith("GS\nN\n/f")); out.reset(); TexturePaint tp = new TexturePaint(img, new Rectangle()); p.setPaint(tp); p.fill(new Rectangle()); assertTrue(out.toString().startsWith("GS\n<<\n/PatternType 1\n")); p.dispose(); } @Test public void testAcrobatDownsample() { ByteArrayOutputStream out = new ByteArrayOutputStream(); PSGenerator gen = new PSGenerator(out); PSGraphics2D p = new PSGraphics2D(false, gen); p.setGraphicContext(new GraphicContext()); BufferedImage img = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB); TexturePaint tp = new TexturePaint(img, new Rectangle()); p.setPaint(tp); p.fill(new Rectangle()); assertTrue(out.toString().contains("1 1 8 matrix\n{<\nffffff\n>} false 3 colorimage")); out.reset(); gen.setAcrobatDownsample(true); p.fill(new Rectangle()); assertTrue(out.toString().contains("1 1 4 matrix\n{<\nfff\n>} false 3 colorimage")); p.dispose(); } @Test public void testFillAlpha() { ByteArrayOutputStream out = new ByteArrayOutputStream(); PSGenerator gen = new PSGenerator(out); PSGraphics2D p = new PSGraphics2D(false, gen); p.setGraphicContext(new GraphicContext()); p.setComposite(AlphaComposite.getInstance(3, 0)); p.fill(new Rectangle()); assertEquals(out.toString(), ""); p.setComposite(AlphaComposite.getInstance(3, 0.5f)); p.fill(new Rectangle()); assertTrue(out.toString().contains("\nN\n")); } } xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/ps/FormGeneratorTestCase.java0100644 0000000 0000000 00000010722 13777276623 030643 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id$ */ package org.apache.xmlgraphics.ps; import java.awt.Color; import java.awt.Dimension; import java.awt.color.ColorSpace; import java.awt.geom.Dimension2D; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.IOException; import org.junit.Assert; import org.junit.Test; import org.apache.xmlgraphics.java2d.Dimension2DDouble; import org.apache.xmlgraphics.java2d.color.NamedColorSpace; public class FormGeneratorTestCase { @Test public void testGeneratePaintProc() throws IOException { Dimension2D dimension = new Dimension2DDouble(300, 500); BufferedImage im = new BufferedImage(100, 75, BufferedImage.TYPE_INT_ARGB); ByteArrayOutputStream out = new ByteArrayOutputStream(); ImageFormGenerator formImageGen = new ImageFormGenerator("form", "title", dimension, im, false); PSGenerator gen = new PSGenerator(out); formImageGen.generatePaintProc(gen); String test = out.toString("UTF-8"); String expected = " form:Data 0 setfileposition\n" + "[300 0 0 500 0 0] CT\n" + "/DeviceRGB setcolorspace\n" + "<<\n"; Assert.assertTrue(test.contains(expected)); Assert.assertTrue(test.contains(" /DataSource form:Data")); Assert.assertTrue(test.contains(" /ImageMatrix [100 0 0 75 0 0]\n")); Assert.assertTrue(test.contains(" /BitsPerComponent 8\n")); Assert.assertTrue(test.contains(" /Height 75\n")); Assert.assertTrue(test.contains(" /ImageType 1\n")); Assert.assertTrue(test.contains(" /Decode [0 1 0 1 0 1]\n")); Assert.assertTrue(test.contains(">> image\n")); out.reset(); im = null; Color c = Color.BLUE; Dimension dimensionPX = new Dimension(200, 400); ImageEncoder enco = ImageEncodingHelper.createRenderedImageEncoder(im); ColorSpace cs = new NamedColorSpace("myColor", c); formImageGen = new ImageFormGenerator("form", "title", dimension, dimensionPX, enco, cs, false); gen = new PSGenerator(out); gen.setPSLevel(2); formImageGen.generatePaintProc(gen); test = out.toString("UTF-8"); expected = " userdict /i 0 put\n" + "[300 0 0 500 0 0] CT\n" + "/DeviceGray setcolorspace\n" + "<<\n"; Assert.assertTrue(test.contains(expected)); Assert.assertTrue(test.contains(" /DataSource { form:Data i get /i i 1 add store } bind\n")); Assert.assertTrue(test.contains(" /ImageMatrix [200 0 0 400 0 0]\n")); Assert.assertTrue(test.contains(" /Height 400\n")); Assert.assertTrue(test.contains(" /BitsPerComponent 8\n")); Assert.assertTrue(test.contains(" /ImageType 1\n")); Assert.assertTrue(test.contains(" /Decode [0 1]\n")); Assert.assertTrue(test.contains(" /Width 200\n")); Assert.assertTrue(test.contains(">> image\n")); } @Test public void testFlateDecodeCommand() throws IOException { Dimension2D dimension = new Dimension2DDouble(300, 500); BufferedImage im = new BufferedImage(100, 75, BufferedImage.TYPE_INT_ARGB); ByteArrayOutputStream out = new ByteArrayOutputStream(); ImageFormGenerator formImageGen = new ImageFormGenerator("form", "title", dimension, im, false); PSGenerator gen = new PSGenerator(out); formImageGen.generate(gen); String test = out.toString("UTF-8"); Assert.assertTrue(test.contains("/ASCII85Decode filter\n")); //FlateDecode at DataSource so executed on page load rather than document load so viewer loads faster Assert.assertTrue(test.contains("/DataSource form:Data /FlateDecode filter\n")); } } xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/ps/ImageEncodingHelperTestCase.java0100644 0000000 0000000 00000014240 13777276623 031721 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ImageEncodingHelperTestCase.java 1732019 2016-02-24 05:01:10Z gadams $ */ package org.apache.xmlgraphics.ps; import java.awt.Color; import java.awt.Graphics2D; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; import java.awt.image.DataBuffer; import java.awt.image.DirectColorModel; import java.awt.image.WritableRaster; import java.io.IOException; import java.util.Arrays; import org.junit.Test; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import static org.junit.Assert.assertTrue; import static org.mockito.Matchers.anyInt; import static org.mockito.Matchers.anyObject; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import org.apache.commons.io.output.ByteArrayOutputStream; public class ImageEncodingHelperTestCase { private BufferedImage prepareImage(BufferedImage image) { Graphics2D ig = image.createGraphics(); ig.scale(.5, .5); ig.setPaint(new Color(128, 0, 0)); ig.fillRect(0, 0, 100, 50); ig.setPaint(Color.orange); ig.fillRect(100, 0, 100, 50); ig.setPaint(Color.yellow); ig.fillRect(0, 50, 100, 50); ig.setPaint(Color.red); ig.fillRect(100, 50, 100, 50); ig.setPaint(new Color(255, 127, 127)); ig.fillRect(0, 100, 100, 50); ig.setPaint(Color.black); ig.draw(new Rectangle2D.Double(0.5, 0.5, 199, 149)); ig.dispose(); return image; } /** * Tests encodeRenderedImageWithDirectColorModeAsRGB(). Tests the optimised method against the * non-optimised method(encodeRenderedImageAsRGB) to ensure the BufferedImage produced are the * same. * @throws IOException if an I/O error occurs. */ @Test public void testEncodeRenderedImageWithDirectColorModelAsRGB() throws IOException { BufferedImage image = new BufferedImage(100, 75, BufferedImage.TYPE_INT_ARGB); image = prepareImage(image); ByteArrayOutputStream optimized = new ByteArrayOutputStream(); ImageEncodingHelper.encodeRenderedImageWithDirectColorModelAsRGB(image, optimized); ByteArrayOutputStream nonoptimized = new ByteArrayOutputStream(); ImageEncodingHelper.encodeRenderedImageAsRGB(image, nonoptimized); assertTrue(Arrays.equals(nonoptimized.toByteArray(), optimized.toByteArray())); } /** * Tests a BGR versus RBG image. Debugging shows the BGR follows the optimizeWriteTo() (which * is intended). The bytes are compared with the RBG image, which happens to follow the * writeRGBTo(). * * @throws IOException */ @Test public void testRGBAndBGRImages() throws IOException { BufferedImage imageBGR = new BufferedImage(100, 75, BufferedImage.TYPE_3BYTE_BGR); imageBGR = prepareImage(imageBGR); BufferedImage imageRGB = new BufferedImage(100, 75, BufferedImage.TYPE_INT_BGR); imageRGB = prepareImage(imageRGB); ImageEncodingHelper imageEncodingHelperBGR = new ImageEncodingHelper(imageBGR, false); ImageEncodingHelper imageEncodingHelperRGB = new ImageEncodingHelper(imageRGB, false); ByteArrayOutputStream baosBGR = new ByteArrayOutputStream(); imageEncodingHelperBGR.encode(baosBGR); ByteArrayOutputStream baosRGB = new ByteArrayOutputStream(); imageEncodingHelperRGB.encode(baosRGB); assertTrue(Arrays.equals(baosBGR.toByteArray(), baosRGB.toByteArray())); } /** * Tests encodeRenderedImageWithDirectColorModeAsRGB(). Uses mocking to test the method * implementation. * @throws IOException if an I/O error occurs. */ @Test public void testMockedEncodeRenderedImageWithDirectColorModelAsRGB() throws IOException { BufferedImage image = mock(BufferedImage.class); final int[] templateMasks = new int[] {0x00ff0000 /*R*/, 0x0000ff00 /*G*/, 0x000000ff /*B*/, 0xff000000 /*A*/}; DirectColorModel dcm = new DirectColorModel(255, templateMasks[0], templateMasks[1], templateMasks[2], templateMasks[3]); WritableRaster raster = mock(WritableRaster.class); DataBuffer buffer = mock(DataBuffer.class); when(image.getColorModel()).thenReturn(dcm); when(image.getRaster()).thenReturn(raster); when(raster.getDataBuffer()).thenReturn(buffer); when(buffer.getDataType()).thenReturn(DataBuffer.TYPE_INT); when(image.getWidth()).thenReturn(3); when(image.getHeight()).thenReturn(3); final int expectedValue = 1 + 2 << 8 + 3 << 16; Answer ans = new Answer() { public Object answer(InvocationOnMock invocation) throws Throwable { Object[] args = invocation.getArguments(); int[] data = (int[]) args[4]; Arrays.fill(data, expectedValue); return null; } }; when(raster.getDataElements(anyInt(), anyInt(), anyInt(), anyInt(), anyObject())) .thenAnswer(ans); ByteArrayOutputStream optimized = new ByteArrayOutputStream(); ImageEncodingHelper.encodeRenderedImageWithDirectColorModelAsRGB(image, optimized); byte[] expectedByteArray = new byte[27]; Arrays.fill(expectedByteArray, (byte) expectedValue); assertTrue(Arrays.equals(expectedByteArray, optimized.toByteArray())); } } xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/ps/PSEscapeTestCase.java0100644 0000000 0000000 00000004562 13777276623 027541 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: PSEscapeTestCase.java 1365650 2012-07-25 15:59:30Z mehdi $ */ package org.apache.xmlgraphics.ps; import org.junit.Test; import static org.junit.Assert.assertEquals; /** * Tests literal text string escaping. */ public class PSEscapeTestCase { @Test public void testBasics() throws Exception { StringBuffer sb = new StringBuffer(); PSGenerator.escapeChar('a', sb); PSGenerator.escapeChar('b', sb); PSGenerator.escapeChar('c', sb); PSGenerator.escapeChar('!', sb); assertEquals("abc!", sb.toString()); sb.setLength(0); PSGenerator.escapeChar('0', sb); PSGenerator.escapeChar('\t', sb); PSGenerator.escapeChar('(', sb); PSGenerator.escapeChar('x', sb); PSGenerator.escapeChar(')', sb); PSGenerator.escapeChar('\n', sb); PSGenerator.escapeChar('\u001E', sb); // PSGenerator.escapeChar('\u00E4', sb); //a umlaut PSGenerator.escapeChar('\u20AC', sb); //EURO Sign assertEquals("0\\t\\(x\\)\\n\\036\\344?", sb.toString()); } @Test public void testStringToDSC() throws Exception { String escaped; escaped = PSGenerator.convertStringToDSC("0\t(x)\n\u001E\u00E4\u20AC"); assertEquals("0\\t\\(x\\)\\n\\036\\344?", escaped); escaped = PSGenerator.convertStringToDSC("0\t(x)\n\u001E\u00E4 \u20AC"); assertEquals("(0\\t\\(x\\)\\n\\036\\344 ?)", escaped); escaped = PSGenerator.convertStringToDSC("0\t(x)\n\u001E\u00E4\u20AC", true); assertEquals("(0\\t\\(x\\)\\n\\036\\344?)", escaped); } } xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/ps/PSPageDeviceDictionaryTestCase.java0100644 0000000 0000000 00000002472 13777276623 032361 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.xmlgraphics.ps; import java.util.HashMap; import java.util.Map; import org.junit.Assert; import org.junit.Test; public class PSPageDeviceDictionaryTestCase { @Test public void testPSPageDeviceDictionary() { PSPageDeviceDictionary p = new PSPageDeviceDictionary(); p.setFlushOnRetrieval(true); Map m = new HashMap(); m.put("x", "y"); p.putAll(m); Assert.assertEquals(p.getContent(), "<<\n x y\n>>"); Assert.assertEquals(p.getContent(), ""); } } xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/ps/dsc/DSCParserTestCase.java0100644 0000000 0000000 00000004133 13777276623 030427 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: DSCParserTestCase.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.ps.dsc; import java.io.ByteArrayInputStream; import org.junit.Test; public class DSCParserTestCase { private final String correctDSC = "%!PS-Adobe-3.0\n" + "%%LanguageLevel: 3\n" + "%%EOF"; private final String spuriousContentAfterEOF = "%!PS-Adobe-3.0\n" + "%%LanguageLevel: 3\n" + "%%EOF\n" + "%%SpuriousContent"; @Test public void eofDetectedWhenCheckEOFEnabled() throws Exception { parseDSC(correctDSC, true); } @Test public void eofDetectedWhenCheckEOFDisabled() throws Exception { parseDSC(correctDSC, false); } @Test(expected = DSCException.class) public void spuriousContentDetected() throws Exception { parseDSC(spuriousContentAfterEOF, true); } @Test public void spuriousContentIgnored() throws Exception { parseDSC(spuriousContentAfterEOF, false); } private void parseDSC(String dsc, boolean checkEOF) throws Exception { DSCParser parser = new DSCParser(new ByteArrayInputStream(dsc.getBytes("US-ASCII"))); parser.setCheckEOF(checkEOF); while (parser.hasNext()) { parser.next(); } } } xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/ps/dsc/ListenerTestCase.java0100644 0000000 0000000 00000011043 13777276623 030424 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ListenerTestCase.java 1681108 2015-05-22 13:26:12Z ssteiner $ */ package org.apache.xmlgraphics.ps.dsc; import java.io.IOException; import java.io.InputStream; import java.util.Map; import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; import org.apache.commons.io.IOUtils; import org.apache.xmlgraphics.ps.DSCConstants; import org.apache.xmlgraphics.ps.dsc.events.DSCComment; import org.apache.xmlgraphics.ps.dsc.events.DSCCommentLanguageLevel; import org.apache.xmlgraphics.ps.dsc.events.DSCEvent; /** * Tests the listener functionality on the DSC parser. */ public class ListenerTestCase { /** * Tests {@link DSCParser#setFilter(DSCFilter)}. * @throws Exception if an error occurs */ @Test public void testFilter() throws Exception { InputStream in = getClass().getResourceAsStream("test1.txt"); try { DSCParser parser = new DSCParser(in); parser.setFilter(new DSCFilter() { public boolean accept(DSCEvent event) { //Filter out all non-DSC comments return !event.isComment(); } }); while (parser.hasNext()) { DSCEvent event = parser.nextEvent(); if (parser.getCurrentEvent().isComment()) { fail("Filter failed. Comment found."); } } } finally { IOUtils.closeQuietly(in); } } /** * Tests listeners on DSCParser. * @throws Exception if an error occurs */ @Test public void testListeners() throws Exception { InputStream in = getClass().getResourceAsStream("test1.txt"); try { final Map results = new java.util.HashMap(); DSCParser parser = new DSCParser(in); //Filter the prolog parser.addListener(new DSCListener() { public void processEvent(DSCEvent event, DSCParser parser) throws IOException, DSCException { if (event.isDSCComment()) { DSCComment comment = event.asDSCComment(); if (DSCConstants.BEGIN_PROLOG.equals(comment.getName())) { //Skip until end of prolog while (parser.hasNext()) { DSCEvent e = parser.nextEvent(); if (e.isDSCComment()) { if (DSCConstants.END_PROLOG.equals( e.asDSCComment().getName())) { parser.next(); break; } } } } } } }); //Listener for the language level parser.addListener(new DSCListener() { public void processEvent(DSCEvent event, DSCParser parser) throws IOException, DSCException { if (event instanceof DSCCommentLanguageLevel) { DSCCommentLanguageLevel level = (DSCCommentLanguageLevel) event; results.put("level", level.getLanguageLevel()); } } }); int count = 0; while (parser.hasNext()) { DSCEvent event = parser.nextEvent(); System.out.println(event); count++; } assertEquals(12, count); assertEquals(1, results.get("level")); } finally { IOUtils.closeQuietly(in); } } } ././@LongLink0100644 0000000 0000000 00000000156 13777276623 011661 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/ps/dsc/events/DSCCommentBoundingBoxTestCase.javaxmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/ps/dsc/events/DSCCommentBoundingBoxTest0100644 0000000 0000000 00000004344 13777276623 032530 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: DSCCommentBoundingBoxTestCase.java 1365650 2012-07-25 15:59:30Z mehdi $ */ package org.apache.xmlgraphics.ps.dsc.events; import java.awt.Rectangle; import java.awt.geom.Rectangle2D; import org.junit.Test; import static org.junit.Assert.assertEquals; import org.apache.xmlgraphics.ps.dsc.DSCCommentFactory; public class DSCCommentBoundingBoxTestCase { @Test public void testBoundingBox() throws Exception { DSCComment comment = DSCCommentFactory.createDSCCommentFor("BoundingBox"); DSCCommentBoundingBox bbox = (DSCCommentBoundingBox) comment; bbox.parseValue("289 412 306 429"); Rectangle refRect = new Rectangle(289, 412, 306 - 289, 429 - 412); assertEquals(refRect, bbox.getBoundingBox()); comment = DSCCommentFactory.createDSCCommentFor("BoundingBox"); bbox = (DSCCommentBoundingBox) comment; bbox.parseValue("289.12 412.2 306.777 429.11"); Rectangle2D refRect2D = new Rectangle2D.Double( 289.12, 412.2, 306.777 - 289.12, 429.11 - 412.2); assertEquals(refRect2D, bbox.getBoundingBox()); comment = DSCCommentFactory.createDSCCommentFor("HiResBoundingBox"); bbox = (DSCCommentHiResBoundingBox) comment; bbox.parseValue("289.12 412.2 306.777 429.11"); refRect2D = new Rectangle2D.Double( 289.12, 412.2, 306.777 - 289.12, 429.11 - 412.2); assertEquals(refRect2D, bbox.getBoundingBox()); } } ././@LongLink0100644 0000000 0000000 00000000147 13777276623 011661 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/ps/dsc/events/DSCValueParserTestCase.javaxmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/ps/dsc/events/DSCValueParserTestCase.ja0100644 0000000 0000000 00000005330 13777276623 032401 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: DSCValueParserTestCase.java 1365650 2012-07-25 15:59:30Z mehdi $ */ package org.apache.xmlgraphics.ps.dsc.events; import java.util.List; import org.junit.Test; import static org.junit.Assert.assertEquals; public class DSCValueParserTestCase { private String[] toArray(List params) { return (String[]) params.toArray(new String[params.size()]); } @Test public void testText() throws Exception { DSCCommentBeginResource obj = new DSCCommentBeginResource(); String[] res = toArray(obj.splitParams("procset Test")); assertEquals(2, res.length); assertEquals("procset", res[0]); assertEquals("Test", res[1]); res = toArray(obj.splitParams("procset\tTest")); assertEquals(2, res.length); assertEquals("procset", res[0]); assertEquals("Test", res[1]); } @Test public void testParentheseText() throws Exception { DSCCommentBeginResource obj = new DSCCommentBeginResource(); String[] res = toArray(obj.splitParams("procset (Hello World!)")); assertEquals(2, res.length); assertEquals("procset", res[0]); assertEquals("Hello World!", res[1]); res = toArray(obj.splitParams("procset\t(Hello\t\\\\wonderful/ World!)")); assertEquals(2, res.length); assertEquals("procset", res[0]); assertEquals("Hello\t\\wonderful/ World!", res[1]); res = toArray(obj.splitParams("procset (Hello \\042wonderful\\042 World!) blahblah")); assertEquals(3, res.length); assertEquals("procset", res[0]); assertEquals("Hello \"wonderful\" World!", res[1]); assertEquals("blahblah", res[2]); //Parentheses not balanced res = toArray(obj.splitParams("procset (Hello (wonderful) World! blahblah")); assertEquals(2, res.length); assertEquals("procset", res[0]); assertEquals("Hello (wonderful) World! blahblah", res[1]); } } xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/ps/dsc/test1.txt0100644 0000000 0000000 00000000364 13777276623 026145 0ustar000000000 0000000 %!PS-Adobe-3.0 EPSF-3.0 %%BoundingBox: 0 0 136 43 %%LanguageLevel: 1 %Custom comment %%EndComments %%BeginProlog prologing %%EndProlog dummy postscript dummy postscript %Custom comment dummy postscript dummy postscript dummy postscript %%EOF xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/ps/dsc/tools/DSCToolsTestCase.java0100644 0000000 0000000 00000004251 13777276623 031434 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: DSCToolsTestCase.java 1365650 2012-07-25 15:59:30Z mehdi $ */ package org.apache.xmlgraphics.ps.dsc.tools; import org.junit.Test; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import org.apache.xmlgraphics.ps.dsc.events.DSCCommentEndComments; import org.apache.xmlgraphics.ps.dsc.events.DSCCommentPages; import org.apache.xmlgraphics.ps.dsc.events.DSCEvent; import org.apache.xmlgraphics.ps.dsc.events.PostScriptComment; import org.apache.xmlgraphics.ps.dsc.events.PostScriptLine; public class DSCToolsTestCase { @Test public void testEndComment() throws Exception { DSCEvent event; event = new DSCCommentEndComments(); assertTrue(DSCTools.headerCommentsEndHere(event)); event = new PostScriptComment("FOPTest"); assertFalse(DSCTools.headerCommentsEndHere(event)); event = new DSCCommentPages(7); assertFalse(DSCTools.headerCommentsEndHere(event)); event = new PostScriptComment(null); assertTrue(DSCTools.headerCommentsEndHere(event)); event = new PostScriptComment("\t"); assertTrue(DSCTools.headerCommentsEndHere(event)); event = new PostScriptComment(" ***"); assertTrue(DSCTools.headerCommentsEndHere(event)); event = new PostScriptLine("/pgsave save def"); assertTrue(DSCTools.headerCommentsEndHere(event)); } } xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/util/ClasspathResourceTestCase.java0100644 0000000 0000000 00000004151 13777276623 032055 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ClasspathResourceTestCase.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.util; import java.net.URL; import java.util.Iterator; import java.util.List; import org.junit.Test; import static org.junit.Assert.assertTrue; /** * Test for the Service class. */ public class ClasspathResourceTestCase { /** * Tests whether the file /sample.txt with mime-type text/plain exists. * * @throws Exception * in case of an error */ @Test public void testSampleResource() throws Exception { final List list = ClasspathResource.getInstance() .listResourcesOfMimeType("text/plain"); boolean found = false; final Iterator i = list.iterator(); while (i.hasNext()) { final URL u = (URL) i.next(); if (u.getPath().endsWith("sample.txt")) { found = true; } } assertTrue(found); } /** * Tests the mode where Service returns class names. * * @throws Exception * in case of an error */ @Test public void testNonexistingResource() throws Exception { final List list = ClasspathResource.getInstance() .listResourcesOfMimeType("nota/mime-type"); assertTrue(list.isEmpty()); } } xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/util/DateFormatUtilTestCase.java0100644 0000000 0000000 00000010041 13777276623 031302 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: DateFormatUtilTestCase.java 1365650 2012-07-25 15:59:30Z mehdi $ */ package org.apache.xmlgraphics.util; import java.util.Calendar; import java.util.Date; import java.util.Locale; import java.util.TimeZone; import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; import org.apache.xmlgraphics.xmp.XMPSchemaAdapter; /** * Tests date formatting for XMP. */ public class DateFormatUtilTestCase { /** * Checks date formatting for XMP. * @throws Exception if an error occurs */ @Test public void testDateFormattingISO8601() throws Exception { Date dt = createTestDate(); String s = XMPSchemaAdapter.formatISO8601Date(dt, TimeZone.getTimeZone("GMT")); assertEquals("2008-02-07T15:11:07Z", s); assertEquals(dt, DateFormatUtil.parseISO8601Date(s)); s = XMPSchemaAdapter.formatISO8601Date(dt, TimeZone.getTimeZone("GMT+02:00")); assertEquals("2008-02-07T17:11:07+02:00", s); assertEquals(dt, DateFormatUtil.parseISO8601Date(s)); s = XMPSchemaAdapter.formatISO8601Date(dt, TimeZone.getTimeZone("GMT+02:30")); assertEquals("2008-02-07T17:41:07+02:30", s); assertEquals(dt, DateFormatUtil.parseISO8601Date(s)); s = XMPSchemaAdapter.formatISO8601Date(dt, TimeZone.getTimeZone("GMT-08:00")); assertEquals("2008-02-07T07:11:07-08:00", s); assertEquals(dt, DateFormatUtil.parseISO8601Date(s)); s = XMPSchemaAdapter.formatISO8601Date(dt, TimeZone.getTimeZone("GMT-11:00")); assertEquals("2008-02-07T04:11:07-11:00", s); assertEquals(dt, DateFormatUtil.parseISO8601Date(s)); } private Date createTestDate() { Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"), Locale.ENGLISH); cal.set(2008, Calendar.FEBRUARY, 07, 15, 11, 07); cal.set(Calendar.MILLISECOND, 0); Date dt = cal.getTime(); return dt; } @Test public void testDateFormattingPDF() throws Exception { Date dt = createTestDate(); String s = DateFormatUtil.formatPDFDate(dt, TimeZone.getTimeZone("GMT")); assertEquals("D:20080207151107Z", s); s = DateFormatUtil.formatPDFDate(dt, TimeZone.getTimeZone("GMT+02:00")); assertEquals("D:20080207171107+02'00'", s); s = DateFormatUtil.formatPDFDate(dt, TimeZone.getTimeZone("GMT+02:30")); assertEquals("D:20080207174107+02'30'", s); s = DateFormatUtil.formatPDFDate(dt, TimeZone.getTimeZone("GMT-08:00")); assertEquals("D:20080207071107-08'00'", s); s = DateFormatUtil.formatPDFDate(dt, TimeZone.getTimeZone("GMT-11:00")); assertEquals("D:20080207041107-11'00'", s); } @Test public void testParseInvalidDateNoColonUTC() { testInvalidDate("2008-02-07T151107Z"); } @Test public void testParseInvalidDateNoColonLocal() { testInvalidDate("2008-02-07T151107+0000"); } @Test public void testParseInvalidDateColonLast() { testInvalidDate("2008-02-07T151107Z:"); } private void testInvalidDate(String date) { try { DateFormatUtil.parseISO8601Date(date); fail(); } catch (IllegalArgumentException e) { // Expected } } } xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/util/DoubleFormatUtilTestCase.java0100644 0000000 0000000 00000054521 13777276623 031652 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: DoubleFormatUtilTestCase.java 1780540 2017-01-27 11:10:50Z ssteiner $ */ package org.apache.xmlgraphics.util; import java.math.BigDecimal; import java.math.RoundingMode; import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; import java.util.Locale; import java.util.Random; import org.junit.Ignore; import org.junit.Test; import static org.junit.Assert.assertTrue; /** * Test class of DoubleFormatUtil */ public class DoubleFormatUtilTestCase { /** * Test simple values as specified in the format contract. *

    * Note: Some of these tests will fail if formatFast is used. */ @Test public void testSimple() { int decimals = 4; int precision = 8; double value = 0.0; String expected = "0"; String actual = format(value, decimals, precision); assertEquals(value, decimals, precision, expected, actual); value = 0.1; expected = "0.1"; actual = format(value, decimals, precision); assertEquals(value, decimals, precision, expected, actual); value = 1234.1; expected = "1234.1"; actual = format(value, decimals, precision); assertEquals(value, decimals, precision, expected, actual); // rounding value = 1234.1234567; expected = "1234.1235"; actual = format(value, decimals, precision); assertEquals(value, decimals, precision, expected, actual); value = 1234.99995; expected = "1235"; actual = format(value, decimals, precision); assertEquals(value, decimals, precision, expected, actual); value = -1234.99995; expected = "-1235"; actual = format(value, decimals, precision); assertEquals(value, decimals, precision, expected, actual); value = 1234.99994999; expected = "1234.9999"; actual = format(value, decimals, precision); assertEquals(value, decimals, precision, expected, actual); // decimals / precision switch value = 0.00000001; expected = "0.00000001"; actual = format(value, decimals, precision); assertEquals(value, decimals, precision, expected, actual); value = -0.00000001; expected = "-0.00000001"; actual = format(value, decimals, precision); assertEquals(value, decimals, precision, expected, actual); value = 72.00001234; expected = "72"; actual = format(value, decimals, precision); assertEquals(value, decimals, precision, expected, actual); // limit precision value = 0.000000001; expected = "0"; actual = format(value, decimals, precision); assertEquals(value, decimals, precision, expected, actual); value = 5.0e-9; expected = "0.00000001"; actual = format(value, decimals, precision); assertEquals(value, decimals, precision, expected, actual); value = 4.9999999999e-9; expected = "0"; actual = format(value, decimals, precision); assertEquals(value, decimals, precision, expected, actual); value = 2.0005e-5; expected = "0.00002001"; actual = format(value, decimals, precision); assertEquals(value, decimals, precision, expected, actual); value = 2.00049999999999e-5; expected = "0.00002"; actual = format(value, decimals, precision); assertEquals(value, decimals, precision, expected, actual); // Test added after bug #43940 was reopened value = 0.005859375; expected = "0.00585938"; actual = format(value, 8, 8); assertEquals(value, 8, 8, expected, actual); value = 5.22534294505995E-4; expected = "0.000522534294506"; actual = format(value, 17, 17); assertEquals(value, 17, 17, expected, actual); value = 4.9E-324; expected = "0"; actual = format(value, 309, 309); assertEquals(value, 309, 309, expected, actual); value = 7.003868765287485E-280; expected = refFormat(value, 294, 294); actual = format(value, 294, 294); assertEquals(value, 294, 294, expected, actual); value = 5E-304; expected = refFormat(value, 303, 303); actual = format(value, 303, 303); assertEquals(value, 303, 303, expected, actual); value = 9.999999999999999E-250; expected = refFormat(value, 265, 265); actual = format(value, 265, 265); assertEquals(value, 265, 265, expected, actual); } @Test public void testLimits() { int decimals = 19; int precision = 19; double value = Double.NaN; String expected = "NaN"; String actual = format(value, decimals, precision); assertEquals(value, decimals, precision, expected, actual); value = Double.POSITIVE_INFINITY; expected = "Infinity"; actual = format(value, decimals, precision); assertEquals(value, decimals, precision, expected, actual); value = Double.NEGATIVE_INFINITY; expected = "-Infinity"; actual = format(value, decimals, precision); assertEquals(value, decimals, precision, expected, actual); value = 1e-3 + Double.MIN_VALUE; expected = "0.001"; actual = format(value, decimals, precision); assertEquals(value, decimals, precision, expected, actual); value = 1e-3 - Double.MIN_VALUE; expected = "0.001"; actual = format(value, decimals, precision); assertEquals(value, decimals, precision, expected, actual); value = 1e-3; expected = "0.001"; actual = format(value, decimals, precision); assertEquals(value, decimals, precision, expected, actual); value = 0.0010000000000000002; // == Math.nextAfter(1e-3, Double.POSITIVE_INFINITY); expected = "0.0010000000000000002"; actual = format(value, decimals, precision); assertEquals(value, decimals, precision, expected, actual); expected = "0.001"; actual = format(value, 18, 18); assertEquals(value, 18, 18, expected, actual); value = 0.0009999999999999998; // == Math.nextAfter(1e-3, Double.NEGATIVE_INFINITY); expected = "0.0009999999999999998"; actual = format(value, decimals, precision); assertEquals(value, decimals, precision, expected, actual); expected = "0.001"; actual = format(value, 18, 18); assertEquals(value, 18, 18, expected, actual); value = 1e7 + Double.MIN_VALUE; expected = "10000000"; actual = format(value, decimals, precision); assertEquals(value, decimals, precision, expected, actual); value = 1e7 - Double.MIN_VALUE; expected = "10000000"; actual = format(value, decimals, precision); assertEquals(value, decimals, precision, expected, actual); value = 1e7; expected = "10000000"; actual = format(value, decimals, precision); assertEquals(value, decimals, precision, expected, actual); value = 1.0000000000000002E7; // == Math.nextAfter(1e7, Double.POSITIVE_INFINITY); expected = "10000000.000000002"; actual = format(value, decimals, precision); assertEquals(value, decimals, precision, expected, actual); expected = "10000000"; actual = format(value, 8, 8); assertEquals(value, 8, 8, expected, actual); value = 9999999.999999998; // == Math.nextAfter(1e7, Double.NEGATIVE_INFINITY); expected = "9999999.999999998"; actual = format(value, decimals, precision); assertEquals(value, decimals, precision, expected, actual); expected = "10000000"; actual = format(value, 8, 8); assertEquals(value, 8, 8, expected, actual); value = 0.000009999999999999997; // Check higher precision expected = "0.000009999999999999997"; actual = format(value, 21, 21); assertEquals(value, 21, 21, expected, actual); expected = "0.00001"; actual = format(value, 20, 20); assertEquals(value, 20, 20, expected, actual); } /** * AssertEquals with a more detailed message */ private static void assertEquals(double value, int decimals, int precision, String expected, String actual) { assertTrue("value: " + value + ", decimals: " + decimals + ", precision: " + precision, expected.equals(actual)); } /** * The buffer used to format */ private StringBuffer buf = new StringBuffer(); /** * Formats using FormatUtil#formatDouble method */ private String format(double value, int decimals, int precision) { buf.setLength(0); DoubleFormatUtil.formatDouble(value, decimals, precision, buf); return buf.toString(); } /** * Formats using FormatUtil#formatDoublePrecise method */ private String formatPrecise(double value, int decimals, int precision) { buf.setLength(0); DoubleFormatUtil.formatDoublePrecise(value, decimals, precision, buf); return buf.toString(); } /** * Formats using FormatUtil#formatDoubleFast method */ private String formatFast(double value, int decimals, int precision) { buf.setLength(0); DoubleFormatUtil.formatDoubleFast(value, decimals, precision, buf); return buf.toString(); } /** * Formats using a BigDecimal. This is the reference (always returns the correct format) * whereas DecimalFormat may have some formating errors regarding the last digit. */ private String refFormat(double value, int decimals, int precision) { if (Double.isNaN(value) || Double.isInfinite(value)) { return Double.toString(value); } buf.setLength(0); BigDecimal bg = new BigDecimal(Double.toString(value)); int scale = Math.abs(value) < 1.0 ? precision : decimals; bg = bg.setScale(scale, RoundingMode.HALF_UP); //buf.append(bg.toString()); // Java 1.4 buf.append(bg.toPlainString()); // Java 1.5 and more ! if (buf.indexOf(".") >= 0) { for (int i = buf.length() - 1; i > 1 && buf.charAt(i) == '0'; i--) { buf.setLength(i); } if (buf.charAt(buf.length() - 1) == '.') { buf.setLength(buf.length() - 1); } } return buf.toString(); } /** * The decimal format used within formatDf method */ private DecimalFormat df = new DecimalFormat("0", new DecimalFormatSymbols(Locale.US)); /** * Formats using DecimalFormat#format method */ private String formatDf(double value, int decimals, int precision) { int scale = Math.abs(value) < 1.0 ? precision : decimals; df.setMaximumFractionDigits(scale); return df.format(value); } /** * The maximum power of ten to use when testing high values double */ private static final int MAX_POW = 12; /** * Tests the formatPrecise method against the reference, with random values */ @Test public void testPrecise() { long seed = System.currentTimeMillis(); Random r = new Random(); r.setSeed(seed); double value; double highValue; double lowValue; int nbTest = 10000; int maxDecimals = 12; String actual; String expected; for (int i = nbTest; i > 0; i--) { int decimals = r.nextInt(maxDecimals); int precision = decimals + 3; value = 1 + r.nextDouble(); // Use decimals and not precision expected = refFormat(value, decimals, precision); actual = formatPrecise(value, decimals, precision); assertEquals(value, decimals, precision, expected, actual); highValue = value * DoubleFormatUtil.tenPow(r.nextInt(MAX_POW)); expected = refFormat(highValue, decimals, precision); actual = formatPrecise(highValue, decimals, precision); assertEquals(highValue, decimals, precision, expected, actual); lowValue = (value - 1) / 1000; expected = refFormat(lowValue, decimals, precision); actual = formatPrecise(lowValue, decimals, precision); assertEquals(lowValue, decimals, precision, expected, actual); } } /** * Tests the format method against the reference, with random values */ @Test public void testFormat() { long seed = System.currentTimeMillis(); Random r = new Random(); r.setSeed(seed); double value; double highValue; double lowValue; int nbTest = 10000; int maxDecimals = 12; String actual; String expected; for (int i = nbTest; i > 0; i--) { int decimals = r.nextInt(maxDecimals); int precision = decimals + 3; value = 1 + r.nextDouble(); // Use decimals and not precision expected = refFormat(value, decimals, precision); actual = format(value, decimals, precision); assertEquals(value, decimals, precision, expected, actual); highValue = value * DoubleFormatUtil.tenPow(r.nextInt(MAX_POW)); expected = refFormat(highValue, decimals, precision); actual = format(highValue, decimals, precision); assertEquals(highValue, decimals, precision, expected, actual); lowValue = (value - 1) / 1000; expected = refFormat(lowValue, decimals, precision); actual = format(lowValue, decimals, precision); assertEquals(lowValue, decimals, precision, expected, actual); } } /** * Tests the formatFast method against the reference, with random values. * Disabled since the formatFast method is not accurate. */ @Test @Ignore("Disabled since the formatFast method is not accurate.") public void fast() { long seed = System.currentTimeMillis(); Random r = new Random(); r.setSeed(seed); double value; double highValue; double lowValue; int nbTest = 10000; int maxDecimals = 12; String actual; String expected; for (int i = nbTest; i > 0; i--) { int decimals = r.nextInt(maxDecimals); int precision = decimals + 3; value = 1 + r.nextDouble(); // Use decimals and not precision expected = refFormat(value, decimals, precision); actual = formatFast(value, decimals, precision); assertEquals(value, decimals, precision, expected, actual); highValue = value * DoubleFormatUtil.tenPow(r.nextInt(MAX_POW)); expected = refFormat(highValue, decimals, precision); actual = formatFast(highValue, decimals, precision); System.out.println(expected); System.out.println(actual); assertEquals(highValue, decimals, precision, expected, actual); lowValue = (value - 1) / 1000; expected = refFormat(lowValue, decimals, precision); actual = formatFast(lowValue, decimals, precision); assertEquals(lowValue, decimals, precision, expected, actual); } } /** * Performance comparison of the differents formatXXX methods, * to see which one is the fastest in the same conditions. */ @Test @Ignore("Disabled since this doesn't test correctness.") public void performanceCompare() { // Rename this method in testPerformanceCompare to run it within JUnit tests // This method is quite long (depends of the value of nbTest). long seed = System.currentTimeMillis(); Random r = new Random(); r.setSeed(seed); double value; double highValue; double lowValue; long start = System.currentTimeMillis(); int nbTest = 1000000; int maxDecimals = 16; r.setSeed(seed); start = System.currentTimeMillis(); for (int i = nbTest; i > 0; i--) { int decimals = r.nextInt(maxDecimals); int precision = decimals + 3; value = 1 + r.nextDouble(); // Use decimals and not precision format(value, decimals, precision); highValue = value * DoubleFormatUtil.tenPow(r.nextInt(MAX_POW)); format(highValue, decimals, precision); lowValue = (value - 1) / 1000; format(lowValue, decimals, precision); } long formatDuration = System.currentTimeMillis() - start; System.out.println("Format duration: " + formatDuration + "ms to format " + (3 * nbTest) + " doubles"); r.setSeed(seed); start = System.currentTimeMillis(); for (int i = nbTest; i > 0; i--) { int decimals = r.nextInt(maxDecimals); int precision = decimals + 3; value = 1 + r.nextDouble(); // Use decimals and not precision formatPrecise(value, decimals, precision); highValue = value * DoubleFormatUtil.tenPow(r.nextInt(MAX_POW)); formatPrecise(highValue, decimals, precision); lowValue = (value - 1) / 1000; formatPrecise(lowValue, decimals, precision); } long preciseFormatDuration = System.currentTimeMillis() - start; System.out.println("Format Precise duration: " + preciseFormatDuration + "ms to format " + (3 * nbTest) + " doubles"); r.setSeed(seed); start = System.currentTimeMillis(); for (int i = nbTest; i > 0; i--) { int decimals = r.nextInt(maxDecimals); int precision = decimals + 3; value = 1 + r.nextDouble(); // Use decimals and not precision formatFast(value, decimals, precision); highValue = value * DoubleFormatUtil.tenPow(r.nextInt(MAX_POW)); formatFast(highValue, decimals, precision); lowValue = (value - 1) / 1000; formatFast(lowValue, decimals, precision); } long fastFormatDuration = System.currentTimeMillis() - start; System.out.println("Fast Format duration: " + fastFormatDuration + "ms to format " + (3 * nbTest) + " doubles"); r.setSeed(seed); start = System.currentTimeMillis(); for (int i = nbTest; i > 0; i--) { int decimals = r.nextInt(maxDecimals); int precision = decimals + 3; value = 1 + r.nextDouble(); // Use decimals and not precision refFormat(value, decimals, precision); highValue = value * DoubleFormatUtil.tenPow(r.nextInt(MAX_POW)); refFormat(highValue, decimals, precision); lowValue = (value - 1) / 1000; refFormat(lowValue, decimals, precision); } long bgDuration = System.currentTimeMillis() - start; System.out.println("BigDecimal format duration: " + bgDuration + "ms to format " + (3 * nbTest) + " doubles"); r.setSeed(seed); start = System.currentTimeMillis(); for (int i = nbTest; i > 0; i--) { int decimals = r.nextInt(maxDecimals); int precision = decimals + 3; value = 1 + r.nextDouble(); // Use decimals and not precision formatDf(value, decimals, precision); highValue = value * DoubleFormatUtil.tenPow(r.nextInt(MAX_POW)); formatDf(highValue, decimals, precision); lowValue = (value - 1) / 1000; formatDf(lowValue, decimals, precision); } long dfDuration = System.currentTimeMillis() - start; System.out.println("DecimalFormat duration: " + dfDuration + "ms to format " + (3 * nbTest) + " doubles"); r.setSeed(seed); start = System.currentTimeMillis(); for (int i = nbTest; i > 0; i--) { int decimals = r.nextInt(maxDecimals); int precision = decimals + 3; precision++; // Avoid warning unused local variable value = 1 + r.nextDouble(); // Use decimals and not precision Double.toString(value); highValue = value * DoubleFormatUtil.tenPow(r.nextInt(MAX_POW)); Double.toString(highValue); lowValue = (value - 1) / 1000; Double.toString(lowValue); } long toStringDuration = System.currentTimeMillis() - start; System.out.println("toString duration: " + toStringDuration + "ms to format " + (3 * nbTest) + " doubles"); } @Test public void testAllDoubleRanges() { double[] values = {0, 1, 5, 4.9999, 5.0001, 9.9999, 1234567890, 0 /* The last one is random */}; Random r = new Random(); double value; String expected; String actual; int minScale; int maxScale; for (int i = -330; i <= 315; i++) { values[values.length - 1] = r.nextDouble(); double pow = Math.pow(10.0, i); for (double d : values) { value = d * pow; minScale = 1; maxScale = 350; // Reduce scales (unnecessary tests) if (i < -30) { minScale = -i - 30; maxScale = -i + 30; } else if (i <= 0) { minScale = 1; maxScale = -i + 30; } else { minScale = 1; maxScale = 30; } for (int scale = minScale; scale <= maxScale; scale++) { expected = refFormat(value, scale, scale); actual = format(value, scale, scale); assertEquals(value, scale, scale, expected, actual); } } } } } xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/util/HexUtil.java0100644 0000000 0000000 00000003151 13777276623 026350 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: HexUtil.java 1365650 2012-07-25 15:59:30Z mehdi $ */ package org.apache.xmlgraphics.util; /** * Provides helper functions for converting hexadecimal strings. */ public final class HexUtil { private HexUtil() { } private static final char[] DIGITS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; /** * Converts a byte array to a hexadecimal String * @param data the data to encode * @return String the resulting String */ public static String toHex(byte[] data) { final StringBuffer sb = new StringBuffer(data.length * 2); for (int i = 0; i < data.length; i++) { sb.append(DIGITS[(data[i] >>> 4) & 0x0F]); sb.append(DIGITS[data[i] & 0x0F]); } return sb.toString(); } } xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/util/ServiceTestCase.java0100644 0000000 0000000 00000010016 13777276623 030020 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ServiceTestCase.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.util; import java.util.Iterator; import org.junit.Test; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import org.apache.xmlgraphics.image.writer.ImageWriter; /** * Test for the Service class. */ public class ServiceTestCase { /** * Tests the mode where Service returns instances. * @throws Exception in case of an error */ @Test public void testWithInstances() throws Exception { Class cls = ImageWriter.class; boolean found = false; Object writer1 = null; Object writer2 = null; //First run: Find a writer implementation (one of the two must be available) Iterator iter = Service.providers(cls); while (iter.hasNext()) { Object obj = iter.next(); assertNotNull(obj); String className = obj.getClass().getName(); if ("org.apache.xmlgraphics.image.writer.internal.PNGImageWriter".equals(className)) { writer1 = obj; found = true; break; } else if ("org.apache.xmlgraphics.image.writer.imageio.ImageIOPNGImageWriter".equals( className)) { writer2 = obj; found = true; break; } } assertTrue("None of the expected classes found", found); //Second run: verify that the same instances are returned iter = Service.providers(cls); while (iter.hasNext()) { Object obj = iter.next(); assertNotNull(obj); String className = obj.getClass().getName(); if ("org.apache.xmlgraphics.image.writer.internal.PNGImageWriter".equals(className)) { assertTrue(obj == writer1); break; } else if ("org.apache.xmlgraphics.image.writer.imageio.ImageIOPNGImageWriter".equals( className)) { assertTrue(obj == writer2); break; } } } /** * Tests the mode where Service returns class names. * @throws Exception in case of an error */ @Test public void testWithClassNames() throws Exception { Class cls = ImageWriter.class; boolean found = true; Iterator iter = Service.providerNames(cls); while (iter.hasNext()) { Object obj = iter.next(); assertNotNull(obj); assertTrue("Returned object must be a class name", obj instanceof String); if ("org.apache.xmlgraphics.image.writer.internal.PNGImageWriter".equals(obj) || ("org.apache.xmlgraphics.image.writer.imageio.ImageIOPNGImageWriter".equals( obj))) { found = true; } } assertTrue("None of the expected classes found", found); //Do it a second time to make sure the cache works as expected iter = Service.providerNames(cls); while (iter.hasNext()) { Object obj = iter.next(); assertNotNull(obj); assertTrue("Returned object must be a class name", obj instanceof String); } } } xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/util/UnitConvTestCase.java0100644 0000000 0000000 00000003656 13777276623 030201 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: UnitConvTestCase.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.util; import org.junit.Test; import static org.junit.Assert.assertEquals; /** * Test class for UnitConv. */ public class UnitConvTestCase { /** * Test all kinds of unit conversions. * @throws Exception if the test fails */ @Test public void testConversions() throws Exception { assertEquals("in2mm", 25.4, UnitConv.in2mm(1), 0.00001); assertEquals("mm2in", 1.0, UnitConv.mm2in(25.4), 0.00001); assertEquals("mm2pt", 841.890, UnitConv.mm2pt(297), 0.001 / 2); //height of an A4 page assertEquals("mm2mpt", 841890, UnitConv.mm2mpt(297), 1.0 / 2); assertEquals("pt2mm", 297, UnitConv.pt2mm(841.890), 0.0001); assertEquals("in2mpt", 792000, UnitConv.in2mpt(11.0), 1.0 / 2); //height of a letter page assertEquals("mpt2in", 11.0, UnitConv.mpt2in(792000), 0.01 / 2); //height of a letter page assertEquals("mm2px/72dpi", 841.8897764234434, UnitConv.mm2px(297.0, 72), 0); assertEquals("mm2px/300dpi", 3507.8740684310146, UnitConv.mm2px(297.0, 300), 0); } } ././@LongLink0100644 0000000 0000000 00000000145 13777276623 011657 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/util/io/ASCII85InputStreamTestCase.javaxmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/util/io/ASCII85InputStreamTestCase.java0100644 0000000 0000000 00000013012 13777276623 032227 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ASCII85InputStreamTestCase.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.util.io; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; import org.apache.commons.io.IOUtils; import org.apache.commons.io.output.ByteArrayOutputStream; import org.apache.xmlgraphics.util.HexUtil; /** * Test case for ASCII85InputStream. *

    * ATTENTION: Some of the tests here depend on the correct behaviour of * ASCII85OutputStream. If something fails here make sure * ASCII85OutputStreamTestCase runs! */ public class ASCII85InputStreamTestCase { private static final boolean DEBUG = false; private byte[] decode(String text) throws Exception { byte[] ascii85 = text.getBytes("US-ASCII"); InputStream in = new ByteArrayInputStream(ascii85); InputStream decoder = new ASCII85InputStream(in); return IOUtils.toByteArray(decoder); } private byte[] getChunk(int count) { byte[] buf = new byte[count]; System.arraycopy(ASCII85OutputStreamTestCase.DATA, 0, buf, 0, buf.length); return buf; } private String encode(byte[] data, int len) throws Exception { ByteArrayOutputStream baout = new ByteArrayOutputStream(); java.io.OutputStream out = new ASCII85OutputStream(baout); out.write(data, 0, len); out.close(); return new String(baout.toByteArray(), "US-ASCII"); } private void innerTestDecode(byte[] data) throws Exception { String encoded = encode(data, data.length); if (DEBUG) { if (data[0] == 0) { System.out.println("self-encode: " + data.length + " chunk 000102030405..."); } else { System.out.println("self-encode: " + new String(data, "US-ASCII") + " " + HexUtil.toHex(data)); } System.out.println(" ---> " + encoded); } byte[] decoded = decode(encoded); if (DEBUG) { if (data[0] == 0) { System.out.println("decoded: " + data.length + " chunk 000102030405..."); } else { System.out.println("decoded: " + new String(decoded, "US-ASCII") + " " + HexUtil.toHex(decoded)); } } assertEquals(HexUtil.toHex(data), HexUtil.toHex(decoded)); } /** * Tests the output of ASCII85. * @throws Exception if an error occurs */ @Test public void testDecode() throws Exception { innerTestDecode("1. Bodypart".getBytes("US-ASCII")); if (DEBUG) { System.out.println("==========================================="); } innerTestDecode(getChunk(1)); innerTestDecode(getChunk(2)); innerTestDecode(getChunk(3)); innerTestDecode(getChunk(4)); innerTestDecode(getChunk(5)); if (DEBUG) { System.out.println("==========================================="); } innerTestDecode(getChunk(10)); innerTestDecode(getChunk(62)); innerTestDecode(getChunk(63)); innerTestDecode(getChunk(64)); innerTestDecode(getChunk(65)); if (DEBUG) { System.out.println("==========================================="); } String sz; sz = HexUtil.toHex(decode("zz~>")); assertEquals(HexUtil.toHex(new byte[] {0, 0, 0, 0, 0, 0, 0, 0}), sz); sz = HexUtil.toHex(decode("z\t \0z\n~>")); assertEquals(HexUtil.toHex(new byte[] {0, 0, 0, 0, 0, 0, 0, 0}), sz); if (DEBUG) { System.out.println("==========================================="); } try { decode("vz~>"); fail("Illegal character should be detected"); } catch (IOException ioe) { //expected } /* DISABLED because of try/catch in InputStream.read(byte[], int, int). * Only the exception happening on the first byte in a block is being * reported. BUG in JDK??? * try { decode("zv~>"); fail("Illegal character should be detected"); } catch (IOException ioe) { //expected }*/ } private byte[] getFullASCIIRange() { java.io.ByteArrayOutputStream baout = new java.io.ByteArrayOutputStream(256); for (int i = 254; i < 256; i++) { baout.write(i); } return baout.toByteArray(); } /** * Tests the full 8-bit ASCII range. * @throws Exception if an error occurs */ @Test public void testFullASCIIRange() throws Exception { innerTestDecode(getFullASCIIRange()); } } ././@LongLink0100644 0000000 0000000 00000000146 13777276623 011660 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/util/io/ASCII85OutputStreamTestCase.javaxmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/util/io/ASCII85OutputStreamTestCase.jav0100644 0000000 0000000 00000006160 13777276623 032275 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: ASCII85OutputStreamTestCase.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.util.io; import java.io.OutputStream; import org.junit.Test; import static org.junit.Assert.assertEquals; import org.apache.commons.io.output.ByteArrayOutputStream; /** * Test case for ASCII85OutputStream */ public class ASCII85OutputStreamTestCase { /** Test data */ public static final byte[] DATA = new byte[100]; static { //Fill in some data for (int i = 0; i < 100; i++) { DATA[i] = (byte) i; } } private String encode(int count) throws Exception { return encode(DATA, count); } private String encode(byte[] data, int len) throws Exception { ByteArrayOutputStream baout = new ByteArrayOutputStream(); OutputStream out = new ASCII85OutputStream(baout); out.write(data, 0, len); out.close(); return new String(baout.toByteArray(), "US-ASCII"); } /** * Tests the output of ASCII85. * @throws Exception if an error occurs */ @Test public void testOutput() throws Exception { String sz = encode(new byte[] {0, 0, 0, 0, 0, 0, 0, 0}, 8); assertEquals("zz~>", sz); String s3 = encode(3); //System.out.println(">>>" + s3 + "<<<"); assertEquals("!!*-~>", s3); String s10 = encode(10); //System.out.println(">>>" + s10 + "<<<"); assertEquals("!!*-'\"9eu7#RL~>", s10); String s62 = encode(62); //System.out.println(">>>" + s62 + "<<<"); assertEquals("!!*-'\"9eu7#RLhG$k3[W&.oNg'GVB\"(`=52*$$(B+<_pR," + "UFcb-n-Vr/1iJ-0JP==1c70M3&s#]4?W~>", s62); String s63 = encode(63); //System.out.println(">>>" + s63 + "<<<"); assertEquals("!!*-'\"9eu7#RLhG$k3[W&.oNg'GVB\"(`=52*$$(B+<_pR," + "UFcb-n-Vr/1iJ-0JP==1c70M3&s#]4?Yk\n~>", s63); String s64 = encode(64); //System.out.println(">>>" + s64 + "<<<"); assertEquals("!!*-'\"9eu7#RLhG$k3[W&.oNg'GVB\"(`=52*$$(B+<_pR," + "UFcb-n-Vr/1iJ-0JP==1c70M3&s#]4?Ykm\n~>", s64); String s65 = encode(65); //System.out.println(">>>" + s65 + "<<<"); assertEquals("!!*-'\"9eu7#RLhG$k3[W&.oNg'GVB\"(`=52*$$(B+<_pR," + "UFcb-n-Vr/1iJ-0JP==1c70M3&s#]4?Ykm\n5Q~>", s65); } } xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/util/io/Base64TestCase.java0100644 0000000 0000000 00000020725 13777276623 030063 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: Base64TestCase.java 1876186 2020-04-06 13:37:10Z ssteiner $ */ package org.apache.xmlgraphics.util.io; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PipedInputStream; import java.io.PipedOutputStream; import java.net.URL; import org.junit.Test; import static org.junit.Assert.fail; import org.apache.commons.io.IOUtils; /** * This test validates that the Base64 encoder/decoders work properly. * * @version $Id: Base64TestCase.java 1876186 2020-04-06 13:37:10Z ssteiner $ */ public class Base64TestCase { private void innerBase64Test(String action, URL in, URL ref) throws Exception { InputStream inIS = dos2Unix(in); if (action.equals("ROUND")) { ref = in; } else if (!action.equals("ENCODE") && !action.equals("DECODE")) { fail("Bad action string"); } InputStream refIS = dos2Unix(ref); if (action.equals("ENCODE") || action.equals("ROUND")) { // We need to encode the incomming data PipedOutputStream pos = new PipedOutputStream(); OutputStream os = new Base64EncodeStream(pos); // Copy the input to the Base64 Encoder (in a seperate thread). Thread t = new StreamCopier(inIS, os); // Read that from the piped output stream. inIS = new PipedInputStream(pos); t.start(); } if (action.equals("DECODE") || action.equals("ROUND")) { inIS = new Base64DecodeStream(inIS); } int mismatch = compareStreams(inIS, refIS, action.equals("ENCODE")); if (mismatch != -1) { fail("Wrong result"); } } private InputStream dos2Unix(URL url) throws IOException { InputStream is = url.openStream(); byte[] data = IOUtils.toByteArray(is); if (data.length > 1 && data[data.length - 1] == '\n') { ByteArrayOutputStream bos = new ByteArrayOutputStream(); for (byte b : data) { if (b != '\r') { bos.write(b); } } return new ByteArrayInputStream(bos.toByteArray()); } return new ByteArrayInputStream(data); } private void innerBase64Test(String action, String in, String ref) throws Exception { final String baseURL = "file:src/test/resources/org/apache/xmlgraphics/util/io/"; innerBase64Test(action, new URL(baseURL + in), new URL(baseURL + ref)); } private void innerBase64Test(String in) throws Exception { innerBase64Test("ROUND", in, in); } private void testBase64Group(String name) throws Exception { innerBase64Test("ENCODE", name, name + ".64"); innerBase64Test("DECODE", name + ".64", name); innerBase64Test(name); } /** * This method will only throw exceptions if some aspect * of the test's internal operation fails. */ @Test public void testBase64() throws Exception { System.out.println(new File(".").getCanonicalPath()); testBase64Group("zeroByte"); testBase64Group("oneByte"); testBase64Group("twoByte"); testBase64Group("threeByte"); testBase64Group("fourByte"); testBase64Group("tenByte"); testBase64Group("small"); testBase64Group("medium"); innerBase64Test("DECODE", "medium.pc.64", "medium"); innerBase64Test("large"); } /** * Returns true if the contents of is1 match the * contents of is2 */ public static int compareStreams(InputStream is1, InputStream is2, boolean skipws) { byte[] data1 = new byte[100]; byte[] data2 = new byte[100]; int off1 = 0; int off2 = 0; int idx = 0; try { while (true) { int len1 = is1.read(data1, off1, data1.length - off1); int len2 = is2.read(data2, off2, data2.length - off2); if (off1 != 0) { if (len1 == -1) { len1 = off1; } else { len1 += off1; } } if (off2 != 0) { if (len2 == -1) { len2 = off2; } else { len2 += off2; } } if (len1 == -1) { if (len2 == -1) { break; // Both done... } // Only is1 is done... if (!skipws) { return idx; } // check if the rest of is2 is whitespace... for (int i2 = 0; i2 < len2; i2++) { if ((data2[i2] != '\n') && (data2[i2] != '\r') && (data2[i2] != ' ')) { return idx + i2; } } off1 = off2 = 0; continue; } if (len2 == -1) { // Only is2 is done... if (!skipws) { return idx; } // Check if rest of is1 is whitespace... for (int i1 = 0; i1 < len1; i1++) { if ((data1[i1] != '\n') && (data1[i1] != '\r') && (data1[i1] != ' ')) { return idx + i1; } } off1 = off2 = 0; continue; } int i1 = 0; int i2 = 0; while ((i1 < len1) && (i2 < len2)) { if (skipws) { if ((data1[i1] == '\n') || (data1[i1] == '\r') || (data1[i1] == ' ')) { i1++; continue; } if ((data2[i2] == '\n') || (data2[i2] == '\r') || (data2[i2] == ' ')) { i2++; continue; } } if (data1[i1] != data2[i2]) { return idx + i2; } i1++; i2++; } if (i1 != len1) { System.arraycopy(data1, i1, data1, 0, len1 - i1); } if (i2 != len2) { System.arraycopy(data2, i2, data2, 0, len2 - i2); } off1 = len1 - i1; off2 = len2 - i2; idx += i2; } } catch (IOException ioe) { ioe.printStackTrace(); return idx; } return -1; } static class StreamCopier extends Thread { InputStream src; OutputStream dst; public StreamCopier(InputStream src, OutputStream dst) { this.src = src; this.dst = dst; } public void run() { try { byte[] data = new byte[1000]; while (true) { int len = src.read(data, 0, data.length); if (len == -1) { break; } dst.write(data, 0, len); } } catch (IOException ioe) { // Nothing } try { dst.close(); } catch (IOException ioe) { // Nothing } } } } xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/util/io/SubInputStreamTestCase.java0100644 0000000 0000000 00000004401 13777276623 031755 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: SubInputStreamTestCase.java 1365650 2012-07-25 15:59:30Z mehdi $ */ package org.apache.xmlgraphics.util.io; import java.io.ByteArrayInputStream; import java.util.Arrays; import org.junit.Test; import static org.junit.Assert.assertEquals; /** * Test case for SubInputStream. */ public class SubInputStreamTestCase { /** * Tests SubInputStream. * @throws Exception if an error occurs */ @Test public void testMain() throws Exception { //Initialize test data byte[] data = new byte[256]; for (int i = 0; i < data.length; i++) { data[i] = (byte) (i & 0xff); } int v; int c; byte[] buf; String s; SubInputStream subin = new SubInputStream(new ByteArrayInputStream(data), 10); v = subin.read(); assertEquals(0, v); v = subin.read(); assertEquals(1, v); buf = new byte[4]; c = subin.read(buf); assertEquals(4, c); s = new String(buf, "US-ASCII"); assertEquals("\u0002\u0003\u0004\u0005", s); Arrays.fill(buf, (byte) 0); c = subin.read(buf, 2, 2); assertEquals(2, c); s = new String(buf, "US-ASCII"); assertEquals("\u0000\u0000\u0006\u0007", s); Arrays.fill(buf, (byte) 0); c = subin.read(buf); assertEquals(2, c); s = new String(buf, "US-ASCII"); assertEquals("\u0008\u0009\u0000\u0000", s); subin.close(); } } ././@LongLink0100644 0000000 0000000 00000000145 13777276623 011657 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/util/uri/CommonURIResolverTestCase.javaxmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/util/uri/CommonURIResolverTestCase.java0100644 0000000 0000000 00000002645 13777276623 032562 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: CommonURIResolverTestCase.java 1732018 2016-02-24 04:51:06Z gadams $ */ package org.apache.xmlgraphics.util.uri; import javax.xml.transform.URIResolver; import org.junit.Test; /** * Test case for the {@link CommonURIResolver}. */ public class CommonURIResolverTestCase { /** * Test the DataURIResolver with correct values. * * @throws Exception * if an error occurs */ @Test public void testDataURLHandling() throws Exception { URIResolver resolver = CommonURIResolver.getDefaultURIResolver(); DataURIResolverTestCase.actualURLHAndlingTest(resolver); } } xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/util/uri/DataURIResolverTestCase.java0100644 0000000 0000000 00000012763 13777276623 032205 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: DataURIResolverTestCase.java 1365650 2012-07-25 15:59:30Z mehdi $ */ package org.apache.xmlgraphics.util.uri; import java.io.ByteArrayInputStream; import javax.xml.transform.Source; import javax.xml.transform.URIResolver; import javax.xml.transform.stream.StreamSource; import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import org.apache.commons.io.IOUtils; /** * Test case for the RFC 2397 data URL/URI resolver. */ public class DataURIResolverTestCase { private static final byte[] TESTDATA = new byte[] {0, 1, 2, 3, 4, 5}; /** * Tests DataURLUtil. * * @throws Exception * if an error occurs */ @Test public void testRFC2397Generator() throws Exception { String url = DataURLUtil.createDataURL(new ByteArrayInputStream( TESTDATA), null); assertEquals("Generated data URL is wrong", "data:;base64,AAECAwQF", url); url = DataURLUtil.createDataURL(new ByteArrayInputStream(TESTDATA), "application/pdf"); assertEquals("Generated data URL is wrong", "data:application/pdf;base64,AAECAwQF", url); } /** * Test the URIResolver contract if the protocol doesn't match. Resolver * must return null in this case. * * @throws Exception * if an error occurs */ @Test public void testNonMatchingContract() throws Exception { URIResolver resolver = new DataURIResolver(); Source src; src = resolver.resolve("http://xmlgraphics.apache.org/fop/index.html", null); assertNull(src); src = resolver.resolve("index.html", "http://xmlgraphics.apache.org/fop/"); assertNull(src); } private static boolean byteCmp(byte[] src, int srcOffset, byte[] cmp) { for (int i = 0, c = cmp.length; i < c; i++) { if (src[srcOffset + i] != cmp[i]) { return false; } } return true; } /** * Test the DataURIResolver with correct values. * * @throws Exception * if an error occurs */ @Test public void testDataURLHandling() throws Exception { URIResolver resolver = new DataURIResolver(); actualURLHAndlingTest(resolver); } static final void actualURLHAndlingTest(URIResolver resolver) throws Exception { Source src; src = resolver.resolve("data:;base64,AAECAwQF", null); assertNotNull(src); StreamSource streamSource = (StreamSource) src; byte[] data = IOUtils.toByteArray(streamSource.getInputStream()); assertTrue("Decoded data doesn't match the test data", byteCmp( TESTDATA, 0, data)); src = resolver .resolve( "data:application/octet-stream;interpreter=fop;base64,AAECAwQF", null); assertNotNull(src); streamSource = (StreamSource) src; assertNotNull(streamSource.getInputStream()); assertNull(streamSource.getReader()); data = IOUtils.toByteArray(streamSource.getInputStream()); assertTrue("Decoded data doesn't match the test data", byteCmp( TESTDATA, 0, data)); src = resolver.resolve("data:,FOP", null); assertNotNull(src); streamSource = (StreamSource) src; assertNull(streamSource.getInputStream()); assertNotNull(streamSource.getReader()); String text = IOUtils.toString(streamSource.getReader()); assertEquals("FOP", text); src = resolver.resolve("data:,A%20brief%20note", null); assertNotNull(src); streamSource = (StreamSource) src; text = IOUtils.toString(streamSource.getReader()); assertEquals("A brief note", text); src = resolver.resolve("data:text/plain;charset=iso-8859-7,%be%f9%be", null); assertNotNull(src); streamSource = (StreamSource) src; text = IOUtils.toString(streamSource.getReader()); assertEquals("\u038e\u03c9\u038e", text); } /** * Test that the system Id is not null for the resulting stream objects * @throws Exception If an error occurs. */ @Test public void testSystemIdForNull() throws Exception { URIResolver resolver = new DataURIResolver(); Source source = resolver.resolve("data:;base64,AAECAwQF", null); assertNotNull(source.getSystemId()); source = resolver.resolve("data:text/plain;charset=iso-8859-7,%be%f9%be", null); assertNotNull(source.getSystemId()); } } xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/xmp/XMPParserTestCase.java0100644 0000000 0000000 00000021042 13777276623 030071 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: XMPParserTestCase.java 1878394 2020-06-02 13:18:41Z ssteiner $ */ package org.apache.xmlgraphics.xmp; import java.io.StringReader; import java.net.URL; import java.util.Calendar; import java.util.Date; import java.util.TimeZone; import javax.xml.transform.TransformerException; import javax.xml.transform.stream.StreamSource; import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import org.apache.xmlgraphics.xmp.schemas.DublinCoreAdapter; import org.apache.xmlgraphics.xmp.schemas.DublinCoreSchema; import org.apache.xmlgraphics.xmp.schemas.XMPBasicAdapter; import org.apache.xmlgraphics.xmp.schemas.XMPBasicSchema; import org.apache.xmlgraphics.xmp.schemas.pdf.AdobePDFAdapter; import org.apache.xmlgraphics.xmp.schemas.pdf.AdobePDFSchema; /** * Tests for the XMP parser. */ public class XMPParserTestCase { @Test public void testParseBasics() throws Exception { URL url = getClass().getResource("test-basics.xmp"); Metadata meta = XMPParser.parseXMP(url); DublinCoreAdapter dcAdapter = DublinCoreSchema.getAdapter(meta); XMPBasicAdapter basicAdapter = XMPBasicSchema.getAdapter(meta); AdobePDFAdapter pdfAdapter = AdobePDFSchema.getAdapter(meta); XMPProperty prop; prop = meta.getProperty(XMPConstants.DUBLIN_CORE_NAMESPACE, "creator"); XMPArray array; array = prop.getArrayValue(); assertEquals(1, array.getSize()); assertEquals("John Doe", array.getValue(0).toString()); assertEquals("John Doe", dcAdapter.getCreators()[0]); prop = meta.getProperty(XMPConstants.DUBLIN_CORE_NAMESPACE, "title"); assertEquals("Example document", prop.getValue().toString()); assertEquals("Example document", dcAdapter.getTitle()); prop = meta.getProperty(XMPConstants.XMP_BASIC_NAMESPACE, "CreateDate"); //System.out.println("Creation Date: " + prop.getValue() + " " + prop.getClass().getName()); prop = meta.getProperty(XMPConstants.XMP_BASIC_NAMESPACE, "CreatorTool"); assertEquals("An XML editor", prop.getValue().toString()); assertEquals("An XML editor", basicAdapter.getCreatorTool()); prop = meta.getProperty(XMPConstants.ADOBE_PDF_NAMESPACE, "Producer"); assertEquals("Apache FOP Version SVN trunk", prop.getValue().toString()); assertEquals("Apache FOP Version SVN trunk", pdfAdapter.getProducer()); prop = meta.getProperty(XMPConstants.ADOBE_PDF_NAMESPACE, "PDFVersion"); assertEquals("1.4", prop.getValue().toString()); assertEquals("1.4", pdfAdapter.getPDFVersion()); } @Test public void testParse1() throws Exception { URL url = getClass().getResource("unknown-schema.xmp"); Metadata meta = XMPParser.parseXMP(url); DublinCoreAdapter dcAdapter = DublinCoreSchema.getAdapter(meta); XMPProperty prop; //Access through the known schema as reference prop = meta.getProperty(XMPConstants.DUBLIN_CORE_NAMESPACE, "title"); assertEquals("Unknown Schema", prop.getValue().toString()); assertEquals("Unknown Schema", dcAdapter.getTitle()); //Access through a schema unknown to the XMP framework prop = meta.getProperty("http://unknown.org/something", "dummy"); assertEquals("Dummy!", prop.getValue().toString()); } @Test public void testParseStructures() throws Exception { URL url = getClass().getResource("test-structures.xmp"); Metadata meta = XMPParser.parseXMP(url); XMPProperty prop; String testns = "http://foo.bar/test/"; prop = meta.getProperty(testns, "something"); assertEquals("blablah", prop.getValue().toString()); prop = meta.getProperty(testns, "ingredients"); XMPArray array = prop.getArrayValue(); assertEquals(3, array.getSize()); XMPStructure struct = array.getStructure(0); assertEquals(2, struct.getPropertyCount()); prop = struct.getValueProperty(); assertEquals("Apples", prop.getValue()); prop = struct.getProperty(testns, "amount"); assertEquals("4", prop.getValue()); prop = meta.getProperty(testns, "villain"); XMPProperty prop1; prop1 = prop.getStructureValue().getProperty(testns, "name"); assertEquals("Darth Sidious", prop1.getValue()); prop1 = prop.getStructureValue().getProperty(testns, "other-name"); assertEquals("Palpatine", prop1.getValue()); //Test shorthand form prop = meta.getProperty(testns, "project"); prop1 = prop.getStructureValue().getProperty(testns, "name"); assertEquals("Apache XML Graphics", prop1.getValue()); prop1 = prop.getStructureValue().getProperty(testns, "url"); assertEquals("http://xmlgraphics.apache.org/", prop1.getValue()); } @Test public void testAttributeValues() throws Exception { URL url = getClass().getResource("test-attribute-values.xmp"); Metadata meta = XMPParser.parseXMP(url); DublinCoreAdapter dcAdapter = DublinCoreSchema.getAdapter(meta); assertEquals("Ender's Game", dcAdapter.getTitle()); assertEquals("Orson Scott Card", dcAdapter.getCreators()[0]); } @Test public void testParseDates() throws Exception { URL url = getClass().getResource("test-dates.xmp"); Metadata meta = XMPParser.parseXMP(url); XMPProperty prop; DublinCoreAdapter dcAdapter = DublinCoreSchema.getAdapter(meta); //Simple adapter access Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT+2:00")); cal.set(2006, Calendar.JUNE, 2, 10, 36, 40); cal.set(Calendar.MILLISECOND, 0); assertEquals(cal.getTime(), dcAdapter.getDate()); Date[] dates = dcAdapter.getDates(); assertEquals(2, dates.length); //The second is the most recent and should match the simple value assertEquals(dates[1], dcAdapter.getDate()); prop = meta.getProperty(XMPConstants.DUBLIN_CORE_NAMESPACE, "date"); assertNotNull(prop.getArrayValue()); assertEquals(2, prop.getArrayValue().getSize()); //Now add a new date and check if the adapter's getDate() method returns the new date. cal.set(2008, Calendar.NOVEMBER, 1, 10, 10, 0); dcAdapter.addDate(cal.getTime()); assertEquals(3, dcAdapter.getDates().length); prop = meta.getProperty(XMPConstants.DUBLIN_CORE_NAMESPACE, "date"); assertNotNull(prop.getArrayValue()); assertEquals(3, prop.getArrayValue().getSize()); assertEquals(cal.getTime(), dcAdapter.getDate()); } @Test public void testParseEmptyValues() throws Exception { URL url = getClass().getResource("empty-values.xmp"); Metadata meta = XMPParser.parseXMP(url); DublinCoreAdapter dc = DublinCoreSchema.getAdapter(meta); String title = dc.getTitle(); assertEquals("empty", title); title = dc.getTitle("fr"); //Does not exist assertNull(title); title = dc.getTitle("de"); assertNull(title); //Empty value treated same as not existant } @Test public void testExternalDTD() { String payload = "" + "\n%remote;]>\n" + ""; StreamSource streamSource = new StreamSource(new StringReader(payload)); String msg = ""; try { XMPParser.parseXMP(streamSource); } catch (TransformerException e) { msg = e.getMessage(); } assertTrue(msg, msg.contains("access is not allowed")); } } xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/xmp/XMPPropertyTestCase.java0100644 0000000 0000000 00000016624 13777276623 030473 0ustar000000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: XMPPropertyTestCase.java 1829045 2018-04-13 09:22:33Z ssteiner $ */ package org.apache.xmlgraphics.xmp; import java.io.StringWriter; import java.util.Arrays; import java.util.Calendar; import java.util.Date; import java.util.Locale; import java.util.Set; import java.util.TimeZone; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import org.apache.xmlgraphics.util.QName; import org.apache.xmlgraphics.xmp.schemas.DublinCoreAdapter; import org.apache.xmlgraphics.xmp.schemas.DublinCoreSchema; import org.apache.xmlgraphics.xmp.schemas.XMPBasicAdapter; import org.apache.xmlgraphics.xmp.schemas.XMPBasicSchema; /** * Tests property access methods. */ public class XMPPropertyTestCase { @Test public void testPropertyAccess() throws Exception { Metadata xmp = new Metadata(); DublinCoreAdapter dc = DublinCoreSchema.getAdapter(xmp); assertNull(dc.getContributors()); dc.addContributor("Contributor1"); assertEquals(1, dc.getContributors().length); assertEquals("Contributor1", dc.getContributors()[0]); dc.removeContributor("Contributor1"); assertNull(dc.getContributors()); dc.addContributor("Contributor1"); assertEquals(1, dc.getContributors().length); dc.addContributor("Contributor2"); assertEquals(2, dc.getContributors().length); assertFalse(dc.removeContributor("DoesNotExist")); assertTrue(dc.removeContributor("Contributor1")); assertEquals(1, dc.getContributors().length); assertTrue(dc.removeContributor("Contributor2")); assertFalse(dc.removeContributor("Contributor2")); assertNull(dc.getContributors()); } @Test public void testPropertyRemovalLangAlt() throws Exception { Metadata xmp = new Metadata(); DublinCoreAdapter dc = DublinCoreSchema.getAdapter(xmp); //dc:title is a "Lang Alt" dc.setTitle("en", "The title"); String title = dc.removeTitle("en"); assertEquals("The title", title); dc.setTitle("en", "The title"); dc.setTitle("de", "Der Titel"); title = dc.removeTitle("en"); assertEquals("The title", title); title = dc.removeTitle("en"); assertNull(title); title = dc.removeTitle("de"); assertEquals("Der Titel", title); title = dc.removeTitle("de"); assertNull(title); } @Test public void testReplaceLangAlt() throws Exception { Metadata xmp = new Metadata(); DublinCoreAdapter dc = DublinCoreSchema.getAdapter(xmp); dc.setTitle("Default title"); StringWriter writer = new StringWriter(); XMPSerializer.writeXML(xmp, new StreamResult(writer)); String xmpString = writer.toString(); xmp = XMPParser.parseXMP(new StreamSource(new java.io.StringReader(xmpString))); dc = DublinCoreSchema.getAdapter(xmp); assertEquals("Default title", dc.getTitle()); dc.setTitle("Updated title"); XMPProperty prop = xmp.getProperty(new QName(DublinCoreSchema.NAMESPACE, "title")); XMPArray array = prop.getArrayValue(); assertNotNull(array); //Check that only one title is present. There used to be a bug that didn't set the //non-qualified value equal to the value qualified with "x-default". assertEquals(1, array.getSize()); assertEquals("Updated title", array.getValue(0)); } @Test public void testPropertyValues() throws Exception { Metadata xmp = new Metadata(); DublinCoreAdapter dc = DublinCoreSchema.getAdapter(xmp); String format = dc.getFormat(); assertNull(format); dc.setFormat("application/pdf"); format = dc.getFormat(); assertEquals("application/pdf", format); dc.setFormat("image/jpeg"); format = dc.getFormat(); assertEquals("image/jpeg", format); dc.setFormat(null); format = dc.getFormat(); assertNull(format); dc.setFormat(""); //Empty string same as null value format = dc.getFormat(); assertNull(format); dc.setTitle("title"); String title = dc.getTitle(); assertEquals("title", title); dc.setTitle("Titel"); title = dc.getTitle(); assertEquals("Titel", title); dc.setTitle(null); title = dc.getTitle(); assertNull(title); dc.setTitle(""); title = dc.getTitle(); assertNull(title); } @Test public void testDates() throws Exception { Metadata xmp = new Metadata(); XMPBasicAdapter basic = XMPBasicSchema.getAdapter(xmp); Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"), Locale.ENGLISH); cal.set(2008, Calendar.FEBRUARY, 07, 15, 11, 07); cal.set(Calendar.MILLISECOND, 0); Date dt = cal.getTime(); assertNull(basic.getCreateDate()); basic.setCreateDate(dt); Date dt2 = basic.getCreateDate(); assertEquals(dt2, dt); } @Test public void testQualifiers() throws Exception { Metadata xmp = new Metadata(); XMPBasicAdapter basic = XMPBasicSchema.getAdapter(xmp); basic.addIdentifier("x123"); basic.setIdentifier("id1", "system1"); basic.setIdentifier("12345", "system2"); String[] ids = basic.getIdentifiers(); assertEquals(3, ids.length); Set set = new java.util.HashSet(Arrays.asList(ids)); assertTrue(set.contains("x123")); assertTrue(set.contains("id1")); assertTrue(set.contains("12345")); assertEquals("id1", basic.getIdentifier("system1")); basic.setIdentifier("id2", "system1"); assertEquals("id2", basic.getIdentifier("system1")); assertEquals(3, basic.getIdentifiers().length); } @Test public void testEmptyPropertyValue() { Metadata xmp = new Metadata(); DublinCoreAdapter dc = DublinCoreSchema.getAdapter(xmp); String ex = ""; try { dc.addLanguage(""); } catch (IllegalArgumentException e) { ex = e.getMessage(); } assertEquals(ex, "'language' value must not be empty"); try { dc.addSubject(""); } catch (IllegalArgumentException e) { ex = e.getMessage(); } assertEquals(ex, "'subject' value must not be empty"); } } xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/xmp/empty-values.xmp0100644 0000000 0000000 00000000670 13777276623 027136 0ustar000000000 0000000 empty xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/xmp/test-attribute-values.xmp0100644 0000000 0000000 00000002311 13777276623 030752 0ustar000000000 0000000 xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/xmp/test-basics.xmp0100644 0000000 0000000 00000003342 13777276623 026723 0ustar000000000 0000000 John Doe Example document 2006-06-02T10:36:40+02:00 2006-06-02T10:36:40+02:00 An XML editor Apache FOP Version SVN trunk 1.4 xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/xmp/test-dates.xmp0100644 0000000 0000000 00000002431 13777276623 026555 0ustar000000000 0000000 2006-04-27T23:01:02+02:00 2006-06-02T10:36:40+02:00 xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/xmp/test-structures.xmp0100644 0000000 0000000 00000004542 13777276623 027705 0ustar000000000 0000000 2007-12-23T16:22:04+01:00 blablah Apples 4 Nuts 12 Hamburger 1 Darth Sidious Palpatine Apache XML Graphics http://xmlgraphics.apache.org/ xmlgraphics-commons-2.6/src/test/java/org/apache/xmlgraphics/xmp/unknown-schema.xmp0100644 0000000 0000000 00000002441 13777276623 027436 0ustar000000000 0000000 Unknown Schema Dummy! xmlgraphics-commons-2.6/src/test/resources/META-INF/MANIFEST.MF0100644 0000000 0000000 00000000105 13777276623 022474 0ustar000000000 0000000 Manifest-Version: 1.0 Name: sample.txt Content-Type: text/plain xmlgraphics-commons-2.6/src/test/resources/org/apache/xmlgraphics/io/test-catalog.xml0100644 0000000 0000000 00000000515 13777276623 027760 0ustar000000000 0000000 xmlgraphics-commons-2.6/src/test/resources/org/apache/xmlgraphics/io/testResource.txt0100644 0000000 0000000 00000000065 13777276623 030077 0ustar000000000 0000000 This is a text file used to test the CatalogResolver ././@LongLink0100644 0000000 0000000 00000000147 13777276623 011661 Lustar 0000000 0000000 xmlgraphics-commons-2.6/src/test/resources/org/apache/xmlgraphics/java2d/color/profile/ncp-example.iccxmlgraphics-commons-2.6/src/test/resources/org/apache/xmlgraphics/java2d/color/profile/ncp-example.i0100644 0000000 0000000 00000001024 13777276623 032544 0ustar000000000 0000000  nmclLab XYZ  $acsp-descRcprtXwtpt`ncl2tmluc enUS6Named Color Profile Examplemluc enUS<The Apache Software FoundationXYZ -ncl2PostgelbVP,fMyRed6Sxmlgraphics-commons-2.6/src/test/resources/org/apache/xmlgraphics/util/io/fourByte0100644 0000000 0000000 00000000004 13777276623 027337 0ustar000000000 0000000 ABCDxmlgraphics-commons-2.6/src/test/resources/org/apache/xmlgraphics/util/io/fourByte.640100644 0000000 0000000 00000000011 13777276623 027565 0ustar000000000 0000000 QUJDRA== xmlgraphics-commons-2.6/src/test/resources/org/apache/xmlgraphics/util/io/large0100644 0000000 0000000 00000044610 13777276623 026645 0ustar000000000 0000000 gTz2tomer.red]tTW. ~T"$Z&Êpjā7v vōڄR%V5!U -QHB(Ϥ<{l۟#-h~ >\/ QP^Đ+UR^%Qlx}{wmpJbc%˕Xx 'V264>p.5K Ώp~1fBa+ R ֡R@ozz=x>`9-.U8]FArJh%zRmb ̢r _FL&-#<8~XP~y1^/ wBYF%1|m:ŠdѓUqգR~S(FY.ZҞJ,L}8,F ~y\FiOWG],$3<ˠ_@!CCQ{ M.њ?_:tez3rʋJz;"(V K^eW7di39~~p"X$ !clip",^ %HhUFvWCQTJZ +r.Җʕ1m:Os* _/gWtlޱ9Y/ *G.c!9d >Oi iE/7<*>/܉V`| FY`>4' !aWaTFjBϝO.)dp KԜ|bdb֡SBTz]`>|%@C߁xn 00r8S)ü^M,@BQj$mظ׳֥\Kx.xR^ŢEt231ŤsZ5 ,]fb _X# x?7M??OH:,b/7`Wk*Jkmv߹11h.1SvROlqhQ@0n3 l,"\|p ȫ GXM3B"ze2 Pb̉y\ZŦu=YYݮ6zK$$At"nYIfT&-X:>+kJ:z} <.J ??_@0T"IW0_G,įQkZ-XJc.XxMݼwmJ4.\c*5dJc0Ұ*`:e 2#K^$srpAt?.<|1P!. Yhz-U&/%;k+$Z˫kp"P0qi;>f}H f!rN3X綻-[O]j\o0ظ-3KH$:90X%-#K J 06$Bͭ0b܏3?K? H$1`]*59tŜ^m3XQz^k0@CWW/_^3/_'zq`+9w{iO~uؼqƾ'??I|"~\vprK 7EqU &Rrk߁/gח/o;ua|Ͼ|tSW'ݾӱg΍}߽;CʇgO<8su NB91Dh|4mU0n :hxd\篼s_v?w~wc'/m?GלGO'n>pȖc}| cr 0{a!L(9?tהF>b!=c  hqa՞cˮznDoYc*Ts_WUڦʃKlylh̍ Wn3?͹8s"2?W$HWi#uCW*JPøCf1MUջ"C[ uR!l$IG- eHXFY$Ds(LaUGi ~#pspMg/z&XG_1'.sD)7ltK<',v ~';m/291ŌI\}Ge\Xh5AvgiVח XFeUApX k8Z/axܾ X\)c$Aَ4:[.ܛ#aQx&To;]b~1ǻ't/ыXN_Y[@V%7TxRh (כ?7X > ;%D f׈؅~o;qޫfQ1dZNC5N6BD+FMUV_êI%kW]I"x3(_5MҺ/E=*%aԾ\=\jqN+IX2 \XUP2IW[W;u'_|{rpTWsNo>6}2Zi8x݋t!WDGz(ݱTo1C[LV+JTҾH!dsƶe!f_x5#76]FWG (.*"$,{٬tyoppDJf\3. x+[Ț&b*NsW5wT?qPd}jm[+a b:g[M}GL(ʆXsReh6R~Kܬ, /_5a'$Qk"{ 0if!cAD*{ѽbeVkmnv:>#QSWBT^vUĆ&Yn.d*ŐN_8"KZ>1 H;&p9`NX`7Ai b Bh"ܸSrL\,|mp=QEpmT-UZFt'{J5T M{ϴ r@ /S לP2Zt\`(nyj/ գ5t=]AWКdsU/lNZ3$:gO`B_)h/VZz&ȇ6{!i$s:wW_!#N&X+]0tVBpE]հ'7+%= #톀֒D$ޮA,DڎQu EW'>@b9Ut?C(W=ׅ~P!In3McWo.Dg(TE*M?ㅐϋ*YM&H.ȗW[X(TitX:Jc0ilR;/w\bKJ= mgG݈HX +*˦?P2Xzi5}eEYo˛x}[OU5D7عe5ξe…z뗭 Kps/ؔ!ӝ7.^wagzbE AR’SX 6{,(n'p$^]hlܼtg91?_1oQ';=bòXw]{AMɪf !VYqhU•-x瓍?}l#/X2g iQfNa' ?CjP q֯m0^_TU3\eJ4c33i,O},I;UnZeMbC7ڹk|סe{[ee'7~䧧x덨aob 7@( %*)ArfǛK2gΙ;UzAV* _ f.+f}ؙZ^ڦM]t5w֛E؞.7\ዧ7ߟ|7/pwtH>;oXi׍cO|L VhKXbJy\PRhTZZǤ{p$QUMv5kM <+e/,)YX\w?xg;ݸwa??y7Ʒ=ở;ᠻBd]˿Κhs.X&]0Wx%+e, drHIv~18ws3rcUQbEpzIQ>ThxE3EkoӺ.rj_;ŋG{_Vݱq1az7nnӰiC ^r[ <$b/-$3sА:TPPtҌfd#-{OmKFNPf`}xO.\fQW4KQ$KU9zެytjP}/ekn]Y_x؇7_7i,;$ee,*X8c)P33] +_.^rҹMqn_$OVw,ӢFg-UaW@-z33{l1sѼâN&u=\ALik :k?`Qqǎ^ Mw }Ti!ZsgϚPs2gef.QJ(tܻc|;kH$Nu"M MZ0qV=M_γTdw/A[U򫫻a>P8hU 06|``_H9o͚].a-\SB [v޳uw߾cmc#D4WU뗀^X\<ȉQG$vVf0k'2NUGZ-!RhH5Mz¢4kM` D}ī2\(/%/ZY$T7ڵ䡉':svԱ#ONHśzzk*ң|,Z5Q(bs6nd[Ґh#W̨kJ-(_PQQYT#Rk v8~6\.Nc/)(/̘ R[&z5{.\xđ񓧧N_z֍o߸xؾ=:暚Ge NKjhh$7bg#DJ#+5Ndx\n*vd  Z`t("=_/`wb]@)gJ*4gAfN>C4vk7W/tݽqɫ?wֻܾvԡ}O=udUoٚ5붌m߸1VHe*]~qf<^ Eb5"¸єrF8.O1M)I|ϭw ?:L&'"\!,PQ󲩅38"X^{+||;7WXVvG>zp޻7\0uG&&v/_ad&N9yxswuU`i&m岊FReA!ݡLm[GGK2x1MEJo0v6/ƞ.i|$\6K` JbΞ_ի~x<2d}إ?G<}¾cGN:>y^u瞉C?rk:Q2剸.I &^ :a*ɘ_ȦHnFZ5t?~A^9VqTaҪ:aYx#7u>C#3<{OL>z+VlwhԹc''4<ڿlqΟ;}ľo2u `i67йvbrϞؿ{=k~=Vԭwm[wv7ؾwW._x䙗GjkP٣#ŅrJ!!NGŖjNT$~oj(=(\X%2IIr[<{ܹ3f^|x_MtUoI\.BO҇w|I A>V>iQƌo̝;kx{ųO}W<9d&G''֍7o|c_vGػ{}KOgK*|뷮ݾuScWU*$r?\ 񣛫*S5ф ??" Q ")%@n}o}ӧ~WOU}@m]n>{ؾ}mꮉ3pGnii[so߾v<ϿcP* ά0J.\~eԩG7-ZCU&8ۜJ*TV xy@'!t&Qit:g)"z񳯿ϟ~w/?}@_dpx߻wn)埓OͷJ2Y`-3{MD_D22,"ɺ{_=ٓϿg|q/>{?ӏ. }8>;7//[ Gwﭱ+tU=< 6`٫7zo_?~× vJEAS$\^FƐ~AY%I4#"^Rn1_WQhBKϦr[X_xOݯէ~ǟ=|GvkOjEm޺vqESޟ`45ZlݲeSow?Va=|Ě'Kf27J3}>D2MFbQQpg.wnBQ\d0JȬYd|ŋoy~>xPɜrs/`56;~pgPG][w͟߾y~gwv3>QbTt≊UR 6N%x>H(L%’r;gz~ӓڽwݻl=ɵ61q}Nt5붬6q??۞hf*$fby:-.3Ũ@aNPWiXNwp?(Q VXP` (ELkϞ> <πyMmۼfÆM/ٻyrPo1yΝU om1%V8ygn?w?<˖D.%]F#V{P 5;e/A%\]NfTbpL 8 a"fYYf4mj|Ǐ}w t|ȮUkF6w|kߡ cOߵ~ުxN)3n`t歧o\}pǿm$=0 K ^OLy$b0YbdQ&Z($S23i'o1j~C!QȌR*hm}# <Vڿ~BM#Gk7l=cŎܾ56XNn[?~+{㖲5 #JK+ 攓sAZhAq 2Ie|D$%Y40`:'r#I^qIV.QQD*d ==CMo:twwu-Xmt}Oۿ{P*굸=nI l^e׽rN]HA%)Dg@`d1)Yy F#UU׬t:O( HZF9-M upi[-B"yif ޿8MA1N8>Bc sYeTcb.ZNݺ{߻}Y)ڹ;>ӇW޸#!T:zαV}vte+6ًU};fϙ# <<äFCPMi9z{)KP4O쵺Tb`o.cVxb"SH,:Kbtׯ];$ݯrx䉛='woN8s`W{oZ7<4.msCʦU[6=hx_N&;,)kUJ%UqZ:B2C5ISpC8]44Թlާe8A;px ~">b.ZCQT -g_zE\CS?gG'lݲqt׾-A1pxƁ5vM\[_zLaAX38%e݃ckZ::wNP[[gVn.`wٯ tp< HrFFf~n~.""3/> ~u);1q{>λ?c޶i*q5Mk7o7vVl3hOXn_7 Z߼c֯U [~yEjĮFjԵkF"zkc%$؉HʔRȴ*]J%E9K $NM8ux;uD|힉w}o߼~͛v:wtU_c" IU5v Y:%Rk[o^l`h`-UNVE~qƖf>Z)>gvK)Yٻ؉6]!YWF>03PYUQ_W=V緿(-^kW5rŬڎƆeAyMBoi\di$4ZSV]k@K ΫM\(ADbYR[4/{3gg̛h^=ieMښѱ6]|EW{GSeEe1T63ƪu RFu,xk_d[jk0:<[4l#ڪVZWk> Um߿`0g_#FB)( ¬3g(bk;zW XVߵrkW ttv6t t4$D"jlhdh j9eR93f"liIUkcY>WXom펨(ninT|mkEZįA+`39mBP3D.,-X2+32o5.omjkm]6|y{GOW@9lo.L54YsrQKpTse֜,i7툰 a#Uwu$*fL575hrtZA,oJյv6. ͕ K hKe9s2BV%:z:ښ::[;:;Zb UUVjEof2QE5gΌ_1J)ޠ%mQUS+O:"E=v_%Lj4Z'6 Z}N\VR^0+rr1sK)H7vwSPP[[܁Ɔڰ4#+䕀JbŌY3#NaZS1EC-Or{"&]_O`"ڥP;5m|W@\ը);B8`&7X",@iQY<*5ͷfx3Rrv^ߟhokonkiiK$+@TFvRk\S+%#l^I$&.y/@HWPBlOĢWJQYUR;&RbY\]Ng3M@t"⻔Q]R=wܷޚ1+\BΛdYUVפՉX"^-n_4Q]%YD^B[HQS9@5r^L'6֨c\ WZ^"YќƆm}'ڵmۦݗn~ĐnW-P<xp$,RZX[`֌Y(sެ3gΚ $Du2Q]]RIU`%xe;P( H2/Ly)7K\Y3:۔4W+z@ k/ן=//S.oWw>?Mgfa>L}rX40eYF# y s ,7c֬sȜ`;1нbGeԛKv5k PR($ǯTH`WR 6ڛO o^wҵ~{Ƨ?͟a+::Y@._\]ZRPRXGZxYK0Ȍ7g̜oԁ UW͊M[pٵFv;=` (*/<dPI{_/h9s>ɮm:v'?ןNuj{_} -F]~ޅ+nOt: $bIW|v@^^R8txdY?7|knf`d5+VuwuTWĬfn fgHR*XfId[1=bף>Xrk[|Xbk!ܘlwDF6ë"F8~fZMPz6*/E?;7ga1IFloH.,rE8Gglڼ1X vD:<..^lƒJE3wiV .9oƜ3Ν5kޒ2Eb0cp%`RTR5Ia*FĔ,0^ow֭3Z/Wntvo1y@Ŋ쭩d_n!4:|*g{(xF`UB-!f͛ւsgɘ;{9+[ ƪ~h3T5&j~PhpQPT(kQG0:LeVZ6KjKu}&et}[ ,>9Zj;ªP3*t:^U~H+"5{ e.],flҩ*xs l6 lլ5"N'7PdɚO]VCPeptΚZMIWz kw% |~,c!ƒ<ᇳǰwQTR$ňREE2R/0&|p-#dO}LЋZI-quU^FTkSΖL:gliiViP3KEy -*$\MDJiL@0@CLiJK բT2T*2^ÖK<*Qo4a rU4bx\ќv_#!!?es#ɪzB˕*|QTGH=e<#da KMB4zx a/ /:-qa[fu즤TTgCK xNI) 5&Z#d X~X,#6 sNRBv# K+n٦CFm>`c,(;|:xAbhT:bSjRQy6*[&a 9A>*IɥeM,q]D1`y$$ϣH"ZXnDb/ʦ^Tf$1; .[JDb6_ˁ78tKVN[I!U|Xh\DdI~.RI-T bQUB' Pau" g)ED:~z4vv@ Un"be*%~G &FlQ zAߝ. _Edd⢔[Y9E'5d2Dlt"b$cif j rL(g:*n怔UtfOc"b63& 6#J0&VR$},wX2+6[mZFOVFbEX"`Nj J\"&FV\fdhX`ZHPz1&U ûETxMߥ">lfӺm^kWTD:leRNESO\UEF,4^ZwLv.ã/+ 7|D3V"pWyiJc( c`r8iLF2uz8hMf2C/%ɢ.Ufȱc'V.2z5+*6[U ΁Zo͖JVǫ==a[ހ4^%ˈټ4@EFB,W[3O~վb;=5yW Y T Gj!6 m\>;Zjx|n"ѹ+v ~M l֠C`'`+W8 _xE8Їy4kgnM6;V:VYNL+xe2LF.5MSJ E$HtM CMo ;8˙aXH0R|t c!LM9 :^hAR%q:\,O]YV^Y\ -)XbNб V):z1*ct6Q%*Y" Esx"}9*p+(GN; &8h#A(Ѓ8Ӛ0m- 69 XWN*!C1٨RR @F9b1KY\X32FX.E  Zf bxY@(i,fQ1yZI`*vVTktԉ`0*l4( 9a5Sm7j$Lmd5aQ@.D!BI j|T#5xL i_bJNf1ĭl`{] atjUFJEUַzMn&dsLTjCè;?.,`)LK̨JeBB: STpq%$Ħ"x d2bFqVTGF` $wU$.\٤uv9FPk{*&T`kEcz-/ QKUmCr 6Xa4`}x_&D ~ Bĵ~l.ب4 -|/P[-uGF,$*Qv;aV]rI^ A=˦'֖F_`ѕ5r*ZaxuÔP qJ H$@OPT b \NSiM >Wkjndg_n\V[Au]zrQ4*YVN' 6( $JI(` .a\,$X(p2< o7MPj &+ryfqm}CW݃ǗG7\6~oLV)j}QIU)d<&eQJc9$͠2 ?RORlsH _"b8=K9\L&"(d2Yz8p! -F}E,^n[ڃƇ׮5訊ҶkV1Ww)2W2eQ!Y 7 B%hii`@UcW($_`l.>S LA2JEs֪|}[pi|ݵ~d.v?w]{.ض+ l ܧD$,N){WރebÏrLb|b4봖㟱I2Fiu Ο|Ʒ\}rWkcQ_fG*`mXlhPUVE\Eiy ~)帊'1lWǩW2Āw܃:||6`Qg\ g@)*u=kG=޶纚F/0hEC 6i(<;hYo(Xbr$EJNe*TD[M#BӰژ)\gӃ b:=((Q(t:n`C#~ڱ1YcaHZ!L)dR K2Ș3##/%3#ťj )x*e1ZϞ1>4~ |U0Q\;lR`3Ww yCPWJ)P$37{И_tdu.' z[o8Mj3jsMѶWd4SV˪OFqM5UE{k*L[Vs_0^%D RT47 G108e ö;C+ ~ V}8=nM}8=_Ù`*z'|;]/=H\L- EKݦ`*[sw(mѝy)D;XrLC~lh(bly,lczw0VlᕱmkyraΝsw=Z:: CzmB'Fτp%X"k,`=6\Cu:(s> O<1g'O"[?"oLw_/G3ޑg.NH^/B%%~Jp(.=f)EqJ)C2>t- _ ez)G4i|Dsi' OY &M3Зb6!P@Z"q#ԕyG/5f~*㈜TQGi"A=Nv*ޟpd")/Y3#'wcW3D-%9p|ndf5lʦ*i bt%R#˔&]zFi`R$ق-8&oטG#';FfG\ JELwl)x"dKP^(dXRcU*#7A~!\IɟHצC8:E}c9 } x5<nw3?zǕU|!opW`> 7Ԉx*1|71j~>Pğѿ9%- xmlgraphics-commons-2.6/src/test/resources/org/apache/xmlgraphics/util/io/medium.640100644 0000000 0000000 00000003117 13777276623 027260 0ustar000000000 0000000 H4sICFfuQDsAA21lZGl1bQCtVk1T4zgQvedXdOUyUGUCzO5c2I9ax1FAVcbOWjYstzG2Qlxj WynZIZV/v6/lhG/2skMVRLFbr9973S1Bf/zEnxG9/0lXmvx1XuBDmWW/za2msCp022mPbrTt KtPS+eR8RD+XyYgCs97Z6mHV01FwTF/Pzs4+JDM3m7bMe9CYkF/X5LZ0ZHWn7aMuJwyV6LLq elvdbziO8rakTaepaqkzG1to9+S+anO7o6WxTefRtupXZKz7NJueGlNWy6rIT0bEGB5x7rW2 TdX3uqS1NY9ViUW/ynv80cCpa7Ot2gcqTFtWvKlzmxrdXzCp88kbXh2ZJR0YFaZE6KbrCVL6 HFQZNL83j/zu4Ay1pkcxPFe5flV1VAOQcV4mbcs3jJC1qPOq0dbZ8/U9E+R74cdAxGqoLDcg 9xGV/8uE9hJLU2wa3faupA4Nu05RCYO3lpq817bK6+7Zclcqt/WFBCfsl4lrGd2WJ6i3fY2N hEW9eQVgX7ngUbVE8p3n5Dsq+y30RgXlxY/WbGtdPjD8BdE4ZQsGv/rDto6rO7StQyv1o67N Ggzofucg/6O7iY5Wfb++OD3dbreT3MVNjH04PZ6MHZpfw5kW9tRg7Crwhha82+HZeq3zJ7cP fKjqO10vPUhcHkynLQwHRUvdpmCDKluerHPb794Adyi+bfK63u3Rnfm/Dua3eQPh4ylE/Bg7 WBp/rnJMQ6+hm+gefqBsaBnjKKGMxmJseSzhbGN6rPcWdzDTVo9s5RKv9vqf1B2mGOGVsQ5t a3ly22GGu86dH3Me+HfPPVrXOu+42dE6xdAJQwH+eq6D0/xtQosDoSdGz4Se+HAlWCJrLGAc ovamjD02kwNcmsPTQ9n2daus8xXlOihzwj4gTzyC2DG0yOdnJ7NPr6QiFc/TWz8RhPUiiW/k TMzo+3df4cGXL+RHM/zekfhnkQil8C5OSF4vQokl9iV+lEqhcA7IKAizmYwuPZpmKUVxSqG8 lini0thDMvHBPorndC2S4Apf/akMZXrHKUc0l2mEfERz5PNp4SepDLLQT4gWWbKIlSAmTTOp gtCX12I2IVBAWiJxI6KU1JUfhsR5R+Qv/AD5n7QCNYtmfirjiJygVFEQR2kiQT1OkHYqwN6f hsIRcBbMZCKC1CndL1kz/AL10CO1EIHkBbwSEOondx5jA1eJvzNE4S0I+9f+JYQfOb9wvXxu GcoRZIm4ZjVslMqmKpVplgq6jOOZYnQlkhsZCPUbhbFSIw7LlPCQJvVdekaBmQjAl2mm5GCr jFKRJNmCLTgmuopv4RrI+hnXmKseRyMnmx2MkztGZkdcjSDy9krgReJMd9b5bAgpeBikryKR F56mo71k1ksUictQXoooEI5kzFi3UoljlFUqDgGuy3/rIzfcQX7uIZaH9Zvu9VzRSc7Jn91I 16ZDODpFyX1jOQuDq30JhhF4NaY88R1uBHczP5p6g/nHlcjnwPNV2eR8IeAAb3BXYD7LCtfS BjfUiHj87vUqr5eHMXw3gq/+f+HzpzH8tGr53h0OftMOA/z59D6dUJ3W9PvH18Sfk9G/1zkl kS0KAAA= xmlgraphics-commons-2.6/src/test/resources/org/apache/xmlgraphics/util/io/medium.pc.640100644 0000000 0000000 00000003117 13777276623 027661 0ustar000000000 0000000 H4sICFfuQDsAA21lZGl1bQCtVk1T4zgQvedXdOUyUGUCzO5c2I9ax1FAVcbOWjYstzG2Qlxj WynZIZV/v6/lhG/2skMVRLFbr9973S1Bf/zEnxG9/0lXmvx1XuBDmWW/za2msCp022mPbrTt KtPS+eR8RD+XyYgCs97Z6mHV01FwTF/Pzs4+JDM3m7bMe9CYkF/X5LZ0ZHWn7aMuJwyV6LLq elvdbziO8rakTaepaqkzG1to9+S+anO7o6WxTefRtupXZKz7NJueGlNWy6rIT0bEGB5x7rW2 TdX3uqS1NY9ViUW/ynv80cCpa7Ot2gcqTFtWvKlzmxrdXzCp88kbXh2ZJR0YFaZE6KbrCVL6 HFQZNL83j/zu4Ay1pkcxPFe5flV1VAOQcV4mbcs3jJC1qPOq0dbZ8/U9E+R74cdAxGqoLDcg 9xGV/8uE9hJLU2wa3faupA4Nu05RCYO3lpq817bK6+7Zclcqt/WFBCfsl4lrGd2WJ6i3fY2N hEW9eQVgX7ngUbVE8p3n5Dsq+y30RgXlxY/WbGtdPjD8BdE4ZQsGv/rDto6rO7StQyv1o67N Ggzofucg/6O7iY5Wfb++OD3dbreT3MVNjH04PZ6MHZpfw5kW9tRg7Crwhha82+HZeq3zJ7cP fKjqO10vPUhcHkynLQwHRUvdpmCDKluerHPb794Adyi+bfK63u3Rnfm/Dua3eQPh4ylE/Bg7 WBp/rnJMQ6+hm+gefqBsaBnjKKGMxmJseSzhbGN6rPcWdzDTVo9s5RKv9vqf1B2mGOGVsQ5t a3ly22GGu86dH3Me+HfPPVrXOu+42dE6xdAJQwH+eq6D0/xtQosDoSdGz4Se+HAlWCJrLGAc ovamjD02kwNcmsPTQ9n2daus8xXlOihzwj4gTzyC2DG0yOdnJ7NPr6QiFc/TWz8RhPUiiW/k TMzo+3df4cGXL+RHM/zekfhnkQil8C5OSF4vQokl9iV+lEqhcA7IKAizmYwuPZpmKUVxSqG8 lini0thDMvHBPorndC2S4Apf/akMZXrHKUc0l2mEfERz5PNp4SepDLLQT4gWWbKIlSAmTTOp gtCX12I2IVBAWiJxI6KU1JUfhsR5R+Qv/AD5n7QCNYtmfirjiJygVFEQR2kiQT1OkHYqwN6f hsIRcBbMZCKC1CndL1kz/AL10CO1EIHkBbwSEOondx5jA1eJvzNE4S0I+9f+JYQfOb9wvXxu GcoRZIm4ZjVslMqmKpVplgq6jOOZYnQlkhsZCPUbhbFSIw7LlPCQJvVdekaBmQjAl2mm5GCr jFKRJNmCLTgmuopv4RrI+hnXmKseRyMnmx2MkztGZkdcjSDy9krgReJMd9b5bAgpeBikryKR F56mo71k1ksUictQXoooEI5kzFi3UoljlFUqDgGuy3/rIzfcQX7uIZaH9Zvu9VzRSc7Jn91I 16ZDODpFyX1jOQuDq30JhhF4NaY88R1uBHczP5p6g/nHlcjnwPNV2eR8IeAAb3BXYD7LCtfS BjfUiHj87vUqr5eHMXw3gq/+f+HzpzH8tGr53h0OftMOA/z59D6dUJ3W9PvH18Sfk9G/1zkl kS0KAAA= xmlgraphics-commons-2.6/src/test/resources/org/apache/xmlgraphics/util/io/oneByte0100644 0000000 0000000 00000000001 13777276623 027142 0ustar000000000 0000000 Axmlgraphics-commons-2.6/src/test/resources/org/apache/xmlgraphics/util/io/oneByte.640100644 0000000 0000000 00000000005 13777276623 027376 0ustar000000000 0000000 QQ== xmlgraphics-commons-2.6/src/test/resources/org/apache/xmlgraphics/util/io/small0100644 0000000 0000000 00000000232 13777276623 026653 0ustar000000000 0000000 Thomas DeWeese Thomas.DeWeese@Kodak.com "The only difference between theory and practice is that in theory there isn't any." -- unknown xmlgraphics-commons-2.6/src/test/resources/org/apache/xmlgraphics/util/io/small.640100644 0000000 0000000 00000000323 13777276623 027104 0ustar000000000 0000000 CQkJCQkJCVRob21hcyBEZVdlZXNlClRob21hcy5EZVdlZXNlQEtvZGFrLmNvbQoJCQkgICJU aGUgb25seSBkaWZmZXJlbmNlIGJldHdlZW4gdGhlb3J5IGFuZCBwcmFjdGljZSBpcwoJCQkg ICB0aGF0IGluIHRoZW9yeSB0aGVyZSBpc24ndCBhbnkuIiAtLSB1bmtub3duCg== xmlgraphics-commons-2.6/src/test/resources/org/apache/xmlgraphics/util/io/tenByte0100644 0000000 0000000 00000000012 13777276623 027151 0ustar000000000 0000000 JIHGFEDCBAxmlgraphics-commons-2.6/src/test/resources/org/apache/xmlgraphics/util/io/tenByte.640100644 0000000 0000000 00000000021 13777276623 027401 0ustar000000000 0000000 SklIR0ZFRENCQQ== xmlgraphics-commons-2.6/src/test/resources/org/apache/xmlgraphics/util/io/threeByte0100644 0000000 0000000 00000000003 13777276623 027472 0ustar000000000 0000000 ABCxmlgraphics-commons-2.6/src/test/resources/org/apache/xmlgraphics/util/io/threeByte.640100644 0000000 0000000 00000000005 13777276623 027724 0ustar000000000 0000000 QUJD xmlgraphics-commons-2.6/src/test/resources/org/apache/xmlgraphics/util/io/twoByte0100644 0000000 0000000 00000000002 13777276623 027173 0ustar000000000 0000000 ABxmlgraphics-commons-2.6/src/test/resources/org/apache/xmlgraphics/util/io/twoByte.640100644 0000000 0000000 00000000005 13777276623 027426 0ustar000000000 0000000 QUI= xmlgraphics-commons-2.6/src/test/resources/org/apache/xmlgraphics/util/io/zeroByte0100644 0000000 0000000 00000000000 13777276623 027337 0ustar000000000 0000000 xmlgraphics-commons-2.6/src/test/resources/org/apache/xmlgraphics/util/io/zeroByte.640100644 0000000 0000000 00000000000 13777276623 027567 0ustar000000000 0000000 xmlgraphics-commons-2.6/src/test/resources/sample.txt0100644 0000000 0000000 00000000016 13777276623 021725 0ustar000000000 0000000 A sample text xmlgraphics-commons-2.6/src/tools/resources/checkstyle/LICENSE.txt0100644 0000000 0000000 00000001364 13777276623 024054 0ustar000000000 0000000 Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. xmlgraphics-commons-2.6/src/tools/resources/checkstyle/checkstyle.header0100644 0000000 0000000 00000001575 13777276623 025545 0ustar000000000 0000000 ^\/\* ^ \* Licensed to the Apache Software Foundation \(ASF\) under one or more ^ \* contributor license agreements. See the NOTICE file distributed with ^ \* this work for additional information regarding copyright ownership. ^ \* The ASF licenses this file to You under the Apache License, Version 2.0 ^ \* \(the "License"\); you may not use this file except in compliance with ^ \* the License. You may obtain a copy of the License at ^ \* ^ \* http://www.apache.org/licenses/LICENSE-2.0 ^ \* ^ \* Unless required by applicable law or agreed to in writing, software ^ \* distributed under the License is distributed on an "AS IS" BASIS, ^ \* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ^ \* See the License for the specific language governing permissions and ^ \* limitations under the License. ^ \*\/ ^\/\* \$Id.*\$ \*\/ ^package .*xmlgraphics-commons-2.6/src/tools/resources/checkstyle/checkstyle.xml0100644 0000000 0000000 00000043161 13777276623 025112 0ustar000000000 0000000 xmlgraphics-commons-2.6/src/tools/resources/checkstyle/suppressions.xml0100644 0000000 0000000 00000003504 13777276623 025526 0ustar000000000 0000000 xmlgraphics-commons-2.6/src/tools/resources/findbugs/exclusions.xml0100644 0000000 0000000 00000014711 13777276623 024612 0ustar000000000 0000000 xmlgraphics-commons-2.6/test/images/asf-logo.png0100644 0000000 0000000 00000034221 13777276623 020571 0ustar000000000 0000000 PNG  IHDR3(( cHRMz&u0`:pQ<gAMA|QsRGBbKGD pHYs+ IDATx}Uչ.330 0P;%^F(.veo!&7M4g=othM Cqn[!zMs~)c>CӗRzg^pq_^3_oHM_fsWmݤEQ. ;JJ+jsEX.òX.ǒ$.&[0; *(Yii~ƙ@;7G˝pYv7%'DIdl^6]heƎĨ/+Xe9#`]Qŧx]ӬJN-5_vY2p/ XJlG@`YtZQLT7MQ8؇5~ W4f2Mcj.xi[88Oxp9X*`9~o[p 5r5_ا{D{kj9W_ 1S 0zod.fY4bnb-ybzJtf$޵kUoo0][6ý]a;nR 9?o<,r5#f,GaٍӍ]vc$=pIxX~5v](˅XXFdOXy% #<2E?(C98X,kLng vaw&֚BrMJ5=}JK2Tғ!h tB`@/DnZVq]C;DJyQr\Iv֓~m+py2a 2h(?4sqjW`g-PJ&m#{+'R-P* *Î|lBF]:zબ x>!^u`~ډ`c# eJPK!3& *LgJ"d[WFEYY#n]]]/q8"8UU3Ϭ?K΀xj%lBwGk+bR=``X >c=3HKd~ݐأS K9zk-!*vAY)>Hd(, y:턁CDQ@X(DH_f(W[zaX|fW- A&jd2SS?ZTEBBCDX7 A! JP t,|C,eFi)uT@$c1֋zoթh6g6V38t࿎k˗/g}Y PPDjMC7>lp#sc7Uk@kg\}w;2B2#KxIxg,_{Mp+wړPa9J쇯c,ė9Q< 9/6}Z*ok}0]t9eAf"I `jC4eAy7?&H8~d2"C|!Skjj䣏>Z83]vI!{r@G6uiEJAm&+UtBj֝Z<98$pYonޖXHjh;""쳛Թf Ƣ ӴHASvSe9+\v h8j-ɒACӞQeX թ 6p]ܿV ; nfsɶ7xPOMm76;chY~niGsRRk1W]9ʮr,m,|ʅkl~9ٿ?-|3y"?Lx 7voV_iQq}/ r^J SApqp~x|ȆYЖP&H>}eMP5Hɧ |1xe@3ZuV\]'k=ġBix  c_`IP:ӡĜˊvk' ↗=TCfg-:X2qEY ֌+7Q0-|JoB3?APߋ4@'09aOٝ~M3i0l~"c=u P, ah7ò5!gynv4|d:  dŚ > "Pt d^"@Kc(P\5,D w63Pc]`"?!S l]h mZK|+|3M#g+mi.*qBnT҉k`):jиu8kh۝/|]o/ΞU6idKúx)xi03T/BV.)bW\z's %.N:̥`8p@F󓒂@T ~7) qlJv9P蠍XU 7@mx>-7ru;:.JxbPr- yh8}60N@ 1%͐)S{'t?(Mf նZA]t}@xP}0.Rϱ ^mu#lw\%OW\N78p~h fk=۞_j'ևtU=;Aũ9exWʮ}U~Q*MLDZ$E4ꙫ(ˮNeRڦ1QRwDVʹVHV3am B Va!N͗$TCsG9;&G1B!Ey;@dx-eSa,2,YMw HQ‹2>1_IZtSȶCVc#ya&[J-%l* eiMRbH@% kKC.B?&'aA8tOw`_8Ntil/? 4wY3M2է_.J Vz lTsW o7< RX!jUߘ>ֹu4H6$"=LCJ6'W3DTA-)"-jZ/EiAv K``tpL1de*C ;6}0Qa?:  K ג|iם0k%nBҚ\Oe"OILzs1r! a c"+h(+)TdeAC*CU[i *U3VáI~o*3&  fyZM<32Mvp%H"d1d+n4AKG! PrfH P4ArVҦ,Jtd!q[{YNΐ~m_|#섡\'-*y&C0Bllr9R{k#P A@O3n*3Ӛd >0?'I`TЧq&b|IpAj*)jkƲLz="IvcV/V|hHWL<>sz=,w&HCPjB6s?)==(Sy41U z)LFrݜ`0dm|hͦF)e; LD;_jb :IL Y?w AU4 <`sZ@SABeà+h:h&LP&H\d": ̚0s+W\M&ْWgsfs3Nx'~{=\ 2u;E]fLLN8Pũg47ljLwL NP H& mz'fGsTSc4'ِ ݅ڔ$p+`\:%ϔHK4bpS &*k#lV)A11 hΦO:fn5 &Wc7ެ$!cӓQ ZߥK(6d6KD4 Q쁶\iovG!Ea},p }H6\WACPAtgl1e҄yRi;&S+ѡ_٧-@'f {m6= i9c &"r3],)h﮷Ê|~MEEEo/_|-[SWZf͚ 4ru'N<_]tQ<R U,?ZSP>K LNsɢ C!/VbAG6#o4+}Vw'd$ aL7)#>:5o2sLFD]9u_F&*JmATvCG>hc6dIA,FPbYV@!䆽zlLj9(6-`RkF } Lq%kM%}tO3M_h!=RcOfY|6q8Tu,Has U-NRk_΋tG)o !j ;`s Y Vꠢ|pWo{0[(lr%e7Fм,z_Mb=Jh% W$6I>3+m+tGp;Em2h䝞]z008մRڪL`&6 b\fCgʌ%~Oj,wA(]L}h~?֦Y+d% P^.A"d w8lxܧf5+vS6< )c} Bz\)L`5r#xĉ^kXLB!$[P744W`93X>Lk/7%z R3 kr[mHtEK1T8] kg!dM4H%BXI>?'_ =ҋ%У7(4j5LM9`LX2YhgA|/0`&8-.`lYhْ9,'Rag sʁ:|4)mejx ,0h> IPQ-De\ƴJMx˻\ȁGݹDfU~ $@PSc7Ɵc4Plx 8Jx%kql*)'Owy;T#pu6]^2Vɥtxoܖq3OE?gTD5rSK~MTVg T ZECpO_TC)7Fi㕙pm8>k {,h) ,fJ wN]$Ё009MaJ~.I/"\dsfVdД L~_z+[遬YNHnǂ?[P?vR0J%i#_h^tPC~P TbkVN< _/?X"FQOACex~:0K}yԓID֙D[d< &# PQUʥ`:9˽} I.f0QlXARr2nAP/ΐIK7ј([!rux]dp8/ Gd G F( 5 kxu@]>삯'M ,V\<-i{F۲МaTsyyN+P xI3L~zpyoo-·mI6qt߳E*z#'jӼ+jrCԋU<>]׻1ހ}w.Wt"5sJQ! @"սr=RԪpy4Td5T{਩^X0-?yl7wfxGAdc4`SDKsaܢEfMv"5O̮ؠ3ؗURB ˑɋ'{ID̄oobiH5 )cK0+W6ö QsVA]8|R o8F9SfO),>fw4R,#=⺈@~R__? ^:+d}gom뎼zɉ󏮂~˝%c?kǸH$Nٝ4Wt+ FΩxx0E7h&=P,.B* 9kI` 2$5I$H5Aqp H "vCP#c!|NVKSQ2i~Q>.gaK'ji@@ԣCՅ,)>r k'UhTRQ)_JSedA0)dQKzmPB}yXhytx}ܐf`S #9A"l&~}X{[E=9Y((fpo~ A`\RC셲2+L݊36cABPK)%}ITD6Gn[p,-4w΅]]'f8_;dJїvֿC93XPCpMHeųJ2Hv/792-iЂt)mdm4Mbw1O^BK̥@jSIѤORȒ\#ƔԜiOʕ%dt*p<엀&8c6L7>6r'؉jqD3Yry_O Aq#v/cz4Ѵ!.Vd g%x,Pg0 ,ܸn _dH\w40a/gs[)k O8@o.K WS<t/3r1F}dA=ؿHOp,|^OҚeMD,ur.RмNP]=jkIO8r>VK)(P5jV"pZ"f7 7C x;rnH}.Kǣx]qE-)-F!@U`&nm{uVI!urK/l{G͏ )>1XvyGx'M6$3{p0p Yn#2׭O .'^[Aoէr@0c g;UiZ?oo>Ef\]}8"K@$k I (ZFaJC`hoYG.,c9 Y%3W 6pNidcpȖئF~_Fo LHH`b-*NIW@^c=Az;% t6}L1AaP2dxUSVo n;GMI圏(m q֏=0o N--|PU+O\lI,ʂ #"[ͩT괹sSr7C%l~@zit%Ūbuw5鷞;''ϾzJpЋv^_c7:w_ ӟrzw`W&A`flR-s5FP9#zIgGc$-Eeǡ׎IXBqNF`" y A)0e!*ѱaèp9!W}U~72>0LBcQ~y|Co q T\?[%V`H jИT wۜ.l P1䦬td}) Yg[akis ~Z[J_XBX5>A=Ew~p{{ވ+S>f0Am L6׃͛ni ]Z"DEò!\]cgf~I=n=k/)t_>9~nBP062ң/N )맰#X쐶WG¯uJ*c#ڡܖR<&"tͫt>LM>!,W,XV)8|< rID%ͤ:76(O^8n-7}t^}VGG,m-+<8aFQ-wY<5ߓobp#O؉!&&jW_챻?RUx !܍SɝKGXq6M2|5R ݽ{qu|"kK:o~0!J\yj9}-1٠r+ْQE&`+ .rwؠGM(;.ċR$;fYG39 #ێ 9 bIs-˲kal#(`9@yF@vQҁ/+ HwыS#X1̲;MR;YOֿ 6T޾(rK 3ʧ JKRMB&Oukōi5SWkU~T]ŮQ.>LVl޾=B9 w-7Ah *x =}peI}u6~b5Ah n.pӲ0S#Hk5G9iH"blYL^0(4+ZYsXa'%Xԋ8!dρ⒒6*e8(!tn`\Y2"IqӟX!Μ[H$_ b+"c BX)N6!>ܵ5^8bt(ͭQiמvڱ㔖֜Pb?=_4/+[V3qHT=5& f>zA o-YSk]a<69_z,X;PLN27 SZƨsp^24y,#iӷdi2|?0E3ϙ  }xG얌`j{Q@n֒b6kc-(|@8,_f;e OHq OsQEXkq_шLw<&kao1L\+Ȓ+ 8ܹF1IHVLsW(VgAi4-vSٔ:Kex@s]dR{TgTtĪ#l-}V6c_R[@470lB!3*"+) aj/4jԗ-X,&ߣ nŕ>{=hFs#9,߂g8pb'¨/4Ju؅?lY.D]۶ms鏟ڵa=Źx#`1*ڰ?s";(#R֍1$<_ĿQcp[p^ yFJeDlK/>oSbhp?2n$8~}d旟}B Ub-bG2֑`;)ޏs{ YfF;43ϊM:%'pe7V'[ŕ+W 9°s*欁TYmAqAV;S\9'xn RY<5v;#0e ^g\pf `GY@I8 ;o0cv҄˜9 ^o:q[+(>}C; z)r16Ll` 6\,s'6h ,;-i1 gh42\-\\/A (WOGb<'6<7lZpgd<{pLrW(|s >Y>"~3!o1{X ٍ> ' 5̥Krn.o&bLq5厑/q܏^/-Jcm smXTmcm @1~!'B 0IENDB`xmlgraphics-commons-2.6/test/images/basn4a08.png0100644 0000000 0000000 00000000176 13777276623 020404 0ustar000000000 0000000 PNG  IHDR sgAMA1_5IDATxch41",(,?a0T1`4GÀ*hP* }IENDB`xmlgraphics-commons-2.6/test/images/basn6a08.png0100644 0000000 0000000 00000000270 13777276623 020401 0ustar000000000 0000000 PNG  IHDR szzgAMA1_oIDATx1 0 F'dhO?U!ExRP(M(ي0^{~3uG XN5"}\TB\.y 6{@<P6@R LIENDB`xmlgraphics-commons-2.6/test/images/bgimg300dpi.bmp0100644 0000000 0000000 00000330070 13777276623 021062 0ustar000000000 0000000 BM86( . .  ",*-7*8(-''($.%4,<5=:=>>@@EADEIKKSOTSQWR_[`_U_V`h^i_babcxfzkqprqtnyoyz||~~~~~|x|xywxvrqqponjjfgbc_`]\ZZYVUSTRPQOPKKJJFFEE?B>>;<:94534100/--,,%%$$""!!    #-+.8+9).(()%/&5-=6>;>??AAFBEFJLLTPUTRXS`\a`V`Wai_j`bacdygzkrqsruoyozz|}~~~~}y|xywxvsrqponjjghcd`a_^[[ZWVTUSQRPQLLKKGGFF@C??<=;:56453210..--&&%%##""   '( + ,!-.)-4.>2F3I4J5I7J;IGJNMRNSPGQHMZN[MSNTVW[]_igso~plimjpvu~xxmunv}~yy}z}zzyyxtursnpmlhjgfcdb`]^\]ZYYXTTSSPQNOJLIHDFCB?@><9:894534100/(*')%%$$ "    () !,!.#./*.5/?3G4J5K6J8K=:?;F:L;PCRKSQRYSe[f\Z[[\jhkigbhczp{tdrfws~{~{|z}{ "쵴~~~}}|xywxsurtlpklgjffcbba__]]XZWVSSRROPNOJKIGDECA?>>=9:894534-.,-)*()%'$#"!    ())*&#$!!"<<==06178D=E@CBEA=?>;@:;9:5645./-.*+)*&(%$#" ' (!"# %$.+;>>=;;::4332//..,++*''## !(!)"# $!&%0-EBCN@SAVRWVOWPXOSPTUa]jpnqoicjdosptitjruouoqrwxzz鼮|~|~y|x{twssmqlmjkhiffee^_]^ZZZZWVVUQSPOLMJHEFDB@??><<;;544300//-,,+(($$!" $"&$ !!)--(+49*2C?C?<-A2;;@H?L?KEPJTOZLWT`QYWYc^dYeWl`h^wuvtljpnv}slvr{{w 구²鸭||x|xytwssopnomllkeddca`_^[]ZYUVTRPRONJKIGDECD?@>?9:894534100/+-*)%'$# !! &$'% !$'3314-2.6>:A=;,2#??7?=JDPITHRHSP[O[fn\^^YdYk]pdvlompngeomt}zxhmst|||蕠 컶||y}xytwsspqnomllkfeedbaa`\^[ZVWUSQSPOKLJHEFDE@A?@:;9:56453210,.+*&(%$!"  #!$" !"(&,63--31*+RZtq    y|jS^NYKWI\gakenksio{x    㔒~~zy{y޲   ܺ  ظ     '{}{}xywxtursqppojiihfeeda``_[]ZYVWUSPQNOJKIJFGED?@>?;<:;7965120.,-+)%%$$ !   $"%#!" #)(.,)773156E( /bKaQXJ\Ncnkuirdlhn6    &{~}w{  ߺ     |~{}yzxyuvturqrqlkjigffebaa`\^[ZWXVTPQOPLMJKGHFE@A?@<=;<8:76341/-.,*&&%%!" !  "0&1%*=>>?//5,I/ *-+!v}ZrZbSpiwr (% {xzwy혵 ##       ߼  ~}}|zyyxxvwunmmljjiifeedcb]][\WXSSRROPNOKLJHDECD@A?@;>::4733/0.-)*()%%$$""!! #1'2&+>??@++4+N4}wv~}x}ɜ!vnKt\tejcpk. ٞیҷ &膁tv|~ 㧨ޢߣ 훝 Կ     ~~}{zzyywywonnmkkjjgffedc__[\WXTTSSPQPQLMKIEFDEAB@A6>7A3?DGON\aSXCM5?KLgV  qqq\Sf]  yhrpt|mw}{曚 眒     輦 ~{}z|x|xsrrqnmmljiihfeba__[[WXWXTTSSPQOPHHGGDECD?A>=9;874531-.,-(*')%%$$&*'+3&5(!(")(108D==97<:B5?>JFIMLX]Y^?I>HNOraÅqccned[|܂ vtrrzw{眃 蝖  ᱩ  뿨!~{~{}y|xtssronnmlkjigfcb``\\XYXYUUTTQRPQJJHHEFDE@B?>:<985642./-.)+(*&&%%-%.&--.4/90:4:8;:7>8B:C;D?EFGJHQTQZT\TXP`_\^{l ogrjmgrq ╀ڠ 쫙   ~~|x|xyvxurqqponjjfgbc__]ZZYYXUSTRPQOPKKJJFFEE?B>>;<:94534100/--,,.&/'../50:1;5;9<;8?9C;D?B@GDHFLJMONSNYOZSYUWcg_eScyꈔљ'rgwlzwt|  葂xzxuuss ~諞 ʲ 껺}z}zzxywtursnpmlhjgfcdb`]\\[ZYYXTTSSPQNOJLIHDFCB?@><9:894534100/.#/$1)2/337::@AEEHFLJOKTLUMVNWOXPx%  +cl]fss~vn䘉{{|ts~~   ' ꮧ  羺 ﲳ û~~~}}|xywxsvrrlokkgifecbba_^]\XYWXSSRROPNOJKIGDECA?>>=9:894534.6/73:7;9;?@ABFFIGMKPLUMVNWOXPYQxh!͞[dpyww~w}rxf䘉{{|ts~~     弾  û~~}yzxytwttmpllhjgfdccb`__^XYWXTTSSPQPQKLJHEFDB@??>:;9:5645465798>9@:E>F@JGLLQRPUUYUYYZZZ^[}w/$ ³}}tv㜊~~    Ҿ໾    ǹ 콳|~{}xyxysvrrlokkhigheedd]^\]YYYYVUUTPRONJKIGDECA?>>=;;::5768:9?:A;F?GAKHMMRSQVVZVZZ[[[_\ys݈אӣȟ .tx}{x 䝊~         ½ 콳|~|~yzxytwssmplljkhiffee^_]^ZZZZWVVUQSPOLMJHEFDB@??><<;;<>=?@@EAIBJCLFMJKKNQQXQWZ]ada`edU_OYW_ilpmud# ̵mxw|}䡇}쭠   |~|~xyxytvsuopnomllkeddca`_^[]ZYUVTRPRONJKIGDECD?@>?=?>@AAFBJCKDMGNKUUPSLS[a\_VYjicbWa[e\d]`ifxШ u{~~ ֓   묢     ͷ°"|~|~yzxytvsupqnomllkfeedbaa`\^[ZVWUSQSPOKLJHEFDE@A?@DLEMHPLQMPNQNOOPKKRRNO_^gdjf}w|vknknz}||ss t}~z|ڜ   ꮙ 皫 źø{}{}xywxtursqppojiihfeeda``_[]ZYVWUSPQNOJKIJFFEEEMFNIQMRNQOROPPQPPUUXYWVfcqmsmtnrutwz}}}|lkor{w  蘐 竔  ƼƲ|~{}yzxyuvturqrqlkjigffebaa`\^[ZWXVTPQOPLMJKGGFFF?G@JGNMQRRSQTRUSVZY\]rsy~'ל֜Ԛ腊焘蕥ס  {}  ߤߜ㠰ܷ (ꭦ鬥諯  ͹ýƻȶ~}}|zxywxuwtnmmljjiifeedcb]][\WXSSRROPNOKKJJG@HAKHONRSSTRUSVWZTSdekluz+..&  ʴ &% " !š ˺ĵ¸¿Ÿ ~~}{yzxyvyvonnmkkjjgffedc__[\WXTTSSPQPQLLKKGFHGMRQYS]T^V^W]Z[f`jb|t  "k~vx!   ŹſżŸ ǵó~{}z|x|xsrrqnmmljiihfeba__[[WXWXTTSSPQOPHGIHNSRZT^U_W_X^YZa[rjvn늗ڕΠ   Ҧqr  窗    Ạ ǿĻ ˷ź~{~{}y|xtssronnmlkjigfcb``\\XYXYUUTTQRPQORPSTUYYYY]]a_ecgfljlkpoqprtrtvwswyyzz||}~~" "~~|x|xywxvrqqponjjfgbc_`]\ZZYVUTTQPSQTUVZZZZ^^b`fdhgmkmlrqsrsutvxyz~~~}y|xywxvsrqponjjghcd`a_^[[ZWVUURVWWXXY\]]^baedihkjpmqputvuwxxyx|¿¾}z}zzyyxtursnpmlhjgfcdb`]^\]ZYYXWXXYYZ]^^_cbfejilkqnrqvuxwyzyzz~~~{}z{zzyuvtuoqonjlhgdeca^_]^[ZZYZ\[]]_bcedihjiolqptswtyxzy{}~}~~~~}}|xywxsurtlpklgjffcbba__]][]\^^`cdfejikjpmrqutxuzy{z|~~}~~}yzxytvtvmqlmhkggdccb``__cbdceeiijjonqputvv{z|{}º¾|~{}x{x{svrrlpklhigheedddcedffjjkkporqvuww|{}|}¾|~|~y|x{twssmqlmjkhiffeeiiiijjpoqquuvv{z|{}||x|xytwssopnomllkiijjkkporrvvww{z}|}||y}xytwsspqnomllknmonpotsuu{z|{|~{}{}xywxtursqppopopoqputww|{}|}|~{}yzxyuvturqrqrqsrutwxxy}}~~}}|zyyxxvwusrtswvxyyz~~~~}{zzyywywvswtxwyz|}~{}z|x|xwtwtxwyz|}~{~{}y|x|~}~~}}~~¾¾¾¾¾¾¾¾~~¾~~|x}y~z~}~}~}~|{{z|x|x}y~}~}~|}{zzyywywzy{z~{~~|{{zxxwwwuxvyxzy}z~~~~~~~{zzywwvvrqrqtsuwxxy|y|~~}}|yyxxtustpoqprqtvwwx{y|}~}||{wwvvstqrlkmlnmprqsuwvy{}z~~~}}|xxwwssrrnomnlkmlnmoqqsuwvyz|z~~~}||{vvuurrpplmkleeffhgjljmoqqsuwvy{}z~~~~}}|xxwwrrqqmnlmhjgiddeegfhjilnpprtvvyz|y}~~}||{wwvvqqpplmklgifh__``cadeegikjmoqrtuwvx{||}~~~~~}}|xxwwrtqplmkjggffad`c]]__b`cddfhjilnpprtvuwz{{|}}~~~~}||{wwvvqspokljiffee`c_bZY[Z\\``aafeggllmnqqsswwxy}z}z~{~}~|{{zyyxxssrrmpllhide_a^`\^[]YXZY[[__``edffjjklppqqvvwx|y}z}z}~|}{zzywwvvrrpplokkghcd^`]_[]Z\USVTXW\[]^bacdghjjonpoutvv{w|x}y}¾|{{zxxwwtustnomnjkfhce^a\_[[UXTWTRUSWV[Z[\a`bcfgjjonpotsvv{w|x|x}{zzyvvuustqrlmklijegbd]`[^ZZTWSVPQQRTSUVVWZZ\\``cbgfhgnlnlopqput|w}z~z~}~}~}~|{{zvuutrqqpmmllgifeab`_\\[[VWUVTTSSOPPQSRTUUVYY[[__bafegfljmknopots|w|y}y~}~}~|}{zzyuttsqppollkkfhed`a_^[[ZZUVTUSSRRKKLLPOPRQRVUWX[\__dcedihjiklllqpytywzw{z~{~~|{{zxxwwrqqpnmmlhighceba]_\[WXVWTTSSOPNOJJKKNMOQPQUTWX[\]]cbdchgihjkkkpowrxvyvzy}z~~~~~~~{zzywwvvqppomllkghfgbda`\^[ZVWUVSSRRNOMNFFGGHIMNMNRRTTYXZZ^^__dcedihhgnlrprstsuwxxy|y|~~}}|yyxxtustmmllhigheddc_`^]ZZYVTTSSNOMNJKIJEEFFGHKLLMRRSSXWYY]]^^cbdchggfljpnqrrqtvwwx{y|}~}||{wwvvstqrllkkghfgdccb^_]\YYXUSSRRMNKLIJHI?@@ABCGGHHLLNOSSSSXWZZ^^__dccbgfljmnnmprqsuwvx{|z}~~}}|xxwwssrrnomnggffcdbc_`^]YYXUTUSRMNLJHHGGCDBC>??@ABFFGGKKMNRRRRWVYY]]]]cbbafeljmnnmoqqsuwvxz{z}~~}||{vvuurrpplmklffeebcab^_]\XXWTSTRQLMKIGGFFBCAB;;<<==AABBGFHHMMNOSSTTYXZYZ\\\``cdghhgjljlopqsuwvx{|z}~~}}|xxwwrrqqmnlmhjgiaa``]^\]ZYYXVUQRNOJKFHEDBBAA?>>=::;;<<@@AAFEGGKKMNRRSSXWYXY[[[__bcfggfhjiknoprtvvxz{y|~}||{wwvvqqpplmklgifh``__\][\YXXWUTPQMNIJEGDCAA@@>==<455678<<==AABBGFHHLLNORRSRTUUVZZ]\b`cadeefijjloprtuwvx{||}~~~~~}}|xxwwrtqplmkjggffad`c\\[[WXVWTUSRONKJHHCDAB@A==<<8978344567;;<<@@AAFEGGKKLMQQRQSTUVZZ[Za_b`cddehiiknoprtvuwz{{|}}~~~~}||{wwvvqspokljiffee`c_b[[ZZVWUVSTRQNMJIGGBC@A?@<<;;78671032435778<<==AABCGGHIMNMNRRRSWVXW\[\[`_aafeggllmnqqsswwxx}y}y~}~}~|{{zyyxxssrrmpllhide_a^`\^[]VWUVTTSSNQMMHIGFBCA?==<<786745340/10324667;;<<@@ABFFGHKLLMRRQRVUWV[Z[Z_^``edffjjklppqqvvww|x}y}|}~|}{zzywwvvrrpplokkghcd^`]_[]Z\UVTUSSRRMPKKGHFEAB@><<;;67563423--..1/3434789:>=>?BCDEIHJINMNOSSSRXUXW\[]\b`cdghjjonpoutvu{v|w}z}|{{zxxwwtustnomnjkfhce^a\_[[UXTWTTSSOPNOJLIHCEBA?@><89784534100/,,--0.12236789=<=>ABCDHGIHMLMNRRRQWTWV[Z[Za_bcfgjjonpotsvu{v|w|y}{zzyvvuustqrlmklijegbd]`[^ZZTWSVSSRRNOMNIKHGBDA@>?=;786734230//.%%&&((),+,00226678<<=>ABBCGGFGLKNOSSTSUVVWZZ\\``cbgfhgnlnlopqput|w}z~z~}~}~}~|{{zvuutrqqpmmllgifeab`_\\[[VWUVTTSSKLJKHHGGBEAA=><;7:662310,-+,')&($$%%''(+*+//115567;;<=@AABFFEFJIMNRRSRTUUVYY[[__bafegfljmknopots|w|y}y~}~}~|}{zzyuttsqppollkkfhed`a_^[[ZZUVTUSSRRJKIJGGFFAD@@<=;:695512/.+,*+&(%'""##%$&('),--.2134789;>??@CDBCGGJINMPOPRQRVUWX[\__dcedihjiklllqpyvyxzy{z~{~~|{{zxxwwrqqpnmmlhighceba]_\[WXVWTTSSOPNOHHGGDECD?A>=8:764531-.,-')&(%%$$!!""$#%'&(+,,-1023678:=>>?BCABFFIHMLNMOQPQUTWX[\]]cbdchgihjkkkpowtxwyxzy}z~~~~~~~{zzywwvvqppomllkghfgbda`\^[ZVWUVSSRRNOMNGGFFCDBC>@=<7965341/,-+,&(%'$$####$$((**/.//4456::;;ABDEIHHIMNMNRRTTYXZZ^^__dcedihhgnlrprstsuwxxy|y|~~}}|yyxxtustmmllhigheddc_`^]ZZYVTTSSNOMNJKIJBCAB?@>?;<:9763201+.'*&&$$## ! ""##'')).-..224599::;><=@ACDHGGHKLLMRRSSXWYY]]^^cbdchggfljpnqrrqtvwwx{y|}~}||{wwvvstqrllkkghfgdccb^_]\YYXUSSRRMNKLIJHIAB@A>?=>:;986521/0*-&)%%##"" #"$$(()*..//44445878<<>?BCBCGGHHLLNOSSSSXWZZ^^__dccbgfljmnnmprqsuwvy{}z~~~}}|xxwwssrrnomnggffcdbc_`^]YYXUTUSRMNLJHHGGCDBC==<<8978554410,-)*%&"#!""!##''()--..22334767;;=>ABABFFGGKKMNRRRRWVYY]]]]cbbafeljmnnmoqqsuwvyz|z~~~}||{vvuurrpplmklffeebcab^_]\XXWTSTRQLMKIGGFFBCAB<<;;786744330/+,()$%!" !!"$$((**/./.0122669:>===AABBGFHHMMNOSSTTYXZYZ\\\``cdghhgjljmoqqsuwvy{}z~~~~}}|xxwwrrqqmnlmhjgiaa``]^\]ZYYXVUQRNOJKFHEDBBAA?>>=7:664332.0-/'*&&"$!  !##'')).-.-/0115589=<<<@@AAFEGGKKMNRRSSXWYXY[[[__bcfggfhjilnpprtvvyz|y}~~}||{wwvvqqpplmklgifh``__\][\YXXWUTPQMNIJEGDCAA@@>==<69553210-/,.&)%%!#   #"$$(())*-+,00347878<<==AABBGFHHLLNORRSRTUUVZZ]^bacadeegikjmoqrtuwvx{||}~~~~~}}|xxwwrtqplmkjggffad`c\\[[WXVWTUSRONKJHHCDAB@A==<<89782211-.,-'*&&"$!  "!##''((),*+//236767;;<<@@AAFEGGKKLMQQRQSTUVZZ[\a`b`cddfhjilnpprtvuwz{{|}}~~~~}||{wwvvqspokljiffee`c_b[[ZZVWUVSTRQNMJIGGBC@A?@<<;;786711//,-+,&)%%!#   ##%$&(((),1/34435778<<==AABCGGHIMNMNRRRSWVXW\[\\``aafeggllmnqqsswwxy}z}z~{~}~|{{zyyxxssrrmpllhide_a^`\^[]VWUVTTSSNQMMHIGFBCA?==<<78674534,-+,')&($$##!   ""$#%'''(+0.12324667;;<<@@ABFFGHKLLMRRQRVUWV[Z[[__``edffjjklppqqvvwx|y}z}z}~|}{zzywwvvrrpplokkghcd^`]_[]Z\UVTUSSRRMPKKGHFEAB@><<;;67563423+,*+&(%'##""     !$$$$((+,0/1/3434789:>=>?BCDEIHJINMNOSSSRXUXW\[]^bacdghjjonpoutvv{w|x}y}|{{zxxwwtustnomnjkfhce^a\_[[UXTWTTSSOPNOJLIHCEBA?@><89784534100/')&(%%$$ "    ####''*+/.0.12236789=<=>ABCDHGIHMLMNRRRQWTWV[Z[\a`bcfgjjonpotsvv{w|x|x}{zzyvvuustqrlmklijegbd]`[^ZZTWSVSSRRNOMNIKHGBDA@>?=;786734230//.&(%'$$##!   xmlgraphics-commons-2.6/test/images/bgimg300dpi.jpg0100644 0000000 0000000 00000012044 13777276623 021062 0ustar000000000 0000000 JFIF,,C     C   " }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?[^VŭN(k⿏s3 [^V1kkӊl>.-mzqZEE\DG>E%Y:#:اL#PSvqՈ8%v| W:$uU䎜UJf{W:В:\SN #~H #).0S9^V=կ^+d]Zg>C5-mzqZZVN+0s0Pk[qSuf8:8ӄf0:B%Ou V#("TDqՔOλ!ѧL$u]Ҵ?:$t #GZ^Hp8*S3*քwJ:p(IWtGPIqN8wnz]S ֢&$rWVuk׊뮭zYV9)kkӊ׷(*%}<(*qu9*=vg dU䒜:I*\S`i$I*z>@wIDUy$90Jއz$9I%A$I%Vw)T([\G&kk܌rkˣYI.k%NYέ0?CV8L!3AJIfa3ЄjVb7 Li4#z=eǾŨx_,%[u^GkA` !X턛vGNM#GYɐ9]NfI*IUPsҜT+U$s<ޫI%IU䒸3ΜI*z괒WpNa$Q$Y޸3ϩPEYW]y2nSbQkus\oW_|!g|WR$a"KO.DԐq'VQj۵kg౒5R-R5i5Ϗ>'~ ~=xkZvW0ƾ`R<A}CQ|TmXyCqg"Gs?YĘ;f&%v/w,&~"K|yi^#'ŋtd0M"LCSj# !r|yWsj^#t 6( !M ѐʅW!W^i9Zֿ]w+u,:SsTro5]_m49/_g4_d'> _'Ԣ'7_R]baQ0fkݿ`ό>&߁I_}>Iy6J Id]I$D dA ˟t%|['D}|NmĿ#=Yehx7~Ly{cO5f9wQ=rxyo`<{چoAVSo- YIPgc}4/[3'K3os{n\\Yh&9;.[TJz"p񢨪[[g6Ŗ[j:u}+qowk )e R | _ |7X?mW^}ni.o5x%K"?tǞο&uv϶ѵثcr['pI6oҮ8USJ(V7uޫI%IU䒼I$wޫI%qNgIPI%IUs<ީ\m\\muuך+V=?j߀>>BмQI']'sG@]ٶȎt _L?>/]V-Ftn" V5nX\_@k\澂YPpqJfw۟Q,2c&w_o'ƏX֭FVh=*3<'"$AˣUƯQwX-NIh=;' .]"*ɚG1k[v65콟*yr^˟_~]}?k8KrVCayw#$I\1;Uƾ?!?ioZ-V;H<ͱO$1bŶ.VQ붆cRbSqٵaZcŸڻK_Q&4?KOd_<' i>ڎc` [V'3,Y~9[WgG\G7˻>^>s1]g»so zU/󼘖=rvnq5CtloUC 2ݚZFz'x6CPE4ϸ"P~D,7yi?v g? ]VEog [۠m;(qsNE}G$^I+x8/;9S7_I*z괒W94IPI%IUs<ީ\m\\muuך+V<|F!E^k"拫gȺ|#|+W]yuuךǺ|#|+xmlgraphics-commons-2.6/test/images/bgimg72dpi.gif0100644 0000000 0000000 00000046363 13777276623 021010 0ustar000000000 0000000 GIF89aʎҵ]m줕ۜ8FYenw|w듟KTQW߹Z]gkkox|⦽  !00@?GGNMTTYZ^^cbgfllpqtsww|{~勉)'97qnmk셒ဎ퓦ҒHA}vrn:*jbunz`S䗷詮͕{퇩ӝ!,e)TRt*0Yx",Y2fѢ .^|1dRIJS'3fP!SJ1Æ#"xF[bOIi4ft9\cewzx=#bVPctdA)4$Q$ayHFK_iCuRɱJ Y{ZgW!t| [Z"vΘh嗩䕇^2^BI&AtPfğUfBҪbz(K]*7Ik뭹fr7T 7$7"sTY;V[^I(x^PGdaAqꞒiv_~K%ҡ"/Jm&ǮkU} BL51+!vWrhYhM{S/]ݸW]`.zn.gvAI:ܩ\ U %d͋dEPi )v58!fAu HBDB(.j%G"WN>T &yj\\`u4 f_ =78  8 ;{d rߞ|X=4P]rļTrG2ϸz'*Z]3F@SJ҄;%AMj6.FVI3cXlā Ҏ(.v`XVɁBp9k,qD5T&]Ž4-A$|T$u)pLT(QД, 6ьUf& !,鉛{.ōwUrI>1-paCd bŠm9sD':&8-ځn"mbIiIUgHz4Reb5T BaЁ:[TЫ2)&V}EdؙfJhd 0qb69-Hd_([TjaWtn<@.tX\sŊ¨,dbD[g[gϊl,AIlb3RYkTJ #!gTW-q4+mu{BJ0AB}. ^,WL5Db*XAPQt-|*eD/ߺ$&;@PY0X 񝰡9Sqpc4ptW:fYW2e+QV_X@`dK/(`Wb0֛i%FTaبF@L^!*1ҁbWΪ8V P2¸ɼD9w v@t>ZL4B>l8YbE/~A_ ft#Gݲ0g'6Hf5o3nJyn*E.dI :мk{--pEȽvǻ" ^tZu qoF;AjnG<ݙ$J=N/`a=5%C% dE" н^*gػO,2 D~E w̋Zݭ.EAqAyE/.rd$9c(4k-kcdlݧt '~g~PlLdP&CVi}`CaebHH7VhD+R-ETE"1ygScAwFbvGQHmFztGpׁ Z8~!(y\GzG}HBiLe'Hiq;b$EAJJ,JfK(s`K7vFKwd h ৅Z\H~zTLePCLt"8:qDj#(ФQ5;D=MO.`N^t[CNNO?Sd0NOAOrOu\Iw7wAAp]xwYsPRUPH{YgAxՑQqH"jg5@Z/5_2S5SҲSfSS70tT`(wX9~獫glTO1UUWE";4٥"2oQRD16%vx[[ r"0`Xu5ȅTIFl~B ؘ|~WYvYf(:;2[ofW:9\w#6rb{Sb/I7?<}ryew&`ӗzKzKw+ 𭍀 Ālj€@wI3:z{u_G|2s{b<[v>OgN;8yɱJKP ;е@j_\>?8#Ӓ?Q7Dsˇ9AB}kkqB3SBCxV뱑K00pKƠOh5:9@8(f:EG F(vIKK4jPokXψG}Y ۼ{ мY;?]FGyG}:4itHlxgpQsX;Cz%FĀ!hKsXKK`[{yȅ^VP{hL(i諬]jNqo 85 Ryd/ ;WziT{: ΫȍchLlP eU5%V-9$Sxc84a:>/\JF) ɣJ ۼt\ [kj Ȫw`UAU\i%Y\5qQVHVN괞 x}WKAYXjB)IYnXy˼KʰlL!>S j͕%̀w]`ȍܙ\ţj7 {5ou4—Gvl|m,ʑ8 7U m'C]aU(֚ DcNfs`Iy뱔[ R=կ<,@ɜa;FFWq:6 ̏f8nҞ:m&d!?Yd雿ÉHS-lճZhS&-HXi!f-<dҢk~f5d7J۸㜪lΉ ۱ =!ۣ wJHʽFYLPiC2\*k `jidkokY3H t t<Ľv*:ȧ&imLնiڊFbdd kB-n'޷*ئ ۔΋LM Rmڪd;)]rtعZVmmtpm50azk"5WtsJp :qڣ]Őv$Lp-ܔ*ԋ캠CWCk1)tJ4BKFdcưRvV9:-X{- ۠ `ɀM%`+e/13˫7ڧ/ :J\ȴmR8|؊ߌ. N閮 Ø{`AgJ9Lw綻|ӷ= >cK}}k-ՎPN%U▋[˝~~,Cn gB CWꍼ] . @= k'*Ȃ8pH rJH?քTzSοx+| \p> `? +_]~tɮ雎ܹ\,\eزl>̵A9鉄,L: ĨqL*J{OmTMƍsR~O hǁ H>|LQɯqD$eʚ0I02d-YR1b=zԨ#-$E Exҥk׮[ 5KPWGO7n̙ʨ8pĩѴ7BUWJ WSq1jPVr3g @;vQ+S,0aA9$bH(QB1H1iI4w,sMH1ڴaĆͣ!7eʖ/_Uf@;{C(Q:t&]6mRMj\1ej,ٲgo%޶ON@qֵR^E|\GĊ;,eI0۬< D#**f5bZ6f^ncɥpŷt≸sHjROB!9TQŬ9<`ˏrDj z_+# "1sD n (8fIJH3%l"U˨#@Fl0f0Xˉ'?;8qT :>jgsM")'%'oR){J,0#$\129Me.[s7;FO(J Beda 66EkaQ{cJ(8PEFI)JG t^h Djiݼxʿ #f?"s;1cjNl%{1oզi$``XnN8?Zie:8ڷ_OF ~;WS:`E֝N. /0dA ̼3iQNy8[΄dNfД6\g)xDSTJ7r1SKG7 fUF2%! WuAJ`!0Fhd-7xPRp A @q0G'a$U>*ęW.MAXZB!͂.ѢMɭJX _x]^:1OS PT_%EQ=TI)wMCBn+\bmQүb+1.~Kjq|zMG.r8 j'[}j.tZj׻~Z^_3{nQ.K_GP[%Pj\`/O2f٪pMg|ILp(LK6 Vb1UR;n6Qʬon|Ao(*yzG[eCxr[_ε.a[X G]a+üY,̢7>>ϓ#[`jIZ9I{Bp"{)JWX•Ҳ ߑ z0ӏ ڠfi SS8L@k 9ssX[y!rrˡX  &%r0R2,T {C#7?\@7kA>;>z/rDH9ʩ )!218vR xj˜z:|'K6 (5ˬ6<+B?LYңcA{]//ԜyqDO0 #smAK 14kJ$Mu\@3tT/˳1ȱ?L!2м,K_3l(118LU,ǏSC<,uH8|(DN*t?~4/DY'J2L2M{8k㓬P6iȿKDW,O\OLσ5dZ$\ӵ ?_GOg[K2k6AmjyPr 5 L"MO<ݴw4!uԀ7]۵zɷ4ɕq-0!0 09#dM81Q:4L 5O u#vt%,;ѳ3nAP?cI]K HB Ju .?0. 2G@̮2K6 7TD M>%:YBER K-|TԻt*[1܁ :\oLUU<$ J:r\[ƀ7>c)!F]xԚ yi ZCILKi֑25]S5ڛ7XU"9|X=R@LsՅ m \+LװTB~݁ziJjp2ގ8T]Th%pa G He]@en1b*K T3]oeS1F׌o>Z>UyToЙgTKced` m⎤Hn]blUZmkno aÎwuVz/l}W]O;0Ύ'#9P-ظFXeVxؤ=܉V,TXPu\ ݖu@DGi٫gJ2IȽCw#Ѣumfr4S%hU> Dobٸ H3s#Ojs#:^߽] \5\ą,uahܣ\PV;ht] 4T]@ƻI-Án%Oњx"^0Vd2QX<%U}Z2N[ţ^_` ^amg~/i 6_q@"nZ)*8prEZxޝ.u0_EՐaB?*0_~Aj yCI.':Sȟ @Np׉bD*FmG-VY cq$yc@Ec?^bk&ꟕr"(pjJN^SPޥCc‘^c|>Y?&@"ABl&"Uy"CJdfeCf)hgkLj^h'UlXo@+v]el_&`Tȁ7 I D*DhР@sܸÊU+?~|JYj*Th.]T"0`1bHHGBi+Zؒ%"!Ci2eRIr2iݠ@knY<:U&P-]zTb A†Q„ ,篚b޺RLg:uɘ 86 1M+"4ueiU5A;T,LRɹ5Z-Sɶm;*Vnar +[I2_mRHB W^yu!;bXdwH6YFP)0DkD8 iqQvxH}R,+Ղ-0$MpBdC$DisTRK5sIUUOhEaYA^xqU^y{nbH~$֟d iF =>R eXHZ58 ɔ"SȌ5Ǵr>JRdieu}*U/+i('Ƅęƃh ̡A6`:S76t LA8eSWZZsYvʐrM"6^`]x fc~ rQFx;'׮Fwst" Rb-*M74B!]ciQ5{l'0y;j\rVEzU7?>r`Y2\І }4'\84|of":g9hF u"cQQn7(n%)QלpJUP9;/Q^abp*=Fw@zKĸzPaX Qn[㋡HfOL>C/7cZ'uDH^SgwI UiY0V܌_KYuph(2B,A*4C':qL%nr"HC8rC QjK(R.hr:  ]{CSMLFZEP`8%[%na ^!OKp)&<쒃qLsq{h㖞bXj~s#Z+4ETiL|1XJnb ^!xϔT{z:!vNmFi9F[H0~ P]W]Hg^ N,6walZWM1dM@%'+ZrYز3E>2I"D)jÈ*W˜T/=kh ;2;: `P$E!YHP;r7ags6\JD鮗6uvAһ%\<oQc)7Qy{w]du^я>0Qz2M&g9gV;w5!/ KR(5 OL1=OEQ V{ڝ۝U!U D ] oTpң1(P4^TZ cah%eal7vɁV[K:;%pLc<Z{DAADp#eKVFN2&^0UN}tIe}ȅcW쑜[A!c쪾mgb ]KډYlMB  %8K@yjP4!cQcdžefm&Q+`z+kުdA;c ڥV3!jI!ݜ u؁P-܂,%UƋSF݅ 0}I^Bձ$ X/M T ڬj l3 .ᖁArO 2.A@ܡU(m+H"/j+,ŀeLxNXf\ɜ ع)1ʼn灡Z +:lޮl tN/Hj48( P @C9<B;$H)،4CD/x#   @T6A/@J/A5\AIR_B溡&ū;zi,:°p@oR^*3$0Wo4@3̀;)B@9HX B" T" :@?IS "`0jex8~j#;@ kͲ0d`$,v$%_'C@%C<<`NDCn8 F&UaTiOI JVTbTj#"߫ U6&v l\o<3ACB()`S m J3NR[5~z (H 87߀+*.FʀiAD/ "\~jq; ‚ O6 Y‚FwPQASXAhXcBdj' ZEA 3 C %P9*3p3x&D4ՃVna`,SM3GDSO%ç` *z7YAs2I%߬)*FB6¢: x@Nx<8A 2*ri='R|yBFkĖ#;lvXD4 R5|A$oV\%<V A a3Q#ZL4 <?(|@@g:@TRF$Y* BZTtPml`CøMpnUR ӌOoA(& jՋd$|D%#ɟ0Ql P XM֑ 1 4`-qHP+K"*px4>!ئg=&ЁAb8T64C'NC**dEYFd,89 e4iA>ǒ@^ QUxJ8 b)Շ h>9D!+!~bQ ]0V9` 6Dπo뛢ZӐUmLqn\<#W ($GZ2c @Ќqa AGR5o 0& yS /`Q)@0쁏9 ґ9D%{ 1FBw=)RnoZ>n DhS謐.Z^ %\je`) $a} K<*VX AJ rx[Q@j<>pinyp[V0R[UR=؆2S O4SkœyUniNNfuI#\ uG RR89\`Ќf 9ĉxH ɹ=F*)F7L~oAXEkPP7[{슻on^pU_Xr {nA M*C)e?$5f TF ?o2# #XFw;w<5P~fP5πQb zW=*UÞdo DB`gخBb5Enlgp$-myфGa2໰6 О ` G Db&-rԊ:p֐Ҩ FGa$aɘV",ݼ bPUĀ;! P! o p0 o `>l2 fلa*}~Pn- ;xmlgraphics-commons-2.6/test/images/big-image.png0100644 0000000 0000000 00000077663 13777276623 020724 0ustar000000000 0000000 PNG  IHDRE0PLTE))399GDDUVVkyyiiԹ: pHYs&? tEXtComment* IDATx邢FKA`Xv$եڲ,vtp-?w_}?An( Yn3N <% \% \% \% \% \% \% \% \% \% \% \% \% \% \% \% \% \% \% \% \% \% \% \% \% \% \% \% \% \% \% \% \% \% \% \% \% \% \% \B׶1}Z!]!xE͗/ 1{_Q㓮O /x(.&/W/TNc凷Pd{]t7g:L?]Uowr8ӯOv6p(^~=_[.Yw~7r:,\xדr~G7_C{?|na"FG嫯|,p|7ZX8M_wu=Q8~J_ȭZΙu9{r?ٓnxx*mi.شo9_CuKFn}^s,fpFpY"/P5m}=j{\TV-nq[5m󮆟p9LRXd(Ou/>|u~s}/wkXsW_Wwwo|Jn|+KPȭǣCwqwg};.G91(P^uW=kWo3XyzOן}E7w=!)5fL?VnkV}b[Lh鯿rRܺǯz,Kl]w?yŪQv}ݭcOpZǿup(^t:*#釗kҝmw|W?uݾuY\ kw8W.wk _?ʭ~X:YH]νwrb!6ܪX6w;}Buhb5ʱ=6N/[\΢Ǽ?h rlRtXժxl^q?(/QfGtDyjLlB6: .ܲsk|7VҤkM7F/k-5Uwy'q]~9:^n3Yurk.4ɭ)͇FnKwƥtm]~ĖF7wSoglb:A_Jn r@W8,.;\Lkdz?ӝ<-:d A(x௅Yn|By{a7CvZ~?\;|pΆ?n\ e{.Nl`Η{ ߯1 'g8C_.b"1v#'_z~ɆKVnmc%\oI3r:]fVr?8dzo^,|e^msVuvX}i֬-TTBkr.Ag%;_28ZnSu\7];YQnq @hvĝKB<ԍbP ^e.gP=~8.N:y˷ՇmybpM1WoAetuy7]y9,z>?5M5DUwC1p2R銽k[EnVԀڨݝ> ?ŵmE:҇as}W#nkBYncĶ=k- u2r<)Lj-ptP~Mq콪"u78FY|N\W;ﲍ?8^7mh_4Ur(~.`x/3U9?֗Jns1;cb{/nm/f%euSϯN_LEk5K21ͺZ\zkhVsjxhc/;'P_r[dXXVtm§{uWr[6{,bw]fp.ݎ<Կ6n_7Dkifgg~|.ts=4|[O{ysVnuUv`N!i][M7<6⯲)ib,n ܦc:L?quuMu SiN9}68#1<ʛ6Jnt@C[r+63Nf_lh|SWr@>^r;\͗!>Ui@^_%@}H6Vq5?]GrX~ܖ r])an[U[˿jc@;?Q+LOXp9/i.gտ䶼n#07iWWuzqƅ@Ǣc:N?1}]bW񸹪p*=Ư9ӕlz󷺽s;R]VN>al>Ձ"[? Ǒ[~un#zJKӇp_n|D{r3vZ7Uny{NWW_Dnko7a8Ìl%溠7M4Oj[;vŬ9z^nuYHDnrО6r돳 cQ$[W+onlWrv(>nNGrܪ'[\Cw#uzUӼ(ʽ)eb6Bڛѐ[IܫemTpvYW{;Ϊ[<.wj:ţܺb*jMpgknh(GV]ܖSxH,ծS8՝՛n%)Y3-p&SnKuIm!6͒ 3[GaK7o\W f'v;˱횗wr1simUsBNiiX}~LVϛbWB9̈́^K~g6~)p^X7.WKmAijExU^mCji:q@<}VΟ]|Z#&r:m.sna;%1H[lGgKF̩-r^[w7r>Wy,yso^q:UX׽#6~js366Wr Q Ko66GmLZᏇ񄺭OSӔ.?i\ٰ1%iFnV,v%tSqBaҰgt5SOy#y&tyLjY79?\j°vff[q}ܗ(߭}r۾vLzc>S/tCh.nwu_\udz[hN+xm–>2|gknqXu ,.z[5RuC\nZ*8n~#>.qMz<} ]NqB/UnMeFn"mS7h ?idy@;]umpffyS~(ý)Ynffڻrg->n9}icaoh͆ÎI҄ʌ6,/+1rMCayyZRkߟ& quy97Ɔ]A9V|1p,#cO;Q{rN#H_)Mr0+?6ya g;Q(6"u_ւՍ+s_ݾ(vs[(X꫾ɸyI>]گ,׍G#2^:a3(镾JrBԝ#z[F* -+ ^23x$(ej=vC{P|![2)ܞb{[* P.$&̉RCiÂ# ?i!ݏz!U| r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7p r 7ڶi꺼Pmm>P- Ȭ/+Nyv<pөʺiq Ϟٷ"s.R+Sv|igAn{ov8,NwyO{c^8>rmsI?d!gO B!&Tm wꖚ5mOtMYdl, IDAT"R{(P r m(Z;fKg黦,wשkJ` Pw AnNv pHኒ, rsK[n6%4Wp.GID^n#+jB 7o\v틋$µᎧR!'n#!^KApW#_Жb;AYA ^ {sVyA>U%rn^2Ҧ qWY60wW ![\̶ lkrgr/op r)t4_{|HVLf[U-@k.v=f= rKt.`I-Ť#\S POh *|MUg<4CsVշw 7%yUVF rӡ*jFb}#3M% 5Kv@oItG( 79 z#KBo{R;u>fR# frQCfj}vr3b^@n&,j|YPs0P0Mi2fâ7wr4<s*r,43ѶanRkC}9nȸU `|>\9ʖyқcǘ,)}jb A5An+PcPzs r5"sgқKN -R57 fH~$Jo@nT!Qo+O3R]& {PF/hwaM nC~@nŴDJuL)-m? ?b HaM Ba϶l9GoUr*Ii0 C~.TM>=a oHH La | a\aP m~7, r{adAn?yc ޘI<2ol& ՘p8ZC 3YC.kS:]R+$ r%c]yOL9ij 1e+QۯsiTq)v}F})~}HMLMJ'HMTe&% SjJ 5-qvGҊY* sR}מ*R}B _vXje&$ۏ'@XlO&9+An?e0W7u)IKXrcɅzT]S&rDZ&AnSsq1VtAnOCVP~=x.)LH,9, ,đG 7K52bo.l AnO@q0b T! ½^UTU"@n3VcbӔ~[ӖI&NIw0O1l r)$HHa}= OS՟!mvȊfi3;Dp>{5`rcO!U1D}&)YY-ɑ1}5Hw8q}T!v-py޵*=$6q-uZgom._B#wzzNPCRc5 ]%mIP8Jbw++8|䲁k[]UyL_ .H=[ps8X7+OdGq({׻h2T'*S;8[PdrYVn8l+Ns)%lWzC><]6]!K^%|>w¸إo϶8,D28ǂ&{[,뺉zR[ >O{5ke Cjȯ,B}V!icgrR'w0Е4B@ٟ ?%rߥxaw76;^U$= <#@ z7yi.jq~i.2> LnADɯ.)iٷ[^ZKn>ΩA%ͽ[6[] 9~|x 2[~Q5ɨΞnIwOecP8H#ّb#!ݱ||> GnɟKqO3-Gng4NUu0ttD-m;!MV1ىOJy"6"MAn\=&zDn~n]m>;[wȩtBN[YL:PgrKɗՒf`['{j ciaɧ$s"ݤB=ȭOu$y~&b|K؃-M4ӭ3XM);[iHmh\O/4 n협fџ%ܔ^nX$4L/eR+aYS˧]]nMz)lK->Pv1oƹ®2iuj[z#jeZ_h&$0)jm#Gy<%xǷHJol Rsk} ? T)kV9I|YnMPm{̃r+*ҦX*%eXc52mD.it֩U+>t%D3 &3{J/_))Uba",\/΃$r VnMB3cJJvƝRdS:iR E:)Ix[B勱KN[7-ơ4RӴ 8[: KON/O4bp4>vJe;.a $oRL*aJ6<JRڥTN>tL߅Gi$cȐB7>)&m-I8uЗQ$XrK\"2@"F}-l,4`ID[!̡Ln,ڢ`Gm<:ۤ,mX᱔Q+>OѮzV~+?IĶۯ$7mNʑQ#_cQǓGb2$^ ccG@/q$RdmZD F)5IGnaQTUR-3gqȭk&GnPhy7r sA!-׽vҊ'⸑[.}vz$F/r %DdֱN8ڄR~`vҕq"7s)m78>wյ MNn 'r3M4X,IʭQ~ ^o+ej%YZ nJw["۳(7ކ\-tҹZ IQn'AF WqI[+zXE-0Ȓ7 @꟤'5-v_ ?IOnmK"[d*v Za7שe/$'Rv% m*Nyep.OEUM+ ΕbugQRؐOyIi6eqv'p̋v+9[K R[-5OywоԮ9f "IRԗf, ־SܩfPILn$&7p<u,ʺiM]eUyv/ttLb*V$1IRCRe Vj٩*][W2YG U IKnR-pGIiS]혿=x]\Rԥ JZr]9IJ\ٯewvy]@+1-MԊaIiWk y;jƚYmTb IME )6mw,SI˩'}sZlm"+u/)m/GJrSI<)mWuC ;Y2M*1̈́E&TBM:)˥7zX']udɦJ2kAR;ᤴ-+}^VK߅RbtAH܄nT&}lTcR&! 4nfsgN~;D :"I:rjI&]5MRYI6F@'+܆#뉓ts>,5=5gá$#p8 Ye*vuH#b\B)=-HFn:JCCҞ|TPؕ$IFn:Jun1Gmze"L4׮G*ri'$MYmBi7W3cz B#z"BX7>*-0M) ꑈt*IuL^maV4tz : MR7'O;1NOA&$ɔdnd.%QJhz :h=ҐLS(n”%ӆi:=L%# U"E>n”S:W-SLO! &-$&*`*ainzE±pT=[+bB."9tc |d?d*FB1|۬GrSY3?tw:G?(L?gMHo)ԁC֋oe0U17 ; hBʑj[ʭ;&3$P|B*C$z0 fO 8+-vis䖙[VAGՍQI5g3ۛPhڎLQ[8)kq{'Y7Uz$'7B}-,N&_`x0 f{]/S}DmL+,%p{+LMk I IDATf:Dkh3mymC`-ٶ̏yn۟2Z-5s:<ŷ,bLys qCi>m:Ζnbr+x aqޫI%7W%7V^@t뇛 %7q Vy3%Lq e Ht+;s |/Kf,5Q_0].]*%7p֏O謓(D2x1=hJFgBe>qK4`uLKl%R0㲺TJnO'mzR%[q(R |fE}&sfZ$0ިݔ+aatՋu%w @7l!L+~3^%(N{?Q7Ӫ{CInGx{']{Kc:ݷ\&Y%Y@'wMY‘1;Uu+~!e)z%Y[I[ծȊZXpƏk4m}DInms鬴OGbWFʦtkf'MNiЏhNwBÝ?*7`[X{DHn{'|@WcPckb+a*WXԶ7˔`m8 j%iױ ߔz%rR@Hn@2+YS}P7erzmXN>L!YVlW+cQ[V>ݥ6%ڶlVeoǶYMu(/Dve6-:LJVsw7FHn}%fik͸Gڌz;Hm GHnKܶYj}uz[.$L rFБeYzQOm>o-˹;tӑ[kڱFjn:^ю2L?`sk;rI`L5US+1TޔihKw,fk8`6oފiQӲȭ2<Ӯ+Xn;!hBSѪ3]nyrYzБaӴYڛavKhM ӂO,謽oM%Wntw]2ƴ4Rrkx)To C,w*R4@GnKEJH- N,Ӳ*efANh,woDٿ;I7 ИrL+C>1շ -(gܬ"(RWC yaZ4,XW##7ʄeUbLTПď2j92r3)63H  Ѹ 7,^u#qb>Sw,!{dfY-EN;WqXf;o##7~唥 ~z3K̲oc^%#7„eKɾ0l',CÇP{ 1,lL3Jb[?:M-ç]`ӼW" ѡmm9h(V1{dfx.2}=4Z'خ"7‡W͟ ^}(a"eOeii]/.Uac=Y7K?q7;no,ۥQͰ^훥W2L-ۥ2rQ~fߖa<~nF# /3˥ )WΫ0 qkYnRîWΫpg, O}; oE]STf%/3{2M| 7"7C^q\0κ> [VDInk(VDLg /sîˬ"7C9Nd~C11PG*r3,u~k>m i[c%]kM+Y} rq2>= v߾vnydtz>CE.j6&&#Jrݶ |vsW^mv^b~r30،fSh4Anyr?ǔ䶷Mi sg2|hpa"°qhw/j< ԮEFvgxz C6l_l"r3,_ Ù×6+Ommzå1;|ᬾq#}r3hVfq./f\g6*אּMcQ͙g aϾi,_ _?U˦mn: 90$I ]/YC < TQ?i= gr`mr—},oeʊ܎ o$l# n!$#,A0FM(ٰel\%ahX VV;ad߲Ro/%7wY޹#*r3 w: s}qZb܌ Fs}C6FTmR-(kijػ14f7]~2?囵g4! m; '垊nG-0h/{~.b|;)}nbR-|+ /mꗡb"鳄ffaC֓M'"2r3>~!q4E2=#7Á}|waeay~qRl7ohYڴ\ bH2r34etv'yic:bY|2,o#7 ,΂%/J-몆Ksӑ-nz4+5M W_N9- !7[k7>EcymVj$O ]䥶YetFFneW": v 2N df|&c{+nR07#2rY?Ű4O#5oѲYjXX7#7, K]?3]Wj,5< Ͱjٲ|ټ r{G($KKf2s> -h܏԰!THnK-cyKV|~nR!Lb= b"\bٱT UGniڸ`-恩EnyӶ>cАekY1(ĢgKrf[5ݼ`W[],吶e̺2#7m.[S `QX5\-V_ rٴi}Bem?33}HaKa,y_of o:r>{ 6}ajh=}t!1쥽4eUߴcGa>on3nge3}>%1Kvmf:k:cdς,[~"(iV,l7 a}$Pa[6K%fxf*vZ y'!N,W͛6K-$7K@'3@eR JritېPum)l f9c;Q_&B-]VR17)Yv~yy*[goS&/,5mJI2Q-3!ܱ? I"VM [Ujmi1h8X6iV(4z t t>Sa[I,Hf:l۾0N!-j?ₔ,;/W`RЍmߋiFJn;^$z13a^O ) n,MLnC*and HDvU\nIm4}UrI㯯#smt"Rr3M "yؗ_ b,#nU[p vZ(7ێGcO%aR{3ԶW(7zۣswi /bjx(>u˪m_q!pA=LEަbi3_(5c~:ێGg{17=>r"w+flmC%I:}W>xNSh܌7RyezӋ&l>ykVlPJSlTzDTv!JOi6m !nPCDMyD3+ K'道@fM:E /M#t;÷8jKP܌VIEY yi"yǯ}շʦz+(nY:$f=E iK]튷Nrk0{ܬ@X>/|˪86/Y?* Ådu!5+*7$P6Ю·C^"S?Df]-zdi@Rn;w<4Lu.?/tnO+n}~u6h:wX[Yix}`ܬw4κ g[=EV 旵hR rt%v5*ʾWMb;O187< '_)7c/kb{ֲS^ عUj,+7QgM*ҷg78Y qwTU)?MkYVnE/%ф{+}u}> ֶ![n\Cw$֥k"*7(BXhvh$4ܭ\MVnE7SeDʁ4"۱\MVnEd a^G nJnr3/i:S>z]`MVnE^aߣ4+=:q#+ͺ,-Tj:p:`8Z%z%7]Y//'N*7;•c^E[Xzy| z t,ͼfyFf |3;=܄f^ `)A']Е|b(q3jjAWnں1s=>0ϳ!,7,>2$!aM0Q-{;bނe8K3}ن{~BnaprHdF2͗EXn#S1R4:9e_@bPR* ZpY[n+P $J%]}ŵWgm- r;V-tK"1A() _w0HR 1աJJc;*0HI?HLEJJ;QsAq : 1`>On r 'CXJy?QhM`!90*>rS'dBsK͚XpsP yi1%qɥJs M#5 2^[j[Rb?0q Yhoy r g|bXϖ<ӋutJ&P" hM" YTP]p֗['5Zw^'*)j3[Q5L5v)uy&ƚpT4tSQ=D^n PVהj!u\"/7Bp+X>t \1M9Z Ԯ4 WWt?<1rSK J'v̑4;.*~ YirKBssAB3`}ݠIg)M!/ h*|fF& 7Z[g & M"/ Z[l2{?3JgIMb3F/t憓`Tg6& G>GB|inYirKً H+tGحkgiM_M5"hDk,r2jJF^qBsC#JӐȞCwk B\tq**iMcv-k47|KrS؏WCu⠂Tm4.!mkEb(8>)eezû"e4.oHDn7 ЭniSߑD{d¤TEh¿#4fBf7^ fw"7RMuK|+^ݦا57oIEn"н]nG&nكl[R[X.rۼ^m2QqpK2rSUCq2wɔ}EDߒ4T]nt+ tVts{DII1~n ea6K"un1?!|UXd-~E:ru!ƮQ kIF9 wx+U휔j vX-b׉V.UnH{ȨNjpy{:IDATJܦV>"S)Tg6$$7OT{>쀤PL0Du8r;%7Q7v]F)دBm2cH) ӒLSev!x[ЍHdUz{ )U<  EqUb3F"2?d&eϏґ訖(qMUY13O/[8ZMTA <'Vɤ DŽtJ~[ GFc"_-*X\ -ɴNtvO>`r*4vBrr $SP'Ix@ )t !virEbri)pOBA )J;!9ɬRP>d,'qo%DV' &7:E1 'w[OBKA[:2V4NF,ʤЍT9 Mơ*<7 OmJ B?INnB)Pڭ@#ƆJ'N$'7% Pa\3Ijz͘Jd6U| Ba PHM)~HT4}"2 t}xR9+?@wJJP~$(7mB ÷1C 1\]ttP*~˘ư-Tʚ E: Ѽc"c98JO܄A,@=p/I+ H9Mť"fr9/|+;xö: F.uT!II}e2k(A[n\M'1=O[`$Rnz?c1R>'Ҕy(+|v \S H%J˺#MitJ鰔>o&7.j]tϐܴn"I%&C~Mz!TR.=ErJJLs)iw0TlJJ OܤySKLKP&uJ?Qjk% *7AXH)y)PMJJSHUnb37%OJ?g* ;ĒR'IVn ݒKL/tcnRLݓBϡQs$+7O;,[,)%#])&1gKhyɶ,¢XR*Vzt֚ir⹟Jo*stl RѫgIXnj\xeo-*=;NR*6y, -D(tB&p*SGG#k$eP5% tlq?Q\1ggvjݲ&Hpdb$&6HB{V?b%n3MԮgIZnrwP+IXҹ,yhfz'e,iM"w! |'6_*{wO+y+O*;mArٳ$.7J&ekބ{4GvW4r54Mﮢ6(T+]hwS-ÒrӤ.7 h%*>kJYM&x_ :+_e<驨5%MûaX.v%]`OBYhҋ4KwQ\ݭ{Hy6o&DIZ5YeHW?R(~k|1ogW7-Kgj9!=#Y5"/y%q5}W'} BXUPh_&ZQMDh睟o.&fnѡЖuwRxmrS)ܻFL_ӧזG撚[RrkäZ6{u`bTgS^&bAR&ӽE{b $CZ5𮩮_GotC\LH=p!7-6Ps~ ׷U/b̈́xN7p!7):{nuȊ]A\הEvzl狽DCnGBS!߿.搝.{5ۋN7Z\~vSfh\ >ކ3cbώs\~UU73۶AG]v\3-nrS^ ܩtSQ\\WUeY.7<;ޕhȪ}sl&3IN2qtMu/|Kv]X4ϒ77r*DHה=b%@4 ~ђdH9ZH]/9hW+{kz~u}:15 t:y6߆BܓM rť"z1R\-R a ?rkEbB3bB/W4?rS6} U,'=A?đ$ϟy}ĭwW̏x[X 8w1ޟԐS_1?In90E94s\ɭURzjWrBp:L3__ncyCKn!,`._r-lqxdb}xP{JOq&8|(yב-n1u/Ln?| ٺ&7N&|nىp'Sd mHn١djhޱS^Z{'.Np@v6ʉsM۔Ӟp(7v7n.XGU"gGQ:MpBsƥnuD_¥ܴˢmMyrumoDiNH' n\}/tWmf}r;D&~ q/Un{2]ѫmv:*{vcm6aŤY^俭n%NmK[>{S*-y;-VHkq)Wĝdgw ۋ8y!¯I[7,8&pO_@|q x[vѯHk%pGhV:~"'sa 4ħ^ķWa uYO}uW#])᥇V%bn^Źz;CMiRT1xXgЏ+I.Fb:.V*cL'}lj/KpBn$SwBꌭwLJo/%vJ$ o BnܡƦ.hhǍ3مҙh+$KPO"_4ɴΩL-yOpNv" BJ7vGnqR}}$(F,J8坟b[JflQxKH;{Gn)c[!KhBJHJ #*c-RB*v:_#w i]-;'{QRWIniݯZRTHJ) {[bݒZRWJnRjvIz~ǾnCZp$vվ#<[jS;dILbU$ܒ-$5eJIR-oza[Rˀ 3bwrKbjUIN `\> wI)%M*+'HɴB"xSR narC<46}r%߱G6H2 JuLEv)nKZ3>4Ͼ n-EPHB }\2.Kjd`7KJg)4}ƙѴ1 $7UUUcre46sT2ّD߰Wz|O mhؖj;*XvKq+o ^`Tö8ܹyr;שϑG*IV<|N-N$7B>4b6a=;[\Bc2 MȧKx(ežc Si;K1H&KSZ%{THM9wLصm* LS! -h[}6-XH00.'7C4E3di\nqtURiOG׻ع'$A"ZnM=߰w[m$\Dt?cUyq~/rcކO5Eo9Zb#P-jpʓo2 tXHcbL#_iW2w( [zq[iw7Jjӊ,2R]kPQ@n2MyX->RnF³v( HJy d"7aIm*[CIy~ *qJkGm[8ʛ&_=ͬ6oAnq G|}."7NkۚY|{sR'3K\L̀rX~.7S͕ݠrR Dv_+Ҋ@nWq7g+Ӕ~NU{pAnל<ցo(\vMtTaͪĴDpX v?;nüG WuVzStKnAnuK/nuѣܝ0V.\^Z!xULf [H]VrG.suta^'}߁vex^Usmp&WݧqmMcpf/st|eޛ&Xa|/jnAnoKޝ-7CflۀQ rV:M68O=M9jww@mz<# xp*ܵT|7ڑ*Ƀ6-mukV:.oP'/GV.N٠-|W챗xtnD~ʼplDqgEa "w^w!nUv3Xu[{hwmouؠ9]@ܖWfĩmѨ/ A~!nLxd>6Geo.p33RY%?ڶqf<$-/ަeװѶEm˨JKUjլ֒ZWXE?xQ."np!SYqa&qUfqYW\DQw[mn/\Z_Ue$Y*3?[tdⶒp$~z3=(n:MV}gE-|ӺrZ{@R"R7jںgFQDQ57|:~ w?!c'06s~ڶWPvP*iZF,6yq@ՍzSgԠNHд_ mˈR՚ҕYA53Oԡg멶IW nqe.\mp' FL\MȳHk/hKˎEPP^u+Wl#nG0W7 nMCqcNPpHKa^Νt⶛z /Lxm⶟~y<͈e-TB"naY ?#nQ/X0j?v>4JrLzq;Jlzc'vrs͝qgR3cގy}%@N$È93o(vrVJng nQ $8JprESk-]㩣ۉn'ް~qLzN@Υ^USs"v2؍٘`'f"ny&{䜶RXOoI'lMS8:ꔔ7:q3ߚ2Ƣ- XKClIOF܌鷦2f7e%C/\f)Ff@܌rY$w n)|0 Waͼ~|b k q@d:$4v v 7(zy&k37m"n\w:N #n)XolÈuXeۅەiۅۥXeەŸŭZjP&)o_]_Q!>?ee 2ϧCY҅-ʈ۸OzĿMGp'@R@E`1fW#nOثHO 8qpT*oDn5ٛ8q\ܺE6l\͢Te+vw!nn)?b)K7{S/R/jf~o}^~-ΎV3<<)-Aܬ{ p~G݈EA ' ݏd.QljYqMc qϰ)qF qQ-iR{7+ nq*ρ8 qysiq\yؐ6q'hJe ^jfnr`]ʘٍYo[56f-W"f""m#nNx-9Y=0563#CMYK<!1"2qAQaRb5BrCMYK?:hI2/9n#'=h?:t $bPU\ǻTb5绳ws=oZ[oRxTתsdf{>:WC-2͹ ^\ ܡHev'/5³V47dav,vs٬T޽hz+J~cGIU/CJ5W3]Nl}@9V1حEn1r'irU9*FDJ |tGn\+˱UG Ւ[ANy=g;yoJK~ujdf|ޞvXx~,0 9-Ui#sj%jHuLvK ]SڠłSȣL5HY)8܎@?o d#Q{\ Sߤ$R(kbukImF}jEbr-;UU8gyJiTfWE#k{I D.tz*Iihףr9@˱xdO ԕgᗧ5y^_#ߴJPnvݯ_n0$2ʴ2΢~'jh{om9ߥ@:oinHUkU:*?- \:4WMT#\@ ˊ=3͓WjmTw ՑUg bDwU9+IxdVUFL@6r"ȹEE M;M@ 5WD#W>Hy mc|Քe09=@0~ZfʘYQ~ y|N|_5UP4Ҙijoo5P2<īc;{2@9q߂Ƨy͒W=Ƶ@M۞7 ]ƶ~ iwk9rB8arhwW8z 5+I/x~\(᭦L=0)>=Vz-U3̗ D>!کjcW=]29DP ?&5{Jp0廝 %lhwt;[.mEW~( UpY5Tnڞr tݣOZZ 7t[yUz"BϨ[L$5hԖ{uڍ*)s0D\Qz*5Jwۭ ';dTT&|H|ok-VpBo3xح6+==aIdhvܪUU:`F.ioJe{6{iYxu,7[*ݲDGc(^JNd!5ݵ[K**]ZGUvBq$0ՎFKxmlgraphics-commons-2.6/test/images/cmyk.jpg0100644 0000000 0000000 00000003371 13777276623 020023 0ustar000000000 0000000 JFIFHHAdobedC    !%0)!#-$*9*-13666 (;?:4>0563#CMYK< !1"2QqAaRbBrtCMYK?:hWnD䈉ڎ4D_> HˡEeʪpj_7J",]u N>{$D\Ȉܸ,{ĈU9df{""vDEЂixă(g}P2d^ѸV{)gDEǩd{~+h#|DEԧä'J. iCO",_K>;͗ٿr")c[cpTNZ`z"P[FrwQmr*}"-Y+h 'wM"] ?舋t9ޞqﴱxDVuDEԱIi7>/6}^Z$!3ݮiN]yDEcA )dQ5Eu% 7dDQ~mk'wx4z""=J,˜QJ4PH${ODE*UӪEbqd  "&̯1RIM#t̞q""G~ nnr G4gpp?DEQz2DE%3ۚy^r~}HDE%wd ߌ"")ٔU<.5 "-Mr|{';DW""ޭ-5rëHB"/> Ȉ4wޚyQLQeze3TDUkdyjlYTw "$sDEҚ˱/ WK) |<戊FKdx Nҳ=>&fŒF}y=>(rlJjwdap舊a[ IW@iJw41A^I9`D^X/Jl+0cp(v}USmiBǷ>"+cZ8{L-..>6{:z""gUh;(jfH 9]y^jI1@n?"+dBml@IB"+aDn0MW9ޒN<8@=Ȉ]1g֩-1s@=DE4sC?fDR;KdV}rBQr-;2++uCW&98;w# J")r""p\0B"(1'=?Hvk5ClA<8II=IDEEXw^SÄGniYk <98;Et%^+n&v6z $#>,Ѷ6TF˖xmlgraphics-commons-2.6/test/images/corrupt-icc.png0100644 0000000 0000000 00000066136 13777276623 021326 0ustar000000000 0000000 PNG  IHDR,br 7iCCPPhotoshop ICC profilexwTSϽ7PkhRH H.*1 J"6DTpDQ2(C"QDqpId߼y͛~kg}ֺLX Xňg` lpBF|،l *?Y"1P\8=W%Oɘ4M0J"Y2Vs,[|e92<se'9`2&ctI@o|N6(.sSdl-c(2-yH_/XZ.$&\SM07#1ؙYrfYym";8980m-m(]v^DW~ emi]P`/u}q|^R,g+\Kk)/C_|Rax8t1C^7nfzDp 柇u$/ED˦L L[B@ٹЖX!@~(* {d+} G͋љς}WL$cGD2QZ4 E@@A(q`1D `'u46ptc48.`R0) @Rt CXCP%CBH@Rf[(t CQhz#0 Zl`O828.p|O×X ?:0FBx$ !i@ڐH[EE1PL ⢖V6QP>U(j MFkt,:.FW8c1L&ӎ9ƌaX: rbl1 {{{;}#tp8_\8"Ey.,X%%Gщ1-9ҀKl.oo/O$&'=JvMޞxǥ{=Vs\x ‰N柜>ucKz=s/ol|ϝ?y ^d]ps~:;/;]7|WpQoH!ɻVsnYs}ҽ~4] =>=:`;cܱ'?e~!ańD#G&}'/?^xI֓?+\wx20;5\ӯ_etWf^Qs-mw3+?~O~gAMA|Q cHRMz%u._:oi+aIDATxb? F(C@;`Q0 4Z`Q0 kQ0d@X`!h` @(`-F(Ch5 F(2 F Q0 F4Z`Q0 N @ 8 ++ЧH v->,忈sF0"rDV[ʙ)cӬ9!ܚCufU"뛔W<S8 N--$>%+hfS`U^ D ЁD i7[Um"=_<6[7S  X8bA)0z7.Q iUKH{ X X G=o!8PP\6z3(.7:֨XX zMmPR`A)`ׯޫW@t DR@ h(X$3 Pp elS.XH"` { XR n)60 NhhDDځ՚R&)a˶k`Y[-K @5::UHh ؛C-B gn=}zɓэGȆ PPjD.BZ@ÁQ@, X# Pq\T[Or X<]ڃ߿@u6)›Z2k4 !@t*FGRb.A)p0߼u!*`) Խ{Ww\}@J@ /ƧOoB-@cM-2k5T@ѣINuPiA$`;&,}ݻ , ԭ[o޼x4t*F-DhS =2khy5:: rVTA)`tkիg\A U8PPj[N"0-2 ::G@- UHT{* TBRA;VReg.]:}"BB@+W /bHimAZ@v!,Pm7l9 XȥHPT{>7'On@AJ(QH?P XAʩ N?ܹ@tq8 %P P#P;!mY,`ʁvfhU7@Ѫ,UH{P؇D7"xhUB̙cO;u(:}(P RxA-FXS =Yt90=,|!1|3= pI;0q9@ <%yV$S'O9q㇎C (\b"Rf ` N36 ,, GGR QA@6ԍШ>|4xԅ '*`It`t#G> D!  %j7ʬ+t<̂w AS7 z ,27,\ H4{ /0 ؞ EiU?~RTK8w=0 /HjmZ2$t' ;+ȸ,B+U1xGGR9Qs`:S}Hc M*h;|Pٻw=h]JK.2b`S RfAY@W]CFHh \`A!20߿,> 1rilCH{`5 d.bx9:.;VOwܵkǎhvJ-`^fAX  d$ T{YF֠D At`2d 4. ;kc 7?::$t \0: O @L> lU۷MUT:RD,D|&X.ޘ Ҋ# Aáq\n~LU=Mj{ q:7j<Z5+Hһ`1fy6YJYrU!tD N"'qht A ~H I*#{ 6+]HXih^CWKXXX XYY ,2`:+%`uRác!7_ V`aɠZr?}Jo`MlIRёT:=2 X޽ j"Xq|ZK3Z` !@T({q[ Tv"܉WZ<݃G ,€*uϪUDXȚp# 7 | +\f{ZZĴ[ZZ644 :!X@cq 0 )#4]3@ѨV`AF=e u""`W`=:Z`Q P!G%tʞ=0;W@ ޼B?&Htr3#an,v) Z`S9|R k dQs. ckNPBa R]`0Y@;c) AD6 :ڄ_3D ,SZ#6R & iR`Wg*ϫH,0?J):h-,Xeqj,D; m$^ ̈́t=V?6919< ,r  +˾\2xJ.Nsr$i6|IXr<EwI J):uxwj,` _P6v@zp4R>?^Ga< E2z`ب# (@@e Vr p@T\ր>6:< 'zGf d{FdH 1|t.)T{Hc2KԎ}?gNb 5iq/ri ޼Bx0dNjr ^BcX3ї/@ =CT*p55=@ @7Ac/E%Ka/J %>kd3g+Ճo7)&I\7)( cWGۯVw>疩X#BWZ2IJЯl喏U;cPG SMҔ ZX_bn7^1ƙ4T]>Vr|`]S7^^=GR!v ( nC)F"}4=`7|*hp rhuڵkꅯt&d3F3`lg`>$=rnozGz@ 7u$+h`  Aā `P a2LllÇCONC[$pX9XlԪ<B5Ԝ> 3ceDYSCS4 Dx=L9wtFƎS$]TMob|V>+3A+`w,<^r\ /|23.{W ޷x+-QAI]t6yV^ &NuI,!‘S'U=+k`*N'!fxu#؅ڶ1N}Fcp4 qF_˥ŲdFiI@*dp/^}w@VrF̬{û [/\]TKȷjYǺiNu%Npp„VQ8*l ))F5ݺV[L_Ie%ڊ[̅!hK{HB ҰB?h:FBoq?| Ad>4\| =c送GaRЊ*N(4= '(3%HKOX8hkzU-Ꞧ'ॷ MY'Rא{rO'튥PTٵk\ᛥQ:?R~\tmd' }(Ń C ; CG *9rz3G+o+Z9`o\.**sM3annADHlU3Ôy5+J{0lS5LYx`t0H(U7s+M|U{;v <,`d $;3s8r◈{#W^aSSN=mq.C@V+PS4 ,% ݻ 2GUp(Z5=rB~.( rk4P 8ʊlc#w (l5=zB~,SbtaAWwOvAn0Dzfi'N8 VMOL*5=@\`Q~1: ;@G%Ο-'kv&х`JjzQHVMOEЀX^,6lX ۷ Q/Ft֒@#] ym^Q0I5=|IkBYBw  bt`+ s @RE5:@[-F ׮MCwG 1XGT d;rj`kznC-iu~>h5  TC!Xe^6/vG(w_^$Yr. Qd5=@ pK+-*ѦEt+@F􍪣`p5=;ލ{ie0,~ ̂tMΝahPX !H=l=kz=/FV#Ǽ۴Sᣆԝ*W/ ]B>ȸ;QH/R ; i^3$/`6h]X{1:') h6F5=lwPG~U;rrڙtL ZР(bt5XXq ~6rvt(R*RuR`!]?q rȃ܏- ))G_X(ЭR`bt 6F  YrNYg2p,|~PRlY^8 :/6d#0n@  F/F1Xh2Ҽ Cta?xl(d#! 9OЪ@CыGH [Nsߏt; ؽ9˥ @ػ4,gFjaߔ|z4 ,}L|h b;O$x?,q A}9qM9B vgPϖ9 (w2@CBp] ۽K _RqYfA kvww/ZTqwi [sfϵx4 Q0 F¸b<|~:}@ t`P ]v_xEhOcQ:B8kP6x[>,7bzC=0  J ѡQ0 X  BBۉW؅ c2d;= ,maQ04Zq/p?ݷn 1="2mV[hu:>#yThBaaˁB^YY5 ,X}5>}|k s0.~"kk\ G!'#Cnfv q fk+ 2o^ϟ?tQWp F ! mI,qC#cGu}؎j:;0H# Rf^kl|J+2wU[TCF!g?~mkh5d߯{!h7X; h ? i;Fd$ X :[f -[,X`eeظmxgy-sqU@Sqց%u ҁgqyU@Ov2'0?C; Q>aRfvACA; rd3 }ȗԣ|q `$1h5$t~!!Y= BpAT6~t@۰#"6Y_G9H#E.g·=CWhg @F7@X Xxh "v04yvdPrcay?I@"5n!7_?|*:p?[sw|ArPD^!7 7{B4=" F 0/ }ЏGիH~ 7E h)26Ŏ@hs;OބoY?C.: r*Q/OEh,l5| z>2|~Xc4Z` :vZFWAg_ш 70"_n~O >yLüq""sGYsC2 r\2FUPS XNǏ4\NZU@@eg@/"V ŢAjz6 {g@5'v?,T]W .kO AdȎ$SV0ד̨J/X3U*о𴣡?HƐ oX ]0mrDMT9D'u3?qPWG_&{g N;$'ƂVHƽ#d'~TNn}9t@XXDl2>N+H-@A]+´IVO'B>3 伦j--D *A5cU5rZ]p{Ew)@բE(.D+t'1\)hŠ 4f4h/cq؛Kr&$оH2$l$K8k5[3Ò y[H<}ED֍Yz}ׅ1a֝YCΛZ׋\N8go7=}i/E[3߽8h5(x_+ lM@ h @J`l߸q P R+D%6t o,B+;n}2ZfdA8`- G 0v Sr RT<ꛘ՗/ϐ:4bA :{ء!UV(TDEM9 [Xa>[h j;KTJtΦe$\GR$ېI, W_Lsg,^no GdttRfAĜA#`n;eB^6k`3h5`P7G {Y! +X=zu?xw~:fXsA!ʀaB A1(T.M-2 mc rRh#z|)l;+`y {h7/@v?7B.E00VB ZmQ!-{K I"V+ZC'F+~yS@NJŨa[ОUQߓxK֙R/0O3*NkJƷ{,[.;gl@gBi~ Z+ƟE4D#*Bul kmԺèpUT!|suV0 ~KM^BϢ,Im?F_Z|wjU"%h!3Hdz.z {,uI ;aM+]*3w Bĭ4&pdňV d=ж(A}gya)osghAN?^OĒp(ay -::IB΍"۷oX\b |.1^N) .c!fBLYgݼJ;FYοF9p4䃰Β?о!0E$5Ul_:B;Q({'=J1cnWKy̥r_"BDVOM} r9 nZMM r; 2[#V׮]CL{!7A;Fh$ +D{F4Z` ¸ <{ _`X[E|2Y䂌[S®27v]]ݏv0֫X @`{'0\A\ Z|/Z :XkdD+BqݯY`\ tWkr\!0u G F x ,Ăq A`555VVV֭e+r# X;6x9Ez̑@ +HG Q@@l= 2~< `A Ҳ xyyX=x# [{`!6Ƃ:>Z`j-_`[X h-,b8ZX;qx[X(!k1.!x X`0(Q`AIÂLݻ  w-F@X'=K_5e}>ݷt߅4N,!d}'Awf G@r@Xؗ]%&HSeYdjY@:,Q=e ;ͱA:at;( h50Ǐov <~ Wazww4H!2|KKˆj+p;hfy(QR,7#-4σ]%v&!3 GG F hGa;lgP# Xf7acB. M6zzzddd@b+J+2wUCf #pmk^Q@k`ͽ>=A> i%f nY۫ jx!| ZTGg'drT =h+Hm;ƈh5 4Z` u m3ѣYX#pj;jQ-O"=xtdQðc 1r ;z c :X( h50q݁BȐ,HX:Y!g!CW79ZU{>ȹ~Q. 3i{K+ð+ej h0+Djd!@qr!jurgt1!/ WKu??rP2dHьr>2 6Xg1zܼBkFQ@>k(HB;/t!$ P@KA#hwO G(xveQZG :GP4Z` $@>w-G,qݏ]J|Bz;!uл."D\ ՄUO@z ʜ("k RsCH, }C]b :U(B-"ߜ >1vU˟mYҶ-EѼd- do']RfK7΃o[ze$f`;f,z`Qz 3m^@X C`j غ| ^HP"'4&4h#tVWK+JQxgpvQ@@ؚ,eÇ1wM-`1imK ` Rxr*&ld$ "1Vc6Un㛘| '@E&{zwYϞ=5]+@m.4JT DFXE2h/U) B;=A!CWF;* F A Ce0C M-rHuH+Ȇ& ;wDI1QmUІЅQvL@ noh,\fAeև޽{}HS u!%_RPL"zÇp"^ [U@@V@ t-hZ kH c??v޿nj!gn=}zX^K GBn HTn"s`t"E@-@*x 秐Qvxj+R9rE3&˾_"?rB F ,<|}//pނ4 `iTTT ԂBL/_BŁ 2Udz5ZZ`Ƀ!%0< +H%j1 EɠK4DK R LKw}=l-M[,_h2450'I *L-*8" _/j:Wcx9!~N@`=[VrA\ AE#bX ?nXVIЃRHy [X  vh%b8?@X@ u/fFJ͏! *_AKc!E{2+yMBW:F:/-Ik 2@7yi"!xwx4, ib!TÔ=;=!Z<c4Z` mPeDR,tRƎ\9O ,yYa6@P}Xv!7t x{eK#cG4ihK`E]e+Knח@d 8%h@XC-|\[H#cGrioX63@*R:8"kE]64Z`Q@sYZ}h[  Pw\]AumJ5p*hi( ذ|q9 BO*\@b IDވta  F Q0 DOtr7P cΐhD?p(9 XxO|9rY@Q?HW-F( S`W0@G}QZe5`gB˩ @'#^8rJ5@}bș_),xdCc@($TkRZaފ-nݺiXM ~N? DW /H;\t,{)]\՛h(@ V/`PNJ+!>$ː# y52'M-2 |5M@eн F Q0 2To UEճg< al:A.LWۂ^ .D›ZHe F!hmdh5 FN@ x^5|7ckdAFpk"hP~ӧ!G/ -]4Ixi܁K+`j/U,e۶mۊ \ P ԂYO:zq,]ȍ,`i ,ya¡kʁ HEa6! lL˦- @!P Ov Y ,Hhdp h ud2VNjV|Q(@,=`1)6b ^f;@u CF!#Y<]BzCk hׯ`kRZ;ٳkNhjƍf͂Rk׮^h@}CHd8@z@g^!|pX4Z`Q@)v3VdYPi_ );۷oۺ\r1c`~~>u+X!dAz7n@zEBaWCn5@X`.@*Tr +XTAJ+E Ү];& XK:x6,@ Q7r h#J+ )e`9)K+`'a P1 1ZYA: ,-F+߷ C4[w@W  # X)h#@\A:lLa0N8F!XZ BWe ,aaa]0PSScee%5l ,-Fh(3Y@ ǎD墣G+`O ,KKv0(**(@{B+݇M@(> e'@ر ~pT ۛ ,݁M1N(kG-4Z` `WH+xg0}NV.klr޵kxY+_[~ճuXȻslz h# ,Z f7/wLd؁0 RxX`s@^!d) 2o^ϟ-~/ c={r]8 @(ظX`^zuҼ,bu"KXAvҐzP\xKы-HR`AY2 ȂYWZ`_ m(Em{ h#ᓃ++(;, @`,Pv; fRTriALްa{zz:x  XYY566Cf@Ɇּіc F Q0 hry yu'H>PLY=܃ڇ΂g--Elpi94z>wt0X@(v>|x "MGNB?,T?2(AYxhYq1b FZGn&ۋ\Zo^-|T44Z` +v`Rؼ: k?qyv-7!b>؂ #CLO=AxiuIXg1zܼBkި @(s 2?l[% "!@Bᓆ "/B^)_(pd+A` t$h#Aΰ8 8]u 2Y{nbXO!e2 # o^= YP YZP Y%]MQ') KЮ+ k8B,h `f ;H=PaǎmI=`ܼ.P݅Pr!{a?U;!CV -EѼrW@(q[uHڋ4؞S"RTݺ*ξ㛘zXgp6 F Q0׸g F t$ T Y9\Z˩{R. SG7n\S!*HQlX=ztX>{vz 2t9aHw! F ,rk9~M,"5SFaaˁB^Y_N ryDiv*H zM |]/S*XQmX=~2ʎԶBVCn3&0Y޾ƵpcQ0B!@eHiu)1)`9iO)x X0!#H!D U, +`7Z|!ShЍ,d@Nc+d`'XX dgPO#hGa;l=֭[)ϟoiiЀ@tH <kU!zT#`K n)`ԪUh VC+p-HX`db`Ǐ` PP$K#װqwðzFlHX]|` ɟ={ ( auҤK@i=!H! C`Q ) + pij8V@@  ϱ ~`/_)zb`6aHB#׸v5zaXp t djOH iAJ%4.@?`9iU*`[ 9AL3aW A{Rb[N$/XpLEW 4h 0ۥ`KP+9^4߼6x t<Y,O,ӂZ9?Ik lA@kG=s4p(ad @Zhsw_BI~|/C_~C  tE|2p)0Wt9Wi0q8U@ dM ` HX`& ` JtցΰbN 1kQlE. %w?v)!*| _)yi:];ЁJ[@#tc&0ɢfڻ #+@`քvGPdCl! 3r0:2} E;1Y"7ݥ *S=B p~z ACe%Yزa۪B4B ,| ob+XL lGr,0^Vlã!\K;P#HvB(eq;#7kTHO`oN8rO!%Htی:2}M#'/ ɷc gANk;wN iliiEEEu+dy'gU˨uGG4 ,sI;T+'!+૽w(;'a˾!c٧tz՗58_ahXP>~|~k-uc#𢤭x.d@?ZB r/LVptxz {@#B9ۡ`:0ܻj*̬[PP˷h'!ǭ@E:&/ PH˾/@n! Ș0+ݻ x͚5 e̙BBB@)q+| ԈЀ|=SQ0@ A+ S7B>{A7o鑑lYѢE [[[৬-8S{oAʡP#ף` ; g'*!c:.0[$iv7oJ߿9ߢ oh|huI/c􏐚w1\\ɇ{A$xr90`GD| 4-B 74ݢ#ף`x)xqd viUW >||s>$B|.D ?>=)>S쾍z FDNlDν'G#Kw 2vy #ף`)ԵȷH l^VQPFXleL{ ~{;vH+h,[Z6t=As)GGp4 ,1=}kQr/0ݸq|o;4C]CkfZ2-j:MF( FT8w :z{͛P| ,1$@.$BzC@hv o"[ȚIx~M#ף`A$d?!h4]h!`vy u `c ځz&fNkGG4 w.dE%f} 4,Z@ɺ6Pc/BL 4h@xhdrJݺE#ף`XYX kf0 d{@0,_d] ]94p˴&(x3R+o_Ј+Cs/t({?|x7oCH]ap6dH2]!P4h,p|KFG04 E^d4'D~ӧ7-؎fQH,B8›ϟBƛᭌɷ#ף`8d4R g``A=@lG$Bؐ TTT ɴ&d.o_ x-Fy+XG<C 0+~}!u\pv! x^y4fFG4 4: `yd d]"TTT ɴ$:D(ߎL_ahX ߀|y l A >Js,P Z  |;2}= 4 `}%Pt MX65@ u!l`^JA+d)걛Q0D@X]apfKHfd] ʮ@e (r F ,yyu!l8Pe (B F ,9 Y†]GG 4Z` Yw]Ao02}= GYwdz *@02(T zF( PkQ@C@ F Q0 F uK-F(4-ah`PkQ@C@ F Q0 F uK-F(4-ah`PkQ@C@ F Q0 F uK-F(4-ah`PkQ@C@ F Q0 F uK-F(4-ahYY󸠄X@WWs]-7sK#lfi<<p_hNKzNsL,sɧwKsi\U5󸾄n`cߪZg[#ۛxRϮvw|/eEiywn!>Ǥ-L%QI4be.WsxpC!7y|M wVpw[yi̓x?]9//[סFʤ16X-lql*BS=sV} XCS5߯Z ɛgx" :1è&v&QM,eW>O."%b/U=m&5hꝼ}w !iP㇍17QKbOd7Wym,`_!7~Sg5Zުwm k;}'D8,G"r4*bU5M3꺑4d&3҉<$א/udE r]Dߎ#qqxN7t)?7&+uŗo6p-[ca!I#’3"ccUyt4g9OWsN Xsvwf7؀d0D_ T% RRFD2cR?([stw2^qz},bpFf_MA!DRRRR>Q?z vqN|Y\P|q%A:m'Ix,)B E0U It)2Gw"9{nΚӹDzbV\D O*V M(Y"`l?KIV a?%cX:K= L*snXͿb#L w</[B!"8F?ǞԙR|-E \=k' ӹ׊6-Ng\p'<<4>Ẉ {C̆+n'<.x'7iPBkA)T'k4OMv{yv6TG6yp=7φ%B;&D-=x:&KX,Zan.nx pOhF)VXl1؁,']p1҃^LaS aQJˣXK*^#-]C¡{/! { 3L$[bNd`w#ǃ^8}O&XB/Q,XZ!72}yo]@ adE f;:Յ 72=E/a xDA~ &cJODaqkxNOHr9_ FLv$;`vb 7R=H& 6?(#a8#&p -a |4/ '.H$ fR@jȈ`p1 Qa' 9:o&Z$IENDB`xmlgraphics-commons-2.6/test/images/f04n2c08.png0100644 0000000 0000000 00000001731 13777276623 020226 0ustar000000000 0000000 PNG  IHDR IDATx͎E[Uv۔("  ${Y[g*BQ,<3c/n=c ZG֭v[N+:ۭv=WoTQa8`HB[ n zeH4;؂->VJP_Ӻrό9q'JB i9 "Ok-E4Ҹ2mr n:(UB 칻ZLwW)40)t\+ T_?G٪{wGN)t йj^0~_j 4hL| sIE@ ͐mʢv;̣8R^j" RC6>|+WAp )O'-a_[>w(e5H5:϶yz8㖫$CykU樏G.% )xr|Ok5 }MR9?Hұ5`_€Q .i P7|Hrel$Л\$XT)3T%?qoٿ*V%J(Kq Oq/nB]g_`GR|%mʹbZ2w̛@{?X&^~ MTPIF$->Ү|#0M&ؑd'Q($4 0Scs:yꆼU]Mj 0WGɱ٦o l` k;4 Xͽ {vG!@,'$iKqOaHOv}8Xg DBs96)j2"4~, *ڧ30ClZ(cՂU@ \Ҍivݙ!)̓r+LV71 jIENDB`xmlgraphics-commons-2.6/test/images/iccTest.jpg0100644 0000000 0000000 00000067522 13777276623 020466 0ustar000000000 0000000 JFIFvvICC_PROFILEADBEprtrGRAYXYZ acspAPPLnone-ADBEcprt2descgwtpt\bkptpkTRC textCopyright 1999 Adobe Systems Incorporateddesc Dot Gain 15%XYZ -XYZ curv*NyZ1(<kB$    3 S{F!g ^ dx-U L! !"#Z$"$%&'N(()*+e,;--./0|1Z293345678x9a:L;8<%=>>?@ABCDEFGHIJKLMNOPQRSTUVXYZ"[3\F]Z^n_`abcefg"TT֏ R0瞽fmL6%-5ܒEb$yꎡhRR# զpFc\܉J :+kS[4*3m2֭ IVl_#f-?W=g:d.3EIIy_7X\Q&D9?Uk3o 3Mөy*-iQLA4e GeW&]JXk^͜~bӾ΂Kfl1u3uϨO?T#5<uoν#vl*??ӛu}Ɓ?{rcb(/QIElt9ЏglK.-q YE=hJUu ؆]k7ؾe,bZ{ԡ@()䔐By@0p 0` 0`+s5/ӜuEgT81LHM^s ;ΨhmW *b xB~_ ]g TCaƩ37S/^ż ys2US(‚*>)mF$ٽʆm ]TuRdן,)ˆj>J]eD)ͿqKnZCE6LF,M2 :rmbR8 ]RNZi|]– m4p 1>X >?QG+-G:`yy}'$Q\+JJDn Ϯ~wJ}tK)SBjSlޒxi8PM}n% U1zԞu;:|It*R]UBh裶Q"@P -3 KB:崃 NoLH(iӲ^) r"5-! &! %N` ܦNR&DIhhHu)1Ø,bo.K %QCN!JҔXY^:ffqE:2@GRܫ[B(fMJJͶM[M6Ru9>Ch0y)Bt6*}LDàIPyR w^ۛu#4j:k,ǒ*TI+NV2m .~FWKoO]kSk@ g ]PD,l28ʵ1tcog=5;~(|׶ΕrɝA2pd33 Y)d]ŏ.񕔙ZOC-ٞFOKD¼sO0|3|^.nY_+k]Ix,!4t9+tVx t4)Z$l 0` ՏWbu#[@k2Bn])tuWK&*U&ޥ46Gr)SxǗ41Vș^:1\VrOITylr[KY7'dSGfUз qەںpܫ]EuՏUX}VK:$QBITmƒ@$NL;I9­eN:IRS" Rh') Q (SWҥ)'u*˿^ތڅr݊mܝl۰W@CNU>idٴJ:P(a$ER6LIvHI;z4] ʏ:;y(3yRelJJDH$m**qGI$+J l+ $5.RB8w$\liϛDxfmz+E*3P}gU e]I:_K,\isFuPb]'DwO2Ti~c1ljg4۴%*Rܨ*Pekmu^ ]ʚjq 0` Ryizqy4,<(mЕ-IRqJvN|4>/vemm[QS>d!%) HʪԣiJIx}},=JѸjT} sgoIn#oRNKdvDI g8NIk+4RBN I3l6ⱶә%H %A$&v&=sΙe{3ک}Jc.0"6WKmJǡږ6 %;aeaCHJ[j 2B ! 1kM[ RTF+p5g~m@!)E*5z [(BDYA(@҇D6%.)A&LTVBivո- ¾4t*>ʗTb,+El*tk}=-3I[e)n;Nݠ #ncl;Z M}5p\K+eUE™hvjYZNSnNr7 VIYY;f?g9vRo^C)J]Rj\ZS2oJ)Ќj]3 -ÇX*(.Uwj2T΢Zh*հjL)9oe]uOQOWNU+ԲE5M;z%_aԦeԗu)!IZRA5`/&U]3&d6J*snCJqiI&Ta) Z~V >s=nPE%E]G;EzTjvL* m*u!^4M7WPjH*S^(AI \LjoJm*ARJ@}p#tKsUኺXi: K I$("3^o%fd!IT +x0ؖSxlqf( JtʢD)G*fBF5 PҐO* G-Z:-j3mT_5yRvըԗf;3  R]]"Uez+*^M]];<\Uv 0_ݫIYZSU rWh$-@05MөIRJ)!-I +YS,c@m7"F`}>$(JHⒷjV4ԴꗪKlS6oT:A2$E1Ut+۪+AS~mJ|iuFkRE^O]I][Sm#WFUOx9IS[Jj&HvULtceH jm7͡{2RCb +뗪l-jZR]bN|%a[O'̡3YVӕ+T'0ۨl0jihHm!E-3aH ! JeQFIv?3Ip~ڂNŚ֖MKUTij/& ekJZxH9bA D !E Tq\Eן92rut*tK.U{*.fnZz:MKM)ò^XSETTV"RdMSS=rqD) \n“ Msy$FJݩqkԢ `+& J$ |$,\Z vBXP j$-z*zBڄ,LӤ].-6*YX @~g2Bt]N1[}*iFgfZzleźjїl!e}5 .j 䬯ES^WKnW)SVcb.m<@٪qV̥-U$.־ =V1i90\4ZVVX`[2n^STi3em@%?sFayЙ ZBi bƼYWL{* Vh=xK "danC[+:\n8ӜpE/1P-]km4(AKm4uU@PcQsoqȗ"U]55OV.O6 [2(uR^ʘfdFuMUZcvy@%E>s$sw~Y v~*ǰ~1Y2#;s?c~'h&??0N)RAJ I:$q> >:.Y)*Yˣ uu3|7JͶYP\^fU!nI9toQ\-V[45l(-:QQKRiCl(~OGijMY9G+׶UTwSYpF22BqpV[Zq)JQRFy2I$Jdեu%)% RLI;Y:  1$=QKtHJTV$La=[}lT:ϨI?Gl\GYZZn)%;!$Lf<K嵖]%%6}#/C934mڥR4.% 5WT]n2UUiRI fܧwn˖ip%TڒF慙*idM.8R\$ˉO'>d9zjT!SYPޤ<(^Viۀ!>ZsXSeΚiyH$Km"`&myN]:y4 cu)ʥ(m:&Tt2Lijn/758Ai;[R|~ä/% /6W0|ןjQ~,(HZ6`M'QZLU0fK儫%Pмט۸+$\E[+O]{ӈTmjnj,12QM(0 U_yRR]:0ƷU@,Vs9jJ5陻3̻U[6[18'[)C, ĥ6N/Ui*SzֵNk+ 4Ka7 37R߯\*wq}\!  % JRi)  p ~N 4D=LG6<ߏsY߶cycvqU)"O$݆68o7700B۰ N㱙qCumY; %nzjVre6/Vu%'ڿ@8i'HLgQ>K6eyu#s{5rԻ^B˵ͽC46V [ Kd-5T.g޾[=3gln1kSV\NվHf0Sҵ 4 1fUPtk?ILQQ)K mPJV&`3 i@?"g#0 '~AGq;{lK0v 6۟lVK'qi߹?l)B wߏޣdnqm/)g̱yui%')4?BKN@SkP qBuLuL^Mr"Os]m hTL\gH\UP)J&d ?~8wMSj,ceDH'nS%P$s#Hx"NǃT%[oy< #JG3EQA BFLH<>u*@%i&D $6y'r @!z N0vqlgP I@H"`FO&&gFR@0!CCh2?'8sB*`lpB}jDHf~G1黢N*зT$@H>0IT&!%jfdFUi}EHwP =VOzWHUu*3v0^b}m 0_ LVo}p :בB U>)?`sC nfPf97ʗ`<]˔TV([[NaNu +5n4f<}YvLtQ$V;ZicM; 'M 'w DoO%+P8LLn5$ dN6T?P: }m#FG#6g~|~|8?3hbHi7 AI;F>$yn"{v,ieJĂITG'&WA38u7½+2Ai7g`ZP p%ctGRx7cNP7lrJq-Um.bj%Kyq(DbH #Ǔcxޮu S\j^yըQ*$Ű} Q< A|']9-*'B; NrFWD>7;o䙟X  DX>ۍATq'PH۹G7QѭGSh)vvԂ6I; y-Oi@I A*PX$"7*u,TiQtF>-ۅ2%. TCP=lfg:e恄)TNԔ8R$4? 'xo"GNIDAҠBJ!!'bG=m{ʻ]+nҳ iuI`!Iaă<-G⊒D]ru2#@zT({nE}/I<$ZYfX]9+4BJ &7JjY‰׾Ÿs'? Fb{}8[۩Jﲉ߉#*mzHx:1mN#nGxi⊭LG$o d'UH}0tDLm1@ߝobmo&`~n6?"+OM\Rڷ3hl)\i+_ Yk|lIrm;3@ Msv ;8k$gqj*p?~worRBgs$2vAVԄD1 \7Oh2I <#~ϴm"0b#AcOvǨ79$ I9qNxWwG}~e;( PUI.1IGΰ clA=wձ^6BXsevUy ( vkR'?$rI' L$DZlG`-N8 TNDsnhydDJyviki+x"N6=۝)2Lci>H(U {r`Ns1S;};mkR; w;]ݚiCHr}3;aZFRI8) "2VL LO< &!H 1"D '܂pD+T4A$@&Abmg K/,mJƐLY IТR*<ڵ@)RZ)WҐ ]Cߥ迱sV_iՖ眭*M m^,LPgZi5c7B5O6] >$gm_N:dj+42fjmv}E#),scUQˉZЩ16[ʠ:{ԌAN)S4mfY+JTILL >4+M6icQ[6+.WD![MyG\l an'?Ia@;q)Cl!< O@atePDF'qd0T`;ma oG'}w_d~m#2>܀NۘH/%"I)x2g۶hOo@1nZֆφ NVa2LJ2I@hXgO6sUjJirTYK %,XmW$7J~iz֎g~3|{uj.)nuJ*Q$K'}d]$(igc宅OoLnp*;@ﰏۑ}hmŁQ"7vxWZҽ\;DA`x5$teRBIә0vFkKJք:"`7'iĝNJ:U$񶝁ۈgȐ ezΡ1{8@ɔn q +4Dcp@<đ٭n,@pRgbչ= B]q$&PJӫo̡ZBĥGvz *LRR רAP09Ӥ_T_3*IH)@J$HtұӼIjR1V `u$o- Ń <Β G1QBJH*O=;TI^HBIQ dnOTB$ ;S"wv'Yy:R eRH?OwO V%=Ju"4ԣlR#m@')u_@eKZw:E[V8j)MJ,QJmT |G̳̫+4Yh4v47"&톳qI$Aۍ\#s}w:߹ߐ?a!@nyÿ'} T"D{Icp$rNDqѾ.?F³ViKlOT$ {W\VJp U~E#3gU]Kf0F:͕-9ZAMA{;T2HƜ~>̽"uM*ADSu9LOwA!$IiY*pO S=;^[Hn 6~6#q,F*b D,Acۃ3RpPďq;bsl)n'I9~I; 屝(i:IH ' J #åheK. % 0xG1Pm+Fv"Lm̝=GCxvJBb$zOXze>1uYɬˉi)OI&&#"7:- U Ann`w4!5S$8 Om_)V*CopBA72L=2~@mR־?)jIzuJv a/R)떯J}4! nH*mI2 NÜ$[zƕW6%\%M֬'h @jkZ4"XD(xA@@I ' U*ڮ==ZUXT)[}ȀqhT)vPhUx\Ӿ,e e)o301as;A$csn6?}bYEU2 FJ)$6$$K)QQP ( 8B.p fdǼ?M5$᪊^t nj}9*{N|#REŪТRTm5%F;I&.OC]FVq OM's5v&I#ֻG\IC9#eKkU0vPQ$ b5.U8 [RH[J BN*?.ܡĕDJL1 lIGWZ%D'}{s"~rwBB[m)BBBP$)J@ J@)@4ݟ9+^G&{ioN]VGul> o2RRSkՠZI]: G2dfܥN$!_P  A6f`Wb CnN6$b*[(>}qIVII2@Ȃ8(.[w'HVxjy)8CJUHag!LԲD!P"09b\1}i,Ӎ\mA0T$FMY(jpmP-"ROMr*_mo(JJ]$v[i^ *eamD1:2IJ|ā N!`@1;%RRJV0b^l@ğ&AusKwYLu #u8URL;ȧM>ch*BnZy/H<-LBeJ P7J_duԦ# iHI edU dēOpa}vroQK6_4) UԵO2(̈7&x}>1{X. *\Jfkm丑lWZTUR:v"K+QJR6J$b:gIP#mJW2DO8n]_HvmDMA=dOsf~nvWKǹ?n ]N xpTLn>i{g]=Q2GֆWZ$ѧjP>nQPV11v<01NxZIdnt a)er)M >Y˔-oԥztc@i>omMd|eN#cV_{bHud+fm4狼V@ԒLL@GpRpeJ @:};$1֝24I3ǴG_ٷJV@ؘ*pgpj $9nA<}Ns+w}? ºUJKK+6ԇi]Ιq%. sJյ=lQD-NHhUl}uzy-PQ? qvsJ>Il\YH;= r MONq2Rr=*mKlyE8p2T7Bt+JT{kASpA)%zBwHY0 x8JQ E1t[mԱSB-%;S|Āqv/uɨnoiLon=eu(?Fy qi=]XlR^hy}M5L>d AO*?4$bGve~`ZU!TIREDJd2"Qt`#V 9("w]#!LbH`XJvh=cs2ƓD?iWdkP_r[mw=dWۋ,l$•Jܺ=!(dףgXTmR]3U+~Sy.۲uA4) ufʮ$!C,SݫKu9BgӡyVCpN\7ߗ)Bs/b)lşGin.[еVSeZ'*|.DQlTPHSN6% R`@Q$Jˀ-*mkA%$dld(s )T]JoJQuǧ[em,zRB֖ k!cJPHI" 0 \*P2 SNIPJTRFXKVSԓ=?RAXHn0ܦIH&y2F}ߑa;a "7m$;m 6c;'neе$$< ^4[LMNo$AŷeR*  a (ԾZ!KHP ymaok -ɗS+e[5MLybmGCAl\f~;HUD o T* HQCvtAb!fj". uHдuw*Г6/J*C͒l- BmYYDhZZ:A7S5M)D^G u(/Dwu5@yⓇD+im9VkՊZԥi]3aS-ĂAҜiq@ʒ'x;wzvG|7&T[s%"jhEJ 8ە-AuO.f&|]~{a&%zQYJN4Jj%4^z݆h #;mh8)biZ6)^Q%|7Jzoj6~VNVMW_AB<{g[LJHL9G^j(Q\рS$M #HH\SǐƤβtzBVJL`eWJUPBQ)Bt@`; v$ ecQQ?rPFĉn fP0D6{_e@;qJ*bݘ:xCq[i?>ˎ}_(ڽ85֧^IʹzÖ+GΧ[E )TIaS3fݒ3!ZZH|ۈdkNq8|C>]Rő՝iHJW+נ!:>͹$Jk:YB.g,jtgMKzmWQѼ\5K_fHr埪ޱo7Kg.} T?J2$$ژeggɤgRqŭKV-εꋅQSpTVT<& +AMyO}7e܁V~wr*ЯU3U3df*k,j֥D~ę=;̍4aIV)" 2u֥*KoR)D:)w d/YY~ EPoև H@^L%^iCqrG&_):z_1ݷ;rjc$Ų> :k Q{Wp5,YNp]bP;lCmFL3x{5JzU`SwJfE䚠AP]Dmh߱0J>vK'JeDZ3#P;J@1 ݝsrUOQB?nf.QAv'@۝3C4 "N'-HvHS~/j@RZ<7 DHB3SHPۤNcFe$~"(q#B*+sQS eEHp(,ﱾ~u<_OKV26\SJ)>X;tujT^dlV$64Wަ+?M2pm(+js/gV;3F=i%O=IӋfQ$}K01UY#ˈ:O-o?f %EJ$Nz+ >er,g>.H7!EnT@+.Y<Ymö:q9w >U~56kWShPu wR^fa{IMNRwұ] mۭQPPPӵIEEGJa MKLhev[CL6`f?XuuEʔ[MK Z oZ^H 4-hvWEs2.(l8r#|G)]Bi&D!@Gy@{EH<gWNmA%94H u{n 'm(jIt%:J)PD-av>a Q!GcHP1glXBǜBU;TvhE)Sn`&'&@]lBIT j#b]K&`#Ld=5rI07 8@ F> JyPFG~ ۴3(!ƶ<$sIw=nE2m$iH6";cbcvn̿Q /DMbW2 H;#5z-ݿ[}nKL|JdiCz*حA6⏤$ʳ] 'V}Gfv 0` 0`ǝһδkʗ WgUBЭmլ PP8ń(V4j@Dq@Lt[iKJ4RIzJZNy @HJ@+ZH;lDp=s=tm!(ס5"WJ1GdO+UUD,9  b@OBnj!PIvNm6}5X%4U Ě*)4Qΐ%Oq  6< ]̿La@& &psȣ̂e$!"0T;py|7VڇVvR!O<@))[%j$ zxCi}JQnu!JHBl(!>P$$0` 0`~Z|ygGg#tYXVM*KjHITan4 )K(C[A[ !: K%Z gf j"6L&F9;ip@)JRDFF%=D~0 m;JBo'd$HGkP׫CiӲ#sñ܌DS# XA%a)$3[m+Q B$% jRJD;;: LPLIפ=ƓS%!e%['Z`H a'Hd}cNIqN'xq9gm)L p";2$suGxrHt )1ʣmFo+J)'mv۴'lM,KlNxo$ס/ZF$jY$#cgS_z+AH+0iLh HBR+Hv<(t)ДPGΡ݀H#b 2 0` 0coFݷM[U6B`+{Z^J4#J>`(HPJ&dbNuqRRd$ܢc})$$ѥԓgh& k!cc$(YOjATuI1Ǿ݉m@$I(rNmZJ 0aD0ALDPމI:%$omyF\FD :GI8l}2I)Ha趒 HNQ>bgh29GS>a9ҴID}*2wpF ?hH&ԲA߼;N$m4T*B uO() p*p$ @I H*RJPIsLD!Ĕ0J6 ۰8L*A106%[Wl4m+jil!2q- (uKaqJ0}42mزTϖv& KHD IH` 0` rcM,?BʈU6*ի,픷&r[Uu{oT[ž|˗vV[*ZkPKkSR$-Rwm)-N-eB:>G:ѩ# ') (J$#xO&$א{-$D,$n&RgdpAnбF"'NTuIOH*QLx$Kp*#sznygho䂭CPLH`5*${F1wl7dALNA)DseA;vL>ѡd"7Z{1 qliHRZDsjNII["{NqHTIcOp7:yܓqgGh7 c̓Ƞ%kN(L̘jW: ftXzcC|gϭfC`TYuwUVVrJVޮ!;;\(_0` 0`7ff~Q厧RS]Roq>b˷Z0BPQRSNo4mKm/`()nee} ĺ'A[N*rNYE;t )n%oY?%ԩj]>`UeM!j3E] UVSުJd *+Z*%tR]m{IJlC[0ۧ5h 'QjG0&$Oa aBJIBBi$D"5 M#A;\(-;NG<ҭJfx17A n}$.`uX<AR=ѷHhõ26$vC@GasPB[eJ@fHć&H)|V Q$ 48:viRg}aߙՖ-E]a$vM FTI#cEstӖ-AjB lW]PR <,T%@u;fȔ4$Omn]S몪ZuWoyjevz;M?~ 0` 0`j|\VehiUnXs+fv-ovJR-%¡QJPR($;eLKOԵZP;w O6z}kHܝ妐M;90I/cmēR,#*yRgo= CdmvL%oT߾i5:)v*nD=&8IM[mRdyⷔـw*yWg噅 վ$KCE- ΒK$/Ty`$$,2?*iiVh BCvWswRI85 :'W,_X[YG8f uZ*A[fjoznuOpq>` 0` bo#lj+]) seM޻AhL qG^|[m-4񧺰,RT$ykRm)o]W;jbӴӵ56jvV*Ҫ_C@YeDAڊ2J(gZt{,fmWSpbIoS(0ҕ7Tx'lV,S\q?P>OUZ~zh "F&꒰ki)?.w%Db%WSVEl݁ҭBcj䒻]Cg49}>aM"t=#xi H=<77;5F&~إHHmO MsSGLN*5Q*ELLSH'mu!YpV愈 S;D~dKN'ԥ,|};t6ºwjP;nS.(7q6>1Y}1*V;=Vm=/UUUM=14ʏ:ܵ҇ZV!!E-[;V:u47|Պ^,>-6jSp4]l(HkPQWyWZԺ驪: 0` 1bݝrhɷi͹vn}|Rz4 AǙ?עlYʸe\g|"KrGO,s}{0Y*e}^U=pn|bpf8#KOY*-DuT4-Ts;UJn6"K*wȴ۽55\ۋ8C)Jš}-"-Ӫl! [J2UELm U:CͿUN),i&JJ8?ITV܂L_t"G:гI\7YQSJEv%TeA-<O$b+TI&`Rԍp7$j M[ lw["L[j {"LBَ~i$v-iQT1#aݔl.RWuO8b%ڒmė+>Z@rp6# B:]Nu?NNvm ]~_UZqaS O\ZȞr5IbyIz oCWZ+CeJ٫; Uj@SNp˹zn[mcZMh _ș^U5v:%s%KjPVp` 0` 0`Mbfs©nv[i/맮ap53Pˍ7IƱGQu 2yQ|_O93RkQpɎQ+u+uI]B( ֪^cGJJLUf)ED;(g[A % rtǗ<}iFs% 㧋pQt,8:9/ǿI Q|>f퓪$% ({$pl}|x+ t /Z2#SMN OB>%o঍a5?޴k֑$T|MmERsŗJOԫUWyҚ[J%H$ |껫hO|eW뻀4JL$Ġv\7z nuG^s;I)}3C J]ޯyZO|HUdשsc>$!%3\6kuR^eK,:ڈ(>@Dl/wB*i;+jM&k]U@۽uN9\ۨk7TRlŗ9^KcVKF]жXv]I%[}zJv20` 0` 1xmlgraphics-commons-2.6/test/images/iccTest.png0100644 0000000 0000000 00000073420 13777276623 020464 0ustar000000000 0000000 PNG  IHDR*fD_ pHYs.#.#x?viCCPPhotoshop ICC profilexc``$PPTR~!11 !/?/020|pYɕ4\PTp(%8 CzyIA c HRvA cHvH3c OIjE s~AeQfzFcJ~RBpeqIjng^r~QA~QbIj ^<CSU*( >1H.-*%C%*ҌQ2250]b`ndb25*&v\\myx {_- $ZMPatQ^ѭbq[%R$%JUHJ?#*'(wVGGW(%ת[4d5jӚc+J|(#KcI&L0﷨L򱶰Qcjc{]w[cB }.[>`kޠcCn> )mߒ0;qsLir6QUYcW/),.]|mDKEa弪k'5klВ:z`wW{^> &8u3gΚhܒyp- [xǥ&,xUku5`S[MaU{8;~@`Gn>.~g=~ӥ˧Z\[vCf뭯w޼#ǫ*>Bek7uo/Sw_?U. < 1gAMA|Q cHRMz%u0`:o_Fs_IDATxڄ?heƟޛkj[ljjE$-8XDNnbup\Dttp'AEBh*ڴ$&qDop #/ yG9|&'t}?|?WYiffF.LzM6>H~n^;>έ|ջ o&mNZ wO}P\×?-$Exg2qT["CnSד# uw+DRZ!F/7.@ V`D!{2[`\r^ !V!OụP{Vvw_>Ģ1)'(Ij#r0l]EKѴj2D>@4/5 " le$y:Te֭F Ie׉& #ԓ+?WbPLƨ4ka'@P|Xd϶ vQbaܼPgE|ReWWCӋ ۯNyqj%`ḑ5'EISG.EDHP!ٚG.zOAW ^ ڛ*FER (  6;Y"n7b x\^,0}k}R]C1*Q J"A'Q\@q@h0D q 8q#"hw']կ{^S#j뷾R>X4_z]-RNw N- #t;¥zg4S@5:SYtcyG=^_]?g[əՍ{aIm4X PsdE6g}8hԹo;k(C8^ B &q|mwWQ7݂hVؗ!o?kǶ6~Ibrڷ&&$Ju09~K;^>7A {w 'pȅ8ZZYϗe"!co,{Jd4i$/F8uP)L{BJ^]0r8 NL]eunjPxyH;1X`*rI݁e'kG(Ӎij8EHM%ll͡w#c^ګYy/nHmО !kV̨*6+}jn FF$(G:9rMݞNfm4W~`2<Ý?=>hH8yMB2xƗ>gP$ ԣ_q}o<{vI2jumDJ}(͛z|hGB k'2(X,4k;_x=X:vcMZQ-gu970X`ZqεqTD1h.W`&Sn]rC@t=bpCoN!:E`C"tTVsU=+ ,GAp9,OB1B$Ӡ GBnwqg_0 !ІJ7]<|/o$3DI1 ___~yO%֒ksnN&1 3@V)7LLlĀ(HH" ȊQ)$"XJl W}}9{A1T{WZukߛ٬xy%JM,qcُ]B*~:!=3AKJ D!##ct1a7ik_n,>}!oFOrZu͝] o ch`X`k;J?Tԝ[4k b (ÏL՝pҧAy뵭=(}'iU;+ۯV邾$?z7O>sDs7yɧ/ KG/WcaG`*٬՝e0jyуDxc! z&KY,!#uĢ#,(o} )#?z U0!Fd3;{rO>_ xo#;XHn?ŵTTUh90ҙӀ|G~EXD _I'W5^X -h>TP+ q\A,Htb90tzAaۗKsSjfCpIPjfD _yF@""HF!MX DV۾#0G{_Y $% 1KJцB5sAi5b:&)"`tU}goVU`E E@4wfL c@ӡ/Wvu,S 2^.۟]AlmS gQ0U|s`u_<L%K`Nqr)Rk00u5+/cHФ nW̖UXn?ݔ< ߓplԘI`Uda9~>u0KM-x[G+%W91duY~]TlK"̧SHf$8}zYm|s_ĊERĥi8_}}bzk??n&gߵu W6a!,_{>|)l6vз] e8< U{lc[杳L)U#( 9lEi=~UurRc`r =գۜ'dk|R7HD([CvDKI%iqTWTrB|¢Дyq$ݑ 2\RLQAfSff'@gBP!D[8a8ULI V M/ Mb=H_F2 be'@dC1MH(I6nyB01LI{1砥dKY1?}R.kЪ? 5HTMyIm0NR6o?٘^|v6 CdIB`S4_W?y4jƬv.->k<چJQ*[\N:(.7yu<ۨvk*k={w̙imZT.Z\ "&Q%J`4$@!*11 B-Z3Nv̜YwΔ9ΟZ({]v/M?^=$yf*^"Ϲ뚫nu~$'2=}74^ٷ+`0+(v;p)xv_ Yi PrbJ*( O-C%G%)˂luw<yɯT2{L'+Kn$ N'wac8ɛw0P4H0L8q4Ey#©'7{/ ~.BM<#;#xi^`1. 0<7ΪVQPt[ Y`!f0o2(v_dDYMg\MJfͲAF @iE !r1f (r6&]vp` * ;KEDQ|_LC@Ӎ"@'/ &ψ<ԣ@b 6aNVz7 Wo"eM2Bk $+-H` -QhGEs=_ҕϥ":{4Īn9Qd H'`UCn)h曺gBҢd024 yߺ4DauT VDPN W璿7'Ř+Wt`hc=aPYspt A'jK7|;bEVjCl>IT?$^ #gJJƤ=eMhE^_VWk65/ $z.d(^>+oeծ8C3Kve/@dxAN !Naq$.j߷Nhh*SDkNdP1ª$B" \98tR=;EUb[@U\F!!20ov9jdC& duK?6v䌦aՐ"lqS#7GQr '=$0!#p@0vogvO>OO0vSovȺo E=d ӵ)l,ؓ9=y.`lB^n I2e{υewi1@E9X:ɖBa0^OJu6[۸,[!XC=ouA1]?{Ȇq!PBhX*7("bK0r7eo,jRm.^!9E*^@KաZ+j9>QZL{t7ub礠~BK׬P(ԪJ-r, Yrmg].MIMe4\mubyTosx- 9Me"]֖4^֬.ܽksOmsYu'^r|Ǿ,IUT[, 5‡q!h, 1^$z K).vޱ}A'-?e^W'FwEڞt)Uy>gak̨23}'dg5]+UrF5].gc^+_Cy)Ef,Te{h&ȠEj nUZEﲌ1!uUY~ױ}9x"L&IDȋ .[vIZdTntFq4>\&p{٭a&k.^w%?>1z=pLhG*^b_EIf].Xj6T AD\W_{d$Cu<'76d'.& a!`V61=6څ\ V&Bk/ɘڳɼztr# 1$ eMF]`$%Y&7\h>favR]b=Xdfe>mqf[qrVyjeTX;y6ܐPCv7yַ}s`i4KR2CmWbm7o˅J!AZHKWf>'ß̓ք_S{2biRP_<݁hJlEԱFx;\ŽL[ܱɋ^ߟK/8bj,sP^T] DbT]Ɣ<{?K VI_h䴒A|&.y:&Y b f֭oq/%ǝYeA)olUc`!H .vt"\ܔ +)Vh)JBfG> BeBh &"GbQ24E O(XaࡴJ&<$B^+gn!ÔRiZ]0 jN8 V`̗Z璍B [x]]Q!CuB+Ȟ&Zp" F ΤC3ܸ \e,!'H^,>u^4uѾy䅣 zW@ bNX`dh Ot}lڐAϐɧ.[umRuW X h!9}O߶7|yߢ?7ړy0q/kx19Ꙣݧ w ϖWgYX!lhe"w e1cgI@^NW7=ܡK*/V`!B1tHy@.jԮGGTi!I*|0` 3dJ# uG}Ǫ7ggvW J0 iI\ތ,ҁ"&]~-7a@IE-68Dƺz$ I‡wPmM!P՞=lsɭ_0jQ4/]x'E?,X*[ks=IjId<20e *T*KR$`T* / 8q2 W !IRzgﵾ<}{e` Qwk}k$kmw}@RcI_ iʗW~PE1:!ˊo|^Wo]hAQ 5AO0on@w+Kn~Sw})y ބT?7R@rJH GjR7S%%b~@.Zr: wчyL@M`9y Әysߙ@>3ge)@kxel>BIW$SsNSKT> a$? ɳXdce؍ ʊS]"2y@~ʦj-E *Y<n8wݽS4 Uuk?w/ Z((P W/q)DWuq'3Q\ˎNmث/<ӷvku/;>PV+ RյP{f+A=v\J:wõU_\}K (F> <oހD[CvgB^<M%bl;D ^ņ)7լ=d&Z] aY-+'3^)\On+'Sݚ#"oY?,Ep:"0y1*wfPmu2iyBQ`Է/7Rhd9y3>t,-zcEi{V1>Np?r7>iRژnmnԪXŷ z1[^}{M.A)֟E ?T@8Ҿ ˏ9@.|c9`t><f+^eN>s=Ϋ&}ny"* ~y{ZSWݼȫ08W1-}kK/:S0$}אGzЧ{;EM:9mD''b~ ڷκaLlOdfˡwO}p#ɮ\KdK} ym_yOhR'-nt.iz^O^b؞N/=}곷< zGP!!!CQ/@>^2;ѭZOf14tU,ihf<ͮEuOr_ 7,.j{Aj4ֈpdMioyGڢ$ ,Mw8[l,N݌+sO&y˓Y>wW~FG"`k;iszY y9qiJ}Uh 4 eo:8nl¯>|sOOBdJ]fYĕʄ*#[Y\EAP8Hnki(N%^u S{Jq%*W$FK %P:pK^~jYx%AgG(Cʲ@sX e7/rڻn]噧屮b"UI%M6}^G~\҄Td!>x}e.^ˏ?y# {V-D[sTE|di~A !CQqJa$,A3 [v)oZgFHƒIil# ;E +URI}@P2(׸E1d7>47)1áL/-t/|!T =GID]0" nh<|!ee[}k0$9H%vV8t{/Ÿ ^u&zJN͟*V\Z8C5s)]Iy0P{2Wȿ}Q k¦dB PHPHaP^7e*we@>`|/RTJȵ:AhEFrT$K ݥd F9m%X8@ɋ/_xFBR㌣S'JX @P% feo+Wc"M9 $>ƂHHgtnWugs%e99?ƪU_u,yJ\44&HTE>T,liwϳ@]Ş0]ӤQw=#ֈuuP? c*`*}ml'5% D{钢qAMYvMP9|ШIMBɜ.RRΖ Q5FFRByXQAT*eU\)U^@f+hLBhc_Z>"k9=+J(ђQUVݪcNCxFG:gj/S߾q*1, dĈFnPHtDZ+{ptLyHցBOXi#O) iPMk rP>ǵؕ̚R7ζ7fɤW7l[0f1IAJ%K։pwJ}ƜP߀0lurbsE 5/g<kVhO,!tzհ*%}B:x(yQ 68Lpl p2ȓ<׫uY'ZD!VVc"\\]=#*Js0j&|A(5&M̊ACЭ׏\4ʘ<}O-8)LA)鼍A?l9{dwk#"* H@ĒITa" ]Und(x$CMձN$ Ъ>"E( bLJZ-BD%.[&\p]%:@hձ.O:oAՂ f"h0IDJIDNf}@cU-:y-fZR*Z0/ aBBRSIy(`ʵRu|!J.QQOq -7:KE4”mllkռm ?4ъ}> F2Unf1'XB{1LBu|Hɵ7)uS>2 ZP5ɢ”;!z]nOB8a'X*BA0PI"ZЀx?pX>I Q$1@*?Qt D\=vJ P\W9s+fsT c˯=4I+H=,z#4+")C;Ur[FwEîK9΀ly-Tu2]qJ1scC`Cm"4 Ԉ S"uއ,!i =ቅ!FƐʛ["!CzL@D)n6222ډBKm #m;|/Q06hP4C# @@%HU7jI/v74 v\m  ܠrzBXXWI+x)dU#T!^CqEDtO2 "zq1*"f=/ҍCʈK@{xez .[ 8v_) ͺ@CWx:usJ2o6$ a ]cyI8J4;r fԛUUm/zRM_HV]I뼐ҴMuc8ArD&p}='8Y"SRaA'N@7|h|xV qu9"fǚ+G$^Ȝg .@G4AGD'O@Ldݯo1s(d@k`}NzJiqޅ*{'/lkPnMsg2wW.C"c[;pW; G,~%:=a*Q:EBCQUH$jlM^ .{sZR:-ؙwȭSF:Rbx_ċoaXBilL7gQ>ž;G#"wRn[m#EޱwK .æ$ Mդh&ޒa9pa}"]4^Oo^~_D,'`DS=yEDtbFF! Ֆَi=3Eu ]12 &ݪ8=İl<2>Y[S]u<FGcK }WSTPژF(W9֫_ rSbi8DY`dz$YEqp"\Dmq`/V'/\Y"JU{!j3ІF؊iC)`"<.;?5 _XQ{bPET(15USݧ 0ȈBDN+t)S,?_ub58  9/|nz'J'o{AwV'=@*\e_*W ˻׮u3Ks"J.hl|rtq'>HڽpZO/B_-k%XJar<R" SϖlYȿqUi7~== Q[Z͑ 6/zvRqn;*uSU5SS6iCӈ.JkÄgkq1:"P33y:J[䎻B27V(0%!m2=6~?NfQ)2Ҕ\ђVf 9RNj%$< {'C![g z3jQӤ(R9fHK37W@:b&2GHx !IDLL֣ ((@I*pYyPCGoJ4 $ZvG!i7t͹bzHh"l~5X"(PEHRl5.=Pc)^eTFm*M5 +tq(@m `JTV\f:SIT}RUDx3w;H4#5="upB"k-N7KD6f9aaE"Th wh(S} [x|k\ \PKE긌VQcM ll > zqs7hƀ{6Dt$VOwV^u@EsU5NM01ɁBV A7jW[iY).,PELA8Fo&c!TC$n93!@ @[ & &&s^lM*e4]F3$I~т9z E%RCJYŪDQۢ"07w~A( :Є:]6`DuT0}/h@?~qIzoozu!jWIu7!B ^]Hjʯ[!JR35Om|TKsB:vfO*`. c!$SD?HHs+9XY?RrdwDT?oSJRQu&D?*;{W\`$6IF@M'.'WpgQܺ[ l`$8"{Ҙ`V PZq, &F'W3ݣ;]LRIIxG~MJ!jbX ids(ݦoOL*ј2ѤN+K*,2Ku3᷿O7OMXĶzg+.Dv&Pn #7|̱*j%ywy+y ?[ia 9glyn?K%{SO]]['Ozי;o_ޛZy9unWU&E%2"H1,(QGl%0l0" C$' m9 -QS"%&T͞k9gﵾ7?dSS\~wﵾm]>kW/DlgNvgϝ yB_֔dr9K ݻ};o?gC(^-ew+|E%rpa|ѻãy 6MtZ;?\,&AE0@K^DN.:Y(@c@H36>Ļov ׾ =՟8P el&8/[,r*TrҪ0;wѻv է~㩯_V•T!Qb޺oR EKbIT-ar=(@ٝC) 5k66;_G G]p̜}! όWRPf}̄2]qzr4 F̞c JnfeӭJqk'"'׏fs?g@_~hMǤCI C{,ozRpGpMya_e$zLS#ۻ $6fh 6J4 1__# /[WX] ǭ`=N^ e_F&( 3(&ΐgrf#; u^X!D l5G=5<)z|iI<;{2[b_k\O# aXBBó|_|9  XN&d2x Qbl`VSpv"N Q$hRc/=opο=ynN\D^MOqq9OMkOkep,G UJ_@}-!,Bh8LI.[Xi00<@h?u:0ܬfvF8M{v?/Լ&"ॆ&x]/hMFȪ/ gnG@^/<}DZ ̢M;tQ-Ch47=޽{Dct]\# g8ep>(7{|P~rw5dP/??-\7#/Lj&gxdxfThSfb`lb4f̚Hk *#01EUKmyuLGT?2"M7œ\z+ksW>tF~fơjt QNCQ@ow$@f$bOhYd03 Bi v&)Ըmd7STy+d>ƫ0ya7{$ u%:{q/}=8y'?^DTP_F@*G{,Ǿ~2{Q#Pb!Y@cFs/6v7"M&m%> =1aY_ݹ8W~u_x^/<g@~עܫ<a% ;I޷_x̕>Ajlݢ f&1l^~)31ݜis eAo~jpv<£B|#!aԳ!N;`2/ x$"vfrK\E}p#A4"LƊ=ڗif駶`jR+YƄ ʽ|{=ʙBzg_sBW;pl#@ Ts~W9:?6{NtYe@WWq`>T.ɬ/r7^ 2,𐐥XMKl{^f'~"/k>TFwzRq#7eս ዏ? ywVz#gYbhQC !&!)do̓^ip12r7WW/x\}/⛿Υ MM8rA9#VoddI} /-o{_Dۨx溩ZS]C%D-(%>+aY,;:GF޼%Y${{篆ѫĥv9.~l}ݠUf;&\x}v;JrbQʨM QEg%Hh->Ii|%1|}/]j捻"9z;?}~]^Y_4i#& {WNRXv9-D [3".ʍM-w-KDO/._~͋Gd=fP~J(Vn){kAXpʕ3mroqWEƣ,} .V|s /ŜLY`D0G8La_hh/yqI15xyi!mu>ݚͱSWPadb+TXFj]DSޕQ9Ise%˚r!t1a^-4pUNud-Ͳ*Ҽ14G*iȀkʗ Ks,&Xe@ TfEoebJ{pMV2ނ4n99A9Ig:&KBʂ8EY% Ҿk4 //yG0p0!-nM}GL 2;$TQYLn} K"H K%sLF8g].N*0J,P^a1tLe< lE,a^F8f am" }8Vq2$SVPV ϖV$@udpv)3[}\~1c ^eZ/Y,p茽xӀÒ~Pڐ 56\Cg5AH5^?0(+XdFhTBlA~}o^H9O׎z!c ;'MjL /d}?JU<'ֳ[K~D2 dzó/+a`nd$cX7|kXd+=|^Ye6&H7!/-riˑica9CNȚhQX : s<Oh $DkN6Lkctmձ -+Lw!S<g PEkPPF(^^4\. 䲼,Ü2"R N?hs~<,}24Aby`\6n L[B*uwP/^NKgA_c"duxmdIЊ kT-͂҂LN5|v>>mk_oˋ0M3Ś]ZW,5Xmm8.bifn_znYSWHV jCZ 7vH+zjhk&sY6ե|3<s < >Xe@5 y5dVoa h0`[]?C4t+mbA{σE,P"46I>!'g҅6LPΚ`5f׫gܱ̳7 _]|X6l| ʧrN^mJsON`4_\yv~y/Hn/cÈ#4y ;u&/d|ͬ"ܠ_i^E> gY5(Ue;K%KW壣u tf|܌0kɦ2!ĵZ+qq\C}5\Z?VGE7JT5?oGi##W8˹5hŝ \e.Ʃ ;\ WF9rsTE4B/ H7^ANCfj{%U <~WUW$tdd"Ø^5cGUf\v鳅"JXHJ^2X7L[4TP>&n}iF2SEV ᅦU6kˆ+EfJrX]%APnBΎ躐)ۼʵ95ZgFރksbĽ~o@^^T{4QhËoýSRҠ-̄PUB*zdW͒9ȃ#;sI^8/- V/@[k /N;6#y:nހ\}xcs: hf#gRrp.#2eXzK hشo;9i^:{IGQmќb{sTs} yjw@N$ /xBX`$$TCrFZ=ҳ#rҐe7^3*f,,,t+珏KLk.*rZpZ#;7o@x5 -Of!H)seU&I\keHeOMhuFyР2f*>nRrz=7 ^aTۚ<9ښ$daF0`?2"Kp ca>wrPd[L٥dZOsMr4;LN*iѮBDURg4ye|n-sV~+t.zZqà-MI fLLʘ wM%2pz8 n{æK X`"Ϛ1nu7FWOJـ$V3}~{nWʀuh}Ma]?nQp! `f f9L؋h+`3xe;/Lb2C6Փ/] C7̙VȌ\V#Ey}g3+׃4ըߕ%0gwplx!Z-[,EzHAIVˊlcrlϯyZT'Rmo_+\;SGqhÄ( d4:+f'ES:RCZ5hhf3S>dL@1D6nPq6Or#u -v^֩rqu0ιjT,FO`Ua&9< n@^#2z ؤү_5ei'c[' 4V3NǞj6{6-H=^]nŮD$k٣i!^mOcw~J+ K{ 2#N}ۭ\U{`ʤ71.y}{2xp&9}9ĝujcݔ?W| JUZp}jJw=9?uÄxK'Ŋr,D 6RWrOs~=)=.-~2ϖ:j%|frcC?}_s^Ht?㯄ee ]裮| .>zQU[>+,nDq|rqܞ=$)g?ޗ<̾Coٜ0ڸ6=ZDqJ 6 Oݵl"m`0zŽk]V+*?Y@L*hjB)1_a& $!?zhb,K9)5)c d\ںs&VB™+W\X| !ܹy:U+d>'6$>_I|Ӏȃ )i{w3+0oCY׵&vO]*>8܃˽K9Y-g³k |fooFS{j_DJPJzc%YKjJ x;{v/[$kpeztKe V~:5`v mrʐ,=!yѕWNݵst ڸwikӎמZ,~-, od\\jɹmձ=Աߓb5Gjg`Ƚ-;Y 2 ݔC.g :oOb>=v.zߝ_tԨDkI=kW'V/ y,_G/U䌓6Bt/s^.]_[tn"")>?jn |<﻾WӞTcC1tҘr KK7!7)YKatacZ/|A؅u|KJɫK !QE dL=Zgފ)gN>@*]3 Wh֩YCB16Nlkk&.m{'GyzjvԞ>bM]gw@xS썔5! !b4M4mcP}\,E={ToM_PQ+lTJR$ 0GWn Qnm_rͭY[L]?9|w)^\+M ,B^mlzܓˡr8^)4lp ca(kKF~3GË.\;: 㶢 j21!e) 9gKG0-v,[ծ$xL*E<*~ȺݓV"`f}i;\,A+:3+q꾮]45dDpz"M2n O"vaҞF߭d1QGj.zd7x R(|3k1˭)2g9y;k8ؒ.4[ͨ,, ѹJ35Wp20f`6>+ɭPdԂ11hoU@S8 J} fh [eF:FY 4l\IE VL!|oiE&rGW+IIE 2,{%`re̳x 3[sʳy7[3* q=NF\B>-2d8,sܿCrHZ_sXTšfW}ayy̲iVP1•jn^P#Iu9B5K3AhbܸeD\ReleيŹY sUg 8~liL>.Seitހg2À Rí ȩƼӱApN),<м1W1ɪj"H(M{efAsh%B^aX27(Ms1aкnIaK޺'dz)L%`AXՕ6bTJ\ȭL~} ̊JƵ8Pt܉?'nf!CNnY@2ќCCxg@]c $(-i]N^-`aP< Z吡p["n b% }yeLwGYU{ˆZL=8W4WdsEo "0;vCʙ >IJ8=#hX+Ԋ ROz>5JF [VR٘**TQΕbC(Ejc,ݺ4w4t+H. KI#aܺrqhN9&,/ Ak !X(]<ԭ eAt܈Z-} А QASQoŘT0Mu OM7V{ rl|=TcH0{qʽ.Vxp:YU8xʙ:G+@yƲ᣷ꍁ<[S f@Z˶%dݽ,J GΚx߁x ( Cl <|;tqWU+Utv XjI+[A:d 7tS;[WV~q{g@V:b+"ykS! Mʛ! 26m4{ښ޼3O3t̮r-jc)>80j||[X20UgڢYf89lwNRpKrn]nκK]<RRS7 4'Dt׽DsnDV2֖'D]vkyï\/di2gOuJT$UU@i1+ !64 FAa;[3{p~;͗Ʌ.xwAǩ5*B*U7#2Uɽ(P0n}=ec) C\ wKB:I;mW.[|.>snx޻mi<4m!9RԵ^p•(|\qkVK]k,fi<{Χq)^5ާ$fp|겡b(s֩0qcU,RKLBKonm>Rè<eez9 nN#84J}gm&yh~prܷ<[['{Wt8AʅU'XY9H7Vhh:X~' >m VFFHAAMs]]Qvvx~~~~~|||zzzJJvvvtttrrrpppnnnjpjzffjjjDDKKadabbb88\\\ZZZ]BxBVVV..GhG11`RRRPPP!!mLLLokkHHH4f4SS`OO44odVYdNNk{A!!YWWYDDx--T `}}atRNS@fbKGDEIDAT8c`2x* =fO,|*^ʴMoU_"PejVi\)}ãu]c`1Y>_[+f@|ޓ5:9k2 *kkߒ{&ĉg`}X }Yohii3ם=[Wd~=XA|35P-O܃a5[~0tz'9C]9+i|Sd@FAQ- EGl-x֖K>j3: $&:_d.Owόw۴Āh˦Oҵtg]S5aɴƕN"ͲŽ^ e{rM~9ٻ px43 rwXS}o6Ry găw'ؼen.GLA;!wn!zccg^{ăayx' o-:&kP v[ o9p }Y|cA~)ӟq0$k% *Fqs<-If3T`,&cS BC n%:1䁠|[Ȣkyibg`5lS]'{y6pJf IENDB`xmlgraphics-commons-2.6/test/images/tbrn2c08.png0100644 0000000 0000000 00000003141 13777276623 020421 0ustar000000000 0000000 PNG  IHDR gAMA1_tRNS7X}bKGD3'|IDATH͖ LwǿRl0E h D)P)A""`ӉW)!A se"0e!fL4sNi|kɖ b6]B({?̾apΝp޽X4G=Z탑͍Ruu33* K|RSSSW^-++_Hٵ+{2ix.7Aby˖lllxaGf;:p8Y &ɷPۧg@!Hbcc uʝ>>ځs\nmbe!60G~(rMEGGS**'''33355Uan~Jw$))/P(Zv[W.w씝]jP9p}rQRBQbݻt9SlfWuĉ QwL&s- tQ^^s5` vyqq1REEEiiivvTlv {.14G51ZMTR8 73vwk:FrS2UIS!ꃯtTTWW@Eu'T͛O5#w,,rpRPSvAMprrr=xf .e.>%AD.GPFFq..w\)II&qrEw *!*MPĠ%@pNi[[40LAmIÀ7o)tTxkkB]_U@T"cdrq Vlhca͚W>*T`8J|SbJbPvLׇA)ci8==m@+~OӶ288L E=E{ZtA3$x {f<>ptnnOƏ rZ> \n p2*^ o\oL]}44  \cdt31 ^ 9`Xxt~ !HhA:(J/ |DDDDDGjYgjY*dI@m|DA|*2DQq-[4 |fq FGL `vX"vRљ-D( PVч4,z3 {d]IpreGi:^*3}MAm^RH3?# rFGWu_dE1gjmF`˼hy#vm32|Τpads>g "%rxE/9>#,nN χqaG@ ! `M^kGFg A a5B |4Bv! = AB!mTc &-ø0_'DfQ#coaWE?_h `QcPDvCoQ$\8_BB/,{,u-=EP޿8_7 A}xu$:Zb.?Wh疆}m(v}|T)j-xPK~ h<?I?^^=T~WU-_@at /kuj.Zd(xE?)縔uuVݯս}C~Xa}~&?nvkoa&!һ[[_ __S?R8<-85N;V)Pk|5acTڎ"تjjؤXئq4ӈRvӇj_?8U㎿jSlVSTAՠ֪Lza[ 0lp5&9&L[-=a00l!Gkq>⢺X4%Vq2Ci0 & Mc 'jL& VhXML0&"M–M"""#M7iإwTrc4JIJ -- v&a2"" "3DqJZzy7HoU[_Ӱa3j[)CDDDDDE%q 5 nIB 'A:m!O66""01eBlE&TDEL%*#0SNakCIC^I6Hڤ O$A<'kA+u-~h.^'jGE#ٞ^438뮯ӵ^d35GfΤ|D&hXM0B/@13ȏ0x#dsUtw CPL&jjުk_HW=\f~th vRމ3L{˻&lknj;-E7[IRRp.=$'M>0R'<\QvX0iJzJƽCVDD|Yʑ*lw EmӖL)#[‚ py&[W jگ0AISEKKq@S% u-Iav&i}?8|^R 9w"R1$B" Ez'd4b7Ag|#nj n.g;͗Wǯ(AӢB!͙\fٸ.gb<)ȹGchah0h0NдU uTy/)j9ͳ28ͳyv3C.f\G#9̹͹ PȻ8(@͊l[P@칄AаPZބX!4* O;ЍiX-Lғ>łf2@3˳ p'N45 VtXF~,wxѢHQ{ Ã|vF>\Q I[z62xaFњ.Ȝk"\ #``PPiVXWv1ˇqN%o+_ $o} n]]uoֵtǡԾƻUXFwD~g44[hpחpqu!g.ano qdރu~Pwaq|ׄ?_\g'f^Fd$9x'^ˍ?+{Z k ~?ca\NizA}Q^__'Դ o?_?"gc_w_r-"_A}}`w7v{<_ߜpTl5C߰/_8ֶ?k_ͧ 0k~}mۄPO^W_>j_ۯۭ&S޿ CWqx"}k"falk}o^m__moT5±_lv 0OkkTE\CiI1ŦF?UlMlwqED;UNM;q A6!aRaZ 1A)zqZl+TږCICua;J)7Ao_[Z_kwM6M1 &&8AanTs⦃2-X aT)u4AqQQXL&&p4Ւ;cOd__[@ӰL 3AhDDDDDDDDDDGU8\}0 a 8&0elmЈLfB+"""""%jPXL!r9h!Ts; FF.a0D%hG) Uڪs7kD{9ǧ3ѡݤ܆>Rooר믮UO 4uȮD葔>Og3'uv~ϳ#ޗ2ӰhIM:knE&Ǘm/U߃s,ǒ_֩md-amȠ0N>?k-ж;kBKֺLl7>]e˴? `9-cݎj%cz7dcQGq5؝eԹ-sݖَ-wۨw:0[f~zSlbYSjɢ]Ie}Xzی>+IU8_n" zebWfE}Ʈ-KK~Ghů+ū%>|^GoMqT_}>ӺE7eMʫ>7,}έUߴޕio6Nmf'/P:XeTc=lmvmu}~m]κyG)ӲԭuϿ9n;kͳ&]XvYmPιK.9 z]n&ޥ>ȷ;qez>kUT>JuO̜YkY_OUOVn%V6W}c}:N;+ֲ2:3G=ee꺞vm߉EVunvCfk[s;cm+eOƽ->ٱA&6Nxuv춍<G=j=eSrS^.9 i96b鿧v/[VgY`}{uRfC׮1F>L-m}ɤnk^3ޫcY]>,¿eձ+5XgNƶNϴRf˘oSZλeg OYj~V?A}jO-mpe6^W{7SM?jǺ>uܬJ{Wh[~r4]䑹m_h0=Yc\Z콗c1}1i=,zS;3O:4z?1YumeVo꿯U_ 1F,Ʊm}=L[mo7?Weo+-ͪ̇˪,͖]WfW^ؘ$8BIM!UAdobe PhotoshopAdobe Photoshop 7.0xmlgraphics-commons-2.6/xmlgraphics-commons-pom-template.pom0100644 0000000 0000000 00000006636 13777276623 023252 0ustar000000000 0000000 4.0.0 org.apache.xmlgraphics xmlgraphics-commons jar Apache XML Graphics Commons @version@ http://xmlgraphics.apache.org/commons/ Apache XML Graphics Commons is a library that consists of several reusable components used by Apache Batik and Apache FOP. Many of these components can easily be used separately outside the domains of SVG and XSL-FO. 2005 XML Graphics General List general-subscribe@xmlgraphics.apache.org general-unsubscribe@xmlgraphics.apache.org http://mail-archives.apache.org/mod_mbox/xmlgraphics-general/ XML Graphics Commit List commits-subscribe@xmlgraphics.apache.org commits-unsubscribe@xmlgraphics.apache.org http://mail-archives.apache.org/mod_mbox/xmlgraphics-commits/ The Apache Software License, Version 2.0 http://www.apache.org/licenses/LICENSE-2.0.txt repo scm:svn:http://svn.apache.org/repos/asf/xmlgraphics/commons/trunk scm:svn:https://svn.apache.org/repos/asf/xmlgraphics/commons/trunk http://svn.apache.org/viewvc/xmlgraphics/commons/trunk/?root=Apache-SVN Apache Software Foundation http://www.apache.org/ org.apache apache 7 commons-io commons-io 1.3.1 commons-logging commons-logging 1.0.4

    i2Bz $R:+.rMMI Fҳ(ԭEs7f$4 c੖[m29)(oQpooro~'/ /k=_l<k=|+ˁi,x742{ ₅%jw J A@(9¡;4!D)iuoeM*#Qb.Rԏ^D^Է椄Spa*m'!-atVoTƜyWDʜ ɓYĘp&0:604N#; G5{{f={{|5{w;1- K(́K`;b}t ^Eg@9#LtIG g?Hs 9H,n0yLsۇ#{9|qc]88=}vʁ\co"$9}Nqۧg"~t|VF {`v$hu,.@B, 6@Y !*:eiI7hK!7n>@.?iZm;g'MsklVIgmAO`Ai}ulwpfh^e<zXn0ر^kf0k즀nčě`ڄcnZ86lS#ܱHsN$ ol%$lJ%V&K$\z`jcKa5d) jQat2Rv,aP ZGؽЁ]e@a,9!Oba6fsYF 3~ x=o |Ȟ!F tY\p :A.ao?옎dZ}L; QQeJ<o@{\!dl&sfO#358d$zfu RvA;Y'Xǯf K &K{8؇$kidq؇gA} }'0} #g>\Ԋ8\rsW;(S1z^8O%v?'WomXu0 (~ I&PoA"{4(a(FYv\v/iiPΐO`@;+歿A?'d05 Rs .:\MXmxw%eJ@W^z?+n5(JC$ؙɽ x[#ogqtqa;u0X%ᬙTY+c5Pe-,xQP{ -ۡ&g&? k6C/l,73ݷ$iWxުߏ v}2_ TUpU5&$&>};\7ķl#Gl>E'pt^-YÌ:6>Pa2=LK1 -c'H/J1c6TCk+^ٍw ^[hjdD%%ERO |"y[C6Л5ulQ<:( - >;b;xl&6`hcnɪ[4xG|3Z9hΠ5?^!Y`HfXJl*h,Z@znP,Տ;^:p)#@,u:]X,+?հ;^!F5 @y\2~.l{@)82c}@6a|Yfb~[˳Y-.|yi>'7.ʎa-f &<9 /=x1OH^G,܅,܍kD}ȺQ:la޸?50\ϟp+ C7 6<^=_q:PF1CPcl\&qAYR(z!K*)OW>XNI,&&E#0ު,$0$h])142*~ ̿Fr}['K&^b^j徤)d+`Ukd32"O ~g ֨m8UmHQ3Ni'aOg2:0'H.$E~B@e3م2*DBrc߯YTV %GGJDbù 54J5\9V(_ƒZ4:kZ'x[ Ǵ.vr[C9Iy3'8E(&VDS2q*m:)n$U1B[+'2KE*S0ڒxX}qhdm0J1Oa\L+ vÒdϱ{s,Ğc.{l.+SQ&0T2ԇzpcf؄+j ÕPb_[8<4[H:m"1WEu`U|^Ka2ug׋J-vNjFZ'I'KŊ;4.eK 2N-ŒQh@\ v!xYE Z (m\͇)Z .BT[RMvhY:xAqm|mkfIuncImgYlv/.v2!X{-v!ak^F2vA^.OTA=[Vjjd w)ۡH B'j[Pd$V\m`]w ̵Y\V Y{ؕJ5r_sFH$WkZFt=u4Ś:$\ZHwYI l6W#s$gh}1\EWS텞㐤ړ=vYBJОG6봗k>(<hGv ko?.ߴФG,BEk|vemu߫lENs6p5k)c26,Ǿi'mbsd*6]\vF&\fq!~/nswCf0pZ7";@ 5k}=?|Q`Q^4^an=5|⒳JQbKŶP#Ͱ99Gst7DzW vwv015 GĪ=Z5ԸɹM ,#6!TpmXFzz:~蘿^詷 z{wq 8)v\>˂'끠EgpkEg!>C&U;qwNE~vca&7'wo> `@^X>Hhel2x[dveDn\v/~+@'zV׌ 4{u "3AR$CAEg$! S]CI>#Y^ !1H/`hBĠT:Djp&K;\ hu$LRCÐ! C|,꣠Jl+暓ήUFTa2 ---.|6%q %hp렯 (`0AܱUt!_˔ @_{ԋrֆVRwLԐq!dCw=#R0R^Fq=C.]L!-6F廹6 _,Id:f;&h>é^Ra}z1t"/FB^?ȂG+_"L"6g~4 w7Ћ~LN.VS2NSuXw*?#k떹.Kt[SJs!єT0= ]Ֆ;8K!Z_~}9_ = Q{Z_W+o2bzܿpw9'rR39tR̤1j<,O<[> å$*E+|XoI8f[ѮQUg|ggTa9zvG x|ЁBF#0@\ǩ'f|fI"mCp "Zy:$$֜Hj}vX~k_sLy_9 mR`EIG#VϼNV]S^̄\IRDFK?'dM4 P€uH2_7j8$,w² G4lbW4$ d䄛a(m)6贕ЭFg~ڳy.toeWhuF]ӣaN&]7M+HLh5}|jAOv f >*ѧZ):U}aA !C;\¥M{6",U%pWBAl `]#uMsOC:hcCO';6vYik`k’vvxY0SJda0yD p ;%rw6K1 Kl֣0 m{+t;[ pӥlMxs U'W$Ђ.Q+B{Z\ ۲G.ÙN bhY2J{\Y6S]Ɯ^/=+4Ty, &S \50zCM? AHӟƘY f2y _UK.7(ܢi]voAmxN?1Oc91+boY7;S%?d'6L.cD'X.34`7&lͰFe8lɎQm-hǾF{dtȻ~od ?Gg1F7e'4'mFo^n#_i$uF~џx17F?jnj1c|1hӘE9w3"F;OKCPϽm) ->5y[W ".VOΣv 3eG0yo zұ(t Wa(^tq[a;I1mLքqpxށu|]OES4bV>@JHq ue3HƸ;%J@P~DE yȟQ~.(@'7`P9>ɴ`i\%f,3 V^Xo[vՌGg%m3|g00cfvby4gQM~C|z}uHF_OЅ]:-Jɥ+F\nDFAP! ;:4x5KdF7AI]s0$KCp1֦=<6| J^CkȝRNBd("2 ژqDf$53`9 v"]))|za0}Σͻ&o`jef0͘=\b*bXEum.WEb"ڟ wOu~Ic F]4#{ V[]b9; w3]v@A?3EhdXCB Օ0*\C8mR:yQտaL,&U㈀B4tCfzbg7Jm7]@NX O.qݥjtdlP\M+!5 R&ױ4i{Y^a{r{ySPPgPgC35sa9 mNsL6' s 2A9̙ʜ5Ep9Bg~s>f.E?f|lÏfa.&s ̥P.c]l2J6߼UY5(ͫZjvy f^7gnn`o7͛&yy[ټ4!EtǸ>$<~XF/W 88C؇"<&K {ݝ>>3kJFqYjl&,b??}j orBh mwf#<;Pok! koK|(V{A׹1_@V> `%T8FGbq* ULHU<yqTlA<ȇD-t|L=o&Gb)]/ٕGa0v2&~|Ih0F 1sy%Gy6| 7_b#W8Um&i,|o;|-6cc l՚Z"pߗy K %ȋ׮ ]5=Y+k1$ Zsl8T6 Co_| _KT-1!‹?3/LW-^k#ojyv#TNst(}~~>zĨn5HdPpPPs^hY˪aW|{J:`G͢p^=W)%rr}#!^U(#"hrH(k|~q:F0h>; K%D,JKU QX!@ -ewy^h==# W5/RB ~=UA.0SwA7v$6 )BІp NJ!e@m 6ydz'L\2'ЍOx'4wJc X"v$|O+*ohJft: z 9†sD$,m*ᅵ&*==>xZtDGX љg3ƺsXl&/JE_V-eD?V$v)a15!)^M;~mvk;z/;RkQzGm\>юzzQ_awүƺvnwsvwuSj_۽~N0h8ve1:}nvo#o vm6CPc=ܘg0.ӍE{4./0YuvojO0ؓ;=4c=xԞa43 'Y"5{o|m?s_B=vyi/2esg}k_mNט5"Zs\e`no4oכwZ{}}yd>gbfj~`o6?6ٵ´}sbf?$EYc-ٍb,}@{nk- ĸ.qUxSYmSIv#;ۡ57 CnS྄p-t .]1y M w t z6Lb7L:7ѫ R?:jC?(S~kw_Pdɓw8b>vH1aO۱q==bGp;}zx[ F~?G'$ŸrJd˳,1V^hvUh, C=6ºqG.^wI ݿGҍ~+0I $ht}otdBv a-]7+YI;Aw==lO< APK mN:x=.X}z{]n:;ng_@H@s-o=.sCರ:w By٪ a5~KG/h÷n;62 (GҐ)?W`C?اn@Hx aU$I=0B@ԁ_n]w_һ^"B=n]>Bvm`=D_ +k{bh"d19yv?f|-)Ο?Ԛ%q6(^0GoJ>0?M' $MRXT 5MgJAYV̛NA:$Vta>j J& @|ϼ~:RTBF,ՊT#d˯\d_g;r|bY`qZ;F(ϧsaSM )=H#@8L89"sNPLT垂\SJ8h }wãm`?%6onzMYت$꾆FoՆt^*wnr\@Kkbr*/Ht8f_Iov:zc0dW(z]Nt~ͩB3P7x(k瀥yⰆT\CwUY@Qכ?" WOR/e=3Z}ڃxHk b.5{Q A[vZVG TD97nP!xCoQ :F}]D*Fpkt`Ev:IH×uq$=I+/z*6Sv;74+. c |%sޒ>G/kx$vJZNtڬث Ԗ6|ȘUFsrc7߯ Ԗ6Մz ʮǩOkf06#ӡfu C[;582% :'-zH-m-y&5~[I Wx*3  s?ò\\ٌz^2J[i!Z3HAr@VkX֋:ЍA5r.^[Xm5o=dI雮Tӳe]uo2-Hwaձ4f\\"ύI,cضAbM,_́Dr iebm.>RrO`1dzJWNsyEKѥZHvX|v wX4ŝȆ1̜w4^X.r8w lqDhb+l-]k(Z+`Yr)5O?ۓʉeTjhIo2y%P*-XcP qNp~lU.HdU96y.Q=8K8!0 JKlo׽Ҧ2~5x"KU/y15aGmՠ+F2pP9zIr6G =^1قrLT5^bڭCcBjkbHEb9O2T/EkcjJ%+`hjJdVj/ڂe m5f C^!l=Ln])|ѯ>496ȢAPբVLg~0 hrPn8!ǨpP: Qܦ nqr_P')I,ȶϾLbx6= KBԑȸAKOML? [ofF#C]p-L5{r ~OL ,]w'ޚ\_'qRIkc<ܶ!MT]6z1*^s pO\DK~( G|m7d75RF핌ѭ+_R* [53dkK Cq,Y“zjJkdB,WK5>[tbc >z`I ߬HLX[*$äK_  M V)Y y!AC%ʔcbҞ*՞y4ZdmP?:pqHt&nsq~VAG= D֖mip8r3ȡoUpS c̞gͲ?L5gF,ڝ$FO,&dX0 eb1irC 8M)*:a 8AhL"^6-Wj^CLΠZI|VW' :MJipR'q#=SnTi 0} mIl&wbko;Nrcj+ՉKj=u#)m%sd~1s8KjSX֊F}<U3W~Q#~/ JV `&@mj \˦=$1A-2P¿ SEf3 P]QLhs$ټ.+ujΥ;bd!+9]%Ja!" -UL恓yUQnaoTJI-vSr<'}vL/Y.c2CL8^  ͤwXFp*Bl VVmEPjpdC˩ߦ<|d o.fhG҉ŸCҀZ{խ~n&lY}O_YM_+o /LڱbeUt |۠5~iY_b-؍R ͈wi cfOy#59&X? V_+7]2ؤAcGڲ~ᆱ!S<:eFk7uSyEV(N/av큿z~Mv2loTc cDI=ZVKmSٌh\,GxWwu&eϒ1F3iǫբٯi^LoX6e,bR03nߌ~]ɈJc RQ5,CMN_W X(ۍZ, .z8\/}9KrovG܄lJH#"Q<(1Mu_XVn-3\-m;L;8:o Jchp["^ 43G?lSCIWxV<6gӶ-7tH˝ɿ$o0Y9".GdK)2lƉ|2DBBj[E:i>tvh= 4çDK NT4Qbw7yVGUUvk}k ArqkaQ] L38FfK/!#Cs\r1Re{e=QC@Zpx\l@d\CUhXv(ҲʹgWS>*aoz;]~Q.pɮ{TW17&<݀c*k64O{G#r) MQFF'U,=LmwXfw![.kC G!%ݶ~~ӧ,Ag{^feHlҢM<KWJ'9I8K5xÙHn! gz' /zΈi({_ ֗<:NzcaX nuHۻ;w)L]Oыr T{st"fl ylgm!CN&l%>Dn^yu³NABʳ (2wv Nyט6fr2d%yj^D 8!Fq"aօ유faV'(AZ[\Y`1iUNs6C\s/8[8M'e'llxQ_Xw tc_0f  s-m.3+c8SW1gh1ah"y  9|m͇+vs"29oA n`mwT+)ԡPTsEծx;2ŮܝxF+1ҒHʺ\>W][{NY:j\}&]^ޑS .?@ xs_AJ^Oe~VئJ ${\=+`=|Fi)~¬^H`\c\-:(ȣܔw]nEuo0x*YoM8%SDD4zjTbwq/Q\ZBʪzTgjcXaҕ?[T] #Kgx)%bB޶sLmo/^lIx'8ͱxަX|1t8,~V R BW q(X3+6V!$nKZN21`6Am/K@=#yyӏ:Rs8`Q$XƛF ZW!KI0+6,^h,c=»2 UU=?b'd*iT-"S‘x5K,9\8-@ ||r—X'C]*ӔH&W%6(%8˸ r897v/ del0![F5Uԧ#ɽs4 6O`"=%Wk~<@ =`wtm^xS=Cܷpdm#GdImW{ʮ?2~8k#m0~w+C58ު_vTrUQus,NhV1@Ì7g7s:pR,|̫c*s,Mh݁_p~YJFC×YİG#p^IXw@va~ \S٪k{a=_:~ꙉx@h/qpWu%:nƹ-.rck:ЍI50C6쩹WMWN?܀>J_^zkKp+x7|K~G^nl~|.V76T>!F1R%5ْ $taaƃěFWx#9G:b6LKt@:ۯVܲw6<_ţǨmWқ[@wbI9_&^vϛƉ~l=ihո>U0bӫe(Q;8ͯ_wq,Sϭ\oB,/FZDQ Xc،,h`vwpT1mT}W/2@|կhi ҾLbokn1t#kU7lezo8eSjbzr=QT]2pV`NIPLU[ydۿz\gb"p,{-؆@WɅL;yV=PnVg.ᄖ*ʨR}`(z*R;2*6PDȏYy49=0=[t45V~ϷNy/l_p'\Հ`}}w ?`IMϮqwM.z/l]b޼ C桶1Zؕi]~J>|!cIǰs8ɡ$9XƌCpSjcc;=Vl'tt,5ø>PDVj7I\>P7kPUo3V $_6`]&8Q7v '/7Rl.,عK fmwQ쓘攦c|@?ee/κrr=> Pvӥ):ch3ߐ {fh8s GŀPVmxejF`_>L j_ެ?XPutK{0۱[dCó6TQk>4 Qz>_w ImX@{^7jً߷iSS!Et}3:EI j3,c;<^Cdb+sHEHwLCCV(D88x9}@P4fŀ),[NaMw!GB޿739UDO[d WvD5̔9ӧRwɧ[\bhq .ĦR`cM UT'EӴZt΍Isd;F=t6X6B{,@I 9 &fhAvBvadAՕ-[kڜ$^I` '.6L&O0NYgjUtLSq 0R"ƒ͌w ƍ}z#?psnsyYhmaWR;ҁגYѪT&PThO1{1<|jѰ5J[Y ]P^FGdi{؀o./O"S H&tS& NXFVSL> Z)`Ad( uPkHޛ>`ghRo2{K19-sLř̞dzZF͵1W[Li@HJUSRBRG&uP/J Mh%NifzB(Y iO9L 8pYMR;PRxC{ 7GU',:Xb?8PN16~3ߠ['9q_wD=twg2}^z[E6/H,7tD#'q<&u˓*+Rk=+ 6eC!82X1Z+*SkKjpܺL C,BRK=Z.W,Öcvtmrw5H36ٝZu1[z4y6WHNHwOl[OJ KɝY&䜂jw ;uFEA9d"p I=*:V*ngѨ.+W?\ S!_gX)ɀg y,h"=| ЊP<@#wTT/e̸iwC\ q2Eӡ3>}x/| x$Mh(粽K~#V"ׁ{~%\2~G^O|H|\U}_`pd8XGwn(}>BWSvb:jIPgV)gv.M3bW@)rˍQSnuōu:8l ;ɝ#Z]vaiLX)(v;ѧ?^ȣc- *:IJӎv.w]eIϋ\^UTҢ(c8>N`+ w l\䈲u8J_$Sh%Chy|@$g(;4ՉuܛE2:Oˬr!@Sa|R}#e3`2q]24 6Cu dpNiKw%Z#;),$z0k XYQt 0pP& c{<@Ẑ:.S`bAhEP4^ 2YbO$u歌mdjǏUgSf%)N A% pY؈ [HWupRRLxC(͚mBYN xEOӔɌϊ] Z311AE:+Pءtۍռj< j?Jݱ+{g{IDjT[,;W ]i E/~8XWihomݝmy~'"Cn NVNWF h08͇̤A7w)ۥh} ضՇ?fFP9(ۯT|W,M|>HBf= sV%FL<5~|s :DhAQ [&1iU !C?6{۝AgA5w_iM-ߠ83Eea+xH+@E&EGEw?>q *񏈨-?1f>!~A cˉadsq\=>~/kTQ|mA4߼T|KĸfǝN6Jrf@7_߀FݐwX(=Iy96)Yӯh:Uu+od&mcۭeY>a> GԎeg1 0FY,؜x߬5Mfls 1vO :>6fqp+-z E9k!+| &` ZxLVkYҼ$τ/ k_X=7a+C(IX ^v]7锆bTX>G:8we77K''qȉ_Vgoq5|B:Ӎ~o˻r{dF.va1DIFs^.NN8DC#oz2dju5xȰ8YKS4- _j˵[v>FyuJY_%OØ1_Oun4J;! @nҷU5{;M&wnɿ-N!댯͗2 }Km.AY/h6lYϚ_yR] Ǿbжa cGRn<=MgZ( "mf$p} +{_" kI] ^Zn8zvCh|1:Ro/5SD!{=#&xL[D]cϽ1wK|̮8e.+{C>̇dsN}f] s8Ejb2ӮJԺZJGÞkv*pHS102͚O+4ن uq<7X,pj^_s;g`]1RX=Qf rC&qʒ)Ŵ1r͸1e* *S7Jc84V~e}g[qDzO7]ՋNӎtSDs5%|S*D\oiا\'-*2y,at*:1WAo WWF;lj_0Dտ2φ^=^;7.f;t[ `.cw!__QEU7C0c4L M$;I>=;S VERhe\1} !䬩C7ĘuitR)4<-j6$DniH cDaQn0FkMlIzh).EۚѣYRm-~AR L5vt41F4] @,J!4dGkAmmܦW)馋)1hbږ]##~pT[5 -ݟz`*;_6̋CpdEg湴Q?[JVd!3_B!Ş#)@PðnIFt2(԰PL)RɝThY2a[YѴ E6tl(𢋙~*ؘٓ6 K-8G4,Ը9 !%xY` QLlEm}|%6?9t6QB:WG$~V >viw7ypL拔rQGPbC',`_3 $z. 4=+rOnh @i:cABgyVD瘊4qr@Y3 W<ϳ X-e.Qf9=#=^dc#LA%Z#4P9l!\ÉH 39vw bڋdeĒԱA_)?ѓGJk3P.n^ h+TGv9KfmT+XN3n\J ʠ.3l޴J83m9G*ۅ4S fGj\HΫJXEr/šg XbIBqibpy>Na0=q~ud4Qcd~B/' gye]ŎXsILVn[6NV)T-pAgYSGo1.av̂,=V;nIِ,1|n|eMrеó;S[XqpiDCgII\-Xt*4:)Hj_$\ V/# FR N=ZimqjO}SȌ|keVИOcI+'˙%ybVs9 s=d l"|FXyQ* e3 r蛰lv{AsZ3nZ F:)ƂgO0ȑ ̑w̿jA5VtN6/z**4o'Oy0K2G z$p -cIAjY_~l}`1hS&?\g)V]{tU"\љҾ UY>ДCh-(+Y[ň*4 $7!dNa!mܕq]٠[`0 s@2&Nr%Jt9PBCT'u!ce %MGi&j@flXteMR5M^~x}hSDqA~\hFX|ͅ F:/{uM"qy!6׫܇J&7OnsoXK-Z9ڸO:k cxI͢x7|Hp0\&h!MGl9nӇ|o'-0(Wgm-۸ 4b!W` suoS!;?hP;"bf1©U/uTA `^{P$46Jߖ ޟJkKW0*8;ͽnCLēY]ki6 N '|C6`(w_("6颿7w;:3l-]DU1 g&cwr.t'A Iu/%R-BT@|"mMi>ki 1"-&n( Zom~Ѝ-Y#XkٶDK ʆ䦲"# *"Vk! nM#%gLk@_Z4.^6jcU^54`RzI]-\Lղ%$7^fVӇNBB &/@D5#،EA1ݣzR]~=\ԍ7ɿGxdk #dtP n','}9>BKL_ X]o[Ǣ 燶5D^ovni#a]5JQWv#UV`Yhnsp;xT=4-gkD[S{ݺnFf;XjQH썵4z®<÷m)WJ;qO"h:DP=9vU@sU/GLPq] 0W<=_#tEb.q^ UhZ|}) E'ʴ)X:2r/;?^K6 J9bqy̧>-~_*}ć+á 6ώ&[K-%`/ijKpPuD^se!nmFHPmPRvmS0RC`Jl;Ceeםf:^O]Z^tdkqE4Mti6{챗<Όy f)%:gmE\ 8:я'@pd3cc<<|•RP5WNRD$LA^ㅏlayJynH^`F.;F6:ԫF<< ,,qÌ$y4/Vcd^X ЂHÏd/Bc@ ,Kz!K}OS !Fh'3l*111y62 %JtA0<#q%Sdc#P^y} VKr3ϵ?xߕHONa.l53qrLːL9XpC8`;u0s:I@S :,s@n>-hyx+Zb YPq[Ym_}g s(?@5v?l-j*޾D7=Vc jIDAG973'\hN~_ŚD>saZ VknNIwJ$!:!h:}*OyU5**;6PxƄ\zz.|(ٓ#!$uX8LG:`E|bPG&5C^u($b!JQ EዻE-'?Se٘obܤJْCAGEݤk ̆/Y!|J6&,Z飲Fl)VҀ߄ƌwd^ΈʊEsk(%-~xQ ёzhBFOHl럊Ӽ %ؽrs#fBx!3>TR|Bf {q)#}zJiOJX`P8/ﮔࠃNi:Tye*S>TsNc+CV9D7љ !RlJ.:AټePiPK )w:;vҺ org/mockito/asm/Opcodes.classew|e%!Hw`!zc;lf qMB`( 7{ATT۩w^yfv|}wޙyJV#{z;jV-iYYֳ}UZU/kYRQ.ko+W%ZłVZiD|ז`~<?L?Rsx*ŵZUx>KYq` 8Z93)O~̸g&(Y2 *)l#E ɦMcpzh c[ ΍R9'qR|9u7 p3`>k˴9+WXgI#N~*8Q/rxřO1GOASv|1VPִBULfGu2 [2/o0x9kU)Ǡ#2 ./C95{&e*ѩ(*ͦ_%l/M67iN'Ah6+;ģo»kh*Zzӥ1?kX4|8VCe[eJ+mԱ3^/|5Ax1q;oꃸxrOX9>WP}wS}PkVR}_KAKAm>Tk>m]kwzqfa ڠKoi$mP! *|6b uS7ytV$N]e.yFA/3YۤLڌ[~$N,HGI~N5ez╏p]*u`2y )ӮxN^/ f|.mĔxaM71F4o1<(-[÷ a_Nz%)yo۱ pۺ:;i] {G젪t5.*AoFeWiSm팩y~;\?S?S^ݗkZMx 8@^kiB*ӳ=ՎJWUֳƒ03#£gBg #|.|^cχ?EQc __*|<^ <OO4 ,Ba aN iEsT|p#M7=y|fO/F摋̣)2y4G #zUd]EȺ#zMd][[6pCx)y /W=Jk^Upjxu}amd_XG"&6.>‡GooMv;ỄO~ᇄ~~Lq 'ᧄ~>.|By// ~~M4oo ~G]=OŸܧ?Vs煿QK𗅿UkׅS[𷅿W{PGTgυRWVw#?@CZKRct9\!\ W cAƒj!Pa#Qjgg +|,E>F__(|,EEoѢo[[4-EEoѢo[[4-= .<)< -|9,}T>E}EѧhѧhZ)ڂE_hїFv<pnEao腰/"X:AmbvxpTFE/h/h Z FE/h/h Z z-^#sM+J)\rRo9QX s2PX> +8<@a_q1päB @0h.E0 BZFPK mN:Cp @+org/mockito/asm/Opcodes.javaZnH}h̾āH,ۓP"iuB^x_ Zm"(cv}yi[`ntݚ߿}3#bl_XK> 9~K̳EV:qfkvWsF:e><qƸsm',Li%Zm'ۧdq~HbY ܥ\϶Þe[?f-tNwXM&ٮҢHl͞|(~$h̞gErR WI3;.g}喠im"wQo|=!T2DZ:+y4gKPz˴Ŷ[`uU%X_uLJT^;p T-n:p,l!d˼ 5;9fnBXCW=fEaIZG:U'Qƒ&:*+&)%zʳâ6o9M1dkny^tk÷|7-n؛r瘖05|<`O"4f}V0g|:s8( :c'2{a^>!^ 6u)l6~5F ٴy= lf!GYϼ@-<;Z1xue! &ػv-H(s1r,a6lr7 f֘{2sAԸm ƑoMu&EA4 BF.=$˿c+/ ꀕ@P 00|EGnh~4 _KM"si@ߠbΣî'-1UGwr#fW_~a!7~j}@ :l'my=mmtBO!/oogc\f'Cܧr1[E\e^u\8AhqPt6G/-ړqs]:W;Qny[psrOL 2( Buw%1킇W^Fj?1.E݃AuD篸C"ѳ5\h6NZvr) ZBy$ :J#i˓"{5L ư!w랽>lP9WעFVގ<ϱ 2CJ?=l=5hDzz]&pq ّC˖oDe;f9"mJ(] )(yJ].ty)E6^'wn+Vզxߥ1Y.>ie|^Ѓ{o;ݐIo^T+/BS{[?bEx)X {e9 epu\=y=tIM[UN O:ٗ*k,3ؗqE22]K#nr^1 BC@4~ϛbެ-^Wt_迊mJH%BT*D˨S)x0j_KSm{c Oa}r Luٍmkvc[ǚֱf6u큎5=бfԶ:֌@ǚֱf4ժU᠕EkH)]f )˨S%G5Tq )ԐZ'ev-dאRR1jH5.J{ ꢩĩi?œ###&d_d_ǟ-g7ϴ?g6t3d_}d_ǟ!gHul]NJ\-LQ$5LQ)}r`Jr ds%59wV( ~ųP ]TDdBR:-FkДpk߅€S-M NcfTZM]eNB]!m+BԑBQmB[oM Q8p*Du®5\KRB(5 *DbT Q9&>!*ATAj Ԑ&ī&JDO(ST DBTKחr&%7]er2e޷I@kX P)URB]RC=P[P5PP5P+CJ݁fTJ4m~@tFu@cdQYZfJ}7a["Ej $b;Ze})֨ؗb#֨s}ajXx9T/|wHbZ=Jb[|s+[.! WBo GyKcyw$xNޔy_FzydٷFj0]+Q[$kN5O5jHB)^Zaޙƿ1}ECUIlaq!^y_+Uw.18{)J 5PH: sݕ!r3 rk=W<4zPL/w9T2瀲 HP" I~&bxB!03,rnſ/֓&z"]unETuE&fʨn0Xw,5C=f)dф ٲk}8M^4b`h%dKU]H-^Dd֮*'Q/ekKIi,H֤|[dlk_e4t=݈{+{Z{#_ ^˦֦KGZv/.=Z{v0ς̙nyoW\#T..jOzhqHh<o)h3ޖΝ/vIt ,L2m1>qJ$Wф-T8>w(Vs'%1X)̜=V!#c3&rDXO[t[}j|؋}16N*,G=vSJTŻ{=| XK VaNrHV8G͐HZʧ2[VXp:{LPmvB2Wjx?7*XRfiFҸ)Ħ,~M\ H_g!;[Ŝt,k2Di1fI6Ej㭑H"aiFYm'Z߽%!ޟhuEYSht@ (4<4G<+ L|J'O% ?3|,ϐ̳y=ϵST{g̬ x5ϛew\ىy?lڝk-ೆ@1 ϖVŬZ bNb.3G(wa,ƒ`0 _dLџi7 $; $;3iZ8=Y9⬵ln2 8V.Y XzB4| N_B(cy<~!G6LRl+t)`%]iח -/ln-¦#~p &`cvGK 'Vnr^1>kuG:#'jU:SC3]/(af_ױoPYob9ޢoc-a.6c\oBXZPgr59QqwԆQ5cζ <i8q[aт<=wQ4wFٸPIQ =Yb1֚(|*&;{RęƎh-#B @JYCA-=K {m ȑtDc?j%i=[=WFwog7pܚO4KGmK"UBTRSQy($$eG'޵pz}.q ۋvI5CGm 9[m#lKK PФ= NI7TP ئj3WKjVVQܣ:Gu!Cn1cij\Q.w*۽.hƱ3o7s=Ws= {^m֜nAUVjeeBȿԜeTe8fv",.T Tk^Ih>4hS9V@-:]zt$L\CZ= lܡN}*ᐞúz/eR;'do%#BrO_ZeS/&)c3RP=u%< Yae =j'Ѱ޶}4Ms΅dcHb.'Tb1윳upz2Syp "ho6 ŠDax{lZU:___DV7!jtbN}d-kXֹ,ҋ5aSMYה@$l sHcؔ^F"+æ8+, "rZ^aS{DN "_A$ÿB<}uIO1o? qE?O;c~_jɆSFYD\ `8z+_a2,݇jy}lhyI9%Yh)ucU8ǹle~d(f^ WR-TqFa6-)\Nbg^)$p71YE'9]a8[ 6bw>l_JVCy-y;H\od-/؏vs+^K%ʿp>+{NSgi)k>ǑI9|8sc Yhn ՌOꘖ1Li὆C (6 4`.an 1FBY;0*[{IT +I,sY9a/sbNŷ+ PK mN:(M&eorg/mockito/asm/Type.java]ms8>U0#Ev2{;wxwdE(9qh 9D-Iٛn$A)GnmkFIӍFэG^{xF_Ix9YxqB>zY8d&?\E-C}ap5oҚwo'bvCN#o5dB@ZrQ$1鼋1q7 Ĕ+΍@E-y;F;$ f?cwQO:'(#ჿ%p5(f0H{nIT, h."w#!*L@?&"NΙU(pyWXJjIE7 3ICxESy8,*Ҷ;f @8W?k7D+c ߙ. 4y)$~A=8tWrCўF!9ܥh: 2L(`l]-\LAqH,xMghj@Fhd+nnqֈaLlSol}1v.5 'W"}jl83g8.pw4'Ӊ7^\|;<썮r]⌉}~18{mt`>t3!Cܞ@A JJSrnggړ+Ԟ)0쑋xbޘ\Lᰊ{5XhBܳpXid p;Z!Tx`k"AaV֯ԩ7.wVȵg { A3cEwN;=q'd:0ݻ[:.SԵ:eC4ԵQ\5O/&3ڇZ=|XAa Q=:әGi '-'rQ JH%#`>uZ m ٜ XӁtd>% }!k 3Bw?M߭{mwξI}\QB~qxnD0$>8$^FGbA咯k%bVXz_`JbR#E}wgoO#bE,N͊& K@oht*esm@+h<`U~$}>._-M\,.)!gdCK>!= 7aPok9NghF Ƣhrw+ 11[k)3.] D",۹CbAݵC1vng1ZA( \6( (D)0!Vw0JRF#+S}N.P+n澑[C7e(pof[Myí0ě5,5Z4s+צ cw );pfp̪12cNŽ53,ƦUM3lʏ G~[y@O}g7 ^c貢 9wH}lnY+eA h @#X{\ }auy81N35pi6nֈ3$EEl.ȥ9[%k$sW!Wt@gR"2]!c~"oNR ĘbL*2S_qan6A!]>|S)ڮNEbCR)u2z$J}Տe1Ep 0ZVN@-S1b{>G,g)8uGc PC`EŘ&h3EmF8SǷ`+\`A( 2(q6C4/D aw Rbn{Ѵ.p~b#tlkquXZUU,bAy7 KU{Ti,]?H:.m$6go{ Qoj}>YP Y׏/ұ_xA}.1ح"M0% pU/|+nkNx:[''u<㥩b ڮ#`Tl--k,œSkP w:GBJ(_!)K%߹goeLjًn(#3޹𢅱@; hzYj]|PwO0;qq(L?hKjnÝP҂0VٓϢkl?1aiO#n"}1t*A=TS sPH]zZT%a KS&H/k4fuVyq@o~Ijd>hX&-Ǐӹ?wab%$E[G OH:^_|,B28]@R9z^2R#G\qvÇb X.yƯ's) bܑ( ' Y4Aj #P)`B΢Zf&g+?|b Cr a6?lWskb5J: l7<:nᦤDo ĝjJ: |י Rn^'<)SSV3v sWn&tVuk^]~⠏nIobB>5 L"nDׁ7=eqG6&ci/:zX,Y>ejy.8^qxr}b8G#eg XQPCai4ٟF֖v ( 5TF٨vO#Tr钗ӥ 曄O5ZhcS'"(\qGxseӹlOr~Zqde/ʦuӣVNɫ"\.ԛC yf[ycIstTb6m-Dj{P.q\aZK^Fs}T Wi4mm=n[Q|$ ^i.2 G#"$i$;K\/=3[nBu.Tq ox-Q5ѽ VPu/Cl dLwKLu #["2 tKLM!C~R~Ƞ-AuynJX,zb/Wj"ʐG Ɓa;F|/EADv2=,^ҹnNǛ_ͪI24CA 4S%=UnV^y8Or85UJw fx}6j+Vb9f Ty'XdNQɿEնGѸkAYmIro:Dž[f5;7 E1 )k|I"ڿ|lfT( ņ=nl1dŭ>76}\;LRW4sO@>܅z.yLaStjǪsd^st"e0 &4_|^GBlV{G񄏄v 挏6;# N pϼ ҘeTT+t/yW}pC;4V_95V,x|%hx@ʒ wH)0||RC.]<  yO4fnR^~ټ_I6~-F{/|Ge]ẁspUzKi-lqA'Up?-dS;F c쑏g"8ۋxsoW/قR)aE4NoPkfhcn Owz!|K[L>=*hʿz#DqΘ5 LQ52հ7S!0 2[2tX1;JN_:@,S34Κ*Q.\*~Z(szccwyiFxY^5{zJ ͒ : ݄ 'z#Mdx߫0T*5i:}(ODa@UF4LX@k5@c¦.b47/f/Y,wȝ@Rs'/Mh|t̆[>EjȊH"{t2ċ&&8te8Ίm =눕0` +% ^A0 YTD\U>q4P|@-@£"pL 3@cRr?W= o(.ǫ "+|9-nCv[;=2߫gW:Qdر?2&9SSjIe 6 m i6MY0ݬY+`.h[F9py c^PK U[5jorg/mockito/asm/package.htmlXmOHPtp2 IsZ'1l,{S6IX~~ꩧʜ-Uq~9C%?LdDf%D\~fOt.i%JVy%VQW_-@*X!;'''q]T$YP%de,seJ61TIFo* *\je p$QXIJ i2qtK%<۰AX30aU0}$tw)t'^2~1mGM ÄS޹Q{6^? /i$a##lL&8"ܘf:߉+=; @@Y"EA8˺^zEfuu :>;z"Q&[tY~]o;~.7w>wxmԓ;k3CR# >V9N7Mݭni֫@oֆDOSrЅU9ETg=\{vr_Z]t}5|_EUXJ;2Y5#OsA-8_w.Yn)s̹}O'vp@@vh vJ%ꠛ< +>xTJinvbG?mRIOOyaȆ"U!7C'Yڗy0jkz?`PK )w:?ܾ /org/mockito/asm/signature/SignatureReader.classUmlSU~N{n]0(S+ dcU`!Џ嶛HPCDM$ʆ1TaLh&&jbbbbe1a>޶{ι9sX/X&TӉ`:֓T3lͯZ4Kɞ`s~-*P1h<%PR%0i\5ǒ=Eud,S/^_p8ԉ"K` %K T7M9~OF@;XnDi0%{2F'ܘ@z=)ވ/<̗GKvilHDjU* ߙ6 ̑Uqbn K*ƔPmm&;qJJ^ơp\MS.o:rji,T=I_7qdZm`jtw 6$~ՌXXa3B2'Vp(fFI[cbwU7\rp U[4=*D(oTN4P#)bW})RWD)aʀ@`:uNa٬ q ˫[|d 2nF"Pn@r]cjghINj S{?7<mB{B<7[ӟВ':LT73`WBJ֭`aVp+J6GmS:KtA]jD9=ppjB9Q,ѣ]"!TjCcdQd[vyj/`^muAgXJ˨+Լgⱜp5ma!{6k=qgY|Ź`j68V!X+§&|!x_cFǷ%|/f4aPK mN:.- $.org/mockito/asm/signature/SignatureReader.javaYKSHwDmP@wlˠ cy%SY. d! }2e+2|V89::z@wπ#!^0La~e & ) rD"Oa yts$ 4|:== 6u  <.BIE9rG yȧmZ68d%eUA9D !hk$9fNLx,B$ 2 9KGF>0 K6q3򱽆.pRfZ"0K|$|B L5$1ȐUX(XHZ >mBA%dPP 4XMCoA2ߝ[B$0 Dž߈sY߿0Bn$Ps?Q T%"3Db"=ÄSеصpg?DE}xo#pl0G[hg/5@&0\צd`ms+X}6s`wRft$ukv݆YbG*L;kF(csk[C&*vw L躤YEC"́`fN}!_UcgH=ZD5{,nm㚠[}wtǮՓw 9 ,GoJqu@lrϝc 凮akZvq{OJ`}G^8fN&qЊ]LrѨnI_v ZӭԅCD1@ѩRPk`Aݘ?mp4p3^.)rݒy2m/ڱXwߝd$K",sD`XJK"Ff 7,:X$NU+[aG O5#¼D'a鰚82ۜaI?? ͼ!};8QX` ˼5UӬbO"Y::/dNJTm_lQÅ%Us'Fm4uEյ[:P:R77LB"-2w&wGb8"x5Q\2N5$|st<;KU1_-lڐRbs -E(x5ɚ|HVLHcE.#y<'K٪PIKHch2;*6k5zSi.|6e[ʭgߍĪ͘wcf< 1|i*QkeKNJ6kcx i m@C+6R69c|P5Չ\PxY7*cx۫.?[l~J[5?S5G{ 87IBMʳT֢}nX$/UۛYsS]̐:" S]mL|I;SI$\𦪚'\D@$,5I0GCv'٧p+­zM,rN$l~O/1}TTGpq P+VRز:?yYfDlIAR<*SeDdwvbx OguNS?mOO߬OHKeiAXgzOzO8{O iYvA~9Hv;[ue8SQn@Uޟ2Q:8^DF%*uUGxۯ(OYgS6^cլ-YoPsmft! PK )w:~:g8"0org/mockito/asm/signature/SignatureVisitor.classRN@BSJOЪX=HH( " :ZQy}MzjO;?}s{Y=$*XyE Jɽp4L V6@={d^D]y6=1cFp;_B50\׆|$4˞Q>6A/KOc~$˸Rt.ᡒO{OYQ奸#t/)aZ ETa9229š,i6:CTJ5|X%x ^z7uVl! |ە=UiJ4\ΨSˌ EuLb\ 5dica^ʈ/P߲-,@38lM_%-@ W9\w`vobw].PK mN:,_T/org/mockito/asm/signature/SignatureVisitor.javaXKsFc&9jٞ$q 5p\I{g$ݭpwK=8'|B?B>i SKZ,dPBƢ[d)JQM )sm*(r,55)wbV*Qq9Yk- 7hBh|e~7B^WK8pBIl_AEgQ_QH lLN(^U8m\gfؼ[/`wd3EjEKuc kљPE*7/T[[oa]ffWy#њ Q\fo?3Ԩf^+Zo%-?3>>]tITϥN9L=m|$zAn5M/PK )w:]W /org/mockito/asm/signature/SignatureWriter.classUkO#U~O)Э-EX/mV, (ڽp]8iiSv7K\MtDK4~PMM41jF9sN”Mszsy˭4iSE3{I͔Z.zP튥2ղۚJQx]PSȧήkY%YˈQ$GeԴR1KqdlK7\N&iB{Q6ΩZԀ6Wagl5{ gLnO>_R(D Qo}V R7u(#GGtՂھ лxB̉6 nҿCXGS4WtO=^qS2}t?p9QF8Պ_ q Y9xb 3Kx _M-Ncܽ9|WٓPj0e/"pqNH-˨+%W*Ɣ{sI0poӸ|q'Xݜj0{E9x&W_CqqAr qU.Ѱ 8CTƹy >eW;A rz ң{ yܵEut-zm=Y#rDkl݉ 7ޢAz'kwT9_mj^ۡ;8A"']Ar |#5|+#LjθmlEXc(_NQØǛ7 3oVm\<]&|hU߉VW7h n3!ΓR y:w(X8H8.={fOA|ԕsZʉοTdEj~Cs?P?qvڅ^ޔ n*s`znLڹPK mN:8$.org/mockito/asm/signature/SignatureWriter.javaXmo8^a!Nu܇͢$\8W,@Kt̋,\ʒIe2<gd޿p‹/N03&0~E3y\ &ĽҷFOЊӧOϿyspy DfWcW}' @$Z FB%ˌ#3ӆ{OAi*rkf9̅< ̵ 6)G4U2XeEƚ3|3&R"򱺣B ~e,8EH YzWa8r&U 6ˆ,@I2,(1r%OR~odIxBڅ4!À#TԮT ,g-!Ҵ‰3cA,^Af*Pʅ%%"h5),f.b 5\+)5YV1#k#:g!it.`{{.u#8}7E";~qB\KH8x~nDE ۘϼ6E8-Z\ )\AtlkE;E b `8 ~X#}pDtsg0Xc_yn@VvKctn Y"blPH9hC8t{799uBN w.3ڡnSo?Q7X4\8>tKscom9̠r8(daA0FqP%}+Y(\aG]ǝ*Q$!؋S/5 ؙ\ &G$:DW6Aݶ %# hFa Q|6E߿PFtf*p3y ~'벤߈Lh7f9G2X>,4+/05DS5 "[s5xWUV-)b-4Vy*6.(&TRJ*@Lp]Ur!^,FD:òUk e4.&p_noΰV39Yhk(h.a-J`ͩ]h~1:dBxar0ǀb.:ZGeTM9\tDǵE{H1a-cpDFwQeR8<ռ:۪U9CWСSZ5,2j*p0_aȔ]?cϩ6xxj2kvV$fZMevq̘٭}}¯YdFrBOx,Ɋ wJ&e*#XLh{EsaY+c-0(&WDZ6t|Wo{e18:^pC[˶GU]Bg6^dUv?-,jgê'tPnjRQWd^Eزn 8k=g?J*^ѳ6'JLŜ&^lY`k*k|X9xacNd oI){|8ZKVa=x.Nh'ЧShZOyCB8V >mdǏK F4N[>j^GrcY%ϲgm\4 ^O. ukgmTUz| op2%ej- mF0@h\w>qmp5z}ؾNoKYS!Q}Q`In<(wla[ɆU[+PK T[5;]&org/mockito/asm/signature/package.htmlUn6?L)$ݢmPh YRI*^iNJARv=Tlyޛۛ&X~GN0tmA :*؜FCz?ΩNYwH˫;8߀fN[ RԍUNAnA<1wfsà0؃C1B;!7_k>t1;PN^x;{4 .m_`kƄ!„N/߱.F^!݀6E֛N0 "`y%~K n[e:SG*Xʖ Fnb1yjwcQ߯PhC@Xնv x-1~0B#N`<" opWANFp0\⬟?Ѡ[0jk0d8npQ1 L늗,LxH!-5gEg ElZ7> IT(9e3 QuƊyE)!gK&1LI(~LrK%S35gL ,s¡yU.H̘Hs–4GX3-$ ,gdӱ  W)4DES+EM_Ve!_5bddI(8mJkNz9@ d-)2 ʟYJ"W `I1`BRJ֯%`z /( +:?b?X-(c狋BIDźh lN2 w2X~Ev,Cvj``3 3 ~ cN#2icV+~o4𧽆ۛ?ng]PK )w:[3+org/mockito/asm/tree/AbstractInsnNode.classU]sU~N>&~ P(-E4MMR4&)n&0?./qpk_٬vln9{y?{_Yޱ럘;ieLZm`o==Эtvר;ս Bj\j 0*Lb W3D+kıe5-$!x>WY)EaZz!YiDC[6 ʔ*E-WP+ٕ<&pD+و L׵)62Rfr)I05Gfu2 < ,Cf2i 5Y&U)œD@ZADUfۆS *i8#35)8[]Uʮ2\^7Lbcp[UMAk^&7l\IhnuAߏ5 Fy",\yq8"ౄ ><ۓv}pg)"Xc/ %\ʼÃS^" >I<ç_>|e~Y/+R#Z|LTMXg\Hx#%Xwy$c.m'+~b}Ýq#OsO?(УDC[oX~&o$ox(CsFk_.2O]jI=JbO٭Sסu#W..Y#eUx|pajw89;5zsS<(gw.Ec>CBs9q}qR^!rPK mN:9,y *org/mockito/asm/tree/AbstractInsnNode.javaYmo8^at]mE[Nؓ%$',- 7dPE͐(bZ3bͭ޾~ 2D@,2DYV1%(Q i:Lg(RYj%'"R̡,*Hd"s.O 5+;p/-|60"S;P3HaLo? $EJ2* ΄xbڸeeP9%4Gw Ou 䅖YBb6!nIL(u)di\X Nހ J\fNpZ 0PgJ~3o.BCc‘W^E UbQfJ.0 ]|ˆ yO4++&&KK:ic* ʹH(VR*Jܦ[Y6E ]( .Y5v F!;"nl uQAl8"C1sĞ73~dž,aq!bk nػX|m8,o0f0 pbE=aCE/K׏!pG4Q UB4߄5f>:pusy0$B{PEQxw=v=zBb{\O!hWrI3um%uL08KFzF4Bhܻ,<7"o"rJwϟ=&gBi7.ax oz)K|fKr 5P *z Zp*;#H8V\pew{TZ~ C&;`ySzz"Jh|UXgT ]f$ç|.DVI>y'IUJanj3dy=ۘFMZRO`N5fJ/]k6}(aM[K#t†m[_܆Ƕ)0s~C׶v<,֖c5Fq<5oK,umY=֌irX^ׄKV2~^?|]ˈN{Ѻ^yEqWͿ^k$t$dkvBX}/v.YV^n_#o{yY?f^j5PK )w:{ ( )org/mockito/asm/tree/AnnotationNode.classUmsU~ftmKkE bEk!%% H!mI׺M0V(ɷ8~P*_3 %IS`3s}sy_^q$#_䳯V>gbV0bC\-3K' @>Ǧd)#k^3m,h][b F1+В,C[37/P7OEuVg-s:4\0suH-qk0- 44I&Cf^5 3YC.hp[sH]w nM7T(ԇ2 $]~ta}xUe>a;m@7v,l6#{GV\!$d*)Gpd6(_v?'[W;Ie_I57m2>vQw7 lָj@]R[̄藃aɁ&GqO ֒6 j8gdiu8" L>Kd }8!DATZe>Y^ڥuZ/|hILaD)|VNS??mJ,iyzBֈQ- Oȣw=-Js3BZFs(|-y>8+hŃmmw@>0}GhS3wz/Lɪ3I1be\O蕫+':BnYϻU]6&r<2(f1,+Vv1J`!mx1!~b9h۷0yG8㉌gx5͐[9R9bBZ Y W=I&2]ԣK;J^,#^/]}:|)pimquQoPVor'ϋWܙYcBpx̼ەmI~RJ߷|y|g< ;qjM"lχv>wo{4=]Z`#"Z۳R_h+_T[q2}D%BUB:j jԄQ$sf}|؎)/%-b_s̼`JD?IA.Q$$RpԳ7]AJ,J*Eq' D 6(<&lJ$D\ӭ, !Ϣk;pΜLnpӁ . BzQN ?!J/n 8.' \]Tۋ\'MΗ3;*Ϗ`^1VL/=qntlGР ;rnX ?(ęN{,-sx|9 w]{2wA x4Ț)n.K/ίd7cԫοx̾1 i.\ϔp9 #7ZFLa:;uSo:cAp'% 5^rwFg pSa#`~pC 1\_8&HBDq]5j s>woЮO92)tC:j6^*u~mz س+7xR#t P0\N/L 9~j'vO7ZS* +K O_z*] !"l!M^쫵s}V]%. ujXXRlUr?)Wg X &bsYU` Wj%4f=2e|t=&A*e,54M*cb< *R%G!nYRQjiٲa@u}I *%19؈xiz0ف42ƍ:ӓMS[vSQd c;j) aes%s¼ 7OgYd_ɬ@[Ϙ}"F/k:X^k#jLF{a: }_\36heU[Wք̏q@,uԜ`p(?M}<HP ZUCZGƛ"PAΟ¬CyI_)1ݟN^YRХOՍ_-U+lÑ?ܨC8 50b6`l5j?5| ?Z[UR?~QMZ;J%"M4]Х^oyl`절iT u1&ԭpoZ;:mw]K=cK?uJ4Q9;M RrJ!0Uu7t fς7:[Tӈ.7=5DH ?twk`:piVIFߵ;qגP$wk=a=aʩ ĝ+^fсmz*=x&8S.ζ=R!8?tG!E⟏?Ko?.G{.GiQHk?'QJϮm;xp6gYms#O%@oXnY] K2~o;ȡx9vf3Χls`f$@_諵lI"J4Kɗw_Y/CvKA{͖\ޗt'  HRy/ ԉplW8QvPK )w:H$org/mockito/asm/tree/ClassNode.classVmpTW~~dasIB e4MҥbkTlFIhLٽ 6I?,/ jim%(?8:_G:?=nt}uO\Lv26IwX<7gm;5F2I;ZSf؞Fȫv1 PzݾL\!0cgsN&≄))[yHbxz26:>9g2OgmH@ tNĩA;ؐs_0&'EzRf[57.a;7Th%,'vR݄c)-$S8i'Eš |+f a hZ 6XXeVt uheǍGψF"ծHKTt[tzX6YXf,4Ads(ω#s-g'} h&ćT-.OB9[fR)cuLJq+QtvڨȥI|ܜ6 }O^8]ADzѮQW.R\k*J{3"ew@aJRq}o> )*kX[Jz'9jp?>/Y@?ax3[*Dj6sEG=fDm+y '`g-#qD-)yZaw[:i ֈkLp3d/rtL"g8S^ېGϝ Fr൯?J~=.sw_Wc;rWUz\B, K,F/`YV+;&m,5<pG|hgmeH zk E{ 9pC"g;"=b{$T;=CK}S5+n8Op\y<0^B P7ѮlP`1躪'h Z MFs]UY4QΊY/h¨kIڣN}|֬ vfy$\Ş^?ݿ1/3|ňIg]a|}X/CP98YKN؆aVz=!_? tCuNZ&ԪM*Jhu! ؇$D0&k;IZPkjW4P="?Sۡ9BK:#5S!a."s=|nڗ x A/b.q\DLϝE|' O,ߺTgTY:!ބں[;.OY8ᵰy.w-Й+ : f Y)@` kػrmrT*[8–۳{<0s1Ҟ9F,zze Q:G7GD4[C΄`uN m8}` DV=A+p59\UȻ1 qp\s0Ͽy&pua{̼= }$(BSbPC_psn3z\ӕcB'B4eHFQOD9kU,QeB@ׯ6$DnyU*(=~+n[<\h@dJ:c4ZR-*.یVyúI".WJF -+T09&%.n,t"НN,ee8>{t,(*\'䶄QI)|S'ކOxYY+[ ΙƜL`jtww$_@P-2qײÇ -E-1AX8A%H-覰$6Ia;Á̈[/8ˋZ&I*[n~QEDI  Y"CiO7Zx7ѴO^|\xNZ_sݓ#&jOUlZ@k2,Nx|jm\(~(̰B܎ d^lfkIt'BiMGlS/KyTNfHK#}jrNԢu^E+MŰVGM֌O$U,$uh&I W~)Ph;dpIn i qpȴKρ8d$oxE0K^1wr1jŞI;1$-d B֒n$:{OUWSNIy}9g~DnE:7brCrB=p Xhj7 ,TGl/B< F%>B(^bj~]#c+(ԧ/y[ITZ~5RP%(i0TZgBAqG&"KP` dCk Ցlލ:gOH1WB$%KJIK +c&M\OTޛn/BLd7 )D;-<@/Ec%O5Z)ڵz/ԕpGILfOzR+dEJkU.9 h7tKS+h|7,u5nə&ƌV58ƨAhbnamPb{ iH6UCG2E9_fGveOeCkOaM`x-=Ѩ~+ңG50R{Fm7noU> PadTӤ:5}J3WF9Yl~PK )w:AV(org/mockito/asm/tree/FieldInsnNode.classQmkA~f6VkY)P$M%P˒^%򃂡G#i~ؙgyvaazV߷;ooEց#n C+2` W^u(v4&wgH<cC-{=8 WcHz/uEh3_:30̨W:rsH⦎42Yh(1nNΜaq7&#Fk5Vz ۮs* sd4jVņosw\q"D;8;"3cqF 0?ܞYS;tHers{Esgc+h%l:P-8d$h**T,+djW*^2YIv5w9vJo(s16yK|Lc)&yK>qIҖ :ttc#yY6,N/<7|)v:{y^ƖL TSPK nN:xd'org/mockito/asm/tree/FieldInsnNode.javaWo6~=<4P٦Ir< D'\digA}wGC'6MQ9?;;;=3{3(KU a,!6V源ZKa`Q|s,t.{/;(AƵr ,i齢@-7ӂ[Ld||*0z]#U%BKӃ'e@[YB-T@V^*keZoT ,~H*K{uU(d m\J΀^|֘ZZt W 9|*mU.{h H8/]k^ ;.wRX5؀*t^ʊvX5*ZҼՍwևH* *?<貐^\I5-#Ck4\gKFAVJrZj+ uZoDK Dhf%sU$šDVyF0kB ai ]¯3KRFY,Ɖ7A;At4ai q|2 9$2a8QA'<0 gatLQ#ÀOب,3e^axq|B wB Bb#aFH !0 !oVq?gh0 &FLY&D=;t6H32Wq?݅ÍQ'jgx^}6 jxUx,, kؒEۣIP+( uN#QoڈrZX뀆2繏bk`5vAUYlPxe`An>QԼ|`1B~\r:j?# ;w1Rnw~P(Jt/ѭӅ~ tMD)hV׋܈q04yVX!"onASdv|X |ʽFe;ldվ4]ly_0XeӠwbYؼͶCsH8#jN!? y~ZZ}M-lGa`v"O/&fo {2O/1}_[t9lOޒKe+x%ݧҚ#*TGtdvU_ƾWhU6vn:Ul ʘu_{Zz2Z+Iٺ1a`A &U}&*[&va'?|zwlD3aؗVvD (K`!OqS0[ ^P?{[5q lsh.0waƻlv|H~mɭiu;6庠v*=VOVߓ_AYCSѼtp(ԥֳٟwg^g)Zc\}u[&{ך~hX}V! -WhKeNiKNkKe7gp4r/c;؃wQMf`\TƛG.벸.k벲.7Qby'7K_M<*>iLS_R c'S2\!œt=7xsC\7r<$ Y,m'S-sdRL5%Lز(Ɩ7 V($~y2)5Zi-zkD^fx 6lD6>C>U~g|9O>e7uPK mN:#org/mockito/asm/tree/FieldNode.javaWmsF|)8$q}$!j0ҁf߻{' ޳ϾN'FP$<,xO0T"" Ojs%9OCkAzNA'»7`Ǭr#Rb\"߈O-D$ Z"օBsD7srtyIу wV&"v<y"l##\;C Pg2]BMP_;-* Mkd.نD%C4S2=TH8[:Ķ[h5LDw]A Z*W0h oZAEYNDxSLK 9Vq_獐~#H )yEH)<8 t zˆ2iodJ %%zYhl,jb%B*5+s*Ԕ[QTi໣ls- m[]^p厇 xb7Ph9`zL тg9v`<2MXj#VpG0.ؘA lly0yS7p&^em'w"voۣZ^1.ƶ1gl 0Z؟mn{k_3TDZi0 4?.]wm l]_7Z ,r`9b30ͦs.YB,>Ԅ s[&>t>zpse{̼SExQ#vԠ/8]&KH7̷e OJ̘(ЩC̲Q=``#׌/ X>+7U"G+%u䲟dTYI_B|8>:>*3LA̋Z;?5"ZGIS&ĠVcÂv?>5΅GEN*<Ʒ!ڔCQE_{HK|YdLZ?Ca(|eB)HXSeQi 9lř*52)cQB tje2Uo^ ӌi \k/<=z^!)W\abΙJ).^Po~ՌLX1lx&wF;U\8&&2x ݫ=skIIKX oT5^)W$^t=0bDmDtwf//\RPRŧk(ީ׵h;;m =]UoDPTZT-G`Q*ulaW_gk UncqWk^uvJ9> Ǎ5!3fvVgηý%ez^ Hy5[[mM&cKy=HoJL0+}ZDj_fnbk$n2i>Vcl^>ۤu/6QkZ)nkHY9Aֱ3ZNyjlh!MatJD? Q+:M4r$} }+ N;}Bud=#jK[yq4JgN>Z? d##٤HΚfP13CB`c3▝5v4m-Ƹ!ύ"*IeFJ"&"cv2%-[m$ x&I]@ 6r0ا ~LF;G͈MhtI2ҧ#Gfn-)- U`X`u`wWX2Jcft̡]U"qNvҊܣG"adžlLLf/iёmJ-[ʇe%ϛ:6a}6b3S־l8 h,NG#BZX~Q >4 B=*˰[\#kK ʤ~W!.c?R:%ڝz>bhˏrW5,R[Wވq3S OC˦82<Dd ID%.8Q'ۈuTYDMIt4ȶ+ᨬG-x="k,tH5{cp(͑ K JLEGN3aRsRW}F6iSfi{l$nfsOf,0%S&ֳ: dgW'XF\ǹ fZ.$;^T`!YwQx`\yDEF\Y٘{9:9z9CY<6P֣$y$v$Cs@۝9ҒYi-”ZQv\yfONq? zx|AբW>O"뚋vd17q"·.!PRv7+!˚A54L(!#J1f%BI0އoy]-{O*?PK mN:/(S #org/mockito/asm/tree/FrameNode.javaYmo az"9-'mD3V|QgvIP/4@ɝgfyfy+zC{O!EH*dBPp1t"(9+0iB,Ckv:{]Nݻrc5< @D@W2D6/=1*о8B ȀOF2 4bդQik8ȩ뀛ff"e Ͳt.'?(}-d"Hi6E^qҪE(Va 0ϝТN{ص< 8NN Q3Wv? vk}6=3`]:!88]D"nvFNw+b!PYHCئг{{80u;{R5yCnK`q gCa p, Mi0׻a`CG/m< bJ|֗/H }u.~.#];}Tn"Ǹ{Ctvz9'sp%_l𝲌`ۗ9~j[VeBLׯ^,rԂ\D-+.tK>^8[S'+ ;ݻ̝4P0#e/΄r$ iڢje$B$MP h@l2axIuBp^Kƛ "#">O|9}}Gtr͌ T$Q8p <(pYKϽn=[gSH_x$=`6\;_baEha|u)P=7SÌyf_@l =5b:48zwPd CE|4xGԑv``;dkE0w۞,pf P*csS,\tzĽY1vUt:Q5'ŭ0Ip±awÑ/J>>Iq`ZDR؋D&XF?|1#} uN7vq"rHӢOrDVr3\rxU'7eToONͳ.i<P\,ͯ *KP7}A#qxҊg!'%2OxՃ:˿U^Y{ik㡟%ǾNv 夎goQ\z&2x{i@ 2ZJՈlzaZb땫)ݖz[-82%_--oa\ sxCw8֕ZҚֵڊ{ӻq(y1Ǻadled()Sa4¹`FWpZݱ`pL˓}v %>P(͉:ϡ W,V榃'įX AG橜P8v ӑx1kjԤ~j)eP//,?T l&Zχ51B?:=+K#<|WnvmO鮑o/oQK#}R@|;m*|V55wU["w,~w1q!/$Fj4ր[P&w®V,PK )w:pi{'org/mockito/asm/tree/IincInsnNode.classROPn;6V kQ m|3#.^ KL|+7pkn9>h!je<-L"irι~;9~  89qAiW~[FA;J@T/*: g0GʔIKY/ #}8j"1\҅f8"}^?T2wոxu,vSB!m6AFk"0|'xPk2~O$EڋI ^PN%U 0 1KQstzG|ŧS6OPk.Uo#dfdY9 b)7a\<'U\+:= kLyLm穂ZӔ\/J aoc߰d\B~=VX2nS&m5eVh%7oxOe:X݂5PK mN: &org/mockito/asm/tree/IincInsnNode.javaVQo6~pSxN= hP LdɓyhNHARN}wMgggGpAvj1B}2Iq ޿~ 3#Ug0 <L*e J=yl5rrWI2g,!. J2/*c#rhdqҰS>Y9OS, :>'%-#3< H U EB̮"~␑5!Ӿ:>RV4qQboq!%- scɖƷH݈sAso4ÙydKb@@N7v].NNkmb!(-k{6|htIуҔ0 +] vG뺒4tYF.Vv-$T--P맿&7CJB#e==r+_EG@ 1}O>jBP/VhDS_gi JUNi+O_t ;JE!tA;@wY-N<{^5zQf_iZVܩgD+طPK )w:0:)org/mockito/asm/tree/InnerClassNode.classRMo@}8 N(R8ĥR(=6*lqlvr/!%BpkUz̛7F/!z@d R$8Y6HeDXS"' uT $b, iU2tK=W/(YFTׄ;j0akPwQM7 hC~I5n- Υ UƵO;W1GXb>VJ4%^٘98Za,ߚ*x(ui7*h5#2-3߉su;96'sαo:sl3_L%hU,2jUG%zﱊh#o:)ݜ:gdFfchװUYiaĈ5[Ĝs<3PK mN:o*&(org/mockito/asm/tree/InnerClassNode.javaV[8~iQF,>vV a0y40$1 #TﱝpKU7B`|ˋ3 KV9,6m̶rΡdX f`Xzp\mXhmx/QB r/ZQAqՆϻ&|.Qbv, *rDŐBRwQ{ʵq00aU)sX)s\{f#PQGQ-!\K؋%7ݟ?'4EC˻iS0kqLnQ!O%yE-^3j &JS*- uFz6PsK^"Q@a+.noߟ]p@ gY?bΕFR.$% l 3n -9r:ȩw&& K:iqramZzsjxW$T6*nZ79lHSHAv$p=I'}!0%z0IBq7ڛf1n R/) dD5$AQvѴO Dq#:eq*vhOB<1I! ztD;s@&Ap: LIz8kb(c" D`4:8HbM82F4荈WiBZ_H9@:!! MArA\߬(%LQk4aiBƖz.o;p->4z-Uѐ_-_M~|6Pr"OP /SӚhIns*_,U ᳰZh煳].$ }͵׽}p]5hWGHhWGHվѷ=p%"WuX6~_|2b%G/i#ܱ[GMCr;ALϿPK )w:ab]%org/mockito/asm/tree/InsnList$1.class}LA 0֪<Q((|A $y>JWf]֬5YzøkBR;ϋD~Lq]ݡOFLJ#d{sXK%㕮qR[OHZ T9:E4h]HfRhCPK )w:l߅ 4org/mockito/asm/tree/InsnList$InsnListIterator.classU[WWI`HQ$0iI(kj *jQ!a0d@oЮծս3C@$6{@e/VKӵRrmRS̚_d\eekcHRjjaE] kRo{4SY5Qj :^ XTc kyr֢&5[mԺ˦Oɞ4Q;bMwT7Q67AgCh$x߄0c~JǙΡ#:#hv8/-)7k8O_ʌ"AK$'2\{ sErU.BЙ,Z OWXs5fqQm %l8R1I/ZHG..gM' jUͼZsM0!r nijm(VJMz7pU%PO=1uJn q fDF>'>Tꗾssckٶ-'`1^R2C(B).}z2 -7+1;eSEU[w(C< SsZM'bQnD 0br3Tt)Y6A1kUn}uAIxZɛHXTxp M!A7 s4ʏɆ%hY퐞F~F.ѭ6ӓ];H𙾅-}W0hlP>>(qqM-h#董m 1$M?t^F&fȉīeƏʢ0HInV:BU M[O$ӗQRcXOKy~;{heӻoH٣eF1@.yR^/d̻ޣNec,*ufK&ZJ:ɿ`Z{^W &Ζ|}GtI:|O(O2EߨnbPˀ!Jg{ͫm% jDq!iѺPK )w:MH9s #org/mockito/asm/tree/InsnList.class{pTǿf7FBbIdcCcn6dKn"*NgiOhN+T@k}w:}h_h_νs|sۏ= +,ڃ P*mHe5grT._Py 1hH'2 ]$k*&fN kg4ҞD>k*䐂SR[|mg+L[.o'y3;`pp:!gTa#72|BQ]}Oba>,1LZZ *pA *Z펀9.$y +p bSFX`ֵuB$̀uk4ߵoKv43P:Oe3%85XDzgl;q# 1RH9:"LNf\'/rdy't1A['!gl`[F&h&8%2Abfz=abd Af(?DZfi=şY))?kMZXt-1UYp6G-٢$ϻp|!Q3zȗQ=Ɗq&r{CH{Rvnc\24O(63r DT6]u$>1MjgW]K&_e5ia}Ƈ\+͢S Szt;z3tOVƵ#[dyA8=Œgw{(Jm%ޞN:V[qluRlҔ tMlmEk|A,Anb lUs)]E|F )^)ʥY+G<a2Ԟ>EF9 i:NGZs,g# u3_+GHDWx7~x 9;&[['o .㓴,Q4{w8H:J3"a>ν:#B?zS6yݞ :ʇ WT)֨2DU 6 lSЮ*ѩc nt d *#W_r ZTHREHыPčDB崻N㖩~U9!-9rBq2\-UwSa4UبVD;TT=h&IQ Rj-gI| ^x"w?ȫ6J^ɫ6򺒼|x+,B(y򺖼vW7y]G^דW/y!>򺑼Mu3y%ȫZ;{SVLhQ-TgHIdQE2sRn5n1;FTy!CTFyACЪVuWRwR]Z]/pӰ]+22L u7DpAS15j:/GDp/ @ <ݶL l1@Z=ZE#r#:#. 37IE'I~OI1COZ uȗ1-/#WYTDŽ,G<#&|ߨ]Qg ?K?& %VA-nQ>{ pP=O&RV |;5YIVn&T!eU"!"<8qa7z챫 8zxɂz 2UUaz lVo2Ϳ\W- i#cwŴ7[{k=Gk D(EX .@ϟ?<'gB5o _ 4 ^S2M,3Z4,bd7Q|%htm_\&5!??!^9mrpȘ@i)1q_yD}t-x}%zHW + P/a39ߌ<`+ #~aN`rN0K@dx`CE, Rh%OIQ$ @%],,] ޤ5\_~8g󮝒=8d];3۬]⎅\`m -1ɏ;LJz.OlND1h;$d' l8h$h/j8NL(ҼIcZ/0oҏiF.Dx`Wa3tMTfă$y`1˛[/e/i[;`m]+ծ/EEPL(c]8mjȒu-HXؚگZ;5D]r8Nzp6}d1*iK4bUr[q`j٠:MP9`{XGK Yo.#D\@XaDk? 2JR^G> C[M\ <^1e/>22)%Q"%]S >L zyLksK-5O .>2637(,ɤ [r)=VSItu2XFpR ]%G=矊ԛ AvVApjFFW$d7岷v7cLNr_&\Ήcz[FH\ $j0a~bb /DblPr4#YP6chT/`QJ֎YV0].Ǣhr'xƔ{g^7>`M'ϤӐ$9c@SR:)h",#)1m@#X0^)z?rSzSeA\Wqy c%-fC:e!g͂E+eKc1QR )ous'0I`ba˜9F,\N|61 Swh#kT%EH!R,ѯ*EhX ]p^)v-7I2<̖יXM)oj#Od*Q͜j=Y݅%k`_l%2#`%c .x{c'!ٽu64c߂UU܋6#F؋瑬.?|܀h)pc[Z"cCWqW+WE,/DF/,j`b9U*3Өm3j :A4w(cP |6S+ 7%Taq鿝(\bLX"Y*%q-n^FVZUhJ;bp ^zr ": i~qj6.,ٵʓY ΰ<5=b Tz?/oEKب5o$S#EY՜E)H50]L!8бoU KZ@ :rƌcl4k׬YW;9/YX xַet |~TƷ P{8L{"s#C3XRf%*<ˎAxUB dsE_[_TyoCUhd*JN3'Oo k; hwő^,IŨһ$ +Nǭ1S^档GYw'Z *U|=q,٨SSv!m3Nmo"騀YG)xSFi#T $ 9yyf@KIݐgeDS$[ѴոR2ؿHb֨2@b*byB qʪضE/YW?b&Q5Pm1}k˝ ;~T(\AxB9e @a{-ej3*"$jZ  /Vac d)(]Z5Gfup+Aw%aì,{8/,@JW;/e 464nȨ8tW_ ,sj9r,9Vy]Q_z5mW#C:HjzN'[٨7<k[@K_'(|.4/`@d9%d\@x5=WSVGj|%v%qV ds]Kuu̽&XjNPĨs|F_F`.^!JɩuFCeN-Q]OYrà|4HG;t1?T'7uX(/<*ljeE6l$m ˱ <%&H0ypAv4TYI*+I{Ҵׯ6kVǸyƉS3,Z"KO^R ɞޯ&9/#j/6e8uYĢfd\le`]wAmWP)?5{hK8{nJIOG 3WMrd&sf^2R AU h& GtTw@,qWQMch6)i}ֵNCk,\*#?PK )w:4N9#org/mockito/asm/tree/InsnNode.class}]KA$fwUkjDK )PF{Q x9Ydf'N'/,B@Tu4t/yg9{fXWI7*i?ЉA3N#u*0W3K>vRP--0ޜgXCڬ}p\1GɔaPv t>>PV(yfT Sm>˰41G&1F|iJv;"9-LqhTZ*Q'w"ql8;"&,#.|E0K(nR ݢYF;,>S˺l3H(=)^ p1JΩd$|y~ݹ Z⍭xxVhmĿubX"cȉPKPK mN: "org/mockito/asm/tree/InsnNode.javaVYo6~0ا$PmQ`ee1 YruxZ2aHtߐĻاpH|sp8->RJ;ټP[EAit꥓YTUi7i)IaX;:Nizqq $PMZebYVaGiV6; :o&_m-gJ+jm$^YU l zλG5N:3Ai#i#2:MS51@$~ΫjR`XG5~pKi5K.㦫z[} ~U4 Tq^-ߺYlThz LepptԺζt8sK &O5y?߯eYBW̏c]e"W)u$y! ]CL_h%QMZcUr$t0.Q}3E_mndƥݜ"tˆ"(p3t2 4æCV rka9'H%/Vb`dgI$8:~aEo%*l$,àu?D&$Bx_vx/^+O\9nH7"rN# mƄSiv u$\2kbF$2bX9?>ڤS7aRSՓ-']#㣼MGq]ExBχmc-mQ{ҿ得WLhccRslCNk?kja*ض$ٌ=aݒ^uWfٟJ>E^=p&|ޤxxÒ۷ͽHKx~)Fo_^ oPO+j1.*ҕ,雷x(VPK )w:,tv&org/mockito/asm/tree/IntInsnNode.classn@uN1I(嘖 BP%Ԋ*"m"q8ؑD❸$BkPBE/<;;3?wh5 wnXv4PJ]?,Al[|š) Ϝ}֞`,C @@v[}%:(TLn$ڻHe`(G2>H|WRU819d؎#1?=þ1vpKM@ ncI@MV.pMfMb׳qu~uv<{ =6L)-vO*]_OFfu0 $wToD@9vF{OjOLS$߆`Lդj')~5bq?itF.fdӓ6y;\cmz4ABÌcc&$٥]*Tڃg,~rrj395_r^#MN4p*So)>Q3jȨVR_PK mN:"*- %org/mockito/asm/tree/IntInsnNode.javaVMo6) \g l2%WTDCDvSC7oC_^\\x L%D]F .$TV])5lQG<8 _ouwo,?>~ u.!%"UWvh^cZp,Z/3T FDR2#xTt:JjrGxMlW콰TQwP8XIu|΀Zv\#@+zOKBZ[(%΋g!-BUqJoˁ,=! Pwswih`Y(Q]yHcrɠƂ#V4~,dc0+eMh5V ֒ # g%rʅ k+Z|@Fo#EWm`2Rý"r3as@[/fe)d h'>x $\˘% D12b/L9KFx zaB0&/^mVQ24Dz a YrA8񲄍KApǓ,a|8Ζ)sL-:x}B6 +&=\>Fp;g8#ITOEMBȮ~BjDH·//@ETurE܏?{w]X MKdV`+zEK-CJ[(ƳKq7,BvLP-](khIu,eeEWs,FdeDa6v"M~!m$ GQx?<"6V$ʚ."̣hXgKfAV9JTj+ uZoE#;Dhf!3U$šDV5r3a<$7^8C6-.2mǗ)\F xg4Y;/^x 4fIQ |2 8 SΒD? y8@ O,zءnh爧!C^rx1Lg4J8Jq? zvK/2nBS ;{51!RfDbA)9 79ymqf :CC47Ƙ aY&z4r@l< Q4t',>K. G,a=z s,a|8MSXd yp.m$,o p%y|eQ ~m~t+_8cV#B ;mK2}ψW:n |S-_VF1m 9?>ZQӉ:{TV)H ][SEџƉC_+3<>lljxUxX lkؑE9P&Èi~pn{}KVcJZ]uL,b5W )b7܀7GLOJT"=;Ek&LgAiA!hrɥQvnF=@w{ϛAZ@n\Kţ*?z!փ/ (VXvϋ,tSAYOV#[(d n q6MY9{ƿ|v5;55\un8G\c[|W7ah!sqsD K j?IYfH>6mj |PKc8RǦǰ:@Ы#$IHf?A ʅ|aι2I9\bt-a}P>bN!M7XfP:b$McV $# ˱0Fk`C%2nSu  M>@iG< 5'twaH|r3VCjkuA\5m~nֹ![iqQcʩC{Z[Nxv;3t'ZIG24ߧOXV^.NRZ.|xшU2 3_v ŕD?i]Ҕ 4V(B93f~!~GH@NrBEHa$MI|AЇ'$Ѱ$uߏ!c^!Og CC~uT~br+ĝ&2rֵ2D7ΜuȮ] 75u;\a"Y\E y7t Sl#鉪ֺ7Fx]XLR%>ŵ2xXï?JU?@I֦n_ڸW"9wr6/+i(+d-9Pv"t78sy}/gi+|Y>￑;RoQ;i;|5n`Ll8NW+t@))OϮx~#[ y.׶3h\ Ϸ;i׉WK]mnxEj^o-_wPK )w:(l"&org/mockito/asm/tree/LdcInsnNode.classRmOA~ZZzwZ*o&A M |4vSwݶhQc%3>7XcXIA0LĉIaS)n_t,O ưze՛0)ivc> izDAApK M+ay91V,\Ex>J(WݛF>ԇF4[˅#Rh^'Q社4tmI {xX"30,ЄaFDIL^==>jozmKyLE<fnC1O#yhVCZS!߫H qa#W$mPKyNV?%կ;xJv,9Ԁ3 ȯ@M&/8 )\3 ]Kv5PK mN:1J7 %org/mockito/asm/tree/LdcInsnNode.javaVMo6) \e=ؠ@dNXȒ+Tp#H9 2E{3.ϦAF/`jQU XSl,^,t)ZwJ7lE-u0~iYq>~ ~M!!"սWvhF-TV-:Հ]H4P}ݺ_YSR-Uh%e[+ke VoT(,$U~V ݔ6Cki?_7mXL*J+0\ A!O*M  gQ< PlRP,PkaxS4BjX%EAdeDe!oRd`QT4*ekʥDYy k I4ȦYI1JD`u>->N b60kYP^EER5}e0[AL{?eY0~EA2{HmI4?q6S> N|3?HRe# zH8,I y IdD[!-~c<&tOs#?<%YGCϧ,0 9d~a,% Gt=XqzH8) rb($ Ӏ}aOF7$_s4D4C!LS0OٔBO&(MNw<`DIěgl^r TqnIh`I@oc-nwD.OO֢x+:+œl+鉪׺/'EMpƩCZ)ջfɚڷqHۻJ);(TnQ`ÖbױZtb?]#nܺE8,xc<_BQ8xA!] DİUZP;+œvجւjK헮ȪJ5O+W}r;5Ad{8fuj$%i-Z]mߪ嫷yWYX( 7H>G BU:g/X# ]Q T:S=m=麟=,"siǠ?Mn0R(JZ4ZwHq}U (U7G@1**lvX(f*C PK )w:<@)org/mockito/asm/tree/LineNumberNode.classR]OQ=eP*|VƚHvm6? ?eVeܹgΜ;3~ `w`]鷍¨k >ϴZDat;oG T#B>̬<$鵋Х&Wk$.iH#3 Y ,C/z֐9އ.O%6-KtY>ߴ}xUg@ aFHçEu3X&d2 0l LU/Or\9z]Nc4nucw)^6Lzp %\K0% #<>ޅF]tg-GI#у,v7L[[3g{oos`\8foa6b9Г|zQsaGH1 '&2'13q@EZҤ3Wp5N}EXr_ k EGq%0Lc,V@yl~:Ü0#f6 ?PK mN:`?X (org/mockito/asm/tree/LineNumberNode.javaV]o6}pѧ$pv{Р@eI8Ȓ'IHKtE ﻗ;M1`؄q9^] *f@F'h] +a.6ONVЊNF8;Xʭ6#'TˇoӜG#4$A6D8#4Yi/V},[ {H4T@+mZ;r{aZ]<#a-M5ިA84z{tW+:d= l|bgAZ3 Kb7sȣi*9-BKыAN}w]SlB`3sw=<KFARghJQ f1X >չRTj(Qu3-JTGg d۷Ø{=Ԣ$@E8vGZ6R/e'52Wj(E#AU Hf*)j]6=xRjm녱0el=Z\R#szr\aC"PQOrE CKi~d@=r4-9-t WL%Z, >UmT&{(p֑miaԬ2^!7hRZ?e*E)+#ޝc[jtШ #E7 qއP**eEUP -Q2:tx$=aE5*Ƿ9Ba"B][c jy"Yjf.3U$BM"ܚb<$LoqtÇl;42]̯S!! Ә&i/x |q̒hp%=<~0aBGb>fݰ0 ېTVpo0 )U^H$ 3ӂ}fX (LtDz# <M$f#J=@d< hhOX|}| J,y0JQ̡׃I‰C|8S[d ypl$,50=$At"F_gd'm!Oȉƞu[ng  [hJ#ᭌpc2#r~|4٣y/Q/oT9yaI4sɴv"m?Q0 -Aȍ֏Y-9.py0LiTdQZct7!p [ᝨ*+ ib* ۺmfU.)凓pJ[o\~9*{H%BU/mŧ9)Ի$>Ji^J* ]?ﯟnu=ZQ ~i9zl$CUs_8ؑձ8ukbo|-UE7ALk)^l m'2R/ӿep Xe2|wGS',5 \.AIJV9,ss޺trٷx[R:KH{de#XAqAfPK )w:(g?(/org/mockito/asm/tree/LookupSwitchInsnNode.classUSU.tY)6 QZE)& jIe͂K|>L[(SpGgf i0={9wOmf6Һx |>y]ÏY \Ę$6A'&cL8mݠ`:[L19-Xm_܈d#Ncn@ f^ؠHi[Ԋ,0~\ v䉿ېEh @Krn>Myssxu?"XhxQ,꼘KW㵷p w]~- i- 9aW2fѱCFۮ5QG_5k;c@ȯ-!2᪇Jɷ?Ov]LzS1utaSH?!tFUdpH!r1 ZZxSKڣ3fͳOxy0Oy/ (:v*J@h =7[ԿISɆpIg=LIΦo+z{ %SP-SNLf<‡h#k*#ŦHb3yyd vi7t*i 澉(4ʌeQ5@%=V&Ѵ, U!@PdUH4)G,O><\}gU`,K*}เY"Ue!('CM(ߪ v-ZZ Eɑ.EZ!O2}4H8*mZ5LD7TeG UHb:**iɛܝcZ24ȱJKU8Bdb+!#JDE& #@ *d-&KKhQٲ| p"̩R]nED0k^gg{&Fwh؝y:kמX3Y'h8q+}pt8,6 уg:>ı=0ͦ,@cKZ#fNdC.ѡ 3 xn58a6Ԛ zrMމؽu,B wlflK;Ā'̳EQHiYcF룅1]quruhsj^a?(i=kJKG~y`Nݰv}%ܷ%0rgV ,ϛ:=L-:}w6 zwLz|y̼Dx&I⣊k~QԠ/8֕ͮ,glѪKH̷zu OFL5$PCvz)J0K0'7z, eN:"'+>{:$ e x \LVY^|!'fxu;ނK5<0o9ʔ&. }#Q{16ı_3LQbj+/+.4ʫTY(Z-bv]`gcs,-R\?]E a.|!~4Gz`$e%PH,yc3nc^Ĩ蠱?׃JŽq9< ǕnQ<o.'I4ԗL dcitֺ݆ފ(&FUtb>Lh&gxjHK755^{*o^Kɮd騌GmI~~wP~h-$zQGZ4qL)>K|wʴ,g%R t=mecYTj`Խf=޽Ɗ5*sò^UEہ =aVg*}_'lѓo}Rdf uY ki+"8ܨeea19b֍BG-Fދ2x^ c[PV?93lYMCZW }iێR8v:/E,,1$=3ȥtIrjLF` `@S* 7se ]OC*R|O^ f08BapaƧeu[Mg]/f1,1Ć !EVX=o4|=sL"QLxV(m5iF'2``u'InBc49KʐʝU $5p0L[6kܡ;U Nq <^U+0Dv۴E22TР;?F@;2A4:oi$#,`#mJkS"8kFܣdƩA/:!P9Lx;>aC,ԌyZGNaR >!)xHn4 rȓW[UU:Oha u$n3cϱhQXK5Twi`2܏@q2LHh]ڦ/RxM+G,=6qyCu PK nN:K˰~$org/mockito/asm/tree/MemberNode.javaWO8~GSApҲ{ڴ5SGqKW[MQXvu']c|3x1XHu)DT +':PJ慰JW059=usk59߿ _̈j"!"*q5YKy@ n1Q㹳Ek Z "XU]jSmWq:Rj&6#a&M9̌^VX|I* }*WT;R,>>;ՠ[92g.኱^Ғ!O6 $e[huRUJ㘂]A4`hɼMN0- VF^Fț~ )@G^x?"R.%֍G(XK'HrT:SO&+KeSY, ꙜP"4Td/n"rO!ϲ0aa_Atu/2=F=wFY5at 0ai q|0sD Iem܉ǣ6 Dq}>eq ;% ;ϳkgg;C! $Q?L`8Jq(OX/@/2Ke^NU a+܎g  fzE"~!ro c 6fG){(pc0i6 3:iƳQ<{%Sǩ#o6ZBr`9\qgr3e,IFÌ YBBT9ȅ5.m`8$$JRdm]$5ۈ"v,2Z 銧hBB=" \;?(K03{_E X)_*2nNЎ J=SV.k<=<8׫.UeQۈw9?ɍw5FS%Z :K뫘fct̼VWMqۈ0XGMۧ·81,0qAgdX&6l+Dk;XSE<'?yQ|>AZ q=Qx{lXb,&fQ5L}#T|KCVJ-UxOtarf ֞D`_abvTqv!]` 1B#ڷϊ6=o <z hmy=cغi3hal;sl2. 6GoC5,۵Z<2jȴz"5$H#Ȼ"yKOl\b"8 -X!-*J(  >? ЪJŇ!ÆvH߱ R?!f(c&My&23mr<>Ң!B1Vx spt.wh9239bóLcu0m5tGrGȷsԍB`b1?yg"DݥG§^+LNPW,{dF(\Cx"=Q)!=Q+ C"IEu(X^P*X ^2EUqU5Enb-ڡ[R>Oy(IDސ8M\C""︛¼TV [wFV~,܇7)r9򔽌mL[$>PK mN:-?(org/mockito/asm/tree/MethodInsnNode.javaWKo6ln6Llmɕds*hIH!NE{gHɯĻ8oyR9?;;;=3G3B92;ajM,kLB!J\VJIWJ?I?ϯ{=UL%$2GYE;JYe'F2SbemJ0zU!,T) Ӄ'U?_-L3uRKUZfZeD?\?R]f C Y/?w--F@+zM&BR*=TQr$e>-BɝTl'6m2 Y֢9EBTJloFȻ8~C =H %?<M8 v?yp L`§ox͉~/:`tWIJ{A`Ù_hvw-*QnP? w*`A*e"]ƀKSDTS%3-ЖH yEyFL#ɧ31Rn~U$^] h ;/~ tO1Na9Ջc7ׁH84i{|szӠSK6OK_RD.\Hk4]_ik?]e6Ӡ/u;Q2^73yM<C,'j-ߗ[WU$5ժQVO}QNQ0RMz69&$GɈ}ɾlU F:dbO4}Mk m/n]}A/oG,1k[=A N߮lVYr00;aXBa?įdAADeݰڻX$ےm+7WXGL\mL\,dnz-cPK )w:c 'org/mockito/asm/tree/MethodNode$1.classRMo1}$4mih@SHR% PU)(nƤ.[:'.HJ? 16CVZ{v7w]<$3vOM^9l;+eR3>6c@Sq&Si|`8P+!OX>ƙʔ;8;1Ka \†el/U Ewc>giOVoo#T* UP:'|c2f>'xLl ГT&~KXn/B#V%lG~;,oxC9&PX%F|Ml:"Symf6G*_$5ғ"dC rgzg>65psY+BkQ|AnwϱiN_m1UB'__y({z"ɤ@:X?"ХDc[֥ؖ%${X85<_dWOd Ǹ~Y4uE). bTXM8+9<ؗʖ}m5v/6H^HɕEGc'\ƒ`9ˑX2f H%vz.,.)Z l]ѧÉh(:# MGLuZd10S)pa&)NmRtgeGMGuW7udz6w5P4 GjQaZsgZsGёHw:  }XSJ4?Lt5@<~#,Y-J`V|iu?>a9-=Vގ>A)cx__DȒ ~eXsAd&zUz$傩|'ԜgiVRbGg p8OX_C)>-4rd/a-.LѺ;t'pr;nr/ܭr?+xnRĖH#e?KNEIr-@c:a }=XMR7iZM}j|T hbk+gj59m$±޴@&{#Y5l]7 2^|YJE:ЈIx_2gFz끠g8WZ¿Ň[q0i(Fgapc:w6rh>MF>-3T>+$p{34˙n}>܉+WL)#vYAOz(|CutFctgF>R~^DDis.Z3Rʈ[0,=&Ȗn`ISAYyVNqerR6g1=I3KћU}P]9zJ!iccx|@6<:7|>x8GY<Ͻo]yјlhǚN]Sd~Ygf/PΏWg;pFc2/P9NwD}[y?Č{`NcY,} *RcrkU߿]TFc]+TWB q ]JQc.iִ\^1H *%F􉈋Lb>fЧotgSPJ7mKZ9 Ӧp2O({+"v z]g:m*_0fV NQ,eE`'y_O7K2",ȞLў4N~h =\2ӏXS"-87_ y+wP] -Dde/h(ce"{O=~Jy}8lvYfq | on7hyMFB(2`ڂdAw{ }( xcVzp(ǽvƒ!ń~,xŠtp|n)^E.RܺuKѭ8^,<.:"]q7JqK#\Yx98~,о vDiw=uXɕ$% ȝKػW jvOXI*.9I|=Ëj!%jv1TbC6יg[H>,gGQBT%D$DG%MG9?Cw{fz@_$G/ebG*:1ⶫt?׷% E{w= ݵut_ه`0vV{;4cOFakm-n}{KQ2mZ1a}%2ZʝÙ.ZkkY̸>_QR#˿ԯZK:ZLRi~[׳N3lFnT#Ǯ+ nq웸[ݵ O -Gą2qܺJ㯲096FQ\J%npda(/n!;ҸV󿇿p/`;8ZmWո 3)`5 +ZV@!wpr[xR1@C#@~)utJ=Xi=<{`#+3^8(X hl%Ael:4w+je?j7T1vkkG_dLF#n5ӝYY/2w;Jw:vR!u)I]ƱOn+v pAa6X}˜i6ڐx]#YynQLnfy翃:bKx;Jjz.ƿaL5CQW3n[I¿̪kjQvQv2/{v\~L \e2]NJn5lrwB37Xڏ a{GEFK 6bxbpXC$ILq gYU O >$ڽ>tvLl瓴uWeGnERRB9^íƜF̧MF$e7IBZAKREiZT7(>J힖(rb'ROb[.Kҕ`zTGc]զ[`AUj wcy?6F%l~!\%pe{2BK=Ga<))9c#9".yXJ' ʓ2G~*)Y&OK\.c;Z'/Ƀ<.kKyx7]U|ۮ&kC..Q[.Շ8 PK nN:,LаA$org/mockito/asm/tree/MethodNode.java[{oF?@öTiWZAVʦÇ@RrfvrINs(pD`ofgfwgϞ=}B78A(ٳ1"B5м =%˻5#1M.E&dјݦGNcn j@~|ğ}wH2Y(ł+3re{auYq^(.g$LH2-0 &|Hn⚤ N&N&\qflYEdp /5-BQކY:I9'cV02I)0EtK"ĩEbC$HU18RǦ(Rt]@/$ j,) 4kݐ#2e!p8 +uY(nK@A:1#K%khe: S1p~ .Pn[t m$߲ 3tD[q~@;_goSNg z69q:] vXHN﷋d6'aN a%'Ր2-?0l1"cN9ȹ7?/qgb΀K._N9_AU<ϽHƛ.HڝL goU=&{2CPԟ{jVHs2$7!j6 _@@Ns@4{( .O\xlvʱd2 8x7. @2te#›//l:ӿrgS66Cˆǐ}A;X~ZjI(P .}{5_yӱ34 _KSF7>/ /&|=} W(NW"<cO<}4+nA7aqB>dg̶8 Dh4yliwuvQY@]3 1a@JN RL|/t-2w'.aE-#h]!vD(?ED56K&*b1gD@0 ϹfRoAՊMDr䌑?~#8F0&dњ@I+B!d4( E"] ˜Fp0W?/R0)0ƼB&g#VYETC@N80*!c]I W)#iRUH?ȩg˝ ˶Za1C,Ȗ. l+іf{hv4*oVT/JW!~:"r CE9&߾vJ-bX0|  0L`'Dw $ InH bMǪÁ3yU_,#,1R9A" BZG)ԱƻT̐zge pAdC = Xzk8߃^A44 /m@)i*}K&45Ih)ͮ];UdX'{[ NڍCa>tj֗~pdDIEYخsaN}-؟mؗ͊IOõ9cm> [5b v$|oajghLm/usA/XrGgnہ^ `5ϙ) W 9fCwnyYTha/oR6CA'3-J(kq]T*=0~PT{yQ[ xȉ)m\b@hŎKg)VSqХ| 5ǦeSSc 4%D8l#UDt,J ShYEnn6q׼b*WS4bLu<~V\mT Ue,7ɸS}Y"8c^H\WUjzfw#[rZ]@ -o7aI; V^#M"?X▁"TEM\'j^uO* ?Q=J+Vfj|3Pga?U4P`yxS݇NMQRh8r5IHz4ҹ&:o >T!ox$#x~"cwaC{N}GCz] m$PM3]KQU8P;X8C?j:-5sخxHwD2|6PzN?\ܽz aV{A얻]X(WT)5ьlz^){7|0s2Hy)kxVr4n+Ӫh&@kHi_창Lf0~M59=KB˯s @Cr3$X* 5E+6FRMr~止Inane)v-/ = q`1 Mh24v$6P2۵z~umȗ3@@܉B|Ay{5U\J!꼝&;] p!o7lYot{Y9&1Mj7?ĸmn͕m(bxۣZw8@%9zN3gHX(܌o-W7jOh"4& Z [>{/qN|הϧ]o~Oyqp!-n$@k L-rc>;llPK )w:q'΋1org/mockito/asm/tree/MultiANewArrayInsnNode.classRoAYT?L* /mHL|Y ]=݂&m5(qƗٙovv#T~г^*aVvs*Yo g /Z~Wv6; 4gHvE0v׳U ^Md?d` IP,"6KLd`f5)` gbK:HJb;tO`HZ w1P ۥP~-CJ5l4n3avUd5?b<=R8^PInAMZV e&[ PK mN:dZ 0org/mockito/asm/tree/MultiANewArrayInsnNode.javaVMo6 \g l2%W%:a#I9 PVb=a7á/OOly[єb'`dK hԶS|czh흃Aq?}x`S#BB.+Dǟ`f'-T:֭E|Z+A5`ukf֪HyMmhyZj OxHJS+d [wā$U~P-)}8z΂:ZtH'.ኵ!F;U!nQ*$^1-ZTBx৷T0-=ZHbE[Ɖ>w VFʾFȇB:}?  3U)E/|J=#AkXGXK'TA6%J*Tk' %h z,v+ *5< Yӕ"xY2oir'l.2*WfI4aiA<8Ox'8)"b}_, IG@qY6ěF '9D|sܖ'C d s37+sM1` ytdI,>gYC6 &f)I8;"#D0'e/D 9 wt5DܮY%q~[F`\?8i )dꁲ8y\%{,(ɼyˌ 1JApe8gi\<077uȮ'5'{Fee8ۧ_ӓ(-Q{Hz䌔''j|F.\l^K嵲8a.?ܖl}[tѿWJٽGj1/#{ {s_D 0alF:*uBy[9!0F<61b)-kD{^8R7xbN-ڢbXGU#:ǽOge5#{^csf[;5LGEbinP}%Ыx߯<CK /eW:Lޯ3*l/`_<|G{烦V:repDyu/~qӪQrj)Ի#z7[=ޔb@EdP{>qPK )w:=.[.org/mockito/asm/tree/TableSwitchInsnNode.classUmSU~n ky+Myfy/ J)@Q3f¶,Y?3Hc>g7Ch6~{=>/>6tʔ=xZmgfѵ׿qk;[VּR2zX | q-0{BTTV,[n0k3+s ] 99@杊,(l;;ҳ邆WГDz5t!q1k8Y5DR!:E7 βJ=90k&))ѐRM`UɥN׬lenV0n,]Ɠū KJ0K]\pWKojxz7^GU6Z+bWX[=[vczde;r\oJ^mTpt^Tl o##4Ql J2{ixŗsNO+|&A?BP!ZXT8'%fZhfy#%\U,F9 HAy;_i^4{;sշռ A5jfMxڞFTnɽ<%ֺBOOsewdhb햋_$׽]߲W敌?%-%F{r`['ч_gǀqa>0q/wLvlg"L`-aBKxBKCSdqy&7ę1ll2$425S7ޛhy-rՖخ7R IiY8Č__HM>&SN`|}\?wCt^A:kꖏTXȆzϲO/Α`[ l짱kf jt5F!qC?;@#&CQ\6cw>PK nN:+"-org/mockito/asm/tree/TableSwitchInsnNode.javaWoF 득zJ= $7Ȓ'I9F$+nC|S$ 8g3! zl/bN88v] A#pٔErl^S'_O{\,9:af];t+6v!~hțD6@0q=8"'泈^K,!6O gFS\_: &JBdquU/uϹpمtBߔj6t]49ؓ+F7|FȚ6Bp>lJ`ъN䭕ԅUfRVE_]x*&WRFyX_W]Gp.]A5<$T$,|e71ND7MmsC"jEHqNxڌIW^ NChTVEZ-RiD|V|r{Po\fiݍb9\ʍ&5$rOhm넷)B7hCA7$KxD[5w2{5,+m[~w?/_EL.3,íXYs"wXLIӱ#j*vfzp3{]r FԫҴ œI5Ywas{::SVi%z;~m*y7.dC_kjeƬs6`m)ZQLfLQ=Ux<nddҋ:-XZ5& ]Re=Xu&FC?$8m+6`16g[\DXa8<}"O-cu~(~[Ɠu cOuޝ͈Ԛ-N,m[|ٻ`N}=Ƣ3F٩c,}5|>M3Q4RLi)>;L&b ǃTz'lYLM;LzK4.JNˑ]]SPK mN:M<} +org/mockito/asm/tree/TryCatchBlockNode.javaVmo6 /sf,31Y$9i>ыAΌ}wi&sˋ7k7P"AEm/0VBjʅQU s- TGUˍV޾yWxqׁk-TB"sD*V;jвz->-Hf6ZVYT u҈D33U ty^vIVU*; ԅ2FfZe80D  {&=l>1]I$1%ȋ&{Bn|~jHHw?똇ovq=+f΄^TM\m"%= ]R䁁UW4Xɏ#Q*X<%|7oRG:/xl ;WT"nD:שX-A:{VB޹C:ފtTg;ۮgPK )w:M'org/mockito/asm/tree/TypeInsnNode.classmOP:וmLq b;!@fBnFknHPs2 =7dh'W,rn`` 7G"qaXZԞ jGgCH?l1ۮѾ7{Tm͞;4dQԡ"_ 7bX:);16C! u,*yC.dC0)Kêq}.NAύƍ.7%G Si\41 EԱ̠ +s^ɲ&}{2o" Fyv{66^U8׳C{X ;yz`:|8E{/EZ4s)جConLɧIeTXǡBIR"64]:(t.ɵ;#)Y8K=p?emCA2'1Izޓ|iu(w,W'̷SS .y@VS;ګT~Ax=dzsʌZ:6Rj8?PK nN:a?jr &org/mockito/asm/tree/TypeInsnNode.javaVMo6 \g=`2%Wͩ%&a#H; $X>8p͛'p} U-eQr/r#aTfrj]HM,ճhG!Ì% |;sӈ1` Iy < 8"|Fdݰ(1 Ӄۈ%^lʃ51OXRfoD>9 9-g9]qaG@GtQ0 1?(e  xb(R.Rq< K‹QҀ *۸.' 壔%b8:ߢJCG^8i`qrGGn' X0MDaqQt'__(d--!ě^tȮY4u '^t[CX\d$F> J=igҖW+uyzrz˕E1Kh;^tO\5OI|*ˊH8 4Ekm8YW$N>I/놸kXq u:98kxeh?q%Fn|iX5yhp $ST St>7G,۳Jm\z:Қ :f p ˁz\~bhZ>$] Yna"kqT9KzDZoO_QmoR8aa Rz\u ƛC\@ͩ5\fFMem&_PK nN: %org/mockito/asm/tree/VarInsnNode.javaVMo8^=hPD'\ȒW洠%:F v;CIGauhr͛P'p^:6ySQb#`le j] t FTI7׫F?X8{7%dD~4bH n12QE|FuH4P@KTfO>n[t*w  +TZYU>?R?r]6C+i??˞V+kHpBohSȡSkr9@eD@zv!By)T%|xM]SX5@hU|]ڊ>w VFȻ6H* j,8bEB6Z(kzFG ѰϰTOY8+tSV.,LVXX]2zi,j9UT Yݖ1}D#)88&,.2]¯o2À%)xQQ,q❗wAE/u48>CEgO]A 3ghr^ox 7gwgC^qz Lg4N[8 1z|‚!@, 6b  7 Yx"ێ|iH4`_%wmUĻ0~ɟ%lBJg4,cpǁ>eɜ,0Nx KApǣYIV(cI2f<1 G.l,Np y|G%I~k~Ql'^uȯY3Z 閧K!OɈo==# \];)K01xN/ڀpc:o#ryzy?t S m#鉪V^NClp"V 'i1W'gx_}6 ^&" (u.JlV.M UcތsPjQ3i`n5Υ.~5knju-{֋gs%aBܾ,|' :ЃA:uzeُ;BU]o[e;Ȫڒ1"R"j߿~ , ~ MݕvJX{aǾa׸}u嵋<œ#toϽD #C]X;I:Qn!7$l_Kg3sNֻ3kqڝ_mԆ&hDZH5R{P2vuk)͇K!A%hU6v^' sgp(16{^ɳ= |]75̽O+re;J{hnhbNu奮C)4ǸSw+PK )w:0@7(,org/mockito/asm/tree/analysis/Analyzer.classX |TչsL&d!\D$B5P hj"0L&@2g&TmU]\PhU$**ϪkUi߫[[;YI߯&|s׎/)dCEs"2NTSd4Z.NR3&@MxCł+/-D]4%b0Q ct4ْ`|>y@Xx*NՏzwc4)x]S4IZt"OKQdB$Evuy2AqE6~0nl%hkNZo'2҉"|5 &~ [Hq Q색~x5a'=I'c)M7&Πק)+ՑhK:{pG^2˃R8DS)?ʐq/=e=(#|e NFl:9$Hwbʲ U~7*=4\=G.t:tL?(Pt_!c4׏(3xV8iD֌@ߤy)̣4DӂPq}Y f:S[㧳t8I%RuxyIpNb16^P/( g,‘tRpOqpYWH&;^XC#S>E:w 9: 71TbNح:=G?i-=oaYzN5xEi[O`Z]}@M"cФS[/*u̷d9qQԏ5N|C0jSyp)#Io*o\oOvC?kq%-xr?Cdu5X}ǦOUk*#fkJ?w*]LJ1YR$7)+5"^~,(˶Zf2tF9OEվoM!?O}dDm|;@l6bbvrǂ MgN=<{4ɩіN2ME:;[D.Q@[԰+Uo hj qQފ{UHܧ>PVT:!3$gRӜ;csfeo?tb\;t24)jv2"*?Gʿf GP=<fY(SMբ4e=&F-?J֓kc'4BD$>$TVwK G,AybS,r`ġc~[UeQoD*_ I)`7H'UHVn ox>U U!>*+U/|a0IhCL|c$^yFC2%ZnoAM؀ R'hP.΄uГT.}3,2IF;~W#Pu?)ݥx)3k/kJ~ԠWokP1FJ27S+Շ iM&9M8@fA5;3ӱuU) K)iB1Zl9Yҹ)ݔLaE}1'qtI֓nբVD9;3erU13T_,Rdj_I5s qR5'!CV9O>_ҡOr +w4(U\N=%`+@>Ga[rLD2zZ - $蜞ك`aԎa덩 Xڼ<̬s$ZXSMЯBP} C~3,DH?H?klqD|uN,ߎ*\I0g%R΅gQՒM:BsmOu7mͶ;Gց{0w*Jv{ wnu}p|\q7,ouB$!erf7|]*p 2 *2u~ 39JUfQ0 }p\#`r_-/-7,Xc߉7wP3C2P@v?C&t)+ eWۭ#IĻJxP{km7GJ N=lBzn݈(q=+q> pxU]H6\ams/&F ;W |;BennTb0~B}a>_2V lOe{t8 *P!Bkin)N !LB-Af!EvNkpm \MBwuښpFg'H6E"9RbKk6` . F+(B1Γe4r\3u{ɱ2>9zgC$E8Jo0 N1J8)#f ̊.yz3k0Is.n%Kk(qger];%rn 5 +G\ M 1Fgߛ9 o04-oM\Kx׼OmxCQ4_n񩕏,3aM?"VbZbYe]-9:ɵ~(yC G%d=-En+g9HݦpJPuIۖQ92=WqXj慌5aT&o=eeyVdkrU*SUQ]ܪ  jT5-Viz:MN wMmx6`93ķCǞp9Ѕ^j֩iVK!ww[8T./ھx )VbBo/AT<ʲݘT#r&_M4 vVwr⯍]%3!R_rZ!̛Re.v1a+ـN;`>]NcXvѽ{[r&a=Ij[]VKYWwuA 6|v#qGtȶWI'weeI]*r"3Zf,7p!s(T]s^=Lp4p⼸ᢏ?;G9[<d8'֌#z'VXdYӫFtwޮڞ( ywm8o W81Wmnõ2õJ!CC4)a)ʘn,dYR}Ò?]O.`|R9ȑ/,Lgpl?W>FD>AZ>;$uzPK nN:c?2R+org/mockito/asm/tree/analysis/Analyzer.java=V~1?^WgɂMae]~&d}79} GLf5`gy<L+AP<-_ g|fy7D d1˒M <}`yl%)lrBJ2 S<]yl&>7~8 .Yċ;e;x4qdjڀR.-6I x$>0c D<%eP "?\4~n$5(V@N0!BH͊ǹlwfI yQV솘uA| #p~.g7IiPd0G @ʿgs% xuUs& CKu𐂲dߡ[Hocٚj7D'LbnY$"޹2wz潷f6ϗ;>e'f凙c=s59o\ySxr3HhM>0/3utƜ˱̚x GSgv L=6v. fW6=clt_gxMإ5ؚ˫PS->@skrԡijgKϙN`%ЃOI > bcޟ,?Qz3 UG tA&/o[{2u;ݗ&t\rоB;Qs9g:} R_\uAGjt.M@!r>U|dgar>c?'OuRCJS~ 䕡n./MטW@ҞN `WP fuZqy \|ެ]H͎/8$?^~I-;S 'Nbɲ$"w 8|cb#GqHrE,gQipLe F0Qoo@=)S ~nb' <%a `qΘRw0na fK"0&^ m,nUNrY>n@FFV@dS^aKp$coĽj4J'08>XJqXsaZ|e822|O$_0R8 ݦ`P%5.~Q6̕YH ļ^Cؒo2]uQ¿ `{+f dP@%f5MaM'_h50 Y Mr!|` $FSv 5Na?L7G@C VoM4+S%kBԱ^'4cC~"M-ͩ?@fra~ͼ (-B^o5􃀃w>g=k4 @, N,yg_TD0۫*"+04.kp˒ֱΌJ%+"/K u349Czq^xS!̀EjkAk3HxcV+eaÎp &k~͜_1]0mL=5=Tp)c6ۥQJ[ ,,zgFuk!$r#yȴT#~|@녇%#vU u5U4!P+x&WHШ,VSWZ9A4nX*~Pg!%!plcsa￳~|ﳙua[KB'c[y ?n{^k/$SxLGU|Tx[bAE*WߪIRkvYQVޙnmdzE(|\S[Dy ۩7jWw >u{i(0(1cdH;Tze M=KWYyvc*0j%n=>51N9v3h=Z팄pJƴi&SeXv 6O2j%|#e?JT'*82EEjJիfrYۢ+Ulq-~kZԴki Ϳu7NVAZZ}7cw.hcǧ!I##TVL׺t3q&VJq5X i8U^%@r%"#o:T$CSKM3X٦K|Z#Oii+8w>&9^Wox7L=_mv2d'ŐiiW髐мeB$.P׻iV1jcau5wWU6|rYjG^iv3y,#9B^De̍015"ZU,C鐽Vq[w,mƫ ׽$Z 4:},@J~gz%Uo\T[u\1n;V`~blS%-+s~Kձﯫ ׾ugڥOߎIGC2/`nA3-xOZ?W"OwG^F,VQFIA^y0$kےT S΁Vjr/ 1PK )w:R`~?&5org/mockito/asm/tree/analysis/AnalyzerException.classn@M8MC ir s0ABH5HHQhˍ[;rl(57H<bqm|:11N]30˝}7)Nl j` =7v̙$Ca.RRO+]|1->|vR3 fX dOeC0;0 D|o9"Ĭ31/gh~:v`e&wB՜a,y(5l҄őBylE[O 3f.:PLxauGS-t6 *;V[/tU"8}1 צ@*eΗ^ -ѳTx zCb?춄G2^tM7$zdkڥx)jB~2Sv՛">S[pDn%R۸t_w1@Z;eu5A ;|)k{(M[i r]'o90=AHp<ԨG5.U.AsK|M ԍ^) |!˞ ZHbC{ʔ}NŠղvB~@$Xx0u^~Itڠc#a"ЪuSc:\ؘ/Ǧ ̶{ Nj -5Y;sWg!I"P(yQE߰$b4Қ v6.!ćs$_:d7 _4u-'^!F(h1."G;Y~#')Lk&Uj"[Y?;.,k 7V qWʟ|c(3\9_?-YS۷3gъsʲO}rpA #ŜnAts(xz0,^0:!S/uλoo0 x+u$-^:pPPK )w:1t4org/mockito/asm/tree/analysis/BasicInterpreter.classWkSg~BX@ZP @[l6d޺Ҟw$,,^TjT-Uk^xvY2JtNq:㌎|$`[g{\ש@K O'f:fLCBjJMgl]hԌhث u 59uga-)XX.Eۢts@Mi/zQ @9gĮϜvp@M4+gMj'@­.nGѾh[,+-X^,nBn"+MM宨^,{ !၊a) GnWWd;ꁎa,ZG: 2[tf|Fdʠb ]}[$kFPBH=]8 0gnj̴rz]E'#iy"EO v8ݻn|Lv7׍G% ;8"q؍OK v4EF0Fنx CvОӓòh>œ"25Ѥr+,lV_SWN:{_'fi{G# .~i8w4a g[M猄֩'5>UP7_&G!bA<'x^$4>{O|Pg/~`N`D_( BV .B\8F2 Bai9;[du:VRӠ%s=M@7b;_S]hvjeB{pOl5-ZSCK+؊? %AoQkd "H$iX, \#]r()z!$)'{{1̀]`.u#>o`/>$³ ##0U+ +n-D3MxPD|ĭp*&Jt>G7Ieʌ8D<ߚP2P1 aB^(?ogңeC;Pg2\^(1]H`Q0nBָmhlS 6݌ cA?T)P/P,P*P8i;=ϝs*%<'w_WW[st tKDa-*W-2D>I9)L{x(Yyaä8 Exgşp^KEEŇ_+-uYiūJ;^S;}x]ى?ɳ]&yLgZ/^:' Z@e~[=[K@'jw+F#LO| xy%EF@tgO2qE=NQ0pj>H@4kB?<8@N?hbx@8n@8Kĵɔz#Yp-y,p 23!7<2 p|lJ!H N@C=TaKQ ƙ1f [̣f<`H?&Nw=:XO a"L 15ƠfBMf)G~0d캖OKfRpח }:. X< }6-Y\[V;ܒw6!c@&aF3$>X 6_0j/q蘳1uLTO-d>Nb5+xhu ]İ..ڍ`#rvj_;Y[AViEpXنa~Kec )&waz=q9 ^zMŻ-.^GijB O/`ޞlaəhu, !yVO|; n_p.n# |-w*O;b.J\\ fm|s,Ǣ>Һa`>;!-G97oS<7j;X >}ڍ5M my ] -|Y-ZqVj.nacVO-BG ZdQT,'*6fҾk} Feѯ0E:LzTC˅N{gxyLDM>;ͣ.-n6Zgnb |Z¬QYNĸhna?Z2cC̱LÖzJ dDmqEgQkU__+p!޲wJcfhm^3Vf4=けntqYw2;:g &hUJ>SoiZPb0+3CB1B~lV:i崒whITKz&-ir9 }N\a?$Qc5Bac ƒfHǬQT[MϺ(*[n<8G*U674W^ƫKIpA!~DY=C'H~wy1 1Ln$>x^Kteb_!8yLw pU/aFR@~a"輻q1KucQ18'cFC_#܉AG^Xu(/~!|o"#}tz"ޤR tqVEԨj+ߊ>*o>u]-7-oSkItK!"S,+"Zڱdzy `mZ"hcܡJ(]t M׿e}7! 7)dM*2sH"[nzʶ,)c6F/ :.Qն;UPK nN:UDE=-org/mockito/asm/tree/analysis/BasicValue.javaWMSHS吲)!V65I ɫ50>76`>yu맞p.>[YA"@ X m೸0_ (Ԫ΄QeJ򮬾YqZW@/Ç_w~ȝL*Qb!RD8CC%nbHv3 M浍EZ*@uH2We)see0yPKڄ * +YUUު>aK"Pw,!\4..yyK[-C?EiT*h4dH8mia4*e >D}rI0ִq I0 zl}FkS )V`2z)lOU*=j,ř(,~X]o}ECZp9QLh(wWlq) ގC'.e[C*#(5F'.6 A:DyD}uئ2^=&rC&9@0 4ѷ(،Bu`njߒ_%ꃯ{ $T=J UChQe>U:\9BTYJo򲚲^j|î ?58Z* VC#L):\N'NxѠ@#;$߷Z^39Zg&fpq 7ڤevnhx ?7O;НK;ifiyyw7<@ )ކhA<,/퍌\_pQoCQ~Ȉ>QվF4=.Wʬ r_1$6_D=:[,ݽϲ8 J_'s'A28CwOPJ!e;rjǔd>™U Y\օ1,J0La F:r{!%Ϟ0O߆2?JET0Um&k#X͍`NN^{p!=0//2{%8(ǻO1'0c-""Ic3țfzY GN;:?ak_CSZ(V%$?NZ=NǧbtcS+ō9I.E;OGnǒlm r[,gA ry1}/.ڏn̦&7y,*=ݘUuy251ZA_ZWw㚇bmtŬEP̚bY0xFI-E, `BzY[$7.7=Wn޲E^V9Nyv%_b|g5iNՆsx3snOgb֗_}8j"-wxj0Yhki ZjMRvTܮ$ՓnW0IuNRݨh#DQѪLQ100UTcjuajV)2 i=Th3[Qh$f@#l$8|VQ9pʣPvCOcSV bӋ07ctXkWW$\T|5ILt֦Um6i ֌׵xC[7o xGۈwӶm~ƇZ>c>юS|ڇv'?ڟW|}VDD3%t2X)Cd>^Fe1dOqt9[/s2A_,qKţ%_A&@@&[eM&mK,R9qgjJ="sr0HL7:p[,( ؆AZY7ζe6geT$@Q&|szr9QfլB+Qdnc+ki&d7aG]2 ERR̖r,h UR[ rllZMxc͹]d1ȕ8*K\|( Xq7Ii_xkwЙ\J+!m|GS1` G GQO yIj; afFSm:t~V'r>NC\k/vHQInu0ͳeͳƣǛ tGwaZ̥jj_g) E鉆 lGviy~e(qsNv(4sC1<_^I4Uce7srָ*<#|GS,K;ײgXW o ̱#Z2-bR sfT:̓[NnxyAco]@Ɨr?q'nS̍g$ȳ2ϝ=_>G}fM{HZ[+Dz=IVl=Vl|$Zy,$Yg2/$y=s9VW~Tm-sPK nN:S!/ <0org/mockito/asm/tree/analysis/BasicVerifier.java[o6^xN|<&KTU *?K!M3`>$̳!H'0p< $JJqS$ CK%P6j07dN2'eY!w<4#sKb`#]㣎cfj.i}j3kb!Af_#bCHg \ uoYK|;MƘS[uw&9O6gC 4'z\=䘈tK#]lpF>:e-I\e",,-,q3tP$a/#4 tErlև0ZW1k4f.2 yct8׽KcYǕpȀa:}O-4np;6׌0G]u0BB՘J<Т_P_"1u+̄c`>S7_KNFDqIp &z}33_"ǯ_M}pVmk :N$x=%nl{;ϛW|{SCqb>qN*5_UO:O&'窞yUmᙩkHMtϨHj+.wTb&.݃p[Ae5cy-{y|>~}y|>̗gxy|>,J8 cq9yD3I/ r8t;r:^GpC8DTީ*NU݇w?jJ=eg$>c*|TS3&ӇcdQҎBSփ’XhvsV֛zݭFe)‡$|X3{ 0a(PZJvKiMyN]z ɂtzeH`D pW&N LeG T̲$[ N*53L-W+N|(<-`6Z!vS+(f#X2IEdRTWTcI-g{[]٣rvKխm!z{\Ss9@k/k.gfͽ)cqM0顶F6G[O{j9=yQQ[-> b%_$F*H[֊ڢJ{7c'rBfeWCFV4^|`Ep{pO*M6FɌGPPnj*fHpD7C4-j\Lڵ95Ԟr05lN p{,kz\umx^Kdf %&U+] \gAP րA&ًycE2 AQԊV7:`)d(@9X#@(O-*kà9|_N jWzi?'z;(˴/-ғlk{>JNJ3'tŠe9P WtC` uvBC9)'M통9&Ishd.3$g&vBs %`7Tk$]r|ƥ1܍.SDtCP9d0Maqmr ڎt{ޗ=rɳ)S(`=|#WEKO80<7VۿH@,Քy]bmu4$fQx3M¢XdKX8{}km-+[ rH?LjfF8RB& [IȞIзlmߖ;8>n3o yoll3ls ̍փ s磉S;xax|aD1t}{I[;7t/v"'!k}9{8x86n1042Axr@q@2bPdM삮0J8TGn;eR啘d[͖v5Ub#- T Sl2jY *^Ath^h1*BvPeOPTMKBT 'y>VGjLpi6߄pK/$ЅL8 ( ayfgL)"(QH#ct' 8^ċ:(6$1YFt[0[܊9ݘ+>yX|/`"t8C<3ŏBIR*Α.K)X$MbIKDR.TZK0.6c /v`t?VHJ&ur8^j \):}\%}WHt[-˸F8tNlg[.F =\/E vɷy0$ǰ(ɇp|7DZ]~7'*=| ƫQFxN۔|A7*ex+ެ47/ަlە-Cَ;]xTුøK9(/ ܭS>Oq9> #!5V'~;ԙu>#j%Uj>KukzPo7-u/~>O) ?Uԗ3+B}~d4Sϙ D6Bhm44-kXdi3,v]-eilV&j.6Ikd9jmlv=n.6UGYɦk?b3W,U6[-.Nb4+ΰ:cl>-3Y>9B/dBzez-ү`z3׳Z=VV~dߛߡ>RXOzSB0CLMKr-:U϶TdKi0$Y4jxm6;<7F+4 %c2mM{ m^ckK2e :0RY a^b>(b~XZi5w% řS ǣ'ѳ8}P*Nm~2~R>J Ia$Ps{)1~ ?ל'Hv0Fa23 045xja8AGǛe¥tjd;3lcIn>m2>脏-8c'\ِnHmJ'(2+e;Aew@22y!Ep={3SPK nN:q8d(org/mockito/asm/tree/analysis/Frame.javaksH;U ƄUP,9Ѯ#y-9(Jlj[IrB~3,ˣ$lZ ݣGǏ߿G9yE5uC'` a`!UC׆ 5f> 51{@̓~@aYi8-XP7$IJ]3OL\ͩc9ڡ3ft-k {ڀ􇃾pt(n:fz85,8ZW>&!G3Þ 90:.J:"^8}cʶ!ѵl(4f  nw"gx踦;t rd:ӽc N͎0 T\ @49ác- }״& z`n[LlP=Q-rvluI4TZEP Ju 8G1pFLgc4Sf: L.SO53u# ;ǩ yvqEm/Ҷx؏߻ϟ/(!,Ն1kkQ] HT Z=Fļqbq`6㚠'"ͤ.rEBjN:{ϲQ8F1OqVE@!V?Y9ĔY8f ץ4$ dmL+^@Bxдəb^DH480 8қ-!Ce0A`>]*|c^bs)E4e| a`h0Z4 g= 15uXh&Orfz dKHuS*jr>Y@?H:WjB.;Pz$ Uayp|c?O-<&AWBK:Q9p^fBYu NZ"0 5J%=GcVW#| p163+<%fA ~'8)|S`$cA@4L(Z,&`3j+(s-ӈs't0c!XiEZd4SQ5/p"_{2 VJ5+&kKi͔+(#gU>8:,p7_EwE^Dl221]$OS)IHq@ZBu,++I z }jz|].i*555ay11Y/}/L|m|-|?ɌGXrl j(P=eO\0z[0CJw3rXƃUtJ)E*KFUKb)|P4waG8Y=@U#K\g oRyl V4[HS.M$ˑeG0T{-7(FΌzQP1F j{2p5&7Z͇( ob޸*dWkCtH&ҍ3%(n` @:8Mů>E^jQ_Е-*yk[a&+ 7fr69nlfSza ^N؇`?Ziѓ'+;We2X);A e lA~R[{Шp(XyO} 3[ɭ(߀G|' J6d~+0؋)Io-j}/iv?[^`'kՀg̋0/kKӫ!W\xHננuhα QB5Y0+,6D#" (mlMt&ʌwLօnmʎ|hn7Yk!4wԘu)!J] )!%Se!IH%叿K.mL UBJM,se*_Lpeb,(tc Fa*lW \hP EVDD %{fqS"-Uqd(}{*uŸ]Ÿ7Ɖb7^#]Ÿ9.p)PrWbtLRD/iˇx\oZ7P̊yL7vu}wr7R=9yW.XW\#uvLa篈I@-4~җk^A`]wy!{|H1H1'z)k&XV R)ā`WH#&}۲cb#۵w@WGo㍁Qhi.rL#ŶppKPt DqK q5_4oQI j4zl"WIiڿjjoڀ;MoTE_/U y=* 2~`jg4Ba,+dcln1toU<:]}ؖ_aܓq7E-ds*cY!* [PٟǷ[7zؤ)?Z%f:S.zB5X?T!W/BFc^ԣܐQl)Vs $yDK9yNKv ݂r|}Z+iL=H^ko}ǂF]^$8D!|YoTXMIFa8^yZе6v㍬ &hCҴD,tM@֤䂲UmJ2I01}"Y'Gyd3/|/KIs}rjr =CF} D!,* [&TLԃ^" ݚ5qy0mɖݦ}2䐼`Q.?.1g'ELjjҼ]lQEQrecPK )w:s/F/org/mockito/asm/tree/analysis/Interpreter.classN1"0ܼ5qB K2ێOⳘP %Y9I8!C;c>[ic.̔[MąH{ʒN45chMĽPc>M(];"*DQ/r9K^kϟwj.0!-`9]wd)Mnvx"}R)28-XV7R%Fs$=RڷپJ[{\g>XKcs,MIݐP/~q8!ˈ }"C hPHc4&<bZ@PK nN:a !.org/mockito/asm/tree/analysis/Interpreter.javaY[o8~/@SRx6mQT$SY蒴OfmeɫK!u̶`yD#ٳgOgŠD*Uu+m"-6"czFˍ۴vm6YY*ݪ<.q>ϟ? ҚJiw>Uu6Sz/C[ދik%Be[gE /j[OM\lf-7Ef'"ةj5ڈ]U^gUڠQ`MV\uYl2ZT3ZU+~x1ݓE'VS UI!.Mkze4\+&[ d ;]ymUŚE#tଛ=4Bc)VMf)15Ҽv# _e&p8^~qUU80M5u'ΡYMoŹ"‰J FdږZ]pL0u!0&ZamFNX;Od$ϬWap*mxyI,NvHXQ?, `EX$ (A(rI0҉&Ĺ_L?'2ƴ8Rb88~La[Kkc`y:K=pQ̢XIEج O܉^ /XyILKlkг$Cy?v0Y2a3h zf> Ę㰼ߝ0-RI-T ƣ YxrsLFΡ1h۟Y;! &GN=a >$-kDҸFĘC]^RD^NS֔ӴNJiZmկ>y$ʪ@7 gϾ sPndQ>uR YP9dŬe,)TZNG3DY:7$@*f]ku-#i@WE`=B袾z@7`]h$&/iU\}c:K+HRő~}g'ai~QoĞ*FGE˶7R݄B:CjM)s+ lӔ̫ζTO]ڂo%vVjʢs?FD,8-dϺ(t  A|sմmtNO1{p"0c8 WUEEzV0䦭Y Pi? }n/IJ (Ȼ\gKXze)t֝;AQ5!$d^{v<YG;#,CVI@W:O_F$u/be'ap6g~@- _> |I@_b2?!;oJ[-SEjsS>N%M2L6e福$f=lNrɌR.6rk=n]nmn-OGI":K%9!~܂F+|>32Lv\Q%\y#Q)ȣYä &5 1F0d , xB{LVݱ~x/xqJBX;YG;"wwFWY f܍zp3TVnebCi9a?#s %2org/mockito/asm/tree/analysis/SimpleVerifier.classWmpTW~NvM @ IJI> &KJ[6%\솻Dj-Z/jh(P18ut3:~PCGQ9B'ss{>{ξW,Mv5њP&nzM( 'ꦱM7C1#+5VI֑0M= b19Mn=أi$zt3 $%H*']¶`cqk㺦ƶ kV/xR4,X%sFKD͸*oxΝMHnʉA5)TVQ%X?jX;e Vhoo[ieVXJ VI#Z`6GMGTáHWMK4"]>^ 3:+ s˭ONي l\?ӣG:+&i'f)$QkSxPS-* -2]O#{(Dۈ3A 稱lWNh.UQI+gxsnpM%BaAmiߣwĩBC:=h[9#E۫Iz5ɶ=:IzOrc@A,SxsbO1dwM3JcaK\Ԥ' V06J!a5*gxK][v l\&]B#3"`F5e?e0 I+ Wnv$P8n [N6yd<):fMgp R3l^մOʪ[:X9|Qj{~ զ_V_y_QwXfURz/J*WofB,cyAq,͜ Ȧ{~:'U83 k8Kℶ{S ]SSbv0o&"z-HS ;ќʺmǐloyW ɼt*/"%f ,hlao e8OQ~ǃ$9 9Ȅvhv­!Ӑ-U#NLt립Ɉh<9+"yRo^ԛ)5yk%^!ØytoqrGh֍J [6/ cNVڰHJ:'%St1D+>L̶M溋20J$Q \|o"*68362626TR֝ʺv&i/uQ#D h݄{I_ ՅӱK)=XGG?Who˓^h00ڳxx-u,JaM kb7`l> Nԙ–kG]bJKFhi3@25v!xەC Men.^RrwDNR8Ⅺ܇rry(^0lg+3 ): ?&߃*,LKEg9eς$WSoiyJKգzӦfIj=ü0Ɍ?pW`n/8gVgY3q0|դ9΋x?u_2(ЉC̞PDyr5h\ A|\*\ e)uΦSXS9(? =`E1SI :sk5]_&>;:L* y(`YMU4J<Re;BYMN98c ϤbvZ93G| d2OI/ioѥ2}6IP`I5#cUحQgVw.sτ(̉\eQu~?n0a7?dNtOq}K__ڑQὀw 'y@\@ŠK_J?rs,**:gßi7*Rぜʓ69cKx5BlpNWJ_+w^|m IbI|˝?q.Wlm?ö+E-\(5G̱f.c@ЩEwc鼵N/ *Q'V1C jp;HI=0 *̿iF9_%R!P'8օr]xHLApâG}LLSbki{R_5)\K@"ߛ 0]SH"$Q,b.dp׉漜eR((#JPrwD?PK nN:  9)1org/mockito/asm/tree/analysis/SimpleVerifier.javaY[s~ñbf!'}UM (ECb`i%9$I:ѐ v\s7o^7ڗ= ٺAnp]X=pEk[7wir? a[vO,==7޽{膥8c)m%W#v${VhBLZl'0&nIk$h8 yܨ|e\'5W~~k 1Ƿcӥc#ƝG2pR5nAlL ˫b9׍ 0L2ǜcA3ԬTBwn312TJ}\\-+ӖHŹn~9vbؼ14T;:]h!*<-mf b.&`_i34In'HW&+Ӱ,q!.z',n--D7!{9Y:\֬k}'0maMD-<]:PZp4Z^9i7h%!F-&{LBy#бT2V9եTC;_1h$J736-%y/u(|z" kE7E"/_\{Gyl##M S ?9y b?cR0osHuIy11׾gTD~L17>ey8e+ S^,%)ˡ6cR}v=.8ʀ5e4|} ̓9f3Gb\JQȲ-X">>)f4NCƣ63%OW.hǀ3S%uv+R4* 2%VU^91X`u+xiJ?飞;2Wodha~lzTa*tW @i,:Їtg7,fg'Ǣ$C:<[$Fc d(L`s va< )"L ҒR삨7"Z1x}IF3ZCabw\ssWQlr*қ=!<ZQjZϱ\DP[ \UB %(<#c "z =Nճki利ů~ŹUF`k7HxU L-P|G/:=!^4)KC7tjj_VF51$O66XȐ+ɥY.V%QGF^M4Dg4.i\:ǩi.4x?Ol魣 ./бbYʎuVJ?Ѭ"(ǛDȜ{2vōvYtb.lk4maM5h<W,phT 4^9. 0lޝ x}n  o*$yVث}sN[(@Zxـ1 c}+GմaHz"LmO'-18whAs'G O7==~ޗ#Z]GԤa[Ky,,M0ȿXL[5C%2iNsQ|4^ڪ^tAL/𬑬Z;Hh(IJDAmzWwnY <(Icdq$*%!b+ܴ#dWNmM> b[',2%*߁JX'hVrla 8颫29"8eeN?jElV[QA|OS#E(sCQ9,(f$Bw80RQdUx4Mfhw[e]xjp_s+tݑVH[;;H" ]UOh&6I  "kSAranzÒFC"it4l}ӯbrƭH4f)acp̹)r]J`HBw\-0>J5'Ht./`Kqc/9=@WB ۳s.B|l/  Vv¦(GOF 8FhPңh.-PJ_ qqOďp_#ǝuC%:_~޺*R)K˔}y - ~&[rtr]hr'(4tVQKr$| riE:zE(CP=xU&ջ̴}VԜ^4zDt{WoQN74Oy@- I;m>=w}|]7Yd=u%G7J?#}bg5=GuNM>%:\Xۛx}U0KjJv%ǯ'Zy=5d+F7q{ #~Ẹ֒$wC ׹2QQG#QNJS*ΰ,79œUZS]U GNoۈ4z}4SgLH6 .H!<i=Ԟ#L?Ne86%llBf -99e_6v#ltCwn6LZ xtCۘs?pD P6bkXc4B@Zu-;<<x_ΨQ҈FJQ8G d>PK nN:Ul+org/mockito/asm/tree/analysis/SmallSet.javaW]o6}pۇ]` $\8W'ӂ ;rvKʶ<4k ŏs=:{ #/@ULyNh)MCύJLQ!KZUIZꩪXqz燆ziF߿" 誖e(Q9 gv C2~Tِ`2mZ/6tIZ@➅.%\^VuajZ72ԩux@VRuFeG<BAT܊Ӓp-˥^ѭo]H+l =yQ"lq'Cxo:=8 C ҁMw9A<?N8]k "t@ n?ɋub9&bM[a!i<[v=@2ND2O|É>Ob4 cK<xÀ9 }9s?DAK%< l ,ݍ~d>DDSqҝ 5K=~0y4d;6"I™`{;&yOo(Xe||ӦnӓLϼ#?*j(M1ljDnRCF>6j.^Ȑ0Ikcn$>(*HeqekCM~ aץj i |ԯP'-&m,Cgg jT|@jNr43qjZQ0\R8rH^*gJNRrO#iA9vvЭ90jCD3/G=jvmņwRQͷUf Z/rd`[m8uc]qrjQ0m2o>P%) |(ZTyU+Y҃4v1ھs$!-f'n#V+aNۦmo֤uh5ff_heT~ '&FG{=,HsQ)﵄v01ll|UocNu}gcoʯPRm}ֻQ:6&o.U%yl+cm<]ҷ3eDRZZL!Uog˥5SY ҴZŢ?BLs,BKnF0d~Q/E_i.}xXf{AہAۻLKCe=fE6;ܒQwCD+Q-GpPK )w:M{mP85org/mockito/asm/tree/analysis/SourceInterpreter.classWisE~:ɐ͆( [ $9d5&f`w6ٝ%$5Rey|вBE"Q"AJ >XV˧g:͡%Xyߧ'6@8)ML2-+l:fb cgl:jEJ-i30xu  ,n7Y@?x)PvlI`!(=vF`c˿ 0DZ%X7CsjYO0}fU fsf`{FƢ!`>ȩĔ@{)Gm&D/6n8m[WdrRYJhX6XtRw5͸U-ӹDKQ5s'W[RN)lݓv'hnYDlf Nm'Nh_N kfI4Al㲪BuB,>ٜ-P U""PM1#S(3 "FYY6˰G_?UZut>Ȋn{̅ Cqbd5-4` 杸k'-vkܞT%plڑ7{p_y#!aV:N Y]^ "/KޘGp1xf"A'h/xq/,ZtnD0 <)cxyʭj=zx'mz"ĩl$jӿy!X)ʢ)5 N%|C+ 2ܳx8#?5JXu,lE1B}L(F=m7&_TL4ӶɷSvceVZ| 섅(GPJ0u1Ab'1l%P1pWMԌa񍜭j%GK&nf()0XrV}+vdUll߳G5tu_@Ӹ\卣: (,a$5 =$ M )ao p;7r {9je`&R9G͜ҏ_!cX{ {ɔ),s+{9GEyYme?gwTͲu+9y%Q]%S%GM$$,NFC1C1PtLgR;"/.q 8.zP4>մ˘p~fkKSɨq%m%O)T2d%\Fsų^䨅b\yҼ\U{I\\5zA>).Q9 H׳z<r9Y9X>4XW+Q_`FZT'!ɓY("҅OT 8K$Y<r#j| ݅Aڸ.q0m-ںQ "k9y7CyNFPI++C7$85zoY P74org/mockito/asm/tree/analysis/SourceInterpreter.javaX[oF~0CeQICcE-18 89yְNhX,8J,8&6$9J"~mww;0'Ȕ' ,%7H@ʳx]% VO}^)q~(N?|-~}Y(  "UvH(FD:-EOD,xY)[ħ d^DeqʋTjpw^ &ͣxE`]8‡%(I80Ϣ6ICSQ~R{$-:LF%G˗)dyBCXB\|N SQH!4 ˖ UHb[(Td%=%G+E !#b2,8bEO6O"QHt`RrsTL,z" *楀:\Xc]b7E {*@EH{c*‚,MʭG #2|w\FqU.5h ua [aB_h{A!PCvc5``0KFx, 5exڤ@5 u䍞]\:^B<Ƀ(NyQ/xKxn$[_%.yo]ә.G Z*O6,hObDoԵ3'Uv8ƻKtl徺.yRG/Y^!vVyQe̳m2eR)l`ZF'. M6 xұ( {0X]J>4tggU8|'ImoDǿp81Lx1^eJ ࣝH€tv=ZoSwɦ#+ç5}f>Ew.]"B'`0ha@Pt;ǹfSLɗ?0B Ϛsm8UDbū7v¦MZM M%AXoS]S`RETbg٩-6;[<tk?ѸfVZp_v~Z5x?Q݅ѻbfώnm~ܞ-:+&8|wmmןzENߝr[>_؛QkKǻŗ 24k\:\2%ӱA/wDEԭ==<~>ٿ~ }Œf;7y{~A?e -6GTӿ2!B{Ww*[CʨzK G$9"T>z<0f6^H䌗zgƮdU%҄W5M_mk$<7DyQ?ΣHlS _awlv=?PK )w:|Ȓ /org/mockito/asm/tree/analysis/SourceValue.classRKOa=_L[GCKF@W 5ƚN`pDWܰш$N ,z;q=@2k kҭ^ӲLYkvbլZ%, BoGJӑ-~eǪz ڣl?7"y]w@೴<1(sˮmVIa^ʦ>#~t%Sҡc0Α۶9Jpp,AO_^SV<n4[JD8ݦ@ttнvH(i!stFrm8clIN#D4j O /Mwb^&YL.jjTSM[VkSu|nmjD%ڎqJ#W_iøsZB5@ }G )[fw!H61b|C!X 7R4Tevyn0+N$r'$;4M_Q{fы \T@cU=Q3F:z;/A`ƙO!@h]A{!t'x -^d#t/FRJT2kf; 1-"vLS~PK nN:m) .org/mockito/asm/tree/analysis/SourceValue.javaVmo6~(@Svŀ m:H$ͧ鄍$"+wGoif EQG{pAr} \E(0b!`rrQy tRQR[hM/ x^)Tf^яaF 9i-r-ոr(HP]D3cU yx=וu0=,se¼ 5ŁL?&*d m̥=u/' *Z +.኱^RC_HM  gQ N2rY:ס-YV iO@Mt5Փ*aZ4XAVJdf#!o!m$ :~T l\J5G 0KK'dAST:SZ.,LVXXM d>RY4f.'TjWQTdE]nƬ9'Dt p<e]h"N4U WQa0pUWA a$(~=sDq%NaB_#ŝ+| ڼ[Ӑa Nygb ApD˓N?׬c SH~h(m`}v<]1̇+i$ IM/n]% ;V#B4) (@C[EAн~mHxSF1v#r7qG'AY ȖF=ui#R>O^x!c Sد݆]_gxUq=onz Hvo͜Y+󺅥-f]Y)sOذ:l:hp5{6X=]VXU3fl $"rIĦ_*5.(D NݴV wAj4Nfxdں-gSj-]NÉ(`s @Iς"rgݩc-khsnk44Jxnu5R<lzey2t cMlONAg ZSG'_Oi8?q6j9S2R 0M?'M/"06[ڭ l,D<{pzW҃q1~w|ϝ%G EUxhk~(/&Ow&ޔc3GC~^ԫۘlpPK )w:3.org/mockito/asm/tree/analysis/Subroutine.classT]SU~f@,,*ɦ"~@,RSW:#HjЭ.a:{ Bgd?>&Bk6<㯇U(Ѧ _IxqI"/𚻱;z?9(޶4`ӹQIG^⠐/J&ܞ]+ᆮ(  [ l7ŬMD\O bi݂W0QP0;>CzakVpڪqci }kH(vAq y I0FvƆPؕ- qcB!#uU<οpv.K//[ ύnV%i'}UM,b6Ft})$FAnG{D#lKGZa_zًBSttu~Qؿ٫YJ.V"= ̋߂B_# b uZxmNKq%O¤^{^oˀvMa;je1V |8j҃4]q83 p:I4HM>?M5KIII`0hfa~3_cd/:n;ab ^Zo|Zn& |1B>[(x+]@V`[fA}qLYWL :9ه- +]*Lt1K !KϝB:| `|; ٩qVjk7Ó?0(e4z9{Us1h>N}y~MMj g1*jZaOvI&er>9P(w ^GsVA =V2s (ժEt # W1ҫGw>===~܈2&*q+,i1se+fE|j+A`umffHyMa=xPhu]9BBeHXISsX}8D?\?r .YC Ys/YЋ5F3HpLߓUȡSJeCe!G@Fv)¨Y.T!S >!;`OlIt 5Y]Ȳ{ۢ`U(ۭnHor ɡĂ#V4;ϥm@kt,#$fAsT:ȩЕF.,LVXXmzQ=PYv%3*5\ YٔFzHƏxG|0E#Q4e Q0fq~80pF8Op o},I _M!ÔÓ8 c^x F)FvhOBtW,]?Oo]s0㔏dO<>bYBr^MbJa'ap& &<1v4B!fA2a#NaN~|!nӬ0aM`_f_mMcvEԣsLIi"N|Ē3ĉ7MQR *f ' Ôt(ߠJN(ti`Q|Kn.· 'ITqv]1.v]#FֈnxxSmk?|͉~-Hx[F0.-pGJd_ŒNrP쫪@bP)UH+m*F>6v~c9.Ve]1yw|f}Uq`֠Jw6xɭZ9>$1vMlxg;~57 KY鲕lPhjK2`+alDjo*8>1Zbg{Y*G&ۚLrY.nɣd1#xzpԞӮ]Qզl>#^OY^SͶ'[gwiطLFG5\v'ʥ$ ,!IУTh<=ÿ?vs>ׯңےi>ëWbd=[KfSl~n_;=BmŴ%ǡ;nwǃ ;lC>B,eS9k/<Ïe>Z9e=I=񞗵l[?PK )w:Y|)org/mockito/asm/tree/analysis/Value.class1 @E$1VF ^B؏6nl=Pb_<Xah b`;*K/1/'5 ¦U rR#FcJw0 VkIP B ˙?PK nN:yI(org/mockito/asm/tree/analysis/Value.javaUn8? zJv ms!K^#m I4H*!e'i{ ̛7oۛ /?ge:ٶ yS>KڙFA'{}Zaoe^}9~xpOwww%i3+ZDƨ'z8)I؈L5yC N"RսD{c;`l50i^"UpPޫ<Qz|)j[ؙE)98?eP9DWns:)Q;v"`ySFݵRwFӯT0;YT0f@z=C5f7t\[,AղuoǺ>R zl*_ãie&fK;3A=)EZ?e\KB ?; N 2ĄsH&Bfo DE|E2RIwVU_52cW)Y,z 0`DcAX:d7.5u ti~O^[S#ũ^^I>0I{3xD=:\^\^ܞot ^n[mMGYCX« *?0l)qƉ__倇1C܆m{K1߁M#KGgJN?.#1x}6nj+0>ݎ sDF9PK V[5߭yJe *org/mockito/asm/tree/analysis/package.htmlVMs6{aȴ͔!-Ev:"L!({N{߂T$'oZwUt=vGReI^Jَ~Uv.Jf-UgVS~tfk͇uG^]^^'Q"1ZU2]aVz[Lخ5[l&Sm-x WM[1=nMMͶs0U4+S8cRn+uzIy4K T͓?PKÛፕ޸YjV{ZL[(N.㪇摗 ~uәBab,dgsZZTuJѫo,{*u Mtݩ]XȠNF ;7F>G6n#H8f/iݔKZprGb:g8zу|BD zYͩNUiBb /Cͪ{Fjk8 [NO7k9FƳOaH[&X4&Gf,<1OEG$/'$P?ʤHǸ0dt=&Pgʹ`cvоJ"՟PfLfO ?4yC d: }9LVD7~~q|Cx ? E2ӌ#;41 1<b1pbG=! (5B8i9Sg('i&<tǁ>ɭ-qS1g 尌$O%k+e"IE& G<\,Np1y|0K|$~!jv/E:" ^Nl8B%0d^!1ͧ7sczh;<1+JСpu#kUu3T^[y]qUQ}pu9@ObR1D+*ZjDG}_<{;G̤MyjE멢ЛnTxorw &5۝\|n\joY]˗ݚ՛a0yeݍ ]fE~352j!/"Oi,k}Ȋ zcqf|?kcË cbأڶEݯ' КWHZk:!rﳩgz߄4hp_U5T=Cn-7PkM}hdwU=6[ccy$#3D'Vx1ׯ Q)ǔHܽ,O"?\`;y3B0ܖ_\GЏs1\٫_PK T[5) !org/mockito/asm/tree/package.htmlY[o~7pBrA_QZm䒔c#rdMhy )Q7@P!302M..tvv|D!'H2_S$!4EIKAu)#KJEU"J3"+nxbyI~~9]EI eN 9DA,dq7̦/cUVFSTFrp╩T<-RtnuU6LEF.\B*K"K㡜$%^"Ŋ LexӮ =kԲ0U@.WLj |2]HvA Jl%wՂ(*A~>T"[4ָz#mڰuT2+EsE G2W")1!־=Ie2Acy?u˼[*UFò LŚ iYUɡR]Jp!0X!.uc*\qXFBFj88s̆[Q4P0%<o .Owsx8p& 'N'6錞|A@c;s.2? MF㐆ޝ,wYvxt[t>^8byн^2t|c^:ޝ;A H&:Ǒ ;^YfCϹV xٲS@Ba{مM_[ƣ sMޱk(\NBn>ph8 xBJaWc -}Gp#P 1'fxt:kL59կIvRTk|yq_ZpvEKU$Tb|(LCjlLB#ԁ4hZaayh".` P.r!A}Ԇ#:jo5_C9Y+}I:7.RO_cvsh,r!3uӡSNFBdpQf(=j3mGl]ˋ:/'O.-9l͘!Q0Y쩅FC]3ˋsu :B(k0Ln6#oIL{tZ ΣKhN~1!Zӆ(kRǒDyOD\%9 F^mH78-*;¬zʎ 3)n؆m#G2 [F7mt^mej}'&®W9GcB)8l9؉'MVk:fIÚCQWl7;/I^⇜=ZdΦ5UFŴYTcnSFwԁGPJa=]j8@Nj6TzDYY7Rh.{Q7:*V+%%Ӗˇi!۵VR=*sH$믲nof{νϡ΄tٶ??m6o/^~N;*m;\ftT"¡h+*/l31r|wSIϟ?{Y%(SƆ6ef\{UW xcm1iͩ1&|yJAޝ2=N'Af!`pJֺ2(vyI/m`b 5ư6w6C&#rG"bv"fƜ쫀,n* u:c1dq@VPXJ EPn#lXșrG&%7xiufy UZa=m42@`_a^MX*Nunr4WVf[3Z٪|3YW=`riY"ڏ974αzh$entjSedKk&] 4oɺ };Qw&4-e3̔U`MҖovG[iq⾕E pgeGrG'RNOX/s9O?}_C;X:6V"+[Z7+-{|.j"ۖB~Vl[lqW|!q}KdT˾C^>_A=ۥU ;4wT< ido{zVso=߁][oPK )w:VDZ%org/mockito/asm/util/ASMifiable.class;o>CNFt̒|\Ғ}`̴ĤTvFFIJDļt}vfF~*=F6i 6>-%EyNiiEP֚a \Eɩn9l L , bL PK nN: pk $org/mockito/asm/util/ASMifiable.javaVMo6xSv{({YYc#iNؕDE{;IўLc޼PWWgtEaLvT {wmј`PA4J4Q~o4OJr gY zM-Mܖ?0BZcb+i-m=!#M+mSI^.&/Z9dXd$Qq:q!jq/%&7,M-~ yn'q.DJ|n.@i|_FXb\mE]<0iu] z"vghv@rrغÍ+٣yǍ2"ǨvsW{#ny義|4Ob FqYj4UTLb#|-.:6wui6rT`FbHb}kc+ZYHqdQDcc4n> h=n`xo`d7Z]&ji{|?Gxk$ht=/ zT_)/׾Ӫ&<_=L}Hr zPK )w:7 2org/mockito/asm/util/ASMifierAbstractVisitor.classW{|S{!xUDMP( }n'--ݴiLGU EEEQ2g   8@  ۜ{?g&i n9_C`}HЭ[ш.5"O8"0! 5R%U1W_kZWQ)nhvWGB@sͯyy d>UZكf,}sjTgN6m!v % 2kGqn.E@0E|~{E 6 _mj å#/c(7R 4GZ藳B<cl (6+3VZ[7Tp#&H$BV,0,?%N+njlR #Z <˼ Bi_\6:K8I`>nid,M>zTE/m]FHS1MOq,ʹƫ8Qo,931eRSoAJfoFwƑ0;cϡpd<~QO.0O52aD<9o!nwvQM5e^jX@jE׎:yjPf$meR OF-XBtYqVdkXí3OrHi0P8K(U/FV4!ce O̝}N<;l=jC8һsbF~+B< PnJ6$_U5LeaYm V;Vׁ|'X1+^!GlrtzC)},t5F#]=v^-`cXjWt?'lX'6ek/()UVؾ%byI pْM~ed;v+J؄lEF[b%ŝN)JDU~^W"f6 ?K?їNRL_ʄW*ޠRH3fW!anl%/)؂]&G{+v |wYO[Yf YmAH2$ZʕXpK{ $T'L}}ɘciSO oe:M2Jr Ι6i!>%D ѨG,1Jb|*1Șs"*Ȁ`~) 6hZ-7MdVyV7dRlh[{?eb`rJ(m݅np0 ]ߦ# PE;:pyyX 㥙.%$^+)kyMnrLKVr9?Opjr9;Sta6-r9H:klmNNdT?R8Nyu.ǻqA]??PK nN:!1org/mockito/asm/util/ASMifierAbstractVisitor.javaXsF~ߪba_֛E H&@#\.Bx a{g|ݻo{aŊG(aB0 K W!L9<̒2 yg0-9{ȋc/dvA?׿r̒4-%phJ1$PrD"I )Zpq,a2g` 6U6hLA_%Jրth9g؝bXr(08+0-r߿tpX"@ GV{m?i̊XK$,B?$t& =ʁe12Jis.LLN0/1U#*)PEj6$,(2neYy$0+߽n |y54пIγ.r`8Cu:+;r#܁3}\m! j 'L;q`s GRp/Wi- +pH*4`dx5ۆ7r} G.-`ֵ9 _ؽuL\p/lۦT-mDv9D ﮇXo8FAqm\0Lg^}?q`¥X?yc졖 i|}8;yQ`NC,!. ]G"=2q#TA h^$5h yi[30i%[7*OBTk1Q BFRDcxc/Z[*p?\-r">3ڑ3}Ga9ױ2o߼}y (:7I~Q./<.XSۯ uU"7Fz),X+i,dp2/yV8,k C*oKJ'2J4U0W!IJ5LY*zX쨇Ω|I<P8,}OoNX*  ky`(+U. -V|f␔5(y>3 o7mH 2`h%>=4>cVE Iq9M=c6ņ6ӥ0I. ?e iFf,cͰ)Rc~zbVF_̦"Y5Q`؇S|dk"D^]O& 4<-*u $r+ rno<&y0 F&˩^2nlﵳTX`A:ONw=U=|:YsAoi"Ħ 3LGv=='G+9<=c x.ԺMzSlE&\Q+h,\3TU t[vVɵ6Wՠ-!u=Mh f'm龐#?l-5|4ewݓMU7ꞼP<ҨiPu7tz_y=fޯ. 7_xuG=RV }p-[ZA+Mk~+,Wj-j妪Br%}%3LU&Ć٥ rQm$ǯRM%h˶B1 t*\y$Ԫ Ep6AsVz*=w[g50?'=5.jZk"!5.Stj+EEvYrXrUJ&LmWϚCAm]x%{bT+6imi)rXREn'є ;HR㒥Z8Mպ?kc Z8U?+oPK )w:b= 4org/mockito/asm/util/ASMifierAnnotationVisitor.classTvU7 &MR"TXSDHB>5b1mNI:ɤ~ dCt- ~\;3I!IkGn=spUaVufiQO7--iM5guݰK3`8NaJDz&#$<"0o}e[he(%M׬+b ! ‡G`mj #8-MsѬ)z5LMf%+c(6+'{¯5+̄pKcxY`ZYUZ!a0WpܕI]Ru+&dc져32 V 9V;XsްB&{Uy$#IHi  ~Ɍ#EJVkXޖ# h/aNaZR!g{2U>nqeJ]V3Ԛ]nٖw^of}=rSDu"*Q۽7y+[=9$l7m`99kU= {tW XC+tTߧp^bDZqd– 3v?R+(kj^.;r^TMM.h5/^iS%01#w:'80`[2J{^S>M /{ޓO8mU~ip6&A>l{mϛܵS.Y\#i}FIut0J[j L}뭶M>܍;N'X]8grر?tidɮ#"E qܣo7BՊX"Uf]g|*&ƌYSޣ!Xljj$p}ƎF_6P:}5آS4M|m<˽R}gSr% Q>D V7PK nN:9mʻ3org/mockito/asm/util/ASMifierAnnotationVisitor.javaW]O8}G?\Բ<4hIS^0H6.dGeﱓ~QjFUq}s=:!'B925*ZNTR!l6υΪJRwëf*ԙt;|L<ЩDR"s W;jRj!Ӟ1Xc$Ӭ*ϭ/ϼTWs$33J*j3}K0EflbvH(I3LkLU,@ / <&UffSmaBO޳j˰`NI-jaL-COYl",jhp֞ma$Y!e>,CA}hIt Vy!K-;BY*,PP*y o&GFLTfn?cnj54HWW߬5.RYO^57o]'VM~*\g mvݖ DRA#5旱v5󏤬Uk}ji~ɣXnNsjӳ`\´WS){IBfs.RkbJ;%~}_/PK )w:Of#/org/mockito/asm/util/ASMifierClassVisitor.classYy`Tչ}' „ !*&$d0$(MIf, Z\ZuuusO-NTk֭j[-}n];3$?f|vΙǃ,,um DCUHU, p}?Dv@H]G`H2sřUN=mm=mmf!7y`>_ck 4N 5kaUPp ]Dp  n ު(izk:Ćh tP[mn(du8Rbun|)[bLsb*J d(˩x0󭍈;t3P鎆ܽf n]:NHz6\' ax*(8NA}mk.ugJ{ݵ=nMmM7UOϴP e*- a#-cXVav02o>b:EP[M2#kF/2TcQ8lCHXYZ貿K׼`y(TIW[:_ŢY ݖp/M-ЕANO_SV"k; hDуs)(%@9 gRwǂc׮|؅٫4ϧ292=ٚ4u@UR;!'wmeg*=S906TdQpZEL .ȋp^h.ک ؈asejğ.M|W4p [=jK\s2r ݝ/`8\/i_@@(ukJ-\K2Q::1,M @Wbs!?~SO=# V ygp[sqC;"yd}KpU,pwp/s4d2mnם=5;*3%[8o<`H &h71cS3QOUC`,4|Oחm6z͊w>ͮV[cQܥw,ش=6Tm6}6 bZl󖩘t?TQ'i#eǰJݓcjŋ^L;eL/.y޿b3졡CpZZ?ڷQcW3'-xC$ `48CP;RCmN)qh6t?rd2bX.4YA!J-|MNݠ6 w}CJ˳^ig_#{,*ʬt,%_Kccx޴zm]ސJnvx ϫhioool06d{M^ِ Ymv-4h;}+[[|{imVCjfr5S򄘺Vo\HifH]¤Vk7!㣌41z[&kѶ 93SF9ќ76y)ƗիIV'HQF,H(hh\XﱢVWfoZeӕyI :>y3'_v=z}pk[894}f8q6>Vha6M4ȃX'\O[Od"O$XCJ!voVmβoF^Z>zLsM)Ϫc][7Z[1^vG;)/vUQ% 6ƱXD Wix/XI b}Ƴ48i;E h~DrZ}$:ey :ބw\܀ HPbs9߷bo%}m8$܁q'*}Tn,="AACzMs3>y+)_騗Ħ?{XΑXMӴ3 vôf]9)dQŎ" yK}-ߏvb+ǎ"GT07Ẕ_q\ȑ}nЌX z!8))6ZקNߘߜo͊8^Wrp%?TO?m\+(?T뢂X22ao/VXXh-sŃZvou5%~C\wt]%+sV?i迭~Ȳ!mA/ʱًX%oڒayxYYzY/_^fO*ooxw)@]d/e._d1ޗ@Dzz~"|y$"9W!_jɓx+.ɗ2^yZ&/@^Igq_@LVd*Sl)V e06co^ˣemKL͇:ˆJHYmt>9 čY2 sd6 ȉyq-}:E5,-QG3V2| i*eAo2\(7Cх PI|H5NgW"Jy`*a_q^e&zh-u| z']7޵nЩ戇es9<~YG?gVJ#Z ]rS- *q变KGv~1~H<>Zws{$ĆsNkms*^{%a] *& W`&7 V 1 !kVL6(X(X&P'gY:+fF좄+xT_#fS|$bDlgm8?"[~ȁ[Kdr9E=ϜKJ&9U%IOéN%p*iSI;JaLNI!ʤ1i!A̖6H+$3%&al);qW\GY.a\r)Wy.tUd_t= TY $g r &P?}7&SRyjdIME#HJ\΋vc3,ɷ|s8pz:e-b='0 #G0#ZӘ$3+4ǢDLlgk˜IF7lc~&I1iV%i4-Icl5Ii4>&MM75 ǥs-OJݹ%&RO˾y|Bl(P$(9T|KaNGx>&y kxmq<$r3T~/OeygA~;kyOʋxF^s2^_5yY%wR.H+K=i?It-IH>m7R>/q\ܬdʑGU<ʗxyIM+QǪH)ʡXij 5W*:URuJZN6Rգ6RETPUUZQ:HݨNQ{bu:M=F=jj9gι֯ PK nN:NAJ.org/mockito/asm/util/ASMifierClassVisitor.javaisH{z&';2ȶv0x%ao6Id q%^RF_-ٳǏ3"'oIfԿ!tb#26˜&7db4r\2 {57}y${;;;/Dk"ZLNi@I85:з/"F Jl^&|ra&(dh&cEL)'vMxe"{I,8)`hp℆oؗ]]@qWSih׼f8kaBۢ-BēQf"c3M2+@RPK :pAT#ϊ& v`|('&" \}? b& =7䂢?DRti⅔pucb|=vZo-bo#Zj0F'\nAHpǪNq.k Smpv.9x NkѱADwiԃ1[3BA(9]''=M`%vzî?j@B0cB [y*EW@{FP5HT 39jCҕ L3oX "=z|S8AjJ@ɲ(쵈~tTQLxyuCҕO#DC`PSN!CtC5B.ӽhgjGۤ7Й*  PWQ\}CѴᩡM09h .S " < MFŎ!]P!KQO=RG\ՕflBUG ?UL[[D=$rLEc}p ]&qlD?ֵy+RxֵzL$ NǏC;$'Cۡ;B=9iN} aIR__/Y:xkA;5GtRT6uFKN(ę`)fIwWv-O{SL&T<}KR5p&<]G C! Y+?"ۺvnX<Ix)0 _Bub ُwd߱+GTKt $ˍmC)2xw36q@'5$D {uʴ3D{Pq˒(yc˥ HRpuG. =7?aAF~\yg* Rw AVg/G_Ǽ9 h4iaHƎy߸*fL 6ΠL,6: -ghᡝ}K^|پ/c PUz]˽_~/bAȴ+j7,ޒݝu%/X3}LMJ2V͒Z|['vB'Ļ uq EuG?JzZb @k?ыJe @A 'RcI!ӛ_oNXD7&܏.SۘMXj qhlVPGS!Vzؒ˳/&qZe_ 6xN;'<$7sW9~ׅ9>#*2!A|M/%߾;9bB#"|jPDȝ"?ౖKLC}?4[U%Ij#]i=m9/,]%^>TTp4b.$aN;ëƖĈm5oQ/qǏOW/v˒To ` {xevF䷄2^"˗0LCFʈl@ٍi6[em\ҰKfr,hШd+%a* t<J va2]y %bڕ[$,lֈ;o5QK ĥfqI\q:,bS؄eOnEd1ġF֚~H<nWe%s'$-eQMFPܥ(aN9=jl =FyVpQY¦/X7SS@Lg "sW3u@OۇR+ʛCKN} *WwԲ"}1&lB-2\EmJMOp5c?gHu]=E{t"|-G\ :JaA+ nnx'+n9i>jQIH44{Bֹ؋fafͪ7KuVQ1uz d.35}k3Z~_˦ŜڐVBk cLzp\BDu$xY-K1+9Däjs## q;$]b!@,۳BmVQJxeW=#}[l| ;0jc+壘 +@g.cB|"P8+SJ}= ߩGcu, UN5#7+UF~]Y<ɽO?PK )w:|y /org/mockito/asm/util/ASMifierFieldVisitor.classPJ@}VScZAU1"襒6m6'GSAaΛ7;/Ozfmy\y6p|3nLS.tpgpRz2*\!6N-a zjE!M|lTc4BQ6 %("SMh'6S&U%Z Ōc[Lh&s彲WkbMp[ngఽ kh Fi%~GN( p*MWoPK nN:bUA_.org/mockito/asm/util/ASMifierFieldVisitor.javaUn6? rJn6%f!KH#- I4H ȿwHYw@O̼y8ގGp ![~Gi^6A/q}d+ hPNvF4EgQO\7ӧOϟ@Ӝ̌hK \ֈY1`(3xc.+e;9X V)il/{m}@XՖg>EӼ4D/,pV&l97Ѡo_Q놲1'5"ڽM`X\<Ζ*'Y`F'Oc_SkG'd 6ֽ:պƶ{jܚӭ[T;[U"E,AOK2束‰jZW۷ӆė;8CLM-]I~ܣ(9 r, F 1kΖ|y0j-PGTRj]Yd0>J/UA1l5?@2*TJgJLHl.|x udD)q١H-Rh_PGP'\=Fk~l W>ꑡ8zBϱʁI|ʹ9xϪ|. ۤ^q3 P#}cB$[#:o8Xb,0AKmAl`/M"|/ s>oЬ\Ž]D5SZzs3`&+; 9⧑CzzMe:/   '31)$t{AjAM24a94cv߾H{ Gטb; &"7E!w#pT_p.~aJqKGAְvE)9+߫)lN7:! ߷?V<}dWY`A.!?.g' kkͦ)1g)!/L ̝#iC,Vm)hLlrU˵Nq9{:›]nlc&OSrXbc7ÏSX[c#[nwǽU%\2"b^"tPl)̤$,̒buSx1[5^NYRIW:yU+I} X\\ViS6Cc+R)m2b`}`^4Jn^s'" D|oiS*0"5#}U>3qQ,Gd 9fc k*n7yXEJxnczVUvvWq;4l?'&3zf^ 7`x*A 6S|Ӽ~W+"A#a^V 曄0xmG-6uQP)-)rLLQةދ]^7FBqP6tiռ,c9:Nlkgݔc{9Iv8'gi~E$oIŘ+>ΰw/{V:GQi!OWtX.*Q=.F/pL|1CFMI)0*[ug,6]Go1MI֩? ~7bfvlVn݁b}s֝E)t{Vc7pr?+ øaDD1軟8x k?m̅Okj5;ʼnŅŸ(K0kwmBMýkT µv>E6ѥ>x?4-!WǓCU !9QوlDux, ljqc✏g=`!ژ诒պhh`µP8OSXOaA~sj|J쪚;3{l=x*=8VnrlJo%"p&Iiq^d.~Y/Rޓ1&~&LNAIEM_ߡߥOӟć(kM:jϧN^@؆؆P3{ws}T&7 J^*i8$*YVq`AọܶsLã*>g&xt8Vy ED"o8*QQHQMkAoE?)US,n?W~4hr<՗[QiP3\ѭ3 tKќinG> Z% 2)rYYuR t/E~Ȇe9 |P. zkο3'/5(6%cz݊֞= s",C0KT{:4uh)N#E;HNR -r=:l=$a[ma{"6h{øQ,>nxsp?'WX&{`%JGIU/OGxe,l: &WrA r)KlKX %, *72eyj` Y0-}ĺ\kW)P"(1qW`8_7-T$p/mzMoezӛcz7JLo^~1NjjM9s6y8DnF܂ v{P+w_q'"r OWcG]q#N؃ -qD#D3z zCFl |D,d9M=0 P8d{$(aɀ{D$l~ 2#>7 `£9d3C4a@uݑ9; vT|y\.$(Kr(taUϏ5  ΒP1/pOX " ,(x$ Ov`A 8u%nH9&1RB~2]!(l%L£0}h8dП@#0ρR2M 8&G"6N] rt̓F}Y2;S UI6 VaCCh@ʕrj7 fj{nv!nٚݷUramjݴx}Km[A |޷4P"ojښio%Ami0waT,o=!Ŗm |T;/1 ]P&R,(1fa#MQw!cƩD} ^\7Vu@ ׯtxOpD5'G~&DׯdQ^ sC( *t+HŜb2 yIt%rwOr r A3JDXSMDWxDfH#R j<=^&F䯱±?KQ.(D3$4gY ba.ȏ%ׯ#X.!&=(J1'W6ic_ڧ~D/E cdV;:[b\oA> I+ӖTݪI,lDc7K0G͐E:q$+Vp׾ë- 558aF`&u:Ҍ| @~mdA :Kl{Κw,kբAm"'Jql73(+Y}ItY ]cV"|8, |e.;{pY~*ZӺ ֱhܲX9EuԾJx~IXTt]RMM&dAk:i8e O-T"~Jjӊ`"bN~B;: C?C It2#6;a0L e 5͊T=Q I-Ǐy jeaI=?54gXK?s\WbQ(3q-{)Ix#dugㆴ7Y4-FFirJ~~V̸ Į[J| [fm@îOrRrv]AmRk~~޷[L@kR=k^՗3/'Oa1̶j}sS\ɖsS,խ:A]vC*[]- dtq:ط]\)e 8LvM&s,^\(1f-rBނ#yLHRpp:BCQŢWԸnjz1 -$?jȺpuWTsOg__iY?Ǔ&66%IY=7k!žڂa& <]mga24 di.4Al怴f}Ne2#:p%* J'[\'gFUaÝ&0"HN߇L۷uW5Kx^1QTB:; ~^25J=5K~'a')YrUM NO}>k<c9 fChlZ ̾c7 5{b > WK=ő9fEa"bA$W*jse%Kڸå2@ظ*p^dO؇4Pi%wU]<A~*i};xW{.p×9{̈'dR.6.sкqgj`-O8 oa=IΠse‰φ(ky,ʀh$t#̍,s*Cbtq?Yz#7ՓvJ^Xeٔ9)UjMLYQ 0iR[eX;-eR%z}JPo&ԍxXEq}Rr]IzhCEòu ";vtSc,f\Wyqq?a#Ǿ]m7?/cͭrx[]P1O.b$ RYO +@IL( !їv/P8ķ"SY.x!槵,7%C]%;]/1zC.Ĝ,X% 1us%1B\zRBt!ΨC.̏ӟr9rYX-qe0BLNM   op /^rtäE>.į[z]TFQ/I\S0Ώ9l՝Ok9| Xy)df]9';oDW~CK%.+SjP)B+%~uT $jX2ʕR): BDK|YD<,ob:|PA9;frg%c3<)=FSoW 2= JDI֖&e $1 jYJs.|Pt6m1y9/0_"_aa"n Ct>dI?O[Z =58~<#Uɻ.` wq0 < Oob~l3f<8Q6lrel c-d]zqƬpYwiy'ۃ4yh#]zDa*J ",~ W 93să~JEnlDТ`zyČbH?(2Uq)3^Fŷ9P-s'׀?% +C@C@J~eHI^$N?Ys,`YߤxEXH)U5OD_2F]WJz"U~vMwq׭^hz. V{Nojo?4Ʋk,9e]hF=|2G*h1lW74[, Y&F,xM0Mg4=y6i<ȸ6vN;I@Ӱ62[ Fud|Hź>Wp}עAVbPv>KZ8I@Wtt&>Ωvgg_w>Z|>@s,af 7T(̀K^oCT kOH0xw]-x {Ý]_T#d(myuۂ޶E|{f$H [vJK-]"be~VWo:LI:2v(0LFyҋm4nȧp#X:] eu;l!WeQBȓ0\q{hA,;t Z\gwqYxi=p3 `|J#pgq.2y$Ұe"\tq'U5LbU!$>RF3 ` g+6"juޑfTyaA%5yV>;c`a[]!lS>=xzuiC}K* . 3!lOy בNte7&E@W{~2uT'= wz8ﰑˬ2yvdlho^v+rk}-ĪJ"Sv QMM4I#늮z. V K h<Ƴv C!^k$ɖ{ SI#)ѭpdJىt㦣貧rU[}w|ڵc<\%e$x?˄(+9+Ɵ8xF5PMoq0W3Cg/PK )w:zc+ 1org/mockito/asm/util/CheckAnnotationAdapter.classVsUNm- r&))T()PZ+-6ɒdS) 3::3>Ⱦ_uFVfd|$sͭ94N@)E'XpQ.&+nJm;{4k,fIؽ`,I˰s[3j mܤqOJN,p,T#mQ4b^ h\X %'00+пBWBY`p+FU0BA;::HZa씫 iYT)vK;7jM =#M^P7[PI!:}++ =DZLp\`O}{,o] >N k"]3'&;djjq(tn5 gzZ1Qwhx[⼆ 4\8) JI 5L 5DaYfΰFKJѴ݉sIYU}SaQ+΍َkLRġ؁l$[U(@i_vWɄ]) utGu;lmg7j,gzpF:LHC ?T0VHۘ @lx4\X*+[ǶsKЯ0Re+EcsdSMlh%qL1,K7tŨUto8FYOv¸іeJ%wjGs$U͛b,;iRʘQ_[D#F ;x΄̛6jծLWSts'~[Co,b@TH|R*>39jHU9XOBDŽ˄0!OHz0<0M8!E0A8a0Cc&<pyW u 5ZxWq~쇙hca-&P?:sJ<|[2SC<O꒺YASj_4T4Ϲ mJ]*餖(fY;8'ql_2Tԉf^@?ӕ b ~nX.QSջ7MMj__C'2fu,w9u 诹KJ. a)D$ To>V6~Kd.nT#0N.JYslGc t7zhYP[I列|1 {5w*;?PK nN:*3G0org/mockito/asm/util/CheckAnnotationAdapter.javaXoH~a "z'5,ɞl4 b{ڐ7 CqvfǮsvzzz|7 `)=2EQVX W2V\|*ULҷU{Ng4&~/;p/N zZHf[h(ARL$0@&iYt0ȟE)!-T H2N .Oܥ 6բ20JI[ yZU2V4j&*e.-"IiSi`hc.7_ۏ+AMnYȜ@w WՒD+ ~ UlJZBlB|Z3Ru4E5Y{?/rYTb3LBTIoFہ~k'S ,8򊞿3%RFˤ$ʵGV{K'H,\T:S* .,LN.WECP&Ūڠ˘J TV FtC^t yW˺йA!2KeAU/ xgpℸ6 a`Nj8 [؉nE "E Z}+=?#{=4 "NQ0C G!vy>`6z]1/E_{,۱`}tĀ<`nDm\$ 2{0&'i!VF ux!L; ؀\{(uˆGw ! s!oZr`9sgr2E,FÈ^S,!n}τ &-dFCȢm]$5ڊ:>JUM8йJK\{U4Pg3Oﲴ{B3ߖG 3T ;=7C.N,PI8:zQJ( Wq%$b^\癤QZ݂O?M$9K0Pݪc2) 32Zr#Nv߁&y MІXYyn_&+X[KŃe5|YTiK2r#O@ڳqKaLMݰ"i4-zAےt jYѽ g lg;ZTY!ju/*9W0^vI KDm~q?|- xRA*CqҢ!L=8!fs!l5 y6)mjlCՑ(+yc_=D> f ̹kmE cߺ6l!{r$$;d!yOpY~n[B=;zgWhِݬOp\?rJ#ֿ1mO{y?bJ|us2>moÑ%t&N؀WWP:L~/+] M]+6|i_d49 hqA:APK )w:ia&,org/mockito/asm/util/CheckClassAdapter.classY x[Օ%K8(v%dqYȂᬸHHm%#Ɇ@Y(B!lvHdCRhN̔0Ng>Im9Ǘ/}9׿~Y3p#k|юX XԾ;MP2p9n ;Eb,pD]&?7]u5e(/ n5u@AJE|v]3OTRMb7H̻-8]hC`PԇΈ?J]hA' ll=pH^~Qꧯ}}ħ?L NnB>'t\Ì)/?fB]ͨ`'.vу+42.Dz\4kNӷ3&0LR|phGܸZЌni&bP$)ZX܁P4j^HMP4Ȱp!k:q ?x}M11l]vwdfBЪfwc P׶hxq^ `iLC†p/uAn<`%w(m/إz*cZUx…'q=J‘U|/~bk12唸:[Xu~Ʋ߽H*#ŧ$ss䑀ZzNֻ%KlL GS/R/wSrq=A7 `׋=fyJ?֥` up-88s%%lQi [}Aֈ1TƼ~/KEQ8I)jXxtp5[iFdxg1YQ*[ݻ-e:cYu Α)-5|ȴƽpeę+ki.W$R _-Y6eRHpP4ĝu֮(s5c ăӧ8Nˑy..L#R`[h b]Fb!-Y$X<܀:&q6u"H$IL!p2naJBpp1@Y8ONNNQ:11|)rIC~38u9OLN'C =#GpZR:.GkuQVp1A+s6Zmfũ<1yoh?#@%3cle[-Բ&}ICIФz};T6s73Kl斠~nVU48V">e_߰Pf ƥάj}B-5=آ2TΌrlS.Haߵt|+9M|0/K27/1u*LU+2`W.RҾ//ʰ2yjVMÖeza֍*ڴtI-,0DZ~dE6F);rܠC;N'EM`](f5EnAF 1Gx rܫo曣K'.sQKdeD62a ܒO͋!)Lw%Q?m|sQ<,?hy֜x*+CnSExJ0kO&.7FFK8OЦr"ע.)/!'sy[(;j yyȤ31X}Ԩ+K?É#Wg/8—@035Jldy\q/t{dC _ӥ.HVe5Y}Og,;72#;n=Y>nQ6ӇM}ĭT`fn٘PiÜM^Q*?_EXe(5Jۨ]$|}Ձq:׍3Rۥmه6`>dmV>9KX_k۵ٶyb'{?wb~4fy4:B6h;i\<}U} !mt8nۅ/̲8/Ww^u{rf׎8|`il m^~qgDD38?Ӌ-Gwژ"y6aHxI5:ooe#ZUW^ǻq4Wj'?RWy\ ߞG)>y|@C 04 ߐ,9**{ddI*v@Fip(D.kr?G/rP>Or#Wן-)3VEՌ)ǯo&`U"\+% K;M Ҵs Be4dtG 1&ay7Z+*fRݮJ\dL9%r/-}{\+~@5剚P%RhO9=3ShY >6...ѽ^S&Vq*qnhCsAƵO3Wl,mLCJ|=E vم\8ٌM㍼T>j'0OI/OʞD+1-NCNkx'6zžxlvjd3g/ؾ~ V*(;ʎbPo{ aV/}ؑ^Ƙe]sq-flz&.{_#,E!p|= }jPK nN:7/YH+org/mockito/asm/util/CheckClassAdapter.java3=󙟤?ғ%!K,H82CHG2{?eQLFYJ`̟anيK?Mh&uSPD~`^|\\182+%,+2\SE4Z#)!W;0OXNX,X<&I7uR&E :ˀ?&Uf-yj`["< )OuF2ِ'pH(8Y%~(:KM9p1`M(L Ri"%!cN]}"ĭ`f_nFpcK5u2Vw."242digN?{_8e 8~d^U:iImU0IW"HsG[ 93ԀԦ)M]8kI;iy09뒃#=m4O<0Cc iyOn ,M;فY2 g*bӕD[%B& Dd/q%xe(AwCI8 ˼{}46{+\vtP_bZ9]>>=3Au+ ンCb@b+)Nb [ڠ,TI2 Uyft}0aAf*t8 [i<\F[A R(@6WG6;$x)—)j=(S]ؖKr(µ)fn9L\)()?龓<$+8/C9 KevrAh]IhpΒi%{ x9Iʗ&$@ S 4ZʅjOvnVy^ieYYj_rsRO?>@gLBjtߕ^։8{T?BL2ؔ/c :*6H ȿePU<7" nN,uz` "<,(Y69I1O M"|lu)HXjY:["ϵR-VQjl1/u ]u⹡R}K:~>,?1ݽf!۷ԣ \t42t:͛jY株 4ÌT-1Ȯ@*+fERE(9 G2`b39F%W.U%^n^I[u=^_j.v?_C_ >PErDj'qCPaS{!FpQ4e ƋlSg@'G&xUIUPOjZ駍ٴS[r]/4g9vJM21hl"t!ݟ>ܠ)s%1 pm5 ށ:!BhwK* Q1Z'n##j0ZkN>\Y7wa3:#۞],D]aX0"6Yl6P,P͋\u=k26Xlަ=cQ߶oݞ0j $ee[Vn4Ym KnZ֪*Luae֪#J@)RLvR;ϣ'y~hdSmeI{QV!d`XBEj"a(F8%RL0w`=<ɹƕ1:+tYw:Tq8yoMh#Iru5z݉TU8G^k "Vj?F4JZEiVATT-c)!0u HŖ]t/HZW%\ G>P:ѽe{SsW*kU&4ʣ =IG-/mA&}.Hm{ѼEoeڊMұ}Ck𚤽Q,F޺RW+($B!k ̶6EPSLE+=2jocv;H6lQYCP O ZC>H \.JV aQ0m6mKkӗ6k;fb,`aÄ"[BV+ִ`/DﬥĮ(g\=w'eWc]x4zxbn34?2nopΚe4A fڱد[x|=(3ڵd|oҮvb:6~QDB%ګk- @G+Z䪀4qUza*7/Yy *B ZFZvM*AQ-޴]~Di睜B{ǣVgU]Dws*C1ORw 1TcK2z(QEuEu>Eu h3.NU$8umG }'`1Tjli ˜'$OUa$W1#`)v\7H}8ճ.7GoPKm$B u+0Yss;^]~PH?wyugcyiw}yķ:=qNVq@L9gU4PαT/ l S%Uʦڲ^@+A;pg ,'ߥCfd ;(Q#T&l;MW~+Ty +@1x2ү(%/PK )w:5خ,org/mockito/asm/util/CheckFieldAdapter.class}T[OAຢ Z\^+Lhh`CoXLJEXkRG5= Q_2gw;߯akD.jf"UţCd;c:'c fU &naeMSUa9/Eq,a&kp(]TuG'zAV4~,0] XTC\\I4{Dd]SdӶba.)_gXMq^䦩sEԫMH"+N%?6l`Ħ쒐#5S柹`ΰF jenԊb0MC_ }it'C 4C^ZW1@$кJ C)wt 6+C}H )zKybYikaCVC8 L~@ԋ3~kͽm!$%Şk|ooNCmqIa.0%%=kn Բ$Ѭ odlSߢR7"b=X,砓!Q[Z$Z#Pԃ49л~ &G#կƞu˛5f.YQ=PK nN:}  +org/mockito/asm/util/CheckFieldAdapter.javaVQo8~0T{8iJ)>C}4)VŁ^JwէC=|L\]^^%b $Te .`%m ˝KrS(d7R԰jdM0Byi㺅^އ_| ?<u S%"U>*qeUSŐa mF/.峵 t lD%2Me5}m`*S]j*ݶMcvE-~(*KGM]hr+~s?~dgL[TQt W.͎ 9|զչP" ";¨y)u| &1XiH56eEamB5 \Itk6hXX*'dd@*j̩2/6&kK} dͪ}w؍ʩWS6do7k;F#r"dA4c62CoLhRA<8Kh%q I |68b430Zy|;8 3Y (C f, 3g.g1ś`Ap)<(xY`d`w,@L(:a,% ?;?4!Ν\ڴ@dUYϮ~U -^5UdkSX4A&ĩZܴۡ4XMhw%Dg*pmVS15ͼÙCO!/n|,z=PawVneY?a,KG9Y]ׇMGm*6tvc sqNiձ^ۦZ={Co솧T]6[u1iHH.#BI?47=]Z۟lU3 PK )w:\2*C-org/mockito/asm/util/CheckMethodAdapter.class{ |T9I&a 5{E$@VdBF&03b]П vVAZkmEي .kZժUj[+7oD|={{;ħ?>IDS!L%ݑ6cݓѮɽ`hrCgm@ D2'-љFnԿϔ#2e,C e,)8K=+uMXV csƕ6:Ddvj dPӰ8Eh'gR.^ Ϧ_Hl^w/E;#3_6 e\_ֵG6⦨Zhr/;(0PC=+yi+I:XUό.s_FFVS8iJRFaXUNi|M1\PȻntm.M{M7[]<"]N^߀V zV1MObca_/"C`\R]]]V/C7эBo#{-V#J-HЏ ܴ qZZ:qQzE}R063 [Ev6lI D2yK-X}I~I?]:~M}a3FX-#JEEHqȊ PMM:Ýx8Tp cn:n9GS;"u#x脒񤇎QU]ܫŋG,jbUwl O(rah,?@ Byu6BMOo,04%7O[z~#u|۔'kGLzʑk#qnzza[4XqXyJS0l2f Dp?<BT_"u*c1̜Կ7F:R6ʳl&d^H`X D*Mcҩ3 T@JnMQˢnycN*CHmds)uwoITHhH!$ <vmF;|}QHDapqU~u[ez7B-L D! /Wl $"5ߜ`s"?d ,Pa<a @K T(Z*`Ic=a/LubM;[ݚSl_N*iYK <ܦpJ\ ׵xC͠]2/[A!'.E|U}sCj ݏlUsDljYӲ,jZz 8mًm.f49iO&oE}N:4@Jc_@ȗCtIC,|*>AVp#@T%ۀD9, Y%;zHܣ}o8e8q BX& u|;%݋79YY_c*KNhQF2"27߆>>BD]=>!tNyq h7m*^T(m(k.ޝw4N*b/huS2]ndcBTtMڶju3N%#sQ| ?LaQΞ}uljZ]v~ʉf %ʂOtUbO⢤KrA(J4Wk;+.!Sbmʽ\UT!-BH0~D\Ai֪h` "ldCw[_hhe axI:ZCOn5jrF(5usZ`z>駡nKct~/iV/g!~Q][C3k/r*ULH[`A0 "rAi~,߂Y(h>#Cs00Ġ$Ü-tp.]w.):LSP7?c8tb r/M\ogRViv44eU5/|7rSRZ78|*,pA#fs \=JVc%á˔G[a!7|5l6fIKeit9 9s.Je9IWa) z%r7f14P-< W"NKjZRonAh'1=_G&-6PlA9=ogPݐ`;]mEBx(P%cTe{(І`Fpn49= ݈9T}ARQ>E#Q*:@e=/Cwh21]wWQ/d)raK)T?!!=DS *Gh=M ha˸\1.}`O5Ɔ5Ɔ5a…S0`=By(ǰbox>+s{)FwSi~۝J|O~ >sZ̿#tԄ|;<C6L ǀ\Qz@A*0.jFUMTPM1HÁ9 ->/T1Uˠ&*H%Ɵ(p:> ZeV@Ro-}@߁!]y2L/gnP^az2R;F7F7_'_} o4?w}~c",6QȨ_6mTqzEdQ ouZc?F6إ";@' 'T>C֬o4ޥjF[P+̊Tޣmޣ[G3`6 eRE[gČ>@2@xs0gOR㳹dp`9wbJC 1Z.~Jg `%j2Gh i.ז͐}hZy%CfN@=R#xx.7 3+D̔J)$i8j Zu ZVWu<:TgDfD dy|.baUDA=Esgd)sJș{-i+_9t{b 'Sˑr/UO# ͖pZQ sD-2C4Z;LFDND hRE0uh=M ͵SӇ'ؑ5tק[ `F RgtErzo VmZ0̷ft/q"xqT%6^j(ew q`\ ߹ iv ě&NNp9\a9:(Wہkl>@ Up5G‡"+Xf4A_[0s]:6dّ $w$t$?gH;Ar?ʉnX׼,?<ȁ4 hrx? c~#v?LD)7 `L!+hDABGMT0׎mĊ[v8S My;sV%k0k)4$9fwJm?+s4ڙ&œh sG,E"kf[Wl:zlI~ l7l'N{(pUg1a`ƓmƓS(2"x͸d\ Ugt\80Jke ׷i{W9#sW{e'͆}y'M;;pdNwpcļOh)MRu(3Y"HꙔ56u(nez4jqt91AqP%zEz(ݙT|aE%+f51Y>Xnyv5{)dO![jԑNHTF @l} -}tTDED0~H/6lEf^<mJw_EX{Nm"+UQQ9^q/Ք{Wz0IZ E5U(tV!KBPNsJ?YTϦz-E:Bz݋z=ۉo2xrReP(`<$6/fkh]'g" t8P$E(q.\ǥ3F,$>'ol;f7>68\kz ջ)Wh=Jz&[<}+շQ~%-h~W8T׉`e^tVM. AD;^;n/ߗ~ȼ{qz|hP*OaI]s#~㳎Uo? {^Kk u9]^C*ϙ][,\ݕ'&bhl14yˢ]:JWXf+,H\H'd:V^ҿMvo{[^]GG҃}tJ?Hs!=P?ȃCF]TFw9kuwyLŰ_iR!UYB5Cs4_!ZZh b&5[~S^+**kkzZxi9/k_O4&R8KrMJE⋊ 7$Dc@78ȇZ(c_4MVg9Ѕ&꽩sJ<~IB?̿ё_s{%jq&ݯM0*b::k`CD!1rThP1yTc F>-6F ZB(zgqǘ=a[۪ުoAO6AgP Fe4ĘLTZsj*⹦M, (DYʯɌmԁe=2hol7XW?Hseb10g-JRccq`F _,XC㍵TeyE)fb.o쨌Wvlt{Wޖffz13zh1b@A130V{Bj:R3U"kř7Ԋg^ʙ-&]o]@++L:zqtEK4 1JMܸ.4n$V%G[s'[lb(n&JFs9U!ͩ%TMfx+VUD)lq՘|a18Jck6 LG8؏G\G8-$} > O_\#T%Vj'lu<&hMT(4IJklYIfF;ar,J |J |VGuJ gO u6:eiUf:+yq5ɛ܎} Ӵ4(⌻a† TnAkp Rw0C J3|6fwqAW"сPx:j*P/ɖp-/F0[}d݊@4lXyAcmogm-hV*4>U~iMxN౜s|uvzjY[y3d!g$?Nn*շR% ?PT>`;;AU|MZYI*=a6wOB Sn@F뛘f5)L}nQqyVR#ΨH+Uح۝"ز=h./83wPs}##"eeiۜWW6bU {=v"Whɞ{%>qձ":AV$`eo>Sb2mxFM#ަoӈ6ⵍxm#^ۈ2ⵌx-#^K8\! f`vl5 ^ŶK8G[iU #.I/kq̸[f-3wӌi4͸m3nی6̸-3nˌRq y.Nhi&e gkw`zCt_k{e5B nop M bklD- qmBA =Sh5vN<Al NUh(wWA֤C pժȐ:nWT*q hU&MۦVj[T}m=ƙMH]utBڎ iUȉVDsCXzlm2Sb(9;E^.ot~oHЊ/s(51Ҭl h /4H[}Q`tU.Bsve*;ƢbR .4 ڸ!䫤=j,PiΫ"Ʃ"؅Šn8u.F 8sɯn_+G z}W'?gy:FI/,3KǕ#Pw'Βm*LT+id߶]|.m>VBNcQCl9,?L4>|Eބ ?}ڑaF:do ,G=5p0gyF". t]H3ų[@)yFRw6JƣAoms*Wr(X񰦖yZq9\"4[i"V5Ʊ/WdMiTıƔkuz+gm.7'ꒃY֬eK{9sjzfO0A>Xg [+6 `n'ޭZ'l8DFQ]&00sw-i3hrwkVT+~󖍍Բx-c,֥NH$`1HTvmz^3^o|n&rJb~fj CepʗvJYgD/ P(klW.A!~MG2=B 8Fe/ S\O]=5+ԓ[:9M qo4G_PE8 ;cQ#i>89/>M|@]^>g) }f;5Qz\xB3P}`KJfxe2 `sY VZ)6<*``A`o?[Q|?vzhlЛd(q`ύICn3g3DFqZ)e@J2N5ۢ#* m?zy,TȘ9LlX8C<5Ek(d*1ge'\ H_?h (D_?AӺp伛c@;.#_IE=sCt};KRR 9O `UQ.P4cc87ÑU!^W =#iMfF0*DQL*D>Nfl͈I3̨sP|X.G+R0 l⎮Ɖӿ$ƛq (j@,6ȵ Z)XXK`hA),Œ%"eH !7H"] yh؁E:| OtJΤ@ԉd7[43| Յ,]QF%bgstbsNz_jZ$C譚\ ӹ фk?iBO3VH)KU{x3j޺%%w/YS7K3ySo%ό,XfP˞ߝK! h'.\B ^zR.RYsيG_.Sr9Gt@}(ßJJ`q?"aɣYAd~6.DZvVhB,{gd2VBRl0s|CT @E Vj@&S*а &,@aJE,We,X֡ߦRM҆ >^3]hyP)NQKMV&zL6,Қr .]eï"*$5[>>@W CYѬ?' )ɘKX6+i66y!aK[ޯ/?EN ^uJ nQ8煉hbh_9 u`a!Sj8c&&7l FdA(&y], $V@{rH}q;#G֩':{#(t.{6*s\kp|o$}A~L뾱awxɖ(bAmxcˡyCERG.yлD_Ik ɇhBXDw:Y;/UJל!5-č+MHY>5/RMzѨ9i}knCi32={ehhGloGl;TÁoq%i<92YųYΕ4Z$TďcyMw'#I ,~Nbɛ>E+Yb6m~;71G$=Ae:%%d6WvBs놬 -Y칤L|6+͗n2UbԎ#{b@Z,9:+1U6.pf/Xl$I ' <=~p,`ʿ3 wʖ1kʚiEuUJ\׬'ѝV{t;c> M΅j}XHF| S|{;tZ4q]XVqFz:Ȝ j[4˘Dhם|ƛ~:~hm^f7ٻls5Tp3L*Ifg}单,oؿ@~B"$4#NBCA,xzWFCUnkH#zZcl7_j^8"@q߷a?{/,t;95v pZՍ“MS1.wQ3m4=+a`6)C& )3*}]ryYG~2x/cl :\GWprrf3]3i4m-`>o8/Λxâ,^r%}vvTQMCg{,nF[LYl͛DNl+LSCoDgҖ4}*(ĵ_sՕz3W.IּY\x5?n{ܓ*MsOڠM6^lgDMTQrJx)ż/>G} zrDd'ŽE~f.ܞA]/m@UtKmfLɌ?KJ+;,}` )8%C]`ӧyFoWdW]?Z@ Ma3z'aSWC]8 "2 T-> NB cE"5zS ,υ>KzSҭeI+3uCx/A9]U;x¬-"VTVUAwvTwwoy?a H5ko|ieGy_" uiW^(]vQ,aeh0x*W1z 10ESE^EVq%ӚAJ1JQ BbLb$t)BlmW62j{)bǁ,HTR~e<Q |]tꇦ:;Hv8+;N\iǗ#bZUY`LUדM wQ}vbWlJ%XJ<_Wmm( YD=v:VOz5o9@VJJCS)㲍. SUU(U4ݫ-ㆭq;HZ9W(]EQ)rPNX!Utm3:ڦ)J}KaVpiǤiOTH mFxe#\SϲhE??%T`h}3\sxkQ%9(EE2^J1jOqApc@C.~+~>rZ_V;V,861)-eIFGfЩQhwvjk%D6lj"|,w^gD^ 6徽D_ĦD\~׀c M{ 6~L곽ge:92]ꦒ%=){~,BykL|hGMzo$#偨)-bx/=@m7/ecOW)'_kpa~B4\}[xҥ QxDhУ2!\R`C/= 3SMI&$H&.KB?vCx6Pf!H'y{'8I9,Hnfwn85M{/y8@35e{y- |$)i5_]LH?Xn4}q_9\ֆ @/G)PK )w:0org/mockito/asm/util/CheckSignatureAdapter.class{lWƿYo4x^?6$yvîmBIֳfBG[J > B$H4I(R  CH !x6sϝs~sدկx#. |!{B/"ji>R)HlN˞H볆ZhN](kE/@ฺF1>e^45R>qd"0-.҉G&"D^0{*>OɩxG%X326&04vhtXzi'18J+$ЖNƓc2\: +gf\|jAcRY-ښU!-Sst`!vt'nɞ ɺ{2 ހ~4[AZ[AXAȺSp/w~N/5[-ȷiQ&)$~\-}.ucZ^MڬOKKYm /v ݌0c IYC > l_2 9s¶DN3.ٶ7`kDA<U&<І5O `.SX^- )aX&gufu֛_kFjvmurFyKѷ-p =ZLWbV*|o㙪M m&Φ˩,>\: 7e(d!X0ZY-t%mb2#†岂ǬN{%+Z-˅;Ygλ_ v}J B%oo522ȳI=˪Eg)`%0 AQYX!gBVWT^ m2?~VBFƶp|q")?6^@;׻;iopi7;尿eoe`>d_y(x 9k;;pU"ewڃü2s;Ճy-}J|q^mN^+꽌5u _ :[$ˈ| kx SJw/q8egQ^do^dqDoYyv >wmn%8j|}{dWl9#H߆@s<ޟg~;H C9P;@>}\QqmO]d)~I[dž `g,}+x 5,x8'Ng]c0sBďBpgn#~#l -8:<<|njJN l~Č8_2Cd'ܿZ_g3CGK<,níL!oHYpsg~0wjb&,I,q.u%u +Q⻬C4Hv "*,?c\0GPe -3hfʋŌ J .y#@d|?u@gHBvQ1c(?3D4sWEB2bE I  Kz*Z|Aq4InI 3s}!'RnqE$lgqb_( ƹWнNzNl83}մ@VM; |X8sO.$TKPea6 44LE5jJ }M?mݰa 5F kS8j_ 4RlZt-~XP+*S FVBSX"<᙮)j<+tx9&fϟ _~zޓV )\*pdG"X㺝TDk*Ã8JV 7Re#g8 a@nм!I繃5YJM,U};練{:3S-9EʰK9IͩuVWI{}ZUggG|J?2ҹ!zu .-uDDKN"T'FD-+R91Uۗ؏k{C1&{~}i4 o_~%J|URLyt+@!j*u_4E4ugs^0j {A\󌒽,;*3ԪC W",aGyF_TPgƁHWi*@!V q>dpFByU׆e 6Rhdl;$ :rg͔Z tՄE}x>|("p5Y1".=DA"Z߮gC{\3gyɥ^ʦmt[H !G/D.Y.;퇎xZMrܘҜIݪS Wڇg3Aݩܟ7kE Qx%o+iVo^W55wki':~?~>sj8I_|v2(JPȈ;weL [4^sG]Ν;KKc)g9 R,k 3;Ө-(RZ2 9/>5nIZ-򝙣Yv4P |Z*VJǏ[?\{/ޟxyo.r\\Ս>w7->E:ğPK )w: /org/mockito/asm/util/TraceAbstractVisitor.classVsU$m4%B %T|DТ%MDӴ&$K%ݔdSG?F}fjt&݄vFrwϹ;sﯿ8-PZU 7tUkkѺJU-h|5nV:Y:vqfUPi%IRұلH:̵D6I+sM}6y%S2 vM(WSlv|Q)ɹw3~|߆[`p2Hdv=NS S2hY5JѬYՍҤ@Eͷh |1/\8.<8QN &I 1~|FTMbXu ׯ i_U'}xA 6DB:۸ifJ3J &ec8($D]_׌h'}dq`vIYI3ZPי!Q%eb ڦI禝E}J|oYKYi  c%$i{1C" 8l'`.вq \8Vj5K^`{YmV`;2H KXl'gz1 ;@agh@7d9[d5$Xφ3Bbo|d`{?e1E$5N'NZ|(  6d*qKO wwEmͪV@E @ݸaTn$L*1矒Ѣ"ae 8[H|M/Yj̕fSus+EMάJA-Ԫ.3PT&)VmiJZ.eu rtu r8C&^,G]M>@&P>hɇ(ɃGTr8h)]7a<6[xed"^V.v6|7xc140)AKƔ?BҁEͦvlKEx _l* 7lo1Ea-aVS>> :4Kd1$$'D6EYlC|{ʜs2e1lCcr?QC?PFn8q}RYzyN.9=B\?#)AܷK+,kZ5b{o)ݖRȹr<o[z{??-Oh-C ϐ; # 50*{+{|R+6&;Lsȸƭ:^y~"?mZPK nN:9\.org/mockito/asm/util/TraceAbstractVisitor.javaXQoF~0{0^C\%A"Uk@W6aȥ|FoDQr]\$jwffgvuׯ-# ZcIHs+X >(9KCI D"*Jgb!NcC*̺>'lӠL$3I(B^S&sd =0UM )rIQByZd@i$8I\…Tu9ڬM ԦkXJ5TΊLcwȐAJfuIM, *~_Oi,I"(S.M%$S6-R%t^%-<{N*(_F'YR[׌4FpagY^k@ט=" w8#spixR÷4BҿBWK17#oztv'E!>~hL33o&(b\F9EUY;!EH)iUH|v|FV~TiR^Lc1PF22Eysjf{̔65ɕHTYPl?)K d>ˢ%/oLYB+iv".-mI]_$\-$"{&e07jeL}5vRĹ }{b,_Lqn 31W!U't@tt !&_q kW37fUi. H[5L~TY!8 E;qͩEqAIG@6I|үm mwXlVbl;:ii37T3Fɂ-[\ta}g 8 3RU_@Q<|c7Tm:7B{o}KCjyKl6\7n5T}*@~pz=>5F,_AeWQ 7v`l X=1qKjkS vzֻ`{4#-;P7է :w*ʌ~y.ڨS=պn~Jw#ݪ\;'ei ,2E9XWOjMc*Y>6PK )w:p i 1org/mockito/asm/util/TraceAnnotationVisitor.classX xT$ÓL(LBB 5jB$!, h%$L:3)E""QPi* hEBRT[ֶ֥*73dcy{0^0&l)j4^ P{QgVT4%~ l}/J!Ba TȪ*t -t61U2uL9IXc9va'r.V )V!p:.k3B:C==wvwa5֤̜tb* :/)v#~*9ԉu2;^'6X&+M*'n‰;d,wbTAo#춬1K_/1wnJp yVbI72 '3xFSS/.a`?ё,y:a` ,>Atn߷KI) U[{W/QT _Ol`B$bGi^&~2.ǬTFRx4K_ֳYgA|% cE$IOi\/ڏNjnl32O%:';. =FNUN7ul;=m+^_*"&Or$z7Ơ{7 E4u:'07 ͍ɞ=/q.;?v KgeX(LH C<$q(`)# zYܨF Z,>WM3yqq9fe58PEʏ!;?a<(XWfʠ<{>9&煜gqA۝'eDqj~ȩw, i 9řț]tcH~~(͡fù | Q6[YŤ*#TNSCMDsR9VΊbn WDԇTηh9^VFCGD=IeVXÒE2[,1-QMj^jws7 ״ H~pthCEQ3h8~-F^i2 6+-F(O|?o_ +-~!GnWZ mLSIJ!;(S.-顁&~įش ҇H?bM#~e6ql/:ZBxK0 J[{dPoG T?=S`a/I 1eY;3Q=GߧD!s1+,g^p)Ŋ';BDz'b9{D1(t7S?>96{E7\fi{>-6բ0g^DxMd%D1Kj&84y05:߈@bߢċp9ǎ^w E ؏R=3T3}MYE#}`4Y<< /02WݛA)ImK+F W=;qׯ^ޜ*zM-z0J<-2:0߈!7AmDn4 k.w΄:qktC;2zcP x1iinteTr1k}ճw-s::dW9}\}n\0^kϧu9鎉TKFۚIα 4}hއ8ieF+UǪs9SjjP}!j ^\|cחh;x}?r|jEwڲX+զ[B&(boUING PK )w:)4o",org/mockito/asm/util/TraceClassVisitor.classY{|T՝=@^p䥠"!F# q WCiZZ⳵jmjbRZꪵ/ۇmkmWW=Nf&~=ww~q<TH6ݛt)5efiU2mEéj3/I7DP{t֮Tt.>\S0i97͂c G-L4-OtgL#6/Vx=b sBgniCLvZ5L?x -1q{B;l t-EV&HOK#FFxEF3Q*9IFhfDg9lDvޘ`7/6hR:%xiR?MIn}S~ Z_g[,–&3hVr^r"?mf#NDN槮ӫ>r+@0-X]ƄpR'  lǸ-M>9*Vc49˭sX?`jo8if^cr/ʟjDͩ>7\,ҷ%iӷLj_IEYTy.! 485ʥ͌x%i– #"f<zTVVԶx7c7Լt͉(JN)y+fuH_/F<2VDΥDw8:4ºtqci&e$0[Cboc |NT7Og,.IA=:2L-/ gc(q̷/৻=ʏljy2BUkѰU\ǩPMj}?0{1y͎P2p<-kup8QOtZ_ ;BI+W܋U;p7Vse#^tbrU!RTw+9*]rlLĉN'рkфݼ~pp=Fr ߎ)V܇Š4QYWCR7y&Ydz@TxDJwkak֐nW! P ?Р9'D^Jig!~}8lclR"E>UU޻c9cdYǖJw?,mJWאVࢳ;xͽKj7Wj:C|7皽5 ~ܪƭ S=|fET1;˂y.uU{,beuBؓ>Ai<Lן>+PTg\qFup/fi}K⽘ Ja{vy偏^g-֏AR=3Ġ^ɴOö34r@U! =Wu"wu"8 r?qԫgD.Vk}p/p+8O5y&3XD^6zs؄ L/h?~ 5Wr_e M;q7+2 982B&qo%xS6-Imمwh x)'Zw?O]:#?y`l/&%Tԣ~?cd&s ͇t&ilLh`1Υbcr"".\!e'k1}8- ,So0M 8 -f^e^ Q`_:?g_cgקeӫ# eY2$HrJd"1ҭ2*$8zqe-ޝQY۬u_MVzi͆GGۘӷQ&z6@Y}'LI䟀 9S$K-w:թ34?Y 6,3sd˖{ڈ2)ST̐<%P'{~Ptk3Tɒz.@+~1, J w{m޽Wdk#T"y|Bfs9-`!8GZqgNizY^N{19[\'N9dY-  =gUBWzUor.Uj0:uSˮڗ+߾w/BiX U9 #2S5T!*8ib^ަ)c_5YiYV)nD J +Wm"8E")KsMU*[:@m&S$T2'bpi$QoFt #X֢]"YϪu202طF+&`xD8 1<-q6ݠ_!Y_[sPcP^͖j"*G` %~x9 y)!5ױG pǗUl# t8e.Ҥ4OYiQU!96 xc67yD wPK nN:l[B+org/mockito/asm/util/TraceClassVisitor.java\{sV?3LR;igw;` ldM2d* 9{y?Vݝe:y9zٳǏ3"E4%r]bysˆZdvQ۟SW`%Gi{$`sjKh84C/KTlP^ )])܏]8H$=E0ׁt6`itpaF_7Ωj6BEFGDOIf&XF0}VK'-oԎ9B0;:546.",Za9Iq&jNr6`:Cѐ1,$ޒ7 ;]Sf4Nq̻ڂ= xZLm2c&FׁMlR>f^( ( |hZr iXS\k,K>8&ZN4)_G,u>^3w)QyR "K%v $%bJ#)yZwE0a)z?d>~WH/m߽QΒ%?WHŠJ ޽l_Kx@zXT (T^7s1F&z>8D+'z"c'7_ǧ}/ ?G%J5#bdz@j1> YUS,i4 kFv.tWC߃\Ό,T+2A& ?8VR Iw=ZQ{߾S3/!J}KȠ`]kK} /RJRX 3X@qYgn2pCo蠮o*] `ԗx4جi6S"#PhXYxn 9r WX9^a؛7oȋ6 1јd_kB{=LOŧf;{D<pGJ1# . Di8lCɔG}W+EFFFv~śǧB;F4g1K񫡜Ae] ä.Y6N݉嚩xG4]jj+MU2B u^h> p ")U2#qSeIJY+ot"BSRU sp54ߦpBz5T3TCV}<ǟUUYLrUJ z壽t#n"M̌As?%˫%NYkCmMU <[].s\eqD~Y!#U*ۭQHsuxMsGF>OB5Pb5yTI \i+ɾػƒ` 'nqP66 鎤g93F֬{6\FGټL߇s.<7G.a#yM qX`Rhax4اr8zvR#C.n /o+7=sIL,w2bX)96}ȪhLZh;١UuoX?iN J<+XXؤ4 (zM[9qÐK]_\r 1rꑆƇ R{ IW-Kl-wSݖJsS^`=R.8w/]8\JXl!xv]ub8eUZk}NPdZ )|mv~mYW&2H=+.UCdBwCd]&UL땖:֢Bmd`Sk(Ր}7ną {鞨82M#u37`:Z7VyCnLښ]1czZNb+? ỳ?ťaS+ k7ȏK}Kb*o۝-~!UH 35fd ;dx?'Mt.,bᡙ7DY|ݟϩ ~Ṯ?:+lȶϽuAqo}x%Pd& ,/t`9G:1Ot;N1uXʁzU-u7PK )w: e/*a,org/mockito/asm/util/TraceFieldVisitor.classRQoP=0TtBUߦ,ƹ̘ X-mR K (-z|;~ x z=vY>-[?2nċCT=h|F d5Fz$Pl"h-D*Ֆ$6Bo@eÑ*5q}÷\G`ҔZtpzYNqQ]b"Sq u$P-P["E Đ}(Wk@yN5~mB`+i{3Y\lvڐFIVleT J`=rtUT+*ݮ)nePڹK5-<ۦ7$ܡ'o6C!Y p?Q0icl~FA&.XѸަ#EKZ0ƕS#2ߐENnk F VLw 7q8 X}iT+V(96ƝPf} #eCجq;GyG?$'K'S2tI {2LPXt-k! $;6^PK nN:[7 +org/mockito/asm/util/TraceFieldVisitor.javaVMo6Tg=+tB\}$#- I4HIiwHIc7@ə7ތ8? pg`r dEat 9ۦ`l+TÓg%jecǟ7AD]UTvQ1РÈBJh-Hfg-*)o*O~؈&S\y[%[~`5~p* ${d -q,y~erdjP9k\9(TwDh(#[o¨YDɕU >!dRAyO@Gte֔PK,DTs%XۺC"_'paA g2] +V$CFȣhXgXsOHru0R:1X`_bMHMdڢ6[VC_aP&vz`d1!ɭ* o`zpuEП(7nDt&!n|pcнHxw@"F@+" F $vMtFk0.ifI9,I-;>Ml9Mo]XQBw#X*;8CqFcw&FrCGۀḐ']@$<lPHLw ^N9 0ɟ)ܥ{4GK#4s 8IÙ>& H|~[Ҙ8%qMc\OӘ ;僄DQJh 6 Fwa>V>&k$QE/94Ÿ(jrrkxĜdܗƈvo] l0nyԎ-09j21[%ٖe޼Rf NL[s!f΍и7y7 ^{Ẅo⵻Fpn03ּ̘\8>Z1N8oM;58Pdײti2~paʲz8D7C9>?{1vJ=x XYR׿WMQ|dؾ8uwڴWCf'uG{ :sRU5_fX _A78'ǑmEl`i᧯`0hԕ8'6h%i^mzf+E 8Nw`z!H@x?gR2g%4 PK )w:6l+-org/mockito/asm/util/TraceMethodVisitor.classY xT~IfHdJ &f@6Ʉ2$ $8*(JBbDqZZkVۭ}&IS's~x_O0]74l[}m@S7kWZ8rCY}O.\3lOw k8蓦m *b.TUMp(\kࣉOABoo 1kVNg YK2OptCmVԢ>蜣''\H@ nN8f;txͮSYk[Gaܘi CԬL RlJQ!( [¾p%(833ђ_r\\) r1 ݘxᣒOQ30s4ok Y.H2 0;F+4\ݾFpJEkՉs1OqF{g :",WfQg :Zg  ՎhŅ^:o) R֧nT+7pBPł&R ZJY N7۷v}TKqI|vh|N+ 3fg7[6<8_AopĪ@[lOI[3FstR}ܠœF*#5qcC"h20sY\>+HǸh/+7QI+hM hW1#oi ڤVn&g&y\H膐VA~ 7O*F/]{"S`{zZ@m+08gM}/8"ܬXv>@G}g+#5+#??xMQ3Vnvpqy0_|J #Nr;][H'j] LT|ESa1lqa .v]EE gAndfM ܏S+iv55U%a5=@ϫ%.$,՚ =J+Z|Mܻ|NM 6pZ4),D5%SyϢX"7lim ++BjJk j71$ֱu7 WoQK?S)~/73s>Z`=4c:5vwj, Mdc9@ztd]:}JȘ gVfcb9W(7P(Pu>+Ѵ9A7S +_#uا̅#X(gX-C7 &Ș\%K:Go`bU)vG 흨%/;`#A2@|<J_4 M6#JϺ[~SNq$y’Y۾gj<+/"` mb97eiԪƨ73ͤk-,(//HH2Oڲ|dDj0J5׷Y՞kTזxJ_jL#ji|_?zQ]~!$C%h+FGiUMoy5QC**U.# YLL{:SLe(L,9&ɻxYq!-.^DX * VCTSWuM* X3 0Z|.9)14I[Xpq27Ţ*66 A$\qn랚o/ZP"P9;AK!ÝߪꢄuWDmTxzϰurnt{ )gА3L h~j@КlQ.I ܝ*AU{je)UUuE)A!^;^}4ҷXY[HC+Oءu]{V܌ba Aljk_iѐ}F++<П>15`PZ{{AM~ݢܐf nȅe#)!R呋<)=R`P q{svI & gX]e\*l,=W@^Mpe2E?V =7gr;4C3{dKuz2f<)7G\-;cײN֗V9cǥNs{ ]{ݥС[8VHqiRN37Sߥ>o8J}%PyC Arlͽ]J6nO">{t9λc-Krj?9|:*)}^mJzy~H⬞+Z?sz`|'1^wPޏ^qBlT :t3>Ll~s-~rV<~s3JǨ@ EC_'CxnT tܗ0~]^L:^xoC_.e Y^s ʃD.Jl6Jhף4SC)b8Q"z^&nٓDZ "KO3 I6`?ܣON:Td~@ag^e֭R:\|J|B|0; Չ+ڟGVhnO ϙ Ąg^q[&-u'B[#AvA٠lu ,0ߢHD]UC1jɀ<߳Bk b%b她̘% ْh,fLd5!]s`$L!-CQ(X$)8OARq~Hm ğ'G3(xJ=RJ'RIz ΤȒ1P'B2p;h;rymtGکQ!et0 d&jtAľ|(Fb&ʜ?e62Q"0".s23e>("b0~daߔP_&1EO fҭo:-1s;ubShwx, X@J)`;Sy?MR*DJiHb,v޳E}2D}RZGSFgeL5tZ)R'P">T.꣠UmTLo"yz\j\}8Pbƭd64Wj\A'}-b0 21BNUoQT-DQ$*hڮSX+Zf @r0J1I8KZp\KiCPTr;MI6c1ϢKa &yTWDnkjw{Q"uoĠn@N=D|n^Lt cp&NՊ{mjD&dM^M3k&Nt+hO;P'Wa\&Z\)wM$j îOXQl3qtg"}uox{ źb ;wT8+Cn zOk^WI.eFtfI69M:rm$tS)'%?`{0TɣXY@UCqiQrop+јozl+#H|Ouy36ώ#e2g̛>,uJlO'!e=P&wщT紸.tGp}弄鸊ߍ+kTay.MD/G#r֎KvtuRadYSs40K^DRGX)'Y~6yģs𲼍wjk9,[SOK"I:4،,eVH^t(ȔP (寰P>d,C=Y:>h&lv/CC1M Pþ!kmjۀD@-n&ƜZu(g0P9)}պ`dC4nǘI4b.B= _BWP}u&"/c>S,Un0[0(Qp<>7@d*lyR+=tZJcLD<ZZI{tr}n1*)v4֓tfLٽJs@') '0ܱ\ci炼Fk%1F4+</UkpjOȜO":<KHo>m j:0;̊F b3JNf$t>xRYU|/[#vOWJPM"wYT) Q'n% f (zeUuLrՐ}n.)@2%Iw;5&_[.C$ܟ]I mWbl˖}"X,o4 @ D:E*,a+Vc kDk^@Ү^{W|A$\)KiDFHiF^׬1Ps/49#k~Z+úx{wB5s8$`TYP` 7 5p_ts70շZ^*;iH8@h\ѩj=&_HH*U{^D"Hhs)gZ5,)E|~׈M\/ȊUMJ|iq~KU5rKe&Jfld&ߜl,2fW:T8v&ڰ&R^,:2g^VN4$^OɁ s8ׯUx N]u'Orӵ~RH^Â3agJDN=D8Cb ?Ƴ9W8Z]<u9T"UkqW #k^!osQqoru/d%.,p ظkeO]r\ ohۼ\=YUW8q׻?7O #6 c ud_oSne\؁CɭlٺsCnƢ/Ji]!⫄v{, YO}耩 dmN@c5W)"w|rr&\DkftxxT$Oѓ p)\(etvt΀KဟoyWLbI^zGk[qDe3iI8F񘶘Y[G] o1{{+gS}B +=K(3n=Tx/%c>rrlKqx7>KHgg71B8Nkm$K6IG:C-0 %}a!VɝKAz~/U׶?q䣥8>O#6ʕe(eLN8uX^:8ZZڢIn$\vˠKjUK/JR{h "Ij;9f-Xr՝O+; {u7owdvdۍ?wdn#{m7ޑh+Ӿf+7/d59ܗ~Ogp,ɧyHOk_J.(BVg"D"\/ǚ? t8d.ּ-?Hoh"ޢRX߂yJ1{rrg{aPK )w:W 0org/mockito/asm/util/TraceSignatureVisitor.classW l[giI#ii뵬+mBЭM:sqn7]_v[7`{16K76Vhi6@@<5  $qN?;|7{ls3ϥn.nE78VNG[twqkŠgHrk0Bl|jKuCv*c9eh1:HOqxvR0]ؓumgamgwq+m D'ٓ+fO!cZvd^N);/(i9#q;&\+5F{(`9u,ğg'ٴ%hqP`N{0bq4 %a\²0B6Q!Ds'kjvGDvgXBR)s- B)a/J>Ofꗱ_wxMaL"Pخ`{$@F`" VOvqeG]f0V6A(u` 9C* F8Y\B V&ȵFy Y0b;y~{wxquO0<|V|V9gHܐ-{g.eeJI7$^ %rE'eNgl,g`P򞫒S]o =ϼ#FѼ@o|/0;ĢKki= L!0gc29UXsF)}uЌiW}t&C yi ˙`!Yi Q `;khձX'>`t9͝|ӈߖr=>MB3nA+XيmdC8`GOsXR_#eo ǸJ]Kcľîʗk)sLg`1 #tg8e>P;i.,{{)qyw?xO1u|EuI}S5 h<r4]<@4CQJ{ƅ*GuG䘞QKOTޣ)=١&\&#zrYMDe1: .ihHϑ;ϓ7#EE</%|/c_ W}~Amn4o:/k^ټ:scQ5]QUUr}J^nma#b4f,K(bRSړruu>u*VDGYOMѨ iBR31SXW'5a"g'V!V2~ Z?E;n}V?PK nN:zW 5$/org/mockito/asm/util/TraceSignatureVisitor.javaXmoH>:; LIp&tj!v_U7Wf:+JwSUOWWUw+8ý~ xdA,~a &1F3K$`0lɟ"0zY&}weBp"-VԣfH\rgmP2$QȞDrCQ"LH,e "FI`̟Sep b1JD _{/@A=Q8iT04qwu,MS 34p$z5C 0)o/!@@I5+fi%)8-*3lLA_g jM%cY.K#(gLWFYG?a}5B 8޷}̸@*ď"CCG(d0OQqfr~\E".+Jl!Ɨ8*lgSᏟ?|]+pe,&%_N>d"8Rg5g``& rGpy=擮HBGᆛdWLR'ؔt>e,>G;e$! (Wv؍pWHT_ԉ r)_bCv[U8_A,Q\1:`&N6lz\/QSm! o36xxqz>bTV6=k{s,X$ӛw1Zs޼wzx91& oyl7[įEnл<1]-{Z*o转S.e;̎EȆ:i^↑]= 9gl⺝I bFs->ks;ls6WhEctI66O䴩1(V+l  >B5xFPex¤ w(kwL!7OeA`_-{ި砿UζF<ͦ$@p^fW2LuJʕk,sK$m"I̊wt΀M_;T.Қe+ N$T+ʧ'?Nc)Av+sLggUCH_pq$[wG[cy${(4űC)0ľ8{Dpq_j~, "܋h&+\BؽI bwkynZzRZLF3گu.:W>km[BV.5[}YmֳZr*MDH:3n`#sLu:)- m6Kh`o'4FIdĐfe9=uΚ69ϴKb 8 ?.x;t=NumWuNvYd up5Mbb`3'N_q F sHG]iWϗvBj琾ߒV"XO+eϫ8|x/wu~\Αic&o0:A&?3c(6ea3U9%VB1J*.D"DTW^!f 섬 2|>g@v殌L!ӽt6ڿS:>|PK )w:fW$org/mockito/asm/util/Traceable.classEM@ZA<36ν98Ͷvem=P’0d~2`!aj]%+O[Ft^qp,F ¤+ m%EO#e a1w]Y*}ÎHsRmQ}BHPK nN:3, #org/mockito/asm/util/Traceable.javaVn6?<) T' ^V阭,D;JAI!e'졽>u{ssyA7'tPF5ɶzM$m^zUJQ#[jkF=cDfb>ǯēͭlKEԌYGtdUAU7'3U鮷z3\)-uf@ro65z0Vp@*+W9 Ix(յyJVu6y]Gf{54@9z WnM(ץ DwTe%~O YZFY} RrZ'64zL94in- ,:WV˺{C>/d %J@E9VnʟL])ۡU~Ktߝ`a#_h\?"CVFИKiuf?8vu{UVCvMh]cuݩ"/ 0c*Kh$(]3~i3 &yƧEŇP x0&kb_WҌrs"C&9g"IbƓBIS̗<Dz< \bc(sZ,Zpc}9o!,QlΕ8"Cd X 3$a8}LXJp1! EmAHЌ+q7`_j uѬD? ,e^BئQOHSݧk/X#&>S /^!X,y8(iNQ$gYVr&GBϼiˆ`ivN=.cSy:IT Qz)a1gIl`--c ':gM &>p^.!(hqDn//&wD&)LdL ˋ O\Nd)~tvīKٺd%7{dSG_y hܘf_7Cpy 6#$`/pn;P^z1b@bTle$jBb(3,}ړs`ײ%9,aZEIaSò[g//'QR@Ӏ/c^6΁z!wwNr}#.J>4:g x܎~Wv79J@hh//PK T[5QTS!!org/mockito/asm/util/package.htmlVr6{вL/'S,d(R%@;>B"d%  wl'9TFݷr~v X~/7AlzQ>vzc+ j;Ugl [}љ]KŸ߀g#;n4H]#R3xE?ƒ^]Mh!,2sf_O5"ڴ CZہui.42[ Gv:]S۩4յ=6 C>`zdNaF ~ZۙpP# y)~z4P;ZN`UO mNƲXః:팪n>!Oȴ ņh?l]i1]$0Fa0# pVS`L4 tac"^? o݁b6{VC[CMڡݼ?e0 \> O WO_HXl,9N|Z~.o y|J9"$g"“g d/m2q@9,Y,5˧seF0U\Hi\,V(I%M0 e"N23VP ߥ;ROS68Ąg`F aK8 79SX`7,^0eJʂ-)|D9R2Y^'Li.y`z1@0.xZ NgE<.,g!m$,/qp+2ELd1﷢_$U2v{%VsBz]%6cK : >x)/2|l#4eKG.\ 邂M8A7I>Ԑ2䜟Uz??w{뵟MZ޿1FH28(jP5ݑ40}[hiHNpu_oP_]Ym֎d:Cʩn@B7x9^a^1`;;Ǐ!q4{~7tɧ-}=}w=1PK )w:2rҐ46org/mockito/cglib/beans/BeanCopier$BeanCopierKey.classNn0WhBP FHHlliZ~HX7;Nww:a@:_ȃrReZ QK-@TTou%!<Ɨ@.*}_+*e5M۷Ev&U!ٺyi:(]Y~Q8Dh4JH럀j.GPK )w:mb 2org/mockito/cglib/beans/BeanCopier$Generator.classX xTo2̼ʀ"HI%,0%ƗKd&Λ `R ZwѪ`ZEUk[Z[k}7ޝd̐T/s?Ko> j¼x'鶓Hgnn̘S}6㽶(_mŬ'|P V6'0#8CX Jo7LT"bPP 'm~qxv`( [mPRaQqc %8'&6J+hƽvN.W( W4(E8l)0#f*x]0?~JeJxOECo;(qj00fdyVGԊ$}xBOE-7Tl3P¨RQZ5bE ;ֹ/j_G{hz L$;|WϠ\<,y61Sd)LEuffY;da@!+™ #$=cgf$b9NyMM q\\k1\UZ!v4Ĝ ,+ۆzm;K xW%X#R&Z"[ th"fSr#0gxŘNv؂j픑v mx%YHih3)S=v2)&Ź1xL.LNnMj .FbЉ`iZ#:4ᆆ )%r D8c+㿸9iGbh5'yйz x6BXwEl;cf2h]D0tpzdW]py’Ws}@ }qALv lK'NαHxEGKsMRq\(pLY>\fB`xYUA\s^Fԇk j#fFp}!2QvVx}X7&ٻ?eE#Ν' 44dN^4k;)fcn4--2ۛ2<~1xdt飸WRrf Ǚ|=mRI, ▄Oh1%ntda)ćMc؇G4Ⱦ"љbnvC5OAx pO"n8ϣՎŻݣu=@hZLxFZ!|l4gMnH]@Oo2K~xZM/c兲ʀ1j0_c7F1|] yIx"+7MhK$k&(խѸؖ9/pzk |_:>K)j3)& Ca3}OXd?ǚj `};;N45q@JC J hpRէ0Wٽk? $'̥.ҖcJ$v1^~86;UHV7:}UqߓG×Py˔WY8k"tU"ޓP>UKSN85\W\Wbey1k9vv4urR}j2$r-g̈́-6o2*mcڔJ@Va4xQtmay͐'grəOA(*@)ZuűBqB8uRƇ;32LJ~̻JNkXXYeeNtZ;+}k9Բմ\j9}ZKZPK#e=aIF򌖢ʙO`HE2h!q/6QrUK:cQg?r+[[h)M$\-b=,;F+cݳ<23ᧇfi Wϧ T9HK5$z8=:OS6ShW:7oRΫ/+ܗⲭp?T̽*MצBlWz#M:~ y=i7O㮐]\: S!u?M 4#HŞP'TqJ 4I#]X[Wm8z]  i<>gQ֏8hbۏ4!i|Ko?}C%!ۏiY',OCtYt/+\>dߠLB[T/笔!${8+kx 0ٟX_)8+ u3A.SѿJuN⿜nƛxX߫*/wTg`!/ ɾ0TABㄢPK )w:qJ (org/mockito/cglib/beans/BeanCopier.classVSU=|4"b%l`+ICM @MfL]t 0}o3$129޽&aδS{;fJkFUNei̙:` 5Rfõ.*) K{ nI~Pgː»/6󵽍\]cX._ ʕKj~ajLJ@czi/W*n#fZQ#U0(G:t aʢSD vB2:RªqێiաR( w =lU0k㫮Dzy)]+鴂.z׼*7\cj0t UۦgG Ru5R[lG5:ׄ^94*Exz{އ~mv;3`㾕&#n2KQwį WwS P/d~m H֮jjūbU ^::hpm =pC`P_:훥(FZM LF7Vhf hT\#nC ' (Qi ~@ӥg41}gXûbqK\%h*$.M?FdI2e: naG߬DdZ<dK ! }Ȍr _#y!z!s^>$t״H"|.P9E6#{INoŶUbӭV Yi=O4Hpl#tx%e1R  H,HL=.`ϑYRxc)73RA@hC#k@hK"〠=[mj'$q x۸ zR&x؏ߍ|3V=qߔrpyp#99=a ˠҳBrJe $ o8Fg9`>/Ӈ2x4GN'7x:[4PD$|z٬-n-[UkN-:0~|fin h9n ju<_cjZS+(F2KlsGqEB/GFVth+ׄQ^ p02w3ۜ5I*)CM?˜W._g%-sÏH-Suc*~J.J=xܱ{ 2RUFƐx< PV#(KRYn<Xd͙ʍ"q|jmw/1(j$ushӒJZGٰ.yɮ1Z[Դ>\*]=u ^7TBªT35+#rXu%|D)[/{QcSQgWxH aŎg[W-L@h]=Ѩa&$zmh窣#/ק1Pd|Ymհ[mS}sa2rҔ418FC^(%UćxԻI5iҤ.ҳ Cck쵗*>ZLo"Elp*N5џW)_DeFf@ɀS'˒mgK BW{U9|*UUR$y}dL^ vty PK )w:S?<org/mockito/cglib/beans/BeanGenerator$BeanGeneratorKey.classN1qHϠlhXfv`xq`X e 1We򙥅̊iFgJ"UfdhHnvv0)U*e1lUPJApTv2Z`JvQ=4уYS j Cb,C=VJXoA5i!p@z8j -o V:I(jh:/F"Zh EUƖ~MIX 9FȔH#dO3Ml꫱#6 A?$T9I[&x$n-;q.BU$+3c"zE۫ƃVUeEgȧ6{p^5 D57= HN Ź] F~$MBA" M^Q^ Z]&vFa( ƪ&k-9*la4D!PPCb|[1hZ]Pw'igvZ (`XCEeLJM=7'5_M9O܃ ̼ŢN,,7O2$y B/dpC42=qS0C8AdËPF¡7IX<)`&iH7 1u"znVm.;$O+l ItlؼK:xO.ޅR_C}1]5G-{"1x0EFjC55`XƇQN:} 5FkfZ*ωɪ'dV۸$ ns}Q<J{FQ~ΙBSXKTϛr&})*wSŵTGj/6td+o_T_hƴf,k:RE 6"8Vp'g#|`(41N7nKRn)K ]B2ߺ+ũtjjp3nmv)+^uV:ȂD62[V@p-s_@&9El泅Hh%MsВ5c-;V'}`L2|Gq7yTJj6NX^/YJq˽S)9")ԏ͂G~ m=Ş9YNFyOFb>V)ç=#8vzW=f,'; xȼCqB#5 cG=CfMN6m  AD1arWQ|5gcx2Y3M @. ̧WA?Ӑ; / mSLYPHo 4t%p((a@&=kWTt>I~m>ˀ5u΄;~ʰ}N:|G(pB{|Bv  2e|1͸rs /PK jN:|`,di*org/mockito/cglib/beans/BeanGenerator.javaW[s8~Wcjٷd;-!dKۅL d0¨1WCi'}.62vlwnAOk҅ӓ`Ic1+")\ψfсw,\7J T DF鏚scc- X5pPm0sQ_k`3FxBaVbcSMPBOP.QYZbbBɪλA?#RgT)I y#LlFV $TR<^IO۠|SZikY+Abphv07;ȇv77dz`2 ;x;^bKd&tf7a.$ӄY )TGR3*,Bפ Ͳh&j2{X-4YtCIΑmW қB|% .HƊ҆Bb!S*Ss1 ʩ$))N$ju0}KH4V6$É,$xt{ tE5uTɒF-3ql5_u{hZ Iꎈ]T Fw ]F4&GH{Pv$9F%SlPOC35"C#ϽJ "~#W:>OLe`ԙD.',|ĖʲP2Œ!*\fTȂ<"!$+-pȴXRE10ՍW9dBsچ_x(WD'ڣ`3PT+{vT9D_^8OϞ14T T5qFfVQ\nN0d6+9TMj#͇,R8Rl$BD捚Hخa_&ħ־БlxѰ,s=f{'}TsRd:x{TE5A @3]{ +opd<8aϱƐ^, u ๩梔+'%/Q=RƱKgΠi7f.ƍ쁚+)7B]MTn(4Pv~Km_fPA5qa1jwsduyɎa|r @ԊJI^w2اI4e[ۈ\d1:9Ǐ-Hv|C0G@3<,,slxõ p·cPۥ{Z?mnw}{W%Q;(g^ M79ha[ʪ7J^93U(v}ve!s6gRj73ں=۸94*MȨrG\?{/UɜUR6 gf'31t0OE~bڦ/Kp, c".-:^5ĚvKц[|MK|Q~" ;fkA(V ? FUڢ@4(Obvܿm=),mSPK )w:;_:org/mockito/cglib/beans/BeanMap$Generator$BeanMapKey.classNjA63?xqxYT<C3I<(qV$mfZIr+u&X'~.Ԯ7eÙmֻ^f Bg~L2Z^+kP| @PPи\̈́-$U΍>{w+Io~ (eV@ uj3PK )w:^`7 /org/mockito/cglib/beans/BeanMap$Generator.classVkWW0! V hŴ EC@yij[: 80 >t~߱ZZ?kGuܙ!$<rν>ɿ'O!lXȮ45pEb4N*kM6L?C_y0y,lS M# tmEYWCj# W9yQ0dz~&10z!x<17=srhS')!iLS\l:³6Ğ㟡Y}ɟTaI iXU{6^фsл(P. uLD'*>PPeA Zns~2I W #qm#Sϭw5Tq.@5EV3 օ{x_`\'._V ?e(KjB% wm*c~0 SܤeM佋@OЕ'5-n ycYfDqa,wz=na6U=9.a2;乐-\i,.qF5oeuSI '|#[k[d0dLbˎN#Cx Jux^;_ʻTKu*DL=!/cyն9GTwJ(U c'0ԹNNƷt.JB,eS"Tk<]GżjTK"MY  UtRM 'PEZ#7K(׫8 R;`IuaҧcDHⳳũ$ua`F^ݦ,ÄS JNP-2vNͮKeOK\|-(d4>'j+)US|ފTQ*oؑ:վC[gpQ|hvQMzֈ,פIrHgs@3C3]S)9bL=;XyQToj1}\?P&dJV!_(!zoֱtObx7| RBҀo8~tO΅UWBPK )w:WΫ%org/mockito/cglib/beans/BeanMap.classW[pXZc 0[k!.6㘀ca&d-/F Kvp4mZ$M/IN[&0mg!=d>vN~gw%g9gӷ}m[X6y!eftj8>lB #z.!Pw^i=3?:|HxXf* }k\hY|!#cu3 (P ,=sd3zz >/99+'9P$@}>2o!\ܒXLeRfePr aXwkZ5-!3C}g v0gsFޜq涹,OTfz/ER #$aS`WM-5سiF $89uS7bK;|zz*FKy-4L Iv2Sy9fz.&|`O{d6cLn͂IuXOHo)S{;$ KUt3vA;`,a<}<a%WT^7.V՜Vqa$pᴊc%'Slพ&At4bOxRYR>}t*I WN 9Nwsb^c~9 c2k軶Vݯby&ˁY"LyΠ|Ajp;;b> JIrkF;X? V7}(h)(tgi#d6ˎΦxW({ to1%h>ɯe2YV?듉TIa"7mSleKUYe\o jN]ʄ-Q+bk־orl-Ap+sX 1OGlw#ț񵓿5lz݅WI܆!sqz! %-W 9(IҝKb_,53hZ\̸X‘])lc ^r|jg쫊jȻT~ɯ"-?}Z~׃?9ӎ]V=2.>9vtlp{<? @̹;ixp"j`=m.qi#pMQ>(dvuX rujMom KZpZT]*ցTV &loydc[zm!1'T[PZoq|%j#vA2[ Ott$>2[dJ?sLbAD1|WۂGcZlg=[d:!ݸ(s)ĐyB s7w?:XJԮ#+yj?Ԍ.ι9s,JkDƘhDatIn @j#idN^SʧqD: Og[2|1|Cw YvI7I,1ؿELixD}ƒc‹{(AD|Jល [iZS"̈b&tNqQ0@X mV*U(mwbX:yhB_%X!bEw=?M/.gEd:UN Z̊y⥦\ [.Vowb56FZmb--.Cg&9Z&f)*km~֭lJiTr5ֺp!|z#p sr*>D܄b30 %GxqZ6W"^nf#C%V"^%huZ6E|u~-H%ϸRk쉶;[)ubގqDL]t ]MjPK jN:/4 3'$org/mockito/cglib/beans/BeanMap.javaZs9~_!B28pD6wc ${v/Gcf<4vl֏xd-x8WAV# D|߻?咑~N3sעfTs*\He 0ItȍtG& c7t9E[QݒLhR(2"s2nk3Ur%l^}e|r2TSNaADB_Kf8rK\{? ''_uL)"o`tKhj%t ʦtC$t!ijo$<[trWZiky%pF3rܟ䘼OF. et痣\rtq^'ntK`\&G<̀7a\XT> - `d!Lf`ə\q~U Ť|ŵ!ڵ 7(W"Z"xhN@/!5}?>=D]b)Kt<,-Y^Y}ByP#V J}䊇wNdFLH3L)ǚ 򑒟``YLL؜&if[P^a4%H+H`ZCl;}ۉIW7Axb(Ξ,VR6dNq uя6V8lt!3*gkV36&ckb+oЦ(@9" M&k&oجc0IK :eS&At &y1# a5[ vŏ_0Ѝk5 s4 bC\XܯDHPIN ˘@ kls3 c&3g //crFzCƐ7٩4-KA2a%|M2K2L38$nŤLK[̳z8@78;|b3KT4+M ת]ASIWs‡Mg/lL>,xх>GJp X>:D(52B!.pۣlVͲ"}&VÕkAWQHpj<:;lCr<4u:.ztA~?"g*BjNxlՠݻK9O.!LiB@:W#GȀF6Nc$pmn;V2wN[*j'_MmՉMt.n7QKQ3csX¡6PY(V:&t(ǀ ˋg䡋8450I>cXm YPɭ u-& %ۥE`+-Y›ɊgP<] >#>;4B=MZB@Cѩ⫤[Qm>G:69ރGJ.~pݦ}=bj^ׄ6B~?wf#&JśB>֮pի[lTlq{Zߙ$=|(6PoRWDamso#Hh )_Y;pAX\UX{=2V(ro($+PcƇpn.M}p<ݗ*RilAӾ\ %*:ڂ:SJ?MTú,(Z⫀9|iqx~b%ڝrķPɺcP4#"TBBZ%-zb\*RpT5I qUȬvO}2(3u':t3*l \`c˺c 7HrQD I9V }wb\ݴ'35L5o\*mk p&4ײBgv&Z"Ĩ7x6j9ʄxož{7hn(E\CH(=mtIyJǦmK]7tOXyf10b𧕯гXVZɓT,Us{k81B @+@=e(o`r{j+OAm)KqCrȋIJ-\BJ8F{q"$t4k]Y4 - MV9>>bFzdf0qFPl/vpaSXۭ}Zs7+XlGy̕gAiB cGK;?I U|9֍PVpk E_wl{dQ'+}'DSGTpF] ByVmuyY #sSa1&(w4 ?@uC*CQLS;,XJ 簜!⿳6 jMV8%~,~FX;\v:f3RqLy&il e p&"i$;{wjזz+!]Ҽm˾FF^ƕ_o PK )w:o/Ґ.org/mockito/cglib/beans/BeanMapEmitter$1.classUkWU7ʣ%b)ڊZ@+P|u3\483A1ג?}gBy%==_Ŧ@*VͷN[vuVYI/q]ŚE*/宴\Uʎ Lư@T~r"{(],^75DwT !(O2ROT$0/+2 瓋FM'70tsBjZrA-bBsюncm9xѵ p[Y\@> eя}kA\6E%,cVaX!mh*ÚUe咞cQANω68 1!p5&<~]ނ G>k&Ow^UrkYE;Q@m) 21iW^ML3Cbmm:?x@0k7ι۬.*~ij= s&#g+ekNœQ#Эk-r~,m^nOѵ%~X`F5uDGbMv|Cen; U'ptQeuvlqE!wן$#/@]~}k{i'6^PK )w: (.org/mockito/cglib/beans/BeanMapEmitter$2.classU[SEl @.]&x E F20;͔ZQKU^,߬GY~=pYa{w>}+ˮbn,V!_P79NX mrUm h0]O\f׬\]JM/iTQI@sI9ʓ[PgP!*4/pt@+DFܢ1`ӗ{1, 8h̓p#hI-hիSM:3ڧgRH@B"= six|D{o;WlhٖUTRϞ=pzwoHf\D܊Q回U \L{F ܢӘZ "B/;KC Nh.ka?yI3w]= ~x /"^Űb՘ rV?kxMDzp/әJ BO?L]OH&FRQy̭WxLǎcti x o-Qp?v_n:ö+ +іγӶ;ds׳kan\Fyt+e_W~:k~LizQ lV2 cjXସ\)EXQw?,CSu@Ct7]RPZU2]SҳdVszMrTuCT<昶[Ni! |t%Gc[n|ghfK__#vp6Lo s?s.G8ϹPc.Xnt~ SUnb'o:ԙbgT<{VsqTan& I4RЫEjI,+|,cI,vS23$`Cb~ɢ W5L[#3;{|_ƙ9~, .}ѡG&HKmR WT56h f-zRkF ɚ Zڶ::z$6knSJ=ήfE\ki\n} mh1E;{dNE3j妖nاp;aRNCȯBVČY}XΉ^?@% ߛ~zRN"X%P! 2c`Ԏ2x0CX$Ed'S,S[i[X B,{Ig7d}ߩ $5VJjfZ%8|G: k3gi?h8LmDaD^=="&+% yN  A+I'P9|'p:lO l֪.`&LI]hF(iG%L!3e8k ;Q1EwX#{Hm&z~!b Z,ʍH'KZ&]Z:bib14x@XϓXRڲ9;P *ecVz8yHHq9$p4+,5I`l:+^W Y>] \Z[CR̕ Ȩbz!]IwRBX5 6S.:r5b]DU0sR`S-0A0FW fCZ93/Rnrø ! I[pGi.3(9UҐ Tbw pC$bȣho,i ܍cǍL᩺k`>`ɴrS'[P YIzxKJ?%ׂa'ylS2!䆚5#E8&I%8BÃ̳|uƳwz=FE,Ά|`Ns>?3eEt.K9Ӈ+2S,ߌ . F>If([d/}dm|GyY5`>.RΉ3q)-<'U$R.Z'u` v ot 4&B1w <}7|)p? ,W+Φ3a^(c8b ccx3c8'YJJJSBBrF1|>&^OIoRRy[T\Ye/{+P {Ux~?ʫJ^x'H-* *ga 5H^"F(N}$I}ah4ڟjP7P7P7̐릡s&kZ'ꛈf2 eyOL.t8iolezy +iʿ(^,xqL =IE4oc[^۔=%ZKʞn˼_3X|X♸+q'*py7en}~)1;eqe²q)ťVT #[R8Tj$K/w^V*UsRtbw8] 5x%8tjKeKQ\#"w`w=Bzpt|m3ÿ&)O>80I2ၘ260y BHD'$& 48HQ @r"`3,' ~c̼sޞT^fJxYLOBszDtO"2=o4_^FYQxR?xS>$f_S5uqqe6껹}$RrxРU3p?7zZWėPR} vȬ/)tFw7naF`(;ubS\oz cogcl [*'xp.$fi+icQE%PXh53ZqȧwvA^t.,5 2w};EIc\C~P)jݵSFOy2HE c$R 3֐:Q 9<9NȣIى۵{ذ~yRҔcZC-xlb.*:%M OP7}_XLuɌ^<kzUSud4}'ħ&bf: c+c?0U%WfP{DJ2 Ǖg&C(K :[ZǎP%惹eAt %ʻrˮwif@3zZFKv擘"; pIO4ڠTnjC2WE%:~h %Jڞ.64V2C&se$R6 ̳#Ю^/)hs9,T;1HZ\սz6Ic}rGr{MN='|69iX88=5j x(yw PM,iV6P ׋UM˥h8NiL&@ߗjְ~g Zo_eO~&½5Z`#,[H$#_g-ϭ)&Ojl~Pl@k"Z͵7E\BʇCpD$`!zwڐr*x]{Qw ȵu@uq~f56UI|*R+d[ɹ)I&wy5ɩd̯$Zw-sWsؐݽ0cfl+w,烝 {wawٯן32+R_j;ZPK )w:@\P2org/mockito/cglib/beans/BulkBean$BulkBeanKey.classN @DOPk(XXZ8Bk~%^Ql؝fv\L!"f\dI3$bڰТ ,)?r:J(] l\ _.Ban7-O mJ$wҦ,ORSDٸBkY7FAhGDNd PK )w:p3fG 0org/mockito/cglib/beans/BulkBean$Generator.classVkWWݗ@cTD>$|TkkiFXŪ&:3(}Տ+u~O3!d5ke9{>? A,8|bL^%o,/Jv3wҖUf{ɢ9 Z]:0Dj22@4 X@n86\ I5uu勃ONIz ۥoLeO::vI%}77-vDO DҽcIG{-*p<~n+خWBT4t*A/UcߔnZ].ڕ!Co&e/ 3 3̔-)9X ~[f{O*A!u3Kj8ÑMt51$Mӵn`z 8Я1v. KeϴIX4 1$=I ┆W40"&$Y|Aіlm7C" qD'?o>yf}cQmrtQÎ^:fD#Sjt43ǥ{wd!=¹x\- ˦$*x !7ϻl}7㖆DY8a:\B{BQx!Lb.%XO0T^W͹,PG3*l&BDC* 5Ng〚vY c̒%wL!~°wb!grۯڊ[ccEK^RwL(DU S ^gLI٬Z]b'릕;ڰUkQ_9r8s]AR.3cz~-3!vp}¯Q"n'vU1)Wh&;2BW "La+0JX*zk7+Vg bݤ$aXXEbQX?C9>]/>*2+p/E|>o6'0ٿ|]&^)&Wv) \f"3]d Mڢ]6O\7~4ׯf3qSro+!Y_#A7\]+>!Tm0Յs/15Kt/©J]吒T%S["PiY+<.b/8}{~0*kjԵSڅ< |aw ?>Fj)[OjBܱ*[A{;MԧbW;4VmSF/aa+Iƌ'ְ.PK )w:;&org/mockito/cglib/beans/BulkBean.classUSF}يBNRMIK(mp0MpB\RJ;Yq+#!]Hq:4PdCf%۷ Q`q=~]o6jZ~*5B`*4VY{&mOǰٮͼZ J˖t-qu {C@߮!tΜhcmRuɎ|}n z[@rji\ԹI-0{bysZowG23h5LvҠՁ GBW2nӽ>ឍ71DCb#\4͐Ȍ0DOՉ\Mf[gb*pV$7n:-F㺁9 _fmx:[dgLv1^Wހ/;tu2,W5<1Zo '=W:eLb*fPLybҙwH-Sy뒧%??{waٶlbQ!n&Ϊr>brv3™~qe.ef`^3[`i%gZı6ZSVG\ђj g-gߵe+ xsʉ1%{ӗPe( ËqT?2~`)grPN4KJB/`O17@{wp5 B`}4> 6[9{,p}0!1uP8S/[$^?ta`%~oF, 3{+_i=B97bIKi˔6-ҮwMJ`f\iTч|M}/,qDD߻<kc3X!6Cj}47<>}%I CK3iG0~W<Ѯ~?P&|c;ΌPK kN:'g5%org/mockito/cglib/beans/BulkBean.javaW]o8}W\)TlfUZJ,YQL0ie$vv# s^< Z+pu3_ėjG; O>XLSITٝ[ #[~HuL}E JV4+ G:hvCT xg)JdUN>q/M-]ƺ}H(imм]`isi^KIc-MjhhiѴE~[ l9jj=5P۱{PM7>hgizC9*N3fOm\zkiNQ#3McW)d+;5@.;1EQva%b^ mC=G/:'l( ~P\>cGkZ\K3Ԕߝk.}YҗEfAV:DVNdB *IV[e~,r7&<SߡI3*bcM5[3]tC$TZY.L/[Oʈg"Is:WGr)uSqΔ) x7hCMWDWC6JrY &u<"ē|$Mxq.o>W"_~*a+Zhy>#S$"H9!ӗvtH_ ~#OD8,Tf9kҲKMY.)g\u.; oTmٌ Yb9\ȃ n?.F S} b8Sis55''q 2~ĥa 1q ,/Ä5\H.㣽H;`| . 1ݬN݉a ps9%x k3Ej4?\|2䩆=N5DI~8eu# wlQJ/}NQ jmpZp@]>Mn~p|즬̰z9NkutRn#U,=Zm]p$R&%Ee!<,հ5=m)=|'L( J Aۺe3 (tlnzfr@(v/b GALPgAp% dDw-cWTD)9>I$ mdxp&ک];_P(Y{N8''PenSӞQ&[t=5RD2'`ܰz@:eqiZ>|WP9hϏW}È7<$ؖ܍%~=<*sLe|Տr&pұKէxL^#xn4fiĜ}xp#zeNWvf.KJc,v_(%TJmX1i' x N?p[1c96i.q\z 5^ݒaISf 7;[Λly86"=~@ξE mh(aƂ;JJS!ܱ'f8g'Q :'SƤcE]^MD_c~πFq:hZOĭGy0Q5QL? &LrFr (5s6}L,BAnM8>ykn4eL"k6-%-{"qA.n̓7Czdhn!r1%|nZq*\O|­p]VFpRW~,U AT; V\Ed^̋UX ix זQGe Ūu&֨H6c-[nZ1Yis͖OU غQ1+uq*s:qkK3m] *~ԋ ipq#hˠ3k\ w8:^Nx.ipgЫ^d`_;2]-[k'0L?{^ƹ>\xb ޏ(<Vh Ւx1~ +D߄ v>+3 QBֳb :"ՒKV#O]u[nQ2$ p5=Yw-jX$஠tÍ=ތ;p #$YNw;]xFjé;\8"f@}7#b6,org/mockito/cglib/beans/BulkBeanEmitter.javaXsF$Dn3@HN=\,$Ew{=IpHc73Ճtەj:a\ɯ Z jb$0%.'<aNpcpfE~tN2 PA"9=)x" <+ZO&&p3dnjSt͕~o6WʹvϚ~J+Ntߣ9us)!'`11YLd*J,$g"8Q[QˍDM rԡrzN|\Kk8lG!tQoǻ^C8 (&LA<-aj'CׂYffzBR^%8!1XC"E`E=c{Y k5+|eKfZ;S{X' Ts5' 2%|Fi 3)o")╇^sAWH w1pJG`"A~Q,LaN(G|p,`*WUw8uoZXɮktP%_3Ye(&0*1 `CՀH7F8o7B4#:hx:+j]&eG8\Q7m^U$חvS:Zun:LeWc*6i[ף6"#2k5O l!6Kb1RR ,c2hS^aQqtKZb֏RY[#&>fj~^fUr/xmbԉ`}(M|&Wm%SV^]q6n*A&3ve(.*LQoPxcWGJH3ϵV˰o0mrB:ᄯv9XV`uJz1+Ӗy'fl⢵։J=xL*Fq!Rߎ 䗡T^*ɕ =X P9ۮ+=r4-`fQ0i !`pE0OwD[bЉ`>̦T1#!_63ntJH`LgDkw8nM]H6ep+9dn_bGl>Yhr#p},^n%TnW=F0Ǎ5c:*&t^@-@ 0E1o\AjَPOVQM'ItV)c=:rY./w'48 v]Y̔.TJO=5D{ ;k8j_2WhZ[ xC>VLOQi +W$45bWHaP Fzi=xO¿w/ȃY[&8SnfDO @mh~Ga*RHW~( Zuy\Jz 2D*%8Hyߕ+KEO(،П BZ{ׁORj(EcRkx({oS}80x-_.KQuAjj^"UJV~7@>aMKqdʝ|BZf-b2=ypL|[~$< H C('n(kϵPK )w:s/org/mockito/cglib/beans/BulkBeanException.classRnP=8I>h( uV E H*;7{c#?$  >B6HHsg33_x'No*=?Ia2zvwz+ /QΣLTJ؜=*N}1Q;9KbBTպSY 9 -LXPGcL7c"!NlJ3ً+3+l6Mleam]_&n!3}D(>Ǿ"QEՁ|<$cy*˶?*3jk;|% +nku}[hXgb 0^]-԰m-13W\9Kmc_zRƦZ˼_ w8SZykŭ29/:ϱ2O$;uW7PK G:sS!H.org/mockito/cglib/beans/BulkBeanException.javaSKo@W8AD JoE=BZ)Hiz=${2 1mʋ{dJb+8EY2L=Jԅ0\ LM. aarBz;j/ |"d<|)m?p_D,A?h:9|*ωej`SI+ <  ORݶgN9d膶ʾFtTSAuSyjv /xj3[? f6.sD᥺F[iOsX8(z/+PK )w:[)org/mockito/cglib/beans/FixedKeySet.classRn@={]) Mo ǁoAHREEAa,鶎-D&@jG!ƎE4s 2o |L*r-[p/{.F` +=JS;TwT2SƐ bXlO(bȅ`` ғ Cx3ƹ[Hjthtuh5䰠9dȰ4}Ó%j$cQX2a[TpT1t:n0ԌTw]ʐUPڔ4 wۮDl34f:pS&uP&%ԉ i+LeJR+?O?N 0Ty4q7^ -0whp˃xW6/=b8Eh8H;4S }4b|ς'k-27 \3W(?Pyݼ/s8>[m!:W₫dkT` XzD̯=xq$ +aCLr]bT7PK G:WUP0(org/mockito/cglib/beans/FixedKeySet.javamSMo@+FQ;JoE9PD ŤQT^f(P ̼7]&pi뭣rp~vkVZ~2V9ۘB1Y#{h< tPߙt^p( p< [FmXƣpUf nꊔ-ӳD9+Wku<ófq۶G֕q}zy=Ϯ=T=8ӐT-ElZTPzl)OA )ޏ$7e`dfCdi6 $Ov񸄧!/ p_t1Hpί"BXte'Vv'רiEZQ%Bi_q5 p^ qw9¢x 9I:XBl#]VG9*g貎zUQTE)M.)C<%$Jʪ"rCoX6CnjjpWrg'E2R(n(2_[?9`pѕ M١'.VUll!h p:')!Q^è3>NtNq8et,!7΄ѡ.cPK )w:ȎZ&~5org/mockito/cglib/beans/ImmutableBean$Generator.classWYxW-[K'c! GIڄIb'q;q긭3]K#wf,tBKZR(KIȦ!a-#< /|};W^%Ŧ?=޸`(̻d.oM~>ieXrLLrl퓎tM?!:˅+<5-7kz"Z%xΛӦN`Z2zz.p#*GR'Nvl+RjWr%5LyiܫM7#}v vl[66d(jp۳E4bC !v'MKž{n)5kNnaG B#mewЂ^AIe:$BVʹdz[F9$bhVr/.X\فAߵ ߎ jO=qXΫXݍ]1:[`Kh/؆{T0N`Lc94 Ro_ ٞ6D8uit@{~%V҃\ఢhw G'`I@JGn7Z;~.ɌZѡD*U&T^8L;IzS=gTD0h%ջrtܖٴ@wb6TS81)1Ӳn߾]5VcW> YcDv]+WJUͽ,吺X|rQՑ )F0%QۙOQ+ﰻ,RՀԇJQQC"7['5!I|%D,rJ -2URui!FЕ3:mf 䡧u3&t)TYfogو.gt#=oK 5t_.tHzkO5!<e|sG@b%g]mjR#PG1A[r+r1r*a <hr\q'U/d*tVO$>oA> A_Yb3}vwޘI?/"Y(b{- s 7aT^oI*ܾI_a(Ztݼ Ob^ILL l hH_4*/PLt"ljk$=_,jF_nR=zb֌ۮL'eZaNE#qUQHGyaAr#=f3Uo 2Ȓȋx[KŞ ӬY5a*jv[fvtmESA2ێ<^PMS[0RpqX4jL[@ozok7ׅZm3JpM> 8|g0vq6qjgm{Ulj(*, mл%$,ZZ ܃:졵]Hpw[:y&+܆dIDɮ&-W2}3躲̸T`/-1 W{h\/W[׬ab}Kбk82L{w6l 񁭢Xlhl*8_FBPiȔjpzA=.j骋ׅjgHW}6^µ#͑x'^9ǻ(wW">hD75@pY|" "^\eYl7MDy3v%|36/?@1Xx w=}!EGy<'dGS\a%·px8!I'cd)i9z;9,DP7`Eiqp3ܿ$p pi+Ļ>Zc3he7 Z5ީ^gih%2G*ˡP*@]f|~5_@5c54.J:vF=D,o1JPK )w:V%:+org/mockito/cglib/beans/ImmutableBean.classTkS@=+-5V^"*`RP|2~lN +utLAZ>dosg7 `k _Q=ժ8vY- jZ%&v{:ܭ]a 1NI z&̪pCO 2 C_%/%(6z<ŏ{bC3[ZkE j5?K7Mݤ~^}jBV \Z? q`VhFa)R6%cĶN!X[bH|C05k0J!!$JVqT Iul W0$Tt9bJ7O3gPt9WnY"2 T\Ҏs8Ǣ'CA;R2aĬVp=Ð\ { #*1CB`H; C',o$0O{>\X}5zDlFEhu9*x+qd*/IzD<rS*MHb1G`k߱#m-31AQo:Q ѼGgΣ%KPK kN:F*org/mockito/cglib/beans/ImmutableBean.javaWsF~a8TifXƩZf2!qԻMwN2i׷-+NO/0[! rW-Ֆ ˬHL,%+m#a*q$@jgTJzpBrO R}q}g=B"wRyL(6̮W"`e$x2q\#C;?@L]/aRpnJ -(PXAAx+Ag Q6bN z](+XKGwa.)Z3Qۧ, hv0 `6 y+]YxӱO3!Q:]?I0fI@phvcL`6f7;ǣ*QDDӝ?O7kA@v-9Oa@=wGxnH]?a^٥jԭL;/rP*ٚ,SΫSRS vĮDe';@b95eRx%e 9"eh݉wP`r=%~4pcTc&5CB ,I-c5mq«|s*K?1%ۄj`)Α"Sb5ʘ>HTmu/6cJDm[nDY۪5vH~hB Ԡj͖ڑBĶh髟iC6gEj~1+nXI 8[E[_u6-1ObҧKto~ _g:&' rZҟTZZ$31ڽ^#a,.9& ٥?vS^alH^<:5uʉ`ɅTIr'ѣA2ݞʜͩgW/f<}M.&!#<91n#YVʵQ~>tPK )w:5org/mockito/cglib/core/AbstractClassGenerator$1.classRn@=ㄺM\Ђ<% U ux2r8inRЙ*lc[!V$ Iӂ(򝻜*I,ҸM,=o`kp DcC8Bj<{ME2Vhp 形 ?PK )w:pqvqr:org/mockito/cglib/core/AbstractClassGenerator$Source.classQJ1=kNmm(|@ՅZqMH&\A;S hBNsOw[Xf tA-Oth.Lax"} UBZ` sv0 7#2ƟY0d%R>Tl ^>CZpѦ`~9"+sPL\k2$kM9H@­+챆׭~ fT`*AZWG;}tYrf1РD4h+tNis0.k?`SG?/f]^ũ)>հB0Ԇ`Ukޏ- YĀDbm(9Pn+hiu`p ?݉烞Iyv,y|ns'~j!9HZ76>.H85|O_}5vh[w˿%v&NrRzTEʫ&'dU!%k^5 ?b{w6Yߧc•dt#.#c!#!? 7w=DFT2։2Ϧ<:T5CkYA6?ya0Xb-"^#+%C3؏K8Q?T:+= s9yE%reZ}#_& ^'[ProgA]~>:D6&6&S-Ϳd$38ۄWmX%ߖMeYtrPƚ)|PK jN:kb=  2org/mockito/cglib/core/AbstractClassGenerator.javaYo6 ""^ywOͦ=Mv,Ái,[~ȔDbI$gf=rM"?J)Ͽr( ,FdQfk`n$w-t9d4L~>̀K<O-F"g mKed+D$gr kL\i(BFtx/'DlS!Mb \7/iKn'O}g2 \\gɝOz LB=rޣS P*BG/|Q>uP "B|2[@XOg*Hczo.3D EFSr|&$c5`ӵq`w"|>-fo)HT2-³==ܒlCTb9'uqftJE0GRtPYRB,O}SA<7C@>ſԧ-OX"e zu(Y GaaT) W-p*3vcj'MgkaV>H|wy44#RcsS}g6dwTSD30gva"}'lY81T̜E>a!QVr t4pt܋ƨ)E2Uʬi0/Uh}O/Y`J'EvgK*E? ffP4::g`4-qu<*uАL3,7ֿ  ipL+@{Qշ׮8:cBO& 8ՕbGm,Dw+W.gBj3DE LhaOfX7w4o%:OCb3|(M G_- }]%+nN0]ZWes qpY*O=Tykez!LF(VrHS%;ح1֟n)F\gz :KŅ@?t$V$mĶQC+q&TPRvZז3K3:fUIucFӄN];q@z R| :a@iy+}ϴǹe=x/MmsJ~VԬZve"zHp 1Cshqo$אu4Bb1>&XBQ%(L&e(Ch,3G 64-^ѩčeoKV {ж ((@v⪵q2F-VGNW!\.cH:E2lYrLV:n˚1Ԯ7sʼ93P%xe%#d ^uB:UTŠjEB<'%uP6І > ^נC3Txp*jٰvUl)_KKqSE\{VO҆ނ}Y8o 㖦 6^.jL3k%k[*Ϫ^zrنhtڶ2.:݂B5To4Ab8M='jn<|MpߐAh[g,A9J泎euob"HeuaxqhF?&l: ؔJvV3ŪE:!LHvUl+ ,~YyJ9ѼEs.1pf2ܝr1]OoA񴈡b "3  zntV+Œ^. Z:suM. 5&b.JsG 1].+p^f4 H lE7Ɵ*] Bs`~sRe[E~sMXKPK )w:d"org/mockito/cglib/core/Block.class]OQ7h@ nՍ/451i4 c]迒D$DGlABSoffggy̯_xZq*rQ\/$\DX=pKO&I@!=3!!;Q"Vdv@\ᐐ{䇾zL8s꛸ M_B ń<ʄX'ݚT ƚ4~[B؞'4Yly$Օk<΄1Mh\^yȑzJ(wʏ<,ЊXm bњHU.bw/!=p ,7SÎ>HF+"'}1km+]?/N2F/:=$#S| ͞oQJ//F nm+Χؗ 8sz8lצDLh'v5P?j˞T3J"irԠ\(Κ{ ss'߰sT{%:gנ+Щ&ceTnPW]־YKPK kN:i[!org/mockito/cglib/core/Block.javamSn0+f9AԽmm6Zzt!X8vvHъߙd[37*+7|z:¬)bҙh*X (G92g*:`tGSA!!aH[-҃ԐTR~9z0.ݶ_Xy_LE8466M|ϿKՓVXSIK#h"!J`,"żaڵ^| dy+\$Mhb(3Kzl-7<Wˇh{~Gˇ1 yF}𭴬hJƼGakZJTneJt^!7A`0J7}ō&gr:,LބidM-c}/.\.Deݐ*A*efiAx;hxV{ 5༰4m~Aۍ҆WGa!~8j#l0G}eq02c![ЕRPKך4)P1 F՘!E>޿8N~vΒʘJ_g}t^qePK )w:+fU+org/mockito/cglib/core/ClassEmitter$1.classSnP=ymW(qny.Z!*EB,*ǹu/8ve;"6,!`ɂBu"ڄHϙ{ol!Êzӳފ-u|;f" _N15c/T/syf2,$$X=dFYVӵJ )3^}ww^O_k `at Q'd_ Z'ǦiιjZ"3 [{yMBrW"|C1?R,b Ơh^x'`2 )`7|qdˣ23vayQx^-RT!P.I B TVW/KG/JUXp?NK{ "[,ө0J0Y.jiN&]Zşuɵ/+yA ~$ 'U&2xד'#O˒Hz1F_6p@$ƜFNhcAXfm,i_qaFpBLcwIFdWp[W'/ rϑ{dWw,~ -{$?c|J%3c<%cyåg^J>8RHEiz?PK )w:.+org/mockito/cglib/core/ClassEmitter$2.classRnP=yiJMn@*R&U6]s^Ge;U $b7t*( !*g9wt脝 t /OT㪾a4]Ec6 l<#`b N)%Bu8&#h}(V{_PG˦ߟJ9 d"!W14dSᕾT@h6{Vើ@{X'dE4|f7 B,I;b˺e5{'FX'n#-Vqw[ 1잰rz"T$ʗ^_ -_|n)Lf u]_4U**9[⯌UB9{Yi=J1mfX 8ͩXJTp J٬Gŵd|VWZ /{+O˸ 'rO3_ vR2?x ?PK )w:̅m+org/mockito/cglib/core/ClassEmitter$3.classSMo@}8 .MBҴnF""\Rpܕ"Ap.~? 1 gf󼝝WX#4tc\AɡT#?vc"mu rU1a~R{'LQ P&Oc³vW 0Q*'Q,v_zr°fPf-Gh©ǂ{2]{*ş9L2DC+NÙ9›b [OXSí^mMX:!PWOɖ5.a:RGR{1AS TH@D<C3x nD*I7y$"5Z^Wog@(AU^7?ykn8p908'ˠE\@ɠ&.J \e ]a\z[K&:k~r3ZJ씱ʫͮkPK )w:Rz3org/mockito/cglib/core/ClassEmitter$FieldInfo.classRKOQLہ:,AA-C(IutNIܙ \cbF>Mxm:{wν~>|` F`|]pi7\\>[rCe:o-Zkyb~ۡm+##B!CFeۼ\f`Yg8C{nt8^a|uV%s]_z䌝v<'dLe'9<ó jjxVG:∠SG3PЭct؍=hA@DET:Y\vvTף᠎cC ;p8#*(MDU.Ns\HcTBF2$Оm˝ʻ|F, -9*<'i# =y͸:pd Que ;E؄sÒY9PaCg 5Й"5%MH{ҽN?PGL3. + Sz (]J2jHG 2lrٟ^5QQ]܍ MhPK )w:PrF H)org/mockito/cglib/core/ClassEmitter.classX x\UdN^4I[4tLMBiIRZa2yI̤3RD@M\*ZL-/#({,L}sYy_>`8QD'؛싦HO,$f%N6Fi3[1;uԎ24M{`hcԌu Sr'C̅)ܺ܅Inmva*9-L$K?m4B?[}\-ߓHkIy LM/jKH(M ,RlV3'ѵ#D<<Ɣ)eZi6thWt$QF`Ju; <OspLY {)a\楷EX234jbC6`Ix D+iS`e4'8[Y'}є/?E|݉O ߍfe=wl gjٴ%tƢ붇Z6ov0pVVBn v7ʳxp3>̐iWo X13>*%}.CѺ}fyUuyA?{=8thMtE$ :Ҩ6e%[, y+xa^hأ#R qX$-6K3nS%ê9(c&.%dk!c;h3fn+H4nnd/g<F(74f c&=oso|]]֛7vg@ 2~m⼍Ă@}b93"@c 9@Kӥ|;Ǣ31}?sG3sE5[f?Idѯ!!|9.+đQ,A:yn-Q3'<| ,!( uus2*C4` lz+6 `|U?s Q\N_5T$;+ xHP65z&)c  ]r\@ؿ7`ndD޷1oQ4⍸w~I'ewr #QuOGŋ"N; Oµ1 W;UV*qM^2xV+96W 9(9$eة=ژN ;8۬O13b\]652h25**4titpA+^c4?N[T[-W~|jЕ:'b2=E5bZ (]gJ6CpbU,U! d i~9 j b)YTy`1&RD*Z{v``ek:%"#n;qv8J25ȮFjߕr2^b#*yͥ\ ψ(nS8i$- ]2T0kT`RV*r'XjTԨP8s!Yod(Y=]9~<"J!P`#/<]$4JtbΌًe>º̄/*Y0fL`0ꇱ0v {U 29]AusK0ɄіʰO0H/OODt*Ja~*jrb;sR?!x7QOo y&jSU#[AhVXKNL APcfFfaڵPK4 2([5йa61 .‹_tic|A?R jY^]* ]9C:'CEry%*h )Y8? /4Jr $Po?k2)[ۆ[0|ɞnhLC]vv*Fq̖4FFuĠSAp,d }^4-0ئJ&FjF44SŠ3vo`:~󊓒{t8FjAΛkU݃**졂XY5QEjQ =tBT_euMp/EYҳ%aJZM}T:˟}, iQ|mm5$?(~B#JjU6\:ši`9z1*cCu΂w,1x=5!Gֹndd7>ѧ,K=zdM2?wXUTmfgV'jl\͇ԋ fCLfFwz i-G],J9ivKyoWn! ?rg_'>?:.I]R@ՅO?+NW TrM`G_"yK Q,Rx? r\×c|ZGСqo$ų=@0Wm.XLoH׺ZNX1)9 Bua]Wu#":?v?"f>Y[O\^9k/^w'*tܘ*Zė̜C3(/){P2&!Qn Dz{BhZ j2AS c7+@(s+ CTA,VqV6:X:CV4 @ł09~ZW5p=RM)"bKmGwwo<8ԓ*Ղ>6{H`|PU: *org/mockito/cglib/core/ClassGenerator.javaeAo0 DNmAw[N^n =2%M(AC'%wJf~ =Bj_k?{U OZqC'V?^:x7A0Je8:q=ك"DHݙxC^\pU}){o%0 cm=i]ygբs`wOG. cIQ2l+Dck^'M T*3$~)܄YZ@V{Zd? 0&<+j}Br%$y4Ahȅ{u X:pJ"=pq;y˦22K[UWp-L_rG[ ~c*' |TAsQqs[zp/?PK )w:qk&org/mockito/cglib/core/ClassInfo.classQMo@}8 )%I TB!UpZg-_7"q@pBG!fm@h۝yo_ҡ{"_X'q`z?bKXbz7O:G:C>N )nϜ vO7qz6C#t{J-Y?fb:^p>E'g~PK kN:#Sg^%org/mockito/cglib/core/ClassInfo.javaSMo@W 99USL HuJU!Yj5iߙI4_{ogN`bڕU;/VHzdKaM =p$jP-禾2huYt !}i03tЈhsHAj|zPiZ -/6,s<&Z* N5_ 8^.(zuM:fWoINX)KdIZ,XEyòVy>A)V?Jm'(7adfxdi6btav76ӫ f0M/y:5$N/GOe$SqXl$f+ɵ(U$YU'*@hx_ ,Vp/}Bq@9?2%5F>*o"Y*8e? DZ9E'ic@ւN o(9})Rk-w&^* yp:_/_jkX=?&ܘiFh*EYKp/JjQÛGy>ttA +Յ3Fz}}䌝/[LLᡟϨ?d4<4l_9-&@hv9ӡm㈥zۘ@:PK )w:ME!-.org/mockito/cglib/core/ClassNameReader$1.classT[OA=B[(VDrYbAc&#HMiepKf K|0.U3gϞ~~>CUUZ/VՖ*a.VyM ^j,o1 Us֒ݫ]_(A;; c  _Ege͔FmYK͝+T qtaVWg]_C4W3$Z뾴͒CdQ:ҿÐKeѻ*4͖Ao7H2ǺN?BrNgIf!hBLx͝0m-SN.2J r`Gp)a2+ A^0 dX>YW11De P2N;wz#(,rQ``"i9vtMS:ܯ+]V8*YmQCA_Neݺ\Ii'̓$Zm uDݺ}?8z][8B隅ZMD$p 7 ݥ ݱ;&> Fnљq(d@8B7}P]toޢo*a&'dxEI1`#0Fc{GL~4MIp&qLB5n:F75<,iX{3$Aʑ~~Lq[FX$$.w!NDPK )w:GtƲL?org/mockito/cglib/core/ClassNameReader$EarlyExitException.classPMK@}~jU RR**oӥ&Y٤R'?%NҀE/vǛ@ sW=9u\x/Ƃτ>p 2,]I` sg"鋵|y\pm"ChfƵ;&62Cٚ(ö&C>!Co+ΚY^kb' vv"W3A*{%z.6 hON#֭ZhW\رo@褩qLAJy!#,߰dUl+&#rI]B#%WU0%ǿ]Ԩt U$VL`RPK )w: ,org/mockito/cglib/core/ClassNameReader.classTOP=o{Ta*m((!3Y21B\`RgkM[ |+hT6]w=rXfR׆g+Z4f;b5]VߪZ5iu[<0Ciqa3TQu̽w5gG!q:ΐ3 ʕg |2%p:).J!2\!;Q5;2Z[obcX%0{2.㊄pL>a3LeqԽR%$ apih7-.A 3Rs&:0vN 1jf.0pˢFO՜V L )rs(d-5Km2]n*73ðLjM +hf0Sf*te^ Ee[SM1ԪoCoٰ՝zUwn8dY']0 EA)LD %Ez .!AĸWlC@8˳1o (~d4% :ydA7!{&G?a="O&ߐ~`axyk8}1/s2C ~"wbiB/.Z> sgǪ ȵj<1wІH]xgzc7O|bPK kN:_lz+org/mockito/cglib/core/ClassNameReader.javaTMs6Wl}1娔&E遱WʈrRǓ%X]COq}.F\,vg+_`B O$Se Z"aKA6nxBcd@9 #*Mk`b1v5ہJ5Cs'js9 M!"t~0i\5p2=~7;˷m=F:Wnkc2xwn$O`57.6c7&Gw3 /)i/CMjP9%=UW<$nU=;@CS ~ڎrTT4S (2WWs=N^q X^>*xwslQbfQmAº}+;PK )w:f +org/mockito/cglib/core/ClassesKey$Key.classMA 0mE (٣ JkM_| ٙz0E00EFpi̥),UR8 M)Y189 HXB:/uY -a8ڭ[f_lͱj-Zjw4r -𵛈 @3PK )w:'org/mockito/cglib/core/ClassesKey.classo0?6֭](h"oJJT0꼥 xxBdEE=>>9;oPf䎵8Vv(PCWh#]/Q$ưpp7-d*I楸Y`R`uv~倡_ioB?!D Fs PE 뗓0ǒnϷnrP]B5r(QC!\C Nmd(n`*"I[X29}<_s(c^R0h$5}B뢚>:euNG{5YY>7OW|1f잞!;*Y8{a(jP's8n'vS ]1e6hfFs~O(`F, hOM[K@N)ڧX|8GqQ ifEH@jgK'٦5RtKVBPK G:N(&org/mockito/cglib/core/ClassesKey.javaeQo0)NQVh hMXMX[VjU YN t:;aycv$ 47&a#iNS}K3x 7pŋ D>dM%-<) ͌[n뇗"^!djɲa%B^QKr509J5 <ӡI_U>/+\ii+F{y=j-^%0׆ӎHV /(K6[ cNd*\#U~/:`29Zi֑NҢ.۹;Im, r||0Y7|xWg+ɠv8:, ?mɷsMPK )w:(ٸ .org/mockito/cglib/core/CodeEmitter$State.classT[OAv,w+ QRErL \5limwO7_|Ī2ٮ*69gwΜ?\]3e~)%خ3_+ )7%-u0&׹wNe9ya[ߣ# .chK+F暁g[}e(Eǒ2wNGP_Ψ:QrmY(\2t6?uB`|A8B.14') <;a/X+D?Naw#?k~ŀ9YEbМbLjUCp-{hlNf>*s5\RĂHiR "C"h#{V9¬Ӊ Ҷ$<$G3k y3?#.%CA*Cv׏~h ~Lnn}30y x5"{wBTFddrKN +DSPK )w:j8a>#T(org/mockito/cglib/core/CodeEmitter.class\ `Tf&l^BB @ r !`@ Kd7n oQ&DQzVmU޶}3o_6džȾ73o}wͼ~"&46j*n 6G M5  YhtBl4x|aaLͷ %`RBc5bjž}JkxՎìOya?oX Vu:v ݤ4(mJćf5[A{س5GkY -E=Sy )%`z׵._ECx y7b ++YjAjuAWNo]k4&P;d6ɘI7ҰVA'\a[$C*Un5CiLt(t ln5ycIg ʁ k Ⴖ@I񨰷v΢&2vEIh~ul֛t7H9R,`\mt{-tڥ4X-pmhS9KLB:>p5]FWѵP(KqFHmR`h"Oh PF$ ]va[Kke ʄM1fnJ_hkFT]v֟bV )qݘ[ԫzOBͲ?nXYV)x9eĕ&Vc(Tּv })6ia]]JeZ>[>cA2ťb vTre2U&% SY 4 |l,[ycHy r6НRZbbB]r!Om<AK6-m.BlBa]b-()xr8J6 J-pPZx% v˰!hzԅJL)H~Q&w#&ֱ 9ޏ_O/L g|`ՋC}'y K.xO 3 e|7*ҬeմKbݽo -_wI[ 87m@K7= r@5G:R̼BZ̼24?nheA@sS|mGz6)u(x2[v9}n. ﮬ:6s%[7f:uRLk#a%֫]9n0Z?E+\®R|vXFfҀ,U O=}5ކXQD$hA]2q6 ytmJ.h#ҥ%H=-qL2[WDf ,В,hi G jD7܀ 99Eku$G=x9v''q$AE NFZjV L9"9vg&b?fi.5GL9L0(Q?'Gq+8*I W:#]9F9D<"'nz;'ɛ;+gUPWTk y% u&BgLnf/+9 1IR ?=NuX>o),>KLµ\a?u,0ƚ dB,f}5`(y[8)Eg7 }qJfBP>&gQ=*Mhm b>X٨ ~,ߵ|xVv*g(R$L5򸝂|E3ĺXKh8 &\<硞Wh cPW!qOOD0> uw\݃zQ\}2SŨOOC}z\PgC$~8~GБryTܤNMw25s ZBKTUe ƥ`PX *Ku$FyjYOi`)Z fJ@anO'2TyJ'$hDIt C5"QO-E1Ҹ3uS(ɪd\ӭ)n1>SqZka4k|Hq&~:т( ^u=d{>^ yC:݆Ýq]ju.xf+C-}I{ڋ-nS,6p偒 I?{3:w.){$@uC[zEC7Ѝե=Wb>W\> e@e0,j JF[t#w${nuG"gHb«dhZfҝTqe> ގg krw=yXz"ld|gKidɁJG~IR5AY8˟ϓhLPN)YtSIg]v% '*o~c%{^#!u:^cUP5ASDLumUG:iǢKL," QTb'OD Ȣ[JTE>vreSo+q0GQz%U@U\-khTz%7 Vݠv7V{/;;vQvcwΦ}FǨ8ZSzZ8aҳ"yO/1L/)8 | ~miZ 81-\3{9q}3Ʊx׷` M\b 0V׸c1\Kq1x>!zGXpkͅ/ȱFzNp-~(IvЍ\DNt.Q/J!o "GH>F;ȟ gx9&G${_"㿴'}5ts齦 _%yr ȌYdA Ro{ha 1jEAqow Š*ȜL;S8D`?!?c#=z)Ctw;h~Q}k^CW!ݺj-KUqQTbGA0wK]7OuHGut5fg7Nnޠ@ v˭ڭWXv#wZ֍yVkQjVsV,/>;@D }"VKU_d`cI;5 D5IE /RY(,] tM1"CE1U1y/~$Fb/ D#fL!X6I$O"`ϓirȪ{0@m^mҿ="ߒQygަEW6:XkVuH/̞ZBoYhnξD%!"4 1tZ|Dq8O_O(`mNj+v]uf1bibN1Ol4ViXL.rC̏=cBJMXƟ5)m\8Qj;~c,Msg#N'lfy_-:ZI#qX@fzVhLs% J`1Uvy:.+U[)ئ73+V#9QXK::DAkmpTX1A v&K},<7]Nt[Vwz 9rƯ oRZ1 vQqo 19g&sF$dKnvODk$}j cL+K%Ԏ'zO FO q gxqagLq.IFb~#gc1wdvo;r:38g?:rB(N l K/nd7C1*.jjH'JY:ACteR"&h e@`S"%?U p5qE`q|牊noTOl?ө^4uXiyHw).ꩶ6x| B V@^lhGɤ6 v;zυr:|^hBy,h,5=G<6*n"S*M7q`qm?7 mw! C C`V=i$4; ^h@Ǐ'0<wIO1x* #.O><>Ѹ-iNCGH>b gA9O""/K rODyD^eɾSY">t\GTܻW?;r UW%&l҃hs~w0]#iļF㼏}8l}CuX{,imߞqŻ`>vYjyT7H jå%J'F/<0ρTB%pBEct(ճ⹨Vˢ-m62}&G|x-^%N0VZk`shx+,)|^)ؚR>?}"G*QP@#@N[JwovgBL;Bw0& D{31,~e1;&`!2ge>ɑWEjd109Jۭ~ou;%W+WM2,[teҐ׵o)' YHCFKo.yQ;*9x3J*w!P,LU}Oع`, ơSGv.gk:<:-'9 ξ9^gMCЬ}:7C).y-/0)-SvrQݞPSy=2]f(NApa_=/ͭ(_by/zc#N#热e>vG娙uM쿙>/I%NON2/IIqb%#R$'LW+ױGb$oa.ONtdDΜ\Gk,FEuON\WNf븃sͨtsun^YlBx$+6!f!Spi>lˠ"u;vȖ(O#a5K%}4N:!4GRL d y!Ct kd~&ꐧ^y*=)OqMA3 y}+Ϧ"I'"K^ EҿX@ r*/Ǽz-81;Ͻ;+o;J{6cc*媅`EqVu<Ք-uwO3xY|?ڍo"x+UYYU]D^='qnBފȾu1#[%ᆚije;ZmYfe%d9tOTӃfyP>x?+_x-Yc}Ժr9vsXd~hX3[;Ѷ<Ҋr"!Er7 Q!;A8;"[W4#2 e F&M4LG4E!,N8ie=.ֵҪǟ+OsgD%4Ν[asiQyy;eʻ7`=EQR0u2ih*5 K82bctdj418ߣ4~p_c*8֯kܓ:nrsz"(mٰ?i ulG9:n"sv92#(83)ߘEc4ޘCnc.G 'XRka4ߘ5/-{(o^,j{-ߢ,kɅ3EQӨtc!6G:hQ abŻg&!:/ppH4#wڍv1O{E\3bq6B:'Ƚ*+;~ ;[(J3SFK!Zve,*cC_|1ۨ|^W43N#?b}XN|t|A)[> l*-SS pz|IΖ#_{PϖopAhcIaK2`4JcGi<D:&w}]7#ٟ80RPK kN:+Yi'org/mockito/cglib/core/CodeEmitter.java=]w6hvD?Kn+˲V\KvS̚"$em ,d |`f0x cnSr|2PLe@cF΢md{,L؂ o: @>iaxdMId0'd/ۤ7OC?t$.(qD7)6kV$4͸6M7os܍^ &{a0U$!1֏7n-} QL*f.Op! YI7TZ$]r!yٛ%9M"u8{7_{l8%OƧp2_g7H~O;̀d .)c Hl/}t*gq-" Dk?Ƒۅ^H;?*o^/(NovH+٦~eY&kjW֏tB;~Fӄ qtWP" G 6\^)  E i죢)@+=MAVr6[0'hϯ{9~!LoaWЖqꭗ7Q0P{M-kyG'׻lLɻ1h&4,?vq:: SYD[nFެ1eє ͉!: ˫l>\4/xQz#^37< ;=%DŽC0MC(8x5!xD  ! ,^ PP q:!b<8!r^jȸF#xQ3|VMadj&A `T065_ /d9{4'3$%1lju6hg0.2ȾK9,(Sσ((+A⯊b>k38nN˄%0A jؒɎ\GgcVZF" Lq50djf{UENP~2:n OޒZS`biO-n G_@ޡMhe*@>Z@ 2SeL_1P:i(#f>\\Z+c2fG޽=2Nlm:JP2EGvk?08&o'BV-m%^opowbMO1L( B ;ǺquBcrt6?3SU JM '̊,9o-Y|Ew.4HXsfC7g 1\EרjCY濜*R3w3 "ϊ>sޣ_~[[rܰo2Z&B[p6||8/?:u4 C0t *Ea D7z3 UV٤#kI%eu26[058)tS%jh5AZz米iJ#%)|N6(q8^ey ọ [&&fH6ҫ}-6na*Q"ZeXŨBHI#)^.hq[ˋOAХrےm0;E7W#QxRnjJA+# ]qIZd/kE!`K ewC}C.RP%i@7W?\-.іf,ܑy!(kd1FL(0eAj&ڴԑ0֋ɅuDC+b[IN*A Áa= ڇ]ԅa쒦֙hןb)pٽ 1||g"=0 VC,5;I n$4M#脄̂(};۰]цos-S2u $e'lr9V }&x> gv [GF7/cf_mvt4<Qiޥ84S6߽$M2$ `f1p4"4pwWYfs %"Sx=>VP>%Y<Q^[l*gc 'Dc䦱#>%E(*#P-WC>5*h_g߭&?F;(mTvjV'gO𤱜yœhx  zX w'6dZo{f7GW)Ň7Vm#ۅ)vl PmL;;yL8&)IqօdE P*TYȤiVpR ={w9$(΢RߜTKW [ _DzQVo",ė̖ĺnn2tC8q6Kј* AݠsLŹgq҇EgAboLΚL)pI"sʼnɟ>; jiĒxJ[,X=QwuJn @~çe5E.B[E'(}Rސ? gd^䇂 A%ŝA ]ɥy)<&)#%4XdhO[%SE[?;5>_yv.a O۝Umᒪmr@e]WAsV #ʮ#y}@V}.riemՁ]8DV?匢nQL;M b *bթ9U:hK)t8i C ^a=@Z0E*)9-1(Gs.PG-o8g!uH;k4X Z`Ɓ u@H6BYڟ|>dK,Q𭼇 b`9M|rMԀ!ptuYPaQ>}CX׶iF?D34(0)9vFtRܝz,W6;2cb|xW{v ['BYڒ=96~.bZXJL,:#Rl4ݞ#7Df2GRn|UT\D@v8 <$i#_[pٯ5+V{%XSVjnuL=)—z_O0_[+DѓBgAoR1Q-vJ'ļ%ʔvu,<cDv$J` Xѣs2۔ލ:3'(,C/ ۳ۍŤLʎs@ȉ!@ >a Hf"*|~UطŌk@f;[y lJlzV;?oA}®nj`H8ҘSDrüh T 6ʡHNk2q%aS-d7=̚$.|$-u7;eK$_&rX{WR5rVo3Mŷ4)n`N~Y<͸9ڣs+u!#avD8h\wD;/*wi5sԽ\QF\UW3sv)|};G: 4 $*XSXiZY-0|PK )w:xs4org/mockito/cglib/core/CodeGenerationException.classSn@=\:-%m(KPHǍ[;, @(؎HJ/3s̜<%<6NiَꙖKsWҕhah BL#\|ȩ aV#,ڙsd\֫3+j]ByrqʵGK_NTk]:BXI+԰H(2wDNIm*J:LXR*Ac"+W?tF$$IR PK G:R*3org/mockito/cglib/core/CodeGenerationException.javauSQo0~WPB nT(]uA"tU^;R4 }w0SNlca<^j0-_ֶfFU2eV(I.Gi02ZCC5u{Wc*(P$ a`-r|XZ*\0ja7Mw-J,#wF%ǎ쁵[kIut{_܅yu/s44hqٜՠ4L#٬rk-YLIZ$=Q@j?v ݘ40—i}n+x.hcX,aUtu4<\jWNOLb kdJb-8&eڢT a\_ LL. a0~Y.+WNpHyYNh0Su>o6Oe- 7C0h2z?*Nv=*0dQWR-H/D=g4D3k125~v8z=X^Aw0ԥ_OR빷.>D\.h+-O_:PK )w:τ ,org/mockito/cglib/core/CollectionUtils.classT]S[U]'_PZϐ~UZ*Uћnsś3"q|s?A\HΘ;{>k_GWQd/M#[LOY)a8Y N<7sj N &džA #jTb٣E\5_XօPƾs걭++&}Wgu3<+4j8F.nÑX@_lӌgz"8^5"9<#xgHO54|_YuusaHiXAmÜDž&4\&tVGb ;5*EQ.B}JiE9"_+PmyRnfU"II͙pgZSM޻p]R uy'hT冴+=kl^d0(Mʤ,TSnixAV5TvBnЊa2aGٲ`uG6]C]M+Ǫ xBX\6hz M{-q84C<ڳܵmE]+gmL58L}XFͥR5ugjۍ:{S̕sȢjaɋJ ,U n?Xy\mCϙSB4rg /ژ6L!8/';>Wow0nD+5e9N.IZ‰x }s DK>>x?3hFXpÏ!u~̇/wO~ M>' ܋b0[ BpMyw61w`SGo*8sΪLσ &9NqKqYǴL3wjMz)$ݔg˝ȍ*~?B՘#Lg=H(- |[05 vbaA Qv f,7v3!ms\PK G:{ߤM +org/mockito/cglib/core/CollectionUtils.javaUnF}WL abe+Kִ[pdmW~AJύH\!n<MXɴ@ ur*n) V=ȼՈD VA$PE`E`u -]9q>Т/lYEܕ1E19SXE{iZ^hZ 1-J*d9MB8\K|&MK!|Y!8]&\ 7*}YF{#Kgm%vwYoi߿Y4g9Jw*xdwsJC^N8J>!<*KKN<1t 8Y<ɟKQ1!!oߞTiW PK )w:qso, &org/mockito/cglib/core/Constants.classUwd@6@eET\h&v&˜Ni`&L.;;Ux<7}XЇ$e RzQ,XnR jQڏ8N1v-F"f_ZIS`EE,oDHPg:!;_Ptٲ iyQ}.Rv}!*0sL2OcLh -ۚ"V*by%߉j!蠑 Fꀪ:\o٦smM199rZ5-Ȧؔ HzKj=\?:c%LЍ@K a6Ry[SԬz)v4Fd?q g E$(N#(X>V "LtYAmXi_,8|XzDx@N`T͏M8u~ D )OD98*c%9{Y"^%wdsXogp'LRwtsۤݢWq"|@` 9/26Uu95?*zNEx"|N`ן'V0@l79f[;;8{}"ޡ[]DcUENn_a\\ OJ|ϦM~.w!b+t=H qYWŸ:ĸ6ƮŸ> 1nqScqK[cwĸ3g](_$߈rI M(6($ߎM(k._U:HnAU`H],Hy!aX\%cxT0 Vc G` g(5oHo1|[z҇ ?>a/~+} 3r8VVrm'qp'/#ۋڏG&#Ʀ^8il )> I899{<"26D_Y[PK kN: zi %org/mockito/cglib/core/Constants.javaW]S8}ϯNݝYcfll(ؖW n^9&!sϽ.w=x6/7++ fIZAWł( h x, *@}53 84ͱdWPIL’e}BKeHPX3iX 1m8\\NPhB A*zmZE:ȶksmǏ_PjRdTJ yRQlFTPS\^ Xl< &`J=qA$7#p>XfFƍ$3 M?v8ӟŸ?>:ɴtQQD’o%ɒ&l H+RHF%9:.4Mr zA'Lq#I367.IPO̍xS:IVC!,)˳~NX|:72?:>)7@!)4;>Go0<<@?盅} oUs,̼bIX{E|ZP&|A%|l1CP H38Wtf{ft֧p_iN4  ƒ(6c׆hb4J"$}\׿lI ?;ղfhOhw3>秄8t݄"2vzwvg1 ̑8H:6Cӎw0 g~yFIэkL,iqnLZk./2N: 6i7׏v]Ү~G l,cd4nuڨ>+=0O܍)kҹ,t_Ƞ~aU#vLd%EV\vNrf_sۚ6*˩Sww0hUV4ְ7RѼ#{$l7NcۻMn1g;™o^o`}wXw+Tr`'7zXRHw/vdpXcwmϚ) e/0G؍c\;V]-o3،9x%$=ݓPK )w:L$C&org/mockito/cglib/core/Converter.class;o>CNFt̒|$T}Ԣ"vFFIJDļt}vfF>"=<#{2DS]5sNbq5ML!FҢT̜T6F&`dad`c`8$+PK G:%org/mockito/cglib/core/Converter.javaeRn0 +"4Ō-zHD (R"#aiSgY,v;Wنmovi=@MH=)3'A:&]U,M٧ۈq= e hCF@=~3e°5+)W$j. Auk Ðqj}u!{(Z}GaWO^$'PNhiU N `=֣Fڃ'&!LFT3I~Y )*yy.׏[x7 X˻b[K!/_GQ3GIO܍U(4Rp!-L۫o(@!5]@<G_W%kӃկ6mGu$q}-~uQ52R"ĭ럨Y;>_MzeD+"/J,' PK )w:l='org/mockito/cglib/core/Customizer.classu1 @Dǘ6.J,6f]l=P)D,by^;9/]ڈdOomt!@6"B/PK kN:H4&org/mockito/cglib/core/Customizer.javaeRn@#+5'8*j%C,vC[;jr-3{o'L<{ {)-v<+pk'*&k1pGMTY JWpu8 FucA:Uc ڎn e4L?9aVҮԽog3Y6sSlx ]ޔ注>̀!ǟy@9U#b5zRceϞLpJ0S3"MXUQ-#cQvyY ;Xo˛.n!/GQ,%3G"bë?H웤PSGZ~R=Bo_qH!kmh$>.GW%s䑤gb~&u,C]1.VH,z lG%~'R_,/ֶōh~ X^xPK )w:Όl[ 3org/mockito/cglib/core/DebuggingClassWriter$1.classV[WU$$LPzE ВЛ 􆆋BSjar!'(Z{߭ԥI%o>g?'ߙ EJf朽'o:Ng-ctHaòe&f*ћ31tpRO%ƒp|htW3v!Gh-ôxܼ9\U}`#ߋxI%SԷG+hlG_[宜 !xWͭ?Eh]O8áEq$Q?w9}sf%~y]5`UWN*V"'ަ_;x '$m|1>Z§LUY4k_ @#pxDԶ*hKh T W7tAm7ڂSg:ET٬D 3}{ޏ̿~8zL5X1+1]Of&JRJ6j;KO{]U3;RM7 }xih8:1=u4S/Lߝ53;yk~Q QRF3T2sGQj \-i.phK {)'cŖe$a*FUפנ, D8EBGd*#.FzHzݪYtXpvs5 h\d0W5qBq|G'::88z ~֥W rf1&Ϫ8_HàW-?l!5,Aor U@6J4y^ '5ib*ﹶC(nٲbS8n>}=qIG,Yk`pz#lN (qdSe&erlF M,eUQ^ H/q(ol1'Ol{P͞wF͗U 3,1+>,IVnJiYSNUBp춒[vY|Q5HI Sb*;=?dw񵚈5CF u菠[卻RВ$nC&z[}ȝiǙ\S 31>`3~:~<]-;=bP\ٴiXU77D0:5߁뮍UԢ)Y8y5pîS.ZpR-}np{,%7+YWWr9.H/ k8/U֎<-դUQ/ ynvm-~}HR8Fǁ,9\4~R#]&Tol2;>mLg mgCS$ a?P)RрR!,.1 `FafUcqm38YTi c|1*c83L(]Kr.UL{u6MB'a^&sL?=×/lbL2MT6QM/P} z)MYQLsu< a[4 p-v-5cECh ?ӢaPK kN: 0org/mockito/cglib/core/DebuggingClassWriter.javaWߏ9 ~C˅U{OnN*3!0K2Pt?{~T:?؟ώj+dgTrm>~ aȀmAxx!1Y!<c 4FN>do-x.ڝ>ct kX;H-T0qb:rO"K}'I]ABUEe\{n"ڄ(׵p4~KqւRe(e2S܂6 C45ʩ8-d(?u'ARUM`x4 |<Я0|?Ǔ. qF~Gb8 S1ț!yH6@-U@a*CPoĔ$hr]-`H˚bGqiwH";ٗv- %u> :S`IY1GF +ZJRJ +=iR/Dxao{+(,sPC2ػ}a:p>>MGO/9 vjF:,Q %E_'?c` ,\cҮMpr%6Yk{4{N4:O,:#(E~xqp3zӆgM33,Yk_l9(D3)*큂 VWFoq˜9}/uG2ee~VEh go1߭eWTdyN讘|ARҥEQC*0p8TKL"Rnz7]7Z%*S9%%M9d+T?S:q2ABzά l*qC;20FN`Z'h^G N݉AFP("=B\xgGA;?9ESLZרٰPdS\:jyWJy(czb$F 򸫒Pܬp:اO2ÎXK?Kl)?CS3B#]d\LSD.].^{탻E࠙U*rBoo h|97s=Y׊nϦJbyH,(XRR<mRY̒&P,S/eR{y 6ڞåKa\7T<&V,Ԯ:f3Пlck<etU^d=}0W?C؟K?PK )w:щ5org/mockito/cglib/core/DefaultGeneratorStrategy.classkOQYmE l[d ^&hHM ]vl* cR$qζs:y3_l[7,u x&̲C>}O᚞m* +7A]h'6 :aq"kˎ`ՠ"" ;%$AkY**K| ߋ:a&pB9Y*gzѧBA?!ʽҁ [bA BiLK)q:>QaR]DrG1 F.i=IB*WBE0*0W# vX6aŦeg^KGoZm;}NQ]* ,f$-7Z:)WӐ@2ɷE-5,bGBצ㉭r G?Kog{_1[Dg}lQ2-m| *  f+ׁP޲1QHg542{()&y c/v;N{Zb"s @Sp{נMCx6{hL u eKPlj?'4PK kN:VX|`4org/mockito/cglib/core/DefaultGeneratorStrategy.javaSN@+F9:ފz0!Vp(EUU7 {DYiLQǞ7o{;8''oaF+!5!\,ik!h<. M]e _yF0Jã5bC{X%VڀeUha$BiXqq؜7TANu8kd4M$ZőujRl~rLgi6{êw]@Z;o@T,K@(\#d7N6j K0,'󚞥M$,Ɓ.Y|..E2`~yz,yo)I/ƀ,S[IBWZ5jΰ#Еڇ{,ph ]jjÿMCᤣM6y$óeYG—ѴqT92| \h .#~ڴDC^ tD>rF4[t`s7 Kͧ? ~jQko'HuQ9x-[̃lxB} 5W3k#vo"3vN4pP}WaݸmnyP;ί?.f?!]{݇ ;k'H4PK )w:KTȂ0org/mockito/cglib/core/DefaultNamingPolicy.classTrF=/)`m!1v(1_.6i(]i$yf ÌCaqޕT GWw9ܻkyϒNlVl:(_g_EǶM a.6 ͻ” a3[R z|QP* 9k ln@I`0dU{-bIDU`$(]ѲL.E%a`Va%.7K8M߀A(CғܕMKvF䟻m` 84e$ƕ2,cb( i*&qL1MQۤl2@"la!kݖXX⳵\@3*Ðkz!(m"-N˼msNSNuNK#A_ rպR(_QFҹ.6vE>9ɏ\͝.sG G5k\E̓0>wDFb`H \SzOln?~!ޥ{0 n4GtR)-(ʻFzm^2U=gSt #qڧZieeխh֚ #%-pbI+FRkdoӪLoFx~ {Od >gz~d>`V 2fP*Uə>>yW#}LljzSTL0RS[>ν8Og3Z:Nj qBfT{>+@?O}gXjƯn:EX8bv8KĶW%ORStv 8NЏ@".A SW*Mt]WtlO~ p9nwGjPK G:f3w/org/mockito/cglib/core/DefaultNamingPolicy.javauUaOH_1@ΡU Z(pzNglqv5Bu)Ԋxw͛~ar݀naD"Ln- ¥nB8eq"\pOIEc)C9 궢1chAiE Y!} ׫Bk=J?: =w%T<6Z:Wu"h2K/2^x:9OgtBO0|H{6\є'.xBJ\2TوwhU5WK Sɕte]ateR:YV:e%I zDK?ŝH'$CG} TjM·l߈*na4'Dƕ3*4iт+&_uR:?$vޅZY;|pчoO>?}ح慼 36$f΄MdR4$`#xO|y֤drP#`mHKaL3HF彥N.>eBa&q v1ɞ~w9֎:#bC;GO%_ž{ މfHCg)bxԃ'L1j{CG BsvrwN6pgvš9^ vd*By~l65<PK )w:@0org/mockito/cglib/core/DuplicatesPredicate.classR]OA=~h+" j6< @06ݽCNwUH@I(Ý-Ixw9s;ϏVIIIujQb(|dJwE *Ύ Gt e=9#b+7RmJ R= ]&=(_0A.=FҮlݾQ6C3ֿ=7=pn'tݐ~Y/2-_6*l\ L]G<->6<{\%1Y,ޕFɶ}mem2o;LDJ;|/9_g[E3c*8E1JG|͙9Cwpu^#@kUhֹnr 0sXtXmH8q+;rl| PK G:Q/org/mockito/cglib/core/DuplicatesPredicate.javaeSn0 + `/IQc3eڒ+q>q%IȲrp\~C\O sp;s'",@4>@cdXB ['Ld'AO"qH M`@*ikɕ@襫:# O#tNnDڟʹ[}iS9׆z/zP5Z _;irvޒ,3[^^vo\;yriY箺vI?'P߸IBNG“<Ƈ>J6ֻd]B['' [k)}?1"^I(YmQB ʎ>QZ4~枦tr}Ba@}~Pݽk;CaqðZR[!Cg4w͑ A*xPD ]T̓hkJ-3jc裆&C eЙEÂi fhoayiEy5H:uBhc7Ih+)WcrżfAR ɮ-c(`f2n6@i{ι0i9vC7@kl',.-` ]~u{+HEA?+"l~e:EEØ+܆Ïvd6!@Q;BBQK02jZm$q3ޕOһaphr)Nлb{vaϙDP F2%\,QfT~;D3lKծRQY>F}W]]@\WI$0̵;95 Fl(яk0¢ba\*fDa[‬.iuH,4q;}:*4,bWxQRIyT1;~L,Ǜ cQD3s4/zάvorg6o8bS.r0mO%l;mq`vr晎ڞB&=OCb4 RV(ȩ?)ӳh!F+Ǹ%yDkrL2]2|uW11dhVaz)?q~_H#~ܡj)=D?4eIra1 =NPT<=5VC@aW PK )w:Aw)org/mockito/cglib/core/EmitUtils$11.classRKo@6uC[Jo#-HR(zvEu[p)TqG!N`qؙMO XؑSns#^jYV-vj6f18e'Ԡ]vdLc|.C󜫜WT`鈫n$/Pb//XzܑM$^2FJgnrZ}7M(e"sԈ"=b6I3' wI&N\*-zsvIW ŧ\> :ֱA2c ,Pc,w PK )w:zaH,)org/mockito/cglib/core/EmitUtils$12.classTYSPnJXmYBqCE2 s.mh0I򳜡n3or<7yܜ}g9{q3NFzlMϘFZmGhɼ-{ Cɭ6alf95 Ò2E>-Ug\ sS8 "OkBRx™HLK7Q s\Ϣ+*BgNlwx^PȥmJOA{PͰ`M =]ss27*dNUC׳b!^ \B"P$Xgh?n^K0"' 2|<퇓՞SR! f98S.hA.hY]QqRUqRSYҮ2TE$C!T#Pe }'cغpwi#Y9o= ]lzm)ah8ogFx 54NMe qLPITNl3 սf[޲+r˟nJI9 ҈d%3t !ipMP*ât-׷-Ȏe6]+ښƐr׵v $b{"000yuk`! #W=ʷ[Cn;B ([Q}Z2T8 RٽwcGUy r~sMkxG8qpy;  D<1dST}¡37'Ʋu*9LgdI(H*CJdȰtlmɨ?φag!*fqXv}wTJFlFzjz=y,L`~9ǒY,3QK$ml@#zbjIO<0D-⡌7=Cu2d'PX@t'hq Rl4gɆnp7hG#oPy /}QW}B1#}wVX 2it"ZSP Vo*TڌTPK )w:4Њ)org/mockito/cglib/core/EmitUtils$14.classTSWYجXE@-@ ,Q*j۴iԹY.aeٽ3Flq+@nRtR̽sη_ a.ζ+)ynvPع+WĚs?}x_8RGD 0pD-?tWζS*"att2E(ﶄW!B l!T)¹BJɹV>CniyYC+*f/ z|̈́$}wt#.*Vm!#M/C'R̝ GbK:̑dЕdoA_F ʛ ?^E+vAY}8N'#ЯNMƀ:>fhKC7]nTJy:u]-HM'b?uPK )w:;mN)org/mockito/cglib/core/EmitUtils$15.classT[OA-,-J"ʥ`[hL4%M`N ٝbWH<}l+aCxؙ39? âLdzLe˦iy0^+irct17m̗͎8BDb;[8 s50u۶hSïB="x@ Zv ʬ@Ubz4Ie7m7u<+sGP] cySؑR5Habfרgu cnUO._!a`5 JH+$bȥŤn0 2)$p!2`XE]a[J0 _fֿS\ϫX%n謇Ҟ@8<")K1:B`PK )w:gA)org/mockito/cglib/core/EmitUtils$16.classUYSA&1x'!APWk ɚnjw"^>߱DNSț힮>gחrxpfͳL%|aj|!m'H50W57+aI QLV.[rASkbxF1]c`+^znڮ-o38.)>U¡>DpV0+뜎#8:Ḳ.8.iYi'qJYhJ:l ]d#妉x,y*N?%fJ2 .D]ڞ CwapdK^똉nнp!-:93561w˴ey|Zb75~i(eocIu$E<>QJWx<ܷy+ꡮ튧 l{b-{ 0ZnyAȊG\Wy0E0ІZiBM+jZP:zi'JrgVb/ #Ĩ1Ęm"i$7MDOК{HOP.ʑ^ QhpT*kؠ|lpIqA2 w usa44V$l#h$YQtd6UކǻзѪ8x4baG9&{<PK )w:l)(org/mockito/cglib/core/EmitUtils$2.classTNP] r8P.E3tt@:P %m5~KL #>1ùtw:ggzVji[p=lYظи蚭;F aL#5/>c=vF76%T1 DP+~B'U.%CDì dD;dM y,QCObaŠwaD$E3ÝUI˱)W!{"jeؔ1ӭC}-*pZAŮSA Z^ʸkC1Du?T3Kt;_Iݧꊧrch)soHdh*H97'aSyj#21Pw%{ tiO%6)ǥ(5ej"V2Ⱥ!:"}^oxqCF-&H&RD2ʱ|W+SJ4.kY;(bP(.݄. #*o32%oNLڥ\=K|IL-g2+XZݬgY+q 镙K└p/i}QG@Q(*>\Õj>\[ŊJmh{@մC9t9t#9tzԎ]ސOR4+I80/,_i8y ܗd:E' ?څW*5BS7}(Pb7a!L ҆[MbPYQwObi+"09z[${nYu0P͌I}%M,KxvV rC֤cF\G{'<w;e8P.x: 3d"}Nc),0<{Ǣ"ePdv(U_5/51Imk.hl7K[e@byeMIJvgͷ--s1kj,3Ց9ӿ蛖-1骥l.7| QuNs{}7feucVBCˏ""CHhbXi€U.ãt3ECyB9 U YԜVmoJF =JK,=UC44I 4ΐ1ݨeUr{a};U|Cm7Ҵ*^0-͈CJ KF[m Y^h[elm ѴD_1( 1GUYbGEHku2^꩑/cK0-4JIHZmwaEM$#3VSկC}n8 om J8BINQ1AQgXK@Da $Mh0-S8 QT&C"fYfh f#ة,I= I\Pc1b9ZuJwM=oIxi.NkwpJGw6,ǣI8@˚ms7k=d @W* IȶN$A AHDi%NQ.6EHnWT:بtѭ$ce(Ɇ2RJ^%)V#B_Y J1yKA%r,@"5:_bו]ġ^cx67nӷ16GDj H]ę(KXVZ³1I SU ,!RFq h=z}H5Dt;hM% dG ǥ)(R끧Af hPK )w:}D!(org/mockito/cglib/core/EmitUtils$5.classR]o0=WPQ|ԁD T RIɼěK;0 $~? quν(| 6INNA*6"ؙHJUz` i&>P_5gv>XahL EE2,_0l ? ("uq^ah$kKS3uL F˛>z3swƿCF]+f =U-[&{ "4)JPlLfNS] *ѣj3vQwٸbEI#l^N|@d$ fǵu3vYř%̆SUִ&;@ĪNulwBFABp^13E5aK)o1FB&֝^H\(*N5B`%]-M'͜&T|4d4im?{Qxa=aYp P2QvhB풱lmY76,2'|V;3,78|sdUJ\R[BSe!iZV%DI8Yv0AGشy 0z©M]oqG8+R=::c$)("cKx VAqcZ "URQ7 }P,NlpTKRAxu2b*^hj7;G2 ^mA 5K8BXZR,j *u࿄ usڍ Fzԋw9(ŗ[*< Tӯ-EP$gy6 /PK )w:%(org/mockito/cglib/core/EmitUtils$7.classS]OA=JʇjW|*&b_t`b2YԄjޛsgo<a+~Fe+?T"ũAXɴ>*Jq,˜'L/tXA/`D{+AT[cHHYbݿ0" óm4 ;f.O(Be؛*&Ps)/ |auGx>Im]|Sb%[]s%[rUYuyliO'?b/}ߨ@)azڄbv-œ"'/qz&,")L[Zt:ҡz9:*8A,3CiD*EG*n$*CAj7B[U^9mSbae# &NoM߄b+nH OmcS-ȭ^דz"_Ss3uP&2jh2FG 2'z%F`Q6 `֩QrVwXt]ek31+>>]Ry>;\T:F Lt78pZ>c Z*,+kc-P}PK )w:Q(org/mockito/cglib/core/EmitUtils$9.classU]OA=- TSP"IEB OtnmWO4}Gg>sgιN^VE昊ZѵSUv4ݎ,@i*:5*>S| e̶-fz@AYI` 褵3vKciF}4˘L`f~vU)X b^{0DdcV؎n$=N T0U6w ώ'E32cW`Lо&xwlKݻ;2zqKC#EOCci_t=WBi%guVeC0b;! L2I+Q/z!YA,Iz|(=C<.$sJ0sW{?É +H0)W%cC w AofT(noVsAȘ|xҒcNƼ(h:uKL)JJ3+54˩S QR(8R}Z-(&5mԫef5-YTܟ6sLNmHw>|ݢsWs_E#k.'0?`|Czg,so*"-y f*OHi O0~iOOxC§!byZ+.)#-bXZ¸Y@~<kī6PK )w:9%6org/mockito/cglib/core/EmitUtils$ArrayDelimiters.classRn@=3q&4mMY$n BE "(~Ni[~  >BܙD-H>9_&COc~ԋUGrgͧZd"uVcEw#ejg;ϰ?2J m`(f;vs#$S-c ֿT]BuqU8ZǬKh΅;Pѡ:(Yּ ۭSǩԛ8[4DZ0Q|yU鉎2"IފE $CO%k?jÄޢ,͌} \!B]HQ;׿^5SPt PK )w:SG)d&org/mockito/cglib/core/EmitUtils.class| `T& !$a_â!  $ (aH0ɄqQQ\Q Vbk][k7[}.߹d2ͼY~g=>,MQeC uऺFIuoRI?"olqowwR70bF_]AJPzlD~.h6¾Pf_A)Xk]0n+5 TA}u :Lq՛qSޛqԯ7;(7f8h@otތ7ACz3n }|9OvЈ^ F{5*9W1@h%W rEQum2H,*Cn S…e%KFR4SV--(F;d²*A}0|qmYI%+hIaema5XTQi/Y\VWԖU`jQYEa5wW}3 aeJʋc.;}f25w9(VT(*dV.-^RQ,(dQ2~RVTOM$>BO  +-*%"AI ch.(I_ Cj6hZQbGńA2k624 [TN.ZJ|[j7Pe[TBPB}kE3ƠjUwuAg!|5…&_ *f[onmـKN)FshV 9!?wct7ɢ{M}BRSdfЭAVCj*nRo3(rTpW\X@dX%' HDע:aSl?n=7A0U~+2O(4̜nLX]jAb0[] gEsY,zeZ!GU1Bdd#Co6[$EO8N}뽭aK41Naͷڍ9 sf%F]ﻡwiw7cQ5~1 6eu5[b&]ʥ8LXɣt}@-,Qg1ϢiJht^iBWy2E!X$d@=;n>a]wYb&MV"yq&x.KCT qƫO-rQ&*PEnQ*Yeib5H4ZqB k@L^ RռVc! ;fˬ>zb6i_&W(cq O-)Dq& i;tV@NEXql7 ׏ nBo6#St\q&.XW,Mî\AVtsӜwb 87؞lQ@`H\$vpl8zԫCe!S7qv/^\Sʊb}zĕ.p69cS22X,q.-xDiVUYFf"q,Lˏw^o / 7Yb8܊kjm}Zi}ro$IX8:;w]M76t\,q2ڸ4tNq >Z>qAă!&gE~_c}| oQc ]3-Yr!OOڹTLQ%ͭ> ψ5x9@l`4)MOo>Ƙ6Cu'XzE|EI]C|ˢx,^!_[QoLQKkl#(3uBOS87[.'ۢbR>\WPs-h d\1S7K$??w;c3}, \EZ[f_q%,xgxYa*oKOs^0i!dF;UVJKո ſߍL?wC8%gPb1'mt/,.)*]ZXfIGlNԭ<_$/Hn&J*WW@|=7WiBާP(w6@}%~$m"ԛ3a|Ԑ22tE!=T&cAh)c׶w^x!\@y'Nbvpي b6mYrnyJ=ħ}R2 ĵ W,ZlKo\v^hQihihi]jӺܢyu%bcR̜@(3ZrKDNy->h.inMkz߱d,͝Ϛ<ْ{ͮ,eR7ݢM]MRK*A,aWL>K/<{h|;]U_1F>&yMgJK>ȈEFnT 8) ᱢ}_f h5bLm'w7Ycy[ψd)*+%Z=;/A~ubK:gQooQ|FG8Xh*9=`ϒoe;LЋ'*c':~D+UF7,z͊x aP˕wA/ߴ|)w J`%(΋ƪ0)'L.K 9Z[2^n Ec_w_~:l>.mGB_CMXɯp(emd^B#gLo!f_0m%?s/GwKY&b$>y[E0O8'R]4AHW$.'Ta%]Nl.%P9%? q'wz>8zWA[BpAvactvLаcs~LӐ2DKWxsؿMT@A}뼜_Xj *7ZkNP}dU,FXsEe352*ѐ:&v!@vQZn~Je.DrCި֩{d]/??6d<& /Z–.)N1ծUՖ,]V]c !haz;f!sV RRsRjQ {u2htuv˭lǃ=of BXY=}KPp,kJ~?_PՒTH{W=~eԥT90 @j\Q^]䌢eե喪2vXTVVTZj>]oE嘉r(z/s[!yZ#(EeCxP{KZ]>w'.&I<u2L៩3όISNʧJY+:ŏ3;f%t5if/L&:]T e1dۇ Nu"&.6w\gKu`6r~)}% eOa8O{5 Tc!{}00dnAùޟ]l2  FȻ WKa\@eYFAC=٦׹A{`H%U i@[AuOY0x|{, < BOmM`]2!ʌ ((g5X 呗,,ps~3/۩|zH>:ǸG\R_E4)ү13w+!?Ďe~.WsfJ*-44پEh uZu}l_שu}n_gיu}m_:׾γz}=žꫛܸNTBB=iHɞ;jǯe:i o߉NӧQ* @5Ǔ+"|i^VgFh]mP#n umQ tAfڂQI'*oZFh9 JIU4i<=[iMOaJz\ DlE v!ajzc7B)=5N(Vc? ͆b`ve]Ui"tcA2no)Hѿ;)BzTq's=wJ'?B%mc34BOy<\Wv@ $ر Eo:F Cv+I9(;D5vѯ]dD@`C 9L}kɞ|A Q 6OD;$&0lKϕ1>Wjw˅(bܝ&rJsH*iW&NcV48wN)pbmDU}!Аh5D# 4UlyHf6d\4'|s][%?3 / kd%$iLKrQ:LO7=ܱ{N19&&,tjQ&C颀bx\@)0T~B0s[wCi{ŽqgFrfp\m `TѾNdx ٝɱxpϰwu:hx\%#]s&0T#^/A'C_CMq_<`e_Z^BD)e0ԥDSUbim.+[G`7OTr#Fx'"U>{ 0G !~ϻ&n`};@(/lq5"V r8F(Gji/tMeȾ]^rdW< }E ̖># 3/F 9Sl!Os%Ao6\q8f{'󜗖eX|w<E]ͨSBׄjY4RI'ThF82q+I32(Y,W{ix>Qx;y @I*ƙşLu`UZ=5T?ߩㇹ+j-$$bȽa$f^\O,cG`RV )cpӾ<.* \mhy2"ϊ%3;z:KH6Gy k 6onM)r>s11`OL{l|z5_Gow~?IO;F _{K!tT%>Cb9?RئE :W*D&52nNH Yc󗠅2[lqVo^kSS>zNWdG6PCއ)}".2$1LYL[lM,byX"|Q#Zypwc6;*I* NP;ٗ~r7to1ȗ 7{19Nʐ y)$/L]= M^SF.#M UbS.q¥;K 1&Ǹ,?Xܒt+3X)q_^ M:6ˇPrbnWî]8ݎC jfjV]ԝrSR#OhYư?֞ڙ:5V钊qҰ3U}N>$?SFN93Ute>753 PvPmGh`= Ӆ^1CiNhN uL[K`#5Q;堂zSdq"I*Ӥ~JQ4Q94*S p,BK"64_J\'muO$c1qyL>LbyLhɯX,nPNTH_PhJbL*VzVF۔EcKU_E?ݮ2Irӛj}O ATS5Z5V$q"MYjp+r25#ұqU4ӮEԐ܈4/qۮFF(܏ǫjjN Uls* 5y4DͧN99jM=ϧjp͎VwT.WwO=SA7ȱԤ xzCw6 K5C6Fxл2Jj!9UTW ՕL iZ Tq;CM]XMJMl,Lt^yP\v]}A u\7]\ QyUP5WRt=}v*,㔏=n-\jIM$&w ԩvm9MS4GUA^TVRH-L:_*K 9#W(]FUYM^H:*8dzT%#JR3 `q&30:LLJ~2R Y{ t츸D= chFX_B،nbu \Oj5krg|Ui:ƪU+ʹDmjΡ<j;{>{P;./et. []Im*rhX;tyrs#C ^ .\qYc vk\gXvgAzlt &!~ozYt8ܡk-Ɏj#s RA~;׹+;] oFc8 "-#` i{'Ct/bt&Rvå tF;v?{^7XMO\&xdgb]1%oWAң#=Tۺ1 c(HQ P[Q I^!CmTrCT;:%ˏ3egg+tO}Jdd]qrF7T1 2 1'SݤeuLW7.TuLun\Ѝ2՝qY[77wf{uLզ&S=TT>.5 VEpLD2h$ Q49M>E@O'$ٽ<9xDq'V'6>zq[Z6 tgo$W֙?} }>y;gzSA̗tftt^ o'w;$eԲah5fI_pԝ .^&IǺ8+) })r  Pb>XJ\BlDLN$F6p7Ć@lb;Q1?<  y7^ϧGj/7`:xhڀf9ѿGAb7sNx{=DbwI * ݰuQܐԻjKꋋbCn#`@md\!23+?H!Izo6i`(;0ĩO|Jx/@,^O癳&8s@O[$`#͞a9IY}^ĴO8;̽8.] /T>PҟRv9wsZ=c׉ &Cr-EȂ/&J0KOۨO`~Mjcnvľ"K KrSeF?{`.pظnGh0Lע]0e%On7,WpbB2>e<)}zKr+[vlpp^{63oZ/qҒ 8nӄM"/#eOԒbܰ) 0Ub0E| LghȇΤ$SGhBI/UMEiiק<-J~L$i <;δAZ2~Cn"KՍLU% W(EJMTFc+' L 2_s|Q_]-u4 u8j+^/lr PB[?%s^gN׹5HCX(] @w|Zt @Z~"$|36)->-H~7A2I.9IִrFt_+'D>:0>a(6djّQ{vvq؞;/~TS&R&/(CCH}3eN3ܙZԔ*U,qZ$--\\@͛P>j|*J+%[q`/pJA;d.ےl(OW!U)2oɡp'')O[~k שiL;ΘЎSj" :۶?;؜69_ݾYsLO - TL Eel9"nl#ͬUvbw#$Yۘ<kROR85s<&xaxW;''l}u܎K0A|`SI}fh'a{+O 8:J}*bl;=]bL"0 P甁6$t.<1m2:#߉{=`> |Y|`n<`מɩ!0څ6k._,|޺@zo3iUsoS^_PXAe+Xa!ZN6?t'ew8O<4s9t5')=t5wæBT 6:P,-DJ̹z+G^("4cA*Nh3,W8}/R8Gۙ7 iPr)@L[Z_7B8jdsى|ŵ <y|l*2%A.acu8eKl +4)l+DK^KܙTށc5j0PtJgDRqTܫG`j.T\xnmz6xwnoWYInPdwgkP:dy!{wo9d7 __sGT sw0/9c<;=(jtTL,Qp'?UKCPx'vMw%o 'z(װ4RP]ְaЖ2fˇ2H{g6WPe&$wϋUIi3JS/{U `bHh)׾Ou[)q0NZXtFҪh̉63-=fdz.p.P9 WdKmž_S6ȻFPZt? =33# g4&]{9s'wC~ asZk"eusߢ' S`Wk$+ŭFY[a ޹_^~;{E^8w/At=PD !uf <Ӭ[Z 0fLe[`_D|4Sm|ྔtƋFuoh#A a2׍Dcqi'LxsǾzKJDQ-`@ޣ_~lsGW- wq>0q. Oc(tY@E^@ iU 澶zt'7/MJ f|܍CI9J6 :ٓԠs"}aCxFL)\ pv[;7CDz~0k儈!%{Sp(k@a]KlPΎETc隤Iv1GADYKDp=?\=5qsdE3pA3R>7t43>X +BBV&W\%+|3f ?P3@UHMqK23JQbPYEhAI|HH#RcZ`[& 5BӒT]GB}TtLQf$ dBw8 sP-5ڑ卓6JC1 1C \}K©8i%}g҃,Ogo ?Kl.jJ)ƦHڝhwAbogE AD4~pT[2P S t=$tTk5z1&-,*|da PZőRr岕g` p`T!ke=XaV'K .ij|1*|ya8p 5St0z8ZSI `M)a'a5Nה P$ z 陉SZ+"F%MgƗ!0ڋԑ*3slQ [8Pr %Iˋ&]tP G.n5؏+HOMZyɃp;.ͺNu6!t)ީlPlB-sh oiJۦS#$"nAsXP*Rmœ ]V~RLKyՙ\ 9Z!E$17(ꅎ2$%,tJ-p UI%𘂛Yb.~rw5р?EP,=HUC<ǩRdhmY<`qTd=`A$b\'X9W/>+֥JefW+bv<@#s} !3?!3^QkW mI~k! oUdTȒ8RvBZ ׈LQʔ-+@+M0aZYox(aMĽqaO'Ay$GԀb.CEw4zSi*;@?X`-ηԪPjp4*UTYͧZ^$YN0"jaJY2Zӏ:K~_aNZs-6d*k󑯙i UGL JI7R~芤q_-Q3d.&J cʖW&]UZIN2՚JTjk$Q@%tH5Ǎ=E9=/) 6yv-U:kT$̖ȿ9Gy,˒G9^`uEJU&U&'[g+oaɷ:Q 3˔ZA}c݊+~~n.v7cebOOz &>؟ome.e&Udjψ)|! ZWqM8TQ(MgLh k͕V~C  , vCfBN5 QHQNc!h"S7iK#DR-9T6.d6x~Ḃښ[Z>.yM"MzSM*QZ\UcEl%!NUﹷBioŒKv[AXcᩐ'),x|&a &?Is#0foC綌&p"<[ن%k{t_r-BjDtC} z5PK G:֜@Z-org/mockito/cglib/core/GeneratorStrategy.javaUQo6~8/iIAA\'݌6+auPFRQ"wMdǏ}9Xm7:U7\^ a I ۛRe 3QI4K t=4,tN9l:{1FC+F06@0Ji|Pm; MgB˄a (\Ёު ̚?M/y> C&"̺:)7'b=d4z镣DG(XvH{2L?)8'$)0pfW~ 7vyuw6{z6-} ,I3;Mzb#Pl;RR3u/j>3tZ幮 UB4_/H{!{l&kLZo"J{'mWA'u@w9geՏ=SZ+sk-?b<1U-{#|YGZu %8Q'*I" ȸhv0'Gha %Ctqd窭(\p;cjAiM d$_87X^&].%vNQCK@[ MιdU9p+aO jꊀ/h7f.dϘP6o]w‰$W1IVx4Cd5?؏-j>.?ޙr*x1Veu59;xZz; x,-8Ee%a`ԫ,jԥșQBQN+6oBtn۸;TxB\&i6U7ᾍ :!>fF'wqlqw iNN*~[Jt|ي]CUבb7u?JHݗ#<dXEexWI6\zv$;,s#Xd\byr WG|3m}N#xWD)aW*IM{>&sϰ,')PK )w:cH)org/mockito/cglib/core/KeyFactory$2.classROA^+ EZHkELhlMY5&5>G玚Ƅrٙݙng~ >[ X Di3<@31A$Ap?#l̠7X}a_𐰤>2n("BzOO|ύv3 e(`/PK )w:i 1org/mockito/cglib/core/KeyFactory$Generator.classX |Si\CVLR (-uoB^&7`:٦1u :t*jځN7onttS~޼Hn~{sqgXHё`طF 6 GՆNŧՐU"/@t0G-bY$Ei /RG} V&ݭ6 4 IGPWZ V4UFՀ+j4fP;*9BңWu-ubaEh\%PB#  }j߾1I/JH'E@j!M_B(r;Pr;$EXjJY# ݯet,sDa5t!!]ksŁǞ9b E@ eQK,+zYN,"q gc~n-v+yB#8H(l*!کlBBCHfjfN=Z-5hBplYfrԙSXb)lHw:p,0DCMzHf=BGb 8a~zj-Y3(UC4.A;G Bk1MDpr!Qp+GFVYЊ0KT[!vѱPtgS6o(z<31}bB1ډ8I JsbszJ\ r,B9ÐA0}2@@QK#;N] l@[U*V52K qcYD9٦B(Q)P)\ d‘I:D@43AEc-UqDZ:NNMYXS Ne8w†oteM)|&ΒqҚ %%X ̀w{<H~&_?C,F}Fv.YId|ɘMsj#!ͱĝ7_|mt!/R"nfAqI8rr힋@hCDDԶlK XuR*\X1jJݞYm!5 p y-+~JWΏX0H[Sbzu,\({S x`L҈oˆb'(7Ygfo!7 o|{ᮜ4+޾ϊe:;;z3 u?طΛ\E5KK >9|T_UBndɨv0FVC5/8k^E})/N ѹtUW%4B)xmqj4ODDIup+&%bʨcs"Eh;Gk sv=;Ȥ9xəCgh/1UB̺z2e1>2q,j۪ŵwm+erS O𝞎vo KGjV䨙O \a|]5Bq67$xhQV_[ -f?/ @Ք'|aBꊸ+NMpxB<Sc}/C9Iƛoƛel+-_ͼN.݄cM9^gb60ּ]a +ecX0VHbͬZShI}a=s55Za\{ VމeP-[KY-?VǮ\9Xrb''/"n]@ѝ6+fZeHuRCX5<=&v6 ԍ[X}ǭ _)[(_=6^cbK}Kmn1Pdҝ[έq8.-j.,@ \&px\g|5ۜ6e8Y8mM x2Ӕ:mcXc;\V-1L`zm|ؼ[KV )_.t*JP?N% rLeP!]&v$)43=b*NG;9c9X`|̃rKi* h]JڋüL:GlQ:ޜ*'JTŴX-\ڇS`;F*hTLZ,c <>vt*pa˜)V@V3[k0JN:SX̏V_9v#"G^ǤOpVg_8[ۻBs~yRaozxˍ.!Å~O7E\~lC@)i=Ry, "m9R&KzNutNǢdJA?YL:k"=!QH^:8pazX[!nZaq3O!~CČ1n{ -6b'WDu z.G Fv뎰kU n^GmYVt} U"K^Cfqh6VhZZ锬:<w }pg[B}1iì\^* $)ëV6WZV&w>I ;tZOHɕV:HwL<ѵc<逸ٵy~zH,`xZZ in5ky戹AzƃWuL:4O1L=kj u-|b-} cjo}2wY%DYlb%vufD.zḊL~N>Lh2=ߎ.Ho:]V @P!tSQa ق`%%K.XD6_sd5 ypyPPjmٟXia3||- j>]8y:C`kXA7ښQgi*^pw.F>]uգDO)r0z2 Adk1@6(pwd9Y? V85Ys 7<.2C" `"0g|Xp쑒_ͳ;Lj VE.^imo⑥4Gh+}l@IP"' P_X+fx(F0B?jLJ@M5&% V^cPBhski KC7 $qɐ %>rjhM&>q<9}>D^⍏rpVŜg^8MA4  <.K =2t1w _s"# $e&J D+YCXSѩ5(H+rG>7ΜsE ~jVJЉ!e}%UW} f5)5Nب; V*2P\Re>fix9,Xi UFGu"⹐P} " 4QuHVxy9- DѯE5>z!RVI~|}=6r{ˠ?A\j-*tiT,ܱɇnBDѯEv+ lĢ 0n!U}v ΪBquw˪>HSA[knpQu (/wkEIU8 yJ`lT);9X*>h S{VdEJiW!C1ӼS 9)? [fb(ߞ⹏/OAIqN.f2Yw`%]X 3;ܥEPeA2j0@?\YV|n#·-\}EemO1ُ;QXVCrυa!7I0]((Qj KYnd/]0JXőg8.Ncyx UN.o>7@K Yw\ä]2wj & {cjn2W:O.q15TeC|p/c'_4D,Mӫn/!*z)/1x \.ҹ\k*^>)mz WK!zVXS|rAD_1=]9l97ו08 ~)GH;I)͡2\˗EΝO-=+{)$O FW{NN] G#@0B<1nȩMӢM7Q(6V9_NN<CI7 Vg9Caj~|j㧅3 bB'4>nØopYAV!2$+X#E( !/Q$T*<8&DJ.:v-CG:VoGm7D% c|& 9jk BLA=7wySocޔ6_GkŰ' ¿:\/ʎ8g7#ñO'IvЎ|gp'_p ^gʒmRPPN/9ʂ(9eTg0(#X󃊏JU4c@5׿5_¦VUz2\oI,|bos./ `PlKWD^)דPK )w:#ce"org/mockito/cglib/core/Local.classPJPۤ 7mkō .,Iz?P.?J<-*9's̙!6ZQ[ȻIdy~ \ˋbnّy0йs }r/CaФ 1-g?͜Đ3.CX"9ah>uh5X֑C : (JzZ>|tgȖ"ĵvi4 !]N,7ʶdxh$8v)J7CX" ղ?ElNa<˅lUKmR XA&Jhfj5_`<~3rn$Mڂӿ{-~PK kN:!org/mockito/cglib/core/Local.javamRMo@W8(5%D@¤Q`V1u ;cC0J}ct7U˪VE,(Xƅ+\}9ZFmSP kAK,u7izy:XiD%:arޛ1I x4gT2指Cx(^G?PK )w:%3org/mockito/cglib/core/LocalVariablesSorter$1.classMj@ScSzMt7Cf}č}zJW{0{7ON9Amj+FVc#aన VNN۞P`DX_N ;F e#uLx~Ip#aË1rȐ#LfxcEJJmJPK )w:hs7org/mockito/cglib/core/LocalVariablesSorter$State.classRMK@}ӯ1X~<UD E^4EhxA(N 'B%ApX }/ \PNA |2Fa@` q qT*>#dk2l9ZUBs\|"a'zZZf3y,ݬ*";ʗa_ F+ϕ ߗaQ$#l /Lc&d@XZ]{7_0~X@:P1 &Zו<-TZ C5U!!?bFc}%QhȣLPK )w:6O•\ 1org/mockito/cglib/core/LocalVariablesSorter.classV[wUݧiH!PEQ)TrZN!L̴`| k)/<ȋkA w]>G}LCKڇo{䷿~ `+>XsJ]Zaj]R*V0* 2F*;Ps< Cd>0jWk=ELBo>iK{dk[d3<3]m"',/-q@.˶dz>ɩbإϱRw\8 8 8%S4[̏W/9ٲ m⋅hME`< fjؼj>>6UGL'8 Ɯyy6}uMkY\R7brsm]/j:[h3Xu7;5nkIhu zR}y;x kZ\6Gy}AW3'xsRa=2 ]brmPMiR;,@/W<]Gyڎ=@8!egBeqSLEkB"lԙԒz.H1()SWT9={|whrz\+g%SnCI=n,?'8\d6umxL\?2(-uxu[/kNWə7()Eɭᤪ4IFӔ5$jV%s{/] Dy=p_} |>?|,3Y'J"ئ7sz2Ns>{ 7,{3pccӘLM4ޙf7o!E5b9"Vi4?>#I }IX_3.ַ;{_a@JgQ@‹ PK kN:K80org/mockito/cglib/core/LocalVariablesSorter.javaX]s}ϯ;;x} {'جmMMn [ P!NolmHfa`ӧOZbNLx \n@%,Lwf0<" Kr\d)L%Ks&˖)fZa.ξ_v<4F4 $W\yq2y<*b~Jq)l%F&"eHwD,9dRgP,Sj0ae"GZDY8q,Y Z%F-a.` +!?}+O7k<@!Uߊi J,ؿϞ98%ײwQO.4S@H .{lQ]C呬;5IB^B 8#HFJ+N@LYUߖWܞʢًN npQc!znUc|yms4[]gҤ,eJ-w)&uy[WP){ \WA Qx߫e)9o1?~ MozN̞uqg,ַA%K֧qHy>)?ףPK )w: 'org/mockito/cglib/core/MethodInfo.classQMo@}8 |I[;X1KRz:[oߐ\ uG,y{3;3| w2Us} @C5؏Uaᄿnȣ}?P;gCCv,Q€`C04{su@{!O}ghοd3V:Py,Ed/؟:2x:SXjT4*:|{*(߆M˓c/Wci]TynaUPWu Xb `Ϥ '=56QLU?e0,S粩k-mJX'W>x,Cmh='Sq'2FZ1? m= dG\@vZS'LKFuv+U2aekbzytZRq;}ha3ܘ*Nye}[k7 jaФ-8zv>ГKOc]z?WJ?PK lN:5~&org/mockito/cglib/core/MethodInfo.javaTn@SN&v%DFQz=6ۘ]ww]UpXϛ}%: LX{8;=5´FX+SLxe45p\+aT@ U8 O!`+ Gؚ6b xr$Vi6Uv%dä^\PCEU:iB*-ruu-Vp?.V<-̖x/>Nj1 eFSeT'fmx bOBnv\RJ5]Ԣ@(OAv#Ӕj|;o_Q47F>*oBY* 8 HWnN}-j[qH):!=TuJd  +k7_s'K+|KTv_нoZg |S&ϥ6g M-2/U/Z$t$t"Ъ C *6gnV 8::mdv<s&k42L\mN^ECC'QGbzr0Guca1ӪU[IZR"u4RG 2;H;A.̝sh(Q Zp{ǵi @(#ݠ[:rD$BO u|{bXP PK G:,1org/mockito/cglib/core/MethodInfoTransformer.javaTn@+F>QS㨨) i&.]LY QK9ؙy͛avQ8=R]kݨ-sB+*5p#8*[p/ECdX0Bӳ8*v4 CX(D'몖) xc:wVj휫mۆSjSek7rϤTu$Z 4PXM8Id-h4H1'T9;8q:#ƽr$z'oL4J!N=JtA6h,^r\YN~ <#|d 'n;RW K5rQNa%Bhu5JX?WKFJn9۾<|B>?zr:4N"6LH6؞54XH.<`d6pɨ_vzBg)K+ 0:F왣JN+'N,J+ Z5XegA̷>^b0lp' CZ>^8mDuBڐdgYOgqPK )w:OPS;org/mockito/cglib/core/MethodWrapper$MethodWrapperKey.classNn@el("eHRHAu+cp(3 7l;;+oۨmPyY,2Ŝڬ؎n{)JsܰrڄFy(@!֕Z1!BEj2e*(Jo=f^ʪwizCy಻3PK )w:̑Gg *org/mockito/cglib/core/MethodWrapper.classUVW7D&Lb)u%TEH Eea53T W۵Z.9|uI$$kc=9g}9俏= A)O%Y~*ZB`̻+姗(;2"q>C_SP/ 2N@zbtص̢hq<'*bgFDъ *d dJFJ`*VE cT{;Π f+,>)v(pE t `Ś {ۢ CuNxΔ܉74pX U!BSV=fM-rGqf&4_xI@ L{ٸFҳ3am@Ұ*q& j\ +V*euJ/t|KLGFuT 7eB&tv60ppXV@:^%0GwWO+2Rϣf#~J*\f[p]fЁν8A25gCd(q  GjtR,KF5ViBx{ۭ\M`L)3/pof:e8-te%W闦xjj}u7l1gVcd=OqZ$86JD=q\w7o|gFc|t}C ?L 0J}qϡ p^$^ ʰ!\4n:CopطӛYOט{6psS ,C5Ʒ4nǴ f`aṣsgce,Z{A0-mzbnd56p=*ֲ,X?NޡnLރߕvTb $YJ.Hl!7`!˲7NmAɴN/pN$ ߤQ IzGi6_Nop;Fyrt,' ]hrWlHQ|,W@25Ym^x aiIDZQi&dt*Z{'zC=m]h#19-V z!ux,)8p,Pf'UЅP[G! O=u TS4\FW|:^3%먘 u[Q 9>$&oSR*:[hgČwm%{GVVWo?=97D)55 h^R:@m~As*gSZ*jnMoxw7Y 1LHsY3H743~&D3pEĽ{1%ŝ#mϲ!]g8u-KWiy*A>~p+'n^@,6} cj@iPK )w:Ѹ/)org/mockito/cglib/core/NamingPolicy.class} 1EZ_~6-+Q.Q,?Jb :ss\ohkwjgJ[ <ܛ^:k%:[yʃl*$(ܨ@mabe`x7yُϖ7F[C$mN 5r'xj,%TPLHh$EPK G:@(org/mockito/cglib/core/NamingPolicy.javaUMoFW t 2[QjH4qI(. od, qgg{f8%-LZyzu}mvLFIM23.צCw:qA8`KR2:ܠW5M$`/n$GkTK#vTꊉsn$edzΡysup\U"R^)աM=3Ȩrӿ`c]e*v=g[*liK_G☈B>@3FTTI7@ԏ+GU'0};J@jOM?^Rz/;l)WjUG%ȏ m{niMsrG4 K&(kɌؑۙPB%fV?J7\%jFFun rL.^C1O1gNZ]E{%}o[?1Uꑪ,qIJ˜=R},X4Pwݔ8 A4U|՟_0&2;/[҈<|Q vd _8W'&Gp۠!,8(a6-&̋vRzEoh>G0>3]$ ?BKE. ʹ2B'gṓaPK lN:57>0org/mockito/cglib/core/ObjectSwitchCallback.javamRAn0 VTA2`9 rD$(.e";3;3dr=,9Yjϰ? FHW6$Q9h#]&319L`rMA{ ;d rPSoR ugZJ" 㞋J4^. O{ uK qmgK6rOzR-:d9ryaؖ%mڂh,`{I53pNE[*{$gބIZ@VLkZd,*uŐHQe;0\V`@ȝl˓v4bF b ܑF W4G} JWpsh:j: c@Ѡ-1mד2a">*ix5lJҕ89oAusMӔ._sCvW7e(U㯑\A9U-f{5:cmOL0: T٤6A)Z*ey(_{xw ;Xo˛b_lK9B^>·Y 3/ &E؜U,Rp%-nTBgBkMi >=\Q秨#'bꮧ:uѷJ]@ `Fĭ(DY\_l럨5IPK )w:JT\1org/mockito/cglib/core/ProcessArrayCallback.classm1 @DǘzEpJPP7OHɆMr5  ރyO+ b[Β*M)NY86&Ҝ $w.buR:D0/;0.lg$nUW4Wloe |t! m{PK lN:K0org/mockito/cglib/core/ProcessArrayCallback.javaeRn0+>+9 RHQ+ydI*P߻Q(;;3:kX;;nV/Pr+$*ӅI8{3V2bgۇ`f4M8(N3uCޔ3>w=jރ_#9 ,˒aJL`!cDٓ@_?%yZQ3"MhXUQ-#sQ>vyY ;Xo˻.%!/_GQ-93E,b«/$t([ԑdkEЛ7tE7Y`i e y8t0IeIqx$,˸p ?l#jdž`N.tF91R $>(PH^?_PK )w:2org/mockito/cglib/core/ProcessSwitchCallback.classmJBAѣ$^ Z@~0VWWήyP agg=w*Fot0+5o ai| ٹeW3ްq,k1S9k] p3x^0c.=N ?*ZqF<;]$459R!_W#Mh CFzIeNN˚EPK lN:/;1org/mockito/cglib/core/ProcessSwitchCallback.javamRAn0 VTAra9 rD$(.e";3;3dr=,9Yjϰ? FHW6$Q9h#]&319L`rMA{ ;d rPSoR ugZJ" 㞋J4^. O{ uK qmgK6rOzR-:d9ryaؖ%mڂh,`{I53pNE[*{$gބIZ@VLkZd,* ,zo yPK )w:9u+org/mockito/cglib/core/ReflectUtils$2.classT[S@ )TP~) EiA4"N)K WM=oϷw#XeNAkQmW ϴܞQnO?UK 93Iˍczu<0-^y3>QXArʴMo<>EeyЯ]B2!gǩm]7#%QwSbch?ʈl]ޮ504A ?(!4-3U43(;.$ʜdq'2Tis)t0m-(IzWl(衫ȭ{A>W &-<.gI 7,0]@j\ M49@M}o!wݞQIW c$*ZWf=C?k(j\KXsۢ|N"(vQ29ucouO\bI10*uIdߩGbiЭM1V2mX"YQt dJw6,!bAwieq?*^7ZJ;b5 ђ7PK }ס$'Y}X1jC7c\(֝U|@6W)W%6=zx:4i_1:(Ai7很ƓE%YD?0I*I!M<-M1j}fh5BS3Ui9J Y'&{PK )w:C9+org/mockito/cglib/core/ReflectUtils$3.classTNQ]ZfQ.E2 $ĤIAa8:!3S_a&&&&~؈>jGN()Фgڷ71L\\ݴlQMSos3x,)` M<8pξ4uqd0L^"6N5=قTmñt"V…H!f fuΐ<2L)0<;"=/3<"}I-,'U`>/VDW;b=6}6В&G!yS*mdN lצ,`aY 2hH17m 0(E:I;0,r!|Ơ%`fm4|y2s=I+uv^r枟~I1/f,~K[*'倪RrN”.KS66ߑCwA8|,SG[LD Ǵ]RYQp/)q8YZ7#bh%!!B?m-k3 h FFѩ0d*aoxEhKk1)O1[tLB ia#mķЗ:ֆ>ЩP#4?ҹňc, OtƝ?ck`~ VT%)$PK )w: d?+org/mockito/cglib/core/ReflectUtils$4.classS]OP~ξu2`|Ŕ!]bM /drUםjג#D$L=kcd&}{yz~S`Xuܾ6pOhF2;\{{7iy՝,C%o״{NISa?da+ǰfv?Өnˢ!#ݞnp>Q&j1CY&QAU V!fN)ԕ`\R2jP%(8]gr)c"ڹtc֑zmaiAxCg9>~mvNb5mܸ-`UT3h-+͗N0 Fw e>¬>œ1‚zO`Lhތs0hzٯtd+xwCr ;'% K4Pb;[\$vƨ4%jcNēPK )w:]{N8)org/mockito/cglib/core/ReflectUtils.classZ xT>rg&  ,L6ea J*LI2:3knժUk]Jm/6KSV][kvm{{gf2H=s쿿tiEKHuWo(YzB`(3\ý[:/+lLtUB´d,/9M3trMtNie DxpO Ɣݢt:GXO$ڏ3=P%D洤Lb l6ܺ~WcK}{;< aԐzs [oּuWӖͭL%ƆXk0nF"`f6nlinVxn8$ox4sU0a]!;giI4l%RvDm\K3 믖]4w*[t*)e;ZbZ䡅B^niL.kJY^:Ty5F@/βx ɪ㶾hrg(`A]K`@.( <)g$ #eO$UkX"nd–xs"c7)DIebzM U{:HfWoFOSY}4CwK333xqi[vxt_K#b+?dx}Bš =$tCuEri(B]f ;xx B?O0u.!*f52L?)SafӥHfRD/1Ldti'1%Eoc{CݪDFQ-gM`ץ^0vycA9TYgt8NO ȝ1,MV8py3 ?KJO:jS7qC۶uۮ[;0(ҰaN_&gim!'.嘩i:ܧQ.Y7dj#,^&Д-a`Z有T,T&R A ː)1O^/9hy.$[KwxB o.DYkT Syy@l0&h@22(AT!"4#.#X"$`.@4 "/W^1guY;C9' :P(d#l0$^|B4c=dg̶zDmQ*O BZ<FƲIuc aEePMt,c_D̆{K,0XbtN.(*<~#ۢ@48M3ȮNOu;vLVkuV)E'dsRRm daD>M(m xq2hlIKv[v xBt}/-xD5L'Dn Nx:iɜZ J/ȱ(_.BS/a]8YNX!NO~h^*eS 4 C̙yfJn^$ʣD82!ZhO,jatFbƷP I4dm.L=Ϟ,TkKlWW%F:_mdi~OhsCw2[؃Jbɴ 1-j9@+>ʝwB/PQ?"8PZD1>JSL&US**=ycqWtV]b^˩^?٪b*(5FB!2|n/7K:2L 0٧~RxbI!$ƙݟ5~ %_x!3SJN$ӂ^;(2xh_2ĀCڍ<0O5a#O"Ԓ%l}^<1:|!ǽGݣ24c| E1 k;`-ɜ6c1 9 ȼ|\ Ӽ Qi,:`m32&jsu7"a֝~S߬%L^: Dft6XWiʰ¢Og"C`j֔l_.!dR'S5ϔm3L:eW=_g+;+)>4C| <H+34S-mοS?hu(O5 ,xgFޥVVxp IE7V O+ƼO~[_,Pt_n j1?k쎴E{>05ܛxYoV 4XO:3b]szh*a}KJ|@Uk3V~j6SÌnG]Znhv[:gws&^ҤVu2GO(⏻ lE][֊ȆNu Okv[;]qER6k,Z["3 IriUKkK2!Fv&.M.,\6]ܝVָʯ2c]eW[P*[OI-o FKFv"r<ƇymN]gQ.)~P]\\agXS5bquFahZzE*XjTJ }dSUim4wӒQ*?Jcrdev֌ЙRE+,8"b( ԉSQSokqqQ=?JGb8Er[hk(/$J U߻ClmL@ %Rx5.]4J"?5_lQų}9Z0Z+!>rsd8]Q1B{,uV24kp>YBu!݇冈#+a>)Wa~r5v2ᦓQs0%a*X5>[aZȾ۴L.)pֹ}j뜅HV׆uBɆFĝ ._dӡs kX%iNl~%4=jgb Y9oi.5ys81B W8|9,p; a*.N ctXN!=ηE(_QY cAQ_봭C;{>Fi|8Sڝ :[9)xw#&qa ޘiHYw.]CoXs ʐ|T݂ݟ[6~A)]ݴsGR.#F \쐢ӠaiZ wn_xJ |Rw)P1JdgZm+6x*Q1;};9NOt|{=cZ?~f8svsەلʑoͷIyD K{ɑZ]޻rd<:hAlCvm[wWgZ)+5T /2tCgS}Cd49 GSxg(J]r;*G跏#Ÿwe.c B[fDڽXMwxlM@\xY?z%܋;#JO2 CrBH/+*JX !w.$QVr|.b|ཊFc 4N#(8C')ӫ 4*=GC9^u e H7 I5bGّnv_l3l6'eoCf yYlPPq\`S7}a.sIk%O#ܕwüXj1ف~g>R%՜p|UI7e9K4HR(PΧ4uWu\4>.WnPzDQ04-ϰ*BK| EKup57x \02l|9Ns nsTXj2 {bT}yPShNs gX?c_OaD!ĕ)B,G}Zl ˁ兾ša>&T>1f)),A +q x/ATv!'ȇp'.6΃Fi.R!Q)SJEH4Se&*>}c阤c2Lm^ۦwR_fb*nD|ؾfx'K>XICTYS0 ?Nؐ/;:0:4>o+.| ˗\]SJZ:K9W,W6pȴPhBSw $Ape):n#>6[JZ+S*+wohESOGT9lؓ-IJ[u5*D1|#RHĭ([ 4.HHzlE$]]Q?O^yHJAJ$Z7> JK[5+ǟF Q"L.<w:.d\7k/I@L@5ŝ#ZܟBp{yz]/N Ul 倇P@pq% Qp6 ڊ? ENX dyѿ[[M:ܶp[ y5f/@i :_/QxtGaw;KrjX_'U$P ^?8=H?mZSE/bֶj9_n'2uۃAo +9wQ-z/}l"YiYO.?, [$ўKQ^_K_3DvυԿ!LBϡ=c__?!8fۚ"i+ 죴l{_;0؍KwAjaq)0y2h46jIɝT'`! }pUj~} qr } `1'QƟ?MWq~>_q/su:u_勤e&({݅j y0dŐCщlFkf+W?BSΨ8iFLjv;[iF1i!m,7Ͷ<[!mqɐVjy i!&ΰ䒔8y29ϖw,_d{k>d #g6dV4,,Q8Ms:%2RAIBY#vE|#8Yw$ )s2JLj. $$ӈ۸H,x'qd",jfPT(;mrGÓ@6MhF_ Xܑp dEM[1gEd߲yRg'’"x7@naJᘌy9}D |xr1:szr0+2/'叿9$@e6w.pb,Id0 ?rL"In_6PvK-[SNT~Pp'2s}Z3+Փ(V_òuc,0`+uOy<:)2v,MkRWr:I6^E2lM&]%IW3 ӿ"F/ߟ >D/lhNw_S׳`*|=듗 ] @+ i- "??g\ ~]qc'ʇWh~ xe dp(>:T~t>`I{#@R~P)h L {%$`@ڀ(q;")MsIp XJ[LXxF|q %M"" =Hg`"l]rTaZTOd b~9繇JO4Gۚ!Y\NƵ/VTkv)NZU$C|&R Q~ZG׍ υ o0>9!u2r55nzTb-ӻ_{_u?ԳnnAr5(& X2a֌PG5m[:-[M%MgN5^M:{ZK 2Ըdt}Ce\?j m#;vkfkVvW\i`S'0ɩ;q(X2FRG'gc&=G{}0sA"DOg0ܖGזּlD]WWM*mG!Yr 0zT]t-58jF]uU_ELڕtDcv/ B;\r$'Nz:j"AD78.މ}x6]_H~B B6; q}b_}qH$x%$" pqnڢѹv7iE1ɔ!l0G(c.`R*@dލ&fMEOM#YOhά2_ve=,+})s 4V=毮.sn}%Zz|\pŦYNVv{)ԦD۲  J4.t+#JdVFΌ "O8n;0 /Xrچ'1e%{ adcLZBk, =#{fh)a@< +X-0m#3-)+ĽWz#cTFé Ǵd'QڌN&YN TdhW*)}yRV} mf"h'bKa`tP eJ=^dhɇ.9x *?+%ݞj74_2_eG\Z^3 R2-/Vp*4Bv.DX-yG(]!JP9E$<*f_0R{@nF-i1>.:U>i(46Jܛ>9bnhFuNܩ[Jց' M֖_toC669YӎW`VQ5[F ]֕G!a|f(R4?!;poyVJRbFE#S a3ǶmX&-ewzx[̶c Xh@Z:d`bځzLq)j^[cc-vɫApF̭Vo 5/ 1mq_Ī4wVcZ<֛ݢ^Tjg_OTwc?WӛՆp OhgbK@^+ٝ*gPMYL'Dud/F=~ݼ L<+ ƙyVBiIEdI9<óZ|)Yqpj - ZN|JQnS>_"pON#_WW 6PĶ)4B56n:\ouߞYJ团8y6u4a@+wc| m`QwJ)OLqu^.osj:Sz  7;a[D!nQ]5ZB)™7W0 7sfCE9  u<<"DTDm SEHVZu _^?] N+ږ_{eUm#\K@%$6It@;66&*`>Ԋc˘в<IDȝKD۷?1`^Zt T% n6 FZR݆ۂaCd(DCXo aH^>aX\tB(|Z]yѐ'X᠐E y議)\艠.@dž0ZSm׍(jOn@b6'?l98ŷU~HyfmƁċ EGf043wLg']]4n`o4p>8\A<2h)7?PK G:X 3org/mockito/cglib/core/RejectModifierPredicate.javauRn@#*l`E=5:8r\o tw1{g1mU b7ol8` (nf/"D IUa;U+sfDpx4T !3`4F[qP-RYh 0P 86LrNmgP ˠ2Έ_q fOZ| î;.5CX&3>dƀ߭4rv֐-22[VjUvt:0VWLʍIE)EiNszs^G&^Zbśx=D ) eF}n)\᥈W udFeJRQKԵ0n N0s:tP+VDpȖ^ٞk`BŦ(lJ*'>hFi /=F}әّp_9 :c㹻;ers?u0d]iWwzf%<1XO-Ӷ}I3}5y0Xmΐ·|O825x0vS8_aQÖv4cBcɄ(g4/)VXӐk*"0fۼiksǿ;pS 3=a7༊I=Afs)̒nu:i0,TR2E^% -ݬpZhp!!a*?0/xNbW5AGy Pө;~Kt'O3訟mtxxT܍\oP?&]ǒlR1p>>äJ~I#ǹ ӏ_a.d.AL><@x^| lE,&yYIIHV^$vKX!dQ\|wP:ë>Dj >2$Ir9B.$1+FP^ Qx`,$o:;na%r^S*!QjK$ɯZZg)xepʃg.-~Gh97F{_H(".~$)DtRF~Hro`Jі1j1E&mRLPA~2a}~7P]z$? PPK lN:#vX%org/mockito/cglib/core/Signature.javaUQoH~ϯ@^ή7"", p!NZg5щ~3k'qDCSgfof7.V7[#ˍWWj7"T]' kݪB8p 9*P C?h,U N1ZlAiEֲBRA릒Btg@ Ӏ3'(]PACoq"cƹeu] 8Ԧ>FEz'U}PZ Ґl !ZȈl%:DibN3H'U9;88ȬuGHq&Lt iczCX%),vKVrAo!^|nHQ|j + ›"QX랒m0k4UD(#EASKsD`J?Fф|8tXt:Jfa ^O&DKwWۆѥDL#`!v(Gz=R0gC~V˻K1?4fD;Kr&0N(:.f`( *,E{` $}L/x;z,O.va O~b̯v{ڰD8m11$!-۰G*GOԟ3ū=S;,D>ʎ{xyt9hΩʹnGLq+3>:0gm"7ڣOũ?O n۝#⌻# *!#|" G 4Fױ, x.Om(ķNo-8CJ=v9_.]ԧvѹ+)zCN14i>22hݮ>g)ƹ%px@kw<ܘ{2 =gf]_PK G:mN&org/mockito/cglib/core/TinyBitSet.javaoo0)nPLQ*Z &]UULr GC9mA(t wq JKDCD@/dn)2FL (rDb!MRSBEF *&o1!i`c Y# $4S!](QBHo@`zMmf3IKRyM?wM߾9!uC(%~ƨew ,$,\YR=- vPc!4:#B7֐v(l2\lˮG:xpw;֍ {-z'f 3#2&?(50R cZɹPuP3̹F822>PjCN7f 6TS*K~a:,/QBï9Pi3e8@oON!VaXPT dy\Tj2 U/PK )w:(org/mockito/cglib/core/Transformer.class;o>CNFt̒|$Tļ"vFFIJDļt}vf(2= F#6kML!FҢT̜T6F&`dad`c`8$+PK G:L'org/mockito/cglib/core/Transformer.javaeRn0 +"4Ō-zjKD ZC"{.uGO݁j!wJ˯-O#5#&h,}\+ t9vAX1pPz|ȀI0Nsf4r<a%JNNFP|Ve48ސMYm>3x5YZ5"WX(5QtKsgO=5#H,RoܔE^AQ-[^2<} nu`)b[ ~P29|t 2)Sx }jjI5ӍC z#(Ľ4= ħey$tئIx$nl$OѷJ]{ewm~fsbxQ$PK )w:F(_(&org/mockito/cglib/core/TypeUtils.classY |e&m )WiNBmiXZ,IIRu{oo#bwgqwvuqGٝufgga~M4A׼{<?~SE$]#P6Ńyo: wWv^mda*Ln/LxD{cLEP?֫V0DSj`|]Ad g4h in- WT"869}k]0h\"74B.yg!AhP2vzBh/CI@TJ *xD/2Mpg<2f YؐIsqP94L/kB Xr2k }!TUbp7A`-l0!#0]jaCgHXmg nծp<ݥΗ3x@{Z!hی`&N+eN9iYV\B5rdI|M]HM:[=EcbI}Tr02ea9tL k"hh0Hw4lҵT9i sEH)EJA/\@@[;Gmn yN+ :1eGIf^Wcm.ADŽNH/͌IAI:0Z ޮ*SuIb}jAoNIA|@6 ;y3sɨoB]PkAD|-$^! _Ⱦ_3 >ߦ:C$C!]hҹ6lEc37 \UGS;}D?Cf v$/oD́=F{o ҹdM1\20l5q/ה+ @Fq\UȚg>674?٠2( 7:Aߢ@ĂH5u_\v$Z#d)V%qRU le<v. vHd=\($v.*|jqu}.&~hQL c6" ;noota>p)x4jau릺WPL76ֶ;xF֖5gSojioX#l+gJ֍R Shj={n7;-!&![1y> KR51yٜ]gq[Z̊`l] U-F=J9sIOÕq$ B@/TE װ#a7#D [ugdH`"W1-3J#d֣(kq )ケQ<ǝ-c+ j +/fmf#0Rbg/C*yf)PL%]UnE#!Ȧn5oomikG04V:i$sjsshiRqcm8j]gˬ J  ί328kRWeߨ (3*2?⵾X\v>>|'f?|O|/v @ǍwWڻB_ aK0UKc w{* ~D ~DB_1$Ytןeeo *w/SiHW~_q~ bG}Ц]'`83Hh 4JSva4U`.|oo9^<=I㨐Ob,%WXwzޙC8AŮ *8;tكTy,L5穙*y&%`)Ωz4"h>U"r.U,I"M"[v14±4_F hԤQ8J٩r!,@%+QY *'4g$i%8,4c ҊAZg] X1ϷEdmVה>L({, Z7Bnަ䤋 &n$ .,wIІȵcfx, j &hNtKI!mچV˒v´J!pS7^~rp+=!*=HW^M}U:)ƛD cNXOӨ wAkGGg]4mׯ[ssʺ-< }s男mwhIwA9tR~1݋}M ڍS!&*>Z ~#@V8 O8=*-R%UTw&i Fhi"D*'tS(<3TCiPy=h>L4Om6˰.i,z\2OAz>z3h !c0lzPLKiq3Xav@wP9~gA$=e ER3̾ttgf_:05}6Y:=Ȳ{%a>=Gg׿t zlbTCB#q+c7z :^q!8+JCrԺLFCtQ0<$NOug uôVb;IgWqIr8P)0o!$$/A?9A?Qt#jB;{̍R0>@ FEK0OY?c*RrmoL zt8,N=cZN"%1xd.BH> Mm" 5d>fd*Kʽ'SvaX3 9Z+P3\Z*X+C8ږ!hs >Kbզ/9rR[y>vwt_JЎvjxF 3ocw16]J֗oQƢӼ _|K^4D_t'tY%:0syJ'Kp"$[shDugb,m)@,iE0\2SFʧ:.P!L#2>BHA8ͲvjLpaǹ3\\P ?LyiFe'iٱrnT>zU /r6ciйBV!.Fȁ 2 e btx,/@OAz4~ jүh }3~C<T)37{oN5TߙAzZ[MO\0UwiG]pep[ Ҕ#rlƀ3oip9_N2*nJZ#7nN+*p)V # NasL}, =w*ޥT;0r̤t`d 8fSqcId&q*tI:Hs7]99EjPY+F){Dx.8kNAt^mL Ae<$S5Cy>mLWqWqh_C5|}&T[ͷ:r^ [ÍeUeOs41hHqs%ʦ:&o4u³ O(5cx@k1Fcxz1A+0I'bxڽҹ r,I)[F9f&d-a1DJߦ 3E w߃pv}G>Dazz{_p䇽O!>q  K1$g-b>P1?zMy}Hy}Ny=ZϦ>_)*c= _|al' f6v!V] W/\5j7O̯PK lN:ؘU 2%org/mockito/cglib/core/TypeUtils.javaZmsڸ_ܘ:3&BZ:t'#@[c9e[6&e&ۏλΑ|<#`R&{E&KF:k8;2rl?d#̹wZ7X=N};.OLA71`*)) X\*r}rttwwP%#/ŠA{/@dԵ1!H~T>\:a=zGE P컐K/DD:3.dȧZ"$n'VgLcwqڟ]OȯptGË?% o/E0a519ړ͔ƌeDHb\>./6t"e5 W\_8C2_qCBFG`oH,.<>u d VJFryQr&kL(ha !TA\*z]R_+AΈ;*ƘV b7bi#@L3Hۺ jKcM$Cy]A*,*ZUP*_U #j\i +~1Q `vJ2f{(QH`1LMnCb ͏!Wx'[0,6ۋǫѤם.Rߏiuѩ+b9O:I C_ɴK1NzWni~ToO/?u&evj9~a;Towhݲ=:™1^"bå/ i"VD?9(\va!U)̮*Wְ47ه~4Ċ8 9nem`;;<˶YC%qC!i3sb:{Yp <RJ_'RY݃T$.J,gDhl*8hYy \rME84Hfw]5/GH]so =hZ9 w?ϋ3𬐘4ٵIj46L/d[XO>NnoŻJsBKxK LNc%N&Y{enj|§ddM^+ 5T pxR]B"9lh6ГY$PJč*\Q~ao$Cdc<0!Β!`pUI[ tC+S6R~EHD]ʺ^l1L&vD[Dl:Cg[kWgxrNp-gNVܚ>7U n\ )`V~ FlYW0а̲e!vp&QgR( F÷u 4?ߚ9~7ECԲ#36Or\e^ ŴeIqSŁƔhڴc|mQH&kS`M)oum8!) \Bצ&Vm m]^u6N~7Wlfͮްo_:a<0SeA؂zpYўzm)Í5o퀞jԪj2Zޝd\ꝇ)߽*k>c5p8qVj^u]JO{V>GXdNfAlr9vԾHߟaDMϤkeL.VH@UC.Ʒ j,x-x?W6VRocxjZhZGljA_C_栯ʡryR[, ==U?:Dp*٠`pmj&Ԫg ڦ6)2[KNy/)^PQ vmBςwpSz&M_aON{D..׫=xŧ諒{λ R*.]췛ċ+c/EW ߏ}xVhOۯpްC/v^Vy*Gye anjPK )w:T0org/mockito/cglib/core/VisibilityPredicate.classS]OA=KPAVT,M>bۡvqwKO^L(m#HK̝{9c~4t-* 1- O-ˋ2}c6wM6%c-?09(bZNI<  l!S.1ij'|+4ÅyQ#EؤWSA]*!BMbl퐸^h5jVqi/t| ۋ C'LlY!2=ZkN\ 1BAC'<7RsjE=M2]Ӯ ֨;'.߲XwŠR+NQl zA;2*4H"E'K2jhE1Wa@W0 -Qa /@l$6U`V]ܓ^VArFMF4ME~?OHlS;(CoRkGx,3yo7)gT\fڞ%+Xs*鞙F1i3)rX'fraʊ*_7nN1N;$$ة!Hk:s~ !zǸzO{֑5!-  q" d&3}aY.}t~  =u1-|@C2"XGZFQO:|pFg^%aj%w(LƐuΐ9&jPK lN:ǚ8z/org/mockito/cglib/core/VisibilityPredicate.javaTQo0~WxJ*fnOVBV}tKpIvh]V|w OzpcS*NO? ZMW"\Fg+)Ff@wI]dhe8P?`ikC0\bAiHMUJaPcCvFt̒|$J}ĜlvFFIJDļt}vfF^=4#Wp~iQr[fN*# 02I&VPK G:9v%org/mockito/cglib/proxy/Callback.javaeRn0+>+魹Dʀ$ȑV2adI*߻AuΌ&F06+;7a^},\b^hE arXh_N:ڀx _ na!qh<\LqNMω%']zF A`:<͏$.fX&Y,,/fHyIIt,i%!Y$VX$ Ռ Rft HybՇW ~P$gZp5~C;u$ 4R.J"yx(xVxF26VQ S)3)KZ =ښqt}R-&t~5:v2߻{pd7Ji{Ar4Â=,4#OS TLi}$=VLxۖԎ,EGPK )w:o ,org/mockito/cglib/proxy/CallbackFilter.classU 0淋"Q-T|JLqPo98PSHTMR1,UVDf™DŽL N "\YX`jFRڽF܁Tru&n.]|1">/"oVO gDuFwsLsLH-qRc^1h l ͚"Cte:cM8h:<2 JcL4<9p,PK )w:DC7org/mockito/cglib/proxy/CallbackGenerator$Context.classQN@=RQĽ1tcÚ%Q‚@!௹(㴀&bN2st-UFya[i,I.\r͌% Dh;&coyh_#SVGpOvqP!8;+e ai:R,puG_}B#౐cnTDѱk4߲K+*rn^жY'Z,H)0ǡOZ/#!4Uφ-n d"U2df9axR?!a}:/"M_ڝ]Z edR&P,69^opk%wȴT+_PK )w:8C,/org/mockito/cglib/proxy/CallbackGenerator.classJ@ƿ1ikU'`/.=u lwf+<> ?fpDZWRmYƵ./{aR;47%.*)||qٟO3kl_LH_Pn:2͛fTK~27G,WO7C筐+IG'Zx T?粷c ?4A, ytx+d=DpT(L1: c;: ^PK G:dzk.org/mockito/cglib/proxy/CallbackGenerator.javaTn@+FHDMTN!URL帶fcPfi{.!zg\;z?Z#Lk+µ rs刵<攡wNF \W0b9vF@Ƣp*fX; oꊔZrρ%ONr%ZVE;ڹxܶm:!r\kxGE2{']`GCF,;PT*b+PA9ser:Ciޤv)0&'4MdI՗ *%hWr![.kJfD&<1KH(x/֘QAXeJ_hq5 YV枦 n8/hHϞG7=0++Jv7 wQ%90c᥯MdB"UUtrl&JY;L4ba:=6֜ 1c0fRLN9o?Fx;➝=O'\-SUOJ%黮~ >(둈b)_Ҫ\B2ۿv H9^ۛ6OEJ5MMdokPK )w:J;d ,org/mockito/cglib/proxy/CallbackHelper.classV[SSW6I8!D4jh ^5jxGԊH!=ɉ{dNg:@g*H>1>}L@i !AKgd^?؁O&xd,ۉH,nCq+q{"ҮƐѥ㚥@R#j#k1[k:uÖ<gm 4{41ܫ T8ERnDhˬIAGOtM>H|톚LF,p}~ ʅ]jrUTP ?(+C BR'dyk}X'|(qAЋ0GU3&xE^gUr\aj|xV.*p';n?갹s{ 36e\tG҈4 3K0Zw8:dfWD`シ0j٪u܎i㶞0ɫCf,3d Ë ٖnƣNh W&М`,̕WC9s’3ċ'גP,a&yri:[5JbQg(8\ /8֣8|X>t2OQ&{(̒'pRa*ux| /q ΰ@$dWU'). xtsX):Å$ً]P2ALi-jXU518 e?O7n '&N8\%l~ .[FN:hm8䰠%B3svVג!ݤU^X/&ˏah#QW 5ٴVγEضVmOCd+H-|J՘6쒣<~Hi~ͲަqOJ{bwэLLFҏqZQ JPIU'H[jꐡ.v*56Y/b_W]K^`bG{|˧m\jC V?BuTcSc2!mnWy[\o؍?Oq*BM6xIx]OoJ\Y`0 ]SɃOP!4q8(L$2pr\Q'Za7ͩX *Qn9A0'j/&p'R1+i0xm: wlS)*gLʝVL9@AL/ yx\dRPd_M_ S"˔ֺ^PK G:rȺz +org/mockito/cglib/proxy/CallbackHelper.javaVmo6_q5BJ]1}Ha RŐ|ҢJRq6}G]vu`sϽRX&{57E7+c B.cR:p#5.PCI<+͏l4j$ a>D1DraQ!ǐ HBBU])X۵1&9w]@u_d'.ncZ)Wb,!Z[Yv B:3)nx#hq\iD I(n,h fgAއ9܌p2_O߄zJ M?MbFv!Qmw(Ο,E:72ւ/DɇyC2ݳ F&xf# pTZTd$I}^ bw\ ,|Nk5 ON;/Lxc J $邊"(M`TcS\paKVe=3oY[}b%ymjWT.`:)T2fMN)=;=po~&f+~.g4#I&v hjn+jwNx pP?rnINpG_sr¹){ !ٴz񑪪̫)Zsn3џmKoXIMB=ˏO0/+9Wps҇kYӅk |w%4y} +4@]r_y38 O# UN(veصe--|V{ۖccWN2U$ry f 3z+6Bv5]sS!Dܝ?c8x:*~c^j]=U vx!TrPNZ`JΟPK )w:o+*org/mockito/cglib/proxy/CallbackInfo.classWiWW~-Q1 ĕ,h*E H0a&&Av^_mG?я֟ 'ͻ<{˟.$aǍȘjHTS1y9*kڰ6H/ȗ&`%bP,aUN!"8%%4Ъɉ> +q4\fy9H$'ƃ}\[Ca uhbD1+ A `9]k݆r .4۪ nvk$H*:h-A^RBXnw`׻6RS3du~T1ڼy07S% ۰U+VoqJpF(?&UW.̳0gz}.c%Pw`CvK1 O\]\pb(Q/kgwh)JdDgFɣ&(̿N"(alc2f3l;r,#v̂ydzéy~Bs'GG cii9Az6ՆpN<ƄGda.^(.$ LMS 1: U$ih ɷ]FwҶBYGq;}]̞)3G/"@ ;D' E9jtMD9,Ƽ +Zw ^(CdDdQGHٗ \ B8+Z8_sUΧ\USo_\. [rhXqm[a5Ȩ^HrY>()#> H%^Ҭ\ AʡaA>*糣B=ݧzڇfjхo jp4ZWa'!>ϺJ< I)0KJ.a;"qZ=: ^JHqj?7ppj5 wQZ$?[z(nG*Q*b-ֱ/c4#g(e[յtu͒\.ŵ媇6QC[z3w[k?s\qK>z:@  guOw௿F.=q)BL05{X!mZ O،ˣ$*Nwڹų$]i),+, mQտ*2nBK#x]MC׎d5~zv@` Ϲr 8°#f!+1[kYIY~p3H 9~K8)$VV9I]fz*'H1N|aI՛!}=8Miʵ:oc݀[W%9\Ο_V ؉f_ى} 5Z٠T50(G@=6n=s%t2i5}9ִ̚5kj5[OSaM_c"u.7i,PK kN:jEs)org/mockito/cglib/proxy/CallbackInfo.javaWs6~_ .dnt4>=Q`k&s#0ɕʿ=!Xow];@;Ţ|MI?\-QF2Kbh`m`B*4]nP2wpGF x^B*Vo1v2 فMiX1N>46rsFDHa:>ǐ CPAU])ژCn]FJx{c0ß1Vp5(g1,0XN HQ3҆U0uA Z%FEbAbuhyA >zt-iz;/lM0 ɵ?\gr+,tPa%tLCb!&D"D jô 3isü4"<@_t^Űۭ^U,@Ԡ9>m)eEͺv˱-Ʃ[o ៫lmJ \="EGJn#QY yCG7T \\Nt]8H2n Hnţ[QV<;'iu2O`D%d;olڐ5ߏn1˄r2R#;PK )w:ےR|(org/mockito/cglib/proxy/Dispatcher.classuK 0Eh.@ء1hlJ[E(1EP<=-?Zyй22:Ij/W>Y"rS):{q܈8pdP"g˜PCƅ+o7~SB-.R%1Cl)j< Ts9j8*ں PK G:`'org/mockito/cglib/proxy/Dispatcher.javaeS]o@|WX.D[cYqGEl8xkѻ#FCMd .4)LZ¡@XVB-1Gpoj &c`$jZA ~u .`2M.o55E xrpT%H<( ҜR -勮2aR/\B~TW}- E846ʾEx&/zD=jerڂH)-EƂ-ҙ7,+ 2O*F}&4L /81c|{8r_n:V]|w[z ~ۻ eF}d*.񃄣% :*It^!7h59 Y9#Ӕ|/ny(lIyʼTiXYA4S^Tk]HQ)12ԞPrԕ)Fm7Fd Tڣ= Z" 41 %X +<=0^xKb9W=i8h %i yr,:xt4M£ {G_[Eh(ؓTir{F_Z<%0u$,fC\#u9ҊiP[@g@ յ\~GI͢\+k{}o {L+)ڴn-3˜?Ӌ3Mr87ڦchRH^5rlj`bj>Q :UsH1Ӱ<2xJo|053gHECcg__<fhQ-"#g8ݰrrCb/={?6°c>iHJ=k +HJ|3uC2Q@pTA Z}p`6֣i=|ι)gT#˫bAmnEzj( Y[Gzю fyFdt9I. +NKQ;Nqyx݃I8(NW@ Dw62v^ y/:ľ0*~8I37&L1(9n6έW|Dڪm!Eb2m"lqA90h9sf0;DY^QЍPR(vyUYT _q\ ,@{T _` P<'M y+8))MX'Zz4U-ݘ3yZ'ZFI ˏQAE s)3 t̽EI8=P=]zw{*ɟTO0|i9PerMkj_jj_ʑs'8\:q lcqrS\ဒ|Ȧ םi*̴EADPJk`PZ5]kJ@V~y8[p4Kt1PELJFnw4""w/A&QdTj.vlk_j]ԣ5 ШZ_.66-mqVU⋞@`AF7@hA!݆Lf=б] ].k {Eы0ή:"uL[±ZtGX p_ZE$"FnQFocF~{eEL3S)NY6Gsxu2q{/MEw x[ze]E/y / +BG)@Fp:s8BX](U#x9rpșX$u&{eJ[Ѕ.ɐGڻ>]~=|q ld%Mܐrӷ4UF~7c c'Q'}s PK kN: 0org/mockito/cglib/proxy/DispatcherGenerator.javaUMs6 W>Wl{jf^6'%A272?^P+ّ',VH= 2x2?*n |eL?j0YD@&f,D l Ȁ LT[*M: kptc1-; 5$ϖ#U^9S^0e6)]jQO3ͯv[]b 7 d՟|C>qIa`h1Mm`f#ccM ^.O  s]7ޮ/e/Y(XT'a<2Tg M|1M?Fvy2&q$:a7ĔJc R!) @iƏC9iijMH}vкpϸĬZHSWl]7_K}=GL}i{m9P*XW:V-^XXV`?x]t^zjA9k{?PK )w:-Hs\O(org/mockito/cglib/proxy/Enhancer$1.classQJ1=T~ "ҺpME PgblӦdFrJpQhW"ǹ$_XcشԆU;.7B0tceӽdLT|Ivu݊iP$/-p?⯘^tΐm$F1mO3L/?%duBmCtu34D&2e E цIRטa4=nO* EA-gYElLzA 0 ;*3W_[EZ6Ž2`e\B?RD Vñ}ݴI[w?WĕvaaO*'a"2*)cKyr6cΡ":$tTznM }'W.X2&srx67m,"S{ a9is5f%c n" CHUE4R"DO]-n313&zq]ZHiC>WraLH /K3k6, 0ns ٮj]1j^-R:KE NG=T? DR[ =9FB'Zf碎#h.fԉ\PNW,jhX&J3Xϯ.8s8HG21Wц'&=N⢅ DUժbui#So+%|OwbHPl(6Fߔ 0<^bU/4eOkE5W4&gbL}Ü;sWdVٚ^4VuZ*qKNt\3U^ÐmGho[gxz)M C 2!C~3EkbrpM{IdU0{ͨ`^hVCW2h^ D^3,[gv);\Q1ai3Ĥgp'ev/$szژ4w%±0V/ػNFJ?n0 6}+eH]3߸N$Mfp].&ySx[URq0G2:w=Xw1qLFR'{a@CR,RE՚gsW;22VdTs޲;XCI{3+ɟ>H%͍tKtf^&+Yo[>UT=;1V,Lc&K'aɤ]ڨ OwiK>=C_QaWy #0J^j9/j0A m5 s .L ^YhV9F ;ޞ[$ [I]٫}m,u +:mbWEpGO53З%cCɳ)Ubt{ZcvѦa{b#_^[yV'j|!9&6I5-^e2/ā-v#=z";^%`E-C[;G+'m+]r'zYH -;5ve@9z[R -'{a`|\?,Гn7IݤMBX2o'^|W~QkqPA16}uIILK&41{+d\7f,G'PiG&kr70Oёv;z8c:920bztk-/ob_"KF _& a1j361csnZa*! `9[&7Ӻ:@)YñAXuSwO2\^+W17)hAXu*hW] 6ފnbB:B>lqKVR'*ubk@^ьGHu,f5IR7 =U> ы8Cke7IzI7 (r/DI/)qy Þ:1KaPD/U#C&R'# iqBPy`CVp'DV_;Uz t!Fh ƨ3UhP]% Dv'X~(\sHJxExo>Y"ZC\Zf|wFhq@.x%EUWp)?ˍ@ ڴƮxsd]wNeV5pR?UF5/b.Y1,7FROuآM!'c٠-St[CPbdxtxblL~#  2վOn漮m 0^Id &BÁ+4K\T;G\^ 5oL643s)xxWmr3| !&FWk5_j04ht.UDA-ei1ں5ĥ|rEt%$M= A7]{PGE܍mysyۓ^يm$>ΐ:;= .`{4юvF_hШIbB4ߤQ|nH`f!%oҿMcѲ I7J{~ǁ (գx+xtMa D?@^t-Je,O绌HMoMO,}F{g|2)ty%\yJҋwײ*4^ĥ2?M;ӻaacWqgͣ?V~,@k3Kc+0},:=s#&'nmCnebi = Do 9/)}n+a[ {~#.H?懞 n#Z /?PK )w:r{2org/mockito/cglib/proxy/Enhancer$EnhancerKey.classJ1ƿk-zP=₇zjO0ۦII}ɃCIBb)!eo2?_n1"\[WU*XJ]b{-̳4x'N@|BKSb*$8!vp7A0hT~,ʔⰔ4ZR+ֶQx7-dn#*`FHg)v-g蠋&K#ya)O^ PK )w:Y 4*b&org/mockito/cglib/proxy/Enhancer.class| |{3f ` `! `Kd7n8xޠZxq&mVgZZmafMv'ߙo{Ι7c/܁`[yGe/(oik) 6o)[A; BY⨖@[^&zZPh z"&l iqB;#d5 LN(kt[v@HucSPio_i^v0<\1G$28; dd;d; ȸvp dܱvਪk^Yt1Baݑ6,^aj9GbynUuMS.Lx4ϭ[Z7>WW;{c6_ZS5H]U!:}ٿXX[rRn jVZDaK2͹ &M\XՋ.nx3XωqdxC(o[4f^UZ% hOy7w&Yu 9(U65NhTk{]AjH2ΙB+׬h%ҫY\-k%5ϫj0Ƽ>YTּ9|hM 4hvm}B>Do{Ud+Ub[!K9vfEgӬaRm~F NfWZNoP5L%*l&;Xf%L3]!\2 }`/%͉TP:=R1jNfLWKcN}hG;4#̴ L1S1 ^um--J.}s( 7qqHa#dkC;3_6*!Ԑk&0Qn 7a@]v qxͰ LalB% 4 {FpfXq92ŻQt.&EMĎ/0ve̾ɨX8fm{^ejGff_;\M| =[-?v-ߖNNN!\g@=,fݠaYr W2wFG$e1Xeh!g#1ֿ6`k>4%6m2v ?NfNz^֪D5`V{ X^_͙m'4~ {E":ILX(lR]nXVZnˀp ^T-D^Z6H+o.Y:V*d 96z}SG%eC:$yq[ސ%cܖqA'8,=A;HVP228Œ:œ3) [1D֒({C'H#ZOh=Mrlusp&y8ʩoX'OsyAdHR[)9K M&Lw2C|$85:mg^(՚v]{"+o u}4߶t0C]:Nq:-> M(ҍ8NJ#<,tn+&r(_-BZ:oav 6oD06ܶ$]l_` bARvb벰>"F`ap|p cMH'$7vIx/߻L5'$yShʕ %eL`G: i@7(4b!ew$J1.ihtٿA4' t^+楌bDm@$!E1vD ,ˁ9NfCS_PX{X|R*JRj :g8dg8PH NARL6^ MM:Q7tBa[->eq #%"U%u'`!iKfdǒ!|Ŋ 8_R~Z:Ƅi|zq'"Y}x; E1+C x+ S3q2N#KOJ̱:. qyl v<#Z-Q38gnCGKBXTf-݇Cq)1j'F `SY#kQ2_ܬd&mIqNWgЉus,dIdEK,m6gRbuhFü  aHňhHA,+!WE<%b oev_hiObOu*<,Xv͡5*o%Nݺӣ)BUo HʦHbh1}^P;Ae"F :֏/a<^'(%~'`!W0}Q7CV U (!=uJ7:qMNZv\<)=I_BwԽTYv6zwn`I%$Q\"gx's*vp2XuxܧD[B%?YFT=;Yw$2p#9L|Kx}oۃ r A: >Z㎴ G/bbA3(12ʸ__ˋcB{U䎞CyZyFA>:qIɿfl3/x`|Y/1ߙb |Ejm"D7Ά>םo {t$6(ΉUFч hdHWŰ]X t"6[>:I\#>/Ly:sCqfdf>YHI,_̴߻9#i 'D z`x9/J~i:sJ-QೈM' /Ar;!Mb*?-Yz6CP1DH# JMgâ3UjbIcd!38jM~g}eևX,qF+Dn-f RE#XtC!i>EuG@ZZ1T#$WĄF4"n}4yW]%ъ(%SǝyͭiCIVZ8?1&>ѯLj DFܴibTBJR o2.+#tDk Kb%BX9֑8  },Ai XX * qD54<…IHl|I=)*ϳjv9K6).S޴'gb!9DjXwsC=ٛ#v$`@,%?SZa_ DQ,s<M)V<|/oV&r֮NCO"QVX]pDl' Ns.9o(m R\p[ΨvfR:$Rؤ =@:B ƙEV!6ܸ(ziFO{gjE6T8G7K2%{gpмqo6F!xО Dnȶ$S4S!chV^p:%G܇ ŕAT qޜhȇAXH9ab8ή9nYǧRRDmPC?׋ Yvk _o!i#=0ďƧt?4g|o;W٧&-3q'4nSqݤ. qxNL~@d6=Qf]Ti0K"}4#௏n?LaM|DND`9PQͬVn' 8^w']) s 1 0J<+cL~mlNBOMTZĻsgM"/MP>".AxE_YzQR꘰^߂Czx ?o$.t->էqԪseEC;]'%IX SGE?LS^{ <(?9t;GQul{)-S/BC]|N^\: K~|!#PYC|6~2!տ|u~ h#uSiC2: @ʘ+צRx|&yJė~{ÿ*!30B:?! i0&,z>@#|S-s!"]1D3CI† tF#RuMquǷ;Z$lQ1V]lQd A|lep k㻿ƌ@3ҾYA8DIMT[?8{ZILE 6X&MFS+3v|8ɩ1ghORqwM7^8[g+JT|=eD9ʝNC`j=` P KB3ԆGe-C^@l"1~:"C(ԣS2Me%!ʖXX{>>xo >c7h8-A8ާ4fyYVt<,)W,<,rYV1˹f9,eY.PѨr_sr ʥРFXp*J $iāGm>BCnn8Zm{ˏ]!!Iۺ&/m3@S=AUt*z~!s!\AOF3urFAɁ;TDa"7os_%FFeH[vn*6A@RO(Ns2\s!h'1ˑQzhJMd8o~HXEABfol?I7̿-%'1,p2;H-Cp!)FP' \ l>.5c+ \?!lߢ^5/ І>8 q,v`5KedSC0zN>݊IJx¿*t'k=%˜ABz̷祿6{xJ`zc֬0L.n fGefd* 0sF:OVp_mLjCI/l%e 82W@[l~̎Bf!`.y8FBAm#zpa ٫ڠQ,% t%Wt BFqI)b/hpmi2ovpd&84NWbC`/+L#s9ANMOgU^?,xtiJv]^؇SUZsg48z^yMŶ\`5"Nrq1r)f}H*̫,2dZ=դ-%YIKN4ńِC$7 ƻ!p$T iNrr@ W"EB;bx$w= M`RR^lG$CQ5_܏-M4;z,anJ[7Qesez)Jsl!ؕރgyxASIrLGbYARFj77DpOFˑ;~7ށd}mNJMS&<"h7m) .: ArHwn~wVNw]EZF>LePqM =TS5=1Kgl7m#L rFSJr L$Q$?# 7I5'%a˰? NJҠ ԥ8Fɤ S[(R|` [1CI{Yy# !^!l?G|FIp ϰ?TVᗸFX+lEįq3 ^dAowv4yp/#C{G[sM+4Y)r/ϕUdlYɊj E. y0L D>WBiu(Vd1cálklʊtU(] CC?fiKm8RF NfߋUKw<`"YޣJz=ı> v7cwS³Q`UB)ǐpC8F1P X11p( W8DaGAAG܊^1?4͑xHвE (-CWwи8eGb3T|h8ғ[ _ +)^e Ä1SZbh}R^IU0>NIhLx☦QWۥ6|Iu*'r9Sz$E_b?j%Tj REN&k]haѺ0\iL0KaykZ̮J扉DtE˱ɊbĦj&So"̙JT.ZDWLYTA+E,;H.PrxԦYZ5-NU\)"=K.mB*3[o"!aA4GҒQ01M6Ǣ@Y&7N2 re\Ю2ZoFY5X+*Շe,wÉhnU&L,d&XLP@BX8%-8Zeۋڋ0R샣$0=h&^89tu|r#<*NՕf+*]XJQaNyhtw+Zߕ[tFDH>& "v+=wJDlᖳq^. CO y₾o)aPTn%gIA/ՖdvU;cB!8B$~1(W.؇`B<k!x6<* p-&^{K'( "aBG\VIAb^WtKMrca4B*H_Q ZE|\ǦRb-.LjT`u!UqMY~TLϦ}O-NQ)Q;J!M}L;d%|\}-S$B3B MT34Q܆*ܶn-[ᦵ KҖ(ښ%1dAee[HRIen8jI騈FUD](<'9*i__g&`OO^\U&N0F2miФ(-3`tRz JNYrTl's-J5)Y͔D *jHCmGDo u73}8MNQԽ'QV[ԭ[GJ(eQ7ˇ|9\rQ7 &p 3dTQP+G"jonX!Ur QEz3,`jjjyψJ=b@:17Gjq`i jHc%p-1\ب"Ʋ5p8YDPOF%'XV8Qz0G{!MȣMxWYi/ޢHʴh%=ZS~e(Su>t2L;<9.0J 5e dvpgsgs7.+seLvÕ\kJs* x++= nU֨TGr9e+sZo'FOj2IY4\n;"߬^vK[D:\FnXN$*ÈbB7葙lӂ+*s\}r${g m`C0ɕSB 'lqe>2ו{2W.'"[ ȝ+7.|H}̔/( 9)ɤ[(51Lخ.C(#Hadm$ٻ\Or6^.^r4,Gl'啨w5:t_ˣbrGm$P-n9jv(9Wel^Q͉nb\s,!0p!\AUp,#5HKHCl\AdDQf0.8En Δa˳qy6*ρ<"/ar+E8^^%xg˰F^ 啸JޏYr'^$wur7,"j.0>$#=O M5"I:.k Ѿ6//I#(py& nYfd&~rIx4=gq4=Le2|7 4q؇U34s'[fY(\TfE>%5KQb2op]@p`|?/h3{."?>M~ʮ!;EpzVxIy] d8vyګja7Xy1Rc"5+,bȚm&nѧ'0|NyU3qKWdu2`2[º59??tIlY-3aA͓jd 4m\5cYH@op QE8y9/ A'ÿp4r[&YQT7(*?h~hY c:U9|_rlq3dd% E6g͐ u.&i|eGyNT"09GUv͒z$7W*a΁+PdP̠uUq$\XH^} cIU c //}¹xGpr$7 <[6d'Q1AFw=UɁ¨vr@uVKX yy΀H!E+d=W'Cd&c(j_bsX_6&KA=$9IQ חW׈7ޣߑDbdVRX%c’8`J>at+,)ج֠YG=~=2Ъw YT hŤI. @i7Y9^!6 )P(r1@ں"ܑ#H@4y&^pbjҗkM"xw}!_0?< ّ*b怆ML3µ197YR͜rog N@St{pƜ09]V$ `pT'j;Z%YHSZ赩ͩwZ `%DSӆ醤iIr-nؠm[]05*J|9 kКћ s@R9Ј}WOm t`δ\d ހ=:rd$3&%Q aĬ N[DV`Nļ9; IЖuv)Wɚdh d$4 gh'=$óDi0,RQ_\ MtSֺ3uFEYU̎N#[*g>k >}cw^OH R.'q|G6`GӃL`$?ǝLEoǣ}Xf.yd?}t:z=6!Cpz1t-0̉B)p ïN2ų4pjtH{O^ݣN]f 1u6?dF¦bDGc\$.+6p8gx<9 #Ni8%m>óa0Y5DV IO:V6M=|{498; |ǎۏ~qir/W; jOthP: Ud1DΎ^c1Py}zx2<8xp4qLVd5U/SLǟdZElZqcXnfgаѶȼ̥l݁}(QZO^aFw53 6QfFڔwih00de/*4(5ãqPdFvuAӎ$ֆ.H͇'7S-> _nAӑˀ:ÞSG*XFn aInK8]eGamXgNV3-EN/ 71 n!'Np3Kx 03&2^.8sə,H0%T%2٧3E|KC UJziϲVr![U+@*W6hG]zc ?$=p2&P;\D+x$ RӧArτgҸ;91wrPbyʜ'WBUtif >vD2W+L9K)}(:2d+8 RQCfpnZr,k݇5FVJxJjs}K{Q4gc9oTؘ!kd$ҽZ}Ԙ*LEJ >k_yOw]O98z1^  ;8%WUm5Fg!ˆN-VzCVK^1]qbHfeV/ ӿ+Wf.ceuQZ@KSZk,6!Ɉ>CKID6Fq҆+ʩV!Eg-ii\c$BGx7&;VHNx|ELL |ȁckCι># bڰ7 ʳRNHu|=] ԃ揷y[@sNLJQarYVAw`< +:|%s#& 8 #RjG)`^lLͨLmZ'=\+,qVnZ@YhCvRFRBEÑ>vMRcgXaKH?O Icj[Zq`ə{3 "īY#V2`rfv g'` ~32[1ysѺ%(J_{T44#9X^/ZhYMSݸᶕ5AxP$W)ů 6Pءٺm7#m YSij|!$LqK!s-c-҈WGBYIbYy<0arZ-]MM(GF%V ܽ:K'i@jK6ZG=cw<ݴو ҫ6jRhȳ8}M|$b]V8xDSPwIR.P .'}_ˁ/ 蟮mGi)bAle5nSZ=pU?ƲN8*|yW^v ZIyQ  1iӋ)*kx@'l!kK*1) vV;c&>@'sd5_#;."F zQaeLʆ-=@DK@ ixK/Ȁ]F(%& Ra *ࠔhN-kA95 W 2/ܭlE1-Bx0KtXdQ k`-:)BS1%r֛cH%ar0Yfp\gσV6YZjU{H_}|%#cW 3Y RAg2򗿄tZQ1hsND d!3GŨ;3o[IsPh+2[I܋_v2oqSZ (ùUlE^~EG`ԭc"M0,4ΒѥOFݱxٓ4H^،؝Ѳ``M.=^7y[hC!tnf Acn%򔼋\U x]׼"F̞ oIhSz'X sR?lK?L?^Ξ'Ȅ8W,7&)ޱ@SlNwaa8+!ŢgkV"`WХ8whJvv2ϣz:~%0VZ<`ͼq~UAt ǏБVxB=d2#7mݨ*EƽAsڙbI~łʋ,JL?*_me #+U0Iʹ$ZK8XJQޱH2uqC$L"*`:7&]WadlxÕC eOW?1é '- )bHәA>' gX jv.'+^oEd(ʊ(:{ o87)C^-0]mk1!)ǯtYX/Ш(B )`={*oof0겯i~:dlmzydOXƪƚ fuqc{rK;}$+$^_) Zʅ1CKvxŽGuk/nr"oo5\-̃550d::t 7(},%׻p$4f7sd3=W˰8 kZ KfFZ +7kqM6L(S on\%\5\n6us]{{Qͯ5%׬Mx%X̧_rcxJw6VUҘp:ѦKǥ::[f#:|5Wf^:P A`g3w5殈~.GZ0:Ѕ@9& !k@?Rm)4@p5őmУISPoǽ~{|4s|mUf%uDL7G'c, t8Ȑ.TR#&+Z/s,0Y1693qYEM퓳b'Дcm屚TccR#_o1&һ (Kcom7,ʱ< /!bx8qp;Ug (A /n 6(=y;: 4h*aC ~wsXxWrcb58TXת$\K'pܧۢdp(@u1#w9> B:VO޸4o` C/hAi>0mBC{~cWl`3no"/Si9F-c_RgƦvm7dWUSjʼZrk`ʐ 7FSI^[aҟe$TVFOo5掫-\NUKE.* `d~d& R~aΨFڬ*$":O]ey*ܡܢIODV] D\T]c'DqG5\M5(T1:=w\<FN"Ds@teo}zVu]&7uxBAhs׍E8MZʤp)t JX;3?E7JK hƙE ,&qdz^KʩJȋjSN(Mf7Ҽ0zH\G'xB}J`>VdɅU9z7L#F>y4c,d෢?ǃ»Df́EOUʉ]癑+:L&*j: IClRYwrUu`*0kQp%ݮyy# fXcV]S˯SNuÊ "&Jx_ߔU^MߒjW) 2J7Cf ^bmt ^!rSQED}+W^+.494+d{"4]%0oؿ0%`eK@}$JO'nеL5% .^"T&9η4'' 8/UJM1hor-$ @syQr%v`[h(-k rQe 56†RηL<ޣͫuYELkYw7zV*XwY򃳒ݞ X ʹ\>)jg9\Ғ%-wmvhH~KGPƢ2w gn0Z.j @4( Ex rъtrSxMC{|KWYrF꠺z݈> iַfo>_cCu](V3؍H_ fEz,.2tc߄@V[.LIt\acaE@5ZBC+˻CRcۯQY-~5Ilb'4GUz!&.AK=> #tpXj"DGي8Q20Y$/܅JwϊarGJ ҁ螖3`?cs(h9Cz#;Gu`;lCQ~@aUYƱ^iHY:W Pwowwb!P֥Zʆl/dž@TK~9QB{.8x^}>piL{LDp[4svF豊"Q܁onxPOP^>SQidTc42͕P8Ccnd@}n61~O%0EH=n{~+ پ3'Ϯ cf{<(Ibma.tx5S`}Z:*)Jv#s󌧃qLv~Lrcâg(^p^?R{5M)NhQQO_믡O2NֽBx3~b<3OX42ɧomǫus>caFC;v8~Ó~L/n=c)=Z]uR(uXɻ~B]Ǿ hB4EKUPDŽV : l\z%݈X~ $`K*z56o촪tκb4@oYňg~.-aTD@c`V':d1q++`ɓ`Dd)@Uh L{Sg I\F~)l ۪J {ZsJ?<VٲKVcPB1.I`cy8H P:].8XEGXsڔhyjld)~A K Xs1VLۥmU77f1ՄԾWgC*/z+;2ܐd4[Ĉx:c M9k㜒Z#;2>"ċV ߌ™zʱ]_QBd|#Pܰ 5c#]`o^"::]R#H6F4΁A.g>tٵk[d&xM~6֓/ZF6ph!~oCK rV3Û(_^R6&^#V]2ߧݨG ,}$H@7FSlftrl{9 iG#B1 -aQ:yǿa~P ! e6[Pe/u$ՄDVE{i?*6qi io}b/W7qz}=Ds&%Lgh~HQ434%뉩oBL\ȄY-2LP*ԅ4\WC BZ!/$A;iUdJ =#hw;yw \JUN[K{ed 1ۢ7Ê@]lo&Kne=% Å8v@0YV&:\FF}]p/Y1aF9C0^ c!uK eh:ڗ[RsmS`gϙT6N#@QQٶu]PK G:$'org/mockito/cglib/proxy/FixedValue.javaeTn0#N-b{VUY ZH@[8NűC@U}gm$ϼyh#he^xBb_YsSyi4&PI+X[N*YdkX` nRcpJLjA$~1 !l1,VO[xדv1j a]d ˇ1 Ce)IO6B|ؚk ^XA%l)`J0J҇E#T:* Io"+D5`oJtAwLypDNb5g${@2kʰG,&`I`e` ,1JFARe53Xp{Rc | -1#8#l8XNǹd;99RYY2+QVA4`P1%M5u֧Áay.G^]iRv Ss/tNm@sN=#Xw Nk𪒚~*AZƽr]m%n;qr.NyAYe=PW֪ WG Kۿ@5f~D7?PK )w:DB;Z 1org/mockito/cglib/proxy/FixedValueGenerator.classUmSU~n$-Emyo +V[aJ)hhl.f7O~eqg&gޜ9o9_`5)۩US=>x^.fwtv"` };UQJ;p#`Hdt,n H`f=7xƶ\~@D"? j~}q50i =+GKbn/ת=.kw/gF1lyQtH)CG"YPcC- ъgMfLV[ Z`W+L5'j,0*`I9H$[ zǻ ~Uȶ^[*B1?Q0\(lyKM28&I<<]Z[v *GW 7NkZ2.&zЍin*@/Z dJN1$h1l7$Ƈ .!Tp}1l橱o 8[AT[lKI (19:"XgXJwHn샢pFZ²Z,:mdi2ĸU.V+1 ތ` ?OaBBr];݉shoHS @RwaU@:c00a1b2aPڶJc&MHk9͂du0\ ֫%4$]w "%kQ=  }giM9&nYtRigw^3:`ӪBA$z[}s1w;1#rtw$绦]ǘ|x:N?31>"'q9p;9]ߗ˃ԧ{d*汊5,I/ɯ(xH l2{Z\@}hxv9v܁6CPBm5ҐU])se[gka2.Piq$7bal9\7IN^=NWXQ[v kˌVrƂ,-r.Gz=OY5t^$~I 08»0ӑ'>Lf9 Y;{.t<5-9ny B`k˛71].ȼ z9I)4+-I)xVeJv 讝vL1,QLbܜvӐް@Co@ DJ`g,*6tꈢKlnӝM W)vk@+ e7gb-RE f*%0T经-1lйyUmYD4#| 1tbIiyW b}+B1.ϐg-99QcJZy9ĸr)ߟuL DQWC^ɾpm CwyяL:GQM㬁~0o43謓XYYkBJ{~YbQF|EWŗt؅:vbHzR !oc"WmثV.QgJERrS jwPe׌J 1y`fhM;j` : sLohӧ*]uIXyiztՕaWߢjb1e~NZk54!sn5 `&̔ tW;"Y;zILG jKU5XlGо,ddLzt8zTNNT(aHP`1@]2U_[:2,wly)Vq*a4k{:2=ﴎSVul*1CKRfdvNXϩX2Y{Pg\CxXQ +<7)9;Ÿ\b5=G~lف- O{!'vn2\'SxOz_)s;ZvVbQ9/_W%@ưx ǕC/k¬^ƒW~fɥdX$^Wa5?'24@x eH V @ bx'pݥ~)x'F'`uX"L/F BxWT`{r<1EEV"Xij[go]Q%]+߮xgTtGx.C=1UQݯFa.o~gK^[>'a7H:GIv|3RQjhƧ6Ц"Kt(xm/}ލ*~x0PK kN:.P.+org/mockito/cglib/proxy/InterfaceMaker.javaWmo6_q3 LN=9MKڡgEQDl$Q%);;e;Nl7>;h dR"8:<|9~b˙Y2LVEŒ*'\(.J@o;'dc%+ im 3qw1/ b`Ea)VBېSPBo 0SGMܘ[.!Ry4ß0Zȸ֠J(M8b~] IZ:' 3^fkO6=l@J^t%"f76 xfr5hoFvgcڼ澵kyMQ4ju J)~On\k>6x#Z`.qKЛ{rp$3R׊KF3sƪ4VN*j{cs&6Q9v.O(j4vZ{0@obm˯ 4W\+92l_w3$f>{EQώeVO#"+:`#^ S&v=g7G=NbS,G?>jnN~& 7vܜE݆70VXnj kP(>9B~n]o]hlswPpJ[{iN#Du\)-?< }h@c* qڮChDx$89PK )w:J/org/mockito/cglib/proxy/InvocationHandler.classuNAAdјX[Bƚ`$X`G r YNW|(\b1LLp PRn_2Nr+UAW#'"\>g+?ɝ1s08&\57 :(0<~ċ>qh\6^I]٠Kw= SyKC60 '8T3s[0PK G:,;.org/mockito/cglib/proxy/InvocationHandler.javaSN@+F)R;C4B "T'Β!PZ>Z̛7o{X[ͳA%¨` }"窔)\I*p5pSjEmQ߇]iCتr, Xp \BBp&eݧE]b(QAAD`{ g5c_,M dM맪)F V2Ѯ4\f=0'jjO$i EF<¨@nftN"]x6= lJsM2I3ꃛB &wzbZ!P %S`s〝hH;zk]à1`a8%ަM;ʘN$[X7ej`=x+s3dX;NV:)Ok4ݶiP[MZT -^L֭Ue q!/>zPK )w:XhK8org/mockito/cglib/proxy/InvocationHandlerGenerator.classWwU^IAJ%U@)Rmh@!nlbLLo^wP?zLR"ZϜ佼y~w{_~p+ff&5ceMMMcL(2Ҋzkun*aJ` 'SJHSL7u- 7i)%=VRͰ]HP3ܺh戡[|0H X32w[ Pos ֛Ht&>URrqN&xg_;9{+MFDw Cсn܃׆yJ&]٥ꪵq=n +Q5Gvf9Ø 0)\4Z7îlRN[9+bkIrNQ@٩Xq=,&\^B9qT%l'dl:G3٬77agX!n1}Đb9íXv\a+WΆ ;NF+֡AvKFV2 %˯62U=C!բ;6.ngX6Ӛbʵa\\E v PUwaЗf9b #xK~ ]%)wэ쳳͊|aӢ"%&1,cSUfaL!AeV3}wbݎ^EϮuǀ>Ty'MNЛxjYr) O1ɿ!=O ~M < 1sxz> xmHmJ& ^%\1{ Ҧ&LNm1lQÇ0mRǝ9{܉O7$Pr"vZJ7W(M0kH)>kdMg%#ˌlU N4j{ O-%|0>8=m4NE-d'Dy_Qi@J#^]KxkjPK kN:ݻ! 7org/mockito/cglib/proxy/InvocationHandlerGenerator.javaUMo6W |U=5؃"+^ya9IE!PXF&Uc,w+U@Py =x)4|զ`BpKW$zE4L"Ly ( > \e6 ptc0v5ہ WXjR. DzPÐfQBIF`gmvuXؑ*j< s-4/xJn%olÜZ¹ڿ~rrcYGT;Qdv=`VޟJӜo3Zʆ[Wm$ o-g,i.PO /ۦ4j; ΃\]ׯ~bUHP:7OK6K9df3D9Y'GЛl-IzNxɱ,Ꙏ&2݅;ig7U vh6(zuǓzs.,n 0ډdlļ?UGF$!AE8IG,)2V E1S9);Gj s⤖,E)8˭E"{\Gf9G_4cxL5xÊOYu;(Ӑ9vqzPb4c4l^C26|1&6q wHǠ|wb|֍ߛ tʺ3MB PK )w:ϟǷ(org/mockito/cglib/proxy/LazyLoader.classuK @D/ĕn\]\x81b\x% z e;r'uh@+WdDꤤUI(Alt.P& @@/ Loa09햅6iD w̴YE%T@sT!`j1&_s PK G:tCym'org/mockito/cglib/proxy/LazyLoader.javaeSMo@+F>%Qzk.qGEl8r\`a.!ND7<9t{2\]^~ClEFDNw*NjEFf,@h' K8x4;f'PAg8Ba@*tR :#K#NrAυ 䚟ʹ{} 8ԦFx& r=Uւ4rzђLd=h4HgNH'U;&<ȴs_RLR (7`L NfcɂIr{ moC,+.)3pdSr/ =X-fN~B#h4\-̙t~9}PPG桤FgGtLuDsF.j-rz:ZU 2Q)Q]J3BІ0xCX߱C[Xx x^9uFy:ٰaT]sxҙlV'Z+Qz54wl4Q/z≆ qh<-k͇]_|b "EGjOC"7fnppTFL߻~SѽuPK )w:^}RDA1org/mockito/cglib/proxy/LazyLoaderGenerator.classWixW=O-YS'QRh;XuJMbjq뤠xf.KQ3nQ]m!;}YD+r[pԥ9#V*f[~ (iRwh -EȨ&M-cxVp;'fIEc+*!<+P=nF*n<'V0q.Y ҵFMOUx)S~W HK릇@|đV :ױ..K3!+CA\ 袻츂W ( ^Ր׫C :ݜFĄn;YHxXS+20Q¸K19ɉ@u8-)82o.~<UdVw^|Qp "-9T3PxyyF tcjDZξ呴̦QRw2XqN3S1WMMgd^! x L[B غޟՍLA3_'x1\[*DkLʓM~2Jv)x;_Nq)nG56YHīM#% Y-ŵ|v,TAo`tݦ-|9Z$WGވ7ɵOy7Qrq%зL2TVihxTy'kA6-شz<xTy7Ӹ^/Gz4.lMwn?vKe}KZ>WkL4{XM4E{e#xXB>ZaML6)8yQ=V4ڣ f=(սO# }Esr'LivOKq{"mc͊Edy8Q͚ Odrvh1P?}- QPl[nҗ$EQw]g'Z^XeG8ypsTGO [QUN֤NAYS?#c^"w@o <m^ew;~_o3Pc^ѕnti\; wmo˯貋{A.GdQVT!C]ugdž4;?쳲vR;%fS7 b7&ٔ)k QBM㲳>oUWls=6xʾ;(DBRs[ZJC!p'NShh) p O ԆP,Z|hJ:XƾYtpcC[@(C|<7"s !-?fL9~|8gs2T2yhGӚdsN*oUYhחSx5ʸ(_<&myL9RΩ#4U C` N䗏y3b7/#8>?b7' O3kyF >!ud9|OR`|}ܰ< ,X9,Cc חk̠r6 p 5|nm̋5|Cu;D9 6ً-:OSS(‘$S,yiGq~%hy&˽pGyN98]0{:R9_P39T9 PK kN:ٙ 0org/mockito/cglib/proxy/LazyLoaderGenerator.javaVMsF+ĆgS\>``p!-B R#f-fI# #qEL~cԀOtx06 nBȹY3p+31å +k}m7*wJ|v/Vui12%ۂ25yS\@(i™,r?%k1&%F6fv0&Y.Rŝ8;} Ozg(qE!϶RM+=#-↋ TD\g9PmGb ݘf7?hu7c `8o8p@oLp$nRe# Q.^x@a. J:ŐyH8c1B,WE)%6F&KnqYGlqHiw)gn eA2𝭘U+n0<;ަXY8 kXR+#=*CҬ01Ծ66Dn'@;"ܠ.5czAN}l!;٥UvpLU>7\[d, 3>g/JR#@qc42ZoڧJ$)?8PpQDKE_.<.rY]E'j <.Xq5ØB*&Gtm}Ncei+W&cI`J')K?|6hk^9_| Z%FW!Xa=hZi]"sWqʼ+Eqˀ.,"L03 ޗCeLcNHE IDcza?uǽ+x>%CmY%vTXNZ_Q>=dݍ[n!y)`uLk"cinKFإcx>RXN>MT ܡR*d:\*wTsS)v xX'Ւ@ύsc2%hP |Xm(fT]}~&Ɠ2_AmL2/PK )w:gnr/org/mockito/cglib/proxy/MethodInterceptor.class}N1寀hHL\ YMH0UPZ`|5>e$&|i=o grziK9ʵU>0af P[%39NF*[\RN:i= Bq3="A풧_hRwpw*uFMhe9K4SĮ֙T#4ъ]I9PK G:PK.org/mockito/cglib/proxy/MethodInterceptor.javauTێF }WFvZAa:ui}K<4Ό,;Ah,݆<$tt72_;zn?b0DJ^FVpR+bG ST34N$X~܃+6膣1RAiEV@] eUHRFPb0 2P;dڹj$Mgk'Ekkt>^UւkiDEibIm@iN1IG`I\CT&tGs̻v4#4Y:Ot1ab2{M?88 W@iJ3O,nSr%S*MrE"Дr_-%1L!K88P!7CLǥN78 +waxAFUm*M)}/XY;(Zk ܻ°NAd[ 5ދڭZފB ~BN)uߜN ~1r6Q U؊h wOɶ}u)]n0r?[i\ƴ~g&v2dgPK )w:a:org/mockito/cglib/proxy/MethodInterceptorGenerator$2.classT]OA=څ/Q@AXZ`" JP IQ dvnQ `0j_a[#6;̹{~=,3:n٨8,[hWƺwҚ >p99Ɛܰ]6wk2L5 ;+ܲ0<єwXv陊`\=H AmU_Z:_G[ino{L 3 t +Q/J[K :ojhЈ.t#>T^$Rʻ(La!jd<՘ )-aF$[DS)5=Y\O)JOz @RfsG8op5GHNh ޣ5Dָĭ؇r[܈Əacpnb6`-J P) +ϓ -Ud}.E(;yBvH ޖdch)2/PK )w:c9$8org/mockito/cglib/proxy/MethodInterceptorGenerator.classZ |?f2`1B! ZB 4 Gę k[^jEV :I8A4#fZd)h`o_1iZ9_=V|gZ#(o ƚMrjR`9הnGc[}.`BAqCJXhriؐV\N،_wAкFlCzDMʝJ,F|-5-?"ɞ6B-Ճ-`b/&p ƴ]3!6t! ؃ 0v(?j@Sf_? d}Ϥ4b<,Kf mBfҒImSǬ = 4ץ;91gJ[_VڶN 7*7\&,oIԲY(ʘ{a_`+5<3ӐMn;d ve;y>;W6}*s~"HC߅Ud`:=QT.3HS^ƒf(6\cY D+~)8}wھisNZG:Ǜ y M)WP2!5)| +O䗍5byn ̒4O+lBOUf **t$^Tl5d,VX,P>Q^ f.5:T6f*&5mb*m fRMwE"Quv4# h-X}i]ctb1z5U]O0OBw2̛@1\bBwlU;-hdmL϶,M 2H*\S`Ba'H^EGFe&6I7AK;HlDc ! ?W5+ 3XmW,(VIje_k 3 &~H[XƿShdNV)Ay:|*&>I.&>Cd"9nM`@l ٴJr>cۍ7Y"Aqzwm2dk#H'.h[':)8}SجvX':>0&0zV#BgJ 'd9d)TM4"朴lLSrNPRxY ؄Ѩ0]6y]L^&KO%l̒`]1|S6G1y'\ry@'6ҺGqXCNK+Qu%9/RE\-YKYKYjS&xtڣԘ\i**;UʵR}AO%,aR*!Ѹ\r`[d4@ӣ ,Ycd:,֥\18|W0,iѥXZ-l0loRNtIӧ԰ c+z@*ě-7QH%>cդ/)D@KpH4J>5h sbvNLrP^#8QNffK&QEaen.\k I"7x߃.,}RSg\*vs Pd\O Ǘ//`<}BZ ]O7-*ysF3"ã+!LupAr]'}t 3U˼X&ˆh4u} >4f,w]< ^fCPeަvJ>mJaҰlՕ-IQ_O~c-gUo5: XI[>G|iIE _TvQ$g',5P~16_8>"hnRny=t*YA] S? U9*C+[^IMeK~dd,͆Yq򃦲LҟԢbt6*vĘ2cD{&9VZU7ݡ~T ۭ]vԙ񌴀̷H?UYT+VSOΎfe 1 x&*1Nhr5Z|H:b`OLVaKu7'j"o0e]ub{u~xvz=ø6W & Uc9)Spx݊ysp7/ϧ+ngB%Xț%bd&AxVqnJ_y޼)S~nƷwirVCm|7./=z. w>G܍yx{#!6Yf'kIo8[У\)? #H>+(Օl WVD>ؔc;@a>^<0%8Ż).;^:(LR[dn9KmRBAM"ŷ2'ar ј01Daɿ?q+?:)kG&g2 FKp?i"#Ҡ@E4$@yfB*gIY7|H*ˌ9$ 2_0, QPuKEaZ[ \)>4!e.y- ˊ 3]>X]THV'r]2Y˜9^wBꇤQfS~]; YҞM' qcJ!6|Mȣu@,!eAGZQqFD;@9GSt^us8nXqe17Ki1r#ZBƾB]>;>泋[l"q+]Jibͥ?:DX;`Hvv 2ϕ>Q6*y+I{4c6 'Yb;H,>͚ ѳ 簚k E"5@l/Qϗ<=]C\x>~o?~ x[۴iwhw1S|CV}S~KZm#5}goHƏMj Z}|A!̄e澳#.bϸ: bѠaYAy\Qrf QG/3dGjVc2q[ݿR;&SrMnwl>Σ ht uLi7Ur օQdtʝrOgBH>uCz+@./G̾ByL\(OSB }\$;o6qޙ]wP^8,[̉C49S'S'p:}z/S=![( Ϳ(&Q2PayEY:mYD1\|6C %̍elq21pZkas[:Ӳ1zrr M$3PK lN:! i%7org/mockito/cglib/proxy/MethodInterceptorGenerator.java]SH_ѕe{w#jvb]˲$=4 ${6U>_}aerEד[d877Y-L60!q8's$CB'&d9` 2@O[Ak™MNFED^R(Hi8 h#Xƃ(p )|[BjZQ:l[ s$["ƣ3q}[5IcJFi@/<7l."/ xj#夕u}-/o>݂7T,F`%O6rb4G5BxIE֔/#[;^*ϠMfn=#w|Aw*aͻϩT¼XVUI!7cE?bUl}RT!uARMXX2!2m3Do7/"hhwCrvTq#娬Պft*b.g6 1ۅW4sHAԂZԢo7\6ųW8fÞ3rFn s˲V|45 Vf,uc$5KGET]ɓn/h q]4lj Y[KZq<0_' 2fy( (IS$Uܼ@' nh8\$2 C-K1l"]vVfB f,7{Aɛ fPS((?XS>PSoX(7epa_(I7jFÿ2`Z7H87(d]Hwr*?tµ;UxyY ɆV*o ©vhVa"IŁJ;S$is@ WJc(W.wjN_fz|<cٻ0G1Q5xhMUVRn\{ېbh` Km8'ZSn\`<ݳW"'o]> /o"PFw3?[@.97*\r{5J$2ajKNUmZ\۝E}msODH16y!xw8k!xg/%Ka0\JbQuVUJFs:"׺DPK )w:X vN4org/mockito/cglib/proxy/MethodProxy$CreateInfo.classS]OA= ȗ|KbB4$`v;n/wP5>?xgi&;wvs6Pʳ[=]/OB7d̗J8Zucj:;pB~Wm W'>Dd0,y 0])Nm6x;25\]K#X[+Rb ${K;Z։.IFwׯH:3PBd+3B79ƑG 8g; !%VMݮKb<.vfdjmy,p&|ֵ|xe9 F|~s :α!rL`3LnEGyL1iJ Ͱqוl 'tbP.ʚ`)I *j ޛ,.(wZUz+CQxO(X$I"E2'tr5î>z\wa9+]hu3q982X43HlOqUh֠|hbX@@- 26ECcHPK )w:%o7org/mockito/cglib/proxy/MethodProxy$FastClassInfo.classRJ@=kSc߂օct%A(Oif$JpQ|`3=wnι0 K ڼkh72389 DWÖJq'x 6?mt7Ѧa0,Fa^y6GoA$[y㟭 y"N}䀡oRw1Frɕvh%Ѡd^2-UP7%C}ED#&0k*'݆so#_)spa(ԭDs  e8b-Zt=`'dO{LQt?<|Z,ēxS_≏b&64f 1R~? ˩+8lZxPK )w:͓o)org/mockito/cglib/proxy/MethodProxy.classXeN&ԶevI(*I[iڦMl-*elIAQ(rLkA"Mi/fi}fy97yϜЄhXgfa3~(ix"ḍB5dt셦aX(K'B]E%ߺ6+@\< Qݞ1bё4yT@{,kmOŲY g,):keL23^,("/iid& kq3cztn3ݍܽFd:iiaI0>pv()kY#<;MF^Xd:Q֛r V :V *PbAbeQ}X+u,ť5*R=@( >ԠQX&5TY$+3`d㳳P MJ*!)3xxPiѱ"mUMW[}>WmcbԈ.*Uő+P~:cd'C7T: vaw wh ::U°:Qs=qq$U//x{o$+xP~{dևRެaa]Z\_UT9|ES، H.j8'FH,[`hwJ8$qP8p,CfJBK#-A4Zȍ#0s{2#de-N`#A\1( #.!,L>Be#%Чv|TÎ6gO?]2-|JGՋ419Z}H,|%kX_DF̋R˛P 6t|8NqUW`223g4>dy4nXI3lc[4\}Wmx"Uokh0ed̸n+5#@M]7GFw_>5~ㇴvT,c8,4\_l,Fq67xLyL򹴼xE!:ĺ_|k_''C޸3IiwOjXV_h2Źŏ|fFrldĐR Lq;X$4~,pX'b5uKVh֨@59,t8βJUO}8KU'm7 3W^dFݨCH?e8?%94c &|kKźJ;|ԯ[nx; -/kl=Z7Koր 7-rXD3U@ZXH.ܙgy>}/U%rdR{c0_<ɴ72_~/zQa{Ri#5YŕWgJrqV+/\ȽkD y%VA-q}*XRU[5u`$6Lo?zǀ/mqGQVsFD$!r2nwcbqs_;| q*XH dzs9͎q/W˶_—^3_rG߉ ݅S%u:r? kl..v|F,SГTDOE0xM,aO/9C!sxa /Es?wI Uzj݌q6ӂ2_J{KIQ̻Urbhʫ0qNq1Np'5y x*|"[{},;UvN+n2T*3հ|[zO*YJVGpiJzu{d$!?N|~|rv7{]O醴3|zzmE'@5ٓ/朷THSIox"RъdLsU`ZhF$&kalpsF'2$,xŴmx^&VS7766qrnVrH6Ǘ 7KUδ\1#+\Wr=1jZ4<}ahw쫴s̔!iwb=s SW(>MSA"r3`GW3 ^Nٜ$ Iw\+n[Tȵ #F NaG#&Dr/bHQq/CΜQ^I'4Q4ΠH%L_D[UN,h#UF^Xl>#* F}pG~|+~9Y@C 9<^s. ܡ_(4j|N :Ԃax4t$`c'&mW"Y"Liϻ6<Ԩ.R}n-|P4>J-Am3'D'BT/Ck,k}@islWD``88F?ާ$mcS2H(+q>m>IC_zsEeN6^Lގ .:^hEg '7asDtJ^*9Ld-;]rJ8 = I Dx0* 'rSQd]:n~4egqOֆ& h}iXYF[fogz *_R8˅GZZknP^dv,#b]rhYB/uik;#].MhQ$ ̿dy1q$AKɲv Qz۶@;[^ۦ{>Ju+ʼno/yU׮RcP w}.%rCmgK5*d4 o|klBM ]1ۡS\~]J6$0p쓽~k>{jc%ػ"ue!~)y%ZOPw)\sms;m*1x7ϴɟLWDŽTZْV^UIh>Ph\ߵ{NKjOˑ}lkuRH4檄IVR&ydnsh66-+aBAݳ&Tq[멩ƨ2Fdֽ.4ȬE1sRe%]=! [L0UPWRTa)Glk(^ЗQS[%F:Ɂ5'; ŗn)ӪLg?{?.?|ͼS u="?C 3 Ld4NzhP]4'Ė] &S $ۯZ5gTOjUxwG,B Uh(u ڥiu^$+XŎx]:ac=8 3wc-67;x/^?7:^FZF`f ޛ(%r}Q =s `"=9~+VfpW+!Km[@JVab܂&|=PK )w:UAp85-org/mockito/cglib/proxy/Mixin$Generator.classW{~&d7` &A6%|i0uJ 4N67LV-jMT@!_W.tg޹{{νo` LgN4=3ɚC=1ٹל0=ҒNBJΝCi+knɒ:Yw76O1'-hhjE@cA`ucdM/eý]nf[i5!]rWgְ28eVf O Z*L{zY@ aivD{fڈ ܗ9cJ+Rp[-P7i^{ԪK2{Pc@W6%v{ VD)lh*CB,q:̕^_DO{"BOV98ɌuOgFۊr}cZ]cfQlVXnNZ)+S;^F0(*^1s[Uoh5+O&'*Pv'v).\?6a7S $QNHU,Pti GRܦCҎ4IW&` y"N}kYN<̤ Yύ^|Hig [3imׯR9 :05h8Rܠ0XJQ 0Xܨ ۿ+dEݨZ#YgfHij͔}mUT3[bD0Ƚ }2mrÑqJ۹Q32~!+F)S`t]3c9JqYXX9gZ!2Q?k[ЂOְ8o{ 4xcI##8Gr[qz ?S>9:}:P)z'Xc9bNxJfOI#9WN/n4Q|}+7X~</ ̷ KDOV/XWy’}x];o*J)(kIFLpHw܀a`k#JնZs穓mVٔ B;3*>k85%i t,>XW-ҙ)P0O׶1+2kMPT3Msʌ2ԼuLDq1mv7mKgK:wa_N~1U;^ԤLK I'т{nS}= e$yϋ{u?[~ `A _ aEuWvo=v-69{"me$6NbV^Ͽ"iEhO>8340A}Ӹe;`{w4 r-XJct80A<هZBC =N'8C<\ ko-,R4Ga%.q˔b6{ƂhuN?K'XwAWcP\qNNIwLc)%s{Js9TmƎVr:mJf6bX0= y_A e$;~<]?S9,x/}N4}xy"$5: פA7~r23$//eGf&8"o)6dfU8i,L<4i}(?Bby|ı3*ӑr+PL-g2q|ySR ezvwn"M>ӸtLQSAQ>硢 C!hzML߀6gY¯ND5r$crDGW_<*sn>Y4_#i4,jPK )w:n s( ,org/mockito/cglib/proxy/Mixin$MixinKey.class}= @hLbTv"jbReuYjܕMPb) 3|&`^冉$U[vzc+uU_B<gR= A3)o8.dZZ^"\ IxElrth Ɯsvg\eCh"@iU@=PK )w:zOZ)org/mockito/cglib/proxy/Mixin$Route.classTYSUL4 G%.! K%F2B0 #($ At=fVj|A^4 )|*r{Yo03,~Y>-](1Bz NӘM{y%=b,V˸] ư?& {* 1ch_,QȠ&w]2䶑ܜ[h&7,{)yoE_j!LMjžgJa;?‹*ch{ {WrKW$w Ic2[An#) ́Z#b$)NҒ#Q}eb% 5hEbTR!NŰ[a^ݶĕW1Wp{&ұHhe2MD7pe媛=Ϩ u.!NMOǕu<0V}Vھ ed+?Wb1Loa H"R #W ַ+-J$05L!>xÿ3.Gь ^'$8HSxt{!'[ EF<)#̡@>a/a >C  /*+5 oЍoq 1a<~Ƌ*~#V /B{0˹IMF߈.XKRQ `aw}qU>ZؿPK )w:/iQb #org/mockito/cglib/proxy/Mixin.classVSW.BP bA o$%eYKct/5 =|qͫ~ *p" zG3bZZ$%AV*C1sۚjP/w=-Qzhp>z6L-Vއ&RֆsB[! z%<ΌG3SYPbg(C4D1 'E[7"IeL62)"^삶p*-EMe3Ԙ x/n_MpoAǞ f,ڽYSe~On$6Է-Wkᗾ;Z"rhI=8*- tv:WSi6n:QC)(~KvjqBuU7jSMaHji7xf Od 'TpQR}_`J.lFF}0p;6Qg5I/RӐ/M oе$a\&!N2zN  k ` ?|Hp$U2Ir/{|>'~Lb`?k71tlZG0\ &ֲnp9,6dhfČ6GeEBCPsi#n֩>T8(X4XMe2sZ0]?m6E nrjyx96=Y<~~^^˫n_5h7/T>$B?ǎʏ|JBC|9Lnä&Jq_j_}Ʀ_A QK@Fb㴗 ^@ dzĎ n dup o~IWlrLs\L(1L9AU%Ka7)^GrϺַ]e\*%Z;eq.]øQ%d|ݤc(r+F"KL:67^/\t&I t-:*?!/˲afU®"y"tc'q62}yDʭɀh il`5td G5bs'hy z_⻧P:=lcaՀ_X[ik?PK lN:W؃ ( "org/mockito/cglib/proxy/Mixin.javamo6{~k xra;uSN Ze.QToDɲpYN{x@I?I7KINց??钑^JxL\Sys*y"K8csLY"D?&V}46INVtCDS[D,~J2g>&s@r#G4>ķe  7A2gx~E:UIBd$A cb0g<>P9ULa}>Ee20И!*. 7$ ,1jHJ$ڠZs贬l*Ms@.b3&Buo(}4m瞼?'ׯO>93CJ~Pާ3 |YC4&F:LHq@@U!7_{=Y6;? [b!D7|}wu829Mm_ [m`)lM.hm jm+dd2|1h =ݠ7B|oѯqb$m&iaۿ= zW:@!$V^frAM@/ڇ *ZƞY.] mXft*p A1qձTgڔ@CxR$AS+):P d;- bt $зPӫWw_&` 8W-3҃7Qg  &s+Xý3ӫ/LJeOѸ Y8qE}V?>;Hxx(K(^&'H=:|ItLzN7 s{,g bWn;N\&WD}Z7i?drDW.Amlg6L@z .ls%s<WCVxZkr! #:u_o~3B:Q}礈R[J,Xq3uÞQs^ P#:R=϶`fwsm&z"YFԠ*$~-5BW>_p.ENUx|NvL\PNp ˗d7TOpϊ*cP*T&,Ie/. `?bq((6dnL tkB1^AW +uVH[ϒwU\^ToGGOxey2xv.S^bUKŽVKA}Ϥڼq_aӓ'FۗJd6>)Bo+KiC\[;vtk|o 2v&>g *=6ƖwNs} -)/F+wD4oflZÑmB~/ Gb06wQ .2YDF& I8sP+>b83b`zF=?<+Alק;d3 fkrWxۼՇA,Cz4۸mWnujCpXB fCi.U8Zr岸> Ix5iE}kr F9xAGHAx 10dGO_x́m)H\G-rP-n,| bHm $:o;+ty4 nC)%K3o2L51RGGxPK )w:E l.org/mockito/cglib/proxy/MixinBeanEmitter.classS[OAN)-]*ީ(KQ6ėLD4$>tvW$2٭>9]ΜwP u'eBkvuxsԩ ^Ilt1RA9F_(N!eE1uu_DQSEz]_mwhR1$:K"rpE5G*"ڜ:Nѥ EGʃ1@yyLd[̀ gA!MFt%Qxh=7/}w[^Ӫk;Uup neo{{T *=^ϣ4m >~Sh%Z`TCrӒqvc7ʗE|0.|)} y% bL,`WfgS(;+̒ \L }<]d`|yx,yH+%/=@Ю)6E/$T+H5SٮƊ}EE#(.(cڵW)aADCj |C7A|~Bsǔ4e;swGy-3CH *i ?(l]\sdU+ε#Hl%?>~PK )w::$*org/mockito/cglib/proxy/MixinEmitter.classWW-yde*T)M \KmhMcNlEINj)N\SԱ<'Gh,Z(вvZ7a/P~?^xxb(zݹ:;|gGo5Oy+]gv>挙hʟ_ 3`ضn){%3yKrZ**h䌶 $⣇CcqQif6- lM wƏI|ĒTH_CCSw6%idM.Y:cӉq7kŅhj tb<Ѫ4AFV5[htkR`:H]*btP-E`sV&ٛ2zQ`_^CWx nm v HPGwc Sm%i 1g 3DưM݉ O`YҙYR B6m!tNUl&0:YJ/|~V`dcx'ATj1fo?.5u"~COfԻp?3jVg@,==g9:pTjϜ3c޻ K,(7U:u]mLg**Ġ [ sym6m֐$~ b[i\̟kSEQWKЬ'#xH6 %Bp 8mq\ [N+*&\ IJݜ⤻f+1Ǵ|RSxXc1 ݼcX\H{ JW 23_m tW}A $jumv-{D!}ZТO iqZ^D4>#>GDY΅s'b`Ɗ_m7)H0n@A&0n>sHF@2g-3/nႋ΍()ƹ巎Pr[Enל~CɈ:*#ӏfXۨ=[gґtđ81812v^WcM+R5j78s g>s#`n`4Co߲VIy1>2䈟hI2 dя9YU-`'xo-h;g w{(=Uh w_"\{ʸ+2zVpoѾ^QF_س.y2Gj-c,H2;)8uSS1ګk/pO@_Fhy.@g[eLUAgJ7yo@)}2>V'gs]\ϳ>2|+ 9|"DFy>a%)9|_)N^Y}/Y} &|^!E|q#?X7]Up~>qs88>Vx?4i!  )org/mockito/cglib/proxy/MixinEmitter.javaV]sF}ׯ9)NifZF!x<"Y H[,s=8;ͶEK ';(#BnpIH$K.% h"hx@9Ryb o5Ctˣno0i+$ Ls@3 , ]e1#I@aR)Q,qWbsIМ W!cil,[)qa+x3ݺNb*p5gCodH+ s$ H)Tp&Y JNȄlˆj;{u# tG>~F ֝~_Ov40=ݩ;pu#vs(j~sUH)=i)mPX%р-X%QN" Q< |ńʫ@يI]Ǹ~u~R8J'&S+b62>oJG&rkqi +*i8lquKʲc" CFmF[ bAʩ?U'ɑ{1U^9>Z~䆧pŞY$rK5Mu/pt̷sGZ@o`%MB:淎*猳54'!1XG ׹Bt;ΧW(!2ηڞg9>vVR^c.. yFw<?f?GTK{n,-ҫHO}͕$>e27`?zƊi%ySo]6TVebw_J-(H[b8YeP^FMiL*:Oi[D(f8^9MJ4m Qs'8v6~OTCU+ۍ$z8XSRաhZ5NP'% ~Q/)[^}[՚IcD[ԶU3} PK )w:DhK;4org/mockito/cglib/proxy/MixinEverythingEmitter.classT[S@"P(Q- 7Er.e1m$0g/2:>gIJK 3Iݳ|wݟ~0eiՌiCl-MNM7";˭%pnI` =gy:*D]f\d30$!5;NmV,ME8"_axp+A༌j2Tpa(o1]γ1|Vpr} IBKX4wY"tשWPJi:iYZ.!lGE/%mhg.O\7-.M2!04iԤaUʘǼ.e!@'CC隄.j-rOf<u04 KsL/9.s$0-.怄jX OeIl)J8Zp /rz騌>Q ivSvbŽ{2>ehu4\bafcP2$͔ܚxJ%{zmk{ L?9W$r wp~ Bϧ52a"J|V5i`!wմQb@/YHvvz(hb_pk=L$#xԾ}W ^’ CbsDЈ4x^QaC8PK lN:(j_T3org/mockito/cglib/proxy/MixinEverythingEmitter.javaTo6~_q d%0u0a2DN-e64m~4Jt$ \Wl 92v{n.t VcR,@4zKXS6;ht [ހj!,DC J rp6O<ƇC'wNcGn`ƹ,=-cMF|fu$Z ?PɫxEr"AA9ipB!^ASXjI}@qGqIvY}f 8]& a~IUJ g I3ʃ zbъ!>%[a."TY;4* VX_-,<[O |qHip+V}h'⥍O|ǙO %掽EwtAdxCܯ;b%EE]xGmk|cCR}'qlM~^$trAġa^p'vO+8=9;y}v3Pw?`qEr3KU1/^T<%]5;uT-[1Z)BlMPȽw AR;}hG %D5tISH=M_Abcx>_~T"9~DU |9kE,TQ܆-Q_]m L#sex=o IӍVM &,c۝e#tT7#-3# '"IKdxy }GBXPK )w:$org/mockito/cglib/proxy/NoOp$1.class}P=O0M- Rq%$E𳘐(K`{w> O8rE&N= &½N!_)ri31IZU!|-BV2}mn4F"BPMI8N6ɑi qJSY.^b.ѭ LӾ*wكnF(eK\4y`YxqLm>8L0=F}PK )w:˪ "org/mockito/cglib/proxy/NoOp.class}_K0O]DAŰg Ea0 4-kFۉ~,APě@r89 c|a\/sc;^z` x܈,ddp_.$B=l00tbh 6㯉H3]0/.ʆD'nm5l14"#xHT>I0\{L82GF* P1CEF{CCw_?{[b!{5x' hWPK G:БoE!org/mockito/cglib/proxy/NoOp.javaeMo0 DNmEw[a^b:=2U$OE(Z|{-l^HUQ8;F B *c@h,':pIHMevb YCyhFg=2 J0*>J4' [t=oA+uD,181grUV3~7xzg,)jb@t9F6`N2`i'޹ ɳM`߄Y^AQk^"<o ܻ0c'6Ѽ BkHGZ%y4 Cot'Np NQ\\QOANwV>)촪edmXLJfq#^he`ea кfAA dJp V }#m8@Z ]j;|%t+g -K)rk99͙-hSi-ms߉I*Z?R&/+^p?PK )w:.ֻ@+org/mockito/cglib/proxy/NoOpGenerator.classUrF=V,$ 5-$NHiKkj'%!-4`dyq6Q$gQav>J]&xCw{?5Yp k[)WZh۞^sor{fz c 8i I1~ wFB2NSA0hԖW* g}1*3# ⪆pHEC `]ڊ6JZmcC(WCQہrq6G)D /c/k8Y|OIw M*Fi' # G=Lȧ1*1ui8\yi`-HXEC$dAtʓm~ _܀M"S0$8b3 ӓ1b_Hqv/#H N$[a _wTr[T|c_%ͺ;WVkZ!v~{{u츛\|p<=cmZ- *w54 QF,ZCBkAkp} [M.|;&(o^~d90a1l_528gaS, KѨ^T]˴WMO Ȏa*^ko5ױn۳ !?4áءܧ IG-'LUUb0)XJXl4­*e,WPws4< vqGm_Z.ТfVy|:B9SѿT0:R ʆΡnPZ"!eLqM4. QD>ĪhOig7Q'iJQ{) 4};ؠ] Q:jY>KS_3Nn׀PT%r@` ;0o/ܧjVSSUhg#qVݫξה CV6MwTGu n*ÃH-,AҰlU]M ,%};ƀ;z(#- l$w% KU$Qbt}-Lf8D.XY ی_Ul bQT;?PK )w:?q/V #org/mockito/cglib/proxy/Proxy.classV[[G~@DJB Z`M Tq auٍ *=eA|G7 bw2; C6#j^re>y%CeC芑pՖavv53斦ڦӹf:&kLt mWp1$I& SUl4fcEVԍtfy.Y'mᆆ])øێ c<n \A^UT^Fиpc  S/D#9_k2O (c aZt:QֈG-VcVXMT)ڦEI/ H 9C;e̋-wCoj8SLÊSM6 |=IP֊UWE,QQIыN-ʸ{b,344j;ilmm^Wݻ]2lm״,U=9tjRVId^u_cUGjh>.X]r_Q &V-`Pel8մ8yZ׹-%jY*̩>l )Mdcj~넪;WB^zM}A/rIz[_,Y*?r S-/f7]a'ڟ- ?>wL2@h =27wt/q*4~"&|Mϣ0N ଄qoh'à%2N 6W7p<7~D6Y^BӯzFv{28E?K(+ 6[87q1=p}N!/] ~iv=}P/7!' 6dW .@ ȷ!s* A4PK G:qJڟ1"org/mockito/cglib/proxy/Proxy.javaVmsF_eAPaifj:7d2'N;; $B}yv]uS| ϗI һ!K sϫ.uQ Q/\=88wC@GX&hm4P[M5l2%[َ<%`DGE}QWCZ*_xRhכWq 0%55Ŝv&j7hWHUe~PAnu:NV2Rfat^j =i+5V6cf͗)hN*LzXvQ~v^vaݟ`'27\isvɰQAtFS?ډF p=Yf*FR\nm/3ڛfR)N\ W`=?l<5*8z4Tлl7j?|~a95n ^BUzhr`FꊲSHg}kFTJi9Nyj+iIBʰW*\i[euVtF8$hh//6ߣ+ .@$&JpcA5}8Ȭ\l?.w;C7=m}?PK )w:<#0org/mockito/cglib/proxy/ProxyRefDispatcher.classuAe(*AaV$'c l^M<(NݜzCбQwVnul yϒ=W>"k1'|o҄?@ en#˗lMۿFgX=CxpH6*KH!G!(InN=PK G:/org/mockito/cglib/proxy/ProxyRefDispatcher.javaeSO0_q])Z4NMq.lP!gUʇ~_wJG-WW˖q=w9BIjp=p/8J9jpߨ uEtg`KqT4RY 0P_8Lr^a< YFZz+jwUֶyőe\&OVMBǮY1o'4YΎZYFbkփJtfka,`B'juCjHrct ߗi.c}r[n:VmOz ~& eFB L\5YvD(3jIEjH``j| |p8t(~VEEZ/'xeWkY7ମ3BhG).ygF i\8nM(cˮAvJ]FDڰ?me4}E]0_dʼnH-*׉>]sءx)$A[TW#Hnm<3-s~]# xgןQe53;EY5E l, 0lzbյbxxiXYPK )w:smctAH:org/mockito/cglib/proxy/UndeclaredThrowableException.classPNA=auE+ V<&&CCfc#d]vȰ(6X~qv!Dp83s1ʄ}6Rޝ@X#  PH0 "4*=먁<~Ӭ*6o='Xg2Q_uc<ْުXH#GHGC9!٣EP\yhP~䌤ç`y)7_B(Aks+Cq5^ jO\@b ҈O omڦOlXN{&(ll$* 6hj; Cl!b&ə OK+g.YXJX/PK G:w9org/mockito/cglib/proxy/UndeclaredThrowableException.javaTMS0Wf0B[& GE8jlɕ8wSTi{oWN#8V+㣣_>l0[f pi RFsO+%Q;́7$u;qGnwp1JlA!c(KU"FbM4HSեZ"VN{,Hpߖ 艵_+Sm86H]Kx?0맬.9Q%/ j%łɖcAyZEJp'WZ4ʵ'}?}z Ҭ,&}gp3Nf85tN'v -|O'@শ^TÕy+ Kjj$KE# ܡլjr T0o]PElqeZeQE\[ٞD3b<29~A6KCnטR5 $. 5>w"c%s.KnV>[Y>:MBRL4boTZuFa?Cg5󋏪EAhlyS2 A|ZJx&)qW" N{pO@S\'y=>KZF>Ej#3cPK )w:ߝTBorg/mockito/cglib/reflect/ConstructorDelegate$ConstructorKey.class1n1E% (st $ŞXkؒ׀ZCE!@=͟Oߟ_x"bԦN(maX1v ~6e?lD^ #: S/{%. җв|E$b 8ȃ/ޒu!!+&iϬe?6,LQ Poog{fPK )w:B=org/mockito/cglib/reflect/ConstructorDelegate$Generator.classW_=/& ^0uLj0-F33#ۦi6]5]4]c;7K6]zތf4wvw'm'ڌ)-k)G2uKuۖ9yͳԳ7_-Q)B<َAUMuˎ AmΩy;E@};ԠuQ(yg(=_"&eL60:+pݸwF`G@hDOo_ZȵYΘRe,aMM\NVTѶN2ɖb[#j[t+Qva# j9u[1WҖ;K;>I۱Cc,5Y /p4rgюkFRMj)3ls +{&V)h!nujyғv{D@Q5Mw#GqNM^CMr?)Ppi KBl+ L^VBM،SGCTa\{)5oYՌꌯrlYNy dd"%+*_3\CeL`~{8M_Խi;;鳞a[QJ y D 3eX!rd9VCxHA}vE ^ޱd3^2 af]kd-u;v..0QOfrڔt3l>[^YxٹY3p|j%&q|}6u.vbG1! f)dЖ"$4]FXn7 9Ӧu-1cWrSՉkN*0pm+`NQ\ wI6,1Q|,h.=&$Zb7BS@JemMsB+Gh+ϖog9AeÌdh&jLEY_ ,Mփg$Wim͜K7 lUo팾o~aQn&=@ga3괟`H~HM̩fu@/8u+S y /_D)JJ Z@}}N51'pJ`O^4BU"t.\ͷ)qAx`AXvX~]*G͗4pS3{/aaECnN c")S.A#n U+տo y 5c( K˲/J}ސLw3#"#Gkߍ|_'(|7@||X =ON($zk{(b\Է+iA23C'%cXkux_+ZU(pG~~GQӵkm[@P^Yp?(B`Õ^_Tz?A@}ʀ4=Dϋ')JRE\x@| M𑷤kjzKrq6GGZ n`6vniORϓ訋Gx$rh_ VG}>^Ws~ ?Qri%ä1&fͱ*G벤_ +C}3}uo݋7݋_7Wdc9a,cUAHY3[Tk҄z-ȷqp?=ke *|Hm/fgާ1.#RՂatUv7dR `cmE*7 V4-r W .K!Z%n!7L􋬋"'<务 y (WJ }tos75-MR+W{I-ˢzaGHC2~s+$5M2b;VֹI t8jZW0Qή`WHΈDSӧ>9J#qэӈ!f \tc+0s xjXKAUGGߞ a6_#.stT഻gzNQ/ѺU'C"7сX.[X-YC'#t+݀/XgD К)*|MOȝHĤ跢3Q.qXcN,|{SzW( dzUrcg0!֒O "G$zUAtOGv_ wokn:9`>3X ltp d&\7A. vYCcx$mXTnR7&O_hl͐sw[X<,,YZH]v)v~=U)ų\Q*PD_Q[dza*2Wń8 )qXLDFi$3Gk4q_F%g6W0&-w[y~hsWEwtD5v7Ģ< nt-x l|Gk1fk߁MͶâ~tѕB(mv|[ 'nZFmu^2Nܫ9:vOPK )w:m*/^3org/mockito/cglib/reflect/FastClass$Generator.classTmWG~&YXWĠjER*b)fͮgw_7詧=~Gl\$R?dν}3w? &e!myi|㮴H.xN?>X7=ߌdqN*%0`}p&x# ]n ϐm`n`a0Q[ 50aɟS uՈ9~֡s RyۂsȠ0]zj eMpIU~*" GFMb1ԂrGRR4u|d5KS52~ku|db 7Eqc JM2m[3b4SuYҮBg:{^̻8O8C56D9)Pm܊zvv-"Π0rTRO*йRrL1Xoy),|>յ4 S  k'c"IWf=nZ_X-)<>JoO465,XCDb40z P"ҴXk< xN(7Bw.|n1٠2w`Ik٧ӝO&F[t;h]Sg[#|LާSc'ӴW$cj'_+GcoAYKa $U\`=T~Õiʫ@Z4HU)C̜{D32~ZC/m : 033a7k+vF^ -qR'&yCwm- P~O,F>\sy9n7qnֵxsQ9{Rmp6Fx=[y6to"٦: Ƙ ,} [#C#]!p _60]!ƺ;h19EESH+/$yQĤ^\HN: m 0"@j*ΙE&ed[#O7N Īs7=JtZws9L+i(__3IsѸ"9kǷ8(G{#uV}asL@v` ua` 5:X Kk*6l@i\Nrgʹ!)|-HLZJe_=cs&SGgg9:!<)$1H$.scF* hn0S&fx/& *s-|R{!IWcUTk$jd`t `[@oW5R:l99۴2NxLLcTXḮ*=*Z%;m-i3Vf=h_^p9;%#?U  `{ԼUlk~eU"mNp^$R4'[QH"^?=vkgw;m>=ԓ{e쌾=7@LDtJKUWx8&e| mp^JIC8g'Ї|OP>|yw)61(な{ xG}aRԏp\yONOY\3~~Fҷ{žh.㓢zj=U$ta,cC\5x`i99UVTVƧZPۈ[a]@f VVb FĈLa *.OQZ{><<#Q ˸wOo 5g`d}G<xݘ5zT~߾ wbOMjz_,(>JniWNwC<𼯟~rWs|^ke'_mo/P_bzB6ne+ՀX.Vz" nndN?e 7}O$΃xٷ>ƙ`<2{-lȕk'>8.Y??r+v냪TF^tٷ hwg&1|}ddo~~z"uPK kN:`r[(org/mockito/cglib/reflect/FastClass.javaXYs6~غJ>Ij9cx2 DA`P& 夝)$K< X*x]&K D7s!K%3OK39h" p P%[*$r -vN-`Ep(Ih%U3D6L-'%2 >U 24 Jz&$qŢ[Z;FcDs]%11&O@R)װ7), Ji*^A>$pp|/ḫNe4dx1§]i( ЛTh &31sn!ɔFl"4-YddAaT$hTqplŔIٴK+?i9pţOL0Zl :iN >5 |)`%HqqjydPLXPufryEՒJ><"W &RaDmJ[4mEI&b9~F?g$y06 ׯCփMQrptoЛ ё?!g0?=XE*4#B8L>Rb=J\e C$CbM%,QtۋVwD B%BĔ/X %~(>o(ecf˙B[k$սiWBm j3g&o?=*)G3hE#ۧ:<<No4yB54~{ӌ˷93 > Zսc 7/jD8'n˕5Wv`.&BIodCqD$ N7=KKoN|g˂ӛ~VHn>T,#!(Ҟ q|cju abRyV٪\㾱'AԎW*4N;T9lbx!gsK"3UN-"!IS uQ{`c߳0B-q R!uS*#4oΪ5dGsD\nNPK )w:˿!2org/mockito/cglib/reflect/FastClassEmitter$1.classSn@=ӄq Q %"QR@%R8[w\♏B:i"ZK=3sfxBT:*x+0]OHI3]n: BȏCogGY@ih?N aoֆ#.^9’^_|0P b74221a. X&erZLlemޫ 2{/`EK-иc̉qShUB vBRcspɽa%wP)Ox]9}<ᾋ(JvF3cC~eʌel nk6EWqsO0_ }Q3rw0G(E6"ԑYs e/֋K Pi Dxo=7ºZaa$)+/"߬P<{Gnw R.ߩ&5 ܪuBޖq>\=2PyKeB1^Hc6&`~A \\8)" Wގ6-\%u/ZЗ\uB.n*A?Q3ɟWBz`_&nٸ!?QBִa0M%e<)mi-8.gkjVNPɠ q= 9ʩ>&8Q*N8mkm |/jX7*Ci ؖkQSbY&yZTPdFDOZػdz ʡkǴjzt-hNsG IGѭ~p\[MY>׋ 탯"yծryGI" qTH5BL` 1&po*TEL[K +C*݊^L3,K/ccJRVn%S[x;71)0׏czt< 5|+x'xRx+nZh]B33@d[.{U4buZ]o8AsЯX.q wL!C['IM15GVYe⎮Xa'鼥rT*G8֥B,F\SPF[b;ni)h<8ѩc"^ 광gL ZmbzRefݞӱ} lA?Cg㽆mx 5ұC bC ]?uw!?r oMW0ŜwǑu?U^T#A8q>fU )bSgO6ުG^HUȊ7MHɕ=fh fdH% l+A(pG,(MV4Ψ U"wj"lΫҏ2 ~l5SfkAE30辐5߽}O긨1̈4TJ Hf^s9kLP`ŝ"m^r5hbV- nOz5M~8`K `iCuhIZ3c}2/):]v2<`96 +d>y 8ō'~{2i=H}H0bQ“RqȿNdF;zKJߣ #R1|tmRچ sCApiIbqWB1IRB/W'_CG,(Ž4XL.YX RnhkiPK )w:f 0org/mockito/cglib/reflect/FastClassEmitter.classX |[Yl)MFC:i+m4u8j9Ǯ۩ҍsY2uۀ{б`[)t/`svuOcx7 `G{-˱GO|{s_xSpXh8=YȜBwf"gw9+t5KN,gJIq"y%}P 6\Q)8p쳜D>k]ܸ9GYAuՏU׷6?V_ߎ~N&6<KcCC5'3]Ա#x*HBCdo`rvUj MdHg V4&F2~Cd5x"v5^:T"L&ө<;TVe2Udw9O<OXD*1lQz "A|+``XRT)9vg\d A;o;w DVlvK+Ι!h'*g4偶aJz6mvbW>XMb? QA[dA55Ў 4-PnV*;TքOg+p$[j rr/nR; ܀J;kѓs@$5m3VZ^У:!*Zͧϙi})3Ȭ|Cqw:Y5k\mhTH%LSl, djdz**8[w~ac-9QimTQGq69 Hya'+ ?J^PQ G94(Ųwӝ"+,mqAE:d6 . ltW-l׿ӅT̗N*d7%g(˞HʹQQA)₠:]g?GwLy; xRZ;+Utv2k:׷4;] މ lrmcnBWX̲_$?O3VlT^Yk??C=ݼJqM|Mz&j|Py lv59uUu>? ,+)vsG -]~H JcE O/ᓜ.1pɅW*U0G2uTѷR ]&lIsҭ_y Pg +r>d絘BPwn' O嶤y2˒fѵ j>R37' \;u6C+LN8|_<2{\]*Egdn?P5r?f--.T?UYFr%z)_6 H;c/+.^j17n s]|A?, + R V3 aY[~+.A9TS[ͻqʹ?B3'su'M3g[9bW52w/\AZV*ǭ >;ԛ~,aH 'V*[1&3䦊U* 72V'\ڕUT*\ ajg6ds&MSEsb9t?pYF@琍tfvj^Jxf + lui쎙|i=m糭&5a]LW\-tںH^+uU{>JlWI|rR)^ 6[fW 6Ё+F'y9Y n(X7` :'vnWʸ++i,Xcp_WO܆ۃr!j XѪe{- w*Ureb֋BdJ1^ Q;x.\Bt>WQ&x4(wESp;*IlXÒ|'tZ["$hu[My\ݣ5mPI(wq{Iƕ2~l´3J*&r]]]^* K,}S2lD9Z'_ Ȁ1&.Ų,ADͪp` v{rfVi*uvJNfCb:j筢V* ݬ>׬nk7xF䵛6^-ۼO nٯ|;yp gA@stΣmu`mYi789<0Y?TOcG02p<(YLΣ4s=p%sxL>}ҹp`o[{V«U>wk Ԇ},~l~6P23KY2u҄aNů.!'b +ç8R|Ы MzPr|7 "p?_ï#~IC=[1*'>ڏոr&>6[pW7FG1gQL<-}I<wOHQΓf_(^ă: 70M”KiBVaM8#Qز!ØS: U%Gs]Z8١ @ ^şD;:Boe/{ "vk5sk>W.؅ЁDZ'eF%ˮxMgJҿВ1UY+ت]wMvt*_U+Կ[4ƽFYُ5)kt5 F6&ry+yuy~;twḩp 年|x:J X;m?&;:㟞÷^x.ܢ{J:z` V^~>C?+ċX2a3iΊ4F>-μ4,i4싶t$0+FqVn7Hh^6E~%:#[CrӬܼ$1Q NB zrToKv 葈Q40i>Տ>K?@< T{OE??4ִ Nw?QdXq$ℤC:NB8}bD1t1# ɞyw C^\ rh4$aH|hN]—Br&y1$$u=!9;τdPw>yy!Qx ]E\a í^71VYB'Fюqt,' etjvZkIPK kN:o< p$/org/mockito/cglib/reflect/FastClassEmitter.javaZ[S8~Wh2Nw@> S@B%nr)q%']98o0;jѹ;}}@N|Ml瓓w7'S AqM0qBtC12A0AEzH`l KT}&x)ZWД,9 28 ZS>r4[x<1@aަ&!9e @M*I&y#B *Lc[NiE+D`ZdAW N.(`U#qLylLC#,N8W)Ya.4c٠턘=9k"c6zKR;t !]bƥ`|9& %˄07 hDg)Ě3;7}9R*݃^͓4!j7[s_q5 جZ4hFxBO=ŎzWw?tk$Gd qVGd=޹I(?D8s?zO!o{=lVX Qr0|tt0C` *~& 5_f n9@2fOaPXCz_gW'`k_"sWqʇ^"+ew#QHƭƼkona{wW.DqD.dn2K$,P-`vBTwo"Hy8m_OE~D_ϭھj!%c*%2 Zuƌ,0} Rm]KR( I1/*3rنnLf4+Ϩ玑aݟCg19 Cshp?t\wzC\a'MZ 2(TI%߰a'(04,]\Z1%[ÔAt7m;;!wDB`[-ZQj&^uܲhb`P[ELax&z$U,''RZoCͻ@,\)F˪e\=Ƚ :h4={b*cBܴLʙGQkIq,ζBY2e)T> @IT1[p]:fg.u0~iF 9mb (5@A2 ;%^"ЈE ēNɻۦCB_FoT:(jGRL8UU2-Qu4M\*Lb(íb3y y+d]ldB񊠐F(\!5<֔*oZTЋ`4䵩A.VזΡU G4cM7fU}jfn/@x;Po\;޽8֒&^Jb[Ř2:59]3bb 2 eQtsFC1cbL$նJCw,|;|s ԔY }'DT,-^kLA_IH)W;$ьaǦJmtcAfF4/}O;+x6/]̜st0pȲL,!i|ESlnӲ)8z]:$ P#U]L.\!Q(\\]R$?(*@L|,ǷPK )w:W;u/org/mockito/cglib/reflect/FastConstructor.classkO`g ɸ2/3&f33o 0]K41e-nPA9 $V/ B{_fnf &&{`Jb !D&OD -90C5B7s a~b7`1!<ӱ}qT,*Tan-}S?d&w'H Wᶊ똓5¨(GRy-4]GmKi5m[bѦzKvk_0xG>(]zRUDy1-_K?|<;bߩ\/!yʮ.׸k~zJ9j |Ksk[Ǝa\KWmߗ̳]XXb*GI IFdCg{dmk>n{ƸH .;Kbp.#Jf{x{-ƻZ,}GPK G:P|}.org/mockito/cglib/reflect/FastConstructor.javaSn0 +"s4żuP+aYIt`迏rmRl-|pSS*V'o!]!Lj!ZaM\kBI@OEu\'1>a cm!h2r$J4U]*%BhlQ"q0 N\P.'jVDmHt#cqux:'7zWuKt,h喳5eIR`,"x٭Ut1u,#ɽ7a0I N~ȃ\U ד$WTܚ.Q 掠F[)ձ)Uߗ'a;E&Eb^ `e܊{y](20FgNE*l4f ]7R Q!g2ʋİwAB>aSkح'F\z{EXQ!M5p8/c}}t"}=vX aS:gzYzi-6f Vִ^} mByG[TIZܛ#ȃC>ۼ~ ~PK )w:Q{9*org/mockito/cglib/reflect/FastMember.classKSAOABy@aH  +UPЄI'BKn\,O Bܾ继o~  NP7ke ܶ*+% :wwzҫ. b tVMж!0^?wky'/O },fuK*̪RR=d7™ DСVХ!Vѐ@ D&0qAt_^t6I3N*}z`=״AiǘX#ͣY-wmcam iXyzAGaB@#^FC D?XmS:~0#烻olpU5\Cd :s#t&kȮ0Ϙkp}Sl=?S2S541 E1 j%!I"Fs:dZ[#g$ɯ@H42c!NB1rx~1_@L3NpA;P=g73rKVL!DÇ ǼwLH$Eo>mX=fvEPK G:†)org/mockito/cglib/reflect/FastMember.javaTr0+LLz+%d614 kĶ\I0M+ۀI}ZN`"˵'/%,BU3#dAˁ+Pّ~Ā3\ 赥^d5ֲ*!4$"CҀ(˼+8REOYVCF f60<.KՎ=a`ʟLp\oXEZ?PrV-"2%H,UH5#FtՉ6JDKmcz(7V@o8Á_gs܌? avYpY@o0\ )3WMaĸ/Dܳƒ.DpjH+" UAA*ڞ&D.L=m_vC9?ZJ%Fz(1ji@=RIC< і&5(Wy+_W[ɆvzBW%η~ *]CjD֓]iΤ67h~0r40?;:-iڎ[ n+Ro-1!n@~Q-J4A.*+n Czm;2Q긯HF6h Z0XP;!H eڝE4 r"W9U3|piMyKfLҸҗw\(oݿ8PK )w:HV/l *org/mockito/cglib/reflect/FastMethod.classUSU.6-mPZ),(,(Up ݸYUtwo>833Kww#~{r9ί>|&pqZ3='J[bܕ˖Lyq#MHoY NYJ{W CimXh1冓,nvz0#ڊ?:¨Nt騆ABފ8Eb9%~"LB7xxx͇ihқ42R\fsM;=<#hT2\*{ҝʜoPd0 Z%@ {In \) ,DE"'3*i lM'>E,Ȑ5jЁN֒nĂFЃU+Fne$X#6+[ri: tݏڍ}% ̆1,I=#}C-ȷEs#Iw9=h( /)jòrq1x%{xѨza!߇.w,6nz=#mfJf=ӱ5Nrcm;^tٴAGØ9lcR/!IO-aI^C3hSi魻jz27(Eè.ÆѿtXMW#"ڍݟ+`VkՆĽpt* [ݥMK-fq],()+p3 tU\W:x9!2FCР =QZ Sd֜Ƣ%gL\W5)DvçȌiI0OSU#JB%zWwOwϨF_F3O(-ԀszLY}sfe~lcOtuqOkWGZJ]O3x}_J'Z) ڃN&vf I94gޛ7 eU< 1i9ŁTٸhsc8\DOIu" -d%,&k@*`Bie7.2tYsmksZ/zO ߘ,0›YF%-zX,a\ WrA+-Çp$Ϩ>Tv@2μ@B*[I„~܇JSe,_iL-Pݥ3Y++ %>TƵPC#6M#2u;6aE 9F".lq  fqF(@eΎevnih)(v’\kIvHr9)1=i)A'fQxb8I<㤃,PG?&Eũ5Fq%H :i7Tv-dOhqیE} 1ݙP3 kc-bKz+N#7ˇX99g+o(jz9D"v"ʚԛ.yº垽zBq.c9Nw|D[ti',lf!+blb$ g`@8 "H՛7(Ōcq6r'8[,)֡hOp\0Y]L638WYΟNB!mpN/*;݊qfsÜ8|5kGs}Ҍ qż.7Ya@:d+6Kɚ>셋p^t1Kg@jtcj^ '#MWpW*DgXTZ5Uk5R9~ɕzu9P&sv@~܀Yפ{{AkF;JGڃP {rǹ߽HCUVqsi9Zgscmۛ:[vZ6iMt+n6etrBFE'>w/s'~.4OLb/YH3,ddiy۶9v7 W5wNҭ7V ^'Zs? bQF IcHi-~'<Ȳw><*SS Ha?G[4QqqdGQc-3"{uT)]񖫕r eӳ}xtOvB [B۸1fK߬}ftWlI Wdut#I.)-m e!*©\m|ʣΫ˭7͛Iԝk-TJ5E|(.UB>5ǯ^T( 4%vdzI$ӱPYF +Td=Ld 4 Y*M3n0MGl*4943Ghbx2ѧ|et[6bBpsNht8JZB]C'n>]7n'_8;\4f8K'>ri01pyY'R㮯q׸VՌmt4/[ CU9{zA+iGڏI^ʓh-#/i-S:6m5ZPO֕a)#Z(md#,4G~osq>Y?@~6p>7tss?$sS a2USϱjLWaXbl22z/U)E,5o̩((n2XuqyKiz:+raO%ndsZ9qnbUXb1Pº<kֻ F*10 ʛv'ѭtV' ˭,I;Ntlt͟V=2~Ό w1shZMk< gCcb0̌/K!Ÿ %pVG駆; s<닄=ypfѹFÅCVwRtf%~2-!_R\ի5~2<ᆎBElyxN-REw(\.||rg_/rcS + l /KkMS ]N/rʥnI&L E)*K!#P):XPx CS@-_sxx MTWh6~ٿ,ޤx6ڊ(S?wMfa 2_;r|.!߃et0كѼ2:60!ZsGWE\\闲˛/aP24~:.fy `PK )w:s.b[@org/mockito/cglib/reflect/MethodDelegate$MethodDelegateKey.class=n1% H\!4Xie"D ǖN\p(.  S7fExw^o&[+*)[~a-^cAFJabk1k_B^1"Bΐа7yV1a؝?BY!)!xnsd-yTPCT#<#A4N ͢&QGPK )w:^j .org/mockito/cglib/reflect/MethodDelegate.classUMsE}cև7D1G,Cd PfKkV5Bp*\8$R(rGQU)⠙ޞot?)ǭf;Yj+-i5ל+%/#;zjvMQ ڻ$pW䩋Җ;n֧|{?W(nRncRY`Su*}da4\ɫavUE// 75$q("~=#fV}0Ֆ1gwBǖ3&UTzD:= FXE.ST38"&y4Fm_ۺ!5 (`xf#0p'Bs.q0^XUg{/VQQOu{7ֵO | g[^pqE #U{ry^FNe9~Mc5ݫ+2%W՞Ss$\Ox٥lI|VW؍H CzܜB=KAK']0f_OvB+ Y VuvDT*m/o֖uv=ߩץˌoRo$PGv}Vy;,|KC6u+Ppeq^nӓ(9!WLmLzIP?(hET3ˋsB΂@.oC:qq_+E 8ḧ́ Z#L33 0*ar>s?#8ه1E~I7+2vc69OCZW4ߏ9OsH-&GØz|_Mklfy ` .6q -<"#Ojd"Xcm+Dp`8=$~}Aun{/ 39'iE PK kN:& $&-org/mockito/cglib/reflect/MethodDelegate.javaYs6=fKM6eCXBZv;;;{1kޓd[!^<>8!/@$֊dfMRhȵ*.b؅ X,YH`DJg?%RyEF6tObH&,y{XI 6Ii0jX.>hy@NaC.!*Ry|5EFVvoFx:w#&%IoOŞ 莈U`M T{rUHArRTk`K~1id4m7hA&F&fC?S2#j4M/U0aIB)c¨$%x#+ei .1 M7\MPP||F\ ?XE|l@>9DȯtK}//Ew?Q)s Ljf\4xb-)]2\MI(oT X(H@R4& $ž:}.Wx-~ ܺ φdpӟN/K{ ~#W,b+R-@%#B 0OȔc a+#5ݲ22K ,0 Tǔdx 0EdEI=Q2=V(F}~aI7W1R+e )bJB`i!Ȅ|E6,BvwP\+Y%^t]8>X9dL5SZ(^p ϋ؝u $a} hK~/ )B{S06^} o y ߊtArTWIN \BF P':5O$c" #&'-P#d掙Ԇ!4\0 E Bvys)!-. =T3틮f[a1nLȵUqjZN(^2]vlyYBzsﶫnҞɚ51=-ܩRE`x߅#n|mc^ӽTlL HPUL<4S|ao#Yea L+\n:#9Ea[A@GյF5c­-^؁ |+\i4`m-Riɱ5q;zEƣcASTAG_(>~J[sh?.b|(*N8463Z!A/[@dQ0eTrZ pkMC}TLM 9/RqWeel{ZbJO9^jk,p@/?JfrKl'[ J?QJ@YRaBQ{Fɠwk'C`DE!!0EmIS;f$Yg(b7"z~iYDSl` QG+V+Qc-0'@uʱ.0T.N`v4^ KԀ8Bq&ؕ:oS5Z;s="[db,6|d)pn7'W b0ʤv?,ԄO8CB ;!WE]y.u ͐K3$5@03IыU[(N/ˁY w :U9gRf:jRfVL0 G\fG(`:V^:i! MX5)U~Ϫ.Z8/[{tj>:[?{{9=;˿>2|HWHSlq.#[; .y Qeq~&wIktO* c;n z#8u$yumL ^#nvF)䣂e 7ii/e`T2L1tEJV Ysyƪ rT1s>t<^Kf$-d{MQ`3!M? [GX1]EXz~8As=L\+|_!U+pW[ߕ*,Lb8WHҷRt˥t tn0iy9ηEs6r;4z )Izdk}$Wi}Ijx:U9r€CuUF?}]?B%Ƿ<::5;$6I(s.C4rIdgRfb+xHJx&m)o5Qr2<<_'Ԫ y8|9(\ax\VGK!DZDWlIH9wRAOs6@[|d5/xBkeq{u):֛U#G%Op{;-+6!3X ͣ{#s+蟯+F)[lېҩI2,XC6#U̪}#AK2Q/tzl Bqm~zN!y ]/v{m˾'EĮStzT^ jaP~G+c}T_R:/dҭx?_k-V|xɯ|Ҝ/G97Rf*Bp.=ENR#vgZafn>CD㥷w oS| ;@(&p7ݍ?vLU`,&x q[` ^<;Vo9ՓŦ}m5Okb:,2*\^`Y9^cIw9d2utۃ5 *U t.jEqoWzx+õAaqQƚᘕ@tzQvRT&;Yr1{gˢPD=GJh/gZmӈwmJH2%sylJāl>?eVL -xPK )w:9=org/mockito/cglib/reflect/MulticastDelegate$Generator$1.classTNQ] c r)HeZ PD/t823y/P$>~qBV{ڷ;$Vl'm=gxgM#9b-sכrOD%N41wLne.(f ێ^:.\wq 7 s j"n #W"CP n|}Ȱԗ.Ci䮛"OO8圖co-Xdl]Eu%s,LusN怛Q-KY1{']K:o߱\qnq0C{9sjÍ&h>JxV 1eXsWQIy*(ƿ= pWE7֮7֡ RR-Ed\+zC>C@ajFTI"/,q7 bLCuM$IWp,}.LPAh MnWdP“/ KҬU<1*wUL` q<"iMd]SxLfXv(]6)i!6M9 e.&f26%;"R:k.bhc׹c)А6,h ]甥kX ίpApX.@ח4% 9Wӊ;@"ג(^|xsxKM=G.ҩR$#8%zj}[:1P}C1!S`RNhZkZf4ܷLHW"}-b%nfeMV`; ~nmv(45QpRK%Sy7)ڨ"X߯<_YX+,ċ ݩJۅZJ&/+آݴg#by*4hW+PkpX__b9֊& k]F`qM1DBDK]xcǽ2^8lpЭ!ѓtlZr$5V)XRot,(nfa=(`a1 DTDDfa9@/$p:m" KQ3t5]T6DžA=abq;H.^Uz4q .qALp`9l2SٸARU:p n3o(bk "oj9P`=FW"SFBປ>a7O{cqRq=&$j(PvLE=`O腙ptL[QMbZ2KBg;pܽ}x}6H]uaе>x&"mnGD{QJZ#7݂ =>_nc7 U|flr)bT&w'pB>b]VƏ;Di,)6 hk־XKOOˀ'EINEnhsГ$vcyýN³*8^*rrWwƅXqfLL]xq'7/Ln{CLj')QJ&dDPY;ɟYhN5 ٩•zBr6 [Ȑt3.$zyN{xH|QiCu}h=nwZuw.ŏIx .RsW0={186Vnxu9?z^4:)-,{@ݴUG[<_P]\YcÉgaCM 9iZ9=Lw5p ]fۦ+|sLX+ж$:'34Ӑ < [fg)B'y&+9͞ZO)qN\,q+.iC^SqLpK-%lhco`՜ވ7Qj.x *i|+T{t&uH ]GIQdz_'Y6q)qc0p!snD?w6.L93ExCybmWy B"6{P7'P>3f_'1{ϫMSP Ra/Lc;(+P A X*XO:>ϚP_ K2E='CzPVe%۱w`=m]ԾY^~RG'ǹWM FV7Nnߜ]@|qE }9mpK[-|}R)JA˙T̨VaN7 Kt?>j~:_ꁁ߰*XL r_z勃ߊ_/롍 laӉСt_J[ &CTeg?PK )w:fJw1org/mockito/cglib/reflect/MulticastDelegate.classUrV]'VX IHI1)6jS- f0ad""QI>':^aLyS? XG2q ~eu^{}?%PxIh-[#ؗnbn:qrE$Ryؾ;kOӑZk~Hg'|P`|)#2aV@O%46'0t d^ Wkb7P0 f'%O<6PDfaW?)Mgۉ /VG(r6Y7ku:&(ՉBxG*;MD8$0Q歅\w0K4K^' ?]ĉR.e8N_Fu**>zh0UeT XYzqEr=|mU&~iD#n$#5߉>kk ˤ$2z쨪eqIMWEcQ`ˎq В~uT-lJUuNgB r{}MF#W^ƬIXk`SHϓk-!86 oa9|=q-ƚęTcgq>a' v%7iI*]i*}quwL_s97KOJ.o ԡar]<>$sad3PFhM1|BNcZSn`% I l4 a!c|pm@&u,E!G/^ghmNG\ANL Mi,jqm@|tG:(!ɼ'5r]t`stzLS ITzSNf]}zyl]NE1=΅4yL=f;E[2btǽ&ɽ&2vڲ%*rectY}+eV9e)ߩ$%Waa_<3mSr4Fxi| 5O)E 4" 5-/^)|M{N W fyAXߨ)k{VSebYYl)oW)!σ? :)_S}<ۉߚ:,CZϪsKa3z"g"l,/^M]ø9@^S%  ~ z!raIme8m*H4LF_,f:v{׺:fnЂ/GY N|c=ww4YB7m|*vZ-lxkc;l߳ˍ@FAn6Hu*ؓn$Z$kĞ]hV] @ 4>ҺV&VdDl$ X:wȫ~;i:-:F{hEQt(YgLVQŗ}}}H|pݱk{NWceĮKyV&ZƱ^(g= |zV'.!K[c_b"甤;$w|y{*bv,߱4ۖ̆ڥ~2\I76&9 , M9_jp>?jB ?fE(KL{}| (?D^ȩs䧞!s3aN'τa!ǗdL̈1IH@w_ע Mdq}"DCҚS4fy2UW"ѡ: y!V[OzM)gj:t\ }7/O)=[>+{%<:#,kZLYUmyRKXƚXß=B)t rO/$pl5+. .N$ h26a{ЅfTJ:#lgT++, 'gd TMnkb+ёpCD:`ZeeV׆o(u>9AzR?x=ԻlNMz'E+M qD:!qޢMv_PK jN:C ?org/mockito/cglib/transform/AbstractClassFilterTransformer.javaV]o0}ﯸS6tBK,]:;[;YÖ݁j5y3 pV%g"CsqyZr|m9djT4Z@`Sm1l߇)*feճ"~FODAᯚ+*9V$d{ X֌.)A˓smOk3pI 83x%q2$_ջ|no*N`y Wx/4hNjS@J H&~bKֲ+gT(jV rJPEPrmUҔ|ˍk.h6!Zr:'72̊QLhJO&M*31 /hd TuJCV2'jg膗ժse=3 Q)crECgIUT9Dk'yʭGmV 1Vmb% few#8ZƞN+6a|%R̞ր OSHsb?мʛ^,<̷՚wAھ9%>9<ojډNG@Kx n~=l_?㛓ZetQ9uЏBx%ݝ5zT=NZ&Ŝ z;0x zRbci»qW"ӾV:UP b!>0ZZ3M]$jBa9?rzsޞښ icPF]Rs53.wOM0̴;A)Y/B)Wa:l)/kc`H)fbO"WmA?Un~فF&1ߍQ.(T61F{}ϏѡEQ4O7N_䟐D6~1::m`zD+͉x]y^C CUEeL] XTPK )w:b5org/mockito/cglib/transform/AbstractClassLoader.classVwřL [dٲ6@Tl1KF2a4#F+tKh+eJ"RNiӟcz7-[c<ݾ{ẇv@ْg>n^,:v>f0ʘg,?!q:[.u¦_ ?Cݾ;@/3e8T֘a#8%pXKԊ84>T,a ,3=W2lW];OxvuϔMLX. Qlщ5k:4M]aWע2[n9|dw4B9[YW\Ҿ'm q'nX<)Y=Vc1$uы> idv^cSȲ)1rnZIZ§u$FqYRsj;jH|W^ tTN`@·ʎaZS##=ͱu܇5g$rr }ƈDq.ubT3BETПEN}dZP Q⸷!i䖫AJ_cehSbU͍3*vv+,2JA jJ_Wt͙ƌ#*Hc2[pBI[VZ,ג眧r!lNXGVpUҢSrrlk2IquU";ڠ+ #S)] ^,$>XCoQAGUur>IłU"ׂ3ù~q%׾eƴdխ2"UvU VܰϞZr:y4U5gkwcs\Չo Nq]W]ϡjw 5FWFn5EZP ~ec_:FsN+xU~)a\-B}Aѐ+r#iP۱r{RM|_)/i}:lr\{(,{虆3e$줼 <Ƒ_-ӎWߜr\F˪DwQ~vΏ"ӇwM= : ut63ѝ͗,Pp#NI$=GIꀴڨ3,#6dzĉ$[CjXWC5f=쉐5k$;=ޮl C5/5|Cc4Տ^tf D35<|@L+qT[p&< F,7s89NFk8yrf M:9|i NkZ2>;" +p '^mu߉2-)C#Qy(Go۬f[qU~Q}SNx+,~Xs<}L<+ػO#݈? m#Dy~ƞfa/w?Q (A2 !{1#mM6M&fa|Qf`q晵I͈Qb+ߤu^dYto9vvC6DJ$j%WLeiEzcɲDKbOВ]JVb#*w"U%k[Kmr0;*T *PtPK jN:}m 4org/mockito/cglib/transform/AbstractClassLoader.javaWKs6Wlt1骔')?ZMcc9M3N4 `Њ&AR|Iua~#8 H->;{3/pgӟz;U.7 %I){Q]{T*o&jC:: ˫q8s6*-ۃTrdCx)~Yf`#},V"gSiC-#qF l}N.bHdzY3}?Z~&ԕ1\h y,6e;PXrwZX! Agg#bkH)@1 xūj|p㻻xq?Z.|5ċO|q9$~ʹ` 'n V-C2r 8&%zB-)"Poqy5p̤b+lQs4_b:*EX$j& 9F#¦m 1b[2{N"e!#/| [F-W_QfV kJ UQ{jΓoᮔ>' ͗ #aB:;U_ C# ¢hm#Y7"%' Rsc[ĸAS V+T[ײ˛xZ9/ k\9uV4Em-a&$z+pgB:KG͵HTp%hePp$/4Aͬe4 gr2P̀LN &4Y7m:sT %`ŷ`ESd[ ɔV~n5A"xauWAdzpk_js; N1iVkcXC!x幏wYb(RyPqhS,4C=d[J![u;Ш\s KXq"Y8'dzO05ЫۤQtl\]1+K^ȡy(9N=z sI˅nݴM vg34`e혞Cc^Uw/TXc)Ž) ̠=X~&sՉ@=!*[bב^-7.cپˣ:|m26zgR~udʸW;weY?KwbM^iM/G b](ϛj۬Wk05t oP\ 8)KL]=BچTYݍ\i@LOJlZQYe0:PK )w:k*B[:org/mockito/cglib/transform/AbstractClassTransformer.classN1ƿ( 7PƄxOċdݥbu5{y0&|8,LT:̯ 9jN'vzʄ7k-mF,<3El3 B{;ţYT$ ?)B\җjLlB5uGEuE> [ܩp1ϓ\$H47'm]rH̃U5ǒPp}9ZBqzRM8ӞRL()V{^Pxm~+j+^z'b3ք]}gͪ3N5|PK jN:)P!9org/mockito/cglib/transform/AbstractClassTransformer.java}SMo0 W9Em^nƊ=2%MC(CD<7G2N8{R2 B <(c @h 0 ɐ\iGІN&( 4VBKNѾ3āe0 .|ۍ :=4w]^ql\5OX?HuUFV98,K֢@T9G&"S*ON-]vɳ0I2H |I44y9nu2laYߥyY |Ow3@uaXev$[j$VT9<XtaVq? x1UeU"&'m6$|/k}R Kn zRI0^F׋^Q$mX!},P {AMC|\3 /:C(Ö<M궮w=:ќ4*#UHӱ@}lL&yޣ_PK )w:&m  5org/mockito/cglib/transform/AbstractProcessTask.classV]wUݷI34-@oґ R(PMm-PLɔIL෢k«®<qIh99ɟa 9nQ+;Mw4h[yw7em,/az޴T 2H_Ѝc{^;$E~KY陾')'MZշlm4|*?*Jg"" U{bqP@ ~"ōUP8W&LZ*,&MHz6ne°T]Wڥhc XfB6*EgAFX(ʭQ.)#hL/re sAS*&}dK F;Sθ˖V_A-tufB`[bag%,wt+(SOI.~p`|›vJ=r]Uc~ VZײAocQ#&EQ|>cӓk4͒Z%3Nݵ$dyZΛnâm)dCa~%p$m!΀:2]Bo~H[{FmƖl; r h#]:D;}eծ\}^ _C>Yo Op(Nj8mOp, ^GJh8MDGrfJ"Z[X"VDʽx{!??¤/+d]K>\ƻd5^ 49 =JF(؀>`DHid! We\u%1w`/8O 2G2x:|BG$b |QOpvK Npӿ'qcv` 8ۈоH)"/i"uCMM4f(!K'{KY^Rg|u8+%ЩUc]v]pXN؉}B]P/8f`tl_&pp`q0ܳnx xZM'Ae g/7X}ۈ9;N3JNE5[S#gC4%EV*nInƧWNۺ=0h}&сd Q<[ШZS<|;ꔥ[g'Y~ PK )w:\, 7org/mockito/cglib/transform/AbstractTransformTask.classX x\Uof&Li5隵.Ф[$-Mi K2t2/̼tCj4R@D#b)D[ Z"& l`{34I%ߗs;cf HKE4@K(XaDhiXGXYnuB)T?FZl c7r6B-YQSjlkW k44XݶGhsiԣ6)d/ b[Q7#;(؍`Tano+؋6Ap" #hFuOǒӴBuZ"T4`eAV"+ l04?xs6'(=݊`+ ұxm1iَn855g&7&E &IMpc T-]Xӭ)3SRCքѽT 5i'\([º䠂9k&"܏n8W*8 u(!0υJ˵qȂ r TQt."{)6jxU-%deJaBwn,;Mi^Ej֤ "RC& 4(/ uI^.g4McVa#%_oӬ9NcҒքu9ERGVBi?+/;ZZ(m* R5lrn=ugAR}!̝_4*TD)HB k~YIĊAڬf7<+k %jdc  ԁ' -`z..zrmǣDk+\@ nhBa?oF6!)I`4;d2NRק$4>zNC[w P7W)\UMn.|m >ϊ= 9٧vZ&Yck3I݄sEC, zr{ ,DPqqIӫ:TN IO15nᓴDora?$_|ÅEjxŅ[%ڊQ Y}.8? ju`@!߭;".$/.7'^ =RN=[#Zp㰥^q/# 4Z[鯧{C\UotPŮ`{Ŧ`{Fp[;X|,kɬ<=2`n)zȅxآzm,lDXacKWmщX3.YPΜ-_|/͓`[.@_qNi^71m2RIȐLjxO)^# xV( <ǾfC">_bKbKG,iFE)hO벝Ÿp^6s̝›7W)V!<d&K.us8 a.u}q]C3ùʍ?2!eHZOlja & ,"LCʸ>n6+r`*[PGj\v\E,T3FIzYkF[591`V#8\FqB.F5X0wՒGxL5 [yjAR|:z\Ed&*¤3zmKReo6'8vlr#r&Q'*\jcms8F$&/,+wFeZ͖,L=.sl uO/0:eC:Ú99)%30{aIi `PIiӺ0SJ08fϊycX{ z0B,NJjna j1SLEGŅueG>=KxIl-9Q0!ee&FO[GQ]ލ>:~7ۓ-Ov uai<̎my%?iV/1Ŗ51-+։xzr=>@n ŸZqPX9rTScuzK 2[qu<Ϡ15$ne15A=݉n%<W%} BN!9!YySJRı=0wrטשፌ 빊EĖuBtuҞu+e#15[eUʧs)OJL K?el0vQ̷)e#Ki ;:ҲoϷH,ɁH*#R̾'-n)3xΒl& ISO[j:PY#K:Os?Q|D9Ӕ*ZPK jN:Z8 6org/mockito/cglib/transform/AbstractTransformTask.javar۶v@\VM=\YS챔t PKQ܎$H]3D 9#<<|hjqBZєk* [ȊHC=K3 /TNIdKH,$3U" ϣ/;;L鷠xG,Hy 殞M@@шH S0)P]%!ɴ͚g2\?!'._2q''H%~>Em%fҿS K5IAL$>H9!$)L%@U47 $/T¢oWin`zȘ}|M2&@<КフuWCؾ`z~vVAm<*AL)A7MhJloY": ,Ps \}W lD/SL6׼8c|P0KdߙgǮ(b!)Rڵq eO`\rLrqBaT~a^56j4H)c%e&4 A`Hp7@W.ܼsKM6h\H%w":A>Z@@WfSѡЭF%Q2LbՐJ`17X"^ӢVPlG*C`j=?Bee׭ku0%yqu4Z꨹Z[*f ~bR)@O[--qiX;CĹhE| bJSܼ]̳\&3,'5ATGO/'9qWOӔ>WQ ½V]M?͹EB6BfqMi g^ zZы+n+ôiw]c3f+J0Cnie^ӻM(JdDT~lW>bb{Uۘ >̹"WX\sQ,AzlſJuH-Q^ˮfb5$ DC$cJMF%Pmq"iV2t3=b=OxNEBm(7#S[4y@gpP`SRw+k*r6 ݯQ(6Ȏ^ z qa5Z:གྷQ6tc6]ρEIQL]NH'EY?u)оl=>o|X?|"[%Yx. G,&,(az=ϘKm96@d J4=hF9P_hE]1NWCO6#?z>d~%Rv D1&`B۲օv7nIW5`5e|gvbE7g9>gΜXsJl-+UT=өqZ㸾ۮsdיZVB`<7 Uө^NGT`Y|}dW@<_X(UiWn U,ߩSr=!e َ?_# 70@I^0|&Ø 2rSC"&b[.Qwd}K`)WNeª,Џir~zRFW0T=Q3;y,R^H*Uի"ûhXBN5 Ac$&U)]{sSD5-#ӳR:w.ڎQ+Y^8p^zfW-̱8\#rzGp&n"\'3ȱn\bݗ +ԒTx>42$f4sQIq =6`6S&IʓBropT:)RF[Q\qq6.۔ʛUa~-(Eb2ԟ0+-,BVw`z؆eڰ gTk3l3yfrCKjh6wnH#ͮKfl ֯v ǐRIYUZQZX#fCFGyC*qR{B +0-H E;-p2?PK jN:t5org/mockito/cglib/transform/AnnotationVisitorTee.javaTn@+F>ّzkM5$q1vbjUmZX;{[oOˏ\#x9'+S2p/ 3å PhIMfϨ41u.ad&5_[Y@ƶ B#VkcOiY;R%Ӵ;zz)j \p ,'Y IlJ XrFZ٥↋dsm ә^$yohnL  `b/%x|X-"VIK1Ggx/PK )w:lmx9org/mockito/cglib/transform/ClassEmitterTransformer.classPJ1}nV[G/EE "=)=-^,gc dS˓q""HțǼ8Őp\jt]_ oֆD)4>M6 +;_<'M^pqLhzXz!\F?t.򉿵av3XNϹ׋ђn"{&{hq&JrĒT 6%i/[7%vfGpJ?PK G:GI.8org/mockito/cglib/transform/ClassEmitterTransformer.javamRn@#+5'8*j%C,c< ݡĪ%XrA˼潷$W\GǴf!핖Wa<*`S+&k8Hd/i,+y|4vNXh=g v}Kh0U:k؊z9ρ:<kql]X٘ǎNGEQT0/g.gxOjkjZ0#(zX꣟N ƒ"6OX8^Lz?"Sxvp2aYȢTF"2D/UDՋ5=qL׻^lZ^;qB-`Pr WVNcZUZXa'* ,QF %\u>:Ra@βq?,Pxe'c&Ry.P. _+c(9K=d48XD(xE>l=c{Rs3IM>oLCXB0()A]Y+&k9:pQSm}gle\4\fmb Apظ(k]F9vPޒnQPK kN:CTb7org/mockito/cglib/transform/ClassFilterTransformer.javauSn0 +\]t;K[XuvjK$ H\tg*9 ,;U~ ; IlC'•iFe4Uq!\+(ߢ!t*,>9Cj8gi{&@8I 4HZ -:v}%fÔA\Ph;GBXc㪤>`}r-/>V[hr’,)J[Q9\0,s*(]Eg|pl׎"i1|iY1ieo5ܥ77i. Xr_dlSti~߳"$Ϩ>YL~7@|#akEJhjEPGt&Q'UB\(CNǍ*XV*Ը9LHq H&>mKd-h%TЭCZB'֩GpŻGM2_NЏߒ{>>PW y8PNH[!$_w, "UZ4xUiZ7:a5 vHzݙ=vhkBg,Y<[,_&PK )w:C"a6org/mockito/cglib/transform/ClassReaderGenerator.classSnQ=Â[b H.U_&Cl.[ܺR?g>G%PSK9g`p?Twz8tAXQt(z%ŁTH* GX ba,*М"*ѬRj4!#XEgOca0:Kͅb"UcR(;'x_y|p]!rKfwypYcYg5 aF|z~kymll䇘{ۅfq_1m $ =E?ot v|9Vrñ3?hiPҖ_3'ŧ+X\rZ~gShqqWi>2fJ͹*l oaLԝ\wZTOOXT'>fɴeȘ!Ӽt5v֘[WtP[sr6w❚\gz?PK kN:͙eV5org/mockito/cglib/transform/ClassReaderGenerator.javaTMo@WL95(%*$$LEU(AQ{gmCL }yap)Tє, _`B GFr!,) nn)Aip<@ }pC;@N.F He4d`I$XX ʋL*Ze cˡV0\Bw.ݺv|0*@t5X3F3n KyQDl&*PDgV9ە&K2 :i^ڽֶ&9{ 0(0bߑvƈ4Vƈs JW%dlö; 03[e-O'L=ܽ٢ran@V:sn|ϳYh.V]eL!!w(" v YPK kN:Tb 1org/mockito/cglib/transform/ClassTransformer.javaeRn@#+5'8*jdK$q!Ī%XU.h޼:kX{tnVoPR*yQ9{3Z1-P{A?Id O0&^U,m8zumAB@*ێFôgVˬaJVWBrj΁:<f=Iq86MOfoQw=8=[*lF0TPflnNM_v2)қҰHsH,_{,9mmraeE ʶwK@Lu!ؤ'Sy9ⅅ|X+jhTК7tZEדՋ:tO+,J"5HqoWbWmGeNi/(oH>^w'rvC)KˌQr1yqҙ29D7C5xB7PK )w::W7org/mockito/cglib/transform/ClassTransformerChain.classTSWnYD@U/H JkQ*PlѠ28OV]fwa_3}Qg>_{nR$ws}s?"0R1YS2kuZ]VQ)ݹ5òcNJz4Lhz aEǞ@ ғitM DoZO - eqh"HSR-zWvT3Ѕ:u"@_Ħ,JYx]_keצ+wLAPBq+pU%|@9a64uVgsjosSc3j4I9;X]UqMu$v$~[|}]u1ۮgKs=. EV^!Pxq+!wz1pT>PQWȐIa3l2 :~FqQ  5-} #g#G~p@ 14&1pJD}C@R4q鷨_3^eǻR){RWhԴ/]Bb{BfX4;ͷs"q?l Sx7%Rʛ}SyTPK kN:eT6org/mockito/cglib/transform/ClassTransformerChain.javaTO@~篘8M5G΃ĢivTbo-R܇vf_*[i/,{(c^l4µeȬP\ `d@ vT[zpPz8vmjwcrH $ a  r, \Y"FcȝQ@F#0Qg_JŞq?|Mf2W'zu'44˅dq؄4X#٬r -qL]A crSHʽ@uc#&~.F9nt>av r2̦FG3^făvLaY<qGB*I&C.")5,F C jH`` [#귨/*<'"fq:lHvlj;"STo 49/\բ "v ZKf3p3,*׊ ]n㎛h38-mONb^K%B0hLh+{a4M*Sgg4xQ T.ܚ];B}%,Aҝ!ݞ''M^w*.ܠw jwjƍָ>_ gUqNہS4 Zd6_#ɩ>xnHX \zW U"MCU+iUWyѶ%ع4zj~fr ykw?.7EkgxDD1p}}{nv}mA_7뎐y PK )w:D9org/mockito/cglib/transform/ClassTransformerFactory.class;o>CNFt̒|$ļ\}7-1$A +,Q?'1/]?)+5A=jFrϼļTF MRfd /-JNuIecd`b`aFF6vH21PK G: 89M8org/mockito/cglib/transform/ClassTransformerFactory.javaeRn0 +"4+z!jKD C{̮u'Oݑf!wJ˯-O#lh!DܓFR@4W}ܤ+\Z|'; N`,P4(@K=ht d@F>J5f ۰W/wdvlTwY }ޔ棸L!#y9rbKFjAu6ڞ<1n aN0(fw]Lo2+(|ɫZFǢ{1.6ޕwE]Jym!/[Q-%3/ &Tp`:mvIzim4={f[BՅ1~6qwZxϞPaW #Đ^08ZPÐ-ܐ.*dOz ÿK1":"hdz2Tj+B#\P^>]WtbɾfGG)Đ!MR cqM[dž!^=q6 9}e+i )GEF>)H6G5%6FI讳Y)XH0[yg8IRm? *3U^U{vvgN`4%qLhj>,[Y.m;z9NjUrm&wӶ#>*v+>JnjMT67VQĴ/$reePyl&p׺'Ⱥ [䆜Ukssl*JtՍ=vüzlF;SLOm⯴n`nu ;mblԯdz%xۺX;XI볔2^_ B l6"+|U]39-;}<]Y&Map`vzr_^3vi^KQjxDW|'9ރ9G}Iq@/P##qЄ5bF#># {\G0D+"0NXq:h ɞ9 0 1od %4!8 *p٧i^kxYI'1+/nf>,YZƂ̇E,',}x-$6ud㘌6lI?7FB㛿Ҳ3'LXx;U\c}dy7 ,N_5\7$/)jsSndu}V #Y_~Vw1du֬r~3}fgVC"z:_0u< E̝:$;٠THȆe1̾|yMfO; `2FLȆyʣa+yK PKA ܑ`wP0X/2H2.#| P J"VQQE2DKw8?PK kN:4 l 0org/mockito/cglib/transform/ClassVisitorTee.javaWs7~Cu)f I&Ƀ8C͝ttO{wHp8=vvӞ< t`x{ ,6B$5kAj%ԊpfXa| \5[W#x% vPZ$ ia-3`@*Ht^dRa'ݦӠČK'\CA־!ײg\`bQ1IYmko'wOĺz2 SJC)/@D+K"h"5H{N3흑N 㬤uF.KT%IT7j< ~'>|,[xawb2үO?Ÿ> ՌpDSr=qUoPX뚒-0kPj*-E-EA&ja2KWÞŁ=ơJǹNH$2vF(KQGܴqy|C[EzC J?KKfA9pNr~Fnp+ܧ2Gѩ k8&+mGjn\Q#l#$_JxT Wv%5zgff-_*H\'&צPx|5_^NFZpUf&Jdmk i"4 4+)5wkLCi:0٪=/f]p _t m!xf˿1*9y{هrXGAr QEuArRaxy͚]( /t*^zd^/;MïO_AaPBM9. ,c=S *gA徠duil~-_imZڰcV`wьi0j^܉NJ~h]o ҫ;^p,ˑn`ute##.Ruc_}n^s=b]sItֵMG3M{ϽPK )w:<E1org/mockito/cglib/transform/FieldVisitorTee.classSNA=ڥl+XʤFc $&@nv74h|(7 Uj̷9gL߷}!CϲZ֑N#'Bd[w ?axhwo)وTgͷt39ËzkH!o`H`@6 vi-KBJexZkO\;}[)+Vp741R15dE Bڂbڷi[N{`f(NQvuRNy!UÐk|Um;ĖrhX8*343l+'>NUoL8=iҞPX hW Zw哴_׼Rcz`Q(:RpLG 0" O63LbTQ8f 1V߰yhRfC3xG1cZgi%cw@Y8hr隠`|Em}+ҒcitL%@ɗԤPK kN:Hs0org/mockito/cglib/transform/FieldVisitorTee.javaTn@#Խʁ&Rptw0{g1݃13o޼y .=]mW㫫oX!H%5 ZeV\j^,f 4@.0`.58PRbE  )THZ}:qt:!p-@SΊ>5MVqM>*X;nxUUւߵ4;g/+ʸ Xt~b֚#IX$[a*2T^!k4' M){fv9\c_;:}4/drryM: [ i堙|οOwlOUuB;܂qVaSskTǩ?I -Nȇe'Ejkmkw=1{6Ch] /r5ڨsB&ȑ"eɽCؒH=O_ku3cǟ2!2Υ|86{}ǬPK )w:9.org/mockito/cglib/transform/MethodFilter.class10CKi nQ"fv$$*n0!A8BH,x'[~s V^{m A5 ~*6ARݔTc(faݛuB6g&djY\c/n _6IbtGPK kN:WW-org/mockito/cglib/transform/MethodFilter.javaeRMo@+F> VzKdHaY< ݥĪ;Ke޼y1uװPsppZ}B#׵AAU‘V{$*p Mse XpWKwwv0XdPS/{@oI(0;Lsfs<tz>o IQ4c(&š6MԾbmti}ϪO]Ekρ [. z%Eb[16 \s 9R유:C.R;doPsH|$_zǤ=qZ$=tIiq_tx;`j /GPWIGI5IA4F#td,4-u򃢀s~?_PK )w:ʉ9org/mockito/cglib/transform/MethodFilterTransformer.classTNA-[ۮV? M/jHKv >H^>̴`)i2s7gVavsdN#vs78+C-;뿽1ntp­+(?.㧜8rm\n cİ<'- 'dA?!:Wҕ&þ5>)5Vad1M'-7PV! ދhmLjwHPLcZSUg8vjw^K1gUE˥ָ㘣#II{XHa&Hx@=xhqUC`XKzkvyxS^RWK_2T3pqTͅ)4#%ovD]- tśnƢIy'#HwE"F+QihɊ;I#&tj?JTr rNsQh] @[6Ӗs1AkϐI"9#>ҠRl'.pG$5 qڊef:QA eMB*e)kɊi"H:H+}}R5B*lF1\`5%ER^|95銓E|^h/PK lN: "8org/mockito/cglib/transform/MethodFilterTransformer.javaTN@+F9:@UPD6뉳uw Qſwv-hUk=o޼y38cjgU&8=9!GbV:Jv:΀0Bsϱ35bC9X$VJ4eU(%VѺӱ0K PmjDtnC(ͧEuxv9O.?}֭.9V[^@T,K%-[/{k)OuzL9jYH`߄Q@Kēm M4O70[/4^v {u𩲾5% +JrJR[y-rlj*r~fPf9|i>?zv:,|TdBjq<X4 W% wɮTAh}~&DKQHyt; PYw8^W|rk3J+7PȟmC6h e$FR-=eFLR#zFS-fR45UdLB4+bR&fl \*mZo2ucteaPK1gR!GZ*Q9#,e-TޥMLeBs' -j$c";Vs[iَ%0(Zf@_*h'穻Ql6 G8n/ac235Bv8s?} \jRC^!d.Q 8jDj*&$>LGxQG9ۋͩdq!V6Xy!*^<$S`&9)AQuDK3tAKx;NTr/8+q4dϤQ >3=|"kNJ"30fjI%rTn%&A eV2IB7^3FH{iX L)&R ]f>WaBt0Nf8xm4'ggt]I3}*H5t)o8\4o-p[&&ָ,kQ Nz[c~{jr5vVmy\xOoS7w!!aVĞ{%<7.Է{PΝ; ? PK lN:Wk1org/mockito/cglib/transform/MethodVisitorTee.javaWMs6WxTuoc֕3L&DBj`P/,%o߾],p-d˕ˋ`0Ib7DROf{ShhtTZDB\@dgݕ؊2.4"S`)\,O1 +d/%kp9-@ Rmfx r:ޏo'_PuT)߂ILyQlJ6 $hH_A4< SZywVp6xzGoH>g>q4ol0;M_M( З\ P&3-ޔ $lbL/ k*9f9Sf] L M2msn^&аu~6Вp^ w@Des4 qJ0^)D&az̊璭'"[zuҁiWu]w$s~ hT_ev` $נ99ߋ}xCcڦeS澭 ZԎ,*|!F'py|CHuԖ-.$ T9)y5۱Wmq^/Pa.DJqΛ7J:r雤yj>5ټz~Hwo<8ޝ̙.LQ _Zz'G|"Ŀ mQ>y. S=pn6 |+v~ ACž [:W kpAa!13|ytԴvWQT9XGSRuh%6lF{]qCXcqO2IJ";ܓ9M,kA=*Ȑ.+!zMC5C&Nz+YŒcN6Ҟ)7ق01_jSWq/#/U$T4?h-%r;yN .Ebj`z[T:.bBBx\f ݌$[˳s6$,Suv^7ip^=~<5nښN;%%)Nr 7~˚F%'x'l n'@ӵ5sߦn'䨼}L0N'E6Ҏow89![]tygKq`ơvIvIQ;[lzޙsw Oá>)(N Fma7Ri,{#Sifĉa_HMpz&b7|N K퉧XWGS/TK~BShHRFwQ*ýeL;4G(ڏ*#<ꑱxȼBhiHdU dDU:s>Lڞ0>ex$Ժ:I_%@vU*\SvkH4yErܸܰx378;gs:;?/nrlʸ Gr=d=kiDXX3l!Dncvc$It>d亦 SM(b|aJ{3L9` ur(,zw 7}nڎKTdC~ȝ QM/'@]u0^ڏ?Pnn0ħ=NZ Flbtca>]O)&GFǺl蟛@PK )w: l9org/mockito/cglib/transform/TransformingClassLoader.classTn@=uʥ&%8"x BB PEP5Fk_NZYϙsg/A)G[?l ({"?N$v*‡nrhPFJwqiMF"UE"M~h6;ghO&A2]H5@E(,"%B>yǓ<P2dWG4ȐBsf 'G2J5NHg29ٍ2aq18p1bj8 EF7YTM9} /Sln`sbc'ۄTx]6rʼn\tE/z!,;~({R ϣ}J:n>瘣 XW%8iҗ$@ 40JGx@w`r5PjO:[“XiPc˟3qW`k(e5k'PK lN:hc8org/mockito/cglib/transform/TransformingClassLoader.javauSo08)E{`iUU}4p!^fQMw#%ʋef~,uu42?\]^~!DKҵIxLQỲ h^Xaҗ&8Jq j!-e)VRA˪BCӣ naNh-SKÖ#e"ah@Av#I'p2iȤ} 0(0b߁G܇mE71lܬ]Yn~Fk3c|s26L^wl˔9B(vRZwfq':}4/d2q<֦ o$d\'-]?3e! m2H9ZvjIBUƵ{>O ͊9-ڶl:(;ؕ,L55|5fX;~]i= G:m:[l1[@WL1}{<@a)Kd(^[$3l6yPK )w:ےEC Eorg/mockito/cglib/transform/impl/AbstractInterceptFieldCallback.class]S@Ϧ)-|b!~HL;rxmc R|x& "n9}Ͷ?}H`ôZrli)7ZVmM-k}]ެH.j5}zS^uj]a B` kf"K[ ;F ~hi HjL΍lK3ZkT'2yRzsN%n {eZ(6JW[lBA*aWkJ ^r<L^1-դk]qI7)TJ(cfsOX UMūT j+]{#\KFTdIgYS(1"> Su'dt^rd,8LeO"pdݴXXآ9S0Z7!LȅyvA-jigiT5C}iUIn{%MWa=qWv5l `+v:b{ lduﱍbwȓ:QH2qƐ.MsI0DG|n"unb|}@d}D6ph"&ЈipGsF}Dg,"&G>b1p^}X]xBe.AT'>A3_'@/}S,GxLISXo6 CX_+| Ih|eQhŀo+]оɀUaWbPK G:֊ Dorg/mockito/cglib/transform/impl/AbstractInterceptFieldCallback.javaQo0'ڊ2J$Gpkvj}g-#|;g|63rypq~kI2IL#T%sf[4-VF% ilU,TIXqLmJjnמT"4Tj3PR:LfwUx\u|őX4f|Oo'z^ 44#[`%i*Wv t:97V+~@}cdW$NFN1^~[/qrw7/w0]̯eS4  8Zjw*~b ~(aL_&Z҉Dݫs'#[8rtFe/ܪ(+O#4D`|UvMLך:3W/SEV|3MRjl,-jlfE>eB Jk%m^ \ZH;N3fdz.K*Dk=[i>u  ٚ1Q;!>NI)>oOaR &+dLwn(qvZg5qwJ(H37l'5{Rw'r&u4H̳niNy{S4vn&Fwvn_>u=lz\̩e#/׆8^;.8 q QǵrW :N_Z ~PK )w: gForg/mockito/cglib/transform/impl/AccessFieldTransformer$Callback.classJA ƿm׊޽zOA)R ̎0YfF](ؓ9$!pAmMBik*iV<()M ~r" FJaڰO[1=B'i΋jy7 wW29<|x=ex6^G9NLS6KlN1M-j {/PK )w:=org/mockito/cglib/transform/impl/AccessFieldTransformer.classU[wUNM:R[IhnmJF{ӄHD 'tL̄O>}GQ.Kib{ 4o Өi-wvlm]7Y/=' p&w\<1 2Lq[i*M(" CϾ?..)x!2oXS.Yfɲa#1c-i  䎨nHÂZXLn5V#M%2/նe$c8.y3( u 'd'SD0ͺc=^M2Wc`i3ێzFq!ny^8`/Eaq(3xcmujIP)C@ĉEIL8qQbi2S+R`Yr=nyK\[Y/U( {!fio5;81OU ê6iSnR,v]VGo1=X?EizU;rzQ1Y;ޯX Dݪ>f[(LmJ-ы^jyƕ]չ_QUyp*0>nwQ/wwBjAK>Zn( R~hfRV" 5d>?%r$aNoH2AҍTic)JlXbݬN%^ێ.P %k &:@ `K[nCsxj Ͼ6] 6$I$Sz^ikv1Y$IM̤]H&f~ǻAssDo| =t)]f:\$ y]^_}{?QW!|U_xh/#"xj)<ˍo/z2=&z^!YnbsB[cE|z?xo7̻Ykk_A G;B!r(TO5}UPK )w:Ȋ?org/mockito/cglib/transform/impl/AddDelegateTransformer$1.classTRA=B1 xŨrY"x#x URhCl0MnP?7*>YLINOs(2uܺpww nỦaF6knQ0-FީBC>w3G|kn H"^BVpj oRR.M뿮^(l\S!99 }10,J3W RSVu(G s+%GFFGfMC?I풵9SqDpZ1h*z!3e7zsnh0W'f ۔ucw(Mp^iVٓNK' qӲG"O^LӐ8FM-oJ3 ;4,K#ķjj;oVM;v``JQ2$t eK@Њ4fTT~T|TY( KBn35[6M@}bV!1q }zQԜlнH{- *Yr,^3]aVm^VbU?n5WkEe;ly> G$hLZxW↱qD\al6)%{6A#Jq9qD(MFtk*)`6q;6{ؗjTpZkgXKurҞ߁wGMsq-%yuQUIFƖ4TaM BsUL5d}dɌ1QNݒ/Rbr.?0Tt-9a͎ؓhy)Hc҅ ēLv>{َ{d 繳 'fz=l\IޠLcvVsB2q6 K[+ߏW!я/pBPIuKؠ[\s||T1HiLjfZ,a>6XgoFED~RUqWjL4̭ 95i%`mE^|6>Hr>J~^H~SL/|I*n,Bc^U ;J]%swӹhc+wo2o h.2ZEŒjdT ^^>>Qp[<jD:c~LF'ud/KmVNx?_g OFSp׶CіHn0*M Gsr_=;::$RbPvcNaѻ*X#}Xn^?dث׆w gS h 'ZZ|Մ9,H@FLIذjbCzB(`%Lp/&6o l UW~+C53lzr\9^-?o7AV)w?0}-k&_ l5iS@#F;uK_-(:I"Y'MsyAyWt77:QW;vPtWSr cS{3̠髫o8b?u<0Ffqudr_sb_.@l =@.MDtSū wu,??FoG@ܯp?_T2`YDFʹfwXqMVF*L L7sKbNYl)eXҧ`PGìqU~>V(%Sl"ް\+-  [42R!';lqnqV07oZ+/>eRPK jN:[+<org/mockito/cglib/transform/impl/AddDelegateTransformer.javaWmo6_q5BN=0q;]N"( Ze&ݬߑ$JbyR`4?宛4RL`ȫ :=p$nS, -ZOĤlj+9.\|Loy8 '`< FU &W}ڡ2#@7ƓF9 ּpIf4dkbhiBwTdTly`$l˔)y6tAD)qV$hxkq숯*lXK򥫚ȭ?T)Cv|,:Fr]q~fw . $a=)@WX3&S1+И((L)FFZh**]™`;RbϤ$9Ƌ _cO|<)Q9h݌hm4Z73"$^߼s3at"w׫uA\$HP\ 1>H'ƜE^ y-ַ_G<ă3ÕcF*JӾZdC_ȣҋ׎`HDlk;Y;FG 7M<7(|46Z{[RaQW{u3d mEc. BKSzBy_-F&8#}bXUm<!}E޳ J ^ak^ME$B"^9u=%QAQ(AF \3D)W*GYI|h'~#z4tjݭS2iuO,S 1}9NS Mc/^+(YFШRY;[GxbHIWKK.Nʼnռe ʍJGvpUgE|D:=wĜΖAEӊOIHYQƻ+j!6<;w{| Mu Wه"PuDHܧB&Τ:=5*s{ha(%*!Dqaz*ml^y-S4~n|!BVq0wLx!] z~;A\ ~r/)!{)P޻,AF-im pLb `= ۦc=&+E{N`=g.ixgSRú5 ުV M"Lcv8s26E>*]'V ߋ,y2ǨT ay)V.6-(h56O'ٵ +iR2VQ3rkgŃ|F7jCEްv?%mn:hY{p2S_ӭO-ξŅ1 M|J7L-OLӧf9ЩL{1'P$=Do?U`7m\4z ׅJZQGmw w x]Czۿa.`+"qH k!sRAy&m<55^9ApA9m רq.;{O=maVac0LoZ PɫdbEb3m@ii7I2O"3rU3T{@ ]? ;? |EܟF$Ƴm)ރ?<<-7\ɔ'&y!♄$c1BޡQThZ0M&ҕa/D<䴷tڋL-/;]VO Z\Ub_o]nN8tOެU *ԯ y0m;17ǐ/_d8hjKߤcx4eRz^wxU~ѳ!2;v=Y9GgD̑~+@뚍WާYpd~nc!2LE2)V5+tAVMnoZVJ{R9qL01{-ihb=xgi%qh-m˼QF8͗SHSz_:R֫nٳ2ʪDTLBh'IOi,gA/N?`[_+OE\R?@6!TY0LǑq{!ge^Hap'q(+2fq=kHC v5%t.[4zv0Tc̷}>"q:"S Ñ {zNO"qL4ћxb& Z?B}F?Fܡ<"?7$ P"qJ(hE6`XsdchaUo@W0E傃"#HbZ< In0Gx4PK jN:O2<org/mockito/cglib/transform/impl/AddPropertyTransformer.javaTn@SN&&Jo=V[b(huw8nIR>1{ozpWFk''`Fr+A8ׅJZQWЀ7*CR'1+ctQ !-d1XoL #ҭ9;9wz5AV5?kQYڤp2EӷTZ Ґe"'YXL ՜f٥Ntv $:#;HI޻M(Q>Q *\|_.*fp&Y3z;`v _29v@2%I^x aI6XdLTZ![4Af#-߫% dr#]/4QCIK8wF(K7>+zth p2_vۅ*kņ;pKS3AQIhrEt MɷCӭFn@Dt*%6hǯ ToexDN:D~r`oMo0~굊 7lU3mH e׀}wc%@'c:>Ԣ'y˚l'%1V*uF?0A]/oc\SZ&@+qWwp+KZcK,-b R5 "IƜD뱞akq<~lA ~GQPK )w:$?org/mockito/cglib/transform/impl/AddStaticInitTransformer.classV[WWXD/.$\R/X)FԴA,iѶq29 &3qڧoԧkd(2%/{>;߯\3[KsSH'e,QNIװSްRJ^RY[w` W=cTRr^ AƖva̽t\Zrݩd(CMB{2ZUcNz㉢4 !#Uq5.C2,^n:E:pR |(zpaH0N3*"^0QXJTt!"<:Morg/mockito/cglib/transform/impl/AddStaticInitTransformer.javaUQ6~WdT\>&3%@sd27^!CݵMܥOF+1%LlwXxqu~~a\ʔ^C-k[Le eq"ܪ hcR3lO/`2x>kxv3$ψ?+ Ĭ1/A]vsDŽ C_w ,7ٛeR9؜|H xf 9Ӽl:_8 \Ai=)|s$}ϼUqO]{͝ jFNƓ{ `'tn4Ƒݙy)-"B m'j"@BGpp PK G:ٔ3org/mockito/cglib/transform/impl/FieldProvider.javaRn@+F> VzkNԱUW44]*Y[@˼͛ 'p ꭃd[H?\/ Jud=(-4 ̀`W0K7^:hrYd PQPV7$dГ}Fk<*w O9;9> 8P#ֆb˷z Z tdxBBl=(65ސ#Y z3w"I (8‡(әy &Jxzurg: > 3>O6^xaRGKVcA<;Q#jFDѴd^-,LC-rsFs~:tЪ♜ &_t!2PK )w:4c?Aorg/mockito/cglib/transform/impl/FieldProviderTransformer$1.classT]SG=͂ˠA]uX>hT$.yagk7LX%yHe,RZ:U}{|Ͽx0x+RWe!WbV]Y0X ">a6o1t.U\Uei )^ x<E3kR{KeXha?Ψ1pʐ^T )C3_q{FRU狃s6hgh[~V@Z B0dK- b*!%e( _)ܔJ < } jCa:n:C1nьS F5ío5'zxDsxY ekGSOԴ e=/wxmFhώ,8 >&ڽe#v bg0pٲ@2[bUO8"f^4 ~dhzшf8/   A,l09σZ H+2A>0dpx+w"}¼Ia30阤jxVT]t+~g8`.b8p- tRq}1kRJL2P}'(/3AzbR& AD^ (rvQ)|E"X3Tg>fdznjV@Onhzs#8{״߄4ڄ& N{(!tJ. i#M4}3׏6q|l掩\b˔Y"'Y*~;d8A h!CC (CBxIwYdǂU)%)C\ n2)!oT@}ФժYG-Ԫ!b(Lڣ(Irƿ&b$Oo7Rq?gyF ekOSK:(RAB[ _!9:8Ezj~;`PPz>%ڿ#jʹͼp@2+dNJ0F#@~f\VPp{  9K(U5Rm>"U6!V񝤏^/øJ¼NgNzjUXwA{JoT3ԧ] ܓ hji2|9Emŭm\T۸m\3(RR$ WpP1t1H 4% }xMhW$w\[F{mLYOgNtne;fý*: ,PK )w:W,Aorg/mockito/cglib/transform/impl/FieldProviderTransformer$3.classTYSAk!,*1b.X/ @pT@M!Yv7!Jǃų?ʲg PRU;3M}rixgL#yuiF.oj30{X_pB Cɭ!v٬n; Y6<=䦙Z I c7橠>#<:9IDVTP͐` iyI0yY S+IP7,ÛdHoa:e-hm@hB?Q2R<5*| QPK )w:ltf'Aorg/mockito/cglib/transform/impl/FieldProviderTransformer$4.classTYSAa9EEK @V`M!lvSwUŃA_B ))ت3!,eqMo}.^\HtON7.^У {il=mf. Ȣ.j1>xxYeLks<3|Wʠ_2!!+p DYB$^o?h| o Jol$6}>!0t$p89I m-LE"K56媜t($]boE n?=$rӑ?{b*Լy%swzžҘ%/~{n˾ne)4x{Be90 F<8XZD1o2-5AFثۥTrf5<*wX }7c}ObLFbzn^,"&sS׭5|FK%('w=dHxН˃m/kYisgՖs(nPKGS~bSQM6P ?ɿPn+ ٯ)Yy\4[憢y{L=.C/݃񘼑X{D۝5 vQDzn%4l?݃xI"UYz<}AŖi)$VgplVص#eOC=(<`E}}@XQ5ِ~R<%qSU:k:k4"_6Y=nvy3Y^ߏ# ЀM$:boǶ++&\-*_4ړ]@ķ{hb(pɿ'fUX6 ][h^S;RJka}vrI].\,#l])>"W0i'.H]%sS^c!=ҩMy?hF^fM$~iOyWh(o a=F_9)G2ȢVc3.v2g,w%j̑/,5 ő僖_ V2KQ / s(aM-~? Kf`8N\?Wc}6E48q@ɽ׍X0w(XH0B]ciL.5CBry>LV𖧄o頯<,)gsyNg0;vPg,Jå C 3a …9;]#yn*W;xWT:w.t՜f]M߇G|1|B:~1x۔Db)I\DKWinbH6wpe'߉s[pZq6Wg:BXAnҿedFq|=ʾQ>2q(79sM|!|U]8IQ^zƸu>dJ;AL<07?v3=#AVg,jGCCIjuTF,`u?I F%2-P&">S4zG/!Rj/+7ױs|K/H-5x5?a|5c(Vg&cwb"g*;{B-QJRbE^bz{%Miy?rc$ x3mxdWWWWnIn%N]i2w Z(_BW8OfgThrRCtCp.sx1 HsUD%xND1'%Q=NTO0OiFIdEB).O]{KfvbGDisp'KbggXau-'"XkbQ,JbXM^.j|8NM=T =R#YO+5HO,GѠUå|%tg,7PK kN:2D}>org/mockito/cglib/transform/impl/FieldProviderTransformer.javaY[sF~2}*[<j1 ē08bE+ًЊ1񴝔=\%: H#36K 4Ư(̀9PR X \dDLNC&񏉧jvxdӜLT\` Y>0qi(̘k=VdYi_R$0_CPYX>c)ofO~C+Zaَ?-O@9)>I3BGLٳIGu",J΀ ~.+F.F9 9 0+!m|: u,muN=l f>O30E1IL!fCk|QG * (1 0C J"OԏG 2\≯,;984H\U^t٩xlh>$OzVc[fo$(WFN>P3H7YnAc!i(&"'_T{Ѝ48MH.cf0ޑZ\({w*B_"6QY)7YC*Sg>Oi&@jO߯VaռZsq{lw{͏捪vI#(Mn0j؈Sc7,]4-u%y*vRUUubLGeٺ{+xeQ^*m-.j \+L+ɠ7,{9 lM<$`mL+d!0nV|S 4^)~%k\)i1ݚ*accq6_2J}F!êpM!1xK6t I, c'f\t"^ylݚ6!u𪦑-~ j-Hi'5XMW\9A}y;ed{KdI ݣIeZT5>i5~|$N V3! ~Z[bj0R֕֒h6+)¿nwqՈA7lNJb5A/zjCâʓdeLOeVEKʎ'*& )64)l1U7A%o''vx_˾ vmu"deuӥ.qjفUfgĖymERҬU曃 L7ge>)";s1G{P'^jfP^8z{kޠ{nUb-R]벬B9+tH]%Djc^Ȗ./FjDGфO wҢ; R![&<'skW.cKRc'HAѻ=mn_4!P\zrƒ5w;860F`׀ N[7}9y^Ooн\.,D{i6~^Yz31g>j$[h5ݒpK H[A+>;4n39履5-a96ٔP& 4O-ԥzX:7?W-錛ޤ"ބ.mVk ͚Iv%L}ջgo-~ra^)w f!WH>%VsI8GBj~{ETcO}7-w%L2k}X.g7VX mxQh AtiϹC[b|s.1WTLݮ,r&Y Yy-vR#hNT*/NPHwbQ&L+*((y#v%BYȯ=T}_H !FPRQ!VQ#b8 $Ә!b8"X!b &!bb<}#>OPK G:I<org/mockito/cglib/transform/impl/InterceptFieldCallback.javan@<ňSQRB6)&r\ۃd:wfpEUs?Ό8Fk`FT"D\# Le.%p K9pp24*23 'flu R;-CZXIVd TJ2Ch[{%bS` *([ A]Y;W}8ҦVkǷfܼwUBkZ9݂LԬ h0HgNsۍNl srii펶kf?D Iq2I'# sϢvkk WBE:Ӛ gcfU>Jt_IzH1sd$p2,CVb36,}0-gJiI>ҭuEiQ>V(@ktpx*6VJqx*6r]}|{bxA*MxKia>Bi  =qLqj\7媬V_uz x²-)j6Ɓr-h{tHwsSQ!C8Kdg܄Y^AQG^<<6/wŪOk'Y7s@ΌuqI1OlUgZf[Ԓt73/4O]O>ޫgMQS8>\QpQN{#)Tv48=7:IPsb@ "{Xfc N]jc8,R5w7i!OPݧPK )w:I;org/mockito/cglib/transform/impl/InterceptFieldFilter.classm 1g;[@ Vp rș(j>%&Xh6~|f0⬜a"*a>[0UTK'[)ӕ~@aίi^flRM_~>ᰕ<%Lo7 Ur;gU-'GzIڙp!4BFAx|PK kN:.Tb?:org/mockito/cglib/transform/impl/InterceptFieldFilter.java}Rn0 +"4 ze!jK$5/@\Gp km&Kj#BjЍEA“V x a \@ ?h, c+ r8&=@/&P9ACJ4HԽH(0?,qx9t 5A7ߒdXڶI뒇lɋ >U΁_Y\M ˒bA[EydSfP%%wi }mv:daSx-@@'jsCCPǠx^XLXh"oi^hN>)LG5U2 +7E q( fmyǔ(6caB}]FM 4&D1. [+akQ[G54+NxH:ڪMO m,͸! F aV`5].5J1.mu?GQn6!BHW\)LS-GqGX)G/hHI+r8+Hgy*pL5{TP6yO; TNPRSZKHN QjZK Z,2]ݿY*h$5g{sJbC+t9O l]34Gh9Oö1ak%3ǝDKz %kWZy\p5TbCZZ t:Gz_ҐX2YQڛM*. 85c7ɲtSکΕ`%9PH-`_hgZ-M~Fl[ǿ&YWOؒLnMή ,]FZ@21 (@@@,u<.jQ2H%y"׸7w=ţRL?L}ťPme2(\@IHrHW(;Bv2XPK )w:m;% @org/mockito/cglib/transform/impl/InterceptFieldTransformer.classW xToH@6b2وQ8:Jb4_&/#͛+ྴ.}Ӷ֪(UXkv@f X1s{{/?fq@kŠ6%"hDcPmHk2ǒ`6{L#6?hX^wT{̴0b6uWnYuyPG{y`wK"$U7x϶xt@UuP#+|`wxJoPMzjAP7!渣p_wɡNDgF㺝pVd1%6Q QTi3㦽y:jkj4,b?JDC%3IGd 3On,)rmR^Ƙ)e1`Mvp+j 0W~ Yчzj ِwn FBj8+$u4A`Az,#<"P3krmiD2MX-A5,@iМ81.%1?$;ÆX#X8~/(%L; eF5ljE_lϦAq=64t8Z:F|^C3ݣaC9QuZyrWkɴc^j` Uφ 6qJ8,\=1d5Ǩ,N}_jN%)7-)nK%,;3e|fm3"'/&NugGҚBZR3^Q/bIǒ6Cgjf],as'5lv3.O %cc'k1˴1G WdH8"I=BQb+JU~E&(^~re"lH 4~޲LҎ]ҵkxbo}S$z/up>SqL2byR,$h 'End#D|?'6UlKft[VB:_p#cSLVp.X|OYsșxz'~w\>1;e؅+u[]aٷK,P өpn@%ɋeJ~#-dƍ/Ό/ZqRf* >A%U9Uy3W w|QJ.@czX\`j$5Q<󳎶ӊ)Vgw$ X VM"P@}`sbJtֵz+U魘AwɏMrC lvmvʧȴ'hi8 +-}rt>GEj4@rYFbjB久3ӊ||m@:y6lʷ;Ks7,jB>8݈|(gc`Y=}!?&q4EU qDq ͙OO_6鎺B,)7"EGF%ʽ'Ĵ륋[DnPd} ip ƫTcuSk 6JZPYf(=ŷq~ w>)0Ǫ7*IX&Tb3ѓNݏT񰝥|qS%Xŀ#̐_5b#FAތJD{WMډ0WK W#k$~"VY0y{OYe|M&Cnn9qZYFgݟetG '9rԔq2 KI`3t5Kf^ȵd:꼞@ff-rm;V8u!Yr!x>Pֳ<[)8'v7#.Mk1oTU$o+xw-\dMX#`圣QTEJl>QjĿ'Թ(G}B"WWkq<...X{IH#PI(="mO~==^ E٤jJfBXTQŜ(抚;]65BJžq5*LŴT88PK kN:_S?org/mockito/cglib/transform/impl/InterceptFieldTransformer.javaYs6_q`2o6BH疑r'la4I24HllmnBl=/Uӓ:A]=q%z}v3 D؅5]8,Ń% ‘̙ҕ6'\zm!K4ӥf\xb1Z'2bA@hFGDl.Ak*ZO*V2Sl*1c`mf",3K9=]6ֈm }z?. brxG$SלJm$R*9i, ^@& !gD3j+!1z uoWع5 {gpF|zLj+ &U$vވK tF]0-c!X"—T )1]RCڥ6 %4o,E׳zHs UY;I;N)JEk "ąv5[AUe! x^pFzK6<鞶`ςS%[V@Q eJaC69Jxb Kh@uL qDUlV÷`6S}U:JjkhN`-d[4V@F4>^%Z(,T-}a*%J>sa6STWDl1a b^ZH;MU6թk\銤Z$6݅,{n'Hn/)Q5}"P,htT)bu}?a%k$gcfM74:%ۙlwU-*=`dc *=f%ׇ>kME VEgҵLCX9JRA" Y䂞 !᥉.}FOiFr?3ΖDu5Zbk*9(U* ňq JS=Բ+{$_o퉚Cf|R,vJvew2z~ᕻ7|8)Rgkؘ,Ś0nY[峴ͮ(1*)"+N+WL甡1+WoMTDjAiyD iU*%%V-SXpMM<Ms["trs}ƽ)Cg9cy]KÔ:,. #ƥUnXQ{,?i4+}#3 JV }r163T]\Tk_ pɅUQ#MNqM9 nG1gMcPK )w:_NuDorg/mockito/cglib/transform/impl/UndeclaredThrowableStrategy$1.classROA.,TԪ-+gHcB4iRĄO43SxŋQƷFb0Ą{~|{o_X C4Vy4S[ݾDYRdng;6xWWC0?Iulu!J 7KyiCL2,Qiϰ~!֕VPwcD!@r [Bȁgج5['sӵ9mрNSʤ}<;^e.Ìr:$>TYߋqW#̣?C\gt?JhƸ7pk܌&y5izJ'S~h).G є?(kt D#x˭ʧ/ٖհߑvl I;_hG8MbZKq3LRt$#9?Gt##.adTayLwɖs7\{J? >"(}Er pT=JvЪx@,N?zbdU+pPK )w:SeBorg/mockito/cglib/transform/impl/UndeclaredThrowableStrategy.classTmOA~-hXiODCTbs\rzkWk2]Z1jiZF OkR#*jqUxTcWuOD,4Xfyqyؚ` Ȧ$hK0L^ W<+0BXx-$؞}D2.ω~:YsLH(#vbHc΍AGQp:+pp+JH`En'CsQ2J^P'PK lN:,,&Aorg/mockito/cglib/transform/impl/UndeclaredThrowableStrategy.java}UaoFίFDDoMZ%E ;w:UU,]Ǡ3k@ g̼f3%LL*< a\ I_ZX;ShJW5 7CQ5cL؁6*lT[A̕V> uZ1f J(9]y_2uqdl:ʛX7Mxu}z9:VȫڒbEcA7vmW:kdrުUOX;4IoB8Y|Y`Ic1Ns1.c>W@Vxcc*EfjأmkتvudRPQ vPcϬ5l)zpqi͖T}fVTے0P;DIb YdfHjEvN.xH6w`<굃[܈*(o=ޡҪ':Ä<[~zȡ4ԸaÊ] ߗŠF]{״tcF5 z3 gn RC‘e4$m%}X ⑅Gk@6 >L+Ad'E79hz7 t-ШѤ;' VK~<9|ny*C0bGg$tIwft9f牛"h K3U\!]iQ$Wδ(;TJUq1~,RrƒW،oJ͛P."vn͆}Ct x]An/^t':56u` }PK )w:I&Gorg/mockito/cglib/transform/impl/UndeclaredThrowableTransformer$1.classU[OA-Ekv,(ȥ(" B!1>t;#{ivPM&rPK0}3}gsf?caqKwtdʂ>:Kb{vQ&wE1_vc^0ErpSI00 })-Kp3L܎6qJA-,ᗝ"Çtn;"]Y_uE?[gDyu2$.ezm\)Q3Dŗ1E34e(_76ؚKa(꾊t"*=0L5 } gh'(0X]{1ݐ60C"aQQR$rFJ$ Gғ{S:3 v$0ąMuOJQ0 A!<9x37'O4f$1KrGpϗ2pAcpsQeѵzT8 -<("p1II0t}PzoVA3ʮSu F[a:K;mnQq>=ZQB7d/kS'fNЫMa@N#_C508&h:>,6ppH #҂Z/sXΰjpE5e\`U'_Y;BWe҄uY yB,PK )w:)Ujgo Eorg/mockito/cglib/transform/impl/UndeclaredThrowableTransformer.classUWElذo I hE%Jh,fH6i/># J9<{;`24|h;cռe {˴qWPun\`xV# a` YԹm/5+>'CΰpAGd42ȏ,+,IDnwEfh32L'TElE[ZMd)p'Rp{}cV6y%1&N%+9Z;mdF_Ar ,.؋VƿeaZх+i`V5c`pixZ)Y"Q",͜8(!^}mtջ f/dc:p-/{HC+NLg2E# +o*3kPc?/|oz[26.UUaSl ]G]N:T@t㎾X!dXxunuD d)S*46OiX.tV$J,Y?akacou_ Zh-m9CKt%:Gon˾KhK.cx?n-#i9~_r2>(n 4`yJOGXt¢gc V&/[.FHS@48@VpߔHc$Ä=B(B\C&TD Z0Os$?he|ҋ}k^8z8UI am"Uv/I'Ї89<@C48o+Bh IhiaЬT\PK lN:J?NjDorg/mockito/cglib/transform/impl/UndeclaredThrowableTransformer.java}UMsF W:dd[VFQZN]cd<ϒ]vw)YDYvx,899u32[;0/EBPVϺRpR+  *) CPk4"7; [l;]A!v"aH +#S EKt:O1ƷCNV}GcڹdzfiMNb..Vh-Jw Jb ڀ i5I 2N*32ܑjI@ C? G? 1| ?o#(Xp} 73X~fJMzbZ"QX醒-1+Pi*D EAj`0,Þʼn&qHiɣtK\ƞ3BYJ\xl6M8gpc9;S%N[P]-y."qpv DpeӰ@™iR'hmG(V9T悄uh<å' M#(I4g{XiNW}%rsew4ϖZ$FQq$mQenM/.\esĘSu1w-(Ee{?!_rE mݻnzG{Qg/Y44P~XcT#:& 9f"MVܢޝtv !$/ڵBKg9d1 TGrqت|4asb;c&i4$pƴΕ!Y@}ŽkGV<.Gi5devgu2~Lĵg;Gw='Q(0!(4 աCZ7/11AQiǷ29߈t;_6di(?lz2 /ē;UzCvR㵁nz^fm{u42mv鮦ontPK )w:$#8org/mockito/cglib/util/ParallelSorter$ByteComparer.class_kA]5vI&mLP.mBAK`ƌa\N})$ЏB5}KX̹{g~sv?>}l8UPA0M> #<64Dv0Ҹ H܊@h F2L\dͧi'\ r8B~aAEr"E'djkEd JMz1'7y{R[r#fwKnzq(t_%Z~BXH~<)Sʏ^7h1 8k]<acuwG|K׼eݘuRg fGV~qJ9oo֝|VQe,ptyPJs8CWb%PK )w: 3>org/mockito/cglib/util/ParallelSorter$ComparatorComparer.classR]kA=7IIԵQ. -iqdL6UQ(bFPιsΝ;cvS= &iZfiLY#Ku&Z/p$Ku@qt*JFXę2a_8 krBEB ӵ_7P'HgT>9LzKh5PAۆ upE4 BdpYq nz!ay^O6?"n˃o/}B~Gji 7DnV g~rcob*Z] T*/f7}3|\R%-S9E=xn2*8c,z _:ǥ n3CƜaS~q\F\= X\i?w GcT?}=4c:Vq96^}fAf7o)w>TCB̰lByf|{WLll"M_:-FPT=ʝT%*־vT` | ߀q u\spѾKs&Y!G^pW~r\;97_XlQ#Bq |:plPq#!q6[Dn7/fUCȗ+.\PK )w:0 5org/mockito/cglib/util/ParallelSorter$Generator.classU][G~'6KK*b@ki)hJ`vnA7_OyqU{fw ! Hd|? 2,;*XݵRZ37-mnr[u-[cܨY6O3k;oSupr[Q/udk\BCfx"ګHBucm~azm|%ն]=\lRjSmyN7u:CKblSvcIE҉na0:ٞjulȳxw(&?2t'UHsUBAwa 1,9:)c N%0 Nm]2W5h(&p\9$6(T+02}x*{ 2dp1vnng5"zk)2(_~ "U0eHVӷ4Tm]XWu n7rdt/EY2i CT a6x'GD{&n?ޟl9$& Zƣ >A/Q`e^=Z5%Ï~c4*G)U4xrmBLxQ: m2 KF Yi1:IW,8N?PK )w:ݷx7org/mockito/cglib/util/ParallelSorter$IntComparer.classKK@Mik mq)ҍii"_FPW;)aΜ;I6;8RI Q?Fh-ili6(iĽkaqARW_2L\dI#ͺDr#F}[bsFUH<JURYLQxR ==(|2)v2_p܌C[( a"y4赥|S8& ih>9jY<aau GkK׬;aYa%sd5j^[]_~և/,K7ҝ.iG` #DVyQV?!Lθ4;Aq8b/.:™63}ahBR|:H{~S3Sg%Q'Mmk1 osWPx]=r+j_p9.Uprk̝"ϵ󬐱:Jj->",'!|Š-ŠnV>fֱ(ea6*|op\5}Z\p 3SPK )w:2:org/mockito/cglib/util/ParallelSorter$ObjectComparer.class]KA߳nöj&)TJoZ B[ƫ:NvdFh)z!^xv7,^HY{}ao...άd*6~8ЪObo K?a6JKCq"|-U]{Hs^&<@(߷G($1zG'xrfCK%ԃ'E8w5&|ni\#6s.^CC7pxXVϫx0myJDŽBU 0 Ŏɨ/t5*I mk116ypk.c&g;PJ C[AIlEx/ "$!\ǧ'G:Pl0_ԈC( a"yﶤS 呲MEԴdk6 ~1^MaauC#JLݥ{YgLC,WY}x{L-V.U/nxk<REvwI4g3xG#ùPK )w:Y:O9:+org/mockito/cglib/util/ParallelSorter.classVYwSUN4-J H 20BK6M8 2 *(f)kx}W>nbP:ܽ>{nXkx8kFf FH4ТhԈ >ji3zz(VEߦ r5k3z¤*P@P¨5{%, 4(b , fx4^8O QSi"}b&3NLb29 s 2,P9>k r'',7(KAVK!w!0..X%MQ=X.ࡐ}hAvH,xBlJ7 8=9A0flz,dle`vCĪx\Cj, Tr5,ZҤ1dvD&#`f'4#R+Z _0 GkHZ[T.5LBB} '-X#U_0h*K5aCƃv˻gN;#󣡓u6Q}.agxϻ/!J}gƌXm $5-0!`eXuS:D\c CiQ57Jem ^S'c%FHh n5!!"_<[[Ջ1:?F>jǤù oT{UOD^O K< 7Q L<1$\0Ʋ+6ju)s9VPrg-uLd=Or䤰MS쿎'շK#-@q|BM =ro['<) {ZXS(WL͆[ΕgS&&:y;*0wʲ2ݒ5c-O龡S[c>_^Lbb; iŖ^-Ntf䷪O{%b$b;oC!5=%b߫!Dd"1yΝJ۲ʫ a˝ek: &oc-s%g)R+ה^)+w|oK|W))")?A%_+Gl[ʏr%qBU?iR gEUdwI%sdoAmv*!w|H*ȍjQʏQr8x}}}}p;G{\p , mww}m%UQxo ·zy,s*BHIHKH  i ҩH$}`PK lN:u &*org/mockito/cglib/util/ParallelSorter.javaZ[s~ׯ@EQFSN\)d<=K, ,)sp dוxD\s\VҐoBKFF+DfC#eϩ2 8 5`jߘ0| z~?G[YnI. )4\ FcV$2[ N 7K+s;C r V 5Ak,Y}7n6ZcChfr} ZYos&},g[BWVBg" `HT{b@G̹6 @-( 7hBƓi4Ooof:;ry{s5oo5ݼ#of =Zjrē-x*ҩW,)O|Q# f*ȊkFz.4<? @:d' gqa8?92䁮iRcR8o!y| AA5RU3뜩KAknZD*2N/_{X sBWbLe0|.JѭFGB0a~~,'f#LС/ 7jlvn`*a2 甠Peu4pbԀV$gwd#g ԉI9 [Ch5ѩ=R W$Y<2k( 5g@i r bX6TI}sˤQ:YZLCrμ.CQ9eii)ٌ( P]|jN~H$dV9Mj1Cs& -ndV*YfJ5G`ތiC6K.PbP&>M(cq&/M $Pq2kl e68IEDIcRZ8pc+54e>XƁTXBʜ 1*8(ckXZ~A/%PlmbEYr*6̵\*AO/?,!.$љvɰ*fZ'ka\8)_'VA(@zpkaxOks$?nxgvSf?د]=w42α8%,԰ `'~NrD}֕iW&aeaL 5UJ85* |Fe= (fhE#ZgK.!7MRbQ(I3q~BR{nqGB-`.jK `u3:;7j\=GNN.#wQ$82"°bPB° &Q]?7*ga`SNи _|,hYvuy֯U6גk!Kݒ0 Y;T";͏]ڗf;Ӗ@:0 ZƤN \,HGqD%zPL:SM O-5KR||L59 c!Wӗ?'=d)fa܃]N+h'A>p?A;1-_}`uXۃ e t$?׸q<5RoY13^θqطQx)`:yݱh˦~u k Ne"L86$dx.JBHNbi%hnz ; I]dEh|.秭VRLo.܂qs jCN)8`W+(- :.@(0wyR9(>hМeMF(MG4f]&OU쎕5ILjhpBK⑺WU((uz N(A:8^(G@o~wݮ -Ohh;JGCbIc T>dH--cvag,^Q+x>}e#`~mkAtφx4?}䚭EGBтNRQ>z!藈F: lJ/XuRGs\KbM T-ͳygRu.FF>O9>fBA4}{wyzX.j^V.inh[~![ofye] ENƊXz}sRZS{C9Hkc7-ő{8ǻか/WM9dakxuU| >Fk=NS7Q;8(:g8l۴ *FjQ`򕬣M2w].s4ԂW/_|H!{vӣ gXƘ$=wbȒZoaiv:/gDTZRʟt\iS^V{۝sykq27^(xX΅2PU?~:7PK )w:f `2org/mockito/cglib/util/ParallelSorterEmitter.classWC[W MXZZRiKDlhR`IJEZKr \nNksnU9puv>"s ihᇜ{8߼nx-Y\fQs̼EnDTK5 H,[KG+ZL"Z(Tԕ.N 'hPk٥-{(uPhEnhL,V1CFGASz+s= :R o)FVuLb:A*Eg^ IO:P<Z9Tg`[oҏ&LR>gjf9F7eЕ%5c2!pj[r,K>.1 m^cEˑW+N; taU{;M=fďcG?cV1~ f8t2i! [+TW%X7H k2 TV%/^c.S[ʭ۪K'Z%v-tF μsz9"vKfu௮od{^iZtuRrMm4Y_2W2ژnhfy8{8q<=\ηH+Nְ;; /{J\ <\%D^%ke[ATrw фrF=48qp?#cBy؁Ms 3kxp K+++:\{( 58քI)ϕ*ڨvг QB\ y6 /ar({5\w8J >CSsO7{>g` m8M> F8Ѯ'CϑS4A@}ĺrDICB4q8q!!La\Tf#aR퐃nmsSbM'͎oq0(R;]`ܭ6MUd7?wWgj]&\z+5 x+4oVмYA*4簟#<'1J>KR9rNI8'TЎY%9<\5re=GsvzYf*i?/UUL3߳<&_r ZE/*^YwN!fAPK lN:*\ 1org/mockito/cglib/util/ParallelSorterEmitter.javaV]OF}ϯ)p[)m!qxuBt퀓.BU@י3g6woHNO`a?|97k8\"2xy h [Pm+pfB{tN96%@& ca.R9A$y*XqX (Ylq_3Нa@o#0EM˜~^۬DlKW|Df) [m+b35H,QmFFdfB%fam {o: o,|yiwd0 <ׇ ߮a0ѕ9:9W'K|w eI<sakYRC"W\e\-jST,)šBDyi{)'a%مy2𝭘MUm)77  c[f2owuSyIcQ2a)O}MIY,=!JAjU& &xT2%vΔg)뽚H2f i&S'ǗAz5^wgxzܶFłe\ SY[/ INz3I3]P''[!hO ;*!n$O.7s"X.|Maz!bB"Vm{B~FJ$7%)ig*̪&)Q|J$Zɽ5saZGkBTCJ\r2 1jl +Lk6ikG56-&F)37nn݃ۑJ@bIm)ƍ;Ôe̘9Ï4'Bq~`7LŬHSn%Y|a$]Dѡv2m3mmXִ=zwVɘ3#"#ͭ mTmn03 z0Eº˚>'zGms~1OF~&4sie3@E:&vC q@sRU-H/UT5_hoG #{ 3tEL,zՖֻƪS.EDf\BVS"Ю[ ]A8*/ӝi*6]+5 SYjRC *c%&Y&Akp^36+WTY( 6&rj3 Ȫ,5Ok TReZF+EQ~X}@["4'hB,M6H~^}! ͸Ͻ6v@14K RFV@c=&i?]t:2NKO2p.#򾇈5׫ e yG+nQ=ިZo0*o>\u F[ nW}«>@A@S4m~̉S zj;_^_ l]:9ugl)/ZZ{55p]vxHiⱞg`87{ aW9]\RTcb9S wBh[YehS %&j b$eڤ0#j05@{hZBUbp;.E ~5 bQ1#H;HXԁ5~q6 8%_ 2N*bؕx1ō1(n'ō1M 9b~ؙs İs.yk}RiĘAEKt^ 2şH]#[ޯ:F5)nRć"]]n@HR  ;, {GWa%~ u4Mz m6`x>[Ŀ/n@CNx2a3S2)\EfPv ëëg\:*=^DA>+|~ʮ"F =`](Zh? +n<|bgeI_Wk;!PK G:(4+*org/mockito/cglib/util/SorterTemplate.javaWn"G}+J~sC1ZY 4f&= VOU/" LW:uzܿn5ywŔ\t x6wTtw.Adpm],xgoz G Z87 \C(VljPz5𖊡9CT̚V)~? ӌ{c|Eֱ׳ 8)/߀HfK$< l#9)hR(n:D JJATIbYԍp5x~?y@|fb}{X~{?|.l-aKOq u MrkYuM]MQ吱W\;ފV?;X&Y,i#3«LӴ#Oa3רV@zJ"5r*}|Znz1 C\q!n1Į@:j8G|?ZfyM-NV.-͙U295TuYT&^h2th*nUSb-N/־}Hk+-{jc(?Bl XC+_< 4a`îۭR2{&I[\&Q'-arQܬ/{/:蔥XU 苣b-ͧ /jHp76?&h'ރ&%X3muf ԋ}@۞V΄8|`sPvf MDE.6 qRE SB%:do T"#ZIc;❂IkR9NK9ls.Se#NJ3J wWQuXUW=S7cGO͌TA>wdS O_URU(N Cw3,`>)iݪ+'&dڜ7|Sh(e/4_ JFzW]C{Sy\NeoPfJDTGRUNZ9a.Q PK )w:W,7org/mockito/cglib/util/StringSwitcher$Generator$1.classTRA= Es6KD(X`M!RR?*˃GYlRUIvg3yW1k)״*,@JIRVUxcg50͝\V!ʐ=JfhBdEnenmjhc?XfF2-X}!*~ #ҧWHꈣaT4t3t)жmC0]tbM = %`)0,vToR*y^:2X`Z>`'"8#3;ʻM)"CLa<ks-ES,/ dsK9wu}ϗtLrBwyP iM:k:1)?.d005$VݯI-)!G '缠 sJ5C "љ>n|T7̵=˶x^ %鈧ZYx͝[,HEDz]|"Ku% ?c#YD 5:YPџS! y a0b$3]f`3G& {p /hrUI'3;IJH~L3{{x$VM T#xG)>fQW|b_ Gh hu !0 PK )w:VZl5org/mockito/cglib/util/StringSwitcher$Generator.classVWW^$ Aպ@ K`Jkl*mq2 adЙBWv~b?FO@9gM{? Df":TF4;UlMvۦf$Oi2UTC5e;i "F-۔M-+Hҙ '䓲NLE D^ foB;vlDMnkh.jLkT5æE_L@1Do n( a(p?֑l{X#ٍeԖ,X"\4X*Ac- ^ ZGpo +yCjUՙUU9K` U"$$g#ps[M.xbM2]9!܇ERLU)kxArt^6+'%cLP{Bc?FvY`Ldx v[2 A%,&4c@q- b|/<]8h 1sϦh2PzDvW(Y)g"P| ~SqDyomdR$WxcVWb8EҪ1nwH&2%Z}mj&i :љ]d zL; fu |:2!}FaIW7×O\+A|/=<ّSfEN;)u6CÎ:3ka-Ӟ+PtɌ=A㣸.#JPK )w:STU7=org/mockito/cglib/util/StringSwitcher$StringSwitcherKey.class@Dpp,ҙj]qfU|5 -D)z:0mʶ(3jb;4U&ʉ_L=g-V. +/Qc#@oPK )w:}f+org/mockito/cglib/util/StringSwitcher.classUkSa~^F^ЬR 4Xˌ6 KS?8F[8K9cN4}G5wAL/ޞ\8')l0͢[vY֊%}GzI٦nsu[{M/C;*T(E'CidLhCKjɁ~dmqᚡ'_UK۹u%|ZeCv= J6]X̬ghe9hvSd~eRzI[ډɣ\9Bx+s*4lF#T:Ñ AvmQK,C ^+M`wxKoA\o[Z_+^fp7`p!nW՘pyAQnm&-w]\ Ф)U0'AޯW/08dxňtQб\_1+$3SG{dۀL4CA#rIa=1_C#dunJp,hNn5@;.'s_PK lN:iB*org/mockito/cglib/util/StringSwitcher.javaXmoF_1}q"]]k)Gt* BY6C)3~TR>̚\B_&{%} ^7kcÍL3Bƨ@:05_.pTV:pϕF γ+)lbi m kqO M"NYCfC. Cq ޭL5]cnؗ*FNVwG`<Ũs8ZBᖗ{` %H,T׌wJdg%Qbjyb8`8;zCF~o'ws7`)'p2ƻp1C?9Q S|eq^ a-]H:X) 9w W[)\HlЇ"G3 VH?#S#3 K*'fê[1{uuLhĖ<::'uHmKˀ913 ?탶w0ìO"6H$!Kl~\jn|lf$]"2 yPҾ[%Y> ѿLB'LiNy;~ݥc>g"I }ot78 gQ=ⴛZD_ 7|2}(zbwJoqF ՚,1Ƌ(3!x})eı-ql/λe]p#*r>\hN cdTB5ٱQ3bcNQ rreEY#&mslL)/=X_6hŶ:sJOD0MpRB/42lh\,)KXbQDG>Z-|1#əBzrEFJy'wK .)+rHpd\3LGYYbݣV VePL./e#χK7EA(i@1Au|Ce7u& Qd lP% jm`g DWVoo5Ǽ6$[maTuE51gu߾Fa0 ɩyh5#)k)-k0(;8dWBh_e(/WϗPK L<$C:0org/mockito/configuration/AnnotationEngine.classuJ@5j/ \79?;||~Ő0.޵BYYֈcɴD4x]Y]Me# c9O#\O}B-Ub9_t.ZunYEAj3ǹ,t?)M4^ox ȹ90$f:3җ ^?̖ND:袪N!qݟpIAPK .<[T/org/mockito/configuration/AnnotationEngine.javamj0ǿ5 clRlJ (Q+$7 モYVY:w'/f`MvT 0S\;/*H2MUډlD ^bZSET'$EYGVQ#&G+8Z։ȬƣH5\gPhaBC!׽aQF.veJ>y.f09:j%a[eJrm杽73 {o+S !(,#5y4QNЇE6~al H~ibtY| hJetņ^leRIǥ|K=gL aձw0_6k 9R◅+8] c>pT?PK L<V;org/mockito/configuration/DefaultMockitoConfiguration.classSYOAvQp9CiX0l001Yd|iff7=="o D}GkˀVMWuUu_߾#X!Li{(]%kfgq`^gf?VB`}`vouk*P&`T%w&j):r}=U`,#"ϛUQnb-,9r՗ΰ0UŻp}'F|˻Y |v1WrQ:*<*q=St_)}#Qmֻ34*m(&XsjTz̫!i "Sq[F#t҂LbGmkD&v3,E?,Ze|,uFagɋжV }?&Ը0Hdp1b|-I6c.vZF-]\{MT. L |78SMx׹M |<".n _2=fqֱpb"%\\\AԸ7(FM \%r$3Rk0 4)jBm6q7~s ɯ[P p>FUOav),>xx(,gǯ) |.DE|"PK .<ݛw:org/mockito/configuration/DefaultMockitoConfiguration.javaTn0 PEK$C-]PIbLI5{Xv["wl>.t1|FpVΈs{_ ѕa k ȄdDT\4t>n,.|-L #6ѝ];Dx s -R 뾼A@Ʉ*5z w.n/ﺶ5hfbӤ@Z&e>ONHطl#E]..[1NJEbCቪ'fsHV?GJ,-[v]ntŗeOs =mq!k/4I] dӔziM]gY(v%&/iYId;> e]߷rC6Ha]2;~#r5z%MC LP'p0^ja}ϛwUzܿSzudwn{r}$Ə0r×PK L<$L"05org/mockito/configuration/IMockitoConfiguration.class}PMK1^KXU*B+=x%6l̓?%nͼy3/_.p$YDsfHY3Ipkk%| S&T$z| e?E@#!?$4P&pjٮ`eҧWGJzzaɓ4!=8/|ceY3<ӭI!NA{b[$M6R͞TItN8E;-VS(f -ȇ7??=su0ɧ͛˗:8ȝ ^g]pc Z**Ji2=!o\|{{%IfM6h:vD7O .G-V.˴f3AY7mXh{&牴AHEԸam;;?Vg]`r3,̋Pv 3Wu|8 +Bp,Ge,b&G5Łw~)BC + _Chc& W6\B˒'g1Bamfi2*lPi̒AMB,N6eTO"SDap2euh5d}k˺[(4ZC,U/ ( FDKSa<QpoyPu"SΞc\O+F;\ gnuhr"&lAB63mudt7ny%^}>cG}966neXmKpV@? xuKWn҅grێWhM&|ܩV3dzn"[ENʦȗ}Rfk)O:}2'n%QfH ++%6ModvW#R۵][|PhKG]L=KH[BO7JUI8hbdw:t56ؼC&VwƯI*mǂJF00Gyz Գ0ƤSk[&Ƙ ͵Q"`JX 8?/}*ugoPK - ŀ|6z=z+.v0`><y۵PK -<vB4&org/mockito/exceptions/Pluralizer.java5Nj@ BC衧Bh4 GEZ +<[ fCg wY 8p(QZoNiؙr8@q/Glu5{6=!J뵖,1]]J[XgR›b Dh)c!d9i0f 3[oLBlV替60].,ĞJk^bR*+CyAH ě G PK -wG6q245Nܒs+]Gq8 nO]8up&'$ 1YLbf[IɴksE2-DDC0$&FI'+Wԥ7QPNer L3!T:F {+L$VJRJFh:'YH=!7BN~'I=1<` =t\dRo҄Lqdz?=zcK`1Ф;^f)%5`cbN%-x&JW3,OXעҍQA̲%(1-Ėb^_鱰F"Ce1=f^f"qيt}4,'F$,of\\ jPDC*d?V',@.;ΐXBރ4ocA.N2i2 VlIVY=9 P">SvK)Tv-f8n)8{I\}60͙V%Fq16Lfس`5作BZ>od8~8bθBET}[lSrv~N]͹4:·[mLCrg͒hR|*->{'=ooI1#}goNCuS kQ<<GܦI|Q|)- ,#SObz-Ĩ)\+~U|Q|lVVcR|3-f4wB*5W- ޘѫLD#Ea{9@ʝI&וt>D]YZ^Ict(J!u>qn;7Dv~*~ ˮ\u;'Zy7P&ėߊCE iqV3+ TUۗܡS(tӻ Rֳ?sRᖢDݧCh˫[&o^ٿDC/7*b%hk@4'{Uf4My)IiK>9$ ' |>/6'w]ml^u.U[GmINE7o}$9Ɔ \B$RTճְZH{zvA. 1`4]&}r2Tsqy1]9`\>htLſ=ׄgDJZImA: L#$uix2>]WHuް[ż@Ij=h  0FTL:ÿN1U]EWi=mGC@pkGBYˀ'4SM2}wbVz qY~n m'q>/Z4  *3ּ "{~ʴr?nshG;3$C@1?YuҴVꉌAG4JوmDPzN1/ϸ. B a&C{9\?|00J4 w#qD20f|qf?渮0]3yW՝[:q9EzRris8o`0`"UjH\z"rUXNUe4L4(wI.O#z&RuyЯT 3ҬRJ[39c]dyli38ÕuP;9z>;g]$ðڪIzDcQybYp=)_E89*84 f>.L'1[M9f]̛ѡ3Qx/ )-EO#[q cRP"TYlu,O3`Om}ٰU2|v7 sOA JSe wOZ1$ !ÚY|Oϭ<&ɦ$Ҋ{EFVXށ6jS A W=i:X.o9PrJ+Jy2 rbe`Ko}SO57q^$l5WXxW2w0!;-s[w?1T^v0T\{ cfA=ArC L絲o~Dn a'<3>O8kz\ ŕ%] 'nlxCI,+ٮmIٮ(C.2/ڢ 4}NO q}E2TwF2I9=$zҝD;{A\V#9f!ͯ~V`snDZWľIbvy•|@2 yuz"&PZT,E&V#HtU|FvPFh=LBGT\#aZ|n4UEL]mr9-ߐVΟjp{:VWэ* ɩu%>4>-X%.72~`svmR&1m#Yce_F}#-Yѓwj_ޓ첩DF*qMGwF-' USbn/'{;!9+I M$NX'[jS*ٓfey)jk1gx "z^s̉PWWRxC&P,"_{7,Wy֨[ʙ8vA 1;Oy]1L0fpʟE82.O%.&snbt} 2ތ{.s~3]$b7bг EBTV) M. kVUD뢿y]y' |%q/Q:9e:LYK!'&1]y.xGʾH% n&r!2b-ץZ]Yܓ4đON0e)Z ڒ4,)j_9k  $bCU`l!#0Y+G9o p T}"0q]R£qsE rDYԕ 20j{uC͜8; %ZQ>bwm£i$6yb p9gөD|yE[J=a:Mnjnb%D'7hH9\Q.q_wȻBr\/Mf7r%Rpb`)xR\9R$ʭ^fAF&xK-rcID_z~%dok¶eCën:8;NaΓ%ou 9ЇQG#EM]B=N7oOu7=_[V%fYYGua퐀?v455^*9;q3]YV&I2MQ*D7v<$cv_-\X9 N׏csN\8}'g8x X^K.ݏj-G, 2((u "Dc1.H$٤^W{|ųI,Гo -4?0%Zψ /<-.YuZ\vZ,[Jtnk- Э̫Aꪡp_P<0EI1xO|U`c&7.|?x(V<.m\5\&|[W<<XG*yʍ %Z4fp_gdd:-wC˛=W6VX\ x\ !  3:zhvF#8#Yzo: =^eB;&%8 p<m} kv1cU3tO3 XaZ ŀhJC5D}Ḥ#` 0&ƶ!4Lc i`Zc0`:L'ɦ![5)!jhed'Ci1qWTgȏrBkR@eW蘠[tHU9GnTyHae ֹ0q+=XZijfuJk r̳ `z4RZ|2B3GyXi/cuXOHOB$~ P<֞Nf nKTpOW; pg=+ 9l@l1s܊x?T61Ea~d")HN/xl^鴅^3Mu:'Zv0e^wʵQWE-f(Z, t(f{魺Ko^)91fOj;KߩKxd:7@ӻt*XOﮬ M la>QmZz#B };t|?C2h@V3ڐ6}8K1r5ᗭw}X-:HLk_ [RQXSƏX-675;?5((Gt-i-!~aуv[WL~/M1; @WI^M @2}6\PH? U4?+ϳ߳w@^k/[^ӉyZ5M,`+K,dKfhrF' '& V)iQEF(ڢВ5qbvl l{51'Z%i/!7l3I50a#0%Ӵ5+cId+WbJ1; R++83ʭ壴YZ牕 'bFGxI>u#;s|O>]>k_bO_<^4/PK -.˩ fDL菋+JNDEP,3LU./4RɃrTap#'7E]B.IY6%/"*U`v+M}cqd:ZT˪RՓ=f_րw~^ﵸ]p3JBjy!\Mpo@9bf]6Oa'R깘3x _Qə-!>VZ/-o/jkMf~R] Q}Rr6Aާk|,AP-|B,[ o(һlAR4'SP/ ^$wn` m8[]JmɹMŸF|?>Z4ɊW`ЂTo*?YExLJ YL)^=]?.KgfKGrI8L)՚Y?A` 5x,1Y2, > ?W %AL OO=E\1v[0tK671))03U DAkp@['E>bC` : yl\ Y#r/Bhtʲ/(ld@U3gTB%;RxInvǃ >ፒSksoռR+)115+Ŋm:7o] "D* 1!Gh1;`0|4zB/Ke5}f61*2:6+CxDoZo[V_88.)æXG`"^9 wi1|רc I_bYUUQ0E2)ԗ(5U-FOJR>UCqk6`~AUɱ?L}=FZD&Gljd{b6ԀA `$2",liQׂ$1k4GQhKIw]RO)Y -3x0 ɜ9eGoHΎh()g`ƄRz- V& iQI}wRhudM(9` %#hU/a'^4R ^(dÄDgZe7܈c/c  걕$%\i! b 򑱬plQVw5&AW>MKmbbĽ%7kkkh[!ou wK>U">,mn-$ v; 춠gn_v;̿MLKִ:w ?ֲ%E w X R.96nYCg7dn^ALm.ˉȶ$,CxĊTmx2_S?8dEB-)H[^ p!c0 vnL!6#?׫@ ܑƷNw8]omd6_-ʃE)kb/7T~iҦpvƜ/bx룸!? ]!D=%oEn8*7m/d!yuA);ӣ+t{NVkD$YѮ⺁ytl0l݊(W|YRy ȱD9[&{)QN5K 12^ub1fR\,z[@tcVX;g3~ۚ,TZݶ>Vg7F=?#$%{E/L=`c6|Ɵ䆹FYd[ ?xc듁!冼N$i|,xʯۻpZ!e]-䈤07}JzčTNºP!ua3;1A=)=C( ͊[PP+HT܉PRiLG%,u^ῘJTh8M{C"3Bm-LGW/މf-&_ ^p/1GxJINVѴJ: YbR q#X*<nIgs#;1qÙN Px}g}cTPͲ Xd g-&#gtӆgP%O KnczqEj9MyG;ǭ+%R*_.Jg"G#/bfrԪiQ:zzf37viYCw{pğqޯ.ҿLC14@]'O0CbJ.w!s*OT[7ygX<{iӏ{i$ڱ^+@:4>oLomOk/U^}@P݅4/fK65myt5f|!FGz`QpY.Yq__gl*.gWхHٞ`wZb|B^ .Al"XRG ,RRaWs^> 0cD'3)}><+ؗyQ}MC?f;%d/Pb"1m _P]04jd&vKXF]sLtMO&^" .yFݏp Mk`@ih#._j! & AU86<ȝ4Zw~H.?Գo{4ssنLYyre?o7 #5UL^Vy="3!3\R_}]g+ (%ޙZi7BlןPK L<77org/mockito/exceptions/base/MockitoAssertionError.classRn@= $M I)-$EXE(E4i,@*Qc;"<9;;g;Mllv|H޻M}8}(g7cosCV:4CnJ~;bZz=e?}, e dȓ-%>(8p۪`W`X=r.ҳrtdVF9LfLVtH3$PH'/]xW쐱p5P1LwI$0Qpkߥa+z2NZ?