iron_titan 0.3.10 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +201 -0
  3. data/README.md +6 -5
  4. data/lib/iron_titan/api/groups_api.rb +34 -31
  5. data/lib/iron_titan/api/jobs_api.rb +140 -182
  6. data/lib/iron_titan/api/runner_api.rb +43 -47
  7. data/lib/iron_titan/api_client.rb +48 -8
  8. data/lib/iron_titan/api_error.rb +12 -1
  9. data/lib/iron_titan/configuration.rb +23 -0
  10. data/lib/iron_titan/models/complete.rb +63 -27
  11. data/lib/iron_titan/models/error.rb +59 -21
  12. data/lib/iron_titan/models/error_body.rb +61 -24
  13. data/lib/iron_titan/models/group.rb +112 -28
  14. data/lib/iron_titan/models/group_wrapper.rb +60 -21
  15. data/lib/iron_titan/models/groups_wrapper.rb +60 -21
  16. data/lib/iron_titan/models/id_status.rb +89 -28
  17. data/lib/iron_titan/models/job.rb +168 -90
  18. data/lib/iron_titan/models/job_wrapper.rb +60 -21
  19. data/lib/iron_titan/models/jobs_wrapper.rb +62 -24
  20. data/lib/iron_titan/models/new_job.rb +91 -42
  21. data/lib/iron_titan/models/new_jobs_wrapper.rb +60 -21
  22. data/lib/iron_titan/models/start.rb +59 -21
  23. data/lib/iron_titan/version.rb +13 -2
  24. data/lib/iron_titan.rb +12 -1
  25. data/spec/api/groups_api_spec.rb +16 -17
  26. data/spec/api/jobs_api_spec.rb +37 -78
  27. data/spec/api/runner_api_spec.rb +20 -21
  28. data/spec/api_client_spec.rb +296 -0
  29. data/spec/configuration_spec.rb +48 -0
  30. data/spec/models/complete_spec.rb +16 -17
  31. data/spec/models/error_body_spec.rb +15 -12
  32. data/spec/models/error_spec.rb +14 -7
  33. data/spec/models/group_spec.rb +33 -12
  34. data/spec/models/group_wrapper_spec.rb +14 -7
  35. data/spec/models/groups_wrapper_spec.rb +14 -7
  36. data/spec/models/id_status_spec.rb +18 -12
  37. data/spec/models/job_spec.rb +43 -88
  38. data/spec/models/job_wrapper_spec.rb +14 -7
  39. data/spec/models/jobs_wrapper_spec.rb +15 -12
  40. data/spec/models/new_job_spec.rb +20 -37
  41. data/spec/models/new_jobs_wrapper_spec.rb +14 -7
  42. data/spec/models/start_spec.rb +14 -7
  43. data/spec/spec_helper.rb +122 -0
  44. metadata +9 -2
@@ -3,25 +3,36 @@ Titan API
3
3
 
4
4
  The ultimate, language agnostic, container based job processing framework.
5
5
 
6
- OpenAPI spec version: 0.3.10
6
+ OpenAPI spec version: 0.4.0
7
7
 
8
8
  Generated by: https://github.com/swagger-api/swagger-codegen.git
9
9
 
10
+ Licensed under the Apache License, Version 2.0 (the "License");
11
+ you may not use this file except in compliance with the License.
12
+ You may obtain a copy of the License at
13
+
14
+ http://www.apache.org/licenses/LICENSE-2.0
15
+
16
+ Unless required by applicable law or agreed to in writing, software
17
+ distributed under the License is distributed on an "AS IS" BASIS,
18
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19
+ See the License for the specific language governing permissions and
20
+ limitations under the License.
10
21
 
11
22
  =end
12
23
 
13
24
  require 'date'
14
25
 
15
26
  module IronTitan
27
+
16
28
  class Error
17
29
  attr_accessor :error
18
30
 
31
+
19
32
  # Attribute mapping from ruby-style variable name to JSON key.
20
33
  def self.attribute_map
21
34
  {
22
-
23
35
  :'error' => :'error'
24
-
25
36
  }
26
37
  end
27
38
 
@@ -29,24 +40,38 @@ module IronTitan
29
40
  def self.swagger_types
30
41
  {
31
42
  :'error' => :'ErrorBody'
32
-
33
43
  }
34
44
  end
35
45
 
46
+ # Initializes the object
47
+ # @param [Hash] attributes Model attributes in the form of hash
36
48
  def initialize(attributes = {})
37
49
  return unless attributes.is_a?(Hash)
38
50
 
39
51
  # convert string to symbol for hash key
40
- attributes = attributes.inject({}){|memo,(k,v)| memo[k.to_sym] = v; memo}
52
+ attributes = attributes.each_with_object({}){|(k,v), h| h[k.to_sym] = v}
41
53
 
42
-
43
- if attributes[:'error']
54
+ if attributes.has_key?(:'error')
44
55
  self.error = attributes[:'error']
45
56
  end
46
-
57
+
58
+ end
59
+
60
+ # Show invalid properties with the reasons. Usually used together with valid?
61
+ # @return Array for valid properies with the reasons
62
+ def list_invalid_properties
63
+ invalid_properties = Array.new
64
+ return invalid_properties
65
+ end
66
+
67
+ # Check to see if the all the properties in the model are valid
68
+ # @return true if the model is valid
69
+ def valid?
70
+ return true
47
71
  end
48
72
 
49
- # Check equality by comparing each attribute.
73
+ # Checks equality by comparing each attribute.
74
+ # @param [Object] Object to be compared
50
75
  def ==(o)
51
76
  return true if self.equal?(o)
52
77
  self.class == o.class &&
@@ -54,35 +79,41 @@ module IronTitan
54
79
  end
55
80
 
56
81
  # @see the `==` method
82
+ # @param [Object] Object to be compared
57
83
  def eql?(o)
58
84
  self == o
59
85
  end
60
86
 
61
- # Calculate hash code according to all attributes.
87
+ # Calculates hash code according to all attributes.
88
+ # @return [Fixnum] Hash code
62
89
  def hash
63
90
  [error].hash
64
91
  end
65
92
 
66
- # build the object from hash
93
+ # Builds the object from hash
94
+ # @param [Hash] attributes Model attributes in the form of hash
95
+ # @return [Object] Returns the model itself
67
96
  def build_from_hash(attributes)
68
97
  return nil unless attributes.is_a?(Hash)
69
98
  self.class.swagger_types.each_pair do |key, type|
70
99
  if type =~ /^Array<(.*)>/i
100
+ # check to ensure the input is an array given that the the attribute
101
+ # is documented as an array but the input is not
71
102
  if attributes[self.class.attribute_map[key]].is_a?(Array)
72
103
  self.send("#{key}=", attributes[self.class.attribute_map[key]].map{ |v| _deserialize($1, v) } )
73
- else
74
- #TODO show warning in debug mode
75
104
  end
76
105
  elsif !attributes[self.class.attribute_map[key]].nil?
77
106
  self.send("#{key}=", _deserialize(type, attributes[self.class.attribute_map[key]]))
78
- else
79
- # data not found in attributes(hash), not an issue as the data can be optional
80
- end
107
+ end # or else data not found in attributes(hash), not an issue as the data can be optional
81
108
  end
82
109
 
83
110
  self
84
111
  end
85
112
 
113
+ # Deserializes the data based on type
114
+ # @param string type Data type
115
+ # @param string value Value to be deserialized
116
+ # @return [Object] Deserialized data
86
117
  def _deserialize(type, value)
87
118
  case type.to_sym
88
119
  when :DateTime
@@ -116,21 +147,25 @@ module IronTitan
116
147
  end
117
148
  end
118
149
  else # model
119
- _model = IronTitan.const_get(type).new
120
- _model.build_from_hash(value)
150
+ temp_model = IronTitan.const_get(type).new
151
+ temp_model.build_from_hash(value)
121
152
  end
122
153
  end
123
154
 
155
+ # Returns the string representation of the object
156
+ # @return [String] String presentation of the object
124
157
  def to_s
125
158
  to_hash.to_s
126
159
  end
127
160
 
128
- # to_body is an alias to to_body (backward compatibility))
161
+ # to_body is an alias to to_hash (backward compatibility)
162
+ # @return [Hash] Returns the object in the form of hash
129
163
  def to_body
130
164
  to_hash
131
165
  end
132
166
 
133
- # return the object in the form of hash
167
+ # Returns the object in the form of hash
168
+ # @return [Hash] Returns the object in the form of hash
134
169
  def to_hash
135
170
  hash = {}
136
171
  self.class.attribute_map.each_pair do |attr, param|
@@ -141,8 +176,10 @@ module IronTitan
141
176
  hash
142
177
  end
143
178
 
144
- # Method to output non-array value in the form of hash
179
+ # Outputs non-array value in the form of hash
145
180
  # For object, use to_hash. Otherwise, just return the value
181
+ # @param [Object] value Any valid value
182
+ # @return [Hash] Returns the value in the form of hash
146
183
  def _to_hash(value)
147
184
  if value.is_a?(Array)
148
185
  value.compact.map{ |v| _to_hash(v) }
@@ -158,4 +195,5 @@ module IronTitan
158
195
  end
159
196
 
160
197
  end
198
+
161
199
  end
@@ -3,29 +3,39 @@ Titan API
3
3
 
4
4
  The ultimate, language agnostic, container based job processing framework.
5
5
 
6
- OpenAPI spec version: 0.3.10
6
+ OpenAPI spec version: 0.4.0
7
7
 
8
8
  Generated by: https://github.com/swagger-api/swagger-codegen.git
9
9
 
10
+ Licensed under the Apache License, Version 2.0 (the "License");
11
+ you may not use this file except in compliance with the License.
12
+ You may obtain a copy of the License at
13
+
14
+ http://www.apache.org/licenses/LICENSE-2.0
15
+
16
+ Unless required by applicable law or agreed to in writing, software
17
+ distributed under the License is distributed on an "AS IS" BASIS,
18
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19
+ See the License for the specific language governing permissions and
20
+ limitations under the License.
10
21
 
11
22
  =end
12
23
 
13
24
  require 'date'
14
25
 
15
26
  module IronTitan
27
+
16
28
  class ErrorBody
17
29
  attr_accessor :message
18
30
 
19
31
  attr_accessor :fields
20
32
 
33
+
21
34
  # Attribute mapping from ruby-style variable name to JSON key.
22
35
  def self.attribute_map
23
36
  {
24
-
25
37
  :'message' => :'message',
26
-
27
38
  :'fields' => :'fields'
28
-
29
39
  }
30
40
  end
31
41
 
@@ -34,28 +44,42 @@ module IronTitan
34
44
  {
35
45
  :'message' => :'String',
36
46
  :'fields' => :'String'
37
-
38
47
  }
39
48
  end
40
49
 
50
+ # Initializes the object
51
+ # @param [Hash] attributes Model attributes in the form of hash
41
52
  def initialize(attributes = {})
42
53
  return unless attributes.is_a?(Hash)
43
54
 
44
55
  # convert string to symbol for hash key
45
- attributes = attributes.inject({}){|memo,(k,v)| memo[k.to_sym] = v; memo}
56
+ attributes = attributes.each_with_object({}){|(k,v), h| h[k.to_sym] = v}
46
57
 
47
-
48
- if attributes[:'message']
58
+ if attributes.has_key?(:'message')
49
59
  self.message = attributes[:'message']
50
60
  end
51
-
52
- if attributes[:'fields']
61
+
62
+ if attributes.has_key?(:'fields')
53
63
  self.fields = attributes[:'fields']
54
64
  end
55
-
65
+
56
66
  end
57
67
 
58
- # Check equality by comparing each attribute.
68
+ # Show invalid properties with the reasons. Usually used together with valid?
69
+ # @return Array for valid properies with the reasons
70
+ def list_invalid_properties
71
+ invalid_properties = Array.new
72
+ return invalid_properties
73
+ end
74
+
75
+ # Check to see if the all the properties in the model are valid
76
+ # @return true if the model is valid
77
+ def valid?
78
+ return true
79
+ end
80
+
81
+ # Checks equality by comparing each attribute.
82
+ # @param [Object] Object to be compared
59
83
  def ==(o)
60
84
  return true if self.equal?(o)
61
85
  self.class == o.class &&
@@ -64,35 +88,41 @@ module IronTitan
64
88
  end
65
89
 
66
90
  # @see the `==` method
91
+ # @param [Object] Object to be compared
67
92
  def eql?(o)
68
93
  self == o
69
94
  end
70
95
 
71
- # Calculate hash code according to all attributes.
96
+ # Calculates hash code according to all attributes.
97
+ # @return [Fixnum] Hash code
72
98
  def hash
73
99
  [message, fields].hash
74
100
  end
75
101
 
76
- # build the object from hash
102
+ # Builds the object from hash
103
+ # @param [Hash] attributes Model attributes in the form of hash
104
+ # @return [Object] Returns the model itself
77
105
  def build_from_hash(attributes)
78
106
  return nil unless attributes.is_a?(Hash)
79
107
  self.class.swagger_types.each_pair do |key, type|
80
108
  if type =~ /^Array<(.*)>/i
109
+ # check to ensure the input is an array given that the the attribute
110
+ # is documented as an array but the input is not
81
111
  if attributes[self.class.attribute_map[key]].is_a?(Array)
82
112
  self.send("#{key}=", attributes[self.class.attribute_map[key]].map{ |v| _deserialize($1, v) } )
83
- else
84
- #TODO show warning in debug mode
85
113
  end
86
114
  elsif !attributes[self.class.attribute_map[key]].nil?
87
115
  self.send("#{key}=", _deserialize(type, attributes[self.class.attribute_map[key]]))
88
- else
89
- # data not found in attributes(hash), not an issue as the data can be optional
90
- end
116
+ end # or else data not found in attributes(hash), not an issue as the data can be optional
91
117
  end
92
118
 
93
119
  self
94
120
  end
95
121
 
122
+ # Deserializes the data based on type
123
+ # @param string type Data type
124
+ # @param string value Value to be deserialized
125
+ # @return [Object] Deserialized data
96
126
  def _deserialize(type, value)
97
127
  case type.to_sym
98
128
  when :DateTime
@@ -126,21 +156,25 @@ module IronTitan
126
156
  end
127
157
  end
128
158
  else # model
129
- _model = IronTitan.const_get(type).new
130
- _model.build_from_hash(value)
159
+ temp_model = IronTitan.const_get(type).new
160
+ temp_model.build_from_hash(value)
131
161
  end
132
162
  end
133
163
 
164
+ # Returns the string representation of the object
165
+ # @return [String] String presentation of the object
134
166
  def to_s
135
167
  to_hash.to_s
136
168
  end
137
169
 
138
- # to_body is an alias to to_body (backward compatibility))
170
+ # to_body is an alias to to_hash (backward compatibility)
171
+ # @return [Hash] Returns the object in the form of hash
139
172
  def to_body
140
173
  to_hash
141
174
  end
142
175
 
143
- # return the object in the form of hash
176
+ # Returns the object in the form of hash
177
+ # @return [Hash] Returns the object in the form of hash
144
178
  def to_hash
145
179
  hash = {}
146
180
  self.class.attribute_map.each_pair do |attr, param|
@@ -151,8 +185,10 @@ module IronTitan
151
185
  hash
152
186
  end
153
187
 
154
- # Method to output non-array value in the form of hash
188
+ # Outputs non-array value in the form of hash
155
189
  # For object, use to_hash. Otherwise, just return the value
190
+ # @param [Object] value Any valid value
191
+ # @return [Hash] Returns the value in the form of hash
156
192
  def _to_hash(value)
157
193
  if value.is_a?(Array)
158
194
  value.compact.map{ |v| _to_hash(v) }
@@ -168,4 +204,5 @@ module IronTitan
168
204
  end
169
205
 
170
206
  end
207
+
171
208
  end
@@ -3,16 +3,28 @@ Titan API
3
3
 
4
4
  The ultimate, language agnostic, container based job processing framework.
5
5
 
6
- OpenAPI spec version: 0.3.10
6
+ OpenAPI spec version: 0.4.0
7
7
 
8
8
  Generated by: https://github.com/swagger-api/swagger-codegen.git
9
9
 
10
+ Licensed under the Apache License, Version 2.0 (the "License");
11
+ you may not use this file except in compliance with the License.
12
+ You may obtain a copy of the License at
13
+
14
+ http://www.apache.org/licenses/LICENSE-2.0
15
+
16
+ Unless required by applicable law or agreed to in writing, software
17
+ distributed under the License is distributed on an "AS IS" BASIS,
18
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19
+ See the License for the specific language governing permissions and
20
+ limitations under the License.
10
21
 
11
22
  =end
12
23
 
13
24
  require 'date'
14
25
 
15
26
  module IronTitan
27
+
16
28
  class Group
17
29
  # Name of this group. Must be different than the image name. Can ony contain alphanumeric, -, and _.
18
30
  attr_accessor :name
@@ -20,14 +32,24 @@ module IronTitan
20
32
  # Time when image first used/created.
21
33
  attr_accessor :created_at
22
34
 
35
+ # Name of Docker image to use in this group. You should include the image tag, which should be a version number, to be more accurate. Can be overridden on a per job basis with job.image.
36
+ attr_accessor :image
37
+
38
+ # User defined environment variables that will be passed in to each job in this group.
39
+ attr_accessor :env_vars
40
+
41
+ # The maximum number of jobs that will run at the exact same time in this group.
42
+ attr_accessor :max_concurrency
43
+
44
+
23
45
  # Attribute mapping from ruby-style variable name to JSON key.
24
46
  def self.attribute_map
25
47
  {
26
-
27
48
  :'name' => :'name',
28
-
29
- :'created_at' => :'created_at'
30
-
49
+ :'created_at' => :'created_at',
50
+ :'image' => :'image',
51
+ :'env_vars' => :'env_vars',
52
+ :'max_concurrency' => :'max_concurrency'
31
53
  }
32
54
  end
33
55
 
@@ -35,66 +57,121 @@ module IronTitan
35
57
  def self.swagger_types
36
58
  {
37
59
  :'name' => :'String',
38
- :'created_at' => :'DateTime'
39
-
60
+ :'created_at' => :'DateTime',
61
+ :'image' => :'String',
62
+ :'env_vars' => :'Hash<String, String>',
63
+ :'max_concurrency' => :'Integer'
40
64
  }
41
65
  end
42
66
 
67
+ # Initializes the object
68
+ # @param [Hash] attributes Model attributes in the form of hash
43
69
  def initialize(attributes = {})
44
70
  return unless attributes.is_a?(Hash)
45
71
 
46
72
  # convert string to symbol for hash key
47
- attributes = attributes.inject({}){|memo,(k,v)| memo[k.to_sym] = v; memo}
73
+ attributes = attributes.each_with_object({}){|(k,v), h| h[k.to_sym] = v}
48
74
 
49
-
50
- if attributes[:'name']
75
+ if attributes.has_key?(:'name')
51
76
  self.name = attributes[:'name']
52
77
  end
53
-
54
- if attributes[:'created_at']
78
+
79
+ if attributes.has_key?(:'created_at')
55
80
  self.created_at = attributes[:'created_at']
56
81
  end
57
-
82
+
83
+ if attributes.has_key?(:'image')
84
+ self.image = attributes[:'image']
85
+ end
86
+
87
+ if attributes.has_key?(:'env_vars')
88
+ if (value = attributes[:'env_vars']).is_a?(Array)
89
+ self.env_vars = value
90
+ end
91
+ end
92
+
93
+ if attributes.has_key?(:'max_concurrency')
94
+ self.max_concurrency = attributes[:'max_concurrency']
95
+ end
96
+
97
+ end
98
+
99
+ # Show invalid properties with the reasons. Usually used together with valid?
100
+ # @return Array for valid properies with the reasons
101
+ def list_invalid_properties
102
+ invalid_properties = Array.new
103
+ return invalid_properties
104
+ end
105
+
106
+ # Check to see if the all the properties in the model are valid
107
+ # @return true if the model is valid
108
+ def valid?
109
+ return false if @image.to_s.length >
110
+ return true
111
+ end
112
+
113
+ # Custom attribute writer method with validation
114
+ # @param [Object] image Value to be assigned
115
+ def image=(image)
116
+ if image.nil?
117
+ fail ArgumentError, "image cannot be nil"
118
+ end
119
+
120
+ if image.to_s.length >
121
+ fail ArgumentError, "invalid value for 'image', the character length must be smaller than or equal to ."
122
+ end
123
+
124
+ @image = image
58
125
  end
59
126
 
60
- # Check equality by comparing each attribute.
127
+ # Checks equality by comparing each attribute.
128
+ # @param [Object] Object to be compared
61
129
  def ==(o)
62
130
  return true if self.equal?(o)
63
131
  self.class == o.class &&
64
132
  name == o.name &&
65
- created_at == o.created_at
133
+ created_at == o.created_at &&
134
+ image == o.image &&
135
+ env_vars == o.env_vars &&
136
+ max_concurrency == o.max_concurrency
66
137
  end
67
138
 
68
139
  # @see the `==` method
140
+ # @param [Object] Object to be compared
69
141
  def eql?(o)
70
142
  self == o
71
143
  end
72
144
 
73
- # Calculate hash code according to all attributes.
145
+ # Calculates hash code according to all attributes.
146
+ # @return [Fixnum] Hash code
74
147
  def hash
75
- [name, created_at].hash
148
+ [name, created_at, image, env_vars, max_concurrency].hash
76
149
  end
77
150
 
78
- # build the object from hash
151
+ # Builds the object from hash
152
+ # @param [Hash] attributes Model attributes in the form of hash
153
+ # @return [Object] Returns the model itself
79
154
  def build_from_hash(attributes)
80
155
  return nil unless attributes.is_a?(Hash)
81
156
  self.class.swagger_types.each_pair do |key, type|
82
157
  if type =~ /^Array<(.*)>/i
158
+ # check to ensure the input is an array given that the the attribute
159
+ # is documented as an array but the input is not
83
160
  if attributes[self.class.attribute_map[key]].is_a?(Array)
84
161
  self.send("#{key}=", attributes[self.class.attribute_map[key]].map{ |v| _deserialize($1, v) } )
85
- else
86
- #TODO show warning in debug mode
87
162
  end
88
163
  elsif !attributes[self.class.attribute_map[key]].nil?
89
164
  self.send("#{key}=", _deserialize(type, attributes[self.class.attribute_map[key]]))
90
- else
91
- # data not found in attributes(hash), not an issue as the data can be optional
92
- end
165
+ end # or else data not found in attributes(hash), not an issue as the data can be optional
93
166
  end
94
167
 
95
168
  self
96
169
  end
97
170
 
171
+ # Deserializes the data based on type
172
+ # @param string type Data type
173
+ # @param string value Value to be deserialized
174
+ # @return [Object] Deserialized data
98
175
  def _deserialize(type, value)
99
176
  case type.to_sym
100
177
  when :DateTime
@@ -128,21 +205,25 @@ module IronTitan
128
205
  end
129
206
  end
130
207
  else # model
131
- _model = IronTitan.const_get(type).new
132
- _model.build_from_hash(value)
208
+ temp_model = IronTitan.const_get(type).new
209
+ temp_model.build_from_hash(value)
133
210
  end
134
211
  end
135
212
 
213
+ # Returns the string representation of the object
214
+ # @return [String] String presentation of the object
136
215
  def to_s
137
216
  to_hash.to_s
138
217
  end
139
218
 
140
- # to_body is an alias to to_body (backward compatibility))
219
+ # to_body is an alias to to_hash (backward compatibility)
220
+ # @return [Hash] Returns the object in the form of hash
141
221
  def to_body
142
222
  to_hash
143
223
  end
144
224
 
145
- # return the object in the form of hash
225
+ # Returns the object in the form of hash
226
+ # @return [Hash] Returns the object in the form of hash
146
227
  def to_hash
147
228
  hash = {}
148
229
  self.class.attribute_map.each_pair do |attr, param|
@@ -153,8 +234,10 @@ module IronTitan
153
234
  hash
154
235
  end
155
236
 
156
- # Method to output non-array value in the form of hash
237
+ # Outputs non-array value in the form of hash
157
238
  # For object, use to_hash. Otherwise, just return the value
239
+ # @param [Object] value Any valid value
240
+ # @return [Hash] Returns the value in the form of hash
158
241
  def _to_hash(value)
159
242
  if value.is_a?(Array)
160
243
  value.compact.map{ |v| _to_hash(v) }
@@ -170,4 +253,5 @@ module IronTitan
170
253
  end
171
254
 
172
255
  end
256
+
173
257
  end