summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorDan Allen <dan.j.allen@gmail.com>2022-05-14 14:06:06 -0600
committerGitHub <noreply@github.com>2022-05-14 14:06:06 -0600
commit77393d3459be6a91e118a0e16a37a1d6a414f9ca (patch)
tree91256d516857c7106d8118ce2b0cd4b43b32daf1 /spec
parent508ab3f5f2062fb856626ebfd6a6ec5d57b25b52 (diff)
resolves #353 add support for image float to converter (PR #2147)
Diffstat (limited to 'spec')
-rw-r--r--spec/fixtures/lorem-ipsum.yml5
-rw-r--r--spec/fixtures/rect.pngbin0 -> 845 bytes
-rw-r--r--spec/image_float_spec.rb928
-rw-r--r--spec/reference/image-float.pdf963
4 files changed, 1896 insertions, 0 deletions
diff --git a/spec/fixtures/lorem-ipsum.yml b/spec/fixtures/lorem-ipsum.yml
index 479413e2..e36e2560 100644
--- a/spec/fixtures/lorem-ipsum.yml
+++ b/spec/fixtures/lorem-ipsum.yml
@@ -5,6 +5,11 @@
2-sentences-1-paragraph: |-
Lorem ipsum dolor sit amet consectetur adipiscing elit conubia turpis, elementum porttitor sagittis pellentesque dictumst egestas ante praesent.
Magna velit egestas quam sociis placerat facilisis felis mauris, primis ridiculus commodo scelerisque eleifend morbi non.
+4-sentences-1-paragraph: |-
+ Lorem ipsum dolor sit amet consectetur adipiscing elit conubia turpis, elementum porttitor sagittis pellentesque dictumst egestas ante praesent.
+ Magna velit egestas quam sociis placerat facilisis felis mauris, primis ridiculus commodo scelerisque eleifend morbi non.
+ Blandit nam porta arcu sociosqu eros libero cras morbi, enim tempus est elementum ut interdum accumsan, hendrerit ornare imperdiet proin vivamus inceptos fames mi, sociis leo odio donec mattis hac.
+ Condimentum egestas velit accumsan lobortis montes quisque mattis curae placerat magna, primis justo tristique elementum facilisis penatibus pretium in scelerisque est, euismod tempor luctus tincidunt sed potenti enim ac ut.
2-sentences-2-paragraphs: |-
Lorem ipsum dolor sit amet consectetur adipiscing elit conubia turpis, elementum porttitor sagittis pellentesque dictumst egestas ante praesent.
diff --git a/spec/fixtures/rect.png b/spec/fixtures/rect.png
new file mode 100644
index 00000000..d146357e
--- /dev/null
+++ b/spec/fixtures/rect.png
Binary files differ
diff --git a/spec/image_float_spec.rb b/spec/image_float_spec.rb
new file mode 100644
index 00000000..24f24ad4
--- /dev/null
+++ b/spec/image_float_spec.rb
@@ -0,0 +1,928 @@
+# frozen_string_literal: true
+
+require_relative 'spec_helper'
+
+describe 'Asciidoctor::PDF::Converter - Image Float' do
+ page_width = 612.0
+ page_height = 792.0
+ page_margin = 36.0
+ float_gap_s = 12.0
+ float_gap_b = 6.0
+
+ let :pdf_theme do
+ {
+ page_margin: page_margin,
+ page_size: [page_width, page_height],
+ }
+ end
+
+ it 'should ignore float attribute is value is unknown' do
+ input = <<~EOS
+ image::rect.png[pdfwidth=3in,float=center]
+
+ #{lorem_ipsum '1-sentence'}
+ EOS
+
+ image = (to_pdf input, pdf_theme: pdf_theme, analyze: :image).images[0]
+ pdf = to_pdf input, pdf_theme: pdf_theme, analyze: true
+ (expect image[:x]).to eql page_margin
+ first_line = pdf.text[0]
+ (expect first_line[:y]).to be < (image[:y] + image[:height])
+ end
+
+ it 'should wrap paragraph around left of image with float right' do
+ input = <<~EOS
+ image::rect.png[pdfwidth=3in,float=right]
+
+ #{lorem_ipsum '1-sentence'}
+ EOS
+
+ images = (to_pdf input, pdf_theme: pdf_theme, analyze: :image).images
+ (expect images).to have_size 1
+ image = images[0]
+ (expect image[:width].to_f).to eql 216.0
+ (expect image[:x].to_f).to eql page_width - page_margin - image[:width].to_f
+ pdf = to_pdf input, pdf_theme: pdf_theme, analyze: true
+ first_line = pdf.text[0]
+ (expect first_line[:x].to_f).to eql page_margin
+ text_right_boundary = image[:x] - float_gap_s
+ pdf.text.each {|text| (expect text[:x] + text[:width]).to be < text_right_boundary }
+ end
+
+ it 'should ignore align attribute if float attribute is set' do
+ input = <<~EOS
+ image::rect.png[pdfwidth=3in,align=left,float=right]
+
+ #{lorem_ipsum '1-sentence'}
+ EOS
+
+ image = (to_pdf input, pdf_theme: pdf_theme, analyze: :image).images[0]
+ (expect image[:x].to_f).to eql page_width - page_margin - image[:width].to_f
+ pdf = to_pdf input, pdf_theme: pdf_theme, analyze: true
+ first_line = pdf.text[0]
+ (expect first_line[:x].to_f).to eql page_margin
+ text_right_boundary = image[:x] - float_gap_s
+ pdf.text.each {|text| (expect text[:x] + text[:width]).to be < text_right_boundary }
+ end
+
+ it 'should wrap paragraph around right of image with float left' do
+ input = <<~EOS
+ image::rect.png[pdfwidth=3in,float=left]
+
+ #{lorem_ipsum '1-sentence'}
+ EOS
+
+ images = (to_pdf input, pdf_theme: pdf_theme, analyze: :image).images
+ (expect images).to have_size 1
+ image = images[0]
+ (expect image[:width].to_f).to eql 216.0
+ (expect image[:x].to_f).to eql page_margin
+ pdf = to_pdf input, pdf_theme: pdf_theme, analyze: true
+ text_left_boundary = image[:x] + image[:width] + float_gap_s
+ pdf.text.each {|text| (expect text[:x]).to eql text_left_boundary }
+ end
+
+ it 'should apply hyphenation to paragraph in float box if hyphens is set', if: (gem_available? 'text-hyphen'), &(proc do
+ input = <<~EOS
+ :hyphens:
+
+ image::rect.png[pdfwidth=3in,float=right]
+
+ This story chronicles the inexplicable hazards and tremendously vicious beasts the team must conquer and vanquish.
+ EOS
+
+ pdf = to_pdf input, pdf_theme: pdf_theme, analyze: true
+ lines = pdf.lines
+ (expect lines).to have_size 2
+ (expect lines[0]).to end_with ?\u00ad
+ (expect lines[0].count ?\u00ad).to be 1
+ end)
+
+ it 'should apply base font color to text within float box' do
+ pdf_theme[:base_font_color] = '0000AA'
+ input = <<~EOS
+ image::rect.png[pdfwidth=3in,float=right]
+
+ #{lorem_ipsum '1-sentence'}
+ EOS
+
+ pdf = to_pdf input, pdf_theme: pdf_theme, analyze: true
+ (expect pdf.text[0][:font_color]).to eql pdf_theme[:base_font_color]
+ end
+
+ it 'should fit single paragraph within float box' do
+ input = <<~EOS
+ image::rect.png[pdfwidth=3in,float=right]
+
+ #{lorem_ipsum '1-sentence'}
+ *fin*
+ EOS
+
+ image = (to_pdf input, pdf_theme: pdf_theme, analyze: :image).images[0]
+ pdf = to_pdf input, pdf_theme: pdf_theme, analyze: true
+ fin_text = pdf.find_unique_text 'fin'
+ (expect fin_text).not_to be_nil
+ (expect fin_text[:x] + fin_text[:width]).to be < image[:x]
+ (expect fin_text[:y]).to be > image[:y] - image[:height]
+ end
+
+ it 'should fit multiple paragraphs within float box' do
+ input = <<~EOS
+ image::rect.png[pdfwidth=3in,float=left]
+
+ #{lorem_ipsum '2-sentences-2-paragraphs'}
+ EOS
+
+ pdf = to_pdf input, pdf_theme: (pdf_theme.merge section_indent: [228, 0]), analyze: true
+ fragments = pdf.text
+ expected_text_top = fragments[0][:y]
+ p2_start_idx = fragments.index {|it| it[:string].start_with? 'Magna' }
+ expected_paragraph_gap = (fragments[p2_start_idx - 1][:y] - fragments[p2_start_idx][:y]).round 5
+
+ image = (to_pdf input, pdf_theme: pdf_theme, analyze: :image).images[0]
+ pdf = to_pdf input, pdf_theme: pdf_theme, analyze: true
+ text_left_boundary = image[:x] + image[:width] + float_gap_s
+ fragments = pdf.text
+ fragments.each {|text| (expect text[:x]).to eql text_left_boundary }
+ p2_start_idx = fragments.index {|it| it[:string].start_with? 'Magna' }
+ paragraph_gap = (fragments[p2_start_idx - 1][:y] - fragments[p2_start_idx][:y]).round 5
+ (expect fragments[0][:y]).to eql expected_text_top
+ (expect paragraph_gap).to eql expected_paragraph_gap
+ end
+
+ it 'should wrap current paragraph around bottom of image if it extends beyond image' do
+ input = <<~EOS
+ image::rect.png[pdfwidth=3in,float=left]
+
+ #{lorem_ipsum '4-sentences-1-paragraph'}
+ EOS
+
+ image = (to_pdf input, pdf_theme: pdf_theme, analyze: :image).images[0]
+ pdf = to_pdf input, pdf_theme: pdf_theme, analyze: true
+ text_left_boundary = image[:x] + image[:width] + float_gap_s
+ fragments = pdf.text
+ first_line_text = fragments[0]
+ (expect first_line_text[:x]).to eql text_left_boundary
+ last_line_text = fragments[-1]
+ (expect last_line_text[:x]).to eql page_margin
+ # NOTE: the line that didn't fit will be fragmented so that two fragments get placed on the first line under the image
+ (expect fragments[-3][:y]).to eql fragments[-2][:y]
+ line_gaps = (1.upto fragments.size - 1).map {|idx| (fragments[idx - 1][:y] - fragments[idx][:y]).round 5 }.reject {|it| it == 0 }
+ (expect line_gaps.reject(&:zero?).uniq).to eql [15.78]
+ end
+
+ it 'should wrap second paragraph around bottom of image if it extends beyond image' do
+ input = <<~EOS
+ image::rect.png[pdfwidth=3in,float=left]
+
+ #{lorem_ipsum '4-sentences-2-paragraphs'}
+ EOS
+
+ image = (to_pdf input, pdf_theme: pdf_theme, analyze: :image).images[0]
+ pdf = to_pdf input, pdf_theme: pdf_theme, analyze: true
+ text_left_boundary = image[:x] + image[:width] + float_gap_s
+ fragments = pdf.text
+ first_line_text = fragments[0]
+ (expect first_line_text[:x]).to eql text_left_boundary
+ last_line_text = fragments[-1]
+ (expect last_line_text[:x]).to eql page_margin
+ end
+
+ it 'should wrap around single-line caption on bottom of image' do
+ pdf_theme[:image_caption_font_color] = 'AA0000'
+ input = <<~EOS
+ .Image description
+ image::rect.png[pdfwidth=2in,float=left]
+
+ #{lorem_ipsum '4-sentences-2-paragraphs'}
+ EOS
+
+ image = (to_pdf input, pdf_theme: pdf_theme, analyze: :image).images[0]
+ pdf = to_pdf input, pdf_theme: pdf_theme, analyze: true
+ text_left_boundary = image[:x] + image[:width] + float_gap_s
+ caption_texts = pdf.find_text font_color: 'AA0000'
+ (expect caption_texts).to have_size 1
+ (expect caption_texts[0][:x]).to eql page_margin
+ fragments = pdf.text - caption_texts
+ first_line = fragments[0]
+ (expect first_line[:x]).to eql text_left_boundary
+ last_line = fragments[-1]
+ (expect last_line[:x]).to eql page_margin
+ first_line_after_float = fragments.find {|it| it[:x] == page_margin }
+ (expect caption_texts[0][:y] - first_line_after_float[:y]).to (be_within 1).of 30
+ end
+
+ it 'should wrap around multi-line caption on bottom of image' do
+ pdf_theme[:image_caption_font_color] = 'AA0000'
+ input = <<~EOS
+ .Long image description
+ image::rect.png[pdfwidth=2in,float=left]
+
+ #{lorem_ipsum '4-sentences-2-paragraphs'}
+ EOS
+
+ image = (to_pdf input, pdf_theme: pdf_theme, analyze: :image).images[0]
+ pdf = to_pdf input, pdf_theme: pdf_theme, analyze: true
+ text_left_boundary = image[:x] + image[:width] + float_gap_s
+ caption_texts = pdf.find_text font_color: 'AA0000'
+ (expect caption_texts).to have_size 2
+ (expect caption_texts[0][:x]).to eql page_margin
+ fragments = pdf.text - caption_texts
+ first_line = fragments[0]
+ (expect first_line[:x]).to eql text_left_boundary
+ last_line = fragments[-1]
+ (expect last_line[:x]).to eql page_margin
+ first_line_after_float = fragments.find {|it| it[:x] == page_margin }
+ (expect caption_texts[-1][:y] - first_line_after_float[:y]).to (be_within 1).of 30
+ end
+
+ it 'should wrap around bottom of image when image has single-line caption on top' do
+ pdf_theme[:image_caption_end] = 'top'
+ pdf_theme[:image_caption_font_color] = 'AA0000'
+ input = <<~EOS
+ .Image description
+ image::rect.png[pdfwidth=2in,float=left]
+
+ #{lorem_ipsum '4-sentences-2-paragraphs'}
+ EOS
+
+ image = (to_pdf input, pdf_theme: pdf_theme, analyze: :image).images[0]
+ pdf = to_pdf input, pdf_theme: pdf_theme, analyze: true
+ text_left_boundary = image[:x] + image[:width] + float_gap_s
+ fragments = pdf.text - (pdf.find_text font_color: 'AA0000')
+ first_line = fragments[0]
+ (expect first_line[:x]).to eql text_left_boundary
+ last_line = fragments[-1]
+ (expect last_line[:x]).to eql page_margin
+ first_line_after_float = fragments.find {|it| it[:x] == page_margin }
+ expected_ceil = image[:y] - image[:height] - float_gap_b
+ (expect first_line_after_float[:y] + first_line_after_float[:font_size]).to be < expected_ceil
+ end
+
+ it 'should wrap around bottom of image when image has multi-line caption on top' do
+ pdf_theme[:image_caption_end] = 'top'
+ pdf_theme[:image_caption_font_color] = 'AA0000'
+ input = <<~EOS
+ .Long image description
+ image::rect.png[pdfwidth=2in,float=left]
+
+ #{lorem_ipsum '4-sentences-2-paragraphs'}
+ EOS
+
+ image = (to_pdf input, pdf_theme: pdf_theme, analyze: :image).images[0]
+ pdf = to_pdf input, pdf_theme: pdf_theme, analyze: true
+ text_left_boundary = image[:x] + image[:width] + float_gap_s
+ fragments = pdf.text - (pdf.find_text font_color: 'AA0000')
+ first_line = fragments[0]
+ (expect first_line[:x]).to eql text_left_boundary
+ last_line = fragments[-1]
+ (expect last_line[:x]).to eql page_margin
+ first_line_after_float = fragments.find {|it| it[:x] == page_margin }
+ expected_ceil = image[:y] - image[:height] - float_gap_b
+ (expect first_line_after_float[:y] + first_line_after_float[:font_size]).to be < expected_ceil
+ end
+
+ it 'should place caption directly under image when image floats to the right' do
+ input = <<~EOS
+ .Image description
+ image::rect.png[pdfwidth=3in,float=right]
+
+ #{lorem_ipsum '1-sentence'}
+ EOS
+
+ image = (to_pdf input, pdf_theme: pdf_theme, analyze: :image).images[0]
+ pdf = to_pdf input, pdf_theme: pdf_theme, analyze: true
+ caption_text = pdf.find_unique_text %r/^Figure/
+ (expect caption_text[:x]).to eql image[:x]
+ end
+
+ it 'should allow theme to specify float gap using single value' do
+ pdf_theme[:image_float_gap] = 24
+ input = <<~EOS
+ image::rect.png[pdfwidth=3in,float=left]
+
+ #{lorem_ipsum '4-sentences-2-paragraphs'}
+ EOS
+
+ image = (to_pdf input, pdf_theme: pdf_theme, analyze: :image).images[0]
+ pdf = to_pdf input, pdf_theme: pdf_theme, analyze: true
+ text_left_boundary = image[:x] + image[:width] + pdf_theme[:image_float_gap]
+ fragments = pdf.text
+ first_line = fragments[0]
+ (expect first_line[:x]).to eql text_left_boundary
+ last_line = fragments[-1]
+ (expect last_line[:x]).to eql page_margin
+ first_line_after_float = (pdf.find_text x: page_margin)[0]
+ expected_ceil = image[:y] - image[:height] - pdf_theme[:image_float_gap]
+ (expect first_line_after_float[:y]).to be < expected_ceil
+ end
+
+ it 'should allow theme to specify float gap using array value (side, bottom)' do
+ pdf_theme[:image_float_gap] = [0, 0]
+ input = <<~EOS
+ image::rect.png[pdfwidth=3in,float=left]
+
+ #{lorem_ipsum '4-sentences-2-paragraphs'}
+ EOS
+
+ image = (to_pdf input, pdf_theme: pdf_theme, analyze: :image).images[0]
+ pdf = to_pdf input, pdf_theme: pdf_theme, analyze: true
+ text_left_boundary = image[:x] + image[:width]
+ fragments = pdf.text
+ first_line = fragments[0]
+ (expect first_line[:x]).to eql text_left_boundary
+ last_line = fragments[-1]
+ (expect last_line[:x]).to eql page_margin
+ first_line_after_float = (pdf.find_text x: page_margin)[0]
+ expected_ceil = image[:y] - image[:height]
+ (expect first_line_after_float[:y]).to be < expected_ceil
+ end
+
+ it 'should apply base font color to text that extends beyond image' do
+ pdf_theme[:base_font_color] = '0000AA'
+ input = <<~EOS
+ image::rect.png[pdfwidth=3in,float=right]
+
+ #{lorem_ipsum '4-sentences-1-paragraph'}
+ EOS
+
+ pdf = to_pdf input, pdf_theme: pdf_theme, analyze: true
+ (expect pdf.text[-1][:font_color]).to eql pdf_theme[:base_font_color]
+ end
+
+ it 'should add anchors to paragraphs in float box' do
+ input = <<~EOS
+ image::rect.png[pdfwidth=3in,float=right]
+
+ [#first]
+ #{lorem_ipsum '1-sentence'}
+
+ [#second]
+ #{lorem_ipsum '1-sentence'}
+ EOS
+
+ pdf = to_pdf input, pdf_theme: pdf_theme
+ names = get_names pdf
+ (expect names).to have_key 'first'
+ (expect names).to have_key 'second'
+ end
+
+ it 'should apply text-align to text within float box' do
+ input = <<~'EOS'
+ image::rect.png[pdfwidth=3in,float=right]
+
+ [.text-center]
+ center me
+ EOS
+
+ image = (to_pdf input, pdf_theme: pdf_theme, analyze: :image).images[0]
+ text = (to_pdf input, pdf_theme: pdf_theme, analyze: true).text[0]
+ (expect text[:x]).to be > page_margin
+ midpoint = text[:x] + (text[:width] * 0.5)
+ expected_midpoint = (image[:x] - float_gap_s - page_margin) * 0.5 + page_margin
+ (expect midpoint).to eql expected_midpoint
+ end
+
+ it 'should support role on paragraph in float box' do
+ pdf_theme[:role_important_text_align] = 'center'
+ pdf_theme[:role_important_font_color] = 'AA0000'
+ pdf_theme[:role_important_text_transform] = 'uppercase'
+ input = <<~'EOS'
+ image::rect.png[pdfwidth=3in,float=right]
+
+ [.important]
+ center me
+ EOS
+
+ image = (to_pdf input, pdf_theme: pdf_theme, analyze: :image).images[0]
+ text = (to_pdf input, pdf_theme: pdf_theme, analyze: true).text[0]
+ (expect text[:x]).to be > page_margin
+ midpoint = text[:x] + (text[:width] * 0.5)
+ expected_midpoint = (image[:x] - float_gap_s - page_margin) * 0.5 + page_margin
+ (expect midpoint).to eql expected_midpoint
+ (expect text[:string]).to eql 'CENTER ME'
+ (expect text[:font_color]).to eql 'AA0000'
+ end
+
+ # TODO: could check that gap to next paragraph is correct
+ it 'should honor role that changes font size, font family, and line height on paragraph in float box' do
+ pdf_theme[:extends] = 'default-with-fallback-font'
+ pdf_theme[:role_lead_line_height] = 1.5
+ pdf_theme[:role_lead_font_family] = 'M+ 1p Fallback'
+ pdf_theme[:role_muted_font_color] = '999999'
+ input = <<~EOS
+ image::rect.png[pdfwidth=2.25in,float=left]
+
+ [.muted]
+ #{lorem_ipsum '1-sentence'}
+
+ [.lead]
+ #{lorem_ipsum '2-sentences-1-paragraph'}
+
+ [.muted]
+ #{lorem_ipsum '1-sentence'}
+ EOS
+
+ image = (to_pdf input, pdf_theme: pdf_theme, analyze: :image).images[0]
+ pdf = to_pdf input, pdf_theme: pdf_theme, analyze: true
+ lead_fragments = pdf.text - (pdf.find_text font_color: '999999')
+ (expect lead_fragments[0][:x]).to eql image[:x] + image[:width] + float_gap_s
+ (expect lead_fragments[-1][:x]).to eql page_margin
+ lead_fragments.each do |fragment|
+ (expect fragment[:font_name]).to eql 'mplus-1p-regular'
+ (expect fragment[:font_size]).to eql 13
+ end
+ line_gaps = (1.upto lead_fragments.size - 1)
+ .map {|idx| (lead_fragments[idx - 1][:y] - lead_fragments[idx][:y]).round 5 }
+ .reject {|it| it == 0 }
+ (expect line_gaps.uniq).to eql [20.67]
+ end
+
+ it 'should support prose text indent and prose margin inner' do
+ pdf_theme.update \
+ prose_text_indent_inner: 18,
+ prose_margin_inner: 0
+ input = <<~EOS
+ image::rect.png[pdfwidth=50%,float=right]
+
+ #{lorem_ipsum '4-sentences-2-paragraphs'}
+
+ fin.
+ EOS
+ image = (to_pdf input, pdf_theme: pdf_theme, analyze: :image).images[0]
+ pdf = to_pdf input, pdf_theme: pdf_theme, analyze: true
+ first_line_first_para_text = pdf.find_unique_text %r/^Lorem/
+ (expect first_line_first_para_text[:x]).to eql page_margin
+ first_line_second_para_text = pdf.find_unique_text %r/^Blandit/
+ (expect first_line_second_para_text[:x]).to eql page_margin + 18
+ first_line_last_para_text = pdf.find_unique_text 'fin.'
+ (expect first_line_last_para_text[:x]).to eql page_margin + 18
+ lines_wrapping_under = pdf.text.select {|it| it[:x] + it[:width] > image[:x] }
+ (expect lines_wrapping_under).not_to be_empty
+ last_line_first_para_text = pdf.text[(pdf.text.index first_line_second_para_text) - 1]
+ inner_margin = last_line_first_para_text[:y] - (first_line_second_para_text[:y] + first_line_second_para_text[:font_size])
+ (expect inner_margin).to be < 12
+ end
+
+ it 'should not end float box if next unstyled paragraph will fit' do
+ with_content_spacer 180, 220 do |spacer_path|
+ input = <<~EOS
+ image::#{spacer_path}[float=left]
+
+ #{lorem_ipsum '1-sentence'}
+
+ [.lead]
+ #{lorem_ipsum '2-sentences-1-paragraph'}
+
+ #{lorem_ipsum '1-sentence'}
+ EOS
+
+ pdf = to_pdf input, pdf_theme: pdf_theme, analyze: true
+ expected_x = 228.0
+ pdf.text.each {|text| (expect text[:x]).to eql expected_x }
+ end
+ end
+
+ it 'should position next block below wrapped content when wrapped content extends past image' do
+ pdf_theme.update code_border_radius: 0, code_border_color: '0000EE', code_border_width: [0.5, 0, 0, 0]
+
+ ref_input = <<~'EOS'
+ para
+
+ ----
+ code block
+ ----
+ EOS
+
+ expected_margin = (
+ ((to_pdf ref_input, pdf_theme: pdf_theme, analyze: true).find_unique_text 'para')[:y] -
+ (to_pdf ref_input, pdf_theme: pdf_theme, analyze: :line).lines[0][:from][:y]
+ ).round 5
+
+ input = <<~EOS
+ image::rect.png[pdfwidth=1.75in,float=left]
+
+ #{lorem_ipsum '2-paragraphs'}
+
+ ----
+ code block
+ ----
+ EOS
+
+ image = (to_pdf input, pdf_theme: pdf_theme, analyze: :image).images[0]
+ code_block_top = (to_pdf input, pdf_theme: pdf_theme, analyze: :line).lines[0][:from][:y]
+ pdf = to_pdf input, pdf_theme: pdf_theme, analyze: true
+ float_bottom = image[:y] - image[:height]
+ last_para_text = pdf.find_unique_text %r/All your base/
+ (expect last_para_text[:x]).to eql (image[:x] + image[:width] + float_gap_s)
+ (expect last_para_text[:y]).to be < float_bottom
+ (expect code_block_top).to be < float_bottom
+ code_block_text = pdf.find_unique_text 'code block'
+ (expect code_block_text[:y]).to be < code_block_top
+ (expect (last_para_text[:y] - code_block_top).round 5).to eql expected_margin
+ end
+
+ it 'should end float box after first paragraph if next block is not a paragraph' do
+ input = <<~EOS
+ image::rect.png[pdfwidth=3in,float=left]
+
+ #{lorem_ipsum '1-sentence'}
+
+ term:: desc
+ EOS
+
+ image = (to_pdf input, pdf_theme: pdf_theme, analyze: :image).images[0]
+ pdf = to_pdf input, pdf_theme: pdf_theme, analyze: true
+ text_left_boundary = image[:x] + image[:width] + float_gap_s
+ (expect pdf.text[0][:x]).to eql text_left_boundary
+ term_text = pdf.find_unique_text 'term'
+ (expect term_text[:x]).to eql page_margin
+ compiled_pdf_theme = build_pdf_theme pdf_theme
+ expected_next_top = image[:y] - image[:height] - compiled_pdf_theme.block_margin_bottom
+ (expect term_text[:y] + term_text[:font_size]).to (be_within 2).of expected_next_top
+ end
+
+ it 'should not create float box if next block is not a paragraph' do
+ input = <<~'EOS'
+ image::rect.png[pdfwidth=50%,float=right]
+
+ term:: desc
+ EOS
+
+ image = (to_pdf input, pdf_theme: pdf_theme, analyze: :image).images[0]
+ pdf = to_pdf input, pdf_theme: pdf_theme, analyze: true
+ compiled_pdf_theme = build_pdf_theme pdf_theme
+ expected_next_top = image[:y] - image[:height] - compiled_pdf_theme.block_margin_bottom
+ term_text = pdf.find_unique_text 'term'
+ (expect term_text[:x]).to eql page_margin
+ (expect term_text[:y] + term_text[:font_size]).to (be_within 2).of expected_next_top
+ (expect image[:x]).to eql (pdf.pages[0][:size][0] * 0.5)
+ end
+
+ # also verifies that unwrapped paragraph isn't pulled closer to previous than prose margin bottom
+ it 'should continue below image if next paragraph does not fit in remaining height' do
+ pdf_theme[:role_outline_border_width] = 0.5
+ pdf_theme[:role_outline_border_color] = '0000EE'
+ input = <<~EOS
+ image::rect.png[pdfwidth=1.5in,float=left]
+
+ #{(lorem_ipsum '4-sentences-2-paragraphs').gsub %r/non|nam/, '[.outline]#\\0#'}
+ EOS
+
+ image = (to_pdf input, pdf_theme: pdf_theme, analyze: :image).images[0]
+ pdf = to_pdf input, pdf_theme: pdf_theme, analyze: true
+ rects = (to_pdf input, pdf_theme: pdf_theme, analyze: :rect).rectangles
+ text_left_boundary = image[:x] + image[:width] + float_gap_s
+ (expect pdf.text[0][:x]).to eql text_left_boundary
+ last_para_in_float_bottom = rects[0][:point][1]
+ first_para_below_float_top = rects[1][:point][1] + rects[1][:height]
+ (expect last_para_in_float_bottom - first_para_below_float_top).to eql 13.5 # 12 + 1.5 leading
+ end
+
+ it 'should indent and align next paragraph if next paragraph does not fit in remaining height and prose-text-indent is set' do
+ pdf_theme[:prose_text_indent] = 18
+ input = <<~EOS
+ image::rect.png[pdfwidth=1.5in,float=left]
+
+ #{(lorem_ipsum '4-sentences-2-paragraphs').sub 'Blandit', %([.text-left]\nBlandit)}
+ EOS
+
+ image = (to_pdf input, pdf_theme: pdf_theme, analyze: :image).images[0]
+ pdf = to_pdf input, pdf_theme: pdf_theme, analyze: true
+ text_left_boundary = image[:x] + image[:width] + float_gap_s
+ (expect pdf.text[0][:x]).to eql text_left_boundary + 18
+ first_line_below_float = pdf.text.find {|it| it[:x] < text_left_boundary }
+ (expect first_line_below_float[:x]).to eql page_margin + 18
+ end
+
+ it 'should advance cursor to block bottom if next paragraph does not fit and cursor is above block bottom' do
+ pdf_theme[:role_outline_border_width] = 0.5
+ pdf_theme[:role_outline_border_color] = '0000EE'
+ input = <<~EOS
+ image::rect.png[pdfwidth=110.6pt,float=left]
+
+ #{lorem_ipsum '2-sentences-1-paragraph'}
+
+ [.outline]#fin#.
+ EOS
+
+ image = (to_pdf input, pdf_theme: pdf_theme, analyze: :image).images[0]
+ expected_y = image[:y] - image[:height] - float_gap_b
+ rects = (to_pdf input, pdf_theme: pdf_theme, analyze: :rect).rectangles
+ actual_y = rects[0].yield_self {|it| it[:point][1] + it[:height] }
+ (expect actual_y).to (be_within 1).of expected_y # off by top padding of prose
+ end
+
+ it 'should end float box if inked text depletes float box' do
+ input = <<~EOS
+ image::rect.png[pdfwidth=1.2in,float=left]
+
+ #{lorem_ipsum '2-sentences-1-paragraph'}
+
+ after
+
+ after that
+ EOS
+
+ image = (to_pdf input, pdf_theme: pdf_theme, analyze: :image).images[0]
+ pdf = to_pdf input, pdf_theme: pdf_theme, analyze: true
+ last_text_in_float_box = (pdf.find_text x: (image[:x] + image[:width] + float_gap_s))[-1]
+ expected_gap = (pdf.text[-2][:y] - pdf.text[-1][:y]).round 5
+ (expect (last_text_in_float_box[:y] - pdf.text[-2][:y]).round 5).to eql expected_gap
+ end
+
+ it 'should leave no less than bottom gap below image' do
+ pdf_theme[:role_outline_border_width] = 0.5
+ pdf_theme[:role_outline_border_color] = '0000EE'
+ [[116.5, 6], [117, 22]].each do |pdfwidth, expected_gap|
+ input = <<~EOS
+ image::rect.png[pdfwidth=#{pdfwidth}pt,float=left]
+
+ #{(lorem_ipsum '4-sentences-1-paragraph').sub 'lobortis', '[.outline]#lobortis#'}
+ EOS
+
+ image = (to_pdf input, pdf_theme: pdf_theme, analyze: :image).images[0]
+ rects = (to_pdf input, pdf_theme: pdf_theme, analyze: :rect).rectangles
+ first_line_below_float_top = rects[0].yield_self {|it| (it[:point][1] + it[:height]).round 5 }
+ actual_gap = image[:y] - image[:height] - first_line_below_float_top
+ (expect actual_gap).to be > 6
+ (expect actual_gap).to (be_within 1).of expected_gap
+ end
+ end
+
+ it 'should allow paragraph that starts in float box to extend to next page' do
+ with_content_spacer 10, 596 do |spacer_path|
+ input = <<~EOS
+ image::#{spacer_path}[]
+
+ image::rect.png[pdfwidth=2in,float=left]
+
+ #{lorem_ipsum '4-sentences-1-paragraph'}
+
+ <<<
+
+ at top
+ EOS
+
+ image = (to_pdf input, pdf_theme: pdf_theme, analyze: :image).images[0]
+ pdf = to_pdf input, pdf_theme: pdf_theme, analyze: true
+ p1_fragments = pdf.find_text page_number: 1
+ (expect p1_fragments).not_to be_empty
+ p1_fragments.each do |fragment|
+ (expect fragment[:x]).to eql image[:x] + image[:width] + float_gap_s
+ end
+ p2_fragments = (pdf.find_text page_number: 2).uniq {|it| it[:y] }
+ (expect p2_fragments).not_to be_empty
+ p2_fragments.each do |fragment|
+ (expect fragment[:x]).to eql page_margin
+ end
+ # FIXME: off by line_metrics.padding_top, which doesn't get applied at page transition
+ (expect p2_fragments[0][:y] - 0.75).to eql (pdf.find_text page_number: 3)[0][:y]
+ end
+ end
+
+ it 'should run float box to bottom of page if taller than remaining space on page' do
+ with_content_spacer 10, 605 do |spacer_path|
+ input = <<~EOS
+ image::#{spacer_path}[]
+
+ image::rect.png[pdfwidth=2in,float=left]
+
+ #{lorem_ipsum '4-sentences-1-paragraph'}
+
+ <<<
+
+ at top
+ EOS
+
+ image = (to_pdf input, pdf_theme: pdf_theme, analyze: :image).images[0]
+ pdf = to_pdf input, pdf_theme: pdf_theme, analyze: true
+ p1_fragments = pdf.find_text page_number: 1
+ (expect p1_fragments).not_to be_empty
+ p1_fragments.each do |fragment|
+ (expect fragment[:x]).to eql image[:x] + image[:width] + float_gap_s
+ end
+ p2_fragments = (pdf.find_text page_number: 2).uniq {|it| it[:y] }
+ (expect p2_fragments).not_to be_empty
+ p2_fragments.each do |fragment|
+ (expect fragment[:x]).to eql page_margin
+ end
+ # FIXME: off by line_metrics.padding_top, which doesn't get applied at page transition
+ (expect p2_fragments[0][:y] - 0.75).to eql (pdf.find_text page_number: 3)[0][:y]
+ end
+ end
+
+ it 'should not continue float box if bottom margin of last paragraph starts new page' do
+ with_content_spacer 10, 630 do |spacer_path|
+ input = <<~EOS
+ image::#{spacer_path}[]
+
+ image::rect.png[pdfwidth=1.5in,float=left]
+
+ #{lorem_ipsum '2-sentences-2-paragraphs'}
+
+ at top
+ EOS
+
+ image = (to_pdf input, pdf_theme: pdf_theme, analyze: :image).images[0]
+ pdf = to_pdf input, pdf_theme: pdf_theme, analyze: true
+ expected_wrap_margin = image[:x] + image[:width] + float_gap_s
+ p1_fragments = pdf.find_text page_number: 1
+ (expect p1_fragments).not_to be_empty
+ p1_fragments.each {|fragment| (expect fragment[:x]).to eql expected_wrap_margin }
+ at_top_text = pdf.find_unique_text 'at top'
+ (expect at_top_text[:page_number]).to eql 2
+ (expect at_top_text[:x]).to eql page_margin
+ (expect at_top_text).to eql (pdf.find_text page_number: 2)[0]
+ end
+ end
+
+ it 'should float image inside a delimited block' do
+ input = <<~EOS
+ ****
+ image::rect.png[pdfwidth=3in,float=left]
+
+ #{lorem_ipsum '4-sentences-2-paragraphs'}
+ ****
+ EOS
+
+ image = (to_pdf input, pdf_theme: pdf_theme, analyze: :image).images[0]
+ pdf = to_pdf input, pdf_theme: pdf_theme, analyze: true
+ (expect image[:x]).to eql page_margin + 15
+ text_left_boundary = image[:x] + image[:width] + float_gap_s
+ fragments = pdf.text
+ first_line_text = fragments[0]
+ (expect first_line_text[:x]).to eql text_left_boundary
+ last_line_text = fragments[-1]
+ (expect last_line_text[:x]).to eql page_margin + 15
+ end
+
+ it 'should support multiple image floats in same document', visual: true do
+ input = <<~EOS
+ Start.
+
+ image::rect.png[pdfwidth=2.5in,float=left]
+
+ #{lorem_ipsum '4-sentences-2-paragraphs'}
+
+ .Image description
+ image::rect.png[pdfwidth=50%,float=right]
+
+ #{lorem_ipsum '4-sentences-2-paragraphs'}
+
+ [cols=1;3]
+ |===
+ |normal cell
+ a|
+ #{lorem_ipsum '1-sentence'}
+
+ image::rect.png[pdfwidth=50%,float=right]
+
+ #{lorem_ipsum '2-sentences-1-paragraph'}
+
+ #{lorem_ipsum '1-sentence'}
+ |===
+
+ fin.
+ EOS
+
+ to_file = to_pdf_file input, 'image-float.pdf', pdf_theme: pdf_theme
+ (expect to_file).to visually_match 'image-float.pdf'
+ end
+
+ it 'should not add bottom margin to image with float inside enclosure when wrapped text is shorter than float box' do
+ pdf_theme.update \
+ sidebar_border_radius: 0,
+ sidebar_border_width: [0.5, 0],
+ sidebar_border_color: '0000EE',
+ sidebar_background_color: 'transparent'
+ input = <<~EOS
+ ****
+ image::rect.png[pdfwidth=3in,float=right]
+
+ #{lorem_ipsum '2-sentences-1-paragraph'}
+ ****
+ EOS
+
+ image = (to_pdf input, pdf_theme: pdf_theme, analyze: :image).images[0]
+ lines = (to_pdf input, pdf_theme: pdf_theme, analyze: :line).lines
+ top_padding = lines[0][:from][:y] - image[:y]
+ bottom_padding = (image[:y] - image[:height]) - lines[1][:from][:y]
+ (expect top_padding).to eql 12.0
+ (expect bottom_padding).to eql 12.0
+ end
+
+ it 'should not add bottom margin to paragraph that wraps around image float inside enclosure' do
+ pdf_theme.update \
+ sidebar_border_radius: 0,
+ sidebar_border_width: [0.5, 0],
+ sidebar_border_color: '0000EE',
+ sidebar_background_color: 'transparent'
+ input = <<~EOS
+ ****
+ image::rect.png[pdfwidth=3in,float=right]
+
+ #{lorem_ipsum '4-sentences-2-paragraphs'}
+ ****
+ EOS
+
+ pdf = to_pdf input, pdf_theme: pdf_theme, analyze: true
+ lines = (to_pdf input, pdf_theme: pdf_theme, analyze: :line).lines
+ last_text = pdf.text[-1]
+ (expect (last_text[:y] - lines[1][:from][:y]).round 5).to eql 15.816
+ end
+
+ it 'should not add bottom margin to paragraph that extends past bottom of image float inside enclosure' do
+ pdf_theme.update \
+ sidebar_border_radius: 0,
+ sidebar_border_width: [0.5, 0],
+ sidebar_border_color: '0000EE',
+ sidebar_background_color: 'transparent'
+ input = <<~EOS
+ ****
+ image::rect.png[pdfwidth=2.25in,float=right]
+
+ #{lorem_ipsum '2-paragraphs'}
+ ****
+ EOS
+
+ pdf = to_pdf input, pdf_theme: pdf_theme, analyze: true
+ lines = (to_pdf input, pdf_theme: pdf_theme, analyze: :line).lines
+ last_text = pdf.text[-1]
+ (expect (last_text[:y] - lines[1][:from][:y]).round 5).to eql 15.816
+ end
+
+ it 'should not process paragraph preceded by paragraph without an active float box' do
+ input = <<~'EOS'
+ paragraph
+
+ another paragraph
+ EOS
+
+ pdf = to_pdf input, pdf_theme: pdf_theme, analyze: true
+ pdf.text.each {|fragment| (expect fragment[:x]).to eql page_margin }
+ end
+
+ it 'should not process paragraph preceded by image without float attribute' do
+ input = <<~'EOS'
+ image::rect.png[pdfwidth=3in]
+
+ paragraph
+ EOS
+
+ image = (to_pdf input, pdf_theme: pdf_theme, analyze: :image).images[0]
+ pdf = to_pdf input, pdf_theme: pdf_theme, analyze: true
+ para_fragment = pdf.text[0]
+ (expect para_fragment[:x]).to eql page_margin
+ compiled_pdf_theme = build_pdf_theme pdf_theme
+ expected_top = image[:y] - image[:height] - compiled_pdf_theme.block_margin_bottom
+ (expect para_fragment[:y] + para_fragment[:font_size]).to be < expected_top
+ end
+
+ it 'should not process paragraph preceded by image with float attribute that spans width of content area' do
+ input = <<~EOS
+ image::rect.png[pdfwidth=100%,float=left]
+
+ #{lorem_ipsum '1-sentence'}
+ EOS
+
+ image = (to_pdf input, pdf_theme: pdf_theme, analyze: :image).images[0]
+ pdf = to_pdf input, pdf_theme: pdf_theme, analyze: true
+ para_fragment = pdf.text[0]
+ (expect para_fragment[:x]).to eql page_margin
+ compiled_pdf_theme = build_pdf_theme pdf_theme
+ expected_top = image[:y] - image[:height] - compiled_pdf_theme.block_margin_bottom
+ (expect para_fragment[:y] + para_fragment[:font_size]).to be < expected_top
+ end
+
+ it 'should allow extended converter to enlist other blocks to wrap around float' do
+ source_file = doc_file 'modules/extend/examples/pdf-converter-code-float-wrapping.rb'
+ source_lines = (File.readlines source_file).select {|l| l == ?\n || (l.start_with? ' ') }
+ ext_class = create_class Asciidoctor::Converter.for 'pdf'
+ backend = %(pdf#{ext_class.object_id})
+ source_lines[0] = %( register_for '#{backend}'\n)
+ ext_class.class_eval source_lines.join, source_file
+ input = <<~EOS
+ image::rect.png[pdfwidth=50%,float=left]
+
+ #{lorem_ipsum '1-sentence'}
+
+ ----
+ code
+ here
+ ----
+
+ #{lorem_ipsum '1-sentence'}
+ EOS
+
+ image = (to_pdf input, backend: backend, pdf_theme: pdf_theme, analyze: :image).images[0]
+ pdf = to_pdf input, backend: backend, pdf_theme: pdf_theme, analyze: true
+
+ text_left_boundary = image[:x] + image[:width] + float_gap_s
+ lorem_text = pdf.find_text %r/^Lorem/
+ (expect lorem_text).to have_size 2
+ (expect lorem_text[0][:x]).to eql text_left_boundary
+ (expect lorem_text[1][:x]).to eql lorem_text[0][:x]
+ (expect (pdf.find_unique_text 'code')[:x]).to be > text_left_boundary
+ end
+end
diff --git a/spec/reference/image-float.pdf b/spec/reference/image-float.pdf
new file mode 100644
index 00000000..6db927f3
--- /dev/null
+++ b/spec/reference/image-float.pdf
@@ -0,0 +1,963 @@
+%PDF-1.4
+%
+1 0 obj
+<< /Title (Untitled)
+/Creator (Asciidoctor PDF 2.0.0.beta.1, based on Prawn 2.4.0)
+/Producer (Asciidoctor PDF 2.0.0.beta.1, based on Prawn 2.4.0)
+/ModDate (D:20220514004556-06'00')
+/CreationDate (D:20220514004556-06'00')
+>>
+endobj
+2 0 obj
+<< /Type /Catalog
+/Pages 3 0 R
+/Outlines 11 0 R
+/PageLabels 13 0 R
+/PageMode /UseOutlines
+/OpenAction [7 0 R /FitH 792]
+/ViewerPreferences << /DisplayDocTitle true
+>>
+/Names 15 0 R
+>>
+endobj
+3 0 obj
+<< /Type /Pages
+/Count 1
+/Kids [7 0 R]
+>>
+endobj
+4 0 obj
+<< /Length 2
+>>
+stream
+q
+
+endstream
+endobj
+5 0 obj
+<< /Type /Page
+/Parent 3 0 R
+/MediaBox [0 0 612 792]
+/CropBox [0 0 612 792]
+/BleedBox [0 0 612 792]
+/TrimBox [0 0 612 792]
+/ArtBox [0 0 612 792]
+/Contents 4 0 R
+/Resources << /ProcSet [/PDF /Text /ImageB /ImageC /ImageI]
+>>
+>>
+endobj
+6 0 obj
+<< /Length 10300
+>>
+stream
+q
+/DeviceRGB cs
+0.2 0.2 0.2 scn
+/DeviceRGB CS
+0.2 0.2 0.2 SCN
+
+BT
+36.0 744.036 Td
+/F1.0 10.5 Tf
+<53746172742e> Tj
+ET
+
+0.0 0.0 0.0 SCN
+0.0 0.0 0.0 scn
+
+q
+180.0 0.0 0.0 112.5 36.0 615.72 cm
+/I1 Do
+Q
+0.2 0.2 0.2 scn
+0.2 0.2 0.2 SCN
+
+4.11056 Tw
+
+BT
+228.0 716.256 Td
+/F1.0 10.5 Tf
+<4c6f72656d20697073756d20646f6c6f722073697420616d657420636f6e73656374657475722061646970697363696e6720656c697420636f6e75626961> Tj
+ET
+
+
+0.0 Tw
+0.0 0.0 0.0 SCN
+0.0 0.0 0.0 scn
+0.2 0.2 0.2 scn
+0.2 0.2 0.2 SCN
+
+3.47875 Tw
+
+BT
+228.0 700.476 Td
+/F1.0 10.5 Tf
+<7475727069732c20656c656d656e74756d20706f72747469746f722073616769747469732070656c6c656e7465737175652064696374756d73742065676573746173> Tj
+ET
+
+
+0.0 Tw
+0.0 0.0 0.0 SCN
+0.0 0.0 0.0 scn
+0.2 0.2 0.2 scn
+0.2 0.2 0.2 SCN
+
+0.87021 Tw
+
+BT
+228.0 684.696 Td
+/F1.0 10.5 Tf
+[<616e7465207072> 20.01953 <616573656e742e204d61676e612076656c69742065676573746173207175616d20736f6369697320706c61636572> 20.01953 <617420666163696c697369732066656c6973>] TJ
+ET
+
+
+0.0 Tw
+0.0 0.0 0.0 SCN
+0.0 0.0 0.0 scn
+0.2 0.2 0.2 scn
+0.2 0.2 0.2 SCN
+
+BT
+228.0 668.916 Td
+/F1.0 10.5 Tf
+<6d61757269732c207072696d6973207269646963756c757320636f6d6d6f646f207363656c6572697371756520656c656966656e64206d6f726269206e6f6e2e> Tj
+ET
+
+0.0 0.0 0.0 SCN
+0.0 0.0 0.0 scn
+0.2 0.2 0.2 scn
+0.2 0.2 0.2 SCN
+
+0.14582 Tw
+
+BT
+228.0 641.136 Td
+/F1.0 10.5 Tf
+[<426c616e646974206e616d20706f727461206172637520736f63696f7371752065726f73206c696265726f206372> 20.01953 <6173206d6f7262692c20656e696d2074656d707573>] TJ
+ET
+
+
+0.0 Tw
+0.0 0.0 0.0 SCN
+0.0 0.0 0.0 scn
+0.2 0.2 0.2 scn
+0.2 0.2 0.2 SCN
+
+2.23479 Tw
+
+BT
+228.0 625.356 Td
+/F1.0 10.5 Tf
+<65737420656c656d656e74756d20757420696e74657264756d20616363756d73616e2c2068656e647265726974206f726e61726520696d70657264696574> Tj
+ET
+
+
+0.0 Tw
+0.0 0.0 0.0 SCN
+0.0 0.0 0.0 scn
+0.2 0.2 0.2 scn
+0.2 0.2 0.2 SCN
+
+1.6851 Tw
+
+BT
+228.0 609.576 Td
+/F1.0 10.5 Tf
+<70726f696e20766976616d757320696e636570746f732066616d6573206d692c20736f63696973206c656f206f64696f20646f6e6563206d6174746973206861632e> Tj
+ET
+
+
+0.0 Tw
+0.0 0.0 0.0 SCN
+0.0 0.0 0.0 scn
+0.2 0.2 0.2 scn
+0.2 0.2 0.2 SCN
+
+1.54316 Tw
+
+BT
+36.0 593.796 Td
+/F1.0 10.5 Tf
+<436f6e64696d656e74756d20656765737461732076656c697420616363756d73616e206c6f626f72746973206d6f6e7465732071756973717565206d6174746973> Tj
+ET
+
+
+0.0 Tw
+0.0 0.0 0.0 SCN
+0.0 0.0 0.0 scn
+0.2 0.2 0.2 scn
+0.2 0.2 0.2 SCN
+
+1.54316 Tw
+
+BT
+392.12611 593.796 Td
+/F1.0 10.5 Tf
+[<20637572> 20.01953 <616520706c61636572> 20.01953 <6174206d61676e612c207072696d6973206a7573746f>] TJ
+ET
+
+
+0.0 Tw
+0.0 0.0 0.0 SCN
+0.0 0.0 0.0 scn
+0.2 0.2 0.2 scn
+0.2 0.2 0.2 SCN
+
+2.05675 Tw
+
+BT
+36.0 578.016 Td
+/F1.0 10.5 Tf
+<74726973746971756520656c656d656e74756d20666163696c697369732070656e617469627573207072657469756d20696e207363656c65726973717565206573742c20657569736d6f642074656d706f72206c75637475732074696e636964756e7420736564> Tj
+ET
+
+
+0.0 Tw
+0.0 0.0 0.0 SCN
+0.0 0.0 0.0 scn
+0.2 0.2 0.2 scn
+0.2 0.2 0.2 SCN
+
+BT
+36.0 562.236 Td
+/F1.0 10.5 Tf
+<706f74656e746920656e696d2061632075742e> Tj
+ET
+
+0.0 0.0 0.0 SCN
+0.0 0.0 0.0 scn
+
+q
+270.0 0.0 0.0 168.75 306.0 377.67 cm
+/I2 Do
+Q
+
+BT
+306.0 362.3042 Td
+ET
+
+0.2 0.2 0.2 scn
+0.2 0.2 0.2 SCN
+
+BT
+306.0 362.3042 Td
+/F2.0 9.975 Tf
+<46696775726520312e20496d616765206465736372697074696f6e> Tj
+ET
+
+0.0 0.0 0.0 SCN
+0.0 0.0 0.0 scn
+0.2 0.2 0.2 scn
+0.2 0.2 0.2 SCN
+
+0.76375 Tw
+
+BT
+36.0 534.456 Td
+/F1.0 10.5 Tf
+<4c6f72656d20697073756d20646f6c6f722073697420616d657420636f6e73656374657475722061646970697363696e67> Tj
+ET
+
+
+0.0 Tw
+0.0 0.0 0.0 SCN
+0.0 0.0 0.0 scn
+0.2 0.2 0.2 scn
+0.2 0.2 0.2 SCN
+
+4.1295 Tw
+
+BT
+36.0 518.676 Td
+/F1.0 10.5 Tf
+<656c697420636f6e75626961207475727069732c20656c656d656e74756d20706f72747469746f72207361676974746973> Tj
+ET
+
+
+0.0 Tw
+0.0 0.0 0.0 SCN
+0.0 0.0 0.0 scn
+0.2 0.2 0.2 scn
+0.2 0.2 0.2 SCN
+
+8.92093 Tw
+
+BT
+36.0 502.896 Td
+/F1.0 10.5 Tf
+[<70656c6c656e7465737175652064696374756d7374206567657374617320616e7465207072> 20.01953 <616573656e742e>] TJ
+ET
+
+
+0.0 Tw
+0.0 0.0 0.0 SCN
+0.0 0.0 0.0 scn
+0.2 0.2 0.2 scn
+0.2 0.2 0.2 SCN
+
+2.49103 Tw
+
+BT
+36.0 487.116 Td
+/F1.0 10.5 Tf
+[<4d61676e612076656c69742065676573746173207175616d20736f6369697320706c61636572> 20.01953 <617420666163696c69736973>] TJ
+ET
+
+
+0.0 Tw
+0.0 0.0 0.0 SCN
+0.0 0.0 0.0 scn
+0.2 0.2 0.2 scn
+0.2 0.2 0.2 SCN
+
+0.486 Tw
+
+BT
+36.0 471.336 Td
+/F1.0 10.5 Tf
+<66656c6973206d61757269732c207072696d6973207269646963756c757320636f6d6d6f646f207363656c65726973717565> Tj
+ET
+
+
+0.0 Tw
+0.0 0.0 0.0 SCN
+0.0 0.0 0.0 scn
+0.2 0.2 0.2 scn
+0.2 0.2 0.2 SCN
+
+BT
+36.0 455.556 Td
+/F1.0 10.5 Tf
+<656c656966656e64206d6f726269206e6f6e2e> Tj
+ET
+
+0.0 0.0 0.0 SCN
+0.0 0.0 0.0 scn
+0.2 0.2 0.2 scn
+0.2 0.2 0.2 SCN
+
+2.23567 Tw
+
+BT
+36.0 427.776 Td
+/F1.0 10.5 Tf
+[<426c616e646974206e616d20706f727461206172637520736f63696f7371752065726f73206c696265726f206372> 20.01953 <6173>] TJ
+ET
+
+
+0.0 Tw
+0.0 0.0 0.0 SCN
+0.0 0.0 0.0 scn
+0.2 0.2 0.2 scn
+0.2 0.2 0.2 SCN
+
+2.80075 Tw
+
+BT
+36.0 411.996 Td
+/F1.0 10.5 Tf
+<6d6f7262692c20656e696d2074656d7075732065737420656c656d656e74756d20757420696e74657264756d> Tj
+ET
+
+
+0.0 Tw
+0.0 0.0 0.0 SCN
+0.0 0.0 0.0 scn
+0.2 0.2 0.2 scn
+0.2 0.2 0.2 SCN
+
+8.77125 Tw
+
+BT
+36.0 396.216 Td
+/F1.0 10.5 Tf
+<616363756d73616e2c2068656e647265726974206f726e61726520696d706572646965742070726f696e> Tj
+ET
+
+
+0.0 Tw
+0.0 0.0 0.0 SCN
+0.0 0.0 0.0 scn
+0.2 0.2 0.2 scn
+0.2 0.2 0.2 SCN
+
+2.03014 Tw
+
+BT
+36.0 380.436 Td
+/F1.0 10.5 Tf
+<766976616d757320696e636570746f732066616d6573206d692c20736f63696973206c656f206f64696f20646f6e6563> Tj
+ET
+
+
+0.0 Tw
+0.0 0.0 0.0 SCN
+0.0 0.0 0.0 scn
+0.2 0.2 0.2 scn
+0.2 0.2 0.2 SCN
+
+2.5965 Tw
+
+BT
+36.0 364.656 Td
+/F1.0 10.5 Tf
+<6d6174746973206861632e20436f6e64696d656e74756d20656765737461732076656c697420616363756d73616e> Tj
+ET
+
+
+0.0 Tw
+0.0 0.0 0.0 SCN
+0.0 0.0 0.0 scn
+0.2 0.2 0.2 scn
+0.2 0.2 0.2 SCN
+
+5.82218 Tw
+
+BT
+36.0 348.876 Td
+/F1.0 10.5 Tf
+[<6c6f626f72746973206d6f6e7465732071756973717565206d617474697320637572> 20.01953 <616520706c61636572> 20.01953 <6174>] TJ
+ET
+
+
+0.0 Tw
+0.0 0.0 0.0 SCN
+0.0 0.0 0.0 scn
+0.2 0.2 0.2 scn
+0.2 0.2 0.2 SCN
+
+1.97975 Tw
+
+BT
+36.0 333.096 Td
+/F1.0 10.5 Tf
+<6d61676e612c207072696d6973206a7573746f2074726973746971756520656c656d656e74756d20666163696c6973697320> Tj
+ET
+
+
+0.0 Tw
+0.0 0.0 0.0 SCN
+0.0 0.0 0.0 scn
+0.2 0.2 0.2 scn
+0.2 0.2 0.2 SCN
+
+1.97975 Tw
+
+BT
+295.227 333.096 Td
+/F1.0 10.5 Tf
+<70656e617469627573207072657469756d20696e207363656c65726973717565206573742c20657569736d6f642074656d706f72> Tj
+ET
+
+
+0.0 Tw
+0.0 0.0 0.0 SCN
+0.0 0.0 0.0 scn
+0.2 0.2 0.2 scn
+0.2 0.2 0.2 SCN
+
+BT
+36.0 317.316 Td
+/F1.0 10.5 Tf
+<6c75637475732074696e636964756e742073656420706f74656e746920656e696d2061632075742e> Tj
+ET
+
+0.0 0.0 0.0 SCN
+0.0 0.0 0.0 scn
+1.0 1.0 1.0 scn
+36.0 82.14 135.0 219.36 re
+f
+0.0 0.0 0.0 scn
+1.0 1.0 1.0 scn
+171.0 82.14 405.0 219.36 re
+f
+0.0 0.0 0.0 scn
+0.5 w
+0.86667 0.86667 0.86667 SCN
+36.0 301.5 m
+171.0 301.5 l
+S
+[] 0 d
+0.5 w
+0.86667 0.86667 0.86667 SCN
+36.0 82.14 m
+171.0 82.14 l
+S
+[] 0 d
+0.5 w
+0.86667 0.86667 0.86667 SCN
+36.0 301.75 m
+36.0 81.89 l
+S
+[] 0 d
+0.5 w
+0.86667 0.86667 0.86667 SCN
+171.0 301.75 m
+171.0 81.89 l
+S
+[] 0 d
+1 w
+0.0 0.0 0.0 SCN
+0.2 0.2 0.2 scn
+
+BT
+39.0 286.536 Td
+/F1.0 10.5 Tf
+<6e6f726d616c2063656c6c> Tj
+ET
+
+0.0 0.0 0.0 scn
+0.5 w
+0.86667 0.86667 0.86667 SCN
+171.0 301.5 m
+576.0 301.5 l
+S
+[] 0 d
+0.5 w
+0.86667 0.86667 0.86667 SCN
+171.0 82.14 m
+576.0 82.14 l
+S
+[] 0 d
+0.5 w
+0.86667 0.86667 0.86667 SCN
+171.0 301.75 m
+171.0 81.89 l
+S
+[] 0 d
+0.5 w
+0.86667 0.86667 0.86667 SCN
+576.0 301.75 m
+576.0 81.89 l
+S
+[] 0 d
+1 w
+0.0 0.0 0.0 SCN
+0.2 0.2 0.2 scn
+0.2 0.2 0.2 SCN
+
+5.41333 Tw
+
+BT
+174.0 286.536 Td
+/F1.0 10.5 Tf
+<4c6f72656d20697073756d20646f6c6f722073697420616d657420636f6e73656374657475722061646970697363696e6720656c697420636f6e75626961207475727069732c> Tj
+ET
+
+
+0.0 Tw
+0.0 0.0 0.0 SCN
+0.0 0.0 0.0 scn
+0.2 0.2 0.2 scn
+0.2 0.2 0.2 SCN
+
+BT
+174.0 270.756 Td
+/F1.0 10.5 Tf
+[<656c656d656e74756d20706f72747469746f722073616769747469732070656c6c656e7465737175652064696374756d7374206567657374617320616e7465207072> 20.01953 <616573656e742e>] TJ
+ET
+
+0.0 0.0 0.0 SCN
+0.0 0.0 0.0 scn
+
+q
+199.5 0.0 0.0 124.6875 373.5 130.2525 cm
+/I3 Do
+Q
+0.2 0.2 0.2 scn
+0.2 0.2 0.2 SCN
+
+12.19875 Tw
+
+BT
+174.0 242.976 Td
+/F1.0 10.5 Tf
+<4c6f72656d20697073756d20646f6c6f722073697420616d6574> Tj
+ET
+
+
+0.0 Tw
+0.0 0.0 0.0 SCN
+0.0 0.0 0.0 scn
+0.2 0.2 0.2 scn
+0.2 0.2 0.2 SCN
+
+4.603 Tw
+
+BT
+174.0 227.196 Td
+/F1.0 10.5 Tf
+<636f6e73656374657475722061646970697363696e6720656c697420636f6e75626961> Tj
+ET
+
+
+0.0 Tw
+0.0 0.0 0.0 SCN
+0.0 0.0 0.0 scn
+0.2 0.2 0.2 scn
+0.2 0.2 0.2 SCN
+
+3.9485 Tw
+
+BT
+174.0 211.416 Td
+/F1.0 10.5 Tf
+<7475727069732c20656c656d656e74756d20706f72747469746f72207361676974746973> Tj
+ET
+
+
+0.0 Tw
+0.0 0.0 0.0 SCN
+0.0 0.0 0.0 scn
+0.2 0.2 0.2 scn
+0.2 0.2 0.2 SCN
+
+4.68 Tw
+
+BT
+174.0 195.636 Td
+/F1.0 10.5 Tf
+<70656c6c656e7465737175652064696374756d7374206567657374617320616e7465> Tj
+ET
+
+
+0.0 Tw
+0.0 0.0 0.0 SCN
+0.0 0.0 0.0 scn
+0.2 0.2 0.2 scn
+0.2 0.2 0.2 SCN
+
+2.3918 Tw
+
+BT
+174.0 179.856 Td
+/F1.0 10.5 Tf
+[<7072> 20.01953 <616573656e742e204d61676e612076656c69742065676573746173207175616d>] TJ
+ET
+
+
+0.0 Tw
+0.0 0.0 0.0 SCN
+0.0 0.0 0.0 scn
+0.2 0.2 0.2 scn
+0.2 0.2 0.2 SCN
+
+2.96143 Tw
+
+BT
+174.0 164.076 Td
+/F1.0 10.5 Tf
+[<736f6369697320706c61636572> 20.01953 <617420666163696c697369732066656c6973206d61757269732c>] TJ
+ET
+
+
+0.0 Tw
+0.0 0.0 0.0 SCN
+0.0 0.0 0.0 scn
+0.2 0.2 0.2 scn
+0.2 0.2 0.2 SCN
+
+27.5895 Tw
+
+BT
+174.0 148.296 Td
+/F1.0 10.5 Tf
+<7072696d6973207269646963756c757320636f6d6d6f646f> Tj
+ET
+
+
+0.0 Tw
+0.0 0.0 0.0 SCN
+0.0 0.0 0.0 scn
+0.2 0.2 0.2 scn
+0.2 0.2 0.2 SCN
+
+BT
+174.0 132.516 Td
+/F1.0 10.5 Tf
+<7363656c6572697371756520656c656966656e64206d6f726269206e6f6e2e> Tj
+ET
+
+0.0 0.0 0.0 SCN
+0.0 0.0 0.0 scn
+0.2 0.2 0.2 scn
+0.2 0.2 0.2 SCN
+
+5.41333 Tw
+
+BT
+174.0 104.736 Td
+/F1.0 10.5 Tf
+<4c6f72656d20697073756d20646f6c6f722073697420616d657420> Tj
+ET
+
+
+0.0 Tw
+0.0 0.0 0.0 SCN
+0.0 0.0 0.0 scn
+0.2 0.2 0.2 scn
+0.2 0.2 0.2 SCN
+
+5.41333 Tw
+
+BT
+342.49117 104.736 Td
+/F1.0 10.5 Tf
+<636f6e73656374657475722061646970697363696e6720656c697420636f6e75626961207475727069732c> Tj
+ET
+
+
+0.0 Tw
+0.0 0.0 0.0 SCN
+0.0 0.0 0.0 scn
+0.2 0.2 0.2 scn
+0.2 0.2 0.2 SCN
+
+BT
+174.0 88.956 Td
+/F1.0 10.5 Tf
+[<656c656d656e74756d20706f72747469746f722073616769747469732070656c6c656e7465737175652064696374756d7374206567657374617320616e7465207072> 20.01953 <616573656e742e>] TJ
+ET
+
+0.0 0.0 0.0 SCN
+0.0 0.0 0.0 scn
+0.2 0.2 0.2 scn
+0.2 0.2 0.2 SCN
+
+BT
+36.0 58.176 Td
+/F1.0 10.5 Tf
+<66696e2e> Tj
+ET
+
+0.0 0.0 0.0 SCN
+0.0 0.0 0.0 scn
+Q
+
+endstream
+endobj
+7 0 obj
+<< /Type /Page
+/Parent 3 0 R
+/MediaBox [0 0 612 792]
+/CropBox [0 0 612 792]
+/BleedBox [0 0 612 792]
+/TrimBox [0 0 612 792]
+/ArtBox [0 0 612 792]
+/Contents 6 0 R
+/Resources << /ProcSet [/PDF /Text /ImageB /ImageC /ImageI]
+/Font << /F1.0 8 0 R
+/F2.0 10 0 R
+>>
+/XObject << /I1 9 0 R
+/I2 9 0 R
+/I3 9 0 R
+>>
+>>
+>>
+endobj
+8 0 obj
+<< /Type /Font
+/BaseFont /3e50aa+NotoSerif
+/Subtype /TrueType
+/FontDescriptor 18 0 R
+/FirstChar 32
+/LastChar 255
+/Widths 20 0 R
+/ToUnicode 19 0 R
+>>
+endobj
+9 0 obj
+<< /Type /XObject
+/Subtype /Image
+/ColorSpace /DeviceRGB
+/Height 250
+/Width 400
+/BitsPerComponent 8
+/Length 313
+/Filter [/FlateDecode]
+>>
+stream
+x
+endstream
+endobj
+10 0 obj
+<< /Type /Font
+/BaseFont /c2c7af+NotoSerif-Italic
+/Subtype /TrueType
+/FontDescriptor 22 0 R
+/FirstChar 32
+/LastChar 255
+/Widths 24 0 R
+/ToUnicode 23 0 R
+>>
+endobj
+11 0 obj
+<< /Type /Outlines
+/Count 1
+/First 12 0 R
+/Last 12 0 R
+>>
+endobj
+12 0 obj
+<< /Title <feff0055006e007400690074006c00650064>
+/Parent 11 0 R
+/Count 0
+/Dest [7 0 R /XYZ 0 792 null]
+>>
+endobj
+13 0 obj
+<< /Nums [0 << /P (1)
+>>]
+>>
+endobj
+14 0 obj
+[7 0 R /XYZ 0 792 null]
+endobj
+15 0 obj
+<< /Type /Names
+/Dests 16 0 R
+>>
+endobj
+16 0 obj
+<< /Names [(__anchor-top) 14 0 R]
+>>
+endobj
+17 0 obj
+<< /Length1 10876
+/Length 6670
+/Filter [/FlateDecode]
+>>
+stream
+xz pי{ݍo'H&x A 
+ I@(q|:(ϵzSl$dR1ddd6<ryb-")yfvkk;Z4t34;y.^
+Z9؛3'b80˨gh0H3.>$
+9FFBmpAw JzMs9ُ1xz1OD: HEϜBrE$DM܋TWNk¾&P9o )N,)@:ދ%(gdflYNn^~Ae][_oOb4u47ol0uZMMEyT(Q)eicjBy\۫!wAԽ['{[s{4M1MӶ&[Q
+|'F\@n>!P+L*0* >=5}|a걀}fKԠ}@*\!6qE;Samd4 fVlxxeU*/&Xh2Sa9,&E=o| 4Nf0녾ucpfuR+O.<k5\MFDZE ;‡7wKqX "d7wc[7<ޫѳ!llla4^W<)ws3< 9l-=rf$!U5#bRǟjBώb<o f<i9h 1FS
+Vi#$BF8\%ldeM:7U"AXP)Fen^a,I
+lCC9Ξaoi<'[49lcqqq!dgޞdeeK{pA582q#Ð K7ҙY?:n!Fgs_OmǪmW%Q؇%z<M#aa8QW-\7
+{ݶ,&B"x3u`^8x8X}jLHA}CkZ[
+(#x`ЂGL,/}ڡWA(X2 !t)G2t(B"OOۇ!'J;ZCSz ~C?+1 gl]us4mzsB~z#-:zȭHi y:Z.ci9~;ށ9EZb5XJ @8c{4:5.y('z ƥ8&SrC%E>EGie12F*s?9%b:"[dL%-jXtZ"ʐf~ ۸Ŕ1_dN9{(MT/zMt[U|[,ϥR)񏁌 9<k!SVe-ћOsÚÚZHX :ϗM喔h8;O.ɝdL#+TiH^0:?jog)h32A'/ 99Pd+|Zo(o aN|0#*P3L56xS>%-Ccȝ 6m\VR;d2润~4~bDwb'&N*Kǟz ,iJ3#?LV6ٛFEs3/߳::||l7 kћ+ 0 ?P!8>xY/>?o;
+Cߘ~t 3sKWVz[^2e)[=oN;J)G~s,
+Bv v)TABmP%mZ9*My;}2LR4j>إz6қCb1 Q*:Fc&p&ڂsTGM‰c͢, 8DD)/$_ïLONT 5mϖK"F 4~ @HFWH]kYv=w)TW?}v@x_8|aJk>w´a?rTN'O|Y}t|}fu{Qkp]iLeӪڜƶC6szwzF:7v*)FbY. ^VI6Dx˅4VyA'5#v_OkiLs}Lҥ)j!3ރ&˚C?~+†+=+t^sB$sI:o1rǦ>_ WET!:eK ٓL8C;KW khM-\44xԌ4y{HceI.<:b9VTeʿsB}W4\?-*A7`,6? 2.?J)7&AM qL}j
+=d¤`WZZ" ƝH<6%GE慁 o=&'euSڇW̊M:UY_^RUrM{[ِwn6/.NWhJӝ-D"2=:t:X3ilMFk#Yc4yycTI2S +9U2A=P*+gd<;|OTLr*xƪ+{{j+ZJE[W.KAÏG:dgg283%?'5%z5Дc'+
+"ȱ.ׅϷN*U 6wUVLj>7]/;?5\Y\Yfp?:ؠkҫX'^Ɨj؏~#&ܽH4Z2K_]'lR_ k FgP(Xڋ
+,Fb j)[dXXDdf
+,;W*ev*Ϣ`Ivy)wLzEJB_
+T&߂sQ,};:~u[lQR_RVW;[ZzKI36Fr
+Kj쟜N!Sȋ.
+s; mQty} v?b<hJQdb4$h#S@P4(Wtwt2Ңl]q:pC*dH0G}y1Nc$ciqEͬ"NsHƺKqZ,l¦UPqNF\aއڹq:rߍө׸t<jWB|||ʌ\ZGIS}}AϏVF}kKh=
+4t<v/}!(u;ݩB06/
+Vb1nDj.Ck s+:j>{Ώwvc(o;ݼoR*;X_\,-P|< |3s3we~;^|ˋAoe_^ yCtV5i j"@( ..idF~@h-]@!ģ:h| C+h*htWr>xqx΂ ͣ1*_DsTkA/H@
+ZQetW÷;_;9)X -ҰCw"M/VQyo#|M Ae }- Q, F(Dƣi.ˡe-Itaסz~]]ܲ^3] Aw;DhHdC`Dڷ%x
+lz<<qP;MNQx߇HxC }uӹ6A !}*UʝȬJRԏe'U\yWN uDyl/(3@.X&2o6e wI}Wg:(8l ;w>1l\Zm yh'H}.=LFeЋ4k7 ~
+endstream
+endobj
+18 0 obj
+<< /Type /FontDescriptor
+/FontName /3e50aa+NotoSerif
+/FontFile2 17 0 R
+/FontBBox [-212 -250 1246 1047]
+/Flags 6
+/StemV 0
+/ItalicAngle 0
+/Ascent 1068
+/Descent -292
+/CapHeight 1462
+/XHeight 1098
+>>
+endobj
+19 0 obj
+<< /Length 1278
+/Filter [/FlateDecode]
+>>
+stream
+xenFὮBtHs&@nu{stԒ + }ik/y_!}t~]snVyg쾝+|<.÷}v)[eO/_q9_ɯ}ഏOmt_LLv͵LJ1w9)e6=n?[i(JKiU:JSz2QeL*EJ̔Ye,*+eU(NU-уk5x5F^ky ^#k5x5F^ky ^#kxZV^kZy-^+kxZV^kZy-^+uxu:N^:y^'uxu:N^:y^'xz^^zy=^/xz^^zy=^/o xo7 Aހ7y o xo7 Aހ7y oxo7jo$JI$$*I$ITH$$QI"IDD%$JI$$*I$ITD$$III$$u>M&Iބ7ɛ&y$o›Mx o7M&Iބ7ɛ&yUoa[5joSor4ۂs
+JJ특xxx+!ÊwBxbx+ށr;2kΜJYeY7+|x oS7+[ƛețךyޢoV浖 -㭌"RW*4XqC^J[(^1»y]k}YM-x e#e_y+h܊7k:/Z5dUluz5n[eB&Si|y(%q& %+S%*ABijPU6\h,(+L,4G5<cD [˧*t [ jjaijIxʪwgFwضR>sh>:OVRP*#i|e0U,*oU/*[U,Nmlx:&\}M)L2\%CHF7էʻBL)jƻJ1:%H߯:=S۳zrmkO媳7
+endstream
+endobj
+20 0 obj
+[259 500 500 500 500 500 500 500 500 500 500 500 250 500 250 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 653 613 500 500 500 500 500 500 500 500 623 937 500 500 500 500 500 543 500 500 500 500 500 500 500 500 500 500 500 500 500 562 613 492 613 535 369 538 634 319 299 500 310 944 645 577 613 613 471 451 352 634 579 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500]
+endobj
+21 0 obj
+<< /Length1 8436
+/Length 5106
+/Filter [/FlateDecode]
+>>
+stream
+x8 tוml<@` ȶd[6'ɑ k$[%%aɀIDДlIH6cݒiö춛!Ba)I,}Oc lvٱ{YDpM8
+H\C>}Ԕ:F%VM"*J.yBpIuydlt:9{o4'995%*QMD6£9ê"DhԚPUY7R+RJK`,%TERx,ZK8 ,Fb[\VKYZbgI\\$ 0a?+y5v`\4lrɢDk,O(Ky=bԦzn$P/ǀH/LxP10I.y{%bcii# .5xy\wSֻdl]{vK
+߃_'W3:'yZo  hd7C7"6WНw̦NYpW'Wlen dwdU+Y1=n-,^u-(23JS'hÂnJa[bz̺.桂LRB1LU\@KKd.lAQrd[b7(`MRX6H5̲.E&je|i)d4SkmIdImSP8?VA^(
+0ٵXWE֘+iԕg͝NdZ|FYuRSF
+Ő*$Fr%`ɺBu yb'2@j(k ux1Jf u<F3(| &TʩaR(!iL^%.SE1б6L.$@b82<uI>SSb(+1Wr嘆M  <`uyS+s:pӲmrtR=ƄK@@m26Y`cG~ͬmc5 a249jJKaV3&F)=|pNDut-5)
+NB$#y
+q"(%JJWq1Xk~axbOBe2YXPY|YAmMcw3׌V~iImXMƪe˫WITPL'GǕ~TZiϤ[p'F:Yp&ڊYWYQLT?l*$hEEc^ۑ/Gft[UDP#OMڇj_먩1M 2
+f>8!{'v>ۂV*hL*2;>L=ThP< 8$^`Jx!+qA B!JRe9UL:
+`*U….O6qoć6z胦/{~|}%6VLG;kyZ1^Nj+26\|Xړ/l$'zƃg?x̢N+aqǛns WP:LdzܯH^kuPI_+ۚ[8m>arbRPÜ$X;X,)0_,=ǧ+5+<ٯ03B1TB5j T-25ҌUEP>ې`6A7rѝo~H?WpmA/ 9ďm!pHu<ju]yJvG%#:תMC87f-ػ,o# B&{׻yz^^IvEj& Ϸv>o}WYv:'\ݲ?1<ʲtl-i`u1qASmu
+%P`Q Xq@ܩj+,!^SHE868֪R4XPg
+RWYP}6 tْh}(`Ol)B}v9 Qo0kz=BPt8;<}`-7Xh `$
+ҥeKzTyzg)'x}4;ռ/hF" u<OC`W>/יI(2*iǎe}\YYOh狚9d<l y ~4.R{73c>;`uAݶ}$$C e¼Ht0=PiAnлlU^Yֶ4[l[K3bu6ٚ-%@sogx ,TvPғH ~OoӇ^}s'v`k844HP5W' H,4gj[]/A2XKqP!1PP5Rqn+1>G/r6(>R<;6Z IڇA)--ir#3+C/ p<xGӃ-Gr/ni1cQdV9^ Qnˈ*hQd4QErVyV3;_r m ! q!n{&7$D6;7,u?"E),ҾyHf͇\!<?cdµI^?MB RnUKyT'yU֍VE2=|,Pq1;B hgWc، |o R(g R-|ɵ:ޅЉs0&ۇV%3ȱA^ n c
+endstream
+endobj
+22 0 obj
+<< /Type /FontDescriptor
+/FontName /c2c7af+NotoSerif-Italic
+/FontFile2 21 0 R
+/FontBBox [-254 -250 1238 1047]
+/Flags 70
+/StemV 0
+/ItalicAngle -12
+/Ascent 1068
+/Descent -292
+/CapHeight 1462
+/XHeight 1098
+>>
+endobj
+23 0 obj
+<< /Length 1278
+/Filter [/FlateDecode]
+>>
+stream
+xenFὮBtHs&@nu{stԒ + }ik/y_!}t~]snVyg쾝+|<.÷}v)[eO/_q9_ɯ}ഏOmt_LLv͵LJ1w9)e6=n?[i(JKiU:JSz2QeL*EJ̔Ye,*+eU(NU-уk5x5F^ky ^#k5x5F^ky ^#kxZV^kZy-^+kxZV^kZy-^+uxu:N^:y^'uxu:N^:y^'xz^^zy=^/xz^^zy=^/o xo7 Aހ7y o xo7 Aހ7y oxo7jo$JI$$*I$ITH$$QI"IDD%$JI$$*I$ITD$$III$$u>M&Iބ7ɛ&y$o›Mx o7M&Iބ7ɛ&yUoa[5joSor4ۂs
+JJ특xxx+!ÊwBxbx+ށr;2kΜJYeY7+|x oS7+[ƛețךyޢoV浖 -㭌"RW*4XqC^J[(^1»y]k}YM-x e#e_y+h܊7k:/Z5dUluz5n[eB&Si|y(%q& %+S%*ABijPU6\h,(+L,4G5<cD [˧*t [ jjaijIxʪwgFwضR>sh>:OVRP*#i|e0U,*oU/*[U,Nmlx:&\}M)L2\%CHF7էʻBL)jƻJ1:%H߯:=S۳zrmkO媳7
+endstream
+endobj
+24 0 obj
+[259 600 600 600 600 600 600 600 600 600 600 600 600 600 250 600 600 559 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 589 600 600 367 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 579 600 486 579 493 600 556 600 304 600 600 600 895 599 574 577 600 467 463 368 599 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600]
+endobj
+xref
+0 25
+0000000000 65535 f
+0000000015 00000 n
+0000000254 00000 n
+0000000453 00000 n
+0000000510 00000 n
+0000000561 00000 n
+0000000803 00000 n
+0000011156 00000 n
+0000011480 00000 n
+0000011644 00000 n
+0000012128 00000 n
+0000012300 00000 n
+0000012374 00000 n
+0000012496 00000 n
+0000012541 00000 n
+0000012581 00000 n
+0000012630 00000 n
+0000012683 00000 n
+0000019444 00000 n
+0000019656 00000 n
+0000021010 00000 n
+0000021924 00000 n
+0000027120 00000 n
+0000027342 00000 n
+0000028696 00000 n
+trailer
+<< /Size 25
+/Root 2 0 R
+/Info 1 0 R
+>>
+startxref
+29610
+%%EOF