microstation 0.8.5 → 0.8.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +26 -29
  3. data/Rakefile +45 -44
  4. data/bin/dgn2pdf +5 -6
  5. data/bin/dgn_template +23 -25
  6. data/bin/pw_print +11 -13
  7. data/cad_files/drawing_no_block.dgn +0 -0
  8. data/cad_files/drawing_with_3_block.dgn +0 -0
  9. data/cad_files/drawing_with_block.dgn +0 -0
  10. data/cad_files/drawing_with_text.dgn +0 -0
  11. data/lib/microstation/app.rb +91 -87
  12. data/lib/microstation/cad_input_queue.rb +10 -20
  13. data/lib/microstation/cell.rb +6 -18
  14. data/lib/microstation/changer.rb +3 -3
  15. data/lib/microstation/configuration.rb +33 -50
  16. data/lib/microstation/criteria_creation_t.rb +4 -8
  17. data/lib/microstation/dir.rb +27 -59
  18. data/lib/microstation/directory.rb +2 -7
  19. data/lib/microstation/drawing.rb +103 -102
  20. data/lib/microstation/element.rb +55 -68
  21. data/lib/microstation/enumerator.rb +4 -9
  22. data/lib/microstation/errors.rb +0 -5
  23. data/lib/microstation/event_handler.rb +1 -5
  24. data/lib/microstation/ext/pathname.rb +12 -14
  25. data/lib/microstation/ext/win32ole.rb +0 -2
  26. data/lib/microstation/extensions/faa.rb +12 -34
  27. data/lib/microstation/file_tests.rb +15 -50
  28. data/lib/microstation/functions.rb +10 -20
  29. data/lib/microstation/graphics.rb +6 -13
  30. data/lib/microstation/line.rb +2 -6
  31. data/lib/microstation/model.rb +11 -20
  32. data/lib/microstation/model_trait.rb +40 -40
  33. data/lib/microstation/ole_cad_input_message.rb +25 -34
  34. data/lib/microstation/ole_helper.rb +58 -66
  35. data/lib/microstation/pdf_support.rb +7 -16
  36. data/lib/microstation/point3d.rb +17 -30
  37. data/lib/microstation/primitive_command_interface.rb +8 -14
  38. data/lib/microstation/properties.rb +29 -17
  39. data/lib/microstation/property_handler.rb +6 -8
  40. data/lib/microstation/scan/color.rb +1 -8
  41. data/lib/microstation/scan/criteria.rb +17 -33
  42. data/lib/microstation/scan/klass.rb +8 -12
  43. data/lib/microstation/scan/level.rb +2 -9
  44. data/lib/microstation/scan/line_style.rb +4 -12
  45. data/lib/microstation/scan/line_weight.rb +1 -3
  46. data/lib/microstation/scan/range.rb +2 -8
  47. data/lib/microstation/scan/scan_trait.rb +48 -51
  48. data/lib/microstation/scan/subtype.rb +0 -10
  49. data/lib/microstation/scan/type.rb +9 -15
  50. data/lib/microstation/scan_trait.rb +13 -20
  51. data/lib/microstation/scanner.rb +1 -11
  52. data/lib/microstation/tag.rb +12 -21
  53. data/lib/microstation/tag_set.rb +52 -71
  54. data/lib/microstation/tag_set_trait.rb +6 -10
  55. data/lib/microstation/tagged_element.rb +16 -28
  56. data/lib/microstation/template.rb +15 -14
  57. data/lib/microstation/template_info.rb +35 -49
  58. data/lib/microstation/template_runner.rb +14 -22
  59. data/lib/microstation/text.rb +15 -19
  60. data/lib/microstation/text_node.rb +17 -26
  61. data/lib/microstation/ts/attribute.rb +16 -20
  62. data/lib/microstation/ts/instance.rb +28 -38
  63. data/lib/microstation/ts/tagset_trait.rb +5 -12
  64. data/lib/microstation/types.rb +0 -3
  65. data/lib/microstation/version.rb +1 -3
  66. data/lib/microstation/wrap.rb +3 -10
  67. data/lib/microstation.rb +57 -72
  68. data/spec/microstation/app_spec.rb +49 -46
  69. data/spec/microstation/configuration_spec.rb +45 -43
  70. data/spec/microstation/drawing_spec.rb +103 -101
  71. data/spec/microstation/functions_spec.rb +18 -12
  72. data/spec/microstation/tag_set_spec.rb +57 -55
  73. data/spec/microstation/template_spec.rb +41 -42
  74. data/spec/microstation/text_node_spec.rb +16 -14
  75. data/spec/microstation/text_spec.rb +10 -8
  76. data/spec/microstation_spec.rb +18 -17
  77. data/spec/spec_helper.rb +18 -18
  78. metadata +36 -22
@@ -1,19 +1,15 @@
1
- require 'microstation/element'
1
+ require "microstation/element"
2
2
 
3
3
  module Microstation
4
-
5
4
  class Line < Element
6
-
7
5
  def length
8
6
  ole_obj.Length
9
7
  end
10
8
 
11
-
12
9
  def vertices
13
10
  ole_obj.AsVertexList
14
11
  n = ole_obj.VerticesCount
15
- list = ole_obj.GetVertices
16
- list
12
+ ole_obj.GetVertices
17
13
  end
18
14
  end
19
15
  end
@@ -1,45 +1,36 @@
1
- #require_relative 'scan/scan_trait'
2
- require 'microstation/wrap'
3
- require_relative 'model_trait'
4
-
5
- #require_relative 'ts/tagset_trait'
6
- #require_relative 'graphics'
7
- #require_relative 'ts/instance'
1
+ # require_relative 'scan/scan_trait'
2
+ require "microstation/wrap"
3
+ require_relative "model_trait"
8
4
 
5
+ # require_relative 'ts/tagset_trait'
6
+ # require_relative 'graphics'
7
+ # require_relative 'ts/instance'
9
8
 
10
9
  module Microstation
11
-
12
10
  class DefaultModel
13
-
14
11
  include ::Microstation::ModelTrait
15
12
 
16
- attr_reader :app,:ole_obj
13
+ attr_reader :app, :ole_obj
17
14
 
18
- def initialize(app,ole)
15
+ def initialize(app, ole)
19
16
  @app = app
20
17
  @ole_obj = ole
21
18
  end
22
19
 
23
20
  def drawing
24
- @drawing ||= ::Microstation::Drawing.from_ole_obj(app,ole_obj)
21
+ @drawing ||= ::Microstation::Drawing.from_ole_obj(app, ole_obj)
25
22
  end
26
-
27
-
28
23
  end
29
24
 
30
-
31
25
  class Model
32
-
33
26
  include ::Microstation::ModelTrait
34
27
 
35
- attr_reader :app,:drawing,:ole_obj
28
+ attr_reader :app, :drawing, :ole_obj
36
29
 
37
- def initialize(app,drawing,ole)
30
+ def initialize(app, drawing, ole)
38
31
  @app = app
39
32
  @drawing = drawing
40
33
  @ole_obj = ole
41
34
  end
42
-
43
35
  end
44
-
45
36
  end
@@ -1,9 +1,8 @@
1
- require_relative 'graphics'
2
- require_relative 'scan_trait'
1
+ require_relative "graphics"
2
+ require_relative "scan_trait"
3
3
 
4
4
  module Microstation
5
5
  module ModelTrait
6
-
7
6
  include Graphics
8
7
 
9
8
  include ScanTrait
@@ -14,7 +13,11 @@ module Microstation
14
13
  end
15
14
 
16
15
  def find_by_id(id)
17
- ele = ole_obj.GetElementById64(id) rescue nil
16
+ ele = begin
17
+ ole_obj.GetElementById64(id)
18
+ rescue
19
+ nil
20
+ end
18
21
  return nil unless ele
19
22
  app.ole_to_ruby(ele)
20
23
  end
@@ -24,20 +27,20 @@ module Microstation
24
27
  end
25
28
 
26
29
  def get_selected_elements
27
- Enumerator.new(ole_obj.GetSelectedElements,app)
30
+ Enumerator.new(ole_obj.GetSelectedElements, app)
28
31
  end
29
32
 
30
33
  def get_selected_text
31
- get_selected_elements.select{|t| t.textual?}
34
+ get_selected_elements.select { |t| t.textual? }
32
35
  end
33
36
 
34
37
  def get_matching_text(re)
35
38
  result = []
36
39
  get_selected_text.each do |t|
37
- md = re.match( t)
40
+ md = re.match(t)
38
41
  if md
39
42
  if block_given?
40
- yield t,md
43
+ yield t, md
41
44
  else
42
45
  result << t
43
46
  end
@@ -46,10 +49,10 @@ module Microstation
46
49
  end
47
50
  end
48
51
 
49
- def change_text_suffix(reg,offset)
50
- get_matching_text(reg) do |t,md|
52
+ def change_text_suffix(reg, offset)
53
+ get_matching_text(reg) do |t, md|
51
54
  pre = md[1]
52
- suff = Integer( md[2] ) + offset
55
+ suff = Integer(md[2]) + offset
53
56
  t.replace "#{pre}#{suff}"
54
57
  end
55
58
  end
@@ -78,7 +81,6 @@ module Microstation
78
81
  "Microstation::Model-#{name}"
79
82
  end
80
83
 
81
-
82
84
  def add_element(el)
83
85
  if el.respond_to? :ole_obj
84
86
  el = el.ole_obj
@@ -88,56 +90,55 @@ module Microstation
88
90
  end
89
91
 
90
92
  def select_tagset_instances
91
-
92
93
  end
93
94
 
94
- def scan_tags_filtered( ts_name: nil, base_element_id: nil,&block)
95
+ def scan_tags_filtered(ts_name: nil, base_element_id: nil, &block)
95
96
  case [ts_name, base_element_id]
96
- in [nil, nil]
97
- scan_tags(&block)
98
- in [String,nil]
99
- scan_tags.select{ |t| t.tagset_name == ts_name }
100
- in [String, Numeric]
101
- scan_tags.select{ |t| t.tagset_name == ts_name && t.base_element_id == base_element_id }
102
- in [nil, Numeric]
103
- scan_tags.select{ |t| t.base_element_id == base_element_id }
97
+ in [nil, nil]
98
+ scan_tags(&block)
99
+ in [String, nil]
100
+ scan_tags.select { |t| t.tagset_name == ts_name }
101
+ in [String, Numeric]
102
+ scan_tags.select { |t| t.tagset_name == ts_name && t.base_element_id == base_element_id }
103
+ in [nil, Numeric]
104
+ scan_tags.select { |t| t.base_element_id == base_element_id }
104
105
 
105
106
  end
106
107
  end
107
108
 
108
109
  def tags_to_hash(tags)
109
- return to_enum(__callee__,tags) unless block_given?
110
- tsets = tags.group_by{ |t| t.tagset_name }
110
+ return to_enum(__callee__, tags) unless block_given?
111
+ tsets = tags.group_by { |t| t.tagset_name }
111
112
  tsets.each do |tsname, tags|
112
- elements = tags.group_by{|t| t.base_element_id}
113
+ elements = tags.group_by { |t| t.base_element_id }
113
114
  elements.each do |id, tag_elts|
114
115
  result_hash = {
115
116
  name: tsname,
116
117
  model: name,
117
118
  tags: tag_elts,
118
- base_element_id: id,
119
+ base_element_id: id
119
120
  }
120
121
  yield result_hash
121
122
  end
122
123
  end
123
124
  end
124
125
 
125
- def get_tagsets_in_model_hash(ts_name: nil, base_element_id: nil,&block)
126
+ def get_tagsets_in_model_hash(ts_name: nil, base_element_id: nil, &block)
126
127
  tags = scan_tags_filtered(ts_name: ts_name, base_element_id: base_element_id)
127
128
  tags_to_hash(tags, &block)
128
129
  end
129
130
 
130
131
  def get_tagsets_in_model_hash_old
131
132
  results = []
132
- tsets = scan_tags.group_by{|t| t.tagset_name}
133
+ tsets = scan_tags.group_by { |t| t.tagset_name }
133
134
  tsets.each do |tsname, tags|
134
- elements = tags.group_by{|t| t.base_element_id}
135
+ elements = tags.group_by { |t| t.base_element_id }
135
136
  elements.each do |id, tag_elts|
136
137
  result_hash = {
137
138
  name: tsname,
138
139
  model: name,
139
140
  tags: tag_elts,
140
- base_element_id: id,
141
+ base_element_id: id
141
142
  }
142
143
  if block_given?
143
144
  yield result_hash
@@ -146,22 +147,20 @@ module Microstation
146
147
  end
147
148
  end
148
149
  results unless block_given?
149
- end
150
-
150
+ end
151
151
  end
152
152
 
153
-
154
153
  # Scan the model with
155
154
  # @param [Scan::Criteria] criteria - the criteria to scan
156
155
  # @yield the item
157
- def scan_model(criteria=nil)
156
+ def scan_model(criteria = nil)
158
157
  # binding.pry
159
- criteria = criteria || create_scanner(:nullscanner)
158
+ criteria ||= create_scanner(:nullscanner)
160
159
  scan_result = ole_run_scan(criteria)
161
160
  return [] unless scan_result
162
161
  # binding.pry
163
162
  scan_enum = ::Microstation::Enumerator.new(scan_result, app)
164
- result = []
163
+ result = []
165
164
  if block_given?
166
165
  scan_enum.each do |item|
167
166
  yield item
@@ -180,10 +179,11 @@ module Microstation
180
179
 
181
180
  def ole_run_scan(criteria)
182
181
  criteria.resolve
183
- scan_result = self.ole_obj.Scan(criteria.ole_obj) rescue nil
182
+ scan_result = begin
183
+ ole_obj.Scan(criteria.ole_obj)
184
+ rescue
185
+ nil
186
+ end
184
187
  end
185
-
186
-
187
188
  end
188
-
189
189
  end
@@ -1,25 +1,17 @@
1
1
  module Microstation
2
-
3
-
4
2
  module InputType
5
-
6
- Command = 1
7
- Reset = 2
8
- DataPoint = 3
9
- Keyin = 4
10
- Any = 5
11
- Unassigned = 6
12
-
3
+ COMMAND = 1
4
+ DATA_POINT = 3
5
+ KEYIN = 4
6
+ ANY = 5
7
+ UNASSIGNED = 6
13
8
  end
14
9
 
15
-
16
10
  class OLE_CadInputMessage
11
+ include WIN32OLE::VARIANT
12
+ attr_reader :lastargs, :ole_obj, :app
17
13
 
18
- include WIN32OLE::VARIANT
19
- attr_reader :lastargs,:ole_obj, :app
20
-
21
-
22
- def initialize(ole,app)
14
+ def initialize(ole, app)
23
15
  @ole_obj = ole
24
16
  @app = app
25
17
  end
@@ -29,23 +21,23 @@ module Microstation
29
21
  end
30
22
 
31
23
  def command?
32
- input_type == InputType::Command
24
+ input_type == InputType::COMMAND
33
25
  end
34
26
 
35
27
  def data_point?
36
- input_type == InputType::DataPoint
28
+ input_type == InputType::DATA_POINT
37
29
  end
38
30
 
39
31
  def key_in?
40
- input_type == InputType::Keyin
32
+ input_type == InputType::KEYIN
41
33
  end
42
34
 
43
35
  def any?
44
- input_type == InputType::Any
36
+ input_type == InputType::ANY
45
37
  end
46
38
 
47
39
  def unassigned?
48
- input_type == InputType::Unassigned
40
+ input_type == InputType::UNASSIGNED
49
41
  end
50
42
 
51
43
  def input_type
@@ -53,49 +45,48 @@ module Microstation
53
45
  end
54
46
 
55
47
  # MsdCadInputType InputType
56
- def get_input_type()
48
+ def get_input_type
57
49
  ole_obj.InputType
58
50
  end
59
51
 
60
52
  # BSTR Keyin
61
- def get_keyin()
62
- ret = ole_obj._getproperty(1610743809, [], [])
53
+ def get_keyin
54
+ ret = ole_obj._getproperty(1_610_743_809, [], [])
63
55
  @lastargs = WIN32OLE::ARGV
64
56
  ret
65
57
  end
66
58
 
67
59
  # Point3d Point
68
- def get_point()
60
+ def get_point
69
61
  app.to_point3d(ole_obj.Point)
70
62
  end
71
63
 
72
64
  # BSTR CommandKeyin
73
- def get_command_keyin()
74
- ret = ole_obj._getproperty(1610743811, [], [])
65
+ def get_command_keyin
66
+ ret = ole_obj._getproperty(1_610_743_811, [], [])
75
67
  @lastargs = WIN32OLE::ARGV
76
68
  ret
77
69
  end
78
70
 
79
71
  # _View View
80
- def get_view()
81
- ret = ole_obj._getproperty(1610743812, [], [])
72
+ def get_view
73
+ ret = ole_obj._getproperty(1_610_743_812, [], [])
82
74
  @lastargs = WIN32OLE::ARGV
83
75
  ret
84
76
  end
85
77
 
86
78
  # Point3d ScreenPoint
87
- def get_screen_point()
88
- ret = ole_obj._getproperty(1610743813, [], [])
79
+ def get_screen_point
80
+ ret = ole_obj._getproperty(1_610_743_813, [], [])
89
81
  @lastargs = WIN32OLE::ARGV
90
82
  ret
91
83
  end
92
84
 
93
85
  # I4 CursorButton
94
- def get_cursor_button()
95
- ret = ole_obj._getproperty(1610743814, [], [])
86
+ def get_cursor_button
87
+ ret = ole_obj._getproperty(1_610_743_814, [], [])
96
88
  @lastargs = WIN32OLE::ARGV
97
89
  ret
98
90
  end
99
91
  end
100
-
101
92
  end
@@ -1,21 +1,20 @@
1
1
  module OleHelper
2
-
3
2
  def select_ole_type(name)
4
- if name.class == String
3
+ if name.instance_of?(String)
5
4
  name = Regexp.new(name)
6
5
  end
7
- reg = Regexp.new(name.source,Regexp::IGNORECASE)
6
+ reg = Regexp.new(name.source, Regexp::IGNORECASE)
8
7
  typelib.ole_classes.select do |k|
9
8
  reg =~ k.name
10
9
  end
11
10
  end
12
11
 
13
12
  def select_ole_method(name)
14
- if name.class == String
13
+ if name.instance_of?(String)
15
14
  name = Regexp.new(name)
16
15
  end
17
- reg = Regexp.new(name.source,Regexp::IGNORECASE)
18
- self.ole_methods.select do |k|
16
+ reg = Regexp.new(name.source, Regexp::IGNORECASE)
17
+ ole_methods.select do |k|
19
18
  reg =~ k.name
20
19
  end
21
20
  end
@@ -29,8 +28,8 @@ module OleHelper
29
28
  end
30
29
 
31
30
  def ole_classes_detail
32
- s = String.new
33
- ole_classes.sort_by{|k| k.ole_type}.each do |k|
31
+ s = ""
32
+ ole_classes.sort_by { |k| k.ole_type }.each do |k|
34
33
  s << "#{k.name}\n\n"
35
34
  s << "Type: #{k.ole_type}\n"
36
35
  s << "progid: #{k.progid}\n"
@@ -40,9 +39,8 @@ module OleHelper
40
39
  s
41
40
  end
42
41
 
43
-
44
42
  def ole_methods_detail
45
- s = String.new
43
+ s = ""
46
44
  ole_methods.each do |m|
47
45
  s << "Method #{m.name}\n\n"
48
46
  s << "dispid: #{m.dispid}\n"
@@ -65,7 +63,6 @@ module OleHelper
65
63
  s
66
64
  end
67
65
 
68
-
69
66
  def each_ole_type
70
67
  return enum_for(:each_ole_type) unless block_given?
71
68
  typelib.ole_classes.each do |t|
@@ -74,8 +71,8 @@ module OleHelper
74
71
  end
75
72
 
76
73
  def get_ole_type(name)
77
- if name.class == String
78
- return ole_classes.find{|t| t.name == name}
74
+ if name.instance_of?(String)
75
+ return ole_classes.find { |t| t.name == name }
79
76
  end
80
77
  reg = Regexp.new(name.source, Regexp::IGNORECASE)
81
78
  ole_classes.find do |t|
@@ -84,69 +81,64 @@ module OleHelper
84
81
  end
85
82
 
86
83
  def typelib
87
- self.ole_typelib
84
+ ole_typelib
88
85
  end
89
-
90
-
91
86
  end
92
87
 
93
-
94
88
  class WIN32OLE
95
-
96
89
  include OleHelper
97
-
98
90
  end
99
91
 
100
92
 
101
- # def select_ole_type(name)
102
- # if name.class == String
103
- # name = Regexp.new(name)
104
- # end
105
- # reg = Regexp.new(name.source,Regexp::IGNORECASE)
106
- # typelib.ole_classes.select do |k|
107
- # reg =~ k.name
108
- # end
109
- # end
110
-
111
- # def select_ole_method(name)
112
- # if name.class == String
113
- # name = Regexp.new(name)
114
- # end
115
- # reg = Regexp.new(name.source,Regexp::IGNORECASE)
116
- # ole_obj.ole_methods.select do |k|
117
- # reg =~ k.name
118
- # end
119
- # end
120
-
121
- # def ole_classes
122
- # typelib.ole_classes
123
- # end
124
-
125
- # def create_ole_type(type)
126
- # WIN32OLE.new(type.guid)
127
- # end
128
-
129
- # def each_ole_type
130
- # return enum_for(:each_ole_type) unless block_given?
131
- # typelib.ole_classes.each do |t|
132
- # yield t
133
- # end
134
- # end
135
-
136
- # def get_ole_type(name)
137
- # if name.class == String
138
- # name = Regexp.new name
139
- # end
140
- # reg = Regexp.new(name.source, Regexp::IGNORECASE)
141
- # typelib.ole_classes.find do |t|
142
- # t.name =~ name
143
- # end
144
- # end
93
+ # def select_ole_type(name)
94
+ # if name.class == String
95
+ # name = Regexp.new(name)
96
+ # end
97
+ # reg = Regexp.new(name.source,Regexp::IGNORECASE)
98
+ # typelib.ole_classes.select do |k|
99
+ # reg =~ k.name
100
+ # end
101
+ # end
102
+
103
+ # def select_ole_method(name)
104
+ # if name.class == String
105
+ # name = Regexp.new(name)
106
+ # end
107
+ # reg = Regexp.new(name.source,Regexp::IGNORECASE)
108
+ # ole_obj.ole_methods.select do |k|
109
+ # reg =~ k.name
110
+ # end
111
+ # end
112
+
113
+ # def ole_classes
114
+ # typelib.ole_classes
115
+ # end
116
+
117
+ # def create_ole_type(type)
118
+ # WIN32OLE.new(type.guid)
119
+ # end
120
+
121
+ # def each_ole_type
122
+ # return enum_for(:each_ole_type) unless block_given?
123
+ # typelib.ole_classes.each do |t|
124
+ # yield t
125
+ # end
126
+ # end
127
+
128
+ # def get_ole_type(name)
129
+ # if name.class == String
130
+ # name = Regexp.new name
131
+ # end
132
+ # reg = Regexp.new(name.source, Regexp::IGNORECASE)
133
+ # typelib.ole_classes.find do |t|
134
+ # t.name =~ name
135
+ # end
136
+ # end
145
137
 
146
138
 
147
139
 
148
140
  # alias :find_ole_type :get_ole_type
149
141
 
150
- # def typelib
151
- # ole_obj.ole_typelib
152
- # end
142
+ # def typelib
143
+ # ole_obj.ole_typelib
144
+ # end
@@ -1,12 +1,9 @@
1
1
  module Microstation
2
-
3
-
4
2
  module PdfSupport
5
-
6
- def pdf_name(output_dir=nil)
7
- name = self.basename
8
- dir = output_dir || self.dirname
9
- pdfname = Pathname(name).ext('pdf')
3
+ def pdf_name(output_dir = nil)
4
+ name = basename
5
+ dir = output_dir || dirname
6
+ pdfname = Pathname(name).ext("pdf")
10
7
  (dir + pdfname).expand_path
11
8
  end
12
9
 
@@ -18,23 +15,17 @@ module Microstation
18
15
  file.file?
19
16
  end
20
17
 
21
- def needs_pdf?(output_dir=nil)
18
+ def needs_pdf?(output_dir = nil)
22
19
  pdf_path = pdf_name(output_dir)
23
20
  !file_exists?(pdf_path) || pdf_older?(pdf_path)
24
21
  end
25
22
 
26
23
  def pdf_older?(pdf)
27
- self.mtime > pdf.mtime
24
+ mtime > pdf.mtime
28
25
  end
29
26
 
30
-
31
27
  def mtime
32
- self.path.mtime
28
+ path.mtime
33
29
  end
34
-
35
-
36
30
  end
37
-
38
-
39
31
  end
40
-