barometer 0.1.0
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.
- data/LICENSE +20 -0
- data/README.rdoc +266 -0
- data/VERSION.yml +4 -0
- data/bin/barometer +63 -0
- data/lib/barometer.rb +52 -0
- data/lib/barometer/base.rb +52 -0
- data/lib/barometer/data.rb +15 -0
- data/lib/barometer/data/current.rb +93 -0
- data/lib/barometer/data/distance.rb +131 -0
- data/lib/barometer/data/forecast.rb +66 -0
- data/lib/barometer/data/geo.rb +98 -0
- data/lib/barometer/data/location.rb +20 -0
- data/lib/barometer/data/measurement.rb +161 -0
- data/lib/barometer/data/pressure.rb +133 -0
- data/lib/barometer/data/speed.rb +147 -0
- data/lib/barometer/data/sun.rb +35 -0
- data/lib/barometer/data/temperature.rb +164 -0
- data/lib/barometer/data/units.rb +55 -0
- data/lib/barometer/data/zone.rb +124 -0
- data/lib/barometer/extensions/graticule.rb +50 -0
- data/lib/barometer/extensions/httparty.rb +21 -0
- data/lib/barometer/query.rb +228 -0
- data/lib/barometer/services.rb +6 -0
- data/lib/barometer/services/google.rb +146 -0
- data/lib/barometer/services/noaa.rb +6 -0
- data/lib/barometer/services/service.rb +324 -0
- data/lib/barometer/services/weather_bug.rb +6 -0
- data/lib/barometer/services/weather_dot_com.rb +6 -0
- data/lib/barometer/services/wunderground.rb +285 -0
- data/lib/barometer/services/yahoo.rb +274 -0
- data/lib/barometer/weather.rb +187 -0
- data/spec/barometer_spec.rb +162 -0
- data/spec/data_current_spec.rb +225 -0
- data/spec/data_distance_spec.rb +336 -0
- data/spec/data_forecast_spec.rb +150 -0
- data/spec/data_geo_spec.rb +90 -0
- data/spec/data_location_spec.rb +59 -0
- data/spec/data_measurement_spec.rb +411 -0
- data/spec/data_pressure_spec.rb +336 -0
- data/spec/data_speed_spec.rb +374 -0
- data/spec/data_sun_spec.rb +76 -0
- data/spec/data_temperature_spec.rb +396 -0
- data/spec/data_zone_spec.rb +133 -0
- data/spec/fixtures/current_calgary_ab.xml +1 -0
- data/spec/fixtures/forecast_calgary_ab.xml +1 -0
- data/spec/fixtures/geocode_40_73.xml +1 -0
- data/spec/fixtures/geocode_90210.xml +1 -0
- data/spec/fixtures/geocode_T5B4M9.xml +1 -0
- data/spec/fixtures/geocode_calgary_ab.xml +1 -0
- data/spec/fixtures/geocode_newyork_ny.xml +1 -0
- data/spec/fixtures/google_calgary_ab.xml +1 -0
- data/spec/fixtures/yahoo_90210.xml +1 -0
- data/spec/query_spec.rb +469 -0
- data/spec/service_google_spec.rb +144 -0
- data/spec/service_wunderground_spec.rb +330 -0
- data/spec/service_yahoo_spec.rb +299 -0
- data/spec/services_spec.rb +1106 -0
- data/spec/spec_helper.rb +14 -0
- data/spec/units_spec.rb +101 -0
- data/spec/weather_spec.rb +265 -0
- metadata +119 -0
@@ -0,0 +1,336 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Distance" do
|
4
|
+
|
5
|
+
describe "when initialized" do
|
6
|
+
|
7
|
+
it "defines METRIC_UNITS" do
|
8
|
+
Barometer::Distance.const_defined?("METRIC_UNITS").should be_true
|
9
|
+
Barometer::Distance::METRIC_UNITS.should == "km"
|
10
|
+
end
|
11
|
+
|
12
|
+
it "defines IMPERIAL_UNITS" do
|
13
|
+
Barometer::Distance.const_defined?("IMPERIAL_UNITS").should be_true
|
14
|
+
Barometer::Distance::IMPERIAL_UNITS.should == "m"
|
15
|
+
end
|
16
|
+
|
17
|
+
before(:each) do
|
18
|
+
@distance = Barometer::Distance.new
|
19
|
+
end
|
20
|
+
|
21
|
+
it "responds to kilometers" do
|
22
|
+
@distance.kilometers.should be_nil
|
23
|
+
end
|
24
|
+
|
25
|
+
it "responds to miles" do
|
26
|
+
@distance.miles.should be_nil
|
27
|
+
end
|
28
|
+
|
29
|
+
it "responds to metric_default" do
|
30
|
+
lambda { @distance.metric_default = 5 }.should_not raise_error(NotImplementedError)
|
31
|
+
end
|
32
|
+
|
33
|
+
it "responds to imperial_default" do
|
34
|
+
lambda { @distance.imperial_default = 5 }.should_not raise_error(NotImplementedError)
|
35
|
+
end
|
36
|
+
|
37
|
+
it "responds to nil?" do
|
38
|
+
@distance.nil?.should be_true
|
39
|
+
@distance.km = 5
|
40
|
+
@distance.nil?.should be_false
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
describe "conversion" do
|
46
|
+
|
47
|
+
# For all conversions
|
48
|
+
# 26.2 M = 42.2 KM
|
49
|
+
before(:each) do
|
50
|
+
@m = 26.2
|
51
|
+
@km = 42.2
|
52
|
+
end
|
53
|
+
|
54
|
+
it "requires a value, that is either Integer or Float" do
|
55
|
+
Barometer::Distance.km_to_m(nil).should be_nil
|
56
|
+
Barometer::Distance.m_to_km(nil).should be_nil
|
57
|
+
|
58
|
+
not_float_or_integer = "string"
|
59
|
+
Barometer::Distance.km_to_m(not_float_or_integer).should be_nil
|
60
|
+
Barometer::Distance.m_to_km(not_float_or_integer).should be_nil
|
61
|
+
end
|
62
|
+
|
63
|
+
it "converts KM to M" do
|
64
|
+
((Barometer::Distance.km_to_m(@km)*10).round/10.0).should == @m
|
65
|
+
end
|
66
|
+
|
67
|
+
it "converts M to KM" do
|
68
|
+
((Barometer::Distance.m_to_km(@m)*10).round/10.0).should == @km
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
describe "updating" do
|
74
|
+
|
75
|
+
before(:each) do
|
76
|
+
@distance = Barometer::Distance.new
|
77
|
+
@m = 26.2
|
78
|
+
@km = 42.2
|
79
|
+
end
|
80
|
+
|
81
|
+
it "nils M if new KM converts to a M that changes more then 1 unit" do
|
82
|
+
@distance.miles = (@m + 1.1)
|
83
|
+
@distance.update_miles(@km)
|
84
|
+
@distance.miles.should be_nil
|
85
|
+
end
|
86
|
+
|
87
|
+
it "doesn't update M if new KM converts to a M that does not change more then 1 unit" do
|
88
|
+
@distance.miles = (@m + 0.9)
|
89
|
+
@distance.update_miles(@km)
|
90
|
+
@distance.miles.should == (@m + 0.9)
|
91
|
+
end
|
92
|
+
|
93
|
+
it "doesn't set M if not already set" do
|
94
|
+
@distance.miles.should be_nil
|
95
|
+
@distance.kilometers.should be_nil
|
96
|
+
@distance.update_miles(@km)
|
97
|
+
@distance.miles.should be_nil
|
98
|
+
@distance.kilometers.should be_nil
|
99
|
+
end
|
100
|
+
|
101
|
+
it "nils KM if new M converts to a KM that changes more then 1 unit" do
|
102
|
+
@distance.kilometers = (@km + 1.1)
|
103
|
+
@distance.update_kilometers(@m)
|
104
|
+
@distance.kilometers.should be_nil
|
105
|
+
end
|
106
|
+
|
107
|
+
it "doesn't update KM if new M converts to a KM that does not change more then 1 unit" do
|
108
|
+
@distance.kilometers = (@km + 0.9)
|
109
|
+
@distance.update_kilometers(@m)
|
110
|
+
@distance.kilometers.should == (@km + 0.9)
|
111
|
+
end
|
112
|
+
|
113
|
+
it "doesn't set KM if not already set" do
|
114
|
+
@distance.miles.should be_nil
|
115
|
+
@distance.kilometers.should be_nil
|
116
|
+
@distance.update_kilometers(@m)
|
117
|
+
@distance.miles.should be_nil
|
118
|
+
@distance.kilometers.should be_nil
|
119
|
+
end
|
120
|
+
|
121
|
+
end
|
122
|
+
|
123
|
+
describe "storing" do
|
124
|
+
|
125
|
+
before(:each) do
|
126
|
+
@distance = Barometer::Distance.new
|
127
|
+
@m = 26.2
|
128
|
+
@km = 42.2
|
129
|
+
end
|
130
|
+
|
131
|
+
it "doesn't update KM if nil value (or equivalent)" do
|
132
|
+
@distance.kilometers.should be_nil
|
133
|
+
@distance.km = nil
|
134
|
+
@distance.kilometers.should be_nil
|
135
|
+
@distance.km = "na"
|
136
|
+
@distance.kilometers.should be_nil
|
137
|
+
end
|
138
|
+
|
139
|
+
it "stores KM and resets M" do
|
140
|
+
@distance.kilometers.should be_nil
|
141
|
+
@distance.miles = (@m + 1.1)
|
142
|
+
@distance.km = @km
|
143
|
+
@distance.kilometers.should == @km
|
144
|
+
@distance.miles.should be_nil
|
145
|
+
end
|
146
|
+
|
147
|
+
it "doesn't update M if nil value (or equivalent)" do
|
148
|
+
@distance.miles.should be_nil
|
149
|
+
@distance.m = nil
|
150
|
+
@distance.miles.should be_nil
|
151
|
+
@distance.m = "na"
|
152
|
+
@distance.miles.should be_nil
|
153
|
+
end
|
154
|
+
|
155
|
+
it "stores M and resets KM" do
|
156
|
+
@distance.miles.should be_nil
|
157
|
+
@distance.kilometers = (@km + 1.1)
|
158
|
+
@distance.m = @m
|
159
|
+
@distance.miles.should == @m
|
160
|
+
@distance.kilometers.should be_nil
|
161
|
+
end
|
162
|
+
|
163
|
+
end
|
164
|
+
|
165
|
+
describe "retrieving" do
|
166
|
+
|
167
|
+
before(:each) do
|
168
|
+
@distance = Barometer::Distance.new
|
169
|
+
@m = 26.2
|
170
|
+
@km = 42.16
|
171
|
+
end
|
172
|
+
|
173
|
+
it "returns KM if it exists" do
|
174
|
+
@distance.km = @km
|
175
|
+
@distance.kilometers.should == @km
|
176
|
+
@distance.km(false).should == @km
|
177
|
+
end
|
178
|
+
|
179
|
+
it "auto converts from M if KM is nil and M exists" do
|
180
|
+
@distance.m = @m
|
181
|
+
@distance.miles.should == @m
|
182
|
+
@distance.kilometers.should be_nil
|
183
|
+
@distance.km(false).should == @km
|
184
|
+
end
|
185
|
+
|
186
|
+
it "allows a float to be returned for KM" do
|
187
|
+
km = 42.12
|
188
|
+
@distance.km = km
|
189
|
+
@distance.kilometers.should == km
|
190
|
+
@distance.km(true).should == km.to_i
|
191
|
+
@distance.km(false).should == km.to_f
|
192
|
+
end
|
193
|
+
|
194
|
+
it "allows only 2 decimal precision for KM" do
|
195
|
+
km = 42.1234
|
196
|
+
@distance.km = km
|
197
|
+
@distance.kilometers.should == km
|
198
|
+
@distance.km(false).should == 42.12
|
199
|
+
end
|
200
|
+
|
201
|
+
it "returns M if it exists" do
|
202
|
+
@distance.m = @m
|
203
|
+
@distance.miles.should == @m
|
204
|
+
@distance.m(false).should == @m
|
205
|
+
end
|
206
|
+
|
207
|
+
it "auto converts from KM if M is nil and KM exists" do
|
208
|
+
@distance.km = @km
|
209
|
+
@distance.kilometers.should == @km
|
210
|
+
@distance.miles.should be_nil
|
211
|
+
((@distance.m(false)*10).round/10.0).should == @m
|
212
|
+
end
|
213
|
+
|
214
|
+
it "allows a float to be returned for M" do
|
215
|
+
m = 26.12
|
216
|
+
@distance.m = m
|
217
|
+
@distance.miles.should == m
|
218
|
+
@distance.m(true).should == m.to_i
|
219
|
+
@distance.m(false).should == m.to_f
|
220
|
+
end
|
221
|
+
|
222
|
+
it "allows only 2 decimal precision for M" do
|
223
|
+
m = 26.1234
|
224
|
+
@distance.m = m
|
225
|
+
@distance.miles.should == m
|
226
|
+
@distance.m(false).should == 26.12
|
227
|
+
end
|
228
|
+
|
229
|
+
end
|
230
|
+
|
231
|
+
describe "operators" do
|
232
|
+
|
233
|
+
before(:each) do
|
234
|
+
@m = 26.2
|
235
|
+
@km = 42.16
|
236
|
+
@distance_low = Barometer::Distance.new
|
237
|
+
@distance_low.km = (@m - 1.0)
|
238
|
+
@distance_high = Barometer::Distance.new
|
239
|
+
@distance_high.km = (@km + 1.0)
|
240
|
+
@distance = Barometer::Distance.new
|
241
|
+
@distance.km = @km
|
242
|
+
@distance_same = Barometer::Distance.new
|
243
|
+
@distance_same.km = @km
|
244
|
+
end
|
245
|
+
|
246
|
+
it "defines <=>" do
|
247
|
+
Barometer::Distance.method_defined?("<=>").should be_true
|
248
|
+
(@distance_low <=> @distance_high).should == -1
|
249
|
+
(@distance_high <=> @distance_low).should == 1
|
250
|
+
(@distance <=> @distance_same).should == 0
|
251
|
+
end
|
252
|
+
|
253
|
+
it "defines <" do
|
254
|
+
Barometer::Distance.method_defined?("<").should be_true
|
255
|
+
@distance_low.should < @distance_high
|
256
|
+
@distance_high.should_not < @distance_low
|
257
|
+
@distance.should_not < @distance_same
|
258
|
+
end
|
259
|
+
|
260
|
+
it "defines >" do
|
261
|
+
Barometer::Distance.method_defined?(">").should be_true
|
262
|
+
@distance_low.should_not > @distance_high
|
263
|
+
@distance_high.should > @distance_low
|
264
|
+
@distance.should_not > @distance_same
|
265
|
+
end
|
266
|
+
|
267
|
+
it "defines ==" do
|
268
|
+
Barometer::Distance.method_defined?("==").should be_true
|
269
|
+
@distance_low.should_not == @distance_high
|
270
|
+
@distance.should == @distance_same
|
271
|
+
end
|
272
|
+
|
273
|
+
it "defines <=" do
|
274
|
+
Barometer::Distance.method_defined?("<=").should be_true
|
275
|
+
@distance_low.should <= @distance_high
|
276
|
+
@distance_high.should_not <= @distance_low
|
277
|
+
@distance.should <= @distance_same
|
278
|
+
end
|
279
|
+
|
280
|
+
it "defines >=" do
|
281
|
+
Barometer::Distance.method_defined?(">=").should be_true
|
282
|
+
@distance_low.should_not >= @distance_high
|
283
|
+
@distance_high.should >= @distance_low
|
284
|
+
@distance.should >= @distance_same
|
285
|
+
end
|
286
|
+
|
287
|
+
end
|
288
|
+
|
289
|
+
describe "changing units" do
|
290
|
+
|
291
|
+
before(:each) do
|
292
|
+
@m = 26.2
|
293
|
+
@km = 42.16
|
294
|
+
@distance = Barometer::Distance.new
|
295
|
+
@distance.km = @km
|
296
|
+
end
|
297
|
+
|
298
|
+
it "returns just the integer value (no units)" do
|
299
|
+
@distance.metric?.should be_true
|
300
|
+
@distance.to_i.should == @km.to_i
|
301
|
+
|
302
|
+
@distance.imperial!
|
303
|
+
@distance.metric?.should be_false
|
304
|
+
@distance.to_i.should == @m.to_i
|
305
|
+
end
|
306
|
+
|
307
|
+
it "returns just the float value (no units)" do
|
308
|
+
@distance.metric?.should be_true
|
309
|
+
@distance.to_f.should == @km.to_f
|
310
|
+
|
311
|
+
@distance.imperial!
|
312
|
+
@distance.metric?.should be_false
|
313
|
+
((@distance.to_f*10).round/10.0).should == @m.to_f
|
314
|
+
end
|
315
|
+
|
316
|
+
it "returns just the integer value with units" do
|
317
|
+
@distance.metric?.should be_true
|
318
|
+
@distance.to_s.should == "#{@km.to_i} #{Barometer::Distance::METRIC_UNITS}"
|
319
|
+
|
320
|
+
@distance.imperial!
|
321
|
+
@distance.metric?.should be_false
|
322
|
+
@distance.to_s.should == "#{@m.to_i} #{Barometer::Distance::IMPERIAL_UNITS}"
|
323
|
+
end
|
324
|
+
|
325
|
+
it "returns just the units" do
|
326
|
+
@distance.metric?.should be_true
|
327
|
+
@distance.units.should == Barometer::Distance::METRIC_UNITS
|
328
|
+
|
329
|
+
@distance.imperial!
|
330
|
+
@distance.metric?.should be_false
|
331
|
+
@distance.units.should == Barometer::Distance::IMPERIAL_UNITS
|
332
|
+
end
|
333
|
+
|
334
|
+
end
|
335
|
+
|
336
|
+
end
|
@@ -0,0 +1,150 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Forecast Measurement" do
|
4
|
+
|
5
|
+
describe "when initialized" do
|
6
|
+
|
7
|
+
before(:each) do
|
8
|
+
@forecast = Barometer::ForecastMeasurement.new
|
9
|
+
end
|
10
|
+
|
11
|
+
it "responds to date" do
|
12
|
+
@forecast.date.should be_nil
|
13
|
+
end
|
14
|
+
|
15
|
+
it "responds to icon" do
|
16
|
+
@forecast.icon.should be_nil
|
17
|
+
end
|
18
|
+
|
19
|
+
it "responds to condition" do
|
20
|
+
@forecast.condition.should be_nil
|
21
|
+
end
|
22
|
+
|
23
|
+
it "responds to low" do
|
24
|
+
@forecast.low.should be_nil
|
25
|
+
end
|
26
|
+
|
27
|
+
it "responds to high" do
|
28
|
+
@forecast.high.should be_nil
|
29
|
+
end
|
30
|
+
|
31
|
+
it "responds to pop" do
|
32
|
+
@forecast.pop.should be_nil
|
33
|
+
end
|
34
|
+
|
35
|
+
it "responds to sun" do
|
36
|
+
@forecast.sun.should be_nil
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
describe "when writing data" do
|
42
|
+
|
43
|
+
before(:each) do
|
44
|
+
@forecast = Barometer::ForecastMeasurement.new
|
45
|
+
end
|
46
|
+
|
47
|
+
it "only accepts Date for date" do
|
48
|
+
invalid_data = 1
|
49
|
+
invalid_data.class.should_not == Date
|
50
|
+
lambda { @forecast.date = invalid_data }.should raise_error(ArgumentError)
|
51
|
+
|
52
|
+
valid_data = Date.new
|
53
|
+
valid_data.class.should == Date
|
54
|
+
lambda { @forecast.date = valid_data }.should_not raise_error(ArgumentError)
|
55
|
+
end
|
56
|
+
|
57
|
+
it "only accepts String for icon" do
|
58
|
+
invalid_data = 1
|
59
|
+
invalid_data.class.should_not == String
|
60
|
+
lambda { @forecast.icon = invalid_data }.should raise_error(ArgumentError)
|
61
|
+
|
62
|
+
valid_data = "valid"
|
63
|
+
valid_data.class.should == String
|
64
|
+
lambda { @forecast.icon = valid_data }.should_not raise_error(ArgumentError)
|
65
|
+
end
|
66
|
+
|
67
|
+
it "only accepts String for condition" do
|
68
|
+
invalid_data = 1
|
69
|
+
invalid_data.class.should_not == String
|
70
|
+
lambda { @forecast.condition = invalid_data }.should raise_error(ArgumentError)
|
71
|
+
|
72
|
+
valid_data = "valid"
|
73
|
+
valid_data.class.should == String
|
74
|
+
lambda { @forecast.condition = valid_data }.should_not raise_error(ArgumentError)
|
75
|
+
end
|
76
|
+
|
77
|
+
it "only accepts Barometer::Temperature for high" do
|
78
|
+
invalid_data = 1
|
79
|
+
invalid_data.class.should_not == Barometer::Temperature
|
80
|
+
lambda { @forecast.high = invalid_data }.should raise_error(ArgumentError)
|
81
|
+
|
82
|
+
valid_data = Barometer::Temperature.new
|
83
|
+
valid_data.class.should == Barometer::Temperature
|
84
|
+
lambda { @forecast.high = valid_data }.should_not raise_error(ArgumentError)
|
85
|
+
end
|
86
|
+
|
87
|
+
it "only accepts Barometer::Temperature for low" do
|
88
|
+
invalid_data = 1
|
89
|
+
invalid_data.class.should_not == Barometer::Temperature
|
90
|
+
lambda { @forecast.low = invalid_data }.should raise_error(ArgumentError)
|
91
|
+
|
92
|
+
valid_data = Barometer::Temperature.new
|
93
|
+
valid_data.class.should == Barometer::Temperature
|
94
|
+
lambda { @forecast.low = valid_data }.should_not raise_error(ArgumentError)
|
95
|
+
end
|
96
|
+
|
97
|
+
it "only accepts Fixnum for pop" do
|
98
|
+
invalid_data = "test"
|
99
|
+
invalid_data.class.should_not == Fixnum
|
100
|
+
lambda { @forecast.pop = invalid_data }.should raise_error(ArgumentError)
|
101
|
+
|
102
|
+
valid_data = 50
|
103
|
+
valid_data.class.should == Fixnum
|
104
|
+
lambda { @forecast.pop = valid_data }.should_not raise_error(ArgumentError)
|
105
|
+
end
|
106
|
+
|
107
|
+
it "only accepts Barometer::Sun for sun" do
|
108
|
+
invalid_data = 1
|
109
|
+
invalid_data.class.should_not == Barometer::Sun
|
110
|
+
lambda { @forecast.sun = invalid_data }.should raise_error(ArgumentError)
|
111
|
+
|
112
|
+
valid_data = Barometer::Sun.new
|
113
|
+
valid_data.class.should == Barometer::Sun
|
114
|
+
lambda { @forecast.sun = valid_data }.should_not raise_error(ArgumentError)
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
118
|
+
|
119
|
+
describe "method missing" do
|
120
|
+
|
121
|
+
before(:each) do
|
122
|
+
@forecast = Barometer::ForecastMeasurement.new
|
123
|
+
end
|
124
|
+
|
125
|
+
it "responds to method + ?" do
|
126
|
+
valid_method = "pop"
|
127
|
+
@forecast.respond_to?(valid_method).should be_true
|
128
|
+
lambda { @forecast.send(valid_method + "?") }.should_not raise_error(NoMethodError)
|
129
|
+
end
|
130
|
+
|
131
|
+
it "ignores non_method + ?" do
|
132
|
+
invalid_method = "humid"
|
133
|
+
@forecast.respond_to?(invalid_method).should be_false
|
134
|
+
lambda { @forecast.send(invalid_method + "?") }.should raise_error(NoMethodError)
|
135
|
+
end
|
136
|
+
|
137
|
+
it "returns true if set" do
|
138
|
+
@forecast.pop = 10
|
139
|
+
@forecast.pop.should_not be_nil
|
140
|
+
@forecast.pop?.should be_true
|
141
|
+
end
|
142
|
+
|
143
|
+
it "returns false if not set" do
|
144
|
+
@forecast.pop.should be_nil
|
145
|
+
@forecast.pop?.should be_false
|
146
|
+
end
|
147
|
+
|
148
|
+
end
|
149
|
+
|
150
|
+
end
|