aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--manual/qpdf-manual.xml37
-rw-r--r--qpdf/qpdf.cc36
-rw-r--r--qpdf/qtest/qpdf.test15
-rw-r--r--qpdf/qtest/qpdf/three-files-2-collate-out.pdf978
5 files changed, 1051 insertions, 21 deletions
diff --git a/ChangeLog b/ChangeLog
index 2009162c..676a2466 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2021-02-17 Jay Berkenbilt <ejb@ql.org>
+
+ * Allow optional numeric argument to --collate. If --collate=n is
+ given, pull n pages from the first file, n pages from the second
+ file, etc., until we run out of pages.
+
2021-02-15 Jay Berkenbilt <ejb@ql.org>
* Add a version of QPDFObjectHandle::parse that takes a QPDF* as
diff --git a/manual/qpdf-manual.xml b/manual/qpdf-manual.xml
index 508e0ec9..144c4edf 100644
--- a/manual/qpdf-manual.xml
+++ b/manual/qpdf-manual.xml
@@ -1077,12 +1077,14 @@ make
</listitem>
</varlistentry>
<varlistentry>
- <term><option>--collate</option></term>
+ <term><option>--collate=<replaceable>n</replaceable></option></term>
<listitem>
<para>
When specified, collate rather than concatenate pages from
- files specified with <option>--pages</option>. See <xref
- linkend="ref.page-selection"/> for additional details.
+ files specified with <option>--pages</option>. With a numeric
+ argument, collate in groups of <replaceable>n</replaceable>.
+ The default is 1. See <xref linkend="ref.page-selection"/> for
+ additional details.
</para>
</listitem>
</varlistentry>
@@ -1647,6 +1649,27 @@ make
</itemizedlist>
</para>
<para>
+ Starting in qpdf version 10.2, you may specify a numeric argument
+ to <option>--collate</option>. With
+ <option>--collate=<replaceable>n</replaceable></option>, pull
+ groups of <replaceable>n</replaceable> pages from each file,
+ again, stopping when there are no more pages. For example, if you
+ ran <command>qpdf --collate=2 --empty --pages a.pdf 1-5 b.pdf 6-4
+ c.pdf r1 -- out.pdf</command>, you would get the following pages
+ in this order:
+ <itemizedlist>
+ <listitem><para>a.pdf page 1</para></listitem>
+ <listitem><para>a.pdf page 2</para></listitem>
+ <listitem><para>b.pdf page 6</para></listitem>
+ <listitem><para>b.pdf page 5</para></listitem>
+ <listitem><para>c.pdf last page</para></listitem>
+ <listitem><para>a.pdf page 3</para></listitem>
+ <listitem><para>a.pdf page 4</para></listitem>
+ <listitem><para>b.pdf page 4</para></listitem>
+ <listitem><para>a.pdf page 5</para></listitem>
+ </itemizedlist>
+ </para>
+ <para>
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
@@ -5144,6 +5167,14 @@ print "\n";
reference to the file spec object.
</para>
</listitem>
+ <listitem>
+ <para>
+ Add numeric option to <option>--collate</option>. If
+ <option>--collate=<replaceable>n</replaceable></option> is
+ given, take pages in groups of <replaceable>n</replaceable>
+ from the given files.
+ </para>
+ </listitem>
</itemizedlist>
</listitem>
<listitem>
diff --git a/qpdf/qpdf.cc b/qpdf/qpdf.cc
index e41be64b..8de2ab8b 100644
--- a/qpdf/qpdf.cc
+++ b/qpdf/qpdf.cc
@@ -201,7 +201,7 @@ struct Options
show_filtered_stream_data(false),
show_pages(false),
show_page_images(false),
- collate(false),
+ collate(0),
flatten_rotation(false),
list_attachments(false),
json(false),
@@ -307,7 +307,7 @@ struct Options
bool show_filtered_stream_data;
bool show_pages;
bool show_page_images;
- bool collate;
+ size_t collate;
bool flatten_rotation;
bool list_attachments;
std::string attachment_to_show;
@@ -804,7 +804,7 @@ class ArgParser
void argUnderlay();
void argOverlay();
void argRotate(char* parameter);
- void argCollate();
+ void argCollate(char* parameter);
void argFlattenRotation();
void argListAttachments();
void argShowAttachment(char* parameter);
@@ -1048,7 +1048,7 @@ ArgParser::initOptionTable()
&ArgParser::argRotate, "[+|-]angle:page-range");
char const* stream_data_choices[] =
{"compress", "preserve", "uncompress", 0};
- (*t)["collate"] = oe_bare(&ArgParser::argCollate);
+ (*t)["collate"] = oe_optionalParameter(&ArgParser::argCollate);
(*t)["flatten-rotation"] = oe_bare(&ArgParser::argFlattenRotation);
(*t)["list-attachments"] = oe_bare(&ArgParser::argListAttachments);
(*t)["show-attachment"] = oe_requiredParameter(
@@ -1369,8 +1369,9 @@ ArgParser::argHelp()
<< " encoding errors\n"
<< "--password-mode=mode control qpdf's encoding of passwords\n"
<< "--pages options -- select specific pages from one or more files\n"
- << "--collate causes files specified in --pages to be collated\n"
- << " rather than concatenated\n"
+ << "--collate=n causes files specified in --pages to be collated\n"
+ << " in groups of n pages (default 1) rather than\n"
+ << " concatenated\n"
<< "--flatten-rotation move page rotation from /Rotate key to content\n"
<< "--rotate=[+|-]angle[:page-range]\n"
<< " rotate each specified page 90, 180, or 270 degrees;\n"
@@ -2068,9 +2069,11 @@ ArgParser::argEncryptionFilePassword(char* parameter)
}
void
-ArgParser::argCollate()
+ArgParser::argCollate(char* parameter)
{
- o.collate = true;
+ auto n = ((parameter == 0) ? 1 :
+ QUtil::string_to_uint(parameter));
+ o.collate = QIntC::to_size(n);
}
void
@@ -5788,16 +5791,19 @@ static void handle_page_specs(QPDF& pdf, Options& o, bool& warnings)
for (size_t i = 0; i < nspecs; ++i)
{
QPDFPageData& page_data = parsed_specs.at(i);
- if (cur_page < page_data.selected_pages.size())
+ for (size_t j = 0; j < o.collate; ++j)
{
- got_pages = true;
- new_parsed_specs.push_back(
- QPDFPageData(
- page_data,
- page_data.selected_pages.at(cur_page)));
+ if (cur_page + j < page_data.selected_pages.size())
+ {
+ got_pages = true;
+ new_parsed_specs.push_back(
+ QPDFPageData(
+ page_data,
+ page_data.selected_pages.at(cur_page + j)));
+ }
}
}
- ++cur_page;
+ cur_page += o.collate;
}
parsed_specs = new_parsed_specs;
}
diff --git a/qpdf/qtest/qpdf.test b/qpdf/qtest/qpdf.test
index 38a2d1b8..c033e7ef 100644
--- a/qpdf/qtest/qpdf.test
+++ b/qpdf/qtest/qpdf.test
@@ -2573,17 +2573,26 @@ show_ntests();
# ----------
$td->notify("--- Collating ---");
my @collate = (
- ["three-files", "collate-odd",
+ ["", "three-files", "collate-odd",
+ "collate-odd.pdf 1-5 minimal.pdf collate-even.pdf 7-1"],
+ [1, "three-files", "collate-odd",
+ "collate-odd.pdf 1-5 minimal.pdf collate-even.pdf 7-1"],
+ [2, "three-files-2", "collate-odd",
"collate-odd.pdf 1-5 minimal.pdf collate-even.pdf 7-1"],
);
$n_tests += 2 * scalar(@collate);
foreach my $d (@collate)
{
- my ($description, $first, $args) = @$d;
+ my ($n, $description, $first, $args) = @$d;
+ my $collate = '--collate';
+ if ($n)
+ {
+ $collate .= "=$n";
+ }
$td->runtest("collate pages: $description",
{$td->COMMAND =>
- "qpdf --qdf --static-id --collate $first.pdf" .
+ "qpdf --qdf --static-id $collate $first.pdf" .
" --pages $args -- a.pdf"},
{$td->STRING => "", $td->EXIT_STATUS => 0});
$td->runtest("check output",
diff --git a/qpdf/qtest/qpdf/three-files-2-collate-out.pdf b/qpdf/qtest/qpdf/three-files-2-collate-out.pdf
new file mode 100644
index 00000000..2abda2da
--- /dev/null
+++ b/qpdf/qtest/qpdf/three-files-2-collate-out.pdf
@@ -0,0 +1,978 @@
+%PDF-1.3
+%¿÷¢þ
+%QDF-1.0
+
+%% Original object ID: 1 0
+1 0 obj
+<<
+ /Outlines 2 0 R
+ /PageLabels <<
+ /Nums [
+ 0
+ <<
+ /P ()
+ /St 1
+ >>
+ 1
+ <<
+ /S /r
+ /St 1
+ >>
+ 2
+ <<
+ /St 3
+ >>
+ 3
+ <<
+ /S /D
+ /St 3
+ >>
+ 4
+ <<
+ /P ()
+ /St 1
+ >>
+ 5
+ <<
+ /S /r
+ /St 3
+ >>
+ 6
+ <<
+ /S /r
+ /St 5
+ >>
+ 8
+ <<
+ /P ()
+ /St 1
+ >>
+ 10
+ <<
+ /S /r
+ /St 4
+ >>
+ 11
+ <<
+ /S /r
+ /St 2
+ >>
+ 12
+ <<
+ /P ()
+ /St 2
+ >>
+ ]
+ >>
+ /PageMode /UseOutlines
+ /Pages 3 0 R
+ /Type /Catalog
+>>
+endobj
+
+%% Original object ID: 2 0
+2 0 obj
+<<
+ /Count 6
+ /First 4 0 R
+ /Last 5 0 R
+ /Type /Outlines
+>>
+endobj
+
+%% Original object ID: 3 0
+3 0 obj
+<<
+ /Count 13
+ /Kids [
+ 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
+ ]
+ /Type /Pages
+>>
+endobj
+
+%% Original object ID: 4 0
+4 0 obj
+<<
+ /Count 4
+ /Dest [
+ null
+ /XYZ
+ null
+ null
+ null
+ ]
+ /First 19 0 R
+ /Last 20 0 R
+ /Next 5 0 R
+ /Parent 2 0 R
+ /Title (Isís 1 -> 5: /XYZ null null null)
+ /Type /Outline
+>>
+endobj
+
+%% Original object ID: 5 0
+5 0 obj
+<<
+ /Dest [
+ null
+ /XYZ
+ 66
+ 756
+ 3
+ ]
+ /Parent 2 0 R
+ /Prev 4 0 R
+ /Title (Trepak 2 -> 15: /XYZ 66 756 3)
+ /Type /Outline
+>>
+endobj
+
+%% Page 1
+%% Original object ID: 6 0
+6 0 obj
+<<
+ /Contents 21 0 R
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 3 0 R
+ /Resources <<
+ /Font <<
+ /F1 23 0 R
+ >>
+ /ProcSet 24 0 R
+ >>
+ /Type /Page
+>>
+endobj
+
+%% Page 2
+%% Original object ID: 7 0
+7 0 obj
+<<
+ /Contents 25 0 R
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 3 0 R
+ /Resources <<
+ /Font <<
+ /F1 23 0 R
+ >>
+ /ProcSet 24 0 R
+ >>
+ /Type /Page
+>>
+endobj
+
+%% Page 3
+%% Original object ID: 47 0
+8 0 obj
+<<
+ /Contents 27 0 R
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 3 0 R
+ /Resources <<
+ /Font <<
+ /F1 29 0 R
+ >>
+ /ProcSet 30 0 R
+ >>
+ /Type /Page
+>>
+endobj
+
+%% Page 4
+%% Original object ID: 51 0
+9 0 obj
+<<
+ /Contents 31 0 R
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 3 0 R
+ /Resources <<
+ /Font <<
+ /F1 33 0 R
+ >>
+ /ProcSet 34 0 R
+ >>
+ /Type /Page
+>>
+endobj
+
+%% Page 5
+%% Original object ID: 55 0
+10 0 obj
+<<
+ /Contents 35 0 R
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 3 0 R
+ /Resources <<
+ /Font <<
+ /F1 33 0 R
+ >>
+ /ProcSet 34 0 R
+ >>
+ /Type /Page
+>>
+endobj
+
+%% Page 6
+%% Original object ID: 8 0
+11 0 obj
+<<
+ /Contents 37 0 R
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 3 0 R
+ /Resources <<
+ /Font <<
+ /F1 23 0 R
+ >>
+ /ProcSet 24 0 R
+ >>
+ /Type /Page
+>>
+endobj
+
+%% Page 7
+%% Original object ID: 9 0
+12 0 obj
+<<
+ /Contents 39 0 R
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 3 0 R
+ /Resources <<
+ /Font <<
+ /F1 23 0 R
+ >>
+ /ProcSet 24 0 R
+ >>
+ /Type /Page
+>>
+endobj
+
+%% Page 8
+%% Original object ID: 57 0
+13 0 obj
+<<
+ /Contents 41 0 R
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 3 0 R
+ /Resources <<
+ /Font <<
+ /F1 33 0 R
+ >>
+ /ProcSet 34 0 R
+ >>
+ /Type /Page
+>>
+endobj
+
+%% Page 9
+%% Original object ID: 59 0
+14 0 obj
+<<
+ /Contents 43 0 R
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 3 0 R
+ /Resources <<
+ /Font <<
+ /F1 33 0 R
+ >>
+ /ProcSet 34 0 R
+ >>
+ /Type /Page
+>>
+endobj
+
+%% Page 10
+%% Original object ID: 10 0
+15 0 obj
+<<
+ /Contents 45 0 R
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 3 0 R
+ /Resources <<
+ /Font <<
+ /F1 23 0 R
+ >>
+ /ProcSet 24 0 R
+ >>
+ /Type /Page
+>>
+endobj
+
+%% Page 11
+%% Original object ID: 61 0
+16 0 obj
+<<
+ /Contents 47 0 R
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 3 0 R
+ /Resources <<
+ /Font <<
+ /F1 33 0 R
+ >>
+ /ProcSet 34 0 R
+ >>
+ /Type /Page
+>>
+endobj
+
+%% Page 12
+%% Original object ID: 63 0
+17 0 obj
+<<
+ /Contents 49 0 R
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 3 0 R
+ /Resources <<
+ /Font <<
+ /F1 33 0 R
+ >>
+ /ProcSet 34 0 R
+ >>
+ /Type /Page
+>>
+endobj
+
+%% Page 13
+%% Original object ID: 65 0
+18 0 obj
+<<
+ /Contents 51 0 R
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 3 0 R
+ /Resources <<
+ /Font <<
+ /F1 33 0 R
+ >>
+ /ProcSet 34 0 R
+ >>
+ /Type /Page
+>>
+endobj
+
+%% Original object ID: 21 0
+19 0 obj
+<<
+ /Count -3
+ /Dest [
+ null
+ /Fit
+ ]
+ /First 53 0 R
+ /Last 54 0 R
+ /Next 20 0 R
+ /Parent 4 0 R
+ /Title (Amanda 1.1 -> 11: /Fit)
+ /Type /Outline
+>>
+endobj
+
+%% Original object ID: 22 0
+20 0 obj
+<<
+ /Count 2
+ /Dest [
+ null
+ /FitH
+ 792
+ ]
+ /First 55 0 R
+ /Last 56 0 R
+ /Parent 4 0 R
+ /Prev 19 0 R
+ /Title <feff00530061006e00640079002000f703a303b103bd03b403b900f700200031002e00320020002d003e002000310033003a0020002f00460069007400480020003700390032>
+ /Type /Outline
+>>
+endobj
+
+%% Contents for page 1
+%% Original object ID: 23 0
+21 0 obj
+<<
+ /Length 22 0 R
+>>
+stream
+BT
+ /F1 24 Tf
+ 72 720 Td
+ (Potato 0) Tj
+ET
+endstream
+endobj
+
+22 0 obj
+46
+endobj
+
+%% Original object ID: 24 0
+23 0 obj
+<<
+ /BaseFont /Helvetica
+ /Encoding /WinAnsiEncoding
+ /Name /F1
+ /Subtype /Type1
+ /Type /Font
+>>
+endobj
+
+%% Original object ID: 25 0
+24 0 obj
+[
+ /PDF
+ /Text
+]
+endobj
+
+%% Contents for page 2
+%% Original object ID: 26 0
+25 0 obj
+<<
+ /Length 26 0 R
+>>
+stream
+BT
+ /F1 24 Tf
+ 72 720 Td
+ (Potato 2) Tj
+ET
+endstream
+endobj
+
+26 0 obj
+46
+endobj
+
+%% Contents for page 3
+%% Original object ID: 48 0
+27 0 obj
+<<
+ /Length 28 0 R
+>>
+stream
+BT
+ /F1 24 Tf
+ 72 720 Td
+ (Potato) Tj
+ET
+endstream
+endobj
+
+28 0 obj
+44
+endobj
+
+%% Original object ID: 49 0
+29 0 obj
+<<
+ /BaseFont /Helvetica
+ /Encoding /WinAnsiEncoding
+ /Name /F1
+ /Subtype /Type1
+ /Type /Font
+>>
+endobj
+
+%% Original object ID: 50 0
+30 0 obj
+[
+ /PDF
+ /Text
+]
+endobj
+
+%% Contents for page 4
+%% Original object ID: 52 0
+31 0 obj
+<<
+ /Length 32 0 R
+>>
+stream
+BT
+ /F1 24 Tf
+ 72 720 Td
+ (Potato 13) Tj
+ET
+endstream
+endobj
+
+32 0 obj
+47
+endobj
+
+%% Original object ID: 53 0
+33 0 obj
+<<
+ /BaseFont /Helvetica
+ /Encoding /WinAnsiEncoding
+ /Name /F1
+ /Subtype /Type1
+ /Type /Font
+>>
+endobj
+
+%% Original object ID: 54 0
+34 0 obj
+[
+ /PDF
+ /Text
+]
+endobj
+
+%% Contents for page 5
+%% Original object ID: 56 0
+35 0 obj
+<<
+ /Length 36 0 R
+>>
+stream
+BT
+ /F1 24 Tf
+ 72 720 Td
+ (Potato 11) Tj
+ET
+endstream
+endobj
+
+36 0 obj
+47
+endobj
+
+%% Contents for page 6
+%% Original object ID: 27 0
+37 0 obj
+<<
+ /Length 38 0 R
+>>
+stream
+BT
+ /F1 24 Tf
+ 72 720 Td
+ (Potato 4) Tj
+ET
+endstream
+endobj
+
+38 0 obj
+46
+endobj
+
+%% Contents for page 7
+%% Original object ID: 28 0
+39 0 obj
+<<
+ /Length 40 0 R
+>>
+stream
+BT
+ /F1 24 Tf
+ 72 720 Td
+ (Potato 6) Tj
+ET
+endstream
+endobj
+
+40 0 obj
+46
+endobj
+
+%% Contents for page 8
+%% Original object ID: 58 0
+41 0 obj
+<<
+ /Length 42 0 R
+>>
+stream
+BT
+ /F1 24 Tf
+ 72 720 Td
+ (Potato 9) Tj
+ET
+endstream
+endobj
+
+42 0 obj
+46
+endobj
+
+%% Contents for page 9
+%% Original object ID: 60 0
+43 0 obj
+<<
+ /Length 44 0 R
+>>
+stream
+BT
+ /F1 24 Tf
+ 72 720 Td
+ (Potato 7) Tj
+ET
+endstream
+endobj
+
+44 0 obj
+46
+endobj
+
+%% Contents for page 10
+%% Original object ID: 29 0
+45 0 obj
+<<
+ /Length 46 0 R
+>>
+stream
+BT
+ /F1 24 Tf
+ 72 720 Td
+ (Potato 8) Tj
+ET
+endstream
+endobj
+
+46 0 obj
+46
+endobj
+
+%% Contents for page 11
+%% Original object ID: 62 0
+47 0 obj
+<<
+ /Length 48 0 R
+>>
+stream
+BT
+ /F1 24 Tf
+ 72 720 Td
+ (Potato 5) Tj
+ET
+endstream
+endobj
+
+48 0 obj
+46
+endobj
+
+%% Contents for page 12
+%% Original object ID: 64 0
+49 0 obj
+<<
+ /Length 50 0 R
+>>
+stream
+BT
+ /F1 24 Tf
+ 72 720 Td
+ (Potato 3) Tj
+ET
+endstream
+endobj
+
+50 0 obj
+46
+endobj
+
+%% Contents for page 13
+%% Original object ID: 66 0
+51 0 obj
+<<
+ /Length 52 0 R
+>>
+stream
+BT
+ /F1 24 Tf
+ 72 720 Td
+ (Potato 1) Tj
+ET
+endstream
+endobj
+
+52 0 obj
+46
+endobj
+
+%% Original object ID: 40 0
+53 0 obj
+<<
+ /Count -2
+ /Dest [
+ 57 0 R
+ /FitV
+ 100
+ ]
+ /First 58 0 R
+ /Last 59 0 R
+ /Next 54 0 R
+ /Parent 19 0 R
+ /Title (Isosicle 1.1.1 -> 12: /FitV 100)
+ /Type /Outline
+>>
+endobj
+
+%% Original object ID: 41 0
+54 0 obj
+<<
+ /Count 1
+ /Dest [
+ 57 0 R
+ /XYZ
+ null
+ null
+ null
+ ]
+ /First 60 0 R
+ /Last 60 0 R
+ /Parent 19 0 R
+ /Prev 53 0 R
+ /Title (Isosicle 1.1.2 -> 12: /XYZ null null null)
+ /Type /Outline
+>>
+endobj
+
+%% Original object ID: 42 0
+55 0 obj
+<<
+ /Dest [
+ null
+ /FitR
+ 66
+ 714
+ 180
+ 770
+ ]
+ /Next 56 0 R
+ /Parent 20 0 R
+ /Title (Trepsichord 1.2.1 -> 1: /FitR 66 714 180 770)
+ /Type /Outline
+>>
+endobj
+
+%% Original object ID: 43 0
+56 0 obj
+<<
+ /Dest [
+ 6 0 R
+ /XYZ
+ null
+ null
+ null
+ ]
+ /Parent 20 0 R
+ /Prev 55 0 R
+ /Title (Trepsicle 1.2.2 -> 0: /XYZ null null null)
+ /Type /Outline
+>>
+endobj
+
+%% Original object ID: 12 0
+57 0 obj
+null
+endobj
+
+%% Original object ID: 44 0
+58 0 obj
+<<
+ /Dest [
+ 61 0 R
+ /XYZ
+ null
+ null
+ null
+ ]
+ /Next 59 0 R
+ /Parent 53 0 R
+ /Title (Isosicle 1.1.1.1 -> 18: /XYZ null null null)
+ /Type /Outline
+>>
+endobj
+
+%% Original object ID: 45 0
+59 0 obj
+<<
+ /Dest [
+ null
+ /XYZ
+ null
+ null
+ null
+ ]
+ /Parent 53 0 R
+ /Prev 58 0 R
+ /Title (Isosicle 1.1.1.2 -> 19: /XYZ null null null)
+ /Type /Outline
+>>
+endobj
+
+%% Original object ID: 46 0
+60 0 obj
+<<
+ /Dest [
+ 62 0 R
+ /XYZ
+ null
+ null
+ null
+ ]
+ /Parent 54 0 R
+ /Title (Isosicle 1.1.2.1 -> 22: /XYZ null null null)
+ /Type /Outline
+>>
+endobj
+
+%% Original object ID: 15 0
+61 0 obj
+null
+endobj
+
+%% Original object ID: 17 0
+62 0 obj
+null
+endobj
+
+xref
+0 63
+0000000000 65535 f
+0000000052 00000 n
+0000000799 00000 n
+0000000906 00000 n
+0000001135 00000 n
+0000001376 00000 n
+0000001576 00000 n
+0000001808 00000 n
+0000002041 00000 n
+0000002274 00000 n
+0000002507 00000 n
+0000002740 00000 n
+0000002973 00000 n
+0000003207 00000 n
+0000003441 00000 n
+0000003676 00000 n
+0000003911 00000 n
+0000004146 00000 n
+0000004381 00000 n
+0000004605 00000 n
+0000004813 00000 n
+0000005170 00000 n
+0000005273 00000 n
+0000005321 00000 n
+0000005468 00000 n
+0000005555 00000 n
+0000005658 00000 n
+0000005729 00000 n
+0000005830 00000 n
+0000005878 00000 n
+0000006025 00000 n
+0000006112 00000 n
+0000006216 00000 n
+0000006264 00000 n
+0000006411 00000 n
+0000006498 00000 n
+0000006602 00000 n
+0000006673 00000 n
+0000006776 00000 n
+0000006847 00000 n
+0000006950 00000 n
+0000007021 00000 n
+0000007124 00000 n
+0000007195 00000 n
+0000007298 00000 n
+0000007370 00000 n
+0000007473 00000 n
+0000007545 00000 n
+0000007648 00000 n
+0000007720 00000 n
+0000007823 00000 n
+0000007895 00000 n
+0000007998 00000 n
+0000008046 00000 n
+0000008275 00000 n
+0000008531 00000 n
+0000008751 00000 n
+0000008964 00000 n
+0000009014 00000 n
+0000009230 00000 n
+0000009444 00000 n
+0000009645 00000 n
+0000009695 00000 n
+trailer <<
+ /Root 1 0 R
+ /Size 63
+ /ID [<d3fab8d0603e683dc94e42ac31141868><31415926535897932384626433832795>]
+>>
+startxref
+9717
+%%EOF