aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog4
-rw-r--r--include/qpdf/QPDFObjectHandle.hh7
-rw-r--r--libqpdf/QPDFObjectHandle.cc56
-rw-r--r--manual/qpdf-manual.xml20
-rw-r--r--qpdf/qpdf.cc109
-rw-r--r--qpdf/qpdf.testcov1
-rw-r--r--qpdf/qtest/qpdf.test20
-rw-r--r--qpdf/qtest/qpdf/rotated.pdfbin0 -> 7319 bytes
-rw-r--r--qpdf/qtest/qpdf/to-rotate.pdf909
9 files changed, 1126 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index 3b7eb32a..93a380dd 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
2017-08-12 Jay Berkenbilt <ejb@ql.org>
+ * Add QPDFObjectHandle::rotatePage to apply rotation to a page
+ object. Add --rotate option to qpdf to specify page rotation from
+ the command line.
+
* Provide --verbose option that causes qpdf to print an indication
of what files it is writing.
diff --git a/include/qpdf/QPDFObjectHandle.hh b/include/qpdf/QPDFObjectHandle.hh
index 456dade4..fbe02ba8 100644
--- a/include/qpdf/QPDFObjectHandle.hh
+++ b/include/qpdf/QPDFObjectHandle.hh
@@ -507,6 +507,13 @@ class QPDFObjectHandle
QPDF_DLL
void addPageContents(QPDFObjectHandle contents, bool first);
+ // Rotate a page. If relative is false, set the rotation of the
+ // page to angle. Otherwise, add angle to the rotation of the
+ // page. Angle must be a multiple of 90. Adding 90 to the rotation
+ // rotates clockwise by 90 degrees.
+ QPDF_DLL
+ void rotatePage(int angle, bool relative);
+
// Initializers for objects. This Factory class gives the QPDF
// class specific permission to call factory methods without
// making it a friend of the whole QPDFObjectHandle class.
diff --git a/libqpdf/QPDFObjectHandle.cc b/libqpdf/QPDFObjectHandle.cc
index e263a3ec..a8a7e5a7 100644
--- a/libqpdf/QPDFObjectHandle.cc
+++ b/libqpdf/QPDFObjectHandle.cc
@@ -673,6 +673,62 @@ QPDFObjectHandle::addPageContents(QPDFObjectHandle new_contents, bool first)
this->replaceKey("/Contents", contents);
}
+void
+QPDFObjectHandle::rotatePage(int angle, bool relative)
+{
+ assertPageObject();
+ if ((angle % 90) != 0)
+ {
+ throw std::runtime_error(
+ "QPDF::rotatePage called with an"
+ " angle that is not a multiple of 90");
+ }
+ int new_angle = angle;
+ if (relative)
+ {
+ int old_angle = 0;
+ bool found_rotate = false;
+ QPDFObjectHandle cur_obj = *this;
+ bool searched_parent = false;
+ std::set<QPDFObjGen> visited;
+ while (! found_rotate)
+ {
+ if (visited.count(cur_obj.getObjGen()))
+ {
+ // Don't get stuck in an infinite loop
+ break;
+ }
+ if (! visited.empty())
+ {
+ searched_parent = true;
+ }
+ visited.insert(cur_obj.getObjGen());
+ if (cur_obj.getKey("/Rotate").isInteger())
+ {
+ found_rotate = true;
+ old_angle = cur_obj.getKey("/Rotate").getIntValue();
+ }
+ else if (cur_obj.getKey("/Parent").isDictionary())
+ {
+ cur_obj = cur_obj.getKey("/Parent");
+ }
+ else
+ {
+ break;
+ }
+ }
+ QTC::TC("qpdf", "QPDFObjectHandle found old angle",
+ searched_parent ? 0 : 1);
+ if ((old_angle % 90) != 0)
+ {
+ old_angle = 0;
+ }
+ new_angle += old_angle;
+ }
+ new_angle = (new_angle + 360) % 360;
+ replaceKey("/Rotate", QPDFObjectHandle::newInteger(new_angle));
+}
+
std::string
QPDFObjectHandle::unparse()
{
diff --git a/manual/qpdf-manual.xml b/manual/qpdf-manual.xml
index d05af020..0266a1dc 100644
--- a/manual/qpdf-manual.xml
+++ b/manual/qpdf-manual.xml
@@ -349,6 +349,26 @@ make
</listitem>
</varlistentry>
<varlistentry>
+ <term><option>--rotate=[+|-]angle:page-range</option></term>
+ <listitem>
+ <para>
+ Apply rotation to specified pages. The
+ <option>page-range</option> portion of the option value has
+ the same format as page ranges in <xref
+ linkend="ref.page-selection"/>. The <option>angle</option>
+ portion of the parameter may be either 90, 180, or 270. If
+ preceded by <option>+</option> or <option>-</option>, the
+ angle is added to or subtracted from the specified pages'
+ original rotations. Otherwise the pages' rotations are set to
+ the exact value. For example, the command <command>qpdf in.pdf
+ out.pdf --rotate=+90:2,4,6 --rotate=180:7-8</command> would
+ rotate pages 2, 4, and 6 90 degrees clockwise from their
+ original rotation and force the rotation of pages 7 through 9
+ to 180 degrees regardless of their original rotation.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
<term><option>--pages options --</option></term>
<listitem>
<para>
diff --git a/qpdf/qpdf.cc b/qpdf/qpdf.cc
index b68434a9..f6b1de28 100644
--- a/qpdf/qpdf.cc
+++ b/qpdf/qpdf.cc
@@ -37,6 +37,18 @@ struct PageSpec
char const* range;
};
+struct RotationSpec
+{
+ RotationSpec(int angle = 0, bool relative = false) :
+ angle(angle),
+ relative(relative)
+ {
+ }
+
+ int angle;
+ bool relative;
+};
+
struct Options
{
Options() :
@@ -151,6 +163,7 @@ struct Options
bool show_page_images;
bool check;
std::vector<PageSpec> page_specs;
+ std::map<std::string, RotationSpec> rotations;
bool require_outfile;
char const* infilename;
char const* outfilename;
@@ -209,6 +222,8 @@ Basic Options\n\
--encrypt options -- generate an encrypted file\n\
--decrypt remove any encryption on the file\n\
--pages options -- select specific pages from one or more files\n\
+--rotate=[+|-]angle:page-range\n\
+ rotate each specified page 90, 180, or 270 degrees\n\
--split-pages=[n] write each output page to a separate file\n\
\n\
If none of --copy-encryption, --encrypt or --decrypt are given, qpdf will\n\
@@ -219,6 +234,13 @@ parameters will be copied, including both user and owner passwords, even\n\
if the user password is used to open the other file. This works even if\n\
the owner password is not known.\n\
\n\
+The --rotate flag can be used to specify pages to rotate pages either\n\
+90, 180, or 270 degrees. The page range is specified in the same\n\
+format as with the --pages option, described below. Repeat the option\n\
+to rotate multiple groups of pages. If the angle is preceded by + or -,\n\
+it is added to or subtracted from the original rotation. Otherwise, the\n\
+rotation angle is set explicitly to the given value.\n\
+\n\
If --split-pages is specified, each page is written to a separate output\n\
file. File names are generated as follows:\n\
* If the string %d appears in the output file name, it is replaced with a\n\
@@ -1148,6 +1170,62 @@ static void handle_help_verison(int argc, char* argv[])
}
}
+static void parse_rotation_parameter(Options& o, std::string const& parameter)
+{
+ std::string angle_str;
+ std::string range;
+ size_t colon = parameter.find(':');
+ int relative = 0;
+ if (colon != std::string::npos)
+ {
+ if (colon > 0)
+ {
+ angle_str = parameter.substr(0, colon);
+ if (angle_str.length() > 0)
+ {
+ char first = angle_str.at(0);
+ if ((first == '+') || (first == '-'))
+ {
+ relative = ((first == '+') ? 1 : -1);
+ angle_str = angle_str.substr(1);
+ }
+ else if (! QUtil::is_digit(angle_str.at(0)))
+ {
+ angle_str = "";
+ }
+ }
+ }
+ if (colon + 1 < parameter.length())
+ {
+ range = parameter.substr(colon + 1);
+ }
+ }
+ bool range_valid = false;
+ try
+ {
+ parse_numrange(range.c_str(), 0, true);
+ range_valid = true;
+ }
+ catch (std::runtime_error)
+ {
+ // ignore
+ }
+ if (range_valid &&
+ ((angle_str == "90") || (angle_str == "180") || (angle_str == "270")))
+ {
+ int angle = atoi(angle_str.c_str());
+ if (relative == -1)
+ {
+ angle = -angle;
+ }
+ o.rotations[range] = RotationSpec(angle, (relative != 0));
+ }
+ else
+ {
+ usage("invalid parameter to rotate: " + parameter);
+ }
+}
+
static void parse_options(int argc, char* argv[], Options& o)
{
for (int i = 1; i < argc; ++i)
@@ -1237,6 +1315,10 @@ static void parse_options(int argc, char* argv[], Options& o)
usage("--pages: no page specifications given");
}
}
+ else if (strcmp(arg, "rotate") == 0)
+ {
+ parse_rotation_parameter(o, parameter);
+ }
else if (strcmp(arg, "stream-data") == 0)
{
if (parameter == 0)
@@ -1829,6 +1911,29 @@ static void handle_page_specs(QPDF& pdf, Options& o,
}
}
+static void handle_rotations(QPDF& pdf, Options& o)
+{
+ std::vector<QPDFObjectHandle> pages = pdf.getAllPages();
+ int npages = static_cast<int>(pages.size());
+ for (std::map<std::string, RotationSpec>::iterator iter =
+ o.rotations.begin();
+ iter != o.rotations.end(); ++iter)
+ {
+ std::string const& range = (*iter).first;
+ RotationSpec const& rspec = (*iter).second;
+ std::vector<int> to_rotate = parse_numrange(range.c_str(), npages);
+ for (std::vector<int>::iterator i2 = to_rotate.begin();
+ i2 != to_rotate.end(); ++i2)
+ {
+ int pageno = *i2 - 1;
+ if ((pageno >= 0) && (pageno < npages))
+ {
+ pages.at(pageno).rotatePage(rspec.angle, rspec.relative);
+ }
+ }
+ }
+}
+
static void set_encryption_options(QPDF& pdf, Options& o, QPDFWriter& w)
{
int R = 0;
@@ -2124,6 +2229,10 @@ int main(int argc, char* argv[])
{
handle_page_specs(pdf, o, page_heap);
}
+ if (! o.rotations.empty())
+ {
+ handle_rotations(pdf, o);
+ }
if (o.outfilename == 0)
{
diff --git a/qpdf/qpdf.testcov b/qpdf/qpdf.testcov
index 14ff9f6c..72f5331e 100644
--- a/qpdf/qpdf.testcov
+++ b/qpdf/qpdf.testcov
@@ -295,3 +295,4 @@ QPDF ignore second extra space in xref entry 0
QPDF ignore length error xref entry 0
QPDF_encryption pad short parameter 0
QPDFWriter ignore self-referential object stream 0
+QPDFObjectHandle found old angle 1
diff --git a/qpdf/qtest/qpdf.test b/qpdf/qtest/qpdf.test
index 98887102..9242a8a7 100644
--- a/qpdf/qtest/qpdf.test
+++ b/qpdf/qtest/qpdf.test
@@ -780,6 +780,26 @@ foreach my $d (@sp_cases)
show_ntests();
# ----------
+$td->notify("--- Rotate Pages ---");
+$n_tests += 2;
+# XXX do absolute, positive, and negative on ranges that include
+# inherited and non-inherited.
+# Pages 11-15 inherit /Rotate 90
+# Pages 1 and 2 have explicit /Rotate 270
+# Pages 16 and 17 have explicit /Rotate 180
+
+$td->runtest("page rotation",
+ {$td->COMMAND => "qpdf --static-id to-rotate.pdf a.pdf" .
+ " --rotate=+90:1,4,11,16" .
+ " --rotate=180:2,5,12-13" .
+ " --rotate=-90:3,15,17,18"},
+ {$td->STRING => "", $td->EXIT_STATUS => 0});
+$td->runtest("check output",
+ {$td->FILE => "a.pdf"},
+ {$td->FILE => "rotated.pdf"});
+
+show_ntests();
+# ----------
$td->notify("--- Numeric range parsing tests ---");
my @nrange_tests = (
[",5",
diff --git a/qpdf/qtest/qpdf/rotated.pdf b/qpdf/qtest/qpdf/rotated.pdf
new file mode 100644
index 00000000..06cef942
--- /dev/null
+++ b/qpdf/qtest/qpdf/rotated.pdf
Binary files differ
diff --git a/qpdf/qtest/qpdf/to-rotate.pdf b/qpdf/qtest/qpdf/to-rotate.pdf
new file mode 100644
index 00000000..43b549f5
--- /dev/null
+++ b/qpdf/qtest/qpdf/to-rotate.pdf
@@ -0,0 +1,909 @@
+%PDF-1.4
+%¿÷¢þ
+%QDF-1.0
+
+1 0 obj
+<<
+ /Pages 3 0 R
+ /Type /Catalog
+>>
+endobj
+
+2 0 obj
+<<
+ /CreationDate (D:20120721200217)
+ /Producer (Apex PDFWriter)
+>>
+endobj
+
+3 0 obj
+<<
+ /Count 20
+ /Kids [
+ 4 0 R
+ 5 0 R
+ 6 0 R
+ 7 0 R
+ 8 0 R
+ 9 0 R
+ 10 0 R
+ 11 0 R
+ 12 0 R
+ 13 0 R
+ 14 0 R
+ 15 0 R
+ 16 0 R
+ 17 0 R
+ 18 0 R
+ 19 0 R
+ ]
+ /Type /Pages
+>>
+endobj
+
+%% Page 1
+4 0 obj
+<<
+ /Contents 20 0 R
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 3 0 R
+ /Resources <<
+ /Font <<
+ /F1 22 0 R
+ >>
+ /ProcSet [
+ /PDF
+ /Text
+ ]
+ >>
+ /Rotate 270
+ /Type /Page
+>>
+endobj
+
+%% Page 2
+5 0 obj
+<<
+ /Contents 23 0 R
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 3 0 R
+ /Resources <<
+ /Font <<
+ /F1 22 0 R
+ >>
+ /ProcSet [
+ /PDF
+ /Text
+ ]
+ >>
+ /Rotate 270
+ /Type /Page
+>>
+endobj
+
+%% Page 3
+6 0 obj
+<<
+ /Contents 25 0 R
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 3 0 R
+ /Resources <<
+ /Font <<
+ /F1 22 0 R
+ >>
+ /ProcSet [
+ /PDF
+ /Text
+ ]
+ >>
+ /Type /Page
+>>
+endobj
+
+%% Page 4
+7 0 obj
+<<
+ /Contents 27 0 R
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 3 0 R
+ /Resources <<
+ /Font <<
+ /F1 22 0 R
+ >>
+ /ProcSet [
+ /PDF
+ /Text
+ ]
+ >>
+ /Type /Page
+>>
+endobj
+
+%% Page 5
+8 0 obj
+<<
+ /Contents 29 0 R
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 3 0 R
+ /Resources <<
+ /Font <<
+ /F1 22 0 R
+ >>
+ /ProcSet [
+ /PDF
+ /Text
+ ]
+ >>
+ /Type /Page
+>>
+endobj
+
+%% Page 6
+9 0 obj
+<<
+ /Contents 31 0 R
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 3 0 R
+ /Resources <<
+ /Font <<
+ /F1 22 0 R
+ >>
+ /ProcSet [
+ /PDF
+ /Text
+ ]
+ >>
+ /Type /Page
+>>
+endobj
+
+%% Page 7
+10 0 obj
+<<
+ /Contents 33 0 R
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 3 0 R
+ /Resources <<
+ /Font <<
+ /F1 22 0 R
+ >>
+ /ProcSet [
+ /PDF
+ /Text
+ ]
+ >>
+ /Type /Page
+>>
+endobj
+
+%% Page 8
+11 0 obj
+<<
+ /Contents 35 0 R
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 3 0 R
+ /Resources <<
+ /Font <<
+ /F1 22 0 R
+ >>
+ /ProcSet [
+ /PDF
+ /Text
+ ]
+ >>
+ /Type /Page
+>>
+endobj
+
+%% Page 9
+12 0 obj
+<<
+ /Contents 37 0 R
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 3 0 R
+ /Resources <<
+ /Font <<
+ /F1 22 0 R
+ >>
+ /ProcSet [
+ /PDF
+ /Text
+ ]
+ >>
+ /Type /Page
+>>
+endobj
+
+%% Page 10
+13 0 obj
+<<
+ /Contents 39 0 R
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 3 0 R
+ /Resources <<
+ /Font <<
+ /F1 22 0 R
+ >>
+ /ProcSet [
+ /PDF
+ /Text
+ ]
+ >>
+ /Type /Page
+>>
+endobj
+
+14 0 obj
+<<
+ /Count 5
+ /Kids [
+ 41 0 R
+ 42 0 R
+ 43 0 R
+ 44 0 R
+ 45 0 R
+ ]
+ /Parent 3 0 R
+ /Rotate 90
+ /Type /Pages
+>>
+endobj
+
+%% Page 16
+15 0 obj
+<<
+ /Contents 46 0 R
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 3 0 R
+ /Resources <<
+ /Font <<
+ /F1 22 0 R
+ >>
+ /ProcSet [
+ /PDF
+ /Text
+ ]
+ >>
+ /Rotate 180
+ /Type /Page
+>>
+endobj
+
+%% Page 17
+16 0 obj
+<<
+ /Contents 48 0 R
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 3 0 R
+ /Resources <<
+ /Font <<
+ /F1 22 0 R
+ >>
+ /ProcSet [
+ /PDF
+ /Text
+ ]
+ >>
+ /Rotate 180
+ /Type /Page
+>>
+endobj
+
+%% Page 18
+17 0 obj
+<<
+ /Contents 50 0 R
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 3 0 R
+ /Resources <<
+ /Font <<
+ /F1 22 0 R
+ >>
+ /ProcSet [
+ /PDF
+ /Text
+ ]
+ >>
+ /Type /Page
+>>
+endobj
+
+%% Page 19
+18 0 obj
+<<
+ /Contents 52 0 R
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 3 0 R
+ /Resources <<
+ /Font <<
+ /F1 22 0 R
+ >>
+ /ProcSet [
+ /PDF
+ /Text
+ ]
+ >>
+ /Type /Page
+>>
+endobj
+
+%% Page 20
+19 0 obj
+<<
+ /Contents 54 0 R
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 3 0 R
+ /Resources <<
+ /Font <<
+ /F1 22 0 R
+ >>
+ /ProcSet [
+ /PDF
+ /Text
+ ]
+ >>
+ /Type /Page
+>>
+endobj
+
+%% Contents for page 1
+20 0 obj
+<<
+ /Length 21 0 R
+>>
+stream
+BT /F1 15 Tf 72 720 Td (Original page 1) Tj ET
+endstream
+endobj
+
+21 0 obj
+47
+endobj
+
+22 0 obj
+<<
+ /BaseFont /Times-Roman
+ /Encoding /WinAnsiEncoding
+ /Subtype /Type1
+ /Type /Font
+>>
+endobj
+
+%% Contents for page 2
+23 0 obj
+<<
+ /Length 24 0 R
+>>
+stream
+BT /F1 15 Tf 72 720 Td (Original page 2) Tj ET
+endstream
+endobj
+
+24 0 obj
+47
+endobj
+
+%% Contents for page 3
+25 0 obj
+<<
+ /Length 26 0 R
+>>
+stream
+BT /F1 15 Tf 72 720 Td (Original page 3) Tj ET
+endstream
+endobj
+
+26 0 obj
+47
+endobj
+
+%% Contents for page 4
+27 0 obj
+<<
+ /Length 28 0 R
+>>
+stream
+BT /F1 15 Tf 72 720 Td (Original page 4) Tj ET
+endstream
+endobj
+
+28 0 obj
+47
+endobj
+
+%% Contents for page 5
+29 0 obj
+<<
+ /Length 30 0 R
+>>
+stream
+BT /F1 15 Tf 72 720 Td (Original page 5) Tj ET
+endstream
+endobj
+
+30 0 obj
+47
+endobj
+
+%% Contents for page 6
+31 0 obj
+<<
+ /Length 32 0 R
+>>
+stream
+BT /F1 15 Tf 72 720 Td (Original page 6) Tj ET
+endstream
+endobj
+
+32 0 obj
+47
+endobj
+
+%% Contents for page 7
+33 0 obj
+<<
+ /Length 34 0 R
+>>
+stream
+BT /F1 15 Tf 72 720 Td (Original page 7) Tj ET
+endstream
+endobj
+
+34 0 obj
+47
+endobj
+
+%% Contents for page 8
+35 0 obj
+<<
+ /Length 36 0 R
+>>
+stream
+BT /F1 15 Tf 72 720 Td (Original page 8) Tj ET
+endstream
+endobj
+
+36 0 obj
+47
+endobj
+
+%% Contents for page 9
+37 0 obj
+<<
+ /Length 38 0 R
+>>
+stream
+BT /F1 15 Tf 72 720 Td (Original page 9) Tj ET
+endstream
+endobj
+
+38 0 obj
+47
+endobj
+
+%% Contents for page 10
+39 0 obj
+<<
+ /Length 40 0 R
+>>
+stream
+BT /F1 15 Tf 72 720 Td (Original page 10) Tj ET
+endstream
+endobj
+
+40 0 obj
+48
+endobj
+
+%% Page 11
+41 0 obj
+<<
+ /Contents 56 0 R
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 14 0 R
+ /Resources <<
+ /Font <<
+ /F1 22 0 R
+ >>
+ /ProcSet [
+ /PDF
+ /Text
+ ]
+ >>
+ /Type /Page
+>>
+endobj
+
+%% Page 12
+42 0 obj
+<<
+ /Contents 58 0 R
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 14 0 R
+ /Resources <<
+ /Font <<
+ /F1 22 0 R
+ >>
+ /ProcSet [
+ /PDF
+ /Text
+ ]
+ >>
+ /Type /Page
+>>
+endobj
+
+%% Page 13
+43 0 obj
+<<
+ /Contents 60 0 R
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 14 0 R
+ /Resources <<
+ /Font <<
+ /F1 22 0 R
+ >>
+ /ProcSet [
+ /PDF
+ /Text
+ ]
+ >>
+ /Type /Page
+>>
+endobj
+
+%% Page 14
+44 0 obj
+<<
+ /Contents 62 0 R
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 14 0 R
+ /Resources <<
+ /Font <<
+ /F1 22 0 R
+ >>
+ /ProcSet [
+ /PDF
+ /Text
+ ]
+ >>
+ /Type /Page
+>>
+endobj
+
+%% Page 15
+45 0 obj
+<<
+ /Contents 64 0 R
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 14 0 R
+ /Resources <<
+ /Font <<
+ /F1 22 0 R
+ >>
+ /ProcSet [
+ /PDF
+ /Text
+ ]
+ >>
+ /Type /Page
+>>
+endobj
+
+%% Contents for page 16
+46 0 obj
+<<
+ /Length 47 0 R
+>>
+stream
+BT /F1 15 Tf 72 720 Td (Original page 16) Tj ET
+endstream
+endobj
+
+47 0 obj
+48
+endobj
+
+%% Contents for page 17
+48 0 obj
+<<
+ /Length 49 0 R
+>>
+stream
+BT /F1 15 Tf 72 720 Td (Original page 17) Tj ET
+endstream
+endobj
+
+49 0 obj
+48
+endobj
+
+%% Contents for page 18
+50 0 obj
+<<
+ /Length 51 0 R
+>>
+stream
+BT /F1 15 Tf 72 720 Td (Original page 18) Tj ET
+endstream
+endobj
+
+51 0 obj
+48
+endobj
+
+%% Contents for page 19
+52 0 obj
+<<
+ /Length 53 0 R
+>>
+stream
+BT /F1 15 Tf 72 720 Td (Original page 19) Tj ET
+endstream
+endobj
+
+53 0 obj
+48
+endobj
+
+%% Contents for page 20
+54 0 obj
+<<
+ /Length 55 0 R
+>>
+stream
+BT /F1 15 Tf 72 720 Td (Original page 20) Tj ET
+endstream
+endobj
+
+55 0 obj
+48
+endobj
+
+%% Contents for page 11
+56 0 obj
+<<
+ /Length 57 0 R
+>>
+stream
+BT /F1 15 Tf 72 720 Td (Original page 11) Tj ET
+endstream
+endobj
+
+57 0 obj
+48
+endobj
+
+%% Contents for page 12
+58 0 obj
+<<
+ /Length 59 0 R
+>>
+stream
+BT /F1 15 Tf 72 720 Td (Original page 12) Tj ET
+endstream
+endobj
+
+59 0 obj
+48
+endobj
+
+%% Contents for page 13
+60 0 obj
+<<
+ /Length 61 0 R
+>>
+stream
+BT /F1 15 Tf 72 720 Td (Original page 13) Tj ET
+endstream
+endobj
+
+61 0 obj
+48
+endobj
+
+%% Contents for page 14
+62 0 obj
+<<
+ /Length 63 0 R
+>>
+stream
+BT /F1 15 Tf 72 720 Td (Original page 14) Tj ET
+endstream
+endobj
+
+63 0 obj
+48
+endobj
+
+%% Contents for page 15
+64 0 obj
+<<
+ /Length 65 0 R
+>>
+stream
+BT /F1 15 Tf 72 720 Td (Original page 15) Tj ET
+endstream
+endobj
+
+65 0 obj
+48
+endobj
+
+xref
+0 66
+0000000000 65535 f
+0000000025 00000 n
+0000000079 00000 n
+0000000165 00000 n
+0000000408 00000 n
+0000000651 00000 n
+0000000894 00000 n
+0000001123 00000 n
+0000001352 00000 n
+0000001581 00000 n
+0000001810 00000 n
+0000002040 00000 n
+0000002270 00000 n
+0000002501 00000 n
+0000002721 00000 n
+0000002879 00000 n
+0000003124 00000 n
+0000003369 00000 n
+0000003600 00000 n
+0000003831 00000 n
+0000004074 00000 n
+0000004178 00000 n
+0000004198 00000 n
+0000004330 00000 n
+0000004434 00000 n
+0000004477 00000 n
+0000004581 00000 n
+0000004624 00000 n
+0000004728 00000 n
+0000004771 00000 n
+0000004875 00000 n
+0000004918 00000 n
+0000005022 00000 n
+0000005065 00000 n
+0000005169 00000 n
+0000005212 00000 n
+0000005316 00000 n
+0000005359 00000 n
+0000005463 00000 n
+0000005507 00000 n
+0000005612 00000 n
+0000005643 00000 n
+0000005875 00000 n
+0000006107 00000 n
+0000006339 00000 n
+0000006571 00000 n
+0000006816 00000 n
+0000006921 00000 n
+0000006965 00000 n
+0000007070 00000 n
+0000007114 00000 n
+0000007219 00000 n
+0000007263 00000 n
+0000007368 00000 n
+0000007412 00000 n
+0000007517 00000 n
+0000007561 00000 n
+0000007666 00000 n
+0000007710 00000 n
+0000007815 00000 n
+0000007859 00000 n
+0000007964 00000 n
+0000008008 00000 n
+0000008113 00000 n
+0000008157 00000 n
+0000008262 00000 n
+trailer <<
+ /Info 2 0 R
+ /Root 1 0 R
+ /Size 66
+ /ID [<e032a88c7a987db6ca3abee555506ccc><0c6f92bbd30230ec62bc832f23eddc35>]
+>>
+startxref
+8282
+%%EOF