Preserve page labels (numbers) when splitting and merging

This commit is contained in:
Jay Berkenbilt 2018-12-18 14:59:14 -05:00
parent 6ef9e31233
commit 352ce9b22b
12 changed files with 806 additions and 144 deletions

View File

@ -1,5 +1,11 @@
2018-12-18 Jay Berkenbilt <ejb@ql.org>
* Preserve page labels when merging and splitting files. Prior
versions of qpdf simply preserved the page label information from
the first file, which usually wouldn't make any sense in the
merged file. Now any page that had a page number in any original
file will have the same page number after merging or splitting.
* Add QPDFPageLabelDocumentHelper class. This is a document helper
class that provides useful methods for dealing with page labels.
It abstracts the fact that they are stored as number trees and

View File

@ -911,23 +911,23 @@ make
</itemizedlist>
</para>
<para>
Note that qpdf doesn't presently do anything special about other
constructs in a PDF file that may know about pages, so semantics
of splitting and merging vary across features. For example, the
document's outlines (bookmarks) point to actual page objects, so
if you select some pages and not others, bookmarks that point to
pages that are in the output file will work, and remaining
bookmarks will not work. On the other hand, page labels (page
numbers specified in the file) are just sequential, so page labels
will be messed up in the output file. A future version of
<command>qpdf</command> may do a better job at handling these
issues. (Note that the qpdf library already contains all of the
APIs required in order to implement this in your own application
if you need it.) In the mean time, you can always use
<option>--empty</option> as the primary input file to avoid
copying all of that from the first file. For example, to take
pages 1 through 5 from a <filename>infile.pdf</filename> while
preserving all metadata associated with that file, you could use
Starting in qpdf version 8.3, when you split and merge files, any
page labels (page numbers) are preserved in the final file. It is
expected that more document features will be preserved by
splitting and merging. In the mean time, semantics of splitting
and merging vary across features. For example, the document's
outlines (bookmarks) point to actual page objects, so if you
select some pages and not others, bookmarks that point to pages
that are in the output file will work, and remaining bookmarks
will not work. A future version of <command>qpdf</command> may do
a better job at handling these issues. (Note that the qpdf library
already contains all of the APIs required in order to implement
this in your own application if you need it.) In the mean time,
you can always use <option>--empty</option> as the primary input
file to avoid copying all of that from the first file. For
example, to take pages 1 through 5 from a
<filename>infile.pdf</filename> while preserving all metadata
associated with that file, you could use
<programlisting><command>qpdf</command> <option>infile.pdf --pages infile.pdf 1-5 -- outfile.pdf</option>
</programlisting>
@ -946,8 +946,8 @@ make
If, for some reason, you wanted to take the first page of an
encrypted file called <filename>encrypted.pdf</filename> with
password <literal>pass</literal> and repeat it twice in an output
file, and if you wanted to drop metadata (like page numbers and
outlines) but preserve encryption, you would use
file, and if you wanted to drop document-level metadata but
preserve encryption, you would use
<programlisting><command>qpdf</command> <option>--empty --copy-encryption=encrypted.pdf --encryption-file-password=pass
--pages encrypted.pdf --password=pass 1 ./encrypted.pdf --password=pass 1 --

View File

@ -16,6 +16,7 @@
#include <qpdf/QPDF.hh>
#include <qpdf/QPDFPageDocumentHelper.hh>
#include <qpdf/QPDFPageObjectHelper.hh>
#include <qpdf/QPDFPageLabelDocumentHelper.hh>
#include <qpdf/QPDFExc.hh>
#include <qpdf/QPDFWriter.hh>
@ -2296,11 +2297,25 @@ static void handle_page_specs(QPDF& pdf, Options& o,
// Keep track of any pages from the original file that we are
// selecting.
std::set<int> selected_from_orig;
std::vector<QPDFObjectHandle> new_labels;
bool any_page_labels = false;
int out_pageno = 0;
for (std::vector<QPDFPageData>::iterator iter =
parsed_specs.begin();
iter != parsed_specs.end(); ++iter)
{
QPDFPageData& page_data = *iter;
ClosedFileInputSource* cis = 0;
if (page_spec_cfis.count(page_data.filename))
{
cis = page_spec_cfis[page_data.filename];
cis->stayOpen(true);
}
QPDFPageLabelDocumentHelper pldh(*page_data.qpdf);
if (pldh.hasPageLabels())
{
any_page_labels = true;
}
if (o.verbose)
{
std::cout << whoami << ": adding pages from "
@ -2309,22 +2324,14 @@ static void handle_page_specs(QPDF& pdf, Options& o,
for (std::vector<int>::iterator pageno_iter =
page_data.selected_pages.begin();
pageno_iter != page_data.selected_pages.end();
++pageno_iter)
++pageno_iter, ++out_pageno)
{
// Pages are specified from 1 but numbered from 0 in the
// vector
int pageno = *pageno_iter - 1;
ClosedFileInputSource* cis = 0;
if (page_spec_cfis.count(page_data.filename))
{
cis = page_spec_cfis[page_data.filename];
cis->stayOpen(true);
}
pldh.getLabelsForPageRange(pageno, pageno, out_pageno,
new_labels);
dh.addPage(page_data.orig_pages.at(pageno), false);
if (cis)
{
cis->stayOpen(false);
}
if (page_data.qpdf == &pdf)
{
// This is a page from the original file. Keep track
@ -2332,6 +2339,18 @@ static void handle_page_specs(QPDF& pdf, Options& o,
selected_from_orig.insert(pageno);
}
}
if (cis)
{
cis->stayOpen(false);
}
}
if (any_page_labels)
{
QPDFObjectHandle page_labels =
QPDFObjectHandle::newDictionary();
page_labels.replaceKey(
"/Nums", QPDFObjectHandle::newArray(new_labels));
pdf.getRoot().replaceKey("/PageLabels", page_labels);
}
// Delete page objects for unused page in primary. This prevents
@ -2574,6 +2593,7 @@ static void write_outfile(QPDF& pdf, Options& o)
dh.pushInheritedAttributesToPage();
dh.removeUnreferencedResources();
}
QPDFPageLabelDocumentHelper pldh(pdf);
std::vector<QPDFObjectHandle> const& pages = pdf.getAllPages();
int pageno_len = QUtil::int_to_string(pages.size()).length();
unsigned int num_pages = pages.size();
@ -2592,6 +2612,16 @@ static void write_outfile(QPDF& pdf, Options& o)
QPDFObjectHandle page = pages.at(pageno - 1);
outpdf.addPage(page, false);
}
if (pldh.hasPageLabels())
{
std::vector<QPDFObjectHandle> labels;
pldh.getLabelsForPageRange(first - 1, last - 1, 0, labels);
QPDFObjectHandle page_labels =
QPDFObjectHandle::newDictionary();
page_labels.replaceKey(
"/Nums", QPDFObjectHandle::newArray(labels));
outpdf.getRoot().replaceKey("/PageLabels", page_labels);
}
std::string page_range = QUtil::int_to_string(first, pageno_len);
if (o.split_pages > 1)
{

View File

@ -360,3 +360,4 @@ qpdf disable keep files open 0
qpdf keep files open n 0
qpdf keep files open y 0
qpdf don't disable keep files open 0
QPDFPageLabelDocumentHelper skip first 0

View File

@ -1137,7 +1137,7 @@ my @sp_cases = (
[11, 'pdf extension', '', 'split-out.Pdf'],
[4, 'fallback', '--pages 11-pages.pdf 1-3 minimal.pdf --', 'split-out'],
);
$n_tests += 9;
$n_tests += 12;
for (@sp_cases)
{
$n_tests += 1 + $_->[0];
@ -1171,6 +1171,17 @@ foreach my $i (qw(01-04 05-08 09-10))
{$td->FILE => "shared-split-$i.pdf"});
}
$td->runtest("split page with labels",
{$td->COMMAND => "qpdf --qdf --static-id --split-pages=6".
" 11-pages-with-labels.pdf split-out-labels.pdf"},
{$td->STRING => "", $td->EXIT_STATUS => 0});
foreach my $i (qw(01-06 07-11))
{
$td->runtest("check output ($i)",
{$td->FILE => "split-out-labels-$i.pdf"},
{$td->FILE => "labels-split-$i.pdf"});
}
foreach my $d (@sp_cases)
{
my ($n, $description, $xargs, $out) = @$d;
@ -1335,7 +1346,7 @@ foreach my $d (@nrange_tests)
show_ntests();
# ----------
$td->notify("--- Merging and Splitting ---");
$n_tests += 16;
$n_tests += 18;
# Select pages from the same file multiple times including selecting
# twice from an encrypted file and specifying the password only the
@ -1368,8 +1379,7 @@ $td->runtest("merge three files",
" $pages_options --static-id"},
{$td->STRING => "", $td->EXIT_STATUS => 0});
# Manually verified about this file: it has the same pages but does
# not contain outlines, page labels, or other things from the original
# file.
# not contain outlines or other things from the original file.
$td->runtest("check output",
{$td->FILE => "a.pdf"},
{$td->FILE => "merge-three-files-2.pdf"});
@ -1392,6 +1402,17 @@ $td->runtest("merge with implicit ranges",
$td->runtest("check output",
{$td->FILE => "a.pdf"},
{$td->FILE => "merge-implicit-ranges.pdf"});
$td->runtest("merge with multiple labels",
{$td->COMMAND =>
"qpdf --empty a.pdf" .
" --pages 11-pages-with-labels.pdf 8-11" .
" minimal.pdf " .
" page-labels-and-outlines.pdf 17-19 --" .
" --static-id"},
{$td->STRING => "", $td->EXIT_STATUS => 0});
$td->runtest("check output",
{$td->FILE => "a.pdf"},
{$td->FILE => "merge-multiple-labels.pdf"});
$td->runtest("split with shared resources",
{$td->COMMAND =>

Binary file not shown.

View File

@ -0,0 +1,324 @@
%PDF-1.3
%¿÷¢þ
%QDF-1.0
%% Original object ID: 1 0
1 0 obj
<<
/PageLabels <<
/Nums [
0
<<
/P (pre-)
/St 1
>>
4
<<
/S /r
/St 4
>>
]
>>
/Pages 2 0 R
/Type /Catalog
>>
endobj
%% Original object ID: 2 0
2 0 obj
<<
/Count 6
/Kids [
3 0 R
4 0 R
5 0 R
6 0 R
7 0 R
8 0 R
]
/Type /Pages
>>
endobj
%% Page 1
%% Original object ID: 3 0
3 0 obj
<<
/Contents 9 0 R
/MediaBox [
0
0
612
792
]
/Parent 2 0 R
/Resources <<
/Font <<
/F1 11 0 R
>>
/ProcSet [
/PDF
/Text
]
>>
/Type /Page
>>
endobj
%% Page 2
%% Original object ID: 6 0
4 0 obj
<<
/Contents 12 0 R
/MediaBox [
0
0
612
792
]
/Parent 2 0 R
/Resources <<
/Font <<
/F1 11 0 R
>>
/ProcSet [
/PDF
/Text
]
>>
/Type /Page
>>
endobj
%% Page 3
%% Original object ID: 8 0
5 0 obj
<<
/Contents 14 0 R
/MediaBox [
0
0
612
792
]
/Parent 2 0 R
/Resources <<
/Font <<
/F1 11 0 R
>>
/ProcSet [
/PDF
/Text
]
>>
/Type /Page
>>
endobj
%% Page 4
%% Original object ID: 10 0
6 0 obj
<<
/Contents 16 0 R
/MediaBox [
0
0
612
792
]
/Parent 2 0 R
/Resources <<
/Font <<
/F1 11 0 R
>>
/ProcSet [
/PDF
/Text
]
>>
/Type /Page
>>
endobj
%% Page 5
%% Original object ID: 12 0
7 0 obj
<<
/Contents 18 0 R
/MediaBox [
0
0
612
792
]
/Parent 2 0 R
/Resources <<
/Font <<
/F1 11 0 R
>>
/ProcSet [
/PDF
/Text
]
>>
/Type /Page
>>
endobj
%% Page 6
%% Original object ID: 14 0
8 0 obj
<<
/Contents 20 0 R
/MediaBox [
0
0
612
792
]
/Parent 2 0 R
/Resources <<
/Font <<
/F1 11 0 R
>>
/ProcSet [
/PDF
/Text
]
>>
/Type /Page
>>
endobj
%% Contents for page 1
%% Original object ID: 4 0
9 0 obj
<<
/Length 10 0 R
>>
stream
BT /F1 15 Tf 72 720 Td (Original page 1) Tj ET
endstream
endobj
10 0 obj
47
endobj
%% Original object ID: 5 0
11 0 obj
<<
/BaseFont /Times-Roman
/Encoding /WinAnsiEncoding
/Subtype /Type1
/Type /Font
>>
endobj
%% Contents for page 2
%% Original object ID: 7 0
12 0 obj
<<
/Length 13 0 R
>>
stream
BT /F1 15 Tf 72 720 Td (Original page 2) Tj ET
endstream
endobj
13 0 obj
47
endobj
%% Contents for page 3
%% Original object ID: 9 0
14 0 obj
<<
/Length 15 0 R
>>
stream
BT /F1 15 Tf 72 720 Td (Original page 3) Tj ET
endstream
endobj
15 0 obj
47
endobj
%% Contents for page 4
%% Original object ID: 11 0
16 0 obj
<<
/Length 17 0 R
>>
stream
BT /F1 15 Tf 72 720 Td (Original page 4) Tj ET
endstream
endobj
17 0 obj
47
endobj
%% Contents for page 5
%% Original object ID: 13 0
18 0 obj
<<
/Length 19 0 R
>>
stream
BT /F1 15 Tf 72 720 Td (Original page 5) Tj ET
endstream
endobj
19 0 obj
47
endobj
%% Contents for page 6
%% Original object ID: 15 0
20 0 obj
<<
/Length 21 0 R
>>
stream
BT /F1 15 Tf 72 720 Td (Original page 6) Tj ET
endstream
endobj
21 0 obj
47
endobj
xref
0 22
0000000000 65535 f
0000000052 00000 n
0000000285 00000 n
0000000444 00000 n
0000000699 00000 n
0000000955 00000 n
0000001212 00000 n
0000001469 00000 n
0000001726 00000 n
0000001995 00000 n
0000002098 00000 n
0000002145 00000 n
0000002304 00000 n
0000002408 00000 n
0000002478 00000 n
0000002582 00000 n
0000002653 00000 n
0000002757 00000 n
0000002828 00000 n
0000002932 00000 n
0000003003 00000 n
0000003107 00000 n
trailer <<
/Root 1 0 R
/Size 22
/ID [<31415926535897932384626433832795><31415926535897932384626433832795>]
>>
startxref
3127
%%EOF

View File

@ -0,0 +1,280 @@
%PDF-1.3
%¿÷¢þ
%QDF-1.0
%% Original object ID: 1 0
1 0 obj
<<
/PageLabels <<
/Nums [
0
<<
/S /r
/St 6
>>
2
<<
/S /a
/St 16
>>
]
>>
/Pages 2 0 R
/Type /Catalog
>>
endobj
%% Original object ID: 2 0
2 0 obj
<<
/Count 5
/Kids [
3 0 R
4 0 R
5 0 R
6 0 R
7 0 R
]
/Type /Pages
>>
endobj
%% Page 1
%% Original object ID: 3 0
3 0 obj
<<
/Contents 8 0 R
/MediaBox [
0
0
612
792
]
/Parent 2 0 R
/Resources <<
/Font <<
/F1 10 0 R
>>
/ProcSet [
/PDF
/Text
]
>>
/Type /Page
>>
endobj
%% Page 2
%% Original object ID: 6 0
4 0 obj
<<
/Contents 11 0 R
/MediaBox [
0
0
612
792
]
/Parent 2 0 R
/Resources <<
/Font <<
/F1 10 0 R
>>
/ProcSet [
/PDF
/Text
]
>>
/Type /Page
>>
endobj
%% Page 3
%% Original object ID: 8 0
5 0 obj
<<
/Contents 13 0 R
/MediaBox [
0
0
612
792
]
/Parent 2 0 R
/Resources <<
/Font <<
/F1 10 0 R
>>
/ProcSet [
/PDF
/Text
]
>>
/Type /Page
>>
endobj
%% Page 4
%% Original object ID: 10 0
6 0 obj
<<
/Contents 15 0 R
/MediaBox [
0
0
612
792
]
/Parent 2 0 R
/Resources <<
/Font <<
/F1 10 0 R
>>
/ProcSet [
/PDF
/Text
]
>>
/Type /Page
>>
endobj
%% Page 5
%% Original object ID: 12 0
7 0 obj
<<
/Contents 17 0 R
/MediaBox [
0
0
612
792
]
/Parent 2 0 R
/Resources <<
/Font <<
/F1 10 0 R
>>
/ProcSet [
/PDF
/Text
]
>>
/Type /Page
>>
endobj
%% Contents for page 1
%% Original object ID: 4 0
8 0 obj
<<
/Length 9 0 R
>>
stream
BT /F1 15 Tf 72 720 Td (Original page 7) Tj ET
endstream
endobj
9 0 obj
47
endobj
%% Original object ID: 5 0
10 0 obj
<<
/BaseFont /Times-Roman
/Encoding /WinAnsiEncoding
/Subtype /Type1
/Type /Font
>>
endobj
%% Contents for page 2
%% Original object ID: 7 0
11 0 obj
<<
/Length 12 0 R
>>
stream
BT /F1 15 Tf 72 720 Td (Original page 8) Tj ET
endstream
endobj
12 0 obj
47
endobj
%% Contents for page 3
%% Original object ID: 9 0
13 0 obj
<<
/Length 14 0 R
>>
stream
BT /F1 15 Tf 72 720 Td (Original page 9) Tj ET
endstream
endobj
14 0 obj
47
endobj
%% Contents for page 4
%% Original object ID: 11 0
15 0 obj
<<
/Length 16 0 R
>>
stream
BT /F1 15 Tf 72 720 Td (Original page 10) Tj ET
endstream
endobj
16 0 obj
48
endobj
%% Contents for page 5
%% Original object ID: 13 0
17 0 obj
<<
/Length 18 0 R
>>
stream
BT /F1 15 Tf 72 720 Td (Original page 11) Tj ET
endstream
endobj
18 0 obj
48
endobj
xref
0 19
0000000000 65535 f
0000000052 00000 n
0000000282 00000 n
0000000431 00000 n
0000000686 00000 n
0000000942 00000 n
0000001199 00000 n
0000001456 00000 n
0000001725 00000 n
0000001827 00000 n
0000001873 00000 n
0000002032 00000 n
0000002136 00000 n
0000002206 00000 n
0000002310 00000 n
0000002381 00000 n
0000002486 00000 n
0000002557 00000 n
0000002662 00000 n
trailer <<
/Root 1 0 R
/Size 19
/ID [<31415926535897932384626433832795><31415926535897932384626433832795>]
>>
startxref
2682
%%EOF

View File

@ -1,7 +1,7 @@
%PDF-1.3
%¿÷¢þ
1 0 obj
<< /Pages 2 0 R /Type /Catalog >>
<< /PageLabels << /Nums [ 0 << /St 1 >> 21 << /P () /St 1 >> 23 << /S /r /St 1 >> 28 << /P () /St 1 >> 30 << /S /r /St 6 >> 32 << /P () /St 1 >> 33 << /S /D /St 2 >> 36 << /S /D /St 6 >> 40 << /P () /St 1 >> 41 << /S /D /St 12 >> 43 << /S /D /St 16059 >> 44 << /S /r /St 50 >> 50 << /S /r /St 54 >> ] >> /Pages 2 0 R /Type /Catalog >>
endobj
2 0 obj
<< /Count 51 /Kids [ 3 0 R 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 20 0 R 21 0 R 22 0 R 23 0 R 24 0 R 25 0 R 26 0 R 27 0 R 28 0 R 29 0 R 30 0 R 31 0 R 32 0 R 33 0 R 34 0 R 35 0 R 36 0 R 37 0 R 38 0 R 39 0 R 40 0 R 41 0 R 42 0 R 43 0 R 44 0 R 45 0 R 46 0 R 47 0 R 48 0 R 49 0 R 50 0 R 51 0 R 52 0 R 53 0 R ] /Type /Pages >>
@ -514,115 +514,115 @@ xref
0 110
0000000000 65535 f
0000000015 00000 n
0000000064 00000 n
0000000468 00000 n
0000000614 00000 n
0000000768 00000 n
0000000922 00000 n
0000001076 00000 n
0000001230 00000 n
0000001384 00000 n
0000001538 00000 n
0000001693 00000 n
0000001848 00000 n
0000002003 00000 n
0000002158 00000 n
0000002313 00000 n
0000002468 00000 n
0000002623 00000 n
0000002778 00000 n
0000002933 00000 n
0000003088 00000 n
0000003243 00000 n
0000003398 00000 n
0000003553 00000 n
0000003708 00000 n
0000003855 00000 n
0000004002 00000 n
0000004149 00000 n
0000004296 00000 n
0000004443 00000 n
0000004590 00000 n
0000004737 00000 n
0000004884 00000 n
0000005031 00000 n
0000005178 00000 n
0000005325 00000 n
0000005472 00000 n
0000005619 00000 n
0000005766 00000 n
0000005913 00000 n
0000006060 00000 n
0000006207 00000 n
0000006354 00000 n
0000006501 00000 n
0000006648 00000 n
0000006796 00000 n
0000006944 00000 n
0000007092 00000 n
0000007240 00000 n
0000007388 00000 n
0000007536 00000 n
0000007684 00000 n
0000007832 00000 n
0000007980 00000 n
0000008128 00000 n
0000008247 00000 n
0000008355 00000 n
0000008386 00000 n
0000008510 00000 n
0000008610 00000 n
0000008734 00000 n
0000008858 00000 n
0000008982 00000 n
0000009106 00000 n
0000009230 00000 n
0000009354 00000 n
0000009478 00000 n
0000009602 00000 n
0000009726 00000 n
0000009851 00000 n
0000009976 00000 n
0000010101 00000 n
0000010226 00000 n
0000010351 00000 n
0000010475 00000 n
0000010600 00000 n
0000010725 00000 n
0000010850 00000 n
0000010975 00000 n
0000011096 00000 n
0000011204 00000 n
0000011235 00000 n
0000011356 00000 n
0000011477 00000 n
0000011598 00000 n
0000011719 00000 n
0000011840 00000 n
0000011961 00000 n
0000012082 00000 n
0000012203 00000 n
0000012324 00000 n
0000012446 00000 n
0000012568 00000 n
0000012690 00000 n
0000012812 00000 n
0000012934 00000 n
0000013056 00000 n
0000013178 00000 n
0000013300 00000 n
0000013422 00000 n
0000013544 00000 n
0000013667 00000 n
0000013790 00000 n
0000013913 00000 n
0000014036 00000 n
0000014158 00000 n
0000014281 00000 n
0000014404 00000 n
0000014527 00000 n
0000014650 00000 n
0000000365 00000 n
0000000769 00000 n
0000000915 00000 n
0000001069 00000 n
0000001223 00000 n
0000001377 00000 n
0000001531 00000 n
0000001685 00000 n
0000001839 00000 n
0000001994 00000 n
0000002149 00000 n
0000002304 00000 n
0000002459 00000 n
0000002614 00000 n
0000002769 00000 n
0000002924 00000 n
0000003079 00000 n
0000003234 00000 n
0000003389 00000 n
0000003544 00000 n
0000003699 00000 n
0000003854 00000 n
0000004009 00000 n
0000004156 00000 n
0000004303 00000 n
0000004450 00000 n
0000004597 00000 n
0000004744 00000 n
0000004891 00000 n
0000005038 00000 n
0000005185 00000 n
0000005332 00000 n
0000005479 00000 n
0000005626 00000 n
0000005773 00000 n
0000005920 00000 n
0000006067 00000 n
0000006214 00000 n
0000006361 00000 n
0000006508 00000 n
0000006655 00000 n
0000006802 00000 n
0000006949 00000 n
0000007097 00000 n
0000007245 00000 n
0000007393 00000 n
0000007541 00000 n
0000007689 00000 n
0000007837 00000 n
0000007985 00000 n
0000008133 00000 n
0000008281 00000 n
0000008429 00000 n
0000008548 00000 n
0000008656 00000 n
0000008687 00000 n
0000008811 00000 n
0000008911 00000 n
0000009035 00000 n
0000009159 00000 n
0000009283 00000 n
0000009407 00000 n
0000009531 00000 n
0000009655 00000 n
0000009779 00000 n
0000009903 00000 n
0000010027 00000 n
0000010152 00000 n
0000010277 00000 n
0000010402 00000 n
0000010527 00000 n
0000010652 00000 n
0000010776 00000 n
0000010901 00000 n
0000011026 00000 n
0000011151 00000 n
0000011276 00000 n
0000011397 00000 n
0000011505 00000 n
0000011536 00000 n
0000011657 00000 n
0000011778 00000 n
0000011899 00000 n
0000012020 00000 n
0000012141 00000 n
0000012262 00000 n
0000012383 00000 n
0000012504 00000 n
0000012625 00000 n
0000012747 00000 n
0000012869 00000 n
0000012991 00000 n
0000013113 00000 n
0000013235 00000 n
0000013357 00000 n
0000013479 00000 n
0000013601 00000 n
0000013723 00000 n
0000013845 00000 n
0000013968 00000 n
0000014091 00000 n
0000014214 00000 n
0000014337 00000 n
0000014459 00000 n
0000014582 00000 n
0000014705 00000 n
0000014828 00000 n
0000014951 00000 n
trailer << /Root 1 0 R /Size 110 /ID [<31415926535897932384626433832795><31415926535897932384626433832795>] >>
startxref
14773
15074
%%EOF

Binary file not shown.