rubygame 2.1.0 → 2.2.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/CREDITS +10 -0
- data/{Changelog → NEWS} +39 -0
- data/README +25 -8
- data/{TODO → ROADMAP} +7 -9
- data/Rakefile +151 -122
- data/doc/macosx_install.rdoc +2 -6
- data/doc/windows_install.rdoc +11 -12
- data/ext/rubygame/rubygame_gfx.c +13 -22
- data/ext/rubygame/rubygame_gfx.h +0 -1
- data/ext/rubygame/rubygame_screen.c +29 -1
- data/ext/rubygame/rubygame_screen.h +2 -0
- data/ext/rubygame/rubygame_shared.c +57 -0
- data/ext/rubygame/rubygame_shared.h +6 -0
- data/ext/rubygame/rubygame_surface.c +58 -18
- data/ext/rubygame/rubygame_ttf.c +18 -19
- data/lib/rubygame.rb +1 -0
- data/lib/rubygame/color.rb +79 -0
- data/lib/rubygame/color/models/base.rb +106 -0
- data/lib/rubygame/color/models/hsl.rb +153 -0
- data/lib/rubygame/color/models/hsv.rb +149 -0
- data/lib/rubygame/color/models/rgb.rb +78 -0
- data/lib/rubygame/color/palettes/css.rb +49 -0
- data/lib/rubygame/color/palettes/palette.rb +100 -0
- data/lib/rubygame/color/palettes/x11.rb +177 -0
- data/lib/rubygame/rect.rb +2 -4
- data/lib/rubygame/sprite.rb +42 -8
- data/samples/demo_rubygame.rb +12 -7
- data/samples/song.ogg +0 -0
- metadata +18 -6
data/lib/rubygame.rb
CHANGED
@@ -0,0 +1,79 @@
|
|
1
|
+
#--
|
2
|
+
# Rubygame -- Ruby code and bindings to SDL to facilitate game creation
|
3
|
+
# Copyright (C) 2007 John Croisant
|
4
|
+
#
|
5
|
+
# This library is free software; you can redistribute it and/or
|
6
|
+
# modify it under the terms of the GNU Lesser General Public
|
7
|
+
# License as published by the Free Software Foundation; either
|
8
|
+
# version 2.1 of the License, or (at your option) any later version.
|
9
|
+
#
|
10
|
+
# This library is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
13
|
+
# Lesser General Public License for more details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU Lesser General Public
|
16
|
+
# License along with this library; if not, write to the Free Software
|
17
|
+
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
18
|
+
#++
|
19
|
+
|
20
|
+
require 'rubygame/color/models/base'
|
21
|
+
require 'rubygame/color/models/rgb'
|
22
|
+
require 'rubygame/color/models/hsv'
|
23
|
+
require 'rubygame/color/models/hsl'
|
24
|
+
|
25
|
+
require 'rubygame/color/palettes/palette'
|
26
|
+
require 'rubygame/color/palettes/x11'
|
27
|
+
require 'rubygame/color/palettes/css'
|
28
|
+
|
29
|
+
module Rubygame
|
30
|
+
|
31
|
+
# The Color module contains classes related to colors.
|
32
|
+
#
|
33
|
+
# Available color representations:
|
34
|
+
#
|
35
|
+
# ColorRGB:: color class with red, green, and blue components.
|
36
|
+
# ColorHSV:: color class with hue, saturation, and value components.
|
37
|
+
# ColorHSL:: color class with hue, saturation, and luminosity components.
|
38
|
+
#
|
39
|
+
# The Palette class allows you to conveniently store and access a
|
40
|
+
# collection of many different colors, with inheritance from
|
41
|
+
# included Palettes.
|
42
|
+
#
|
43
|
+
# The available predefined palettes are:
|
44
|
+
#
|
45
|
+
# X11:: palette with the default X11 colors
|
46
|
+
# CSS:: palette used with HTML and CSS, very similar to X11
|
47
|
+
# GLOBAL:: special palette used for automatic lookup (see below)
|
48
|
+
#
|
49
|
+
# The GLOBAL palette is special; it is used for automatic color lookup
|
50
|
+
# in functions like Surface#draw_circle and TTF#render.It includes the
|
51
|
+
# CSS palette by default; you can include other palettes or define new
|
52
|
+
# custom colors in GLOBAL to make them available for automatic lookup.
|
53
|
+
#
|
54
|
+
# For convenience, you can access the GLOBAL palette through the
|
55
|
+
# #[] and #[]= methods:
|
56
|
+
#
|
57
|
+
# include Rubygame
|
58
|
+
# player_color = Color[:red]
|
59
|
+
# Color[:favorite] = Color[:azure]
|
60
|
+
#
|
61
|
+
module Color
|
62
|
+
|
63
|
+
(GLOBAL = Palette.new()).include(CSS) # :nodoc:
|
64
|
+
|
65
|
+
# Retrieve a color from the GLOBAL palette.
|
66
|
+
# See Palette#[]
|
67
|
+
def self.[]( name )
|
68
|
+
GLOBAL[name]
|
69
|
+
end
|
70
|
+
|
71
|
+
# Store a color in the GLOBAL palette.
|
72
|
+
# See Palette#[]=
|
73
|
+
def self.[]=( name, color )
|
74
|
+
GLOBAL[name] = color
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
@@ -0,0 +1,106 @@
|
|
1
|
+
#--
|
2
|
+
# Rubygame -- Ruby code and bindings to SDL to facilitate game creation
|
3
|
+
# Copyright (C) 2007 John Croisant
|
4
|
+
#
|
5
|
+
# This library is free software; you can redistribute it and/or
|
6
|
+
# modify it under the terms of the GNU Lesser General Public
|
7
|
+
# License as published by the Free Software Foundation; either
|
8
|
+
# version 2.1 of the License, or (at your option) any later version.
|
9
|
+
#
|
10
|
+
# This library is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
13
|
+
# Lesser General Public License for more details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU Lesser General Public
|
16
|
+
# License along with this library; if not, write to the Free Software
|
17
|
+
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
18
|
+
#++
|
19
|
+
|
20
|
+
|
21
|
+
# A mix-in module defining color arithmetic operations.
|
22
|
+
module ColorBase
|
23
|
+
|
24
|
+
# Perform color addition with another color of any type.
|
25
|
+
# The alpha of the new color will be equal to the alpha
|
26
|
+
# of the receiver.
|
27
|
+
def +(other)
|
28
|
+
wrap( simple_op(other) { |a,b| a + b } )
|
29
|
+
end
|
30
|
+
|
31
|
+
# Perform color subtraction with another color of any type.
|
32
|
+
# The alpha of the new color will be equal to the alpha
|
33
|
+
# of the receiver.
|
34
|
+
def -(other)
|
35
|
+
wrap( simple_op(other) { |a,b| a - b } )
|
36
|
+
end
|
37
|
+
|
38
|
+
# Perform color multiplication with another color of any type.
|
39
|
+
# The alpha of the new color will be equal to the alpha
|
40
|
+
# of the receiver.
|
41
|
+
def *(other)
|
42
|
+
wrap( simple_op(other) { |a,b| a * b } )
|
43
|
+
end
|
44
|
+
|
45
|
+
# Perform color division with another color of any type.
|
46
|
+
# The alpha of the new color will be equal to the alpha
|
47
|
+
# of the receiver.
|
48
|
+
def /(other)
|
49
|
+
wrap( simple_op(other) { |a,b| a / b } )
|
50
|
+
end
|
51
|
+
|
52
|
+
# Layer this color over another color.
|
53
|
+
def over(other)
|
54
|
+
c1, c2 = self.to_rgba_ary, other.to_rgba_ary
|
55
|
+
a1, a2 = c1[3], c2[3]
|
56
|
+
|
57
|
+
rgba = [0,1,2].collect do |i|
|
58
|
+
clamp( a1*c1.at(i) + a2*c2.at(i)*(1-a1) )
|
59
|
+
end
|
60
|
+
|
61
|
+
rgba << ( a1 + a2*(1-a1) )
|
62
|
+
|
63
|
+
wrap( rgba )
|
64
|
+
end
|
65
|
+
|
66
|
+
# Average this color with another color. (Linear weighted average)
|
67
|
+
#
|
68
|
+
# A weight of 0.0 means 0% of this color, 100% of the other.
|
69
|
+
# A weight of 1.0 means 100% of this color, 0% of the other.
|
70
|
+
# A weight of 0.5 means 50% of each color.
|
71
|
+
#
|
72
|
+
def average(other, weight=0.5)
|
73
|
+
c1, c2 = self.to_rgba_ary, other.to_rgba_ary
|
74
|
+
|
75
|
+
rgba = [0,1,2,3].collect do |i|
|
76
|
+
clamp( c1.at(i)*weight + c2.at(i)*(1-weight) )
|
77
|
+
end
|
78
|
+
|
79
|
+
wrap( rgba )
|
80
|
+
end
|
81
|
+
|
82
|
+
private
|
83
|
+
|
84
|
+
def wrap( rgba )
|
85
|
+
self.class.new_from_rgba( rgba )
|
86
|
+
end
|
87
|
+
|
88
|
+
def simple_op(other, &block)
|
89
|
+
c1, c2 = self.to_rgba_ary, other.to_rgba_ary
|
90
|
+
a1, a2 = c1[3], c2[3]
|
91
|
+
|
92
|
+
rgba = [0,1,2].collect do |i|
|
93
|
+
clamp( block.call( a1*c1.at(i), a2*c2.at(i) ) )
|
94
|
+
end
|
95
|
+
|
96
|
+
rgba << a1
|
97
|
+
|
98
|
+
return rgba
|
99
|
+
end
|
100
|
+
|
101
|
+
def clamp(v, min=0.0, max=1.0)
|
102
|
+
v = min if v < min
|
103
|
+
v = max if v > max
|
104
|
+
return v
|
105
|
+
end
|
106
|
+
end
|
@@ -0,0 +1,153 @@
|
|
1
|
+
#--
|
2
|
+
# Rubygame -- Ruby code and bindings to SDL to facilitate game creation
|
3
|
+
# Copyright (C) 2007 John Croisant
|
4
|
+
#
|
5
|
+
# This library is free software; you can redistribute it and/or
|
6
|
+
# modify it under the terms of the GNU Lesser General Public
|
7
|
+
# License as published by the Free Software Foundation; either
|
8
|
+
# version 2.1 of the License, or (at your option) any later version.
|
9
|
+
#
|
10
|
+
# This library is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
13
|
+
# Lesser General Public License for more details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU Lesser General Public
|
16
|
+
# License along with this library; if not, write to the Free Software
|
17
|
+
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
18
|
+
#++
|
19
|
+
|
20
|
+
require 'rubygame/color/models/base'
|
21
|
+
|
22
|
+
module Rubygame
|
23
|
+
module Color
|
24
|
+
|
25
|
+
# Represents color in the HSL (Hue, Saturation, Luminosity) color space.
|
26
|
+
class ColorHSL
|
27
|
+
include ColorBase
|
28
|
+
|
29
|
+
attr_reader :h, :s, :l, :a
|
30
|
+
|
31
|
+
# call-seq:
|
32
|
+
# new( [h,s,l,a] ) -> ColorHSL
|
33
|
+
# new( [h,s,l] ) -> ColorHSL
|
34
|
+
# new( color ) -> ColorHSL
|
35
|
+
#
|
36
|
+
# Create a new instance from an Array or an existing color
|
37
|
+
# (of any type). If the alpha (opacity) component is omitted
|
38
|
+
# from the array, full opacity will be used.
|
39
|
+
#
|
40
|
+
# All color components range from 0.0 to 1.0.
|
41
|
+
#
|
42
|
+
def initialize( color )
|
43
|
+
if color.kind_of?(Array)
|
44
|
+
@h, @s, @l, @a = color.collect { |i| i.to_f }
|
45
|
+
@a = 1.0 unless @a
|
46
|
+
elsif color.respond_to?(:to_rgba_ary)
|
47
|
+
@h, @s, @l, @a = self.class.rgba_to_hsla( *color.to_rgba_ary )
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Return an Array with the red, green, blue, and alpha components
|
52
|
+
# of the color (converting the color to the RGBA model first).
|
53
|
+
def to_rgba_ary
|
54
|
+
return self.class.hsla_to_rgba( @h, @s, @l, @a )
|
55
|
+
end
|
56
|
+
|
57
|
+
def to_s
|
58
|
+
"#<#{self.class} [#{@h}, #{@s}, #{@l}, #{@a}]>"
|
59
|
+
end
|
60
|
+
alias :inspect :to_s
|
61
|
+
|
62
|
+
class << self
|
63
|
+
|
64
|
+
def new_from_rgba( rgba )
|
65
|
+
new( rgba_to_hsla(*rgba) )
|
66
|
+
end
|
67
|
+
|
68
|
+
def new_from_sdl_rgba( rgba )
|
69
|
+
new_from_rgba( rgba.collect { |i| i / 255.0 } )
|
70
|
+
end
|
71
|
+
|
72
|
+
# Convert the red, green, blue, and alpha to the
|
73
|
+
# equivalent hue, saturation, luminosity, and alpha.
|
74
|
+
def rgba_to_hsla( r, g, b, a ) # :nodoc:
|
75
|
+
rgb_arr = [r, g, b]
|
76
|
+
max = rgb_arr.max
|
77
|
+
min = rgb_arr.min
|
78
|
+
|
79
|
+
# Calculate lightness.
|
80
|
+
l = (max + min) / 2.0
|
81
|
+
|
82
|
+
# Calculate saturation.
|
83
|
+
if l == 0.0 or max == min
|
84
|
+
s = 0
|
85
|
+
elsif 0 < l and l <= 0.5
|
86
|
+
s = (max - min) / (max + min)
|
87
|
+
else # l > 0.5
|
88
|
+
s = (max - min) / (2 - (max + min))
|
89
|
+
end
|
90
|
+
|
91
|
+
# Calculate hue.
|
92
|
+
if min == max
|
93
|
+
h = 0
|
94
|
+
# Undefined in this case, but set it to zero
|
95
|
+
elsif max == r and g >= b
|
96
|
+
h = (1.quo(6) * (g - b) / (max - min)) + 0
|
97
|
+
elsif max == r and g < b
|
98
|
+
h = (1.quo(6) * (g - b) / (max - min)) + 1.0
|
99
|
+
elsif max == g
|
100
|
+
h = (1.quo(6) * (b - r) / (max - min)) + 1.quo(3)
|
101
|
+
elsif max == b
|
102
|
+
h = (1.quo(6) * (r - g) / (max - min)) + 2.quo(3)
|
103
|
+
else
|
104
|
+
raise "Should never happen"
|
105
|
+
end
|
106
|
+
|
107
|
+
return [h,s,l,a]
|
108
|
+
end
|
109
|
+
|
110
|
+
# Convert the hue, saturation, luminosity, and alpha
|
111
|
+
# to the equivalent red, green, blue, and alpha.
|
112
|
+
def hsla_to_rgba( h, s, l, a ) # :nodoc:
|
113
|
+
# If the color is achromatic, return already with the lightness value for all components
|
114
|
+
if s == 0.0
|
115
|
+
return [l, l, l, a]
|
116
|
+
end
|
117
|
+
|
118
|
+
# Otherwise, we have to do the long, hard calculation
|
119
|
+
|
120
|
+
# q helper value
|
121
|
+
q = (l < 0.5) ? (l * (1.0 + s)) : (l + s - l * s)
|
122
|
+
|
123
|
+
# p helper value
|
124
|
+
p = (2.0 * l) - q
|
125
|
+
|
126
|
+
r = calculate_component( p, q, h + 1.quo(3) )
|
127
|
+
g = calculate_component( p, q, h )
|
128
|
+
b = calculate_component( p, q, h - 1.quo(3) )
|
129
|
+
|
130
|
+
return [r,g,b,a]
|
131
|
+
end
|
132
|
+
|
133
|
+
private
|
134
|
+
|
135
|
+
# Perform some arcane math to calculate a color component.
|
136
|
+
def calculate_component(p, q, tc) # :nodoc:
|
137
|
+
tc %= 1.0
|
138
|
+
if tc < 1.quo(6)
|
139
|
+
p + (q - p) * tc * 6.0
|
140
|
+
elsif tc < 0.5
|
141
|
+
q
|
142
|
+
elsif tc < 2.quo(3)
|
143
|
+
p + (q - p) * (2.quo(3) - tc) * 6.0
|
144
|
+
else
|
145
|
+
p
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
end
|
150
|
+
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
@@ -0,0 +1,149 @@
|
|
1
|
+
#--
|
2
|
+
# Rubygame -- Ruby code and bindings to SDL to facilitate game creation
|
3
|
+
# Copyright (C) 2007 John Croisant
|
4
|
+
#
|
5
|
+
# This library is free software; you can redistribute it and/or
|
6
|
+
# modify it under the terms of the GNU Lesser General Public
|
7
|
+
# License as published by the Free Software Foundation; either
|
8
|
+
# version 2.1 of the License, or (at your option) any later version.
|
9
|
+
#
|
10
|
+
# This library is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
13
|
+
# Lesser General Public License for more details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU Lesser General Public
|
16
|
+
# License along with this library; if not, write to the Free Software
|
17
|
+
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
18
|
+
#++
|
19
|
+
|
20
|
+
require 'rubygame/color/models/base'
|
21
|
+
|
22
|
+
module Rubygame
|
23
|
+
module Color
|
24
|
+
|
25
|
+
# Represents color in the HSV (Hue, Saturation, Value) color space.
|
26
|
+
class ColorHSV
|
27
|
+
include ColorBase
|
28
|
+
|
29
|
+
attr_reader :h, :s, :v, :a
|
30
|
+
|
31
|
+
# call-seq:
|
32
|
+
# new( [h,s,v,a] ) -> ColorHSV
|
33
|
+
# new( [h,s,v] ) -> ColorHSV
|
34
|
+
# new( color ) -> ColorHSV
|
35
|
+
#
|
36
|
+
# Create a new instance from an Array or an existing color
|
37
|
+
# (of any type). If the alpha (opacity) component is omitted
|
38
|
+
# from the array, full opacity will be used.
|
39
|
+
#
|
40
|
+
# All color components range from 0.0 to 1.0.
|
41
|
+
#
|
42
|
+
def initialize( color )
|
43
|
+
if color.kind_of?(Array)
|
44
|
+
@h, @s, @v, @a = color.collect { |i| i.to_f }
|
45
|
+
@a = 1.0 unless @a
|
46
|
+
elsif color.respond_to?(:to_rgba_ary)
|
47
|
+
@h, @s, @v, @a = self.class.rgba_to_hsva( *color.to_rgba_ary )
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Return an Array with the red, green, blue, and alpha components
|
52
|
+
# of the color (converting the color to the RGBA model first).
|
53
|
+
def to_rgba_ary
|
54
|
+
return self.class.hsva_to_rgba( @h, @s, @v, @a )
|
55
|
+
end
|
56
|
+
|
57
|
+
def to_s
|
58
|
+
"#<#{self.class} [#{@h}, #{@s}, #{@v}, #{@a}]>"
|
59
|
+
end
|
60
|
+
alias :inspect :to_s
|
61
|
+
|
62
|
+
class << self
|
63
|
+
|
64
|
+
def new_from_rgba( rgba )
|
65
|
+
new( rgba_to_hsva(*rgba) )
|
66
|
+
end
|
67
|
+
|
68
|
+
def new_from_sdl_rgba( rgba )
|
69
|
+
new_from_rgba( rgba.collect { |i| i / 255.0 } )
|
70
|
+
end
|
71
|
+
|
72
|
+
# Convert the red, green, blue, and alpha to the
|
73
|
+
# equivalent hue, saturation, value, and alpha.
|
74
|
+
def rgba_to_hsva( r, g, b, a ) # :nodoc:
|
75
|
+
rgb_arr = [r, g, b]
|
76
|
+
max = rgb_arr.max
|
77
|
+
min = rgb_arr.min
|
78
|
+
|
79
|
+
# Calculate hue.
|
80
|
+
if min == max
|
81
|
+
h = 0
|
82
|
+
# Undefined in this case, but set it to zero
|
83
|
+
elsif max == r and g >= b
|
84
|
+
h = (1.quo(6) * (g - b) / (max - min)) + 0
|
85
|
+
elsif max == r and g < b
|
86
|
+
h = (1.quo(6) * (g - b) / (max - min)) + 1.0
|
87
|
+
elsif max == g
|
88
|
+
h = (1.quo(6) * (b - r) / (max - min)) + 1.quo(3)
|
89
|
+
elsif max == b
|
90
|
+
h = (1.quo(6) * (r - g) / (max - min)) + 2.quo(3)
|
91
|
+
else
|
92
|
+
raise "Should never happen"
|
93
|
+
end
|
94
|
+
|
95
|
+
# Calulate value.
|
96
|
+
v = max
|
97
|
+
|
98
|
+
# Calculate saturation.
|
99
|
+
if max == 0.0
|
100
|
+
s = 0.0
|
101
|
+
else
|
102
|
+
s = 1.0 - (min / max)
|
103
|
+
end
|
104
|
+
|
105
|
+
return [h,s,v,a]
|
106
|
+
end
|
107
|
+
|
108
|
+
# Convert the hue, saturation, value, and alpha
|
109
|
+
# to the equivalent red, green, blue, and alpha.
|
110
|
+
def hsva_to_rgba( h, s, v, a ) # :nodoc:
|
111
|
+
# Determine what part of the "color hexagon" the hue is in.
|
112
|
+
hi = (h * 6).floor % 6
|
113
|
+
|
114
|
+
# Fractional part
|
115
|
+
f = (h * 6) - hi
|
116
|
+
|
117
|
+
# Helper values
|
118
|
+
p = v * (1.0 - s)
|
119
|
+
q = v * (1.0 - (f * s))
|
120
|
+
t = v * (1.0 - ((1.0 - f) * s))
|
121
|
+
|
122
|
+
# Finally calculate the rgb values
|
123
|
+
r, g, b = calculate_rgb(hi, v, p, t, q)
|
124
|
+
|
125
|
+
return [r, g, b, a]
|
126
|
+
end
|
127
|
+
|
128
|
+
private
|
129
|
+
|
130
|
+
def calculate_rgb(hi, v, p, t, q) # :nodoc:
|
131
|
+
case hi
|
132
|
+
when 0
|
133
|
+
return v, t, p
|
134
|
+
when 1
|
135
|
+
return q, v, p
|
136
|
+
when 2
|
137
|
+
return p, v, t
|
138
|
+
when 3
|
139
|
+
return p, q, v
|
140
|
+
when 4
|
141
|
+
return t, p, v
|
142
|
+
when 5
|
143
|
+
return v, p, q
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|