itunes_transporter_generator 0.2 → 0.4.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (80) hide show
  1. data/Gemfile +3 -0
  2. data/LICENSE +19 -0
  3. data/README.md +250 -52
  4. data/doc/Itunes.html +198 -0
  5. data/doc/Itunes/Transporter.html +380 -0
  6. data/doc/Itunes/Transporter/Achievement.html +165 -0
  7. data/doc/Itunes/Transporter/AchievementLocale.html +165 -0
  8. data/doc/Itunes/Transporter/Generator.html +700 -0
  9. data/doc/Itunes/Transporter/Helpers.html +427 -0
  10. data/doc/Itunes/Transporter/InAppPurchase.html +165 -0
  11. data/doc/Itunes/Transporter/Interval.html +165 -0
  12. data/doc/Itunes/Transporter/Leaderboard.html +165 -0
  13. data/doc/Itunes/Transporter/LeaderboardLocale.html +165 -0
  14. data/doc/Itunes/Transporter/Locale.html +256 -0
  15. data/doc/Itunes/Transporter/Product.html +165 -0
  16. data/doc/Itunes/Transporter/PurchaseLocale.html +165 -0
  17. data/doc/Object.html +307 -0
  18. data/doc/Rakefile.html +112 -0
  19. data/doc/bin/itmsp.html +60 -0
  20. data/doc/created.rid +16 -0
  21. data/doc/example/achievements_rb.html +54 -0
  22. data/doc/example/in_app_purchases_rb.html +54 -0
  23. data/doc/example/leaderboards_rb.html +54 -0
  24. data/doc/example/test_rb.html +54 -0
  25. data/doc/images/brick.png +0 -0
  26. data/doc/images/brick_link.png +0 -0
  27. data/doc/images/bug.png +0 -0
  28. data/doc/images/bullet_black.png +0 -0
  29. data/doc/images/bullet_toggle_minus.png +0 -0
  30. data/doc/images/bullet_toggle_plus.png +0 -0
  31. data/doc/images/date.png +0 -0
  32. data/doc/images/find.png +0 -0
  33. data/doc/images/loadingAnimation.gif +0 -0
  34. data/doc/images/macFFBgHack.png +0 -0
  35. data/doc/images/package.png +0 -0
  36. data/doc/images/page_green.png +0 -0
  37. data/doc/images/page_white_text.png +0 -0
  38. data/doc/images/page_white_width.png +0 -0
  39. data/doc/images/plugin.png +0 -0
  40. data/doc/images/ruby.png +0 -0
  41. data/doc/images/tag_green.png +0 -0
  42. data/doc/images/wrench.png +0 -0
  43. data/doc/images/wrench_orange.png +0 -0
  44. data/doc/images/zoom.png +0 -0
  45. data/doc/index.html +110 -0
  46. data/doc/js/darkfish.js +116 -0
  47. data/doc/js/jquery.js +32 -0
  48. data/doc/js/quicksearch.js +114 -0
  49. data/doc/js/thickbox-compressed.js +10 -0
  50. data/doc/lib/itunes/transporter/achievement_rb.html +52 -0
  51. data/doc/lib/itunes/transporter/commands/package_rb.html +54 -0
  52. data/doc/lib/itunes/transporter/commands_rb.html +56 -0
  53. data/doc/lib/itunes/transporter/generator_rb.html +58 -0
  54. data/doc/lib/itunes/transporter/helpers_rb.html +60 -0
  55. data/doc/lib/itunes/transporter/in_app_purchase_rb.html +52 -0
  56. data/doc/lib/itunes/transporter/leaderboard_rb.html +54 -0
  57. data/doc/lib/itunes/transporter/locale_rb.html +52 -0
  58. data/doc/lib/itunes_rb.html +52 -0
  59. data/doc/rdoc.css +763 -0
  60. data/example/config copy.yaml +75 -0
  61. data/example/config.yaml +109 -4
  62. data/example/metadata.xml +201 -0
  63. data/example/sample sku.itmsp/metadata.xml +201 -0
  64. data/example/sample sku.itmsp/test.jpg +0 -0
  65. data/itmsp.gemspec +8 -4
  66. data/lib/itunes.rb +2 -2
  67. data/lib/itunes/transporter.rb +75 -0
  68. data/lib/itunes/transporter/commands.rb +1 -1
  69. data/lib/itunes/transporter/commands/package.rb +12 -9
  70. data/lib/itunes/transporter/generator.rb +291 -191
  71. data/lib/itunes/transporter/helpers.rb +236 -139
  72. data/lib/itunes/transporter/in_app_purchase.rb +16 -23
  73. data/lib/itunes/transporter/leaderboard.rb +0 -36
  74. data/lib/itunes/transporter/locale.rb +11 -11
  75. metadata +81 -7
  76. data/example/achievements.rb +0 -11
  77. data/example/in_app_purchases.rb +0 -9
  78. data/example/leaderboards.rb +0 -12
  79. data/example/test.rb +0 -5
  80. data/lib/itunes/transporter/achievement.rb +0 -9
@@ -1,143 +1,240 @@
1
1
  require 'yaml'
2
- require 'itunes/transporter/achievement'
3
- require 'itunes/transporter/leaderboard'
4
- require 'itunes/transporter/in_app_purchase'
2
+ require 'itunes/transporter'
5
3
 
6
4
  module Itunes
7
- module Transporter
8
- module Helpers
9
- def metadata_from_yaml(yaml_file)
10
- objs = YAML.load_file(Dir.pwd + "/#{yaml_file}")
11
-
12
- metadata = {
13
- :provider => objs['provider'],
14
- :team_id => objs['team_id'],
15
- :vendor_id => objs['vendor_id'],
16
- :id_prefix => objs['id_prefix'] || '',
17
- :achievements => parse_achievements(objs),
18
- :leaderboards => parse_leaderboards(objs),
19
- :purchases => parse_purchases(objs)
20
- }
21
- end
22
-
23
- def parse_achievements(objs)
24
- achievements = []
25
-
26
- objs['achievements'].each do |dict|
27
- achievement = Achievement.new
28
- achievement.id = dict['id']
29
- achievement.name = dict['name']
30
- achievement.points = dict['points']
31
- achievement.hidden = dict.has_key?('hidden') ? dict['has_key'] : false
32
- achievement.reusable = dict.has_key?('reusable') ? dict['reusable'] : false
33
- achievement.should_remove = dict.has_key?('should_remove') ? dict['should_remove'] : false
34
- achievement.locales = []
35
-
36
- dict['locales'].each do |loc|
37
- locale = AchievementLocale.new
38
- locale.name = loc['name']
39
- locale.title = loc['title']
40
- locale.before_earned_description = loc['before_earned_description']
41
- locale.after_earned_description = loc['after_earned_description']
42
- locale.after_earned_image = loc['after_earned_image']
43
- locale.should_remove = loc.has_key?('should_remove') ? loc['should_remove'] : false
44
-
45
- achievement.locales << locale
46
- end
47
-
48
- achievements << achievement
49
- end
50
-
51
- achievements
52
- end
53
-
54
- def parse_leaderboards(objs)
55
- leaderboards = []
56
-
57
- objs['leaderboards'].each do |dict|
58
- leaderboard = Leaderboard.new
59
- leaderboard.default = dict['default']
60
- leaderboard.name = dict['name']
61
- leaderboard.aggregate_parent_leaderboard = dict['aggregate_parent_leaderboard']
62
- leaderboard.sort_ascending = dict.has_key?('sort_ascending') ? dict['sort_ascending'] : false
63
- leaderboard.score_range_min = dict['score_range_min']
64
- leaderboard.score_range_max = dict['score_range_max']
65
- leaderboard.locales = []
66
-
67
- dict['locales'].each do |loc|
68
- locale = LeaderboardLocale.new
69
- locale.name = loc['name']
70
- locale.title = loc['title']
71
- locale.formatter_suffix = loc['formatter_suffix']
72
- locale.formatter_suffix_singular = loc['formatter_suffix_singular']
73
- locale.formatter_type = loc['formatter_type']
74
- locale.leaderboard_image = loc['leaderboard_image']
75
- locale.should_remove = loc.has_key?('should_remove') ? loc['should_remove'] : false
76
-
77
- leaderboard.locales << locale
78
- end
79
-
80
- leaderboards << leaderboard
81
- end
82
-
83
- leaderboards
84
- end
85
-
86
- def parse_purchases(objs)
87
- purchases = []
88
-
89
- objs['purchases'].each do |dict|
90
- purchase = InAppPurchase.new
91
- purchase.product_id = dict['product_id']
92
- purchase.reference_name = dict['reference_name']
93
- purchase.type = dict['type']
94
- purchase.duration = dict['duration']
95
- purchase.free_trial_duration = dict['free_trial_duration']
96
- purchase.bonus_duration = dict['bonus_duration']
97
- purchase.review_screenshot_image = dict['review_screenshot_image']
98
- purchase.review_notes = dict['review_notes']
99
- purchase.should_remove = dict.has_key?('should_remove') ? dict['should_remove'] : false
100
- purchase.locales = []
101
- purchase.products = []
102
-
103
- dict['products'].each do |p|
104
- product = Product.new
105
- product.cleared_for_sale = p['cleared_for_sale']
106
- product.wholesale_price_tier = p['wholesale_price_tier']
107
- product.should_remove = dict.has_key?('should_remove') ? dict['should_remove'] : false
108
- product.intervals = []
109
-
110
- intervals = p['intervals']
111
- if intervals
112
- p['intervals'].each do |i|
113
- interval = Interval.new
114
- interval.start_date = i['start_date']
115
- interval.end_date = i['end_date']
116
- interval.wholesale_price_tier = i['wholesale_price_tier']
117
-
118
- product.intervals << interval
119
- end
120
- end
121
-
122
- purchase.products << product
123
- end
124
-
125
- dict['locales'].each do |loc|
126
- locale = PurchaseLocale.new
127
- locale.name = loc['name']
128
- locale.title = loc['title']
129
- locale.description = loc['description']
130
- locale.publication_name = loc['publication_name']
131
-
132
- purchase.locales << locale
133
- end
134
-
135
- purchases << purchase
136
- end
137
-
138
- purchases
139
- end
140
-
141
- end
142
- end
5
+ module Transporter
6
+ module Helpers
7
+ def metadata_from_yaml(yaml_file)
8
+ objs = YAML.load_file(Dir.pwd + "/#{yaml_file}")
9
+
10
+ return {
11
+ :provider => objs['provider'],
12
+ :team_id => objs['team_id'],
13
+ :vendor_id => objs['vendor_id'],
14
+ :id_prefix => objs['id_prefix'] || '',
15
+ :versions => parse_versions(objs),
16
+ :default_achievement_image => objs['default_achievement_image'],
17
+ :achievements => parse_achievements(objs),
18
+ :leaderboards => parse_leaderboards(objs),
19
+ :purchases => parse_purchases(objs)
20
+ }
21
+ end
22
+
23
+ def parse_versions(objs)
24
+
25
+ return unless objs.has_key?('versions')
26
+
27
+ [].tap do |versions|
28
+ objs['versions'].each do |dict|
29
+ version = Version.new
30
+ version.name = dict['name']
31
+ version.locales = []
32
+
33
+ dict['locales'].each do |loc|
34
+ locale = VersionLocale.new
35
+ locale.name = loc['name']
36
+ locale.title = loc['title']
37
+ locale.description = loc['description']
38
+ locale.keywords = loc['keywords']
39
+ locale.version_whats_new = loc['version_whats_new']
40
+ locale.software_url = loc['software_url']
41
+ locale.privacy_url = loc['privacy_url']
42
+ locale.support_url = loc['support_url']
43
+ locale.screenshots = []
44
+
45
+ loc['screenshots'].each do |scrshot|
46
+ screenshot = VersionScreenshot.new
47
+ screenshot.display_target = scrshot['display_target']
48
+ screenshot.file_name = scrshot['file_name']
49
+
50
+ locale.screenshots << screenshot
51
+ end
52
+
53
+ version.locales << locale
54
+ end
55
+
56
+ versions << version
57
+ end
58
+ end
59
+ end
60
+
61
+ def parse_achievements(objs)
62
+ achievements = []
63
+
64
+ if objs.has_key?('achievements')
65
+ objs['achievements'].each do |dict|
66
+ achievement = Achievement.new
67
+ achievement.id = dict['id']
68
+ achievement.name = dict['name']
69
+ achievement.points = dict['points']
70
+ achievement.hidden = dict['has_key'] || false
71
+ achievement.reusable = dict['reusable'] || false
72
+ achievement.should_remove = dict['should_remove'] || false
73
+ achievement.locales = []
74
+
75
+ dict['locales'].each do |loc|
76
+ locale = AchievementLocale.new
77
+ locale.name = loc['name']
78
+ locale.title = loc['title']
79
+ locale.before_earned_description = loc['before_earned_description']
80
+ locale.after_earned_description = loc['after_earned_description']
81
+ locale.achievement_after_earned_image = loc['achievement_after_earned_image']
82
+ locale.should_remove = loc['should_remove'] || false
83
+
84
+ achievement.locales << locale
85
+ end
86
+
87
+ achievements << achievement
88
+ end
89
+ end
90
+ achievements
91
+ end
92
+
93
+ def parse_leaderboards(objs)
94
+ leaderboards = []
95
+
96
+ if objs.has_key?('leaderboards')
97
+ objs['leaderboards'].each do |dict|
98
+ leaderboard = Leaderboard.new
99
+ leaderboard.default = dict['default']
100
+ leaderboard.id = dict['id']
101
+ leaderboard.name = dict['name']
102
+ leaderboard.aggregate_parent_leaderboard = dict['aggregate_parent_leaderboard']
103
+ leaderboard.sort_ascending = dict['sort_ascending'] || false
104
+ leaderboard.score_range_min = dict['score_range_min']
105
+ leaderboard.score_range_max = dict['score_range_max']
106
+ leaderboard.locales = []
107
+
108
+ dict['locales'].each do |loc|
109
+ locale = LeaderboardLocale.new
110
+ locale.name = loc['name']
111
+ locale.title = loc['title']
112
+ locale.formatter_suffix = loc['formatter_suffix']
113
+ locale.formatter_suffix_singular = loc['formatter_suffix_singular']
114
+ locale.formatter_type = loc['formatter_type']
115
+ locale.leaderboard_image = loc['leaderboard_image']
116
+ locale.should_remove = loc['should_remove'] || false
117
+
118
+ leaderboard.locales << locale
119
+ end
120
+
121
+ leaderboards << leaderboard
122
+ end
123
+ end
124
+
125
+ leaderboards
126
+ end
127
+
128
+ def parse_auto_renewables(auto_renewables)
129
+ return nil if auto_renewables == nil
130
+
131
+ fam = auto_renewables['family']
132
+ family = Family.new
133
+ family.name = fam['name']
134
+ family.review_screenshot_image = fam['review_screenshot_image']
135
+ family.review_notes = fam['review_notes']
136
+ family.purchases = []
137
+ family.locales = []
138
+
139
+ # process all purchases in this family
140
+ fam['purchases'].each do |pur|
141
+ purchase = InAppPurchase.new
142
+ purchase.product_id = pur['product_id']
143
+ purchase.type = pur['type']
144
+ purchase.duration = pur['duration']
145
+ purchase.free_trial_duration = pur['free_trial_duration']
146
+ purchase.bonus_duration = pur['bonus_duration']
147
+ purchase.products = []
148
+ purchase.locales = []
149
+
150
+ product = Product.new
151
+ product.cleared_for_sale = pur['cleared_for_sale']
152
+ product.wholesale_price_tier = pur['wholesale_price_tier']
153
+ product.intervals = []
154
+ purchase.products << product
155
+
156
+ family.purchases << purchase
157
+ end
158
+
159
+ # process all locales for this family
160
+ fam['locales'].each do |loc|
161
+ locale = PurchaseLocale.new
162
+ locale.name = loc['name']
163
+ locale.title = loc['title']
164
+ locale.description = loc['description']
165
+ locale.publication_name = loc['publication_name']
166
+
167
+ family.locales << locale
168
+ end
169
+
170
+ family
171
+ end
172
+
173
+ def parse_other_purchases(other_purchases)
174
+ return nil if other_purchases == nil
175
+
176
+ purchases = []
177
+
178
+ other_purchases.each do |pur|
179
+ purchase = InAppPurchase.new
180
+ purchase.product_id = pur['product_id']
181
+ purchase.reference_name = pur['reference_name']
182
+ purchase.type = pur['type']
183
+ purchase.review_screenshot_image = pur['review_screenshot_image']
184
+ purchase.review_notes = pur['review_notes']
185
+ purchase.should_remove = pur['should_remove'] || false
186
+ purchase.locales = []
187
+ purchase.products = []
188
+
189
+ intervals = pur['intervals'] || []
190
+
191
+ product = Product.new
192
+ product.cleared_for_sale = pur['cleared_for_sale']
193
+ product.wholesale_price_tier = pur['wholesale_price_tier'] if intervals.count == 0
194
+ product.should_remove = pur['should_remove'] || false
195
+ product.intervals = []
196
+
197
+ intervals.each do |i|
198
+ interval = Interval.new
199
+ interval.start_date = i['start_date']
200
+ interval.end_date = i['end_date']
201
+ interval.wholesale_price_tier = i['wholesale_price_tier']
202
+
203
+ product.intervals << interval
204
+ end
205
+
206
+ purchase.products << product
207
+
208
+ pur['locales'].each do |loc|
209
+ locale = PurchaseLocale.new
210
+ locale.name = loc['name']
211
+ locale.title = loc['title']
212
+ locale.description = loc['description']
213
+ locale.publication_name = loc['publication_name']
214
+
215
+ purchase.locales << locale
216
+ end
217
+
218
+ purchases << purchase
219
+ end
220
+
221
+ purchases
222
+ end
223
+
224
+ def parse_purchases(objs)
225
+ purchases = {}
226
+
227
+ if objs.has_key?('purchases')
228
+ all_purchases = objs['purchases']
229
+
230
+ purchases = {
231
+ :auto_renewable_purchase_family => parse_auto_renewables(all_purchases['auto_renewable_purchases']),
232
+ :other_purchases => parse_other_purchases(all_purchases['other_purchases'])
233
+ }
234
+ end
235
+
236
+ purchases
237
+ end
238
+ end
239
+ end
143
240
  end
@@ -1,28 +1,21 @@
1
1
  module Itunes
2
- module Transporter
3
-
4
- CONSUMABLE = 'consumable'
5
- NON_CONSUMABLE = 'non-consumable'
6
- SUBSCRIPTION = 'subscription'
7
- FREE_SUBSCRIPTION = 'free-subscription'
2
+ module Transporter
3
+ class InAppPurchase < Struct.new(:product_id, :reference_name, :type, :duration, :free_trial_duration, :bonus_duration, :products, :locales, :review_screenshot_image, :review_notes, :should_remove)
4
+ def to_s
5
+ "Product ID: #{self.product_id} Reference Name: #{self.reference_name}"
6
+ end
7
+ end
8
8
 
9
- DURATION_7_DAYS = '7 Days'
10
- DURATION_1_MONTH = '1 Month'
11
- DURATION_2_MONTHS = '2 Months'
12
- DURATION_3_MONTHS = '3 Months'
13
- DURATION_6_MONTH = '6 Months'
14
- DURATION_1_YEAR = '1 Year'
9
+ class Product < Struct.new(:cleared_for_sale, :intervals, :should_remove, :wholesale_price_tier)
10
+ def to_s
11
+ "Cleared for sale: #{self.cleared_for_sale}, Tier: #{self.wholesale_pricing_tier}"
12
+ end
13
+ end
15
14
 
16
- class InAppPurchase < Struct.new(:product_id, :reference_name, :type, :duration, :free_trial_duration, :bonus_duration, :products, :locales, :review_screenshot_image, :review_notes, :should_remove)
17
- end
15
+ class Interval < Struct.new(:start_date, :end_date, :wholesale_price_tier)
16
+ end
18
17
 
19
- class Product < Struct.new(:cleared_for_sale, :intervals, :should_remove, :wholesale_price_tier)
20
- end
21
-
22
- class Interval < Struct.new(:start_date, :end_date, :wholesale_price_tier)
23
- end
24
-
25
- class PurchaseLocale < Struct.new(:name, :title, :description, :publication_name)
26
- end
27
- end
18
+ class PurchaseLocale < Struct.new(:name, :title, :description, :publication_name)
19
+ end
20
+ end
28
21
  end
@@ -1,36 +0,0 @@
1
- require 'itunes/transporter/locale'
2
-
3
- module Itunes
4
- module Transporter
5
- class Leaderboard < Struct.new(:default, :id, :name, :aggregate_parent_leaderboard, :sort_ascending, :score_range_min, :score_range_max, :locales)
6
- end
7
-
8
- class LeaderboardLocale < Struct.new(:name, :title, :formatter_suffix, :formatter_suffix_singular, :formatter_type, :leaderboard_image, :should_remove)
9
- end
10
-
11
- INTEGER_COMMA_SEPARATOR = 'INTEGER_COMMA_SEPARATOR'
12
- INTEGER_DECIMAL_SEPARATOR = 'INTEGER_DECIMAL_SEPARATOR'
13
- FIXED_POINT_1_PLACE_WITH_COMMA_SEPARATOR = 'FIXED_POINT_1_PLACE_WITH_COMMA_SEPARATOR'
14
- FIXED_POINT_1_PLACE_WITH_DECIMAL_SEPARATOR = 'FIXED_POINT_1_PLACE_WITH_DECIMAL_SEPARATOR'
15
- FIXED_POINT_2_PLACE_WITH_COMMA_SEPARATOR = 'FIXED_POINT_2_PLACE_WITH_COMMA_SEPARATOR'
16
- FIXED_POINT_2_PLACE_WITH_DECIMAL_SEPARATOR = 'FIXED_POINT_2_PLACE_WITH_DECIMAL_SEPARATOR'
17
- FIXED_POINT_3_PLACE_WITH_COMMA_SEPARATOR = 'FIXED_POINT_3_PLACE_WITH_COMMA_SEPARATOR'
18
- FIXED_POINT_3_PLACE_WITH_DECIMAL_SEPARATOR = 'FIXED_POINT_3_PLACE_WITH_DECIMAL_SEPARATOR'
19
- ELAPSED_TIME_TO_MINUTE = 'ELAPSED_TIME_TO_MINUTE'
20
- ELAPSED_TIME_TO_SECOND = 'ELAPSED_TIME_TO_SECOND'
21
- ELAPSED_TIME_TO_HUNDREDTH_OF_SECOND = 'ELAPSED_TIME_TO_HUNDREDTH_OF_SECOND'
22
- MONEY_DOLLAR_WHOLE_WITH_COMMA_SEPARATOR = 'MONEY_DOLLAR_WHOLE_WITH_COMMA_SEPARATOR'
23
- MONEY_EURO_WHOLE_WITH_DECIMAL_SEPARATOR = 'MONEY_EURO_WHOLE_WITH_DECIMAL_SEPARATOR'
24
- MONEY_EURO_WHOLE_WITH_SPACE_SEPARATOR = 'MONEY_EURO_WHOLE_WITH_SPACE_SEPARATOR'
25
- MONEY_POUND_WHOLE_WITH_COMMA_SEPARATOR = 'MONEY_POUND_WHOLE_WITH_COMMA_SEPARATOR'
26
- MONEY_KR_WHOLE_WITH_COMMA_SEPARATOR = 'MONEY_KR_WHOLE_WITH_COMMA_SEPARATOR'
27
- MONEY_FR_WHOLE_WITH_SPACE_SEPARATOR = 'MONEY_FR_WHOLE_WITH_SPACE_SEPARATOR'
28
- MONEY_YEN_WHOLE_WITH_COMMA_SEPARATOR= 'MONEY_YEN_WHOLE_WITH_COMMA_SEPARATOR'
29
- MONEY_DOLLAR_2DECIMALS_WITH_COMMA_SEPARATOR = 'MONEY_DOLLAR_2DECIMALS_WITH_COMMA_SEPARATOR'
30
- MONEY_EURO_2DECIMALS_WITH_DECIMAL_SEPARATOR= 'MONEY_EURO_2DECIMALS_WITH_DECIMAL_SEPARATOR'
31
- MONEY_EURO_2DECIMALSE_WITH_SPACE_SEPARATOR = 'MONEY_EURO_2DECIMALSE_WITH_SPACE_SEPARATOR'
32
- MONEY_POUND_2DECIMALS_WITH_COMMA_SEPARATOR = 'MONEY_POUND_2DECIMALS_WITH_COMMA_SEPARATOR'
33
- MONEY_KR_2DECIMALS_WITH_COMMA_SEPARATOR = 'MONEY_KR_2DECIMALS_WITH_COMMA_SEPARATOR'
34
- MONEY_FR_2DECIMALS_WITH_SPACE_SEPARATOR = 'MONEY_FR_2DECIMALS_WITH_SPACE_SEPARATOR'
35
- end
36
- end