ansible4ozw 0.0.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.
- data/lib/ansible.rb +47 -0
- data/lib/ansible/ansible_callback.rb +142 -0
- data/lib/ansible/ansible_device.rb +68 -0
- data/lib/ansible/ansible_value.rb +179 -0
- data/lib/ansible/config.rb +92 -0
- data/lib/ansible/devices/ansible_dimmer.rb +80 -0
- data/lib/ansible/devices/ansible_switch.rb +66 -0
- data/lib/ansible/knx/EIBConnection.rb +2371 -0
- data/lib/ansible/knx/dpt/canonical_1bit.rb +54 -0
- data/lib/ansible/knx/dpt/dpt1.rb +224 -0
- data/lib/ansible/knx/dpt/dpt10.rb +85 -0
- data/lib/ansible/knx/dpt/dpt11.rb +72 -0
- data/lib/ansible/knx/dpt/dpt12.rb +61 -0
- data/lib/ansible/knx/dpt/dpt13.rb +100 -0
- data/lib/ansible/knx/dpt/dpt14.rb +87 -0
- data/lib/ansible/knx/dpt/dpt15.rb +72 -0
- data/lib/ansible/knx/dpt/dpt16.rb +67 -0
- data/lib/ansible/knx/dpt/dpt17.rb +65 -0
- data/lib/ansible/knx/dpt/dpt18.rb +66 -0
- data/lib/ansible/knx/dpt/dpt19.rb +100 -0
- data/lib/ansible/knx/dpt/dpt2.rb +156 -0
- data/lib/ansible/knx/dpt/dpt3.rb +104 -0
- data/lib/ansible/knx/dpt/dpt4.rb +75 -0
- data/lib/ansible/knx/dpt/dpt5.rb +124 -0
- data/lib/ansible/knx/dpt/dpt6.rb +73 -0
- data/lib/ansible/knx/dpt/dpt7.rb +146 -0
- data/lib/ansible/knx/dpt/dpt8.rb +118 -0
- data/lib/ansible/knx/dpt/dpt9.rb +204 -0
- data/lib/ansible/knx/dpt/tests/test_dpt10.rb +45 -0
- data/lib/ansible/knx/dpt/tests/test_dpt9.rb +60 -0
- data/lib/ansible/knx/hexdump.rb +113 -0
- data/lib/ansible/knx/knx_dpt.rb +58 -0
- data/lib/ansible/knx/knx_dpt_scalar.rb +62 -0
- data/lib/ansible/knx/knx_eistypes.rb +76 -0
- data/lib/ansible/knx/knx_protocol.rb +99 -0
- data/lib/ansible/knx/knx_scene.rb +48 -0
- data/lib/ansible/knx/knx_tools.rb +76 -0
- data/lib/ansible/knx/knx_transceiver.rb +237 -0
- data/lib/ansible/knx/knx_value.rb +327 -0
- data/lib/ansible/openzwave/ozw_constants.rb +11 -0
- data/lib/ansible/openzwave/ozw_headers.rb +80 -0
- data/lib/ansible/openzwave/ozw_remote_manager.rb +7615 -0
- data/lib/ansible/openzwave/ozw_types.rb +406 -0
- data/lib/ansible/orbiter_proxy.rb +12 -0
- data/lib/ansible/transceiver.rb +63 -0
- data/lib/ansible/zwave/types/valuetype_bool.rb +74 -0
- data/lib/ansible/zwave/types/valuetype_button.rb +63 -0
- data/lib/ansible/zwave/types/valuetype_byte.rb +78 -0
- data/lib/ansible/zwave/types/valuetype_decimal.rb +64 -0
- data/lib/ansible/zwave/types/valuetype_int.rb +63 -0
- data/lib/ansible/zwave/types/valuetype_list.rb +64 -0
- data/lib/ansible/zwave/types/valuetype_short.rb +63 -0
- data/lib/ansible/zwave/types/valuetype_string.rb +61 -0
- data/lib/ansible/zwave/zwave_command_classes.rb +113 -0
- data/lib/ansible/zwave/zwave_node.rb +5 -0
- data/lib/ansible/zwave/zwave_protocol.rb +52 -0
- data/lib/ansible/zwave/zwave_transceiver.rb +435 -0
- data/lib/ansible/zwave/zwave_value.rb +193 -0
- metadata +108 -0
@@ -0,0 +1,74 @@
|
|
1
|
+
=begin
|
2
|
+
Project Ansible - An extensible home automation scripting framework
|
3
|
+
----------------------------------------------------
|
4
|
+
Copyright (c) 2011 Elias Karakoulakis <elias.karakoulakis@gmail.com>
|
5
|
+
|
6
|
+
SOFTWARE NOTICE AND LICENSE
|
7
|
+
|
8
|
+
Project Ansible is free software: you can redistribute it and/or modify
|
9
|
+
it under the terms of the GNU Lesser General Public License as published
|
10
|
+
by the Free Software Foundation, either version 3 of the License,
|
11
|
+
or (at your option) any later version.
|
12
|
+
|
13
|
+
Project Ansible is distributed in the hope that it will be useful,
|
14
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
15
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
16
|
+
GNU Lesser General Public License for more details.
|
17
|
+
|
18
|
+
You should have received a copy of the GNU Lesser General Public License
|
19
|
+
along with Project Ansible. If not, see <http://www.gnu.org/licenses/>.
|
20
|
+
|
21
|
+
for more information on the LGPL, see:
|
22
|
+
http://en.wikipedia.org/wiki/GNU_Lesser_General_Public_License
|
23
|
+
=end
|
24
|
+
|
25
|
+
module Ansible
|
26
|
+
|
27
|
+
module ZWave
|
28
|
+
|
29
|
+
# boolean value type for OpenZWave
|
30
|
+
module ValueType_Bool
|
31
|
+
|
32
|
+
# define type-specific OZW::Manager API calls
|
33
|
+
def read_operation
|
34
|
+
return :GetValueAsBool
|
35
|
+
end
|
36
|
+
|
37
|
+
#
|
38
|
+
def write_operation
|
39
|
+
return :SetValue_Bool
|
40
|
+
end
|
41
|
+
|
42
|
+
#
|
43
|
+
def as_canonical_value()
|
44
|
+
return (
|
45
|
+
case
|
46
|
+
when [TrueClass, FalseClass].include?(current_value.class) then current_value
|
47
|
+
else false
|
48
|
+
end
|
49
|
+
)
|
50
|
+
end
|
51
|
+
|
52
|
+
# map any ruby value to boolean
|
53
|
+
def to_protocol_value(new_val)
|
54
|
+
return (
|
55
|
+
case
|
56
|
+
when [Fixnum].include?(new_val.class) then (new_val > 0)
|
57
|
+
when [TrueClass, FalseClass].include?(new_val.class) then new_val
|
58
|
+
when new_val.nil? then false
|
59
|
+
else true
|
60
|
+
end
|
61
|
+
)
|
62
|
+
end
|
63
|
+
|
64
|
+
# return a human-readable representation of a ZWave frame
|
65
|
+
def explain
|
66
|
+
puts "cv = #{@current_value}"
|
67
|
+
return(@current_value? "ON":"OFF")
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
|
@@ -0,0 +1,63 @@
|
|
1
|
+
=begin
|
2
|
+
Project Ansible - An extensible home automation scripting framework
|
3
|
+
----------------------------------------------------
|
4
|
+
Copyright (c) 2011 Elias Karakoulakis <elias.karakoulakis@gmail.com>
|
5
|
+
|
6
|
+
SOFTWARE NOTICE AND LICENSE
|
7
|
+
|
8
|
+
Project Ansible is free software: you can redistribute it and/or modify
|
9
|
+
it under the terms of the GNU Lesser General Public License as published
|
10
|
+
by the Free Software Foundation, either version 3 of the License,
|
11
|
+
or (at your option) any later version.
|
12
|
+
|
13
|
+
Project Ansible is distributed in the hope that it will be useful,
|
14
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
15
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
16
|
+
GNU Lesser General Public License for more details.
|
17
|
+
|
18
|
+
You should have received a copy of the GNU Lesser General Public License
|
19
|
+
along with Project Ansible. If not, see <http://www.gnu.org/licenses/>.
|
20
|
+
|
21
|
+
for more information on the LGPL, see:
|
22
|
+
http://en.wikipedia.org/wiki/GNU_Lesser_General_Public_License
|
23
|
+
=end
|
24
|
+
|
25
|
+
module Ansible
|
26
|
+
|
27
|
+
module ZWave
|
28
|
+
|
29
|
+
# button value type for OpenZWave
|
30
|
+
module ValueType_Button
|
31
|
+
|
32
|
+
# define type-specific OZW::Manager API calls
|
33
|
+
def read_operation
|
34
|
+
return nil # FIXME
|
35
|
+
end
|
36
|
+
|
37
|
+
def write_operation
|
38
|
+
return :PressButton # FIXME: also: ReleaseButton
|
39
|
+
end
|
40
|
+
|
41
|
+
#
|
42
|
+
def as_canonical_value()
|
43
|
+
puts 'TODO:: zwave_button: as_canonical'
|
44
|
+
return (current_value > 0)
|
45
|
+
end
|
46
|
+
|
47
|
+
#
|
48
|
+
def to_protocol_value(new_val)
|
49
|
+
puts 'TODO:: zwave_button: to_protocol'
|
50
|
+
result = nil
|
51
|
+
if [TrueClass, FalseClass].include?(new_val.class)
|
52
|
+
result = new_val ? 1 : 0
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# return a human-readable representation of a ZWave frame
|
57
|
+
def explain
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
=begin
|
2
|
+
Project Ansible - An extensible home automation scripting framework
|
3
|
+
----------------------------------------------------
|
4
|
+
Copyright (c) 2011 Elias Karakoulakis <elias.karakoulakis@gmail.com>
|
5
|
+
|
6
|
+
SOFTWARE NOTICE AND LICENSE
|
7
|
+
|
8
|
+
Project Ansible is free software: you can redistribute it and/or modify
|
9
|
+
it under the terms of the GNU Lesser General Public License as published
|
10
|
+
by the Free Software Foundation, either version 3 of the License,
|
11
|
+
or (at your option) any later version.
|
12
|
+
|
13
|
+
Project Ansible is distributed in the hope that it will be useful,
|
14
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
15
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
16
|
+
GNU Lesser General Public License for more details.
|
17
|
+
|
18
|
+
You should have received a copy of the GNU Lesser General Public License
|
19
|
+
along with Project Ansible. If not, see <http://www.gnu.org/licenses/>.
|
20
|
+
|
21
|
+
for more information on the LGPL, see:
|
22
|
+
http://en.wikipedia.org/wiki/GNU_Lesser_General_Public_License
|
23
|
+
=end
|
24
|
+
|
25
|
+
module Ansible
|
26
|
+
|
27
|
+
module ZWave
|
28
|
+
|
29
|
+
# byte value type for OpenZWave (0-255)
|
30
|
+
module ValueType_Byte
|
31
|
+
|
32
|
+
# define type-specific OZW::Manager API calls
|
33
|
+
def read_operation
|
34
|
+
return :GetValueAsByte
|
35
|
+
end
|
36
|
+
|
37
|
+
def write_operation
|
38
|
+
return :SetValue_UInt8
|
39
|
+
end
|
40
|
+
|
41
|
+
# ZWave 1-byte values canonical form is a Fixnum between 0 and 255
|
42
|
+
def as_canonical_value()
|
43
|
+
return( case current_value
|
44
|
+
when 0..255 then current_value
|
45
|
+
else raise "#{self}: value #{current value} out of bounds 0..255"
|
46
|
+
end
|
47
|
+
)
|
48
|
+
end
|
49
|
+
|
50
|
+
# ZWave 1-byte values protocol form is a Fixnum between 0 and 255
|
51
|
+
def to_protocol_value(new_val)
|
52
|
+
return( case new_val
|
53
|
+
when TrueClass then 255
|
54
|
+
when FalseClass then 0
|
55
|
+
when 0..255 then new_val
|
56
|
+
else raise "#{self}: value #{current value} out of bounds 0..255"
|
57
|
+
end
|
58
|
+
)
|
59
|
+
end
|
60
|
+
|
61
|
+
# return a human-readable representation of a ZWave frame
|
62
|
+
def explain
|
63
|
+
result = case @_commandClassId
|
64
|
+
when 38 then
|
65
|
+
case @current_value
|
66
|
+
when 0..99 then "#{@current_value} %"
|
67
|
+
else "Off"
|
68
|
+
end
|
69
|
+
else "#{@current_value}"
|
70
|
+
end
|
71
|
+
return(result)
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
=begin
|
2
|
+
Project Ansible - An extensible home automation scripting framework
|
3
|
+
----------------------------------------------------
|
4
|
+
Copyright (c) 2011 Elias Karakoulakis <elias.karakoulakis@gmail.com>
|
5
|
+
|
6
|
+
SOFTWARE NOTICE AND LICENSE
|
7
|
+
|
8
|
+
Project Ansible is free software: you can redistribute it and/or modify
|
9
|
+
it under the terms of the GNU Lesser General Public License as published
|
10
|
+
by the Free Software Foundation, either version 3 of the License,
|
11
|
+
or (at your option) any later version.
|
12
|
+
|
13
|
+
Project Ansible is distributed in the hope that it will be useful,
|
14
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
15
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
16
|
+
GNU Lesser General Public License for more details.
|
17
|
+
|
18
|
+
You should have received a copy of the GNU Lesser General Public License
|
19
|
+
along with Project Ansible. If not, see <http://www.gnu.org/licenses/>.
|
20
|
+
|
21
|
+
for more information on the LGPL, see:
|
22
|
+
http://en.wikipedia.org/wiki/GNU_Lesser_General_Public_License
|
23
|
+
=end
|
24
|
+
|
25
|
+
module Ansible
|
26
|
+
|
27
|
+
module ZWave
|
28
|
+
|
29
|
+
# Decimal value type for OpenZWave: special form for string representation
|
30
|
+
# of floating point values in order to avoid rounding errors
|
31
|
+
module ValueType_Decimal
|
32
|
+
|
33
|
+
# define type-specific OZW::Manager API calls
|
34
|
+
def read_operation
|
35
|
+
return :GetValueAsString
|
36
|
+
end
|
37
|
+
|
38
|
+
def write_operation
|
39
|
+
return :SetValue_String
|
40
|
+
end
|
41
|
+
|
42
|
+
#
|
43
|
+
def as_canonical_value()
|
44
|
+
puts 'TODO:: zwave_decimal: as_canonical'
|
45
|
+
return (current_value > 0)
|
46
|
+
end
|
47
|
+
|
48
|
+
#
|
49
|
+
def to_protocol_value(new_val)
|
50
|
+
puts 'TODO:: zwave_decimal: to_protocol'
|
51
|
+
result = nil
|
52
|
+
if [TrueClass, FalseClass].include?(new_val.class)
|
53
|
+
result = new_val ? 1 : 0
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# return a human-readable representation of a ZWave frame
|
58
|
+
def explain
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
=begin
|
2
|
+
Project Ansible - An extensible home automation scripting framework
|
3
|
+
----------------------------------------------------
|
4
|
+
Copyright (c) 2011 Elias Karakoulakis <elias.karakoulakis@gmail.com>
|
5
|
+
|
6
|
+
SOFTWARE NOTICE AND LICENSE
|
7
|
+
|
8
|
+
Project Ansible is free software: you can redistribute it and/or modify
|
9
|
+
it under the terms of the GNU Lesser General Public License as published
|
10
|
+
by the Free Software Foundation, either version 3 of the License,
|
11
|
+
or (at your option) any later version.
|
12
|
+
|
13
|
+
Project Ansible is distributed in the hope that it will be useful,
|
14
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
15
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
16
|
+
GNU Lesser General Public License for more details.
|
17
|
+
|
18
|
+
You should have received a copy of the GNU Lesser General Public License
|
19
|
+
along with Project Ansible. If not, see <http://www.gnu.org/licenses/>.
|
20
|
+
|
21
|
+
for more information on the LGPL, see:
|
22
|
+
http://en.wikipedia.org/wiki/GNU_Lesser_General_Public_License
|
23
|
+
=end
|
24
|
+
|
25
|
+
module Ansible
|
26
|
+
|
27
|
+
module ZWave
|
28
|
+
|
29
|
+
# integer (32-bit) value type for OpenZWave
|
30
|
+
module ValueType_Int
|
31
|
+
|
32
|
+
# define type-specific OZW::Manager API calls
|
33
|
+
def read_operation
|
34
|
+
return :GetValueAsInt
|
35
|
+
end
|
36
|
+
|
37
|
+
def write_operation
|
38
|
+
return :SetValue_Int32
|
39
|
+
end
|
40
|
+
|
41
|
+
#
|
42
|
+
def as_canonical_value()
|
43
|
+
puts 'TODO:: zwave_int: as_canonical'
|
44
|
+
return (current_value > 0)
|
45
|
+
end
|
46
|
+
|
47
|
+
#
|
48
|
+
def to_protocol_value(new_val)
|
49
|
+
puts 'TODO:: zwave_int: to_protocol'
|
50
|
+
result = nil
|
51
|
+
if [TrueClass, FalseClass].include?(new_val.class)
|
52
|
+
result = new_val ? 1 : 0
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# return a human-readable representation of a ZWave frame
|
57
|
+
def explain
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
=begin
|
2
|
+
Project Ansible - An extensible home automation scripting framework
|
3
|
+
----------------------------------------------------
|
4
|
+
Copyright (c) 2011 Elias Karakoulakis <elias.karakoulakis@gmail.com>
|
5
|
+
|
6
|
+
SOFTWARE NOTICE AND LICENSE
|
7
|
+
|
8
|
+
Project Ansible is free software: you can redistribute it and/or modify
|
9
|
+
it under the terms of the GNU Lesser General Public License as published
|
10
|
+
by the Free Software Foundation, either version 3 of the License,
|
11
|
+
or (at your option) any later version.
|
12
|
+
|
13
|
+
Project Ansible is distributed in the hope that it will be useful,
|
14
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
15
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
16
|
+
GNU Lesser General Public License for more details.
|
17
|
+
|
18
|
+
You should have received a copy of the GNU Lesser General Public License
|
19
|
+
along with Project Ansible. If not, see <http://www.gnu.org/licenses/>.
|
20
|
+
|
21
|
+
for more information on the LGPL, see:
|
22
|
+
http://en.wikipedia.org/wiki/GNU_Lesser_General_Public_License
|
23
|
+
=end
|
24
|
+
|
25
|
+
module Ansible
|
26
|
+
|
27
|
+
module ZWave
|
28
|
+
|
29
|
+
# list value type for OpenZWave
|
30
|
+
#
|
31
|
+
module ValueType_List
|
32
|
+
|
33
|
+
# define type-specific OZW::Manager API calls
|
34
|
+
def read_operation
|
35
|
+
raise 'FIXME'
|
36
|
+
return :GetValueListItems
|
37
|
+
end
|
38
|
+
|
39
|
+
def write_operation
|
40
|
+
raise 'FIXME'
|
41
|
+
return :SetValueListSelection
|
42
|
+
end
|
43
|
+
|
44
|
+
#
|
45
|
+
def as_canonical_value()
|
46
|
+
puts 'TODO'
|
47
|
+
end
|
48
|
+
|
49
|
+
#
|
50
|
+
def to_protocol_value(new_val)
|
51
|
+
result = nil
|
52
|
+
if [TrueClass, FalseClass].include?(new_val.class)
|
53
|
+
result = new_val ? 1 : 0
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# return a human-readable representation of a ZWave frame
|
58
|
+
def explain
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
=begin
|
2
|
+
Project Ansible - An extensible home automation scripting framework
|
3
|
+
----------------------------------------------------
|
4
|
+
Copyright (c) 2011 Elias Karakoulakis <elias.karakoulakis@gmail.com>
|
5
|
+
|
6
|
+
SOFTWARE NOTICE AND LICENSE
|
7
|
+
|
8
|
+
Project Ansible is free software: you can redistribute it and/or modify
|
9
|
+
it under the terms of the GNU Lesser General Public License as published
|
10
|
+
by the Free Software Foundation, either version 3 of the License,
|
11
|
+
or (at your option) any later version.
|
12
|
+
|
13
|
+
Project Ansible is distributed in the hope that it will be useful,
|
14
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
15
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
16
|
+
GNU Lesser General Public License for more details.
|
17
|
+
|
18
|
+
You should have received a copy of the GNU Lesser General Public License
|
19
|
+
along with Project Ansible. If not, see <http://www.gnu.org/licenses/>.
|
20
|
+
|
21
|
+
for more information on the LGPL, see:
|
22
|
+
http://en.wikipedia.org/wiki/GNU_Lesser_General_Public_License
|
23
|
+
=end
|
24
|
+
|
25
|
+
module Ansible
|
26
|
+
|
27
|
+
module ZWave
|
28
|
+
|
29
|
+
# short integer (16-bit) value type for OpenZWave
|
30
|
+
module ValueType_Short
|
31
|
+
|
32
|
+
# define type-specific OZW::Manager API calls
|
33
|
+
def read_operation
|
34
|
+
return :GetValueAsShort
|
35
|
+
end
|
36
|
+
|
37
|
+
def write_operation
|
38
|
+
return :SetValue_Int16
|
39
|
+
end
|
40
|
+
|
41
|
+
#
|
42
|
+
def as_canonical_value()
|
43
|
+
puts 'TODO:: zwave_short: as_canonical'
|
44
|
+
return (current_value > 0)
|
45
|
+
end
|
46
|
+
|
47
|
+
#
|
48
|
+
def to_protocol_value(new_val)
|
49
|
+
puts 'TODO:: zwave_short: to_protocol'
|
50
|
+
result = nil
|
51
|
+
if [TrueClass, FalseClass].include?(new_val.class)
|
52
|
+
result = new_val ? 1 : 0
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# return a human-readable representation of a ZWave frame
|
57
|
+
def explain
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|