morhekil-globalite 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,364 @@
1
+ locale_name: 台灣 (Taiwan)
2
+ # ActiveRecord::Errors.default_error_messages
3
+ error_message_inclusion: 不在指定的名單上
4
+ error_message_exclusion: 已在指定的名單上
5
+ error_message_invalid: 是錯誤的資料
6
+ error_message_confirmation: 與指定值不同
7
+ error_message_accepted: 必須要選擇接受指定的條款
8
+ error_message_empty: 不能不填
9
+ error_message_blank: 不能是空白
10
+ error_message_too_long: 太長 (最多 %d 個字元)
11
+ error_message_too_short: 太短 (最少 %d 個字元)
12
+ error_message_wrong_length: 長度不正確 (應該要 %d 個字元)
13
+ error_message_taken: 已經有人使用
14
+ error_message_not_a_number: 不是數字
15
+
16
+ # ActionController::Base.resources_path_names
17
+ # Chinese needs to be transliterated into latin
18
+ resources_path_new: xin-de
19
+ resources_path_edit: bian-ji
20
+ # translated using google translate,
21
+ # transliterated using http://rcalvi.com/cu_archive/Transliteration/demo.html
22
+
23
+ # used by ActionView::Helpers::ActiveRecordHelper.error_messages_for
24
+ active_record_helper_header_message: 輸入資訊錯誤
25
+ active_record_helper_error_description: 請更正下列問題,
26
+
27
+ # used by ActionView::Helpers::DateHelper.distance_of_time_in_words
28
+ date_helper_less_than_x_seconds: 少於 %d 秒
29
+ date_helper_half_a_minute: 30 秒
30
+ date_helper_less_than_a_minute: 少於一分鐘
31
+ date_helper_one_minute: 一分鐘
32
+ date_helper_x_minutes: %d 分鐘
33
+ date_helper_one_hour: 約 1 小時
34
+ date_helper_x_hours: 約 %d 小時
35
+ date_helper_one_day: 1 天
36
+ date_helper_x_days: %d 天
37
+ date_helper_one_month: 1 個月
38
+ date_helper_x_months: %d 個月
39
+ date_helper_one_year: 1 年
40
+ date_helper_x_years: %d 年
41
+
42
+ # DON'T TRANSLATE, just order
43
+ date_helper_order: [:day, :month, :year] #default Rails is US ordered: :order => [:year, :month, :day]
44
+
45
+ date_helper_date_formats: # DON'T TRANSLATE, RE ORDER
46
+ default: "%Y/%m/%d"
47
+ short: "%b %e"
48
+ long: "%b %e, %Y"
49
+
50
+ date_helper_time_formats: # DON'T TRANSLATE, RE ORDER
51
+ default: "%a, %Y %b %d %H:%M:%S %z"
52
+ short: "%b %d, %H:%M"
53
+ long: "%Y/%b/%d %H:%M"
54
+
55
+ # added at the end of date if your date system doesn't use a 24 hours system
56
+ date_helper_am: am
57
+ date_helper_pm: pm
58
+
59
+ # used by ActionView::Helpers::NumberHelper.number_to_currency
60
+ number_helper_unit: "NT$"
61
+ number_helper_separator: "." #unit separator (between integer part and fraction part)
62
+ number_helper_delimiter: "," #delimiter between each group of thousands. Example: 1.234.567
63
+ number_helper_order: [ unit, number ]
64
+ #to support for instance French format, the order is different: Unit comes last (ex. "1.234,00 €")
65
+
66
+ # use by +Array#to_sentence()+
67
+ array_connector: '和'
68
+ array_skip_last_comma: 'true'
69
+
70
+ date_helper_month_names:
71
+ - # Leave that line
72
+ - # Leave that line
73
+ - 一月
74
+ - 二月
75
+ - 三月
76
+ - 四月
77
+ - 五月
78
+ - 六月
79
+ - 七月
80
+ - 八月
81
+ - 九月
82
+ - 十月
83
+ - 十一月
84
+ - 十二月
85
+
86
+ date_helper_abbr_month_names:
87
+ - # Leave that line
88
+ - # Leave that line
89
+ - 1月
90
+ - 2月
91
+ - 3月
92
+ - 4月
93
+ - 5月
94
+ - 6月
95
+ - 7月
96
+ - 8月
97
+ - 9月
98
+ - 10月
99
+ - 11月
100
+ - 12月
101
+
102
+ date_helper_day_names:
103
+ - 星期天
104
+ - 星期一
105
+ - 星期二
106
+ - 星期三
107
+ - 星期四
108
+ - 星期五
109
+ - 星期六
110
+
111
+ date_helper_abbr_day_names:
112
+ - 周日
113
+ - 周一
114
+ - 周二
115
+ - 周三
116
+ - 周四
117
+ - 周五
118
+ - 周六
119
+
120
+ countries_list:
121
+ - Afghanistan
122
+ - Albania
123
+ - Algeria
124
+ - American Samoa
125
+ - Andorra
126
+ - Angola
127
+ - Anguilla
128
+ - Antarctica
129
+ - Antigua And Barbuda
130
+ - Argentina
131
+ - Armenia
132
+ - Aruba
133
+ - Australia
134
+ - Austria
135
+ - Azerbaijan
136
+ - Bahamas
137
+ - Bahrain
138
+ - Bangladesh
139
+ - Barbados
140
+ - Belarus
141
+ - Belgium
142
+ - Belize
143
+ - Benin
144
+ - Bermuda
145
+ - Bhutan
146
+ - Bolivia
147
+ - Bosnia and Herzegowina
148
+ - Botswana
149
+ - Bouvet Island
150
+ - Brazil
151
+ - British Indian Ocean Territory
152
+ - Brunei Darussalam
153
+ - Bulgaria
154
+ - Burkina Faso
155
+ - Burma
156
+ - Burundi
157
+ - Cambodia
158
+ - Cameroon
159
+ - Canada
160
+ - Cape Verde
161
+ - Cayman Islands
162
+ - Central African Republic
163
+ - Chad
164
+ - Chile
165
+ - China
166
+ - Christmas Island
167
+ - Cocos (Keeling) Islands
168
+ - Colombia
169
+ - Comoros
170
+ - Congo
171
+ - Congo, the Democratic Republic of the
172
+ - Cook Islands
173
+ - Costa Rica
174
+ - Cote d'Ivoire
175
+ - Croatia
176
+ - Cuba
177
+ - Cyprus
178
+ - Czech Republic
179
+ - Denmark
180
+ - Djibouti
181
+ - Dominica
182
+ - Dominican Republic
183
+ - East Timor
184
+ - Ecuador
185
+ - Egypt
186
+ - El Salvador
187
+ - England
188
+ - Equatorial Guinea
189
+ - Eritrea
190
+ - Espana
191
+ - Estonia
192
+ - Ethiopia
193
+ - Falkland Islands
194
+ - Faroe Islands
195
+ - Fiji
196
+ - Finland
197
+ - France
198
+ - French Guiana
199
+ - French Polynesia
200
+ - French Southern Territories
201
+ - Gabon
202
+ - Gambia
203
+ - Georgia
204
+ - Germany
205
+ - Ghana
206
+ - Gibraltar
207
+ - Great Britain
208
+ - Greece
209
+ - Greenland
210
+ - Grenada
211
+ - Guadeloupe
212
+ - Guam
213
+ - Guatemala
214
+ - Guinea
215
+ - Guinea-Bissau
216
+ - Guyana
217
+ - Haiti
218
+ - Heard and Mc Donald Islands
219
+ - Honduras
220
+ - Hong Kong
221
+ - Hungary
222
+ - Iceland
223
+ - India
224
+ - Indonesia
225
+ - Ireland
226
+ - Israel
227
+ - Italy
228
+ - Iran
229
+ - Iraq
230
+ - Jamaica
231
+ - Japan
232
+ - Jordan
233
+ - Kazakhstan
234
+ - Kenya
235
+ - Kiribati
236
+ - Korea, Republic of
237
+ - Korea (South)
238
+ - Kuwait
239
+ - Kyrgyzstan
240
+ - Lao People's Democratic Republic
241
+ - Latvia
242
+ - Lebanon
243
+ - Lesotho
244
+ - Liberia
245
+ - Liechtenstein
246
+ - Lithuania
247
+ - Luxembourg
248
+ - Macau
249
+ - Macedonia
250
+ - Madagascar
251
+ - Malawi
252
+ - Malaysia
253
+ - Maldives
254
+ - Mali
255
+ - Malta
256
+ - Marshall Islands
257
+ - Martinique
258
+ - Mauritania
259
+ - Mauritius
260
+ - Mayotte
261
+ - Mexico
262
+ - Micronesia, Federated States of
263
+ - Moldova, Republic of
264
+ - Monaco
265
+ - Mongolia
266
+ - Montserrat
267
+ - Morocco
268
+ - Mozambique
269
+ - Myanmar
270
+ - Namibia
271
+ - Nauru
272
+ - Nepal
273
+ - Netherlands
274
+ - Netherlands Antilles
275
+ - New Caledonia
276
+ - New Zealand
277
+ - Nicaragua
278
+ - Niger
279
+ - Nigeria
280
+ - Niue
281
+ - Norfolk Island
282
+ - Northern Ireland
283
+ - Northern Mariana Islands
284
+ - Norway
285
+ - Oman
286
+ - Pakistan
287
+ - Palau
288
+ - Panama
289
+ - Papua New Guinea
290
+ - Paraguay
291
+ - Peru
292
+ - Philippines
293
+ - Pitcairn
294
+ - Poland
295
+ - Portugal
296
+ - Puerto Rico
297
+ - Qatar
298
+ - Reunion
299
+ - Romania
300
+ - Russia
301
+ - Rwanda
302
+ - Saint Kitts and Nevis
303
+ - Saint Lucia
304
+ - Saint Vincent and the Grenadines
305
+ - Samoa (Independent)
306
+ - San Marino
307
+ - Sao Tome and Principe
308
+ - Saudi Arabia
309
+ - Scotland
310
+ - Senegal
311
+ - Serbia and Montenegro
312
+ - Seychelles
313
+ - Sierra Leone
314
+ - Singapore
315
+ - Slovakia
316
+ - Slovenia
317
+ - Solomon Islands
318
+ - Somalia
319
+ - South Africa
320
+ - South Georgia and the South Sandwich Islands
321
+ - South Korea
322
+ - Spain
323
+ - Sri Lanka
324
+ - St. Helena
325
+ - St. Pierre and Miquelon
326
+ - Suriname
327
+ - Svalbard and Jan Mayen Islands
328
+ - Swaziland
329
+ - Sweden
330
+ - Switzerland
331
+ - Taiwan
332
+ - Tajikistan
333
+ - Tanzania
334
+ - Thailand
335
+ - Togo
336
+ - Tokelau
337
+ - Tonga
338
+ - Trinidad
339
+ - Trinidad and Tobago
340
+ - Tunisia
341
+ - Turkey
342
+ - Turkmenistan
343
+ - Turks and Caicos Islands
344
+ - Tuvalu
345
+ - Uganda
346
+ - Ukraine
347
+ - United Arab Emirates
348
+ - United Kingdom
349
+ - United States
350
+ - United States Minor Outlying Islands
351
+ - Uruguay
352
+ - Uzbekistan
353
+ - Vanuatu
354
+ - Vatican City State (Holy See)
355
+ - Venezuela
356
+ - Viet Nam
357
+ - Virgin Islands (British)
358
+ - Virgin Islands (U.S.)
359
+ - Wales
360
+ - Wallis and Futuna Islands
361
+ - Western Sahara
362
+ - Yemen
363
+ - Zambia
364
+ - Zimbabwe
data/lib/globalite.rb ADDED
@@ -0,0 +1,30 @@
1
+ # Add support for localization keys
2
+ require 'rails/core_ext'
3
+ require 'globalite/l10n'
4
+ require 'globalite/locale'
5
+ Symbol.send :include, SymbolExtension
6
+
7
+ module Globalite
8
+ extend L10n
9
+ def self.localize_rails
10
+ ActiveRecord::Errors.relocalize
11
+ ActionController::Base.relocalize
12
+ end
13
+ end
14
+
15
+ # Localize Rails
16
+ require 'rails/localization.rb'
17
+ require 'rails/localized_action_view'
18
+ require 'rails/localized_action_controller'
19
+ require 'rails/localized_active_record'
20
+
21
+ # added Boolean function to 'boolean' a string
22
+ module Kernel
23
+ def Boolean(string)
24
+ return true if string == true || string =~ /^true$/i
25
+ return false if string == false || string.nil? || string =~ /^false$/i
26
+ raise ArgumentError.new("invalid value for Boolean: \"#{string}\"")
27
+ end
28
+ end
29
+
30
+ Globalite.load_localization!
@@ -0,0 +1,333 @@
1
+ module Globalite
2
+
3
+ module L10n
4
+
5
+ @@default_language = :en
6
+ attr_reader :default_language
7
+
8
+ @@default_country = :*
9
+ mattr_reader :default_country
10
+
11
+ @@reserved_keys = [ :limit ]
12
+ mattr_reader :reserved_keys
13
+
14
+ @@languages = []
15
+ def languages
16
+ @@languages
17
+ end
18
+
19
+ def default_language
20
+ @@default_language
21
+ end
22
+
23
+ @@countries = []
24
+ def countries
25
+ @@countries
26
+ end
27
+
28
+ @@locales = {}
29
+ def locales
30
+ @@locales.keys
31
+ end
32
+
33
+ @@rails_locales = {}
34
+ def rails_locales
35
+ @@rails_locales
36
+ end
37
+
38
+ @@ui_locales = {}
39
+ def ui_locales
40
+ @@ui_locales
41
+ end
42
+
43
+ @@inflectors = {}
44
+ def inflectors
45
+ @@inflectors
46
+ end
47
+
48
+ @@current_language = nil
49
+ def current_language
50
+ @@current_language || default_language
51
+ end
52
+ alias :language :current_language
53
+
54
+ @@current_country = nil
55
+ def country
56
+ @@current_country || default_country
57
+ end
58
+ alias :current_country :country
59
+
60
+ def current_locale
61
+ "#{current_language}-#{current_country}".to_sym
62
+ end
63
+ alias :locale :current_locale
64
+
65
+ # Set the current language ( ISO 639-1 language code in lowercase letters)
66
+ # Usage:
67
+ # Globalite.language = 'fr' or Globalite.language = :Fr
68
+ # Will save the current language code if available, otherwise nada, switching back to the previous language
69
+ #
70
+ def language=(language)
71
+
72
+ language = language.to_s.downcase.to_sym if language.class == Symbol
73
+ language = language.downcase.to_sym if language.class == String && !language.empty?
74
+
75
+ if @@languages.include?(language)
76
+ @@current_language = language
77
+ if !@@locales.include?("#{language}-#{@@current_country}".to_sym)
78
+ @@current_country = :*
79
+ end
80
+ end
81
+
82
+ #Locale.update_session_locale
83
+ localize_rails
84
+ @@current_language
85
+ end
86
+ alias :current_language= :language=
87
+
88
+ # Set the current country code (ISO 3166 country code in uppercase letters)
89
+ # Usage:
90
+ # Globalite.country = 'US' or Globalite.country = :fr
91
+ # Will store the current country code if supported
92
+ # Will try to automatically find the language for your country
93
+ # If the country isn't unknown to the system, the country will be set as :*
94
+ #
95
+ def country=(country)
96
+ load_localization! if (defined? RAILS_ENV) && (RAILS_ENV == 'development')
97
+ country = country.to_s.upcase.to_sym if country.class == Symbol
98
+ country = country.upcase.to_sym if country.class == String && !country.empty?
99
+
100
+ if @@locales.include?("#{current_language}-#{country}".to_sym)
101
+ @@current_country = country
102
+ elsif locales.each {|locale| locale =~ /[a-z][a-z]-#{country.to_s}/ }
103
+ locales.each do |key|
104
+ if key.to_s.include?(country.to_s)
105
+ @new_language = key.to_s.split('-')[0].downcase.to_sym
106
+ end
107
+ end
108
+ if @new_language && @@locales.include?("#{@new_language}-#{country}".to_sym)
109
+ @@current_language = @new_language
110
+ @@current_country = country
111
+ end
112
+ else
113
+ @@current_country = :*
114
+ end
115
+ #Locale.update_session_locale
116
+ @@current_country
117
+ end
118
+ alias :current_country= :country=
119
+
120
+ def locale=(locale)
121
+ Locale.set_code(locale)
122
+ end
123
+ alias :current_locale= :locale=
124
+
125
+ @@localization_sources = []
126
+ def add_localization_source(path)
127
+ @@localization_sources << path
128
+ load_localization!
129
+ end
130
+
131
+ def localization_sources
132
+ @@localization_sources
133
+ end
134
+
135
+ # List localizations for the current locale
136
+ def localizations
137
+ @@locales[Locale.code] || {}
138
+ end
139
+
140
+ # Return the translation for the key, a string can be passed to replaced a missing translation
141
+ def localize(key, error_msg='__localization_missing__', args={}, locale=nil)
142
+ return if reserved_keys.include? key
143
+
144
+ # Set a temporary Locale to support the localized_in method
145
+ #
146
+ unless locale.nil?
147
+ @original_locale = Locale.code
148
+ Locale.set_code(locale)
149
+ end
150
+ localized = localizations[key] || error_msg
151
+ # Get translations from another country but in the same language if Globalite can't find a translation for my locale
152
+ #
153
+ if localized == error_msg
154
+ locales.each do |t_locale|
155
+ if t_locale.to_s.include?("#{current_language.to_s}-") && t_locale != Locale.code
156
+ localized = @@locales[t_locale][key] || error_msg
157
+ end
158
+ end
159
+ end
160
+ localized = interpolate_string(localized.dup, args.dup) if localized.class == String && localized != error_msg
161
+
162
+ # let's handle pluralization if needed
163
+ # the translation must include pluralize{count, singular string} to be translated
164
+ # the translator can also pass the plural form if needed:
165
+ # pluralize{3, goose, geese}
166
+ localized = localized.gsub( /pluralize\{(.*?)\}/){ |erb| pluralize(Regexp.last_match(1)) } if localized.is_a?(String) && (localized=~ /pluralize\{(.*)\}/)
167
+
168
+ # Set the locale back to normal
169
+ #
170
+ unless locale.nil?
171
+ Locale.code = @original_locale
172
+ end
173
+
174
+ return localized
175
+ end
176
+ alias :loc :localize
177
+
178
+ def localize_with_args(key, args={})
179
+ localize(key, '_localization missing_', args)
180
+ end
181
+ alias :l_with_args :localize_with_args
182
+
183
+ def add_reserved_key(*key)
184
+ (@@reserved_keys += key.flatten).uniq!
185
+ end
186
+ alias :add_reserved_keys :add_reserved_key
187
+
188
+ # modified version of the Rails pluralize method from ActionView::Helpers::TextHelper module
189
+ # TODO: load custom inflector based on the language one uses.
190
+ def pluralize(l_string) #count, singular, plural = nil)
191
+
192
+ if inflectors.include?(current_language) then
193
+ # We have custom inflector loaded - return it's result
194
+ inflectors[current_language].call(l_string)
195
+
196
+ else
197
+ # No custom inflectors - do the default stuff
198
+
199
+ # map the arguments like in the original pluralize method
200
+ count, singular, plural = l_string.split(',').map{ |arg| arg.strip}
201
+
202
+ "#{count} " + if count == 1 || count == '1'
203
+ singular
204
+ elsif plural
205
+ plural
206
+ elsif Object.const_defined?("Inflector")
207
+ Inflector.pluralize(singular)
208
+ else
209
+ singular + "s"
210
+ end
211
+ end
212
+ end
213
+
214
+ def reset_l10n_data
215
+ @@languages = []
216
+ @@countries = []
217
+ @@locales = {}
218
+ @@rails_locales = {}
219
+ @@ui_locales = {}
220
+ end
221
+
222
+ # Loads ALL the UI localization in memory, I might want to refactor this later on.
223
+ # (can be hard on the memory if you load 25 languages with 900 entries each)
224
+ def load_localization!
225
+ reset_l10n_data
226
+
227
+ # Load the rails localization
228
+ if rails_localization_files
229
+ rails_localization_files.each do |file|
230
+ lang = File.basename(file, '.*')[0,2].downcase.to_sym
231
+ # if a country is defined
232
+ if File.basename(file, '.*')[3,5]
233
+ country = File.basename(file, '.*')[3,5].upcase.to_sym
234
+ @@countries << country if ( country != :* && !@@countries.include?(country) )
235
+ if locales.include?("#{lang}-#{country}".to_sym)
236
+ @@locales["#{lang}-#{country}".to_sym].merge(YAML.load_file(file).symbolize_keys)
237
+ else
238
+ @@locales["#{lang}-#{country}".to_sym] = YAML.load_file(file).symbolize_keys
239
+ @@rails_locales[locale_name("#{lang}-#{country}")] = "#{lang}-#{country}".to_sym
240
+ end
241
+ @@languages << lang unless @@languages.include? lang
242
+ else
243
+ @@languages << lang unless @@languages.include? lang
244
+ @f_locale = "#{lang}-*".to_sym
245
+ @@locales[@f_locale] = @@locales[@f_locale].merge(YAML.load_file(file).symbolize_keys) if locales.include?(@f_locale)
246
+ @@locales[@f_locale] = YAML.load_file(file).symbolize_keys unless locales.include?(@f_locale)
247
+ end
248
+ end
249
+ end
250
+ alias :load_translations! :load_localization!
251
+ alias :load_localizations! :load_localization!
252
+
253
+ # Load the UI localization
254
+ if ui_localization_files
255
+ ui_localization_files.each do |file|
256
+ lang = File.basename(file, '.*')[0,2].downcase.to_sym
257
+ if File.basename(file, '.*')[3,5]
258
+ country = File.basename(file, '.*')[3,5].upcase.to_sym
259
+ else
260
+ country = '*'.to_sym
261
+ end
262
+ @@languages << lang unless @@languages.include? lang
263
+ @@countries << country if ( country != :* && !@@countries.include?(country) )
264
+ @file_locale = "#{lang}-#{country}".to_sym
265
+ if locales.include?(@file_locale)
266
+ @@locales[@file_locale] = @@locales[@file_locale].merge(YAML.load_file(file).symbolize_keys)
267
+ @@ui_locales[locale_name("#{lang}-#{country}")] = "#{lang}-#{country}".to_sym
268
+ else
269
+ @@locales[@file_locale] = YAML.load_file(file).symbolize_keys
270
+ @@ui_locales[locale_name("#{lang}-#{country}")] = "#{lang}-#{country}".to_sym
271
+ end
272
+
273
+ end
274
+ end
275
+
276
+ # Load inflectors
277
+ inflector_localization_files.each do |file|
278
+ lang = File.basename(file, '.*')[0,2].downcase.to_sym
279
+ @@inflectors[lang] = eval("Proc.new { |l_string| "+File.readlines(file).join("\n")+" }")
280
+ end if inflector_localization_files
281
+
282
+ localize_rails
283
+ # Return the path of the localization files
284
+ return "#{ui_localization_files} | #{rails_localization_files}".to_s
285
+ end
286
+
287
+ def locale_name(locale_code)
288
+ locale_code = locale_code.to_sym
289
+ if locales.include?(locale_code)
290
+ @@locales[locale_code][:locale_name] || nil
291
+ end
292
+ end
293
+
294
+ protected
295
+ # Return the list of UI files used by Globalite
296
+ def ui_localization_files
297
+ loc_files = Dir[File.join(RAILS_ROOT, 'lang/ui/', '*.{yml,yaml}')]
298
+ unless @@localization_sources.empty?
299
+ @@localization_sources.each do |path|
300
+ loc_files += Dir[File.join(path, '*.{yml,yaml}')]
301
+ end
302
+ end
303
+ loc_files
304
+ end
305
+
306
+ # Return a list of the Rails localization files
307
+ def rails_localization_files
308
+ loc_files = Dir[File.join( RAILS_ROOT, '/vendor/plugins/globalite/lang/rails/', '*.{yml,yaml}')]
309
+ end
310
+
311
+ # Return a list of the localized inflectors
312
+ def inflector_localization_files
313
+ loc_files = Dir[File.join(RAILS_ROOT, 'lang/inflectors/', '*.{txt,rb}')]
314
+ unless @@localization_sources.empty?
315
+ @@localization_sources.each do |path|
316
+ loc_files += Dir[File.join(path, '../inflectors/*.{txt,rb}')]
317
+ end
318
+ end
319
+ loc_files
320
+ end
321
+
322
+ # Interpolate a string using the passed arguments
323
+ def interpolate_string(string, args={})
324
+ if args.length > 0
325
+ args.each do |arg|
326
+ string = string.gsub("{#{arg[0].to_s}}", arg[1].to_s)
327
+ end
328
+ end
329
+ string
330
+ end
331
+
332
+ end
333
+ end