Allow adding the same page more than once in --pages (fixes #272)

This commit is contained in:
Jay Berkenbilt 2019-01-12 09:14:20 -05:00
parent 53d8e916b7
commit 654c0e8caf
11 changed files with 727 additions and 12 deletions

View File

@ -1,5 +1,21 @@
2019-01-12 Jay Berkenbilt <ejb@ql.org>
* In the --pages option, allow the same page to be specified more
than once. You can now do "--pages A.pdf 1,1 --" or
"--pages A.pdf 1 A.pdf 1" instead of having to use two different
paths to specify A.pdf. Fixes #272.
* Add QPDFPageObjectHelper::shallowCopyPage(). This method creates
a new page object that is a "shallow copy" of the given page as
described in the comments in QPDFPageObjectHelper. The resulting
object has not been added anywhere but is ready to be passed to
QPDFPageDocumentHelper::addPage of its own QPDF or another QPDF
object.
* Add QPDF::getUniqueId() method to return an identifier that is
intended to be unique within the scope of all QPDF objects created
by the calling application in a single run.
* In --pages, allow "." as a replacement for the current input
file, making it possible to say "qpdf A.pdf --pages . 1-3 --"
instead of having to repeat the input filename.

View File

@ -203,6 +203,16 @@ class QPDF
QPDF_DLL
std::vector<QPDFExc> getWarnings();
// Return an application-scoped unique ID for this QPDF object.
// This is not a globally unique ID. It is constructing using a
// timestamp and a random number and is intended to be unique
// among QPDF objects that are created by a single run of an
// application. While it's very likely that these are actually
// globally unique, it is not recommended to use them for
// long-term purposes.
QPDF_DLL
unsigned long long getUniqueId() const;
QPDF_DLL
std::string getFilename() const;
QPDF_DLL

View File

@ -140,6 +140,19 @@ class QPDFPageObjectHelper: public QPDFObjectHelper
QPDF_DLL
void removeUnreferencedResources();
// Return a new QPDFPageDocumentHelper that is a duplicate of the
// page. The returned object is an indirect object that is ready
// to be inserted into the same or a different QPDF object using
// any of the addPage methods in QPDFPageDocumentHelper or QPDF.
// Without calling one of those methods, the page will not be
// added anywhere. Thew new page object shares all content streams
// and indirect objet resources with the original page, so if you
// are going to modify the contents or other aspects of the page,
// you will need to handling copying of the component parts
// separately.
QPDF_DLL
QPDFPageObjectHelper shallowCopyPage();
private:
class Members
{

View File

@ -2470,6 +2470,12 @@ QPDF::swapObjects(int objid1, int generation1, int objid2, int generation2)
this->m->obj_cache[og2] = t;
}
unsigned long long
QPDF::getUniqueId() const
{
return this->m->unique_id;
}
std::string
QPDF::getFilename() const
{

View File

@ -1,5 +1,6 @@
#include <qpdf/QPDFPageObjectHelper.hh>
#include <qpdf/QTC.hh>
#include <qpdf/QPDF.hh>
QPDFPageObjectHelper::Members::~Members()
{
@ -167,3 +168,17 @@ QPDFPageObjectHelper::removeUnreferencedResources()
}
}
}
QPDFPageObjectHelper
QPDFPageObjectHelper::shallowCopyPage()
{
QPDF* qpdf = this->oh.getOwningQPDF();
if (! qpdf)
{
throw std::runtime_error(
"QPDFPageObjectHelper::shallowCopyPage"
" called with a direct objet");
}
QPDFObjectHandle new_page = this->oh.shallowCopy();
return QPDFPageObjectHelper(qpdf->makeIndirectObject(new_page));
}

View File

@ -982,15 +982,6 @@ make
easily combine all pages in a set of files with a command like
<command>qpdf --empty out.pdf --pages *.pdf --</command>.
</para>
<para>
It is not presently possible to specify the same page from the
same file directly more than once, but you can make this work by
specifying two different paths to the same file (such as by
putting <filename>./</filename> somewhere in the path). This can
also be used if you want to repeat a page from one of the input
files in the output file. This may be made more convenient in a
future version of qpdf if there is enough demand for this feature.
</para>
<para>
The page range is a set of numbers separated by commas, ranges of
numbers separated dashes, or combinations of those. The character
@ -1112,6 +1103,12 @@ outfile.pdf</option>
are all corner cases that most users should hopefully never have
to be bothered with.
</para>
<para>
Prior to version 8.4, it was not possible to specify the same page
from the same file directly more than once, and the workaround of
specifying the same file in more than one way was required.
Version 8.4 removes this limitation.
</para>
</sect1>
<sect1 id="ref.advanced-parsing">
<title>Advanced Parsing Options</title>

View File

@ -3731,6 +3731,7 @@ static void handle_page_specs(QPDF& pdf, Options& o)
std::map<std::string, ClosedFileInputSource*> page_spec_cfis;
page_spec_qpdfs[o.infilename] = &pdf;
std::vector<QPDFPageData> parsed_specs;
std::map<unsigned long long, std::set<QPDFObjGen> > copied_pages;
for (std::vector<PageSpec>::iterator iter = o.page_specs.begin();
iter != o.page_specs.end(); ++iter)
{
@ -3905,7 +3906,20 @@ static void handle_page_specs(QPDF& pdf, Options& o)
int pageno = *pageno_iter - 1;
pldh.getLabelsForPageRange(pageno, pageno, out_pageno,
new_labels);
dh.addPage(page_data.orig_pages.at(pageno), false);
QPDFPageObjectHelper to_copy = page_data.orig_pages.at(pageno);
QPDFObjGen to_copy_og = to_copy.getObjectHandle().getObjGen();
unsigned long long from_uuid = page_data.qpdf->getUniqueId();
if (copied_pages[from_uuid].count(to_copy_og))
{
QTC::TC("qpdf", "qpdf copy same page more than once",
(page_data.qpdf == &pdf) ? 0 : 1);
to_copy = to_copy.shallowCopyPage();
}
else
{
copied_pages[from_uuid].insert(to_copy_og);
}
dh.addPage(to_copy, false);
if (page_data.qpdf == &pdf)
{
// This is a page from the original file. Keep track

View File

@ -411,3 +411,4 @@ QPDF pipe foreign encrypted stream 0
QPDF copy foreign stream with provider 0
QPDF copy foreign stream with buffer 0
QPDF immediate copy stream data 0
qpdf copy same page more than once 1

View File

@ -1624,7 +1624,7 @@ foreach my $f (qw(screen print))
show_ntests();
# ----------
$td->notify("--- Merging and Splitting ---");
$n_tests += 18;
$n_tests += 22;
# Select pages from the same file multiple times including selecting
# twice from an encrypted file and specifying the password only the
@ -1692,7 +1692,7 @@ $td->runtest("check output",
{$td->FILE => "a.pdf"},
{$td->FILE => "merge-multiple-labels.pdf"});
$td->runtest("split with shared resources", # QXXXQ
$td->runtest("split with shared resources",
{$td->COMMAND =>
"qpdf --qdf --static-id" .
" shared-images.pdf --pages . 1,3" .
@ -1702,6 +1702,16 @@ $td->runtest("check output",
{$td->FILE => "a.pdf"},
{$td->FILE => "shared-images-pages-out.pdf"});
$td->runtest("split with really shared resources",
{$td->COMMAND =>
"qpdf --qdf --static-id" .
" shared-images.pdf --pages . 1,3" .
" . 1,2 -- a.pdf"},
{$td->STRING => "", $td->EXIT_STATUS => 0});
$td->runtest("check output",
{$td->FILE => "a.pdf"},
{$td->FILE => "really-shared-images-pages-out.pdf"});
$td->runtest("shared resources relevant errors",
{$td->COMMAND =>
"qpdf --qdf --static-id" .
@ -1733,6 +1743,16 @@ $td->runtest("check output",
{$td->FILE => "a.pdf"},
{$td->FILE => "shared-images-errors-1-3-out.pdf"});
$td->runtest("duplicate pages",
{$td->COMMAND =>
"qpdf --qdf --static-id 11-pages-with-labels.pdf" .
" --pages . 6,5,6 . 5 minimal.pdf 1,1 minimal.pdf 1 --" .
" a.pdf"},
{$td->STRING => "", $td->EXIT_STATUS => 0});
$td->runtest("check output",
{$td->FILE => "a.pdf"},
{$td->FILE => "duplicate-pages.pdf"});
show_ntests();
# ----------
$td->notify("--- Collating ---");

View File

@ -0,0 +1,335 @@
%PDF-1.4
%¿÷¢þ
%QDF-1.0
%% Original object ID: 1 0
1 0 obj
<<
/PageLabels <<
/Nums [
0
<<
/S /r
/St 5
>>
1
<<
/S /r
/St 4
>>
3
<<
/S /r
/St 4
>>
4
<<
/St 5
>>
]
>>
/Pages 3 0 R
/Type /Catalog
>>
endobj
%% Original object ID: 2 0
2 0 obj
<<
/CreationDate (D:20120721200217)
/Producer (Apex PDFWriter)
>>
endobj
%% Original object ID: 3 0
3 0 obj
<<
/Count 7
/Kids [
4 0 R
5 0 R
6 0 R
7 0 R
8 0 R
9 0 R
10 0 R
]
/Type /Pages
>>
endobj
%% Page 1
%% Original object ID: 9 0
4 0 obj
<<
/Contents 11 0 R
/MediaBox [
0
0
612
792
]
/Parent 3 0 R
/Resources <<
/Font <<
/F1 13 0 R
>>
/ProcSet [
/PDF
/Text
]
>>
/Type /Page
>>
endobj
%% Page 2
%% Original object ID: 8 0
5 0 obj
<<
/Contents 14 0 R
/MediaBox [
0
0
612
792
]
/Parent 3 0 R
/Resources <<
/Font <<
/F1 13 0 R
>>
/ProcSet [
/PDF
/Text
]
>>
/Type /Page
>>
endobj
%% Page 3
%% Original object ID: 27 0
6 0 obj
<<
/Contents 11 0 R
/MediaBox [
0
0
612
792
]
/Parent 3 0 R
/Resources <<
/Font <<
/F1 13 0 R
>>
/ProcSet [
/PDF
/Text
]
>>
/Type /Page
>>
endobj
%% Page 4
%% Original object ID: 28 0
7 0 obj
<<
/Contents 14 0 R
/MediaBox [
0
0
612
792
]
/Parent 3 0 R
/Resources <<
/Font <<
/F1 13 0 R
>>
/ProcSet [
/PDF
/Text
]
>>
/Type /Page
>>
endobj
%% Page 5
%% Original object ID: 29 0
8 0 obj
<<
/Contents 16 0 R
/MediaBox [
0
0
612
792
]
/Parent 3 0 R
/Resources <<
/Font <<
/F1 18 0 R
>>
/ProcSet 19 0 R
>>
/Type /Page
>>
endobj
%% Page 6
%% Original object ID: 33 0
9 0 obj
<<
/Contents 16 0 R
/MediaBox [
0
0
612
792
]
/Parent 3 0 R
/Resources <<
/Font <<
/F1 18 0 R
>>
/ProcSet 19 0 R
>>
/Type /Page
>>
endobj
%% Page 7
%% Original object ID: 34 0
10 0 obj
<<
/Contents 16 0 R
/MediaBox [
0
0
612
792
]
/Parent 3 0 R
/Resources <<
/Font <<
/F1 18 0 R
>>
/ProcSet 19 0 R
>>
/Type /Page
>>
endobj
%% Contents for page 3
%% Original object ID: 21 0
11 0 obj
<<
/Length 12 0 R
>>
stream
BT /F1 15 Tf 72 720 Td (Original page 6) Tj ET
endstream
endobj
12 0 obj
47
endobj
%% Original object ID: 16 0
13 0 obj
<<
/BaseFont /Times-Roman
/Encoding /WinAnsiEncoding
/Subtype /Type1
/Type /Font
>>
endobj
%% Contents for page 4
%% Original object ID: 20 0
14 0 obj
<<
/Length 15 0 R
>>
stream
BT /F1 15 Tf 72 720 Td (Original page 5) Tj ET
endstream
endobj
15 0 obj
47
endobj
%% Contents for page 7
%% Original object ID: 30 0
16 0 obj
<<
/Length 17 0 R
>>
stream
BT
/F1 24 Tf
72 720 Td
(Potato) Tj
ET
endstream
endobj
17 0 obj
44
endobj
%% Original object ID: 31 0
18 0 obj
<<
/BaseFont /Helvetica
/Encoding /WinAnsiEncoding
/Name /F1
/Subtype /Type1
/Type /Font
>>
endobj
%% Original object ID: 32 0
19 0 obj
[
/PDF
/Text
]
endobj
xref
0 20
0000000000 65535 f
0000000052 00000 n
0000000375 00000 n
0000000488 00000 n
0000000658 00000 n
0000000914 00000 n
0000001171 00000 n
0000001428 00000 n
0000001685 00000 n
0000001918 00000 n
0000002151 00000 n
0000002398 00000 n
0000002502 00000 n
0000002550 00000 n
0000002710 00000 n
0000002814 00000 n
0000002885 00000 n
0000002986 00000 n
0000003034 00000 n
0000003181 00000 n
trailer <<
/Info 2 0 R
/Root 1 0 R
/Size 20
/ID [<e032a88c7a987db6ca3abee555506ccc><31415926535897932384626433832795>]
>>
startxref
3217
%%EOF

View File

@ -0,0 +1,288 @@
%PDF-1.3
%¿÷¢þ
%QDF-1.0
%% Original object ID: 1 0
1 0 obj
<<
/Pages 2 0 R
/Type /Catalog
>>
endobj
%% Original object ID: 2 0
2 0 obj
<<
/Count 4
/Kids [
3 0 R
4 0 R
5 0 R
6 0 R
]
/Type /Pages
>>
endobj
%% Page 1
%% Original object ID: 3 0
3 0 obj
<<
/Contents 7 0 R
/MediaBox [
0
0
612
792
]
/Parent 2 0 R
/Resources <<
/Font <<
/F1 9 0 R
>>
/ProcSet 10 0 R
/XObject <<
/Im1 11 0 R
>>
>>
/Type /Page
>>
endobj
%% Page 2
%% Original object ID: 5 0
4 0 obj
<<
/Contents 13 0 R
/MediaBox [
0
0
612
792
]
/Parent 2 0 R
/Resources <<
/Font <<
/F1 9 0 R
>>
/ProcSet 10 0 R
/XObject <<
/Im3 15 0 R
>>
>>
/Type /Page
>>
endobj
%% Page 3
%% Original object ID: 56 0
5 0 obj
<<
/Contents 7 0 R
/MediaBox [
0
0
612
792
]
/Parent 2 0 R
/Resources <<
/Font <<
/F1 9 0 R
>>
/ProcSet 10 0 R
/XObject <<
/Im1 11 0 R
>>
>>
/Type /Page
>>
endobj
%% Page 4
%% Original object ID: 4 0
6 0 obj
<<
/Contents 17 0 R
/MediaBox [
0
0
612
792
]
/Parent 2 0 R
/Resources <<
/Font <<
/F1 9 0 R
>>
/ProcSet 10 0 R
/XObject <<
/Im2 19 0 R
>>
>>
/Type /Page
>>
endobj
%% Contents for page 3
%% Original object ID: 13 0
7 0 obj
<<
/Length 8 0 R
>>
stream
BT /F1 24 Tf 72 720 Td (page 1) Tj ET
q 468 0 0 468 72 72 cm /Im1 Do Q
endstream
endobj
8 0 obj
71
endobj
%% Original object ID: 15 0
9 0 obj
<<
/BaseFont /Helvetica
/Encoding /WinAnsiEncoding
/Name /F1
/Subtype /Type1
/Type /Font
>>
endobj
%% Original object ID: 16 0
10 0 obj
[
/PDF
/Text
/ImageC
]
endobj
%% Original object ID: 17 0
11 0 obj
<<
/BitsPerComponent 8
/ColorSpace /DeviceGray
/Height 50
/Subtype /Image
/Type /XObject
/Width 50
/Length 12 0 R
>>
stream
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀ
endstream
endobj
%QDF: ignore_newline
12 0 obj
2500
endobj
%% Contents for page 2
%% Original object ID: 23 0
13 0 obj
<<
/Length 14 0 R
>>
stream
BT /F1 24 Tf 72 720 Td (page 3) Tj ET
q 468 0 0 468 72 72 cm /Im3 Do Q
endstream
endobj
14 0 obj
71
endobj
%% Original object ID: 25 0
15 0 obj
<<
/BitsPerComponent 8
/ColorSpace /DeviceGray
/Height 50
/Subtype /Image
/Type /XObject
/Width 50
/Length 16 0 R
>>
stream
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀ
endstream
endobj
%QDF: ignore_newline
16 0 obj
2500
endobj
%% Contents for page 4
%% Original object ID: 19 0
17 0 obj
<<
/Length 18 0 R
>>
stream
BT /F1 24 Tf 72 720 Td (page 2) Tj ET
q 468 0 0 468 72 72 cm /Im2 Do Q
endstream
endobj
18 0 obj
71
endobj
%% Original object ID: 21 0
19 0 obj
<<
/BitsPerComponent 8
/ColorSpace /DeviceGray
/Height 50
/Subtype /Image
/Type /XObject
/Width 50
/Length 20 0 R
>>
stream
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀ@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
endstream
endobj
%QDF: ignore_newline
20 0 obj
2500
endobj
xref
0 21
0000000000 65535 f
0000000052 00000 n
0000000133 00000 n
0000000272 00000 n
0000000543 00000 n
0000000816 00000 n
0000001087 00000 n
0000001373 00000 n
0000001499 00000 n
0000001546 00000 n
0000001692 00000 n
0000001766 00000 n
0000004453 00000 n
0000004526 00000 n
0000004654 00000 n
0000004702 00000 n
0000007389 00000 n
0000007462 00000 n
0000007590 00000 n
0000007638 00000 n
0000010325 00000 n
trailer <<
/Root 1 0 R
/Size 21
/ID [<31415926535897932384626433832795><31415926535897932384626433832795>]
>>
startxref
10347
%%EOF