openxml-docx 0.10.0 → 0.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +2 -2
  3. data/examples/drawing-ml +1 -1
  4. data/examples/image-embedding +141 -0
  5. data/examples/ochanomizu.jpg +0 -0
  6. data/lib/openxml/docx.rb +8 -0
  7. data/lib/openxml/docx/attribute_builder.rb +11 -1
  8. data/lib/openxml/docx/elements/book_fold_printing.rb +12 -0
  9. data/lib/openxml/docx/elements/book_fold_printing_sheets.rb +12 -0
  10. data/lib/openxml/docx/elements/book_fold_reverse_printing.rb +12 -0
  11. data/lib/openxml/docx/elements/drawing.rb +1 -1
  12. data/lib/openxml/docx/elements/embed_system_fonts.rb +14 -0
  13. data/lib/openxml/docx/elements/embed_true_type_fonts.rb +14 -0
  14. data/lib/openxml/docx/elements/font_alternate_name.rb +15 -0
  15. data/lib/openxml/docx/elements/font_character_set.rb +15 -0
  16. data/lib/openxml/docx/elements/font_panose_one.rb +15 -0
  17. data/lib/openxml/docx/elements/font_pitch.rb +15 -0
  18. data/lib/openxml/docx/elements/font_sig.rb +20 -0
  19. data/lib/openxml/docx/elements/save_subset_fonts.rb +14 -0
  20. data/lib/openxml/docx/elements/word_processing_drawing_anchor.rb +13 -11
  21. data/lib/openxml/docx/elements/word_processing_drawing_object_nv_properties.rb +1 -1
  22. data/lib/openxml/docx/elements/word_processing_drawing_position_h.rb +1 -11
  23. data/lib/openxml/docx/elements/word_processing_drawing_position_offset.rb +18 -1
  24. data/lib/openxml/docx/elements/word_processing_drawing_position_v.rb +1 -11
  25. data/lib/openxml/docx/elements/word_processing_drawing_wrap_coordinate.rb +26 -0
  26. data/lib/openxml/docx/elements/word_processing_drawing_wrap_polygon.rb +13 -0
  27. data/lib/openxml/docx/elements/word_processing_drawing_wrap_square.rb +17 -0
  28. data/lib/openxml/docx/elements/word_processing_drawing_wrap_through.rb +15 -0
  29. data/lib/openxml/docx/elements/word_processing_drawing_wrap_tight.rb +15 -0
  30. data/lib/openxml/docx/elements/word_processing_drawing_wrap_top_and_bottom.rb +14 -0
  31. data/lib/openxml/docx/elements/word_processing_groups_group_shape_properties.rb +13 -0
  32. data/lib/openxml/docx/elements/word_processing_groups_nv_shape_drawing_properties.rb +11 -0
  33. data/lib/openxml/docx/elements/word_processing_shapes_nv_drawing_properties.rb +17 -0
  34. data/lib/openxml/docx/package.rb +39 -13
  35. data/lib/openxml/docx/parts/document.rb +3 -2
  36. data/lib/openxml/docx/parts/fonts.rb +2 -1
  37. data/lib/openxml/docx/parts/footer.rb +2 -1
  38. data/lib/openxml/docx/parts/header.rb +2 -1
  39. data/lib/openxml/docx/parts/settings.rb +5 -0
  40. data/lib/openxml/docx/properties/tabs.rb +2 -0
  41. data/lib/openxml/docx/root_namespaces.rb +1 -1
  42. data/lib/openxml/docx/version.rb +1 -1
  43. data/lib/openxml/drawingml/elements/blip.rb +18 -0
  44. data/lib/openxml/drawingml/elements/blip_fill.rb +1 -1
  45. data/lib/openxml/drawingml/elements/fill_rectangle.rb +16 -0
  46. data/lib/openxml/drawingml/elements/graphic_frame_locks.rb +6 -6
  47. data/lib/openxml/drawingml/elements/non_visual_drawing_properties.rb +1 -1
  48. data/lib/openxml/drawingml/elements/picture_locks.rb +23 -0
  49. data/lib/openxml/drawingml/elements/picture_shape_properties.rb +13 -0
  50. data/lib/openxml/drawingml/elements/source_rectangle.rb +16 -0
  51. data/lib/openxml/drawingml/elements/stretch.rb +10 -0
  52. data/spec/elements/book_fold_printing_sheets_spec.rb +27 -0
  53. data/spec/elements/book_fold_printing_spec.rb +19 -0
  54. data/spec/elements/book_fold_reverse_printing_spec.rb +19 -0
  55. data/spec/elements/drawingml/blip_fill_spec.rb +8 -3
  56. data/spec/elements/drawingml/blip_spec.rb +47 -0
  57. data/spec/elements/drawingml/fill_rectangle_spec.rb +76 -0
  58. data/spec/elements/drawingml/graphic_frame_locks_spec.rb +47 -18
  59. data/spec/elements/drawingml/non_visual_drawing_properties_spec.rb +8 -3
  60. data/spec/elements/drawingml/non_visual_picture_drawing_properties_spec.rb +7 -2
  61. data/spec/elements/drawingml/picture_locks_spec.rb +122 -0
  62. data/spec/elements/drawingml/picture_shape_properties_spec.rb +21 -0
  63. data/spec/elements/drawingml/source_rectangle_spec.rb +76 -0
  64. data/spec/elements/drawingml/stretch_spec.rb +8 -0
  65. data/spec/elements/embed_system_fonts_spec.rb +19 -0
  66. data/spec/elements/embed_true_type_fonts_spec.rb +19 -0
  67. data/spec/elements/font_alternate_name_spec.rb +19 -0
  68. data/spec/elements/font_character_set_spec.rb +19 -0
  69. data/spec/elements/font_panose_one_spec.rb +19 -0
  70. data/spec/elements/font_pitch_spec.rb +21 -0
  71. data/spec/elements/font_sig_spec.rb +74 -0
  72. data/spec/elements/save_subset_fonts_spec.rb +19 -0
  73. data/spec/elements/word_processing_drawing_anchor_spec.rb +107 -25
  74. data/spec/elements/word_processing_drawing_object_nv_properties_spec.rb +1 -1
  75. data/spec/elements/word_processing_drawing_position_h_spec.rb +6 -5
  76. data/spec/elements/word_processing_drawing_position_v_spec.rb +6 -5
  77. data/spec/elements/word_processing_drawing_wrap_coordinate_spec.rb +40 -0
  78. data/spec/elements/word_processing_drawing_wrap_polygon_spec.rb +23 -0
  79. data/spec/elements/word_processing_drawing_wrap_square_spec.rb +65 -0
  80. data/spec/elements/word_processing_drawing_wrap_through_spec.rb +43 -0
  81. data/spec/elements/word_processing_drawing_wrap_tight_spec.rb +43 -0
  82. data/spec/elements/word_processing_drawing_wrap_top_and_bottom_spec.rb +30 -0
  83. data/spec/elements/word_processing_groups_group_shape_properties_spec.rb +21 -0
  84. data/spec/elements/word_processing_groups_nv_shape_drawing_properties_spec.rb +8 -0
  85. data/spec/elements/word_processing_shapes_nv_drawing_properties_spec.rb +64 -0
  86. data/spec/package_spec.rb +2 -2
  87. data/spec/parts/settings_spec.rb +6 -0
  88. data/spec/properties/table_border_spec.rb +2 -2
  89. data/spec/properties/table_cell_border_spec.rb +2 -2
  90. data/spec/style_spec.rb +2 -2
  91. data/spec/support/data/parts/document_with_children_part.xml +1 -1
  92. data/spec/support/data/parts/document_with_multiple_sections_part.xml +1 -1
  93. data/spec/support/data/parts/document_with_one_section_part.xml +1 -1
  94. data/spec/support/data/parts/empty_document_part.xml +1 -1
  95. data/spec/support/data/parts/settings_part.xml +1 -1
  96. data/spec/support/property_test_macros.rb +1 -1
  97. metadata +56 -2
@@ -8,7 +8,7 @@ module OpenXml
8
8
  attribute :description, expects: :string, displays_as: :descr
9
9
  attribute :hidden, expects: :true_or_false
10
10
  attribute :id, expects: :positive_integer
11
- attribute :property_name, expects: :string, displays_as: :name
11
+ attribute :object_name, expects: :string, displays_as: :name
12
12
  attribute :title, expects: :string
13
13
 
14
14
  end
@@ -5,18 +5,8 @@ module OpenXml
5
5
  tag :positionH
6
6
  namespace :wp
7
7
 
8
- attribute :relativeFrom, expects: :valid_relative_from
8
+ attribute :relative_from, one_of: %i(character column insideMargin leftMargin margin outsideMargin page rightMargin), displays_as: :relativeFrom
9
9
 
10
- private
11
-
12
- def valid_relative_from(value)
13
- raise ArgumentError unless ok_values.include? value
14
- end
15
-
16
- def ok_values
17
- %i(character column insideMargin leftMargin margin outsideMargin
18
- page rightMargin)
19
- end
20
10
  end
21
11
  end
22
12
  end
@@ -1,9 +1,26 @@
1
1
  module OpenXml
2
2
  module Docx
3
3
  module Elements
4
- class WordProcessingDrawingPositionOffset < Container
4
+ class WordProcessingDrawingPositionOffset < Element
5
5
  tag :posOffset
6
6
  namespace :wp
7
+
8
+ def <<(text)
9
+ value << text if text.is_a? String
10
+ end
11
+
12
+ def value
13
+ @value ||= ""
14
+ end
15
+
16
+ def value=(new_value)
17
+ @value = new_value if new_value.is_a? String
18
+ end
19
+
20
+ def to_xml(xml)
21
+ xml[namespace.to_s].public_send(tag, value, xml_attributes)
22
+ end
23
+
7
24
  end
8
25
  end
9
26
  end
@@ -5,18 +5,8 @@ module OpenXml
5
5
  tag :positionV
6
6
  namespace :wp
7
7
 
8
- attribute :relativeFrom, expects: :valid_relative_from
8
+ attribute :relative_from, one_of: %i(bottomMargin insideMargin line margin outsideMargin page paragraph topMargin), displays_as: :relativeFrom
9
9
 
10
- private
11
-
12
- def valid_relative_from(value)
13
- raise ArgumentError unless ok_values.include? value
14
- end
15
-
16
- def ok_values
17
- %i(bottomMargin insideMargin line margin outsideMargin page
18
- paragraph topMargin)
19
- end
20
10
  end
21
11
  end
22
12
  end
@@ -0,0 +1,26 @@
1
+ module OpenXml
2
+ module Docx
3
+ module Elements
4
+ class WordProcessingDrawingWrapCoordinate < Element
5
+ namespace :wp
6
+
7
+ attr_reader :tag
8
+
9
+ attribute :x, expects: :integer
10
+ attribute :y, expects: :integer
11
+
12
+ def initialize(tag)
13
+ raise ArgumentError, "Tag must be one of #{ok_tags.join(", ")}" unless ok_tags.include? tag
14
+ @tag = tag
15
+ end
16
+
17
+ private
18
+
19
+ def ok_tags
20
+ %i(start lineTo)
21
+ end
22
+
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,13 @@
1
+ module OpenXml
2
+ module Docx
3
+ module Elements
4
+ class WordProcessingDrawingWrapPolygon < Container
5
+ tag :wrapPolygon
6
+ namespace :wp
7
+
8
+ attribute :edited, expects: :true_or_false
9
+
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,17 @@
1
+ module OpenXml
2
+ module Docx
3
+ module Elements
4
+ class WordProcessingDrawingWrapSquare < Element
5
+ tag :wrapSquare
6
+ namespace :wp
7
+
8
+ attribute :distance_from_bottom, expects: :positive_integer, displays_as: :distB
9
+ attribute :distance_from_left, expects: :positive_integer, displays_as: :distL
10
+ attribute :distance_from_right, expects: :positive_integer, displays_as: :distR
11
+ attribute :distance_from_top, expects: :positive_integer, displays_as: :distT
12
+ attribute :wrap_text, one_of: %i(bothSides largest left right), displays_as: :wrapText
13
+
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,15 @@
1
+ module OpenXml
2
+ module Docx
3
+ module Elements
4
+ class WordProcessingDrawingWrapThrough < Container
5
+ tag :wrapThrough
6
+ namespace :wp
7
+
8
+ attribute :distance_from_left, expects: :positive_integer, displays_as: :distL
9
+ attribute :distance_from_right, expects: :positive_integer, displays_as: :distR
10
+ attribute :wrap_text, one_of: %i(bothSides largest left right), displays_as: :wrapText
11
+
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ module OpenXml
2
+ module Docx
3
+ module Elements
4
+ class WordProcessingDrawingWrapTight < Container
5
+ tag :wrapTight
6
+ namespace :wp
7
+
8
+ attribute :distance_from_left, expects: :positive_integer, displays_as: :distL
9
+ attribute :distance_from_right, expects: :positive_integer, displays_as: :distR
10
+ attribute :wrap_text, one_of: %i(bothSides largest left right), displays_as: :wrapText
11
+
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,14 @@
1
+ module OpenXml
2
+ module Docx
3
+ module Elements
4
+ class WordProcessingDrawingWrapTopAndBottom < Element
5
+ tag :wrapTopAndBottom
6
+ namespace :wp
7
+
8
+ attribute :distance_from_bottom, expects: :positive_integer, displays_as: :distB
9
+ attribute :distance_from_top, expects: :positive_integer, displays_as: :distT
10
+
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,13 @@
1
+ module OpenXml
2
+ module Docx
3
+ module Elements
4
+ class WordProcessingGroupsGroupShapeProperties < Container
5
+ tag :grpSpPr
6
+ namespace :wpg
7
+
8
+ attribute :bw_mode, one_of: %i(auto black blackGray blackWhite clr gray grayWhite hidden invGray ltGray white), displays_as: :bwMode
9
+
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,11 @@
1
+ module OpenXml
2
+ module Docx
3
+ module Elements
4
+ class WordProcessingGroupsNvShapeDrawingProperties < Container
5
+ tag :cNvGrpSpPr
6
+ namespace :wpg
7
+
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,17 @@
1
+ module OpenXml
2
+ module Docx
3
+ module Elements
4
+ class WordProcessingShapesNvDrawingProperties < Container
5
+ tag :cNvPr
6
+ namespace :wps
7
+
8
+ attribute :description, expects: :string, displays_as: :descr
9
+ attribute :hidden, expects: :true_or_false
10
+ attribute :id, expects: :positive_integer
11
+ attribute :object_name, expects: :string, displays_as: :name
12
+ attribute :title, expects: :string
13
+
14
+ end
15
+ end
16
+ end
17
+ end
@@ -4,17 +4,21 @@ module OpenXml
4
4
  module Docx
5
5
  class Package < OpenXml::Package
6
6
  attr_reader :document,
7
- :doc_rels,
8
- :font_rels,
9
7
  :settings,
10
8
  :headers,
11
9
  :footers,
12
10
  :styles,
13
- :fonts
11
+ :fonts,
12
+ :image_names
14
13
 
15
14
  content_types do
16
15
  default "xml", TYPE_XML
17
16
  default "odttf", TYPE_OBSCURED_FONT
17
+ default "jpeg", TYPE_IMAGE[:jpeg]
18
+ default "png", TYPE_IMAGE[:png]
19
+ default "gif", TYPE_IMAGE[:gif]
20
+ default "bmp", TYPE_IMAGE[:bmp]
21
+ default "tiff", TYPE_IMAGE[:tiff]
18
22
  override "/word/styles.xml", TYPE_STYLES
19
23
  override "/word/settings.xml", TYPE_SETTINGS
20
24
  override "/word/fontTable.xml", TYPE_FONT_TABLE
@@ -24,21 +28,20 @@ module OpenXml
24
28
  super
25
29
 
26
30
  rels.add_relationship REL_DOCUMENT, "/word/document.xml"
27
- @doc_rels = OpenXml::Parts::Rels.new
28
- @font_rels = OpenXml::Parts::Rels.new
29
31
  @settings = OpenXml::Docx::Parts::Settings.new
30
32
  @styles = OpenXml::Docx::Parts::Styles.new
31
33
  @fonts = OpenXml::Docx::Parts::Fonts.new
32
34
  @document = OpenXml::Docx::Parts::Document.new
33
35
  @headers = []
34
36
  @footers = []
37
+ @image_names = []
35
38
 
36
- doc_rels.add_relationship REL_STYLES, "styles.xml"
37
- doc_rels.add_relationship REL_SETTINGS, "settings.xml"
38
- doc_rels.add_relationship REL_FONT_TABLE, "fontTable.xml"
39
+ document.relationships.add_relationship REL_STYLES, "styles.xml"
40
+ document.relationships.add_relationship REL_SETTINGS, "settings.xml"
41
+ document.relationships.add_relationship REL_FONT_TABLE, "fontTable.xml"
39
42
 
40
- add_part "word/_rels/document.xml.rels", doc_rels
41
- add_part "word/_rels/fontTable.xml.rels", font_rels
43
+ add_part "word/_rels/document.xml.rels", document.relationships
44
+ add_part "word/_rels/fontTable.xml.rels", fonts.relationships
42
45
  add_part "word/document.xml", document
43
46
  add_part "word/settings.xml", settings
44
47
  add_part "word/styles.xml", styles
@@ -51,7 +54,7 @@ module OpenXml
51
54
  data = obfuscation_data[:bytes] << source_font.read
52
55
  destination_font_name = "font#{fonts.fonts.count + 1}.odttf"
53
56
  add_part "word/fonts/#{destination_font_name}", OpenXml::Parts::UnparsedPart.new(data)
54
- font_relationship = font_rels.add_relationship REL_FONT, "fonts/#{destination_font_name}"
57
+ font_relationship = fonts.relationships.add_relationship REL_FONT, "fonts/#{destination_font_name}"
55
58
 
56
59
  font_description = OpenXml::Docx::Elements::Font.new
57
60
  font_description.font_name = name
@@ -63,12 +66,34 @@ module OpenXml
63
66
  end
64
67
  end
65
68
 
69
+ def embed_image(path: nil, content_type: nil, into_part: nil)
70
+ return if path.nil?
71
+ into_part = document unless into_part.respond_to?(:relationships)
72
+
73
+ extension_match = path.match(/\.(?<extension>[^\.]+)$/)
74
+ content_type ||= extension_match[:extension] if extension_match
75
+ return if content_type.nil?
76
+
77
+ content_type = "jpeg" if content_type == "jpg"
78
+ content_type = content_type.to_sym
79
+
80
+ File.open(path, "rb") do |source_image|
81
+ destination_image_name = "image#{image_names.count + 1}.#{content_type}"
82
+ add_part "word/media/#{destination_image_name}", OpenXml::Parts::UnparsedPart.new(source_image.read)
83
+ image_names << destination_image_name
84
+
85
+ image_relationship = into_part.relationships.add_relationship REL_IMAGE, "media/#{destination_image_name}"
86
+ image_relationship.id
87
+ end
88
+ end
89
+
66
90
  def add_header(header)
67
91
  headers << header
68
92
  header_name = "header#{headers.count}.xml"
69
93
  Package.content_types { override "/word/#{header_name}", TYPE_HEADER }
70
94
  add_part "word/#{header_name}", header
71
- relationship = doc_rels.add_relationship REL_HEADER, header_name
95
+ add_part "word/_rels/#{header_name}.rels", header.relationships
96
+ relationship = document.relationships.add_relationship REL_HEADER, header_name
72
97
  relationship.id
73
98
  end
74
99
 
@@ -77,7 +102,8 @@ module OpenXml
77
102
  footer_name = "footer#{footers.count}.xml"
78
103
  Package.content_types { override "/word/#{footer_name}", TYPE_FOOTER }
79
104
  add_part "word/#{footer_name}", footer
80
- relationship = doc_rels.add_relationship REL_FOOTER, footer_name
105
+ add_part "word/_rels/#{footer_name}.rels", footer.relationships
106
+ relationship = document.relationships.add_relationship REL_FOOTER, footer_name
81
107
  relationship.id
82
108
  end
83
109
 
@@ -4,13 +4,14 @@ module OpenXml
4
4
  class Document < OpenXml::Part
5
5
  include RootNamespaces
6
6
 
7
- attr_reader :children, :current_section
7
+ attr_reader :children, :current_section, :relationships
8
8
 
9
- use_namespaces :wpc, :mo, :mv, :o, :r, :m, :v, :wp14, :wp, :w10, :w14, :wpg, :wpi, :wne, :wps, :w, :mc, :a14, :pic
9
+ use_namespaces :wpc, :mo, :mv, :o, :r, :m, :v, :wp14, :wp, :w10, :w14, :wpg, :wpi, :wne, :wps, :w, :mc, :a, :a14, :pic
10
10
  can_ignore :w14, :wp14, :a14
11
11
 
12
12
  def initialize
13
13
  @children = []
14
+ @relationships = OpenXml::Parts::Rels.new
14
15
  end
15
16
 
16
17
  def <<(child)
@@ -4,12 +4,13 @@ module OpenXml
4
4
  class Fonts < OpenXml::Part
5
5
  include RootNamespaces
6
6
 
7
- attr_reader :fonts
7
+ attr_reader :fonts, :relationships
8
8
 
9
9
  use_namespaces :r, :w
10
10
 
11
11
  def initialize
12
12
  @fonts = []
13
+ @relationships = OpenXml::Parts::Rels.new
13
14
  end
14
15
 
15
16
  def <<(font)
@@ -7,10 +7,11 @@ module OpenXml
7
7
  use_namespaces :wpc, :mo, :mv, :o, :r, :m, :v, :wp14, :wp, :w10, :w14, :w15, :wpg, :wpi, :wne, :wps, :w, :mc, :a, :a14
8
8
  can_ignore :w14, :w15, :wp14, :a14
9
9
 
10
- attr_reader :children
10
+ attr_reader :children, :relationships
11
11
 
12
12
  def initialize
13
13
  @children = []
14
+ @relationships = OpenXml::Parts::Rels.new
14
15
  end
15
16
 
16
17
  def <<(child)
@@ -7,10 +7,11 @@ module OpenXml
7
7
  use_namespaces :wpc, :mo, :mv, :o, :r, :m, :v, :wp14, :wp, :w10, :w14, :w15, :wpg, :wpi, :wne, :wps, :w, :mc, :a, :a14
8
8
  can_ignore :w14, :w15, :wp14, :a14
9
9
 
10
- attr_reader :children
10
+ attr_reader :children, :relationships
11
11
 
12
12
  def initialize
13
13
  @children = []
14
+ @relationships = OpenXml::Parts::Rels.new
14
15
  end
15
16
 
16
17
  def <<(child)
@@ -12,10 +12,15 @@ module OpenXml
12
12
  @settings = []
13
13
  end
14
14
 
15
+ def <<(child)
16
+ settings << child
17
+ end
18
+
15
19
  def to_xml
16
20
  build_standalone_xml do |xml|
17
21
  xml.settings(root_namespaces) {
18
22
  xml.parent.namespace = :w
23
+ settings.each { |setting| setting.to_xml(xml) }
19
24
  }
20
25
  end
21
26
  end
@@ -1,3 +1,5 @@
1
+ require "openxml/docx/properties/tab"
2
+
1
3
  module OpenXml
2
4
  module Docx
3
5
  module Properties
@@ -23,7 +23,7 @@ module OpenXml
23
23
  mc: "http://schemas.openxmlformats.org/markup-compatibility/2006".freeze,
24
24
  a: "http://schemas.openxmlformats.org/drawingml/2006/main".freeze,
25
25
  a14: "http://schemas.microsoft.com/office/drawing/2010/main".freeze,
26
- pic: "http://purl.oclc.org/ooxml/drawingml/main".freeze
26
+ pic: "http://schemas.openxmlformats.org/drawingml/2006/picture".freeze
27
27
  }
28
28
 
29
29
  def self.included(base)
@@ -1,5 +1,5 @@
1
1
  module OpenXml
2
2
  module Docx
3
- VERSION = "0.10.0"
3
+ VERSION = "0.10.1"
4
4
  end
5
5
  end