robust_excel_ole 1.1.5 → 1.1.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/Changelog +6 -0
  3. data/README.rdoc +2 -2
  4. data/docs/README_excel.rdoc +2 -3
  5. data/docs/README_open.rdoc +8 -12
  6. data/docs/README_ranges.rdoc +21 -9
  7. data/docs/README_sheet.rdoc +1 -1
  8. data/lib/robust_excel_ole/book.rb +3 -23
  9. data/lib/robust_excel_ole/excel.rb +2 -15
  10. data/lib/robust_excel_ole/reo_common.rb +11 -7
  11. data/lib/robust_excel_ole/sheet.rb +36 -15
  12. data/lib/robust_excel_ole/version.rb +1 -1
  13. data/robust_excel_ole.gemspec +1 -1
  14. data/spec/book_spec.rb +1 -1
  15. data/spec/book_specs/book_close_spec.rb +3 -3
  16. data/spec/book_specs/book_misc_spec.rb +25 -1
  17. data/spec/book_specs/book_open_spec.rb +299 -5
  18. data/spec/book_specs/book_sheet_spec.rb +1 -1
  19. data/spec/book_specs/book_unobtr_spec.rb +275 -35
  20. data/spec/data/another_workbook.xls +0 -0
  21. data/spec/data/different_workbook.xls +0 -0
  22. data/spec/data/workbook.xls +0 -0
  23. data/spec/excel_spec.rb +118 -5
  24. data/spec/helpers/key_sender.rb +2 -2
  25. data/spec/reo_common_spec.rb +0 -4
  26. data/spec/sheet_spec.rb +32 -0
  27. data/spec/spec_helper.rb +3 -0
  28. metadata +3 -21
  29. data/spec/ruby1.8.6_rspec2.14/book_spec.rb +0 -1421
  30. data/spec/ruby1.8.6_rspec2.14/book_specs/book_all_spec.rb +0 -22
  31. data/spec/ruby1.8.6_rspec2.14/book_specs/book_close_spec.rb +0 -252
  32. data/spec/ruby1.8.6_rspec2.14/book_specs/book_misc_spec.rb +0 -1070
  33. data/spec/ruby1.8.6_rspec2.14/book_specs/book_open_spec.rb +0 -1855
  34. data/spec/ruby1.8.6_rspec2.14/book_specs/book_save_spec.rb +0 -514
  35. data/spec/ruby1.8.6_rspec2.14/book_specs/book_sheet_spec.rb +0 -395
  36. data/spec/ruby1.8.6_rspec2.14/book_specs/book_subclass_spec.rb +0 -51
  37. data/spec/ruby1.8.6_rspec2.14/book_specs/book_unobtr_spec.rb +0 -1737
  38. data/spec/ruby1.8.6_rspec2.14/bookstore_spec.rb +0 -495
  39. data/spec/ruby1.8.6_rspec2.14/cell_spec.rb +0 -76
  40. data/spec/ruby1.8.6_rspec2.14/cygwin_spec.rb +0 -42
  41. data/spec/ruby1.8.6_rspec2.14/excel_spec.rb +0 -1820
  42. data/spec/ruby1.8.6_rspec2.14/general_spec.rb +0 -212
  43. data/spec/ruby1.8.6_rspec2.14/range_spec.rb +0 -131
  44. data/spec/ruby1.8.6_rspec2.14/reo_common_spec.rb +0 -130
  45. data/spec/ruby1.8.6_rspec2.14/sheet_spec.rb +0 -663
  46. data/spec/ruby1.8.6_rspec2.14/spec_helper.rb +0 -35
@@ -1,663 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
-
3
- require File.join(File.dirname(__FILE__), './spec_helper')
4
-
5
- $VERBOSE = nil
6
-
7
- include RobustExcelOle
8
- include General
9
-
10
- describe Sheet do
11
-
12
- before(:all) do
13
- excel = Excel.new(:reuse => true)
14
- open_books = excel == nil ? 0 : excel.Workbooks.Count
15
- puts "*** open books *** : #{open_books}" if open_books > 0
16
- Excel.kill_all
17
- end
18
-
19
- before do
20
- @dir = create_tmpdir
21
- @simple_file = @dir + '/workbook.xls'
22
- @protected_file = @dir + '/protected_sheet.xls'
23
- @blank_file = @dir + '/book_with_blank.xls'
24
- @merge_file = @dir + '/merge_cells.xls'
25
- @book = Book.open(@simple_file)
26
- @sheet = @book.sheet(1)
27
- end
28
-
29
- after do
30
- @book.close(:if_unsaved => :forget)
31
- Excel.kill_all
32
- rm_tmp(@dir)
33
- end
34
-
35
- describe ".initialize" do
36
- context "when open sheet protected(with password is 'protect')" do
37
- before do
38
- @key_sender = IO.popen 'ruby "' + File.join(File.dirname(__FILE__), '/helpers/key_sender.rb') + '" "Microsoft Office Excel" ' , "w"
39
- @book_protect = Book.open(@protected_file, :visible => true, :read_only => true, :force_excel => :new)
40
- @book_protect.excel.displayalerts = false
41
- @key_sender.puts "{p}{r}{o}{t}{e}{c}{t}{enter}"
42
- @protected_sheet = @book_protect.sheet('protect')
43
- end
44
-
45
- after do
46
- @book_protect.close
47
- @key_sender.close
48
- end
49
-
50
- it "should be a protected sheet" do
51
- @protected_sheet.ProtectContents.should be_true
52
- end
53
-
54
- it "protected sheet can't be write" do
55
- expect { @protected_sheet[1,1] = 'write' }.to raise_error
56
- end
57
- end
58
-
59
- end
60
-
61
- shared_context "sheet 'open book with blank'" do
62
- before do
63
- @book_with_blank = Book.open(@blank_file, :read_only => true)
64
- @sheet_with_blank = @book_with_blank.sheet(1)
65
- end
66
-
67
- after do
68
- @book_with_blank.close
69
- end
70
- end
71
-
72
- describe "workbook" do
73
- before do
74
- @book = Book.open(@simple_file)
75
- @sheet = @book.sheet(1)
76
- end
77
-
78
- after do
79
- @book.close
80
- end
81
-
82
- it "should return workbook" do
83
- @sheet.workbook.should === @book
84
- end
85
-
86
- end
87
-
88
- describe "access sheet name" do
89
- describe "#name" do
90
- it 'get sheet1 name' do
91
- @sheet.name.should eq 'Sheet1'
92
- end
93
- end
94
-
95
- describe "#name=" do
96
-
97
- it 'change sheet1 name to foo' do
98
- @sheet.name = 'foo'
99
- @sheet.name.should eq 'foo'
100
- end
101
-
102
- it "should raise error when adding the same name" do
103
- @sheet.name = 'foo'
104
- @sheet.name.should eq 'foo'
105
- new_sheet = @book.add_sheet @sheet
106
- expect{
107
- new_sheet.name = 'foo'
108
- }.to raise_error(NameAlreadyExists, /sheet name "foo" already exists/)
109
- end
110
- end
111
- end
112
-
113
- describe 'access cell' do
114
-
115
- describe "#[,]" do
116
-
117
- context "access [1,1]" do
118
-
119
- it { @sheet[1, 1].should be_kind_of Cell }
120
- it { @sheet[1, 1].value.should eq 'foo' }
121
- end
122
-
123
- context "access [1, 1], [1, 2], [3, 1]" do
124
- it "should get every values" do
125
- @sheet[1, 1].value.should eq 'foo'
126
- @sheet[1, 2].value.should eq 'workbook'
127
- @sheet[3, 1].value.should eq 'matz'
128
- end
129
- end
130
-
131
- context "supplying nil as parameter" do
132
- it "should access [1,1]" do
133
- @sheet[1, nil].value.should eq 'foo'
134
- @sheet[nil, 1].value.should eq 'foo'
135
- end
136
- end
137
-
138
- end
139
-
140
- it "change a cell to 'bar'" do
141
- @sheet[1, 1] = 'bar'
142
- @sheet[1, 1].value.should eq 'bar'
143
- end
144
-
145
- it "should change a cell to nil" do
146
- @sheet[1, 1] = nil
147
- @sheet[1, 1].value.should eq nil
148
- end
149
-
150
- it "should raise error for bad ranges" do
151
- expect{
152
- @sheet[0,0]
153
- }.to raise_error(RangeNotEvaluatable, "cannot read cell (0,0)")
154
- expect{
155
- @sheet[0,0] = "foo"
156
- }.to raise_error(RangeNotEvaluatable, /cannot assign value/)
157
- end
158
-
159
- describe '#each' do
160
- it "should sort line in order of column" do
161
- @sheet.each_with_index do |cell, i|
162
- case i
163
- when 0
164
- cell.value.should eq 'foo'
165
- when 1
166
- cell.value.should eq 'workbook'
167
- when 2
168
- cell.value.should eq 'sheet1'
169
- when 3
170
- cell.value.should eq 'foo'
171
- when 4
172
- cell.value.should be_nil
173
- when 5
174
- cell.value.should eq 'foobaaa'
175
- end
176
- end
177
- end
178
-
179
- context "read sheet with blank" do
180
- include_context "sheet 'open book with blank'"
181
-
182
- it 'should get from ["A1"]' do
183
- @sheet_with_blank.each_with_index do |cell, i|
184
- case i
185
- when 5
186
- cell.value.should be_nil
187
- when 6
188
- cell.value.should eq 'simple'
189
- when 7
190
- cell.value.should be_nil
191
- when 8
192
- cell.value.should eq 'workbook'
193
- when 9
194
- cell.value.should eq 'sheet1'
195
- end
196
- end
197
- end
198
- end
199
-
200
- end
201
-
202
- describe "#each_row" do
203
- it "items should RobustExcelOle::Range" do
204
- @sheet.each_row do |rows|
205
- rows.should be_kind_of RobustExcelOle::Range
206
- end
207
- end
208
-
209
- context "with argument 1" do
210
- it 'should read from second row' do
211
- @sheet.each_row(1) do |rows|
212
- case rows.row
213
- when 2
214
- rows.values.should eq ['foo', nil, 'foobaaa']
215
- when 3
216
- rows.values.should eq ['matz', 'is', 'nice']
217
- end
218
- end
219
- end
220
- end
221
-
222
- context "read sheet with blank" do
223
- include_context "sheet 'open book with blank'"
224
-
225
- it 'should get from ["A1"]' do
226
- @sheet_with_blank.each_row do |rows|
227
- case rows.row - 1
228
- when 0
229
- rows.values.should eq [nil, nil, nil, nil, nil]
230
- when 1
231
- rows.values.should eq [nil, 'simple', nil, 'workbook', 'sheet1']
232
- when 2
233
- rows.values.should eq [nil, 'foo', nil, nil, 'foobaaa']
234
- when 3
235
- rows.values.should eq [nil, nil, nil, nil, nil]
236
- when 4
237
- rows.values.should eq [nil, 'matz', nil, 'is', 'nice']
238
- end
239
- end
240
- end
241
- end
242
-
243
- end
244
-
245
- describe "#each_row_with_index" do
246
- it "should read with index" do
247
- @sheet.each_row_with_index do |rows, idx|
248
- case idx
249
- when 0
250
- rows.values.should eq ['foo', 'workbook', 'sheet1']
251
- when 1
252
- rows.values.should eq ['foo', nil, 'foobaaa']
253
- when 2
254
- rows.values.should eq ['matz', 'is', 'nice']
255
- end
256
- end
257
- end
258
-
259
- context "with argument 1" do
260
- it "should read from second row, index is started 0" do
261
- @sheet.each_row_with_index(1) do |rows, idx|
262
- case idx
263
- when 0
264
- rows.values.should eq ['foo', nil, 'foobaaa']
265
- when 1
266
- rows.values.should eq ['matz', 'is', 'nice']
267
- end
268
- end
269
- end
270
- end
271
-
272
- end
273
-
274
- describe "#each_column" do
275
- it "items should RobustExcelOle::Range" do
276
- @sheet.each_column do |columns|
277
- columns.should be_kind_of RobustExcelOle::Range
278
- end
279
- end
280
-
281
- context "with argument 1" do
282
- it "should read from second column" do
283
- @sheet.each_column(1) do |columns|
284
- case columns.column
285
- when 2
286
- columns.values.should eq ['workbook', nil, 'is']
287
- when 3
288
- columns.values.should eq ['sheet1', 'foobaaa', 'nice']
289
- end
290
- end
291
- end
292
- end
293
-
294
- context "read sheet with blank" do
295
- include_context "sheet 'open book with blank'"
296
-
297
- it 'should get from ["A1"]' do
298
- @sheet_with_blank.each_column do |columns|
299
- case columns.column- 1
300
- when 0
301
- columns.values.should eq [nil, nil, nil, nil, nil]
302
- when 1
303
- columns.values.should eq [nil, 'simple', 'foo', nil, 'matz']
304
- when 2
305
- columns.values.should eq [nil, nil, nil, nil, nil]
306
- when 3
307
- columns.values.should eq [nil, 'workbook', nil, nil, 'is']
308
- when 4
309
- columns.values.should eq [nil, 'sheet1', 'foobaaa', nil, 'nice']
310
- end
311
- end
312
- end
313
- end
314
-
315
- context "read sheet which last cell is merged" do
316
- before do
317
- @book_merge_cells = Book.open(@merge_file)
318
- @sheet_merge_cell = @book_merge_cells.sheet(1)
319
- end
320
-
321
- after do
322
- @book_merge_cells.close
323
- end
324
-
325
- it "should get from ['A1'] to ['C2']" do
326
- columns_values = []
327
- @sheet_merge_cell.each_column do |columns|
328
- columns_values << columns.values
329
- end
330
- columns_values.should eq [
331
- [nil, 'first merged', nil, 'merged'],
332
- [nil, 'first merged', 'first', 'merged'],
333
- [nil, 'first merged', 'second', 'merged'],
334
- [nil, nil, 'third', 'merged']
335
- ]
336
- end
337
- end
338
- end
339
-
340
- describe "#each_column_with_index" do
341
- it "should read with index" do
342
- @sheet.each_column_with_index do |columns, idx|
343
- case idx
344
- when 0
345
- columns.values.should eq ['foo', 'foo', 'matz']
346
- when 1
347
- columns.values.should eq ['workbook', nil, 'is']
348
- when 2
349
- columns.values.should eq ['sheet1', 'foobaaa', 'nice']
350
- end
351
- end
352
- end
353
-
354
- context "with argument 1" do
355
- it "should read from second column, index is started 0" do
356
- @sheet.each_column_with_index(1) do |column_range, idx|
357
- case idx
358
- when 0
359
- column_range.values.should eq ['workbook', nil, 'is']
360
- when 1
361
- column_range.values.should eq ['sheet1', 'foobaaa', 'nice']
362
- end
363
- end
364
- end
365
- end
366
- end
367
-
368
- describe "#row_range" do
369
- context "with second argument" do
370
- before do
371
- @row_range = @sheet.row_range(1, 2..3)
372
- end
373
-
374
- it { @row_range.should be_kind_of RobustExcelOle::Range }
375
-
376
- it "should get range cells of second argument" do
377
- @row_range.values.should eq ['workbook', 'sheet1']
378
- end
379
- end
380
-
381
- context "without second argument" do
382
- before do
383
- @row_range = @sheet.row_range(3)
384
- end
385
-
386
- it "should get all cells" do
387
- @row_range.values.should eq ['matz', 'is', 'nice']
388
- end
389
- end
390
-
391
- end
392
-
393
- describe "#col_range" do
394
- context "with second argument" do
395
- before do
396
- @col_range = @sheet.col_range(1, 2..3)
397
- end
398
-
399
- it { @col_range.should be_kind_of RobustExcelOle::Range }
400
-
401
- it "should get range cells of second argument" do
402
- @col_range.values.should eq ['foo', 'matz']
403
- end
404
- end
405
-
406
- context "without second argument" do
407
- before do
408
- @col_range = @sheet.col_range(2)
409
- end
410
-
411
- it "should get all cells" do
412
- @col_range.values.should eq ['workbook', nil, 'is']
413
- end
414
- end
415
- end
416
-
417
- describe "[], []=" do
418
- before do
419
- @book1 = Book.open(@dir + '/another_workbook.xls')
420
- @sheet1 = @book1.sheet(1)
421
- end
422
-
423
- after do
424
- @book1.close(:if_unsaved => :forget)
425
- end
426
-
427
- it "should return value of a defined name" do
428
- @sheet1["firstcell"].should == "foo"
429
- end
430
-
431
- it "should return value of a defined name" do
432
- @sheet1["new"].should == "foo"
433
- @sheet1["one"].should == 1.0
434
- @sheet1["four"].should == [[1,2],[3,4]]
435
- @sheet1["firstrow"].should == [[1,2]]
436
- end
437
-
438
- it "should return value of a name with coordinates" do
439
- @sheet1["A1"].should == "foo"
440
- end
441
-
442
- it "should return nil for a range with empty contents" do
443
- @sheet1["another"].should == nil
444
- end
445
-
446
- #it "should evaluate named formula" do
447
- # @sheet1["named_formula"].should == 4
448
- #end
449
-
450
- #it "should evaluate a formula" do
451
- # @sheet1["another_formula"].should == 5
452
- #end
453
-
454
- it "should raise an error if name not defined" do
455
- expect {
456
- @sheet1["foo"]
457
- }.to raise_error(NameNotFound, /name "foo" not in #<Sheet: Sheet1/)
458
- end
459
-
460
- it "should set a range to a value" do
461
- @sheet1[1,1].Value.should == "foo"
462
- @sheet1["firstcell"] = "bar"
463
- @sheet1[1,1].Value.should == "bar"
464
- @sheet1["new"] = "bar"
465
- @sheet1["new"].should == "bar"
466
- end
467
-
468
- it "should raise an error if name cannot be evaluated" do
469
- expect{
470
- @sheet1["foo"] = 1
471
- }.to raise_error(NameNotFound, /name "foo" not in #<Sheet: Sheet1/)
472
- end
473
- end
474
-
475
- describe "nameval, set_nameval" do
476
-
477
- before do
478
- @book1 = Book.open(@dir + '/another_workbook.xls')
479
- @sheet1 = @book1.sheet(1)
480
- end
481
-
482
- after do
483
- @book1.close(:if_unsaved => :forget)
484
- end
485
-
486
- it "should return value of a defined name" do
487
- @sheet1.nameval("firstcell").should == "foo"
488
- end
489
-
490
- #it "should evaluate a formula" do
491
- # @sheet1.nameval("another_formula").should == 5
492
- #end
493
-
494
- it "should raise an error if name not defined" do
495
- expect {
496
- @sheet1.nameval("foo")
497
- }.to raise_error(NameNotFound, /name "foo" not in/)
498
- end
499
-
500
- it "should raise an error of coordinates are given instead of a defined name" do
501
- expect {
502
- @sheet1.nameval("A1")
503
- }.to raise_error(NameNotFound, /name "A1" not in #<Sheet: Sheet1/)
504
- end
505
-
506
- it "should return default value for a range with empty contents" do
507
- @sheet1.nameval("another", :default => 2) == 2
508
- end
509
-
510
- it "should set a range to a value" do
511
- @sheet1.nameval("firstcell").should == "foo"
512
- @sheet1[1,1].Value.should == "foo"
513
- @sheet1.set_nameval("firstcell","bar")
514
- @sheet1.nameval("firstcell").should == "bar"
515
- @sheet1[1,1].Value.should == "bar"
516
- end
517
-
518
- it "should raise an error if name cannot be evaluated" do
519
- expect{
520
- @sheet1.set_nameval("foo", 1)
521
- }.to raise_error(NameNotFound, /name "foo" not in #<Sheet: Sheet1/)
522
- end
523
- end
524
-
525
- describe "rangeval, set_rangeval" do
526
-
527
- before do
528
- @book1 = Book.open(@dir + '/another_workbook.xls')
529
- @sheet1 = @book1.sheet(1)
530
- @sheet2 = @book1.sheet(2)
531
- end
532
-
533
- after do
534
- @book1.close(:if_unsaved => :forget)
535
- end
536
-
537
- it "should return value of a locally defined name" do
538
- @sheet1.rangeval("firstcell").should == "foo"
539
- end
540
-
541
- it "should return value of a name with coordinates" do
542
- @sheet1.rangeval("A1").should == "foo"
543
- end
544
-
545
- it "should return nil for a range with empty contents" do
546
- @sheet1.rangeval("another").should == nil
547
- end
548
-
549
- it "should return value of a defined name" do
550
- @sheet1.rangeval("new").should == "foo"
551
- @sheet1.rangeval("one").should == 1.0
552
- @sheet1.rangeval("four").should == [[1,2],[3,4]]
553
- @sheet1.rangeval("firstrow").should == [[1,2]]
554
- end
555
-
556
- it "should return default value if name not defined and default value is given" do
557
- @sheet1.rangeval("foo", :default => 2).should == 2
558
- end
559
-
560
- it "should raise an error if name not defined for the sheet" do
561
- expect {
562
- @sheet1.rangeval("foo")
563
- }.to raise_error(NameNotFound, /name "foo" not in #<Sheet: Sheet1/)
564
- expect {
565
- @sheet1.rangeval("named_formula")
566
- }.to raise_error(NameNotFound, /name "named_formula" not in #<Sheet: Sheet1/)
567
- expect {
568
- @sheet2.rangeval("firstcell")
569
- }.to raise_error(NameNotFound, /name "firstcell" not in #<Sheet: Sheet2/)
570
- end
571
-
572
- it "should set a range to a value" do
573
- @sheet1.rangeval("firstcell").should == "foo"
574
- @sheet1[1,1].Value.should == "foo"
575
- @sheet1.set_rangeval("firstcell","bar")
576
- @sheet1.rangeval("firstcell").should == "bar"
577
- @sheet1[1,1].Value.should == "bar"
578
- end
579
-
580
- it "should raise an error if name cannot be evaluated" do
581
- expect{
582
- @sheet1.set_nameval("foo", 1)
583
- }.to raise_error(NameNotFound, /name "foo" not in #<Sheet: Sheet1/)
584
- end
585
-
586
- it "should raise an error if name not defined and default value is not provided" do
587
- expect {
588
- @sheet1.rangeval("foo", :default => nil)
589
- }.to_not raise_error
590
- expect {
591
- @sheet1.rangeval("foo", :default => :__not_provided)
592
- }.to raise_error(NameNotFound, /name "foo" not in #<Sheet: Sheet1 another_workbook/)
593
- expect {
594
- @sheet1.rangeval("foo")
595
- }.to raise_error(NameNotFound, /name "foo" not in #<Sheet: Sheet1 another_workbook/)
596
- @sheet1.rangeval("foo", :default => nil).should be_nil
597
- @sheet1.rangeval("foo", :default => 1).should == 1
598
- @sheet1.nameval("empty", :default => 1).should be_nil
599
- end
600
- end
601
-
602
- describe "set_name" do
603
-
604
- context "setting the name of a range" do
605
-
606
- before do
607
- @book1 = Book.open(@dir + '/another_workbook.xls', :read_only => true, :visible => true)
608
- @book1.excel.displayalerts = false
609
- @sheet1 = @book1.sheet(1)
610
- end
611
-
612
- after do
613
- @book1.close
614
- end
615
-
616
- it "should name an unnamed range with a giving address" do
617
- expect{
618
- @sheet1[1,2].Name.Name
619
- }.to raise_error
620
- @sheet1.set_name("foo",1,2)
621
- @sheet1[1,2].Name.Name.should == "Sheet1!foo"
622
- end
623
-
624
- it "should rename an already named range with a giving address" do
625
- @sheet1[1,1].Name.Name.should == "Sheet1!firstcell"
626
- @sheet1.set_name("foo",1,1)
627
- @sheet1[1,1].Name.Name.should == "Sheet1!foo"
628
- end
629
-
630
- it "should raise an error" do
631
- expect{
632
- @sheet1.set_name("foo",-2,1)
633
- }.to raise_error(RangeNotEvaluatable, /cannot add name "foo" to cell with row -2 and column 1/)
634
- end
635
- end
636
- end
637
-
638
- describe "send methods to worksheet" do
639
-
640
- it "should send methods to worksheet" do
641
- @sheet.Cells(1,1).Value.should eq 'foo'
642
- end
643
-
644
- it "should raise an error for unknown methods or properties" do
645
- expect{
646
- @sheet.Foo
647
- }.to raise_error(VBAMethodMissingError, /unknown VBA property or method :Foo/)
648
- end
649
-
650
- end
651
-
652
- describe "#method_missing" do
653
- it "can access COM method" do
654
- @sheet.Cells(1,1).Value.should eq 'foo'
655
- end
656
-
657
- context "unknown method" do
658
- it { expect { @sheet.hogehogefoo }.to raise_error }
659
- end
660
- end
661
-
662
- end
663
- end